[
  {
    "path": "CN/README-old-2.md",
    "content": "# **完整设备仿真定制固件开发指南**\n\n---\n\n## **目录**\n\n### **第1部分：基础概念**\n\n1. [介绍](#1-介绍)\n   - [1.1 本指南的目的](#11-本指南的目的)\n   - [1.2 目标受众](#12-目标受众)\n   - [1.3 如何使用本指南](#13-如何使用本指南)\n2. [关键定义](#2-关键定义)\n3. [设备兼容性](#3-设备兼容性)\n   - [3.1 支持的基于FPGA的硬件](#31-支持的基于fpga的硬件)\n   - [3.2 PCIe硬件注意事项](#32-pcie硬件注意事项)\n   - [3.3 系统要求](#33-系统要求)\n4. [要求](#4-要求)\n   - [4.1 硬件](#41-硬件)\n   - [4.2 软件](#42-软件)\n   - [4.3 环境设置](#43-环境设置)\n5. [收集捐赠设备信息](#5-收集捐赠设备信息)\n   - [5.1 使用Arbor进行PCIe设备扫描](#51-使用arbor进行pcie设备扫描)\n   - [5.2 提取和记录设备属性](#52-提取和记录设备属性)\n6. [初始固件定制](#6-初始固件定制)\n   - [6.1 修改配置空间](#61-修改配置空间)\n   - [6.2 插入设备序列号（DSN）](#62-插入设备序列号dsn)\n7. [Vivado项目设置和定制](#7-vivado项目设置和定制)\n   - [7.1 生成Vivado项目文件](#71-生成vivado项目文件)\n   - [7.2 修改IP模块](#72-修改ip模块)\n\n### **第2部分：中级概念与实现**\n\n8. [高级固件定制](#8-高级固件定制)\n   - [8.1 为仿真配置PCIe参数](#81-为仿真配置pcie参数)\n   - [8.2 调整BAR和内存映射](#82-调整bar和内存映射)\n   - [8.3 仿真设备电源管理和中断](#83-仿真设备电源管理和中断)\n9. [仿真设备特定功能](#9-仿真设备特定功能)\n   - [9.1 实现高级PCIe功能](#91-实现高级pcie功能)\n   - [9.2 仿真供应商特定特性](#92-仿真供应商特定特性)\n10. [事务层数据包（TLP）仿真](#10-事务层数据包tlp仿真)\n    - [10.1 理解和捕获TLP](#101-理解和捕获tlp)\n    - [10.2 为特定操作制作自定义TLP](#102-为特定操作制作自定义tlp)\n\n### **第3部分：高级技术与优化**\n\n11. [构建、烧录和测试](#11-构建烧录和测试)\n    - [11.1 综合与实现](#111-综合与实现)\n    - [11.2 烧录比特流](#112-烧录比特流)\n    - [11.3 测试与验证](#113-测试与验证)\n12. [高级调试技术](#12-高级调试技术)\n    - [12.1 使用Vivado的集成逻辑分析器](#121-使用vivado的集成逻辑分析器)\n    - [12.2 PCIe流量分析工具](#122-pcie流量分析工具)\n13. [故障排除](#13-故障排除)\n    - [13.1 设备检测问题](#131-设备检测问题)\n    - [13.2 内存映射和BAR配置错误](#132-内存映射和bar配置错误)\n    - [13.3 DMA性能和TLP错误](#133-dma性能和tlp错误)\n14. [仿真准确性和优化](#14-仿真准确性和优化)\n    - [14.1 精确计时仿真技术](#141-精确计时仿真技术)\n    - [14.2 对系统调用的动态响应](#142-对系统调用的动态响应)\n15. [固件开发最佳实践](#15-固件开发最佳实践)\n    - [15.1 持续测试和文档编制](#151-持续测试和文档编制)\n    - [15.2 管理固件版本](#152-管理固件版本)\n    - [15.3 安全考虑](#153-安全考虑)\n16. [其他资源](#16-其他资源)\n17. [联系信息](#17-联系信息)\n18. [支持与贡献](#18-支持与贡献)\n\n---\n\n## **前言**\n\n对于那些想要学习的人，你们选择了真正启迪的道路。你们用本指南所构建的东西将超越这些人能想象的一切。你们正在走向卓越，我们将一起超越他们所建立的失败。\n\n---\n\n## **第1部分：基础概念**\n\n---\n\n## **1. 介绍**\n\n### **1.1 本指南的目的**\n\n本指南的主要目的是提供一种分步方法，开发用于基于FPGA设备的自定义直接内存访问（DMA）固件，以准确仿真PCIe硬件。这使得能够实现硬件测试、系统调试、安全研究和硬件仿真等应用。\n\n通过遵循本指南，您将学习如何：\n\n- 从捐赠设备收集必要信息。\n- 定制固件以仿真特定的硬件设备。\n- 使用Vivado和Visual Studio Code等工具设置开发环境。\n- 了解与PCIe和DMA操作相关的关键概念。\n\n### **1.2 目标受众**\n\n本指南适用于：\n\n- **固件开发人员**：对创建用于硬件仿真、测试或绕过硬件限制的自定义固件感兴趣的工程师。\n- **硬件工程师**：需要仿真特定设备进行硬件测试和开发的专业人员。\n- **安全研究人员**：进行漏洞评估、恶意软件分析或需要硬件仿真的安全测试的个人。\n- **FPGA爱好者**：对FPGA定制和低级硬件仿真感兴趣的爱好者和学习者。\n\n### **1.3 如何使用本指南**\n\n本指南分为三个部分：\n\n- **第1部分：基础概念**：涵盖开始设备仿真所需的基本概念、设置和初始步骤的固件开发。\n- **第2部分：中级概念与实现**：深入讨论更复杂的主题，如高级固件定制、TLP仿真和初始调试技术。\n- **第3部分：高级技术与优化**：探索高级调试、故障排除、优化策略和最佳实践。\n\n建议按照指南的顺序进行，以建立牢固的理解，然后再处理高级主题。\n\n---\n\n## **2. 关键定义**\n\n理解术语对于有效地遵循本指南至关重要。以下是与PCIe、DMA和设备仿真相关的关键定义：\n\n- **DMA（直接内存访问）**：一种允许硬件设备直接从系统内存读取或写入数据的功能，无需CPU干预，实现高速数据传输。\n- **TLP（事务层数据包）**：PCIe架构中的基本通信单位，封装控制和数据信息。\n- **BAR（基地址寄存器）**：PCIe设备中的寄存器，定义内存和I/O地址区域，将设备内存映射到系统内存空间。\n- **FPGA（现场可编程门阵列）**：一种可重配置的集成电路，可编程以执行特定的硬件功能。\n- **MSI/MSI-X（消息信号中断）**：PCIe设备用于向CPU发送中断的机制，无需使用传统的中断线。\n- **设备序列号（DSN）**：与特定设备关联的唯一标识符，通常用于高级设备识别。\n- **PCIe配置空间**：标准化的内存区域，PCIe设备在其中提供关于自身的信息并配置操作参数。\n- **捐赠设备**：用于提取配置和识别详细信息以在FPGA上仿真其行为的PCIe硬件设备。\n\n---\n\n## **3. 设备兼容性**\n\n### **3.1 支持的基于FPGA的硬件**\n\n虽然本指南主要关注**Squirrel DMA（35T）**卡，因为它易于获取，但这些方法也可适用于其他基于FPGA的DMA硬件：\n\n- **Squirrel（35T）**\n  - **描述**：经济实惠的基于FPGA的DMA设备，适用于标准内存获取和设备仿真。\n- **Enigma-X1（75T）**\n  - **描述**：中端FPGA，提供增强的资源，适合更高要求的内存操作。\n- **ZDMA（100T）**\n  - **描述**：高性能FPGA，针对快速内存交互进行了优化，适用于广泛的内存读/写。\n- **Kintex-7**\n  - **描述**：高级FPGA，具有强大的功能，适用于复杂项目和大规模DMA解决方案。\n\n### **3.2 PCIe硬件注意事项**\n\n为了确保平滑的仿真，必须解决多个PCIe特定功能：\n\n- **IOMMU/VT-d设置**\n  - **建议**：禁用IOMMU（Intel的VT-d）或AMD的等效功能，以允许不受限制的DMA访问。\n  - **理由**：IOMMU可能会限制DMA操作，可能会干扰内存获取和仿真。\n- **内核DMA保护**\n  - **建议**：在现代系统中禁用内核DMA保护功能。\n  - **步骤**：\n    - **Windows**：在BIOS/UEFI设置中禁用安全启动或基于虚拟化的安全性（VBS）等功能。\n    - **注意**：禁用这些功能可能会使系统暴露于安全风险中；确保您在安全的环境中操作。\n- **PCIe插槽要求**\n  - **建议**：使用与FPGA设备要求匹配的兼容PCIe插槽（例如，x1、x4）。\n  - **理由**：确保与主机系统的最佳性能和兼容性。\n\n### **3.3 系统要求**\n\n- **主机系统**\n  - **处理器**：多核CPU（Intel i5/i7或AMD等效）\n  - **内存**：至少16 GB RAM\n  - **存储**：至少有100 GB可用空间的SSD\n  - **操作系统**：Windows 10/11（64位）或兼容的Linux发行版\n- **外围设备**\n  - **JTAG编程器**：用于将固件烧录到FPGA\n  - **PCIe插槽**：确保主机系统有一个兼容DMA卡的可用PCIe插槽\n\n---\n\n## **4. 要求**\n\n### **4.1 硬件**\n\n- **捐赠PCIe设备**\n  - **目的**：用于仿真提取设备ID和配置数据的来源。\n  - **示例**：网络适配器、存储控制器或任何未使用的通用PCIe卡。\n- **DMA FPGA卡**\n  - **描述**：能够执行DMA操作的基于FPGA的设备。\n  - **示例**：Squirrel（35T）、Enigma-X1（75T）、ZDMA（100T）、Kintex-7\n- **JTAG编程器**\n  - **目的**：用于将固件烧录到FPGA上。\n  - **示例**：Xilinx Platform Cable USB II、Digilent JTAG-HS3\n\n### **4.2 软件**\n\n- **Xilinx Vivado设计套件**\n  - **描述**：用于综合和构建固件项目的FPGA开发软件。\n  - **下载**：[Xilinx Vivado](https://www.xilinx.com/support/download.html)\n- **Visual Studio Code**\n  - **描述**：用于编辑Verilog或VHDL代码的代码编辑器。\n  - **下载**：[Visual Studio Code](https://code.visualstudio.com/)\n- **PCILeech-FPGA**\n  - **描述**：用于DMA固件开发的代码库和基础代码。\n  - **代码库**：[PCILeech-FPGA在GitHub上](https://github.com/ufrisk/pcileech-fpga)\n- **Arbor**\n  - **描述**：用于收集设备信息的PCIe设备扫描工具。\n  - **下载**：[Arbor by MindShare](https://www.mindshare.com/software/Arbor)\n  - **注意**：需要创建账户；提供14天试用。\n- **替代工具**\n  - **Telescan PE**\n    - **描述**：作为Arbor替代的PCIe流量分析工具。\n    - **下载**：[Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n    - **注意**：免费但需要手动注册批准。\n\n### **4.3 环境设置**\n\n#### **4.3.1 安装Xilinx Vivado设计套件**\n\n- **步骤**：\n\n  1. 访问[Xilinx Vivado下载页面](https://www.xilinx.com/support/download.html)。\n  2. 下载与您的FPGA设备兼容的适当版本。\n  3. 运行安装程序并按照屏幕指示进行操作。\n  4. 在安装过程中选择必要的组件。\n  5. 启动Vivado以确保正确安装。\n\n#### **4.3.2 安装Visual Studio Code**\n\n- **步骤**：\n\n  1. 访问[Visual Studio Code下载页面](https://code.visualstudio.com/)。\n  2. 下载并安装适用于您的操作系统的版本。\n  3. 安装支持Verilog或VHDL的扩展（例如，**Verilog-HDL/SystemVerilog**）。\n\n#### **4.3.3 克隆PCILeech-FPGA代码库**\n\n- **步骤**：\n\n  1. 打开终端或命令提示符。\n  2. 导航到您想要的目录：\n\n     ```bash\n     cd ~/Projects/\n     ```\n\n  3. 克隆代码库：\n\n     ```bash\n     git clone https://github.com/ufrisk/pcileech-fpga.git\n     ```\n\n  4. 进入克隆的目录：\n\n     ```bash\n     cd pcileech-fpga\n     ```\n\n#### **4.3.4 设置干净的开发环境**\n\n- **建议**：在隔离的环境中工作，以防止意外的交互。\n- **步骤**：\n\n  1. 使用专用的开发机器或虚拟机。\n  2. 确保没有其他应用程序干扰PCIe操作或FPGA编程。\n\n---\n\n## **5. 收集捐赠设备信息**\n\n准确的设备仿真依赖于仔细提取并复制捐赠设备的关键信息。全面的数据收集使您的FPGA能够忠实地模仿目标硬件的PCIe配置和行为，确保与主机系统的兼容性和功能。\n\n### **5.1 使用Arbor进行PCIe设备扫描**\n\n**Arbor**是一款功能强大且用户友好的工具，专为深入扫描PCIe设备而设计。它提供了连接硬件的配置空间的详细见解，使其成为提取设备仿真所需信息的宝贵资源。\n\n#### **5.1.1 安装Arbor**\n\n要开始使用Arbor进行设备扫描，您必须首先在系统上安装该软件。\n\n**步骤**：\n\n1. **访问Arbor下载页面**：\n\n   - 使用您的首选浏览器，导航到官方[Arbor下载页面](https://www.mindshare.com/software/Arbor)。\n   - 确保您直接访问该网站，以避免任何恶意重定向。\n\n2. **创建账户（如果需要）**：\n\n   - Arbor可能需要您创建用户账户以访问下载链接。\n   - 提供必要的信息，例如您的姓名、电子邮件地址和组织。\n   - 如果提示，请验证您的电子邮件以激活账户。\n\n3. **下载Arbor**：\n\n   - 登录后，找到Arbor的下载部分。\n   - 选择与您的操作系统兼容的版本（例如，Windows 10/11 64位）。\n   - 点击**下载**按钮，将安装程序保存到计算机上的已知位置。\n\n4. **安装Arbor**：\n\n   - 找到下载的安装程序文件（例如，`ArborSetup.exe`）。\n   - 右键单击安装程序，选择**以管理员身份运行**，以确保其具有必要的权限。\n   - 按照屏幕上的指示完成安装过程。\n     - 接受许可协议。\n     - 选择安装目录。\n     - 如果需要，可选择创建桌面快捷方式。\n\n5. **验证安装**：\n\n   - 完成后，确保Arbor列在您的开始菜单或桌面上。\n   - 启动Arbor，确认其无错误打开。\n\n#### **5.1.2 扫描PCIe设备**\n\n安装Arbor后，您可以继续扫描系统中连接的PCIe设备。\n\n**步骤**：\n\n1. **启动Arbor**：\n\n   - 双击桌面上的Arbor图标，或通过开始菜单找到它。\n   - 如果用户帐户控制（UAC）提示，请允许应用程序对您的设备进行更改。\n\n2. **导航到本地系统选项卡**：\n\n   - 在Arbor界面中，找到导航窗格或选项卡。\n   - 点击**Local System**以访问扫描本地计算机的工具。\n\n3. **扫描PCIe设备**：\n\n   - 找到通常位于界面顶部或底部的**Scan**或**Rescan**按钮。\n   - 点击**Scan/Rescan**以启动检测过程。\n   - 等待扫描过程完成；根据连接的设备数量，这可能需要一些时间。\n\n4. **查看检测到的设备**：\n\n   - 扫描完成后，Arbor将显示所有检测到的PCIe设备列表。\n   - 设备通常以其名称、设备ID和其他识别信息列出。\n\n#### **5.1.3 识别捐赠设备**\n\n正确识别捐赠设备对于准确的仿真至关重要。\n\n**步骤**：\n\n1. **在列表中找到您的捐赠设备**：\n\n   - 滚动浏览Arbor检测到的设备列表。\n   - 查找与您的捐赠硬件型号匹配的设备。\n   - 设备可能按供应商名称、设备类型或功能列出。\n\n2. **验证设备详细信息**：\n\n   - 点击设备以选择它。\n   - 确认**设备ID**和**供应商ID**与您的捐赠设备匹配。\n     - **提示**：这些ID通常可以在设备的文档或制造商的网站上找到。\n\n3. **查看详细配置**：\n\n   - 选择设备后，找到并点击**查看详细信息**或**属性**等选项。\n   - 这将打开一个详细视图，显示设备的配置空间和功能。\n\n4. **与物理硬件进行交叉引用**：\n\n   - 如果列出了多个类似的设备，请将**插槽编号**或**总线地址**与安装捐赠设备的物理插槽进行比较。\n\n#### **5.1.4 捕获设备数据**\n\n从捐赠设备中提取详细信息对于准确的仿真至关重要。\n\n**要提取的信息**：\n\n- **设备ID（0xXXXX）**：\n  - 一个唯一的16位设备型号标识符。\n- **供应商ID（0xYYYY）**：\n  - 分配给制造商的16位标识符。\n- **子系统ID（0xZZZZ）**：\n  - 标识特定的子系统或变体。\n- **子系统供应商ID（0xWWWW）**：\n  - 标识子系统的供应商。\n- **修订ID（0xRR）**：\n  - 指示设备的修订级别。\n- **类代码（0xCCCCCC）**：\n  - 定义设备类型的24位代码（例如，网络控制器、存储设备）。\n- **基地址寄存器（BARs）**：\n  - 定义设备使用的内存或I/O空间的寄存器。\n  - 包括BAR0到BAR5，每个可能为32位或64位。\n- **功能**：\n  - 列出支持的功能，如MSI/MSI-X、电源管理、PCIe链路速度和宽度。\n- **设备序列号（DSN）**：\n  - 如果设备支持，则为64位唯一标识符。\n\n**步骤**：\n\n1. **导航到PCI配置选项卡**：\n\n   - 在设备的详细视图中，找到并选择**PCI Config**或**Configuration Space**选项卡。\n\n2. **记录相关细节**：\n\n   - 仔细记录每个所需的字段。\n   - 为了准确性，可以使用截图或将值复制到文本文件或电子表格中。\n   - 确保十六进制值记录正确，包括`0x`前缀（如果使用）。\n\n3. **展开功能列表**：\n\n   - 查找标记为**Capabilities**或**Advanced Features**的部分。\n   - 记录每个功能及其参数（例如，MSI数量、支持的电源状态）。\n\n4. **详细检查BARs**：\n\n   - 对于每个BAR，注意：\n     - **BAR编号（例如，BAR0）**：\n     - **类型（内存或I/O）**：\n     - **位宽（32位或64位）**：\n     - **大小（例如，256 MB）**：\n     - **可预取状态（是/否）**：\n\n5. **保存数据以供参考**：\n\n   - 将所有信息编入组织良好的文档中。\n   - 清晰地标记每个部分，便于在固件定制期间参考。\n\n6. **仔细检查条目**：\n\n   - 重新检查所有记录的数据以确保准确性。\n   - 通过重新访问Arbor界面，纠正任何差异。\n\n### **5.2 提取和记录设备属性**\n\n在捕获数据后，理解每个属性的意义并确保其已被准确记录至关重要。\n\n**确保您已准确记录以下内容**：\n\n1. **设备ID**：\n\n   - **目的**：唯一标识设备型号。\n   - **用途**：对于主机操作系统加载正确的驱动程序至关重要。\n\n2. **供应商ID**：\n\n   - **目的**：标识制造商。\n   - **用途**：与设备ID一起用于匹配设备驱动程序。\n\n3. **子系统ID和子系统供应商ID**：\n\n   - **目的**：指定子系统的设备和供应商ID，允许区分变体。\n   - **用途**：对于具有多种配置或OEM特定版本的设备很重要。\n\n4. **修订ID**：\n\n   - **目的**：指示硬件修订版本。\n   - **用途**：有助于识别可能需要不同驱动程序或固件的特定硬件版本。\n\n5. **类代码**：\n\n   - **目的**：对设备类型进行分类（例如，大容量存储、网络控制器）。\n   - **用途**：允许操作系统了解设备的主要功能。\n\n6. **基地址寄存器（BARs）**：\n\n   - **目的**：定义设备将使用的内存或I/O地址区域。\n   - **用途**：对于将设备内存映射到系统地址空间至关重要。\n\n7. **功能**：\n\n   - **目的**：列出设备支持的高级功能。\n   - **示例**：\n     - **MSI/MSI-X**：用于高效中断处理的消息信号中断。\n     - **电源管理**：如D0、D1、D2、D3hot、D3cold状态。\n     - **PCIe链路速度/宽度**：确定数据传输能力。\n\n8. **设备序列号（DSN）**：\n\n   - **目的**：设备的唯一64位标识符。\n   - **用途**：用于高级识别，可能是某些驱动程序所必需的。\n\n**最佳实践**：\n\n- **组织数据**：\n\n  - 创建一个结构化的文档或电子表格。\n  - 使用清晰的标题和子标题标记每个属性。\n\n- **包括单位和格式**：\n\n  - 指明大小的单位（例如，MB、KB）。\n  - 对十六进制值使用一致的格式（例如，`0x1234`）。\n\n- **与规格交叉引用**：\n\n  - 如果可用，请查阅设备的数据表以验证值。\n  - 这有助于识别任何差异或不寻常的配置。\n\n- **保护数据**：\n\n  - 安全地存储收集的信息。\n  - 注意任何专有或机密信息。\n\n---\n\n## **6. 初始固件定制**\n\n在详细记录了捐赠设备的信息后，下一步是定制您的FPGA固件，以准确仿真捐赠设备。这涉及修改PCIe配置空间，并确保内存映射正确对齐。\n\n### **6.1 修改配置空间**\n\nPCIe配置空间是定义设备如何被识别和与主机系统交互的关键组件。将此空间定制为匹配捐赠设备对于成功的仿真至关重要。\n\n#### **6.1.1 导航到配置文件**\n\n配置空间在您的项目中定义在特定的SystemVerilog（.sv）文件中。\n\n**路径**：\n\n- **标准路径**：\n\n  ```\n  pcileech-fpga/pcileech-wifi-main/src/pcileech_pcie_cfg_a7.sv\n  ```\n\n- **备用路径（取决于目录结构）**：\n\n  ```\n  pcileech-fpga/src/pcileech_pcie_cfg_a7.sv\n  ```\n\n**注意**：\n\n- 确保您位于正确的项目目录中。\n- 文件名可能会根据FPGA型号略有变化（例如，`_a7`表示Artix-7系列）。\n\n#### **6.1.2 在Visual Studio Code中打开文件**\n\n编辑配置文件需要一个支持SystemVerilog语法高亮的合适代码编辑器。\n\n**步骤**：\n\n1. **启动Visual Studio Code**：\n\n   - 点击VS Code图标，或通过开始菜单找到它。\n\n2. **打开文件**：\n\n   - 使用**文件 > 打开文件**，或按`Ctrl + O`。\n   - 导航到上述的配置文件路径。\n   - 选择`pcileech_pcie_cfg_a7.sv`，然后点击**打开**。\n\n3. **验证语法高亮**：\n\n   - 确保编辑器识别`.sv`文件扩展名。\n   - 如果需要，安装支持SystemVerilog的扩展。\n\n4. **熟悉文件结构**：\n\n   - 滚动浏览文件，了解现有的赋值和注释。\n   - 查找定义配置寄存器的部分。\n\n#### **6.1.3 修改设备ID和供应商ID**\n\n更新这些标识符对于主机系统将仿真设备识别为捐赠设备至关重要。\n\n**步骤**：\n\n1. **搜索`cfg_deviceid`**：\n\n   - 使用搜索功能（`Ctrl + F`）。\n   - 找到定义`cfg_deviceid`的行。\n\n2. **更新设备ID**：\n\n   ```verilog\n   cfg_deviceid <= 16'hXXXX;  // 用捐赠设备的设备ID替换XXXX\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的设备ID是`0x1234`，则更新为：\n\n       ```verilog\n       cfg_deviceid <= 16'h1234;\n       ```\n\n3. **搜索`cfg_vendorid`**：\n\n   - 找到定义`cfg_vendorid`的行。\n\n4. **更新供应商ID**：\n\n   ```verilog\n   cfg_vendorid <= 16'hYYYY;  // 用捐赠设备的供应商ID替换YYYY\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的供应商ID是`0xABCD`，则更新为：\n\n       ```verilog\n       cfg_vendorid <= 16'hABCD;\n       ```\n\n5. **确保正确的格式**：\n\n   - 确认十六进制值以`16'h`为前缀。\n   - 保持一致的缩进和注释风格。\n\n#### **6.1.4 修改子系统ID和修订ID**\n\n这些标识符提供有关设备变体和硬件修订的其他详细信息。\n\n**步骤**：\n\n1. **搜索`cfg_subsysid`**：\n\n   - 找到定义`cfg_subsysid`的行。\n\n2. **更新子系统ID**：\n\n   ```verilog\n   cfg_subsysid <= 16'hZZZZ;  // 用捐赠设备的子系统ID替换ZZZZ\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的子系统ID是`0x5678`，则更新为：\n\n       ```verilog\n       cfg_subsysid <= 16'h5678;\n       ```\n\n3. **搜索`cfg_subsysvendorid`**：\n\n   - 找到定义`cfg_subsysvendorid`的行。\n\n4. **更新子系统供应商ID（如果适用）**：\n\n   ```verilog\n   cfg_subsysvendorid <= 16'hWWWW;  // 用捐赠设备的子系统供应商ID替换WWWW\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的子系统供应商ID是`0x9ABC`，则更新为：\n\n       ```verilog\n       cfg_subsysvendorid <= 16'h9ABC;\n       ```\n\n5. **搜索`cfg_revisionid`**：\n\n   - 找到定义`cfg_revisionid`的行。\n\n6. **更新修订ID**：\n\n   ```verilog\n   cfg_revisionid <= 8'hRR;   // 用捐赠设备的修订ID替换RR\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的修订ID是`0x01`，则更新为：\n\n       ```verilog\n       cfg_revisionid <= 8'h01;\n       ```\n\n#### **6.1.5 更新类代码**\n\n类代码告知主机设备的类型和功能。\n\n**步骤**：\n\n1. **搜索`cfg_classcode`**：\n\n   - 找到定义`cfg_classcode`的行。\n\n2. **更新类代码**：\n\n   ```verilog\n   cfg_classcode <= 24'hCCCCCC;  // 用捐赠设备的类代码替换CCCCCC\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的类代码是`0x020000`（以太网控制器），则更新为：\n\n       ```verilog\n       cfg_classcode <= 24'h020000;\n       ```\n\n3. **验证正确的位宽**：\n\n   - 确保类代码是24位值。\n   - 十六进制值应以`24'h`为前缀。\n\n#### **6.1.6 保存更改**\n\n在进行所有修改后，保存并查看更改非常重要。\n\n**步骤**：\n\n1. **保存文件**：\n\n   - 点击**文件 > 保存**，或按`Ctrl + S`。\n\n2. **查看更改**：\n\n   - 重新阅读修改的行以确认准确性。\n   - 检查是否有任何语法错误或拼写错误。\n\n3. **可选 - 使用版本控制**：\n\n   - 如果使用Git或其他版本控制系统，用有意义的消息提交您的更改。\n\n     - **示例**：\n\n       ```\n       git add pcileech_pcie_cfg_a7.sv\n       git commit -m \"更新PCIe配置，包含捐赠设备标识符\"\n       ```\n\n### **6.2 插入设备序列号（DSN）**\n\n设备序列号（DSN）是某些设备用于高级功能的唯一标识符。包括它可增强仿真的真实性。\n\n#### **6.2.1 找到DSN字段**\n\nDSN通常在同一配置文件中定义。\n\n**步骤**：\n\n1. **搜索`cfg_dsn`**：\n\n   - 在`pcileech_pcie_cfg_a7.sv`中，使用搜索功能（`Ctrl + F`）查找`cfg_dsn`。\n\n2. **了解现有赋值**：\n\n   - DSN可能设置为默认值或清零。\n\n     ```verilog\n     cfg_dsn <= 64'h0000000000000000;  // 默认DSN\n     ```\n\n#### **6.2.2 插入DSN**\n\n更新DSN涉及将其设置为捐赠设备的确切值。\n\n**步骤**：\n\n1. **更新`cfg_dsn`**：\n\n   ```verilog\n   cfg_dsn <= 64'hXXXXXXXX_YYYYYYYY;  // 用捐赠设备的DSN替换\n   ```\n\n   - **示例**：\n     - 如果捐赠设备的DSN是`0x0011223344556677`，则更新为：\n\n       ```verilog\n       cfg_dsn <= 64'h0011223344556677;\n       ```\n\n2. **处理DSN不可用的情况**：\n\n   - 如果捐赠设备没有DSN或不需要DSN，将其设置为零：\n\n     ```verilog\n     cfg_dsn <= 64'h0000000000000000;  // 无DSN\n     ```\n\n3. **确保正确的格式**：\n\n   - DSN是一个64位值；确保其格式正确。\n   - 对十六进制值使用`64'h`前缀。\n\n4. **添加注释以增加清晰度**：\n\n   - 包括一条注释，指明DSN的来源。\n\n     ```verilog\n     cfg_dsn <= 64'h0011223344556677;  // 捐赠设备的DSN\n     ```\n\n#### **6.2.3 保存更改**\n\n通过保存和查看，完成修改。\n\n**步骤**：\n\n1. **保存文件**：\n\n   - 点击**文件 > 保存**，或按`Ctrl + S`。\n\n2. **验证语法**：\n\n   - 查找编辑器中的任何红色下划线或错误指示。\n   - 在继续之前，纠正任何问题。\n\n3. **记录更改**：\n\n   - 如果使用版本控制，请用适当的消息提交更新。\n\n     - **示例**：\n\n       ```\n       git commit -am \"在配置中插入捐赠设备的序列号（DSN）\"\n       ```\n\n---\n\n## **7. Vivado项目设置和定制**\n\n在将固件文件更新为反映捐赠设备的配置后，下一步是将这些更改集成到Vivado项目中。这涉及生成项目文件、定制IP核，并为综合和实现准备设计。\n\n### **7.1 生成Vivado项目文件**\n\nVivado使用Tcl脚本自动创建和配置项目。通过运行这些脚本，您可以确保所有设置都根据您的FPGA设备正确应用。\n\n#### **7.1.1 打开Vivado**\n\n从一个新的Vivado会话开始，确保先前的设置或项目不会干扰您当前的工作。\n\n**步骤**：\n\n1. **启动Vivado**：\n\n   - 在开始菜单或桌面上找到Vivado应用程序。\n   - 点击打开它。\n\n2. **选择正确的版本**：\n\n   - 如果安装了多个版本，确保您使用的版本与您的FPGA兼容（例如，Vivado 2020.1）。\n\n3. **等待启动屏幕**：\n\n   - 允许Vivado完全初始化，然后再继续。\n\n#### **7.1.2 访问Tcl控制台**\n\nTcl控制台允许您直接执行脚本和命令。\n\n**步骤**：\n\n1. **打开Tcl控制台**：\n\n   - 在Vivado界面中，转到菜单栏。\n   - 点击**窗口** > **Tcl控制台**。\n   - Tcl控制台将出现在窗口底部。\n\n2. **调整控制台大小（可选）**：\n\n   - 拖动控制台的顶部边框，以调整其大小，便于查看。\n\n3. **清除先前的命令**：\n\n   - 如果存在任何命令，您可以清除它们，以便干净地开始。\n\n#### **7.1.3 导航到项目目录**\n\n确保Tcl控制台指向您的项目脚本所在的正确目录。\n\n**对于Squirrel DMA（35T）**：\n\n**路径**：\n\n- 您的项目目录，通常是：\n\n  ```\n  C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-wifi-main/\n  ```\n\n**步骤**：\n\n1. **设置工作目录**：\n\n   - 在Tcl控制台中输入：\n\n     ```tcl\n     cd C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-wifi-main/\n     ```\n\n     - 用您系统上的实际位置替换路径。\n\n2. **验证目录更改**：\n\n   - 在Tcl控制台中输入`pwd`。\n   - 控制台应显示当前目录，确认更改。\n\n#### **7.1.4 生成Vivado项目**\n\n运行适当的Tcl脚本将设置项目，包含所有必要的配置。\n\n**步骤**：\n\n1. **运行Tcl脚本**：\n\n   - 对于**Squirrel（35T）**：\n\n     ```tcl\n     source vivado_generate_project_squirrel.tcl -notrace\n     ```\n\n   - 对于**Enigma-X1（75T）**：\n\n     ```tcl\n     source vivado_generate_project_enigma_x1.tcl -notrace\n     ```\n\n   - 对于**ZDMA（100T）**：\n\n     ```tcl\n     source vivado_generate_project_100t.tcl -notrace\n     ```\n\n2. **等待脚本完成**：\n\n   - 该脚本将执行多个命令：\n     - 创建项目。\n     - 添加源文件。\n     - 配置项目设置。\n   - 监视Tcl控制台的进度消息。\n   - 解决可能出现的任何错误，例如缺少文件或路径不正确。\n\n3. **确认项目生成**：\n\n   - 完成后，控制台将指示项目已创建。\n   - 项目文件（`.xpr`和相关目录）将出现在项目目录中。\n\n#### **7.1.5 打开生成的项目**\n\n现在项目已生成，您可以在Vivado中打开它以进行进一步的定制。\n\n**步骤**：\n\n1. **打开项目**：\n\n   - 在Vivado中，点击**文件** > **打开项目**。\n   - 导航到您的项目目录。\n\n2. **选择项目文件**：\n\n   - 对于**Squirrel**：\n\n     ```\n     pcileech_squirrel_top.xpr\n     ```\n\n   - 点击`.xpr`文件以选择它。\n\n3. **点击打开**：\n\n   - Vivado将加载项目，显示设计层次结构和源文件。\n\n4. **验证项目内容**：\n\n   - 在**项目管理器**窗口中，确保所有源文件都列出。\n   - 检查打开时是否有任何警告或错误。\n\n### **7.2 修改IP模块**\n\nPCIe IP核是一个关键组件，必须配置以匹配捐赠设备的规格。定制IP核可确保FPGA在PCIe协议级别与捐赠硬件的行为相同。\n\n#### **7.2.1 访问PCIe IP核**\n\nPCIe IP核是在您的Vivado项目中实例化的IP模块。\n\n**步骤**：\n\n1. **找到PCIe IP核**：\n\n   - 在**源文件**窗格中，确保选择了**层次结构**选项卡。\n   - 展开设计层次结构，找到PCIe IP核。\n     - 通常命名为`pcie_7x_0.xci`或类似名称。\n\n2. **打开IP定制窗口**：\n\n   - 右键点击`pcie_7x_0.xci`。\n   - 从上下文菜单中选择**定制IP**。\n   - **IP配置**窗口将打开。\n\n3. **等待IP设置加载**：\n\n   - IP定制界面可能需要一些时间初始化。\n   - 在继续之前，确保所有选项和选项卡都已完全加载。\n\n#### **7.2.2 定制设备ID和BARs**\n\n在IP核中配置设备标识符对于主机系统正确枚举设备至关重要。\n\n**步骤**：\n\n1. **导航到设备和供应商标识符**：\n\n   - 在IP定制窗口中，选择**设备和供应商标识符**选项卡或部分。\n\n2. **输入设备ID**：\n\n   - 找到标记为**Device ID**的字段。\n   - 输入捐赠设备的设备ID（例如，`0x1234`）。\n\n3. **输入供应商ID**：\n\n   - 找到**Vendor ID**字段。\n   - 输入捐赠设备的供应商ID（例如，`0xABCD`）。\n\n4. **输入子系统ID和子系统供应商ID**：\n\n   - 输入**Subsystem ID**（例如，`0x5678`）。\n   - 输入**Subsystem Vendor ID**（例如，`0x9ABC`）。\n\n5. **设置修订ID**：\n\n   - 输入**Revision ID**（例如，`0x01`）。\n\n6. **设置类代码**：\n\n   - 输入**Class Code**（例如，`0x020000`用于以太网控制器）。\n\n7. **配置其他标识符（如果可用）**：\n\n   - 一些IP核允许设置**编程接口**、**设备功能**等。\n   - 根据需要将其与捐赠设备匹配。\n\n#### **7.2.3 配置BAR大小**\n\nBAR定义了设备如何将其内部内存和寄存器映射到主机系统。\n\n**步骤**：\n\n1. **导航到基地址寄存器（BARs）**：\n\n   - 在IP定制窗口中，选择**BARs**选项卡或部分。\n\n2. **配置每个BAR**：\n\n   - 对于**BAR0**到**BAR5**，根据捐赠设备设置以下参数：\n\n     - **启用BAR**：选中或取消选中以匹配捐赠设备。\n     - **BAR大小**：从下拉列表中选择大小（例如，**256 MB**、**64 KB**）。\n     - **BAR类型**：\n       - **内存（32位寻址）**\n       - **内存（64位寻址）**\n       - **I/O**\n     - **可预取**：如果捐赠设备的BAR可预取，则选中。\n\n3. **示例配置**：\n\n   - **BAR0**：\n     - 已启用\n     - 大小：**256 MB**\n     - 类型：**内存（64位）**\n     - 可预取：**是**\n   - **BAR1**：\n     - 已禁用（如果捐赠设备不使用BAR1）\n\n4. **确保对齐和不重叠空间**：\n\n   - 确认映射的总内存不超过FPGA的能力。\n   - 确保BAR大小符合PCIe规范要求。\n\n5. **高级设置（如果适用）**：\n\n   - 某些设备可能有特殊要求，如扩展ROM BAR。\n   - 如果必要，配置这些设置。\n\n#### **7.2.4 完成IP定制**\n\n在配置所有必要的设置后，您需要应用更改。\n\n**步骤**：\n\n1. **审查所有设置**：\n\n   - 浏览IP定制窗口中的每个选项卡。\n   - 确认所有条目与捐赠设备的规格相匹配。\n\n2. **应用更改**：\n\n   - 点击**OK**或**Generate**以应用设置。\n   - 如果提示，确认您希望继续更改。\n\n3. **重新生成IP核**：\n\n   - Vivado将重新生成IP核以反映新配置。\n   - 监视**消息**窗格以获取任何错误或警告。\n\n4. **更新项目中的IP**：\n\n   - 确保更新的IP核已正确集成到您的项目中。\n   - Vivado可能会提示更新IP依赖项；允许其执行此操作。\n\n#### **7.2.5 锁定IP核**\n\n锁定IP核可防止在综合和实现期间的意外更改。\n\n**目的**：\n\n- **防止覆盖**：确保您的手动配置被保留。\n- **保持一致性**：在整个构建过程中保持IP核处于已知状态。\n\n**步骤**：\n\n1. **打开Tcl控制台**：\n\n   - 在Vivado中，如果尚未打开，转到**窗口** > **Tcl控制台**。\n\n2. **执行锁定命令**：\n\n   - 输入以下命令：\n\n     ```tcl\n     set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n     ```\n\n   - 按**Enter**执行。\n\n3. **验证锁定**：\n\n   - 检查**消息**窗格以确认。\n   - IP核现在应标记为已锁定。\n\n4. **解锁（如有必要）**：\n\n   - 要在将来进行进一步更改，可以解锁IP核：\n\n     ```tcl\n     set_property -name {IP_LOCKED} -value false -objects [get_ips pcie_7x_0]\n     ```\n\n   - 记得在进行更改后重新锁定它。\n\n5. **记录操作**：\n\n   - 在您的项目文档中注明IP核已被锁定。\n   - 这有助于团队成员了解项目的配置状态。\n\n---\n\n### **第2部分：中级概念与实现**\n\n---\n\n## **8. 高级固件定制**\n\n为了实现对捐赠设备的精确仿真，需要进一步深入定制固件。这包括调整PCIe参数、调整基地址寄存器（BARs）、以及仿真电源管理和中断机制，以匹配捐赠设备的规格。这些步骤确保仿真设备能够与主机系统无缝交互，其行为与原始硬件完全一致。\n\n### **8.1 为仿真配置PCIe参数**\n\n准确的仿真要求您的FPGA设备的PCIe参数与捐赠设备精确匹配。这包括设置如PCIe链路速度、链路宽度、能力指针和最大有效载荷大小等。正确的配置确保与主机系统的兼容性，以及与设备驱动程序和应用程序的正确交互。\n\n#### **8.1.1 匹配PCIe链路速度和宽度**\n\nPCIe链路速度和宽度是决定设备数据吞吐量和性能的关键参数。匹配这些设置对于准确仿真至关重要。\n\n**步骤**：\n\n1. **访问PCIe IP核设置**：\n\n   - **打开您的Vivado项目**：\n     - 启动Vivado并打开您之前创建或修改的项目。\n     - 确保所有源文件都已正确添加到项目中。\n\n   - **找到PCIe IP核**：\n     - 在**源文件**窗格中，展开层次结构，找到PCIe IP核实例，通常命名为`pcie_7x_0`。\n     - 与IP核关联的文件通常是`pcie_7x_0.xci`。\n\n   - **定制IP核**：\n     - 右键点击`pcie_7x_0.xci`，选择**定制IP**。\n     - IP配置窗口将打开，显示各种配置选项。\n\n2. **设置最大链路速度**：\n\n   - **导航到链路参数**：\n     - 在IP配置窗口中，点击**Link Parameters**选项卡或部分。\n     - 该部分包含与PCIe链路特性相关的设置。\n\n   - **配置最大链路速度**：\n     - 找到**Maximum Link Speed**选项。\n     - 设置为与捐赠设备的链路速度相匹配。\n       - **示例**：\n         - 如果捐赠设备以**Gen2（5.0 GT/s）**运行，选择**5.0 GT/s**。\n         - 如果以**Gen1（2.5 GT/s）**或**Gen3（8.0 GT/s）**运行，选择相应的选项。\n       - **注意**：确保您的FPGA和物理硬件支持所选的链路速度。\n\n3. **设置链路宽度**：\n\n   - **配置链路宽度**：\n     - 在同一**Link Parameters**部分，找到**Link Width**设置。\n     - 设置为与捐赠设备的链路宽度相匹配。\n       - **示例**：\n         - 如果捐赠设备使用**x4**链路，将**Link Width**设置为**4**。\n         - 选项通常包括**1**、**2**、**4**、**8**、**16**通道。\n       - **注意**：物理连接器和FPGA必须支持所选的链路宽度。\n\n4. **保存并重新生成**：\n\n   - **应用更改**：\n     - 配置链路速度和宽度后，点击**OK**应用更改。\n     - Vivado可能提示您由于更改需要重新生成IP核。\n     - 确认并允许重新生成过程完成。\n\n   - **验证设置**：\n     - 重新生成完成后，重新查看IP核设置，确保配置已正确应用。\n     - 检查**消息**窗口中的任何警告或错误。\n\n#### **8.1.2 设置能力指针**\n\nPCIe配置空间中的能力指针指向各种能力结构，如MSI、电源管理等。正确设置这些指针确保主机系统能够找到并利用设备的功能。\n\n**步骤**：\n\n1. **在固件中找到能力指针**：\n\n   - **打开配置文件**：\n     - 在Visual Studio Code中，打开`pcileech_pcie_cfg_a7.sv`文件，位于：\n\n       ```\n       pcileech-fpga/pcileech-wifi-main/src/pcileech_pcie_cfg_a7.sv\n       ```\n\n   - **了解能力指针**：\n     - 能力指针是一个8位寄存器，指向PCIe配置空间中的第一个能力结构，通常从标准配置头之后开始。\n\n2. **设置能力指针值**：\n\n   - **找到`cfg_cap_pointer`的赋值**：\n     - 搜索代码中`cfg_cap_pointer`的定义行。\n\n       ```verilog\n       cfg_cap_pointer <= 8'hXX; // 当前值\n       ```\n\n   - **更新能力指针**：\n     - 将`XX`替换为捐赠设备的能力指针值。\n       - **示例**：\n         - 如果捐赠设备的能力指针是`0x60`，则更新为：\n\n           ```verilog\n           cfg_cap_pointer <= 8'h60; // 更新以匹配捐赠设备\n           ```\n\n     - **确保正确对齐**：\n       - 能力结构必须在4字节边界上对齐。\n       - 能力指针应指向配置空间内的有效偏移量。\n\n3. **保存更改**：\n\n   - **保存配置文件**：\n     - 进行更改后，点击**文件 > 保存**或按`Ctrl + S`保存文件。\n\n   - **验证语法**：\n     - 确保更改未引入语法错误。\n\n   - **添加注释以增加清晰度**：\n     - 添加注释，说明更改的原因，便于将来参考。\n\n       ```verilog\n       cfg_cap_pointer <= 8'h60; // 设置为捐赠设备在偏移量0x60的能力指针\n       ```\n\n#### **8.1.3 调整最大有效载荷和读取请求大小**\n\n这些参数定义了在单个PCIe事务中可以传输的最大数据量。与捐赠设备匹配这些设置可确保兼容性和最佳性能。\n\n**步骤**：\n\n1. **设置最大有效载荷大小**：\n\n   - **访问设备功能**：\n     - 在PCIe IP核定制窗口中，导航到**Device Capabilities**或**Capabilities**选项卡。\n\n   - **配置支持的最大有效载荷大小**：\n     - 找到**Max Payload Size Supported**设置。\n     - 将其设置为捐赠设备支持的值。\n       - **选项**：\n         - **128字节**、**256字节**、**512字节**、**1024字节**、**2048字节**、**4096字节**。\n       - **示例**：\n         - 如果捐赠设备支持最大有效载荷大小为**256字节**，请选择**256字节**。\n\n2. **设置最大读取请求大小**：\n\n   - **配置支持的最大读取请求大小**：\n     - 在同一选项卡中，找到**Max Read Request Size Supported**设置。\n     - 将其设置为与捐赠设备的能力相匹配。\n       - **示例**：\n         - 如果捐赠设备支持最大读取请求大小为**512字节**，请选择**512字节**。\n\n3. **调整固件参数**：\n\n   - **打开`pcileech_pcie_cfg_a7.sv`**：\n     - 确保配置文件在Visual Studio Code中打开。\n\n   - **更新固件常量**：\n     - 找到定义`max_payload_size_supported`和`max_read_request_size_supported`的行。\n\n       ```verilog\n       max_payload_size_supported <= 3'bZZZ; // 当前值\n       max_read_request_size_supported <= 3'bWWW; // 当前值\n       ```\n\n   - **设置适当的值**：\n     - 将`ZZZ`和`WWW`替换为大小的二进制表示。\n\n       - **映射关系**：\n         - **128字节**：`3'b000`\n         - **256字节**：`3'b001`\n         - **512字节**：`3'b010`\n         - **1024字节**：`3'b011`\n         - **2048字节**：`3'b100`\n         - **4096字节**：`3'b101`\n\n       - **示例**：\n         - 对于**256字节**的有效载荷大小：\n\n           ```verilog\n           max_payload_size_supported <= 3'b001; // 支持高达256字节\n           ```\n\n         - 对于**512字节**的读取请求大小：\n\n           ```verilog\n           max_read_request_size_supported <= 3'b010; // 支持高达512字节\n           ```\n\n4. **保存更改**：\n\n   - **保存文件**：\n     - 更新值后，保存文件。\n\n   - **验证一致性**：\n     - 确保固件中的值与PCIe IP核中配置的值匹配。\n\n   - **添加注释**：\n     - 记录更改，便于将来参考。\n\n       ```verilog\n       max_payload_size_supported <= 3'b001; // 根据捐赠设备支持256字节\n       max_read_request_size_supported <= 3'b010; // 根据捐赠设备支持512字节\n       ```\n\n### **8.2 调整BAR和内存映射**\n\n基地址寄存器（BARs）定义了设备向主机暴露的内存区域。正确配置BARs和内存映射对于准确仿真和设备驱动程序的正常运行至关重要。\n\n#### **8.2.1 设置BAR大小**\n\n配置BAR大小可确保设备在枚举期间请求正确的地址空间，并且主机正确映射这些区域。\n\n**步骤**：\n\n1. **访问BAR配置**：\n\n   - **定制PCIe IP核**：\n     - 在Vivado中，右键点击`pcie_7x_0.xci`，选择**定制IP**。\n\n   - **导航到BARs选项卡**：\n     - 在IP配置窗口中，点击**Base Address Registers (BARs)**选项卡。\n\n2. **配置BAR大小和类型**：\n\n   - **匹配捐赠设备的BARs**：\n     - 对于每个BAR（BAR0至BAR5），设置大小和类型以匹配捐赠设备。\n\n   - **设置BAR大小**：\n     - 从下拉菜单中为每个BAR选择适当的大小。\n       - **示例**：\n         - 如果**BAR0**是**64 KB**，将**BAR0 Size**设置为**64 KB**。\n         - 如果**BAR1**是**128 MB**，将**BAR1 Size**设置为**128 MB**。\n\n   - **设置BAR类型**：\n     - 为每个BAR选择**32位**或**64位**寻址。\n     - 指定BAR的类型是**内存**还是**I/O**。\n     - 根据捐赠设备设置**可预取**状态。\n\n   - **启用或禁用BARs**：\n     - 确保仅启用了捐赠设备使用的BARs。\n\n3. **更新BRAM配置**：\n\n   - **调整BRAM IP核**：\n     - 在`ip`目录中，找到与BARs对应的BRAM配置。\n\n       - **文件**：\n\n         ```\n         pcileech-fpga/pcileech-wifi-main/ip/bram_bar_zero4k.xci\n         pcileech-fpga/pcileech-wifi-main/ip/bram_pcie_cfgspace.xci\n         ```\n\n   - **修改BRAM大小**：\n     - 打开每个BRAM IP核，调整内存大小以匹配相应的BAR大小。\n     - 确保总内存不超过FPGA的容量。\n\n4. **保存并重新生成**：\n\n   - **应用更改**：\n     - 配置BARs并更新BRAM大小后，点击**OK**。\n\n   - **重新生成IP核**：\n     - Vivado可能会提示由于更改需要重新生成IP核。\n     - 允许重新生成完成。\n\n   - **检查错误**：\n     - 查看**消息**窗口中的任何与BAR配置相关的警告或错误。\n\n#### **8.2.2 在固件中定义BAR地址空间**\n\n设置BAR大小和类型后，您需要定义固件如何处理对这些BAR的访问。\n\n**步骤**：\n\n1. **打开BAR控制器文件**：\n\n   - **找到源文件**：\n     - 在Visual Studio Code中，打开：\n\n       ```\n       pcileech-fpga/pcileech-wifi-main/src/pcileech_tlps128_bar_controller.sv\n       ```\n\n2. **映射地址范围**：\n\n   - **定义地址解码逻辑**：\n     - 实现逻辑以检测何时访问BAR，基于地址。\n\n       ```verilog\n       always_comb begin\n         if (bar_hit[0]) begin\n           // 处理对BAR0的访问\n         end else if (bar_hit[1]) begin\n           // 处理对BAR1的访问\n         end\n         // 继续处理其他BAR\n       end\n       ```\n\n   - **实现BAR访问处理**：\n     - 对于每个BAR，定义如何管理读写操作。\n\n       - **示例**：\n\n         ```verilog\n         if (bar_hit[0]) begin\n           case (addr_offset)\n             16'h0000: data_out <= reg0;\n             16'h0004: data_out <= reg1;\n             // 其他寄存器\n             default: data_out <= 32'h0;\n           endcase\n         end\n         ```\n\n3. **实现地址解码逻辑**：\n\n   - **计算地址偏移量**：\n\n     ```verilog\n     addr_offset = incoming_address - bar_base_address[0];\n     ```\n\n   - **处理数据传输**：\n\n     ```verilog\n     if (cfg_write) begin\n       // 将数据写入适当的寄存器\n     end else if (cfg_read) begin\n       // 从适当的寄存器读取数据\n     end\n     ```\n\n4. **保存更改**：\n\n   - **保存文件**：\n     - 实现逻辑后，保存`pcileech_tlps128_bar_controller.sv`文件。\n\n   - **验证功能**：\n     - 确保逻辑正确处理所有可能的访问。\n\n#### **8.2.3 处理多个BAR**\n\n正确管理多个BAR对于暴露多个内存或I/O区域的设备至关重要。\n\n**步骤**：\n\n1. **为每个BAR实现逻辑**：\n\n   - **分离逻辑块**：\n     - 为了清晰起见，在控制器内为每个BAR创建单独的代码块。\n\n       ```verilog\n       // BAR0处理\n       if (bar_hit[0]) begin\n         // BAR0特定逻辑\n       end\n       // BAR1处理\n       if (bar_hit[1]) begin\n         // BAR1特定逻辑\n       end\n       ```\n\n   - **定义寄存器和内存**：\n     - 根据需要为每个BAR分配寄存器或内存块。\n\n2. **确保地址空间不重叠**：\n\n   - **验证地址范围**：\n     - 确认每个BAR的地址空间不重叠。\n     - 根据PCIe规范要求，将BAR大小对齐到2的幂边界。\n\n   - **更新地址解码**：\n     - 调整地址解码逻辑，以考虑每个BAR的大小和基地址。\n\n3. **测试BAR访问**：\n\n   - **仿真测试**：\n     - 使用仿真工具测试对每个BAR的读写操作。\n     - 验证读取或写入的数据是否正确。\n\n   - **硬件测试**：\n     - 编程FPGA，使用主机上的软件访问每个BAR。\n       - **示例**：\n         - 在Linux上使用`lspci`检查BAR映射。\n         - 编写执行内存映射I/O到BAR的测试程序。\n\n### **8.3 仿真设备电源管理和中断**\n\n仿真电源管理功能并实现中断对于需要与主机操作系统的电源和中断处理机制紧密交互的设备至关重要。\n\n#### **8.3.1 电源管理配置**\n\n实现电源管理允许设备支持各种电源状态，有助于系统范围的电源效率，并符合操作系统的期望。\n\n**步骤**：\n\n1. **在PCIe IP核中启用电源管理**：\n\n   - **访问功能选项**：\n     - 在PCIe IP核配置窗口中，选择**Capabilities**选项卡。\n\n   - **启用电源管理**：\n     - 勾选**Power Management**选项，以在设备的配置空间中包含此功能。\n\n2. **设置支持的电源状态**：\n\n   - **配置支持的状态**：\n     - 指定设备支持哪些电源状态，例如：\n       - **D0（完全开启）**\n       - **D1、D2（中间状态）**\n       - **D3hot、D3cold（低功耗状态）**\n     - 将这些设置与捐赠设备的功能相匹配。\n\n3. **在固件中实现电源状态逻辑**：\n\n   - **打开`pcileech_pcie_cfg_a7.sv`**：\n     - 修改固件以处理电源状态转换。\n\n   - **处理电源管理控制和状态寄存器（PMCSR）**：\n     - 实现对PMCSR的读写访问。\n\n       ```verilog\n       // PMCSR地址\n       localparam PMCSR_ADDRESS = 12'h44; // 示例地址\n\n       // PMCSR寄存器\n       reg [15:0] pmcsr_reg;\n\n       // 处理PMCSR写操作\n       always @(posedge clk) begin\n         if (cfg_write && cfg_address == PMCSR_ADDRESS) begin\n           pmcsr_reg <= cfg_writedata[15:0];\n           // 根据pmcsr_reg[1:0]更新电源状态\n         end\n       end\n       ```\n\n   - **管理电源状态效果**：\n     - 实现逻辑，根据当前的电源状态改变设备行为。\n\n4. **保存更改**：\n\n   - **保存固件文件**：\n     - 确保所有修改都已保存。\n\n   - **验证功能**：\n     - 通过仿真或硬件测试，测试电源管理功能。\n\n#### **8.3.2 MSI/MSI-X配置**\n\n实现MSI/MSI-X允许设备使用基于消息的中断，这比传统的基于引脚的中断更高效和可扩展。\n\n**步骤**：\n\n1. **在PCIe IP核中启用MSI/MSI-X**：\n\n   - **访问中断配置**：\n     - 在PCIe IP核配置窗口中，导航到**Interrupts**或**MSI/MSI-X**选项卡。\n\n   - **选择中断类型**：\n     - 根据捐赠设备，选择**MSI**或**MSI-X**。\n\n   - **配置支持的向量数量**：\n     - 设置与捐赠设备匹配的中断向量数量。\n       - **MSI**支持最多32个向量。\n       - **MSI-X**支持最多2048个向量。\n\n   - **启用功能**：\n     - 确保MSI或MSI-X功能包含在设备的配置空间中。\n\n2. **在固件中实现中断逻辑**：\n\n   - **打开`pcileech_pcie_tlp_a7.sv`**：\n     - 修改固件以处理中断生成。\n\n   - **定义中断信号**：\n\n     ```verilog\n     reg msi_req;\n     ```\n\n   - **实现中断生成逻辑**：\n\n     ```verilog\n     // 示例中断条件\n     wire interrupt_condition = /* 条件逻辑 */;\n\n     // 生成MSI中断\n     always @(posedge clk) begin\n       if (interrupt_condition) begin\n         msi_req <= 1'b1;\n       end else begin\n         msi_req <= 1'b0;\n       end\n     end\n     ```\n\n   - **连接到PCIe核心**：\n     - 确保`msi_req`信号正确连接到PCIe IP核的中断接口。\n\n3. **保存更改**：\n\n   - **保存固件文件**：\n     - 实现中断逻辑后，保存文件。\n\n   - **检查时序约束**：\n     - 确认新逻辑未引入时序违规。\n\n#### **8.3.3 实现中断处理逻辑**\n\n定义何时以及如何生成中断对于设备与主机的中断处理机制的交互至关重要。\n\n**步骤**：\n\n1. **定义中断条件**：\n\n   - **识别触发事件**：\n     - 确定应引起中断的特定事件。\n       - **示例**：\n         - 数据已准备好处理。\n         - 错误条件。\n         - 任务完成。\n\n   - **实现条件逻辑**：\n     - 使用组合逻辑或时序逻辑来检测这些事件。\n\n2. **创建中断生成模块**：\n\n   - **模块化设计**：\n     - 将中断逻辑实现为一个独立的模块，以提高清晰度和可重用性。\n\n       ```verilog\n       module interrupt_controller(\n         input wire clk,\n         input wire reset,\n         input wire event_trigger,\n         output reg msi_req\n       );\n         always @(posedge clk or posedge reset) begin\n           if (reset) begin\n             msi_req <= 1'b0;\n           end else if (event_trigger) begin\n             msi_req <= 1'b1;\n           end else begin\n             msi_req <= 1'b0;\n           end\n         end\n       endmodule\n       ```\n\n   - **与主固件集成**：\n     - 实例化模块，并将其连接到主固件逻辑。\n\n3. **确保正确的时序和顺序**：\n\n   - **遵守PCIe规范**：\n     - 确保中断按照协议正确生成和清除。\n\n   - **管理中断延迟**：\n     - 优化逻辑，最小化事件发生和中断生成之间的延迟。\n\n4. **测试中断传递**：\n\n   - **仿真**：\n     - 使用仿真工具验证中断是否正确生成。\n\n   - **硬件测试**：\n     - 编程FPGA，使用主机端软件确认中断已接收并处理。\n\n   - **调试工具**：\n     - 利用集成逻辑分析器（ILA）核实时监控信号。\n\n5. **保存更改**：\n\n   - **最终确定代码**：\n     - 确保所有更改都已保存并记录。\n\n   - **审查和改进**：\n     - 根据测试结果迭代设计。\n\n---\n\n## **10. 事务层数据包（TLP）仿真**\n\n事务层数据包（TLP）是PCIe通信的基本单位。准确的TLP仿真对于设备正确地与主机系统交互至关重要。\n\n### **10.1 理解和捕获TLP**\n\n#### **10.1.1 学习TLP结构**\n\n- **组成部分**：\n\n  - **头部**：包含字段，如**事务层数据包类型（Type）**、**长度**、**请求者ID**、**标签**、**地址**等。\n  - **数据负载**：存在于内存写入和其他一些TLP中。\n  - **CRC**：确保数据完整性。\n\n- **理解TLP类型**：\n\n  - **内存读取请求**\n  - **内存读取完成**\n  - **内存写入**\n  - **配置读取/写入**\n  - **供应商定义的消息**\n\n#### **10.1.2 从捐赠设备捕获TLP**\n\n- **步骤**：\n\n  1. **设置PCIe协议分析仪**：\n\n     - 使用如**Teledyne LeCroy PCIe分析仪**的硬件工具。\n\n  2. **捕获事务**：\n\n     - 在捐赠设备正常运行期间进行监控，记录TLP。\n\n  3. **分析捕获的TLP**：\n\n     - 使用分析仪的软件，剖析TLP，理解其结构和序列。\n\n#### **10.1.3 记录关键TLP事务**\n\n- **步骤**：\n\n  1. **识别关键事务**：\n\n     - 关注设备初始化、配置、数据传输和错误处理所必需的TLP。\n\n  2. **创建详细文档**：\n\n     - 对于每个关键TLP，记录字段值、序列和发送条件。\n\n  3. **理解时序和顺序**：\n\n     - 注意TLP之间的时序，以及所需的响应时间。\n\n### **10.2 为特定操作制作自定义TLP**\n\n#### **10.2.1 在固件中实现TLP处理**\n\n- **需要修改的文件**：\n\n  - `pcileech_pcie_tlp_a7.sv`\n\n    ```\n    pcileech-wifi-main/src/pcileech_pcie_tlp_a7.sv\n    ```\n\n- **步骤**：\n\n  1. **创建TLP生成函数**：\n\n     - 在`pcileech_pcie_tlp_a7.sv`中，编写函数，组装具有所需头部和负载的TLP。\n\n       - **示例**：\n\n         ```verilog\n         function automatic [127:0] generate_tlp;\n           input [15:0] requester_id;\n           input [7:0] tag;\n           input [7:0] length;\n           input [31:0] address;\n           input [31:0] data;\n           begin\n             generate_tlp = { /* TLP头部和负载 */ };\n           end\n         endfunction\n         ```\n\n  2. **处理TLP接收**：\n\n     - 实现逻辑，解析接收到的TLP，提取必要信息。\n     - 使用状态机管理不同的TLP类型。\n\n  3. **确保合规性**：\n\n     - 验证TLP符合PCIe规范的格式和时序。\n\n  4. **实现完成处理**：\n\n     - 对于内存读取请求，生成适当的完成TLP。\n\n  5. **保存更改**：\n\n     - 实现更改后，保存文件。\n\n#### **10.2.2 处理不同的TLP类型**\n\n- **内存读取请求**：\n\n  - **实现**：\n\n    - 解析请求头部。\n    - 从适当的内存位置获取数据。\n    - 组装并发送包含数据的完成TLP。\n\n- **内存写入请求**：\n\n  - **实现**：\n\n    - 接收TLP并提取数据负载。\n    - 将数据写入指定的内存位置。\n\n- **配置读取/写入请求**：\n\n  - **实现**：\n\n    - 访问配置空间寄存器。\n    - 对于读取，返回请求的数据。\n    - 对于写入，更新寄存器值。\n\n- **供应商定义的消息**：\n\n  - **实现**：\n\n    - 根据捐赠设备的协议，实现解析和响应逻辑。\n\n#### **10.2.3 验证TLP时序和序列**\n\n- **步骤**：\n\n  1. **使用仿真工具**：\n\n     - 使用测试平台仿真固件，验证TLP处理。\n\n  2. **使用ILA监控**：\n\n     - 插入ILA核，捕获TLP相关信号的硬件测试。\n\n  3. **检查时序约束**：\n\n     - 确保TLP在PCIe标准允许的时序窗口内处理和响应。\n\n  4. **合规性测试**：\n\n     - 使用PCIe合规性工具验证对标准的遵从。\n\n  5. **保存更改**：\n\n     - 测试和验证后，保存所有修改的文件。\n\n---\n\n## **第3部分：高级技术与优化**\n\n---\n\n## **11. 构建、烧录和测试**\n\n完成所有定制后，接下来是构建固件，将其编程到FPGA上，并彻底测试以确保其正常功能。\n\n### **11.1 综合与实现**\n\n#### **11.1.1 运行综合**\n\n综合将您的高级代码转换为门级表示。\n\n- **步骤**：\n\n  1. **启动综合**：\n\n     - 在Vivado中，点击**Flow Navigator**中的**Run Synthesis**。\n\n  2. **监视进度**：\n\n     - 注意任何警告或错误。\n\n     - **常见警告**：\n\n       - **未连接端口**：确保所有必要的信号已连接。\n\n       - **未满足时序约束**：可能需要调整约束。\n\n  3. **查看综合报告**：\n\n     - 检查**利用率摘要**，确保设计适合FPGA。\n\n#### **11.1.2 运行实现**\n\n实现将综合的设计映射到FPGA的资源上。\n\n- **步骤**：\n\n  1. **启动实现**：\n\n     - 综合成功后，点击**Run Implementation**。\n\n  2. **分析时序报告**：\n\n     - 确保所有时序约束都已满足。\n\n     - **解决违规**：\n\n       - 调整逻辑或约束，以修复建立或保持时间违规。\n\n  3. **验证布局**：\n\n     - 检查关键组件已被优化地放置。\n\n#### **11.1.3 生成比特流**\n\n比特流是用于编程FPGA的二进制文件。\n\n- **步骤**：\n\n  1. **生成比特流**：\n\n     - 点击**Generate Bitstream**。\n\n  2. **等待完成**：\n\n     - 根据设计的复杂性，这可能需要一些时间。\n\n  3. **查看比特流生成日志**：\n\n     - 确保生成过程中没有发生错误。\n\n### **11.2 烧录比特流**\n\n#### **11.2.1 连接FPGA设备**\n\n- **步骤**：\n\n  1. **准备硬件**：\n\n     - 确保FPGA板已通电，并通过JTAG连接。\n\n     - 参考您的FPGA板手册，获取特定的连接说明。\n\n  2. **打开硬件管理器**：\n\n     - 在Vivado中，导航到**Flow Navigator > Program and Debug > Open Hardware Manager**。\n\n#### **11.2.2 编程FPGA**\n\n- **步骤**：\n\n  1. **连接到目标设备**：\n\n     - 在硬件管理器中，点击**Open Target**，选择**Auto Connect**。\n\n     - Vivado应检测到您的FPGA设备。\n\n  2. **编程设备**：\n\n     - 在硬件窗口中，右键点击您的FPGA设备，选择**Program Device**。\n\n     - 选择生成的比特流文件（扩展名为`.bit`）。\n\n     - 点击**Program**，将固件烧录到FPGA上。\n\n     - 等待编程过程完成。\n\n#### **11.2.3 验证编程**\n\n- **步骤**：\n\n  1. **检查状态**：\n\n     - 确保编程无错误地完成。\n\n     - Vivado将在完成后显示成功消息。\n\n  2. **观察LED或指示灯**：\n\n     - 一些FPGA板具有指示成功编程或活动状态的LED。\n\n### **11.3 测试与验证**\n\n#### **11.3.1 验证设备枚举**\n\n- **Windows**：\n\n  - **步骤**：\n\n    1. **打开设备管理器**：\n\n       - 按`Win + X`，选择**设备管理器**。\n\n    2. **检查设备属性**：\n\n       - 在适当的设备类别下查找（例如，**网络适配器**、**存储控制器**）。\n\n       - 确认**设备ID**、**供应商ID**和其他标识符与捐赠设备匹配。\n\n- **Linux**：\n\n  - **步骤**：\n\n    1. **使用lspci**：\n\n       ```bash\n       lspci -nn\n       ```\n\n    2. **验证设备列表**：\n\n       - 检查仿真设备是否以正确的ID出现。\n\n       - **示例输出**：\n\n         ```\n         03:00.0 Network controller [0280]: VendorID DeviceID\n         ```\n\n#### **11.3.2 测试设备功能**\n\n- **步骤**：\n\n  1. **安装必要的驱动程序**：\n\n     - 如有需要，使用捐赠设备的驱动程序。\n\n     - 按制造商的说明进行安装。\n\n  2. **执行功能测试**：\n\n     - 运行与设备交互的应用程序。\n\n     - 测试数据传输、配置和任何特殊功能。\n\n     - **示例**：\n\n       - 对于网络卡，执行ping测试或数据流传输。\n\n       - 对于存储控制器，执行读/写操作。\n\n  3. **监视系统行为**：\n\n     - 检查系统稳定性，是否无错误。\n\n     - 确保设备在各种负载下按预期运行。\n\n#### **11.3.3 监控错误**\n\n- **Windows**：\n\n  - **步骤**：\n\n    1. **检查事件查看器**：\n\n       - 按`Win + X`，选择**事件查看器**。\n\n       - 导航到**Windows日志 > 系统**。\n\n    2. **查找与PCIe相关的错误**：\n\n       - 搜索与PCIe或特定设备相关的警告或错误。\n\n- **Linux**：\n\n  - **步骤**：\n\n    1. **检查dmesg日志**：\n\n       ```bash\n       dmesg | grep pci\n       ```\n\n    2. **识别问题**：\n\n       - 查找指示PCIe通信或设备初始化问题的消息。\n\n---\n\n## **12. 高级调试技术**\n\n当出现问题时，高级调试工具和技术可以帮助有效地识别和解决问题。\n\n### **12.1 使用Vivado的集成逻辑分析器**\n\n集成逻辑分析器（ILA）允许实时监控FPGA内部信号。\n\n#### **12.1.1 插入ILA核**\n\n- **步骤**：\n\n  1. **添加ILA IP核**：\n\n     - 在Vivado中，打开**IP目录**。\n\n     - 搜索**ILA**。\n\n     - 在设计中实例化ILA核。\n\n  2. **连接信号**：\n\n     - 将您希望监控的信号连接到ILA探针。\n\n     - **示例**：\n\n       ```verilog\n       ila_0 your_ila_instance (\n         .clk(clk),\n         .probe0(signal_to_monitor)\n       );\n       ```\n\n     - **文件路径**：\n\n       ```\n       pcileech-wifi-main/src/pcileech_squirrel_top.sv\n       ```\n\n#### **12.1.2 配置触发条件**\n\n- **步骤**：\n\n  1. **设置探针属性**：\n\n     - 定义每个探针的宽度，以匹配信号宽度。\n\n  2. **定义触发器**：\n\n     - 在ILA仪表板中，设置触发数据捕获的条件。\n\n     - **示例**：\n\n       - 当检测到特定的TLP类型或发生错误条件时触发。\n\n#### **12.1.3 捕获和分析数据**\n\n- **步骤**：\n\n  1. **运行设计**：\n\n     - 使用包含ILA的比特流编程FPGA。\n\n  2. **打开硬件管理器**：\n\n     - 在Vivado中访问ILA界面。\n\n  3. **捕获数据**：\n\n     - 臂ILA，等待触发条件。\n\n     - 触发后，ILA将捕获波形数据。\n\n  4. **分析波形**：\n\n     - 使用波形查看器检查信号行为。\n\n     - 识别异常或验证正确的操作。\n\n### **12.2 PCIe流量分析工具**\n\n使用外部工具可以深入了解PCIe通信。\n\n#### **12.2.1 PCIe协议分析仪**\n\n- **示例**：\n\n  - **Teledyne LeCroy PCIe分析仪**\n\n  - **Keysight PCIe分析仪**\n\n- **步骤**：\n\n  1. **设置分析仪**：\n\n     - 将分析仪连接在主机系统和FPGA设备之间。\n\n  2. **配置捕获设置**：\n\n     - 定义要捕获的数据范围（例如，特定的TLP类型、错误条件）。\n\n  3. **捕获流量**：\n\n     - 在设备运行期间记录PCIe事务。\n\n  4. **分析结果**：\n\n     - 检查TLP的合规性和正确性。\n\n     - 识别任何协议违规或意外行为。\n\n#### **12.2.2 基于软件的工具**\n\n- **示例**：\n\n  - **Wireshark与PCIe插件**\n\n  - **ChipScope Pro**（适用于Xilinx设备）\n\n- **步骤**：\n\n  1. **安装必要的插件**：\n\n     - 确保工具中启用了PCIe支持。\n\n  2. **监控PCIe总线**：\n\n     - 捕获并显示PCIe数据包。\n\n  3. **分析通信**：\n\n     - 查找数据中的异常或错误。\n\n     - 验证TLP的正确形成和顺序。\n\n---\n\n## **13. 故障排除**\n\n本节提供了您在固件开发和测试过程中可能遇到的常见问题的解决方案。\n\n### **13.1 设备检测问题**\n\n**问题**：FPGA设备未被主机系统识别。\n\n#### **可能的原因和解决方案**：\n\n1. **设备ID不正确**：\n\n   - **原因**：固件中的ID与主机期望的不匹配。\n\n   - **解决方案**：验证并纠正固件中的**设备ID**、**供应商ID**和**子系统ID**。\n\n2. **PCIe链路训练失败**：\n\n   - **原因**：PCIe链路未建立。\n\n   - **解决方案**：\n\n     - 检查物理连接。\n\n     - 确保**链路宽度**和**链路速度**已正确配置。\n\n3. **电源问题**：\n\n   - **原因**：FPGA设备供电不足。\n\n   - **解决方案**：验证电源连接和电压水平。\n\n4. **固件错误**：\n\n   - **原因**：固件中的错误阻止正常运行。\n\n   - **解决方案**：检查代码中的语法错误或配置错误。\n\n### **13.2 内存映射和BAR配置错误**\n\n**问题**：设备的内存区域不可访问，或访问它们导致系统错误。\n\n#### **可能的原因和解决方案**：\n\n1. **BAR大小或类型不正确**：\n\n   - **原因**：BAR配置与捐赠设备不匹配。\n\n   - **解决方案**：在PCIe IP核和固件中调整BAR大小和类型。\n\n2. **地址解码错误**：\n\n   - **原因**：固件未正确解释地址。\n\n   - **解决方案**：调试固件中的地址解码逻辑。\n\n3. **地址空间重叠**：\n\n   - **原因**：BARs重叠或与其他设备冲突。\n\n   - **解决方案**：确保BAR地址正确对齐且不重叠。\n\n### **13.3 DMA性能和TLP错误**\n\n**问题**：DMA操作期间发生数据传输速率低或错误，或TLP格式错误。\n\n#### **可能的原因和解决方案**：\n\n1. **DMA逻辑效率低下**：\n\n   - **原因**：DMA引擎未优化。\n\n   - **解决方案**：实现缓冲和流水线以提高吞吐量。\n\n2. **TLP格式错误**：\n\n   - **原因**：TLP格式不正确。\n\n   - **解决方案**：检查TLP组装代码，确保符合PCIe规范。\n\n3. **流控制问题**：\n\n   - **原因**：未正确处理流控制信用。\n\n   - **解决方案**：在固件中实现正确的流控制机制。\n\n---\n\n## **14. 仿真准确性和优化**\n\n提高仿真准确性可确保兼容性和性能，使仿真设备与捐赠设备无异。\n\n### **14.1 精确计时仿真技术**\n\n- **实施时序约束**：\n\n  - 使用Vivado的时序约束，匹配捐赠设备的时序特性。\n\n  - 将约束应用于关键路径，确保它们满足所需的建立和保持时间。\n\n- **使用时钟域交叉（CDC）技术**：\n\n  - 正确处理跨越不同时钟域的信号，防止亚稳态。\n\n  - 根据需要使用同步器或FIFO。\n\n- **仿真设备行为**：\n\n  - 使用仿真工具对设备行为进行建模和验证。\n\n  - 确认操作的时序和顺序与捐赠设备匹配。\n\n### **14.2 对系统调用的动态响应**\n\n- **实现状态机**：\n\n  - 设计状态机，允许设备对各种命令和状态进行动态响应。\n\n  - 确保设备能够优雅地处理意外或乱序的请求。\n\n- **监控并响应主机命令**：\n\n  - 实现逻辑，解码并响应配置写入、供应商特定命令和其他交互。\n\n  - 相应地更新内部寄存器和状态。\n\n- **优化固件逻辑**：\n\n  - 精简固件代码，减少延迟，提高响应速度。\n\n  - 删除不必要的延迟或数据路径中的瓶颈。\n\n---\n\n## **15. 固件开发最佳实践**\n\n遵循最佳实践有助于维护代码质量，促进协作，并确保项目的长期可行性。\n\n### **15.1 持续测试和文档编制**\n\n- **定期测试**：\n\n  - 在每次重要更改后测试固件，及早发现问题。\n\n  - 在实现之前，使用测试平台和仿真验证逻辑。\n\n- **自动化测试**：\n\n  - 实现自动化测试脚本，验证功能和性能。\n\n  - 如果在团队环境中工作，使用持续集成工具。\n\n- **维护文档**：\n\n  - 记录设计，包括框图、状态机和接口。\n\n  - 通过清晰的提交消息跟踪更改，并相应地更新设计文档。\n\n### **15.2 管理固件版本**\n\n- **使用版本控制系统**：\n\n  - 使用**Git**等系统管理代码版本并与他人协作。\n\n  - 使用清晰的目录结构和命名约定组织代码库。\n\n- **标记发布和里程碑**：\n\n  - 为固件的稳定版本打标签，供将来参考。\n\n  - 为实验性功能或重大更改使用分支。\n\n- **备份和恢复**：\n\n  - 定期备份您的工作，以防止数据丢失。\n\n  - 根据需要使用云端代码库或本地备份。\n\n### **15.3 安全考虑**\n\n- **安全编码实践**：\n\n  - 遵循指南，防止常见漏洞，如缓冲区溢出或竞争条件。\n\n  - 验证所有输入，优雅地处理错误。\n\n- **数据保护**：\n\n  - 确保设备处理的任何敏感数据都受到保护。\n\n  - 如果必要，实施加密或访问控制。\n\n- **合规和道德**：\n\n  - 了解与设备仿真相关的法律和道德考虑。\n\n  - 确保遵守相关的法律、法规和许可协议。\n\n---\n\n## **16. 其他资源**\n\n通过以下资源增强您的理解并保持更新：\n\n- **Xilinx文档**\n  - [Xilinx用户指南](https://www.xilinx.com/support/documentation/user_guides.htm)\n  - 包含有关Vivado、IP核和FPGA开发的详细信息。\n\n- **PCI-SIG规范**\n  - [PCI Express基本规范](https://pcisig.com/specifications)\n  - PCIe标准的官方规范。\n\n- **FPGA教程和论坛**\n  - [FPGA4Fun](http://www.fpga4fun.com/)\n  - [Stack Overflow的FPGA问题](https://stackoverflow.com/questions/tagged/fpga)\n  - 由社区驱动的讨论和教程。\n\n- **Verilog和VHDL资源**\n  - [ASIC World Verilog教程](https://www.asic-world.com/verilog/index.html)\n  - [VHDL参考指南](https://www.vhdlwhiz.com/vhdl-reference-guide/)\n\n- **Vivado设计套件用户指南**\n  - [Vivado用户指南](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_1/ug893-vivado-ip-subsystems.pdf)\n\n- **PCIe协议分析工具**\n  - [Teledyne LeCroy](https://teledynelecroy.com/protocolanalyzer/)\n  - 提供一系列PCIe分析工具。\n\n---\n\n## **17. 联系信息**\n\n如果您需要帮助、有疑问或希望合作，欢迎随时联系。我可以提供指导，解决复杂问题，或详细讨论想法。\n\n### **Discord**： [**VCPU**](https://discord.com/users/196741541094621184) | [**服务器邀请链接**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **18. 支持与贡献**\n\n您的支持有助于维护和改进本指南和相关项目。\n\n### **捐赠**\n\n- **加密货币捐赠（LTC）**：\n  - **地址**：`MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi`\n\n如果您发现本指南有用，并希望支持正在进行的工作，请考虑贡献。每一份捐赠都有助于继续创建、分享和支持社区。\n\n**特别奖励**：如果您进行了捐赠，请在Discord上联系我（VCPU），以收到个人感谢，可能还有额外的资源或帮助。\n\n**注意**：如果您需要我查看您的实现或解决问题，请在相关部分标注`//VCPU-REVIEW//`，并提供您遇到的问题的详细说明。\n\n---\n\n**指南结束**\n"
  },
  {
    "path": "CN/README-old.md",
    "content": "# **全设备仿真的定制固件开发指南**\n\n## **目录**\n\n1. [介绍](#1-介绍)\n   - [1.1 指南目的](#11-指南目的)\n   - [1.2 目标受众](#12-目标受众)\n2. [关键定义](#2-关键定义)\n3. [设备兼容性](#3-设备兼容性)\n   - [3.1 支持的基于FPGA的硬件](#31-支持的基于FPGA的硬件)\n   - [3.2 PCIe硬件考虑事项](#32-pcie硬件考虑事项)\n   - [3.3 系统要求](#33-系统要求)\n4. [需求](#4-需求)\n   - [4.1 硬件](#41-硬件)\n   - [4.2 软件](#42-软件)\n   - [4.3 环境设置](#43-环境设置)\n5. [收集捐赠设备信息](#5-收集捐赠设备信息)\n   - [5.1 使用Arbor进行PCIe设备扫描](#51-使用arbor进行pcie设备扫描)\n   - [5.2 提取和记录设备属性](#52-提取和记录设备属性)\n6. [初始固件定制](#6-初始固件定制)\n   - [6.1 修改配置空间](#61-修改配置空间)\n   - [6.2 插入设备序列号（DSN）](#62-插入设备序列号-dsn)\n7. [Vivado项目设置与定制](#7-vivado项目设置与定制)\n   - [7.1 生成Vivado项目文件](#71-生成vivado项目文件)\n   - [7.2 修改IP模块](#72-修改ip模块)\n8. [高级固件定制](#8-高级固件定制)\n   - [8.1 配置用于仿真的PCIe参数](#81-配置用于仿真的pcie参数)\n   - [8.2 调整BAR和内存映射](#82-调整bar和内存映射)\n   - [8.3 仿真设备电源管理和中断](#83-仿真设备电源管理和中断)\n9. [仿真设备特定功能](#9-仿真设备特定功能)\n   - [9.1 实现高级PCIe功能](#91-实现高级pcie功能)\n   - [9.2 仿真厂商特定功能](#92-仿真厂商特定功能)\n10. [事务层数据包（TLP）仿真](#10-事务层数据包-tlp-仿真)\n    - [10.1 理解和捕获TLP](#101-理解和捕获tlp)\n    - [10.2 为特定操作制作自定义TLP](#102-为特定操作制作自定义tlp)\n11. [构建、闪存和测试](#11-构建、闪存和测试)\n    - [11.1 综合与实现](#111-综合与实现)\n    - [11.2 闪存比特流](#112-闪存比特流)\n    - [11.3 测试与验证](#113-测试与验证)\n12. [高级调试技术](#12-高级调试技术)\n    - [12.1 使用Vivado的集成逻辑分析仪](#121-使用vivado的集成逻辑分析仪)\n    - [12.2 PCIe流量分析工具](#122-pcie流量分析工具)\n13. [故障排除](#13-故障排除)\n    - [13.1 设备检测问题](#131-设备检测问题)\n    - [13.2 内存映射和BAR配置错误](#132-内存映射和bar配置错误)\n    - [13.3 DMA性能和TLP错误](#133-dma性能和tlp错误)\n14. [仿真精度和优化](#14-仿真精度和优化)\n    - [14.1 精确时序仿真的技术](#141-精确时序仿真的技术)\n    - [14.2 对系统调用的动态响应](#142-对系统调用的动态响应)\n15. [固件开发的最佳实践](#15-固件开发的最佳实践)\n    - [15.1 持续测试和文档记录](#151-持续测试和文档记录)\n    - [15.2 管理固件版本](#152-管理固件版本)\n    - [15.3 安全考虑](#153-安全考虑)\n16. [附加资源](#16-附加资源)\n\n---\n\n## **前言**\n\n**注意，你们这些盗贼渣滓。** 我不是来溺爱或纵容你们可悲的阴谋的。**去你妈的AQUA**，也就是更广为人知的Aqua Teen Paster Force——对任何有一点诚信的人来说都是耻辱。**去你妈的DIVINER**，还有DUCK？去别的地方贬低自己。**DMA KINGDOM**？你和你们寄生的帝国以及这些骗子一起在地狱里腐烂。**SHITLETTE**和你们这些贪图金钱的贼人，准备迎接报应。**神的愤怒**？你们即将理解真正毁灭的意义。要么为你们的贪婪赎罪，要么被你们应得的毁灭席卷而去。既然我们谈到这个话题，**比尔·盖茨你也去他妈的。**\n\n对于那些**来学习**的人，你们选择了**真正启蒙**的道路。你们用这本指南构建的东西将超越这些江湖骗子能梦想到的任何东西。你们正走在**卓越**的道路上，携手一起焚烧他们建立财富所基于的失败。\n\n---\n\n## **联系方式**\n\n如果您需要帮助、有疑问或希望合作，请随时联系。我可以提供指导、排除复杂问题或详细讨论想法。\n\n### **Discord** - **VCPU** | [**服务器**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **支持我的工作**\n\n如果您觉得这本指南有帮助，并希望支持更多项目，请考虑捐助以帮助维持一切运作。每一笔捐款都能帮助我继续创建、分享和支持社区，衷心感谢。\n\n### **买杯咖啡**  \n- [ko-fi.com/virtualcpu](https://ko-fi.com/virtualcpu)  \n- [buymeacoffee.com/vcpu](https://buymeacoffee.com/vcpu)  \n\n### **加密捐赠（LTC）**  \n- MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi\n\n我通过销售固件赚得不多——大约5笔销售，总额约300美元——但我知道许多使用这本指南的人将会赚得更多。如果这本指南帮助您走上成功之路，请考虑回馈，以便我可以继续为大家提供这些资源。\n\n### **特别奖励**  \n如果您捐赠，请通过Discord（VCPU）联系我并告知。我很乐意亲自感谢您，并提供一些回报。我甚至会进行随机抽奖——无论是免费固件、私人源代码，还是一些绕过ACS的见解，都会有特别的东西给您。\n\n您的支持对我意义重大，我们可以一起继续建设和分享未来。谢谢！\n\n---\n\n没有时间或精力自己制作固件？我提供最低60美元的固件服务。也欢迎转售商！\n\n随时联系以获取支持或进一步讨论本指南或相关主题。无论您是需要深入帮助的开发人员，还是深入FPGA仿真的研究人员，我都在这里确保您的成功之路顺利且信息充分。让我们一起构建一些卓越的东西。\n\n如果您不确定是否正确完成了某个步骤，或希望我审核您的实现，我会这样做，但您必须在需要审核的部分标记为 //VCPU-REVIEW// 并解释您的问题，以免浪费我的时间。\n\n我相信你们中的很多人将超越我的能力。如果您发现了新东西或制作了一些很棒的固件，我很想看到它的实际运行。此外，我还有一些非常强大的字节和位可以分享，但如果我在这里分享，Riot PD会把我抓到警车上。\n\n分享知识，传播充满爱的善意。愿上帝保佑。\n\n---\n\n## **1. 介绍**\n\n### **1.1 指南目的**\n\n本指南的主要目标是为开发人员、安全研究人员和硬件工程师提供必要的知识和实际步骤，以开发用于精确1:1硬件设备仿真的定制DMA固件，使用基于FPGA的系统如**PCILeech-FPGA**。这使得在硬件测试、系统调试、恶意软件分析以及其他需要不可检测或看似合法的设备仿真的场景中应用成为可能。\n\n### **1.2 目标受众**\n\n- **固件开发人员**：为硬件仿真、测试或绕过硬件限制构建定制固件的工程师。\n- **硬件测试人员**：仿真故障或过时的硬件设备，以评估系统弹性或兼容性的专业人士。\n- **安全研究人员**：利用定制固件进行漏洞测试、恶意软件分析或安全评估的个人。\n- **FPGA爱好者**：探索FPGA定制和低级硬件仿真的爱好者。\n\n---\n\n## **2. 关键定义**\n\n理解术语对于有效地遵循本指南至关重要。以下是与PCIe、DMA和设备仿真相关的关键定义：\n\n- **DMA（直接内存访问）**：一种允许硬件设备直接从系统内存读取或写入数据而无需CPU干预的能力，促进快速数据传输。\n- **TLP（事务层数据包）**：PCIe架构中通信的基本单元，封装控制和数据信息。\n- **BAR（基地址寄存器）**：PCIe设备中的寄存器，将设备内存映射到系统内存空间，定义内存和I/O地址区域。\n- **FPGA（现场可编程门阵列）**：一种可重新配置的集成电路，可编程以执行特定的硬件功能，实现定制的设备仿真。\n- **MSI/MSI-X（消息信号中断）**：PCIe设备用于向CPU发送中断的机制，处理异步事件。\n- **设备序列号（DSN）**：与特定设备相关联的唯一标识符，通常用于高级设备识别和验证。\n- **PCIe配置空间**：PCIe设备提供有关自身信息和配置操作参数的内存区域。\n- **捐赠卡**：用于提取配置和识别详细信息以在FPGA上仿真其行为的PCIe设备。\n\n---\n\n## **3. 设备兼容性**\n\n### **3.1 支持的基于FPGA的硬件**\n\n虽然本指南主要关注**Squirrel DMA（35T）**卡，但所述方法可适用于其他基于FPGA的DMA硬件。以下是兼容设备列表：\n\n- **Squirrel (35T)**\n  - **描述**：价格实惠且广泛可获取的基于FPGA的DMA设备。\n  - **使用案例**：适用于标准内存获取和设备仿真任务。\n\n- **EnigmaX1 (75T)**\n  - **描述**：中档FPGA，提供增强的资源和性能。\n  - **使用案例**：适合需要更高带宽的更具挑战性的内存操作。\n\n- **ZDMA (100T)**\n  - **描述**：高性能FPGA，优化用于快速内存交互。\n  - **使用案例**：最适合需要快速和广泛内存读写的场景。\n\n- **Kintex-7**\n  - **描述**：先进的FPGA，具备强大的能力用于复杂项目。\n  - **使用案例**：适用于大规模或高度定制的DMA解决方案。\n\n### **3.2 PCIe硬件考虑事项**\n\n为确保顺利仿真，必须解决多个PCIe特定功能：\n\n- **IOMMU/VT-d设置**\n  - **建议**：禁用IOMMU（英特尔的VT-d），以允许不受限制的DMA访问。\n  - **理由**：IOMMU可能会限制DMA操作，可能干扰内存获取和仿真。\n\n- **内核DMA保护**\n  - **建议**：禁用现代系统中的内核DMA保护功能。\n  - **步骤**：\n    - **Windows**：这可能涉及禁用安全启动或基于虚拟化的安全性（VBS）。\n    - **BIOS/UEFI**：访问固件设置以关闭相关安全功能。\n  - **注意**：禁用这些功能可能会使系统面临风险；确保在安全和隔离的环境中操作。\n\n- **PCIe插槽要求**\n  - **建议**：使用与FPGA设备要求匹配的兼容PCIe插槽（例如x1、x4、x16）。\n  - **理由**：确保与主机系统的最佳性能和兼容性。\n\n### **3.3 系统要求**\n\n- **主机系统**\n  - **处理器**：多核CPU（Intel i5/i7或同等）\n  - **内存**：至少16GB RAM\n  - **存储**：至少100GB可用空间的SSD\n  - **操作系统**：Windows 10/11（64位）或兼容的Linux发行版（例如Ubuntu、Debian）及必要的驱动程序\n\n- **外围设备**\n  - **JTAG适配器**：用于将固件闪存到FPGA\n  - **PCIe插槽**：确保主机系统有可用的与DMA卡兼容的PCIe插槽\n\n---\n\n## **4. 需求**\n\n### **4.1 硬件**\n\n- **捐赠PCIe设备**\n  - **用途**：用于欺骗的设备ID和配置数据来源。\n  - **示例**：网络适配器、存储控制器或任何不在主机PC上使用的通用PCIe卡。\n\n- **DMA FPGA卡**\n  - **描述**：能够执行DMA操作的基于FPGA的设备。\n  - **示例**：Squirrel (35T)、EnigmaX1 (75T)、ZDMA (100T)、Kintex-7\n\n- **JTAG程序员**\n  - **用途**：用于将固件闪存到FPGA。\n  - **示例**：Xilinx Platform Cable USB、Digilent JTAG USB Cable\n\n### **4.2 软件**\n\n- **Vivado**\n  - **描述**：Xilinx的FPGA开发软件，用于综合和构建固件项目。\n  - **下载**： [Xilinx Vivado](https://www.xilinx.com/support/download.html)\n\n- **Visual Studio**\n  - **描述**：用于编辑Verilog或VHDL代码的集成开发环境（IDE）。\n  - **下载**： [Visual Studio Community](https://visualstudio.microsoft.com/vs/community/)\n\n- **PCILeech-FPGA**\n  - **描述**：用于DMA固件开发的存储库和基础代码。\n  - **存储库**： [PCILeech-FPGA 在 GitHub 上](https://github.com/ufrisk/pcileech-fpga)\n\n- **Arbor**\n  - **描述**：用于收集设备信息的PCIe设备扫描工具。\n  - **下载**： [MindShare 的 Arbor](https://www.mindshare.com/software/Arbor)\n  - **注意**：需要创建账户；提供14天试用。\n\n- **替代工具**\n  - **Telescan PE**\n    - **描述**：可以作为Arbor替代的PCIe流量分析工具。\n    - **下载**： [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n    - **注意**：免费但需要手动注册批准。\n\n### **4.3 环境设置**\n\n1. **安装Vivado**\n   - **步骤**：\n     1. 访问 [Xilinx Vivado 下载页面](https://www.xilinx.com/support/download.html)。\n     2. 下载与您的FPGA设备兼容的适当版本。\n     3. 按照Xilinx提供的安装说明进行安装。\n     4. 启动Vivado并确保其正确配置。\n\n2. **安装Visual Studio**\n   - **步骤**：\n     1. 访问 [Visual Studio 下载页面](https://visualstudio.microsoft.com/vs/community/)。\n     2. 下载并安装 **Visual Studio Community Edition**。\n     3. 在安装过程中，确保包括与**使用C++进行桌面开发**相关的工作负载，以支持硬件描述语言（HDL）如Verilog或VHDL。\n\n3. **克隆PCILeech-FPGA存储库**\n   - **步骤**：\n     1. 打开终端或命令提示符。\n     2. 使用Git克隆存储库：\n        ```bash\n        git clone https://github.com/ufrisk/pcileech-fpga.git\n        ```\n     3. 进入克隆的目录：\n        ```bash\n        cd pcileech-fpga\n        ```\n\n4. **设置干净的开发环境**\n   - **建议**：在隔离的环境中工作，以防止意外交互，尤其是如果使用固件进行敏感任务如恶意软件分析。\n   - **步骤**：\n     1. 使用专用的开发机器或虚拟环境。\n     2. 确保没有其他应用程序干扰PCIe操作或FPGA编程。\n\n---\n\n## **5. 收集捐赠设备信息**\n\n精确的设备仿真依赖于从捐赠设备中提取关键信息。这些数据使您的FPGA能够在PCIe配置和行为方面模拟目标硬件。\n\n### **5.1 使用Arbor进行PCIe设备扫描**\n\n**Arbor**是一个强大的工具，用于扫描PCIe设备并提取必要的信息。按照以下步骤收集捐赠设备的详细信息：\n\n1. **安装Arbor**\n   - **步骤**：\n     1. 访问 [Arbor下载页面](https://www.mindshare.com/software/Arbor)。\n     2. 如果需要，创建一个账户。\n     3. 下载并安装Arbor到您的系统上。\n\n2. **扫描PCIe设备**\n   - **步骤**：\n     1. 启动Arbor。\n     2. 导航到 **本地系统** 标签。\n     3. 在 **扫描选项** 下，确保默认设置适当。\n     4. 点击 **扫描/重新扫描** 以检测所有连接的PCIe设备。\n\n3. **识别捐赠设备**\n   - **标准**：\n     - 不应在主机PC上使用。\n     - 示例：PCIe WiFi卡、存储控制器或通用PCIe设备。\n   - **步骤**：\n     1. 在扫描设备列表中找到您的捐赠设备。\n     2. 点击设备以查看详细配置。\n\n4. **捕获设备数据**\n   - **需要提取的信息**：\n     - **设备ID**\n     - **厂商ID**\n     - **子系统ID**\n     - **修订ID**\n     - **基地址寄存器（BARs）**\n     - **功能**（例如，MSI、电源管理、PCIe链路宽度/速度）\n     - **设备序列号（DSN）**（如果可用）\n\n   - **步骤**：\n     1. 导航到Arbor中的 **PCI配置** 标签。\n     2. 滚动浏览 **解码** 部分，找到并记录上述详细信息。\n     3. 截屏或记录每个值，以便在固件定制过程中参考。\n\n   - **示例提取**：\n\n     ![设备ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/8baec3fe-c4bd-478e-9f95-d262804d6f67)\n\n     ![厂商ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/39c7de6d-d8db-4744-b0a0-ddeca0dfd7d7)\n\n     ![修订ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/c2374ea7-ca9c-47b7-8a8d-4ceff5dffe3b)\n\n     ![BAR大小](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/19239179-057a-4ed5-a79f-45cf242787a5)\n\n     ![子系统ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/94522a95-70bd-4336-8e38-58c0839e38ad)\n\n     ![DSN](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/595ae3e2-4cd8-4b3d-bcfa-cf6a59f289d5)\n\n   - **注意**：并非所有设备都包含DSN。如果不可用，在定制过程中DSN字段使用零即可。\n\n### **5.2 提取和记录设备属性**\n\n扫描后，确保准确记录捐赠设备的以下属性：\n\n1. **设备ID**：硬件设备的唯一标识符。\n2. **厂商ID**：设备制造商的标识符。\n3. **子系统ID**：标识与设备相关联的特定子系统。\n4. **修订ID**：硬件版本的修订号。\n5. **基地址寄存器（BARs）**：定义设备的内存和I/O地址区域。\n6. **功能**：如电源管理（PM）、MSI/MSI-X、PCIe链路速度和宽度。\n7. **设备序列号（DSN）**：如果适用，与设备关联的唯一序列号。\n\n**重要注意事项**：\n\n- **BAR大小**：确保内存映射I/O区域与捐赠设备的配置匹配。\n- **功能**：正确仿真所有功能以确保与主机系统的无缝集成。\n- **DSN**：提高仿真的逼真度；如果可用，请使用。\n\n---\n\n## **6. 初始固件定制**\n\n在掌握必要的捐赠设备信息后，继续定制固件中的PCIe配置空间和内存映射，以欺骗捐赠设备。\n\n### **6.1 修改配置空间**\n\n1. **导航到配置文件**\n   - **路径**：`/PCIeSquirrel/src/pcileech_pcie_cfg_a7.sv`\n   - **描述**：此Verilog文件包含设备的PCIe配置逻辑。\n\n2. **在Visual Studio中打开文件**\n   - **步骤**：\n     1. 启动 **Visual Studio**。\n     2. 打开位于 `/PCIeSquirrel/src/` 目录下的 `pcileech_pcie_cfg_a7.sv` 文件。\n\n3. **修改设备ID和厂商ID**\n   - **步骤**：\n     1. 使用 **Ctrl + F** 搜索 `cfg_deviceid`。\n     2. 使用捐赠设备的值更新设备ID：\n        ```verilog\n        cfg_deviceid <= 16'hXXXX;  // 将XXXX替换为捐赠设备的设备ID\n        ```\n     3. 同样，搜索 `cfg_vendorid` 并更新：\n        ```verilog\n        cfg_vendorid <= 16'hYYYY;  // 将YYYY替换为捐赠设备的厂商ID\n        ```\n\n4. **修改子系统ID**\n   - **步骤**：\n     1. 搜索 `cfg_subsysid`。\n     2. 更新子系统ID：\n        ```verilog\n        cfg_subsysid <= 16'hZZZZ;  // 将ZZZZ替换为捐赠设备的子系统ID\n        ```\n\n5. **根据捐赠设备调整BARs**\n   - **步骤**：\n     1. 找到BAR大小配置。\n     2. 设置BAR大小以匹配捐赠设备：\n        ```verilog\n        bar0_size <= 32'hXXXX_YYYY;  // 将XXXX_YYYY替换为捐赠设备的BAR0大小\n        ```\n     3. 根据需要重复设置其他BAR（BAR1, BAR2等）。\n\n   - **示例**：\n     ```verilog\n     bar0_size <= 32'h00004000;  // BAR0的16KB\n     ```\n\n### **6.2 插入设备序列号（DSN）**\n\n如果您的捐赠设备有**设备序列号（DSN）**，将其纳入固件可以增强仿真的逼真度。\n\n1. **定位DSN字段**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中搜索 `rw[127:64]`。\n     2. 该字段代表 `cfg_dsn`（配置空间设备序列号）。\n\n2. **插入DSN**\n   - **步骤**：\n     1. 用捐赠设备的DSN替换占位符：\n        ```verilog\n        rw[127:64] <= 64'hXXXXXXXX_YYYYYYYY;  // 将X和Y替换为捐赠设备的DSN\n        ```\n     2. **示例**：\n        - **捐赠设备DSN**：上DW：`01 00 00 00`，下DW：`68 4C E0 00`\n        - **组合DSN**：`64'h01000000684CE000`\n        ```verilog\n        rw[127:64] <= 64'h01000000684CE000;  // 捐赠设备的DSN\n        ```\n     - **无DSN可用**：\n        ```verilog\n        rw[127:64] <= 64'h0000000000000000;  // 无DSN\n        ```\n\n3. **保存更改**\n   - **步骤**：\n     1. 修改DSN后，保存文件以保留更改。\n\n---\n\n## **7. Vivado项目设置与定制**\n\n在定制配置空间后，将这些更改集成到Vivado项目中，以准备固件进行综合和实现。\n\n### **7.1 生成Vivado项目文件**\n\n1. **打开Vivado**\n   - **步骤**：\n     1. 在您的开发机器上启动 **Vivado**。\n     2. 确保Vivado已正确安装并为您的FPGA设备配置。\n\n2. **访问Tcl控制台**\n   - **步骤**：\n     1. 在Vivado中，找到应用程序窗口底部的 **Tcl控制台**。\n     2. 如果不可见，导航到 **窗口 > Tcl控制台** 以显示它。\n\n3. **导航到PCIeSquirrel目录**\n   - **步骤**：\n     1. 在Tcl控制台中，确定当前目录：\n        ```tcl\n        pwd\n        ```\n     2. 切换到克隆的 `pcileech-fpga` 存储库中的 `PCIeSquirrel` 文件夹：\n        ```tcl\n        cd C:/Users/YourUsername/Desktop/pcileech-fpga/PCIeSquirrel\n        ```\n        *根据您的设置替换 `YourUsername` 和路径。*\n\n     - **注意**：如果遇到反斜杠 (`\\`) 的错误，使用正斜杠 (`/`)：\n       ```tcl\n       cd C:/Users/YourUsername/Desktop/pcileech-fpga/PCIeSquirrel\n       ```\n\n4. **生成Vivado项目**\n   - **步骤**：\n     1. 在Tcl控制台中，执行项目生成脚本：\n        ```tcl\n        source vivado_generate_project.tcl -notrace\n        ```\n     2. 等待脚本完成。此过程将使用必要的配置设置Vivado项目。\n\n5. **打开生成的项目**\n   - **步骤**：\n     1. 成功生成后，Vivado应自动打开 `.xpr`（Vivado项目）文件。\n     2. 保持项目打开以进行进一步的定制。\n\n### **7.2 修改IP模块**\n\n1. **访问PCIe IP核**\n   - **步骤**：\n     1. 在 **Sources** 窗格中，导航到：\n        ```\n        pcileech_squirrel_top > i_pcileech_pcie_a7 : pcileech_pcie_a7\n        ```\n     2. 双击PCIe IP核 (`i_pcie_7x_0 : pcie_7x_0`) 以打开 **重新定制IP** 窗口。\n\n2. **定制设备ID和BARs**\n   - **步骤**：\n     1. 在 **重新定制IP** 对话框中，导航到 **IDs** 标签。\n     2. 输入从捐赠设备收集的 **设备ID**、**厂商ID** 和 **子系统ID**。\n     3. 验证 **类代码**：\n        - 返回Arbor或您的扫描工具，以确定捐赠设备的类代码。\n        - 在 **重新定制IP** 窗口中，设置类代码以匹配捐赠设备。\n     4. **示例**：\n        - **设备ID**：`0x1234`\n        - **厂商ID**：`0xABCD`\n        - **子系统ID**：`0x5678`\n        - **类代码**：`0x030000`（例如，网络控制器）\n\n3. **配置BAR大小**\n   - **步骤**：\n     1. 在 **重新定制IP** 对话框中导航到 **BARs** 标签。\n     2. 设置 **BAR0大小** 以匹配捐赠设备的BAR0大小。\n        - **示例**：如果捐赠设备的BAR0是16KB：\n          ```tcl\n          BAR0 Size: 16KB\n          ```\n     3. 如果捐赠设备使用了额外的BAR（BAR1、BAR2等），请重复设置。\n\n4. **完成IP定制**\n   - **步骤**：\n     1. 设置所有必要参数后，点击 **确定** 以应用更改。\n     2. Vivado可能会提示重新生成IP核；确认并允许过程完成。\n\n5. **锁定IP核**\n   - **目的**：防止Vivado在综合过程中覆盖手动配置。\n   - **步骤**：\n     1. 打开Vivado中的 **Tcl控制台**。\n     2. 执行以下命令以锁定IP核：\n        ```tcl\n        set_property is_managed false [get_files pcie_7x_0.xci]\n        ```\n     3. **解锁**（如果将来需要）：\n        ```tcl\n        set_property is_managed true [get_files pcie_7x_0.xci]\n        ```\n\n---\n\n## **8. 高级固件定制**\n\n为了实现精确的1:1仿真，进一步定制PCIe参数、BARs、内存映射、电源管理和中断处理。\n\n### **8.1 配置用于仿真的PCIe参数**\n\n1. **匹配PCIe链路速度和宽度**\n   - **重要性**：确保仿真设备以与捐赠设备相同的速度和宽度进行通信。\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，找到PCIe链路速度和宽度配置。\n     2. 更新这些参数以匹配捐赠设备的规格。\n        ```verilog\n        pcie_link_speed <= 4'bXXXX;  // 将XXXX替换为捐赠设备的PCIe链路速度\n        pcie_link_width <= 8'b00000100;  // 将其替换为捐赠设备的PCIe链路宽度（例如x1、x4、x8）\n        ```\n     - **示例**：\n       - **捐赠设备PCIe链路速度**：Gen3（8 GT/s）\n       - **捐赠设备PCIe链路宽度**：x4\n         ```verilog\n         pcie_link_speed <= 4'b0011;  // Gen3\n         pcie_link_width <= 8'b00000100;  // x4\n         ```\n\n2. **设置能力指针**\n   - **目的**：确保PCIe功能正确链接并被主机系统识别。\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中找到能力指针配置。\n     2. 设置能力指针以匹配捐赠设备的配置。\n        ```verilog\n        capability_pointer <= 8'h40;  // 示例值；根据捐赠设备的能力指针替换\n        ```\n\n### **8.2 调整BAR和内存映射**\n\n精确的内存映射对于仿真硬件设备至关重要。基地址寄存器（BARs）定义设备的内存和寄存器在系统内存空间中的位置。\n\n1. **设置BAR大小**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，找到BAR大小分配。\n     2. 将BAR大小设置为与捐赠设备匹配。\n        ```verilog\n        bar0_size <= 32'h00004000;  // BAR0的16KB\n        bar1_size <= 32'h00008000;  // BAR1的32KB（如果适用）\n        ```\n\n2. **定义BAR地址空间**\n   - **步骤**：\n     1. 确保BAR地址空间不重叠，并与捐赠设备的内存布局匹配。\n     2. 使用记录的BAR大小适当地设置地址范围。\n        ```verilog\n        bar0_addr <= 32'hF0000000;  // 示例地址；根据捐赠设备的BAR0地址替换\n        bar1_addr <= 32'hF0004000;  // 示例地址；根据需要替换\n        ```\n\n3. **处理多个BAR**\n   - **步骤**：\n     1. 如果捐赠设备使用多个BAR，请重复配置每个BAR。\n     2. 确保每个BAR的大小和地址与捐赠设备的规格一致。\n\n### **8.3 仿真设备电源管理和中断**\n\n正确仿真电源管理和中断处理确保主机系统与仿真设备无缝交互。\n\n1. **电源管理（PM）配置**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，找到电源管理能力设置。\n     2. 设置PM能力以匹配捐赠设备。\n        ```verilog\n        PM_CAP_VERSION <= 4'b0011;  // 示例版本；根据捐赠设备的PM版本替换\n        PM_CAP_D1SUPPORT <= 1'b1;   // 如果捐赠设备支持D1，则启用\n        PM_CAP_AUXCURRENT <= 4'b1000; // 示例值；根据捐赠设备调整\n        PM_CSR_NOSOFTRST <= 1'b0;   // 示例值；根据需要调整\n        ```\n\n2. **MSI/MSI-X（中断）配置**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中找到MSI/MSI-X配置。\n     2. 启用并配置MSI/MSI-X以正确处理中断。\n        ```verilog\n        MSI_CAP_64_BIT_ADDR_CAPABLE <= 1'b1;  // 如果支持，启用64位MSI\n        cfg_interrupt <= 1'b1;               // 启用MSI中断\n        ```\n\n3. **实现中断处理逻辑**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，确保中断信号正确路由。\n        ```verilog\n        assign cfg_interrupt_di = cfg_int_di;\n        assign cfg_interrupt_assert = cfg_int_assert;\n        ```\n     2. 测试中断功能，确保主机系统正确接收和处理来自仿真设备的中断。\n   \n---\n\n## **9. 仿真设备特定功能**\n\n为了实现真正的1:1仿真，除了基本的PCIe交互之外，还必须复制捐赠设备的独特功能。\n\n### **9.1 实现高级PCIe功能**\n\n大多数PCIe设备支持**高级错误报告（AER）**、**链路速度协商**和**扩展能力**等高级功能。仿真这些功能确保主机系统将仿真设备视为与捐赠设备相同。\n\n1. **高级错误报告（AER）**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，找到AER配置。\n     2. 如果捐赠设备支持，启用AER。\n        ```verilog\n        AER_CAP_VERSION <= 4'b0001;  // 示例版本；根据捐赠设备的AER版本替换\n        AER_CAP_NEXTPTR <= 8'h00;    // 适当地设置下一个指针\n        ```\n     3. 实现错误处理逻辑以管理与AER相关的事件。\n\n2. **链路速度协商**\n   - **步骤**：\n     1. 确保PCIe链路速度和宽度协商与捐赠设备匹配。\n     2. 如 **8.1** 所述，调整链路速度设置。\n\n3. **扩展能力**\n   - **步骤**：\n     1. 确定捐赠设备使用的任何扩展能力（例如，厂商特定的扩展能力、LTR、VSEC）。\n     2. 通过在 `pcileech_pcie_cfg_a7.sv` 中定义适当的寄存器和逻辑，实现场这些能力。\n        ```verilog\n        // 示例：厂商特定的扩展能力\n        VSEC_CAP_ID <= 16'hXXXX;       // 将XXXX替换为厂商特定的ID\n        VSEC_CAP_VERSION <= 8'hYY;    // 将YY替换为版本\n        VSEC_CAP_NEXTPTR <= 8'hZZ;    // 下一个能力指针\n        ```\n\n### **9.2 仿真厂商特定功能**\n\n一些设备包含专有或厂商特定的功能，必须准确仿真以确保与主机系统的无缝集成。\n\n1. **识别厂商特定功能**\n   - **步骤**：\n     1. 使用PCIe流量分析工具（例如，Wireshark、Teledyne LeCroy）监控厂商特定的TLP。\n     2. 记录捐赠设备在典型操作中使用的独特寄存器、命令或行为。\n\n2. **实现厂商特定逻辑**\n   - **步骤**：\n     1. 在 `pcileech_pcie_cfg_a7.sv` 中，添加逻辑以处理厂商特定功能。\n        ```verilog\n        // 示例：厂商特定寄存器\n        vendor_specific_reg <= 32'hXXXXXXXX;  // 将其替换为实际值\n        ```\n     2. 确保任何专有命令或响应被准确复制。\n\n3. **测试厂商特定功能**\n   - **步骤**：\n     1. 使用厂商特定的驱动程序或应用程序与仿真设备交互。\n     2. 验证所有专有功能是否按预期运行。\n\n---\n\n## **10. 事务层数据包（TLP）仿真**\n\n准确仿真事务层数据包（TLP）对于确保基于FPGA的设备与主机系统无缝通信至关重要，模仿捐赠设备的行为。\n\n### **10.1 理解和捕获TLP**\n\nTLP是PCIe通信的基本单元，处理内存读写、配置访问和中断信号。\n\n1. **从捐赠设备捕获TLP**\n   - **步骤**：\n     1. 使用PCIe分析工具如 **Teledyne LeCroy的Telescan PE** 或支持PCIe的 **Wireshark** 监控捐赠设备生成的TLP。\n     2. 记录捐赠设备在典型操作中使用的TLP的结构、类型和模式。\n\n2. **分析TLP结构**\n   - **TLP的组成部分**：\n     - **头字段**：定义类型、格式、地址和其他控制信息。\n     - **数据载荷**：实际传输的数据。\n     - **尾字段**：附加信息，如字节计数和序列号。\n\n   - **示例TLP结构**：\n     ```verilog\n     tlps_static.tdata[127:0] = {TLP头字段, 数据载荷};\n     ```\n\n3. **仿真合法流量**\n   - **步骤**：\n     1. 确保FPGA生成的TLP在类型、地址、长度和数据方面与捐赠设备捕获的TLP一致。\n     2. 实现处理不同类型TLP的逻辑，如内存写、内存读和配置访问。\n\n### **10.2 为特定操作制作自定义TLP**\n\n为了准确模仿捐赠设备，您必须制作自定义TLP，以复制其在各种操作中的行为。\n\n1. **内存写TLP示例**\n   - **描述**：表示对系统内存的写操作。\n   - **Verilog示例**：\n     ```verilog\n     tlp_mem_write <= {\n         1'b0,                    // 保留位\n         7'b10_00000,             // TLP类型：内存写\n         1'b0,                    // TLP格式\n         address[31:0],           // 写入地址\n         data[31:0]               // 数据载荷\n     };\n     ```\n\n2. **内存读TLP示例**\n   - **描述**：表示从系统内存的读操作。\n   - **Verilog示例**：\n     ```verilog\n     tlp_mem_read <= {\n         1'b0,                    // 保留位\n         7'b00_00000,             // TLP类型：内存读\n         1'b0,                    // TLP格式\n         address[31:0],           // 读取地址\n         tag[7:0]                 // 事务识别标签\n     };\n     ```\n\n3. **配置访问TLP示例**\n   - **描述**：表示配置空间访问。\n   - **Verilog示例**：\n     ```verilog\n     tlp_config_access <= {\n         1'b0,                    // 保留位\n         7'b01_00000,             // TLP类型：配置读/写\n         1'b0,                    // TLP格式\n         config_address[31:0],    // 配置空间地址\n         config_data[31:0]        // 配置数据载荷\n     };\n     ```\n\n4. **中断信号TLP示例**\n   - **描述**：表示向CPU发送中断信号。\n   - **Verilog示例**：\n     ```verilog\n     tlp_interrupt <= {\n         1'b0,                    // 保留位\n         7'b11_00000,             // TLP类型：中断\n         1'b0,                    // TLP格式\n         interrupt_address[31:0], // 与中断相关的地址\n         interrupt_data[31:0]     // 中断数据载荷\n     };\n     ```\n\n5. **实现TLP处理器**\n   - **步骤**：\n     1. 在固件中，实现不同TLP类型的处理器，以确保正确处理和响应。\n     2. 使用状态机或逻辑块管理TLP生成、处理和响应处理。\n\n---\n\n## **11. 构建、闪存和测试**\n\n在定制固件并确保所有配置与捐赠设备一致后，继续在您的FPGA设备上构建、闪存和测试固件。\n\n### **11.1 综合与实现**\n\n1. **运行综合**\n   - **步骤**：\n     1. 在Vivado中，点击 **运行综合**。\n     2. 监控综合过程中的任何警告或错误。\n     3. 在继续之前解决任何关键问题。\n\n2. **运行实现**\n   - **步骤**：\n     1. 综合成功后，启动 **运行实现**。\n     2. 确保实现阶段在没有关键警告的情况下完成。\n     3. 查看实现报告以识别任何潜在问题。\n\n3. **生成比特流**\n   - **步骤**：\n     1. 一旦实现完成，点击 **生成比特流**。\n     2. 确认生成比特流的任何提示。\n     3. 等待比特流生成成功完成。\n\n### **11.2 闪存比特流**\n\n1. **通过JTAG连接FPGA**\n   - **步骤**：\n     1. 确保您的FPGA设备通过JTAG接口连接到主机系统。\n     2. 为FPGA设备供电。\n\n2. **打开Vivado硬件管理器**\n   - **步骤**：\n     1. 在Vivado中，导航到 **窗口 > 硬件管理器**。\n     2. 点击 **打开目标 > 自动连接** 以检测连接的FPGA设备。\n\n3. **编程FPGA**\n   - **步骤**：\n     1. 在硬件管理器中，右键点击检测到的设备并选择 **编程设备**。\n     2. 浏览到生成的比特流文件（`pcileech_squirrel_top.bit`）。\n     3. 点击 **编程** 以将固件闪存到FPGA。\n     4. 通过硬件管理器控制台确认编程成功。\n\n### **11.3 测试与验证**\n\n1. **验证设备检测**\n   - **步骤**：\n     1. 使用 **lspci**（在Linux上）或 **设备管理器**（在Windows上）验证FPGA是否被检测为捐赠设备。\n     2. 确认 **设备ID**、**厂商ID**、**子系统ID** 和 **BARs** 是否与捐赠设备的规格匹配。\n\n   - **示例（Linux）**：\n     ```bash\n     lspci -vvv -s <PCI地址>\n     ```\n\n2. **内存映射测试**\n   - **步骤**：\n     1. 访问设备的 **BARs** 以确保正确的内存映射。\n     2. 使用内存访问工具或简单的读写操作测试响应性。\n\n3. **中断测试**\n   - **步骤**：\n     1. 通过仿真设备触发中断。\n     2. 验证主机系统是否正确接收和处理这些中断。\n     3. 使用系统日志或诊断工具确认中断处理。\n\n4. **性能测试**\n   - **步骤**：\n     1. 运行DMA速度测试工具以测量数据传输速率。\n     2. 将性能指标与预期值进行比较，以确保固件的稳定性和效率。\n\n   - **示例工具**：\n     - **PCILeech DMA速度测试**：在PCILeech工具集中可用。\n     - **自定义基准测试脚本**：执行读写操作以测量性能。\n\n5. **配置空间验证**\n   - **步骤**：\n     1. 使用诊断工具检查PCIe配置空间。\n     2. 确保所有字段（设备ID、厂商ID、BARs、功能）正确设置并与捐赠设备匹配。\n\n   - **示例（Linux）**：\n     ```bash\n     lspci -vvv -s <PCI地址>\n     ```\n\n---\n\n## **12. 高级调试技术**\n\n在开发定制固件时，遇到问题是常见的。高级调试技术可以帮助有效地识别和解决这些问题。\n\n### **12.1 使用Vivado的集成逻辑分析仪**\n\nVivado的**集成逻辑分析仪（ILA）**允许实时监控内部FPGA信号，有助于调试和验证。\n\n1. **设置ILA探针**\n   - **步骤**：\n     1. 在Vivado中，导航到 **Sources > 添加源** 并添加一个 **集成逻辑分析仪**。\n     2. 在PCIe通信路径的关键点插入ILA探针，例如TLP生成器或BAR访问控制器。\n        ```verilog\n        // 示例：为TLP数据添加ILA探针\n        wire [127:0] tlp_data;\n        assign tlp_data = tlps_static.tdata[127:0];\n        ila_0 probe (\n            .clk(clk),\n            .probe0(tlp_data)\n        );\n        ```\n\n2. **配置触发器**\n   - **步骤**：\n     1. 打开 **ILA** 配置对话框。\n     2. 根据特定事件设置触发条件，例如TLP生成或内存访问。\n        ```verilog\n        // 示例触发条件：内存写TLP的开始\n        if (tlp_type == MEMORY_WRITE && tlp_valid) begin\n            trigger_signal <= 1;\n        end\n        ```\n\n3. **分析信号波形**\n   - **步骤**：\n     1. 启用ILA探针运行FPGA。\n     2. 使用Vivado的 **波形查看器** 检查捕获的信号波形。\n     3. 识别时序问题、不正确的逻辑状态或意外行为。\n\n   - **优势**：\n     - 实时查看内部信号。\n     - 能够捕获和分析TLP处理过程中的瞬态问题。\n\n### **12.2 PCIe流量分析工具**\n\n除了Vivado的ILA，外部PCIe流量分析工具提供了深入了解FPGA与主机系统之间PCIe通信的能力。\n\n1. **带有PCIe扩展的Wireshark**\n   - **描述**：Wireshark可以通过适当的扩展或插件捕获和分析PCIe流量。\n   - **步骤**：\n     1. 安装带有PCIe支持的Wireshark。\n     2. 配置Wireshark以捕获PCIe流量。\n     3. 分析捕获的TLP，以确保其符合预期的捐赠设备行为。\n\n2. **Teledyne LeCroy Telescan PE**\n   - **描述**：专业级PCIe流量分析工具，提供全面的PCIe流量监控和分析功能。\n   - **步骤**：\n     1. 安装Teledyne LeCroy的Telescan PE。\n     2. 将其连接到您的系统以监控PCIe流量。\n     3. 使用其分析功能捕获和解析FPGA与主机系统之间交换的TLP。\n\n3. **Total Phase Beagle**\n   - **描述**：PCIe流量分析仪，允许实时捕获和分析PCIe通信。\n   - **步骤**：\n     1. 使用Total Phase Beagle PCIe分析仪设置您的系统。\n     2. 配置其以监控和捕获PCIe流量。\n     3. 使用其分析功能验证TLP的完整性和行为。\n\n**使用PCIe流量分析工具的优势**：\n\n- **全面的TLP分析**：详细检查TLP，确保准确的仿真。\n- **错误检测**：识别格式错误的TLP或意外的事务模式。\n- **性能指标**：测量数据传输速率并识别瓶颈。\n\n---\n\n## **13. 故障排除**\n\n在固件开发过程中遇到问题是常见的。本节提供了在仿真过程中可能遇到的常见问题的解决方案。\n\n### **13.1 设备检测问题**\n\n**问题**：主机系统未能检测到FPGA作为捐赠设备。\n\n**解决方案**：\n\n1. **验证设备ID**\n   - **步骤**：\n     1. 仔细检查固件中的 **设备ID**、**厂商ID** 和 **子系统ID** 是否与捐赠设备匹配。\n     2. 确保配置空间中没有拼写错误或不正确的值。\n\n2. **检查PCIe链路训练**\n   - **步骤**：\n     1. 使用PCIe诊断工具验证PCIe链路是否正确训练。\n     2. 确保链路速度和宽度配置与捐赠设备匹配。\n\n3. **确保正确的BAR配置**\n   - **步骤**：\n     1. 确认 **BAR大小** 和 **地址范围** 是否准确设置。\n     2. 确保没有重叠或冲突的BAR配置。\n\n4. **电源和连接检查**\n   - **步骤**：\n     1. 确保FPGA设备已正确连接并通电。\n     2. 重新插拔PCIe卡以确保连接牢固。\n\n### **13.2 内存映射和BAR配置错误**\n\n**问题**：不正确的内存映射导致内存访问失败或不准确。\n\n**解决方案**：\n\n1. **仔细检查BAR大小和地址**\n   - **步骤**：\n     1. 验证固件中的每个BAR大小是否与捐赠设备的配置匹配。\n     2. 确保BAR地址空间设置正确且不重叠。\n\n2. **使用诊断工具**\n   - **步骤**：\n     1. 利用 **lspci** 或 **Arbor** 等工具检查PCIe配置空间。\n     2. 确认BARs是否正确映射并可访问。\n\n3. **调整内存区域**\n   - **步骤**：\n     1. 如果内存区域不可访问，调整BAR配置以更好地匹配系统的内存映射。\n     2. 确保固件逻辑正确处理内存读/写操作。\n\n### **13.3 DMA性能和TLP错误**\n\n**问题**：DMA性能缓慢或与事务层数据包（TLP）相关的错误。\n\n**解决方案**：\n\n1. **优化TLP生成**\n   - **步骤**：\n     1. 确保TLP格式正确且无错误。\n     2. 使用Vivado的ILA和PCIe流量分析工具识别并修正格式错误的TLP。\n\n2. **调整有效载荷大小**\n   - **步骤**：\n     1. 将最大读取请求和有效载荷大小设置为4KB或捐赠设备支持的最高值。\n        ```verilog\n        max_read_request_size <= 4;  // 4KB\n        max_payload_size <= 4;       // 4KB\n        ```\n     2. 避免设置超出捐赠设备支持的有效载荷大小，以防止系统不稳定。\n\n3. **检查PCIe链路设置**\n   - **步骤**：\n     1. 验证PCIe链路速度和宽度是否正确配置。\n     2. 确保FPGA与主机系统准确协商链路参数。\n\n4. **固件完整性**\n   - **步骤**：\n     1. 审查并验证固件的所有最近更改，确保没有引入无意的修改。\n     2. 如果性能问题持续存在，恢复到已知稳定的固件版本。\n\n---\n\n## **14. 仿真精度和优化**\n\n确保仿真的精度对于无缝集成和不可检测的行为至关重要。本节概述了提高仿真精确度和优化性能的技术。\n\n### **14.1 精确时序仿真的技术**\n\n匹配捐赠设备的时序特性确保主机系统与仿真设备交互时如同与原始硬件设备一样。\n\n1. **使用匹配的时钟域**\n   - **步骤**：\n     1. 确保FPGA的时钟与PCIe链路的时钟速率匹配。\n     2. 同步FPGA内部的时钟，以符合PCIe时序要求。\n\n2. **控制响应延迟**\n   - **步骤**：\n     1. 实现寄存器或计数器，以管理TLP确认和中断处理的响应时间。\n     2. 确保响应延迟与捐赠设备的典型响应时间匹配。\n\n3. **实现流水线阶段**\n   - **步骤**：\n     1. 在FPGA设计中使用流水线技术，以与捐赠设备的数据处理阶段对齐。\n     2. 这减少了延迟，并确保及时的TLP生成和处理。\n\n### **14.2 对系统调用的动态响应**\n\n基于系统交互仿真设备的动态行为，确保FPGA设备在各种条件下适当响应。\n\n1. **实现状态机**\n   - **步骤**：\n     1. 在FPGA中设计状态机，以管理仿真设备的不同操作状态。\n     2. 确保状态之间的过渡基于系统调用和交互，模仿捐赠设备的行为。\n\n2. **跟踪并响应系统请求**\n   - **步骤**：\n     1. 监控传入的系统请求，并动态调整设备的响应。\n     2. 确保FPGA固件能够处理不同的工作负载，并准确响应不同类型的TLP。\n\n3. **处理异步事件**\n   - **步骤**：\n     1. 实现逻辑，以管理异步事件如中断或错误条件。\n     2. 确保固件能够以与捐赠设备一致的方式生成和响应这些事件。\n\n---\n\n## **15. 固件开发的最佳实践**\n\n遵循最佳实践确保开发过程高效、可维护且安全。\n\n### **15.1 持续测试和文档记录**\n\n- **频繁测试**\n  - **步骤**：\n    1. 每次修改后进行定期测试，以确保固件按预期运行。\n    2. 使用自动化脚本或测试台持续验证固件功能。\n\n- **记录更改**\n  - **步骤**：\n    1. 为固件的每次更改保持详细的文档记录。\n    2. 包括更改的原因及其对整体设计的影响。\n\n### **15.2 管理固件版本**\n\n- **使用版本控制**\n  - **步骤**：\n    1. 实施版本控制系统（例如 **Git**），以管理固件的不同迭代版本。\n    2. 定期提交更改，并附上描述性消息，以跟踪项目的演变。\n\n- **分支策略**\n  - **步骤**：\n    1. 使用分支管理功能开发、修复漏洞和实验性更改。\n    2. 仅在彻底测试后将稳定分支合并到主分支。\n\n### **15.3 安全考虑**\n\n- **防止未经授权的访问**\n  - **步骤**：\n    1. 确保固件不会将系统内存或硬件暴露给未经授权的访问。\n    2. 在固件中实施访问控制和验证检查。\n\n- **保护固件完整性**\n  - **步骤**：\n    1. 避免在固件开发过程中引入漏洞或后门。\n    2. 定期进行安全审查和代码审计，以维护固件的完整性。\n\n- **安全处理敏感数据**\n  - **步骤**：\n    1. 如果固件与敏感数据交互，实施加密和安全的数据处理实践。\n    2. 确保通过固件接口或日志不泄露敏感信息。\n\n---\n\n## **16. 附加资源**\n\n为了进一步提升您在开发用于设备仿真的定制固件方面的理解和能力，以下资源非常宝贵：\n\n- **PCILeech-FPGA 存储库**\n  - **链接**： [https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n\n- **Vivado FPGA 文档**\n  - **链接**： [Xilinx Vivado 文档](https://www.xilinx.com/support/documentation.html)\n\n- **PCI-SIG 规范**\n  - **链接**： [PCI-SIG](https://pcisig.com)\n\n- **PCIe TLP 初学者教程**\n  - **链接**： [PCIe TLP 初学者教程](https://www.xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1)\n\n- **Teledyne LeCroy Telescan PE 文档**\n  - **链接**： [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n\n- **Wireshark PCIe 扩展**\n  - **链接**： [Wireshark 扩展](https://www.wireshark.org/docs/)\n\n- **现场可编程门阵列（FPGA）基础**\n  - **链接**： [FPGA 基础](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug901-vivado-tutorial.pdf)\n\n- **Arbor 软件用户指南**\n  - **链接**： [Arbor 用户指南](https://www.mindshare.com/software/Arbor)\n\n- **PCIe 规范和指南**\n  - **链接**： [PCIe 规范](https://pcisig.com/specifications)\n"
  },
  {
    "path": "CN/README.md",
    "content": "# **全设备仿真的定制固件开发指南**\n\n---\n\n**特别鸣谢慷慨捐助的传奇人物，我将很快与您联系。如果您愿意，请DM我，我会在本文中添加鸣谢并提供更多信息！**\n\n正在将此指南整理到[维基](https://github.com/JPShag/PCILeech-DMA-Firmware/wiki/Introduction)中。欢迎提供帮助！\n\n----\n\n**作者留言及指南状态：**\n\n我正在透明地分享这一切，因为最近的日子异常艰难。除了因欺诈性退款造成的巨大经济损失外，我还面临多重生活和健康困境，严重影响了我上网和投入项目的时间。坦率地说，在这些个人困难中，继续创作像本指南这样全面的资源已成为一项深刻的挣扎。\n\n这预计是主指南的最后一次重大迭代。对于已经熟悉基本硬件概念（例如，FTDI芯片的功能）的更有经验的用户，我们将提供一个简洁的精简版。\n\n如果您觉得这项工作有价值并能够提供帮助，任何形式的支持都将不胜感激。您的慷慨使我尽管面临持续的挑战，仍能继续为这个社区做出贡献。我真诚地希望本指南已经并将继续成为一份宝贵的资源。\n\n---\n\n## 纪念与献词\n\n![Ross](https://github.com/user-attachments/assets/de7f12fe-8992-4738-a6af-712dc48217ee)\n\n本指南谨献给\n**Ross Freeman (1947–1989)** 的记忆\n\n作为一位富有远见的工程师、杰出的密歇根人，以及Xilinx的联合创始人，Ross Freeman被广泛认为是现场可编程门阵列（FPGA）技术之父，该技术彻底改变了计算领域。\n\n在1984年，半导体行业主要专注于固定功能芯片之时，Freeman敢于想象一种不同的范式：制造后可以重新编程的硬件。他的革命性专利（#4,870,302）和对可重构计算的不懈倡导，开启了一个四十年后仍在改变我们世界的科技范式。\n\n他的开创性创新使得在无需承担传统ASIC开发高昂成本的情况下，快速原型化和部署定制芯片解决方案成为可能，从而使硬件设计民主化，并加速了无数领域的技术进步。\n\n如今，Freeman的愿景驱动着人工智能、高性能计算、电信、汽车系统、航空航天应用以及他在世时仅是梦想的许多其他领域的尖端发展。\n\n他于2009年被追授进入国家发明家名人堂，其遗产不仅体现在硅片中，更体现在挑战我们所有人质疑既定限制并想象新可能性的技术勇气精神中。\n\n*\"FPGA的最终目标是制造可编程逻辑器件，以取代标准数字芯片。\"* — Ross Freeman\n\n---\n\n## **目录**\n\n### **第一部分：基础概念**\n\n1.  [引言](#1-引言)\n    *   [1.1 本指南的目的](#11-本指南的目的)\n    *   [1.2 目标读者](#12-目标读者)\n    *   [1.3 如何使用本指南](#13-如何使用本指南)\n2.  [关键定义](#2-关键定义)\n3.  [设备兼容性](#3-设备兼容性)\n    *   [3.1 支持的基于FPGA的硬件](#31-支持的基于fpga的硬件)\n    *   [3.2 PCIe硬件注意事项](#32-pcie硬件注意事项)\n    *   [3.3 系统要求](#33-系统要求)\n4.  [要求](#4-要求)\n    *   [4.1 硬件](#41-硬件)\n    *   [4.2 软件](#42-软件)\n    *   [4.3 环境设置](#43-环境设置)\n5.  [收集捐赠设备信息](#5-收集捐赠设备信息)\n    *   [5.1 使用Arbor进行PCIe设备扫描](#51-使用arbor进行pcie设备扫描)\n    *   [5.2 提取和记录设备属性](#52-提取和记录设备属性)\n6.  [初始固件定制](#6-初始固件定制)\n    *   [6.1 修改配置空间](#61-修改配置空间)\n    *   [6.2 插入设备序列号（DSN）](#62-插入设备序列号dsn)\n7.  [Vivado项目设置与定制](#7-vivado项目设置与定制)\n    *   [7.1 生成Vivado项目文件](#71-生成vivado项目文件)\n    *   [7.2 修改IP核](#72-修改ip核)\n\n### **第二部分：中级概念与实现**\n\n8.  [高级固件定制](#8-高级固件定制)\n    *   [8.1 配置PCIe参数以进行仿真](#81-配置pcie参数以进行仿真)\n    *   [8.2 调整BARs和内存映射](#82-调整bars和内存映射)\n    *   [8.3 仿真设备电源管理和中断](#83-仿真设备电源管理和中断)\n9.  [仿真设备特定功能](#9-仿真设备特定功能)\n    *   [9.1 实现高级PCIe功能](#91-实现高级pcie功能)\n    *   [9.2 仿真厂商特定功能](#92-仿真厂商特定功能)\n10. [事务层数据包（TLP）仿真](#10-事务层数据包tlp仿真)\n    *   [10.1 理解和捕获TLP](#101-理解和捕获tlp)\n    *   [10.2 制作用于特定操作的定制TLP](#102-制作用于特定操作的定制tlp)\n\n### **第三部分：高级技术与优化**\n\n11. [构建、烧录与测试](#11-构建烧录与测试)\n    *   [11.1 综合与实现](#111-综合与实现)\n    *   [11.2 烧录比特流](#112-烧录比特流)\n    *   [11.3 测试与验证](#113-测试与验证)\n12. [高级调试技术](#12-高级调试技术)\n    *   [12.1 使用Vivado的集成逻辑分析仪](#121-使用vivado的集成逻辑分析仪)\n    *   [12.2 PCIe流量分析工具](#122-pcie流量分析工具)\n13. [故障排除](#13-故障排除)\n    *   [13.1 设备检测问题](#131-设备检测问题)\n    *   [13.2 内存映射和BAR配置错误](#132-内存映射和bar配置错误)\n    *   [13.3 DMA性能和TLP错误](#133-dma性能和tlp错误)\n14. [仿真精度与优化](#14-仿真精度与优化)\n    *   [14.1 精确定时仿真技术](#141-精确定时仿真技术)\n    *   [14.2 对系统调用的动态响应](#142-对系统调用的动态响应)\n15. [固件开发最佳实践](#15-固件开发最佳实践)\n    *   [15.1 持续测试与文档](#151-持续测试与文档)\n    *   [15.2 管理固件版本](#152-管理固件版本)\n    *   [15.3 安全注意事项](#153-安全注意事项)\n16. [其他资源](#16-其他资源)\n17. [联系方式](#17-联系方式)\n18. [支持与贡献](#18-支持与贡献)\n\n---\n\n## **第一部分：基础概念**\n\n---\n\n## **1. 引言**\n\n### **1.1 本指南的目的**\n\n本指南的总体目标是让您掌握开发基于现场可编程门阵列（FPGA）设备的定制直接内存访问（DMA）固件的知识和实践技能。这种专用固件允许您的FPGA精确地仿真其他PCIe（Peripheral Component Interconnect Express）硬件设备的身份和行为。这种仿真是一种强大的技术，在多个高级领域具有深远意义：\n\n**硬件安全研究**：\n*   **漏洞发现**：通过仿真设备，您可以创建一个受控环境，向主机驱动程序发送格式错误或意外数据，系统性地进行模糊测试，以发现可能通过硬件外设利用的漏洞（例如，缓冲区溢出、竞态条件）。\n*   **驱动程序分析**：观察操作系统和特定驱动程序如何与硬件交互。您可以仿真具有非标准配置或未文档化功能的设备，以了解驱动程序行为、识别安全假设或逆向工程专有协议。\n*   **侧信道分析**：虽然更复杂，但仿真设备可以通过精确控制外设操作，潜在地协助进行与通过时序或功耗分析进行信息泄漏相关的实验。\n\n**红队演练与渗透测试**：\n*   **绕过安全措施**：仿真一个看似良性或白名单的硬件设备（例如，一个常见的网卡或存储控制器），以获取DMA权限。一旦实现，这允许直接与系统内存交互，可能绕过在更高软件层运行的端点检测和响应（EDR）系统或反恶意软件解决方案。\n*   **隐蔽持久性**：仿真恶意设备可以提供一种隐蔽的方式来维护对受损系统的访问，因为它可能比基于软件的植入物更难检测。\n*   **利用信任关系**：系统通常对连接的硬件有隐式信任。定制固件可以通过模仿被授予特定权限或访问的设备来利用这一点。\n\n**系统调试与诊断**：\n*   **可复现的测试平台**：创建高度特定的硬件场景，以可靠地复现可能仅在特定设备状态或数据模式下发生的难以捉摸的错误。\n*   **故障注入**：故意仿真有缺陷的设备行为（例如，错误的TLP形成、延迟响应），以测试主机系统及其驱动程序的健壮性和错误处理能力。\n\n**硬件测试与验证**：\n*   **驱动程序开发**：在物理原型可用之前，或为了模拟比物理可访问的更广泛的硬件变体，针对仿真硬件配置文件测试新的或修改的驱动程序。\n*   **合规性测试**：虽然不能替代官方合规性测试，但仿真设备可以帮助预验证PCIe协议遵守的某些方面。\n\n**传统系统支持与互操作性**：\n*   仿真老旧、停产或难以采购的PCIe设备，以保持传统系统运行或弥合不同硬件代之间的兼容性差距。\n\n通过学习本指南，您将熟练掌握：\n*   精细地从物理“捐赠”PCIe设备中提取识别属性和配置细节。\n*   修改和扩展现有开源FPGA固件框架（主要关注广泛使用的PCILeech-FPGA项目），以采用捐赠设备的身份。\n*   配置和利用以Xilinx Vivado为核心的专业FPGA开发工具链，以及Visual Studio Code等基本代码编辑工具。\n*   对PCIe架构的分层模型、DMA数据传输机制以及低级别复制硬件行为的固件开发细微之处，形成扎实的理解。\n\n### **1.2 目标读者**\n\n本指南专为已具备计算机系统、硬件原理和软件开发基础到中级知识的个人量身定制。内容技术性强，并假定读者具备进行详细、低级别工作的能力。具体来说，它面向以下人群：\n\n*   **固件开发人员**：旨在为FPGA设计或改编固件的工程师，特别是涉及高速数据传输（DMA）和通过PCIe直接硬件接口操作的应用。强烈建议具备Verilog/VHDL背景和FPGA开发工具经验。\n*   **硬件工程师**：参与PCIe硬件设计、测试或验证的专业人员。本指南可以帮助创建复杂的测试线束或在更大的系统设计中仿真组件。预计熟悉PCIe协议和数字设计。\n*   **网络安全专业人员与研究人员**：\n    *   **漏洞研究员与漏洞利用开发人员**：希望探索硬件级攻击面或开发利用DMA的概念验证漏洞。操作系统内部、内存管理和驱动程序架构的理解至关重要。\n    *   **红队成员**：寻求通过直接硬件操作来获取系统访问、持久性和数据窃取的先进技术操作员。\n    *   **数字取证与事件响应人员**：虽然本指南侧重于攻击，但理解这些技术有助于识别和分析复杂的基于硬件的攻击。\n*   **FPGA爱好者与高级业余爱好者**：有FPGA项目经验，渴望应对PCIe通信和硬件仿真等复杂挑战的个人。愿意深入研究数据手册和技术规范是关键。\n\n学习曲线可能很陡峭，特别是如果PCIe或高级FPGA概念是新知识。然而，本指南旨在将复杂主题分解为可管理的步骤。\n\n### **1.3 如何使用本指南**\n\n本指南分为三个逻辑递进的部分，旨在逐步构建您的知识：\n\n*   **第一部分：基础概念**：这第一部分至关重要。它介绍了核心术语、PCIe和DMA的基本原理、必要的硬件和软件堆栈（包括Xilinx Vivado和PCILeech-FPGA框架等工具的设置说明），以及从目标“捐赠”设备获取重要信息和进行基本固件修改的初始程序。强烈建议按顺序彻底学习本部分。\n*   **第二部分：中级概念与实现**：（后续章节）在基础知识之上，本部分将引导您进行更高级的固件定制。主题将包括微调PCIe操作参数、仿真设备特定寄存器和功能（如电源管理状态和消息信号中断 - MSI/MSI-X），以及初步理解事务层数据包（TLP）的构建和解释。\n*   **第三部分：高级技术与优化**：（后续章节）最后一部分将探讨复杂的调试方法（包括使用集成逻辑分析仪 - ILA和外部PCIe协议分析仪）、优化固件性能和仿真精度的技术、常见和复杂问题的全面故障排除，以及关于最佳实践的关键讨论，特别关注开发和部署仿真PCIe设备的安全影响。\n\n**学习本指南的步骤**：\n*   **顺序学习**：特别是对于第一部分和第二部分，请按顺序学习各节，因为后面的概念建立在前面的基础之上。\n*   **动手实践**：这是一份实践指南。请在您自己的硬件上积极执行设置步骤、代码修改和实验。\n*   **适应您的环境**：文件路径、特定设备ID和软件版本可能有所不同。理解指令背后的概念，以使其适应您的特定设置。\n*   **查阅外部资源**：PCIe规范和FPGA文档是您的最终参考。本指南进行简化和引导，但深入研究通常需要查阅原始资料。\n*   **迭代开发**：固件开发很少是线性的。预期会进行迭代、调试和改进您的设计。广泛使用故障排除部分和调试技术。\n\n您将使用HDL（PCILeech-FPGA中的SystemVerilog）、FPGA综合和实现工具（Vivado），并可能使用主机端编程工具和PCIe分析实用程序。\n\n---\n\n## **2. 关键定义**\n\n牢固掌握以下术语对于理解PCIe设备仿真和定制固件开发的复杂性至关重要。这些术语将在整个指南中广泛使用。\n\n*   **DMA (Direct Memory Access)** (直接内存访问)：\n    *   **定义**：现代计算机体系结构的一项基本功能，允许硬件外设（如网卡、GPU或您的基于FPGA的仿真设备）直接读取和写入主系统内存（RAM），而无需CPU参与每个字节的传输。\n    *   **重要性**：DMA对于高性能I/O操作至关重要。通过将数据传输任务从CPU卸载，它使CPU能够执行其他计算，显著提高整体系统吞吐量和效率。在本指南中，您的FPGA将利用DMA与主机系统的内存进行交互，这是一种在安全研究和红队演练中经常被利用的强大功能。\n\n*   **PCIe (Peripheral Component Interconnect Express)** (外围组件互连高速)：\n    *   **定义**：一种高速串行计算机扩展总线标准，旨在取代旧的总线标准，如PCI、PCI-X和AGP。它采用点对点拓扑结构，每个设备通过独立的串行链路连接到根联合体（通常是芯片组或CPU的一部分）。通信通过数据包进行。\n    *   **重要性**：PCIe是连接高性能外设到主板的主导标准。理解其协议、分层架构（物理层、数据链路层、事务层）和配置机制对于仿真任何现代硬件设备至关重要。\n\n*   **TLP (Transaction Layer Packet)** (事务层数据包)：\n    *   **定义**：PCIe协议事务层的数据交换基本单位。TLP负责在PCIe设备之间传输请求（例如，内存读/写、I/O读/写、配置读/写）和完成（对请求的响应）。每个TLP由一个报头、一个可选的数据有效载荷和一个可选的端到端CRC（ECRC）组成。\n    *   **重要性**：为了精确仿真设备，您的FPGA固件必须能够正确地形成、传输、接收和解释与捐赠设备行为匹配的TLP。理解TLP类型、格式和流控制对于高级仿真至关重要。\n\n*   **BAR (Base Address Register)** (基地址寄存器)：\n    *   **定义**：位于PCIe设备的配置空间内，BAR是特殊的寄存器，设备通过它们向主机系统请求地址空间资源。一个设备最多可以有六个32位BAR（或更少，或成对的32位BAR可以形成64位BAR）。这些寄存器定义了设备用于向主机CPU公开其寄存器和内部内存的内存映射I/O（MMIO）区域或I/O端口区域的起始地址和大小。\n    *   **重要性**：当主机系统枚举PCIe设备时，它会读取BAR以确定设备的内存和I/O要求，然后分配并用系统中物理地址图中的实际基地址来编程这些BAR。您的仿真设备必须精确定义其BAR以匹配捐赠设备，以便主机操作系统和驱动程序能够正确地与其交互。\n\n*   **FPGA (Field-Programmable Gate Array)** (现场可编程门阵列)：\n    *   **定义**：一种集成电路（IC），可以在制造后由设计者或客户进行配置——因此称为“现场可编程”。FPGA包含一个可编程逻辑块阵列和可重构互连的层次结构，允许这些块“连接”起来以实现定制数字逻辑电路。\n    *   **重要性**：FPGA是本指南中使用的核心硬件。其可重构特性使其成为仿真其他硬件设备的理想选择，因为您可以定义精确的逻辑和接口来模仿捐赠设备的PCIe存在和行为。\n\n*   **MSI/MSI-X (Message Signaled Interrupts / Message Signaled Interrupts Extended)** (消息信号中断 / 扩展消息信号中断)：\n    *   **定义**：允许PCIe设备通过向系统定义的内存地址写入特殊消息（TLP，特别是内存写入TLP）来向CPU传递中断的机制，而不是使用专用的物理中断线（如传统PCI）。MSI-X是MSI的增强版，提供更多的中断向量和更大的灵活性。\n    *   **重要性**：大多数现代PCIe设备使用MSI或MSI-X以实现更高效、更灵活的中断处理。精确仿真通常需要实现捐赠设备选择的中断机制，包括配置MSI/MSI-X能力结构并正确生成中断消息。\n\n*   **DSN (Device Serial Number)** (设备序列号)：\n    *   **定义**：一个64位全局唯一标识符，可由PCIe设备可选实现。如果存在，它通常位于设备配置空间内的扩展能力结构中。\n    *   **重要性**：虽然并非所有设备都具有DSN，但某些驱动程序或管理软件可能会使用它进行唯一标识、许可或跟踪。正确仿真它对于完全透明和避免检测到仿真设备可能很重要。\n\n*   **PCIe Configuration Space** (PCIe配置空间)：\n    *   **定义**：与每个PCIe功能（一个设备可以有多个功能）关联的标准化256字节（对于Type 0、端点设备）或4KB地址区域。此空间包含有关设备的重要信息，包括其厂商ID、设备ID、类别代码、修订ID、BAR、能力指针以及各种状态和控制寄存器。主机系统使用特殊的配置读和配置写TLP访问此空间。\n    *   **重要性**：配置空间是PCIe设备的“身份证”。设备仿真的第一步就是将捐赠设备配置空间的相关部分精确复制到您的FPGA固件中。主机系统使用此信息来识别、配置和分配资源给设备。\n\n*   **Donor Device** (捐赠设备)：\n    *   **定义**：您旨在在FPGA上仿真其身份和行为的物理PCIe硬件设备。该设备作为提取配置细节（厂商ID、设备ID、BAR设置、能力等）和行为模式的来源。\n    *   **重要性**：您的仿真 fidelity 直接取决于您能够多么精确和完整地收集并复制捐赠设备的特性。\n\n*   **Root Complex (RC)** (根联合体)：\n    *   **定义**：PCIe层级结构中将CPU和内存子系统连接到PCIe结构的实体。它代表CPU生成PCIe事务，并处理下游PCIe设备发起的事务。它还执行初始的总线枚举和配置。\n    *   **重要性**：您的仿真设备在与主机系统通信时，将主要与根联合体（或与其连接的交换机）交互。\n\n*   **Endpoint (EP)** (端点)：\n    *   **定义**：位于PCIe结构外围，消费或生产数据的一种PCIe设备。示例包括网卡、显卡、存储控制器以及您将要编程的FPGA设备。端点请求资源并向根联合体发起事务。\n    *   **重要性**：在本指南中，您的FPGA将被编程为充当一个端点设备，仿真一个特定的捐赠端点。\n\n*   **HDL (Hardware Description Language)** (硬件描述语言)：\n    *   **定义**：一种专用计算机语言，用于描述电子电路的结构、设计和操作，特别是数字逻辑电路。常见的HDL包括Verilog和VHDL。\n    *   **重要性**：您将在PCILeech-FPGA项目中使用Verilog（特别是SystemVerilog，Verilog的扩展）来定义仿真设备的定制逻辑。\n\n*   **Bitstream** (比特流)：\n    *   **定义**：加载到FPGA上的最终配置文件，用于编程其逻辑块和互连，从而实现您的定制硬件设计。它是FPGA开发工具（如Xilinx Vivado）的编译输出。\n    *   **重要性**：生成和烧录正确的比特流是将定制固件部署到FPGA的最终步骤。\n\n---\n\n## **3. 设备兼容性**\n\n成功且精确的PCIe设备仿真取决于确保您选择的基于FPGA的硬件和主机系统配置完全兼容。本节详细介绍了支持的FPGA平台、关键的PCIe硬件注意事项以及设置开发环境所需的系统要求。\n\n### **3.1 支持的基于FPGA的硬件**\n\n虽然本指南提供了一种可适用于各种基于FPGA的DMA硬件的通用方法，但我们的主要示例和具体说明将侧重于 **Xilinx 7系列FPGA**，由于其性能和可访问性的平衡，它们在开源DMA板中很常见。**Squirrel DMA (35T)** 卡因其受欢迎程度以及与PCILeech-FPGA框架的良好兼容性而受到强调。\n\n定制PCIe IP核和开发硬件描述语言（HDL）逻辑的核心原则和技术广泛适用于以下FPGA系列和特定板卡：\n\n*   **Squirrel (Artix-7 35T)**\n    *   **描述**：一种广泛可用且经济高效的基于FPGA的DMA设备，采用Xilinx Artix-7 35T FPGA。它为标准内存采集任务以及各种基本到中级设备仿真项目提供了足够的逻辑资源和内存。它是初次接触基于FPGA的DMA的优秀起点。\n    *   **主要特点**：Artix-7提供了良好的性能价格比，适用于教育和研究目的。\n*   **Enigma-X1 (Artix-7 75T)**\n    *   **描述**：与35T相比，提供增强的逻辑和内存资源的中级FPGA，通常基于Xilinx Artix-7 75T FPGA。这为更复杂的仿真场景、更大的内存映射区域或需要额外FPGA逻辑的更复杂的DMA操作提供了更大的灵活性。\n    *   **主要特点**：增加的逻辑单元和块RAM（BRAM）支持更复杂的设计。\n*   **ZDMA (Artix-7 100T)**\n    *   **描述**：基于更高性能的Artix-7 100T FPGA，针对要求更高的内存交互和大量的读/写操作进行了优化。此板卡适用于大规模DMA解决方案、高吞吐量仿真或需要大量片上内存的项目。\n    *   **主要特点**：100T变体在资源方面提供了显著升级，是突破仿真界限的理想选择。\n*   **Kintex-7 (K325T, K410T等)**\n    *   **描述**：代表高级别，Kintex-7 FPGA（例如K325T、K410T）为高度复杂的项目、大规模DMA解决方案以及需要更高PCIe通道数或速度（例如，Gen3 x8/x16）的应用提供了强大的功能。虽然价格更昂贵，但它们提供了更多的逻辑、DSP切片和内存，从而能够仿真高度复杂和苛刻的捐赠设备。\n    *   **主要特点**：用于更快PCIe世代的高性能收发器，丰富的逻辑和内存资源，适用于复杂设计。\n\n**关于FPGA系列的重要说明**：尽管原理相似，但不同的Xilinx 7系列FPGA（Artix-7、Kintex-7、Zynq-7000 PS/PL）之间，特定的IP核配置和时钟结构可能略有不同。请始终参考特定板卡文档和您所选FPGA系列的Xilinx PCIe IP核用户指南。PCILeech-FPGA项目通常提供板卡特定的Tcl脚本和源文件以简化此过程。\n\n### **3.2 PCIe硬件注意事项**\n\n为了确保基于FPGA的DMA设备在仿真中平稳无限制地运行，需要仔细考虑一些PCIe特定和主机系统功能，并在某些情况下进行修改。\n\n*   **IOMMU / VT-d / AMD-Vi 设置**\n    *   **建议**：对于初始设置和测试，**强烈建议在系统的BIOS/UEFI设置中禁用IOMMU（Intel的定向I/O虚拟化技术 - VT-d）或AMD的等效技术（AMD-Vi）**。\n    *   **理由**：IOMMU是为DMA功能设备提供内存管理单元的硬件组件。它们执行地址转换，类似于CPU的MMU，并且可以强制执行内存访问权限。虽然它们对于安全和虚拟化（防止恶意设备访问未经授权的内存区域）至关重要，但它们**会**限制DMA设备对系统内存的访问，可能干扰内存采集和设备仿真。禁用IOMMU允许DMA设备不受限制地访问内存，这对于高级仿真和安全研究目的通常是必要的。\n    *   **位置**：通常在BIOS/UEFI中的“CPU Configuration”、“Virtualization”、“Advanced Settings”或“I/O Virtualization”下找到。\n*   **内核DMA保护（Windows）/ Thunderbolt安全级别（Linux）**\n    *   **建议（Windows）**：在现代Windows系统中禁用**内核DMA保护**功能。这包括**基于虚拟化的安全性（VBS）**和**内存完整性（HVCI）**等设置。这些功能利用IOMMU来防止通过Thunderbolt或PCIe连接的外部外设进行未经授权的DMA攻击。\n    *   **步骤（Windows）**：\n        *   访问Windows安全设置：**开始 > 设置 > 隐私和安全性 > Windows 安全中心 > 设备安全性**。\n        *   在“核心隔离”下，点击“核心隔离详细信息”。\n        *   关闭“内存完整性”。\n        *   您可能还需要在BIOS/UEFI中禁用安全启动，因为VBS通常依赖于它。\n        *   **注意**：禁用这些功能会显著**降低您系统的安全态势**，使其容易受到包括涉及恶意DMA设备的各种攻击。这应该只在专用测试系统上进行，而不是在您的主机器上，并且在您了解风险的安全、隔离环境中进行。\n    *   **建议（Linux/Thunderbolt）**：如果使用带有Thunderbolt端口的系统，请了解并可能调整BIOS/UEFI中的**Thunderbolt安全级别**。较低的安全级别（例如，“无安全”、“用户授权”）通常是任意Thunderbolt/PCIe设备在未经明确主机批准的情况下执行DMA所必需的。\n*   **PCIe插槽要求**\n    *   **建议**：使用与FPGA设备要求物理匹配的兼容PCIe插槽。大多数基于Artix-7的DMA卡在PCIe Gen2 x1或x4下运行。\n    *   **理由**：\n        *   **物理匹配**：x1卡可以插入x1、x4、x8或x16插槽，但x4卡至少需要x4插槽。\n        *   **性能**：虽然x4卡*可能*在x1插槽中工作（如果物理连接是开放式或已修改的），但它将以x1速度运行，严重限制数据传输速率。为了获得最佳性能和精确仿真捐赠设备的功能，请确保FPGA板卡安装在提供至少*仿真*链路宽度和速度的插槽中（例如，如果您要仿真Gen2 x4设备，请在主机上使用Gen2 x4插槽）。\n    *   **主板BIOS设置**：一些主板允许配置PCIe插槽速度（例如，强制Gen1或Gen2）。确保这些设置不与您期望的仿真速度冲突。\n\n### **3.3 系统要求**\n\n建立一个健壮的开发环境对于高效的固件开发、综合和调试至关重要。\n\n*   **主机系统**\n    *   **处理器**：现代多核CPU对于运行Vivado等FPGA开发工具至关重要，这些工具在综合和实现过程中计算密集。（例如，Intel Core i5/i7/i9 或 AMD Ryzen 5/7/9 等效处理器，建议8代或更新）。\n    *   **内存（RAM）**：强烈建议最低16 GB RAM；对于复杂FPGA设计，**32 GB 或更高是理想选择**，因为Vivado会消耗大量内存，尤其是在实现阶段。\n    *   **存储**：一个固态硬盘（SSD）并至少有 **200 GB 的可用空间** 至关重要。FPGA工具安装（仅Vivado就可能超过50 GB）、项目文件以及综合/实现输出会迅速占用磁盘空间。SSD的速度能显著缩短构建时间。\n    *   **操作系统**：\n        *   **Windows 10/11 (64位 专业版或企业版)**：Xilinx Vivado 和许多硬件调试工具广泛支持。请记住内核DMA保护的注意事项。\n        *   **兼容的Linux发行版 (64位)**：Ubuntu LTS（长期支持）版本（例如 20.04、22.04）是Vivado常用且支持良好的系统。Linux通常为脚本编写和低级PCIe交互工具提供更灵活的环境。\n*   **外围设备**\n    *   **JTAG编程器**：将编译后的比特流烧录到基于FPGA的DMA卡上绝对必需。示例包括Xilinx Platform Cable USB II、Digilent JTAG-HS3 或某些开发板上集成的JTAG编程器。确保它与您的FPGA板卡和Vivado兼容。\n    *   **PCIe插槽**：如第3.2节所述，确保您的主机系统有可用的兼容PCIe插槽用于DMA卡。\n    *   **USB端口**：用于连接JTAG编程器，并可能用于连接FPGA板卡的UART/串行控制台以进行调试输出。\n\n---\n\n## **4. 要求**\n\n本节概述了进行PCIe设备仿真定制固件开发所必需的基本硬件和软件组件，以及推荐的环境设置。在开始之前，具备这些先决条件将简化您的开发过程。\n\n### **4.1 硬件**\n\n*   **捐赠PCIe设备**\n    *   **目的**：这是您打算在FPGA上仿真其配置和行为的物理硬件设备。它作为关键识别细节、寄存器值和操作特性的权威来源。\n    *   **示例**：常见示例包括标准网卡（NIC）、SATA或NVMe存储控制器、USB控制器，或任何其他您可以安全地从系统中移除进行分析的通用PCIe扩展卡。强烈建议使用对系统操作非必需的设备，因为您将检查其低级配置。\n*   **DMA FPGA卡**\n    *   **描述**：一种基于FPGA的开发板，专门设计或改编用于通过PCIe接口执行直接内存访问（DMA）操作。这是您的定制固件将加载到的平台。\n    *   **示例**：如第3.1节所述，兼容卡包括 **Squirrel (Artix-7 35T)**、**Enigma-X1 (Artix-7 75T)**、**ZDMA (Artix-7 100T)** 或各种基于 **Kintex-7** 的解决方案。确保您选择的卡具有PCIe金手指连接器。\n*   **JTAG编程器**\n    *   **目的**：这个关键工具促进了您的开发PC与DMA卡上FPGA之间的通信。它用于将编译后的比特流编程（烧录）到FPGA上，更重要的是，用于使用Vivado的硬件管理器和集成逻辑分析仪（ILA）等工具进行交互式调试。\n    *   **示例**：\n        *   **Xilinx Platform Cable USB II**：Xilinx FPGA传统且广泛兼容的编程器。确保您已安装必要的驱动程序。\n        *   **Digilent JTAG-HS3 / JTAG-HS2**：流行且可靠的编程器，以良好的Vivado集成和支持而闻名。HS3提供更快的编程速度。\n        *   **集成JTAG**：某些FPGA板可能具有板载USB转JTAG桥（例如FTDI芯片），这消除了对独立编程器的需求。请查阅您的板卡文档。\n\n### **4.2 软件**\n\n*   **Xilinx Vivado Design Suite**\n    *   **描述**：Xilinx（现为AMD）官方的、全面的FPGA开发环境。Vivado对于综合您的HDL代码、将设计实现到目标FPGA上、生成最终比特流以及执行硬件调试至关重要。它包括必要的IP核、编译器和实用程序。\n    *   **下载**：访问Xilinx（AMD）官方下载页面：[https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html)。\n    *   **版本说明**：虽然一些旧指南可能引用Vivado 2020.1等旧版本，但强烈建议下载与您的目标FPGA系列（Artix-7、Kintex-7）兼容的**最新稳定版本**（例如Vivado 2023.x或更高版本）。PCILeech-FPGA项目通常支持较新的Vivado版本。\n*   **Visual Studio Code**\n    *   **描述**：Microsoft出品的高度可定制且功能丰富的代码编辑器。它是编写和编辑Verilog/SystemVerilog HDL代码的绝佳选择，因为它拥有广泛的扩展生态系统，提供语法高亮、代码检查、自动补全和版本控制集成等功能。\n    *   **下载**：[https://code.visualstudio.com/](https://code.visualstudio.com/)\n*   **PCILeech-FPGA**\n    *   **描述**：一个用于基于FPGA的DMA开发的开源框架和基础代码库。它提供了即插即用的PCIe IP核实例化和一个结构良好的项目，是定制固件的绝佳起点。本指南将大量利用其架构。\n    *   **仓库**：[https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n*   **Arbor (MindShare)**\n    *   **描述**：一款强大且用户友好的软件工具，专门设计用于深入扫描和分析PCIe设备。它提供了对连接PCIe硬件的配置空间、功能和寄存器的详细洞察，对于收集捐赠设备信息来说非常有价值。\n    *   **下载**：可从MindShare网站获取：[https://www.mindshare.com/](https://www.mindshare.com/)（您可能需要导航到他们的软件部分）。\n    *   **注意**：通常需要创建账户，并且可能提供限时试用。\n*   **替代PCIe设备分析工具**\n    *   **Telescan PE (Teledyne LeCroy)**：\n        *   **描述**：Teledyne LeCroy提供的一款免费PCIe流量分析和设备枚举工具。虽然它主要是一款与其硬件协议分析仪交互的软件工具，但它也可以在没有专用硬件的情况下提供一些基本的配置空间视图。\n        *   **下载**：[https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n        *   **注意**：需要手动注册和批准才能下载。\n    *   **OS原生工具（用于基本检查）**：\n        *   **Windows设备管理器**：在设备属性的“详细信息”选项卡下提供基本的厂商ID、设备ID、子系统ID和类别代码信息。\n        *   **Linux `lspci` 工具**：一个强大的命令行工具，用于检查PCIe设备。使用`lspci -nn`查看厂商/设备ID，`lspci -vvv`查看包括BAR和功能在内的详细信息，`lspci -s <BUS:DEV.FUN> -xxxx`用于原始配置空间转储。\n\n### **4.3 环境设置**\n\n一个干净且正确配置的开发环境对于避免常见陷阱并确保流畅的工作流程至关重要。\n\n#### **4.3.1 安装Xilinx Vivado设计套件**\n\n**步骤**：\n1.  **访问Xilinx (AMD) Vivado下载页面**：[https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html)。\n2.  **下载适当版本**：选择与您的操作系统兼容的最新稳定版Vivado，更重要的是，它必须与您的特定FPGA设备（例如Artix-7、Kintex-7）兼容。查阅Vivado发行说明以了解设备支持情况。\n3.  **运行安装程序**：执行下载的安装程序并仔细遵循屏幕上的说明。\n4.  **选择必要组件**：在安装过程中，系统会提示您选择要安装的设备家族。**至关重要的是，选择与您的FPGA板卡对应的设备家族（例如，Artix-7/Kintex-7的“7 Series”）**。这与安装所有家族相比，能节省大量磁盘空间。确保您选择“设计工具”（综合、实现）和“编程与调试”组件。\n5.  **启动Vivado**：安装完成后，启动Vivado以确认它能无错误打开，并且许可证（如果适用）已正确配置。\n\n#### **4.3.2 安装Visual Studio Code**\n\n**步骤**：\n1.  **访问Visual Studio Code下载页面**：[https://code.visualstudio.com/](https://code.visualstudio.com/)。\n2.  **下载并安装**：下载适用于您操作系统的安装程序，并遵循标准安装提示。\n3.  **安装HDL支持扩展**：安装VS Code后，打开它并导航到扩展视图（Ctrl+Shift+X或Cmd+Shift+X）。搜索并安装适用于Verilog/SystemVerilog的相关扩展，例如：\n    *   **Verilog-HDL/SystemVerilog** (由mshr-h提供)\n    *   **VHDL** (如果您也使用VHDL)\n    这些扩展提供了语法高亮、代码检查和其他有用的功能。\n\n#### **4.3.3 克隆PCILeech-FPGA仓库**\n\n此仓库包含您将要修改的基础固件结构和脚本。\n\n**步骤**：\n1.  **打开终端或命令提示符**：（例如，Windows上的Git Bash，Linux上的Terminal）。\n2.  **导航到您想要的目录**：选择一个您想存储项目的位置。\n    ```bash\n    cd ~/Projects/ # 在Linux/macOS上\n    cd C:\\Users\\YourUsername\\Documents\\Projects\\ # 在Windows上\n    ```\n3.  **克隆仓库**：\n    ```bash\n    git clone https://github.com/ufrisk/pcileech-fpga.git\n    ```\n4.  **导航到克隆的目录**：\n    ```bash\n    cd pcileech-fpga\n    ```\n    这将是您的主项目目录。PCILeech-FPGA项目通常包含不同板卡变体的子目录（例如`pcileech-artix-7-50t`、`pcileech-squirrel-35t`）。您将根据您的特定硬件导航到相关的板卡特定目录。\n\n#### **4.3.4 设置一个干净的开发环境**\n\n**建议**：始终在隔离或专用的环境中工作，尤其是在处理低级硬件和潜在的安全隐患时。\n\n**步骤**：\n1.  **使用专用开发机或虚拟机**：\n    *   **物理机**：如果可能，使用一台单独的物理计算机进行FPGA开发和测试。这可以防止在您的主机器上发生意外的系统不稳定或安全风险。\n    *   **虚拟机（VM）**：虚拟机可以是隔离开发环境的好选择。然而，通常需要向虚拟机进行直接PCIe直通（PCIe热插拔或VT-d直通），FPGA卡才能被正确检测和操作，这可能配置复杂，并且如果操作不当，仍然可能暴露主机。对于初始工具安装和代码编辑，虚拟机完全没问题。\n2.  **最小化后台应用程序**：确保没有其他资源密集型应用程序正在运行，这些应用程序可能会干扰Vivado在综合和实现过程中的性能。\n3.  **禁用冲突软件**：在开发和测试期间，暂时禁用任何可能干扰低级硬件访问或JTAG通信的防病毒、防火墙或安全软件。完成工作后请记得重新启用它们。\n\n---\n\n## **5. 收集捐赠设备信息**\n\n精确的设备仿真取决于精细地提取和复制捐赠设备的关键信息。这种全面的数据收集使您的FPGA能够忠实地模仿目标硬件的PCIe配置和行为，确保与主机系统接口时的兼容性和功能性。\n\n### **5.1 使用Arbor进行PCIe设备扫描**\n\n**Arbor** 是一款强大且用户友好的工具，专为深入扫描PCIe设备而设计。它提供了对连接硬件配置空间的详细洞察，使其成为提取设备仿真所需信息的宝贵资源。\n\n#### **5.1.1 安装Arbor**\n\n要开始使用Arbor进行设备扫描，您必须首先在系统上安装该软件。\n\n**步骤：**\n\n1.  **访问Arbor下载页面：**\n    *   使用您偏好的网页浏览器导航到MindShare官方网站（[https://www.mindshare.com/](https://www.mindshare.com/)）。您需要找到他们的“Software”或“Downloads”部分来定位Arbor。\n    *   确保您直接访问该网站，以避免任何恶意重定向。\n2.  **创建账户（如果需要）：**\n    *   Arbor可能要求您创建用户账户才能访问下载链接。\n    *   提供必要的信息，例如您的姓名、电子邮件地址和组织。\n    *   如果出现提示，请验证您的电子邮件以激活您的账户。\n3.  **下载Arbor：**\n    *   登录后，找到Arbor的下载部分。\n    *   选择与您的操作系统兼容的版本（例如，Windows 10/11 64位）。\n    *   点击 **Download** 按钮并将安装程序保存到计算机上已知的位置。\n4.  **安装Arbor：**\n    *   找到下载的安装程序文件（例如，`ArborSetup.exe`）。\n    *   右键单击安装程序并选择 **以管理员身份运行** 以确保它具有必要的权限。\n    *   按照屏幕上的说明完成安装过程。\n        *   接受许可协议。\n        *   选择安装目录。\n        *   如果需要，选择创建桌面快捷方式。\n5.  **验证安装：**\n    *   安装完成后，确保Arbor列在您的“开始”菜单或桌面上。\n    *   启动Arbor以确认它能无错误打开。\n\n#### **5.1.2 扫描PCIe设备**\n\n安装Arbor后，您可以继续扫描系统中的PCIe设备。\n\n**步骤：**\n\n1.  **启动Arbor：**\n    *   双击桌面上的Arbor图标或通过“开始”菜单找到它。\n    *   如果用户账户控制（UAC）提示，允许应用程序对设备进行更改。\n2.  **导航到本地系统选项卡：**\n    *   在Arbor界面中，找到导航窗格或选项卡。\n    *   单击 **Local System** 以访问扫描本地机器的工具。\n3.  **扫描PCIe设备：**\n    *   查找 **Scan** 或 **Rescan** 按钮，通常位于界面的顶部或底部。\n    *   点击 **Scan/Rescan** 以启动检测过程。\n    *   等待扫描过程完成；这可能需要几分钟，具体取决于连接的设备数量。\n4.  **审查检测到的设备：**\n    *   扫描完成后，Arbor将显示所有检测到的PCIe设备的列表。\n    *   设备通常会列出其名称、设备ID和其他识别信息。\n\n#### **5.1.3 识别捐赠设备**\n\n识别正确的捐赠设备对于精确仿真至关重要。\n\n**步骤：**\n\n1.  **在列表中找到您的捐赠设备：**\n    *   滚动浏览Arbor检测到的设备列表。\n    *   查找与您的捐赠硬件的品牌和型号匹配的设备。\n    *   设备可能按其厂商名称、设备类型或功能列出。\n2.  **验证设备详细信息：**\n    *   单击设备以选中它。\n    *   确认 **Device ID** 和 **Vendor ID** 与您的捐赠设备匹配。\n        *   **提示：** 这些ID通常可以在设备文档或制造商网站上找到。对于常见设备，快速在网上搜索“\\[设备名称] Vendor ID Device ID”通常能得到结果。\n3.  **查看详细配置：**\n    *   选中设备后，找到并单击类似 **View Details** 或 **Properties** 的选项。\n    *   这将打开一个详细视图，显示设备的配置空间和功能。\n4.  **与物理硬件交叉引用：**\n    *   如果列出了多个类似设备，请将 **Slot Number** 或 **Bus Address** 与安装捐赠设备的物理插槽交叉引用。这有助于确认您正在分析正确的硬件。\n\n#### **5.1.4 捕获设备数据**\n\n从捐赠设备中提取详细信息对于精确仿真至关重要。\n\n**要提取的信息：**\n\n*   **设备ID (0xXXXX)：** 唯一标识设备型号的16位标识符。\n*   **厂商ID (0xYYYY)：** 分配给制造商的16位标识符。\n*   **子系统ID (0xZZZZ)：** 标识特定子系统或变体（例如，产品线中的特定型号）。\n*   **子系统厂商ID (0xWWWW)：** 标识子系统的厂商（通常与主厂商ID相同，但对于OEM版本可能会有所不同）。\n*   **修订ID (0xRR)：** 指示设备的硬件修订级别。\n*   **类别代码 (0xCCCCCC)：** 一个24位代码，定义设备的主要功能/类型（例如，`0x020000`用于以太网控制器，`0x010802`用于NVMe控制器）。这有助于操作系统加载通用驱动程序。\n*   **基地址寄存器 (BARs)：**\n    *   定义设备使用的内存或I/O地址区域的寄存器。\n    *   包括BAR0到BAR5，每个都可能是32位或64位。对于每个BAR，请记录其 **类型（内存或I/O）**、**位宽（32位或64位）**、**大小（例如，256 MB，4KB）** 和 **可预取状态（是/否）**。这对于内存映射至关重要。\n*   **功能：** 列出支持的功能及其配置，通常在配置空间中的链表结构中找到。示例包括：\n    *   **PCIe功能结构**：PCIe链路速度（例如，Gen2，Gen3），链路宽度（例如，x1，x4），最大载荷大小，最大读取请求大小。\n    *   **MSI/MSI-X功能结构**：消息信号中断信息，包括支持的向量数量。\n    *   **电源管理功能结构**：支持的电源状态（D0，D1，D2，D3hot，D3cold）。\n*   **设备序列号 (DSN)：** 一个64位唯一标识符，如果设备支持（在“设备序列号”扩展功能中找到）。并非所有设备都实现了此功能。\n\n**步骤：**\n\n1.  **导航到PCI配置选项卡：**\n    *   在设备详细视图中，找到并选择 **PCI Config** 或 **Configuration Space** 选项卡。这通常会以解码视图显示原始配置空间寄存器。\n2.  **记录相关详细信息：**\n    *   仔细记录上面列出的每个所需字段。\n    *   使用截图或将值复制到文本文件、专用电子表格或结构化文档格式中以确保准确性。\n    *   确保十六进制值正确记录，包括是否使用`0x`前缀。\n3.  **展开功能列表：**\n    *   查找标记为 **Capabilities** 或 **Advanced Features** 的部分。这些通常是可点击或可展开以显示子部分的。\n    *   记录存在的每个功能及其相关参数（例如，MSI消息控制，电源状态标志，当前/最大PCIe链路设置）。\n4.  **详细检查BAR：**\n    *   在配置空间中，找到BAR0到BAR5的条目。\n    *   对于每个活动的BAR，记录其分配的大小、是内存映射还是I/O、其位宽（32位或64位）以及是否可预取。这些信息通常在Arbor的GUI中清晰显示。\n5.  **保存数据以备参考：**\n    *   将所有提取的信息编译成一个组织良好的文档（例如，Markdown文件、`.txt`文件或Excel电子表格）。\n    *   为每个部分清晰标记，以便在固件定制期间轻松参考。\n\n### **5.2 提取和记录设备属性**\n\n捕获数据后，理解每个属性的重要性并确保其准确记录对于成功仿真至关重要。\n\n**确保您已准确记录以下内容：**\n\n1.  **设备ID：**\n    *   **目的：** 唯一标识PCIe设备的特定型号。\n    *   **仿真用法：** 对于主机操作系统（OS）正确识别仿真设备至关重要，更重要的是，它能尝试加载适当的设备驱动程序。\n2.  **厂商ID：**\n    *   **目的：** 标识PCIe设备的制造商。\n    *   **仿真用法：** 与设备ID结合使用，形成主机操作系统用于将设备与相应驱动程序匹配的唯一标识符（`VendorID:DeviceID`）。\n3.  **子系统ID和子系统厂商ID：**\n    *   **目的：** 这些可选ID允许区分同一厂商设备的变体，或区分主厂商/设备ID可能为通用的OEM特定版本。\n    *   **仿真用法：** 对于仿真具有多种配置的设备或OEM提供的设备很重要，因为驱动程序可能会专门查找这些值。\n4.  **修订ID：**\n    *   **目的：** 指示设备的硬件修订级别。\n    *   **仿真用法：** 有助于识别可能需要不同驱动程序、固件或具有细微行为差异的特定硬件版本。\n5.  **类别代码：**\n    *   **目的：** 一个24位代码，用于对设备的通用功能进行分类（例如，`0x020000`用于以太网控制器，`0x010802`用于NVMe控制器，`0x0C0300`用于USB主机控制器）。它由基本类别、子类别和编程接口组成。\n    *   **仿真用法：** 允许操作系统理解设备的通用功能，并在找不到特定厂商驱动程序时加载通用类别驱动程序。这对于初始设备识别至关重要。\n6.  **基地址寄存器（BARs）：**\n    *   **目的：** 定义设备用于寄存器、内部缓冲区或配置空间扩展的内存映射或I/O端口地址区域。主机操作系统在枚举期间将物理地址分配给这些BAR。\n    *   **仿真用法：** 对于将仿真设备的内部内存和寄存器映射到主机系统的地址空间至关重要。每个BAR的大小、类型（内存/I/O，32/64位）和可预取状态必须与捐赠设备精确匹配。\n7.  **功能：**\n    *   **目的：** 列出设备支持的高级功能，如高级错误报告、电源管理、MSI/MSI-X、PCIe高级功能（如AER、VC/PF）等。每个功能由一个具有其自身寄存器的结构定义。\n    *   **仿真用法：** 对于准确复制捐赠设备如何宣传其功能以及主机系统如何与这些功能交互（例如，中断传递机制、电源状态转换、错误报告）至关重要。\n8.  **设备序列号（DSN）：**\n    *   **目的：** 设备的唯一64位标识符，通常是可选的扩展功能。\n    *   **仿真用法：** 虽然可选，但某些驱动程序或管理应用程序可能会专门查询并依赖DSN进行识别、许可或安全检查。准确仿真此功能可以防止您的设备被检测为通用或修改的外设。\n\n**数据收集的最佳实践：**\n\n*   **组织数据：** 创建一个结构化的文档或电子表格。为每个属性使用清晰的标题和子标题。模板会很有益。\n*   **包含单位和格式：** 始终注明大小的单位（例如，MB、KB），并为十六进制值使用一致的格式（例如，`0x1234`、`16'h1234`）。\n*   **与规范交叉引用（如果可能）：** 如果可用，查阅捐赠设备的数据手册或公开可用的规范以验证值。这有助于识别原始扫描中不明显或不寻常的配置。\n*   **保护数据：** 安全存储收集到的信息。请注意，这些数据可能包含专有或敏感信息。\n*   **理解“缺少什么”：** 像Arbor这样的专业工具非常出色，但它们可能无法捕捉复杂、高度专有设备的每一个细微之处（例如，标准配置空间之外的特定厂商定义寄存器）。对于高级仿真，您可能需要将此信息与捐赠设备驱动程序的逆向工程结合起来。\n\n---\n\n## **6. 初始固件定制**\n\n在细致地记录了捐赠设备的信息之后，下一个关键阶段是定制您的FPGA固件，以准确仿真捐赠设备。这个过程首先要修改PCIe配置空间中的关键识别寄存器，并确保设备序列号等特定标识符被正确集成。\n\n### **6.1 修改配置空间**\n\nPCIe配置空间是定义设备如何被识别并与主机系统在枚举期间交互的基本组件。精确定制此空间以匹配捐赠设备的配置文件对于成功仿真绝对至关重要，它能让主机操作系统加载正确的驱动程序并按预期交互。\n\n#### **6.1.1 导航到配置文件**\n\nPCIe配置空间参数通常在PCILeech-FPGA项目中的特定SystemVerilog（`.sv`）文件中定义。此文件将综合成配置PCIe IP核并向主机公开设备身份的逻辑。\n\n**PCILeech-FPGA（基于Artix-7的板卡，如Squirrel）的常见路径：**\n找到负责为您特定板卡配置PCIe参数的文件。对于许多Artix-7 PCILeech变体，这将是：\n```\npcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv\n```\n*   **示例（对于Squirrel 35T）**：\n    ```\n    pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv\n    ```\n    *注意：实际的文件夹名称，如`pcileech-squirrel-35t`，可能会根据您克隆的PCILeech-FPGA的具体版本或分支略有不同。克隆主仓库后，请始终导航到相关的板卡特定子目录。*\n\n#### **6.1.2 在Visual Studio Code中打开文件**\n\n编辑配置文件需要一个合适的代码编辑器，该编辑器支持SystemVerilog（或Verilog）的语法高亮，使代码更易于阅读和修改。\n\n**步骤：**\n\n1.  **启动Visual Studio Code：**\n    *   点击VS Code图标或通过“开始”菜单找到它。\n2.  **打开文件：**\n    *   使用 **文件 > 打开文件** 或按下 `Ctrl + O`（macOS上为 `Cmd + O`）。\n    *   导航到第6.1.1节中确定的配置文件路径（例如，`pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv`）。\n    *   选择文件并点击 **打开**。\n3.  **验证语法高亮：**\n    *   确保编辑器识别 `.sv` 文件扩展名并应用正确的SystemVerilog语法高亮。如果不行，请返回第4.3.2节，确保您已安装推荐的Verilog/SystemVerilog扩展程序。\n4.  **熟悉文件结构：**\n    *   滚动浏览文件。您通常会发现使用`localparam`或`reg`赋值定义的参数，通常附有解释其目的的注释。查找定义和赋值标准PCIe配置寄存器（厂商ID、设备ID等）的部分。\n\n#### **6.1.3 修改设备ID和厂商ID**\n\n更新这些基本标识符是主机系统正确将仿真设备识别为您的捐赠设备的最关键步骤。操作系统严重依赖 `Vendor ID` 和 `Device ID` 对来识别连接的硬件并加载适当的设备驱动程序。\n\n**步骤：**\n\n1.  **搜索 `cfg_deviceid`：**\n    *   在VS Code中使用搜索功能（`Ctrl + F`或`Cmd + F`）。\n    *   找到定义`cfg_deviceid`的行。它通常看起来像这样：\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'hAAAA; // 默认或占位符设备ID\n        ```\n2.  **更新设备ID：**\n    *   将`AAAA`替换为您使用Arbor从捐赠设备中提取的16位十六进制设备ID（例如，`0x1234`）。\n    *   **示例：**\n        如果捐赠设备的设备ID是`0x1234`，则将该行更新为：\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'h1234; // 更新为捐赠设备的设备ID（例如，来自网卡）\n        ```\n3.  **搜索 `cfg_vendorid`：**\n    *   找到定义`cfg_vendorid`的行。其格式将类似于`cfg_deviceid`：\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hBBBB; // 默认或占位符厂商ID\n        ```\n4.  **更新厂商ID：**\n    *   将`BBBB`替换为您从捐赠设备中提取的16位十六进制厂商ID（例如，`0xABCD`）。\n    *   **示例：**\n        如果捐赠设备的厂商ID是`0xABCD`，则将该行更新为：\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hABCD; // 更新为捐赠设备的厂商ID（例如，Intel Corporation）\n        ```\n5.  **确保格式正确：**\n    *   验证十六进制值是否正确以`16'h`为前缀（表示一个16位十六进制数）。\n    *   保持一致的缩进和注释风格以提高可读性。\n\n#### **6.1.4 修改子系统ID和修订ID**\n\n这些标识符提供了关于设备变体、特定产品型号或硬件修订的额外详细信息。虽然通常是可选的，但匹配它们能增强仿真的真实性，并且对于执行细粒度检查的驱动程序可能至关重要。\n\n**步骤：**\n\n1.  **搜索 `cfg_subsysid`：**\n    *   找到定义`cfg_subsysid`的行。\n    ```verilog\n    reg [15:0] cfg_subsysid = 16'hCCCC; // 占位符子系统ID\n    ```\n2.  **更新子系统ID：**\n    *   将`CCCC`替换为您捐赠设备的16位十六进制子系统ID（例如，`0x5678`）。\n    *   **示例：**\n        ```verilog\n        reg [15:0] cfg_subsysid = 16'h5678; // 设置为捐赠设备的子系统ID\n        ```\n3.  **搜索 `cfg_subsysvendorid`：**\n    *   找到定义`cfg_subsysvendorid`的行。\n    ```verilog\n    reg [15:0] cfg_subsysvendorid = 16'hDDDD; // 占位符子系统厂商ID\n    ```\n4.  **更新子系统厂商ID（如果适用）：**\n    *   将`DDDD`替换为您捐赠设备的16位十六进制子系统厂商ID（例如，`0x9ABC`）。如果您的捐赠设备没有唯一的子系统厂商ID（即与主厂商ID相同），您仍应将其设置为该值。\n    *   **示例：**\n        ```verilog\n        reg [15:0] cfg_subsysvendorid = 16'h9ABC; // 设置为捐赠设备的子系统厂商ID\n        ```\n5.  **搜索 `cfg_revisionid`：**\n    *   找到定义`cfg_revisionid`的行。\n    ```verilog\n    reg [7:0] cfg_revisionid = 8'hEE; // 占位符修订ID\n    ```\n6.  **更新修订ID：**\n    *   将`EE`替换为您捐赠设备的8位十六进制修订ID（例如，`0x01`）。\n    *   **示例：**\n        ```verilog\n        reg [7:0] cfg_revisionid = 8'h01; // 设置为捐赠设备的修订ID\n        ```\n\n#### **6.1.5 更新类别代码**\n\n类别代码通知主机操作系统设备的通用类型和功能（例如，网络控制器、存储设备）。这对于操作系统加载通用类别驱动程序至关重要，即使没有安装特定厂商驱动程序。\n\n**步骤：**\n\n1.  **搜索 `cfg_classcode`：**\n    *   找到定义`cfg_classcode`的行。\n    ```verilog\n    reg [23:0] cfg_classcode = 24'hFFFFFF; // 默认或占位符类别代码\n    ```\n2.  **更新类别代码：**\n    *   将`FFFFFF`替换为您从捐赠设备中提取的24位十六进制类别代码（例如，`0x020000`用于以太网控制器）。请记住格式：基本类别、子类别、编程接口。\n    *   **示例：**\n        如果捐赠设备的类别代码是`0x020000`（表示基本类别：0x02 - 网络控制器，子类别：0x00 - 以太网控制器，编程接口：0x00），则更新为：\n        ```verilog\n        reg [23:0] cfg_classcode = 24'h020000; // 设置为捐赠设备的类别代码（例如，以太网控制器）\n        ```\n3.  **验证正确的位宽：**\n    *   确保类别代码使用`24'h`前缀正确表示为24位十六进制值。\n\n#### **6.1.6 保存更改**\n\n在对配置参数进行所有修改后，保存和审查更改至关重要。\n\n**步骤：**\n\n1.  **保存文件：**\n    *   在VS Code中点击 **文件 > 保存**，或按下 `Ctrl + S`（macOS上为 `Cmd + S`）。\n2.  **审查更改：**\n    *   在关闭之前，快速重新阅读修改过的行，以根据您的捐赠设备信息文档确认其准确性。\n    *   检查是否有任何明显的语法错误或拼写错误（VS Code的扩展可能会高亮显示这些）。\n3.  **可选 - 使用版本控制：**\n    *   如果您正在使用Git（强烈推荐用于任何代码项目，尤其是固件），请以清晰且有意义的消息提交您的更改。这将创建您的修改历史记录。\n    *   **示例Git命令：**\n        ```bash\n        git add pcileech_pcie_cfg_a7.sv\n        git commit -m \"更新PCIe配置寄存器（VID, DID, SubIDs, Revision, Class Code）以匹配捐赠设备：[捐赠设备名称]\"\n        ```\n\n### **6.2 插入设备序列号（DSN）**\n\n设备序列号（DSN）是一些PCIe设备（特别是那些具有高级功能或特定驱动程序的设备）可能使用的独特64位标识符。包含它能增强仿真的真实性，并有助于绕过明确查询此值的驱动程序中的检查。\n\n#### **6.2.1 定位DSN字段**\n\nDSN（如果由捐赠设备实现）是PCIe扩展能力的一部分。在PCILeech-FPGA框架中，DSN字段通常作为您一直在编辑的同一配置文件中的可配置参数公开。\n\n**步骤：**\n\n1.  **搜索 `cfg_dsn`：**\n    *   在 `pcileech_pcie_cfg_a7.sv`（或您的板卡等效配置文件）中，使用搜索功能（`Ctrl + F` 或 `Cmd + F`）查找 `cfg_dsn`。\n2.  **理解现有赋值：**\n    *   DSN可能被设置为默认值（通常是全零）或被注释掉。它通常看起来像这样：\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // 默认DSN（如果未使用，通常为0）\n        ```\n\n#### **6.2.2 插入DSN**\n\n更新DSN涉及将其设置为从捐赠设备捕获的精确64位十六进制值。\n\n**步骤：**\n\n1.  **更新 `cfg_dsn`：**\n    *   将现有的十六进制值替换为您使用Arbor从捐赠设备中提取的64位DSN。\n    *   **示例：**\n        如果捐赠设备的DSN是`0x0011223344556677`，则更新为：\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0011223344556677; // 捐赠设备序列号\n        ```\n2.  **处理DSN不可用或不相关的情况：**\n    *   如果您的捐赠设备*没有*DSN，或者您已确定它不是您目标驱动程序所需的参数，您可以简单地将其保留为零：\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // 捐赠设备没有特定DSN，保留为默认0\n        ```\n    *   **注意**：对于关键仿真，如果捐赠设备有DSN，最好准确仿真它。\n3.  **确保格式正确：**\n    *   DSN是64位值；确保它以`64'h`前缀正确格式化为十六进制值。\n\n#### **6.2.3 保存更改**\n\n通过保存和审查文件来完成DSN修改。\n\n**步骤：**\n\n1.  **保存文件：**\n    *   在VS Code中点击 **文件 > 保存**，或按下 `Ctrl + S`。\n2.  **验证语法：**\n    *   检查VS Code的语法检查器是否有任何红色下划线或错误指示。立即纠正任何问题。\n3.  **记录更改：**\n    *   如果使用版本控制，请使用适当的消息提交更新。\n    *   **示例Git命令：**\n        ```bash\n        git commit -am \"在PCIe配置中插入捐赠设备序列号（DSN）\"\n        ```\n\n---\n\n## **7. Vivado项目设置与定制**\n\n在固件文件更新以反映捐赠设备的关键识别和配置数据后，下一个关键步骤是将这些更改集成到Vivado项目中。这包括为您的特定FPGA板卡生成项目文件，定制嵌入式PCIe IP核，并准备整个设计以进行综合和实现阶段。\n\n### **7.1 生成Vivado项目文件**\n\nVivado是Xilinx（AMD）开发套件，使用Tcl（工具命令语言）脚本来自动化项目创建、添加源文件和配置项目设置。通过运行PCILeech-FPGA框架提供的这些脚本，您可以确保您的Vivado项目已为目标FPGA板卡正确设置。\n\n#### **7.1.1 打开Vivado**\n\n启动Vivado的新会话可确保之前会话中没有残留设置或打开项目干扰当前工作。\n\n**步骤：**\n\n1.  **启动Vivado：**\n    *   在“开始”菜单（Windows）或“应用程序”文件夹（Linux/macOS）中找到Vivado应用程序图标。\n    *   点击打开。\n2.  **选择正确的版本：**\n    *   如果您安装了多个Vivado版本，请确保您启动的是与您的FPGA板卡和PCILeech-FPGA项目兼容的版本（如第4.3.1节所述，建议使用Vivado 2023.x等最新稳定版本）。\n3.  **等待启动界面：**\n    *   让Vivado完全初始化并显示欢迎界面或项目仪表板，然后才能继续。\n\n#### **7.1.2 访问Tcl控制台**\n\nVivado内的Tcl控制台是您执行脚本和直接命令的主要界面。您将在此处运行项目生成脚本。\n\n**步骤：**\n\n1.  **打开Tcl控制台：**\n    *   在Vivado界面中，导航到菜单栏。\n    *   单击 **Window** > **Tcl Console**。\n    *   Tcl控制台窗格通常会出现在Vivado窗口的底部。\n2.  **调整控制台大小（可选）：**\n    *   您可以拖动控制台的顶部边框来调整其大小，使其更高以便更好地查看命令和输出。\n3.  **清除先前命令（可选但推荐）：**\n    *   如果存在任何先前的命令或消息，您可以在控制台内右键单击并选择“Clear Console”以获得一个干净的开始。\n\n#### **7.1.3 导航到项目目录**\n\n在运行Tcl脚本之前，您必须确保Tcl控制台的当前工作目录已设置为您的板卡特定PCILeech-FPGA项目脚本所在的正确位置。\n\n**对于Squirrel DMA (Artix-7 35T) 或类似板卡：**\n\n**典型路径（克隆`pcileech-fpga`并导航到您的板卡变体后）：**\n```\nC:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/  # 在Windows上\n~/Projects/pcileech-fpga/pcileech-squirrel-35t/  # 在Linux/macOS上\n```\n*注意：将`<your_board_variant>`替换为您的板卡子目录的实际名称（例如，`pcileech-squirrel-35t`，`pcileech-artix-7-50t`）。*\n\n**步骤：**\n\n1.  **在Tcl控制台中设置工作目录：**\n    *   在Vivado Tcl控制台中，输入`cd`命令，后跟您的板卡项目目录的完整路径。\n    *   **示例（Windows）：**\n        ```tcl\n        cd C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   **示例（Linux/macOS）：**\n        ```tcl\n        cd ~/Projects/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   *自我纠正提示：即使在Windows上，Tcl路径也使用正斜杠（`/`）。*\n2.  **验证目录更改：**\n    *   要确认您处于正确的目录中，请在Tcl控制台中输入`pwd`（打印工作目录）。\n    *   控制台应显示您刚刚设置的完整路径，确认更改。\n\n#### **7.1.4 生成Vivado项目**\n\n运行适用于您的FPGA板卡的相应Tcl脚本将自动化Vivado内部的整个项目设置过程。这包括创建项目、添加所有必要的源文件（HDL、约束）以及配置核心项目设置。\n\n**步骤：**\n\n1.  **运行Tcl脚本：**\n    *   输入`source`命令，后跟您的板卡的项​​目生成脚本的名称。PCILeech-FPGA项目通常在主板卡目录中提供这些脚本。\n    *   **对于Squirrel (Artix-7 35T)（以及类似的Artix-7板卡）：**\n        ```tcl\n        source vivado_generate_project_squirrel.tcl -notrace\n        ```\n    *   **对于Enigma-X1 (Artix-7 75T)：**\n        ```tcl\n        source vivado_generate_project_enigma_x1.tcl -notrace\n        ```\n    *   **对于ZDMA (Artix-7 100T)：**\n        ```tcl\n        source vivado_generate_project_100t.tcl -notrace\n        ```\n    *   `-notrace`选项可防止每个Tcl命令的详细输出，使控制台更整洁。\n2.  **等待脚本完成：**\n    *   脚本将按顺序执行许多命令。此过程可能需要几分钟，具体取决于您的系统性能和项目的复杂性。\n    *   监控Tcl控制台的进度消息。脚本将：\n        *   在当前目录中创建一个新的Vivado项目（`.xpr`文件）。\n        *   添加所有SystemVerilog/Verilog源文件（`.sv`，`.v`）。\n        *   添加Xilinx IP核配置（`.xci`）。\n        *   添加XDC（Xilinx设计约束）文件。\n        *   可能配置各种项目设置。\n    *   **处理任何错误**：如果发生任何错误（例如，“文件未找到”、“无效命令”），脚本通常会停止。检查错误消息，纠正底层问题（例如，路径不正确、文件丢失），然后重新运行脚本。\n3.  **确认项目生成：**\n    *   成功完成后，Tcl控制台通常会指示项目已创建，并且您应该在项目目录中看到新生成的项目文件（例如，`pcileech_squirrel_top.xpr`）和相关目录（例如，`pcileech_squirrel_top.runs`，`pcileech_squirrel_top.ip`）。\n\n#### **7.1.5 打开生成的项目**\n\n现在Vivado项目文件已成功由Tcl脚本生成，您可以在Vivado GUI中打开该项目以进行进一步检查和定制。\n\n**步骤：**\n\n1.  **打开项目：**\n    *   在Vivado中，点击 **文件** > **打开项目**。\n    *   导航到您的项目目录（与您在第7.1.3节中在Tcl控制台中设置的目录相同）。\n2.  **选择项目文件：**\n    *   找到并选择与您的板卡对应的Vivado项目文件（`.xpr`扩展名）。\n    *   **对于Squirrel：** 文件名通常为 `pcileech_squirrel_top.xpr`。\n    *   点击 `.xpr` 文件以选择它。\n3.  **点击打开：**\n    *   Vivado将加载项目，显示设计层次结构、源文件、IP集成器块设计（如果使用）和各种设计视图。这可能需要一些时间。\n4.  **验证项目内容：**\n    *   在 **项目管理器** 窗口（通常在左侧）中，展开 **源文件** 窗格。\n    *   确保所有预期的源文件（Verilog/SystemVerilog、XDC、IP核）都已列出，并且设计层次结构看起来正确。\n    *   检查 **消息** 窗格（底部）中打开项目时出现的任何警告或严重警告，因为这些可能表明潜在问题。\n\n### **7.2 修改IP核**\n\nPCIe IP核是设备PCIe接口的核心。它是一个经过Xilinx（AMD）预验证、可配置的模块，用于处理复杂的PCIe协议层。尽管某些配置空间值在SystemVerilog文件中处理（第6.1节），但其他核心PCIe参数，特别是与链路能力和BAR结构相关的参数，是在Vivado中直接通过PCIe IP核的定制设置进行配置的。定制IP核可确保您的FPGA在PCIe协议级别上与捐赠硬件的行为完全一致。\n\n#### **7.2.1 访问PCIe IP核**\n\nPCIe IP核在您的Vivado项目中被实例化为一个IP块。您需要打开其定制GUI来修改其参数。\n\n**步骤：**\n\n1.  **定位PCIe IP核：**\n    *   在 **Sources**（源文件）窗格（位于 **Project Manager**（项目管理器）窗口内）中，确保已选择 **Hierarchy**（层次结构）选项卡。\n    *   展开设计层次结构，直到找到PCIe IP核的实例。\n    *   对于7系列FPGA（如Squirrel中使用的Artix-7），它通常被命名为 `pcie_7x_0.xci` 或类似名称，通常位于项目源文件的 `ip` 子目录中。\n2.  **打开IP定制窗口：**\n    *   **右键单击** `pcie_7x_0.xci` 文件。\n    *   从上下文菜单中选择 **Customize IP**（定制IP）。\n    *   将打开 **IP Configuration**（IP配置）窗口（或类似名称，如“Customize IP”或“Re-customize IP”），显示带有各种选项卡和选项的图形界面，用于配置PCIe核。\n3.  **等待IP设置加载：**\n    *   IP定制界面可能需要几分钟才能初始化并填充所有设置。在您开始进行更改之前，请确保所有选项和选项卡都已完全加载并响应。\n\n#### **7.2.2 在IP核内部定制设备ID和BAR**\n\n尽管某些设备标识符在`pcileech_pcie_cfg_a7.sv`中设置，但PCIe IP核本身也包含设备ID、厂商ID以及至关重要的基地址寄存器（BARs）的定义参数。您必须确保这些参数保持一致。`.sv`文件中的某些值可能会覆盖或输入到IP核中，但在此处也确保一致性是一个好习惯。IP核中的BAR设置尤其重要，因为它们决定了内存映射的硬件实现。\n\n**步骤：**\n\n1.  **导航到基本/识别参数：**\n    *   在IP定制窗口中，查找与 **基本**、**设备和厂商标识符**、**通用** 或 **PCIe能力** 相关的选项卡或部分。这是定义基本ID和初始链路设置的地方。\n2.  **验证/输入设备ID、厂商ID、子系统ID、修订ID、类别代码：**\n    *   **至关重要：请确认这些值与您在`pcileech_pcie_cfg_a7.sv`中设置的以及从捐赠设备中获取的值相匹配。**\n    *   查找以下字段：\n        *   **设备ID**：输入`0xXXXX`（例如，`0x1234`）。\n        *   **厂商ID**：输入`0xYYYY`（例如，`0xABCD`）。\n        *   **子系统ID**：输入`0xZZZZ`（例如，`0x5678`）。\n        *   **子系统厂商ID**：输入`0xWWWW`（例如，`0x9ABC`）。\n        *   **修订ID**：输入`0xRR`（例如，`0x01`）。\n        *   **类别代码**：输入`0xCCCCCC`（例如，`0x020000`）。\n    *   **重要提示**：某些IP核版本或特定配置可能会直接从用户逻辑（如`pcileech_pcie_cfg_a7.sv`）拉取这些值，或者可能允许直接在此处设置它们。最可靠的方法是，如果IP GUI中提供此选项，则在两个位置都保持一致设置。\n3.  **导航到基地址寄存器（BARs）选项卡：**\n    *   在IP定制窗口中，找到并选择 **BARs** 选项卡或部分。这是您定义PCIe设备暴露的内存区域的地方。\n4.  **配置每个BAR：**\n    *   对于您的捐赠设备使用的每个BAR（BAR0到BAR5），根据您使用Arbor提取的信息，仔细配置以下参数：\n        *   **启用BAR**：仅当捐赠设备使用此特定BAR时才选中此框。禁用（取消选中）捐赠设备不使用的任何BAR。\n        *   **BAR大小**：从下拉列表中选择精确的大小（例如，**256 MB**，**64 KB**，**4 KB**）。这对于主机操作系统分配正确数量的内存至关重要。\n        *   **BAR类型**：选择适当的类型：\n            *   **Memory (32-bit Addressing)**（内存（32位寻址））: 用于32位地址可访问的内存映射区域。\n            *   **Memory (64-bit Addressing)**（内存（64位寻址））: 用于可以驻留在64位地址空间中任何位置的内存映射区域（对于大内存区域或如果捐赠设备使用它，则需要）。\n            *   **I/O**: 用于传统I/O端口区域（在现代PCIe中较不常见，但仍然可能）。\n        *   **可预取**：如果捐赠设备的BAR被标记为可预取，则选中此框。此属性允许主机系统从此区域缓存或预取数据以提高性能。\n    *   **示例配置（基于您的捐赠设备）：**\n        *   **BAR0**：\n            *   启用：是\n            *   大小：**256 MB**\n            *   类型：**Memory (64-bit Addressing)**\n            *   可预取：是\n        *   **BAR1**：\n            *   启用：否（如果捐赠设备不使用BAR1）\n        *   *继续配置BAR2-BAR5，镜像捐赠设备的配置。*\n5.  **确保对齐和非重叠空间**：\n    *   Vivado IP核通常会根据您选择的大小自动处理对齐。但是，请注意PCIe规范要求BAR大小是2的幂，并且BAR必须对其大小进行对齐。\n    *   确保所有活动BAR映射的总内存不超过FPGA可用的块RAM（BRAM）或外部内存容量。\n\n#### **7.2.3 完成IP定制**\n\n在IP核定制窗口中配置所有必要的设置后，您必须应用这些更改，使其在Vivado项目中生效。\n\n**步骤：**\n\n1.  **审查所有设置：**\n    *   在应用之前，花点时间快速最后一次审查IP定制窗口中的每个选项卡。\n    *   确认所有条目都与您捐赠设备的文档规范精确匹配。这里的一个小错误可能导致设备检测或功能问题。\n2.  **应用更改：**\n    *   点击IP定制窗口底部的 **OK** 或 **Generate** 按钮（标签可能不同）。\n    *   如果Vivado提示您确认是否继续更改并重新生成IP输出产品，请点击 **Yes** 确认。\n3.  **重新生成IP核：**\n    *   Vivado现在将重新生成IP核的输出产品（例如，网表、仿真模型、新的`.xci`配置文件），以反映您的新配置。\n    *   监控 **消息** 窗格（Vivado窗口底部），查看在此重新生成过程中可能出现的任何错误、警告或严重警告。立即解决任何严重警告。\n4.  **更新项目中的IP：**\n    *   在IP核重新生成后，Vivado可能会自动更新或提示您更新项目中的任何IP依赖项。允许它这样做，以确保在整个设计中使用最新的配置。\n\n#### **7.2.4 锁定IP核**\n\n锁定IP核是Vivado中推荐的最佳实践，可防止在后续综合和实现运行期间意外修改或重新定制，这可能会潜在地恢复您精心配置的设置。\n\n**锁定的目的：**\n\n*   **防止覆盖：** 确保您在IP核GUI中进行的手动配置得以保留，不会因Vivado自动化或IP因细微项目更改而被检测为“过时”而意外覆盖。\n*   **保持一致性：** 在整个构建过程中保持IP核处于已知、稳定的状态，这对于PCIe接口等关键组件尤其重要。\n\n**步骤：**\n\n1.  **打开Tcl控制台：**\n    *   在Vivado中，如果Tcl控制台尚未打开，请转到 **Window** > **Tcl Console**。\n2.  **执行锁定命令：**\n    *   在Tcl控制台中，精确输入以下命令。此命令将PCIe IP核实例（`pcie_7x_0`）的`IP_LOCKED`属性设置为`true`。\n    ```tcl\n    set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n    ```\n    *   按 **Enter** 执行命令。\n3.  **验证锁定：**\n    *   检查 **消息** 窗格。您应该会看到一条确认属性已设置的消息。\n    *   您还可以右键单击源文件窗格中的 `pcie_7x_0.xci`，选择“IP Properties”（IP属性），并验证 `IP_LOCKED` 是否设置为 `true`。您可能还会注意到“Customize IP”（定制IP）选项现在已灰显，或者只允许“Re-customize IP”（重新定制IP），然后会警告您关于锁定。\n4.  **解锁（如果需要）：**\n    *   如果您将来需要对PCIe IP核的设置进行进一步修改，则必须先将其解锁。使用以下Tcl命令：\n    ```tcl\n    set_property -name {IP_LOCKED} -value false -objects [get_ips pcie_7x_0]\n    ```\n    *   请记住在进行和应用更改后重新锁定它。\n5.  **记录操作：**\n    *   在您的项目文档（例如，README文件、项目说明）中注明PCIe IP核已锁定是一个好习惯。这有助于项目中其他人理解其配置状态并避免混淆。\n\n---\n\n## **第二部分：中级概念与实现**\n\n---\n\n## **8. 高级固件定制**\n\n为了实现对捐赠设备精确且令人信服的仿真，除了基本识别之外，还需要对FPGA固件进行更深入的定制。这包括调整PCIe参数（例如链路速度和事务大小），细致地调整基地址寄存器（BARs）及其相关的内存映射，以及准确仿真电源管理和中断机制。这些步骤确保仿真设备不仅在主机系统看来与原始硬件相同，而且在协议和功能级别上行为也完全一致。\n\n### **8.1 配置PCIe参数以进行仿真**\n\n精确仿真要求您的FPGA设备的PCIe操作参数经过细致配置，以匹配捐赠设备的参数。这包括PCIe链路速度、链路宽度、能力指针和最大有效载荷大小等设置。正确的配置可确保与主机系统的兼容性、驱动程序和应用程序与设备交互的正确操作以及数据传输的最佳性能。\n\n#### **8.1.1 匹配PCIe链路速度和宽度**\n\nPCIe链路速度（例如，Gen1、Gen2、Gen3）和链路宽度（例如，x1、x4、x8）是决定设备最大理论数据吞吐量和性能的关键参数。将这些设置与捐赠设备匹配对于精确仿真至关重要，因为驱动程序或系统组件可能期望特定的链路能力。\n\n**步骤：**\n\n1.  **访问PCIe IP核设置：**\n    *   **打开您的Vivado项目：** 启动Vivado并打开您之前创建或修改的项目（例如，`pcileech_squirrel_top.xpr`）。确保所有源文件都已正确添加到项目中。\n    *   **定位PCIe IP核：** 在 **Sources**（源文件）窗格（通常在左侧）中，展开设计层次结构以找到PCIe IP核实例。对于Xilinx 7系列设计（如Squirrel中使用的Artix-7），这通常被命名为 `pcie_7x_0.xci`。\n    *   **定制IP核：** 右键单击 `pcie_7x_0.xci` 并选择 **Customize IP**（定制IP）。IP定制窗口将打开，显示多个选项卡中的各种配置选项。\n\n2.  **设置最大链路速度：**\n    *   **导航到链路参数：** 在IP定制窗口中，点击 **PCIe Capabilities**（PCIe功能）选项卡（有时是“PCIe Configuration”或“General”）。在此选项卡内，查找与 **Link Parameters**（链路参数）或 **Link Capability Register**（链路能力寄存器）相关的部分。\n    *   **配置最大链路速度：** 找到标有 **Maximum Link Speed**（最大链路速度）的选项（或“Target Link Speed”）。\n    *   将其设置为与您的捐赠设备支持和广告的最大链路速度相匹配。\n        *   **示例：**\n            *   如果捐赠设备在 **PCIe Gen2 (5.0 GT/s)** 下运行，选择 **5.0 GT/s**。\n            *   如果它在 **PCIe Gen1 (2.5 GT/s)** 或 **PCIe Gen3 (8.0 GT/s)** 下运行，请选择相应的选项。\n    *   **注意**：确保您的FPGA的收发器和物理硬件（主板PCIe插槽）支持所选的链路速度。FPGA只会协商到其配置的最大速度。\n\n3.  **设置链路宽度：**\n    *   **配置链路宽度：** 在相同的 **Link Parameters**（链路参数）部分中，找到 **Link Width**（链路宽度）设置（或“PCIe Link Width”、“Target Link Width”）。\n    *   将其设置为与您的捐赠设备广告的最大链路宽度相匹配。\n        *   **示例：**\n            *   如果捐赠设备使用 **x4** 链路，将 **Link Width** 设置为 **4**。\n            *   选项通常包括 **1**、**2**、**4**、**8**、**16** 通道。\n    *   **注意**：物理PCIe插槽和FPGA的封装必须支持所选的链路宽度。尝试配置大于物理连接的宽度将导致链路协商问题。\n\n4.  **保存并重新生成：**\n    *   **应用更改：** 配置链路速度和宽度后，点击 **OK** 以在IP定制窗口中应用更改。\n    *   **重新生成IP输出产品：** Vivado很可能会提示您由于所做的更改而重新生成IP核的输出产品。确认并允许重新生成过程完成。这可能需要一些时间。\n    *   **验证设置：** 一旦重新生成完成，您可以选择性地重新访问IP核设置，以确保配置已正确应用。检查Vivado中 **Messages**（消息）窗口中是否有任何警告或错误。\n\n#### **8.1.2 设置能力指针**\n\nPCIe配置空间中的能力指针是8位寄存器，它们形成一个链表，指向各种能力结构（例如，电源管理、MSI/MSI-X、PCIe Express能力）。正确设置这些指针可确保主机系统能够遍历能力列表并定位和利用设备广告的功能。\n\n**步骤：**\n\n1.  **在固件中定位能力指针：**\n    *   **打开配置文件：** 在Visual Studio Code中，打开您的板卡的主配置文件，通常是`pcileech_pcie_cfg_a7.sv`，位于`pcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv`。\n    *   **理解能力指针：** 此文件中的能力指针（`cfg_cap_pointer`）指向PCIe配置空间中的*第一个*能力结构，通常从标准64字节配置头之后开始。后续的能力通过其“下一个能力指针”字段链接起来。\n\n2.  **设置能力指针值：**\n    *   **找到`cfg_cap_pointer`的赋值：** 在代码中搜索定义`cfg_cap_pointer`的行。\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'hXX; // 当前值（例如，默认的8'h40）\n        ```\n    *   **更新能力指针：** 将`XX`替换为您使用Arbor从捐赠设备观察到的8位十六进制能力指针值。此值通常指向设备特定配置空间（通常在偏移量`0x3F`结束）之后第一个能力结构的偏移量。能力常见的起始点是`0x40`或`0x60`。\n        *   **示例：**\n            *   如果捐赠设备的第一个能力指针是`0x60`（表示其第一个能力结构在配置空间中从偏移量`0x60`开始），将该行更新为：\n                ```verilog\n                reg [7:0] cfg_cap_pointer = 8'h60; // 更新以匹配捐赠设备的第一个能力偏移量\n                ```\n    *   **确保正确对齐：** 能力结构必须对齐到4字节边界。能力指针应始终指向配置空间中有效的4字节对齐偏移量。\n\n3.  **保存更改：**\n    *   **保存配置文件：** 进行更改后，点击 **文件 > 保存** 或按下 `Ctrl + S` 保存文件。\n    *   **验证语法：** 确保更改未引入任何语法错误（VS Code通常会高亮显示这些错误）。\n    *   **添加注释以清晰说明：** 添加注释解释更改，以便将来参考和维护。\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'h60; // 设置为捐赠设备的能力指针（例如，PCIe能力位于0x60）\n        ```\n\n#### **8.1.3 调整最大载荷和读取请求大小**\n\n这些参数定义了单个PCIe事务层数据包（TLP）中可以传输的最大数据量，以及非posted内存读取请求TLP的最大大小。将这些设置与捐赠设备匹配可确保兼容性并优化数据传输操作的性能。不匹配可能导致吞吐量降低或通信错误。\n\n**步骤：**\n\n1.  **设置支持的最大载荷大小（IP核）：**\n    *   **访问设备功能：** 在PCIe IP核定制窗口（Vivado中的`pcie_7x_0.xci`）中，导航到 **PCIe Capabilities**（PCIe功能）选项卡。\n    *   **配置支持的最大载荷大小：** 找到标有 **Max Payload Size Supported**（支持的最大载荷大小）的设置（或类似名称）。\n    *   将其设置为与您的捐赠设备支持和广告的值相匹配（例如，128字节、256字节、512字节、1024字节、2048字节、4096字节）。\n        *   **示例：** 如果捐赠设备支持的最大载荷大小为 **256字节**，请从下拉列表中选择 **256字节**。\n\n2.  **设置支持的最大读取请求大小（IP核）：**\n    *   **配置支持的最大读取请求大小：** 在同一选项卡中，找到 **Max Read Request Size Supported**（支持的最大读取请求大小）设置。\n    *   将其设置为与捐赠设备的能力相匹配。这指定了设备在单个读取事务中可以请求的最大数据量。\n        *   **示例：** 如果捐赠设备支持的最大读取请求大小为 **512字节**，请选择 **512字节**。\n\n3.  **调整固件参数（匹配IP核）：**\n    *   **打开 `pcileech_pcie_cfg_a7.sv`：** 确保配置文件在Visual Studio Code中打开。\n    *   **更新固件常量：** 找到定义`max_payload_size_supported`和`max_read_request_size_supported`的行。这些通常是与您在IP核中选择的字节大小对应的位编码值。\n        ```verilog\n        reg [2:0] max_payload_size_supported = 3'bZZZ;   // 当前值\n        reg [2:0] max_read_request_size_supported = 3'bWWW; // 当前值\n        ```\n    *   **设置适当的值：** 将`ZZZ`和`WWW`替换为与所选大小对应的3位二进制表示。\n        *   **映射（根据PCIe规范）：**\n            *   **128字节**：`3'b000`\n            *   **256字节**：`3'b001`\n            *   **512字节**：`3'b010`\n            *   **1024字节**：`3'b011`\n            *   **2048字节**：`3'b100`\n            *   **4096字节**：`3'b101`\n        *   **示例：**\n            *   对于 **256字节** 载荷大小：\n                ```verilog\n                reg [2:0] max_payload_size_supported = 3'b001; // 支持最大256字节 (0x100)\n                ```\n            *   对于 **512字节** 读取请求大小：\n                ```verilog\n                reg [2:0] max_read_request_size_supported = 3'b010; // 支持最大512字节 (0x200)\n                ```\n    *   **原因**：这些固件参数通常决定了与PCIe核接口的用户逻辑的行为，确保您的逻辑遵循配置的最大值。\n\n4.  **保存更改：**\n    *   **保存文件：** 更新`pcileech_pcie_cfg_a7.sv`中的值后，保存文件。\n    *   **验证一致性：** Vivado PCIe IP核GUI中配置的值*必须*与您的HDL配置文件中设置的值*匹配*。任何不匹配都可能导致意外行为或链路训练问题。\n    *   **添加注释：** 在您的代码中清晰地记录这些更改，以便将来参考。\n\n### **8.2 调整BARs和内存映射**\n\n基地址寄存器（BARs）是PCIe设备向主机系统公开其内部内存和寄存器的基本方式。正确配置BARs并在FPGA的BRAMs（块RAMs）和逻辑中定义它们的内存映射对于精确仿真和主机端设备驱动程序的正常运行至关重要。\n\n#### **8.2.1 设置BAR大小和类型（IP核和BRAM）**\n\n配置BAR大小和类型可确保您的仿真设备在枚举期间向主机请求正确的地址空间量，并且主机适当地分配和映射这些区域。这还涉及将这些地址区域与FPGA内的物理内存块关联起来。\n\n**步骤：**\n\n1.  **访问BAR配置（PCIe IP核）：**\n    *   **定制PCIe IP核：** 在Vivado中，右键单击 `pcie_7x_0.xci` 并选择 **Customize IP**（定制IP）以打开其配置GUI。\n    *   **导航到BARs选项卡：** 在IP定制窗口中，点击 **Base Address Registers (BARs)**（基地址寄存器（BARs））选项卡。\n\n2.  **配置每个BAR（IP核）：**\n    *   **匹配捐赠设备的BARs：** 对于每个BAR（BAR0到BAR5），根据您使用Arbor从捐赠设备中提取的信息，细致地设置大小、类型和可预取状态。\n    *   **启用/禁用BARs：** 确保只启用捐赠设备实际使用的BARs。禁用（取消选中）任何未使用的BARs。\n    *   **设置BAR大小：** 为每个*已启用*的BAR从下拉列表中选择适当的大小。这将是2的幂次（例如，4KB、8KB、64KB、1MB、256MB、1GB）。\n        *   **示例：**\n            *   如果 **BAR0** 是 **64 KB**，将 **BAR0 Size** 设置为 **64 KB**。\n            *   如果 **BAR1** 是 **128 MB**，将 **BAR1 Size** 设置为 **128 MB**。\n    *   **设置BAR类型：**\n        *   如果BAR是内存映射的，选择 **Memory (32-bit Addressing)**（内存（32位寻址））或 **Memory (64-bit Addressing)**（内存（64位寻址））。如果捐赠设备的BAR是64位或您需要访问4GB以上的地址，请选择 **64-bit Addressing**。\n        *   如果BAR用于I/O端口空间（现代PCIe设备较少见），选择 **I/O**。\n    *   **设置可预取状态**：如果捐赠设备的BAR被识别为可预取，请选中“Prefetchable”（可预取）框。此位允许主机预取该区域的数据，可能提高性能。\n\n3.  **更新BRAM配置（如果适用）：**\n    *   许多PCILeech-FPGA项目使用Xilinx块RAM（BRAM）IP核来表示BARs暴露的内存区域。这些BRAM提供仿真设备内存的物理存储。\n    *   **定位BRAM IP核：** 在您的Vivado项目 **Sources**（源文件）窗格中，在`ip`子目录（或类似目录）中，您可能会找到BRAM的`.xci`文件，名称可能类似：\n        ```\n        pcileech-fpga/<your_board_variant>/ip/bram_bar_zero4k.xci\n        pcileech-fpga/<your_board_variant>/ip/bram_pcie_cfgspace.xci\n        # 可能还有BAR1、BAR2等的其他文件\n        ```\n    *   **修改BRAM大小：** 对于与*已启用*BAR关联的每个BRAM IP核，您可能需要 **Customize IP**（定制IP）（右键单击`.xci`文件）并调整其内存大小配置，以精确匹配相应的BAR大小。\n        *   **示例：** 如果BAR0是256MB，请确保连接到BAR0的BRAM大小为256MB。\n        *   **注意**：确保所有活动BAR所需的总内存不超过您的FPGA设备的物理BRAM容量。超出容量将导致实现失败。\n\n4.  **保存并重新生成：**\n    *   **应用更改（IP核）：** 在PCIe IP核中配置BAR后，点击IP定制窗口中的 **OK**。\n    *   **重新生成IP核：** Vivado将提示您由于所做的更改而重新生成PCIe IP核和任何相关的BRAM IP核。允许重新生成完成。这可确保硬件网表反映您的新BAR定义。\n    *   **检查错误：** 检查 **Messages**（消息）窗口中是否有与BAR配置或BRAM实例化相关的任何警告或错误。\n\n#### **8.2.2 在固件中定义BAR地址空间**\n\n尽管PCIe IP核配置了BAR的*硬件*方面，但您的定制固件（SystemVerilog代码）需要定义当主机CPU对这些BAR区域内的地址执行读写操作时，仿真设备如何响应的*逻辑*。这涉及地址解码和实现寄存器/内存访问逻辑。\n\n**步骤：**\n\n1.  **打开BAR控制器文件：**\n    *   在Visual Studio Code中，打开负责处理BAR访问的SystemVerilog文件。对于PCILeech-FPGA，这通常是：\n        ```\n        pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv\n        ```\n        此模块通常接收PCIe内存读/写TLP，并解码地址以确定正在访问哪个BAR（以及该BAR内的哪个偏移量）。\n\n2.  **实现地址解码逻辑：**\n    *   在`pcileech_tlps128_bar_controller.sv`模块中，您会找到确定传入事务目标是哪个BAR的逻辑。这通常涉及根据配置的BAR大小检查地址位。\n    *   您需要定义传入地址`req_addr`（来自TLP）如何映射到您的特定BAR内的偏移量。\n    *   **概念示例：**\n        ```verilog\n        // 示例：BAR0的逻辑（假设它是一个256MB的64位内存BAR，用于寄存器/数据）\n        // 'bar_hit[0]'是一个指示命中BAR0的输入信号，通常来自PCIe核。\n        // 'req_addr'是传入的PCIe地址。\n        // 'req_be'是来自TLP的字节使能。\n        // 'req_data'是传入的写入数据。\n        // 'rsp_data'是传出的读取数据。\n\n        // 假设BAR0是256MB (2^28字节)，地址位 [27:0] 在BAR范围内。\n        localparam BAR0_SIZE_BITS = 28; // 2^28 = 256MB\n\n        reg [31:0] internal_register_0; // BAR0内的示例寄存器\n        reg [31:0] internal_register_1; // 另一个示例寄存器\n\n        assign bar0_offset = req_addr[BAR0_SIZE_BITS-1:0]; // 提取BAR0内的偏移量\n\n        always_comb begin\n            // 默认响应\n            rsp_data = 32'hFFFFFFFF; // 默认值为全F或类似值，表示未映射区域\n\n            if (bar_hit[0]) begin // 如果事务目标是BAR0\n                if (req_write) begin // 这是写入操作\n                    case (bar0_offset)\n                        // 示例：将偏移量0x0映射到internal_register_0\n                        32'h0000_0000: begin\n                            if (req_be[3]) internal_register_0[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_0[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_0[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_0[7:0]   = req_data[7:0];\n                        end\n                        // 示例：将偏移量0x4映射到internal_register_1\n                        32'h0000_0004: begin\n                            if (req_be[3]) internal_register_1[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_1[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_1[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_1[7:0]   = req_data[7:0];\n                        end\n                        // 添加更多寄存器映射或内存访问（例如，BRAM访问）\n                        default: begin\n                            // 处理BAR0内未映射的写入，例如，忽略或记录\n                        end\n                    endcase\n                end else if (req_read) begin // 这是读取操作\n                    case (bar0_offset)\n                        // 示例：从internal_register_0读取\n                        32'h0000_0000: rsp_data = internal_register_0;\n                        // 示例：从internal_register_1读取\n                        32'h0000_0004: rsp_data = internal_register_1;\n                        // 添加更多寄存器映射或内存访问（例如，BRAM访问）\n                        default: begin\n                            rsp_data = 32'h0; // 对于未映射的读取返回0或特定错误值\n                        end\n                    endcase\n                end\n            end\n        end\n        ```\n    *   **处理数据传输：** `always_comb`块（或`always_ff`用于时序逻辑）应定义如何为读取生成`rsp_data`，以及如何根据`bar0_offset`和字节使能（`req_be`）更新内部寄存器/内存。\n\n3.  **实现BRAM访问（如果BAR映射到BRAM）：**\n    *   如果BAR映射到大块内存（例如，256MB），您通常会实例化一个BRAM IP核（如8.2.1所述）并将其`bar_controller`逻辑与它连接。`bar_controller`将向BRAM提供地址和控制信号。\n    *   **概念性BRAM集成（简化）：**\n        ```verilog\n        // 在pcileech_tlps128_bar_controller.sv或子模块中\n        // BRAM接口\n        wire [BAR0_SIZE_BITS-1:0] bram_addr;\n        wire [31:0] bram_wr_data;\n        wire [3:0] bram_wr_en; // BRAM的字节使能\n        wire bram_wr_ce;\n        wire bram_rd_ce;\n        wire [31:0] bram_rd_data;\n\n        // 将TLP信号映射到BRAM接口\n        assign bram_addr = bar0_offset;\n        assign bram_wr_data = req_data;\n        assign bram_wr_en = req_be;\n        assign bram_wr_ce = bar_hit[0] && req_write;\n        assign bram_rd_ce = bar_hit[0] && req_read;\n\n        // 实例化BRAM IP核\n        bram_bar_zero bram_inst ( // 假设'bram_bar_zero'是您的BRAM IP模块\n            .clka(clk),\n            .ena(1'b1),\n            .wea(bram_wr_en),\n            .addra(bram_addr),\n            .dina(bram_wr_data),\n            .douta(bram_rd_data)\n        );\n\n        // 对于从BAR0的读取，输出BRAM的数据\n        if (bar_hit[0] && req_read) begin\n            rsp_data = bram_rd_data;\n        end\n        ```\n\n4.  **保存更改：**\n    *   实现每个BAR的逻辑后，保存`pcileech_tlps128_bar_controller.sv`文件。\n    *   **验证功能：** 此逻辑很复杂。彻底的仿真（使用测试平台）和后续的硬件测试对于确保正确行为至关重要。\n\n#### **8.2.3 处理多个BAR**\n\n正确管理多个BAR对于暴露多个独立内存或I/O区域的设备至关重要。`bar_controller`模块通常处理所有BAR。\n\n**步骤：**\n\n1.  **实现每个BAR的逻辑：**\n    *   在`pcileech_tlps128_bar_controller.sv`内部，扩展逻辑以处理您的捐赠设备使用的所有已启用BAR（BAR0、BAR1、BAR2等）。\n    *   **独立逻辑块：** 为清晰和可维护性，创建独立的`if/else if`块或`case`语句，根据哪个`bar_hit`信号被断言而激活。\n        ```verilog\n        // BAR0处理\n        if (bar_hit[0]) begin\n            // BAR0特定读/写逻辑，用于其寄存器/内存\n        end else if (bar_hit[1]) begin\n            // BAR1特定读/写逻辑，用于其寄存器/内存\n        end else if (bar_hit[2]) begin\n            // BAR2特定逻辑\n        end\n        // ... 继续其他BAR\n        ```\n    *   **定义寄存器和内存：** 根据需要为每个BAR分配独立的寄存器集或连接不同的BRAM实例。\n\n2.  **确保非重叠地址空间：**\n    *   虽然PCIe IP核处理与主机操作系统的每个BAR的不同地址空间的协商，但您的内部固件逻辑*必须*假定这些空间是独立的且不重叠的。\n    *   **验证地址范围**：仔细检查PCIe IP核中的BAR大小配置，以确保它们是独立的，并且根据PCIe规范正确地对齐到2的幂次方边界。\n    *   **更新地址解码**：您的`bar_controller`逻辑依赖于PCIe IP核生成的`bar_hit`信号。确保这些信号被正确解释并导致每个BAR的独特处理逻辑。\n\n3.  **测试BAR访问：**\n    *   **仿真测试：** 在硬件部署之前，使用仿真工具（例如Vivado仿真器）和全面的测试平台来验证对每个BAR的所有读写操作。\n        *   向每个BAR内的特定偏移量发送内存写入TLP。\n        *   向每个BAR内的特定偏移量发送内存读取TLP并验证返回的数据。\n    *   **硬件测试：** 编程FPGA后，使用主机端软件工具（如PCILeech客户端软件或定制C/Python脚本）访问和验证每个BAR。\n        *   **Linux**：使用`lspci -vvv`检查BAR映射（`Memory at XXXX (64-bit, prefetchable) [size=YYYY]`）。然后可以使用`devmem2`或自定义内核模块来读/写这些映射地址。\n        *   **Windows**：使用“RW-Everything”等工具或自定义用户模式应用程序来检查和与映射的内存区域交互。\n        *   执行各种读/写模式以确保所有BAR之间的数据完整性和正确寻址。\n\n---\n\n### **8.3 仿真设备电源管理和中断**\n\n实现电源管理功能和中断对于需要与主机操作系统的电源管理和中断处理机制密切高效交互的设备至关重要。没有这些，仿真设备可能无法完全正常工作，或者性能可能不理想。\n\n#### **8.3.1 电源管理配置**\n\n实现电源管理允许仿真设备支持各种电源状态（例如D0、D3hot），有助于系统范围的电源效率并符合操作系统的预期。主机操作系统将查询设备的功能并发送命令以在这些状态之间转换。\n\n**步骤：**\n\n1.  **在PCIe IP核中启用电源管理：**\n    *   **访问功能：** 在PCIe IP核定制窗口（`pcie_7x_0.xci`）中，导航到 **PCIe Capabilities**（PCIe功能）选项卡。\n    *   **启用电源管理：** 查找与 **Power Management Capability**（电源管理功能）相关的部分或选项。确保已选中或启用此选项，以便在设备的配置空间中包含电源管理（PM）功能结构。\n\n2.  **设置支持的电源状态：**\n    *   **配置支持的状态：** 在IP核的电源管理功能部分，指定设备支持的电源状态。这些通常是复选框或下拉菜单。将这些设置与您通过Arbor观察到的捐赠设备的能力相匹配。\n        *   **D0（完全开启/运行）**：始终支持。\n        *   **D1、D2（中间状态）**：可选，用于低功耗空闲状态。\n        *   **D3hot（断电，辅助电源存在）**：设备逻辑关闭，但可以响应PM事件。\n        *   **D3cold（完全断电）**：设备没有电源。\n    *   **示例**：如果捐赠设备仅支持D0和D3hot，则只启用它们。\n\n3.  **在固件中实现电源状态逻辑：**\n    *   **打开 `pcileech_pcie_cfg_a7.sv`（或相关控制模块）：** 您通常需要修改固件以反映并可能响应主机命令的电源状态转换。PCIe核本身处理大部分协议，但您的用户逻辑需要知道当前状态。\n    *   **处理电源管理控制和状态寄存器（PMCSR）写入：** 主机操作系统通过写入PMCSR中的特定位来改变设备的电源状态，PMCSR是PM能力结构的一部分。您的固件理想情况下应有逻辑来读取这些位并调整设备行为（例如，暂停/恢复操作，启用/禁用时钟）。\n        ```verilog\n        // 示例：pcileech_pcie_cfg_a7.sv或专用PM模块的一部分\n        // 假设'cfg_write'在配置写入时被断言，'cfg_address'是偏移量，'cfg_writedata'是数据。\n        // D状态位位于PM能力结构中偏移量0x04处，位[1:0]。\n\n        // PMCSR寄存器（内部表示）\n        reg [15:0] pmcsr_reg = 16'h0000; // 初始化为D0\n\n        // 用户逻辑信号，指示当前电源状态\n        reg [1:0] current_d_state = 2'b00; // 00 = D0, 01 = D1, 10 = D2, 11 = D3hot\n\n        always @(posedge clk) begin\n            if (reset) begin\n                pmcsr_reg <= 16'h0000;\n                current_d_state <= 2'b00; // 重置为D0\n            end else begin\n                // 示例：捕获对PMCSR的写入（如果直接在用户逻辑中处理）\n                // 注意：PCIe IP核管理大部分内容，但您的用户逻辑可能需要从中读取值。\n                // 假设PCIe核提供一个反映当前D状态的输出：\n                // assign current_d_state = pcie_core_d_state_output;\n\n                // 如果用户逻辑*需要*写入PMCSR（较少见，通常是只读状态）\n                // 或者它需要处理命令\n                // if (cfg_write && (cfg_address == PM_CAP_OFFSET + 2'h04)) begin // PMCSR在PM Cap基础地址+0x04\n                //     pmcsr_reg[1:0] <= cfg_writedata[1:0]; // 捕获新D状态\n                //     // current_d_state <= cfg_writedata[1:0]; // 更新内部状态\n                // end\n\n                // 在PCILeech中，PCIe核管理PMCSR。您可能会从核读取信号。\n                // 为了演示，假设'pcie_d_state'是来自IP核的输入。\n                current_d_state <= pcie_d_state; // 根据PCIe核的状态更新\n            end\n        end\n\n        // 示例：响应D状态变化的逻辑\n        always @(*) begin\n            if (current_d_state == 2'b11) begin // D3hot状态\n                // 禁用非必要模块的电源，暂停操作，\n                // 断言信号给主DMA逻辑以停止活动。\n                // 例如：dma_engine_enable = 1'b0;\n            end else if (current_d_state == 2'b00) begin // D0状态\n                // 启用全部功能\n                // 例如：dma_engine_enable = 1'b1;\n            end\n        end\n        ```\n    *   **管理电源状态效果：** 实现逻辑以根据`current_d_state`更改设备的内部行为（例如，启用/禁用时钟，将子模块置于低功耗模式）。这对于精确的功耗仿真以及确保设备正确响应操作系统命令至关重要。\n\n4.  **保存更改：**\n    *   保存任何修改过的固件文件。\n    *   通过仿真或硬件测试（例如，Windows“睡眠”或“休眠”功能，或Linux `poweroff`命令）彻底测试电源管理功能，以查看设备是否正确转换。\n\n#### **8.3.2 MSI/MSI-X配置**\n\n实现消息信号中断（MSI）或其扩展版本（MSI-X）允许仿真设备使用基于消息的中断。这些中断比传统的引脚中断（INTx）效率更高、可扩展性更强，是现代PCIe设备的优选方法。MSI/MSI-X允许设备通过向特定内存地址写入特殊TLP来通知CPU。\n\n**步骤：**\n\n1.  **在PCIe IP核中启用MSI/MSI-X：**\n    *   **访问中断配置：** 在PCIe IP核定制窗口（`pcie_7x_0.xci`）中，导航到 **Interrupts**（中断）选项卡或专门标记为 **MSI/MSI-X Capabilities**（MSI/MSI-X功能）的部分。\n    *   **选择中断类型：** 根据捐赠设备的功能，选择 **MSI** 或 **MSI-X**。MSI-X通常因其灵活性（更多向量，每个向量可屏蔽）而受到青睐。\n    *   **配置支持的向量数量：** 设置设备将支持的中断向量（消息）数量。这应与捐赠设备匹配。\n        *   **MSI** 支持最多32个向量（通常是1、2、4、8、16或32）。\n        *   **MSI-X** 支持最多2048个向量，允许更细粒度的中断源。\n    *   **启用功能：** 确保MSI或MSI-X功能结构已明确启用，以便包含在设备的配置空间中。这是主机操作系统发现设备中断能力的方式。\n\n2.  **在固件中实现中断逻辑：**\n    *   **打开 `pcileech_pcie_tlp_a7.sv`（或用户逻辑模块）：** 此文件通常负责用户定义的TLP生成，并且可能是启动MSI/MSI-X消息的合适位置。但是，中断的*触发*将来自您的自定义逻辑。\n    *   **定义中断信号：** 声明内部信号，指示何时需要生成中断。\n        ```verilog\n        // 在自定义模块中（例如，'my_device_logic.sv'），该模块与TLP生成逻辑接口\n        reg msi_trigger_signal; // 当发生中断条件时断言此信号\n        ```\n    *   **实现中断生成逻辑：** 定义应该触发中断的条件。这通常涉及在仿真设备的逻辑中检测事件。\n        ```verilog\n        // 在'my_device_logic.sv'内部\n        input wire clk;\n        input wire reset;\n        input wire event_data_ready; // 示例：当数据就绪时来自您的逻辑的输入\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_trigger_signal <= 1'b0;\n            end else if (event_data_ready) begin // 当特定事件发生时\n                msi_trigger_signal <= 1'b1; // 触发MSI\n            end else begin\n                msi_trigger_signal <= 1'b0; // 一个周期后或被确认后清除\n            end\n        end\n        ```\n    *   **连接到PCIe核的MSI接口：** `msi_trigger_signal`（或您的自定义逻辑的类似输出）需要连接到PCIe IP核的适当输入（例如，如果使用AXI-Stream接口进行MSI TLP，则连接到`s_axis_tdata_tready`、`s_axis_tdata_tvalid`、`s_axis_tdata_tlast`；或者连接到IP核提供的专用MSI请求端口）。然后PCIe核会形成并发送实际的MSI/MSI-X TLP。有关精确的接口详细信息，请查阅Xilinx PCIe IP核文档。\n\n3.  **保存更改：**\n    *   实现中断逻辑后，保存所有修改过的固件文件。\n    *   **检查时序约束：** 新逻辑，特别是中断路径，可能对时序很敏感。确保综合和实现工具不会报告与您的中断生成逻辑相关的任何时序违规。\n\n#### **8.3.3 实现中断处理逻辑（设备端）**\n\n除了启用功能之外，定义仿真设备何时以及如何生成中断对于其与主机中断处理机制和驱动程序行为的正确交互至关重要。这涉及创建断言中断请求的内部逻辑。\n\n**步骤：**\n\n1.  **定义中断条件：**\n    *   **识别触发事件：** 根据您的捐赠设备的行为，确定哪些特定的内部事件应导致您的仿真设备生成中断。\n        *   **示例**：数据传输完成、接收缓冲区中有新数据、内部错误条件、特定命令完成、链路状态更改。\n    *   **实现条件逻辑：** 在您的自定义SystemVerilog模块中使用组合逻辑或时序逻辑，精确检测这些事件并生成一个短脉冲或电平信号，指示中断请求。\n\n2.  **创建中断生成模块（模块化设计）：**\n    *   将中断生成逻辑封装到一个单独的专用模块中是一个好习惯，这样可以提高清晰度、可重用性并方便调试。此模块将内部事件作为输入，并产生一个连接到PCIe核的`msi_req`（或类似）输出。\n        ```verilog\n        // 文件：interrupt_generator.sv\n        module interrupt_generator (\n            input wire clk,\n            input wire reset,\n            input wire event_trigger,        // 来自您的自定义逻辑的输入信号（例如，data_ready, error_flag）\n            output reg msi_req_o            // 输出：断言此信号以请求MSI/MSI-X\n        );\n\n        // MSI的简单脉冲发生器（一次性中断）\n        reg event_trigger_d1;\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_req_o <= 1'b0;\n                event_trigger_d1 <= 1'b0;\n            end else begin\n                event_trigger_d1 <= event_trigger;\n                // 当event_trigger从低到高跳变时，生成一个单周期脉冲\n                if (event_trigger && !event_trigger_d1) begin\n                    msi_req_o <= 1'b1; // 断言MSI请求\n                end else begin\n                    msi_req_o <= 1'b0; // 一个周期后取消断言\n                end\n            end\n        end\n\n        endmodule // interrupt_generator\n        ```\n    *   **与主固件集成：** 在您的顶层用户逻辑中（例如，在`pcileech_squirrel_top.sv`或其实例化的模块中）实例化此`interrupt_generator`模块，并将其`msi_req_o`输出连接到PCIe IP核的MSI输入。\n\n3.  **确保正确的时序和序列：**\n    *   **遵守PCIe规范：** MSI/MSI-X消息是TLP。确保这些消息的生成符合PCIe TLP格式、流控制和时序要求。PCIe IP核处理大部分内容，但您提供给它的输入信号必须稳定且时序正确。\n    *   **管理中断延迟：** 优化您的逻辑，以最大限度地减少内部事件发生与`msi_req_o`信号断言之间的任何不必要延迟。\n\n4.  **测试中断传递：**\n    *   **仿真：** 使用全面的测试平台模拟应生成中断的场景。验证您的`msi_req_o`信号是否按预期工作，以及PCIe核是否生成正确的MSI/MSI-X TLP。\n    *   **硬件测试：**\n        *   用更新的固件编程FPGA。\n        *   使用主机端软件触发应引起中断的事件（例如，启动完成的DMA传输）。\n        *   确认主机操作系统接收到中断。在Linux上，`dmesg`可以显示中断消息。在Windows上，您可以使用特定的驱动程序调试工具或事件查看器。\n        *   **调试工具：** 利用Vivado的集成逻辑分析仪（ILA）核（如第12节所述）实时监控`event_trigger`、`msi_req_o`和PCIe核的TLP输出信号，以验证正确的中断生成。\n\n5.  **保存更改：**\n    *   完成所有代码修改并保存相关固件文件。\n    *   根据测试结果审查并改进您的中断逻辑，以确保可靠性。\n\n---\n\n## **9. 仿真设备特定功能**\n\n除了标准的PCIe配置空间和通用DMA功能之外，许多捐赠设备还具有独特的功能、自定义寄存器或厂商特定功能，这些对于其完整功能或与其专有驱动程序交互至关重要。精确的仿真需要理解和复制这些细微之处。本节将深入探讨如何实现这些高级功能，从而实现更忠实和功能更全面的仿真。\n\n### **9.1 实现高级PCIe功能**\n\nPCIe规范包含除了基本配置空间之外的各种*扩展功能*。这些功能提供了高级错误报告、电源管理、虚拟化等特性。实现这些功能有助于您的仿真设备显得更合法，并与现代主机系统正确交互。\n\n**步骤：**\n\n1.  **识别所需的扩展功能：**\n    *   在使用Arbor等工具收集捐赠设备信息时，请仔细查找并记录捐赠设备配置空间中存在的任何扩展功能。这些通常在标准配置空间的初始256字节之外找到。\n    *   **常见示例：**\n        *   **高级错误报告（AER）**：为PCIe链路提供强大的错误检测、日志记录和报告机制。\n        *   **设备序列号（DSN）**：（已在第6.2节中介绍）。\n        *   **电源管理（PM）**：（已在第8.3.1节中介绍）。\n        *   **PCI Express（PCIe）功能结构**：（已在第8.1节中介绍链路速度/宽度、最大载荷/读取请求，但也包括其他字段，如设备控制/状态、链路控制/状态）。\n        *   **虚拟通道（VC）/多功能虚拟通道（MFVC）**：用于服务质量（QoS）和流量管理。\n        *   **精确时间测量（PTM）**：用于设备之间的时间同步。\n        *   **延迟容忍报告（LTR）**：基于延迟要求进行电源管理。\n        *   **可重置FPC（功能级重置）**：用于更细粒度的重置。\n\n2.  **在Vivado PCIe IP核中启用功能：**\n    *   访问Vivado中的PCIe IP核定制窗口（`pcie_7x_0.xci`）。\n    *   导航到各个选项卡（例如，“PCIe Capabilities”、“Extended Capabilities”、“Advanced Options”）。\n    *   查找复选框或下拉菜单，以启用和配置从捐赠设备中识别出的特定扩展功能。\n    *   **示例（AER）：** 您会找到一个“高级错误报告”部分，您可以在其中启用它并配置其寄存器（例如，严重性掩码）。\n    *   **注意：** Xilinx PCIe IP核为许多标准和扩展功能提供了高度可配置性。通常只需在GUI中启用正确的选项即可。\n\n3.  **实现功能寄存器的固件逻辑（如果需要）：**\n    *   虽然PCIe IP核处理这些功能的*存在*和大部分*协议*，但某些功能会暴露您的自定义固件可能需要读写或其值需要固件响应的寄存器。\n    *   **示例（AER）：** 如果您的仿真设备检测到应通过AER报告的内部错误，您的固件需要写入特定的AER错误状态寄存器（这些寄存器可能作为BAR的一部分暴露，或由PCIe核内部处理，然后反映到用户逻辑）。然后您的用户逻辑将向PCIe核断言错误输入。\n    *   **示例（电源管理）：** 如8.3.1节所述，您的固件需要响应PCIe核发出的D状态变化。\n    *   **流程：**\n        *   识别您的捐赠设备驱动程序交互的每个已启用功能结构中的特定寄存器。\n        *   在PCILeech-FPGA框架中找到与这些寄存器接口的相应信号或逻辑（通常在`pcileech_pcie_cfg_a7.sv`或`bar_controller`中）。\n        *   实现这些寄存器的读写逻辑，确保您的仿真设备的内部状态准确反映驱动程序期望的值。\n\n### **9.2 仿真厂商特定功能**\n\n这是真正的“全设备仿真”变得高度专业化的部分。许多实际设备具有独特的寄存器、未文档化的命令、自定义数据格式或专有控制流程，这些都使其与众不同。复制这些需要更深入的分析和定制HDL开发。\n\n**步骤：**\n\n1.  **逆向工程厂商特定行为：**\n    *   这通常是最具挑战性的部分。\n    *   **静态分析（驱动程序/固件）：** 反汇编捐赠设备的官方驱动程序（Windows `.sys`，Linux `.ko`）或设备的原始固件（如果可用）。查找独特的I/O或MMIO访问模式、魔术值或寄存器写入序列。Ghidra、IDA Pro或objdump等工具会非常有价值。\n    *   **动态分析（驱动程序执行）：** 运行捐赠设备及其驱动程序，并使用**PCIe协议分析仪**（例如，Teledyne LeCroy，Keysight，如第12.2节所述）监控PCIe流量。这是理解实际TLP交换，包括厂商定义消息和寄存器访问序列的黄金标准。请注意：\n        *   BARs中访问的特定内存地址。\n        *   对这些地址的读/写模式。\n        *   写入或读取特定寄存器的值。\n        *   命令和响应之间的时序关系。\n    *   **系统调用/API监控**：在主机上，使用Procmon（Windows）或`strace`（Linux）等工具查看驱动程序如何与操作系统交互以及它使用了哪些特定的设备I/O控制（IOCTL）代码，这些代码可能对应于特定的硬件操作。\n    *   **硬件嗅探**：如果可能，使用硬件嗅探器（如Saleae逻辑分析仪）捕获设备内部总线（例如SPI，I2C）上的信号，如果它有外部闪存或组件。\n\n2.  **在BARs中实现自定义寄存器和逻辑：**\n    *   一旦您识别出厂商特定的寄存器或命令协议，您将需要将这些定义到您的FPGA固件中，通常作为可通过您的某个BAR访问的内存映射寄存器。\n    *   **创建内部寄存器：** 在您的SystemVerilog代码中声明`reg`变量来表示这些自定义寄存器。\n        ```verilog\n        // 在pcileech_tlps128_bar_controller.sv或子模块中\n        reg [31:0] custom_control_reg;\n        reg [31:0] custom_status_reg;\n        reg [31:0] custom_data_reg;\n\n        // 示例：将它们映射到BAR0中的特定偏移量（假设BAR0足够大）\n        // 调整'bar0_offset' case语句（来自第8.2.2节）\n        // ...\n        if (bar_hit[0]) begin\n            if (req_write) begin\n                case (bar0_offset)\n                    32'h0000_1000: custom_control_reg <= req_data; // 自定义控制寄存器\n                    32'h0000_1004: custom_data_reg <= req_data;    // 自定义数据写入寄存器\n                    // ... 其他映射\n                endcase\n            end else if (req_read) begin\n                case (bar0_offset)\n                    32'h0000_1000: rsp_data = custom_control_reg; // 读取控制寄存器\n                    32'h0000_1008: rsp_data = custom_status_reg;  // 自定义状态寄存器\n                    // ... 其他映射\n                endcase\n            end\n        end\n        // ...\n        ```\n    *   **实现行为逻辑：** 创建SystemVerilog逻辑（状态机、组合逻辑），用于：\n        *   响应对`custom_control_reg`的写入。例如，此寄存器中的某个特定位可能触发DMA传输、清除状态标志或启动内部操作。\n        *   根据仿真设备的内部状态更新`custom_status_reg`（例如，“操作完成”、“发生错误”、“数据可用”）。\n        *   处理写入`custom_data_reg`的数据，或在读取时从中提供数据，模仿捐赠设备的数据路径。\n\n3.  **仿真厂商特定消息（如果适用）：**\n    *   一些复杂设备可能通过PCIe使用“厂商定义消息”（VDM）进行特定控制或通信。如果您的分析揭示了此类消息，您将需要：\n        *   在PCIe IP核中启用VDM支持（如果可用）。\n        *   实现TLP生成逻辑（如第10节所述）来制作和发送这些VDM。\n        *   实现TLP接收和解析逻辑来解释来自主机的传入VDM。\n\n4.  **验证仿真行为：**\n    *   **迭代测试：** 这是一个高度迭代的过程。进行小修改，编译，烧录，然后测试。\n    *   **驱动程序加载：** 捐赠设备的驱动程序是否正确加载而没有错误？\n    *   **功能测试：** 驱动程序能否启动基本操作？它是否从您的仿真寄存器获得预期的响应？\n    *   **应用程序测试：** 依赖捐赠设备的应用程序能否在您的仿真版本下正常运行？\n    *   **调试：** 广泛使用ILA和PCIe协议分析仪来比较您的仿真设备的行为与真实捐赠设备捕获的行为。寻找TLP时序、寄存器值和总体协议流中的差异。\n\n---\n\n## **10. 事务层数据包（TLP）仿真**\n\n事务层数据包（TLP）是PCIe架构中通信的基本单位。主机系统与PCIe设备之间的每一次交互，从配置读取到数据传输，都被封装在一个或多个TLP中。精确的TLP仿真不仅重要；它对于您的仿真设备与主机系统正确交互，确保驱动程序正常运行和数据按预期移动，是*至关重要*的。\n\n### **10.1 理解和捕获TLP**\n\n在您能够制作自定义TLP之前，您必须深入理解它们的结构和常见类型。从您的捐赠设备捕获真实世界的TLP可提供最精确的蓝图。\n\n*   **TLP结构的学习**：\n    TLP通常由报头、可选数据载荷和可选的端到端CRC（ECRC）组成。报头至关重要，它定义了TLP的类型、事务细节和路由信息。\n\n    *   **TLP的组成部分**：\n        *   **报头（Header）**：最重要的部分，通常是3或4个双字（Dword = 4字节）。它包含定义TLP目的和处理方式的关键字段：\n            *   **Fmt（格式）和 Type（类型）**：定义TLP的格式（3DW/4DW，带/不带数据）及其特定目的（例如，内存读取请求、内存写入、完成、配置读取/写入）。\n            *   **Length（长度）**：指定数据载荷的长度（以双字为单位）。\n            *   **Requester ID（总线、设备、功能）**：标识发起请求的PCIe功能。对于将完成数据路由回正确的源头至关重要。\n            *   **Tag（标签）**：由请求者分配给事务的唯一标识符，允许完成者将完成TLP与其原始请求TLP匹配。\n            *   **Address（地址）**：对于内存/IO事务，这是目标内存或I/O地址。\n            *   **First DW Byte Enable (FBE)** 和 **Last DW Byte Enable (LBE)**：指定数据载荷的第一个和最后一个双字中哪些字节对于写入操作有效，或哪些字节正在请求读取完成。\n            *   **Traffic Class (TC)** 和 **Transaction ID (TID)**：用于QoS和排序规则。\n        *   **数据载荷（可选）**：存在于内存写入、配置写入和读取完成等TLP中。它包含实际传输的数据。\n        *   **端到端CRC (ECRC)（可选）**：一个32位CRC，覆盖整个TLP，确保从源到目的地的数据完整性，通常由软件生成/检查。\n\n*   **理解常见的TLP类型**：您的固件将主要处理这些类型：\n    *   **Memory Read Request (MRd)**：由请求者（例如，主机CPU，或您的FPGA作为DMA主设备）发送的TLP，用于从特定内存地址读取数据。\n    *   **Memory Read Completion (CplD)**：由完成者（例如，您的FPGA响应主机MRd）发送的TLP，携带请求的数据。\n    *   **Memory Write (MWr)**：由请求者（例如，主机CPU，或您的FPGA）发送的TLP，用于向特定内存地址写入数据。\n    *   **Completion Without Data (Cpl)**：由完成者发送的TLP，用于确认不返回数据的请求（例如，成功的MWr）。\n    *   **Configuration Read Request (CfgRd)**：来自主机的TLP，用于读取设备配置空间中的寄存器。\n    *   **Configuration Read Completion (CplD)**：来自设备返回CfgRd数据数据的TLP。\n    *   **Configuration Write Request (CfgWr)**：来自主机的TLP，用于写入设备配置空间中的寄存器。\n    *   **Vendor-Defined Messages (VDM)**：特定厂商用于专有通信的自定义TLP。\n\n#### **10.1.2 从捐赠设备捕获TLP**\n\n从您的捐赠设备捕获真实的PCIe流量是无价的。它提供了TLP结构、序列和时序的具体示例，使您能够精确地复制它们。\n\n*   **步骤**：\n    1.  **设置PCIe协议分析仪**：\n        *   最有效的方法是使用专用的硬件工具，通常称为“PCIe协议分析仪”。这些设备位于主机和捐赠PCIe卡之间，被动捕获所有流量。\n        *   **示例**：\n            *   **Teledyne LeCroy PCIe 分析仪**：行业标准，功能强大，但投资巨大。\n            *   **Keysight PCIe 分析仪**：另一个领先的供应商。\n            *   （对于基本调试，一些带PCIe解码器的高端逻辑分析仪可能提供有限的TLP查看功能，但真正的协议分析仪更优越）。\n    2.  **捕获事务**：\n        *   在连接了协议分析仪的测试系统中安装捐赠设备。\n        *   运行捐赠设备的驱动程序和任何相关应用程序。\n        *   在正常操作期间，尤其是关键阶段，监控和记录PCIe事务，例如：\n            *   设备枚举（操作系统首次检测到它时）。\n            *   驱动程序加载和初始化。\n            *   典型数据传输操作（例如，存储设备的大文件复制，网卡的网络流量）。\n            *   设备特定命令或诊断。\n    3.  **分析捕获的TLP**：\n        *   使用协议分析仪的先进软件解剖捕获的TLP。软件将解码字段，提供时间顺序视图，并允许过滤和搜索。\n        *   密切关注：\n            *   精确的`Fmt`和`Type`字段。\n            *   `Requester ID`和`Tag`值（特别是对于完成）。\n            *   内存事务的`Address`和`Length`。\n            *   写入和读取完成的`Data Payload`内容。\n            *   任何厂商特定字段或自定义TLP。\n\n#### **10.1.3 记录关键TLP事务**\n\n对捕获的TLP进行结构化文档创建了一个用于您的仿真的蓝图。\n\n*   **步骤**：\n    1.  **识别关键事务**：\n        *   重点关注对设备核心功能至关重要的TLP。这包括：\n            *   **初始化序列**：操作系统在枚举期间执行的一系列配置读/写。\n            *   **驱动程序初始化**：驱动程序启动时交换的命令和数据。\n            *   **主要数据传输**：`MWr`和`MRd` TLP如何为设备的主要功能构建和完成。\n            *   **错误处理**：设备如何报告错误（例如，带有Completer Abort (CA)、Unsupported Request (UR)的Completion）。\n            *   **电源管理转换**：与D状态变化相关的TLP。\n            *   **中断生成**：MSI/MSI-X消息如何发送。\n        *   协议分析仪的截图在这里会非常有帮助。\n    2.  **创建详细文档**：\n        *   对于每个关键TLP序列，记录：\n            *   **TLP类型**（例如，MWr、MRd、CplD）。\n            *   其**报头字段**（Fmt、Type、Requester ID、Tag、Length、Address、Byte Enables）。\n            *   **数据载荷**（如果适用）。\n            *   事务中的**序列号**或顺序。\n            *   发送它的**条件**（例如，“主机在驱动程序初始化时发送”，“设备在DMA完成时发送”）。\n            *   任何**预期的响应**或后续TLP。\n        *   协议分析仪的截图在这里会非常有帮助。\n    3.  **理解时序和序列**：\n        *   除了TLP内容，TLP的*时序*和*序列*至关重要。PCIe有严格的排序规则和流控制机制。注意：\n            *   **请求和完成之间的延迟**：真实设备响应的速度。\n            *   **流控制信用**：设备如何管理其传入/传出TLP的缓冲区空间。虽然Xilinx PCIe IP核处理基本的流控制，但对于高级仿真，了解捐赠设备的典型信用使用情况会有所帮助。\n            *   **事务层数据包排序**：理解posted（写入）和non-posted（读取、完成）事务如何排序。\n\n### **10.2 制作用于特定操作的定制TLP**\n\n一旦您理解了蓝图，您就可以将这些知识转化为您的FPGA固件（SystemVerilog），以主动生成和响应TLP。PCILeech-FPGA框架提供了抽象层，但对于深度仿真，您可能需要直接与TLP生成/解析逻辑交互。\n\n#### **10.2.1 在固件中实现TLP处理**\n\n您的固件需要逻辑来发送和接收TLP。PCIe IP核处理物理层和数据链路层，向您的用户逻辑暴露一个事务层接口（通常是AXI-Stream）。\n\n*   **要修改的文件（主要）**：\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_pcie_tlp_a7.sv`（或类似文件，取决于板卡变体）\n        *   此文件通常包含将用户请求转换为出站TLP并将传入TLP解析为用户逻辑信号的核心逻辑。\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv`\n        *   此模块专门处理解析目标为设备BAR的传入内存读/写TLP，并生成相应的完成TLP。\n\n*   **步骤**：\n\n    1.  **理解PCIe IP核接口**：\n        *   在编写TLP逻辑之前，请彻底阅读Xilinx PCIe IP核用户指南（特别是关于用户应用接口或AXI4-Stream接口的部分）。这定义了您的SystemVerilog逻辑如何连接到PCIe核以发送和接收TLP。您通常会与`s_axis_rx_tdata`（接收到的TLP数据）、`s_axis_rx_tvalid`（接收到有效TLP）、`m_axis_tx_tdata`（传出TLP数据）、`m_axis_tx_tready`（核已准备好接受TLP）等进行交互。\n\n    2.  **创建TLP生成函数（用于出站TLP）**：\n        *   在`pcileech_pcie_tlp_a7.sv`（或与`m_axis_tx_*`接口的模块）中，您将编写逻辑来组装具有所需报头和载荷的TLP。这通常涉及将各种字段组合成一个`[127:0]`（对于128位接口）或`[63:0]`（对于64位接口）总线，该总线馈送PCIe核。\n        *   **示例（概念性，简化函数，用于3DW TLP报头）：**\n            ```verilog\n            // 这是一个概念性辅助函数。实际上，您将构建一个状态机\n            // 通过AXI-Stream接口发送TLP，可能使用FIFO。\n            function automatic [95:0] create_3dw_tlp_header; // 假设3个双字 = 96位\n                input logic [7:0] tlp_type_fmt;   // 格式和类型字段\n                input logic [15:0] requester_id;  // BDF\n                input logic [7:0] tag;\n                input logic [7:0] lower_address_bits; // 或更复杂的地址\n                input logic [7:0] byte_enables;   // 第一个双字字节使能\n\n                begin\n                    create_3dw_tlp_header = {\n                        tlp_type_fmt,                     // Fmt[6:4], Type[3:0]\n                        8'b0,                             // 保留\n                        4'b0,                             // TC[3:0] (流量类别)\n                        3'b0,                             // Attr[2:0]\n                        1'b0,                             // TH (TLP提示)\n                        2'b0,                             // D(igest) (ECRC存在)\n                        1'b0,                             // EP (Poisoned)\n                        1'b0,                             // TD (类型依赖)\n                        // DW0: Fmt, Type, TC, Attr, TH, D, EP, TD, Length (不在3DW中, 4DW有)\n\n                        requester_id,                     // 请求者ID (Bus[7:0], Device[4:0], Function[2:0])\n                        tag,                              // 标签\n                        lower_address_bits,               // 示例：地址的低位或数据的一部分\n                        byte_enables,                     // 第一个双字字节使能\n                        4'b0,                             // 保留\n                        4'b0                              // 最后一个双字字节使能 (通常用于MWr)\n                        // DW1, DW2... 字段\n                    };\n                end\n            endfunction\n\n            // 示例：在状态机中生成带数据的完成（CplD）\n            // 这只是一个片段，不是完整实现\n            localparam  CPLD_3DW_FMT = 8'h4A; // Fmt=100 (4DW, 带数据), Type=1010 (Cpl)\n            localparam  CPL_D_FMT_TYPE_LEN = 8'h4A; // 根据PCIe规范调整。(带数据的4DW报头)\n\n            // ... 发送TLP的状态机\n            // 在准备发送CplD的状态下\n            if (tx_ready_from_pcie_core) begin\n                // 构建报头和载荷\n                // 对于CplD，您需要Compliter ID, Status, Byte Count, Requester ID, Tag, Completion ID, Lower Address\n                // 然后是实际的读取数据载荷\n                m_axis_tx_tdata_reg = {\n                    CPL_D_FMT_TYPE_LEN,         // 字节0: Fmt/Type\n                    tlp_length_dw_minus_one,    // 字节1: TLP长度 (以双字为单位) - 1\n                    status_completion_bits,     // 字节2: Cpl Status, BCM, Rsvd\n                    byte_count_dws_upper,       // 字节3: 字节计数 (高位)\n                    requester_id,               // 字节4-5: 请求者ID (来自原始MRd)\n                    tag,                        // 字节6: 标签 (来自原始MRd)\n                    byte_count_dws_lower,       // 字节7: 字节计数 (低位)\n                    completion_id,              // 字节8-9: 完成ID (您的BDF)\n                    lower_address_from_request  // 字节10-11: 请求的低位地址\n                    // ... 接着是实际的数据载荷\n                };\n                m_axis_tx_tvalid_reg = 1'b1;\n                m_axis_tx_tlast_reg = 1'b1; // 最后一个TLP片段\n                // ... 状态转换以等待tready\n            end\n            ```\n        *   **注意**：实际实现涉及状态机、FIFO，以及遵循PCIe IP核的AXI-Stream协议。PCILeech-FPGA框架已经为此提供了良好的基础，但您可能需要为非常特定的TLP行为进行扩展或修改。\n\n    3.  **处理TLP接收（用于入站TLP）**：\n        *   实现逻辑以解析来自PCIe核接收接口的传入TLP（例如，`s_axis_rx_tdata`、`s_axis_rx_tvalid`）。\n        *   此解析包括：\n            *   检查`s_axis_rx_tvalid`以判断是否存在TLP。\n            *   从TLP报头中读取`Fmt`和`Type`字段以确定其目的。\n            *   提取`Requester ID`、`Tag`、`Address`、`Length`和`Data Payload`等相关字段。\n        *   使用`case`语句或`if/else if`块，根据TLP类型将信息路由到适当的内部逻辑（例如，用于内存写入的`bar_controller`，用于配置写入的配置模块）。\n        *   **示例（概念性，简化解析）：**\n            ```verilog\n            // 在pcileech_pcie_tlp_a7.sv或TLP解析模块中\n            input wire [127:0] s_axis_rx_tdata;\n            input wire s_axis_rx_tvalid;\n            output wire s_axis_rx_tready; // 需要断言此信号以接受更多数据\n\n            reg [7:0] received_tlp_fmt_type;\n            reg [15:0] received_requester_id;\n            // ... 声明其他已解析的字段\n\n            assign s_axis_rx_tready = 1'b1; // 为简化起见始终准备好接收，在实际设计中管理反压\n\n            always @(posedge clk) begin\n                if (s_axis_rx_tvalid) begin\n                    received_tlp_fmt_type = s_axis_rx_tdata[127:120]; // 假设最高位\n                    received_requester_id = s_axis_rx_tdata[111:96]; // 示例偏移量\n\n                    // 根据TLP类型解码\n                    case (received_tlp_fmt_type[3:0]) // 仅TLP类型位\n                        4'h0: // 内存写入 (3DW或4DW取决于Fmt)\n                            // 提取地址、长度、载荷并传递给BAR控制器\n                            begin\n                                // 传递给BAR控制器，用于写入仿真内存\n                                // bar_write_enable = 1'b1;\n                                // bar_write_address = s_axis_rx_tdata[...];\n                                // bar_write_data = s_axis_rx_tdata[...];\n                            end\n                        4'h1: // 内存读取\n                            // 提取地址、长度，并传递给BAR控制器进行读取\n                            begin\n                                // bar_read_enable = 1'b1;\n                                // bar_read_address = s_axis_rx_tdata[...];\n                                // (完成将由BAR控制器生成)\n                            end\n                        // ... 其他TLP类型\n                        default: begin\n                            // 处理不支持或保留的TLP类型（例如，日志记录、错误）\n                        end\n                    endcase\n                end\n            end\n            ```\n\n    4.  **确保符合性**：\n        *   严格验证您生成和解析的TLP是否符合PCIe规范的格式、字段定义和时序。偏差将导致通信失败。\n\n    5.  **实现完成处理**：\n        *   对于从主机接收到的内存读取请求（MRd）和配置读取请求（CfgRd），您的设备必须在指定的时间内返回适当的完成TLP（CplD表示数据，Cpl表示无数据）。`bar_controller`模块（第8.2.2节）是此BAR读取逻辑所在的位置。\n\n    6.  **保存更改**：\n        *   保存文件（`pcileech_pcie_tlp_a7.sv`、`pcileech_tlps128_bar_controller.sv`或任何自定义模块）后，实现更改。\n\n#### **10.2.2 处理不同TLP类型**\n\n每种TLP类型都有特定的报头格式和行为。您的固件必须擅长处理与您的捐赠设备相关的那些类型。\n\n*   **内存读取请求（MRd）**：\n    *   **实现**：\n        *   当接收到MRd TLP（由`pcileech_pcie_tlp_a7.sv`解析并路由到`bar_controller`）时，`bar_controller`需要：\n            *   解析请求的地址和长度。\n            *   从适当的内部内存位置（例如，连接到BAR的BRAM）或内部寄存器中获取数据。\n            *   组装一个**带数据的完成（CplD）** TLP。关键是，此TLP必须包含来自MRd请求的原始`Requester ID`、`Tag`和`Completion ID`（您的设备BDF），以及获取的数据载荷。\n            *   通过PCIe IP核的传输接口将CplD TLP发送回主机。\n\n*   **内存写入请求（MWr）**：\n    *   **实现**：\n        *   当接收到MWr TLP时，`bar_controller`需要：\n            *   解析目标地址、长度和`Byte Enables`（FBE/LBE）。\n            *   提取`数据载荷`。\n            *   将数据写入仿真设备内的指定内存位置（例如，BRAM或内部寄存器），并遵循字节使能。\n        *   内存写入是“posted事务”，这意味着它们不需要完成TLP进行确认，除非发生错误。\n\n*   **配置读/写请求（CfgRd/CfgWr）**：\n    *   **实现**：\n        *   这些TLP针对设备的配置空间（厂商ID、设备ID、BAR、功能等）。Xilinx PCIe IP核根据其配置自动处理大部分标准配置空间访问。\n        *   但是，如果您的配置空间中存在非标准的自定义寄存器或扩展功能，您可能需要特定的逻辑来：\n            *   对于CfgRd：从您的内部`cfg_`寄存器返回请求的数据。\n            *   对于CfgWr：更新您的内部`cfg_`寄存器或根据写入的数据触发操作。\n        *   配置读取需要**带数据的完成（CplD）**，而配置写入需要**不带数据的完成（Cpl）**。\n\n*   **厂商定义消息（VDM）**：\n    *   **实现**：\n        *   如果您的捐赠设备使用VDM，这将需要专门的解析和响应逻辑。\n        *   **解析传入VDM**：根据其`Fmt`和`Type`字段识别VDM。提取厂商特定数据并根据您的逆向工程发现进行解释。\n        *   **制作出站VDM**：当您的仿真设备需要发送VDM时，创建逻辑来组装具有精确厂商特定报头和载荷格式的VDM。\n\n#### **10.2.3 验证TLP时序和序列**\n\n即使TLP格式完美，不正确的时序或序列也会导致设备故障或被检测为不兼容。\n\n*   **步骤**：\n\n    1.  **使用仿真工具**：\n        *   **测试平台**：为您的TLP生成和解析模块开发全面的SystemVerilog测试平台。\n        *   模拟各种场景（例如，主机发送MRd，您的设备发送CplD；主机发送MWr；主机枚举设备），以验证TLP是否正确形成、传输、接收和处理。\n        *   验证TLP的序列，并确保在合理的时间内发送完成。\n\n    2.  **使用ILA监控（集成逻辑分析仪）**：\n        *   如第12.1节所述，在您的Vivado设计中插入一个ILA核。\n        *   将ILA探头连接到PCIe IP核的AXI-Stream接口（例如，`s_axis_rx_tdata`、`s_axis_rx_tvalid`、`m_axis_tx_tdata`、`m_axis_tx_tready`）。\n        *   设置触发器以捕获特定TLP（例如，在`m_axis_tx_tvalid`上针对某种TLP类型触发）。\n        *   这使您可以在硬件操作期间实时查看FPGA上的实际TLP位，验证您的固件是否向/从PCIe IP核发送/接收正确的数据和控制信号。\n\n    3.  **检查时序约束**：\n        *   PCIe IP核对其AXI-Stream接口有严格的时序要求。确保您的用户逻辑向`m_axis_tx_tdata`提供数据和处理`s_axis_rx_tdata`满足这些时序约束。\n        *   Vivado的时序分析报告（综合和实现后）将标记任何违规。通过优化您的逻辑或在可能的情况下调整时钟来解决这些问题。\n\n    4.  **符合性测试（高级）**：\n        *   对于高保真仿真，请考虑使用专用的PCIe符合性测试套件（通常与高端协议分析仪集成）。这些测试系统地检查是否符合PCIe规范，揭示细微的协议违规。\n\n    5.  **保存更改**：\n        *   在彻底测试和验证后保存所有修改过的文件。迭代是TLP级调试的关键。\n\n---\n\n## **第三部分：高级技术与优化**\n\n---\n\n## **11. 构建、烧录与测试**\n\n完成所有定制后，就到了验证的时刻：构建固件，将其编程到您的FPGA上，并严格测试其功能，以确保它与捐赠设备的行为完全一致。此阶段将您的设计从代码转换为可工作的硬件仿真。\n\n### **11.1 综合与实现**\n\n这是FPGA设计流程中的核心步骤，您的SystemVerilog高级代码将被转换为可以加载到FPGA上的低级硬件配置。\n\n#### **11.1.1 运行综合**\n\n综合是Vivado将您的HDL代码转换为门级网表（逻辑门及其互连的描述）的过程。它还执行初步的时序分析和资源估算。\n\n*   **步骤**：\n    1.  **开始综合**：\n        *   在Vivado GUI中，在 **Flow Navigator**（流程导航器）窗格（通常在左侧）中，在“Synthesis”（综合）下，点击 **Run Synthesis**（运行综合）。\n    2.  **监控进度**：\n        *   Vivado将打开一个“Launch Runs”（启动运行）对话框。您通常只需点击“OK”。\n        *   监控Vivado窗口底部的 **Messages**（消息）选项卡。它将显示综合运行的进度。\n        *   **常见警告/错误关注点**：\n            *   **`[Synth 8-327]` Unconnected Ports / Unused Inputs（未连接端口/未使用的输入）**：这表明您设计中的信号或端口未连接到任何东西。虽然有时是故意的（例如，FPGA上未使用的引脚），但它们也可能指向端口名称中的拼写错误或遗忘的连接。检查每个警告以确保这不是功能问题。\n            *   **`[Synth 8-256]` Registers/Wires Not Optimized（寄存器/线未优化）**：这可能表明逻辑推断不正确，或者您有冗余逻辑可以优化。\n            *   **Syntax Errors（语法错误）**：如果您的SystemVerilog代码中有致命的语法错误，综合将立即失败。请在Visual Studio Code中修复这些错误。\n    3.  **审查综合报告**：\n        *   成功完成后，Vivado将询问您下一步要做什么。选择 **Open Synthesized Design**（打开综合设计）或 **Open Report**（打开报告）。\n        *   最重要的是，查看综合报告中的 **Utilization Summary**（资源利用率摘要）。这显示了您的设计消耗了FPGA多少资源（LUT、触发器、BRAM、DSP）。确保设计适合您的目标FPGA的容量（例如，对于Artix-7 35T，您应该在其限制内）。\n\n#### **11.1.2 运行实现**\n\n实现是最耗时的一步。它接收综合后的网表并将其物理映射到FPGA的资源上（放置逻辑块，布线连接），然后执行详细的时序分析，以确保设计能够以指定的时钟频率运行。\n\n*   **步骤**：\n    1.  **开始实现**：\n        *   成功综合后，在 **Flow Navigator**（流程导航器）中，在“Implementation”（实现）下，点击 **Run Implementation**（运行实现）。\n        *   确认“Launch Runs”（启动运行）对话框。\n    2.  **监控进度**：\n        *   实现包括几个阶段：Opt Design（优化设计）、Power Opt Design（功耗优化设计）、Place Design（放置设计）、Post-Placement Phys Opt Design（后放置物理优化设计）、Route Design（布线设计）、Post-Route Phys Opt Design（后布线物理优化设计）。每个阶段都可能需要大量时间。\n        *   监控 **Messages**（消息）选项卡以了解进度和潜在问题。\n    3.  **分析时序报告**：\n        *   这是实现后*最关键的步骤*。完成后，Vivado会再次询问下一步做什么。选择 **Open Implemented Design**（打开已实现设计），或者更重要的是，选择 **Open Report**（打开报告），然后选择 **Report Timing Summary**（报告时序摘要）。\n        *   **确保所有时序约束都得到满足。** 查找“WNS (Worst Negative Slack)”值。\n            *   **正WNS**：表示所有时序路径都满足其要求（有余量）。这是您想要的结果。\n            *   **负WNS**：表示**时序违规**，这意味着您的设计无法在所需的时钟频率下运行，或者数据可能不稳定。**这是一个必须解决的关键问题。**\n        *   **解决违规**：\n            *   如果您有负余量，请调查失败的具体路径。Vivado的时序报告将显示失败路径的源、目标和组件。\n            *   解决方案可以包括：\n                *   优化HDL代码以减少逻辑深度或关键路径延迟。\n                *   添加流水线级（寄存器）以打断长组合路径。\n                *   改进XDC（约束）文件，确保所有时钟都正确定义和传播。\n                *   调整时钟频率（如果应用程序允许）。\n                *   在Vivado中使用更快的时序收敛策略。\n                *   确保您的自定义逻辑与PCIe核的AXI-Stream接口时序要求正确接口。\n    4.  **验证布局（可选）**：\n        *   在已实现的设计中，您可以打开“Device”（器件）视图，查看您的逻辑如何在FPGA上布局。这通常适用于高级用户，以确认关键组件是否最佳布局（例如，靠近PCIe收发器）。\n\n#### **11.1.3 生成比特流**\n\n比特流是最终的二进制配置文件（`.bit`扩展名），将被加载到您的FPGA上。它是综合和实现的成果。\n\n*   **步骤**：\n    1.  **生成比特流**：\n        *   成功实现后（没有严重的时序违规），在 **Flow Navigator**（流程导航器）中，在“Program and Debug”（编程和调试）下，点击 **Generate Bitstream**（生成比特流）。\n    2.  **等待完成**：\n        *   此过程通常比实现花费的时间少，但仍可能因设计复杂性而异。\n    3.  **审查比特流生成日志**：\n        *   完成后，Vivado会指示成功。审查日志中是否有任何警告，但通常如果实现顺利通过，比特流生成也会顺利通过。\n        *   `.bit`文件将生成在您的项目目录`pcileech_squirrel_top.runs/impl_1/`（或您的板卡类似路径）中。\n\n### **11.2 烧录比特流**\n\n编程（烧录）比特流会将您编译的设计加载到FPGA上，使您的仿真设备激活。\n\n#### **11.2.1 连接FPGA设备**\n\n*   **步骤**：\n    1.  **准备硬件**：\n        *   确保您的基于FPGA的DMA板卡已正确插入主机系统的兼容PCIe插槽。\n        *   将JTAG编程器（例如，Digilent HS3，Xilinx Platform Cable）连接到FPGA板卡上的JTAG接口和开发PC的USB端口。\n        *   打开主机系统电源。\n        *   请参阅您的特定FPGA板卡手册，了解精确的电源、JTAG和PCIe连接说明。\n    2.  **打开硬件管理器**：\n        *   在Vivado中，导航到 **Flow Navigator > Program and Debug > Open Hardware Manager**（流程导航器 > 编程和调试 > 打开硬件管理器）。\n        *   如果Vivado未运行，您可以作为独立应用程序启动硬件管理器。\n\n#### **11.2.2 编程FPGA**\n\n*   **步骤**：\n    1.  **连接到目标**：\n        *   在硬件管理器窗口中，点击 **Open Target**（打开目标）（通常是一个大按钮或链接），然后选择 **Auto Connect**（自动连接）。\n        *   Vivado应该自动检测到您的JTAG编程器，然后检测到JTAG链上连接的FPGA设备。如果检测失败，请检查JTAG电缆连接、板卡电源以及PC上的JTAG驱动程序。\n    2.  **编程设备**：\n        *   一旦您的FPGA设备在硬件窗口中被检测并显示，**右键单击** 您的FPGA设备（例如，`xc7a35t_0`）并选择 **Program Device**（编程设备）。\n        *   将出现一个对话框。点击“Bitstream file”（比特流文件）字段旁边的“...”按钮，导航到您生成的比特流文件（例如，`pcileech_squirrel_top.runs/impl_1/pcileech_squirrel_top.bit`）。\n        *   点击 **Program**（编程）开始将固件烧录到FPGA上。\n        *   等待编程过程完成。您将看到一个进度条。\n\n#### **11.2.3 验证编程**\n\n*   **步骤**：\n    1.  **检查状态**：\n        *   确保编程在Vivado的硬件管理器中无错误地完成。Vivado将在完成后显示“Program Device”成功消息。\n    2.  **观察LED或指示灯**：\n        *   许多FPGA板卡都有状态LED。成功的编程操作通常会导致特定LED亮起或改变状态（例如，“DONE”LED）。这是一个快速的视觉确认。\n    3.  **主机系统重启（有时需要）**：\n        *   为了让主机操作系统正确识别新编程的PCIe设备，通常需要系统重启，尤其是在Windows上，以触发完整的PCIe枚举过程。\n\n### **11.3 测试与验证**\n\n编程完成后，关键一步是验证您的仿真设备是否被主机正确检测，并且其功能是否按预期工作，模仿捐赠设备。\n\n#### **11.3.1 验证设备枚举**\n\n这证实主机操作系统根据您编程的ID将您的FPGA识别为捐赠设备。\n\n*   **Windows**：\n    *   **步骤**：\n        1.  **打开设备管理器**：按下 `Win + X` 并从快速链接菜单中选择 **Device Manager**（设备管理器）。\n        2.  **检查设备属性**：\n            *   在适当的设备类别下查找（例如，**Network Adapters**（网络适配器）、**Storage Controllers**（存储控制器）、**System devices**（系统设备））。\n            *   找到您的仿真设备。它现在应该显示为*捐赠设备的名称*（例如，“Intel(R) Ethernet Connection...”）。\n            *   右键单击该设备，选择 **Properties**（属性），然后转到 **Details**（详细信息）选项卡。\n            *   在“Property”（属性）下拉菜单中，选择“Hardware Ids”（硬件ID）。确认 **设备ID（DID）** 和 **厂商ID（VID）**（例如，`PCI\\VEN_ABCD&DEV_1234`）与您编程到固件中的值匹配。\n            *   还应检查“Class Code”（类别代码）和“Subsystem ID”（子系统ID）以进行进一步验证。\n*   **Linux**：\n    *   **步骤**：\n        1.  **使用 `lspci`**：打开终端并使用`lspci`命令。\n            ```bash\n            lspci -nn # 显示厂商ID:设备ID\n            lspci -vvv # 显示包括BAR、功能等详细信息\n            ```\n        2.  **验证设备列表**：\n            *   检查仿真设备是否在`lspci`输出中显示了正确的厂商ID、设备ID和类别代码。\n            *   **示例输出（仿真Intel NIC）**：\n                ```\n                03:00.0 Network controller [0280]: Intel Corporation Ethernet Connection I219-V [8086:1570] (rev 21)\n                ```\n                （`8086`是Intel的厂商ID，`1570`是I219-V的设备ID，`0280`是网络控制器类别代码）。\n            *   使用`lspci -vvv`确认BAR是否以正确的大小和类型枚举，与您的捐赠设备配置匹配。\n\n#### **11.3.2 测试设备功能**\n\n一旦设备被枚举，最终的测试是它是否像原始设备一样工作。\n\n*   **步骤**：\n    1.  **安装必要的驱动程序**：\n        *   如果主机操作系统未自动加载合适的驱动程序，您将需要手动安装捐赠设备的官方驱动程序。从制造商网站下载它们。\n        *   按照制造商的说明进行安装。如果仿真成功，驱动程序应该安装并识别您的FPGA为真实硬件。\n    2.  **执行功能测试**：\n        *   运行通常与捐赠设备交互的应用程序或实用程序。\n        *   **示例**：\n            *   **网卡**：执行ping测试、浏览网页或启动大文件传输以测试吞吐量。\n            *   **存储控制器**：尝试格式化模拟驱动器（如果您的仿真包括存储功能），执行读/写操作，或运行磁盘基准测试。\n            *   **USB控制器**：连接USB设备（如果您的仿真包括USB主机功能）并测试它们的检测和操作。\n        *   监控主机系统以获取预期的行为和性能特征。\n    3.  **监控系统行为**：\n        *   检查系统稳定性（Windows上没有蓝屏，Linux上没有内核崩溃）。\n        *   在系统日志中查找设备特定错误（Windows上的事件查看器，Linux上的`dmesg`或`journalctl`）。\n        *   确保仿真设备在各种工作负载下（包括大数据传输或压力测试）按预期运行。\n\n#### **11.3.3 监控错误**\n\n主动的错误监控对于识别可能不会立即导致崩溃的细微仿真问题至关重要。\n\n*   **Windows**：\n    *   **步骤**：\n        1.  **检查事件查看器**：按下 `Win + X` 并选择 **Event Viewer**（事件查看器）。\n        2.  **查找与PCIe相关的错误**：导航到 **Windows Logs > System**（Windows 日志 > 系统）。筛选或搜索与“PCIe”、“PCI Express”相关的警告、错误或关键事件，或源自特定设备驱动程序的事件（查找与您的仿真设备驱动程序匹配的源名称）。\n            *   常见错误包括资源冲突、驱动程序初始化失败或意外的设备响应。\n*   **Linux**：\n    *   **步骤**：\n        1.  **检查 `dmesg` 日志**：打开终端并输入：\n            ```bash\n            dmesg | grep -i pci # 不区分大小写地搜索pci消息\n            dmesg | grep -i <VendorID> # 过滤您的设备的厂商ID\n            ```\n        2.  **识别问题**：查找指示PCIe链路训练问题、设备初始化问题、内存分配失败或意外DMA活动的消息。Linux内核的PCIe子系统非常详细。\n    *   **Systemd Journal (现代Linux)**：\n        ```bash\n        journalctl -b | grep -i pci # 当前引导日志\n        ```\n\n---\n\n## **12. 高级调试技术**\n\n当问题出现时，特别是在复杂的PCIe设备仿真中，基本的故障排除可能不足以解决问题。高级调试工具和技术提供对FPGA内部逻辑和PCIe总线的深入可见性，使您能够高效地识别和解决问题。\n\n### **12.1 使用Vivado的集成逻辑分析仪（ILA）**\n\n集成逻辑分析仪（ILA）是Xilinx提供的一种强大、可配置的调试IP核，您可以直接将其嵌入到FPGA设计中。它允许您监控内部FPGA信号（线和寄存器）的实时行为，而无需外部探测硬件，其功能类似于一个强大的内部示波器或逻辑分析仪。\n\n#### **12.1.1 插入ILA核**\n\n*   **步骤**：\n    1.  **规划您的探头**：确定您需要观察的关键信号。对于PCIe仿真，这些信号通常包括：\n        *   PCIe IP核的AXI-Stream接口（例如，`s_axis_rx_tdata`、`s_axis_rx_tvalid`、`m_axis_tx_tdata`、`m_axis_tx_tready`）。\n        *   内部状态机信号（`current_state`、`next_state`）。\n        *   BAR地址解码输出（`bar_hit[0]`、`bar_hit[1]`）。\n        *   自定义寄存器值（`custom_control_reg`、`custom_status_reg`）。\n        *   中断请求信号（`msi_trigger_signal`）。\n    2.  **添加ILA IP核**：\n        *   在Vivado中，打开 **IP Catalog**（IP目录）（通常在 **Flow Navigator**（流程导航器）窗格中）。\n        *   搜索“ILA”（Integrated Logic Analyzer）。\n        *   双击“Debug Bridge”（用于基本ILA）或“Integrated Logic Analyzer (ILA)”以打开其定制GUI。\n        *   配置ILA：\n            *   设置您需要的**捕获数据端口数量**（探头）。\n            *   设置每个探头的**宽度**以匹配您计划连接的信号。\n            *   配置**采样深度**（在触发前/后存储多少个样本）。更深的深度会消耗更多BRAM。\n            *   点击“OK”并让Vivado生成IP。\n    3.  **实例化并连接信号**：\n        *   Vivado将生成ILA的`.xci`文件。您可以将其直接实例化在您的顶层SystemVerilog文件（例如，`pcileech_squirrel_top.sv`）中，或在可用信号的模块中。\n        *   **示例（在`pcileech_squirrel_top.sv`或子模块中）：**\n            ```verilog\n            // 假设您已从IP Catalog生成了ila_0\n            // 连接到您设计的时钟和感兴趣的信号\n            ila_0 your_ila_instance (\n                .clk(clk_125mhz), // 连接到您设计中稳定的时钟，通常是PCIe用户时钟\n                .probe0(pcie_s_axis_rx_tdata),    // 示例：PCIe入站TLP数据\n                .probe1(pcie_s_axis_rx_tvalid),   // 示例：PCIe入站TLP有效\n                .probe2(pcie_m_axis_tx_tdata),    // 示例：PCIe出站TLP数据\n                .probe3(my_bar_controller_state), // 示例：您的BAR逻辑状态\n                .probe4(my_custom_register),      // 示例：自定义寄存器的值\n                // 根据需要添加更多探头\n                .probeN(signal_to_monitor_N)\n            );\n            ```\n        *   **替代方法（标记用于调试）：** 对于更简单的信号，有时可以直接在HDL代码中标记它们用于调试。使用`(* mark_debug = \"true\" *) wire my_signal;` 或 `(* mark_debug = \"true\" *) reg my_register;`。Vivado随后会自动建议将它们添加到ILA中。\n\n#### **12.1.2 配置触发条件**\n\n当您配置智能触发条件以精确地在感兴趣的事件发生时（例如，错误、特定TLP类型、状态转换）捕获数据时，ILA最强大。\n\n*   **步骤**：\n    1.  **生成带有ILA的比特流**：插入并连接ILA后，您必须运行综合、实现并生成新的比特流。ILA核消耗FPGA资源，并将嵌入到您的设计中。\n    2.  **打开硬件管理器**：使用支持ILA的比特流编程您的FPGA（第11.2节）。然后，在Vivado中，打开硬件管理器并连接到您的目标。\n    3.  **访问ILA仪表板**：在硬件管理器中，选择您的ILA实例（例如，`hw_ila_1`）。这将打开ILA仪表板。\n    4.  **定义触发器**：\n        *   选择要用作触发输入的探头。\n        *   设置特定的**触发模式**（例如，`pcie_s_axis_rx_tdata`为`0x4A`以触发完成TLP）。\n        *   配置**触发条件**（例如，“等于”、“不等于”、“上升沿”、“下降沿”）。\n        *   设置**触发位置**（在触发事件*之前*捕获多少样本，用于预触发可见性）。\n        *   您可以设置多个触发序列以检测复杂事件。\n        *   **触发器示例场景**：\n            *   在收到的TLP中触发特定的`Fmt/Type`以分析传入命令。\n            *   当特定寄存器（`my_custom_register`）达到某个值时触发。\n            *   在`pcie_m_axis_tx_tvalid`断言 AND `pcie_m_axis_tx_tdata[3:0]` == `4'hC`（用于内存写入TLP）时触发，以分析出站写入。\n            *   在错误信号断言时触发。\n\n#### **12.1.3 捕获和分析数据**\n\n*   **步骤**：\n    1.  **运行设计**：让您的主机系统与已编程的FPGA交互，从而引发您要调试的事件。\n    2.  **布防ILA**：在ILA仪表板中，点击 **Run Trigger**（运行触发器）按钮（通常是绿色的“播放”图标）。ILA将等待定义的触发条件。\n    3.  **捕获数据**：一旦满足触发条件，ILA将把信号快照捕获到其内部内存缓冲区中。\n    4.  **分析波形**：\n        *   捕获的数据将出现在波形查看器中。\n        *   检查信号随时间的变化行为。放大、添加光标并解码值。\n        *   寻找：\n            *   **意外的跳变**：信号在错误的时间改变。\n            *   **不正确的值**：寄存器中保存了错误的数据。\n            *   **协议违规**：您的逻辑在PCIe接口上发送了不正确的数据。\n            *   **时序问题**：如果信号在预期时不稳定（尽管完整的时序分析在实现中完成，但ILA显示运行时行为）。\n        *   将捕获到的行为与您的预期设计逻辑和捐赠设备的观察行为（如果您使用协议分析仪捕获了它）进行比较。\n\n### **12.2 PCIe流量分析工具**\n\n虽然ILA提供了FPGA内部可见性，但外部PCIe流量分析工具提供了对您的仿真设备和主机之间PCIe总线上实际通信的无与伦比的视图。这对于验证协议符合性和调试链路级问题至关重要。\n\n#### **12.2.1 PCIe协议分析仪（硬件）**\n\n*   **示例**：\n    *   **Teledyne LeCroy PCIe 分析仪**：深度分析的黄金标准，完整的协议解码，高级触发，以及错误注入功能。\n    *   **Keysight PCIe 分析仪**：另一个领先的供应商，具有类似的高端功能。\n*   **步骤**：\n    1.  **设置分析仪**：将硬件分析仪串联连接在主机系统的PCIe插槽和您的基于FPGA的DMA设备之间。这通常涉及一个特殊的中间卡。\n    2.  **配置捕获设置**：使用分析仪的软件定义要捕获的流量。您可以按TLP类型、地址、请求者ID、错误条件等进行过滤，以关注相关事件。\n    3.  **捕获流量**：在主机上运行您的仿真设备。分析仪将被动记录所有PCIe事务。\n    4.  **分析结果**：\n        *   使用分析仪强大的软件查看解码的TLP、事务列表和波形视图。\n        *   **检查TLP的符合性和正确性**：所有字段都正确吗？序列是否正确？\n        *   **识别任何协议违规或意外行为**：这是您发现驱动程序可能失败的原因（例如，您的设备发送了带数据的完成，而规范要求不带数据的完成，或者响应太慢）。\n        *   **与捐赠设备捕获进行比较**：直接比较您的仿真设备捕获的流量与您从真实捐赠设备捕获的流量。这是仿真准确性的最终测试。\n\n#### **12.2.2 基于软件的工具**\n\n对于基本的PCIe总线检查，或者在没有专用硬件分析仪的情况下，一些软件工具可以提供有限的洞察。\n\n*   **示例**：\n    *   **Wireshark with PCIe Plugins**：虽然Wireshark主要用于网络流量，但通过专用硬件（例如，将PCIe跟踪暴露给操作系统的网卡，或特定的捕获硬件/驱动程序），它有时可以捕获和解码PCIe数据包。这高度依赖于系统。\n    *   **ChipScope Pro（传统Xilinx，现已集成到Vivado中）**：Integrated Logic Analyzer (ILA) 是现代的等效工具，但ChipScope曾是一个独立工具。\n    *   **`lspci` (Linux)**：如第11.3.1节所述，`lspci -vvv`提供了广泛的静态配置空间信息。您可以将其与`watch`或脚本结合使用来监控随时间的变化。\n    *   **`pcileech`客户端（来自PCILeech框架）**：`pcileech`客户端软件本身可以通过您的FPGA执行内存和配置空间的读写操作，并可用于测试基本的DMA功能。虽然不是“流量分析仪”，但它对于测试功能接口至关重要。\n*   **步骤**：\n    1.  **安装必要的工具/插件**：确保工具已安装并配置了任何所需的驱动程序或插件。\n    2.  **监控PCIe总线**：运行软件工具以捕获和显示PCIe相关信息。\n    3.  **分析通信**：\n        *   查找设备配置中的差异。\n        *   如果工具支持，分析捕获数据包的结构是否存在异常或错误。\n        *   验证您的仿真设备是否正确响应了配置请求。\n\n---\n\n## **13. 故障排除**\n\n本节提供了在PCIe设备仿真定制固件开发、比特流编程和硬件测试过程中可能遇到的常见问题的解决方案。固件调试可能具有挑战性，因此采用系统方法是关键。\n\n### **13.1 设备检测问题**\n\n**问题**：您的基于FPGA的DMA设备在编程后未被主机系统识别，或者在设备管理器/lspci中显示为不正确的ID（例如，“未知设备”）或错误符号。\n\n#### **可能原因及解决方案**：\n\n1.  **设备ID、厂商ID、子系统ID或类别代码不正确**：\n    *   **原因**：最常见的原因。您编程到FPGA固件中的识别值与主机操作系统预期或您打算仿真的值不匹配。\n    *   **解决方案**：\n        *   **验证**：仔细检查`pcileech_pcie_cfg_a7.sv`（或等效文件）中的所有`cfg_deviceid`、`cfg_vendorid`、`cfg_subsysid`、`cfg_subsysvendorid`、`cfg_revisionid`和`cfg_classcode`参数，与您精心记录的捐赠设备信息（来自第5节）进行比对。\n        *   **一致性**：确保这些值在Vivado PCIe IP核定制GUI（第7.2.2节）中也保持一致设置。\n        *   **重新构建并重新烧录**：进行任何更改后，始终重新综合、重新实现、生成新的比特流并重新烧录FPGA（第11.1、11.2节）。\n        *   **重启主机**：烧录后务必重启主机系统，因为Windows通常需要完全重启才能正确重新枚举PCIe设备。\n\n2.  **PCIe链路训练失败**：\n    *   **原因**：主机根联合体与您的FPGA卡之间的基本PCIe链路未能建立。这发生在任何配置空间读取之前。症状包括设备完全不出现（`lspci`在该总线/插槽上没有任何显示，或设备管理器显示“PCI Express Root Port”错误）。\n    *   **解决方案**：\n        *   **物理连接**：确保FPGA板卡牢固地插入PCIe插槽，并且所有电源连接都牢固。如果可能，尝试不同的PCIe插槽。\n        *   **电源**：验证FPGA板卡是否获得足够的电源。某些板卡需要辅助PCIe电源连接器。\n        *   **链路速度/宽度**：\n            *   检查Vivado PCIe IP核中的`Max Link Speed`和`Link Width`设置（第8.1.1节）。\n            *   尝试将链路速度设置为较低的代数（例如，Gen1 / 2.5 GT/s）并将宽度设置为x1，即使您的板卡支持更高。有时，在较高速度下与特定主板会产生兼容性问题。\n            *   检查主板BIOS设置中的PCIe插槽速度选项。\n        *   **复位**：确保FPGA的复位逻辑正确实现（例如，与PCIe参考时钟同步），并在上电/重启时正确断言/去断言。\n        *   **PCIe IP核**：确保PCIe IP核正确实例化，并且其时钟和复位在您的顶层设计中正确连接。\n\n3.  **电源问题（电源不足或不稳定）**：\n    *   **原因**：FPGA板卡未获得足够的稳定电源，或电源供应不稳定，导致操作不可靠。\n    *   **解决方案**：\n        *   **验证连接**：仔细检查所有电源线（主PCIe插槽电源、辅助PCIe电源、如果使用则包括外部直流插孔）。\n        *   **电源供应**：确保您的主机系统电源（PSU）具有足够的瓦数和稳定的12V电压轨。对于高功耗FPGA，弱电源可能导致问题。\n        *   **外部电源**：如果板卡有外部电源插孔，请确保使用正确电压和电流额定值的电源。\n\n4.  **固件错误（早期阶段）**：\n    *   **原因**：SystemVerilog代码中的逻辑错误，特别是顶层模块或PCIe核的包装器中，导致PCIe核无法初始化或正确呈现自身。\n    *   **解决方案**：\n        *   **Vivado消息**：仔细检查Vivado的综合和实现日志中与PCIe IP核相关的**严重警告**或**错误**。这些通常是配置错误或连接不当的指示。\n        *   **ILA调试**：如果链路尝试训练但失败，请使用连接到PCIe IP核的状态信号（例如，`link_up`、`link_speed`、`link_width`）和AXI-Stream接口的ILA（第12.1节），以查看链路协商在哪个点失败，或者核是否生成了意外流量。\n\n### **13.2 内存映射和BAR配置错误**\n\n**问题**：仿真设备已检测到，但当主机操作系统或驱动程序尝试通过BAR访问其内存映射寄存器或缓冲区时，系统崩溃、冻结或报告错误。\n\n#### **可能原因及解决方案**：\n\n1.  **BAR大小或类型不正确（IP核和固件）**：\n    *   **原因**：您在Vivado PCIe IP核（第7.2.2节）中配置的BAR大小或类型（32位/64位、内存/I/O、可预取/不可预取）和/或在`pcileech_tlps128_bar_controller.sv`中处理的值与捐赠设备实际提供的值不匹配。这可能导致主机分配不正确的地址空间或尝试不支持的访问。\n    *   **解决方案**：\n        *   **交叉验证**：返回到您的Arbor/协议分析仪数据（第5节），重新验证每个BAR配置（大小、类型、可预取）。\n        *   **一致性**：确保这些值在PCIe IP核定制中完全匹配，并且您的`bar_controller`逻辑正确处理每个BAR的大小（地址解码范围）和类型。\n        *   **BRAM大小**：如果您的BAR映射到BRAM，请确认BRAM IP核的大小（第8.2.1节）与BAR大小完全匹配。\n\n2.  **固件中的地址解码错误**：\n    *   **原因**：您的`pcileech_tlps128_bar_controller.sv`（或自定义BAR逻辑）错误地解释了传入的PCIe地址，导致访问了不正确的内部寄存器或内存位置。\n    *   **解决方案**：\n        *   **审查逻辑**：仔细审查`bar_controller`中的`case`语句和地址计算。\n        *   **仿真**：在您的SystemVerilog测试平台中开发特定的测试用例，模拟主机对每个BAR中不同偏移量的读写访问。验证内部`bar_hit`信号是否正确，以及数据是否正确路由到/从正确的内部寄存器/BRAM。\n        *   **ILA调试**：在`req_addr`、`req_write`、`req_read`、`req_data`、`rsp_data`以及`bar_controller`中与您的地址解码和寄存器访问相关的内部信号上放置ILA探头。实时观察地址如何解码以及正在读/写的数据。\n\n3.  **内部地址空间重叠**：\n    *   **原因**：虽然PCIe标准确保不同设备的BAR在主机的内存映射中不重叠，但在FPGA*内部*，您可能会意外地将不同的逻辑组件映射到单个BAR中的相同物理地址空间。\n    *   **解决方案**：\n        *   **仔细映射**：在BAR中定义内部寄存器和内存块时，显式为每个寄存器和内存块分配唯一的、不重叠的偏移量。使用`localparam`来定义这些偏移量以防止错误。\n        *   **设计审查**：需要对您的`bar_controller`进行彻底的设计审查，以确保每个地址范围都得到唯一处理。\n\n4.  **BRAM访问问题**：\n    *   **原因**：您的逻辑与BRAM IP核接口存在问题（例如，不正确的BRAM时钟、异步复位、错误的字节使能或不正确的写入使能逻辑）。\n    *   **解决方案**：\n        *   **BRAM文档**：查阅Xilinx BRAM IP核文档，了解正确的实例化和接口信号。\n        *   **ILA**：在BRAM接口信号（地址、写入使能、数据输入、数据输出）上放置ILA探头，以验证您的逻辑是否向BRAM发送了正确的控制信号。\n\n### **13.3 DMA性能和TLP错误**\n\n**问题**：设备已检测到并功能上看起来正常，但在大型DMA操作期间，数据传输速率缓慢，或者系统间歇性崩溃、挂起或报错。PCIe协议分析仪报告TLP格式错误或流控制问题。\n\n#### **可能原因及解决方案**：\n\n1.  **TLP格式错误（报头/载荷）**：\n    *   **原因**：您的固件生成的TLP（特别是您的FPGA作为DMA主设备时发送的完成或出站内存写入）具有不正确的报头、长度、字节使能或载荷。主机系统的PCIe核或驱动程序将其检测为违规。\n    *   **解决方案**：\n        *   **PCIe协议分析仪**：这是最好的工具（第12.2.1节）。捕获流量并仔细比较您生成的TLP与PCIe规范，更重要的是，与您*真实捐赠设备*的捕获进行比较。\n        *   **TLP生成逻辑**：审查您的TLP组装代码（`pcileech_pcie_tlp_a7.sv`及相关模块）。确保所有字段（Fmt、Type、Requester ID、Tag、Completion ID、Length、Byte Enables、Address）都正确派生并打包到TLP结构中。\n        *   **错误检查**：在固件中实现基本的错误检查（例如，检查是否存在意外的`req_valid`而没有`req_ready`，反之亦然）。\n\n2.  **流控制问题**：\n    *   **原因**：PCIe使用基于信用的流控制机制。如果您的固件（或PCIe IP核与其的交互）错误地管理信用，可能导致死锁、超时或丢包。症状包括PCIe链路“停滞”、超时或低吞吐量。\n    *   **解决方案**：\n        *   **PCIe IP核配置**：确保Vivado PCIe IP核定制中的流控制设置适用于您预期的流量模式。默认设置通常是健壮的。\n        *   **用户逻辑反压**：您的用户逻辑向PCIe IP核发送TLP（`m_axis_tx_*`接口）*必须*遵守来自IP核的`m_axis_tx_tready`信号。如果`tready`被去断言，您*必须*暂停发送数据。否则将导致核的缓冲区溢出。\n        *   **ILA调试**：将ILA探头连接到PCIe IP核的流控制接口信号和您的用户逻辑，以观察`tvalid`/`tready`握手是否正常工作。\n\n3.  **DMA逻辑效率低下/缓冲问题**：\n    *   **原因**：FPGA内部的DMA引擎实现（读取/写入主机内存数据的部分）未优化，导致瓶颈。这可能涉及：\n        *   缺少流水线。\n        *   BRAM使用效率低下。\n        *   外部内存访问延迟导致的停滞。\n        *   突发大小过小。\n    *   **解决方案**：\n        *   **流水线**：将长组合路径分解为更小、更连续的阶段，使用寄存器。这允许更高的时钟频率和更好的吞吐量。\n        *   **缓冲**：使用FIFO（先进先出缓冲区）来解耦发送方和接收方逻辑，平滑数据流并防止停滞。\n        *   **突发传输**：利用PCIe执行突发读/写的能力以提高效率。确保您的DMA逻辑以适当的突发大小请求和处理数据。\n        *   **内存带宽**：确保您的BRAM或外部DDR内存接口能够足够快地提供/消耗数据，以满足您所需的DMA速率。\n        *   **ILA**：监控您的DMA引擎的内部状态、读写指针和数据路径信号，以识别瓶颈。\n\n4.  **完成超时/不支持的请求**：\n    *   **原因**：主机发送请求（例如MRd、CfgRd），但您的FPGA设备未在允许的超时时间内响应完成TLP，或者它以错误状态（例如，带有Unsupported Request (UR) 或 Completer Abort (CA) 的完成）进行响应。\n    *   **解决方案**：\n        *   **响应逻辑**：验证您的`bar_controller`（用于MRd）和`pcileech_pcie_cfg_a7.sv`（用于自定义配置空间的CfgRd）是否正确识别请求并生成适当的完成。\n        *   **超时值**：审查您的捐赠设备预期的完成延迟。虽然PCIe定义了默认超时，但某些驱动程序可能对此敏感。\n        *   **ILA/协议分析仪**：对于查明*为什么*未发送完成或完成格式错误至关重要。请求TLP是否甚至到达了您的用户逻辑？您的逻辑是否生成了响应？PCIe核是否成功发送了响应？\n\n---\n\n## **14. 仿真精度与优化**\n\n实现真正令人信服的仿真意味着让您的基于FPGA的设备与捐赠设备难以区分，不仅在ID上，而且在行为上。这需要对时序、响应速度和微妙的操作细节进行细致的关注。\n\n### **14.1 精确定时仿真技术**\n\n精确的时序在硬件中至关重要，特别是对于PCIe这样的高速接口。不匹配可能导致驱动程序超时、数据解释不正确或系统不稳定。\n\n*   **实现时序约束（XDC文件）**：\n    *   **目的**：时序约束是 Vivado 综合和实现工具的指令，告诉它们您的设计需要运行多快。它们定义了时钟周期、输入/输出延迟和路径延迟。\n    *   **用法**：PCILeech-FPGA项目包含 XDC 文件（例如，`pcileech_squirrel_top.xdc`），它们定义了主时钟（例如，`create_clock -name sys_clk_p -period 8.0 [get_ports sys_clk_p]`）。\n    *   **优化**：如果您的仿真需要非常特定的内部时序或对时间敏感的命令做出反应，您可能需要在自定义逻辑中添加进一步的约束（`set_max_delay`、`set_input_delay`、`set_output_delay`）到关键路径。\n    *   **目标**：确保 Vivado 在实现后报告所有路径的 **正 WNS（最差负余量）**，表明设计满足其时序要求。\n\n*   **使用时钟域交叉（CDC）技术**：\n    *   **目的**：PCIe设计通常涉及多个时钟域（例如，125MHz PCIe用户时钟，自定义逻辑的单独时钟）。在这些域之间异步移动信号（没有适当的同步）可能导致**亚稳态**，从而导致不可靠的行为。\n    *   **实现**：对于跨时钟域的信号，始终使用适当的CDC电路：\n        *   **双触发器同步器**：用于单比特控制信号。\n        *   **异步FIFO（先进先出）**：用于多比特数据路径，提供时钟域之间的数据缓冲和流控制。\n        *   **格雷码编码器/解码器**：用于跨域的计数器或地址，以确保每次只有一个比特发生变化。\n    *   **Vivado 工具**：Vivado 包含 CDC 分析工具（例如，`report_cdc`），可以识别潜在的亚稳态问题。\n\n*   **使用时间精确模型仿真设备行为**：\n    *   **高级测试平台**：使用 SystemVerilog 测试平台，其中包含真实的定时延迟，甚至提供时间精确的 PCIe 总线功能模型（BFM）。\n    *   **验证**：这使您可以观察您的仿真设备的内部状态以及外部 TLP 生成/响应时序在各种条件下如何表现，确保它们与您捕获的捐赠设备行为相匹配。\n\n### **14.2 对系统调用的动态响应**\n\n真正精确的仿真不仅能呈现正确的ID；它还能智能且动态地响应主机系统的命令和查询，模仿真实、活动设备的行为。\n\n*   **实现设备控制的状态机**：\n    *   **目的**：设计健壮的 SystemVerilog 状态机来管理设备的操作模式、命令处理和数据流。\n    *   **响应性**：确保状态机能够逻辑地、快速地响应传入命令（例如，写入 BAR 中的控制寄存器，特定的 TLP）。\n    *   **优雅处理**：状态机应能够优雅地处理意外或无序的请求，可能返回错误 TLP 或仅仅忽略无效命令，而不是崩溃或冻结。\n\n*   **监控和响应主机命令（超越简单的读写）**：\n    *   **配置写入**：除了初始枚举之外，驱动程序通常会写入配置空间寄存器以启用功能、设置阈值或清除状态位。您的固件必须处理这些写入并相应地更新内部状态。\n    *   **厂商特定命令**：如第9.2节所述，如果捐赠设备具有专有命令（通过自定义寄存器或厂商定义消息访问），您的固件必须解析这些命令并触发适当的仿真行为。\n    *   **电源管理命令**：通过启用/禁用内部逻辑并确认状态更改来响应主机发起的电源状态转换（D0、D1、D3hot 等）。\n    *   **中断确认**：如果主机驱动程序通过写入特定寄存器来确认中断，请确保您的固件能够检测到此并清除内部中断请求。\n\n*   **优化固件逻辑以提高响应性**：\n    *   **降低延迟**：关键数据路径和控制路径应优化，以最小化组合逻辑深度和流水线停顿。\n    *   **并行性**：利用 FPGA 固有的并行性来同时执行多个操作，提高吞吐量和响应时间。\n    *   **高效内存访问**：优化对内部 BRAM 或外部 DDR 内存的访问，以确保在需要时为 DMA 传输或寄存器读取提供数据。\n    *   **硬件加速**：对于捐赠设备执行的复杂计算或数据操作，请考虑在 FPGA 上实现专用的硬件加速器，而不是尝试以缓慢、类似软件的方式执行它们。\n\n---\n\n## **15. 固件开发最佳实践**\n\n在定制固件开发中遵循最佳实践对于保持代码质量、促进协作（如果团队合作）、简化调试以及确保项目的长期可维护性和可靠性至关重要。这对于安全敏感的应用尤为如此。\n\n### **15.1 持续测试与文档**\n\n*   **定期、增量测试**：\n    *   **单元测试**：使用专用测试平台隔离测试小型独立模块（例如，TLP解析器、寄存器块）。\n    *   **集成测试**：验证不同模块是否协同工作。\n    *   **系统测试**：烧录后，与主机系统执行端到端测试，确保整体功能。\n    *   **尽早测试，经常测试**：在每次重大更改后，无论多小，都要测试固件，以便尽早发现问题，此时问题更容易调试。\n\n*   **自动化测试（高级）**：\n    *   对于复杂项目，在主机端实现自动化测试脚本（例如，使用Python和硬件抽象层）以重复验证功能和性能。\n    *   在团队环境中，考虑与持续集成（CI）工具（例如，Jenkins、GitLab CI）集成，以自动化每次代码提交的构建、测试和静态分析。\n\n*   **维护全面的文档**：\n    *   **设计文档**：创建并更新描述固件架构的文档，包括：\n        *   **框图**：说明主要模块及其互连。\n        *   **状态机图**：适用于所有有状态逻辑。\n        *   **接口规范**：详细说明模块之间的输入/输出信号、时序和协议。\n        *   **内存映射**：针对所有BAR，定义寄存器地址、位域及其功能。\n    *   **代码注释**：在SystemVerilog代码中使用清晰、简洁的注释来解释复杂的逻辑、信号的目的以及任何不明显的设计选择。\n    *   **更改日志/提交消息**：维护更改日志或使用详细的Git提交消息来跟踪所有修改、错误修复和功能添加，解释*为什么*进行更改。\n    *   **用户指南**：对于您的定制固件，一个简单的用户指南，解释如何从主机端构建、烧录和与仿真设备交互，是无价的。\n\n### **15.2 管理固件版本**\n\n正确的版本控制对于跟踪更改、有效协作和管理发布至关重要。\n\n*   **使用版本控制系统（VCS）**：\n    *   **Git**：强烈推荐。使用Git管理您的HDL源代码、约束文件和项目脚本。\n    *   **组织仓库**：保持清晰的目录结构（例如，为`src`、`xdc`、`ip`、`scripts`、`doc`等设置单独的文件夹）。\n    *   **分支**：使用功能分支开发新功能或进行重大更改。在彻底测试后合并回`main`或`develop`分支。\n    *   **定期提交**：频繁提交，提交内容原子化，提交消息有意义。\n\n*   **标记发布和里程碑**：\n    *   **稳定版本**：使用Git标签（例如，`v1.0.0`、`v1.0.1_bugfix`）标记固件的稳定、经过测试的版本。这使得回溯或部署已知良好状态变得容易。\n    *   **里程碑**：标记重要的开发里程碑（例如，“基本枚举工作正常”、“DMA读/写功能正常”）。\n\n*   **备份和恢复策略**：\n    *   **基于云的仓库**：将您的Git仓库托管在GitHub、GitLab或Bitbucket等平台上。这提供了异地备份并促进了协作。\n    *   **本地备份**：即使有云仓库，也要定期对整个Vivado项目目录进行本地备份（由于生成的文件，它可能非常大）。\n\n### **15.3 安全注意事项**\n\n开发用于PCIe设备仿真（特别是能够直接内存访问的设备）的定制固件具有重要的安全影响。这项技术本质上是一种“两用”能力，意味着它既可以用于合法目的（例如，硬件测试、安全研究），也可以用于恶意目的（例如，DMA攻击、安全绕过）。**理解并负责任地管理这些风险至关重要。**\n\n*   **两用性质与道德影响**：\n    *   **道德黑客行为与恶意使用**：明确区分将这些知识用于授权安全测试（红队演练、渗透测试）和未经授权的非法活动。\n    *   **负责任的披露**：如果您使用这些技术发现漏洞，请遵循负责任的披露准则。\n    *   **法律和许可合规性**：了解并遵守所有与硬件逆向工程和设备修改相关的法律、法规和许可协议（例如，PCIe-SIG规范、Xilinx EULA）。\n    *   **“武器化”**：认识到精确仿真受信任硬件的能力可以被武器化用于高级持久威胁（APTs）或复杂恶意软件。\n\n*   **理解攻击向量（攻击视角）**：\n    *   **内存窃取**：恶意仿真设备可以执行DMA读取，以访问任何物理内存地址，包括内核、用户进程中的敏感数据、加密密钥或网络缓冲区。\n    *   **内存注入/修改**：恶意仿真设备可以执行DMA写入以任意修改内存，从而实现：\n        *   **权限提升**：修改内核数据结构（例如，进程令牌、SID）以获得管理员或系统权限。\n        *   **代码注入**：将恶意代码注入正在运行的进程或内核，然后触发其执行。\n        *   **安全软件绕过**：通过直接修改内存来禁用或颠覆端点检测和响应（EDR）、防病毒或防火墙软件。\n    *   **模糊测试和崩溃**：发送格式错误或不符合规范的TLP/命令，以触发驱动程序漏洞，导致系统崩溃（蓝屏死机）或潜在的可利用内存损坏。\n    *   **固件/BIOS操作**：在某些高级场景中，DMA设备可能能够与包含BIOS/UEFI的主机SPI闪存进行交互，可能用于持久性修改。\n\n*   **防御措施和缓解策略（防御视角）**：\n    *   **IOMMU/VT-d/AMD-Vi**：如第3.2节所述，这些技术旨在通过为外设提供内存保护来缓解DMA攻击。**对于合法测试，您会禁用它们，但在生产系统中，它们应始终启用。** 它们阻止外设未经授权的内存访问。\n    *   **内核DMA保护（Windows）/ Thunderbolt安全（Linux）**：现代操作系统功能专门解决“冷启动”DMA攻击（攻击者在系统关闭或锁定时连接恶意设备）。在生产系统上保持这些功能启用。\n    *   **安全启动**：虽然不是直接的DMA保护，但安全启动有助于确保只加载受信任的引导加载程序和内核模块，从而减少攻击者注入恶意内核组件以绕过DMA保护的机会。\n    *   **物理安全**：最基本但最关键的防御。如果攻击者可以物理访问PCIe插槽或Thunderbolt端口，他们可以绕过许多软件保护。保护对关键系统的物理访问。\n    *   **驱动程序强化**：驱动程序应以防御性方式编写，严格验证来自硬件的所有输入并在严格的内存边界内操作。\n    *   **内存强化**：操作系统级的内存保护（例如KASLR、DEP、SMAP/SMEP）有助于减少内存损坏的影响，但直接DMA攻击会绕过这些保护。\n    *   **监控和日志记录**：虽然在硬件层面很难，但异常的DMA活动或未知PCIe设备的枚举应在安全监控系统中触发警报。\n\n*   **固件安全编码实践**：\n    *   **输入验证**：如果您的固件接受任何输入（例如，通过UART调试接口，或由主机写入的内部寄存器），请严格验证它们，以防止缓冲区溢出、整数溢出或意外行为。\n    *   **最小权限**：设计您的固件逻辑，使其仅执行其功能绝对必要的操作。避免授予不必要的功能。\n    *   **状态管理**：实现健壮的状态机，以防止由于无效状态转换而导致的意外行为。\n    *   **无硬编码秘密**：避免直接在固件中嵌入敏感信息（例如，加密密钥、硬编码凭据），如果它们可以轻易被提取。\n    *   **篡改检测**：对于生产固件，考虑实现检测固件本身是否已被篡改或是否加载了未经授权配置的机制。\n\n---\n\n## **16. 其他资源**\n\n为了加深您对FPGA开发、PCIe和硬件安全等动态领域的理解并保持更新，请查阅以下资源：\n\n*   **Xilinx (AMD) 文档**：您获取Vivado和Xilinx FPGA所有信息的主要来源。\n    *   **主文档门户**：[https://docs.amd.com/](https://docs.amd.com/)（原Xilinx.com/support/documentation）。\n    *   **Vivado 设计套件用户指南**：\n        *   **UG900 - 入门指南**：Vivado新用户必备。\n        *   **UG901 - 逻辑综合**：深入了解综合。\n        *   **UG904 - 实现**：关于放置和布线的详细指南。\n        *   **UG912 - Tcl 命令参考指南**：对于脚本编写价值巨大。\n        *   **UG939 - 调试**：ILA和其他调试功能的综合指南。\n    *   **PCI Express IP 核用户指南**：理解Xilinx PCIe IP至关重要（例如，**PG054 for 7 Series Integrated Block for PCI Express**）。在文档门户上搜索“PCI Express”。这详细介绍了核的配置、接口和限制。\n\n*   **PCI-SIG 规范**：PCIe 标准的权威来源。\n    *   **PCI Express Base Specification**：基础文档。虽然不公开免费，但基于它的摘要和教育材料广泛可用。您通常可以在其网站上找到信息：[https://pcisig.com/specifications](https://pcisig.com/specifications)（注意：完整规范通常需要PCI-SIG会员资格）。\n\n*   **FPGA 教程和学习平台**：\n    *   **FPGA4Fun**：[http://www.fpga4fun.com/](http://www.fpga4fun.com/) - 一个经典网站，提供许多实用的FPGA项目和教程。\n    *   **Verilog/VHDL 教程**：\n        *   **ASIC World Verilog 教程**：[https://www.asic-world.com/verilog/index.html](https://www.asic-world.com/verilog/index.html) - 很好的Verilog基础参考。\n        *   **VHDLwhiz**：[https://www.vhdlwhiz.com/](https://www.vhdlwhiz.com/) - VHDL 参考和教程。\n    *   **Stack Overflow (FPGA/Verilog/PCIe 标签)**：[https://stackoverflow.com/questions/tagged/fpga](https://stackoverflow.com/questions/tagged/fpga) - 社区驱动的针对特定技术问题的问答。\n\n*   **PCIe 协议分析工具**：\n    *   **Teledyne LeCroy Protocol Analyzers**：[https://teledynelecroy.com/protocolanalyzer/](https://teledynelecroy.com/protocolanalyzer/) - 探索他们的高性能PCIe分析仪和软件系列。\n    *   **Telescan PE Software**：[https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software) - 一款免费软件工具，提供一些PCIe分析功能（需要注册）。\n\n*   **PCILeech 社区和资源**：\n    *   `ufrisk/pcileech` GitHub 仓库是核心。积极关注其更新和问题。\n    *   寻找致力于PCILeech或类似开源DMA项目的社区论坛或Discord服务器。\n\n*   **硬件安全与逆向工程**：\n    *   关于硬件黑客、逆向工程和低级系统利用的书籍。\n    *   Black Hat、DEF CON、Recon 和 Troopers 等会议通常会举办关于 PCIe 和 DMA 攻击的讲座。\n    *   专注于硬件的安全研究人员的博客和研究论文。\n\n---\n\n## **17. 联系方式**\n\n如果您需要帮助、有疑问或希望就本指南、固件开发或硬件安全相关主题进行合作，请随时联系。我乐意提供指导、解决复杂问题或详细讨论想法。\n\n### **Discord**：\n*   **用户**：[**VCPU**](https://discord.com/users/196741541094621184)\n*   **服务器邀请链接**：[**加入硬件黑客与固件开发Discord**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **18. 支持与贡献**\n\n您的支持有助于维护和改进本指南及相关项目。创建和更新全面的技术文档以及开源硬件项目需要大量时间和精力。\n\n### **捐赠**\n\n如果您觉得本指南有帮助并希望支持正在进行的工作，请考虑捐赠。每一笔捐款，无论大小，都有助于我们继续通过进一步的研究、开发和文档工作来创建、分享和支持社区。\n\n*   **加密货币捐赠（LTC - 莱特币）**：\n    *   **地址**：`MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi`\n\n**特别奖励**：如果您捐赠，请随时在Discord上（VCPU）与我联系，以获得个人感谢，并可能获得额外资源、新内容的早期访问或项目上的个性化帮助。\n\n**注意**：如果您需要我审查您实现的特定部分、解决问题或提供详细的代码反馈，请在您的代码中用`//VCPU-REVIEW//`注释标记相关部分，并提供您遇到的问题或疑问的详细说明。这有助于我集中精力并提供最有效的支持。\n\n愿上帝保佑您的灵魂。\n\n---\n\n**指南结束**\n"
  },
  {
    "path": "CN/核对表.md",
    "content": "# 固件修改清单\n\n使用此清单来指导您的固件创建过程。\n\n---\n\n## **1. 收集捐赠设备信息**\n\n从捐赠的PCIe设备收集以下信息：\n\n- [ ] **设备ID** (`0xXXXX`)\n- [ ] **供应商ID** (`0xYYYY`)\n- [ ] **子系统ID** (`0xZZZZ`)\n- [ ] **子系统供应商ID** (`0xWWWW`)\n- [ ] **修订ID** (`0xRR`)\n- [ ] **类代码** (`0xCCCCCC`)\n- [ ] **基地址寄存器（BARs）配置**：\n  - [ ] **BAR0**至**BAR5**的大小、类型（内存或I/O）、可预取状态\n- [ ] **功能**：\n  - [ ] 电源管理设置\n  - [ ] MSI/MSI-X设置\n- [ ] **设备序列号（DSN）** (`0xXXXXXXXXYYYYYYYY`)\n\n---\n\n## **2. 修改固件配置文件**\n\n### **2.1. 打开固件配置文件**\n\n- [ ] **要编辑的文件**：`pcileech_pcie_cfg_a7.sv`\n- [ ] **位置**：`pcileech-fpga/pcileech-wifi-main/src/pcileech_pcie_cfg_a7.sv`\n\n### **2.2. 更新设备和供应商ID**\n\n- [ ] **修改** `cfg_deviceid`：\n\n  ```verilog\n  cfg_deviceid <= 16'hXXXX;  // 将XXXX替换为捐赠设备的设备ID\n  ```\n\n- [ ] **修改** `cfg_vendorid`：\n\n  ```verilog\n  cfg_vendorid <= 16'hYYYY;  // 将YYYY替换为捐赠设备的供应商ID\n  ```\n\n### **2.3. 更新子系统ID和修订ID**\n\n- [ ] **修改** `cfg_subsysid`：\n\n  ```verilog\n  cfg_subsysid <= 16'hZZZZ;  // 将ZZZZ替换为捐赠设备的子系统ID\n  ```\n\n- [ ] **修改** `cfg_subsysvendorid`：\n\n  ```verilog\n  cfg_subsysvendorid <= 16'hWWWW;  // 将WWWW替换为捐赠设备的子系统供应商ID\n  ```\n\n- [ ] **修改** `cfg_revisionid`：\n\n  ```verilog\n  cfg_revisionid <= 8'hRR;  // 将RR替换为捐赠设备的修订ID\n  ```\n\n### **2.4. 更新类代码**\n\n- [ ] **修改** `cfg_classcode`：\n\n  ```verilog\n  cfg_classcode <= 24'hCCCCCC;  // 将CCCCCC替换为捐赠设备的类代码\n  ```\n\n### **2.5. 插入设备序列号（DSN）**\n\n- [ ] **修改** `cfg_dsn`：\n\n  ```verilog\n  cfg_dsn <= 64'hXXXXXXXXYYYYYYYY;  // 替换为捐赠设备的DSN\n  ```\n\n---\n\n## **3. 定制Vivado项目**\n\n### **3.1. 生成Vivado项目文件**\n\n- [ ] **打开Vivado**，并在Tcl控制台中运行相应的Tcl脚本：\n\n  ```tcl\n  cd <project_directory>\n  source vivado_generate_project_<your_board>.tcl -notrace\n  ```\n\n  - 将`<project_directory>`替换为您的项目路径。\n  - 将`<your_board>`替换为您的FPGA板标识符（例如，`squirrel`）。\n\n### **3.2. 打开生成的项目**\n\n- [ ] **文件**：在Vivado中打开生成的`.xpr`项目文件。\n\n---\n\n## **4. 修改PCIe IP核**\n\n### **4.1. 打开PCIe IP核配置**\n\n- [ ] **要编辑的文件**：`pcie_7x_0.xci`\n- [ ] **操作**：右键点击并选择**定制IP**。\n\n### **4.2. 设置设备标识符**\n\n- [ ] **设备ID**：设置为捐赠设备的设备ID。\n- [ ] **供应商ID**：设置为捐赠设备的供应商ID。\n- [ ] **子系统ID**：设置为捐赠设备的子系统ID。\n- [ ] **子系统供应商ID**：设置为捐赠设备的子系统供应商ID。\n- [ ] **修订ID**：设置为捐赠设备的修订ID。\n- [ ] **类代码**：设置为捐赠设备的类代码。\n\n### **4.3. 配置BARs**\n\n对于每个BAR（BAR0至BAR5）：\n\n- [ ] **启用/禁用**：与捐赠设备匹配。\n- [ ] **类型**：内存（32位或64位）或I/O。\n- [ ] **大小**：设置为捐赠设备的BAR大小。\n- [ ] **可预取**：与捐赠设备的设置匹配。\n\n### **4.4. 匹配PCIe链路参数**\n\n- [ ] **最大链路速度**：设置为匹配捐赠设备（例如，**Gen2**、**Gen3**）。\n- [ ] **链路宽度**：设置为匹配捐赠设备（例如，**x1**、**x4**）。\n\n### **4.5. 配置功能**\n\n- [ ] **启用电源管理**（如果捐赠设备支持）。\n- [ ] **启用MSI/MSI-X**（如果捐赠设备支持）。\n\n### **4.6. 应用更改并锁定IP核**\n\n- [ ] **应用**：点击**OK**保存IP核设置。\n- [ ] **锁定IP核**：在Tcl控制台中运行：\n\n  ```tcl\n  set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n  ```\n\n---\n\n## **5. 为高级功能调整固件**\n\n### **5.1. 更新能力指针**\n\n- [ ] **要编辑的文件**：`pcileech_pcie_cfg_a7.sv`\n- [ ] **修改** `cfg_cap_pointer`：\n\n  ```verilog\n  cfg_cap_pointer <= 8'hXX;  // 将XX替换为捐赠设备的能力指针\n  ```\n\n### **5.2. 调整最大有效载荷和读取请求大小**\n\n- [ ] **在PCIe IP核中**：将**最大有效载荷大小**和**最大读取请求大小**设置为匹配捐赠设备。\n\n- [ ] **在固件中（`pcileech_pcie_cfg_a7.sv`）**：\n\n  ```verilog\n  max_payload_size_supported <= 3'bYYY;  // 二进制值，对应于捐赠设备的最大有效载荷大小\n  ```\n\n  - **映射关系**：\n\n    | 有效载荷大小（字节） | 二进制值   |\n    |----------------------|------------|\n    | 128                  | `3'b000`   |\n    | 256                  | `3'b001`   |\n    | 512                  | `3'b010`   |\n    | 1024                 | `3'b011`   |\n    | 2048                 | `3'b100`   |\n    | 4096                 | `3'b101`   |\n\n### **5.3. 实现电源管理逻辑**\n\n- [ ] **要编辑的文件**：`pcileech_pcie_cfg_a7.sv`\n- [ ] **添加逻辑**以处理电源状态转换（如果适用）。\n\n### **5.4. 实现MSI/MSI-X中断**\n\n- [ ] **在PCIe IP核中**：启用MSI或MSI-X功能，并设置支持的向量数量。\n\n- [ ] **在固件中（`pcileech_pcie_tlp_a7.sv`）**：\n\n  - [ ] **添加中断逻辑**以处理MSI/MSI-X中断。\n\n---\n\n## **6. 调整固件中的BAR处理**\n\n### **6.1. 打开BAR控制器文件**\n\n- [ ] **要编辑的文件**：`pcileech_tlps128_bar_controller.sv`\n- [ ] **位置**：`pcileech-fpga/pcileech-wifi-main/src/pcileech_tlps128_bar_controller.sv`\n\n### **6.2. 更新BAR地址解码**\n\n- [ ] **修改**地址解码逻辑，以匹配捐赠设备的BAR大小和地址。\n\n### **6.3. 实现BAR访问逻辑**\n\n对于每个启用的BAR：\n\n- [ ] **实现读/写处理程序**，对应于BAR的用途。\n\n---\n\n## **7. 实现TLP处理**\n\n### **7.1. 打开TLP处理文件**\n\n- [ ] **要编辑的文件**：`pcileech_pcie_tlp_a7.sv`\n\n### **7.2. 修改TLP处理逻辑**\n\n- [ ] **实现**处理捐赠设备所需的特定TLP类型的逻辑：\n\n  - [ ] 内存读取请求\n  - [ ] 内存写入请求\n  - [ ] 配置读取/写入请求\n  - [ ] 供应商定义的消息\n\n### **7.3. 确保TLP合规**\n\n- [ ] **验证**TLP按照PCIe规范正确格式化。\n\n---\n\n## **8. 构建并烧录固件**\n\n### **8.1. 运行综合和实现**\n\n在Vivado中：\n\n- [ ] **运行综合**\n- [ ] **运行实现**\n- [ ] **生成比特流**\n\n### **8.2. 编程FPGA**\n\n- [ ] **通过JTAG连接**您的FPGA设备。\n- [ ] **打开硬件管理器**。\n- [ ] **使用生成的比特流编程设备**。\n\n---\n\n## **9. 测试与验证**\n\n### **9.1. 验证设备枚举**\n\n- [ ] **检查**FPGA是否在主机系统上显示为捐赠设备。\n\n### **9.2. 安装必要的驱动程序**\n\n- [ ] **使用**捐赠设备的驱动程序（如果需要）。\n\n### **9.3. 执行功能测试**\n\n- [ ] **测试**捐赠设备预期的所有功能。\n\n### **9.4. 监控错误**\n\n- [ ] **检查**系统日志中与设备相关的任何错误或警告。\n\n---\n\n## **10. 根据需要调试和优化**\n\n### **10.1. 使用集成逻辑分析器（ILA）**\n\n- [ ] **插入**ILA核以监控内部信号（如果必要）。\n\n### **10.2. 分析PCIe流量**\n\n- [ ] **使用**PCIe协议分析仪，调试通信问题。\n\n### **10.3. 精炼固件**\n\n- [ ] **迭代**您的固件代码，修复错误并提高性能。\n"
  },
  {
    "path": "CN/版本 4.md",
    "content": "# **第一部分：基础概念**\n\n## **1. 引言**\n\n### **1.1 本指南的目的**\n\n本指南概述了一条详细的路线图，用于在基于 FPGA 的设备上创建自定义的直接内存访问 (DMA) 固件，最终目标是精确地仿真 PCIe 硬件。这种仿真可用于以下广泛应用场景：\n\n- **硬件开发与测试**  \n  - 使用基于 FPGA 的仿真来复制在开发过程中所需的各类硬件设备。  \n  - 在无需昂贵或受限于特定捐赠硬件的情况下，进行系统级测试。\n\n- **系统调试与诊断**  \n  - 在可控环境中重现复杂的硬件行为，以便查找驱动程序相关的 bug 或问题。  \n  - 在交易层 (TLP) 或内存映射 I/O 级别进行追踪分析。\n\n- **安全与恶意软件研究**  \n  - 调查 PCIe 低级漏洞或与硬件直接交互的高级恶意软件。  \n  - 当硬件签名部分或全部被伪造时，观察特定设备驱动程序的行为。\n\n- **硬件仿真与旧版支持**  \n  - 用 FPGA 解决方案替代老化的硬件，通过仿真捐赠设备的 PCIe ID、BAR 布局和中断。  \n  - 在新系统上通过仿真较旧或停产的 PCIe 设备来保持传统工作流程。\n\n通过阅读本指南，你将学会如何：\n1. **收集** 实体“捐赠” PCIe 卡的必要设备信息。  \n2. **定制** FPGA 固件，使其呈现相同的设备/厂商 ID、BAR 布局和功能。  \n3. **构建与配置** 开发环境（如 Xilinx Vivado、Visual Studio Code 等）。  \n4. **理解** PCIe 与 DMA 的基本原理，这对于可靠的设备仿真至关重要。\n\n> **为何这很重要**  \n> 适当的硬件仿真可以节省工作量、降低成本，并允许快速迭代。基于 FPGA 的卡可以随时重新编程，从而让你比固定硬件更容易地适应多种设备或固件变体。\n\n---\n\n### **1.2 目标受众**\n\n本资源适用于广泛的专业人士和爱好者：\n\n- **固件开发人员**  \n  对操控低级系统交互、驱动程序设计或高级硬件/固件栈调试感兴趣。\n\n- **硬件与验证工程师**  \n  寻求一种可控方式来测试具有多种设备配置和条件的系统组件——而无需每次都更换 PCIe 卡。\n\n- **安全研究人员**  \n  专注于分析 DMA 引入的威胁向量，探索 PCIe 交互中的潜在漏洞，或对恶意代码进行安全沙箱仿真。\n\n- **FPGA 爱好者与创客**  \n  渴望通过构建自定义 PCIe 核、学习高级硬件描述语言及探索实际设备枚举来扩展他们的 FPGA 知识。\n\n---\n\n### **1.3 如何使用本指南**\n\n本指南分为三个部分，每个部分都在前一部分的基础上进一步深入：\n\n1. **第一部分：基础概念**  \n   - 涵盖先决知识、环境设置、提取捐赠设备数据以及初步固件调整。\n2. **第二部分：中级概念与实现**  \n   - 深入讨论固件定制、TLP 级别的操作、调试策略，以及如何细化仿真设备的行为以匹配或超越捐赠设备的功能。\n3. **第三部分：高级技术与优化**  \n   - 探讨深入的调试工具、性能调优和最佳实践，以确保你的基于 FPGA 的 DMA 解决方案具有长期可维护性。\n\n> **建议**：在进入下一部分之前，请彻底完成第一部分。跳过或部分实施这些基础步骤可能会导致后续阶段中的混乱或配置错误。\n\n---\n\n## **2. 关键定义**\n\n精确定义术语对于成功进行基于 FPGA 的 PCIe 仿真至关重要。下列列表详细解释了各相关术语：\n\n1. **DMA (直接内存访问)**  \n   - **定义**：无需 CPU 干预，由硬件直接在设备与系统内存之间传输数据。  \n   - **相关性**：仿真设备高度依赖 DMA 以达到高吞吐量。确保正确配置 DMA 对于功能正常的 FPGA 设计至关重要。\n\n2. **TLP (交易层数据包)**  \n   - **定义**：PCIe 中的基本通信单元，封装了头部信息和数据有效载荷。  \n   - **相关性**：理解 TLP 结构对于修改或分析 PCIe 交易层数据十分关键。\n\n3. **BAR (基地址寄存器)**  \n   - **定义**：寄存器，用于指定设备资源在系统地址空间中显示的地址范围（内存或 I/O）。  \n   - **相关性**：准确复制捐赠设备的 BAR 布局是确保驱动程序正确加载和内存映射 I/O 处理的关键。\n\n4. **FPGA (现场可编程门阵列)**  \n   - **定义**：一种可重构芯片，其内部电路可以通过 HDL 重新设计，以实现定制硬件逻辑。  \n   - **相关性**：FPGA 使你可以快速迭代 PCIe 设备设计，通过最小的硬件更改便可切换仿真设备。\n\n5. **MSI/MSI-X (消息信号中断)**  \n   - **定义**：符合 PCIe 标准的中断方法，允许设备通过带内消息而非专用线路触发 CPU 中断。  \n   - **相关性**：复制捐赠中断行为（特别是支持的 MSI 向量数量）对于预期使用特定中断机制的驱动程序至关重要。\n\n6. **设备序列号 (DSN)**  \n   - **定义**：某些 PCIe 设备用于许可、认证或高级驱动程序校验的 64 位唯一标识符。  \n   - **相关性**：若捐赠设备依赖 DSN，一些驱动程序可能会拒绝加载或运行，除非 DSN 匹配预期的硬件。\n\n7. **PCIe 配置空间**  \n   - **定义**：定义的区域（PCI 为 256 字节，PCIe 扩展为 4 KB），详细列出了设备 ID、厂商 ID、功能和操作参数。  \n   - **相关性**：确保 FPGA 设备的配置空间与捐赠设备完全一致（或包含正确的子集）对于让主机将其视为真实设备至关重要。\n\n8. **捐赠设备**  \n   - **定义**：你从中提取数据（如 ID、类代码等）以进行仿真的实际 PCIe 卡。  \n   - **相关性**：你复制的数据越准确，你的 FPGA 在枚举和功能上就越能接近真实硬件。\n\n---\n\n## **3. 设备兼容性**\n\n### **3.1 支持的基于 FPGA 的硬件**\n\n1. **Squirrel (35T)**  \n   - 基于 Artix-7 的性价比较高的 FPGA 板，支持基本的 DMA 操作。推荐给刚接触基于 FPGA 的 PCIe 开发的用户。\n\n2. **Enigma-X1 (75T)**  \n   - 提供比 35T 更多的逻辑资源（LUTs、块 RAM），适用于中等复杂度任务或扩展调试/追踪功能。\n\n3. **ZDMA (100T)**  \n   - 针对高性能应用，具备大量 FPGA 资源，适合密集数据传输或多个并发 DMA 通道。\n\n4. **Kintex-7**  \n   - 一个更高级的 FPGA 系列，具备先进的 PCIe IP 核，通常用于要求高或大规模仿真任务。\n\n> **提示**：始终检查你的 FPGA 卡的具体通道配置（x1、x4、x8）和速度等级（Gen1、Gen2 等），确保它满足或超过主板支持的要求。\n\n---\n\n### **3.2 PCIe 硬件考虑因素**\n\n- **IOMMU / VT-d**  \n  - *建议*：为了避免 DMA 区域受限，建议暂时禁用，尤其是在需要完全内存访问以进行充分测试时。\n\n- **内核 DMA 保护**  \n  - *Windows VBS / Secure Boot*：在某些情况下，这些功能会截获或限制直接的 PCIe 内存映射。  \n  - *Linux IOMMU 或 AppArmor/SELinux 规则*：请根据需要调整，以确保 FPGA 能够访问仿真所需的内存区域。\n\n- **PCIe 插槽要求**  \n  - 选择物理 PCIe 插槽时，确保有足够的通道，并确认 BIOS 已正确分配通道。  \n  - 如果发现性能问题或部分枚举，请确认系统没有将较大插槽强制为 x1 操作。\n\n---\n\n### **3.3 系统要求**\n\n1. **硬件**  \n   - **CPU**：至少需要四核 Intel 或 AMD，以便顺畅运行 Vivado 综合和管理操作系统开销。  \n   - **内存**：建议 16 GB 或更多，以便在多小时的综合运行中获得舒适体验。  \n   - **存储**：建议 100 GB SSD 以加快项目构建；机械硬盘可能会大幅降低构建速度。  \n   - **操作系统**：支持 Windows 10/11（64 位）或主流 Linux 发行版（例如 Ubuntu LTS、RHEL/CentOS），用于运行 Xilinx Vivado。\n\n2. **外设设备**  \n   - **JTAG 编程器**：  \n     - 如 Xilinx Platform Cable USB II、Digilent HS3 或类似设备，用于将生成的比特流下载到 FPGA 上，或在实时调试固件时使用。  \n   - **专用机器**：  \n     - 强烈建议使用专用测试机（或精心配置的双启动/虚拟机）以便在修改 BIOS 设置（如 VT-d）或需要一个无其他 PCIe 设备干扰的环境时使用。\n\n---\n\n## **4. 需求**\n\n### **4.1 硬件**\n\n1. **捐赠 PCIe 设备**  \n   - 目的：你需要提取设备的厂商/设备 ID、子系统 ID、类代码、BAR 大小和功能。  \n   - 示例：旧款网络接口卡（NIC）、基本存储控制器，或其他你希望复制或扩展的专用 PCIe 设备。\n\n2. **DMA FPGA 卡**  \n   - 目的：运行 FPGA 逻辑、实现 PCIe 接口的实际硬件平台。  \n   - 示例：Squirrel 35T、Enigma-X1 或 ZDMA 100T 板。\n\n3. **JTAG 编程器**  \n   - 用于连接 FPGA 板上的 JTAG 引脚，便于使用 Vivado 加载综合生成的比特流或实时调试固件。\n\n---\n\n### **4.2 软件**\n\n1. **Xilinx Vivado 设计套件**  \n   - 用于创建、综合和实现 FPGA 设计。  \n   - 请从 [Xilinx](https://www.xilinx.com/support/download.html) 下载，确保选择与你的板卡 IP 要求相符的版本。\n\n2. **Visual Studio Code**  \n   - 一个灵活的跨平台编辑器，支持 Verilog/SystemVerilog，并有额外插件。  \n   - 帮助保持一致的代码风格，追踪变更，并通过版本控制（如 Git）简化协作。\n\n3. **PCILeech-FPGA**  \n   - GitHub 仓库：[PCILeech-FPGA](https://github.com/ufrisk/pcileech-fpga)。  \n   - 提供针对各 FPGA 板的基本 DMA 设计，你可以在此基础上进行定制，以复制捐赠设备的 PCIe 配置。\n\n4. **Arbor（PCIe 设备扫描工具）**  \n   - 一个用户友好的 GUI 工具，可对已连接的 PCIe 设备进行详细分析。  \n   - 替代方案：Telescan PE 用于流量捕获，或者在 Linux 中使用命令行工具 `lspci -vvv` 进行检查。\n\n---\n\n### **4.3 环境设置**\n\n1. **安装 Vivado**  \n   - 按照 Xilinx 官方安装程序进行安装，选择相应的 FPGA 系列（Artix-7、Kintex-7 等）。  \n   - 可能需要注册 Xilinx 账户以下载设计套件或获取更新。\n\n2. **安装 Visual Studio Code**  \n   - 从 [Visual Studio Code](https://code.visualstudio.com/) 下载。  \n   - 安装推荐插件：*Verilog-HDL/SystemVerilog* 和 *Git* 集成插件（若你计划使用版本控制）。\n\n3. **克隆 PCILeech-FPGA 仓库**  \n   ```bash\n   cd ~/Projects/\n   git clone https://github.com/ufrisk/pcileech-fpga.git\n   cd pcileech-fpga\n   ```\n   - 确保你已安装并配置 Git。\n\n4. **隔离开发环境**  \n   - 建议使用专用测试机（或经过精心配置的双启动/虚拟机），以减少风险。  \n   - 这种方式允许你更自由地禁用内核 DMA 保护、IOMMU 或安全启动，而不会影响主要生产系统。\n\n---\n\n## **5. 收集捐赠设备信息**\n\n要有效地仿真设备，必须复制其 PCIe 配置空间。这意味着需要捕获从设备/厂商 ID 到高级功能的所有信息。\n\n### **5.1 使用 Arbor 进行 PCIe 设备扫描**\n\n#### **5.1.1 安装并启动 Arbor**\n\n1. **获取 Arbor**  \n   - 在 Arbor 官方网站注册并下载。  \n   - 以管理员权限安装。\n\n2. **启动 Arbor**  \n   - 如果 Windows 的 UAC 提示，请确认允许该应用以管理员权限运行。  \n   - 你应看到一个列出所有 PCI/PCIe 设备的界面。\n\n#### **5.1.2 扫描设备**\n\n1. **本地系统标签**  \n   - 导航至 Arbor 的“Local System”或“Scan”区域。  \n2. **点击“Scan”**  \n   - Arbor 将枚举所有 PCIe 总线上的设备。  \n3. **识别捐赠设备**  \n   - 根据品牌名称或厂商 ID 与已知的捐赠硬件相匹配。如果不易识别，请参照硬件文档中的已知 ID 进行比对。\n\n#### **5.1.3 提取关键属性**\n\n从 Arbor 的详细视图中收集以下信息：\n\n- **厂商 ID / 设备 ID**：例如，0x8086 / 0x10D3（Intel NIC）。  \n- **子系统厂商 ID / 子系统 ID**：例如，0x8086 / 0xA02F。  \n- **修订版本 ID**：例如，0x01。  \n- **类代码**：例如，0x020000（用于以太网控制器）。  \n- **BARs (基地址寄存器)**：  \n  - 对于每个 BAR，注意其是否启用、内存大小（256 MB、64 KB 等）以及是否支持预取或是 32 位/64 位。  \n- **功能**：  \n  - MSI 或 MSI-X 详情（支持的中断向量数量）。  \n  - 扩展配置或高级电源管理功能。  \n- **设备序列号 (DSN)**（如有）：  \n  - 某些设备具有唯一 DSN 字段，特别是用于许可或特殊驱动检查时。\n\n> **组织提示**：  \n> 使用电子表格或结构化文档记录这些数值，确保你不会忽略高级功能或扩展功能等细节。\n\n---\n\n## **6. 初步固件定制**\n\n获取捐赠设备的 PCIe 属性后，开始定制 FPGA 固件以匹配这些设置。\n\n### **6.1 修改 PCIe 配置空间**\n\n你的 FPGA 设计中可能包含一个顶层文件，用于设置 PCIe 配置寄存器。例如，在 `pcileech-fpga` 仓库中，查找类似 `pcileech_pcie_cfg_a7.sv` 或 `pcie_7x_0_core_top.v` 的文件。\n\n1. **在 VS Code 中打开文件**  \n   - 搜索定义 `cfg_deviceid`、`cfg_vendorid`、`cfg_subsysid` 等的代码行。\n\n2. **赋予正确的 ID**  \n   ```verilog\n   cfg_deviceid        <= 16'h10D3; // 示例设备 ID\n   cfg_vendorid        <= 16'h8086; // 示例厂商 ID\n   cfg_subsysid        <= 16'h1234;\n   cfg_subsysvendorid  <= 16'h5678;\n   cfg_revisionid      <= 8'h01;\n   cfg_classcode       <= 24'h020000; // 例如以太网控制器\n   ```\n   - 将上述示例替换为从 Arbor（或捐赠设备数据手册）中获得的确切值。\n\n3. **如有需要，插入 DSN**  \n   ```verilog\n   cfg_dsn             <= 64'h0011223344556677;\n   ```\n   - 如果捐赠设备不依赖 DSN，则可省略或置为 0。\n\n4. **保存并检查**  \n   - 任一字段的单个数字错误都可能导致操作系统错误识别或拒绝该设备。请仔细核对每一行。\n\n---\n\n### **6.2 考虑 BAR 配置**\n\n虽然有些 PCIe IP 核会在相同的 SystemVerilog 文件中存储 BAR 设置，但也有些依赖于 Vivado 的 IP 定制 GUI：\n\n- **检查捐赠设备使用了多少个 BAR**（0 到 6 个）。  \n- **设置每个 BAR**（例如，内存类型、大小、是否支持预取、是 64 位还是 32 位）。  \n- 如果捐赠设备具有较大 BAR 区域（例如 256 MB 或更大），请确保你的 FPGA 板卡在 IP 核设置中可以容纳。\n\n---\n\n## **7. Vivado 工程设置与定制**\n\n### **7.1 生成 Vivado 工程文件**\n\n为便于组织所有设计文件，许多仓库都包含 Tcl 脚本：\n\n1. **启动 Vivado**  \n   - 确保你使用的 Vivado 版本与 FPGA 系列（Artix-7、Kintex-7 等）匹配。\n\n2. **打开 Tcl 控制台**  \n   - 在 Vivado 顶部菜单中选择 **Window > Tcl Console**。\n\n3. **进入工程目录**  \n   ```tcl\n   cd C:/path/to/pcileech-fpga/pcileech-wifi-main/\n   pwd\n   ```\n   - 使用 `pwd` 命令确认控制台已进入正确的文件夹。\n\n4. **运行生成脚本**  \n   ```tcl\n   source vivado_generate_project_squirrel.tcl -notrace\n   ```\n   - 如果使用 Enigma-X1 或 ZDMA，请运行相应的脚本（例如 `vivado_generate_project_enigma_x1.tcl`）。\n\n5. **打开生成的工程**  \n   - 通过 **File > Open Project**，定位并选择 `.xpr` 文件（例如 `pcileech_squirrel_top.xpr`）。  \n   - 检查 **Project Manager** 窗口，确保所有源文件已正确导入。\n\n---\n\n### **7.2 定制 PCIe IP 核**\n\n在 Vivado 中，你可能会找到一个 PCIe IP 核（例如 `pcie_7x_0.xci`），位于 **Sources** 下：\n\n1. **右键点击 -> Customize IP**  \n   - 更新厂商/设备 ID、修订版本和子系统字段。  \n   - 按照捐赠设备的 BAR 配置（大小、内存类型等）进行匹配。\n\n2. **生成/更新 IP**  \n   - 点击 **OK** 或 **Generate** 以重建 IP 核。  \n   - 如果 IP 版本发生变化，Vivado 可能会提示升级或确认依赖项。\n\n3. **锁定 IP 核**  \n   ```tcl\n   set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n   ```\n   - 这可以防止将来脚本意外覆盖你的手动更改。\n\n---\n\n## **附加最佳实践**\n\n1. **版本控制** - *强烈推荐*  \n   - 经常提交你的修改（使用 Git 或其他版本控制系统）。  \n   - 对重大更改进行打标签或分支，以便在出现问题时能快速回退。\n\n2. **文档记录**  \n   - 保留笔记、电子表格或 Wiki，总结捐赠设备的详细信息、特殊偏移或功能缺陷。  \n   - 记录定制 FPGA 固件的每一步操作。\n\n3. **在主机上测试**  \n   - 生成比特流后，将其烧录到 FPGA，然后检查：  \n     - **Windows**：使用设备管理器或 `devcon.exe` 检查设备是否以正确的 ID 枚举。  \n     - **Linux**：使用 `lspci -vvv` 检查设备是否正确显示，包括 BAR、类代码、子系统等信息。\n\n4. **安全考虑**  \n   - 禁用 VT-d 或安全启动等功能可能会使系统面临安全风险。建议使用专用测试平台或将环境隔离，以确保操作安全。\n\n5. **接下来的内容**  \n   - 在 **第二部分** 中，你将学到如何基于这些基础知识进一步进行 TLP 操作、部分重配置策略、固件调试以及任何高级 ID 伪装或握手仿真。\n\n---\n\n# **第二部分：中级概念与实现**\n\n---\n\n## **8. 高级固件定制**\n\n为了精确仿真捐赠设备，你必须扩展基础配置，使高级 PCIe 参数、BAR 设置以及电源管理与中断机制完全与捐赠设备一致。这确保你的基于 FPGA 的仿真设备能与主机像真实硬件一样交互。\n\n---\n\n### **8.1 配置 PCIe 参数以实现仿真**\n\n精确的 PCIe 仿真要求设备的链路特性、功能指针以及数据传输参数（有效载荷和读请求大小）与捐赠设备一致。\n\n#### **8.1.1 匹配 PCIe 链路速度和宽度**\n\n**目的：**  \nPCIe 链路速度（例如，Gen1 为 2.5 GT/s，Gen2 为 5.0 GT/s，Gen3 为 8.0 GT/s）和链路宽度（例如，x1、x4、x8）直接影响性能与兼容性。必须复制捐赠设备的参数，确保主机系统和驱动程序能够无缝识别和操作仿真设备。\n\n**步骤：**\n\n1. **启动 Vivado 并打开工程**  \n   - 打开你的 Vivado 工程（例如 `pcileech_squirrel_top.xpr`），确认所有源文件均已导入，工程层次结构完整。\n\n2. **进入 PCIe IP 核设置**  \n   - 在 **Sources** 面板中找到 PCIe IP 核（通常命名为 `pcie_7x_0.xci`）。  \n   - 右键点击该文件，选择 **Customize IP** 以打开配置 GUI。\n\n3. **设置最大链路速度**  \n   - 导航至 **Link Parameters** 选项卡。  \n   - 找到“Maximum Link Speed”选项，并选择与捐赠设备匹配的速度（例如，对于 Gen2 选择 5.0 GT/s）。  \n   - *注意：* 验证 FPGA 板和物理插槽是否均支持所选速度。\n\n4. **配置链路宽度**  \n   - 在同一选项卡中，找到“Link Width”。  \n   - 选择适当的宽度（例如，x4）以匹配捐赠设备。  \n   - *注意：* 常见选项包括 1、2、4、8 或 16 条通道。\n\n5. **应用并重新生成**  \n   - 点击 **OK** 保存更改。Vivado 可能会提示你重新生成 IP 核，允许该过程完成。  \n   - 最后，在 **Messages** 窗口检查任何警告或错误信息。\n\n---\n\n#### **8.1.2 设置功能指针**\n\n**目的：**  \nPCIe 配置空间中的功能指针引导主机定位扩展功能（如 MSI/MSI‑X、电源管理等）。匹配这些指针可确保主机按照与捐赠设备相同的方式访问这些功能。\n\n**步骤：**\n\n1. **打开固件配置文件**  \n   - 在 Visual Studio Code 中，打开位于 `pcileech-fpga/pcileech-wifi-main/src/` 下的文件（例如 `pcileech_pcie_cfg_a7.sv`）。\n\n2. **查找并更新功能指针赋值**  \n   - 找到 `cfg_cap_pointer` 的赋值语句，例如：\n     ```verilog\n     cfg_cap_pointer <= 8'hXX; // 当前默认值\n     ```\n   - 将 `XX` 替换为正确的捐赠设备偏移（例如，如果捐赠设备的功能指针在 0x60 处，则写为 `8'h60`）：\n     ```verilog\n     cfg_cap_pointer <= 8'h60; // 设置为捐赠设备在 0x60 偏移处的功能指针\n     ```\n   - *验证：* 确保功能结构按照 PCIe 要求对齐到 4 字节边界。\n\n3. **保存文件并添加注释说明更改**  \n   - 保存文件（Ctrl+S），并在代码中添加内联注释以备将来参考。\n\n---\n\n#### **8.1.3 调整最大有效载荷和读请求大小**\n\n**目的：**  \nPCIe 设备在交易中协商每个传输的数据量。“最大有效载荷大小”（MPS）和“最大读请求大小”（MRRS）必须设置为与捐赠设备一致，以确保驱动程序兼容性和最佳数据吞吐量。\n\n**步骤：**\n\n1. **在 PCIe IP 核中配置**  \n   - 在 IP 定制 GUI 中（位于 PCIe IP 核设置中），导航至 **Device Capabilities** 或 **Capabilities** 选项卡。  \n   - 设置 **Maximum Payload Size Supported**（例如 256 字节）和 **Maximum Read Request Size Supported**（例如 512 字节），使其与捐赠设备一致。\n\n2. **更新固件常量**  \n   - 在 Visual Studio Code 中打开 `pcileech_pcie_cfg_a7.sv`。  \n   - 查找定义有效载荷和读请求大小的参数，例如：\n     ```verilog\n     max_payload_size_supported       <= 3'bZZZ; // 当前值\n     max_read_request_size_supported  <= 3'bWWW; // 当前值\n     ```\n   - 替换为正确的二进制编码：  \n     - **示例映射：**\n       - 128 字节: `3'b000`\n       - 256 字节: `3'b001`\n       - 512 字节: `3'b010`\n       - 1024 字节: `3'b011`\n       - 2048 字节: `3'b100`\n       - 4096 字节: `3'b101`\n     - 例如，如果捐赠设备支持 256 字节有效载荷和 512 字节读请求：\n       ```verilog\n       max_payload_size_supported       <= 3'b001; // 256 字节\n       max_read_request_size_supported  <= 3'b010; // 512 字节\n       ```\n\n3. **重新构建并验证**  \n   - 保存修改后重新运行综合，确保 IP 核设置与固件常量之间一致。\n\n---\n\n### **8.2 调整 BAR 与内存映射**\n\nBAR（基地址寄存器）决定了设备用于内存或 I/O 的地址空间。正确配置 BAR 对于驱动程序操作和操作系统资源分配至关重要。\n\n#### **8.2.1 设置 BAR 大小**\n\n**目的：**  \n确保每个 BAR 设置了正确的大小和类型（32 位与 64 位；内存与 I/O）以保证主机分配正确的地址空间。\n\n**步骤：**\n\n1. **在 PCIe IP 核中定制 BAR**  \n   - 在 Vivado 中，右键点击 `pcie_7x_0.xci`，选择 **Customize IP**。  \n   - 导航到 **BARs** 选项卡。  \n   - 对于每个 BAR（BAR0–BAR5）：  \n     - **设置大小：** 选择与捐赠设备相同的大小（例如 64 KB、128 MB）。  \n     - **设置类型：** 选择 32 位或 64 位内存寻址（或 I/O 空间）。  \n     - **启用或禁用：** 仅启用捐赠设备使用的 BAR。\n\n2. **与片上内存（如适用）同步**  \n   - 如果使用块 RAM（BRAM）来支持仿真 BAR 区域，请打开相关的 BRAM IP 核文件（例如 `bram_bar_zero4k.xci`），确保内存大小与 BAR 配置相对应。\n\n3. **保存、重新生成并验证**  \n   - 保存更改，让 Vivado 重新生成 IP 核。  \n   - 检查 **Messages** 窗口，确保无配置警告。\n\n---\n\n#### **8.2.2 在固件中定义 BAR 地址空间**\n\n**目的：**  \n实现逻辑，用以解码针对 BAR 的地址并正确路由读/写操作。\n\n**步骤：**\n\n1. **打开 BAR 控制器源文件**  \n   - 例如，在 Visual Studio Code 中打开 `pcileech_tlps128_bar_controller.sv`。\n\n2. **实现地址解码逻辑**  \n   - 使用组合逻辑确定访问的是哪个 BAR：\n     ```verilog\n     always_comb begin\n       if (bar_hit[0]) begin\n         // 处理对 BAR0 的访问\n       end else if (bar_hit[1]) begin\n         // 处理对 BAR1 的访问\n       end\n       // 根据需要继续处理其他 BAR\n     end\n     ```\n\n3. **为每个 BAR 实现读/写处理**  \n   - 在每个分支内，创建 case 语句或条件块，将特定地址偏移映射到内部寄存器：\n     ```verilog\n     if (bar_hit[0]) begin\n       case (addr_offset)\n         16'h0000: data_out <= reg0;\n         16'h0004: data_out <= reg1;\n         // 根据需要添加其他寄存器\n         default: data_out <= 32'h0;\n       endcase\n     end\n     ```\n\n4. **保存并仿真验证**  \n   - 保存更改后，进行仿真以验证地址解码与数据传输是否正确。\n\n---\n\n#### **8.2.3 处理多个 BAR**\n\n**目的：**  \n如果设备暴露多个 BAR，必须确保每个 BAR 的逻辑独立，并且它们的地址空间不冲突。\n\n**步骤：**\n\n1. **分离 BAR 逻辑**  \n   - 考虑将每个 BAR 的逻辑模块化，分离为不同的代码块或模块（例如 `bar0_controller.sv`、`bar1_controller.sv`）。\n\n2. **验证地址范围**  \n   - 确保每个 BAR 分配了唯一且不重叠的地址范围。  \n   - 确保大小符合 PCIe 规范中要求的幂次对齐。\n\n3. **测试**  \n   - 既使用测试平台仿真（测试基准）又使用硬件工具（如在 Linux 中用 `lspci -vvv` 或在 Windows 中使用设备管理器）验证映射与访问是否正确。\n\n---\n\n### **8.3 仿真设备的电源管理与中断**\n\n高级仿真需要支持设备电源管理状态和中断处理，这对于驱动程序的正常工作和系统稳定性至关重要。\n\n---\n\n#### **8.3.1 电源管理配置**\n\n**目的：**  \n启用电源管理功能使设备支持各种电源状态（D0 到 D3），这对提高能效及确保操作系统行为正常非常重要。\n\n**步骤：**\n\n1. **在 PCIe IP 核中启用电源管理**  \n   - 在 IP 定制窗口中，导航到 **Capabilities** 选项卡，并启用 “Power Management”。  \n   - 选择支持的电源状态（例如，D0 完全开启、D1/D2 中间状态，以及 D3 低功耗）。\n\n2. **在固件中实现 PMCSR 逻辑**  \n   - 在你的配置文件（例如 `pcileech_pcie_cfg_a7.sv`）中，实现处理电源管理控制/状态寄存器（PMCSR）写操作的逻辑：\n     ```verilog\n     localparam PMCSR_ADDRESS = 12'h44; // PMCSR 的示例地址\n     reg [15:0] pmcsr_reg;\n\n     always @(posedge clk) begin\n       if (cfg_write && cfg_address == PMCSR_ADDRESS) begin\n         pmcsr_reg <= cfg_writedata[15:0];\n         // 根据 pmcsr_reg[1:0] 更新内部电源状态\n       end\n     end\n     ```\n   - *注意：* 如果进入低功耗状态，请根据需要更新设备操作行为。\n\n3. **测试实现**  \n   - 仿真电源状态转换，验证 PMCSR 是否按照预期运行。\n\n---\n\n#### **8.3.2 MSI/MSI-X 配置与设备“激活”行为**\n\n**理解“激活设备”：**  \n在固件术语中，“激活设备”指的是那些定期发起 DMA 传输并在传输完成时通过中断通知主机的设备。这里的“激活”并非泛指激活状态，而是指设备主动“敲门”通知 CPU 数据已就绪。在高效中断信号传递要求较高的系统中，这一概念至关重要。\n\n**MSI 与 MSI-X：**  \n- **MSI：** 使用 Xilinx PCIe IP 核提供的内置中断接口。  \n- **MSI-X：** 由于内置接口不原生支持 MSI-X，固件需要手动构造并发送一个 MEMWR64 TLP 作为“门铃”中断。\n\n**使用 MSI（基于内置接口）的步骤：**\n\n1. **在 PCIe IP 核中配置 MSI**  \n   - 在 IP 核定制中，找到 **Interrupt** 或 **MSI/MSI-X** 部分。  \n   - 启用 MSI 并设置支持的向量数量（通常最多 32 个）。\n\n2. **在固件中实现中断接口**  \n   - 在配置文件中，将中断信号连接如下：\n     ```verilog\n     assign ctx.cfg_interrupt_di             = cfg_int_di;\n     assign ctx.cfg_pciecap_interrupt_msgnum = cfg_msg_num;\n     assign ctx.cfg_interrupt_assert         = cfg_int_assert;\n     assign ctx.cfg_interrupt                = cfg_int_valid;\n     assign ctx.cfg_interrupt_stat           = cfg_int_stat;\n     ```\n   - 然后，添加一个进程，当事件发生（例如 DMA 完成）时断言 `cfg_int_valid`：\n     ```verilog\n     always @(posedge clk_pcie) begin\n       if (rst) begin\n         cfg_int_valid <= 1'b0;\n         cfg_msg_num   <= 5'b0;\n         cfg_int_assert<= 1'b0;\n         cfg_int_di    <= 8'b0;\n         cfg_int_stat  <= 1'b0;\n       end else if (cfg_int_ready && cfg_int_valid) begin\n         cfg_int_valid <= 1'b0;\n       end else if (o_int) begin\n         cfg_int_valid <= 1'b0; // 根据中断生成时序进行调整\n       end\n     end\n\n     // 示例：中断计数器，用于生成周期性中断：\n     reg [31:0] int_cnt;\n     always @(posedge clk_pcie) begin\n       if (rst)\n         int_cnt <= 0;\n       else if (int_cnt == 32'd100000)\n         int_cnt <= 0;\n       else if (int_enable)\n         int_cnt <= int_cnt + 1;\n     end\n     assign o_int = (int_cnt == 32'd100000);\n     ```\n\n**使用 MSI-X（手动构造 TLP）的步骤：**\n\n1. **手动构造 MSI-X TLP**  \n   - 由于 Xilinx IP 核中断接口不支持 MSI-X，你必须构造一个 MEMWR64 TLP 以信号中断。  \n   - 定义 TLP 字段如下（根据捐赠设备的规格适当修改）：\n     ```verilog\n     // 定义 MEMWR64 TLP 的头部字段\n     wire [31:0] HDR_MEMWR64 = 32'b01000000_00000000_00000000_00000001;\n     // 构造后续数据字（注意位拼接正确）：\n     wire [31:0] MWR64_DW2   = { _bs16(pcie_id), 8'b0, 8'b00001111 };\n     wire [31:0] MWR64_DW3   = { i_addr[31:2], 2'b0 };\n     wire [31:0] MWR64_DW4   = i_data;\n     ```\n\n2. **与 TLP 输出集成**  \n   - 在你的 TLP 发送逻辑中（例如 `pcileech_pcie_tlp_a7.sv` 内），将构造的 TLP 分配如下：\n     ```verilog\n     reg         msix_valid;\n     reg         msix_has_data;\n     reg [127:0] msix_tlp;\n\n     assign tlps_static.tdata   = msix_tlp;\n     assign tlps_static.tkeepdw = 4'hF;\n     assign tlps_static.tlast   = 1'b1;\n     assign tlps_static.tuser[0]= 1'b1;\n     assign tlps_static.tvalid  = msix_valid;\n     assign tlps_static.has_data= msix_has_data;\n\n     always @(posedge clk_pcie) begin\n       if (rst) begin\n         msix_valid    <= 1'b0;\n         msix_has_data <= 1'b0;\n         msix_tlp      <= 128'b0;\n       end else if (msix_valid) begin\n         msix_valid <= 1'b0;\n       end else if (msix_has_data && tlps_static.tready) begin\n         msix_valid    <= 1'b1;\n         msix_has_data <= 1'b0;\n         msix_tlp      <= { MWR64_DW4, MWR64_DW3, MWR64_DW2, HDR_MEMWR64 };\n       end else if (o_int) begin\n         msix_has_data <= 1'b1;\n       end\n     end\n     // 如有需要，使用类似的中断计数器以生成周期性中断。\n     ```\n   - *验证：* 确保组装的 TLP 符合 PCIe 对 MEMWR64 数据包的规格要求。建议使用仿真和集成逻辑分析器（ILA）进行硬件测试。\n\n---\n\n#### **8.3 实现中断处理逻辑**\n\n**目的：**  \n定义明确的条件和专用模块，用于在满足特定事件（例如 DMA 传输完成）时生成中断。这对于一个“激活”设备（频繁向主机发起“门铃”通知）至关重要。\n\n**步骤：**\n\n1. **定义中断触发条件**  \n   - 确定哪些事件应生成中断，可能包括：  \n     - DMA 传输完成。  \n     - 数据就绪。  \n     - 错误状态等。\n   - 实现组合或时序逻辑检测这些事件。\n\n2. **模块化中断控制器**  \n   - 建议将中断逻辑封装在一个独立模块中，例如：\n     ```verilog\n     module interrupt_controller(\n       input  wire clk,\n       input  wire rst,\n       input  wire event_trigger,\n       output reg  msi_req\n     );\n       always @(posedge clk or posedge rst) begin\n         if (rst)\n           msi_req <= 1'b0;\n         else if (event_trigger)\n           msi_req <= 1'b1;\n         else\n           msi_req <= 1'b0;\n       end\n     endmodule\n     ```\n   - 将该模块集成到你的主固件逻辑中。\n\n3. **确保正确时序**  \n   - 验证中断信号的断言与撤销是否符合 PCIe 的时序要求。  \n   - 使用仿真和硬件调试工具（例如 ILA）确认主机能够正确接收中断信号。\n\n---\n\n### **8.4 “FULL EMU” 与 “DUMP EMU” 有何区别？**\n\n**术语理解：**\n\n- **DUMP EMU：**  \n  一种固件方法，其基本上“转储”了捐赠设备的 BAR 和功能寄存器（通常通过 Arbor 扫描获得）到 FPGA 中。该方法只复制静态配置数据。\n\n- **FULL EMU：**  \n  真正的全仿真不仅复制静态配置（ID、BAR、功能），而且仿真捐赠设备的动态行为，包括：  \n  - 正确生成 TLP（读取、写入、完成、厂商自定义消息）。  \n  - 处理电源管理状态转换。  \n  - 实现中断生成及正确的“门铃”通知（特别是在 MSI‑X 情况下）。  \n  - 支持主动 DMA 传输与实时响应，与捐赠设备完全一致。\n\n**未来改进：**  \n计划中的更新可能包括检测方法，以验证固件项目是真正的“FULL EMU”（具有主动动态行为）还是仅为静态的“DUMP EMU”。例如，可以使用基于 Realtek 的网卡进行高级测试作为基准。\n\n---\n\n## **10. 交易层数据包 (TLP) 仿真**\n\nTLP 是 PCIe 通信的基本单元。为了实现完全功能的仿真，你的设计不仅要复制配置空间，还必须准确地生成和响应 TLP，就像真实设备一样。\n\n### **10.1 理解并捕获 TLP**\n\n#### **10.1.1 学习 TLP 结构**\n\n- **头部：**  \n  包含字段如：  \n  - TLP 类型（例如内存读取、内存写入、配置、厂商自定义）  \n  - 长度、请求者 ID、标签、地址  \n- **数据有效载荷：**  \n  存在于如内存写入等交易中。必须遵循协商的最大有效载荷大小。  \n- **CRC：**  \n  用于数据完整性校验。\n\n#### **10.1.2 捕获捐赠设备的 TLP**\n\n1. **使用 PCIe 协议分析仪**  \n   - 使用 Teledyne LeCroy 分析仪或 Xilinx ILA 方案捕获实时 TLP。\n2. **捕获并分析交易**  \n   - 监控正常操作期间的 TLP，记录头部字段、顺序和时序。\n3. **记录关键交易**  \n   - 重点关注初始化序列、内存读写交换以及厂商自定义消息。\n\n---\n\n### **10.2 针对特定操作构造自定义 TLP**\n\n#### **10.2.1 在固件中实现 TLP 处理**\n\n1. **TLP 生成函数**  \n   - 在你的 TLP 模块（例如 `pcileech_pcie_tlp_a7.sv`）中，创建函数以组装 TLP。例如：\n     ```verilog\n     function automatic [127:0] generate_tlp(\n       input [15:0] requester_id,\n       input [7:0]  tag,\n       input [7:0]  length,\n       input [31:0] address,\n       input [31:0] data\n     );\n       // 构造并返回一个包含头部和载荷的 128 位 TLP\n     endfunction\n     ```\n2. **TLP 接收与解析**  \n   - 实现状态机以解析传入的 TLP，并根据类型（例如区分内存读与写）进行路由。\n\n3. **完成处理**  \n   - 对于内存读请求，生成包含请求数据的完成 TLP，确保遵守 PCIe 的时序和 CRC 要求。\n\n---\n\n#### **10.2.2 处理不同类型的 TLP**\n\n1. **内存读请求：**  \n   - 解析 TLP 头部，从正确的内存区域读取数据，并发送完成 TLP。\n2. **内存写请求：**  \n   - 提取数据有效载荷，并将数据写入仿真寄存器或内存块。\n3. **配置读/写：**  \n   - 分别访问配置空间寄存器。\n4. **厂商自定义消息：**  \n   - 如果捐赠设备使用专有 TLP，实现特殊处理。\n\n---\n\n#### **10.2.3 验证 TLP 的时序和顺序**\n\n1. **仿真测试：**  \n   - 开发测试平台仿真 TLP 交换，并验证头部、载荷以及响应时序的正确性。\n2. **硬件调试：**  \n   - 使用 ILA 核实时监控 TLP 总线信号。\n3. **合规性验证：**  \n   - 如有可能，使用 PCIe 合规性工具验证你的 TLP 实现是否符合规范。\n\n---\n\n## **结论**\n\n通过遵循第二部分中的详细步骤，你不仅扩展了对静态寄存器复制的仿真，还配置了关键的 PCIe 链路参数，确保正确的 BAR 和内存映射，实现了完整的电源管理以及同时支持 MSI 与 MSI‑X 中断。此外，你已经建立了一个基础，能够构造和验证自定义 TLP，从而实现一个真正“FULL EMU”的固件解决方案——其动态行为与捐赠设备完全一致。\n\n**关键要点：**\n\n1. **精确匹配高级 PCIe 参数：**  \n   - 链路速度、链路宽度、功能指针和有效载荷大小必须与捐赠设备一致。\n\n2. **BAR 配置与地址解码：**  \n   - 正确设置 BAR 的大小与类型，并实现健壮的地址解码逻辑。\n\n3. **中断 – MSI 与 MSI‑X：**  \n   - 对于 MSI 使用内置中断接口；对于 MSI‑X 则需手动构造 MEMWR64 TLP。\n\n4. **主动设备行为：**  \n   - 通过仿真频繁的 DMA 传输和“门铃”中断信号，模仿真实硬件的动态行为。\n\n5. **TLP 仿真：**  \n   - 确保 TLP 的生成、接收和时序完全符合 PCIe 标准，实现完整仿真。\n\n在 **第三部分** 中，我们将以此为基础，进一步讨论性能优化、深入调试技巧以及生产级最佳实践。请继续根据捐赠设备的规格验证每个功能，以实现真正难以区分的仿真效果。\n\n---\n\n# **第三部分：高级技术与优化**\n\n*（第三部分内容将在后续详细介绍，包括性能优化、扩展调试方法以及长远维护的最佳实践。）*\n"
  },
  {
    "path": "Checklist.md",
    "content": "# Firmware Modification Checklist\n\nUse this checklist to guide you through the firmware creation.\n\n---\n\n## **1. Gather Donor Device Information**\n\nCollect the following information from the donor PCIe device:\n\n- [ ] **Device ID** (`0xXXXX`)\n- [ ] **Vendor ID** (`0xYYYY`)\n- [ ] **Subsystem ID** (`0xZZZZ`)\n- [ ] **Subsystem Vendor ID** (`0xWWWW`)\n- [ ] **Revision ID** (`0xRR`)\n- [ ] **Class Code** (`0xCCCCCC`)\n- [ ] **Base Address Registers (BARs) Configuration**:\n  - [ ] **BAR0** to **BAR5** sizes, types (Memory or I/O), prefetchable status\n- [ ] **Capabilities**:\n  - [ ] Power Management settings\n  - [ ] MSI/MSI-X settings\n- [ ] **Device Serial Number (DSN)** (`0xXXXXXXXXYYYYYYYY`)\n\n---\n\n## **2. Modify Firmware Configuration Files**\n\n### **2.1. Open Firmware Configuration File**\n\n### **2.2. Update Device and Vendor IDs**\n\n- [ ] **Modify** `cfg_deviceid`:\n\n  ```verilog\n  cfg_deviceid <= 16'hXXXX;  // Replace XXXX with donor's Device ID\n  ```\n\n- [ ] **Modify** `cfg_vendorid`:\n\n  ```verilog\n  cfg_vendorid <= 16'hYYYY;  // Replace YYYY with donor's Vendor ID\n  ```\n\n### **2.3. Update Subsystem IDs and Revision ID**\n\n- [ ] **Modify** `cfg_subsysid`:\n\n  ```verilog\n  cfg_subsysid <= 16'hZZZZ;  // Replace ZZZZ with donor's Subsystem ID\n  ```\n\n- [ ] **Modify** `cfg_subsysvendorid`:\n\n  ```verilog\n  cfg_subsysvendorid <= 16'hWWWW;  // Replace WWWW with donor's Subsystem Vendor ID\n  ```\n\n- [ ] **Modify** `cfg_revisionid`:\n\n  ```verilog\n  cfg_revisionid <= 8'hRR;  // Replace RR with donor's Revision ID\n  ```\n\n### **2.4. Update Class Code**\n\n- [ ] **Modify** `cfg_classcode`:\n\n  ```verilog\n  cfg_classcode <= 24'hCCCCCC;  // Replace CCCCCC with donor's Class Code\n  ```\n\n### **2.5. Insert Device Serial Number (DSN)**\n\n- [ ] **Modify** `cfg_dsn`:\n\n  ```verilog\n  cfg_dsn <= 64'hXXXXXXXXYYYYYYYY;  // Replace with donor's DSN\n  ```\n\n---\n\n## **3. Customize Vivado Project**\n\n### **3.1. Generate Vivado Project Files**\n\n- [ ] **Open Vivado** and run the appropriate Tcl script in the Tcl Console:\n\n  ```tcl\n  cd <project_directory>\n  source vivado_generate_project_<your_board>.tcl -notrace\n  ```\n\n  - Replace `<project_directory>` with your project path.\n  - Replace `<your_board>` with your FPGA board identifier (e.g., `squirrel`).\n\n### **3.2. Open Generated Project**\n\n- [ ] **File**: Open the generated `.xpr` project file in Vivado.\n\n---\n\n## **4. Modify PCIe IP Core**\n\n### **4.1. Open PCIe IP Core Configuration**\n\n- [ ] **File to Edit**: `pcie_7x_0.xci`\n- [ ] **Action**: Right-click and select **Customize IP**.\n\n### **4.2. Set Device Identifiers**\n\n- [ ] **Device ID**: Set to donor's Device ID.\n- [ ] **Vendor ID**: Set to donor's Vendor ID.\n- [ ] **Subsystem ID**: Set to donor's Subsystem ID.\n- [ ] **Subsystem Vendor ID**: Set to donor's Subsystem Vendor ID.\n- [ ] **Revision ID**: Set to donor's Revision ID.\n- [ ] **Class Code**: Set to donor's Class Code.\n\n### **4.3. Configure BARs**\n\nFor each BAR (BAR0 to BAR5):\n\n- [ ] **Enable/Disable**: Match donor device.\n- [ ] **Type**: Memory (32-bit or 64-bit) or I/O.\n- [ ] **Size**: Set to donor's BAR size.\n- [ ] **Prefetchable**: Match donor's setting.\n\n### **4.4. Match PCIe Link Parameters**\n\n- [ ] **Maximum Link Speed**: Set to match donor device (e.g., **Gen2**, **Gen3**).\n- [ ] **Link Width**: Set to match donor device (e.g., **x1**, **x4**).\n\n### **4.5. Configure Capabilities**\n\n- [ ] **Enable Power Management** if the donor device supports it.\n- [ ] **Enable MSI/MSI-X** if the donor device supports it.\n\n### **4.6. Apply Changes and Lock IP Core**\n\n- [ ] **Apply**: Click **OK** to save IP core settings.\n- [ ] **Lock IP Core**: In the Tcl Console, run:\n\n  ```tcl\n  set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n  ```\n\n---\n\n## **5. Adjust Firmware for Advanced Features**\n\n### **5.1. Update Capability Pointer**\n\n- [ ] **File to Edit**: `pcileech_pcie_cfg_a7.sv`\n- [ ] **Modify** `cfg_cap_pointer`:\n\n  ```verilog\n  cfg_cap_pointer <= 8'hXX;  // Replace XX with donor's capability pointer\n  ```\n\n### **5.2. Adjust Max Payload and Read Request Sizes**\n\n- [ ] **In PCIe IP Core**: Set **Max Payload Size** and **Max Read Request Size** to match donor device.\n\n- [ ] **In Firmware (`pcileech_pcie_cfg_a7.sv`)**:\n\n  ```verilog\n  max_payload_size_supported <= 3'bYYY;  // Binary value corresponding to donor's Max Payload Size\n  ```\n\n  - **Mapping**:\n\n    | Payload Size (Bytes) | Binary Value |\n    |----------------------|--------------|\n    | 128                  | `3'b000`     |\n    | 256                  | `3'b001`     |\n    | 512                  | `3'b010`     |\n    | 1024                 | `3'b011`     |\n    | 2048                 | `3'b100`     |\n    | 4096                 | `3'b101`     |\n\n### **5.3. Implement Power Management Logic**\n\n- [ ] **File to Edit**: `pcileech_pcie_cfg_a7.sv`\n- [ ] **Add Logic** to handle power state transitions if applicable.\n\n### **5.4. Implement MSI/MSI-X Interrupts**\n\n- [ ] **In PCIe IP Core**: Enable MSI or MSI-X capability and set the number of supported vectors.\n\n- [ ] **In Firmware (`pcileech_pcie_tlp_a7.sv`)**:\n\n  - [ ] **Add Interrupt Logic** to handle MSI/MSI-X interrupts.\n\n---\n\n## **6. Adjust BAR Handling in Firmware**\n\n### **6.1. Open BAR Controller File**\n\n- [ ] **File to Edit**: `pcileech_tlps128_bar_controller.sv`\n- [ ] **Location**: `pcileech-fpga/pcileech-wifi-main/src/pcileech_tlps128_bar_controller.sv`\n\n### **6.2. Update BAR Address Decoding**\n\n- [ ] **Modify** the address decoding logic to match the BAR sizes and addresses of the donor device.\n\n### **6.3. Implement BAR Access Logic**\n\nFor each enabled BAR:\n\n- [ ] **Implement Read/Write Handlers** corresponding to the BAR's purpose.\n\n---\n\n## **7. Implement TLP Handling**\n\n### **7.1. Open TLP Handling File**\n\n- [ ] **File to Edit**: `pcileech_pcie_tlp_a7.sv`\n\n### **7.2. Modify TLP Processing Logic**\n\n- [ ] **Implement** logic to handle specific TLP types required by the donor device:\n\n  - [ ] Memory Read Requests\n  - [ ] Memory Write Requests\n  - [ ] Configuration Read/Write Requests\n  - [ ] Vendor-Defined Messages\n\n### **7.3. Ensure TLP Compliance**\n\n- [ ] **Verify** that TLPs are correctly formatted according to PCIe specifications.\n\n---\n\n## **8. Build and Flash Firmware**\n\n### **8.1. Run Synthesis and Implementation**\n\nIn Vivado:\n\n- [ ] **Run Synthesis**\n- [ ] **Run Implementation**\n- [ ] **Generate Bitstream**\n\n### **8.2. Program the FPGA**\n\n- [ ] **Connect** your FPGA device via JTAG.\n- [ ] **Open Hardware Manager**.\n- [ ] **Program Device** with the generated bitstream.\n\n---\n\n## **9. Test and Validate**\n\n### **9.1. Verify Device Enumeration**\n\n- [ ] **Check** that the FPGA appears as the donor device on the host system.\n\n### **9.2. Install Necessary Drivers**\n\n- [ ] **Use** donor device drivers if required.\n\n### **9.3. Perform Functional Testing**\n\n- [ ] **Test** all functionalities expected from the donor device.\n\n### **9.4. Monitor for Errors**\n\n- [ ] **Check** system logs for any errors or warnings related to the device.\n\n---\n\n## **10. Debug and Optimize as Needed**\n\n### **10.1. Use Integrated Logic Analyzer (ILA)**\n\n- [ ] **Insert** ILA cores to monitor internal signals if necessary.\n\n### **10.2. Analyze PCIe Traffic**\n\n- [ ] **Use** PCIe protocol analyzers to debug communication issues.\n\n### **10.3. Refine Firmware**\n\n- [ ] **Iterate** on your firmware code to fix bugs and improve performance.\n"
  },
  {
    "path": "FW-Guide-v4.md",
    "content": "## Need DMA Equiptment? I recommend shopping with [DMAPolice.com](https://dmapolice.com/)\n\n# **Part 1: Foundational Concepts**\n\n## **1. Introduction**\n\n### **1.1 Purpose of the Guide**\n\nThis guide outlines a detailed roadmap for creating custom Direct Memory Access (DMA) firmware on FPGA-based devices, with the ultimate goal of accurately emulating PCIe hardware. Such emulation can serve a wide range of applications, including:\n\n- **Hardware Development & Testing**  \n  - Use FPGA-based emulation to replicate various hardware devices during development.  \n  - Run system-level tests without the expense or availability constraints of specific donor hardware.\n\n- **System Debugging & Diagnostics**  \n  - Reproduce complex hardware behaviors in a controlled environment to pinpoint bugs or driver-related issues.  \n  - Conduct trace analysis at the transaction layer (TLP) or memory-mapped I/O level.\n\n- **Security & Malware Research**  \n  - Investigate low-level PCIe vulnerabilities or advanced malware that interacts with hardware directly.  \n  - Observe how certain device drivers behave when hardware signatures are partially or fully spoofed.\n\n- **Hardware Emulation & Legacy Support**  \n  - Replace aging hardware with an FPGA-based solution that mimics the original device’s PCIe IDs, BARs, and interrupts.  \n  - Preserve legacy workflows on newer systems by emulating older or discontinued PCIe devices.\n\nBy following this guide, you will learn to:\n1. **Gather** essential device information from a physical “donor” PCIe card.  \n2. **Customize** FPGA firmware to present the same device/vendor IDs, BAR layouts, and capabilities.  \n3. **Build & Configure** your development environment (Xilinx Vivado, Visual Studio Code, etc.).  \n4. **Understand** the fundamentals of PCIe and DMA that are crucial to reliable device emulation.\n\n> **Why This Matters**  \n> Proper hardware emulation saves effort, reduces costs, and often allows for rapid iteration. FPGA-based cards can be reprogrammed on-the-fly, letting you adapt to multiple devices or firmware variations far more easily than with fixed hardware.\n\n---\n\n### **1.2 Target Audience**\n\nThis resource caters to a broad spectrum of professionals and enthusiasts:\n\n- **Firmware Developers**  \n  Interested in manipulating low-level system interactions, driver design, or advanced debugging of hardware/firmware stacks.\n\n- **Hardware & Validation Engineers**  \n  Seeking a controllable way to test system components with a wide variety of device profiles and conditions—without physically swapping PCIe cards every time.\n\n- **Security Researchers**  \n  Focused on analyzing the threat vectors introduced by DMA, exploring potential vulnerabilities in PCIe interactions, or performing safe sandbox emulations of malicious code.\n\n- **FPGA Hobbyists & Makers**  \n  Eager to expand their FPGA knowledge by building custom PCIe cores, learning advanced hardware description languages, and exploring real-world device enumeration.\n\n---\n\n### **1.3 How to Use This Guide**\n\nThe guide is split into three parts, each building on the last:\n\n1. **Part 1: Foundational Concepts**  \n   - Covers the prerequisite knowledge, environment setup, capturing donor device data, and making initial firmware adjustments.\n2. **Part 2: Intermediate Concepts and Implementation**  \n   - Delves into deeper firmware customization, TLP-level manipulations, debugging strategies, and how to refine an emulated device’s behavior to match or surpass its donor’s functionality.\n3. **Part 3: Advanced Techniques and Optimization**  \n   - Explores in-depth debugging tools, performance tuning, and best practices to ensure long-term maintainability of your FPGA-based DMA solutions.\n\n> **Recommendation**: Complete Part 1 thoroughly before moving on. Skipping or partially implementing these foundational steps can lead to confusion and misconfigurations in later stages.\n\n---\n\n## **2. Key Definitions**\n\nHaving precise terminology is crucial for success in FPGA-based PCIe emulation. The following list expands on each relevant term:\n\n1. **DMA (Direct Memory Access)**  \n   - **Definition**: Hardware-mediated transfers between devices and system memory without CPU intervention.  \n   - **Relevance**: Emulated devices heavily rely on DMA for throughput. Ensuring correct DMA configuration is central to a functional FPGA design.\n\n2. **TLP (Transaction Layer Packet)**  \n   - **Definition**: The fundamental communication unit in PCIe, encapsulating both header information and data payload.  \n   - **Relevance**: Understanding TLP structure is vital if you plan to modify or analyze data at the PCIe transaction layer.\n\n3. **BAR (Base Address Register)**  \n   - **Definition**: Registers specifying the address ranges (memory or I/O) where a PCIe device’s resources appear in the system address space.  \n   - **Relevance**: Accurately replicating a donor device’s BAR layout is key for correct driver loading and memory-mapped I/O handling.\n\n4. **FPGA (Field-Programmable Gate Array)**  \n   - **Definition**: A reconfigurable chip whose internal circuitry can be redesigned (via HDL) to implement custom hardware logic.  \n   - **Relevance**: FPGAs let you quickly iterate on PCIe device designs, swapping out emulated devices with minimal hardware changes.\n\n5. **MSI/MSI-X (Message Signaled Interrupts)**  \n   - **Definition**: PCIe-compliant interrupt methods allowing devices to trigger CPU interrupts through in-band messages rather than dedicated lines.  \n   - **Relevance**: Replicating donor interrupt behavior (especially the number of MSI vectors) can be critical for the driver that expects a specific interrupt mechanism.\n\n6. **Device Serial Number (DSN)**  \n   - **Definition**: A 64-bit unique identifier some PCIe devices use for licensing, authentication, or advanced driver checks.  \n   - **Relevance**: Some drivers refuse to load or function unless the DSN matches the expected hardware.\n\n7. **PCIe Configuration Space**  \n   - **Definition**: A defined region (256 bytes for PCI or 4 KB for PCIe extended) detailing device ID, vendor ID, capabilities, and operational parameters.  \n   - **Relevance**: Ensuring your FPGA device’s configuration space mirrors the donor’s (or includes the right subset) is essential to fool a host into treating it as the genuine article.\n\n8. **Donor Device**  \n   - **Definition**: The actual PCIe card from which you obtain data (IDs, class codes, etc.) for emulation.  \n   - **Relevance**: The more data you accurately replicate, the closer your FPGA will behave to the original hardware in enumerations and function.\n\n---\n\n## **3. Device Compatibility**\n\n### **3.1 Supported FPGA-Based Hardware**\n\n1. **Squirrel (35T)**  \n   - A cost-effective Artix-7–based FPGA board that supports basic DMA operations. Recommended if you’re new to FPGA-based PCIe development.\n\n2. **Enigma-X1 (75T)**  \n   - Offers more logic resources (LUTs, Block RAM) than a 35T, useful for moderate complexity tasks or extended debugging/tracing features.\n\n3. **ZDMA (100T)**  \n   - Targets higher performance applications with substantial FPGA resources for intensive data transfers or multiple concurrent DMA channels.\n\n4. **Kintex-7**  \n   - A robust, more premium FPGA family with advanced PCIe IP cores, typically used in demanding or large-scale emulation tasks.\n\n> **Tip**: Always check the specific lane configuration (x1, x4, x8) and speed rating (Gen1, Gen2, etc.) for your FPGA card, verifying it meets or exceeds what your host motherboard can support.\n\n### **3.2 PCIe Hardware Considerations**\n\n- **IOMMU / VT-d**  \n  - *Recommendation*: Temporarily disable to avoid restricted DMA regions, especially important if you need full memory access for thorough testing.\n\n- **Kernel DMA Protection**  \n  - *Windows VBS / Secure Boot*: In some cases, these features intercept or limit direct PCIe memory mapping.  \n  - *Linux IOMMU or AppArmor/SELinux rules*: Adjust accordingly to ensure the FPGA can access the memory ranges it needs for emulation.\n\n- **PCIe Slot Requirements**  \n  - Choose a physical PCIe slot with enough lanes and confirm the BIOS is set to allocate those lanes appropriately.  \n  - If you notice performance issues or partial enumeration, confirm your system is not forcing x1 operation on a physically larger slot.\n\n### **3.3 System Requirements**\n\n1. **Hardware**  \n   - **CPU**: At least a quad-core from Intel or AMD for smooth Vivado synthesis and to manage OS overhead.  \n   - **RAM**: 16 GB or more for comfortable Vivado usage, especially for multi-hour synthesis runs.  \n   - **Storage**: 100 GB of SSD space recommended for faster project builds; mechanical HDDs can slow the build process drastically.  \n   - **OS**: Windows 10/11 (64-bit) or a well-supported Linux distribution (e.g., Ubuntu LTS, RHEL/CentOS) to run Xilinx Vivado.\n\n2. **Peripheral Devices**  \n   - **JTAG Programmer**: (Xilinx Platform Cable USB II, Digilent HS3, or similar) needed to program your FPGA with the bitstream you create.  \n   - **Dedicated Machine**: Strongly suggested if you’re altering BIOS-level settings (VT-d) or require an environment free of unexpected conflicts with existing PCIe devices.\n\n---\n\n## **4. Requirements**\n\n### **4.1 Hardware**\n\n1. **Donor PCIe Device**  \n   - Purpose: You’ll extract the vendor/device ID, subsystem IDs, class code, BAR size, and capabilities.  \n   - Examples: An older network interface card (NIC), a basic storage controller, or even a specialized PCIe device that you want to replicate/extend.\n\n2. **DMA FPGA Card**  \n   - Purpose: The actual hardware platform that runs the FPGA logic implementing the PCIe interface.  \n   - Examples: Squirrel 35T, Enigma-X1, or ZDMA 100T boards.\n\n3. **JTAG Programmer**  \n   - Connects to the JTAG pins on your FPGA board, letting Vivado load the synthesized bitstream or debug firmware in real time.\n\n### **4.2 Software**\n\n1. **Xilinx Vivado Design Suite**  \n   - Required for creating, synthesizing, and implementing the FPGA design.  \n   - Download from [Xilinx](https://www.xilinx.com/support/download.html), ensuring you pick the correct version for your board’s IP requirements.\n\n2. **Visual Studio Code**  \n   - A flexible, cross-platform editor supporting Verilog/SystemVerilog with additional plugins.  \n   - Helps maintain consistent code style, track changes, and streamline collaboration with version control (Git).\n\n3. **PCILeech-FPGA**  \n   - GitHub repository: [PCILeech-FPGA](https://github.com/ufrisk/pcileech-fpga).  \n   - Offers baseline DMA designs for various FPGA boards, which you can further customize to replicate your donor device’s PCIe configuration.\n\n4. **Arbor** (PCIe Device Scanner)  \n   - A user-friendly GUI tool that provides in-depth analysis of connected PCIe devices.  \n   - Alternatives: Telescan PE for traffic capture, or `lspci -vvv` in Linux for command-line introspection.\n\n### **4.3 Environment Setup**\n\n1. **Installing Vivado**  \n   - Follow Xilinx’s official installer, selecting the appropriate FPGA family (Artix-7, Kintex-7, etc.).  \n   - A Xilinx account may be required to download the Design Suite or access updates.\n\n2. **Installing Visual Studio Code**  \n   - Download from [Visual Studio Code](https://code.visualstudio.com/).  \n   - Install recommended plugins: *Verilog-HDL/SystemVerilog* and a *Git* integration if you plan to maintain your project under source control.\n\n3. **Cloning PCILeech-FPGA**  \n   ```bash\n   cd ~/Projects/\n   git clone https://github.com/ufrisk/pcileech-fpga.git\n   cd pcileech-fpga\n   ```\n   - Ensure you have Git installed and configured.\n\n4. **Isolated Development Environment**  \n   - Consider using a dedicated test machine (or a carefully configured dual-boot/VM) to reduce risk.  \n   - This approach allows you to disable kernel DMA protections, IOMMU, or secure boot features more freely, without compromising a primary production system.\n\n---\n\n## **5. Gathering Donor Device Information**\n\nEmulating a device effectively requires replicating its PCIe configuration space. That means capturing everything from device/vendor IDs to advanced capabilities.\n\n### **5.1 Using Arbor for PCIe Device Scanning**\n\n#### **5.1.1 Install & Launch Arbor**\n\n1. **Obtain Arbor**  \n   - Register and download from the official Arbor site.  \n   - Install with administrator rights.\n\n2. **Start Arbor**  \n   - If prompted by UAC on Windows, confirm the application can run with elevated privileges.  \n   - You should see an interface listing PCI/PCIe devices.\n\n#### **5.1.2 Scan for Devices**\n\n1. **Local System Tab**  \n   - Navigate to the “Local System” or “Scan” area in Arbor.  \n2. **Click “Scan”**  \n   - Arbor enumerates all devices on your PCIe bus.  \n3. **Identify the Donor**  \n   - Match the brand name or vendor ID to your known donor hardware. If it’s not easily recognized, cross-reference with known IDs from hardware documentation.\n\n#### **5.1.3 Extract Key Attributes**\n\nCollect the following from Arbor’s detailed view:\n\n- **Vendor ID / Device ID**: e.g., 0x8086 / 0x10D3 (Intel NIC).  \n- **Subsystem Vendor ID / Subsystem ID**: e.g., 0x8086 / 0xA02F.  \n- **Revision ID**: e.g., 0x01.  \n- **Class Code**: e.g., 0x020000 for an Ethernet controller.  \n- **BARs (Base Address Registers)**:  \n  - For each BAR, note if it’s enabled, the memory size (256 MB, 64 KB, etc.), and whether it’s prefetchable or 32-bit/64-bit.  \n- **Capabilities**:  \n  - MSI or MSI-X details (number of interrupt vectors supported).  \n  - Extended configuration or advanced power management features.  \n- **Device Serial Number (DSN)** (if present):  \n  - Some devices have a unique DSN field, especially if used for licensing or special driver checks.\n\n> **Organization Tip**: Use a spreadsheet or structured document to save these values. This ensures you don’t overlook details like advanced features or extended capabilities.\n\n---\n\n## **6. Initial Firmware Customization**\n\nWith the donor’s PCIe attributes in hand, begin customizing your FPGA firmware to match those settings.\n\n### **6.1 Modifying the PCIe Configuration Space**\n\nYour FPGA design likely includes a top-level file that sets the PCIe configuration registers. For example, in the `pcileech-fpga` repository, look for a file such as `pcileech_pcie_cfg_a7.sv` or `pcie_7x_0_core_top.v`.\n\n1. **Open File in VS Code**  \n   - Search for lines defining `cfg_deviceid`, `cfg_vendorid`, `cfg_subsysid`, etc.\n\n2. **Assign the Correct IDs**  \n   ```verilog\n   cfg_deviceid        <= 16'h10D3; // Example device ID\n   cfg_vendorid        <= 16'h8086; // Example vendor ID\n   cfg_subsysid        <= 16'h1234;\n   cfg_subsysvendorid  <= 16'h5678;\n   cfg_revisionid      <= 8'h01;\n   cfg_classcode       <= 24'h020000; // Example for Ethernet\n   ```\n   - Replace these with the exact values from Arbor (or your donor’s datasheet).\n\n3. **Insert DSN If Needed**  \n   ```verilog\n   cfg_dsn             <= 64'h0011223344556677;\n   ```\n   - Omit or set to 0 if your donor device doesn’t rely on a DSN.\n\n4. **Save & Review**  \n   - A single-digit error in any field could cause the OS to misidentify or reject the device. Double-check each line.\n\n### **6.2 Consider BAR Configuration**\n\nWhile some PCIe IP cores store BAR settings in the same SystemVerilog file, others rely on Vivado’s IP customization GUI:\n\n- **Check how many BARs** your donor device uses (0 to 6).  \n- **Set each BAR** (e.g., memory type, size, prefetchable, 64-bit vs. 32-bit).  \n- If your donor has a large BAR region (e.g., 256 MB or bigger), ensure your FPGA board can accommodate it in the IP core settings.\n\n---\n\n## **7. Vivado Project Setup and Customization**\n\n### **7.1 Generating Vivado Project Files**\n\nTo organize all design files properly, many repositories include Tcl scripts:\n\n1. **Launch Vivado**  \n   - Confirm you are using the correct version for your FPGA series (Artix-7, Kintex-7, etc.).\n\n2. **Open Tcl Console**  \n   - **Window > Tcl Console** in Vivado’s top menu.\n\n3. **Navigate to Project Directory**  \n   ```tcl\n   cd C:/path/to/pcileech-fpga/pcileech-wifi-main/\n   pwd\n   ```\n   - Confirm with `pwd` that the console is in the correct folder.\n\n4. **Run the Generation Script**  \n   ```tcl\n   source vivado_generate_project_squirrel.tcl -notrace\n   ```\n   - If you’re using Enigma-X1 or ZDMA, run the corresponding script (e.g., `vivado_generate_project_enigma_x1.tcl`).\n\n5. **Open the Generated Project**  \n   - **File > Open Project**. Locate and select the `.xpr` (e.g., `pcileech_squirrel_top.xpr`).  \n   - Check the **Project Manager** window for properly imported sources.\n\n### **7.2 Customizing the PCIe IP Core**\n\nIn Vivado, you may find a PCIe IP core (e.g., `pcie_7x_0.xci`) under **Sources**:\n\n1. **Right-Click -> Customize IP**  \n   - Update vendor/device IDs, revision, and subsystem fields.  \n   - Match your desired BAR configurations (sizes, memory type, etc.).\n\n2. **Generate/Update the IP**  \n   - Click **OK** or **Generate** to rebuild.  \n   - Vivado might prompt you to upgrade or confirm dependencies if IP versions have changed.\n\n3. **Lock the IP Core**  \n   ```tcl\n   set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n   ```\n   - This prevents future scripts from overwriting your manual changes inadvertently.\n\n---\n\n## **Additional Best Practices**\n\n1. **Version Control** - *Highly Recommended*  \n   - Commit your changes often (Git or another SCM).  \n   - Tag or branch major changes so you can revert quickly if something breaks.\n\n2. **Documentation**  \n   - Keep a notebook, spreadsheet, or wiki summarizing donor device details, any special offsets, or capability quirks.  \n   - Document each step you take in customizing your FPGA firmware.\n\n3. **Testing on the Host**  \n   - After generating a bitstream, program the FPGA, then check:  \n     - **Windows**: Device Manager or `devcon.exe` to confirm the device enumerates with the correct IDs.  \n     - **Linux**: `lspci -vvv` to see if the device identifies correctly, including BAR, Class Code, Subsystem, etc.\n\n4. **Security Considerations**  \n   - Disabling features like VT-d or Secure Boot can open up the system to vulnerabilities. Use a dedicated test rig or isolate the environment to maintain operational security.\n\n5. **Where to Next?**  \n   - In **Part 2**, you will learn to build on these basics with deeper TLP manipulation, partial reconfiguration strategies, firmware debugging, and any advanced ID spoofing or handshake emulations.\n\n---\n\n# **Part 2: Intermediate Concepts and Implementation**\n\n---\n\n## **8. Advanced Firmware Customization**\n\nTo precisely emulate your donor device, you must extend your basic configuration by aligning advanced PCIe parameters, fine-tuning BAR settings, and fully implementing power management and interrupt mechanisms. This ensures that your FPGA-based emulated device interacts with the host exactly as the original hardware would.\n\n---\n\n### **8.1 Configuring PCIe Parameters for Emulation**\n\nAccurate PCIe emulation requires that your device’s link characteristics, capability pointers, and data transfer parameters (payload and read request sizes) match the donor device.\n\n#### **8.1.1 Matching PCIe Link Speed and Width**\n\n**Purpose:**  \nThe PCIe link speed (e.g., Gen1 at 2.5 GT/s, Gen2 at 5.0 GT/s, Gen3 at 8.0 GT/s) and the link width (e.g., x1, x4, x8) directly affect performance and compatibility. The donor’s parameters must be mirrored to ensure that the host system and drivers recognize and operate with the emulated device seamlessly.\n\n**Steps:**\n\n1. **Launch Vivado and Open Your Project:**  \n   - Open the Vivado project (e.g., `pcileech_squirrel_top.xpr`) where your design is maintained.\n   - Confirm that all source files are included and that the project hierarchy is intact.\n\n2. **Access the PCIe IP Core Settings:**  \n   - In the **Sources** pane, locate the PCIe IP core (typically named `pcie_7x_0.xci`).\n   - Right-click the file and select **Customize IP** to open the configuration GUI.\n\n3. **Set the Maximum Link Speed:**  \n   - Navigate to the **Link Parameters** tab.  \n   - Find the option labeled “Maximum Link Speed” and select the speed matching the donor device (e.g., 5.0 GT/s for Gen2).  \n   - *Note:* Verify that both your FPGA board and the physical slot support the selected speed.\n\n4. **Configure the Link Width:**  \n   - In the same tab, locate “Link Width.”  \n   - Choose the appropriate width (e.g., x4) as per the donor device.\n   - *Note:* Options typically include 1, 2, 4, 8, or 16 lanes.\n\n5. **Apply and Regenerate:**  \n   - Click **OK** to save your changes. Vivado may prompt you to regenerate the IP core; allow the process to complete.\n   - Finally, check the **Messages** window for any warnings or errors.\n\n---\n\n#### **8.1.2 Setting Capability Pointers**\n\n**Purpose:**  \nCapability pointers in the PCIe configuration space direct the host to locate extended capabilities (such as MSI/MSI‑X, power management, etc.). Matching these pointers ensures that the host accesses these capabilities exactly as it would with the donor device.\n\n**Steps:**\n\n1. **Open the Firmware Configuration File:**  \n   - In Visual Studio Code, open the file (for example, `pcileech_pcie_cfg_a7.sv`) located under `pcileech-fpga/pcileech-wifi-main/src/`.\n\n2. **Locate and Update the Capability Pointer Assignment:**  \n   - Find the assignment statement for `cfg_cap_pointer`. For example:\n     ```verilog\n     cfg_cap_pointer <= 8'hXX; // Current default value\n     ```\n   - Replace `XX` with the correct donor offset (e.g., `8'h60` if the donor’s capability pointer is at offset 0x60):\n     ```verilog\n     cfg_cap_pointer <= 8'h60; // Set to donor's capability pointer at offset 0x60\n     ```\n   - *Verification:* Ensure that the capability structure is aligned on a 4-byte boundary as required by PCIe.\n\n3. **Save the File and Comment Your Changes:**  \n   - Save the file (Ctrl+S) and add inline comments for future reference.\n\n---\n\n#### **8.1.3 Adjusting Maximum Payload and Read Request Sizes**\n\n**Purpose:**  \nPCIe devices negotiate the maximum amount of data per transaction. The “Maximum Payload Size” (MPS) and “Maximum Read Request Size” (MRRS) must be set to values identical to the donor device to guarantee driver compatibility and optimal data throughput.\n\n**Steps:**\n\n1. **Configure in the PCIe IP Core:**  \n   - In the IP customization GUI (found in the PCIe IP core), navigate to the **Device Capabilities** or **Capabilities** tab.\n   - Set the **Maximum Payload Size Supported** (e.g., 256 bytes) and **Maximum Read Request Size Supported** (e.g., 512 bytes) to match the donor device.\n\n2. **Update Firmware Constants:**  \n   - Open `pcileech_pcie_cfg_a7.sv` in Visual Studio Code.\n   - Locate the definitions for payload and read request sizes, for example:\n     ```verilog\n     max_payload_size_supported       <= 3'bZZZ; // Current value\n     max_read_request_size_supported  <= 3'bWWW; // Current value\n     ```\n   - Replace with the correct binary encodings:\n     - **Mapping (example):**\n       - 128 bytes: `3'b000`\n       - 256 bytes: `3'b001`\n       - 512 bytes: `3'b010`\n       - 1024 bytes: `3'b011`\n       - 2048 bytes: `3'b100`\n       - 4096 bytes: `3'b101`\n     - For example, if the donor supports 256 bytes payload and 512 bytes read requests:\n       ```verilog\n       max_payload_size_supported       <= 3'b001; // 256 bytes\n       max_read_request_size_supported  <= 3'b010; // 512 bytes\n       ```\n\n3. **Rebuild and Verify:**  \n   - Save the changes, re-run synthesis, and check for consistency between the IP core settings and firmware constants.\n\n---\n\n### **8.2 Adjusting BARs and Memory Mapping**\n\nBARs (Base Address Registers) determine which address spaces the device uses for memory or I/O. Correct BAR configuration is essential for driver operation and OS resource allocation.\n\n#### **8.2.1 Setting BAR Sizes**\n\n**Purpose:**  \nEnsuring that each BAR is set to the correct size and type (32-bit vs. 64-bit; memory vs. I/O) guarantees that the host allocates the proper address space.\n\n**Steps:**\n\n1. **Customize BARs in the PCIe IP Core:**  \n   - In Vivado, right-click on `pcie_7x_0.xci` and select **Customize IP**.\n   - Navigate to the **BARs** tab.\n   - For each BAR (BAR0–BAR5):\n     - **Set the Size:** Select the size (e.g., 64 KB, 128 MB) as defined by the donor.\n     - **Set the Type:** Choose between 32-bit or 64-bit memory addressing (or I/O space).\n     - **Enable or Disable:** Enable only those BARs used by the donor.\n\n2. **Synchronize with On-Chip Memory (if applicable):**  \n   - If using Block RAM (BRAM) to back up the emulated BAR regions, open the associated BRAM IP core files (e.g., `bram_bar_zero4k.xci`) and ensure that the memory size corresponds to the BAR configuration.\n\n3. **Save, Regenerate, and Verify:**  \n   - Save your changes and allow Vivado to regenerate the IP core.\n   - Review the **Messages** window for any configuration warnings.\n\n---\n\n#### **8.2.2 Defining BAR Address Spaces in Firmware**\n\n**Purpose:**  \nImplement logic to decode addresses targeting the BARs and route read/write operations correctly.\n\n**Steps:**\n\n1. **Open the BAR Controller Source File:**  \n   - For example, open `pcileech_tlps128_bar_controller.sv` in Visual Studio Code.\n\n2. **Implement Address Decoding Logic:**  \n   - Use combinational logic to determine which BAR is being accessed:\n     ```verilog\n     always_comb begin\n       if (bar_hit[0]) begin\n         // Handle accesses to BAR0\n       end else if (bar_hit[1]) begin\n         // Handle accesses to BAR1\n       end\n       // Continue for additional BARs as necessary\n     end\n     ```\n3. **Implement Read/Write Handling for Each BAR:**  \n   - Within each branch, create case statements or conditional blocks to map specific address offsets to internal registers:\n     ```verilog\n     if (bar_hit[0]) begin\n       case (addr_offset)\n         16'h0000: data_out <= reg0;\n         16'h0004: data_out <= reg1;\n         // Add additional registers as needed\n         default: data_out <= 32'h0;\n       endcase\n     end\n     ```\n4. **Save and Simulate:**  \n   - Save your changes, then simulate the design (if possible) to verify that address decoding and data transfers are correctly handled.\n\n---\n\n#### **8.2.3 Handling Multiple BARs**\n\n**Purpose:**  \nIf your device exposes multiple BARs, you must ensure that the logic for each BAR is isolated and that their address spaces do not conflict.\n\n**Steps:**\n\n1. **Separate BAR Logic:**  \n   - Consider modularizing your code by separating logic for each BAR into distinct blocks or even separate modules (e.g., `bar0_controller.sv`, `bar1_controller.sv`).\n\n2. **Validate Address Ranges:**  \n   - Confirm that each BAR is allocated a unique, non-overlapping address range.  \n   - Ensure that the sizes are aligned on power-of-two boundaries as required by the PCIe specification.\n\n3. **Testing:**  \n   - Perform both simulation (using test benches) and hardware testing (with tools such as `lspci -vvv` on Linux or Device Manager on Windows) to validate proper mapping and access.\n\n---\n\n### **8.3 Emulating Device Power Management and Interrupts**\n\nAdvanced emulation includes support for device power management states and interrupt handling. This is critical for driver functionality and overall system stability.\n\n---\n\n#### **8.3.1 Power Management Configuration**\n\n**Purpose:**  \nEnabling power management capabilities lets the device support various power states (D0 through D3), which is important for energy efficiency and proper OS behavior.\n\n**Steps:**\n\n1. **Enable Power Management in the PCIe IP Core:**  \n   - In the IP customization window, navigate to the **Capabilities** tab and enable “Power Management.”  \n   - Select the supported power states (e.g., D0 fully on, D1/D2 intermediate states, and D3 for low power).\n\n2. **Implement PMCSR Logic in Firmware:**  \n   - In your configuration file (e.g., `pcileech_pcie_cfg_a7.sv`), implement logic to handle writes to the Power Management Control/Status Register (PMCSR):\n     ```verilog\n     localparam PMCSR_ADDRESS = 12'h44; // Example address for PMCSR\n     reg [15:0] pmcsr_reg;\n\n     always @(posedge clk) begin\n       if (cfg_write && cfg_address == PMCSR_ADDRESS) begin\n         pmcsr_reg <= cfg_writedata[15:0];\n         // Update internal power state based on pmcsr_reg[1:0]\n       end\n     end\n     ```\n   - *Note:* Update the device’s operational behavior if entering lower power states, as required by your donor.\n\n3. **Test the Implementation:**  \n   - Simulate power state transitions and verify that the PMCSR behaves as expected.\n\n---\n\n#### **8.3.2 MSI/MSI-X Configuration and Active Device Behavior**\n\n**Understanding “Active Devices”:**  \nIn firmware parlance, an “active device” is one that regularly initiates DMA transfers and signals the host via interrupts when transfers complete. Rather than being “active” in a generic sense, these devices actively “ring the doorbell” to inform the CPU that data is ready. This concept is critical in systems where efficient interrupt signaling is key.\n\n**MSI (Message Signaled Interrupts) vs. MSI-X:**  \n- **MSI:** Uses the built-in interrupt interface provided by the Xilinx PCIe IP core.  \n- **MSI-X:** Requires the firmware to manually construct and send a MEMWR64 (Memory Write 64-bit) TLP as the “doorbell” because the built-in interface does not support MSI-X natively.\n\n**Steps for MSI (if using the built-in interface):**\n\n1. **Configure MSI in the PCIe IP Core:**  \n   - In the IP core customization, locate the **Interrupt** or **MSI/MSI-X** section.\n   - Enable MSI and set the number of supported vectors (typically up to 32).\n\n2. **Implement the Interrupt Interface in Firmware:**  \n   - In your configuration file, wire up the interrupt signals as follows:\n     ```verilog\n     assign ctx.cfg_interrupt_di             = cfg_int_di;\n     assign ctx.cfg_pciecap_interrupt_msgnum = cfg_msg_num;\n     assign ctx.cfg_interrupt_assert         = cfg_int_assert;\n     assign ctx.cfg_interrupt                = cfg_int_valid;\n     assign ctx.cfg_interrupt_stat           = cfg_int_stat;\n     ```\n   - Then, include a process that asserts `cfg_int_valid` when an event occurs (for example, DMA completion):\n     ```verilog\n     always @(posedge clk_pcie) begin\n       if (rst) begin\n         cfg_int_valid <= 1'b0;\n         cfg_msg_num   <= 5'b0;\n         cfg_int_assert<= 1'b0;\n         cfg_int_di    <= 8'b0;\n         cfg_int_stat  <= 1'b0;\n       end else if (cfg_int_ready && cfg_int_valid) begin\n         cfg_int_valid <= 1'b0;\n       end else if (o_int) begin\n         cfg_int_valid <= 1'b0; // Adjust based on your interrupt generation timing\n       end\n     end\n\n     // Example interrupt counter to generate periodic interrupts:\n     reg [31:0] int_cnt;\n     always @(posedge clk_pcie) begin\n       if (rst)\n         int_cnt <= 0;\n       else if (int_cnt == 32'd100000)\n         int_cnt <= 0;\n       else if (int_enable)\n         int_cnt <= int_cnt + 1;\n     end\n     assign o_int = (int_cnt == 32'd100000);\n     ```\n\n**Steps for MSI-X (Manual TLP Construction):**\n\n1. **Manually Build the MSI-X TLP:**  \n   - Because the Xilinx IP core interrupt interface does not support MSI-X, you must construct a MEMWR64 TLP that signals an interrupt.\n   - Define the TLP fields as follows (modify as needed based on your donor’s specification):\n     ```verilog\n     // Define the header fields for a MEMWR64 TLP.\n     wire [31:0] HDR_MEMWR64 = 32'b01000000_00000000_00000000_00000001;\n     // Construct subsequent data words (ensure proper bit concatenation):\n     wire [31:0] MWR64_DW2   = { _bs16(pcie_id), 8'b0, 8'b00001111 };\n     wire [31:0] MWR64_DW3   = { i_addr[31:2], 2'b0 };\n     wire [31:0] MWR64_DW4   = i_data;\n     ```\n\n2. **Integrate with TLP Output:**  \n   - In your TLP transmit logic (e.g., within `pcileech_pcie_tlp_a7.sv`), assign the constructed TLP:\n     ```verilog\n     reg         msix_valid;\n     reg         msix_has_data;\n     reg [127:0] msix_tlp;\n\n     assign tlps_static.tdata   = msix_tlp;\n     assign tlps_static.tkeepdw = 4'hF;\n     assign tlps_static.tlast   = 1'b1;\n     assign tlps_static.tuser[0]= 1'b1;\n     assign tlps_static.tvalid  = msix_valid;\n     assign tlps_static.has_data= msix_has_data;\n\n     always @(posedge clk_pcie) begin\n       if (rst) begin\n         msix_valid    <= 1'b0;\n         msix_has_data <= 1'b0;\n         msix_tlp      <= 128'b0;\n       end else if (msix_valid) begin\n         msix_valid <= 1'b0;\n       end else if (msix_has_data && tlps_static.tready) begin\n         msix_valid    <= 1'b1;\n         msix_has_data <= 1'b0;\n         msix_tlp      <= { MWR64_DW4, MWR64_DW3, MWR64_DW2, HDR_MEMWR64 };\n       end else if (o_int) begin\n         msix_has_data <= 1'b1;\n       end\n     end\n     // Use a similar interrupt counter for periodic generation if needed.\n     ```\n   - *Verification:* Confirm that the assembled TLP conforms to the PCIe specification for a MEMWR64 packet. Use simulation and an Integrated Logic Analyzer (ILA) during hardware testing.\n\n---\n\n#### **8.3.3 Implementing Interrupt Handling Logic**\n\n**Purpose:**  \nDefine clear conditions and a dedicated module for generating interrupts when required by events (e.g., DMA transfer completion). This is critical for an “active” device that signals the host frequently.\n\n**Steps:**\n\n1. **Define Interrupt Trigger Conditions:**  \n   - Identify which events should generate an interrupt. These might include:\n     - DMA transfer completion.\n     - Data availability.\n     - Error conditions.\n   - Implement combinational or sequential logic to detect these events.\n\n2. **Modularize the Interrupt Controller:**  \n   - It is advisable to encapsulate interrupt logic in a separate module:\n     ```verilog\n     module interrupt_controller(\n       input  wire clk,\n       input  wire rst,\n       input  wire event_trigger,\n       output reg  msi_req\n     );\n       always @(posedge clk or posedge rst) begin\n         if (rst)\n           msi_req <= 1'b0;\n         else if (event_trigger)\n           msi_req <= 1'b1;\n         else\n           msi_req <= 1'b0;\n       end\n     endmodule\n     ```\n   - Integrate this module with your main firmware logic.\n\n3. **Ensure Correct Timing:**  \n   - Verify that interrupt assertions and de-assertions follow PCIe timing requirements.\n   - Test with simulation and hardware debug tools (such as ILA) to confirm that the host receives interrupts appropriately.\n\n---\n\n### **8.4 What is “FULL EMU” vs. “DUMP EMU”?**\n\n**Understanding the Terminology:**\n\n- **DUMP EMU:**  \n  A firmware approach that essentially “dumps” the donor device’s BAR and capability registers (often obtained via an Arbor scan) into the FPGA. This method replicates only the static configuration data.\n\n- **FULL EMU:**  \n  True full emulation replicates not only the static configuration (IDs, BARs, capabilities) but also the dynamic behavior of the donor device. This includes:\n  - Generating correct TLPs (for reads, writes, completions, vendor-specific messages).\n  - Handling power management transitions.\n  - Implementing interrupt generation and proper “doorbell” signaling (especially with MSI‑X).\n  - Supporting active DMA transfers and real-time responses as the donor would.\n\n**Future Enhancements:**  \nPlanned updates may include detection methods that verify whether a firmware project is truly “FULL EMU” (with active dynamic behavior) versus a static “DUMP EMU.” For example, advanced testing on a Realtek-based NIC may be used as a benchmark.\n\n---\n\n## **10. Transaction Layer Packet (TLP) Emulation**\n\nTLPs are the fundamental units of communication over PCIe. For a fully functional emulation, your design must not only replicate configuration space but also accurately generate and respond to TLPs as a real device would.\n\n### **10.1 Understanding and Capturing TLPs**\n\n#### **10.1.1 Learning the TLP Structure**\n\n- **Header:**  \n  Contains fields such as:\n  - TLP Type (e.g., Memory Read, Memory Write, Config, Vendor-Defined)\n  - Length, Requester ID, Tag, Address  \n- **Data Payload:**  \n  Present in transactions like Memory Write. Must honor the negotiated Maximum Payload Size.\n- **CRC:**  \n  Used for data integrity verification.\n\n#### **10.1.2 Capturing TLPs from the Donor Device**\n\n1. **Use a PCIe Protocol Analyzer:**  \n   - Tools like Teledyne LeCroy analyzers or Xilinx ILA setups capture real-time TLPs.\n2. **Capture and Analyze Transactions:**  \n   - Monitor TLPs during normal operation to note header fields, sequence, and timing.\n3. **Document Key Transactions:**  \n   - Focus on initialization sequences, memory read/write exchanges, and vendor-specific messages.\n\n---\n\n### **10.2 Crafting Custom TLPs for Specific Operations**\n\n#### **10.2.1 Implementing TLP Handling in Firmware**\n\n1. **TLP Generation Functions:**  \n   - In your TLP module (e.g., `pcileech_pcie_tlp_a7.sv`), create functions to assemble TLPs. For example:\n     ```verilog\n     function automatic [127:0] generate_tlp(\n       input [15:0] requester_id,\n       input [7:0]  tag,\n       input [7:0]  length,\n       input [31:0] address,\n       input [31:0] data\n     );\n       // Construct and return a 128-bit TLP comprising header and payload.\n     endfunction\n     ```\n2. **TLP Reception and Parsing:**  \n   - Implement state machines to parse incoming TLPs and route them based on type (e.g., distinguishing between memory read and write).\n\n3. **Completion Handling:**  \n   - For memory read requests, generate completion TLPs with the requested data, ensuring adherence to PCIe timing and CRC requirements.\n\n---\n\n#### **10.2.2 Handling Different TLP Types**\n\n1. **Memory Read Requests:**  \n   - Parse the TLP header, read from the correct memory region, and send a completion TLP.\n2. **Memory Write Requests:**  \n   - Extract data payloads and write the data to emulated registers or memory blocks.\n3. **Configuration Read/Write:**  \n   - Access the configuration space registers accordingly.\n4. **Vendor-Defined Messages:**  \n   - Implement special handling if your donor device uses proprietary TLPs.\n\n---\n\n#### **10.2.3 Validating TLP Timing and Sequence**\n\n1. **Simulation Testing:**  \n   - Develop test benches that simulate TLP exchanges and verify the correctness of headers, payloads, and response timing.\n2. **Hardware Debugging:**  \n   - Use an ILA core to monitor TLP bus signals in real time.\n3. **Compliance Verification:**  \n   - Consider using PCIe compliance tools if available to verify that your TLP implementation meets specifications.\n\n---\n\n## **Conclusion**\n\nBy following these detailed procedures in Part 2, you now extend your emulation beyond static register replication. You are configuring critical PCIe link parameters, ensuring proper BAR and memory mapping, implementing full power management, and handling both MSI and MSI‑X interrupts. Furthermore, you have established a foundation for crafting and validating custom TLPs that enable a fully active, “FULL EMU” firmware solution—one that mirrors the dynamic behavior of the donor device.\n\n**Key Takeaways:**\n\n1. **Match Advanced PCIe Parameters Exactly:**  \n   - Link speed, link width, capability pointers, and payload sizes must be identical to the donor’s.\n2. **BAR Configuration and Address Decoding:**  \n   - Correctly size and type your BARs, and implement robust address decoding logic.\n3. **Interrupts – MSI vs. MSI‑X:**  \n   - Use the built-in interrupt interface for MSI; manually construct MEMWR64 TLPs for MSI‑X.\n4. **Active Device Behavior:**  \n   - Emulate frequent DMA transfers and “doorbell” interrupt signaling to mirror real hardware activity.\n5. **TLP Emulation:**  \n   - Ensure that TLP generation, reception, and timing conform to PCIe standards for complete emulation.\n\nIn **Part 3**, we will build on these intermediate concepts with performance optimizations, extensive debugging techniques, and production-level best practices. Continue to validate each feature against the donor device’s specifications to achieve a truly indistinguishable emulation.\n"
  },
  {
    "path": "Lesson 3_ Advanced PCIe Configuration and Interrupt Handling.md",
    "content": "# Lesson: Understanding PCIe Configuration and Interrupt Handling on Xilinx Artix-7 Platforms\n\n## **Overview**\n\nPlease let me know if you guys like the lesson based format over the all in one guide. If so, I will provide a course nd perhaps videos.\n\nThis lesson delves into the intricacies of PCI Express (PCIe) configuration, specifically focusing on determining maximal payload sizes and handling interrupts within FPGA-based systems using Xilinx Artix-7. Additionally, it explores the PCIe data link layer mechanisms, including Transaction Layer Packets (TLPs), Data Link Layer Packets (DLLPs), and flow control. By the end of this lesson, you will have a comprehensive understanding of configuring PCIe devices, defining interrupts in FPGA designs, and optimizing PCIe performance on Artix-7 platforms.\n\n---\n    \n## **Objectives**\n\nBy the end of this lesson, you will be able to:\n\n1. **Determine Maximal Payload Sizes** for PCIe devices using both automated tools and manual methods.\n2. **Define and Handle Interrupts** in FPGA-based PCIe designs for Xilinx Artix-7 platforms.\n3. **Understand PCIe Data Link Layer Mechanisms**, including TLPs, DLLPs, and flow control.\n4. **Optimize PCIe Performance** by analyzing payload sizes and their impact on data transmission.\n\n---\n    \n## **1. Introduction to PCI Express (PCIe)**\n\nPCI Express (PCIe) is a high-speed serial computer expansion bus standard designed to replace older bus standards like PCI and PCI-X. It is widely used for connecting peripheral devices to the motherboard, including graphics cards, SSDs, and network cards. Understanding PCIe configuration and interrupt handling is crucial for optimizing system performance and ensuring reliable communication between devices.\n\nOn FPGA platforms like Xilinx Artix-7, implementing PCIe interfaces allows for the creation of custom peripherals, enabling applications in hardware testing, system debugging, data acquisition, and more.\n\n---\n    \n## **2. Determining Maximal Payload Size**\n\n### **2.1. Automated Approach with `lspci`**\n\nThe `lspci` utility in Linux provides detailed information about all PCI devices connected to the system. It can automatically determine the maximal payload size a PCIe device can handle without manual intervention.\n\n**Example Command:**\n\n```bash\nlspci -vv\n```\n\nThis command displays verbose information about all PCI devices, including their capabilities and configuration registers.\n\n### **2.2. Manual Approach: Parsing Configuration Space**\n\nUnderstanding how to manually determine the maximal payload size can demystify underlying processes and provide deeper insights into PCIe configurations.\n\n#### **2.2.1. PCIe Configuration Space**\n\nEach PCIe device has a 256-byte configuration space containing various registers that define its capabilities and settings. Key registers related to payload size include:\n\n- **Device Capabilities Register (DevCap):** Located at offset `0x04` in the PCI Express Capability structure. Bits `2-0` indicate the `max_payload_size_capable`.\n  \n- **Device Control Register (DevCtrl):** Located at offset `0x08` in the PCI Express Capability structure. Bits `7-5` indicate the `max_payload_size_in_effect`.\n\n#### **2.2.2. Calculating Maximal Payload Size**\n\nThe maximal payload size is determined using the following formula:\n\n```c\nmax_payload_size_capable = 1 << ((DevCapReg & 0x07) + 7); // In bytes\nmax_payload_size_in_effect = 1 << (((DevCtrlReg >> 5) & 0x07) + 7); // In bytes\n```\n\n- **`DevCapReg`**: Value from the Device Capabilities Register.\n- **`DevCtrlReg`**: Value from the Device Control Register.\n\n#### **2.2.3. Example: Manual Parsing with `lspci -xxx`**\n\nConsider the following `lspci -xxx` output for a specific device:\n\n```\n01:00.0 Class ff00: Xilinx Corporation Artix-7 PCIe Core\n00: ee 10 34 12 07 04 10 00 00 00 00 ff 01 00 00 00\n...\n40: 01 48 03 70 08 00 00 00 05 58 81 00 0c 30 e0 fe\n...\n58: 00 00 00 00 00 00 00 00\n60: 10 28 00 00 11 f4 03 00\n...\n```\n\n**Steps:**\n\n1. **Identify the PCI Express Capability Structure:**\n   - Locate the capability with **Cap ID `0x10`**.\n   - Follow the linked list pointers to find the structure at offset `0x58`.\n\n2. **Extract Registers:**\n   - **Device Capabilities Register (`0x5C`):** `0x00288fc2`\n     - Bits `2-0`: `2` → `1 << (2 + 7) = 512 bytes`\n   - **Device Control Register (`0x60`):** `0x00002810`\n     - Bits `7-5`: `0` → `1 << (0 + 7) = 128 bytes`\n\n3. **Interpretation:**\n   - **Max Payload Size Capable:** `512 bytes`\n   - **Max Payload Size in Effect:** `128 bytes`\n\n### **2.3. Impact on Performance**\n\nA smaller maximal payload size (e.g., `128 bytes`) can lead to increased overhead, as more TLPs (Transaction Layer Packets) are required to transmit the same amount of data compared to larger payload sizes (e.g., `512 bytes`). This overhead affects the effective bandwidth:\n\n- **128-byte TLPs:**\n  - Overhead: ~12%\n  - Effective Bandwidth: ~219 MB/s\n\n- **512-byte TLPs:**\n  - Overhead: ~3.4%\n  - Effective Bandwidth: ~241 MB/s\n\nUnderstanding and optimizing payload sizes can significantly enhance system performance, especially in high-throughput applications.\n\n---\n    \n## **3. Interrupt Definitions in FPGA-Based PCIe Designs**\n\n### **3.1. Overview of Interrupts in PCIe**\n\nInterrupts are essential for asynchronous event handling in PCIe devices. Properly defining and handling interrupts ensures that the FPGA-based PCIe device can notify the host system of events, such as data availability or error conditions.\n\n### **3.2. Defining Interrupts in FPGA Designs**\n\nInterrupts in FPGA-based PCIe designs are typically managed through Message Signaled Interrupts (MSI) or MSI-X, which allow devices to generate interrupts by writing to a specific memory address.\n\n#### **3.2.1. Example: MSI Interrupt Definition**\n\nIn the FPGA firmware, defining MSI involves configuring the MSI capability structure and ensuring that the host system can map and handle these interrupts.\n\n**Verilog Example:**\n\n```verilog\n// MSI Capability Structure\nmodule msi_cap (\n    input wire clk,\n    input wire reset,\n    // Other signals\n    output reg [31:0] msi_address,\n    output reg [31:0] msi_data,\n    output reg msi_enable\n);\n\n// Configuration\nalways @(posedge clk or posedge reset) begin\n    if (reset) begin\n        msi_address <= 32'h00000000;\n        msi_data <= 32'h00000000;\n        msi_enable <= 1'b0;\n    end else begin\n        // Set MSI Address and Data based on host configuration\n        msi_address <= 32'hFEE00000; // Example address\n        msi_data <= 32'h00000001;    // Example data\n        msi_enable <= 1'b1;          // Enable MSI\n    end\nend\n\nendmodule\n```\n\n**Explanation:**\n\n- **`msi_address`:** The address where the MSI will write to notify the host.\n- **`msi_data`:** The data payload sent with the MSI.\n- **`msi_enable`:** Enables or disables MSI generation.\n\n### **3.3. Handling Interrupts in the Host System**\n\nOn the host side (e.g., Linux), interrupt handling involves mapping the MSI addresses and ensuring that the kernel can process the interrupts generated by the FPGA.\n\n**Example Steps on Linux:**\n\n1. **Device Tree Configuration:**\n\n   Define the MSI interrupt properties in the device tree to inform the kernel about the interrupt capabilities.\n\n   ```dts\n   pcie_fpga@0000:01:00.0 {\n       compatible = \"xilinx,artix7-pcie-core\";\n       reg = <0x0000 0x0001 0x0000 0x0000>;\n       interrupts = <1 45 4>;\n       interrupt-parent = <&msi_controller>;\n       msix-num = <16>;\n       // Other properties\n   };\n   ```\n\n   **Explanation:**\n   \n   - **`interrupts = <1 45 4>;`**\n     - **`1`**: Indicates MSI interrupt.\n     - **`45`**: Interrupt number.\n     - **`4`**: Level-sensitive, active high.\n\n2. **Kernel Module Driver:**\n\n   In the FPGA's kernel driver, register the interrupt handler to respond to MSIs.\n\n   ```c\n   irq = irq_of_parse_and_map(op->dev.of_node, 0);\n   rc = request_irq(irq, artix7_pcie_isr, 0, \"artix7_pcie\", op->dev);\n   if (rc) {\n       // Handle error\n   }\n   ```\n\n   - **`irq_of_parse_and_map`:** Parses the `interrupts` property and maps it to a Linux IRQ number.\n   - **`request_irq`:** Registers the interrupt handler (`artix7_pcie_isr`) for the specified IRQ.\n\n---\n    \n## **4. PCIe Data Link Layer Mechanisms**\n\n### **4.1. Transaction Layer Packets (TLPs)**\n\nTLPs are the fundamental units of communication in PCIe, carrying both control and data information between devices.\n\n**Components of a TLP:**\n\n- **Header:** Contains information like type, length, and address.\n  - **3 DWs** for 32-bit addressing.\n  - **4 DWs** for 64-bit addressing.\n  \n- **Data Payload:** The actual data being transmitted.\n  \n- **Optional Digest:** Typically a 1-DW TLP digest (ECRC).\n\n### **4.2. Data Link Layer Packets (DLLPs)**\n\nDLLPs are used by the Data Link Layer to manage reliable transmission over PCIe. They include:\n\n- **Ack DLLP:** Acknowledges successful receipt of TLPs.\n- **Nack DLLP:** Indicates a corrupted TLP, prompting retransmission.\n- **Flow Control DLLPs:** Manage credits for data transmission.\n- **Power Management DLLPs:** Handle power state transitions.\n\n### **4.3. Flow Control Mechanism**\n\nFlow Control ensures that a sender does not overwhelm a receiver by transmitting more data than it can handle.\n\n**Key Concepts:**\n\n- **Flow Control Units:** Correspond to 16 bytes (4 DWs) of traffic.\n  \n- **Credit Types:** Six distinct types based on the TLP category:\n  1. Posted Requests TLPs (headers)\n  2. Posted Requests TLPs (data)\n  3. Non-Posted Requests TLPs (headers)\n  4. Non-Posted Requests TLPs (data)\n  5. Completion TLPs (headers)\n  6. Completion TLPs (data)\n\n- **Doorkeeper Analogy:** Manages the number of flow control units to prevent buffer overflows.\n\n**Flow Control Operations:**\n\n1. **Initial Exchange:** Both sides exchange their initial credit limits upon link establishment.\n2. **Credit Updates:** As TLPs are transmitted and processed, credit limits are updated via UpdateFC DLLPs.\n3. **Credit Overflow Handling:** Uses modulo arithmetic to handle counter overflows gracefully.\n\n**Infinite Credit Option:**\n\nEndpoints must advertise infinite credit for completion headers and data, ensuring they can always accept completion TLPs without relying on flow control.\n\n### **4.4. Virtual Channels**\n\nVirtual Channels (VCs) allow multiple independent streams of TLPs to coexist without interfering with each other.\n\n**Key Points:**\n\n- **Traffic Class (TC):** Identifies the virtual channel.\n- **Default Usage:** Most systems use a single virtual channel (`TC0`), rendering VCs optional for standard applications.\n- **Advanced Usage:** Useful in scenarios requiring segregated traffic streams to prevent blocking.\n\n### **4.5. Packet Reordering**\n\nPCIe allows certain degrees of TLP reordering to optimize transmission and prevent deadlocks.\n\n**Reordering Rules:**\n\n1. **Posted Writes and MSIs:** Always arrive in the order sent.\n2. **Read Requests:** Never arrive before preceding write requests or MSIs.\n3. **Write Requests:** May arrive before preceding read requests.\n4. **Read Completions:** Ordered per request but can be reordered across different requests.\n\n**Implications:**\n\n- **Consistency:** Ensures memory operations maintain expected order for data integrity.\n- **Deadlock Prevention:** Reordering rules are designed to prevent communication deadlocks in complex topologies.\n\n### **4.6. Zero-Length Read Requests**\n\nZero-length read requests are used to ensure write operations have completed without retrieving any actual data.\n\n**Behavior:**\n\n- **Completion Requirement:** Must return a single DW of data, which is typically disregarded.\n- **Usage Scenario:** Acts as a synchronization mechanism to confirm the completion of preceding write operations.\n\n---\n    \n## **5. Practical Considerations**\n\n### **5.1. FPGA Firmware Probing and Mapping**\n\nWhen developing FPGA firmware for PCIe devices, it's essential to correctly probe and map hardware resources to ensure seamless communication with the host system.\n\n**Key Steps:**\n\n1. **Configure PCIe Parameters:**\n   - Set device IDs, vendor IDs, subsystem IDs, and BARs to match the desired emulated device.\n   \n2. **Implement Interrupt Handling:**\n   - Configure MSI/MSI-X capabilities in the FPGA firmware.\n   - Ensure the host system can map and handle these interrupts.\n\n3. **Map Memory Regions:**\n   - Define BAR sizes and address spaces accurately to match the target device's configuration.\n\n4. **Integrate with Host Drivers:**\n   - Develop or modify host-side drivers to interact with the FPGA-based PCIe device effectively.\n\n### **5.2. Accessing Hardware Registers Correctly**\n\nDirectly accessing hardware registers via pointers can lead to cache coherency issues, especially on platforms interfacing with FPGAs like Artix-7.\n\n**Best Practices:**\n\n- **Use IO Functions:** Utilize provided API functions or interfaces for register access to maintain cache coherency.\n- **Avoid `volatile`:** The Linux kernel discourages the use of the `volatile` keyword for hardware registers. Instead, use appropriate memory barriers or synchronization mechanisms.\n\n**Example in Kernel Module:**\n\n```c\n#include <linux/io.h>\n\nu32 value;\nvalue = ioread32(registers + OFFSET);\niowrite32(new_value, registers + OFFSET);\n```\n\n### **5.3. Interrupt Handler Registration**\n\nProperly registering interrupt handlers ensures that your FPGA-based PCIe device responds to hardware events correctly.\n\n**Example:**\n\n```c\nirq = irq_of_parse_and_map(op->dev.of_node, 0);\nrc = request_irq(irq, artix7_pcie_isr, 0, \"artix7_pcie\", op->dev);\nif (rc) {\n    dev_err(&op->dev, \"Failed to request IRQ\\n\");\n    return rc;\n}\n```\n\n- **`irq_of_parse_and_map`:** Parses the `interrupts` property and maps it to a Linux IRQ number.\n- **`request_irq`:** Registers the interrupt handler (`artix7_pcie_isr`) for the specified IRQ.\n\n---\n    \n## **6. Summary and Best Practices**\n\n- **Maximal Payload Size:**\n  - Use `lspci -vv` for automated retrieval.\n  - Manual parsing provides deeper insights and can be essential for custom configurations.\n  - Larger payload sizes reduce overhead and improve bandwidth efficiency.\n\n- **Interrupt Definitions:**\n  - Clearly define interrupts in FPGA designs with correct flags, numbers, and types.\n  - Understand the distinction between MSI and MSI-X interrupts and their respective configurations.\n  - Ensure the interrupt type aligns with hardware capabilities and kernel expectations.\n\n- **PCIe Data Link Layer:**\n  - TLPs and DLLPs manage data transmission and flow control.\n  - Flow control mechanisms prevent buffer overflows and ensure reliable communication.\n  - Virtual Channels and packet reordering enhance transmission efficiency and prevent deadlocks.\n\n- **FPGA Firmware Development:**\n  - Always use IO functions for register access to maintain cache coherency.\n  - Properly probe and map hardware resources to avoid conflicts.\n  - Register interrupt handlers accurately to respond to hardware events effectively.\n\n---\n    \n## **7. Exercises and Questions**\n\n### **Exercise 1: Calculating Maximal Payload Size**\n\nGiven a Device Capabilities Register value of `0x00000005` and a Device Control Register value of `0x00000060`, calculate:\n\n1. **Max Payload Size Capable**\n2. **Max Payload Size in Effect**\n\n*Solution:*\n\n1. **Max Payload Size Capable:**\n   - `(DevCapReg & 0x07) + 7 = (5) + 7 = 12`\n   - `1 << 12 = 4096 bytes`\n\n2. **Max Payload Size in Effect:**\n   - `((DevCtrlReg >> 5) & 0x07) + 7 = ((0x60 >> 5) & 0x07) + 7 = (3 & 0x07) + 7 = 10`\n   - `1 << 10 = 1024 bytes`\n\n### **Question 1: Interrupt Type Flags**\n\nExplain the significance of each value in the `interrupts` property `<0x0 0x32 0x0>` for a device in an FPGA-based PCIe design.\n\n*Answer:*\n\n- **`0x0`:** Indicates the interrupt is an MSI (Message Signaled Interrupt).\n- **`0x32`:** The interrupt number, used by the host to identify the interrupt source.\n- **`0x0`:** Specifies the interrupt type as default (leave as set by the FPGA firmware).\n\n### **Question 2: Flow Control Units**\n\nWhy are flow control units rounded up to the nearest integer when calculating data consumption in TLPs?\n\n*Answer:*\n\nFlow control units correspond to fixed sizes (16 bytes) and ensure that buffer space is allocated efficiently without mixing data from different TLPs. Rounding up ensures that any partial data payload still consumes a full flow control unit, maintaining alignment and preventing buffer overflow.\n\n### **Exercise 2: FPGA Firmware Interrupt Mapping**\n\nGiven the following interrupt definition in FPGA firmware:\n\n```verilog\ninterrupts = <1 45 4>;\n```\n\nDetermine:\n\n1. **Is the interrupt an MSI or MSI-X?**\n2. **What is the interrupt number?**\n3. **What is the interrupt type?**\n\n*Solution:*\n\n1. **`1`:** Indicates it's an MSI (Message Signaled Interrupt).\n2. **`45`:** Interrupt number as specified.\n3. **`4`:** Level-sensitive, active high.\n\n---\n    \n## **8. Further Reading and Resources**\n\n- **PCI Express Base Specification:** Comprehensive guide to PCIe standards.\n- **Xilinx Artix-7 FPGA Documentation:** Official documentation for Artix-7 FPGA configurations and capabilities.\n- **Linux Device Drivers Documentation:** Official documentation for writing and understanding PCIe drivers in Linux.\n- **Xilinx Vivado Documentation:** Detailed guides and tutorials for using Vivado with Artix-7 FPGAs.\n- **PCILeech-FPGA Repository:** [https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n- **Wireshark PCIe Extensions:** [https://www.wireshark.org/docs/](https://www.wireshark.org/docs/)\n- **Teledyne LeCroy Telescan PE Documentation:** [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n- **Arbor Software User Guide:** [Arbor User Guide](https://www.mindshare.com/software/Arbor)\n- **Field Programmable Gate Array (FPGA) Basics:** [FPGA Basics](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug901-vivado-tutorial.pdf)\n- **PCI-SIG Specifications:** [PCI-SIG](https://pcisig.com/specifications)\n\n---\n    \n**End of Lesson**\n\n---\n\n## **Feedback and Donation Request**\n\nI aimed to provide this lesson in a clear and structured format to enhance understanding and facilitate easier absorption of complex PCIe concepts on Xilinx Artix-7 platforms. Your feedback is invaluable in improving the quality and effectiveness of this content. If you find this lesson helpful and would like to support further development, please consider making a donation.\n\nThank you for your support!\n\n---\n    \n## **Support My Work**\n\nIf you found this guide helpful and want to fuel more projects, consider contributing to help keep everything going. Every donation helps me continue to create, share, and support the community, and it’s greatly appreciated.\n\n### **Crypto Donations (LTC)**  \n- MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi\n\nI don’t make much from selling firmware—maybe 5 sales adding up to around $300 total—but I know many people using this guide will go on to make far more. If this guide helped you on your path to success, consider giving back so I can keep these resources available for everyone.\n\n### **Special Bonus**  \nIf you donate, reach out to me on Discord (VCPU) and let me know. I’d love to thank you personally and offer something in return. I’ll even do a random prize spin—whether it's free firmware, private source codes, or some insights on bypassing ACS, there’ll be something special for you.\n\nYour support means the world to me, and together we can keep building and sharing for the future. Thank you!\n\n---\n    \nDon't have the time or energy to develop firmware yourself? I offer custom firmware solutions starting at $60. Resellers are also welcome!\n\nReach out anytime for support or further discussion on this guide or related topics. Whether you’re a developer needing in-depth help or a researcher diving into FPGA emulation, I’m here to ensure your path to success is smooth and informed. Let's build something remarkable together.\n\nIf you are unsure if you completed a step properly or want me to review your implementation, I will do so, but you must have the section for review marked with `//VCPU-REVIEW//` and explain your problems so my time is not wasted.\n\nI am sure quite a few of you will exceed my capabilities. If you find something new or just develop some impressive firmware, I would love to see it in action. Moreover, I also have some very powerful bytes and bits to share, but if I shared here Riot PD would put me in a squad car.\n\nShare knowledge and spread loving kindness. God bless.\n\n---\n\n## **Contact Information**\n\nIf you need assistance, have inquiries, or are looking to collaborate, feel free to reach out. I’m available to provide guidance, troubleshoot complex problems, or discuss ideas in detail.\n\n### **Discord** - **VCPU** | [**Server**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **Best Practices for Firmware Development**\n\nAdhering to best practices ensures the development process is efficient, maintainable, and secure.\n\n### **15.1. Continuous Testing and Documentation**\n\n- **Test Frequently**\n  - **Steps**:\n    1. Conduct regular tests after each modification to ensure the firmware behaves as expected.\n    2. Use automated scripts or test benches to validate firmware functionality continuously.\n\n- **Document Changes**\n  - **Steps**:\n    1. Maintain detailed documentation for each change made to the firmware.\n    2. Include explanations for why changes were made and their impact on the overall design.\n\n### **15.2. Managing Firmware Versioning**\n\n- **Use Version Control**\n  - **Steps**:\n    1. Implement a version control system (e.g., **Git**) to manage different iterations of the firmware.\n    2. Commit changes regularly with descriptive messages to track the evolution of the project.\n\n- **Branching Strategy**\n  - **Steps**:\n    1. Use branches to manage feature development, bug fixes, and experimental changes.\n    2. Merge stable branches into the main branch only after thorough testing.\n\n### **15.3. Security Considerations**\n\n- **Prevent Unintended Access**\n  - **Steps**:\n    1. Ensure that the firmware does not expose system memory or hardware to unauthorized access.\n    2. Implement access controls and validation checks within the firmware.\n\n- **Protect Firmware Integrity**\n  - **Steps**:\n    1. Avoid introducing vulnerabilities or backdoors during firmware development.\n    2. Conduct regular security reviews and code audits to maintain firmware integrity.\n\n- **Handle Sensitive Data Securely**\n  - **Steps**:\n    1. If the firmware interacts with sensitive data, implement encryption and secure data handling practices.\n    2. Ensure that sensitive information is not exposed through firmware interfaces or logs.\n"
  },
  {
    "path": "README-old.md",
    "content": "## Need DMA Equiptment? I recommend shopping with [DMAPolice.com](https://dmapolice.com/)\n\n# **Custom Firmware Development Guide for Full Device Emulation**\n\n***v4 in progress - nearly done***\n---\n## **Table of Contents**\n\n### **Part 1: Foundational Concepts**\n\n1. [Introduction](#1-introduction)\n   - [1.1 Purpose of the Guide](#11-purpose-of-the-guide)\n   - [1.2 Target Audience](#12-target-audience)\n   - [1.3 How to Use This Guide](#13-how-to-use-this-guide)\n2. [Key Definitions](#2-key-definitions)\n3. [Device Compatibility](#3-device-compatibility)\n   - [3.1 Supported FPGA-Based Hardware](#31-supported-fpga-based-hardware)\n   - [3.2 PCIe Hardware Considerations](#32-pcie-hardware-considerations)\n   - [3.3 System Requirements](#33-system-requirements)\n4. [Requirements](#4-requirements)\n   - [4.1 Hardware](#41-hardware)\n   - [4.2 Software](#42-software)\n   - [4.3 Environment Setup](#43-environment-setup)\n5. [Gathering Donor Device Information](#5-gathering-donor-device-information)\n   - [5.1 Using Arbor for PCIe Device Scanning](#51-using-arbor-for-pcie-device-scanning)\n   - [5.2 Extracting and Recording Device Attributes](#52-extracting-and-recording-device-attributes)\n6. [Initial Firmware Customization](#6-initial-firmware-customization)\n   - [6.1 Modifying Configuration Space](#61-modifying-configuration-space)\n   - [6.2 Inserting the Device Serial Number (DSN)](#62-inserting-the-device-serial-number-dsn)\n7. [Vivado Project Setup and Customization](#7-vivado-project-setup-and-customization)\n   - [7.1 Generating Vivado Project Files](#71-generating-vivado-project-files)\n   - [7.2 Modifying IP Blocks](#72-modifying-ip-blocks)\n\n### **Part 2: Intermediate Concepts and Implementation**\n\n8. [Advanced Firmware Customization](#8-advanced-firmware-customization)\n   - [8.1 Configuring PCIe Parameters for Emulation](#81-configuring-pcie-parameters-for-emulation)\n   - [8.2 Adjusting BARs and Memory Mapping](#82-adjusting-bars-and-memory-mapping)\n   - [8.3 Emulating Device Power Management and Interrupts](#83-emulating-device-power-management-and-interrupts)\n9. [Emulating Device-Specific Capabilities](#9-emulating-device-specific-capabilities)\n   - [9.1 Implementing Advanced PCIe Capabilities](#91-implementing-advanced-pcie-capabilities)\n   - [9.2 Emulating Vendor-Specific Features](#92-emulating-vendor-specific-features)\n10. [Transaction Layer Packet (TLP) Emulation](#10-transaction-layer-packet-tlp-emulation)\n    - [10.1 Understanding and Capturing TLPs](#101-understanding-and-capturing-tlps)\n    - [10.2 Crafting Custom TLPs for Specific Operations](#102-crafting-custom-tlps-for-specific-operations)\n\n### **Part 3: Advanced Techniques and Optimization**\n\n11. [Building, Flashing, and Testing](#11-building-flashing-and-testing)\n    - [11.1 Synthesis and Implementation](#111-synthesis-and-implementation)\n    - [11.2 Flashing the Bitstream](#112-flashing-the-bitstream)\n    - [11.3 Testing and Validation](#113-testing-and-validation)\n12. [Advanced Debugging Techniques](#12-advanced-debugging-techniques)\n    - [12.1 Using Vivado's Integrated Logic Analyzer](#121-using-vivados-integrated-logic-analyzer)\n    - [12.2 PCIe Traffic Analysis Tools](#122-pcie-traffic-analysis-tools)\n13. [Troubleshooting](#13-troubleshooting)\n    - [13.1 Device Detection Issues](#131-device-detection-issues)\n    - [13.2 Memory Mapping and BAR Configuration Errors](#132-memory-mapping-and-bar-configuration-errors)\n    - [13.3 DMA Performance and TLP Errors](#133-dma-performance-and-tlp-errors)\n14. [Emulation Accuracy and Optimizations](#14-emulation-accuracy-and-optimizations)\n    - [14.1 Techniques for Accurate Timing Emulation](#141-techniques-for-accurate-timing-emulation)\n    - [14.2 Dynamic Response to System Calls](#142-dynamic-response-to-system-calls)\n15. [Best Practices for Firmware Development](#15-best-practices-for-firmware-development)\n    - [15.1 Continuous Testing and Documentation](#151-continuous-testing-and-documentation)\n    - [15.2 Managing Firmware Versioning](#152-managing-firmware-versioning)\n    - [15.3 Security Considerations](#153-security-considerations)\n16. [Additional Resources](#16-additional-resources)\n17. [Contact Information](#17-contact-information)\n18. [Support and Contributions](#18-support-and-contributions)\n\n---\n\n## **Part 1: Foundational Concepts**\n\n---\n\n## **1. Introduction**\n\n### **1.1 Purpose of the Guide**\n\nThe primary purpose of this guide is to provide a step-by-step approach to developing custom Direct Memory Access (DMA) firmware for FPGA-based devices to emulate PCIe hardware accurately. This enables applications such as hardware testing, system debugging, security research, and hardware emulation.\n\nBy following this guide, you will learn how to:\n\n- Gather necessary information from a donor device.\n- Customize firmware to emulate a specific hardware device.\n- Set up the development environment using tools like Vivado and Visual Studio Code.\n- Understand key concepts related to PCIe and DMA operations.\n\n### **1.2 Target Audience**\n\nThis guide is intended for:\n\n- **Firmware Developers**: Engineers interested in creating custom firmware for hardware emulation, testing, or bypassing hardware restrictions.\n- **Hardware Engineers**: Professionals working on hardware testing and development who need to emulate specific devices.\n- **Security Researchers**: Individuals conducting vulnerability assessments, malware analysis, or security testing requiring hardware emulation.\n- **FPGA Enthusiasts**: Hobbyists and learners interested in FPGA customization and low-level hardware emulation.\n\n### **1.3 How to Use This Guide**\n\nThe guide is divided into three parts:\n\n- **Part 1: Foundational Concepts**: Covers the basic concepts, setup, and initial steps required to start firmware development for device emulation.\n- **Part 2: Intermediate Concepts and Implementation**: Delves into more complex topics such as advanced firmware customization, TLP emulation, and initial debugging techniques.\n- **Part 3: Advanced Techniques and Optimization**: Explores advanced debugging, troubleshooting, optimization strategies, and best practices.\n\nIt is recommended to follow the guide sequentially to build a solid understanding before tackling advanced topics.\n\n---\n\n## **2. Key Definitions**\n\nUnderstanding the terminology is crucial for effectively following this guide. Below are key definitions related to PCIe, DMA, and device emulation:\n\n- **DMA (Direct Memory Access)**: A capability that allows hardware devices to read from or write to system memory directly, without CPU intervention, enabling high-speed data transfers.\n- **TLP (Transaction Layer Packet)**: The fundamental unit of communication in the PCIe architecture, encapsulating control and data information.\n- **BAR (Base Address Register)**: Registers in PCIe devices that define memory and I/O address regions, mapping device memory into the system memory space.\n- **FPGA (Field-Programmable Gate Array)**: A reconfigurable integrated circuit that can be programmed to perform specific hardware functions.\n- **MSI/MSI-X (Message Signaled Interrupts)**: Mechanisms used by PCIe devices to send interrupts to the CPU without using traditional interrupt lines.\n- **Device Serial Number (DSN)**: A unique identifier associated with a specific device, often used for advanced device identification.\n- **PCIe Configuration Space**: A standardized memory area where PCIe devices provide information about themselves and configure operational parameters.\n- **Donor Device**: A PCIe hardware device used to extract configuration and identification details for the purpose of emulating its behavior on an FPGA.\n\n---\n\n## **3. Device Compatibility**\n\n### **3.1 Supported FPGA-Based Hardware**\n\nWhile this guide focuses on the **Squirrel DMA (35T)** card due to its accessibility, the methodologies are adaptable to other FPGA-based DMA hardware:\n\n- **Squirrel (35T)**\n  - **Description**: Affordable FPGA-based DMA device suitable for standard memory acquisition and device emulation.\n- **Enigma-X1 (75T)**\n  - **Description**: Mid-tier FPGA offering enhanced resources, ideal for more demanding memory operations.\n- **ZDMA (100T)**\n  - **Description**: High-performance FPGA optimized for rapid memory interactions, suitable for extensive memory reads/writes.\n- **Kintex-7**\n  - **Description**: Advanced FPGA with robust capabilities for complex projects and large-scale DMA solutions.\n\n### **3.2 PCIe Hardware Considerations**\n\nTo ensure smooth emulation, several PCIe-specific features must be addressed:\n\n- **IOMMU/VT-d Settings**\n  - **Recommendation**: Disable IOMMU (Intel's VT-d) or AMD's equivalent to allow unrestricted DMA access.\n  - **Rationale**: IOMMU can restrict DMA operations, potentially interfering with memory acquisition and emulation.\n- **Kernel DMA Protection**\n  - **Recommendation**: Disable Kernel DMA Protection features in modern systems.\n  - **Steps**:\n    - **Windows**: Disable features like Secure Boot or Virtualization-Based Security (VBS) in BIOS/UEFI settings.\n    - **Caution**: Disabling these features can expose the system to security risks; ensure you're operating in a secure environment.\n- **PCIe Slot Requirements**\n  - **Recommendation**: Use a compatible PCIe slot that matches the FPGA device's requirements (e.g., x1, x4).\n  - **Rationale**: Ensures optimal performance and compatibility with the host system.\n\n### **3.3 System Requirements**\n\n- **Host System**\n  - **Processor**: Multi-core CPU (Intel i5/i7 or AMD equivalent)\n  - **Memory**: Minimum 16 GB RAM\n  - **Storage**: SSD with at least 100 GB free space\n  - **Operating System**: Windows 10/11 (64-bit) or compatible Linux distribution\n- **Peripheral Devices**\n  - **JTAG Programmer**: For flashing firmware onto the FPGA\n  - **PCIe Slot**: Ensure the host system has an available PCIe slot compatible with the DMA card\n\n---\n\n## **4. Requirements**\n\n### **4.1 Hardware**\n\n- **Donor PCIe Device**\n  - **Purpose**: Source of device IDs and configuration data for emulation.\n  - **Examples**: Network adapters, storage controllers, or any generic PCIe card not in use.\n- **DMA FPGA Card**\n  - **Description**: FPGA-based device capable of performing DMA operations.\n  - **Examples**: Squirrel (35T), Enigma-X1 (75T), ZDMA (100T), Kintex-7\n- **JTAG Programmer**\n  - **Purpose**: For flashing firmware onto the FPGA.\n  - **Examples**: Xilinx Platform Cable USB II, Digilent JTAG-HS3\n\n### **4.2 Software**\n\n- **Xilinx Vivado Design Suite**\n  - **Description**: FPGA development software for synthesizing and building firmware projects.\n  - **Download**: [Xilinx Vivado](https://www.xilinx.com/support/download.html)\n- **Visual Studio Code**\n  - **Description**: Code editor for editing Verilog or VHDL code.\n  - **Download**: [Visual Studio Code](https://code.visualstudio.com/)\n- **PCILeech-FPGA**\n  - **Description**: Repository and base code for DMA firmware development.\n  - **Repository**: [PCILeech-FPGA on GitHub](https://github.com/ufrisk/pcileech-fpga)\n- **Arbor**\n  - **Description**: PCIe device scanning tool for gathering device information.\n  - **Download**: [Arbor by MindShare](https://www.mindshare.com/software/Arbor)\n  - **Note**: Requires account creation; offers a 14-day trial.\n- **Alternative Tools**\n  - **Telescan PE**\n    - **Description**: PCIe traffic analysis tool as an alternative to Arbor.\n    - **Download**: [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n    - **Note**: Free but requires manual registration approval.\n\n### **4.3 Environment Setup**\n\n#### **4.3.1 Install Xilinx Vivado Design Suite**\n\n- **Steps**:\n  1. Visit the [Xilinx Vivado Download Page](https://www.xilinx.com/support/download.html).\n  2. Download the appropriate version compatible with your FPGA device.\n  3. Run the installer and follow the on-screen instructions.\n  4. Select necessary components during installation.\n  5. Launch Vivado to ensure proper installation.\n\n#### **4.3.2 Install Visual Studio Code**\n\n- **Steps**:\n  1. Visit the [Visual Studio Code Download Page](https://code.visualstudio.com/).\n  2. Download and install for your operating system.\n  3. Install extensions for Verilog or VHDL support (e.g., **Verilog-HDL/SystemVerilog**).\n\n#### **4.3.3 Clone the PCILeech-FPGA Repository**\n\n- **Steps**:\n  1. Open a terminal or command prompt.\n  2. Navigate to your desired directory:\n     ```bash\n     cd ~/Projects/\n     ```\n  3. Clone the repository:\n     ```bash\n     git clone https://github.com/ufrisk/pcileech-fpga.git\n     ```\n  4. Navigate to the cloned directory:\n     ```bash\n     cd pcileech-fpga\n     ```\n\n#### **4.3.4 Set Up a Clean Development Environment**\n\n- **Recommendation**: Work in an isolated environment to prevent unintended interactions.\n- **Steps**:\n  1. Use a dedicated development machine or virtual machine.\n  2. Ensure no other applications interfere with PCIe operations or FPGA programming.\n\n---\n\n\n## **5. Gathering Donor Device Information**\n\nAccurate device emulation hinges on meticulously extracting and replicating critical information from the donor device. This comprehensive data collection enables your FPGA to faithfully mimic the target hardware's PCIe configuration and behavior, ensuring compatibility and functionality when interfacing with the host system.\n\n### **5.1 Using Arbor for PCIe Device Scanning**\n\n**Arbor** is a robust and user-friendly tool designed for in-depth scanning of PCIe devices. It provides detailed insights into the configuration space of connected hardware, making it an invaluable resource for extracting the necessary information for device emulation.\n\n#### **5.1.1 Install Arbor**\n\nTo begin utilizing Arbor for device scanning, you must first install the software on your system.\n\n**Steps:**\n\n1. **Visit the Arbor Download Page:**\n\n   - Navigate to the official [Arbor Download Page](https://www.mindshare.com/software/Arbor) using your preferred web browser.\n   - Ensure you are accessing the site directly to avoid any malicious redirects.\n\n2. **Create an Account (if required):**\n\n   - Arbor may require you to create a user account to access the download links.\n   - Provide the necessary information, such as your name, email address, and organization.\n   - Verify your email if prompted, to activate your account.\n\n3. **Download Arbor:**\n\n   - Once logged in, locate the download section for Arbor.\n   - Select the version compatible with your operating system (e.g., Windows 10/11 64-bit).\n   - Click the **Download** button and save the installer to a known location on your computer.\n\n4. **Install Arbor:**\n\n   - Locate the downloaded installer file (e.g., `ArborSetup.exe`).\n   - Right-click the installer and select **Run as administrator** to ensure it has the necessary permissions.\n   - Follow the on-screen instructions to complete the installation process.\n     - Accept the license agreement.\n     - Choose the installation directory.\n     - Opt to create desktop shortcuts if desired.\n\n5. **Verify Installation:**\n\n   - Upon completion, ensure that Arbor is listed in your Start Menu or on your desktop.\n   - Launch Arbor to confirm it opens without errors.\n\n#### **5.1.2 Scan PCIe Devices**\n\nWith Arbor installed, you can proceed to scan your system for connected PCIe devices.\n\n**Steps:**\n\n1. **Launch Arbor:**\n\n   - Double-click the Arbor icon on your desktop or find it via the Start Menu.\n   - If prompted by User Account Control (UAC), allow the application to make changes to your device.\n\n2. **Navigate to the Local System Tab:**\n\n   - In the Arbor interface, locate the navigation pane or tabs.\n   - Click on **Local System** to access tools for scanning the local machine.\n\n3. **Scan for PCIe Devices:**\n\n   - Look for a **Scan** or **Rescan** button, typically located at the top or bottom of the interface.\n   - Click **Scan/Rescan** to initiate the detection process.\n   - Wait for the scanning process to complete; this may take a few moments depending on the number of devices connected.\n\n4. **Review Detected Devices:**\n\n   - Once the scan is complete, Arbor will display a list of all detected PCIe devices.\n   - The devices are usually listed with their names, device IDs, and other identifying information.\n\n#### **5.1.3 Identify the Donor Device**\n\nIdentifying the correct donor device is crucial for accurate emulation.\n\n**Steps:**\n\n1. **Locate Your Donor Device in the List:**\n\n   - Scroll through the list of devices detected by Arbor.\n   - Look for the device matching the make and model of your donor hardware.\n   - Devices may be listed by their vendor names, device types, or function.\n\n2. **Verify Device Details:**\n\n   - Click on the device to select it.\n   - Confirm that the **Device ID** and **Vendor ID** match those of your donor device.\n     - **Tip:** These IDs are typically found in the device's documentation or on the manufacturer's website.\n\n3. **View Detailed Configuration:**\n\n   - With the device selected, find and click on an option like **View Details** or **Properties**.\n   - This will open a detailed view showing the device's configuration space and capabilities.\n\n4. **Cross-Reference with Physical Hardware:**\n\n   - If multiple similar devices are listed, cross-reference the **Slot Number** or **Bus Address** with the physical slot where the donor device is installed.\n\n#### **5.1.4 Capture Device Data**\n\nExtracting detailed information from the donor device is essential for accurate emulation.\n\n**Information to Extract:**\n\n- **Device ID (0xXXXX):**\n  - A 16-bit identifier unique to the device model.\n- **Vendor ID (0xYYYY):**\n  - A 16-bit identifier assigned to the manufacturer.\n- **Subsystem ID (0xZZZZ):**\n  - Identifies the specific subsystem or variant.\n- **Subsystem Vendor ID (0xWWWW):**\n  - Identifies the vendor of the subsystem.\n- **Revision ID (0xRR):**\n  - Indicates the revision level of the device.\n- **Class Code (0xCCCCCC):**\n  - A 24-bit code that defines the type of device (e.g., network controller, storage device).\n- **Base Address Registers (BARs):**\n  - Registers defining the memory or I/O space the device uses.\n  - Includes BAR0 through BAR5, each potentially 32 or 64 bits.\n- **Capabilities:**\n  - Lists supported features such as MSI/MSI-X, power management, PCIe link speed, and width.\n- **Device Serial Number (DSN):**\n  - A 64-bit unique identifier, if the device supports it.\n\n**Steps:**\n\n1. **Navigate to the PCI Config Tab:**\n\n   - Within the device's detailed view, find and select the **PCI Config** or **Configuration Space** tab.\n\n2. **Record Relevant Details:**\n\n   - Carefully document each of the required fields.\n   - Use screenshots or copy the values into a text file or spreadsheet for accuracy.\n   - Ensure hexadecimal values are noted correctly, including the `0x` prefix if used.\n\n3. **Expand Capability Lists:**\n\n   - Look for sections labeled **Capabilities** or **Advanced Features**.\n   - Document each capability and its parameters (e.g., MSI count, power states supported).\n\n4. **Examine BARs in Detail:**\n\n   - For each BAR, note:\n     - **BAR Number (e.g., BAR0):**\n     - **Type (Memory or I/O):**\n     - **Bit Width (32-bit or 64-bit):**\n     - **Size (e.g., 256 MB):**\n     - **Prefetchable Status (Yes/No):**\n\n5. **Save the Data for Reference:**\n\n   - Compile all the information into a well-organized document.\n   - Label each section clearly for easy reference during firmware customization.\n\n6. **Double-Check Entries:**\n\n   - Review all recorded data to ensure accuracy.\n   - Correct any discrepancies by revisiting the Arbor interface.\n\n### **5.2 Extracting and Recording Device Attributes**\n\nAfter capturing the data, it's crucial to understand the significance of each attribute and ensure they've been accurately documented.\n\n**Ensure You Have Accurately Recorded the Following:**\n\n1. **Device ID:**\n\n   - **Purpose:** Uniquely identifies the device model.\n   - **Usage:** Essential for the host OS to load the correct driver.\n\n2. **Vendor ID:**\n\n   - **Purpose:** Identifies the manufacturer.\n   - **Usage:** Used in conjunction with Device ID to match device drivers.\n\n3. **Subsystem ID and Subsystem Vendor ID:**\n\n   - **Purpose:** Specifies the subsystem's device and vendor IDs, allowing for differentiation between variants.\n   - **Usage:** Important for devices with multiple configurations or OEM-specific versions.\n\n4. **Revision ID:**\n\n   - **Purpose:** Indicates the hardware revision.\n   - **Usage:** Helps in identifying specific hardware versions that may require different drivers or firmware.\n\n5. **Class Code:**\n\n   - **Purpose:** Categorizes the device type (e.g., mass storage, network controller).\n   - **Usage:** Allows the OS to understand the device's general function.\n\n6. **Base Address Registers (BARs):**\n\n   - **Purpose:** Define the memory or I/O address regions that the device will use.\n   - **Usage:** Critical for mapping device memory into the system address space.\n\n7. **Capabilities:**\n\n   - **Purpose:** Lists the advanced features the device supports.\n   - **Examples:**\n     - **MSI/MSI-X:** Message Signaled Interrupts for efficient interrupt handling.\n     - **Power Management:** States like D0, D1, D2, D3hot, D3cold.\n     - **PCIe Link Speed/Width:** Determines the data transfer capabilities.\n\n8. **Device Serial Number (DSN):**\n\n   - **Purpose:** A unique 64-bit identifier for the device.\n   - **Usage:** Used for advanced identification and may be required by some drivers.\n\n**Best Practices:**\n\n- **Organize the Data:**\n\n  - Create a structured document or spreadsheet.\n  - Use clear headings and subheadings for each attribute.\n\n- **Include Units and Formats:**\n\n  - Indicate units for sizes (e.g., MB, KB).\n  - Use consistent formatting for hexadecimal values (e.g., `0x1234`).\n\n- **Cross-Reference with Specifications:**\n\n  - If available, consult the device's datasheet to verify values.\n  - This can help identify any discrepancies or unusual configurations.\n\n- **Secure the Data:**\n\n  - Store the collected information securely.\n  - Be mindful of any proprietary or confidential information.\n\n---\n\n## **6. Initial Firmware Customization**\n\nWith the donor device's information meticulously documented, the next phase involves customizing your FPGA's firmware to emulate the donor device accurately. This involves modifying the PCIe configuration space and ensuring that memory mappings align correctly.\n\n### **6.1 Modifying Configuration Space**\n\nThe PCIe configuration space is a critical component that defines how the device is recognized and interacts with the host system. Customizing this space to match the donor device is essential for successful emulation.\n\n#### **6.1.1 Navigate to the Configuration File**\n\nThe configuration space is defined within a specific SystemVerilog (.sv) file in your project.\n\n**Path:**\n\n- **Standard Path:**\n  ```\n  pcileech-fpga/pcileech-wifi-main/src/pcie_7x_0_core_top.v\n  ```\n\n- **Alternative Path (Depending on Directory Structure):**\n  ```\n  src\\pcie_7x\\pcie_7x_0_core_top.v\n  ```\n\n#### **6.1.2 Open the File in Visual Studio Code**\n\nEditing the configuration file requires a suitable code editor that supports syntax highlighting for SystemVerilog.\n\n**Steps:**\n\n1. **Launch Visual Studio Code:**\n\n   - Click on the VS Code icon or find it via the Start Menu.\n\n2. **Open the File:**\n\n   - Use **File > Open File** or press `Ctrl + O`.\n   - Navigate to the configuration file path mentioned above.\n   - Select `pcileech_pcie_cfg_a7.sv` and click **Open**.\n\n3. **Verify Syntax Highlighting:**\n\n   - Ensure that the editor recognizes the `.sv` file extension.\n   - If necessary, install extensions for SystemVerilog support.\n\n4. **Familiarize Yourself with the File Structure:**\n\n   - Scroll through the file to understand the existing assignments and comments.\n   - Look for sections where configuration registers are defined.\n\n#### **6.1.3 Modify Device ID and Vendor ID**\n\nUpdating these identifiers is crucial for the host system to recognize the emulated device as the donor.\n\n**Steps:**\n\n1. **Search for `cfg_deviceid`:**\n\n   - Use the search functionality (`Ctrl + F`).\n   - Locate the line defining `cfg_deviceid`.\n\n2. **Update Device ID:**\n\n   ```verilog\n   cfg_deviceid <= 16'hXXXX;  // Replace XXXX with the donor's Device ID\n   ```\n\n   - **Example:**\n     - If the donor's Device ID is `0x1234`, update as:\n       ```verilog\n       cfg_deviceid <= 16'h1234;\n       ```\n\n3. **Search for `cfg_vendorid`:**\n\n   - Locate the line defining `cfg_vendorid`.\n\n4. **Update Vendor ID:**\n\n   ```verilog\n   cfg_vendorid <= 16'hYYYY;  // Replace YYYY with the donor's Vendor ID\n   ```\n\n   - **Example:**\n     - If the donor's Vendor ID is `0xABCD`, update as:\n       ```verilog\n       cfg_vendorid <= 16'hABCD;\n       ```\n\n5. **Ensure Correct Formatting:**\n\n   - Verify that hexadecimal values are prefixed with `16'h`.\n   - Maintain consistent indentation and commenting style.\n\n#### **6.1.4 Modify Subsystem ID and Revision ID**\n\nThese identifiers provide additional details about the device variant and hardware revision.\n\n**Steps:**\n\n1. **Search for `cfg_subsysid`:**\n\n   - Locate the line defining `cfg_subsysid`.\n\n2. **Update Subsystem ID:**\n\n   ```verilog\n   cfg_subsysid <= 16'hZZZZ;  // Replace ZZZZ with the donor's Subsystem ID\n   ```\n\n   - **Example:**\n     - If the donor's Subsystem ID is `0x5678`, update as:\n       ```verilog\n       cfg_subsysid <= 16'h5678;\n       ```\n\n3. **Search for `cfg_subsysvendorid`:**\n\n   - Locate the line defining `cfg_subsysvendorid`.\n\n4. **Update Subsystem Vendor ID (if applicable):**\n\n   ```verilog\n   cfg_subsysvendorid <= 16'hWWWW;  // Replace WWWW with the donor's Subsystem Vendor ID\n   ```\n\n   - **Example:**\n     - If the donor's Subsystem Vendor ID is `0x9ABC`, update as:\n       ```verilog\n       cfg_subsysvendorid <= 16'h9ABC;\n       ```\n\n5. **Search for `cfg_revisionid`:**\n\n   - Locate the line defining `cfg_revisionid`.\n\n6. **Update Revision ID:**\n\n   ```verilog\n   cfg_revisionid <= 8'hRR;   // Replace RR with the donor's Revision ID\n   ```\n\n   - **Example:**\n     - If the donor's Revision ID is `0x01`, update as:\n       ```verilog\n       cfg_revisionid <= 8'h01;\n       ```\n\n#### **6.1.5 Update Class Code**\n\nThe Class Code informs the host of the device type and function.\n\n**Steps:**\n\n1. **Search for `cfg_classcode`:**\n\n   - Locate the line defining `cfg_classcode`.\n\n2. **Update Class Code:**\n\n   ```verilog\n   cfg_classcode <= 24'hCCCCCC;  // Replace CCCCCC with the donor's Class Code\n   ```\n\n   - **Example:**\n     - If the donor's Class Code is `0x020000` (Ethernet Controller), update as:\n       ```verilog\n       cfg_classcode <= 24'h020000;\n       ```\n\n3. **Verify Correct Bit Width:**\n\n   - Ensure that the Class Code is a 24-bit value.\n   - Hexadecimal values should be prefixed with `24'h`.\n\n#### **6.1.6 Save Changes**\n\nAfter making all modifications, it's important to save and review the changes.\n\n**Steps:**\n\n1. **Save the File:**\n\n   - Click **File > Save** or press `Ctrl + S`.\n\n2. **Review Changes:**\n\n   - Re-read the modified lines to confirm accuracy.\n   - Check for any syntax errors or typos.\n\n3. **Optional - Use Version Control:**\n\n   - If using Git or another version control system, commit your changes with a meaningful message.\n     - **Example:**\n       ```\n       git add pcileech_pcie_cfg_a7.sv\n       git commit -m \"Updated PCIe configuration with donor device identifiers\"\n       ```\n\n### **6.2 Inserting the Device Serial Number (DSN)**\n\nThe Device Serial Number (DSN) is a unique identifier that some devices utilize for advanced features. Including it enhances the authenticity of the emulation.\n\n#### **6.2.1 Locate the DSN Field**\n\nThe DSN is typically defined in the same configuration file.\n\n**Steps:**\n\n1. **Search for `cfg_dsn`:**\n\n   - In `pcileech_pcie_cfg_a7.sv`, use the search function (`Ctrl + F`) to find `cfg_dsn`.\n\n2. **Understand the Existing Assignment:**\n\n   - The DSN may be set to a default value or zeroed out.\n     ```verilog\n     cfg_dsn <= 64'h0000000000000000;  // Default DSN\n     ```\n\n#### **6.2.2 Insert the DSN**\n\nUpdating the DSN involves setting it to the exact value from the donor device.\n\n**Steps:**\n\n1. **Update `cfg_dsn`:**\n\n   ```verilog\n   cfg_dsn <= 64'hXXXXXXXX_YYYYYYYY;  // Replace with donor DSN\n   ```\n\n   - **Example:**\n     - If the donor's DSN is `0x0011223344556677`, update as:\n       ```verilog\n       cfg_dsn <= 64'h0011223344556677;\n       ```\n\n2. **Handle DSN Unavailability:**\n\n   - If the donor device does not have a DSN or it is not required, set it to zero:\n     ```verilog\n     cfg_dsn <= 64'h0000000000000000;  // No DSN\n     ```\n\n3. **Ensure Correct Formatting:**\n\n   - The DSN is a 64-bit value; ensure it's properly formatted.\n   - Use the `64'h` prefix for hexadecimal values.\n\n4. **Add Comments for Clarity:**\n\n   - Include a comment indicating the DSN source.\n     ```verilog\n     cfg_dsn <= 64'h0011223344556677;  // Donor DSN\n     ```\n\n#### **6.2.3 Save Changes**\n\nFinalize the modifications by saving and reviewing.\n\n**Steps:**\n\n1. **Save the File:**\n\n   - Click **File > Save** or press `Ctrl + S`.\n\n2. **Verify the Syntax:**\n\n   - Look for any red underlines or error indications in the editor.\n   - Correct any issues before proceeding.\n\n3. **Document the Changes:**\n\n   - If using version control, commit the updates with an appropriate message.\n     - **Example:**\n       ```\n       git commit -am \"Inserted donor Device Serial Number (DSN) into configuration\"\n       ```\n\n---\n\n## **7. Vivado Project Setup and Customization**\n\nWith the firmware files updated to reflect the donor device's configuration, the next step is to integrate these changes into the Vivado project. This involves generating the project files, customizing IP cores, and preparing the design for synthesis and implementation.\n\n### **7.1 Generating Vivado Project Files**\n\nVivado uses Tcl scripts to automate project creation and configuration. By running these scripts, you ensure that all settings are correctly applied based on your FPGA device.\n\n#### **7.1.1 Open Vivado**\n\nStarting with a fresh session of Vivado ensures that previous settings or projects do not interfere with your current work.\n\n**Steps:**\n\n1. **Launch Vivado:**\n\n   - Find the Vivado application in your Start Menu or desktop.\n   - Click to open it.\n\n2. **Select the Correct Version:**\n\n   - If multiple versions are installed, ensure you are using the one compatible with your FPGA (e.g., Vivado 2020.1).\n\n3. **Wait for the Startup Screen:**\n\n   - Allow Vivado to fully initialize before proceeding.\n\n#### **7.1.2 Access the Tcl Console**\n\nThe Tcl Console allows you to execute scripts and commands directly.\n\n**Steps:**\n\n1. **Open the Tcl Console:**\n\n   - In the Vivado interface, go to the menu bar.\n   - Click on **Window** > **Tcl Console**.\n   - The Tcl Console will appear at the bottom of the window.\n\n2. **Adjust Console Size (Optional):**\n\n   - Drag the console's top border to resize it for better visibility.\n\n3. **Clear Previous Commands:**\n\n   - If any commands are present, you can clear them for a clean start.\n\n#### **7.1.3 Navigate to the Project Directory**\n\nEnsure that the Tcl Console is pointing to the correct directory where your project scripts are located.\n\n**For Squirrel DMA (35T):**\n\n**Path:**\n\n- Your project directory, typically:\n  ```\n  C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-wifi-main/\n  ```\n\n**Steps:**\n\n1. **Set the Working Directory:**\n\n   - In the Tcl Console, enter:\n     ```tcl\n     cd C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-wifi-main/\n     ```\n     - Replace the path with the actual location on your system.\n\n2. **Verify the Directory Change:**\n\n   - Enter `pwd` in the Tcl Console.\n   - The console should display the current directory, confirming the change.\n\n#### **7.1.4 Generate the Vivado Project**\n\nRunning the appropriate Tcl script will set up the project with all necessary configurations.\n\n**Steps:**\n\n1. **Run the Tcl Script:**\n\n   - For **Squirrel (35T)**:\n     ```tcl\n     source vivado_generate_project_squirrel.tcl -notrace\n     ```\n   - For **Enigma-X1 (75T)**:\n     ```tcl\n     source vivado_generate_project_enigma_x1.tcl -notrace\n     ```\n   - For **ZDMA (100T)**:\n     ```tcl\n     source vivado_generate_project_100t.tcl -notrace\n     ```\n\n2. **Wait for Script Completion:**\n\n   - The script will execute several commands:\n     - Create the project.\n     - Add source files.\n     - Configure project settings.\n   - Monitor the Tcl Console for progress messages.\n   - Address any errors that may occur, such as missing files or incorrect paths.\n\n3. **Confirm Project Generation:**\n\n   - Upon completion, the console will indicate that the project has been created.\n   - The project files (`.xpr` and associated directories) will be present in the project directory.\n\n#### **7.1.5 Open the Generated Project**\n\nNow that the project is generated, you can open it within Vivado for further customization.\n\n**Steps:**\n\n1. **Open the Project:**\n\n   - In Vivado, click **File** > **Open Project**.\n   - Navigate to your project directory.\n\n2. **Select the Project File:**\n\n   - For **Squirrel**:\n     ```\n     pcileech_squirrel_top.xpr\n     ```\n   - Click on the `.xpr` file to select it.\n\n3. **Click Open:**\n\n   - Vivado will load the project, displaying the design hierarchy and sources.\n\n4. **Verify Project Contents:**\n\n   - In the **Project Manager** window, ensure that all source files are listed.\n   - Check for any warnings or errors upon opening.\n\n### **7.2 Modifying IP Blocks**\n\nThe PCIe IP core is a critical component that must be configured to match the donor device's specifications. Customizing the IP core ensures that the FPGA behaves identically to the donor hardware at the PCIe protocol level.\n\n#### **7.2.1 Access the PCIe IP Core**\n\nThe PCIe IP core is an instantiated IP block within your Vivado project.\n\n**Steps:**\n\n1. **Locate the PCIe IP Core:**\n\n   - In the **Sources** pane, ensure the **Hierarchy** tab is selected.\n   - Expand the design hierarchy to find the PCIe IP core.\n     - It is typically named `pcie_7x_0.xci` or similar.\n\n2. **Open the IP Customization Window:**\n\n   - Right-click on `pcie_7x_0.xci`.\n   - Select **Customize IP** from the context menu.\n   - The **IP Configuration** window will open.\n\n3. **Wait for IP Settings to Load:**\n\n   - The IP customization interface may take a few moments to initialize.\n   - Ensure that all options and tabs are fully loaded before proceeding.\n\n#### **7.2.2 Customize Device IDs and BARs**\n\nConfiguring the device identifiers within the IP core is crucial for correct enumeration by the host system.\n\n**Steps:**\n\n1. **Navigate to Device and Vendor Identifiers:**\n\n   - In the IP customization window, select the **Device and Vendor Identifiers** tab or section.\n\n2. **Enter the Device ID:**\n\n   - Find the field labeled **Device ID**.\n   - Enter the donor's Device ID (e.g., `0x1234`).\n\n3. **Enter the Vendor ID:**\n\n   - Locate the **Vendor ID** field.\n   - Input the donor's Vendor ID (e.g., `0xABCD`).\n\n4. **Enter the Subsystem ID and Subsystem Vendor ID:**\n\n   - Input the **Subsystem ID** (e.g., `0x5678`).\n   - Input the **Subsystem Vendor ID** (e.g., `0x9ABC`).\n\n5. **Set the Revision ID:**\n\n   - Enter the **Revision ID** (e.g., `0x01`).\n\n6. **Set the Class Code:**\n\n   - Enter the **Class Code** (e.g., `0x020000` for Ethernet Controller).\n\n7. **Configure Other Identifiers (if available):**\n\n   - Some IP cores allow setting **Programming Interface**, **Device Capabilities**, etc.\n   - Match these to the donor device as needed.\n\n#### **7.2.3 Configure BAR Sizes**\n\nThe BARs define how the device maps its internal memory and registers to the host system.\n\n**Steps:**\n\n1. **Navigate to Base Address Registers (BARs):**\n\n   - Select the **BARs** tab or section in the IP customization window.\n\n2. **Configure Each BAR:**\n\n   - For **BAR0** to **BAR5**, set the following parameters based on the donor device:\n     - **Enable BAR**: Check or uncheck to match donor device.\n     - **BAR Size**: Select the size from the dropdown (e.g., **256 MB**, **64 KB**).\n     - **BAR Type**:\n       - **Memory (32-bit Addressing)**\n       - **Memory (64-bit Addressing)**\n       - **I/O**\n     - **Prefetchable**: Check if the donor's BAR is prefetchable.\n\n3. **Example Configuration:**\n\n   - **BAR0**:\n     - Enabled\n     - Size: **256 MB**\n     - Type: **Memory (64-bit)**\n     - Prefetchable: **Yes**\n   - **BAR1**:\n     - Disabled (if the donor device does not use BAR1)\n\n4. **Ensure Alignment and Non-Overlapping Spaces:**\n\n   - Verify that the total memory mapped does not exceed the FPGA's capabilities.\n   - Ensure that BAR sizes align with PCIe specification requirements.\n\n5. **Advanced Settings (if applicable):**\n\n   - Some devices may have special requirements, such as expansion ROM BAR.\n   - Configure these settings if necessary.\n\n#### **7.2.4 Finalize IP Customization**\n\nAfter configuring all necessary settings, you need to apply the changes.\n\n**Steps:**\n\n1. **Review All Settings:**\n\n   - Go through each tab in the IP customization window.\n   - Confirm that all entries match the donor device's specifications.\n\n2. **Apply Changes:**\n\n   - Click **OK** or **Generate** to apply the settings.\n   - If prompted, confirm that you wish to proceed with the changes.\n\n3. **Regenerate IP Core:**\n\n   - Vivado will regenerate the IP core to reflect the new configurations.\n   - Monitor the **Messages** pane for any errors or warnings.\n\n4. **Update IP in Project:**\n\n   - Ensure that the updated IP core is correctly integrated into your project.\n   - Vivado may prompt to update IP dependencies; allow it to do so.\n\n#### **7.2.5 Lock the IP Core**\n\nLocking the IP core prevents unintended changes during synthesis and implementation.\n\n**Purpose:**\n\n- **Prevent Overwrites:** Ensures that your manual configurations are preserved.\n- **Maintain Consistency:** Keeps the IP core in a known state throughout the build process.\n\n**Steps:**\n\n1. **Open the Tcl Console:**\n\n   - In Vivado, if not already open, go to **Window** > **Tcl Console**.\n\n2. **Execute the Lock Command:**\n\n   - Enter the following command:\n     ```tcl\n     set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n     ```\n   - Press **Enter** to execute.\n\n3. **Verify the Lock:**\n\n   - Check the **Messages** pane for confirmation.\n   - The IP core should now be marked as locked.\n\n4. **Unlocking (if necessary):**\n\n   - To make further changes in the future, you can unlock the IP core:\n     ```tcl\n     set_property -name {IP_LOCKED} -value false -objects [get_ips pcie_7x_0]\n     ```\n   - Remember to re-lock it after making changes.\n\n5. **Document the Action:**\n\n   - Note in your project documentation that the IP core has been locked.\n   - This helps team members understand the project's configuration state.\n\n---\n\n## **Part 2: Intermediate Concepts and Implementation**\n\n---\n\n## **8. Advanced Firmware Customization**\n\nTo achieve a precise emulation of the donor device, further in-depth customization of the firmware is necessary. This involves aligning the PCIe parameters, adjusting Base Address Registers (BARs), and emulating power management and interrupt mechanisms to match the donor device's specifications. These steps ensure that the emulated device interacts seamlessly with the host system and behaves identically to the original hardware.\n\n### **8.1 Configuring PCIe Parameters for Emulation**\n\nAccurate emulation requires that the PCIe parameters of your FPGA device are meticulously configured to match those of the donor device. This includes settings such as the PCIe link speed, link width, capability pointers, and maximum payload sizes. Proper configuration ensures compatibility with the host system and the correct operation of drivers and applications that interact with the device.\n\n#### **8.1.1 Matching PCIe Link Speed and Width**\n\nThe PCIe link speed and width are critical parameters that determine the data throughput and performance of the device. Matching these settings with the donor device is essential for accurate emulation.\n\n**Steps:**\n\n1. **Access PCIe IP Core Settings:**\n\n   - **Open Your Vivado Project:**\n     - Launch Vivado and open the project you previously created or modified.\n     - Ensure that all source files are correctly added to the project.\n\n   - **Locate the PCIe IP Core:**\n     - In the **Sources** pane, expand the hierarchy to find the PCIe IP core instance, typically named `pcie_7x_0`.\n     - The file associated with the IP core is usually `pcie_7x_0.xci`.\n\n   - **Customize the IP Core:**\n     - Right-click on `pcie_7x_0.xci` and select **Customize IP**.\n     - The IP customization window will open, displaying various configuration options.\n\n2. **Set Maximum Link Speed:**\n\n   - **Navigate to Link Parameters:**\n     - In the IP customization window, click on the **Link Parameters** tab or section.\n     - This section contains settings related to the PCIe link's characteristics.\n\n   - **Configure Maximum Link Speed:**\n     - Find the **Maximum Link Speed** option.\n     - Set it to match the donor device's link speed.\n       - **Example:**\n         - If the donor device operates at **Gen2 (5.0 GT/s)**, select **5.0 GT/s**.\n         - If it operates at **Gen1 (2.5 GT/s)** or **Gen3 (8.0 GT/s)**, select the corresponding option.\n     - **Note:** Ensure that your FPGA and the physical hardware support the selected link speed.\n\n3. **Set Link Width:**\n\n   - **Configure Link Width:**\n     - In the same **Link Parameters** section, locate the **Link Width** setting.\n     - Set it to match the donor device's link width.\n       - **Example:**\n         - If the donor device uses a **x4** link, set the **Link Width** to **4**.\n         - Options typically include **1**, **2**, **4**, **8**, **16** lanes.\n     - **Note:** The physical connectors and the FPGA must support the selected link width.\n\n4. **Save and Regenerate:**\n\n   - **Apply Changes:**\n     - After configuring the link speed and width, click **OK** to apply the changes.\n     - Vivado may prompt you to regenerate the IP core due to the changes made.\n     - Confirm and allow the regeneration process to complete.\n\n   - **Verify Settings:**\n     - Once regeneration is complete, revisit the IP core settings to ensure the configurations are correctly applied.\n     - Check for any warnings or errors in the **Messages** window.\n\n#### **8.1.2 Setting Capability Pointers**\n\nCapability pointers in the PCIe configuration space point to various capability structures, such as MSI, power management, and others. Correctly setting these pointers ensures that the host system can locate and utilize the device's capabilities.\n\n**Steps:**\n\n1. **Locate Capability Pointer in Firmware:**\n\n   - **Open Configuration File:**\n     - In Visual Studio Code, open the `pcileech_pcie_cfg_a7.sv` file located at:\n       ```\n       pcileech-fpga/pcileech-wifi-main/src/pcileech_pcie_cfg_a7.sv\n       ```\n\n   - **Understand the Capability Pointer:**\n     - The capability pointer is an 8-bit register that points to the first capability structure in the PCIe configuration space, usually starting after the standard configuration header.\n\n2. **Set Capability Pointer Value:**\n\n   - **Find the Assignment for `cfg_cap_pointer`:**\n     - Search for the line in the code where `cfg_cap_pointer` is assigned.\n       ```verilog\n       cfg_cap_pointer <= 8'hXX; // Current value\n       ```\n\n   - **Update the Capability Pointer:**\n     - Replace `XX` with the donor device's capability pointer value.\n       - **Example:**\n         - If the donor device's capability pointer is `0x60`, update the line to:\n           ```verilog\n           cfg_cap_pointer <= 8'h60; // Updated to match donor device\n           ```\n\n   - **Ensure Correct Alignment:**\n     - Capability structures must be aligned on a 4-byte boundary.\n     - The capability pointer should point to a valid offset within the configuration space.\n\n3. **Save Changes:**\n\n   - **Save the Configuration File:**\n     - After making the changes, save the file by clicking **File > Save** or pressing `Ctrl + S`.\n\n   - **Verify Syntax:**\n     - Ensure there are no syntax errors introduced by the changes.\n\n   - **Comment for Clarity:**\n     - Add a comment explaining the change for future reference.\n       ```verilog\n       cfg_cap_pointer <= 8'h60; // Set to donor's capability pointer at offset 0x60\n       ```\n\n#### **8.1.3 Adjusting Maximum Payload and Read Request Sizes**\n\nThese parameters define the maximum amount of data that can be transferred in a single PCIe transaction. Matching these settings with the donor device ensures compatibility and optimal performance.\n\n**Steps:**\n\n1. **Set Maximum Payload Size:**\n\n   - **Access Device Capabilities:**\n     - In the PCIe IP core customization window, navigate to the **Device Capabilities** or **Capabilities** tab.\n\n   - **Configure Max Payload Size Supported:**\n     - Find the **Max Payload Size Supported** setting.\n     - Set it to the value supported by the donor device.\n       - **Options:**\n         - **128 bytes**, **256 bytes**, **512 bytes**, **1024 bytes**, **2048 bytes**, **4096 bytes**.\n       - **Example:**\n         - If the donor device supports a maximum payload size of **256 bytes**, select **256 bytes**.\n\n2. **Set Maximum Read Request Size:**\n\n   - **Configure Max Read Request Size Supported:**\n     - In the same tab, find the **Max Read Request Size Supported** setting.\n     - Set it to match the donor device's capability.\n       - **Example:**\n         - If the donor supports a maximum read request size of **512 bytes**, select **512 bytes**.\n\n3. **Adjust Firmware Parameters:**\n\n   - **Open `pcileech_pcie_cfg_a7.sv`:**\n     - Ensure that the configuration file is open in Visual Studio Code.\n\n   - **Update Firmware Constants:**\n     - Locate the lines where `max_payload_size_supported` and `max_read_request_size_supported` are defined.\n       ```verilog\n       max_payload_size_supported <= 3'bZZZ; // Current value\n       max_read_request_size_supported <= 3'bWWW; // Current value\n       ```\n\n   - **Set the Appropriate Values:**\n     - Replace `ZZZ` and `WWW` with the binary representations of the sizes.\n       - **Mapping:**\n         - **128 bytes**: `3'b000`\n         - **256 bytes**: `3'b001`\n         - **512 bytes**: `3'b010`\n         - **1024 bytes**: `3'b011`\n         - **2048 bytes**: `3'b100`\n         - **4096 bytes**: `3'b101`\n       - **Example:**\n         - For **256 bytes** payload size:\n           ```verilog\n           max_payload_size_supported <= 3'b001; // Supports up to 256 bytes\n           ```\n         - For **512 bytes** read request size:\n           ```verilog\n           max_read_request_size_supported <= 3'b010; // Supports up to 512 bytes\n           ```\n\n4. **Save Changes:**\n\n   - **Save the File:**\n     - After updating the values, save the file.\n\n   - **Verify Consistency:**\n     - Ensure that the values in the firmware match those configured in the PCIe IP core.\n\n   - **Add Comments:**\n     - Document the changes for future reference.\n       ```verilog\n       max_payload_size_supported <= 3'b001; // 256 bytes as per donor device\n       max_read_request_size_supported <= 3'b010; // 512 bytes as per donor device\n       ```\n\n### **8.2 Adjusting BARs and Memory Mapping**\n\nBase Address Registers (BARs) define the memory regions that the device exposes to the host. Correctly configuring the BARs and memory mapping is crucial for accurate emulation and proper operation of device drivers.\n\n#### **8.2.1 Setting BAR Sizes**\n\nConfiguring the BAR sizes ensures that the device requests the correct amount of address space during enumeration and that the host maps these regions appropriately.\n\n**Steps:**\n\n1. **Access BAR Configuration:**\n\n   - **Customize PCIe IP Core:**\n     - In Vivado, right-click on `pcie_7x_0.xci` and select **Customize IP**.\n\n   - **Navigate to BARs Tab:**\n     - In the IP customization window, click on the **Base Address Registers (BARs)** tab.\n\n2. **Configure BAR Sizes and Types:**\n\n   - **Match Donor Device's BARs:**\n     - For each BAR (BAR0 to BAR5), set the size and type to match the donor device.\n\n   - **Set BAR Sizes:**\n     - Select the appropriate size from the dropdown for each BAR.\n       - **Example:**\n         - If **BAR0** is **64 KB**, set **BAR0 Size** to **64 KB**.\n         - If **BAR1** is **128 MB**, set **BAR1 Size** to **128 MB**.\n\n   - **Set BAR Types:**\n     - Choose between **32-bit** or **64-bit** addressing for each BAR.\n     - Specify if the BAR is of type **Memory** or **I/O**.\n     - Set **Prefetchable** status based on the donor device.\n\n   - **Enable or Disable BARs:**\n     - Ensure that only the BARs used by the donor device are enabled.\n\n3. **Update BRAM Configurations:**\n\n   - **Adjust BRAM IP Cores:**\n     - In the `ip` directory, locate the BRAM configurations corresponding to the BARs.\n       - **Files:**\n         ```\n         pcileech-fpga/pcileech-wifi-main/ip/bram_bar_zero4k.xci\n         pcileech-fpga/pcileech-wifi-main/ip/bram_pcie_cfgspace.xci\n         ```\n\n   - **Modify BRAM Sizes:**\n     - Open each BRAM IP core and adjust the memory size to match the corresponding BAR size.\n     - Ensure that the total memory does not exceed the FPGA's capacity.\n\n4. **Save and Regenerate:**\n\n   - **Apply Changes:**\n     - After configuring the BARs and updating BRAM sizes, click **OK** in the IP customization window.\n\n   - **Regenerate IP Cores:**\n     - Vivado may prompt you to regenerate the IP cores due to the changes.\n     - Allow the regeneration to complete.\n\n   - **Check for Errors:**\n     - Review the **Messages** window for any warnings or errors related to BAR configurations.\n\n#### **8.2.2 Defining BAR Address Spaces in Firmware**\n\nWith the BAR sizes and types set, you need to define how the firmware handles accesses to these BARs.\n\n**Steps:**\n\n1. **Open the BAR Controller File:**\n\n   - **Locate the Source File:**\n     - In Visual Studio Code, open:\n       ```\n       pcileech-fpga/pcileech-wifi-main/src/pcileech_tlps128_bar_controller.sv\n       ```\n\n2. **Map Address Ranges:**\n\n   - **Define Address Decoding Logic:**\n     - Implement logic to detect when a BAR is accessed based on the address.\n       ```verilog\n       always_comb begin\n         if (bar_hit[0]) begin\n           // Handle accesses to BAR0\n         end else if (bar_hit[1]) begin\n           // Handle accesses to BAR1\n         end\n         // Continue for additional BARs\n       end\n       ```\n\n   - **Implement BAR Access Handling:**\n     - For each BAR, define how reads and writes are managed.\n       - **Example:**\n         ```verilog\n         if (bar_hit[0]) begin\n           case (addr_offset)\n             16'h0000: data_out <= reg0;\n             16'h0004: data_out <= reg1;\n             // Additional registers\n             default: data_out <= 32'h0;\n           endcase\n         end\n         ```\n\n3. **Implement Address Decoding Logic:**\n\n   - **Calculate Address Offsets:**\n     - Use the incoming address to calculate offsets within the BAR.\n       ```verilog\n       addr_offset = incoming_address - bar_base_address[0];\n       ```\n\n   - **Handle Data Transfers:**\n     - Implement logic for read and write operations.\n       ```verilog\n       if (cfg_write) begin\n         // Write data to the appropriate register\n       end else if (cfg_read) begin\n         // Read data from the appropriate register\n       end\n       ```\n\n4. **Save Changes:**\n\n   - **Save the File:**\n     - After implementing the logic, save the `pcileech_tlps128_bar_controller.sv` file.\n\n   - **Verify Functionality:**\n     - Ensure that the logic correctly handles all possible accesses.\n\n#### **8.2.3 Handling Multiple BARs**\n\nProperly managing multiple BARs is essential for devices that expose multiple memory or I/O regions.\n\n**Steps:**\n\n1. **Implement Logic for Each BAR:**\n\n   - **Separate Logic Blocks:**\n     - For clarity, create separate code blocks for each BAR within the controller.\n       ```verilog\n       // BAR0 Handling\n       if (bar_hit[0]) begin\n         // BAR0 specific logic\n       end\n       // BAR1 Handling\n       if (bar_hit[1]) begin\n         // BAR1 specific logic\n       end\n       ```\n\n   - **Define Registers and Memories:**\n     - Allocate registers or memory blocks for each BAR as needed.\n\n2. **Ensure Non-Overlapping Address Spaces:**\n\n   - **Validate Address Ranges:**\n     - Confirm that the address spaces for each BAR do not overlap.\n     - Align BAR sizes to power-of-two boundaries as per PCIe specifications.\n\n   - **Update Address Decoding:**\n     - Adjust the address decoding logic to account for the sizes and bases of each BAR.\n\n3. **Test BAR Accesses:**\n\n   - **Simulation Testing:**\n     - Use simulation tools to test read and write operations to each BAR.\n     - Verify that the correct data is read or written.\n\n   - **Hardware Testing:**\n     - After programming the FPGA, use software tools on the host to access each BAR.\n     - **Example:**\n       - Use `lspci` on Linux to inspect BAR mappings.\n       - Write test programs that perform memory-mapped I/O to the BARs.\n\n### **8.3 Emulating Device Power Management and Interrupts**\n\nEmulating power management features and implementing interrupts are critical for devices that need to interact closely with the host operating system's power and interrupt handling mechanisms.\n\n#### **8.3.1 Power Management Configuration**\n\nImplementing power management allows the device to support various power states, contributing to system-wide power efficiency and compliance with operating system expectations.\n\n**Steps:**\n\n1. **Enable Power Management in PCIe IP Core:**\n\n   - **Access Capabilities:**\n     - In the PCIe IP core customization window, select the **Capabilities** tab.\n\n   - **Enable Power Management:**\n     - Check the option for **Power Management** to include the capability in the device's configuration space.\n\n2. **Set Power States Supported:**\n\n   - **Configure Supported States:**\n     - Specify which power states the device supports, such as:\n       - **D0 (Fully On)**\n       - **D1, D2 (Intermediate States)**\n       - **D3hot, D3cold (Low Power States)**\n     - Match these settings to the donor device's capabilities.\n\n3. **Implement Power State Logic in Firmware:**\n\n   - **Open `pcileech_pcie_cfg_a7.sv`:**\n     - Modify the firmware to handle power state transitions.\n\n   - **Handle Power Management Registers:**\n     - Implement read and write access to the Power Management Control and Status Register (PMCSR).\n       ```verilog\n       // PMCSR Address\n       localparam PMCSR_ADDRESS = 12'h44; // Example address\n\n       // PMCSR Register\n       reg [15:0] pmcsr_reg;\n\n       // Handle PMCSR Writes\n       always @(posedge clk) begin\n         if (cfg_write && cfg_address == PMCSR_ADDRESS) begin\n           pmcsr_reg <= cfg_writedata[15:0];\n           // Update power state based on pmcsr_reg[1:0]\n         end\n       end\n       ```\n\n   - **Manage Power State Effects:**\n     - Implement the logic to alter device behavior based on the current power state.\n\n4. **Save Changes:**\n\n   - **Save the Firmware File:**\n     - Ensure all modifications are saved.\n\n   - **Verify Functionality:**\n     - Test the power management features through simulation or hardware testing.\n\n#### **8.3.2 MSI/MSI-X Configuration**\n\nImplementing MSI/MSI-X allows the device to use message-based interrupts, which are more efficient and scalable than traditional pin-based interrupts.\n\n**Steps:**\n\n1. **Enable MSI/MSI-X in PCIe IP Core:**\n\n   - **Access Interrupts Configuration:**\n     - In the PCIe IP core customization window, navigate to the **Interrupts** or **MSI/MSI-X** tab.\n\n   - **Select Interrupt Type:**\n     - Choose **MSI** or **MSI-X** based on the donor device.\n\n   - **Configure Number of Supported Vectors:**\n     - Set the number of interrupt vectors to match the donor device.\n       - **MSI** supports up to 32 vectors.\n       - **MSI-X** supports up to 2048 vectors.\n\n   - **Enable Capabilities:**\n     - Ensure that the MSI or MSI-X capabilities are included in the device's configuration space.\n\n2. **Implement Interrupt Logic in Firmware:**\n\n   - **Open `pcileech_pcie_tlp_a7.sv`:**\n     - Modify the firmware to handle interrupt generation.\n\n   - **Define Interrupt Signals:**\n     - Declare signals for MSI/MSI-X requests.\n       ```verilog\n       reg msi_req;\n       ```\n\n   - **Implement Interrupt Generation Logic:**\n     - Define conditions under which an interrupt is triggered.\n       ```verilog\n       // Example Interrupt Condition\n       wire interrupt_condition = /* condition logic */;\n\n       // Generate MSI Interrupt\n       always @(posedge clk) begin\n         if (interrupt_condition) begin\n           msi_req <= 1'b1;\n         end else begin\n           msi_req <= 1'b0;\n         end\n       end\n       ```\n\n   - **Connect to PCIe Core:**\n     - Ensure that the `msi_req` signal is properly connected to the PCIe IP core's interrupt interface.\n\n3. **Save Changes:**\n\n   - **Save the Firmware File:**\n     - After implementing the interrupt logic, save the file.\n\n   - **Check for Timing Constraints:**\n     - Verify that the new logic does not introduce timing violations.\n\n#### **8.3.3 Implementing Interrupt Handling Logic**\n\nDefining when and how interrupts are generated is essential for the device's interaction with the host's interrupt handling mechanisms.\n\n**Steps:**\n\n1. **Define Interrupt Conditions:**\n\n   - **Identify Trigger Events:**\n     - Determine specific events that should cause an interrupt.\n       - **Examples:**\n         - Data ready for processing.\n         - Error conditions.\n         - Completion of a task.\n\n   - **Implement Condition Logic:**\n     - Use combinational or sequential logic to detect these events.\n\n2. **Create Interrupt Generation Module:**\n\n   - **Modular Design:**\n     - Implement the interrupt logic as a separate module for clarity and reuse.\n       ```verilog\n       module interrupt_controller(\n         input wire clk,\n         input wire reset,\n         input wire event_trigger,\n         output reg msi_req\n       );\n         always @(posedge clk or posedge reset) begin\n           if (reset) begin\n             msi_req <= 1'b0;\n           end else if (event_trigger) begin\n             msi_req <= 1'b1;\n           end else begin\n             msi_req <= 1'b0;\n           end\n         end\n       endmodule\n       ```\n\n   - **Integrate with Main Firmware:**\n     - Instantiate the module and connect it to the main firmware logic.\n\n3. **Ensure Proper Timing and Sequencing:**\n\n   - **Adhere to PCIe Specifications:**\n     - Ensure interrupts are generated and cleared according to the protocol.\n\n   - **Manage Interrupt Latency:**\n     - Optimize logic to minimize delay between event occurrence and interrupt generation.\n\n4. **Test Interrupt Delivery:**\n\n   - **Simulation:**\n     - Use simulation tools to verify that interrupts are generated correctly.\n\n   - **Hardware Testing:**\n     - Program the FPGA and use host-side software to confirm that interrupts are received and handled.\n\n   - **Debugging Tools:**\n     - Utilize Integrated Logic Analyzer (ILA) cores to monitor signals in real time.\n\n5. **Save Changes:**\n\n   - **Finalize Code:**\n     - Ensure all changes are saved and documented.\n\n   - **Review and Refine:**\n     - Iterate on the design as needed based on testing results.\n\n---\n\n## **10. Transaction Layer Packet (TLP) Emulation**\n\nTransaction Layer Packets (TLPs) are the fundamental units of communication in PCIe. Accurate TLP emulation is crucial for the device to interact properly with the host system.\n\n### **10.1 Understanding and Capturing TLPs**\n\n#### **10.1.1 Learning the TLP Structure**\n\n- **Components**:\n\n  - **Header**: Contains fields such as **Transaction Layer Packet Type (Type)**, **Length**, **Requester ID**, **Tag**, **Address**, etc.\n  - **Data Payload**: Present in Memory Write and some other TLPs.\n  - **CRC**: Ensures data integrity.\n\n- **Understanding TLP Types**:\n\n  - **Memory Read Request**\n  - **Memory Read Completion**\n  - **Memory Write**\n  - **Configuration Read/Write**\n  - **Vendor-Defined Messages**\n\n#### **10.1.2 Capturing TLPs from the Donor Device**\n\n- **Steps**:\n\n  1. **Set Up a PCIe Protocol Analyzer**:\n\n     - Use hardware tools like **Teledyne LeCroy PCIe Analyzers**.\n\n  2. **Capture Transactions**:\n\n     - Monitor the donor device during normal operation and record the TLPs.\n\n  3. **Analyze Captured TLPs**:\n\n     - Use the analyzer's software to dissect the TLPs and understand their structure and sequence.\n\n#### **10.1.3 Documenting Key TLP Transactions**\n\n- **Steps**:\n\n  1. **Identify Critical Transactions**:\n\n     - Focus on TLPs that are essential for device initialization, configuration, data transfer, and error handling.\n\n  2. **Create Detailed Documentation**:\n\n     - For each key TLP, note the field values, sequence, and conditions under which it is sent.\n\n  3. **Understand Timing and Sequencing**:\n\n     - Pay attention to the timing between TLPs and the required response times.\n\n### **10.2 Crafting Custom TLPs for Specific Operations**\n\n#### **10.2.1 Implementing TLP Handling in Firmware**\n\n- **Files to Modify**:\n\n  - `pcileech_pcie_tlp_a7.sv`\n    ```\n    pcileech-wifi-main/src/pcileech_pcie_tlp_a7.sv\n    ```\n\n- **Steps**:\n\n  1. **Create TLP Generation Functions**:\n\n     - In `pcileech_pcie_tlp_a7.sv`, write functions to assemble TLPs with the required headers and payloads.\n     - **Example**:\n       ```verilog\n       function automatic [127:0] generate_tlp;\n         input [15:0] requester_id;\n         input [7:0] tag;\n         input [7:0] length;\n         input [31:0] address;\n         input [31:0] data;\n         begin\n           generate_tlp = { /* TLP Header and Payload */ };\n         end\n       endfunction\n       ```\n\n  2. **Handle TLP Reception**:\n\n     - Implement logic to parse incoming TLPs and extract necessary information.\n     - Use state machines to manage different TLP types.\n\n  3. **Ensure Compliance**:\n\n     - Verify that the TLPs conform to the PCIe specification regarding format and timing.\n\n  4. **Implement Completion Handling**:\n\n     - For Memory Read Requests, generate appropriate Completion TLPs.\n\n  5. **Save Changes**:\n\n     - Save the file after implementing the changes.\n\n#### **10.2.2 Handling Different TLP Types**\n\n- **Memory Read Requests**:\n\n  - **Implementation**:\n\n    - Parse the request header.\n    - Fetch data from the appropriate memory location.\n    - Assemble and send a Completion TLP with the data.\n\n- **Memory Write Requests**:\n\n  - **Implementation**:\n\n    - Receive the TLP and extract the data payload.\n    - Write the data to the specified memory location.\n\n- **Configuration Read/Write Requests**:\n\n  - **Implementation**:\n\n    - Access the configuration space registers.\n    - For reads, return the requested data.\n    - For writes, update the register values.\n\n- **Vendor-Defined Messages**:\n\n  - **Implementation**:\n\n    - Implement parsing and response logic for any vendor-specific messages as per the donor device's protocol.\n\n#### **10.2.3 Validating TLP Timing and Sequence**\n\n- **Steps**:\n\n  1. **Use Simulation Tools**:\n\n     - Simulate the firmware using test benches to validate TLP handling.\n\n  2. **Monitor with ILA**:\n\n     - Insert an ILA core to capture TLP-related signals during hardware testing.\n\n  3. **Check Timing Constraints**:\n\n     - Ensure that TLPs are processed and responded to within the allowed timing windows specified by the PCIe standard.\n\n  4. **Compliance Testing**:\n\n     - Use PCIe compliance tools to verify adherence to the standard.\n\n  5. **Save Changes**:\n\n     - Save all modified files after testing and validation.\n\n---\n\n## **Part 3: Advanced Techniques and Optimization**\n\n---\n\n## **11. Building, Flashing, and Testing**\n\nAfter all customizations, it's time to build the firmware, program it onto the FPGA, and thoroughly test it to ensure proper functionality.\n\n### **11.1 Synthesis and Implementation**\n\n#### **11.1.1 Running Synthesis**\n\nSynthesis converts your high-level code into a gate-level representation.\n\n- **Steps**:\n\n  1. **Start Synthesis**:\n\n     - In Vivado, click **Run Synthesis** in the **Flow Navigator**.\n\n  2. **Monitor Progress**:\n\n     - Watch for any warnings or errors.\n     - **Common Warnings**:\n       - **Unconnected Ports**: Ensure all necessary signals are connected.\n       - **Timing Constraints Not Met**: May need to adjust constraints.\n\n  3. **Review Synthesis Report**:\n\n     - Check the **Utilization Summary** to ensure the design fits on the FPGA.\n\n#### **11.1.2 Running Implementation**\n\nImplementation maps the synthesized design onto the FPGA's resources.\n\n- **Steps**:\n\n  1. **Start Implementation**:\n\n     - After successful synthesis, click **Run Implementation**.\n\n  2. **Analyze Timing Reports**:\n\n     - Ensure that all timing constraints are met.\n     - **Address Violations**:\n       - Adjust logic or constraints to fix setup or hold time violations.\n\n  3. **Verify Placement**:\n\n     - Check that critical components are placed optimally.\n\n#### **11.1.3 Generating Bitstream**\n\nThe bitstream is the binary file used to program the FPGA.\n\n- **Steps**:\n\n  1. **Generate Bitstream**:\n\n     - Click **Generate Bitstream**.\n\n  2. **Wait for Completion**:\n\n     - This may take some time depending on design complexity.\n\n  3. **Review Bitstream Generation Log**:\n\n     - Ensure no errors occurred during generation.\n\n### **11.2 Flashing the Bitstream**\n\n#### **11.2.1 Connecting the FPGA Device**\n\n- **Steps**:\n\n  1. **Prepare Hardware**:\n\n     - Ensure the FPGA board is powered and connected via JTAG.\n     - Refer to your FPGA board's manual for specific connection instructions.\n\n  2. **Open Hardware Manager**:\n\n     - In Vivado, navigate to **Flow Navigator > Program and Debug > Open Hardware Manager**.\n\n#### **11.2.2 Programming the FPGA**\n\n- **Steps**:\n\n  1. **Connect to the Target**:\n\n     - In the Hardware Manager, click **Open Target** and select **Auto Connect**.\n     - Vivado should detect your FPGA device.\n\n  2. **Program Device**:\n\n     - In the Hardware window, right-click on your FPGA device and select **Program Device**.\n     - Select the generated bitstream file (with `.bit` extension).\n     - Click **Program** to flash the firmware onto the FPGA.\n     - Wait for the programming process to complete.\n\n#### **11.2.3 Verifying Programming**\n\n- **Steps**:\n\n  1. **Check Status**:\n\n     - Ensure the programming completes without errors.\n     - Vivado will display a success message upon completion.\n\n  2. **Observe LEDs or Indicators**:\n\n     - Some FPGA boards have LEDs indicating successful programming or active status.\n\n### **11.3 Testing and Validation**\n\n#### **11.3.1 Verifying Device Enumeration**\n\n- **Windows**:\n\n  - **Steps**:\n    1. **Open Device Manager**:\n       - Press `Win + X` and select **Device Manager**.\n    2. **Check Device Properties**:\n       - Look under the appropriate device category (e.g., **Network Adapters**, **Storage Controllers**).\n       - Confirm that the **Device ID**, **Vendor ID**, and other identifiers match those of the donor device.\n\n- **Linux**:\n\n  - **Steps**:\n    1. **Use lspci**:\n       ```bash\n       lspci -nn\n       ```\n    2. **Verify Device Listing**:\n       - Check that the emulated device appears with correct IDs.\n       - **Example Output**:\n         ```\n         03:00.0 Network controller [0280]: VendorID DeviceID\n         ```\n\n#### **11.3.2 Testing Device Functionality**\n\n- **Steps**:\n\n  1. **Install Necessary Drivers**:\n\n     - Use the donor device's drivers if required.\n     - Install them as per the manufacturer's instructions.\n\n  2. **Perform Functional Tests**:\n\n     - Run applications that interact with the device.\n     - Test data transfers, configurations, and any special functions.\n     - **Examples**:\n       - For a network card, perform ping tests or data streaming.\n       - For a storage controller, perform read/write operations.\n\n  3. **Monitor System Behavior**:\n\n     - Check for system stability and absence of errors.\n     - Ensure that the device behaves as expected under various workloads.\n\n#### **11.3.3 Monitoring for Errors**\n\n- **Windows**:\n\n  - **Steps**:\n    1. **Check Event Viewer**:\n       - Press `Win + X` and select **Event Viewer**.\n       - Navigate to **Windows Logs > System**.\n    2. **Look for PCIe-Related Errors**:\n       - Search for warnings or errors related to PCIe or the specific device.\n\n- **Linux**:\n\n  - **Steps**:\n    1. **Check dmesg Logs**:\n       ```bash\n       dmesg | grep pci\n       ```\n    2. **Identify Issues**:\n       - Look for messages indicating problems with PCIe communication or device initialization.\n\n---\n\n## **12. Advanced Debugging Techniques**\n\nWhen issues arise, advanced debugging tools and techniques can help identify and resolve problems efficiently.\n\n### **12.1 Using Vivado's Integrated Logic Analyzer**\n\nThe Integrated Logic Analyzer (ILA) allows real-time monitoring of internal FPGA signals.\n\n#### **12.1.1 Inserting ILA Cores**\n\n- **Steps**:\n\n  1. **Add ILA IP Core**:\n\n     - In Vivado, open the **IP Catalog**.\n     - Search for **ILA**.\n     - Instantiate the ILA core in your design.\n\n  2. **Connect Signals**:\n\n     - Attach the signals you wish to monitor to the ILA probes.\n     - **Example**:\n       ```verilog\n       ila_0 your_ila_instance (\n         .clk(clk),\n         .probe0(signal_to_monitor)\n       );\n       ```\n     - **File Path**:\n       ```\n       pcileech-wifi-main/src/pcileech_squirrel_top.sv\n       ```\n\n#### **12.1.2 Configuring Trigger Conditions**\n\n- **Steps**:\n\n  1. **Set Probe Properties**:\n\n     - Define the width of each probe to match the signal widths.\n\n  2. **Define Triggers**:\n\n     - In the ILA dashboard, set conditions that will trigger data capture.\n     - **Example**:\n       - Trigger when a specific TLP type is detected or when an error condition occurs.\n\n#### **12.1.3 Capturing and Analyzing Data**\n\n- **Steps**:\n\n  1. **Run the Design**:\n\n     - Program the FPGA with the ILA-enabled bitstream.\n\n  2. **Open Hardware Manager**:\n\n     - Access the ILA interface within Vivado.\n\n  3. **Capture Data**:\n\n     - Arm the ILA and wait for the trigger condition.\n     - Once triggered, the ILA will capture the waveform data.\n\n  4. **Analyze Waveforms**:\n\n     - Use the waveform viewer to inspect signal behavior.\n     - Identify anomalies or verify correct operation.\n\n### **12.2 PCIe Traffic Analysis Tools**\n\nUsing external tools can provide deeper insights into PCIe communications.\n\n#### **12.2.1 PCIe Protocol Analyzers**\n\n- **Examples**:\n\n  - **Teledyne LeCroy PCIe Analyzers**\n  - **Keysight PCIe Analyzers**\n\n- **Steps**:\n\n  1. **Set Up Analyzer**:\n\n     - Connect the analyzer between the host system and FPGA device.\n\n  2. **Configure Capture Settings**:\n\n     - Define the scope of data to capture (e.g., specific TLP types, error conditions).\n\n  3. **Capture Traffic**:\n\n     - Record PCIe transactions during device operation.\n\n  4. **Analyze Results**:\n\n     - Examine TLPs for compliance and correctness.\n     - Identify any protocol violations or unexpected behaviors.\n\n#### **12.2.2 Software-Based Tools**\n\n- **Examples**:\n\n  - **Wireshark with PCIe Plugins**\n  - **ChipScope Pro** (for Xilinx devices)\n\n- **Steps**:\n\n  1. **Install Necessary Plugins**:\n\n     - Ensure PCIe support is enabled in the tool.\n\n  2. **Monitor PCIe Bus**:\n\n     - Capture and display PCIe packets.\n\n  3. **Analyze Communications**:\n\n     - Look for anomalies or errors in the data.\n     - Verify that TLPs are correctly formed and sequenced.\n\n---\n\n## **13. Troubleshooting**\n\nThis section provides solutions to common problems you may encounter during firmware development and testing.\n\n### **13.1 Device Detection Issues**\n\n**Problem**: The FPGA device is not recognized by the host system.\n\n#### **Possible Causes and Solutions**:\n\n1. **Incorrect Device IDs**:\n   - **Cause**: Mismatch between the IDs in the firmware and what the host expects.\n   - **Solution**: Verify and correct the **Device ID**, **Vendor ID**, and **Subsystem ID** in your firmware.\n\n2. **PCIe Link Training Failure**:\n   - **Cause**: The PCIe link is not established.\n   - **Solution**:\n     - Check physical connections.\n     - Ensure the **Link Width** and **Link Speed** are correctly configured.\n\n3. **Power Issues**:\n   - **Cause**: Insufficient power to the FPGA device.\n   - **Solution**: Verify power supply connections and voltage levels.\n\n4. **Firmware Errors**:\n   - **Cause**: Errors in the firmware prevent proper operation.\n   - **Solution**: Review code for syntax errors or misconfigurations.\n\n### **13.2 Memory Mapping and BAR Configuration Errors**\n\n**Problem**: The device's memory regions are not accessible, or accessing them causes system errors.\n\n#### **Possible Causes and Solutions**:\n\n1. **Incorrect BAR Sizes or Types**:\n   - **Cause**: BAR configurations do not match the donor device.\n   - **Solution**: Adjust BAR sizes and types in both the PCIe IP Core and firmware.\n\n2. **Address Decoding Errors**:\n   - **Cause**: Firmware fails to correctly interpret addresses.\n   - **Solution**: Debug the address decoding logic in your firmware.\n\n3. **Overlapping Address Spaces**:\n   - **Cause**: BARs overlap or conflict with other devices.\n   - **Solution**: Ensure BAR addresses are correctly aligned and do not overlap.\n\n### **13.3 DMA Performance and TLP Errors**\n\n**Problem**: Slow data transfer rates or errors occur during DMA operations, or TLPs are malformed.\n\n#### **Possible Causes and Solutions**:\n\n1. **Inefficient DMA Logic**:\n   - **Cause**: DMA engine not optimized.\n   - **Solution**: Implement buffering and pipelining to enhance throughput.\n\n2. **Malformed TLPs**:\n   - **Cause**: Incorrect TLP formatting.\n   - **Solution**: Review TLP assembly code to ensure compliance with the PCIe specification.\n\n3. **Flow Control Issues**:\n   - **Cause**: Improper handling of flow control credits.\n   - **Solution**: Implement proper flow control mechanisms in the firmware.\n\n---\n\n## **14. Emulation Accuracy and Optimizations**\n\nEnhancing emulation accuracy ensures compatibility and performance, making the emulated device indistinguishable from the donor.\n\n### **14.1 Techniques for Accurate Timing Emulation**\n\n- **Implement Timing Constraints**:\n  - Use Vivado's timing constraints to match the timing characteristics of the donor device.\n  - Apply constraints to critical paths to ensure they meet the required setup and hold times.\n\n- **Use Clock Domain Crossing (CDC) Techniques**:\n  - Properly handle signals crossing between different clock domains to prevent metastability.\n  - Use synchronizers or FIFOs as appropriate.\n\n- **Simulate Device Behavior**:\n  - Use simulation tools to model and verify the device's behavior under different conditions.\n  - Validate that the timing and sequencing of operations match the donor device.\n\n### **14.2 Dynamic Response to System Calls**\n\n- **Implement State Machines**:\n  - Design state machines that allow the device to respond dynamically to various commands and states.\n  - Ensure that the device can handle unexpected or out-of-order requests gracefully.\n\n- **Monitor and Respond to Host Commands**:\n  - Implement logic to decode and respond to configuration writes, vendor-specific commands, and other interactions.\n  - Update internal registers and states accordingly.\n\n- **Optimize Firmware Logic**:\n  - Refine the firmware code to reduce latency and improve responsiveness.\n  - Remove unnecessary delays or bottlenecks in the data paths.\n\n---\n\n## **15. Best Practices for Firmware Development**\n\nFollowing best practices helps maintain code quality, facilitates collaboration, and ensures the longevity of your project.\n\n### **15.1 Continuous Testing and Documentation**\n\n- **Regular Testing**:\n  - Test the firmware after each significant change to catch issues early.\n  - Use test benches and simulation to validate logic before implementation.\n\n- **Automated Testing**:\n  - Implement automated test scripts to verify functionality and performance.\n  - Use continuous integration tools if working in a team environment.\n\n- **Maintain Documentation**:\n  - Document the design, including block diagrams, state machines, and interfaces.\n  - Keep track of changes with clear commit messages and update design documents accordingly.\n\n### **15.2 Managing Firmware Versioning**\n\n- **Use Version Control Systems**:\n  - Employ systems like **Git** to manage code versions and collaborate with others.\n  - Organize the repository with clear directory structures and naming conventions.\n\n- **Tag Releases and Milestones**:\n  - Tag stable versions of the firmware for future reference.\n  - Use branches for experimental features or major changes.\n\n- **Backup and Recovery**:\n  - Regularly backup your work to prevent data loss.\n  - Use cloud-based repositories or local backups as appropriate.\n\n### **15.3 Security Considerations**\n\n- **Secure Coding Practices**:\n  - Follow guidelines to prevent common vulnerabilities such as buffer overflows or race conditions.\n  - Validate all inputs and handle errors gracefully.\n\n- **Data Protection**:\n  - Ensure that any sensitive data handled by the device is protected.\n  - Implement encryption or access controls if necessary.\n\n- **Compliance and Ethics**:\n  - Be aware of legal and ethical considerations related to device emulation.\n  - Ensure compliance with relevant laws, regulations, and licensing agreements.\n\n---\n\n## **16. Additional Resources**\n\nEnhance your understanding and stay updated with the following resources:\n\n- **Xilinx Documentation**\n  - [Xilinx User Guides](https://www.xilinx.com/support/documentation/user_guides.htm)\n  - Includes detailed information on Vivado, IP cores, and FPGA development.\n\n- **PCI-SIG Specifications**\n  - [PCI Express Base Specification](https://pcisig.com/specifications)\n  - Official specifications for PCIe standards.\n\n- **FPGA Tutorials and Forums**\n  - [FPGA4Fun](http://www.fpga4fun.com/)\n  - [Stack Overflow FPGA Questions](https://stackoverflow.com/questions/tagged/fpga)\n  - Community-driven discussions and tutorials.\n\n- **Verilog and VHDL Resources**\n  - [ASIC World Verilog Tutorials](https://www.asic-world.com/verilog/index.html)\n  - [VHDL Reference Guide](https://www.vhdlwhiz.com/vhdl-reference-guide/)\n\n- **Vivado Design Suite User Guide**\n  - [Vivado User Guide](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_1/ug893-vivado-ip-subsystems.pdf)\n\n- **PCIe Protocol Analysis Tools**\n  - [Teledyne LeCroy](https://teledynelecroy.com/protocolanalyzer/)\n  - Offers a range of tools for PCIe analysis.\n\n---\n\n## **17. Contact Information**\n\nIf you need assistance, have questions, or wish to collaborate, feel free to reach out. I'm available to provide guidance, troubleshoot complex problems, or discuss ideas in detail.\n\n### **Discord**: [**VCPU**](https://discord.com/users/196741541094621184) | [**Server Invite Link**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **18. Support and Contributions**\n\nYour support helps maintain and improve this guide and related projects.\n\n### **Donations**\n\n- **Crypto Donations (LTC)**:\n  - **Address**: `MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi`\n\nIf you found this guide helpful and want to support ongoing work, consider contributing. Every donation helps in continuing to create, share, and support the community.\n\n**Special Bonus**: If you donate, reach out on Discord (VCPU) to receive a personal thank you and possibly additional resources or assistance.\n\n**Note**: If you need me to review your implementation or troubleshoot issues, please mark the relevant sections with `//VCPU-REVIEW//` and provide detailed explanations of the problems you're encountering.\n\n---\n\n**End of Guide**\n"
  },
  {
    "path": "README-v2-old.md",
    "content": "# **Custom Firmware Development Guide for Full Device Emulation**\n\n\n## **Table of Contents**\n\n1. [Introduction](#1-introduction)\n   - [1.1 Purpose of the Guide](#11-purpose-of-the-guide)\n   - [1.2 Target Audience](#12-target-audience)\n2. [Key Definitions](#2-key-definitions)\n3. [Device Compatibility](#3-device-compatibility)\n   - [3.1 Supported FPGA-Based Hardware](#31-supported-fpga-based-hardware)\n   - [3.2 PCIe Hardware Considerations](#32-pcie-hardware-considerations)\n   - [3.3 System Requirements](#33-system-requirements)\n4. [Requirements](#4-requirements)\n   - [4.1 Hardware](#41-hardware)\n   - [4.2 Software](#42-software)\n   - [4.3 Environment Setup](#43-environment-setup)\n5. [Gathering Donor Device Information](#5-gathering-donor-device-information)\n   - [5.1 Using Arbor for PCIe Device Scanning](#51-using-arbor-for-pcie-device-scanning)\n   - [5.2 Extracting and Recording Device Attributes](#52-extracting-and-recording-device-attributes)\n6. [Initial Firmware Customization](#6-initial-firmware-customization)\n   - [6.1 Modifying Configuration Space](#61-modifying-configuration-space)\n   - [6.2 Inserting the Device Serial Number (DSN)](#62-inserting-the-device-serial-number-dsn)\n7. [Vivado Project Setup and Customization](#7-vivado-project-setup-and-customization)\n   - [7.1 Generating Vivado Project Files](#71-generating-vivado-project-files)\n   - [7.2 Modifying IP Blocks](#72-modifying-ip-blocks)\n8. [Advanced Firmware Customization](#8-advanced-firmware-customization)\n   - [8.1 Configuring PCIe Parameters for Emulation](#81-configuring-pcie-parameters-for-emulation)\n   - [8.2 Adjusting BARs and Memory Mapping](#82-adjusting-bars-and-memory-mapping)\n   - [8.3 Emulating Device Power Management and Interrupts](#83-emulating-device-power-management-and-interrupts)\n9. [Emulating Device-Specific Capabilities](#9-emulating-device-specific-capabilities)\n   - [9.1 Implementing Advanced PCIe Capabilities](#91-implementing-advanced-pcie-capabilities)\n   - [9.2 Emulating Vendor-Specific Features](#92-emulating-vendor-specific-features)\n10. [Transaction Layer Packet (TLP) Emulation](#10-transaction-layer-packet-tlp-emulation)\n    - [10.1 Understanding and Capturing TLPs](#101-understanding-and-capturing-tlps)\n    - [10.2 Crafting Custom TLPs for Specific Operations](#102-crafting-custom-tlps-for-specific-operations)\n11. [Building, Flashing, and Testing](#11-building-flashing-and-testing)\n    - [11.1 Synthesis and Implementation](#111-synthesis-and-implementation)\n    - [11.2 Flashing the Bitstream](#112-flashing-the-bitstream)\n    - [11.3 Testing and Validation](#113-testing-and-validation)\n12. [Advanced Debugging Techniques](#12-advanced-debugging-techniques)\n    - [12.1 Using Vivado's Integrated Logic Analyzer](#121-using-vivados-integrated-logic-analyzer)\n    - [12.2 PCIe Traffic Analysis Tools](#122-pcie-traffic-analysis-tools)\n13. [Troubleshooting](#13-troubleshooting)\n    - [13.1 Device Detection Issues](#131-device-detection-issues)\n    - [13.2 Memory Mapping and BAR Configuration Errors](#132-memory-mapping-and-bar-configuration-errors)\n    - [13.3 DMA Performance and TLP Errors](#133-dma-performance-and-tlp-errors)\n14. [Emulation Accuracy and Optimizations](#14-emulation-accuracy-and-optimizations)\n    - [14.1 Techniques for Accurate Timing Emulation](#141-techniques-for-accurate-timing-emulation)\n    - [14.2 Dynamic Response to System Calls](#142-dynamic-response-to-system-calls)\n15. [Best Practices for Firmware Development](#15-best-practices-for-firmware-development)\n    - [15.1 Continuous Testing and Documentation](#151-continuous-testing-and-documentation)\n    - [15.2 Managing Firmware Versioning](#152-managing-firmware-versioning)\n    - [15.3 Security Considerations](#153-security-considerations)\n16. [Additional Resources](#16-additional-resources)\n\n---\n\n## **Preface**\n\n**Attention, you thieving scum.** I’m not here to coddle or indulge your pitiful schemes. **FUCK AQUA**, better known as Aqua Teen Paster Force—a disgrace to anyone with a shred of integrity. **FUCK DIVINER**, too. And DUCK? Go degrade yourself elsewhere. **DMA KINGDOM**? You and your parasitic empire can rot in hell with the rest of these frauds. SHITLETTE and all of you money-grubbing thieves, prepare for a reckoning. The **Wrath of God**? You’re about to understand the meaning of true devastation. Either atone for your greed, or get swept away by the destruction you deserve. While we are on this topic, FUCK YOU TOO BILL GATES.\n\nFor those who’ve come to **learn**, you’ve chosen the path of **true enlightenment**. What you build with this guide will outshine anything these charlatans could dream of. You’re on the road to **excellence**, and together, we’ll torch the failures they’ve built their fortunes on. \n\n---\n\n## **Contact Information**\n\nIf you need assistance, have inquiries, or are looking to collaborate, feel free to reach out. I’m available to provide guidance, troubleshoot complex problems, or discuss ideas in detail.\n\n### **Discord** - **VCPU** | [**Server**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **Support My Work**\n\nIf you found this guide helpful and want to fuel more projects, consider contributing to help keep everything going. Every donation helps me continue to create, share, and support the community, and it’s greatly appreciated.\n\n### **Crypto Donations (LTC)**  \n- MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi\n\nI don’t make much from selling firmware—maybe 5 sales adding up to around $300 total—but I know many people using this guide will go on to make far more. If this guide helped you on your path to success, consider giving back so I can keep these resources available for everyone.\n\n### **Special Bonus**  \nIf you donate, reach out to me on Discord (VCPU) and let me know. I’d love to thank you personally and offer something in return. I’ll even do a random prize spin—whether it's free firmware, private source codes, or some insights on bypassing ACS, there’ll be something special for you.\n\nYour support means the world to me, and together we can keep building and sharing for the future. Thank you!\n\n---\n\nDon't have the time or energy to make firmware yourself? I offer firmware starting at $60. Resellers are also welcome!\n\nReach out anytime for support or further discussion on this guide or related topics. Whether you’re a developer needing in-depth help or a researcher diving into FPGA emulation, I’m here to ensure your path to success is smooth and informed. Let's build something remarkable together.\n\nIf you are unsure if you completed a step properly or want me to review your implementation I will do so but you must have the section for review marked with //VCPU-REVIEW// and explain your problems so my time is not wasted.\n\nI am sure quite a few of you will exceed my capabilities, If you find something new or just make some sick firmware, I would love to see it in action. Moreover, I also have some very powerful bytes and bits to share, but if I shared here Riot PD would put me in a squad car.\n\nShare knowledge and spread loving kindness. God bless.\n\n---\n\n## **1. Introduction**\n\n### **1.1 Purpose of the Guide**\n\nThe primary objective of this guide is to equip developers, security researchers, and hardware engineers with the knowledge and practical steps necessary to develop custom DMA firmware for accurate 1:1 hardware device emulation using FPGA-based systems like **PCILeech-FPGA**. This enables applications in hardware testing, system debugging, malware analysis, and other scenarios requiring undetectable or legitimate-looking device emulation.\n\n### **1.2 Target Audience**\n\n- **Firmware Developers**: Engineers building custom firmware for hardware emulation, testing, or bypassing hardware restrictions.\n- **Hardware Testers**: Professionals emulating faulty or outdated hardware devices to assess system resilience or compatibility.\n- **Security Researchers**: Individuals utilizing custom firmware for vulnerability testing, malware analysis, or security assessments.\n- **FPGA Enthusiasts**: Hobbyists exploring FPGA customization and low-level hardware emulation.\n\n---\n\n## **2. Key Definitions**\n\nUnderstanding the terminology is crucial for effectively following this guide. Below are key definitions related to PCIe, DMA, and device emulation:\n\n- **DMA (Direct Memory Access)**: A capability allowing hardware devices to directly read from or write to system memory without CPU intervention, facilitating rapid data transfers.\n- **TLP (Transaction Layer Packet)**: The fundamental unit of communication in PCIe architecture, encapsulating control and data information.\n- **BAR (Base Address Register)**: Registers in PCIe devices that map device memory into system memory space, defining memory and I/O address regions.\n- **FPGA (Field Programmable Gate Array)**: A reconfigurable integrated circuit that can be programmed to perform specific hardware functions, enabling custom device emulation.\n- **MSI/MSI-X (Message Signaled Interrupts)**: Mechanisms used by PCIe devices to send interrupts to the CPU, handling asynchronous events.\n- **Device Serial Number (DSN)**: A unique identifier associated with a specific device, often used for advanced device identification and verification.\n- **PCIe Configuration Space**: A memory area where PCIe devices provide information about themselves and configure operational parameters.\n- **Donor Card**: A PCIe device used to extract configuration and identification details for the purpose of emulating its behavior on an FPGA.\n\n---\n\n## **3. Device Compatibility**\n\n### **3.1 Supported FPGA-Based Hardware**\n\nWhile this guide primarily focuses on the **Squirrel DMA (35T)** card, the methodologies outlined are adaptable to other FPGA-based DMA hardware. Below is a list of compatible devices:\n\n- **Squirrel (35T)**\n  - **Description**: Affordable and widely accessible FPGA-based DMA device.\n  - **Use Case**: Suitable for standard memory acquisition and device emulation tasks.\n\n- **EnigmaX1 (75T)**\n  - **Description**: Mid-tier FPGA offering enhanced resources and performance.\n  - **Use Case**: Ideal for more demanding memory operations requiring higher bandwidth.\n\n- **ZDMA (100T)**\n  - **Description**: High-performance FPGA, optimized for rapid memory interactions.\n  - **Use Case**: Best suited for scenarios requiring fast and extensive memory reads/writes.\n\n- **Kintex-7**\n  - **Description**: Advanced FPGA with robust capabilities for complex projects.\n  - **Use Case**: Suitable for large-scale or highly customized DMA solutions.\n\n### **3.2 PCIe Hardware Considerations**\n\nTo ensure smooth emulation, several PCIe-specific features must be addressed:\n\n- **IOMMU/VT-d Settings**\n  - **Recommendation**: Disable IOMMU (Intel's VT-d) to allow unrestricted DMA access.\n  - **Rationale**: IOMMU can restrict DMA operations, potentially interfering with memory acquisition and emulation.\n\n- **Kernel DMA Protection**\n  - **Recommendation**: Disable Kernel DMA Protection features found in modern systems.\n  - **Steps**:\n    - **Windows**: This may involve disabling Secure Boot or Virtualization-Based Security (VBS).\n    - **BIOS/UEFI**: Access firmware settings to turn off related security features.\n  - **Caution**: Disabling these features can expose the system to risks; ensure you're operating within a secure and isolated environment.\n\n- **PCIe Slot Requirements**\n  - **Recommendation**: Use a compatible PCIe slot that matches the FPGA device's requirements (e.g., x1, x4, x16).\n  - **Rationale**: Ensures optimal performance and compatibility with the host system.\n\n### **3.3 System Requirements**\n\n- **Host System**\n  - **Processor**: Multi-core CPU (Intel i5/i7 or equivalent)\n  - **Memory**: Minimum 16GB RAM\n  - **Storage**: SSD with at least 100GB free space\n  - **Operating System**: Windows 10/11 (64-bit) or a compatible Linux distribution (e.g., Ubuntu, Debian) with necessary drivers\n\n- **Peripheral Devices**\n  - **JTAG Adapter**: For flashing firmware onto the FPGA\n  - **PCIe Slot**: Ensure the host system has available PCIe slots compatible with the DMA card\n\n---\n\n## **4. Requirements**\n\n### **4.1 Hardware**\n\n- **Donor PCIe Device**\n  - **Purpose**: Source of device IDs and configuration data for spoofing.\n  - **Examples**: Network adapters, storage controllers, or any generic PCIe card not used on the main PC.\n\n- **DMA FPGA Card**\n  - **Description**: FPGA-based device capable of performing DMA operations.\n  - **Examples**: Squirrel (35T), EnigmaX1 (75T), ZDMA (100T), Kintex-7\n\n- **JTAG Programmer**\n  - **Purpose**: For flashing firmware onto the FPGA.\n  - **Examples**: Xilinx Platform Cable USB, Digilent JTAG USB Cable\n\n### **4.2 Software**\n\n- **Vivado**\n  - **Description**: Xilinx's FPGA development software for synthesizing and building firmware projects.\n  - **Download**: [Xilinx Vivado](https://www.xilinx.com/support/download.html)\n\n- **Visual Studio**\n  - **Description**: Integrated Development Environment (IDE) for editing Verilog or VHDL code.\n  - **Download**: [Visual Studio Community](https://visualstudio.microsoft.com/vs/community/)\n\n- **PCILeech-FPGA**\n  - **Description**: The repository and base code for DMA firmware development.\n  - **Repository**: [PCILeech-FPGA on GitHub](https://github.com/ufrisk/pcileech-fpga)\n\n- **Arbor**\n  - **Description**: PCIe device scanning tool for gathering device information.\n  - **Download**: [Arbor by MindShare](https://www.mindshare.com/software/Arbor)\n  - **Note**: Requires account creation; offers a 14-day trial.\n\n- **Alternative Tools**\n  - **Telescan PE**\n    - **Description**: PCIe traffic analysis tool that can be used as an alternative to Arbor.\n    - **Download**: [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n    - **Note**: Free but requires manual registration approval.\n\n### **4.3 Environment Setup**\n\n1. **Install Vivado**\n   - **Steps**:\n     1. Visit the [Xilinx Vivado Download Page](https://www.xilinx.com/support/download.html).\n     2. Download the appropriate version compatible with your FPGA device.\n     3. Follow the installation instructions provided by Xilinx.\n     4. Launch Vivado and ensure it is properly configured.\n\n2. **Install Visual Studio**\n   - **Steps**:\n     1. Visit the [Visual Studio Download Page](https://visualstudio.microsoft.com/vs/community/).\n     2. Download and install the **Visual Studio Community Edition**.\n     3. During installation, ensure you include workloads related to **Desktop development with C++** to support hardware description languages (HDLs) like Verilog or VHDL.\n\n3. **Clone the PCILeech-FPGA Repository**\n   - **Steps**:\n     1. Open a terminal or command prompt.\n     2. Clone the repository using Git:\n        ```bash\n        git clone https://github.com/ufrisk/pcileech-fpga.git\n        ```\n     3. Navigate to the cloned directory:\n        ```bash\n        cd pcileech-fpga\n        ```\n\n4. **Set Up a Clean Development Environment**\n   - **Recommendation**: Work in an isolated environment to prevent unintended interactions, especially if using the firmware for sensitive tasks like malware analysis.\n   - **Steps**:\n     1. Use a dedicated development machine or a virtual environment.\n     2. Ensure no other applications interfere with PCIe operations or FPGA programming.\n\n---\n\n## **5. Gathering Donor Device Information**\n\nAccurate device emulation relies on extracting critical information from the donor device. This data allows your FPGA to mimic the target hardware in terms of PCIe configuration and behavior.\n\n### **5.1 Using Arbor for PCIe Device Scanning**\n\n**Arbor** is a powerful tool for scanning PCIe devices and extracting necessary information. Follow these steps to gather donor device details:\n\n1. **Install Arbor**\n   - **Steps**:\n     1. Visit the [Arbor Download Page](https://www.mindshare.com/software/Arbor).\n     2. Create an account if required.\n     3. Download and install Arbor on your system.\n\n2. **Scan PCIe Devices**\n   - **Steps**:\n     1. Launch Arbor.\n     2. Navigate to the **Local System** tab.\n     3. Under **Scan Options**, ensure default settings are appropriate.\n     4. Click **Scan/Rescan** to detect all connected PCIe devices.\n\n3. **Identify the Donor Device**\n   - **Criteria**:\n     - Should not be used on your main PC.\n     - Examples: PCIe WiFi cards, storage controllers, or generic PCIe devices.\n   - **Steps**:\n     1. Locate your donor device in the list of scanned devices.\n     2. Click on the device to view detailed configuration.\n\n4. **Capture Device Data**\n   - **Information to Extract**:\n     - **Device ID**\n     - **Vendor ID**\n     - **Subsystem ID**\n     - **Revision ID**\n     - **Base Address Registers (BARs)**\n     - **Capabilities** (e.g., MSI, power management, PCIe link width/speed)\n     - **Device Serial Number (DSN)** (if available)\n\n   - **Steps**:\n     1. Navigate to the **PCI Config** tab within Arbor.\n     2. Scroll through the **Decode** section to locate and record the above details.\n     3. Take screenshots or notes of each value for reference during firmware customization.\n\n   - **Example Extraction**:\n     \n     ![Device IDs](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/8baec3fe-c4bd-478e-9f95-d262804d6f67)\n     \n     ![Vendor ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/39c7de6d-d8db-4744-b0a0-ddeca0dfd7d7)\n     \n     ![Revision ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/c2374ea7-ca9c-47b7-8a8d-4ceff5dffe3b)\n     \n     ![BAR Sizing](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/19239179-057a-4ed5-a79f-45cf242787a5)\n     \n     ![Subsystem ID](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/94522a95-70bd-4336-8e38-58c0839e38ad)\n     \n     ![DSN](https://github.com/Silverr12/DMA-CFW-Guide/assets/89455475/595ae3e2-4cd8-4b3d-bcfa-cf6a59f289d5)\n     \n\n   - **Note**: The DSN may not be present on all devices. If unavailable, proceed with zeros in the DSN field during customization.\n\n### **5.2 Extracting and Recording Device Attributes**\n\nAfter scanning, ensure you have accurately recorded the following attributes from the donor device:\n\n1. **Device ID**: A unique identifier for the hardware device.\n2. **Vendor ID**: The identifier of the device manufacturer.\n3. **Subsystem ID**: Identifies the specific subsystem associated with the device.\n4. **Revision ID**: The revision number of the hardware version.\n5. **Base Address Registers (BARs)**: Defines memory and I/O address regions of the device.\n6. **Capabilities**: Such as Power Management (PM), MSI/MSI-X, PCIe link speed, and width.\n7. **Device Serial Number (DSN)**: If applicable, the unique serial number associated with the device.\n\n**Important Considerations**:\n\n- **BAR Sizes**: Ensure the memory-mapped I/O regions match the donor device’s configuration.\n- **Capabilities**: Properly emulate all capabilities to ensure seamless integration with the host system.\n- **DSN**: Enhances the fidelity of emulation; use if available.\n\n---\n\n## **6. Initial Firmware Customization**\n\nWith the necessary donor information in hand, proceed to customize the PCIe configuration space and memory mapping within the firmware to spoof the donor device.\n\n### **6.1 Modifying Configuration Space**\n\n1. **Navigate to the Configuration File**\n   - **Path**: `/PCIeSquirrel/src/pcileech_pcie_cfg_a7.sv`\n   - **Description**: This Verilog file contains the PCIe configuration logic for the device.\n\n2. **Open the File in Visual Studio**\n   - **Steps**:\n     1. Launch **Visual Studio**.\n     2. Open the `pcileech_pcie_cfg_a7.sv` file located in the `/PCIeSquirrel/src/` directory.\n\n3. **Modify Device ID and Vendor ID**\n   - **Steps**:\n     1. Use **Ctrl + F** to search for `cfg_deviceid`.\n     2. Update the Device ID with the donor's value:\n        ```verilog\n        cfg_deviceid <= 16'hXXXX;  // Replace XXXX with donor Device ID\n        ```\n     3. Similarly, search for `cfg_vendorid` and update:\n        ```verilog\n        cfg_vendorid <= 16'hYYYY;  // Replace YYYY with donor Vendor ID\n        ```\n\n4. **Modify Subsystem ID**\n   - **Steps**:\n     1. Search for `cfg_subsysid`.\n     2. Update the Subsystem ID:\n        ```verilog\n        cfg_subsysid <= 16'hZZZZ;  // Replace ZZZZ with donor Subsystem ID\n        ```\n\n5. **Adjust BARs Based on Donor Device**\n   - **Steps**:\n     1. Locate the BAR size configurations.\n     2. Set the BAR sizes to match those of the donor device:\n        ```verilog\n        bar0_size <= 32'hXXXX_YYYY;  // Replace with donor's BAR0 size\n        ```\n     3. Repeat for additional BARs (BAR1, BAR2, etc.) as necessary.\n\n   - **Example**:\n     ```verilog\n     bar0_size <= 32'h00004000;  // 16KB for BAR0\n     ```\n\n### **6.2 Inserting the Device Serial Number (DSN)**\n\nIf your donor device has a **Device Serial Number (DSN)**, incorporating it into the firmware enhances the emulation's fidelity.\n\n1. **Locate the DSN Field**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, search for `rw[127:64]`.\n     2. This field represents the `cfg_dsn` (Configuration Space Device Serial Number).\n\n2. **Insert the DSN**\n   - **Steps**:\n     1. Replace the placeholder with your donor device's DSN:\n        ```verilog\n        rw[127:64] <= 64'hXXXXXXXX_YYYYYYYY;  // Replace Xs and Ys with donor DSN\n        ```\n     2. **Example**:\n        - **Donor DSN**: Upper DW: `01 00 00 00`, Lower DW: `68 4C E0 00`\n        - **Combined DSN**: `64'h01000000684CE000`\n        ```verilog\n        rw[127:64] <= 64'h01000000684CE000;  // Donor DSN\n        ```\n\n   - **No DSN Available**:\n     ```verilog\n     rw[127:64] <= 64'h0000000000000000;  // No DSN\n     ```\n\n3. **Save Changes**\n   - **Steps**:\n     1. After modifying the DSN, save the file to retain changes.\n\n---\n\n## **7. Vivado Project Setup and Customization**\n\nAfter customizing the configuration space, integrate these changes into the Vivado project to prepare the firmware for synthesis and implementation.\n\n### **7.1 Generating Vivado Project Files**\n\n1. **Open Vivado**\n   - **Steps**:\n     1. Launch **Vivado** on your development machine.\n     2. Ensure Vivado is properly installed and configured for your FPGA device.\n\n2. **Access the Tcl Console**\n   - **Steps**:\n     1. In Vivado, locate the **Tcl Console** at the bottom of the application window.\n     2. If not visible, navigate to **Window > Tcl Console** to display it.\n\n3. **Navigate to the PCIeSquirrel Directory**\n   - **Steps**:\n     1. In the Tcl Console, determine your current directory:\n        ```tcl\n        pwd\n        ```\n     2. Change the directory to the `PCIeSquirrel` folder within the cloned `pcileech-fpga` repository:\n        ```tcl\n        cd C:/Users/YourUsername/Desktop/pcileech-fpga/PCIeSquirrel\n        ```\n        *Replace `YourUsername` and the path as per your setup.*\n\n     - **Note**: If you encounter errors with backslashes (`\\`), use forward slashes (`/`):\n       ```tcl\n       cd C:/Users/YourUsername/Desktop/pcileech-fpga/PCIeSquirrel\n       ```\n\n4. **Generate the Vivado Project**\n   - **Steps**:\n     1. In the Tcl Console, execute the project generation script:\n        ```tcl\n        source vivado_generate_project.tcl -notrace\n        ```\n     2. Wait for the script to complete. This process sets up the Vivado project with the necessary configurations.\n\n5. **Open the Generated Project**\n   - **Steps**:\n     1. Upon successful generation, Vivado should automatically open the `.xpr` (Vivado Project) file.\n     2. Keep the project open for further customization.\n\n### **7.2 Modifying IP Blocks**\n\n1. **Access the PCIe IP Core**\n   - **Steps**:\n     1. In the **Sources** pane, navigate to:\n        ```\n        pcileech_squirrel_top > i_pcileech_pcie_a7 : pcileech_pcie_a7\n        ```\n     2. Double-click on the PCIe IP core (`i_pcie_7x_0 : pcie_7x_0`) to open the **Re-customize IP** window.\n\n2. **Customize Device IDs and BARs**\n   - **Steps**:\n     1. In the **Re-customize IP** dialog, navigate to the **IDs** tab.\n     2. Enter the **Device ID**, **Vendor ID**, and **Subsystem ID** gathered from the donor device.\n     3. Verify the **Class Code**:\n        - Go back to Arbor or your scanning tool to determine the class code of your donor device.\n        - In the **Re-customize IP** window, set the class code accordingly to match the donor device.\n     4. **Example**:\n        - **Device ID**: `0x1234`\n        - **Vendor ID**: `0xABCD`\n        - **Subsystem ID**: `0x5678`\n        - **Class Code**: `0x030000` (e.g., Network Controller)\n\n3. **Configure BAR Sizes**\n   - **Steps**:\n     1. Navigate to the **BARs** tab within the **Re-customize IP** dialog.\n     2. Set the **BAR0 Size** to match the donor device's BAR0 size.\n        - **Example**: If the donor's BAR0 is 16KB:\n          ```tcl\n          BAR0 Size: 16KB\n          ```\n     3. Repeat for additional BARs (BAR1, BAR2, etc.) if the donor device utilizes them.\n\n4. **Finalize IP Customization**\n   - **Steps**:\n     1. After setting all necessary parameters, click **OK** to apply the changes.\n     2. Vivado may prompt to regenerate the IP core; confirm and allow the process to complete.\n\n5. **Lock the IP Core**\n   - **Purpose**: Prevent Vivado from overwriting manual configurations during synthesis.\n   - **Steps**:\n     1. Open the **Tcl Console** within Vivado.\n     2. Execute the following command to lock the IP core:\n        ```tcl\n        set_property is_managed false [get_files pcie_7x_0.xci]\n        ```\n     3. **To Unlock** (if needed in the future):\n        ```tcl\n        set_property is_managed true [get_files pcie_7x_0.xci]\n        ```\n\n---\n\n## **8. Advanced Firmware Customization**\n\nTo achieve precise 1:1 emulation, further customize PCIe parameters, BARs, memory mapping, power management, and interrupt handling.\n\n### **8.1 Configuring PCIe Parameters for Emulation**\n\n1. **Match PCIe Link Speed and Width**\n   - **Importance**: Ensures the emulated device communicates at the same speed and width as the donor device.\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, locate the PCIe link speed and width configurations.\n     2. Update these parameters to match the donor device's specifications.\n        ```verilog\n        pcie_link_speed <= 4'bXXXX;  // Replace XXXX with donor's PCIe link speed\n        pcie_link_width <= 8'b00000100;  // Replace with donor's PCIe link width (e.g., x1, x4, x8)\n        ```\n     - **Example**:\n       - **Donor PCIe Link Speed**: Gen3 (8 GT/s)\n       - **Donor PCIe Link Width**: x4\n         ```verilog\n         pcie_link_speed <= 4'b0011;  // Gen3\n         pcie_link_width <= 8'b00000100;  // x4\n         ```\n\n2. **Set Capability Pointers**\n   - **Purpose**: Ensure the PCIe capabilities are correctly linked and recognized by the host system.\n   - **Steps**:\n     1. Locate the capability pointer configurations in `pcileech_pcie_cfg_a7.sv`.\n     2. Set the capability pointers to match the donor device's configuration.\n        ```verilog\n        capability_pointer <= 8'h40;  // Example value; replace with donor's capability pointer\n        ```\n\n### **8.2 Adjusting BARs and Memory Mapping**\n\nAccurate memory mapping is critical for emulating hardware devices. Base Address Registers (BARs) define where the device's memory and registers appear in system memory space.\n\n1. **Set BAR Sizes**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, locate the BAR size assignments.\n     2. Set the BAR sizes to match those of the donor device.\n        ```verilog\n        bar0_size <= 32'h00004000;  // 16KB for BAR0\n        bar1_size <= 32'h00008000;  // 32KB for BAR1 (if applicable)\n        ```\n\n2. **Define BAR Address Spaces**\n   - **Steps**:\n     1. Ensure the BAR address spaces do not overlap and match the donor device's memory layout.\n     2. Use the recorded BAR sizes to set the address ranges appropriately.\n        ```verilog\n        bar0_addr <= 32'hF0000000;  // Example address; replace with donor's BAR0 address\n        bar1_addr <= 32'hF0004000;  // Example address; replace as needed\n        ```\n\n3. **Handle Multiple BARs**\n   - **Steps**:\n     1. If the donor device uses multiple BARs, repeat the configuration for each BAR.\n     2. Ensure each BAR's size and address align with the donor device's specifications.\n\n### **8.3 Emulating Device Power Management and Interrupts**\n\nProperly emulating power management and interrupt handling ensures the host system interacts seamlessly with the emulated device.\n\n1. **Power Management (PM) Configuration**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, locate the Power Management capability settings.\n     2. Set the PM capabilities to match the donor device.\n        ```verilog\n        PM_CAP_VERSION <= 4'b0011;  // Example version; replace with donor's PM version\n        PM_CAP_D1SUPPORT <= 1'b1;   // Enable D1 support if the donor does\n        PM_CAP_AUXCURRENT <= 4'b1000; // Example value; adjust as per donor\n        PM_CSR_NOSOFTRST <= 1'b0;   // Example value; adjust as needed\n        ```\n\n2. **MSI/MSI-X (Interrupts) Configuration**\n   - **Steps**:\n     1. Locate MSI/MSI-X configuration in `pcileech_pcie_cfg_a7.sv`.\n     2. Enable and configure MSI/MSI-X to handle interrupts correctly.\n        ```verilog\n        MSI_CAP_64_BIT_ADDR_CAPABLE <= 1'b1;  // Enable 64-bit MSI if supported\n        cfg_interrupt <= 1'b1;               // Enable MSI interrupts\n        ```\n\n3. **Implementing Interrupt Handling Logic**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, ensure the interrupt signals are correctly routed.\n        ```verilog\n        assign cfg_interrupt_di = cfg_int_di;\n        assign cfg_interrupt_assert = cfg_int_assert;\n        ```\n     2. Test interrupt functionality to ensure the host system correctly receives and handles interrupts from the emulated device.\n\n---\n\n## **9. Emulating Device-Specific Capabilities**\n\nTo achieve a true 1:1 emulation, it's essential to replicate the unique capabilities of the donor device beyond basic PCIe interactions.\n\n### **9.1 Implementing Advanced PCIe Capabilities**\n\nMost PCIe devices support advanced features like **Advanced Error Reporting (AER)**, **Link Speed Negotiation**, and **Extended Capabilities**. Emulating these ensures the host system perceives the emulated device as identical to the donor.\n\n1. **Advanced Error Reporting (AER)**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, locate AER configurations.\n     2. Enable AER if supported by the donor device.\n        ```verilog\n        AER_CAP_VERSION <= 4'b0001;  // Example version; replace with donor's AER version\n        AER_CAP_NEXTPTR <= 8'h00;    // Set next pointer appropriately\n        ```\n     3. Implement error handling logic to manage AER-related events.\n\n2. **Link Speed Negotiation**\n   - **Steps**:\n     1. Ensure the PCIe link speed and width negotiation matches the donor device.\n     2. Adjust link speed settings as previously outlined in **8.1**.\n\n3. **Extended Capabilities**\n   - **Steps**:\n     1. Identify any extended capabilities used by the donor device (e.g., Vendor-Specific Extended Capabilities, LTR, VSEC).\n     2. Implement these capabilities within `pcileech_pcie_cfg_a7.sv` by defining the appropriate registers and logic.\n        ```verilog\n        // Example for Vendor-Specific Extended Capability\n        VSEC_CAP_ID <= 16'hXXXX;       // Replace XXXX with vendor-specific ID\n        VSEC_CAP_VERSION <= 8'hYY;    // Replace YY with version\n        VSEC_CAP_NEXTPTR <= 8'hZZ;    // Next capability pointer\n        ```\n\n### **9.2 Emulating Vendor-Specific Features**\n\nSome devices incorporate proprietary or vendor-specific features that must be accurately emulated to ensure seamless integration.\n\n1. **Identify Vendor-Specific Features**\n   - **Steps**:\n     1. Use PCIe traffic analysis tools (e.g., Wireshark, Teledyne LeCroy) to monitor vendor-specific TLPs.\n     2. Document unique registers, commands, or behaviors exhibited by the donor device.\n\n2. **Implementing Vendor-Specific Logic**\n   - **Steps**:\n     1. In `pcileech_pcie_cfg_a7.sv`, add logic to handle vendor-specific features.\n        ```verilog\n        // Example: Vendor-Specific Register\n        vendor_specific_reg <= 32'hXXXXXXXX;  // Replace with actual value\n        ```\n     2. Ensure that any proprietary commands or responses are accurately replicated.\n\n3. **Testing Vendor-Specific Features**\n   - **Steps**:\n     1. Use vendor-specific drivers or applications to interact with the emulated device.\n     2. Verify that all proprietary features function as expected.\n\n---\n\n## **10. Transaction Layer Packet (TLP) Emulation**\n\nAccurate emulation of Transaction Layer Packets (TLPs) is vital for ensuring the FPGA-based device communicates seamlessly with the host system, mimicking the behavior of the donor device.\n\n### **10.1 Understanding and Capturing TLPs**\n\nTLPs are the fundamental units of PCIe communication, handling memory reads/writes, configuration accesses, and interrupt signaling.\n\n1. **Capture TLPs from the Donor Device**\n   - **Steps**:\n     1. Use PCIe analysis tools like **Teledyne LeCroy’s Telescan PE** or **Wireshark** with PCIe support to monitor TLPs generated by the donor device.\n     2. Record the structure, types, and patterns of TLPs used by the donor device during typical operations.\n\n2. **Analyze TLP Structure**\n   - **Components of a TLP**:\n     - **Header Fields**: Define the type, format, address, and other control information.\n     - **Data Payload**: The actual data being transferred.\n     - **Tail Fields**: Additional information such as byte counts and sequence numbers.\n\n   - **Example TLP Structure**:\n     ```verilog\n     tlps_static.tdata[127:0] = {TLP header fields, Data Payload};\n     ```\n\n3. **Emulating Legitimate Traffic**\n   - **Steps**:\n     1. Ensure that TLPs generated by the FPGA match those captured from the donor device in terms of type, address, length, and data.\n     2. Implement logic to handle different types of TLPs, such as memory writes, memory reads, and configuration accesses.\n\n### **10.2 Crafting Custom TLPs for Specific Operations**\n\nTo accurately mimic the donor device, you must craft custom TLPs that replicate its behavior during various operations.\n\n1. **Memory Write TLP Example**\n   - **Description**: Represents a write operation to system memory.\n   - **Verilog Example**:\n     ```verilog\n     tlp_mem_write <= {\n         1'b0,                    // Reserved\n         7'b10_00000,             // TLP Type: Memory Write\n         1'b0,                    // TLP Format\n         address[31:0],           // Address being written to\n         data[31:0]               // Data payload\n     };\n     ```\n\n2. **Memory Read TLP Example**\n   - **Description**: Represents a read operation from system memory.\n   - **Verilog Example**:\n     ```verilog\n     tlp_mem_read <= {\n         1'b0,                    // Reserved\n         7'b00_00000,             // TLP Type: Memory Read\n         1'b0,                    // TLP Format\n         address[31:0],           // Address being read from\n         tag[7:0]                 // Tag for transaction identification\n     };\n     ```\n\n3. **Configuration Access TLP Example**\n   - **Description**: Represents a configuration space access.\n   - **Verilog Example**:\n     ```verilog\n     tlp_config_access <= {\n         1'b0,                    // Reserved\n         7'b01_00000,             // TLP Type: Configuration Read/Write\n         1'b0,                    // TLP Format\n         config_address[31:0],    // Configuration space address\n         config_data[31:0]        // Configuration data payload\n     };\n     ```\n\n4. **Interrupt Signaling TLP Example**\n   - **Description**: Represents an interrupt signaling to the CPU.\n   - **Verilog Example**:\n     ```verilog\n     tlp_interrupt <= {\n         1'b0,                    // Reserved\n         7'b11_00000,             // TLP Type: Interrupt\n         1'b0,                    // TLP Format\n         interrupt_address[31:0], // Address related to the interrupt\n         interrupt_data[31:0]     // Interrupt data payload\n     };\n     ```\n\n5. **Implement TLP Handlers**\n   - **Steps**:\n     1. In your firmware, implement handlers for different TLP types to ensure correct processing and response.\n     2. Use state machines or logic blocks to manage TLP generation, processing, and response handling.\n\n---\n\n## **11. Building, Flashing, and Testing**\n\nAfter customizing the firmware and ensuring all configurations align with the donor device, proceed to build, flash, and test the firmware on your FPGA device.\n\n### **11.1 Synthesis and Implementation**\n\n1. **Run Synthesis**\n   - **Steps**:\n     1. In Vivado, click on **Run Synthesis**.\n     2. Monitor the synthesis process for any warnings or errors.\n     3. Address any critical issues before proceeding.\n\n2. **Run Implementation**\n   - **Steps**:\n     1. After successful synthesis, initiate **Run Implementation**.\n     2. Ensure that the implementation phase completes without critical warnings.\n     3. Review the implementation report for any potential issues.\n\n3. **Generate Bitstream**\n   - **Steps**:\n     1. Once implementation is complete, click on **Generate Bitstream**.\n     2. Confirm any prompts to generate the bitstream.\n     3. Wait for the bitstream generation to finish successfully.\n\n### **11.2 Flashing the Bitstream**\n\n1. **Connect FPGA via JTAG**\n   - **Steps**:\n     1. Ensure your FPGA device is connected to the host system via the JTAG interface.\n     2. Power on the FPGA device.\n\n2. **Open Vivado Hardware Manager**\n   - **Steps**:\n     1. In Vivado, navigate to **Window > Hardware Manager**.\n     2. Click **Open Target > Auto Connect** to detect the connected FPGA device.\n\n3. **Program the FPGA**\n   - **Steps**:\n     1. In the Hardware Manager, right-click on the detected device and select **Program Device**.\n     2. Browse to the generated bitstream file (`pcileech_squirrel_top.bit`).\n     3. Click **Program** to flash the firmware onto the FPGA.\n     4. Confirm successful programming via the Hardware Manager console.\n\n### **11.3 Testing and Validation**\n\n1. **Verify Device Detection**\n   - **Steps**:\n     1. Use **lspci** (on Linux) or **Device Manager** (on Windows) to verify that the FPGA is detected as the donor device.\n     2. Confirm that the **Device ID**, **Vendor ID**, **Subsystem ID**, and **BARs** match the donor device's specifications.\n\n   - **Example (Linux)**:\n     ```bash\n     lspci -vvv -s <PCI address>\n     ```\n\n2. **Memory Mapping Test**\n   - **Steps**:\n     1. Access the device's **BARs** to ensure correct memory mapping.\n     2. Use memory access tools or simple read/write operations to test responsiveness.\n\n3. **Interrupts Test**\n   - **Steps**:\n     1. Trigger interrupts through the emulated device.\n     2. Verify that the host system correctly receives and handles these interrupts.\n     3. Use system logs or diagnostic tools to confirm interrupt handling.\n\n4. **Performance Testing**\n   - **Steps**:\n     1. Run DMA speed test tools to measure data transfer rates.\n     2. Compare performance metrics against expected values to ensure firmware stability and efficiency.\n\n   - **Example Tools**:\n     - **PCILeech DMA Speed Test**: Available within the PCILeech toolset.\n     - **Custom Benchmark Scripts**: Scripts that perform read/write operations to measure performance.\n\n5. **Configuration Space Validation**\n   - **Steps**:\n     1. Use diagnostic tools to inspect the PCIe configuration space.\n     2. Ensure all fields (Device ID, Vendor ID, BARs, Capabilities) are correctly set and match the donor device.\n\n   - **Example (Linux)**:\n     ```bash\n     lspci -vvv -s <PCI address>\n     ```\n\n---\n\n## **12. Advanced Debugging Techniques**\n\nWhen developing custom firmware, encountering issues is common. Advanced debugging techniques can help identify and resolve these problems effectively.\n\n### **12.1 Using Vivado's Integrated Logic Analyzer**\n\nVivado's **Integrated Logic Analyzer (ILA)** allows real-time monitoring of internal FPGA signals, aiding in debugging and verification.\n\n1. **Set Up ILA Probes**\n   - **Steps**:\n     1. In Vivado, navigate to **Sources > Add Sources** and add an **Integrated Logic Analyzer**.\n     2. Insert ILA probes at critical points in the PCIe communication path, such as TLP generators or BAR access controllers.\n        ```verilog\n        // Example: Adding ILA probe for TLP data\n        wire [127:0] tlp_data;\n        assign tlp_data = tlps_static.tdata[127:0];\n        ila_0 probe (\n            .clk(clk),\n            .probe0(tlp_data)\n        );\n        ```\n\n2. **Configure Triggers**\n   - **Steps**:\n     1. Open the **ILA** configuration dialog.\n     2. Set trigger conditions based on specific events, such as TLP generation or memory access.\n        ```verilog\n        // Example trigger condition: Start of memory write TLP\n        if (tlp_type == MEMORY_WRITE && tlp_valid) begin\n            trigger_signal <= 1;\n        end\n        ```\n\n3. **Analyze Signal Waveforms**\n   - **Steps**:\n     1. Run the FPGA with the ILA probes enabled.\n     2. Use Vivado’s **Waveform Viewer** to examine captured signal waveforms.\n     3. Identify timing issues, incorrect logic states, or unexpected behaviors.\n\n   - **Benefits**:\n     - Real-time visibility into internal signals.\n     - Ability to capture and analyze transient issues during TLP processing.\n\n### **12.2 PCIe Traffic Analysis Tools**\n\nBeyond Vivado's ILA, external PCIe traffic analysis tools provide in-depth insights into PCIe communications between the FPGA and the host system.\n\n1. **Wireshark with PCIe Extensions**\n   - **Description**: Wireshark can capture and analyze PCIe traffic with the appropriate extensions or plugins.\n   - **Steps**:\n     1. Install Wireshark with PCIe support.\n     2. Configure Wireshark to capture PCIe traffic.\n     3. Analyze captured TLPs to ensure they align with expected donor device behavior.\n\n2. **Teledyne LeCroy Telescan PE**\n   - **Description**: A professional-grade PCIe traffic analysis tool offering comprehensive PCIe traffic monitoring and analysis capabilities.\n   - **Steps**:\n     1. Install Teledyne LeCroy’s Telescan PE.\n     2. Connect it to your system to monitor PCIe traffic.\n     3. Use it to capture and dissect TLPs exchanged between the FPGA and host system.\n\n3. **Total Phase Beagle**\n   - **Description**: A PCIe traffic analyzer that allows for real-time capture and analysis of PCIe communications.\n   - **Steps**:\n     1. Set up the Total Phase Beagle PCIe analyzer with your system.\n     2. Configure it to monitor and capture PCIe traffic.\n     3. Use its analysis features to verify TLP integrity and behavior.\n\n**Benefits of Using PCIe Traffic Analysis Tools**:\n\n- **Comprehensive TLP Analysis**: Detailed inspection of TLPs to ensure accurate emulation.\n- **Error Detection**: Identify malformed TLPs or unexpected transaction patterns.\n- **Performance Metrics**: Measure data transfer rates and identify bottlenecks.\n\n---\n\n## **13. Troubleshooting**\n\nEncountering issues during firmware development is common. This section provides solutions to common problems you may face during the emulation process.\n\n### **13.1 Device Detection Issues**\n\n**Problem**: The host system fails to detect the FPGA as the donor device.\n\n**Solutions**:\n\n1. **Verify Device IDs**\n   - **Steps**:\n     1. Double-check that the **Device ID**, **Vendor ID**, and **Subsystem ID** in the firmware match those of the donor device.\n     2. Ensure there are no typos or incorrect values in the configuration space.\n\n2. **Check PCIe Link Training**\n   - **Steps**:\n     1. Use PCIe diagnostic tools to verify that the PCIe link is properly trained.\n     2. Ensure that the link speed and width configurations match the donor device.\n\n3. **Ensure Correct BAR Configuration**\n   - **Steps**:\n     1. Confirm that the **BAR sizes** and **address ranges** are accurately set.\n     2. Ensure no overlapping or conflicting BAR configurations.\n\n4. **Power and Connection Check**\n   - **Steps**:\n     1. Ensure the FPGA device is properly connected and powered.\n     2. Re-seat the PCIe card to ensure a secure connection.\n\n### **13.2 Memory Mapping and BAR Configuration Errors**\n\n**Problem**: Incorrect memory mapping leads to failed or inaccurate memory access.\n\n**Solutions**:\n\n1. **Double-Check BAR Sizes and Addresses**\n   - **Steps**:\n     1. Verify that each BAR size in the firmware matches the donor device's configuration.\n     2. Ensure that BAR address spaces are correctly set and do not overlap.\n\n2. **Use Diagnostic Tools**\n   - **Steps**:\n     1. Utilize tools like **lspci** or **Arbor** to inspect the PCIe configuration space.\n     2. Confirm that the BARs are correctly mapped and accessible.\n\n3. **Adjust Memory Regions**\n   - **Steps**:\n     1. If memory regions are not accessible, adjust the BAR configurations to better match the system's memory map.\n     2. Ensure that the firmware logic correctly handles memory read/write operations.\n\n### **13.3 DMA Performance and TLP Errors**\n\n**Problem**: Slow DMA performance or errors related to Transaction Layer Packets (TLPs).\n\n**Solutions**:\n\n1. **Optimize TLP Generation**\n   - **Steps**:\n     1. Ensure that TLPs are correctly formatted and free of errors.\n     2. Use Vivado’s ILA and PCIe traffic analysis tools to identify and rectify malformed TLPs.\n\n2. **Adjust Payload Sizes**\n   - **Steps**:\n     1. Set the maximum read request and payload sizes to 4KB or the highest supported by the donor device.\n        ```verilog\n        max_read_request_size <= 4;  // 4KB\n        max_payload_size <= 4;       // 4KB\n        ```\n     2. Avoid setting payload sizes beyond what the donor device supports to prevent system instability.\n\n3. **Check PCIe Link Settings**\n   - **Steps**:\n     1. Verify that the PCIe link speed and width are correctly configured.\n     2. Ensure that the FPGA is negotiating the link parameters accurately with the host system.\n\n4. **Firmware Integrity**\n   - **Steps**:\n     1. Review and validate all recent changes to the firmware to ensure no unintended modifications were introduced.\n     2. Revert to a known stable firmware version if performance issues persist.\n\n---\n\n## **14. Emulation Accuracy and Optimizations**\n\nEnsuring the emulation's accuracy is critical for seamless integration and undetectable behavior. This section outlines techniques to enhance emulation precision and optimize performance.\n\n### **14.1 Techniques for Accurate Timing Emulation**\n\nMatching the donor device's timing characteristics ensures that the host system interacts with the emulated device as if it were the original hardware.\n\n1. **Use Matching Clock Domains**\n   - **Steps**:\n     1. Ensure that the FPGA’s clock matches the PCIe link’s clock rate.\n     2. Synchronize internal clocks within the FPGA to align with PCIe timing requirements.\n\n2. **Control Response Latency**\n   - **Steps**:\n     1. Implement registers or counters to manage response times for TLP acknowledgments and interrupt handling.\n     2. Ensure that the latency in responses matches the donor device’s typical response times.\n\n3. **Implement Pipeline Stages**\n   - **Steps**:\n     1. Use pipelining in the FPGA design to align with the donor device’s data processing stages.\n     2. This reduces latency and ensures timely TLP generation and processing.\n\n### **14.2 Dynamic Response to System Calls**\n\nEmulating dynamic device behavior based on system interactions ensures the FPGA device responds appropriately under various conditions.\n\n1. **Implement State Machines**\n   - **Steps**:\n     1. Design state machines within the FPGA to manage different operational states of the emulated device.\n     2. Ensure transitions between states mimic the donor device’s behavior based on system calls and interactions.\n\n2. **Track and Respond to System Requests**\n   - **Steps**:\n     1. Monitor incoming system requests and adjust the device’s responses dynamically.\n     2. Ensure that the FPGA firmware can handle varying workloads and respond accurately to different types of TLPs.\n\n3. **Handle Asynchronous Events**\n   - **Steps**:\n     1. Implement logic to manage asynchronous events such as interrupts or error conditions.\n     2. Ensure that the firmware can generate and respond to these events in a manner consistent with the donor device.\n\n---\n\n## **15. Best Practices for Firmware Development**\n\nAdhering to best practices ensures the development process is efficient, maintainable, and secure.\n\n### **15.1 Continuous Testing and Documentation**\n\n- **Test Frequently**\n  - **Steps**:\n    1. Conduct regular tests after each modification to ensure the firmware behaves as expected.\n    2. Use automated scripts or test benches to validate firmware functionality continuously.\n\n- **Document Changes**\n  - **Steps**:\n    1. Maintain detailed documentation for each change made to the firmware.\n    2. Include explanations for why changes were made and their impact on the overall design.\n\n### **15.2 Managing Firmware Versioning**\n\n- **Use Version Control**\n  - **Steps**:\n    1. Implement a version control system (e.g., **Git**) to manage different iterations of the firmware.\n    2. Commit changes regularly with descriptive messages to track the evolution of the project.\n\n- **Branching Strategy**\n  - **Steps**:\n    1. Use branches to manage feature development, bug fixes, and experimental changes.\n    2. Merge stable branches into the main branch only after thorough testing.\n\n### **15.3 Security Considerations**\n\n- **Prevent Unintended Access**\n  - **Steps**:\n    1. Ensure that the firmware does not expose system memory or hardware to unauthorized access.\n    2. Implement access controls and validation checks within the firmware.\n\n- **Protect Firmware Integrity**\n  - **Steps**:\n    1. Avoid introducing vulnerabilities or backdoors during firmware development.\n    2. Conduct regular security reviews and code audits to maintain firmware integrity.\n\n- **Handle Sensitive Data Securely**\n  - **Steps**:\n    1. If the firmware interacts with sensitive data, implement encryption and secure data handling practices.\n    2. Ensure that sensitive information is not exposed through firmware interfaces or logs.\n\n---\n\n## **16. Additional Resources**\n\nTo further enhance your understanding and capabilities in developing custom firmware for device emulation, the following resources are invaluable:\n\n- **PCILeech-FPGA Repository**\n  - **Link**: [https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n\n- **Vivado FPGA Documentation**\n  - **Link**: [Xilinx Vivado Documentation](https://www.xilinx.com/support/documentation.html)\n\n- **PCI-SIG Specifications**\n  - **Link**: [PCI-SIG](https://pcisig.com)\n\n- **PCIe TLP Primer Tutorial**\n  - **Link**: [PCIe TLP Primer](https://www.xillybus.com/tutorials/pci-express-tlp-pcie-primer-tutorial-guide-1)\n\n- **Teledyne LeCroy Telescan PE Documentation**\n  - **Link**: [Teledyne LeCroy Telescan PE](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n\n- **Wireshark PCIe Extensions**\n  - **Link**: [Wireshark Extensions](https://www.wireshark.org/docs/)\n\n- **Field Programmable Gate Array (FPGA) Basics**\n  - **Link**: [FPGA Basics](https://www.xilinx.com/support/documentation/sw_manuals/xilinx2020_2/ug901-vivado-tutorial.pdf)\n\n- **Arbor Software User Guide**\n  - **Link**: [Arbor User Guide](https://www.mindshare.com/software/Arbor)\n\n- **PCIe Specifications and Guides**\n  - **Link**: [PCIe Specifications](https://pcisig.com/specifications)\n"
  },
  {
    "path": "README.md",
    "content": "# **Custom Firmware Development Guide for Full Device Emulation**\n\n---\n\n**Shout out to the legend that donated, I will be in contact soon. I will add a shoutout here if you want + more just DM me if you haven't already!**\n\nWorking on organizing this into a [wiki](https://github.com/JPShag/PCILeech-DMA-Firmware/wiki/Introduction). Help is welcomed!\n\n----\n\n**A Note from the Author & Guide Status:**\n\nI'm sharing this transparently, as recent times have been incredibly challenging. Beyond a significant financial setback from a fraudulent chargeback, I've faced multiple other difficult living and health problems that have severely impacted my ability to be online and dedicate time to projects. Frankly, continuing to create comprehensive resources like this guide has been a profound struggle amidst these personal difficulties.\n\nThis is anticipated to be the final major iteration of the main guide. For more experienced users already familiar with fundamental hardware concepts (e.g., the function of an FTDI chip), a concise, minified version will also be made available.\n\nIf you find this work valuable and are in a position to help, any form of support would be profoundly appreciated. Your generosity enables me to continue contributing to this community despite the ongoing challenges. I sincerely hope this guide has been and continues to be a valuable resource.\n\n---\n\n## In Memoriam & Dedication\n\n![Ross](https://github.com/user-attachments/assets/de7f12fe-8992-4738-a6af-712dc48217ee)\n\nThis guide is humbly dedicated to the memory of\n**Ross Freeman (1947–1989)**\n\nA visionary engineer, pioneering Michigander, and co-founder of Xilinx, Ross Freeman is widely recognized as the father of Field-Programmable Gate Array (FPGA) technology, which revolutionized computing.\n\nIn 1984, at a time when the semiconductor industry predominantly focused on fixed-function chips, Freeman dared to imagine a different paradigm: hardware that could be reprogrammed after manufacturing. His revolutionary patent (#4,870,302) and tireless advocacy for reconfigurable computing unlocked a technological paradigm that continues to transform our world four decades later.\n\nHis groundbreaking innovation enabled the rapid prototyping and deployment of custom silicon solutions without the prohibitive costs of traditional ASIC development, democratizing hardware design and accelerating technological progress across countless domains.\n\nToday, Freeman's vision powers cutting-edge advancements in artificial intelligence, high-performance computing, telecommunications, automotive systems, aerospace applications, and numerous other fields that were merely dreams during his lifetime.\n\nPosthumously inducted into the National Inventors Hall of Fame in 2009, his legacy endures not merely in silicon, but in the spirit of technological audacity that challenges us all to question established limitations and imagine new possibilities.\n\n*\"The ultimate goal of the FPGA was to make programmable logic devices that could replace standard digital chips.\"* — Ross Freeman\n\n---\n\n## **Table of Contents**\n\n### **Part 1: Foundational Concepts**\n\n1.  [Introduction](#1-introduction)\n    *   [1.1 Purpose of the Guide](#11-purpose-of-the-guide)\n    *   [1.2 Target Audience](#12-target-audience)\n    *   [1.3 How to Use This Guide](#13-how-to-use-this-guide)\n2.  [Key Definitions](#2-key-definitions)\n3.  [Device Compatibility](#3-device-compatibility)\n    *   [3.1 Supported FPGA-Based Hardware](#31-supported-fpga-based-hardware)\n    *   [3.2 PCIe Hardware Considerations](#32-pcie-hardware-considerations)\n    *   [3.3 System Requirements](#33-system-requirements)\n4.  [Requirements](#4-requirements)\n    *   [4.1 Hardware](#41-hardware)\n    *   [4.2 Software](#42-software)\n    *   [4.3 Environment Setup](#43-environment-setup)\n5.  [Gathering Donor Device Information](#5-gathering-donor-device-information)\n    *   [5.1 Using Arbor for PCIe Device Scanning](#51-using-arbor-for-pcie-device-scanning)\n    *   [5.2 Extracting and Recording Device Attributes](#52-extracting-and-recording-device-attributes)\n6.  [Initial Firmware Customization](#6-initial-firmware-customization)\n    *   [6.1 Modifying Configuration Space](#61-modifying-configuration-space)\n    *   [6.2 Inserting the Device Serial Number (DSN)](#62-inserting-the-device-serial-number-dsn)\n7.  [Vivado Project Setup and Customization](#7-vivado-project-setup-and-customization)\n    *   [7.1 Generating Vivado Project Files](#71-generating-vivado-project-files)\n    *   [7.2 Modifying IP Blocks](#72-modifying-ip-blocks)\n\n### **Part 2: Intermediate Concepts and Implementation**\n\n8.  [Advanced Firmware Customization](#8-advanced-firmware-customization)\n    *   [8.1 Configuring PCIe Parameters for Emulation](#81-configuring-pcie-parameters-for-emulation)\n    *   [8.2 Adjusting BARs and Memory Mapping](#82-adjusting-bars-and-memory-mapping)\n    *   [8.3 Emulating Device Power Management and Interrupts](#83-emulating-device-power-management-and-interrupts)\n9.  [Emulating Device-Specific Capabilities](#9-emulating-device-specific-capabilities)\n    *   [9.1 Implementing Advanced PCIe Capabilities](#91-implementing-advanced-pcie-capabilities)\n    *   [9.2 Emulating Vendor-Specific Features](#92-emulating-vendor-specific-features)\n10. [Transaction Layer Packet (TLP) Emulation](#10-transaction-layer-packet-tlp-emulation)\n    *   [10.1 Understanding and Capturing TLPs](#101-understanding-and-capturing-tlps)\n    *   [10.2 Crafting Custom TLPs for Specific Operations](#102-crafting-custom-tlps-for-specific-operations)\n\n### **Part 3: Advanced Techniques and Optimization**\n\n11. [Building, Flashing, and Testing](#11-building-flashing-and-testing)\n    *   [11.1 Synthesis and Implementation](#111-synthesis-and-implementation)\n    *   [11.2 Flashing the Bitstream](#112-flashing-the-bitstream)\n    *   [11.3 Testing and Validation](#113-testing-and-validation)\n12. [Advanced Debugging Techniques](#12-advanced-debugging-techniques)\n    *   [12.1 Using Vivado's Integrated Logic Analyzer](#121-using-vivados-integrated-logic-analyzer)\n    *   [12.2 PCIe Traffic Analysis Tools](#122-pcie-traffic-analysis-tools)\n13. [Troubleshooting](#13-troubleshooting)\n    *   [13.1 Device Detection Issues](#131-device-detection-issues)\n    *   [13.2 Memory Mapping and BAR Configuration Errors](#132-memory-mapping-and-bar-configuration-errors)\n    *   [13.3 DMA Performance and TLP Errors](#133-dma-performance-and-tlp-errors)\n14. [Emulation Accuracy and Optimizations](#14-emulation-accuracy-and-optimizations)\n    *   [14.1 Techniques for Accurate Timing Emulation](#141-techniques-for-accurate-timing-emulation)\n    *   [14.2 Dynamic Response to System Calls](#142-dynamic-response-to-system-calls)\n15. [Best Practices for Firmware Development](#15-best-practices-for-firmware-development)\n    *   [15.1 Continuous Testing and Documentation](#151-continuous-testing-and-documentation)\n    *   [15.2 Managing Firmware Versioning](#152-managing-firmware-versioning)\n    *   [15.3 Security Considerations](#153-security-considerations)\n16. [Additional Resources](#16-additional-resources)\n17. [Contact Information](#17-contact-information)\n18. [Support and Contributions](#18-support-and-contributions)\n\n---\n\n## **Part 1: Foundational Concepts**\n\n---\n\n## **1. Introduction**\n\n### **1.1 Purpose of the Guide**\n\nThe overarching goal of this guide is to empower you with the knowledge and practical skills to develop custom Direct Memory Access (DMA) firmware for Field-Programmable Gate Array (FPGA)-based devices. This specialized firmware allows your FPGA to accurately emulate the identity and behavior of other PCIe (Peripheral Component Interconnect Express) hardware devices. Such emulation is a powerful technique with profound implications across several advanced domains:\n\n**Hardware Security Research**:\n*   **Vulnerability Discovery**: By emulating a device, you can create a controlled environment to send malformed or unexpected data to host drivers, systematically fuzzing for vulnerabilities (e.g., buffer overflows, race conditions) that might be exploitable from a hardware peripheral.\n*   **Driver Analysis**: Observe how operating systems and specific drivers interact with hardware. You can emulate devices with non-standard configurations or undocumented features to understand driver behavior, identify security assumptions, or reverse-engineer proprietary protocols.\n*   **Side-Channel Analysis**: While more complex, an emulated device could potentially be programmed to assist in experiments related to information leakage through timing or power analysis, by precisely controlling peripheral operations.\n\n**Red Teaming & Penetration Testing**:\n*   **Bypassing Security Measures**: Emulate a seemingly benign or whitelisted hardware device (e.g., a common NIC or storage controller) to gain DMA privileges. Once achieved, this allows direct interaction with system memory, potentially bypassing endpoint detection and response (EDR) systems or anti-malware solutions that operate at higher software layers.\n*   **Stealthy Persistence**: An emulated malicious device could offer a covert way to maintain access to a compromised system, as it might be harder to detect than software-based implants.\n*   **Exploiting Trust Relationships**: Systems often have implicit trust in connected hardware. Custom firmware can exploit this by mimicking devices that are granted specific permissions or access.\n\n**System Debugging & Diagnostics**:\n*   **Reproducible Testbeds**: Create highly specific hardware scenarios to reliably reproduce elusive bugs that may only occur with particular device states or data patterns.\n*   **Fault Injection**: Intentionally emulate faulty device behavior (e.g., incorrect TLP formation, delayed responses) to test the robustness and error handling capabilities of the host system and its drivers.\n\n**Hardware Testing & Validation**:\n*   **Driver Development**: Test new or modified drivers against an emulated hardware profile before physical prototypes are available, or to simulate a wider range of hardware variants than physically accessible.\n*   **Compliance Testing**: While not a substitute for official compliance tests, an emulated device can help pre-verify certain aspects of PCIe protocol adherence.\n\n**Legacy System Support & Interoperability**:\n*   Emulate older, discontinued, or hard-to-source PCIe devices to keep legacy systems operational or to bridge compatibility gaps between different hardware generations.\n\nBy progressing through this guide, you will gain proficiency in:\n*   Meticulously extracting identifying attributes and configuration details from a physical \"donor\" PCIe device.\n*   Modifying and extending existing open-source FPGA firmware frameworks (with a primary focus on the widely-used PCILeech-FPGA project) to adopt the identity of the donor device.\n*   Configuring and utilizing a professional FPGA development toolchain, centered around Xilinx Vivado, alongside essential code editing tools like Visual Studio Code.\n*   Developing a solid understanding of the PCIe architecture's layered model, the mechanics of DMA data transfers, and the nuances of crafting firmware that faithfully replicates hardware behavior at a low level.\n\n### **1.2 Target Audience**\n\nThis guide is tailored for individuals who already possess a foundational to intermediate knowledge of computer systems, hardware principles, and software development. The content is technically demanding and assumes a capacity for detailed, low-level work. Specifically, it caters to:\n\n*   **Firmware Developers**: Engineers aiming to design or adapt firmware for FPGAs, especially for applications involving high-speed data transfer (DMA) and direct hardware interface manipulation over PCIe. A background in Verilog/VHDL and experience with FPGA development tools are highly recommended.\n*   **Hardware Engineers**: Professionals involved in the design, testing, or validation of PCIe-based hardware. This guide can help in creating sophisticated test harnesses or emulating components within a larger system design. Familiarity with PCIe protocol and digital design is expected.\n*   **Cybersecurity Professionals & Researchers**:\n    *   **Vulnerability Researchers & Exploit Developers**: Those looking to explore hardware-level attack surfaces or develop proof-of-concept exploits leveraging DMA. Understanding of OS internals, memory management, and driver architecture is crucial.\n    *   **Red Team Members**: Operators seeking advanced techniques for system access, persistence, and data exfiltration by leveraging direct hardware manipulation.\n    *   **Digital Forensics & Incident Responders**: While this guide is offensively focused, understanding these techniques can aid in recognizing and analyzing sophisticated hardware-based attacks.\n*   **FPGA Enthusiasts & Advanced Hobbyists**: Individuals with prior FPGA project experience who are eager to tackle complex challenges like PCIe communication and hardware emulation. A willingness to delve into datasheets and technical specifications is key.\n\n**Prerequisite Knowledge (Recommended)**:\n*   Solid understanding of digital logic and computer architecture.\n*   Familiarity with at least one Hardware Description Language (HDL), such as Verilog or VHDL.\n*   Basic proficiency in a Linux environment (many tools and scripts are Linux-friendly) and familiarity with command-line interfaces.\n*   Experience with a C/C++ or a scripting language (like Python) for host-side interaction or test scripting.\n*   A conceptual understanding of operating system principles (memory management, drivers, interrupts).\n*   Patience and a methodical approach to debugging, as firmware development can be intricate.\n\nThe learning curve can be steep, especially if PCIe or advanced FPGA concepts are new. However, the guide aims to break down complex topics into manageable steps.\n\n### **1.3 How to Use This Guide**\n\nThis guide is segmented into three logically progressing parts designed to build your knowledge incrementally:\n\n*   **Part 1: Foundational Concepts**: This initial part is crucial. It introduces the core terminology, the underlying principles of PCIe and DMA, the necessary hardware and software stack (including setup instructions for tools like Xilinx Vivado and the PCILeech-FPGA framework), and the initial procedures for acquiring vital information from your target \"donor\" device and making basic firmware modifications. It is strongly advised to work through this part sequentially and thoroughly.\n*   **Part 2: Intermediate Concepts and Implementation**: (Forthcoming sections) Building on the foundation, this part will guide you through more advanced firmware customizations. Topics will include fine-tuning PCIe operational parameters, emulating device-specific registers and capabilities (such as power management states and Message Signaled Interrupts - MSI/MSI-X), and gaining an initial understanding of constructing and interpreting Transaction Layer Packets (TLPs).\n*   **Part 3: Advanced Techniques and Optimization**: (Forthcoming sections) The final part will explore sophisticated debugging methodologies (including the use of Integrated Logic Analyzers - ILAs and external PCIe protocol analyzers), techniques for optimizing firmware performance and emulation accuracy, comprehensive troubleshooting for common and complex issues, and a critical discussion on best practices, particularly focusing on the security implications of developing and deploying emulated PCIe devices.\n\n**Working Through the Guide**:\n*   **Sequential Progression**: Especially for Parts 1 and 2, follow the sections in order, as later concepts build upon earlier ones.\n*   **Hands-On Practice**: This is a practical guide. Actively perform the setup steps, code modifications, and experiments on your own hardware.\n*   **Adapt to Your Environment**: File paths, specific device IDs, and software versions may vary. Understand the concepts behind the instructions to adapt them to your particular setup.\n*   **Consult External Resources**: The PCIe specification and FPGA documentation are your ultimate references. This guide simplifies and directs, but deep dives often require consulting primary sources.\n*   **Iterative Development**: Firmware development is rarely linear. Expect to iterate, debug, and refine your designs. Use the troubleshooting sections and debugging techniques extensively.\n\nYou will be working with HDLs (SystemVerilog in PCILeech-FPGA), FPGA synthesis and implementation tools (Vivado), and potentially host-side programming tools and PCIe analysis utilities.\n\n---\n\n## **2. Key Definitions**\n\nA solid grasp of the following terminology is essential for navigating the complexities of PCIe device emulation and custom firmware development. These terms will be used extensively throughout the guide.\n\n*   **DMA (Direct Memory Access)**:\n    *   **Definition**: A fundamental feature of modern computer architectures that allows hardware peripherals (like network cards, GPUs, or your FPGA-based emulated device) to read from and write to the main system memory (RAM) directly, without involving the Central Processing Unit (CPU) for every byte transferred.\n    *   **Significance**: DMA is crucial for high-performance I/O operations. By offloading data transfer tasks from the CPU, it frees up the CPU to perform other computations, significantly improving overall system throughput and efficiency. In the context of this guide, your FPGA will leverage DMA to interact with the host system's memory, which is a powerful capability often targeted in security research and red teaming.\n\n*   **PCIe (Peripheral Component Interconnect Express)**:\n    *   **Definition**: A high-speed serial computer expansion bus standard designed to replace older bus standards like PCI, PCI-X, and AGP. It uses a point-to-point topology, with separate serial links connecting each device to the root complex (typically part of the chipset or CPU). Communication occurs via packets.\n    *   **Significance**: PCIe is the dominant standard for connecting high-performance peripherals to motherboards. Understanding its protocol, layered architecture (Physical Layer, Data Link Layer, Transaction Layer), and configuration mechanisms is paramount for emulating any modern hardware device.\n\n*   **TLP (Transaction Layer Packet)**:\n    *   **Definition**: The fundamental unit of data exchange at the Transaction Layer of the PCIe protocol. TLPs are responsible for conveying requests (e.g., memory read/write, I/O read/write, configuration read/write) and completions (responses to requests) between PCIe devices. Each TLP consists of a header, an optional data payload, and an optional End-to-End CRC (ECRC).\n    *   **Significance**: To emulate a device accurately, your FPGA firmware must be capable of correctly forming, transmitting, receiving, and interpreting TLPs that match the behavior of the donor device. Understanding TLP types, formats, and flow control is critical for advanced emulation.\n\n*   **BAR (Base Address Register)**:\n    *   **Definition**: Located within a PCIe device's Configuration Space, BARs are special registers used by the device to request address space resources from the host system. A device can have up to six 32-bit BARs (or fewer, or pairs of 32-bit BARs can form 64-bit BARs). These registers define the starting addresses and sizes of memory-mapped I/O (MMIO) regions or I/O port regions that the device uses to expose its registers and internal memory to the host CPU.\n    *   **Significance**: When the host system enumerates a PCIe device, it reads the BARs to determine the device's memory and I/O requirements, then allocates and programs these BARs with the actual base addresses in the system's physical address map. Your emulated device must accurately define its BARs to match the donor device so that the host OS and drivers can interact with it correctly.\n\n*   **FPGA (Field-Programmable Gate Array)**:\n    *   **Definition**: An integrated circuit (IC) that can be configured by a designer or customer after manufacturing – hence \"field-programmable.\" FPGAs contain an array of programmable logic blocks and a hierarchy of reconfigurable interconnects that allow the blocks to be \"wired together\" to implement custom digital logic circuits.\n    *   **Significance**: FPGAs are the core hardware used in this guide. Their reconfigurable nature makes them ideal for emulating other hardware devices, as you can define the precise logic and interfaces required to mimic the donor device's PCIe presence and behavior.\n\n*   **MSI/MSI-X (Message Signaled Interrupts / Message Signaled Interrupts Extended)**:\n    *   **Definition**: Mechanisms that allow a PCIe device to deliver interrupts to the CPU by writing a special message (a TLP, specifically a Memory Write TLP) to a system-defined memory address, rather than using dedicated physical interrupt lines (as in legacy PCI). MSI-X is an enhancement of MSI, offering more interrupt vectors and greater flexibility.\n    *   **Significance**: Most modern PCIe devices use MSI or MSI-X for more efficient and flexible interrupt handling. Accurate emulation often requires implementing the chosen interrupt mechanism of the donor device, including configuring the MSI/MSI-X capability structures and generating interrupt messages correctly.\n\n*   **DSN (Device Serial Number)**:\n    *   **Definition**: A 64-bit globally unique identifier that can be optionally implemented by a PCIe device. If present, it's typically located in an extended capability structure within the device's Configuration Space.\n    *   **Significance**: While not all devices have a DSN, some drivers or management software might use it for unique identification, licensing, or tracking purposes. Emulating it correctly can be important for full transparency and avoiding detection of the emulated device.\n\n*   **PCIe Configuration Space**:\n    *   **Definition**: A standardized 256-byte (for Type 0, endpoint devices) or 4KB address region associated with each PCIe function (a device can have multiple functions). This space contains vital information about the device, including its Vendor ID, Device ID, Class Code, Revision ID, BARs, capability pointers, and various status and control registers. It is accessed by the host system using special Configuration Read and Configuration Write TLPs.\n    *   **Significance**: The Configuration Space is the \"identity card\" of a PCIe device. The very first step in device emulation is to meticulously replicate the relevant parts of the donor device's Configuration Space in your FPGA firmware. The host system uses this information to identify, configure, and allocate resources to the device.\n\n*   **Donor Device**:\n    *   **Definition**: The physical PCIe hardware device whose identity and behavior you aim to emulate on your FPGA. This device serves as the source for extracting configuration details (Vendor ID, Device ID, BAR settings, capabilities, etc.) and behavioral patterns.\n    *   **Significance**: The fidelity of your emulation directly depends on how accurately and completely you can gather and replicate the characteristics of the donor device.\n\n*   **Root Complex (RC)**:\n    *   **Definition**: The entity in a PCIe hierarchy that connects the CPU and memory subsystem to the PCIe fabric. It generates PCIe transactions on behalf of the CPU and processes transactions initiated by downstream PCIe devices. It also performs the initial bus enumeration and configuration.\n    *   **Significance**: Your emulated device will primarily interact with the Root Complex (or switches connected to it) when communicating with the host system.\n\n*   **Endpoint (EP)**:\n    *   **Definition**: A type of PCIe device that resides at the periphery of the PCIe fabric, consuming or producing data. Examples include network cards, graphics cards, storage controllers, and the FPGA device you will be programming. Endpoints request resources and initiate transactions to the Root Complex.\n    *   **Significance**: In this guide, your FPGA will be programmed to act as an Endpoint device, emulating a specific donor Endpoint.\n\n*   **HDL (Hardware Description Language)**:\n    *   **Definition**: A specialized computer language used to describe the structure, design, and operation of electronic circuits, particularly digital logic circuits. Common HDLs include Verilog and VHDL.\n    *   **Significance**: You will be working with Verilog (specifically SystemVerilog, an extension of Verilog) within the PCILeech-FPGA project to define the custom logic for your emulated device.\n\n*   **Bitstream**:\n    *   **Definition**: The final configuration file that is loaded onto an FPGA to program its logic blocks and interconnects, thereby implementing your custom hardware design. It's the compiled output from the FPGA development tools (like Xilinx Vivado).\n    *   **Significance**: Generating and flashing the correct bitstream is the ultimate step in deploying your custom firmware onto the FPGA.\n\n---\n\n## **3. Device Compatibility**\n\nAchieving successful and accurate PCIe device emulation hinges on ensuring your chosen FPGA-based hardware and host system configuration are fully compatible. This section details the supported FPGA platforms, critical PCIe hardware considerations, and the necessary system requirements to set up your development environment.\n\n### **3.1 Supported FPGA-Based Hardware**\n\nWhile this guide provides a generic methodology adaptable to various FPGA-based DMA hardware, our primary examples and specific instructions will focus on **Xilinx 7-series FPGAs**, commonly found in open-source DMA boards due to their balance of performance and accessibility. The **Squirrel DMA (35T)** card is highlighted due to its popularity and well-documented compatibility with the PCILeech-FPGA framework.\n\nThe core principles and techniques for customizing the PCIe IP core and developing hardware description language (HDL) logic are broadly applicable to the following FPGA families and specific boards:\n\n*   **Squirrel (Artix-7 35T)**\n    *   **Description**: A widely available and cost-effective FPGA-based DMA device featuring the Xilinx Artix-7 35T FPGA. It offers sufficient logic resources and memory for standard memory acquisition tasks and a wide range of basic to intermediate device emulation projects. It's an excellent starting point for those new to FPGA-based DMA.\n    *   **Key Features**: Artix-7 offers a good performance-to-cost ratio, making it suitable for educational and research purposes.\n*   **Enigma-X1 (Artix-7 75T)**\n    *   **Description**: A mid-tier FPGA offering enhanced logic and memory resources compared to the 35T, typically based on the Xilinx Artix-7 75T FPGA. This provides greater flexibility for more complex emulation scenarios, larger memory-mapped regions, or more intricate DMA operations that require additional FPGA fabric.\n    *   **Key Features**: Increased logic cells and Block RAM (BRAM) enable more sophisticated designs.\n*   **ZDMA (Artix-7 100T)**\n    *   **Description**: A higher-performance Artix-7 100T-based FPGA, optimized for more demanding memory interactions and extensive reads/writes. This board is suitable for large-scale DMA solutions, high-throughput emulation, or projects that require significant on-chip memory.\n    *   **Key Features**: The 100T variant provides a substantial upgrade in resources, ideal for pushing the boundaries of emulation.\n*   **Kintex-7 (K325T, K410T, etc.)**\n    *   **Description**: Representing an advanced tier, Kintex-7 FPGAs (e.g., K325T, K410T) offer robust capabilities for highly complex projects, large-scale DMA solutions, and applications requiring higher PCIe lane counts or speeds (e.g., Gen3 x8/x16). While more expensive, they provide significantly more logic, DSP slices, and memory, enabling the emulation of highly sophisticated and demanding donor devices.\n    *   **Key Features**: High-performance transceivers for faster PCIe generations, abundant logic and memory resources for complex designs.\n\n**Important Note on FPGA Families**: While the principles are similar, specific IP core configurations and clocking structures may vary slightly between different Xilinx 7-series FPGAs (Artix-7, Kintex-7, Zynq-7000 PS/PL). Always refer to the specific board's documentation and the Xilinx PCIe IP Core user guides for your chosen FPGA family. The PCILeech-FPGA project often provides board-specific Tcl scripts and source files to simplify this process.\n\n### **3.2 PCIe Hardware Considerations**\n\nTo ensure smooth and unrestricted operation of your FPGA-based DMA device for emulation, several PCIe-specific and host system features require careful consideration and, in some cases, modification.\n\n*   **IOMMU / VT-d / AMD-Vi Settings**\n    *   **Recommendation**: For initial setup and testing, it is **highly recommended to disable IOMMU (Intel's Virtualization Technology for Directed I/O - VT-d) or AMD's equivalent (AMD-Vi)** in your system's BIOS/UEFI settings.\n    *   **Rationale**: IOMMUs are hardware components that provide memory management units for DMA-capable devices. They perform address translation, similar to a CPU's MMU, and can enforce memory access permissions. While crucial for security and virtualization (preventing a rogue device from accessing unauthorized memory regions), they *will* restrict your DMA device's access to system memory, potentially interfering with memory acquisition and device emulation. Disabling the IOMMU allows your DMA device unrestricted access, which is often necessary for advanced emulation and security research purposes.\n    *   **Location**: Typically found under \"CPU Configuration,\" \"Virtualization,\" \"Advanced Settings,\" or \"I/O Virtualization\" in your BIOS/UEFI.\n*   **Kernel DMA Protection (Windows) / Thunderbolt Security Level (Linux)**\n    *   **Recommendation (Windows)**: Disable **Kernel DMA Protection** features in modern Windows systems. This includes settings like **Virtualization-Based Security (VBS)** and **Memory Integrity (HVCI)**. These features leverage the IOMMU to prevent unauthorized DMA attacks from external peripherals connected via Thunderbolt or PCIe.\n    *   **Steps (Windows)**:\n        *   Access Windows Security settings: **Start > Settings > Privacy & security > Windows Security > Device security**.\n        *   Under \"Core isolation,\" click \"Core isolation details.\"\n        *   Turn off \"Memory integrity.\"\n        *   You may also need to disable Secure Boot in BIOS/UEFI, as VBS often depends on it.\n        *   **Caution**: Disabling these features significantly **reduces your system's security posture**, making it vulnerable to various attacks, including those involving malicious DMA devices. This should only be done on a dedicated test system, not on your primary machine, and in a secure, isolated environment where you understand the risks.\n    *   **Recommendation (Linux/Thunderbolt)**: If using a system with Thunderbolt ports, understand and potentially adjust the **Thunderbolt Security Level** in your BIOS/UEFI. Lower security levels (e.g., \"No Security,\" \"User Authorization\") are generally required for arbitrary Thunderbolt/PCIe devices to perform DMA without explicit host approval.\n*   **PCIe Slot Requirements**\n    *   **Recommendation**: Use a compatible PCIe slot that physically matches the FPGA device's requirements. Most Artix-7-based DMA cards operate at PCIe Gen2 x1 or x4.\n    *   **Rationale**:\n        *   **Physical Fit**: An x1 card can fit into x1, x4, x8, or x16 slots, but an x4 card requires at least an x4 slot.\n        *   **Performance**: While an x4 card *might* work in an x1 slot (if the physical connector is open-ended or modified), it will operate at the x1 speed, severely limiting data transfer rates. For optimal performance and accurate emulation of a donor device's capabilities, ensure the FPGA board is installed in a slot that provides at least the *emulated* link width and speed (e.g., if you're emulating a Gen2 x4 device, use a Gen2 x4 slot on the host).\n    *   **Motherboard BIOS Settings**: Some motherboards allow configuration of PCIe slot speeds (e.g., forcing Gen1 or Gen2). Ensure these settings do not conflict with your desired emulation speed.\n\n### **3.3 System Requirements**\n\nSetting up a robust development environment is key for efficient firmware development, synthesis, and debugging.\n\n*   **Host System**\n    *   **Processor**: A modern multi-core CPU is essential for running FPGA development tools like Vivado, which are computationally intensive during synthesis and implementation. (e.g., Intel Core i5/i7/i9 or AMD Ryzen 5/7/9 equivalent, 8th generation or newer recommended).\n    *   **Memory (RAM)**: Minimum 16 GB RAM is strongly recommended; **32 GB or more is ideal** for complex FPGA designs, as Vivado can consume significant memory, especially during implementation.\n    *   **Storage**: A Solid-State Drive (SSD) with at least **200 GB of free space** is crucial. FPGA tool installations (Vivado alone can be 50+ GB), project files, and synthesis/implementation outputs can quickly consume disk space. The speed of an SSD dramatically reduces build times.\n    *   **Operating System**:\n        *   **Windows 10/11 (64-bit Professional or Enterprise edition)**: Widely supported by Xilinx Vivado and many hardware debugging tools. Remember the Kernel DMA Protection considerations.\n        *   **Compatible Linux Distribution (64-bit)**: Ubuntu LTS (Long Term Support) releases (e.g., 20.04, 22.04) are commonly used and well-supported for Vivado. Linux often provides a more flexible environment for scripting and low-level PCIe interaction tools.\n*   **Peripheral Devices**\n    *   **JTAG Programmer**: Absolutely necessary for flashing the compiled bitstream onto your FPGA-based DMA card. Examples include Xilinx Platform Cable USB II, Digilent JTAG-HS3, or integrated JTAG programmers found on some development boards. Ensure it's compatible with your FPGA board and Vivado.\n    *   **PCIe Slot**: As discussed in Section 3.2, ensure your host system has an available and compatible PCIe slot for your DMA card.\n    *   **USB Port**: For connecting the JTAG programmer and potentially for a UART/serial console to your FPGA board for debug output.\n\n---\n\n## **4. Requirements**\n\nThis section outlines the essential hardware and software components, along with the recommended environment setup, necessary to embark on custom firmware development for PCIe device emulation. Having these prerequisites in place before you begin will streamline your development process.\n\n### **4.1 Hardware**\n\n*   **Donor PCIe Device**\n    *   **Purpose**: This is the physical hardware device whose configuration and behavior you intend to emulate on your FPGA. It serves as the authoritative source for critical identification details, register values, and operational characteristics.\n    *   **Examples**: Common examples include a standard Network Interface Card (NIC), a SATA or NVMe storage controller, a USB controller, or any other generic PCIe expansion card that you can safely remove from a system for analysis. It is highly recommended to use a device that is *not* essential for the system's operation, as you will be inspecting its low-level configuration.\n*   **DMA FPGA Card**\n    *   **Description**: An FPGA-based development board specifically designed or adapted to perform Direct Memory Access (DMA) operations over a PCIe interface. This is the platform onto which your custom firmware will be loaded.\n    *   **Examples**: As detailed in Section 3.1, compatible cards include the **Squirrel (Artix-7 35T)**, **Enigma-X1 (Artix-7 75T)**, **ZDMA (Artix-7 100T)**, or various **Kintex-7** based solutions. Ensure your chosen card has a PCIe edge connector.\n*   **JTAG Programmer**\n    *   **Purpose**: This crucial tool facilitates the communication between your development PC and the FPGA on your DMA card. It's used to program (flash) the compiled bitstream onto the FPGA and, importantly, for interactive debugging using tools like Vivado's Hardware Manager and Integrated Logic Analyzer (ILA).\n    *   **Examples**:\n        *   **Xilinx Platform Cable USB II**: A traditional, widely compatible programmer for Xilinx FPGAs. Ensure you have the necessary drivers installed.\n        *   **Digilent JTAG-HS3 / JTAG-HS2**: Popular and reliable programmers known for good Vivado integration and support. The HS3 offers faster programming speeds.\n        *   **Integrated JTAG**: Some FPGA boards may have an onboard USB-to-JTAG bridge (e.g., a FTDI chip) which eliminates the need for a separate programmer. Consult your board's documentation.\n\n### **4.2 Software**\n\n*   **Xilinx Vivado Design Suite**\n    *   **Description**: The official, comprehensive FPGA development environment from Xilinx (now AMD). Vivado is essential for synthesizing your HDL code, implementing the design onto the target FPGA, generating the final bitstream, and performing hardware debugging. It includes the necessary IP cores, compilers, and utilities.\n    *   **Download**: Visit the official Xilinx (AMD) downloads page: [https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html).\n    *   **Version Note**: While older versions like Vivado 2020.1 might be referenced in some legacy guides, it is strongly recommended to download a **recent stable version** (e.g., Vivado 2023.x or later) compatible with your target FPGA family (Artix-7, Kintex-7). The PCILeech-FPGA project generally supports newer Vivado versions.\n*   **Visual Studio Code**\n    *   **Description**: A highly customizable and feature-rich code editor from Microsoft. It's an excellent choice for writing and editing your Verilog/SystemVerilog HDL code due to its extensive extension ecosystem, offering features like syntax highlighting, linting, auto-completion, and version control integration.\n    *   **Download**: [https://code.visualstudio.com/](https://code.visualstudio.com/)\n*   **PCILeech-FPGA**\n    *   **Description**: An open-source framework and base code repository for FPGA-based DMA development. It provides ready-to-use PCIe IP core instantiations and a well-structured project that serves as an excellent starting point for custom firmware. This guide heavily leverages its architecture.\n    *   **Repository**: [https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n*   **Arbor (MindShare)**\n    *   **Description**: A powerful and user-friendly software tool specifically designed for in-depth scanning and analysis of PCIe devices. It provides detailed insights into the configuration space, capabilities, and registers of connected PCIe hardware, making it invaluable for gathering donor device information.\n    *   **Download**: Available from the MindShare website: [https://www.mindshare.com/](https://www.mindshare.com/) (You will likely need to navigate to their software section).\n    *   **Note**: Typically requires account creation and may offer a time-limited trial.\n*   **Alternative PCIe Device Analysis Tools**\n    *   **Telescan PE (Teledyne LeCroy)**:\n        *   **Description**: A no-cost utility from Teledyne LeCroy for PCIe traffic analysis and device enumeration. While it's primarily a software tool that interfaces with their hardware protocol analyzers, it can also provide some basic configuration space views without dedicated hardware.\n        *   **Download**: [https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n        *   **Note**: Requires manual registration and approval for download.\n    *   **OS-Native Tools (For basic checks)**:\n        *   **Windows Device Manager**: Provides basic Vendor ID, Device ID, Subsystem ID, and Class Code information under the \"Details\" tab of a device's properties.\n        *   **Linux `lspci` utility**: A powerful command-line tool for inspecting PCIe devices. Use `lspci -nn` for Vendor/Device IDs, `lspci -vvv` for verbose details including BARs and capabilities, and `lspci -s <BUS:DEV.FUN> -xxxx` for raw configuration space dumps.\n\n### **4.3 Environment Setup**\n\nA clean and correctly configured development environment is crucial to avoid common pitfalls and ensure a smooth workflow.\n\n#### **4.3.1 Install Xilinx Vivado Design Suite**\n\n**Steps**:\n1.  **Visit the Xilinx (AMD) Vivado Download Page**: [https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html).\n2.  **Download the Appropriate Version**: Select the latest stable version of Vivado that is compatible with your operating system and, importantly, with your specific FPGA device (e.g., Artix-7, Kintex-7). Check the Vivado release notes for device support.\n3.  **Run the Installer**: Execute the downloaded installer and follow the on-screen instructions carefully.\n4.  **Select Necessary Components**: During installation, you will be prompted to select which device families to install. **Crucially, select the device family corresponding to your FPGA board (e.g., \"7 Series\" for Artix-7/Kintex-7).** This saves significant disk space compared to installing all families. Ensure you select the \"Design Tools\" (Synthesis, Implementation) and \"Programming & Debugging\" components.\n5.  **Launch Vivado**: After installation, launch Vivado to confirm it opens without errors and that licenses (if applicable) are correctly configured.\n\n#### **4.3.2 Install Visual Studio Code**\n\n**Steps**:\n1.  **Visit the Visual Studio Code Download Page**: [https://code.visualstudio.com/](https://code.visualstudio.com/).\n2.  **Download and Install**: Download the installer for your operating system and follow the standard installation prompts.\n3.  **Install Extensions for HDL Support**: Once VS Code is installed, open it and navigate to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X). Search for and install relevant extensions for Verilog/SystemVerilog, such as:\n    *   **Verilog-HDL/SystemVerilog** (by mshr-h)\n    *   **VHDL** (if you also work with VHDL)\n    These extensions provide syntax highlighting, linting, and other helpful features.\n\n#### **4.3.3 Clone the PCILeech-FPGA Repository**\n\nThis repository contains the base firmware structure and scripts you'll be modifying.\n\n**Steps**:\n1.  **Open a Terminal or Command Prompt**: (e.g., Git Bash on Windows, Terminal on Linux).\n2.  **Navigate to Your Desired Directory**: Choose a location where you want to store your projects.\n    ```bash\n    cd ~/Projects/ # On Linux/macOS\n    cd C:\\Users\\YourUsername\\Documents\\Projects\\ # On Windows\n    ```\n3.  **Clone the Repository**:\n    ```bash\n    git clone https://github.com/ufrisk/pcileech-fpga.git\n    ```\n4.  **Navigate to the Cloned Directory**:\n    ```bash\n    cd pcileech-fpga\n    ```\n    This will be your main project directory. The PCILeech-FPGA project often contains subdirectories for different board variants (e.g., `pcileech-artix-7-50t`, `pcileech-squirrel-35t`). You will navigate into the relevant board-specific directory for your particular hardware.\n\n#### **4.3.4 Set Up a Clean Development Environment**\n\n**Recommendation**: Always work in an isolated or dedicated environment, especially when dealing with low-level hardware and potential security implications.\n\n**Steps**:\n1.  **Use a Dedicated Development Machine or Virtual Machine**:\n    *   **Physical Machine**: If possible, use a separate physical computer for your FPGA development and testing. This prevents accidental system instability or security risks on your primary machine.\n    *   **Virtual Machine (VM)**: A VM can be a good option for isolating the development environment. However, direct PCIe passthrough (PCIe Hotplug or VT-d passthrough) to the VM is generally required for the FPGA card to be detected and operate correctly, which can be complex to configure and may still expose the host if not done carefully. For initial tool installation and code editing, a VM is perfectly fine.\n2.  **Minimize Background Applications**: Ensure no other resource-intensive applications are running that might interfere with Vivado's performance during synthesis and implementation.\n3.  **Disable Conflicting Software**: Temporarily disable any anti-virus, firewall, or security software that might interfere with low-level hardware access or JTAG communication during development and testing. Remember to re-enable them when you're done with your work.\n\n---\n\n## **5. Gathering Donor Device Information**\n\nAccurate device emulation hinges on meticulously extracting and replicating critical information from the donor device. This comprehensive data collection enables your FPGA to faithfully mimic the target hardware's PCIe configuration and behavior, ensuring compatibility and functionality when interfacing with the host system.\n\n### **5.1 Using Arbor for PCIe Device Scanning**\n\n**Arbor** is a robust and user-friendly tool designed for in-depth scanning of PCIe devices. It provides detailed insights into the configuration space of connected hardware, making it an invaluable resource for extracting the necessary information for device emulation.\n\n#### **5.1.1 Install Arbor**\n\nTo begin utilizing Arbor for device scanning, you must first install the software on your system.\n\n**Steps:**\n\n1.  **Visit the Arbor Download Page:**\n    *   Navigate to the official MindShare website ([https://www.mindshare.com/](https://www.mindshare.com/)) using your preferred web browser. You'll need to find their \"Software\" or \"Downloads\" section to locate Arbor.\n    *   Ensure you are accessing the site directly to avoid any malicious redirects.\n2.  **Create an Account (if required):**\n    *   Arbor may require you to create a user account to access the download links.\n    *   Provide the necessary information, such as your name, email address, and organization.\n    *   Verify your email if prompted, to activate your account.\n3.  **Download Arbor:**\n    *   Once logged in, locate the download section for Arbor.\n    *   Select the version compatible with your operating system (e.g., Windows 10/11 64-bit).\n    *   Click the **Download** button and save the installer to a known location on your computer.\n4.  **Install Arbor:**\n    *   Locate the downloaded installer file (e.g., `ArborSetup.exe`).\n    *   Right-click the installer and select **Run as administrator** to ensure it has the necessary permissions.\n    *   Follow the on-screen instructions to complete the installation process.\n        *   Accept the license agreement.\n        *   Choose the installation directory.\n        *   Opt to create desktop shortcuts if desired.\n5.  **Verify Installation:**\n    *   Upon completion, ensure that Arbor is listed in your Start Menu or on your desktop.\n    *   Launch Arbor to confirm it opens without errors.\n\n#### **5.1.2 Scan PCIe Devices**\n\nWith Arbor installed, you can proceed to scan your system for connected PCIe devices.\n\n**Steps:**\n\n1.  **Launch Arbor:**\n    *   Double-click the Arbor icon on your desktop or find it via the Start Menu.\n    *   If prompted by User Account Control (UAC), allow the application to make changes to your device.\n2.  **Navigate to the Local System Tab:**\n    *   In the Arbor interface, locate the navigation pane or tabs.\n    *   Click on **Local System** to access tools for scanning the local machine.\n3.  **Scan for PCIe Devices:**\n    *   Look for a **Scan** or **Rescan** button, typically located at the top or bottom of the interface.\n    *   Click **Scan/Rescan** to initiate the detection process.\n    *   Wait for the scanning process to complete; this may take a few moments depending on the number of devices connected.\n4.  **Review Detected Devices:**\n    *   Once the scan is complete, Arbor will display a list of all detected PCIe devices.\n    *   The devices are usually listed with their names, device IDs, and other identifying information.\n\n#### **5.1.3 Identify the Donor Device**\n\nIdentifying the correct donor device is crucial for accurate emulation.\n\n**Steps:**\n\n1.  **Locate Your Donor Device in the List:**\n    *   Scroll through the list of devices detected by Arbor.\n    *   Look for the device matching the make and model of your donor hardware.\n    *   Devices may be listed by their vendor names, device types, or function.\n2.  **Verify Device Details:**\n    *   Click on the device to select it.\n    *   Confirm that the **Device ID** and **Vendor ID** match those of your donor device.\n        *   **Tip:** These IDs are typically found in the device's documentation or on the manufacturer's website. For common devices, a quick web search for \"\\[Device Name] Vendor ID Device ID\" often yields results.\n3.  **View Detailed Configuration:**\n    *   With the device selected, find and click on an option like **View Details** or **Properties**.\n    *   This will open a detailed view showing the device's configuration space and capabilities.\n4.  **Cross-Reference with Physical Hardware:**\n    *   If multiple similar devices are listed, cross-reference the **Slot Number** or **Bus Address** with the physical slot where the donor device is installed. This helps confirm you're analyzing the correct hardware.\n\n#### **5.1.4 Capture Device Data**\n\nExtracting detailed information from the donor device is essential for accurate emulation.\n\n**Information to Extract:**\n\n*   **Device ID (0xXXXX):** A 16-bit identifier unique to the device model.\n*   **Vendor ID (0xYYYY):** A 16-bit identifier assigned to the manufacturer.\n*   **Subsystem ID (0xZZZZ):** Identifies the specific subsystem or variant (e.g., a specific model within a product line).\n*   **Subsystem Vendor ID (0xWWWW):** Identifies the vendor of the subsystem (often the same as the main Vendor ID, but can differ for OEM versions).\n*   **Revision ID (0xRR):** Indicates the hardware revision level of the device.\n*   **Class Code (0xCCCCCC):** A 24-bit code that defines the primary function/type of device (e.g., `0x020000` for Ethernet Controller, `0x010802` for NVMe controller). This helps the OS load generic drivers.\n*   **Base Address Registers (BARs):**\n    *   Registers defining the memory or I/O address regions the device uses.\n    *   Includes BAR0 through BAR5, each potentially 32 or 64 bits. For each BAR, note its **Type (Memory or I/O)**, **Bit Width (32-bit or 64-bit)**, **Size (e.g., 256 MB, 4KB)**, and **Prefetchable Status (Yes/No)**. This is crucial for memory mapping.\n*   **Capabilities:** Lists supported features and their configurations, often found in a linked list structure within the configuration space. Examples include:\n    *   **PCIe Capability Structure**: PCIe Link Speed (e.g., Gen2, Gen3), Link Width (e.g., x1, x4), Max Payload Size, Max Read Request Size.\n    *   **MSI/MSI-X Capability Structure**: Information on Message Signaled Interrupts, including the number of vectors supported.\n    *   **Power Management Capability Structure**: Supported power states (D0, D1, D2, D3hot, D3cold).\n*   **Device Serial Number (DSN):** A 64-bit unique identifier, if the device supports it (found in the \"Device Serial Number\" Extended Capability). Not all devices implement this.\n\n**Steps:**\n\n1.  **Navigate to the PCI Config Tab:**\n    *   Within the device's detailed view, find and select the **PCI Config** or **Configuration Space** tab. This typically presents a decoded view of the raw configuration space registers.\n2.  **Record Relevant Details:**\n    *   Carefully document each of the required fields listed above.\n    *   Use screenshots or copy the values into a text file, a dedicated spreadsheet, or a structured documentation format for accuracy.\n    *   Ensure hexadecimal values are noted correctly, including the `0x` prefix if used.\n3.  **Expand Capability Lists:**\n    *   Look for sections labeled **Capabilities** or **Advanced Features**. These are often clickable or expandable to reveal sub-sections.\n    *   Document each capability present and its relevant parameters (e.g., MSI message control, power state flags, current/max PCIe link settings).\n4.  **Examine BARs in Detail:**\n    *   Within the Configuration Space, locate the entries for BAR0 through BAR5.\n    *   For each active BAR, note its allocated size, whether it's Memory-mapped or I/O, its bit width (32-bit or 64-bit), and if it's prefetchable. This information is often presented clearly in Arbor's GUI.\n5.  **Save the Data for Reference:**\n    *   Compile all the extracted information into a well-organized document (e.g., a Markdown file, a `.txt` file, or an Excel spreadsheet).\n    *   Label each section clearly for easy reference during firmware customization.\n\n\n\nhttps://github.com/user-attachments/assets/0f192c29-d1ad-4e68-aa21-607976037218\n\n\n\n### **5.2 Extracting and Recording Device Attributes**\n\nAfter capturing the data, it's crucial to understand the significance of each attribute and ensure they've been accurately documented for successful emulation.\n\n**Ensure You Have Accurately Recorded the Following:**\n\n1.  **Device ID:**\n    *   **Purpose:** Uniquely identifies the specific model of the PCIe device.\n    *   **Usage in Emulation:** Essential for the host Operating System (OS) to correctly identify the emulated device and, crucially, to attempt to load the appropriate device driver.\n2.  **Vendor ID:**\n    *   **Purpose:** Identifies the manufacturer of the PCIe device.\n    *   **Usage in Emulation:** Used in conjunction with the Device ID to form a unique identifier (`VendorID:DeviceID`) that the OS uses to match the device to its corresponding driver.\n3.  **Subsystem ID and Subsystem Vendor ID:**\n    *   **Purpose:** These optional IDs allow for differentiation between variants of a device from the same vendor, or for OEM-specific versions where the main Vendor/Device ID might be generic.\n    *   **Usage in Emulation:** Important for emulating devices with multiple configurations or those supplied by an OEM, as the driver might specifically look for these values.\n4.  **Revision ID:**\n    *   **Purpose:** Indicates the hardware revision level of the device.\n    *   **Usage in Emulation:** Helps in identifying specific hardware versions that might require different drivers, firmware, or possess subtle behavioral differences.\n5.  **Class Code:**\n    *   **Purpose:** A 24-bit code that categorizes the device's general function (e.g., `0x020000` for an Ethernet controller, `0x010802` for an NVMe controller, `0x0C0300` for a USB host controller). It's composed of a Base Class, Sub-Class, and Programming Interface.\n    *   **Usage in Emulation:** Allows the OS to understand the device's general function and load a generic class driver if a specific vendor driver isn't found. This is crucial for initial device recognition.\n6.  **Base Address Registers (BARs):**\n    *   **Purpose:** Define the memory-mapped or I/O port address regions that the device uses for registers, internal buffers, or configuration space extensions. The host OS allocates physical addresses to these BARs during enumeration.\n    *   **Usage in Emulation:** Critical for mapping the emulated device's internal memory and registers into the host system's address space. The size, type (Memory/I/O, 32/64-bit), and prefetchability status of each BAR must be precisely matched to the donor device.\n7.  **Capabilities:**\n    *   **Purpose:** Lists the advanced features the device supports, such as advanced error reporting, power management, MSI/MSI-X, PCIe Advanced Capabilities (e.g., AER, VC/PF), etc. Each capability is defined by a structure with its own registers.\n    *   **Usage in Emulation:** Essential for accurately replicating how the donor device advertises its features and how the host system interacts with these features (e.g., interrupt delivery mechanisms, power state transitions, error reporting).\n8.  **Device Serial Number (DSN):**\n    *   **Purpose:** A unique 64-bit identifier for the device, typically an optional extended capability.\n    *   **Usage in Emulation:** While optional, some drivers or management applications might specifically query and rely on the DSN for identification, licensing, or security checks. Emulating this accurately can prevent detection of your device as a generic or modified peripheral.\n\n**Best Practices for Data Collection:**\n\n*   **Organize the Data:** Create a structured document or spreadsheet. Use clear headings and subheadings for each attribute. A template can be beneficial.\n*   **Include Units and Formats:** Always indicate units for sizes (e.g., MB, KB) and use consistent formatting for hexadecimal values (e.g., `0x1234`, `16'h1234`).\n*   **Cross-Reference with Specifications (If Possible):** If available, consult the donor device's datasheet or publicly available specifications to verify values. This can help identify any discrepancies or unusual configurations not immediately obvious from a raw scan.\n*   **Secure the Data:** Store the collected information securely. Be mindful that this data might contain proprietary or sensitive information.\n*   **Understand \"What's Missing\":** Specialized tools like Arbor are excellent, but they may not capture every single nuance of complex, highly proprietary devices (e.g., specific vendor-defined registers outside standard configuration space). For advanced emulation, you might need to combine this information with reverse engineering of the donor device's drivers.\n\n---\n\n## **6. Initial Firmware Customization**\n\nWith the donor device's information meticulously documented, the next critical phase involves customizing your FPGA's firmware to emulate the donor device accurately. This process begins by modifying key identification registers within the PCIe configuration space and ensuring that specific identifiers, like the Device Serial Number, are correctly integrated.\n\n### **6.1 Modifying Configuration Space**\n\nThe PCIe Configuration Space is a fundamental component that defines how the device is recognized and interacts with the host system during enumeration. Customizing this space to precisely match the donor device's profile is absolutely essential for successful emulation, allowing the host OS to load the correct driver and interact as expected.\n\n#### **6.1.1 Navigate to the Configuration File**\n\nThe PCIe configuration space parameters are typically defined within a specific SystemVerilog (`.sv`) file in the PCILeech-FPGA project. This file synthesizes into the logic that configures the PCIe IP core and exposes the device's identity to the host.\n\n**Common Path for PCILeech-FPGA (Artix-7 based boards like Squirrel):**\nLocate the file responsible for configuring the PCIe parameters for your specific board. For many Artix-7 PCILeech variants, this will be:\n```\npcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv\n```\n*   **Example (for Squirrel 35T)**:\n    ```\n    pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv\n    ```\n    *Note: The actual folder name like `pcileech-squirrel-35t` might vary slightly based on the specific PCILeech-FPGA version or fork you cloned. Always navigate to the relevant board-specific subdirectory after cloning the main repository.*\n\n#### **6.1.2 Open the File in Visual Studio Code**\n\nEditing the configuration file requires a suitable code editor that supports syntax highlighting for SystemVerilog (or Verilog), making the code easier to read and modify.\n\n**Steps:**\n\n1.  **Launch Visual Studio Code:**\n    *   Click on the VS Code icon or find it via the Start Menu.\n2.  **Open the File:**\n    *   Use **File > Open File** or press `Ctrl + O` (or `Cmd + O` on macOS).\n    *   Navigate to the configuration file path identified in Section 6.1.1 (e.g., `pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv`).\n    *   Select the file and click **Open**.\n3.  **Verify Syntax Highlighting:**\n    *   Ensure that the editor recognizes the `.sv` file extension and applies proper SystemVerilog syntax highlighting. If it doesn't, revisit Section 4.3.2 to ensure you've installed the recommended Verilog/SystemVerilog extensions for VS Code.\n4.  **Familiarize Yourself with the File Structure:**\n    *   Scroll through the file. You will typically find parameters defined using `localparam` or `reg` assignments, often with comments explaining their purpose. Look for sections where standard PCIe configuration registers (Vendor ID, Device ID, etc.) are defined and assigned.\n\n#### **6.1.3 Modify Device ID and Vendor ID**\n\nUpdating these fundamental identifiers is the most crucial step for the host system to correctly recognize the emulated device as your donor. The Operating System relies heavily on the `Vendor ID` and `Device ID` pair to identify connected hardware and load the appropriate device driver.\n\n**Steps:**\n\n1.  **Search for `cfg_deviceid`:**\n    *   Use the search functionality (`Ctrl + F` or `Cmd + F`) within VS Code.\n    *   Locate the line defining `cfg_deviceid`. It will typically look something like:\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'hAAAA; // Default or placeholder Device ID\n        ```\n2.  **Update Device ID:**\n    *   Replace `AAAA` with the 16-bit hexadecimal Device ID you extracted from the donor device using Arbor (e.g., `0x1234`).\n    *   **Example:**\n        If the donor's Device ID is `0x1234`, update the line as:\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'h1234; // Updated with donor's Device ID (e.g., from network card)\n        ```\n3.  **Search for `cfg_vendorid`:**\n    *   Locate the line defining `cfg_vendorid`. It will be similar in format to `cfg_deviceid`:\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hBBBB; // Default or placeholder Vendor ID\n        ```\n4.  **Update Vendor ID:**\n    *   Replace `BBBB` with the 16-bit hexadecimal Vendor ID extracted from the donor device (e.g., `0xABCD`).\n    *   **Example:**\n        If the donor's Vendor ID is `0xABCD`, update the line as:\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hABCD; // Updated with donor's Vendor ID (e.g., Intel Corporation)\n        ```\n5.  **Ensure Correct Formatting:**\n    *   Verify that hexadecimal values are correctly prefixed with `16'h` (indicating a 16-bit hexadecimal number).\n    *   Maintain consistent indentation and commenting style for readability.\n\n#### **6.1.4 Modify Subsystem ID and Revision ID**\n\nThese identifiers provide additional details about the device variant, specific product models, or hardware revisions. While often optional, matching them enhances the authenticity of the emulation and can be critical for drivers that perform granular checks.\n\n**Steps:**\n\n1.  **Search for `cfg_subsysid`:**\n    *   Locate the line defining `cfg_subsysid`.\n    ```verilog\n    reg [15:0] cfg_subsysid = 16'hCCCC; // Placeholder Subsystem ID\n    ```\n2.  **Update Subsystem ID:**\n    *   Replace `CCCC` with the 16-bit hexadecimal Subsystem ID from your donor device (e.g., `0x5678`).\n    *   **Example:**\n        ```verilog\n        reg [15:0] cfg_subsysid = 16'h5678; // Set to donor's Subsystem ID\n        ```\n3.  **Search for `cfg_subsysvendorid`:**\n    *   Locate the line defining `cfg_subsysvendorid`.\n    ```verilog\n    reg [15:0] cfg_subsysvendorid = 16'hDDDD; // Placeholder Subsystem Vendor ID\n    ```\n4.  **Update Subsystem Vendor ID (if applicable):**\n    *   Replace `DDDD` with the 16-bit hexadecimal Subsystem Vendor ID from your donor device (e.g., `0x9ABC`). If your donor device does not have a unique Subsystem Vendor ID (i.e., it's the same as the main Vendor ID), you should still set it to that value.\n    *   **Example:**\n        ```verilog\n        reg [15:0] cfg_subsysvendorid = 16'h9ABC; // Set to donor's Subsystem Vendor ID\n        ```\n5.  **Search for `cfg_revisionid`:**\n    *   Locate the line defining `cfg_revisionid`.\n    ```verilog\n    reg [7:0] cfg_revisionid = 8'hEE; // Placeholder Revision ID\n    ```\n6.  **Update Revision ID:**\n    *   Replace `EE` with the 8-bit hexadecimal Revision ID from your donor device (e.g., `0x01`).\n    *   **Example:**\n        ```verilog\n        reg [7:0] cfg_revisionid = 8'h01; // Set to donor's Revision ID\n        ```\n\n#### **6.1.5 Update Class Code**\n\nThe Class Code informs the host Operating System about the device's general type and function (e.g., network controller, storage device). This is vital for the OS to load generic class drivers, even if a specific vendor driver isn't installed.\n\n**Steps:**\n\n1.  **Search for `cfg_classcode`:**\n    *   Locate the line defining `cfg_classcode`.\n    ```verilog\n    reg [23:0] cfg_classcode = 24'hFFFFFF; // Default or placeholder Class Code\n    ```\n2.  **Update Class Code:**\n    *   Replace `FFFFFF` with the 24-bit hexadecimal Class Code you extracted from the donor device (e.g., `0x020000` for an Ethernet Controller). Remember the format: Base Class, Sub-Class, Programming Interface.\n    *   **Example:**\n        If the donor's Class Code is `0x020000` (meaning Base Class: 0x02 - Network Controller, Sub-Class: 0x00 - Ethernet Controller, Prog IF: 0x00), update as:\n        ```verilog\n        reg [23:0] cfg_classcode = 24'h020000; // Set to donor's Class Code (e.g., Ethernet Controller)\n        ```\n3.  **Verify Correct Bit Width:**\n    *   Ensure that the Class Code is correctly represented as a 24-bit value using the `24'h` prefix for hexadecimal.\n\n#### **6.1.6 Save Changes**\n\nAfter making all modifications to the configuration parameters, it's critically important to save and review the changes.\n\n**Steps:**\n\n1.  **Save the File:**\n    *   Click **File > Save** in VS Code, or press `Ctrl + S` (or `Cmd + S`).\n2.  **Review Changes:**\n    *   Before closing, quickly re-read the modified lines to confirm their accuracy against your documented donor device information.\n    *   Check for any obvious syntax errors or typos (VS Code's extensions may highlight these).\n3.  **Optional - Use Version Control:**\n    *   If you are using Git (highly recommended for any code project, especially firmware), commit your changes with a clear and meaningful message. This creates a historical record of your modifications.\n    *   **Example Git Commands:**\n        ```bash\n        git add pcileech_pcie_cfg_a7.sv\n        git commit -m \"Updated PCIe configuration registers (VID, DID, SubIDs, Revision, Class Code) to match donor device: [Donor Device Name]\"\n        ```\n\n### **6.2 Inserting the Device Serial Number (DSN)**\n\nThe Device Serial Number (DSN) is a unique 64-bit identifier that some PCIe devices (especially those with advanced features or specific drivers) may utilize. Including it enhances the authenticity of your emulation and can help bypass checks in drivers that explicitly query for this value.\n\n#### **6.2.1 Locate the DSN Field**\n\nThe DSN, if implemented by the donor device, is part of the PCIe Extended Capabilities. In the PCILeech-FPGA framework, the DSN field is often exposed as a configurable parameter within the same configuration file you've been editing.\n\n**Steps:**\n\n1.  **Search for `cfg_dsn`:**\n    *   In `pcileech_pcie_cfg_a7.sv` (or your board's equivalent configuration file), use the search function (`Ctrl + F` or `Cmd + F`) to find `cfg_dsn`.\n2.  **Understand the Existing Assignment:**\n    *   The DSN may be set to a default value (often all zeros) or commented out. It will typically look like:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // Default DSN (usually 0 if not used)\n        ```\n\n#### **6.2.2 Insert the DSN**\n\nUpdating the DSN involves setting it to the exact 64-bit hexadecimal value captured from your donor device.\n\n**Steps:**\n\n1.  **Update `cfg_dsn`:**\n    *   Replace the existing hexadecimal value with the 64-bit DSN you extracted from the donor device using Arbor.\n    *   **Example:**\n        If the donor's DSN is `0x0011223344556677`, update as:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0011223344556677; // Donor Device Serial Number\n        ```\n2.  **Handle DSN Unavailability or Irrelevance:**\n    *   If your donor device does *not* have a DSN, or if you've determined it's not a required parameter for the driver you're targeting, you can simply leave it as zeros:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // No specific DSN from donor, leaving as default 0\n        ```\n    *   **Caution**: For critical emulations, if the donor device has a DSN, it's best to emulate it accurately.\n3.  **Ensure Correct Formatting:**\n    *   The DSN is a 64-bit value; ensure it's properly formatted with the `64'h` prefix for hexadecimal values.\n\n#### **6.2.3 Save Changes**\n\nFinalize the DSN modification by saving and reviewing the file.\n\n**Steps:**\n\n1.  **Save the File:**\n    *   Click **File > Save** in VS Code, or press `Ctrl + S`.\n2.  **Verify the Syntax:**\n    *   Check for any red underlines or error indications from VS Code's syntax checker. Correct any issues immediately.\n3.  **Document the Changes:**\n    *   If using version control, commit the updates with an appropriate message.\n    *   **Example Git Commands:**\n        ```bash\n        git commit -am \"Inserted donor Device Serial Number (DSN) into PCIe configuration\"\n        ```\n\n---\n\n## **7. Vivado Project Setup and Customization**\n\nWith the firmware files updated to reflect the donor device's critical identification and configuration data, the next crucial step is to integrate these changes into the Vivado project. This involves generating the project files for your specific FPGA board, customizing the embedded PCIe IP core, and preparing the entire design for the synthesis and implementation phases.\n\n### **7.1 Generating Vivado Project Files**\n\nVivado, the Xilinx (AMD) development suite, uses Tcl (Tool Command Language) scripts to automate project creation, add source files, and configure project settings. By running these scripts provided with the PCILeech-FPGA framework, you ensure that your Vivado project is correctly set up for your target FPGA board.\n\n#### **7.1.1 Open Vivado**\n\nStarting with a fresh session of Vivado ensures that no lingering settings or open projects from previous sessions interfere with your current work.\n\n**Steps:**\n\n1.  **Launch Vivado:**\n    *   Find the Vivado application icon in your Start Menu (Windows) or Applications folder (Linux/macOS).\n    *   Click to open it.\n2.  **Select the Correct Version:**\n    *   If you have multiple Vivado versions installed, ensure you are launching the one compatible with your FPGA board and the PCILeech-FPGA project (as noted in Section 4.3.1, a recent stable version like Vivado 2023.x is recommended).\n3.  **Wait for the Startup Screen:**\n    *   Allow Vivado to fully initialize and present its welcome screen or project dashboard before proceeding.\n\n#### **7.1.2 Access the Tcl Console**\n\nThe Tcl Console within Vivado is your primary interface for executing scripts and direct commands. This is where you will run the project generation scripts.\n\n**Steps:**\n\n1.  **Open the Tcl Console:**\n    *   In the Vivado interface, navigate to the menu bar.\n    *   Click on **Window** > **Tcl Console**.\n    *   The Tcl Console pane will typically appear at the bottom of the Vivado window.\n2.  **Adjust Console Size (Optional):**\n    *   You can drag the console's top border to resize it, making it taller for better visibility of commands and output.\n3.  **Clear Previous Commands (Optional but Recommended):**\n    *   If there are any previous commands or messages, you can right-click within the console and select \"Clear Console\" for a clean start.\n\n#### **7.1.3 Navigate to the Project Directory**\n\nBefore running the Tcl script, you must ensure that the Tcl Console's current working directory is set to the correct location where your board-specific PCILeech-FPGA project scripts reside.\n\n**For Squirrel DMA (Artix-7 35T) or similar boards:**\n\n**Typical Path (after cloning `pcileech-fpga` and navigating to your board variant):**\n```\nC:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/  # On Windows\n~/Projects/pcileech-fpga/pcileech-squirrel-35t/  # On Linux/macOS\n```\n*Note: Replace `<your_board_variant>` with the actual name of the subdirectory for your board (e.g., `pcileech-squirrel-35t`, `pcileech-artix-7-50t`).*\n\n**Steps:**\n\n1.  **Set the Working Directory in Tcl Console:**\n    *   In the Vivado Tcl Console, enter the `cd` command followed by the full path to your board's project directory.\n    *   **Example (Windows):**\n        ```tcl\n        cd C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   **Example (Linux/macOS):**\n        ```tcl\n        cd ~/Projects/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   *Self-correction tip: Use forward slashes (`/`) even on Windows for Tcl paths.*\n2.  **Verify the Directory Change:**\n    *   To confirm you are in the correct directory, enter `pwd` (print working directory) in the Tcl Console.\n    *   The console should display the full path you just set, confirming the change.\n\n#### **7.1.4 Generate the Vivado Project**\n\nRunning the appropriate Tcl script specific to your FPGA board will automate the entire project setup process within Vivado. This includes creating the project, adding all necessary source files (HDL, constraints), and configuring core project settings.\n\n**Steps:**\n\n1.  **Run the Tcl Script:**\n    *   Enter the `source` command followed by the name of the project generation script for your board. The PCILeech-FPGA project typically provides these scripts in the main board directory.\n    *   **For Squirrel (Artix-7 35T) (and similar Artix-7 boards):**\n        ```tcl\n        source vivado_generate_project_squirrel.tcl -notrace\n        ```\n    *   **For Enigma-X1 (Artix-7 75T):**\n        ```tcl\n        source vivado_generate_project_enigma_x1.tcl -notrace\n        ```\n    *   **For ZDMA (Artix-7 100T):**\n        ```tcl\n        source vivado_generate_project_100t.tcl -notrace\n        ```\n    *   The `-notrace` option prevents verbose output for every single Tcl command, keeping the console cleaner.\n2.  **Wait for Script Completion:**\n    *   The script will execute many commands in sequence. This process can take several minutes, depending on your system's performance and the complexity of the project.\n    *   Monitor the Tcl Console for progress messages. The script will:\n        *   Create a new Vivado project (`.xpr` file) in your current directory.\n        *   Add all SystemVerilog/Verilog source files (`.sv`, `.v`).\n        *   Add Xilinx IP core configurations (`.xci`).\n        *   Add XDC (Xilinx Design Constraints) files.\n        *   Potentially configure various project settings.\n    *   **Address Any Errors**: If any errors occur (e.g., \"file not found,\" \"invalid command\"), the script will usually stop. Review the error message, correct the underlying issue (e.g., incorrect path, missing file), and re-run the script.\n3.  **Confirm Project Generation:**\n    *   Upon successful completion, the Tcl Console will typically indicate that the project has been created, and you should see the new project files (e.g., `pcileech_squirrel_top.xpr`) and associated directories (e.g., `pcileech_squirrel_top.runs`, `pcileech_squirrel_top.ip`) generated in your project directory.\n\n#### **7.1.5 Open the Generated Project**\n\nNow that the Vivado project files have been successfully generated by the Tcl script, you can open the project within the Vivado GUI for further inspection and customization.\n\n**Steps:**\n\n1.  **Open the Project:**\n    *   In Vivado, click **File** > **Open Project**.\n    *   Navigate to your project directory (the same one you set in the Tcl Console in Section 7.1.3).\n2.  **Select the Project File:**\n    *   Locate and select the Vivado project file (`.xpr` extension) that corresponds to your board.\n    *   **For Squirrel:** The file will typically be named `pcileech_squirrel_top.xpr`.\n    *   Click on the `.xpr` file to select it.\n3.  **Click Open:**\n    *   Vivado will load the project, displaying the design hierarchy, source files, IP Integrator block design (if used), and various design views. This may take a moment.\n4.  **Verify Project Contents:**\n    *   In the **Project Manager** window (typically on the left), expand the **Sources** pane.\n    *   Ensure that all expected source files (Verilog/SystemVerilog, XDC, IP cores) are listed and that the design hierarchy looks correct.\n    *   Check the **Messages** pane (bottom) for any warnings or critical warnings that appear upon opening the project, as these might indicate potential issues.\n\n### **7.2 Modifying IP Blocks**\n\nThe PCIe IP core is the heart of your device's PCIe interface. It's a pre-verified, configurable block from Xilinx that handles the complex PCIe protocol layers. While some configuration space values are handled in the SystemVerilog file (Section 6.1), other core PCIe parameters, especially those related to link capabilities and BAR structures, are configured directly within the PCIe IP core's customization settings in Vivado. Customizing the IP core ensures that your FPGA behaves identically to the donor hardware at the PCIe protocol level.\n\n#### **7.2.1 Access the PCIe IP Core**\n\nThe PCIe IP core is instantiated as an IP block within your Vivado project. You'll need to open its customization GUI to modify its parameters.\n\n**Steps:**\n\n1.  **Locate the PCIe IP Core:**\n    *   In the **Sources** pane (within the **Project Manager** window), ensure the **Hierarchy** tab is selected.\n    *   Expand the design hierarchy until you find the instance of the PCIe IP core.\n    *   It is commonly named `pcie_7x_0.xci` (for 7-Series FPGAs) or similar, typically found within the `ip` subdirectory of your project sources.\n2.  **Open the IP Customization Window:**\n    *   **Right-click** on the `pcie_7x_0.xci` file.\n    *   From the context menu, select **Customize IP**.\n    *   The **IP Configuration** window (or similar name, like \"Customize IP\" or \"Re-customize IP\") will open, presenting a graphical interface with various tabs and options for configuring the PCIe core.\n3.  **Wait for IP Settings to Load:**\n    *   The IP customization interface may take a few moments to initialize and populate all its settings. Ensure that all options and tabs are fully loaded and responsive before you begin making changes.\n\n#### **7.2.2 Customize Device IDs and BARs within the IP Core**\n\nWhile some device identifiers are set in `pcileech_pcie_cfg_a7.sv`, the PCIe IP core itself also contains internal parameters for Device ID, Vendor ID, and crucially, the definitions for the Base Address Registers (BARs). You must ensure these align. Some values set in the `.sv` file might override or be fed into the IP core, but it's good practice to ensure consistency here too. The BAR settings in the IP core are particularly important as they dictate the hardware implementation of memory mapping.\n\n**Steps:**\n\n1.  **Navigate to Basic/Identification Parameters:**\n    *   In the IP customization window, look for a tab or section related to **Basic**, **Device and Vendor Identifiers**, **General**, or **PCIe Capabilities**. This is where fundamental IDs and initial link settings are defined.\n2.  **Verify/Enter the Device ID, Vendor ID, Subsystem IDs, Revision ID, Class Code:**\n    *   **Crucially, confirm these match the values you put in `pcileech_pcie_cfg_a7.sv` and from your donor device.**\n    *   Find fields like:\n        *   **Device ID**: Enter `0xXXXX` (e.g., `0x1234`).\n        *   **Vendor ID**: Enter `0xYYYY` (e.g., `0xABCD`).\n        *   **Subsystem ID**: Enter `0xZZZZ` (e.g., `0x5678`).\n        *   **Subsystem Vendor ID**: Enter `0xWWWW` (e.g., `0x9ABC`).\n        *   **Revision ID**: Enter `0xRR` (e.g., `0x01`).\n        *   **Class Code**: Enter `0xCCCCCC` (e.g., `0x020000`).\n    *   **Important**: Some IP core versions or specific configurations might pull these directly from the user logic (like `pcileech_pcie_cfg_a7.sv`) or might allow setting them directly here. The most reliable approach is to set them consistently in both places if the option is available in the IP GUI.\n3.  **Navigate to Base Address Registers (BARs) Tab:**\n    *   Within the IP customization window, locate and select the **BARs** tab or section. This is where you define the memory regions the PCIe device exposes.\n4.  **Configure Each BAR:**\n    *   For each BAR (BAR0 through BAR5) that your donor device uses, meticulously configure the following parameters based on the information extracted using Arbor:\n        *   **Enable BAR**: Check this box only if the donor device uses this specific BAR. Disable (uncheck) any BARs the donor device does not use.\n        *   **BAR Size**: Select the exact size from the dropdown list (e.g., **256 MB**, **64 KB**, **4 KB**). This is critical for the host OS to allocate the correct amount of memory.\n        *   **BAR Type**: Choose the appropriate type:\n            *   **Memory (32-bit Addressing)**: For memory-mapped regions accessible with 32-bit addresses.\n            *   **Memory (64-bit Addressing)**: For memory-mapped regions that can reside anywhere in the 64-bit address space (required for large memory regions or if the donor device uses it).\n            *   **I/O**: For legacy I/O port regions (less common in modern PCIe but still possible).\n        *   **Prefetchable**: Check this box if the donor's BAR is marked as prefetchable. This property allows the host system to cache or prefetch data from this region for performance.\n    *   **Example Configuration (based on your donor device):**\n        *   **BAR0**:\n            *   Enabled: Yes\n            *   Size: **256 MB**\n            *   Type: **Memory (64-bit Addressing)**\n            *   Prefetchable: Yes\n        *   **BAR1**:\n            *   Enabled: No (if the donor device does not use BAR1)\n        *   *Continue for BAR2-BAR5, mirroring the donor device's configuration.*\n5.  **Ensure Alignment and Non-Overlapping Spaces**:\n    *   The Vivado IP core typically handles the alignment automatically based on the size you select. However, be aware that PCIe specification requires BAR sizes to be a power of two, and BARs must be aligned to their size.\n    *   Ensure that the total memory mapped by your BARs does not exceed the FPGA's available Block RAM (BRAM) or external memory capabilities.\n\n#### **7.2.3 Finalize IP Customization**\n\nAfter configuring all necessary settings within the IP core's customization window, you must apply these changes for them to take effect in your Vivado project.\n\n**Steps:**\n\n1.  **Review All Settings:**\n    *   Before applying, take a moment to quickly review each tab in the IP customization window one last time.\n    *   Confirm that all entries precisely match the documented specifications of your donor device. A small error here can lead to device detection or functionality issues.\n2.  **Apply Changes:**\n    *   Click the **OK** or **Generate** button (the label may vary) at the bottom of the IP customization window.\n    *   If Vivado prompts you to confirm that you wish to proceed with the changes and regenerate the IP output products, confirm by clicking **Yes**.\n3.  **Regenerate IP Core:**\n    *   Vivado will now regenerate the IP core's output products (e.g., netlists, simulation models, new `.xci` configuration files) to reflect your new configurations.\n    *   Monitor the **Messages** pane (bottom of Vivado window) for any errors, warnings, or critical warnings that may arise during this regeneration process. Address any critical warnings immediately.\n4.  **Update IP in Project:**\n    *   Vivado might automatically update or prompt you to update any IP dependencies in your project after a core is regenerated. Allow it to do so to ensure the latest configuration is used throughout your design.\n\n#### **7.2.4 Lock the IP Core**\n\nLocking the IP core is a recommended best practice in Vivado to prevent unintended modifications or re-customizations during subsequent synthesis and implementation runs, which could potentially revert your carefully configured settings.\n\n**Purpose of Locking:**\n\n*   **Prevent Overwrites:** Ensures that your manual configurations within the IP core's GUI are preserved and not accidentally overwritten by Vivado's automation or if the IP is detected as \"out-of-date\" due to subtle project changes.\n*   **Maintain Consistency:** Keeps the IP core in a known, stable state throughout the build process, which is especially important for critical components like the PCIe interface.\n\n**Steps:**\n\n1.  **Open the Tcl Console:**\n    *   In Vivado, if the Tcl Console is not already open, go to **Window** > **Tcl Console**.\n2.  **Execute the Lock Command:**\n    *   In the Tcl Console, enter the following command precisely. This command sets the `IP_LOCKED` property to `true` for your PCIe IP core instance (`pcie_7x_0`).\n    ```tcl\n    set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n    ```\n    *   Press **Enter** to execute the command.\n3.  **Verify the Lock:**\n    *   Check the **Messages** pane. You should see a confirmation message indicating that the property was set.\n    *   You can also right-click on `pcie_7x_0.xci` in the Sources pane, select \"IP Properties,\" and verify that `IP_LOCKED` is set to `true`. You might also notice that the \"Customize IP\" option is now grayed out or only allows \"Re-customize IP\" which then warns you about the lock.\n4.  **Unlocking (if necessary):**\n    *   If you need to make further modifications to the PCIe IP core's settings in the future, you must first unlock it. Use the following Tcl command:\n    ```tcl\n    set_property -name {IP_LOCKED} -value false -objects [get_ips pcie_7x_0]\n    ```\n    *   Remember to re-lock it after making and applying your changes.\n5.  **Document the Action:**\n    *   It's a good practice to note in your project documentation (e.g., a README file, project notes) that the PCIe IP core has been locked. This helps anyone else working on the project understand its configuration state and avoid confusion.\n\n---\n\n## **Part 2: Intermediate Concepts and Implementation**\n\n---\n\n## **8. Advanced Firmware Customization**\n\nTo achieve a precise and convincing emulation of the donor device, further in-depth customization of the FPGA firmware is necessary beyond just basic identification. This involves aligning the PCIe parameters (such as link speed and transaction sizes), meticulously adjusting Base Address Registers (BARs) and their associated memory mappings, and accurately emulating power management and interrupt mechanisms. These steps ensure that the emulated device not only looks like the original hardware to the host system but also behaves identically at the protocol and functional levels.\n\n### **8.1 Configuring PCIe Parameters for Emulation**\n\nAccurate emulation requires that the PCIe operational parameters of your FPGA device are meticulously configured to match those of the donor device. This includes settings such as the PCIe link speed, link width, capability pointers, and maximum payload sizes. Proper configuration ensures compatibility with the host system, the correct operation of drivers and applications that interact with the device, and optimal performance for data transfer.\n\n#### **8.1.1 Matching PCIe Link Speed and Width**\n\nThe PCIe link speed (e.g., Gen1, Gen2, Gen3) and link width (e.g., x1, x4, x8) are critical parameters that determine the maximum theoretical data throughput and performance of the device. Matching these settings with the donor device is essential for accurate emulation, as drivers or system components might expect specific link capabilities.\n\n**Steps:**\n\n1.  **Access PCIe IP Core Settings:**\n    *   **Open Your Vivado Project:** Launch Vivado and open the project you previously created or modified (e.g., `pcileech_squirrel_top.xpr`). Ensure that all source files are correctly added to the project.\n    *   **Locate the PCIe IP Core:** In the **Sources** pane (typically on the left), expand the design hierarchy to find the PCIe IP core instance. For Xilinx 7-series designs (like Artix-7 used in Squirrel), this is usually named `pcie_7x_0.xci`.\n    *   **Customize the IP Core:** Right-click on `pcie_7x_0.xci` and select **Customize IP**. The IP customization window will open, displaying various configuration options across multiple tabs.\n\n2.  **Set Maximum Link Speed:**\n    *   **Navigate to Link Parameters:** In the IP customization window, click on the **PCIe Capabilities** tab (or sometimes \"PCIe Configuration\" or \"General\"). Within this, look for a section related to **Link Parameters** or **Link Capability Register**.\n    *   **Configure Maximum Link Speed:** Find the option labeled **Maximum Link Speed** (or \"Target Link Speed\").\n    *   Set it to match the maximum link speed supported and advertised by your donor device.\n        *   **Example:**\n            *   If the donor device operates at **PCIe Gen2 (5.0 GT/s)**, select **5.0 GT/s**.\n            *   If it operates at **PCIe Gen1 (2.5 GT/s)** or **PCIe Gen3 (8.0 GT/s)**, select the corresponding option.\n    *   **Note**: Ensure that your FPGA's transceivers and the physical hardware (motherboard PCIe slot) support the selected link speed. The FPGA will only negotiate up to its configured maximum.\n\n3.  **Set Link Width:**\n    *   **Configure Link Width:** In the same **Link Parameters** section, locate the **Link Width** setting (or \"PCIe Link Width,\" \"Target Link Width\").\n    *   Set it to match the maximum link width advertised by your donor device.\n        *   **Example:**\n            *   If the donor device uses a **x4** link, set the **Link Width** to **4**.\n            *   Options typically include **1**, **2**, **4**, **8**, **16** lanes.\n    *   **Note**: The physical PCIe slot and the FPGA's package must support the selected link width. Attempting to configure a width greater than the physical connection will result in link negotiation issues.\n\n4.  **Save and Regenerate:**\n    *   **Apply Changes:** After configuring the link speed and width, click **OK** to apply the changes within the IP customization window.\n    *   **Regenerate IP Output Products:** Vivado will likely prompt you to regenerate the IP core's output products due to the changes made. Confirm and allow the regeneration process to complete. This can take some time.\n    *   **Verify Settings:** Once regeneration is complete, you can optionally revisit the IP core settings to ensure the configurations are correctly applied. Check for any warnings or errors in the **Messages** window in Vivado.\n\n#### **8.1.2 Setting Capability Pointers**\n\nCapability pointers within the PCIe configuration space are 8-bit registers that form a linked list, pointing to various capability structures (e.g., Power Management, MSI/MSI-X, PCIe Express Capability). Correctly setting these pointers ensures that the host system can traverse the capability list and locate and utilize the device's advertised features.\n\n**Steps:**\n\n1.  **Locate Capability Pointer in Firmware:**\n    *   **Open Configuration File:** In Visual Studio Code, open the primary configuration file for your board, typically `pcileech_pcie_cfg_a7.sv`, located at `pcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv`.\n    *   **Understand the Capability Pointer:** The capability pointer (`cfg_cap_pointer`) in this file points to the *first* capability structure in the PCIe configuration space, usually starting after the standard 64-byte configuration header. Subsequent capabilities are chained by their \"Next Capability Pointer\" fields.\n\n2.  **Set Capability Pointer Value:**\n    *   **Find the Assignment for `cfg_cap_pointer`:** Search for the line in the code where `cfg_cap_pointer` is assigned.\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'hXX; // Current value (e.g., 8'h40 for default)\n        ```\n    *   **Update the Capability Pointer:** Replace `XX` with the 8-bit hexadecimal capability pointer value observed from your donor device using Arbor. This value typically points to the offset of the first capability structure after the Device-Specific Configuration Space (which usually ends at offset `0x3F`). A common starting point for capabilities is `0x40` or `0x60`.\n        *   **Example:**\n            *   If the donor device's first capability pointer is `0x60` (meaning its first capability structure starts at offset `0x60` in the configuration space), update the line to:\n                ```verilog\n                reg [7:0] cfg_cap_pointer = 8'h60; // Updated to match donor device's first capability offset\n                ```\n    *   **Ensure Correct Alignment:** Capability structures must be aligned on a 4-byte boundary. The capability pointer should always point to a valid 4-byte aligned offset within the configuration space.\n\n3.  **Save Changes:**\n    *   **Save the Configuration File:** After making the changes, save the file by clicking **File > Save** or pressing `Ctrl + S`.\n    *   **Verify Syntax:** Ensure there are no syntax errors introduced by the changes (VS Code will usually highlight these).\n    *   **Comment for Clarity:** Add a comment explaining the change for future reference and maintainability.\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'h60; // Set to donor's capability pointer (e.g., PCIe Cap at 0x60)\n        ```\n\n#### **8.1.3 Adjusting Maximum Payload and Read Request Sizes**\n\nThese parameters define the maximum amount of data that can be transferred in a single PCIe Transaction Layer Packet (TLP) and the maximum size of a non-posted Memory Read Request TLP. Matching these settings with the donor device ensures compatibility and optimal performance for data transfer operations. Mismatches can lead to reduced throughput or communication errors.\n\n**Steps:**\n\n1.  **Set Maximum Payload Size Supported (IP Core):**\n    *   **Access Device Capabilities:** In the PCIe IP core customization window (`pcie_7x_0.xci` in Vivado), navigate to the **PCIe Capabilities** tab.\n    *   **Configure Max Payload Size Supported:** Find the setting labeled **Max Payload Size Supported** (or similar).\n    *   Set it to the value supported and advertised by your donor device (e.g., 128 bytes, 256 bytes, 512 bytes, 1024 bytes, 2048 bytes, 4096 bytes).\n        *   **Example:** If the donor device supports a maximum payload size of **256 bytes**, select **256 bytes** from the dropdown.\n\n2.  **Set Maximum Read Request Size Supported (IP Core):**\n    *   **Configure Max Read Request Size Supported:** In the same tab, find the **Max Read Request Size Supported** setting.\n    *   Set it to match the donor device's capability. This specifies the maximum amount of data a device can request in a single read transaction.\n        *   **Example:** If the donor supports a maximum read request size of **512 bytes**, select **512 bytes**.\n\n3.  **Adjust Firmware Parameters (Matching IP Core):**\n    *   **Open `pcileech_pcie_cfg_a7.sv`:** Ensure that the configuration file is open in Visual Studio Code.\n    *   **Update Firmware Constants:** Locate the lines where `max_payload_size_supported` and `max_read_request_size_supported` are defined. These are typically bit-encoded values that correspond to the byte sizes you selected in the IP core.\n        ```verilog\n        reg [2:0] max_payload_size_supported = 3'bZZZ;   // Current value\n        reg [2:0] max_read_request_size_supported = 3'bWWW; // Current value\n        ```\n    *   **Set the Appropriate Values:** Replace `ZZZ` and `WWW` with the 3-bit binary representations corresponding to the selected sizes.\n        *   **Mapping (as per PCIe spec):**\n            *   **128 bytes**: `3'b000`\n            *   **256 bytes**: `3'b001`\n            *   **512 bytes**: `3'b010`\n            *   **1024 bytes**: `3'b011`\n            *   **2048 bytes**: `3'b100`\n            *   **4096 bytes**: `3'b101`\n        *   **Example:**\n            *   For **256 bytes** payload size:\n                ```verilog\n                reg [2:0] max_payload_size_supported = 3'b001; // Supports up to 256 bytes (0x100)\n                ```\n            *   For **512 bytes** read request size:\n                ```verilog\n                reg [2:0] max_read_request_size_supported = 3'b010; // Supports up to 512 bytes (0x200)\n                ```\n    *   **Reasoning**: These firmware parameters often dictate the behavior of your user logic that interfaces with the PCIe core, ensuring that your logic respects the configured maximums.\n\n4.  **Save Changes:**\n    *   **Save the File:** After updating the values in `pcileech_pcie_cfg_a7.sv`, save the file.\n    *   **Verify Consistency:** It's crucial that the values configured in the Vivado PCIe IP core's GUI *match* the values set in your HDL configuration file. Any mismatch can lead to unexpected behavior or link training issues.\n    *   **Add Comments:** Document these changes clearly in your code for future reference.\n\n### **8.2 Adjusting BARs and Memory Mapping**\n\nBase Address Registers (BARs) are fundamental to how a PCIe device exposes its internal memory and registers to the host system. Correctly configuring the BARs and defining their memory mapping within your FPGA's BRAMs (Block RAMs) and logic is crucial for accurate emulation and the proper operation of host-side device drivers.\n\n#### **8.2.1 Setting BAR Sizes and Types (IP Core & BRAMs)**\n\nConfiguring the BAR sizes and types ensures that your emulated device requests the correct amount of address space from the host during enumeration and that the host allocates and maps these regions appropriately. This also involves associating these address regions with physical memory blocks within your FPGA.\n\n**Steps:**\n\n1.  **Access BAR Configuration (PCIe IP Core):**\n    *   **Customize PCIe IP Core:** In Vivado, right-click on `pcie_7x_0.xci` and select **Customize IP** to open its configuration GUI.\n    *   **Navigate to BARs Tab:** In the IP customization window, click on the **Base Address Registers (BARs)** tab.\n\n2.  **Configure Each BAR (IP Core):**\n    *   **Match Donor Device's BARs:** For each BAR (BAR0 to BAR5), set the size, type, and prefetchable status to precisely match what you extracted from the donor device using Arbor.\n    *   **Enable/Disable BARs:** Ensure that only the BARs actually used by the donor device are enabled. Disable (uncheck) any unused BARs.\n    *   **Set BAR Sizes:** Select the appropriate size from the dropdown for each *enabled* BAR. This will be a power-of-two size (e.g., 4KB, 8KB, 64KB, 1MB, 256MB, 1GB).\n        *   **Example:**\n            *   If **BAR0** is **64 KB**, set **BAR0 Size** to **64 KB**.\n            *   If **BAR1** is **128 MB**, set **BAR1 Size** to **128 MB**.\n    *   **Set BAR Types:**\n        *   Choose between **Memory (32-bit Addressing)** or **Memory (64-bit Addressing)** if the BAR is memory-mapped. Select **64-bit Addressing** if the donor device's BAR is 64-bit or if you require access to addresses above 4GB.\n        *   Choose **I/O** if the BAR is for I/O port space (less common for modern PCIe devices).\n    *   **Set Prefetchable Status**: Check the \"Prefetchable\" box if the donor's BAR was identified as prefetchable. This bit allows the host to prefetch data from that region, potentially improving performance.\n\n3.  **Update BRAM Configurations (if applicable):**\n    *   Many PCILeech-FPGA projects use Xilinx Block RAM (BRAM) IP cores to represent the memory regions exposed by the BARs. These BRAMs provide the physical storage for your emulated device's memory.\n    *   **Locate BRAM IP Cores:** In your Vivado project's **Sources** pane, within the `ip` subdirectory (or similar), you might find `.xci` files for BRAMs, potentially named like:\n        ```\n        pcileech-fpga/<your_board_variant>/ip/bram_bar_zero4k.xci\n        pcileech-fpga/<your_board_variant>/ip/bram_pcie_cfgspace.xci\n        # And potentially others for BAR1, BAR2 etc.\n        ```\n    *   **Modify BRAM Sizes:** For each BRAM IP core associated with an *enabled* BAR, you may need to **Customize IP** (right-click on the `.xci` file) and adjust its memory size configuration to exactly match the corresponding BAR size you set in the PCIe IP core.\n        *   **Example:** If BAR0 is 256MB, ensure the BRAM connected to BAR0 has a size of 256MB.\n        *   **Caution**: Ensure that the total memory required by all active BARs does not exceed the physical BRAM capacity of your FPGA device. Exceeding capacity will lead to implementation failures.\n\n4.  **Save and Regenerate:**\n    *   **Apply Changes (IP Core):** After configuring the BARs in the PCIe IP core, click **OK** in the IP customization window.\n    *   **Regenerate IP Cores:** Vivado will prompt you to regenerate the PCIe IP core and any associated BRAM IP cores due to the size changes. Allow the regeneration to complete. This ensures the hardware netlist reflects your new BAR definitions.\n    *   **Check for Errors:** Review the **Messages** window for any warnings or errors related to BAR configurations or BRAM instantiation.\n\n#### **8.2.2 Defining BAR Address Spaces in Firmware**\n\nWhile the PCIe IP core configures the *hardware* aspects of the BARs, your custom firmware (SystemVerilog code) needs to define the *logic* for how your emulated device responds when the host CPU performs read or write operations to addresses within these BAR regions. This involves address decoding and implementing register/memory access logic.\n\n**Steps:**\n\n1.  **Open the BAR Controller File:**\n    *   In Visual Studio Code, open the SystemVerilog file responsible for handling BAR accesses. For PCILeech-FPGA, this is often:\n        ```\n        pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv\n        ```\n        This module typically receives PCIe Memory Read/Write TLPs and decodes the address to determine which BAR (and which offset within that BAR) is being accessed.\n\n2.  **Implement Address Decoding Logic:**\n    *   Within the `pcileech_tlps128_bar_controller.sv` module, you'll find logic that determines which BAR an incoming transaction targets. This often involves checking the address bits against the configured BAR sizes.\n    *   You'll need to define how the incoming address `req_addr` (from the TLP) maps to an offset within your specific BAR.\n    *   **Conceptual Example:**\n        ```verilog\n        // Example: Logic for BAR0 (assuming it's a 256MB 64-bit Memory BAR, for registers/data)\n        // 'bar_hit[0]' would be an input signal indicating a hit on BAR0, typically from the PCIe core.\n        // 'req_addr' is the incoming PCIe address.\n        // 'req_be' is the byte enable from the TLP.\n        // 'req_data' is the incoming write data.\n        // 'rsp_data' is the outgoing read data.\n\n        // Assuming BAR0 is 256MB (2^28 bytes), address bits [27:0] are within the BAR.\n        localparam BAR0_SIZE_BITS = 28; // 2^28 = 256MB\n\n        reg [31:0] internal_register_0; // Example register within BAR0\n        reg [31:0] internal_register_1; // Another example register\n\n        assign bar0_offset = req_addr[BAR0_SIZE_BITS-1:0]; // Extract offset within BAR0\n\n        always_comb begin\n            // Default response\n            rsp_data = 32'hFFFFFFFF; // Default to all F's or similar for unmapped regions\n\n            if (bar_hit[0]) begin // If the transaction targets BAR0\n                if (req_write) begin // This is a write operation\n                    case (bar0_offset)\n                        // Example: Map offset 0x0 to internal_register_0\n                        32'h0000_0000: begin\n                            if (req_be[3]) internal_register_0[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_0[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_0[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_0[7:0]   = req_data[7:0];\n                        end\n                        // Example: Map offset 0x4 to internal_register_1\n                        32'h0000_0004: begin\n                            if (req_be[3]) internal_register_1[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_1[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_1[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_1[7:0]   = req_data[7:0];\n                        end\n                        // Add more register mappings or memory accesses (e.g., BRAM access)\n                        default: begin\n                            // Handle unmapped writes within BAR0, e.g., ignore or log\n                        end\n                    endcase\n                end else if (req_read) begin // This is a read operation\n                    case (bar0_offset)\n                        // Example: Read from internal_register_0\n                        32'h0000_0000: rsp_data = internal_register_0;\n                        // Example: Read from internal_register_1\n                        32'h0000_0004: rsp_data = internal_register_1;\n                        // Add more register mappings or memory accesses (e.g., BRAM access)\n                        default: begin\n                            rsp_data = 32'h0; // Return 0 for unmapped reads or specific error value\n                        end\n                    endcase\n                end\n            end\n        end\n        ```\n    *   **Handle Data Transfers:** The `always_comb` block (or `always_ff` for sequential logic) should define how `rsp_data` is generated for reads and how internal registers/memories are updated for writes, based on the `bar0_offset` and byte enables (`req_be`).\n\n3.  **Implement BRAM Accesses (if BAR maps to BRAM):**\n    *   If a BAR maps to a large block of memory (e.g., 256MB), you'll typically instantiate a BRAM IP core (as discussed in 8.2.1) and interface your `bar_controller` logic to it. The `bar_controller` would provide the address and control signals to the BRAM.\n    *   **Conceptual BRAM Integration (simplified):**\n        ```verilog\n        // Inside pcileech_tlps128_bar_controller.sv or a sub-module\n        // Interface to BRAM\n        wire [BAR0_SIZE_BITS-1:0] bram_addr;\n        wire [31:0] bram_wr_data;\n        wire [3:0] bram_wr_en; // Byte enables for BRAM\n        wire bram_wr_ce;\n        wire bram_rd_ce;\n        wire [31:0] bram_rd_data;\n\n        // Map TLP signals to BRAM interface\n        assign bram_addr = bar0_offset;\n        assign bram_wr_data = req_data;\n        assign bram_wr_en = req_be;\n        assign bram_wr_ce = bar_hit[0] && req_write;\n        assign bram_rd_ce = bar_hit[0] && req_read;\n\n        // Instantiate the BRAM IP core\n        bram_bar_zero bram_inst ( // Assuming 'bram_bar_zero' is your BRAM IP module\n            .clka(clk),\n            .ena(1'b1),\n            .wea(bram_wr_en),\n            .addra(bram_addr),\n            .dina(bram_wr_data),\n            .douta(bram_rd_data)\n        );\n\n        // For reads from BAR0, output data from BRAM\n        if (bar_hit[0] && req_read) begin\n            rsp_data = bram_rd_data;\n        end\n        ```\n\n4.  **Save Changes:**\n    *   After implementing the logic for each BAR, save the `pcileech_tlps128_bar_controller.sv` file.\n    *   **Verify Functionality:** This logic is complex. Thorough simulation (using a test bench) and later hardware testing will be crucial to ensure correct behavior.\n\n#### **8.2.3 Handling Multiple BARs**\n\nProperly managing multiple BARs is essential for devices that expose several distinct memory or I/O regions. The `bar_controller` module typically handles all BARs.\n\n**Steps:**\n\n1.  **Implement Logic for Each BAR:**\n    *   Within `pcileech_tlps128_bar_controller.sv`, extend the logic to handle all enabled BARs (BAR0, BAR1, BAR2, etc.) that your donor device uses.\n    *   **Separate Logic Blocks:** For clarity and maintainability, create distinct `if/else if` blocks or `case` statements that activate based on which `bar_hit` signal is asserted.\n        ```verilog\n        // BAR0 Handling\n        if (bar_hit[0]) begin\n            // BAR0 specific read/write logic for its registers/memory\n        end else if (bar_hit[1]) begin\n            // BAR1 specific read/write logic for its registers/memory\n        end else if (bar_hit[2]) begin\n            // BAR2 specific logic\n        end\n        // ... continue for other BARs\n        ```\n    *   **Define Registers and Memories:** Allocate separate sets of registers or connect distinct BRAM instances for each BAR as needed.\n\n2.  **Ensure Non-Overlapping Address Spaces:**\n    *   While the PCIe IP core handles the negotiation of distinct address spaces for each BAR with the host OS, your internal firmware logic *must* assume that these spaces are separate and non-overlapping.\n    *   **Validate Address Ranges**: Double-check your BAR size configurations in the PCIe IP core to ensure they are distinct and correctly aligned to power-of-two boundaries as per PCIe specifications.\n    *   **Update Address Decoding**: Your `bar_controller` logic relies on the `bar_hit` signals generated by the PCIe IP core. Ensure these are correctly interpreted and lead to the unique handling logic for each BAR.\n\n3.  **Test BAR Accesses:**\n    *   **Simulation Testing:** Before hardware deployment, use simulation tools (e.g., Vivado Simulator) with a comprehensive test bench to verify all read and write operations to each BAR.\n        *   Send Memory Write TLPs to specific offsets within each BAR.\n        *   Send Memory Read TLPs to specific offsets within each BAR and verify the returned data.\n    *   **Hardware Testing:** After programming the FPGA, use host-side software tools (like PCILeech client software, or custom C/Python scripts) to access and verify each BAR.\n        *   **Linux**: Use `lspci -vvv` to inspect BAR mappings (`Memory at XXXX (64-bit, prefetchable) [size=YYYY]`). You can then use `devmem2` or a custom kernel module to read/write to these mapped addresses.\n        *   **Windows**: Use tools like \"RW-Everything\" or custom user-mode applications to inspect and interact with the mapped memory regions.\n        *   Perform various read/write patterns to ensure data integrity and correct addressing across all BARs.\n\n---\n\n### **8.3 Emulating Device Power Management and Interrupts**\n\nEmulating power management features and implementing interrupts are critical for devices that need to interact closely and efficiently with the host operating system's power management and interrupt handling mechanisms. Without these, the emulated device may not appear fully functional, or performance could be suboptimal.\n\n#### **8.3.1 Power Management Configuration**\n\nImplementing power management allows the emulated device to support various power states (e.g., D0, D3hot), contributing to system-wide power efficiency and compliance with operating system expectations. The host OS will query the device's capabilities and send commands to transition between these states.\n\n**Steps:**\n\n1.  **Enable Power Management in PCIe IP Core:**\n    *   **Access Capabilities:** In the PCIe IP core customization window (`pcie_7x_0.xci`), navigate to the **PCIe Capabilities** tab.\n    *   **Enable Power Management:** Look for a section or option related to **Power Management Capability**. Ensure this is checked or enabled to include the Power Management (PM) capability structure in the device's configuration space.\n\n2.  **Set Power States Supported:**\n    *   **Configure Supported States:** Within the Power Management Capability section of the IP core, specify which power states the device supports. These are typically checkboxes or dropdowns. Match these settings to the donor device's capabilities as observed by Arbor.\n        *   **D0 (Fully On/Operational)**: Always supported.\n        *   **D1, D2 (Intermediate States)**: Optional, for low-power idle states.\n        *   **D3hot (Power Down, Auxiliary Power Present)**: Device logic is off, but can respond to PM events.\n        *   **D3cold (Power Off)**: No power to the device.\n    *   **Example**: If the donor device only supports D0 and D3hot, enable only those.\n\n3.  **Implement Power State Logic in Firmware:**\n    *   **Open `pcileech_pcie_cfg_a7.sv` (or relevant control module):** You'll typically need to modify the firmware to reflect and potentially react to power state transitions commanded by the host. The PCIe core itself handles much of the protocol, but your user logic needs to know the state.\n    *   **Handle Power Management Control and Status Register (PMCSR) Writes:** The host OS changes the device's power state by writing to specific bits in the PMCSR, which is part of the PM Capability structure. Your firmware should ideally have logic to read these bits and adjust device behavior (e.g., pausing/resuming operations, enabling/disabling clocks).\n        ```verilog\n        // Example: Part of pcileech_pcie_cfg_a7.sv or a dedicated PM module\n        // Assume 'cfg_write' is asserted for config writes, 'cfg_address' is the offset, 'cfg_writedata' is the data.\n        // The D-state bits are at offset 0x04 within the PM capability structure, bits [1:0].\n\n        // PMCSR Register (Internal representation)\n        reg [15:0] pmcsr_reg = 16'h0000; // Initialize to D0\n\n        // User logic signal indicating current power state\n        reg [1:0] current_d_state = 2'b00; // 00 = D0, 01 = D1, 10 = D2, 11 = D3hot\n\n        always @(posedge clk) begin\n            if (reset) begin\n                pmcsr_reg <= 16'h0000;\n                current_d_state <= 2'b00; // Reset to D0\n            end else begin\n                // Example: Capture writes to PMCSR (if directly handled in user logic)\n                // Note: The PCIe IP core manages much of this, but your user logic might need to read values from it.\n                // Assuming the PCIe core provides an output reflecting the current D-state:\n                // assign current_d_state = pcie_core_d_state_output;\n\n                // If user logic *needs* to write to PMCSR (less common, usually read-only status)\n                // Or if it needs to process the command\n                // if (cfg_write && (cfg_address == PM_CAP_OFFSET + 2'h04)) begin // PMCSR is at +0x04 from PM Cap base\n                //     pmcsr_reg[1:0] <= cfg_writedata[1:0]; // Capture New D-state\n                //     // current_d_state <= cfg_writedata[1:0]; // Update internal state\n                // end\n\n                // In PCILeech, the PCIe core manages the PMCSR. You would likely read a signal from the core.\n                // For demonstration, let's assume 'pcie_d_state' is an input from the IP core.\n                current_d_state <= pcie_d_state; // Update based on PCIe core's status\n            end\n        end\n\n        // Example: Logic reacting to D-state changes\n        always @(*) begin\n            if (current_d_state == 2'b11) begin // D3hot state\n                // Disable power to non-essential blocks, pause operations,\n                // assert a signal to main DMA logic to stop activity.\n                // For instance: dma_engine_enable = 1'b0;\n            end else if (current_d_state == 2'b00) begin // D0 state\n                // Enable full functionality\n                // For instance: dma_engine_enable = 1'b1;\n            end\n        end\n        ```\n    *   **Manage Power State Effects:** Implement logic to alter the device's internal behavior (e.g., enable/disable clocks, put sub-modules into low-power modes) based on the `current_d_state`. This is crucial for accurate power consumption emulation and to ensure the device responds correctly to OS commands.\n\n4.  **Save Changes:**\n    *   Save any modified firmware files.\n    *   Thoroughly test power management features through simulation or hardware testing (e.g., Windows \"Sleep\" or \"Hibernate\" functions, or Linux `poweroff` commands to see if the device transitions correctly).\n\n#### **8.3.2 MSI/MSI-X Configuration**\n\nImplementing Message Signaled Interrupts (MSI) or its extended version (MSI-X) allows the emulated device to use message-based interrupts. These are significantly more efficient and scalable than traditional pin-based interrupts (INTx) and are the preferred method for modern PCIe devices. MSI/MSI-X allow the device to notify the CPU by writing a special TLP to a specific memory address.\n\n**Steps:**\n\n1.  **Enable MSI/MSI-X in PCIe IP Core:**\n    *   **Access Interrupts Configuration:** In the PCIe IP core customization window (`pcie_7x_0.xci`), navigate to the **Interrupts** tab or a section specifically labeled **MSI/MSI-X Capabilities**.\n    *   **Select Interrupt Type:** Choose between **MSI** or **MSI-X** based on the donor device's capabilities. MSI-X is generally preferred for its flexibility (more vectors, per-vector masking).\n    *   **Configure Number of Supported Vectors:** Set the number of interrupt vectors (messages) that the device will support. Match this to the donor device.\n        *   **MSI** supports up to 32 vectors (typically 1, 2, 4, 8, 16, or 32).\n        *   **MSI-X** supports up to 2048 vectors, allowing for more granular interrupt sources.\n    *   **Enable Capabilities:** Ensure that the MSI or MSI-X capability structure is explicitly enabled to be included in the device's configuration space. This is how the host OS discovers the device's interrupt capabilities.\n\n2.  **Implement Interrupt Logic in Firmware:**\n    *   **Open `pcileech_pcie_tlp_a7.sv` (or user logic module):** This file is generally responsible for user-defined TLP generation and might be the appropriate place to initiate MSI/MSI-X messages. However, the *trigger* for the interrupt will come from your custom logic.\n    *   **Define Interrupt Signals:** Declare internal signals that will indicate when an interrupt needs to be generated.\n        ```verilog\n        // In a custom module (e.g., 'my_device_logic.sv') that interfaces with TLP generation logic\n        reg msi_trigger_signal; // Assert this when an interrupt condition occurs\n        ```\n    *   **Implement Interrupt Generation Logic:** Define the conditions under which an interrupt should be triggered. This typically involves event detection within your emulated device's logic.\n        ```verilog\n        // Inside 'my_device_logic.sv'\n        input wire clk;\n        input wire reset;\n        input wire event_data_ready; // Example: Input from your logic when data is ready\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_trigger_signal <= 1'b0;\n            end else if (event_data_ready) begin // When a specific event happens\n                msi_trigger_signal <= 1'b1; // Trigger an MSI\n            end else begin\n                msi_trigger_signal <= 1'b0; // Clear after one cycle or when acknowledged\n            end\n        end\n        ```\n    *   **Connect to PCIe Core's MSI Interface:** The `msi_trigger_signal` (or similar output from your custom logic) needs to be connected to the appropriate input of the PCIe IP core (e.g., `s_axis_tdata_tready`, `s_axis_tdata_tvalid`, `s_axis_tdata_tlast` if using an AXI-Stream interface for MSI TLPs, or dedicated MSI request ports provided by the IP core). The PCIe core then forms and sends the actual MSI/MSI-X TLP. Consult the Xilinx PCIe IP core documentation for precise interface details.\n\n3.  **Save Changes:**\n    *   Save any modified firmware files after implementing the interrupt logic.\n    *   **Check for Timing Constraints:** New logic, especially interrupt paths, can be timing-critical. Ensure that the synthesis and implementation tools do not report any timing violations related to your interrupt generation logic.\n\n#### **8.3.3 Implementing Interrupt Handling Logic (Device Side)**\n\nBeyond just enabling the capability, defining *when* and *how* interrupts are generated by your emulated device is crucial for its proper interaction with the host's interrupt handling mechanisms and driver behavior. This involves creating the internal logic that asserts the interrupt request.\n\n**Steps:**\n\n1.  **Define Interrupt Conditions:**\n    *   **Identify Trigger Events:** Based on your donor device's behavior, determine the specific internal events that should cause your emulated device to generate an interrupt.\n        *   **Examples**: Data transfer completion, new data ready in a receive buffer, an internal error condition, completion of a specific command, link status change.\n    *   **Implement Condition Logic:** Use combinational or sequential logic within your custom SystemVerilog modules to precisely detect these events and generate a short-duration pulse or level-based signal that indicates an interrupt request.\n\n2.  **Create Interrupt Generation Module (Modular Design):**\n    *   It's a good practice to encapsulate your interrupt generation logic into a separate, dedicated module for clarity, reusability, and easier debugging. This module would take internal events as inputs and produce an `msi_req` (or similar) output that connects to the PCIe core.\n        ```verilog\n        // File: interrupt_generator.sv\n        module interrupt_generator (\n            input wire clk,\n            input wire reset,\n            input wire event_trigger,        // Input signal from your custom logic (e.g., data_ready, error_flag)\n            output reg msi_req_o            // Output: Assert to request an MSI/MSI-X\n        );\n\n        // Simple pulse generator for MSI (one-shot interrupt)\n        reg event_trigger_d1;\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_req_o <= 1'b0;\n                event_trigger_d1 <= 1'b0;\n            end else begin\n                event_trigger_d1 <= event_trigger;\n                // Generate a single-cycle pulse when event_trigger goes high\n                if (event_trigger && !event_trigger_d1) begin\n                    msi_req_o <= 1'b1; // Assert MSI request\n                end else begin\n                    msi_req_o <= 1'b0; // De-assert after one cycle\n                end\n            end\n        end\n\n        endmodule // interrupt_generator\n        ```\n    *   **Integrate with Main Firmware:** Instantiate this `interrupt_generator` module in your top-level user logic (e.g., within `pcileech_squirrel_top.sv` or a module it instantiates) and connect its `msi_req_o` output to the PCIe IP core's MSI input.\n\n3.  **Ensure Proper Timing and Sequencing:**\n    *   **Adhere to PCIe Specifications:** MSI/MSI-X messages are TLPs. Ensure that the generation of these messages adheres to PCIe TLP formatting, flow control, and timing requirements. The PCIe IP core handles much of this, but your input signals to it must be stable and correctly timed.\n    *   **Manage Interrupt Latency:** Optimize your logic to minimize any unnecessary delay between the internal event occurrence and the assertion of the `msi_req_o` signal.\n\n4.  **Test Interrupt Delivery:**\n    *   **Simulation:** Use a comprehensive test bench to simulate scenarios where interrupts should be generated. Verify that your `msi_req_o` signal behaves as expected and that the PCIe core generates the correct MSI/MSI-X TLPs.\n    *   **Hardware Testing:**\n        *   Program the FPGA with the updated firmware.\n        *   Use host-side software to trigger the events that should cause an interrupt (e.g., initiating a DMA transfer that completes).\n        *   Confirm that the interrupts are received by the host operating system. On Linux, `dmesg` can show interrupt messages. On Windows, you might use specific driver debug tools or Event Viewer.\n        *   **Debugging Tools:** Utilize Vivado's Integrated Logic Analyzer (ILA) cores (as discussed later in Section 12) to monitor `event_trigger`, `msi_req_o`, and the PCIe core's TLP output signals in real time to verify correct interrupt generation.\n\n5.  **Save Changes:**\n    *   Finalize all code modifications and save the relevant firmware files.\n    *   Review and refine your interrupt logic based on testing results to ensure reliability.\n\n---\n\n## **9. Emulating Device-Specific Capabilities**\n\nBeyond the standard PCIe configuration space and generic DMA functionality, many donor devices possess unique capabilities, custom registers, or vendor-specific features that are critical for their full functionality or for interacting with their proprietary drivers. Accurate emulation requires understanding and replicating these nuances. This section delves into implementing such advanced capabilities, enabling a more faithful and fully functional emulation.\n\n### **9.1 Implementing Advanced PCIe Capabilities**\n\nThe PCIe specification includes various *extended capabilities* beyond the basic configuration space. These capabilities provide features like advanced error reporting, power management, virtualization, and more. Implementing these helps your emulated device appear more legitimate and interact correctly with modern host systems.\n\n**Steps:**\n\n1.  **Identify Required Extended Capabilities:**\n    *   When gathering donor device information with tools like Arbor, carefully look for and document any Extended Capabilities present in the donor's configuration space. These are usually found beyond the initial 256 bytes of standard configuration space.\n    *   **Common Examples:**\n        *   **Advanced Error Reporting (AER)**: Provides robust error detection, logging, and reporting mechanisms for PCIe links.\n        *   **Device Serial Number (DSN)**: (Already covered in Section 6.2).\n        *   **Power Management (PM)**: (Already covered in Section 8.3.1).\n        *   **PCI Express (PCIe) Capability Structure**: (Already covered in Section 8.1 for Link Speed/Width, Max Payload/Read Request, but also includes other fields like Device Control/Status, Link Control/Status).\n        *   **Virtual Channel (VC)/Multi-Function Virtual Channel (MFVC)**: For Quality of Service (QoS) and traffic management.\n        *   **Precision Time Measurement (PTM)**: For synchronizing time across devices.\n        *   **Latency Tolerance Reporting (LTR)**: For power management based on latency requirements.\n        *   **Resettable FPC (Function-Level Reset)**: For more granular resets.\n\n2.  **Enable Capabilities in Vivado PCIe IP Core:**\n    *   Access the PCIe IP core customization window (`pcie_7x_0.xci`) in Vivado.\n    *   Navigate through the various tabs (e.g., \"PCIe Capabilities,\" \"Extended Capabilities,\" \"Advanced Options\").\n    *   Look for checkboxes or dropdowns to enable and configure the specific extended capabilities identified from your donor device.\n    *   **Example (AER):** You'll find a section for \"Advanced Error Reporting\" where you can enable it and configure its registers (e.g., severity masks).\n    *   **Note:** The Xilinx PCIe IP core provides a high degree of configurability for many standard and extended capabilities. It's often just a matter of enabling the correct options in the GUI.\n\n3.  **Implement Firmware Logic for Capability Registers (if necessary):**\n    *   While the PCIe IP core handles the *presence* and much of the *protocol* for these capabilities, some capabilities expose registers that your custom firmware might need to read or write, or whose values your firmware needs to react to.\n    *   **Example (AER):** If your emulated device detects an internal error that should be reported via AER, your firmware needs to write to specific AER error status registers (which might be exposed as part of the BARs or handled internally by the PCIe core and then reflected to user logic). Your user logic would then assert an error input to the PCIe core.\n    *   **Example (Power Management):** As discussed in 8.3.1, your firmware needs to react to the D-state changes signaled by the PCIe core.\n    *   **Process:**\n        *   Identify the specific registers within each enabled capability structure that your donor device's driver interacts with.\n        *   Locate the corresponding signals or logic within the PCILeech-FPGA framework that interface with these registers (often within `pcileech_pcie_cfg_a7.sv` or the `bar_controller`).\n        *   Implement read/write logic for these registers, ensuring your emulated device's internal state accurately reflects the values the driver expects.\n\n### **9.2 Emulating Vendor-Specific Features**\n\nThis is where true \"full device emulation\" becomes highly specialized. Many real-world devices have unique registers, undocumented commands, custom data formats, or proprietary control flows that differentiate them. Replicating these requires deeper analysis and custom HDL development.\n\n**Steps:**\n\n1.  **Reverse Engineer Vendor-Specific Behaviors:**\n    *   This is often the most challenging part.\n    *   **Static Analysis (Driver/Firmware):** Disassemble the donor device's official driver (Windows `.sys`, Linux `.ko`) or the device's original firmware (if available). Look for unique I/O or MMIO access patterns, magic values, or sequences of register writes. Tools like Ghidra, IDA Pro, or objdump can be invaluable.\n    *   **Dynamic Analysis (Driver Execution):** Run the donor device with its driver and monitor PCIe traffic using a **PCIe Protocol Analyzer** (e.g., Teledyne LeCroy, Keysight, as discussed in Section 12.2). This is the gold standard for understanding actual TLP exchanges, including vendor-defined messages and sequences of register accesses. Pay attention to:\n        *   Specific memory addresses accessed within BARs.\n        *   Read/write patterns to these addresses.\n        *   The values written to or read from specific registers.\n        *   Timing relationships between commands and responses.\n    *   **System Calls/API Monitoring**: On the host, use tools like Procmon (Windows) or `strace` (Linux) to see how the driver interacts with the OS and what specific device I/O control (IOCTL) codes it uses, which might correspond to specific hardware operations.\n    *   **Hardware Sniffing**: If possible, use a hardware sniffer (like a Saleae Logic Analyzer) to capture signals on the device's internal buses (e.g., SPI, I2C) if it has external flash or components.\n\n2.  **Implement Custom Registers and Logic within BARs:**\n    *   Once you've identified vendor-specific registers or command protocols, you'll need to define these within your FPGA firmware, typically as memory-mapped registers accessible via one of your BARs.\n    *   **Create Internal Registers:** Declare `reg` variables in your SystemVerilog code to represent these custom registers.\n        ```verilog\n        // In your pcileech_tlps128_bar_controller.sv or a sub-module\n        reg [31:0] custom_control_reg;\n        reg [31:0] custom_status_reg;\n        reg [31:0] custom_data_reg;\n\n        // Example: Map these to specific offsets within BAR0 (assuming BAR0 is large enough)\n        // Adjust the 'bar0_offset' case statement (from Section 8.2.2)\n        // ...\n        if (bar_hit[0]) begin\n            if (req_write) begin\n                case (bar0_offset)\n                    32'h0000_1000: custom_control_reg <= req_data; // Custom control register\n                    32'h0000_1004: custom_data_reg <= req_data;    // Custom data write register\n                    // ... other mappings\n                endcase\n            end else if (req_read) begin\n                case (bar0_offset)\n                    32'h0000_1000: rsp_data = custom_control_reg; // Read control register\n                    32'h0000_1008: rsp_data = custom_status_reg;  // Custom status register\n                    // ... other mappings\n                endcase\n            end\n        end\n        // ...\n        ```\n    *   **Implement Behavioral Logic:** Create SystemVerilog logic (state machines, combinational logic) that:\n        *   Responds to writes to your `custom_control_reg`. For example, a specific bit in this register might trigger a DMA transfer, clear a status flag, or initiate an internal operation.\n        *   Updates your `custom_status_reg` based on the internal state of your emulated device (e.g., \"operation complete,\" \"error occurred,\" \"data available\").\n        *   Processes data written to `custom_data_reg` or provides data from it on reads, mimicking the donor device's data paths.\n\n3.  **Emulate Vendor-Specific Messages (if applicable):**\n    *   Some complex devices might use \"Vendor Defined Messages\" (VDMs) over PCIe for specific control or communication. If your analysis reveals such messages, you would need to:\n        *   Enable VDM support in the PCIe IP core (if available).\n        *   Implement TLP generation logic (as will be discussed in Section 10) to craft and send these VDMs.\n        *   Implement TLP reception and parsing logic to interpret incoming VDMs from the host.\n\n4.  **Validate Emulated Behavior:**\n    *   **Iterative Testing:** This is a highly iterative process. Make small changes, compile, flash, and test.\n    *   **Driver Loading:** Does the donor device's driver load correctly without errors?\n    *   **Functional Tests:** Can the driver initiate basic operations? Does it get the expected responses from your emulated registers?\n    *   **Application Tests:** Can applications that rely on the donor device function correctly with your emulated version?\n    *   **Debugging:** Use ILA and PCIe protocol analyzers extensively to compare your emulated device's behavior against the captured behavior of the real donor device. Look for discrepancies in TLP timing, register values, and overall protocol flow.\n\n---\n\n## **10. Transaction Layer Packet (TLP) Emulation**\n\nTransaction Layer Packets (TLPs) are the fundamental units of communication in the PCIe architecture. Every interaction between a host system and a PCIe device, from configuration reads to data transfers, is encapsulated within one or more TLPs. Accurate TLP emulation is not just important; it is *crucial* for your emulated device to interact properly with the host system, ensuring that drivers function correctly and that data moves as expected.\n\n### **10.1 Understanding and Capturing TLPs**\n\nBefore you can craft custom TLPs, you must deeply understand their structure and common types. Capturing real-world TLPs from your donor device provides the most accurate blueprint.\n\n#### **10.1.1 Learning the TLP Structure**\n\nA TLP is generally composed of a header, an optional data payload, and an optional End-to-End CRC (ECRC). The header is paramount, defining the TLP's type, transaction specifics, and routing information.\n\n*   **Components of a TLP**:\n    *   **Header**: The most important part, typically 3 or 4 Double Words (Dwords = 4 bytes). It contains critical fields that define the TLP's purpose and how it should be handled:\n        *   **Fmt (Format) and Type**: Defines the TLP's format (3DW/4DW, with/without data) and its specific purpose (e.g., Memory Read Request, Memory Write, Completion, Configuration Read/Write).\n        *   **Length**: Specifies the size of the data payload in Dwords.\n        *   **Requester ID (Bus, Device, Function)**: Identifies the PCIe function that initiated the request. Essential for routing completions back to the correct source.\n        *   **Tag**: A unique identifier assigned by the Requester to a transaction, allowing a Completer to match a Completion TLP to its original Request TLP.\n        *   **Address**: For Memory/IO transactions, this is the target memory or I/O address.\n        *   **First DW Byte Enable (FBE)** and **Last DW Byte Enable (LBE)**: Specify which bytes within the first and last Dwords of the payload are valid for write operations, or which bytes are being requested for read completions.\n        *   **Traffic Class (TC)** and **Transaction ID (TID)**: For QoS and ordering rules.\n    *   **Data Payload (Optional)**: Present in TLPs like Memory Write, Configuration Write, and Read Completions. It contains the actual data being transferred.\n    *   **End-to-End CRC (ECRC) (Optional)**: A 32-bit CRC that covers the entire TLP, ensuring data integrity from source to destination, typically generated/checked by software.\n\n*   **Understanding Common TLP Types**: Your firmware will primarily deal with these:\n    *   **Memory Read Request (MRd)**: A TLP sent by a Requester (e.g., host CPU, or your FPGA as a DMA master) to read data from a specific memory address.\n    *   **Memory Read Completion (CplD)**: A TLP sent by a Completer (e.g., your FPGA responding to a host MRd) carrying the requested data.\n    *   **Memory Write (MWr)**: A TLP sent by a Requester (e.g., host CPU, or your FPGA) to write data to a specific memory address.\n    *   **Completion Without Data (Cpl)**: A TLP sent by a Completer to acknowledge a request that does not return data (e.g., a successful MWr).\n    *   **Configuration Read Request (CfgRd)**: A TLP from the host to read registers in the device's Configuration Space.\n    *   **Configuration Read Completion (CplD)**: A TLP from the device returning data for a CfgRd.\n    *   **Configuration Write Request (CfgWr)**: A TLP from the host to write to registers in the device's Configuration Space.\n    *   **Vendor-Defined Messages (VDM)**: Custom TLPs used by specific vendors for proprietary communication.\n\n#### **10.1.2 Capturing TLPs from the Donor Device**\n\nCapturing real PCIe traffic from your donor device is invaluable. It provides concrete examples of TLP structures, sequences, and timing, allowing you to replicate them precisely.\n\n*   **Steps**:\n    1.  **Set Up a PCIe Protocol Analyzer**:\n        *   The most effective method involves using dedicated hardware tools, often referred to as \"PCIe Protocol Analyzers.\" These devices sit in-line between the host and the donor PCIe card, passively capturing all traffic.\n        *   **Examples**:\n            *   **Teledyne LeCroy PCIe Analyzers**: Industry standard, highly capable, but significant investment.\n            *   **Keysight PCIe Analyzers**: Another leading vendor.\n            *   (For basic debugging, some higher-end logic analyzers with PCIe decoders might offer limited TLP viewing, but a true protocol analyzer is superior).\n    2.  **Capture Transactions**:\n        *   Install the donor device in a test system with the protocol analyzer connected.\n        *   Run the donor device's driver and any associated applications.\n        *   Monitor and record the PCIe transactions during normal operation, and especially during critical phases like:\n            *   Device enumeration (when the OS first detects it).\n            *   Driver loading and initialization.\n            *   Typical data transfer operations (e.g., large file copies for a storage device, network traffic for a NIC).\n            *   Device-specific commands or diagnostics.\n    3.  **Analyze Captured TLPs**:\n        *   Use the protocol analyzer's sophisticated software to dissect the captured TLPs. The software will decode fields, provide chronological views, and allow filtering and searching.\n        *   Pay close attention to:\n            *   The exact `Fmt` and `Type` fields.\n            *   `Requester ID` and `Tag` values (especially for completions).\n            *   The `Address` and `Length` for memory transactions.\n            *   The contents of `Data Payload` for writes and read completions.\n            *   Any vendor-specific fields or custom TLPs.\n\n#### **10.1.3 Documenting Key TLP Transactions**\n\nStructured documentation of captured TLPs creates a blueprint for your emulation.\n\n*   **Steps**:\n    1.  **Identify Critical Transactions**:\n        *   Focus on TLPs that are essential for the device's core functionality. These include:\n            *   **Initialization Sequence**: The series of configuration reads/writes the OS performs during enumeration.\n            *   **Driver Initialization**: The commands and data exchanged when the driver starts up.\n            *   **Primary Data Transfers**: How `MWr` and `MRd` TLPs are structured and completed for the device's main function.\n            *   **Error Handling**: How the device reports errors (e.g., Completion with Completer Abort (CA), Unsupported Request (UR)).\n            *   **Power Management Transitions**: TLPs related to D-state changes.\n            *   **Interrupt Generation**: How MSI/MSI-X messages are sent.\n    2.  **Create Detailed Documentation**:\n        *   For each key TLP sequence, record:\n            *   The **TLP Type** (e.g., MWr, MRd, CplD).\n            *   Its **header fields** (Fmt, Type, Requester ID, Tag, Length, Address, Byte Enables).\n            *   The **data payload** (if applicable).\n            *   The **sequence number** or order within a transaction.\n            *   The **conditions** under which it is sent (e.g., \"sent by host when driver initializes,\" \"sent by device on DMA completion\").\n            *   Any **expected responses** or follow-up TLPs.\n        *   Screenshots from the protocol analyzer can be very helpful here.\n    3.  **Understand Timing and Sequencing**:\n        *   Beyond just the TLP content, the *timing* and *sequence* of TLPs are vital. PCIe has strict ordering rules and flow control mechanisms. Pay attention to:\n            *   **Delay between Request and Completion**: How quickly the real device responds.\n            *   **Flow Control Credits**: How the device manages its buffer space for incoming/outgoing TLPs. While the Xilinx PCIe IP core handles basic flow control, for advanced emulation, knowing the donor's typical credit usage can be helpful.\n            *   **Transaction Layer Packet Ordering**: Understand how posted (writes) and non-posted (reads, completions) transactions are ordered.\n\n### **10.2 Crafting Custom TLPs for Specific Operations**\n\nOnce you understand the blueprint, you can translate this knowledge into your FPGA firmware (SystemVerilog) to actively generate and respond to TLPs. The PCILeech-FPGA framework provides abstraction layers, but for deep emulation, you might need to interact directly with the TLP generation/parsing logic.\n\n#### **10.2.1 Implementing TLP Handling in Firmware**\n\nYour firmware will need logic to both send and receive TLPs. The PCIe IP core handles the physical and data link layers, exposing a Transaction Layer interface (often AXI-Stream) to your user logic.\n\n*   **Files to Modify (Primary)**:\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_pcie_tlp_a7.sv` (or similar, depending on board variant)\n        *   This file often contains the core logic for translating user requests into outbound TLPs and parsing incoming TLPs into signals for your user logic.\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv`\n        *   This module specifically handles parsing incoming Memory Read/Write TLPs that target your device's BARs and generating corresponding Completion TLPs.\n\n*   **Steps**:\n\n    1.  **Understand the PCIe IP Core Interface**:\n        *   Before writing TLP logic, thoroughly read the Xilinx PCIe IP Core User Guide (specifically the sections on the User Application Interface or AXI4-Stream Interface). This defines how your SystemVerilog logic connects to the PCIe core to send and receive TLPs. You'll typically interact with `s_axis_rx_tdata` (received TLP data), `s_axis_rx_tvalid` (valid TLP received), `m_axis_tx_tdata` (outgoing TLP data), `m_axis_tx_tready` (core ready to accept TLP), etc.\n\n    2.  **Create TLP Generation Functions (for outbound TLPs)**:\n        *   In `pcileech_pcie_tlp_a7.sv` (or a module that interfaces with `m_axis_tx_*`), you will write logic to assemble TLPs with the required headers and payloads. This often involves combining various fields into a `[127:0]` (for 128-bit interface) or `[63:0]` (for 64-bit interface) bus that feeds the PCIe core.\n        *   **Example (Conceptual, Simplified Function for a 3DW TLP Header):**\n            ```verilog\n            // This is a conceptual helper function. In reality, you'd build a state machine\n            // to send TLPs over an AXI-Stream interface, possibly using a FIFO.\n            function automatic [95:0] create_3dw_tlp_header; // Assuming 3 Dwords = 96 bits\n                input logic [7:0] tlp_type_fmt;   // Format and Type fields\n                input logic [15:0] requester_id;  // BDF\n                input logic [7:0] tag;\n                input logic [7:0] lower_address_bits; // Or more complex address\n                input logic [7:0] byte_enables;   // First DW Byte Enable\n\n                begin\n                    create_3dw_tlp_header = {\n                        tlp_type_fmt,                     // Fmt[6:4], Type[3:0]\n                        8'b0,                             // Reserved\n                        4'b0,                             // TC[3:0] (Traffic Class)\n                        3'b0,                             // Attr[2:0]\n                        1'b0,                             // TH (TLP Hint)\n                        2'b0,                             // D(igest) (ECRC presence)\n                        1'b0,                             // EP (Poisoned)\n                        1'b0,                             // TD (Type Dependent)\n                        // DW0: Fmt, Type, TC, Attr, TH, D, EP, TD, Length (not in 3DW, 4DW has it)\n\n                        requester_id,                     // Requester ID (Bus[7:0], Device[4:0], Function[2:0])\n                        tag,                              // Tag\n                        lower_address_bits,               // Example: lower bits of address or a portion of data\n                        byte_enables,                     // First DW Byte Enable\n                        4'b0,                             // Reserved\n                        4'b0                              // Last DW Byte Enable (for MWr usually)\n                        // DW1, DW2... fields\n                    };\n                end\n            endfunction\n\n            // Example: Generating a Completion with Data (CplD) in a state machine\n            // This is just a snippet, not a full implementation\n            localparam  CPLD_3DW_FMT = 8'h4A; // Fmt=100 (4DW, with data), Type=1010 (Cpl)\n            localparam  CPL_D_FMT_TYPE_LEN = 8'h4A; // Adjusted based on PCIe spec. (4DW header with data)\n\n            // ... state machine to send TLP\n            // In a state where you are ready to send CplD\n            if (tx_ready_from_pcie_core) begin\n                // Build the header and payload\n                // For a CplD, you need Complier ID, Status, Byte Count, Requester ID, Tag, Completion ID, Lower Address\n                // And then the actual read data payload\n                m_axis_tx_tdata_reg = {\n                    CPL_D_FMT_TYPE_LEN,         // Byte 0: Fmt/Type\n                    tlp_length_dw_minus_one,    // Byte 1: TLP Length (in Dwords) - 1\n                    status_completion_bits,     // Byte 2: Cpl Status, BCM, Rsvd\n                    byte_count_dws_upper,       // Byte 3: Byte Count (upper bits)\n                    requester_id,               // Byte 4-5: Requester ID (from original MRd)\n                    tag,                        // Byte 6: Tag (from original MRd)\n                    byte_count_dws_lower,       // Byte 7: Byte Count (lower bits)\n                    completion_id,              // Byte 8-9: Completion ID (your BDF)\n                    lower_address_from_request  // Byte 10-11: Lower Address from Request\n                    // ...followed by actual data payload\n                };\n                m_axis_tx_tvalid_reg = 1'b1;\n                m_axis_tx_tlast_reg = 1'b1; // Last TLP segment\n                // ... state transition to wait for tready\n            end\n            ```\n        *   **Note**: The actual implementation involves state machines, FIFOs, and adherence to the AXI-Stream protocol for the PCIe IP core. The PCILeech-FPGA framework already provides a good base for this, but you might extend or modify it for very specific TLP behaviors.\n\n    3.  **Handle TLP Reception (for inbound TLPs)**:\n        *   Implement logic to parse incoming TLPs from the PCIe core's receive interface (e.g., `s_axis_rx_tdata`, `s_axis_rx_tvalid`).\n        *   This parsing involves:\n            *   Checking `s_axis_rx_tvalid` to know a TLP is present.\n            *   Reading the `Fmt` and `Type` fields from the TLP header to determine its purpose.\n            *   Extracting relevant fields like `Requester ID`, `Tag`, `Address`, `Length`, and `Data Payload`.\n        *   Use `case` statements or `if/else if` blocks based on the TLP type to route the information to the appropriate internal logic (e.g., `bar_controller` for Memory Writes, a configuration module for Configuration Writes).\n        *   **Example (Conceptual, Simplified Parsing):**\n            ```verilog\n            // In pcileech_pcie_tlp_a7.sv or a TLP parser module\n            input wire [127:0] s_axis_rx_tdata;\n            input wire s_axis_rx_tvalid;\n            output wire s_axis_rx_tready; // Needs to be asserted to accept more data\n\n            reg [7:0] received_tlp_fmt_type;\n            reg [15:0] received_requester_id;\n            // ... declare other parsed fields\n\n            assign s_axis_rx_tready = 1'b1; // Always ready to receive for simplicity, manage backpressure in real design\n\n            always @(posedge clk) begin\n                if (s_axis_rx_tvalid) begin\n                    received_tlp_fmt_type = s_axis_rx_tdata[127:120]; // Assuming highest bits\n                    received_requester_id = s_axis_rx_tdata[111:96]; // Example offset\n\n                    // Decode based on TLP type\n                    case (received_tlp_fmt_type[3:0]) // Only TLP Type bits\n                        4'h0: // Memory Write (3DW or 4DW depending on Fmt)\n                            // Extract address, length, payload and pass to BAR controller\n                            begin\n                                // Pass to BAR controller for writing to emulated memory\n                                // bar_write_enable = 1'b1;\n                                // bar_write_address = s_axis_rx_tdata[...];\n                                // bar_write_data = s_axis_rx_tdata[...];\n                            end\n                        4'h1: // Memory Read\n                            // Extract address, length, and pass to BAR controller for reading\n                            begin\n                                // bar_read_enable = 1'b1;\n                                // bar_read_address = s_axis_rx_tdata[...];\n                                // (Completion will be generated by BAR controller)\n                            end\n                        // ... other TLP types\n                        default: begin\n                            // Handle unsupported or reserved TLP types (e.g., log, error)\n                        end\n                    endcase\n                end\n            end\n            ```\n\n    4.  **Ensure Compliance**:\n        *   Strictly verify that both your generated and parsed TLPs conform to the PCIe specification regarding format, field definitions, and timing. Deviations will lead to communication failures.\n\n    5.  **Implement Completion Handling**:\n        *   For Memory Read Requests (MRd) and Configuration Read Requests (CfgRd) received from the host, your device is obligated to send back appropriate Completion TLPs (CplD for data, Cpl for no data) within a specific timeframe. The `bar_controller` module (Section 8.2.2) is where this logic for BAR reads resides.\n\n    6.  **Save Changes**:\n        *   Save the files (`pcileech_pcie_tlp_a7.sv`, `pcileech_tlps128_bar_controller.sv`, or any custom modules) after implementing the changes.\n\n#### **10.2.2 Handling Different TLP Types**\n\nEach TLP type has a specific header format and behavior. Your firmware must be adept at handling the ones relevant to your donor device.\n\n*   **Memory Read Requests (MRd)**:\n    *   **Implementation**:\n        *   When an MRd TLP is received (parsed by `pcileech_pcie_tlp_a7.sv` and routed to the `bar_controller`), the `bar_controller` needs to:\n            *   Parse the requested address and length.\n            *   Fetch the data from the appropriate internal memory location (e.g., BRAM connected to a BAR) or internal register.\n            *   Assemble a **Completion with Data (CplD)** TLP. Crucially, this TLP must include the original `Requester ID`, `Tag`, and `Completion ID` (your device's BDF) from the MRd request, along with the fetched data payload.\n            *   Send the CplD TLP back to the host via the PCIe IP core's transmit interface.\n\n*   **Memory Write Requests (MWr)**:\n    *   **Implementation**:\n        *   When an MWr TLP is received, the `bar_controller` needs to:\n            *   Parse the target address, length, and `Byte Enables` (FBE/LBE).\n            *   Extract the `data payload`.\n            *   Write the data to the specified memory location within your emulated device (e.g., a BRAM or internal registers), respecting the byte enables.\n        *   Memory Writes are \"posted transactions,\" meaning they don't require a completion TLP for acknowledgment unless an error occurs.\n\n*   **Configuration Read/Write Requests (CfgRd/CfgWr)**:\n    *   **Implementation**:\n        *   These TLPs target the device's Configuration Space (Vendor ID, Device ID, BARs, Capabilities, etc.). The Xilinx PCIe IP core handles the majority of standard Configuration Space accesses automatically based on its configuration.\n        *   However, if you have custom registers or extended capabilities *within* the Configuration Space that are not standard, you might need specific logic to:\n            *   For CfgRd: Return the requested data from your internal `cfg_` registers.\n            *   For CfgWr: Update your internal `cfg_` registers or trigger actions based on the written data.\n        *   Configuration Reads require a **Completion with Data (CplD)**, while Configuration Writes require a **Completion without Data (Cpl)**.\n\n*   **Vendor-Defined Messages (VDM)**:\n    *   **Implementation**:\n        *   If your donor device uses VDMs, this requires specialized parsing and response logic.\n        *   **Parsing Incoming VDMs**: Identify VDMs based on their `Fmt` and `Type` fields. Extract the vendor-specific data and interpret it according to your reverse-engineering findings.\n        *   **Crafting Outbound VDMs**: Create logic to assemble VDMs with the precise vendor-specific header and payload formats when your emulated device needs to send them.\n\n#### **10.2.3 Validating TLP Timing and Sequence**\n\nEven if TLPs are perfectly formatted, incorrect timing or sequencing will lead to device malfunction or detection as non-compliant.\n\n*   **Steps**:\n\n    1.  **Use Simulation Tools**:\n        *   **Test Benches**: Develop comprehensive SystemVerilog test benches for your TLP generation and parsing modules.\n        *   Simulate various scenarios (e.g., host sending MRd, your device sending CplD; host sending MWr; host enumerating device) to validate that TLPs are correctly formed, transmitted, received, and processed.\n        *   Verify the sequence of TLPs and that completions are sent within reasonable timeframes.\n\n    2.  **Monitor with ILA (Integrated Logic Analyzer)**:\n        *   As detailed in Section 12.1, insert an ILA core into your Vivado design.\n        *   Connect the ILA probes to the AXI-Stream interfaces of the PCIe IP core (e.g., `s_axis_rx_tdata`, `s_axis_rx_tvalid`, `m_axis_tx_tdata`, `m_axis_tx_tready`).\n        *   Set triggers to capture specific TLPs (e.g., on `m_axis_tx_tvalid` for a certain TLP type).\n        *   This allows you to see the actual TLP bits on the FPGA in real time during hardware operation, verifying if your firmware is sending/receiving the correct data and control signals to/from the PCIe IP core.\n\n    3.  **Check Timing Constraints**:\n        *   The PCIe IP core has strict timing requirements for its AXI-Stream interfaces. Ensure that your user logic providing data to `m_axis_tx_tdata` and handling `s_axis_rx_tdata` meets these timing constraints.\n        *   Vivado's timing analysis reports (after synthesis and implementation) will flag any violations. Address these by optimizing your logic or adjusting clocking where possible.\n\n    4.  **Compliance Testing (Advanced)**:\n        *   For high-fidelity emulation, consider using a dedicated PCIe compliance test suite (often integrated with high-end protocol analyzers). These tests systematically check adherence to the PCIe specification, uncovering subtle protocol violations.\n\n    5.  **Save Changes**:\n        *   Save all modified files after thorough testing and validation. Iteration is key in TLP-level debugging.\n\n---\n\n## **Part 3: Advanced Techniques and Optimization**\n\n---\n\n## **11. Building, Flashing, and Testing**\n\nAfter all your customizations are complete, the moment of truth arrives: building the firmware, programming it onto your FPGA, and rigorously testing its functionality to ensure it behaves exactly like the donor device. This phase transitions your design from code to a working hardware emulation.\n\n### **11.1 Synthesis and Implementation**\n\nThese are the core steps in the FPGA design flow, where your high-level SystemVerilog code is transformed into a low-level hardware configuration that can be loaded onto the FPGA.\n\n#### **11.1.1 Running Synthesis**\n\nSynthesis is the process by which Vivado translates your HDL code into a gate-level netlist (a description of logical gates and their interconnections). It also performs preliminary timing analysis and resource estimation.\n\n*   **Steps**:\n    1.  **Start Synthesis**:\n        *   In the Vivado GUI, in the **Flow Navigator** pane (typically on the left), under \"Synthesis,\" click **Run Synthesis**.\n    2.  **Monitor Progress**:\n        *   Vivado will open a \"Launch Runs\" dialog. You can typically just click \"OK.\"\n        *   Monitor the **Messages** tab at the bottom of the Vivado window. It will show the progress of the synthesis run.\n        *   **Common Warnings/Errors to Watch For**:\n            *   **`[Synth 8-327]` Unconnected Ports / Unused Inputs**: These indicate that a signal or port in your design is not connected to anything. While sometimes intentional (e.g., unused pins on the FPGA), they can also point to typos in port names or forgotten connections. Investigate each to ensure it's not a functional issue.\n            *   **`[Synth 8-256]` Registers/Wires Not Optimized**: This might indicate that logic is being inferred incorrectly or that you have redundant logic that could be optimized.\n            *   **Syntax Errors**: If there are fatal syntax errors in your SystemVerilog code, synthesis will fail immediately. Fix these in Visual Studio Code.\n    3.  **Review Synthesis Report**:\n        *   Upon successful completion, Vivado will ask you what to do next. Select **Open Synthesized Design** or **Open Report**.\n        *   Crucially, review the **Utilization Summary** in the synthesis report. This shows how much of the FPGA's resources (LUTs, Flip-Flops, BRAMs, DSPs) your design consumes. Ensure that the design fits within your target FPGA's capacity (e.g., for a Artix-7 35T, you should be well within its limits).\n\n#### **11.1.2 Running Implementation**\n\nImplementation is the most time-consuming step. It takes the synthesized netlist and physically maps it onto the FPGA's resources (placing logic blocks, routing connections) and then performs a detailed timing analysis to ensure the design can operate at the specified clock frequencies.\n\n*   **Steps**:\n    1.  **Start Implementation**:\n        *   After successful synthesis, in the **Flow Navigator**, under \"Implementation,\" click **Run Implementation**.\n        *   Confirm the \"Launch Runs\" dialog.\n    2.  **Monitor Progress**:\n        *   Implementation consists of several phases: Opt Design, Power Opt Design, Place Design, Post-Placement Phys Opt Design, Route Design, Post-Route Phys Opt Design. Each phase can take a significant amount of time.\n        *   Monitor the **Messages** tab for progress and potential issues.\n    3.  **Analyze Timing Reports**:\n        *   This is *the most critical step* after implementation. Upon completion, Vivado will again ask what to do next. Select **Open Implemented Design** or, more importantly, **Open Report** and then select **Report Timing Summary**.\n        *   **Ensure that all timing constraints are met.** Look for \"WNS (Worst Negative Slack)\" values.\n            *   **Positive WNS**: Indicates that all timing paths meet their requirements (slack means you have extra time). This is what you want.\n            *   **Negative WNS**: Indicates **timing violations**, meaning your design cannot operate at the desired clock frequency or data might not be stable. **This is a critical issue that *must* be addressed.**\n        *   **Address Violations**:\n            *   If you have negative slack, investigate the specific paths that are failing. Vivado's timing report will show you the source, destination, and components of the failing paths.\n            *   Solutions can include:\n                *   Optimizing your HDL code to reduce logic depth or critical path delays.\n                *   Adding pipeline stages (registers) to break up long combinational paths.\n                *   Refining your XDC (constraints) file, ensuring all clocks are correctly defined and propagated.\n                *   Adjusting clock frequencies (if the application allows).\n                *   Using faster timing-closure strategies in Vivado.\n                *   Ensuring your custom logic interfaces correctly with the PCIe core's AXI-Stream interface timing requirements.\n    4.  **Verify Placement (Optional)**:\n        *   In the implemented design, you can open the \"Device\" view to see how your logic has been placed on the FPGA. This is generally for advanced users to confirm that critical components are placed optimally (e.g., close to PCIe transceivers).\n\n#### **11.1.3 Generating Bitstream**\n\nThe bitstream is the final, binary configuration file (`.bit` extension) that will be loaded onto your FPGA. It's the culmination of synthesis and implementation.\n\n*   **Steps**:\n    1.  **Generate Bitstream**:\n        *   After successful implementation (with no critical timing violations), in the **Flow Navigator**, under \"Program and Debug,\" click **Generate Bitstream**.\n    2.  **Wait for Completion**:\n        *   This process generally takes less time than implementation but can still vary based on design complexity.\n    3.  **Review Bitstream Generation Log**:\n        *   Upon completion, Vivado will indicate success. Review the log for any warnings, though typically if implementation passed cleanly, bitstream generation will too.\n        *   The `.bit` file will be generated in your project's `pcileech_squirrel_top.runs/impl_1/` directory (or similar path for your board).\n\n### **11.2 Flashing the Bitstream**\n\nProgramming (flashing) the bitstream loads your compiled design onto the FPGA, making your emulated device active.\n\n#### **11.2.1 Connecting the FPGA Device**\n\n*   **Steps**:\n    1.  **Prepare Hardware**:\n        *   Ensure your FPGA-based DMA board is correctly inserted into a compatible PCIe slot on your host system.\n        *   Connect the JTAG programmer (e.g., Digilent HS3, Xilinx Platform Cable) to the JTAG header on your FPGA board and to a USB port on your development PC.\n        *   Power on the host system.\n        *   Refer to your specific FPGA board's manual for precise power, JTAG, and PCIe connection instructions.\n    2.  **Open Hardware Manager**:\n        *   In Vivado, navigate to **Flow Navigator > Program and Debug > Open Hardware Manager**.\n        *   If Vivado is not running, you can launch Hardware Manager as a standalone application.\n\n#### **11.2.2 Programming the FPGA**\n\n*   **Steps**:\n    1.  **Connect to the Target**:\n        *   In the Hardware Manager window, click **Open Target** (often a large button or link) and select **Auto Connect**.\n        *   Vivado should automatically detect your JTAG programmer and then the connected FPGA device(s) on the JTAG chain. If detection fails, check JTAG cable connections, power to the board, and JTAG drivers on your PC.\n    2.  **Program Device**:\n        *   Once your FPGA device is detected and displayed in the Hardware window, **right-click** on your FPGA device (e.g., `xc7a35t_0`) and select **Program Device**.\n        *   A dialog will appear. Click the \"...\" button next to the \"Bitstream file\" field and navigate to your generated bitstream file (e.g., `pcileech_squirrel_top.runs/impl_1/pcileech_squirrel_top.bit`).\n        *   Click **Program** to begin flashing the firmware onto the FPGA.\n        *   Wait for the programming process to complete. You'll see a progress bar.\n\n#### **11.2.3 Verifying Programming**\n\n*   **Steps**:\n    1.  **Check Status**:\n        *   Ensure the programming completes without errors in Vivado's Hardware Manager. Vivado will display a \"Program Device\" success message upon completion.\n    2.  **Observe LEDs or Indicators**:\n        *   Many FPGA boards have status LEDs. A successful programming operation often causes a specific LED to illuminate or change state (e.g., a \"DONE\" LED). This is a quick visual confirmation.\n    3.  **Host System Reboot (Sometimes Required)**:\n        *   For the host operating system to correctly recognize the newly programmed PCIe device, a system reboot is often necessary, especially on Windows, to trigger the full PCIe enumeration process.\n\n### **11.3 Testing and Validation**\n\nAfter programming, the crucial step is to verify that your emulated device is detected correctly by the host and that it functions as expected, mimicking the donor device.\n\n#### **11.3.1 Verifying Device Enumeration**\n\nThis confirms that the host OS sees your FPGA as the donor device based on the IDs you programmed.\n\n*   **Windows**:\n    *   **Steps**:\n        1.  **Open Device Manager**: Press `Win + X` and select **Device Manager** from the Quick Link menu.\n        2.  **Check Device Properties**:\n            *   Look under the appropriate device category (e.g., **Network Adapters**, **Storage Controllers**, **System devices**).\n            *   Find your emulated device. It should now appear with the *name of the donor device* (e.g., \"Intel(R) Ethernet Connection...\")\n            *   Right-click on the device, select **Properties**, and go to the **Details** tab.\n            *   In the \"Property\" dropdown, select \"Hardware Ids.\" Confirm that the **Device ID (DID)** and **Vendor ID (VID)** (e.g., `PCI\\VEN_ABCD&DEV_1234`) match those you programmed into your firmware.\n            *   Also check \"Class Code\" and \"Subsystem ID\" for further verification.\n*   **Linux**:\n    *   **Steps**:\n        1.  **Use `lspci`**: Open a terminal and use the `lspci` command.\n            ```bash\n            lspci -nn # Shows VendorID:DeviceID\n            lspci -vvv # Shows verbose details including BARs, capabilities, and more\n            ```\n        2.  **Verify Device Listing**:\n            *   Check that the emulated device appears in the `lspci` output with the correct Vendor ID, Device ID, and Class Code.\n            *   **Example Output (emulating an Intel NIC):**\n                ```\n                03:00.0 Network controller [0280]: Intel Corporation Ethernet Connection I219-V [8086:1570] (rev 21)\n                ```\n                (`8086` is Intel's Vendor ID, `1570` is the Device ID for I219-V, `0280` is the Network Controller Class Code).\n            *   Use `lspci -vvv` to confirm that the BARs are enumerated with the correct sizes and types, matching your donor device's configuration.\n\n#### **11.3.2 Testing Device Functionality**\n\nOnce the device is enumerated, the ultimate test is whether it functions like the original.\n\n*   **Steps**:\n    1.  **Install Necessary Drivers**:\n        *   If the host OS doesn't automatically load a suitable driver, you will need to manually install the official drivers for your donor device. Download them from the manufacturer's website.\n        *   Install them as per the manufacturer's instructions. If the emulation is successful, the driver should install and recognize your FPGA as the real hardware.\n    2.  **Perform Functional Tests**:\n        *   Run applications or utilities that would typically interact with the donor device.\n        *   **Examples**:\n            *   **Network Card**: Perform ping tests, browse the web, or initiate large file transfers to test throughput.\n            *   **Storage Controller**: Attempt to format a simulated drive (if your emulation includes storage features), perform read/write operations, or run disk benchmarks.\n            *   **USB Controller**: Connect USB devices (if your emulation includes USB host functionality) and test their detection and operation.\n        *   Monitor the host system for expected behavior and performance characteristics.\n    3.  **Monitor System Behavior**:\n        *   Check for system stability (no BSODs on Windows, kernel panics on Linux).\n        *   Look for device-specific errors in system logs (Event Viewer on Windows, `dmesg` or `journalctl` on Linux).\n        *   Ensure that the emulated device behaves as expected under various workloads, including heavy data transfers or stress tests.\n\n#### **11.3.3 Monitoring for Errors**\n\nProactive error monitoring is crucial for identifying subtle emulation issues that might not cause immediate crashes.\n\n*   **Windows**:\n    *   **Steps**:\n        1.  **Check Event Viewer**: Press `Win + X` and select **Event Viewer**.\n        2.  **Look for PCIe-Related Errors**: Navigate to **Windows Logs > System**. Filter or search for warnings, errors, or critical events related to \"PCIe,\" \"PCI Express,\" or events originating from the specific device driver (look for source names matching your emulated device's driver).\n            *   Common errors include resource conflicts, driver initialization failures, or unexpected device responses.\n*   **Linux**:\n    *   **Steps**:\n        1.  **Check `dmesg` Logs**: Open a terminal and type:\n            ```bash\n            dmesg | grep -i pci # Case-insensitive grep for pci messages\n            dmesg | grep -i <VendorID> # Filter for your device's Vendor ID\n            ```\n        2.  **Identify Issues**: Look for messages indicating problems with PCIe link training, device initialization, memory allocation failures, driver probing errors, or unexpected DMA activity. The Linux kernel's PCIe subsystem is quite verbose.\n    *   **Systemd Journal (Modern Linux)**:\n        ```bash\n        journalctl -b | grep -i pci # Current boot log\n        ```\n\n---\n\n## **12. Advanced Debugging Techniques**\n\nWhen issues arise, especially in complex PCIe device emulation, basic troubleshooting might not suffice. Advanced debugging tools and techniques provide deep visibility into the FPGA's internal logic and the PCIe bus, allowing you to identify and resolve problems efficiently.\n\n### **12.1 Using Vivado's Integrated Logic Analyzer (ILA)**\n\nThe Integrated Logic Analyzer (ILA) is a powerful, configurable debug IP core provided by Xilinx that you can embed directly into your FPGA design. It allows you to monitor the real-time behavior of internal FPGA signals (wires and registers) without needing external probing hardware, functioning like a powerful, internal oscilloscope or logic analyzer.\n\n#### **12.1.1 Inserting ILA Cores**\n\n*   **Steps**:\n    1.  **Plan Your Probes**: Identify the key signals you need to observe. For PCIe emulation, these often include:\n        *   The AXI-Stream interfaces of the PCIe IP core (e.g., `s_axis_rx_tdata`, `s_axis_rx_tvalid`, `m_axis_tx_tdata`, `m_axis_tx_tready`).\n        *   Internal state machine signals (`current_state`, `next_state`).\n        *   BAR address decoding outputs (`bar_hit[0]`, `bar_hit[1]`).\n        *   Custom register values (`custom_control_reg`, `custom_status_reg`).\n        *   Interrupt request signals (`msi_trigger_signal`).\n    2.  **Add ILA IP Core**:\n        *   In Vivado, open the **IP Catalog** (usually in the **Flow Navigator** pane).\n        *   Search for \"ILA\" (Integrated Logic Analyzer).\n        *   Double-click on the \"Debug Bridge\" (for basic ILA) or \"Integrated Logic Analyzer (ILA)\" to open its customization GUI.\n        *   Configure the ILA:\n            *   Set the **Number of Capture Data Ports** (probes) you need.\n            *   Set the **Width** of each probe to match the signals you plan to connect.\n            *   Configure the **Sample Depth** (how many samples to store before/after a trigger). Larger depths consume more BRAM.\n            *   Click \"OK\" and let Vivado generate the IP.\n    3.  **Instantiate and Connect Signals**:\n        *   Vivado will generate an `.xci` file for the ILA. You can instantiate it directly in your top-level SystemVerilog file (e.g., `pcileech_squirrel_top.sv`) or within a module where the signals of interest are available.\n        *   **Example (in `pcileech_squirrel_top.sv` or a sub-module):**\n            ```verilog\n            // Assuming you've generated ila_0 from IP Catalog\n            // Connect to your design's clock and signals of interest\n            ila_0 your_ila_instance (\n                .clk(clk_125mhz), // Connect to a stable clock in your design, typically the PCIe user clock\n                .probe0(pcie_s_axis_rx_tdata),    // Example: PCIe inbound TLP data\n                .probe1(pcie_s_axis_rx_tvalid),   // Example: PCIe inbound TLP valid\n                .probe2(pcie_m_axis_tx_tdata),    // Example: PCIe outbound TLP data\n                .probe3(my_bar_controller_state), // Example: State of your BAR logic\n                .probe4(my_custom_register),      // Example: Value of a custom register\n                // Add more probes as needed\n                .probeN(signal_to_monitor_N)\n            );\n            ```\n        *   **Alternative (Marking for Debugging):** For simpler signals, you can sometimes mark them directly in your HDL code for debugging. Use `(* mark_debug = \"true\" *) wire my_signal;` or `(* mark_debug = \"true\" *) reg my_register;`. Vivado will then automatically suggest adding these to an ILA.\n\n#### **12.1.2 Configuring Trigger Conditions**\n\nILA is most powerful when you configure intelligent trigger conditions to capture data precisely when an event of interest occurs (e.g., an error, a specific TLP type, a state transition).\n\n*   **Steps**:\n    1.  **Generate Bitstream with ILA**: After inserting and connecting the ILA, you must run synthesis, implementation, and generate a new bitstream. The ILA core consumes FPGA resources and will be embedded in your design.\n    2.  **Open Hardware Manager**: Program your FPGA with the ILA-enabled bitstream (Section 11.2). Then, in Vivado, open the Hardware Manager and connect to your target.\n    3.  **Access the ILA Dashboard**: In the Hardware Manager, select your ILA instance (e.g., `hw_ila_1`). This will open the ILA dashboard.\n    4.  **Define Triggers**:\n        *   Select the probes you want to use as trigger inputs.\n        *   Set specific **trigger patterns** (e.g., `0x4A` for `pcie_s_axis_rx_tdata` to trigger on a Completion TLP).\n        *   Configure **trigger conditions** (e.g., \"equal to,\" \"not equal to,\" \"rising edge,\" \"falling edge\").\n        *   Set **trigger positions** (how many samples to capture *before* the trigger event, for pre-trigger visibility).\n        *   You can set up multiple trigger sequences for complex event detection.\n        *   **Example Scenarios for Triggers**:\n            *   Trigger on a specific `Fmt/Type` in a received TLP to analyze incoming commands.\n            *   Trigger when a specific register (`my_custom_register`) reaches a certain value.\n            *   Trigger on a `pcie_m_axis_tx_tvalid` AND `pcie_m_axis_tx_tdata[3:0]` == `4'hC` (for a Memory Write TLP) to analyze outbound writes.\n            *   Trigger on the assertion of an error signal.\n\n#### **12.1.3 Capturing and Analyzing Data**\n\n*   **Steps**:\n    1.  **Run the Design**: Allow your host system to interact with the programmed FPGA, causing the events you want to debug.\n    2.  **Arm the ILA**: In the ILA dashboard, click the **Run Trigger** button (often a green \"Play\" icon). The ILA will wait for the defined trigger condition.\n    3.  **Capture Data**: Once the trigger condition is met, the ILA will capture a snapshot of the signals into its internal memory buffer.\n    4.  **Analyze Waveforms**:\n        *   The captured data will appear in the waveform viewer.\n        *   Inspect the signal behavior over time. Zoom in, add cursors, and decode values.\n        *   Look for:\n            *   **Unexpected transitions**: Signals changing at the wrong time.\n            *   **Incorrect values**: Registers holding incorrect data.\n            *   **Protocol violations**: Your logic sending incorrect data on PCIe interfaces.\n            *   **Timing issues**: If signals are not stable when expected (though full timing analysis is done in implementation, ILA shows runtime behavior).\n        *   Compare the captured behavior against your expected design logic and the observed behavior of the donor device (if you captured it with a protocol analyzer).\n\n### **12.2 PCIe Traffic Analysis Tools**\n\nWhile ILA gives you internal FPGA visibility, external PCIe traffic analysis tools provide an unrivaled view of the actual communication on the PCIe bus *between* your emulated device and the host. This is crucial for verifying protocol compliance and debugging link-level issues.\n\n#### **12.2.1 PCIe Protocol Analyzers (Hardware)**\n\n*   **Examples**:\n    *   **Teledyne LeCroy PCIe Analyzers**: Gold standard for deep analysis, full protocol decoding, advanced triggering, and error injection capabilities.\n    *   **Keysight PCIe Analyzers**: Another leading vendor with similar high-end features.\n*   **Steps**:\n    1.  **Set Up Analyzer**: Connect the hardware analyzer in-line between the host system's PCIe slot and your FPGA-based DMA device. This typically involves a special interposer card.\n    2.  **Configure Capture Settings**: Use the analyzer's software to define what traffic to capture. You can filter by TLP type, address, Requester ID, error conditions, etc., to focus on relevant events.\n    3.  **Capture Traffic**: Run your emulated device on the host. The analyzer will passively record all PCIe transactions.\n    4.  **Analyze Results**:\n        *   Use the analyzer's powerful software to view decoded TLPs, transaction lists, and waveform views.\n        *   **Examine TLPs for compliance and correctness**: Are all fields correct? Is the sequence proper?\n        *   **Identify any protocol violations or unexpected behaviors**: This is where you find why the driver might be failing (e.g., your device sends a Completion with data when the spec requires a Completion without data, or it responds too slowly).\n        *   **Compare with Donor Device Captures**: Directly compare the captured traffic from your emulated device to the captures you made from the real donor device. This is the ultimate test of emulation accuracy.\n\n#### **12.2.2 Software-Based Tools**\n\nFor basic PCIe bus inspection, or if a dedicated hardware analyzer is unavailable, some software tools can provide limited insights.\n\n*   **Examples**:\n    *   **Wireshark with PCIe Plugins**: While Wireshark is primarily for network traffic, with specialized hardware (e.g., network cards that expose PCIe traces to the OS, or specific capture hardware/drivers), it can sometimes capture and decode PCIe packets. This is highly dependent on the system.\n    *   **ChipScope Pro (Legacy Xilinx, now part of Vivado)**: Integrated Logic Analyzer (ILA) is the modern equivalent, but ChipScope was the standalone tool.\n    *   **`lspci` (Linux)**: As mentioned in Section 11.3.1, `lspci -vvv` provides extensive static configuration space information. You can combine it with `watch` or scripting to monitor changes over time.\n    *   **`pcileech` client (from the PCILeech framework)**: The `pcileech` client software itself can perform read/write operations to memory and configuration space via your FPGA, and can be used to test basic DMA functionality. While not a \"traffic analyzer,\" it's essential for testing the functional interface.\n*   **Steps**:\n    1.  **Install Necessary Tools/Plugins**: Ensure the tool is installed and any required drivers or plugins are configured.\n    2.  **Monitor PCIe Bus**: Run the software tool to capture and display PCIe-related information.\n    3.  **Analyze Communications**:\n        *   Look for discrepancies in device configuration.\n        *   If the tool supports it, analyze the structure of captured packets for anomalies or errors.\n        *   Verify that your emulated device is responding to configuration requests correctly.\n\n---\n\n## **13. Troubleshooting**\n\nThis section provides solutions to common problems you may encounter during custom firmware development, bitstream programming, and hardware testing of your PCIe device emulation. Firmware debugging can be challenging, so a methodical approach is key.\n\n### **13.1 Device Detection Issues**\n\n**Problem**: Your FPGA-based DMA device, after programming, is not recognized by the host system, or it shows up with incorrect IDs (e.g., \"Unknown device\") or an error symbol in Device Manager/lspci.\n\n#### **Possible Causes and Solutions**:\n\n1.  **Incorrect Device IDs, Vendor IDs, Subsystem IDs, or Class Code**:\n    *   **Cause**: The most common reason. There is a mismatch between the identification values programmed into your FPGA firmware and what the host operating system expects, or what you intend to emulate.\n    *   **Solution**:\n        *   **Verify**: Double-check all `cfg_deviceid`, `cfg_vendorid`, `cfg_subsysid`, `cfg_subsysvendorid`, `cfg_revisionid`, and `cfg_classcode` parameters in `pcileech_pcie_cfg_a7.sv` (or equivalent file) against your meticulously recorded donor device information (from Section 5).\n        *   **Consistency**: Ensure these values are also consistently set in the Vivado PCIe IP Core customization GUI (Section 7.2.2).\n        *   **Rebuild & Re-flash**: After any changes, always re-synthesize, re-implement, generate a new bitstream, and re-flash the FPGA (Section 11.1, 11.2).\n        *   **Reboot Host**: Always reboot the host system after flashing, as Windows often needs a full restart to re-enumerate PCIe devices correctly.\n\n2.  **PCIe Link Training Failure**:\n    *   **Cause**: The fundamental PCIe link between the host's root complex and your FPGA card fails to establish. This happens before any configuration space reads. Symptoms include the device not appearing at all (`lspci` shows nothing at that bus/slot, or Device Manager shows a \"PCI Express Root Port\" error).\n    *   **Solution**:\n        *   **Physical Connections**: Ensure the FPGA board is seated firmly in the PCIe slot and all power connections are secure. Try a different PCIe slot if available.\n        *   **Power**: Verify that the FPGA board is receiving adequate power. Some boards require auxiliary PCIe power connectors.\n        *   **Link Speed/Width**:\n            *   Check `Max Link Speed` and `Link Width` settings in your Vivado PCIe IP Core (Section 8.1.1).\n            *   Try setting the link speed to a lower generation (e.g., Gen1 / 2.5 GT/s) and width to x1, even if your board supports higher. Sometimes, compatibility issues arise with specific motherboards at higher speeds.\n            *   Check motherboard BIOS settings for PCIe slot speed options.\n        *   **Reset**: Ensure the FPGA's reset logic is correctly implemented (e.g., synchronized to the PCIe reference clock) and asserted/de-asserted correctly upon power-up/reboot.\n        *   **PCIe IP Core**: Ensure the PCIe IP core is correctly instantiated and its clocks and resets are properly connected in your top-level design.\n\n3.  **Power Issues (Insufficient or Unstable Power)**:\n    *   **Cause**: The FPGA board is not receiving enough stable power, or the power supply is noisy, leading to unreliable operation.\n    *   **Solution**:\n        *   **Verify Connections**: Double-check all power cables (main PCIe slot power, auxiliary PCIe power, external DC jack if used).\n        *   **Power Supply**: Ensure your host system's power supply (PSU) has sufficient wattage and stable 12V rails. For high-power FPGAs, a weak PSU can cause issues.\n        *   **External Power**: If the board has an external power jack, ensure it's used with the correct voltage and current rating.\n\n4.  **Firmware Errors (Early Stage)**:\n    *   **Cause**: Logic errors in your SystemVerilog code, particularly in the top-level module or the PCIe core's wrapper, that prevent the PCIe core from initializing or presenting itself correctly.\n    *   **Solution**:\n        *   **Vivado Messages**: Scrutinize Vivado's synthesis and implementation logs for **Critical Warnings** or **Errors** related to the PCIe IP core. These are often indicators of misconfigurations or improper connections.\n        *   **ILA Debugging**: If the link attempts to train but fails, use an ILA (Section 12.1) connected to the PCIe IP core's status signals (e.g., `link_up`, `link_speed`, `link_width`) and AXI-Stream interfaces to see at what point the link negotiation fails or if the core is generating unexpected traffic.\n\n### **13.2 Memory Mapping and BAR Configuration Errors**\n\n**Problem**: The emulated device is detected, but when the host OS or a driver tries to access its memory-mapped registers or buffers (via BARs), it crashes, freezes, or reports errors.\n\n#### **Possible Causes and Solutions**:\n\n1.  **Incorrect BAR Sizes or Types (IP Core & Firmware)**:\n    *   **Cause**: The BAR sizes or types (32-bit/64-bit, Memory/I/O, Prefetchable/Non-prefetchable) configured in your Vivado PCIe IP Core (Section 7.2.2) and/or handled in your `pcileech_tlps128_bar_controller.sv` do not match what the donor device actually provides. This can cause the host to allocate an incorrect address space or attempt unsupported accesses.\n    *   **Solution**:\n        *   **Cross-Verify**: Go back to your Arbor/protocol analyzer data (Section 5) and re-verify every single BAR configuration (size, type, prefetchable).\n        *   **Consistency**: Ensure these match perfectly in the PCIe IP Core customization and that your `bar_controller` logic correctly handles the size (address decoding range) and type of each BAR.\n        *   **BRAM Sizing**: If your BARs map to BRAMs, confirm that the BRAM IP core sizes (Section 8.2.1) exactly match the BAR sizes.\n\n2.  **Address Decoding Errors in Firmware**:\n    *   **Cause**: Your `pcileech_tlps128_bar_controller.sv` (or custom BAR logic) is misinterpreting the incoming PCIe addresses, leading to accesses to incorrect internal registers or memory locations.\n    *   **Solution**:\n        *   **Review Logic**: Meticulously review the `case` statements and address calculations in your `bar_controller`.\n        *   **Simulation**: Develop specific test cases in your SystemVerilog test bench to simulate host read/write accesses to various offsets within each BAR. Verify that the internal `bar_hit` signals are correct and that the data is routed to/from the correct internal registers/BRAMs.\n        *   **ILA Debugging**: Place ILA probes on the `req_addr`, `req_write`, `req_read`, `req_data`, `rsp_data`, and the internal signals related to your address decoding and register access within the `bar_controller`. Observe how the address is decoded and what data is being read/written in real time.\n\n3.  **Overlapping Address Spaces (Internal)**:\n    *   **Cause**: While the PCIe standard ensures that BARs from different devices don't overlap in the host's memory map, *internally* within your FPGA, you might accidentally map different logical components to the same physical address space within a single BAR.\n    *   **Solution**:\n        *   **Map Carefully**: When defining internal registers and memory blocks within a BAR, explicitly assign unique, non-overlapping offsets to each. Use `localparam` for these offsets to prevent errors.\n        *   **Design Review**: A thorough design review of your `bar_controller` is necessary to ensure every address range is uniquely handled.\n\n4.  **BRAM Access Issues**:\n    *   **Cause**: Problems with interfacing your logic to the BRAM IP cores (e.g., incorrect BRAM clocking, asynchronous resets, wrong byte enables, or incorrect write enable logic).\n    *   **Solution**:\n        *   **BRAM Documentation**: Consult the Xilinx BRAM IP core documentation for correct instantiation and interface signals.\n        *   **ILA**: Place ILA probes on the BRAM interface signals (address, write enable, data in, data out) to verify that your logic is sending the correct control signals to the BRAM.\n\n### **13.3 DMA Performance and TLP Errors**\n\n**Problem**: The device is detected and functionally appears to work, but data transfer rates are slow, or the system experiences intermittent crashes, hangs, or errors during large DMA operations. PCIe protocol analyzers report malformed TLPs or flow control issues.\n\n#### **Possible Causes and Solutions**:\n\n1.  **Malformed TLPs (Header/Payload)**:\n    *   **Cause**: Your firmware is generating TLPs (especially Completions or outbound Memory Writes if your FPGA is acting as a DMA master) with incorrect headers, lengths, byte enables, or payloads. The host system's PCIe core or driver detects these as violations.\n    *   **Solution**:\n        *   **PCIe Protocol Analyzer**: This is the best tool here (Section 12.2.1). Capture traffic and meticulously compare your generated TLPs against the PCIe specification and, more importantly, against captures from your *real donor device*.\n        *   **TLP Generation Logic**: Review your TLP assembly code (`pcileech_pcie_tlp_a7.sv` and related modules). Ensure all fields (Fmt, Type, Requester ID, Tag, Completion ID, Length, Byte Enables, Address) are correctly derived and packed into the TLP structure.\n        *   **Error Checking**: Implement basic error checking in your firmware (e.g., checking for unexpected `req_valid` without `req_ready` or vice-versa).\n\n2.  **Flow Control Issues**:\n    *   **Cause**: PCIe uses a credit-based flow control mechanism. If your firmware (or the PCIe IP core's interaction with it) incorrectly manages credits, it can lead to deadlocks, timeouts, or dropped packets. Symptoms include a \"stalled\" PCIe link, timeouts, or low throughput.\n    *   **Solution**:\n        *   **PCIe IP Core Configuration**: Ensure the flow control settings within the Vivado PCIe IP Core customization are appropriate for your expected traffic patterns. The default settings are usually robust.\n        *   **User Logic Backpressure**: Your user logic that sends TLPs to the PCIe IP core (`m_axis_tx_*` interface) *must* respect the `m_axis_tx_tready` signal from the IP core. If `tready` is de-asserted, you *must* pause sending data. Failing to do so will overflow the core's buffers.\n        *   **ILA Debugging**: Connect ILA probes to the flow control interface signals of the PCIe IP core and your user logic to observe if `tvalid`/`tready` handshake is working correctly.\n\n3.  **Inefficient DMA Logic / Buffering Issues**:\n    *   **Cause**: Your DMA engine implementation within the FPGA (the part that reads/writes data to/from host memory) is not optimized, causing bottlenecks. This can involve:\n        *   Lack of pipelining.\n        *   Inefficient use of BRAMs.\n        *   Stalls due to external memory access latency.\n        *   Small burst sizes.\n    *   **Solution**:\n        *   **Pipelining**: Break down long combinational paths into smaller, sequential stages using registers. This allows higher clock frequencies and better throughput.\n        *   **Buffering**: Use FIFOs (First-In, First-Out buffers) to decouple sender and receiver logic, smoothing out data flow and preventing stalls.\n        *   **Burst Transfers**: Utilize PCIe's ability to perform burst reads/writes for efficiency. Ensure your DMA logic requests and handles data in appropriate burst sizes.\n        *   **Memory Bandwidth**: Ensure your BRAMs or external DDR memory interfaces are capable of supplying/consuming data fast enough for your desired DMA rates.\n        *   **ILA**: Monitor your DMA engine's internal state, read/write pointers, and data path signals to identify bottlenecks.\n\n4.  **Completion Timeout / Unsupported Request**:\n    *   **Cause**: The host sends a request (e.g., MRd, CfgRd), but your FPGA device does not respond with a Completion TLP within the allowed timeout period, or it responds with an error status (e.g., Completion with Unsupported Request (UR) or Completer Abort (CA)).\n    *   **Solution**:\n        *   **Response Logic**: Verify that your `bar_controller` (for MRds) and `pcileech_pcie_cfg_a7.sv` (for CfgRds to custom config space) correctly identify the request and generate the appropriate Completion.\n        *   **Timeout Value**: Review your donor device's expected completion latency. While PCIe defines default timeouts, some drivers might be sensitive.\n        *   **ILA/Protocol Analyzer**: Crucial for pinpointing *why* a completion isn't sent or why it's malformed. Is the request TLP even reaching your user logic? Is your logic generating a response? Is the PCIe core successfully sending the response?\n\n---\n\n## **14. Emulation Accuracy and Optimizations**\n\nAchieving truly convincing emulation means making your FPGA-based device indistinguishable from the donor, not just in its ID, but in its behavior. This requires meticulous attention to timing, responsiveness, and subtle operational details.\n\n### **14.1 Techniques for Accurate Timing Emulation**\n\nPrecise timing is paramount in hardware, especially for high-speed interfaces like PCIe. Mismatches can lead to driver timeouts, incorrect data interpretation, or system instability.\n\n*   **Implement Timing Constraints (XDC Files)**:\n    *   **Purpose**: Timing constraints are instructions to Vivado's synthesis and implementation tools, telling them how fast your design needs to operate. They define clock periods, input/output delays, and path delays.\n    *   **Usage**: The PCILeech-FPGA project includes XDC files (e.g., `pcileech_squirrel_top.xdc`) that define the main clocks (e.g., `create_clock -name sys_clk_p -period 8.0 [get_ports sys_clk_p]`).\n    *   **Refinement**: If your emulation requires very specific internal timing or reacts to time-sensitive commands, you might need to add further constraints to critical paths (`set_max_delay`, `set_input_delay`, `set_output_delay`) within your custom logic.\n    *   **Goal**: Ensure Vivado reports **positive WNS (Worst Negative Slack)** for all paths after implementation, indicating the design meets its timing requirements.\n\n*   **Use Clock Domain Crossing (CDC) Techniques**:\n    *   **Purpose**: PCIe designs often involve multiple clock domains (e.g., a 125MHz PCIe user clock, a separate clock for your custom logic). Moving signals between these domains asynchronously (without proper synchronization) can lead to **metastability**, causing unreliable behavior.\n    *   **Implementation**: Always use proper CDC circuits for signals crossing clock domains:\n        *   **Two-Flip-Flop Synchronizers**: For single bit control signals.\n        *   **Asynchronous FIFOs (First-In, First-Out)**: For multi-bit data paths, providing buffering and flow control between clock domains.\n        *   **Gray Code Encoders/Decoders**: For counters or addresses crossing domains to ensure only one bit changes at a time.\n    *   **Vivado Tools**: Vivado includes CDC analysis tools (e.g., `report_cdc`) that can identify potential metastability issues.\n\n*   **Simulate Device Behavior with Time-Accurate Models**:\n    *   **Advanced Test Benches**: Use SystemVerilog test benches that incorporate realistic timing delays or even provide time-accurate PCIe bus functional models (BFMs).\n    *   **Verification**: This allows you to observe how your emulated device's internal state and external TLP generation/response timings behave under various conditions, ensuring they match your captured donor device behavior.\n\n### **14.2 Dynamic Response to System Calls**\n\nA truly accurate emulation doesn't just present the correct IDs; it also reacts intelligently and dynamically to the host system's commands and queries, mimicking the behavior of a real, active device.\n\n*   **Implement State Machines for Device Control**:\n    *   **Purpose**: Design robust SystemVerilog state machines that manage the device's operational modes, command processing, and data flow.\n    *   **Responsiveness**: Ensure the state machine transitions logically and quickly in response to incoming commands (e.g., writes to control registers in a BAR, specific TLPs).\n    *   **Graceful Handling**: The state machine should be able to handle unexpected or out-of-order requests gracefully, perhaps returning an error TLP or simply ignoring invalid commands, rather than crashing or freezing.\n\n*   **Monitor and Respond to Host Commands (Beyond Simple Reads/Writes)**:\n    *   **Configuration Writes**: Beyond initial enumeration, drivers often write to configuration space registers to enable features, set thresholds, or clear status bits. Your firmware must process these writes and update internal state accordingly.\n    *   **Vendor-Specific Commands**: As discussed in Section 9.2, if the donor device has proprietary commands (accessed via custom registers or Vendor Defined Messages), your firmware must parse these commands and trigger the appropriate emulated behavior.\n    *   **Power Management Commands**: React to host-initiated power state transitions (D0, D1, D3hot, etc.) by enabling/disabling internal logic and acknowledging the state change.\n    *   **Interrupt Acknowledgment**: If the host driver acknowledges interrupts by writing to a specific register, ensure your firmware can detect this and clear the internal interrupt request.\n\n*   **Optimize Firmware Logic for Responsiveness**:\n    *   **Reduce Latency**: Critical data paths and control paths should be optimized to minimize combinational logic depth and pipeline stalls.\n    *   **Parallelism**: Leverage the FPGA's inherent parallelism to perform multiple operations concurrently, improving throughput and response times.\n    *   **Efficient Memory Access**: Optimize access to internal BRAMs or external DDR memory to ensure data is available when needed for DMA transfers or register reads.\n    *   **Hardware Acceleration**: For complex computations or data manipulations that the donor device performs, consider implementing dedicated hardware accelerators on the FPGA rather than trying to perform them in a slow, software-like fashion.\n\n---\n\n## **15. Best Practices for Firmware Development**\n\nAdhering to best practices in custom firmware development is crucial for maintaining code quality, facilitating collaboration (if working in a team), simplifying debugging, and ensuring the long-term maintainability and reliability of your project. This is especially true for security-sensitive applications.\n\n### **15.1 Continuous Testing and Documentation**\n\n*   **Regular, Incremental Testing**:\n    *   **Unit Testing**: Test small, individual modules (e.g., a TLP parser, a register block) in isolation using dedicated test benches.\n    *   **Integration Testing**: Verify that different modules work together correctly.\n    *   **System Testing**: After flashing, perform end-to-end tests with the host system to ensure overall functionality.\n    *   **Test Early, Test Often**: Test the firmware after each significant change, no matter how small, to catch issues early when they are easier to debug.\n\n*   **Automated Testing (Advanced)**:\n    *   For complex projects, implement automated test scripts (e.g., using Python with a hardware abstraction layer) on the host side to repeatedly verify functionality and performance.\n    *   Consider integrating with Continuous Integration (CI) tools (e.g., Jenkins, GitLab CI) in a team environment to automate builds, tests, and static analysis on every code commit.\n\n*   **Maintain Comprehensive Documentation**:\n    *   **Design Documents**: Create and update documents that describe your firmware's architecture, including:\n        *   **Block Diagrams**: Illustrating the major modules and their interconnections.\n        *   **State Machine Diagrams**: For all stateful logic.\n        *   **Interface Specifications**: Detailing input/output signals, timing, and protocols between modules.\n        *   **Memory Maps**: For all BARs, defining register addresses, bit fields, and their functionality.\n    *   **Code Comments**: Use clear, concise comments within your SystemVerilog code to explain complex logic, purpose of signals, and any non-obvious design choices.\n    *   **Change Log/Commit Messages**: Maintain a change log or use detailed Git commit messages to track all modifications, bug fixes, and feature additions, explaining *why* changes were made.\n    *   **User Guide**: For your custom firmware, a simple user guide explaining how to build, flash, and interact with the emulated device from the host side is invaluable.\n\n### **15.2 Managing Firmware Versioning**\n\nProper version control is essential for tracking changes, collaborating effectively, and managing releases.\n\n*   **Use Version Control Systems (VCS)**:\n    *   **Git**: Strongly recommended. Use Git to manage your HDL source code, constraints files, and project scripts.\n    *   **Organize Repository**: Maintain a clear directory structure (e.g., separate folders for `src`, `xdc`, `ip`, `scripts`, `doc`).\n    *   **Branches**: Use feature branches for developing new capabilities or large changes. Merge back to a `main` or `develop` branch after thorough testing.\n    *   **Regular Commits**: Commit frequently with atomic, meaningful commit messages.\n\n*   **Tag Releases and Milestones**:\n    *   **Stable Versions**: Use Git tags (e.g., `v1.0.0`, `v1.0.1_bugfix`) to mark stable, tested versions of your firmware. This makes it easy to revert or deploy a known good state.\n    *   **Milestones**: Tag significant development milestones (e.g., \"Basic Enumeration Working,\" \"DMA Read/Write Functional\").\n\n*   **Backup and Recovery Strategy**:\n    *   **Cloud-Based Repositories**: Host your Git repository on platforms like GitHub, GitLab, or Bitbucket. This provides off-site backups and facilitates collaboration.\n    *   **Local Backups**: Even with cloud repositories, maintain regular local backups of your entire Vivado project directory (which can be very large due to generated files).\n\n### **15.3 Security Considerations**\n\nDeveloping custom firmware for PCIe device emulation, especially one capable of Direct Memory Access, carries significant security implications. This technology is inherently a \"dual-use\" capability, meaning it can be used for both legitimate (e.g., hardware testing, security research) and malicious purposes (e.g., DMA attacks, security bypasses). **It is paramount to understand and responsibly manage these risks.**\n\n*   **Dual-Use Nature and Ethical Implications**:\n    *   **Ethical Hacking vs. Malicious Use**: Clearly distinguish between using this knowledge for authorized security testing (red teaming, penetration testing) and unauthorized, illegal activities.\n    *   **Responsible Disclosure**: If you discover vulnerabilities using these techniques, follow responsible disclosure guidelines.\n    *   **Legal and Licensing Compliance**: Be aware of and comply with all relevant laws, regulations, and licensing agreements (e.g., PCIe-SIG specifications, Xilinx EULAs) concerning hardware reverse engineering and device modification.\n    *   **\"Weaponization\"**: Recognize that the ability to accurately emulate trusted hardware can be weaponized for advanced persistent threats (APTs) or sophisticated malware.\n\n*   **Understanding Attack Vectors (Offensive Perspective)**:\n    *   **Memory Exfiltration**: A malicious emulated device can perform DMA reads to access any physical memory address, including sensitive data in the kernel, user processes, cryptographic keys, or network buffers.\n    *   **Memory Injection/Modification**: A malicious emulated device can perform DMA writes to arbitrarily modify memory, enabling:\n        *   **Privilege Escalation**: Modifying kernel data structures (e.g., process tokens, SIDs) to gain administrator or system privileges.\n        *   **Code Injection**: Injecting malicious code into running processes or the kernel, then triggering its execution.\n        *   **Security Software Bypass**: Disabling or subverting endpoint detection and response (EDR), antivirus, or firewall software by modifying their memory directly.\n    *   **Fuzzing and Crashing**: Sending malformed or out-of-spec TLPs/commands to trigger driver vulnerabilities, leading to system crashes (BSODs) or potentially exploitable memory corruption.\n    *   **Firmware/BIOS Manipulation**: In some advanced scenarios, a DMA device might be able to interact with the host's SPI flash memory containing the BIOS/UEFI, potentially for persistent modification.\n\n*   **Defensive Measures and Mitigation Strategies (Defensive Perspective)**:\n    *   **IOMMU/VT-d/AMD-Vi**: As noted in Section 3.2, these technologies are designed to mitigate DMA attacks by providing memory protection for peripherals. **For legitimate testing, you disable them, but in production systems, they should always be enabled.** They prevent unauthorized memory access by peripherals.\n    *   **Kernel DMA Protection (Windows) / Thunderbolt Security (Linux)**: Modern OS features specifically address \"cold boot\" DMA attacks (where an attacker connects a malicious device while the system is off or locked). Keep these enabled on production systems.\n    *   **Secure Boot**: While not directly a DMA protection, Secure Boot helps ensure that only trusted bootloaders and kernel modules are loaded, reducing the chance of an attacker injecting malicious kernel components to bypass DMA protections.\n    *   **Physical Security**: The most basic but critical defense. If an attacker has physical access to a PCIe slot or Thunderbolt port, they can bypass many software protections. Secure physical access to critical systems.\n    *   **Driver Hardening**: Drivers should be written defensively, validating all inputs from hardware and operating within strict memory boundaries.\n    *   **Memory Hardening**: OS-level memory protections (e.g., KASLR, DEP, SMAP/SMEP) help reduce the impact of memory corruption, but a direct DMA attack bypasses these.\n    *   **Monitoring and Logging**: While difficult at the hardware level, unusual DMA activity or enumeration of unknown PCIe devices should trigger alerts in security monitoring systems.\n\n*   **Secure Coding Practices for Firmware**:\n    *   **Input Validation**: If your firmware accepts any inputs (e.g., via a UART debug interface, or internal registers written by the host), validate them rigorously to prevent buffer overflows, integer overflows, or unexpected behavior.\n    *   **Least Privilege**: Design your firmware logic to only perform the operations absolutely necessary for its function. Avoid granting unnecessary capabilities.\n    *   **State Management**: Implement robust state machines to prevent unintended behavior due to invalid state transitions.\n    *   **No Hardcoded Secrets**: Avoid embedding sensitive information (e.g., cryptographic keys, hardcoded credentials) directly in your firmware if it could be easily extracted.\n    *   **Tamper Detection**: For production firmware, consider implementing mechanisms to detect if the firmware itself has been tampered with or if non-authorized configurations are loaded.\n\n---\n\n## **16. Additional Resources**\n\nTo deepen your understanding and stay updated in the dynamic fields of FPGA development, PCIe, and hardware security, consult the following resources:\n\n*   **Xilinx (AMD) Documentation**: Your primary source for all things Vivado and Xilinx FPGAs.\n    *   **Main Documentation Portal**: [https://docs.amd.com/](https://docs.amd.com/) (formerly Xilinx.com/support/documentation).\n    *   **Vivado Design Suite User Guides**:\n        *   **UG900 - Getting Started**: Essential for new Vivado users.\n        *   **UG901 - Logic Synthesis**: Deep dive into synthesis.\n        *   **UG904 - Implementation**: Detailed guide on placement and routing.\n        *   **UG912 - Tcl Command Reference Guide**: Invaluable for scripting.\n        *   **UG939 - Debugging**: Comprehensive guide to ILA and other debug features.\n    *   **PCI Express IP Core User Guide**: Critically important for understanding the Xilinx PCIe IP (e.g., **PG054 for 7 Series Integrated Block for PCI Express**). Search for \"PCI Express\" on the documentation portal. This details the core's configuration, interfaces, and limitations.\n\n*   **PCI-SIG Specifications**: The definitive source for the PCIe standard.\n    *   **PCI Express Base Specification**: The foundational document. While not publicly free, summaries and educational materials based on it are widely available. You can usually find information on their website: [https://pcisig.com/specifications](https://pcisig.com/specifications) (Note: Full specifications typically require PCI-SIG membership).\n\n*   **FPGA Tutorials and Learning Platforms**:\n    *   **FPGA4Fun**: [http://www.fpga4fun.com/](http://www.fpga4fun.com/) - A classic site with many practical FPGA projects and tutorials.\n    *   **Verilog/VHDL Tutorials**:\n        *   **ASIC World Verilog Tutorials**: [https://www.asic-world.com/verilog/index.html](https://www.asic-world.com/verilog/index.html) - Good fundamental Verilog reference.\n        *   **VHDLwhiz**: [https://www.vhdlwhiz.com/](https://www.vhdlwhiz.com/) - VHDL reference and tutorials.\n    *   **Stack Overflow (FPGA/Verilog/PCIe tags)**: [https://stackoverflow.com/questions/tagged/fpga](https://stackoverflow.com/questions/tagged/fpga) - Community-driven Q&A for specific technical problems.\n\n*   **PCIe Protocol Analysis Tools**:\n    *   **Teledyne LeCroy Protocol Analyzers**: [https://teledynelecroy.com/protocolanalyzer/](https://teledynelecroy.com/protocolanalyzer/) - Explore their range of high-performance PCIe analyzers and software.\n    *   **Telescan PE Software**: [https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software) - A no-cost software tool that provides some PCIe analysis features (requires registration).\n\n*   **PCILeech Community & Resources**:\n    *   The `ufrisk/pcileech` GitHub repository is the core. Actively follow its updates and issues.\n    *   Look for community forums or Discord servers dedicated to PCILeech or similar open-source DMA projects.\n\n*   **Hardware Security & Reverse Engineering**:\n    *   Books on hardware hacking, reverse engineering, and low-level system exploitation.\n    *   Conferences like Black Hat, DEF CON, Recon, and Troopers often feature talks on PCIe and DMA attacks.\n    *   Blogs and research papers from security researchers focusing on hardware.\n\n---\n\n## **17. Contact Information**\n\nIf you need assistance, have questions, or wish to collaborate on topics related to this guide, firmware development, or hardware security, please feel free to reach out. I'm available to provide guidance, troubleshoot complex problems, or discuss ideas in detail.\n\n### **Discord**:\n*   **User**: [**VCPU**](https://discord.com/users/196741541094621184)\n*   **Server Invite Link**: [**Join the Hardware Hacking & Firmware Development Discord**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **18. Support and Contributions**\n\nYour support helps maintain and improve this guide and related projects. Creating and updating comprehensive technical documentation and open-source hardware projects requires significant time and effort.\n\n### **Donations**\n\nIf you found this guide helpful and want to support ongoing work, consider contributing. Every donation, no matter how small, helps in continuing to create, share, and support the community through further research, development, and documentation efforts.\n\n*   **Crypto Donations (LTC - Litecoin)**:\n    *   **Address**: `MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi`\n\n**Special Bonus**: If you donate, please feel free to reach out on Discord (VCPU) to receive a personal thank you and possibly additional resources, early access to new content, or personalized assistance with your project.\n\n**Note**: If you need me to review specific sections of your implementation, troubleshoot issues, or provide detailed feedback on your code, please mark the relevant sections within your code with `//VCPU-REVIEW//` comments and provide detailed explanations of the problems or questions you're encountering. This helps me focus my efforts and provide the most effective support.\n\nMay God bless your soul.\n\n---\n\n**End of Guide**\n"
  },
  {
    "path": "RU/README.md",
    "content": "# **Руководство по разработке пользовательской прошивки для полной эмуляции устройства**\n\n---\n\n**Выражаю огромную благодарность легенде, которая сделала пожертвование, я скоро свяжусь с вами. Я добавлю сюда публичную благодарность, если вы хотите + больше, просто напишите мне в личные сообщения, если вы еще этого не сделали!**\n\nРаботаю над организацией этого материала в [вики](https://github.com/JPShag/PCILeech-DMA-Firmware/wiki/Introduction). Помощь приветствуется!\n\n----\n\n**Примечание от автора и статус руководства:**\n\nЯ делюсь этим прозрачно, так как последние времена были невероятно сложными. Помимо значительных финансовых потерь из-за мошеннического оспаривания платежа, я столкнулся с множеством других трудных жизненных проблем и проблем со здоровьем, которые сильно повлияли на мою способность быть онлайн и уделять время проектам. Честно говоря, продолжать создавать такие всеобъемлющие ресурсы, как это руководство, было глубокой борьбой на фоне этих личных трудностей.\n\nОжидается, что это будет последняя крупная итерация основного руководства. Для более опытных пользователей, уже знакомых с фундаментальными аппаратными концепциями (например, с функцией чипа FTDI), будет также доступна краткая, минифицированная версия.\n\nЕсли вы считаете эту работу ценной и имеете возможность помочь, любая форма поддержки будет глубоко оценена. Ваша щедрость позволяет мне продолжать вносить вклад в это сообщество, несмотря на постоянные трудности. Я искренне надеюсь, что это руководство было и остается ценным ресурсом.\n\n---\n\n## В память и посвящение\n\n![Ross](https://github.com/user-attachments/assets/de7f12fe-8992-4738-a6af-712dc48217ee)\n\nЭто руководство с глубоким уважением посвящается памяти\n**Росса Фримена (1947–1989)**\n\nДальновидный инженер, новатор из Мичигана и соучредитель Xilinx, Росс Фримен широко признан отцом технологии Field-Programmable Gate Array (FPGA), которая произвела революцию в вычислительной технике.\n\nВ 1984 году, когда полупроводниковая промышленность преимущественно фокусировалась на чипах с фиксированными функциями, Фримен осмелился представить другую парадигму: оборудование, которое можно было бы перепрограммировать после производства. Его революционный патент (№ 4,870,302) и неустанная поддержка реконфигурируемых вычислений открыли технологическую парадигму, которая продолжает трансформировать наш мир спустя четыре десятилетия.\n\nЕго новаторское изобретение позволило быстро создавать прототипы и развертывать пользовательские кремниевые решения без непомерных затрат на традиционную разработку ASIC, демократизируя аппаратное проектирование и ускоряя технологический прогресс в бесчисленных областях.\n\nСегодня видение Фримена питает передовые достижения в области искусственного интеллекта, высокопроизводительных вычислений, телекоммуникаций, автомобильных систем, аэрокосмических приложений и многих других областей, которые были лишь мечтами при его жизни.\n\nПосмертно введенный в Национальный зал славы изобретателей в 2009 году, его наследие сохраняется не только в кремнии, но и в духе технологической смелости, которая призывает всех нас подвергать сомнению установленные ограничения и представлять новые возможности.\n\n*\"Конечной целью FPGA было создание программируемых логических устройств, которые могли бы заменить стандартные цифровые чипы.\"* — Росс Фримен\n\n---\n\n## **Содержание**\n\n### **Часть 1: Основополагающие концепции**\n\n1.  [Введение](#1-введение)\n    *   [1.1. Цель руководства](#11-цель-руководства)\n    *   [1.2. Целевая аудитория](#12-целевая-аудитория)\n    *   [1.3. Как пользоваться этим руководством](#13-как-пользоваться-этим-руководством)\n2.  [Ключевые определения](#2-ключевые-определения)\n3.  [Совместимость устройств](#3-совместимость-устройств)\n    *   [3.1. Поддерживаемое оборудование на базе FPGA](#31-поддерживаемое-оборудование-на-базе-fpga)\n    *   [3.2. Аппаратные особенности PCIe](#32-аппаратные-особенности-pcie)\n    *   [3.3. Системные требования](#33-системные-требования)\n4.  [Требования](#4-требования)\n    *   [4.1. Аппаратное обеспечение](#41-аппаратное-обеспечение)\n    *   [4.2. Программное обеспечение](#42-программное-обеспечение)\n    *   [4.3. Настройка среды](#43-настройка-среды)\n5.  [Сбор информации об устройстве-доноре](#5-сбор-информации-об-устройстве-доноре)\n    *   [5.1. Использование Arbor для сканирования устройств PCIe](#51-использование-arbor-для-сканирования-устройств-pcie)\n    *   [5.2. Извлечение и запись атрибутов устройства](#52-извлечение-и-запись-атрибутов-устройства)\n6.  [Начальная настройка прошивки](#6-начальная-настройка-прошивки)\n    *   [6.1. Изменение пространства конфигурации](#61-изменение-пространства-конфигурации)\n    *   [6.2. Вставка серийного номера устройства (DSN)](#62-вставка-серийного-номера-устройства-dsn)\n7.  [Настройка проекта Vivado](#7-настройка-проекта-vivado)\n    *   [7.1. Генерация файлов проекта Vivado](#71-генерация-файлов-проекта-vivado)\n    *   [7.2. Изменение IP-блоков](#72-изменение-ip-блоков)\n\n### **Часть 2: Промежуточные концепции и реализация**\n\n8.  [Расширенная настройка прошивки](#8-расширенная-настройка-прошивки)\n    *   [8.1. Настройка параметров PCIe для эмуляции](#81-настройка-параметров-pcie-для-эмуляции)\n    *   [8.2. Настройка БАР и отображения памяти](#82-настройка-бар-и-отображения-памяти)\n    *   [8.3. Эмуляция управления питанием устройства и прерываний](#83-эмуляция-управления-питанием-устройства-и-прерываний)\n9.  [Эмуляция специфических возможностей устройства](#9-эмуляция-специфических-возможностей-устройства)\n    *   [9.1. Реализация расширенных возможностей PCIe](#91-реализация-расширенных-возможностей-pcie)\n    *   [9.2. Эмуляция функций, специфичных для поставщика](#92-эмуляция-функций-специфичных-для-поставщика)\n10. [Эмуляция пакетов транспортного уровня (TLP)](#10-эмуляция-пакетов-транспортного-уровня-tlp)\n    *   [10.1. Понимание и захват TLP-пакетов](#101-понимание-и-захват-tlp-пакетов)\n    *   [10.2. Создание пользовательских TLP-пакетов для специфических операций](#102-создание-пользовательских-tlp-пакетов-для-специфических-операций)\n\n### **Часть 3: Продвинутые методы и оптимизация**\n\n11. [Сборка, прошивка и тестирование](#11-сборка-прошивка-и-тестирование)\n    *   [11.1. Синтез и реализация](#111-синтез-и-реализация)\n    *   [11.2. Прошивка битстрима](#112-прошивка-битстрима)\n    *   [11.3. Тестирование и проверка](#113-тестирование-и-проверка)\n12. [Продвинутые методы отладки](#12-продвинутые-методы-отладки)\n    *   [12.1. Использование встроенного логического анализатора Vivado](#121-использование-встроенного-логического-анализатора-vivado)\n    *   [12.2. Инструменты анализа трафика PCIe](#122-инструменты-анализа-трафика-pcie)\n13. [Устранение неполадок](#13-устранение-неполадок)\n    *   [13.1. Проблемы с обнаружением устройства](#131-проблемы-с-обнаружением-устройства)\n    *   [13.2. Ошибки отображения памяти и конфигурации BAR](#132-ошибки-отображения-памяти-и-конфигурации-bar)\n    *   [13.3. Ошибки производительности DMA и TLP](#133-ошибки-производительности-dma-и-tlp)\n14. [Точность эмуляции и оптимизация](#14-точность-эмуляции-и-оптимизация)\n    *   [14.1. Методы для точной эмуляции временных характеристик](#141-методы-для-точной-эмуляции-временных-характеристик)\n    *   [14.2. Динамический отклик на системные вызовы](#142-динамический-отклик-на-системные-вызовы)\n15. [Лучшие практики разработки прошивок](#15-лучшие-практики-разработки-прошивок)\n    *   [15.1. Непрерывное тестирование и документирование](#151-непрерывное-тестирование-и-документирование)\n    *   [15.2. Управление версиями прошивки](#152-управление-версиями-прошивки)\n    *   [15.3. Вопросы безопасности](#153-вопросы-безопасности)\n16. [Дополнительные ресурсы](#16-дополнительные-ресурсы)\n17. [Контактная информация](#17-контактная-информация)\n18. [Поддержка и вклад](#18-поддержка-и-вклад)\n\n---\n\n## **Часть 1: Основополагающие концепции**\n\n---\n\n## **1. Введение**\n\n### **1.1. Цель руководства**\n\nОсновная цель этого руководства — предоставить вам знания и практические навыки для разработки пользовательской прошивки для прямого доступа к памяти (DMA) на устройствах на базе программируемых логических интегральных схем (FPGA). Эта специализированная прошивка позволяет вашей FPGA точно эмулировать идентичность и поведение других аппаратных устройств с интерфейсом PCIe (Peripheral Component Interconnect Express). Такая эмуляция является мощным методом с глубокими последствиями в нескольких продвинутых областях:\n\n**Исследования аппаратной безопасности**:\n*   **Обнаружение уязвимостей**: Эмулируя устройство, вы можете создать контролируемую среду для отправки некорректных или неожиданных данных драйверам хоста, систематически проводя фаззинг для поиска уязвимостей (например, переполнений буфера, состояний гонки), которые могут быть использованы с периферийного аппаратного обеспечения.\n*   **Анализ драйверов**: Наблюдайте, как операционные системы и конкретные драйверы взаимодействуют с оборудованием. Вы можете эмулировать устройства с нестандартными конфигурациями или недокументированными функциями, чтобы понять поведение драйвера, выявить предположения безопасности или реверс-инжинирить проприетарные протоколы.\n*   **Анализ побочных каналов**: Хотя это более сложно, эмулируемое устройство потенциально может быть запрограммировано для помощи в экспериментах, связанных с утечкой информации через анализ временных характеристик или энергопотребления, путем точного управления периферийными операциями.\n\n**Red Teaming и тестирование на проникновение**:\n*   **Обход мер безопасности**: Эмулируйте внешне безопасное или внесенное в белый список аппаратное устройство (например, обычный сетевой контроллер или контроллер хранилища) для получения привилегий DMA. После достижения этого, это позволяет напрямую взаимодействовать с системной памятью, потенциально обходя системы обнаружения и реагирования на конечных точках (EDR) или антивирусные решения, которые работают на более высоких программных уровнях.\n*   **Скрытое закрепление**: Эмулируемое вредоносное устройство может предложить скрытый способ сохранения доступа к скомпрометированной системе, поскольку его может быть труднее обнаружить, чем программные импланты.\n*   **Использование доверительных отношений**: Системы часто неявно доверяют подключенному оборудованию. Пользовательская прошивка может использовать это, имитируя устройства, которым предоставлены определенные разрешения или доступ.\n\n**Отладка и диагностика систем**:\n*   **Воспроизводимые тестовые стенды**: Создавайте высокоспецифичные аппаратные сценарии для надежного воспроизведения трудноуловимых ошибок, которые могут возникать только при определенных состояниях устройства или шаблонах данных.\n*   **Инъекция ошибок**: Намеренно эмулируйте неисправное поведение устройства (например, некорректное формирование TLP-пакетов, задержки ответов) для проверки надежности и возможностей обработки ошибок хост-системы и ее драйверов.\n\n**Тестирование и валидация оборудования**:\n*   **Разработка драйверов**: Тестируйте новые или измененные драйверы на эмулированном аппаратном профиле до того, как физические прототипы станут доступны, или для имитации более широкого спектра аппаратных вариантов, чем физически доступно.\n*   **Тестирование на соответствие**: Хотя это не заменяет официальные тесты на соответствие, эмулируемое устройство может помочь предварительно проверить некоторые аспекты соответствия протоколу PCIe.\n\n**Поддержка устаревших систем и совместимость**:\n*   Эмулируйте старые, снятые с производства или труднодоступные устройства PCIe, чтобы поддерживать работоспособность устаревших систем или устранять пробелы в совместимости между различными поколениями оборудования.\n\nПроходя это руководство, вы приобретете навыки в:\n*   Тщательном извлечении идентификационных атрибутов и деталей конфигурации из физического устройства-«донора» PCIe.\n*   Модификации и расширении существующих открытых фреймворков прошивок FPGA (с основным акцентом на широко используемый проект PCILeech-FPGA) для принятия идентичности устройства-донора.\n*   Настройке и использовании профессионального набора инструментов для разработки FPGA, сосредоточенного вокруг Xilinx Vivado, наряду с основными инструментами редактирования кода, такими как Visual Studio Code.\n*   Развитии твердого понимания многоуровневой архитектуры PCIe, механики передачи данных DMA и нюансов создания прошивки, которая точно воспроизводит поведение оборудования на низком уровне.\n\n### **1.2. Целевая аудитория**\n\nЭто руководство предназначено для лиц, уже обладающих базовыми или средними знаниями компьютерных систем, аппаратных принципов и разработки программного обеспечения. Содержание технически требовательно и предполагает способность к детальной работе на низком уровне. В частности, оно подходит для:\n\n*   **Разработчиков прошивок**: Инженеров, стремящихся проектировать или адаптировать прошивки для FPGA, особенно для приложений, включающих высокоскоростную передачу данных (DMA) и прямое манипулирование аппаратными интерфейсами через PCIe. Настоятельно рекомендуется знание Verilog/VHDL и опыт работы с инструментами разработки FPGA.\n*   **Аппаратных инженеров**: Специалистов, занимающихся проектированием, тестированием или валидацией оборудования на базе PCIe. Это руководство может помочь в создании сложных тестовых стендов или эмуляции компонентов в рамках более крупного системного проектирования. Ожидается знакомство с протоколом PCIe и цифровым проектированием.\n*   **Специалистов и исследователей в области кибербезопасности**:\n    *   **Исследователей уязвимостей и разработчиков эксплойтов**: Тех, кто хочет исследовать аппаратные поверхности атаки или разрабатывать прототипы эксплойтов, использующих DMA. Крайне важно понимание внутренней структуры ОС, управления памятью и архитектуры драйверов.\n    *   **Членов Red Team**: Операторов, ищущих продвинутые методы доступа к системе, закрепления и эксфильтрации данных путем использования прямого манипулирования аппаратным обеспечением.\n    *   **Специалистов по цифровой криминалистике и реагированию на инциденты**: Хотя это руководство ориентировано на атаку, понимание этих методов может помочь в распознавании и анализе сложных аппаратных атак.\n*   **Энтузиастов FPGA и продвинутых любителей**: Лиц с предыдущим опытом работы с проектами FPGA, которые стремятся решать сложные задачи, такие как связь по PCIe и аппаратная эмуляция. Важна готовность углубляться в спецификации и технические описания.\n\nКривая обучения может быть крутой, особенно если концепции PCIe или продвинутых FPGA являются новыми. Однако руководство нацелено на разбиение сложных тем на управляемые шаги.\n\n### **1.3. Как пользоваться этим руководством**\n\nЭто руководство разделено на три логически последовательные части, разработанные для постепенного наращивания ваших знаний:\n\n*   **Часть 1: Основополагающие концепции**: Эта начальная часть имеет решающее значение. Она вводит основную терминологию, базовые принципы PCIe и DMA, необходимый аппаратный и программный стек (включая инструкции по настройке инструментов, таких как Xilinx Vivado и фреймворк PCILeech-FPGA), а также начальные процедуры для получения жизненно важной информации от вашего целевого устройства-«донора» и выполнения базовых модификаций прошивки. Настоятельно рекомендуется последовательно и тщательно изучить эту часть.\n*   **Часть 2: Промежуточные концепции и реализация**: (Предстоящие разделы) Опираясь на фундамент, эта часть проведет вас через более продвинутые настройки прошивки. Темы будут включать тонкую настройку рабочих параметров PCIe, эмуляцию специфических для устройства регистров и возможностей (таких как состояния управления питанием и прерывания, генерируемые сообщениями – MSI/MSI-X), а также первоначальное понимание построения и интерпретации пакетов транспортного уровня (TLP).\n*   **Часть 3: Продвинутые методы и оптимизация**: (Предстоящие разделы) Заключительная часть будет посвящена сложным методам отладки (включая использование встроенных логических анализаторов – ILA и внешних анализаторов протокола PCIe), методам оптимизации производительности прошивки и точности эмуляции, всестороннему устранению распространенных и сложных проблем, а также критическому обсуждению лучших практик, с особым акцентом на вопросы безопасности при разработке и развертывании эмулированных устройств PCIe.\n\n**Работа с руководством**:\n*   **Последовательное прохождение**: Особенно для Частей 1 и 2, следуйте разделам по порядку, так как последующие концепции строятся на предыдущих.\n*   **Практика**: Это практическое руководство. Активно выполняйте шаги по настройке, модификации кода и эксперименты на вашем собственном оборудовании.\n*   **Адаптация к вашей среде**: Пути к файлам, конкретные ID устройств и версии программного обеспечения могут отличаться. Поймите концепции, лежащие в основе инструкций, чтобы адаптировать их к вашей конкретной настройке.\n*   **Обращение к внешним ресурсам**: Спецификация PCIe и документация FPGA являются вашими окончательными справочниками. Это руководство упрощает и направляет, но для глубокого погружения часто требуется обращение к первоисточникам.\n*   **Итеративная разработка**: Разработка прошивки редко бывает линейной. Ожидайте итераций, отладки и доработки ваших проектов. Широко используйте разделы по устранению неполадок и методы отладки.\n\nВы будете работать с ЯОА (SystemVerilog в PCILeech-FPGA), инструментами синтеза и реализации FPGA (Vivado) и, возможно, с хост-стороной программирования и утилитами анализа PCIe.\n\n---\n\n## **2. Ключевые определения**\n\nТвердое понимание следующей терминологии необходимо для навигации по сложностям эмуляции устройств PCIe и разработки пользовательской прошивки. Эти термины будут широко использоваться на протяжении всего руководства.\n\n*   **DMA (Прямой доступ к памяти)**:\n    *   **Определение**: Фундаментальная особенность современной компьютерной архитектуры, позволяющая аппаратным периферийным устройствам (таким как сетевые карты, графические процессоры или ваше эмулируемое устройство на базе FPGA) считывать и записывать данные непосредственно в основную системную память (ОЗУ) без участия центрального процессора (CPU) для каждого переданного байта.\n    *   **Значение**: DMA имеет решающее значение для высокопроизводительных операций ввода-вывода. Снимая задачи передачи данных с CPU, он освобождает CPU для выполнения других вычислений, значительно повышая общую пропускную способность и эффективность системы. В контексте этого руководства ваша FPGA будет использовать DMA для взаимодействия с памятью хост-системы, что является мощной возможностью, часто используемой в исследованиях безопасности и ред-тиминге.\n\n*   **PCIe (Peripheral Component Interconnect Express)**:\n    *   **Определение**: Высокоскоростной последовательный компьютерный стандарт шины расширения, разработанный для замены более старых стандартов шин, таких как PCI, PCI-X и AGP. Он использует топологию \"точка-точка\" с отдельными последовательными линиями, соединяющими каждое устройство с корневым комплексом (обычно являющимся частью чипсета или CPU). Связь осуществляется с помощью пакетов.\n    *   **Значение**: PCIe является доминирующим стандартом для подключения высокопроизводительных периферийных устройств к материнским платам. Понимание его протокола, многоуровневой архитектуры (физический уровень, уровень канала данных, уровень транзакций) и механизмов конфигурации имеет первостепенное значение для эмуляции любого современного аппаратного устройства.\n\n*   **TLP (Пакет транспортного уровня)**:\n    *   **Определение**: Фундаментальная единица обмена данными на уровне транзакций протокола PCIe. TLP-пакеты отвечают за передачу запросов (например, чтение/запись памяти, чтение/запись ввода-вывода, чтение/запись конфигурации) и завершений (ответов на запросы) между устройствами PCIe. Каждый TLP-пакет состоит из заголовка, необязательного блока данных и необязательного CRC от начала до конца (ECRC).\n    *   **Значение**: Для точной эмуляции устройства ваша прошивка FPGA должна быть способна правильно формировать, передавать, принимать и интерпретировать TLP-пакеты, соответствующие поведению устройства-донора. Понимание типов, форматов и управления потоком TLP-пакетов критически важно для продвинутой эмуляции.\n\n*   **BAR (Базовый адресный регистр)**:\n    *   **Определение**: Расположенные в пространстве конфигурации устройства PCIe, BARы — это специальные регистры, используемые устройством для запроса ресурсов адресного пространства у хост-системы. Устройство может иметь до шести 32-битных BARов (или меньше, или пары 32-битных BARов могут образовывать 64-битные BARы). Эти регистры определяют начальные адреса и размеры областей памяти, отображаемой на ввод-вывод (MMIO), или областей портов ввода-вывода, которые устройство использует для предоставления своих регистров и внутренней памяти хост-процессору.\n    *   **Значение**: Когда хост-система перечисляет устройство PCIe, она считывает BARы, чтобы определить требования устройства к памяти и вводу-выводу, затем выделяет и программирует эти BARы фактическими базовыми адресами в карте физических адресов системы. Ваше эмулируемое устройство должно точно определить свои BARы, чтобы они соответствовали устройству-донору, чтобы ОС хоста и драйверы могли правильно взаимодействовать с ним.\n\n*   **FPGA (Программируемая логическая интегральная схема)**:\n    *   **Определение**: Интегральная схема (ИС), которая может быть сконфигурирована разработчиком или заказчиком после изготовления – отсюда и \"field-programmable\" (программируемая на месте). FPGA содержат массив программируемых логических блоков и иерархию реконфигурируемых межсоединений, которые позволяют \"соединять\" блоки для реализации пользовательских цифровых логических схем.\n    *   **Значение**: FPGA являются основным аппаратным обеспечением, используемым в этом руководстве. Их реконфигурируемая природа делает их идеальными для эмуляции других аппаратных устройств, так как вы можете определить точную логику и интерфейсы, необходимые для имитации присутствия и поведения устройства-донора по PCIe.\n\n*   **MSI/MSI-X (Прерывания, генерируемые сообщениями / Расширенные прерывания, генерируемые сообщениями)**:\n    *   **Определение**: Механизмы, позволяющие устройству PCIe доставлять прерывания CPU путем записи специального сообщения (TLP-пакета, в частности, TLP-пакета записи в память) в системно-определенный адрес памяти, а не с использованием выделенных физических линий прерываний (как в устаревшем PCI). MSI-X является усовершенствованием MSI, предлагающим больше векторов прерываний и большую гибкость.\n    *   **Значение**: Большинство современных устройств PCIe используют MSI или MSI-X для более эффективной и гибкой обработки прерываний. Точная эмуляция часто требует реализации выбранного механизма прерываний устройства-донора, включая настройку структур возможностей MSI/MSI-X и правильную генерацию сообщений прерываний.\n\n*   **DSN (Серийный номер устройства)**:\n    *   **Определение**: 64-битный глобально уникальный идентификатор, который может быть опционально реализован устройством PCIe. Если он присутствует, он обычно находится в расширенной структуре возможностей в пространстве конфигурации устройства.\n    *   **Значение**: Хотя не все устройства имеют DSN, некоторые драйверы или программное обеспечение для управления могут использовать его для уникальной идентификации, лицензирования или отслеживания. Правильная его эмуляция может быть важна для полной прозрачности и предотвращения обнаружения эмулируемого устройства.\n\n*   **Пространство конфигурации PCIe**:\n    *   **Определение**: Стандартизированная область адресов размером 256 байт (для устройств конечной точки типа 0) или 4 КБ, связанная с каждой функцией PCIe (устройство может иметь несколько функций). Это пространство содержит жизненно важную информацию об устройстве, включая его Vendor ID, Device ID, Class Code, Revision ID, BARы, указатели на возможности и различные регистры состояния и управления. Доступ к нему осуществляется хост-системой с помощью специальных TLP-пакетов чтения и записи конфигурации.\n    *   **Значение**: Пространство конфигурации — это \"удостоверение личности\" устройства PCIe. Самым первым шагом в эмуляции устройства является тщательное воспроизведение соответствующих частей пространства конфигурации устройства-донора в прошивке вашей FPGA. Хост-система использует эту информацию для идентификации, настройки и выделения ресурсов устройству.\n\n*   **Устройство-донор**:\n    *   **Определение**: Физическое аппаратное устройство PCIe, идентичность и поведение которого вы стремитесь эмулировать на своей FPGA. Это устройство служит источником для извлечения деталей конфигурации (Vendor ID, Device ID, настройки BAR, возможности и т.д.) и поведенческих шаблонов.\n    *   **Значение**: Точность вашей эмуляции напрямую зависит от того, насколько точно и полно вы сможете собрать и воспроизвести характеристики устройства-донора.\n\n*   **Корневой комплекс (RC)**:\n    *   **Определение**: Сущность в иерархии PCIe, которая соединяет CPU и подсистему памяти с PCIe-фабрикой. Он генерирует транзакции PCIe от имени CPU и обрабатывает транзакции, инициированные нижестоящими устройствами PCIe. Он также выполняет начальное перечисление и конфигурацию шины.\n    *   **Значение**: Ваше эмулируемое устройство будет преимущественно взаимодействовать с корневым комплексом (или коммутаторами, подключенными к нему) при связи с хост-системой.\n\n*   **Конечная точка (EP)**:\n    *   **Определение**: Тип устройства PCIe, которое находится на периферии PCIe-фабрики, потребляя или производя данные. Примеры включают сетевые карты, графические карты, контроллеры хранилища и устройство FPGA, которое вы будете программировать. Конечные точки запрашивают ресурсы и инициируют транзакции к корневому комплексу.\n    *   **Значение**: В этом руководстве ваша FPGA будет запрограммирована действовать как устройство конечной точки, эмулируя конкретную конечную точку донора.\n\n*   **HDL (Язык описания аппаратуры)**:\n    *   **Определение**: Специализированный компьютерный язык, используемый для описания структуры, дизайна и работы электронных схем, в частности цифровых логических схем. Распространенные HDL включают Verilog и VHDL.\n    *   **Значение**: Вы будете работать с Verilog (в частности, SystemVerilog, расширением Verilog) в проекте PCILeech-FPGA для определения пользовательской логики для вашего эмулируемого устройства.\n\n*   **Битстрим**:\n    *   **Определение**: Конечный файл конфигурации, который загружается в FPGA для программирования ее логических блоков и межсоединений, тем самым реализуя ваш пользовательский аппаратный дизайн. Это скомпилированный вывод из инструментов разработки FPGA (таких как Xilinx Vivado).\n    *   **Значение**: Генерация и прошивка правильного битстрима является конечным шагом в развертывании вашей пользовательской прошивки на FPGA.\n\n---\n\n## **3. Совместимость устройств**\n\nУспешная и точная эмуляция устройства PCIe зависит от обеспечения полной совместимости выбранного аппаратного обеспечения на базе FPGA и конфигурации хост-системы. В этом разделе подробно описаны поддерживаемые платформы FPGA, критические аппаратные особенности PCIe и необходимые системные требования для настройки среды разработки.\n\n### **3.1. Поддерживаемое оборудование на базе FPGA**\n\nХотя это руководство предоставляет общую методологию, адаптируемую к различному аппаратному обеспечению DMA на базе FPGA, наши основные примеры и конкретные инструкции будут сосредоточены на **ПЛИС Xilinx 7-й серии**, обычно встречающихся в открытых платах DMA благодаря их балансу производительности и доступности. Карта **Squirrel DMA (35T)** выделена из-за ее популярности и хорошо документированной совместимости с фреймворком PCILeech-FPGA.\n\nОсновные принципы и методы настройки IP-ядра PCIe и разработки логики на языке описания аппаратуры (HDL) широко применимы к следующим семействам FPGA и конкретным платам:\n\n*   **Squirrel (Artix-7 35T)**\n    *   **Описание**: Широкодоступное и экономичное устройство DMA на базе FPGA с ПЛИС Xilinx Artix-7 35T. Оно предлагает достаточные логические ресурсы и память для стандартных задач сбора памяти и широкого спектра проектов по базовой и промежуточной эмуляции устройств. Это отличная отправная точка для тех, кто новичок в DMA на базе FPGA.\n    *   **Ключевые особенности**: Artix-7 предлагает хорошее соотношение производительности и стоимости, что делает его подходящим для образовательных и исследовательских целей.\n*   **Enigma-X1 (Artix-7 75T)**\n    *   **Описание**: Среднеуровневая FPGA, предлагающая расширенные логические и запоминающие ресурсы по сравнению с 35T, обычно основанная на ПЛИС Xilinx Artix-7 75T. Это обеспечивает большую гибкость для более сложных сценариев эмуляции, больших областей отображения памяти или более сложных операций DMA, требующих дополнительного аппаратного обеспечения FPGA.\n    *   **Ключевые особенности**: Увеличенное количество логических ячеек и блочной памяти (BRAM) позволяет создавать более сложные конструкции.\n*   **ZDMA (Artix-7 100T)**\n    *   **Описание**: Более производительная FPGA на базе Artix-7 100T, оптимизированная для более требовательных взаимодействий с памятью и обширных операций чтения/записи. Эта плата подходит для крупномасштабных решений DMA, высокопроизводительной эмуляции или проектов, требующих значительного объема встроенной памяти.\n    *   **Ключевые особенности**: Вариант 100T обеспечивает существенное увеличение ресурсов, идеально подходящее для расширения границ эмуляции.\n*   **Kintex-7 (K325T, K410T и т.д.)**\n    *   **Описание**: Представляя собой продвинутый уровень, ПЛИС Kintex-7 (например, K325T, K410T) предлагают надежные возможности для очень сложных проектов, крупномасштабных решений DMA и приложений, требующих большего количества линий PCIe или более высоких скоростей (например, Gen3 x8/x16). Хотя они дороже, они предоставляют значительно больше логики, DSP-слайсов и памяти, что позволяет эмулировать высокосложные и требовательные устройства-доноры.\n    *   **Ключевые особенности**: Высокопроизводительные трансиверы для более быстрых поколений PCIe, обильные логические и запоминающие ресурсы для сложных проектов.\n\n**Важное примечание о семействах FPGA**: Хотя принципы схожи, конкретные конфигурации IP-ядер и тактовые структуры могут немного отличаться между различными ПЛИС Xilinx 7-й серии (Artix-7, Kintex-7, Zynq-7000 PS/PL). Всегда обращайтесь к документации конкретной платы и руководствам пользователя IP-ядер Xilinx PCIe для выбранного вами семейства FPGA. Проект PCILeech-FPGA часто предоставляет специфические для платы Tcl-скрипты и исходные файлы для упрощения этого процесса.\n\n### **3.2. Аппаратные особенности PCIe**\n\nДля обеспечения бесперебойной и неограниченной работы вашего DMA-устройства на базе FPGA для эмуляции, несколько особенностей PCIe и хост-системы требуют тщательного рассмотрения, а в некоторых случаях — модификации.\n\n*   **Настройки IOMMU / VT-d / AMD-Vi**\n    *   **Рекомендация**: Для первоначальной настройки и тестирования **настоятельно рекомендуется отключить IOMMU (Intel's Virtualization Technology for Directed I/O - VT-d) или его аналог от AMD (AMD-Vi)** в настройках BIOS/UEFI вашей системы.\n    *   **Обоснование**: IOMMU — это аппаратные компоненты, которые обеспечивают блоки управления памятью для устройств, поддерживающих DMA. Они выполняют преобразование адресов, аналогично MMU CPU, и могут применять разрешения на доступ к памяти. Хотя они имеют решающее значение для безопасности и виртуализации (предотвращая несанкционированный доступ к памяти несанкционированным устройством), они *будут* ограничивать доступ вашего DMA-устройства к системной памяти, потенциально мешая получению памяти и эмуляции устройства. Отключение IOMMU позволяет вашему DMA-устройству неограниченный доступ, что часто необходимо для продвинутых исследований эмуляции и безопасности.\n    *   **Расположение**: Обычно находится в разделах \"CPU Configuration\", \"Virtualization\", \"Advanced Settings\" или \"I/O Virtualization\" в вашем BIOS/UEFI.\n*   **Защита DMA на уровне ядра (Windows) / Уровень безопасности Thunderbolt (Linux)**\n    *   **Рекомендация (Windows)**: Отключите функции **Защиты DMA на уровне ядра** в современных системах Windows. Это включает такие настройки, как **Виртуализация на основе безопасности (VBS)** и **Целостность памяти (HVCI)**. Эти функции используют IOMMU для предотвращения несанкционированных DMA-атак от внешних периферийных устройств, подключенных через Thunderbolt или PCIe.\n    *   **Шаги (Windows)**:\n        *   Получите доступ к настройкам безопасности Windows: **Пуск > Параметры > Конфиденциальность и безопасность > Безопасность Windows > Безопасность устройства**.\n        *   В разделе \"Изоляция ядра\" нажмите \"Сведения об изоляции ядра\".\n        *   Отключите \"Целостность памяти\".\n        *   Вам также может потребоваться отключить Secure Boot в BIOS/UEFI, поскольку VBS часто зависит от него.\n        *   **Внимание**: Отключение этих функций значительно **снижает уровень безопасности вашей системы**, делая ее уязвимой для различных атак, включая те, которые используют вредоносные DMA-устройства. Это следует делать только на выделенной тестовой системе, а не на вашей основной машине, и в безопасной, изолированной среде, где вы понимаете риски.\n    *   **Рекомендация (Linux/Thunderbolt)**: Если вы используете систему с портами Thunderbolt, изучите и потенциально настройте **Уровень безопасности Thunderbolt** в вашем BIOS/UEFI. Более низкие уровни безопасности (например, \"No Security\", \"User Authorization\") обычно требуются для произвольных устройств Thunderbolt/PCIe для выполнения DMA без явного одобрения хоста.\n*   **Требования к слотам PCIe**\n    *   **Рекомендация**: Используйте совместимый слот PCIe, который физически соответствует требованиям FPGA-устройства. Большинство DMA-карт на базе Artix-7 работают на PCIe Gen2 x1 или x4.\n    *   **Обоснование**:\n        *   **Физическое соответствие**: Карта x1 может быть установлена в слоты x1, x4, x8 или x16, но карта x4 требует как минимум слота x4.\n        *   **Производительность**: Хотя карта x4 *может* работать в слоте x1 (если физический разъем открытый или модифицирован), она будет работать со скоростью x1, что серьезно ограничит скорость передачи данных. Для оптимальной производительности и точной эмуляции возможностей устройства-донора убедитесь, что плата FPGA установлена в слот, который обеспечивает как минимум *эмулируемую* ширину и скорость канала (например, если вы эмулируете устройство Gen2 x4, используйте слот Gen2 x4 на хосте).\n    *   **Настройки BIOS материнской платы**: Некоторые материнские платы позволяют настраивать скорость слотов PCIe (например, принудительно Gen1 или Gen2). Убедитесь, что эти настройки не конфликтуют с желаемой скоростью эмуляции.\n\n### **3.3. Системные требования**\n\nНастройка надежной среды разработки является ключом к эффективной разработке прошивки, синтезу и отладке.\n\n*   **Хост-система**\n    *   **Процессор**: Современный многоядерный процессор необходим для запуска инструментов разработки FPGA, таких как Vivado, которые требуют значительных вычислительных мощностей во время синтеза и реализации. (Например, Intel Core i5/i7/i9 или AMD Ryzen 5/7/9 эквивалент, рекомендуется 8-е поколение или новее).\n    *   **Оперативная память (ОЗУ)**: Минимум 16 ГБ ОЗУ настоятельно рекомендуется; **32 ГБ и более идеально** для сложных проектов FPGA, так как Vivado может потреблять значительный объем памяти, особенно во время реализации.\n    *   **Хранилище**: Твердотельный накопитель (SSD) с минимум **200 ГБ свободного места** крайне важен. Установка инструментов FPGA (один Vivado может занимать более 50 ГБ), файлы проекта и результаты синтеза/реализации могут быстро заполнить дисковое пространство. Скорость SSD значительно сокращает время сборки.\n    *   **Операционная система**:\n        *   **Windows 10/11 (64-битная Professional или Enterprise)**: Широко поддерживается Xilinx Vivado и многими инструментами отладки оборудования. Помните о соображениях защиты DMA на уровне ядра.\n        *   **Совместимый дистрибутив Linux (64-битный)**: Выпуски Ubuntu LTS (Long Term Support) (например, 20.04, 22.04) обычно используются и хорошо поддерживаются Vivado. Linux часто предоставляет более гибкую среду для написания скриптов и низкоуровневых инструментов взаимодействия с PCIe.\n*   **Периферийные устройства**\n    *   **JTAG-программатор**: Абсолютно необходим для прошивки скомпилированного битстрима на вашу DMA-карту на базе FPGA. Примеры включают Xilinx Platform Cable USB II, Digilent JTAG-HS3 или встроенные JTAG-программаторы, встречающиеся на некоторых платах разработки. Убедитесь, что он совместим с вашей платой FPGA и Vivado.\n    *   **Слот PCIe**: Как обсуждалось в разделе 3.2, убедитесь, что в вашей хост-системе есть доступный и совместимый слот PCIe для вашей DMA-карты.\n    *   **USB-порт**: Для подключения JTAG-программатора и, возможно, для UART/последовательной консоли к вашей плате FPGA для вывода отладочной информации.\n\n---\n\n## **4. Требования**\n\nВ этом разделе излагаются основные аппаратные и программные компоненты, а также рекомендуемая настройка среды, необходимые для начала разработки пользовательской прошивки для эмуляции устройств PCIe. Наличие этих предварительных условий до начала работы значительно упростит процесс разработки.\n\n### **4.1. Аппаратное обеспечение**\n\n*   **Устройство-донор PCIe**\n    *   **Назначение**: Это физическое аппаратное устройство, конфигурацию и поведение которого вы собираетесь эмулировать на вашей FPGA. Оно служит авторитетным источником для получения критических идентификационных данных, значений регистров и рабочих характеристик.\n    *   **Примеры**: Распространенные примеры включают стандартную сетевую карту (NIC), контроллер хранения SATA или NVMe, контроллер USB или любую другую стандартную карту расширения PCIe, которую вы можете безопасно извлечь из системы для анализа. Настоятельно рекомендуется использовать устройство, которое *не* является необходимым для работы системы, так как вы будете проверять его низкоуровневую конфигурацию.\n*   **Плата ПЛИС для ПДП (DMA FPGA Card)**\n    *   **Описание**: Плата разработки на базе FPGA, специально разработанная или адаптированная для выполнения операций прямого доступа к памяти (DMA) через интерфейс PCIe. Это платформа, на которую будет загружена ваша пользовательская прошивка.\n    *   **Примеры**: Как подробно описано в разделе 3.1, совместимые карты включают **Squirrel (Artix-7 35T)**, **Enigma-X1 (Artix-7 75T)**, **ZDMA (Artix-7 100T)** или различные решения на базе **Kintex-7**. Убедитесь, что выбранная вами карта имеет краевой разъем PCIe.\n*   **JTAG-программатор**\n    *   **Назначение**: Этот важный инструмент облегчает связь между вашим компьютером для разработки и FPGA на вашей DMA-карте. Он используется для программирования (прошивки) скомпилированного битстрима на FPGA и, что важно, для интерактивной отладки с использованием таких инструментов, как Hardware Manager Vivado и встроенный логический анализатор (ILA).\n    *   **Примеры**:\n        *   **Xilinx Platform Cable USB II**: Традиционный, широко совместимый программатор для FPGA Xilinx. Убедитесь, что у вас установлены необходимые драйверы.\n        *   **Digilent JTAG-HS3 / JTAG-HS2**: Популярные и надежные программаторы, известные хорошей интеграцией с Vivado и поддержкой. HS3 предлагает более высокие скорости программирования.\n        *   **Встроенный JTAG**: Некоторые платы FPGA могут иметь встроенный мост USB-в-JTAG (например, чип FTDI), что устраняет необходимость в отдельном программаторе. Обратитесь к документации вашей платы.\n\n### **4.2. Программное обеспечение**\n\n*   **Xilinx Vivado Design Suite**\n    *   **Описание**: Официальная, всеобъемлющая среда разработки FPGA от Xilinx (теперь AMD). Vivado необходим для синтеза вашего HDL-кода, реализации проекта на целевой FPGA, генерации окончательного битстрима и выполнения аппаратной отладки. Он включает необходимые IP-ядра, компиляторы и утилиты.\n    *   **Загрузка**: Посетите официальную страницу загрузок Xilinx (AMD): [https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html).\n    *   **Примечание о версии**: Хотя в некоторых устаревших руководствах могут упоминаться старые версии, такие как Vivado 2020.1, настоятельно рекомендуется загрузить **последнюю стабильную версию** (например, Vivado 2023.x или новее), совместимую с вашим целевым семейством FPGA (Artix-7, Kintex-7). Проект PCILeech-FPGA обычно поддерживает более новые версии Vivado.\n*   **Visual Studio Code**\n    *   **Описание**: Высоко настраиваемый и многофункциональный редактор кода от Microsoft. Это отличный выбор для написания и редактирования вашего HDL-кода на Verilog/SystemVerilog благодаря его обширной экосистеме расширений, предлагающей такие функции, как подсветка синтаксиса, линтинг, автодополнение и интеграция с системой контроля версий.\n    *   **Загрузка**: [https://code.visualstudio.com/](https://code.visualstudio.com/)\n*   **PCILeech-FPGA**\n    *   **Описание**: Проект с открытым исходным кодом и базовая кодовая база для разработки DMA на базе FPGA. Он предоставляет готовые к использованию экземпляры IP-ядер PCIe и хорошо структурированный проект, который служит отличной отправной точкой для пользовательской прошивки. Это руководство активно использует его архитектуру.\n    *   **Репозиторий**: [https://github.com/ufrisk/pcileech-fpga](https://github.com/ufrisk/pcileech-fpga)\n*   **Arbor (MindShare)**\n    *   **Описание**: Мощный и удобный программный инструмент, специально разработанный для глубокого сканирования и анализа устройств PCIe. Он предоставляет подробную информацию о пространстве конфигурации, возможностях и регистрах подключенного оборудования PCIe, что делает его бесценным для сбора информации об устройстве-доноре.\n    *   **Загрузка**: Доступно на веб-сайте MindShare: [https://www.mindshare.com/](https://www.mindshare.com/) (Вам, вероятно, потребуется перейти в раздел программного обеспечения).\n    *   **Примечание**: Обычно требуется создание учетной записи и может предлагаться ограниченная по времени пробная версия.\n*   **Альтернативные инструменты анализа устройств PCIe**\n    *   **Telescan PE (Teledyne LeCroy)**:\n        *   **Описание**: Бесплатная утилита от Teledyne LeCroy для анализа трафика PCIe и перечисления устройств. Хотя это в первую очередь программный инструмент, который взаимодействует с их аппаратными анализаторами протоколов, он также может предоставлять некоторые базовые представления пространства конфигурации без специального оборудования.\n        *   **Загрузка**: [https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software)\n        *   **Примечание**: Требуется ручная регистрация и одобрение для загрузки.\n    *   **Собственные инструменты ОС (для базовых проверок)**:\n        *   **Диспетчер устройств Windows**: Предоставляет базовую информацию о Vendor ID, Device ID, Subsystem ID и Class Code на вкладке \"Сведения\" в свойствах устройства.\n        *   **Утилита `lspci` Linux**: Мощный инструмент командной строки для проверки устройств PCIe. Используйте `lspci -nn` для Vendor/Device ID, `lspci -vvv` для подробных сведений, включая BARы и возможности, и `lspci -s <BUS:DEV.FUN> -xxxx` для дампов необработанного пространства конфигурации.\n\n### **4.3. Настройка среды**\n\nЧистая и правильно настроенная среда разработки имеет решающее значение для предотвращения распространенных ловушек и обеспечения бесперебойного рабочего процесса.\n\n#### **4.3.1. Установка Xilinx Vivado Design Suite**\n\n**Шаги**:\n1.  **Посетите страницу загрузки Vivado Xilinx (AMD)**: [https://www.xilinx.com/support/download.html](https://www.xilinx.com/support/download.html).\n2.  **Загрузите соответствующую версию**: Выберите последнюю стабильную версию Vivado, которая совместима с вашей операционной системой и, что важно, с вашим конкретным устройством FPGA (например, Artix-7, Kintex-7). Проверьте примечания к выпуску Vivado на предмет поддержки устройств.\n3.  **Запустите установщик**: Запустите загруженный установщик и внимательно следуйте инструкциям на экране.\n4.  **Выберите необходимые компоненты**: Во время установки вам будет предложено выбрать, какие семейства устройств установить. **Критически важно выбрать семейство устройств, соответствующее вашей плате FPGA (например, \"7 Series\" для Artix-7/Kintex-7).** Это значительно экономит место на диске по сравнению с установкой всех семейств. Убедитесь, что вы выбрали компоненты \"Design Tools\" (Synthesis, Implementation) и \"Programming & Debugging\".\n5.  **Запустите Vivado**: После установки запустите Vivado, чтобы убедиться, что он открывается без ошибок и что лицензии (если применимо) настроены правильно.\n\n#### **4.3.2. Установка Visual Studio Code**\n\n**Шаги**:\n1.  **Посетите страницу загрузки Visual Studio Code**: [https://code.visualstudio.com/](https://code.visualstudio.com/).\n2.  **Загрузка и установка**: Загрузите установщик для вашей операционной системы и следуйте стандартным инструкциям по установке.\n3.  **Установка расширений для поддержки HDL**: После установки VS Code откройте его и перейдите в представление расширений (Ctrl+Shift+X или Cmd+Shift+X). Найдите и установите соответствующие расширения для Verilog/SystemVerilog, такие как:\n    *   **Verilog-HDL/SystemVerilog** (от mshr-h)\n    *   **VHDL** (если вы также работаете с VHDL)\n    Эти расширения обеспечивают подсветку синтаксиса, линтинг и другие полезные функции.\n\n#### **4.3.3. Клонирование репозитория PCILeech-FPGA**\n\nЭтот репозиторий содержит базовую структуру прошивки и скрипты, которые вы будете изменять.\n\n**Шаги**:\n1.  **Откройте терминал или командную строку**: (например, Git Bash в Windows, Terminal в Linux).\n2.  **Перейдите в желаемый каталог**: Выберите место, где вы хотите хранить свои проекты.\n    ```bash\n    cd ~/Projects/ # В Linux/macOS\n    cd C:\\Users\\YourUsername\\Documents\\Projects\\ # В Windows\n    ```\n3.  **Клонируйте репозиторий**:\n    ```bash\n    git clone https://github.com/ufrisk/pcileech-fpga.git\n    ```\n4.  **Перейдите в клонированный каталог**:\n    ```bash\n    cd pcileech-fpga\n    ```\n    Это будет ваш основной каталог проекта. Проект PCILeech-FPGA часто содержит подкаталоги для различных вариантов плат (например, `pcileech-artix-7-50t`, `pcileech-squirrel-35t`). Вам нужно будет перейти в соответствующий подкаталог, специфичный для вашей платы.\n\n#### **4.3.4. Настройка чистой среды разработки**\n\n**Рекомендация**: Всегда работайте в изолированной или выделенной среде, особенно при работе с низкоуровневым оборудованием и потенциальными последствиями для безопасности.\n\n**Шаги**:\n1.  **Используйте выделенную машину для разработки или виртуальную машину**:\n    *   **Физическая машина**: Если возможно, используйте отдельный физический компьютер для разработки и тестирования FPGA. Это предотвращает случайную нестабильность системы или риски безопасности на вашей основной машине.\n    *   **Виртуальная машина (ВМ)**: ВМ может быть хорошим вариантом для изоляции среды разработки. Однако прямой сквозной проброс PCIe (PCIe Hotplug или VT-d passthrough) в ВМ обычно требуется для правильного обнаружения и работы карты FPGA, что может быть сложно настроить и все еще может представлять риск для хоста, если не сделано осторожно. Для первоначальной установки инструментов и редактирования кода ВМ вполне подходит.\n2.  **Минимизируйте фоновые приложения**: Убедитесь, что не запущены другие ресурсоемкие приложения, которые могут мешать производительности Vivado во время синтеза и реализации.\n3.  **Отключите конфликтующее программное обеспечение**: Временно отключите любое антивирусное, брандмауэрное или защитное программное обеспечение, которое может мешать низкоуровневому доступу к оборудованию или JTAG-связи во время разработки и тестирования. Не забудьте включить их снова, когда закончите работу.\n\n---\n\n## **5. Сбор информации об устройстве-доноре**\n\nТочная эмуляция устройства зависит от тщательного извлечения и воспроизведения критической информации с устройства-донора. Этот всесторонний сбор данных позволяет вашей FPGA точно имитировать конфигурацию и поведение целевого оборудования по PCIe, обеспечивая совместимость и функциональность при взаимодействии с хост-системой.\n\n### **5.1. Использование Arbor для сканирования устройств PCIe**\n\n**Arbor** — это мощный и удобный инструмент, разработанный для глубокого сканирования устройств PCIe. Он предоставляет подробную информацию о пространстве конфигурации подключенного оборудования, что делает его бесценным ресурсом для извлечения необходимой информации для эмуляции устройства.\n\n#### **5.1.1. Установка Arbor**\n\nЧтобы начать использовать Arbor для сканирования устройств, вы должны сначала установить программное обеспечение на свою систему.\n\n**Шаги:**\n\n1.  **Посетите страницу загрузки Arbor:**\n    *   Перейдите на официальный сайт MindShare ([https://www.mindshare.com/](https://www.mindshare.com/)) с помощью вашего любимого веб-браузера. Вам нужно будет найти раздел \"Software\" или \"Downloads\", чтобы найти Arbor.\n    *   Убедитесь, что вы заходите на сайт напрямую, чтобы избежать вредоносных перенаправлений.\n2.  **Создайте учетную запись (если требуется):**\n    *   Arbor может потребовать от вас создания учетной записи пользователя для доступа к ссылкам для скачивания.\n    *   Предоставьте необходимую информацию, такую как ваше имя, адрес электронной почты и организацию.\n    *   Подтвердите свой адрес электронной почты, если потребуется, для активации вашей учетной записи.\n3.  **Скачайте Arbor:**\n    *   После входа в систему найдите раздел загрузки для Arbor.\n    *   Выберите версию, совместимую с вашей операционной системой (например, Windows 10/11 64-бит).\n    *   Нажмите кнопку **Download** и сохраните установщик в известном месте на вашем компьютере.\n4.  **Установите Arbor:**\n    *   Найдите загруженный файл установщика (например, `ArborSetup.exe`).\n    *   Щелкните правой кнопкой мыши по установщику и выберите **Run as administrator**, чтобы убедиться, что у него есть необходимые разрешения.\n    *   Следуйте инструкциям на экране, чтобы завершить процесс установки.\n        *   Примите лицензионное соглашение.\n        *   Выберите каталог установки.\n        *   Выберите создание ярлыков на рабочем столе, если это необходимо.\n5.  **Проверка установки:**\n    *   По завершении убедитесь, что Arbor отображается в меню \"Пуск\" или на рабочем столе.\n    *   Запустите Arbor, чтобы убедиться, что он открывается без ошибок.\n\n#### **5.1.2. Сканирование устройств PCIe**\n\nПосле установки Arbor вы можете приступить к сканированию вашей системы на наличие подключенных устройств PCIe.\n\n**Шаги:**\n\n1.  **Запустите Arbor:**\n    *   Дважды щелкните по значку Arbor на рабочем столе или найдите его через меню \"Пуск\".\n    *   Если появится запрос контроля учетных записей (UAC), разрешите приложению вносить изменения в ваше устройство.\n2.  **Перейдите на вкладку \"Local System\":**\n    *   В интерфейсе Arbor найдите панель навигации или вкладки.\n    *   Нажмите **Local System** для доступа к инструментам сканирования локальной машины.\n3.  **Сканирование устройств PCIe:**\n    *   Найдите кнопку **Scan** или **Rescan**, обычно расположенную вверху или внизу интерфейса.\n    *   Нажмите **Scan/Rescan**, чтобы начать процесс обнаружения.\n    *   Дождитесь завершения процесса сканирования; это может занять несколько мгновений в зависимости от количества подключенных устройств.\n4.  **Просмотр обнаруженных устройств:**\n    *   После завершения сканирования Arbor отобразит список всех обнаруженных устройств PCIe.\n    *   Устройства обычно перечисляются с их именами, идентификаторами устройств и другой идентификационной информацией.\n\n#### **5.1.3. Идентификация устройства-донора**\n\nИдентификация правильного устройства-донора имеет решающее значение для точной эмуляции.\n\n**Шаги:**\n\n1.  **Найдите ваше устройство-донор в списке:**\n    *   Прокрутите список устройств, обнаруженных Arbor.\n    *   Ищите устройство, соответствующее марке и модели вашего донорского оборудования.\n    *   Устройства могут быть перечислены по именам поставщиков, типам устройств или функциям.\n2.  **Проверьте детали устройства:**\n    *   Нажмите на устройство, чтобы выбрать его.\n    *   Убедитесь, что **Device ID** и **Vendor ID** соответствуют идентификаторам вашего устройства-донора.\n        *   **Совет:** Эти идентификаторы обычно можно найти в документации устройства или на веб-сайте производителя. Для распространенных устройств быстрый поиск в Интернете по запросу \"[Название устройства] Vendor ID Device ID\" часто дает результаты.\n3.  **Просмотр подробной конфигурации:**\n    *   Выбрав устройство, найдите и нажмите на опцию, такую как **View Details** или **Properties**.\n    *   Это откроет подробное представление, показывающее пространство конфигурации и возможности устройства.\n4.  **Перекрестная проверка с физическим оборудованием:**\n    *   Если в списке несколько похожих устройств, перекрестно проверьте **номер слота** или **адрес шины** с физическим слотом, где установлено устройство-донор. Это поможет убедиться, что вы анализируете правильное оборудование.\n\n#### **5.1.4. Захват данных устройства**\n\nИзвлечение подробной информации из устройства-донора необходимо для точной эмуляции.\n\n**Информация для извлечения:**\n\n*   **Device ID (0xXXXX):** 16-битный идентификатор, уникальный для модели устройства.\n*   **Vendor ID (0xYYYY):** 16-битный идентификатор, присвоенный производителю.\n*   **Subsystem ID (0xZZZZ):** Идентифицирует конкретную подсистему или вариант (например, конкретную модель в рамках линейки продуктов).\n*   **Subsystem Vendor ID (0xWWWW):** Идентифицирует поставщика подсистемы (часто совпадает с основным Vendor ID, но может отличаться для OEM-версий).\n*   **Revision ID (0xRR):** Указывает уровень аппаратной ревизии устройства.\n*   **Class Code (0xCCCCCC):** 24-битный код, определяющий основную функцию/тип устройства (например, `0x020000` для контроллера Ethernet, `0x010802` для контроллера NVMe). Это помогает ОС загружать общие драйверы.\n*   **Базовые адресные регистры (BARs):**\n    *   Регистры, определяющие области адресов памяти или ввода-вывода, используемые устройством.\n    *   Включает BAR0 до BAR5, каждый потенциально 32 или 64 бита. Для каждого BAR отметьте его **Тип (Память или Ввод-вывод)**, **Разрядность (32-битный или 64-битный)**, **Размер (например, 256 МБ, 4 КБ)** и **Статус Prefetchable (Да/Нет)**. Это критически важно для отображения памяти.\n*   **Возможности (Capabilities):** Перечисляет поддерживаемые функции и их конфигурации, часто находятся в структуре связанного списка в пространстве конфигурации. Примеры включают:\n    *   **Структура возможностей PCIe**: Скорость канала PCIe (например, Gen2, Gen3), Ширина канала (например, x1, x4), Максимальный размер полезной нагрузки, Максимальный размер запроса на чтение.\n    *   **Структура возможностей MSI/MSI-X**: Информация о прерываниях, генерируемых сообщениями, включая количество поддерживаемых векторов.\n    *   **Структура возможностей управления питанием**: Поддерживаемые состояния питания (D0, D1, D2, D3hot, D3cold).\n*   **Серийный номер устройства (DSN):** 64-битный уникальный идентификатор, если устройство его поддерживает (находится в расширенной возможности \"Device Serial Number\"). Не все устройства реализуют это.\n\n**Шаги:**\n\n1.  **Перейдите на вкладку PCI Config:**\n    *   В подробном представлении устройства найдите и выберите вкладку **PCI Config** или **Configuration Space**. Обычно это представляет собой декодированный вид необработанных регистров пространства конфигурации.\n2.  **Запишите соответствующие детали:**\n    *   Тщательно задокументируйте каждое из требуемых полей, перечисленных выше.\n    *   Используйте скриншоты или скопируйте значения в текстовый файл, выделенную электронную таблицу или структурированный формат документации для точности.\n    *   Убедитесь, что шестнадцатеричные значения записаны правильно, включая префикс `0x`, если он используется.\n3.  **Разверните списки возможностей:**\n    *   Ищите разделы, помеченные как **Capabilities** или **Advanced Features**. Они часто являются кликабельными или расширяются, чтобы показать подразделы.\n    *   Задокументируйте каждую присутствующую возможность и ее соответствующие параметры (например, управление сообщениями MSI, флаги состояния питания, текущие/максимальные настройки канала PCIe).\n4.  **Подробно изучите BARы:**\n    *   В пространстве конфигурации найдите записи для BAR0 до BAR5.\n    *   Для каждого активного BAR отметьте его выделенный размер, является ли он отображаемым на память или I/O, его разрядность (32-битную или 64-битную) и является ли он prefetchable. Эта информация часто четко представлена в графическом интерфейсе Arbor.\n5.  **Сохраните данные для справки:**\n    *   Скомпилируйте всю извлеченную информацию в хорошо организованный документ (например, файл Markdown, файл `.txt` или электронную таблицу Excel).\n    *   Четко пометьте каждый раздел для удобства ссылки при настройке прошивки.\n\n### **5.2. Извлечение и запись атрибутов устройства**\n\nПосле захвата данных крайне важно понять значение каждого атрибута и убедиться, что они были точно задокументированы для успешной эмуляции.\n\n**Убедитесь, что вы точно записали следующее:**\n\n1.  **Device ID:**\n    *   **Назначение:** Уникально идентифицирует конкретную модель устройства PCIe.\n    *   **Использование в эмуляции:** Необходим для корректного распознавания эмулируемого устройства операционной системой хоста и, что крайне важно, для попытки загрузки соответствующего драйвера устройства.\n2.  **Vendor ID:**\n    *   **Назначение:** Идентифицирует производителя устройства PCIe.\n    *   **Использование в эмуляции:** Используется в сочетании с Device ID для формирования уникального идентификатора (`VendorID:DeviceID`), который ОС использует для сопоставления устройства с соответствующим драйвером.\n3.  **Subsystem ID и Subsystem Vendor ID:**\n    *   **Назначение:** Эти необязательные идентификаторы позволяют различать варианты устройства от одного и того же поставщика или OEM-версии, где основной Vendor/Device ID может быть общим.\n    *   **Использование в эмуляции:** Важно для эмуляции устройств с несколькими конфигурациями или тех, которые поставляются OEM-производителем, поскольку драйвер может специально искать эти значения.\n4.  **Revision ID:**\n    *   **Назначение:** Указывает уровень аппаратной ревизии устройства.\n    *   **Использование в эмуляции:** Помогает в идентификации конкретных аппаратных версий, которые могут требовать разных драйверов, прошивок или иметь тонкие поведенческие различия.\n5.  **Class Code:**\n    *   **Назначение:** 24-битный код, который классифицирует общую функцию устройства (например, `0x020000` для контроллера Ethernet, `0x010802` для контроллера NVMe, `0x0C0300` для контроллера USB-хоста). Он состоит из базового класса, подкласса и программного интерфейса.\n    *   **Использование в эмуляции:** Позволяет ОС понять общую функцию устройства и загрузить общий драйвер класса, если специфический драйвер поставщика не найден. Это крайне важно для первоначального распознавания устройства.\n6.  **Базовые адресные регистры (BARs):**\n    *   **Назначение:** Определяют области адресов, отображаемые на память или порты ввода-вывода, которые устройство использует для регистров, внутренних буферов или расширений пространства конфигурации. ОС хоста выделяет физические адреса этим BARам во время перечисления.\n    *   **Использование в эмуляции:** Критически важно для отображения внутренней памяти и регистров эмулируемого устройства в адресное пространство хост-системы. Размер, тип (Память/Ввод-вывод, 32/64-бит) и статус prefetchable для каждого BAR должны точно соответствовать устройству-донору.\n7.  **Возможности (Capabilities):**\n    *   **Назначение:** Перечисляет расширенные функции, поддерживаемые устройством, такие как расширенная отчетность об ошибках, управление питанием, MSI/MSI-X, расширенные возможности PCIe (например, AER, VC/PF) и т.д. Каждая возможность определяется структурой со своими регистрами.\n    *   **Использование в эмуляции:** Необходимы для точного воспроизведения того, как устройство-донор объявляет свои функции и как хост-система взаимодействует с этими функциями (например, механизмы доставки прерываний, переходы состояний питания, отчетность об ошибках).\n8.  **Серийный номер устройства (DSN):**\n    *   **Назначение:** Уникальный 64-битный идентификатор для устройства, обычно необязательная расширенная возможность.\n    *   **Использование в эмуляции:** Хотя это необязательно, некоторые драйверы или приложения управления могут специально запрашивать и полагаться на DSN для идентификации, лицензирования или проверок безопасности. Точная эмуляция этого может предотвратить обнаружение вашего устройства как общего или модифицированного периферийного устройства.\n\n**Лучшие практики сбора данных:**\n\n*   **Организуйте данные:** Создайте структурированный документ или электронную таблицу. Используйте четкие заголовки и подзаголовки для каждого атрибута. Шаблон может быть полезен.\n*   **Включайте единицы измерения и форматы:** Всегда указывайте единицы измерения для размеров (например, МБ, КБ) и используйте последовательное форматирование для шестнадцатеричных значений (например, `0x1234`, `16'h1234`).\n*   **Перекрестная проверка со спецификациями (если возможно):** Если доступны, обратитесь к техническим описаниям устройства-донора или общедоступным спецификациям для проверки значений. Это может помочь выявить любые расхождения или необычные конфигурации, не сразу очевидные из необработанного сканирования.\n*   **Защитите данные:** Храните собранную информацию в безопасности. Помните, что эти данные могут содержать проприетарную или конфиденциальную информацию.\n*   **Поймите \"что отсутствует\":** Специализированные инструменты, такие как Arbor, превосходны, но они могут не охватывать каждую тонкость сложных, высокопроприетарных устройств (например, специфические регистры, определяемые поставщиком, за пределами стандартного пространства конфигурации). Для продвинутой эмуляции вам может потребоваться объединить эту информацию с обратным инжинирингом драйверов устройства-донора.\n\n---\n\n## **6. Начальная настройка прошивки**\n\nПосле того как информация об устройстве-доноре тщательно задокументирована, следующий критически важный этап включает настройку прошивки вашей FPGA для точной эмуляции устройства-донора. Этот процесс начинается с изменения ключевых идентификационных регистров в пространстве конфигурации PCIe и обеспечения правильной интеграции специфических идентификаторов, таких как серийный номер устройства.\n\n### **6.1. Изменение пространства конфигурации**\n\nПространство конфигурации PCIe является фундаментальным компонентом, который определяет, как устройство распознается и взаимодействует с хост-системой во время перечисления. Настройка этого пространства для точного соответствия профилю устройства-донора абсолютно необходима для успешной эмуляции, позволяя ОС хоста загружать правильный драйвер и взаимодействовать, как ожидается.\n\n#### **6.1.1. Переход к файлу конфигурации**\n\nПараметры пространства конфигурации PCIe обычно определяются в определенном файле SystemVerilog (`.sv`) в проекте PCILeech-FPGA. Этот файл синтезируется в логику, которая конфигурирует IP-ядро PCIe и предоставляет идентификационные данные устройства хосту.\n\n**Обычный путь для PCILeech-FPGA (платы на базе Artix-7, такие как Squirrel):**\nНайдите файл, отвечающий за настройку параметров PCIe для вашей конкретной платы. Для многих вариантов PCILeech на базе Artix-7 это будет:\n```\npcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv\n```\n*   **Пример (для Squirrel 35T)**:\n    ```\n    pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv\n    ```\n    *Примечание: Фактическое имя папки, например `pcileech-squirrel-35t`, может немного отличаться в зависимости от конкретной версии PCILeech-FPGA или форка, который вы клонировали. Всегда переходите в соответствующий подкаталог, специфичный для платы, после клонирования основного репозитория.*\n\n#### **6.1.2. Открытие файла в Visual Studio Code**\n\nРедактирование файла конфигурации требует подходящего редактора кода, поддерживающего подсветку синтаксиса для SystemVerilog (или Verilog), что делает код более легким для чтения и модификации.\n\n**Шаги:**\n\n1.  **Запустите Visual Studio Code:**\n    *   Щелкните по значку VS Code или найдите его через меню \"Пуск\".\n2.  **Откройте файл:**\n    *   Используйте **File > Open File** или нажмите `Ctrl + O` (или `Cmd + O` на macOS).\n    *   Перейдите по пути к файлу конфигурации, указанному в разделе 6.1.1 (например, `pcileech-fpga/pcileech-squirrel-35t/src/pcileech_pcie_cfg_a7.sv`).\n    *   Выберите файл и нажмите **Open**.\n3.  **Проверьте подсветку синтаксиса:**\n    *   Убедитесь, что редактор распознает расширение файла `.sv` и применяет правильную подсветку синтаксиса SystemVerilog. Если этого не происходит, пересмотрите раздел 4.3.2, чтобы убедиться, что вы установили рекомендуемые расширения Verilog/SystemVerilog для VS Code.\n4.  **Ознакомьтесь со структурой файла:**\n    *   Прокрутите файл. Вы обычно найдете параметры, определенные с помощью `localparam` или `reg` присвоений, часто с комментариями, объясняющими их назначение. Ищите разделы, где определены и присвоены стандартные регистры конфигурации PCIe (Vendor ID, Device ID и т.д.).\n\n#### **6.1.3. Изменение Device ID и Vendor ID**\n\nОбновление этих фундаментальных идентификаторов является наиболее важным шагом для правильного распознавания эмулируемого устройства хост-системой как вашего донора. Операционная система в значительной степени полагается на пару `Vendor ID` и `Device ID` для идентификации подключенного оборудования и загрузки соответствующего драйвера устройства.\n\n**Шаги:**\n\n1.  **Поиск `cfg_deviceid`:**\n    *   Используйте функцию поиска (`Ctrl + F` или `Cmd + F`) в VS Code.\n    *   Найдите строку, определяющую `cfg_deviceid`. Она обычно выглядит примерно так:\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'hAAAA; // Идентификатор устройства по умолчанию или заполнитель\n        ```\n2.  **Обновление Device ID:**\n    *   Замените `AAAA` на 16-битный шестнадцатеричный Device ID, извлеченный из устройства-донора с помощью Arbor (например, `0x1234`).\n    *   **Пример:**\n        Если Device ID донора `0x1234`, обновите строку следующим образом:\n        ```verilog\n        reg [15:0] cfg_deviceid = 16'h1234; // Обновлен Device ID донора (например, из сетевой карты)\n        ```\n3.  **Поиск `cfg_vendorid`:**\n    *   Найдите строку, определяющую `cfg_vendorid`. Она будет аналогична по формату `cfg_deviceid`:\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hBBBB; // Идентификатор поставщика по умолчанию или заполнитель\n        ```\n4.  **Обновление Vendor ID:**\n    *   Замените `BBBB` на 16-битный шестнадцатеричный Vendor ID, извлеченный из устройства-донора (например, `0xABCD`).\n    *   **Пример:**\n        Если Vendor ID донора `0xABCD`, обновите строку следующим образом:\n        ```verilog\n        reg [15:0] cfg_vendorid = 16'hABCD; // Обновлен Vendor ID донора (например, Intel Corporation)\n        ```\n5.  **Обеспечение правильного форматирования:**\n    *   Убедитесь, что шестнадцатеричные значения правильно предваряются `16'h` (указывает на 16-битное шестнадцатеричное число).\n    *   Поддерживайте последовательный отступ и стиль комментариев для удобочитаемости.\n\n#### **6.1.4. Изменение Subsystem ID и Revision ID**\n\nЭти идентификаторы предоставляют дополнительные сведения о варианте устройства, конкретных моделях продуктов или аппаратных ревизиях. Хотя они часто являются необязательными, их соответствие повышает аутентичность эмуляции и может быть критически важным для драйверов, выполняющих детальные проверки.\n\n**Шаги:**\n\n1.  **Поиск `cfg_subsysid`:**\n    *   Найдите строку, определяющую `cfg_subsysid`.\n    ```verilog\n    reg [15:0] cfg_subsysid = 16'hCCCC; // Заполнитель Subsystem ID\n    ```\n2.  **Обновление Subsystem ID:**\n    *   Замените `CCCC` на 16-битный шестнадцатеричный Subsystem ID из вашего устройства-донора (например, `0x5678`).\n    *   **Пример:**\n        ```verilog\n        reg [15:0] cfg_subsysid = 16'h5678; // Установлен Subsystem ID донора\n        ```\n3.  **Поиск `cfg_subsysvendorid`:**\n    *   Найдите строку, определяющую `cfg_subsysvendorid`.\n    ```verilog\n    reg [15:0] cfg_subsysvendorid = 16'hDDDD; // Заполнитель Subsystem Vendor ID\n    ```\n4.  **Обновление Subsystem Vendor ID (если применимо):**\n    *   Замените `DDDD` на 16-битный шестнадцатеричный Subsystem Vendor ID из вашего устройства-донора (например, `0x9ABC`). Если ваше устройство-донор не имеет уникального Subsystem Vendor ID (т.е. он такой же, как и основной Vendor ID), вы все равно должны установить его на это значение.\n    *   **Пример:**\n        ```verilog\n        reg [15:0] cfg_subsysvendorid = 16'h9ABC; // Установлен Subsystem Vendor ID донора\n        ```\n5.  **Поиск `cfg_revisionid`:**\n    *   Найдите строку, определяющую `cfg_revisionid`.\n    ```verilog\n    reg [7:0] cfg_revisionid = 8'hEE; // Заполнитель Revision ID\n    ```\n6.  **Обновление Revision ID:**\n    *   Замените `EE` на 8-битный шестнадцатеричный Revision ID из вашего устройства-донора (например, `0x01`).\n    *   **Пример:**\n        ```verilog\n        reg [7:0] cfg_revisionid = 8'h01; // Установлен Revision ID донора\n        ```\n\n#### **6.1.5. Обновление Class Code**\n\nClass Code информирует операционную систему хоста об общем типе и функции устройства (например, сетевой контроллер, устройство хранения данных). Это жизненно важно для ОС, чтобы загрузить общие драйверы класса, даже если специфический драйвер поставщика не установлен.\n\n**Шаги:**\n\n1.  **Поиск `cfg_classcode`:**\n    *   Найдите строку, определяющую `cfg_classcode`.\n    ```verilog\n    reg [23:0] cfg_classcode = 24'hFFFFFF; // Код класса по умолчанию или заполнитель\n    ```\n2.  **Обновление Class Code:**\n    *   Замените `FFFFFF` на 24-битный шестнадцатеричный Class Code, который вы извлекли из устройства-донора (например, `0x020000` для контроллера Ethernet). Помните формат: Базовый класс, Подкласс, Интерфейс программирования.\n    *   **Пример:**\n        Если Class Code донора `0x020000` (что означает Базовый класс: 0x02 - Сетевой контроллер, Подкласс: 0x00 - Контроллер Ethernet, Prog IF: 0x00), обновите следующим образом:\n        ```verilog\n        reg [23:0] cfg_classcode = 24'h020000; // Установлен Class Code донора (например, контроллер Ethernet)\n        ```\n3.  **Проверка правильной разрядности:**\n    *   Убедитесь, что Class Code правильно представлен как 24-битное значение с использованием префикса `24'h` для шестнадцатеричных значений.\n\n#### **6.1.6. Сохранение изменений**\n\nПосле внесения всех изменений в параметры конфигурации крайне важно сохранить и просмотреть их.\n\n**Шаги:**\n\n1.  **Сохраните файл:**\n    *   Нажмите **File > Save** в VS Code или нажмите `Ctrl + S` (или `Cmd + S`).\n2.  **Просмотрите изменения:**\n    *   Перед закрытием быстро перечитайте измененные строки, чтобы подтвердить их точность по сравнению с задокументированной информацией об устройстве-доноре.\n    *   Проверьте наличие очевидных синтаксических ошибок или опечаток (расширения VS Code могут их подсветить).\n3.  **Опционально - Использование контроля версий:**\n    *   Если вы используете Git (настоятельно рекомендуется для любого проекта кода, особенно прошивки), зафиксируйте свои изменения с четким и значимым сообщением. Это создает историческую запись ваших модификаций.\n    *   **Пример команд Git:**\n        ```bash\n        git add pcileech_pcie_cfg_a7.sv\n        git commit -m \"Обновлены регистры конфигурации PCIe (VID, DID, SubIDs, Revision, Class Code) в соответствии с устройством-донором: [Название устройства-донора]\"\n        ```\n\n### **6.2. Вставка серийного номера устройства (DSN)**\n\nСерийный номер устройства (DSN) — это уникальный 64-битный идентификатор, который могут использовать некоторые устройства PCIe (особенно те, которые имеют расширенные функции или специальные драйверы). Включение его повышает аутентичность вашей эмуляции и может помочь обойти проверки в драйверах, которые явно запрашивают это значение.\n\n#### **6.2.1. Определение поля DSN**\n\nDSN, если реализован устройством-донором, является частью расширенных возможностей PCIe. В рамках PCILeech-FPGA поле DSN часто представлено как настраиваемый параметр в том же файле конфигурации, который вы редактировали.\n\n**Шаги:**\n\n1.  **Поиск `cfg_dsn`:**\n    *   В `pcileech_pcie_cfg_a7.sv` (или эквивалентном файле конфигурации вашей платы) используйте функцию поиска (`Ctrl + F` или `Cmd + F`), чтобы найти `cfg_dsn`.\n2.  **Понимание существующего назначения:**\n    *   DSN может быть установлен в значение по умолчанию (часто все нули) или закомментирован. Обычно он выглядит примерно так:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // DSN по умолчанию (обычно 0, если не используется)\n        ```\n\n#### **6.2.2. Вставка DSN**\n\nОбновление DSN включает установку его точного 64-битного шестнадцатеричного значения, полученного с вашего устройства-донора.\n\n**Шаги:**\n\n1.  **Обновление `cfg_dsn`:**\n    *   Замените существующее шестнадцатеричное значение 64-битным DSN, который вы извлекли из устройства-донора с помощью Arbor.\n    *   **Пример:**\n        Если DSN донора `0x0011223344556677`, обновите следующим образом:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0011223344556677; // Серийный номер устройства-донора\n        ```\n2.  **Обработка недоступности или неактуальности DSN:**\n    *   Если ваше устройство-донор *не* имеет DSN, или если вы определили, что это не обязательный параметр для драйвера, на который вы ориентируетесь, вы можете просто оставить его нулями:\n        ```verilog\n        reg [63:0] cfg_dsn = 64'h0000000000000000; // DSN не указан донором, оставлено значение по умолчанию 0\n        ```\n    *   **Внимание**: Для критически важных эмуляций, если устройство-донор имеет DSN, лучше эмулировать его точно.\n3.  **Обеспечение правильного форматирования:**\n    *   DSN — это 64-битное значение; убедитесь, что оно правильно отформатировано с префиксом `64'h` для шестнадцатеричных значений.\n\n#### **6.2.3. Сохранение изменений**\n\nЗавершите модификацию DSN, сохранив и просмотрев файл.\n\n**Шаги:**\n\n1.  **Сохраните файл:**\n    *   Нажмите **File > Save** в VS Code или нажмите `Ctrl + S`.\n2.  **Проверьте синтаксис:**\n    *   Проверьте наличие красных подчеркиваний или индикаторов ошибок от синтаксического анализатора VS Code. Немедленно исправьте любые проблемы.\n3.  **Задокументируйте изменения:**\n    *   Если используется контроль версий, зафиксируйте обновления с соответствующим сообщением.\n    *   **Пример команд Git:**\n        ```bash\n        git commit -am \"Вставлен серийный номер устройства (DSN) донора в конфигурацию PCIe\"\n        ```\n\n---\n\n## **7. Настройка проекта Vivado**\n\nПосле обновления файлов прошивки для отражения критически важных идентификационных и конфигурационных данных устройства-донора, следующим важным шагом является интеграция этих изменений в проект Vivado. Это включает генерацию файлов проекта для вашей конкретной платы FPGA, настройку встроенного IP-ядра PCIe и подготовку всего проекта к этапам синтеза и реализации.\n\n### **7.1. Генерация файлов проекта Vivado**\n\nVivado, пакет разработки Xilinx (AMD), использует скрипты Tcl (Tool Command Language) для автоматизации создания проектов, добавления исходных файлов и настройки параметров проекта. Запуская эти скрипты, предоставленные с фреймворком PCILeech-FPGA, вы гарантируете, что ваш проект Vivado правильно настроен для вашей целевой платы FPGA.\n\n#### **7.1.1. Открытие Vivado**\n\nЗапуск новой сессии Vivado гарантирует, что никакие оставшиеся настройки или открытые проекты из предыдущих сессий не будут мешать вашей текущей работе.\n\n**Шаги:**\n\n1.  **Запустите Vivado:**\n    *   Найдите значок приложения Vivado в меню \"Пуск\" (Windows) или папке \"Приложения\" (Linux/macOS).\n    *   Щелкните, чтобы открыть его.\n2.  **Выберите правильную версию:**\n    *   Если у вас установлено несколько версий Vivado, убедитесь, что вы запускаете ту, которая совместима с вашей платой FPGA и проектом PCILeech-FPGA (как отмечено в разделе 4.3.1, рекомендуется использовать последнюю стабильную версию, такую как Vivado 2023.x).\n3.  **Дождитесь экрана запуска:**\n    *   Дождитесь полной инициализации Vivado и появления приветственного экрана или панели управления проектами, прежде чем продолжить.\n\n#### **7.1.2. Доступ к консоли Tcl**\n\nКонсоль Tcl в Vivado — это ваш основной интерфейс для выполнения скриптов и прямых команд. Здесь вы будете запускать скрипты генерации проекта.\n\n**Шаги:**\n\n1.  **Откройте консоль Tcl:**\n    *   В интерфейсе Vivado перейдите в строку меню.\n    *   Нажмите **Window** > **Tcl Console**.\n    *   Панель Tcl Console обычно появляется в нижней части окна Vivado.\n2.  **Изменение размера консоли (необязательно):**\n    *   Вы можете перетащить верхнюю границу консоли, чтобы изменить ее размер, сделав ее выше для лучшей видимости команд и вывода.\n3.  **Очистка предыдущих команд (необязательно, но рекомендуется):**\n    *   Если есть какие-либо предыдущие команды или сообщения, вы можете щелкнуть правой кнопкой мыши внутри консоли и выбрать \"Clear Console\" для чистого старта.\n\n#### **7.1.3. Переход в каталог проекта**\n\nПеред запуском Tcl-скрипта вы должны убедиться, что текущий рабочий каталог Tcl Console установлен в правильное место, где находятся скрипты проекта PCILeech-FPGA, специфичные для вашей платы.\n\n**Для Squirrel DMA (Artix-7 35T) или аналогичных плат:**\n\n**Типичный путь (после клонирования `pcileech-fpga` и перехода к вашему варианту платы):**\n```\nC:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/  # В Windows\n~/Projects/pcileech-fpga/pcileech-squirrel-35t/  # В Linux/macOS\n```\n*Примечание: Замените `<your_board_variant>` на фактическое имя подкаталога для вашей платы (например, `pcileech-squirrel-35t`, `pcileech-artix-7-50t`).*\n\n**Шаги:**\n\n1.  **Установите рабочий каталог в Tcl Console:**\n    *   В консоли Vivado Tcl введите команду `cd`, за которой следует полный путь к каталогу проекта вашей платы.\n    *   **Пример (Windows):**\n        ```tcl\n        cd C:/Users/YourUsername/Documents/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   **Пример (Linux/macOS):**\n        ```tcl\n        cd ~/Projects/pcileech-fpga/pcileech-squirrel-35t/\n        ```\n    *   *Совет для самокоррекции: Используйте прямые слеши (`/`) даже в Windows для путей Tcl.*\n2.  **Проверьте изменение каталога:**\n    *   Чтобы убедиться, что вы находитесь в правильном каталоге, введите `pwd` (print working directory) в Tcl Console.\n    *   Консоль должна отобразить полный путь, который вы только что установили, подтверждая изменение.\n\n#### **7.1.4. Генерация проекта Vivado**\n\nЗапуск соответствующего Tcl-скрипта, специфичного для вашей платы FPGA, автоматизирует весь процесс настройки проекта в Vivado. Это включает создание проекта, добавление всех необходимых исходных файлов (HDL, ограничения) и настройку основных параметров проекта.\n\n**Шаги:**\n\n1.  **Запустите Tcl-скрипт:**\n    *   Введите команду `source`, за которой следует имя скрипта генерации проекта для вашей платы. Проект PCILeech-FPGA обычно предоставляет эти скрипты в основном каталоге платы.\n    *   **Для Squirrel (Artix-7 35T) (и аналогичных плат Artix-7):**\n        ```tcl\n        source vivado_generate_project_squirrel.tcl -notrace\n        ```\n    *   **Для Enigma-X1 (Artix-7 75T):**\n        ```tcl\n        source vivado_generate_project_enigma_x1.tcl -notrace\n        ```\n    *   **Для ZDMA (Artix-7 100T):**\n        ```tcl\n        source vivado_generate_project_100t.tcl -notrace\n        ```\n    *   Опция `-notrace` предотвращает подробный вывод для каждой команды Tcl, сохраняя консоль более чистой.\n2.  **Дождитесь завершения скрипта:**\n    *   Скрипт будет выполнять множество команд последовательно. Этот процесс может занять несколько минут, в зависимости от производительности вашей системы и сложности проекта.\n    *   Следите за сообщениями о ходе выполнения в Tcl Console. Скрипт будет:\n        *   Создавать новый проект Vivado (файл `.xpr`) в вашем текущем каталоге.\n        *   Добавлять все исходные файлы SystemVerilog/Verilog (`.sv`, `.v`).\n        *   Добавлять конфигурации IP-ядер Xilinx (`.xci`).\n        *   Добавлять файлы XDC (Xilinx Design Constraints).\n        *   Потенциально настраивать различные параметры проекта.\n    *   **Устранение любых ошибок**: Если возникают какие-либо ошибки (например, \"file not found,\" \"invalid command\"), скрипт обычно останавливается. Просмотрите сообщение об ошибке, исправьте основную проблему (например, неверный путь, отсутствующий файл) и перезапустите скрипт.\n3.  **Подтвердите генерацию проекта:**\n    *   После успешного завершения Tcl Console обычно указывает, что проект создан, и вы должны увидеть новые файлы проекта (например, `pcileech_squirrel_top.xpr`) и связанные каталоги (например, `pcileech_squirrel_top.runs`, `pcileech_squirrel_top.ip`), сгенерированные в вашем каталоге проекта.\n\n#### **7.1.5. Открытие сгенерированного проекта**\n\nТеперь, когда файлы проекта Vivado были успешно сгенерированы Tcl-скриптом, вы можете открыть проект в графическом интерфейсе Vivado для дальнейшего изучения и настройки.\n\n**Шаги:**\n\n1.  **Откройте проект:**\n    *   В Vivado нажмите **File** > **Open Project**.\n    *   Перейдите в каталог вашего проекта (тот же, который вы установили в Tcl Console в разделе 7.1.3).\n2.  **Выберите файл проекта:**\n    *   Найдите и выберите файл проекта Vivado (расширение `.xpr`), который соответствует вашей плате.\n    *   **Для Squirrel:** Файл обычно будет называться `pcileech_squirrel_top.xpr`.\n    *   Нажмите на файл `.xpr`, чтобы выбрать его.\n3.  **Нажмите Открыть:**\n    *   Vivado загрузит проект, отображая иерархию проекта, исходные файлы, блочный дизайн IP Integrator (если используется) и различные представления дизайна. Это может занять некоторое время.\n4.  **Проверьте содержимое проекта:**\n    *   В окне **Project Manager** (обычно слева) разверните панель **Sources**.\n    *   Убедитесь, что все ожидаемые исходные файлы (Verilog/SystemVerilog, XDC, IP-ядра) перечислены и что иерархия проекта выглядит правильно.\n    *   Проверьте панель **Messages** (внизу) на наличие любых предупреждений или критических предупреждений, которые появляются при открытии проекта, так как они могут указывать на потенциальные проблемы.\n\n### **7.2. Изменение IP-блоков**\n\nIP-ядро PCIe является сердцем интерфейса PCIe вашего устройства. Это предварительно проверенный, настраиваемый блок от Xilinx, который обрабатывает сложные уровни протокола PCIe. Хотя некоторые значения пространства конфигурации обрабатываются в файле SystemVerilog (Раздел 6.1), другие основные параметры PCIe, особенно те, что связаны с возможностями канала и структурами BAR, настраиваются непосредственно в параметрах настройки IP-ядра PCIe в Vivado. Настройка IP-ядра гарантирует, что ваша FPGA ведет себя идентично донорскому оборудованию на уровне протокола PCIe.\n\n#### **7.2.1. Доступ к IP-ядру PCIe**\n\nIP-ядро PCIe является экземпляром IP-блока в вашем проекте Vivado. Вам нужно будет открыть его графический интерфейс настройки, чтобы изменить его параметры.\n\n**Шаги:**\n\n1.  **Найдите IP-ядро PCIe:**\n    *   На панели **Sources** (в окне **Project Manager**) убедитесь, что выбрана вкладка **Hierarchy**.\n    *   Разверните иерархию проекта, пока не найдете экземпляр IP-ядра PCIe.\n    *   Обычно он называется `pcie_7x_0.xci` (для FPGA 7-й серии) или аналогично, и находится в подкаталоге `ip` исходных файлов вашего проекта.\n2.  **Откройте окно настройки IP:**\n    *   **Щелкните правой кнопкой мыши** по файлу `pcie_7x_0.xci`.\n    *   В контекстном меню выберите **Customize IP**.\n    *   Откроется окно **IP Configuration** (или аналогичное название, например \"Customize IP\" или \"Re-customize IP\"), представляющее графический интерфейс с различными вкладками и опциями для настройки IP-ядра PCIe.\n3.  **Дождитесь загрузки настроек IP:**\n    *   Интерфейс настройки IP может занять несколько мгновений для инициализации и заполнения всех своих настроек. Убедитесь, что все опции и вкладки полностью загружены и реагируют, прежде чем вы начнете вносить изменения.\n\n#### **7.2.2. Настройка идентификаторов устройств и BAR в IP-ядре**\n\nХотя некоторые идентификаторы устройств устанавливаются в `pcileech_pcie_cfg_a7.sv`, само IP-ядро PCIe также содержит внутренние параметры для Device ID, Vendor ID и, что важно, определения для базовых адресных регистров (BAR). Вы должны убедиться, что они совпадают. Некоторые значения, установленные в файле `.sv`, могут переопределять или передаваться в IP-ядро, но рекомендуется обеспечить согласованность и здесь. Настройки BAR в IP-ядре особенно важны, так как они определяют аппаратную реализацию отображения памяти.\n\n**Шаги:**\n\n1.  **Перейдите к базовым/идентификационным параметрам:**\n    *   В окне настройки IP найдите вкладку или раздел, относящийся к **Basic**, **Device and Vendor Identifiers**, **General** или **PCIe Capabilities**. Здесь определяются основные идентификаторы и начальные настройки канала.\n2.  **Проверьте/введите Device ID, Vendor ID, Subsystem ID, Revision ID, Class Code:**\n    *   **Критически важно убедиться, что они соответствуют значениям, которые вы ввели в `pcileech_pcie_cfg_a7.sv` и которые вы получили от устройства-донора.**\n    *   Найдите поля, такие как:\n        *   **Device ID**: Введите `0xXXXX` (например, `0x1234`).\n        *   **Vendor ID**: Введите `0xYYYY` (например, `0xABCD`).\n        *   **Subsystem ID**: Введите `0xZZZZ` (например, `0x5678`).\n        *   **Subsystem Vendor ID**: Введите `0xWWWW` (например, `0x9ABC`).\n        *   **Revision ID**: Введите `0xRR` (например, `0x01`).\n        *   **Class Code**: Введите `0xCCCCCC` (например, `0x020000`).\n    *   **Важно**: Некоторые версии IP-ядра или конкретные конфигурации могут получать эти данные непосредственно из пользовательской логики (например, `pcileech_pcie_cfg_a7.00`), или могут позволять устанавливать их непосредственно здесь. Наиболее надежный подход — устанавливать их согласованно в обоих местах, если эта опция доступна в графическом интерфейсе IP.\n3.  **Перейдите на вкладку базовых адресных регистров (BARs):**\n    *   В окне настройки IP найдите и выберите вкладку или раздел **BARs**. Здесь вы определяете области памяти, которые предоставляет устройство PCIe.\n4.  **Настройте каждый BAR:**\n    *   Для каждого BAR (BAR0 до BAR5), который использует ваше устройство-донор, тщательно настройте следующие параметры на основе информации, извлеченной с помощью Arbor:\n        *   **Enable BAR**: Установите этот флажок только в том случае, если устройство-донор использует этот конкретный BAR. Отключите (снимите флажок) любые BARы, которые устройство-донор не использует.\n        *   **BAR Size**: Выберите точный размер из выпадающего списка (например, **256 МБ**, **64 КБ**, **4 КБ**). Это критически важно для того, чтобы ОС хоста выделила правильный объем памяти.\n        *   **BAR Type**: Выберите соответствующий тип:\n            *   **Memory (32-bit Addressing)**: Для областей, отображаемых на память, доступных по 32-битным адресам.\n            *   **Memory (64-bit Addressing)**: Для областей, отображаемых на память, которые могут располагаться в любом месте 64-битного адресного пространства (требуется для больших областей памяти или если устройство-донор использует это).\n            *   **I/O**: Для устаревших областей портов ввода-вывода (менее распространены в современных PCIe, но все еще возможны).\n        *   **Prefetchable**: Установите этот флажок, если BAR донора помечен как prefetchable. Это свойство позволяет хост-системе кэшировать или предвыбирать данные из этой области для повышения производительности.\n    *   **Пример конфигурации (на основе вашего устройства-донора):**\n        *   **BAR0**:\n            *   Включено: Да\n            *   Размер: **256 МБ**\n            *   Тип: **Memory (64-bit Addressing)**\n            *   Предвыбираемое: Да\n        *   **BAR1**:\n            *   Включено: Нет (если устройство-донор не использует BAR1)\n        *   *Продолжайте для BAR2-BAR5, зеркально отображая конфигурацию устройства-донора.*\n5.  **Обеспечьте выравнивание и отсутствие перекрывающихся пространств**:\n    *   IP-ядро Vivado обычно автоматически обрабатывает выравнивание на основе выбранного вами размера. Однако имейте в виду, что спецификация PCIe требует, чтобы размеры BAR были степенью двойки, и BARы должны быть выровнены по их размеру.\n    *   Убедитесь, что общая память, отображаемая вашими BAR, не превышает доступную блочную память (BRAM) или возможности внешней памяти FPGA.\n\n#### **7.2.3. Завершение настройки IP**\n\nПосле настройки всех необходимых параметров в окне настройки IP-ядра вы должны применить эти изменения, чтобы они вступили в силу в вашем проекте Vivado.\n\n**Шаги:**\n\n1.  **Просмотрите все настройки:**\n    *   Перед применением уделите немного времени, чтобы еще раз быстро просмотреть каждую вкладку в окне настройки IP.\n    *   Убедитесь, что все записи точно соответствуют задокументированным спецификациям вашего устройства-донора. Небольшая ошибка здесь может привести к проблемам с обнаружением устройства или функциональностью.\n2.  **Примените изменения:**\n    *   Нажмите кнопку **OK** или **Generate** (метка может варьироваться) в нижней части окна настройки IP.\n    *   Если Vivado предложит вам подтвердить, что вы хотите продолжить изменения и регенерировать выходные продукты IP, подтвердите, нажав **Yes**.\n3.  **Регенерация IP-ядра:**\n    *   Vivado теперь регенерирует выходные продукты IP-ядра (например, списки соединений, модели симуляции, новые файлы конфигурации `.xci`), чтобы отразить ваши новые конфигурации.\n    *   Следите за панелью **Messages** (внизу окна Vivado) на наличие любых ошибок, предупреждений или критических предупреждений, которые могут возникнуть во время этого процесса регенерации. Немедленно устраняйте любые критические предупреждения.\n4.  **Обновление IP в проекте:**\n    *   Vivado может автоматически обновить или предложить вам обновить любые IP-зависимости в вашем проекте после регенерации ядра. Разрешите это, чтобы убедиться, что последняя конфигурация используется во всем вашем проекте.\n\n#### **7.2.4. Блокировка IP-ядра**\n\nБлокировка IP-ядра — это рекомендуемая лучшая практика в Vivado для предотвращения непреднамеренных модификаций или повторных настроек во время последующих запусков синтеза и реализации, что потенциально может отменить ваши тщательно настроенные параметры.\n\n**Назначение блокировки:**\n\n*   **Предотвращение перезаписи:** Гарантирует, что ваши ручные конфигурации в графическом интерфейсе IP-ядра сохраняются и не перезаписываются случайно автоматизацией Vivado или если IP обнаруживается как \"устаревший\" из-за тонких изменений проекта.\n*   **Сохранение согласованности:** Поддерживает IP-ядро в известном, стабильном состоянии на протяжении всего процесса сборки, что особенно важно для критически важных компонентов, таких как интерфейс PCIe.\n\n**Шаги:**\n\n1.  **Откройте консоль Tcl:**\n    *   В Vivado, если консоль Tcl еще не открыта, перейдите в **Window** > **Tcl Console**.\n2.  **Выполните команду блокировки:**\n    *   В консоли Tcl введите следующую команду точно. Эта команда устанавливает свойство `IP_LOCKED` в `true` для вашего экземпляра IP-ядра PCIe (`pcie_7x_0`).\n    ```tcl\n    set_property -name {IP_LOCKED} -value true -objects [get_ips pcie_7x_0]\n    ```\n    *   Нажмите **Enter**, чтобы выполнить команду.\n3.  **Проверьте блокировку:**\n    *   Проверьте панель **Messages**. Вы должны увидеть сообщение о подтверждении, указывающее, что свойство было установлено.\n    *   Вы также можете щелкнуть правой кнопкой мыши по `pcie_7x_0.xci` на панели Sources, выбрать \"IP Properties\" и убедиться, что `IP_LOCKED` установлено в `true`. Вы также можете заметить, что опция \"Customize IP\" теперь неактивна или позволяет только \"Re-customize IP\", которая затем предупреждает вас о блокировке.\n4.  **Разблокировка (при необходимости):**\n    *   Если вам потребуется внести дальнейшие изменения в настройки IP-ядра PCIe в будущем, вы должны сначала разблокировать его. Используйте следующую команду Tcl:\n    ```tcl\n    set_property -name {IP_LOCKED} -value false -objects [get_ips pcie_7x_0]\n    ```\n    *   Не забудьте снова заблокировать его после внесения и применения изменений.\n5.  **Задокументируйте действие:**\n    *   Хорошей практикой является отметить в документации вашего проекта (например, в файле README, заметках проекта), что IP-ядро PCIe было заблокировано. Это помогает любому, кто работает над проектом, понять его состояние конфигурации и избежать путаницы.\n\n---\n\n## **Часть 2: Промежуточные концепции и реализация**\n\n---\n\n## **8. Расширенная настройка прошивки**\n\nДля достижения точной и убедительной эмуляции устройства-донора необходима дальнейшая глубокая настройка прошивки FPGA, выходящая за рамки просто базовой идентификации. Это включает согласование параметров PCIe (таких как скорость канала и размеры транзакций), тщательную настройку базовых адресных регистров (BAR) и связанного с ними отображения памяти, а также точную эмуляцию управления питанием и механизмов прерываний. Эти шаги гарантируют, что эмулируемое устройство не только выглядит как оригинальное аппаратное обеспечение для хост-системы, но и ведет себя идентично на протокольном и функциональном уровнях.\n\n### **8.1. Настройка параметров PCIe для эмуляции**\n\nТочная эмуляция требует, чтобы рабочие параметры PCIe вашего FPGA-устройства были тщательно настроены в соответствии с параметрами устройства-донора. Это включает такие настройки, как скорость канала PCIe, ширина канала, указатели возможностей и максимальные размеры полезной нагрузки. Правильная настройка обеспечивает совместимость с хост-системой, корректную работу драйверов и приложений, взаимодействующих с устройством, а также оптимальную производительность для передачи данных.\n\n#### **8.1.1. Согласование скорости и ширины канала PCIe**\n\nСкорость канала PCIe (например, Gen1, Gen2, Gen3) и ширина канала (например, x1, x4, x8) являются критически важными параметрами, которые определяют максимальную теоретическую пропускную способность и производительность устройства. Согласование этих настроек с устройством-донором необходимо для точной эмуляции, поскольку драйверы или системные компоненты могут ожидать определенных возможностей канала.\n\n**Шаги:**\n\n1.  **Доступ к настройкам IP-ядра PCIe:**\n    *   **Откройте ваш проект Vivado:** Запустите Vivado и откройте проект, который вы ранее создали или изменили (например, `pcileech_squirrel_top.xpr`). Убедитесь, что все исходные файлы правильно добавлены в проект.\n    *   **Найдите IP-ядро PCIe:** На панели **Sources** (обычно слева) разверните иерархию проекта, чтобы найти экземпляр IP-ядра PCIe. Для проектов Xilinx 7-й серии (например, Artix-7, используемой в Squirrel) он обычно называется `pcie_7x_0.xci`.\n    *   **Настройте IP-ядро:** Щелкните правой кнопкой мыши по `pcie_7x_0.xci` и выберите **Customize IP**. Откроется окно настройки IP, отображающее различные параметры конфигурации на нескольких вкладках.\n\n2.  **Установите максимальную скорость канала:**\n    *   **Перейдите к параметрам канала:** В окне настройки IP нажмите на вкладку **PCIe Capabilities** (или иногда \"PCIe Configuration\" или \"General\"). Внутри нее найдите раздел, связанный с **Link Parameters** или **Link Capability Register**.\n    *   **Настройте максимальную скорость канала:** Найдите опцию с надписью **Maximum Link Speed** (или \"Target Link Speed\").\n    *   Установите ее в соответствии с максимальной скоростью канала, поддерживаемой и объявленной вашим устройством-донором.\n        *   **Пример:**\n            *   Если устройство-донор работает на **PCIe Gen2 (5.0 GT/s)**, выберите **5.0 GT/s**.\n            *   Если оно работает на **PCIe Gen1 (2.5 GT/s)** или **PCIe Gen3 (8.0 GT/s)**, выберите соответствующую опцию.\n    *   **Примечание**: Убедитесь, что трансиверы вашей FPGA и физическое оборудование (слот PCIe материнской платы) поддерживают выбранную скорость канала. FPGA будет согласовывать только до своей настроенной максимальной скорости.\n\n3.  **Установите ширину канала:**\n    *   **Настройте ширину канала:** В том же разделе **Link Parameters** найдите настройку **Link Width** (или \"PCIe Link Width\", \"Target Link Width\").\n    *   Установите ее в соответствии с максимальной шириной канала, объявленной вашим устройством-донором.\n        *   **Пример:**\n            *   Если устройство-донор использует **x4** канал, установите **Link Width** в **4**.\n            *   Опции обычно включают **1**, **2**, **4**, **8**, **16** линий.\n    *   **Примечание**: Физический слот PCIe и корпус FPGA должны поддерживать выбранную ширину канала. Попытка настроить ширину, превышающую физическое соединение, приведет к проблемам с согласованием канала.\n\n4.  **Сохраните и регенерируйте:**\n    *   **Примените изменения:** После настройки скорости и ширины канала нажмите **OK**, чтобы применить изменения в окне настройки IP.\n    *   **Регенерация выходных продуктов IP:** Vivado, вероятно, предложит вам регенерировать выходные продукты IP-ядра из-за внесенных изменений. Подтвердите и дождитесь завершения процесса регенерации. Это может занять некоторое время.\n    *   **Проверьте настройки:** После завершения регенерации вы можете по желанию снова открыть настройки IP-ядра, чтобы убедиться, что конфигурации применены правильно. Проверьте окно **Messages** в Vivado на наличие предупреждений или ошибок.\n\n#### **8.1.2. Установка указателей возможностей**\n\nУказатели возможностей в пространстве конфигурации PCIe — это 8-битные регистры, образующие связанный список, указывающий на различные структуры возможностей (например, управление питанием, MSI/MSI-X, PCIe Express Capability). Правильная установка этих указателей гарантирует, что хост-система сможет пройти по списку возможностей, найти и использовать объявленные функции устройства.\n\n**Шаги:**\n\n1.  **Найдите указатель возможностей в прошивке:**\n    *   **Откройте файл конфигурации:** В Visual Studio Code откройте основной файл конфигурации для вашей платы, обычно `pcileech_pcie_cfg_a7.sv`, расположенный по адресу `pcileech-fpga/<your_board_variant>/src/pcileech_pcie_cfg_a7.sv`.\n    *   **Поймите указатель возможностей:** Указатель возможностей (`cfg_cap_pointer`) в этом файле указывает на *первую* структуру возможностей в пространстве конфигурации PCIe, обычно начинающуюся после стандартного 64-байтового заголовка конфигурации. Последующие возможности связаны через поля \"Next Capability Pointer\".\n\n2.  **Установите значение указателя возможностей:**\n    *   **Найдите присвоение для `cfg_cap_pointer`:** Найдите строку в коде, где присваивается `cfg_cap_pointer`.\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'hXX; // Текущее значение (например, 8'h40 по умолчанию)\n        ```\n    *   **Обновите указатель возможностей:** Замените `XX` на 8-битное шестнадцатеричное значение указателя возможностей, полученное от вашего устройства-донора с помощью Arbor. Это значение обычно указывает на смещение первой структуры возможностей после пространства конфигурации, специфичного для устройства (которое обычно заканчивается по смещению `0x3F`). Обычная отправная точка для возможностей — `0x40` или `0x60`.\n        *   **Пример:**\n            *   Если первый указатель возможностей устройства-донора равен `0x60` (что означает, что его первая структура возможностей начинается со смещения `0x60` в пространстве конфигурации), обновите строку следующим образом:\n                ```verilog\n                reg [7:0] cfg_cap_pointer = 8'h60; // Обновлено в соответствии со смещением первой возможности донора\n                ```\n    *   **Обеспечьте правильное выравнивание:** Структуры возможностей должны быть выровнены по 4-байтовой границе. Указатель возможностей всегда должен указывать на допустимое 4-байтовое выровненное смещение в пространстве конфигурации.\n\n3.  **Сохраните изменения:**\n    *   **Сохраните файл конфигурации:** После внесения изменений сохраните файл, нажав **File > Save** или `Ctrl + S`.\n    *   **Проверьте синтаксис:** Убедитесь, что изменения не привели к синтаксическим ошибкам (VS Code обычно подсвечивает их).\n    *   **Прокомментируйте для ясности:** Добавьте комментарий, объясняющий изменение, для будущих ссылок и удобства поддержки.\n        ```verilog\n        reg [7:0] cfg_cap_pointer = 8'h60; // Установлен указатель возможностей донора (например, PCIe Cap по 0x60)\n        ```\n\n#### **8.1.3. Настройка максимального размера полезной нагрузки и запроса на чтение**\n\nЭти параметры определяют максимальный объем данных, который может быть передан в одном пакете транспортного уровня PCIe (TLP), и максимальный размер непостированных TLP-запросов на чтение памяти. Согласование этих настроек с устройством-донором обеспечивает совместимость и оптимальную производительность для операций передачи данных. Несоответствия могут привести к снижению пропускной способности или ошибкам связи.\n\n**Шаги:**\n\n1.  **Установите максимально поддерживаемый размер полезной нагрузки (IP-ядро):**\n    *   **Доступ к возможностям устройства:** В окне настройки IP-ядра PCIe (`pcie_7x_0.xci` в Vivado) перейдите на вкладку **PCIe Capabilities**.\n    *   **Настройте Max Payload Size Supported:** Найдите настройку с надписью **Max Payload Size Supported** (или аналогичной).\n    *   Установите ее в значение, поддерживаемое и объявляемое вашим устройством-донором (например, 128 байт, 256 байт, 512 байт, 1024 байта, 2048 байт, 4096 байт).\n        *   **Пример:** Если устройство-донор поддерживает максимальный размер полезной нагрузки **256 байт**, выберите **256 bytes**.\n\n2.  **Установите максимально поддерживаемый размер запроса на чтение (IP-ядро):**\n    *   **Настройте Max Read Request Size Supported:** На той же вкладке найдите настройку **Max Read Request Size Supported**.\n    *   Установите ее в соответствии с возможностями устройства-донора. Это определяет максимальный объем данных, который устройство может запросить в одной транзакции чтения.\n        *   **Пример:** Если донор поддерживает максимальный размер запроса на чтение **512 байт**, выберите **512 bytes**.\n\n3.  **Настройка параметров прошивки (соответствие IP-ядру):**\n    *   **Откройте `pcileech_pcie_cfg_a7.sv`:** Убедитесь, что файл конфигурации открыт в Visual Studio Code.\n    *   **Обновите константы прошивки:** Найдите строки, где определены `max_payload_size_supported` и `max_read_request_size_supported`. Обычно это битовое кодирование значений, которые соответствуют размерам в байтах, выбранным вами в IP-ядре.\n        ```verilog\n        reg [2:0] max_payload_size_supported = 3'bZZZ;   // Текущее значение\n        reg [2:0] max_read_request_size_supported = 3'bWWW; // Текущее значение\n        ```\n    *   **Установите соответствующие значения:** Замените `ZZZ` и `WWW` на 3-битные двоичные представления, соответствующие выбранным размерам.\n        *   **Сопоставление (согласно спецификации PCIe):**\n            *   **128 байт**: `3'b000`\n            *   **256 байт**: `3'b001`\n            *   **512 байт**: `3'b010`\n            *   **1024 байт**: `3'b011`\n            *   **2048 байт**: `3'b100`\n            *   **4096 байт**: `3'b101`\n        *   **Пример:**\n            *   Для размера полезной нагрузки **256 байт**:\n                ```verilog\n                reg [2:0] max_payload_size_supported = 3'b001; // Поддерживает до 256 байт (0x100)\n                ```\n            *   Для размера запроса на чтение **512 байт**:\n                ```verilog\n                reg [2:0] max_read_request_size_supported = 3'b010; // Поддерживает до 512 байт (0x200)\n                ```\n    *   **Обоснование**: Эти параметры прошивки часто определяют поведение вашей пользовательской логики, которая взаимодействует с ядром PCIe, гарантируя, что ваша логика соблюдает настроенные максимумы.\n\n4.  **Сохраните изменения:**\n    *   **Сохраните файл:** После обновления значений в `pcileech_pcie_cfg_a7.sv` сохраните файл.\n    *   **Проверьте согласованность:** Крайне важно, чтобы значения, настроенные в графическом интерфейсе IP-ядра PCIe Vivado, *совпадали* со значениями, установленными в вашем файле конфигурации HDL. Любое несоответствие может привести к неожиданному поведению или проблемам с обучением канала.\n    *   **Добавьте комментарии:** Четко задокументируйте эти изменения в своем коде для будущих ссылок.\n\n### **8.2. Настройка БАР и отображения памяти**\n\nБазовые адресные регистры (BAR) являются фундаментальными для того, как устройство PCIe предоставляет свою внутреннюю память и регистры хост-системе. Правильная настройка BAR и определение их отображения памяти в БПА (блочной памяти) вашей FPGA и логике имеет решающее значение для точной эмуляции и правильной работы драйверов устройств на стороне хоста.\n\n#### **8.2.1. Установка размеров и типов BAR (IP-ядро и BRAM)**\n\nНастройка размеров и типов BAR гарантирует, что ваше эмулируемое устройство запрашивает правильный объем адресного пространства у хоста во время перечисления и что хост выделяет и отображает эти области соответствующим образом. Это также включает связывание этих адресных областей с физическими блоками памяти внутри вашей FPGA.\n\n**Шаги:**\n\n1.  **Доступ к конфигурации BAR (IP-ядро PCIe):**\n    *   **Настройте IP-ядро PCIe:** В Vivado щелкните правой кнопкой мыши по `pcie_7x_0.xci` и выберите **Customize IP**, чтобы открыть его графический интерфейс конфигурации.\n    *   **Перейдите на вкладку BARs:** В окне настройки IP нажмите на вкладку **Base Address Registers (BARs)**.\n\n2.  **Настройте каждый BAR (IP-ядро):**\n    *   **Согласуйте BARы устройства-донора:** Для каждого BAR (BAR0 до BAR5) установите размер, тип и статус prefetchable, чтобы они точно соответствовали тому, что вы извлекли из устройства-донора с помощью Arbor.\n    *   **Включение/отключение BAR:** Убедитесь, что включены только те BARы, которые фактически используются устройством-донором. Отключите (снимите флажок) любые неиспользуемые BARы.\n    *   **Установка размеров BAR:** Выберите соответствующий размер из выпадающего списка для каждого *включенного* BAR. Это будет степень двойки (например, 4КБ, 8КБ, 64КБ, 1МБ, 256МБ, 1ГБ).\n        *   **Пример:**\n            *   Если **BAR0** равен **64 КБ**, установите **BAR0 Size** в **64 KB**.\n            *   Если **BAR1** равен **128 МБ**, установите **BAR1 Size** в **128 MB**.\n    *   **Установка типов BAR:**\n        *   Выберите между **Memory (32-bit Addressing)** или **Memory (64-bit Addressing)**, если BAR отображается на память. Выберите **64-bit Addressing**, если BAR устройства-донора 64-битный или если вам нужен доступ к адресам выше 4 ГБ.\n        *   Выберите **I/O**, если BAR предназначен для адресного пространства портов ввода-вывода (менее распространено для современных устройств PCIe).\n    *   **Установите статус Prefetchable**: Установите флажок \"Prefetchable\", если BAR донора был идентифицирован как prefetchable. Этот бит позволяет хосту предвыбирать данные из этой области, потенциально повышая производительность.\n\n3.  **Обновление конфигураций BRAM (если применимо):**\n    *   Многие проекты PCILeech-FPGA используют IP-ядра Xilinx Block RAM (BRAM) для представления областей памяти, предоставляемых BAR. Эти BRAM обеспечивают физическое хранилище для памяти вашего эмулируемого устройства.\n    *   **Найдите IP-ядра BRAM:** В панели **Sources** вашего проекта Vivado, в подкаталоге `ip` (или аналогичном), вы можете найти файлы `.xci` для BRAM, потенциально названные так:\n        ```\n        pcileech-fpga/<your_board_variant>/ip/bram_bar_zero4k.xci\n        pcileech-fpga/<your_board_variant>/ip/bram_pcie_cfgspace.xci\n        # И, возможно, другие для BAR1, BAR2 и т.д.\n        ```\n    *   **Изменение размеров BRAM:** Для каждого IP-ядра BRAM, связанного с *включенным* BAR, вам может потребоваться **Customize IP** (щелкните правой кнопкой мыши по файлу `.xci`) и настроить его конфигурацию размера памяти, чтобы она точно соответствовала соответствующему размеру BAR, который вы установили в IP-ядре PCIe.\n        *   **Пример:** Если BAR0 равен 256 МБ, убедитесь, что BRAM, подключенный к BAR0, имеет размер 256 МБ.\n        *   **Внимание**: Убедитесь, что общий объем памяти, требуемый всеми активными BAR, не превышает физическую емкость BRAM вашего FPGA-устройства. Превышение емкости приведет к ошибкам реализации.\n\n4.  **Сохраните и регенерируйте:**\n    *   **Примените изменения (IP-ядро):** После настройки BAR в IP-ядре PCIe нажмите **OK** в окне настройки IP.\n    *   **Регенерация IP-ядер:** Vivado предложит вам регенерировать IP-ядро PCIe и любые связанные IP-ядра BRAM из-за изменений размера. Дождитесь завершения регенерации. Это гарантирует, что аппаратный список соединений отражает ваши новые определения BAR.\n    *   **Проверьте на ошибки:** Просмотрите окно **Messages** на наличие любых предупреждений или ошибок, связанных с конфигурацией BAR или экземплярами BRAM.\n\n#### **8.2.2. Определение адресных пространств BAR в прошивке**\n\nВ то время как IP-ядро PCIe конфигурирует *аппаратные* аспекты BAR, ваша пользовательская прошивка (код SystemVerilog) должна определять *логику* того, как ваше эмулируемое устройство реагирует, когда хост-ЦП выполняет операции чтения или записи по адресам в этих областях BAR. Это включает декодирование адресов и реализацию логики доступа к регистрам/памяти.\n\n**Шаги:**\n\n1.  **Откройте файл контроллера BAR:**\n    *   В Visual Studio Code откройте файл SystemVerilog, отвечающий за обработку доступов к BAR. Для PCILeech-FPGA это часто:\n        ```\n        pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv\n        ```\n        Этот модуль обычно принимает TLP-пакеты чтения/записи памяти PCIe и декодирует адрес, чтобы определить, какой BAR (и какое смещение внутри этого BAR) доступно.\n\n2.  **Реализуйте логику декодирования адресов:**\n    *   Внутри модуля `pcileech_tlps128_bar_controller.sv` вы найдете логику, которая определяет, какой BAR является целью входящей транзакции. Это часто включает проверку битов адреса относительно настроенных размеров BAR.\n    *   Вам нужно будет определить, как входящий адрес `req_addr` (из TLP) отображается на смещение внутри вашего конкретного BAR.\n    *   **Концептуальный пример:**\n        ```verilog\n        // Пример: Логика для BAR0 (предполагается, что это 256 МБ 64-битный BAR памяти, для регистров/данных)\n        // 'bar_hit[0]' будет входным сигналом, указывающим на попадание в BAR0, обычно от ядра PCIe.\n        // 'req_addr' - это входящий адрес PCIe.\n        // 'req_be' - это байтовое разрешение из TLP.\n        // 'req_data' - это входящие данные для записи.\n        // 'rsp_data' - это исходящие данные для чтения.\n\n        // Предположим, что BAR0 составляет 256 МБ (2^28 байт), биты адреса [27:0] находятся в BAR.\n        localparam BAR0_SIZE_BITS = 28; // 2^28 = 256 МБ\n\n        reg [31:0] internal_register_0; // Пример регистра внутри BAR0\n        reg [31:0] internal_register_1; // Другой пример регистра\n\n        assign bar0_offset = req_addr[BAR0_SIZE_BITS-1:0]; // Извлечение смещения внутри BAR0\n\n        always_comb begin\n            // Ответ по умолчанию\n            rsp_data = 32'hFFFFFFFF; // По умолчанию все F's или аналогичное для не отображенных областей\n\n            if (bar_hit[0]) begin // Если транзакция нацелена на BAR0\n                if (req_write) begin // Это операция записи\n                    case (bar0_offset)\n                        // Пример: Отображение смещения 0x0 на internal_register_0\n                        32'h0000_0000: begin\n                            if (req_be[3]) internal_register_0[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_0[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_0[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_0[7:0]   = req_data[7:0];\n                        end\n                        // Пример: Отображение смещения 0x4 на internal_register_1\n                        32'h0000_0004: begin\n                            if (req_be[3]) internal_register_1[31:24] = req_data[31:24];\n                            if (req_be[2]) internal_register_1[23:16] = req_data[23:16];\n                            if (req_be[1]) internal_register_1[15:8]  = req_data[15:8];\n                            if (req_be[0]) internal_register_1[7:0]   = req_data[7:0];\n                        end\n                        // Добавьте больше сопоставлений регистров или доступов к памяти (например, доступ к BRAM)\n                        default: begin\n                            // Обработка не отображенных записей внутри BAR0, например, игнорировать или логировать\n                        end\n                    endcase\n                end else if (req_read) begin // Это операция чтения\n                    case (bar0_offset)\n                        // Пример: Чтение из internal_register_0\n                        32'h0000_0000: rsp_data = internal_register_0;\n                        // Пример: Чтение из internal_register_1\n                        32'h0000_0004: rsp_data = internal_register_1;\n                        // Добавьте больше сопоставлений регистров или доступов к памяти (например, доступ к BRAM)\n                        default: begin\n                            rsp_data = 32'h0; // Возвращаем 0 для не отображенных чтений или специальное значение ошибки\n                        end\n                    endcase\n                end\n            end\n        end\n        ```\n    *   **Обработка передачи данных:** Блок `always_comb` (или `always_ff` для последовательной логики) должен определять, как генерируется `rsp_data` для чтений и как обновляются внутренние регистры/память для записей, на основе `bar0_offset` и байтовых разрешений (`req_be`).\n\n3.  **Реализуйте доступы к BRAM (если BAR отображается на BRAM):**\n    *   Если BAR отображается на большой блок памяти (например, 256 МБ), вы обычно создаете экземпляр IP-ядра BRAM (как обсуждалось в 8.2.1) и подключаете к нему логику вашего `bar_controller`. `bar_controller` будет предоставлять адрес и управляющие сигналы BRAM.\n    *   **Концептуальная интеграция BRAM (упрощенная):**\n        ```verilog\n        // Внутри pcileech_tlps128_bar_controller.sv или подмодуля\n        // Интерфейс к BRAM\n        wire [BAR0_SIZE_BITS-1:0] bram_addr;\n        wire [31:0] bram_wr_data;\n        wire [3:0] bram_wr_en; // Байтовые разрешения для BRAM\n        wire bram_wr_ce;\n        wire bram_rd_ce;\n        wire [31:0] bram_rd_data;\n\n        // Сопоставление сигналов TLP с интерфейсом BRAM\n        assign bram_addr = bar0_offset;\n        assign bram_wr_data = req_data;\n        assign bram_wr_en = req_be;\n        assign bram_wr_ce = bar_hit[0] && req_write;\n        assign bram_rd_ce = bar_hit[0] && req_read;\n\n        // Создание экземпляра IP-ядра BRAM\n        bram_bar_zero bram_inst ( // Предполагается, что 'bram_bar_zero' - это ваш модуль BRAM IP\n            .clka(clk),\n            .ena(1'b1),\n            .wea(bram_wr_en),\n            .addra(bram_addr),\n            .dina(bram_wr_data),\n            .douta(bram_rd_data)\n        );\n\n        // Для чтения из BAR0, вывод данных из BRAM\n        if (bar_hit[0] && req_read) begin\n            rsp_data = bram_rd_data;\n        end\n        ```\n\n4.  **Сохраните изменения:**\n    *   После реализации логики для каждого BAR сохраните файл `pcileech_tlps128_bar_controller.sv`.\n    *   **Проверка функциональности:** Эта логика сложна. Тщательная симуляция (с использованием тестового стенда) и последующее аппаратное тестирование будут иметь решающее значение для обеспечения правильного поведения.\n\n#### **8.2.3. Обработка нескольких BAR**\n\nПравильное управление несколькими BAR необходимо для устройств, которые предоставляют несколько различных областей памяти или ввода-вывода. Модуль `bar_controller` обычно обрабатывает все BAR.\n\n**Шаги:**\n\n1.  **Реализуйте логику для каждого BAR:**\n    *   Внутри `pcileech_tlps128_bar_controller.sv` расширьте логику для обработки всех включенных BAR (BAR0, BAR1, BAR2 и т.д.), которые использует ваше устройство-донор.\n    *   **Раздельные блоки логики:** Для ясности и удобства поддержки создавайте отдельные блоки `if/else if` или операторы `case`, которые активируются в зависимости от того, какой сигнал `bar_hit` активен.\n        ```verilog\n        // Обработка BAR0\n        if (bar_hit[0]) begin\n            // Логика чтения/записи, специфичная для BAR0, для его регистров/памяти\n        end else if (bar_hit[1]) begin\n            // Логика чтения/записи, специфичная для BAR1, для его регистров/памяти\n        end else if (bar_hit[2]) begin\n            // Логика, специфичная для BAR2\n        end\n        // ... продолжайте для других BAR\n        ```\n    *   **Определите регистры и память:** Выделите отдельные наборы регистров или подключите отдельные экземпляры BRAM для каждого BAR по мере необходимости.\n\n2.  **Обеспечьте отсутствие перекрывающихся адресных пространств:**\n    *   Хотя IP-ядро PCIe обрабатывает согласование различных адресных пространств для каждого BAR с ОС хоста, ваша внутренняя логика прошивки *должна* предполагать, что эти пространства являются раздельными и неперекрывающимися.\n    *   **Проверка диапазонов адресов**: Дважды проверьте конфигурации размеров BAR в IP-ядре PCIe, чтобы убедиться, что они являются дискретными и правильно выровнены по степеням двойки в соответствии со спецификациями PCIe.\n    *   **Обновление декодирования адресов**: Логика вашего `bar_controller` полагается на сигналы `bar_hit`, генерируемые IP-ядром PCIe. Убедитесь, что они правильно интерпретируются и приводят к уникальной логике обработки для каждого BAR.\n\n3.  **Тестирование доступов к BAR:**\n    *   **Имитационное тестирование:** Перед развертыванием оборудования используйте инструменты имитации (например, Vivado Simulator) с всеобъемлющим тестовым стендом для проверки всех операций чтения и записи для каждого BAR.\n        *   Отправьте TLP-пакеты записи в память по определенным смещениям внутри каждого BAR.\n        *   Отправьте TLP-пакеты чтения памяти по определенным смещениям внутри каждого BAR и проверьте возвращенные данные.\n    *   **Аппаратное тестирование:** После программирования FPGA используйте программные инструменты на стороне хоста (такие как клиентское ПО PCILeech или пользовательские скрипты на C/Python) для доступа и проверки каждого BAR.\n        *   **Linux**: Используйте `lspci -vvv` для проверки отображений BAR (`Memory at XXXX (64-bit, prefetchable) [size=YYYY]`). Затем вы можете использовать `devmem2` или пользовательский модуль ядра для чтения/записи по этим отображенным адресам.\n        *   **Windows**: Используйте такие инструменты, как \"RW-Everything\" или пользовательские приложения, для проверки и взаимодействия с отображенными областями памяти.\n        *   Выполняйте различные шаблоны чтения/записи, чтобы обеспечить целостность данных и правильную адресацию по всем BAR.\n\n---\n\n### **8.3. Эмуляция управления питанием устройства и прерываний**\n\nЭмуляция функций управления питанием и реализация прерываний критически важны для устройств, которым необходимо тесно и эффективно взаимодействовать с механизмами управления питанием и обработки прерываний операционной системы хоста. Без них эмулируемое устройство может не выглядеть полностью функциональным, или производительность может быть субоптимальной.\n\n#### **8.3.1. Конфигурация управления питанием**\n\nРеализация управления питанием позволяет эмулируемому устройству поддерживать различные состояния питания (например, D0, D3hot), способствуя общей энергоэффективности системы и соответствию ожиданиям операционной системы. ОС хоста будет запрашивать возможности устройства и отправлять команды для перехода между этими состояниями.\n\n**Шаги:**\n\n1.  **Включите управление питанием в IP-ядре PCIe:**\n    *   **Доступ к возможностям:** В окне настройки IP-ядра PCIe (`pcie_7x_0.xci`) перейдите на вкладку **PCIe Capabilities**.\n    *   **Включите управление питанием:** Найдите раздел или опцию, связанную с **Power Management Capability**. Убедитесь, что она отмечена или включена, чтобы включить структуру возможностей управления питанием (PM) в пространство конфигурации устройства.\n\n2.  **Установите поддерживаемые состояния питания:**\n    *   **Настройте поддерживаемые состояния:** В разделе возможностей управления питанием IP-ядра укажите, какие состояния питания поддерживает устройство. Обычно это флажки или выпадающие списки. Согласуйте эти настройки с возможностями устройства-донора, как это было замечено Arbor.\n        *   **D0 (Полностью включено/работоспособно)**: Всегда поддерживается.\n        *   **D1, D2 (Промежуточные состояния)**: Необязательные, для состояний низкого энергопотребления в режиме ожидания.\n        *   **D3hot (Выключено, вспомогательное питание присутствует)**: Логика устройства выключена, но может отвечать на события PM.\n        *   **D3cold (Выключено полностью)**: Питание на устройство не подается.\n    *   **Пример**: Если устройство-донор поддерживает только D0 и D3hot, включите только их.\n\n3.  **Реализуйте логику состояний питания в прошивке:**\n    *   **Откройте `pcileech_pcie_cfg_a7.sv` (или соответствующий модуль управления):** Вам обычно потребуется изменить прошивку, чтобы она отражала и потенциально реагировала на переходы состояний питания, управляемые хостом. Само ядро PCIe обрабатывает большую часть протокола, но ваша пользовательская логика должна знать состояние.\n    *   **Обработка записей в регистр управления и состояния управления питанием (PMCSR):** ОС хоста изменяет состояние питания устройства, записывая данные в определенные биты PMCSR, который является частью структуры возможностей PM. Ваша прошивка должна иметь логику для чтения этих битов и соответствующей настройки поведения устройства (например, приостановка/возобновления операций, включение/отключение тактовых сигналов).\n        ```verilog\n        // Пример: Часть pcileech_pcie_cfg_a7.sv или выделенный модуль PM\n        // Предположим, что 'cfg_write' активен для записей конфигурации, 'cfg_address' - смещение, 'cfg_writedata' - данные.\n        // Биты D-состояния находятся по смещению 0x04 внутри структуры возможностей PM, биты [1:0].\n\n        // Регистр PMCSR (внутреннее представление)\n        reg [15:0] pmcsr_reg = 16'h0000; // Инициализация в D0\n\n        // Сигнал пользовательской логики, указывающий на текущее состояние питания\n        reg [1:0] current_d_state = 2'b00; // 00 = D0, 01 = D1, 10 = D2, 11 = D3hot\n\n        always @(posedge clk) begin\n            if (reset) begin\n                pmcsr_reg <= 16'h0000;\n                current_d_state <= 2'b00; // Сброс в D0\n            end else begin\n                // Пример: Захват записей в PMCSR (если обрабатывается непосредственно в пользовательской логике)\n                // Примечание: Ядро PCIe управляет большей частью этого, но вашей пользовательской логике может потребоваться считывать значения из него.\n                // Предположим, что ядро PCIe предоставляет выход, отражающий текущее D-состояние:\n                // assign current_d_state = pcie_core_d_state_output;\n\n                // Если пользовательская логика *нуждается* в записи в PMCSR (менее распространено, обычно только для чтения статуса)\n                // Или если ей нужно обработать команду\n                // if (cfg_write && (cfg_address == PM_CAP_OFFSET + 2'h04)) begin // PMCSR находится по +0x04 от базового адреса PM Cap\n                //     pmcsr_reg[1:0] <= cfg_writedata[1:0]; // Захват нового D-состояния\n                //     // current_d_state <= cfg_writedata[1:0]; // Обновление внутреннего состояния\n                // end\n\n                // В PCILeech ядро PCIe управляет PMCSR. Вы, вероятно, будете считывать сигнал из ядра.\n                // Для демонстрации предположим, что 'pcie_d_state' - это вход из IP-ядра.\n                current_d_state <= pcie_d_state; // Обновление на основе статуса ядра PCIe\n            end\n        end\n\n        // Пример: Логика, реагирующая на изменения D-состояния\n        always @(*) begin\n            if (current_d_state == 2'b11) begin // Состояние D3hot\n                // Отключить питание второстепенных блоков, приостановить операции,\n                // активировать сигнал для основной логики DMA для остановки активности.\n                // Например: dma_engine_enable = 1'b0;\n            end else if (current_d_state == 2'b00) begin // Состояние D0\n                // Включить полную функциональность\n                // Например: dma_engine_enable = 1'b1;\n            end\n        end\n        ```\n    *   **Управление эффектами состояния питания:** Реализуйте логику для изменения внутреннего поведения устройства (например, включение/отключение тактовых сигналов, перевод подмодулей в режимы низкого энергопотребления) на основе `current_d_state`. Это имеет решающее значение для точной эмуляции энергопотребления и обеспечения правильной реакции устройства на команды ОС.\n\n4.  **Сохраните изменения:**\n    *   Сохраните все измененные файлы прошивки.\n    *   Тщательно протестируйте функции управления питанием с помощью симуляции или аппаратного тестирования (например, функции \"Сон\" или \"Гибернация\" Windows, или команды Linux `poweroff`, чтобы увидеть, правильно ли устройство переходит в эти состояния).\n\n#### **8.3.2. Конфигурация MSI/MSI-X**\n\nРеализация прерываний, генерируемых сообщениями (MSI), или их расширенной версии (MSI-X) позволяет эмулируемому устройству использовать прерывания на основе сообщений. Они значительно более эффективны и масштабируемы, чем традиционные прерывания на основе контактов (INTx), и являются предпочтительным методом для современных устройств PCIe. MSI/MSI-X позволяют устройству уведомлять ЦП, записывая специальный TLP-пакет в определенный адрес памяти.\n\n**Шаги:**\n\n1.  **Включите MSI/MSI-X в IP-ядре PCIe:**\n    *   **Доступ к конфигурации прерываний:** В окне настройки IP-ядра PCIe (`pcie_7x_0.xci`) перейдите на вкладку **Interrupts** или в раздел, специально помеченный **MSI/MSI-X Capabilities**.\n    *   **Выберите тип прерывания:** Выберите **MSI** или **MSI-X** на основе возможностей устройства-донора. MSI-X обычно предпочтительнее из-за его гибкости (больше векторов, маскирование каждого вектора).\n    *   **Настройте количество поддерживаемых векторов:** Установите количество векторов прерываний (сообщений), которое будет поддерживать устройство. Согласуйте это с устройством-донором.\n        *   **MSI** поддерживает до 32 векторов (обычно 1, 2, 4, 8, 16 или 32).\n        *   **MSI-X** поддерживает до 2048 векторов, что позволяет более детально определять источники прерываний.\n    *   **Включите возможности:** Убедитесь, что структура возможностей MSI или MSI-X явно включена для включения в пространство конфигурации устройства. Именно так ОС хоста обнаруживает возможности прерываний устройства.\n\n2.  **Реализуйте логику прерываний в прошивке:**\n    *   **Откройте `pcileech_pcie_tlp_a7.sv` (или модуль пользовательской логики):** Этот файл обычно отвечает за генерацию TLP-папакетов, определяемых пользователем, и может быть подходящим местом для инициации сообщений MSI/MSI-X. Однако *триггер* прерывания будет исходить от вашей пользовательской логики.\n    *   **Определите сигналы прерываний:** Объявите внутренние сигналы, которые будут указывать, когда необходимо сгенерировать прерывание.\n        ```verilog\n        // В пользовательском модуле (например, 'my_device_logic.sv'), который взаимодействует с логикой генерации TLP\n        reg msi_trigger_signal; // Установите его, когда возникает условие прерывания\n        ```\n    *   **Реализуйте логику генерации прерываний:** Определите условия, при которых должно быть вызвано прерывание. Обычно это включает обнаружение событий внутри логики вашего эмулируемого устройства.\n        ```verilog\n        // Внутри 'my_device_logic.sv'\n        input wire clk;\n        input wire reset;\n        input wire event_data_ready; // Пример: Входной сигнал от вашей логики, когда данные готовы\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_trigger_signal <= 1'b0;\n            end else if (event_data_ready) begin // Когда происходит определенное событие\n                msi_trigger_signal <= 1'b1; // Вызвать MSI\n            end else begin\n                msi_trigger_signal <= 1'b0; // Сбросить после одного цикла или при подтверждении\n            end\n        end\n        ```\n    *   **Подключение к интерфейсу MSI ядра PCIe:** Сигнал `msi_trigger_signal` (или аналогичный выход от вашей пользовательской логики) должен быть подключен к соответствующему входу IP-ядра PCIe (например, `s_axis_tdata_tready`, `s_axis_tdata_tvalid`, `s_axis_tdata_tlast`, если используется интерфейс AXI-Stream для MSI TLP-пакетов, или выделенные порты запросов MSI, предоставляемые IP-ядром). Затем ядро PCIe формирует и отправляет фактический TLP-пакет MSI/MSI-X. Обратитесь к документации IP-ядра Xilinx PCIe для получения точных сведений об интерфейсе.\n\n3.  **Сохраните изменения:**\n    *   Сохраните все измененные файлы прошивки после реализации логики прерываний.\n    *   **Проверка временных ограничений:** Новая логика, особенно пути прерываний, может быть критичной ко времени. Убедитесь, что инструменты синтеза и реализации не сообщают о каких-либо нарушениях временных ограничений, связанных с вашей логикой генерации прерываний.\n\n#### **8.3.3. Реализация логики обработки прерываний (на стороне устройства)**\n\nПомимо простого включения возможности, определение *когда* и *как* прерывания генерируются вашим эмулируемым устройством, имеет решающее значение для его правильного взаимодействия с механизмами обработки прерываний хоста и поведением драйверов. Это включает создание внутренней логики, которая активирует запрос на прерывание.\n\n**Шаги:**\n\n1.  **Определите условия прерывания:**\n    *   **Определите события-триггеры:** Основываясь на поведении вашего устройства-донора, определите конкретные внутренние события, которые должны вызывать прерывание вашим эмулируемым устройством.\n        *   **Примеры**: Завершение передачи данных, готовность новых данных в буфере приема, внутреннее состояние ошибки, завершение конкретной команды, изменение состояния канала.\n    *   **Реализуйте логику условий:** Используйте комбинационную или последовательную логику в ваших пользовательских модулях SystemVerilog для точного обнаружения этих событий и генерации короткого импульса или сигнала на основе уровня, который указывает на запрос прерывания.\n\n2.  **Создайте модуль генерации прерываний (модульный дизайн):**\n    *   Хорошей практикой является инкапсуляция логики генерации прерываний в отдельный, выделенный модуль для ясности, повторного использования и облегчения отладки. Этот модуль будет принимать внутренние события в качестве входных данных и выдавать выходной сигнал `msi_req` (или аналогичный), который подключается к ядру PCIe.\n        ```verilog\n        // Файл: interrupt_generator.sv\n        module interrupt_generator (\n            input wire clk,\n            input wire reset,\n            input wire event_trigger,        // Входной сигнал от вашей пользовательской логики (например, data_ready, error_flag)\n            output reg msi_req_o            // Выход: Активировать для запроса MSI/MSI-X\n        );\n\n        // Простой генератор импульсов для MSI (однократное прерывание)\n        reg event_trigger_d1;\n\n        always @(posedge clk or posedge reset) begin\n            if (reset) begin\n                msi_req_o <= 1'b0;\n                event_trigger_d1 <= 1'b0;\n            end else begin\n                event_trigger_d1 <= event_trigger;\n                // Генерируем одноцикловый импульс, когда event_trigger переходит в высокий уровень\n                if (event_trigger && !event_trigger_d1) begin\n                    msi_req_o <= 1'b1; // Активируем запрос MSI\n                end else begin\n                    msi_req_o <= 1'b0; // Деактивируем после одного цикла\n                end\n            end\n        end\n\n        endmodule // interrupt_generator\n        ```\n    *   **Интеграция с основной прошивкой:** Создайте экземпляр этого модуля `interrupt_generator` в вашей высокоуровневой пользовательской логике (например, в `pcileech_squirrel_top.sv` или в модуле, который он инстанциирует) и подключите его выход `msi_req_o` к входу MSI IP-ядра PCIe.\n\n3.  **Обеспечьте правильную синхронизацию и последовательность:**\n    *   **Соблюдайте спецификации PCIe:** Сообщения MSI/MSI-X являются TLP-пакетами. Убедитесь, что генерация этих сообщений соответствует формату TLP PCIe, управлению потоком и временным требованиям. IP-ядро PCIe обрабатывает большую часть этого, но ваши входные сигналы к нему должны быть стабильными и правильно синхронизированными.\n    *   **Управление задержкой прерывания:** Оптимизируйте свою логику, чтобы минимизировать любые ненужные задержки между возникновением внутреннего события и активацией сигнала `msi_req_o`.\n\n4.  **Протестируйте доставку прерываний:**\n    *   **Симуляция:** Используйте комплексный тестовый стенд для имитации сценариев, в которых должны генерироваться прерывания. Убедитесь, что ваш сигнал `msi_req_o` ведет себя ожидаемым образом и что ядро PCIe генерирует правильные TLP-пакеты MSI/MSI-X.\n    *   **Аппаратное тестирование:**\n        *   Прошейте FPGA обновленной прошивкой.\n        *   Используйте программное обеспечение на стороне хоста для запуска событий, которые должны вызывать прерывание (например, инициирование передачи DMA, которая завершается).\n        *   Подтвердите, что прерывания получены операционной системой хоста. В Linux `dmesg` может показывать сообщения прерываний. В Windows вы можете использовать специальные инструменты отладки драйверов или Просмотр событий.\n        *   **Инструменты отладки:** Используйте встроенные логические анализаторы (ILA) Vivado (как будет обсуждаться далее в Разделе 12) для мониторинга `event_trigger`, `msi_req_o` и выходных сигналов TLP ядра PCIe в реальном времени, чтобы проверить правильность генерации прерываний.\n\n5.  **Сохраните изменения:**\n    *   Завершите все изменения кода и сохраните соответствующие файлы прошивки.\n    *   Просмотрите и доработайте логику прерываний на основе результатов тестирования, чтобы обеспечить надежность.\n\n---\n\n## **9. Эмуляция специфических возможностей устройства**\n\nПомимо стандартного пространства конфигурации PCIe и общей функциональности DMA, многие устройства-доноры обладают уникальными возможностями, пользовательскими регистрами или функциями, специфичными для поставщика, которые критически важны для их полной функциональности или для взаимодействия с их проприетарными драйверами. Точная эмуляция требует понимания и воспроизведения этих нюансов. В этом разделе рассматривается реализация таких расширенных возможностей, что позволяет добиться более точной и полнофункциональной эмуляции.\n\n### **9.1. Реализация расширенных возможностей PCIe**\n\nСпецификация PCIe включает различные *расширенные возможности* помимо базового пространства конфигурации. Эти возможности предоставляют такие функции, как расширенная отчетность об ошибках, управление питанием, виртуализация и многое другое. Их реализация помогает вашему эмулируемому устройству выглядеть более легитимно и корректно взаимодействовать с современными хост-системами.\n\n**Шаги:**\n\n1.  **Определите требуемые расширенные возможности:**\n    *   При сборе информации об устройстве-доноре с помощью таких инструментов, как Arbor, тщательно ищите и документируйте любые расширенные возможности, присутствующие в пространстве конфигурации донора. Они обычно находятся за пределами первоначальных 256 байтов стандартного пространства конфигурации.\n    *   **Распространенные примеры:**\n        *   **Расширенная отчетность об ошибках (AER)**: Обеспечивает надежные механизмы обнаружения, регистрации и отчетности об ошибках для каналов PCIe.\n        *   **Серийный номер устройства (DSN)**: (Уже рассмотрено в Разделе 6.2).\n        *   **Управление питанием (PM)**: (Уже рассмотрено в Разделе 8.3.1).\n        *   **Структура возможностей PCI Express (PCIe)**: (Уже рассмотрено в Разделе 8.1 для скорости/ширины канала, максимальной полезной нагрузки/запроса на чтение, но также включает другие поля, такие как Device Control/Status, Link Control/Status).\n        *   **Виртуальный канал (VC)/Многофункциональный виртуальный канал (MFVC)**: Для качества обслуживания (QoS) и управления трафиком.\n        *   **Точное измерение времени (PTM)**: Для синхронизации времени между устройствами.\n        *   **Отчетность о задержках (LTR)**: Для управления питанием на основе требований к задержкам.\n        *   **Сбрасываемый FPC (сброс на уровне функции)**: Для более гранулированных сбросов.\n\n2.  **Включите возможности в IP-ядре PCIe Vivado:**\n    *   Получите доступ к окну настройки IP-ядра PCIe (`pcie_7x_0.xci`) в Vivado.\n    *   Перейдите по различным вкладкам (например, \"PCIe Capabilities\", \"Extended Capabilities\", \"Advanced Options\").\n    *   Ищите флажки или выпадающие списки для включения и настройки конкретных расширенных возможностей, идентифицированных у вашего устройства-донора.\n    *   **Пример (AER):** Вы найдете раздел \"Advanced Error Reporting\", где вы можете включить его и настроить его регистры (например, маски серьезности).\n    *   **Примечание:** IP-ядро Xilinx PCIe обеспечивает высокую степень настраиваемости для многих стандартных и расширенных возможностей. Часто это просто вопрос включения правильных опций в графическом интерфейсе.\n\n3.  **Реализуйте логику прошивки для регистров возможностей (при необходимости):**\n    *   Хотя IP-ядро PCIe обрабатывает *присутствие* и большую часть *протокола* для этих возможностей, некоторые возможности предоставляют регистры, которые вашей пользовательской прошивке может потребоваться читать или записывать, или на значения которых вашей прошивке нужно реагировать.\n    *   **Пример (AER):** Если ваше эмулируемое устройство обнаруживает внутреннюю ошибку, которую следует сообщить через AER, вашей прошивке необходимо записать данные в конкретные регистры состояния ошибок AER (которые могут быть представлены как часть BAR или обрабатываться внутренне ядром PCIe, а затем отражаться в пользовательской логике). Ваша пользовательская логика затем активирует вход ошибки для ядра PCIe.\n    *   **Пример (Управление питанием):** Как обсуждалось в 8.3.1, вашей прошивке необходимо реагировать на изменения D-состояния, сигнализируемые ядром PCIe.\n    *   **Процесс:**\n        *   Определите конкретные регистры в каждой включенной структуре возможностей, с которыми взаимодействует драйвер вашего устройства-донора.\n        *   Найдите соответствующие сигналы или логику в рамках PCILeech-FPGA, которые взаимодействуют с этими регистрами (часто в `pcileech_pcie_cfg_a7.sv` или `bar_controller`).\n        *   Реализуйте логику чтения/записи для этих регистров, убедившись, что внутреннее состояние вашего эмулируемого устройства точно отражает значения, которые ожидает драйвер.\n\n### **9.2. Эмуляция функций, специфичных для поставщика**\n\nЗдесь начинается истинная \"полная эмуляция устройства\", которая становится высокоспециализированной. Многие реальные устройства имеют уникальные регистры, недокументированные команды, пользовательские форматы данных или проприетарные потоки управления, которые отличают их. Воспроизведение этих нюансов требует более глубокого анализа и пользовательской разработки HDL.\n\n**Шаги:**\n\n1.  **Обратный инжиниринг поведения, специфичного для поставщика:**\n    *   Это часто самая сложная часть.\n    *   **Статический анализ (драйвер/прошивка):** Дизассемблируйте официальный драйвер устройства-донора (Windows `.sys`, Linux `.ko`) или оригинальную прошивку устройства (если доступна). Ищите уникальные шаблоны доступа к вводу-выводу или MMIO, \"магические\" значения или последовательности записей в регистры. Такие инструменты, как Ghidra, IDA Pro или objdump, могут быть бесценны.\n    *   **Динамический анализ (выполнение драйвера):** Запустите устройство-донор с его драйвером и отслеживайте трафик PCIe с помощью **анализатора протокола PCIe** (например, Teledyne LeCroy, Keysight, как обсуждается в Разделе 12.2). Это золотой стандарт для понимания фактических обменов TLP, включая сообщения, определяемые поставщиком, и последовательности доступов к регистрам. Обратите внимание на:\n        *   Конкретные адреса памяти, к которым осуществляется доступ в BAR.\n        *   Шаблоны чтения/записи по этим адресам.\n        *   Значения, записываемые в конкретные регистры или считываемые из них.\n        *   Временные зависимости между командами и ответами.\n    *   **Мониторинг системных вызовов/API**: На хосте используйте такие инструменты, как Procmon (Windows) или `strace` (Linux), чтобы увидеть, как драйвер взаимодействует с ОС и какие конкретные коды управления вводом-выводом устройства (IOCTL) он использует, которые могут соответствовать конкретным аппаратным операциям.\n    *   **Аппаратное перехватывание (Hardware Sniffing)**: Если возможно, используйте аппаратный сниффер (например, Saleae Logic Analyzer) для захвата сигналов на внутренних шинах устройства (например, SPI, I2C), если у него есть внешняя флэш-память или компоненты.\n\n2.  **Реализация пользовательских регистров и логики в BAR:**\n    *   Как только вы определили регистры, специфичные для поставщика, или командные протоколы, вам нужно будет определить их в вашей прошивке FPGA, обычно как регистры, отображаемые на память, доступные через один из ваших BAR.\n    *   **Создайте внутренние регистры:** Объявите переменные `reg` в вашем коде SystemVerilog для представления этих пользовательских регистров.\n        ```verilog\n        // В вашем pcileech_tlps128_bar_controller.sv или подмодуле\n        reg [31:0] custom_control_reg;\n        reg [31:0] custom_status_reg;\n        reg [31:0] custom_data_reg;\n\n        // Пример: Сопоставьте их с конкретными смещениями в BAR0 (предполагая, что BAR0 достаточно большой)\n        // Измените оператор case 'bar0_offset' (из раздела 8.2.2)\n        // ...\n        if (bar_hit[0]) begin\n            if (req_write) begin\n                case (bar0_offset)\n                    32'h0000_1000: custom_control_reg <= req_data; // Пользовательский управляющий регистр\n                    32'h0000_1004: custom_data_reg <= req_data;    // Пользовательский регистр записи данных\n                    // ... другие сопоставления\n                endcase\n            end else if (req_read) begin\n                case (bar0_offset)\n                    32'h0000_1000: rsp_data = custom_control_reg; // Чтение управляющего регистра\n                    32'h0000_1008: rsp_data = custom_status_reg;  // Пользовательский регистр состояния\n                    // ... другие сопоставления\n                endcase\n            end\n        end\n        // ...\n        ```\n    *   **Реализация поведенческой логики:** Создайте логику SystemVerilog (конечные автоматы, комбинационную логику), которая:\n        *   Реагирует на записи в ваш `custom_control_reg`. Например, определенный бит в этом регистре может запускать передачу DMA, сбрасывать флаг состояния или инициировать внутреннюю операцию.\n        *   Обновляет ваш `custom_status_reg` на основе внутреннего состояния вашего эмулируемого устройства (например, \"операция завершена\", \"произошла ошибка\", \"данные доступны\").\n        *   Обрабатывает данные, записанные в `custom_data_reg`, или предоставляет данные из него при чтении, имитируя пути данных устройства-донора.\n\n3.  **Эмуляция сообщений, специфичных для поставщика (если применимо):**\n    *   Некоторые сложные устройства могут использовать \"Сообщения, определяемые поставщиком\" (VDM) через PCIe для специфического управления или связи. Если ваш анализ выявляет такие сообщения, вам потребуется:\n        *   Включить поддержку VDM в IP-ядре PCIe (если доступно).\n        *   Реализовать логику генерации TLP (как будет обсуждаться в Разделе 10) для создания и отправки этих VDM.\n        *   Реализовать логику приема и анализа TLP для интерпретации входящих VDM от хоста.\n\n4.  **Проверка эмулируемого поведения:**\n    *   **Итеративное тестирование:** Это очень итеративный процесс. Вносите небольшие изменения, компилируйте, прошивайте и тестируйте.\n    *   **Загрузка драйвера:** Загружается ли драйвер устройства-донора корректно, без ошибок?\n    *   **Функциональные тесты:** Может ли драйвер инициировать базовые операции? Получает ли он ожидаемые ответы от ваших эмулированных регистров?\n    *   **Тесты приложений:** Могут ли приложения, которые полагаются на устройство-донор, корректно работать с вашей эмулированной версией?\n    *   **Отладка:** Широко используйте ILA и анализаторы протокола PCIe для сравнения поведения вашего эмулируемого устройства с захваченным поведением реального устройства-донора. Ищите расхождения во времени TLP, значениях регистров и общем потоке протокола.\n\n---\n\n## **10. Эмуляция пакетов транспортного уровня (TLP)**\n\nПакеты транспортного уровня (TLP) являются фундаментальными единицами связи в архитектуре PCIe. Каждое взаимодействие между хост-системой и устройством PCIe, от чтения конфигурации до передачи данных, инкапсулируется в один или несколько TLP-пакетов. Точная эмуляция TLP-пакетов не просто важна; она *критически* важна для правильного взаимодействия эмулируемого устройства с хост-системой, гарантируя корректную работу драйверов и ожидаемое перемещение данных.\n\n### **10.1. Понимание и захват TLP-пакетов**\n\nПрежде чем вы сможете создавать пользовательские TLP-пакеты, вы должны глубоко понять их структуру и общие типы. Захват реальных TLP-пакетов с вашего устройства-донора предоставляет наиболее точный шаблон.\n\n*   **Компоненты TLP-пакета**:\n    *   **Заголовок**: Наиболее важная часть, обычно 3 или 4 двойных слова (Dword = 4 байта). Он содержит критически важные поля, которые определяют назначение TLP-пакета и то, как он должен обрабатываться:\n        *   **Fmt (Формат) и Type (Тип)**: Определяет формат TLP-пакета (3DW/4DW, с данными/без данных) и его конкретное назначение (например, запрос на чтение памяти, запись в память, завершение, чтение/запись конфигурации).\n        *   **Length (Длина)**: Указывает размер полезной нагрузки в Dword.\n        *   **Requester ID (Шина, Устройство, Функция)**: Идентифицирует функцию PCIe, которая инициировала запрос. Важно для маршрутизации завершений обратно к правильному источнику.\n        *   **Tag (Тег)**: Уникальный идентификатор, присвоенный запрашивающим устройством транзакции, позволяющий завершающему устройству сопоставить TLP-пакет завершения с исходным TLP-запросом.\n        *   **Address (Адрес)**: Для транзакций памяти/ввода-вывода это целевой адрес памяти или ввода-вывода.\n        *   **First DW Byte Enable (FBE)** и **Last DW Byte Enable (LBE)**: Указывают, какие байты в первом и последнем Dword полезной нагрузки действительны для операций записи, или какие байты запрашиваются для завершений чтения.\n        *   **Traffic Class (TC)** и **Transaction ID (TID)**: Для QoS и правил упорядочивания.\n    *   **Полезная нагрузка (Optional)**: Присутствует в TLP-пакетах, таких как запись в память, запись конфигурации и завершения чтения. Она содержит фактические передаваемые данные.\n    *   **End-to-End CRC (ECRC) (Optional)**: 32-битный CRC, охватывающий весь TLP-пакет, обеспечивающий целостность данных от источника до получателя, обычно генерируется/проверяется программным обеспечением.\n\n*   **Понимание общих типов TLP-пакетов**: Ваша прошивка будет в основном иметь дело с ними:\n    *   **Запрос на чтение памяти (MRd)**: TLP-пакет, отправленный запрашивающим устройством (например, хост-ЦП или вашей FPGA в качестве мастера DMA) для чтения данных из определенного адреса памяти.\n    *   **Завершение чтения памяти с данными (CplD)**: TLP-пакет, отправленный завершающим устройством (например, вашей FPGA, отвечающей на MRd хоста), несущий запрошенные данные.\n    *   **Запись в память (MWr)**: TLP-пакет, отправленный запрашивающим устройством (например, хост-ЦП или вашей FPGA) для записи данных в определенный адрес памяти.\n    *   **Завершение без данных (Cpl)**: TLP-пакет, отправленный завершающим устройством для подтверждения запроса, который не возвращает данных (например, успешная MWr).\n    *   **Запрос на чтение конфигурации (CfgRd)**: TLP-пакет от хоста для чтения регистров в пространстве конфигурации устройства.\n    *   **Завершение чтения конфигурации с данными (CplD)**: TLP-пакет от устройства, возвращающий данные для CfgRd.\n    *   **Запрос на запись конфигурации (CfgWr)**: TLP-пакет от хоста для записи в регистры в пространстве конфигурации устройства.\n    *   **Сообщения, определяемые поставщиком (VDM)**: Пользовательские TLP-пакеты, используемые конкретными поставщиками для проприетарной связи.\n\n#### **10.1.2. Захват TLP-пакетов с устройства-донора**\n\nЗахват реального трафика PCIe с вашего устройства-донора бесценен. Он предоставляет конкретные примеры структур TLP-пакетов, последовательностей и временных характеристик, позволяя вам точно их воспроизвести.\n\n*   **Шаги**:\n    1.  **Настройте анализатор протокола PCIe**:\n        *   Наиболее эффективный метод включает использование специализированных аппаратных средств, часто называемых \"Анализаторами протокола PCIe\". Эти устройства располагаются между хостом и платой PCIe-донора, пассивно захватывая весь трафик.\n        *   **Примеры**:\n            *   **Анализаторы PCIe Teledyne LeCroy**: Отраслевой стандарт, высокопроизводительные, но требуют значительных инвестиций.\n            *   **Анализаторы PCIe Keysight**: Еще один ведущий производитель.\n            *   (Для базовой отладки некоторые высококлассные логические анализаторы с декодерами PCIe могут предлагать ограниченный просмотр TLP-пакетов, но настоящий анализатор протокола превосходит их).\n    2.  **Захват транзакций**:\n        *   Установите устройство-донор в тестовую систему с подключенным анализатором протокола.\n        *   Запустите драйвер устройства-донора и любые связанные приложения.\n        *   Отслеживайте и записывайте транзакции PCIe во время нормальной работы, и особенно во время критических фаз, таких как:\n            *   Перечисление устройства (когда ОС впервые его обнаруживает).\n            *   Загрузка и инициализация драйвера.\n            *   Типичные операции передачи данных (например, копирование больших файлов для устройства хранения данных, сетевой трафик для сетевой карты).\n            *   Команды или диагностика, специфичные для устройства.\n    3.  **Анализ захваченных TLP-пакетов**:\n        *   Используйте сложное программное обеспечение анализатора протокола для анализа захваченных TLP-пакетов. Программное обеспечение будет декодировать поля, предоставлять хронологические представления, а также позволять фильтровать и искать.\n        *   Обратите пристальное внимание на:\n            *   Точные поля `Fmt` и `Type`.\n            *   Значения `Requester ID` и `Tag` (особенно для завершений).\n            *   `Address` и `Length` для транзакций памяти.\n            *   Содержимое `Data Payload` для записей и завершений чтения.\n            *   Любые поля, специфичные для поставщика, или пользовательские TLP-пакеты.\n\n#### **10.1.3. Документирование ключевых TLP-транзакций**\n\nСтруктурированная документация захваченных TLP-пакетов создает шаблон для вашей эмуляции.\n\n*   **Шаги**:\n    1.  **Определите критически важные транзакции**:\n        *   Сосредоточьтесь на TLP-пакетах, которые необходимы для основной функциональности устройства. К ним относятся:\n            *   **Последовательность инициализации**: Серия чтений/записей конфигурации, которые ОС выполняет во время перечисления.\n            *   **Инициализация драйвера**: Команды и данные, обмениваемые при запуске драйвера.\n            *   **Основные передачи данных**: Как TLP-пакеты `MWr` и `MRd` структурируются и завершаются для основной функции устройства.\n            *   **Обработка ошибок**: Как устройство сообщает об ошибках (например, завершение с прерыванием от завершающего устройства (CA), неподдерживаемый запрос (UR)).\n            *   **Переходы состояний управления питанием**: TLP-пакеты, связанные с изменениями D-состояния.\n            *   **Генерация прерываний**: Как отправляются сообщения MSI/MSI-X.\n    2.  **Создайте подробную документацию**:\n        *   Для каждой ключевой последовательности TLP-пакетов запишите:\n            *   **Тип TLP-пакета** (например, MWr, MRd, CplD).\n            *   Его **поля заголовка** (Fmt, Type, Requester ID, Tag, Length, Address, Byte Enables).\n            *   **Полезная нагрузка данных** (если применимо).\n            *   **Порядковый номер** или порядок в транзакции.\n            *   **Условия**, при которых он отправляется (например, \"отправлено хостом при инициализации драйвера\", \"отправлено устройством по завершении DMA\").\n            *   Любые **ожидаемые ответы** или последующие TLP-пакеты.\n        *   Снимки экрана с анализатора протокола могут быть очень полезны здесь.\n    3.  **Поймите временные характеристики и последовательность**:\n        *   Помимо содержимого TLP-пакетов, *время* и *последовательность* TLP-пакетов жизненно важны. PCIe имеет строгие правила упорядочивания и механизмы управления потоком. Обратите внимание на:\n            *   **Задержка между запросом и завершением**: Как быстро реагирует реальное устройство.\n            *   **Кредиты управления потоком**: Как устройство управляет своим буферным пространством для входящих/исходящих TLP-пакетов. Хотя IP-ядро Xilinx PCIe обрабатывает базовое управление потоком, для расширенной эмуляции знание типичного использования кредитов донора может быть полезно.\n            *   **Порядок пакетов транспортного уровня**: Поймите, как упорядочиваются постированные (записи) и непостированные (чтения, завершения) транзакции.\n\n### **10.2. Создание пользовательских TLP-пакетов для специфических операций**\n\nКак только вы поймете шаблон, вы сможете применить эти знания в прошивке вашей FPGA (SystemVerilog) для активной генерации и ответа на TLP-пакеты. Фреймворк PCILeech-FPGA предоставляет уровни абстракции, но для глубокой эмуляции вам может потребоваться прямое взаимодействие с логикой генерации/анализа TLP-пакетов.\n\n#### **10.2.1. Реализация обработки TLP в прошивке**\n\nВаша прошивка должна иметь логику для отправки и приема TLP-пакетов. IP-ядро PCIe обрабатывает физический уровень и уровень канала данных, предоставляя интерфейс уровня транзакций (часто AXI-Stream) вашей пользовательской логике.\n\n*   **Файлы для изменения (основные)**:\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_pcie_tlp_a7.sv` (или аналогичный, в зависимости от варианта платы)\n        *   Этот файл часто содержит основную логику для преобразования пользовательских запросов в исходящие TLP-пакеты и анализа входящих TLP-пакетов в сигналы для вашей пользовательской логики.\n    *   `pcileech-fpga/<your_board_variant>/src/pcileech_tlps128_bar_controller.sv`\n        *   Этот модуль специально обрабатывает анализ входящих TLP-пакетов чтения/записи памяти, которые нацелены на BARы вашего устройства, и генерацию соответствующих TLP-пакетов завершения.\n\n*   **Шаги**:\n\n    1.  **Поймите интерфейс IP-ядра PCIe**:\n        *   Прежде чем писать логику TLP-папакетов, тщательно изучите Руководство пользователя IP-ядра PCIe Xilinx (в частности, разделы об интерфейсе пользовательского приложения или интерфейсе AXI4-Stream). В нем определяется, как ваша логика SystemVerilog подключается к ядру PCIe для отправки и приема TLP-пакетов. Вы обычно будете взаимодействовать с `s_axis_rx_tdata` (полученные данные TLP), `s_axis_rx_tvalid` (получен действительный TLP), `m_axis_tx_tdata` (исходящие данные TLP), `m_axis_tx_tready` (ядро готово принять TLP) и т. д.\n\n    2.  **Создайте функции генерации TLP (для исходящих TLP-пакетов)**:\n        *   В `pcileech_pcie_tlp_a7.sv` (или модуле, который взаимодействует с `m_axis_tx_*`), вы будете писать логику для сборки TLP-пакетов с требуемыми заголовками и полезными нагрузками. Это часто включает объединение различных полей в шину `[127:0]` (для 128-битного интерфейса) или `[63:0]` (для 64-битного интерфейса), которая подается на ядро PCIe.\n        *   **Пример (концептуальная, упрощенная функция для 3DW заголовка TLP):**\n            ```verilog\n            // Это концептуальная вспомогательная функция. В реальности вы бы построили конечный автомат\n            // для отправки TLP-пакетов через интерфейс AXI-Stream, возможно, используя FIFO.\n            function automatic [95:0] create_3dw_tlp_header; // Предполагается, что 3 Dword = 96 бит\n                input logic [7:0] tlp_type_fmt;   // Поля формата и типа\n                input logic [15:0] requester_id;  // BDF\n                input logic [7:0] tag;\n                input logic [7:0] lower_address_bits; // Или более сложный адрес\n                input logic [7:0] byte_enables;   // Разрешение байтов первого DW\n\n                begin\n                    create_3dw_tlp_header = {\n                        tlp_type_fmt,                     // Fmt[6:4], Type[3:0]\n                        8'b0,                             // Зарезервировано\n                        4'b0,                             // TC[3:0] (класс трафика)\n                        3'b0,                             // Attr[2:0]\n                        1'b0,                             // TH (подсказка TLP)\n                        2'b0,                             // D(igest) (присутствие ECRC)\n                        1'b0,                             // EP (отравлено)\n                        1'b0,                             // TD (зависит от типа)\n                        // DW0: Fmt, Type, TC, Attr, TH, D, EP, TD, Length (не в 3DW, в 4DW есть)\n\n                        requester_id,                     // ID запрашивающего (Bus[7:0], Device[4:0], Function[2:0])\n                        tag,                              // Тег\n                        lower_address_bits,               // Пример: младшие биты адреса или часть данных\n                        byte_enables,                     // Разрешение байтов первого DW\n                        4'b0,                             // Зарезервировано\n                        4'b0                              // Разрешение байтов последнего DW (обычно для MWr)\n                        // Поля DW1, DW2...\n                    };\n                end\n            endfunction\n\n            // Пример: Генерация завершения с данными (CplD) в конечном автомате\n            // Это всего лишь фрагмент, не полная реализация\n            localparam  CPLD_3DW_FMT = 8'h4A; // Fmt=100 (4DW, с данными), Type=1010 (Cpl)\n            localparam  CPL_D_FMT_TYPE_LEN = 8'h4A; // Скорректировано на основе спецификации PCIe. (4DW заголовок с данными)\n\n            // ... конечный автомат для отправки TLP\n            // В состоянии, когда вы готовы отправить CplD\n            if (tx_ready_from_pcie_core) begin\n                // Построить заголовок и полезную нагрузку\n                // Для CplD вам нужны Complier ID, Status, Byte Count, Requester ID, Tag, Completion ID, Lower Address\n                // А затем фактическая полезная нагрузка прочитанных данных\n                m_axis_tx_tdata_reg = {\n                    CPL_D_FMT_TYPE_LEN,         // Байт 0: Fmt/Type\n                    tlp_length_dw_minus_one,    // Байт 1: Длина TLP (в Dword) - 1\n                    status_completion_bits,     // Байт 2: Статус Cpl, BCM, Rsvd\n                    byte_count_dws_upper,       // Байт 3: Количество байтов (старшие биты)\n                    requester_id,               // Байт 4-5: ID запрашивающего (из оригинального MRd)\n                    tag,                        // Байт 6: Тег (из оригинального MRd)\n                    byte_count_dws_lower,       // Байт 7: Количество байтов (младшие биты)\n                    completion_id,              // Байт 8-9: ID завершения (ваш BDF)\n                    lower_address_from_request  // Байт 10-11: Младший адрес из запроса\n                    // ...затем фактическая полезная нагрузка данных\n                };\n                m_axis_tx_tvalid_reg = 1'b1;\n                m_axis_tx_tlast_reg = 1'b1; // Последний сегмент TLP\n                // ... переход состояния для ожидания tready\n            end\n            ```\n        *   **Примечание**: Фактическая реализация включает конечные автоматы, FIFO и соответствие протоколу AXI-Stream для IP-ядра PCIe. Фреймворк PCILeech-FPGA уже предоставляет хорошую основу для этого, но вам может потребоваться расширить или изменить его для очень специфического поведения TLP-пакетов.\n\n    3.  **Обработка приема TLP (для входящих TLP-пакетов)**:\n        *   Реализуйте логику для анализа входящих TLP-пакетов с интерфейса приема ядра PCIe (например, `s_axis_rx_tdata`, `s_axis_rx_tvalid`).\n        *   Этот анализ включает:\n            *   Проверку `s_axis_rx_tvalid`, чтобы узнать, присутствует ли TLP.\n            *   Чтение полей `Fmt` и `Type` из заголовка TLP, чтобы определить его назначение.\n            *   Извлечение соответствующих полей, таких как `Requester ID`, `Tag`, `Address`, `Length` и `Data Payload`.\n        *   Используйте операторы `case` или блоки `if/else if` на основе типа TLP-пакета, чтобы маршрутизировать информацию к соответствующей внутренней логике (например, `bar_controller` для записей в память, модуль конфигурации для записей конфигурации).\n        *   **Пример (концептуальный, упрощенный парсинг):**\n            ```verilog\n            // В pcileech_pcie_tlp_a7.sv или модуле парсера TLP\n            input wire [127:0] s_axis_rx_tdata;\n            input wire s_axis_rx_tvalid;\n            output wire s_axis_rx_tready; // Должен быть установлен для приема дополнительных данных\n\n            reg [7:0] received_tlp_fmt_type;\n            reg [15:0] received_requester_id;\n            // ... объявить другие разобранные поля\n\n            assign s_axis_rx_tready = 1'b1; // Всегда готов к приему для простоты, управляйте обратным давлением в реальном проекте\n\n            always @(posedge clk) begin\n                if (s_axis_rx_tvalid) begin\n                    received_tlp_fmt_type = s_axis_rx_tdata[127:120]; // Предполагается, что это старшие биты\n                    received_requester_id = s_axis_rx_tdata[111:96]; // Пример смещения\n\n                    // Декодирование на основе типа TLP\n                    case (received_tlp_fmt_type[3:0]) // Только биты типа TLP\n                        4'h0: // Запись в память (3DW или 4DW в зависимости от Fmt)\n                            // Извлечь адрес, длину, полезную нагрузку и передать контроллеру BAR\n                            begin\n                                // Передать контроллеру BAR для записи в эмулируемую память\n                                // bar_write_enable = 1'b1;\n                                // bar_write_address = s_axis_rx_tdata[...];\n                                // bar_write_data = s_axis_rx_tdata[...];\n                            end\n                        4'h1: // Чтение памяти\n                            // Извлечь адрес, длину и передать контроллеру BAR для чтения\n                            begin\n                                // bar_read_enable = 1'b1;\n                                // bar_read_address = s_axis_rx_tdata[...];\n                                // (Завершение будет сгенерировано контроллером BAR)\n                            end\n                        // ... другие типы TLP\n                        default: begin\n                            // Обработка неподдерживаемых или зарезервированных типов TLP (например, логирование, ошибка)\n                        end\n                    endcase\n                end\n            end\n            ```\n\n    4.  **Обеспечьте соответствие**:\n        *   Строго проверяйте, что как ваши сгенерированные, так и проанализированные TLP-пакеты соответствуют спецификации PCIe в отношении формата, определений полей и временных характеристик. Отклонения приведут к сбоям связи.\n\n    5.  **Реализуйте обработку завершений**:\n        *   Для запросов на чтение памяти (MRd) и запросов на чтение конфигурации (CfgRd), полученных от хоста, ваше устройство обязано отправить обратно соответствующие TLP-пакеты завершения (CplD для данных, Cpl для без данных) в течение определенного временного окна. Модуль `bar_controller` (Раздел 8.2.2) — это место, где находится эта логика для чтения BAR.\n\n    6.  **Сохраните изменения**:\n        *   Сохраните файлы (`pcileech_pcie_tlp_a7.sv`, `pcileech_tlps128_bar_controller.sv` или любые пользовательские модули) после реализации изменений.\n\n#### **10.2.2. Обработка различных типов TLP**\n\nКаждый тип TLP имеет специфический формат заголовка и поведение. Ваша прошивка должна уметь обрабатывать те, которые имеют отношение к вашему устройству-донору.\n\n*   **Запросы на чтение памяти (MRd)**:\n    *   **Реализация**:\n        *   При получении TLP-пакета MRd (разобранного `pcileech_pcie_tlp_a7.sv` и перенаправленного в `bar_controller`), `bar_controller` должен:\n            *   Разобрать запрошенный адрес и длину.\n            *   Получить данные из соответствующего внутреннего местоположения памяти (например, BRAM, подключенного к BAR) или внутреннего регистра.\n            *   Собрать TLP-пакет **завершения с данными (CplD)**. Крайне важно, чтобы этот TLP-пакет включал исходный `Requester ID`, `Tag` и `Completion ID` (BDF вашего устройства) из запроса MRd, а также полученную полезную нагрузку данных.\n            *   Отправить TLP-пакет CplD обратно хосту через интерфейс передачи IP-ядра PCIe.\n\n*   **Запросы на запись в память (MWr)**:\n    *   **Реализация**:\n        *   При получении TLP-пакета MWr, `bar_controller` должен:\n            *   Разобрать целевой адрес, длину и `Byte Enables` (FBE/LBE).\n            *   Извлечь `data payload` (полезную нагрузку данных).\n            *   Записать данные в указанное местоположение памяти внутри вашего эмулируемого устройства (например, BRAM или внутренние регистры), соблюдая байтовые разрешения.\n        *   Записи в память являются \"постированными транзакциями\", что означает, что они не требуют TLP-пакета завершения для подтверждения, если только не возникает ошибка.\n\n*   **Запросы на чтение/запись конфигурации (CfgRd/CfgWr)**:\n    *   **Реализация**:\n        *   Эти TLP-пакеты нацелены на пространство конфигурации устройства (Vendor ID, Device ID, BAR, Capabilities и т.д.). IP-ядро Xilinx PCIe автоматически обрабатывает большинство стандартных доступов к пространству конфигурации на основе своей конфигурации.\n        *   Однако, если у вас есть пользовательские регистры или расширенные возможности *внутри* пространства конфигурации, которые не являются стандартными, вам может потребоваться специальная логика для:\n            *   Для CfgRd: Возврата запрошенных данных из ваших внутренних `cfg_` регистров.\n            *   Для CfgWr: Обновления ваших внутренних `cfg_` регистров или запуска действий на основе записанных данных.\n        *   Чтения конфигурации требуют **завершения с данными (CplD)**, в то время как записи конфигурации требуют **завершения без данных (Cpl)**.\n\n*   **Сообщения, определяемые поставщиком (VDM)**:\n    *   **Реализация**:\n        *   Если ваше устройство-донор использует VDM, это требует специализированной логики анализа и ответа.\n        *   **Анализ входящих VDM**: Идентифицируйте VDM на основе их полей `Fmt` и `Type`. Извлеките данные, специфичные для поставщика, и интерпретируйте их в соответствии с вашими результатами обратного инжиниринга.\n        *   **Создание исходящих VDM**: Создайте логику для сборки VDM с точными форматами заголовка и полезной нагрузки, специфичными для поставщика, когда ваше эмулируемое устройство должно их отправить.\n\n#### **10.2.3. Проверка временных характеристик и последовательности TLP**\n\nДаже если TLP-пакеты идеально отформатированы, некорректное время или последовательность приведут к сбою устройства или обнаружению его как несоответствующего.\n\n*   **Шаги**:\n\n    1.  **Использование инструментов симуляции**:\n        *   **Тестовые стенды**: Разработайте комплексные тестовые стенды SystemVerilog для ваших модулей генерации и анализа TLP-пакетов.\n        *   Имитируйте различные сценарии (например, хост отправляет MRd, ваше устройство отправляет CplD; хост отправляет MWr; хост перечисляет устройство), чтобы убедиться, что TLP-пакеты правильно формируются, передаются, принимаются и обрабатываются.\n        *   Проверьте последовательность TLP-пакетов и убедитесь, что завершения отправляются в разумные сроки.\n\n    2.  **Мониторинг с помощью ILA (встроенного логического анализатора)**:\n        *   Как подробно описано в Разделе 12.1, вставьте ядро ILA в ваш проект Vivado.\n        *   Подключите пробники ILA к интерфейсам AXI-Stream IP-ядра PCIe (например, `s_axis_rx_tdata`, `s_axis_rx_tvalid`, `m_axis_tx_tdata`, `m_axis_tx_tready`).\n        *   Установите триггеры для захвата конкретных TLP-пакетов (например, на `m_axis_tx_tvalid` для определенного типа TLP).\n        *   Это позволяет вам видеть фактические биты TLP-пакетов на FPGA в реальном времени во время работы оборудования, проверяя, отправляет/принимает ли ваша прошивка правильные данные и управляющие сигналы к/от IP-ядра PCIe.\n\n    3.  **Проверка временных ограничений**:\n        *   IP-ядро PCIe имеет строгие требования к временным характеристикам своих интерфейсов AXI-Stream. Убедитесь, что ваша пользовательская логика, предоставляющая данные `m_axis_tx_tdata` и обрабатывающая `s_axis_rx_tdata`, соответствует этим временным ограничениям.\n        *   Отчеты Vivado по временному анализу (после синтеза и реализации) отметят любые нарушения. Устраните их путем оптимизации вашей логики или корректировки тактовых сигналов, где это возможно.\n\n    4.  **Тестирование на соответствие (Продвинутое)**:\n        *   Для высокоточной эмуляции рассмотрите возможность использования специализированного набора тестов на соответствие PCIe (часто интегрированного с высококлассными анализаторами протокола). Эти тесты систематически проверяют соблюдение спецификации PCIe, выявляя тонкие нарушения протокола.\n\n    5.  **Сохраните изменения**:\n        *   Сохраните все измененные файлы после тщательного тестирования и проверки. Итерации являются ключевыми при отладке на уровне TLP.\n\n---\n\n## **Часть 3: Продвинутые методы и оптимизация**\n\n---\n\n## **11. Сборка, прошивка и тестирование**\n\nПосле завершения всех настроек наступает момент истины: сборка прошивки, программирование ее на вашу FPGA и тщательное тестирование ее функциональности, чтобы убедиться, что она ведет себя точно так же, как устройство-донор. Этот этап переводит ваш проект из кода в работающую аппаратную эмуляцию.\n\n### **11.1. Синтез и реализация**\n\nЭто основные шаги в процессе проектирования FPGA, где ваш высокоуровневый код SystemVerilog преобразуется в низкоуровневую аппаратную конфигурацию, которая может быть загружена на FPGA.\n\n#### **11.1.1. Запуск синтеза**\n\nСинтез — это процесс, в ходе которого Vivado преобразует ваш HDL-код в логическую схему на уровне вентилей (описание логических вентилей и их взаимосвязей). Он также выполняет предварительный анализ временных характеристик и оценку ресурсов.\n\n*   **Шаги**:\n    1.  **Начните синтез**:\n        *   В графическом интерфейсе Vivado, на панели **Flow Navigator** (обычно слева), в разделе \"Synthesis\", нажмите **Run Synthesis**.\n    2.  **Отслеживайте прогресс**:\n        *   Vivado откроет диалоговое окно \"Launch Runs\". Обычно можно просто нажать \"OK\".\n        *   Следите за вкладкой **Messages** в нижней части окна Vivado. Там будет отображаться ход выполнения синтеза.\n        *   **Распространенные предупреждения/ошибки, на которые следует обратить внимание**:\n            *   **`[Synth 8-327]` Неподключенные порты / Неиспользуемые входы**: Указывает на то, что сигнал или порт в вашем проекте ни к чему не подключены. Хотя иногда это намеренно (например, неиспользуемые контакты на FPGA), они также могут указывать на опечатки в именах портов или забытые соединения. Изучите каждый, чтобы убедиться, что это не функциональная проблема.\n            *   **`[Synth 8-256]` Регистры/провода не оптимизированы**: Это может указывать на неправильное определение логики или наличие избыточной логики, которую можно оптимизировать.\n            *   **Синтаксические ошибки**: Если в вашем коде SystemVerilog есть фатальные синтаксические ошибки, синтез немедленно завершится сбоем. Исправьте их в Visual Studio Code.\n    3.  **Просмотрите отчет о синтезе**:\n        *   После успешного завершения Vivado спросит, что делать дальше. Выберите **Open Synthesized Design** или **Open Report**.\n        *   Критически важно просмотреть **Utilization Summary** в отчете о синтезе. Это показывает, сколько ресурсов FPGA (LUT, Flip-Flops, BRAM, DSP) потребляет ваш проект. Убедитесь, что проект соответствует емкости вашей целевой FPGA (например, для Artix-7 35T вы должны находиться в пределах ее ограничений).\n\n#### **11.1.2. Запуск реализации**\n\nРеализация — самый трудоемкий шаг. Он берет синтезированный список соединений и физически отображает его на ресурсы FPGA (размещая логические блоки, трассируя соединения), а затем выполняет детальный анализ временных характеристик, чтобы убедиться, что проект может работать на заданных тактовых частотах.\n\n*   **Шаги**:\n    1.  **Начните реализацию**:\n        *   После успешного синтеза, на панели **Flow Navigator**, в разделе \"Implementation\", нажмите **Run Implementation**.\n        *   Подтвердите диалоговое окно \"Launch Runs\".\n    2.  **Отслеживайте прогресс**:\n        *   Реализация состоит из нескольких фаз: Opt Design, Power Opt Design, Place Design, Post-Placement Phys Opt Design, Route Design, Post-Route Phys Opt Design. Каждая фаза может занимать значительное количество времени.\n        *   Следите за вкладкой **Messages** для отслеживания прогресса и потенциальных проблем.\n    3.  **Анализируйте временные отчеты**:\n        *   Это *самый важный шаг* после реализации. По завершении Vivado снова спросит, что делать дальше. Выберите **Open Implemented Design** или, что более важно, **Open Report**, а затем выберите **Report Timing Summary**.\n        *   **Убедитесь, что все временные ограничения соблюдены.** Ищите значения \"WNS (Worst Negative Slack)\".\n            *   **Положительный WNS**: Указывает на то, что все временные пути соответствуют своим требованиям (slack означает, что у вас есть дополнительное время). Это то, что вы хотите.\n            *   **Отрицательный WNS**: Указывает на **нарушения временных характеристик**, что означает, что ваш дизайн не может работать на желаемой тактовой частоте или данные могут быть нестабильными. **Это критическая проблема, которую *необходимо* устранить.**\n        *   **Устранение нарушений**:\n            *   Если у вас отрицательный запас по времени, исследуйте конкретные пути, которые не проходят. Отчет о временных характеристиках Vivado покажет вам источник, назначение и компоненты неисправных путей.\n            *   Решения могут включать:\n                *   Оптимизация вашего HDL-кода для уменьшения глубины логики или задержек критических путей.\n                *   Добавление стадий конвейера (регистров) для разбиения длинных комбинационных путей.\n                *   Уточнение вашего XDC-файла (ограничений), убедившись, что все тактовые сигналы правильно определены и распространяются.\n                *   Настройка тактовых частот (если позволяет приложение).\n                *   Использование более быстрых стратегий временного закрытия в Vivado.\n                *   Обеспечение правильного взаимодействия вашей пользовательской логики с временными требованиями интерфейса AXI-Stream ядра PCIe.\n    4.  **Проверка размещения (необязательно)**:\n        *   В реализованном проекте вы можете открыть представление \"Device\", чтобы увидеть, как ваша логика была размещена на FPGA. Это, как правило, для продвинутых пользователей, чтобы убедиться, что критически важные компоненты размещены оптимально (например, близко к трансиверам PCIe).\n\n#### **11.1.3. Генерация битстрима**\n\nБитстрим — это окончательный, двоичный файл конфигурации (расширение `.bit`), который будет загружен на вашу FPGA. Это кульминация синтеза и реализации.\n\n*   **Шаги**:\n    1.  **Сгенерируйте битстрим**:\n        *   После успешной реализации (без критических нарушений временных характеристик), на панели **Flow Navigator**, в разделе \"Program and Debug\", нажмите **Generate Bitstream**.\n    2.  **Дождитесь завершения**:\n        *   Этот процесс обычно занимает меньше времени, чем реализация, но все еще может варьироваться в зависимости от сложности проекта.\n    3.  **Просмотрите журнал генерации битстрима**:\n        *   По завершении Vivado укажет на успех. Просмотрите журнал на наличие предупреждений, хотя обычно, если реализация прошла чисто, генерация битстрима тоже пройдет.\n        *   Файл `.bit` будет сгенерирован в каталоге вашего проекта `pcileech_squirrel_top.runs/impl_1/` (или аналогичном пути для вашей платы).\n\n### **11.2. Прошивка битстрима**\n\nПрограммирование (прошивка) битстрима загружает ваш скомпилированный дизайн на FPGA, делая ваше эмулируемое устройство активным.\n\n#### **11.2.1. Подключение устройства FPGA**\n\n*   **Шаги**:\n    1.  **Подготовьте оборудование**:\n        *   Убедитесь, что ваша DMA-плата на базе FPGA правильно установлена в совместимый слот PCIe на вашей хост-системе.\n        *   Подключите JTAG-программатор (например, Digilent HS3, Xilinx Platform Cable) к JTAG-разъему на вашей плате FPGA и к USB-порту вашего компьютера разработчика.\n        *   Включите хост-систему.\n        *   Обратитесь к руководству вашей конкретной платы FPGA для получения точных инструкций по питанию, JTAG и подключению PCIe.\n    2.  **Откройте Hardware Manager**:\n        *   В Vivado перейдите в **Flow Navigator > Program and Debug > Open Hardware Manager**.\n        *   Если Vivado не запущен, вы можете запустить Hardware Manager как отдельное приложение.\n\n#### **11.2.2. Программирование FPGA**\n\n*   **Шаги**:\n    1.  **Подключитесь к цели**:\n        *   В окне Hardware Manager нажмите **Open Target** (часто большая кнопка или ссылка) и выберите **Auto Connect**.\n        *   Vivado должен автоматически обнаружить ваш JTAG-программатор, а затем подключенные устройства FPGA в цепочке JTAG. Если обнаружение не удалось, проверьте соединения JTAG-кабеля, питание платы и драйверы JTAG на вашем ПК.\n    2.  **Программирование устройства**:\n        *   Как только ваше устройство FPGA будет обнаружено и отображено в окне Hardware, **щелкните правой кнопкой мыши** по вашему устройству FPGA (например, `xc7a35t_0`) и выберите **Program Device**.\n        *   Появится диалоговое окно. Нажмите кнопку \"...\" рядом с полем \"Bitstream file\" и перейдите к файлу сгенерированного битстрима (например, `pcileech_squirrel_top.runs/impl_1/pcileech_squirrel_top.bit`).\n        *   Нажмите **Program**, чтобы начать прошивку на FPGA.\n        *   Дождитесь завершения процесса программирования. Вы увидите индикатор выполнения.\n\n#### **11.2.3. Проверка программирования**\n\n*   **Шаги**:\n    1.  **Проверьте статус**:\n        *   Убедитесь, что программирование завершилось без ошибок в Vivado's Hardware Manager. Vivado отобразит сообщение об успешном завершении \"Program Device\".\n    2.  **Наблюдайте за светодиодами или индикаторами**:\n        *   Многие платы FPGA имеют светодиодные индикаторы состояния. Успешная операция программирования часто приводит к загоранию или изменению состояния определенного светодиода (например, светодиод \"DONE\"). Это быстрое визуальное подтверждение.\n    3.  **Перезагрузка хост-системы (иногда требуется)**:\n        *   Для корректного распознавания вновь запрограммированного устройства PCIe операционной системой хоста часто требуется перезагрузка системы, особенно в Windows, чтобы запустить полный процесс перечисления PCIe.\n\n### **11.3. Тестирование и проверка**\n\nПосле программирования решающим шагом является проверка того, что ваше эмулируемое устройство правильно обнаруживается хостом и что оно функционирует, как ожидается, имитируя устройство-донор.\n\n#### **11.3.1. Проверка перечисления устройства**\n\nЭто подтверждает, что ОС хоста видит вашу FPGA как устройство-донор на основе запрограммированных вами идентификаторов.\n\n*   **Windows**:\n    *   **Шаги**:\n        1.  **Откройте диспетчер устройств**: Нажмите `Win + X` и выберите **Диспетчер устройств** из меню быстрого доступа.\n        2.  **Проверьте свойства устройства**:\n            *   Посмотрите в соответствующей категории устройств (например, **Сетевые адаптеры**, **Контроллеры хранилищ**, **Системные устройства**).\n            *   Найдите свое эмулируемое устройство. Теперь оно должно отображаться с *именем устройства-донора* (например, \"Intel(R) Ethernet Connection...\").\n            *   Щелкните правой кнопкой мыши по устройству, выберите **Свойства** и перейдите на вкладку **Сведения**.\n            *   В выпадающем списке \"Свойство\" выберите \"ИД оборудования\". Убедитесь, что **Device ID (DID)** и **Vendor ID (VID)** (например, `PCI\\VEN_ABCD&DEV_1234`) совпадают с теми, что вы запрограммировали в свою прошивку.\n            *   Также проверьте \"Class Code\" и \"Subsystem ID\" для дальнейшей проверки.\n*   **Linux**:\n    *   **Шаги**:\n        1.  **Используйте `lspci`**: Откройте терминал и используйте команду `lspci`.\n            ```bash\n            lspci -nn # Показывает VendorID:DeviceID\n            lspci -vvv # Показывает подробные сведения, включая BAR, возможности и многое другое\n            ```\n        2.  **Проверьте список устройств**:\n            *   Убедитесь, что эмулируемое устройство отображается в выводе `lspci` с правильными Vendor ID, Device ID и Class Code.\n            *   **Пример вывода (эмуляция сетевой карты Intel):**\n                ```\n                03:00.0 Network controller [0280]: Intel Corporation Ethernet Connection I219-V [8086:1570] (rev 21)\n                ```\n                (`8086` — Vendor ID Intel, `1570` — Device ID для I219-V, `0280` — Class Code сетевого контроллера).\n            *   Используйте `lspci -vvv`, чтобы убедиться, что BAR перечисляются с правильными размерами и типами, соответствующими конфигурации вашего устройства-донора.\n\n#### **11.3.2. Тестирование функциональности устройства**\n\nКак только устройство перечислено, окончательной проверкой является то, функционирует ли оно как оригинал.\n\n*   **Шаги**:\n    1.  **Установите необходимые драйверы**:\n        *   Если ОС хоста не загружает автоматически подходящий драйвер, вам потребуется вручную установить официальные драйверы для вашего устройства-донора. Загрузите их с веб-сайта производителя.\n        *   Установите их в соответствии с инструкциями производителя. Если эмуляция прошла успешно, драйвер должен установиться и распознать вашу FPGA как реальное оборудование.\n    2.  **Выполните функциональные тесты**:\n        *   Запустите приложения или утилиты, которые обычно взаимодействуют с устройством-донором.\n        *   **Примеры**:\n            *   **Сетевая карта**: Выполните тесты ping, просмотрите веб-страницы или инициируйте большие передачи файлов для проверки пропускной способности.\n            *   **Контроллер хранилища**: Попробуйте отформатировать имитированный диск (если ваша эмуляция включает функции хранения), выполните операции чтения/записи или запустите тесты производительности диска.\n            *   **USB-контроллер**: Подключите USB-устройства (если ваша эмуляция включает функциональность USB-хоста) и проверьте их обнаружение и работу.\n        *   Отслеживайте хост-систему на предмет ожидаемого поведения и характеристик производительности.\n    3.  **Мониторинг поведения системы**:\n        *   Проверьте стабильность системы (отсутствие BSOD в Windows, паник ядра в Linux).\n        *   Ищите ошибки, специфичные для устройства, в системных журналах (Просмотр событий в Windows, `dmesg` или `journalctl` в Linux).\n        *   Убедитесь, что эмулируемое устройство ведет себя, как ожидается, при различных нагрузках, включая интенсивные передачи данных или стресс-тесты.\n\n#### **11.3.3. Мониторинг ошибок**\n\nАктивный мониторинг ошибок крайне важен для выявления тонких проблем эмуляции, которые могут не вызывать немедленных сбоев.\n\n*   **Windows**:\n    *   **Шаги**:\n        1.  **Проверьте Просмотр событий**: Нажмите `Win + X` и выберите **Просмотр событий**.\n        2.  **Ищите ошибки, связанные с PCIe**: Перейдите в **Журналы Windows > Система**. Отфильтруйте или найдите предупреждения, ошибки или критические события, связанные с \"PCIe\", \"PCI Express\" или события, исходящие от конкретного драйвера устройства (ищите имена источников, соответствующие драйверу вашего эмулируемого устройства).\n            *   Распространенные ошибки включают конфликты ресурсов, сбои инициализации драйвера или неожиданные ответы устройства.\n*   **Linux**:\n    *   **Шаги**:\n        1.  **Проверьте журналы `dmesg`**: Откройте терминал и введите:\n            ```bash\n            dmesg | grep -i pci # Регистронезависимый поиск сообщений pci\n            dmesg | grep -i <VendorID> # Фильтр по Vendor ID вашего устройства\n            ```\n        2.  **Выявите проблемы**: Ищите сообщения, указывающие на проблемы с обучением канала PCIe, инициализацией устройства, сбои выделения памяти или ошибки при проверке драйвера, или неожиданную активность DMA. Подсистема PCIe ядра Linux довольно многословна.\n    *   **Журнал Systemd (современный Linux)**:\n        ```bash\n        journalctl -b | grep -i pci # Журнал текущей загрузки\n        ```\n\n---\n\n## **12. Продвинутые методы отладки**\n\nКогда возникают проблемы, особенно в сложной эмуляции устройств PCIe, базового устранения неполадок может быть недостаточно. Продвинутые инструменты и методы отладки обеспечивают глубокую видимость внутренней логики FPGA и шины PCIe, позволяя эффективно выявлять и устранять проблемы.\n\n### **12.1. Использование встроенного логического анализатора Vivado (ILA)**\n\nВстроенный логический анализатор (ILA) — это мощное, настраиваемое отладочное IP-ядро, предоставляемое Xilinx, которое можно встраивать непосредственно в ваш проект FPGA. Оно позволяет отслеживать поведение внутренних сигналов FPGA (проводов и регистров) в реальном времени без необходимости внешнего зондирующего оборудования, функционируя как мощный внутренний осциллограф или логический анализатор.\n\n#### **12.1.1. Вставка ядер ILA**\n\n*   **Шаги**:\n    1.  **Спланируйте ваши пробники**: Определите ключевые сигналы, которые вам необходимо наблюдать. Для эмуляции PCIe это часто включает:\n        *   Интерфейсы AXI-Stream IP-ядра PCIe (например, `s_axis_rx_tdata`, `s_axis_rx_tvalid`, `m_axis_tx_tdata`, `m_axis_tx_tready`).\n        *   Сигналы внутреннего конечного автомата (`current_state`, `next_state`).\n        *   Выходы декодирования адресов BAR (`bar_hit[0]`, `bar_hit[1]`).\n        *   Значения пользовательских регистров (`custom_control_reg`, `custom_status_reg`).\n        *   Сигналы запросов на прерывание (`msi_trigger_signal`).\n    2.  **Добавьте IP-ядро ILA**:\n        *   В Vivado откройте **IP Catalog** (обычно на панели **Flow Navigator**).\n        *   Найдите \"ILA\" (Integrated Logic Analyzer).\n        *   Дважды щелкните по \"Debug Bridge\" (для базового ILA) или \"Integrated Logic Analyzer (ILA)\", чтобы открыть его графический интерфейс настройки.\n        *   Настройте ILA:\n            *   Установите **Number of Capture Data Ports** (пробников), которые вам нужны.\n            *   Установите **Width** каждого пробника, чтобы он соответствовал сигналам, которые вы планируете подключить.\n            *   Настройте **Sample Depth** (сколько образцов хранить до/после триггера). Большая глубина потребляет больше BRAM.\n            *   Нажмите \"OK\" и позвольте Vivado сгенерировать IP.\n    3.  **Создайте экземпляр и подключите сигналы**:\n        *   Vivado сгенерирует файл `.xci` для ILA. Вы можете создать его экземпляр непосредственно в вашем SystemVerilog-файле верхнего уровня (например, `pcileech_squirrel_top.sv`) или в модуле, где доступны интересующие сигналы.\n        *   **Пример (в `pcileech_squirrel_top.sv` или подмодуле):**\n            ```verilog\n            // Предполагается, что вы сгенерировали ila_0 из IP Catalog\n            // Подключите к тактовому сигналу и интересующим сигналам вашего проекта\n            ila_0 your_ila_instance (\n                .clk(clk_125mhz), // Подключите к стабильному тактовому сигналу в вашем проекте, обычно к пользовательскому тактовому сигналу PCIe\n                .probe0(pcie_s_axis_rx_tdata),    // Пример: входящие данные TLP PCIe\n                .probe1(pcie_s_axis_rx_tvalid),   // Пример: входящий TLP PCIe действителен\n                .probe2(pcie_m_axis_tx_tdata),    // Пример: исходящие данные TLP PCIe\n                .probe3(my_bar_controller_state), // Пример: состояние логики вашего BAR\n                .probe4(my_custom_register),      // Пример: значение пользовательского регистра\n                // Добавьте больше пробников по мере необходимости\n                .probeN(signal_to_monitor_N)\n            );\n            ```\n        *   **Альтернатива (пометка для отладки):** Для более простых сигналов иногда можно пометить их непосредственно в вашем HDL-коде для отладки. Используйте `(* mark_debug = \"true\" *) wire my_signal;` или `(* mark_debug = \"true\" *) reg my_register;`. Vivado затем автоматически предложит добавить их в ILA.\n\n#### **12.1.2. Настройка условий срабатывания**\n\nILA наиболее мощен, когда вы настраиваете интеллектуальные условия срабатывания для точного захвата данных при возникновении интересующего события (например, ошибки, определенного типа TLP, перехода состояния).\n\n*   **Шаги**:\n    1.  **Сгенерируйте битстрим с ILA**: После вставки и подключения ILA вы должны запустить синтез, реализацию и сгенерировать новый битстрим. Ядро ILA потребляет ресурсы FPGA и будет встроено в ваш проект.\n    2.  **Откройте Hardware Manager**: Программируйте свою FPGA битстримом с включенным ILA (Раздел 11.2). Затем в Vivado откройте Hardware Manager и подключитесь к вашей цели.\n    3.  **Доступ к панели ILA**: В Hardware Manager выберите ваш экземпляр ILA (например, `hw_ila_1`). Откроется панель ILA.\n    4.  **Определите триггеры**:\n        *   Выберите пробники, которые вы хотите использовать в качестве входных данных триггера.\n        *   Установите конкретные **шаблоны триггеров** (например, `0x4A` для `pcie_s_axis_rx_tdata`, чтобы сработать при TLP завершения).\n        *   Настройте **условия триггера** (например, \"равно\", \"не равно\", \"положительный фронт\", \"отрицательный фронт\").\n        *   Установите **позиции триггера** (сколько образцов захватить *до* события триггера, для предварительной видимости).\n        *   Вы можете настроить несколько последовательностей триггеров для сложного обнаружения событий.\n        *   **Пример сценариев для триггеров**:\n            *   Триггер по определенному `Fmt/Type` в полученном TLP для анализа входящих команд.\n            *   Триггер, когда определенный регистр (`my_custom_register`) достигает определенного значения.\n            *   Триггер по `pcie_m_axis_tx_tvalid` И `pcie_m_axis_tx_tdata[3:0]` == `4'hC` (для TLP записи в память) для анализа исходящих записей.\n            *   Триггер по активации сигнала ошибки.\n\n#### **12.1.3. Захват и анализ данных**\n\n*   **Шаги**:\n    1.  **Запустите проект**: Позвольте вашей хост-системе взаимодействовать с запрограммированной FPGA, вызывая события, которые вы хотите отладить.\n    2.  **Взведите ILA**: На панели ILA нажмите кнопку **Run Trigger** (часто зеленая иконка \"Play\"). ILA будет ждать определенного условия срабатывания.\n    3.  **Захватите данные**: Как только условие срабатывания будет выполнено, ILA захватит снимок сигналов в свой внутренний буфер памяти.\n    4.  **Анализируйте формы сигналов**:\n        *   Захваченные данные появятся в окне просмотра форм сигналов.\n        *   Изучите поведение сигнала во времени. Увеличивайте масштаб, добавляйте курсоры и декодируйте значения.\n        *   Ищите:\n            *   **Неожиданные переходы**: Сигналы, изменяющиеся в неподходящее время.\n            *   **Некорректные значения**: Регистры, содержащие неверные данные.\n            *   **Нарушения протокола**: Ваша логика отправляет некорректные данные по интерфейсам PCIe.\n            *   **Проблемы с временными характеристиками**: Если сигналы не стабильны в ожидаемое время (хотя полный временной анализ выполняется при реализации, ILA показывает поведение во время выполнения).\n        *   Сравните захваченное поведение с ожидаемой логикой вашего проекта и наблюдаемым поведением устройства-донора (если вы захватывали его с помощью анализатора протокола).\n\n### **12.2. Инструменты анализа трафика PCIe**\n\nВ то время как ILA дает вам внутреннюю видимость FPGA, внешние инструменты анализа трафика PCIe предоставляют непревзойденный обзор фактической связи по шине PCIe *между* вашим эмулируемым устройством и хостом. Это крайне важно для проверки соответствия протоколу и отладки проблем на уровне канала.\n\n#### **12.2.1. Анализаторы протокола PCIe (аппаратные)**\n\n*   **Примеры**:\n    *   **Анализаторы PCIe Teledyne LeCroy**: Золотой стандарт для глубокого анализа, полного декодирования протокола, расширенных функций триггеров и возможностей инъекции ошибок.\n    *   **Анализаторы PCIe Keysight**: Еще один ведущий производитель с аналогичными высококлассными функциями.\n*   **Шаги**:\n    1.  **Настройка анализатора**: Подключите аппаратный анализатор последовательно между слотом PCIe хост-системы и вашим DMA-устройством на базе FPGA. Это обычно включает использование специальной карты-переходника.\n    2.  **Настройка параметров захвата**: Используйте программное обеспечение анализатора для определения трафика, который нужно захватить. Вы можете фильтровать по типу TLP, адресу, Requester ID, условиям ошибок и т.д., чтобы сосредоточиться на соответствующих событиях.\n    3.  **Захват трафика**: Запустите ваше эмулируемое устройство на хосте. Анализатор будет пассивно записывать все транзакции PCIe.\n    4.  **Анализ результатов**:\n        *   Используйте мощное программное обеспечение анализатора для просмотра декодированных TLP-пакетов, списков транзакций и временных диаграмм.\n        *   **Проверьте TLP-пакеты на соответствие и корректность**: Правильны ли все поля? Правильна ли последовательность?\n        *   **Выявите любые нарушения протокола или неожиданное поведение**: Здесь вы найдете причину сбоя драйвера (например, ваше устройство отправляет завершение с данными, когда спецификация требует завершения без данных, или оно отвечает слишком медленно).\n        *   **Сравните с захватами устройства-донора**: Напрямую сравните захваченный трафик с вашего эмулируемого устройства с захватами, которые вы сделали с реального устройства-донора. Это окончательный тест на точность эмуляции.\n\n#### **12.2.2. Программные средства**\n\nДля базовой проверки шины PCIe, или если выделенный аппаратный анализатор недоступен, некоторые программные средства могут предоставить ограниченную информацию.\n\n*   **Примеры**:\n    *   **Wireshark с плагинами PCIe**: Хотя Wireshark в первую очередь предназначен для сетевого трафика, со специализированным оборудованием (например, сетевыми картами, которые предоставляют трассы PCIe ОС, или специфическим оборудованием/драйверами захвата) он иногда может захватывать и декодировать пакеты PCIe. Это сильно зависит от системы.\n    *   **ChipScope Pro (устаревшая Xilinx, теперь часть Vivado)**: Встроенный логический анализатор (ILA) является современным эквивалентом, но ChipScope был отдельным инструментом.\n    *   **`lspci` (Linux)**: Как упоминалось в разделе 11.3.1, `lspci -vvv` предоставляет обширную статическую информацию о пространстве конфигурации. Вы можете объединить его с `watch` или скриптами для отслеживания изменений во времени.\n    *   **Клиент `pcileech` (из фреймворка PCILeech)**: Само клиентское программное обеспечение `pcileech` может выполнять операции чтения/записи в память и пространство конфигурации через вашу FPGA и может использоваться для тестирования базовой функциональности DMA. Хотя это не \"анализатор трафика\", он необходим для тестирования функционального интерфейса.\n*   **Шаги**:\n    1.  **Установите необходимые инструменты/плагины**: Убедитесь, что инструмент установлен и все необходимые драйверы или плагины настроены.\n    2.  **Мониторинг шины PCIe**: Запустите программный инструмент для захвата и отображения информации, связанной с PCIe.\n    3.  **Анализ коммуникаций**:\n        *   Ищите расхождения в конфигурации устройства.\n        *   Если инструмент поддерживает это, анализируйте структуру захваченных пакетов на наличие аномалий или ошибок.\n        *   Убедитесь, что ваше эмулируемое устройство правильно отвечает на запросы конфигурации.\n\n---\n\n## **13. Устранение неполадок**\n\nВ этом разделе приведены решения распространенных проблем, с которыми вы можете столкнуться при разработке пользовательской прошивки, программировании битстрима и аппаратном тестировании вашей эмуляции устройства PCIe. Отладка прошивки может быть сложной, поэтому методический подход является ключевым.\n\n### **13.1. Проблемы с обнаружением устройства**\n\n**Проблема**: Ваше DMA-устройство на базе FPGA, после программирования, не распознается хост-системой, или оно отображается с некорректными ID (например, \"Неизвестное устройство\") или с символом ошибки в Диспетчере устройств/lspci.\n\n#### **Возможные причины и решения**:\n\n1.  **Некорректные Device ID, Vendor ID, Subsystem ID или Class Code**:\n    *   **Причина**: Наиболее распространенная причина. Существует несоответствие между идентификационными значениями, запрограммированными в вашу прошивку FPGA, и тем, что ожидает операционная система хоста, или тем, что вы намереваетесь эмулировать.\n    *   **Решение**:\n        *   **Проверьте**: Дважды проверьте все параметры `cfg_deviceid`, `cfg_vendorid`, `cfg_subsysid`, `cfg_subsysvendorid`, `cfg_revisionid` и `cfg_classcode` в `pcileech_pcie_cfg_a7.sv` (или эквивалентном файле) по отношению к тщательно записанной информации о вашем устройстве-доноре (из Раздела 5).\n        *   **Согласованность**: Убедитесь, что эти значения также последовательно установлены в графическом интерфейсе настройки IP-ядра PCIe Vivado (Раздел 7.2.2).\n        *   **Пересборка и перепрошивка**: После любых изменений всегда проводите повторный синтез, повторную реализацию, генерируйте новый битстрим и перепрошивайте FPGA (Разделы 11.1, 11.2).\n        *   **Перезагрузка хоста**: Всегда перезагружайте хост-систему после прошивки, так как Windows часто требует полной перезагрузки для корректного повторного перечисления устройств PCIe.\n\n2.  **Сбой обучения канала PCIe**:\n    *   **Причина**: Фундаментальный канал PCIe между корневым комплексом хоста и вашей картой FPGA не может быть установлен. Это происходит до любых чтений пространства конфигурации. Симптомы включают полное отсутствие устройства (lspci ничего не показывает на этой шине/слоте, или Диспетчер устройств показывает ошибку \"PCI Express Root Port\").\n    *   **Решение**:\n        *   **Физические соединения**: Убедитесь, что плата FPGA плотно вставлена в слот PCIe и все силовые соединения надежны. Попробуйте другой слот PCIe, если доступен.\n        *   **Питание**: Убедитесь, что плата FPGA получает достаточное питание. Некоторым платам требуются дополнительные разъемы питания PCIe.\n        *   **Скорость/ширина канала**:\n            *   Проверьте настройки `Max Link Speed` и `Link Width` в вашем IP-ядре PCIe Vivado (Раздел 8.1.1).\n            *   Попробуйте установить скорость канала на более низкое поколение (например, Gen1 / 2.5 GT/s) и ширину на x1, даже если ваша плата поддерживает более высокую скорость. Иногда возникают проблемы совместимости с конкретными материнскими платами на более высоких скоростях.\n            *   Проверьте настройки BIOS материнской платы для опций скорости слотов PCIe.\n        *   **Сброс**: Убедитесь, что логика сброса FPGA правильно реализована (например, синхронизирована с опорной тактовой частотой PCIe) и правильно активируется/деактивируется при включении/перезагрузке.\n        *   **IP-ядро PCIe**: Убедитесь, что IP-ядро PCIe правильно инстанциировано и его тактовые сигналы и сбросы правильно подключены в вашем проекте верхнего уровня.\n\n3.  **Проблемы с питанием (недостаточное или нестабильное питание)**:\n    *   **Причина**: Плата FPGA не получает достаточно стабильного питания, или блок питания шумит, что приводит к ненадежной работе.\n    *   **Решение**:\n        *   **Проверьте соединения**: Дважды проверьте все кабели питания (питание основного слота PCIe, дополнительное питание PCIe, внешний разъем постоянного тока, если используется).\n        *   **Блок питания**: Убедитесь, что блок питания вашей хост-системы (PSU) имеет достаточную мощность и стабильные линии 12 В. Для высокомощных FPGA слабый блок питания может вызывать проблемы.\n        *   **Внешнее питание**: Если на плате есть внешний разъем питания, убедитесь, что он используется с правильным напряжением и номинальным током.\n\n4.  **Ошибки прошивки (ранняя стадия)**:\n    *   **Причина**: Логические ошибки в вашем коде SystemVerilog, особенно в модуле верхнего уровня или обертке ядра PCIe, которые препятствуют правильной инициализации или представлению ядра PCIe.\n    *   **Решение**:\n        *   **Сообщения Vivado**: Внимательно изучите журналы синтеза и реализации Vivado на наличие **критических предупреждений** или **ошибок**, связанных с IP-ядром PCIe. Они часто указывают на неправильные конфигурации или неверные соединения.\n        *   **Отладка ILA**: Если канал пытается обучиться, но терпит неудачу, используйте ILA (Раздел 12.1), подключенный к сигналам состояния IP-ядра PCIe (например, `link_up`, `link_speed`, `link_width`) и интерфейсам AXI-Stream, чтобы увидеть, на каком этапе происходит сбой согласования канала или генерирует ли ядро неожиданный трафик.\n\n### **13.2. Ошибки отображения памяти и конфигурации BAR**\n\n**Проблема**: Эмулируемое устройство обнаружено, но когда ОС хоста или драйвер пытается получить доступ к его регистрам или буферам, отображаемым на память (через BAR), происходит сбой, зависание или сообщаются ошибки.\n\n#### **Возможные причины и решения**:\n\n1.  **Неправильные размеры или типы BAR (IP-ядро и прошивка)**:\n    *   **Причина**: Размеры или типы BAR (32-бит/64-бит, Память/Ввод-вывод, Предвыбираемые/Непредвыбираемые), настроенные в вашем IP-ядре PCIe Vivado (Раздел 7.2.2) и/или обрабатываемые в вашем `pcileech_tlps128_bar_controller.sv`, не соответствуют тому, что фактически предоставляет устройство-донор. Это может привести к тому, что хост выделит неправильное адресное пространство или попытается выполнить неподдерживаемые обращения.\n    *   **Решение**:\n        *   **Перепроверка**: Вернитесь к данным Arbor/анализатора протокола (Раздел 5) и повторно проверьте каждую конфигурацию BAR (размер, тип, prefetchable).\n        *   **Согласованность**: Убедитесь, что они идеально совпадают в настройках IP-ядра PCIe, и что ваша логика `bar_controller` правильно обрабатывает размер (диапазон декодирования адресов) и тип каждого BAR.\n        *   **Размер BRAM**: Если ваши BARы отображаются на BRAM, убедитесь, что размеры IP-ядер BRAM (Раздел 8.2.1) точно соответствуют размерам BAR.\n\n2.  **Ошибки декодирования адресов в прошивке**:\n    *   **Причина**: Ваш `pcileech_tlps128_bar_controller.sv` (или пользовательская логика BAR) неправильно интерпретирует входящие адреса PCIe, что приводит к доступу к некорректным внутренним регистрам или ячейкам памяти.\n    *   **Решение**:\n        *   **Просмотрите логику**: Тщательно проверьте операторы `case` и расчеты адресов в вашем `bar_controller`.\n        *   **Симуляция**: Разработайте конкретные тестовые примеры в вашем тестовом стенде SystemVerilog для имитации операций чтения/записи хоста по различным смещениям внутри каждого BAR. Убедитесь, что внутренние сигналы `bar_hit` верны и что данные направляются в/из правильных внутренних регистров/BRAM.\n        *   **Отладка ILA**: Разместите пробники ILA на `req_addr`, `req_write`, `req_read`, `req_data`, `rsp_data` и внутренних сигналах, связанных с декодированием адресов и доступом к регистрам в `bar_controller`. Наблюдайте, как декодируется адрес и какие данные считываются/записываются в реальном времени.\n\n3.  **Перекрывающиеся адресные пространства (внутренние)**:\n    *   **Причина**: Хотя стандарт PCIe гарантирует, что BAR разных устройств не перекрываются в карте памяти хоста, *внутри* вашей FPGA вы можете случайно отобразить разные логические компоненты на одно и то же физическое адресное пространство внутри одного BAR.\n    *   **Решение**:\n        *   **Осторожное отображение**: При определении внутренних регистров и блоков памяти в пределах BAR явно назначайте каждому уникальные, неперекрывающиеся смещения. Используйте `localparam` для этих смещений, чтобы предотвратить ошибки.\n        *   **Просмотр проекта**: Необходим тщательный просмотр вашего `bar_controller`, чтобы убедиться, что каждый диапазон адресов обрабатывается уникальным образом.\n\n4.  **Проблемы с доступом к BRAM**:\n    *   **Причина**: Проблемы с интерфейсом вашей логики к IP-ядрам BRAM (например, некорректная тактовая частота BRAM, асинхронные сбросы, неверные разрешения на запись байтов или некорректная логика разрешения записи).\n    *   **Решение**:\n        *   **Документация BRAM**: Обратитесь к документации IP-ядра BRAM Xilinx для правильного создания экземпляров и сигналов интерфейса.\n        *   **ILA**: Разместите пробники ILA на сигналах интерфейса BRAM (адрес, разрешение на запись, входные данные, выходные данные), чтобы убедиться, что ваша логика отправляет правильные управляющие сигналы BRAM.\n\n### **13.3. Ошибки производительности DMA и TLP**\n\n**Проблема**: Устройство обнаружено и функционально, кажется, работает, но скорость передачи данных низкая, или система испытывает периодические сбои, зависания или ошибки во время больших операций DMA. Анализаторы протокола PCIe сообщают о некорректных TLP или проблемах с управлением потоком.\n\n#### **Возможные причины и решения**:\n\n1.  **Некорректно сформированные TLP-пакеты (заголовок/полезная нагрузка)**:\n    *   **Причина**: Ваша прошивка генерирует TLP-пакеты (особенно завершения или исходящие записи в память, если ваша FPGA действует как мастер DMA) с некорректными заголовками, длинами, разрешениями на байты или полезными нагрузками. Ядро PCIe хост-системы или драйвер обнаруживают их как нарушения.\n    *   **Решение**:\n        *   **Анализатор протокола PCIe**: Это лучший инструмент здесь (Раздел 12.2.1). Захватите трафик и тщательно сравните ваши сгенерированные TLP-пакеты со спецификацией PCIe и, что более важно, с захватами с вашего *реального устройства-донора*.\n        *   **Логика генерации TLP**: Просмотрите ваш код сборки TLP-пакетов (`pcileech_pcie_tlp_a7.sv` и связанные модули). Убедитесь, что все поля (Fmt, Type, Requester ID, Tag, Completion ID, Length, Byte Enables, Address) правильно получены и упакованы в структуру TLP-пакета.\n        *   **Проверка ошибок**: Реализуйте базовую проверку ошибок в вашей прошивке (например, проверку на неожиданный `req_valid` без `req_ready` или наоборот).\n\n2.  **Проблемы с управлением потоком**:\n    *   **Причина**: PCIe использует механизм управления потоком на основе кредитов. Если ваша прошивка (или взаимодействие IP-ядра PCIe с ней) неправильно управляет кредитами, это может привести к взаимоблокировкам, таймаутам или потере пакетов. Симптомы включают \"застопоренный\" канал PCIe, таймауты или низкую пропускную способность.\n    *   **Решение**:\n        *   **Конфигурация IP-ядра PCIe**: Убедитесь, что настройки управления потоком в графическом интерфейсе настройки IP-ядра PCIe Vivado соответствуют вашим ожидаемым шаблонам трафика. Настройки по умолчанию обычно надежны.\n        *   **Обратное давление пользовательской логики**: Ваша пользовательская логика, отправляющая TLP-пакеты в IP-ядро PCIe (интерфейс `m_axis_tx_*`), *должна* учитывать сигнал `m_axis_tx_tready` от IP-ядра. Если `tready` деактивирован, вы *должны* приостановить отправку данных. Невыполнение этого приведет к переполнению буферов ядра.\n        *   **Отладка ILA**: Подключите пробники ILA к сигналам интерфейса управления потоком IP-ядра PCIe и вашей пользовательской логики, чтобы наблюдать, правильно ли работает квитирование `tvalid`/`tready`.\n\n3.  **Неэффективная логика DMA / проблемы с буферизацией**:\n    *   **Причина**: Ваша реализация DMA-движка внутри FPGA (часть, которая считывает/записывает данные из/в память хоста) не оптимизирована, что создает узкие места. Это может включать:\n        *   Отсутствие конвейеризации.\n        *   Неэффективное использование BRAM.\n        *   Задержки из-за задержки доступа к внешней памяти.\n        *   Малые размеры пакетов.\n    *   **Решение**:\n        *   **Конвейеризация**: Разделите длинные комбинационные пути на более мелкие, последовательные стадии с использованием регистров. Это позволяет увеличить тактовую частоту и улучшить пропускную способность.\n        *   **Буферизация**: Используйте FIFOs (буферы \"первым пришел - первым вышел\") для разделения логики отправителя и получателя, сглаживая поток данных и предотвращая задержки.\n        *   **Пакетные передачи**: Используйте возможность PCIe выполнять пакетные чтения/записи для эффективности. Убедитесь, что ваша логика DMA запрашивает и обрабатывает данные в соответствующих размерах пакетов.\n        *   **Пропускная способность памяти**: Убедитесь, что ваши BRAM или внешние интерфейсы памяти DDR способны обеспечивать/потреблять данные достаточно быстро для желаемых скоростей DMA.\n        *   **ILA**: Отслеживайте внутреннее состояние вашего DMA-движка, указатели чтения/записи и сигналы путей данных для выявления узких мест.\n\n4.  **Таймаут завершения / Неподдерживаемый запрос**:\n    *   **Причина**: Хост отправляет запрос (например, MRd, CfgRd), но ваше устройство FPGA не отвечает TLP-пакетом завершения в течение разрешенного периода таймаута, или оно отвечает со статусом ошибки (например, завершение с неподдерживаемым запросом (UR) или прерыванием завершения (CA)).\n    *   **Решение**:\n        *   **Логика ответа**: Убедитесь, что ваш `bar_controller` (для MRd) и `pcileech_pcie_cfg_a7.sv` (для CfgRd к пользовательскому пространству конфигурации) правильно идентифицируют запрос и генерируют соответствующее завершение.\n        *   **Значение таймаута**: Просмотрите ожидаемую задержку завершения вашего устройства-донора. Хотя PCIe определяет таймауты по умолчанию, некоторые драйверы могут быть чувствительны.\n        *   **ILA/Анализатор протокола**: Крайне важны для выяснения *почему* завершение не отправляется или почему оно некорректно. Достигает ли TLP-запрос вообще вашей пользовательской логики? Генерирует ли ваша логика ответ? Успешно ли ядро PCIe отправляет ответ?\n\n---\n\n## **14. Точность эмуляции и оптимизация**\n\nДостижение по-настоящему убедительной эмуляции означает сделать ваше устройство на базе FPGA неотличимым от донора не только по ID, но и по его поведению. Это требует пристального внимания к временным характеристикам, отзывчивости и тонким операционным деталям.\n\n### **14.1. Методы для точной эмуляции временных характеристик**\n\nТочная синхронизация имеет первостепенное значение в аппаратном обеспечении, особенно для высокоскоростных интерфейсов, таких как PCIe. Несоответствия могут привести к таймаутам драйверов, неправильной интерпретации данных или нестабильности системы.\n\n*   **Реализация временных ограничений (файлы XDC)**:\n    *   **Назначение**: Временные ограничения — это инструкции для инструментов синтеза и реализации Vivado, сообщающие им, насколько быстро должен работать ваш проект. Они определяют периоды тактовых импульсов, задержки ввода/вывода и задержки путей.\n    *   **Использование**: Проект PCILeech-FPGA включает файлы XDC (например, `pcileech_squirrel_top.xdc`), которые определяют основные тактовые импульсы (например, `create_clock -name sys_clk_p -period 8.0 [get_ports sys_clk_p]`).\n    *   **Уточнение**: Если ваша эмуляция требует очень специфических внутренних временных характеристик или реагирует на чувствительные ко времени команды, вам может потребоваться добавить дополнительные ограничения для критических путей (`set_max_delay`, `set_input_delay`, `set_output_delay`) в вашей пользовательской логике.\n    *   **Цель**: Убедитесь, что Vivado сообщает **положительный WNS (Worst Negative Slack)** для всех путей после реализации, что указывает на соответствие проекта его временным требованиям.\n\n*   **Использование методов перехода между тактовыми доменами (CDC)**:\n    *   **Назначение**: Проекты PCIe часто включают несколько тактовых доменов (например, пользовательский тактовый сигнал PCIe 125 МГц, отдельный тактовый сигнал для вашей пользовательской логики). Перемещение сигналов между этими доменами асинхронно (без надлежащей синхронизации) может привести к **метастабильности**, вызывая ненадежное поведение.\n    *   **Реализация**: Всегда используйте правильные схемы CDC для сигналов, пересекающих тактовые домены:\n        *   **Двухтриггерные синхронизаторы**: Для однобитовых управляющих сигналов.\n        *   **Асинхронные FIFO (First-In, First-Out)**: Для многобитовых путей данных, обеспечивающие буферизацию и управление потоком между тактовыми доменами.\n        *   **Кодировщики/декодировщики Грея**: Для счетчиков или адресов, пересекающих домены, чтобы гарантировать изменение только одного бита за раз.\n    *   **Инструменты Vivado**: Vivado включает инструменты анализа CDC (например, `report_cdc`), которые могут выявлять потенциальные проблемы метастабильности.\n\n*   **Моделирование поведения устройства с временными моделями**:\n    *   **Расширенные тестовые стенды**: Используйте тестовые стенды SystemVerilog, которые включают реалистичные временные задержки или даже предоставляют временные функциональные модели шины PCIe (BFM).\n    *   **Проверка**: Это позволяет вам наблюдать, как внутреннее состояние вашего эмулируемого устройства и временные характеристики генерации/ответа TLP-пакетов ведут себя в различных условиях, гарантируя их соответствие захваченному поведению устройства-донора.\n\n### **14.2. Динамический отклик на системные вызовы**\n\nДействительно точная эмуляция не просто представляет правильные идентификаторы; она также интеллектуально и динамично реагирует на команды и запросы хост-системы, имитируя поведение реального, активного устройства.\n\n*   **Реализация конечных автоматов для управления устройством**:\n    *   **Назначение**: Разработайте надежные конечные автоматы SystemVerilog, которые управляют режимами работы устройства, обработкой команд и потоком данных.\n    *   **Отзывчивость**: Убедитесь, что конечный автомат переходит логически и быстро в ответ на входящие команды (например, записи в управляющие регистры в BAR, специфические TLP-пакеты).\n    *   **Корректная обработка**: Конечный автомат должен уметь корректно обрабатывать неожиданные или внеочередные запросы, возможно, возвращая TLP-пакет ошибки или просто игнорируя недопустимые команды, вместо сбоя или зависания.\n\n*   **Мониторинг и отклик на команды хоста (помимо простых операций чтения/записи)**:\n    *   **Записи конфигурации**: Помимо первоначального перечисления, драйверы часто записывают данные в регистры пространства конфигурации, чтобы включить функции, установить пороги или очистить биты состояния. Ваша прошивка должна обрабатывать эти записи и соответствующим образом обновлять внутреннее состояние.\n    *   **Команды, специфичные для поставщика**: Как обсуждалось в Разделе 9.2, если устройство-донор имеет проприетарные команды (доступ к которым осуществляется через пользовательские регистры или сообщения, определяемые поставщиком), ваша прошивка должна анализировать эти команды и запускать соответствующее эмулируемое поведение.\n    *   **Команды управления питанием**: Реагируйте на инициированные хостом переходы состояний питания (D0, D1, D3hot и т.д.), включая/отключая внутреннюю логику и подтверждая изменение состояния.\n    *   **Подтверждение прерывания**: Если драйвер хоста подтверждает прерывания записью в определенный регистр, убедитесь, что ваша прошивка может обнаружить это и сбросить внутренний запрос на прерывание.\n\n*   **Оптимизация логики прошивки для повышения отзывчивости**:\n    *   **Уменьшение задержки**: Критически важные пути данных и управляющие пути должны быть оптимизированы для минимизации глубины комбинационной логики и задержек конвейера.\n    *   **Параллелизм**: Используйте присущий FPGA параллелизм для одновременного выполнения нескольких операций, что улучшает пропускную способность и время отклика.\n    *   **Эффективный доступ к памяти**: Оптимизируйте доступ к внутренним BRAM или внешней памяти DDR, чтобы обеспечить доступность данных по мере необходимости для передач DMA или чтения регистров.\n    *   **Аппаратное ускорение**: Для сложных вычислений или манипуляций с данными, которые выполняет устройство-донор, рассмотрите возможность реализации выделенных аппаратных ускорителей на FPGA, вместо попытки выполнять их медленным, программным способом.\n\n---\n\n## **15. Лучшие практики разработки прошивок**\n\nСоблюдение лучших практик в разработке пользовательской прошивки крайне важно для поддержания качества кода, облегчения сотрудничества (при работе в команде), упрощения отладки и обеспечения долгосрочной поддерживаемости и надежности вашего проекта. Это особенно актуально для приложений, чувствительных к безопасности.\n\n### **15.1. Непрерывное тестирование и документирование**\n\n*   **Регулярное, инкрементальное тестирование**:\n    *   **Модульное тестирование**: Тестируйте небольшие, отдельные модули (например, анализатор TLP, блок регистров) изолированно, используя выделенные тестовые стенды.\n    *   **Интеграционное тестирование**: Убедитесь, что различные модули работают вместе корректно.\n    *   **Системное тестирование**: После прошивки выполните сквозные тесты с хост-системой, чтобы убедиться в общей функциональности.\n    *   **Тестируйте рано, тестируйте часто**: Тестируйте прошивку после каждого значительного изменения, независимо от того, насколько оно мало, чтобы выявить проблемы на ранней стадии, когда их легче отладить.\n\n*   **Автоматизированное тестирование (расширенное)**:\n    *   Для сложных проектов реализуйте автоматизированные тестовые скрипты (например, с использованием Python с уровнем аппаратной абстракции) на стороне хоста для многократной проверки функциональности и производительности.\n    *   Рассмотрите возможность интеграции с инструментами непрерывной интеграции (CI) (например, Jenkins, GitLab CI) в командной среде для автоматизации сборок, тестов и статического анализа при каждом коммите кода.\n\n*   **Поддерживайте всеобъемлющую документацию**:\n    *   **Документы по проектированию**: Создавайте и обновляйте документы, описывающие архитектуру вашей прошивки, включая:\n        *   **Блок-схемы**: Иллюстрирующие основные модули и их взаимосвязи.\n        *   **Диаграммы конечных автоматов**: Для всей логики с состоянием.\n        *   **Спецификации интерфейсов**: Подробно описывающие входные/выходные сигналы, временные характеристики и протоколы между модулями.\n        *   **Карты памяти**: Для всех BAR, определяющие адреса регистров, битовые поля и их функциональность.\n    *   **Комментарии к коду**: Используйте четкие, лаконичные комментарии в вашем коде SystemVerilog для объяснения сложной логики, назначения сигналов и любых неочевидных дизайнерских решений.\n    *   **Журнал изменений/сообщения коммитов**: Ведите журнал изменений или используйте подробные сообщения коммитов Git для отслеживания всех модификаций, исправлений ошибок и добавлений функций, объясняя *почему* были внесены изменения.\n    *   **Руководство пользователя**: Для вашей пользовательской прошивки бесценным является простое руководство пользователя, объясняющее, как собирать, прошивать и взаимодействовать с эмулируемым устройством со стороны хоста.\n\n### **15.2. Управление версиями прошивки**\n\nПравильный контроль версий необходим для отслеживания изменений, эффективного сотрудничества (если работаете в команде) и управления выпусками.\n\n*   **Используйте системы контроля версий (VCS)**:\n    *   **Git**: Настоятельно рекомендуется. Используйте Git для управления исходным кодом HDL, файлами ограничений и скриптами проекта.\n    *   **Организуйте репозиторий**: Поддерживайте четкую структуру каталогов (например, отдельные папки для `src`, `xdc`, `ip`, `scripts`, `doc`).\n    *   **Ветви**: Используйте ветви функций для разработки новых возможностей или крупных изменений. Объединяйте обратно в ветку `main` или `develop` после тщательного тестирования.\n    *   **Регулярные коммиты**: Коммитьте часто с атомарными, осмысленными сообщениями коммитов.\n\n*   **Отмечайте выпуски и вехи**:\n    *   **Стабильные версии**: Используйте теги Git (например, `v1.0.0`, `v1.0.1_bugfix`) для отметки стабильных, протестированных версий вашей прошивки. Это облегчает откат или развертывание заведомо работоспособного состояния.\n    *   **Вехи**: Отмечайте значимые вехи разработки (например, \"Базовое перечисление работает\", \"Чтение/запись DMA функционально\").\n\n*   **Стратегия резервного копирования и восстановления**:\n    *   **Облачные репозитории**: Размещайте ваш репозиторий Git на платформах, таких как GitHub, GitLab или Bitbucket. Это обеспечивает резервное копирование вне сайта и облегчает сотрудничество.\n    *   **Локальные резервные копии**: Даже с облачными репозиториями регулярно создавайте локальные резервные копии всего каталога вашего проекта Vivado (который может быть очень большим из-за сгенерированных файлов).\n\n### **15.3. Вопросы безопасности**\n\nРазработка пользовательской прошивки для эмуляции устройств PCIe, особенно способной к прямому доступу к памяти, имеет значительные последствия для безопасности. Эта технология по своей сути является \"двойного назначения\", что означает, что она может использоваться как для законных (например, тестирование оборудования, исследования безопасности), так и для вредоносных целей (например, атаки DMA, обход защиты). **Крайне важно понимать и ответственно управлять этими рисками.**\n\n*   **Двойное назначение и этические последствия**:\n    *   **Этичный хакинг против вредоносного использования**: Четко различайте использование этих знаний для авторизованного тестирования безопасности (red teaming, тестирование на проникновение) и несанкционированной, незаконной деятельности.\n    *   **Ответственное разглашение**: Если вы обнаружите уязвимости, используя эти методы, следуйте рекомендациям по ответственному разглашению.\n    *   **Соблюдение законодательства и лицензий**: Ознакомьтесь и соблюдайте все соответствующие законы, правила и лицензионные соглашения (например, спецификации PCIe-SIG, лицензионные соглашения Xilinx) относительно обратного инжиниринга оборудования и модификации устройств.\n    *   **\"Вооружение\"**: Признайте, что возможность точно эмулировать доверенное оборудование может быть использована для постоянных угроз повышенной сложности (APT) или сложного вредоносного ПО.\n\n*   **Понимание векторов атак (наступательная перспектива)**:\n    *   **Эксфильтрация памяти**: Вредоносное эмулируемое устройство может выполнять операции чтения DMA для доступа к любому физическому адресу памяти, включая конфиденциальные данные в ядре, пользовательских процессах, криптографические ключи или сетевые буферы.\n    *   **Инъекция/модификация памяти**: Вредоносное эмулируемое устройство может выполнять операции записи DMA для произвольного изменения памяти, что позволяет:\n        *   **Повышение привилегий**: Модификация структур данных ядра (например, токенов процессов, SID) для получения прав администратора или системных привилегий.\n        *   **Инъекция кода**: Внедрение вредоносного кода в запущенные процессы или ядро, а затем запуск его выполнения.\n        *   **Обход защитного ПО**: Отключение или подрыв систем обнаружения и реагирования на конечных точках (EDR), антивирусного или брандмауэрного программного обеспечения путем прямого изменения их памяти.\n    *   **Фаззинг и сбои**: Отправка некорректных или не соответствующих спецификации TLP-пакетов/команд для выявления уязвимостей драйверов, что приводит к сбоям системы (BSOD) или потенциально эксплуатируемому повреждению памяти.\n    *   **Манипуляции с прошивкой/BIOS**: В некоторых продвинутых сценариях DMA-устройство может взаимодействовать с SPI-флэш-памятью хоста, содержащей BIOS/UEFI, потенциально для постоянной модификации.\n\n*   **Меры защиты и стратегии смягчения (оборонительная перспектива)**:\n    *   **IOMMU/VT-d/AMD-Vi**: Как отмечалось в Разделе 3.2, эти технологии предназначены для смягчения DMA-атак путем обеспечения защиты памяти для периферийных устройств. **Для законного тестирования вы их отключаете, но в производственных системах они всегда должны быть включены.** Они предотвращают несанкционированный доступ к памяти периферийными устройствами.\n    *   **Защита DMA на уровне ядра (Windows) / Безопасность Thunderbolt (Linux)**: Современные функции ОС специально предназначены для борьбы с DMA-атаками \"холодной загрузки\" (когда злоумышленник подключает вредоносное устройство, пока система выключена или заблокирована). Держите их включенными на производственных системах.\n    *   **Безопасная загрузка (Secure Boot)**: Хотя это не прямая защита DMA, Secure Boot помогает гарантировать, что загружаются только доверенные загрузчики и модули ядра, что снижает вероятность внедрения злоумышленником вредоносных компонентов ядра для обхода DMA-защит.\n    *   **Физическая безопасность**: Самая базовая, но критически важная защита. Если злоумышленник имеет физический доступ к слоту PCIe или порту Thunderbolt, он может обойти многие программные защиты. Обеспечьте безопасный физический доступ к критически важным системам.\n    *   **Укрепление драйверов**: Драйверы должны быть написаны с учетом защиты, строго проверяя все входные данные от оборудования и работая в строгих границах памяти.\n    *   **Укрепление памяти**: Защита памяти на уровне ОС (например, KASLR, DEP, SMAP/SMEP) помогает уменьшить влияние повреждения памяти, но прямая DMA-атака обходит эти защиты.\n    *   **Мониторинг и логирование**: Хотя это сложно на аппаратном уровне, необычная активность DMA или обнаружение неизвестных устройств PCIe должно вызывать оповещения в системах мониторинга безопасности.\n\n*   **Практики безопасного кодирования прошивки**:\n    *   **Валидация входных данных**: Если ваша прошивка принимает какие-либо входные данные (например, через отладочный интерфейс UART или внутренние регистры, записываемые хостом), тщательно проверяйте их, чтобы предотвратить переполнение буфера, переполнение целых чисел или неожиданное поведение.\n    *   **Минимальные привилегии**: Проектируйте логику вашей прошивки так, чтобы она выполняла только те операции, которые абсолютно необходимы для ее функции. Избегайте предоставления ненужных возможностей.\n    *   **Управление состоянием**: Реализуйте надежные конечные автоматы для предотвращения непреднамеренного поведения из-за недопустимых переходов состояний.\n    *   **Отсутствие жестко закодированных секретов**: Избегайте встраивания конфиденциальной информации (например, криптографических ключей, жестко закодированных учетных данных) непосредственно в вашу прошивку, если ее можно легко извлечь.\n    *   **Обнаружение несанкционированного доступа**: Для производственной прошивки рассмотрите возможность реализации механизмов для обнаружения того, была ли сама прошивка изменена или загружены ли несанкционированные конфигурации.\n\n---\n\n## **16. Дополнительные ресурсы**\n\nДля углубления вашего понимания и поддержания актуальности в динамичных областях разработки FPGA, PCIe и аппаратной безопасности обратитесь к следующим ресурсам:\n\n*   **Документация Xilinx (AMD)**: Ваш основной источник всей информации о Vivado и FPGA Xilinx.\n    *   **Главный портал документации**: [https://docs.amd.com/](https://docs.amd.com/) (ранее Xilinx.com/support/documentation).\n    *   **Руководства пользователя Vivado Design Suite**:\n        *   **UG900 - Начало работы**: Необходим для новых пользователей Vivado.\n        *   **UG901 - Синтез логики**: Глубокое погружение в синтез.\n        *   **UG904 - Реализация**: Подробное руководство по размещению и трассировке.\n        *   **UG912 - Справочное руководство по командам Tcl**: Бесценно для написания скриптов.\n        *   **UG939 - Отладка**: Всеобъемлющее руководство по ILA и другим функциям отладки.\n    *   **Руководство пользователя IP-ядра PCI Express**: Крайне важно для понимания IP-ядра PCIe Xilinx (например, **PG054 для встроенного блока PCI Express 7-й серии**). Ищите \"PCI Express\" на портале документации. В нем подробно описаны конфигурация ядра, интерфейсы и ограничения.\n \n    *   *   **Спецификации PCI-SIG**: Определяющий источник стандарта PCIe.\n    *   **Базовая спецификация PCI Express**: Фундаментальный документ. Хотя он не является общедоступным и бесплатным, широко доступны его резюме и обучающие материалы. Обычно информацию можно найти на их веб-сайте: [https://pcisig.com/specifications](https://pcisig.com/specifications) (Примечание: полные спецификации обычно требуют членства в PCI-SIG).\n\n*   **Учебные пособия и платформы для изучения FPGA**:\n    *   **FPGA4Fun**: [http://www.fpga4fun.com/](http://www.fpga4fun.com/) – Классический сайт со множеством практических проектов и учебных пособий по FPGA.\n    *   **Учебные пособия по Verilog/VHDL**:\n        *   **Учебные пособия по Verilog на ASIC World**: [https://www.asic-world.com/verilog/index.html](https://www.asic-world.com/verilog/index.html) – Хороший фундаментальный справочник по Verilog.\n        *   **VHDLwhiz**: [https://www.vhdlwhiz.com/](https://www.vhdlwhiz.com/) – Справочник и учебные пособия по VHDL.\n    *   **Stack Overflow (теги FPGA/Verilog/PCIe)**: [https://stackoverflow.com/questions/tagged/fpga](https://stackoverflow.com/questions/tagged/fpga) – Q&A, управляемый сообществом, для решения конкретных технических проблем.\n\n*   **Инструменты анализа протокола PCIe**:\n    *   **Анализаторы протокола Teledyne LeCroy**: [https://teledynelecroy.com/protocolanalyzer/](https://teledynelecroy.com/protocolanalyzer/) – Изучите их ассортимент высокопроизводительных анализаторов PCIe и программного обеспечения.\n    *   **Программное обеспечение Telescan PE**: [https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software](https://www.teledynelecroy.com/protocolanalyzer/pci-express/telescan-pe-software/resources/analysis-software) – Бесплатный программный инструмент, предоставляющий некоторые функции анализа PCIe (требуется регистрация).\n\n*   **Сообщество и ресурсы PCILeech**:\n    *   Репозиторий `ufrisk/pcileech` на GitHub — это основа проекта. Активно следите за его обновлениями и проблемами.\n    *   Ищите форумы сообщества или Discord-серверы, посвященные PCILeech или аналогичным проектам DMA с открытым исходным кодом.\n\n*   **Аппаратная безопасность и обратный инжиниринг**:\n    *   Книги по аппаратному хакингу, обратному инжинирингу и низкоуровневой эксплуатации систем.\n    *   Конференции, такие как Black Hat, DEF CON, Recon и Troopers, часто включают доклады по атакам на PCIe и DMA.\n    *   Блоги и исследовательские статьи от исследователей безопасности, специализирующихся на аппаратном обеспечении.\n\n---\n\n## **17. Контактная информация**\n\nЕсли вам нужна помощь, у вас есть вопросы или вы хотите сотрудничать по темам, связанным с этим руководством, разработкой прошивок или аппаратной безопасностью, пожалуйста, не стесняйтесь обращаться. Я готов предоставить руководство, помочь в решении сложных проблем или обсудить идеи в деталях.\n\n### **Discord**:\n*   **Пользователь**: [**VCPU**](https://discord.com/users/196741541094621184)\n*   **Ссылка-приглашение на сервер**: [**Присоединиться к Discord-серверу по аппаратному хакингу и разработке прошивок**](https://discord.gg/dS2gDUDQmV)\n\n---\n\n## **18. Поддержка и вклад**\n\nВаша поддержка помогает поддерживать и улучшать это руководство и связанные с ним проекты. Создание и обновление всеобъемлющей технической документации и проектов аппаратного обеспечения с открытым исходным кодом требует значительных временных и трудовых затрат.\n\n### **Пожертвования**\n\nЕсли вы нашли это руководство полезным и хотите поддержать текущую работу, рассмотрите возможность внесения вклада. Каждое пожертвование, независимо от размера, помогает продолжать создавать, делиться и поддерживать сообщество через дальнейшие исследования, разработки и усилия по документированию.\n\n*   **Криптовалютные пожертвования (LTC - Litecoin)**:\n    *   **Адрес**: `MPMyQD5zgy2b2CpDn1C1KZ31KmHpT7AwRi`\n\n**Специальный бонус**: Если вы сделаете пожертвование, пожалуйста, свяжитесь со мной в Discord (VCPU), чтобы получить личную благодарность и, возможно, доступ к дополнительным ресурсам, ранний доступ к новому контенту или персонализированную помощь с вашим проектом.\n\n**Примечание**: Если вам нужно, чтобы я просмотрел определенные разделы вашей реализации, устранил проблемы или предоставил подробный отзыв о вашем коде, пожалуйста, пометьте соответствующие разделы в вашем коде комментариями `//VCPU-REVIEW//` и предоставьте подробные объяснения проблем или вопросов, с которыми вы сталкиваетесь. Это поможет мне сосредоточить свои усилия и предоставить наиболее эффективную поддержку.\n\nДа благословит Бог вашу душу.\n\n---\n\n**Конец руководства**\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/bin/ch347.cfg",
    "content": "# 指定CH347-JTAG 调试器\nadapter driver ch347\nch347 vid_pid 0x1a86 0x55dd\n\n# 设置TCK时钟频率\nadapter speed 10000\n\nsource [find cpld/xilinx-xc7.cfg]\n# source [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/contrib/60-openocd.rules",
    "content": "# Copy this file to /etc/udev/rules.d/\n# If rules fail to reload automatically, you can refresh udev rules\n# with the command \"udevadm control --reload\"\n\nACTION!=\"add|change\", GOTO=\"openocd_rules_end\"\n\nSUBSYSTEM==\"gpio\", MODE=\"0660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nSUBSYSTEM!=\"usb|tty|hidraw\", GOTO=\"openocd_rules_end\"\n\n# Please keep this list sorted by VID:PID\n\n# opendous and estick\nATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"204f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232/FT245 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT2232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT4232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232H VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Original FT231XQ VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# DISTORTEC JTAG-lock-pick Tiny 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8220\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TUMPA, TUMPA Lite\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a98\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a99\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell OpenRD JTAGKey FT2232D B\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"9e90\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# XDS100v2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# XDS100v3\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OOCDLink\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"baf8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Kristech KT-Link\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bbe2\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris Evaluation Board FTDI (several)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcd9\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcda\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# egnite Turtelizer 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bdc8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Section5 ICEbear\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c140\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c141\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey and JTAGkey-tiny\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"cff8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ASIX Presto programmer\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"f1a0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Nuvoton NuLink\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5200\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5201\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI ICDI\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"c32a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK V1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3744\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3748\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2.1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3752\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics STLINK-V3\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3753\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3754\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress SuperSpeed Explorer Kit\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"0007\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in KitProg mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f139\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in CMSIS-DAP mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f138\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Infineon DAP miniWiggler v3\nATTRS{idVendor}==\"058b\", ATTRS{idProduct}==\"0043\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex LPC1768-Stick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0026\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hilscher NXHX Boards\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0028\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STR9-comStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STM32-PerformanceStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex Cortino\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0032\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Altera USB Blaster\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Altera USB Blaster2\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6810\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ashling Opella-LD\nATTRS{idVendor}==\"0B6B\", ATTRS{idProduct}==\"0040\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey-HiSpeed\nATTRS{idVendor}==\"0fbb\", ATTRS{idProduct}==\"1000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# SEGGER J-Link\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0101\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0102\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0103\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0104\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0105\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0107\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0108\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1012\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1013\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1016\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1017\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1018\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1020\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1051\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1055\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1061\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Raisonance RLink\nATTRS{idVendor}==\"138e\", ATTRS{idProduct}==\"9000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Debug Board for Neo1973\nATTRS{idVendor}==\"1457\", ATTRS{idProduct}==\"5118\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OSBDM\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0042\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0058\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"005e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0003\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0004\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-JTAG-EW\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"001e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC\nATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"06ad\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# USBprog with OpenOCD firmware\nATTRS{idVendor}==\"1781\", ATTRS{idProduct}==\"0c63\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00fd\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI XDS110 Debug Probe (Launchpads and Standalone)\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef3\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef4\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"02a5\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI Tiva-based ICDI and XDS110 probes in DFU mode\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00ff\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# isodebug v1\nATTRS{idVendor}==\"22b7\", ATTRS{idProduct}==\"150d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# PLS USB/JTAG Adapter for SPC5xxx\nATTRS{idVendor}==\"263d\", ATTRS{idProduct}==\"4001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Numato Mimas A7 - Artix 7 FPGA Board\nATTRS{idVendor}==\"2a19\", ATTRS{idProduct}==\"1009\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ambiq Micro EVK and Debug boards.\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"1106\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell Sheevaplug\nATTRS{idVendor}==\"9e88\", ATTRS{idProduct}==\"9e8f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Keil Software, Inc. ULink\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2710\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2750\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# CMSIS-DAP compatible adapters\nATTRS{product}==\"*CMSIS-DAP*\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nLABEL=\"openocd_rules_end\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/contrib/libdcc/README",
    "content": "This code is an example of using the openocd debug message system.\n\nBefore the message output is seen in the debug window, the functionality\nwill need enabling:\n\nFrom the gdb prompt:\nmonitor target_request debugmsgs enable\nmonitor trace point 1\n\nFrom the Telnet prompt:\ntarget_request debugmsgs enable\ntrace point 1\n\nTo see how many times the trace point was hit:\n(monitor) trace point 1\n\nSpen\nspen@spen-soft.co.uk\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/contrib/libdcc/dcc_stdio.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n#define TARGET_REQ_TRACEMSG\t\t\t\t\t0x00\n#define TARGET_REQ_DEBUGMSG_ASCII\t\t\t0x01\n#define TARGET_REQ_DEBUGMSG_HEXMSG(size)\t(0x01 | ((size & 0xff) << 8))\n#define TARGET_REQ_DEBUGCHAR\t\t\t\t0x02\n\n#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)\n\n/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel\n * DCRDR[7:0] is used by target for status\n * DCRDR[15:8] is used by target for write buffer\n * DCRDR[23:16] is used for by host for status\n * DCRDR[31:24] is used for by host for write buffer */\n\n#define NVIC_DBG_DATA_R\t\t(*((volatile unsigned short *)0xE000EDF8))\n\n#define\tBUSY\t1\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tint len = 4;\n\n\twhile (len--)\n\t{\n\t\t/* wait for data ready */\n\t\twhile (NVIC_DBG_DATA_R & BUSY);\n\n\t\t/* write our data and set write flag - tell host there is data*/\n\t\tNVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);\n\t\tdcc_data >>= 8;\n\t}\n}\n\n#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tunsigned long dcc_status;\n\n\tdo {\n\t\tasm volatile(\"mrc p14, 0, %0, c0, c0\" : \"=r\" (dcc_status));\n\t} while (dcc_status & 0x2);\n\n\tasm volatile(\"mcr p14, 0, %0, c1, c0\" : : \"r\" (dcc_data));\n}\n\n#else\n #error unsupported target\n#endif\n\nvoid dbg_trace_point(unsigned long number)\n{\n\tdbg_write(TARGET_REQ_TRACEMSG | (number << 8));\n}\n\nvoid dbg_write_u32(const unsigned long *val, long len)\n{\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdbg_write(*val);\n\n\t\tval++;\n\t\tlen--;\n\t}\n}\n\nvoid dbg_write_u16(const unsigned short *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 16: 0x0000);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 2;\n\t\tlen -= 2;\n\t}\n}\n\nvoid dbg_write_u8(const unsigned char *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? val[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? val[3] << 24 : 0x00);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_str(const char *msg)\n{\n\tlong len;\n\tunsigned long dcc_data;\n\n\tfor (len = 0; msg[len] && (len < 65536); len++);\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = msg[0]\n\t\t\t| ((len > 1) ? msg[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? msg[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? msg[3] << 24 : 0x00);\n\t\tdbg_write(dcc_data);\n\n\t\tmsg += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_char(char msg)\n{\n\tdbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/contrib/libdcc/dcc_stdio.h",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#ifndef DCC_STDIO_H\n#define DCC_STDIO_H\n\nvoid dbg_trace_point(unsigned long number);\n\nvoid dbg_write_u32(const unsigned long *val, long len);\nvoid dbg_write_u16(const unsigned short *val, long len);\nvoid dbg_write_u8(const unsigned char *val, long len);\n\nvoid dbg_write_str(const char *msg);\nvoid dbg_write_char(char msg);\n\n#endif\t/* DCC_STDIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/contrib/libdcc/example.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n/* enable openocd debugmsg at the gdb prompt:\n * monitor target_request debugmsgs enable\n *\n * create a trace point:\n * monitor trace point 1\n *\n * to show how often the trace point was hit:\n * monitor trace point\n*/\n\nint main(void)\n{\n\tdbg_write_str(\"hello world\");\n\n\tdbg_write_char('t');\n\tdbg_write_char('e');\n\tdbg_write_char('s');\n\tdbg_write_char('t');\n\tdbg_write_char('\\n');\n\n\tunsigned long test_u32 = 0x01234567;\n\tdbg_write_u32(&test_u32, 1);\n\n\tstatic const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF};\n\tdbg_write_u16(test_u16, 8);\n\n\tstatic const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF};\n\tdbg_write_u8(test_u8, 16);\n\n\twhile(1)\n\t{\n\t\tdbg_trace_point(0);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/bitsbytes.tcl",
    "content": "#----------------------------------------\n# Purpose - Create some $BIT variables\n#           Create $K and $M variables\n#          and some bit field extraction variables.\n# Create helper variables ...\n#    BIT0.. BIT31\n\nfor { set x 0  } { $x < 32 } { set x [expr {$x + 1}]} {\n    set vn [format \"BIT%d\" $x]\n    global $vn\n    set $vn   [expr {1 << $x}]\n}\n\n# Create K bytes values\n#    __1K ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dK\" $x]\n    global $vn\n    set $vn   [expr {1024 * $x}]\n}\n\n# Create M bytes values\n#    __1M ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dM\" $x]\n    global $vn\n    set $vn [expr {1024 * 1024 * $x}]\n}\n\nproc create_mask { MSB LSB } {\n    return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}]\n}\n\n# Cut Bits $MSB to $LSB out of this value.\n# Example: % format \"0x%08x\" [extract_bitfield 0x12345678 27 16]\n# Result:  0x02340000\n\nproc extract_bitfield { VALUE MSB LSB } {\n    return [expr {[create_mask $MSB $LSB] & $VALUE}]\n}\n\n\n# Cut bits $MSB to $LSB out of this value\n# and shift (normalize) them down to bit 0.\n#\n# Example: % format \"0x%08x\" [normalize_bitfield 0x12345678 27 16]\n# Result:  0x00000234\n#\nproc normalize_bitfield { VALUE MSB LSB } {\n    return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}]\n}\n\nproc show_normalize_bitfield { VALUE MSB LSB } {\n    set m [create_mask $MSB $LSB]\n    set mr [expr {$VALUE & $m}]\n    set sr [expr {$mr >> $LSB}]\n    echo [format \"((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d \" $VALUE $m $mr $LSB $sr $sr]\n   return $sr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/8devices-lima.cfg",
    "content": "# Product page:\n# https://www.8devices.com/products/lima\n#\n# Location of JTAG pins:\n# J2 GPIO0\tJTAG TCK\n# J2 GPIO1\tJTAG TDI\n# J2 GPIO2\tJTAG TDO\n# J2 GPIO3\tJTAG TMS\n# J2 RST\tdirectly connected to RESET_L of the SoC and can be used as\n#               JTAG SRST. Note: this pin will also reset the debug engine.\n# J1 +3,3V\tCan be use as JTAG Vref\n# J1 or J2 GND\tCan be used for JTAG GND\n#\n# This board is powered from mini USB connecter which is also used\n# as USB to UART converted based on FTDI FT230XQ chip\n\nsource [find target/qualcomm_qca4531.cfg]\n\nproc board_init { } {\n\tqca4531_ddr2_550_550_init\n}\n\n$_TARGETNAME configure -event reset-init {\n\tboard_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/actux3.cfg",
    "content": "# board config file for AcTux3/XBA IXP42x board\n# Date:   2010-12-16\n# Author: Michael Schwingen <michael@schwingen.org>\n\nreset_config trst_and_srst separate\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nsource [find target/ixp42x.cfg]\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init { init_actux3 }\n\nproc init_actux3 { } {\n    ##########################################################################\n    # setup expansion bus CS\n    ##########################################################################\n    mww 0xc4000000  0xbd113842  ;#CS0  : Flash, write enabled @0x50000000\n    mww 0xc4000004  0x94d10013  ;#CS1\n    mww 0xc4000008  0x95960003  ;#CS2\n    mww 0xc400000c  0x00000000  ;#CS3\n    mww 0xc4000010  0x80900003  ;#CS4\n    mww 0xc4000014  0x9d520003  ;#CS5\n    mww 0xc4000018  0x81860001  ;#CS6\n    mww 0xc400001c  0x80900003  ;#CS7\n\n    ixp42x_init_sdram $::IXP42x_SDRAM_16MB_4Mx16_1BANK 2100 3\n\n    #mww 0xc4000020  0xffffee ;# CFG0: remove expansion bus boot flash mirror at 0x00000000\n\n    ixp42x_set_bigendian\n\n    flash probe 0\n}\n\nproc flash_boot { {FILE \"/tftpboot/actux3/u-boot.bin\"} } {\n    echo \"writing bootloader: $FILE\"\n    flash write_image erase $FILE 0x50000000 bin\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x400000 2 2 $_TARGETNAME\n\ninit\nreset init\n\n# setup to debug u-boot in flash\nproc uboot_debug {} {\n    gdb_breakpoint_override hard\n    xscale vector_catch 0xFF\n\n    xscale vector_table low  1 0xe59ff018\n    xscale vector_table low  2 0xe59ff018\n    xscale vector_table low  3 0xe59ff018\n    xscale vector_table low  4 0xe59ff018\n    xscale vector_table low  5 0xe59ff018\n    xscale vector_table low  6 0xe59ff018\n    xscale vector_table low  7 0xe59ff018\n\n    xscale vector_table high 1 0xe59ff018\n    xscale vector_table high 2 0xe59ff018\n    xscale vector_table high 3 0xe59ff018\n    xscale vector_table high 4 0xe59ff018\n    xscale vector_table high 5 0xe59ff018\n    xscale vector_table high 6 0xe59ff018\n    xscale vector_table high 7 0xe59ff018\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/adapteva_parallella1.cfg",
    "content": "#\n# Adapteva Parallella-I board (via Porcupine-1 adapter board)\n#\n\nreset_config srst_only\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/adsp-sc584-ezbrd.cfg",
    "content": "#\n# Analog Devices ADSP-SC584-EZBRD evaluation board\n#\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\n# Analog expects users to use their proprietary ICE-1000 / ICE-2000 with all\n# ADSP-SC58x designs, but this is an ARM target (and subject to the\n# qualifications above) many ARM debug pods should be compatible.\n\n#source [find interface/cmsis-dap.cfg]\nsource [find interface/jlink.cfg]\n\n# Analog's silicon supports SWD and JTAG, but their proprietary ICE is limited\n# to JTAG.  (This is presumably why their connector pinout was modified.)\n# SWD is chosen here, as it is more efficient and doesn't require /TRST.\n\ntransport select swd\n\n# chosen speed is 'safe' choice, but your adapter may be capable of more\nadapter speed 400\n\nsource [find target/adsp-sc58x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/alphascale_asm9260_ek.cfg",
    "content": "source [find target/alphascale_asm9260t.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configure clock\"\n\t# Enable SRAM clk\n\tmww 0x80040024 0x4\n\t# Enable IRQ clk\n\tmww 0x80040034 0x100\n\t# Enable DMA0,1 clk\n\tmww 0x80040024 0x600\n\t# Make sysre syspll is enabled\n\tmww 0x80040238 0x750\n\t#CPU = PLLCLK/2\n\tmww 0x8004017C 0x2\n\t#SYSAHBCLK = CPUCLK/2\n\tmww 0x80040180 0x2\n\t# Set PLL freq to 480MHz\n\tmww 0x80040100 480\n\t# normally we shoul waiting here until we get 0x1 (0x80040104)&0x1)==0x0)\n\tsleep 100\n\n\t# select PLL as main source\n\tmww 0x80040120 0x1\n\t# disable and enable main clk to update changes?\n\tmww 0x80040124 0x0\n\tmww 0x80040124 0x1\n\n\techo \"Configure memory\"\n\t#enable EMI CLK\n\tmww 0x80040024 0x40\n\n\t# configure memory controller for internal SRAM\n\tmww 0x80700000 0x1188\n\t# change default emi clk delay\n\tmww 0x8004034C 0xA0503\n\t# make sure chip_select_register2_low has correct value (why?)\n\tmww 0x8070001c 0x20000000\n\t# set type to sdram and size to 32MB\n\tmww 0x8070005c 0xa\n\t# configure internal SDRAM timing\n\tmww 0x80700004 0x024996d9\n\t# configure Static Memory timing\n\tmww 0x80700094 0x00542b4f\n\n\techo \"Configure uart4\"\n\t# enable pinctrl clk\n\tmww 0x80040024 0x2000000\n\t# mux GPIO3_0 and GPIO3_1 to UART4\n\tmww 0x80044060 0x2\n\tmww 0x80044064 0x2\n\t# configure UART4CLKDIV\n\tmww 0x800401a8 0x1\n\t# enable uart4 clk\n\tmww 0x80040024 0x8000\n\t# clear softrst and clkgate on uart4\n\tmww 0x80010008 0xC0000000\n\t# set bandrate 115200 12M\n\tmww 0x80010030 0x00062070\n\t# enable Rx&Tx\n\tmww 0x80010024 0x301\n\t# clear hw control\n\tmww 0x80010028 0xc000\n}\n\n$_TARGETNAME configure -work-area-phys 0x21ffe000 -work-area-virt 0xc1ffe000 -work-area-size 0x1000\n$_TARGETNAME arm7_9 fast_memory_access enable\n$_TARGETNAME arm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/altera_sockit.cfg",
    "content": "#\n# Cyclone V SocKit board\n# http://www.altera.com/b/arrow-sockit.html\n#\n# Software support page:\n# http://www.rocketboards.org/\n\n# openocd does not currently support the on-board USB Blaster II.\n# Install the JTAG header and use a USB Blaster instead.\nadapter driver usb_blaster\n\nsource [find target/altera_fpgasoc.cfg]\n\n# If the USB Blaster II were supported, these settings would be needed\n#usb_blaster vid_pid 0x09fb 0x6810\n#usb_blaster device_desc \"USB-Blaster II\"\n\nadapter speed 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/am3517evm.cfg",
    "content": "# DANGER!!!! early work in progress for this PCB/target.\n#\n# The most basic operations work well enough that it is\n# useful to have this in the repository for cooperation\n# alpha testing purposes.\n#\n# TI AM3517\n#\n# http://focus.ti.com/docs/prod/folders/print/am3517.html\n# http://processors.wiki.ti.com/index.php/Debug_Access_Port_(DAP)\n# http://processors.wiki.ti.com/index.php?title=How_to_Find_the_Silicon_Revision_of_your_OMAP35x\n\nset CHIPTYPE \"am35x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit am35x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ampere_emag8180.cfg",
    "content": "#\n# OpenOCD Board Configuration for eMAG Development Platform\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure JTAG speed\n#\n\nadapter speed 2000\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nsource [find target/ampere_emag.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/arm_evaluator7t.cfg",
    "content": "# This board is from ARM and has an samsung s3c45101x01 chip\n\nsource [find target/samsung_s3c4510.cfg]\n\n#\n# FIXME:\n#  Add (A) sdram configuration\n#  Add (B) flash cfi programming configuration\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/arm_musca_a.cfg",
    "content": "#\n# Configuration script for ARM Musca-A development board\n#\n# For now we do not support Musca A flash programming using OpenOCD. However, a\n# work area is configured for flash programming speed up.\n#\n# GDB considers all memory as RAM unless target supplies a memory map.\n# OpenOCD will only send memory map if flash banks are configured. Otherwise,\n# configure GDB after connection by issuing following commands:\n# (gdb) mem 0x10200000 0x109FFFFF ro\n# (gdb) mem 0x00200000 0x009FFFFF ro\n# (gdb) set mem inaccessible-by-default off\n\n# ARM Musca A board supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME MUSCA_A\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x6ba00477\n}\n\n# Enable CPU1 debugging as a separate GDB target\nset _ENABLE_CPU1 1\n\n# Musca A1 has 32KB SRAM banks. Override default work-area-size to 8KB per CPU\nset WORKAREASIZE_CPU0 0x2000\nset WORKAREASIZE_CPU1 0x2000\n\n# Set SRAM bank 1 to be used for work area. Override here if needed.\nset WORKAREAADDR_CPU0 0x30008000\nset WORKAREAADDR_CPU1 0x3000A000\n\nsource [find target/arm_corelink_sse200.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/arty_s7.cfg",
    "content": "#\n# Arty S7: Spartan7 25/50 FPGA Board for Makers and Hobbyists\n#\n# https://www.xilinx.com/products/boards-and-kits/1-pnziih.html\n# https://store.digilentinc.com/arty-s7-spartan-7-fpga-board-for-makers-and-hobbyists/\n\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# Xilinx Spartan7-25/50 FPGA (XC7S{25,50}-CSGA324)\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n\n# Usage:\n#\n# Load Bitstream into FPGA:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    pld load 0 bitstream.bit;\\\n#    shutdown\"\n#\n# Write Bitstream to Flash:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    jtagspi_init 0 bscan_spi_xc7s??.bit;\\\n#    jtagspi_program bitstream.bin 0;\\\n#    xc7_program xc7.tap;\\\n#    shutdown\"\n#\n# jtagspi flash proxies can be found at:\n# https://github.com/quartiq/bscan_spi_bitstreams\n#\n# For the Spartan 50 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s50.bit\n# For the Spartan 25 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s25.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/asus-rt-n16.cfg",
    "content": "#\n# http://wikidevi.com/wiki/ASUS_RT-N16\n#\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4718.cfg]\n\n# External 32MB NOR Flash (Macronix MX29GL256EHTI2I-90Q)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/asus-rt-n66u.cfg",
    "content": "#\n# http://wikidevi.com/wiki/Asus_RT-N66U\n#\n\necho \"ATTENTION: you need to solder a 4.7-10k pullup resistor to pin 21 of flash IC\"\necho \"to enable JTAG, see http://wl500g.info/album.php?albumid=28&attachmentid=8991 ,\"\necho \"there is an unpopulated footprint near U8.\\n\"\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4706.cfg]\n\n# External 32MB NOR Flash (Spansion S29GL256P10TF101\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91cap7a-stk-sdram.cfg",
    "content": "# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394\n#\n# use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME cap7\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x40700f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start {\n\t# start off real slow when we're running off internal RC oscillator\n\tadapter speed 32\n}\n\nproc peek32 {address} {\n\treturn [read_memory $address 32 1]\n}\n\n# Wait for an expression to be true with a timeout\nproc wait_state {expression} {\n\tfor {set i 0} {$i < 1000} {set i [expr {$i + 1}]} {\n\t\tif {[uplevel 1 $expression] == 0} {\n\t\t\treturn\n\t\t}\n\t}\n\treturn -code 1 \"Timed out\"\n}\n\n# Use a global variable here to be able to tinker interactively with\n# post reset jtag frequency.\nglobal post_reset_khz\n# Danger!!!! Even 16MHz kinda works with this target, but\n# it needs to be as low as 2000kHz to be stable.\nset post_reset_khz 2000\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configuring master clock\"\n\t# disable watchdog\n\tmww 0xfffffd44 0xff008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# Enable main oscillator\n\tmww 0xFFFFFc20  0x00000f01\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}}\n\n\t# Set PLLA to 96MHz\n\tmww 0xFFFFFc28 0x20072801\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}}\n\n\t# Select prescaler\n\tmww 0xFFFFFC30 0x00000004\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\t# Select master clock to 48MHz\n\tmww 0xFFFFFC30 0x00000006\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\techo \"Master clock ok.\"\n\n\t# Now that we're up and running, crank up speed!\n\tglobal post_reset_khz ;\tadapter speed $post_reset_khz\n\n\techo \"Configuring the SDRAM controller...\"\n\n\t# Configure EBI Chip select for SDRAM\n\tmww 0xFFFFEF30 0x00000102\n\n\t# Enable clock on EBI PIOs\n\tmww 0xFFFFFC10 0x00000004\n\n\t# Configure PIO for SDRAM\n\tmww 0xFFFFF470 0xFFFF0000\n\tmww 0xFFFFF474 0x00000000\n\tmww 0xFFFFF404 0xFFFF0000\n\n\t# Configure SDRAMC CR\n\tmww 0xFFFFEA08 0xA63392F9\n\n\t# NOP command\n\tmww 0xFFFFEA00 0x1\n\tmww 0x20000000 0\n\n\t# Precharge All Banks command\n\tmww 0xFFFFEA00 0x2\n\tmww 0x20000000 0\n\n\t# Set 1st CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000010 0x00000001\n\n\t# Set 2nd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000020 0x00000002\n\n\t# Set 3rd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000030 0x00000003\n\n\t# Set 4th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000040 0x00000004\n\n\t# Set 5th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000050 0x00000005\n\n\t# Set 6th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000060 0x00000006\n\n\t# Set 7th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000070 0x00000007\n\n\t# Set 8th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000080 0x00000008\n\n\t# Set LMR operation\n\tmww 0xFFFFEA00 0x00000003\n\n\t# Perform LMR burst=1, lat=2\n\tmww 0x20000020 0xCAFEDEDE\n\n\t# Set Refresh Timer\n\tmww 0xFFFFEA04 0x00000203\n\n\t# Set Normal mode\n\tmww 0xFFFFEA00 0x00000000\n\tmww 0x20000000 0x00000000\n\n\t#remap internal memory at address 0x0\n\tmww 0xffffef00 0x3\n\n\techo \"SDRAM configuration ok.\"\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91eb40a.cfg",
    "content": "#Script for AT91EB40a\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\n\n#Atmel ties SRST & TRST together, at which point it makes\n#no sense to use TRST, but use TMS instead.\n#\n#The annoying thing with tying SRST & TRST together is that\n#there is no way to halt the CPU *before and during* the\n#SRST reset, which means that the CPU will run a number\n#of cycles before it can be halted(as much as milliseconds).\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n#flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME\n\n# required for usable performance. Used for lots of\n# other things than flash programming.\n$_TARGETNAME configure -work-area-phys 0x00030000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Running reset init script for AT91EB40A\"\n\t# Reset script for AT91EB40a\n\treg cpsr 0x000000D3\n\tmww 0xFFE00020 0x1\n\tmww 0xFFE00024 0x00000000\n\tmww 0xFFE00000 0x01002539\n\tmww 0xFFFFF124 0xFFFFFFFF\n\tmww 0xffff0010 0x100\n\tmww 0xffff0034 0x100\n}\n\n# This target is pretty snappy...\nadapter speed 16000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91rm9200-dk.cfg",
    "content": "#\n# This is for the \"at91rm9200-DK\" (not the EK) eval board.\n#\n# The two are probably very simular.... I have DK...\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_dk_init }\n\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME\n\n\nproc at91rm9200_dk_init { } {\n    # Try to run at 1khz... Yea, that slow!\n    # Chip is really running @ 32khz\n    adapter speed 8\n\n    mww 0xfffffc64 0xffffffff\n    ##  disable all clocks but system clock\n    mww 0xfffffc04 0xfffffffe\n    ##  disable all clocks to pioa and piob\n    mww 0xfffffc14 0xffffffc3\n    ##  master clock = slow cpu = slow\n    ##  (means the CPU is running at 32khz!)\n    mww 0xfffffc30 0\n    ##  main osc enable\n    mww 0xfffffc20 0x0000ff01\n    ##  program pllA\n    mww 0xfffffc28 0x20263e04\n    ##  program pllB\n    mww 0xfffffc2c 0x10483e0e\n    ##  let pll settle... sleep 100msec\n    sleep 100\n    ##  switch to fast clock\n    mww 0xfffffc30 0x202\n    ## Sleep some - (go read)\n    sleep 100\n\n    #========================================\n    # CPU now runs at 180mhz\n    # SYS runs at 60mhz.\n    adapter speed 40000\n    #========================================\n\n\n    ##  set memc for all memories\n    mww 0xffffff60 0x02\n    ##  program smc controller\n    mww 0xffffff70 0x3284\n    ##  init sdram\n    mww 0xffffff98 0x7fffffd0\n    ##  all banks precharge\n    mww 0xffffff80 0x02\n    ##  touch sdram chip to make it work\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    mww 0xffffff90 0x04\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    ##  Refresh, etc....\n    mww 0xffffff90 0x03\n    mww 0x20000080 0\n    mww 0xffffff94 0x1f4\n    mww 0x20000080 0\n    mww 0xffffff90 0x10\n    mww 0x20000000 0\n    mww 0xffffff00 0x01\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91rm9200-ek.cfg",
    "content": "#\n# Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>\n#\n# under GPLv2 Only\n#\n# This is for the \"at91rm9200-ek\" eval board.\n#\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_ek_init }\n\n## flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# The chip may run @ 32khz, so set a really low JTAG speed\nadapter speed 8\n\nproc at91rm9200_ek_init { } {\n\t# Try to run at 1khz... Yea, that slow!\n\t# Chip is really running @ 32khz\n\tadapter speed 8\n\n\tmww 0xfffffc64 0xffffffff\n\t## disable all clocks but system clock\n\tmww 0xfffffc04 0xfffffffe\n\t## disable all clocks to pioa and piob\n\tmww 0xfffffc14 0xffffffc3\n\t## master clock = slow cpu = slow\n\t## (means the CPU is running at 32khz!)\n\tmww 0xfffffc30 0\n\t## main osc enable\n\tmww 0xfffffc20 0x0000ff01\n\t## MC_PUP\n\tmww 0xFFFFFF50 0x00000000\n\t## MC_PUER: Memory controller protection unit disable\n\tmww 0xFFFFFF54 0x00000000\n\t## EBI_CFGR\n\tmww 0xFFFFFF64 0x00000000\n\t## SMC2_CSR[0]: 16bit, 2 TDF, 4 WS\n\tmww 0xFFFFFF70 0x00003284\n\n\t## Init Clocks\n\t## CKGR_PLLAR\n\tmww 0xFFFFFC28 0x2000BF05\n\t## PLLAR: 179,712000 MHz for PCK\n\tmww 0xFFFFFC28 0x20263E04\n\tsleep 100\n\t## PMC_MCKR\n\tmww 0xFFFFFC30 0x00000100\n\tsleep 100\n\t## ;MCKR : PCK/3 = MCK Master Clock = 59,904000MHz from PLLA\n\tmww 0xFFFFFC30 0x00000202\n\tsleep 100\n\n\t#========================================\n\t# CPU now runs at 180mhz\n\t# SYS runs at 60mhz.\n\tadapter speed 40000\n\t#========================================\n\n\t## Init SDRAM\n\t## PIOC_ASR: Configure PIOC as peripheral (D16/D31)\n\tmww 0xFFFFF870 0xFFFF0000\n\t## PIOC_BSR:\n\tmww 0xFFFFF874 0x00000000\n\t## PIOC_PDR:\n\tmww 0xFFFFF804 0xFFFF0000\n\t## EBI_CSA : CS1=SDRAM\n\tmww 0xFFFFFF60 0x00000002\n\t## EBI_CFGR:\n\tmww 0xFFFFFF64 0x00000000\n\t## SDRC_CR :\n\tmww 0xFFFFFF98 0x2188c155\n\t## SDRC_MR : Precharge All\n\tmww 0xFFFFFF90 0x00000002\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Refresh\n\tmww 0xFFFFFF90 0x00000004\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Load Mode Register\n\tmww 0xFFFFFF90 0x00000003\n\t## access SDRAM\n\tmww 0x20000080 0x00000000\n\t## SDRC_TR : Write refresh rate\n\tmww 0xFFFFFF94 0x000002E0\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Normal Mode\n\tmww 0xFFFFFF90 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91sam9261-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9261-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9261.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9261.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9261ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9261ek_reset_init { } {\n\n\t;# for ppla at 199 Mhz\n\tset config(master_pll_div)\t15\n\tset config(master_pll_mul)\t162\n\n\t;# for ppla at 239 Mhz\n\t;# set master_pll_div\t1\n\t;# set master_pll_mul\t13\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBICSA\n\tset config(matrix_ebicsa_val) [expr {$::AT91_MATRIX_DBPUC | $::AT91_MATRIX_CS1A_SDRAMC}]\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (2 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (3 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (8 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91sam9263-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9263-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9263.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9263.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9263ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9263ek_reset_init { } {\n\n\tset config(master_pll_div)\t14\n\tset config(master_pll_mul)\t171\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\tset config(sdram_piod) 1\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBI0CSA\n\n\tset val\t$::AT91_MATRIX_EBI0_DBPUC\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_VDDIOMSEL_3_3V}]\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_CS1A_SDRAMC}]\n\tset config(matrix_ebicsa_val) $val\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (1 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (2 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (1 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/at91sam9g20-ek.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n# Author: Gary Carlson (gcarlson@carlson-minot.com)\t\t\t\t\t\t#\n# Generated for Atmel AT91SAM9G20-EK evaluation board using Atmel SAM-ICE (J-Link) version 8.\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g20.cfg]\n\nset _FLASHTYPE nandflash_cs3\n\n# Set reset type.  Note that the AT91SAM9G20-EK board has the trst signal disconnected.  Therefore\n# the reset needs to be configured for \"srst_only\".  If for some reason, a zero-ohm jumper is\n# added to the board to connect the trst signal, then this parameter may need to be changed.\n\nreset_config srst_only\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init}\n$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start}\n\n# NandFlash configuration and definition\n\nnand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xfffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g20_reset_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n\tadapter speed 2                 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\thalt                            ;# Make sure processor is halted, or error will result in following steps.\n\twait_halt 10000\n\tmww 0xfffffd08 0xa5000501       ;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9g20_reset_init { } {\n\n\t# At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G20 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\tmww 0xfffffd44 0x00008000\t;# WDT_MR : disable watchdog.\n\n\t# Enable the main 18.432 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\tmww 0xfffffc28 0x202a3f01\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00000101\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 0\n\n\t# Enable faster DCC downloads and memory accesses.\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\tmww 0xffffef1c 0x000100a\n\n\t# The AT91SAM9G20-EK evaluation board has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# a number of registers.  The first step involves setting up the general I/O pins on the processor\n\t# to be able to interface and support the external memory.\n\n\tmww 0xfffffc10 0x00000010\t;# PMC_PCER : enable PIOC clock\n\tmww 0xfffff800 0x00006000\t;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n\tmww 0xfffff810 0x00004000\t;# PIOC_OER : enable output on 14\n\tmww 0xfffff814 0x00002000\t;# PIOC_ODR : disable output on 13\n    \tmww 0xfffff830 0x00004000\t;# PIOC_SODR : set 14 to disable NAND\n\n\t# The exact physical timing characteristics for the memory type used on the current board\n\t# (MT29F2G08AACWP) can be established by setting four registers in order:  SMC_SETUP3,\n\t# SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.  Computing the exact values of these registers\n\t# is a little tedious to do here.  If you have questions about how to do this, Atmel has\n\t# a decent application note #6255B that covers this process.\n\n\tmww 0xffffec30 0x00020002\t;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE\n\tmww 0xffffec34 0x04040404\t;# SMC_PULSE3 : 4 clock cycle pulse for all signals\n\tmww 0xffffec38 0x00070006\t;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle\n\tmww 0xffffec3C 0x00020003\t;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n\n\tmww 0xffffe800 0x00000001\t;# ECC_CR : reset the ECC parity registers\n\tmww 0xffffe804 0x00000002\t;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n\t# Identify NandFlash bank 0.\n\n\tnand probe nandflash_cs3\n\n\t# The AT91SAM9G20-EK evaluation board has built-in serial data flash also.\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Micron MT48LC16M16A2-75 memory (4 M x 16 bit x 4 banks).  If you use this file as a reference\n\t# for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted\n\t# into the SDRAM_CR register.  Using the memory datasheet for the -75 grade part and assuming a master clock\n\t# of 132.096 MHz then the SDCLK period is equal to 7.6 ns.  This means the device requires:\n\t#\n\t#\tCAS latency = 3 cycles\n\t#\tTXSR = 10 cycles\n\t#\tTRAS = 6 cycles\n\t#\tTRCD = 3 cycles\n\t#\tTRP = 3 cycles\n\t#\tTRC = 9 cycles\n\t#\tTWR = 2 cycles\n\t#\t9 column, 13 row, 4 banks\n\t#\trefresh equal to or less then 7.8 us for commercial/industrial rated devices\n\t#\n\t#\tThus SDRAM_CR = 0xa6339279\n\n\tmww 0xffffea08 0xa6339279\n\n\t# Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000001\n\tmww 0x20000000 0\n\n\t# Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero\n\t# value into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000002\n\tmww 0x20000000 0\n\n\t# Now issue an 'Auto-Refresh' command through the SDRAMC_MR register.  Follow this operation by writing\n\t# zero values eight times into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x3\n\tmww 0x20000000 0\n\n\t# Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting\n\t# memory location for the SDRAM.\n\n\tmww 0xffffea00 0x0\n\tmww 0x20000000 0\n\n\t# Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles).\n\n\tmww 0xffffea04 0x0000039c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_at91sam7s-ek.cfg",
    "content": "# Atmel AT91SAM7S-EK\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3784\n\nset CHIPNAME at91sam7s256\n\nsource [find target/at91sam7sx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_at91sam9260-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9260-EK eval board\n#\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9260.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198.656 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (99.328 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n\n        mww 0xffffef1c 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_at91sam9rl-ek.cfg",
    "content": "################################################################################\n#\n# Generated for Atmel AT91SAM9RL-EK evaluation board using Atmel SAM-ICE (J-Link) V6\n#\n# Atmel AT91SAM9RL : PLL = 200 MHz, MCK = 100 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9rl.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2031bf03         ;# CKGR_PLLR: Set PLL Register for 200 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLL is selected (100 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff670 0xffff0000         ;# PIO_ASR  : Select peripheral function for D16..D31 (PIOB)\n        mww 0xfffff604 0xffff0000         ;# PIO_PDR  : Disable PIO function for D16..D31 (PIOB)\n\n        mww 0xffffef20 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam3n_ek.cfg",
    "content": "\n#\n# Board configuration for Atmel's SAM3N-EK\n#\n\nreset_config srst_only\n\nset CHIPNAME at91sam3n4c\n\nadapter speed 32\n\nsource [find target/at91sam3nXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam3s_ek.cfg",
    "content": "source [find target/at91sam3sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam3u_ek.cfg",
    "content": "source [find target/at91sam3u4e.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam3x_ek.cfg",
    "content": "source [find target/at91sam3ax_8x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam4e_ek.cfg",
    "content": "# This is an SAM4E-EK board with a single SAM4E16 chip.\n# http://www.atmel.com/tools/sam4e-ek.aspx\n\n# chip name\nset CHIPNAME SAM4E16E\n\nsource [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam4l8_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4L8 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4L8-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4LC8CA\n\nsource [find target/at91sam4lXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam4s_ek.cfg",
    "content": "source [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_sam4s_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4S Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4S-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4SD32C\n\nsource [find target/at91sam4sd32x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samc20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC20 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samc21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC21 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMC21-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samd10_xplained_mini.cfg",
    "content": "#\n# Atmel SAMD10 Xplained mini evaluation kit.\n# http://www.atmel.com/tools/atsamd10-xmini.aspx\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd10d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samd11_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD11 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd11d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samd20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD20 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMD20-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samd21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_same70_xplained.cfg",
    "content": "#\n# Atmel SAME70 Xplained evaluation kit.\n# http://www.atmel.com/tools/ATSAME70-XPLD.aspx\n#\n# Connect using the EDBG chip on the dev kit over USB\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME atsame70q21\n\nsource [find target/atsamv.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samg53_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG53 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG53-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG53N19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samg55_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG55 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG55-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG55J19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_saml21_xplained_pro.cfg",
    "content": "#\n# Atmel SAML21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91saml21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samr21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMR21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samr21g18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/atmel_samv71_xplained_ultra.cfg",
    "content": "#\n# Atmel SAMV71 Xplained Ultra evaluation kit.\n# http://www.atmel.com/tools/ATSAMV71-XULT.aspx\n#\n# To connect using the EDBG chip on the dev kit over USB, you will\n# first need to source [find interface/cmsis-dap.cfg]\n# however, since this board also has a SWD+ETM connector, we don't\n# automatically source that file here.\n\nset CHIPNAME samv71\n\nsource [find target/atsamv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/avnet_ultrazed-eg.cfg",
    "content": "#\n# AVNET UltraZED EG StarterKit\n# ZynqMP UlraScale-EG plus IO Carrier with on-board digilent smt2\n#\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n# jtag transport only\ntransport select jtag\n# reset lines are not wired\nreset_config none\n\n# slow default clock\nadapter speed 1000\n\nset CHIPNAME uscale\n\nsource [find target/xilinx_zynqmp.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/balloon3-cpu.cfg",
    "content": "# Config for balloon3 board, cpu JTAG port. http://balloonboard.org/\n# The board has separate JTAG ports for cpu and CPLD/FPGA devices\n# Chaining is done on IO interfaces if desired.\n\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\n# 29LV650 64Mbit Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/bcm28155_ap.cfg",
    "content": "# BCM28155_AP\n\nadapter speed 20000\n\nset CHIPNAME bcm28155\nsource [find target/bcm281xx.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/bluefield.cfg",
    "content": "#\n# Board configuration for BlueField SoC.\n#\n\nsource [find interface/rshim.cfg]\nsource [find target/bluefield.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/bt-homehubv1.cfg",
    "content": "#\n# BT HomeHub v1\n#\n\nset partition_list {\n    CFE       { Bootloader              0xbe400000 0x00020000 }\n    firmware  { \"Kernel+rootfs\"         0xbe420000 0x007d0000 }\n    fisdir    { \"FIS Directory\"         0xbebf0000 0x0000f000 }\n    nvram     { \"Config space\"          0xbebff000 0x00001000 }\n}\n\nsource [find target/bcm6348.cfg]\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/colibri.cfg",
    "content": "# Toradex Colibri PXA270\nsource [find target/pxa270.cfg]\nreset_config trst_and_srst srst_push_pull\nadapter srst pulse_width 40\n\n# CS0 -- one bank of CFI flash, 32 MBytes\n# the bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/crossbow_tech_imote2.cfg",
    "content": "# Crossbow Technology iMote2\n\nset  CHIPNAME imote2\nsource [find target/pxa270.cfg]\n\n# longer-than-normal reset delay\nadapter srst delay 800\n\nreset_config trst_and_srst separate\n\n# works for P30 flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/csb337.cfg",
    "content": "# Cogent CSB337\n#   http://cogcomp.com/csb_csb337.htm\n\nsource [find target/at91rm9200.cfg]\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# ETM9 trace port connector present on this board, 16 data pins.\nif { [info exists ETM_DRIVER] } {\n\tetm config $_TARGETNAME 16 normal half $ETM_DRIVER\n\t# OpenOCD may someday support a real trace port driver...\n\t# system config file would need to configure it.\n} else {\n\tetm config $_TARGETNAME 16 normal half dummy\n\tetm_dummy config $_TARGETNAME\n}\n\nproc csb337_clk_init { } {\n\t# CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock\n\tadapter speed 8\n\n\t# CKGR_MOR:  start main oscillator (3.6864 MHz)\n\tmww 0xfffffc20 0xff01\n\tsleep 10\n\n\t# CKGR_PLLAR:  start PLL A for CPU and peripherals (184.32 MHz)\n\tmww 0xfffffc28 0x20313e01\n\t# CKGR_PLLBR:  start PLL B for USB timing (96 MHz, with div2)\n\tmww 0xfffffc2c 0x12703e18\n\t# let PLLs lock\n\tsleep 10\n\n\t# PMC_MCKR:  switch to CPU clock = PLLA, master clock = CPU/4\n\tmww 0xfffffc30 0x0302\n\tsleep 20\n\n\t# CPU is in Normal Mode ... allows faster JTAG clock speed\n\tadapter speed 40000\n}\n\nproc csb337_nor_init { } {\n\t# SMC_CSR0:  adjust timings (10 wait states)\n\tmww 0xffffff70 0x1100318a\n\n\tflash probe 0\n}\n\nproc csb337_sdram_init { } {\n\t# enable PIOC clock\n\tmww 0xfffffc10 0x0010\n\t# PC31..PC16 are D31..D16, with internal pullups like D15..D0\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff874 0x0\n\tmww 0xfffff804 0xffff0000\n\n\t# SDRC_CR: set timings\n\tmww 0xffffff98 0x2188b0d5\n\n\t# SDRC_MR: issue all banks precharge to SDRAM\n\tmww 0xffffff90 2\n\tmww 0x20000000 0\n\n\t# SDRC_MR: 8 autorefresh cycles\n\tmww 0xffffff90 4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# SDRC_MR: set SDRAM mode registers (CAS, burst len, etc)\n\tmww 0xffffff90 3\n\tmww 0x20000080 0\n\n\t# SDRC_TR: set refresh rate\n\tmww 0xffffff94 0x200\n\tmww 0x20000000 0\n\n\t# SDRC_MR: normal mode, 32 bit bus\n\tmww 0xffffff90 0\n\tmww 0x20000000 0\n}\n\n# The rm9200 chip has just been reset.  Bring it up far enough\n# that we can write flash or run code from SDRAM.\nproc csb337_reset_init { } {\n\tcsb337_clk_init\n\n\t# EBI_CSA:  CS0 = NOR, CS1 = SDRAM\n\tmww 0xffffff60 0x02\n\n\tcsb337_nor_init\n\tcsb337_sdram_init\n\n\t# Update CP15 control register ... we don't seem to be able to\n\t# read/modify/write its value through a TCL variable, so just\n\t# write it.  Fields are zero unless listed here ... and note\n\t# that OpenOCD numbers this register \"2\", not \"1\" (!).\n\t#\n\t#  - Core to use Async Clocking mode (so it uses 184 MHz most\n\t#    of the time instead of limiting to the master clock rate):\n\t#\tiA(31) = 1, nF(30) = 1\n\t#  - Icache on (it's disabled now, slowing i-fetches)\n\t#\tI(12) = 1\n\t#  - Reserved/ones\n\t#\t6:3 = 1\n\tarm920t cp15 2 0xc0001078\n}\n\n$_TARGETNAME configure -event reset-init {csb337_reset_init}\n\narm7_9 fast_memory_access enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/csb732.cfg",
    "content": "# The Cogent CSB732 board has a single i.MX35 chip\nsource [find target/imx35.cfg]\n\n# Determined by trial and error\nreset_config trst_and_srst combined\nadapter srst delay 200\njtag_ntrst_delay 200\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { csb732_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc csb732_init { } {\n\n\t# Disable fast writing only for init\n\tmemwrite burst disable\n\n\t# All delay loops are omitted.\n\t# We assume the interpreter latency is enough.\n\n\t# Allow access to all coprocessors\n\tarm mcr 15 0 15 1 0 0x2001\n\n\t# Disable MMU, caches, write buffer\n\tarm mcr 15 0 1 0 0 0x78\n\n\t# Grant manager access to all domains\n\tarm mcr 15 0 3 0 0 0xFFFFFFFF\n\n\t# Set ARM clock to 532 MHz, AHB to 133 MHz\n\tmww 0x53F80004 0x1000\n\n\t# Set core clock to 2 * 24 MHz * (11 + 1/12) = 532 MHz\n\tmww 0x53F8001C 0xB2C01\n\n\tset ESDMISC 0xB8001010\n\tset ESDCFG0 0xB8001004\n\tset ESDCTL0 0xB8001000\n\n\t# Enable DDR\n\tmww $ESDMISC 0x4\n\n\t# Timing\n\tmww $ESDCFG0 0x007fff3f\n\n\t# CS0\n\tmww $ESDCTL0 0x92120080\n\n\t# Precharge all dummy write\n\tmww 0x80000400 0\n\n\t# Enable CS) auto-refresh\n\tmww $ESDCTL0 0xA2120080\n\n\t# Refresh twice (dummy writes)\n\tmww 0x80000000 0\n\tmww 0x80000000 0\n\n\t# Enable CS0 load mode register\n\tmww $ESDCTL0 0xB2120080\n\n\t# Dummy writes\n\tmwb 0x80000033 0x01\n\tmwb 0x81000000 0x01\n\n\tmww $ESDCTL0 0x82226080\n\tmww 0x80000000 0\n\n\t# Re-enable fast writing\n\tmemwrite burst enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/da850evm.cfg",
    "content": "#DA850 EVM board\n# http://focus.ti.com/dsp/docs/thirdparty/catalog/devtoolsproductfolder.tsp?actionPerformed=productFolder&productId=5939\n# http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit\n\nsource [find target/omapl138.cfg]\n\nreset_config trst_and_srst separate\n\n#currently any pinmux/timing must be setup by UBL before openocd can do debug\n#TODO: implement pinmux/timing on reset like in board/dm365evm.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/digi_connectcore_wi-9c.cfg",
    "content": "######################################\n# Target: DIGI ConnectCore Wi-9C\n######################################\n\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ns9360\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set  _ENDIAN big\n}\n\n\n# What's a good fallback frequency for this board if RCLK is\n# not available??\njtag_rclk 1000\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 200\njtag_ntrst_delay 0\n\n\n######################\n# Target configuration\n######################\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x90600104 0x33313333\n\tmww 0xA0700000 0x00000001  ;# Enable the memory controller.\n\tmww 0xA0700024 0x00000006  ;# Set the refresh counter 6\n\tmww 0xA0700028 0x00000001  ;#\n\tmww 0xA0700030 0x00000001  ;# Set the precharge period\n\tmww 0xA0700034 0x00000004  ;# Active to precharge command period is 16 clock cycles\n\tmww 0xA070003C 0x00000001  ;# tAPR\n\tmww 0xA0700040 0x00000005  ;# tDAL\n\tmww 0xA0700044 0x00000001  ;# tWR\n\tmww 0xA0700048 0x00000006  ;# tRC 32 clock cycles\n\tmww 0xA070004C 0x00000006  ;# tRFC 32 clock cycles\n\tmww 0xA0700054 0x00000001  ;# tRRD\n\tmww 0xA0700058 0x00000001  ;# tMRD\n\tmww 0xA0700100 0x00004280  ;# Dynamic Config 0 (cs4)\n\tmww 0xA0700120 0x00004280  ;# Dynamic Config 1 (cs5)\n\tmww 0xA0700140 0x00004280  ;# Dynamic Config 2 (cs6)\n\tmww 0xA0700160 0x00004280  ;# Dynamic Config 3 (cs7)\n\t#\n\tmww 0xA0700104 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700124 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700144 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700164 0x00000203  ;# CAS latency is 2 at 100 MHz\n\t#\n\tmww 0xA0700020 0x00000103  ;# issue SDRAM PALL command\n\t#\n\tmww 0xA0700024 0x00000001  ;# Set the refresh counter to be as small as possible\n\t#\n\t# Add some dummy writes to give the SDRAM time to settle, it needs two\n\t# AHB clock cycles, here we poke in the debugger flag, this lets\n\t# the software know that we are in the debugger\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\t#\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\t#\n\tmww 0xA0700024 0x00000030 ;# Set the refresh counter to 30\n\tmww 0xA0700020 0x00000083 ;# Issue SDRAM MODE command\n\t#\n\t# Next we perform a read of RAM.\n\t# mw = move word.\n\tmdw 0x00022000\n\t# mw 0x00022000:P, r3  # 22000 for cas2 latency, 32000 for cas 3\n\t#\n\tmww 0xA0700020 0x00000003   ;# issue SDRAM NORMAL command\n\tmww 0xA0700100 0x00084280   ;# Enable buffer access\n\tmww 0xA0700120 0x00084280   ;# Enable buffer access\n\tmww 0xA0700140 0x00084280   ;# Enable buffer access\n\tmww 0xA0700160 0x00084280   ;# Enable buffer access\n\n\t#Set byte lane state (static mem 1)\"\n\tmww 0xA0700220 0x00000082\n\t#Flash Start\n\tmww 0xA09001F8 0x50000000\n\t#Flash Mask Reg\n\tmww 0xA09001FC 0xFF000001\n\tmww 0xA0700028 0x00000001\n\n\t#  RAMAddr = 0x00020000\n\t#  RAMSize = 0x00004000\n\n\t# Set the processor mode\n\treg cpsr 0xd3\n}\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x1000 -work-area-backup 1\n\n#####################\n# Flash configuration\n#####################\n\n#M29DW323DB - not working\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x0400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/digilent_analog_discovery.cfg",
    "content": "#\n# Digilent Analog Discovery\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY\n#\n# Config is based on data from\n# https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71\n#\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x8008 0x800b\n\nadapter speed 25000\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/digilent_atlys.cfg",
    "content": "# http://digilentinc.com/atlys/\n#\n# The Digilent Atlys normally requires proprietary tools to program and will\n# enumerate as:\n#   ID 1443:0007 Digilent Development board JTAG\n#\n# However, the ixo-usb-jtag project provides an alternative open firmware for\n# the on board programmer. When using this firmware the board will then\n# enumerate as:\n#   ID 16c0:06ad Van Ooijen Technische Informatica\n# (With SerialNumber == hw_nexys)\n#\n# See the interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/digilent_nexys_video.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Digilent Nexys Video with Xilinx Artix-7 FPGA\n# https://reference.digilentinc.com/programmable-logic/nexys-video/start\n\nadapter driver ftdi\nadapter speed 30000\n\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6010\n\n# channel 0 is dedicated for Digilent's DPTI Interface\n# channel 1 is used for JTAG\nftdi channel 1\n\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n\n# Enable sampling on falling edge for high JTAG speeds.\nftdi tdo_sample_edge falling\n\ntransport select jtag\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/digilent_zedboard.cfg",
    "content": "#\n# Digilent Zedboard Rev.C, Rev.D with Xilinx Zynq chip\n#\n# http://zedboard.com/product/zedboard\n#\n\nsource [find interface/ftdi/digilent_jtag_smt2.cfg]\n\nreset_config srst_only srst_push_pull\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/diolan_lpc4350-db1.cfg",
    "content": "#\n# Diolan LPC-4350-DB1 development board\n#\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/diolan_lpc4357-db1.cfg",
    "content": "#\n# Diolan LPC-4357-DB1 development board\n#\n\nset CHIPNAME lpc4357\n\nsource [find target/lpc4357.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dk-tm4c129.cfg",
    "content": "echo \"WARNING: board/dk-tm4c129.cfg is deprecated, please switch to board/ti_dk-tm4c129.cfg\"\n\nsource [find board/ti_dk-tm4c129.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dm355evm.cfg",
    "content": "# DM355 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html\n#   http://c6000.spectrumdigital.com/evmdm355/\n\nsource [find target/ti_dm355.cfg]\n\nreset_config trst_and_srst separate\n\n# NOTE:  disable or replace this call to dm355evm_init if you're\n# debugging new UBL code from SRAM.\n$_TARGETNAME configure -event reset-init { dm355evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm355evm_init {} {\n\tglobal dm355\n\n\techo \"Initialize DM355 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tjtag_rclk 1500\n\n\t########################\n\t# PLL1\t\t= 432 MHz (/8, x144)\n\t# ...SYSCLK1\t= 216 MHz (/2)  ... ARM, MJCP\n\t# ...SYSCLK2\t= 108 MHz (/4)  ... Peripherals\n\t# ...SYSCLK3\t= 27  MHz (/16) ... VPBE, DAC\n\t# ...SYSCLK4\t= 108 MHz (/4)  ... VPSS\n\t#\tpll1.{prediv,div1,div2} are fixed\n\t#\tpll1.postdiv set in MISC (for *this* speed grade)\n\n\tset addr [dict get $dm355 pllc1]\n\tset pll_divs [dict create]\n\tdict set pll_divs div3 16\n\tdict set pll_divs div4 4\n\tpll_v02_setup $addr 144 $pll_divs\n\n\t# ARM is now running at 216 MHz, so JTAG can go faster\n\tjtag_rclk 20000\n\n\t########################\n\t# PLL2\t\t= 342 MHz (/8, x114)\n\t# ....SYSCLK1\t= 342 MHz (/1)  ... DDR PHY at 171 MHz, 2x clock\n\t#\tpll2.{postdiv,div1} are fixed\n\n\tset addr [dict get $dm355 pllc2]\n\tset pll_divs [dict create]\n\tdict set pll_divs div1 1\n\tdict set pll_divs prediv 8\n\tpll_v02_setup $addr 114 $pll_divs\n\n\t########################\n\t# PINMUX\n\n\t# All Video Inputs\n\tdavinci_pinmux $dm355 0 0x00007f55\n\t# All Video Outputs\n\tdavinci_pinmux $dm355 1 0x00145555\n\t# EMIFA (NOTE: more could be set up for use as GPIOs)\n\tdavinci_pinmux $dm355 2 0x00000c08\n\t# SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs\n\tdavinci_pinmux $dm355 3 0x1bff55ff\n\t# MMC/SD0 instead of MS; SPI0\n\tdavinci_pinmux $dm355 4 0x00000000\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t########################\n\t# DDR2 EMIF\n\n\t# VTPIOCR impedance calibration\n\tset addr [dict get $dm355 sysbase]\n\tset addr [expr {$addr + 0x70}]\n\n\t# clear CLR, LOCK, PWRDN; wait a clock; set CLR\n\tmmw $addr 0 0x20c0\n\tmmw $addr 0x2000 0\n\n\t# wait for READY\n        while { [expr {[mrw $addr] & 0x8000}] == 0 } { sleep 1 }\n\n\t# set IO_READY; then LOCK and PWRSAVE; then PWRDN\n\tmmw $addr 0x4000 0\n\tmmw $addr 0x0180 0\n\tmmw $addr 0x0040 0\n\n\t# NOTE:  this DDR2 initialization sequence borrows from\n\t# both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec.\n\n\t# reset (then re-enable) DDR controller\n\tpsc_reset 13\n\tpsc_go\n\tpsc_enable 13\n\tpsc_go\n\n\t# now set it up for Micron MT47H64M16HR-37E @ 171 MHz\n\n\tset addr [dict get $dm355 ddr_emif]\n\n\t# DDRPHYCR1\n\tmww [expr {$addr + 0xe4}] 0x50006404\n\n\t# PBBPR -- burst priority\n\tmww [expr {$addr + 0x20}] 0xfe\n\n\t# SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0x00800000 0\n\tmmw [expr {$addr + 0x08}] 0x0013c632 0x03870fff\n\n\t# SDTIMR0, SDTIMR1\n\tmww [expr {$addr + 0x10}] 0x2a923249\n\tmww [expr {$addr + 0x14}] 0x4c17c763\n\n\t# SDCR -- relock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0 0x00008000\n\n\t# SDRCR -- refresh rate (171 MHz * 7.8usec)\n\tmww [expr {$addr + 0x0c}] 1336\n\n\t########################\n\t# ASYNC EMIF\n\n\tset addr [dict get $dm355 a_emif]\n\n\t# slow/pessimistic timings\n\tset nand_timings 0x40400204\n\t# fast (25% faster page reads)\n\t#set nand_timings 0x0400008c\n\n\t# AWCCR\n\tmww [expr {$addr + 0x04}] 0xff\n\t# CS0 == socketed NAND (default MT29F16G08FAA, 2GByte)\n\tmww [expr {$addr + 0x10}] $nand_timings\n\t# CS1 == dm9000 Ethernet\n\tmww [expr {$addr + 0x14}] 0x00a00505\n\t# NANDFCR -- only CS0 has NAND\n\tmww [expr {$addr + 0x60}] 0x01\n\n\t# default: both chipselects to the NAND socket are used\n\tnand probe 0\n\tnand probe 1\n\n\t########################\n\t# UART0\n\n\tset addr [dict get $dm355 uart0]\n\n\t# PWREMU_MGNT -- rx + tx in reset\n\tmww [expr {$addr + 0x30}] 0\n\n\t# DLL, DLH -- 115200 baud\n\tmwb [expr {$addr + 0x20}] 0x0d\n\tmwb [expr {$addr + 0x24}] 0x00\n\n\t# FCR - clear and disable FIFOs\n\tmwb [expr {$addr + 0x08}] 0x07\n\tmwb [expr {$addr + 0x08}] 0x00\n\n\t# IER - disable IRQs\n\tmwb [expr {$addr + 0x04}] 0x00\n\n\t# LCR - 8-N-1\n\tmwb [expr {$addr + 0x0c}] 0x03\n\n\t# MCR - no flow control or loopback\n\tmwb [expr {$addr + 0x10}] 0x00\n\n\t# PWREMU_MGNT -- rx + tx normal, free running during JTAG halt\n\tmww [expr {$addr + 0x30}] 0xe001\n\n\n\t########################\n\n\t# turn on icache - set I bit in cp15 register c1\n\tarm mcr 15 0 0 1 0 0x00051078\n}\n\n# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one.\n#\n# NOTE:  \"hwecc4\" here presumes that if you're using the standard 2GB NAND\n# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to\n# use \"hwecc4_infix\" for the UBL; or else (b) aren't updating anything that\n# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc.\nset _FLASHNAME $_CHIPNAME.boot\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000\n\n# FIXME\n#  - support writing UBL with its header (new layout only with new ROMs)\n#  - support writing ABL/U-Boot with its header (new layout)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dm365evm.cfg",
    "content": "# DM365 EVM board -- Beta\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html\n#   http://support.spectrumdigital.com/boards/evmdm365\n\nsource [find target/ti_dm365.cfg]\n\n# NOTE:  in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG\n# connector, so it doesn't affect generation of the reset signal.\n# Accordingly, resets require something else.  ICEpick could do it;\n# but its docs aren't generally available.\n#\n# At this writing, newer boards aren't available ... so assume no SRST.\n# Also ICEpick docs aren't available ... so we must use watchdog reset,\n# and hope the CPU isn't wedged or in a WFI loop (either of which can\n# block access to CPU and thus watchdog registers).\n\nreset_config trst_only\n$_TARGETNAME configure -event reset-assert \"davinci_wdog_reset\"\n\n# SW5.1 routes CS0: NAND vs OneNAND.\n# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand)\n# for boot-from-flash, those must agree with SW4.3:1 settings.\n\nif { [info exists CS0MODE] } {\n\t# NAND or OneNAND\n\tset CS0 $CS0MODE\n} else {\n\tset CS0 \"\"\n\techo \"WARNING:  CS0 configuration not known\"\n\tproc cs0_setup {a_emif} {}\n\tproc flashprobe {} {}\n}\n\nset a_emif [dict get $dm365 a_emif]\n\n# As shipped:  boot from NAND.\nif { $CS0 == \"NAND\" } {\n\techo \"CS0 NAND\"\n\n\t# NAND socket has two chipselects.  Default MT29F16G08FAA chip\n\t# has 1GByte on each one.\n\t# NOTE:  \"hwecc4\" here presumes that you're not updating anything\n\t# that needs infix layout (e.g. UBL, old U-Boot, etc)\n\tnand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif\n\tnand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 8 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000016\n\n\t\t# slow/pessimistic timings\n\t\tset nand_timings 0x40400204\n\t\t# fast (25% faster page reads)\n\t\t#set nand_timings 0x0400008c\n\n\t\t# CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes)\n\t\tmww [expr {$a_emif + 0x10}] $nand_timings\n\n\t\t# NANDFCR -- CS0 has NAND\n\t\tmww [expr {$a_emif + 0x60}] 0x01\n\t}\n\tproc flashprobe {} {\n\t\tnand probe 0\n\t\tnand probe 1\n\t}\n\n} elseif { $CS0 == \"OneNAND\" } {\n\techo \"CS0 OneNAND\"\n\n\t# No support for this OneNAND in OpenOCD (yet) or Linux ...\n\t# REVISIT OneNAND timings not verified to work!\n\techo \"WARNING -- OneNAND not yet tested!\"\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 16 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000055\n\n\t\t# CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes)\n\t\tmww [expr {$a_emif + 0x10}] 0x00000001\n\n\t\t# ONENANDCTRL -- CS0 has OneNAND, enable sync reads\n\t\tmww [expr {$a_emif + 0x5c}] 0x0441\n\t}\n\tproc flashprobe {} { }\n}\n\n# NOTE:  disable or replace this call to dm365evm_init if you're\n# debugging new UBL/NANDboot code from SRAM.\n$_TARGETNAME configure -event reset-init { dm365evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm365evm_init {} {\n\tglobal dm365\n\n\techo \"Initialize DM365 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tadapter speed 1500\n\n\t# FIXME -- PLL init\n\n\t########################\n\t# PINMUX setup\n\n\tdavinci_pinmux $dm365 0 0x00fd0000\n\tdavinci_pinmux $dm365 1 0x00145555\n\t# mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand\n\tdavinci_pinmux $dm365 3 0x375affff\n\tdavinci_pinmux $dm365 4 0x55556555\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t# FIXME setup DDR2 (needs PLL)\n\n\t########################\n\t# ASYNC EMIF\n\n\tset a_emif [dict get $dm365 a_emif]\n\n\t# AWCCR\n\tmww [expr {$a_emif + 0x04}] 0xff\n\t# CS0 == NAND or OneNAND\n\tcs0_setup $a_emif\n\t# CS1 == CPLD\n\tmww [expr {$a_emif + 0x14}] 0x00a00505\n\n\t# FIXME setup UART0\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dm6446evm.cfg",
    "content": "# DM6446 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm6446.html\n#   http://c6000.spectrumdigital.com/davincievm/\n# EVM is just the board; buy that at Spectrum.\n# The \"kit\" from TI also has: video camera, LCD video monitor, more.\n\nsource [find target/ti_dm6446.cfg]\n\n# J4 controls what CS2 hooks up to, usually NOR or NAND flash.\n# S3.1/S3.2 controls boot mode, which may force J4 and S3.3 settings.\n# S3.3 controls AEMIF bus width.\n\nif { [info exists J4_OPTION] } {\n\t# NOR, NAND, SRAM, ...\n\tset CS2_MODE $J4_OPTION\n} else {\n\tset CS2_MODE \"\"\n}\n\n# ARM boot:\n#  S3.1 = 0, S3.2 = 0\t==> ROM/UBL boot via NAND (J4 == NAND)\n#  S3.1 = 1, S3.2 = 0\t==> AEMIF boot (J4 == NOR or SRAM)\n#  S3.1 = 0, S3.2 = 1\t==> ROM/UBL boot via HPI\n#  S3.1 = 1, S3.2 = 1\t==> ROM/UBL boot via UART (J4 == don't care)\n# AEMIF bus width:\n#  S3.3 = 0\t\t==> 8 bit bus width\n#  S3.3 = 1\t\t==> 16 bit bus width\n# DSP boot:\n#  S3.4 = 0\t\t==> controlled by ARM\n\nif { $CS2_MODE == \"NOR\" } {\n\t# 16 Mbytes address space; 16 bit bus width\n\t# (older boards used 32MB parts, with upper 16 MB unusable)\n\tset _FLASHNAME $_CHIPNAME.flash\n\tflash bank $_FLASHNAME cfi 0x02000000 0x01000000 2 2 $_TARGETNAME\n\tproc flashprobe {} { flash probe 0 }\n} elseif { $CS2_MODE == \"NAND\" } {\n\t# 64 Mbyte small page; 8 bit bus width\n\tnand device davinci $_TARGETNAME 0x02000000 hwecc1 0x01e00000\n\tproc flashprobe {} { nand probe 0 }\n} elseif { $CS2_MODE == \"SRAM\" } {\n\t# 4 Mbyte address space; 16 bit bus width\n\t# loaded via JTAG or HPI\n\tproc flashprobe {} {}\n} else {\n\t# maybe it's HPI boot?  can't tell...\n\techo \"WARNING:  CS2/flash configuration not recognized\"\n\tproc flashprobe {} {}\n}\n\n# NOTE:  disable or replace this call to dm6446evm_init if you're\n# debugging new UBL code from SRAM (for NAND boot).\n$_TARGETNAME configure -event reset-init { dm6446evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm6446evm_init {} {\n\n\techo \"Initialize DM6446 EVM board\"\n\n\t# FIXME initialize everything:\n\t#  - PLL1\n\t#  - PLL2\n\t#  - PINMUX\n\t#  - PSC\n\t#  - DDR\n\t#  - AEMIF\n\t#  - UART0\n\t#  - icache\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dp_busblaster_v3.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v3.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c32a tap -expected-id 0x06e1c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dp_busblaster_v4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://raw.githubusercontent.com/dergraaf/busblaster_v4/master/ktlink/ktlink.svf\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v4.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c64a tap -expected-id 0x06e5c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/dptechnics_dpt-board-v1.cfg",
    "content": "# Product page:\n# https://www.dptechnics.com/en/products/dpt-board-v1.html\n#\n# JTAG is a 5 pin array located close to main module in following order:\n# 1. JTAG TCK\n# 2. JTAG TDO\n# 3. JTAG TDI\n# 4. JTAG TMS\n# 5. GND\tThe GND is located near letter G of word JTAG on board.\n#\n# Two RST pins are connected to:\n# 1. GND\n# 2. GPIO11\tthis pin is located near letter R of word RST.\n#\n# To enable EJTAG mode, GPIO11 (RST[1]) pin should be pulled up. For example\n# with 10K resistor connected to V3.3 pin.\n#\n# This board is powered from micro USB connector. No real reset pin or button, for\n# example RESET_L is available.\n\nsource [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr2_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/efikamx.cfg",
    "content": "# Genesi USA EfikaMX\n#  http://www.genesi-usa.com/products/efika\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 6000 }\n\nsource [find target/imx51.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/efm32.cfg",
    "content": "# Configuration for EFM32 boards with on-board SEGGER J-Link\n#\n# Tested with Tiny, Giant and Zero Gecko Starter Kit.\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nset CHIPNAME efm32\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/eir.cfg",
    "content": "# Elector Internet Radio board\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nsource [find target/at91sam7se512.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# WDT_MR, disable watchdog\n\tmww 0xFFFFFD44 0x00008000\n\n\t# RSTC_MR, enable user reset\n\tmww 0xfffffd08 0xa5000001\n\n\t# CKGR_MOR\n\tmww 0xFFFFFC20 0x00000601\n\tsleep 10\n\n\t# CKGR_PLLR\n\tmww 0xFFFFFC2C 0x00481c0e\n\tsleep 10\n\n\t# PMC_MCKR\n\tmww 0xFFFFFC30 0x00000007\n\tsleep 10\n\n\t# PMC_IER\n\tmww 0xFFFFFF60 0x00480100\n\n\t#\n\t# Enable SDRAM interface.\n\t#\n\n\t# Enable SDRAM control at PIO A.\n\tmww 0xfffff474 0x3f800000 ;# PIO_BSR_OFF\n\tmww 0xfffff404 0x3f800000 ;# PIO_PDR_OFF\n\n\t# Enable address bus (A0, A2-A11, A13-A17) at PIO B\n\tmww 0xfffff674 0x0003effd ;# PIO_BSR_OFF\n\tmww 0xfffff604 0x0003effd ;# PIO_PDR_OFF\n\n\t# Enable 16 bit data bus at PIO C\n\tmww 0xfffff870 0x0000ffff ;# PIO_ASR_OFF\n\tmww 0xfffff804 0x0000ffff ;# PIO_PDR_OFF\n\n\t# Enable SDRAM chip select\n\tmww 0xffffff80 0x00000002 ;# EBI_CSA_OFF\n\n\t# Set SDRAM characteristics in configuration register.\n\t# Hard coded values for MT48LC32M16A2 with 48MHz CPU.\n\tmww 0xffffffb8 0x2192215a ;# SDRAMC_CR_OFF\n\tsleep 10\n\n\t# Issue 16 bit SDRAM command: NOP\n\tmww 0xffffffb0 0x00000011 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Precharge all\n\tmww 0xffffffb0 0x00000012 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 8 auto-refresh cycles\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Set mode register\n\tmww 0xffffffb0 0x00000013 ;# SDRAMC_MR_OFF\n\tmww 0x20000014 0xcafedede\n\n\t# Set refresh rate count ???\n\tmww 0xffffffb4 0x00000013 ;# SDRAMC_TR_OFF\n\n\t# Issue 16 bit SDRAM command: Normal mode\n\tmww 0xffffffb0 0x00000010 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000180\n\n\t#\n\t# Enable external reset key.\n\t#\n\tmww 0xfffffd08 0xa5000001\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s1968.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S1968 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s1968\n#\n\n# NOTE:  to use J-Link instead of the on-board interface,\n# you may also need to reduce adapter speed to be about 1200.\n# source [find interface/jlink.cfg]\n\n# include the FT2232 interface config for on-board JTAG interface\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s1968\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s3748.cfg",
    "content": "#\n# TI/Luminary Stellaris lm3s3748 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s3748\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s3748\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s6965.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S6965 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s6965\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x5000\nset CHIPNAME lm3s6965\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s811-revb.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits (rev B and earlier)\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE: newer 811-EK boards (rev C and above) shouldn't use this.\n# use board/ek-lm3s811.cfg\nsource [find interface/ftdi/luminary-lm3s811.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s811.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\n# NOTE:  older '811-EK boards (before rev C) shouldn't use this.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s8962.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S8962 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s8962\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s8962\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s9b9x.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9B9x Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9b90\n# http://www.ti.com/tool/ek-lm3s9b92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s9b9x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm3s9d92.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9D92 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9d92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s9d92\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm4f120xl.cfg",
    "content": "#\n# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f120xl\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f120h5qr\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-lm4f232.cfg",
    "content": "#\n# TI Stellaris LM4F232 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f232\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f23x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-tm4c123gxl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c123gxl.cfg is deprecated, please switch to board/ti_ek-tm4c123gxl.cfg\"\n\nsource [find board/ti_ek-tm4c123gxl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ek-tm4c1294xl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c1294xl.cfg is deprecated, please switch to board/ti_ek-tm4c1294xl.cfg\"\n\nsource [find board/ti_ek-tm4c1294xl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/embedded-artists_lpc2478-32.cfg",
    "content": "# Embedded Artists eval board for LPC2478\n# http://www.embeddedartists.com/\n\n# Target device: LPC2478\nset CCLK 72000\nsource [find target/lpc2478.cfg]\n\n# Helper\n#\nproc read_register {register} {\n    return [read_memory $register 32 1]\n}\n\nproc init_board {} {\n    # Delays on reset lines\n    adapter srst delay 500\n    jtag_ntrst_delay 1\n\n    # Adaptive JTAG clocking through RTCK.\n    #\n    jtag_rclk 20\n\n    global _TARGETNAME\n    global _CHIPNAME\n\n    # A working area will help speeding the flash programming\n    $_TARGETNAME configure -work-area-phys 0x40000200 -work-area-size [expr {0x10000-0x200-0x20}] -work-area-backup 0\n\n    # External 16-bit flash at chip select CS0 (SST39VF3201-70, 4 MiB)\n    flash bank $_CHIPNAME.extflash cfi 0x80000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n    # Event handlers\n    #\n    $_TARGETNAME configure -event reset-start {\n        # Back to the slow JTAG clock\n        jtag_rclk 20\n    }\n\n    $_TARGETNAME configure -event reset-init {\n        arm core_state arm\n        arm7_9 dcc_downloads enable     ;# Speed up downloads by using DCC transfer\n        arm7_9 fast_memory_access enable\n\n        # Peripheral clocks\n        mww 0xE01FC0C4 0x04280FFE       ;# PCONP: (reset value)\n\n        # Map the user flash to the vector table area (0x00...0x3F)\n        mww 0xE01FC040 0x00000001       ;# MEMMAP: User flash\n\n        # Memory accelerator module\n        mww 0xE01FC004 0x00000003       ;# MAMTIM: 3 clock cycles\n        mww 0xE01FC000 0x00000002       ;# MAMCR: fully enabled\n\n        # Enable external memory bus (32-bit SDRAM at DYCS0, 16-bit flash at CS0)\n        mww 0xE002C014 0x55010115       ;# PINSEL5: P2.16=CAS, P2.17=RAS, P2.18=CLKOUT0,\n                                         # P2.20=DYCS0, P2.24=CKEOUT0, P2.28=DQMOUT0,\n                                         # P2.29=DQMOUT1, P2.30=DQMOUT2, P2.31=DQMOUT3\n        mww 0xE002C018 0x55555555       ;# PINSEL6: P3.0...P3.15=D0...D15\n        mww 0xE002C01C 0x55555555       ;# PINSEL7: P3.16...P3.31=D16...D31\n        mww 0xE002C020 0x55555555       ;# PINSEL8: P4.0...P4.15=A0...A15\n        mww 0xE002C024 0x50051555       ;# PINSEL9: P4.16...P4.22=A16...A22, P4.24=OE,\n                                         # P4.25=WE, P4.30=CS0, P4.31=CS1\n        mww 0xFFE08000 0x00000001       ;# EMCControl: Enable EMC\n\n        # Start PLL, then use faster JTAG clock\n        enable_pll\n        jtag_rclk 3000\n\n        # 16-bit flash @ CS0 (SST39VF3201-70)\n        mww 0xFFE08200 0x00080081       ;# EMCStaticConfig0: 16 bit, PB=1, buffers on\n        mww 0xFFE08204 0x00000000       ;# EMCStaticWaitWen0\n        mww 0xFFE08208 0x00000000       ;# EMCStaticWaitOen0\n        mww 0xFFE0820C 0x00000005       ;# EMCStaticWaitRd0\n        mww 0xFFE08210 0x00000005       ;# EMCStaticWaitPage0\n        mww 0xFFE08214 0x00000003       ;# EMCStaticWaitWr0\n        mww 0xFFE08218 0x00000001       ;# EMCStaticWaitTurn0\n\n        # 8-bit NAND @ CS1\n        # TODO\n\n        # 32-bit SDRAM @ DYCS0 (K4M563233G-HN75)\n        mww 0xFFE08028 0x00000001       ;# EMCDynamicReadConfig\n        mww 0xFFE08030 0x00000001       ;# EMCDynamicRP\n        mww 0xFFE08034 0x00000003       ;# EMCDynamicRAS\n        mww 0xFFE08038 0x00000005       ;# EMCDynamicSREX\n        mww 0xFFE0803C 0x00000001       ;# EMCDynamicAPR\n        mww 0xFFE08040 0x00000005       ;# EMCDynamicDAL\n        mww 0xFFE08044 0x00000001       ;# EMCDynamicWR\n        mww 0xFFE08048 0x00000005       ;# EMCDynamicRC\n        mww 0xFFE0804C 0x00000005       ;# EMCDynamicRFC\n        mww 0xFFE08050 0x00000005       ;# EMCDynamicXSR\n        mww 0xFFE08054 0x00000001       ;# EMCDynamicRRD\n        mww 0xFFE08058 0x00000001       ;# EMCDynamicMRD\n        #\n        mww 0xFFE08104 0x00000202       ;# EMCDynamicRasCas0\n        mww 0xFFE08100 0x00005488       ;# EMCDynamicConfig0\n        sleep 100\n        mww 0xFFE08020 0x00000183       ;# EMCDynamicControl: Clock on continuously, NOP\n        sleep 10\n        mww 0xFFE08020 0x00000103       ;# EMCDynamicControl: PRECHARGE-ALL\n        mww 0xFFE08024 0x00000046       ;# EMCDynamicRefresh\n        sleep 100\n        mww 0xFFE08020 0x00000083       ;# EMCDynamicControl: MODE\n        mdw 0xA0011000 1                ;# Set SDRAM mode register\n        mww 0xFFE08020 0x00000000       ;# EMCDynamicControl: NORMAL\n        mww 0xFFE08100 0x00085488       ;# EMCDynamicConfig0: Enable buffers\n    }\n\n    $_TARGETNAME configure -event gdb-attach {\n        # Without this gdb-attach will first time as probe will fail\n        reset init\n    }\n}\n\n# Enable the PLL.\n# Generate maximum CPU clock (72 MHz) Run from internal RC oscillator.\n# Note: The PLL output runs at a frequency N times the desired CPU clock.\n#       It in unavoidable that the CPU clock drops down to (4 MHz/N) during\n#       the initialization!\n#       Here: N=4\n#       Note that if the PLL is already active at the time this script is\n#       called, the effective value of N is the value of CCLKCFG at that time!\n#\nproc enable_pll {} {\n    # Disconnect PLL in case it is already connected\n    if {[expr {[read_register 0xE01FC080] & 0x03}] == 3} {\n        # Disconnect it, but leave it enabled\n        # (This MUST be done in two steps)\n        mww 0xE01FC080 0x00000001       ;# PLLCON: disconnect PLL\n        mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n        mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    }\n    # Disable PLL (as it might already be enabled at this time!)\n    mww 0xE01FC080 0x00000000       ;# PLLCON: disable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n\n    # Setup PLL to generate 288 MHz from internal RC oscillator\n    mww 0xE01FC10C 0x00000000       ;# CLKSRCSEL: IRC\n    mww 0xE01FC084 0x00000023       ;# PLLCFG: N=1, M=36\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    mww 0xE01FC080 0x00000001       ;# PLLCON: enable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    sleep 100\n    mww 0xE01FC104 0x00000003       ;# CCLKCFG: divide by 4 (72 MHz)\n    mww 0xE01FC080 0x00000003       ;# PLLCON: connect PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/emcraft_imx8m-som-bsb.cfg",
    "content": "#\n# configuration file for Emcraft IMX8M-SOM-BSB\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# SRST and TRST are wired up\nreset_config trst_and_srst\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/emcraft_twr-vf6-som-bsb.cfg",
    "content": "#\n# EmCraft Systems TWR-VF6-SOM-BSB\n#\n# http://www.emcraft.com/products/259#twr-kit\n#\n\nsource [find board/emcraft_vf6-som.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/emcraft_vf6-som.cfg",
    "content": "#\n# EmCraft Systems Vybrid VF6 SOM\n#\n# http://www.emcraft.com/products/259#som\n#\n\nset CHIPNAME vf610\nsource [find target/vybrid_vf6xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/esp32s2-kaluga-1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S2 Kaluga board.\n#\n# For example, OpenOCD can be started for ESP32-S2 debugging on\n#\n#   openocd -f board/esp32s2-kaluga-1.cfg\n#\n\nsource [find interface/ftdi/esp32s2_kaluga_v1.cfg]\nsource [find target/esp32s2.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n# On ESP32-S2, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ethernut3.cfg",
    "content": "#\n# Ethernut 3 board configuration file\n#\n# http://www.ethernut.de/en/hardware/enut3/\n\n\n# AT91R40008-66AU ARM7TDMI Microcontroller\n# 256kB internal RAM\nsource [find target/at91r40008.cfg]\n\n\n# AT49BV322A-70TU NOR Flash\n# 2M x 16 mode at address 0x10000000\n# Common flash interface supported\n#\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME\n\n\n# Micrel MIC2775-29YM5 Supervisor\n# Reset output will remain active for 280ms (maximum)\n#\nadapter srst delay 300\njtag_ntrst_delay 300\n\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\nadapter speed 16000\n\n\n# Target events\n#\n$_TARGETNAME configure -event reset-init { board_init }\n\n# Initialize board hardware\n#\nproc board_init { } {\n\tboard_remap\n\tflash probe 0\n}\n\n# Memory remap\n#\nproc board_remap {{VERBOSE 0}} {\n\t# CS0: NOR flash\n\t#      16MB @ 0x10000000\n\t#      16-bit data bus\n\t#      4 wait states\n\t#\n\tmww 0xffe00000 0x1000212d\n\n\t# CS1: Ethernet controller\n\t#      1MB @ 0x20000000\n\t#      16-bit data bus\n\t#      2 wait states\n\t#      Byte select access\n\t#\n\tmww 0xffe00004 0x20003025\n\n\t# CS2: CPLD registers\n\t#      1MB @ 0x21000000\n\t#      8-bit data bus\n\t#      2 wait states\n\t#\n\tmww 0xffe00008 0x21002026\n\n\t# CS3: Expansion bus\n\t#      1MB @ 0x22000000\n\t#      8-bit data bus\n\t#      8 wait states\n\t#\n\tmww 0xffe00010 0x22002e3e\n\n\t# Remap command\n\t#\n\tmww 0xffe00020 0x00000001\n\n\tif {$VERBOSE != 0} {\n\t\techo \"0x00000000 RAM\"\n\t\techo \"0x10000000 Flash\"\n\t\techo \"0x20000000 Ethernet\"\n\t\techo \"0x21000000 CPLD\"\n\t\techo \"0x22000000 Expansion\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/evb-lan9255.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip LAN9255 evaluation board\n# https://www.microchip.com/en-us/development-tool/EV25Y25A\n#\n\nset CHIPNAME same53\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/frdm-kl25z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL25Z128VLK4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL25Z128VLK4\n\nreset_config srst_only\n\nsource [find target/kl25.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/frdm-kl46z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL46Z256VLL4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL46Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL46Z256VLL4\n\nreset_config srst_only\n\nsource [find target/kl46.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/fsl_imx6q_sabresd.cfg",
    "content": "#\n# Board configuration file for the Freescale IMX6Q Sabre SD EVM\n#\n# This board does not have an embedded JTAG adapter, you must source\n# a suitable adapter configuration before sourcing this file.\n\n# Sabre SD has a standard ARM-20 JTAG connector with\n# nTRST and nSRST available.\nreset_config trst_and_srst\n\n# the only possible transport is JTAG\ntransport select jtag\n\n# iMX6Q POR gates JTAG and the chip is completely incommunicado\n# over JTAG for at least 10ms after nSRST is deasserted\nadapter srst delay 11\n\n# Source generic iMX6Q target configuration\nset CHIPNAME imx6q\nsource [find target/imx6.cfg]\n\n# function to apply initial configuration after a reset. It\n# provides a basic pad configuration and also DDR memory and clocks\n# sufficient to load and execute a boot loader (e.g. barebox) from\n# DDR memory. This list is extracted from the barebox flash image\n# header.\nproc apply_dcd { } {\n\tmww 0x020e05a8 0x00000030\n\tmww 0x020e05b0 0x00000030\n\tmww 0x020e0524 0x00000030\n\tmww 0x020e051c 0x00000030\n\tmww 0x020e0518 0x00000030\n\tmww 0x020e050c 0x00000030\n\tmww 0x020e05b8 0x00000030\n\tmww 0x020e05c0 0x00000030\n\tmww 0x020e05ac 0x00020030\n\tmww 0x020e05b4 0x00020030\n\tmww 0x020e0528 0x00020030\n\tmww 0x020e0520 0x00020030\n\tmww 0x020e0514 0x00020030\n\tmww 0x020e0510 0x00020030\n\tmww 0x020e05bc 0x00020030\n\tmww 0x020e05c4 0x00020030\n\tmww 0x020e056c 0x00020030\n\tmww 0x020e0578 0x00020030\n\tmww 0x020e0588 0x00020030\n\tmww 0x020e0594 0x00020030\n\tmww 0x020e057c 0x00020030\n\tmww 0x020e0590 0x00003000\n\tmww 0x020e0598 0x00003000\n\tmww 0x020e058c 0x00000000\n\tmww 0x020e059c 0x00003030\n\tmww 0x020e05a0 0x00003030\n\tmww 0x020e0784 0x00000030\n\tmww 0x020e0788 0x00000030\n\tmww 0x020e0794 0x00000030\n\tmww 0x020e079c 0x00000030\n\tmww 0x020e07a0 0x00000030\n\tmww 0x020e07a4 0x00000030\n\tmww 0x020e07a8 0x00000030\n\tmww 0x020e0748 0x00000030\n\tmww 0x020e074c 0x00000030\n\tmww 0x020e0750 0x00020000\n\tmww 0x020e0758 0x00000000\n\tmww 0x020e0774 0x00020000\n\tmww 0x020e078c 0x00000030\n\tmww 0x020e0798 0x000c0000\n\tmww 0x021b081c 0x33333333\n\tmww 0x021b0820 0x33333333\n\tmww 0x021b0824 0x33333333\n\tmww 0x021b0828 0x33333333\n\tmww 0x021b481c 0x33333333\n\tmww 0x021b4820 0x33333333\n\tmww 0x021b4824 0x33333333\n\tmww 0x021b4828 0x33333333\n\tmww 0x021b0018 0x00081740\n\tmww 0x021b001c 0x00008000\n\tmww 0x021b000c 0x555a7975\n\tmww 0x021b0010 0xff538e64\n\tmww 0x021b0014 0x01ff00db\n\tmww 0x021b002c 0x000026d2\n\tmww 0x021b0030 0x005b0e21\n\tmww 0x021b0008 0x09444040\n\tmww 0x021b0004 0x00025576\n\tmww 0x021b0040 0x00000027\n\tmww 0x021b0000 0x831a0000\n\tmww 0x021b001c 0x04088032\n\tmww 0x021b001c 0x0408803a\n\tmww 0x021b001c 0x00008033\n\tmww 0x021b001c 0x0000803b\n\tmww 0x021b001c 0x00428031\n\tmww 0x021b001c 0x00428039\n\tmww 0x021b001c 0x09408030\n\tmww 0x021b001c 0x09408038\n\tmww 0x021b001c 0x04008040\n\tmww 0x021b001c 0x04008048\n\tmww 0x021b0800 0xa1380003\n\tmww 0x021b4800 0xa1380003\n\tmww 0x021b0020 0x00005800\n\tmww 0x021b0818 0x00022227\n\tmww 0x021b4818 0x00022227\n\tmww 0x021b083c 0x434b0350\n\tmww 0x021b0840 0x034c0359\n\tmww 0x021b483c 0x434b0350\n\tmww 0x021b4840 0x03650348\n\tmww 0x021b0848 0x4436383b\n\tmww 0x021b4848 0x39393341\n\tmww 0x021b0850 0x35373933\n\tmww 0x021b4850 0x48254A36\n\tmww 0x021b080c 0x001f001f\n\tmww 0x021b0810 0x001f001f\n\tmww 0x021b480c 0x00440044\n\tmww 0x021b4810 0x00440044\n\tmww 0x021b08b8 0x00000800\n\tmww 0x021b48b8 0x00000800\n\tmww 0x021b001c 0x00000000\n\tmww 0x021b0404 0x00011006\n\tmww 0x020c4068 0x00c03f3f\n\tmww 0x020c406c 0x0030fc03\n\tmww 0x020c4070 0x0fffc000\n\tmww 0x020c4074 0x3ff00000\n\tmww 0x020c4078 0x00fff300\n\tmww 0x020c407c 0x0f0000c3\n\tmww 0x020c4080 0x000003ff\n\tmww 0x020e0010 0xf00000cf\n\tmww 0x020e0018 0x007f007f\n\tmww 0x020e001c 0x007f007f\n}\n\n# disable watchdog\nproc disable_wdog { } {\n\tmwh 0x020bc000 0x30\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc imx6q_sabresd_init { } {\n\tdisable_wdog\n\tapply_dcd\n}\n\n# prevent cortex-a code from asserting SRST again\n$_TARGETNAME.0 configure -event reset-assert { }\n# hook the init function into the reset-init event\n$_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/glyn_tonga2.cfg",
    "content": "#\n# Glyn Tonga2 SO-DIMM CPU module (Toshiba TMPA900CMXBG, ARM9)\n#\n# http://toshiba-mikrocontroller.de/sites/TMPA900CPUBOARDStarter.htm\n#\n# Hardware on the S0-DIMM module:\n#   - Toshiba TMPA900CMXBG (ARM9, ARM926EJ-S, max. 200MHz)\n#   - DDR SDRAM: Hynix H5MS5162DFR-J3M (64Mbyte, x16, 1.8V, 166/83MHz at CL3/2)\n#   - NAND flash: Samsung K9F2G08U0B-PIB0 (256M x 8 Bit, 3.3V)\n#   - Ethernet: SMSC LAN9221I-ABZJ (10/100Mbit, Non-PCI, 16 bit interface)\n#\n\nsource [find target/tmpa900.cfg]\n\n########################\n# Target configuration #\n########################\n\n# Initial JTAG speed should not exceed 1/6 of the initial CPU clock\n# frequency (24MHz). Be conservative and use 1/8 of the frequency.\n# (24MHz / 8 = 3MHz)\nadapter speed 3000\n\n$_TARGETNAME configure -event reset-start {\n\t# Upon reset, set the JTAG frequency to 3MHz again, see above.\n\techo \"Setting JTAG speed to 3MHz until clocks are initialized.\"\n\tadapter speed 3000\n\n\t# Halt the CPU.\n\thalt\n\n\t# Disable faster memory access for now.\n\tarm7_9 fast_memory_access disable\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# Setup clocks, and initialize SRAM and DDR SDRAM.\n\ttonga2_init\n\n\t# At this point the CPU is running at 192MHz, increase JTAG speed.\n\t# Tests showed that 15MHz works OK, higher speeds can cause problems,\n\t# though. Not sure if this is a CPU issue or JTAG adapter issue.\n\techo \"Increasing JTAG speed to 15MHz.\"\n\tadapter speed 15000\n\n\t# Enable faster memory access.\n\tarm7_9 fast_memory_access enable\n}\n\nproc tonga2_init { } {\n\t######################\n\t# PLL initialization #\n\t######################\n\n\t# Clock overview (see datasheet chapter 3.5.2, page 57):\n\t#   - fs: Low-frequency oscillator\n\t#   - fOSCH: High-frequency oscillator (24MHz on this board)\n\t#   - fPLL = fOSCH * multiplier (where multiplier can be 6 or 8)\n\t#   - fFCLK = fPLL / gear (where gear can be 1/2/4/8)\n\t#   - fHCLK is always fFCLK/2. fPCLK is also fFCLK/2.\n\t#\n\t# We select multiplier = 8 and gear = 1, so\n\t#   fFCLK = fOSCH * 8 / 1 = 192MHz.\n\n\t# SYSCR3 (System Control Register 3): Disable and configure PLL.\n\t#   - PLL operation control: off\n\t#   - PLL constant value setting 1: always 0, as per datasheet\n\t#   - PLL constant value setting 2: x8 (multiplier = 8)\n\tmww 0xf005000c 0x00000007\n\n\t# SYSCR4 (System Control Register 4): Configure PLL.\n\t#   - PLL constant value setting 3: 140MHz or more\n\t#   - PLL constant value setting 4: always 1, as per datasheet\n\t#   - PLL constant value setting 5: 140MHz or more\n\tmww 0xf0050010 0x00000065\n\n\t# SYSCR3 (System Control Register 3): Enable PLL.\n\t#   - PLL operation control: on\n\t#   - All other bits remain set as above.\n\tmww 0xf005000c 0x00000087\n\n\t# Wait for PLL to stabilize.\n\tsleep 10\n\n\t# SYSCR2 (System Control Register 2): Switch from fOSCH to fPLL.\n\t#   - Selection of the PLL output clock: fPLL\n\tmww 0xf0050008 0x00000002\n\n\t# SYSCR1 (System Control Register 1):\n\t#   - Clock gear programming: fc/1 (i.e., gear = 1, don't divide).\n\tmww 0xf0050004 0x00000000\n\n\t# CLKCR5 (Clock Control Register 5): Set bits 3 and 6. The datasheet\n\t# says the bits are reserved, but also recommends \"Write as one\".\n\tmww 0xf0050054 0x00000048\n\n\n\t##############################################################\n\t# Dynamic Memory Controller (DMC) / DDR SDRAM initialization #\n\t##############################################################\n\n\t# PMC (Power Management Controller):\n\t# PMCDRV (External Port \"Driverbility\" control register):\n\t# Bits DRV_MEM0/DRV_MEM1 (memory relation port drive power):\n\tmww 0xf0020260 0x00000003\t;# Select 1.8V +/- 0.1V\n\n\t# Setup DDR SDRAM timing parameters for our specific chip.\n\tmww 0xf4310014 0x00000004\t;# cas_latency = 2\n\tmww 0xf4310018 0x00000001\t;# t_dqss = 1\n\tmww 0xf431001c 0x00000002\t;# t_mrd = 2\n\tmww 0xf4310020 0x0000000a\t;# t_ras = 10\n\tmww 0xf4310024 0x0000000a\t;# t_rc = 10\n\tmww 0xf4310028 0x00000013\t;# t_rcd = 3, schedule_rcd = 2\n\tmww 0xf431002c 0x0000010a\t;# t_rfc = 10, schedule_rfc = 8\n\tmww 0xf4310030 0x00000013\t;# t_rp = 3, schedule_rp = 2\n\tmww 0xf4310034 0x00000002\t;# t_rrd = 2\n\tmww 0xf4310038 0x00000002\t;# t_wr = 2\n\tmww 0xf431003c 0x00000001\t;# t_wtr = 1\n\tmww 0xf4310040 0x0000000a\t;# t_xp = 10\n\tmww 0xf4310044 0x0000000c\t;# t_xsr = 12\n\tmww 0xf4310048 0x00000014\t;# t_esr = 20\n\n\t# dmc_memory_cfg_5 (DMC Memory Configuration register):\n\t# Set memory configuration:\n\t# column_bits = 10, row_bits = 13, ap-bit = 10, power_down_prd = 0,\n\t# auto_power_down = disable, stop_mem_clock = disable, memory_burst = 4\n\tmww 0xf431000c 0x00010012\n\n\t# dmc_user_config_5 (DMC user_config register):\n\t# Data bus width of DDR SDRAM: 16 bit\n\tmww 0xf4310304 0x00000058\n\n\t# dmc_refresh_prd_5 (DMC Refresh Period register):\n\t# Auto refresh: every 2656 (0xa60) DMCSCLK periods.\n\tmww 0xf4310010 0x00000a60\n\n\t# dmc_chip_0_cfg_5 (DMC chip_0_cfg registers):\n\t#   - SDRAM address structure: bank, row, column\n\t#   - address_match = 01000000 (start address [31:24])\n\t#   - address_mask  = 11111100 (start address [31:24] mask value)\n\tmww 0xf4310200 0x000140fc\n\n\t# Initialize the DDR SDRAM chip.\n\t# dmc_direct_cmd_5 (DMC Direct Command register).\n\t# See datasheet chapter 3.10.5.1, page 268.\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x00000000\t;# RAM init: Precharge all\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00080032\t;# RAM init: addr_13_to_0 = 0x32\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x000a0000\t;# RAM init: bank_addr = bank 2\n\n\t# dmc_id_<0-5>_cfg_5 (DMC id_<0-5>_cfg registers):\n\t# Set min./max. QoS values.\n\t#   - 0x5: Enable QoS, max. QoS = 1\n\t#   - 0xb: Enable QoS, min. QoS = 2\n\tmww 0xf4310100 0x00000005\t;# AHB0: CPU Data\n\tmww 0xf4310104 0x00000005\t;# AHB1: CPU Inst\n\tmww 0xf4310108 0x0000000b\t;# AHB2: LCDC\n\tmww 0xf431010c 0x00000005\t;# AHB3: LCDDA, USB\n\tmww 0xf4310110 0x00000005\t;# AHB4: DMA1\n\tmww 0xf4310114 0x00000005\t;# AHB5: DMA2\n\n\t# dmc_memc_cmd_5 (DMC Memory Controller Command register):\n\t# Change DMC state to ready.\n\tmww 0xf4310004 0x00000000\t;# memc_cmd = \"Go\"\n\n\t# EBI: SMC Timeout register\n\tmww 0xf00a0050 0x00000001\t;# smc_timeout = 1\n\n\n\t########################################################\n\t# Static Memory Controller (SMC) / SRAM initialization #\n\t########################################################\n\n\t# smc_set_cycles_5 (SMC Set Cycles register):\n\t# tRC = 10, tWC = 10, tCEOE = 7, tWP = 5, tPC=2, tTR=2\n\tmww 0xf4311014 0x0004afaa\n\n\t# smc_set_opmode_5 (SMC Set Opmode register):\n\t# Memory data bus width = 16 bits, async read mode, read burst\n\t# length = 1 beat, async write mode, write burst length = 1 beat,\n\t# byte enable (SMCBE0-1) timing = SMCCSn timing, memory burst boundary\n\t# split setting = burst can cross any address boundary\n\tmww 0xf4311018 0x00000001\n\n\t# smc_direct_cmd_5 (SMC Direct Command register):\n\t# cmd_type = UpdateRegs, chip_select = CS1\n\tmww 0xf4311010 0x00c00000\n\n\techo \"Clocks, SRAM, and DDR SDRAM are now initialized.\"\n}\n\n#######################\n# Flash configuration #\n#######################\n\n# TODO: Implement NAND support.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/gti/espressobin.cfg",
    "content": "# config for ESPRESSObin from\n# Globalscale Technologies Inc.\n\n# srst is isolated through missing resistor\nreset_config trst_only\n\nsource [find target/marvell/88f3720.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/gumstix-aerocore.cfg",
    "content": "# JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on\n# the first interface of a Quad FTDI chip.  nTRST is bit 4.\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\n\nftdi layout_init 0x0000 0x001b\nftdi layout_signal nTRST -data 0x0010\n\nsource [find target/stm32f4x.cfg]\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hammer.cfg",
    "content": "# Target Configuration for the TinCanTools S3C2410 Based Hammer Module\n# http://www.tincantools.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# Reset Script for the TinCanTools S3C2410 Based Hammer Module\n\t# http://www.tincantools.com\n\t#\n\t# Setup primary clocks and initialize the SDRAM\n\tmww 0x53000000 0x00000000\n\tmww 0x4a000008 0xffffffff\n\tmww 0x4a00000c 0x000007ff\n\tmww 0x4c000000 0x00ffffff\n\tmww 0x4c000014 0x00000003\n\tmww 0x4c000004 0x000a1031\n\tmww 0x48000000 0x11111122\n\tmww 0x48000004 0x00000700\n\tmww 0x48000008 0x00000700\n\tmww 0x4800000c 0x00000700\n\tmww 0x48000010 0x00000700\n\tmww 0x48000014 0x00000700\n\tmww 0x48000018 0x00000700\n\tmww 0x4800001c 0x00018005\n\tmww 0x48000020 0x00018005\n\tmww 0x48000024 0x009c0459\n\tmww 0x48000028 0x000000b2\n\tmww 0x4800002c 0x00000030\n\tmww 0x48000030 0x00000030\n\tflash probe 0\n}\n\n\n#flash configuration\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxdb500sys.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for paired K4S561632C (64MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C13261\n  mww 0x00100140 0x030D0121\n\n  puts \"Configuring SRAM nCS0 for 150ns paired Par. Flash (x32)\"\n  mww 0x00100100 0x0201000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x02000000 4 4 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxeb500hmi.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads disable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC8M32 (32MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0111\n\n  puts \"Configuring SRAM nCS0 for 150ns Par. Flash (x16)\"\n  mww 0x00100100 0x0101000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxhx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx10.cfg]\n\n# Usually it is not needed to set srst_pulls_trst\n# but sometimes it does not work without it. If you encounter\n# problems try to line below\n# reset_config trst_and_srst srst_pulls_trst\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1\n\n# Par. Flash can only be accessed if DIP switch on the board is set in proper\n# position and init_sdrambus was called. Don't call these functions if the DIP\n# switch is in invalid position, as some outputs may collide. This is why this\n# function is not called automatically\nproc flash_init { } {\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x101C0100 0x01010008\n\n  flash probe 0\n}\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\nproc init_clocks { } {\n  puts \"Enabling all clocks \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n\n  mww  0x101c0028 0x00007511\n}\n\nproc init_sdrambus { } {\n  puts \"Initializing external SDRAM Bus 16 Bit \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n  mww  0x101c0C40 0x00000050\n\n  puts \"Configuring SDRAM controller for K4S561632E (32MB) \"\n  mww 0x101C0140 0\n  sleep 100\n  #mww 0x101C0144 0x00a13262\n  mww 0x101C0144 0x00a13251\n  mww 0x101C0148 0x00000033\n  mww 0x101C0140 0x030d0121\n}\n\n$_TARGETNAME configure -event reset-init {\n  halt\n  wait_halt 1000\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  init_clocks\n#  init_sdrambus\n\n  puts \"\"\n  puts \"-------------------------------------------------\"\n  puts \"Call 'init_clocks' to enable all clocks\"\n  puts \"Call 'init_sdrambus' to enable external SDRAM bus\"\n  puts \"-------------------------------------------------\"\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\n#flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxhx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx50.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x1C000140 0\n  mww 0x1C000144 0x00A12151\n  mww 0x1C000140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x1C000100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxhx500.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sleep 100\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x00100100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hilscher_nxsb100.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n}\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hitex_lpc1768stick.cfg",
    "content": "# Hitex LPC1768 Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/hitex_lpc1768stick.cfg]\n\nsource [find target/lpc17xx.cfg]\n\n\n# startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hitex_lpc2929.cfg",
    "content": "# Hitex eval board for LPC2929/LPC2939\n# http://www.hitex.com/\n\n# Delays on reset lines\nadapter srst delay 50\njtag_ntrst_delay 1\n\n# Maximum of 1/8 of clock frequency (XTAL = 16 MHz).\n# Adaptive clocking through RTCK is not supported.\nadapter speed 2000\n\n# Target device: LPC29xx with ETB\n# The following variables are used by the LPC2900 script:\n#   HAS_ETB             Must be set to 1. The CPU on this board has ETB.\n#   FLASH_CLOCK         CPU frequency at the time of flash programming (in kHz)\nset HAS_ETB             1\nset FLASH_CLOCK         112000\nsource [find target/lpc2900.cfg]\n\n# A working area will help speeding the flash programming\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 -work-area-backup 0\n$_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work-area-backup 0\n\n# Event handlers\n$_TARGETNAME configure -event reset-start {\n  # Back to the slow JTAG clock\n  adapter speed 2000\n}\n\n# External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB)\nset _FLASHNAME $_CHIPNAME.extflash\nflash bank $_FLASHNAME cfi 0x5C000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n\n$_TARGETNAME configure -event reset-init {\n  # Flash\n  mww 0x20200010 0x00000007     ;# FBWST: 7 wait states, not cached\n\n  # Use PLL\n  mww 0xFFFF8020 0x00000001     ;# XTAL_OSC_CONTROL: enable, 1-20 MHz\n  mww 0xFFFF8070 0x01000000     ;# SYS_CLK_CONF: Crystal\n  mww 0xFFFF8028 0x00000005     ;# PLL: (power down)\n  mww 0xFFFF8028 0x01060004     ;# PLL: M=7, 2P=2 (power up)\n                                 # --> f=112 MHz, fcco=224 MHz\n  sleep 100\n  mww 0xFFFF8070 0x02000000     ;# SYS_CLK_CONF: PLL\n\n  # Increase JTAG speed\n  adapter speed 6000\n\n  # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7)\n  mww 0xE0001138 0x0000001F     ;# P1.14 = D0\n  mww 0xE000113C 0x0000001F     ;# P1.15 = D1\n  mww 0xE0001140 0x0000001F     ;# P1.16 = D2\n  mww 0xE0001144 0x0000001F     ;# P1.17 = D3\n  mww 0xE0001148 0x0000001F     ;# P1.18 = D4\n  mww 0xE000114C 0x0000001F     ;# P1.19 = D5\n  mww 0xE0001150 0x0000001F     ;# P1.20 = D6\n  mww 0xE0001154 0x0000001F     ;# P1.21 = D7\n  mww 0xE0001200 0x0000001F     ;# P2.0  = D8\n  mww 0xE0001204 0x0000001F     ;# P2.1  = D9\n  mww 0xE0001208 0x0000001F     ;# P2.2  = D10\n  mww 0xE000120C 0x0000001F     ;# P2.3  = D11\n  mww 0xE0001210 0x0000001F     ;# P2.4  = D12\n  mww 0xE0001214 0x0000001F     ;# P2.5  = D13\n  mww 0xE0001218 0x0000001F     ;# P2.6  = D14\n  mww 0xE000121C 0x0000001F     ;# P2.7  = D15\n  mww 0xE0001104 0x00000007     ;# P1.1  = A1\n  mww 0xE0001108 0x00000007     ;# P1.2  = A2\n  mww 0xE000110C 0x00000007     ;# P1.3  = A3\n  mww 0xE0001110 0x00000007     ;# P1.4  = A4\n  mww 0xE0001114 0x00000007     ;# P1.5  = A5\n  mww 0xE0001118 0x00000007     ;# P1.6  = A6\n  mww 0xE000111C 0x00000007     ;# P1.7  = A7\n  mww 0xE0001028 0x00000007     ;# P0.10 = A8\n  mww 0xE000102C 0x00000007     ;# P0.11 = A9\n  mww 0xE0001030 0x00000007     ;# P0.12 = A10\n  mww 0xE0001034 0x00000007     ;# P0.13 = A11\n  mww 0xE0001038 0x00000007     ;# P0.14 = A12\n  mww 0xE000103C 0x00000007     ;# P0.15 = A13\n  mww 0xE0001048 0x00000007     ;# P0.18 = A14\n  mww 0xE000104C 0x00000007     ;# P0.19 = A15\n  mww 0xE0001050 0x00000007     ;# P0.20 = A16\n  mww 0xE0001054 0x00000007     ;# P0.21 = A17\n  mww 0xE0001058 0x00000007     ;# P0.22 = A18\n  mww 0xE000105C 0x00000007     ;# P0.23 = A19\n  mww 0xE0001238 0x00000007     ;# P2.14 = BLS0\n  mww 0xE000123C 0x00000007     ;# P2.15 = BLS1\n  mww 0xE0001300 0x00000007     ;# P3.0  = CS6\n  mww 0xE0001304 0x00000007     ;# P3.1  = CS7\n  mww 0xE0001130 0x00000007     ;# P1.12 = OE_N\n  mww 0xE0001134 0x00000007     ;# P1.13 = WE_N\n  mww 0x600000BC 0x00000041     ;# Bank6 16-bit mode, RBLE=1\n  mww 0x600000B4 0x00000000     ;# Bank6 WSTOEN=0\n  mww 0x600000AC 0x00000005     ;# Bank6 WST1=5\n  mww 0x600000B8 0x00000001     ;# Bank6 WSTWEN=1\n  mww 0x600000B0 0x00000006     ;# Bank6 WST2=6\n  mww 0x600000A8 0x00000002     ;# Bank6 IDCY=2\n  mww 0x600000D8 0x00000041     ;# Bank7 16-bit mode, RBLE=1\n  mww 0x600000D0 0x00000000     ;# Bank7 WSTOEN=0\n  mww 0x600000C8 0x0000000A     ;# Bank7 WST1=10\n  mww 0x600000D4 0x00000001     ;# Bank7 WSTWEN=1\n  mww 0x600000CC 0x0000000C     ;# Bank7 WST2=8\n  mww 0x600000C4 0x00000002     ;# Bank7 IDCY=2\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hitex_stm32-performancestick.cfg",
    "content": "# Hitex stm32 performance stick\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/stm32-stick.cfg]\n\nset  CHIPNAME stm32_hitex\nsource [find target/stm32f1x.cfg]\n\n# configure str750 connected to jtag chain\n# FIXME -- source [find target/str750.cfg] after cleaning that up\njtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041\n\n# for some reason this board like to startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/hitex_str9-comstick.cfg",
    "content": "# Hitex STR9-comStick\n# http://www.hitex.com/index.php?id=383\n# This works for the STR9-comStick revisions STR912CS-A1 and STR912CS-A2.\n\nsource [find interface/ftdi/hitex_str9-comstick.cfg]\n\n# set jtag speed\nadapter speed 3000\n\nadapter srst delay 100\njtag_ntrst_delay 100\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\n#\n# FIXME use the standard str912 target config; that script might need\n# updating to \"-ignore-version\" for the boundary scan TAP\n#\n#\tsource [find target/str912.cfg]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # Found on STR9-comStick, revision STR912CS-A1\n   set _BSTAPID1 0x1457f041\n   # Found on STR9-comStick, revision STR912CS-A2\n   set _BSTAPID2 0x2457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID1 -expected-id $_BSTAPID2\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/iar_lpc1768.cfg",
    "content": "# Board from IAR KickStart Kit for LPC1768\n# See www.iar.com and also\n# http://www.olimex.com/dev/lpc-1766stk.html\n#\n\nsource [find target/lpc17xx.cfg]\n\n# The chip has just been reset.\n#\n$_TARGETNAME configure -event reset-init {\n\t# FIXME update the core clock to run at 100 MHz;\n\t# and update JTAG clocking similarly; then\n\t# make CCLK match,\n\n\tflash probe 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/iar_str912_sk.cfg",
    "content": "# The IAR str912-sk evaluation kick start board has an str912\n\nsource [find target/str912.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/icnova_imx53_sodimm.cfg",
    "content": "#################################################################################################\n# Author: Benjamin Tietz <benjamin.tietz@in-circuit.de>                                        ;#\n# based on work from: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com>   ;#\n# Kiwigrid GmbH                                                                                ;#\n# Generated for In-Circuit i.MX53 SO-Dimm                                                      ;#\n#################################################################################################\n\n# The In-Circuit ICnova IMX53SODIMM board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"i.MX53 SO-Dimm board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { sodimm_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc sodimm_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n#*========================================================================================== ======\n# Initialization script for 32 bit DDR3 (CS0+CS1)\n#*========================================================================================== ======\n# Remux D24/D25 to perform Flash-access\n\tmww 0x53fa818C 0x00000000 ; #EIM_RW\n\tmww 0x53fa8180 0x00000000 ; #EIM_CS0\n\tmww 0x53fa8188 0x00000000 ; #EIM_OE\n\tmww 0x53fa817C 0x00000000 ; #A16\n\tmww 0x53fa8178 0x00000000 ; #A17\n\tmww 0x53fa8174 0x00000000 ; #A18\n\tmww 0x53fa8170 0x00000000 ; #A19\n\tmww 0x53fa816C 0x00000000 ; #A20\n\tmww 0x53fa8168 0x00000000 ; #A21\n\tmww 0x53fa819C 0x00000000 ; #DA0\n\tmww 0x53fa81A0 0x00000000 ; #DA1\n\tmww 0x53fa81A4 0x00000000 ; #DA2\n\tmww 0x53fa81A8 0x00000000 ; #DA3\n\tmww 0x53fa81AC 0x00000000 ; #DA4\n\tmww 0x53fa81B0 0x00000000 ; #DA5\n\tmww 0x53fa81B4 0x00000000 ; #DA6\n\tmww 0x53fa81B8 0x00000000 ; #DA7\n\tmww 0x53fa81BC 0x00000000 ; #DA8\n\tmww 0x53fa81C0 0x00000000 ; #DA9\n\tmww 0x53fa81C4 0x00000000 ; #DA10\n\tmww 0x53fa81C8 0x00000000 ; #DA11\n\tmww 0x53fa81CC 0x00000000 ; #DA12\n\tmww 0x53fa81D0 0x00000000 ; #DA13\n\tmww 0x53fa81D4 0x00000000 ; #DA14\n\tmww 0x53fa81D8 0x00000000 ; #DA15\n\tmww 0x53fa8118 0x00000000 ; #D16\n\tmww 0x53fa811C 0x00000000 ; #D17\n\tmww 0x53fa8120 0x00000000 ; #D18\n\tmww 0x53fa8124 0x00000000 ; #D19\n\tmww 0x53fa8128 0x00000000 ; #D20\n\tmww 0x53fa812C 0x00000000 ; #D21\n\tmww 0x53fa8130 0x00000000 ; #D22\n\tmww 0x53fa8134 0x00000000 ; #D23\n\tmww 0x53fa813c 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D24\n\tmww 0x53fa8140 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D25\n\tmww 0x53fa8144 0x00000000 ; #D26\n\tmww 0x53fa8148 0x00000000 ; #D27\n\tmww 0x53fa814C 0x00000000 ; #D28\n\tmww 0x53fa8150 0x00000000 ; #D29\n\tmww 0x53fa8154 0x00000000 ; #D30\n\tmww 0x53fa8158 0x00000000 ; #D31\n\n# DDR3 IOMUX configuration\n#* Global pad control options */\n\tmww 0x53fa8554 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53fa8558 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53fa8560 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53fa8564 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n\tmww 0x53fa8568 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53fa8570 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa8574 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53fa8578 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa857c 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53fa8580 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53fa8584 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53fa8588 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53fa8590 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53fa8594 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53fa86f0 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53fa86f4 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53fa86fc 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8714 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8714 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8718 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53fa871c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53fa8720 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53fa8724 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=0 XXX\n\tmww 0x53fa8728 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53fa872c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa86f4 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL for sDQS[3:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa8714 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE for D[31:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa86fc 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8724 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=00\n\n#* Data bus byte lane pad drive strength control options */\n#\tmww 0x53fa872c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa8554 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n#\tmww 0x53fa8558 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n#\tmww 0x53fa8728 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B2DS\n#\tmww 0x53fa8560 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n#\tmww 0x53fa8568 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n#\tmww 0x53fa871c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B1DS\n#\tmww 0x53fa8594 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n#\tmww 0x53fa8590 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n#\tmww 0x53fa8718 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B0DS\n#\tmww 0x53fa8584 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n#\tmww 0x53fa857c 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\n#* SDCLK pad drive strength control options */\n#\tmww 0x53fa8578 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n#\tmww 0x53fa8570 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\n#* Control and addr bus pad drive strength control options */\n#\tmww 0x53fa8574 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n#\tmww 0x53fa8588 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n#\tmww 0x53fa86f0 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_ADDDS for DDR addr bus\n#\tmww 0x53fa8720 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_CTLDS for CSD0, CSD1, SDCKE0, SDCKE1, SDWE\n\n#\tmww 0x53fa8564 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n#\tmww 0x53fa8580 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\n# Initialize DDR3 memory - Micron MT41J128M16-187Er\n#** Keep for now, same setting as CPU3 board **#\n\tmww 0x63fd901c 0x00008000\n#\tmww 0x63fd904c 0x01680172 ; #write leveling reg 0\n#\tmww 0x63fd9050 0x0021017f ; #write leveling reg 1\n\tmww 0x63fd9088 0x32383535 ; #read delay lines\n\tmww 0x63fd9090 0x40383538 ; #write delay lines\n#\tmww 0x63fd90F8 0x00000800 ; #Measure unit\n\tmww 0x63fd907c 0x0136014d ; #DQS gating 0\n\tmww 0x63fd9080 0x01510141 ; #DQS gating 1\n#* CPU3 Board settingr\n# Enable bank interleaving, Address mirror on, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n#\tmww 0x63fd9018 0x00091740 ; #Misc register:\n#* Quick Silver board setting\n# Enable bank interleaving, Address mirror off, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n\tmww 0x63fd9018 0x00011740 ; #Misc register\n\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n#\tmww 0x63fd9000 0xc3190000 ; #Main control register\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n\tmww 0x63fd9000 0x83190000 ; #Main control register\n# tRFC=64ck;tXS=68;tXP=3;tXPDLL=10;tFAW=15;CAS=6ck\n\tmww 0x63fd900C 0x555952E3 ; #timing configuration Reg 0\n# tRCD=6;tRP=6;tRC=21;tRAS=15;tRPA=1;tWR=6;tMRD=4;tCWL=5ck\n\tmww 0x63fd9010 0xb68e8b63 ; #timing configuration Reg 1\n# tDLLK(tXSRD)=512 cycles; tRTP=4;tWTR=4;tRRD=4\n\tmww 0x63fd9014 0x01ff00db ; #timing configuration Reg 2\n\tmww 0x63fd902c 0x000026d2 ; #command delay (default)\n\tmww 0x63fd9030 0x009f0e21 ; #out of reset delays\n# Keep tAOFPD, tAONPD, tANPD, and tAXPD as default since they are bigger than calc values\n\tmww 0x63fd9008 0x12273030 ; #ODT timings\n# tCKE=3; tCKSRX=5; tCKSRE=5\n\tmww 0x63fd9004 0x0002002d\n#Power down control\n#**********************************\n#DDR device configuration:\n#**********************************\n#**********************************\n# CS0:\n#**********************************\n\tmww 0x63fd901c 0x00008032 ; #write mode reg MR2 with cs0 (see below for settings)\n# Full array self refresh\n# Rtt_WR disabled (no ODT at IO CMOS operation)\n# Manual self refresh\n# CWS=5\n\tmww 0x63fd901c 0x00008033 ; #write mode reg MR3 with cs0.\n\tmww 0x63fd901c 0x00028031 ; #write mode reg MR1 with cs0. ODS=01: out buff= RZQ/7 (see below for settings)\n# out impedance = RZQ/7\n# Rtt_nom disabled (no ODT at IO CMOS operation)\n# Aditive latency off\n# write leveling disabled\n# tdqs (differential?) disabled\n\n\tmww 0x63fd901c 0x09208030 ; #write mode reg MR0 with cs0 , with dll_rst0\n\tmww 0x63fd901c 0x04008040 ; #ZQ calibration with cs0 (A10 high indicates ZQ cal long ZQCL)\n#**********************************\n# CS1:\n#**********************************\n#\tmww 0x63fd901c 0x0000803a ; #write mode reg MR2 with cs1.\n#\tmww 0x63fd901c 0x0000803b ; #write mode reg MR3 with cs1.\n#\tmww 0x63fd901c 0x00028039 ; #write mode reg MR1 with cs1. ODS=01: out buff= RZQ/7\n#\tmww 0x63fd901c 0x09208138 ; #write mode reg MR0 with cs1.\n#\tmww 0x63fd901c 0x04008048 ; #ZQ calibration with cs1(A10 high indicates ZQ cal long ZQCL)\n#**********************************\n\n\n\tmww 0x63fd9020 0x00001800 ; # Refresh control register\n\tmww 0x63fd9040 0x04b80003 ; # ZQ HW control\n\tmww 0x63fd9058 0x00022227 ; # ODT control register\n\n\tmww 0x63fd901c 0x00000000\n\n# CLKO muxing (comment out for now till needed to avoid conflicts with intended usage of signals)\n#\tmww 0x53FA8314 = 0\n#\tmww 0x53FA8320 0x4\n#\tmww 0x53FD4060 0x01e900f0\n\n#\tdap apsel 0\n}\n\n# IRAM\n$_TARGETNAME configure -work-area-phys 0xF8000000 -work-area-size 0x20000 -work-area-backup 1\n\nflash bank mx535_nor cfi 0xf0000000 0x800000 2 2 $_TARGETNAME\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/icnova_sam9g45_sodimm.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t                                                #\n# Author: Lars Poeschel (larsi@wh2.tu-dresden.de)\t\t\t\t\t\t\t\t\t\t\t\t#\n# Generated for In-Circuit ICnova SAM9G45 SODIMM\t\t\t\t\t\t\t\t\t\t\t\t#\n# http://www.ic-board.de/product_info.php?info=p214_ICnova-SAM9G45-SODIMM.html|ICnova\t\t\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g45.cfg]\n\n# Set reset type.\n# reset_config trst_and_srst\n\n# adapter srst delay 200\n# jtag_ntrst_delay 200\n\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g45_init}\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n$_TARGETNAME configure -event reset-start {at91sam9g45_start}\n\n\n# NandFlash configuration and definition\n# Future TBD\n# Flash configuration\n# flash bank cfi <base> <size> <chip width> <bus width> <target#>\nset _FLASHNAME $_CHIPNAME.flash\n# set _NANDNAME $_CHIPNAME.nand\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n# nand device $_NANDNAME at91sam9 $_TARGETNAME 0x40000000 0xFFFFE800\n\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g45_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n    # Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\tadapter speed 4\n    # Make sure processor is halted, or error will result in following steps.\n\thalt\n\twait_halt 10000\n    # RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n}\n\n\nproc at91sam9g45_init { } {\n\n\t# At reset AT91SAM9G45 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G45 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\t# Make sure processor is halted, or error will result in following steps.\n\thalt\n\t# RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n\t# WDT_MR : disable watchdog.\n\tmww 0xfffffd44 0x00008000\n\n\t# Enable the main 15.000 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\t#mww 0xfffffc28 0x202a3f01\n\tmww 0xfffffc28 0x20c73f03\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\t#mww 0xfffffc30 0x00000101\n\tmww 0xfffffc30 0x00001301\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 6000\n\n\t# Enable faster DCC downloads.\n\n\tarm7_9 dcc_downloads enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n#\tmww 0xfffff870 0xffff0000\n#\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\t# mww 0xffffef1c 0x000100a\n\n\t# The ICnova SAM9G45 SODIMM has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# four registers in order:  SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.\n\n\t# mww 0xffffec30 0x00020002\n\t# mww 0xffffec34 0x04040404\n\t# mww 0xffffec38 0x00070007\n\t# mww 0xffffec3c 0x00030003\n\n\t# Identify NandFlash bank 0.  Disabled at the moment because a memory driver is not yet complete.\n\n#\tnand probe 0\n\n    # SMC_SETUP0 : Setup SMC for NOR Flash\n\tmww 0xffffe800 0x0012000a\n    # SMC_PULSE0\n\tmww 0xffffe804 0x3b38343b\n    # SMC_CYCLE0\n\tmww 0xffffe808 0x003f003f\n    # SMC_MODE0\n\tmww 0xffffe80c 0x00001000\n    # Identify flash bank 0\n\tflash probe 0\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Samsung K4T51083QG memory.\n\n\t# 0. Enable DDR2 Clock\n\tmww 0xfffffc00 0x4\n\t# 1. Program memory device type\n\t# 1.1 configure the DDR controller\n\tmww 0xffffe620 0x16\n\t# 1.2 program the DDR controller\n\tmww 0xffffe608 0x3d\n\n\t# 2. program memory device features\n\t# 2.1 assume timings for 7.5ns min clock period\n\tmww 0xffffe60c 0x21128226\n\t# 2.2 pSDDRC->HDDRSDRC2_T1PR\n\tmww 0xffffe610 0x02c8100e\n\t# 2.3 pSDDRC->HDDRSDRC2_T2PR\n\tmww 0xffffe614 0x01000702\n\t# 3. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 3.1 delay 200us\n\tsleep 1\n\t# jim tcl alternative: after ms\n\t# after 0.2\n\n\t# 4. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 4.1 delay 400ns\n\n\t# 5. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 5.1 delay 400ns\n\n\t# 6. set EMR operation (EMRS2)\n\tmww 0xffffe600 0x5\n\tmww 0x74000000 0x1\n\t# 6.1 delay 2 cycles\n\n\t# 7. set EMR operation (EMRS3)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 7.1 delay 2 cycles\n\n\t# 8. set EMR operation (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 8.1 delay 200 cycles (400Mhz -> 5 * 10^-7s)\n\tsleep 1\n\n\t# 9. Enable DLL Reset (set DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] | 0x80}]\n\tmww 0xffffe608 $CR\n\n\t# 10. mode register cycle to reset the DLL\n\tmww 0xffffe600 0x5\n\tmww 0x70000000 0x1\n\t# 10.1 delay 2 cycles\n\n\t# 11. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 11.1 delay 400 ns\n\n\t# 12. two auto-refresh (CBR) cycles are provided.\n\tmww 0xffffe600 0x4\n\tmww 0x70000000 0x1\n\t# 12.1 delay 10 cycles\n\t# 12.2 2nd cycle (schreiben des Mode Register sparen wir uns)\n\tmww 0x70000000 0x1\n\t# 12.3 delay 10 cycles\n\n\t# 13. disable DLL reset (clear DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffffff7f}]\n\tmww 0xffffe608 $CR\n\n\t# 14. mode register set cycle\n\tmww 0xffffe600 0x3\n\tmww 0x70000000 0x1\n\n\t# 15. program OCD field (set OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] | 0x7000}]\n\tmww 0xffffe608 $CR\n\n\t# 16. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 16.1 delay 2 cycles\n\n\t# 17. disable OCD field (clear OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffff8fff}]\n\tmww 0xffffe608 $CR\n\n\t# 18. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 18.1 delay 2 cycles\n\n\t# 19. normal mode command\n\tmww 0xffffe600 0x0\n\tmww 0x70000000 0x1\n\n\t# 20. perform write to any address\n\t#mww 0x70000000 0x1\n\n\t# 21. write refresh rate into the count field of the refresh rate register\n\tmww 0xffffe604 0x24b\n\t# 21.1 delay (500 * 6 cycles)\n\n\tarm7_9 fast_memory_access enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx27ads.cfg",
    "content": "# The IMX27 ADS eval board has a single IMX27 chip\n# Note: tested on IMX27ADS Board REV-2.6 and REV-2.8\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27ads_init }\n\n# The IMX27 ADS board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\nproc imx27ads_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\t# ========================================\n\t#  Configure PSRAM on CS5\n\t# ========================================\n\tmww 0xd8002050 0x0000dcf6\n\tmww 0xd8002054 0x444a4541\n\tmww 0xd8002058 0x44443302\n\n\t#  ========================================\n\t#         Configure16 bit NorFlash on CS0\n\t#  ========================================\n\tmww 0xd8002000 0x0000CC03\n\tmww 0xd8002004 0xa0330D01\n\tmww 0xd8002008 0x00220800\n\n\t# ========================================\n\t#  Configure CPLD on CS4\n\t# ========================================\n\tmww 0xd8002040 0x0000DCF6\n\tmww 0xd8002044 0x444A4541\n\tmww 0xd8002048 0x44443302\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\tmww 0xD8001000 0x92200000\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xA2200000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xB2200000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\tmww 0xD8001000 0x82228085\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx27lnst.cfg",
    "content": "# The Linuxstamp-mx27 is board has a single IMX27 chip\n# For further info see http://opencircuits.com/Linuxstamp_mx27#OpenOCD\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27lnst_init }\n\nproc imx27lnst_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\tadapter speed 500\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\t#mww 0xD8001000 0x92200000\n\tmww 0xD8001000 0x91120000\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xA2200000\n\tmww 0xD8001000 0xA1120000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xB2200000\n\tmww 0xD8001000 0xB1120000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\t#mww 0xD8001000 0x82228085\n\tmww 0xD8001000 0x81128080\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx28evk.cfg",
    "content": "# The IMX28EVK eval board has a IMX28 chip\n# Tested on SCH-26241 Rev D board with Olimex ARM-USB-OCD\n# Date:\t201-02-01\n# Authors: James Robinson & Fabio Estevam\n\nsource [find target/imx28.cfg]\n$_TARGETNAME configure -event gdb-attach { imx28evk_init }\n$_TARGETNAME configure -event reset-init { imx28evk_init }\n\nproc imx28evk_init { } {\n\n\thalt\n\n\t#****************************\n\t# VDDD setting\n\t#****************************\n\t# set VDDD =1.55V =(0.8v + TRIG x 0.025v), TRIG=0x1e\n\tmww 0x80044010 0x0003F503\n\tmww 0x80044040 0x0002041E\n\n\t#****************************\n\t# CLOCK set up\n\t#****************************\n\t# Power up PLL0 HW_CLKCTRL_PLL0CTRL0\n\tmww 0x80040000 0x00020000\n\t# Set up fractional dividers for CPU and EMI - HW_CLKCTRL_FRAC0\n\t# EMI - first set DIV_EMI to div-by-2 before programming frac divider\n\tmww 0x800400F0 0x80000002\n\n\n\t# CPU: CPUFRAC=19 480*18/29=454.7MHz, EMI: EMIFRAC=22, (480/2)*18/22=196.4MHz\n\tmww 0x800401B0 0x92921613\n\t# Clear the bypass bits for CPU and EMI clocks in HW_CLKCTRL_CLKSEQ_CLR\n\tmww 0x800401D8 0x00040080\n\t# HCLK = 227MHz,HW_CLKCTRL_HBUS DIV =0x2\n\tmww 0x80040060 0x00000002\n\n\t#****************************\n\t# POWER up DCDD_VDDA (DDR2)\n\t#****************************\n\t# Now set the voltage level to 1.8V HW_POWER_VDDACTRL bits TRC=0xC\n\tmww 0x80044050 0x0000270C\n\n\t#****************************\n\t# DDR2 DCDD_VDDA\n\t#****************************\n\t# First set up pin muxing and drive strength\n\t# Ungate module clock and bring out of reset HW_PINCTRL_CTRL_CLR\n\tmww 0x80018008 0xC0000000\n\n\t#****************************\n\t# EMI PAD setting\n\t#****************************\n\t# Set up drive strength for EMI pins\n\tmww 0x80019B80 0x00030000\n\t#IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\n\t# Set up pin muxing for EMI, HW_PINCTRL_MUXSEL10, 11, 12, 13\n\tmww 0x800181A8 0xFFFFFFFF\n\tmww 0x800181B8 0xFFFFFFFF\n\tmww 0x800181C8 0xFFFFFFFF\n\tmww 0x800181D8 0xFFFFFFFF\n\n\t#** Ungate EMI clock in CCM\n\tmww 0x800400F0 0x00000002\n\n\t#============================================================================\n\t# DDR Controller Registers\n\t#============================================================================\n\t# Manufacturer:    Elpida\n\t# Device Part Number:    EDE1116AEBG\n\t# Clock Freq.:     200MHz\n\t# Density:         1Gb\n\t# Chip Selects:    1\n\t# Number of Banks: 8\n\t# Row address:     13\n\t# Column address:  10\n\t#============================================================================\n\tmww 0x800E0000 0x00000000\n\tmww 0x800E0040 0x00000000\n\tmww 0x800E0054 0x00000000\n\tmww 0x800E0058 0x00000000\n\tmww 0x800E005C 0x00000000\n\tmww 0x800E0060 0x00000000\n\tmww 0x800E0064 0x00000000\n\tmww 0x800E0068 0x00010101\n\tmww 0x800E006C 0x01010101\n\tmww 0x800E0070 0x000f0f01\n\tmww 0x800E0074 0x0102020A\n\tmww 0x800E007C 0x00010101\n\tmww 0x800E0080 0x00000100\n\tmww 0x800E0084 0x00000100\n\tmww 0x800E0088 0x00000000\n\tmww 0x800E008C 0x00000002\n\tmww 0x800E0090 0x01010000\n\tmww 0x800E0094 0x07080403\n\tmww 0x800E0098 0x06005003\n\tmww 0x800E009C 0x0A0000C8\n\tmww 0x800E00A0 0x02009C40\n\tmww 0x800E00A4 0x0002030C\n\tmww 0x800E00A8 0x0036B009\n\tmww 0x800E00AC 0x031A0612\n\tmww 0x800E00B0 0x02030202\n\tmww 0x800E00B4 0x00C8001C\n\tmww 0x800E00C0 0x00011900\n\tmww 0x800E00C4 0xffff0303\n\tmww 0x800E00C8 0x00012100\n\tmww 0x800E00CC 0xffff0303\n\tmww 0x800E00D0 0x00012100\n\tmww 0x800E00D4 0xffff0303\n\tmww 0x800E00D8 0x00012100\n\tmww 0x800E00DC 0xffff0303\n\tmww 0x800E00E0 0x00000003\n\tmww 0x800E00E8 0x00000000\n\tmww 0x800E0108 0x00000612\n\tmww 0x800E010C 0x01000f02\n\tmww 0x800E0114 0x00000200\n\tmww 0x800E0118 0x00020007\n\tmww 0x800E011C 0xf4004a27\n\tmww 0x800E0120 0xf4004a27\n\tmww 0x800E012C 0x07400300\n\tmww 0x800E0130 0x07400300\n\tmww 0x800E013C 0x00000005\n\tmww 0x800E0140 0x00000000\n\tmww 0x800E0144 0x00000000\n\tmww 0x800E0148 0x01000000\n\tmww 0x800E014C 0x01020408\n\tmww 0x800E0150 0x08040201\n\tmww 0x800E0154 0x000f1133\n\tmww 0x800E015C 0x00001f04\n\tmww 0x800E0160 0x00001f04\n\tmww 0x800E016C 0x00001f04\n\tmww 0x800E0170 0x00001f04\n\tmww 0x800E0288 0x00010000\n\tmww 0x800E028C 0x00030404\n\tmww 0x800E0290 0x00000003\n\tmww 0x800E02AC 0x01010000\n\tmww 0x800E02B0 0x01000000\n\tmww 0x800E02B4 0x03030000\n\tmww 0x800E02B8 0x00010303\n\tmww 0x800E02BC 0x01020202\n\tmww 0x800E02C0 0x00000000\n\tmww 0x800E02C4 0x02030303\n\tmww 0x800E02C8 0x21002103\n\tmww 0x800E02CC 0x00061200\n\tmww 0x800E02D0 0x06120612\n\tmww 0x800E02D4 0x04420442\n\t# Mode register 0 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02D8 0x00000000\n\t# Mode register 0 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02DC 0x00040004\n\t# Mode register 1 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E0 0x00000000\n\t# Mode register 1 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02E4 0x00000000\n\t# Mode register 2 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E8 0x00000000\n\t# Mode register 2 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02EC 0x00000000\n\t# Mode register 3 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02F0 0x00000000\n\t# Mode register 3 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02F4 0xffffffff\n\n\t#**  start controller **#\n\tmww 0x800E0040 0x00000001\n\t# bit[0]: start\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx31pdk.cfg",
    "content": "# The IMX31PDK eval board has a single IMX31 chip\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx31pdk_init }\n\nproc self_test {} {\n\techo \"Running 100 iterations of test.\"\n\tdump_image /ram/test 0x80000000 0x40000\n\tfor {set i 0} {$i < 100} {set i [expr {$i+1}]} {\n\t\techo \"Iteration $i\"\n\t\treset init\n\t\tmww 0x80000000 0x12345678 0x10000\n\t\tload_image /ram/test 0x80000000 bin\n\t\tverify_image /ram/test 0x80000000 bin\n\t}\n}\n\n\n# Slow fallback frequency\n# measure_clk indicates ca. 3-4MHz.\njtag_rclk 1000\n\nproc imx31pdk_init { } {\n\n\timx3x_reset\n\n\t# This setup puts RAM at 0x80000000\n\n\tmww 0x53FC0000 0x040\n\tmww 0x53F80000 0x074B0B7D\n\n\t# 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40\n\t#mww 0x53F80004 0xFF871D50\n\t#mww 0x53F80010 0x00271C1B\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000CC03\n\tmww 0xb8002004 0xa0330D01\n\tmww 0xb8002008 0x00220800\n\n\t# Configure CPLD on CS4\n\tmww 0xb8002040 0x0000DCF6\n\tmww 0xb8002044 0x444A4541\n\tmww 0xb8002048 0x44443302\n\n\t# SDCLK\n\tmww 0x43FAC26C 0\n\n\t# CAS\n\tmww 0x43FAC270 0\n\n\t# RAS\n\tmww 0x43FAC274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43FAC27C 0x1000\n\n\t# DQM3\n\tmww 0x43FAC284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC)\n\tmww 0x43FAC288 0\n\tmww 0x43FAC28C 0\n\tmww 0x43FAC290 0\n\tmww 0x43FAC294 0\n\tmww 0x43FAC298 0\n\tmww 0x43FAC29C 0\n\tmww 0x43FAC2A0 0\n\tmww 0x43FAC2A4 0\n\tmww 0x43FAC2A8 0\n\tmww 0x43FAC2AC 0\n\tmww 0x43FAC2B0 0\n\tmww 0x43FAC2B4 0\n\tmww 0x43FAC2B8 0\n\tmww 0x43FAC2BC 0\n\tmww 0x43FAC2C0 0\n\tmww 0x43FAC2C4 0\n\tmww 0x43FAC2C8 0\n\tmww 0x43FAC2CC 0\n\tmww 0x43FAC2D0 0\n\tmww 0x43FAC2D4 0\n\tmww 0x43FAC2D8 0\n\tmww 0x43FAC2DC 0\n\n\t# Initialization script for 32 bit DDR on MX31 ADS\n\tmww 0xB8001010 0x00000004\n\tmww 0xB8001004 0x006ac73a\n\tmww 0xB8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\tmww 0xB8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\tmww 0xB8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\tmww 0xB8001000 0x82226080\n\tmww 0x80000000 0xDEADBEEF\n\tmww 0xB8001010 0x0000000c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx35pdk.cfg",
    "content": "# The IMX35PDK eval board has a single IMX35 chip\nsource [find target/imx35.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx35pdk_init }\n\n# Stick to *really* low clock rate or reset will fail\n# without RTCK / RCLK\njtag_rclk 10\n\nproc imx35pdk_init { } {\n\n\timx3x_reset\n\n\tmww 0x43f00040 0x00000000\n\tmww 0x43f00044 0x00000000\n\tmww 0x43f00048 0x00000000\n\tmww 0x43f0004C 0x00000000\n\tmww 0x43f00050 0x00000000\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00040 0x00000000\n\tmww 0x53f00044 0x00000000\n\tmww 0x53f00048 0x00000000\n\tmww 0x53f0004C 0x00000000\n\tmww 0x53f00050 0x00000000\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# clock setup\n\tmww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP\n\tmww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz.\n\n\t#=================================================\n\t# WEIM config\n\t#=================================================\n\t# CS0U\n\tmww 0xB8002000 0x0000CC03\n\t# CS0L\n\tmww 0xB8002004 0xA0330D01\n\t# CS0A\n\tmww 0xB8002008 0x00220800\n\t# CS5U\n\tmww 0xB8002050 0x0000dcf6\n\t# CS5L\n\tmww 0xB8002054 0x444a4541\n\t# CS5A\n\tmww 0xB8002058 0x44443302\n\n\t# IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR\n\tmww 0x43FAC368 0x00000006\n\tmww 0x43FAC36C 0x00000006\n\tmww 0x43FAC370 0x00000006\n\tmww 0x43FAC374 0x00000006\n\tmww 0x43FAC378 0x00000006\n\tmww 0x43FAC37C 0x00000006\n\tmww 0x43FAC380 0x00000006\n\tmww 0x43FAC384 0x00000006\n\tmww 0x43FAC388 0x00000006\n\tmww 0x43FAC38C 0x00000006\n\tmww 0x43FAC390 0x00000006\n\tmww 0x43FAC394 0x00000006\n\tmww 0x43FAC398 0x00000006\n\tmww 0x43FAC39C 0x00000006\n\tmww 0x43FAC3A0 0x00000006\n\tmww 0x43FAC3A4 0x00000006\n\tmww 0x43FAC3A8 0x00000006\n\tmww 0x43FAC3AC 0x00000006\n\tmww 0x43FAC3B0 0x00000006\n\tmww 0x43FAC3B4 0x00000006\n\tmww 0x43FAC3B8 0x00000006\n\tmww 0x43FAC3BC 0x00000006\n\tmww 0x43FAC3C0 0x00000006\n\tmww 0x43FAC3C4 0x00000006\n\tmww 0x43FAC3C8 0x00000006\n\tmww 0x43FAC3CC 0x00000006\n\tmww 0x43FAC3D0 0x00000006\n\tmww 0x43FAC3D4 0x00000006\n\tmww 0x43FAC3D8 0x00000006\n\n\t# DDR data bus SD 0 through 31\n\tmww 0x43FAC3DC 0x00000082\n\tmww 0x43FAC3E0 0x00000082\n\tmww 0x43FAC3E4 0x00000082\n\tmww 0x43FAC3E8 0x00000082\n\tmww 0x43FAC3EC 0x00000082\n\tmww 0x43FAC3F0 0x00000082\n\tmww 0x43FAC3F4 0x00000082\n\tmww 0x43FAC3F8 0x00000082\n\tmww 0x43FAC3FC 0x00000082\n\tmww 0x43FAC400 0x00000082\n\tmww 0x43FAC404 0x00000082\n\tmww 0x43FAC408 0x00000082\n\tmww 0x43FAC40C 0x00000082\n\tmww 0x43FAC410 0x00000082\n\tmww 0x43FAC414 0x00000082\n\tmww 0x43FAC418 0x00000082\n\tmww 0x43FAC41c 0x00000082\n\tmww 0x43FAC420 0x00000082\n\tmww 0x43FAC424 0x00000082\n\tmww 0x43FAC428 0x00000082\n\tmww 0x43FAC42c 0x00000082\n\tmww 0x43FAC430 0x00000082\n\tmww 0x43FAC434 0x00000082\n\tmww 0x43FAC438 0x00000082\n\tmww 0x43FAC43c 0x00000082\n\tmww 0x43FAC440 0x00000082\n\tmww 0x43FAC444 0x00000082\n\tmww 0x43FAC448 0x00000082\n\tmww 0x43FAC44c 0x00000082\n\tmww 0x43FAC450 0x00000082\n\tmww 0x43FAC454 0x00000082\n\tmww 0x43FAC458 0x00000082\n\n\t# DQM setup\n\tmww 0x43FAC45c 0x00000082\n\tmww 0x43FAC460 0x00000082\n\tmww 0x43FAC464 0x00000082\n\tmww 0x43FAC468 0x00000082\n\n\tmww 0x43FAC46c 0x00000006\n\tmww 0x43FAC470 0x00000006\n\tmww 0x43FAC474 0x00000006\n\tmww 0x43FAC478 0x00000006\n\tmww 0x43FAC47c 0x00000006\n\tmww 0x43FAC480 0x00000006\t;# CSD0\n\tmww 0x43FAC484 0x00000006\t;# CSD1\n\tmww 0x43FAC488 0x00000006\n\tmww 0x43FAC48c 0x00000006\n\tmww 0x43FAC490 0x00000006\n\tmww 0x43FAC494 0x00000006\n\tmww 0x43FAC498 0x00000006\n\tmww 0x43FAC49c 0x00000006\n\tmww 0x43FAC4A0 0x00000006\n\tmww 0x43FAC4A4 0x00000006\t;# RAS\n\tmww 0x43FAC4A8 0x00000006\t;# CAS\n\tmww 0x43FAC4Ac 0x00000006\t;# SDWE\n\tmww 0x43FAC4B0 0x00000006 \t;# SDCKE0\n\tmww 0x43FAC4B4 0x00000006  ;# SDCKE1\n\tmww 0x43FAC4B8 0x00000002  ;# SDCLK\n\n\t# SDQS0 through SDQS3\n\tmww 0x43FAC4Bc 0x00000082\n\tmww 0x43FAC4C0 0x00000082\n\tmww 0x43FAC4C4 0x00000082\n\tmww 0x43FAC4C8 0x00000082\n\n\n\t# *==================================================\n\t#  Initialization script for 32 bit DDR2 on RINGO 3DS\n\t# *==================================================\n\n\t#--------------------------------------------\n\t# Init CCM\n\t#--------------------------------------------\n\tmww 0x53F80028 0x7D000028\n\n\t#--------------------------------------------\n\t# Init IOMUX for JTAG\n\t#--------------------------------------------\n\tmww 0x43FAC5EC 0x000000C3\n\tmww 0x43FAC5F0 0x000000C3\n\tmww 0x43FAC5F4 0x000000F3\n\tmww 0x43FAC5F8 0x000000F3\n\tmww 0x43FAC5FC 0x000000F3\n\tmww 0x43FAC600 0x000000F3\n\tmww 0x43FAC604 0x000000F3\n\n\n\t# ESD_MISC : enable DDR2\n\tmww 0xB8001010 0x00000304\n\n\t#--------------------------------------------\n\t# Init 32-bit DDR2 memory on CSD0\n\t# COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25]\n\t#--------------------------------------------\n\n\t# ESD_ESDCFG0 : set timing parameters\n\tmww 0xB8001004 0x007ffC2f\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmww 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg EMR2\n\tmwb 0x84000000 0xda\n\t# DDR2 : Load reg EMR3\n\tmwb 0x86000000 0xda\n\t# DDR2 : Load reg EMR1 -- enable DLL\n\tmwb 0x82000400 0xda\n\t# DDR2 : Load reg MR -- reset DLL\n\tmwb 0x80000333 0xda\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmwb 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Manual-Refresh mode\n\tmww 0xB8001000 0xA2220000\n\t# DDR2 : Manual-Refresh 2 times\n\tmww 0x80000000 0x87654321\n\tmww 0x80000000 0x87654321\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset\n\tmwb 0x80000233 0xda\n\t# DDR2 : Load reg EMR1 -- OCD default\n\tmwb 0x82000780 0xda\n\t# DDR2 : Load reg EMR1 -- OCD exit\n\tmwb 0x82000400 0xda\t;# ODT disabled\n\n\t# ESD_ESDCTL0 : select normal-operation mode\n\t# DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit\n\t# disable PWT & PRCT\n\t# disable Auto-Refresh\n\tmww 0xB8001000 0x82220080\n\n\t## ESD_ESDCTL0 : enable Auto-Refresh\n\tmww 0xB8001000 0x82228080\n\t## ESD_ESDCTL1 : enable Auto-Refresh\n\tmww 0xB8001008 0x00002000\n\n\n\t#***********************************************\n\t# Adjust the ESDCDLY5 register\n\t#***********************************************\n\t# Vary DQS_ABS_OFFSET5 for writes\n\tmww 0xB8001020 0x00F48000\t;# this is the default value\n\tmww 0xB8001024 0x00F48000\t;# this is the default value\n\tmww 0xB8001028 0x00F48000\t;# this is the default value\n\tmww 0xB800102c 0x00F48000\t;# this is the default value\n\n\n\t#Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC)\n\tmww 0xB8001010 0x00000384\n\t# wait a while\n\tsleep 1000\n\t# now clear the force measurement bit\n\tmww 0xB8001010 0x00000304\n\n\t# dummy write to DDR memory to set DQS low\n\tmww 0x80000000 0x00000000\n\n\tmww 0x30000100 0x0\n\tmww 0x30000104 0x31024\n\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx53-m53evk.cfg",
    "content": "#######################################\n# DENX M53EVK                         #\n# http://www.denx-cs.de/?q=M53EVK     #\n# Author: Marek Vasut <marex@denx.de> #\n# Based on imx53loco.cfg              #\n#######################################\n\n# The DENX M53EVK has on-board JTAG adapter\nsource [find interface/ftdi/m53evk.cfg]\n# The DENX M53EVK board has a single i.MX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 M53EVK board lodaded.\"\n\n# Set reset type\nreset_config trst_and_srst separate trst_open_drain srst_open_drain\n\n# Run at 6 MHz\nadapter speed 6000\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { m53evk_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc m53evk_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53fa86f4 0x00000000\t ;# GRP_DDRMODE_CTL\n\tmww 0x53fa8714 0x00000000\t ;# GRP_DDRMODE\n\tmww 0x53fa86fc 0x00000000\t ;# GRP_DDRPKE\n\tmww 0x53fa8724 0x04000000\t ;# GRP_DDR_TYPE\n\n\tmww 0x53fa872c 0x00300000\t ;# GRP_B3DS\n\tmww 0x53fa8554 0x00300000\t ;# DRAM_DQM3\n\tmww 0x53fa8558 0x00300040\t ;# DRAM_SDQS3\n\n\tmww 0x53fa8728 0x00300000\t ;# GRP_B2DS\n\tmww 0x53fa8560 0x00300000\t ;# DRAM_DQM2\n\tmww 0x53fa8568 0x00300040\t ;# DRAM_SDQS2\n\n\tmww 0x53fa871c 0x00300000\t ;# GRP_B1DS\n\tmww 0x53fa8594 0x00300000\t ;# DRAM_DQM1\n\tmww 0x53fa8590 0x00300040\t ;# DRAM_SDQS1\n\n\tmww 0x53fa8718 0x00300000\t ;# GRP_B0DS\n\tmww 0x53fa8584 0x00300000\t ;# DRAM_DQM0\n\tmww 0x53fa857c 0x00300040\t ;# DRAM_SDQS0\n\n\tmww 0x53fa8578 0x00300000\t ;# DRAM_SDCLK_0\n\tmww 0x53fa8570 0x00300000\t ;# DRAM_SDCLK_1\n\n\tmww 0x53fa8574 0x00300000\t ;# DRAM_CAS\n\tmww 0x53fa8588 0x00300000\t ;# DRAM_RAS\n\tmww 0x53fa86f0 0x00300000\t ;# GRP_ADDDS\n\tmww 0x53fa8720 0x00300000\t ;# GRP_CTLDS\n\n\tmww 0x53fa8564 0x00300040\t ;# DRAM_SDODT1\n\tmww 0x53fa8580 0x00300040\t ;# DRAM_SDODT0\n\n\t# Initialize DDR2 memory\n\tmww 0x63fd9088 0x32383535\n\tmww 0x63fd9090 0x40383538\n\tmww 0x63fd907c 0x0136014d\n\tmww 0x63fd9080 0x01510141\n\n\tmww 0x63fd9018 0x00011740\n\tmww 0x63fd9000 0xc3190000\n\tmww 0x63fd900c 0x555952e3\n\tmww 0x63fd9010 0xb68e8b63\n\tmww 0x63fd9014 0x01ff00db\n\tmww 0x63fd902c 0x000026d2\n\tmww 0x63fd9030 0x009f0e21\n\tmww 0x63fd9008 0x12273030\n\tmww 0x63fd9004 0x0002002d\n\tmww 0x63fd901c 0x00008032\n\tmww 0x63fd901c 0x00008033\n\tmww 0x63fd901c 0x00028031\n\tmww 0x63fd901c 0x092080b0\n\tmww 0x63fd901c 0x04008040\n\tmww 0x63fd901c 0x0000803a\n\tmww 0x63fd901c 0x0000803b\n\tmww 0x63fd901c 0x00028039\n\tmww 0x63fd901c 0x09208138\n\tmww 0x63fd901c 0x04008048\n\tmww 0x63fd9020 0x00001800\n\tmww 0x63fd9040 0x04b80003\n\tmww 0x63fd9058 0x00022227\n\tmww 0x63fd901c 0x00000000\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx53loco.cfg",
    "content": "##################################################################################\n# Author: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com> #\n# Kiwigrid GmbH                                                                  #\n##################################################################################\n\n# The IMX53LOCO (QSB) board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 Loco board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n#adapter srst delay 200\n#jtag_ntrst_delay 200\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { loco_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc loco_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53FA8554 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53FA8558 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53FA8560 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53FA8564 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT\n\tmww 0x53FA8568 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53FA8570 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\tmww 0x53FA8574 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53FA8578 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n\tmww 0x53FA857c 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53FA8580 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53FA8584 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53FA8588 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53FA8590 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53FA8594 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53FA86f0 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53FA86f4 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53FA86fc 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n\tmww 0x53FA8714 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode\n\tmww 0x53FA8718 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53FA871c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53FA8720 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53FA8724 0x04000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL0=\n\tmww 0x53FA8728 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53FA872c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B3DS\n\n\t# Initialize DDR2 memory\n\tmww 0x63FD9088 0x35343535\t;# ESDCTL_RDDLCTL\n\tmww 0x63FD9090 0x4d444c44\t;# ESDCTL_WRDLCTL\n\tmww 0x63FD907c 0x01370138\t;# ESDCTL_DGCTRL0\n\tmww 0x63FD9080 0x013b013c\t;# ESDCTL_DGCTRL1\n\tmww 0x63FD9018 0x00011740\t;# ESDCTL_ESDMISC\n\tmww 0x63FD9000 0xc3190000\t;# ESDCTL_ESDCTL\n\tmww 0x63FD900c 0x9f5152e3\t;# ESDCTL_ESDCFG0\n\tmww 0x63FD9010 0xb68e8a63\t;# ESDCTL_ESDCFG1\n\tmww 0x63FD9014 0x01ff00db\t;# ESDCTL_ESDCFG2\n\tmww 0x63FD902c 0x000026d2\t;# ESDCTL_ESDRWD\n\tmww 0x63FD9030 0x009f0e21\t;# ESDCTL_ESDOR\n\tmww 0x63FD9008 0x12273030\t;# ESDCTL_ESDOTC\n\tmww 0x63FD9004 0x0002002d\t;# ESDCTL_ESDPDC\n\tmww 0x63FD901c 0x00008032\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00008033\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028031\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x052080b0\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008040\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803a\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803b\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028039\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x05208138\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008048\t;# ESDCTL_ESDSCR\n\tmww 0x63FD9020 0x00005800\t;# ESDCTL_ESDREF\n\tmww 0x63FD9040 0x04b80003\t;# ESDCTL_ZQHWCTRL\n\tmww 0x63FD9058 0x00022227\t;# ESDCTL_ODTCTRL\n\tmww 0x63FD901C 0x00000000\t;# ESDCTL_ESDSCR\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/imx8mp-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8MP-EVK\n#\n# Board includes FTDI-based JTAG adapter: interface/ftdi/imx8mp-evk.cfg\n#\n\ntransport select jtag\nadapter speed 1000\nreset_config srst_only\nadapter srst delay 100\n\nset CHIPNAME imx8mp\nset CHIPCORES 4\n\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/insignal_arndale.cfg",
    "content": "#\n# InSignal Arndale board\n#\n\nsource [find target/exynos5250.cfg]\n\n# Experimentally determined highest working speed\nadapter speed 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kasli.cfg",
    "content": "adapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\nftdi layout_init 0x0008 0x000b\n# adapter usb location 1:8\n\nreset_config none\ntransport select jtag\nadapter speed 25000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kc100.cfg",
    "content": "# Knovative KC-100 cable modem\n\n# TNETC4401PYP, 208-QFP U3\nsource [find target/tnetc4401.cfg]\n\n# 14-pin EJTAG on JP1. Standard pinout, 1-3-5-7-9-11 = nTRST-TDI-TDO-TMS-TCK-nSRST. Use 2 for GND.\n# Was initially disabled in hardware; had to add a solder bridge reenabling R124, R125 on back.\nreset_config trst_and_srst separate\n\n# 16Mb Intel CFI flash. Note this CPU has an internal ROM at 0x1FC0000 (phys) for cold boot.\n# All that really does is some minimal checks before jumping to external flash at 0x00000000 phys.\n# That is remapped to 0xB0000000 uncached, 0x90000000 cached.\nflash bank intel cfi 0xB0000000 0x200000 2 2 $_TARGETNAME\n\n# Perform this after a clean reboot, halt, and reset init (which should also leave it halted).\nproc kc100_dump_flash {} {\n\techo \"Probing 48 TSOP Intel CFI flash chip (2MB)...\"\n\tflash probe intel\n\techo \"Dumping 2MB flash chip to flashdump.bin.\n\tflash read_bank 0 flashdump.bin 0 0x200000\n}\n\n#TODO figure out memory init sequence to be able to dump from cached segment instead\n\n# There is also a serial console on JP2, 3-5-6 = TX-RX-GND. 9600/8/N/1.\n\n# Possibly of note, this modem's ancient ethernet port does not support Auto-MDIX.\n\n# This modem in many ways appears to be essentially a clone of the SB5120. See usbjtag.com.\n# The firmware/OS is also susceptible to many of the same procedures in \"Hacking the Cable Modem\"\n# by DerEngel (Ryan Harris), available from No Starch Press.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kc705.cfg",
    "content": "# http://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html\n\nsource [find interface/ftdi/digilent-hs1.cfg]\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\nadapter speed 25000\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/kc705.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc7k325t.bit;\\\n# jtagspi_program bitstream-kc705.bin 0;\\\n# jtagspi_program bios.bin 0xaf0000;\\\n# jtagspi_program runtime.fbi 0xb00000;\\\n# xc7_program xc7.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kcu105.cfg",
    "content": "# xilinx ultrascale\n# http://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/keil_mcb1700.cfg",
    "content": "#\n# Keil MCB1700 eval board\n#\n# http://www.keil.com/mcb1700/picture.asp\n#\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/keil_mcb2140.cfg",
    "content": "#\n# Keil MCB2140 eval board\n#\n# http://www.keil.com/mcb2140/picture.asp\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kindle2.cfg",
    "content": "# Board configuration file for Amazon Kindle Model No. D00701 and D00801\n# AKA Kindle 2nd generation and Kindle DX\n# using a Freescale MCIMX31LDVKN5D i.MX31 processor\n#\n# Pins at J9 40-Pin FFC-A:\n#  1 - GND\n# 16 - TRSTB\n# 17 - TDI\n# 18 - TMS\n# 19 - TCK\n# 20 - RTCK\n# 21 - TDO\n# 22 - DE\n# 25 - BOOT_MODE4\n# 27 - BOOT_MODE2\n\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n\n$_TARGETNAME configure -event reset-init { kindle2_init }\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n# 8MiB NOR Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xa0000000 0x800000 2 2 $_TARGETNAME\n\n# 16kiB internal SRAM\n$_TARGETNAME configure -work-area-phys 0x1fffc000 \\\n\t-work-area-size 0x4000 -work-area-backup 0\n\n# FIXME: currently SRST is not wired to the system\nreset_config trst_only\njtag_ntrst_assert_width 10\njtag_ntrst_delay 30\n\n# this is broken but enabled by default\narm11 memwrite burst disable\n\nadapter speed 1000\nftdi tdo_sample_edge falling\n\nproc kindle2_init {} {\n\timx3x_reset\n\tkindle2_clock_setup\n\tdisable_mmu_and_cache\n\tkindle2_misc_init\n\tkindle2_sdram_init\n\tarm core_state arm\n}\n\nproc kindle2_clock_setup {} {\n\t# CCMR: clock from FPM/CKIL\n\tmww 0x53f80000  0x074b0b7b\n\t# IPU_CONF\n\tmww 0x53fc0000  0x040\n\t# 398MHz\n\tmww 0x53f80004 0xff871650\n\tmww 0x53f80010 0x00331c23\n}\n\nproc kindle2_misc_init { } {\n\t# AIPS1\n\tmww 0x43f00040 0x0\n\tmww 0x43f00044 0x0\n\tmww 0x43f00048 0x0\n\tmww 0x43f0004c 0x0\n\tmww 0x43f00050 0x0\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\n\t# AIPS2\n\tmww 0x53f00040 0x0\n\tmww 0x53f00044 0x0\n\tmww 0x53f00048 0x0\n\tmww 0x53f0004c 0x0\n\tmww 0x53f00050 0x0\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000cc03\n\tmww 0xb8002004 0xa0330d01\n\tmww 0xb8002008 0x00220800\n}\n\nproc disable_mmu_and_cache {} {\n\t# Mode Supervisor, disable FIQ, IRQ and imprecise data aborts\n\treg cpsr 0x1d3\n\n\t# flush entire BTAC\n\tarm mcr 15 0 7 5 6 0\n\t# invalidate instruction and data cache\n\t# MCR CP15, 0, R1, C7, C7, 0\n\tarm mcr 15 0 7 7 0\n\n\t# clean and invalidate cache\n\tarm mcr 15 0 7 15 0\n\n\t# disable MMU and caches\n\tarm mcr 15 0 1 0 0 0\n\n\tarm mcr 15 0 15 2 4 0\n\n\t# invalidate TLBs\n\tarm mcr 15 0 8 7 0 0\n\n\t# Drain the write buffer\n\tarm mcr 15 0 7 10 4 0\n\n\t# start from AIPS 2GB region\n\tarm mcr 15 0 15 2 4 0x40000015\n}\n\nproc kindle2_sdram_init {} {\n\t#--------------------------------------------\n\t# Samsung K4X1G323PC-8GC3 32Mx32 Mobile DDR SDRAM\n\t#--------------------------------------------\n\t# SDCLK\n\tmww 0x43fac26c 0\n\n\t# CAS\n\tmww 0x43fac270 0\n\n\t# RAS\n\tmww 0x43fac274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43fac27c 0x1000\n\n\t# DQM3\n\tmww 0x43fac284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2dc)\n\tmww 0x43fac288 0\n\tmww 0x43fac28c 0\n\tmww 0x43fac290 0\n\tmww 0x43fac294 0\n\tmww 0x43fac298 0\n\tmww 0x43fac29c 0\n\tmww 0x43fac2a0 0\n\tmww 0x43fac2a4 0\n\tmww 0x43fac2a8 0\n\tmww 0x43fac2ac 0\n\tmww 0x43fac2b0 0\n\tmww 0x43fac2b4 0\n\tmww 0x43fac2b8 0\n\tmww 0x43fac2bc 0\n\tmww 0x43fac2c0 0\n\tmww 0x43fac2c4 0\n\tmww 0x43fac2c8 0\n\tmww 0x43fac2cc 0\n\tmww 0x43fac2d0 0\n\tmww 0x43fac2d4 0\n\tmww 0x43fac2d8 0\n\tmww 0x43fac2dc 0\n\n\t# ?\n\tmww 0xb8002000 0x00006602\n\tmww 0xb8002004 0x00000501\n\tmww 0xb8002008 0x00000000\n\n\t# LPDDR1 Initialization script\n\tmww 0xb8001010 0x00000002\n\tmww 0xb8001010 0x00000004\n\t# ESDCFG0: set timing parameters\n\tmww 0xb8001004 0x007fff7f\n\t# ESDCTL0: select Prechare-All mode\n\tmww 0xb8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\t# ESDCTL0: Auto Refresh\n\tmww 0xb8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\t# ESDCTL0: Load Mode Register\n\tmww 0xb8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\t# ESDCTL0: enable Auto-Refresh\n\tmww 0xb8001000 0x82226080\n\tmww 0x80000000 0xdeadbeef\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kontron_sl28.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Kontron SMARC-sAL28\n\ntransport select jtag\nreset_config srst_only srst_nogate\n\njtag newtap unknown0 tap -irlen 12\n\nset _CPUS 2\nsource [find target/ls1028a.cfg]\n\nsource [find tcl/cpld/altera-epm240.cfg]\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/kwikstik.cfg",
    "content": "#\n# Freescale KwikStik development board\n#\n\n#\n# JLINK interface is onboard\n#\nsource [find interface/jlink.cfg]\n\nsource [find target/k40.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/la_fonera-fon2200.cfg",
    "content": "source [find target/atheros_ar2315.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# LambdaConcept ECPIX-5\n# http://docs.lambdaconcept.com/ecpix-5/\n# Currently there are following board variants:\n# ECPIX-5 45F - LFE5UM5G-45F\n# ECPIX-5 85F - LFE5UM5G-85F\n#\n# This boards have two JTAG interfaces:\n# - CN4, micro USB port connected to FT2232HQ chip:\n#        ADBUS0 TCK\n#        ADBUS1 TDI\n#        ADBUS2 TDO\n#        ADBUS3 TMS\n#        BDBUS0 UART_TXD\n#        BDBUS1 UART_RXD\n#   This interface should be used with following config:\n#        interface/ftdi/lambdaconcept_ecpix-5.cfg\n# - CN3, 6 pin connector\n# See schematics for more details:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n#\n# No reset lines are implemented. So it is not possible to remote reset the FPGA\n# by using any of this interfaces\n\nsource [find interface/ftdi/lambdaconcept_ecpix-5.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lemaker_hikey.cfg",
    "content": "#\n# board configuration for LeMaker Hikey\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi6220.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/linksys-wag200g.cfg",
    "content": "#\n# Linksys WAG200G Router\n#\n# The stock firmware Flash layout is organized as follow:\n#\n#   Start       End         Device\n#   0x90000000  0x90020000  /dev/mtdblock/2\n#   0x90020000  0x900d0000  /dev/mtdblock/1\n#   0x900d0000  0x903a0000  /dev/mtdblock/0\n#   0x903a0000  0x903e0000  /dev/mtdblock/5\n#   0x903e0000  0x903f0000  /dev/mtdblock/3\n#   0x903f0000  0x90400000  /dev/mtdblock/4\n\nset partition_list {\n    adam2\t{ \"Adam2 bootloader\"\t\t0x90000000 0x00020000 }\n    kernel\t{ \"Kernel\"\t\t\t0x90020000 0x000b0000 }\n    rootfs\t{ \"Root FS\"\t\t\t0x900d0000 0x002d0000 }\n    lang\t{ \"Minix language part\"\t\t0x903a0000 0x00040000 }\n    config\t{ \"Firmware config\"\t\t0x903e0000 0x00010000 }\n    adam2env\t{ \"Adam2 environment\"\t\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 4MB MXIC 29LV320MBTC Flash (Manufacturer/Device: 0x00c2 0x227e)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/linksys-wrt54gl.cfg",
    "content": "#\n# Linksys WRT54GL v1.1\n#\n\nsource [find target/bcm5352e.cfg]\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0x1c000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x1c040000 0x003b0000 }\n    nvram\t{ \"Config space\"\t\t0x1c3f0000 0x00010000 }\n}\n\n# External 4MB NOR Flash (Intel TE28F320C3BD90 or similar)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x1c000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/linksys_nslu2.cfg",
    "content": "# This is for the LinkSys (CISCO) NSLU2 board\n# It is an Intel XSCALE IXP420 CPU.\n\nsource [find target/ixp42x.cfg]\n# The _TARGETNAME is set by the above.\n\n$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lisa-l.cfg",
    "content": "# the Lost Illusions Serendipitous Autopilot\n# http://paparazzi.enac.fr/wiki/Lisa\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/logicpd_imx27.cfg",
    "content": "# The LogicPD Eval IMX27 eval board has a single IMX27 chip\nsource [find target/imx27.cfg]\n\n# The Logic PD board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\n#\n# FIX ME, Add support to\n#\n# (A) hard reset the board.\n# (B) Initialize the SDRAM on the board\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lpc1850_spifi_generic.cfg",
    "content": "#\n# Generic LPC1850 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC1850 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc1850\n\nsource [find target/lpc1850.cfg]\n\n#A large working area greatly reduces flash write times\nset _WORKAREASIZE 0x4000\n\n$_CHIPNAME.m3 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lpc4350_spifi_generic.cfg",
    "content": "#\n# Generic LPC4350 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC4350 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/lubbock.cfg",
    "content": "# Intel \"Lubbock\" Development Board with PXA255 (dbpxa255)\n#  Obsolete; this was Intel's original PXA255 development system\n#  Board also had CPU cards for SA1100, PXA210, PXA250, and more.\n\nsource [find target/pxa255.cfg]\n\nadapter srst delay 250\njtag_ntrst_delay 250\n\n# NOTE: until after pinmux and such are set up, only CS0 is\n# available ... not 2nd bank of CFI, or FPGA, SRAM, ENET, etc.\n\n# CS0, CS1 -- two banks of CFI flash, 32 MBytes each\n# each bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME cfi 0x04000000 0x02000000 2 4 $_TARGETNAME\n\n# CS2 low -- FPGA registers\n# CS2 high -- 1 MByte SRAM at 0x0a00.0000 ... last 64K for scratch\n$_TARGETNAME configure -work-area-phys 0x0a0f0000\n\n$_TARGETNAME configure -event reset-assert-pre \\\n\t\"$_TARGETNAME configure -work-area-size 0\"\n\n# Make the hex led display a number, assuming CS2 is set up\n# and all digits have been enabled through the FPGA.\nproc hexled {u32} {\n\tmww 0x08000010 $u32\n}\n\n# CS3 -- Ethernet\n# CS4 -- SA1111\n# CS5 -- PCMCIA\n\n# NOTE:  system console normally uses the FF UART connector\n\nproc lubbock_init {target} {\n\n\techo \"Initialize PXA255 Lubbock board\"\n\n\t# (1) pinmux\n\n\t# GPSR0..GPSR2\n\tmww 0x40e00018 0x00008000\n\tmww 0x40e0001c 0x00FC0382\n\tmww 0x40e00020 0x0001FFFF\n\t# GPDR0..GPDR2\n\tmww 0x40e0000c 0x0060A800\n\tmww 0x40e00010 0x00FF0382\n\tmww 0x40e00014 0x0001C000\n\t# GAFR0_[LU]..GAFR2_[LU]\n\tmww 0x40e00054 0x98400000\n\tmww 0x40e00058 0x00002950\n\tmww 0x40e0005c 0x000A9558\n\tmww 0x40e00060 0x0005AAAA\n\tmww 0x40e00064 0xA0000000\n\tmww 0x40e00068 0x00000002\n\n\t# write PSSR, enable GPIOs\n\tmww 0x40f00000 0x00000020\n\n\t# write LED ctrl register ... ones disable\n\t# high byte, 8 hex leds; low byte, 8 discretes\n\tmwh 0x08000040 0xf0ff\n\n\thexled 0x0000\n\n\t# (2) Address space setup\n\n\t# MSC0/MSC1/MSC2\n\tmww 0x48000008 0x23f223f2\n\tmww 0x4800000c 0x3ff1a441\n\tmww 0x48000010 0x7ff97ff1\n\t# pcmcia/cf\n\tmww 0x48000014 0x00000000\n\tmww 0x48000028 0x00010504\n\tmww 0x4800002c 0x00010504\n\tmww 0x48000030 0x00010504\n\tmww 0x48000034 0x00010504\n\tmww 0x48000038 0x00004715\n\tmww 0x4800003c 0x00004715\n\n\thexled 0x1111\n\n\t# (3) SDRAM setup\n\t# REVISIT this looks dubious ... no refresh cycles\n\tmww 0x48000004 0x03CA4018\n\tmww 0x48000004 0x004B4018\n\tmww 0x48000004 0x000B4018\n\tmww 0x48000004 0x000BC018\n\tmww 0x48000000 0x00001AC8\n\tmww 0x48000000 0x00001AC9\n\n\tmww 0x48000040 0x00000000\n\n\t# FIXME -- setup:\n\t#  CLOCKS (and faster JTAG)\n\t#  enable icache\n\n\t# FIXME SRAM isn't working\n\t# $target configure -work-area-size 0x10000\n\n\thexled 0x2222\n\n\tflash probe 0\n\tflash probe 1\n\n\thexled 0xcafe\n}\n$_TARGETNAME configure -event reset-init \"lubbock_init $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/marsohod.cfg",
    "content": "#\n# Marsohod CPLD Development and Education board\n#\n# http://marsohod.org/howtostart/plata\n#\n\n# Recommended MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Altera MAXII EPM240T100C CPLD\nsource [find cpld/altera-epm240.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/marsohod2.cfg",
    "content": "#\n# Marsohod2 FPGA Development and Education board\n#\n# http://www.marsohod.org/prodmarsohod2\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Cyclone III EP3C10E144 FPGA\nsource [find fpga/altera-ep3c10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/marsohod3.cfg",
    "content": "#\n# Marsohod3 FPGA Development and Education board\n#\n# http://www.marsohod.org/plata-marsokhod3\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# MAX10 10M50SAE144C8GES FPGA\nsource [find fpga/altera-10m50.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/mbed-lpc11u24.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC11U24 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC11U24\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# NXP LPC11U24 Cortex-M0 with 32kB Flash and 8kB SRAM\nset WORKAREASIZE 0x2000\n\nsource [find target/lpc11xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/mbed-lpc1768.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC1768 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC1768\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/mcb1700.cfg",
    "content": "# Keil MCB1700 PCB with 1768\n#\n# Reset init script sets it to 100MHz\nset CCLK 100000\n\nsource [find target/lpc17xx.cfg]\n\nglobal MCB1700_CCLK\nset MCB1700_CCLK $CCLK\n\n$_TARGETNAME configure -event reset-start {\n\t# Start *real slow* as we do not know the\n    # state the boot rom left the clock in\n\tadapter speed 10\n}\n\n# Set up 100MHz clock to CPU\n$_TARGETNAME configure -event reset-init {\n    # PLL0CON: Disable PLL\n\tmww 0x400FC080 0x00000000\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n    # CCLK=PLL/4 (=100 MHz)\n\tmww 0x400FC104 0x00000003\n    # CLKSRCSEL: Clock source = internal RC oscillator\n\tmww 0x400FC10C 0x00000000\n\n    # PLL0CFG: M=50,N=1 -> PLL=400 MHz\n\tmww 0x400FC084 0x00000031\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# PLL0CON: Enable PLL\n\tmww 0x400FC080 0x00000001\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\tsleep 50\n\n    # PLL0CON: Connect PLL\n\tmww 0x400FC080 0x00000003\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# Dividing CPU clock by 8 should be pretty conservative\n\t#\n\t#\n\tglobal MCB1700_CCLK\n\tadapter speed [expr {$MCB1700_CCLK / 8}]\n\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\n\tmww 0x400FC040 0x01\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/microchip_explorer16.cfg",
    "content": "# Microchip Explorer 16 with PIC32MX360F512L PIM module.\n# http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858\n\n# TAPID for PIC32MX360F512L\nset CPUTAPID 0x30938053\n\n# use 32k working area\nset WORKAREASIZE 32768\n\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/microchip_sama5d27_som1_kit1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAMA5D27-SOM1-EK1\n# https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATSAMA5D27-SOM1-EK1\n# This board provide two jtag interfaces:\n# J11 - 10 pin interface\n# J10 - USB interface connected to the J-Link-OB.\n#       This functionality is implemented with an ATSAM3U4C microcontroller and\n#       provides JTAG functions and a bridge USB/Serial debug port (CDC).\n#\n# Jumper J7 disables the J-Link-OB-ATSAM3U4C JTAG functionality.\n# - Jumper J7 not installed: J-Link-OB-ATSAM3U4C is enabled and fully functional.\n# - Jumper J7 installed: J-Link-OB-ATSAM3U4C is disabled and an external JTAG\n#   controller can be used through the 10-pin JTAG port J11.\n\nsource [find interface/jlink.cfg]\nreset_config srst_only\n\nsource [find target/at91sama5d2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/microchip_same51_curiosity_nano.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAME51 Curiosity Nano evaluation kit.\n#\n# https://www.microchip.com/en-us/development-tool/EV76S68A\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same51\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/microchip_same54_xplained_pro.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54 Xplained Pro evaluation kit.\n# http://www.microchip.com/developmenttools/productdetails.aspx?partno=atsame54-xpro\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same54\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/microchip_saml11_xplained_pro.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L11 Xplained Pro Evaluation Kit.\n# https://www.microchip.com/DevelopmentTools/ProductDetails/dm320205\n#\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 1000\n\nset CHIPNAME saml11\nsource [find target/atsaml1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/mini2440.cfg",
    "content": "#-------------------------------------------------------------------------\n# Mini2440 Samsung s3c2440A Processor with 64MB DRAM, 64MB NAND, 2 MB N0R\n# NOTE: Configured for NAND boot (switch S2 in NANDBOOT)\n# 64 MB NAND (Samsung K9D1208V0M)\n# B Findlay  08/09\n#\n#   ----------- Important notes to help you on your way ----------\n# README:\n#     NOR/NAND Boot Switch - I have not read the vivi source, but from\n#     what I could tell from reading the registers it appears that vivi\n#     loads itself into DRAM and then flips NFCONT (0x4E000004) bits\n#     Mode (bit 0 = 1), and REG_nCE (bit 1 = 0) which maps the NAND\n#     FLASH at the bottom 64MB of memory. This essentially takes the\n#     NOR Flash out of the circuit so you can't trash it.\n#\n#     I adapted the samsung_s3c2440.cfg file which is why I did not\n#     include \"source [find target/samsung_s3c2440.cfg]\".  I believe\n#     the -work-area-phys 0x200000 is incorrect, but also had to pad\n#     some additional resets.  I didn't modify it as if it is working\n#     for someone, the work-area-phys is not used by most.\n#\n#     JTAG ADAPTER SPECIFIC\n#     IMPORTANT! Any JTAG device that uses ADAPTIVE CLOCKING will likely\n#     FAIL as the pin RTCK on the mini2440 10 pin JTAG Conn doesn't exist.\n#     This is Pin 11 (RTCK) on 20 pin JTAG connector. Therefore it is\n#     necessary to FORCE setting the clock. Normally this should be configured\n#     in the openocd.cfg file, but was placed here as it can be a tough\n#     problem to figure out.  THIS MAY NOT FIX YOUR PROBLEM.. I modified\n#     the openOCD driver jlink.c and posted it here. It may eventually end\n#     up changed in openOCD, but its a hack in the driver and really should\n#     be in the jtag layer (core.c me thinks), but haven't done it yet. My\n#     hack for jlink.c may be found here.\n#\n#     http://forum.sparkfun.com/viewtopic.php?t=16763&sid=946e65abdd3bab39cc7d90dee33ff135\n#\n#     Note: Also if you have a USB JTAG, you will need the USB library installed\n#     on your system \"libusb-dev\" or the make of openocd will fail. I *think*\n#     it's apt-get install libusb-dev.  When I made my config I only included\n#     --enable-jlink and --enable-usbdevs\n#\n#     I HAVE NOT Tested this thoroughly, so there could still be problems.\n#     But it should get you way ahead of the game from where I started.\n#     If you find problems (and fixes) please post them to\n#     openocd-development@lists.berlios.de and join the developers and\n#     check in fixes to this and anything else you find.  I do not\n#     provide support, but if you ask really nice and I see anything\n#     obvious I will tell you.. mostly just dig, fix, and submit to openocd.\n#\n#     best!   brfindla@yahoo.com   Nashua, NH USA\n#\n#     Recommended resources:\n#       - first two are the best Mini2440 resources anywhere\n#       - maintained by buserror... thanks guy!\n#\n#       http://bliterness.blogspot.com/\n#       http://code.google.com/p/mini2440/\n#\n#       others....\n#\n#       http://forum.sparkfun.com/viewforum.php?f=18\n#       http://labs.kernelconcepts.de/Publications/Micro24401/\n#       http://www.friendlyarm.net/home\n#       http://www.amontec.com/jtag_pinout.shtml\n#\n#-------------------------------------------------------------------------\n#\n#\n# Your openocd.cfg file should contain:\n# source [find interface/<yourjtag>.cfg]\n# source [find board/mini2440.cfg]\n#\n#\n#\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\n#-------------------------------------------------------------------------\n# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor : ARM920Tid(wb) rev 0 (v4l)\n# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d\n#  (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n#-------------------------------------------------------------------------\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x40000000  -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\n#-------------------------------------------------------------------------\n# JTAG ADAPTER SPECIFIC\n# IMPORTANT! See README at top of this file.\n#-------------------------------------------------------------------------\n\n    adapter speed 12000\n    jtag interface\n\n#-------------------------------------------------------------------------\n# GDB Setup\n#-------------------------------------------------------------------------\n\n    gdb_breakpoint_override hard\n\n#------------------------------------------------\n# ARM SPECIFIC\n#------------------------------------------------\n\n    targets\n  #  arm7_9 dcc_downloads enable\n  #  arm7_9 fast_memory_access enable\n\n\n    nand device s3c2440 0\n\n    adapter srst delay 100\n    jtag_ntrst_delay 100\n    reset_config trst_and_srst\n    init\n\n    echo \" \"\n    echo \"-------------------------------------------\"\n    echo \"--- login with - telnet localhost 4444  ---\"\n    echo \"--- then type help_2440                 ---\"\n    echo \"-------------------------------------------\"\n    echo \" \"\n\n\n\n#------------------------------------------------\n# Processor Initialialization\n# Note: Processor writes can only occur when\n# the state is in SYSTEM. When you call init_2440\n# one of the first lines will tell you what state\n# you are in. If a linux image is booting\n# when you run this, it will not work\n# a vivi boot loader will run with this just\n# fine. The reg values were obtained by a combination\n# of figuring them out fromt the manual, and looking\n# at post vivi values with the debugger. Don't\n# place too much faith in them, but seem to work.\n#------------------------------------------------\n\nproc init_2440 { } {\n\n    halt\n    s3c2440.cpu curstate\n\n    #-----------------------------------------------\n    # Set Processor Clocks - mini2440 xtal=12mHz\n    # we set main clock for 405mHZ\n    # we set the USB Clock for 48mHz\n    # OM2 OM3 pulled to ground so main clock and\n    # usb clock are off 12mHz xtal\n    #-----------------------------------------------\n\n    mww phys 0x4C000014 0x00000005 ;#  Clock Divider control Reg\n    mww phys 0x4C000000 0xFFFFFFFF ;#  LOCKTIME count register\n    mww phys 0x4C000008 0x00038022 ;#  UPPLCON  USB clock config Reg\n    mww phys 0x4C000004 0x0007F021 ;#  MPPLCON  Proc clock config Reg\n\n    #-----------------------------------------------\n    # Configure Memory controller\n    # BWSCON configures all banks, NAND, NOR, DRAM\n    # DRAM - 64MB - 32 bit bus, uses BANKCON6 BANKCON7\n    #-----------------------------------------------\n\n    mww phys 0x48000000 0x22111112 ;#  BWSCON - Bank and Bus Width\n    mww phys 0x48000010 0x00001112 ;#  BANKCON4 - ?\n    mww phys 0x4800001c 0x00018009 ;#  BANKCON6 - DRAM\n    mww phys 0x48000020 0x00018009 ;#  BANKCON7 - DRAM\n    mww phys 0x48000024 0x008E04EB ;#  REFRESH  - DRAM\n    mww phys 0x48000028 0x000000B2 ;#  BANKSIZE - DRAM\n    mww phys 0x4800002C 0x00000030 ;#  MRSRB6 - DRAM\n    mww phys 0x48000030 0x00000030 ;#  MRSRB7 - DRAM\n\n    #-----------------------------------------------\n    # Now port configuration for enables for memory\n    # and other stuff.\n    #-----------------------------------------------\n\n    mww phys 0x56000000\t0x007FFFFF ;#  GPACON\n\n    mww phys 0x56000010\t0x00295559 ;#  GPBCON\n    mww phys 0x56000018\t0x000003FF ;#  GPBUP (PULLUP ENABLE)\n    mww phys 0x56000014\t0x000007C2 ;#  GPBDAT\n\n    mww phys 0x56000020\t0xAAAAA6AA ;#  GPCCON\n    mww phys 0x56000028\t0x0000FFFF ;#  GPCUP\n    mww phys 0x56000024\t0x00000020 ;#  GPCDAT\n\n    mww phys 0x56000030\t0xAAAAAAAA ;#  GPDCON\n    mww phys 0x56000038\t0x0000FFFF ;#  GPDUP\n\n    mww phys 0x56000040\t0xAAAAAAAA ;#  GPECON\n    mww phys 0x56000048\t0x0000FFFF ;#  GPEUP\n\n    mww phys 0x56000050\t0x00001555 ;#  GPFCON\n    mww phys 0x56000058\t0x0000007F ;#  GPFUP\n    mww phys 0x56000054\t0x00000000 ;#  GPFDAT\n\n    mww phys 0x56000060\t0x00150114 ;#  GPGCON\n    mww phys 0x56000068\t0x0000007F ;#  GPGUP\n\n    mww phys 0x56000070\t0x0015AAAA ;#  GPHCON\n    mww phys 0x56000078\t0x000003FF ;#  GPGUP\n\n}\n\n\n\nproc flash_config { } {\n\n    #-----------------------------------------\n    # Finish Flash Configuration\n    #-----------------------------------------\n\n    halt\n\n    #flash configuration (K9D1208V0M: 512Mbit, x8, 3.3V, Mode: Normal, 1st gen)\n    nand probe 0\n    nand list\n}\n\nproc flash_uboot { } {\n\n\t# flash the u-Boot binary and reboot into it\n\tinit_2440\n\tflash_config\n\tnand erase 0 0x0 0x40000\n\tnand write 0 /tftpboot/u-boot-nand512.bin 0 oob_softecc_kw\n\tresume\n}\n\n\nproc load_uboot { } {\n        echo \" \"\n        echo \" \"\n        echo \"----------------------------------------------------------\"\n        echo \"---- Load U-Boot into RAM and execute it.              ---\"\n        echo \"---- NOTE: loads, partially runs, and hangs            ---\"\n        echo \"---- U-Boot is fine, this image runs from vivi.        ---\"\n        echo \"---- I burned u-boot into NAND so I didn't finish      ---\"\n        echo \"---- debugging it. I am leaving this here as it is     ---\"\n        echo \"---- part of the way there if you want to fix it.      ---\"\n        echo \"----                                                   ---\"\n        echo \"---- mini2440 U-boot here:                             ---\"\n        echo \"---- http://repo.or.cz/w/u-boot-openmoko/mini2440.git  ---\"\n        echo \"---- Also this:                                        ---\"\n        echo \"---- http://code.google.com/p/mini2440/wiki/MiniBringup --\"\n        echo \"----------------------------------------------------------\"\n\n\tinit_2440\n\techo \"Loading /tftpboot/u-boot-nand512.bin\"\n\tload_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"Verifying image....\"\n\tverify_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"jumping to u-boot\"\n        #bp 0x33f80068 4 hw\n        reg 0 0\n        reg 1 0\n        reg 2 0\n        reg 3 0\n        reg 4 0x33f80000\n      \tresume 0x33f80000\n}\n\n       # this may help a little bit debugging the load_uboot\nproc s {} {\n        step\n        reg\n        arm disassemble 0x33F80068 0x10\n}\n\nproc help_2440 {} {\n    echo \" \"\n    echo \" \"\n    echo \"-----------------------------------------------------------\"\n    echo \"---- The following mini2440 funcs are supported        ----\"\n    echo \"----   init_2440 - initialize clocks, DRAM, IO         ----\"\n    echo \"----   flash_config - configures nand flash            ----\"\n    echo \"----   load_uboot - loads uboot into ram               ----\"\n    echo \"----   flash_uboot - flashes uboot to nand (untested)  ----\"\n    echo \"----   help_2440 - this help display                   ----\"\n    echo \"-----------------------------------------------------------\"\n    echo \" \"\n    echo \" \"\n}\n\n\n#----------------------------------------------------------------------------\n#----------------------------------- END ------------------------------------\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/mini6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a tiny6410\n# Processor       : ARM1176\n# Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2)\n# Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787, part: 0x7b76, ver: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nproc init_6410 {} {\n\thalt\n\treg cpsr 0x1D3\n\tarm mcr 15 0 15 2 4 0x70000013\n\n\t#-----------------------------------------------\n\t# Clock and Timer Setting\n\t#-----------------------------------------------\n\tmww 0x7e004000 0\t\t;# WATCHDOG \t- Disable\n\tmww 0x7E00F120 0x0003\t\t;# MEM_SYS_CFG\t- CS0:8 bit, Mem1:32bit, CS2=NAND\n\t#mww 0x7E00F120 0x1000\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=SROMC\n\t#mww 0x7E00F120 0x1002\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=OND\n\tmww 0x7E00F900 0x805e\t\t;# OTHERS\t- Change SYNCMUX[6] to “1”\n\tsleep 1000\n\tmww 0x7E00F900 0x80de\t\t;# OTHERS\t- Assert SYNCREQ&VICSYNCEN to “1”(rb1004modify)\n\tsleep 1000\t\t\t;#\t\t- Others[11:8] to 0xF\n\tmww 0x7E00F000 0xffff\t\t;# APLL_LOCK\t- APLL LockTime\n\tmww 0x7E00F004 0xffff\t\t;# MPLL_LOCK\t- MPLL LockTime\n\tmww 0x7E00F020 0x1047310\t;# CLK_DIV0 \t- ARMCLK:HCLK:PCLK = 1:4:16\n\tmww 0x7E00F00c 0x81900302\t;# APLL_CON \t- A:400, P:3, S:2 => 400MHz\n\tmww 0x7E00F010 0x81900303\t;# MPLL_CON \t- M:400, P:3, S:3 => 200MHz\n\tmww 0x7E00F01c 0x3\t\t;# CLK_SRC \t- APLL,MPLL Clock Select\n\n\t#-----------------------------------------------\n\t# DRAM initialization\n\t#-----------------------------------------------\n\tmww 0x7e001004 0x4\t\t;# P1MEMCCMD\t- Enter the config state\n\tmww 0x7e001010 0x30C\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 100MHz\n#\tmww 0x7e001010 0x40e\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 133MHz\n\tmww 0x7e001014 0x6\t\t;# P1CASLAT\t- CAS Latency = 3\n\tmww 0x7e001018 0x1\t\t;# P1T_DQSS\n\tmww 0x7e00101c 0x2\t\t;# P1T_MRD\n\tmww 0x7e001020 0x7\t\t;# P1T_RAS\t- 45 ns\n\tmww 0x7e001024 0xA\t\t;# P1T_RC\t- 67.5 ns\n\tmww 0x7e001028 0xC\t\t;# P1T_RCD\t- 22.5 ns\n\tmww 0x7e00102C 0x10B\t\t;# P1T_RFC\t- 80 ns\n\tmww 0x7e001030 0xC\t\t;# P1T_RP\t- 22.5 ns\n\tmww 0x7e001034 0x3\t\t;# P1T_RRD\t- 15 ns\n\tmww 0x7e001038 0x3\t\t;# P1T_WR\t- 15 ns\n\tmww 0x7e00103C 0x2\t\t;# P1T_WTR\n\tmww 0x7e001040 0x2\t\t;# P1T_XP\n\tmww 0x7e001044 0x11\t\t;# P1T_XSR\t- 120 ns\n\tmww 0x7e001048 0x11\t\t;# P1T_ESR\n\n\t#-----------------------------------------------\n\t# Memory Configuration Registers\n\t#-----------------------------------------------\n\tmww 0x7e00100C 0x00010012 \t;# P1MEMCFG\t- 1 CKE, 1Chip, 4burst, Alw, AP[10],ROW/Column bit\n\tmww 0x7e00104C 0x0B41 \t\t;# P1MEMCFG2\t- Read delay 1 Cycle, mDDR, 32bit, Sync.\n\tmww 0x7e001200 0x150F0 \t\t;# CHIP_N_CFG\t- 0x150F0 for 256M, 0x150F8 for 128M\n\n\t#-----------------------------------------------\n\t# Memory Direct Commands\n\t#-----------------------------------------------\n\tmww 0x7e001008 0xc0000\t\t;# Chip0 Direct Command :NOP5\n\tmww 0x7e001008 0x0\t\t;# Chip0 Direct Command :PreCharge al\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0xA0000\t\t;# EMRS, DS:Full, PASR:Full\n\tmww 0x7e001008 0x80032\t\t;# MRS, CAS3, BL4\n\tmww 0x7e001004 0x0\t\t;# Enable DMC1\n}\n\nproc install_6410_uboot {} {\n\t# write U-boot magic number\n\tmww 0x50000000 0x24564236\n\tmww 0x50000004 0x20764316\n\tload_image u-boot_nand-ram256.bin 0x50008000 bin\n\tload_image u-boot_nand-ram256.bin 0x57E00000 bin\n\n\t#Kick in\n\treg pc 0x57E00000\n\tresume\n}\n\nproc init_6410_flash {} {\n\thalt\n\tnand probe 0\n\tnand list\n}\n\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\ngdb_breakpoint_override hard\n\ntargets\nnand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu\n\ninit\necho \" \"\necho \" \"\necho \"-------------------------------------------------------------------\"\necho \"---- The following mini6410/tiny6410 functions are available:  ----\"\necho \"----   init_6410 - initialize clock, timer, DRAM               ----\"\necho \"----   init_6410_flash - initializes NAND flash support        ----\"\necho \"----   install_6410_uboot - copies u-boot image into RAM and   ----\"\necho \"----                        runs it                            ----\"\necho \"-------------------------------------------------------------------\"\necho \" \"\necho \" \"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n\nsource [find interface/ftdi/minispartan6.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to read the device dna of the FPGA on the board;\n# openocd -f board/minispartan6.cfg -c \"init;xc6s_print_dna xc6s.tap;shutdown\"\n\n# example command to write bitstream\n# openocd -f board/minispartan6.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx??.bit;\\\n# jtagspi_program bitstream.bin 0;\\\n# xc6s_program xc6s.tap;\\\n# shutdown\"\n#\n# jtagspi flash procies can be found in the contrib/loaders/flash/fpga/\n# directory, with prebuilt versions available at\n# https://github.com/jordens/bscan_spi_bitstreams\n#\n# For the SLX25 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx25.bit\n# For the SLX9 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx9.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nds32_corvettef1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-Corvette-F1 R1.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r1/\n# ADP-Corvette-F1 R2.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r2/\n\nadapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nreset_config srst_only\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nds32_xc5.cfg",
    "content": "set _CPUTAPID 0x1000063d\nset _CHIPNAME nds32\nsource [find target/nds32v3.cfg]\n\njtag init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nds32_xc7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-XC7K160/410\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/adp-xc7k160-410/\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/netgear-dg834v3.cfg",
    "content": "#\n# Netgear DG834v3 Router\n# Internal 4Kb RAM (@0x80000000)\n# Flash is located at 0x90000000 (CS0) and RAM is located at 0x94000000 (CS1)\n#\n\nset partition_list {\n    loader\t{ \"Bootloader (ADAM2)\"\t\t0x90000000 0x00020000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x90020000 0x003d0000 }\n    config\t{ \"Bootloader config space\"\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 16MB SDRAM - disabled as we use internal sram\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n\n# External 4MB NOR Flash\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/netgear-wg102.cfg",
    "content": "source [find target/atheros_ar2313.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\tmips32 cp0 12 0 0x10400000\n\n\t# configure sdram controller\n\tmww 0xb8300004 0x0e03\n\tsleep 100\n\tmww 0xb8300004 0x0e01\n\tmww 0xb8300008 0x10\n\tsleep 500\n\tmww 0xb8300004 0x0e02\n\n\tmww 0xb8300000 0x6c0088\n\tmww 0xb8300008 0x57e\n\tmww 0xb8300004 0x0e00\n\tmww 0xb8300004 0xb00\n\n\t# configure flash\n\t#                 0x00000001 - 0x01 << FLASHCTL_IDCY_S\n\t#                 0x000000e0 - 0x07 << FLASHCTL_WST1_S\n\t# FLASHCTL_RBLE   0x00000400 - Read byte lane enable\n\t#                 0x00003800 - 0x07 << FLASHCTL_WST2_S\n\t# FLASHCTL_AC_8M  0x00060000 - Size of flash\n\t# FLASHCTL_E      0x00080000 - Flash bank enable (added)\n\t# FLASHCTL_WP     0x04000000 - write protect. If used, CFI mode wont work!!\n\t# FLASHCTL_MWx16  0x10000000 - 16bit mode. Do not use it!!\n\t# FLASHCTL_MWx8   0x00000000 - 8bit mode.\n\tmww 0xb8400000 0x000d3ce1\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbe000000 0x00400000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nordic_nrf51822_mkit.cfg",
    "content": "#\n# Nordic Semiconductor PCA10024 board (aka nRF51822-mKIT)\n#\n\nsource [find interface/cmsis-dap.cfg]\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nordic_nrf51_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF51 Development Kit (nRF6824)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nordic_nrf52_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF52 Development Kit (nRF52832)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nordic_nrf52_ftx232.cfg",
    "content": "#\n# nordic module NRF52 (nRF52832/52840) attached to an adafruit ft232h module\n# or any FT232H/FT2232H/FT4232H based board/module\n#\n\nsource [find interface/ftdi/ft232h-module-swd.cfg]\n#source [find interface/ftdi/minimodule-swd.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/novena-internal-fpga.cfg",
    "content": "#\n# Novena open hardware and F/OSS-friendly computing platform\n#\n# Design documentation:\n# http://www.kosagi.com/w/index.php?title=Novena_PVT_Design_Source\n#\n# +-------------+--------------+------+-------+---------+\n# | Pad name    | Schematic    | GPIO | sysfs | JTAG    |\n# +-------------+--------------+------+-------+---------+\n# | DISP0_DAT13 | FPGA_RESET_N | 5-07 |  135  | RESET_N |\n# | DISP0_DAT14 | FPGA_TCK     | 5-08 |  136  | TCK     |\n# | DISP0_DAT15 | FPGA_TDI     | 5-09 |  137  | TDI     |\n# | DISP0_DAT16 | FPGA_TDO     | 5-10 |  138  | TDO     |\n# | DISP0_DAT17 | FPGA_TMS     | 5-11 |  139  | TMS     |\n# +-------------+--------------+------+-------+---------+\n\nadapter driver sysfsgpio\n\ntransport select jtag\n\n# TCK TMS TDI TDO\nsysfsgpio jtag_nums 136 139 137 138\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/npcx_evb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Nuvoton NPCX Evaluation Board\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\nsource [find target/npcx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/numato_mimas_a7.cfg",
    "content": "#\n# Numato Mimas A7 - Artix 7 FPGA Board\n#\n# https://numato.com/product/mimas-a7-artix-7-fpga-development-board-with-ddr-sdram-and-gigabit-ethernet\n#\n# Note: Connect external DC power supply if programming a heavy design onto FPGA.\n#       Programming while powering via USB may lead to programming failure.\n#       Therefore, prefer external power supply.\n\nadapter driver ftdi\nftdi device_desc \"Mimas Artix 7 FPGA Module\"\nftdi vid_pid 0x2a19 0x1009\n\n# channel 0 is for custom purpose by users (like uart, fifo etc)\n# channel 1 is reserved for JTAG (by-default) or SPI (possible via changing solder jumpers)\nftdi channel 1\nftdi tdo_sample_edge falling\n\n\n# FTDI Pin Layout\n#\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | DBUS7  | DBUS6 | DBUS5 | DBUS4 | DBUS3 | DBUS2 | DBUS1 | DBUS0 |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | PROG_B | OE_N  |  NC   |  NC   |  TMS  |  TDO  |  TDI  |  TCK  |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n#\n# OE_N is JTAG buffer output enable signal (active-low)\n# PROG_B is not used, so left as input to FTDI.\n#\nftdi layout_init 0x0008 0x004b\nreset_config none\nadapter speed 30000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/numato_opsis.cfg",
    "content": "# http://opsis.hdmi2usb.tv\n#\n# The Numato Opsis is an FPGA based, open video platform.\n#\n# The board is supported via ixo-usb-jtag project. See the\n# interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_frdm-k64f.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an NXP Freedom eval board with a single MK64FN1M0VLL12 chip.\n# https://www.nxp.com/design/development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# Set working area to 16 KiB\nset WORKAREASIZE 0x4000\n\nset CHIPNAME k64f\nreset_config srst_only\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_frdm-ls1012a.cfg",
    "content": "#\n# NXP FRDM-LS1012A (Freedom)\n#\n\n#\n# NXP Kinetis K20\n#\nsource [find interface/cmsis-dap.cfg]\ntransport select jtag\n\n# Also offers a 10-pin 0.05\" CoreSight JTAG connector.\n\nsource [find target/ls1012a.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_imx7sabre.cfg",
    "content": "# NXP IMX7SABRE board\n# use on-board JTAG header\ntransport select jtag\n\n# set a safe speed, can be overridden\nadapter speed 1000\n\n# reset configuration has TRST and SRST support\nreset_config trst_and_srst srst_push_pull\n# need at least 100ms delay after SRST release for JTAG\nadapter srst delay 100\n\n# source the target file\nsource [find target/imx7.cfg]\n# import mrw proc\nsource [find mem_helper.tcl]\n\n# function to disable the on-chip watchdog\nproc imx7_disable_wdog { } {\n        # echo \"disable watchdog power-down counter\"\n        mwh phys 0x30280008 0x00\n}\n\nproc imx7_uart_dbgconf { } {\n\t# disable response to debug_req signal for uart1\n\tmww phys 0x308600b4 0x0a60\n}\n\nproc check_bits_set_32 { addr mask } {\n    while { [expr {[mrw $addr] & $mask} == 0] } { }\n}\n\nproc apply_dcd { } {\n    # echo \"apply dcd\"\n\n    mww phys 0x30340004 0x4F400005\n    # Clear then set bit30 to ensure exit from DDR retention\n    mww phys 0x30360388 0x40000000\n    mww phys 0x30360384 0x40000000\n\n    mww phys 0x30391000 0x00000002\n    mww phys 0x307a0000 0x01040001\n    mww phys 0x307a01a0 0x80400003\n    mww phys 0x307a01a4 0x00100020\n    mww phys 0x307a01a8 0x80100004\n    mww phys 0x307a0064 0x00400046\n    mww phys 0x307a0490 0x00000001\n    mww phys 0x307a00d0 0x00020083\n    mww phys 0x307a00d4 0x00690000\n    mww phys 0x307a00dc 0x09300004\n    mww phys 0x307a00e0 0x04080000\n    mww phys 0x307a00e4 0x00100004\n    mww phys 0x307a00f4 0x0000033f\n    mww phys 0x307a0100 0x09081109\n    mww phys 0x307a0104 0x0007020d\n    mww phys 0x307a0108 0x03040407\n    mww phys 0x307a010c 0x00002006\n    mww phys 0x307a0110 0x04020205\n    mww phys 0x307a0114 0x03030202\n    mww phys 0x307a0120 0x00000803\n    mww phys 0x307a0180 0x00800020\n    mww phys 0x307a0184 0x02000100\n    mww phys 0x307a0190 0x02098204\n    mww phys 0x307a0194 0x00030303\n    mww phys 0x307a0200 0x00000016\n    mww phys 0x307a0204 0x00171717\n    mww phys 0x307a0214 0x04040404\n    mww phys 0x307a0218 0x0f040404\n    mww phys 0x307a0240 0x06000604\n    mww phys 0x307a0244 0x00000001\n    mww phys 0x30391000 0x00000000\n    mww phys 0x30790000 0x17420f40\n    mww phys 0x30790004 0x10210100\n    mww phys 0x30790010 0x00060807\n    mww phys 0x307900b0 0x1010007e\n    mww phys 0x3079009c 0x00000d6e\n    mww phys 0x30790020 0x08080808\n    mww phys 0x30790030 0x08080808\n    mww phys 0x30790050 0x01000010\n    mww phys 0x30790050 0x00000010\n\n    mww phys 0x307900c0 0x0e407304\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e447306\n\n    check_bits_set_32 0x307900c4 0x1\n\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e407304\n\n\n    mww phys 0x30384130 0x00000000\n    mww phys 0x30340020 0x00000178\n    mww phys 0x30384130 0x00000002\n    mww phys 0x30790018 0x0000000f\n\n    check_bits_set_32 0x307a0004 0x1\n}\n\n# disable internal reset-assert handling to\n# allow reset-init to work\n$_TARGETNAME.0 configure -event reset-assert \"\"\n$_TARGETNAME.1 configure -event reset-assert \"\"\n$_TARGETNAME_2 configure -event reset-assert \"\"\n\n$_TARGETNAME.0 configure -event reset-init {\n    global _CHIPNAME\n    imx7_disable_wdog\n    imx7_uart_dbgconf\n    apply_dcd\n    $_CHIPNAME.dap memaccess 0\n}\n\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_lpc-link2.cfg",
    "content": "#\n# NXP LPC-Link2\n#\n# http://www.nxp.com/board/OM13054.html\n# https://www.lpcware.com/lpclink2\n# http://embeddedartists.com/products/lpcxpresso/lpclink2.php\n#\n\nsource [find target/lpc4370.cfg]\n\n# W25Q80BVSSIG w/ 1 MB flash\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_mcimx8m-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8M-EVK\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_rdb-ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046ARDB (Reference Design Board)\n# This is for the \"console\" USB port on the front panel\n# You must ensure that SW4-7 is in the \"off\" position\n\n# NXP K20\n# The firmware implements the old CMSIS-DAP v1 USB HID interface\n# You must pass --enable-cmsis-dap to ./configure to enable it\nsource [find interface/cmsis-dap.cfg]\n\ntransport select jtag\nreset_config srst_only\n\nsource [find target/ls1046a.cfg]\n\n# The adapter can't handle 10MHz\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/nxp_rdb-ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088ARDB (Reference Design Board)\n# This is for the \"main\" JTAG connector J55\n\ntransport select jtag\nreset_config srst_only\n\n# To access the CPLD, populate J48 and add `-c 'set CWTAP 1'` to your command\n# line. At the time of this writing, programming is unsupported.\nif { [info exists CWTAP] } {\n\tsource [find cpld/altera-epm240.cfg]\n} else {\n\tsource [find target/ls1088a.cfg]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_LPC2378STK.cfg",
    "content": "#####################################################\n# Olimex LPC2378STK eval board\n#\n# http://olimex.com/dev/lpc-2378stk.html\n#\n# Author: Sten, debian@sansys-electronic.com\n#####################################################\n#\n\nsource [find target/lpc2378.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_lpc_h2148.cfg",
    "content": "#\n# Olimex LPC-H2148 eval board\n#\n# http://www.olimex.com/dev/lpc-h2148.html\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_sam7_ex256.cfg",
    "content": "# Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it.\n\nsource [find target/at91sam7x256.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_sam7_la2.cfg",
    "content": "source [find target/at91sam7a2.cfg]\n\n# delays needed to get stable reads of cpu state\njtag_ntrst_delay 10\nadapter srst delay 200\n\n# board uses pullup and connects only srst\nreset_config srst_open_drain\n\n# srst is connected to NRESET of CPU and fully resets everything...\nreset_config srst_only srst_pulls_trst\n\nadapter speed 1\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 1\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# init script from http://www.mikrocontroller.net/topic/107462\n\t# AT91SAM7A2\n\t# AMC (advanced memory controller)\n\n\techo \"setting up AMC\"\n\t# AMC_CS0 - FLASH 1MB (0x40000000-0x400FFFFF) + DM9000E (0x40100000)\n\tmww 0xFFE00000 0x40003EBD\n\n\t# AMC_CS1 - RAM low 2MB (0x40400000-0x405FFFFF)\n\tmww 0xFFE00004 0x404030A9\n\n\t# AMC_CS2 - RAM high 2MB (0x40800000-0x405FFFFF)\n\t#mww 0xFFE00008 0x404030A9\n\t# changed to  0x40_8_\n\tmww 0xFFE00008 0x408030A9\n\n\t# AMC_MCR\n\tmww 0xFFE00024 0x00000004\n\n\t# AMC_RCR force remap\n\tmww 0xFFE00020 0x00000001\n\n\techo \"set up AMC\"\n\tsleep 100\n\n\t# the following base addresses from the original script did not correspond to those from datasheet\n\t# changed bases from 0xFF000000 to 0xFFF00000\n\n\t# disable watchdog, to prevent unwanted resets\n\tmww 0xFFFA0068 0x00000000\n\techo \"disabled watchdog\"\n\n\tsleep 50\n\n\t# disable PLL\n\tmww 0xFFFEC004 0x18070004\n\n\t# PLL = 10 ==> Coreclock = 6Mhz*10/2 = 30 Mhz\n\tmww 0xFFFEC010 0x762D800A\n\n\t# enable PLL\n\tmww 0xFFFEC000 0x23050004\n\techo \"set up pll\"\n\n\tsleep 100\n\tadapter speed 5000\n}\n\n$_TARGETNAME arm7_9 dcc_downloads enable\n$_TARGETNAME arm7_9 fast_memory_access enable\n\n# remap:  ram at 0, flash at 0x40000000, like reset-init above does\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\nflash bank onboard.flash cfi 0x40000000 0x00100000 2 2 at91sam7a2.cpu\n\n# boot: ram at 0x300000, flash at 0x0, useful if board is in funny configuration\n#$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n#flash bank onboard1.flash cfi 0x00000000 0x00100000 2 2 at91sam7a2.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_sam9_l9260.cfg",
    "content": "################################################################################\n# Olimex SAM9-L9260 Development Board\n#\n# http://www.olimex.com/dev/sam9-L9260.html\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     PMC configured for external 18.432 MHz crystal\n#\n# 32-bit SDRAM : 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks\n# 8-bit NAND Flash : 1 x Samsung K9F4G08U0M, 512M x 8Bit\n# Dataflash : 1 x Atmel AT45DB161D, 16Mbit\n#\n################################################################################\n\nsource [find target/at91sam9260.cfg]\n\n# NTRST_E jumper is enabled by default, so we don't need to override the reset\n# config.\n#reset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n\t# At reset, CPU runs at 32.768 kHz.  JTAG frequency must be 6 times slower if\n\t# RCLK is not supported.\n\tjtag_rclk 5\n\thalt\n\n\t# RSTC_MR : enable user reset, reset length is 64 slow clock cycles.  MMU may\n\t# be enabled... use physical address.\n\tmww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog\n\n\t##\n\t# Clock configuration for 99.328 MHz main clock.\n\t##\n    echo \"Setting up clock\"\n\tmww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable main oscillator, 512 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 15.6 ms for startup)\n\tmww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator (18.432 MHz)\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR : 18.432 MHz / 9 * 97 = 198.656 MHz, 63 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 1.9 ms for startup)\n\tmww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz)\n\n\t# Increase JTAG speed to 6 MHz if RCLK is not supported.\n\tjtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable ;# Enable faster DCC downloads.\n\n\t##\n\t# SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks.\n\t##\n    echo \"Configuring SDRAM\"\n\tmww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips\n\n\tmww 0xffffea00 0x1        ;# SDRAMC_MR : issue NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2        ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4        ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3        ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0        ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\n\tmww 0xffffea04 0x2b6      ;# SDRAMC_TR : set refresh timer count to 7 us\n\n    ##\n    # NAND Flash Configuration for 1 x Samsung K9F4G08U0M, 512M x 8Bit.\n    ##\n    echo \"Configuring NAND flash\"\n    mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock\n    mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n    mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14\n    mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13\n    mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND\n    mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13\n\n    mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before\n\n    mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE\n    mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals\n    mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle\n    mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n                               #             3 TDF cycles, no optimization\n\n    mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers\n    mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n    nand probe at91sam9260.flash\n\n    ##\n    # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit\n    ##\n    echo \"Setting up dataflash\"\n    mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI),\n                               #            2(SPI0_SPCK), and 11(SPI0_NPCS1)\n    mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2\n    mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11\n    mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock\n\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure\n    mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected\n\n    mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud,\n                               #             250ns delay before SPCK, 250ns b/n tx\n\n    mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1\n    mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0\n}\n\nnand device at91sam9260.flash at91sam9 at91sam9260.cpu 0x40000000 0xffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_stm32_h103.cfg",
    "content": "# Olimex STM32-H103 eval board\n# http://olimex.com/dev/stm32-h103.html\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_stm32_h107.cfg",
    "content": "#\n# Olimex STM32-H107\n#\n# http://olimex.com/dev/stm32-h107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_stm32_h405.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Olimex STM32-H405 eval board\n# https://www.olimex.com/Products/ARM/ST/STM32-H405/\n\n# Work-area size (RAM size) = 128kB for STM32F405RG device\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/olimex_stm32_p107.cfg",
    "content": "#\n# Olimex STM32-P107\n#\n# http://olimex.com/dev/stm32-p107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/omap2420_h4.cfg",
    "content": "# OMAP2420 SDP board (\"H4\")\n\nsource [find target/omap2420.cfg]\n\n# NOTE: this assumes you're *NOT* using a TI-14 connector.\nreset_config trst_and_srst separate\n\n# Board configs can vary a *LOT* ... parts, jumpers, etc.\n# This GP board boots from cs0 using NOR (2x32M), and also\n# has 64M NAND on cs6.\nflash bank h4.u10 cfi 0x04000000 0x02000000 2 2 $_TARGETNAME\nflash bank h4.u11 cfi 0x06000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/openrd.cfg",
    "content": "# Marvell OpenRD\n\nsource [find interface/ftdi/openrd.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc openrd_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x37543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000A33 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000004 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x00120012 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000E40F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc openrd_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\topenrd_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc openrd_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\topenrd_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/or1k_generic.cfg",
    "content": "# If you want to use the VJTAG TAP or the XILINX BSCAN,\n# you must set your FPGA TAP ID here\n\nset FPGATAPID 0x020b30dd\n\n# Choose your TAP core (VJTAG , MOHOR or XILINX_BSCAN)\nif { [info exists TAP_TYPE] == 0} {\n   set TAP_TYPE VJTAG\n}\n\n# Set your chip name\nset CHIPNAME or1200\n\nsource [find target/or1k.cfg]\n\n# Set the servers polling period to 1ms (needed to JSP Server)\npoll_period 1\n\n# Set the adapter speed\nadapter speed 3000\n\n# Enable the target description feature\ngdb_target_description enable\n\n# Add a new register in the cpu register list. This register will be\n# included in the generated target descriptor file.\n# format is addreg [name] [address] [feature] [reg_group]\naddreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n# Override default init_reset\nproc init_reset {mode} {\n\tsoft_reset_halt\n\tresume\n}\n\n# Target initialization\ninit\necho \"Halting processor\"\nhalt\n\nforeach name [target names] {\n\tset y [$name cget -endian]\n\tset z [$name cget -type]\n\tputs [format \"Chip is %s, Endian: %s, type: %s\" \\\n\t      $name $y $z]\n}\n\nset c_blue  \"\\033\\[01;34m\"\nset c_reset \"\\033\\[0m\"\n\nputs [format \"%sTarget ready...%s\" $c_blue $c_reset]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/osk5912.cfg",
    "content": "# http://omap.spectrumdigital.com/osk5912/\n\nsource [find target/omap5912.cfg]\n\n# NOTE: this assumes you're using the ARM 20-pin (\"Multi-ICE\")\n# JTAG connector, and accordingly have J1 connecting pins 1 & 2.\n# The TI-14 pin needs \"trst_only\", and J1 connecting 2 & 3.\nreset_config trst_and_srst separate\n\n# NOTE:  boards with XOMAP parts wire nSRST to nPWRON_RESET.\n# That resets everything -- including JTAG and EmbeddedICE.\n# So they must use \"reset_config srst_pulls_trst\".\n\n# NOTE:  an expansion board could add a trace connector ... if\n# it does, change this appropriately.  And reset_config too,\n# assuming JTAG_DIS reroutes JTAG to that connector.\netm config $_TARGETNAME 8 demultiplexed full dummy\netm_dummy config $_TARGETNAME\n\n# standard boards populate two 16 MB chips, but manufacturing\n# options or an expansion board could change this config.\nflash bank osk.u1 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\nflash bank osk.u2 cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\nproc osk5912_init {} {\n\tomap5912_reset\n\n\t# detect flash\n\tflash probe 0\n\tflash probe 1\n}\n$_TARGETNAME configure -event reset-init { osk5912_init }\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/phone_se_j100i.cfg",
    "content": "#\n# Sony Ericsson J100I Phone\n#\n# more information can be found on\n# http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i\n#\nsource [find target/ti_calypso.cfg]\n\n# external flash\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/phytec_lpc3250.cfg",
    "content": "source [find target/lpc3250.cfg]\n\nadapter srst delay 200\njtag_ntrst_delay 1\nadapter speed 200\nreset_config trst_and_srst separate\n\narm7_9 dcc_downloads enable\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n\n$_TARGETNAME configure -event reset-start {\n             arm7_9 fast_memory_access disable\n             adapter speed 200\n}\n\n$_TARGETNAME configure -event reset-end {\n             adapter speed 6000\n             arm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-init { phytec_lpc3250_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc phytec_lpc3250_init { } {\n        # Set clock dividers\n        #   ARMCLK = 266.5 MHz\n        #   HCLK   = 133.25 MHz\n        #   PERIPHCLK = 13.325 MHz\n        mww 0x400040BC 0\n        mww 0x40004050 0x140\n        mww 0x40004040 0x4D\n        mww 0x40004058 0x16250\n\n        # Init PLLs\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004044 0x106\n        sleep 1 busy\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004048 0x2\n\n        # Init SDRAM with 133 MHz timings\n        mww 0x40028134 0x00FFFFFF\n        mww 0x4002802C 0x00000008\n\n        mww 0x31080000 1\n        mww 0x31080008 0\n        mww 0x40004068 0x1C000\n        mww 0x31080028 0x11\n\n        mww 0x31080400 0\n        mww 0x31080440 0\n        mww 0x31080460 0\n        mww 0x31080480 0\n\n        # Delays\n        mww 0x31080030 1\n        mww 0x31080034 6\n        mww 0x31080038 10\n        mww 0x31080044 1\n        mww 0x31080048 9\n        mww 0x3108004C 12\n        mww 0x31080050 10\n        mww 0x31080054 1\n        mww 0x31080058 1\n        mww 0x3108005C 0\n\n        mww 0x31080100 0x5680\n        mww 0x31080104 0x302\n\n        # Init sequence\n        mww 0x31080020 0x193\n        sleep 1 busy\n        mww 0x31080024 1\n        mww 0x31080020 0x113\n        sleep 1 busy\n        mww 0x31080020 0x013\n        sleep 1 busy\n        mww 0x31080024 65\n        mww 0x31080020 0x093\n        mdw 0x80020000\n        mww 0x31080020 0x013\n\n        # SYS_CTRL remapping\n        mww 0x40004014 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/pic-p32mx.cfg",
    "content": "# The Olimex PIC-P32MX has a PIC32MX\n\nset CPUTAPID 0x40916053\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/pico-debug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# pico-debug is a virtual CMSIS-DAP debug adapter\n# it runs on the very same RP2040 target being debugged without additional hardware\n# https://github.com/majbthrd/pico-debug\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 4000\n\nset CHIPNAME rp2040\nsource [find target/rp2040-core0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n\nsource [find interface/ftdi/pipistrello.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/pipistrello.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx45.bit;\\\n# jtagspi_program bitstream-pistrello.bin 0;\\\n# jtagspi_program bios.bin 0x170000;\\\n# jtagspi_program runtime.fbi 0x180000;\\\n# xc6s_program xc6s.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/propox_mmnet1001.cfg",
    "content": "\n## Chip:\nset CHIPNAME at91sam9260\nset CPUTAPID 0x0792603f\nset ENDIAN little\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n\nproc at91sam_init { } {\n\n\t# at reset chip runs at 32 kHz => 1/8 * 32 kHz = 4 kHz\n\tjtag_rclk 4\n\n\t# Enable user reset and disable watchdog\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\t# Oscillator setup\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator (18.432 MHz)\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 18.432 MHz kHz => 1/8 * 18.432 MHz = 2.304 MHz\n\tjtag_rclk 2000\n\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc2c 0x207c3f0c         ;# CKGR_PLLBR: Set PLLB Register for USB usage (USB_CLK = 48 MHz)\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 198.656 MHz kHz => full speed jtag\n\tjtag_rclk 30000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\t# Configure PIO Controller for SDRAM data-lines D16-D31\n\t# PC16-PC31 = Peripheral A: D16-D32\n\tmww 0xfffff844 0xffff0000\t;# Interrupt Disable\n\tmww 0xfffff854 0xffff0000\t;# Multi-Drive Disable\n\tmww 0xfffff860 0xffff0000\t;# Pull-Up Disable\n\tmww 0xfffff870 0xffff0000\t;# PIO_ASR : Select peripheral A function for D15..D31\n\tmww 0xfffff804 0xffff0000\t;# PIO_PDR : Disable PIO function for D15..D31 (Peripheral function enable)\n\tmww 0xfffffc10 0x00000010\t;# Enable PIO-C Clock in PMC (PID=4)\n\n\t# SD-Ram setup\n\tmww 0xffffef1c 0x2\t\t\t;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\tmww 0xffffea08 0x85227259\t;# SDRAMC_CR : Configure SDRAM (IS42S32160A: 4M Words x 32 Bits x 4 Banks (512-Mbit))\n\tmww 0xffffea00 0x1\t\t\t;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2\t\t\t;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (1st)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (2nd)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (3th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (4th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (5th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (6th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (7th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (8th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3\t\t\t;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0\t\t\t;# SDRAMC_MR : Normal Mode\n\tmww 0x20000000 0\n\tmww 0xFFFFEA04 0x30d\t\t;# SDRAM Refresh Time Register\n\t\t\t\t\t\t\t\t #  datasheet: 8k refresh cycles / 64 ms\n\t\t\t\t\t\t\t\t #  MCLK / (8*1024 / 64e-3) = 100e6 / 128000 = 781 = 0x30d\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/pxa255_sst.cfg",
    "content": "# A PXA255 test board with SST 39LF400A flash\n#\n# At reset the memory map is as follows. Note that\n# the memory map changes later on as the application\n# starts...\n#\n# RAM at 0x4000000\n# Flash at 0x00000000\n#\nsource [find target/pxa255.cfg]\n\n# Target name is set by above\n$_TARGETNAME configure -work-area-phys 0x4000000 -work-area-size 0x4000 -work-area-backup 0\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width> <target> [options]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x80000 2 2 $_TARGETNAME jedec_probe\n\nproc pxa255_sst_init {} {\n\txscale cp15   15      0x00002001  ;#Enable CP0 and CP13 access\n\t#\n\t# setup GPIO\n\t#\n\tmww    0x40E00018  0x00008000  ;#CPSR0\n\tsleep   20\n\tmww    0x40E0001C  0x00000002  ;#GPSR1\n\tsleep   20\n\tmww    0x40E00020  0x00000008  ;#GPSR2\n\tsleep   20\n\tmww    0x40E0000C  0x00008000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00054  0x80000000  ;#GAFR0_L\n\tsleep   20\n\tmww    0x40E00058  0x00188010  ;#GAFR0_H\n\tsleep   20\n\tmww    0x40E0005C  0x60908018  ;#GAFR1_L\n\tsleep   20\n\tmww    0x40E0000C  0x0280E000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00010  0x821C88B2  ;#GPDR1\n\tsleep   20\n\tmww    0x40E00014  0x000F03DB  ;#GPDR2\n\tsleep   20\n\tmww    0x40E00000  0x000F03DB  ;#GPLR0\n\tsleep   20\n\n\n\tmww    0x40F00004  0x00000020  ;#PSSR\n\tsleep   20\n\n\t#\n\t# setup memory controller\n\t#\n\tmww    0x48000008  0x01111998  ;#MSC0\n\tsleep   20\n\tmww    0x48000010  0x00047ff0  ;#MSC2\n\tsleep   20\n\tmww    0x48000014  0x00000000  ;#MECR\n\tsleep   20\n\tmww    0x48000028  0x00010504  ;#MCMEM0\n\tsleep   20\n\tmww    0x4800002C  0x00010504  ;#MCMEM1\n\tsleep   20\n\tmww    0x48000030  0x00010504  ;#MCATT0\n\tsleep   20\n\tmww    0x48000034  0x00010504  ;#MCATT1\n\tsleep   20\n\tmww    0x48000038  0x00004715  ;#MCIO0\n\tsleep   20\n\tmww    0x4800003C  0x00004715  ;#MCIO1\n\tsleep   20\n\t#\n\tmww    0x48000004  0x03CA4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x004B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000BC018  ;#MDREF\n\tsleep   20\n\tmww    0x48000000  0x00001AC8  ;#MDCNFG\n\tsleep   20\n\n\tsleep   20\n\n\tmww    0x48000000  0x00001AC9  ;#MDCNFG\n\tsleep   20\n\tmww    0x48000040  0x00000000  ;#MDMRS\n\tsleep   20\n}\n\n$_TARGETNAME configure -event reset-init {pxa255_sst_init}\n\nreset_config trst_and_srst\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n#xscale debug_handler 0  0xFFFF0800      ;# debug handler base address\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/quark_d2000_refboard.cfg",
    "content": "# Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582)\n\n# the board has an onboard FTDI FT232H chip\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\n\nftdi layout_init 0x0000 0x030b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0100\n\nsource [find target/quark_d20xx.cfg]\n\nadapter speed 1000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/quark_x10xx_board.cfg",
    "content": "# There are many Quark boards that can host the quark_x10xx SoC\n# Galileo is an example board\n\nsource [find target/quark_x10xx.cfg]\n\n#default frequency but this can be adjusted at runtime\nadapter speed 4000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/quicklogic_quickfeather.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3 QuickFeather\n# https://www.quicklogic.com/products/eos-s3/quickfeather-development-kit/\n\nsource [find target/eos_s3.cfg]\n\nreset_config srst_only\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Radiona ULX3S\n# https://radiona.org/ulx3s/\n# Currently there are following board variants:\n# CS-ULX3S-01 - LFE5U 12F\n# CS-ULX3S-02 - LFE5U 45F\n# CS-ULX3S-03 - LFE5U 85F\n#\n# two JTAG interfaces:\n# - US1, micro USB port connected to FT231XQ\n#   This interface should be used with following config:\n#        interface/ft232r/radiona_ulx3s.cfg\n# - J4, 6 pin connector\n#\n# Both of this interfaces share the JTAG lines (TDI, TMS, TCK, TDO) between\n# Lattice ECP5 FPGA chip and ESP32 WiFi controller.\n# Note: TRST_N of the ESP32 is pulled up by default and can be pulled down over\n# J3 interface.\n# See schematics for more information:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v308.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v314.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v315.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nsource [find interface/ft232r/radiona_ulx3s.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/redbee.cfg",
    "content": "source [find target/mc13224v.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/reflexces_achilles_i-dev_kit_arria10.cfg",
    "content": "# Achilles Instant-Development Kit Arria 10 SoC SoM\n# https://www.reflexces.com/products-solutions/achilles-instant-development-kit-arria-10-soc-som\n#\n\nif { [info exists USE_EXTERNAL_DEBUGGER] } {\n\techo \"Using external debugger\"\n} else {\n\tsource [find interface/altera-usb-blaster2.cfg]\n\tusb_blaster device_desc \"Arria10 IDK\"\n}\n\nsource [find fpga/altera-10m50.cfg]\nsource [find target/altera_fpgasoc_arria10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_dk-s7g2.cfg",
    "content": "#\n# Renesas Synergy DK-S7G2\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# XXX 19-pin SWD+TRACE connector also available\n\n# Synergy R7FS7G27H2A01CBD\nsource [find target/renesas_s7g2.cfg]\n\n# 32 MB QSPI flash (Micron N25Q256A13EF840E)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_falcon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Renesas R-Car V3U Falcon Board Config\n\n# The Falcon board comes with either an V3U SOC.\n\necho \"\\nFalcon:\"\nif { ![info exists SOC] } {\n\tset SOC V3U\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_gr_peach.cfg",
    "content": "# Renesas RZ/A1H GR-Peach board\n\nreset_config srst_only\n\nsource [find target/renesas_r7s72100.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_porter.cfg",
    "content": "# Renesas R-Car M2 Evaluation Board\n\nset SOC M2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_salvator-xs.cfg",
    "content": "# Renesas R-Car Gen3 Salvator-X(S) Board Config\n\n# The Salvator-X(S) boards come with either an H3, M3W, or M3N SOC.\n\necho \"\\nSalvator-X(S):\"\nif { ![info exists SOC] } {\n\tset SOC H3\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_silk.cfg",
    "content": "# Renesas R-Car E2 Evaluation Board\n\nset SOC E2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/renesas_stout.cfg",
    "content": "# Renesas R-Car H2 Evaluation Board\n\nset SOC H2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/rigado_bmd300_ek.cfg",
    "content": "#\n# Rigado BMD-300 Evaluation Kit\n#\n# https://www.rigado.com/products/modules/bmd-300/\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/rpi3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 3 board with BCM2837 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2837.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/rpi4b.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 4 model B board with BCM2711 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2711.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/rsc-w910.cfg",
    "content": "# Avalue RSC-W8910 sbc\n# http://www.avalue.com.tw/products/RSC-W910.cfm\n# 2MB NOR Flash\n# 64MB SDRAM\n# 128MB NAND Flash\n\n# Based on Nuvoton nuc910\nsource [find target/nuc910.cfg]\n\n#\n# reset only behaves correctly if we use srst_pulls_trst\n#\nreset_config trst_and_srst srst_pulls_trst\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME nuc910 $_TARGETNAME\n\n#\n# Target events\n#\n\n$_TARGETNAME configure -event reset-start {adapter speed 1000}\n\n$_TARGETNAME configure -event reset-init {\n\t# switch on PLL for 200MHz operation\n\t# running from 15MHz input clock\n\n\tmww 0xB0000200 0x00000030 ;# CLKEN\n\tmww 0xB0000204 0x00000f3c ;# CLKSEL\n\tmww 0xB0000208 0x05007000 ;# CLKDIV\n\tmww 0xB000020C 0x00004f24 ;# PLLCON0\n\tmww 0xB0000210 0x00002b63 ;# PLLCON1\n\tmww 0xB000000C 0x08817fa6 ;# MFSEL\n\tsleep 10\n\n\t# we are now running @ 200MHz\n\t# enable all openocd speed tweaks\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\tadapter speed 15000\n\n\t# map nor flash to 0x20000000\n\t# map sdram to 0x00000000\n\n\tmww 0xb0001000 0x000530c1 ;# EBICON\n\tmww 0xb0001004 0x40030084 ;# ROMCON\n\tmww 0xb0001008 0x000010ee ;# SDCONF0\n\tmww 0xb000100C 0x00000000 ;# SDCONF1\n\tmww 0xb0001010 0x0000015b ;# SDTIME0\n\tmww 0xb0001014 0x0000015b ;# SDTIME1\n\tmww 0xb0001018 0x00000000 ;# EXT0CON\n\tmww 0xb000101C 0x00000000 ;# EXT1CON\n\tmww 0xb0001020 0x00000000 ;# EXT2CON\n\tmww 0xb0001024 0x00000000 ;# EXT3CON\n\tmww 0xb000102c 0x00ff0048 ;# CKSKEW\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sayma_amc.cfg",
    "content": "# Sayma AMC is an FPGA board for the µTCA AMC format\n# The board is open hardware (CERN OHL) and the gateware and software\n# running on it are open source (ARTIQ, LGPLv3+).\n#\n# https://github.com/m-labs/sinara/wiki/Sayma\n#\n# It contains a Xilinx Kintex Ultrascale 040 FPGA (xcku040).\n# There is a SCANSTA112SM JTAG router on the board which is configured to\n# automatically add devices to the JTAG svcan chain when they are added.\n# Sayma AMC is usually combined with Sayma RTM (rear transition module)\n# which features an Artix 7 FPGA.\n\nadapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n# Use this to distinguish multiple boards by topology\n#adapter usb location 5:1\n# sampling on falling edge generally seems to work and accelerates things but\n# is not fully tested\n#ftdi tdo_sample_edge falling\n# EN_USB_JTAG on ADBUS7: out, high\n# USB_nTRST on ADBUS4: out, high, but R46 is DNP\nftdi layout_init 0x0098 0x008b\n#ftdi layout_signal EN_USB -data 0x0080\n#ftdi layout_signal nTRST -data 0x0010\nreset_config none\n\nadapter speed 5000\n\ntransport select jtag\n\n# Add the RTM Artix to the chain. Note that this changes the PLD numbering.\n# Unfortunately openocd TAPs can't be disabled after they have been added and\n# before `init`.\n#source [find cpld/xilinx-xc7.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nset XILINX_USER1 0x02\nset XILINX_USER2 0x03\nset JTAGSPI_IR $XILINX_USER1\nsource [find cpld/jtagspi.cfg]\nflash bank xcu.spi1 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER2\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sheevaplug.cfg",
    "content": "# Marvell SheevaPlug\n\nsource [find interface/ftdi/sheevaplug.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc sheevaplug_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x39543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000833 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000042 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x003C0000 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000F80F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc sheevaplug_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_reflash_uboot_env { } {\n\n\t# reflash the u-Boot environment variables area\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0xa0000 0x40000\n\tnand write 0 uboot-env.bin 0xa0000 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\tsheevaplug_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sifive-e31arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e31arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sifive-e51arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e51arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sifive-hifive1-revb.cfg",
    "content": "adapter speed 4000\n\nadapter driver jlink\ntransport select jtag\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 0\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME.0\n\ninit\n\njlink jtag 3\n\nhalt\nflash protect 0 1 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/sifive-hifive1.cfg",
    "content": "adapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nSRST -oe 0x0020 -data 0x0020\n\n#Reset Stretcher logic on FE310 is ~1 second long\n#This doesn't apply if you use\n# ftdi set_signal, but still good to document\n#adapter srst delay 1500\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME\ninit\n#reset -- This type of reset is not implemented yet\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n  #Wait for the reset stretcher\n  #It will work without this, but\n  #will incur lots of delays for later commands.\n  sleep 1500\n}\nhalt\nflash protect 0 64 last off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/smdk6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x00100000 2 2 $_TARGETNAME jedec_probe\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/snps_em_sk.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.x\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# 5MHz seems to work good with all cores that might happen in 2.x\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/snps_em_sk_v1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v1.0 and v1.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\nadapter speed 10000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/snps_em_sk_v2.1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency\n# 20MHz. 7.5 MHz seems to work fine.\nadapter speed 7500\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/snps_em_sk_v2.2.cfg",
    "content": "#  Copyright (C) 2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.2\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# EM11D reportedly requires 5 MHz. Other cores and board can work faster.\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC HSDK Software Development Platform (HS38 cores)\n#\n\nsource [find interface/ftdi/snps_sdp.cfg]\nadapter speed 10000\n\n# ARCs supports only JTAG.\ntransport select jtag\n\n# Configure SoC\nsource [find target/snps_hsdk.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spansion_sk-fm4-176l-s6e2cc.cfg",
    "content": "#\n# Spansion SK-FM4-176L-S6E2CC\n#\n\n#\n# FM3 MB9AF312K\n#\nsource [find interface/cmsis-dap.cfg]\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\n#\n# FM4 S6E2CCAJ0A w/ 192 KB SRAM0\n#\nset CHIPNAME s6e2cc\nset CHIPSERIES S6E2CCAJ0A\nset WORKAREASIZE 0x30000\nsource [find target/fm4_s6e2cc.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spansion_sk-fm4-u120-9b560.cfg",
    "content": "#\n# Spansion SK-FM4-U120-9B560\n#\n\n#\n# FM3 MB9AF312K\n#\n# source [find interface/cmsis-dap.cfg]\n\n#\n# FM4 MB9BF568R w/ 64 KB SRAM0\n#\nset CHIPNAME mb9bf568\nset CHIPSERIES MB9BF568R\nset WORKAREASIZE 0x10000\nsource [find target/fm4_mb9bf.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear300evb.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0\n# http://www.st.com/spear\n#\n# Date:      2010-11-27\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear300evb_init }\n\nproc spear300evb_init {} {\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp300_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear300evb_mod.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the top layer:\n#    1. replace reset chip U4 with a STM6315SDW13F;\n# - Modifications on the bottom layer:\n#    2. add 0 ohm resistor R10. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 and solder it between R10 and R54:\n# - one pad soldered with the pad of R54 connected to 3.3V (this\n#   is the pad of R54 far from JTAG connector J4)\n# - the other pad soldered with the nearest pad of R10.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear300evb.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear310evb20.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n#\n# Check ST Application Note AN3321 on how to fix SRST on\n# the board, then use the script board/spear310evb20_mod.cfg\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n# CFI parallel NOR on EMI CS0. 2x 16bit 8M devices = 16Mbyte.\nset _FLASHNAME0 $_CHIPNAME.pnor\nflash bank $_FLASHNAME0 cfi 0x50000000 0x01000000 2 4 $_TARGETNAME\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear310evb20_init }\n\nproc spear310evb20_init {} {\n\treg pc 0xffff0020\t;# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp310_init\n\tsp310_emi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear310evb20_mod.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note AN3321.\n# - Modifications on the top layer:\n#    1. remove R137 and C57, located near the SMII PHY U18;\n#    2. remove R172 and C75, located near the SMII PHY U19;\n#    3. remove R207 and C90, located near the SMII PHY U20;\n#    4. remove C236, located near the SMII PHY U21;\n#    5. remove U12, located near the JTAG connector;\n#    6. solder together pins 7, 8 and 9 of U12;\n#    7. solder together pins 11, 12, 13, 14, 15, 16, 17 and 18 of U12.\n# - Modifications on the bottom layer:\n#    8. replace reset chip U11 with a STM6315SDW13F;\n#    9. add 0 ohm resistor R329. It is located close to JTAG connector.\n#\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear310evb20.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear320cpu.cfg",
    "content": "# Configuration for the ST SPEAr320 CPU board\n# EVAL_SPEAr320CPU Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear320cpu_init }\n\nif { [info exists DDR_CHIPS] } {\n        set _DDR_CHIPS $DDR_CHIPS\n} else {\n        set _DDR_CHIPS 1\n}\n\nproc spear320cpu_init {} {\n\tglobal _DDR_CHIPS\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\" $_DDR_CHIPS\n\tsp320_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/spear320cpu_mod.cfg",
    "content": "# Configuration for the ST SPEAr320 Evaluation board\n# EVAL_SPEAr320CPU Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the bottom layer:\n#    1. replace reset chip U7 with a STM6315SDW13F;\n#    2. add 0 ohm resistor R45. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 or 0402 and solder it between R15 and R45:\n# - one pad soldered with the pad of R15 connected to 3.3V (this\n#   is the pad of R15 closer to R45)\n# - the other pad soldered with the nearest pad of R45.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear320cpu.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_b-l475e-iot01a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an B-L475E-IOT01A Discovery kit for IoT node with a single STM32L475VGT6 chip.\n# http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000\t;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_8l152r8.cfg",
    "content": "# This is a ST NUCLEO 8L152R8 board with a single STM8L152R8T6 chip.\n# http://www.st.com/en/evaluation-tools/nucleo-8l152r8.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\nsource [find target/stm8l152.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_8s208rb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a ST NUCLEO 8S208RB board with a single STM8S208RBT6 chip.\n# https://www.st.com/en/evaluation-tools/nucleo-8s208rb.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\n# 128 KiB flash and 2 KiB EEPROM\nset FLASHEND 0x27fff\nset EEPROMEND 0x47ff\n\nsource [find target/stm8s.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_f0.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F0. Known boards at the moment:\n# STM32F030R8\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# NUCLEO-F072RB\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# STM32F091RC\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260944\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_f103rb.cfg",
    "content": "# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_f3.cfg",
    "content": "# This is an ST NUCLEO F334R8 board with a single STM32F334R8T6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260004\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_f4.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:\n# STM32F401RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000\n# STM32F411RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_f7.cfg",
    "content": "# STMicroelectronics STM32F7 Nucleo development board\n# Known boards: NUCLEO-F746ZG and NUCLEO-F767ZI\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_g0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G0. Known boards at the moment:\n# NUCLEO-G031K8\n# https://www.st.com/en/evaluation-tools/nucleo-g031k8.html\n# NUCLEO-G070RB\n# https://www.st.com/en/evaluation-tools/nucleo-g070rb.html\n# NUCLEO-G071RB\n# https://www.st.com/en/evaluation-tools/nucleo-g071rb.html\n# NUCLEO-G0B1RE\n# https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_g4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G4. Known boards at the moment:\n# NUCLEO-G431KB\n# https://www.st.com/en/evaluation-tools/nucleo-g431kb.html\n# NUCLEO-G431RB\n# https://www.st.com/en/evaluation-tools/nucleo-g431rb.html\n# NUCLEO-G474RE\n# https://www.st.com/en/evaluation-tools/nucleo-g474re.html\n# NUCLEO-G491RE\n# https://www.st.com/en/evaluation-tools/nucleo-g491re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_h743zi.cfg",
    "content": "# This is an ST NUCLEO-H743ZI board with single STM32H743ZI chip.\n# http://www.st.com/en/evaluation-tools/nucleo-h743zi.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_h745zi.cfg",
    "content": "# This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip.\n\nsource [find interface/stlink-dap.cfg]\ntransport select dapdirect_swd\n\n# STM32H745xx devices are dual core (Cortex-M7 and Cortex-M4)\nset DUAL_CORE 1\n\n# enable CTI for cross halting both cores\nset USE_CTI 1\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_l073rz.cfg",
    "content": "# This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip.\n# http://www.st.com/en/evaluation-tools/nucleo-l073rz.html\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32l0_dual_bank.cfg]\n\n# There is only system reset line and JTAG/SWD command can be issued when SRST\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_l1.cfg",
    "content": "# This is an ST NUCLEO L152RE board with a single STM32L152RET6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l1x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_l4.cfg",
    "content": "# Should work with all STM32L4 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_l5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for STM32L5 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32l5x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/st_nucleo_wb55.cfg",
    "content": "#\n# Configuration for STM32WB55 Nucleo board (STM32WB55RGV6)\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32wbx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/steval-idb007v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-1 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb008v1.html\nset CHIPNAME bluenrg-1\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/steval-idb008v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-2 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb007v1.html\nset CHIPNAME bluenrg-2\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/steval-idb011v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-LP chip.\nset CHIPNAME bluenrg-lp\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/steval-idb012v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later.\n# This is an evaluation board with a single BlueNRG-LPS chip.\nset CHIPNAME bluenrg-lps\nsource [find interface/cmsis-dap.cfg]\nsource [find target/bluenrg-x.cfg]"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/steval_pcc010.cfg",
    "content": "# Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram\n# coming with the STEVAL-PCC010 board\n# http://www.st.com/internet/evalboard/product/251530.jsp\n# or any other board with only a STM32F2x in the JTAG chain\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm320518_eval.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm320518_eval_stlink.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32100b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F100VBT6 chip.\n# http://www.st.com/internet/evalboard/product/247099.jsp\n\n# The chip has only 8KB sram\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3210b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F10x (128KB) chip.\n# http://www.st.com/internet/evalboard/product/176090.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3210c_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F107VCT chip.\n# http://www.st.com/internet/evalboard/product/217965.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3210e_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F103ZET6 chip.\n# http://www.st.com/internet/evalboard/product/204176.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n\n#\n# configure FSMC Bank 1 (NOR/PSRAM Bank 2) NOR flash\n# M29W128GL70ZA6E\n#\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME\n\nproc stm32_enable_fsmc {} {\n\n\techo \"Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)\"\n\n\t# enable gpio (defg) clocks for fsmc\n\t# RCC_APB2ENR\n\tmww 0x40021018 0x000001E0\n\n\t# enable fsmc clock\n\t# RCC_AHBENR\n\tmww 0x40021014 0x00000114\n\n\t# configure gpio to alternate function\n\t# GPIOD_CRL\n\tmww 0x40011400 0x44BB44BB\n\t# GPIOD_CRH\n\tmww 0x40011404 0xBBBBBBBB\n\n\t# GPIOE_CRL\n\tmww 0x40011800 0xBBBBB444\n\t# GPIOE_CRH\n\tmww 0x40011804 0xBBBBBBBB\n\n\t# GPIOF_CRL\n\tmww 0x40011C00 0x44BBBBBB\n\t# GPIOF_CRH\n\tmww 0x40011C04 0xBBBB4444\n\n\t# GPIOG_CRL\n\tmww 0x40012000 0x44BBBBBB\n\t# GPIOG_CRH\n\tmww 0x40012004 0x444444B4\n\n\t# setup fsmc timings\n\t# FSMC_BCR1\n\tmww 0xA0000008 0x00001058\n\n\t# FSMC_BTR1\n\tmww 0xA000000C 0x10000502\n\n\t# FSMC_BCR1 - enable fsmc\n\tmww 0xA0000008 0x00001059\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32_enable_fsmc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3220g_eval.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3220g_eval_stlink.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3241g_eval.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm3241g_eval_stlink.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32429i_eval.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32429i_eval_stlink.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32439i_eval.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32439i_eval_stlink.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm327x6g_eval.cfg",
    "content": "# STM327[4|5]6G-EVAL: This is for the STM32F7 eval boards.\n# STM32746G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261639\n# STM32756G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f0discovery.cfg",
    "content": "# This is an STM32F0 discovery board with a single STM32F051R8T6 chip.\n# http://www.st.com/internet/evalboard/product/253215.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f103c8_blue_pill.cfg",
    "content": "# STM32F103C8 \"Blue Pill\"\n\n# NOTE:\n# There is a fair bit of confusion about whether the \"Blue Pill\" has 128kB or 64kB flash size.\n# The most likely cause is that there exist a -C8 and a -CB variant of the STM32F103, where\n# the C8 has 64kB, the CB has 128kB as per specification. \"Blue Pill\" boards are manufactured\n# by a lot of different vendors, some may actually use the CB variant but from a cursory look\n# it very hard to tell them apart (\"C8\" and \"CB\" look very similar). Nevertheless, people have\n# tried using the full 128kB of flash on the C8 and found it to be working. Hence this board file\n# overrides the internal size detection. Be aware though that you may be using you particular\n# board outside of its specification. If in doubt, comment the following line.\nset FLASH_SIZE 0x20000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f334discovery.cfg",
    "content": "# This is an STM32F334 discovery board with a single STM32F334C8T6 chip.\n# As it is one of the few boards with stlink V.2-1, we source the corresponding\n# nucleo file.\n# http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260318\n\nsource [find board/st_nucleo_f3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f3discovery.cfg",
    "content": "# This is an STM32F3 discovery board with a single STM32F303VCT6 chip.\n# http://www.st.com/internet/evalboard/product/254044.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f412g-disco.cfg",
    "content": "# This is an STM32F412G discovery board with a single STM32F412ZGT6 chip.\n# http://www.st.com/en/evaluation-tools/32f412gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PG06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x000AA000 0x00055000\t;# MODER\n\tmmw 0x40021408 0x000FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f413h-disco.cfg",
    "content": "# This is an STM32F413H discovery board with a single STM32F413ZHT6 chip.\n# http://www.st.com/en/evaluation-tools/32f413hdiscovery.html\n\n#\n# Untested!!!\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PD13: BK1_IO3, PE02: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PF09:AF10:V, PF08:AF10:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V\n\tmmw 0x40021400 0x000A0000 0x00050000\t;# MODER\n\tmmw 0x40021408 0x000F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f429disc1.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f429discovery.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f469discovery.cfg",
    "content": "#\n# This is an STM32F469 discovery board with a single STM32F469NI chip.\n# http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f469i-disco.cfg",
    "content": "# This is an STM32F469I discovery board with a single STM32F469NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f469idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PF10: CLK, PB06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB06:AF10:V, PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\n\t# Port B: PB06:AF10:V\n\tmmw 0x40020400 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40020408 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000000 0x05000000\t;# AFRL\n\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x002AA000 0x00155000\t;# MODER\n\tmmw 0x40021408 0x003FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000009AA 0x00000655\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000005\t\t\t\t;# 5 WS for 160 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24002808\t\t\t\t;# 160 MHz: HSI, PLLM=8, PLLN=160, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f4discovery.cfg",
    "content": "# This is an STM32F4 discovery board with a single STM32F407VGT6 chip.\n# http://www.st.com/internet/evalboard/product/252419.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 64KB\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f723e-disco.cfg",
    "content": "# This is an STM32F723E discovery board with a single STM32F723IEK6 chip.\n# http://www.st.com/en/evaluation-tools/32f723ediscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f746g-disco.cfg",
    "content": "# This is an STM32F746G discovery board with a single STM32F746NGH6 chip.\n# http://www.st.com/en/evaluation-tools/32f746gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PD12: BK1_IO1, PD11: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V\n\tmmw 0x40020C00 0x0A800000 0x05400000\t;# MODER\n\tmmw 0x40020C08 0x0FC00000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00999000 0x00666000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f769i-disco.cfg",
    "content": "# This is an STM32F769I discovery board with a single STM32F769NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f769idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# exit qpi mode\n\tmww 0xA0001014 0x000033f5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\n\t# 1-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\n\t# 4-line qpi mode\n\tmww 0xA0001014 0x00003135\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=EQIO\n\n\t# 4-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0F283FEC\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0xA, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=4READ4B\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32f7discovery.cfg",
    "content": "# This is an STM32F7 discovery board with a single STM32F756NGH6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641\n\n# This is for using the onboard STLINK/V2-1\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h735g-disco.cfg",
    "content": "# This is a stm32h735g-dk with a single STM32H735IGK6 chip.\n# https://www.st.com/en/evaluation-tools/stm32h735g-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h735igk6\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000006FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PF10: OCSPI1_CLK, PB02: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PD05: OCSPI1_IO5,\n\t# PD04: OCSPI1_IO4, PD13: OCSPI1_IO3, PE02: OCSPI1_IO2, PD12: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF10:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V\n\t# PD04:AF10:V, PE02:AF09:V, PF10:AF09:V, PG09:AF09:V, PG06:AF10:V\n\t# Port B: PB02:AF10:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000A00 0x00000500\t;# AFRL\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x58020C00 0x0A808A00 0x05404500\t;# MODER\n\tmmw 0x58020C08 0x0FC0CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x0FC0CF00\t;# PUPDR\n\tmmw 0x58020C20 0xA0AA0000 0x50550000\t;# AFRL\n\tmmw 0x58020C24 0x00999000 0x00666000\t;# AFRH\n\t# Port E: PE02:AF09:V\n\tmmw 0x58021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802100C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58021020 0x00000900 0x00000600\t;# AFRL\n\t# Port F: PF10:AF09:V\n\tmmw 0x58021400 0x00200000 0x00100000\t;# MODER\n\tmmw 0x58021408 0x00300000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x00300000\t;# PUPDR\n\tmmw 0x58021424 0x00000900 0x00000600\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h745i-disco.cfg",
    "content": "# This is a stm32h745i-disco with a single STM32H745XIH6 chip.\n# www.st.com/en/product/stm32h745i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h745xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h747i-disco.cfg",
    "content": "# This is a stm32h747i-disco with a single STM32H747XIH6 chip.\n# www.st.com/en/product/stm32h747i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h747xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PB02:AF09:V, PD11:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h750b-disco.cfg",
    "content": "# This is a stm32h750b-dk with a single STM32H750XBH6 chip.\n# www.st.com/en/product/stm32h750b-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h750xbh6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h7b3i-disco.cfg",
    "content": "# This is a stm32h7b3i-dk with a single STM32H7B3LIH6Q chip.\n# https://www.st.com/en/evaluation-tools/stm32h7b3i-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h7b3lih6q\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PB02: OCSPI1_CLK, PC05: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PH03: OCSPI1_IO5,\n\t# PC01: OCSPI1_IO4, PF06: OCSPI1_IO3, PF07: OCSPI1_IO2, PF09: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF09:V, PC05:AF10:V, PC01:AF10:V, PD11:AF09:V, PD07:AF10:V, PF09:AF10:V\n\t# PF07:AF10:V, PF06:AF10:V, PG09:AF09:V, PG06:AF10:V, PH03:AF09:V\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port C: PC05:AF10:V, PC01:AF10:V\n\tmmw 0x58020800 0x00000808 0x00000404\t;# MODER\n\tmmw 0x58020808 0x00000C0C 0x00000000\t;# OSPEEDR\n\tmmw 0x5802080C 0x00000000 0x00000C0C\t;# PUPDR\n\tmmw 0x58020820 0x00A000A0 0x00500050\t;# AFRL\n\t# Port D: PD11:AF09:V, PD07:AF10:V\n\tmmw 0x58020C00 0x00808000 0x00404000\t;# MODER\n\tmmw 0x58020C08 0x00C0C000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x00C0C000\t;# PUPDR\n\tmmw 0x58020C20 0xA0000000 0x50000000\t;# AFRL\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF10:V, PF06:AF10:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x000CF000\t;# PUPDR\n\tmmw 0x58021420 0xAA000000 0x55000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\t# Port H: PH03:AF09:V\n\tmmw 0x58021C00 0x00000080 0x00000040\t;# MODER\n\tmmw 0x58021C08 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C0C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x58021C20 0x00009000 0x00006000\t;# AFRL\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h7x3i_eval.cfg",
    "content": "# STM32H7[4|5]3I-EVAL: this is for the H7 eval boards.\n# This is an ST EVAL-H743XI board with single STM32H743XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h743i-eval.html\n# This is an ST EVAL-H753XI board with single STM32H753XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h753i-eval.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32h7x_dual_qspi.cfg",
    "content": "# stm32h754i-disco and stm32h750b-dk dual quad qspi.\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PF10: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PD11:AF09:V, PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0028A000 0x00145000\t;# MODER\n\tmmw 0x58021408 0x003CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000009A0 0x00000650\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l0discovery.cfg",
    "content": "# This is an STM32L053 discovery board with a single STM32L053 chip.\n# http://www.st.com/web/en/catalog/tools/PF260319\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32l0.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l476g-disco.cfg",
    "content": "# This is an STM32L476G discovery board with a single STM32L476VGT6 chip.\n# http://www.st.com/en/evaluation-tools/32l476gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000    ;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000    ;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l496g-disco.cfg",
    "content": "# This is an STM32L496G discovery board with a single STM32L496AGI6 chip.\n# http://www.st.com/en/evaluation-tools/32l496gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB11: BK1_NCS, PA03: CLK, PA06: BK1_IO3, PA07: BK1_IO2, PB00: BK1_IO1, PB01: BK1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PA03:AF10:V, PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V, PA03:AF10:V\n\tmmw 0x48000000 0x0000A080 0x00005040    ;# MODER\n\tmmw 0x48000008 0x0000F0C0 0x00000000    ;# OSPEEDR\n\tmmw 0x48000020 0xAA00A000 0x55005000    ;# AFRL\n\n\t# Port B: PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\tmmw 0x48000400 0x0080000A 0x00400005    ;# MODER\n\tmmw 0x48000408 0x00C0000F 0x00000000    ;# OSPEEDR\n\tmmw 0x48000420 0x000000AA 0x00000055    ;# AFRL\n\tmmw 0x48000424 0x0000A000 0x00005000    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l4discovery.cfg",
    "content": "# Explicitly for the STM32L476 discovery board:\n# http://www.st.com/web/en/catalog/tools/PF261635\n# but perfectly functional for any other STM32L4 board connected via\n# an stlink-v2-1 interface.\n# This is for STM32L4 boards that are connected via stlink-v2-1.\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l4p5g-disco.cfg",
    "content": "# This is a STM32L4P5G discovery board with a single STM32L4R9AGI6 chip.\n# http://www.st.com/en/evaluation-tools/stm32l4p5g-dk.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x07050333\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI2\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PE11: P1_NCS, PE10: P1_CLK, PG06: P1_DQS, PD07: P1_IO7, PC03: P1_IO6, PD05: P1_IO5\n\t# PD04: P1_IO4, PA06: P1_IO3, PA07: P1_IO2, PE13: P1_IO1, PE11: P1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PC03:AF10:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\t# PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V, PG06:AF03:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V\n\tmmw 0x48000000 0x0000A000 0x00005000\t;# MODER\n\tmmw 0x48000008 0x0000F000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800000C 0x00000000 0x0000F000\t;# PUPDR\n\tmmw 0x48000020 0xAA000000 0x55000000\t;# AFRL\n\t# Port C: PC03:AF10:V\n\tmmw 0x48000800 0x00000080 0x00000040\t;# MODER\n\tmmw 0x48000808 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x4800080C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x48000820 0x0000A000 0x00005000\t;# AFRL\n\t# Port D: PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x48000C00 0x00008A00 0x00004500\t;# MODER\n\tmmw 0x48000C08 0x0000CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x48000C0C 0x00000000 0x0000CF00\t;# PUPDR\n\tmmw 0x48000C20 0xA0AA0000 0x50550000\t;# AFRL\n\t# Port E: PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0x0AA00000 0x05500000\t;# MODER\n\tmmw 0x48001008 0x0FF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800100C 0x00000000 0x0FF00000\t;# PUPDR\n\tmmw 0x48001024 0x00AAAA00 0x00555500\t;# AFRH\n\t# Port G: PG06:AF03:V\n\tmmw 0x48001800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x48001808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x00003000\t;# PUPDR\n\tmmw 0x48001820 0x03000000 0x0C000000\t;# AFRL\n\n\t# PG12: P2_NCS, PF04: P2_CLK, PF12: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PG01: P2_IO5\n\t# PG00: P2_IO4, PF03: P2_IO3, PF02: P2_IO2, PF01: P2_IO1, PF00: P2_IO0\n\n\t# PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\t# PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\n\t# Port F: PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\tmmw 0x48001400 0x020002AA 0x01000155\t;# MODER\n\tmmw 0x48001408 0x030003FF 0x00000000\t;# OSPEEDR\n\tmmw 0x4800140C 0x00000000 0x030003FF\t;# PUPDR\n\tmmw 0x48001420 0x00055555 0x000AAAAA\t;# AFRL\n\tmmw 0x48001424 0x00050000 0x000A0000\t;# AFRH\n\t# Port G: PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\tmmw 0x48001800 0x0228000A 0x01140005\t;# MODER\n\tmmw 0x48001808 0x033C000F 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x033C000F\t;# PUPDR\n\tmmw 0x48001820 0x00000055 0x000000AA\t;# AFRL\n\tmmw 0x48001824 0x00050550 0x000A0AA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 24000\n\n\toctospi_init 1\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32l4r9i-disco.cfg",
    "content": "# This is a STM32L4R9I discovery board with a single STM32L4R9AII6 chip.\n# http://www.st.com/en/evaluation-tools/32l4r9idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x00000000\t\t\t\t;# OCTOSPIM_P1CR: disable Port 1\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PG12: P2_NCS, PI06: P2_CLK, PG15: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PH10: P2_IO5,\n\t# PH09: P2_IO4, PH08: P2_IO3, PI09: P2_IO2, PI10: P2_IO1, PI11: P2_IO0\n\n\t# PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PH10:AF05:V, PH09:AF05:V\n\t# PH08:AF05:V, PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\n\t# Port G: PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V\n\tmmw 0x48001800 0x82280000 0x41140000\t;# MODER\n\tmmw 0x48001808 0xC33C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001824 0x50050550 0xA00A0AA0\t;# AFRH\n\n\t# Port H: PH10:AF05:V, PH09:AF05:V, PH08:AF05:V\n\tmmw 0x48001C00 0x002A0000 0x00150000\t;# MODER\n\tmmw 0x48001C08 0x003F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001C24 0x00000555 0x00000AAA\t;# AFRH\n\n\t# Port I: PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\tmmw 0x48002000 0x00A82000 0x00541000\t;# MODER\n\tmmw 0x48002008 0x00FC3000 0x00000000\t;# OSPEEDR\n\tmmw 0x48002020 0x05000000 0x0A000000\t;# AFRL\n\tmmw 0x48002024 0x00005550 0x0000AAA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\toctospi_init 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32ldiscovery.cfg",
    "content": "# This is an STM32L discovery board with a single STM32L152RBT6 chip.\n# http://www.st.com/internet/evalboard/product/250990.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x4000\nsource [find target/stm32l1.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32mp13x_dk.cfg",
    "content": "# board MB1635x\n# http://www.st.com/en/evaluation-tools/stm32mp135f-dk.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp13x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32mp15x_dk2.cfg",
    "content": "# board MB1272B\n# http://www.st.com/en/evaluation-tools/stm32mp157a-dk1.html\n# http://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp15x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/stm32vldiscovery.cfg",
    "content": "# This is an STM32VL discovery board with a single STM32F100RB chip.\n# http://www.st.com/internet/evalboard/product/250863.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/str910-eval.cfg",
    "content": "# str910-eval eval board\n#\n# Need reset scripts\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs    -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/telo.cfg",
    "content": "source [find target/c100.cfg]\n# basic register definition for C100\nsource [find target/c100regs.tcl]\n# board-config info\nsource [find target/c100config.tcl]\n# C100 helper functions\nsource [find target/c100helper.tcl]\n\n\n# Telo board & C100 support trst and srst\n# make the reset asserted to\n# allow RC circuit to discharge for: [ms]\nadapter srst pulse_width 100\njtag_ntrst_assert_width 100\n# don't talk to JTAG after reset for: [ms]\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst separate\n\n\n\n\n# issue telnet: reset init\n# issue gdb: monitor reset init\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 100\n\t# this will setup Telo board\n\tsetupTelo\n\t#turn up the JTAG speed\n\tadapter speed 3000\n\techo \"JTAG speek now 3MHz\"\n\techo \"type helpC100 to get help on C100\"\n}\n\n$_TARGETNAME configure -event reset-deassert-post {\n\t# Force target into ARM state.\n#\tsoft_reset_halt ;# not implemented on ARM11\n\techo \"Detected SRSRT asserted on C100.CPU\"\n\n}\n\n$_TARGETNAME configure -event reset-assert-post {\n  echo \"Assering reset\"\n  #sleep 10\n}\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\n# it's really 16MB but the upper 8mb is controller via gpio\n# openocd does not support 'complex reads/writes' to NOR\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x01000000 2 2 $_TARGETNAME\n\n# writing data to memory does not work without this\narm11 memwrite burst disable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am335xevm.cfg",
    "content": "#\n# TI AM335x Evaluation Module\n#\n# For more information please see http://www.ti.com/tool/tmdxevm3358\n#\njtag_rclk 6000\n\nsource [find target/am335x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am437x_idk.cfg",
    "content": "# Texas Instruments AM437x Industrial Development Kit\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\ntransport select jtag\nadapter speed 30000\n\nsource [find target/am437x.cfg]\n$_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 }\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am43xx_evm.cfg",
    "content": "# Works on both AM437x GP EVM and AM438x ePOS EVM\ntransport select jtag\nadapter speed 16000\n\nsource [find target/am437x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am625evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021-2022 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments am625 EVM/SK\n# Link: https://www.ti.com/lit/zip/sprr448\n#\n\n# AM625 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am625\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am642evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM642 EVM\n#\n\n# AM642 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am642\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 250\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_am654evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM654 EVM/IDK Base Board\n#\n\n# AM654 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\nif { ![info exists SOC] } {\n\tset SOC am654\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_beagleboard.cfg",
    "content": "# OMAP3 BeagleBoard\n#  http://beagleboard.org\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n\nsource [find target/omap3530.cfg]\n\n# TI-14 JTAG connector\nreset_config trst_only\n\n# Later run:  omap3_dbginit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_beagleboard_xm.cfg",
    "content": "# BeagleBoard xM (DM37x)\n#  http://beagleboard.org\n\nset CHIPTYPE \"dm37x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit dm37x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_beaglebone-base.cfg",
    "content": "# AM335x Beaglebone family base configuration\n#  http://beagleboard.org/bone\n\nsource [find target/am335x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_beaglebone.cfg",
    "content": "# AM335x Beaglebone\n#  http://beagleboard.org/bone\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\nadapter speed 16000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_beaglebone_black.cfg",
    "content": "# AM335x Beaglebone Black\n#  http://beagleboard.org/bone\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_blaze.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc13x0_launchpad.cfg",
    "content": "#\n# TI CC13x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\ntransport select jtag\nadapter speed 5500\nsource [find target/ti_cc13x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc13x2_launchpad.cfg",
    "content": "#\n# TI CC13x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc13x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc26x0_launchpad.cfg",
    "content": "#\n# TI CC26x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc26x2_launchpad.cfg",
    "content": "#\n# TI CC26x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc3200_launchxl.cfg",
    "content": "#\n# TI SimpleLink Wi-Fi CC3200 LaunchPad\n#\n# http://www.ti.com/tool/cc3200-launchxl\n#\n\nsource [find interface/ftdi/ti-icdi.cfg]\n\nif { [info exists TRANSPORT] } {\n   transport select $TRANSPORT\n} else {\n   transport select jtag\n}\n\nadapter speed 2500\n\nset WORKAREASIZE 0x40000\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc3220sf_launchpad.cfg",
    "content": "#\n# TI CC3220SF-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc3220sf.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_cc32xx_launchpad.cfg",
    "content": "#\n# TI CC32xx-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_dk-tm4c129.cfg",
    "content": "#\n# TI Tiva C DK-TM4C129X Connected Development Kit\n#\n# http://www.ti.com/tool/dk-tm4c129x\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c129xnczad\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_ek-tm4c123gxl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c123gxl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c123gh6pm\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_ek-tm4c1294xl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c1294xl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c1294ncpdt\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_j7200evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J7200 EVM\n#\n\n# J7200 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j7200\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_j721evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721E EVM\n#\n\n# J721E EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721e\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_j721s2evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721s2 EVM\n# Link(SoM): https://www.ti.com/lit/zip/sprr439\n#\n\n# J721s2 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721s2\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_msp432_launchpad.cfg",
    "content": "#\n# TI MSP432 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 10000\ntransport select swd\nsource [find target/ti_msp432.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_pandaboard.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_pandaboard_es.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4460.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_tmdx570ls20susb.cfg",
    "content": "# TMS570 Microcontroller USB Kit\n# http://www.ti.com/tool/TMDX570LS20SUSB\n\n# Board uses a FT2232H to emulate an XDS100v2 JTAG debugger\n# TODO: board also supports an SCI UART on the 2232's B Bus\nsource [find interface/ftdi/xds100v2.cfg]\n\n# Processor is TMS570LS20216\nsource [find target/ti_tms570ls20xxx.cfg]\n\nreset_config trst_only\n\n# xds100v2 config says add this to the end\ninit\nftdi set_signal PWR_RST 1\njtag arp_init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/ti_tmdx570ls31usb.cfg",
    "content": "adapter speed 1500\n\nsource [find interface/ftdi/xds100v2.cfg]\nsource [find target/ti_tms570.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/tocoding_poplar.cfg",
    "content": "#\n# board configuration for Tocoding Poplar\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\nadapter speed 10000\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi3798.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/topas910.cfg",
    "content": "######################################\n# Target:    Toshiba TOPAS910 -- TMPA910 Starterkit\n#\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa910.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topas910_init }\n\nproc topas910_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;\n#  // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/topasa900.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n# Target:    Toshiba TOPAS900 -- TMPA900 Starterkit\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa900.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topasa900_init }\n\nproc topasa900_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n# bplan settings\n#\tmww 0xf0050004 0x00000000\n#\tmww 0xf005000c 0x000000a7\n#\tsleep 10\n#\tmdw 0xf0050008\n#\tmww 0xf0050008 0x00000002\n#\tmww 0xf0050010 0x00000065\n#\tmww 0xf0050054 0x00000040\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;   // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/tp-link_tl-mr3020.cfg",
    "content": "source [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr1_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/tp-link_wdr4300.cfg",
    "content": "source [find target/atheros_ar9344.cfg]\n\nreset_config trst_only separate\n\nproc ar9344_40mhz_pll_init {} {\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x13210f00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x13210f00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_BB_DPLL_BASE_REG\n\tmww 0xb8116188 0x03000000\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\n\t# QCA_PLL_CPU_PLL_CFG_REG\n\tmww 0xb8050000 0x40021380\n\t# QCA_PLL_DDR_PLL_CFG_REG\n\tmww 0xb8050004 0x40815800\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130801C\n\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x10810F00\n\tmww 0xb81161C0 0x41C00000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0810F00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0800F00\n\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x43000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x030003E8\n\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x10810F00\n\tmww 0xb8116240 0x41680000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0810F00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0800F00\n\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x43000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000718\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x01308018\n\tmww 0xb8050008 0x01308010\n\tmww 0xb8050008 0x01308000\n\n\t# QCA_PLL_DDR_PLL_DITHER_REG\n\tmww 0xb8050044 0x78180200\n\t# QCA_PLL_CPU_PLL_DITHER_REG\n\tmww 0xb8050048 0x41C00000\n\n}\n\nproc ar9344_ddr_init {} {\n\t# QCA_DDR_CTRL_CFG_REG\n\tmww 0xb8000108 0x40\n\t# QCA_DDR_RD_DATA_THIS_CYCLE_REG\n\tmww 0xb8000018 0xFF\n\t# QCA_DDR_BURST_REG\n\tmww 0xb80000C4 0x74444444\n\t# QCA_DDR_BURST2_REG\n\tmww 0xb80000C8 0x0222\n\t# QCA_AHB_MASTER_TOUT_MAX_REG\n\tmww 0xb80000CC 0xFFFFF\n\n\t# QCA_DDR_CFG_REG\n\tmww 0xb8000000 0xC7D48CD0\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_DDR2_CFG_REG\n\tmww 0xb80000B8 0x0E59\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x10\n\tmww 0xb8000010 0x20\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x02\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x02\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x0133\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x33\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0382\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0402\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\n\t# QCA_DDR_REFRESH_REG\n\tmww 0xb8000014 0x4270\n\n\t# QCA_DDR_TAP_CTRL_0_REG\n\tmww 0xb800001C 0x0e\n\t# QCA_DDR_TAP_CTRL_1_REG\n\tmww 0xb8000020 0x0e\n\t# QCA_DDR_TAP_CTRL_2_REG\n\tmww 0xb8000024 0x0e\n\t# QCA_DDR_TAP_CTRL_3_REG\n\tmww 0xb8000028 0x0e\n}\n\n$_TARGETNAME configure -event reset-init {\n\n\t# mww 0xb806001c 0x1000000\n\tar9344_40mhz_pll_init\n\tsleep 100\n\n\t# flash remap\n\t# SPI_CONTROL_ADDR\n\tmww 0xbF000004 0x43\n\n\tar9344_ddr_init\n\tsleep 100\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0x1d000000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/twr-k60f120m.cfg",
    "content": "#\n# Freescale TWRK60F120M development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' banks\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.2 kinetis 0x00080000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.3 kinetis 0x000c0000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/twr-k60n512.cfg",
    "content": "#\n# Freescale TWRK60N512 development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' bank\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/twr-vf65gs10.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# Board has a 20 pin Cortex+ETM debug connector with only nSRST available\nreset_config srst_only\n\n# This configuration file only deals with the hardware JTAG.\n# There is has also an embedded Kinetis K20 with OpenSDA\n# where a CMSIS-DAP application can be installed.\n\n# Source generic VF6xx target configuration\nsource [find target/vybrid_vf6xx.cfg]\n\n# basic DDR memory init, setting up pad configuration\n# for DDR first then configuring the DDRMC for the\n# board\nproc ddr_init { } {\n\t# iomux ddr\n\tmww phys 0x40048220 0x00000180\n\tmww phys 0x40048224 0x00000180\n\tmww phys 0x40048228 0x00000180\n\tmww phys 0x4004822c 0x00000180\n\tmww phys 0x40048230 0x00000180\n\tmww phys 0x40048234 0x00000180\n\tmww phys 0x40048238 0x00000180\n\tmww phys 0x4004823c 0x00000180\n\tmww phys 0x40048240 0x00000180\n\tmww phys 0x40048244 0x00000180\n\tmww phys 0x40048248 0x00000180\n\tmww phys 0x4004824c 0x00000180\n\tmww phys 0x40048250 0x00000180\n\tmww phys 0x40048254 0x00000180\n\tmww phys 0x40048258 0x00000180\n\tmww phys 0x4004825c 0x00000180\n\tmww phys 0x40048260 0x00000180\n\tmww phys 0x40048264 0x00000180\n\tmww phys 0x40048268 0x00000180\n\tmww phys 0x4004826c 0x00000180\n\tmww phys 0x40048270 0x00000180\n\tmww phys 0x40048274 0x00000180\n\tmww phys 0x40048278 0x00000180\n\tmww phys 0x4004827c 0x00010180\n\tmww phys 0x40048280 0x00010180\n\tmww phys 0x40048284 0x00010180\n\tmww phys 0x40048288 0x00010180\n\tmww phys 0x4004828c 0x00010180\n\tmww phys 0x40048290 0x00010180\n\tmww phys 0x40048294 0x00010180\n\tmww phys 0x40048298 0x00010180\n\tmww phys 0x4004829c 0x00010180\n\tmww phys 0x400482a0 0x00010180\n\tmww phys 0x400482a4 0x00010180\n\tmww phys 0x400482a8 0x00010180\n\tmww phys 0x400482ac 0x00010180\n\tmww phys 0x400482b0 0x00010180\n\tmww phys 0x400482b4 0x00010180\n\tmww phys 0x400482b8 0x00010180\n\tmww phys 0x400482bc 0x00010180\n\tmww phys 0x400482c0 0x00010180\n\tmww phys 0x400482c4 0x00010180\n\tmww phys 0x400482c8 0x00010180\n\tmww phys 0x400482cc 0x00000180\n\tmww phys 0x400482d0 0x00000180\n\tmww phys 0x400482d4 0x00000180\n\tmww phys 0x400482d8 0x00000180\n\tmww phys 0x4004821c 0x000001a0\n\t# ddr_ctrl_init\n\tmww phys 0x400ae000 0x00000600\n\tmww phys 0x400ae008 0x00000020\n\tmww phys 0x400ae028 0x00013880\n\tmww phys 0x400ae02c 0x00030d40\n\tmww phys 0x400ae030 0x0000050c\n\tmww phys 0x400ae034 0x15040400\n\tmww phys 0x400ae038 0x1406040f\n\tmww phys 0x400ae040 0x04040000\n\tmww phys 0x400ae044 0x006db00c\n\tmww phys 0x400ae048 0x00000403\n\tmww phys 0x400ae050 0x01000000\n\tmww phys 0x400ae054 0x00060001\n\tmww phys 0x400ae058 0x000c0000\n\tmww phys 0x400ae05c 0x03000200\n\tmww phys 0x400ae060 0x00000006\n\tmww phys 0x400ae064 0x00010000\n\tmww phys 0x400ae068 0x0c30002c\n\tmww phys 0x400ae070 0x00000000\n\tmww phys 0x400ae074 0x00000003\n\tmww phys 0x400ae078 0x0000000a\n\tmww phys 0x400ae07c 0x003001d4\n\tmww phys 0x400ae084 0x00010000\n\tmww phys 0x400ae088 0x00050500\n\tmww phys 0x400ae098 0x00000000\n\tmww phys 0x400ae09c 0x04001002\n\tmww phys 0x400ae0a4 0x00000001\n\tmww phys 0x400ae0c0 0x00460420\n\tmww phys 0x400ae108 0x01000200\n\tmww phys 0x400ae10c 0x00000040\n\tmww phys 0x400ae114 0x00000200\n\tmww phys 0x400ae118 0x00000040\n\tmww phys 0x400ae120 0x00000000\n\tmww phys 0x400ae124 0x0a010300\n\tmww phys 0x400ae128 0x01014040\n\tmww phys 0x400ae12c 0x01010101\n\tmww phys 0x400ae130 0x03030100\n\tmww phys 0x400ae134 0x01000101\n\tmww phys 0x400ae138 0x0700000c\n\tmww phys 0x400ae13c 0x00000000\n\tmww phys 0x400ae148 0x10000000\n\tmww phys 0x400ae15c 0x01000000\n\tmww phys 0x400ae160 0x00040000\n\tmww phys 0x400ae164 0x00000002\n\tmww phys 0x400ae16c 0x00020000\n\tmww phys 0x400ae180 0x00002819\n\tmww phys 0x400ae184 0x01000000\n\tmww phys 0x400ae188 0x00000000\n\tmww phys 0x400ae18c 0x00000000\n\tmww phys 0x400ae198 0x00000000\n\tmww phys 0x400ae1a4 0x00000c00\n\tmww phys 0x400ae1a8 0x00000000\n\tmww phys 0x400ae1b8 0x0000000c\n\tmww phys 0x400ae1c8 0x00000000\n\tmww phys 0x400ae1cc 0x00000000\n\tmww phys 0x400ae1d4 0x00000000\n\tmww phys 0x400ae1d8 0x01010000\n\tmww phys 0x400ae1e0 0x02020000\n\tmww phys 0x400ae1e4 0x00000202\n\tmww phys 0x400ae1e8 0x01010064\n\tmww phys 0x400ae1ec 0x00010101\n\tmww phys 0x400ae1f0 0x00000064\n\tmww phys 0x400ae1f8 0x00000800\n\tmww phys 0x400ae210 0x00000506\n\tmww phys 0x400ae224 0x00020000\n\tmww phys 0x400ae228 0x01000000\n\tmww phys 0x400ae22c 0x04070303\n\tmww phys 0x400ae230 0x00000040\n\tmww phys 0x400ae23c 0x06000080\n\tmww phys 0x400ae240 0x04070303\n\tmww phys 0x400ae244 0x00000040\n\tmww phys 0x400ae248 0x00000040\n\tmww phys 0x400ae24c 0x000f0000\n\tmww phys 0x400ae250 0x000f0000\n\tmww phys 0x400ae25c 0x00000101\n\tmww phys 0x400ae268 0x682c4000\n\tmww phys 0x400ae26c 0x00000012\n\tmww phys 0x400ae278 0x00000006\n\tmww phys 0x400ae284 0x00010202\n\tmww phys 0x400ae400 0x00002613\n\tmww phys 0x400ae440 0x00002613\n\tmww phys 0x400ae404 0x00002615\n\tmww phys 0x400ae444 0x00002615\n\tmww phys 0x400ae408 0x00210000\n\tmww phys 0x400ae448 0x00210000\n\tmww phys 0x400ae488 0x00210000\n\tmww phys 0x400ae40c 0x0001012a\n\tmww phys 0x400ae44c 0x0001012a\n\tmww phys 0x400ae48c 0x0001012a\n\tmww phys 0x400ae410 0x00002400\n\tmww phys 0x400ae450 0x00002400\n\tmww phys 0x400ae490 0x00002400\n\tmww phys 0x400ae4c4 0x00000000\n\tmww phys 0x400ae4c8 0x00001100\n\tmww phys 0x400ae4d0 0x00010101\n\tmww phys 0x400ae000 0x00000601\n}\n\n# clock control init, setting up basic\n# clocks\nproc clock_init { } {\n\t# captured from u-boot\n\tmww phys 0x4006b040 0xffffffff\n\tmww phys 0x4006b044 0xffffffff\n\tmww phys 0x4006b048 0xffffffff\n\tmww phys 0x4006b04c 0xffffffff\n\tmww phys 0x4006b050 0xffffffff\n\tmww phys 0x4006b058 0xffffffff\n\tmww phys 0x4006b05c 0xffffffff\n\tmww phys 0x4006b060 0xffffffff\n\tmww phys 0x4006b064 0xffffffff\n\tmww phys 0x4006b068 0xffffffff\n\tmww phys 0x40050030 0x00002001\n\tmww phys 0x40050270 0x80002001\n\tmww phys 0x4006b000 0x00011005\n\tmww phys 0x4006b008 0x0001ff24\n\tmww phys 0x4006b00c 0x00000810\n\tmww phys 0x4006b010 0x00cc0000\n\tmww phys 0x4006b014 0x01000000\n\tmww phys 0x4006b018 0x20000000\n\tmww phys 0x4006b01c 0x0000001f\n\tmww phys 0x4006b020 0x00000000\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc board_init { } {\n\tclock_init\n\tddr_init\n}\n\n# hook the init function into the reset-init event\n${_TARGETNAME}0 configure -event reset-init { board_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/twr-vf65gs10_cmsisdap.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# CMSIS-DAP via USB-OTG connector\n#\nsource [find interface/cmsis-dap.cfg]\n\n# only SWD is supported by the CMSIS-DAP on this board\ntransport select swd\n\n# Source generic part of twr-vf65gs10 configuration\nsource [find board/twr-vf65gs10.cfg]\n\n# override reset configuration\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/tx25_stk5.cfg",
    "content": "# -------------------------------------------------------------------------\n# KaRo TX25 CPU Module on a StarterkitV base board\n# http://www.karo-electronics.com/tx25.html\n# -------------------------------------------------------------------------\n\n\nsource [find target/imx25.cfg]\n\n\t#-------------------------------------------------------------------------\n\t# Declare Nand\n\t#-------------------------------------------------------------------------\n\n\tnand device K9F1G08UOC mxc imx25.cpu mx25 hwecc biswap\n\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx25_init }\n\n\nproc tx25_init { } {\n\n\t#-------------------------------------------------------------------------\n\t# AIPS setup - Only setup MPROTx registers. The PACR default values are good.\n\t# Set all MPROTx to be non-bufferable, trusted for R/W,\n\t# not forced to user-mode.\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\tsleep 100\n\n\t#-------------------------------------------------------------------------\n\t# MAX (Multi-Layer AHB Crossbar Switch) setup\n\t# MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f04000 0x00043210\n\tmww 0x43f04100 0x00043210\n\tmww 0x43f04200 0x00043210\n\tmww 0x43f04300 0x00043210\n\tmww 0x43f04400 0x00043210\n\n\t# SGPCR - always park on last master\n\tmww 0x43f04010 0x10\n\tmww 0x43f04110 0x10\n\tmww 0x43f04210 0x10\n\tmww 0x43f04310 0x10\n\tmww 0x43f04410 0x10\n\n\t# MGPCR - restore default values\n\tmww 0x43f04800 0x0\n\tmww 0x43f04900 0x0\n\tmww 0x43f04a00 0x0\n\tmww 0x43f04b00 0x0\n\tmww 0x43f04c00 0x0\n\n\t# Configure M3IF registers\n\t# M3IF Control Register (M3IFCTL) for MX25\n\t# MRRP[0] = LCDC           on priority list (1 << 0)  = 0x00000001\n\t# MRRP[1] = MAX1       not on priority list (0 << 1)  = 0x00000000\n\t# MRRP[2] = MAX0       not on priority list (0 << 2)  = 0x00000000\n\t# MRRP[3] = USB HOST   not on priority list (0 << 3)  = 0x00000000\n\t# MRRP[4] = SDMA       not on priority list (0 << 4)  = 0x00000000\n\t# MRRP[5] = SD/ATA/FEC not on priority list (0 << 5)  = 0x00000000\n\t# MRRP[6] = SCMFBC     not on priority list (0 << 6)  = 0x00000000\n\t# MRRP[7] = CSI        not on priority list (0 << 7)  = 0x00000000\n\t#                                                       ----------\n\t#                                                       0x00000001\n\tmww 0xb8003000 0x00000001\n\n\t#-------------------------------------------------------------------------\n\t# configure ARM CLK\n\t#-------------------------------------------------------------------------\n\n\t# Set the Clock CTL (HRM p. 355)\n\tmww 0x53F80008 0x20034000\n\n\t# Setup Clock Gating CTL 0-2 (HRM p. 357)\n\tmww 0x53F8000C 0x1fffffff\n\tmww 0x53F80010 0xffffffff\n\tmww 0x53F80014 0x000fdfff\n\n\t#-------------------------------------------------------------------------\n\t# SDRAM initialization\n\t#-------------------------------------------------------------------------\n\n\t# set to 3.3v SDRAM\n\tmww 0x43FAC454 0x00000800\n\n\t# reset (set up ESDMISC)\n\tmww 0xB8001010 0x00000002\n\n\t# Setup for SDRAM Bank 0\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG0\n\tmww 0xB8001004 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001000 0x92116480\n\tmww 0x80000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001000 0xA2116480\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001000 0xB2116480\n\tmwb 0x80000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001000 0x82116480\n\n\t# Setup for SDRAM Bank 1\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG1\n\tmww 0xB800100C 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001008 0x92116480\n\tmww 0x90000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001008 0xA2116480\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001008 0xB2116480\n\tmwb 0x90000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001008 0x82116480\n\n\t# GPIO configuration\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43FAC02C 0x00000015\n\tmww 0x53FD0000 0x01000000\n\tmww 0x53FD0004 0x00000080\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/tx27_stk5.cfg",
    "content": "# KaRo TX27 CPU Module on a StarterkitV base board\n#\n# http://www.karo-electronics.com/tx27.html\n#\nsource [find target/imx27.cfg]\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx27_init }\n\nproc tx27_init { } {\n\t# This setup puts RAM at 0xA0000000\n\t# init_aipi (AIPI1.PSR0, AIPI2.PSR0, AIPI1.PSR1 and AIPI2.PSR1)\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t#init_max ( PORT0.MPR, #PORT0.AMPR, #PORT1.MPR, #PORT1.AMPR, #PORT2.MPR, #PORT2.AMPR)\n\tmww 0x1003F000 0x00302145\n\tmww 0x1003F004 0x00302145\n\tmww 0x1003F100 0x00302145\n\tmww 0x1003F104 0x00302145\n\tmww 0x1003F200 0x00302145\n\tmww 0x1003F204 0x00302145\n\n\t#init_drive_strength (#DSCR3, #DSCR5, #DSCR6, #DSCR7, #DSCR8 )\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\t#init_sdram_speed\n\t#mww 0xD8001010 0x00000004\n\tmww 0xD8001010 0x00000024\n\n\tmww 0xD8001004 0x00395729\n\n\tmww 0xD8001000 0x92120000\n\tmww 0xA0000400 0x0\n\n\tmww 0xD8001000 0xA2120000\n\tmww 0xA0000000 0x0\n\tmww 0xA0000000 0x0\n\n\tmww 0xD8001000 0xB2120000\n\tmdb 0xA0000000\n\tmdb 0xA0000033\n\n\tmww 0xD8001000 0x82126485\n\n\t# =============================================\n\t# Sync mode (AHB Clk = 133MHz ; BCLK = 44.3MHz)\n\t# =============================================\n\tmww 0xD8002000 0x23524E80\n\tmww 0xD8002004 0x10000D03\n\tmww 0xD8002008 0x00720900\n\n\tnand probe 0\n}\n\nnand device tx27.nand mxc $_TARGETNAME mx27 hwecc biswap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/unknown_at91sam9260.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n#\n# Unknown vendor board contains:\n#\n# Atmel AT91SAM9260 : PLLA = 192.512MHz, MCK = 96.256 MHz\n#                     OSCSEL configured for internal RC oscillator (22 to 42 kHz)\n#\n# 16-bit NOR FLASH : Intel JS28F128P30T85 128MBit\n# 32-bit SDRAM : 2 x Samsung K4S561632H-UC75, 4M x 16Bit x 4 Banks\n##################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 22 to 42 kHz.\n        # JTAG Frequency must be 6 times slower.\n        jtag_rclk 3\n        halt\n\t# RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x205dbf09         ;# CKGR_PLLAR: Set PLLA Register for 192.512MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (96.256 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xffffec00 0x01020102         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x09070806         ;# SMC_PULSE0\n\tmww 0xffffec08 0x000d000b         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00001003         ;# SMC_MODE0\n\n\tflash probe 0                     ;# Identify flash bank 0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n        mww 0xfffff860 0xffff0000         ;# PIO_PUDR : Disable D15..D31 pull-ups\n\n        mww 0xffffef1c 0x00010102         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM\n                                           #            VDDIOMSEL set for +3V3 memory\n                                           #            Disable D0..D15 pull-ups\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2a2              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/uptech_2410.cfg",
    "content": "# Target Configuration for the Uptech 2410 board.\n# This configuration should also work on smdk2410, but I haven't tested it yet.\n# Author: xionglingfeng@Gmail.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init { uptech2410_init }\n$_TARGETNAME configure -event gdb-attach { reset init }\n\nproc init_pll_sdram { } {\n\t#echo \"---------- Initializing PLL and SDRAM ---------\"\n\t#watchdog timer disable\n\tmww phys 0x53000000 0x00000000\n\n\t#disable all interrupts\n\tmww phys 0x4a000008 0xffffffff\n\n\t#disable all sub-interrupts\n\tmww phys 0x4a00001c 0x000007ff\n\n\t#clear all source pending bits\n\tmww phys 0x4a000000 0xffffffff\n\n\t#clear all sub-source pending bits\n\tmww phys 0x4a000018 0x000007ff\n\n\t#clear interrupt pending bit\n\tmww phys 0x4a000010 0xffffffff\n\n\t#PLL locktime counter\n\tmww phys 0x4c000000 0x00ffffff\n\n\t#Fin=12MHz Fout=202.8MHz\n\t#mww phys 0x4c000004 0x000a1031\n\n\t#FCLK:HCLK:PCLK = 1:2:4\n\tmww phys 0x4c000014 0x00000003\n\n\n\tmww phys 0x48000000 0x11111110\n\tmww phys 0x48000004 0x00007FFC\n\tmww phys 0x48000008 0x00007FFC\n\tmww phys 0x4800000c 0x00000700\n\tmww phys 0x48000010 0x00000700\n\tmww phys 0x48000014 0x00002E50\n\tmww phys 0x48000018 0x00002E50\n\tmww phys 0x4800001c 0x00018005\n\tmww phys 0x48000020 0x00018005\n\tmww phys 0x48000024 0x008c04e9\n\tmww phys 0x48000028 0x000000b2\n\tmww phys 0x4800002c 0x00000030\n\tmww phys 0x48000030 0x00000030\n}\n\nproc uptech2410_init { } {\n\tinit_pll_sdram\n\t#echo \"---------- Probing Nand flash ----------\"\n\tnand probe 0\n\t#echo \"---------- Enable some functions ----------\"\n}\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME s3c2410 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/vd_a53x2_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex A53x2 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CORES 2\nset _CHIPNAME a53\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x1000000\nset _CPUTAPID 0x5ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_aarch64.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/vd_m4_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m4 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m4\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\nset _CPUTAPID 0x4ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 25000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 20ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/vd_pulpissimo_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV Ibex core with Pulpissimo through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME ibex\nset _HARTID 0x20\nset _CPUTAPID 0x249511c3\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 12500\nadapter srst delay 10\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 40ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[0\\].sram_i.mem_array 0x1c000000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[1\\].sram_i.mem_array 0x1c008000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2\\[0\\].sram_i.mem_array 0x1c010000 0x80000\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x05 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/vd_swerv_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV swerv core with Swerv through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME rv32\nset _HARTID 0x00\nset _CPUTAPID 0x1000008b\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.i_ahb_ic.mem $_MEMSTART $_MEMSIZE\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/verdex.cfg",
    "content": "# Config for Gumstix Verdex XM4 and XL6P (PXA270)\n\nset CHIPNAME verdex\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz\nadapter speed 40000\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n# XL6P has 32 MB flash\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x02000000 2 2 $_TARGETNAME\n# XM4 has 16 MB flash\n#flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/voipac.cfg",
    "content": "# Config for Voipac PXA270/PXA270M module.\n\nset CHIPNAME voipac\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\nflash bank $_CHIPNAME.flash1 cfi 0x02000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/voltcraft_dso-3062c.cfg",
    "content": "#\n# Voltcraft DSO-3062C digital oscilloscope (uses a Samsung S3C2440)\n#\n# http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/\n# http://www.mikrocontroller.net/topic/249628\n# http://elinux.org/Das_Oszi\n# http://randomprojects.org/wiki/Voltcraft_DSO-3062C\n#\n\n# Enable this if your JTAG adapter supports multiple transports (JTAG or SWD).\n# Otherwise comment it out, as it will cause an OpenOCD error.\n### transport select jtag\n\nsource [find target/samsung_s3c2440.cfg]\n\nadapter speed 16000\n\n# Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit)\nnand device $_CHIPNAME.nand s3c2440 $_TARGETNAME\n\n# arm7_9 fast_memory_access enable\n# arm7_9 dcc_downloads enable\n\ninit\nreset\nhalt\nscan_chain\ntargets\nnand probe 0\nnand list\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/x300t.cfg",
    "content": "# This is for the T-Home X300T / X301T IPTV box,\n# which are based on IPTV reference designs from Kiss/Cisco KMM-3***\n#\n# It has Sigma Designs SMP8634 chip.\nsource [find target/smp8634.cfg]\n\n$_TARGETNAME configure -event reset-init { x300t_init }\n\n# 1MB CFI capable flash\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xac000000 0x100000 2 2 $_TARGETNAME\n\nproc x300t_init { } {\n\t# Setup SDRAM config and flash mapping\n\t# initialize ram\n\tmww 0xa003fffc 3\n\tmww 0xa003fffc 2\n\tmww 0xa0030000 0xE34111BA\n\tmww 0xa003fffc 0xa4444\n\tmww 0xa003fffc 0\n\n\t# remap boot vector in CPU local RAM\n\tmww 0xa006f000 0x60000\n\n\t# map flash to CPU address space REG_BASE_cpu_block+CPU_remap4\n\tmww 0x0006f010 0x48000000\n\n\t# map flash addr to REG_BASE_cpu_block + LR_XENV_LOCATION (normally done by XOS)\n\tmww 0x00061ff0 0x48000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc-2go.cfg",
    "content": "#\n# Infineon XMC 2Go\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc1100-boot-kit.cfg",
    "content": "#\n# Infineon XMC1100 Boot Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4200-application-kit-actuator.cfg",
    "content": "#\n# Infineon XMC4200 Application Kit - Actuator\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4200\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4300-relax.cfg",
    "content": "#\n# Infineon XMC4300 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4300\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4500-application-kit-general.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - General Purpose\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4500-application-kit-sdram.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - SDRAM\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4500-relax.cfg",
    "content": "#\n# Infineon XMC4500 Relax Kit / Relax Lite Kit\n#\n\n#\n# Segger J-Link Lite XMC4500 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4700-relax.cfg",
    "content": "#\n# Infineon XMC4700 Relax Lite Kit / Relax Kit for 5V Shields / Relax Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4700\nsource [find target/xmc4xxx.cfg]\n\n# Relax Kit only: N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmc4800-relax.cfg",
    "content": "#\n# Infineon XMC4800 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4800\nsource [find target/xmc4xxx.cfg]\n\n# N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/board/xmos_xk-xac-xa8_arm.cfg",
    "content": "#\n# xCORE-XA Core Module\n#\n# https://www.xmos.com/support/boards?product=17940\n#\n\n#\n# J-Link OB STM32F103\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n#\n# XS1-XAU8A-10\n#\nsource [find target/xmos_xs1-xau8a-10_arm.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/aic.tcl",
    "content": "set AIC_SMR      \t[expr {$AT91C_BASE_AIC + 0x00000000} ]\nglobal AIC_SMR\nset AIC_SVR      \t[expr {$AT91C_BASE_AIC + 0x00000080} ]\nglobal AIC_SVR\nset AIC_IVR      \t[expr {$AT91C_BASE_AIC + 0x00000100} ]\nglobal AIC_IVR\nset AIC_FVR      \t[expr {$AT91C_BASE_AIC + 0x00000104} ]\nglobal AIC_FVR\nset AIC_ISR      \t[expr {$AT91C_BASE_AIC + 0x00000108} ]\nglobal AIC_ISR\nset AIC_IPR      \t[expr {$AT91C_BASE_AIC + 0x0000010C} ]\nglobal AIC_IPR\nset AIC_IMR      \t[expr {$AT91C_BASE_AIC + 0x00000110} ]\nglobal AIC_IMR\nset AIC_CISR     \t[expr {$AT91C_BASE_AIC + 0x00000114} ]\nglobal AIC_CISR\nset AIC_IECR     \t[expr {$AT91C_BASE_AIC + 0x00000120} ]\nglobal AIC_IECR\nset AIC_IDCR     \t[expr {$AT91C_BASE_AIC + 0x00000124} ]\nglobal AIC_IDCR\nset AIC_ICCR     \t[expr {$AT91C_BASE_AIC + 0x00000128} ]\nglobal AIC_ICCR\nset AIC_ISCR     \t[expr {$AT91C_BASE_AIC + 0x0000012C} ]\nglobal AIC_ISCR\nset AIC_EOICR    \t[expr {$AT91C_BASE_AIC + 0x00000130} ]\nglobal AIC_EOICR\nset AIC_SPU      \t[expr {$AT91C_BASE_AIC + 0x00000134} ]\nglobal AIC_SPU\nset AIC_DCR      \t[expr {$AT91C_BASE_AIC + 0x00000138} ]\nglobal AIC_DCR\nset AIC_FFER     \t[expr {$AT91C_BASE_AIC + 0x00000140} ]\nglobal AIC_FFER\nset AIC_FFDR     \t[expr {$AT91C_BASE_AIC + 0x00000144} ]\nglobal AIC_FFDR\nset AIC_FFSR     \t[expr {$AT91C_BASE_AIC + 0x00000148} ]\nglobal AIC_FFSR\n\n\nproc aic_enable_disable_list { VAL ENAME DNAME } {\n    global AT91C_ID\n\n    show_mmr32_bits AT91C_ID $VAL\n\n}\n\nproc show_AIC_IPR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ PENDING\" \"irq not-pending\"\n}\n\nproc show_AIC_IMR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ ENABLED\" \"irq disabled\"\n}\n\n\nproc show_AIC { } {\n    global AIC_SMR\n    if [catch { set aaa [read_memory $AIC_SMR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SMR]\n    }\n    echo \"AIC_SMR: Mode & Type\"\n    global AT91C_ID\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo  [format \"%2d: %5s 0x%08x\"  $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n    global AIC_SVR\n    if [catch { set aaa [read_memory $AIC_SVR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SVR]\n    }\n    echo \"AIC_SVR: Vectors\"\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo [format \"%2d: %5s 0x%08x\" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n\n    foreach REG {\n\tAIC_IVR   AIC_FVR  AIC_ISR\n\tAIC_IPR  AIC_IMR  AIC_CISR  AIC_IECR AIC_IDCR\n\tAIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU  AIC_DCR\n\tAIC_FFER AIC_FFDR AIC_FFSR } {\n\tif [catch { show_mmr32_reg $REG } msg ] {\n\t    error $msg\n\t    break\n\t}\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91_pio.cfg",
    "content": "set PIO_PER\t0x00\t;# Enable Register\nset PIO_PDR\t0x04\t;# Disable Register\nset PIO_PSR\t0x08\t;# Status Register\nset PIO_OER\t0x10\t;# Output Enable Register\nset PIO_ODR\t0x14\t;# Output Disable Register\nset PIO_OSR\t0x18\t;# Output Status Register\nset PIO_IFER\t0x20\t;# Glitch Input Filter Enable\nset PIO_IFDR\t0x24\t;# Glitch Input Filter Disable\nset PIO_IFSR\t0x28\t;# Glitch Input Filter Status\nset PIO_SODR\t0x30\t;# Set Output Data Register\nset PIO_CODR\t0x34\t;# Clear Output Data Register\nset PIO_ODSR\t0x38\t;# Output Data Status Register\nset PIO_PDSR\t0x3c\t;# Pin Data Status Register\nset PIO_IER\t0x40\t;# Interrupt Enable Register\nset PIO_IDR\t0x44\t;# Interrupt Disable Register\nset PIO_IMR\t0x48\t;# Interrupt Mask Register\nset PIO_ISR\t0x4c\t;# Interrupt Status Register\nset PIO_MDER\t0x50\t;# Multi-driver Enable Register\nset PIO_MDDR\t0x54\t;# Multi-driver Disable Register\nset PIO_MDSR\t0x58\t;# Multi-driver Status Register\nset PIO_PUDR\t0x60\t;# Pull-up Disable Register\nset PIO_PUER\t0x64\t;# Pull-up Enable Register\nset PIO_PUSR\t0x68\t;# Pull-up Status Register\nset PIO_ASR\t0x70\t;# Peripheral A Select Register\nset PIO_BSR\t0x74\t;# Peripheral B Select Register\nset PIO_ABSR\t0x78\t;# AB Status Register\nset PIO_OWER\t0xa0\t;# Output Write Enable Register\nset PIO_OWDR\t0xa4\t;# Output Write Disable Register\nset PIO_OWSR\t0xa8\t;# Output Write Status Register\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91_pmc.cfg",
    "content": "set\tAT91_PMC_SCER\t\t[expr {$AT91_PMC + 0x00}]\t;# System Clock Enable Register\nset\tAT91_PMC_SCDR\t\t[expr {$AT91_PMC + 0x04}]\t;# System Clock Disable Register\n\nset\tAT91_PMC_SCSR\t\t[expr {$AT91_PMC + 0x08}]\t;# System Clock Status Register\nset\t\tAT91_PMC_PCK\t\t[expr {1 <<  0}]\t\t;# Processor Clock\nset\t\tAT91RM9200_PMC_UDP\t[expr {1 <<  1}]\t\t;# USB Devcice Port Clock [AT91RM9200 only]\nset\t\tAT91RM9200_PMC_MCKUDP\t[expr {1 <<  2}]\t\t;# USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only]\nset\t\tAT91CAP9_PMC_DDR\t[expr {1 <<  2}]\t\t;# DDR Clock [CAP9 revC & some SAM9 only]\nset\t\tAT91RM9200_PMC_UHP\t[expr {1 <<  4}]\t\t;# USB Host Port Clock [AT91RM9200 only]\nset\t\tAT91SAM926x_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91SAM926x only]\nset\t\tAT91CAP9_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91CAP9 only]\nset\t\tAT91SAM926x_PMC_UDP\t[expr {1 <<  7}]\t\t;# USB Devcice Port Clock [AT91SAM926x only]\nset\t\tAT91_PMC_PCK0\t\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1\t\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2\t\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3\t\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\t\tAT91_PMC_HCK0\t\t[expr {1 << 16}]\t\t;# AHB Clock (USB host) [AT91SAM9261 only]\nset\t\tAT91_PMC_HCK1\t\t[expr {1 << 17}]\t\t;# AHB Clock (LCD) [AT91SAM9261 only]\n\nset\tAT91_PMC_PCER\t\t[expr {$AT91_PMC + 0x10}]\t;# Peripheral Clock Enable Register\nset\tAT91_PMC_PCDR\t\t[expr {$AT91_PMC + 0x14}]\t;# Peripheral Clock Disable Register\nset\tAT91_PMC_PCSR\t\t[expr {$AT91_PMC + 0x18}]\t;# Peripheral Clock Status Register\n\nset\tAT91_CKGR_UCKR\t\t[expr {$AT91_PMC + 0x1C}]\t;# UTMI Clock Register [some SAM9, CAP9]\nset\t\tAT91_PMC_UPLLEN\t\t[expr {1   << 16}]\t\t;# UTMI PLL Enable\nset\t\tAT91_PMC_UPLLCOUNT\t[expr {0xf << 20}]\t\t;# UTMI PLL Start-up Time\nset\t\tAT91_PMC_BIASEN\t\t[expr {1   << 24}]\t\t;# UTMI BIAS Enable\nset\t\tAT91_PMC_BIASCOUNT\t[expr {0xf << 28}]\t\t;# UTMI BIAS Start-up Time\n\nset\tAT91_CKGR_MOR\t\t[expr {$AT91_PMC + 0x20}]\t;# Main Oscillator Register [not on SAM9RL]\nset\t\tAT91_PMC_MOSCEN\t\t[expr {1    << 0}]\t\t;# Main Oscillator Enable\nset\t\tAT91_PMC_OSCBYPASS\t[expr {1    << 1}]\t\t;# Oscillator Bypass [SAM9x, CAP9]\nset\t\tAT91_PMC_OSCOUNT\t[expr {0xff << 8}]\t\t;# Main Oscillator Start-up Time\n\nset\tAT91_CKGR_MCFR\t\t[expr {$AT91_PMC + 0x24}]\t;# Main Clock Frequency Register\nset\t\tAT91_PMC_MAINF\t\t[expr {0xffff <<  0}]\t\t;# Main Clock Frequency\nset\t\tAT91_PMC_MAINRDY\t[expr {1\t<< 16}]\t\t;# Main Clock Ready\n\nset\tAT91_CKGR_PLLAR\t\t[expr {$AT91_PMC + 0x28}]\t;# PLL A Register\nset\tAT91_CKGR_PLLBR\t\t[expr {$AT91_PMC + 0x2c}]\t;# PLL B Register\nset\t\tAT91_PMC_DIV\t\t[expr {0xff  <<  0}]\t\t;# Divider\nset\t\tAT91_PMC_PLLCOUNT\t[expr {0x3f  <<  8}]\t\t;# PLL Counter\nset\t\tAT91_PMC_OUT\t\t[expr {3     << 14}]\t\t;# PLL Clock Frequency Range\nset\t\tAT91_PMC_MUL\t\t[expr {0x7ff << 16}]\t\t;# PLL Multiplier\nset\t\tAT91_PMC_USBDIV\t\t[expr {3     << 28}]\t\t;# USB Divisor (PLLB only)\nset\t\t\tAT91_PMC_USBDIV_1\t\t[expr {0 << 28}]\nset\t\t\tAT91_PMC_USBDIV_2\t\t[expr {1 << 28}]\nset\t\t\tAT91_PMC_USBDIV_4\t\t[expr {2 << 28}]\nset\t\tAT91_PMC_USB96M\t\t[expr {1     << 28}]\t\t;# Divider by 2 Enable (PLLB only)\nset\t\tAT91_PMC_PLLA_WR_ERRATA\t[expr {1     << 29}]\t\t;# Bit 29 must always be set to 1 when programming the CKGR_PLLAR register\n\nset\tAT91_PMC_MCKR\t\t[expr {$AT91_PMC + 0x30}]\t;# Master Clock Register\nset\t\tAT91_PMC_CSS\t\t[expr {3 <<  0}]\t\t;# Master Clock Selection\nset\t\t\tAT91_PMC_CSS_SLOW\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_CSS_MAIN\t\t[expr {1 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLA\t\t[expr {2 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLB\t\t[expr {3 << 0}]\nset\t\t\tAT91_PMC_CSS_UPLL\t\t[expr {3 << 0}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PRES\t\t[expr {7 <<  2}]\t\t;# Master Clock Prescaler\nset\t\t\tAT91_PMC_PRES_1\t\t\t[expr {0 << 2}]\nset\t\t\tAT91_PMC_PRES_2\t\t\t[expr {1 << 2}]\nset\t\t\tAT91_PMC_PRES_4\t\t\t[expr {2 << 2}]\nset\t\t\tAT91_PMC_PRES_8\t\t\t[expr {3 << 2}]\nset\t\t\tAT91_PMC_PRES_16\t\t[expr {4 << 2}]\nset\t\t\tAT91_PMC_PRES_32\t\t[expr {5 << 2}]\nset\t\t\tAT91_PMC_PRES_64\t\t[expr {6 << 2}]\nset\t\tAT91_PMC_MDIV\t\t[expr {3 <<  8}]\t\t;# Master Clock Division\nset\t\t\tAT91RM9200_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [AT91RM9200 only]\nset\t\t\tAT91RM9200_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_3\t\t[expr {2 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_4\t\t[expr {3 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [SAM9,CAP9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_4\t\t[expr {2 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_6\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_3\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PDIV\t\t[expr {1 << 12}]\t\t;# Processor Clock Division [some SAM9 only]\nset\t\t\tAT91_PMC_PDIV_1\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PDIV_2\t\t\t[expr {1 << 12}]\nset\t\tAT91_PMC_PLLADIV2\t[expr {1 << 12}]\t\t;# PLLA divisor by 2 [some SAM9 only]\nset\t\t\tAT91_PMC_PLLADIV2_OFF\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PLLADIV2_ON\t\t[expr {1 << 12}]\n\nset\tAT91_PMC_USB\t\t[expr {$AT91_PMC + 0x38}]\t;# USB Clock Register [some SAM9 only]\nset\t\tAT91_PMC_USBS\t\t[expr {0x1 <<  0}]\t\t;# USB OHCI Input clock selection\nset\t\t\tAT91_PMC_USBS_PLLA\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_USBS_UPLL\t\t[expr {1 << 0}]\nset\t\tAT91_PMC_OHCIUSBDIV\t[expr {0xF <<  8}]\t\t;# Divider for USB OHCI Clock\n\n;# set\tAT91_PMC_PCKR(n)\t[expr {$AT91_PMC + 0x40 + ((n) * 4)}]\t;# Programmable Clock 0-N Registers\nset\t\tAT91_PMC_CSSMCK\t\t[expr {0x1 <<  8}]\t\t;# CSS or Master Clock Selection\nset\t\t\tAT91_PMC_CSSMCK_CSS\t\t[expr {0 << 8}]\nset\t\t\tAT91_PMC_CSSMCK_MCK\t\t[expr {1 << 8}]\n\nset\tAT91_PMC_IER\t\t[expr {$AT91_PMC + 0x60}]\t;# Interrupt Enable Register\nset\tAT91_PMC_IDR\t\t[expr {$AT91_PMC + 0x64}]\t;# Interrupt Disable Register\nset\tAT91_PMC_SR\t\t[expr {$AT91_PMC + 0x68}]\t;# Status Register\nset\t\tAT91_PMC_MOSCS\t\t[expr {1 <<  0}]\t\t;# MOSCS Flag\nset\t\tAT91_PMC_LOCKA\t\t[expr {1 <<  1}]\t\t;# PLLA Lock\nset\t\tAT91_PMC_LOCKB\t\t[expr {1 <<  2}]\t\t;# PLLB Lock\nset\t\tAT91_PMC_MCKRDY\t\t[expr {1 <<  3}]\t\t;# Master Clock\nset\t\tAT91_PMC_LOCKU\t\t[expr {1 <<  6}]\t\t;# UPLL Lock [some SAM9, AT91CAP9 only]\nset\t\tAT91_PMC_OSCSEL\t\t[expr {1 <<  7}]\t\t;# Slow Clock Oscillator [AT91CAP9 revC only]\nset\t\tAT91_PMC_PCK0RDY\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1RDY\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2RDY\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3RDY\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\tAT91_PMC_IMR\t\t[expr {$AT91_PMC + 0x6c}]\t;# Interrupt Mask Register\n\nset AT91_PMC_PROT\t\t[expr {$AT91_PMC + 0xe4}]\t;# Protect Register [AT91CAP9 revC only]\nset\t\tAT91_PMC_PROTKEY\t0x504d4301\t;# Activation Code\n\nset AT91_PMC_VER\t\t[expr {$AT91_PMC + 0xfc}]\t;# PMC Module Version [AT91CAP9 only]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91_rstc.cfg",
    "content": "set AT91_RSTC_CR\t\t[expr {$AT91_RSTC + 0x00}]\t;# Reset Controller Control Register\nset\t\tAT91_RSTC_PROCRST\t[expr {1 << 0}]\t\t;# Processor Reset\nset\t\tAT91_RSTC_PERRST\t[expr {1 << 2}]\t\t;# Peripheral Reset\nset\t\tAT91_RSTC_EXTRST\t[expr {1 << 3}]\t\t;# External Reset\nset\t\tAT91_RSTC_KEY\t\t[expr {0xa5 << 24}]\t\t;# KEY Password\n\nset AT91_RSTC_SR\t\t[expr {$AT91_RSTC + 0x04}]\t;# Reset Controller Status Register\nset\t\tAT91_RSTC_URSTS\t\t[expr {1 << 0}]\t\t;# User Reset Status\nset\t\tAT91_RSTC_RSTTYP\t[expr {7 << 8}]\t\t;# Reset Type\nset\t\t\tAT91_RSTC_RSTTYP_GENERAL\t[expr {0 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WAKEUP\t\t[expr {1 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WATCHDOG\t[expr {2 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_SOFTWARE\t[expr {3 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_USER\t[expr {4 << 8}]\nset\t\tAT91_RSTC_NRSTL\t\t[expr {1 << 16}]\t\t;# NRST Pin Level\nset\t\tAT91_RSTC_SRCMP\t\t[expr {1 << 17}]\t\t;# Software Reset Command in Progress\n\nset AT91_RSTC_MR\t\t[expr {$AT91_RSTC + 0x08}]\t;# Reset Controller Mode Register\nset\t\tAT91_RSTC_URSTEN\t[expr {1 << 0}]\t\t;# User Reset Enable\nset\t\tAT91_RSTC_URSTIEN\t[expr {1 << 4}]\t\t;# User Reset Interrupt Enable\nset\t\tAT91_RSTC_ERSTL\t\t[expr {0xf << 8}]\t\t;# External Reset Length\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91_wdt.cfg",
    "content": "set AT91_WDT_CR\t\t[expr {$AT91_WDT + 0x00}]\t;# Watchdog Control Register\nset\t\tAT91_WDT_WDRSTT\t\t[expr {1    << 0}]\t;# Restart\nset\t\tAT91_WDT_KEY\t\t[expr {0xa5 << 24}]\t;# KEY Password\n\nset AT91_WDT_MR\t\t[expr {$AT91_WDT + 0x04}]\t;# Watchdog Mode Register\nset\t\tAT91_WDT_WDV\t\t[expr {0xfff << 0}]\t;# Counter Value\nset\t\tAT91_WDT_WDFIEN\t\t[expr {1     << 12}]\t;# Fault Interrupt Enable\nset\t\tAT91_WDT_WDRSTEN\t[expr {1     << 13}]\t;# Reset Processor\nset\t\tAT91_WDT_WDRPROC\t[expr {1     << 14}]\t;# Timer Restart\nset\t\tAT91_WDT_WDDIS\t\t[expr {1     << 15}]\t;# Watchdog Disable\nset\t\tAT91_WDT_WDD\t\t[expr {0xfff << 16}]\t;# Delta Value\nset\t\tAT91_WDT_WDDBGHLT\t[expr {1     << 28}]\t;# Debug Halt\nset\t\tAT91_WDT_WDIDLEHLT\t[expr {1     << 29}]\t;# Idle Halt\n\nset AT91_WDT_SR\t\t[expr {$AT91_WDT + 0x08}]\t;# Watchdog Status Register\nset\t\tAT91_WDT_WDUNF\t\t[expr {1 << 0}]\t\t;# Watchdog Underflow\nset\t\tAT91_WDT_WDERR\t\t[expr {1 << 1}]\t\t;# Watchdog Error\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam7x128.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x128\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__128K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__32K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\n\n\n\nset AT91C_BASE_SYS       0xFFFFF000\nset AT91C_BASE_AIC       0xFFFFF000\nset AT91C_BASE_PDC_DBGU  0xFFFFF300\nset AT91C_BASE_DBGU      0xFFFFF200\nset AT91C_BASE_PIOA      0xFFFFF400\nset AT91C_BASE_PIOB      0xFFFFF600\nset AT91C_BASE_CKGR      0xFFFFFC20\nset AT91C_BASE_PMC       0xFFFFFC00\nset AT91C_BASE_RSTC      0xFFFFFD00\nset AT91C_BASE_RTTC      0xFFFFFD20\nset AT91C_BASE_PITC      0xFFFFFD30\nset AT91C_BASE_WDTC      0xFFFFFD40\nset AT91C_BASE_VREG      0xFFFFFD60\nset AT91C_BASE_MC        0xFFFFFF00\nset AT91C_BASE_PDC_SPI1  0xFFFE4100\nset AT91C_BASE_SPI1      0xFFFE4000\nset AT91C_BASE_PDC_SPI0  0xFFFE0100\nset AT91C_BASE_SPI0      0xFFFE0000\nset AT91C_BASE_PDC_US1   0xFFFC4100\nset AT91C_BASE_US1       0xFFFC4000\nset AT91C_BASE_PDC_US0   0xFFFC0100\nset AT91C_BASE_US0       0xFFFC0000\nset AT91C_BASE_PDC_SSC   0xFFFD4100\nset AT91C_BASE_SSC       0xFFFD4000\nset AT91C_BASE_TWI       0xFFFB8000\nset AT91C_BASE_PWMC_CH3  0xFFFCC260\nset AT91C_BASE_PWMC_CH2  0xFFFCC240\nset AT91C_BASE_PWMC_CH1  0xFFFCC220\nset AT91C_BASE_PWMC_CH0  0xFFFCC200\nset AT91C_BASE_PWMC      0xFFFCC000\nset AT91C_BASE_UDP       0xFFFB0000\nset AT91C_BASE_TC0       0xFFFA0000\nset AT91C_BASE_TC1       0xFFFA0040\nset AT91C_BASE_TC2       0xFFFA0080\nset AT91C_BASE_TCB       0xFFFA0000\nset AT91C_BASE_CAN_MB0   0xFFFD0200\nset AT91C_BASE_CAN_MB1   0xFFFD0220\nset AT91C_BASE_CAN_MB2   0xFFFD0240\nset AT91C_BASE_CAN_MB3   0xFFFD0260\nset AT91C_BASE_CAN_MB4   0xFFFD0280\nset AT91C_BASE_CAN_MB5   0xFFFD02A0\nset AT91C_BASE_CAN_MB6   0xFFFD02C0\nset AT91C_BASE_CAN_MB7   0xFFFD02E0\nset AT91C_BASE_CAN       0xFFFD0000\nset AT91C_BASE_EMAC      0xFFFDC000\nset AT91C_BASE_PDC_ADC   0xFFFD8100\nset AT91C_BASE_ADC       0xFFFD8000\n\nset AT91C_ID(0) FIQ\nset AT91C_ID(1) SYS\nset AT91C_ID(2) PIOA\nset AT91C_ID(3) PIOB\nset AT91C_ID(4) SPI0\nset AT91C_ID(5) SPI1\nset AT91C_ID(6) US0\nset AT91C_ID(7) US1\nset AT91C_ID(8) SSC\nset AT91C_ID(9) TWI\nset AT91C_ID(10) PWMC\nset AT91C_ID(11) UDP\nset AT91C_ID(12) TC0\nset AT91C_ID(13) TC1\nset AT91C_ID(14) TC2\nset AT91C_ID(15) CAN\nset AT91C_ID(16) EMAC\nset AT91C_ID(17) ADC\nset AT91C_ID(18) \"\"\nset AT91C_ID(19) \"\"\nset AT91C_ID(20) \"\"\nset AT91C_ID(21) \"\"\nset AT91C_ID(22) \"\"\nset AT91C_ID(23) \"\"\nset AT91C_ID(24) \"\"\nset AT91C_ID(25) \"\"\nset AT91C_ID(26) \"\"\nset AT91C_ID(27) \"\"\nset AT91C_ID(28) \"\"\nset AT91C_ID(29) \"\"\nset AT91C_ID(30) IRQ0\nset AT91C_ID(31) IRQ1\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam7x256.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x256\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__256K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__64K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\nset  AT91C_BASE_SYS              0xFFFFF000\nset  AT91C_BASE_AIC              0xFFFFF000\nset  AT91C_BASE_PDC_DBGU         0xFFFFF300\nset  AT91C_BASE_DBGU             0xFFFFF200\nset  AT91C_BASE_PIOA             0xFFFFF400\nset  AT91C_BASE_PIOB             0xFFFFF600\nset  AT91C_BASE_CKGR             0xFFFFFC20\nset  AT91C_BASE_PMC              0xFFFFFC00\nset  AT91C_BASE_RSTC             0xFFFFFD00\nset  AT91C_BASE_RTTC             0xFFFFFD20\nset  AT91C_BASE_PITC             0xFFFFFD30\nset  AT91C_BASE_WDTC             0xFFFFFD40\nset  AT91C_BASE_VREG             0xFFFFFD60\nset  AT91C_BASE_MC          0xFFFFFF00\nset  AT91C_BASE_PDC_SPI1      0xFFFE4100\nset  AT91C_BASE_SPI1          0xFFFE4000\nset  AT91C_BASE_PDC_SPI0      0xFFFE0100\nset  AT91C_BASE_SPI0          0xFFFE0000\nset  AT91C_BASE_PDC_US1       0xFFFC4100\nset  AT91C_BASE_US1           0xFFFC4000\nset  AT91C_BASE_PDC_US0       0xFFFC0100\nset  AT91C_BASE_US0           0xFFFC0000\nset  AT91C_BASE_PDC_SSC       0xFFFD4100\nset  AT91C_BASE_SSC           0xFFFD4000\nset  AT91C_BASE_TWI           0xFFFB8000\nset  AT91C_BASE_PWMC_CH3      0xFFFCC260\nset  AT91C_BASE_PWMC_CH2      0xFFFCC240\nset  AT91C_BASE_PWMC_CH1      0xFFFCC220\nset  AT91C_BASE_PWMC_CH0      0xFFFCC200\nset  AT91C_BASE_PWMC          0xFFFCC000\nset  AT91C_BASE_UDP           0xFFFB0000\nset  AT91C_BASE_TC0         0xFFFA0000\nset  AT91C_BASE_TC1         0xFFFA0040\nset  AT91C_BASE_TC2         0xFFFA0080\nset  AT91C_BASE_TCB             0xFFFA0000\nset  AT91C_BASE_CAN_MB0         0xFFFD0200\nset  AT91C_BASE_CAN_MB1         0xFFFD0220\nset  AT91C_BASE_CAN_MB2         0xFFFD0240\nset  AT91C_BASE_CAN_MB3         0xFFFD0260\nset  AT91C_BASE_CAN_MB4         0xFFFD0280\nset  AT91C_BASE_CAN_MB5         0xFFFD02A0\nset  AT91C_BASE_CAN_MB6         0xFFFD02C0\nset  AT91C_BASE_CAN_MB7         0xFFFD02E0\nset  AT91C_BASE_CAN             0xFFFD0000\nset  AT91C_BASE_EMAC            0xFFFDC000\nset  AT91C_BASE_PDC_ADC         0xFFFD8100\nset  AT91C_BASE_ADC             0xFFFD8000\n\nset AT91C_ID(0)   \"FIQ\"\nset AT91C_ID(1)   \"SYS\"\nset AT91C_ID(2)   \"PIOA\"\nset AT91C_ID(3)   \"PIOB\"\nset AT91C_ID(4)   \"SPI0\"\nset AT91C_ID(5)   \"SPI1\"\nset AT91C_ID(6)   \"US0\"\nset AT91C_ID(7)   \"US1\"\nset AT91C_ID(8)   \"SSC\"\nset AT91C_ID(9)   \"TWI\"\nset AT91C_ID(10)   \"PWMC\"\nset AT91C_ID(11)   \"UDP\"\nset AT91C_ID(12)   \"TC0\"\nset AT91C_ID(13)   \"TC1\"\nset AT91C_ID(14)   \"TC2\"\nset AT91C_ID(15)   \"CAN\"\nset AT91C_ID(16)   \"EMAC\"\nset AT91C_ID(17)   \"ADC\"\nset AT91C_ID(18)   \"\"\nset AT91C_ID(19)   \"\"\nset AT91C_ID(20)   \"\"\nset AT91C_ID(21)   \"\"\nset AT91C_ID(22)   \"\"\nset AT91C_ID(23)   \"\"\nset AT91C_ID(24)   \"\"\nset AT91C_ID(25)   \"\"\nset AT91C_ID(26)   \"\"\nset AT91C_ID(27)   \"\"\nset AT91C_ID(28)   \"\"\nset AT91C_ID(29)   \"\"\nset AT91C_ID(30)   \"IRQ0\"\nset AT91C_ID(31)   \"IRQ1\"\n\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9261.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9261_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9261_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9261_ID_PIOC\t4\t;# Parallel IO Controller C\nset AT91SAM9261_ID_US0\t6\t;# USART 0\nset AT91SAM9261_ID_US1\t7\t;# USART 1\nset AT91SAM9261_ID_US2\t8\t;# USART 2\nset AT91SAM9261_ID_MCI\t9\t;# Multimedia Card Interface\nset AT91SAM9261_ID_UDP\t10\t;# USB Device Port\nset AT91SAM9261_ID_TWI\t11\t;# Two-Wire Interface\nset AT91SAM9261_ID_SPI0\t12\t;# Serial Peripheral Interface 0\nset AT91SAM9261_ID_SPI1\t13\t;# Serial Peripheral Interface 1\nset AT91SAM9261_ID_SSC0\t14\t;# Serial Synchronous Controller 0\nset AT91SAM9261_ID_SSC1\t15\t;# Serial Synchronous Controller 1\nset AT91SAM9261_ID_SSC2\t16\t;# Serial Synchronous Controller 2\nset AT91SAM9261_ID_TC0\t17\t;# Timer Counter 0\nset AT91SAM9261_ID_TC1\t18\t;# Timer Counter 1\nset AT91SAM9261_ID_TC2\t19\t;# Timer Counter 2\nset AT91SAM9261_ID_UHP\t20\t;# USB Host port\nset AT91SAM9261_ID_LCDC\t21\t;# LDC Controller\nset AT91SAM9261_ID_IRQ0\t29\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9261_ID_IRQ1\t30\t;# Advanced Interrupt Controller (IRQ1)\nset AT91SAM9261_ID_IRQ2\t31\t;# Advanced Interrupt Controller (IRQ2)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9261_BASE_TCB0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC1\t\t0xfffa0040\nset AT91SAM9261_BASE_TC2\t\t0xfffa0080\nset AT91SAM9261_BASE_UDP\t\t0xfffa4000\nset AT91SAM9261_BASE_MCI\t\t0xfffa8000\nset AT91SAM9261_BASE_TWI\t\t0xfffac000\nset AT91SAM9261_BASE_US0\t\t0xfffb0000\nset AT91SAM9261_BASE_US1\t\t0xfffb4000\nset AT91SAM9261_BASE_US2\t\t0xfffb8000\nset AT91SAM9261_BASE_SSC0\t\t0xfffbc000\nset AT91SAM9261_BASE_SSC1\t\t0xfffc0000\nset AT91SAM9261_BASE_SSC2\t\t0xfffc4000\nset AT91SAM9261_BASE_SPI0\t\t0xfffc8000\nset AT91SAM9261_BASE_SPI1\t\t0xfffcc000\nset AT91_BASE_SYS\t\t\t0xffffea00\n\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_SDRAMC\t0xffffea00\nset AT91_SMC\t0xffffec00\nset AT91_MATRIX\t0xffffee00\nset AT91_AIC\t0xfffff000\nset AT91_DBGU\t0xfffff200\nset AT91_PIOA\t0xfffff400\nset AT91_PIOB\t0xfffff600\nset AT91_PIOC\t0xfffff800\nset AT91_PMC\t0xfffffc00\nset AT91_RSTC\t0xfffffd00\nset AT91_SHDWC\t0xfffffd10\nset AT91_RTT\t0xfffffd20\nset AT91_PIT\t0xfffffd30\nset AT91_WDT\t0xfffffd40\nset AT91_GPBR\t0xfffffd50\n\nset AT91_USART0\t$AT91SAM9261_BASE_US0\nset AT91_USART1\t$AT91SAM9261_BASE_US1\nset AT91_USART2\t$AT91SAM9261_BASE_US2\n\n\n#\n# Internal Memory.\n#\nset AT91SAM9261_SRAM_BASE\t0x00300000\t;# Internal SRAM base address\nset AT91SAM9261_SRAM_SIZE\t0x00028000\t;# Internal SRAM size (160Kb)\n\nset AT91SAM9261_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9261_ROM_SIZE\t0x00008000\t;# Internal ROM size (32Kb)\n\nset AT91SAM9261_UHP_BASE\t0x00500000\t;# USB Host controller\nset AT91SAM9261_LCDC_BASE\t0x00600000\t;# LDC controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9261\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9261_matrix.cfg",
    "content": "\nset AT91_MATRIX_MCFG\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register #\nset\t\tAT91_MATRIX_RCB0\t[expr {1 << 0}]\t\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t[expr {1 << 1}]\t\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x04}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x08}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x0C}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x10}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x14}]\t;# Slave Configuration Register 4\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {7    << 18}]\t;# Fixed Index of Default Master\n\nset AT91_MATRIX_TCR\t\t[expr {$AT91_MATRIX + 0x24}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_64\t\t[expr {7 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_64\t\t[expr {7 << 4}]\n\nset AT91_MATRIX_EBICSA\t[expr {$AT91_MATRIX + 0x30}]\t;# EBI Chip Select Assignment Register\nset\t\tAT91_MATRIX_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_CS4A_SMC_CF1\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_CS5A_SMC_CF2\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\n\nset AT91_MATRIX_USBPUCR\t[expr {$AT91_MATRIX + 0x34}]\t;# USB Pad Pull-Up Control Register\nset\t\tAT91_MATRIX_USBPUCR_PUON\t[expr {1 << 30}]\t;# USB Device PAD Pull-up Enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9263.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9263_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9263_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9263_ID_PIOCDE\t4\t;# Parallel IO Controller C, D and E\nset AT91SAM9263_ID_US0\t7\t;# USART 0\nset AT91SAM9263_ID_US1\t8\t;# USART 1\nset AT91SAM9263_ID_US2\t9\t;# USART 2\nset AT91SAM9263_ID_MCI0\t10\t;# Multimedia Card Interface 0\nset AT91SAM9263_ID_MCI1\t11\t;# Multimedia Card Interface 1\nset AT91SAM9263_ID_CAN\t12\t;# CAN\nset AT91SAM9263_ID_TWI\t13\t;# Two-Wire Interface\nset AT91SAM9263_ID_SPI0\t14\t;# Serial Peripheral Interface 0\nset AT91SAM9263_ID_SPI1\t15\t;# Serial Peripheral Interface 1\nset AT91SAM9263_ID_SSC0\t16\t;# Serial Synchronous Controller 0\nset AT91SAM9263_ID_SSC1\t17\t;# Serial Synchronous Controller 1\nset AT91SAM9263_ID_AC97C\t18\t;# AC97 Controller\nset AT91SAM9263_ID_TCB\t19\t;# Timer Counter 0, 1 and 2\nset AT91SAM9263_ID_PWMC\t20\t;# Pulse Width Modulation Controller\nset AT91SAM9263_ID_EMAC\t21\t;# Ethernet\nset AT91SAM9263_ID_2DGE\t23\t;# 2D Graphic Engine\nset AT91SAM9263_ID_UDP\t24\t;# USB Device Port\nset AT91SAM9263_ID_ISI\t25\t;# Image Sensor Interface\nset AT91SAM9263_ID_LCDC\t26\t;# LCD Controller\nset AT91SAM9263_ID_DMA\t27\t;# DMA Controller\nset AT91SAM9263_ID_UHP\t29\t;# USB Host port\nset AT91SAM9263_ID_IRQ0\t30\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9263_ID_IRQ1\t31\t;# Advanced Interrupt Controller (IRQ1)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9263_BASE_UDP\t\t0xfff78000\nset AT91SAM9263_BASE_TCB0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC1\t\t0xfff7c040\nset AT91SAM9263_BASE_TC2\t\t0xfff7c080\nset AT91SAM9263_BASE_MCI0\t\t0xfff80000\nset AT91SAM9263_BASE_MCI1\t\t0xfff84000\nset AT91SAM9263_BASE_TWI\t\t0xfff88000\nset AT91SAM9263_BASE_US0\t\t0xfff8c000\nset AT91SAM9263_BASE_US1\t\t0xfff90000\nset AT91SAM9263_BASE_US2\t\t0xfff94000\nset AT91SAM9263_BASE_SSC0\t\t0xfff98000\nset AT91SAM9263_BASE_SSC1\t\t0xfff9c000\nset AT91SAM9263_BASE_AC97C\t\t0xfffa0000\nset AT91SAM9263_BASE_SPI0\t\t0xfffa4000\nset AT91SAM9263_BASE_SPI1\t\t0xfffa8000\nset AT91SAM9263_BASE_CAN\t\t0xfffac000\nset AT91SAM9263_BASE_PWMC\t\t0xfffb8000\nset AT91SAM9263_BASE_EMAC\t\t0xfffbc000\nset AT91SAM9263_BASE_ISI\t\t0xfffc4000\nset AT91SAM9263_BASE_2DGE\t\t0xfffc8000\nset AT91_BASE_SYS\t\t\t0xffffe000\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_ECC0\t\t0xffffe000\nset AT91_SDRAMC0\t0xffffe200\nset AT91_SMC0\t\t0xffffe400\nset AT91_ECC1\t\t0xffffe600\nset AT91_SDRAMC1\t0xffffe800\nset AT91_SMC1\t\t0xffffea00\nset AT91_MATRIX\t\t0xffffec00\nset AT91_CCFG\t\t0xffffed10\nset AT91_DBGU\t\t0xffffee00\nset AT91_AIC\t\t0xfffff000\nset AT91_PIOA\t\t0xfffff200\nset AT91_PIOB\t\t0xfffff400\nset AT91_PIOC\t\t0xfffff600\nset AT91_PIOD\t\t0xfffff800\nset AT91_PIOE\t\t0xfffffa00\nset AT91_PMC\t\t0xfffffc00\nset AT91_RSTC\t\t0xfffffd00\nset AT91_SHDWC\t\t0xfffffd10\nset AT91_RTT0\t\t0xfffffd20\nset AT91_PIT\t\t0xfffffd30\nset AT91_WDT\t\t0xfffffd40\nset AT91_RTT1\t\t0xfffffd50\nset AT91_GPBR\t\t0xfffffd60\n\nset AT91_USART0\t$AT91SAM9263_BASE_US0\nset AT91_USART1\t$AT91SAM9263_BASE_US1\nset AT91_USART2\t$AT91SAM9263_BASE_US2\n\nset AT91_SMC\t$AT91_SMC0\nset AT91_SDRAMC\t$AT91_SDRAMC0\n\n#\n# Internal Memory.\n#\nset AT91SAM9263_SRAM0_BASE\t0x00300000\t;# Internal SRAM 0 base address\nset AT91SAM9263_SRAM0_SIZE\t0x00014000\t;# Internal SRAM 0 size (80Kb)\n\nset AT91SAM9263_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9263_ROM_SIZE\t0x00020000\t;# Internal ROM size (128Kb)\n\nset AT91SAM9263_SRAM1_BASE\t0x00500000\t;# Internal SRAM 1 base address\nset AT91SAM9263_SRAM1_SIZE\t0x00004000\t;# Internal SRAM 1 size (16Kb)\n\nset AT91SAM9263_LCDC_BASE\t0x00700000\t;# LCD Controller\nset AT91SAM9263_DMAC_BASE\t0x00800000\t;# DMA Controller\nset AT91SAM9263_UHP_BASE\t0x00a00000\t;# USB Host controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9263\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9263_matrix.cfg",
    "content": "set AT91_MATRIX_MCFG0\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register 0\nset AT91_MATRIX_MCFG1\t[expr {$AT91_MATRIX + 0x04}]\t;# Master Configuration Register 1\nset AT91_MATRIX_MCFG2\t[expr {$AT91_MATRIX + 0x08}]\t;# Master Configuration Register 2\nset AT91_MATRIX_MCFG3\t[expr {$AT91_MATRIX + 0x0C}]\t;# Master Configuration Register 3\nset AT91_MATRIX_MCFG4\t[expr {$AT91_MATRIX + 0x10}]\t;# Master Configuration Register 4\nset AT91_MATRIX_MCFG5\t[expr {$AT91_MATRIX + 0x14}]\t;# Master Configuration Register 5\nset AT91_MATRIX_MCFG6\t[expr {$AT91_MATRIX + 0x18}]\t;# Master Configuration Register 6\nset AT91_MATRIX_MCFG7\t[expr {$AT91_MATRIX + 0x1C}]\t;# Master Configuration Register 7\nset AT91_MATRIX_MCFG8\t[expr {$AT91_MATRIX + 0x20}]\t;# Master Configuration Register 8\nset\t\tAT91_MATRIX_ULBT\t[expr {7 << 0}]\t;# Undefined Length Burst Type\nset\t\t\tAT91_MATRIX_ULBT_INFINITE\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SINGLE\t\t[expr {1 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_FOUR\t\t[expr {2 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_EIGHT\t\t[expr {3 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SIXTEEN\t[expr {4 << 0}]\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x40}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x44}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x48}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x4C}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x50}]\t;# Slave Configuration Register 4\nset AT91_MATRIX_SCFG5\t[expr {$AT91_MATRIX + 0x54}]\t;# Slave Configuration Register 5\nset AT91_MATRIX_SCFG6\t[expr {$AT91_MATRIX + 0x58}]\t;# Slave Configuration Register 6\nset AT91_MATRIX_SCFG7\t[expr {$AT91_MATRIX + 0x5C}]\t;# Slave Configuration Register 7\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {0xf  << 18}]\t;# Fixed Index of Default Master\nset\t\tAT91_MATRIX_ARBT\t\t[expr {3    << 24}]\t;# Arbitration Type\nset\t\t\tAT91_MATRIX_ARBT_ROUND_ROBIN\t[expr {0 << 24}]\nset\t\t\tAT91_MATRIX_ARBT_FIXED_PRIORITY\t[expr {1 << 24}]\n\nset AT91_MATRIX_PRAS0\t[expr {$AT91_MATRIX + 0x80}]\t;# Priority Register A for Slave 0\nset AT91_MATRIX_PRBS0\t[expr {$AT91_MATRIX + 0x84}]\t;# Priority Register B for Slave 0\nset AT91_MATRIX_PRAS1\t[expr {$AT91_MATRIX + 0x88}]\t;# Priority Register A for Slave 1\nset AT91_MATRIX_PRBS1\t[expr {$AT91_MATRIX + 0x8C}]\t;# Priority Register B for Slave 1\nset AT91_MATRIX_PRAS2\t[expr {$AT91_MATRIX + 0x90}]\t;# Priority Register A for Slave 2\nset AT91_MATRIX_PRBS2\t[expr {$AT91_MATRIX + 0x94}]\t;# Priority Register B for Slave 2\nset AT91_MATRIX_PRAS3\t[expr {$AT91_MATRIX + 0x98}]\t;# Priority Register A for Slave 3\nset AT91_MATRIX_PRBS3\t[expr {$AT91_MATRIX + 0x9C}]\t;# Priority Register B for Slave 3\nset AT91_MATRIX_PRAS4\t[expr {$AT91_MATRIX + 0xA0}]\t;# Priority Register A for Slave 4\nset AT91_MATRIX_PRBS4\t[expr {$AT91_MATRIX + 0xA4}]\t;# Priority Register B for Slave 4\nset AT91_MATRIX_PRAS5\t[expr {$AT91_MATRIX + 0xA8}]\t;# Priority Register A for Slave 5\nset AT91_MATRIX_PRBS5\t[expr {$AT91_MATRIX + 0xAC}]\t;# Priority Register B for Slave 5\nset AT91_MATRIX_PRAS6\t[expr {$AT91_MATRIX + 0xB0}]\t;# Priority Register A for Slave 6\nset AT91_MATRIX_PRBS6\t[expr {$AT91_MATRIX + 0xB4}]\t;# Priority Register B for Slave 6\nset AT91_MATRIX_PRAS7\t[expr {$AT91_MATRIX + 0xB8}]\t;# Priority Register A for Slave 7\nset AT91_MATRIX_PRBS7\t[expr {$AT91_MATRIX + 0xBC}]\t;# Priority Register B for Slave 7\nset\t\tAT91_MATRIX_M0PR\t\t[expr {3 << 0}]\t\t;# Master 0 Priority\nset\t\tAT91_MATRIX_M1PR\t\t[expr {3 << 4}]\t\t;# Master 1 Priority\nset\t\tAT91_MATRIX_M2PR\t\t[expr {3 << 8}]\t\t;# Master 2 Priority\nset\t\tAT91_MATRIX_M3PR\t\t[expr {3 << 12}]\t;# Master 3 Priority\nset\t\tAT91_MATRIX_M4PR\t\t[expr {3 << 16}]\t;# Master 4 Priority\nset\t\tAT91_MATRIX_M5PR\t\t[expr {3 << 20}]\t;# Master 5 Priority\nset\t\tAT91_MATRIX_M6PR\t\t[expr {3 << 24}]\t;# Master 6 Priority\nset\t\tAT91_MATRIX_M7PR\t\t[expr {3 << 28}]\t;# Master 7 Priority\nset\t\tAT91_MATRIX_M8PR\t\t[expr {3 << 0}]\t\t;# Master 8 Priority (in Register B)\n\nset AT91_MATRIX_MRCR\t[expr {$AT91_MATRIX + 0x100}]\t;# Master Remap Control Register\nset\t\tAT91_MATRIX_RCB0\t\t[expr {1 << 0}]\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t\t[expr {1 << 1}]\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\nset\t\tAT91_MATRIX_RCB2\t\t[expr {1 << 2}]\nset\t\tAT91_MATRIX_RCB3\t\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_RCB4\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_RCB5\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_RCB6\t\t[expr {1 << 6}]\nset\t\tAT91_MATRIX_RCB7\t\t[expr {1 << 7}]\nset\t\tAT91_MATRIX_RCB8\t\t[expr {1 << 8}]\n\nset AT91_MATRIX_TCMR\t[expr {$AT91_MATRIX + 0x114}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\n\nset AT91_MATRIX_EBI0CSA\t[expr {$AT91_MATRIX + 0x120}]\t;# EBI0 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI0_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI0_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignmen\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI0_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC_CF1\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_EBI0_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC_CF2\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_EBI0_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI0_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n\nset AT91_MATRIX_EBI1CSA\t[expr {$AT91_MATRIX + 0x124}]\t;# EBI1 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI1_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI1_CS2A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI1_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI1_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_init.cfg",
    "content": "uplevel #0 [list source [find chip/atmel/at91/at91sam9_sdramc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pmc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pio.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_rstc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_wdt.cfg]]\n\nproc at91sam9_reset_start { } {\n\n\tarm7_9 fast_memory_access disable\n\n\tjtag_rclk 8\n\thalt\n\twait_halt 10000\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | (5 << 8)}]\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9_reset_init { config } {\n\n\tmww $::AT91_WDT_MR $config(wdt_mr_val)\t;# disable watchdog\n\n\tset ckgr_mor [expr {$::AT91_PMC_MOSCEN | (255 << 8)}]\n\n\tmww $::AT91_CKGR_MOR $ckgr_mor\t;# CKGR_MOR - enable main osc.\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MOSCS}] != $::AT91_PMC_MOSCS } { sleep 1 }\n\n\tset pllar_val\t$::AT91_PMC_PLLA_WR_ERRATA ;# Bit 29 must be 1 when prog\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_OUT}]\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_PLLCOUNT}]\n\tset pllar_val\t[expr {$pllar_val | ($config(master_pll_mul) - 1) << 16}]\n\tset pllar_val\t[expr {$pllar_val | $config(master_pll_div)}]\n\n\tmww $::AT91_CKGR_PLLAR $pllar_val\t ;# CKGR_PLLA - (18.432MHz/13)*141 = 199.9 MHz\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_LOCKA}] != $::AT91_PMC_LOCKA } { sleep 1 }\n\n\t;# PCK/2 = MCK Master Clock from PLLA\n\tset mckr_val\t$::AT91_PMC_CSS_PLLA\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PRES_1}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91SAM9_PMC_MDIV_2}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PDIV_1}]\n\n\tmww $::AT91_PMC_MCKR $mckr_val\t;# PMC_MCKR (MCLK: 0x102 - (CLK/2)MHZ, 0x202 - (CLK/3)MHz)\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MCKRDY}] != $::AT91_PMC_MCKRDY } { sleep 1 }\n\n\t## switch JTAG clock to highspeed clock\n\tjtag_rclk 0\n\n\tarm7_9 dcc_downloads enable\t;# Enable faster DCC downloads\n\tarm7_9 fast_memory_access enable\n\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# user reset enable\n\n\tif { [info exists config(sdram_piod)] } {\n\t\tset pdr_addr\t[expr {$::AT91_PIOD + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOD + $::PIO_PUDR}]\n\t\tset asr_addr\t[expr {$::AT91_PIOD + $::PIO_ASR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t\tmww $asr_addr 0xffff0000\n\t} else {\n\t\tset pdr_addr\t[expr {$::AT91_PIOC + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOC + $::PIO_PUDR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t}\n\n\tmww $config(matrix_ebicsa_addr) $config(matrix_ebicsa_val)\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRAMC_MR Mode register\n\tmww $::AT91_SDRAMC_TR\t$config(sdram_tr_val)\t\t;# SDRAMC_TR - Refresh Timer register\n\tmww $::AT91_SDRAMC_CR\t$config(sdram_cr_val)\t\t;# SDRAMC_CR - Configuration register\n\tmww $::AT91_SDRAMC_MDR\t$::AT91_SDRAMC_MD_SDRAM\t\t;# Memory Device Register -> SDRAM\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_PRECHARGE\t;# SDRAMC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_REFRESH\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_LMR\t\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_TR\t1200\t\t\t\t;# SDRAM_TR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\n\tmww $::AT91_MATRIX 0xf\t\t;# MATRIX_MCFG - REMAP all masters\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_sdramc.cfg",
    "content": "\n# SDRAM Controller (SDRAMC) registers\nset AT91_SDRAMC_MR\t\t[expr {$AT91_SDRAMC + 0x00}]\t;# SDRAM Controller Mode Register\nset\t\tAT91_SDRAMC_MODE\t[expr {0xf << 0}]\t;# Command Mode\nset\t\t\tAT91_SDRAMC_MODE_NORMAL\t\t0\nset\t\t\tAT91_SDRAMC_MODE_NOP\t\t1\nset\t\t\tAT91_SDRAMC_MODE_PRECHARGE\t2\nset\t\t\tAT91_SDRAMC_MODE_LMR\t\t3\nset\t\t\tAT91_SDRAMC_MODE_REFRESH\t4\nset\t\t\tAT91_SDRAMC_MODE_EXT_LMR\t5\nset\t\t\tAT91_SDRAMC_MODE_DEEP\t\t6\n\nset AT91_SDRAMC_TR\t\t[expr {$AT91_SDRAMC + 0x04}]\t;# SDRAM Controller Refresh Timer Register\nset\t\tAT91_SDRAMC_COUNT\t[expr {0xfff << 0}]\t\t;# Refresh Timer Counter\n\nset AT91_SDRAMC_CR\t\t[expr {$AT91_SDRAMC + 0x08}]\t;# SDRAM Controller Configuration Register\nset\t\tAT91_SDRAMC_NC\t\t[expr {3 << 0}]\t\t;# Number of Column Bits\nset\t\t\tAT91_SDRAMC_NC_8\t[expr {0 << 0}]\nset\t\t\tAT91_SDRAMC_NC_9\t[expr {1 << 0}]\nset\t\t\tAT91_SDRAMC_NC_10\t[expr {2 << 0}]\nset\t\t\tAT91_SDRAMC_NC_11\t[expr {3 << 0}]\nset\t\tAT91_SDRAMC_NR\t\t[expr {3 << 2}]\t\t;# Number of Row Bits\nset\t\t\tAT91_SDRAMC_NR_11\t[expr {0 << 2}]\nset\t\t\tAT91_SDRAMC_NR_12\t[expr {1 << 2}]\nset\t\t\tAT91_SDRAMC_NR_13\t[expr {2 << 2}]\nset\t\tAT91_SDRAMC_NB\t\t[expr {1 << 4}]\t\t;# Number of Banks\nset\t\t\tAT91_SDRAMC_NB_2\t[expr {0 << 4}]\nset\t\t\tAT91_SDRAMC_NB_4\t[expr {1 << 4}]\nset\t\tAT91_SDRAMC_CAS\t\t[expr {3 << 5}]\t\t;# CAS Latency\nset\t\t\tAT91_SDRAMC_CAS_1\t[expr {1 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_2\t[expr {2 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_3\t[expr {3 << 5}]\nset\t\tAT91_SDRAMC_DBW\t\t[expr {1 << 7}]\t\t;# Data Bus Width\nset\t\t\tAT91_SDRAMC_DBW_32\t[expr {0 << 7}]\nset\t\t\tAT91_SDRAMC_DBW_16\t[expr {1 << 7}]\nset\t\tAT91_SDRAMC_TWR\t\t[expr {0xf <<  8}]\t\t;# Write Recovery Delay\nset\t\tAT91_SDRAMC_TRC\t\t[expr {0xf << 12}]\t\t;# Row Cycle Delay\nset\t\tAT91_SDRAMC_TRP\t\t[expr {0xf << 16}]\t\t;# Row Precharge Delay\nset\t\tAT91_SDRAMC_TRCD\t[expr {0xf << 20}]\t\t;# Row to Column Delay\nset\t\tAT91_SDRAMC_TRAS\t[expr {0xf << 24}]\t\t;# Active to Precharge Delay\nset\t\tAT91_SDRAMC_TXSR\t[expr {0xf << 28}]\t\t;# Exit Self Refresh to Active Delay\n\nset AT91_SDRAMC_LPR\t\t[expr {$AT91_SDRAMC + 0x10}]\t;# SDRAM Controller Low Power Register\nset\t\tAT91_SDRAMC_LPCB\t\t[expr {3 << 0}]\t;# Low-power Configurations\nset\t\t\tAT91_SDRAMC_LPCB_DISABLE\t\t0\nset\t\t\tAT91_SDRAMC_LPCB_SELF_REFRESH\t\t1\nset\t\t\tAT91_SDRAMC_LPCB_POWER_DOWN\t\t2\nset\t\t\tAT91_SDRAMC_LPCB_DEEP_POWER_DOWN\t3\nset\t\tAT91_SDRAMC_PASR\t\t[expr {7 << 4}]\t;# Partial Array Self Refresh\nset\t\tAT91_SDRAMC_TCSR\t\t[expr {3 << 8}]\t;# Temperature Compensated Self Refresh\nset\t\tAT91_SDRAMC_DS\t\t\t[expr {3 << 10}]\t;# Drive Strength\nset\t\tAT91_SDRAMC_TIMEOUT\t\t[expr {3 << 12}]\t;# Time to define when Low Power Mode is enabled\nset\t\t\tAT91_SDRAMC_TIMEOUT_0_CLK_CYCLES\t[expr {0 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_64_CLK_CYCLES\t[expr {1 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_128_CLK_CYCLES\t[expr {2 << 12}]\n\nset AT91_SDRAMC_IER\t\t[expr {$AT91_SDRAMC + 0x14}]\t;# SDRAM Controller Interrupt Enable Register\nset AT91_SDRAMC_IDR\t\t[expr {$AT91_SDRAMC + 0x18}]\t;# SDRAM Controller Interrupt Disable Register\nset AT91_SDRAMC_IMR\t\t[expr {$AT91_SDRAMC + 0x1C}]\t;# SDRAM Controller Interrupt Mask Register\nset AT91_SDRAMC_ISR\t\t[expr {$AT91_SDRAMC + 0x20}]\t;# SDRAM Controller Interrupt Status Register\nset\t\tAT91_SDRAMC_RES\t\t[expr {1 << 0}]\t\t;# Refresh Error Status\n\nset AT91_SDRAMC_MDR\t\t[expr {$AT91_SDRAMC + 0x24}]\t;# SDRAM Memory Device Register\nset\t\tAT91_SDRAMC_MD\t\t[expr {3 << 0}]\t\t;# Memory Device Type\nset\t\t\tAT91_SDRAMC_MD_SDRAM\t\t0\nset\t\t\tAT91_SDRAMC_MD_LOW_POWER_SDRAM\t1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_smc.cfg",
    "content": "set\t\tAT91_SMC_READMODE\t[expr {1 <<  0}]\t\t;# Read Mode\nset\t\tAT91_SMC_WRITEMODE\t[expr {1 <<  1}]\t\t;# Write Mode\nset\t\tAT91_SMC_EXNWMODE\t[expr {3 <<  4}]\t\t;# NWAIT Mode\nset\t\t\tAT91_SMC_EXNWMODE_DISABLE\t[expr {0 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_FROZEN\t[expr {2 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_READY\t\t[expr {3 << 4}]\nset\t\tAT91_SMC_BAT\t\t[expr {1 <<  8}]\t\t;# Byte Access Type\nset\t\t\tAT91_SMC_BAT_SELECT\t\t[expr {0 << 8}]\nset\t\t\tAT91_SMC_BAT_WRITE\t\t[expr {1 << 8}]\nset\t\tAT91_SMC_DBW\t\t[expr {3 << 12}]\t\t;# Data Bus Width */\nset\t\t\tAT91_SMC_DBW_8\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_SMC_DBW_16\t\t\t[expr {1 << 12}]\nset\t\t\tAT91_SMC_DBW_32\t\t\t[expr {2 << 12}]\nset\t\tAT91_SMC_TDFMODE\t[expr {1 << 20}]\t\t;# TDF Optimization - Enabled\nset\t\tAT91_SMC_PMEN\t\t[expr {1 << 24}]\t\t;# Page Mode Enabled\nset\t\tAT91_SMC_PS\t\t[expr {3 << 28}]\t\t;# Page Size\nset\t\t\tAT91_SMC_PS_4\t\t\t[expr {0 << 28}]\nset\t\t\tAT91_SMC_PS_8\t\t\t[expr {1 << 28}]\nset\t\t\tAT91_SMC_PS_16\t\t\t[expr {2 << 28}]\nset\t\t\tAT91_SMC_PS_32\t\t\t[expr {3 << 28}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/hardware.cfg",
    "content": "# External Memory Map\nset AT91_CHIPSELECT_0\t0x10000000\nset AT91_CHIPSELECT_1\t0x20000000\nset AT91_CHIPSELECT_2\t0x30000000\nset AT91_CHIPSELECT_3\t0x40000000\nset AT91_CHIPSELECT_4\t0x50000000\nset AT91_CHIPSELECT_5\t0x60000000\nset AT91_CHIPSELECT_6\t0x70000000\nset AT91_CHIPSELECT_7\t0x80000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/pmc.tcl",
    "content": "\nif [info exists AT91C_MAINOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 18.432mhz is a common thing...\n    set AT91C_MAINOSC_FREQ 18432000\n}\nglobal AT91C_MAINOSC_FREQ\n\nif [info exists AT91C_SLOWOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 32khz is the norm\n    set AT91C_SLOWOSC_FREQ 32768\n}\nglobal AT91C_SLOWOSC_FREQ\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/rtt.tcl",
    "content": "\nset RTTC_RTMR [expr {$AT91C_BASE_RTTC + 0x00}]\nset RTTC_RTAR [expr {$AT91C_BASE_RTTC + 0x04}]\nset RTTC_RTVR [expr {$AT91C_BASE_RTTC + 0x08}]\nset RTTC_RTSR [expr {$AT91C_BASE_RTTC + 0x0c}]\nglobal RTTC_RTMR\nglobal RTTC_RTAR\nglobal RTTC_RTVR\nglobal RTTC_RTSR\n\nproc show_RTTC_RTMR_helper { NAME ADDR VAL } {\n    set rtpres [expr {$VAL & 0x0ffff}]\n    global BIT16 BIT17\n    if { $rtpres == 0 } {\n\tset rtpres 65536;\n    }\n    global AT91C_SLOWOSC_FREQ\n    # Nasty hack, make this a float by tacking a .0 on the end\n    # otherwise, jim makes the value an integer\n    set f [expr \"$AT91C_SLOWOSC_FREQ.0 / $rtpres.0\"]\n    echo [format \"\\tPrescale value: 0x%04x (%5d) => %f Hz\" $rtpres $rtpres $f]\n    if { $VAL & $BIT16 } {\n\techo \"\\tBit16 -> Alarm IRQ Enabled\"\n    } else {\n\techo \"\\tBit16 -> Alarm IRQ Disabled\"\n    }\n    if { $VAL & $BIT17 } {\n\techo \"\\tBit17 -> RTC Inc IRQ Enabled\"\n    } else {\n\techo \"\\tBit17 -> RTC Inc IRQ Disabled\"\n    }\n    # Bit 18 is write only.\n}\n\nproc show_RTTC_RTSR_helper { NAME ADDR VAL } {\n    global BIT0 BIT1\n    if { $VAL & $BIT0 } {\n\techo \"\\tBit0 -> ALARM PENDING\"\n    } else {\n\techo \"\\tBit0 -> alarm not pending\"\n    }\n    if { $VAL & $BIT1 } {\n\techo \"\\tBit0 -> RTINC PENDING\"\n    } else {\n\techo \"\\tBit0 -> rtinc not pending\"\n    }\n}\n\nproc show_RTTC { } {\n\n    show_mmr32_reg RTTC_RTMR\n    show_mmr32_reg RTTC_RTAR\n    show_mmr32_reg RTTC_RTVR\n    show_mmr32_reg RTTC_RTSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/sam9_smc.cfg",
    "content": "# Setup register\n#\n# ncs_read_setup\n# nrd_setup\n# ncs_write_setup\n# set nwe_setup\n#\n#\n# Pulse register\n#\n# ncs_read_pulse\n# nrd_pulse\n# ncs_write_pulse\n# nwe_pulse\n#\n#\n# Cycle register\n#\n# read_cycle 0\n# write_cycle 0\n#\n#\n# Mode register\n#\n# mode\n# tdf_cycles\nproc sam9_smc_config { cs smc_config } {\n\t;# Setup Register for CS n\n\tset AT91_SMC_SETUP [expr {$::AT91_SMC + 0x00 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_setup) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_setup) << 8}]\n\tset val [expr {$val | $smc_config(nrd_setup)) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_setup) << 24}]\n\tmww $AT91_SMC_SETUP $val\n\n\t;# Pulse Register for CS n\n\tset AT91_SMC_PULSE [expr {$::AT91_SMC + 0x04 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_pulse) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_pulse) << 8}]\n\tset val [expr {$val | $smc_config(nrd_pulse) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_pulse) << 24}]\n\tmww $AT91_SMC_PULSE $val\n\n\t;# Cycle Register for CS n\n\tset AT91_SMC_CYCLE [expr {$::AT91_SMC + 0x08 + $cs * 0x10}]\n\tset val [expr {$smc_config(write_cycle) << 0}]\n\tset val [expr {$val | $smc_config(read_cycle) << 16}]\n\tmww $AT91_SMC_CYCLE $val\n\n\t;# Mode Register for CS n\n\tset AT91_SMC_MODE [expr {$::AT91_SMC + 0x0c + $cs * 0x10}]\n\tset val [expr {$smc_config(mode) << 0}]\n\tset val [expr {$val | $smc_config(tdf_cycles) << 16}]\n\tmww $AT91_SMC_MODE $val\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/atmel/at91/usarts.tcl",
    "content": "# the DBGU and USARTs are 'almost' indentical'\nset DBGU_CR         [expr {$AT91C_BASE_DBGU + 0x00000000}]\nset DBGU_MR         [expr {$AT91C_BASE_DBGU + 0x00000004}]\nset DBGU_IER        [expr {$AT91C_BASE_DBGU + 0x00000008}]\nset DBGU_IDR        [expr {$AT91C_BASE_DBGU + 0x0000000C}]\nset DBGU_IMR        [expr {$AT91C_BASE_DBGU + 0x00000010}]\nset DBGU_CSR        [expr {$AT91C_BASE_DBGU + 0x00000014}]\nset DBGU_RHR        [expr {$AT91C_BASE_DBGU + 0x00000018}]\nset DBGU_THR        [expr {$AT91C_BASE_DBGU + 0x0000001C}]\nset DBGU_BRGR       [expr {$AT91C_BASE_DBGU + 0x00000020}]\n# no RTOR\n# no TTGR\n# no FIDI\n# no NER\nset DBGU_CIDR       [expr {$AT91C_BASE_DBGU + 0x00000040}]\nset DBGU_EXID       [expr {$AT91C_BASE_DBGU + 0x00000044}]\nset DBGU_FNTR       [expr {$AT91C_BASE_DBGU + 0x00000048}]\n\n\nset USx_CR           0x00000000\nset USx_MR           0x00000004\nset USx_IER          0x00000008\nset USx_IDR          0x0000000C\nset USx_IMR          0x00000010\nset USx_CSR          0x00000014\nset USx_RHR          0x00000018\nset USx_THR          0x0000001C\nset USx_BRGR         0x00000020\nset USx_RTOR         0x00000024\nset USx_TTGR         0x00000028\nset USx_FIDI         0x00000040\nset USx_NER          0x00000044\nset USx_IF           0x0000004C\n\n# Create all the uarts that exist..\n# we blow up if there are >9\n\n\nproc show_mmr_USx_MR_helper { NAME ADDR VAL } {\n    # First - just print it\n\n    set x [show_normalize_bitfield $VAL 3 0]\n    if { $x == 0 } {\n\techo \"\\tNormal operation\"\n    } else {\n\techo [format \"\\tNon Normal operation mode: 0x%02x\" $x]\n    }\n\n    set x [show_normalize_bitfield $VAL 11 9]\n    set s \"unknown\"\n    switch -exact $x {\n\t0 { set s \"Even\" }\n\t1 { set s \"Odd\" }\n\t2 { set s \"Force=0\" }\n\t3 { set s \"Force=1\" }\n\t* {\n\t    set $x [expr {$x & 6}]\n\t    switch -exact $x {\n\t\t4 { set s \"None\" }\n\t\t6 { set s \"Multidrop Mode\" }\n\t    }\n\t}\n    }\n    echo [format \"\\tParity: %s \" $s]\n\n    set x [expr {5 + [show_normalize_bitfield $VAL 7 6]}]\n    echo [format \"\\tDatabits: %d\" $x]\n\n    set x [show_normalize_bitfield $VAL 13 12]\n    switch -exact $x {\n\t0 { echo \"\\tStop bits: 1\" }\n\t1 { echo \"\\tStop bits: 1.5\" }\n\t2 { echo \"\\tStop bits: 2\" }\n\t3 { echo \"\\tStop bits: Illegal/Reserved\" }\n    }\n}\n\n# For every possbile usart...\nforeach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } {\n    set n AT91C_BASE_[set WHO]\n    set str \"\"\n\n    # Only if it exists on the chip\n    if [ info exists $n ] {\n\t# Hence: $n - is like AT91C_BASE_USx\n\t# For every sub-register\n\tforeach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF}\t{\n\t    # vn = variable name\n\t    set vn [set WHO]_[set REG]\n\t    # vn = USx_IER\n\t    # vv = variable value\n\t    set vv [expr \"$$n + [set USx_[set REG]]\"]\n\t    # And VV is the address in memory of that register\n\n\n\t    # make that VN a GLOBAL so others can find it\n\t    global $vn\n\t    set $vn $vv\n\n\t    # Create a command for this specific register.\n\t    proc show_$vn { } \"show_mmr32_reg $vn\"\n\n\t    # Add this command to the Device(as a whole) command\n\t    set str \"$str\\nshow_$vn\"\n\t}\n\t# Now - create the DEVICE(as a whole) command\n\tset fn show_$WHO\n\tproc $fn { } $str\n    }\n}\n\n# The Debug Uart is special..\nset str \"\"\n\n\n# For every sub-register\nforeach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR\n    DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} {\n\n    # Create a command for this specific register.\n    proc show_$REG { } \"show_mmr32_reg $REG\"\n\n    # Add this command to the Device(as a whole) command\n    set str \"$str\\nshow_$REG\"\n}\n\n# Now - create the DEVICE(as a whole) command\nproc show_DBGU { } $str\n\nunset str\n\nproc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/spear/quirk_no_srst.tcl",
    "content": "# Quirks to bypass missing SRST on JTAG connector\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# For boards that have JTAG SRST not connected.\n# We use \"arm9 vector_catch reset\" to catch button reset event.\n\n\n$_TARGETNAME configure -event reset-assert sp_reset_assert\n$_TARGETNAME configure -event reset-deassert-post sp_reset_deassert_post\n\n# keeps the name of the SPEAr target\nglobal sp_target_name\nset sp_target_name $_TARGETNAME\n\n# Keeps the argument of \"reset\" command (run, init, halt).\nglobal sp_reset_mode\nset sp_reset_mode \"\"\n\n# Helper procedure. Returns 0 is target is halted.\nproc sp_is_halted {} {\n\tglobal sp_target_name\n\n\treturn [expr {[string compare [$sp_target_name curstate] \"halted\" ] == 0}]\n}\n\n# wait for reset button to be pressed, causing CPU to get halted\nproc sp_reset_deassert_post {} {\n\tglobal sp_reset_mode\n\n\tset bar(0) |\n\tset bar(1) /\n\tset bar(2) -\n\tset bar(3) \\\\\n\n\tpoll on\n\techo \"====> Press reset button on the board <====\"\n\tfor {set i 0} { [sp_is_halted] == 0 } { set i [expr {$i + 1}]} {\n\t\techo -n \"$bar([expr {$i & 3}])\\r\"\n\t\tsleep 200\n\t}\n\n\t# Remove catch reset event\n\tarm9 vector_catch none\n\n\t# CPU is halted, but we typed \"reset run\" ...\n\tif { [string compare $sp_reset_mode \"run\"] == 0 } {\n\t\tresume\n\t}\n}\n\n# Override reset-assert, since no SRST available\n# Catch reset event\nproc sp_reset_assert {} {\n\tarm9 vector_catch reset\n}\n\n# Override default init_reset{mode} to catch parameter \"mode\"\nproc init_reset {mode} {\n\tglobal sp_reset_mode\n\n\tset sp_reset_mode $mode\n\n\t# We need to detect CPU get halted, so exit from halt\n\tif { [sp_is_halted] } {\n\t\techo \"Resuming CPU to detect reset\"\n\t\tresume\n\t}\n\n\t# Execute default init_reset{mode}\n\tjtag arp_init-reset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/spear/spear3xx.tcl",
    "content": "# Generic init scripts for all ST SPEAr3xx family\n# http://www.st.com/spear\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Initialize internal clock\n# Default:\n# - Crystal =  24 MHz\n# - PLL1    = 332 MHz\n# - PLL2    = 332 MHz\n# - CPU_CLK = 332 MHz\n# - DDR_CLK = 332 MHz async\n# - HCLK    = 166 MHz\n# - PCLK    =  83 MHz\nproc sp3xx_clock_default {} {\n\tmww 0xfca00000 0x00000002\t;# set sysclk slow\n\tmww 0xfca00014 0x0ffffff8\t;# set pll timeout to minimum (100us ?!?)\n\n\t# DDRCORE disable to change frequency\n\tset val [expr {([mrw 0xfca8002c] & ~0x20000000) | 0x40000000}]\n\tmww 0xfca8002c $val\n\tmww 0xfca8002c $val ;# Yes, write twice!\n\n\t# programming PLL1\n\tmww 0xfca8000c 0xa600010c\t;# M=166 P=1 N=12\n\tmww 0xfca80008 0x00001c0a\t;# power down\n\tmww 0xfca80008 0x00001c0e\t;# enable\n\tmww 0xfca80008 0x00001c06\t;# strobe\n\tmww 0xfca80008 0x00001c0e\n\twhile { [expr {[mrw 0xfca80008] & 0x01}] == 0x00 } { sleep 1 }\n\n\t# programming PLL2\n\tmww 0xfca80018 0xa600010c\t;# M=166, P=1, N=12\n\tmww 0xfca80014 0x00001c0a\t;# power down\n\tmww 0xfca80014 0x00001c0e\t;# enable\n\tmww 0xfca80014 0x00001c06\t;# strobe\n\tmww 0xfca80014 0x00001c0e\n\twhile { [expr {[mrw 0xfca80014] & 0x01}] == 0x00 } { sleep 1 }\n\n\tmww 0xfca80028 0x00000082\t;# enable plltimeen\n\tmww 0xfca80024 0x00000511\t;# set hclkdiv=\"/2\" & pclkdiv=\"/2\"\n\n\tmww 0xfca00000 0x00000004\t;# setting SYSCTL to NORMAL mode\n\twhile { [expr {[mrw 0xfca00000] & 0x20}] != 0x20 } { sleep 1 }\n\n\t# Select source of DDR clock\n\t#mmw 0xfca80020 0x10000000 0x70000000 ;# PLL1\n\tmmw 0xfca80020 0x30000000 0x70000000 ;# PLL2\n\n\t# DDRCORE enable after change frequency\n\tmmw 0xfca8002c 0x20000000 0x00000000\n}\n\nproc sp3xx_common_init {} {\n\tmww 0xfca8002c 0xfffffff8\t;# enable clock of all peripherals\n\tmww 0xfca80038 0x00000000\t;# remove reset of all peripherals\n\n\tmww 0xfca80034 0x0000ffff\t;# enable all RAS clocks\n\tmww 0xfca80040 0x00000000\t;# remove all RAS resets\n\n\tmww 0xfca800e4 0x78000008\t;# COMP1V8_REG\n\tmww 0xfca800ec 0x78000008\t;# COMP3V3_REG\n\n\tmww 0xfc000000 0x10000f5f\t;# init SMI and set HW mode\n\tmww 0xfc000000 0x00000f5f\n\n\t# Initialize Bus Interconnection Matrix\n\t# All ports Round-Robin and lowest priority\n\tmww 0xfca8007c 0x80000007\n\tmww 0xfca80080 0x80000007\n\tmww 0xfca80084 0x80000007\n\tmww 0xfca80088 0x80000007\n\tmww 0xfca8008c 0x80000007\n\tmww 0xfca80090 0x80000007\n\tmww 0xfca80094 0x80000007\n\tmww 0xfca80098 0x80000007\n\tmww 0xfca8009c 0x80000007\n}\n\n\n# Specific init scripts for ST SPEAr300\nproc sp300_init {} {\n\tmww 0x99000000 0x00003fff\t;# RAS function enable\n}\n\n\n# Specific init scripts for ST SPEAr310\nproc sp310_init {} {\n\tmww 0xb4000008 0x00002ff4\t;# RAS function enable\n\n\tmww 0xfca80050 0x00000001\t;# Enable clk mem port 1\n\n\tmww 0xfca8013c 0x2f7bc210\t;# plgpio_pad_drv\n\tmww 0xfca80140 0x017bdef6\n}\n\nproc sp310_emi_init {} {\n\t# set EMI pad strength\n\tmmw 0xfca80134 0x0e000000 0x00000000\n\tmmw 0xfca80138 0x0e739ce7 0x00000000\n\tmmw 0xfca8013c 0x00039ce7 0x00000000\n\n\t# set safe EMI timing as in BootROM\n\t#mww 0x4f000000 0x0000000f\t;# tAP_0_reg\n\t#mww 0x4f000004 0x00000000\t;# tSDP_0_reg\n\t#mww 0x4f000008 0x000000ff\t;# tDPw_0_reg\n\t#mww 0x4f00000c 0x00000111\t;# tDPr_0_reg\n\t#mww 0x4f000010 0x00000002\t;# tDCS_0_reg\n\n\t# set fast EMI timing as in Linux\n\tmww 0x4f000000 0x00000010\t;# tAP_0_reg\n\tmww 0x4f000004 0x00000005\t;# tSDP_0_reg\n\tmww 0x4f000008 0x0000000a\t;# tDPw_0_reg\n\tmww 0x4f00000c 0x0000000a\t;# tDPr_0_reg\n\tmww 0x4f000010 0x00000005\t;# tDCS_0_re\n\n\t# 32bit wide, 8/16/32bit access\n\tmww 0x4f000014 0x0000000e\t;# control_0_reg\n\tmww 0x4f000094 0x0000003f\t;# ack_reg\n}\n\n\n# Specific init scripts for ST SPEAr320\nproc sp320_init {} {\n\tmww 0xb300000c 0xffffac04\t;# RAS function enable\n\tmww 0xb3000010 0x00000001\t;# RAS mode select\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/spear/spear3xx_ddr.tcl",
    "content": "# Init scripts to configure DDR controller of SPEAr3xx\n# http://www.st.com/spear\n# Original values taken from XLoader source code\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\nproc sp3xx_ddr_init {ddr_type {ddr_chips 1}} {\n\tif { $ddr_chips != 1 && $ddr_chips != 2 } {\n\t\terror \"Only 1 or 2 DDR chips permitted. Wrong value \"$ddr_chips\n\t}\n\n\tif { $ddr_type == \"mt47h64m16_3_333_cl5_async\" } {\n\t\tddr_spr3xx_mt47h64m16_3_333_cl5_async $ddr_chips\n\t\tset ddr_size 0x08000000\n\t## add here new DDR chip definition. Prototype:\n\t#} elseif { $ddr_type == \"?????\" } {\n\t#\t????? $ddr_chips\n\t#\tset ddr_size 0x?????\n\t} else {\n\t\terror \"sp3xx_ddr_init: unrecognized DDR type \"$ddr_type\n\t}\n\n\t# MPMC START\n\tmww 0xfc60001c 0x01000100\n\n\tif { $ddr_chips == 2 } {\n\t\techo [format \\\n\t\t\t\"Double chip DDR memory. Total memory size 0x%08x byte\" \\\n\t\t\t[expr {2 * $ddr_size}]]\n\t} else {\n\t\techo [format \\\n\t\t\t\"Single chip DDR memory. Memory size 0x%08x byte\" \\\n\t\t\t$ddr_size]\n\t}\n}\n\n\n# from Xloader file ddr/spr300_mt47h64m16_3_333_cl5_async.S\nproc ddr_spr3xx_mt47h64m16_3_333_cl5_async {ddr_chips} {\n\t# DDR_PAD_REG\n\tmww 0xfca800f0 0x00003aa5\n\n\t# Use \"1:2 sync\" only when DDR clock source is PLL1 and\n\t# HCLK is half of PLL1\n\tmww 0xfc600000 0x00000001\t;# MEMCTL_AHB_SET_00 # This is async\n\tmww 0xfc600004 0x00000000\t;# MEMCTL_AHB_SET_01\n#\tmww 0xfc600000 0x02020201\t;# MEMCTL_AHB_SET_00 # This is 1:2 sync\n#\tmww 0xfc600004 0x02020202\t;# MEMCTL_AHB_SET_01\n\n\tmww 0xfc600008 0x01000000\t;# MEMCTL_RFSH_SET_00\n\tmww 0xfc60000c 0x00000101\t;# MEMCTL_DLL_SET_00\n\tmww 0xfc600010 0x00000101\t;# MEMCTL_GP_00\n\tmww 0xfc600014 0x01000000\t;# MEMCTL_GP_01\n\tmww 0xfc600018 0x00010001\t;# MEMCTL_GP_02\n\tmww 0xfc60001c 0x00000100\t;# MEMCTL_GP_03\n\tmww 0xfc600020 0x00010001\t;# MEMCTL_GP_04\n\tif { $ddr_chips == 2 } {\n\t\tmww 0xfc600024 0x01020203\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x01000102\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000202\t;# MEMCTL_AHB_SET_02\n\t} else {\n\t\tmww 0xfc600024 0x00000201\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x02000001\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000201\t;# MEMCTL_AHB_SET_02\n\t}\n\tmww 0xfc600030 0x04040105\t;# MEMCTL_AHB_SET_03\n\tmww 0xfc600034 0x03030302\t;# MEMCTL_AHB_SET_04\n\tmww 0xfc600038 0x02040101\t;# MEMCTL_AHB_SET_05\n\tmww 0xfc60003c 0x00000002\t;# MEMCTL_AHB_SET_06\n\tmww 0xfc600044 0x03000405\t;# MEMCTL_DQS_SET_0\n\tmww 0xfc600048 0x03040002\t;# MEMCTL_TIME_SET_01\n\tmww 0xfc60004c 0x04000305\t;# MEMCTL_TIME_SET_02\n\tmww 0xfc600050 0x0505053f\t;# MEMCTL_AHB_RELPR_00\n\tmww 0xfc600054 0x05050505\t;# MEMCTL_AHB_RELPR_01\n\tmww 0xfc600058 0x04040405\t;# MEMCTL_AHB_RELPR_02\n\tmww 0xfc60005c 0x04040404\t;# MEMCTL_AHB_RELPR_03\n\tmww 0xfc600060 0x03030304\t;# MEMCTL_AHB_RELPR_04\n\tmww 0xfc600064 0x03030303\t;# MEMCTL_AHB_RELPR_05\n\tmww 0xfc600068 0x02020203\t;# MEMCTL_AHB_RELPR_06\n\tmww 0xfc60006c 0x02020202\t;# MEMCTL_AHB_RELPR_07\n\tmww 0xfc600070 0x01010102\t;# MEMCTL_AHB_RELPR_08\n\tmww 0xfc600074 0x01010101\t;# MEMCTL_AHB_RELPR_09\n\tmww 0xfc600078 0x00000001\t;# MEMCTL_AHB_RELPR_10\n\tmww 0xfc600088 0x0a0c0a00\t;# MEMCTL_DQS_SET_1\n\tmww 0xfc60008c 0x0000023f\t;# MEMCTL_GP_07\n\tmww 0xfc600090 0x00050a00\t;# MEMCTL_GP_08\n\tmww 0xfc600094 0x11000000\t;# MEMCTL_GP_09\n\tmww 0xfc600098 0x00001302\t;# MEMCTL_GP_10\n\tmww 0xfc60009c 0x00001c1c\t;# MEMCTL_DLL_SET_01\n\tmww 0xfc6000a0 0x7c000000\t;# MEMCTL_DQS_OUT_SHIFT\n\tmww 0xfc6000a4 0x005c0000\t;# MEMCTL_WR_DQS_SHIFT\n\tmww 0xfc6000a8 0x2b050e00\t;# MEMCTL_TIME_SET_03\n\tmww 0xfc6000ac 0x00640064\t;# MEMCTL_AHB_PRRLX_00\n\tmww 0xfc6000b0 0x00640064\t;# MEMCTL_AHB_PRRLX_01\n\tmww 0xfc6000b4 0x00000064\t;# MEMCTL_AHB_PRRLX_02\n\tmww 0xfc6000b8 0x00000000\t;# MEMCTL_OUTRANGE_LGTH\n\tmww 0xfc6000bc 0x00200020\t;# MEMCTL_AHB_RW_SET_00\n\tmww 0xfc6000c0 0x00200020\t;# MEMCTL_AHB_RW_SET_01\n\tmww 0xfc6000c4 0x00200020\t;# MEMCTL_AHB_RW_SET_02\n\tmww 0xfc6000c8 0x00200020\t;# MEMCTL_AHB_RW_SET_03\n\tmww 0xfc6000cc 0x00200020\t;# MEMCTL_AHB_RW_SET_04\n\tmww 0xfc6000d8 0x00000a24\t;# MEMCTL_TREF\n\tmww 0xfc6000dc 0x00000000\t;# MEMCTL_EMRS3_DATA\n\tmww 0xfc6000e0 0x5b1c00c8\t;# MEMCTL_TIME_SET_04\n\tmww 0xfc6000e4 0x00c8002e\t;# MEMCTL_TIME_SET_05\n\tmww 0xfc6000e8 0x00000000\t;# MEMCTL_VERSION\n\tmww 0xfc6000ec 0x0001046b\t;# MEMCTL_TINIT\n\tmww 0xfc6000f0 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_01\n\tmww 0xfc6000f4 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_02\n\tmww 0xfc600104 0x001c0000\t;# MEMCTL_DLL_DQS_DELAY_BYPASS_0\n\tmww 0xfc600108 0x0019001c\t;# MEMCTL_DLL_SET_02\n\tmww 0xfc60010c 0x00100000\t;# MEMCTL_DLL_SET_03\n\tmww 0xfc600110 0x001e007a\t;# MEMCTL_DQS_SET_2\n\tmww 0xfc600188 0x00000000\t;# MEMCTL_USER_DEF_REG_0\n\tmww 0xfc60018c 0x00000000\t;# MEMCTL_USER_DEF_REG_1\n\tmww 0xfc600190 0x01010001\t;# MEMCTL_GP_11\n\tmww 0xfc600194 0x01000000\t;# MEMCTL_GP_12\n\tmww 0xfc600198 0x00000001\t;# MEMCTL_GP_13\n\tmww 0xfc60019c 0x00400000\t;# MEMCTL_GP_14\n\tmww 0xfc6001a0 0x00000000\t;# MEMCTL_EMRS2_DATA_X\n\tmww 0xfc6001a4 0x00000000\t;# MEMCTL_LWPWR_CNT\n\tmww 0xfc6001a8 0x00000000\t;# MEMCTL_LWPWR_REG\n\tmww 0xfc6001ac 0x00860000\t;# MEMCTL_GP_15\n\tmww 0xfc6001b0 0x00000002\t;# MEMCTL_TPDEX\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/stm32/stm32.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/cortex_m3.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nsource [find chip/st/stm32/stm32_regs.tcl]\nsource [find chip/st/stm32/stm32_rcc.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/stm32/stm32_rcc.tcl",
    "content": "\nset RCC_CR            [expr {$RCC_BASE + 0x00}]\nset RCC_CFGR          [expr {$RCC_BASE + 0x04}]\nset RCC_CIR           [expr {$RCC_BASE + 0x08}]\nset RCC_APB2RSTR      [expr {$RCC_BASE + 0x0c}]\nset RCC_APB1RSTR      [expr {$RCC_BASE + 0x10}]\nset RCC_AHBENR        [expr {$RCC_BASE + 0x14}]\nset RCC_APB2ENR       [expr {$RCC_BASE + 0x18}]\nset RCC_APB1ENR       [expr {$RCC_BASE + 0x1c}]\nset RCC_BDCR          [expr {$RCC_BASE + 0x20}]\nset RCC_CSR           [expr {$RCC_BASE + 0x24}]\n\n\nproc show_RCC_CR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CR] } msg ] {\n\terror $msg\n    }\n\n    show_mmr_bitfield  0  0 $val HSI      { OFF ON }\n    show_mmr_bitfield  1  1 $val HSIRDY   { NOTRDY RDY  }\n    show_mmr_bitfield  7  3 $val HSITRIM  { _NUMBER_ }\n    show_mmr_bitfield 15  8 $val HSICAL   { _NUMBER_ }\n    show_mmr_bitfield 16 16 $val HSEON    { OFF ON }\n    show_mmr_bitfield 17 17 $val HSERDY   { NOTRDY RDY  }\n    show_mmr_bitfield 18 18 $val HSEBYP   { NOTBYPASSED BYPASSED }\n    show_mmr_bitfield 19 19 $val CSSON    { OFF ON }\n    show_mmr_bitfield 24 24 $val PLLON    { OFF ON }\n    show_mmr_bitfield 25 25 $val PLLRDY   { NOTRDY RDY }\n}\n\nproc show_RCC_CFGR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CFGR] } msg ] {\n\terror $msg\n    }\n\n\n    show_mmr_bitfield  1  0 $val  SW     { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  3  2 $val  SWS    { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  7  4 $val  HPRE   { sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_2 sysclk_div_4 sysclk_div_8 sysclk_div_16 sysclk_div_64 sysclk_div_128 sysclk_div_256 sysclk_div_512 }\n    show_mmr_bitfield 10  8 $val  PPRE1  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 13 11 $val  PPRE2  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 15 14 $val  ADCPRE { pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div2 pclk2_div4 pclk2_div8 pclk2_div16 }\n    show_mmr_bitfield 16 16 $val  PLLSRC { HSI_div_2 HSE }\n    show_mmr_bitfield 17 17 $val  PLLXTPRE { hse_div1 hse_div2 }\n    show_mmr_bitfield 21 18 $val  PLLMUL { x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x16 }\n    show_mmr_bitfield 22 22 $val  USBPRE { div1 div1_5 }\n    show_mmr_bitfield 26 24 $val  MCO    { none none none none SysClk HSI HSE PLL_div2 }\n}\n\n\nproc show_RCC_CIR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CIR] } msg ] {\n\terror $msg\n    }\n\n}\n\nproc show_RCC_APB2RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2RSTR] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB1RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1RSTR] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) uart5\n    set bits(19) uart4\n    set bits(18) uart3\n    set bits(17) uart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_AHBENR   { } {\n    if [ catch { set val [ show_mmr32_reg RCC_AHBENR  ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) xxx\n    set bits(14) xxx\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) xxx\n    set bits(10) sdio\n    set bits(9) xxx\n    set bits(8) fsmc\n    set bits(7) xxx\n    set bits(6) crce\n    set bits(5) xxx\n    set bits(4) flitf\n    set bits(3) xxx\n    set bits(2) sram\n    set bits(1) dma2\n    set bits(0) dma1\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB2ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_APB1ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) usart5\n    set bits(19) usart4\n    set bits(18) usart3\n    set bits(17) usart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_BDCR     { } {\n    if [ catch { set val [ show_mmr32_reg RCC_BDCR    ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lseon\n    set bits(1) lserdy\n    set bits(2) lsebyp\n    set bits(8) rtcsel0\n    set bits(9) rtcsel1\n    set bits(15) rtcen\n    set bits(16) bdrst\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_CSR      { } {\n    if [ catch { set val [ show_mmr32_reg RCC_CSR     ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lsion\n    set bits(1) lsirdy\n    set bits(24) rmvf\n    set bits(26) pin\n    set bits(27) por\n    set bits(28) sft\n    set bits(29) iwdg\n    set bits(30) wwdg\n    set bits(31) lpwr\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC { } {\n\n    show_RCC_CR\n    show_RCC_CFGR\n    show_RCC_CIR\n    show_RCC_APB2RSTR\n    show_RCC_APB1RSTR\n    show_RCC_AHBENR\n    show_RCC_APB2ENR\n    show_RCC_APB1ENR\n    show_RCC_BDCR\n    show_RCC_CSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/st/stm32/stm32_regs.tcl",
    "content": "# /* Peripheral and SRAM base address in the alias region */\nset PERIPH_BB_BASE        0x42000000\nset SRAM_BB_BASE          0x22000000\n\n# /*Peripheral and SRAM base address in the bit-band region */\nset SRAM_BASE             0x20000000\nset PERIPH_BASE           0x40000000\n\n# /*FSMC registers base address */\nset FSMC_R_BASE           0xA0000000\n\n# /*Peripheral memory map */\nset APB1PERIPH_BASE       [set PERIPH_BASE]\nset APB2PERIPH_BASE       [expr {$PERIPH_BASE + 0x10000}]\nset AHBPERIPH_BASE        [expr {$PERIPH_BASE + 0x20000}]\n\nset TIM2_BASE             [expr {$APB1PERIPH_BASE + 0x0000}]\nset TIM3_BASE             [expr {$APB1PERIPH_BASE + 0x0400}]\nset TIM4_BASE             [expr {$APB1PERIPH_BASE + 0x0800}]\nset TIM5_BASE             [expr {$APB1PERIPH_BASE + 0x0C00}]\nset TIM6_BASE             [expr {$APB1PERIPH_BASE + 0x1000}]\nset TIM7_BASE             [expr {$APB1PERIPH_BASE + 0x1400}]\nset RTC_BASE              [expr {$APB1PERIPH_BASE + 0x2800}]\nset WWDG_BASE             [expr {$APB1PERIPH_BASE + 0x2C00}]\nset IWDG_BASE             [expr {$APB1PERIPH_BASE + 0x3000}]\nset SPI2_BASE             [expr {$APB1PERIPH_BASE + 0x3800}]\nset SPI3_BASE             [expr {$APB1PERIPH_BASE + 0x3C00}]\nset USART2_BASE           [expr {$APB1PERIPH_BASE + 0x4400}]\nset USART3_BASE           [expr {$APB1PERIPH_BASE + 0x4800}]\nset UART4_BASE            [expr {$APB1PERIPH_BASE + 0x4C00}]\nset UART5_BASE            [expr {$APB1PERIPH_BASE + 0x5000}]\nset I2C1_BASE             [expr {$APB1PERIPH_BASE + 0x5400}]\nset I2C2_BASE             [expr {$APB1PERIPH_BASE + 0x5800}]\nset CAN_BASE              [expr {$APB1PERIPH_BASE + 0x6400}]\nset BKP_BASE              [expr {$APB1PERIPH_BASE + 0x6C00}]\nset PWR_BASE              [expr {$APB1PERIPH_BASE + 0x7000}]\nset DAC_BASE              [expr {$APB1PERIPH_BASE + 0x7400}]\n\nset AFIO_BASE             [expr {$APB2PERIPH_BASE + 0x0000}]\nset EXTI_BASE             [expr {$APB2PERIPH_BASE + 0x0400}]\nset GPIOA_BASE            [expr {$APB2PERIPH_BASE + 0x0800}]\nset GPIOB_BASE            [expr {$APB2PERIPH_BASE + 0x0C00}]\nset GPIOC_BASE            [expr {$APB2PERIPH_BASE + 0x1000}]\nset GPIOD_BASE            [expr {$APB2PERIPH_BASE + 0x1400}]\nset GPIOE_BASE            [expr {$APB2PERIPH_BASE + 0x1800}]\nset GPIOF_BASE            [expr {$APB2PERIPH_BASE + 0x1C00}]\nset GPIOG_BASE            [expr {$APB2PERIPH_BASE + 0x2000}]\nset ADC1_BASE             [expr {$APB2PERIPH_BASE + 0x2400}]\nset ADC2_BASE             [expr {$APB2PERIPH_BASE + 0x2800}]\nset TIM1_BASE             [expr {$APB2PERIPH_BASE + 0x2C00}]\nset SPI1_BASE             [expr {$APB2PERIPH_BASE + 0x3000}]\nset TIM8_BASE             [expr {$APB2PERIPH_BASE + 0x3400}]\nset USART1_BASE           [expr {$APB2PERIPH_BASE + 0x3800}]\nset ADC3_BASE             [expr {$APB2PERIPH_BASE + 0x3C00}]\n\nset SDIO_BASE             [expr {$PERIPH_BASE + 0x18000}]\n\nset DMA1_BASE             [expr {$AHBPERIPH_BASE + 0x0000}]\nset DMA1_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0008}]\nset DMA1_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x001C}]\nset DMA1_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0030}]\nset DMA1_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0044}]\nset DMA1_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0058}]\nset DMA1_Channel6_BASE    [expr {$AHBPERIPH_BASE + 0x006C}]\nset DMA1_Channel7_BASE    [expr {$AHBPERIPH_BASE + 0x0080}]\nset DMA2_BASE             [expr {$AHBPERIPH_BASE + 0x0400}]\nset DMA2_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0408}]\nset DMA2_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x041C}]\nset DMA2_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0430}]\nset DMA2_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0444}]\nset DMA2_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0458}]\nset RCC_BASE              [expr {$AHBPERIPH_BASE + 0x1000}]\nset CRC_BASE              [expr {$AHBPERIPH_BASE + 0x3000}]\n\n# /*Flash registers base address */\nset FLASH_R_BASE          [expr {$AHBPERIPH_BASE + 0x2000}]\n# /*Flash Option Bytes base address */\nset OB_BASE               0x1FFFF800\n\n# /*FSMC Bankx registers base address */\nset FSMC_Bank1_R_BASE     [expr {$FSMC_R_BASE + 0x0000}]\nset FSMC_Bank1E_R_BASE    [expr {$FSMC_R_BASE + 0x0104}]\nset FSMC_Bank2_R_BASE     [expr {$FSMC_R_BASE + 0x0060}]\nset FSMC_Bank3_R_BASE     [expr {$FSMC_R_BASE + 0x0080}]\nset FSMC_Bank4_R_BASE     [expr {$FSMC_R_BASE + 0x00A0}]\n\n# /*Debug MCU registers base address */\nset DBGMCU_BASE           0xE0042000\n\n# /*System Control Space memory map */\nset SCS_BASE              0xE000E000\n\nset SysTick_BASE          [expr {$SCS_BASE + 0x0010}]\nset NVIC_BASE             [expr {$SCS_BASE + 0x0100}]\nset SCB_BASE              [expr {$SCS_BASE + 0x0D00}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/ti/lm3s/lm3s.tcl",
    "content": "source [find chip/ti/lm3s/lm3s_regs.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/chip/ti/lm3s/lm3s_regs.tcl",
    "content": "#*****************************************************************************\n#\n# The following are defines for the System Control register addresses.\n#\n#*****************************************************************************\n\nset SYSCTL_DID0             0x400FE000  ;# Device Identification 0\nset SYSCTL_DID1             0x400FE004  ;# Device Identification 1\nset SYSCTL_DC0              0x400FE008  ;# Device Capabilities 0\nset SYSCTL_DC1              0x400FE010  ;# Device Capabilities 1\nset SYSCTL_DC2              0x400FE014  ;# Device Capabilities 2\nset SYSCTL_DC3              0x400FE018  ;# Device Capabilities 3\nset SYSCTL_DC4              0x400FE01C  ;# Device Capabilities 4\nset SYSCTL_DC5              0x400FE020  ;# Device Capabilities 5\nset SYSCTL_DC6              0x400FE024  ;# Device Capabilities 6\nset SYSCTL_DC7              0x400FE028  ;# Device Capabilities 7\nset SYSCTL_DC8              0x400FE02C  ;# Device Capabilities 8 ADC\n                                        ;# Channels\nset SYSCTL_PBORCTL          0x400FE030  ;# Brown-Out Reset Control\nset SYSCTL_LDOPCTL          0x400FE034  ;# LDO Power Control\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\nset SYSCTL_RIS              0x400FE050  ;# Raw Interrupt Status\nset SYSCTL_IMC              0x400FE054  ;# Interrupt Mask Control\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and\n                                        ;# Clear\nset SYSCTL_RESC             0x400FE05C  ;# Reset Cause\nset SYSCTL_RCC              0x400FE060  ;# Run-Mode Clock Configuration\nset SYSCTL_PLLCFG           0x400FE064  ;# XTAL to PLL Translation\nset SYSCTL_GPIOHSCTL        0x400FE06C  ;# GPIO High-Speed Control\nset SYSCTL_GPIOHBCTL        0x400FE06C  ;# GPIO High-Performance Bus\n                                        ;# Control\nset SYSCTL_RCC2             0x400FE070  ;# Run-Mode Clock Configuration 2\nset SYSCTL_MOSCCTL          0x400FE07C  ;# Main Oscillator Control\nset SYSCTL_RCGC0            0x400FE100  ;# Run Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_RCGC1            0x400FE104  ;# Run Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_RCGC2            0x400FE108  ;# Run Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_SCGC0            0x400FE110  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_SCGC1            0x400FE114  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_SCGC2            0x400FE118  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_DCGC0            0x400FE120  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 0\nset SYSCTL_DCGC1            0x400FE124  ;# Deep-Sleep Mode Clock Gating\n                                        ;# Control Register 1\nset SYSCTL_DCGC2            0x400FE128  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 2\nset SYSCTL_DSLPCLKCFG       0x400FE144  ;# Deep Sleep Clock Configuration\nset SYSCTL_CLKVCLR          0x400FE150  ;# Clock Verification Clear\nset SYSCTL_PIOSCCAL         0x400FE150  ;# Precision Internal Oscillator\n                                        ;# Calibration\nset SYSCTL_PIOSCSTAT        0x400FE154  ;# Precision Internal Oscillator\n                                        ;# Statistics\nset SYSCTL_LDOARST          0x400FE160  ;# Allow Unregulated LDO to Reset\n                                        ;# the Part\nset SYSCTL_I2SMCLKCFG       0x400FE170  ;# I2S MCLK Configuration\nset SYSCTL_DC9              0x400FE190  ;# Device Capabilities 9 ADC\n                                        ;# Digital Comparators\nset SYSCTL_NVMSTAT          0x400FE1A0  ;# Non-Volatile Memory Information\n\nset SYSCTL_RCC_USESYSDIV    0x00400000  ;# Enable System Clock Divider\nset SYSCTL_RCC2_BYPASS2     0x00000800  ;# PLL Bypass 2\nset SYSCTL_RCC_MOSCDIS      0x00000001  ;# Main Oscillator Disable\n\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\n\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and Clear\n\nset FLASH_FMA               0x400FD000  ;# Flash Memory Address\nset FLASH_FMD               0x400FD004  ;# Flash Memory Data\nset FLASH_FMC               0x400FD008  ;# Flash Memory Control\nset FLASH_FCRIS             0x400FD00C  ;# Flash Controller Raw Interrupt Status\nset FLASH_FCIM              0x400FD010  ;# Flash Controller Interrupt Mask\nset FLASH_FCMISC            0x400FD014  ;# Flash Controller Masked Interrupt Status and Clear\nset FLASH_FMC2              0x400FD020  ;#  Flash Memory Control 2\nset FLASH_FWBVAL            0x400FD030  ;# Flash Write Buffer Valid\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/altera-5m570z-cpld.cfg",
    "content": "# Altera MAXV 5M24OZ/5M570Z CPLD\n# see MAX V Device Handbook\n# Table 6-3: 32-Bit MAX V Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0111     000 0110 1110    1\njtag newtap 5m570z tap -expected-id 0x020a60dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/altera-epm240.cfg",
    "content": "# Altera MAXII EPM240T100C CPLD\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME epm240\n}\n\n# see MAX II Device Handbook\n# Table 3-3: 32-Bit MAX II Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0001     000 0110 1110    1\njtag newtap $_CHIPNAME tap -irlen 10 \\\n\t-expected-id 0x020a10dd \\\n\t-expected-id 0x020a20dd \\\n\t-expected-id 0x020a30dd \\\n\t-expected-id 0x020a40dd \\\n\t-expected-id 0x020a50dd \\\n\t-expected-id 0x020a60dd\n\n# 200ns seems like a good speed\n# c.f. Table 5-34: MAX II JTAG Timing Parameters\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/jtagspi.cfg",
    "content": "set _USER1 0x02\n\nif { [info exists JTAGSPI_IR] } {\n\tset _JTAGSPI_IR $JTAGSPI_IR\n} else {\n\tset _JTAGSPI_IR $_USER1\n}\n\nif { [info exists TARGETNAME] } {\n\tset _TARGETNAME $TARGETNAME\n} else {\n\tset _TARGETNAME $_CHIPNAME.proxy\n}\n\nif { [info exists FLASHNAME] } {\n\tset _FLASHNAME $FLASHNAME\n} else {\n\tset _FLASHNAME $_CHIPNAME.spi\n}\n\ntarget create $_TARGETNAME testee -chain-position $_CHIPNAME.tap\nflash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR\n\nproc jtagspi_init {chain_id proxy_bit} {\n\t# load proxy bitstream $proxy_bit and probe spi flash\n\tglobal _FLASHNAME\n\tpld load $chain_id $proxy_bit\n\treset halt\n\tflash probe $_FLASHNAME\n}\n\nproc jtagspi_program {bin addr} {\n\t# write and verify binary file $bin at offset $addr\n\tglobal _FLASHNAME\n\tflash write_image erase $bin $addr\n\tflash verify_bank $_FLASHNAME $bin $addr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/lattice-lc4032ze.cfg",
    "content": "# Lattice ispMACH 4000ZE family, device LC4032ZE\n# just configure a tap\njtag newtap LC4032ZE tap -irlen 8 -expected-id  0x01806043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xc6s.cfg",
    "content": "# xilinx spartan6\n# http://www.xilinx.com/support/documentation/user_guides/ug380.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc6s\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x04000093 \\\n\t-expected-id 0x04001093 \\\n\t-expected-id 0x04002093 \\\n\t-expected-id 0x04004093 \\\n\t-expected-id 0x04024093 \\\n\t-expected-id 0x04008093 \\\n\t-expected-id 0x04028093 \\\n\t-expected-id 0x0400E093 \\\n\t-expected-id 0x0402E093 \\\n\t-expected-id 0x04011093 \\\n\t-expected-id 0x04031093 \\\n\t-expected-id 0x0401D093 \\\n\t-expected-id 0x0403D093\n\npld device virtex2 $_CHIPNAME.tap\n\nset XC6S_CFG_IN 0x05\nset XC6S_JSHUTDOWN 0x0d\nset XC6S_JPROGRAM 0x0b\nset XC6S_JSTART 0x0c\nset XC6S_BYPASS 0x3f\n\nproc xc6s_program {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JPROGRAM XC6S_JSTART XC6S_BYPASS\n\tirscan $tap $XC6S_JSHUTDOWN\n\tirscan $tap $XC6S_JPROGRAM\n\tirscan $tap $XC6S_JSTART\n\tirscan $tap $XC6S_BYPASS\n}\n\n#xtp038 and xc3sprog approach\nproc xc6s_program_iprog {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JSTART XC6S_BYPASS XC6S_CFG_IN\n\tirscan $tap $XC6S_JSHUTDOWN\n\truntest 16\n\tirscan $tap $XC6S_CFG_IN\n\t# xtp038 IPROG 16bit flipped\n\tdrscan $tap 16 0xffff 16 0x9955 16 0x66aa 16 0x850c 16 0x7000 16 0x0004\n\tirscan $tap $XC6S_JSTART\n\truntest 32\n\tirscan $tap $XC6S_BYPASS\n\truntest 1\n}\n\nset XC6S_ISC_ENABLE 0x10\nset XC6S_ISC_DISABLE 0x16\nset XC6S_ISC_DNA 0x30\n\n# Get the \"Device DNA\" from the Spartan 6.\n# Most Xilinx FPGA devices contain an embedded, unique device identifier called\n# the \"Device DNA\". The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\nproc xc6s_get_dna {tap} {\n\tglobal XC6S_ISC_ENABLE XC6S_ISC_DISABLE XC6S_ISC_DNA\n\tirscan $tap $XC6S_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC6S_ISC_DNA\n\t# Device DNA is 57 bits long, but we can only read 32bits at a time\n\t# with OpenOCD.\n\tset dna [drscan $tap 16 0 16 0 16 0 9 0]\n\truntest 64\n\tirscan $tap $XC6S_ISC_DISABLE\n\truntest 64\n\n\t# Convert the binary data into the order impact uses\n\tscan $dna \"%x %x %x %x\" v1 v2 v3 v4\n\tset bin_dna [string reverse [concat [format \"%09b\" $v4][format \"%016b\" $v3][format \"%016b\" $v2][format \"%016b\" $v1]]]\n\n\t# Return a hex version of binary\n\tscan [format \"0b%s\" $bin_dna] \"%i\" hex_dna\n\treturn $hex_dna\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xc6s_print_dna {tap} {\n\tset hex_dna [xc6s_get_dna $tap]\n\n\tputs [format \"DNA = %57b (0x%x)\\n\" $hex_dna $hex_dna]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xc7.cfg",
    "content": "# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7\n}\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x03622093 \\\n\t-expected-id 0x03620093 \\\n\t-expected-id 0x037C4093 \\\n\t-expected-id 0x0362F093 \\\n\t-expected-id 0x037C8093 \\\n\t-expected-id 0x037C7093 \\\n\t-expected-id 0x037C3093 \\\n\t-expected-id 0x0362E093 \\\n\t-expected-id 0x037C2093 \\\n\t-expected-id 0x0362D093 \\\n\t-expected-id 0x0362C093 \\\n\t-expected-id 0x03632093 \\\n\t-expected-id 0x03631093 \\\n\t-expected-id 0x03636093 \\\n\t-expected-id 0x03647093 \\\n\t-expected-id 0x0364C093 \\\n\t-expected-id 0x03651093 \\\n\t-expected-id 0x03747093 \\\n\t-expected-id 0x03656093 \\\n\t-expected-id 0x03752093 \\\n\t-expected-id 0x03751093 \\\n\t-expected-id 0x03671093 \\\n\t-expected-id 0x036B3093 \\\n\t-expected-id 0x036B7093 \\\n\t-expected-id 0x036BB093 \\\n\t-expected-id 0x036BF093 \\\n\t-expected-id 0x03667093 \\\n\t-expected-id 0x03682093 \\\n\t-expected-id 0x03687093 \\\n\t-expected-id 0x03692093 \\\n\t-expected-id 0x03691093 \\\n\t-expected-id 0x03696093 \\\n\t-expected-id 0x036D5093 \\\n\t-expected-id 0x036D9093 \\\n\t-expected-id 0x036DB093\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc xc7_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xcf-p.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF08P <v>5057093\n# XCF16P <v>5058093\n# XCF32P <v>5059093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 16 -ignore-version \\\n\t-expected-id 0x05057093 \\\n\t-expected-id 0x05058093 \\\n\t-expected-id 0x05059093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_P xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xcf-s.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF01S <v>5044093\n# XCF02S <v>5045093\n# XCF04S <v>5046093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 8 -ignore-version \\\n\t-expected-id 0x05044093 \\\n\t-expected-id 0x05045093 \\\n\t-expected-id 0x05046093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_S xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xcr3256.cfg",
    "content": "#xilinx coolrunner xcr3256\n#simple device - just configure a tap\njtag newtap xcr tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id  0x0494c093\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpld/xilinx-xcu.cfg",
    "content": "# Xilinx Ultrascale (Kintex, Virtex, Zynq)\n# https://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcu\n}\n\n# The cvarious chips in the Ultrascale family have different IR length.\n# Set $CHIP before including this file to determine the device.\narray set _XCU_DATA {\n\tXCKU025 {0x03824093 6}\n\tXCKU035 {0x03823093 6}\n\tXCKU040 {0x03822093 6}\n\tXCKU060 {0x03919093 6}\n\tXCKU095 {0x03844093 6}\n\tXCKU3P {0x04A63093 6}\n\tXCKU5P {0x04A62093 6}\n\tXCKU9P {0x0484A093 6}\n\tXCKU11P {0x04A4E093 6}\n\tXCKU13P {0x04A52093 6}\n\tXCKU15P {0x04A56093 6}\n\tXCVU065 {0x03939093 6}\n\tXCVU080 {0x03843093 6}\n\tXCVU095 {0x03842093 6}\n\tXCVU3P {0x04B39093 6}\n\tXCKU085 {0x0380F093 12}\n\tXCKU115 {0x0390D093 12}\n\tXCVU125 {0x0392D093 12}\n\tXCVU5P {0x04B2B093 12}\n\tXCVU7P {0x04B29093 12}\n\tXCVU160 {0x03933093 18}\n\tXCVU190 {0x03931093 18}\n\tXCVU440 {0x0396D093 18}\n\tXCVU9P {0x04B31093 18}\n\tXCVU11P {0x04B49093 18}\n\tXCVU13P {0x04B51093 24}\n}\n\nif { ![info exists CHIP] } {\n\terror \"set CHIP to one of \"[concat [array names _XCU_DATA]]\n}\n\nif { ![llength [array names _XCU_DATA $CHIP]] } {\n\terror \"unknown CHIP: \"$CHIP\n}\n\nset _EXPID [lindex $_XCU_DATA($CHIP) 0]\nset _IRLEN [lindex $_XCU_DATA($CHIP) 1]\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen $_IRLEN -ignore-version -expected-id $_EXPID\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XCU_JSHUTDOWN 0x0d\nset XCU_JPROGRAM 0x0b\nset XCU_JSTART 0x0c\nset XCU_BYPASS 0x3f\n\nproc xcu_program {tap} {\n\tglobal XCU_JSHUTDOWN XCU_JPROGRAM XCU_JSTART XCU_BYPASS\n\tirscan $tap $XCU_JSHUTDOWN\n\tirscan $tap $XCU_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XCU_JSTART\n\truntest 2000\n\tirscan $tap $XCU_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arc/common.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Things common to all ARCs\n\n# It is assumed that target is already halted.\nproc arc_common_reset { {target \"\"} } {\n        if { $target != \"\" } {\n                targets $target\n        }\n\n        halt\n\n        # 1. Interrupts are disabled (STATUS32.IE)\n        # 2. The status register flags are cleared.\n        # All fields, except the H bit, are set to 0 when the processor is Reset.\n\n        arc jtag set-aux-reg 0xA 0x1\n\n        # 3. The loop count, loop start, and loop end registers are cleared.\n        arc jtag set-core-reg 60 0\n        arc jtag set-aux-reg 0x2 0\n        arc jtag set-aux-reg 0x3 0\n\n        # Program execution begins at the address referenced by the four byte reset\n        # vector located at the interrupt vector base address, which is the first\n        # entry (offset 0x00) in the vector table.\n        set int_vector_base [arc jtag get-aux-reg 0x25]\n        set start_pc [read_memory $int_vector_base 32 1]\n        arc jtag set-aux-reg 0x6 $start_pc\n\n        # It is OK to do uncached writes - register cache will be invalidated by\n        # the reset_assert() function.\n}\n\n# vim:expandtab:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arc/em.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_em_examine_target { {target \"\"} } {\n\t# Will set current target\n\tarc_v2_examine_target $target\n}\n\nproc arc_em_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_em_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_em_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Set DEBUG.ED bit to enable clock in actionpoint module.\n\t# This is specific to ARC EM.\n\tset debug [arc jtag get-aux-reg 5]\n\tif { !($debug & (1 << 20)) } {\n\t\tarc jtag set-aux-reg 5 [expr {$debug | (1 << 20)}]\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arc/hs.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_hs_examine_target { target } {\n\t# Will set current target for us.\n\tarc_v2_examine_target $target\n}\n\nproc arc_hs_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_hs_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_hs_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Invalidate L2 cache if there is one.\n\tset l2_config [$target arc jtag get-aux-reg 0x901]\n\t# Will return 0, if cache is not present and register doesn't exist.\n\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\tif { ($l2_config != 0) && (($l2_ctrl & 1) == 0) } {\n\t\tputs \"L2 cache is present and not disabled\"\n\n\t\t# Wait until BUSY bit is 0.\n\t\tputs \"Invalidating L2 cache...\"\n\t\t$target arc jtag set-aux-reg 0x905 1\n\t\t# Dummy read of SLC_AUX_CACHE_CTRL bit, as described in:\n\t\t# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/arch/arc?id=c70c473396cbdec1168a6eff60e13029c0916854\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\twhile { ($l2_ctrl & 0x100) != 0 } {\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t}\n\n\t\t# Flush cache if needed. If SLC_AUX_CACHE_CTRL.IM is 1, then invalidate\n\t\t# operation already flushed everything.\n\t\tif { ($l2_ctrl & 0x40) == 0 } {\n\t\t\tputs \"Flushing L2 cache...\"\n\t\t\t$target arc jtag set-aux-reg 0x904 1\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\twhile { [expr {$l2_ctrl & 0x100}] != 0 } {\n\t\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\t}\n\t\t}\n\n\t\tputs \"L2 cache has been flushed and invalidated.\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arc/v2.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/common.tcl]\n\n# Currently 'examine_target' can only read JTAG registers and set properties -\n# but it shouldn't write any of registers - writes will be cached, but cache\n# will be invalidated before flushing after examine_target, and changes will be\n# lost.  Perhaps that would be fixed later - perhaps writes shouldn't be cached\n# after all.  But if write to register is really needed from TCL - then it\n# should be done via \"arc jtag\" for now.\nproc arc_v2_examine_target { {target \"\"} } {\n\t# Set current target, because OpenOCD event handlers don't do this for us.\n\tif { $target != \"\" } {\n\t\ttargets $target\n\t}\n\n\t# Those registers always exist. DEBUG and DEBUGI are formally optional,\n\t# however they come with JTAG interface, and so far there is no way\n\t# OpenOCD can communicate with target without JTAG interface.\n\tarc set-reg-exists identity pc status32 bta debug lp_start lp_end \\\n\t\teret erbta erstatus ecr efa\n\n\t# 32 core registers\n\tarc set-reg-exists \\\n\t\tr0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r10 r11 r12 \\\n\t\tr13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 \\\n\t\tgp fp sp ilink r30 blink lp_count pcl\n\n\t# Actionpoints\n\tif { [arc get-reg-field ap_build version] == 5 } {\n\t\tset ap_build_type [arc get-reg-field ap_build type]\n\t\t# AP_BUILD.TYPE > 0b0110 is reserved in current ISA.\n\t\t# Current ISA supports up to 8 actionpoints.\n\t\tif { $ap_build_type < 8 } {\n\t\t\t# Two LSB bits of AP_BUILD.TYPE define amount of actionpoints:\n\t\t\t# 0b00 - 2 actionpoints\n\t\t\t# 0b01 - 4 actionpoints\n\t\t\t# 0b10 - 8 actionpoints\n\t\t\t# 0b11 - reserved.\n\t\t\tset ap_num [expr {0x2 << ($ap_build_type & 3)}]\n\t\t\t# Expression on top may produce 16 action points - which is a\n\t\t\t# reserved value for now.\n\t\t\tif { $ap_num < 16 } {\n\t\t\t\t# Enable actionpoint registers\n\t\t\t\tfor {set i 0} {$i < $ap_num} {incr i} {\n\t\t\t\t\tarc set-reg-exists ap_amv$i ap_amm$i ap_ac$i\n\t\t\t\t}\n\n\t\t\t\t# Set amount of actionpoints\n\t\t\t\tarc num-actionpoints $ap_num\n\t\t\t}\n\t\t}\n\t}\n\n\t# DCCM\n\tset dccm_version [arc get-reg-field dccm_build version]\n\tif { $dccm_version == 3 || $dccm_version == 4 } {\n\t\tarc set-reg-exists aux_dccm\n\t}\n\n\t# ICCM\n\tif { [arc get-reg-field iccm_build version] == 4 } {\n\t\tarc set-reg-exists aux_iccm\n\t}\n\n\t# MPU\n\tif { [arc get-reg-field mpu_build version] >= 2 &&\n\t\t [arc get-reg-field mpu_build version] <= 4 } {\n\t\tarc set-reg-exists mpu_en mpu_ecr\n\t\tset mpu_regions [arc get-reg-field mpu_build regions]\n\t\tfor {set i 0} {$i < $mpu_regions} {incr i} {\n\t\t\tarc set-reg-exists mpu_rdp$i mpu_rdb$i\n\t\t}\n\n\t\t# Secure MPU\n\t\tif { [arc get-reg-field mpu_build version] == 4 } {\n\t\t\tarc set-reg-exists mpu_index mpu_rstart mpu_rend mpu_rper\n\t\t}\n\t}\n}\n\nproc arc_v2_init_regs { } {\n\t# XML features\n\tset core_feature \"org.gnu.gdb.arc.core.v2\"\n\tset aux_min_feature \"org.gnu.gdb.arc.aux-minimal\"\n\tset aux_other_feature \"org.gnu.gdb.arc.aux-other\"\n\n\t# Describe types\n\t# Types are sorted alphabetically according to their name.\n\tarc add-reg-type-struct -name ap_build_t -bitfield version 0 7 \\\n\t\t-bitfield type 8 11\n\tarc add-reg-type-struct -name ap_control_t -bitfield at 0 3 -bitfield tt 4 5 \\\n\t\t-bitfield m 6 6 -bitfield p 7 7 -bitfield aa 8 8 -bitfield q 9 9\n\t# Cycles field added in version 4.\n\tarc add-reg-type-struct -name dccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield size0 8 11 -bitfield size1 12 15 -bitfield cycles 17 19\n\n\tarc add-reg-type-struct -name debug_t \\\n\t\t-bitfield fh 1 1   -bitfield ah 2 2   -bitfield asr 3 10 \\\n\t\t-bitfield is 11 11 -bitfield ep 19 19 -bitfield ed 20 20 \\\n\t\t-bitfield eh 21 21 -bitfield ra 22 22 -bitfield zz 23 23 \\\n\t\t-bitfield sm 24 26 -bitfield ub 28 28 -bitfield bh 29 29 \\\n\t\t-bitfield sh 30 30 -bitfield ld 31 31\n\n\tarc add-reg-type-struct -name ecr_t \\\n\t\t-bitfield parameter 0 7 \\\n\t\t-bitfield cause 8 15 \\\n\t\t-bitfield vector 16 23 \\\n\t\t-bitfield U 30 30 \\\n\t\t-bitfield P 31 31\n\tarc add-reg-type-struct -name iccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield iccm0_size0  8 11 -bitfield iccm1_size0 12 15 \\\n\t\t-bitfield iccm0_size1 16 19 -bitfield iccm1_size1 20 23\n\tarc add-reg-type-struct -name identity_t \\\n\t\t-bitfield arcver 0 7 -bitfield arcnum 8 15 -bitfield chipid 16 31\n\tarc add-reg-type-struct -name isa_config_t -bitfield version 0 7 \\\n\t\t-bitfield pc_size 8 11 -bitfield lpc_size 12 15 -bitfield addr_size 16 19 \\\n\t\t-bitfield b 20 20 -bitfield a 21 21 -bitfield n 22 22 -bitfield l 23 23 \\\n\t\t-bitfield c 24 27 -bitfield d 28 31\n\tarc add-reg-type-struct -name mpu_build_t -bitfield version 0 7 \\\n\t\t-bitfield regions 8 15 \\\n\t\t-bitfield s 16 16 \\\n\t\t-bitfield i 17 17\n\tarc add-reg-type-struct -name mpu_ecr_t \\\n\t\t-bitfield MR 0 7 \\\n\t\t-bitfield VT 8 9 \\\n\t\t-bitfield EC_CODE 16 31\n\tarc add-reg-type-struct -name mpu_en_t \\\n\t\t-bitfield UE  3  3 -bitfield UW   4  4 -bitfield UR 5 5 \\\n\t\t-bitfield KE  6  6 -bitfield KW   7  7 -bitfield KR 8 8 \\\n\t\t-bitfield S  15 15 -bitfield SID 16 23 \\\n\t\t-bitfield EN 30 30\n\tarc add-reg-type-struct -name mpu_index_t \\\n\t\t-bitfield I 0 3 -bitfield M 30 30 -bitfield D 31 31\n\tarc add-reg-type-struct -name mpu_rper_t \\\n\t\t-bitfield V 0 0 \\\n\t\t-bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \\\n\t\t-bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \\\n\t\t-bitfield S 15 15 -bitfield SID 16 23\n\tarc add-reg-type-flags -name status32_t \\\n\t\t-flag   H  0 -flag E0   1 -flag E1   2 -flag E2  3 \\\n\t\t-flag  E3  4 -flag AE   5 -flag DE   6 -flag  U  7 \\\n\t\t-flag   V  8 -flag  C   9 -flag  N  10 -flag  Z 11 \\\n\t\t-flag   L 12 -flag DZ  13 -flag SC  14 -flag ES 15 \\\n\t\t-flag RB0 16 -flag RB1 17 -flag RB2 18 \\\n\t\t-flag  AD 19 -flag US  20 -flag IE  31\n\n\t# Core registers\n\tset core_regs {\n\t\tr0       0  uint32\n\t\tr1       1  uint32\n\t\tr2       2  uint32\n\t\tr3       3  uint32\n\t\tr4       4  uint32\n\t\tr5       5  uint32\n\t\tr6       6  uint32\n\t\tr7       7  uint32\n\t\tr8       8  uint32\n\t\tr9       9  uint32\n\t\tr10      10 uint32\n\t\tr11      11 uint32\n\t\tr12      12 uint32\n\t\tr13      13 uint32\n\t\tr14      14 uint32\n\t\tr15      15 uint32\n\t\tr16      16 uint32\n\t\tr17      17 uint32\n\t\tr18      18 uint32\n\t\tr19      19 uint32\n\t\tr20      20 uint32\n\t\tr21      21 uint32\n\t\tr22      23 uint32\n\t\tr23      24 uint32\n\t\tr24      24 uint32\n\t\tr25      25 uint32\n\t\tgp       26 data_ptr\n\t\tfp       27 data_ptr\n\t\tsp       28 data_ptr\n\t\tilink    29 code_ptr\n\t\tr30      30 uint32\n\t\tblink    31 code_ptr\n\t\tr32      32 uint32\n\t\tr33      33 uint32\n\t\tr34      34 uint32\n\t\tr35      35 uint32\n\t\tr36      36 uint32\n\t\tr37      37 uint32\n\t\tr38      38 uint32\n\t\tr39      39 uint32\n\t\tr40      40 uint32\n\t\tr41      41 uint32\n\t\tr42      42 uint32\n\t\tr43      43 uint32\n\t\tr44      44 uint32\n\t\tr45      45 uint32\n\t\tr46      46 uint32\n\t\tr47      47 uint32\n\t\tr48      48 uint32\n\t\tr49      49 uint32\n\t\tr50      50 uint32\n\t\tr51      51 uint32\n\t\tr52      52 uint32\n\t\tr53      53 uint32\n\t\tr54      54 uint32\n\t\tr55      55 uint32\n\t\tr56      56 uint32\n\t\tr57      57 uint32\n\t\taccl     58 uint32\n\t\tacch     59 uint32\n\t\tlp_count 60 uint32\n\t\tlimm     61 uint32\n\t\treserved 62 uint32\n\t\tpcl      63 code_ptr\n\t}\n\tforeach {reg count type} $core_regs {\n\t\tarc add-reg -name $reg -num $count -core -type $type -g \\\n\t\t\t-feature $core_feature\n\t}\n\n\t# AUX min\n\tset aux_min {\n\t\t0x6 pc       code_ptr\n\t\t0x2 lp_start code_ptr\n\t\t0x3 lp_end   code_ptr\n\t\t0xA status32 status32_t\n\t}\n\tforeach {num name type} $aux_min {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_min_feature -g\n\t}\n\n\t# AUX other\n\tset aux_other {\n\t\t0x004 identity\tidentity_t\n\t\t0x005 debug\t\tdebug_t\n\t\t0x018 aux_dccm\tint\n\t\t0x208 aux_iccm\tint\n\n\t\t0x220 ap_amv0\tuint32\n\t\t0x221 ap_amm0\tuint32\n\t\t0x222 ap_ac0\tap_control_t\n\t\t0x223 ap_amv1\tuint32\n\t\t0x224 ap_amm1\tuint32\n\t\t0x225 ap_ac1\tap_control_t\n\t\t0x226 ap_amv2\tuint32\n\t\t0x227 ap_amm2\tuint32\n\t\t0x228 ap_ac2\tap_control_t\n\t\t0x229 ap_amv3\tuint32\n\t\t0x22A ap_amm3\tuint32\n\t\t0x22B ap_ac3\tap_control_t\n\t\t0x22C ap_amv4\tuint32\n\t\t0x22D ap_amm4\tuint32\n\t\t0x22E ap_ac4\tap_control_t\n\t\t0x22F ap_amv5\tuint32\n\t\t0x230 ap_amm5\tuint32\n\t\t0x231 ap_ac5\tap_control_t\n\t\t0x232 ap_amv6\tuint32\n\t\t0x233 ap_amm6\tuint32\n\t\t0x234 ap_ac6\tap_control_t\n\t\t0x235 ap_amv7\tuint32\n\t\t0x236 ap_amm7\tuint32\n\t\t0x237 ap_ac7\tap_control_t\n\n\t\t0x400 eret\t\tcode_ptr\n\t\t0x401 erbta\t\tcode_ptr\n\t\t0x402 erstatus\tstatus32_t\n\t\t0x403 ecr\t\tecr_t\n\t\t0x404 efa\t\tdata_ptr\n\n\t\t0x409 mpu_en\tmpu_en_t\n\n\t\t0x412 bta\t\tcode_ptr\n\n\t\t0x420 mpu_ecr\tmpu_ecr_t\n\t\t0x422 mpu_rdb0\tint\n\t\t0x423 mpu_rdp0\tint\n\t\t0x424 mpu_rdb1\tint\n\t\t0x425 mpu_rdp1\tint\n\t\t0x426 mpu_rdb2\tint\n\t\t0x427 mpu_rdp2\tint\n\t\t0x428 mpu_rdb3\tint\n\t\t0x429 mpu_rdp3\tint\n\t\t0x42A mpu_rdb4\tint\n\t\t0x42B mpu_rdp4\tint\n\t\t0x42C mpu_rdb5\tint\n\t\t0x42D mpu_rdp5\tint\n\t\t0x42E mpu_rdb6\tint\n\t\t0x42F mpu_rdp6\tint\n\t\t0x430 mpu_rdb7\tint\n\t\t0x431 mpu_rdp7\tint\n\t\t0x432 mpu_rdb8\tint\n\t\t0x433 mpu_rdp8\tint\n\t\t0x434 mpu_rdb9\tint\n\t\t0x435 mpu_rdp9\tint\n\t\t0x436 mpu_rdb10\tint\n\t\t0x437 mpu_rdp10\tint\n\t\t0x438 mpu_rdb11\tint\n\t\t0x439 mpu_rdp11\tint\n\t\t0x43A mpu_rdb12\tint\n\t\t0x43B mpu_rdp12\tint\n\t\t0x43C mpu_rdb13\tint\n\t\t0x43D mpu_rdp13\tint\n\t\t0x43E mpu_rdb14\tint\n\t\t0x43F mpu_rdp14\tint\n\t\t0x440 mpu_rdb15\tint\n\t\t0x441 mpu_rdp15\tint\n\t\t0x448 mpu_index\tmpu_index_t\n\t\t0x449 mpu_rstart uint32\n\t\t0x44A mpu_rend\tuint32\n\t\t0x44B mpu_rper\tmpu_rper_t\n\t\t0x44C mpu_probe uint32\n\t}\n\tforeach {num name type} $aux_other {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_other_feature\n\t}\n\n\t# AUX BCR\n\tset bcr {\n\t\t0x6D mpu_build\n\t\t0x74 dccm_build\n\t\t0x76 ap_build\n\t\t0x78 iccm_build\n\t\t0xC1 isa_config\n\t}\n\tforeach {num reg} $bcr {\n\t\tarc add-reg -name $reg -num $num -type ${reg}_t -bcr -feature $aux_other_feature\n\t}\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_v2_examine_target [target current]\"\n}\n\nproc arc_v2_reset { {target \"\"} } {\n\tarc_common_reset $target\n\n\t# Disable all actionpoints.  Cannot write via regcache yet, because it will\n\t# not be flushed and all changes to registers will get lost.  Therefore has\n\t# to write directly via JTAG layer...\n\tset num_ap [arc num-actionpoints]\n\tfor {set i 0} {$i < $num_ap} {incr i} {\n\t\tarc jtag set-aux-reg [expr {0x222 + $i * 3}] 0\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arm/arm7tdmi.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm7tdmi\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arm/arm920.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm920\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arm/arm946.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm946\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arm/arm966.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm966\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/cpu/arm/cortex_m3.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   cortex_m3\nset CPU_ARCH   armv7\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/altera-10m50.cfg",
    "content": "# see MAX 10 FPGA Device Architecture\n# Table 3-1: IDCODE Information for MAX 10 Devices\n# Intel MAX 10M02 0x31810dd\n# Intel MAX 10M04 0x318a0dd\n# Intel MAX 10M08 0x31820dd\n# Intel MAX 10M16 0x31830dd\n# Intel MAX 10M25 0x31840dd\n# Intel MAX 10M40 0x318d0dd\n# Intel MAX 10M50 0x31850dd\n# Intel MAX 10M02 0x31010dd\n# Intel MAX 10M04 0x310a0dd\n# Intel MAX 10M08 0x31020dd\n# Intel MAX 10M16 0x31030dd\n# Intel MAX 10M25 0x31040dd\n# Intel MAX 10M40 0x310d0dd\n# Intel MAX 10M50 0x31050dd\n\njtag newtap 10m50 tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \\\n\t-expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \\\n\t-expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \\\n\t-expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \\\n\t-expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/altera-ep3c10.cfg",
    "content": "# Altera Cyclone III EP3C10\n# see Cyclone III Device Handbook, Volume 1;\n# Table 14–5. 32-Bit Cyclone III Device IDCODE\njtag newtap ep3c10 tap -expected-id 0x020f10dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/altera-ep4ce10.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ecp4\n}\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id -0x020f10ddc"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/lattice_ecp5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp5\n}\n\n# Lattice ECP5 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/ECP5\n#\n# 0x01111043 - LAE5UM_25F/LFE5UM_25F\n# 0x01112043 - LAE5UM_45F/LFE5UM_45F\n# 0x01113043 - LAE5UM_85F/LFE5UM_85\n# 0x21111043 - LFE5U_12F\n# 0x41111043 - LFE5U_25F\n# 0x41112043 - LFE5U_45F\n# 0x41113043 - LFE5U_85F\n# 0x81111043 - LFE5UM5G-25\n# 0x81112043 - LFE5UM5G-45\n# 0x81113043 - LFE5UM5G-85\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x01111043 -expected-id 0x01112043 -expected-id 0x01113043 \\\n\t-expected-id 0x21111043 -expected-id 0x41111043 -expected-id 0x41112043 \\\n\t-expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \\\n\t-expected-id 0x81113043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/xilinx-dna.cfg",
    "content": "proc xilinx_dna_addr {chip} {\n\tarray set addrs {\n\t\tSpartan6 0x30\n\t\tSeries7 0x17\n\t}\n\treturn $addrs($chip)\n}\n\n# Get the \"Device DNA\".\n# Most Xilinx FPGA devices contain an embedded, unique device identifier.\n# The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\n# This function returns the DNA as a 64 bit integer with the 7 LSBs zeroed.\n# This is compatible with the FUSE DNA which contains all 64 bits.\nproc xilinx_get_dna {tap chip} {\n\tset XC7_ISC_ENABLE 0x10\n\tset XC7_ISC_DISABLE 0x16\n\tset XC7_ISC_DNA [xilinx_dna_addr $chip]\n\n\tirscan $tap $XC7_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC7_ISC_DNA\n\tscan [drscan $tap 32 0 32 0] \"%08x %08x\" hi lo\n\truntest 64\n\tirscan $tap $XC7_ISC_DISABLE\n\truntest 64\n\t# openocd interprets DR scans as LSB first, bit-reverse it\n\treturn [scan [string reverse [format \"%032b%032bb0\" $lo $hi]] \"%i\"]\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xilinx_print_dna {dna} {\n\tset dna [expr {$dna >> 64 - 57}]\n\techo [format \"DNA = %057b (0x%016x)\" $dna $dna]\n}\n\nproc xc7_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Series7]\n}\n\nproc xc6s_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Spartan6]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/fpga/xilinx-xadc.cfg",
    "content": "# Xilinx XADC support for 7 Series FPGAs\n#\n# The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die\n# temperature, internal power supply rail voltages as well as external\n# voltages. The XADC is available both from fabric as well as through the\n# JTAG TAP.\n#\n# This code implements access through the JTAG TAP.\n#\n# https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf\n\n# build a 32 bit DRP command for the XADC DR\nproc xadc_cmd {cmd addr data} {\n\tarray set cmds {\n\t\tNOP 0x00\n\t\tREAD 0x01\n\t\tWRITE 0x02\n\t}\n\treturn [expr {($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)}]\n}\n\n# XADC register addresses\n# Some addresses (status registers 0-3) have special function when written to.\nproc XADC {key} {\n\tarray set addrs {\n\t\tTEMP 0x00\n\t\tLOCK 0x00\n\t\tVCCINT 0x01\n\t\tVCCAUX 0x02\n\t\tVAUXEN 0x02\n\t\tVPVN 0x03\n\t\tRESET 0x03\n\t\tVREFP 0x04\n\t\tVREFN 0x05\n\t\tVCCBRAM 0x06\n\t\tSUPAOFFS 0x08\n\t\tADCAOFFS 0x09\n\t\tADCAGAIN 0x0a\n\t\tVCCPINT 0x0d\n\t\tVCCPAUX 0x0e\n\t\tVCCODDR 0x0f\n\t\tVAUX0 0x10\n\t\tVAUX1 0x11\n\t\tVAUX2 0x12\n\t\tVAUX3 0x13\n\t\tVAUX4 0x14\n\t\tVAUX5 0x15\n\t\tVAUX6 0x16\n\t\tVAUX7 0x17\n\t\tVAUX8 0x18\n\t\tVAUX9 0x19\n\t\tVAUX10 0x1a\n\t\tVAUX11 0x1b\n\t\tVAUX12 0x1c\n\t\tVAUX13 0x1d\n\t\tVAUX14 0x1e\n\t\tVAUX15 0x1f\n\t\tSUPBOFFS 0x30\n\t\tADCBOFFS 0x31\n\t\tADCBGAIN 0x32\n\t\tFLAG 0x3f\n\t\tCFG0 0x40\n\t\tCFG1 0x41\n\t\tCFG2 0x42\n\t\tSEQ0 0x48\n\t\tSEQ1 0x49\n\t\tSEQ2 0x4a\n\t\tSEQ3 0x4b\n\t\tSEQ4 0x4c\n\t\tSEQ5 0x4d\n\t\tSEQ6 0x4e\n\t\tSEQ7 0x4f\n\t\tALARM0 0x50\n\t\tALARM1 0x51\n\t\tALARM2 0x52\n\t\tALARM3 0x53\n\t\tALARM4 0x54\n\t\tALARM5 0x55\n\t\tALARM6 0x56\n\t\tALARM7 0x57\n\t\tALARM8 0x58\n\t\tALARM9 0x59\n\t\tALARM10 0x5a\n\t\tALARM11 0x5b\n\t\tALARM12 0x5c\n\t\tALARM13 0x5d\n\t\tALARM14 0x5e\n\t\tALARM15 0x5f\n\t}\n\treturn $addrs($key)\n}\n\n# Select the XADC DR\nproc xadc_select {tap} {\n\tset XADC_IR 0x37\n\tirscan $tap $XADC_IR\n\truntest 10\n}\n\n# XADC transfer\nproc xadc_xfer {tap cmd addr data} {\n\tset ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]\n\truntest 10\n\treturn [expr \"0x$ret\"]\n}\n\n# XADC register write\nproc xadc_write {tap addr data} {\n\txadc_xfer $tap WRITE $addr $data\n}\n\n# XADC register read, non-pipelined\nproc xadc_read {tap addr} {\n\txadc_xfer $tap READ $addr 0\n\treturn [xadc_xfer $tap NOP 0 0]\n}\n\n# convert 16 bit register code from ADC measurement on\n# external voltages (VAUX) to Volt\nproc xadc_volt {code} {\n\treturn [expr {$code * 1./(1 << 16)}]\n}\n\n# convert 16 bit temperature measurement to Celsius\nproc xadc_temp {code} {\n\treturn [expr {$code * 503.975/(1 << 16) - 273.15}]\n}\n\n# convert 16 bit suppply voltage measurement to Volt\nproc xadc_sup {code} {\n\treturn [expr {$code * 3./(1 << 16)}]\n}\n\n# perform a single channel measurement using default settings\nproc xadc_single {tap ch} {\n\tset cfg0 [xadc_read $tap [XADC CFG0]]\n\tset cfg1 [xadc_read $tap [XADC CFG1]]\n\t# set channel\n\txadc_write $tap [XADC CFG0] $cfg0\n\t# single channel, disable the sequencer\n\txadc_write $tap [XADC CFG1] 0x3000\n\t# leave some time for the conversion\n\truntest 100\n\tset ret [xadc_read $tap [XADC $ch]]\n\t# restore CFG0/1\n\txadc_write $tap [XADC CFG0] $cfg0\n\txadc_write $tap [XADC CFG1] $cfg1\n\treturn $ret\n}\n\n# measure all internal voltages\nproc xadc_report {tap} {\n\txadc_select $tap\n\techo \"TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C\"\n\tforeach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \\\n\t\tVCCPINT VCCPAUX VCCODDR] {\n\t\techo \"$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/altera-usb-blaster.cfg",
    "content": "#\n# Altera USB-Blaster\n#\n# http://www.altera.com/literature/ug/ug_usb_blstr.pdf\n#\n\nadapter driver usb_blaster\nusb_blaster lowlevel_driver ftdi\n# These are already the defaults.\n# usb_blaster vid_pid 0x09FB 0x6001\n# usb_blaster device_desc \"USB-Blaster\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/altera-usb-blaster2.cfg",
    "content": "#\n# Altera USB-Blaster II\n#\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x09fb 0x6010 0x09fb 0x6810\nusb_blaster lowlevel_driver ublast2\nusb_blaster firmware /path/to/quartus/blaster_6810.hex\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/arm-jtag-ew.cfg",
    "content": "#\n# Olimex ARM-JTAG-EW\n#\n# http://www.olimex.com/dev/arm-jtag-ew.html\n#\n\nadapter driver arm-jtag-ew\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/at91rm9200.cfg",
    "content": "#\n# Various Atmel AT91RM9200 boards\n#\n# TODO: URL?\n#\n\nadapter driver at91rm9200\nat91rm9200_device rea_ecr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/beaglebone-jtag-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for JTAG\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio tdo_num 20\nam335xgpio tdi_num 60\nam335xgpio tms_num 4\nam335xgpio tck_num 2\n\nam335xgpio led_num 51\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/beaglebone-swd-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for SWD\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio swclk_num 2\nam335xgpio swdio_num 4\nam335xgpio swdio_dir_num 60\nam335xgpio swdio_dir_output_state on\n\n# USR0 LED\nam335xgpio led_num 53\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/buspirate.cfg",
    "content": "#\n# Buspirate with OpenOCD support\n#\n# http://dangerousprototypes.com/bus-pirate-manual/\n#\n\nadapter driver buspirate\n\n# you need to specify port on which BP lives\n#buspirate port /dev/ttyUSB0\n\n# communication speed setting\nbuspirate speed normal ;# or fast\n\n# voltage regulator Enabled = 1 Disabled = 0\n#buspirate vreg 0\n\n# pin mode normal or open-drain (jtag only)\n#buspirate mode normal\n\n# pullup state Enabled = 1 Disabled = 0\n#buspirate pullup 0\n\n# this depends on the cable, you are safe with this option\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/calao-usb-a9260.cfg",
    "content": "#\n# CALAO Systems USB-A9260 common -C01 -C02 setup\n#\n# http://www.calao-systems.com/\n#\n# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg.\n#\n\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/chameleon.cfg",
    "content": "#\n# Amontec Chameleon POD\n#\n# http://www.amontec.com/chameleon.shtml\n#\n\nadapter driver parport\nparport cable chameleon\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/cmsis-dap.cfg",
    "content": "#\n# ARM CMSIS-DAP compliant adapter\n#\n# http://www.keil.com/support/man/docs/dapdebug/\n#\n\nadapter driver cmsis-dap\n\n# Optionally specify the serial number of CMSIS-DAP usb device.\n# adapter serial 02200201E6661E601B98E3B9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/dln-2-gpiod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use DLN-2 GPIO through linuxgpiod\n#\n# +-----------+-------------+-------------+\n# | signal    | DLN-2       | gpio offset |\n# +-----------+-------------+-------------+\n# | nSRST     | J3.1  (PA0) | 0           |\n# | TDO       | J3.2  (PA1) | 1           |\n# | TCK/SWCLK | J3.3  (PA2) | 2           |\n# | TMS/SWDIO | J3.4  (PA3) | 3           |\n# | TDI       | J3.5  (PA4) | 4           |\n# | nTRST     | J3.6  (PA5) | 5           |\n# | LED       | J3.7  (PA6) | 6           |\n# | GND       | J3.12 (GND) |             |\n# +-----------+-------------+-------------+\n\nadapter driver linuxgpiod\n\nlinuxgpiod gpiochip 0\nlinuxgpiod jtag_nums 2 3 4 1\nlinuxgpiod trst_num 5\nlinuxgpiod swd_nums 2 3\nlinuxgpiod srst_num 0\nlinuxgpiod led_num 6\n\nreset_config trst_and_srst separate srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/dummy.cfg",
    "content": "#\n# Dummy interface (for testing purposes)\n#\n\nadapter driver dummy\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/estick.cfg",
    "content": "#\n# eStick\n#\n# http://code.google.com/p/estick-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/flashlink.cfg",
    "content": "#\n# ST FlashLINK JTAG parallel cable\n#\n# http://www.st.com/internet/evalboard/product/94023.jsp\n# http://www.st.com/stonline/products/literature/um/7889.pdf\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable flashlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ft232r/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to Radiona ULX3S board:\n# \tboard/radiona_ulx3s.cfg\n# See schematics for the ft232r layout:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nadapter driver ft232r\nadapter speed 1000\nft232r_vid_pid 0x0403 0x6015\nft232r_tck_num DSR\nft232r_tms_num DCD\nft232r_tdi_num RI\nft232r_tdo_num CTS\nft232r_trst_num RTS\nft232r_srst_num DTR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ft232r.cfg",
    "content": "adapter driver ft232r\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/100ask-openjtag.cfg",
    "content": "#\n# www.100ask.org OpenJTAG\n#\n# http://www.100ask.net/OpenJTAG.html\n#\n# Schematics are available from\n# https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"USB<=>JTAG&RS232\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0f08 0x0f1b\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/ashling-opella-ld-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi tdo_sample_edge falling\nftdi layout_init 0x0A68 0xFF7B\nftdi channel 0\nftdi layout_signal JTAGOE -ndata 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/ashling-opella-ld-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi layout_init 0x0860 0x0b7b\nftdi channel 0\nftdi layout_signal JTAGOE -data 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/axm0432.cfg",
    "content": "#\n# Axiom axm0432\n#\n# http://www.axman.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Symphony SoundBite\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/c232hm.cfg",
    "content": "# FTDI USB Hi-Speed to MPSSE Cable\n#\n# http://www.ftdichip.com/Products/Cables/USBMPSSE.htm\n#\n# C232HM-DDHSL-0 and C232HM-EDSL-0 provide 3.3V and 5V on pin 1 (Red),\n# respectively.\n#\n# Adapter: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_C232HM_MPSSE_CABLE.PDF\n# Chip: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf\n# See pinout/colors at end of this file.\n#\n# Tech notes:\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf\n\nadapter driver ftdi\n#ftdi device_desc \"C232HM-DDHSL-0\"\n#ftdi device_desc \"C232HM-EDHSL-0\"\n\n# Common PID for FT232H\nftdi vid_pid 0x0403 0x6014\n\n# Layout\n# High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low)\n# Low data byte 0x08 configures TMS on ACBUS3 initially high (asserted); TCK, TDI low\n# High direction byte 0x40 configures red LED on ACBUS6 as high (output)\n# Low direction byte 0x0b configures TDO on ACBUS2 as low (input)\nftdi layout_init 0x4008 0x400b\n\n# ---A*BUS-------CCCCCCCC|DDDDDDDD\n# --------\\______76543210|76543210\n# LED\t0x4000 = 01000000|00000000 = ACBUS6\n#GPIOL0\t0x0010 = 00000000|00010000 = ADBUS4\n#GPIOL1\t0x0020 = 00000000|00100000 = ADBUS5\n#GPIOL2\t0x0040 = 00000000|01000000 = ADBUS6\n#GPIOL3\t0x0080 = 00000000|10000000 = ADBUS7\n# -ndata treats the LED as active-low for expected behavior (toggle when transferring)\nftdi layout_signal LED -ndata 0x4000\n# Available for aliasing as desired\nftdi layout_signal GPIOL0 -data 0x0010 -oe 0x0010\nftdi layout_signal GPIOL1 -data 0x0020 -oe 0x0020\nftdi layout_signal GPIOL2 -data 0x0040 -oe 0x0040\nftdi layout_signal GPIOL3 -data 0x0080 -oe 0x0080\n\n# C232HM\t\tFT232H\tJTAG/Other\n# Num\tColor\tName\tFunc\n# 1\t\tRed\t\tVCC\t\tOptionally, can power the board if it is not using its own power supply.\n# 2\t\tOrange\tADBUS0\tTCK\n# 3\t\tYellow  ADBUS1\tTDI\n# 4\t\tGreen\tADBUS2\tTDO\n# 5\t\tBrown   ADBUS3\tTMS\n# 6\t\tGrey\tADBUS4\tGPIOL0\n# 7\t\tPurple\tADBUS5\tGPIOL1\n# 8\t\tWhite\tADBUS6\tGPIOL2\n# 9\t\tBlue\tADBUS7\tGPIOL3\n# 10\tBlack\tGND\t\tConnect to ground\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/calao-usb-a9260-c01.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C01\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/calao-usb-a9260-c02.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C02\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6001\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/cortino.cfg",
    "content": "#\n# Hitex Cortino\n#\n# http://www.hitex.com/index.php?id=cortino\n#\n\nadapter driver ftdi\nftdi device_desc \"Cortino\"\nftdi vid_pid 0x0640 0x0032\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/digilent-hs1.cfg",
    "content": "# this supports JTAG-HS1 and JTAG-SMT1\n# (the later being the OEM on-board version)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6010\n# channel 1 does not have any functionality\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/digilent-hs2.cfg",
    "content": "# this supports JTAG-HS2 (and apparently Nexys4 as well)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\n\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_hs3.cfg",
    "content": "#\n# Digilent JTAG-HS3\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"Digilent USB Device\"\n\n# From Digilent support:\n# The SRST pin is [...] 0x20 and 0x10 is the /OE (active low output enable)\n\nftdi layout_init 0x2088 0x308b\nftdi layout_signal nSRST -data 0x2000 -noe 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_smt2.cfg",
    "content": "#\n# Digilent JTAG-SMT2\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,1053&Prod=JTAG-SMT2\n#\n# Config is based on data from\n# http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x20e8 0x3feb\nftdi layout_signal nSRST -data 0x2000\nftdi layout_signal GPIO2 -data 0x2000\nftdi layout_signal GPIO1 -data 0x0200\nftdi layout_signal GPIO0 -data 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_smt2_nc.cfg",
    "content": "#\n# Digilent JTAG-SMT2-NC\n#\n# http://store.digilentinc.com/jtag-smt2-nc-surface-mount-programming-module/\n# https://reference.digilentinc.com/_media/jtag_smt2nc/jtag-smt2-nc_rm.pdf\n#\n# Based on reference sheet (above) and Xilinx KCU105 schematics\n# https://www.xilinx.com/products/boards-and-kits/kcu105.html#documentation\n#\n# Note that the digilent_jtag_smt2 layout does not work and hangs while\n# the ftdi device_desc from digilent_hs2 is wrong.\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/dlp-usb1232h.cfg",
    "content": "#\n# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module\n#\n# http://www.dlpdesign.com/usb/usb1232h.shtml\n#\n# Schematics for OpenOCD usage:\n# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/dp_busblaster.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the\n# JTAG header which allows it to emulate various debugger types. It comes\n# configured as a JTAGkey device.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\necho \"Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster\nand use dp_busblaster_kt-link.cfg instead\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/dp_busblaster_kt-link.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster (with KT-Link buffer)\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://github.com/bharrisau/busblaster and is SWD-enabled.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -ndata 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/esp32s2_kaluga_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Driver for the FT2232H JTAG chip on the Espressif Kaluga-1 ESP32-S2 board\n# (and most other FT2232H and FT232H based boards)\n#\n# JTAG DIP switch (labelled SW5 in the schematic) should be \"ON\" for lines\n# labelled TCK, TDO, TDI and TWS, to connect the FT2232H to the ESP32-S2.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010 0x0403 0x6014\n\n# interface 1 is the uart\nftdi channel 0\n\n# TCK, TDI, TDO, TMS: ADBUS0-3\n# TRST/SRST: ADBUS5 (unused for now)\n# LEDs: ACBUS3-4 (inverted)\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal LED -ndata 0x0800\nftdi layout_signal LED2 -ndata 0x1000\n\n# ESP32* series chips do not have a TRST input, and the SRST line is connected\n# to the EN pin.\n# The target code doesn't handle SRST reset properly yet, so this is\n# commented out:\n# ftdi layout_signal nSRST -oe 0x0020\n# reset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/flossjtag-noeeprom.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used\n# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you\n# have several Floss-JTAG connected you have to use the USB ID to select a\n# specific one.\n#\n# If you have a Floss-JTAG WITH EEPROM that is programmed, use the\n# flossjtag.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/flossjtag.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the\n# existence of an EEPROM on Floss-JTAG containing a name. If you have several\n# Floss-JTAG adapters connected you can use the serial number to select a\n# specific device.\n#\n# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the\n# flossjtag-noeeprom.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi device_desc \"FLOSS-JTAG\"\n# adapter serial \"FJ000001\"\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x0800\nftdi layout_signal LED2 -data 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/flyswatter.cfg",
    "content": "#\n# TinCanTools Flyswatter\n#\n# http://web.archive.org/web/20150419072034/http://www.tincantools.com/JTAG/Flyswatter.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0818 0x0cfb\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/flyswatter2.cfg",
    "content": "#\n# TinCanTools Flyswatter2\n#\n# https://www.tincantools.com/product/flyswatter2/\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter2\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0538 0x057b\nftdi layout_signal LED -ndata 0x0400\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020 -noe 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/ft232h-module-swd.cfg",
    "content": "#\n# ADAFRUIT FTDI FT232H as a SWD direct connect interface\n# Any FT232H based board may work\n#\n# http://www.ftdichip.com/Products/ICs/FT232H.htm\n#\n#\n\nadapter driver ftdi\n\nftdi vid_pid 0x0403 0x6014\n\n# data MSB..LSB       direction (1:out) MSB..LSB\n# 0000'0000'0011'0000 0000'0000'0011'1011\nftdi layout_init 0x0030 0x003b\n# 0xfff8 0xfffb\n# Those signal are only required on some platforms or may required to be\n# enabled explicitly (e.g. nrf5x chips).\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\n\n# swd enable\nftdi layout_signal SWD_EN -data 0\n# tri-state (configure as input) TDO/TIO when reading\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n\n# re-configure TDO as tri-state\n#ftdi layout_signal TDO -data 0x0002 -oe 0x0002\n#ftdi layout_signal TDI -data 0x0004\n\n# Adafruit      FT232H    JTAG       SWD\n# Name  Pin     Name      Func       Func\n#  D0   J1-3    ADBUS0    TCK        SWDCLK\n#  D1   J1-4    ADBUS1    TDO/DI     SWDIO\n#  D2   J1-5    ADBUS2    TDI/DO     SWDIO\n#  D3   J1-6    ADBUS3    TMS        N/A\n#  D4   J1-7    ADBUS4    (GPIOL0)   /nSRST  optional module reset\n#  D5   J1-8    ADBUS5    (GPIOL1)   /nTRST  optional target reset\n#  D6   J1-9    ADBUS6    (GPIOL2)\n#  D7   J1-10   ADBUS7    (GPIOL3)\n#  C0   J2-1    ACBUS0    (GPIOH0)\n#  C1   J2-2    ACBUS1    (GPIOH1)\n#  C2   J2-3    ACBUS2    (GPIOH2)\n#  C3   J2-4    ACBUS3    (GPIOH3)\n#  C4   J2-5    ACBUS4    (GPIOH4)\n#  C5   J2-6    ACBUS5    (GPIOH5)\n#  C6   J2-7    ACBUS6    (GPIOH6)\n#  C7   J2-8    ACBUS7    (GPIOH7)\n#  C8   J2-9    ACBUS8\n#  C9   J2-10   ACBUS9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/gw16042.cfg",
    "content": "#\n# Gateworks GW16042 JTAG Dongle\n#\n# http://www.gateworks.com/\n#\n# Layout:  FTDI FT2232H\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO (input)\n#   ADBUS3 TMS\n#   ADBUS4 nTRST\n#   ADBUS5 nSRST\n#   ADBUS6 OE (active high) for TRST, TDI, TMS, TCK\n#   ADBUS7 NC\n#   ACBUS0-7 NC\n#   BDBUS0 RXD\n#   BDBUS1 TXD (input)\n#\n\nadapter driver ftdi\nftdi device_desc \"USB-JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0058 0x007b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hie-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Hofstädtler Industrie-Electronic (HIE) JTAG Debugger\n#\n# https://www.hofstaedtler.com/jtag\n#\n\nadapter driver ftdi\nftdi channel 0\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"HIE JTAG Debugger\"\n\nftdi layout_init 0x0c08 0x4f1b\n\n# define both Reset signals\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\n# Toggle USB LED\nftdi layout_signal LED -ndata 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx10_etm.cfg",
    "content": "#\n# Hilscher NXHX 10-ETM\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 10-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx500_etm.cfg",
    "content": "#\n# Hilscher NXHX 500-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx500_re.cfg",
    "content": "#\n# Hilscher NXHX 500-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx50_etm.cfg",
    "content": "#\n# Hilscher NXHX 50-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 50-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx50_re.cfg",
    "content": "#\n# Hilscher NXHX 50-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX50-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hitex_lpc1768stick.cfg",
    "content": "#\n# Hitex LPC1768-Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\n\nadapter driver ftdi\nftdi device_desc \"LPC1768-Stick\"\nftdi vid_pid 0x0640 0x0026\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/hitex_str9-comstick.cfg",
    "content": "#\n# Hitex STR9-comStick\n#\n# http://www.hitex.com/index.php?id=383\n#\n\nadapter driver ftdi\nftdi device_desc \"STR9-comStick\"\nftdi vid_pid 0x0640 0x002c\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/icebear.cfg",
    "content": "#\n# Section5 ICEBear\n#\n# http://section5.ch/icebear\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"ICEbear JTAG adapter\"\nftdi vid_pid 0x0403 0xc140\n\nftdi layout_init 0x0028 0x002b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/imx8mp-evk.cfg",
    "content": "#\n# Configuration file for NXP MC-IMX8MP-EVK on-board internal JTAG\n#\n# Using this interface requires enabling \"remote mode\" for the board using the\n# NXP bcu tool (see https://github.com/NXPmicro/bcu)\n#\n#\tbcu set_gpio remote_en 1 -board=imx8mpevk\n#\n# The REMOTE_EN gpio is accessible through the same FTDI adapter but it's\n# behind an I2C GPIO expander.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n\nftdi layout_init 0x00f8 0x000b\n\nftdi layout_signal RESET_B\t-data 0x0010 -oe 0x0010\n# Called SYS_nRST in schematics\nftdi layout_signal nSRST\t-data 0x0020 -oe 0x0020\nftdi layout_signal IO_nRST\t-data 0x0040 -oe 0x0040\nftdi layout_signal ONOFF_B\t-data 0x0080 -oe 0x0080\n\nftdi layout_signal GPIO1\t-data 0x0100 -oe 0x0100\nftdi layout_signal GPIO2\t-data 0x0200 -oe 0x0200\nftdi layout_signal GPIO3\t-data 0x0400 -oe 0x0400\nftdi layout_signal GPIO4\t-data 0x0800 -oe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/incircuit-icprog.cfg",
    "content": "#\n# In-Circuit's ICprog OpenOCD JTAG Adapter\n# https://shop.in-circuit.de/product_info.php?products_id=112\n#\n# Schematics available at\n# http://wiki.in-circuit.de/images/0/06/610000158A_openocd.pdf\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nSRST -noe 0x0400 -data 0x0800\nftdi layout_signal nTRST -noe 0x0100 -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/iotlab-usb.cfg",
    "content": "#\n# This is the integrated adapter as found on the IoT-LAB boards\n# https://github.com/iot-lab/iot-lab/wiki\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/isodebug.cfg",
    "content": "# isodebug v1\n# 5 kV isolated JTAG/SWD + UART adapter by Unjo AB\n\nadapter driver ftdi\nftdi vid_pid 0x22b7 0x150d\n\nftdi layout_init 0x0ff8 0xfffb\n\nftdi layout_signal LED -ndata 0x0100\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\nftdi layout_signal SWDIO_OE -data 0x0008\n\n# Mode signals, either of these needs to be high to drive the JTAG/SWD pins.\n# The power-on state is low for both signals but the init setting above sets\n# JTAG_EN high.\nftdi layout_signal SWD_EN -data 0x1000\nftdi layout_signal JTAG_EN -data 0x0800\n\n# In SWD mode, the JTAG_EN signal doubles as SWO_EN_N which switches the\n# second FTDI channel UART RxD to the SWO pin instead of the separate RxD\n# pin. Note that the default init state has this pin high so when OpenOCD\n# starts in SWD mode, SWO is by default disabled. To enable SWO tracing,\n# issue the command 'ftdi set_signal SWO_EN 1' where tracing is configured.\n# To switch back to using the separate UART, SWO_EN needs to be disabled\n# before exiting OpenOCD, or the adapter replugged.\nftdi layout_signal SWO_EN -nalias JTAG_EN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/jtag-lock-pick_tiny_2.cfg",
    "content": "#\n# DISTORTEC JTAG-lock-pick Tiny 2\n#\n# http://www.distortec.com\n#\n\nadapter driver ftdi\nftdi device_desc \"JTAG-lock-pick Tiny 2\"\nftdi vid_pid 0x0403 0x8220\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal SWDIO_OE -ndata 0x1000\nftdi layout_signal LED -ndata 0x8000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/jtagkey.cfg",
    "content": "#\n# Amontec JTAGkey\n#\n# http://www.amontec.com/jtagkey.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/jtagkey2.cfg",
    "content": "#\n# Amontec JTAGkey2\n#\n# http://www.amontec.com/jtagkey2.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/jtagkey2p.cfg",
    "content": "#\n# Amontec JTAGkey2P\n#\n# http://www.amontec.com/jtagkey2p.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2P\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/kt-link.cfg",
    "content": "#\n# Kristech KT-Link\n#\n# http://www.kristech.eu\n#\n\nadapter driver ftdi\nftdi device_desc \"KT-LINK\"\nftdi vid_pid 0x0403 0xbbe2\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -data 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to LambdaConcept ECPIX-5 board:\n# \tinterface/ftdi/lambdaconcept_ecpix-5.cfg\n# See schematics for the ftdi layout:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n\nadapter driver ftdi\nadapter speed 10000\nftdi_device_desc \"Dual RS232-HS\"\nftdi_vid_pid 0x0403 0x6010\n\nftdi_layout_init 0xfff8 0xfffb\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/lisa-l.cfg",
    "content": "#\n# Lisa/L\n#\n# http://paparazzi.enac.fr/wiki/Lisa\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Lisa/L\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x1800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/luminary-icdi.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S9B9x Evaluation Kits\n# In-Circuit Debug Interface (ICDI) Board\n#\n# Essentially all Luminary debug hardware is the same, (with both\n# JTAG and SWD support compatible with ICDI boards.  This ICDI adapter\n# configuration is JTAG-only, but the same hardware handles SWD too.\n#\n# This is a discrete ftdi based debug board which supports ARM's\n# JTAG/SWD connectors in both backwards-compatible 20-pin format and\n# in the new-style compact 10-pin.  There's also an 8-pin connector\n# with serial port support.  It's included with LM3S9B9x eval boards.\n#\n# http://www.luminarymicro.com/products/ek-lm3s9b90.html\n# http://www.luminarymicro.com/products/ek-lm3s9b92.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Luminary Micro ICDI Board\"\nftdi vid_pid 0x0403 0xbcda\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/luminary-lm3s811.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S811 Evaluation Kit\n#\n# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html\n#\n# NOTE:  this is only for boards *before* Rev C, which adds support\n# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals.\n# The \"evb_lm3s811\" layout doesn't set up those signals.\n#\n# Rev C boards work more like the other Stellaris eval boards.  They\n# need to use the \"luminary_icdi\" layout to work correctly.\n#\n\nadapter driver ftdi\nftdi device_desc \"LM3S811 Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x0088 0x008b\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/luminary.cfg",
    "content": "#\n# Luminary Micro Stellaris Evaluation Kits\n#\n# http://www.luminarymicro.com/products/evaluation_kits.html\n#\n# There are a number of evaluation kits for Stellaris Cortex-M3 chips.\n# Currently they all bundle ftdi based debug support.  When that is\n# used (instead of an external adapter), use this config file in one\n# of these two modes:\n#\n# - Eval board debug ... debug of the Stellaris chip via port A.\n#\n# - Other board debug ... same thing, but the board acts as a debug\n#   adapter for another board (using a standard ARM JTAG connector).\n#   The Stellaris chip stays in reset.\n#\n# Those support both JTAG and SWD.  SWD is an ARM-only two-wire debug\n# protocol; in 2009, OpenOCD does not support SWD.\n#\n# Port B of the ftdi chip is normally used as a serial link to the\n# Stellaris chip.  On most boards (but not older LM3S811 eval boards),\n# when SWD is used Port B may instead be used to read low-bandwidth\n# \"SWO trace\" data, including so-called \"printf style\" output from\n# firmware via the ITM module as well as profile data.\n#\n\nadapter driver ftdi\nftdi device_desc \"Stellaris Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/m53evk.cfg",
    "content": "#\n# DENX M53EVK\n#\n# http://www.denx-cs.de/?q=M53EVK\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/mbftdi.cfg",
    "content": "#\n# MBFTDI\n#\n# http://www.marsohod.org/prodmbftdi\n#\n# Also the Marsohod2 and the Marsohod3 boards\n# include a built-in MBFTDI for FPGA programming.\n# See http://www.marsohod.org/prodmarsohod2\n# and http://www.marsohod.org/plata-marsokhod3 for details.\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/minimodule-swd.cfg",
    "content": "#\n# Supports SWD using the FT2232H or FT4232H minimodule.\n# Each can support 2 SWD interfaces.\n#\n# FT2232H or FT4232H minimodule channel 0 (Channel A)\n# Connector  FTDI              Target\n# Pin        Name\n# ---------  ------            ------\n# CN2-11     VIO               VDD_IO (Or connect to CN2-5 on the minimodule instead for a 3V3 interface)\n# CN2-2      GND               GND\n# CN2-7      ADBUS0 (TCK)      SWCLK\n# CN2-9      ADBUS2 (TDI/TDO)  SWDIO\n# CN2-10     ADBUS1 (TDO/TDI)  SWDIO\n# CN2-14     ADBUS4 (GPIOL0)   nRESET\n#\n# FT2232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN3-26  -  SWCLK\n# CN3-25  -  SWDIO\n# CN3-24  -  SWDIO\n# CN3-21  -  nRESET\n#\n# FT4232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN2-18  -  SWCLK\n# CN2-17  -  SWDIO\n# CN2-20  -  SWDIO\n# CN2-22  -  nRESET\n#\n\nadapter driver ftdi\n\n#Select your module type and channel\n\n#ftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n#ftdi channel 1\n\n#ftdi device_desc \"FT4232H MiniModule\"\n#ftdi vid_pid 0x0403 0x6011\n#ftdi channel 1\n\nftdi layout_init 0x0000 0x000b\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal SWD_EN -data 0\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/minimodule.cfg",
    "content": "#\n# FTDI MiniModule\n#\n# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n\n# Every pin set as high impedance except TCK, TDI, TDO and TMS\nftdi layout_init 0x0008 0x000b\n\n# nSRST defined on pin CN2-13 of the MiniModule (pin ADBUS5 [AD5] on the FT2232H chip)\n# This choice is arbitrary. Use other GPIO pin if desired.\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n# https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf\nadapter driver ftdi\n# The miniSpartan6+ sadly doesn't have a custom device description, so we just\n# have to hope you got it right.\n#ftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 30000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/miniwiggler.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Infineon DAP miniWiggler V3\n#\n# https://www.infineon.com/cms/en/product/evaluation-boards/kit_miniwiggler_3_usb/\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 nOE (output enable)\n#   ADBUS5\n#   ADBUS6\n#   ADBUS7 Blue LED\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5\n#   ACBUS6\n#   ACBUS7\n#\n\nadapter driver ftdi\nftdi device_desc \"DAS JDS miniWiggler V3.1\"\nftdi vid_pid 0x058b 0x0043\n\nftdi channel 0\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/neodb.cfg",
    "content": "#\n# Openmoko USB JTAG/RS232 adapter\n#\n# http://wiki.openmoko.org/wiki/Debug_Board_v3\n#\n\nadapter driver ftdi\nftdi device_desc \"Debug Board for Neo1973\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\nftdi layout_signal nNOR_WP -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/ngxtech.cfg",
    "content": "#\n# NGX ARM USB JTAG\n#\n# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NGX JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-jtag-swd.cfg",
    "content": "#\n# Olimex ARM JTAG SWD adapter\n# https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-SWD/\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg",
    "content": "#\n# Olimex ARM-USB-OCD-H\n#\n# http://www.olimex.com/dev/arm-usb-ocd-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-OCD-H\"\nftdi vid_pid 0x15ba 0x002b\n\nftdi layout_init 0x0908 0x0b1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-ocd.cfg",
    "content": "#\n# Olimex ARM-USB-OCD\n#\n# http://www.olimex.com/dev/arm-usb-ocd.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG\"\nftdi vid_pid 0x15ba 0x0003\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg",
    "content": "#\n# Olimex ARM-USB-TINY-H\n#\n# http://www.olimex.com/dev/arm-usb-tiny-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-TINY-H\"\nftdi vid_pid 0x15ba 0x002a\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/olimex-jtag-tiny.cfg",
    "content": "#\n# Olimex ARM-USB-TINY\n#\n# http://www.olimex.com/dev/arm-usb-tiny.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG TINY\"\nftdi vid_pid 0x15ba 0x0004\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/oocdlink.cfg",
    "content": "#\n# Joern Kaipf's OOCDLink\n#\n# http://www.joernonline.de/contrexx2/cms/index.php?page=126\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"OOCDLink\"\nftdi vid_pid 0x0403 0xbaf8\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/opendous_ftdi.cfg",
    "content": "#\n# Opendous\n#\n# http://code.google.com/p/opendous/wiki/JTAG\n#\n# According to the website, it is similar to jtagkey, but it uses channel B\n# (and it has a different pid number).\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/openocd-usb-hs.cfg",
    "content": "#\n# embedded projects openocd usb adapter v3\n#\n# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/openocd-usb.cfg",
    "content": "#\n# Hubert Hoegl's USB to JTAG\n#\n# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/openrd.cfg",
    "content": "#\n# Marvell OpenRD\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"OpenRD JTAGKey FT2232D B\"\nftdi vid_pid 0x0403 0x9e90\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n# http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf\nadapter driver ftdi\nftdi device_desc \"Pipistrello LX45\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/pls_spc5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# PLS SPC5-UDESTK\n#\n# https://www.st.com/en/development-tools/spc5-udestk.html\n#\n# Reference the SPC56D Discovery schematics.\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 TMS\n#   ADBUS5 RTCK\n#   ADBUS6\n#   ADBUS7 LED1\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST (external pull-down)\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5 nSRST direction (input=L, output=H, external pull-down)\n#   ACBUS6 TMS direction (input=L, output=H, external pull-up)\n#   ACBUS7 LED2\n#\n\nadapter driver ftdi\nftdi device_desc \"PLS USB/JTAG Adapter for SPC5xxx\"\nftdi vid_pid 0x263d 0x4001\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -ndata 0x2000 -oe 0x2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/redbee-econotag.cfg",
    "content": "#\n# Redwire Redbee-Econotag\n#\n# http://www.redwirellc.com/store/node/1\n#\n# The Redbee-Econotag has an onboard FT2232H with:\n#  - FT2232H channel A wired to mc13224v JTAG\n#  - FT2232H channel B wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/redbee-usb.cfg",
    "content": "#\n# Redwire Redbee-USB\n#\n# http://www.redwirellc.com\n#\n# The Redbee-USB has an onboard FT2232H with:\n#  - FT2232H channel B wired to mc13224v JTAG\n#  - FT2232H channel A wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/rowley-cc-arm-swd.cfg",
    "content": "#\n# Rowley ARM SWD Adapter\n# http://sites.fastspring.com/rowley/product/armswdadapter\n# https://drive.google.com/file/d/0Bzv7UpKpOQhnTUNNdzI5OUR4WGs/edit?usp=sharing\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/sheevaplug.cfg",
    "content": "#\n# Marvel SheevaPlug Development Kit\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"SheevaPlug JTAGKey FT2232D B\"\nftdi vid_pid 0x9e88 0x9e8f\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/signalyzer-lite.cfg",
    "content": "#\n# Xverve Signalyzer LITE (DT-USB-SLITE)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer LITE\"\nftdi vid_pid 0x0403 0xbca1\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/signalyzer.cfg",
    "content": "#\n# Xverve Signalyzer Tool (DT-USB-ST)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer\"\nftdi vid_pid 0x0403 0xbca0\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/snps_sdp.cfg",
    "content": "#  Copyright (C) 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys SDP Mainboard has embdded FT2232 chip, which is similar to Digilent\n# HS-1, except that it uses channel B for JTAG communication, instead of\n# channel A.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi layout_init 0x0088 0x008b\nftdi channel 1\n\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/steppenprobe.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Steppenprobe\n# https://github.com/diegoherranz/steppenprobe\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\n# Initial Layout\nftdi layout_init 0x0058 0x99fb\n# Signal        Data    Direction       Notes\n# TCK           0       1 (out)\n# TDI           0       1 (out)\n# TDO           0       0 (in)\n# TMS           1       1 (out)         JTAG IEEE std recommendation\n# LED           1       1 (out)         LED off\n# SWD_EN        0       1 (out)         OpenOCD sets this high for SWD\n# SWDIO_OE      1       1 (out)         Ext. buffer tristated\n# SRST          0       1 (out)         Translates to nSRST=Z\n\n# Unused        0       1 (out)\n# GPIO_A        0       0 (in)\n# GPIO_B        0       0 (in)\n# Unused        0       1 (out)\n# Unused        0       1 (out)\n# GPIO_C        0       0 (in)\n# GPIO_D        0       0 (in)\n# Unused        0       1 (out)\n\n# Signals definition\nftdi layout_signal LED -ndata 0x0010\nftdi layout_signal SWD_EN -data 0x0020\nftdi layout_signal SWDIO_OE -ndata 0x0040\nftdi layout_signal nSRST -oe 0x0080\n\nftdi layout_signal GPIO_A -data 0x0200 -oe 0x0200 -input 0x0200\nftdi layout_signal GPIO_B -data 0x0400 -oe 0x0400 -input 0x0400\nftdi layout_signal GPIO_C -data 0x2000 -oe 0x2000 -input 0x2000\nftdi layout_signal GPIO_D -data 0x4000 -oe 0x4000 -input 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/stm32-stick.cfg",
    "content": "#\n# Hitex STM32-PerformanceStick\n#\n# http://www.hitex.com/index.php?id=340\n#\n\nadapter driver ftdi\nftdi device_desc \"STM32-PerformanceStick\"\nftdi vid_pid 0x0640 0x002d\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/swd-resistor-hack.cfg",
    "content": "#\n# Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or\n# so depending on the drive capability of the target and adapter);\n# connect TDO directly to SWDIO.\n#\n# You also need to have reliable GND connection between the target and\n# adapter. Vref of the adapter should be supplied with a voltage equal\n# to the target's (preferably connect it to Vcc). You can also\n# optionally connect nSRST. Leave everything else unconnected.\n#\n# FTDI                          Target\n# ----                          ------\n# 1  - Vref   ----------------- Vcc\n# 3  - nTRST  -\n# 4  - GND    ----------------- GND\n# 5  - TDI    ---/\\470 Ohm/\\--- SWDIO\n# 7  - TMS    -\n# 9  - TCK    ----------------- SWCLK\n# 11 - RTCK   -\n# 13 - TDO    ----------------- SWDIO\n# 15 - nSRST  - - - - - - - - - nRESET\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -data 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/ti-icdi.cfg",
    "content": "#\n# This is an FTDI-based debugging solution as found on some TI boards,\n# e.g. CC3200 LaunchPad.\n#\n# The schematics are identical to luminary-icdi (including SWD\n# support) but the USB IDs are different.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0451 0xc32a\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/tigard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Tigard: An FTDI FT2232H-based multi-protocol tool for hardware hacking.\n# https://github.com/tigard-tools/tigard\n\nadapter driver ftdi\n\nftdi device_desc \"Tigard V1.1\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 1\n\nftdi layout_init 0x0038 0x003b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020\n\n# This board doesn't support open-drain reset modes since its output buffer is\n# always enabled.\nreset_config srst_push_pull trst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/tumpa-lite.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA) Lite\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a99\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/tumpa.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA)\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a98 0x0403 0x6010\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0010\n\nreset_config srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/turtelizer2-revB.cfg",
    "content": "#\n# egnite Turtelizer 2 rev B (with SRST only)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c5b\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/turtelizer2-revC.cfg",
    "content": "#\n# egnite Turtelizer 2 revC (with TRST and SRST)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c7b\nftdi layout_signal nTRST -oe 0x0020\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -ndata 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/um232h.cfg",
    "content": "#\n# FTDI UM232H as a JTAG interface\n#\n# http://www.ftdichip.com/Products/Modules/DevelopmentModules.htm#UM232H\n#\n# This should also work with a UM232H-B, but that has not been tested.\n# Note that UM232H and UM232H-B are 3.3V only.\n#\n\nadapter driver ftdi\n#ftdi device_desc \"UM232H\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0xfff8 0xfffb\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n\n# UM232H        FT232H    JTAG\n# Name  Pin     Name      Func\n# AD0   J2-6    ADBUS0    TCK\n# AD1   J2-7    ADBUS1    TDI\n# AD2   J2-8    ADBUS2    TDO\n# AD3   J2-9    ADBUS3    TMS\n# AD4   J2-10   ADBUS4    (GPIOL0)\n# AD5   J2-11   ADBUS5    (GPIOL1)\n# AD6   J2-12   ADBUS6    (GPIOL2)\n# AD7   J2-13   ADBUS7    (GPIOL3)\n# AD0   J1-14   ACBUS0    /TRST\n# AD1   J1-13   ACBUS1    /SRST\n# AD2   J1-12   ACBUS2    (GPIOH2)\n# AD3   J1-11   ACBUS3    (GPIOH3)\n# AD4   J1-10   ACBUS4    (GPIOH4)\n# AD5   J1-9    ACBUS5    (GPIOH5)\n# AD6   J1-8    ACBUS6    (GPIOH6)\n# AD7   J1-7    ACBUS7    (GPIOH7)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/vpaclink.cfg",
    "content": "#\n# Voipac VPACLink\n#\n# http://voipac.com/27M-JTG-000\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"VPACLink\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/xds100v2.cfg",
    "content": "#\n# Texas Instruments XDS100v2\n#\n# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features\n#\n# Detailed documentation is available only as CPLD verilog source code\n# to the registered TI users.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0xa6d0 0x0403 0x6010\n\nftdi layout_init 0x0038 0x597b\n\n#  8000 z - unused\n#  4000 0 > CPLD loopback          (all target side pins high-Z)\n#  2000 z < !( cable connected )   (open drain on CPLD side for $reasons)\n#  1000 0 > EMU1_oe\n#\n#   800 0 > PWR_RST = clear power-loss flag on rising edge\n#   400 z < !( power-loss flag )\n#   200 z < nSRST\n#   100 0 > nSRST_oe\n#\n#    80 z < RTCK\n#    40 0 > EMU0_oe\n#    20 1 > EMU_EN\n#    10 1 > nTRST\n#\n#     8 1 > TMS\n#     4 z < TDO\n#     2 0 > TDI\n#     1 0 > TCK\n#\n# As long as the power-loss flag is set, all target-side pins are\n# high-Z except the EMU-pins for which the opposite holds unless\n# EMU_EN is high.\n#\n# To use wait-in-reset, drive EMU0 low at power-on reset. If the\n# target normally reuses EMU0 for other purposes, clear EMU_EN to\n# keep the EMU pins high-Z until the target is power-cycled.\n#\n# The LED only turns off at USB suspend, which is also the only way to\n# set the power-loss flag manually. (Can be done in software e.g. by\n# changing the USB configuration to zero.)\n#\n\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0100\nftdi layout_signal EMU_EN -data 0x0020\nftdi layout_signal EMU0 -oe 0x0040\nftdi layout_signal EMU1 -oe 0x1000\nftdi layout_signal PWR_RST -data 0x0800\nftdi layout_signal LOOPBACK -data 0x4000\n\necho \"\\nInfo : to use this adapter you MUST add ``init; ftdi set_signal PWR_RST 1; jtag arp_init'' to the end of your config file!\\n\"\n# note: rising edge on PWR_RST is also needed after power-cycling the\n# target\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ftdi/xds100v3.cfg",
    "content": "#\n# Texas Instruments XDS100 ver 3.0\n#\n# http://processors.wiki.ti.com/index.php/XDS100\n#\n\n# Version 3.0 is the same as 2.0 as far as OpenOCD is concerned\nsource [find interface/ftdi/xds100v2.cfg]\n\n# The USB ids are different.\nftdi vid_pid 0x0403 0xa6d1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/imx-native.cfg",
    "content": "#\n# Config for using NXP IMX CPU\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches to host voltage and the cable is short enough.\n#\n#\n\nadapter driver imx_gpio\n\n# For most IMX processors 0x0209c000\nimx_gpio_peripheral_base 0x0209c000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for IMX6UL@528MHz\n# imx_gpio_speed SPEED_COEFF SPEED_OFFSET\nimx_gpio_speed_coeffs 50000 50\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo.\n# Example configuration:\n# imx_gpio_jtag_nums 6 7 8 9\n\n# SWD interface pins: swclk swdio\n# Example configuration:\nimx_gpio_swd_nums 1 6\n\n# imx_gpio_trst_num 10\n# reset_config trst_only\n\n# imx_gpio_srst_num 11\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/jlink.cfg",
    "content": "#\n# SEGGER J-Link\n#\n# http://www.segger.com/jlink.html\n#\n\nadapter driver jlink\n\n# The serial number can be used to select a specific device in case more than\n# one is connected to the host.\n#\n# Example: Select J-Link with serial number 123456789\n#\n# adapter serial 123456789\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/jtag_dpi.cfg",
    "content": "#\n# Provide support for the Cadence JTAG BFM\n#\n# Copyright (c) 2020, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\nadapter driver jtag_dpi\n\n# Set the DPI JTAG server port\nif { [info exists DPI_PORT] } {\n   set _DPI_PORT $DPI_PORT\n} else {\n   set _DPI_PORT 5555\n}\n\n# Set the DPI JTAG server address\nif { [info exists DPI_ADDRESS] } {\n   set _DPI_ADDRESS $DPI_ADDRESS\n} else {\n   set _DPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_dpi set_port $_DPI_PORT\njtag_dpi set_address $_DPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/jtag_hat_rpi2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Blinkinlabs JTAG_Hat\n#\n# https://github.com/blinkinlabs/jtag_hat\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio_peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio_speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio_jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio_swd_nums 11 25\n\n# Direction pin for SWDIO level shifting buffer\nbcm2835gpio_swdio_dir_num 6\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\nbcm2835gpio_trst_num 7\n#reset_config trst_only\n\nbcm2835gpio_srst_num 24\n#reset_config srst_only\n\n# or if you have both connected\n#reset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/jtag_vpi.cfg",
    "content": "adapter driver jtag_vpi\n\n# Set the VPI JTAG server port\nif { [info exists VPI_PORT] } {\n   set _VPI_PORT $VPI_PORT\n} else {\n   set _VPI_PORT 5555\n}\n\n# Set the VPI JTAG server address\nif { [info exists VPI_ADDRESS] } {\n   set _VPI_ADDRESS $VPI_ADDRESS\n} else {\n   set _VPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_vpi set_port $_VPI_PORT\njtag_vpi set_address $_VPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/kitprog.cfg",
    "content": "#\n# Cypress Semiconductor KitProg\n#\n# Note: This is the driver for the proprietary KitPtog protocol. If the\n# KitProg is in CMSIS-DAP mode, you should either use the cmsis-dap\n# interface driver or switch the KitProg to KitProg mode.\n#\n\nadapter driver kitprog\n\n# Optionally specify the serial number of the KitProg you want to use.\n# adapter serial 1926402735485200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/nds32-aice.cfg",
    "content": "#\n# Andes AICE\n#\n# http://www.andestech.com\n#\n\nadapter driver aice\naice desc \"Andes AICE adapter\"\n# adapter serial \"C001-42163\"\naice vid_pid 0x1CFC 0x0000\naice port aice_usb\nreset_config trst_and_srst\nadapter speed 24000\naice retry_times 50\naice count_to_check_dbger 30\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/nulink.cfg",
    "content": "#\n# Nuvoton Nu-Link in-circuit debugger/programmer\n#\n\nadapter driver hla\nhla_layout nulink\nhla_device_desc \"Nu-Link\"\nhla_vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201\n\n# Only swd is supported\ntransport select hla_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/opendous.cfg",
    "content": "#\n# opendous-jtag\n#\n# http://code.google.com/p/opendous-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/openjtag.cfg",
    "content": "#\n# OpenJTAG\n#\n# www.openjtag.org\n#\n\nadapter driver openjtag\nopenjtag device_desc \"Open JTAG Project\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/osbdm.cfg",
    "content": "#\n# P&E Micro OSBDM (aka OSJTAG) interface\n#\n# http://pemicro.com/osbdm/\n#\nadapter driver osbdm\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/parport.cfg",
    "content": "#\n# Parallel port wiggler (many clones available) on port 0x378\n#\n# Addresses: 0x378/LPT1 or 0x278/LPT2 ...\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   if {$tcl_platform(platform) eq \"windows\"} {\n      set _PARPORTADDR 0x378\n   } {\n      set _PARPORTADDR 0\n   }\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable wiggler\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/parport_dlc5.cfg",
    "content": "#\n# Xilinx Parallel Cable III 'DLC 5' (and various clones)\n#\n# http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable dlc5\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/raspberrypi-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x20000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 113714 28\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/raspberrypi2-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/rlink.cfg",
    "content": "#\n# Raisonance RLink\n#\n# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html\n#\n\nadapter driver rlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/rshim.cfg",
    "content": "#\n# BlueField SoC in-circuit debugger/programmer\n#\n\nadapter driver rshim\ntransport select dapdirect_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/stlink-dap.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n# This new interface driver creates a ST-Link wrapper for ARM-DAP named \"dapdirect\"\n# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support \"dapdirect\"\n#\n# SWIM transport is natively supported\n#\n\nadapter driver st-link\nst-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# transport select dapdirect_jtag\n# transport select dapdirect_swd\n# transport select swim\n\n# Optionally specify the serial number of usb device\n# e.g.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/stlink-v1.cfg",
    "content": "echo \"WARNING: interface/stlink-v1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/stlink-v2-1.cfg",
    "content": "echo \"WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/stlink-v2.cfg",
    "content": "echo \"WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/stlink.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n\nadapter driver hla\nhla_layout stlink\nhla_device_desc \"ST-LINK\"\nhla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# Optionally specify the serial number of ST-LINK/V2 usb device.  ST-LINK/V2\n# devices seem to have serial numbers with unreadable characters.  ST-LINK/V2\n# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial\n# number reset issues.\n# eg.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/sysfsgpio-raspberrypi.cfg",
    "content": "#\n# Config for using RaspberryPi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver sysfsgpio\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nsysfsgpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nsysfsgpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# sysfsgpio trst_num 7\n# reset_config trst_only\n\n# sysfsgpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ti-icdi.cfg",
    "content": "#\n# TI Stellaris In-Circuit Debug Interface (ICDI) Board\n#\n# This is the propriety ICDI interface used on newer boards such as\n# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232\n# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad\n# http://www.ti.com/tool/ek-lm4f232\n#\n\nadapter driver hla\nhla_layout ti-icdi\nhla_vid_pid 0x1cbe 0x00fd\n\n# Optionally specify the serial number of TI-ICDI devices, for when using\n# multiple devices. Serial numbers can be obtained using lsusb -v\n# Ex.\n# adapter serial \"0F003065\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/ulink.cfg",
    "content": "#\n# Keil ULINK running OpenULINK firmware.\n#\n# http://www.keil.com/ulink1/\n# http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362\n#\n\nadapter driver ulink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/usb-jtag.cfg",
    "content": "# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC.\n#\n# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware\n# including;\n#  * Xilinx USB Platform Cable\n#  * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards\n#  * Many fpga4fun.com boards from such as the Saxo and Xylo boards\n#  * The Numato Opsis\n#\n# Original version - http://www.ixo.de/info/usb_jtag/\n#  Updated version - http://ixo-jtag.sourceforge.net/\n#   Newest version - http://github.com/mithro/ixo-usb-jtag\n#\n# Procedure for using is;\n#  * Get the ixo-usb-jtag firmware for your hardware (or build it yourself).\n#  * Load the firmware using the fxload tool.\n#  * Use openocd.\n#\n# Unless you burn the firmware into the EEPROM on your device, power cycling\n# will require you to reload the firmware using the fxload tool. This can be\n# automated by using udev rules (which can be found in the firmware\n# repository).\n#\n# Ubuntu packages built from mithro's version (with prebuilt firmware and udev\n# rules) can be found at\n# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support\n#\n# TODO: Refactor the usb_blaster driver to allow loading firmware using any low\n# level driver. Loading firmware is currently only supported on the ublast2\n# driver but ixo-usb-jtag requires the ftdi driver.\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x16C0 0x06AD\nusb_blaster device_desc \"Van Ooijen Technische Informatica\"\n# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the\n# ftdi modes, using ublast2 will cause openocd to hang.\nusb_blaster lowlevel_driver ftdi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/usbprog.cfg",
    "content": "#\n# Embedded Projects USBprog\n#\n# http://embedded-projects.net/index.php?page_id=135\n#\n\nadapter driver usbprog\n# USBprog is broken w/short TMS sequences, this is a workaround\n# until the C code can be fixed.\ntms_sequence long\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/vdebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n\nif { [info exists VDEBUGHOST] } {\n\tset _VDEBUGHOST $VDEBUGHOST\n} else {\n\tset _VDEBUGHOST localhost\n}\nif { [info exists VDEBUGPORT] } {\n\tset _VDEBUGPORT $VDEBUGPORT\n} else {\n\tset _VDEBUGPORT 8192\n}\n\nadapter driver vdebug\n# vdebug server:port\nvdebug server $_VDEBUGHOST:$_VDEBUGPORT\n\n# example config debug level and log\n#debug_level 3\n#log_output vd_ocd.log\n\n# example config listen on all interfaces, disable tcl/telnet server\nbindto 0.0.0.0\n#gdb_port 3333\n#telnet_port disabled\ntcl_port disabled\n\n# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw\nvdebug batching 1\n\n# Polling values\nvdebug polling 100 1000"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/vsllink.cfg",
    "content": "#\n# Versaloon Link -- VSLLink\n#\n# http://www.versaloon.com/\n#\n\nadapter driver vsllink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/interface/xds110.cfg",
    "content": "#\n# Texas Instruments XDS110\n#\n# http://processors.wiki.ti.com/index.php/XDS110\n# http://processors.wiki.ti.com/index.php/Emulation_Software_Package#XDS110_Support_Utilities\n#\n\nadapter driver xds110\n\n# Use serial number option to use a specific XDS110\n# when more than one are connected to the host.\n# adapter serial 00000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/mem_helper.tcl",
    "content": "# Helper for common memory read/modify/write procedures\n\n# mrw: \"memory read word\", returns value of $reg\nproc mrw {reg} {\n\treturn [read_memory $reg 32 1]\n}\n\nadd_usage_text mrw \"address\"\nadd_help_text mrw \"Returns value of word in memory.\"\n\n# mrh: \"memory read halfword\", returns value of $reg\nproc mrh {reg} {\n\treturn [read_memory $reg 16 1]\n}\n\nadd_usage_text mrh \"address\"\nadd_help_text mrh \"Returns value of halfword in memory.\"\n\n# mrb: \"memory read byte\", returns value of $reg\nproc mrb {reg} {\n\treturn [read_memory $reg 8 1]\n}\n\nadd_usage_text mrb \"address\"\nadd_help_text mrb \"Returns value of byte in memory.\"\n\n# mmw: \"memory modify word\", updates value of $reg\n#       $reg <== ((value & ~$clearbits) | $setbits)\nproc mmw {reg setbits clearbits} {\n\tset old [mrw $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\tmww $reg $new\n}\n\nadd_usage_text mmw \"address setbits clearbits\"\nadd_help_text mmw \"Modify word in memory. new_val = (old_val & ~clearbits) | setbits;\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/memory.tcl",
    "content": "# MEMORY\n#\n# All Memory regions have two components.\n#    (1) A count of regions, in the form N_NAME\n#    (2) An array within info about each region.\n#\n# The ARRAY\n#\n#       <NAME>(  RegionNumber ,  ATTRIBUTE )\n#\n# Where <NAME> is one of:\n#\n#     N_FLASH  & FLASH   (internal memory)\n#     N_RAM    & RAM     (internal memory)\n#     N_MMREGS & MMREGS  (for memory mapped registers)\n#     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)\n# or  N_UNKNOWN & UNKNOWN for things that do not exist.\n#\n# We have 1 unknown region.\nset N_UNKNOWN 1\n# All MEMORY regions must have these attributes\n#     CS          - chip select (if internal, use -1)\nset UNKNOWN(0,CHIPSELECT) -1\n#     BASE        - base address in memory\nset UNKNOWN(0,BASE)       0\n#     LEN         - length in bytes\nset UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS\n#     HUMAN       - human name of the region\nset UNKNOWN(0,HUMAN) \"unknown\"\n#     TYPE        - one of:\n#                       flash, ram, mmr, unknown\n#                    For harvard arch:\n#                       iflash, dflash, iram, dram\nset UNKNOWN(0,TYPE)       \"unknown\"\n#     RWX         - access ablity\n#                       unix style chmod bits\n#                           0 - no access\n#                           1 - execute\n#                           2 - write\n#                           4 - read\n#                       hence: 7 - readwrite execute\nset RWX_NO_ACCESS     0\nset RWX_X_ONLY        $BIT0\nset RWX_W_ONLY        $BIT1\nset RWX_R_ONLY        $BIT2\nset RWX_RW            [expr {$RWX_R_ONLY + $RWX_W_ONLY}]\nset RWX_R_X           [expr {$RWX_R_ONLY + $RWX_X_ONLY}]\nset RWX_RWX           [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]\nset UNKNOWN(0,RWX)     $RWX_NO_ACCESS\n\n#     WIDTH       - access width\n#                      8,16,32 [0 means ANY]\nset ACCESS_WIDTH_NONE 0\nset ACCESS_WIDTH_8    $BIT0\nset ACCESS_WIDTH_16   $BIT1\nset ACCESS_WIDTH_32   $BIT2\nset ACCESS_WIDTH_ANY  [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]\nset UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE\n\nproc iswithin { ADDRESS BASE LEN } {\n    return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]\n}\n\nproc address_info { ADDRESS } {\n\n    foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {\n\tif { info exists $WHERE } {\n\t    set lmt [set N_[set WHERE]]\n\t    for { set region 0 } { $region < $lmt } { incr region } {\n\t\tif { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {\n\t\t    return  \"$WHERE $region\";\n\t\t}\n\t    }\n\t}\n    }\n\n    # Return the 'unknown'\n    return \"UNKNOWN 0\"\n}\n\nproc memread32 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n\nproc memread32_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/mmr_helpers.tcl",
    "content": "\nproc proc_exists { NAME } {\n    set n [info commands $NAME]\n    set l [string length $n]\n    return [expr {$l != 0}]\n}\n\n# Give: REGISTER name - must be a global variable.\nproc show_mmr32_reg { NAME } {\n\n    global $NAME\n    # we want $($NAME)\n    set a [set [set NAME]]\n\n    if ![catch { set v [memread32 $a] } msg ] {\n\techo [format \"%15s: (0x%08x): 0x%08x\" $NAME $a $v]\n\n\t# Was a helper defined?\n\tset fn show_${NAME}_helper\n\tif [ proc_exists $fn ] {\n\t    # Then call it\n\t    $fn $NAME $a $v\n\t}\n\treturn $v;\n    } else {\n\terror [format \"%s (%s)\" $msg $NAME ]\n    }\n}\n\n\n# Give: NAMES - an array of names accessible\n#               in the callers symbol-scope.\n#       VAL - the bits to display.\n\nproc show_mmr32_bits { NAMES VAL } {\n\n    upvar $NAMES MYNAMES\n\n    set w 5\n    foreach {IDX N} $MYNAMES {\n\tset l [string length $N]\n\tif { $l > $w } { set w $l }\n    }\n\n    for { set x 24 } { $x >= 0 } { incr x -8 } {\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    set s $MYNAMES([expr {$x + $y}])\n\t    echo -n [format \"%2d: %-*s | \" [expr {$x + $y}] $w $s ]\n\t}\n\techo \"\"\n\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    echo -n [format \"    %d%*s | \" [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] \"\"]\n\t}\n\techo \"\"\n    }\n}\n\n\nproc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } {\n    set width [expr {(($MSB - $LSB + 1) + 7) / 4}]\n    set nval [show_normalize_bitfield $VAL $MSB $LSB ]\n    set name0 [lindex $FIELDVALUES 0 ]\n    if [ string compare $name0 _NUMBER_ ] {\n\tset sval [lindex $FIELDVALUES $nval]\n    } else {\n\tset sval \"\"\n    }\n    echo [format \"%-15s: %d (0x%0*x) %s\" $FIELDNAME $nval $width $nval $sval ]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/1986ве1т.cfg",
    "content": "# 1986ВЕ1Т\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=236&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME 1986ве1т\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# use AHB-Lite SRAM for work area\n$_TARGETNAME configure -work-area-phys 0x20100000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/adsp-sc58x.cfg",
    "content": "#\n# Analog Devices ADSP-SC58x (ARM Cortex-A5 plus one or two SHARC+ DSPs)\n#\n\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ADSP-SC58x\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3BA02477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ap0.mem mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -event examine-end {\n   global _TARGETNAME\n   sc58x_enabledebug\n}\n\nproc sc58x_enabledebug {} {\n   # Enable debugging functionality by setting bits in the TAPC_DBGCTL register\n   # it is not possible to halt the target unless these bits have been set\n   ap0.mem mww 0x31131000 0xFFFF\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/aduc702x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aduc702x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n## JTAG scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# allocate the entire SRAM as working area\n$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000\n\n## flash configuration\n# only target number is needed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n## If you use the watchdog, the following code makes sure that the board\n## doesn't reboot when halted via JTAG.  Yes, on the older generation\n## AdUC702x, timer3 continues running even when the CPU is halted.\n\nproc watchdog_service {} {\n    global watchdog_hdl\n    mww 0xffff036c 0\n#    echo \"watchdog!!\"\n    set watchdog_hdl [after 500 watchdog_service]\n}\n\n$_TARGETNAME configure -event reset-halt-post {  watchdog_service }\n$_TARGETNAME configure -event resume-start { global watchdog_hdl; after cancel $watchdog_hdl }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/aducm360.cfg",
    "content": "#\n# This file was created using as references the stm32f1x.cfg and aduc702x.cfg\n#\nsource [find target/swj-dp.tcl]\n\n# Chip name\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aducm360\n}\n\n# Endianness\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# Eventually, the whole SRAM of ADuCM360 will be used (8kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# SWD/JTAG speed\nadapter speed 1000\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# allocate the working area\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME\n\nadapter srst delay 100\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/allwinner_v3s.cfg",
    "content": "# This is the config for an Allwinner V3/V3s (sun8iw8).\n#\n# Notes:\n# - Single core ARM Cortex-A7 with a maximum frequency of 1.2 GHz.\n# - Thumb-2 Technology\n# - Support NEON Advanced SIMD(Single Instruction Multiple Data)instruction\n#   for acceleration of media and signal processing functions\n# - Support Large Physical Address Extensions(LPAE)\n# - VFPv4 Floating Point Unit\n# - 32KB L1 Instruction cache and 32KB L1 Data cache\n# - 128KB L2 cache\n# - has some integrated DDR2 RAM.\n#\n# Pins related for debug and bootstrap:\n#   JTAG\n# JTAG_TMS\tPF0, SDC0_D1\n# JTAG_TDI\tPF1, SDC0_D0\n# JTAG_TDO\tPF3, SDC0_CMD\n# JTAG_TCK\tPF5, SDC0_D2\n#   UART\n# None of UART ports seems to be enabled by ROM.\n# UART0_TX\tPF2, SDC0_CLK\t\tPer default disabled\n# UART0_RX\tPF4, SDC0_D3 \t\tPer default disabled\n# UART1_TX\tPE21\t\t\tPer default disabled\n# UART1_RX\tPE22\t \t\tPer default disabled\n# UART2_TX\tPB0\t\t\tPer default disabled\n# UART2_RX\tPB1\t \t\tPer default disabled\n#\n# JTAG is enabled by default after power on on listed JTAG_* pins. So far the\n# boot sequence is:\n# Time\t\tAction\n# 0000ms\tPower ON\n# 0200ms\tJTAG enabled\n# 0220ms\tJTAG pins switched to SD mode\n#\n# The time frame of 20ms can be not enough to init and halt the CPU. In this\n# case I would recommend to set: \"adapter speed 15000\"\n# To get more or less precise timings, the board should provide reset pin,\n# or some bench power supply with remote function. In my case I used\n# EEZ H24005 with this command to power on and halt the target:\n# \"exec  echo \"*TRG\" > /dev/ttyACM0; sleep 220; reset halt\"\n# After this it is possible to enable JTAG mode again from boot loader or OS.\n# Following DAPs are available:\n# dap[0]->MEM-AP AHB\n# dap[1]->MEM-AP APB->CA7[0]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME v3s\n}\n\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# No NRST or SRST is present on the SoC. Boards may provide\n# some sort of Power cycle reset for complete board or SoC.\n# For this case we provide srst_pulls_trst so the board config\n# only needs to set srst_only.\nreset_config none srst_pulls_trst\n\njtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Add Cortex A7 core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/alphascale_asm9260t.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME asm9260t\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x079264F3\n}\n\n# And srst_pulls_trst by chip design.\nreset_config srst_pulls_trst\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/altera_fpgasoc.cfg",
    "content": "#\n# Altera cyclone V SoC family, 5Cxxx\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME fpgasoc\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga\nif { [info exists FPGA_TAPID] } {\n   set _FPGA_TAPID $FPGA_TAPID\n} else {\n   set _FPGA_TAPID 0x02d020dd\n}\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected-id $_FPGA_TAPID\n\n\n#\n# Cortex-A9 target\n#\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80110000\n# core 1  -  0x80112000\n\n# Slow speed to be sure it will work\nadapter speed 1000\n\nset _TARGETNAME1 $_CHIPNAME.cpu.0\nset _TARGETNAME2 $_CHIPNAME.cpu.1\n\n# A9 core 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80110000\n\n$_TARGETNAME1 configure -event reset-start { adapter speed 1000 }\n$_TARGETNAME1 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME1\"\n\n\n# A9 core 1\n#target create $_TARGETNAME2 cortex_a -dap $_CHIPNAME.dap \\\n#        -coreid 1 -dbgbase 0x80112000\n\n#$_TARGETNAME2 configure -event reset-start { adapter speed 1000 }\n#$_TARGETNAME2 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME2\"\n\nproc cycv_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/altera_fpgasoc_arria10.cfg",
    "content": "# Intel (Altera) Arria10 FPGA SoC\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME arria10\n}\n\n# ARM CoreSight Debug Access Port (dap HPS)\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga (tap)\n# See Intel Arria 10 Handbook\n# https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-10/a10_handbook.pdf\n# Intel Arria 10 GX 160  0x02ee20dd\n# Intel Arria 10 GX 220  0x02e220dd\n# Intel Arria 10 GX 270  0x02ee30dd\n# Intel Arria 10 GX 320  0x02e230dd\n# Intel Arria 10 GX 480  0x02e240dd\n# Intel Arria 10 GX 570  0x02ee50dd\n# Intel Arria 10 GX 660  0x02e250dd\n# Intel Arria 10 GX 900  0x02ee60dd\n# Intel Arria 10 GX 1150 0x02e660dd\n# Intel Arria 10 GT 900  0x02e260dd\n# Intel Arria 10 GT 1150 0x02e060dd\n# Intel Arria 10 SX 160  0x02e620dd\n# Intel Arria 10 SX 220  0x02e020dd\n# Intel Arria 10 SX 270  0x02e630dd\n# Intel Arria 10 SX 320  0x02e030dd\n# Intel Arria 10 SX 480  0x02e040dd\n# Intel Arria 10 SX 570  0x02e650dd\n# Intel Arria 10 SX 660  0x02e050dd\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -expected-id 0x02ee20dd -expected-id 0x02e220dd \\\n\t-expected-id 0x02ee30dd -expected-id 0x02e230dd -expected-id 0x02e240dd \\\n\t-expected-id 0x02ee50dd -expected-id 0x02e250dd -expected-id 0x02ee60dd \\\n\t-expected-id 0x02e660dd -expected-id 0x02e260dd -expected-id 0x02e060dd \\\n\t-expected-id 0x02e620dd -expected-id 0x02e020dd -expected-id 0x02e630dd \\\n\t-expected-id 0x02e030dd -expected-id 0x02e040dd -expected-id 0x02e650dd \\\n\t-expected-id 0x02e050dd\n\nset _TARGETNAME $_CHIPNAME.cpu\n\n#\n# Cortex-A9 target\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap -coreid 0\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap -coreid 1 \\\n\t-defer-examine\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/am335x.cfg",
    "content": "source [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME am335x\n}\n\n# set the taps to be enabled by default. this can be overridden\n# by setting DEFAULT_TAPS in a separate configuration file\n# or directly on the command line.\nif { [info exists DEFAULT_TAPS] } {\n\tset _DEFAULT_TAPS \"$DEFAULT_TAPS\"\n} else {\n\tset _DEFAULT_TAPS \"$_CHIPNAME.tap\"\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 12 0\"\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# M3 DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME m3_tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m3_tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 11 0\"\ndap create $_CHIPNAME.m3_dap -chain-position $_CHIPNAME.m3_tap\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0b94402f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup {\n\tglobal _DEFAULT_TAPS\n\tenable_default_taps $_DEFAULT_TAPS\n}\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n#\n# helper function that enables all taps passed as argument\n#\nproc enable_default_taps { taps } {\n\tforeach tap $taps {\n\t\tjtag tapenable $tap\n\t}\n}\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME_2 $_CHIPNAME.m3\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.m3_dap\n\n#\n# Cortex-A8 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80001000\n\n# SRAM: 64K at 0x4030.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x4000\n\n\n# when putting the target into 'reset halt', we need to disable the watchdog as\n# it would otherwise trigger while we're in JTAG\n# FIXME: unify with target/am437x.cfg\nsource [find mem_helper.tcl]\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/am437x.cfg",
    "content": "source [find target/icepick.cfg]\nsource [find mem_helper.tcl]\n\n###############################################################################\n##\t\t\t\tAM437x Registers\t\t\t     ##\n###############################################################################\nset  PRCM_BASE_ADDR                  0x44df0000\nset  REVISION_PRM                    [expr       {$PRCM_BASE_ADDR     +  0x0000}]\nset  PRM_IRQSTATUS_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0004}]\nset  PRM_IRQENABLE_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0008}]\nset  PRM_IRQSTATUS_M3                [expr       {$PRCM_BASE_ADDR     +  0x000c}]\nset  PRM_IRQENABLE_M3                [expr       {$PRCM_BASE_ADDR     +  0x0010}]\nset  PM_MPU_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0300}]\nset  PM_MPU_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0304}]\nset  RM_MPU_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0314}]\nset  RM_MPU_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0324}]\nset  PM_GFX_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0400}]\nset  PM_GFX_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0404}]\nset  RM_GFX_RSTCTRL                  [expr       {$PRCM_BASE_ADDR     +  0x0410}]\nset  RM_GFX_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0414}]\nset  RM_GFX_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0424}]\nset  RM_RTC_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0524}]\nset  RM_WKUP_RSTCTRL                 [expr       {$PRCM_BASE_ADDR     +  0x2010}]\nset  RM_WKUP_RSTST                   [expr       {$PRCM_BASE_ADDR     +  0x2014}]\nset  CM_L3_AON_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x2800}]\nset  CM_WKUP_DEBUGSS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2820}]\nset  CM_L3S_TSC_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2900}]\nset  CM_WKUP_ADC_TSC_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2920}]\nset  CM_L4_WKUP_AON_CLKSTCTRL        [expr       {$PRCM_BASE_ADDR     +  0x2a00}]\nset  CM_WKUP_L4WKUP_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2a20}]\nset  CM_WKUP_WKUP_M3_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a28}]\nset  CM_WKUP_SYNCTIMER_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a30}]\nset  CM_WKUP_CLKDIV32K_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a38}]\nset  CM_WKUP_USBPHY0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a40}]\nset  CM_WKUP_USBPHY1_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a48}]\nset  CM_WKUP_CLKSTCTRL               [expr       {$PRCM_BASE_ADDR     +  0x2b00}]\nset  CM_WKUP_TIMER0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b20}]\nset  CM_WKUP_TIMER1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b28}]\nset  CM_WKUP_WDT0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b30}]\nset  CM_WKUP_WDT1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b38}]\nset  CM_WKUP_I2C0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b40}]\nset  CM_WKUP_UART0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b48}]\nset  CM_WKUP_SMARTREFLEX0_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b50}]\nset  CM_WKUP_SMARTREFLEX1_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b58}]\nset  CM_WKUP_CONTROL_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2b60}]\nset  CM_WKUP_GPIO0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b68}]\nset  CM_CLKMODE_DPLL_CORE            [expr       {$PRCM_BASE_ADDR     +  0x2d20}]\nset  CM_IDLEST_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d24}]\nset  CM_CLKSEL_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d2c}]\nset  CM_DIV_M4_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d38}]\nset  CM_DIV_M5_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d3c}]\nset  CM_DIV_M6_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d40}]\nset  CM_SSC_DELTAMSTEP_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d48}]\nset  CM_SSC_MODFREQDIV_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d4c}]\nset  CM_CLKMODE_DPLL_MPU             [expr       {$PRCM_BASE_ADDR     +  0x2d60}]\nset  CM_IDLEST_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d64}]\nset  CM_CLKSEL_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d6c}]\nset  CM_DIV_M2_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d70}]\nset  CM_SSC_DELTAMSTEP_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d88}]\nset  CM_SSC_MODFREQDIV_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d8c}]\nset  CM_CLKMODE_DPLL_DDR             [expr       {$PRCM_BASE_ADDR     +  0x2da0}]\nset  CM_IDLEST_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2da4}]\nset  CM_CLKSEL_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2dac}]\nset  CM_DIV_M2_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db0}]\nset  CM_DIV_M4_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db8}]\nset  CM_SSC_DELTAMSTEP_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dc8}]\nset  CM_SSC_MODFREQDIV_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dcc}]\nset  CM_CLKMODE_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2de0}]\nset  CM_IDLEST_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2de4}]\nset  CM_CLKSEL_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2dec}]\nset  CM_DIV_M2_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2df0}]\nset  CM_CLKSEL2_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2e04}]\nset  CM_SSC_DELTAMSTEP_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e08}]\nset  CM_SSC_MODFREQDIV_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e0c}]\nset  CM_CLKDCOLDO_DPLL_PER           [expr       {$PRCM_BASE_ADDR     +  0x2e14}]\nset  CM_CLKMODE_DPLL_DISP            [expr       {$PRCM_BASE_ADDR     +  0x2e20}]\nset  CM_IDLEST_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e24}]\nset  CM_CLKSEL_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e2c}]\nset  CM_DIV_M2_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e30}]\nset  CM_SSC_DELTAMSTEP_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e48}]\nset  CM_SSC_MODFREQDIV_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e4c}]\nset  CM_CLKMODE_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e60}]\nset  CM_IDLEST_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e64}]\nset  CM_CLKSEL_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e6c}]\nset  CM_DIV_M2_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e70}]\nset  CM_CLKSEL2_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e84}]\nset  CM_SSC_DELTAMSTEP_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e88}]\nset  CM_SSC_MODFREQDIV_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e8c}]\nset  CM_SHADOW_FREQ_CONFIG1          [expr       {$PRCM_BASE_ADDR     +  0x2fa0}]\nset  CM_SHADOW_FREQ_CONFIG2          [expr       {$PRCM_BASE_ADDR     +  0x2fa4}]\nset  CM_CLKOUT1_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4100}]\nset  CM_DLL_CTRL                     [expr       {$PRCM_BASE_ADDR     +  0x4104}]\nset  CM_CLKOUT2_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4108}]\nset  CLKSEL_TIMER1MS_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4200}]\nset  CLKSEL_TIMER2_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4204}]\nset  CLKSEL_TIMER3_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4208}]\nset  CLKSEL_TIMER4_CLK               [expr       {$PRCM_BASE_ADDR     +  0x420c}]\nset  CLKSEL_TIMER5_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4210}]\nset  CLKSEL_TIMER6_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4214}]\nset  CLKSEL_TIMER7_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4218}]\nset  CLKSEL_TIMER8_CLK               [expr       {$PRCM_BASE_ADDR     +  0x421c}]\nset  CLKSEL_TIMER9_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4220}]\nset  CLKSEL_TIMER10_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4224}]\nset  CLKSEL_TIMER11_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4228}]\nset  CLKSEL_WDT1_CLK                 [expr       {$PRCM_BASE_ADDR     +  0x422c}]\nset  CLKSEL_SYNCTIMER_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4230}]\nset  CLKSEL_MAC_CLK                  [expr       {$PRCM_BASE_ADDR     +  0x4234}]\nset  CLKSEL_CPTS_RFT_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4238}]\nset  CLKSEL_GFX_FCLK                 [expr       {$PRCM_BASE_ADDR     +  0x423c}]\nset  CLKSEL_GPIO0_DBCLK              [expr       {$PRCM_BASE_ADDR     +  0x4240}]\nset  CLKSEL_LCDC_PIXEL_CLK           [expr       {$PRCM_BASE_ADDR     +  0x4244}]\nset  CLKSEL_ICSS_OCP_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4248}]\nset  CLKSEL_DLL_AGING_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4250}]\nset  CLKSEL_USBPHY32KHZ_GCLK         [expr       {$PRCM_BASE_ADDR     +  0x4260}]\nset  CM_MPU_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8300}]\nset  CM_MPU_MPU_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8320}]\nset  CM_GFX_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8400}]\nset  CM_GFX_GFX_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8420}]\nset  CM_RTC_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8500}]\nset  CM_RTC_RTC_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8520}]\nset  CM_PER_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8800}]\nset  CM_PER_L3_CLKCTRL               [expr       {$PRCM_BASE_ADDR     +  0x8820}]\nset  CM_PER_AES0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8828}]\nset  CM_PER_DES_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8830}]\nset  CM_PER_CRYPTODMA_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8838}]\nset  CM_PER_L3_INSTR_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8840}]\nset  CM_PER_MSTR_EXPS_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8848}]\nset  CM_PER_OCMCRAM_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8850}]\nset  CM_PER_SHA0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8858}]\nset  CM_PER_SLV_EXPS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8860}]\nset  CM_PER_VPFE0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8868}]\nset  CM_PER_VPFE1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8870}]\nset  CM_PER_TPCC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8878}]\nset  CM_PER_TPTC0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8880}]\nset  CM_PER_TPTC1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8888}]\nset  CM_PER_TPTC2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8890}]\nset  CM_PER_DLL_AGING_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8898}]\nset  CM_PER_L4HS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a0}]\nset  CM_PER_L4FW_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a8}]\nset  CM_PER_L3S_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8a00}]\nset  CM_PER_GPMC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a20}]\nset  CM_PER_IEEE5000_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8a28}]\nset  CM_PER_MCASP0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a38}]\nset  CM_PER_MCASP1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a40}]\nset  CM_PER_MMC2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a48}]\nset  CM_PER_QSPI_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a58}]\nset  CM_PER_USB_OTG_SS0_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a60}]\nset  CM_PER_USB_OTG_SS1_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a68}]\nset  CM_PER_ICSS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8b00}]\nset  CM_PER_ICSS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8b20}]\nset  CM_PER_L4LS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8c00}]\nset  CM_PER_L4LS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8c20}]\nset  CM_PER_DCAN0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c28}]\nset  CM_PER_DCAN1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c30}]\nset  CM_PER_EPWMSS0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c38}]\nset  CM_PER_EPWMSS1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c40}]\nset  CM_PER_EPWMSS2_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c48}]\nset  CM_PER_EPWMSS3_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c50}]\nset  CM_PER_EPWMSS4_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c58}]\nset  CM_PER_EPWMSS5_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c60}]\nset  CM_PER_ELM_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8c68}]\nset  CM_PER_GPIO1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c78}]\nset  CM_PER_GPIO2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c80}]\nset  CM_PER_GPIO3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c88}]\nset  CM_PER_GPIO4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c90}]\nset  CM_PER_GPIO5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c98}]\nset  CM_PER_HDQ1W_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8ca0}]\nset  CM_PER_I2C1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8ca8}]\nset  CM_PER_I2C2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cb0}]\nset  CM_PER_MAILBOX0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8cb8}]\nset  CM_PER_MMC0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc0}]\nset  CM_PER_MMC1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc8}]\nset  CM_PER_PKA_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8cd0}]\nset  CM_PER_RNG_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8ce0}]\nset  CM_PER_SPARE0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8ce8}]\nset  CM_PER_SPARE1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8cf0}]\nset  CM_PER_SPI0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d00}]\nset  CM_PER_SPI1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d08}]\nset  CM_PER_SPI2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d10}]\nset  CM_PER_SPI3_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d18}]\nset  CM_PER_SPI4_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d20}]\nset  CM_PER_SPINLOCK_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8d28}]\nset  CM_PER_TIMER2_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d30}]\nset  CM_PER_TIMER3_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d38}]\nset  CM_PER_TIMER4_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d40}]\nset  CM_PER_TIMER5_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d48}]\nset  CM_PER_TIMER6_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d50}]\nset  CM_PER_TIMER7_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d58}]\nset  CM_PER_TIMER8_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d60}]\nset  CM_PER_TIMER9_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d68}]\nset  CM_PER_TIMER10_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d70}]\nset  CM_PER_TIMER11_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d78}]\nset  CM_PER_UART1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d80}]\nset  CM_PER_UART2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d88}]\nset  CM_PER_UART3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d90}]\nset  CM_PER_UART4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d98}]\nset  CM_PER_UART5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8da0}]\nset  CM_PER_USBPHYOCP2SCP0_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8db8}]\nset  CM_PER_USBPHYOCP2SCP1_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8dc0}]\nset  CM_PER_EMIF_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8f00}]\nset  CM_PER_EMIF_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8f20}]\nset  CM_PER_DLL_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8f28}]\nset  CM_PER_EMIF_FW_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8f30}]\nset  CM_PER_OTFA_EMIF_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8f38}]\nset  CM_PER_DSS_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9200}]\nset  CM_PER_DSS_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x9220}]\nset  CM_PER_CPSW_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x9300}]\nset  CM_PER_CPGMAC0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x9320}]\nset  CM_PER_OCPWP_L3_CLKSTCTRL       [expr       {$PRCM_BASE_ADDR     +  0x9400}]\nset  CM_PER_OCPWP_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9420}]\n\nset  CONTROL_BASE_ADDR               0x44e10000\nset  CONTROL_STATUS                  [expr       {$CONTROL_BASE_ADDR  +  0x0040}]\nset  DEVICE_ID                       [expr       {$CONTROL_BASE_ADDR  +  0x0600}]\nset  DEV_FEATURE                     [expr       {$CONTROL_BASE_ADDR  +  0x0604}]\nset  DEV_ATTRIBUTE                   [expr       {$CONTROL_BASE_ADDR  +  0x0610}]\nset  MAC_ID0_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0630}]\nset  MAC_ID0_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x0634}]\nset  MAC_ID1_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0638}]\nset  MAC_ID1_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x063c}]\nset  USB_VID_PID                     [expr       {$CONTROL_BASE_ADDR  +  0x07f4}]\nset  CONTROL_CONF_ECAP0_IN_PWM0_OUT  [expr       {$CONTROL_BASE_ADDR  +  0x0964}]\nset  CONTROL_CONF_SPI4_CS0           [expr       {$CONTROL_BASE_ADDR  +  0x0a5c}]\nset  CONTROL_CONF_SPI2_SCLK          [expr       {$CONTROL_BASE_ADDR  +  0x0a60}]\nset  CONTROL_CONF_SPI2_D0            [expr       {$CONTROL_BASE_ADDR  +  0x0a64}]\nset  CONTROL_CONF_XDMA_EVENT_INTR0   [expr       {$CONTROL_BASE_ADDR  +  0x0a70}]\nset  CONTROL_CONF_XDMA_EVENT_INTR1   [expr       {$CONTROL_BASE_ADDR  +  0x0a74}]\nset  CONTROL_CONF_GPMC_A0            [expr       {$CONTROL_BASE_ADDR  +  0x0840}]\nset  DDR_IO_CTRL                     [expr       {$CONTROL_BASE_ADDR  +  0x0e04}]\nset  VTP_CTRL_REG                    [expr       {$CONTROL_BASE_ADDR  +  0x0e0c}]\nset  VREF_CTRL                       [expr       {$CONTROL_BASE_ADDR  +  0x0e14}]\nset  DDR_CKE_CTRL                    [expr       {$CONTROL_BASE_ADDR  +  0x131c}]\nset  DDR_ADDRCTRL_IOCTRL             [expr       {$CONTROL_BASE_ADDR  +  0x1404}]\nset  DDR_ADDRCTRL_WD0_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x1408}]\nset  DDR_ADDRCTRL_WD1_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x140c}]\nset  DDR_DATA0_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1440}]\nset  DDR_DATA1_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1444}]\nset  DDR_DATA2_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1448}]\nset  DDR_DATA3_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x144c}]\nset  EMIF_SDRAM_CONFIG_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1460}]\nset  EMIF_SDRAM_STATUS_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1464}]\n\nset  GPIO0_BASE_ADDR                 0x44e07000\nset  GPIO0_SYSCONFIG                 [expr       {$GPIO0_BASE_ADDR    +  0x0010}]\nset  GPIO0_SYSSTATUS                 [expr       {$GPIO0_BASE_ADDR    +  0x0114}]\nset  GPIO0_CTRL                      [expr       {$GPIO0_BASE_ADDR    +  0x0130}]\nset  GPIO0_OE                        [expr       {$GPIO0_BASE_ADDR    +  0x0134}]\nset  GPIO0_CLEARDATAOUT              [expr       {$GPIO0_BASE_ADDR    +  0x0190}]\nset  GPIO0_SETDATAOUT                [expr       {$GPIO0_BASE_ADDR    +  0x0194}]\n\nset  GPIO5_BASE_ADDR                 0x48322000\nset  GPIO5_SYSCONFIG                 [expr       {$GPIO5_BASE_ADDR    +  0x0010}]\nset  GPIO5_SYSSTATUS                 [expr       {$GPIO5_BASE_ADDR    +  0x0114}]\nset  GPIO5_CTRL                      [expr       {$GPIO5_BASE_ADDR    +  0x0130}]\nset  GPIO5_OE                        [expr       {$GPIO5_BASE_ADDR    +  0x0134}]\nset  GPIO5_CLEARDATAOUT              [expr       {$GPIO5_BASE_ADDR    +  0x0190}]\nset  GPIO5_SETDATAOUT                [expr       {$GPIO5_BASE_ADDR    +  0x0194}]\n\nset  GPIO1_BASE_ADDR                 0x4804c000\nset  GPIO1_SYSCONFIG                 [expr       {$GPIO1_BASE_ADDR    +  0x0010}]\nset  GPIO1_SYSSTATUS                 [expr       {$GPIO1_BASE_ADDR    +  0x0114}]\nset  GPIO1_CTRL                      [expr       {$GPIO1_BASE_ADDR    +  0x0130}]\nset  GPIO1_OE                        [expr       {$GPIO1_BASE_ADDR    +  0x0134}]\nset  GPIO1_CLEARDATAOUT              [expr       {$GPIO1_BASE_ADDR    +  0x0190}]\nset  GPIO1_SETDATAOUT                [expr       {$GPIO1_BASE_ADDR    +  0x0194}]\n\nset  EMIF_BASE_ADDR                  0x4c000000\nset  EMIF_STATUS                     [expr       {$EMIF_BASE_ADDR     +  0x0004}]\nset  EMIF_SDRAM_CONFIG               [expr       {$EMIF_BASE_ADDR     +  0x0008}]\nset  EMIF_SDRAM_CONFIG_2             [expr       {$EMIF_BASE_ADDR     +  0x000c}]\nset  EMIF_SDRAM_REF_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0010}]\nset  EMIF_SDRAM_REF_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0014}]\nset  EMIF_SDRAM_TIM_1                [expr       {$EMIF_BASE_ADDR     +  0x0018}]\nset  EMIF_SDRAM_TIM_1_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x001c}]\nset  EMIF_SDRAM_TIM_2                [expr       {$EMIF_BASE_ADDR     +  0x0020}]\nset  EMIF_SDRAM_TIM_2_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x0024}]\nset  EMIF_SDRAM_TIM_3                [expr       {$EMIF_BASE_ADDR     +  0x0028}]\nset  EMIF_SDRAM_TIM_3_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x002c}]\nset  EMIF_LPDDR2_NVM_TIM             [expr       {$EMIF_BASE_ADDR     +  0x0030}]\nset  EMIF_LPDDR2_NVM_TIM_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0034}]\nset  EMIF_PWR_MGMT_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x0038}]\nset  EMIF_PWR_MGMT_CTRL_SHDW         [expr       {$EMIF_BASE_ADDR     +  0x003c}]\nset  EMIF_LPDDR2_MODE_REG_DATA       [expr       {$EMIF_BASE_ADDR     +  0x0040}]\nset  EMIF_LPDDR2_MODE_REG_CFG        [expr       {$EMIF_BASE_ADDR     +  0x0050}]\nset  EMIF_OCP_CONFIG                 [expr       {$EMIF_BASE_ADDR     +  0x0054}]\nset  EMIF_OCP_CFG_VAL_1              [expr       {$EMIF_BASE_ADDR     +  0x0058}]\nset  EMIF_OCP_CFG_VAL_2              [expr       {$EMIF_BASE_ADDR     +  0x005c}]\nset  EMIF_IODFT_TLGC                 [expr       {$EMIF_BASE_ADDR     +  0x0060}]\nset  EMIF_IODFT_CTRL_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0064}]\nset  EMIF_IODFT_ADDR_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0068}]\nset  EMIF_IODFT_DATA_MISR_RSLT_1     [expr       {$EMIF_BASE_ADDR     +  0x006c}]\nset  EMIF_IODFT_DATA_MISR_RSLT_2     [expr       {$EMIF_BASE_ADDR     +  0x0070}]\nset  EMIF_IODFT_DATA_MISR_RSLT_3     [expr       {$EMIF_BASE_ADDR     +  0x0074}]\nset  EMIF_PERF_CNT_1                 [expr       {$EMIF_BASE_ADDR     +  0x0080}]\nset  EMIF_PERF_CNT_2                 [expr       {$EMIF_BASE_ADDR     +  0x0084}]\nset  EMIF_PERF_CNT_CFG               [expr       {$EMIF_BASE_ADDR     +  0x0088}]\nset  EMIF_PERF_CNT_SEL               [expr       {$EMIF_BASE_ADDR     +  0x008c}]\nset  EMIF_PERF_CNT_TIM               [expr       {$EMIF_BASE_ADDR     +  0x0090}]\nset  EMIF_MISC_REG                   [expr       {$EMIF_BASE_ADDR     +  0x0094}]\nset  EMIF_DLL_CALIB_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0098}]\nset  EMIF_DLL_CALIB_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x009c}]\nset  EMIF_IRQ_EOI                    [expr       {$EMIF_BASE_ADDR     +  0x00a0}]\nset  EMIF_IRQSTATUS_RAW_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00a4}]\nset  EMIF_IRQSTATUS_SYS              [expr       {$EMIF_BASE_ADDR     +  0x00ac}]\nset  EMIF_IRQENABLE_SET_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00b4}]\nset  EMIF_IRQENABLE_CLR_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00bc}]\nset  EMIF_ZQ_CONFIG                  [expr       {$EMIF_BASE_ADDR     +  0x00c8}]\nset  EMIF_TEMP_ALERT_CONFIG          [expr       {$EMIF_BASE_ADDR     +  0x00cc}]\nset  EMIF_OCP_ERR_LOG                [expr       {$EMIF_BASE_ADDR     +  0x00d0}]\nset  EMIF_RDWR_LVL_RMP_WIN           [expr       {$EMIF_BASE_ADDR     +  0x00d4}]\nset  EMIF_RDWR_LVL_RMP_CTRL          [expr       {$EMIF_BASE_ADDR     +  0x00d8}]\nset  EMIF_RDWR_LVL_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x00dc}]\nset  EMIF_DDR_PHY_CTRL_1             [expr       {$EMIF_BASE_ADDR     +  0x00e4}]\nset  EMIF_DDR_PHY_CTRL_1_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x00e8}]\nset  EMIF_DDR_PHY_CTRL_2             [expr       {$EMIF_BASE_ADDR     +  0x00ec}]\nset  EMIF_PRI_COS_MAP                [expr       {$EMIF_BASE_ADDR     +  0x0100}]\nset  EMIF_CONNID_COS_1_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0104}]\nset  EMIF_CONNID_COS_2_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0108}]\nset  ECC_CTRL                        [expr       {$EMIF_BASE_ADDR     +  0x0110}]\nset  ECC_ADDR_RNG_1                  [expr       {$EMIF_BASE_ADDR     +  0x0114}]\nset  ECC_ADDR_RNG_2                  [expr       {$EMIF_BASE_ADDR     +  0x0118}]\nset  EMIF_RD_WR_EXEC_THRSH           [expr       {$EMIF_BASE_ADDR     +  0x0120}]\nset  COS_CONFIG                      [expr       {$EMIF_BASE_ADDR     +  0x0124}]\n\nset  PHY_STATUS_1                    [expr       {$EMIF_BASE_ADDR     +  0x0144}]\nset  PHY_STATUS_2                    [expr       {$EMIF_BASE_ADDR     +  0x0148}]\nset  PHY_STATUS_3                    [expr       {$EMIF_BASE_ADDR     +  0x014c}]\nset  PHY_STATUS_4                    [expr       {$EMIF_BASE_ADDR     +  0x0150}]\nset  PHY_STATUS_5                    [expr       {$EMIF_BASE_ADDR     +  0x0154}]\nset  PHY_STATUS_6                    [expr       {$EMIF_BASE_ADDR     +  0x0158}]\nset  PHY_STATUS_7                    [expr       {$EMIF_BASE_ADDR     +  0x015c}]\nset  PHY_STATUS_8                    [expr       {$EMIF_BASE_ADDR     +  0x0160}]\nset  PHY_STATUS_9                    [expr       {$EMIF_BASE_ADDR     +  0x0164}]\nset  PHY_STATUS_10                   [expr       {$EMIF_BASE_ADDR     +  0x0168}]\nset  PHY_STATUS_11                   [expr       {$EMIF_BASE_ADDR     +  0x016c}]\nset  PHY_STATUS_12                   [expr       {$EMIF_BASE_ADDR     +  0x0170}]\nset  PHY_STATUS_13                   [expr       {$EMIF_BASE_ADDR     +  0x0174}]\nset  PHY_STATUS_14                   [expr       {$EMIF_BASE_ADDR     +  0x0178}]\nset  PHY_STATUS_15                   [expr       {$EMIF_BASE_ADDR     +  0x017c}]\nset  PHY_STATUS_16                   [expr       {$EMIF_BASE_ADDR     +  0x0180}]\nset  PHY_STATUS_17                   [expr       {$EMIF_BASE_ADDR     +  0x0184}]\nset  PHY_STATUS_18                   [expr       {$EMIF_BASE_ADDR     +  0x0188}]\nset  PHY_STATUS_19                   [expr       {$EMIF_BASE_ADDR     +  0x018c}]\nset  PHY_STATUS_20                   [expr       {$EMIF_BASE_ADDR     +  0x0190}]\nset  PHY_STATUS_21                   [expr       {$EMIF_BASE_ADDR     +  0x0194}]\nset  PHY_STATUS_22                   [expr       {$EMIF_BASE_ADDR     +  0x0198}]\nset  PHY_STATUS_23                   [expr       {$EMIF_BASE_ADDR     +  0x019c}]\nset  PHY_STATUS_24                   [expr       {$EMIF_BASE_ADDR     +  0x01a0}]\nset  PHY_STATUS_25                   [expr       {$EMIF_BASE_ADDR     +  0x01a4}]\nset  PHY_STATUS_26                   [expr       {$EMIF_BASE_ADDR     +  0x01a8}]\nset  PHY_STATUS_27                   [expr       {$EMIF_BASE_ADDR     +  0x01ac}]\nset  PHY_STATUS_28                   [expr       {$EMIF_BASE_ADDR     +  0x01b0}]\n\nset  EXT_PHY_CTRL_1                  [expr       {$EMIF_BASE_ADDR     +  0x0200}]\nset  EXT_PHY_CTRL_1_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0204}]\nset  EXT_PHY_CTRL_2                  [expr       {$EMIF_BASE_ADDR     +  0x0208}]\nset  EXT_PHY_CTRL_2_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x020c}]\nset  EXT_PHY_CTRL_3                  [expr       {$EMIF_BASE_ADDR     +  0x0210}]\nset  EXT_PHY_CTRL_3_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0214}]\nset  EXT_PHY_CTRL_4                  [expr       {$EMIF_BASE_ADDR     +  0x0218}]\nset  EXT_PHY_CTRL_4_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x021c}]\nset  EXT_PHY_CTRL_5                  [expr       {$EMIF_BASE_ADDR     +  0x0220}]\nset  EXT_PHY_CTRL_5_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0224}]\nset  EXT_PHY_CTRL_6                  [expr       {$EMIF_BASE_ADDR     +  0x0228}]\nset  EXT_PHY_CTRL_6_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x022c}]\nset  EXT_PHY_CTRL_7                  [expr       {$EMIF_BASE_ADDR     +  0x0230}]\nset  EXT_PHY_CTRL_7_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0234}]\nset  EXT_PHY_CTRL_8                  [expr       {$EMIF_BASE_ADDR     +  0x0238}]\nset  EXT_PHY_CTRL_8_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x023c}]\nset  EXT_PHY_CTRL_9                  [expr       {$EMIF_BASE_ADDR     +  0x0240}]\nset  EXT_PHY_CTRL_9_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0244}]\nset  EXT_PHY_CTRL_10                 [expr       {$EMIF_BASE_ADDR     +  0x0248}]\nset  EXT_PHY_CTRL_10_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x024c}]\nset  EXT_PHY_CTRL_11                 [expr       {$EMIF_BASE_ADDR     +  0x0250}]\nset  EXT_PHY_CTRL_11_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0254}]\nset  EXT_PHY_CTRL_12                 [expr       {$EMIF_BASE_ADDR     +  0x0258}]\nset  EXT_PHY_CTRL_12_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x025c}]\nset  EXT_PHY_CTRL_13                 [expr       {$EMIF_BASE_ADDR     +  0x0260}]\nset  EXT_PHY_CTRL_13_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0264}]\nset  EXT_PHY_CTRL_14                 [expr       {$EMIF_BASE_ADDR     +  0x0268}]\nset  EXT_PHY_CTRL_14_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x026c}]\nset  EXT_PHY_CTRL_15                 [expr       {$EMIF_BASE_ADDR     +  0x0270}]\nset  EXT_PHY_CTRL_15_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0274}]\nset  EXT_PHY_CTRL_16                 [expr       {$EMIF_BASE_ADDR     +  0x0278}]\nset  EXT_PHY_CTRL_16_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x027c}]\nset  EXT_PHY_CTRL_17                 [expr       {$EMIF_BASE_ADDR     +  0x0280}]\nset  EXT_PHY_CTRL_17_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0284}]\nset  EXT_PHY_CTRL_18                 [expr       {$EMIF_BASE_ADDR     +  0x0288}]\nset  EXT_PHY_CTRL_18_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x028c}]\nset  EXT_PHY_CTRL_19                 [expr       {$EMIF_BASE_ADDR     +  0x0290}]\nset  EXT_PHY_CTRL_19_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0294}]\nset  EXT_PHY_CTRL_20                 [expr       {$EMIF_BASE_ADDR     +  0x0298}]\nset  EXT_PHY_CTRL_20_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x029c}]\nset  EXT_PHY_CTRL_21                 [expr       {$EMIF_BASE_ADDR     +  0x02a0}]\nset  EXT_PHY_CTRL_21_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02a4}]\nset  EXT_PHY_CTRL_22                 [expr       {$EMIF_BASE_ADDR     +  0x02a8}]\nset  EXT_PHY_CTRL_22_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ac}]\nset  EXT_PHY_CTRL_23                 [expr       {$EMIF_BASE_ADDR     +  0x02b0}]\nset  EXT_PHY_CTRL_23_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02b4}]\nset  EXT_PHY_CTRL_24                 [expr       {$EMIF_BASE_ADDR     +  0x02b8}]\nset  EXT_PHY_CTRL_24_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02bc}]\nset  EXT_PHY_CTRL_25                 [expr       {$EMIF_BASE_ADDR     +  0x02c0}]\nset  EXT_PHY_CTRL_25_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02c4}]\nset  EXT_PHY_CTRL_26                 [expr       {$EMIF_BASE_ADDR     +  0x02c8}]\nset  EXT_PHY_CTRL_26_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02cc}]\nset  EXT_PHY_CTRL_27                 [expr       {$EMIF_BASE_ADDR     +  0x02d0}]\nset  EXT_PHY_CTRL_27_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02d4}]\nset  EXT_PHY_CTRL_28                 [expr       {$EMIF_BASE_ADDR     +  0x02d8}]\nset  EXT_PHY_CTRL_28_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02dc}]\nset  EXT_PHY_CTRL_29                 [expr       {$EMIF_BASE_ADDR     +  0x02e0}]\nset  EXT_PHY_CTRL_29_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02e4}]\nset  EXT_PHY_CTRL_30                 [expr       {$EMIF_BASE_ADDR     +  0x02e8}]\nset  EXT_PHY_CTRL_30_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ec}]\nset  EXT_PHY_CTRL_31                 [expr       {$EMIF_BASE_ADDR     +  0x02f0}]\nset  EXT_PHY_CTRL_31_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02f4}]\nset  EXT_PHY_CTRL_32                 [expr       {$EMIF_BASE_ADDR     +  0x02f8}]\nset  EXT_PHY_CTRL_32_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02fc}]\nset  EXT_PHY_CTRL_33                 [expr       {$EMIF_BASE_ADDR     +  0x0300}]\nset  EXT_PHY_CTRL_33_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0304}]\nset  EXT_PHY_CTRL_34                 [expr       {$EMIF_BASE_ADDR     +  0x0308}]\nset  EXT_PHY_CTRL_34_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x030c}]\nset  EXT_PHY_CTRL_35                 [expr       {$EMIF_BASE_ADDR     +  0x0310}]\nset  EXT_PHY_CTRL_35_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0314}]\nset  EXT_PHY_CTRL_36                 [expr       {$EMIF_BASE_ADDR     +  0x0318}]\nset  EXT_PHY_CTRL_36_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x031c}]\n\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\n\nset  RTC_BASE_ADDR                   0x44e3e000\nset  RTC_KICK0R                      [expr       {$RTC_BASE_ADDR      +  0x6c}]\nset  RTC_KICK1R                      [expr       {$RTC_BASE_ADDR      +  0x70}]\n\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME am437x\n}\n\nset JRC_MODULE\t\ticepick_d\nset DEBUGSS_MODULE\tdebugss\nset M3_MODULE\t\tm3_wakeupss\n\nset JRC_NAME\t\t$_CHIPNAME.$JRC_MODULE\nset DEBUGSS_NAME\t$_CHIPNAME.$DEBUGSS_MODULE\nset M3_NAME\t\t$_CHIPNAME.$M3_MODULE\nset _TARGETNAME\t\t$_CHIPNAME.mpuss\n\n#\n# M3 WakeupSS DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME $M3_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $M3_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 11 0\"\ndap create $M3_NAME.dap -chain-position $M3_NAME\n\n#\n# DebugSS DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x46b6902f\n}\njtag newtap $_CHIPNAME $DEBUGSS_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $DEBUGSS_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 12 0\"\ndap create $DEBUGSS_NAME.dap -chain-position $DEBUGSS_NAME\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b98c02f\n}\njtag newtap $_CHIPNAME $JRC_MODULE -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $JRC_NAME -event setup \"jtag tapenable $DEBUGSS_NAME\"\n # some TCK tycles are required to activate the DEBUG power domain\njtag configure $JRC_NAME -event post-reset \"runtest 100\"\n\n#\n# Cortex-A9 target\n#\ntarget create $_TARGETNAME cortex_a -dap $DEBUGSS_NAME.dap -coreid 0 -dbgbase 0x80000000\n\n\n# SRAM: 256K at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x40000\n\n# Disables watchdog timer after reset otherwise board won't stay in\n# halted state.\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n\nproc ceil { x y } {\n\treturn [ expr {($x + $y - 1) / $y} ]\n}\n\nproc device_type { } {\n\tglobal CONTROL_STATUS\n\n\tset tmp [ mrw $CONTROL_STATUS ]\n\tset tmp [ expr {$tmp & 0x700} ]\n\tset tmp [ expr {$tmp >> 8} ]\n\n\treturn $tmp\n}\n\nproc get_input_clock_frequency { } {\n\tglobal CONTROL_STATUS\n\n\tif { [ device_type ] != 3 } {\n\t\terror \"Unknown device type\\n\"\n\t\treturn -1\n\t}\n\n\tset freq [ mrw $CONTROL_STATUS ]\n\tset freq [ expr {$freq & 0x00c00000} ]\n\tset freq [ expr {$freq >> 22} ]\n\n\tswitch $freq {\n\t\t0 {\n\t\t\tset CLKIN 19200000\n\t\t}\n\n\t\t1 {\n\t\t\tset CLKIN 24000000\n\t\t}\n\n\t\t2 {\n\t\t\tset CLKIN 25000000\n\t\t}\n\n\t\t3 {\n\t\t\tset CLKIN 26000000\n\t\t}\n\t}\n\n\treturn $CLKIN\n}\n\nproc mpu_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_MPU\n\tglobal CM_CLKSEL_DPLL_MPU\n\tglobal CM_DIV_M2_DPLL_MPU\n\tglobal CM_IDLEST_DPLL_MPU\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_MPU ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ]\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_MPU $clksel\n\n\tset div_m2 [ expr {$div_m2 & (~0x1f)} ]\n\tset div_m2 [ expr {$div_m2 | $M2} ]\n\tmww $CM_DIV_M2_DPLL_MPU $div_m2\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x7\n\twhile { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { }\n\n\techo \"MPU DPLL locked\"\n}\n\nproc core_pll_config { CLKIN N M M4 M5 M6 } {\n\tglobal CM_CLKMODE_DPLL_CORE\n\tglobal CM_CLKSEL_DPLL_CORE\n\tglobal CM_DIV_M4_DPLL_CORE\n\tglobal CM_DIV_M5_DPLL_CORE\n\tglobal CM_DIV_M6_DPLL_CORE\n\tglobal CM_IDLEST_DPLL_CORE\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_CORE ]\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_CORE $clksel\n\tmww $CM_DIV_M4_DPLL_CORE $M4\n\tmww $CM_DIV_M5_DPLL_CORE $M5\n\tmww $CM_DIV_M6_DPLL_CORE $M6\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { }\n\n\techo \"CORE DPLL locked\"\n}\n\nproc per_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_PER\n\tglobal CM_CLKSEL_DPLL_PER\n\tglobal CM_DIV_M2_DPLL_PER\n\tglobal CM_IDLEST_DPLL_PER\n\n\tset x [ expr {$M * $CLKIN / 1000000} ]\n\tset y [ expr {($N + 1) * 250} ]\n\tset sd [ ceil $x $y ]\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_PER ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_PER ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0xff0fffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tset clksel [ expr {$clksel | ($sd << 24)} ]\n\tmww $CM_CLKSEL_DPLL_PER $clksel\n\n\tset div_m2 [ expr {0xffffff80 | $M2} ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { }\n\n\techo \"PER DPLL locked\"\n}\n\nproc ddr_pll_config { CLKIN N M M2 M4 } {\n\tglobal CM_CLKMODE_DPLL_DDR\n\tglobal CM_CLKSEL_DPLL_DDR\n\tglobal CM_DIV_M2_DPLL_DDR\n\tglobal CM_DIV_M4_DPLL_DDR\n\tglobal CM_IDLEST_DPLL_DDR\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_DDR ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ]\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_DDR $clksel\n\n\tset div_m2 [ expr {($div_m2 & 0xffffffe0) | $M2} ]\n\tmww $CM_DIV_M2_DPLL_DDR $div_m2\n\tmww $CM_DIV_M4_DPLL_DDR $M4\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { }\n\n\techo \"DDR DPLL Locked\"\n}\n\nproc config_opp100 { } {\n\tset CLKIN [ get_input_clock_frequency ]\n\n\tif { $CLKIN == -1 } {\n\t\treturn -1\n\t}\n\n\tswitch $CLKIN {\n\t\t24000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  25   1\n\t\t\tcore_pll_config  $CLKIN  2  125  10  8  4\n\t\t\tper_pll_config   $CLKIN  9  400  5\n\t\t\tddr_pll_config   $CLKIN  2  50   1   2\n\t\t}\n\n\t\t25000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  24   1\n\t\t\tcore_pll_config  $CLKIN  0  40   10  8  4\n\t\t\tper_pll_config   $CLKIN  9  384  5\n\t\t\tddr_pll_config   $CLKIN  0  16   1   2\n\t\t}\n\n\t\t26000000 {\n\t\t\tmpu_pll_config   $CLKIN  12  300  1\n\t\t\tcore_pll_config  $CLKIN  12  500  10  8  4\n\t\t\tper_pll_config   $CLKIN  12  480  5\n\t\t\tddr_pll_config   $CLKIN  12  200  1   2\n\t\t}\n\n\t\t19200000 {\n\t\t\tmpu_pll_config   $CLKIN  3   125  1\n\t\t\tcore_pll_config  $CLKIN  11  625  10  8  4\n\t\t\tper_pll_config   $CLKIN  7   400  5\n\t\t\tddr_pll_config   $CLKIN  2   125  1   2\n\t\t}\n\t}\n}\n\nproc emif_prcm_clk_enable { } {\n\tglobal CM_PER_EMIF_FW_CLKCTRL\n\tglobal CM_PER_EMIF_CLKCTRL\n\n\tmww $CM_PER_EMIF_FW_CLKCTRL 0x02\n\tmww $CM_PER_EMIF_CLKCTRL 0x02\n\n\twhile { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { }\n}\n\nproc vtp_enable { } {\n\tglobal VTP_CTRL_REG\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x40 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] & ~0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n}\n\nproc config_ddr_ioctrl { } {\n\tglobal DDR_ADDRCTRL_IOCTRL\n\tglobal DDR_ADDRCTRL_WD0_IOCTRL\n\tglobal DDR_ADDRCTRL_WD1_IOCTRL\n\tglobal DDR_CKE_CTRL\n\tglobal DDR_DATA0_IOCTRL\n\tglobal DDR_DATA1_IOCTRL\n\tglobal DDR_DATA2_IOCTRL\n\tglobal DDR_DATA3_IOCTRL\n\tglobal DDR_IO_CTRL\n\n\tmww $DDR_ADDRCTRL_IOCTRL\t0x84\n\tmww $DDR_ADDRCTRL_WD0_IOCTRL\t0x00\n\tmww $DDR_ADDRCTRL_WD1_IOCTRL\t0x00\n\tmww $DDR_DATA0_IOCTRL\t\t0x84\n\tmww $DDR_DATA1_IOCTRL\t\t0x84\n\tmww $DDR_DATA2_IOCTRL\t\t0x84\n\tmww $DDR_DATA3_IOCTRL\t\t0x84\n\n\tmww $DDR_IO_CTRL\t\t0x00\n\tmww $DDR_CKE_CTRL\t\t0x03\n}\n\nproc config_ddr_phy { } {\n\tglobal EMIF_DDR_PHY_CTRL_1\n\tglobal EMIF_DDR_PHY_CTRL_1_SHDW\n\n\tglobal EXT_PHY_CTRL_1\n\tglobal EXT_PHY_CTRL_1_SHDW\n\tglobal EXT_PHY_CTRL_2\n\tglobal EXT_PHY_CTRL_2_SHDW\n\tglobal EXT_PHY_CTRL_3\n\tglobal EXT_PHY_CTRL_3_SHDW\n\tglobal EXT_PHY_CTRL_4\n\tglobal EXT_PHY_CTRL_4_SHDW\n\tglobal EXT_PHY_CTRL_5\n\tglobal EXT_PHY_CTRL_5_SHDW\n\tglobal EXT_PHY_CTRL_6\n\tglobal EXT_PHY_CTRL_6_SHDW\n\tglobal EXT_PHY_CTRL_7\n\tglobal EXT_PHY_CTRL_7_SHDW\n\tglobal EXT_PHY_CTRL_8\n\tglobal EXT_PHY_CTRL_8_SHDW\n\tglobal EXT_PHY_CTRL_9\n\tglobal EXT_PHY_CTRL_9_SHDW\n\tglobal EXT_PHY_CTRL_10\n\tglobal EXT_PHY_CTRL_10_SHDW\n\tglobal EXT_PHY_CTRL_11\n\tglobal EXT_PHY_CTRL_11_SHDW\n\tglobal EXT_PHY_CTRL_12\n\tglobal EXT_PHY_CTRL_12_SHDW\n\tglobal EXT_PHY_CTRL_13\n\tglobal EXT_PHY_CTRL_13_SHDW\n\tglobal EXT_PHY_CTRL_14\n\tglobal EXT_PHY_CTRL_14_SHDW\n\tglobal EXT_PHY_CTRL_15\n\tglobal EXT_PHY_CTRL_15_SHDW\n\tglobal EXT_PHY_CTRL_16\n\tglobal EXT_PHY_CTRL_16_SHDW\n\tglobal EXT_PHY_CTRL_17\n\tglobal EXT_PHY_CTRL_17_SHDW\n\tglobal EXT_PHY_CTRL_18\n\tglobal EXT_PHY_CTRL_18_SHDW\n\tglobal EXT_PHY_CTRL_19\n\tglobal EXT_PHY_CTRL_19_SHDW\n\tglobal EXT_PHY_CTRL_20\n\tglobal EXT_PHY_CTRL_20_SHDW\n\tglobal EXT_PHY_CTRL_21\n\tglobal EXT_PHY_CTRL_21_SHDW\n\tglobal EXT_PHY_CTRL_22\n\tglobal EXT_PHY_CTRL_22_SHDW\n\tglobal EXT_PHY_CTRL_23\n\tglobal EXT_PHY_CTRL_23_SHDW\n\tglobal EXT_PHY_CTRL_24\n\tglobal EXT_PHY_CTRL_24_SHDW\n\tglobal EXT_PHY_CTRL_25\n\tglobal EXT_PHY_CTRL_25_SHDW\n\tglobal EXT_PHY_CTRL_26\n\tglobal EXT_PHY_CTRL_26_SHDW\n\tglobal EXT_PHY_CTRL_27\n\tglobal EXT_PHY_CTRL_27_SHDW\n\tglobal EXT_PHY_CTRL_28\n\tglobal EXT_PHY_CTRL_28_SHDW\n\tglobal EXT_PHY_CTRL_29\n\tglobal EXT_PHY_CTRL_29_SHDW\n\tglobal EXT_PHY_CTRL_30\n\tglobal EXT_PHY_CTRL_30_SHDW\n\tglobal EXT_PHY_CTRL_31\n\tglobal EXT_PHY_CTRL_31_SHDW\n\tglobal EXT_PHY_CTRL_32\n\tglobal EXT_PHY_CTRL_32_SHDW\n\tglobal EXT_PHY_CTRL_33\n\tglobal EXT_PHY_CTRL_33_SHDW\n\tglobal EXT_PHY_CTRL_34\n\tglobal EXT_PHY_CTRL_34_SHDW\n\tglobal EXT_PHY_CTRL_35\n\tglobal EXT_PHY_CTRL_35_SHDW\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\tmww $EMIF_DDR_PHY_CTRL_1\t0x8009\n\tmww $EMIF_DDR_PHY_CTRL_1_SHDW\t0x8009\n\n\tset slave_ratio\t\t0x80\n\tset gatelvl_init_ratio\t0x20\n\tset wr_dqs_slave_delay\t0x60\n\tset rd_dqs_slave_delay\t0x60\n\tset dq_offset\t\t0x40\n\tset gatelvl_init_mode\t0x01\n\tset wr_data_slave_delay\t0x80\n\tset gatelvl_num_dq0 0x0f\n\tset wrlvl_num_dq0 0x0f\n\n\tmww $EXT_PHY_CTRL_1        [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_1_SHDW   [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_26       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_26_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_31       0x00\n\tmww $EXT_PHY_CTRL_31_SHDW  0x00\n\tmww $EXT_PHY_CTRL_32       0x00\n\tmww $EXT_PHY_CTRL_32_SHDW  0x00\n\tmww $EXT_PHY_CTRL_33       0x00\n\tmww $EXT_PHY_CTRL_33_SHDW  0x00\n\tmww $EXT_PHY_CTRL_34       0x00\n\tmww $EXT_PHY_CTRL_34_SHDW  0x00\n\tmww $EXT_PHY_CTRL_35       0x00\n\tmww $EXT_PHY_CTRL_35_SHDW  0x00\n\tmww $EXT_PHY_CTRL_22       0x00\n\tmww $EXT_PHY_CTRL_22_SHDW  0x00\n\tmww $EXT_PHY_CTRL_23       [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_23_SHDW  [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24       [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24_SHDW  [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0} ]\n\tmww $EXT_PHY_CTRL_25       [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_25_SHDW  [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_36       [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n\tmww $EXT_PHY_CTRL_36_SHDW  [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n}\n\nproc config_ddr_timing { } {\n\tglobal EMIF_SDRAM_TIM_1\n\tglobal EMIF_SDRAM_TIM_2\n\tglobal EMIF_SDRAM_TIM_3\n\tglobal EMIF_SDRAM_TIM_1_SHDW\n\tglobal EMIF_SDRAM_TIM_2_SHDW\n\tglobal EMIF_SDRAM_TIM_3_SHDW\n\tglobal EMIF_ZQ_CONFIG\n\n\tmww $EMIF_SDRAM_TIM_1\t\t0xeaaad4db\n\tmww $EMIF_SDRAM_TIM_1_SHDW\t0xeaaad4db\n\n\tmww $EMIF_SDRAM_TIM_2\t\t0x266b7fda\n\tmww $EMIF_SDRAM_TIM_2_SHDW\t0x266b7fda\n\n\tmww $EMIF_SDRAM_TIM_3\t\t0x107f8678\n\tmww $EMIF_SDRAM_TIM_3_SHDW\t0x107f8678\n\n\tmww $EMIF_ZQ_CONFIG\t\t0x50074be4\n}\n\nproc config_ddr_pm { } {\n\tglobal EMIF_PWR_MGMT_CTRL\n\tglobal EMIF_PWR_MGMT_CTRL_SHDW\n\tglobal EMIF_DLL_CALIB_CTRL\n\tglobal EMIF_DLL_CALIB_CTRL_SHDW\n\tglobal EMIF_TEMP_ALERT_CONFIG\n\n\tmww $EMIF_PWR_MGMT_CTRL\t\t0x00\n\tmww $EMIF_PWR_MGMT_CTRL_SHDW\t0x00\n\tmww $EMIF_DLL_CALIB_CTRL\t0x00050000\n\tmww $EMIF_DLL_CALIB_CTRL_SHDW\t0x00050000\n\tmww $EMIF_TEMP_ALERT_CONFIG\t0x00\n}\n\nproc config_ddr_priority { } {\n\tglobal EMIF_PRI_COS_MAP\n\tglobal EMIF_CONNID_COS_1_MAP\n\tglobal EMIF_CONNID_COS_2_MAP\n\tglobal EMIF_RD_WR_EXEC_THRSH\n\tglobal COS_CONFIG\n\n\tmww $EMIF_PRI_COS_MAP       0x00\n\tmww $EMIF_CONNID_COS_1_MAP  0x00\n\tmww $EMIF_CONNID_COS_2_MAP  0x0\n\tmww $EMIF_RD_WR_EXEC_THRSH  0x0405\n\tmww $COS_CONFIG             0x00ffffff\n}\n\nproc config_ddr3 { SDRAM_CONFIG } {\n\tglobal CM_DLL_CTRL\n\tglobal EMIF_IODFT_TLGC\n\tglobal EMIF_RDWR_LVL_CTRL\n\tglobal EMIF_RDWR_LVL_RMP_CTRL\n\tglobal EMIF_SDRAM_CONFIG\n\tglobal EMIF_SDRAM_CONFIG_EXT\n\tglobal EMIF_SDRAM_REF_CTRL\n\tglobal EMIF_SDRAM_REF_CTRL_SHDW\n\tglobal EMIF_STATUS\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\temif_prcm_clk_enable\n\tvtp_enable\n\n\tset dll [ expr {[ mrw $CM_DLL_CTRL ] & ~0x01 }]\n\tmww $CM_DLL_CTRL $dll\n\twhile { !([ mrw $CM_DLL_CTRL ] & 0x04) } { }\n\n\tconfig_ddr_ioctrl\n\n\tmww $EMIF_SDRAM_CONFIG_EXT\t0xc163\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_SDRAM_REF_CTRL\t0x80003000\n\n\tconfig_ddr_phy\n\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\n\tconfig_ddr_timing\n\tconfig_ddr_pm\n\tconfig_ddr_priority\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x3000\n\tmww $EMIF_SDRAM_CONFIG\t\t$SDRAM_CONFIG\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x0c30\n\tmww $EMIF_SDRAM_REF_CTRL_SHDW\t0x0c30\n\n\tsleep 10\n\n\tset tmp [ expr {[ mrw $EXT_PHY_CTRL_36 ] | 0x0100 }]\n\tmww $EXT_PHY_CTRL_36\t\t$tmp\n\tmww $EXT_PHY_CTRL_36_SHDW\t$tmp\n\n\tmww $EMIF_RDWR_LVL_RMP_CTRL\t0x80000000\n\tmww $EMIF_RDWR_LVL_CTRL\t\t0x80000000\n\n\twhile { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { }\n\n\tif { [ mrw $EMIF_STATUS ]  & 0x70 } {\n\t\terror \"DDR3 Hardware Leveling incomplete!!!\"\n\t}\n}\n\nproc init_platform { SDRAM_CONFIG } {\n\tconfig_opp100\n\tconfig_ddr3 $SDRAM_CONFIG\n}\n\n$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 }\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/amdm37x.cfg",
    "content": "#\n# Copyright (C)   2010-2011   by Karl Kurbjun\n# Copyright (C)   2009-2011   by Øyvind Harboe\n# Copyright (C)   2009        by David Brownell\n# Copyright (C)   2009        by Magnus Lundin\n#\n# TI AM/DM37x Technical Reference Manual (Version R)\n#  http://www.ti.com/lit/ug/sprugn4r/sprugn4r.pdf\n#\n# This script is based on the AM3517 initialization.  It should be considered\n# preliminary since it needs more complete testing and only the basic\n# operations work.\n#\n\n###############################################################################\n# User modifiable parameters\n###############################################################################\n\n# This script uses the variable CHIPTYPE to determine whether this is an AM35x\n# or DM37x target. If CHIPTYPE is not set it will error out.\nif { [info exists CHIPTYPE] } {\n\n   if { [info exists CHIPNAME] } {\n      set _CHIPNAME $CHIPNAME\n   } else {\n      set _CHIPNAME $CHIPTYPE\n   }\n\n   switch $CHIPTYPE {\n      dm37x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x2b89102f -expected-id 0x1b89102f -expected-id 0x0b89102f\"\n      }\n      am35x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x0b7ae02f -expected-id 0x0b86802f\"\n      }\n      default {\n         error \"ERROR: CHIPTYPE was set, but it was not set to a valid value.  Acceptable values are \\\"dm37x\\\" or \\\"am35x\\\".\"\n      }\n   }\n} else {\n  error \"ERROR: CHIPTYPE was not defined. Please set CHIPTYPE to \\\"am35x\\\" for the AM35x or \\\"dm37x\\\" for the DM37x series in the board configuration.\"\n}\n\n# Run the adapter at the fastest acceptable speed with the slowest possible\n# core clock.\nadapter speed 10\n\n###############################################################################\n# JTAG setup\n# The OpenOCD commands are described in the TAP Declaration section\n#  http://openocd.org/doc/html/TAP-Declaration.html\n###############################################################################\n\n# The AM/DM37x has an ICEPick module in it like many of TI's other devices. More\n#  can be read about this module in sprugn4r in chapter 27:  \"Debug and\n#  Emulation\".  The module is used to route the JTAG chain to the various\n#  subsystems in the chip.\nsource [find target/icepick.cfg]\n\n# The TAP order should be described from the TDO connection in OpenOCD to the\n#  TDI pin.  The OpenOCD FAQ describes this in more detail:\n#  http://openocd.org/doc/html/FAQ.html\n\n# From SPRUGN4R CH27 the available secondary TAPs are in this order from TDO:\n#\n#  Device   |  TAP number\n#  ---------|------------\n#  DAP      |  3\n#  Sequencer|  2   Note: The sequencer is an ARM968\n#  DSP      |  1\n#  D2D      |  0\n#\n# Right now the only secondary tap enabled is the DAP so the rest are left\n# undescribed.\n\n######\n# Start of Chain Description\n# The Secondary TAPs all have enable functions defined for use with the ICEPick\n# Only the DAP is enabled.  The AM37xx does not have the Sequencer or DSP but\n# the TAP numbers for ICEPick do not change.\n#\n# TODO: A disable function should also be added.\n######\n\n# Secondary TAP: DAP is closest to the TDO output\n# The TAP enable event also needs to be described\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# These taps are only present in the DM37x series.\nif { $CHIPTYPE == \"dm37x\" } {\n   # Secondary TAP: Sequencer (ARM968) it is not in the chain by default\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME arm2 -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\n   jtag configure $_CHIPNAME.arm2 -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n   # Secondary TAP: C64x+ DSP - it is not in the chain by default (-disable)\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n   jtag configure $_CHIPNAME.dsp -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n}\n\n# Secondary TAP: D2D it is not in the chain by default (-disable)\n# The ICEPick can be used to enable it in the chain.\n# This IRLEN is probably incorrect - not sure where the documentation is.\njtag newtap $_CHIPNAME d2d -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\njtag configure $_CHIPNAME.d2d -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEPick - it is closest to TDI so last in the chain\neval \"jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f $_JRC_TAPID\"\n\n######\n# End of Chain Description\n######\n\n######\n# Start JTAG TAP events\n######\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# Enable the DAP TAP\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\n######\n# End JTAG TAP events\n######\n\n###############################################################################\n# Target Setup:\n# This section is described in the OpenOCD documentation under CPU Configuration\n#  http://openocd.org/doc/html/CPU-Configuration.html\n###############################################################################\n\n# Create the CPU target to be used with GDB:  Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# The DM37x has 64K of SRAM starting at address 0x4020_0000.  Allow the first\n# 16K to be used as a scratchpad for OpenOCD.\n\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n######\n# Start Target Reset Event Setup:\n######\n\n# Set the JTAG clock down to 10 kHz to be sure that it will work with the\n#  slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up\n#  *after* PLL and clock tree setup.\n\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 10 }\n\n# Describe the reset assert process for openocd - this is asserted with the\n# ICEPick\n$_TARGETNAME configure -event \"reset-assert\" {\n\n   global _CHIPNAME\n\n   # assert warm system reset through ICEPick\n   icepick_c_wreset $_CHIPNAME.jrc\n}\n\n# After the reset is asserted we need to re-initialize debugging and speed up\n# the JTAG clock.\n\n$_TARGETNAME configure -event reset-assert-post {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n   adapter speed 1000\n}\n\n$_TARGETNAME configure -event gdb-attach {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n\n   echo \"Halting target\"\n   halt\n}\n\n######\n# End Target Reset Event Setup:\n######\n\n###############################################################################\n# Target Functions\n# Add any functions needed for the target here\n###############################################################################\n\n# Run this to enable invasive debugging.  This is run automatically in the\n# reset sequence.\nproc amdm37x_dbginit {target} {\n   # General Cortex-A8 debug initialisation\n   cortex_a dbginit\n\n   # Enable DBGEN signal.  This signal is described in the ARM v7 TRM, but\n   # access to the signal appears to be implementation specific.  TI does not\n   # describe this register much except a quick line that states DBGEM (sic) is\n   # at this address and this bit.\n   $target mww phys 0x5401d030 0x00002000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ampere_emag.cfg",
    "content": "#\n# OpenOCD Target Configuration for eMAG ARMv8 Processor\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure defaults for target\n# Can be overriden in board configuration file\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME emag\n}\n\nif { [info exists NUMCORES] } {\n\tset _NUMCORES $NUMCORES\n} else {\n\tset _NUMCORES 32\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID ] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4BA00477\n}\n\n#\n# Configure JTAG TAP\n#\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID\nset _TAPNAME $_CHIPNAME.cpu\n\nset _DAPNAME ${_TAPNAME}_dap\nset _APNUM 1\ndap create $_DAPNAME -chain-position $_TAPNAME\n$_DAPNAME apsel $_APNUM\n\n# Create the DAP AP0 MEM-AP AHB-AP target\ntarget create AHB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 0\n\n# Create the DAP AP1 MEM-AP APB-AP target\ntarget create APB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 1\n\n#\n# Configure target CPUs\n#\n\n# Build string used to enable smp mode\nset _SMP_STR \"target smp\"\n\nfor {set _i 0} {$_i < $_NUMCORES} {incr _i} {\n\t# Format a string to reference which CPU target to use\n\tset _TARGETNAME [format \"${_TAPNAME}_%02d\" $_i]\n\n\t# Create and configure Cross Trigger Interface (CTI) - required for halt and resume\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $_DAPNAME -ap-num $_APNUM -baseaddr [expr {0xFC020000 + ($_i << 20)}]\n\n\t# Create the target\n\ttarget create $_TARGETNAME aarch64 -endian $_ENDIAN -dap $_DAPNAME -ap-num $_APNUM -cti $_CTINAME -coreid $_i\n\tset _SMP_STR \"$_SMP_STR $_TARGETNAME\"\n\n\t# Clear CTI output/input enables that are not configured by OpenOCD for aarch64\n\t$_TARGETNAME configure -event examine-start [subst {\n\t\t$_CTINAME write INEN0 0x00000000\n\t\t$_CTINAME write INEN1 0x00000000\n\t\t$_CTINAME write INEN2 0x00000000\n\t\t$_CTINAME write INEN3 0x00000000\n\t\t$_CTINAME write INEN4 0x00000000\n\t\t$_CTINAME write INEN5 0x00000000\n\t\t$_CTINAME write INEN6 0x00000000\n\t\t$_CTINAME write INEN7 0x00000000\n\t\t$_CTINAME write INEN8 0x00000000\n\n\t\t$_CTINAME write OUTEN2 0x00000000\n\t\t$_CTINAME write OUTEN3 0x00000000\n\t\t$_CTINAME write OUTEN4 0x00000000\n\t\t$_CTINAME write OUTEN5 0x00000000\n\t\t$_CTINAME write OUTEN6 0x00000000\n\t\t$_CTINAME write OUTEN7 0x00000000\n\t\t$_CTINAME write OUTEN8 0x00000000\n\t}]\n\n\t# Enable OpenOCD HWTHREAD RTOS feature for GDB thread (CPU) selection support\n\t# This feature presents CPU cores (\"hardware threads\") in an SMP system as threads to GDB\n\t$_TARGETNAME configure -rtos hwthread\n}\neval $_SMP_STR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ar71xx.cfg",
    "content": "# Atheros AR71xx MIPS 24Kc SoC.\n# tested on PB44 refererence board\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst\n\nset CHIPNAME ar71xx\n\njtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1\n\nset _TARGETNAME $CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-halt-post {\n\t#setup PLL to lowest common denominator 300/300/150 setting\n\tmww 0xb8050000 0x000f40a3\t;# reset val + CPU:3 DDR:3 AHB:0\n\tmww 0xb8050000 0x800f40a3\t;# send to PLL\n\n\t#next command will reset for PLL changes to take effect\n\tmww 0xb8050008 3\t\t;# set reset_switch and clock_switch (resets SoC)\n}\n\n$_TARGETNAME configure -event reset-init {\n\t#complete pll initialization\n\tmww 0xb8050000 0x800f0080\t;# set sw_update bit\n\tmww 0xb8050008 0\t\t;# clear reset_switch bit\n\tmww 0xb8050000 0x800f00e8       ;# clr pwrdwn & bypass\n\tmww 0xb8050008 1\t\t;# set clock_switch bit\n\tsleep 1                         ;# wait for lock\n\n\t# Setup DDR config and flash mapping\n\tmww 0xb8000000 0xefbc8cd0       ;# DDR cfg cdl val (rst: 0x5bfc8d0)\n\tmww 0xb8000004 0x8e7156a2       ;# DDR cfg2 cdl val (rst: 0x80d106a8)\n\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb800000c 0                ;# clr ext. mode register\n\tmww 0xb8000010 2 \t\t;# force auto refresh all banks\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000008 0x31             ;# set DDR mode value CAS=3\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb8000014 0x461b           ;# DDR refresh value\n\tmww 0xb8000018 0xffff           ;# DDR Read Data This Cycle value (16bit: 0xffff)\n\tmww 0xb800001c 0x7              ;# delay added to the DQS line (normal = 7)\n\tmww 0xb8000020 0\n\tmww 0xb8000024 0\n\tmww 0xb8000028 0\n}\n\n# setup working area somewhere in RAM\n$_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000\n\n# serial SPI capable flash\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/arm_corelink_sse200.cfg",
    "content": "#\n# Configuration script for Arm CoreLink SSE-200 Subsystem based IoT SoCs.\n#\n\nglobal TARGET\nset TARGET $_CHIPNAME\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n#\n# SRAM on ARM CoreLink SSE-200 can be 4 banks of 8/16/32/64 KB\n# We will configure work area assuming 8-KB bank size in SRAM bank 1.\n# Also SRAM start addresses defaults to secure mode alias.\n# These values can be overridden as per board configuration\n#\n\nglobal _WORKAREASIZE_CPU0\nif { [info exists WORKAREASIZE_CPU0] } {\n\tset _WORKAREASIZE_CPU0 $WORKAREASIZE_CPU0\n} else {\n\tset _WORKAREASIZE_CPU0 0x1000\n}\n\nglobal _WORKAREAADDR_CPU0\nif { [info exists WORKAREAADDR_CPU0] } {\n\tset _WORKAREAADDR_CPU0 $WORKAREAADDR_CPU0\n} else {\n\tset _WORKAREAADDR_CPU0 0x30008000\n}\n\n#\n# Target configuration for Cortex M33 Core 0 on ARM CoreLink SSE-200\n# Core 0 is the boot core and will always be configured.\n#\n\ntarget create ${TARGET}.CPU0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\n${TARGET}.CPU0 configure -work-area-phys $_WORKAREAADDR_CPU0 -work-area-size $_WORKAREASIZE_CPU0 -work-area-backup 0\n\n${TARGET}.CPU0 cortex_m reset_config sysresetreq\n\n#\n# Target configuration for Cortex M33 Core 1 on ARM CoreLink SSE-200\n# Core 1 is optional and locked at boot until core 0 unlocks it.\n#\n\nif { $_ENABLE_CPU1 } {\n\tglobal _WORKAREASIZE_CPU1\n\tif { [info exists WORKAREASIZE_CPU1] } {\n\t\tset _WORKAREASIZE_CPU1 $WORKAREASIZE_CPU1\n\t} else {\n\t\tset _WORKAREASIZE_CPU1 0x1000\n\t}\n\n\tglobal _WORKAREAADDR_CPU1\n\tif { [info exists WORKAREAADDR_CPU1] } {\n\t\tset _WORKAREAADDR_CPU1 $WORKAREAADDR_CPU1\n\t} else {\n\t\tset _WORKAREAADDR_CPU1 0x30009000\n\t}\n\n\ttarget create ${TARGET}.CPU1 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\n\t${TARGET}.CPU1 configure -work-area-phys $_WORKAREAADDR_CPU1 -work-area-size $_WORKAREASIZE_CPU1 -work-area-backup 0\n\n\t${TARGET}.CPU1 cortex_m reset_config vectreset\n}\n\n# Make sure the default target is the boot core\ntargets ${TARGET}.CPU0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/armada370.cfg",
    "content": "#\n# armada370 -- support for the Marvell Armada/370 CPU family\n#\n# gerg@uclinux.org, OCT-2013\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME armada370\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\nproc armada370_dbginit {target} {\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"armada370_dbginit $_TARGETNAME\"\n\ndap apsel 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at32ap7000.cfg",
    "content": "# Atmel AT32AP7000\n#\n# This is the only core in the now-inactive high end AVR32 product line,\n# with MMU, Java Acceleration, and \"pixel coprocessor\".  The AP7 line\n# is for \"Application Processors\" (AP) with 7-stage pipelines.\n#\n# Most current AVR32 parts are in the UC3 flash based microcontroller (UC)\n# product line with 3-stage pipelines and without those extras.\n#\n# All AVR32 parts provide the Nexus Class 3 on-chip debug interfaces\n# through their JTAG interfaces.\n\njtag newtap ap7 nexus -irlen 5 -expected-id 0x21e8203f\n\n# REVISIT declare an avr32 target ... needs OpenOCD infrastructure\n# for both Nexus (generic) and AVR32 (Atmel-specific).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91r40008.cfg",
    "content": "# AT91R40008 target configuration file\n\n# TRST is tied to SRST on the AT91X40 family.\nreset_config srst_only srst_pulls_trst\n\n\nif {[info exists CHIPNAME]} {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91r40008\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Setup the JTAG scan chain.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91rm9200.cfg",
    "content": "# Atmel AT91rm9200\n# http://atmel.com/products/at91/\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91rm9200\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x05b0203f\n}\n\n# Never allow the following!\nif { $_CPUTAPID == 0x15b0203f } {\n   echo \"-------------------------------------------------------\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: TapID 0x15b0203f is wrong for at91rm9200     -\"\n   echo \"- ERROR: The chip/board has a JTAG select pin/jumper  -\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: In one position (0x05b0203f) it selects the  -\"\n   echo \"- ERROR: ARM CPU, in the other position (0x1b0203f)   -\"\n   echo \"- ERROR: it selects boundary-scan not the ARM         -\"\n   echo \"- ERROR:                                              -\"\n   echo \"-------------------------------------------------------\"\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# AT91RM9200 has a 16K block of sram @ 0x0020.0000\n$_TARGETNAME configure -work-area-phys 0x00200000 \\\n\t\t-work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3XXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam3\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n    halt\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3ax_4x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000A0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3ax_8x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 512K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3ax_xx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3nXX.cfg",
    "content": "\n#\n# Configuration for Atmel's SAM3N series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME at91sam3n\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank flash0 at91sam3 0x00400000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3sXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n\nsource [find target/at91sam3XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u1c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u1e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u2c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u2e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u4c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip, it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3u4e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam3uxx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4XXX.cfg",
    "content": "#\n# script for ATMEL sam4, a Cortex-M4 chip\n#\n\n#\n# sam4 devices can support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam4\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4c32x.cfg",
    "content": "# script for ATMEL sam4c32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x01100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4cXXX.cfg",
    "content": "# script for ATMEL sam4c, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4lXX.cfg",
    "content": "# script for ATMEL sam4l, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME\n\n# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3).\n#\n# smap_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the SMAP to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post \"at91sam4l smap_reset_deassert\"\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed.\n# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio.\n# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2\n# but your mileage may vary.\nadapter speed 50\n\n# System RC oscillator RCSYS starts in 3 cycles\nadapter srst delay 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4sXX.cfg",
    "content": "# script for ATMEL sam4, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam4sd32x.cfg",
    "content": "# script for ATMEL sam4sd32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x00500000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam7a2.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7a2\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam7se512.cfg",
    "content": "# ATMEL sam7se512\n# Example: the \"Elektor Internet Radio\" - EIR\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7se512\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# The target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam7sx.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7s\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -event reset-init {\n        soft_reset_halt\n        # RSTC_CR : Reset peripherals\n        mww 0xfffffd00 0xa5000004\n        # disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=73)\n\tmww 0xffffff60 0x00490100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam7x256.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7x256\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam7x512.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME sam7x512\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\nflash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9\n######################################\n\nif { [info exists AT91_CHIPNAME] } {\n\tset _CHIPNAME $AT91_CHIPNAME\n} else {\n\terror \"you must specify a chip name\"\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0792603f\n}\n\nreset_config trst_and_srst separate trst_push_pull srst_open_drain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 300\njtag_ntrst_delay 200\n\nadapter speed 3\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9260.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9260\n}\n\nsource [find target/at91sam9.cfg]\n\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9260 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 4 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x1000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9260_ext_RAM_ext_flash.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nsource [find target/at91sam9261.cfg]\n\nreset_config trst_and_srst\n\nadapter speed 4\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\nscan_chain\n$_TARGETNAME configure -event reset-start {\n\t# at reset chip runs at 32khz\n\tadapter speed 8\n}\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n# Flash configuration\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n\n# Faster memory downloads. This is disabled automatically during\n# reset init since all reset init sequences are too short for\n# fast memory access\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\nproc at91sam_init { } {\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# Now run at anything fast... ie: 10mhz!\n\tadapter speed 10000               ;# Increase JTAG Speed to 6 MHz\n\n\tmww 0xffffec00 0x0a0a0a0a         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x0b0b0b0b         ;# SMC_PULSE0\n\tmww 0xffffec08 0x00160016         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00161003         ;# SMC_MODE0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR : Select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000         ;# PIO_PDR : Disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x2                ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\t#mww 0xffffea08 0x85227254         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S641632H-UC75 : 1M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x5d2              ;# SDRAMC_TR : Set refresh timer count to 15us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9261.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9261\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9261\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x28000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9263.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9263\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9263\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9263 has two SRAM areas,\n# one starting at 0x00300000 of 80KiB\n# and the other  starting at 0x00500000 of 16KiB.\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x14000 -work-area-backup 1\n#$_TARGETNAME configure -work-area-phys 0x00500000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9g10.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G10\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g10\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G10 has one SRAM area at 0x00300000 of 16KiB\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9g20.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G20\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g20\n}\n\nsource [find target/at91sam9.cfg]\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n\nadapter speed 5\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 16 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9g45.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G45\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g45\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G45 has one SRAM area starting at 0x00300000 of 64 KiB.\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x200000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sam9rl.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9RL\n######################################\n\nif { [info exists CHIPNAME] } {\n   set AT91_CHIPNAME $CHIPNAME\n} else {\n   set AT91_CHIPNAME at91sam9rl\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x10000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91sama5d2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The JTAG connection is disabled at reset, and during the ROM Code execution.\n# It is re-enabled when the ROM code jumps in the boot file copied from an\n# external Flash memory into the internalSRAM, or when the ROM code launches\n# the SAM-BA monitor, when no boot file has been found in any external Flash\n# memory.\n# For more JTAG related information see, :\n# https://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-sheet-ds60001476G.pdf\n#\n# If JTAGSEL pin:\n# - if enabled, boundary Scan mode is activated. JTAG ID Code value is 0x05B3F03F.\n# - if disabled, ICE mode is activated. Debug Port JTAG IDCODE value is 0x5BA00477\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME at91sama5d2\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n\t-expected-id 0x5ba00477\n\n# Cortex-A5 target\nset _TARGETNAME $_CHIPNAME.cpu_a5\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91samdXX.cfg",
    "content": "#\n# script for Atmel SAMD, SAMR, SAML or SAMC, a Cortex-M0 chip\n#\n\n#\n# samdXX devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91samd\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2)\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        at91samd dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset.\n# Other members of family usually use SYSCLK = 4 MHz after reset.\n# Datasheet does not specify SYSCLK to SWD clock ratio.\n# Usually used SYSCLK/6 is slow, testing shows that debugging can\n# work @ SYSCLK/2 but your mileage may vary.\n# This limit is most probably imposed by incorrectly handled SWD WAIT\n# on some SWD adapters.\n\nadapter speed 400\n\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at maximal clock speed. Atmel recommends\n# adapter speed less than 10 * CPU clock.\n# adapter speed 5000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/at91samg5x.cfg",
    "content": "# script for the ATMEL samg5x Cortex-M4F chip family\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atheros_ar2313.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2313\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atheros_ar2315.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2315\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atheros_ar9331.cfg",
    "content": "# The Atheros AR9331 is a highly integrated and cost effective\n# IEEE 802.11n 1x1 2.4 GHz System- on-a-Chip (SoC) for wireless\n# local area network (WLAN) AP and router platforms.\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 400 MHz\n# - External 16-bit DDR1, DDR2, or SDRAM memory interface\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin A72 on the SoC will reset internal JTAG logic.\n#\n\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO6, (B46)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO7, (A54)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO8, (A52)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (A72)\tInput only\n# SYS_RST_L\t????????\tOutput reset request or GPIO\n#   Bootstrap\n# MEM_TYPE[1]\tGPIO28, (A74)\t0 - SDRAM, 1 - DDR1 RAM, 2 - DDR2 RAM\n# MEM_TYPE[0]\tGPIO12, (A56)\n# FW_DOWNLOAD\tGPIO16, (A75)\tUsed if BOOT_FROM_SPI = 0. 0 - boot from USB\n#                               1 - boot from MDIO.\n# JTAG_MODE(JS)\tGPIO11, (B48)\t0 - JTAG (Default); 1 - EJTAG\n# BOOT_FROM_SPI\tGPIO1, (A77)\t0 - ROM boot; 1 - SPI boot\n# SEL_25M_40M\tGPIO0, (A78)\t0 - 25MHz; 1 - 40MHz\n#   UART\n# UART0_SOUT\tGPIO10, (A79)\n# UART0_SIN\tGPIO9, (B68)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9331\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\nproc disable_watchdog { } {\n\t;# disable watchdog\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n\n# Section with helpers which can be used by boards\nproc ar9331_25mhz_pll_init {} {\n\tmww 0xb8050008 0x00018004\t;# bypass PLL; AHB_POST_DIV - ratio 4\n\tmww 0xb8050004 0x00000352\t;# 34000(ns)/40ns(25MHz) = 0x352 (850)\n\tmww 0xb8050000 0x40818000\t;# Power down control for CPU PLL\n\t\t\t\t\t;# OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050010 0x001003e8\t;# CPU PLL Dither FRAC Register\n\t\t\t\t\t;# (disabled?)\n\tmww 0xb8050000 0x00818000\t;# Power on | OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050008 0x00008000\t;# remove bypass;\n\t\t\t\t\t;# AHB_POST_DIV - ratio 2\n}\n\nproc ar9331_ddr1_init {} {\n\tmww 0xb8000000 0x7fbc8cd0       ;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x133\t;# mode reg: 0x133 - default\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb800000c 0x2\t;# Extended mode register value.\n\t\t\t\t;# default 0x2 - Reset to weak driver, DLL on\n\tmww 0xb8000010 0x2\t;# Forces an EMRS update cycle\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x33\t;# mode reg: remove some bit?\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb8000014 0x4186\t;# enable refres: bit(14) - set refresh rate\n\tmww 0xb800001c 0x8\t;# This register is used along with DQ Lane 0,\n\t\t\t\t;# DQ[7:0], DQS_0\n\tmww 0xb8000020 0x9\t;# This register is used along with DQ Lane 1,\n\t\t\t\t;# DQ[15:8], DQS_1.\n\tmww 0xb8000018 0xff\t;# DDR read and capture bit mask.\n\t\t\t\t;# Each bit represents a cycle of valid data.\n}\n\nproc ar9331_ddr2_init {} {\n\tmww 0xb8000000 0x7fbc8cd0\t;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb800008c 0x00000a59\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000090 0x00000000\n\tmww 0xb8000010 0x00000010\t;# EMR2S update cycle\n\n\tmww 0xb8000094 0x00000000\n\tmww 0xb8000010 0x00000020\t;# EMR3S update cycle\n\n\tmww 0xb800000c 0x00000000\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000008 0x00000100\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000010 0x00000004\n\tmww 0xb8000010 0x00000004\t;# AUTO REFRESH cycle\n\n\tmww 0xb8000008 0x00000a33\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb800000c 0x00000382\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb800000c 0x00000402\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000014 0x00004186\t;# DDR_REFRESH\n\tmww 0xb800001c 0x00000008\t;# DDR_TAP_CTRL0\n\tmww 0xb8000020 0x00000009\t;# DDR_TAP_CTRL1\n\n\t;# DDR read and capture bit mask.\n\t;# Each bit represents a cycle of valid data.\n\t;# 0xff: use 16-bit DDR\n\tmww 0xb8000018 0x000000ff\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atheros_ar9344.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9344\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\nproc test_ar9344_uart0_tx {} {\n\techo \"configuring uart0..\"\n\tmww 0xb802000c 0x87\n\tmww 0xb8020000 0x15\n\tmww 0xb8020004 0\n\tmww 0xb802000c 7\n\tmww 0xb8020004 0\n\n\techo \"send message: hallo world\"\n\tmww 0xb8020000 0x68\n\tmww 0xb8020000 0x65\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x20\n\tmww 0xb8020000 0x77\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x72\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x64\n\tmww 0xb8020000 0x0a\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atmega128.cfg",
    "content": "# for avr\n\n   set _CHIPNAME avr\n   set _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\nreset_config srst_only\nadapter srst delay 100\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x8970203F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n\n#to use it, script will be like:\n#init\n#adapter speed 4500\n#reset init\n#verify_ircapture disable\n#\n#halt\n#wait halt\n#poll\n#avr mass_erase 0\n#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex\n#reset run\n#shutdown\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atmega128rfa1.cfg",
    "content": "set _CHIPNAME avr\nset _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\n# avr jtag docs never connect RSTN\nreset_config none\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0a70103f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atsame5x.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54, E53, E51 and D51 devices\n# with a Cortex-M4 core\n#\n\n#\n# Devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME atsame5\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (the smallest RAM size is 128kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAM DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        atsame5 dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAM E5x/D51 runs at SYSCLK = 48 MHz from RC oscillator after reset.\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at clock speed over 5000 khz. Atmel recommends\n# adapter speed less than 10 * CPU clock.\nadapter speed 2000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atsaml1x.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L1x target\n#\n# Note: These devices support SWD only.\n#\n\ntransport select swd\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME saml1x\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nswd newdap $_CHIPNAME cpu -expected-id 0x0bf11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/atsamv.cfg",
    "content": "# ATMEL SAMV, SAMS, and SAME chips are Cortex-M7 parts\n# The chips are very similar; the SAMV series just has\n# more peripherals and seems like the \"flagship\" of the\n# family. This script will work for all of them.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME samv\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bd11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 1800\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/avr32.cfg",
    "content": "set _CHIPNAME avr32\nset _ENDIAN big\n\nset _CPUTAPID 0x21e8203f\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CPUTAPID\n\nset _TARGETNAME [format \"%s.cpu\" $_CHIPNAME]\ntarget create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm2711.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom BCM2711 used in Raspberry Pi 4\n# No documentation was found on Broadcom website\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2711\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm281xx.cfg",
    "content": "# BCM281xx\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm281xx\n}\n\n\n# Main CPU DAP\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\n\n\n# Dual Cortex-A9\nset _TARGETNAME0 $_CHIPNAME.cpu0\nset _TARGETNAME1 $_CHIPNAME.cpu1\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME0 cortex_a -dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x3fe10000\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0x3fe12000\ntarget smp $_TARGETNAME0 $_TARGETNAME1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm2835.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi Model A, B, B+,\n# the Compute Module, and the Raspberry Pi Zero.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2835\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x07b7617F\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 5\nadapter speed 4000\n\ntarget create $_CHIPNAME.cpu0 arm11 -chain-position $_CHIPNAME.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm2836.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom chip used in the Raspberry Pi 2 Model B\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2836\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\ttarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -coreid $_core -dbgbase [lindex $_DBGBASE $_core]\n\t$_TARGETNAME configure -event reset-assert-post { cortex_a dbginit }\n\n\tset _smp_command \"$_smp_command $_CHIPNAME.cpu$_core\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm2837.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi 3,\n# and in later models of the Raspberry Pi 2.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837b0\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2837\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\nset _CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\t$_TARGETNAME configure -event reset-assert-post { aarch64  dbginit }\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm4706.cfg",
    "content": "set _CHIPNAME bcm4706\nset _CPUID 0x1008c17f\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm4718.cfg",
    "content": "set _CHIPNAME bcm4718\nset _LVTAPID 0x1471617f\nset _CPUID 0x0008c17f\n\nsource [find target/bcm47xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm47xx.cfg",
    "content": "echo \"Forcing reset_config to none to prevent OpenOCD from pulling SRST after the switch from LV is already performed\"\nreset_config none\n\njtag newtap $_CHIPNAME-lv tap -irlen 32 -ircapture 0x1 -irmask 0x1f -expected-id $_LVTAPID -expected-id $_CPUID\njtag configure $_CHIPNAME-lv.tap -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME-lv.tap -event tap-disable {}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"switch_lv_to_ejtag\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n\nproc switch_lv_to_ejtag {} {\n    global _CHIPNAME\n    poll 0\n    irscan $_CHIPNAME-lv.tap 0x143ff3a\n    drscan $_CHIPNAME-lv.tap 32 1\n    jtag tapdisable $_CHIPNAME-lv.tap\n    poll 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm5352e.cfg",
    "content": "set _CHIPNAME bcm5352e\nset _CPUID 0x0535217f\n\njtag newtap $_CHIPNAME cpu -irlen 8 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bcm6348.cfg",
    "content": "set _CHIPNAME bcm6348\nset _CPUID 0x0634817f\n\nadapter speed 1000\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bluefield.cfg",
    "content": "# BlueField SoC Target\n\nset _CHIPNAME bluefield\n\n# Specify the target device\n#rshim device /dev/rshim0/rshim\n\n# Main DAP\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\nadapter speed 1500\n\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Initialize the target name and command variable.\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\n# CTI relative address\nset $_TARGETNAME.cti(0) 0xC4020000\nset $_TARGETNAME.cti(1) 0xC4120000\nset $_TARGETNAME.cti(2) 0xC8020000\nset $_TARGETNAME.cti(3) 0xC8120000\nset $_TARGETNAME.cti(4) 0xCC020000\nset $_TARGETNAME.cti(5) 0xCC120000\nset $_TARGETNAME.cti(6) 0xD0020000\nset $_TARGETNAME.cti(7) 0xD0120000\nset $_TARGETNAME.cti(8) 0xD4020000\nset $_TARGETNAME.cti(9) 0xD4120000\nset $_TARGETNAME.cti(10) 0xD8020000\nset $_TARGETNAME.cti(11) 0xD8120000\nset $_TARGETNAME.cti(12) 0xDC020000\nset $_TARGETNAME.cti(13) 0xDC120000\nset $_TARGETNAME.cti(14) 0xE0020000\nset $_TARGETNAME.cti(15) 0xE0120000\n\n# Create debug targets for a number of cores starting from core '_core_start'.\n# Adjust the numbers according to board configuration.\nset _core_start 0\nset _cores 16\n\n# Create each core\nfor { set _core $_core_start } { $_core < $_core_start + $_cores } { incr _core 1 } {\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != $_core_start } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\n# Configure SMP\nif { $_cores > 1 } {\n    eval $_smp_command\n}\n\n# Make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# Examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/bluenrg-x.cfg",
    "content": "#\n# bluenrg-1/2 and bluenrg-lp devices support only SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME bluenrg-1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 24kB-256bytes\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x5F00\n}\n\nadapter speed 4000\n\nswj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\nset WDOG_VALUE 0\nset WDOG_VALUE_SET 0\n\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000100 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n# In BlueNRG-X reset pin is actually a shutdown (power-off), so define reset as none\nreset_config none\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset JTAG_IDCODE_B2 0x0200A041\nset JTAG_IDCODE_B1 0x0\n\n$_TARGETNAME configure -event halted {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        # Stop watchdog during halt, if enabled. Only Bluenrg-1/2\n        set WDOG_VALUE [mrw 0x40700008]\n        if [expr {$WDOG_VALUE & (1 << 1)}] {\n            set WDOG_VALUE_SET 1\n            mww 0x40700008 [expr {$WDOG_VALUE & 0xFFFFFFFD}]\n        }\n    }\n}\n$_TARGETNAME configure -event resumed {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        if {$WDOG_VALUE_SET} {\n            # Restore watchdog enable value after resume. Only Bluenrg-1/2\n            mww 0x40700008 $WDOG_VALUE\n            set WDOG_VALUE_SET 0\n           }\n   }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/c100.cfg",
    "content": "# c100 config.\n# This is ARM1136 dual core\n# this script only configures one core (that is used to run Linux)\n\n# assume no PLL lock, start slowly\nadapter speed 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME c100\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x27b3645b\n}\n\nif { [info exists DSPTAPID] } {\n   set _DSPTAPID $DSPTAPID\n} else {\n   set _DSPTAPID 0x27b3645b\n}\n\njtag newtap $_CHIPNAME dsp -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_DSPTAPID\n\n\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# C100's ARAM 64k SRAM\n$_TARGETNAME configure -work-area-phys 0x0a000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/c100config.tcl",
    "content": "\n# board(-config) specific parameters file.\n\n# set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ]\nproc config {label} {\n    return [dict get [configC100] $label ]\n}\n\n# show the value for the param. with label\nproc showconfig {label} {\n    echo [format \"0x%x\" [dict get [configC100] $label ]]\n}\n\n# Telo board config\n# when there are more then one board config\n# use soft links to c100board-config.tcl\n# so that only the right board-config gets\n# included (just like include/configs/board-configs.h\n# in u-boot.\nproc configC100 {} {\n    # xtal freq. 24MHz\n    dict set configC100 CFG_REFCLKFREQ\t         24000000\n\n    # Amba Clk 165MHz\n    dict set configC100 CONFIG_SYS_HZ_CLOCK      165000000\n    dict set configC100 w_amba 1\n    dict set configC100 x_amba 1\n    # y = amba_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_amba [expr {[dict get $configC100 CONFIG_SYS_HZ_CLOCK] * ( ([dict get $configC100 w_amba]+1 ) * ([dict get $configC100 x_amba]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n    # Arm Clk 450MHz, must be a multiple of 25 MHz\n    dict set configC100 CFG_ARM_CLOCK      450000000\n    dict set configC100 w_arm 0\n    dict set configC100 x_arm 1\n    # y = arm_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_arm [expr {[dict get $configC100 CFG_ARM_CLOCK] * ( ([dict get $configC100 w_arm]+1 ) * ([dict get $configC100 x_arm]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n\n}\n\n# This should be called for reset init event handler\nproc setupTelo {} {\n\n    # setup GPIO used as control signals for C100\n    setupGPIO\n    # This will allow access to lower 8MB or NOR\n    lowGPIO5\n    # setup NOR size,timing,etc.\n    setupNOR\n    # setup internals + PLL + DDR2\n    initC100\n}\n\n\nproc setupNOR {} {\n    echo \"Setting up NOR: 16MB, 16-bit wide bus, CS0\"\n    # this is taken from u-boot/boards/mindspeed/ooma-darwin/board.c:nor_hw_init()\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    # enable Expansion Bus Clock + CS0 (NOR)\n    mww $EX_CSEN_REG 0x3\n    # set the address space for CS0=16MB\n    mww $EX_CS0_SEG_REG 0x7ff\n    # set the CS0 bus width to 16-bit\n    mww $EX_CS0_CFG_REG 0x202\n    # set timings to NOR\n    mww $EX_CS0_TMG1_REG 0x03034006\n    mww $EX_CS0_TMG2_REG 0x04040002\n    #mww $EX_CS0_TMG3_REG\n    # set EBUS clock 165/5=33MHz\n    mww $EX_CLOCK_DIV_REG 0x5\n    # everything else is OK with default\n}\n\nproc bootNOR {} {\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n    set BLOCK_RESET_REG\t       [regs BLOCK_RESET_REG]\n    set DDR_RST\t\t       [regs DDR_RST]\n\n    # put DDR controller in reset (so that it comes reset in u-boot)\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $EXP_CS0_BASEADDR\n    # run\n    resume\n}\nproc setupGPIO {} {\n    echo \"Setting up GPIO block for Telo\"\n    # This is current setup for Telo (see sch. for details):\n    #GPIO0 reset for FXS-FXO IC, leave as input, the IC has internal pullup\n    #GPIO1 irq line for FXS-FXO\n    #GPIO5 addr22 for NOR flash (access to upper 8MB)\n    #GPIO17 reset for DECT module.\n    #GPIO29 CS_n for NAND\n\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n\n    # set GPIO29=GPIO17=1, GPIO5=0\n    mww $GPIO_OUTPUT_REG [expr {1<<29 | 1<<17}]\n    # enable [as output] GPIO29,GPIO17,GPIO5\n    mww $GPIO_OE_REG [expr  {1<<29 | 1<<17 | 1<<5}]\n}\n\nproc highGPIO5 {} {\n    echo \"GPIO5 high\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=1\n    mmw $GPIO_OUTPUT_REG [expr {1 << 5}] 0x0\n}\n\nproc lowGPIO5 {} {\n    echo \"GPIO5 low\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=0\n    mmw $GPIO_OUTPUT_REG 0x0 [expr {1 << 5}]\n}\n\nproc boardID {id} {\n    # so far built:\n    # 4'b1111\n    dict set boardID 15 name \"EVT1\"\n    dict set boardID 15 ddr2size 128M\n    # dict set boardID 15 nandsize 1G\n    # dict set boardID 15 norsize 16M\n    # 4'b0000\n    dict set boardID 0 name \"EVT2\"\n    dict set boardID 0 ddr2size 128M\n    # 4'b0001\n    dict set boardID 1 name \"EVT3\"\n    dict set boardID 1 ddr2size 256M\n    # 4'b1110\n    dict set boardID 14 name \"EVT3_old\"\n    dict set boardID 14 ddr2size 128M\n    # 4'b0010\n    dict set boardID 2 name \"EVT4\"\n    dict set boardID 2 ddr2size 256M\n\n    return $boardID\n}\n\n\n# converted from u-boot/boards/mindspeed/ooma-darwin/board.c:ooma_board_detect()\n# figure out what board revision this is, uses BOOTSTRAP register to read stuffed resistors\nproc ooma_board_detect {} {\n    set GPIO_BOOTSTRAP_REG\t[regs GPIO_BOOTSTRAP_REG]\n\n    # read the current value of the BOOTSTRAP pins\n    set tmp [mrw $GPIO_BOOTSTRAP_REG]\n    echo [format \"GPIO_BOOTSTRAP_REG  (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG $tmp]\n    # extract the GPBP bits\n    set gpbt [expr {($tmp &0x1C00) >> 10 | ($tmp & 0x40) >>3}]\n\n    # display board ID\n    echo [format \"This is %s (0x%x)\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # show it on serial console\n    putsUART0 [format \"This is %s (0x%x)\\n\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # return the ddr2 size, used to configure DDR2 on a given board.\n    return [dict get [boardID $gpbt] $gpbt ddr2size]\n}\n\nproc configureDDR2regs_256M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set DENALI_CTL_02_VAL 0x0100000000010100\n    set DENALI_CTL_11_VAL 0x433a32164a560a00\n\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    # 01_DATA mod [40]=1, enable BA2\n    mw64bit $DENALI_CTL_01_DATA  0x0100010100000001\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0000010100000001\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x060a020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x0000000300000206\n    mw64bit $DENALI_CTL_08_DATA  0x6400003f3f0a0209\n    mw64bit $DENALI_CTL_09_DATA  0x1a000000001a1a1a\n    mw64bit $DENALI_CTL_10_DATA  0x0120202020191a18\n    # 11_DATA mod [39-32]=16,more refresh\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000000000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x04f8000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000000002cca0000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000000000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001300c8030600\n    mw64bit $DENALI_CTL_20_DATA  0x0000000081fe00c8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c:config_board99()\n# The values are computed based on Mindspeed and Nanya datasheets\nproc configureDDR2regs_128M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n\n    set DENALI_CTL_02_VAL 0x0100010000010100\n    set DENALI_CTL_11_VAL 0x433A42124A650A37\n    # set some default values\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    mw64bit $DENALI_CTL_01_DATA  0x0100000100000101\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0201010100000201\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x050A020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x000000030E0B0205\n    mw64bit $DENALI_CTL_08_DATA  0x6427003F3F0A0209\n    mw64bit $DENALI_CTL_09_DATA  0x1A00002F00001A00\n    mw64bit $DENALI_CTL_10_DATA  0x01202020201A1A1A\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000080000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x0508000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000020472D200000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000008000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001400C8030604\n    mw64bit $DENALI_CTL_20_DATA  0x00000000823600C8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    # This is not necessary\n    #mw64bit $DENALI_CTL_11_DATA [expr {($DENALI_CTL_11_VAL  & ~0x00007F0000000000) | ($wr_dqs_shift << 40)} ]\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n\n\nproc setupUART0 {} {\n    # configure UART0 to 115200, 8N1\n    set GPIO_LOCK_REG      [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL    [regs GPIO_IOCTRL_VAL]\n    set GPIO_IOCTRL_UART0  [regs GPIO_IOCTRL_UART0]\n    set UART0_LCR\t            [regs UART0_LCR]\n    set LCR_DLAB\t\t    [regs LCR_DLAB]\n    set UART0_DLL\t\t    [regs UART0_DLL]\n    set UART0_DLH\t\t    [regs UART0_DLH]\n    set UART0_IIR\t\t    [regs UART0_IIR]\n    set UART0_IER\t\t    [regs UART0_IER]\n    set LCR_ONE_STOP\t\t    [regs LCR_ONE_STOP]\n    set LCR_CHAR_LEN_8\t\t    [regs LCR_CHAR_LEN_8]\n    set FCR_XMITRES\t\t    [regs FCR_XMITRES]\n    set FCR_RCVRRES\t\t    [regs FCR_RCVRRES]\n    set FCR_FIFOEN\t\t    [regs FCR_FIFOEN]\n    set IER_UUE\t\t\t    [regs IER_UUE]\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable UART0\n    mmw $GPIO_IOCTRL_REG $GPIO_IOCTRL_UART0 0x0\n    # baudrate  115200\n    # This should really be amba_clk/(16*115200) but amba_clk=165MHz\n    set tmp 89\n    # Enable Divisor Latch access\n    mmw  $UART0_LCR $LCR_DLAB 0x0\n    # set the divisor to $tmp\n    mww $UART0_DLL [expr {$tmp & 0xff}]\n    mww $UART0_DLH [expr {$tmp >> 8}]\n    # Disable Divisor Latch access\n    mmw  $UART0_LCR 0x0 $LCR_DLAB\n    # set the UART to 8N1\n    mmw  $UART0_LCR [expr {$LCR_ONE_STOP | $LCR_CHAR_LEN_8} ] 0x0\n    # reset FIFO\n    mmw  $UART0_IIR [expr {$FCR_XMITRES  | $FCR_RCVRRES | $FCR_FIFOEN} ] 0x0\n    #  enable FFUART\n    mww $UART0_IER $IER_UUE\n}\n\nproc putcUART0 {char} {\n\n    set UART0_LSR\t    [regs UART0_LSR]\n    set UART0_THR\t    [regs UART0_THR]\n    set LSR_TEMT\t    [regs LSR_TEMT]\n\n    # convert the 'char' to digit\n    set tmp [ scan $char %c ]\n    # /* wait for room in the tx FIFO on FFUART */\n    while {[expr {[mrw $UART0_LSR] & $LSR_TEMT}] == 0} { sleep 1 }\n    mww $UART0_THR $tmp\n    if { $char == \"\\n\" } { putcUART0 \\r }\n}\n\nproc putsUART0 {str} {\n    set index 0\n    set len [string length $str]\n    while { $index < $len } {\n\tputcUART0 [string index $str $index]\n\tset index [expr {$index + 1}]\n    }\n}\n\n\nproc trainDDR2 {} {\n    set ARAM_BASEADDR\t[regs ARAM_BASEADDR]\n\n    # you must have run 'reset init' or u-boot\n    # load the training code to ARAM\n    load_image ./images/ddr2train.bin $ARAM_BASEADDR bin\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $ARAM_BASEADDR\n    # run\n    resume\n}\n\nproc flashUBOOT {file} {\n    # this will update uboot on NOR partition\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    flash probe 0\n    echo \"Erasing sectors 0-3 for uboot\"\n    putsUART0 \"Erasing sectors 0-3 for uboot\\n\"\n    flash erase_sector 0 0 3\n    echo \"Programming u-boot\"\n    putsUART0 \"Programming u-boot...\"\n    arm11 memwrite burst enable\n    flash write_image $file $EXP_CS0_BASEADDR\n    arm11 memwrite burst disable\n    putsUART0 \"done.\\n\"\n    putsUART0 \"Rebooting, please wait!\\n\"\n    reboot\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/c100helper.tcl",
    "content": "\nproc helpC100 {} {\n    echo \"List of useful functions for C100 processor:\"\n    echo \"1)  reset init:        will set up your Telo board\"\n    echo \"2)  setupNOR:          will setup NOR access\"\n    echo \"3)  showNOR:           will show current NOR config registers for 16-bit, 16MB NOR\"\n    echo \"4)  setupGPIO:         will setup GPIOs for Telo board\"\n    echo \"5)  showGPIO:          will show current GPIO config registers\"\n    echo \"6)  highGPIO5:         will set GPIO5=NOR_addr22=1 to access upper 8MB\"\n    echo \"7)  lowGPIO5:          will set GPIO5=NOR_addr22=0 to access lower 8MB\"\n    echo \"8)  showAmbaClk:       will show current config registers for Amba Bus Clock\"\n    echo \"9)  setupAmbaClk:      will setup Amba Bus Clock=165MHz\"\n    echo \"10) showArmClk:        will show current config registers for Arm Bus Clock\"\n    echo \"11) setupArmClk:       will setup Amba Bus Clock=450MHz\"\n    echo \"12) ooma_board_detect: will show which version of Telo you have\"\n    echo \"13) setupDDR2:         will configure DDR2 controller, you must have PLLs configured\"\n    echo \"14) showDDR2:          will show DDR2 config registers\"\n    echo \"15) showWatchdog:      will show current register config for watchdog\"\n    echo \"16) reboot:            will trigger watchdog and reboot Telo (hw reset)\"\n    echo \"17) bootNOR:           will boot Telo from NOR\"\n    echo \"18) setupUART0:        will configure UART0 for 115200 8N1, PLLs have to be configured\"\n    echo \"19) putcUART0:         will print a character on UART0\"\n    echo \"20) putsUART0:         will print a string on UART0\"\n    echo \"21) trainDDR2:         will run DDR2 training program\"\n    echo \"22) flashUBOOT:        will program NOR sectors 0-3 with u-boot.bin\"\n}\n\nsource [find mem_helper.tcl]\n\n# read a 64-bit register (memory mapped)\nproc mr64bit {reg} {\n    return [read_memory $reg 32 2]\n}\n\n\n# write a 64-bit register (memory mapped)\nproc mw64bit {reg value} {\n    set high [expr {$value >> 32}]\n    set low  [expr {$value & 0xffffffff}]\n    #echo [format \"mw64bit(0x%x): 0x%08x%08x\" $reg $high $low]\n    mww $reg $low\n    mww [expr {$reg+4}] $high\n}\n\n\nproc showNOR {} {\n    echo \"This is the current NOR setup\"\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    echo [format \"EX_CSEN_REG      (0x%x): 0x%x\" $EX_CSEN_REG [mrw $EX_CSEN_REG]]\n    echo [format \"EX_CS0_SEG_REG   (0x%x): 0x%x\" $EX_CS0_SEG_REG [mrw $EX_CS0_SEG_REG]]\n    echo [format \"EX_CS0_CFG_REG   (0x%x): 0x%x\" $EX_CS0_CFG_REG [mrw $EX_CS0_CFG_REG]]\n    echo [format \"EX_CS0_TMG1_REG  (0x%x): 0x%x\" $EX_CS0_TMG1_REG [mrw $EX_CS0_TMG1_REG]]\n    echo [format \"EX_CS0_TMG2_REG  (0x%x): 0x%x\" $EX_CS0_TMG2_REG [mrw $EX_CS0_TMG2_REG]]\n    echo [format \"EX_CS0_TMG3_REG  (0x%x): 0x%x\" $EX_CS0_TMG3_REG [mrw $EX_CS0_TMG3_REG]]\n    echo [format \"EX_CLOCK_DIV_REG (0x%x): 0x%x\" $EX_CLOCK_DIV_REG [mrw $EX_CLOCK_DIV_REG]]\n    echo [format \"EX_MFSM_REG      (0x%x): 0x%x\" $EX_MFSM_REG [mrw $EX_MFSM_REG]]\n    echo [format \"EX_CSFSM_REG     (0x%x): 0x%x\" $EX_CSFSM_REG [mrw $EX_CSFSM_REG]]\n    echo [format \"EX_WRFSM_REG     (0x%x): 0x%x\" $EX_WRFSM_REG [mrw $EX_WRFSM_REG]]\n    echo [format \"EX_RDFSM_REG     (0x%x): 0x%x\" $EX_RDFSM_REG [mrw $EX_RDFSM_REG]]\n}\n\n\n\nproc showGPIO {} {\n    echo \"This is the current GPIO register setup\"\n    # GPIO outputs register\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # GPIO Output Enable register\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n    set GPIO_HI_INT_ENABLE_REG\t    [regs GPIO_HI_INT_ENABLE_REG]\n    set GPIO_LO_INT_ENABLE_REG\t    [regs GPIO_LO_INT_ENABLE_REG]\n    # GPIO input register\n    set GPIO_INPUT_REG\t\t    [regs GPIO_INPUT_REG]\n    set APB_ACCESS_WS_REG\t    [regs APB_ACCESS_WS_REG]\n    set MUX_CONF_REG\t\t    [regs MUX_CONF_REG]\n    set SYSCONF_REG\t\t    [regs SYSCONF_REG]\n    set GPIO_ARM_ID_REG\t\t    [regs GPIO_ARM_ID_REG]\n    set GPIO_BOOTSTRAP_REG\t    [regs GPIO_BOOTSTRAP_REG]\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_DEVID_REG\t\t    [regs GPIO_DEVID_REG]\n\n    echo [format \"GPIO_OUTPUT_REG       (0x%x): 0x%x\" $GPIO_OUTPUT_REG [mrw $GPIO_OUTPUT_REG]]\n    echo [format \"GPIO_OE_REG           (0x%x): 0x%x\" $GPIO_OE_REG [mrw $GPIO_OE_REG]]\n    echo [format \"GPIO_HI_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_HI_INT_ENABLE_REG [mrw $GPIO_HI_INT_ENABLE_REG]]\n    echo [format \"GPIO_LO_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_LO_INT_ENABLE_REG [mrw $GPIO_LO_INT_ENABLE_REG]]\n    echo [format \"GPIO_INPUT_REG        (0x%x): 0x%x\" $GPIO_INPUT_REG [mrw $GPIO_INPUT_REG]]\n    echo [format \"APB_ACCESS_WS_REG     (0x%x): 0x%x\" $APB_ACCESS_WS_REG [mrw $APB_ACCESS_WS_REG]]\n    echo [format \"MUX_CONF_REG          (0x%x): 0x%x\" $MUX_CONF_REG [mrw $MUX_CONF_REG]]\n    echo [format \"SYSCONF_REG           (0x%x): 0x%x\" $SYSCONF_REG [mrw $SYSCONF_REG]]\n    echo [format \"GPIO_ARM_ID_REG       (0x%x): 0x%x\" $GPIO_ARM_ID_REG [mrw $GPIO_ARM_ID_REG]]\n    echo [format \"GPIO_BOOTSTRAP_REG    (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG [mrw $GPIO_BOOTSTRAP_REG]]\n    echo [format \"GPIO_LOCK_REG         (0x%x): 0x%x\" $GPIO_LOCK_REG [mrw $GPIO_LOCK_REG]]\n    echo [format \"GPIO_IOCTRL_REG       (0x%x): 0x%x\" $GPIO_IOCTRL_REG [mrw $GPIO_IOCTRL_REG]]\n    echo [format \"GPIO_DEVID_REG        (0x%x): 0x%x\" $GPIO_DEVID_REG [mrw $GPIO_DEVID_REG]]\n}\n\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_amba_clk())\nproc showAmbaClk {} {\n    set CFG_REFCLKFREQ\t\t     [config CFG_REFCLKFREQ]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t             [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_AHB_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_AHB_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Amba PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_amba_clk())\n# this clock is useb by all peripherals (DDR2, ethernet, ebus, etc)\nproc setupAmbaClk {} {\n    set CLKCORE_PLL_STATUS           [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t    [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t    [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t    [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t    [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t    [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t    [regs DIV_BYPASS]\n    set AHBCLK_PLL_LOCK\t    [regs AHBCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t [config CFG_REFCLKFREQ]\n    set CONFIG_SYS_HZ_CLOCK      [config CONFIG_SYS_HZ_CLOCK]\n    set w    [config w_amba]\n    set x    [config x_amba]\n    set y    [config y_amba]\n\n    echo [format \"Setting Amba PLL to lock to %d MHz\" [expr {$CONFIG_SYS_HZ_CLOCK/1000000}]]\n    #echo [format \"setupAmbaClk: w= %d\" $w]\n    #echo [format \"setupAmbaClk: x= %d\" $x]\n    #echo [format \"setupAmbaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL $AHB_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_AHB_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_arm_clk())\nproc showArmClk {} {\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CLKCORE_ARM_CLK_CNTRL\t[regs CLKCORE_ARM_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t        [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_ARM_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_ARM_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Arm PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_arm_clk())\n# Arm Clock is used by two ARM1136 cores\nproc setupArmClk {} {\n    set CLKCORE_PLL_STATUS        [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_ARM_CLK_CNTRL\t  [regs CLKCORE_ARM_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t          [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t          [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t          [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t          [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t          [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t          [regs DIV_BYPASS]\n    set FCLK_PLL_LOCK\t          [regs FCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CFG_ARM_CLOCK\t\t[config CFG_ARM_CLOCK]\n    set w    [config w_arm]\n    set x    [config x_arm]\n    set y    [config y_arm]\n\n    echo [format \"Setting Arm PLL to lock to %d MHz\" [expr {$CFG_ARM_CLOCK/1000000}]]\n    #echo [format \"setupArmClk: w= %d\" $w]\n    #echo [format \"setupArmaClk: x= %d\" $x]\n    #echo [format \"setupArmaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL $ARM_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_ARM_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n\nproc setupPLL {} {\n    echo \"PLLs setup\"\n    setupAmbaClk\n    setupArmClk\n}\n\n# converted from u-boot/cpu/arm1136/bsp100.c:SoC_mem_init()\nproc setupDDR2 {} {\n    echo \"Configuring DDR2\"\n\n    set MEMORY_BASE_ADDR\t    [regs  MEMORY_BASE_ADDR]\n    set MEMORY_MAX_ADDR\t            [regs  MEMORY_MAX_ADDR]\n    set MEMORY_CR \t\t    [regs  MEMORY_CR]\n    set BLOCK_RESET_REG\t\t    [regs  BLOCK_RESET_REG]\n    set DDR_RST\t\t            [regs  DDR_RST]\n\n    # put DDR controller in reset (so that it is reset and correctly configured)\n    # this is only necessary if DDR was previously confiured\n    # and not reset.\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n\n    set M [expr {1024 * 1024}]\n    set DDR_SZ_1024M\t[expr {1024 * $M}]\n    set DDR_SZ_256M\t[expr {256 * $M}]\n    set DDR_SZ_128M\t[expr {128 * $M}]\n    set DDR_SZ_64M\t[expr {64 * $M}]\n    # ooma_board_detect returns DDR2 memory size\n    set tmp [ooma_board_detect]\n    if {$tmp == \"128M\"} {\n\techo \"DDR2 size 128MB\"\n\tset ddr_size $DDR_SZ_128M\n    } elseif {$tmp == \"256M\"} {\n\techo \"DDR2 size 256MB\"\n\tset ddr_size $DDR_SZ_256M\n    } else {\n\techo \"Don't know how to handle this DDR2 size?\"\n    }\n\n    # Memory setup register\n    mww $MEMORY_MAX_ADDR  [expr {($ddr_size - 1) + $MEMORY_BASE_ADDR}]\n    # disable ROM remap\n    mww $MEMORY_CR 0x0\n    # Take DDR controller out of reset\n    mmw $BLOCK_RESET_REG $DDR_RST 0x0\n    # min. 20 ops delay\n    sleep 1\n\n    # This will setup Denali DDR2 controller\n    if {$tmp == \"128M\"} {\n\tconfigureDDR2regs_128M\n    } elseif {$tmp == \"256M\"} {\n\tconfigureDDR2regs_256M\n    } else {\n\techo \"Don't know how to configure DDR2 setup?\"\n    }\n}\n\n\n\nproc showDDR2 {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set tmp [mr64bit $DENALI_CTL_00_DATA]\n    echo [format \"DENALI_CTL_00_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_00_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_01_DATA]\n    echo [format \"DENALI_CTL_01_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_01_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_02_DATA]\n    echo [format \"DENALI_CTL_02_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_02_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_03_DATA]\n    echo [format \"DENALI_CTL_03_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_03_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_04_DATA]\n    echo [format \"DENALI_CTL_04_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_04_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_05_DATA]\n    echo [format \"DENALI_CTL_05_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_05_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_06_DATA]\n    echo [format \"DENALI_CTL_06_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_06_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_07_DATA]\n    echo [format \"DENALI_CTL_07_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_07_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_08_DATA]\n    echo [format \"DENALI_CTL_08_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_08_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_09_DATA]\n    echo [format \"DENALI_CTL_09_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_09_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_10_DATA]\n    echo [format \"DENALI_CTL_10_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_10_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_11_DATA]\n    echo [format \"DENALI_CTL_11_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_11_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_12_DATA]\n    echo [format \"DENALI_CTL_12_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_12_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_13_DATA]\n    echo [format \"DENALI_CTL_13_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_13_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_14_DATA]\n    echo [format \"DENALI_CTL_14_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_14_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_15_DATA]\n    echo [format \"DENALI_CTL_15_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_15_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_16_DATA]\n    echo [format \"DENALI_CTL_16_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_16_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_17_DATA]\n    echo [format \"DENALI_CTL_17_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_17_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_18_DATA]\n    echo [format \"DENALI_CTL_18_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_18_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_19_DATA]\n    echo [format \"DENALI_CTL_19_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_19_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_20_DATA]\n    echo [format \"DENALI_CTL_20_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_20_DATA $tmp(1) $tmp(0)]\n\n}\n\nproc initC100 {} {\n    # this follows u-boot/cpu/arm1136/start.S\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL\t            [regs GPIO_IOCTRL_VAL]\n    set APB_ACCESS_WS_REG           [regs APB_ACCESS_WS_REG]\n    set ASA_ARAM_BASEADDR\t    [regs ASA_ARAM_BASEADDR]\n    set ASA_ARAM_TC_CR_REG\t    [regs ASA_ARAM_TC_CR_REG]\n    set ASA_EBUS_BASEADDR\t    [regs ASA_EBUS_BASEADDR]\n    set ASA_EBUS_TC_CR_REG\t    [regs ASA_EBUS_TC_CR_REG]\n    set ASA_TC_REQIDMAEN\t    [regs ASA_TC_REQIDMAEN]\n    set ASA_TC_REQTDMEN\t            [regs ASA_TC_REQTDMEN]\n    set ASA_TC_REQIPSECUSBEN        [regs ASA_TC_REQIPSECUSBEN]\n    set ASA_TC_REQARM0EN\t    [regs ASA_TC_REQARM0EN]\n    set ASA_TC_REQARM1EN\t    [regs ASA_TC_REQARM1EN]\n    set ASA_TC_REQMDMAEN\t    [regs ASA_TC_REQMDMAEN]\n    set INTC_ARM1_CONTROL_REG       [regs INTC_ARM1_CONTROL_REG]\n\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable address lines A15-A21\n    mmw $GPIO_IOCTRL_REG 0xf 0x0\n    # set ARM into supervisor mode (SVC32)\n    # disable IRQ, FIQ\n    # Do I need this in JTAG mode?\n    # it really should be done as 'and ~0x1f | 0xd3 but\n    # openocd does not support this yet\n    reg cpsr 0xd3\n    #\t/*\n    #\t * flush v4 I/D caches\n    #\t */\n    #\tmov\tr0, #0\n    #\tmcr\tp15, 0, r0, c7, c7, 0\t/* flush v3/v4 cache */\n    arm mcr 15 0 7 7 0 0x0\n    #\tmcr\tp15, 0, r0, c8, c7, 0\t/* flush v4 TLB */\n    arm mcr 15 0 8 7 0 0x0\n\n    #\t/*\n    #\t * disable MMU stuff and caches\n    #\t */\n    #\tmrc\tp15, 0, r0, c1, c0, 0\n    arm mrc 15 0 1 0 0\n    #\tbic\tr0, r0, #0x00002300\t@ clear bits 13, 9:8 (--V- --RS)\n    #\tbic\tr0, r0, #0x00000087\t@ clear bits 7, 2:0 (B--- -CAM)\n    #\torr\tr0, r0, #0x00000002\t@ set bit 2 (A) Align\n    #\torr\tr0, r0, #0x00001000\t@ set bit 12 (I) I-Cache\n    #\torr\tr0, r0, #0x00400000\t@ set bit 22 (U)\n    #\tmcr\tp15, 0, r0, c1, c0, 0\n    arm mcr 15 0 1 0 0 0x401002\n    # This is from bsp_init() in u-boot/boards/mindspeed/ooma-darwin/board.c\n    # APB init\n    #    \t// Setting APB Bus Wait states to 1, set post write\n    #\t(*(volatile u32*)(APB_ACCESS_WS_REG)) = 0x40;\n    mww $APB_ACCESS_WS_REG 0x40\n    # AHB init\n    #\t// enable all 6 masters for ARAM\n    mmw $ASA_ARAM_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n    #\t// enable all 6 masters for EBUS\n    mmw $ASA_EBUS_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n\n    # ARAM init\n    #\t// disable pipeline mode in ARAM\n    # I don't think this is documented anywhere?\n    mww $INTC_ARM1_CONTROL_REG 0x1\n    # configure clocks\n    setupPLL\n    # setupUART0 must be run before setupDDR2 as setupDDR2 uses UART.\n    setupUART0\n    # enable cache\n    # ? (u-boot does nothing here)\n    # DDR2 memory init\n    setupDDR2\n    putsUART0 \"C100 initialization complete.\\n\"\n    echo \"C100 initialization complete.\"\n}\n\n# show current state of watchdog timer\nproc showWatchdog {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    echo [format \"TIMER_WDT_HIGH_BOUND    (0x%x): 0x%x\" $TIMER_WDT_HIGH_BOUND [mrw $TIMER_WDT_HIGH_BOUND]]\n    echo [format \"TIMER_WDT_CONTROL       (0x%x): 0x%x\" $TIMER_WDT_CONTROL [mrw $TIMER_WDT_CONTROL]]\n    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/intrrupts.c:void reset_cpu (ulong ignored)\n# this will trigger watchdog reset\n# the sw. reset does not work on C100\n# watchdog reset effectively works as hw. reset\nproc reboot {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    # allow the counter to count to high value  before triggering\n    # this is because register writes are slow over JTAG and\n    # I don't want to miss the high_bound==curr_count condition\n    mww $TIMER_WDT_HIGH_BOUND  0xffffff\n    mww $TIMER_WDT_CURRENT_COUNT 0x0\n    echo \"JTAG speed lowered to 100kHz\"\n    adapter speed 100\n    mww $TIMER_WDT_CONTROL 0x1\n    # wait until the reset\n    echo -n \"Waiting for watchdog to trigger...\"\n    #while {[mrw $TIMER_WDT_CONTROL] == 1} {\n    #    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n    #    sleep 1\n    #\n    #}\n    while {[c100.cpu curstate] != \"running\"} { sleep 1}\n    echo \"done.\"\n    echo [format \"Note that C100 is in %s state, type halt to stop\" [c100.cpu curstate]]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/c100regs.tcl",
    "content": "# Note that I basically converted\n# u-boot/include/asm-arm/arch/comcerto_100.h\n# defines\n\n# this is a work-around for 'global' not working under Linux\n# access registers by calling this routine.\n# For example:\n# set EX_CS_TMG1_REG [regs EX_CS0_TMG1_REG]\nproc regs {reg} {\n    return [dict get [regsC100] $reg ]\n}\n\nproc showreg {reg} {\n    echo [format \"0x%x\" [dict get [regsC100] $reg ]]\n}\n\nproc regsC100 {} {\n#/* memcore */\n#/* device memory base addresses */\n#// device memory sizes\n#/* ARAM SIZE=64K */\ndict set regsC100 ARAM_SIZE\t\t0x00010000\ndict set regsC100 ARAM_BASEADDR\t0x0A000000\n\n#/* Hardware Interface Units */\ndict set regsC100 APB_BASEADDR\t0x10000000\n#/* APB_SIZE=16M address range */\ndict set regsC100 APB_SIZE\t\t0x01000000\n\ndict set regsC100 EXP_CS0_BASEADDR       0x20000000\ndict set regsC100 EXP_CS1_BASEADDR       0x24000000\ndict set regsC100 EXP_CS2_BASEADDR       0x28000000\ndict set regsC100 EXP_CS3_BASEADDR       0x2C000000\ndict set regsC100 EXP_CS4_BASEADDR       0x30000000\n\ndict set regsC100 DDR_BASEADDR           0x80000000\n\ndict set regsC100 TDM_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x000000}]\ndict set regsC100 PHI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x010000}]\ndict set regsC100 TDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x020000}]\ndict set regsC100 ASA_DDR_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x040000}]\ndict set regsC100 ASA_ARAM_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x048000}]\ndict set regsC100 TIMER_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x050000}]\ndict set regsC100 ASD_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x060000}]\ndict set regsC100 GPIO_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x070000}]\ndict set regsC100 UART0_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x090000}]\ndict set regsC100 UART1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x094000}]\ndict set regsC100 SPI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x098000}]\ndict set regsC100 I2C_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x09C000}]\ndict set regsC100 INTC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0A0000}]\ndict set regsC100 CLKCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 PUI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 GEMAC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0D0000}]\ndict set regsC100 IDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0E0000}]\ndict set regsC100 MEMCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0F0000}]\ndict set regsC100 ASA_EBUS_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x100000}]\ndict set regsC100 ASA_AAB_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x108000}]\ndict set regsC100 GEMAC1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x190000}]\ndict set regsC100 EBUS_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1A0000}]\ndict set regsC100 MDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1E0000}]\n\n\n#////////////////////////////////////////////////////////////\n#//\tAHB block\t\t\t\t\t\t\t\t\t\t\t    //\n#////////////////////////////////////////////////////////////\ndict set regsC100 ASA_ARAM_PRI_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_ARAM_TC_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_ARAM_TC_CR_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_ARAM_STAT_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x0C}]\n\ndict set regsC100 ASA_EBUS_PRI_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_EBUS_TC_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_EBUS_TC_CR_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_EBUS_STAT_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x0C}]\n\ndict set regsC100 IDMA_MASTER\t\t0\ndict set regsC100 TDMA_MASTER\t\t1\ndict set regsC100 USBIPSEC_MASTER\t2\ndict set regsC100 ARM0_MASTER\t\t3\ndict set regsC100 ARM1_MASTER\t\t4\ndict set regsC100 MDMA_MASTER\t\t5\n\n#define IDMA_PRIORITY(level) (level)\n#define TDM_PRIORITY(level) (level << 4)\n#define USBIPSEC_PRIORITY(level) (level << 8)\n#define ARM0_PRIORITY(level) (level << 12)\n#define ARM1_PRIORITY(level) (level << 16)\n#define MDMA_PRIORITY(level) (level << 20)\n\ndict set regsC100 ASA_TC_REQIDMAEN\t [expr {1<<18}]\ndict set regsC100 ASA_TC_REQTDMEN\t [expr {1<<19}]\ndict set regsC100 ASA_TC_REQIPSECUSBEN [expr {1<<20}]\ndict set regsC100 ASA_TC_REQARM0EN\t [expr {1<<21}]\ndict set regsC100 ASA_TC_REQARM1EN\t [expr {1<<22}]\ndict set regsC100 ASA_TC_REQMDMAEN\t [expr {1<<23}]\n\ndict set regsC100 MEMORY_BASE_ADDR\t0x80000000\ndict set regsC100 MEMORY_MAX_ADDR\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x10}]\ndict set regsC100 MEMORY_CR \t\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x14}]\ndict set regsC100 ROM_REMAP_EN\t0x1\n\n#define HAL_asb_priority(level) \\\n#*(volatile unsigned *)ASA_PRI_REG = level\n\n#define HAL_aram_priority(level) \\\n#*(volatile unsigned *)ASA_ARAM_PRI_REG = level\n\n#define HAL_aram_arbitration(arbitration_mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG |= arbitration_mask\n\n#define HAL_aram_defmaster(mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG = (*(volatile unsigned *)ASA_TC_CR_REG & 0xFFFF) | (mask << 24)\n\n#////////////////////////////////////////////////////////////\n#// INTC block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 INTC_ARM1_CONTROL_REG\t[expr {[dict get $regsC100 INTC_BASEADDR ] + 0x18}]\n\n#////////////////////////////////////////////////////////////\n#// TIMER block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 TIMER0_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x00}]\ndict set regsC100 TIMER0_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x04}]\ndict set regsC100 TIMER1_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x08}]\ndict set regsC100 TIMER1_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x0C}]\n\ndict set regsC100 TIMER2_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x18}]\ndict set regsC100 TIMER2_LBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x10}]\ndict set regsC100 TIMER2_HBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x14}]\ndict set regsC100 TIMER2_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x1C}]\n\ndict set regsC100 TIMER3_LOBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x20}]\ndict set regsC100 TIMER3_HIBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x24}]\ndict set regsC100 TIMER3_CTRL\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x28}]\ndict set regsC100 TIMER3_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x2C}]\n\ndict set regsC100 TIMER_MASK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x40}]\ndict set regsC100 TIMER_STATUS\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_ACK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_WDT_HIGH_BOUND [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD0}]\ndict set regsC100 TIMER_WDT_CONTROL\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD4}]\ndict set regsC100 TIMER_WDT_CURRENT_COUNT [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD8}]\n\n\n\n#////////////////////////////////////////////////////////////\n#//  EBUS block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 EX_SWRST_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 EX_CSEN_REG\t\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 EX_CS0_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 EX_CS1_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x0C}]\ndict set regsC100 EX_CS2_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x10}]\ndict set regsC100 EX_CS3_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x14}]\ndict set regsC100 EX_CS4_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x18}]\ndict set regsC100 EX_CS0_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x1C}]\ndict set regsC100 EX_CS1_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x20}]\ndict set regsC100 EX_CS2_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x24}]\ndict set regsC100 EX_CS3_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x28}]\ndict set regsC100 EX_CS4_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x2C}]\ndict set regsC100 EX_CS0_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x30}]\ndict set regsC100 EX_CS1_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x34}]\ndict set regsC100 EX_CS2_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x38}]\ndict set regsC100 EX_CS3_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x3C}]\ndict set regsC100 EX_CS4_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x40}]\ndict set regsC100 EX_CS0_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x44}]\ndict set regsC100 EX_CS1_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x48}]\ndict set regsC100 EX_CS2_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x4C}]\ndict set regsC100 EX_CS3_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x50}]\ndict set regsC100 EX_CS4_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x54}]\ndict set regsC100 EX_CS0_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x58}]\ndict set regsC100 EX_CS1_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x5C}]\ndict set regsC100 EX_CS2_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x60}]\ndict set regsC100 EX_CS3_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x64}]\ndict set regsC100 EX_CS4_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x68}]\ndict set regsC100 EX_CLOCK_DIV_REG\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x6C}]\n\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_CSFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x104}]\ndict set regsC100 EX_WRFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x108}]\ndict set regsC100 EX_RDFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x10C}]\n\n\ndict set regsC100 EX_CLK_EN\t\t0x00000001\ndict set regsC100 EX_CSBOOT_EN\t0x00000002\ndict set regsC100 EX_CS0_EN\t\t0x00000002\ndict set regsC100 EX_CS1_EN\t\t0x00000004\ndict set regsC100 EX_CS2_EN\t\t0x00000008\ndict set regsC100 EX_CS3_EN\t\t0x00000010\ndict set regsC100 EX_CS4_EN\t\t0x00000020\n\ndict set regsC100 EX_MEM_BUS_8\t0x00000000\ndict set regsC100 EX_MEM_BUS_16       0x00000002\ndict set regsC100 EX_MEM_BUS_32\t0x00000004\ndict set regsC100 EX_CS_HIGH\t\t0x00000008\ndict set regsC100 EX_WE_HIGH\t\t0x00000010\ndict set regsC100 EX_RE_HIGH\t\t0x00000020\ndict set regsC100 EX_ALE_MODE\t\t0x00000040\ndict set regsC100 EX_STRB_MODE\t0x00000080\ndict set regsC100 EX_DM_MODE\t\t0x00000100\ndict set regsC100 EX_NAND_MODE\t0x00000200\ndict set regsC100 EX_RDY_EN\t\t0x00000400\ndict set regsC100 EX_RDY_EDGE\t\t0x00000800\n\n#////////////////////////////////////////////////////////////\n#//  GPIO block\n#////////////////////////////////////////////////////////////\n\n# GPIO outputs register\ndict set regsC100 GPIO_OUTPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x00}]\n# GPIO Output Enable register\ndict set regsC100 GPIO_OE_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x04}]\ndict set regsC100 GPIO_HI_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x08}]\ndict set regsC100 GPIO_LO_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x0C}]\n# GPIO input register\ndict set regsC100 GPIO_INPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x10}]\ndict set regsC100 APB_ACCESS_WS_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x14}]\ndict set regsC100 MUX_CONF_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x18}]\ndict set regsC100 SYSCONF_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x1C}]\ndict set regsC100 GPIO_ARM_ID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x30}]\ndict set regsC100 GPIO_BOOTSTRAP_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x40}]\ndict set regsC100 GPIO_LOCK_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x38}]\ndict set regsC100 GPIO_IOCTRL_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x44}]\ndict set regsC100 GPIO_DEVID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x50}]\n\ndict set regsC100 GPIO_IOCTRL_A15A16\t0x00000001\ndict set regsC100 GPIO_IOCTRL_A17A18\t0x00000002\ndict set regsC100 GPIO_IOCTRL_A19A21\t0x00000004\ndict set regsC100 GPIO_IOCTRL_TMREVT0\t0x00000008\ndict set regsC100 GPIO_IOCTRL_TMREVT1\t0x00000010\ndict set regsC100 GPIO_IOCTRL_GPBT3\t0x00000020\ndict set regsC100 GPIO_IOCTRL_I2C\t0x00000040\ndict set regsC100 GPIO_IOCTRL_UART0\t0x00000080\ndict set regsC100 GPIO_IOCTRL_UART1\t0x00000100\ndict set regsC100 GPIO_IOCTRL_SPI\t0x00000200\ndict set regsC100 GPIO_IOCTRL_HBMODE\t0x00000400\n\ndict set regsC100 GPIO_IOCTRL_VAL\t0x55555555\n\ndict set regsC100 GPIO_0\t\t\t0x01\ndict set regsC100 GPIO_1\t\t\t0x02\ndict set regsC100 GPIO_2\t\t\t0x04\ndict set regsC100 GPIO_3\t\t\t0x08\ndict set regsC100 GPIO_4\t\t\t0x10\ndict set regsC100 GPIO_5\t\t\t0x20\ndict set regsC100 GPIO_6\t\t\t0x40\ndict set regsC100 GPIO_7\t\t\t0x80\n\ndict set regsC100 GPIO_RISING_EDGE\t1\ndict set regsC100 GPIO_FALLING_EDGE\t2\ndict set regsC100 GPIO_BOTH_EDGES\t3\n\n#////////////////////////////////////////////////////////////\n#// UART\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 UART0_RBR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_THR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_DLL\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_IER\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_DLH\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_IIR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_FCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_LCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x0C}]\ndict set regsC100 UART0_MCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x10}]\ndict set regsC100 UART0_LSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x14}]\ndict set regsC100 UART0_MSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x18}]\ndict set regsC100 UART0_SCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x1C}]\n\ndict set regsC100 UART1_RBR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_THR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_DLL\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_IER\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_DLH\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_IIR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_FCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_LCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x0C}]\ndict set regsC100 UART1_MCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x10}]\ndict set regsC100 UART1_LSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x14}]\ndict set regsC100 UART1_MSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x18}]\ndict set regsC100 UART1_SCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x1C}]\n\n# /* default */\ndict set regsC100 LCR_CHAR_LEN_5\t\t0x00\ndict set regsC100 LCR_CHAR_LEN_6\t\t0x01\ndict set regsC100 LCR_CHAR_LEN_7\t\t0x02\ndict set regsC100 LCR_CHAR_LEN_8\t\t0x03\n#/* One stop bit! - default */\ndict set regsC100 LCR_ONE_STOP\t\t0x00\n#/* Two stop bit! */\ndict set regsC100 LCR_TWO_STOP\t\t0x04\n#/* Parity Enable */\ndict set regsC100 LCR_PEN\t\t\t0x08\ndict set regsC100 LCR_PARITY_NONE\t\t0x00\n#/* Even Parity Select */\ndict set regsC100 LCR_EPS\t\t\t0x10\n#/* Enable Parity  Stuff */\ndict set regsC100 LCR_PS\t\t\t0x20\n#/* Start Break */\ndict set regsC100 LCR_SBRK\t\t        0x40\n#/* Parity Stuff Bit */\ndict set regsC100 LCR_PSB\t\t\t0x80\n#/* UART 16550 Divisor Latch Assess */\ndict set regsC100 LCR_DLAB\t\t        0x80\n\n#/* FIFO Error Status */\ndict set regsC100 LSR_FIFOE\t\t[expr {1 << 7}]\n#/* Transmitter Empty */\ndict set regsC100 LSR_TEMT\t\t[expr {1 << 6}]\n#/* Transmit Data Request */\ndict set regsC100 LSR_TDRQ\t\t[expr {1 << 5}]\n#/* Break Interrupt */\ndict set regsC100 LSR_BI\t\t\t[expr {1 << 4}]\n#/* Framing Error */\ndict set regsC100 LSR_FE\t\t\t[expr {1 << 3}]\n#/* Parity Error */\ndict set regsC100 LSR_PE\t\t\t[expr {1 << 2}]\n#/* Overrun Error */\ndict set regsC100 LSR_OE\t\t\t[expr {1 << 1}]\n#/* Data Ready */\ndict set regsC100 LSR_DR\t\t\t[expr {1 << 0}]\n\n#/* DMA Requests Enable */\ndict set regsC100 IER_DMAE\t\t        [expr {1 << 7}]\n#/* UART Unit Enable */\ndict set regsC100 IER_UUE\t\t\t[expr {1 << 6}]\n#/* NRZ coding Enable */\ndict set regsC100 IER_NRZE\t\t        [expr {1 << 5}]\n#/* Receiver Time Out Interrupt Enable */\ndict set regsC100 IER_RTIOE\t\t        [expr {1 << 4}]\n#/* Modem Interrupt Enable */\ndict set regsC100 IER_MIE\t\t\t[expr {1 << 3}]\n#/* Receiver Line Status Interrupt Enable */\ndict set regsC100 IER_RLSE\t\t        [expr {1 << 2}]\n#/* Transmit Data request Interrupt Enable */\ndict set regsC100 IER_TIE\t\t\t[expr {1 << 1}]\n#/* Receiver Data Available Interrupt Enable */\ndict set regsC100 IER_RAVIE\t\t        [expr {1 << 0}]\n\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES1\t\t        [expr {1 << 7}]\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES0\t\t        [expr {1 << 6}]\n#/* Time Out Detected */\ndict set regsC100 IIR_TOD\t\t\t[expr {1 << 3}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID2\t\t        [expr {1 << 2}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID1\t\t        [expr {1 << 1}]\n#/* Interrupt Pending (active low) */\ndict set regsC100 IIR_IP\t\t\t[expr {1 << 0}]\n\n#/* UART 16550 FIFO Control Register */\ndict set regsC100 FCR_FIFOEN\t\t0x01\ndict set regsC100 FCR_RCVRRES\t\t0x02\ndict set regsC100 FCR_XMITRES\t\t0x04\n\n#/* Interrupt Enable Register */\n#// UART 16550\n#// Enable Received Data Available Interrupt\ndict set regsC100 IER_RXTH\t\t0x01\n#// Enable Transmitter Empty Interrupt\ndict set regsC100 IER_TXTH\t\t0x02\n\n\n\n#////////////////////////////////////////////////////////////\n#// CLK  + RESET block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x00}]\ndict set regsC100 CLKCORE_AHB_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x04}]\ndict set regsC100 CLKCORE_PLL_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x08}]\ndict set regsC100 CLKCORE_CLKDIV_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x0C}]\ndict set regsC100 CLKCORE_TDM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x10}]\ndict set regsC100 CLKCORE_FSYNC_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x14}]\ndict set regsC100 CLKCORE_CLK_PWR_DWN\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x18}]\ndict set regsC100 CLKCORE_RNG_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x1C}]\ndict set regsC100 CLKCORE_RNG_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x20}]\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL2\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x24}]\ndict set regsC100 CLKCORE_TDM_REF_DIV_RST\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x40}]\n\ndict set regsC100 ARM_PLL_BY_CTRL\t0x80000000\ndict set regsC100 ARM_AHB_BYP\t\t0x04000000\ndict set regsC100 PLL_DISABLE\t\t0x02000000\ndict set regsC100 PLL_CLK_BYPASS\t0x01000000\n\ndict set regsC100 AHB_PLL_BY_CTRL\t0x80000000\ndict set regsC100 DIV_BYPASS\t\t0x40000000\ndict set regsC100 SYNC_MODE\t\t0x20000000\n\ndict set regsC100 EPHY_CLKDIV_BYPASS\t0x00200000\ndict set regsC100 EPHY_CLKDIV_RATIO_SHIFT\t16\ndict set regsC100 PUI_CLKDIV_BYPASS\t0x00004000\ndict set regsC100 PUI_CLKDIV_SRCCLK\t0x00002000\ndict set regsC100 PUI_CLKDIV_RATIO_SHIFT\t8\ndict set regsC100 PCI_CLKDIV_BYPASS\t0x00000020\ndict set regsC100 PCI_CLKDIV_RATIO_SHIFT\t0\n\ndict set regsC100 ARM0_CLK_PD\t\t0x00200000\ndict set regsC100 ARM1_CLK_PD\t\t0x00100000\ndict set regsC100 EPHY_CLK_PD\t\t0x00080000\ndict set regsC100 TDM_CLK_PD\t\t0x00040000\ndict set regsC100 PUI_CLK_PD\t\t0x00020000\ndict set regsC100 PCI_CLK_PD\t\t0x00010000\ndict set regsC100 MDMA_AHBCLK_PD\t0x00000400\ndict set regsC100 I2CSPI_AHBCLK_PD\t0x00000200\ndict set regsC100 UART_AHBCLK_PD\t0x00000100\ndict set regsC100 IPSEC_AHBCLK_PD\t0x00000080\ndict set regsC100 TDM_AHBCLK_PD\t0x00000040\ndict set regsC100 USB1_AHBCLK_PD\t0x00000020\ndict set regsC100 USB0_AHBCLK_PD\t0x00000010\ndict set regsC100 GEMAC1_AHBCLK_PD\t0x00000008\ndict set regsC100 GEMAC0_AHBCLK_PD\t0x00000004\ndict set regsC100 PUI_AHBCLK_PD\t0x00000002\ndict set regsC100 HIF_AHBCLK_PD\t0x00000001\n\ndict set regsC100 ARM1_DIV_BP\t\t0x00001000\ndict set regsC100 ARM1_DIV_VAL_SHIFT\t8\ndict set regsC100 ARM0_DIV_BP\t\t0x00000010\ndict set regsC100 ARM0_DIV_VAL_SHIFT\t0\n\ndict set regsC100 AHBCLK_PLL_LOCK\t0x00000002\ndict set regsC100 FCLK_PLL_LOCK\t0x00000001\n\n\n#// reset block\ndict set regsC100 BLOCK_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x100}]\ndict set regsC100 CSP_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x104}]\n\ndict set regsC100 RNG_RST\t\t0x1000\ndict set regsC100 IPSEC_RST\t\t0x0800\ndict set regsC100 DDR_RST\t\t0x0400\ndict set regsC100 USB1_PHY_RST\t0x0200\ndict set regsC100 USB0_PHY_RST\t0x0100\ndict set regsC100 USB1_RST\t\t0x0080\ndict set regsC100 USB0_RST\t\t0x0040\ndict set regsC100 GEMAC1_RST\t\t0x0020\ndict set regsC100 GEMAC0_RST\t\t0x0010\ndict set regsC100 TDM_RST\t\t0x0008\ndict set regsC100 PUI_RST\t\t0x0004\ndict set regsC100 HIF_RST\t\t0x0002\ndict set regsC100 PCI_RST\t\t0x0001\n\n#////////////////////////////////////////////////////////////////\n#//\tDDR  CONTROLLER block\n#////////////////////////////////////////////////////////////////\n\ndict set regsC100 DDR_CONFIG_BASEADDR\t0x0D000000\ndict set regsC100 DENALI_CTL_00_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x00}]\ndict set regsC100 DENALI_CTL_01_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x08}]\ndict set regsC100 DENALI_CTL_02_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x10}]\ndict set regsC100 DENALI_CTL_03_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x18}]\ndict set regsC100 DENALI_CTL_04_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x20}]\ndict set regsC100 DENALI_CTL_05_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x28}]\ndict set regsC100 DENALI_CTL_06_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x30}]\ndict set regsC100 DENALI_CTL_07_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x38}]\ndict set regsC100 DENALI_CTL_08_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x40}]\ndict set regsC100 DENALI_CTL_09_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x48}]\ndict set regsC100 DENALI_CTL_10_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x50}]\ndict set regsC100 DENALI_CTL_11_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x58}]\ndict set regsC100 DENALI_CTL_12_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x60}]\ndict set regsC100 DENALI_CTL_13_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x68}]\ndict set regsC100 DENALI_CTL_14_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x70}]\ndict set regsC100 DENALI_CTL_15_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x78}]\ndict set regsC100 DENALI_CTL_16_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x80}]\ndict set regsC100 DENALI_CTL_17_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x88}]\ndict set regsC100 DENALI_CTL_18_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x90}]\ndict set regsC100 DENALI_CTL_19_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x98}]\ndict set regsC100 DENALI_CTL_20_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0xA0}]\n\n# 32-bit value\ndict set regsC100 DENALI_READY_CHECK         [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x44}]\n# 8-bit\ndict set regsC100 DENALI_WR_DQS              [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5D}]\n# 8-bit\ndict set regsC100 DENALI_DQS_OUT             [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5A}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY0          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x4F}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY1          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x50}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY2          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x51}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY3          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x52}]\n\n\n# end of proc regsC100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/cc2538.cfg",
    "content": "# Config for Texas Instruments low power RF SoC CC2538\n# http://www.ti.com/lit/pdf/swru319\n\nadapter speed 100\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc2538\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n# A start sequence is needed to change from cJTAG (Compact JTAG) to\n# 4-pin JTAG before talking via JTAG commands\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/cs351x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME cs351x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00526fa1\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# There is 16K of SRAM on this chip\n# FIXME: flash programming is not working by using this work area. So comment this out for now.\n#$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/davinci.cfg",
    "content": "#\n# Utility code for DaVinci-family chips\n#\n\n# davinci_pinmux: assigns PINMUX$reg <== $value\nproc davinci_pinmux {soc reg value} {\n\tmww [expr {[dict get $soc sysbase] + 4 * $reg}] $value\n}\n\nsource [find mem_helper.tcl]\n\n#\n# pll_setup: initialize PLL\n#  - pll_addr ... physical addr of controller\n#  - mult ... pll multiplier\n#  - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers\n#\n# For PLLs that don't have a given register (e.g. plldiv8), or where a\n# given divider is non-programmable, caller provides *NO* config mapping.\n#\n\n# PLL version 0x02: tested on dm355\n# REVISIT: On dm6446/dm357 the PLLRST polarity is different.\nproc pll_v02_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - clear CLKMODE (bit 8) iff using on-chip oscillator\n\t# NOTE: this assumes we should clear that bit\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0100}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 4 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 5 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 6 - set PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 7 - clear PLLPWRDN (bit 1)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 8 - clear PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\t# NOTE: for dm355 PLL1, postdiv is controlled via MISC register\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult - 1) & 0xff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - optional: set plldiv1, plldiv2, ...\n\t# NOTE:  this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\t#\t- ALNCTL has everything set\n\tset go 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset go 1\n\t}\n\tif {$go != 0} {\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\n\t# 11 - wait at least 5 usec for reset to finish\n\t# (assume covered by overheads including JTAG messaging)\n\n\t# 12 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 13 - wait at least 8000 refclk cycles for PLL to lock\n\t# if we assume 24 MHz (slowest osc), that's 1/3 msec\n\tsleep 3\n\n\t# 14 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# PLL version 0x03: tested on dm365\nproc pll_v03_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_secctrl_addr [expr {$pll_addr + 0x108}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - power up the PLL\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 4 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 5 - wait at least 5 usec\n\tsleep 1\n\n\t# 6 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult / 2) & 0x1ff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - write start sequence to PLLSECCTL\n\tmww $pll_secctrl_addr 0x00470000\n\tmww $pll_secctrl_addr 0x00460000\n\tmww $pll_secctrl_addr 0x00400000\n\tmww $pll_secctrl_addr 0x00410000\n\n\t# 11 - optional: set plldiv1, plldiv2, ...\n\t# NOTE: this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\tset aln 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset aln [expr {$aln | 0x1}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0118}] 0\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset aln [expr {$aln | 0x2}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x011c}] 0\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset aln [expr {$aln | 0x4}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0120}] 0\n\t}\n\tif { [dict exists $config oscdiv] } {\n\t\tset div [dict get $config oscdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0124}] $div\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0124}] 0\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset aln [expr {$aln | 0x8}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0160}] 0\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset aln [expr {$aln | 0x10}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0164}] 0\n\t}\n\tif { [dict exists $config div6] } {\n\t\tset div [dict get $config div6]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0168}] $div\n\t\tset aln [expr {$aln | 0x20}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0168}] 0\n\t}\n\tif { [dict exists $config div7] } {\n\t\tset div [dict get $config div7]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x016c}] $div\n\t\tset aln [expr {$aln | 0x40}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x016c}] 0\n\t}\n\tif { [dict exists $config div8] } {\n\t\tset div [dict get $config div8]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0170}] $div\n\t\tset aln [expr {$aln | 0x80}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0170}] 0\n\t}\n\tif { [dict exists $config div9] } {\n\t\tset div [dict get $config div9]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0174}] $div\n\t\tset aln [expr {$aln | 0x100}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0174}] 0\n\t}\n\tif {$aln != 0} {\n\t\t# clear pllcmd.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x00\n\t\t# write alignment flags\n\t\tmww [expr {$pll_addr + 0x0140}] $aln\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\tset addr [dict get $config ctladdr]\n\twhile {[expr {[mrw $addr] & 0x0e000000}] != 0x0e000000} { sleep 1 }\n\n\t# 12 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain\n# modules can be enabled.\n\n# prepare a non-DSP module to be enabled; finish with psc_go\nproc psc_enable {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x03 0x1f\n}\n\n# prepare a non-DSP module to be reset; finish with psc_go\nproc psc_reset {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x01 0x1f\n}\n\n# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc\nproc psc_go {} {\n\tset psc_addr 0x01c41000\n\tset ptstat_addr [expr {$psc_addr + 0x0128}]\n\n\t# just in case PTSTAT.go isn't clear\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n\n\t# write PTCMD.go ... ignoring any DSP power domain\n\tmww [expr {$psc_addr + 0x0120}] 1\n\n\t# wait for PTSTAT.go to clear (again ignoring DSP power domain)\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n}\n\n#\n# A reset using only SRST is a \"Warm Reset\", resetting everything in the\n# chip except ARM emulation (and everything _outside_ the chip that hooks\n# up to SRST).  But many boards don't expose SRST via their JTAG connectors\n# (it's not present on TI-14 headers).\n#\n# From the chip-only perspective, a \"Max Reset\" is a \"Warm\" reset ... except\n# without any board-wide side effects, since it's triggered using JTAG using\n# either (a) ARM watchdog timer, or (b) ICEpick.\n#\nproc davinci_wdog_reset {} {\n\tset timer2_phys 0x01c21c00\n\n\t# NOTE -- on entry\n\t#   - JTAG communication with the ARM *must* be working OK; this\n\t#     may imply using adaptive clocking or disabling WFI-in-idle\n\t#   - current target must be the DaVinci ARM\n\t#   - that ARM core must be halted\n\t#   - timer2 clock is still enabled (PSC 29 on most chips)\n\n\t#\n\t# Part I -- run regardless of being halted via JTAG\n\t#\n\t# NOTE:  for now, we assume there's no DSP that could control the\n\t# watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog\n\t# suspend signal is controlled via ARM emulation suspend.\n\t#\n\n\t# EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n\n\t#\n\t# Part II -- in case watchdog hasn't been set up\n\t#\n\n\t# TCR: disable, force internal clock source\n\tmww phys [expr {$timer2_phys + 0x20}] 0\n\n\t# TGCR: reset, force to 64-bit wdog mode, un-reset (\"initial\" state)\n\tmww phys [expr {$timer2_phys + 0x24}] 0\n\tmww phys [expr {$timer2_phys + 0x24}] 0x110b\n\n\t# clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers\n\t# so watchdog triggers ASAP\n\tmww phys [expr {$timer2_phys + 0x10}] 0\n\tmww phys [expr {$timer2_phys + 0x14}] 0\n\tmww phys [expr {$timer2_phys + 0x18}] 0\n\tmww phys [expr {$timer2_phys + 0x1c}] 0\n\n\t# WDTCR: put into pre-active state, then active\n\tmww phys [expr {$timer2_phys + 0x28}] 0xa5c64000\n\tmww phys [expr {$timer2_phys + 0x28}] 0xda7e4000\n\n\t#\n\t# Part III -- it's ready to rumble\n\t#\n\n\t# WDTCR: write invalid WDKEY to trigger reset\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/dragonite.cfg",
    "content": "######################################\n# Target:    Marvell Dragonite CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dragonite\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x121003d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/dsp56321.cfg",
    "content": "# Script for freescale DSP56321\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp56321\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1181501d\n}\n\n#jtag speed\nadapter speed 4500\n\n#has only srst\nreset_config srst_only\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/dsp568013.cfg",
    "content": "# Script for freescale DSP568013\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568013\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2401d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\n# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations require certain instruction to be in the IR register during reset, and polling would change this)\njtag configure $_CHIPNAME.chp -event setup \"\n     jtag tapenable $_TARGETNAME\n     poll off\n\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/dsp568037.cfg",
    "content": "# Script for freescale DSP568037\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568037\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2801d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\njtag configure $_CHIPNAME.chp -event setup \"jtag tapenable $_TARGETNAME\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/efm32.cfg",
    "content": "#\n# Silicon Labs (formerly Energy Micro) EFM32 target\n#\n# Note: All EFM32 chips have SWD support, but only newer series 1\n# chips have JTAG support.\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME efm32\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nadapter speed 1000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\nflash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\nflash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/em357.cfg",
    "content": "#\n# Target configuration for the Silicon Labs EM357 chips\n#\n\n#\n# em357 family supports JTAG and SWD transports\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em357\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } else {\n      set _CPUTAPID 0x1ba00477\n   }\n}\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n  set _BSTAPID 0x069a962b\n}\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em358\n}\n\nif { [info exists FLASHSIZE] } {\n    set _FLASHSIZE $FLASHSIZE\n} else {\n    set _FLASHSIZE 0x30000\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nif { [using_jtag] } {\n    jtag newtap $_CHIPNAME bs -irlen 4 -expected-id $_BSTAPID -ircapture 0xe -irmask 0xf\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME em357 0x08000000 $_FLASHSIZE 0 0 $_TARGETNAME\n\nif { ![using_hla]} {\n# according to errata, we need to use vectreset rather than sysresetreq to avoid lockup\n# There is a bug in the chip, which means that when using external debuggers the chip\n# may lock up in certain CPU clock modes. Affected modes are operating the CPU at\n# 24MHz derived from the 24MHz crystal, or 12MHz derived from the high frequency RC\n# oscillator. If an external debugger tool asserts SYSRESETREQ, the chip will lock up and\n# require a pin reset or power cycle.\n#\n# for details, refer to:\n# http://www.silabs.com/Support%20Documents/TechnicalDocs/EM35x-Errata.pdf\n    cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/em358.cfg",
    "content": "# Target configuration for the Silicon Labs EM358 chips\n\n#\n# em357 family supports JTAG and SWD transports\n#\n\nif { ![info exists CHIPNAME] } {\n   set CHIPNAME em358\n}\n\nif { ![info exists BSTAPID] } {\n  set BSTAPID 0x069aa62b\n}\n\n# 512K of flash in the em358 chips\nset FLASHSIZE 0x80000\nsource [find target/em357.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/eos_s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3\n# https://www.quicklogic.com/products/soc/eos-s3-microcontroller/\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME eos_s3\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x80000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# For now we use SRAM only for software upload\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 4000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/epc9301.cfg",
    "content": "# Cirrus Logic EP9301 processor on an Olimex CS-E9301 board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ep9301\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nadapter srst delay 100\njtag_ntrst_delay 100\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -work-area-phys 0x80014000 -work-area-size 0x1000 -work-area-backup 1\n\n#flash configuration\n#flash bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x60000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/esi32xx.cfg",
    "content": "#\n# EnSilica eSi-32xx SoC (eSi-RISC Family)\n# http://www.ensilica.com/risc-ip/\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME esi32xx\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x11234001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME esirisc -chain-position $_CHIPNAME.cpu\n\n# Targets with the UNIFIED_ADDRESS_SPACE option disabled should set\n# CACHEARCH to 'harvard'. By default, 'von_neumann' is assumed.\nif { [info exists CACHEARCH] } {\n    $_TARGETNAME esirisc cache_arch $CACHEARCH\n}\n\nadapter speed 2000\n\nreset_config none\n\n# The default linker scripts provided by the eSi-RISC toolchain do not\n# specify attributes on memory regions, which results in incorrect\n# application of software breakpoints by GDB.\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/esp32s2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The ESP32-S2 only supports JTAG.\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME esp32s2\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x120034e5\n}\n\nset _TARGETNAME $_CHIPNAME\nset _CPUNAME cpu\nset _TAPNAME $_CHIPNAME.$_CPUNAME\n\njtag newtap $_CHIPNAME $_CPUNAME -irlen 5 -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME esp32s2 -endian little -chain-position $_TAPNAME\n\nxtensa maskisr on\n\n$_TARGETNAME configure -event reset-assert-post { soft_reset_halt }\n\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/exynos5250.cfg",
    "content": "#\n# Samsung Exynos 5250 - dual-core ARM Cortex-A15\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME exynos5250\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap\n\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/faux.cfg",
    "content": "#Script for faux target - used for testing\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00000000\n}\n\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#dummy flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME faux 0x01000000 0x200000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/feroceon.cfg",
    "content": "######################################\n# Target:    Marvell Feroceon CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME feroceon\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x20a023d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/fm3.cfg",
    "content": "# MB9BF506\n# Fujitsu Cortex-M3 with 512kB Flash and 64kB RAM\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME mb9bfxx6\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\n# delays on reset lines\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\n# Fujitsu Cortex-M3 reset configuration\nreset_config trst_only\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# MB9BF506 has 64kB of SRAM on its main system bus\n$_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0\n\n# MB9BF506 has 512kB internal FLASH\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n# 4MHz / 6 = 666kHz, so use 500\nadapter speed 500\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/fm4.cfg",
    "content": "#\n# Spansion FM4 (ARM Cortex-M4)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME fm4\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} elseif { [using_jtag] } {\n\tset _CPU_TAPID 0x4ba00477\n} else {\n\tset _CPU_TAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nadapter speed 500\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/fm4_mb9bf.cfg",
    "content": "#\n# Spansion FM4 MB9BFxxx (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# MB9BF566 M/N/R have 32 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x8000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/fm4_s6e2cc.cfg",
    "content": "#\n# Spansion FM4 S6E2CC (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# S6E2CC8 H/J/L have 96 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x18000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\nflash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/gd32e23x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for GigaDevice gd32e23x Cortex-M23 Series\n\n# https://www.gigadevice.com/microcontroller/gd32e230c8t6/\n\n#\n# gd32e23x devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32e23x\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some GD32E230s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # this is the SW-DP tap id not the jtag tap id\n   set _CPUTAPID 0x0bf11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# SWD speed (may be updated to higher value in board config file)\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Debug clock enable\n\t# RCU_APB2EN |= DBGMCUEN\n\tmmw 0x40021018 0x00400000 0\n\n\t# Stop watchdog counters during halt\n\t# DBG_CTL0 |= WWDGT_HOLD | FWDGT_HOLD | STB_HOLD | DSLP_HOLD | SLP_HOLD\n\tmmw 0x40015804 0x00000307 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/gd32vf103.cfg",
    "content": "#\n# GigaDevice GD32VF103 target\n#\n# https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/\n#\n\nsource [find mem_helper.tcl]\n\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32vf103\n}\n\n# The smallest RAM size 6kB (GD32VF103C4/T4/R4)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1800\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME\n\n# DBGMCU_CR register cannot be set in examine-end event as the running RISC-V CPU\n# does not allow the debugger to access memory.\n# Stop watchdogs at least before flash programming.\n$_TARGETNAME configure -event reset-init {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP\n\tmmw 0xE0042004 0x00000300 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/gp326xxxa.cfg",
    "content": "#\n# Support for General Plus GP326XXXA chips\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gp326xxxa\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Use internal SRAM as a work area\n$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0\n\n# The chip has both lines connected together\nreset_config trst_and_srst srst_pulls_trst\n# This delay is needed otherwise communication with the target would\n# be unreliable\nadapter srst delay 100\n\n# Set the adapter speed ridiculously low just in case we are\n# running off of a 32kHz clock\nadapter speed 2\n\nproc gp32xxxa_halt_and_reset_control_registers {} {\n\t# System control registers\n\tset P_SYSTEM_CTRL_NEW       0xD0000008\n\tset P_SYSTEM_CTRL           0xD000000C\n\tset P_SYSTEM_CLK_EN0        0xD0000010\n\tset P_SYSTEM_CLK_EN1        0xD0000014\n\tset P_SYSTEM_RESET_FLAG     0xD0000018\n\tset P_SYSTEM_CLK_CTRL       0xD000001C\n\tset P_SYSTEM_LVR_CTRL       0xD0000020\n\tset P_SYSTEM_WATCHDOG_CTRL  0xD0000024\n\tset P_SYSTEM_PLLEN          0xD000005C\n\n\t# Since we can't use SRST without pulling TRST\n\t# we can't assume the state of the clock configuration\n\t# or watchdog settings. So reset them before porceeding\n\n\t# Set the adapter speed ridiculously low just in case we are\n\t# running off of a 32kHz clock\n\tadapter speed 2\n\n\t# Disable any advanced features at this stage\n\tarm7_9 dcc_downloads disable\n\tarm7_9 fast_memory_access disable\n\n\t# Do a \"soft reset\"\n\tsoft_reset_halt\n\t# Reset all system control registers to their default \"after-reset\" values\n\tmwh $P_SYSTEM_WATCHDOG_CTRL  0x0000\n\tmwh $P_SYSTEM_LVR_CTRL       0x0000\n\n\tmwh $P_SYSTEM_CTRL_NEW       0x0001\n\tmwh $P_SYSTEM_CTRL           0x0001\n\t# Clear all reset flags by writing 1's\n\tmwh $P_SYSTEM_RESET_FLAG     0x001C\n\n\tmwh $P_SYSTEM_CLK_CTRL       0x8000\n\tmwh $P_SYSTEM_CLK_EN0        0xFFFF\n\tmwh $P_SYSTEM_CLK_EN1        0xFFFF\n\tmwh $P_SYSTEM_PLLEN          0x0010\n\n\t# Unfortunately there's no register that would allow us to\n\t# know if PLL is locked. So just wait for 100ms in hopes that\n\t# it would be enough.\n\tsleep 100\n\n\t# Now that we know that we are running at 48Mhz\n\t# Increase JTAG speed and enable speed optimization features\n\tadapter speed 5000\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/hi3798.cfg",
    "content": "# Hisilicon Hi3798 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi3798\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80020000\nset $_TARGETNAME.cti(1) 0x80120000\nset $_TARGETNAME.cti(2) 0x80220000\nset $_TARGETNAME.cti(3) 0x80320000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        #set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/hi6220.cfg",
    "content": "# Hisilicon Hi6220 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi6220\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n# declare the 8 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80198000\nset $_TARGETNAME.cti(1) 0x80199000\nset $_TARGETNAME.cti(2) 0x8019A000\nset $_TARGETNAME.cti(3) 0x8019B000\nset $_TARGETNAME.cti(4) 0x801D8000\nset $_TARGETNAME.cti(5) 0x801D9000\nset $_TARGETNAME.cti(6) 0x801DA000\nset $_TARGETNAME.cti(7) 0x801DB000\n\nset _cores 8\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ncti create cti.sys -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0x80003000\n\n# declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\n# declare the auxiliary Cortex-A7 core\ntarget create ${_TARGETNAME}.a7 cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80210000 -defer-examine\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/hilscher_netx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 10 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx10\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/hilscher_netx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 50 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx50\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# On netX50 SDRAM is not accessible at offset 0xDEAD0-0xDEADF as it is busy from\n# DMA controller at init. This function will setup a dummy DMA to free this ares\n# and must be called before using SDRAM\nproc sdram_fix { } {\n\n  mww 0x1c005830 0x00000001\n\n  mww 0x1c005104 0xBFFFFFFC\n  mww 0x1c00510c 0x00480001\n  mww 0x1c005110 0x00000001\n\n  sleep 100\n\n  mww 0x1c00510c 0\n  mww 0x1c005110 0\n  mww 0x1c005830 0x00000000\n\n\tputs \"SDRAM Fix executed!\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/hilscher_netx500.cfg",
    "content": "#Hilscher netX 500 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx500\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\n# This function must be called on netX100/500 right after halt\n# If it is called later the needed register cannot be written anymore\nproc sdram_fix { } {\n\n  set accesskey [mread32 0x00100070]\n  mww 0x00100070 $accesskey\n  mww 0x0010002c 0x00000001\n\n  if {[expr {[mread32 0x0010002c] & 0x07}] == 0x07} {\n\t puts \"SDRAM Fix was not executed. Probably your CPU halted too late and the register is already locked!\"\n  } else {\n\t puts \"SDRAM Fix succeeded!\"\n  }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/icepick.cfg",
    "content": "#\n# Copyright (C)   2011        by Karl Kurbjun\n# Copyright (C)   2009        by David Brownell\n#\n\n# Utilities for TI ICEpick-C/D used in most TI SoCs\n# Details about the ICEPick are available in the the TRM for each SoC\n# and http://processors.wiki.ti.com/index.php/ICEPICK\n\n# create \"constants\"\nproc CONST { key } {\n\n\tarray set constant {\n\t\t# define ICEPick instructions\n\t\tIR_BYPASS   0x00\n\t\tIR_ROUTER   0x02\n\t\tIR_CONNECT  0x07\n\t\tIF_BYPASS   0x3F\n\t}\n\treturn $constant($key)\n}\n\n# Instruction to connect to the icepick module\nproc icepick_c_connect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x89 -endstate DRPAUSE\n}\n\n# Instruction to disconnect to the icepick module\nproc icepick_c_disconnect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x86 -endstate DRPAUSE\n}\n\n#\n# icepick_c_router:\n#  this function is for sending router commands\n# arguments are:\n#  jrc:        TAP name for the ICEpick\n#  rw:         read/write (0 for read, 1 for write)\n#  block:      icepick or DAP\n#  register:   which register to read/write\n#  payload:    value to read/write\n# this function is for sending router commands\n#\nproc icepick_c_router {jrc rw block register payload} {\n\n\tset new_dr_value \\\n\t\t[expr { ( ($rw & 0x1) << 31)        | ( ($block & 0x7) << 28) | \\\n\t\t\t\t( ($register & 0xF) << 24)  | ( $payload & 0xFFFFFF ) } ]\n\n#\techo \"\\tNew router value:\\t0x[format %x $new_dr_value]\"\n\n\t# select router\n\tirscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE\n\n\t# ROUTER instructions are 32 bits wide\n\tset old_dr_value 0x[drscan $jrc 32 $new_dr_value -endstate DRPAUSE]\n#\techo \"\\tOld router value:\\t0x[format %x $old_dr_value]\"\n}\n\n# Configure the icepick control register\nproc icepick_c_setup {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x001000\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15 for debug tap, 16..31 for test tap\nproc icepick_c_tapenable {jrc port} {\n\n\tif { ($port >= 0) && ($port < 16) } {\n\t\t# Debug tap\"\n\t\tset tap $port\n\t\tset block 0x2\n\t} elseif { $port < 32 } {\n\t\t# Test tap\n\t\tset tap [expr {$port - 16}]\n\t\tset block 0x1\n\t} else {\n\t\techo \"ERROR: Invalid ICEPick C port number: $port\"\n\t\treturn\n\t}\n\n\t# First CONNECT to the ICEPick\n#\techo \"Connecting to ICEPick\"\n\ticepick_c_connect $jrc\n\n#\techo \"Configuring the ICEpick\"\n\ticepick_c_setup $jrc\n\n\t# NOTE: it's important not to enter RUN/IDLE state until\n\t# done sending these instructions and data to the ICEpick.\n\t# And never to enter RESET, which will disable the TAPs.\n\n\t# first enable power and clock for TAP\n\ticepick_c_router $jrc 1 $block $tap 0x110048\n\n\t# TRM states that the register should be read back here, skipped for now\n\n\t# enable debug \"default\" mode\n\ticepick_c_router $jrc 1 $block $tap 0x112048\n\n\t# TRM states that debug enable and debug mode should be read back and\n\t# confirmed - skipped for now\n\n\t# Finally select the tap\n\ticepick_c_router $jrc 1 $block $tap 0x112148\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# jrc\t== TAP name for the ICEpick\n# coreid== core id number 0..15 (not same as port number!)\nproc icepick_d_set_core_control {jrc coreid value } {\n\ticepick_c_router $jrc 1 0x6 $coreid $value\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15\n# Follow the sequence described in\n# http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf\nproc icepick_d_tapenable {jrc port coreid { value 0x2008 } } {\n\n\t# First CONNECT to the ICEPick\n\ticepick_c_connect $jrc\n\ticepick_c_setup $jrc\n\n\t# Select the port\n\ticepick_c_router $jrc 1 0x2 $port 0x2108\n\n\t# Set icepick core control for $coreid\n\ticepick_d_set_core_control $jrc $coreid $value\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# This function uses the ICEPick to send a warm system reset\nproc icepick_c_wreset {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x002101\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx.cfg",
    "content": "# utility fn's for Freescale i.MX series\n\nglobal TARGETNAME\nset TARGETNAME $_TARGETNAME\n\n# rewrite commands of the form below to arm11 mcr...\n#\tData.Set c15:0x042f %long 0x40000015\nproc setc15 {regs value} {\n\tglobal TARGETNAME\n\n\techo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n\tarm mcr 15 [expr {($regs>>12)&0x7}] [expr {($regs>>0)&0xf}] [expr {($regs>>4)&0xf}] [expr {($regs>>8)&0x7}] $value\n}\n\n\nproc imx3x_reset {} {\n\t# this reset script comes from the Freescale PDK\n\t#\n\t# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX35PDK\n\n\techo \"Target Setup: initialize DRAM controller and peripherals\"\n\n#\tData.Set c15:0x01 %long 0x00050078\n\tsetc15 0x01 0x00050078\n\n\techo \"configuring CP15 for enabling the peripheral bus\"\n#\tData.Set c15:0x042f %long 0x40000015\n\tsetc15 0x042f 0x40000015\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx21.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\n#\n# Hmmm.... should srst_pulls_trst be used here like i.MX27???\nreset_config trst_and_srst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx21\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0792611f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx25.cfg",
    "content": "#\n# imx25 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx25\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0x0f -expected-id $_ETBTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0x0 -irmask 0x0 -expected-id 0x0\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882301d\n}\njtag newtap $_CHIPNAME sdma -irlen 5 -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t\t-chain-position $_TARGETNAME\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx27.cfg",
    "content": "# page 3-34 of \"MCIMC27 Multimedia Applications Processor Reference Manual, Rev 0.3\"\n# SRST pulls TRST\n#\n# Without setting these options correctly you'll see all sorts\n# of weird errors, e.g. MOE=0xe, invalid cpsr values, reset\n# failing, etc.\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx27\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there are 2 taps\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926121\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n# REVISIT what operating environment sets up this virtual address mapping?\n$_TARGETNAME configure -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \\\n\t-work-area-size 0x8000 -work-area-backup 1\n# Internal to the chip, there is 45K of SRAM\n#\n\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx28.cfg",
    "content": "# i.MX28 config file.\n# based off of the imx21.cfg file.\n\nreset_config trst_and_srst\n\n#jtag nTRST and nSRST delay\nadapter srst delay 100\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx28\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x079264f3\n}\njtag newtap $_CHIPNAME cpu  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx31.cfg",
    "content": "# imx31 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\n\nadapter srst delay 5\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx31\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x2190101d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The \"SDMA\" - <S>mart <DMA> controller debug tap\n# Based on some IO pins - this can be disabled & removed\n# See diagram: 6-14\n#   SIGNAL NAME:\n#    SJC_MOD - controls multiplexer - disables ARM1136\n#    SDMA_BYPASS - disables SDMA    -\n#\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0xf -expected-id 0x0\n\n# Per section 40.17.1, table 40-85 the IR register is 4 bits\n# But this conflicts with Diagram 6-13, \"3bits ir and drs\"\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx35.cfg",
    "content": "# imx35 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx35\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882601d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0x0 -expected-id 0x0\n\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx51.cfg",
    "content": "# Freescale i.MX51\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx51\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190c01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx51_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx51_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx53.cfg",
    "content": "# Freescale i.MX53\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx53\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190d01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx53_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx53_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx6.cfg",
    "content": "#\n# Freescale i.MX6 series\n#\n# Supports 6Q 6D 6QP 6DP 6DL 6S 6SL 6SLL\n#\n# Some imx6 chips have Cortex-A7 or an Cortex-M and need special handling\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx6\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\n\n# List supported SJC TAPIDs from imx reference manuals:\nset _SJC_TAPID_6Q   0x0191c01d\nset _SJC_TAPID_6D   0x0191e01d\nset _SJC_TAPID_6QP  0x3191c01d\nset _SJC_TAPID_6DP  0x3191d01d\nset _SJC_TAPID_6DL  0x0891a01d\nset _SJC_TAPID_6S   0x0891b01d\nset _SJC_TAPID_6SL  0x0891f01d\nset _SJC_TAPID_6SLL 0x088c201d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6Q\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6QP \\\n        -expected-id $_SJC_TAPID_6DP \\\n        -expected-id $_SJC_TAPID_6D \\\n        -expected-id $_SJC_TAPID_6DL \\\n        -expected-id $_SJC_TAPID_6S \\\n        -expected-id $_SJC_TAPID_6SL \\\n        -expected-id $_SJC_TAPID_6SLL\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x82150000\n# core 1  -  0x82152000\n# core 2  -  0x82154000\n# core 3  -  0x82156000\nset _TARGETNAME $_CHIPNAME.cpu.0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x82150000\n\n# some TCK cycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx6_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n\n# Slow speed to be sure it will work\nadapter speed 1000\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n$_TARGETNAME configure -event reset-assert-post \"imx6_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx6sx.cfg",
    "content": "#\n# Freescale i.MX6SoloX\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6sx\n}\n\n# 2x CoreSight Debug Access Port for Cortex-M4 and Cortex-A9\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu_m4 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_m4 -chain-position $_CHIPNAME.cpu_m4\n\njtag newtap $_CHIPNAME cpu_a9 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_a9 -chain-position $_CHIPNAME.cpu_a9\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID 0x0891c01d\n}\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# Cortex-A9 (boot core)\ntarget create $_CHIPNAME.cpu_a9 cortex_a -dap $_CHIPNAME.dap_a9 \\\n        -coreid 0 -dbgbase 0x82150000\n\n# Cortex-M4 (default off)\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap_m4 \\\n        -ap-num 0 -defer-examine\n\n# AHB mem-ap target\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap_a9 -ap-num 0\n\n# Default target is Cortex-A9\ntargets $_CHIPNAME.cpu_a9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx6ul.cfg",
    "content": "#\n# Freescale i.MX6UltraLite series: 6UL 6ULL 6ULZ\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6ul\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nset _SJC_TAPID_6UL  0x0891d01d\nset _SJC_TAPID_6ULL 0x0891e01d\nset _SJC_TAPID_6ULZ 0x1891e01d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6UL\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6ULL \\\n        -expected-id $_SJC_TAPID_6ULZ \\\n\n# Create DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Main AHB bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Cortex-A7 single core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x82130000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx7.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx7\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n#\n# Cortex-A7 target\n#\n# GDB target: Cortex-A7, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80070000\n# core 1  -  0x80072000\nset _TARGETNAME $_CHIPNAME.cpu_a7\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80070000\n\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 1 -dbgbase 0x80072000 -defer-examine\n#\n# Cortex-M4 target\n#\nset _TARGETNAME_2 $_CHIPNAME.cpu_m4\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.dap -ap-num 4 \\\n        -defer-examine\n\n#\n# AHB mem-ap target\n#\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx7ulp.cfg",
    "content": "#\n# NXP i.MX7ULP: Cortex-A7 + Cortex-M4\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx7ulp\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x188e101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-A7\ntarget create $_CHIPNAME.cpu_a7 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80030000\n\n# Cortex-M4\n# Boots by default so don't defer examination\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap -ap-num 3\n\n# AHB main soc bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Default is Cortex-A7\ntargets $_CHIPNAME.cpu_a7\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx8m.cfg",
    "content": "#\n# configuration file for NXP i.MX8M family of SoCs\n#\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8m\n}\n\nif { [info exists CHIPCORES] } {\n    set _cores $CHIPCORES\n} else {\n    set _cores 1\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# the DAP tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M4 core on AP #4\ntarget create ${_CHIPNAME}.m4 cortex_m -dap ${_CHIPNAME}.dap -ap-num 4 \\\n               -defer-examine\n\n# AHB-AP for direct access to soc bus\ntarget create ${_CHIPNAME}.ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# default target is A53 core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/imx8qm.cfg",
    "content": "#\n# NXP i.MX8QuadMax\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8qm\n}\n\n# CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x1890101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# AXI: Main SOC bus on AP #0\ntarget create ${_CHIPNAME}.axi mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# 4x Cortex-A53 on AP #6\nset _A53_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _A53_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\ncti create $_CHIPNAME.a53_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 0]\ncti create $_CHIPNAME.a53_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 1]\ncti create $_CHIPNAME.a53_cti.2 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 2]\ncti create $_CHIPNAME.a53_cti.3 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 3]\ntarget create $_CHIPNAME.a53.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.0 -dbgbase [lindex $_A53_DBGBASE 0]\ntarget create $_CHIPNAME.a53.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.1 -dbgbase [lindex $_A53_DBGBASE 1] -defer-examine\ntarget create $_CHIPNAME.a53.2 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.2 -dbgbase [lindex $_A53_DBGBASE 2] -defer-examine\ntarget create $_CHIPNAME.a53.3 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.3 -dbgbase [lindex $_A53_DBGBASE 3] -defer-examine\n\n# 2x Cortex-A72 on AP #6\nset _A72_DBGBASE {0x80210000 0x80310000}\nset _A72_CTIBASE {0x80220000 0x80220000}\n\ncti create $_CHIPNAME.a72_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 0]\ncti create $_CHIPNAME.a72_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 1]\ntarget create $_CHIPNAME.a72.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.0 -dbgbase [lindex $_A72_DBGBASE 0] -defer-examine\ntarget create $_CHIPNAME.a72.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.1 -dbgbase [lindex $_A72_DBGBASE 1] -defer-examine\n\n# All Cortex-A in SMP\ntarget smp \\\n        $_CHIPNAME.a53.0 \\\n        $_CHIPNAME.a53.1 \\\n        $_CHIPNAME.a53.2 \\\n        $_CHIPNAME.a53.3 \\\n        $_CHIPNAME.a72.0 \\\n        $_CHIPNAME.a72.1\n\n# SCU: Cortex-M4 core\n# always running imx SC firmware\ntarget create ${_CHIPNAME}.scu cortex_m -dap ${_CHIPNAME}.dap -ap-num 1\n\n# AHB from SCU perspective\ntarget create ${_CHIPNAME}.scu_ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 4\n\n# Cortex-M4 M4_0 core on AP #2 (default off)\ntarget create ${_CHIPNAME}.m4_0 cortex_m -dap ${_CHIPNAME}.dap -ap-num 2 \\\n        -defer-examine\n\n# Cortex-M4 M4_1 core on AP #3 (default off)\ntarget create ${_CHIPNAME}.m4_1 cortex_m -dap ${_CHIPNAME}.dap -ap-num 3 \\\n        -defer-examine\n\n# Debug APB bus\ntarget create ${_CHIPNAME}.apb mem_ap -dap ${_CHIPNAME}.dap -ap-num 6\n\n# Default target is boot core a53.0\ntargets $_CHIPNAME.a53.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/infineon/tle987x.cfg",
    "content": "#\n# Infineon TLE987x family (Arm Cortex-M3 @ up to 40 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tle987x\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\t# JTAG not supported, only SWD\n\tset _CPU_TAPID 0\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME dap -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/is5114.cfg",
    "content": "# script for Insilica IS-5114\n# AKA: Atmel AT76C114 - an ARM946 chip\n# ATMEL sold his product line to Insilica...\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME is5114\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a little endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nreset_config trst_and_srst\n\n# Do not specify a tap id here...\njtag newtap $_CHIPNAME unknown1 -irlen 8 -ircapture 0x01 -irmask 1\n# This is the \"arm946\" chip.\njtag newtap $_CHIPNAME cpu      -irlen 4 -ircapture 0x0e -irmask 0xf\njtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1\n\n\n#arm946e-s and\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\tadapter speed 3000\n}\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ixp42x.cfg",
    "content": "#xscale ixp42x CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ixp42x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x19274013\n}\nset _CPUTAPID2 0x19275013\nset _CPUTAPID3 0x19277013\nset _CPUTAPID4 0x29274013\nset _CPUTAPID5 0x29275013\nset _CPUTAPID6 0x29277013\n\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\n# register constants for IXP42x SDRAM controller\nglobal IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\nglobal IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\nset IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\t0x0000\nset IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\t0x0001\n\nglobal IXP42x_SDRAM_CL3\nglobal IXP42x_SDRAM_CL2\nset IXP42x_SDRAM_CL3\t\t\t0x0008\nset IXP42x_SDRAM_CL2\t\t\t0x0000\n\nglobal IXP42x_SDRAM_8MB_2Mx32_1BANK\nglobal IXP42x_SDRAM_16MB_2Mx32_2BANK\nglobal IXP42x_SDRAM_16MB_4Mx16_1BANK\nglobal IXP42x_SDRAM_32MB_4Mx16_2BANK\nglobal IXP42x_SDRAM_32MB_8Mx16_1BANK\nglobal IXP42x_SDRAM_64MB_8Mx16_2BANK\nglobal IXP42x_SDRAM_64MB_16Mx16_1BANK\nglobal IXP42x_SDRAM_128MB_16Mx16_2BANK\nglobal IXP42x_SDRAM_128MB_32Mx16_1BANK\nglobal IXP42x_SDRAM_256MB_32Mx16_2BANK\n\nset IXP42x_SDRAM_8MB_2Mx32_1BANK\t0x0030\nset IXP42x_SDRAM_16MB_2Mx32_2BANK\t0x0031\nset IXP42x_SDRAM_16MB_4Mx16_1BANK\t0x0032\nset IXP42x_SDRAM_32MB_4Mx16_2BANK\t0x0033\nset IXP42x_SDRAM_32MB_8Mx16_1BANK\t0x0010\nset IXP42x_SDRAM_64MB_8Mx16_2BANK\t0x0011\nset IXP42x_SDRAM_64MB_16Mx16_1BANK\t0x0012\nset IXP42x_SDRAM_128MB_16Mx16_2BANK\t0x0013\nset IXP42x_SDRAM_128MB_32Mx16_1BANK\t0x0014\nset IXP42x_SDRAM_256MB_32Mx16_2BANK\t0x0015\n\n\n# helper function to init SDRAM on IXP42x.\n# SDRAM_CFG: one of IXP42X_SDRAM_xxx\n# REFRESH: refresh counter reload value (integer)\n# CASLAT: 2 or 3\nproc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } {\n\n    switch $CASLAT {\n\t2 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL2} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\n\t}\n\t3 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL3} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\n\t}\n\tdefault { error [format \"unsupported cas latency \\\"%s\\\" \" $CASLAT] }\n    }\n    echo [format \"\\tIXP42x SDRAM Config: 0x%x, Refresh %d \" $SDRAM_CFG $REFRESH]\n\n    mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3\n    mww 0xCC000004          0 ;# disable refresh\n    mww 0xCC000008          3 ;# NOP\n    sleep 100\n    mww 0xCC000004   $REFRESH ;# set refresh counter\n    mww 0xCC000008          2 ;# Precharge All Banks\n    sleep 100\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008    $CASCMD ;# Mode Select CL2/CL3\n}\n\nproc ixp42x_set_bigendian { } {\n    reg XSCALE_CTRL 0xF8\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/k1921vk01t.cfg",
    "content": "# K1921VK01T\n# http://niiet.ru/chips/nis?id=354\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME k1921vk01t\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME\n\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/k40.cfg",
    "content": "#\n# Freescale Kinetis K40 devices\n#\n\nset CHIPNAME k40\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/k60.cfg",
    "content": "#\n# Freescale Kinetis K60 devices\n#\n\nset CHIPNAME k60\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ke0x.cfg",
    "content": "#\n# Freescale Kinetis KE0x and KEAx series devices\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ke\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\n   # It is important that \"kinetis_ke mdm check_security\" is called for\n   # 'examine-end' event and not 'eximine-start'. Calling it in 'examine-start'\n   # causes \"kinetis_ke mdm check_security\" to fail the first time openocd\n   # calls it when it tries to connect after the CPU has been power-cycled.\n   $_CHIPNAME.cpu configure -event examine-end {\n      kinetis_ke mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ke1xf.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xF devices\n#\n\nset CHIPNAME ke\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ke1xz.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xZ devices\n#\n\nset CHIPNAME ke\n\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/kl25.cfg",
    "content": "#\n# Freescale Kinetis KL25 devices\n#\n\nset CHIPNAME kl25\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/kl46.cfg",
    "content": "#\n# Freescale Kinetis KL46 devices\n#\n\nset CHIPNAME kl46\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/klx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis KL series devices\n# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME klx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1KiB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\n# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual\n# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;\n# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ks869x.cfg",
    "content": "# ARM920T CPU\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ks869x\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set  _CPUTAPID $CPUTAPID\n} else {\n   set  _CPUTAPID 0x00922f0f\n}\n\nadapter speed 6000\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/kx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis Kx series devices\n# Also used for Cortex-M4 equipped members of KVx and KE1xF series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME kx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \" Expect problems connecting to a blank device without boot ROM.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU or boot lock-up in RESET/WDOG loop\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n   # During RESET/WDOG loop the target is sometimes falsely examined\n   $_TARGETNAME configure -event examine-end {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc11xx.cfg",
    "content": "# NXP LPC11xx Cortex-M0 with at least 1kB SRAM\nset CHIPNAME lpc11xx\nset CHIPSERIES lpc1100\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc12xx.cfg",
    "content": "# NXP LPC12xx Cortex-M0 with at least 4kB SRAM\nset CHIPNAME lpc12xx\nset CHIPSERIES lpc1200\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc13xx.cfg",
    "content": "# NXP LPC13xx Cortex-M3 with at least 4kB SRAM\nset CHIPNAME lpc13xx\nset CHIPSERIES lpc1300\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc17xx.cfg",
    "content": "# NXP LPC17xx Cortex-M3 with at least 8kB SRAM\nset CHIPNAME lpc17xx\nset CHIPSERIES lpc1700\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x2000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc1850.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc1850\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n#\n# M3 JTAG mode TAP\n#\nif { [info exists M3_JTAG_TAPID] } {\n   set _M3_JTAG_TAPID $M3_JTAG_TAPID\n} else {\n   set _M3_JTAG_TAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME m3 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_JTAG_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.m3\n\nset _TARGETNAME $_CHIPNAME.m3\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc1xxx.cfg",
    "content": "# Main file for NXP LPC1xxx/LPC40xx series Cortex-M0/0+/3/4F parts\n#\n# !!!!!!\n#\n# This file should not be included directly, rather by the lpc11xx.cfg,\n# lpc13xx.cfg, lpc17xx.cfg, etc. which set the needed variables to the\n# appropriate values.\n#\n# !!!!!!\n\n# LPC8xx chips support only SWD transport.\n# LPC11xx chips support only SWD transport.\n# LPC12xx chips support only SWD transport.\n# LPC11Uxx chips support only SWD transports.\n# LPC13xx chips support only SWD transports.\n# LPC17xx chips support both JTAG and SWD transports.\n# LPC40xx chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\terror \"CHIPNAME not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\nif { [info exists CHIPSERIES] } {\n\t# Validate chip series is supported\n\tif { $CHIPSERIES != \"lpc800\" && $CHIPSERIES != \"lpc1100\" && $CHIPSERIES != \"lpc1200\" && $CHIPSERIES != \"lpc1300\" && $CHIPSERIES != \"lpc1700\"  && $CHIPSERIES != \"lpc4000\" } {\n\t\terror \"Unsupported LPC1xxx chip series specified.\"\n\t}\n\tset _CHIPSERIES $CHIPSERIES\n} else {\n\terror \"CHIPSERIES not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\n# After reset, the chip is clocked by an internal RC oscillator.\n# When board-specific code (reset-init handler or device firmware)\n# configures another oscillator and/or PLL0, set CCLK to match; if\n# you don't, then flash erase and write operations may misbehave.\n# (The ROM code doing those updates cares about core clock speed...)\n# CCLK is the core clock frequency in KHz\nif { [info exists CCLK] } {\n\t# Allow user override\n\tset _CCLK $CCLK\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x)\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t\tset _CCLK 12000\n\t} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tset _CCLK 4000\n\t}\n}\n\nif { [info exists CPUTAPID] } {\n\t# Allow user override\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core.\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" } {\n\t\tset _CPUTAPID 0x0bb11477\n\t} elseif { $_CHIPSERIES == \"lpc1300\" || $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tif { [using_jtag] } {\n\t\t\tset _CPUTAPID 0x4ba00477\n\t\t} {\n\t\t\tset _CPUTAPID 0x2ba01477\n\t\t}\n\t}\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\terror \"WORKAREASIZE is not set. The $CHIPNAME part is available in several Flash and RAM size configurations. Please set WORKAREASIZE.\"\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# The LPC11xx devices have 2/4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC12xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC11Uxx devices have 4/6/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC13xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC17xx devices have 8/16/32/64kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC40xx devices have 16/32/64kB of SRAM in the ARMv7-ME \"Code\" area (at 0x10000000)\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n# The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000)\n# The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000)\n# The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 0x00000000)\n# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000)\n# The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000)\n# The LPC40xx devies have 64/128/256/512kB of flash memory (at 0x00000000)\n#\n# All are compatible with the \"lpc1700\" variant of the LPC2000 flash driver\n# (same cmd51 destination boundary alignment, and all three support 256 byte\n# transfers).\n#\n# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum] [iap entry]\nset _IAP_ENTRY 0\nif { [info exists IAP_ENTRY] } {\n\tset _IAP_ENTRY $IAP_ENTRY\n}\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \\\n\tauto $_CCLK calc_checksum $_IAP_ENTRY\n\nif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t# Do not remap 0x0000-0x0200 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# Table 8. System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n\t# Bit Symbol Value Description\n\t# 1:0 MAP          System memory remap\n\t#            0x0   Boot Loader Mode. Interrupt vectors are re-mapped to Boot ROM.\n\t#            0x1   User RAM Mode. Interrupt vectors are re-mapped to Static RAM.\n\t#            0x2   User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash.\n\t# 31:2 -     -     Reserved.\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x40048000 0x02\n\t}\n} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x400FC040 0x01\n\t}\n}\n\n# Run with *real slow* clock by default since the\n# boot rom could have been playing with the PLL, so\n# we have no idea what clock the target is running at.\nadapter speed 10\n\n# delays on reset lines\nadapter srst delay 200\nif {[using_jtag]} {\n jtag_ntrst_delay 200\n}\n\n# LPC8xx (Cortex-M0+ core) support SYSRESETREQ\n# LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ\n# LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ\n# LPC40xx (Cortex-M4F core) support SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2103.cfg",
    "content": "# NXP LPC2103 ARM7TDMI-S with 32kB flash and 8kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2103 {core_freq_khz adapter_freq_khz} {\n\t# 32kB flash and 8kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2103 0x4f1f0f0f 0x8000 lpc2000_v2 0x2000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2103 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2103 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2124.cfg",
    "content": "# NXP LPC2124 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2124 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2124 0x4f1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2124 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2124 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2129.cfg",
    "content": "# NXP LPC2129 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2129 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2129 0xcf1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2129 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2129 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2148.cfg",
    "content": "# NXP LPC2148 ARM7TDMI-S with 512kB flash (12kB used by bootloader) and 40kB SRAM (8kB for USB DMA), clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2148 {core_freq_khz adapter_freq_khz} {\n\t# 500kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2148 \"0x3f0f0f0f 0x4f1f0f0f\" 0x7d000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2148 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2148 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2294.cfg",
    "content": "# NXP LPC2294 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2294 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\n\t# !! TAPID unknown !!\n\tsetup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2294 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2294 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2378.cfg",
    "content": "# NXP LPC2378 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 56kB SRAM (16kB for ETH, 8kB for DMA), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2378 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2378 0x4f1f0f0f 0x7e000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2378 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2378 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2460.cfg",
    "content": "# NXP LPC2460 ARM7TDMI-S with 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2460 {core_freq_khz adapter_freq_khz} {\n\t# 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2460 0x4f1f0f0f 0 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2460 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2460 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2478.cfg",
    "content": "# NXP LPC2478 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2478 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2478 0x4f1f0f0f 0x7e000 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2478 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2478 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2900.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME lpc2900\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0596802B\n}\n\nif { [info exists HAS_ETB] } {\n} else {\n    # Set default (no ETB).\n    # Show a warning, because this should have been configured explicitly.\n    set HAS_ETB 0\n    # TODO: warning?\n}\n\nif { [info exists ETBTAPID] } {\n    set _ETBTAPID $ETBTAPID\n} else {\n    set _ETBTAPID 0x1B900F0F\n}\n\n# TRST and SRST both exist, and can be controlled independently\nreset_config trst_and_srst separate\n\n# Define the _TARGETNAME\nset _TARGETNAME $_CHIPNAME.cpu\n\n# Include the ETB tap controller if asked for.\n# Has to be done manually for newer devices (not an \"old\" LPC2917/2919).\nif { $HAS_ETB == 1 } {\n    # Clear the HAS_ETB flag. Must be set again for a new tap in the chain.\n    set HAS_ETB 0\n\n    # Add the ETB tap controller and the ARM9 core debug tap\n    jtag newtap $_CHIPNAME etb -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_ETBTAPID\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n\n    # Configure ETM and ETB\n    etm config $_TARGETNAME 8 normal full etb\n    etb config $_TARGETNAME $_CHIPNAME.etb\n\n} else {\n    # Add the ARM9 core debug tap\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n}\n\narm7_9 dbgrq enable\narm7_9 dcc_downloads enable\n\n# Flash bank configuration:\n# Flash: flash bank lpc2900 0 0 0 0 <target#> <flash clock (CLK_SYS_FMC) in kHz>\n# Flash base address, total flash size, and number of sectors are all configured automatically.\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME $FLASH_CLOCK\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc2xxx.cfg",
    "content": "# Common setup for the LPC2xxx parts\n\n# parameters:\n# - chip_name - name of the chip, e.g. lpc2103\n# - cputapids - TAP IDs of the core, should be quoted if more than one, e.g. 0x4f1f0f0f or \"0x3f0f0f0f 0x4f1f0f0f\"\n# - flash_size - size of on-chip flash (available for code, not including the bootloader) in bytes, e.g. 0x8000\n# - flash_variant - \"type\" of LPC2xxx device, lpc2000_v1 (LPC22xx and older LPC21xx) or lpc2000_v2 (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)\n# - workarea_size - size of work-area in RAM for flashing procedures, must not exceed the size of RAM available at 0x40000000, e.g. 0x2000\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size core_freq_khz adapter_freq_khz} {\n\treset_config trst_and_srst\n\n\t# reset delays\n\tadapter srst delay 100\n\tjtag_ntrst_delay 100\n\n\tadapter speed $adapter_freq_khz\n\n\tforeach i $cputapids {\n\t\tappend expected_ids \"-expected-id \" $i \" \"\n\t}\n\n\teval \"jtag newtap $chip_name cpu -irlen 4 -ircapture 0x1 -irmask 0xf $expected_ids\"\n\n\tglobal _TARGETNAME\n\tset _TARGETNAME $chip_name.cpu\n\ttarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n\t$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size $workarea_size -work-area-backup 0\n\n\tif { $flash_size > 0 } {\n\t\t# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum]\n\t\tset _FLASHNAME $chip_name.flash\n\t\tflash bank $_FLASHNAME lpc2000 0x0 $flash_size 0 0 $_TARGETNAME $flash_variant $core_freq_khz calc_checksum\n\t}\n}\n\nproc init_targets {} {\n\t# FIX!!! read out CPUTAPID here and choose right setup. In addition to the\n\t# CPUTAPID some querying of the target would be required.\n\treturn -error \"This is a generic LPC2xxx configuration file, use a specific target file.\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc3131.cfg",
    "content": "######################################\n# Target:    NXP lpc3131\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3131\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# ARM926EJS core\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926f0f\n}\n\n# Scan Tap\n# Wired to separate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module\n# JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through.\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1541E02B\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n##################################################################\n# various symbol definitions, to avoid hard-wiring addresses\n##################################################################\n\nglobal lpc313x\nset lpc313x [ dict create ]\n\n# Physical addresses for controllers and memory\ndict set lpc313x sram0\t\t\t0x11028000\ndict set lpc313x sram1\t\t\t0x11040000\ndict set lpc313x uart\t\t\t0x15001000\ndict set lpc313x cgu\t\t\t0x13004000\ndict set lpc313x ioconfig\t\t0x13003000\ndict set lpc313x sysconfig\t\t0x13002800\ndict set lpc313x wdt\t\t\t0x13002400\n\n##################################################################\n# Target configuration\n##################################################################\n\nadapter srst delay 1000\njtag_ntrst_delay 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME invoke-event halted\n\n$_TARGETNAME configure -work-area-phys [dict get $lpc313x sram0] -work-area-size 0x30000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"\\nRunning reset init script for LPC3131\\n\"\n\thalt\n\twait_halt\n\treg cpsr 0xa00000d3\t;#Supervisor mode\n\treg pc 0x11029000\n\tpoll\n\tsleep 500\n}\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc3250.cfg",
    "content": "# lpc3250 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3250\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x17900f0f\n}\n\nif { [info exists CPUTAPID_REV_A0] } {\n   set _CPUTAPID_REV_A0 $CPUTAPID_REV_A0\n} else {\n   set _CPUTAPID_REV_A0 0x17926f0f\n}\n\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1b900f0f\n}\n\njtag newtap $_CHIPNAME sjc -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_SJCTAPID\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID \\\n     -expected-id $_CPUTAPID_REV_A0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -work-area-phys 0x00000000 -work-area-size 0x7d0000 -work-area-backup 0\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc40xx.cfg",
    "content": "# NXP LPC40xx Cortex-M4F with at least 16kB SRAM\nset CHIPNAME lpc40xx\nset CHIPSERIES lpc4000\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x4000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc4350.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4350\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\nif { [using_jtag] } {\n\tswj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tdap create $_CHIPNAME.m0.dap -chain-position $_CHIPNAME.m0\n\ttarget create $_CHIPNAME.m0 cortex_m -dap $_CHIPNAME.m0.dap\n}\n\n# LPC4350 has 96+32 KB SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n\t\t\t-work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # on this CPU we should use VECTRESET to perform a soft reset and\n   # manually reset the periphery\n   # SRST or SYSRESETREQ disable the debug interface for the time of\n   # the reset and will not fit our requirements for a consistent debug\n   # session\n   cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc4357.cfg",
    "content": "#\n# NXP LPC4357\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc4357\n}\nset WORKAREASIZE 0x8000\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.flasha lpc2000 0x1A000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\nflash bank $_CHIPNAME.flashb lpc2000 0x1B000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc4370.cfg",
    "content": "#\n# NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each\n#\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4370\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} else {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\n# LPC4370 has 96+32 KB contiguous SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n                        -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME m0app -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tjtag newtap $_CHIPNAME m0sub -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\n\tdap create $_CHIPNAME.m0app.dap -chain-position $_CHIPNAME.m0app\n\tdap create $_CHIPNAME.m0sub.dap -chain-position $_CHIPNAME.m0sub\n\ttarget create $_CHIPNAME.m0app cortex_m -dap $_CHIPNAME.m0app.dap\n\ttarget create $_CHIPNAME.m0sub cortex_m -dap $_CHIPNAME.m0sub.dap\n\n\t# 32+8+32 KB SRAM\n\t$_CHIPNAME.m0app configure -work-area-phys 0x10080000 \\\n\t                           -work-area-size 0x92000 -work-area-backup 0\n\n\t# 16+2 KB M0 subsystem SRAM\n\t$_CHIPNAME.m0sub configure -work-area-phys 0x18000000 \\\n\t                           -work-area-size 0x4800 -work-area-backup 0\n\n\t# Default to the Cortex-M4\n\ttargets $_CHIPNAME.m4\n}\n\nif { ![using_hla] } {\n\tcortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc84x.cfg",
    "content": "# NXP LPC84x Cortex-M0+ with at least 8kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc84x\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1fe0\n}\n\nset IAP_ENTRY 0x0F001FF1\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc8nxx.cfg",
    "content": "# NXP LPC8Nxx NHS31xx Cortex-M0+ with 8kB SRAM\n# Copyright (C) 2018 by Jean-Christian de Rivaz\n# Based on NXP proposal https://community.nxp.com/message/1011149\n# Many thanks to Dries Moors from NXP support.\n# SWD only transport\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME lpc8nxx\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\nif {![using_hla]} {\n\t# If srst is not fitted use SYSRESETREQ to  perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\nadapter srst delay 100\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0\n\nflash bank $_CHIPNAME.flash lpc2000 0x0 0x7800 0 0 $_TARGETNAME lpc800 500\n\necho \"*********************************************************************************\"\necho \"*         !!!!! IMPORTANT NOTICE FOR LPC8Nxx and NHS31xx CHIPS !!!!!\"\necho \"* When this IC is in power-off or peep power down mode, the SWD HW block is also\"\necho \"* unpowered. These modes can be entered by firmware. The default firmware image\"\necho \"* (flashed in production) makes use of this. Best is to avoid these power modes\"\necho \"* during development, and only later add them when the functionality is complete.\"\necho \"* Hardware reset or NFC field are the only ways to connect in case the SWD is\"\necho \"* powered off. OpenOCD can do a hardware reset if you wire the adapter SRST\"\necho \"* signal to the chip RESETN pin and add the following in your configuration:\"\necho \"*     reset_config srst_only; flash init; catch init; reset\"\necho \"* But if the actual firmware immediately set the power down mode after reset,\"\necho \"* OpenOCD might be not fast enough to halt the CPU before the SWD lost power. In\"\necho \"* that case the only solution is to apply a NFC field to keep the SWD powered.\"\necho \"*********************************************************************************\"\n\n# Using soft-reset 'reset_config none' is strongly discouraged.\n# RESETN sets the system clock to 500 kHz. Unlike soft-reset does not.\n# Set the system clock to 500 kHz before reset to simulate the functionality of hw reset.\n#\nproc set_sysclk_500khz {} {\n\tset SYSCLKCTRL 0x40048020\n\tset SYSCLKUEN 0x40048024\n\tmww $SYSCLKUEN 0\n\tmmw $SYSCLKCTRL 0x8 0xe\n\tmww $SYSCLKUEN 1\n\techo \"Notice: sysclock set to 500kHz.\"\n}\n\n# Do not remap the ARM interrupt vectors to anything but the beginning of the flash.\n# Table System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n# Bit Symbol  Value   Description\n# 0   map         -   interrupt vector remap. 0 after boot.\n#                 0   interrupt vector reside in Flash\n#                 1   interrupt vector reside in SRAM\n# 5:1 offset      -   system memory remap offset. 00000b after boot.\n#            00000b   interrupt vectors in flash or remapped to SRAM but no offset\n#            00001b -\n#            00111b   interrupt vectors offset in flash or SRAM to 1K word segment\n#            01000b -\n#            11111b   interrupt vectors offset in flash to 1K word segment 8 to 31\n# 31:6                reserved\n#\nproc set_no_remap {} {\n\tmww 0x40048000 0x00\n\techo \"Notice: interrupt vector set to no remap.\"\n}\n\n$_TARGETNAME configure -event reset-init {\n\tset_sysclk_500khz\n\tset_no_remap\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lpc8xx.cfg",
    "content": "# NXP LPC8xx Cortex-M0+ with at least 1kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc8xx\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ls1012a.cfg",
    "content": "#\n# NXP LS1012A\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1012a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b2001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ncti create $_CHIPNAME.cti -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0x80420000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -dbgbase 0x80410000 -cti $_CHIPNAME.cti\n\ntarget smp $_TARGETNAME\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ls1028a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1028A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1028a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\nset _CPUS 2\n\nsource [find target/lsch3_common.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1046a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b3001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _CPU_BASE 0x80400000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < 4} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t-coreid $i {*}[expr {$i ? {-defer-examine} : {-rtos hwthread} }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\ntarget create $_CHIPNAME.sap ls1_sap -chain-position $_CHIPNAME.sap -endian big\n\nproc core_up { args } {\n    foreach core $args {\n        $::_CHIPNAME.cpu$core arp_examine\n    }\n}\n\ntargets $_CHIPNAME.cpu0\n\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1088a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nset _CPUS 8\n\nsource [find target/lsch3_common.cfg]\n\n# Seems to work OK in testing\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/lsch3_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# This contains common configuration for NXP Layerscape chassis generation 3\n\nif { ![info exists _CPUS] } {\n\terror \"_CPUS must be set to the number of cores\"\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 1\n\nset _CPU_BASE 0x81000000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < $_CPUS} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 0 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t{*}[expr {$i ? \"-coreid $i\" : \"-rtos hwthread\" }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\n# Service processor\ntarget create $_CHIPNAME.sp cortex_a -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80138000\n\n# Normally you will not need to call this, but if you are using the hard-coded\n# Reset Configuration Word (RCW) you will need to call this manually. The CPU's\n# reset vector is 0, and the boot ROM at that location contains ARMv7-A 32-bit\n# instructions. This will cause the CPU to almost immediately execute an\n# illegal instruction.\n#\n# This code is idempotent; releasing a released CPU has no effect, although it\n# will halt/resume the service processor.\nadd_help_text release_cpu \"Release a cpu which is held off\"\nproc release_cpu {cpu} {\n\tset RST_BRRL 0x1e60060\n\n\tset old [target current]\n\ttargets $::_CHIPNAME.sp\n\tset not_halted [string compare halted [$::_CHIPNAME.sp curstate]]\n\tif {$not_halted} {\n\t\thalt\n\t}\n\n\t# Release the cpu; it will start executing something bogus\n\tmem2array regs 32 $RST_BRRL 1\n\tmww $RST_BRRL [expr {$regs(0) | 1 << $cpu}]\n\n\tif {$not_halted} {\n\t\tresume\n\t}\n\ttargets $old\n}\n\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/marvell/88f3710.cfg",
    "content": "# Marvell Armada 3710\n\nset CORES 1\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/marvell/88f3720.cfg",
    "content": "# Marvell Armada 3720\n\nset CORES 2\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/marvell/88f37x0.cfg",
    "content": "# Main file for Marvell Armada 3700 series targets\n#\n# !!!!!!\n#\n# This file should not be included directly. Instead, please include\n# either marvell/88f3710.cfg or marvell/88f3720.cfg, which set the needed\n# variables to the appropriate values.\n#\n# !!!!!!\n\n# Armada 3700 supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CORES] } {\n    set _cores $CORES\n} else {\n    error \"CORES not set. Please do not include marvell/88f37x0.cfg directly, but the specific chip configuration file (marvell/88f3710.cfg, marvell/88f3720.cfg, etc.).\"\n}\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME [format a37%s0 $_cores]\n}\n\nset _ctis {0x80820000 0x80920000}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# declare the main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [lindex $_ctis $_core] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core \\\n                         -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M3 core on AP #3\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/max32620.cfg",
    "content": "# Maxim Integrated MAX32620 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -ignore-version\n} else {\n    swd newdap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32620.cpu cortex_m -chain-position max32620.cpu\nmax32620.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32620 flash base address   0x00000000\n#   max32620 flash size           0x200000 (2MB)\n#   max32620 FLC base address     0x40002000\n#   max32620 sector (page) size   0x2000 (8kB)\n#   max32620 clock speed          96 (MHz)\nflash bank max32620.flash max32xxx 0x00000000 0x200000 0 0 max32620.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/max32625.cfg",
    "content": "# Maxim Integrated MAX32625 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f71197 -ignore-version\n} else {\n    swd newdap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32625.cpu cortex_m -chain-position max32625.cpu\nmax32625.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32625 flash base address   0x00000000\n#   max32625 flash size           0x80000 (512k)\n#   max32625 FLC base address     0x40002000\n#   max32625 sector (page) size   0x2000 (8kB)\n#   max32625 clock speed          96 (MHz)\nflash bank max32625.flash max32xxx 0x00000000 0x80000 0 0 max32625.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/max3263x.cfg",
    "content": "# Maxim Integrated MAX3263X OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f76197 -ignore-version\n} else {\n    swd newdap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max3263x.cpu cortex_m -chain-position max3263x.cpu\nmax3263x.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max3263x flash base address   0x00000000\n#   max3263x flash size           0x200000 (2MB)\n#   max3263x FLC base address     0x40002000\n#   max3263x sector (page) size   0x2000 (8kB)\n#   max3263x clock speed          96 (MHz)\nflash bank max3263x.flash max32xxx 0x00000000 0x200000 0 0 max3263x.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/mc13224v.cfg",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER             freescale\nset CHIP_FAMILY            mc1322x\nset CHIP_NAME              mc13224\nset N_RAM                  1\nset RAM(0,BASE)            0x00400000\nset RAM(0,LEN)             0x18000\nset RAM(0,HUMAN)           \"internal SRAM\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS                  1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0x80000000\nset MMREGS(0,LEN)             0x00030000\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\nset N_XMEM 0\n\nset _CHIPNAME mc13224v\nset _CPUTAPID 0x1f1f001d\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nreset_config srst_only\njtag_ntrst_delay 200\n\n# rclk hasn't been working well. This maybe the mc13224v or something else.\n#adapter speed 2000\nadapter speed 2000\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n# Internal sram memory\n$_TARGETNAME configure -work-area-phys 0x00408000 \\\n                       -work-area-size 0x1000     \\\n                       -work-area-backup 1\n\n# flash support is pending (should be straightforward to implement)\n#flash bank mc1322x 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/mdr32f9q2i.cfg",
    "content": "# MDR32F9Q2I (1986ВЕ92У)\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=57&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME mdr32f9q2i\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x08000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x08000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nds32v2.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nds32v3.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nds32v3m.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nds32v5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\nset _CHIPNAME nds\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563D\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nhs31xx.cfg",
    "content": "# NXP NHS31xx Cortex-M0+ with 8kB SRAM\n\nset CHIPNAME nhs31xx\nsource [find target/lpc8nxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/npcx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton NPCX Cortex-M4 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NPCX_M4\n}\n\n# SWD DAP ID of Nuvoton NPCX Cortex-M4.\nif { [info exists CPUDAPID ] } {\n   set _CPUDAPID $CPUDAPID\n} else {\n   set _CPUDAPID 0x4BA00477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x200c0000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# Initial JTAG/SWD speed\n# For safety purposes, set for the lowest cpu clock configuration\n# 4MHz / 6 = 666KHz, so use 600KHz for it\nadapter speed 600\n\n# For safety purposes, set for the lowest cpu clock configuration\n$_TARGETNAME configure -event reset-start {adapter speed 600}\n\n# use sysresetreq to perform a system reset\ncortex_m reset_config sysresetreq\n\n# flash configuration\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nrf51.cfg",
    "content": "#\n# script for Nordic nRF51 series, a Cortex-M0 chip\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nrf51\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # The chip supports standard ARM/Cortex-M0 SYSRESETREQ signal\n   cortex_m reset_config sysresetreq\n}\n\nflash bank $_CHIPNAME.flash nrf51 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME\n\n#\n#  The chip should start up from internal 16Mhz RC, so setting adapter\n#  clock to 1Mhz should be OK\n#\nadapter speed 1000\n\nproc enable_all_ram {} {\n\t# nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks\n\t# are reliably enabled after reset on some revisions (contrary to spec.) So after\n\t# resetting we enable all banks via the RAMON register\n\tmww 0x40000524 0xF\n}\n$_TARGETNAME configure -event reset-end {  enable_all_ram }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nrf52.cfg",
    "content": "#\n# Nordic nRF52 series: ARM Cortex-M4 @ 64 MHz\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME nrf52\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nadapter speed 1000\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_hla] } {\n\techo \"\"\n\techo \"nRF52 device has a CTRL-AP dedicated to recover the device from AP lock.\"\n\techo \"A high level adapter (like a ST-Link) you are currently using cannot access\"\n\techo \"the CTRL-AP so 'nrf52_recover' command will not work.\"\n\techo \"Do not enable UICR APPROTECT.\"\n\techo \"\"\n} else {\n\tcortex_m reset_config sysresetreq\n\n\t$_TARGETNAME configure -event examine-fail nrf52_check_ap_lock\n}\n\nflash bank $_CHIPNAME.flash nrf5 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf5 0x10001000 0 1 1 $_TARGETNAME\n\n# Test if MEM-AP is locked by UICR APPROTECT\nproc nrf52_check_ap_lock {} {\n\tset dap [[target current] cget -dap]\n\tset err [catch {set APPROTECTSTATUS [$dap apreg 1 0xc]}]\n\tif {$err == 0 && $APPROTECTSTATUS != 1} {\n\t\techo \"****** WARNING ******\"\n\t\techo \"nRF52 device has AP lock engaged (see UICR APPROTECT register).\"\n\t\techo \"Debug access is denied.\"\n\t\techo \"Use 'nrf52_recover' to erase and unlock the device.\"\n\t\techo \"\"\n\t\tpoll off\n\t}\n}\n\n# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #1)\n# http://www.ebyte.com produces modules with nRF52 locked by default,\n# use nrf52_recover to enable flashing and debug.\nproc nrf52_recover {} {\n\tset target [target current]\n\tset dap [$target cget -dap]\n\n\tset IDR [$dap apreg 1 0xfc]\n\tif {$IDR != 0x02880000} {\n\t\techo \"Error: Cannot access nRF52 CTRL-AP!\"\n\t\treturn\n\t}\n\n\tpoll off\n\n\t# Reset and trigger ERASEALL task\n\t$dap apreg 1 4 0\n\t$dap apreg 1 4 1\n\n\tfor {set i 0} {1} {incr i} {\n\t\tset ERASEALLSTATUS [$dap apreg 1 8]\n\t\tif {$ERASEALLSTATUS == 0} {\n\t\t\techo \"$target device has been successfully erased and unlocked.\"\n\t\t\tbreak\n\t\t}\n\t\tif {$i == 0} {\n\t\t\techo \"Waiting for chip erase...\"\n\t\t}\n\t\tif {$i >= 150} {\n\t\t\techo \"Error: $target recovery failed.\"\n\t\t\tbreak\n\t\t}\n\t\tsleep 100\n\t}\n\n\t# Assert reset\n\t$dap apreg 1 0 1\n\n\t# Deassert reset\n\t$dap apreg 1 0 0\n\n\t# Reset ERASEALL task\n\t$dap apreg 1 4 0\n\n\tsleep 100\n\t$target arp_examine\n\tpoll on\n}\n\nadd_help_text nrf52_recover \"Mass erase and unlock nRF52 device\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/nuc910.cfg",
    "content": "#\n# Nuvoton nuc910 (previously W90P910) based soc\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nuc910\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x07926f0f\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/numicro.cfg",
    "content": "# script for Nuvoton MuMicro Cortex-M0 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NuMicro\n}\n\n# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only.\nif { [info exists CPUDAPID] } {\n\tset _CPUDAPID $CPUDAPID\n} else {\n\tset _CPUDAPID 0x0BB11477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash_aprom\nflash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_data\nflash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_ldrom\nflash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_config\nflash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME\n\n# set default SWCLK frequency\nadapter speed 1000\n\n# set default srst setting \"none\"\nreset_config none\n\n# HLA doesn't have cortex_m commands\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omap2420.cfg",
    "content": "# Texas Instruments OMAP 2420\n#\thttp://www.ti.com/omap\n# as seen in Nokia N8x0 tablets\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap2420\n}\n\n# NOTE: likes slowish clock on reset (1.5 MBit/s or less) or use RCLK\nreset_config srst_nogate\n\n# Subsidiary TAP: ARM7TDMIr4 plus imaging ... must add via ICEpick (addr 6).\njtag newtap $_CHIPNAME iva -irlen 4 -disable\n\n# Subsidiary TAP: C55x DSP ... must add via ICEpick (addr 2).\njtag newtap $_CHIPNAME dsp -irlen 38 -disable\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID\n\n# Subsidiary TAP: ARM1136jf-s with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07b3602f\n}\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\n# Primary TAP: ICEpick-B (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x01ce4801\n}\njtag newtap $_CHIPNAME jrc -irlen 2 -expected-id $_JRC_TAPID\n\n# GDB target: the ARM.\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_TARGETNAME\n\n# scratch: framebuffer, may be initially unavailable in some chips\n$_TARGETNAME configure -work-area-phys 0x40210000\n$_TARGETNAME configure -work-area-size 0x00081000\n$_TARGETNAME configure -work-area-backup 0\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\n# RM_RSTCTRL_WKUP.RST.GS - Trigger a global software reset, and\n# give it a chance to finish before we talk to the chip again.\nset RM_RSTCTRL_WKUP 0x48008450\n$_TARGETNAME configure -event reset-assert \\\n\t\"halt; $_TARGETNAME mww $RM_RSTCTRL_WKUP 2; sleep 200\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omap3530.cfg",
    "content": "# TI OMAP3530\n# http://focus.ti.com/docs/prod/folders/print/omap3530.html\n# Other OMAP3 chips remove DSP and/or the OpenGL support\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap3530\n}\n\n# ICEpick-C ... used to route Cortex, DSP, and more not shown here\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n\n# Subsidiary TAP: CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x0b6d602f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7ae02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# SRAM: 64K at 0x4020.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n###################\n\n# the reset sequence is event-driven\n# and kind of finicky...\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# have the DAP \"always\" be active\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\nproc omap3_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n     # Enable DBGU signal for OMAP353x\n     $target mww phys 0x5401d030 0x00002000\n}\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in.\n# OK to speed up *after* PLL and clock tree setup.\nadapter speed 1000\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1000 }\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  RST_GS (2) is a warm reset, like ICEpick\n# would issue.  RST_DPLL3 (4) is a cold reset.\nset PRM_RSTCTRL 0x48307250\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww $PRM_RSTCTRL 2\"\n\n$_TARGETNAME configure -event reset-assert-post \"omap3_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omap4430.cfg",
    "content": "# OMAP4430\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4430\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x3b95c02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omap4460.cfg",
    "content": "# OMAP4460\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4460\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x2b94e02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omap5912.cfg",
    "content": "# TI OMAP5912 dual core processor\n# http://focus.ti.com/docs/prod/folders/print/omap5912.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap5912\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # NOTE: validated with XOMAP5912 part\n   set _CPUTAPID 0x0692602f\n}\n\nadapter srst delay 100\n\n# NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for\n# its standalone siblings (like TMS320VC5502) of the same era\n\n#jtag scan chain\njtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81\njtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID\njtag newtap $_CHIPNAME unknown -irlen 8\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\nproc omap5912_reset {} {\n\t#\n\t# halt target\n\t#\n\tpoll\n\tsleep 1\n\thalt\n\twait_halt\n\t#\n\t# disable wdt\n\t#\n\tmww 0xfffec808 0x000000f5\n\tmww 0xfffec808 0x000000a0\n\n\tmww 0xfffeb048 0x0000aaaa\n\tsleep 500\n\tmww 0xfffeb048 0x00005555\n\tsleep 500\n}\n\n# omap5912 lcd frame buffer as working area\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n\t-work-area-size 0x3e800 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/omapl138.cfg",
    "content": "#\n# Texas Instruments DaVinci family: OMAPL138\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omapl138\n}\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID -disable\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID -disable\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7d102f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target:  the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\ngdb_breakpoint_override hard\narm7_9 dbgrq enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/or1k.cfg",
    "content": "set  _ENDIAN big\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME or1k\n}\n\nif { [info exists TAP_TYPE] } {\n   set _TAP_TYPE $TAP_TYPE\n} else {\n   puts \"You need to select a tap type\"\n   shutdown\n}\n\n# Configure the target\nif { [string compare $_TAP_TYPE \"VJTAG\"] == 0 } {\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 10 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select vjtag\n\n} elseif { [string compare $_TAP_TYPE \"XILINX_BSCAN\"] == 0 } {\n\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select xilinx_bscan\n} else {\n\t# OpenCores Mohor JTAG TAP ID\n\tset _CPUTAPID  0x14951185\n\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select mohor\n}\n\n# Select the debug unit core we are using. This debug unit as an option.\n\nset ADBG_USE_HISPEED\t\t1\nset ENABLE_JSP_SERVER\t\t2\nset ENABLE_JSP_MULTI\t\t4\n\n# If ADBG_USE_HISPEED is set (options bit 1), status bits will be skipped\n# on burst reads and writes to improve download speeds.\n# This option must match the RTL configured option.\n\ndu_select adv [expr {$ADBG_USE_HISPEED | $ENABLE_JSP_SERVER | $ENABLE_JSP_MULTI}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/pic32mx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pic32mx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x30938053\n}\n\n# default working area is 16384\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#\n# At reset the pic32mx does not allow code execution from RAM\n# we have to setup the BMX registers to allow this.\n# One limitation is that we loose the first 2k of RAM.\n#\n\nglobal _PIC32MX_DATASIZE\nglobal _WORKAREASIZE\nset _PIC32MX_DATASIZE 0x800\nset _PIC32MX_PROGSIZE [expr {$_WORKAREASIZE - $_PIC32MX_DATASIZE}]\n\n$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size $_PIC32MX_PROGSIZE -work-area-backup 0\n$_TARGETNAME configure -event reset-init {\n\t#\n\t# from reset the pic32 cannot execute code in ram - enable ram execution\n\t# minimum offset from start of ram is 2k\n\t#\n\tglobal _PIC32MX_DATASIZE\n\tglobal _WORKAREASIZE\n\n\t# BMXCON\tset 0 wait state option by clearing BMXWSDRM bit, bit 6\n\tmww 0xbf882000 0x001f0000\n\t# BMXDKPBA: 2k kernel data @ 0xa0000000\n\tmww 0xbf882010 $_PIC32MX_DATASIZE\n\t# BMXDUDBA: 14k kernel program @ 0xa0000800 - (BMXDUDBA - BMXDKPBA)\n\tmww 0xbf882020 $_WORKAREASIZE\n\t# BMXDUPBA: 0k user program - (BMXDUPBA - BMXDUDBA)\n\tmww 0xbf882030 $_WORKAREASIZE\n\n\t#\n\t# Set system clock to 8Mhz if the default clock configuration is set\n\t#\n\n\t# SYSKEY register, make sure OSCCON is locked\n\tmww 0xbf80f230 0x0\n\t# SYSKEY register, write unlock sequence\n\tmww 0xbf80f230 0xaa996655\n\tmww 0xbf80f230 0x556699aa\n\t# OSCCON register + 4, clear OSCCON FRCDIV bits: 24, 25 and 26, divided by 1\n\tmww 0xbf80f004 0x07000000\n\t# SYSKEY register, relock OSCCON\n\tmww 0xbf80f230 0x0\n}\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank2 virtual 0xbd000000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank3 virtual 0x9d000000 0 0 0 $_TARGETNAME $_FLASHNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/psoc4.cfg",
    "content": "# script for Cypress PSoC 4 devices\n\n#\n# PSoC 4 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME psoc4\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\nadapter speed 1500\n\n# Reset, bloody PSoC 4 reset\n#\n# 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.\n# High level adapter stops working after SRST and needs OpenOCD restart.\n# If your hw does not use SRST for other circuits, use sysresetreq instead\n#\n# 2) PSoC 4 executes initialization code from system ROM after reset.\n# This code subsequently jumps to user flash reset vector address.\n# Unfortunately the system ROM code is protected from reading and debugging.\n# Protection breaks vector catch VC_CORERESET used for \"reset halt\" by cortex_m.\n#\n# Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code\n# from user flash. Programming specifications states that TEST_MODE flag must be\n# set in time frame 400 usec delayed about 1 msec from reset.\n#\n# OpenOCD have no standard way how to set TEST_MODE in specified time frame.\n# As a workaround the TEST_MODE flag is set before reset instead.\n# It worked for the oldest family PSoC4100/4200 even though it is not guaranteed\n# by specification.\n#\n# Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE\n# clear TEST_MODE flag during device reset so workaround is not possible.\n# Use a KitProg adapter for these devices or \"reset halt\" will not stop\n# before executing user code.\n#\n# 3) SWD cannot be connected during system initialization after reset.\n# This might be a reason for unconnecting ST-Link v2 when deasserting reset.\n# As a workaround arp_reset deassert is not called for hla\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc psoc4_get_family_id {} {\n\tset err [catch {set romtable_pid [read_memory 0xF0000FE0 32 3]}]\n\tif { $err } {\n\t\treturn 0\n\t}\n\tif { [expr {[lindex $romtable_pid 0] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 1] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 2] & 0xffffff00 }] } {\n\t\techo \"Unexpected data in ROMTABLE\"\n\t\treturn 0\n\t}\n\tset designer_id [expr {(( [lindex $romtable_pid 1] & 0xf0 ) >> 4) | (( [lindex $romtable_pid 2] & 0xf ) << 4 ) }]\n\tif { $designer_id != 0xb4 } {\n\t\techo [format \"ROMTABLE Designer ID 0x%02x is not Cypress\" $designer_id]\n\t\treturn 0\n\t}\n\tset family_id [expr {( [lindex $romtable_pid 0] & 0xff ) | (( [lindex $romtable_pid 1] & 0xf ) << 8 ) }]\n\treturn $family_id\n}\n\nproc ocd_process_reset_inner { MODE } {\n\tglobal PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND\n\tglobal _TARGETNAME\n\n\tif { 0 != [string compare $_TARGETNAME [target names]] } {\n\t\treturn -code error \"PSoC 4 reset can handle only one $_TARGETNAME target\";\n\t}\n\tset t $_TARGETNAME\n\n\t# If this target must be halted...\n\tset halt -1\n\tif { 0 == [string compare $MODE halt] } {\n\t\tset halt 1\n\t}\n\tif { 0 == [string compare $MODE init] } {\n\t\tset halt 1;\n\t}\n\tif { 0 == [string compare $MODE run ] } {\n\t\tset halt 0;\n\t}\n\tif { $halt < 0 } {\n\t\treturn -code error \"Invalid mode: $MODE, must be one of: halt, init, or run\";\n\t}\n\n\tif { ! [info exists PSOC4_USE_ACQUIRE] } {\n\t\tif { 0 == [string compare [adapter name] kitprog ] } {\n\t\t\tset PSOC4_USE_ACQUIRE 1\n\t\t} else {\n\t\t\tset PSOC4_USE_ACQUIRE 0\n\t\t}\n\t}\n\tif { $PSOC4_USE_ACQUIRE } {\n\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t} elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {\n\t\tif { [psoc4_get_family_id] == 0x93 } {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 1\n\t\t} else {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t\t}\n\t}\n\n\t#$t invoke-event reset-start\n\t$t invoke-event reset-assert-pre\n\n\tif { $halt && $PSOC4_USE_ACQUIRE } {\n\t\tcatch { [adapter name] acquire_psoc }\n\t\t$t arp_examine\n\t} else {\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tset TEST_MODE 0x40030014\n\t\t\tif { $halt == 1 } {\n\t\t\t\tcatch { mww $TEST_MODE 0x80000000 }\n\t\t\t} else {\n\t\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t\t}\n\t\t}\n\n\t\t$t arp_reset assert 0\n\t}\n\n\t$t invoke-event reset-assert-post\n\t$t invoke-event reset-deassert-pre\n\tif {![using_hla]} {\t# workaround ST-Link v2 fails and forcing reconnect\n\t\t$t arp_reset deassert 0\n\t}\n\t$t invoke-event reset-deassert-post\n\n\t# Pass 1 - Now wait for any halt (requested as part of reset\n\t# assert/deassert) to happen.  Ideally it takes effect without\n\t# first executing any instructions.\n\tif { $halt } {\n\t\t# Now PSoC CPU should loop in system ROM\n\t\t$t arp_waitstate running 200\n\t\t$t arp_halt\n\n\t\t# Catch, but ignore any errors.\n\t\tcatch { $t arp_waitstate halted 1000 }\n\n\t\t# Did we succeed?\n\t\tset s [$t curstate]\n\n\t\tif { 0 != [string compare $s \"halted\" ] } {\n\t\t\treturn -code error [format \"TARGET: %s - Not halted\" $t]\n\t\t}\n\n\t\t# Check if PSoC CPU is stopped in system ROM\n\t\tset pc [reg pc]\n\t\tregsub {pc[^:]*: } $pc \"\" pc\n\t\tif { $pc < 0x10000000 || $pc > 0x1000ffff } {\n\t\t\tset hint \"\"\n\t\t\tset family_id [psoc4_get_family_id]\n\t\t\tif { $family_id == 0x93 } {\n\t\t\t\tset hint \", use 'reset_config none'\"\n\t\t\t} elseif { $family_id > 0x93 } {\n\t\t\t\tset hint \", use a KitProg adapter\"\n\t\t\t}\n\t\t\treturn -code error [format \"TARGET: %s - Not halted in system ROM%s\" $t $hint]\n\t\t}\n\n\t\t# Set registers to reset vector values\n\t\tset value [read_memory 0x0 32 2]\n\t\treg pc [expr {[lindex $value 1] & 0xfffffffe}]\n\t\treg msp [lindex $value 0]\n\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t}\n\t}\n\n\t#Pass 2 - if needed \"init\"\n\tif { 0 == [string compare init $MODE] } {\n\t\tset err [catch \"$t arp_waitstate halted 5000\"]\n\n\t\t# Did it halt?\n\t\tif { $err == 0 } {\n\t\t\t$t invoke-event reset-init\n\t\t}\n\t}\n\n\t$t invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/psoc5lp.cfg",
    "content": "#\n# Cypress PSoC 5LP\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc5lp\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} else {\n\tset _CPU_TAPID 0x4BA00477\n}\n\nif { [using_jtag] } {\n\tset _CPU_DAP_ID $_CPU_TAPID\n} else {\n\tset _CPU_DAP_ID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE / 2}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nsource [find mem_helper.tcl]\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure Target Device (PSoC 5LP Device Programming Specification 5.2)\n\n\tset PANTHER_DBG_CFG 0x4008000C\n\tset PANTHER_DBG_CFG_BYPASS [expr {1 << 1}]\n\tmmw $PANTHER_DBG_CFG $PANTHER_DBG_CFG_BYPASS 0\n\n\tset PM_ACT_CFG0 0x400043A0\n\tmww $PM_ACT_CFG0 0xBF\n\n\tset FASTCLK_IMO_CR 0x40004200\n\tset FASTCLK_IMO_CR_F_RANGE_2    [expr {2 << 0}]\n\tset FASTCLK_IMO_CR_F_RANGE_MASK [expr {7 << 0}]\n\tmmw $FASTCLK_IMO_CR $FASTCLK_IMO_CR_F_RANGE_2 $FASTCLK_IMO_CR_F_RANGE_MASK\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/psoc6.cfg",
    "content": "#\n# Configuration script for Cypress PSoC6 family of microcontrollers (CY8C6xxx)\n# PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share\n# the same Flash/RAM/MMIO address space.\n#\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc6\n}\n\nglobal TARGET\nset TARGET $_CHIPNAME.cpu\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Is CM0 Debugging enabled ?\nglobal _ENABLE_CM0\nif { [info exists ENABLE_CM0] } {\n\tset _ENABLE_CM0 $ENABLE_CM0\n} else {\n\tset _ENABLE_CM0 1\n}\n\n# Is CM4 Debugging enabled ?\nglobal _ENABLE_CM4\nif { [info exists ENABLE_CM4] } {\n\tset _ENABLE_CM4 $ENABLE_CM4\n} else {\n\tset _ENABLE_CM4 1\n}\n\nglobal _WORKAREASIZE_CM0\nif { [info exists WORKAREASIZE_CM0] } {\n\tset _WORKAREASIZE_CM0 $WORKAREASIZE_CM0\n} else {\n\tset _WORKAREASIZE_CM0 0x4000\n}\n\nglobal _WORKAREASIZE_CM4\nif { [info exists WORKAREASIZE_CM4] } {\n\tset _WORKAREASIZE_CM4 $WORKAREASIZE_CM4\n} else {\n\tset _WORKAREASIZE_CM4 0x4000\n}\n\nglobal _WORKAREAADDR_CM0\nif { [info exists WORKAREAADDR_CM0] } {\n\tset _WORKAREAADDR_CM0 $WORKAREAADDR_CM0\n} else {\n\tset _WORKAREAADDR_CM0 0x08000000\n}\n\nglobal _WORKAREAADDR_CM4\nif { [info exists WORKAREAADDR_CM4] } {\n\tset _WORKAREAADDR_CM4 $WORKAREAADDR_CM4\n} else {\n\tset _WORKAREAADDR_CM4 0x08000000\n}\n\nproc init_reset { mode } {\n\tglobal RESET_MODE\n\tset RESET_MODE $mode\n\n\tif {[using_jtag]} {\n\t\tjtag arp_init-reset\n\t}\n}\n\n# Utility to make 'reset halt' work as reset;halt on a target\n# It does not prevent running code after reset\nproc psoc6_deassert_post { target } {\n\t# PSoC6 cleared AP registers including TAR during reset\n\t# Force examine to synchronize OpenOCD target status\n\t$target arp_examine\n\n\tglobal RESET_MODE\n\tglobal TARGET\n\n\tif { $RESET_MODE ne \"run\" } {\n\t\t$target arp_poll\n\t\t$target arp_poll\n\t\tset st [$target curstate]\n\n\t\tif { $st eq \"reset\" } {\n\t\t\t# we assume running state follows\n\t\t\t# if reset accidentally halts, waiting is useless\n\t\t\tcatch { $target arp_waitstate running 100 }\n\t\t\tset st [$target curstate]\n\t\t}\n\n\t\tif { $st eq \"running\" } {\n\t\t\techo \"$target: Ran after reset and before halt...\"\n\t\t\tif { $target eq \"${TARGET}.cm0\" } {\n\t\t\t\t# Try to cleanly reset whole system\n\t\t\t\t# and halt the CM0 at entry point\n\t\t\t\tpsoc6 reset_halt\n\t\t\t\t$target arp_waitstate halted 100\n\t\t\t} else {\n\t\t\t\t$target arp_halt\n\t\t\t}\n\t\t}\n\t}\n}\n\nif { $_ENABLE_CM0 } {\n\ttarget create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\t${TARGET}.cm0 configure -work-area-phys $_WORKAREAADDR_CM0 -work-area-size $_WORKAREASIZE_CM0 -work-area-backup 0\n\n\tflash bank main_flash_cm0\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm0\n\tflash bank work_flash_cm0\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_user_cm0\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_nar_cm0\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_key_cm0\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_toc2_cm0\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm0\n\n\t${TARGET}.cm0 cortex_m reset_config sysresetreq\n\t${TARGET}.cm0 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm0\"\n}\n\nif { $_ENABLE_CM4 } {\n\ttarget create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\t${TARGET}.cm4 configure -work-area-phys $_WORKAREAADDR_CM4 -work-area-size $_WORKAREASIZE_CM4 -work-area-backup 0\n\n\tflash bank main_flash_cm4\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm4\n\tflash bank work_flash_cm4\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_user_cm4\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_nar_cm4\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_key_cm4\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_toc2_cm4\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm4\n\n\t${TARGET}.cm4 cortex_m reset_config vectreset\n\t${TARGET}.cm4 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm4\"\n}\n\nif { $_ENABLE_CM0 } {\n\t# Use CM0+ by default on dual-core devices\n\ttargets ${TARGET}.cm0\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 18 -expected-id 0x2e200069\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/pxa255.cfg",
    "content": "# PXA255 chip ... originally from Intel, PXA line was sold to Marvell.\n# This chip is now at end-of-life.  Final orders have been taken.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa255\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x69264013\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_CHIPNAME.cpu\n\n# PXA255 comes out of reset using 3.6864 MHz oscillator.\n# Until the PLL kicks in, keep the JTAG clock slow enough\n# that we get no errors.\nadapter speed 300\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 300 }\n\n# both TRST and SRST are *required* for debug\n# DCSR is often accessed with SRST active\nreset_config trst_and_srst separate srst_nogate\n\n# reset processing that works with PXA\nproc init_reset {mode} {\n\t# assert both resets; equivalent to power-on reset\n\tadapter assert trst assert srst\n\n\t# drop TRST after at least 32 cycles\n\tsleep 1\n\tadapter deassert trst assert srst\n\n\t# minimum 32 TCK cycles to wake up the controller\n\truntest 50\n\n\t# now the TAP will be responsive; validate scanchain\n\tjtag arp_init\n\n\t# ... and take it out of reset\n\tadapter deassert trst deassert srst\n}\n\nproc jtag_init {} {\n\tinit_reset startup\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/pxa270.cfg",
    "content": "#Marvell/Intel PXA270 Script\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa270\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n#IDs for pxa270. Are there more?\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x49265013\n}\n\nif { [info exists CPUTAPID2] } {\n   set _CPUTAPID2 $CPUTAPID2\n} else {\n  # set useful default\n   set _CPUTAPID2 0x79265013\n}\n\nif { [info exists CPUTAPID3] } {\n   set _CPUTAPID2 $CPUTAPID3\n} else {\n  # set useful default\n   set _CPUTAPID3 0x89265013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n# maps to PXA internal RAM. If you are using a PXA255\n# you must initialize SDRAM or leave this option off\n$_TARGETNAME configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/pxa3xx.cfg",
    "content": "# Marvell PXA3xx\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa3xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# IDs for all currently known PXA3xx chips\nif { [info exists CPUTAPID_PXA30X_A0] } {\n   set _CPUTAPID_PXA30X_A0 $CPUTAPID_PXA30X_A0\n} else {\n   set _CPUTAPID_PXA30X_A0 0x0E648013\n}\nif { [info exists CPUTAPID_PXA30X_A1] } {\n   set _CPUTAPID_PXA30X_A1 $CPUTAPID_PXA30X_A1\n} else {\n   set _CPUTAPID_PXA30X_A1 0x1E648013\n}\nif { [info exists CPUTAPID_PXA31X_A0] } {\n   set _CPUTAPID_PXA31X_A0 $CPUTAPID_PXA31X_A0\n} else {\n   set _CPUTAPID_PXA31X_A0 0x0E649013\n}\nif { [info exists CPUTAPID_PXA31X_A1] } {\n   set _CPUTAPID_PXA31X_A1 $CPUTAPID_PXA31X_A1\n} else {\n   set _CPUTAPID_PXA31X_A1 0x1E649013\n}\nif { [info exists CPUTAPID_PXA31X_A2] } {\n   set _CPUTAPID_PXA31X_A2 $CPUTAPID_PXA31X_A2\n} else {\n   set _CPUTAPID_PXA31X_A2 0x2E649013\n}\nif { [info exists CPUTAPID_PXA31X_B0] } {\n   set _CPUTAPID_PXA31X_B0 $CPUTAPID_PXA31X_B0\n} else {\n   set _CPUTAPID_PXA31X_B0 0x3E649013\n}\nif { [info exists CPUTAPID_PXA32X_B1] } {\n   set _CPUTAPID_PXA32X_B1 $CPUTAPID_PXA32X_B1\n} else {\n   set _CPUTAPID_PXA32X_B1 0x5E642013\n}\nif { [info exists CPUTAPID_PXA32X_B2] } {\n   set _CPUTAPID_PXA32X_B2 $CPUTAPID_PXA32X_B2\n} else {\n   set _CPUTAPID_PXA32X_B2 0x6E642013\n}\nif { [info exists CPUTAPID_PXA32X_C0] } {\n   set _CPUTAPID_PXA32X_C0 $CPUTAPID_PXA32X_C0\n} else {\n   set _CPUTAPID_PXA32X_C0 0x7E642013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 11 -ircapture 0x1 -irmask 0x7f \\\n\t-expected-id $_CPUTAPID_PXA30X_A0 \\\n\t-expected-id $_CPUTAPID_PXA30X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A0 \\\n\t-expected-id $_CPUTAPID_PXA31X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A2 \\\n\t-expected-id $_CPUTAPID_PXA31X_B0 \\\n\t-expected-id $_CPUTAPID_PXA32X_B1 \\\n\t-expected-id $_CPUTAPID_PXA32X_B2 \\\n\t-expected-id $_CPUTAPID_PXA32X_C0\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# work area in internal RAM.\n$_TARGETNAME configure -work-area-phys 0x5c030000 -work-area-size 0x10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/qualcomm_qca4531.cfg",
    "content": "# The QCA4531 is a two stream (2x2) 802.11b/g/n single-band programmable\n# Wi-Fi System-on-Chip (SoC) for the Internet of Things (IoT).\n#\n# Product page:\n# https://www.qualcomm.com/products/qca4531\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 650 MHz\n# - External 16-bit DDR1, operating at up to 200 MHz, DDR2 operating at up\n#   to 300 MHz\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin B56 on the SoC will reset internal JTAG logic.\n#\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO1, (B23)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO2, (A28)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO3, (A29)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (B56)\tInput only\n# SYS_RST_L\tGPIO17, (A79)\tOutput reset request or GPIO\n#   Bootstrap\n# JTAG_MODE\tGPIO16, (A78)\t0 - JTAG (Default); 1 - EJTAG\n# DDR_SELECT\tGPIO10, (A57)\t0 - DDR2; 1 - DDR1\n#   UART\n# UART0_SOUT\tGPIO10, (A57)\n# UART0_SIN\tGPIO9, (B49)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME qca4531\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\n# Section with helpers which can be used by boards\nproc qca4531_ddr2_550_550_init {} {\n\t# Clear reset flags for different SoC components\n\tmww 0xb806001c 0xfeceffff\n\tmww 0xb806001c 0xeeceffff\n\tmww 0xb806001c 0xe6ceffff\n\n\t# PMU configurations\n\t# Internal Switcher\n\tmww 0xb8116c40 0x633c8176\n\t# Increase the DDR voltage\n\tmww 0xb8116c44 0x10200000\n\t# XTAL Configurations\n\tmww 0xb81162c0 0x4b962100\n\tmww 0xb81162c4 0x480\n\tmww 0xb81162c8 0x04000144\n\t# Recommended PLL configurations\n\tmww 0xb81161c4 0x54086000\n\tmww 0xb8116244 0x54086000\n\n\t# PLL init\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x40001580\n\tmww 0xb8050004 0x40015800\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x00001580\n\tmww 0xb8050004 0x00015800\n\tmww 0xb8050008 0x01310000\n\tmww 0xb8050044 0x781003ff\n\tmww 0xb8050048 0x003c103f\n\n\t# DDR2 init\n\tmww 0xb8000108 0x401f0042\n\tmww 0xb80000b8 0x0000166d\n\tmww 0xb8000000 0xcfaaf33b\n\tmww 0xb800015c 0x0000000f\n\tmww 0xb8000004 0xa272efa8\n\tmww 0xb8000018 0x0000ffff\n\tmww 0xb80000c4 0x74444444\n\tmww 0xb80000c8 0x00000444\n\tmww 0xb8000004 0xa210ee28\n\tmww 0xb8000004 0xa2b2e1a8\n\tmww 0xb8000010 0x8\n\tmww 0xb80000bc 0x0\n\tmww 0xb8000010 0x10\n\tmww 0xb80000c0 0x0\n\tmww 0xb8000010 0x40\n\tmww 0xb800000c 0x2\n\tmww 0xb8000010 0x2\n\tmww 0xb8000008 0xb43\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\tmww 0xb8000008 0xa43\n\tmww 0xb8000010 0x1\n\tmww 0xb800000c 0x382\n\tmww 0xb8000010 0x2\n\tmww 0xb800000c 0x402\n\tmww 0xb8000010 0x2\n\tmww 0xb8000014 0x40be\n\tmww 0xb800001C 0x20\n\tmww 0xb8000020 0x20\n\tmww 0xb80000cc 0xfffff\n\n\t# UART GPIO programming\n\tmww 0xb8040000 0xff30b\n\tmww 0xb8040044 0x908\n\tmww 0xb8040034 0x160000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/quark_d20xx.cfg",
    "content": "if { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x38289013\n}\n\njtag newtap quark_d20xx quark -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable\njtag newtap quark_d20xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e786013 -enable\n\nproc quark_d20xx_tapenable {} {\n\techo \"enabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 1\n\truntest 10\n}\n\nproc quark_d20xx_tapdisable {} {\n\techo \"disabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 0\n\truntest 10\n}\n\nproc quark_d20xx_setup {} {\n\tjtag tapenable quark_d20xx.quark\n}\n\njtag configure quark_d20xx.quark -event tap-enable \\\n   \"quark_d20xx_tapenable\"\n\njtag configure quark_d20xx.quark -event tap-disable \\\n   \"quark_d20xx_tapdisable\"\n\ntarget create quark_d20xx.quark quark_d20xx -endian little -chain-position quark_d20xx.quark\n\nquark_d20xx.quark configure -event reset-start {\n\t# need to halt the target to write to memory\n\tif {[quark_d20xx.quark curstate] ne \"halted\"} { halt }\n\t# set resetbreak via the core tap\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x1\n\t# trigger a warm reset\n\tmww 0xb0800570 0x2\n\t# clear resetbreak\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x0\n}\n\njtag configure quark_d20xx.quark -event setup \\\n   \"quark_d20xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/quark_x10xx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME quark_x10xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x18289013\n}\n\njtag newtap quark_x10xx cpu   -irlen 8  -irmask 0xff  -expected-id   $_CPUTAPID  -disable\njtag newtap quark_x10xx cltap -irlen 8  -irmask 0xff  -expected-id   0x0e681013  -enable\n\n#openocd puts tap at front of chain not end of chain\nproc quark_x10xx_tapenable {} {\n\techo \"enabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 1\n\truntest 10\n}\n\nproc quark_x10xx_tapdisable {} {\n\techo \"disabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 0\n\truntest 10\n}\n\nproc quark_x10xx_setup {} {\n\tjtag tapenable quark_x10xx.cpu\n}\n\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"quark_x10xx_tapenable\"\n\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n   \"quark_x10xx_tapdisable\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create quark_x10xx.cpu quark_x10xx -endian $_ENDIAN -chain-position quark_x10xx.cpu\n\njtag configure $_CHIPNAME.cpu -event setup \\\n   \"quark_x10xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/readme.txt",
    "content": "Prerequisites:\nThe users of OpenOCD as well as computer programs interacting with OpenOCD are expecting that certain commands\ndo the same thing across all the targets.\n\nRules to follow when writing scripts:\n\n1. The configuration script should be defined such as , for example, the following sequences are working:\n\treset\n\tflash info <bank>\nand\n\treset\n\tflash erase_address <start> <len>\nand\n\treset init\n\tload\n\nIn most cases this can be accomplished by specifying the default startup mode as reset_init (target command\nin the configuration file).\n\n2. If the target is correctly configured, flash must be writable without any other helper commands. It is\nassumed that all write-protect mechanisms should be disabled.\n\n3. The configuration scripts should be defined such as the binary that was written to flash verifies\n(turn off remapping, checksums, etc...)\n\nflash write_image [file] <parameters>\nverify_image [file] <parameters>\n\n4. adapter speed sets the maximum speed (or alternatively RCLK). If invoked\nmultiple times only the last setting is used.\n\ninterface/xxx.cfg files are always executed *before* target/xxx.cfg\nfiles, so any adapter speed in interface/xxx.cfg will be overridden by\ntarget/xxx.cfg. adapter speed in interface/xxx.cfg would then, effectively,\nset the default JTAG speed.\n\nNote that a target/xxx.cfg file can invoke another target/yyy.cfg file,\nso one can create target subtype configurations where e.g. only\namount of DRAM, oscillator speeds differ and having a single\nconfig file for the default/common settings.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_r7s72100.cfg",
    "content": "# Renesas RZ/A1H\n# https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME r7s72100\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\n\n# Configuring only one core using DAP.\n# Base addresses of cores:\n#  core 0  -  0x80030000\nset _TARGETNAME $_CHIPNAME.ca9\ndap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME} cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x80030000\n\ntargets ${_TARGETNAME}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_rcar_gen2.cfg",
    "content": "# Renesas R-Car Generation 2 SOCs\n# - There are a combination of Cortex-A15s and Cortex-A7s for each Gen2 SOC\n# - Each SOC can boot through any of the, up to 2, core types that it has\n#   e.g. H2 can boot through Cortex-A15 or Cortex-A7\n\n# Supported Gen2 SOCs and their cores:\n# H2:  Cortex-A15 x 4, Cortex-A7 x 4\n# M2:  Cortex-A15 x 2\n# V2H: Cortex-A15 x 2\n# M2N: Cortex-A15 x 2\n# E2:                  Cortex-A7 x 2\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H2')\n# BOOT_CORE: Selects the booting core. 'CA15', or 'CA7'\n#            Defaults to 'CA15' if the SOC has one, else defaults to 'CA7'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H2\n}\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH2 {\n\t\tset _CHIPNAME r8a7790\n\t\tset _num_ca15 4\n\t\tset _num_ca7 4\n\t\tset _boot_core CA15\n\t}\n\tM2 {\n\t\tset _CHIPNAME r8a7791\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tV2H {\n\t\tset _CHIPNAME r8a7792\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tM2N {\n\t\tset _CHIPNAME r8a7793\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tE2 {\n\t\tset _CHIPNAME r8a7794\n\t\tset _num_ca15 0\n\t\tset _num_ca7 2\n\t\tset _boot_core CA7\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\necho \"\\t$_soc - $_num_ca15 CA15(s), $_num_ca7 CA7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000}\nset CA7_DBGBASE  {0x800F0000 0x800F2000 0x800F4000 0x800F6000}\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_ca {core_name dbgbase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tset _command \"target create $_TARGETNAME cortex_a -dap $_DAPNAME \\\n\t\t\t-coreid $_core -dbgbase [lindex $dbgbase $_core]\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA15] } {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 1\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n} elseif { [string equal $_boot_core CA7] } {\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 1\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n} else {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_rcar_gen3.cfg",
    "content": "# Renesas R-Car Generation 3 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, and Cortex-R7 for each Gen3 SOC\n# - Each SOC can boot through any of the, up to 3, core types that it has\n#   e.g. H3 can boot through Cortex-A57, Cortex-A53, or Cortex-R7\n\n# Supported Gen3 SOCs and their cores:\n#  H3: Cortex-A57 x 4, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3W: Cortex-A57 x 2, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3N: Cortex-A57 x 2,                 Cortex-R7 x 2 (Lock-Step)\n# V3U:                 Cortex-A76 x 8, Cortex-R52 x2 (Lock-Step)\n# V3H:                 Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# V3M:                 Cortex-A53 x 2, Cortex-R7 x 2 (Lock-Step)\n#  E3:                 Cortex-A53 x 1, Cortex-R7 x 2 (Lock-Step)\n#  D3:                 Cortex-A53 x 1\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H3')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53', or 'CR7'\n#            Defaults to 'CA57' if the SOC has one, else defaults to 'CA53'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H3\n}\n\nset _num_ca53 0\nset _num_ca57 0\nset _num_ca76 0\nset _num_cr52 0\nset _num_cr7 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH3 {\n\t\tset _CHIPNAME r8a77950\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3W {\n\t\tset _CHIPNAME r8a77960\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3N {\n\t\tset _CHIPNAME r8a77965\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tV3M {\n\t\tset _CHIPNAME r8a77970\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tV3H {\n\t\tset _CHIPNAME r8a77980\n\t\tset _num_ca57 0\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tE3 {\n\t\tset _CHIPNAME r8a77990\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tD3 {\n\t\tset _CHIPNAME r8a77995\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 0\n\t\tset _boot_core CA53\n\t}\n\tV3U {\n\t\tset _CHIPNAME r8a779a0\n\t\tset _num_ca76 8\n\t\tset _num_cr52 1\n\t\tset _boot_core CA76\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\necho \"\\t$_soc - $_num_ca76 CA76(s), $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr52 CR52(s), $_num_cr7 CR7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA76_DBGBASE {0x81410000 0x81510000 0x81610000 0x81710000 0x81c10000 0x81d10000 0x81e10000 0x81f10000}\nset CA76_CTIBASE {0x81420000 0x81520000 0x81620000 0x81720000 0x81c20000 0x81d20000 0x81e20000 0x81f20000}\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset CR52_DBGBASE 0x80c10000\nset CR52_CTIBASE 0x80c20000\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\tset _command \"target create $_TARGETNAME aarch64 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\nproc setup_cr7 {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase\n\t\tset _command \"target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase $dbgbase\"\n\t\tif { $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA76] } {\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 1\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 0\n} elseif { [string equal $_boot_core CA57] } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CA53] } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CR52] } {\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 1\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 0\n} else {\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_rcar_reset_common.cfg",
    "content": "# Renesas R-Car Gen2 Evaluation Board common settings\n\nreset_config trst_and_srst srst_nogate\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_rz_five.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/Five SoC\n#\n# General-purpose Microprocessors with RISC-V CPU Core (Andes AX45MP Single) (1.0 GHz)\n\ntransport select jtag\n\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME r9A07g043u\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_rz_g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/G2 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, Cortex-A55, Cortex-R7\n# and Cortex-M33 for each SOC\n# - Each SOC can boot through the Cortex-A5x cores\n\n# Supported RZ/G2 SOCs and their cores:\n# RZ/G2H:   Cortex-A57 x4, Cortex-A53 x4, Cortex-R7\n# RZ/G2M:   Cortex-A57 x2, Cortex-A53 x4, Cortex-R7\n# RZ/G2N:   Cortex-A57 x2,                Cortex-R7\n# RZ/G2E:                  Cortex-A53 x2, Cortex-R7\n# RZ/G2L:                  Cortex-A55 x2, Cortex-M33\n# RZ/G2LC:                 Cortex-A55 x2, Cortex-M33\n# RZ/G2UL:                 Cortex-A55 x1, Cortex-M33\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'G2L')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53' or 'CA55'\n\ntransport select jtag\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc G2L\n}\n\nset _num_ca57 0\nset _num_ca55 0\nset _num_ca53 0\nset _num_cr7 0\nset _num_cm33 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tG2H {\n\t\tset _CHIPNAME r8a774ex\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2M {\n\t\tset _CHIPNAME r8a774ax\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2N {\n\t\tset _CHIPNAME r8a774bx\n\t\tset _num_ca57 2\n\t\tset _num_ca53 0\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2E {\n\t\tset _CHIPNAME r8a774c0\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t\tset _ap_num 1\n\t}\n\tG2L {\n\t\tset _CHIPNAME r9a07g044l\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2LC {\n\t\tset _CHIPNAME r9a07g044c\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2UL {\n\t\tset _CHIPNAME r9a07g043u\n\t\tset _num_ca55 1\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\necho \"\\t$_soc - $_num_ca57 CA57(s), $_num_ca55 CA55(s), $_num_ca53 CA53(s), $_num_cr7 CR7(s), \\\n\t$_num_cm33 CM33(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID \\\n\t-ignore-version\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\necho \"$_CHIPNAME.cpu\"\n\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA55_DBGBASE {0x10E10000 0x10F10000}\nset CA55_CTIBASE {0x10E20000 0x10F20000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\nset CM33_DBGBASE 0xE000E000\nset CM33_CTIBASE 0xE0042000\n\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $::_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $::_DAPNAME -ap-num $::_ap_num \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\ttarget create $_TARGETNAME aarch64 -dap $::_DAPNAME \\\n\t\t\t-ap-num $::_ap_num -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\n\t\tif { $_core > 0 || $boot == 0 } {\n\t\t\t$_TARGETNAME configure -defer-examine\n\t\t}\n\t\tset ::smp_targets \"$::smp_targets $_TARGETNAME\"\n\t}\n}\n\nproc setup_cr7 {dbgbase ctibase} {\n\tset _TARGETNAME $::_CHIPNAME.r7\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $::_DAPNAME -ap-num 1 -baseaddr $ctibase\n\ttarget create $_TARGETNAME cortex_r4 -dap $::_DAPNAME \\\n\t\t-ap-num 1 -dbgbase $dbgbase -defer-examine\n}\n\nproc setup_cm33 {dbgbase ctibase} {\n        set _TARGETNAME $::_CHIPNAME.m33\n        set _CTINAME $_TARGETNAME.cti\n        cti create $_CTINAME -dap $::_DAPNAME -ap-num 2 -baseaddr $ctibase\n        target create $_TARGETNAME cortex_m -dap $::_DAPNAME \\\n                -ap-num 2 -dbgbase $dbgbase -defer-examine\n}\n\n# Organize target list based on the boot core\nif { $_boot_core == \"CA57\" } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA53\" } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA55\" } {\n\tsetup_a5x a55 $CA55_DBGBASE $CA55_CTIBASE $_num_ca55 1\n\tsetup_cm33 $CM33_DBGBASE $CM33_CTIBASE\n}\necho \"SMP targets:$smp_targets\"\neval \"target smp $smp_targets\"\n\nif { $_soc == \"G2L\" || $_soc == \"G2LC\" || $_soc == \"G2UL\" } {\n\ttarget create $_CHIPNAME.axi_ap mem_ap -dap $_DAPNAME -ap-num 1\n}\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/renesas_s7g2.cfg",
    "content": "#\n# Renesas Synergy S7 G2 w/ ARM Cortex-M4 @ 240 MHz\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME s7g2\n}\n\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x5ba00477\n}\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x5ba02477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\t# 640 KB On-Chip SRAM\n\tset _WORKAREASIZE 0xa0000\n}\n\n$_TARGETNAME configure -work-area-phys 0x1ffe0000 \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/rk3308.cfg",
    "content": "# Rockchip RK3308 Target\n# https://rockchip.fr/RK3308%20datasheet%20V1.5.pdf\n# https://dl.radxa.com/rockpis/docs/hw/datasheets/Rockchip%20RK3308TRM%20V1.1%20Part1-20180810.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3308\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x2ba01477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.core\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x81010000\nset $_TARGETNAME.base(1) 0x81012000\nset $_TARGETNAME.base(2) 0x81014000\nset $_TARGETNAME.base(3) 0x81016000\n\nset $_TARGETNAME.cti(0) 0x81018000\nset $_TARGETNAME.cti(1) 0x81019000\nset $_TARGETNAME.cti(2) 0x8101a000\nset $_TARGETNAME.cti(3) 0x8101b000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\"\n\n    if { $_core != 0 } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n        set _command \"$_command -defer-examine\"\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # set _command \"$_command -rtos hwthread\"\n        set _command \"$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 \\\n                                -work-area-backup 0\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/rk3399.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Rockchip RK3399 Target\n# https://rockchip.fr/RK3399%20datasheet%20V1.8.pdf\n# https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.4%20Part1.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3399\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba02477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\nset _TARGETNAME $_CHIPNAME.lcore\n# declare the 6 main application cores\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x80030000\nset $_TARGETNAME.base(1) 0x80032000\nset $_TARGETNAME.base(2) 0x80034000\nset $_TARGETNAME.base(3) 0x80036000\nset $_TARGETNAME.cti(0) 0x80038000\nset $_TARGETNAME.cti(1) 0x80039000\nset $_TARGETNAME.cti(2) 0x8003a000\nset $_TARGETNAME.cti(3) 0x8003b000\n\n\nset _TARGETNAME $_CHIPNAME.bcore\nset $_TARGETNAME.base(4) 0x80210000\nset $_TARGETNAME.base(5) 0x80310000\nset $_TARGETNAME.cti(4) 0x80220000\nset $_TARGETNAME.cti(5) 0x80320000\n\nset _cores 6\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n    if {$_core < 4} {\n        set _TARGETNAME $_CHIPNAME.lcore\n    } else {\n        set _TARGETNAME $_CHIPNAME.bcore\n    }\n\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1\n\n    target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\n\n    if { $_core != 0 } {\n        ${_TARGETNAME}$_core configure -defer-examine\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # ${_TARGETNAME}$_core configure -rtos hwthread\"\n        ${_TARGETNAME}$_core configure -work-area-size 0x30000 -work-area-phys 0xff8c0000 \\\n                                -work-area-backup 0\n    }\n    set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n}\n\ntarget smp $_smp_command\n\ntargets rk3399.lcore0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/rp2040-core0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\ntransport select swd\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME rp2040\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x01002927\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nset _FLASHSIZE 0x200000\nset _FLASHBASE 0x10000000\nflash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n\n# srst does not exist; use SYSRESETREQ to perform a soft reset\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/samsung_s3c2410.cfg",
    "content": "# Found on the 'TinCanTools' Hammer board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that cannot set TRST/SRST separately\nreset_config trst_and_srst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x30800000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/samsung_s3c2440.cfg",
    "content": "# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor       : ARM920Tid(wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/samsung_s3c2450.cfg",
    "content": "# Target configuration for the Samsung 2450 system on chip\n# Processor       : ARM926ejs (wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2450.cpu tap/device found: 0x07926F0F\n\n\n# FIX!!! what to use here?\n#\n# RCLK?\n#\n# adapter speed 0\n#\n# Really low clock during reset?\n#\n# adapter speed 1\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME s3c2450\n}\n\nif { [info exists ENDIAN] } {\n  set _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n  set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n  set _CPUTAPID $CPUTAPID\n} else {\n  set _CPUTAPID 0x07926f0f\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xE -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# FIX!!!!! should this really use srst_pulls_trst?\n# With srst_pulls_trst \"reset halt\" will not reset into the\n# halted mode, but rather \"reset run\" and then halt the target.\n#\n# However, without \"srst_pulls_trst\", then \"reset halt\" produces weird\n# errors:\n# WARNING: unknown debug reason: 0x0\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/samsung_s3c4510.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c4510\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# This appears to be a \"Version 1\" arm7tdmi.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/samsung_s3c6410.cfg",
    "content": "# -*- tcl -*-\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n# [Duane Ellis 27/nov/2008: Above 0x0032409d appears to be copy/paste from other places]\n# [and I do not believe it to be accurate, hence the 0xffffffff below]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c6410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b76f0f\n}\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nadapter srst delay 500\njtag_ntrst_delay 500\n\n#reset configuration\nreset_config trst_and_srst\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/sharp_lh79532.cfg",
    "content": "reset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lh79532\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # sharp changed the number!\n   set _CPUTAPID 0x00002061\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/sim3x.cfg",
    "content": "#\n# Silicon Laboratories SiM3x Cortex-M3\n#\n\n# SiM3x devices support both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME SiM3x\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nif { [info exists CPURAMSIZE] } {\n  set _CPURAMSIZE $CPURAMSIZE\n} else {\n# Minimum size of RAM in the Silicon Labs product matrix (8KB)\n\tset _CPURAMSIZE 0x2000\n}\n\nif { [info exists CPUROMSIZE] } {\n  set _CPUROMSIZE $CPUROMSIZE\n} else {\n# Minimum size of FLASH in the Silicon Labs product matrix (32KB)\n\tset _CPUROMSIZE 0x8000\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE $_CPURAMSIZE\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/smp8634.cfg",
    "content": "# script for Sigma Designs SMP8634 (eventually even SMP8635)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME smp8634\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x08630001\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/snps_em_sk_fpga.cfg",
    "content": "#  Copyright (C) 2014-2015,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xilinx Spartan-6 XC6SLX45  FPGA on EM Starter Kit v1.\n# Xilinx Spartan-6 XC6SLX150 FPGA on EM Starter Kit v2.\n#\n\nsource [find cpu/arc/em.tcl]\n\nset _CHIPNAME arc-em\nset _TARGETNAME $_CHIPNAME.cpu\n\n# EM SK IDENTITY is 0x200444b1\n# EM SK v2 IDENTITY is 0x200044b1\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -expected-id 0x200444b1 \\\n  -expected-id 0x200044b1\n\nset _coreid 0\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME \\\n  -coreid 0 -dbgbase $_dbgbase -endian little\n\n# There is no SRST, so do a software reset\n$_TARGETNAME configure -event reset-assert \"arc_em_reset $_TARGETNAME\"\n\narc_em_init_regs\n\n# vim:ft=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# HS Development Kit SoC.\n#\n# Contains quad-core ARC HS38.\n#\n\nsource [find cpu/arc/hs.tcl]\n\nset _coreid 0\nset _dbgbase [expr {$_coreid << 13}]\n\n# CHIPNAME will be used to choose core family (600, 700 or EM). As far as\n# OpenOCD is concerned EM and HS are identical.\nset _CHIPNAME arc-em\n\n# OpenOCD discovers JTAG TAPs in reverse order.\n\n# ARC HS38 core 4\nset _TARGETNAME $_CHIPNAME.cpu4\njtag newtap $_CHIPNAME cpu4 -irlen 4 -ircapture 0x1 -expected-id 0x200c24b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n# Flush L2$.\n$_TARGETNAME configure -event reset-assert \"arc_hs_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 4.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 3\nset _TARGETNAME $_CHIPNAME.cpu3\njtag newtap $_CHIPNAME cpu3 -irlen 4 -ircapture 0x1 -expected-id 0x200824b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 3.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 2\nset _TARGETNAME $_CHIPNAME.cpu2\njtag newtap $_CHIPNAME cpu2 -irlen 4 -ircapture 0x1 -expected-id 0x200424b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 2.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 1\nset _TARGETNAME $_CHIPNAME.cpu1\njtag newtap $_CHIPNAME cpu1 -irlen 4 -ircapture 0x1 -expected-id 0x200024b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\narc_hs_init_regs\n\n# Enable L2 cache support for core 1.\n$_TARGETNAME arc cache l2 auto 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/spear3xx.cfg",
    "content": "# Target configuration for the ST SPEAr3xx family of system on chip\n# Supported SPEAr300, SPEAr310, SPEAr320\n# http://www.st.com/spear\n#\n# Processor: ARM926ejs\n# Info:      JTAG tap: spear3xx.cpu tap/device found: 0x07926041\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME spear3xx\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x07926041\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 \\\n\t-expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# SPEAr3xx has a 8K block of sram @ 0xd280.0000\n# REVISIT: what OS puts virtual address equal to phys?\n$_TARGETNAME configure \\\n\t-work-area-virt 0xd2800000 \\\n\t-work-area-phys 0xd2800000 \\\n\t-work-area-size 0x2000 \\\n\t-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stellaris.cfg",
    "content": "# TI/Luminary Stellaris LM3S chip family\n\n# Some devices have errata in returning their device class.\n# DEVICECLASS is provided as a manual override\n# Manual setting of a device class of 0xff is not allowed\n\nglobal _DEVICECLASS\n\nif { [info exists DEVICECLASS] } {\n   set _DEVICECLASS $DEVICECLASS\n} else {\n   set _DEVICECLASS 0xff\n}\n\n# Luminary chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# For now we ignore the SPI and UART options, which\n# are usable only for ISP style initial flash programming.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lm3s\n}\n\n# CPU TAP ID 0x1ba00477 for early Sandstorm parts\n# CPU TAP ID 0x2ba00477 for later SandStorm parts, e.g. lm3s811 Rev C2\n# CPU TAP ID 0x3ba00477 for Cortex-M3 r1p2 (on Fury, DustDevil)\n# CPU TAP ID 0x4ba00477 for Cortex-M3 r2p0 (on Tempest, Firestorm)\n# CPU TAP ID 0x4ba00477 for Cortex-M4 r0p1 (on Blizzard)\n# ... we'll ignore the JTAG version field, rather than list every\n# chip revision that turns up.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0ba00477\n}\n\n# SWD DAP, and JTAG TAP, take same params for now;\n# ... even though SWD ignores all except TAPID, and\n# JTAG shouldn't need anything more then irlen. (and TAPID).\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf \\\n    -expected-id $_CPUTAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   # default to 2K working area\n   set _WORKAREASIZE 0x800\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# 8K working area at base of ram, not backed up\n#\n# NOTE: you may need or want to reconfigure the work area;\n# some parts have just 6K, and you may want to use other\n# addresses (at end of mem not beginning) or back it up.\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\n# JTAG speed ... slow enough to work with a 12 MHz RC oscillator;\n# LM3S parts don't support RTCK\n#\n# NOTE: this may be increased by a reset-init handler, after it\n# configures and enables the PLL.  Or you might need to decrease\n# this, if you're using a slower clock.\nadapter speed 500\n\nsource [find mem_helper.tcl]\n\nproc reset_peripherals {family} {\n\n\tsource [find chip/ti/lm3s/lm3s.tcl]\n\n\techo \"Resetting Core Peripherals\"\n\n\t# Disable the PLL and the system clock divider (nop if disabled)\n\tmmw $SYSCTL_RCC 0 $SYSCTL_RCC_USESYSDIV\n\tmmw $SYSCTL_RCC2 $SYSCTL_RCC2_BYPASS2 0\n\n\t# RCC and RCC2 to their reset values\n\tmww $SYSCTL_RCC [expr {0x078e3ad0 | ([mrw $SYSCTL_RCC] & $SYSCTL_RCC_MOSCDIS)}]\n\tmww $SYSCTL_RCC2 0x07806810\n\tmww $SYSCTL_RCC 0x078e3ad1\n\n\t# Reset the deep sleep clock configuration register\n\tmww $SYSCTL_DSLPCLKCFG 0x07800000\n\n\t# Reset the clock gating registers\n\tmww $SYSCTL_RCGC0 0x00000040\n\tmww $SYSCTL_RCGC1 0\n\tmww $SYSCTL_RCGC2 0\n\tmww $SYSCTL_SCGC0 0x00000040\n\tmww $SYSCTL_SCGC1 0\n\tmww $SYSCTL_SCGC2 0\n\tmww $SYSCTL_DCGC0 0x00000040\n\tmww $SYSCTL_DCGC1 0\n\tmww $SYSCTL_DCGC2 0\n\n\t# Reset the remaining SysCtl registers\n\tmww $SYSCTL_PBORCTL 0\n\tmww $SYSCTL_IMC 0\n\tmww $SYSCTL_GPIOHBCTL 0\n\tmww $SYSCTL_MOSCCTL 0\n\tmww $SYSCTL_PIOSCCAL 0\n\tmww $SYSCTL_I2SMCLKCFG 0\n\n\t# Reset the peripherals\n\tmww $SYSCTL_SRCR0 0xffffffff\n\tmww $SYSCTL_SRCR1 0xffffffff\n\tmww $SYSCTL_SRCR2 0xffffffff\n\tmww $SYSCTL_SRCR0 0\n\tmww $SYSCTL_SRCR1 0\n\tmww $SYSCTL_SRCR2 0\n\n\t# Clear any pending SysCtl interrupts\n\tmww $SYSCTL_MISC 0xffffffff\n\n\t# Wait for any pending flash operations to complete\n\twhile {[expr {[mrw $FLASH_FMC] & 0xffff}] != 0} { sleep 1 }\n\twhile {[expr {[mrw $FLASH_FMC2] & 0xffff}] != 0} { sleep 1 }\n\n\t# Reset the flash controller registers\n\tmww $FLASH_FMA 0\n\tmww $FLASH_FCIM 0\n\tmww $FLASH_FCMISC 0xffffffff\n\tmww $FLASH_FWBVAL 0\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 500\n\n\t#\n\t# When nRST is asserted on most Stellaris devices, it clears some of\n\t# the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;\n\t# and OpenOCD depends on those TRMs.  So we won't use SRST on those\n\t# chips.  (Only power-on reset should affect debug state, beyond a\n\t# few specified bits; not the chip's nRST input, wired to SRST.)\n\t#\n\t# REVISIT current errata specs don't seem to cover this issue.\n\t# Do we have more details than this email?\n\t#   https://lists.berlios.de/pipermail\n\t#\t/openocd-development/2008-August/003065.html\n\t#\n\n\tglobal _DEVICECLASS\n\n\tif {$_DEVICECLASS != 0xff} {\n\t   set device_class $_DEVICECLASS\n\t} else {\n\t   set device_class [expr {([mrw 0x400fe000] >> 16) & 0xff}]\n\t}\n\n\tif {$device_class == 0 || $device_class == 1 ||\n\t\t$device_class == 3 || $device_class == 5 || $device_class == 0xa} {\n\t\tif {![using_hla]} {\n\t\t   # Sandstorm, Fury, DustDevil, Blizzard and Snowflake are able to use NVIC SYSRESETREQ\n\t\t   cortex_m reset_config sysresetreq\n\t\t}\n\t} else {\n\t\tif {![using_hla]} {\n\t\t   # Tempest and Firestorm default to using NVIC VECTRESET\n\t\t   # peripherals will need resetting manually, see proc reset_peripherals\n\t\t   cortex_m reset_config vectreset\n\t\t}\n\t\t# reset peripherals, based on code in\n\t\t# http://www.ti.com/lit/er/spmz573a/spmz573a.pdf\n\t\treset_peripherals $device_class\n\t}\n}\n\n# flash configuration ... autodetects sizes, autoprobed\nflash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f0x.cfg",
    "content": "# script for stm32f0x family\n\n#\n# stm32 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n\tset _FLASH_SIZE $FLASH_SIZE\n} else {\n\t# autodetect size\n\tset _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # See STM Document RM0091\n  # Section 29.5.3\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f0x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f0x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\n\t# Stop watchdog counters during halt\n\tmmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f0x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 6 (48 MHz)\n\tmww 0x40021004 0x00100000   ;# RCC_CFGR = PLLMUL[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON\n\tmww 0x40022000 0x00000011   ;# FLASH_ACR = PRFTBE | LATENCY[0]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f1x.cfg",
    "content": "# script for stm32f1x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f1x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some STM32F100s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0008 Section 26.6.3\n      set _CPUTAPID 0x3ba00477\n   } {\n      # this is the SW-DP tap id not the jtag tap id\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |\n\t#              DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000307 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f2x.cfg",
    "content": "# script for stm32f2x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f2x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0033\n      # Section 32.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f3x.cfg",
    "content": "# script for stm32f3x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f3x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0316\n      # Section 29.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f3x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f3x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\n\t# Stop watchdog counters during halt\n\tmmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f3x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 8 (64 MHz)\n\tmww 0x40021004 0x00380400   ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON\n\tmww 0x40022000 0x00000012   ;# FLASH_ACR = PRFTBE | LATENCY[1]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init }\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xe0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f4x.cfg",
    "content": "# script for stm32f4x family\n\n#\n# stm32f4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (Available RAM in smallest device STM32F410)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0090\n      # Section 38.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x40021000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x40021008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x40021000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x40021008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x40021000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x40021008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure PLL to boost clock to HSI x 4 (64 MHz)\n\tmww 0x40023804 0x08012008   ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P)\n\tmww 0x40023C00 0x00000102   ;# FLASH_ACR = PRFTBE | 2(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32f7x.cfg",
    "content": "# script for stm32f7x family\n\n#\n# stm32f7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f7x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 128kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x20000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0385\n      # Section 40.6.3 - corresponds to Cortex-M7 with FPU r0p0\n      set _CPUTAPID 0x5ba00477\n   } {\n      set _CPUTAPID 0x5ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1ff0f000 0 0 0 $_TARGETNAME\n\n# On the STM32F7, the Flash is mapped at address 0x08000000 via the AXI and\n# also address 0x00200000 via the ITCM. The former mapping is read-write in\n# hardware, while the latter is read-only. By presenting an alias, we\n# accomplish two things:\n# (1) We allow writing at 0x00200000 (because the alias acts identically to the\n#     original bank), which allows code intended to run from that address to\n#     also be linked for loading at that address, simplifying linking.\n# (2) We allow the proper memory map to be delivered to GDB, which will cause\n#     it to use hardware breakpoints at the 0x00200000 mapping (correctly\n#     identifying it as Flash), which it would otherwise not do. Configuring\n#     the Flash via ITCM alias as virtual\nflash bank $_CHIPNAME.itcm-flash.alias virtual 0x00200000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# Use hardware reset.\n#\n# This target is compatible with connect_assert_srst, which may be set in a\n# board file.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# If the HSE was previously enabled and the external clock source\n\t# disappeared, RCC_CR.HSERDY can get stuck at 1 and the PLL cannot be\n\t# properly switched back to HSI. This situation persists even over a system\n\t# reset, including a pin reset via SRST. However, activating the clock\n\t# security system will detect the problem and clear HSERDY to 0, which in\n\t# turn allows the PLL to switch back to HSI properly. Since we just came\n\t# out of reset, HSEON should be 0. If HSERDY is 1, then this situation must\n\t# have happened; in that case, activate the clock security system to clear\n\t# HSERDY.\n\tif {[mrw 0x40023800] & 0x00020000} {\n\t\tmmw 0x40023800 0x00090000 0 ;# RCC_CR = CSSON | HSEON\n\t\tsleep 10                    ;# Wait for CSS to fire, if it wants to\n\t\tmmw 0x40023800 0 0x00090000 ;# RCC_CR &= ~CSSON & ~HSEON\n\t\tmww 0x4002380C 0x00800000   ;# RCC_CIR = CSSC\n\t\tsleep 1                     ;# Wait for CSSF to clear\n\t}\n\n\t# If the clock security system fired, it will pend an NMI. A pending NMI\n\t# will cause a bad time for any subsequent executing code, such as a\n\t# programming algorithm.\n\tif {[mrw 0xE000ED04] & 0x80000000} {\n\t\t# ICSR.NMIPENDSET reads as 1. Need to clear it. A pending NMI can’t be\n\t\t# cleared by any normal means (such as ICSR or NVIC). It can only be\n\t\t# cleared by entering the NMI handler or by resetting the processor.\n\t\techo \"[target current]: Clock security system generated NMI. Clearing.\"\n\n\t\t# Keep the old DEMCR value.\n\t\tset old [mrw 0xE000EDFC]\n\n\t\t# Enable vector catch on reset.\n\t\tmww 0xE000EDFC 0x01000001\n\n\t\t# Issue local reset via AIRCR.\n\t\tmww 0xE000ED0C 0x05FA0001\n\n\t\t# Restore old DEMCR value.\n\t\tmww 0xE000EDFC $old\n\t}\n\n\t# Configure PLL to boost clock to HSI x 10 (160 MHz)\n\tmww 0x40023804 0x08002808   ;# RCC_PLLCFGR 16 Mhz /10 (M) * 128 (N) /2(P)\n\tmww 0x40023C00 0x00000107   ;# FLASH_ACR = PRFTBE | 7(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmww 0x40023808 0x00009400   ;# RCC_CFGR_PPRE1 = 5(div 4), PPRE2 = 4(div 2)\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost SWD frequency\n\t# Do not boost JTAG frequency and slow down JTAG memory access or flash write algo\n\t# suffers from DAP WAITs\n\tif {[using_jtag]} {\n\t\t[[target current] cget -dap] memaccess 16\n\t} {\n\t\tadapter speed 8000\n\t}\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32g0x.cfg",
    "content": "# script for stm32g0x family\n\n#\n# stm32g0 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x1000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# Section 37.5.5 - corresponds to Cortex-M0+\n\tset _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32g0x_default_reset_start {} {\n\t# Reset clock is HSI16 (16 MHz)\n\tadapter speed 2000\n}\n\nproc stm32g0x_default_examine_end {} {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0x40015804 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n\nproc stm32g0x_default_reset_init {} {\n\t# Increase clock to 64 Mhz\n\tmmw 0x40022000 0x00000002 0x00000005\t;# FLASH_ACR: Latency = 2\n\tmww 0x4002100C 0x30000802\t\t\t\t;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2\n\tmmw 0x40021000 0x01000000 0x00000000\t;# RCC_CR |= PLLON\n\tmmw 0x40021008 0x00000002 0x00000005\t;# RCC_CFGR: SW=PLLRCLK\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32g4x.cfg",
    "content": "# script for stm32g4x family\n\n#\n# stm32g4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest current target has 32kB ram, use 16kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# See STM Document RM0440\n\t\t# Section 46.6.3 - corresponds to Cortex-M4 r0p1\n\t\tset _CPUTAPID 0x4ba00477\n\t} {\n\t\tset _CPUTAPID 0x2ba01477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n\tset a [llength [flash list]]\n\tset _QSPINAME $_CHIPNAME.qspi\n\tflash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with HSION | HSIRDY.\n\t# Use HSI 16 MHz clock, compliant even with VOS == 2.\n\t# 1 WS compliant with VOS == 2 and 16 MHz.\n\tmmw 0x40022000 0x00000001 0x0000000E\t;# FLASH_ACR: Latency = 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# RCC_CR |= HSION\n\tmmw 0x40021008 0x00000001 0x00000002\t;# RCC_CFGR: SW=HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is HSI (16 MHz)\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32h7x.cfg",
    "content": "# script for stm32h7x family\n\n#\n# stm32h7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32h7x\n}\n\nif { [info exists DUAL_BANK] } {\n\tset $_CHIPNAME.DUAL_BANK $DUAL_BANK\n\tunset DUAL_BANK\n} else {\n\tset $_CHIPNAME.DUAL_BANK 0\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists USE_CTI] } {\n\tset $_CHIPNAME.USE_CTI $USE_CTI\n\tunset USE_CTI\n} else {\n\tset $_CHIPNAME.USE_CTI 0\n}\n\n# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0\nif { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } {\n\techo \"Warning : could not use CTI with a single core device, CTI is disabled\"\n\tset $_CHIPNAME.USE_CTI 0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n\t  set _CPUTAPID 0x6ba00477\n   } {\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nif {![using_hla]} {\n\t# STM32H7 provides an APB-AP at access port 2, which allows the access to\n\t# the debug and trace features on the system APB System Debug Bus (APB-D).\n\ttarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\n\tswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00E3000\n\ttpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00F5000\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0\n\n$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0\n\nif {[set $_CHIPNAME.DUAL_BANK]} {\n\tflash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3\n\n\t$_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {[set $_CHIPNAME.DUAL_BANK]} {\n\t\tflash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1\n\t}\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_CHIPNAME.cpu0 0x5200A000\n   }\n}\n\n# Clock after reset is HSI at 64 MHz, no need of PLL\nadapter speed 1800\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# use hardware reset\n#\n# The STM32H7 does not support connect_assert_srst mode because the AXI is\n# unavailable while SRST is asserted, and that is used to access the DBGMCU\n# component at 0x5C001000 in the examine-end event handler.\n#\n# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead\n# of the default AP0, and that works with SRST asserted; however, nonzero AP\n# usage does not work with HLA, so is not done by default. That change could be\n# made in a local configuration file if connect_assert_srst mode is needed for\n# a specific application and a non-HLA adapter is in use.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n\n\tif {[set $_CHIPNAME.DUAL_CORE]} {\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable D3 and D1 DBG clocks\n\t# DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00600000 0\n\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D1 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000007 0\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D2 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000038 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB3FZ1 |= WWDG1\n\tstm32h7x_dbgmcu_mmw 0x034 0x00000040 0\n\t# DBGMCU_APB1LFZ1 |= WWDG2\n\tstm32h7x_dbgmcu_mmw 0x03C 0x00000800 0\n\t# DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2\n\tstm32h7x_dbgmcu_mmw 0x054 0x000C0000 0\n\n\t# Enable clock for tracing\n\t# DBGMCU_CR |= TRACECLKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00100000 0\n\n\t# RM0399 (id 0x450) M7+M4 with SWO Funnel\n\t# RM0433 (id 0x450) M7 with SWO Funnel\n\t# RM0455 (id 0x480) M7 without SWO Funnel\n\t# RM0468 (id 0x483) M7 without SWO Funnel\n\t# Enable CM7 and CM4 slave ports in SWO trace Funnel\n\t# Works ok also on devices single core and without SWO funnel\n\t# Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF\n\t# SWTF_CTRL |= ENS0 | ENS1\n\tstm32h7x_dbgmcu_mmw 0x3000 0x00000003 0\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# Clock after reset is HSI at 64 MHz, no need of PLL\n\tadapter speed 4000\n}\n\n# get _CHIPNAME from current target\nproc stm32h7x_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\t$_CHIPNAME.cpu1 configure -event examine-end {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tglobal $_CHIPNAME.USE_CTI\n\n\t\t# Stop watchdog counters during halt\n\t\t# DBGMCU_APB3FZ2 |= WWDG1\n\t\tstm32h7x_dbgmcu_mmw 0x038 0x00000040 0\n\t\t# DBGMCU_APB1LFZ2 |= WWDG2\n\t\tstm32h7x_dbgmcu_mmw 0x040 0x00000800 0\n\t\t# DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2\n\t\tstm32h7x_dbgmcu_mmw 0x058 0x000C0000 0\n\n\t\tif {[set $_CHIPNAME.USE_CTI]} {\n\t\t\tstm32h7x_cti_start\n\t\t}\n\t}\n}\n\n# like mrw, but with target selection\nproc stm32h7x_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32h7x_mmw {used_target reg setbits clearbits} {\n\tset old [stm32h7x_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base\n# this procedure will use the mem_ap on AP2 whenever possible\nproc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {\n\t# use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address\n\tif {![using_hla]} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tset used_target $_CHIPNAME.ap2\n\t\tset reg_addr [expr {0xE00E1000 + $reg_offset}]\n\t} {\n\t\tset used_target [target current]\n\t\tset reg_addr [expr {0x5C001000 + $reg_offset}]\n\t}\n\n\tstm32h7x_mmw $used_target $reg_addr $setbits $clearbits\n}\n\nif {[set $_CHIPNAME.USE_CTI]} {\n\t# create CTI instances for both cores\n\tcti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0043000\n\tcti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -baseaddr 0xE0043000\n\n\t$_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\n\t$_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\n\tproc stm32h7x_cti_start {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Configure Cores' CTIs to halt each other\n\t\t# TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0\n\t\t$_CHIPNAME.cti0 write INEN0 0x1\n\t\t$_CHIPNAME.cti0 write OUTEN0 0x1\n\t\t$_CHIPNAME.cti1 write INEN0 0x1\n\t\t$_CHIPNAME.cti1 write OUTEN0 0x1\n\n\t\t# enable CTIs\n\t\t$_CHIPNAME.cti0 enable on\n\t\t$_CHIPNAME.cti1 enable on\n\t}\n\n\tproc stm32h7x_cti_stop {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t$_CHIPNAME.cti0 enable off\n\t\t$_CHIPNAME.cti1 enable off\n\t}\n\n\tproc stm32h7x_cti_prepare_restart_all {} {\n\t\tstm32h7x_cti_prepare_restart cti0\n\t\tstm32h7x_cti_prepare_restart cti1\n\t}\n\n\tproc stm32h7x_cti_prepare_restart {cti} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Acknowlodge EDBGRQ at TRIGOUT0\n\t\t$_CHIPNAME.$cti write INACK 0x01\n\t\t$_CHIPNAME.$cti write INACK 0x00\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32h7x_dual_bank.cfg",
    "content": "# script for stm32h7x family (dual flash bank)\n\n# STM32H7xxxI 2Mo have a dual bank flash.\nset DUAL_BANK 1\n\nsource [find target/stm32h7x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l0.cfg",
    "content": "#\n# M0+ devices only have SW-DP, but swj-dp code works, just don't\n# set any jtag related features\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB (max ram on smallest part)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    # Arm, m0+, non-multidrop.\n    # http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16088.html\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l0_enable_HSI16 {} {\n\t# Enable HSI16 as clock source\n\techo \"STM32L0: Enabling HSI16\"\n\n\t# Set HSI16ON in RCC_CR (leave MSI enabled)\n    mmw 0x40021000 0x00000101 0\n\n\t# Set HSI16 as SYSCLK (RCC_CFGR)\n\tmmw 0x4002100c 0x00000001 0\n\n\t# Wait until System clock switches to HSI16\n\twhile { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { }\n\n\t# Increase speed\n\tadapter speed 2500\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l0_enable_HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0x40015804 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l0_dual_bank.cfg",
    "content": "source [find target/stm32l0.cfg]\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l1.cfg",
    "content": "#\n# stm32l1 devices support both JTAG and SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 10kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0038\n      # Section 30.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l_enable_HSI {} {\n\t# Enable HSI as clock source\n\techo \"STM32L: Enabling HSI\"\n\n\t# Set HSION in RCC_CR\n\tmmw 0x40023800 0x00000101 0\n\n\t# Set HSI as SYSCLK\n\tmmw 0x40023808 0x00000001 0\n\n\t# Increase JTAG speed\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l_enable_HSI\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l1x_dual_bank.cfg",
    "content": "source [find target/stm32l1.cfg]\n\n# The stm32l1x 384kb have a dual bank flash.\n# Let's add a definition for the second bank here.\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l4x.cfg",
    "content": "# script for stm32l4x family\n\n#\n# stm32l4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 40kB (Available RAM in smallest device STM32L412)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0xa000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0351\n      # Section 44.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_TARGETNAME 0xA0001400\n   }\n}\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x48001000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x48001008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x48001000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x48001008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x48001000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x48001008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 6 (4 MHz).\n\t# Use MSI 24 MHz clock, compliant even with VOS == 2.\n\t# 3 WS compliant with VOS == 2 and 24 MHz.\n\tmww 0x40022000 0x00000103   ;# FLASH_ACR = PRFTBE | 3(Latency)\n\tmww 0x40021000 0x00000099   ;# RCC_CR = MSI_ON | MSIRGSEL | MSI Range 9\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32l5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32l5x family\n# stm32l5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32l5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32l5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is MSI (4MHz) after reset, set MCU freq at 110 MHz with PLL\n\t# RCC_APB1ENR1 = PWREN\n\tmww [expr {0x40021058 + $offset}] 0x10000000\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x40021058 + $offset}]\n\t# PWR_CR1 : VOS Range 0\n\tmww [expr {0x40007000 + $offset}] 0\n\t# while (PWR_SR2 & VOSF)\n\twhile {([mrw [expr {0x40007014 + $offset}]] & 0x0400)} {}\n\t# FLASH_ACR : 5 WS for 110 MHz HCLK\n\tmww 0x40022000 0x00000005\n\t# RCC_PLLCFGR = PLLP=PLLQ=0, PLLR=00=2, PLLREN=1, PLLN=55, PLLM=0000=1, PLLSRC=MSI 4MHz\n\t# fVCO = 4 x 55 /1 = 220\n\t# SYSCLOCK = fVCO/PLLR = 220/2 = 110 MHz\n\tmww [expr {0x4002100C + $offset}] 0x01003711\n\t# RCC_CR |= PLLON\n\tmmw [expr {0x40021000 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLLRDY)\n\twhile {!([mrw [expr {0x40021000 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR |= SW_PLL\n\tmmw [expr {0x40021008 + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR & SWS) != PLL)\n\twhile {([mrw [expr {0x40021008 + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32mp13x.cfg",
    "content": "# STMicroelectronics STM32MP13x (Single Cortex-A7)\n# http://www.st.com/stm32mp1\n\n# HLA does not support custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp13x_dk.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp13x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06501041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\n\n$_CHIPNAME.cpu cortex_a maskisr on\n$_CHIPNAME.cpu cortex_a dacrfixup on\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# srst resets the debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# keep clock enabled in low-power\n\t## catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000004}\n\t# freeze watchdog 1 and 2 on core halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\n# FIXME: most of handlers below will be removed once reset framework get merged\n$_CHIPNAME.ap1 configure -event reset-deassert-pre {\n\tadapter deassert srst deassert trst\n\tcatch {dap init}\n\tcatch {$::_CHIPNAME.dap apid 1}\n}\n$_CHIPNAME.cpu configure -event reset-deassert-pre  {$::_CHIPNAME.cpu arp_examine}\n$_CHIPNAME.cpu configure -event reset-deassert-post {toggle_cpu_dbg_claim0; dbgmcu_enable_debug}\n$_CHIPNAME.ap1 configure -event examine-start       {dap init}\n$_CHIPNAME.ap1 configure -event examine-end         {dbgmcu_enable_debug}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32mp15x.cfg",
    "content": "# STMicroelectronics STM32MP15x (Single/Dual Cortex-A7 plus Cortex-M4)\n# http://www.st.com/stm32mp1\n\n# HLA does not support multi-cores nor custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp15x_dk2.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp15x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06500041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# FIXME: Cortex-M code requires target accessible during reset, but this is not possible in STM32MP1\n# so defer-examine it until the reset framework get merged\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\ntarget create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 1 -dbgbase 0xE00D2000\ntarget create $_CHIPNAME.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\ntargets $_CHIPNAME.cpu0\n\ntarget smp $_CHIPNAME.cpu0 $_CHIPNAME.cpu1\n$_CHIPNAME.cpu0 cortex_a maskisr on\n$_CHIPNAME.cpu1 cortex_a maskisr on\n$_CHIPNAME.cpu0 cortex_a dacrfixup on\n$_CHIPNAME.cpu1 cortex_a dacrfixup on\n\ncti create $_CHIPNAME.cti.sys  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0094000\ncti create $_CHIPNAME.cti.cpu0 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D8000\ncti create $_CHIPNAME.cti.cpu1 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D9000\ncti create $_CHIPNAME.cti.cm4  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE0043000\n\nswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0083000\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0093000\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# Errata \"2.3.5 Incorrect reset of glitch-free kernel clock switch\" requires\n# srst to force VDDCORE power cycle or pull srst_core. Both cases reset the\n# debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# set debug enable bits in DBGMCU_CR to get ap2 and cm4 visible\n\tcatch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000007}\n\t# freeze watchdog 1 and 2 on cores halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu0_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\nproc detect_cpu1 {} {\n\tset cpu1_prsr [$::_CHIPNAME.ap1 read_memory 0xE00D2314 32 1]\n\tset dual_core [expr {$cpu1_prsr & 1}]\n\tif {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine}\n}\n\nproc rcc_enable_traceclk {} {\n\t$::_CHIPNAME.ap2 mww 0x5000080c 0x301\n}\n\n# FIXME: most of handler below will be removed once reset framework get merged\n$_CHIPNAME.ap1  configure -event reset-deassert-pre  {adapter deassert srst deassert trst;catch {dap init};catch {$::_CHIPNAME.dap apid 1}}\n$_CHIPNAME.ap2  configure -event reset-deassert-pre  {dbgmcu_enable_debug;rcc_enable_traceclk}\n$_CHIPNAME.cpu0 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu0 arp_examine}\n$_CHIPNAME.cpu1 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu1 arp_examine allow-defer}\n$_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0}\n$_CHIPNAME.cm4  configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == \"halted\"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}}\n$_CHIPNAME.ap1  configure -event examine-start       {dap init}\n$_CHIPNAME.ap2  configure -event examine-start       {dbgmcu_enable_debug}\n$_CHIPNAME.cpu0 configure -event examine-end         {detect_cpu1}\n$_CHIPNAME.ap2  configure -event examine-end         {rcc_enable_traceclk;$::_CHIPNAME.cm4 arp_examine}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32u5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32u5x family\n# stm32u5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32u5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32u5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is at MSI 4MHz after reset, set MCU freq at 160 MHz with PLL\n\n\t# Enable voltage range 1 for frequency above 100 Mhz\n\t# RCC_AHB3ENR = PWREN\n\tmww [expr {0x46020C94 + $offset}] 0x00000004\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x46020C94 + $offset}]\n\t# PWR_VOSR : VOS Range 1\n\tmmw [expr {0x4602080C + $offset}] 0x00030000 0\n\t# while !(PWR_VOSR & VOSRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00008000)} {}\n\t# FLASH_ACR : 4 WS for 160 MHz HCLK\n\tmww [expr {0x40022000 + $offset}] 0x00000004\n\t# RCC_PLL1CFGR => PLL1MBOOST=0, PLL1M=0=/1, PLL1FRACEN=0, PLL1SRC=MSI 4MHz\n\t#                 PLL1REN=1, PLL1RGE => VCOInputRange=PLLInputRange_4_8\n\tmww [expr {0x46020C28 + $offset}] 0x00040009\n\t# Enable EPOD Booster\n\tmmw [expr {0x4602080C + $offset}] 0x00040000 0\n\t# while !(PWR_VOSR & BOOSTRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00004000)} {}\n\t# RCC_PLL1DIVR => PLL1P=PLL1Q=PLL1R=000001=/2, PLL1N=0x4F=80\n\t# fVCO = 4 x 80 /1 = 320\n\t# SYSCLOCK = fVCO/PLL1R = 320/2 = 160 MHz\n\tmww [expr {0x46020C34 + $offset}] 0x0101024F\n\t# RCC_CR |= PLL1ON\n\tmmw [expr {0x46020C00 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLL1RDY)\n\twhile {!([mrw [expr {0x46020C00 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR1 |= SW_PLL\n\tmmw [expr {0x46020C1C + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR1 & SWS) != PLL)\n\twhile {([mrw [expr {0x46020C1C + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32u5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32w108xx.cfg",
    "content": "#\n# Target configuration for the ST STM32W108xx chips\n#\n# Processor: ARM Cortex-M3\n# Date:      2013-06-09\n# Author:    Giuseppe Barba <giuseppe.barba@gmail.com>\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] == 0 } {\n   set _CHIPNAME stm32w108\n} else {\n   set _CHIPNAME $CHIPNAME\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } {\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nset _ENDIAN little\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n if { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf -expected-id _BSTAPID\n } else {\n   set _BSTAPID_1 0x169a862b\n   set _BSTAPID_2 0x269a862b\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf \\\n\t\t-expected-id $_BSTAPID_1 -expected-id $_BSTAPID_2\n }\n}\n#\n# Set Target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\n# Use the flash driver from the EM357\nset _FLASHNAME $_CHIPNAME.flash\n\n# 64k (0x10000) of flash\nflash bank $_FLASHNAME em357 0x08000000 0x10000 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32wbx.cfg",
    "content": "# script for stm32wbx family\n\n#\n# stm32wb devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32wbx\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x6ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n    # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n    # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n    # 2 WS compliant with VOS=Range1 and 24 MHz.\n    mmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTBE | 2(Latency)\n    mmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n    # Boost JTAG frequency\n    adapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n    # Reset clock is MSI (4 MHz)\n    adapter speed 500\n}\n\n$_TARGETNAME configure -event examine-end {\n    # Enable debug during low power modes (uses more power)\n    # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n    mmw 0xE0042004 0x00000007 0\n\n    # Stop watchdog counters during halt\n    # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n    mmw 0xE004203C 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n    # change this value accordingly to configure trace pins\n    # assignment\n    mmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32wlx.cfg",
    "content": "# script for stm32wlx family\n\n#\n# stm32wl devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32wlx\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists WKUP_CM0P] } {\n\tset $_CHIPNAME.WKUP_CM0P $WKUP_CM0P\n\tunset WKUP_CM0P\n} else {\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# setup the Work-area start address and size\n# Work-area is a space in RAM used for flash programming\n\n# Memory map for known devices:\n# STM32WL   x5JC   x5JB   x5J8\n#   FLASH   256    128    64\n#   SRAM1   32     16     0\n#   SRAM2   32     32     20\n\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n# Use SRAM2 as work area (some devices do not have SRAM1):\nset WORKAREASTART_CM4   0x20008000\nset WORKAREASTART_CM0P  [expr {$WORKAREASTART_CM4 + $_WORKAREASIZE}]\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0\nflash bank $_CHIPNAME.otp.cpu0   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n\t# Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n\t# 2 WS compliant with VOS=Range1 and 24 MHz.\n\tmmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTEN | 2(Latency)\n\tmmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_CHIPNAME.cpu0 configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE004203C 0x00001800 0\n\n\tset _CHIPNAME [stm32wlx_get_chipname]\n\tglobal $_CHIPNAME.WKUP_CM0P\n\n\tif {[set $_CHIPNAME.WKUP_CM0P]} {\n\t\tstm32wlx_wkup_cm0p\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event trace-config {\n\t# nothing to do\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1\n\n\t$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0P -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\tflash bank $_CHIPNAME.otp.cpu1   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {![using_hla]} {\n\t\t# if srst is not fitted use SYSRESETREQ to\n\t\t# perform a soft reset\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n\tproc stm32wlx_wkup_cm0p {} {\n\t\tset _CHIPNAME [stm32wlx_get_chipname]\n\n\t\t# enable CPU2 boot after reset and after wakeup from Stop or Standby mode\n\t\t# PWR_CR4 |= C2BOOT\n\t\tstm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0\n\t}\n}\n\n# get _CHIPNAME from current target\nproc stm32wlx_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\n# like mrw, but with target selection\nproc stm32wlx_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32wlx_mmw {used_target reg setbits clearbits} {\n\tset old [stm32wlx_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32x5x_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common script for stm32l5x and stm32u5x families\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# STM32L5x: RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers\n\t\t# STM32U5x: RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers\n\t\t# Corresponds to Cortex®-M33 JTAG debug port ID code\n\t\tset _CPUTAPID 0x0ba04477\n\t} {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x0be12477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n# use non-secure RAM by default\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# create sec/ns flash and otp memories (sizes will be probed)\nflash bank $_CHIPNAME.flash_ns      stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp           stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME\n\n# Common knowledge tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://review.openocd.org/3366\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32x5x_is_secure {} {\n\t# read Debug Security Control and Status Register (DSCSR) and check CDS (bit 16)\n\tset DSCSR [mrw 0xE000EE08]\n\treturn [expr {($DSCSR & (1 << 16)) != 0}]\n}\n\nproc stm32x5x_ahb_ap_non_secure_access {} {\n\t# SPROT=1=Non Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x4B000000 0x4F000000\n}\n\nproc stm32x5x_ahb_ap_secure_access {} {\n\t# SPROT=0=Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x0B000000 0x4F000000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 480\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0xE0044004 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0044008 0x00001800 0\n}\n\n$_TARGETNAME configure -event halted {\n\tset secure [stm32x5x_is_secure]\n\n\tif {$secure} {\n\t\tset secure_str \"Secure\"\n\t\tstm32x5x_ahb_ap_secure_access\n\t} else {\n\t\tset secure_str \"Non-Secure\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t}\n\n\t# print the secure state only when it changes\n\tset _TARGETNAME [target current]\n\tglobal $_TARGETNAME.secure\n\n\tif {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {\n\t\techo \"CPU in $secure_str state\"\n\t\t# update saved security state\n\t\tset $_TARGETNAME.secure $secure\n\t}\n}\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tset use_secure_workarea 0\n\t# check if FLASH_OPTR.TZEN is enabled\n\tset FLASH_OPTR [mrw 0x40022040]\n\tif {[expr {$FLASH_OPTR & 0x80000000}] == 0} {\n\t\techo \"TZEN option bit disabled\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t} else {\n\t\tstm32x5x_ahb_ap_secure_access\n\t\techo \"TZEN option bit enabled\"\n\n\t\t# check if FLASH_OPTR.RDP is not Level 0.5\n\t\tif {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {\n\t\t\tset use_secure_workarea 1\n\t\t}\n\t}\n\n\tset _TARGETNAME [target current]\n\tset workarea_addr [$_TARGETNAME cget -work-area-phys]\n\techo \"workarea_addr $workarea_addr\"\n\n\tif {$use_secure_workarea} {\n\t\tset workarea_addr [expr {$workarea_addr | 0x10000000}]\n\t} else {\n\t\tset workarea_addr [expr {$workarea_addr & ~0x10000000}]\n\t}\n\n\t$_TARGETNAME configure -work-area-phys $workarea_addr\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0044004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm32xl.cfg",
    "content": "# script for stm32xl family (dual flash bank)\nsource [find target/stm32f1x.cfg]\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8l.cfg",
    "content": "# script for stm8l family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8l\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set stm8l type\n$_TARGETNAME configure -enable_stm8l\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n#uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8l152.cfg",
    "content": "#config script for STM8L152\n\nset EEPROMSTART 0x1000\nset EEPROMEND 0x13ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8s.cfg",
    "content": "# script for stm8s family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8s\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n# uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8s003.cfg",
    "content": "#config script for STM8S003\n\nset FLASHEND 0x9FFF\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8s103.cfg",
    "content": "#config script for STM8S103\n\nset FLASHEND 0x9FFF\nset EEPROMEND 0x427F\nset OPTIONEND 0x480A\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/stm8s105.cfg",
    "content": "#config script for STM8S105\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/str710.cfg",
    "content": "#start slow, speed up after reset\nadapter speed 10\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str710\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 6000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x400C0000 0x00004000 0 0 $_TARGETNAME STR71x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/str730.cfg",
    "content": "#STR730 CPU\n\nadapter speed 3000\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str730\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/str750.cfg",
    "content": "#STR750 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str750\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0041\n}\n\n# jtag speed\nadapter speed 10\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n\tinit_smi\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x20000000 0x00040000 0 0 $_TARGETNAME STR75x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x200C0000 0x00004000 0 0 $_TARGETNAME STR75x\n\n# Serial NOR on SMI CS0.\nset _FLASHNAME $_CHIPNAME.snor\nflash bank $_FLASHNAME stmsmi 0x80000000 0 0 0 $_TARGETNAME\n\nsource [find mem_helper.tcl]\n\nproc init_smi {} {\n\tmmw 0x60000030 0x01000000 0x00000000; # enable clock for GPIO regs\n\tmmw 0xffffe420 0x00000001 0x00000000; # set SMI_EN bit\n\tmmw 0x90000000 0x00000001 0x00000000; # set BLOCK_EN_1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/str912.cfg",
    "content": "# script for str9\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # possible values: 0x1457f041, 0x2457f041\n   # we ignore version in check below\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID -ignore-version\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#adapter speed 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/swj-dp.tcl",
    "content": "# ARM Debug Interface V5 (ADI_V5) utility\n# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since\n# SW-DP and JTAG-DP targets don't need to switch based\n# on which transport is active.\n#\n# declare a JTAG or SWD Debug Access Point (DAP)\n# based on the transport in use with this session.\n# You can't access JTAG ops when SWD is active, etc.\n\n# params are currently what \"jtag newtap\" uses\n# because OpenOCD internals are still strongly biased\n# to JTAG ....  but for SWD, \"irlen\" etc are ignored,\n# and the internals work differently\n\n# for now, ignore non-JTAG and non-SWD transports\n# (e.g. initial flash programming via SPI or UART)\n\n# split out \"chip\" and \"tag\" so we can someday handle\n# them more uniformly irlen too...)\n\nif [catch {transport select}] {\n  echo \"Error: unable to select a session transport. Can't continue.\"\n  shutdown\n}\n\nproc swj_newdap {chip tag args} {\n if [using_jtag] {\n     eval jtag newtap $chip $tag $args\n } elseif [using_swd] {\n     eval swd newdap $chip $tag $args\n } else {\n     echo \"Error: transport '[ transport select ]' not supported by swj_newdap\"\n     shutdown\n }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/swm050.cfg",
    "content": "# Synwit SWM050\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME swm050\n}\nset _CHIPSERIES swm050\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\nadapter speed 1000\n\n$_TARGETNAME configure -event reset-init {\n\t# Stop the watchdog, just to be safe\n\tmww 0x40019000 0x00\n\t# Set clock divider value to 1\n\tmww 0x400F0000 0x01\n\t# Set system clock to 18Mhz\n\tmww 0x400F0008 0x00\n}\n\n# SWM050 (Cortex-M0 core) supports SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/test_reset_syntax_error.cfg",
    "content": "# Test script to check that syntax error in reset\n# script is reported properly.\n\n# at91eb40a target\n\n#jtag scan chain\nset _CHIPNAME syntaxtest\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\n\tsyntax error\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/test_syntax_error.cfg",
    "content": "# This script tests a syntax error in the startup\n# config script\n\nsyntax error here\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti-ar7.cfg",
    "content": "#\n# Texas Instruments AR7 SOC - used in many adsl modems.\n# http://www.linux-mips.org/wiki/AR7\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ti-ar7\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0000100f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_CHIPNAME.cpu\n\n# use onboard 4k sram as working area\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti-cjtag.cfg",
    "content": "# A start sequence to change from cJTAG to 4-pin JTAG\n# This is needed for CC2538 and CC26xx to be able to communicate through JTAG\n# Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information.\nproc ti_cjtag_to_4pin_jtag {jrc} {\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\t# Two zero bit scans and a one bit drshift\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# A two bit drhift and a 9 bit drshift\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\n\t# Set ICEPick IDCODE in data register\n\tirscan $jrc 0x04 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_calypso.cfg",
    "content": "#\n# TI Calypso (lite) G2 C035 Digital Base Band chip\n#\n# ARM7TDMIE + DSP subchip (S28C128)\n#\n# 512K SRAM Calypso\n# 256K SRAM Calypso lite\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME calypso\n}\n\nif { [info exists ENDIAN] } {\n\tset  _ENDIAN $ENDIAN\n} else {\n\tset  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3100e02f\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\njtag newtap $_CHIPNAME dsp -expected-id 0x00000000 -irlen 8\njtag newtap $_CHIPNAME arm -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# target\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position $_TARGETNAME\n\n# workarea\n\n$_TARGETNAME configure -work-area-phys 0x00800000 -work-area-size $_WORKAREASIZE -work-area-backup 1\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n$_TARGETNAME configure -event examine-start {\n\tirscan calypso.arm 0x0b -endstate DRPAUSE\n\tdrscan calypso.arm 2 2 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc13x0.cfg",
    "content": "#\n# Texas Instruments CC13x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x0\nset JRC_TAPID 0x0B9BE02F\nset WORKAREASIZE 0x4000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc13x2.cfg",
    "content": "#\n# Texas Instruments CC13x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc26x0.cfg",
    "content": "#\n# Texas Instruments CC26x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc26x0\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4BA00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B99A02F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n# A start sequence is needed to change from 2-pin cJTAG to 4-pin JTAG\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config vectreset\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc26x2.cfg",
    "content": "#\n# Texas Instruments CC26x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc26x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc3220sf.cfg",
    "content": "#\n# Texas Instruments CC3220SF - ARM Cortex-M4\n#\n# http://www.ti.com/CC3220SF\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\nsource [find target/ti_cc32xx.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n#\n# On CC32xx family of devices, sysreqreset is disabled, and vectreset is\n# blocked by the boot loader (stops in a while(1) statement). srst reset can\n# leave the target in a state that prevents debug. The following uses the\n# soft_reset_halt command to reset and halt the target. Then the PC and stack\n# are initialized from internal flash. This allows for a more reliable reset,\n# but with two caveats: it only works for the SF variant that has internal\n# flash, and it only resets the CPU and not any peripherals.\n#\n\nproc ocd_process_reset_inner { MODE } {\n\n\tsoft_reset_halt\n\n\t# Initialize MSP, PSP, and PC from vector table at flash 0x01000800\n\tset boot [read_memory 0x01000800 32 2]\n\n\treg msp [lindex $boot 0]\n\treg psp [lindex $boot 0]\n\treg pc [lindex $boot 1]\n\n\tif { 0 == [string compare $MODE run ] } {\n\t\tresume\n\t}\n\n\tcc32xx.cpu invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_cc32xx.cfg",
    "content": "#\n# Texas Instruments CC32xx - ARM Cortex-M4\n#\n# http://www.ti.com/product/CC3200\n# http://www.ti.com/product/CC3220\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc32xx\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tif {[using_jtag]} {\n\t\tset _DAP_TAPID 0x4BA00477\n\t} else {\n\t\tset _DAP_TAPID 0x2BA01477\n\t}\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\n\tjtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n} else {\n\tswj_newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\n}\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B97C02F\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\tjtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_dm355.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM355\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm355\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n#\n# Also note: when running without RTCK before the PLLs are set up, you\n# may need to slow the JTAG clock down quite a lot (under 2 MHz).\n#\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b73b02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm355\nset dm355 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm355 sram0\t\t0x00010000\ndict set dm355 sram1\t\t0x00014000\ndict set dm355 sysbase\t\t0x01c40000\ndict set dm355 pllc1\t\t0x01c40800\ndict set dm355 pllc2\t\t0x01c40c00\ndict set dm355 psc\t\t0x01c41000\ndict set dm355 gpio\t\t0x01c67000\ndict set dm355 a_emif\t\t0x01e10000\ndict set dm355 a_emif_cs0\t0x02000000\ndict set dm355 a_emif_cs1\t0x04000000\ndict set dm355 ddr_emif\t\t0x20000000\ndict set dm355 ddr\t\t0x80000000\ndict set dm355 uart0\t\t0x01c20000\ndict set dm355 uart1\t\t0x01c20400\ndict set dm355 uart2\t\t0x01e06000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm355 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_dm365.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM365\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm365\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x0792602f\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b83e02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm365\nset dm365 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm365 sram0\t\t0x00010000\ndict set dm365 sram1\t\t0x00014000\ndict set dm365 sysbase\t\t0x01c40000\ndict set dm365 pllc1\t\t0x01c40800\ndict set dm365 pllc2\t\t0x01c40c00\ndict set dm365 psc\t\t0x01c41000\ndict set dm365 gpio\t\t0x01c67000\ndict set dm365 a_emif\t\t0x01d10000\ndict set dm365 a_emif_cs0\t0x02000000\ndict set dm365 a_emif_cs1\t0x04000000\ndict set dm365 ddr_emif\t\t0x20000000\ndict set dm365 ddr\t\t0x80000000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm365 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_dm6446.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM6446\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm6446\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: unknown ... must enable via ICEpick\njtag newtap $_CHIPNAME unknown -irlen 8 -disable\njtag configure $_CHIPNAME.unknown -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\njtag configure $_CHIPNAME.dsp -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b70002f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_k3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments K3 devices:\n# * AM654x: https://www.ti.com/lit/pdf/spruid7\n#  Has 4 ARMV8 Cores and 2 R5 Cores and an M3\n# * J721E: https://www.ti.com/lit/pdf/spruil1\n#  Has 2 ARMV8 Cores and 6 R5 Cores and an M3\n# * J7200: https://www.ti.com/lit/pdf/spruiu1\n#  Has 2 ARMV8 Cores and 4 R5 Cores and an M3\n# * AM642: https://www.ti.com/lit/pdf/spruim2\n#  Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3\n#\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc am654\n}\n\n# set V8_SMP_DEBUG to non 0 value in board if you'd like to use SMP debug\nif { [info exists V8_SMP_DEBUG] } {\n\tset _v8_smp_debug $V8_SMP_DEBUG\n} else {\n\tset _v8_smp_debug 0\n}\n\n# Common Definitions\n\n# System Controller is the very first processor - all current SoCs have it.\nset CM3_CTIBASE\t\t{0x3C016000}\n\n# sysctrl power-ap unlock offsets\nset _sysctrl_ap_unlock_offsets {0xf0 0x44}\n\n# All the ARMV8s are the next processors.\n#\t\t   CL0,CORE0  CL0,CORE1  CL1,CORE0  CL1,CORE1\nset ARMV8_DBGBASE {0x90410000 0x90510000 0x90810000 0x90910000}\nset ARMV8_CTIBASE {0x90420000 0x90520000 0x90820000 0x90920000}\n\n# And we add up the R5s\n#\t\t(0)MCU 0   (1)MCU 1   (2)MAIN_0_0 (3)MAIN_0_1 (4)MAIN_1_0 (5)MAIN_1_1\nset R5_DBGBASE {0x9d010000 0x9d012000 0x9d410000 0x9d412000 0x9d510000 0x9d512000}\nset R5_CTIBASE {0x9d018000 0x9d019000 0x9d418000 0x9d419000 0x9d518000 0x9d519000}\nset R5_NAMES {mcu_r5.0 mcu_r5.1 main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\n# Finally an General Purpose(GP) MCU\nset CM4_CTIBASE\t\t{0x20001000}\n\n# General Purpose MCU (M4) may be present on some very few SoCs\nset _gp_mcu_cores 0\n# General Purpose MCU power-ap unlock offsets\nset _gp_mcu_ap_unlock_offsets {0xf0 0x60}\n\n# Set configuration overrides for each SOC\nswitch $_soc {\n\tam654 {\n\t\tset _CHIPNAME am654\n\t\tset _K3_DAP_TAPID 0x0bb5a02f\n\n\t\t# AM654 has 2 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\n\t\t# AM654 has 1 cluster of 2 R5s cores.\n\t\tset _r5_cores 2\n\t\tset R5_NAMES {mcu_r5.0 mcu_r5.1}\n\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x50}\n\t}\n\tam642 {\n\t\tset _CHIPNAME am642\n\t\tset _K3_DAP_TAPID 0x0bb3802f\n\n\t\t# AM642 has 1 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 2\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000}\n\n\t\t# AM642 has 2 cluster of 2 R5s cores.\n\t\tset _r5_cores 4\n\t\tset R5_NAMES {main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\t\tset R5_DBGBASE {0x9d410000 0x9d412000 0x9d510000 0x9d512000}\n\t\tset R5_CTIBASE {0x9d418000 0x9d419000 0x9d518000 0x9d519000}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t}\n\tam625 {\n\t\tset _CHIPNAME am625\n\t\tset _K3_DAP_TAPID 0x0bb7e02f\n\n\t\t# AM625 has 1 clusters of 4 A53 cores.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}\n\n\t\t# AM625 has 1 cluster of 1 R5s core.\n\t\tset _r5_cores 1\n\t\tset R5_NAMES {main0_r5.0}\n\t\tset R5_DBGBASE {0x9d410000}\n\t\tset R5_CTIBASE {0x9d418000}\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tj721e {\n\t\tset _CHIPNAME j721e\n\t\tset _K3_DAP_TAPID 0x0bb6402f\n\t\t# J721E has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721E has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\t}\n\tj7200 {\n\t\tset _CHIPNAME j7200\n\t\tset _K3_DAP_TAPID 0x0bb6d02f\n\n\t\t# J7200 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J7200 has 2 clusters of 2 R5 cores each.\n\t\tset _r5_cores 4\n\t\tset R5_DBGBASE {0x9d010000 0x9d012000 0x9d110000 0x9d112000}\n\t\tset R5_CTIBASE {0x9d018000 0x9d019000 0x9d118000 0x9d119000}\n\n\t\t# M3 CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t}\n\tj721s2 {\n\t\tset _CHIPNAME j721s2\n\t\tset _K3_DAP_TAPID 0x0bb7502f\n\n\t\t# J721s2 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721s2 has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tdefault {\n\t\techo \"'$_soc' is invalid!\"\n\t}\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\nset _CTINAME $_CHIPNAME.cti\n\n# sysctrl is always present\ncti create $_CTINAME.sysctrl -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]\ntarget create $_TARGETNAME.sysctrl cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine\n$_TARGETNAME.sysctrl configure -event reset-assert { }\n\nproc sysctrl_up {} {\n\t# To access sysctrl, we need to enable the JTAG access for the same.\n\t# Ensure Power-AP unlocked\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 0] 0x00190000\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 1] 0x00102098\n\n\t$::_TARGETNAME.sysctrl arp_examine\n}\n\n$_TARGETNAME.sysctrl configure -event gdb-attach {\n\tsysctrl_up\n\t# gdb-attach default rule\n\thalt 1000\n}\n\nproc _cpu_no_smp_up {} {\n\tset _current_target [target current]\n\tset _current_type [$_current_target cget -type]\n\n\t$_current_target arp_examine\n\t$_current_target $_current_type dbginit\n}\n\nproc _armv8_smp_up {} {\n\tfor { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on\n\t}\n\t# Set Default target as core 0\n\ttargets $::_TARGETNAME.$::_armv8_cpu_name.0\n}\n\nset _v8_smp_targets \"\"\n\nfor { set _core 0 } { $_core < $_armv8_cores } { incr _core } {\n\n\tcti create $_CTINAME.$_armv8_cpu_name.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $ARMV8_CTIBASE $_core]\n\n\ttarget create $_TARGETNAME.$_armv8_cpu_name.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $ARMV8_DBGBASE $_core] -cti $_CTINAME.$_armv8_cpu_name.$_core -defer-examine\n\n\tset _v8_smp_targets \"$_v8_smp_targets $_TARGETNAME.$_armv8_cpu_name.$_core\"\n\n\tif { $_v8_smp_debug == 0 } {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_cpu_no_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t} else {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_armv8_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t}\n}\n\n# Setup ARMV8 proc commands based on CPU to prevent people confusing SoCs\nset _armv8_up_cmd \"$_armv8_cpu_name\"_up\n# Available if V8_SMP_DEBUG is set to non-zero value\nset _armv8_smp_cmd \"$_armv8_cpu_name\"_smp\n\nif { $_v8_smp_debug == 0 } {\n\tproc $_armv8_up_cmd { args } {\n\t\tforeach _core $args {\n\t\t\ttargets $_core\n\t\t\t_cpu_no_smp_up\n\t\t}\n\t}\n} else {\n\tproc $_armv8_smp_cmd { args } {\n\t\t_armv8_smp_up\n\t}\n\t# Declare SMP\n\ttarget smp $:::_v8_smp_targets\n}\n\nfor { set _core 0 } { $_core < $_r5_cores } { incr _core } {\n\tset _r5_name [lindex $R5_NAMES $_core]\n\tcti create $_CTINAME.$_r5_name -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $R5_CTIBASE $_core]\n\n\t# inactive core examination will fail - wait till startup of additional core\n\ttarget create $_TARGETNAME.$_r5_name cortex_r4 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $R5_DBGBASE $_core] -ap-num 1 -defer-examine\n\n\t$_TARGETNAME.$_r5_name configure -event gdb-attach {\n\t\t_cpu_no_smp_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n\nproc r5_up { args } {\n\tforeach  _core $args {\n\t\ttargets $_core\n\t\t_cpu_no_smp_up\n\t}\n}\n\nif { $_gp_mcu_cores != 0 } {\n\tcti create $_CTINAME.gp_mcu -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]\n\ttarget create $_TARGETNAME.gp_mcu cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine\n\t$_TARGETNAME.gp_mcu configure -event reset-assert { }\n\n\tproc gp_mcu_up {} {\n\t\t# To access GP MCU, we need to enable the JTAG access for the same.\n\t\t# Ensure Power-AP unlocked\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 0] 0x00190000\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 1] 0x00102098\n\n\t\t$::_TARGETNAME.gp_mcu arp_examine\n\t}\n\n\t$_TARGETNAME.gp_mcu configure -event gdb-attach {\n\t\tgp_mcu_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_msp432.cfg",
    "content": "#\n# Texas Instruments MSP432 - ARM Cortex-M4F @ up to 48 MHz\n#\n# http://www.ti.com/MSP432\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME msp432\n}\n\nif { [info exists CPUTAPID] } {\n\tset _DAP_TAPID $CPUTAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists DAP_SWD_ID] } {\n\tset _DAP_SWD_ID $DAP_SWD_ID\n} else {\n\tset _DAP_SWD_ID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _DAP_ID $_DAP_TAPID\n} else {\n\tset _DAP_ID $_DAP_SWD_ID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_rm4x.cfg",
    "content": "source [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_tms570.cfg",
    "content": "adapter speed 1500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tms570\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN big\n}\n\n# TMS570 has an ICEpick-C on which we need the router commands.\nsource [find target/icepick.cfg]\n\n# Main DAP\n# DAP_TAPID should be set before source-ing this file\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# ICEpick-C (JTAG route controller)\n# JRC_TAPID should be set before source-ing this file\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n}\n\nset _JRC_TAPID2 0x0B7B302F\nset _JRC_TAPID3 0x0B95502F\nset _JRC_TAPID4 0x0B97102F\nset _JRC_TAPID5 0x0D8A002F\nset _JRC_TAPID6 0x2B8A002F\nset _JRC_TAPID7 0x2D8A002F\nset _JRC_TAPID8 0x3B8A002F\nset _JRC_TAPID9 0x3D8A002F\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID \\\n\t-expected-id $_JRC_TAPID2 \\\n\t-expected-id $_JRC_TAPID3 \\\n\t-expected-id $_JRC_TAPID4 \\\n\t-expected-id $_JRC_TAPID5 \\\n\t-expected-id $_JRC_TAPID6 \\\n\t-expected-id $_JRC_TAPID7 \\\n\t-expected-id $_JRC_TAPID8 \\\n\t-expected-id $_JRC_TAPID9 \\\n\t-ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-R4 target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_r4 -endian $_ENDIAN \\\n\t-dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x00001003\n\n# TMS570 uses quirky BE-32 mode\n$_CHIPNAME.dap ti_be_32_quirks 1\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\tglobal _CHIPNAME\n\n\t# assert warm system reset through ICEPick\n\ticepick_c_wreset $_CHIPNAME.jrc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_tms570ls20xxx.cfg",
    "content": "# TMS570LS20216, TMS570LS20206, TMS570LS10216\n# TMS570LS10206, TMS570LS10116, TMS570LS10106\nset DAP_TAPID 0x0B7B302F\nset JRC_TAPID 0x0B7B302F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/ti_tms570ls3137.cfg",
    "content": "# TMS570LS3137\nset DAP_TAPID 0x0B8A002F\nset JRC_TAPID 0x0B8A002F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/tmpa900.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA900\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa900\n}\n\n# Toshiba TMPA900 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA900 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (8kB): 0xf8008000\n\n# Use internal RAM-0 and RAM-1 as working area (24kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0x6000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/tmpa910.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA910\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa910\n}\n\n# Toshiba TMPA910 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA910 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (16kB): 0xf8008000\n# Internal RAM-2 (16kB): 0xf800c000\n\n# Use internal RAM-0, RAM-1, and RAM-2 as working area (48kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0xc000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/tnetc4401.cfg",
    "content": "# Texas Instruments (TI) TNETC4401, MIPS32 DOCSIS-tailored SoC (4Kc-based)\n# Used in Knovative KC-100 and Motorola Surfboard SB5120 cable modems.\n# Datasheet: https://brezn.muc.ccc.de/~mazzoo/DOCSIS/tnetc4401.pdf\ntransport select jtag\nset _TARGETNAME tnetc4401\nset _CPUTAPID 0x0000100f\njtag newtap $_TARGETNAME tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\ntarget create $_TARGETNAME mips_m4k -chain-position $_TARGETNAME.tap -endian big\n\n# May need to halt manually before calling reset init\n$_TARGETNAME configure -event reset-init {\n\thalt\n\techo \"Attempting to disable watchdog...\"\n\tmwb phys 0xa8610b00 0 256\n\thalt\n\twait_halt\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/u8500.cfg",
    "content": "#  Copyright (C) ST-Ericsson SA 2011\n#  Author : michel.jaouen@stericsson.com\n#  U8500 target\n\nproc mmu_off {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp & ~1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc mmu_on {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp | 1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc ocd_gdb_restart {target_id} {\n    global _TARGETNAME_1\n\tglobal _SMP\n    targets $_TARGETNAME_1\n\tif { $_SMP == 1 } {\n\tcortex_a smp off\n\t}\n\trst_run\n\thalt\n\tif { $_SMP == 1 } {\n\tcortex_a smp on\n\t}\n}\n\nproc smp_reg {} {\n\tglobal _TARGETNAME_1\n    global _TARGETNAME_2\n    targets $_TARGETNAME_1\n\techo \"$_TARGETNAME_1\"\n\tset pc1 [reg pc]\n\tset stck1 [reg sp_svc]\n\ttargets $_TARGETNAME_2\n\techo \"$_TARGETNAME_1\"\n\tset pc2 [reg pc]\n\tset stck2 [reg sp_svc]\n}\n\n\nproc u8500_tapenable {chip val} {\n\techo \"JTAG tap enable $chip\"\n}\n\n\nproc pwrsts { } {\n\tglobal _CHIPNAME\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\techo \"pwrsts =\"$pwrsts\n\tset a9 [expr \"0x$pwrsts & 0xc\"]\n\tset ape [expr \"0x$pwrsts & 0x3\"]\n\tif {[string equal \"0\" $ape]} {\n\t\techo \"ape off\"\n\t} else {\n\t\techo \"ape on\"\n\t}\n\techo \"$a9\"\n\tswitch $a9 {\n\t\t4 {\n\t\t\techo \"A9 in retention\"\n\t\t  }\n\t\t8 {\n\t\t\techo \"A9 100% DVFS\"\n\t\t  }\n\t\tc {\n\t\t\techo \"A9 50% DVFS\"\n\t\t}\n\t}\n}\n\nproc poll_pwrsts { } {\n\tglobal _CHIPNAME\n\tset result 1\n\tset i 0\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\twhile {[string equal \"4\" $pwrsts] && $i<20} {\n\t\tirscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 0;\n\t\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\t\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\t\tif {![string equal \"4\" $pwrsts]} {\n\t\t\tset result 1\n\t\t} else {\n\t\t\tset result 0\n\t\t\tsleep 200\n\t\t\techo \"loop $i\"\n\t\t}\n\t\tincr i\n\t}\n\treturn $result\n}\n\nproc halt_ { } {\n\tif {[poll_pwrsts]==1} {\n\t\thalt\n\t} else {\n\t\techo \"halt failed : target in retention\"\n\t}\n}\n\n\nproc u8500_dapenable {chip} {\n}\n\nproc u8500_tapdisable {chip val} {\n\techo \"JTAG tap disable $chip\"\n}\n\n\nproc enable_apetap {} {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n    global _TARGETNAME_1\n\tpoll off\n\tirscan $_CHIPNAME.jrc 0x3e\n\tdrscan $_CHIPNAME.jrc 8 0xcf\n\tjtag tapenable $_CHIPNAME.dap\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tset status [$_TARGETNAME_1 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_1 arp_examine\n\tcache_config l2x 0xa0412000 8\n\t}\n\n\tset status [$_TARGETNAME_2 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_2 arp_examine\n\t}\n\t}\n\ntcl_port 5555\ntelnet_port 4444\ngdb_port 3333\n\nif { [info exists CHIPNAME] } {\nglobal _CHIPNAME\n    set _CHIPNAME $CHIPNAME\n} else {\nglobal _CHIPNAME\n\tset _CHIPNAME u8500\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n\tset _ENDIAN little\n}\n\n\n\n# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT,\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"u8500_dapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n\t\"u8500_tapdisable $_CHIPNAME.cpu 0xc0\"\n\n\n#CLTAPC TAP JRC equivalent\nif { [info exists CLTAPC_ID] } {\n   set _CLTAPC_ID $CLTAPC_ID\n} else {\n   set _CLTAPC_ID 0x22286041\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version\n\n\nif { ![info exists TARGETNAME_1] } {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $_CHIPNAME.cpu1\n} else {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $TARGETNAME_1\n}\n\nif { [info exists DAP_DBG1] } {\n\tset _DAP_DBG1 $DAP_DBG1\n} else {\n\tset _DAP_DBG1 0x801A8000\n}\nif { [info exists DAP_DBG2] } {\n\tset _DAP_DBG2 $DAP_DBG2\n} else {\n\tset _DAP_DBG2 0x801AA000\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME_1 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux\n\n\nif { ![info exists TARGETNAME_2] } {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $_CHIPNAME.cpu2\n} else {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $TARGETNAME_2\n}\n\ntarget create $_TARGETNAME_2 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux\n\n\nif {![info exists SMP]} {\nglobal _SMP\nset _SMP 1\n} else {\nglobal _SMP\nset _SMP $SMP\n}\nglobal SMP\nif { $_SMP == 1} {\ntarget smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\n}\n\n\n\n\nproc secsts1 { } {\n\tglobal _CHIPNAME\n        irscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {![string equal \"4\" $secsts1]} {\n\techo \"APE target secured\"\n        } else {\n        echo \"APE target not secured\"\n        }\n}\n\nproc att { } {\n\tglobal _CHIPNAME\n\tjtag arp_init\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {[string equal \"4\" $secsts1]} {\n\t\tif {[poll_pwrsts]==1} {\n\t\tenable_apetap\n                } else {\n\t\techo \"target in retention\"\n\t\t}\n\t} else {\n\t\techo \"target secured\"\n\t}\n\n}\n\n\n\nproc rst_run { } {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n\tglobal _TARGETNAME_1\n\tset status [$_TARGETNAME_1 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_1\n\t}\n    set status [$_TARGETNAME_2 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_2\n\t}\n   \tpoll off\n\tjtag arp_init\n\treset\n\tsleep 20\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\twhile {![string equal \"4\" $secsts1]} {\n\t\tirscan u8500.jrc 0x3a\n\t\tdrscan u8500.jrc 4 4\n\t\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\t\techo \"secsts1 =\"$secsts1\n\t\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\t}\n\techo \"ape debugable\"\n\tenable_apetap\n\tpoll on\n\ttargets $_TARGETNAME_1\n\tdap apsel 1\n}\n\nif {![info exists MAXSPEED]} {\nglobal _MAXSPEED\nset _MAXSPEED 15000\n} else {\nglobal _MAXSPEED\nset _MAXSPEED $MAXSPEED\n}\nglobal _MAXSPEED\nadapter speed $_MAXSPEED\n\n\ngdb_breakpoint_override hard\nset mem inaccessible-by-default-off\n\njtag_ntrst_delay 100\nreset_config trst_and_srst combined\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/vd_aarch64.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm v8 64b Cortex A\n\nif {![info exists _CORES]} {\n\tset _CORES 1\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME aarch64\n}\nset _TARGETNAME $_CHIPNAME.cpu\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80810000 0x80910000}\nset CTIBASE {0x80820000 0x80920000}\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n$_CHIPNAME.dap apsel 1\n\nfor { set _core 0 } { $_core < $_CORES } { incr _core } \\\n{\n\tcti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 -baseaddr [lindex $CTIBASE $_core]\n\tset _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t-dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core\"\n\tif { $_core != 0 } {\n\t\t# non-boot core examination may fail\n\t\tset _command \"$_command -defer-examine\"\n\t\tset _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n\t} else {\n\t\tset _smp_command \"target smp $_TARGETNAME.$_core\"\n\t}\n\teval $_command\n}\neval $_smp_command\n\n# default target is core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/vd_cortex_m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# ARM Cortex M\n\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME cortex_m\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/vd_riscv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV core\n\nif {![info exists _HARTID]} {\n\tset _HARTID 0x00\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME riscv\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID\n\nriscv set_reset_timeout_sec 120\nriscv set_command_timeout_sec 120\n# prefer to use sba for system bus access\nriscv set_prefer_sba on\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/vybrid_vf6xx.cfg",
    "content": "#\n# Freescale Vybrid VF610\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME vf610\n}\n\nif { [info exists A5_JTAG_TAPID] } {\n\tset _A5_JTAG_TAPID $A5_JTAG_TAPID\n} else {\n\tset _A5_JTAG_TAPID 0x4BA00477\n}\n\nif { [info exists A5_SWD_TAPID] } {\n\tset _A5_SWD_TAPID $A5_SWD_TAPID\n} else {\n\tset _A5_SWD_TAPID 0x3BA02477\n}\n\nif { [using_jtag] } {\n\tset _A5_TAPID $_A5_JTAG_TAPID\n} else {\n\tset _A5_TAPID $_A5_SWD_TAPID\n}\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_A5_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap -dbgbase 0xc0088000\ntarget create ${_TARGETNAME}1 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/xilinx_zynqmp.cfg",
    "content": "#\n# target configuration for\n# Xilinx ZynqMP (UltraScale+ / A53)\n#\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME uscale\n}\n\n#\n# DAP tap (Quard core A53)\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# PS tap (UltraScale+)\n#\nif { [info exists PS_TAPID] } {\n    set _PS_TAPID $PS_TAPID\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -expected-id $_PS_TAPID\n} else {\n    # FPGA Programmable logic. Values take from Table 39-1 in UG1085:\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -ignore-version \\\n        -expected-id 0x04711093 \\\n        -expected-id 0x04710093 \\\n        -expected-id 0x04721093 \\\n        -expected-id 0x04720093 \\\n        -expected-id 0x04739093 \\\n        -expected-id 0x04730093 \\\n        -expected-id 0x04738093 \\\n        -expected-id 0x04740093 \\\n        -expected-id 0x04750093 \\\n        -expected-id 0x04759093 \\\n        -expected-id 0x04758093\n}\n\nset jtag_configured 0\n\njtag configure $_CHIPNAME.ps -event setup {\n    global _CHIPNAME\n    global jtag_configured\n\n    if { $jtag_configured == 0 } {\n        # add the DAP tap to the chain\n        # See https://forums.xilinx.com/t5/UltraScale-Architecture/JTAG-Chain-Configuration-for-Zynq-UltraScale-MPSoC/td-p/758924\n        irscan $_CHIPNAME.ps 0x824\n        drscan $_CHIPNAME.ps 32 0x00000003\n        runtest 100\n\n        # setup event will be re-entered through jtag arp_init\n        # break the recursion\n        set jtag_configured 1\n        # re-initialized the jtag chain\n        jtag arp_init\n    }\n}\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\nset _smp_command \"\"\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset _cores 4\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        #set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\ntarget create uscale.axi mem_ap -dap uscale.dap -ap-num 0\n\neval $_smp_command\ntargets $_TARGETNAME.0\n\nproc core_up { args } {\n    global _TARGETNAME\n    foreach core $args {\n        $_TARGETNAME.$core arp_examine\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/xmc1xxx.cfg",
    "content": "#\n# Infineon XMC1100/XMC1200/XMC1300 family (ARM Cortex-M0 @ 32 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc1000\n}\n\n#\n# Only SWD and SPD supported\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_SWD_TAPID $CPUTAPID\n} else {\n\tset _CPU_SWD_TAPID 0x0BB11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n                       -work-area-size $_WORKAREASIZE \\\n                       -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/xmc4xxx.cfg",
    "content": "#\n# Infineon XMC4100/XMC4200/XMC4400/XMC4500 family (ARM Cortex-M4 @ 80-120 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc4000\n}\n\nsource [find target/swj-dp.tcl]\n\n#\n# SWJ-DP\n#\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x4BA00477\n}\n\n#\n# SW_DP\n#\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16 kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc4xxx 0x0C000000 0 0 0 $_TARGETNAME\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/xmos_xs1-xau8a-10_arm.cfg",
    "content": "#\n# XMOS xCORE-XA XS1-XAU8A-10: ARM Cortex-M3 @ 48 MHz\n#\n# http://www.xmos.com/products/silicon/xcore-xa/xa-series\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME xcorexa\n}\n\nif { ![info exists WORKAREASIZE] } {\n\t# XS1-XAU8A-10-FB265: 128 KB SRAM\n\tset WORKAREASIZE 0x20000\n}\n\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/zynq_7000.cfg",
    "content": "#\n# Xilinx Zynq-7000 All Programmable SoC\n#\n# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm\n#\n\nset _CHIPNAME zynq\nset _TARGETNAME $_CHIPNAME.cpu\n\njtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \\\n    -expected-id 0x23727093 \\\n    -expected-id 0x13722093 \\\n    -expected-id 0x03727093 \\\n    -expected-id 0x03736093\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 0 -dbgbase 0x80090000\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 1 -dbgbase 0x80092000\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n\nadapter speed 1000\n\n${_TARGETNAME}0 configure -event reset-assert-post \"cortex_a dbginit\"\n${_TARGETNAME}1 configure -event reset-assert-post \"cortex_a dbginit\"\n\npld device virtex2 zynq_pl.bs 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc zynqpl_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/target/к1879xб1я.cfg",
    "content": "# СБИС К1879ХБ1Я\n# http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/\n\nadapter speed 1000\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME к1879хб1я\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists DSP_TAPID] } {\n    set _DSP_TAPID $DSP_TAPID\n} else {\n    set _DSP_TAPID 0x2b900f0f\n}\n\njtag newtap $_CHIPNAME dsp -irlen 4 -expected-id $_DSP_TAPID\n\nif { [info exists CPU_TAPID] } {\n    set _CPU_TAPID $CPU_TAPID\n} else {\n    set _CPU_TAPID 0x07b76f0f\n}\n\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_CHIPNAME.arm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/test/selftest.cfg",
    "content": "\nadd_help_text selftest \"run selftest using working ram <tmpfile> <address> <size>\"\n\nproc selftest {tmpfile address size} {\n\n   for {set i 0} {$i < $size } {set i [expr {$i+4}]} {\n       mww [expr {$address+$i}] $i\n   }\n\n   for {set i 0} {$i < 10 } {set i [expr {$i+1}]} {\n    echo \"Test iteration $i\"\n    dump_image $tmpfile $address $size\n\tverify_image $tmpfile $address bin\n\tload_image $tmpfile $address bin\n   }\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/test/syntax1.cfg",
    "content": "adapter srst delay 200\njtag_ntrst_delay 200\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough\nadapter assert trst assert srst\nadapter deassert trst deassert srst\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap lpc2148 one -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4f1f0f0f\n\n#target configuration\n#daemon_startup reset\n\nset _TARGETNAME [format \"%s.cpu\" lpc2148]\ntarget create lpc2148.cpu arm7tdmi -endian little -work-area-size 0x4000 -work-area-phys 0x40000000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\nsoft_reset_halt\nmvb 0xE01FC040 0x01\n}\n\n\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/tools/firmware-recovery.tcl",
    "content": "echo \"\\n\\nFirmware recovery helpers\"\necho \"Use -c firmware_help to get help\\n\"\n\nset known_boards {\n    \"asus-rt-n16\t\tASUS RT-N16\"\n    \"asus-rt-n66u\t\tASUS RT-N66U\"\n    \"linksys-wag200g\t\tLinksys WAG200G\"\n    \"linksys-wrt54gl\t\tLinksys WRT54GL v1.1\"\n    \"netgear-dg834v3\t\tNetgear DG834G v3\"\n    \"tp-link_tl-mr3020\t\tTP-LINK TL-MR3020\"\n    \"bt-homehubv1\t\tBT HomeHub v1\"\n}\n\nproc firmware_help { } {\n    echo \"\nYour OpenOCD command should look like this:\nopenocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \\\"<commands>*; shutdown\\\"\n\nWhere:\n<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2\n<commands> are firmware-recovery commands separated by semicolon\n\nSupported commands:\nfirmware_help\t\t\tget this help\nlist_boards\t\t\tlist known boards and exit\nboard <name>\t\t\tselect board you work with\nlist_partitions\t\t\tlist partitions of the currently selected board\ndump_part <name> <filename>\tsave partition's contents to a file\nerase_part <name>\t\terase the given partition\nflash_part <name> <filename>\terase, flash and verify the given partition\nram_boot <filename>\t\tload binary file to RAM and run it\nadapter speed <freq>\t\tset JTAG clock frequency in kHz\n\nFor example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:\nopenocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\\\\n\t-c \\\"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\\\"\n\\n\\n\"\n    shutdown\n}\n\n# set default, can be overridden later\nadapter speed 1000\n\nproc get_partition { name } {\n    global partition_list\n    dict get $partition_list $name\n}\n\nproc partition_desc { name } { lindex [get_partition $name] 0 }\nproc partition_start { name } { lindex [get_partition $name] 1 }\nproc partition_size { name } { lindex [get_partition $name] 2 }\n\nproc list_boards { } {\n    global known_boards\n    echo \"List of the supported boards:\\n\"\n    echo \"Board name\\t\\tDescription\"\n    echo \"-----------------------------------\"\n    foreach i $known_boards {\n\techo $i\n    }\n    echo \"\\n\\n\"\n}\n\nproc board { name } {\n    script [find board/$name.cfg]\n}\n\nproc list_partitions { } {\n    global partition_list\n    set fstr \"%-16s%-14s%-14s%s\"\n    echo \"\\nThe currently selected board is known to have these partitions:\\n\"\n    echo [format $fstr Name Start Size Description]\n    echo \"-------------------------------------------------------\"\n    for {set i 0} {$i < [llength $partition_list]} {incr i 2} {\n\tset key [lindex $partition_list $i]\n\techo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]\n    }\n    echo \"\\n\\n\"\n}\n\n# Magic to work with any targets, including semi-functional\nproc prepare_target { } {\n    init\n    catch {halt}\n    catch {reset init}\n    catch {halt}\n}\n\nproc dump_part { name filename } {\n    prepare_target\n    dump_image $filename [partition_start $name] [partition_size $name]\n}\n\nproc erase_part { name } {\n    prepare_target\n    flash erase_address [partition_start $name] [partition_size $name]\n}\n\nproc flash_part { name filename } {\n    prepare_target\n    flash write_image erase $filename [partition_start $name] bin\n    echo \"Verifying:\"\n    verify_image $filename [partition_start $name]\n}\n\nproc ram_boot { filename } {\n    global ram_boot_address\n    prepare_target\n    load_image $filename $ram_boot_address bin\n    resume $ram_boot_address\n}\n\necho \"\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/tools/memtest.tcl",
    "content": "# Algorithms by Michael Barr, released into public domain\n# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser\n\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nsource [find bitsbytes.tcl]\nsource [find memory.tcl]\n\nproc runAllMemTests { baseAddress nBytes } {\n    memTestDataBus $baseAddress\n    memTestAddressBus $baseAddress $nBytes\n    memTestDevice $baseAddress $nBytes\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDataBus()\n# *\n# * Description: Test the data bus wiring in a memory region by\n# *              performing a walking 1's test at a fixed address\n# *              within that region.  The address (and hence the\n# *              memory region) is selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first pattern that failed.\n# *\n#***********************************************************************************\nproc memTestDataBus { address } {\n    echo \"Running memTestDataBus\"\n\n    for {set i 0} {$i < 32} {incr i} {\n\t# Shift bit\n\tset pattern [expr {1 << $i}]\n\n\t# Write pattern to memory\n\tmemwrite32 $address $pattern\n\n\t# Read pattern from memory\n\tset data [memread32 $address]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data\"\n\t    return $pattern\n\t}\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestAddressBus()\n# *\n# * Description: Perform a walking 1's test on the relevant bits\n# *              of the address and check for aliasing.  This test\n# *              will find single-bit address failures such as stuck\n# *              -high, stuck-low, and shorted pins.  The base address\n# *              and size of the region are selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# *\n# * Notes:       For best results, the selected base address should\n# *              have enough LSB 0's to guarantee single address bit\n# *              changes.  For example, to test a 64-Kbyte region,\n# *              select a base address on a 64-Kbyte boundary.  Also,\n# *              select the region size as a power-of-two--if at all\n# *              possible.\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              aliasing problem was uncovered.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestAddressBus { baseAddress nBytes } {\n    set addressMask [expr {$nBytes - 1}]\n    set pattern 0xAAAAAAAA\n    set antipattern 0x55555555\n\n    echo \"Running memTestAddressBus\"\n\n    echo \"addressMask: [convertToHex $addressMask]\"\n\n    echo \"memTestAddressBus: Writing the default pattern at each of the power-of-two offsets...\"\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {\n\tset addr [expr {$baseAddress + $offset}]\n\tmemwrite32 $addr $pattern\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck high...\"\n    memwrite32 $baseAddress $antipattern\n\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck low or shorted...\"\n    memwrite32 $baseAddress $pattern\n    for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $antipattern\n\n\tset data [memread32 $baseAddress]\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n\n\tfor {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\t    set addr [expr {$baseAddress + $offset}]\n\t    set data [memread32 $baseAddress]\n\n            if {(($data != $pattern) && ($offset != $testOffset))} {\n\t\techo \"FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]\"\n\t\treturn $pattern\n\t    }\n        }\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $pattern\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDevice()\n# *\n# * Description: Test the integrity of a physical memory device by\n# *              performing an increment/decrement test over the\n# *              entire region.  In the process every storage bit\n# *              in the device is tested as zero and as one.  The\n# *              base address and the size of the region are\n# *              selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              incorrect value was read back.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestDevice { baseAddress nBytes } {\n    echo \"Running memTestDevice\"\n\n    echo \"memTestDevice: Filling memory with a known pattern...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tmemwrite32 [expr {$baseAddress + $offset}] $pattern\n    }\n\n    echo \"memTestDevice: Checking each location and inverting it for the second pass...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]\"\n\t    return $pattern\n\t}\n\n\tset antiPattern [expr {~$pattern}]\n\tmemwrite32 [expr {$baseAddress + $offset}] $antiPattern\n    }\n\n    echo \"memTestDevice: Checking each location for the inverted pattern and zeroing it...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset antiPattern [expr {~$pattern & ((1<<32) - 1)}]\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\tset dataHex [convertToHex $data]\n\tset antiPatternHex [convertToHex $antiPattern]\n\tif {$dataHex != $antiPatternHex} {\n\t    echo \"FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset\"\n\t    return $pattern\n\t}\n    }\n}\n\nproc convertToHex { value } {\n    format 0x%08x $value\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/scripts/tools/test_cpu_speed.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Description:\n#  Measure the CPU clock frequency of an ARM Cortex-M based device.\n#\n# Return:\n#  The CPU clock frequency in Hz. A negative value indicates that the loop\n#  counter was saturated.\n#\n# Note:\n#  You may need to adapt the number of cycles for your device.\n#\nadd_help_text cortex_m_test_cpu_speed \"Measure the CPU clock frequency of an ARM Cortex-M based device\"\nadd_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}\nproc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {\n\tset loop_counter_start 0xffffffff\n\n\thalt\n\n\t# Backup registers and memory.\n\tset backup_regs [get_reg -force {pc r0 xPSR}]\n\tset backup_mem [read_memory $address 16 3]\n\n\t# We place the following code at the given address to measure the\n\t# CPU clock frequency:\n\t#\n\t# 3801: subs r0, #1\n\t# d1fd: bne #-2\n\t# e7fe: b #-4\n\twrite_memory $address 16 {0x3801 0xd1fd 0xe7fe}\n\n\tset_reg \"pc $address r0 $loop_counter_start\"\n\tresume\n\tsleep $timeout\n\thalt\n\n\t# Get the loop counter value from register r0.\n\tset loop_counter_end [dict values [get_reg r0]]\n\tset loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]\n\n\t# Restore registers and memory.\n\tset_reg $backup_regs\n\twrite_memory $address 16 $backup_mem\n\n\tif { [expr {$loop_counter_end == 0}] } {\n\t\treturn -1\n\t}\n\n\treturn [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/info/dir",
    "content": "This is the file .../info/dir, which contains the\ntopmost node of the Info hierarchy, called (dir)Top.\nThe first time you invoke Info you start off looking at this node.\n\u001f\nFile: dir,\tNode: Top\tThis is the top of the INFO tree\n\n  This (the Directory node) gives a menu of major topics.\n  Typing \"q\" exits, \"H\" lists all Info commands, \"d\" returns here,\n  \"h\" gives a primer for first-timers,\n  \"mEmacs<Return>\" visits the Emacs manual, etc.\n\n  In Emacs, you can click mouse button 2 on a menu item or cross reference\n  to select it.\n\n* Menu:\n\nDevelopment\n* OpenOCD: (openocd).           OpenOCD User's Guide\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/info/openocd.info",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nIndirect:\nopenocd.info-1: 986\nopenocd.info-2: 336375\n\u001f\nTag Table:\n(Indirect)\nNode: Top986\nNode: About3443\nNode: Developers7775\nNode: Debug Adapter Hardware11115\nNode: About Jim-Tcl23272\nNode: Running25417\nNode: OpenOCD Project Setup30813\nRef: OpenOCD Project Setup-Footnote-150765\nRef: OpenOCD Project Setup-Footnote-251105\nRef: OpenOCD Project Setup-Footnote-351373\nNode: Config File Guidelines51701\nRef: theinitboardprocedure62880\nRef: definecputargetsworkinginsmp69740\nRef: theinittargetsprocedure74220\nRef: theinittargeteventsprocedure76039\nRef: translatingconfigurationfiles77892\nRef: Config File Guidelines-Footnote-179143\nNode: Server Configuration79218\nRef: configurationstage79540\nRef: enteringtherunstage81015\nRef: tcpipports84468\nRef: gdb_port84963\nRef: gdbconfiguration87221\nRef: gdbbreakpointoverride87536\nRef: gdbflashprogram87905\nRef: eventpolling89384\nNode: Debug Adapter Configuration91816\nRef: adapter_usb_location94131\nRef: hla_interface122277\nRef: st_link_dap_interface123830\nRef: swimtransport148030\nRef: jtagspeed148797\nNode: Reset Configuration151759\nRef: srstandtrstissues154687\nRef: reset_config158869\nNode: TAP Declaration166781\nRef: enablinganddisablingtaps178689\nRef: autoprobing181336\nRef: dapdeclaration183991\nRef: dap_create184505\nRef: DAP subcommand apreg186750\nRef: TAP Declaration-Footnote-1189681\nNode: CPU Configuration189881\nRef: targettypes192775\nRef: targetconfiguration197095\nRef: rtostype202889\nRef: gdbportoverride204038\nRef: targetcurstate209063\nRef: targetevents211051\nNode: Flash Commands218097\nRef: norconfiguration219630\nRef: flashprogrammingcommands222867\nRef: flashprotect230643\nRef: program231465\nRef: flashdriverlist231745\nRef: at91samd251325\nRef: at91sam3255006\nRef: atsame5258360\nRef: nandconfiguration320278\nRef: nanddriverlist330660\nNode: Flash Programming336375\nNode: PLD/FPGA Commands337988\nNode: General Commands340152\nRef: debuglevel343120\nRef: targetstatehandling344425\nRef: resetcommand350250\nRef: memoryaccess352669\nRef: imageaccess354537\nNode: Architecture and Core Commands362228\nRef: armhardwaretracing362698\nRef: traceportdrivers370608\nRef: armcrosstrigger372339\nRef: arm9vectorcatch381733\nRef: xscalevectorcatch389604\nRef: add-reg-type-struct429891\nRef: softwaredebugmessagesandtracing436790\nNode: JTAG Commands440249\nNode: Boundary Scan Commands447727\nNode: Utility Commands453407\nNode: GDB and OpenOCD455252\nRef: programmingusinggdb460364\nRef: gdbmeminspect462010\nRef: gdbrtossupport463947\nRef: usingopenocdsmpwithgdb466389\nNode: Tcl Scripting API467063\nNode: FAQ470546\nRef: faqrtck470656\nRef: faqtaporder482547\nNode: Tcl Crash Course484313\nNode: License496321\nNode: OpenOCD Concept Index518733\nNode: Command and Driver Index542795\n\u001f\nEnd Tag Table\n\n\u001f\nLocal Variables:\ncoding: utf-8\nEnd:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/info/openocd.info-1",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nFile: openocd.info,  Node: Top,  Next: About,  Up: (dir)\n\nOpenOCD User's Guide\n********************\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\n\n* Menu:\n\n* About::                            About OpenOCD\n* Developers::                       OpenOCD Developer Resources\n* Debug Adapter Hardware::           Debug Adapter Hardware\n* About Jim-Tcl::                    About Jim-Tcl\n* Running::                          Running OpenOCD\n* OpenOCD Project Setup::            OpenOCD Project Setup\n* Config File Guidelines::           Config File Guidelines\n* Server Configuration::             Server Configuration\n* Debug Adapter Configuration::      Debug Adapter Configuration\n* Reset Configuration::              Reset Configuration\n* TAP Declaration::                  TAP Declaration\n* CPU Configuration::                CPU Configuration\n* Flash Commands::                   Flash Commands\n* Flash Programming::                Flash Programming\n* PLD/FPGA Commands::                PLD/FPGA Commands\n* General Commands::                 General Commands\n* Architecture and Core Commands::   Architecture and Core Commands\n* JTAG Commands::                    JTAG Commands\n* Boundary Scan Commands::           Boundary Scan Commands\n* Utility Commands::                 Utility Commands\n* GDB and OpenOCD::                  Using GDB and OpenOCD\n* Tcl Scripting API::                Tcl Scripting API\n* FAQ::                              Frequently Asked Questions\n* Tcl Crash Course::                 Tcl Crash Course\n* License::                          GNU Free Documentation License\n\n* OpenOCD Concept Index::            Concept Index\n* Command and Driver Index::         Command and Driver Index\n\n\u001f\nFile: openocd.info,  Node: About,  Next: Developers,  Prev: Top,  Up: Top\n\nAbout\n*****\n\nOpenOCD was created by Dominic Rath as part of a 2005 diploma thesis\nwritten at the University of Applied Sciences Augsburg\n(<http://www.hs-augsburg.de>).  Since that time, the project has grown\ninto an active open-source project, supported by a diverse community of\nsoftware and hardware developers from around the world.\n\nWhat is OpenOCD?\n================\n\nThe Open On-Chip Debugger (OpenOCD) aims to provide debugging, in-system\nprogramming and boundary-scan testing for embedded target devices.\n\nIt does so with the assistance of a \"debug adapter\", which is a small\nhardware module which helps provide the right kind of electrical\nsignaling to the target being debugged.  These are required since the\ndebug host (on which OpenOCD runs) won't usually have native support for\nsuch signaling, or the connector needed to hook up to the target.\n\nSuch debug adapters support one or more \"transport\" protocols, each of\nwhich involves different electrical signaling (and uses different\nmessaging protocols on top of that signaling).  There are many types of\ndebug adapter, and little uniformity in what they are called.  (There\nare also product naming differences.)\n\nThese adapters are sometimes packaged as discrete dongles, which may\ngenerically be called \"hardware interface dongles\".  Some development\nboards also integrate them directly, which may let the development board\nconnect directly to the debug host over USB (and sometimes also to power\nit over USB).\n\nFor example, a \"JTAG Adapter\" supports JTAG signaling, and is used to\ncommunicate with JTAG (IEEE 1149.1) compliant TAPs on your target board.\nA \"TAP\" is a \"Test Access Port\", a module which processes special\ninstructions and data.  TAPs are daisy-chained within and between chips\nand boards.  JTAG supports debugging and boundary scan operations.\n\nThere are also \"SWD Adapters\" that support Serial Wire Debug (SWD)\nsignaling to communicate with some newer ARM cores, as well as debug\nadapters which support both JTAG and SWD transports.  SWD supports only\ndebugging, whereas JTAG also supports boundary scan operations.\n\nFor some chips, there are also \"Programming Adapters\" supporting special\ntransports used only to write code to flash memory, without support for\non-chip debugging or boundary scan.  (At this writing, OpenOCD does not\nsupport such non-debug adapters.)\n\nDongles: OpenOCD currently supports many types of hardware dongles:\nUSB-based, parallel port-based, and other standalone boxes that run\nOpenOCD internally.  *Note Debug Adapter Hardware::.\n\nGDB Debug: It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T,\nARM922T, ARM926EJ-S, ARM966E-S), XScale (PXA25x, IXP42x), Cortex-M3\n(Stellaris LM3, STMicroelectronics STM32 and Energy Micro EFM32) and\nIntel Quark (x10xx) based cores to be debugged via the GDB protocol.\n\nFlash Programming: Flash writing is supported for external\nCFI-compatible NOR flashes (Intel and AMD/Spansion command set) and\nseveral internal flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7,\nAT91SAM3U, STR7x, STR9x, LM3, STM32x and EFM32).  Preliminary support\nfor various NAND flash controllers (LPC3180, Orion, S3C24xx, more) is\nincluded.\n\nOpenOCD Web Site\n================\n\nThe OpenOCD web site provides the latest public news from the community:\n\n<http://openocd.org/>\n\nLatest User's Guide:\n====================\n\nThe user's guide you are now reading may not be the latest one\navailable.  A version for more recent code may be available.  Its HTML\nform is published regularly at:\n\n<http://openocd.org/doc/html/index.html>\n\nPDF form is likewise published at:\n\n<http://openocd.org/doc/pdf/openocd.pdf>\n\nOpenOCD User's Forum\n====================\n\nThere is an OpenOCD forum (phpBB) hosted by SparkFun, which might be\nhelpful to you.  Note that if you want anything to come to the attention\nof developers, you should post it to the OpenOCD Developer Mailing List\ninstead of this forum.\n\n<http://forum.sparkfun.com/viewforum.php?f=18>\n\nOpenOCD User's Mailing List\n===========================\n\nThe OpenOCD User Mailing List provides the primary means of\ncommunication between users:\n\n<https://lists.sourceforge.net/mailman/listinfo/openocd-user>\n\nOpenOCD IRC\n===========\n\nSupport can also be found on irc: <irc://irc.libera.chat/openocd>\n\n\u001f\nFile: openocd.info,  Node: Developers,  Next: Debug Adapter Hardware,  Prev: About,  Up: Top\n\n1 OpenOCD Developer Resources\n*****************************\n\nIf you are interested in improving the state of OpenOCD's debugging and\ntesting support, new contributions will be welcome.  Motivated\ndevelopers can produce new target, flash or interface drivers, improve\nthe documentation, as well as more conventional bug fixes and\nenhancements.\n\nThe resources in this chapter are available for developers wishing to\nexplore or expand the OpenOCD source code.\n\n1.1 OpenOCD Git Repository\n==========================\n\nDuring the 0.3.x release cycle, OpenOCD switched from Subversion to a\nGit repository hosted at SourceForge.  The repository URL is:\n\n<git://git.code.sf.net/p/openocd/code>\n\nor via http\n\n<http://git.code.sf.net/p/openocd/code>\n\nYou may prefer to use a mirror and the HTTP protocol:\n\n<http://repo.or.cz/r/openocd.git>\n\nWith standard Git tools, use 'git clone' to initialize a local\nrepository, and 'git pull' to update it.  There are also gitweb pages\nletting you browse the repository with a web browser, or download\narbitrary snapshots without needing a Git client:\n\n<http://repo.or.cz/w/openocd.git>\n\nThe 'README' file contains the instructions for building the project\nfrom the repository or a snapshot.\n\nDevelopers that want to contribute patches to the OpenOCD system are\nstrongly encouraged to work against mainline.  Patches created against\nolder versions may require additional work from their submitter in order\nto be updated for newer releases.\n\n1.2 Doxygen Developer Manual\n============================\n\nDuring the 0.2.x release cycle, the OpenOCD project began providing a\nDoxygen reference manual.  This document contains more technical\ninformation about the software internals, development processes, and\nsimilar documentation:\n\n<http://openocd.org/doc/doxygen/html/index.html>\n\nThis document is a work-in-progress, but contributions would be welcome\nto fill in the gaps.  All of the source files are provided in-tree,\nlisted in the Doxyfile configuration at the top of the source tree.\n\n1.3 Gerrit Review System\n========================\n\nAll changes in the OpenOCD Git repository go through the web-based\nGerrit Code Review System:\n\n<https://review.openocd.org/>\n\nAfter a one-time registration and repository setup, anyone can push\ncommits from their local Git repository directly into Gerrit.  All users\nand developers are encouraged to review, test, discuss and vote for\nchanges in Gerrit.  The feedback provides the basis for a maintainer to\neventually submit the change to the main Git repository.\n\nThe 'HACKING' file, also available as the Patch Guide in the Doxygen\nDeveloper Manual, contains basic information about how to connect a\nrepository to Gerrit, prepare and push patches.  Patch authors are\nexpected to maintain their changes while they're in Gerrit, respond to\nfeedback and if necessary rework and push improved versions of the\nchange.\n\n1.4 OpenOCD Developer Mailing List\n==================================\n\nThe OpenOCD Developer Mailing List provides the primary means of\ncommunication between developers:\n\n<https://lists.sourceforge.net/mailman/listinfo/openocd-devel>\n\n1.5 OpenOCD Bug Tracker\n=======================\n\nThe OpenOCD Bug Tracker is hosted on SourceForge:\n\n<http://bugs.openocd.org/>\n\n\u001f\nFile: openocd.info,  Node: Debug Adapter Hardware,  Next: About Jim-Tcl,  Prev: Developers,  Up: Top\n\n2 Debug Adapter Hardware\n************************\n\nDefined: dongle: A small device that plugs into a computer and serves as\nan adapter ....  [snip]\n\nIn the OpenOCD case, this generally refers to a small adapter that\nattaches to your computer via USB or the parallel port.\n\n2.1 Choosing a Dongle\n=====================\n\nThere are several things you should keep in mind when choosing a dongle.\n\n  1. Transport Does it support the kind of communication that you need?\n     OpenOCD focuses mostly on JTAG. Your version may also support other\n     ways to communicate with target devices.\n  2. Voltage What voltage is your target - 1.8, 2.8, 3.3, or 5V? Does\n     your dongle support it?  You might need a level converter.\n  3. Pinout What pinout does your target board use?  Does your dongle\n     support it?  You may be able to use jumper wires, or an \"octopus\"\n     connector, to convert pinouts.\n  4. Connection Does your computer have the USB, parallel, or Ethernet\n     port needed?\n  5. RTCK Do you expect to use it with ARM chips and boards with RTCK\n     support (also known as \"adaptive clocking\")?\n\n2.2 USB FT2232 Based\n====================\n\nThere are many USB JTAG dongles on the market, many of them based on a\nchip from \"Future Technology Devices International\" (FTDI) known as the\nFTDI FT2232; this is a USB full speed (12 Mbps) chip.  See:\n<http://www.ftdichip.com> for more information.  In summer 2009, USB\nhigh speed (480 Mbps) versions of these FTDI chips started to become\navailable in JTAG adapters.  Around 2012, a new variant appeared -\nFT232H - this is a single-channel version of FT2232H. (Adapters using\nthose high speed FT2232H or FT232H chips may support adaptive clocking.)\n\nThe FT2232 chips are flexible enough to support some other transport\noptions, such as SWD or the SPI variants used to program some chips.\nThey have two communications channels, and one can be used for a UART\nadapter at the same time the other one is used to provide a debug\nadapter.\n\nAlso, some development boards integrate an FT2232 chip to serve as a\nbuilt-in low-cost debug adapter and USB-to-serial solution.\n\n   * usbjtag\n     Link\n     <http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html>\n   * jtagkey\n     See: <http://www.amontec.com/jtagkey.shtml>\n   * jtagkey2\n     See: <http://www.amontec.com/jtagkey2.shtml>\n   * oocdlink\n     See: <http://www.oocdlink.com> By Joern Kaipf\n   * signalyzer\n     See: <http://www.signalyzer.com>\n   * Stellaris Eval Boards\n     See: <http://www.ti.com> - The Stellaris eval boards bundle\n     FT2232-based JTAG and SWD support, which can be used to debug the\n     Stellaris chips.  Using separate JTAG adapters is optional.  These\n     boards can also be used in a \"pass through\" mode as JTAG adapters\n     to other target boards, disabling the Stellaris chip.\n   * TI/Luminary ICDI\n     See: <http://www.ti.com> - TI/Luminary In-Circuit Debug Interface\n     (ICDI) Boards are included in Stellaris LM3S9B9x Evaluation Kits.\n     Like the non-detachable FT2232 support on the other Stellaris eval\n     boards, they can be used to debug other target boards.\n   * olimex-jtag\n     See: <http://www.olimex.com>\n   * Flyswatter/Flyswatter2\n     See: <http://www.tincantools.com>\n   * turtelizer2\n     See: Turtelizer 2\n     (http://www.ethernut.de/en/hardware/turtelizer/index.html), or\n     <http://www.ethernut.de>\n   * comstick\n     Link: <http://www.hitex.com/index.php?id=383>\n   * stm32stick\n     Link <http://www.hitex.com/stm32-stick>\n   * axm0432_jtag\n     Axiom AXM-0432 Link <http://www.axman.com> - NOTE: This JTAG does\n     not appear to be available anymore as of April 2012.\n   * cortino\n     Link <http://www.hitex.com/index.php?id=cortino>\n   * dlp-usb1232h\n     Link <http://www.dlpdesign.com/usb/usb1232h.shtml>\n   * digilent-hs1\n     Link <http://www.digilentinc.com/Products/Detail.cfm?Prod=JTAG-HS1>\n   * opendous\n     Link <http://code.google.com/p/opendous/wiki/JTAG> FT2232H-based\n     (OpenHardware).\n   * JTAG-lock-pick Tiny 2\n     Link <http://www.distortec.com/jtag-lock-pick-tiny-2> FT232H-based\n\n   * GW16042\n     Link:\n     <http://shop.gateworks.com/index.php?route=product/product&path=70_80&product_id=64>\n     FT2232H-based\n\n2.3 USB-JTAG / Altera USB-Blaster compatibles\n=============================================\n\nThese devices also show up as FTDI devices, but are not\nprotocol-compatible with the FT2232 devices.  They are, however,\nprotocol-compatible among themselves.  USB-JTAG devices typically\nconsist of a FT245 followed by a CPLD that understands a particular\nprotocol, or emulates this protocol using some other hardware.\n\nThey may appear under different USB VID/PID depending on the particular\nproduct.  The driver can be configured to search for any VID/PID pair\n(see the section on driver commands).\n\n   * USB-JTAG Kolja Waschk's USB Blaster-compatible adapter\n     Link: <http://ixo-jtag.sourceforge.net/>\n   * Altera USB-Blaster\n     Link: <http://www.altera.com/literature/ug/ug_usb_blstr.pdf>\n\n2.4 USB J-Link based\n====================\n\nThere are several OEM versions of the SEGGER J-Link adapter.  It is an\nexample of a microcontroller based JTAG adapter, it uses an AT91SAM764\ninternally.\n\n   * SEGGER J-Link\n     Link: <http://www.segger.com/jlink.html>\n   * Atmel SAM-ICE (Only works with Atmel chips!)\n     Link: <http://www.atmel.com/tools/atmelsam-ice.aspx>\n   * IAR J-Link\n\n2.5 USB RLINK based\n===================\n\nRaisonance has an adapter called RLink.  It exists in a stripped-down\nform on the STM32 Primer, permanently attached to the JTAG lines.  It\nalso exists on the STM32 Primer2, but that is wired for SWD and not\nJTAG, thus not supported.\n\n   * Raisonance RLink\n     Link:\n     <http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html>\n   * STM32 Primer\n     Link: <http://www.stm32circle.com/resources/stm32primer.php>\n   * STM32 Primer2\n     Link: <http://www.stm32circle.com/resources/stm32primer2.php>\n\n2.6 USB ST-LINK based\n=====================\n\nSTMicroelectronics has an adapter called ST-LINK. They only work with\nSTMicroelectronics chips, notably STM32 and STM8.\n\n   * ST-LINK\n     This is available standalone and as part of some kits, eg.\n     STM32VLDISCOVERY.\n     Link: <http://www.st.com/internet/evalboard/product/219866.jsp>\n   * ST-LINK/V2\n     This is available standalone and as part of some kits, eg.\n     STM32F4DISCOVERY.\n     Link: <http://www.st.com/internet/evalboard/product/251168.jsp>\n   * STLINK-V3\n     This is available standalone and as part of some kits.\n     Link: <http://www.st.com/stlink-v3>\n\nFor info the original ST-LINK enumerates using the mass storage usb\nclass; however, its implementation is completely broken.  The result is\nthis causes issues under Linux.  The simplest solution is to get Linux\nto ignore the ST-LINK using one of the following methods:\n   * modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n   * add \"options usb-storage quirks=483:3744:i\" to /etc/modprobe.conf\n\n2.7 USB TI/Stellaris ICDI based\n===============================\n\nTexas Instruments has an adapter called ICDI. It is not to be confused\nwith the FTDI based adapters that were originally fitted to their\nevaluation boards.  This is the adapter fitted to the Stellaris\nLaunchPad.\n\n2.8 USB Nuvoton Nu-Link\n=======================\n\nNuvoton has an adapter called Nu-Link.  It is available either as\nstand-alone dongle and embedded on development boards.  It supports SWD,\nserial port bridge and mass storage for firmware update.  Both Nu-Link\nv1 and v2 are supported.\n\n2.9 USB CMSIS-DAP based\n=======================\n\nARM has released a interface standard called CMSIS-DAP that simplifies\nconnecting debuggers to ARM Cortex based targets\n<http://www.keil.com/support/man/docs/dapdebug/dapdebug_introduction.htm>.\n\n2.10 USB Other\n==============\n\n   * USBprog\n     Link: <http://shop.embedded-projects.net/> - which uses an Atmel\n     MEGA32 and a UBN9604\n\n   * USB - Presto\n     Link: <http://tools.asix.net/prg_presto.htm>\n\n   * Versaloon-Link\n     Link: <http://www.versaloon.com>\n\n   * ARM-JTAG-EW\n     Link: <http://www.olimex.com/dev/arm-jtag-ew.html>\n\n   * Buspirate\n     Link: <http://dangerousprototypes.com/bus-pirate-manual/>\n\n   * opendous\n     Link: <http://code.google.com/p/opendous-jtag/> - which uses an\n     AT90USB162\n\n   * estick\n     Link: <http://code.google.com/p/estick-jtag/>\n\n   * Keil ULINK v1\n     Link: <http://www.keil.com/ulink1/>\n\n   * TI XDS110 Debug Probe\n     Link:\n     <https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds110.html>\n\n     Link:\n     <https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html#xds110-support-utilities>\n\n2.11 IBM PC Parallel Printer Port Based\n=======================================\n\nThe two well-known \"JTAG Parallel Ports\" cables are the Xilinx DLC5 and\nthe Macraigor Wiggler.  There are many clones and variations of these on\nthe market.\n\nNote that parallel ports are becoming much less common, so if you have\nthe choice you should probably avoid these adapters in favor of\nUSB-based ones.\n\n   * Wiggler - There are many clones of this.\n     Link: <http://www.macraigor.com/wiggler.htm>\n\n   * DLC5 - From XILINX - There are many clones of this\n     Link: Search the web for: \"XILINX DLC5\" - it is no longer produced,\n     PDF schematics are easily found and it is easy to make.\n\n   * Amontec - JTAG Accelerator\n     Link: <http://www.amontec.com/jtag_accelerator.shtml>\n\n   * Wiggler2\n     Link:\n     <http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag>\n\n   * Wiggler_ntrst_inverted\n     Yet another variation - See the source code, src/jtag/parport.c\n\n   * old_amt_wiggler\n     Unknown - probably not on the market today\n\n   * arm-jtag\n     Link: Most likely <http://www.olimex.com/dev/arm-jtag.html>\n     [another wiggler clone]\n\n   * chameleon\n     Link: <http://www.amontec.com/chameleon.shtml>\n\n   * Triton\n     Unknown.\n\n   * Lattice\n     ispDownload from Lattice Semiconductor\n     <http://www.latticesemi.com/lit/docs/devtools/dlcable.pdf>\n\n   * flashlink\n     From STMicroelectronics;\n     Link:\n     <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/DM00039500.pdf>\n\n2.12 Other...\n=============\n\n   * ep93xx\n     An EP93xx based Linux machine using the GPIO pins directly.\n\n   * at91rm9200\n     Like the EP93xx - but an ATMEL AT91RM9200 based solution using the\n     GPIO pins on the chip.\n\n   * bcm2835gpio\n     A BCM2835-based board (e.g.  Raspberry Pi) using the GPIO pins of\n     the expansion header.\n\n   * imx_gpio\n     A NXP i.MX-based board (e.g.  Wandboard) using the GPIO pins\n     (should work on any i.MX processor).\n\n   * am335xgpio\n     A Texas Instruments AM335x-based board (e.g.  BeagleBone Black)\n     using the GPIO pins of the expansion headers.\n\n   * jtag_vpi\n     A JTAG driver acting as a client for the JTAG VPI server interface.\n\n     Link: <http://github.com/fjullien/jtag_vpi>\n\n   * vdebug\n     A driver for Cadence virtual Debug Interface to emulated or\n     simulated targets.  It implements a client connecting to the vdebug\n     server, which in turn communicates with the emulated or simulated\n     RTL model through a transactor.  The current version supports only\n     JTAG as a transport, but other virtual transports, like DAP are\n     planned.\n\n   * jtag_dpi\n     A JTAG driver acting as a client for the SystemVerilog Direct\n     Programming Interface (DPI) for JTAG devices.  DPI allows OpenOCD\n     to connect to the JTAG interface of a hardware model written in\n     SystemVerilog, for example, on an emulation model of target\n     hardware.\n\n   * xlnx_pcie_xvc\n     A JTAG driver exposing Xilinx Virtual Cable over PCI Express to\n     OpenOCD as JTAG/SWD interface.\n\n   * linuxgpiod\n     A bitbang JTAG driver using Linux GPIO through library libgpiod.\n\n   * sysfsgpio\n     A bitbang JTAG driver using Linux legacy sysfs GPIO. This is\n     deprecated from Linux v5.3; prefer using linuxgpiod.\n\n\u001f\nFile: openocd.info,  Node: About Jim-Tcl,  Next: Running,  Prev: Debug Adapter Hardware,  Up: Top\n\n3 About Jim-Tcl\n***************\n\nOpenOCD uses a small \"Tcl Interpreter\" known as Jim-Tcl.  This\nprogramming language provides a simple and extensible command\ninterpreter.\n\nAll commands presented in this Guide are extensions to Jim-Tcl.  You can\nuse them as simple commands, without needing to learn much of anything\nabout Tcl.  Alternatively, you can write Tcl programs with them.\n\nYou can learn more about Jim at its website, <http://jim.tcl.tk>.  There\nis an active and responsive community, get on the mailing list if you\nhave any questions.  Jim-Tcl maintainers also lurk on the OpenOCD\nmailing list.\n\n   * Jim vs.  Tcl\n     Jim-Tcl is a stripped down version of the well known Tcl language,\n     which can be found here: <http://www.tcl.tk>.  Jim-Tcl has far\n     fewer features.  Jim-Tcl is several dozens of .C files and .H files\n     and implements the basic Tcl command set.  In contrast: Tcl 8.6 is\n     a 4.2 MB .zip file containing 1540 files.\n\n   * Missing Features\n     Our practice has been: Add/clone the real Tcl feature if/when\n     needed.  We welcome Jim-Tcl improvements, not bloat.  Also there\n     are a large number of optional Jim-Tcl features that are not\n     enabled in OpenOCD.\n\n   * Scripts\n     OpenOCD configuration scripts are Jim-Tcl Scripts.  OpenOCD's\n     command interpreter today is a mixture of (newer) Jim-Tcl commands,\n     and the (older) original command interpreter.\n\n   * Commands\n     At the OpenOCD telnet command line (or via the GDB monitor command)\n     one can type a Tcl for() loop, set variables, etc.  Some of the\n     commands documented in this guide are implemented as Tcl scripts,\n     from a 'startup.tcl' file internal to the server.\n\n   * Historical Note\n     Jim-Tcl was introduced to OpenOCD in spring 2008.  Fall 2010,\n     before OpenOCD 0.5 release, OpenOCD switched to using Jim-Tcl as a\n     Git submodule, which greatly simplified upgrading Jim-Tcl to\n     benefit from new features and bugfixes in Jim-Tcl.\n\n   * Need a crash course in Tcl?\n     *Note Tcl Crash Course::.\n\n\u001f\nFile: openocd.info,  Node: Running,  Next: OpenOCD Project Setup,  Prev: About Jim-Tcl,  Up: Top\n\n4 Running\n*********\n\nProperly installing OpenOCD sets up your operating system to grant it\naccess to the debug adapters.  On Linux, this usually involves\ninstalling a file in '/etc/udev/rules.d,' so OpenOCD has permissions.\nAn example rules file that works for many common adapters is shipped\nwith OpenOCD in the 'contrib' directory.  MS-Windows needs complex and\nconfusing driver configuration for every peripheral.  Such issues are\nunique to each operating system, and are not detailed in this User's\nGuide.\n\nThen later you will invoke the OpenOCD server, with various options to\ntell it how each debug session should work.  The '--help' option shows:\nbash$ openocd --help\n\n--help       | -h       display this help\n--version    | -v       display OpenOCD version\n--file       | -f       use configuration file <name>\n--search     | -s       dir to search for config files and scripts\n--debug      | -d       set debug level to 3\n             | -d<n>    set debug level to <level>\n--log_output | -l       redirect log output to file <name>\n--command    | -c       run <command>\n\nIf you don't give any '-f' or '-c' options, OpenOCD tries to read the\nconfiguration file 'openocd.cfg'.  To specify one or more different\nconfiguration files, use '-f' options.  For example:\n\n     openocd -f config1.cfg -f config2.cfg -f config3.cfg\n\nConfiguration files and scripts are searched for in\n  1. the current directory,\n  2. any search dir specified on the command line using the '-s' option,\n  3. any search dir specified using the 'add_script_search_dir' command,\n  4. a directory in the 'OPENOCD_SCRIPTS' environment variable (if set),\n  5. '%APPDATA%/OpenOCD' (only on Windows),\n  6. '$HOME/Library/Preferences/org.openocd' (only on Darwin),\n  7. '$XDG_CONFIG_HOME/openocd' ('$XDG_CONFIG_HOME' defaults to\n     '$HOME/.config'),\n  8. '$HOME/.openocd',\n  9. the site wide script library '$pkgdatadir/site' and\n  10. the OpenOCD-supplied script library '$pkgdatadir/scripts'.\nThe first found file with a matching file name will be used.\n\n     Note: Don't try to use configuration script names or paths which\n     include the \"#\" character.  That character begins Tcl comments.\n\n4.1 Simple setup, no customization\n==================================\n\nIn the best case, you can use two scripts from one of the script\nlibraries, hook up your JTAG adapter, and start the server ...  and your\nJTAG setup will just work \"out of the box\".  Always try to start by\nreusing those scripts, but assume you'll need more customization even if\nthis works.  *Note OpenOCD Project Setup::.\n\nIf you find a script for your JTAG adapter, and for your board or\ntarget, you may be able to hook up your JTAG adapter then start the\nserver with some variation of one of the following:\n\n     openocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg\n     openocd -f interface/ftdi/ADAPTER.cfg -f board/MYBOARD.cfg\n\nYou might also need to configure which reset signals are present, using\n'-c 'reset_config trst_and_srst'' or something similar.  If all goes\nwell you'll see output something like\n\n     Open On-Chip Debugger 0.4.0 (2010-01-14-15:06)\n     For bug reports, read\n             http://openocd.org/doc/doxygen/bugs.html\n     Info : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477\n            (mfg: 0x23b, part: 0xba00, ver: 0x3)\n\nSeeing that \"tap/device found\" message, and no warnings, means the JTAG\ncommunication is working.  That's a key milestone, but you'll probably\nneed more project-specific setup.\n\n4.2 What OpenOCD does as it starts\n==================================\n\nOpenOCD starts by processing the configuration commands provided on the\ncommand line or, if there were no '-c command' or '-f file.cfg' options\ngiven, in 'openocd.cfg'.  *Note Configuration Stage: configurationstage.\nAt the end of the configuration stage it verifies the JTAG scan chain\ndefined using those commands; your configuration should ensure that this\nalways succeeds.  Normally, OpenOCD then starts running as a server.\nAlternatively, commands may be used to terminate the configuration stage\nearly, perform work (such as updating some flash memory), and then shut\ndown without acting as a server.\n\nOnce OpenOCD starts running as a server, it waits for connections from\nclients (Telnet, GDB, RPC) and processes the commands issued through\nthose channels.\n\nIf you are having problems, you can enable internal debug messages via\nthe '-d' option.\n\nAlso it is possible to interleave Jim-Tcl commands w/config scripts\nusing the '-c' command line switch.\n\nTo enable debug output (when reporting problems or working on OpenOCD\nitself), use the '-d' command line switch.  This sets the 'debug_level'\nto \"3\", outputting the most information, including debug messages.  The\ndefault setting is \"2\", outputting only informational messages, warnings\nand errors.  You can also change this setting from within a telnet or\ngdb session using 'debug_level<n>' (*note debug_level: debuglevel.).\n\nYou can redirect all output from the server to a file using the '-l\n<logfile>' switch.\n\nNote!  OpenOCD will launch the GDB & telnet server even if it can not\nestablish a connection with the target.  In general, it is possible for\nthe JTAG controller to be unresponsive until the target is set up\ncorrectly via e.g.  GDB monitor commands in a GDB init script.\n\n\u001f\nFile: openocd.info,  Node: OpenOCD Project Setup,  Next: Config File Guidelines,  Prev: Running,  Up: Top\n\n5 OpenOCD Project Setup\n***********************\n\nTo use OpenOCD with your development projects, you need to do more than\njust connect the JTAG adapter hardware (dongle) to your development\nboard and start the OpenOCD server.  You also need to configure your\nOpenOCD server so that it knows about your adapter and board, and helps\nyour work.  You may also want to connect OpenOCD to GDB, possibly using\nEclipse or some other GUI.\n\n5.1 Hooking up the JTAG Adapter\n===============================\n\nToday's most common case is a dongle with a JTAG cable on one side (such\nas a ribbon cable with a 10-pin or 20-pin IDC connector) and a USB cable\non the other.  Instead of USB, some dongles use Ethernet; older ones may\nuse a PC parallel port, or even a serial port.\n\n  1. _Start with power to your target board turned off_, and nothing\n     connected to your JTAG adapter.  If you're particularly paranoid,\n     unplug power to the board.  It's important to have the ground\n     signal properly set up, unless you are using a JTAG adapter which\n     provides galvanic isolation between the target board and the\n     debugging host.\n\n  2. _Be sure it's the right kind of JTAG connector._  If your dongle\n     has a 20-pin ARM connector, you need some kind of adapter (or\n     octopus, see below) to hook it up to boards using 14-pin or 10-pin\n     connectors ...  or to 20-pin connectors which don't use ARM's\n     pinout.\n\n     In the same vein, make sure the voltage levels are compatible.  Not\n     all JTAG adapters have the level shifters needed to work with 1.2\n     Volt boards.\n\n  3. _Be certain the cable is properly oriented_ or you might damage\n     your board.  In most cases there are only two possible ways to\n     connect the cable.  Connect the JTAG cable from your adapter to the\n     board.  Be sure it's firmly connected.\n\n     In the best case, the connector is keyed to physically prevent you\n     from inserting it wrong.  This is most often done using a slot on\n     the board's male connector housing, which must match a key on the\n     JTAG cable's female connector.  If there's no housing, then you\n     must look carefully and make sure pin 1 on the cable hooks up to\n     pin 1 on the board.  Ribbon cables are frequently all grey except\n     for a wire on one edge, which is red.  The red wire is pin 1.\n\n     Sometimes dongles provide cables where one end is an \"octopus\" of\n     color coded single-wire connectors, instead of a connector block.\n     These are great when converting from one JTAG pinout to another,\n     but are tedious to set up.  Use these with connector pinout\n     diagrams to help you match up the adapter signals to the right\n     board pins.\n\n  4. _Connect the adapter's other end_ once the JTAG cable is connected.\n     A USB, parallel, or serial port connector will go to the host which\n     you are using to run OpenOCD. For Ethernet, consult the\n     documentation and your network administrator.\n\n     For USB-based JTAG adapters you have an easy sanity check at this\n     point: does the host operating system see the JTAG adapter?  If\n     you're running Linux, try the 'lsusb' command.  If that host is an\n     MS-Windows host, you'll need to install a driver before OpenOCD\n     works.\n\n  5. _Connect the adapter's power supply, if needed._  This step is\n     primarily for non-USB adapters, but sometimes USB adapters need\n     extra power.\n\n  6. _Power up the target board._  Unless you just let the magic smoke\n     escape, you're now ready to set up the OpenOCD server so you can\n     use JTAG to work with that board.\n\nTalk with the OpenOCD server using telnet ('telnet localhost 4444' on\nmany systems) or GDB. *Note GDB and OpenOCD::.\n\n5.2 Project Directory\n=====================\n\nThere are many ways you can configure OpenOCD and start it up.\n\nA simple way to organize them all involves keeping a single directory\nfor your work with a given board.  When you start OpenOCD from that\ndirectory, it searches there first for configuration files, scripts,\nfiles accessed through semihosting, and for code you upload to the\ntarget board.  It is also the natural place to write files, such as log\nfiles and data you download from the board.\n\n5.3 Configuration Basics\n========================\n\nThere are two basic ways of configuring OpenOCD, and a variety of ways\nyou can mix them.  Think of the difference as just being how you start\nthe server:\n\n   * Many '-f file' or '-c command' options on the command line\n   * No options, but a \"user config file\" in the current directory named\n     'openocd.cfg'\n\nHere is an example 'openocd.cfg' file for a setup using a Signalyzer\nFT2232-based JTAG adapter to talk to a board with an Atmel AT91SAM7X256\nmicrocontroller:\n\n     source [find interface/ftdi/signalyzer.cfg]\n\n     # GDB can also flash my flash!\n     gdb_memory_map enable\n     gdb_flash_program enable\n\n     source [find target/sam7x256.cfg]\n\nHere is the command line equivalent of that configuration:\n\n     openocd -f interface/ftdi/signalyzer.cfg \\\n             -c \"gdb_memory_map enable\" \\\n             -c \"gdb_flash_program enable\" \\\n             -f target/sam7x256.cfg\n\nYou could wrap such long command lines in shell scripts, each supporting\na different development task.  One might re-flash the board with a\nspecific firmware version.  Another might set up a particular debugging\nor run-time environment.\n\n     Important: At this writing (October 2009) the command line method\n     has problems with how it treats variables.  For example, after '-c\n     \"set VAR value\"', or doing the same in a script, the variable VAR\n     will have no value that can be tested in a later script.\n\nHere we will focus on the simpler solution: one user config file,\nincluding basic configuration plus any TCL procedures to simplify your\nwork.\n\n5.4 User Config Files\n=====================\n\nA user configuration file ties together all the parts of a project in\none place.  One of the following will match your situation best:\n\n   * Ideally almost everything comes from configuration files provided\n     by someone else.  For example, OpenOCD distributes a 'scripts'\n     directory (probably in '/usr/share/openocd/scripts' on Linux).\n     Board and tool vendors can provide these too, as can individual\n     user sites; the '-s' command line option lets you say where to find\n     these files.  (*Note Running::.)  The AT91SAM7X256 example above\n     works this way.\n\n     Three main types of non-user configuration file each have their own\n     subdirectory in the 'scripts' directory:\n\n       1. interface - one for each different debug adapter;\n       2. board - one for each different board\n       3. target - the chips which integrate CPUs and other JTAG TAPs\n\n     Best case: include just two files, and they handle everything else.\n     The first is an interface config file.  The second is\n     board-specific, and it sets up the JTAG TAPs and their GDB targets\n     (by deferring to some 'target.cfg' file), declares all flash\n     memory, and leaves you nothing to do except meet your deadline:\n\n          source [find interface/olimex-jtag-tiny.cfg]\n          source [find board/csb337.cfg]\n\n     Boards with a single microcontroller often won't need more than the\n     target config file, as in the AT91SAM7X256 example.  That's because\n     there is no external memory (flash, DDR RAM), and the board\n     differences are encapsulated by application code.\n\n   * Maybe you don't know yet what your board looks like to JTAG. Once\n     you know the 'interface.cfg' file to use, you may need help from\n     OpenOCD to discover what's on the board.  Once you find the JTAG\n     TAPs, you can just search for appropriate target and board\n     configuration files ...  or write your own, from the bottom up.\n     *Note Autoprobing: autoprobing.\n\n   * You can often reuse some standard config files but need to write a\n     few new ones, probably a 'board.cfg' file.  You will be using\n     commands described later in this User's Guide, and working with the\n     guidelines in the next chapter.\n\n     For example, there may be configuration files for your JTAG adapter\n     and target chip, but you need a new board-specific config file\n     giving access to your particular flash chips.  Or you might need to\n     write another target chip configuration file for a new chip built\n     around the Cortex-M3 core.\n\n          Note: When you write new configuration files, please submit\n          them for inclusion in the next OpenOCD release.  For example,\n          a 'board/newboard.cfg' file will help the next users of that\n          board, and a 'target/newcpu.cfg' will help support users of\n          any board using that chip.\n\n   * You may need to write some C code.  It may be as simple as\n     supporting a new FT2232 or parport based adapter; a bit more\n     involved, like a NAND or NOR flash controller driver; or a big\n     piece of work like supporting a new chip architecture.\n\nReuse the existing config files when you can.  Look first in the\n'scripts/boards' area, then 'scripts/targets'.  You may find a board\nconfiguration that's a good example to follow.\n\nWhen you write config files, separate the reusable parts (things every\nuser of that interface, chip, or board needs) from ones specific to your\nenvironment and debugging approach.\n\n   * For example, a 'gdb-attach' event handler that invokes the 'reset\n     init' command will interfere with debugging early boot code, which\n     performs some of the same actions that the 'reset-init' event\n     handler does.\n\n   * Likewise, the 'arm9 vector_catch' command (or its siblings 'xscale\n     vector_catch' and 'cortex_m vector_catch') can be a time-saver\n     during some debug sessions, but don't make everyone use that\n     either.  Keep those kinds of debugging aids in your user config\n     file, along with messaging and tracing setup.  (*Note Software\n     Debug Messages and Tracing: softwaredebugmessagesandtracing.)\n\n   * You might need to override some defaults.  For example, you might\n     need to move, shrink, or back up the target's work area if your\n     application needs much SRAM.\n\n   * TCP/IP port configuration is another example of something which is\n     environment-specific, and should only appear in a user config file.\n     *Note TCP/IP Ports: tcpipports.\n\n5.5 Project-Specific Utilities\n==============================\n\nA few project-specific utility routines may well speed up your work.\nWrite them, and keep them in your project's user config file.\n\nFor example, if you are making a boot loader work on a board, it's nice\nto be able to debug the \"after it's loaded to RAM\" parts separately from\nthe finicky early code which sets up the DDR RAM controller and clocks.\nA script like this one, or a more GDB-aware sibling, may help:\n\n     proc ramboot { } {\n         # Reset, running the target's \"reset-init\" scripts\n         # to initialize clocks and the DDR RAM controller.\n         # Leave the CPU halted.\n         reset init\n\n         # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM.\n         load_image u-boot.bin 0x20000000\n\n         # Start running.\n         resume 0x20000000\n     }\n\nThen once that code is working you will need to make it boot from NOR\nflash; a different utility would help.  Alternatively, some developers\nwrite to flash using GDB. (You might use a similar script if you're\nworking with a flash based microcontroller application instead of a boot\nloader.)\n\n     proc newboot { } {\n         # Reset, leaving the CPU halted. The \"reset-init\" event\n         # proc gives faster access to the CPU and to NOR flash;\n         # \"reset halt\" would be slower.\n         reset init\n\n         # Write standard version of U-Boot into the first two\n         # sectors of NOR flash ... the standard version should\n         # do the same lowlevel init as \"reset-init\".\n         flash protect 0 0 1 off\n         flash erase_sector 0 0 1\n         flash write_bank 0 u-boot.bin 0x0\n         flash protect 0 0 1 on\n\n         # Reboot from scratch using that new boot loader.\n         reset run\n     }\n\nYou may need more complicated utility procedures when booting from NAND.\nThat often involves an extra bootloader stage, running from on-chip SRAM\nto perform DDR RAM setup so it can load the main bootloader code (which\nwon't fit into that SRAM).\n\nOther helper scripts might be used to write production system images,\ninvolving considerably more than just a three stage bootloader.\n\n5.6 Target Software Changes\n===========================\n\nSometimes you may want to make some small changes to the software you're\ndeveloping, to help make JTAG debugging work better.  For example, in C\nor assembly language code you might use '#ifdef JTAG_DEBUG' (or its\nconverse) around code handling issues like:\n\n   * Watchdog Timers...  Watchdog timers are typically used to\n     automatically reset systems if some application task doesn't\n     periodically reset the timer.  (The assumption is that the system\n     has locked up if the task can't run.)  When a JTAG debugger halts\n     the system, that task won't be able to run and reset the timer ...\n     potentially causing resets in the middle of your debug sessions.\n\n     It's rarely a good idea to disable such watchdogs, since their\n     usage needs to be debugged just like all other parts of your\n     firmware.  That might however be your only option.\n\n     Look instead for chip-specific ways to stop the watchdog from\n     counting while the system is in a debug halt state.  It may be\n     simplest to set that non-counting mode in your debugger startup\n     scripts.  You may however need a different approach when, for\n     example, a motor could be physically damaged by firmware remaining\n     inactive in a debug halt state.  That might involve a type of\n     firmware mode where that \"non-counting\" mode is disabled at the\n     beginning then re-enabled at the end; a watchdog reset might fire\n     and complicate the debug session, but hardware (or people) would be\n     protected.(1)\n\n   * ARM Semihosting...  When linked with a special runtime library\n     provided with many toolchains(2), your target code can use I/O\n     facilities on the debug host.  That library provides a small set of\n     system calls which are handled by OpenOCD. It can let the debugger\n     provide your system console and a file system, helping with early\n     debugging or providing a more capable environment for\n     sometimes-complex tasks like installing system firmware onto NAND\n     or SPI flash.\n\n   * ARM Wait-For-Interrupt...  Many ARM chips synchronize the JTAG\n     clock using the core clock.  Low power states which stop that core\n     clock thus prevent JTAG access.  Idle loops in tasking environments\n     often enter those low power states via the 'WFI' instruction (or\n     its coprocessor equivalent, before ARMv7).\n\n     You may want to _disable that instruction_ in source code, or\n     otherwise prevent using that state, to ensure you can get JTAG\n     access at any time.(3)  For example, the OpenOCD 'halt' command may\n     not work for an idle processor otherwise.\n\n   * Delay after reset...  Not all chips have good support for debugger\n     access right after reset; many LPC2xxx chips have issues here.\n     Similarly, applications that reconfigure pins used for JTAG access\n     as they start will also block debugger access.\n\n     To work with boards like this, _enable a short delay loop_ the\n     first thing after reset, before \"real\" startup activities.  For\n     example, one second's delay is usually more than enough time for a\n     JTAG debugger to attach, so that early code execution can be\n     debugged or firmware can be replaced.\n\n   * Debug Communications Channel (DCC)... Some processors include\n     mechanisms to send messages over JTAG. Many ARM cores support\n     these, as do some cores from other vendors.  (OpenOCD may be able\n     to use this DCC internally, speeding up some operations like\n     writing to memory.)\n\n     Your application may want to deliver various debugging messages\n     over JTAG, by _linking with a small library of code_ provided with\n     OpenOCD and using the utilities there to send various kinds of\n     message.  *Note Software Debug Messages and Tracing:\n     softwaredebugmessagesandtracing.\n\n5.7 Target Hardware Setup\n=========================\n\nChip vendors often provide software development boards which are highly\nconfigurable, so that they can support all options that product boards\nmay require.  _Make sure that any jumpers or switches match the system\nconfiguration you are working with._\n\nCommon issues include:\n\n   * JTAG setup ...  Boards may support more than one JTAG\n     configuration.  Examples include jumpers controlling pullups versus\n     pulldowns on the nTRST and/or nSRST signals, and choice of\n     connectors (e.g.  which of two headers on the base board, or one\n     from a daughtercard).  For some Texas Instruments boards, you may\n     need to jumper the EMU0 and EMU1 signals (which OpenOCD won't\n     currently control).\n\n   * Boot Modes ...  Complex chips often support multiple boot modes,\n     controlled by external jumpers.  Make sure this is set up\n     correctly.  For example many i.MX boards from NXP need to be\n     jumpered to \"ATX mode\" to start booting using the on-chip ROM, when\n     using second stage bootloader code stored in a NAND flash chip.\n\n     Such explicit configuration is common, and not limited to booting\n     from NAND. You might also need to set jumpers to start booting\n     using code loaded from an MMC/SD card; external SPI flash;\n     Ethernet, UART, or USB links; NOR flash; OneNAND flash; some\n     external host; or various other sources.\n\n   * Memory Addressing ...  Boards which support multiple boot modes may\n     also have jumpers to configure memory addressing.  One board, for\n     example, jumpers external chipselect 0 (used for booting) to\n     address either a large SRAM (which must be pre-loaded via JTAG),\n     NOR flash, or NAND flash.  When it's jumpered to address NAND\n     flash, that board must also be told to start booting from on-chip\n     ROM.\n\n     Your 'board.cfg' file may also need to be told this jumper\n     configuration, so that it can know whether to declare NOR flash\n     using 'flash bank' or instead declare NAND flash with 'nand\n     device'; and likewise which probe to perform in its 'reset-init'\n     handler.\n\n     A closely related issue is bus width.  Jumpers might need to\n     distinguish between 8 bit or 16 bit bus access for the flash used\n     to start booting.\n\n   * Peripheral Access ...  Development boards generally provide access\n     to every peripheral on the chip, sometimes in multiple modes (such\n     as by providing multiple audio codec chips).  This interacts with\n     software configuration of pin multiplexing, where for example a\n     given pin may be routed either to the MMC/SD controller or the GPIO\n     controller.  It also often interacts with configuration jumpers.\n     One jumper may be used to route signals to an MMC/SD card slot or\n     an expansion bus (which might in turn affect booting); others might\n     control which audio or video codecs are used.\n\nPlus you should of course have 'reset-init' event handlers which set up\nthe hardware to match that jumper configuration.  That includes in\nparticular any oscillator or PLL used to clock the CPU, and any memory\ncontrollers needed to access external memory and peripherals.  Without\nsuch handlers, you won't be able to access those resources without\nworking target firmware which can do that setup ...  this can be awkward\nwhen you're trying to debug that target firmware.  Even if there's a ROM\nbootloader which handles a few issues, it rarely provides full access to\nall board-specific capabilities.\n\n   ---------- Footnotes ----------\n\n   (1) Note that many systems support a \"monitor mode\" debug that is a\nsomewhat cleaner way to address such issues.  You can think of it as\nonly halting part of the system, maybe just one task, instead of the\nwhole thing.  At this writing, January 2010, OpenOCD based debugging\ndoes not support monitor mode debug, only \"halt mode\" debug.\n\n   (2) See chapter 8 \"Semihosting\" in ARM DUI 0203I\n(http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf),\nthe \"RealView Compilation Tools Developer Guide\".  The CodeSourcery EABI\ntoolchain also includes a semihosting library.\n\n   (3) As a more polite alternative, some processors have special\ndebug-oriented registers which can be used to change various features\nincluding how the low power states are clocked while debugging.  The\nSTM32 DBGMCU_CR register is an example; at the cost of extra power\nconsumption, JTAG can be used during low power states.\n\n\u001f\nFile: openocd.info,  Node: Config File Guidelines,  Next: Server Configuration,  Prev: OpenOCD Project Setup,  Up: Top\n\n6 Config File Guidelines\n************************\n\nThis chapter is aimed at any user who needs to write a config file,\nincluding developers and integrators of OpenOCD and any user who needs\nto get a new board working smoothly.  It provides guidelines for\ncreating those files.\n\nYou should find the following directories under $(INSTALLDIR)/scripts,\nwith config files maintained upstream.  Use them as-is where you can; or\nas models for new files.\n   * 'interface' ...  These are for debug adapters.  Files that specify\n     configuration to use specific JTAG, SWD and other adapters go here.\n   * 'board' ...  Think Circuit Board, PWA, PCB, they go by many names.\n     Board files contain initialization items that are specific to a\n     board.\n\n     They reuse target configuration files, since the same\n     microprocessor chips are used on many boards, but support for\n     external parts varies widely.  For example, the SDRAM\n     initialization sequence for the board, or the type of external\n     flash and what address it uses.  Any initialization sequence to\n     enable that external flash or SDRAM should be found in the board\n     file.  Boards may also contain multiple targets: two CPUs; or a CPU\n     and an FPGA.\n   * 'target' ...  Think chip.  The \"target\" directory represents the\n     JTAG TAPs on a chip which OpenOCD should control, not a board.  Two\n     common types of targets are ARM chips and FPGA or CPLD chips.  When\n     a chip has multiple TAPs (maybe it has both ARM and DSP cores), the\n     target config file defines all of them.\n   * _more_ ...  browse for other library files which may be useful.\n     For example, there are various generic and CPU-specific utilities.\n\nThe 'openocd.cfg' user config file may override features in any of the\nabove files by setting variables before sourcing the target file, or by\nadding commands specific to their situation.\n\n6.1 Interface Config Files\n==========================\n\nThe user config file should be able to source one of these files with a\ncommand like this:\n\n     source [find interface/FOOBAR.cfg]\n\nA preconfigured interface file should exist for every debug adapter in\nuse today with OpenOCD. That said, perhaps some of these config files\nhave only been used by the developer who created it.\n\nA separate chapter gives information about how to set these up.  *Note\nDebug Adapter Configuration::.  Read the OpenOCD source code (and\nDeveloper's Guide) if you have a new kind of hardware interface and need\nto provide a driver for it.\n\n -- Command: find 'filename'\n     Prints full path to FILENAME according to OpenOCD search rules.\n\n -- Command: ocd_find 'filename'\n     Prints full path to FILENAME according to OpenOCD search rules.\n     This is a low level function used by the 'find'.  Usually you want\n     to use 'find', instead.\n\n6.2 Board Config Files\n======================\n\nThe user config file should be able to source one of these files with a\ncommand like this:\n\n     source [find board/FOOBAR.cfg]\n\nThe point of a board config file is to package everything about a given\nboard that user config files need to know.  In summary the board files\nshould contain (if present)\n\n  1. One or more 'source [find target/...cfg]' statements\n  2. NOR flash configuration (*note NOR Configuration:\n     norconfiguration.)\n  3. NAND flash configuration (*note NAND Configuration:\n     nandconfiguration.)\n  4. Target 'reset' handlers for SDRAM and I/O configuration\n  5. JTAG adapter reset configuration (*note Reset Configuration::)\n  6. All things that are not \"inside a chip\"\n\nGeneric things inside target chips belong in target config files, not\nboard config files.  So for example a 'reset-init' event handler should\nknow board-specific oscillator and PLL parameters, which it passes to\ntarget-specific utility code.\n\nThe most complex task of a board config file is creating such a\n'reset-init' event handler.  Define those handlers last, after you\nverify the rest of the board configuration works.\n\n6.2.1 Communication Between Config files\n----------------------------------------\n\nIn addition to target-specific utility code, another way that board and\ntarget config files communicate is by following a convention on how to\nuse certain variables.\n\nThe full Tcl/Tk language supports \"namespaces\", but Jim-Tcl does not.\nThus the rule we follow in OpenOCD is this: Variables that begin with a\nleading underscore are temporary in nature, and can be modified and used\nat will within a target configuration file.\n\nComplex board config files can do the things like this, for a board with\nthree chips:\n\n     # Chip #1: PXA270 for network side, big endian\n     set CHIPNAME network\n     set ENDIAN big\n     source [find target/pxa270.cfg]\n     # on return: _TARGETNAME = network.cpu\n     # other commands can refer to the \"network.cpu\" target.\n     $_TARGETNAME configure .... events for this CPU..\n\n     # Chip #2: PXA270 for video side, little endian\n     set CHIPNAME video\n     set ENDIAN little\n     source [find target/pxa270.cfg]\n     # on return: _TARGETNAME = video.cpu\n     # other commands can refer to the \"video.cpu\" target.\n     $_TARGETNAME configure .... events for this CPU..\n\n     # Chip #3: Xilinx FPGA for glue logic\n     set CHIPNAME xilinx\n     unset ENDIAN\n     source [find target/spartan3.cfg]\n\nThat example is oversimplified because it doesn't show any flash memory,\nor the 'reset-init' event handlers to initialize external DRAM or\n(assuming it needs it) load a configuration into the FPGA. Such features\nare usually needed for low-level work with many boards, where \"low\nlevel\" implies that the board initialization software may not be\nworking.  (That's a common reason to need JTAG tools.  Another is to\nenable working with microcontroller-based systems, which often have no\ndebugging support except a JTAG connector.)\n\nTarget config files may also export utility functions to board and user\nconfig files.  Such functions should use name prefixes, to help avoid\nnaming collisions.\n\nBoard files could also accept input variables from user config files.\nFor example, there might be a 'J4_JUMPER' setting used to identify what\nkind of flash memory a development board is using, or how to set up\nother clocks and peripherals.\n\n6.2.2 Variable Naming Convention\n--------------------------------\n\nMost boards have only one instance of a chip.  However, it should be\neasy to create a board with more than one such chip (as shown above).\nAccordingly, we encourage these conventions for naming variables\nassociated with different 'target.cfg' files, to promote consistency and\nso that board files can override target defaults.\n\nInputs to target config files include:\n\n   * 'CHIPNAME' ...  This gives a name to the overall chip, and is used\n     as part of tap identifier dotted names.  While the default is\n     normally provided by the chip manufacturer, board files may need to\n     distinguish between instances of a chip.\n   * 'ENDIAN' ...  By default 'little' - although chips may hard-wire\n     'big'.  Chips that can't change endianness don't need to use this\n     variable.\n   * 'CPUTAPID' ...  When OpenOCD examines the JTAG chain, it can be\n     told verify the chips against the JTAG IDCODE register.  The target\n     file will hold one or more defaults, but sometimes the chip in a\n     board will use a different ID (perhaps a newer revision).\n\nOutputs from target config files include:\n\n   * '_TARGETNAME' ...  By convention, this variable is created by the\n     target configuration script.  The board configuration file may make\n     use of this variable to configure things like a \"reset init\"\n     script, or other things specific to that board and that target.  If\n     the chip has 2 targets, the names are '_TARGETNAME0',\n     '_TARGETNAME1', ...  etc.\n\n6.2.3 The reset-init Event Handler\n----------------------------------\n\nBoard config files run in the OpenOCD configuration stage; they can't\nuse TAPs or targets, since they haven't been fully set up yet.  This\nmeans you can't write memory or access chip registers; you can't even\nverify that a flash chip is present.  That's done later in event\nhandlers, of which the target 'reset-init' handler is one of the most\nimportant.\n\nExcept on microcontrollers, the basic job of 'reset-init' event handlers\nis setting up flash and DRAM, as normally handled by boot loaders.\nMicrocontrollers rarely use boot loaders; they run right out of their\non-chip flash and SRAM memory.  But they may want to use one of these\nhandlers too, if just for developer convenience.\n\n     Note: Because this is so very board-specific, and chip-specific, no\n     examples are included here.  Instead, look at the board config\n     files distributed with OpenOCD. If you have a boot loader, its\n     source code will help; so will configuration files for other JTAG\n     tools (*note Translating Configuration Files:\n     translatingconfigurationfiles.).\n\nSome of this code could probably be shared between different boards.\nFor example, setting up a DRAM controller often doesn't differ by much\nexcept the bus width (16 bits or 32?)  and memory timings, so a reusable\nTCL procedure loaded by the 'target.cfg' file might take those as\nparameters.  Similarly with oscillator, PLL, and clock setup; and\ndisabling the watchdog.  Structure the code cleanly, and provide\ncomments to help the next developer doing such work.  (_You might be\nthat next person_ trying to reuse init code!)\n\nThe last thing normally done in a 'reset-init' handler is probing\nwhatever flash memory was configured.  For most chips that needs to be\ndone while the associated target is halted, either because JTAG memory\naccess uses the CPU or to prevent conflicting CPU access.\n\n6.2.4 JTAG Clock Rate\n---------------------\n\nBefore your 'reset-init' handler has set up the PLLs and clocking, you\nmay need to run with a low JTAG clock rate.  *Note JTAG Speed:\njtagspeed.  Then you'd increase that rate after your handler has made it\npossible to use the faster JTAG clock.  When the initial low speed is\nboard-specific, for example because it depends on a board-specific\noscillator speed, then you should probably set it up in the board config\nfile; if it's target-specific, it belongs in the target config file.\n\nFor most ARM-based processors the fastest JTAG clock(1) is one sixth of\nthe CPU clock; or one eighth for ARM11 cores.  Consult chip\ndocumentation to determine the peak JTAG clock rate, which might be less\nthan that.\n\n     Warning: On most ARMs, JTAG clock detection is coupled to the core\n     clock, so software using a 'wait for interrupt' operation blocks\n     JTAG access.  Adaptive clocking provides a partial workaround, but\n     a more complete solution just avoids using that instruction with\n     JTAG debuggers.\n\nIf both the chip and the board support adaptive clocking, use the\n'jtag_rclk' command, in case your board is used with JTAG adapter which\nalso supports it.  Otherwise use 'adapter speed'.  Set the slow rate at\nthe beginning of the reset sequence, and the faster rate as soon as the\nclocks are at full speed.\n\n6.2.5 The init_board procedure\n------------------------------\n\nThe concept of 'init_board' procedure is very similar to 'init_targets'\n(*Note The init_targets procedure: theinittargetsprocedure.)  - it's a\nreplacement of \"linear\" configuration scripts.  This procedure is meant\nto be executed when OpenOCD enters run stage (*Note Entering the Run\nStage: enteringtherunstage,) after 'init_targets'.  The idea to have\nseparate 'init_targets' and 'init_board' procedures is to allow the\nfirst one to configure everything target specific (internal flash,\ninternal RAM, etc.)  and the second one to configure everything board\nspecific (reset signals, chip frequency, reset-init event handler,\nexternal memory, etc.).  Additionally \"linear\" board config file will\nmost likely fail when target config file uses 'init_targets' scheme\n(\"linear\" script is executed before 'init' and 'init_targets' - after),\nso separating these two configuration stages is very convenient, as the\neasiest way to overcome this problem is to convert board config file to\nuse 'init_board' procedure.  Board config scripts don't need to override\n'init_targets' defined in target config files when they only need to add\nsome specifics.\n\nJust as 'init_targets', the 'init_board' procedure can be overridden by\n\"next level\" script (which sources the original), allowing greater code\nreuse.\n\n     ### board_file.cfg ###\n\n     # source target file that does most of the config in init_targets\n     source [find target/target.cfg]\n\n     proc enable_fast_clock {} {\n         # enables fast on-board clock source\n         # configures the chip to use it\n     }\n\n     # initialize only board specifics - reset, clock, adapter frequency\n     proc init_board {} {\n         reset_config trst_and_srst trst_pulls_srst\n\n         $_TARGETNAME configure -event reset-start {\n             adapter speed 100\n         }\n\n         $_TARGETNAME configure -event reset-init {\n             enable_fast_clock\n             adapter speed 10000\n         }\n     }\n\n6.3 Target Config Files\n=======================\n\nBoard config files communicate with target config files using naming\nconventions as described above, and may source one or more target config\nfiles like this:\n\n     source [find target/FOOBAR.cfg]\n\nThe point of a target config file is to package everything about a given\nchip that board config files need to know.  In summary the target files\nshould contain\n\n  1. Set defaults\n  2. Add TAPs to the scan chain\n  3. Add CPU targets (includes GDB support)\n  4. CPU/Chip/CPU-Core specific features\n  5. On-Chip flash\n\nAs a rule of thumb, a target file sets up only one chip.  For a\nmicrocontroller, that will often include a single TAP, which is a CPU\nneeding a GDB target, and its on-chip flash.\n\nMore complex chips may include multiple TAPs, and the target config file\nmay need to define them all before OpenOCD can talk to the chip.  For\nexample, some phone chips have JTAG scan chains that include an ARM core\nfor operating system use, a DSP, another ARM core embedded in an image\nprocessing engine, and other processing engines.\n\n6.3.1 Default Value Boiler Plate Code\n-------------------------------------\n\nAll target configuration files should start with code like this, letting\nboard config files express environment-specific differences in how\nthings should be set up.\n\n     # Boards may override chip names, perhaps based on role,\n     # but the default should match what the vendor uses\n     if { [info exists CHIPNAME] } {\n        set  _CHIPNAME $CHIPNAME\n     } else {\n        set  _CHIPNAME sam7x256\n     }\n\n     # ONLY use ENDIAN with targets that can change it.\n     if { [info exists ENDIAN] } {\n        set  _ENDIAN $ENDIAN\n     } else {\n        set  _ENDIAN little\n     }\n\n     # TAP identifiers may change as chips mature, for example with\n     # new revision fields (the \"3\" here). Pick a good default; you\n     # can pass several such identifiers to the \"jtag newtap\" command.\n     if { [info exists CPUTAPID ] } {\n        set _CPUTAPID $CPUTAPID\n     } else {\n        set _CPUTAPID 0x3f0f0f0f\n     }\n\n_Remember:_ Board config files may include multiple target config files,\nor the same target file multiple times (changing at least 'CHIPNAME').\n\nLikewise, the target configuration file should define '_TARGETNAME' (or\n'_TARGETNAME0' etc) and use it later on when defining debug targets:\n\n     set _TARGETNAME $_CHIPNAME.cpu\n     target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n6.3.2 Adding TAPs to the Scan Chain\n-----------------------------------\n\nAfter the \"defaults\" are set up, add the TAPs on each chip to the JTAG\nscan chain.  *Note TAP Declaration::, and the naming convention for\ntaps.\n\nIn the simplest case the chip has only one TAP, probably for a CPU or\nFPGA. The config file for the Atmel AT91SAM7X256 looks (in part) like\nthis:\n\n     jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nA board with two such at91sam7 chips would be able to source such a\nconfig file twice, with different values for 'CHIPNAME', so it adds a\ndifferent TAP each time.\n\nIf there are nonzero '-expected-id' values, OpenOCD attempts to verify\nthe actual tap id against those values.  It will issue error messages if\nthere is mismatch, which can help to pinpoint problems in OpenOCD\nconfigurations.\n\n     JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f\n                     (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)\n     ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f\n     ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1\n     ERROR:      got: mfg: 0x787, part: 0xf0f0, ver: 0x3\n\nThere are more complex examples too, with chips that have multiple TAPs.\nOnes worth looking at include:\n\n   * 'target/omap3530.cfg' - with disabled ARM and DSP, plus a JRC to\n     enable them\n   * 'target/str912.cfg' - with flash, CPU, and boundary scan\n   * 'target/ti_dm355.cfg' - with ETM, ARM, and JRC (this JRC is not\n     currently used)\n\n6.3.3 Add CPU targets\n---------------------\n\nAfter adding a TAP for a CPU, you should set it up so that GDB and other\ncommands can use it.  *Note CPU Configuration::.  For the at91sam7\nexample above, the command can look like this; note that '$_ENDIAN' is\nnot needed, since OpenOCD defaults to little endian, and this chip\ndoesn't support changing that.\n\n     set _TARGETNAME $_CHIPNAME.cpu\n     target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\nWork areas are small RAM areas associated with CPU targets.  They are\nused by OpenOCD to speed up downloads, and to download small snippets of\ncode to program flash chips.  If the chip includes a form of\n\"on-chip-ram\" - and many do - define a work area if you can.  Again\nusing the at91sam7 as an example, this can look like:\n\n     $_TARGETNAME configure -work-area-phys 0x00200000 \\\n                  -work-area-size 0x4000 -work-area-backup 0\n\n6.3.4 Define CPU targets working in SMP\n---------------------------------------\n\nAfter setting targets, you can define a list of targets working in SMP.\n\n     set _TARGETNAME_1 $_CHIPNAME.cpu1\n     set _TARGETNAME_2 $_CHIPNAME.cpu2\n     target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \\\n     -coreid 0 -dbgbase $_DAP_DBG1\n     target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \\\n     -coreid 1 -dbgbase $_DAP_DBG2\n     #define 2 targets working in smp.\n     target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\nIn the above example on cortex_a, 2 cpus are working in SMP. In SMP only\none GDB instance is created and :\n   * a set of hardware breakpoint sets the same breakpoint on all\n     targets in the list.\n   * halt command triggers the halt of all targets in the list.\n   * resume command triggers the write context and the restart of all\n     targets in the list.\n   * following a breakpoint: the target stopped by the breakpoint is\n     displayed to the GDB session.\n   * dedicated GDB serial protocol packets are implemented for\n     switching/retrieving the target displayed by the GDB session *note\n     Using OpenOCD SMP with GDB: usingopenocdsmpwithgdb.\n\nThe SMP behaviour can be disabled/enabled dynamically.  On cortex_a\nfollowing command have been implemented.\n   * cortex_a smp on : enable SMP mode, behaviour is as described above.\n   * cortex_a smp off : disable SMP mode, the current target is the one\n     displayed in the GDB session, only this target is now controlled by\n     GDB session.  This behaviour is useful during system boot up.\n   * cortex_a smp : display current SMP mode.\n   * cortex_a smp_gdb : display/fix the core id displayed in GDB session\n     see following example.\n\n     >cortex_a smp_gdb\n     gdb coreid  0 -> -1\n     #0 : coreid 0 is displayed to GDB ,\n     #-> -1 : next resume triggers a real resume\n     > cortex_a smp_gdb 1\n     gdb coreid  0 -> 1\n     #0 :coreid 0 is displayed to GDB ,\n     #->1  : next resume displays coreid 1 to GDB\n     > resume\n     > cortex_a smp_gdb\n     gdb coreid  1 -> 1\n     #1 :coreid 1 is displayed to GDB ,\n     #->1 : next resume displays coreid 1 to GDB\n     > cortex_a smp_gdb -1\n     gdb coreid  1 -> -1\n     #1 :coreid 1 is displayed to GDB,\n     #->-1 : next resume triggers a real resume\n\n6.3.5 Chip Reset Setup\n----------------------\n\nAs a rule, you should put the 'reset_config' command into the board\nfile.  Most things you think you know about a chip can be tweaked by the\nboard.\n\nSome chips have specific ways the TRST and SRST signals are managed.  In\nthe unusual case that these are _chip specific_ and can never be changed\nby board wiring, they could go here.  For example, some chips can't\nsupport JTAG debugging without both signals.\n\nProvide a 'reset-assert' event handler if you can.  Such a handler uses\nJTAG operations to reset the target, letting this target config be used\nin systems which don't provide the optional SRST signal, or on systems\nwhere you don't want to reset all targets at once.  Such a handler might\nwrite to chip registers to force a reset, use a JRC to do that\n(preferable - the target may be wedged!), or force a watchdog timer to\ntrigger.  (For Cortex-M targets, this is not necessary.  The target\ndriver knows how to use trigger an NVIC reset when SRST is not\navailable.)\n\nSome chips need special attention during reset handling if they're going\nto be used with JTAG. An example might be needing to send some commands\nright after the target's TAP has been reset, providing a\n'reset-deassert-post' event handler that writes a chip register to\nreport that JTAG debugging is being done.  Another would be\nreconfiguring the watchdog so that it stops counting while the core is\nhalted in the debugger.\n\nJTAG clocking constraints often change during reset, and in some cases\ntarget config files (rather than board config files) are the right\nplaces to handle some of those issues.  For example, immediately after\nreset most chips run using a slower clock than they will use later.\nThat means that after reset (and potentially, as OpenOCD first starts\nup) they must use a slower JTAG clock rate than they will use later.\n*Note JTAG Speed: jtagspeed.\n\n     Important: When you are debugging code that runs right after chip\n     reset, getting these issues right is critical.  In particular, if\n     you see intermittent failures when OpenOCD verifies the scan chain\n     after reset, look at how you are setting up JTAG clocking.\n\n6.3.6 The init_targets procedure\n--------------------------------\n\nTarget config files can either be \"linear\" (script executed line-by-line\nwhen parsed in configuration stage, *Note Configuration Stage:\nconfigurationstage,) or they can contain a special procedure called\n'init_targets', which will be executed when entering run stage (after\nparsing all config files or after 'init' command, *Note Entering the Run\nStage: enteringtherunstage.)  Such procedure can be overridden by \"next\nlevel\" script (which sources the original).  This concept facilitates\ncode reuse when basic target config files provide generic configuration\nprocedures and 'init_targets' procedure, which can then be sourced and\nenhanced or changed in a \"more specific\" target config file.  This is\nnot possible with \"linear\" config scripts, because sourcing them\nexecutes every initialization commands they provide.\n\n     ### generic_file.cfg ###\n\n     proc setup_my_chip {chip_name flash_size ram_size} {\n         # basic initialization procedure ...\n     }\n\n     proc init_targets {} {\n         # initializes generic chip with 4kB of flash and 1kB of RAM\n         setup_my_chip MY_GENERIC_CHIP 4096 1024\n     }\n\n     ### specific_file.cfg ###\n\n     source [find target/generic_file.cfg]\n\n     proc init_targets {} {\n         # initializes specific chip with 128kB of flash and 64kB of RAM\n         setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536\n     }\n\nThe easiest way to convert \"linear\" config files to 'init_targets'\nversion is to enclose every line of \"code\" (i.e.  not 'source' commands,\nprocedures, etc.)  in this procedure.\n\nFor an example of this scheme see LPC2000 target config files.\n\nThe 'init_boards' procedure is a similar concept concerning board config\nfiles (*Note The init_board procedure: theinitboardprocedure.)\n\n6.3.7 The init_target_events procedure\n--------------------------------------\n\nA special procedure called 'init_target_events' is run just after\n'init_targets' (*Note The init_targets procedure:\ntheinittargetsprocedure.)  and before 'init_board' (*Note The init_board\nprocedure: theinitboardprocedure.)  It is used to set up default target\nevents for the targets that do not have those events already assigned.\n\n6.3.8 ARM Core Specific Hacks\n-----------------------------\n\nIf the chip has a DCC, enable it.  If the chip is an ARM9 with some\nspecial high speed download features - enable it.\n\nIf present, the MMU, the MPU and the CACHE should be disabled.\n\nSome ARM cores are equipped with trace support, which permits\nexamination of the instruction and data bus activity.  Trace activity is\ncontrolled through an \"Embedded Trace Module\" (ETM) on one of the core's\nscan chains.  The ETM emits voluminous data through a \"trace port\".\n(*Note ARM Hardware Tracing: armhardwaretracing.)  If you are using an\nexternal trace port, configure it in your board config file.  If you are\nusing an on-chip \"Embedded Trace Buffer\" (ETB), configure it in your\ntarget config file.\n\n     etm config $_TARGETNAME 16 normal full etb\n     etb config $_TARGETNAME $_CHIPNAME.etb\n\n6.3.9 Internal Flash Configuration\n----------------------------------\n\nThis applies ONLY TO MICROCONTROLLERS that have flash built in.\n\nNever ever in the \"target configuration file\" define any type of flash\nthat is external to the chip.  (For example a BOOT flash on Chip Select\n0.)  Such flash information goes in a board file - not the TARGET (chip)\nfile.\n\nExamples:\n   * at91sam7x256 - has 256K flash YES enable it.\n   * str912 - has flash internal YES enable it.\n   * imx27 - uses boot flash on CS0 - it goes in the board file.\n   * pxa270 - again - CS0 flash - it goes in the board file.\n\n6.4 Translating Configuration Files\n===================================\n\nIf you have a configuration file for another hardware debugger or\ntoolset (Abatron, BDI2000, BDI3000, CCS, Lauterbach, SEGGER, Macraigor,\netc.), translating it into OpenOCD syntax is often quite\nstraightforward.  The most tricky part of creating a configuration\nscript is oftentimes the reset init sequence where e.g.  PLLs, DRAM and\nthe like is set up.\n\nOne trick that you can use when translating is to write small Tcl\nprocedures to translate the syntax into OpenOCD syntax.  This can avoid\nmanual translation errors and make it easier to convert other scripts\nlater on.\n\nExample of transforming quirky arguments to a simple search and replace\njob:\n\n     #   Lauterbach syntax(?)\n     #\n     #       Data.Set c15:0x042f %long 0x40000015\n     #\n     #   OpenOCD syntax when using procedure below.\n     #\n     #       setc15 0x01 0x00050078\n\n     proc setc15 {regs value} {\n         global TARGETNAME\n\n         echo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n         arm mcr 15 [expr {($regs >> 12) & 0x7}] \\\n             [expr {($regs >> 0) & 0xf}] [expr {($regs >> 4) & 0xf}] \\\n             [expr {($regs >> 8) & 0x7}] $value\n     }\n\n   ---------- Footnotes ----------\n\n   (1) A FAQ <http://www.arm.com/support/faqdev/4170.html> gives\ndetails.\n\n\u001f\nFile: openocd.info,  Node: Server Configuration,  Next: Debug Adapter Configuration,  Prev: Config File Guidelines,  Up: Top\n\n7 Server Configuration\n**********************\n\nThe commands here are commonly found in the openocd.cfg file and are\nused to specify what TCP/IP ports are used, and how GDB should be\nsupported.\n\n7.1 Configuration Stage\n=======================\n\nWhen the OpenOCD server process starts up, it enters a _configuration\nstage_ which is the only time that certain commands, _configuration\ncommands_, may be issued.  Normally, configuration commands are only\navailable inside startup scripts.\n\nIn this manual, the definition of a configuration command is presented\nas a _Config Command_, not as a _Command_ which may be issued\ninteractively.  The runtime 'help' command also highlights configuration\ncommands, and those which may be issued at any time.\n\nThose configuration commands include declaration of TAPs, flash banks,\nthe interface used for JTAG communication, and other basic setup.  The\nserver must leave the configuration stage before it may access or\nactivate TAPs.  After it leaves this stage, configuration commands may\nno longer be issued.\n\n -- Command: command mode [command_name]\n     Returns the command modes allowed by a command: 'any', 'config', or\n     'exec'.  If no command is specified, returns the current command\n     mode.  Returns 'unknown' if an unknown command is given.  Command\n     can be multiple tokens.  (command valid any time)\n\n     In this document, the modes are described as stages, 'config' and\n     'exec' mode correspond configuration stage and run stage.  'any'\n     means the command can be executed in either stages.  *Note\n     Configuration Stage: configurationstage, and *Note Entering the Run\n     Stage: enteringtherunstage.\n\n7.2 Entering the Run Stage\n==========================\n\nThe first thing OpenOCD does after leaving the configuration stage is to\nverify that it can talk to the scan chain (list of TAPs) which has been\nconfigured.  It will warn if it doesn't find TAPs it expects to find, or\nfinds TAPs that aren't supposed to be there.  You should see no errors\nat this point.  If you see errors, resolve them by correcting the\ncommands you used to configure the server.  Common errors include using\nan initial JTAG speed that's too fast, and not providing the right\nIDCODE values for the TAPs on the scan chain.\n\nOnce OpenOCD has entered the run stage, a number of commands become\navailable.  A number of these relate to the debug targets you may have\ndeclared.  For example, the 'mww' command will not be available until a\ntarget has been successfully instantiated.  If you want to use those\ncommands, you may need to force entry to the run stage.\n\n -- Config Command: init\n     This command terminates the configuration stage and enters the run\n     stage.  This helps when you need to have the startup scripts manage\n     tasks such as resetting the target, programming flash, etc.  To\n     reset the CPU upon startup, add \"init\" and \"reset\" at the end of\n     the config script or at the end of the OpenOCD command line using\n     the '-c' command line switch.\n\n     If this command does not appear in any startup/configuration file\n     OpenOCD executes the command for you after processing all\n     configuration files and/or command line options.\n\n     NOTE: This command normally occurs near the end of your openocd.cfg\n     file to force OpenOCD to \"initialize\" and make the targets ready.\n     For example: If your openocd.cfg file needs to read/write memory on\n     your target, 'init' must occur before the memory read/write\n     commands.  This includes 'nand probe'.\n\n     'init' calls the following internal OpenOCD commands to initialize\n     corresponding subsystems:\n      -- Config Command: target init\n      -- Command: transport init\n      -- Command: dap init\n      -- Config Command: flash init\n      -- Config Command: nand init\n      -- Config Command: pld init\n      -- Command: tpiu init\n\n     At last, 'init' executes all the commands that are specified in the\n     TCL list POST_INIT_COMMANDS.  The commands are executed in the same\n     order they occupy in the list.  If one of the commands fails, then\n     the error is propagated and OpenOCD fails too.\n          lappend post_init_commands {echo \"OpenOCD successfully initialized.\"}\n          lappend post_init_commands {echo \"Have fun with OpenOCD !\"}\n\n -- Config Command: noinit\n     Prevent OpenOCD from implicit 'init' call at the end of startup.\n     Allows issuing configuration commands over telnet or Tcl\n     connection.  When you are done with configuration use 'init' to\n     enter the run stage.\n\n -- Overridable Procedure: jtag_init\n     This is invoked at server startup to verify that it can talk to the\n     scan chain (list of TAPs) which has been configured.\n\n     The default implementation first tries 'jtag arp_init', which uses\n     only a lightweight JTAG reset before examining the scan chain.  If\n     that fails, it tries again, using a harder reset from the\n     overridable procedure 'init_reset'.\n\n     Implementations must have verified the JTAG scan chain before they\n     return.  This is done by calling 'jtag arp_init' (or 'jtag\n     arp_init-reset').\n\n7.3 TCP/IP Ports\n================\n\nThe OpenOCD server accepts remote commands in several syntaxes.  Each\nsyntax uses a different TCP/IP port, which you may specify only during\nconfiguration (before those ports are opened).\n\nFor reasons including security, you may wish to prevent remote access\nusing one or more of these ports.  In such cases, just specify the\nrelevant port number as \"disabled\".  If you disable all access through\nTCP/IP, you will need to use the command line '-pipe' option.\n\n -- Config Command: gdb_port [number]\n     Normally gdb listens to a TCP/IP port, but GDB can also communicate\n     via pipes(stdin/out or named pipes).  The name \"gdb_port\" stuck\n     because it covers probably more than 90% of the normal use cases.\n\n     No arguments reports GDB port.  \"pipe\" means listen to stdin output\n     to stdout, an integer is base port number, \"disabled\" disables the\n     gdb server.\n\n     When using \"pipe\", also use log_output to redirect the log output\n     to a file so as not to flood the stdin/out pipes.\n\n     Any other string is interpreted as named pipe to listen to.  Output\n     pipe is the same name as input pipe, but with 'o' appended, e.g.\n     /var/gdb, /var/gdbo.\n\n     The GDB port for the first target will be the base port, the second\n     target will listen on gdb_port + 1, and so on.  When not specified\n     during the configuration stage, the port NUMBER defaults to 3333.\n     When NUMBER is not a numeric value, incrementing it to compute the\n     next port number does not work.  In this case, specify the proper\n     NUMBER for each target by using the option '-gdb-port' of the\n     commands 'target create' or '$target_name configure'.  *Note option\n     -gdb-port: gdbportoverride.\n\n     Note: when using \"gdb_port pipe\", increasing the default remote\n     timeout in gdb (with 'set remotetimeout') is recommended.  An\n     insufficient timeout may cause initialization to fail with \"Unknown\n     remote qXfer reply: OK\".\n\n -- Config Command: tcl_port [number]\n     Specify or query the port used for a simplified RPC connection that\n     can be used by clients to issue TCL commands and get the output\n     from the Tcl engine.  Intended as a machine interface.  When not\n     specified during the configuration stage, the port NUMBER defaults\n     to 6666.  When specified as \"disabled\", this service is not\n     activated.\n\n -- Config Command: telnet_port [number]\n     Specify or query the port on which to listen for incoming telnet\n     connections.  This port is intended for interaction with one human\n     through TCL commands.  When not specified during the configuration\n     stage, the port NUMBER defaults to 4444.  When specified as\n     \"disabled\", this service is not activated.\n\n7.4 GDB Configuration\n=====================\n\nYou can reconfigure some GDB behaviors if needed.  The ones listed here\nare static and global.  *Note Target Configuration: targetconfiguration,\nabout configuring individual targets.  *Note Target Events:\ntargetevents, about configuring target-specific event handling.\n\n -- Command: gdb_breakpoint_override [hard|soft|disable]\n     Force breakpoint type for gdb 'break' commands.  This option\n     supports GDB GUIs which don't distinguish hard versus soft\n     breakpoints, if the default OpenOCD and GDB behaviour is not\n     sufficient.  GDB normally uses hardware breakpoints if the memory\n     map has been set up for flash regions.\n\n -- Config Command: gdb_flash_program (enable|disable)\n     Set to 'enable' to cause OpenOCD to program the flash memory when a\n     vFlash packet is received.  The default behaviour is 'enable'.\n\n -- Config Command: gdb_memory_map (enable|disable)\n     Set to 'enable' to cause OpenOCD to send the memory configuration\n     to GDB when requested.  GDB will then know when to set hardware\n     breakpoints, and program flash using the GDB load command.\n     'gdb_flash_program enable' must also be enabled for flash\n     programming to work.  Default behaviour is 'enable'.  *Note\n     gdb_flash_program: gdbflashprogram.\n\n -- Config Command: gdb_report_data_abort (enable|disable)\n     Specifies whether data aborts cause an error to be reported by GDB\n     memory read packets.  The default behaviour is 'disable'; use\n     'enable' see these errors reported.\n\n -- Config Command: gdb_report_register_access_error (enable|disable)\n     Specifies whether register accesses requested by GDB register\n     read/write packets report errors or not.  The default behaviour is\n     'disable'; use 'enable' see these errors reported.\n\n -- Config Command: gdb_target_description (enable|disable)\n     Set to 'enable' to cause OpenOCD to send the target descriptions to\n     gdb via qXfer:features:read packet.  The default behaviour is\n     'enable'.\n\n -- Command: gdb_save_tdesc\n     Saves the target description file to the local file system.\n\n     The file name is target_name.xml.\n\n7.5 Event Polling\n=================\n\nHardware debuggers are parts of asynchronous systems, where significant\nevents can happen at any time.  The OpenOCD server needs to detect some\nof these events, so it can report them to through TCL command line or to\nGDB.\n\nExamples of such events include:\n\n   * One of the targets can stop running ...  maybe it triggers a code\n     breakpoint or data watchpoint, or halts itself.\n   * Messages may be sent over \"debug message\" channels ...  many\n     targets support such messages sent over JTAG, for receipt by the\n     person debugging or tools.\n   * Loss of power ...  some adapters can detect these events.\n   * Resets not issued through JTAG ...  such reset sources can include\n     button presses or other system hardware, sometimes including the\n     target itself (perhaps through a watchdog).\n   * Debug instrumentation sometimes supports event triggering such as\n     \"trace buffer full\" (so it can quickly be emptied) or other signals\n     (to correlate with code behavior).\n\nNone of those events are signaled through standard JTAG signals.\nHowever, most conventions for JTAG connectors include voltage level and\nsystem reset (SRST) signal detection.  Some connectors also include\ninstrumentation signals, which can imply events when those signals are\ninputs.\n\nIn general, OpenOCD needs to periodically check for those events, either\nby looking at the status of signals on the JTAG connector or by sending\nsynchronous \"tell me your status\" JTAG requests to the various active\ntargets.  There is a command to manage and monitor that polling, which\nis normally done in the background.\n\n -- Command: poll [on|off]\n     Poll the current target for its current state.  (Also, *note target\n     curstate: targetcurstate.)  If that target is in debug mode,\n     architecture specific information about the current state is\n     printed.  An optional parameter allows background polling to be\n     enabled and disabled.\n\n     You could use this from the TCL command shell, or from GDB using\n     'monitor poll' command.  Leave background polling enabled while\n     you're using GDB.\n          > poll\n          background polling: on\n          target state: halted\n          target halted in ARM state due to debug-request, \\\n                         current mode: Supervisor\n          cpsr: 0x800000d3 pc: 0x11081bfc\n          MMU: disabled, D-Cache: disabled, I-Cache: enabled\n          >\n\n\u001f\nFile: openocd.info,  Node: Debug Adapter Configuration,  Next: Reset Configuration,  Prev: Server Configuration,  Up: Top\n\n8 Debug Adapter Configuration\n*****************************\n\nCorrectly installing OpenOCD includes making your operating system give\nOpenOCD access to debug adapters.  Once that has been done, Tcl commands\nare used to select which one is used, and to configure how it is used.\n\n     Note: Because OpenOCD started out with a focus purely on JTAG, you\n     may find places where it wrongly presumes JTAG is the only\n     transport protocol in use.  Be aware that recent versions of\n     OpenOCD are removing that limitation.  JTAG remains more functional\n     than most other transports.  Other transports do not support\n     boundary scan operations, or may be specific to a given chip\n     vendor.  Some might be usable only for programming flash memory,\n     instead of also for debugging.\n\nDebug Adapters/Interfaces/Dongles are normally configured through\ncommands in an interface configuration file which is sourced by your\n'openocd.cfg' file, or through a command line '-f interface/....cfg'\noption.\n\n     source [find interface/olimex-jtag-tiny.cfg]\n\nThese commands tell OpenOCD what type of JTAG adapter you have, and how\nto talk to it.  A few cases are so simple that you only need to say what\ndriver to use:\n\n     # jlink interface\n     adapter driver jlink\n\nMost adapters need a bit more configuration than that.\n\n8.1 Adapter Configuration\n=========================\n\nThe 'adapter driver' command tells OpenOCD what type of debug adapter\nyou are using.  Depending on the type of adapter, you may need to use\none or more additional commands to further identify or configure the\nadapter.\n\n -- Config Command: adapter driver name\n     Use the adapter driver NAME to connect to the target.\n\n -- Command: adapter list\n     List the debug adapter drivers that have been built into the\n     running copy of OpenOCD.\n -- Config Command: adapter transports transport_name+\n     Specifies the transports supported by this debug adapter.  The\n     adapter driver builds-in similar knowledge; use this only when\n     external configuration (such as jumpering) changes what the\n     hardware can support.\n\n -- Command: adapter name\n     Returns the name of the debug adapter driver being used.\n\n -- Config Command: adapter usb location [<bus>-<port>[.<port>]...]\n     Displays or specifies the physical USB port of the adapter to use.\n     The path roots at BUS and walks down the physical ports, with each\n     PORT option specifying a deeper level in the bus topology, the last\n     PORT denoting where the target adapter is actually plugged.  The\n     USB bus topology can be queried with the command _lsusb -t_ or\n     _dmesg_.\n\n     This command is only available if your libusb1 is at least version\n     1.0.16.\n\n -- Config Command: adapter serial serial_string\n     Specifies the SERIAL_STRING of the adapter to use.  If this command\n     is not specified, serial strings are not checked.  Only the\n     following adapter drivers use the serial string from this command:\n     aice (aice_usb), arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink,\n     ti-icdi), jlink, kitprog, opendus, openjtag, osbdm, presto, rlink,\n     st-link, usb_blaster (ublast2), usbprog, vsllink, xds110.\n\n8.2 Interface Drivers\n=====================\n\nEach of the interface drivers listed here must be explicitly enabled\nwhen OpenOCD is configured, in order to be made available at run time.\n\n -- Interface Driver: amt_jtagaccel\n     Amontec Chameleon in its JTAG Accelerator configuration, connected\n     to a PC's EPP mode parallel port.  This defines some\n     driver-specific commands:\n\n      -- Config Command: parport port number\n          Specifies either the address of the I/O port (default: 0x378\n          for LPT1) or the number of the '/dev/parport' device.\n\n      -- Config Command: rtck [enable|disable]\n          Displays status of RTCK option.  Optionally sets that option\n          first.\n\n -- Interface Driver: arm-jtag-ew\n     Olimex ARM-JTAG-EW USB adapter This has one driver-specific\n     command:\n\n      -- Command: armjtagew_info\n          Logs some status\n\n -- Interface Driver: at91rm9200\n     Supports bitbanged JTAG from the local system, presuming that\n     system is an Atmel AT91rm9200 and a specific set of GPIOs is used.\n\n -- Interface Driver: cmsis-dap\n     ARM CMSIS-DAP compliant based adapter v1 (USB HID based) or v2 (USB\n     bulk).\n\n      -- Config Command: cmsis_dap_vid_pid [vid pid]+\n          The vendor ID and product ID of the CMSIS-DAP device.  If not\n          specified the driver will attempt to auto detect the CMSIS-DAP\n          device.  Currently, up to eight [VID, PID] pairs may be given,\n          e.g.\n               cmsis_dap_vid_pid 0xc251 0xf001 0x0d28 0x0204\n\n      -- Config Command: cmsis_dap_backend [auto|usb_bulk|hid]\n          Specifies how to communicate with the adapter:\n\n             - 'hid' Use HID generic reports - CMSIS-DAP v1\n             - 'usb_bulk' Use USB bulk - CMSIS-DAP v2\n             - 'auto' First try USB bulk CMSIS-DAP v2, if not found try\n               HID CMSIS-DAP v1.  This is the default if\n               'cmsis_dap_backend' is not specified.\n\n      -- Config Command: cmsis_dap_usb interface [number]\n          Specifies the NUMBER of the USB interface to use in v2 mode\n          (USB bulk).  In most cases need not to be specified and\n          interfaces are searched by interface string or for user class\n          interface.\n\n      -- Command: cmsis-dap info\n          Display various device information, like hardware version,\n          firmware version, current bus status.\n\n      -- Command: cmsis-dap cmd number number ...\n          Execute an arbitrary CMSIS-DAP command.  Use for adapter\n          testing or for handling of an adapter vendor specific command\n          from a Tcl script.\n\n          Take given numbers as bytes, assemble a CMSIS-DAP protocol\n          command packet from them and send it to the adapter.  The\n          first 4 bytes of the adapter response are logged.  See\n          <https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__Commands__gr.html>\n\n -- Interface Driver: dummy\n     A dummy software-only driver for debugging.\n\n -- Interface Driver: ep93xx\n     Cirrus Logic EP93xx based single-board computer bit-banging (in\n     development)\n\n -- Interface Driver: ftdi\n     This driver is for adapters using the MPSSE (Multi-Protocol\n     Synchronous Serial Engine) mode built into many FTDI chips, such as\n     the FT2232, FT4232 and FT232H.\n\n     The driver is using libusb-1.0 in asynchronous mode to talk to the\n     FTDI device, bypassing intermediate libraries like libftdi.\n\n     Support for new FTDI based adapters can be added completely through\n     configuration files, without the need to patch and rebuild OpenOCD.\n\n     The driver uses a signal abstraction to enable Tcl configuration\n     files to define outputs for one or several FTDI GPIO. These outputs\n     can then be controlled using the 'ftdi set_signal' command.\n     Special signal names are reserved for nTRST, nSRST and LED (for\n     blink) so that they, if defined, will be used for their customary\n     purpose.  Inputs can be read using the 'ftdi get_signal' command.\n\n     To support SWD, a signal named SWD_EN must be defined.  It is set\n     to 1 when the SWD protocol is selected.  When set, the adapter\n     should route the SWDIO pin to the data input.  An SWDIO_OE signal,\n     if defined, will be set to 1 or 0 as required by the protocol, to\n     tell the adapter to drive the data output onto the SWDIO pin or\n     keep the SWDIO pin Hi-Z, respectively.\n\n     Depending on the type of buffer attached to the FTDI GPIO, the\n     outputs have to be controlled differently.  In order to support\n     tristateable signals such as nSRST, both a data GPIO and an\n     output-enable GPIO can be specified for each signal.  The following\n     output buffer configurations are supported:\n\n        - Push-pull with one FTDI output as (non-)inverted data line\n        - Open drain with one FTDI output as (non-)inverted\n          output-enable\n        - Tristate with one FTDI output as (non-)inverted data line and\n          another FTDI output as (non-)inverted output-enable\n        - Unbuffered, using the FTDI GPIO as a tristate output directly\n          by switching data and direction as necessary\n\n     These interfaces have several commands, used to configure the\n     driver before initializing the JTAG scan chain:\n\n      -- Config Command: ftdi vid_pid [vid pid]+\n          The vendor ID and product ID of the adapter.  Up to eight\n          [VID, PID] pairs may be given, e.g.\n               ftdi vid_pid 0x0403 0xcff8 0x15ba 0x0003\n\n      -- Config Command: ftdi device_desc description\n          Provides the USB device description (the _iProduct string_) of\n          the adapter.  If not specified, the device description is\n          ignored during device selection.\n\n      -- Config Command: ftdi channel channel\n          Selects the channel of the FTDI device to use for MPSSE\n          operations.  Most adapters use the default, channel 0, but\n          there are exceptions.\n\n      -- Config Command: ftdi layout_init data direction\n          Specifies the initial values of the FTDI GPIO data and\n          direction registers.  Each value is a 16-bit number\n          corresponding to the concatenation of the high and low FTDI\n          GPIO registers.  The values should be selected based on the\n          schematics of the adapter, such that all signals are set to\n          safe levels with minimal impact on the target system.  Avoid\n          floating inputs, conflicting outputs and initially asserted\n          reset signals.\n\n      -- Command: ftdi layout_signal name [-data|-ndata data_mask]\n               [-input|-ninput input_mask] [-oe|-noe oe_mask]\n               [-alias|-nalias name]\n          Creates a signal with the specified NAME, controlled by one or\n          more FTDI GPIO pins via a range of possible buffer\n          connections.  The masks are FTDI GPIO register bitmasks to\n          tell the driver the connection and type of the output buffer\n          driving the respective signal.  DATA_MASK is the bitmask for\n          the pin(s) connected to the data input of the output buffer.\n          '-ndata' is used with inverting data inputs and '-data' with\n          non-inverting inputs.  The '-oe' (or '-noe') option tells\n          where the output-enable (or not-output-enable) input to the\n          output buffer is connected.  The options '-input' and\n          '-ninput' specify the bitmask for pins to be read with the\n          method 'ftdi get_signal'.\n\n          Both DATA_MASK and OE_MASK need not be specified.  For\n          example, a simple open-collector transistor driver would be\n          specified with '-oe' only.  In that case the signal can only\n          be set to drive low or to Hi-Z and the driver will complain if\n          the signal is set to drive high.  Which means that if it's a\n          reset signal, 'reset_config' must be specified as\n          'srst_open_drain', not 'srst_push_pull'.\n\n          A special case is provided when '-data' and '-oe' is set to\n          the same bitmask.  Then the FTDI pin is considered being\n          connected straight to the target without any buffer.  The FTDI\n          pin is then switched between output and input as necessary to\n          provide the full set of low, high and Hi-Z characteristics.\n          In all other cases, the pins specified in a signal definition\n          are always driven by the FTDI.\n\n          If '-alias' or '-nalias' is used, the signal is created\n          identical (or with data inverted) to an already specified\n          signal NAME.\n\n      -- Command: ftdi set_signal name 0|1|z\n          Set a previously defined signal to the specified level.\n             - '0', drive low\n             - '1', drive high\n             - 'z', set to high-impedance\n\n      -- Command: ftdi get_signal name\n          Get the value of a previously defined signal.\n\n      -- Command: ftdi tdo_sample_edge rising|falling\n          Configure TCK edge at which the adapter samples the value of\n          the TDO signal\n\n          Due to signal propagation delays, sampling TDO on rising TCK\n          can become quite peculiar at high JTAG clock speeds.  However,\n          FTDI chips offer a possibility to sample TDO on falling edge\n          of TCK. With some board/adapter configurations, this may\n          increase stability at higher JTAG clocks.\n             - 'rising', sample TDO on rising edge of TCK - this is the\n               default\n             - 'falling', sample TDO on falling edge of TCK\n\n     For example adapter definitions, see the configuration files\n     shipped in the 'interface/ftdi' directory.\n\n -- Interface Driver: ft232r\n     This driver is implementing synchronous bitbang mode of an FTDI\n     FT232R, FT230X, FT231X and similar USB UART bridge ICs by reusing\n     RS232 signals as GPIO. It currently doesn't support using CBUS pins\n     as GPIO.\n\n     List of connections (default physical pin numbers for FT232R in\n     28-pin SSOP package):\n        - RXD(5) - TDI\n        - TXD(1) - TCK\n        - RTS(3) - TDO\n        - CTS(11) - TMS\n        - DTR(2) - TRST\n        - DCD(10) - SRST\n\n     User can change default pinout by supplying configuration commands\n     with GPIO numbers or RS232 signal names.  GPIO numbers correspond\n     to bit numbers in FTDI GPIO register.  They differ from physical\n     pin numbers.  For details see actual FTDI chip datasheets.  Every\n     JTAG line must be configured to unique GPIO number different than\n     any other JTAG line, even those lines that are sometimes not used\n     like TRST or SRST.\n\n     FT232R\n        - bit 7 - RI\n        - bit 6 - DCD\n        - bit 5 - DSR\n        - bit 4 - DTR\n        - bit 3 - CTS\n        - bit 2 - RTS\n        - bit 1 - RXD\n        - bit 0 - TXD\n\n     These interfaces have several commands, used to configure the\n     driver before initializing the JTAG scan chain:\n\n      -- Config Command: ft232r vid_pid VID PID\n          The vendor ID and product ID of the adapter.  If not\n          specified, default 0x0403:0x6001 is used.\n\n      -- Config Command: ft232r jtag_nums TCK TMS TDI TDO\n          Set four JTAG GPIO numbers at once.  If not specified, default\n          0 3 1 2 or TXD CTS RXD RTS is used.\n\n      -- Config Command: ft232r tck_num TCK\n          Set TCK GPIO number.  If not specified, default 0 or TXD is\n          used.\n\n      -- Config Command: ft232r tms_num TMS\n          Set TMS GPIO number.  If not specified, default 3 or CTS is\n          used.\n\n      -- Config Command: ft232r tdi_num TDI\n          Set TDI GPIO number.  If not specified, default 1 or RXD is\n          used.\n\n      -- Config Command: ft232r tdo_num TDO\n          Set TDO GPIO number.  If not specified, default 2 or RTS is\n          used.\n\n      -- Config Command: ft232r trst_num TRST\n          Set TRST GPIO number.  If not specified, default 4 or DTR is\n          used.\n\n      -- Config Command: ft232r srst_num SRST\n          Set SRST GPIO number.  If not specified, default 6 or DCD is\n          used.\n\n      -- Config Command: ft232r restore_serial WORD\n          Restore serial port after JTAG. This USB bitmode control word\n          (16-bit) will be sent before quit.  Lower byte should set GPIO\n          direction register to a \"sane\" state: 0x15 for TXD RTS DTR as\n          outputs (1), others as inputs (0).  Higher byte is usually 0\n          to disable bitbang mode.  When kernel driver reattaches,\n          serial port should continue to work.  Value 0xFFFF disables\n          sending control word and serial port, then kernel driver will\n          not reattach.  If not specified, default 0xFFFF is used.\n\n -- Interface Driver: remote_bitbang\n     Drive JTAG from a remote process.  This sets up a UNIX or TCP\n     socket connection with a remote process and sends ASCII encoded\n     bitbang requests to that process instead of directly driving JTAG.\n\n     The remote_bitbang driver is useful for debugging software running\n     on processors which are being simulated.\n\n      -- Config Command: remote_bitbang port number\n          Specifies the TCP port of the remote process to connect to or\n          0 to use UNIX sockets instead of TCP.\n\n      -- Config Command: remote_bitbang host hostname\n          Specifies the hostname of the remote process to connect to\n          using TCP, or the name of the UNIX socket to use if\n          remote_bitbang port is 0.\n\n     For example, to connect remotely via TCP to the host foobar you\n     might have something like:\n\n          adapter driver remote_bitbang\n          remote_bitbang port 3335\n          remote_bitbang host foobar\n\n     To connect to another process running locally via UNIX sockets with\n     socket named mysocket:\n\n          adapter driver remote_bitbang\n          remote_bitbang port 0\n          remote_bitbang host mysocket\n\n -- Interface Driver: usb_blaster\n     USB JTAG/USB-Blaster compatibles over one of the userspace\n     libraries for FTDI chips.  These interfaces have several commands,\n     used to configure the driver before initializing the JTAG scan\n     chain:\n\n      -- Config Command: usb_blaster vid_pid vid pid\n          The vendor ID and product ID of the FTDI FT245 device.  If not\n          specified, default values are used.  Currently, only one VID,\n          PID pair may be given, e.g.  for Altera USB-Blaster (default):\n               usb_blaster vid_pid 0x09FB 0x6001\n          The following VID/PID is for Kolja Waschk's USB JTAG:\n               usb_blaster vid_pid 0x16C0 0x06AD\n\n      -- Command: usb_blaster pin (pin6|pin8) (0|1|s|t)\n          Sets the state or function of the unused GPIO pins on\n          USB-Blasters (pins 6 and 8 on the female JTAG header).  These\n          pins can be used as SRST and/or TRST provided the appropriate\n          connections are made on the target board.\n\n          For example, to use pin 6 as SRST:\n               usb_blaster pin pin6 s\n               reset_config srst_only\n\n      -- Config Command: usb_blaster lowlevel_driver (ftdi|ublast2)\n          Chooses the low level access method for the adapter.  If not\n          specified, 'ftdi' is selected unless it wasn't enabled during\n          the configure stage.  USB-Blaster II needs 'ublast2'.\n\n      -- Config Command: usb_blaster firmware PATH\n          This command specifies PATH to access USB-Blaster II firmware\n          image.  To be used with USB-Blaster II only.\n\n -- Interface Driver: gw16012\n     Gateworks GW16012 JTAG programmer.  This has one driver-specific\n     command:\n\n      -- Config Command: parport port [port_number]\n          Display either the address of the I/O port (default: 0x378 for\n          LPT1) or the number of the '/dev/parport' device.  If a\n          parameter is provided, first switch to use that port.  This is\n          a write-once setting.\n\n -- Interface Driver: jlink\n     SEGGER J-Link family of USB adapters.  It currently supports JTAG\n     and SWD transports.\n\n          Compatibility Note: SEGGER released many firmware versions for\n          the many hardware versions they produced.  OpenOCD was\n          extensively tested and intended to run on all of them, but\n          some combinations were reported as incompatible.  As a general\n          recommendation, it is advisable to use the latest firmware\n          version available for each hardware version.  However the\n          current V8 is a moving target, and SEGGER firmware versions\n          released after the OpenOCD was released may not be compatible.\n          In such cases it is recommended to revert to the last known\n          functional version.  For 0.5.0, this is from \"Feb 8 2012\n          14:30:39\", packed with 4.42c.  For 0.6.0, the last known\n          version is from \"May 3 2012 18:36:22\", packed with 4.46f.\n\n      -- Command: jlink hwstatus\n          Display various hardware related information, for example\n          target voltage and pin states.\n      -- Command: jlink freemem\n          Display free device internal memory.\n      -- Command: jlink jtag [2|3]\n          Set the JTAG command version to be used.  Without argument,\n          show the actual JTAG command version.\n      -- Command: jlink config\n          Display the device configuration.\n      -- Command: jlink config targetpower [on|off]\n          Set the target power state on JTAG-pin 19.  Without argument,\n          show the target power state.\n      -- Command: jlink config mac [ff:ff:ff:ff:ff:ff]\n          Set the MAC address of the device.  Without argument, show the\n          MAC address.\n      -- Command: jlink config ip [A.B.C.D(/E|F.G.H.I)]\n          Set the IP configuration of the device, where A.B.C.D is the\n          IP address, E the bit of the subnet mask and F.G.H.I the\n          subnet mask.  Without arguments, show the IP configuration.\n      -- Command: jlink config usb [0 to 3]\n          Set the USB address of the device.  This will also change the\n          USB Product ID (PID) of the device.  Without argument, show\n          the USB address.\n      -- Command: jlink config reset\n          Reset the current configuration.\n      -- Command: jlink config write\n          Write the current configuration to the internal persistent\n          storage.\n      -- Command: jlink emucom write <channel> <data>\n          Write data to an EMUCOM channel.  The data needs to be encoded\n          as hexadecimal pairs.\n\n          The following example shows how to write the three bytes 0xaa,\n          0x0b and 0x23 to the EMUCOM channel 0x10:\n               > jlink emucom write 0x10 aa0b23\n      -- Command: jlink emucom read <channel> <length>\n          Read data from an EMUCOM channel.  The read data is encoded as\n          hexadecimal pairs.\n\n          The following example shows how to read 4 bytes from the\n          EMUCOM channel 0x0:\n               > jlink emucom read 0x0 4\n               77a90000\n      -- Config Command: jlink usb <0 to 3>\n          Set the USB address of the interface, in case more than one\n          adapter is connected to the host.  If not specified, USB\n          addresses are not considered.  Device selection via USB\n          address is not always unambiguous.  It is recommended to use\n          the serial number instead, if possible.\n\n          As a configuration command, it can be used only before 'init'.\n\n -- Interface Driver: kitprog\n     This driver is for Cypress Semiconductor's KitProg adapters.  The\n     KitProg is an SWD-only adapter that is designed to be used with\n     Cypress's PSoC and PRoC device families, but it is possible to use\n     it with some other devices.  If you are using this adapter with a\n     PSoC or a PRoC, you may need to add 'kitprog_init_acquire_psoc' or\n     'kitprog acquire_psoc' to your configuration script.\n\n     Note that this driver is for the proprietary KitProg protocol, not\n     the CMSIS-DAP mode introduced in firmware 2.14.  If the KitProg is\n     in CMSIS-DAP mode, it cannot be used with this driver, and must\n     either be used with the cmsis-dap driver or switched back to\n     KitProg mode.  See the Cypress KitProg User Guide for instructions\n     on how to switch KitProg modes.\n\n     Known limitations:\n        * The frequency of SWCLK cannot be configured, and varies\n          between 1.6 MHz and 2.7 MHz.\n        * For firmware versions below 2.14, \"JTAG to SWD\" sequences are\n          replaced by \"SWD line reset\" in the driver.  This is for two\n          reasons.  First, the KitProg does not support sending\n          arbitrary SWD sequences, and only firmware 2.14 and later\n          implement both \"JTAG to SWD\" and \"SWD line reset\" in firmware.\n          Earlier firmware versions only implement \"SWD line reset\".\n          Second, due to a firmware quirk, an SWD sequence must be sent\n          after every target reset in order to re-establish\n          communications with the target.\n        * Due in part to the limitation above, KitProg devices with\n          firmware below version 2.14 will need to use\n          'kitprog_init_acquire_psoc' in order to communicate with PSoC\n          5LP devices.  This is because, assuming debug is not disabled\n          on the PSoC, the PSoC 5LP needs its JTAG interface switched to\n          SWD mode before communication can begin, but prior to firmware\n          2.14, \"JTAG to SWD\" could only be sent with an acquisition\n          sequence.\n\n      -- Config Command: kitprog_init_acquire_psoc\n          Indicate that a PSoC acquisition sequence needs to be run\n          during adapter init.  Please be aware that the acquisition\n          sequence hard-resets the target.\n\n      -- Command: kitprog acquire_psoc\n          Run a PSoC acquisition sequence immediately.  Typically, this\n          should not be used outside of the target-specific\n          configuration scripts since it hard-resets the target as a\n          side-effect.  This is necessary for \"reset halt\" on some PSoC\n          4 series devices.\n\n      -- Command: kitprog info\n          Display various adapter information, such as the hardware\n          version, firmware version, and target voltage.\n\n -- Interface Driver: parport\n     Supports PC parallel port bit-banging cables: Wigglers, PLD\n     download cable, and more.  These interfaces have several commands,\n     used to configure the driver before initializing the JTAG scan\n     chain:\n\n      -- Config Command: parport cable name\n          Set the layout of the parallel port cable used to connect to\n          the target.  This is a write-once setting.  Currently valid\n          cable NAME values include:\n\n             - altium Altium Universal JTAG cable.\n             - arm-jtag Same as original wiggler except SRST and TRST\n               connections reversed and TRST is also inverted.\n             - chameleon The Amontec Chameleon's CPLD when operated in\n               configuration mode.  This is only used to program the\n               Chameleon itself, not a connected target.\n             - dlc5 The Xilinx Parallel cable III.\n             - flashlink The ST Parallel cable.\n             - lattice Lattice ispDOWNLOAD Cable\n             - old_amt_wiggler The Wiggler configuration that comes with\n               some versions of Amontec's Chameleon Programmer.  The new\n               version available from the website uses the original\n               Wiggler layout ('WIGGLER')\n             - triton The parallel port adapter found on the \"Karo\n               Triton 1 Development Board\".  This is also the layout\n               used by the HollyGates design (see\n               <http://www.lartmaker.nl/projects/jtag/>).\n             - wiggler The original Wiggler layout, also supported by\n               several clones, such as the Olimex ARM-JTAG\n             - wiggler2 Same as original wiggler except an led is fitted\n               on D5.\n             - wiggler_ntrst_inverted Same as original wiggler except\n               TRST is inverted.\n\n      -- Config Command: parport port [port_number]\n          Display either the address of the I/O port (default: 0x378 for\n          LPT1) or the number of the '/dev/parport' device.  If a\n          parameter is provided, first switch to use that port.  This is\n          a write-once setting.\n\n          When using PPDEV to access the parallel port, use the number\n          of the parallel port: 'parport port 0' (the default).  If\n          'parport port 0x378' is specified you may encounter a problem.\n\n      -- Config Command: parport toggling_time [nanoseconds]\n          Displays how many nanoseconds the hardware needs to toggle\n          TCK; the parport driver uses this value to obey the 'adapter\n          speed' configuration.  When the optional NANOSECONDS parameter\n          is given, that setting is changed before displaying the\n          current value.\n\n          The default setting should work reasonably well on commodity\n          PC hardware.  However, you may want to calibrate for your\n          specific hardware.\n               Tip: To measure the toggling time with a logic analyzer\n               or a digital storage oscilloscope, follow the procedure\n               below:\n                    > parport toggling_time 1000\n                    > adapter speed 500\n               This sets the maximum JTAG clock speed of the hardware,\n               but the actual speed probably deviates from the requested\n               500 kHz.  Now, measure the time between the two closest\n               spaced TCK transitions.  You can use 'runtest 1000' or\n               something similar to generate a large set of samples.\n               Update the setting to match your measurement:\n                    > parport toggling_time <measured nanoseconds>\n               Now the clock speed will be a better match for 'adapter\n               speed' command given in OpenOCD scripts and event\n               handlers.\n\n               You can do something similar with many digital\n               multimeters, but note that you'll probably need to run\n               the clock continuously for several seconds before it\n               decides what clock rate to show.  Adjust the toggling\n               time up or down until the measured clock rate is a good\n               match with the rate you specified in the 'adapter speed'\n               command; be conservative.\n\n      -- Config Command: parport write_on_exit (on|off)\n          This will configure the parallel driver to write a known\n          cable-specific value to the parallel interface on exiting\n          OpenOCD.\n\n     For example, the interface configuration file for a classic\n     \"Wiggler\" cable on LPT2 might look something like this:\n\n          adapter driver parport\n          parport port 0x278\n          parport cable wiggler\n\n -- Interface Driver: presto\n     ASIX PRESTO USB JTAG programmer.\n\n -- Interface Driver: rlink\n     Raisonance RLink USB adapter\n\n -- Interface Driver: usbprog\n     usbprog is a freely programmable USB adapter.\n\n -- Interface Driver: vsllink\n     vsllink is part of Versaloon which is a versatile USB programmer.\n\n          Note: This defines quite a few driver-specific commands, which\n          are not currently documented here.\n\n -- Interface Driver: hla\n     This is a driver that supports multiple High Level Adapters.  This\n     type of adapter does not expose some of the lower level api's that\n     OpenOCD would normally use to access the target.\n\n     Currently supported adapters include the STMicroelectronics\n     ST-LINK, TI ICDI and Nuvoton Nu-Link.  ST-LINK firmware version >=\n     V2.J21.S4 recommended due to issues with earlier versions of\n     firmware where serial number is reset after first use.  Suggest\n     using ST firmware update utility to upgrade ST-LINK firmware even\n     if current version reported is V2.J21.S4.\n\n      -- Config Command: hla_device_desc description\n          Currently Not Supported.\n\n      -- Config Command: hla_layout (stlink|icdi|nulink)\n          Specifies the adapter layout to use.\n\n      -- Config Command: hla_vid_pid [vid pid]+\n          Pairs of vendor IDs and product IDs of the device.\n\n      -- Config Command: hla_stlink_backend (usb | tcp [port])\n          _ST-Link only:_ Choose between 'exclusive' USB communication\n          (the default backend) or 'shared' mode using ST-Link TCP\n          server (the default port is 7184).\n\n          _Note:_ ST-Link TCP server is a binary application provided by\n          ST available from ST-LINK server software module\n          (https://www.st.com/en/development-tools/st-link-server.html).\n\n      -- Command: hla_command command\n          Execute a custom adapter-specific command.  The COMMAND string\n          is passed as is to the underlying adapter layout handler.\n\n -- Interface Driver: st-link\n     This is a driver that supports STMicroelectronics adapters\n     ST-LINK/V2 (from firmware V2J24) and STLINK-V3, thanks to a new API\n     that provides directly access the arm ADIv5 DAP.\n\n     The new API provide access to multiple AP on the same DAP, but the\n     maximum number of the AP port is limited by the specific firmware\n     version (e.g.  firmware V2J29 has 3 as maximum AP number, while\n     V2J32 has 8).  An error is returned for any AP number above the\n     maximum allowed value.\n\n     _Note:_ Either these same adapters and their older versions are\n     also supported by *note the hla interface driver: hla_interface.\n\n      -- Config Command: st-link backend (usb | tcp [port])\n          Choose between 'exclusive' USB communication (the default\n          backend) or 'shared' mode using ST-Link TCP server (the\n          default port is 7184).\n\n          _Note:_ ST-Link TCP server is a binary application provided by\n          ST available from ST-LINK server software module\n          (https://www.st.com/en/development-tools/st-link-server.html).\n\n          _Note:_ ST-Link TCP server does not support the SWIM\n          transport.\n\n      -- Config Command: st-link vid_pid [vid pid]+\n          Pairs of vendor IDs and product IDs of the device.\n\n      -- Command: st-link cmd rx_n (tx_byte)+\n          Sends an arbitrary command composed by the sequence of bytes\n          TX_BYTE and receives RX_N bytes.\n\n          For example, the command to read the target's supply voltage\n          is one byte 0xf7 followed by 15 bytes zero.  It returns 8\n          bytes, where the first 4 bytes represent the ADC sampling of\n          the reference voltage 1.2V and the last 4 bytes represent the\n          ADC sampling of half the target's supply voltage.\n               > st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n               0xf1 0x05 0x00 0x00 0x0b 0x08 0x00 0x00\n          The result can be converted to Volts (ignoring the most\n          significant bytes, always zero)\n               > set a [st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n               > set n [expr {[lindex $a 4] + 256 * [lindex $a 5]}]\n               > set d [expr {[lindex $a 0] + 256 * [lindex $a 1]}]\n               > echo [expr {2 * 1.2 * $n / $d}]\n               3.24891518738\n\n -- Interface Driver: opendous\n     opendous-jtag is a freely programmable USB adapter.\n\n -- Interface Driver: ulink\n     This is the Keil ULINK v1 JTAG debugger.\n\n -- Interface Driver: xds110\n     The XDS110 is included as the embedded debug probe on many Texas\n     Instruments LaunchPad evaluation boards.  The XDS110 is also\n     available as a stand-alone USB debug probe with the added\n     capability to supply power to the target board.  The following\n     commands are supported by the XDS110 driver:\n\n      -- Config Command: xds110 supply voltage_in_millivolts\n          Available only on the XDS110 stand-alone probe.  Sets the\n          voltage level of the XDS110 power supply.  A value of 0 leaves\n          the supply off.  Otherwise, the supply can be set to any value\n          in the range 1800 to 3600 millivolts.\n\n      -- Command: xds110 info\n          Displays information about the connected XDS110 debug probe\n          (e.g.  firmware version).\n\n -- Interface Driver: xlnx_pcie_xvc\n     This driver supports the Xilinx Virtual Cable (XVC) over PCI\n     Express.  It is commonly found in Xilinx based PCI Express designs.\n     It allows debugging fabric based JTAG/SWD devices such as\n     Cortex-M1/M3 microcontrollers.  Access to this is exposed via\n     extended capability registers in the PCI Express configuration\n     space.\n\n     For more information see Xilinx PG245 (Section on From_PCIE_to_JTAG\n     mode).\n\n      -- Config Command: xlnx_pcie_xvc config device\n          Specifies the PCI Express device via parameter DEVICE to use.\n\n          The correct value for DEVICE can be obtained by looking at the\n          output of lscpi -D (first column) for the corresponding\n          device.\n\n          The string will be of the format \"DDDD:BB:SS.F\" such as\n          \"0000:65:00.1\".\n\n -- Interface Driver: bcm2835gpio\n     This SoC is present in Raspberry Pi which is a cheap single-board\n     computer exposing some GPIOs on its expansion header.\n\n     The driver accesses memory-mapped GPIO peripheral registers\n     directly for maximum performance, but the only possible race\n     condition is for the pins' modes/muxing (which is highly unlikely),\n     so it should be able to coexist nicely with both sysfs bitbanging\n     and various peripherals' kernel drivers.  The driver restores the\n     previous configuration on exit.\n\n     GPIO numbers >= 32 can't be used for performance reasons.\n\n     See 'interface/raspberrypi-native.cfg' for a sample config and\n     pinout.\n\n      -- Config Command: bcm2835gpio jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: bcm2835gpio tck_num TCK\n          Set TCK GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tms_num TMS\n          Set TMS GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tdo_num TDO\n          Set TDO GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tdi_num TDI\n          Set TDI GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: bcm2835gpio swclk_num SWCLK\n          Set SWCLK GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio swd_nums'.\n\n      -- Config Command: bcm2835gpio swdio_num SWDIO\n          Set SWDIO GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio swd_nums'.\n\n      -- Config Command: bcm2835gpio swdio_dir_num SWDIO DIR\n          Set SWDIO direction control pin GPIO number.  If specified,\n          this pin can be used to control the direction of an external\n          buffer on the SWDIO pin (set=output mode, clear=input mode).\n          If not specified, this feature is disabled.\n\n      -- Config Command: bcm2835gpio srst_num SRST\n          Set SRST GPIO number.  Must be specified to enable SRST.\n\n      -- Config Command: bcm2835gpio trst_num TRST\n          Set TRST GPIO number.  Must be specified to enable TRST.\n\n      -- Config Command: bcm2835gpio speed_coeffs SPEED_COEFF\n               SPEED_OFFSET\n          Set SPEED_COEFF and SPEED_OFFSET for delay calculations.  If\n          unspecified, speed_coeff defaults to 113714, and speed_offset\n          defaults to 28.\n\n      -- Config Command: bcm2835gpio peripheral_base BASE\n          Set the peripheral base register address to access GPIOs.  For\n          the RPi1, use 0x20000000.  For RPi2 and RPi3, use 0x3F000000.\n          For RPi4, use 0xFE000000.  A full list can be found in the\n          official guide\n          (https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md).\n\n -- Interface Driver: imx_gpio\n     i.MX SoC is present in many community boards.  Wandboard is an\n     example of the one which is most popular.\n\n     This driver is mostly the same as bcm2835gpio.\n\n     See 'interface/imx-native.cfg' for a sample config and pinout.\n\n -- Interface Driver: am335xgpio The AM335x SoC is present in BeagleBone\n     Black and BeagleBone Green single-board computers which expose some\n     of the GPIOs on the two expansion headers.\n\n     For maximum performance the driver accesses memory-mapped GPIO\n     peripheral registers directly.  The memory mapping requires read\n     and write permission to kernel memory; if /dev/gpiomem exists it\n     will be used, otherwise /dev/mem will be used.  The driver restores\n     the GPIO state on exit.\n\n     All four GPIO ports are available.  GPIOs numbered 0 to 31 are\n     mapped to GPIO port 0, GPIO numbers 32 to 63 are mapped to GPIO\n     port 1 and so on.\n\n     See 'interface/beaglebone-swd-native.cfg' for a sample\n     configuration file.\n\n      -- Config Command: am335xgpio jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: am335xgpio tck_num TCK\n          Set TCK GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tms_num TMS\n          Set TMS GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tdo_num TDO\n          Set TDO GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tdi_num TDI\n          Set TDI GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: am335xgpio swclk_num SWCLK\n          Set SWCLK GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio swd_nums'.\n\n      -- Config Command: am335xgpio swdio_num SWDIO\n          Set SWDIO GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio swd_nums'.\n\n      -- Config Command: am335xgpio swdio_dir_num SWDIO_DIR\n          Set SWDIO direction control pin GPIO number.  If specified,\n          this pin can be used to control the direction of an external\n          buffer on the SWDIO pin.  The direction control state can be\n          set with the command 'am335xgpio swdio_dir_output_state'.  If\n          not specified this feature is disabled.\n\n      -- Config Command: am335xgpio swdio_dir_output_state OUTPUT_STATE\n          Set the state required for an external SWDIO buffer to be an\n          output.  Valid values are 'on' (default) and 'off'.\n\n      -- Config Command: am335xgpio srst_num SRST\n          Set SRST GPIO number.  Must be specified to enable SRST.\n\n      -- Config Command: am335xgpio trst_num TRST\n          Set TRST GPIO number.  Must be specified to enable TRST.\n\n      -- Config Command: am335xgpio led_num LED\n          Set activity LED GPIO number.  If not specified an activity\n          LED is not enabled.\n\n      -- Config Command: am335xgpio led_on_state ON_STATE\n          Set required logic level for the LED to be on.  Valid values\n          are 'on' (default) and 'off'.\n\n      -- Config Command: am335xgpio speed_coeffs SPEED_COEFF\n               SPEED_OFFSET\n          Set SPEED_COEFF and SPEED_OFFSET for delay calculations.  If\n          unspecified speed_coeff defaults to 600000 and speed_offset\n          defaults to 575.\n\n -- Interface Driver: linuxgpiod\n     Linux provides userspace access to GPIO through libgpiod since\n     Linux kernel version v4.6.  The driver emulates either JTAG or SWD\n     transport through bitbanging.\n\n     See 'interface/dln-2-gpiod.cfg' for a sample config.\n\n      -- Config Command: linuxgpiod gpiochip CHIP\n          Set the GPIO chip number for all GPIOs used by linuxgpiod.  If\n          GPIOs use different GPIO chips then the individual GPIO\n          configuration commands (i.e., not 'linuxgpiod jtag_nums' or\n          'linuxgpiod swd_nums') can be used to set chip numbers\n          independently for each GPIO.\n\n      -- Config Command: linuxgpiod jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: linuxgpiod tck_num [CHIP] TCK\n          Set TCK GPIO number, and optionally TCK chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tms_num [CHIP] TMS\n          Set TMS GPIO number, and optionally TMS chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tdo_num [CHIP] TDO\n          Set TDO GPIO number, and optionally TDO chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tdi_num [CHIP] TDI\n          Set TDI GPIO number, and optionally TDI chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod trst_num [CHIP] TRST\n          Set TRST GPIO number, and optionally TRST chip number.  Must\n          be specified to enable TRST.\n\n      -- Config Command: linuxgpiod swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: linuxgpiod swclk_num [CHIP] SWCLK\n          Set SWCLK GPIO number, and optionally SWCLK chip number.  Must\n          be specified to enable SWD transport.  Can also be specified\n          using the configuration command 'linuxgpiod swd_nums'.\n\n      -- Config Command: linuxgpiod swdio_num [CHIP] SWDIO\n          Set SWDIO GPIO number, and optionally SWDIO chip number.  Must\n          be specified to enable SWD transport.  Can also be specified\n          using the configuration command 'linuxgpiod swd_nums'.\n\n      -- Config Command: linuxgpiod swdio_dir_num [CHIP] SWDIO_DIR\n          Set SWDIO direction control GPIO number, and optionally SWDIO\n          direction control chip number.  If specified, this GPIO can be\n          used to control the direction of an external buffer connected\n          to the SWDIO GPIO (set=output mode, clear=input mode).\n\n      -- Config Command: linuxgpiod srst_num [CHIP] SRST\n          Set SRST GPIO number, and optionally SRST chip number.  Must\n          be specified to enable SRST.\n\n      -- Config Command: linuxgpiod led_num [CHIP] LED\n          Set activity LED GPIO number, and optionally activity LED chip\n          number.  If not specified an activity LED is not enabled.\n\n -- Interface Driver: sysfsgpio\n     Linux legacy userspace access to GPIO through sysfs is deprecated\n     from Linux kernel version v5.3.  Prefer using linuxgpiod, instead.\n\n     See 'interface/sysfsgpio-raspberrypi.cfg' for a sample config.\n\n -- Interface Driver: openjtag\n     OpenJTAG compatible USB adapter.  This defines some driver-specific\n     commands:\n\n      -- Config Command: openjtag variant variant\n          Specifies the variant of the OpenJTAG adapter (see\n          <http://www.openjtag.org/>).  Currently valid VARIANT values\n          include:\n\n             - standard Standard variant (default).\n             - cy7c65215 Cypress CY7C65215 Dual Channel USB-Serial\n               Bridge Controller (see\n               <http://www.cypress.com/?rID=82870>).\n\n      -- Config Command: openjtag device_desc string\n          The USB device description string of the adapter.  This value\n          is only used with the standard variant.\n\n -- Interface Driver: vdebug\n     Cadence Virtual Debug Interface driver.\n\n      -- Config Command: vdebug server host:port\n          Specifies the host and TCP port number where the vdebug server\n          runs.\n\n      -- Config Command: vdebug batching value\n          Specifies the batching method for the vdebug request.\n          Possible values are 0 for no batching 1 or wr to batch write\n          transactions together (default) 2 or rw to batch both read and\n          write transactions\n\n      -- Config Command: vdebug polling min max\n          Takes two values, representing the polling interval in ms.\n          Lower values mean faster debugger responsiveness, but lower\n          emulation performance.  The minimum should be around 10,\n          maximum should not exceed 1000, which is the default gdb and\n          keepalive timeout value.\n\n      -- Config Command: vdebug bfm_path path clk_period\n          Specifies the hierarchical path and input clk period of the\n          vdebug BFM in the design.  The hierarchical path uses Verilog\n          notation top.inst.inst The clock period must include the unit,\n          for instance 40ns.\n\n      -- Config Command: vdebug mem_path path base size\n          Specifies the hierarchical path to the design memory instance\n          for backdoor access.  Up to 4 memories can be specified.  The\n          hierarchical path uses Verilog notation.  The base specifies\n          start address in the design address space, size its size in\n          bytes.  Both values can use hexadecimal notation with prefix\n          0x.\n\n -- Interface Driver: jtag_dpi\n     SystemVerilog Direct Programming Interface (DPI) compatible driver\n     for JTAG devices in emulation.  The driver acts as a client for the\n     SystemVerilog DPI server interface.\n\n      -- Config Command: jtag_dpi set_port port\n          Specifies the TCP/IP port number of the SystemVerilog DPI\n          server interface.\n\n      -- Config Command: jtag_dpi set_address address\n          Specifies the TCP/IP address of the SystemVerilog DPI server\n          interface.\n\n -- Interface Driver: buspirate\n\n     This driver is for the Bus Pirate (see\n     <http://dangerousprototypes.com/docs/Bus_Pirate>) and compatible\n     devices.  It uses a simple data protocol over a serial port\n     connection.\n\n     Most hardware development boards have a UART, a real serial port,\n     or a virtual USB serial device, so this driver allows you to start\n     building your own JTAG adapter without the complexity of a custom\n     USB connection.\n\n      -- Config Command: buspirate port serial_port\n          Specify the serial port's filename.  For example:\n               buspirate port /dev/ttyUSB0\n\n      -- Config Command: buspirate speed (normal|fast)\n          Set the communication speed to 115k (normal) or 1M (fast).\n          For example:\n               buspirate speed normal\n\n      -- Config Command: buspirate mode (normal|open-drain)\n          Set the Bus Pirate output mode.\n             - In normal mode (push/pull), do not enable the pull-ups,\n               and do not connect I/O header pin VPU to JTAG VREF.\n             - In open drain mode, you will then need to enable the\n               pull-ups.\n          For example:\n               buspirate mode normal\n\n      -- Config Command: buspirate pullup (0|1)\n          Whether to connect (1) or not (0) the I/O header pin VPU (JTAG\n          VREF) to the pull-up/pull-down resistors on MOSI (JTAG TDI),\n          CLK (JTAG TCK), MISO (JTAG TDO) and CS (JTAG TMS). For\n          example:\n               buspirate pullup 0\n\n      -- Config Command: buspirate vreg (0|1)\n          Whether to enable (1) or disable (0) the built-in voltage\n          regulator, which can be used to supply power to a test circuit\n          through I/O header pins +3V3 and +5V. For example:\n               buspirate vreg 0\n\n      -- Command: buspirate led (0|1)\n          Turns the Bus Pirate's LED on (1) or off (0).  For example:\n          buspirate led 1\n\n8.3 Transport Configuration\n===========================\n\nAs noted earlier, depending on the version of OpenOCD you use, and the\ndebug adapter you are using, several transports may be available to\ncommunicate with debug targets (or perhaps to program flash memory).\n -- Command: transport list\n     displays the names of the transports supported by this version of\n     OpenOCD.\n\n -- Command: transport select transport_name\n     Select which of the supported transports to use in this OpenOCD\n     session.\n\n     When invoked with 'transport_name', attempts to select the named\n     transport.  The transport must be supported by the debug adapter\n     hardware and by the version of OpenOCD you are using (including the\n     adapter's driver).\n\n     If no transport has been selected and no 'transport_name' is\n     provided, 'transport select' auto-selects the first transport\n     supported by the debug adapter.\n\n     'transport select' always returns the name of the session's\n     selected transport, if any.\n\n8.3.1 JTAG Transport\n--------------------\n\nJTAG is the original transport supported by OpenOCD, and most of the\nOpenOCD commands support it.  JTAG transports expose a chain of one or\nmore Test Access Points (TAPs), each of which must be explicitly\ndeclared.  JTAG supports both debugging and boundary scan testing.\nFlash programming support is built on top of debug support.\n\nJTAG transport is selected with the command 'transport select jtag'.\nUnless your adapter uses either *note the hla interface driver:\nhla_interface. (in which case the command is 'transport select\nhla_jtag') or *note the st-link interface driver: st_link_dap_interface.\n(in which case the command is 'transport select dapdirect_jtag').\n\n8.3.2 SWD Transport\n-------------------\n\nSWD (Serial Wire Debug) is an ARM-specific transport which exposes one\nDebug Access Point (DAP, which must be explicitly declared.  (SWD uses\nfewer signal wires than JTAG.) SWD is debug-oriented, and does not\nsupport boundary scan testing.  Flash programming support is built on\ntop of debug support.  (Some processors support both JTAG and SWD.)\n\nSWD transport is selected with the command 'transport select swd'.\nUnless your adapter uses either *note the hla interface driver:\nhla_interface. (in which case the command is 'transport select hla_swd')\nor *note the st-link interface driver: st_link_dap_interface. (in which\ncase the command is 'transport select dapdirect_swd').\n\n -- Config Command: swd newdap ...\n     Declares a single DAP which uses SWD transport.  Parameters are\n     currently the same as \"jtag newtap\" but this is expected to change.\n\nThe newer SWD devices (SW-DP v2 or SWJ-DP v2) support the multi-drop\nextension of SWD protocol: two or more devices can be connected to one\nSWD adapter.  SWD transport works in multi-drop mode if *note DAP:\ndap_create. is configured with both '-dp-id' and '-instance-id'\nparameters regardless how many DAPs are created.\n\nNot all adapters and adapter drivers support SWD multi-drop.  Only the\nfollowing adapter drivers are SWD multi-drop capable: cmsis_dap (use an\nadapter with CMSIS-DAP version 2.0), ftdi, all bitbang based.\n\n8.3.3 SPI Transport\n-------------------\n\nThe Serial Peripheral Interface (SPI) is a general purpose transport\nwhich uses four wire signaling.  Some processors use it as part of a\nsolution for flash programming.\n\n8.3.4 SWIM Transport\n--------------------\n\nThe Single Wire Interface Module (SWIM) is a low-pin-count debug\nprotocol used by the STMicroelectronics MCU family STM8 and documented\nin the User Manual UM470\n(https://www.st.com/resource/en/user_manual/cd00173911.pdf).\n\nSWIM does not support boundary scan testing nor multiple cores.\n\nThe SWIM transport is selected with the command 'transport select swim'.\n\nThe concept of TAPs does not fit in the protocol since SWIM does not\nimplement a scan chain.  Nevertheless, the current SW model of OpenOCD\nrequires defining a virtual SWIM TAP through the command 'swim newtap\nbasename tap_type'.  The TAP definition must precede the target\ndefinition command 'target create target_name stm8 -chain-position\nbasename.tap_type'.\n\n8.4 JTAG Speed\n==============\n\nJTAG clock setup is part of system setup.  It _does not belong with\ninterface setup_ since any interface only knows a few of the constraints\nfor the JTAG clock speed.  Sometimes the JTAG speed is changed during\nthe target initialization process: (1) slow at reset, (2) program the\nCPU clocks, (3) run fast.  Both the \"slow\" and \"fast\" clock rates are\nfunctions of the oscillators used, the chip, the board design, and\nsometimes power management software that may be active.\n\nThe speed used during reset, and the scan chain verification which\nfollows reset, can be adjusted using a 'reset-start' target event\nhandler.  It can then be reconfigured to a faster speed by a\n'reset-init' target event handler after it reprograms those CPU clocks,\nor manually (if something else, such as a boot loader, sets up those\nclocks).  *Note Target Events: targetevents.  When the initial low JTAG\nspeed is a chip characteristic, perhaps because of a required oscillator\nspeed, provide such a handler in the target config file.  When that\nspeed is a function of a board-specific characteristic such as which\nspeed oscillator is used, it belongs in the board config file instead.\nIn both cases it's safest to also set the initial JTAG clock rate to\nthat same slow speed, so that OpenOCD never starts up using a clock\nspeed that's faster than the scan chain can support.\n\n     jtag_rclk 3000\n     $_TARGET.cpu configure -event reset-start { jtag_rclk 3000 }\n\nIf your system supports adaptive clocking (RTCK), configuring JTAG to\nuse that is probably the most robust approach.  However, it introduces\ndelays to synchronize clocks; so it may not be the fastest solution.\n\nNOTE: Script writers should consider using 'jtag_rclk' instead of\n'adapter speed', but only for (ARM) cores and boards which support\nadaptive clocking.\n\n -- Command: adapter speed max_speed_kHz\n     A non-zero speed is in KHZ. Hence: 3000 is 3mhz.  JTAG interfaces\n     usually support a limited number of speeds.  The speed actually\n     used won't be faster than the speed specified.\n\n     Chip data sheets generally include a top JTAG clock rate.  The\n     actual rate is often a function of a CPU core clock, and is\n     normally less than that peak rate.  For example, most ARM cores\n     accept at most one sixth of the CPU clock.\n\n     Speed 0 (khz) selects RTCK method.  *Note FAQ RTCK: faqrtck.  If\n     your system uses RTCK, you won't need to change the JTAG clocking\n     after setup.  Not all interfaces, boards, or targets support\n     \"rtck\".  If the interface device can not support it, an error is\n     returned when you try to use RTCK.\n\n -- Function: jtag_rclk fallback_speed_kHz\n     This Tcl proc (defined in 'startup.tcl') attempts to enable\n     RTCK/RCLK. If that fails (maybe the interface, board, or target\n     doesn't support it), falls back to the specified frequency.\n          # Fall back to 3mhz if RTCK is not supported\n          jtag_rclk 3000\n\n\u001f\nFile: openocd.info,  Node: Reset Configuration,  Next: TAP Declaration,  Prev: Debug Adapter Configuration,  Up: Top\n\n9 Reset Configuration\n*********************\n\nEvery system configuration may require a different reset configuration.\nThis can also be quite confusing.  Resets also interact with RESET-INIT\nevent handlers, which do things like setting up clocks and DRAM, and\nJTAG clock rates.  (*Note JTAG Speed: jtagspeed.)  They can also\ninteract with JTAG routers.  Please see the various board files for\nexamples.\n\n     Note: To maintainers and integrators: Reset configuration touches\n     several things at once.  Normally the board configuration file\n     should define it and assume that the JTAG adapter supports\n     everything that's wired up to the board's JTAG connector.\n\n     However, the target configuration file could also make note of\n     something the silicon vendor has done inside the chip, which will\n     be true for most (or all) boards using that chip.  And when the\n     JTAG adapter doesn't support everything, the user configuration\n     file will need to override parts of the reset configuration\n     provided by other files.\n\n9.1 Types of Reset\n==================\n\nThere are many kinds of reset possible through JTAG, but they may not\nall work with a given board and adapter.  That's part of why reset\nconfiguration can be error prone.\n\n   * _System Reset_ ...  the _SRST_ hardware signal resets all chips\n     connected to the JTAG adapter, such as processors, power management\n     chips, and I/O controllers.  Normally resets triggered with this\n     signal behave exactly like pressing a RESET button.\n   * _JTAG TAP Reset_ ...  the _TRST_ hardware signal resets just the\n     TAP controllers connected to the JTAG adapter.  Such resets should\n     not be visible to the rest of the system; resetting a device's TAP\n     controller just puts that controller into a known state.\n   * _Emulation Reset_ ...  many devices can be reset through JTAG\n     commands.  These resets are often distinguishable from system\n     resets, either explicitly (a \"reset reason\" register says so) or\n     implicitly (not all parts of the chip get reset).\n   * _Other Resets_ ...  system-on-chip devices often support several\n     other types of reset.  You may need to arrange that a watchdog\n     timer stops while debugging, preventing a watchdog reset.  There\n     may be individual module resets.\n\nIn the best case, OpenOCD can hold SRST, then reset the TAPs via TRST\nand send commands through JTAG to halt the CPU at the reset vector\nbefore the 1st instruction is executed.  Then when it finally releases\nthe SRST signal, the system is halted under debugger control before any\ncode has executed.  This is the behavior required to support the 'reset\nhalt' and 'reset init' commands; after 'reset init' a board-specific\nscript might do things like setting up DRAM. (*Note Reset Command:\nresetcommand.)\n\n9.2 SRST and TRST Issues\n========================\n\nBecause SRST and TRST are hardware signals, they can have a variety of\nsystem-specific constraints.  Some of the most common issues are:\n\n   * _Signal not available_ ...  Some boards don't wire SRST or TRST to\n     the JTAG connector.  Some JTAG adapters don't support such signals\n     even if they are wired up.  Use the 'reset_config' SIGNALS options\n     to say when either of those signals is not connected.  When SRST is\n     not available, your code might not be able to rely on controllers\n     having been fully reset during code startup.  Missing TRST is not a\n     problem, since JTAG-level resets can be triggered using with TMS\n     signaling.\n\n   * _Signals shorted_ ...  Sometimes a chip, board, or adapter will\n     connect SRST to TRST, instead of keeping them separate.  Use the\n     'reset_config' COMBINATION options to say when those signals aren't\n     properly independent.\n\n   * _Timing_ ...  Reset circuitry like a resistor/capacitor delay\n     circuit, reset supervisor, or on-chip features can extend the\n     effect of a JTAG adapter's reset for some time after the adapter\n     stops issuing the reset.  For example, there may be chip or board\n     requirements that all reset pulses last for at least a certain\n     amount of time; and reset buttons commonly have hardware\n     debouncing.  Use the 'adapter srst delay' and 'jtag_ntrst_delay'\n     commands to say when extra delays are needed.\n\n   * _Drive type_ ...  Reset lines often have a pullup resistor, letting\n     the JTAG interface treat them as open-drain signals.  But that's\n     not a requirement, so the adapter may need to use push/pull output\n     drivers.  Also, with weak pullups it may be advisable to drive\n     signals to both levels (push/pull) to minimize rise times.  Use the\n     'reset_config' TRST_TYPE and SRST_TYPE parameters to say how to\n     drive reset signals.\n\n   * _Special initialization_ ...  Targets sometimes need special JTAG\n     initialization sequences to handle chip-specific issues (not\n     limited to errata).  For example, certain JTAG commands might need\n     to be issued while the system as a whole is in a reset state (SRST\n     active) but the JTAG scan chain is usable (TRST inactive).  Many\n     systems treat combined assertion of SRST and TRST as a trigger for\n     a harder reset than SRST alone.  Such custom reset handling is\n     discussed later in this chapter.\n\nThere can also be other issues.  Some devices don't fully conform to the\nJTAG specifications.  Trivial system-specific differences are common,\nsuch as SRST and TRST using slightly different names.  There are also\nvendors who distribute key JTAG documentation for their chips only to\ndevelopers who have signed a Non-Disclosure Agreement (NDA).\n\nSometimes there are chip-specific extensions like a requirement to use\nthe normally-optional TRST signal (precluding use of JTAG adapters which\ndon't pass TRST through), or needing extra steps to complete a TAP\nreset.\n\nIn short, SRST and especially TRST handling may be very finicky, needing\nto cope with both architecture and board specific constraints.\n\n9.3 Commands for Handling Resets\n================================\n\n -- Command: adapter srst pulse_width milliseconds\n     Minimum amount of time (in milliseconds) OpenOCD should wait after\n     asserting nSRST (active-low system reset) before allowing it to be\n     deasserted.\n\n -- Command: adapter srst delay milliseconds\n     How long (in milliseconds) OpenOCD should wait after deasserting\n     nSRST (active-low system reset) before starting new JTAG\n     operations.  When a board has a reset button connected to SRST line\n     it will probably have hardware debouncing, implying you should use\n     this.\n\n -- Command: jtag_ntrst_assert_width milliseconds\n     Minimum amount of time (in milliseconds) OpenOCD should wait after\n     asserting nTRST (active-low JTAG TAP reset) before allowing it to\n     be deasserted.\n\n -- Command: jtag_ntrst_delay milliseconds\n     How long (in milliseconds) OpenOCD should wait after deasserting\n     nTRST (active-low JTAG TAP reset) before starting new JTAG\n     operations.\n\n -- Command: reset_config mode_flag ...\n     This command displays or modifies the reset configuration of your\n     combination of JTAG board and target in target configuration\n     scripts.\n\n     Information earlier in this section describes the kind of problems\n     the command is intended to address (*note SRST and TRST Issues:\n     srstandtrstissues.).  As a rule this command belongs only in board\n     config files, describing issues like _board doesn't connect TRST_;\n     or in user config files, addressing limitations derived from a\n     particular combination of interface and board.  (An unlikely\n     example would be using a TRST-only adapter with a board that only\n     wires up SRST.)\n\n     The MODE_FLAG options can be specified in any order, but only one\n     of each type - SIGNALS, COMBINATION, GATES, TRST_TYPE, SRST_TYPE\n     and CONNECT_TYPE - may be specified at a time.  If you don't\n     provide a new value for a given type, its previous value (perhaps\n     the default) is unchanged.  For example, this means that you don't\n     need to say anything at all about TRST just to declare that if the\n     JTAG adapter should want to drive SRST, it must explicitly be\n     driven high ('srst_push_pull').\n\n        * SIGNALS can specify which of the reset signals are connected.\n          For example, If the JTAG interface provides SRST, but the\n          board doesn't connect that signal properly, then OpenOCD can't\n          use it.  Possible values are 'none' (the default),\n          'trst_only', 'srst_only' and 'trst_and_srst'.\n\n               Tip: If your board provides SRST and/or TRST through the\n               JTAG connector, you must declare that so those signals\n               can be used.\n\n        * The COMBINATION is an optional value specifying broken reset\n          signal implementations.  The default behaviour if no option\n          given is 'separate', indicating everything behaves normally.\n          'srst_pulls_trst' states that the test logic is reset together\n          with the reset of the system (e.g.  NXP LPC2000, \"broken\"\n          board layout), 'trst_pulls_srst' says that the system is reset\n          together with the test logic (only hypothetical, I haven't\n          seen hardware with such a bug, and can be worked around).\n          'combined' implies both 'srst_pulls_trst' and\n          'trst_pulls_srst'.\n\n        * The GATES tokens control flags that describe some cases where\n          JTAG may be unavailable during reset.  'srst_gates_jtag'\n          (default) indicates that asserting SRST gates the JTAG clock.\n          This means that no communication can happen on JTAG while SRST\n          is asserted.  Its converse is 'srst_nogate', indicating that\n          JTAG commands can safely be issued while SRST is active.\n\n        * The CONNECT_TYPE tokens control flags that describe some cases\n          where SRST is asserted while connecting to the target.\n          'srst_nogate' is required to use this option.\n          'connect_deassert_srst' (default) indicates that SRST will not\n          be asserted while connecting to the target.  Its converse is\n          'connect_assert_srst', indicating that SRST will be asserted\n          before any target connection.  Only some targets support this\n          feature, STM32 and STR9 are examples.  This feature is useful\n          if you are unable to connect to your target due to incorrect\n          options byte config or illegal program execution.\n\n     The optional TRST_TYPE and SRST_TYPE parameters allow the driver\n     mode of each reset line to be specified.  These values only affect\n     JTAG interfaces with support for different driver modes, like the\n     Amontec JTAGkey and JTAG Accelerator.  Also, they are necessarily\n     ignored if the relevant signal (TRST or SRST) is not connected.\n\n        * Possible TRST_TYPE driver modes for the test reset signal\n          (TRST) are the default 'trst_push_pull', and\n          'trst_open_drain'.  Most boards connect this signal to a\n          pulldown, so the JTAG TAPs never leave reset unless they are\n          hooked up to a JTAG adapter.\n\n        * Possible SRST_TYPE driver modes for the system reset signal\n          (SRST) are the default 'srst_open_drain', and\n          'srst_push_pull'.  Most boards connect this signal to a\n          pullup, and allow the signal to be pulled low by various\n          events including system power-up and pressing a reset button.\n\n9.4 Custom Reset Handling\n=========================\n\nOpenOCD has several ways to help support the various reset mechanisms\nprovided by chip and board vendors.  The commands shown in the previous\nsection give standard parameters.  There are also _event handlers_\nassociated with TAPs or Targets.  Those handlers are Tcl procedures you\ncan provide, which are invoked at particular points in the reset\nsequence.\n\n_When SRST is not an option_ you must set up a 'reset-assert' event\nhandler for your target.  For example, some JTAG adapters don't include\nthe SRST signal; and some boards have multiple targets, and you won't\nalways want to reset everything at once.\n\nAfter configuring those mechanisms, you might still find your board\ndoesn't start up or reset correctly.  For example, maybe it needs a\nslightly different sequence of SRST and/or TRST manipulations, because\nof quirks that the 'reset_config' mechanism doesn't address; or\nasserting both might trigger a stronger reset, which needs special\nattention.\n\nExperiment with lower level operations, such as 'adapter assert',\n'adapter deassert' and the 'jtag arp_*' operations shown here, to find a\nsequence of operations that works.  *Note JTAG Commands::.  When you\nfind a working sequence, it can be used to override 'jtag_init', which\nfires during OpenOCD startup (*note Configuration Stage:\nconfigurationstage.); or 'init_reset', which fires during reset\nprocessing.\n\nYou might also want to provide some project-specific reset schemes.  For\nexample, on a multi-target board the standard 'reset' command would\nreset all targets, but you may need the ability to reset only one target\nat time and thus want to avoid using the board-wide SRST signal.\n\n -- Overridable Procedure: init_reset mode\n     This is invoked near the beginning of the 'reset' command, usually\n     to provide as much of a cold (power-up) reset as practical.  By\n     default it is also invoked from 'jtag_init' if the scan chain does\n     not respond to pure JTAG operations.  The MODE parameter is the\n     parameter given to the low level reset command ('halt', 'init', or\n     'run'), 'setup', or potentially some other value.\n\n     The default implementation just invokes 'jtag arp_init-reset'.\n     Replacements will normally build on low level JTAG operations such\n     as 'adapter assert' and 'adapter deassert'.  Operations here must\n     not address individual TAPs (or their associated targets) until the\n     JTAG scan chain has first been verified to work.\n\n     Implementations must have verified the JTAG scan chain before they\n     return.  This is done by calling 'jtag arp_init' (or 'jtag\n     arp_init-reset').\n\n -- Command: jtag arp_init\n     This validates the scan chain using just the four standard JTAG\n     signals (TMS, TCK, TDI, TDO). It starts by issuing a JTAG-only\n     reset.  Then it performs checks to verify that the scan chain\n     configuration matches the TAPs it can observe.  Those checks\n     include checking IDCODE values for each active TAP, and verifying\n     the length of their instruction registers using TAP '-ircapture'\n     and '-irmask' values.  If these tests all pass, TAP 'setup' events\n     are issued to all TAPs with handlers for that event.\n\n -- Command: jtag arp_init-reset\n     This uses TRST and SRST to try resetting everything on the JTAG\n     scan chain (and anything else connected to SRST). It then invokes\n     the logic of 'jtag arp_init'.\n\n\u001f\nFile: openocd.info,  Node: TAP Declaration,  Next: CPU Configuration,  Prev: Reset Configuration,  Up: Top\n\n10 TAP Declaration\n******************\n\n_Test Access Ports_ (TAPs) are the core of JTAG. TAPs serve many roles,\nincluding:\n\n   * Debug Target A CPU TAP can be used as a GDB debug target.\n   * Flash Programming Some chips program the flash directly via JTAG.\n     Others do it indirectly, making a CPU do it.\n   * Program Download Using the same CPU support GDB uses, you can\n     initialize a DRAM controller, download code to DRAM, and then start\n     running that code.\n   * Boundary Scan Most chips support boundary scan, which helps test\n     for board assembly problems like solder bridges and missing\n     connections.\n\nOpenOCD must know about the active TAPs on your board(s).  Setting up\nthe TAPs is the core task of your configuration files.  Once those TAPs\nare set up, you can pass their names to code which sets up CPUs and\nexports them as GDB targets, probes flash memory, performs low-level\nJTAG operations, and more.\n\n10.1 Scan Chains\n================\n\nTAPs are part of a hardware \"scan chain\", which is a daisy chain of\nTAPs.  They also need to be added to OpenOCD's software mirror of that\nhardware list, giving each member a name and associating other data with\nit.  Simple scan chains, with a single TAP, are common in systems with a\nsingle microcontroller or microprocessor.  More complex chips may have\nseveral TAPs internally.  Very complex scan chains might have a dozen or\nmore TAPs: several in one chip, more in the next, and connecting to\nother boards with their own chips and TAPs.\n\nYou can display the list with the 'scan_chain' command.  (Don't confuse\nthis with the list displayed by the 'targets' command, presented in the\nnext chapter.  That only displays TAPs for CPUs which are configured as\ndebugging targets.)  Here's what the scan chain might look like for a\nchip more than one TAP:\n\n   TapName            Enabled IdCode     Expected   IrLen IrCap IrMask\n-- ------------------ ------- ---------- ---------- ----- ----- ------\n 0 omap5912.dsp          Y    0x03df1d81 0x03df1d81    38 0x01  0x03\n 1 omap5912.arm          Y    0x0692602f 0x0692602f     4 0x01  0x0f\n 2 omap5912.unknown      Y    0x00000000 0x00000000     8 0x01  0x03\n\nOpenOCD can detect some of that information, but not all of it.  *Note\nAutoprobing: autoprobing.  Unfortunately, those TAPs can't always be\nautoconfigured, because not all devices provide good support for that.\nJTAG doesn't require supporting IDCODE instructions, and chips with JTAG\nrouters may not link TAPs into the chain until they are told to do so.\n\nThe configuration mechanism currently supported by OpenOCD requires\nexplicit configuration of all TAP devices using 'jtag newtap' commands,\nas detailed later in this chapter.  A command like this would declare\none tap and name it 'chip1.cpu':\n\n     jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477\n\nEach target configuration file lists the TAPs provided by a given chip.\nBoard configuration files combine all the targets on a board, and so\nforth.  Note that _the order in which TAPs are declared is very\nimportant._  That declaration order must match the order in the JTAG\nscan chain, both inside a single chip and between them.  *Note FAQ TAP\nOrder: faqtaporder.\n\nFor example, the STMicroelectronics STR912 chip has three separate\nTAPs(1).  To configure those taps, 'target/str912.cfg' includes commands\nsomething like this:\n\n     jtag newtap str912 flash ... params ...\n     jtag newtap str912 cpu ... params ...\n     jtag newtap str912 bs ... params ...\n\nActual config files typically use a variable such as '$_CHIPNAME'\ninstead of literals like 'str912', to support more than one chip of each\ntype.  *Note Config File Guidelines::.\n\n -- Command: jtag names\n     Returns the names of all current TAPs in the scan chain.  Use 'jtag\n     cget' or 'jtag tapisenabled' to examine attributes and state of\n     each TAP.\n          foreach t [jtag names] {\n              puts [format \"TAP: %s\\n\" $t]\n          }\n\n -- Command: scan_chain\n     Displays the TAPs in the scan chain configuration, and their\n     status.  The set of TAPs listed by this command is fixed by exiting\n     the OpenOCD configuration stage, but systems with a JTAG router can\n     enable or disable TAPs dynamically.\n\n10.2 TAP Names\n==============\n\nWhen TAP objects are declared with 'jtag newtap', a \"dotted.name\" is\ncreated for the TAP, combining the name of a module (usually a chip) and\na label for the TAP. For example: 'xilinx.tap', 'str912.flash',\n'omap3530.jrc', 'dm6446.dsp', or 'stm32.cpu'.  Many other commands use\nthat dotted.name to manipulate or refer to the TAP. For example, CPU\nconfiguration uses the name, as does declaration of NAND or NOR flash\nbanks.\n\nThe components of a dotted name should follow \"C\" symbol name rules:\nstart with an alphabetic character, then numbers and underscores are OK;\nwhile others (including dots!)  are not.\n\n10.3 TAP Declaration Commands\n=============================\n\n -- Config Command: jtag newtap chipname tapname configparams...\n     Declares a new TAP with the dotted name CHIPNAME.TAPNAME, and\n     configured according to the various CONFIGPARAMS.\n\n     The CHIPNAME is a symbolic name for the chip.  Conventionally\n     target config files use '$_CHIPNAME', defaulting to the model name\n     given by the chip vendor but overridable.\n\n     The TAPNAME reflects the role of that TAP, and should follow this\n     convention:\n\n        * 'bs' - For boundary scan if this is a separate TAP;\n        * 'cpu' - The main CPU of the chip, alternatively 'arm' and\n          'dsp' on chips with both ARM and DSP CPUs, 'arm1' and 'arm2'\n          on chips with two ARMs, and so forth;\n        * 'etb' - For an embedded trace buffer (example: an ARM ETB11);\n        * 'flash' - If the chip has a flash TAP, like the str912;\n        * 'jrc' - For JTAG route controller (example: the ICEPick\n          modules on many Texas Instruments chips, like the OMAP3530 on\n          Beagleboards);\n        * 'tap' - Should be used only for FPGA- or CPLD-like devices\n          with a single TAP;\n        * 'unknownN' - If you have no idea what the TAP is for (N is a\n          number);\n        * _when in doubt_ - Use the chip maker's name in their data\n          sheet.  For example, the Freescale i.MX31 has a SDMA (Smart\n          DMA) with a JTAG TAP; that TAP should be named 'sdma'.\n\n     Every TAP requires at least the following CONFIGPARAMS:\n\n        * '-irlen' NUMBER\n          The length in bits of the instruction register, such as 4 or 5\n          bits.\n\n     A TAP may also provide optional CONFIGPARAMS:\n\n        * '-disable' (or '-enable')\n          Use the '-disable' parameter to flag a TAP which is not linked\n          into the scan chain after a reset using either TRST or the\n          JTAG state machine's RESET state.  You may use '-enable' to\n          highlight the default state (the TAP is linked in).  *Note\n          Enabling and Disabling TAPs: enablinganddisablingtaps.\n        * '-expected-id' NUMBER\n          A non-zero NUMBER represents a 32-bit IDCODE which you expect\n          to find when the scan chain is examined.  These codes are not\n          required by all JTAG devices.  _Repeat the option_ as many\n          times as required if more than one ID code could appear (for\n          example, multiple versions).  Specify NUMBER as zero to\n          suppress warnings about IDCODE values that were found but not\n          included in the list.\n\n          Provide this value if at all possible, since it lets OpenOCD\n          tell when the scan chain it sees isn't right.  These values\n          are provided in vendors' chip documentation, usually a\n          technical reference manual.  Sometimes you may need to probe\n          the JTAG hardware to find these values.  *Note Autoprobing:\n          autoprobing.\n        * '-ignore-version'\n          Specify this to ignore the JTAG version field in the\n          '-expected-id' option.  When vendors put out multiple versions\n          of a chip, or use the same JTAG-level ID for several\n          largely-compatible chips, it may be more practical to ignore\n          the version field than to update config files to handle all of\n          the various chip IDs.  The version field is defined as bit\n          28-31 of the IDCODE.\n        * '-ignore-bypass'\n          Specify this to ignore the 'bypass' bit of the idcode.  Some\n          vendor put an invalid idcode regarding this bit.  Specify this\n          to ignore this bit and to not consider this tap in bypass\n          mode.\n        * '-ircapture' NUMBER\n          The bit pattern loaded by the TAP into the JTAG shift register\n          on entry to the IRCAPTURE state, such as 0x01.  JTAG requires\n          the two LSBs of this value to be 01.  By default, '-ircapture'\n          and '-irmask' are set up to verify that two-bit value.  You\n          may provide additional bits if you know them, or indicate that\n          a TAP doesn't conform to the JTAG specification.\n        * '-irmask' NUMBER\n          A mask used with '-ircapture' to verify that instruction scans\n          work correctly.  Such scans are not used by OpenOCD except to\n          verify that there seems to be no problems with JTAG scan chain\n          operations.\n        * '-ignore-syspwrupack'\n          Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP\n          CTRL/STAT register during initial examination and when\n          checking the sticky error bit.  This bit is normally checked\n          after setting the CSYSPWRUPREQ bit, but some devices do not\n          set the ack bit until sometime later.\n\n10.4 Other TAP commands\n=======================\n\n -- Command: jtag cget dotted.name -idcode\n     Get the value of the IDCODE found in hardware.\n\n -- Command: jtag cget dotted.name -event event_name\n -- Command: jtag configure dotted.name -event event_name handler\n     At this writing this TAP attribute mechanism is limited and used\n     mostly for event handling.  (It is not a direct analogue of the\n     'cget'/'configure' mechanism for debugger targets.)  See the next\n     section for information about the available events.\n\n     The 'configure' subcommand assigns an event handler, a TCL string\n     which is evaluated when the event is triggered.  The 'cget'\n     subcommand returns that handler.\n\n10.5 TAP Events\n===============\n\nOpenOCD includes two event mechanisms.  The one presented here applies\nto all JTAG TAPs.  The other applies to debugger targets, which are\nassociated with certain TAPs.\n\nThe TAP events currently defined are:\n\n   * post-reset\n     The TAP has just completed a JTAG reset.  The tap may still be in\n     the JTAG RESET state.  Handlers for these events might perform\n     initialization sequences such as issuing TCK cycles, TMS sequences\n     to ensure exit from the ARM SWD mode, and more.\n\n     Because the scan chain has not yet been verified, handlers for\n     these events _should not issue commands which scan the JTAG IR or\n     DR registers_ of any particular target.  NOTE: As this is written\n     (September 2009), nothing prevents such access.\n   * setup\n     The scan chain has been reset and verified.  This handler may\n     enable TAPs as needed.\n   * tap-disable\n     The TAP needs to be disabled.  This handler should implement 'jtag\n     tapdisable' by issuing the relevant JTAG commands.\n   * tap-enable\n     The TAP needs to be enabled.  This handler should implement 'jtag\n     tapenable' by issuing the relevant JTAG commands.\n\nIf you need some action after each JTAG reset which isn't actually\nspecific to any TAP (since you can't yet trust the scan chain's contents\nto be accurate), you might:\n\n     jtag configure CHIP.jrc -event post-reset {\n       echo \"JTAG Reset done\"\n       ... non-scan jtag operations to be done after reset\n     }\n\n10.6 Enabling and Disabling TAPs\n================================\n\nIn some systems, a \"JTAG Route Controller\" (JRC) is used to enable\nand/or disable specific JTAG TAPs.  Many ARM-based chips from Texas\nInstruments include an \"ICEPick\" module, which is a JRC. Such chips\ninclude DaVinci and OMAP3 processors.\n\nA given TAP may not be visible until the JRC has been told to link it\ninto the scan chain; and if the JRC has been told to unlink that TAP, it\nwill no longer be visible.  Such routers address problems that JTAG\n\"bypass mode\" ignores, such as:\n\n   * The scan chain can only go as fast as its slowest TAP.\n   * Having many TAPs slows instruction scans, since all TAPs receive\n     new instructions.\n   * TAPs in the scan chain must be powered up, which wastes power and\n     prevents debugging some power management mechanisms.\n\nThe IEEE 1149.1 JTAG standard has no concept of a \"disabled\" tap, as\nimplied by the existence of JTAG routers.  However, the upcoming IEEE\n1149.7 framework (layered on top of JTAG) does include a kind of JTAG\nrouter functionality.\n\nIn OpenOCD, tap enabling/disabling is invoked by the Tcl commands shown\nbelow, and is implemented using TAP event handlers.  So for example,\nwhen defining a TAP for a CPU connected to a JTAG router, your\n'target.cfg' file should define TAP event handlers using code that looks\nsomething like this:\n\n     jtag configure CHIP.cpu -event tap-enable {\n       ... jtag operations using CHIP.jrc\n     }\n     jtag configure CHIP.cpu -event tap-disable {\n       ... jtag operations using CHIP.jrc\n     }\n\nThen you might want that CPU's TAP enabled almost all the time:\n\n     jtag configure $CHIP.jrc -event setup \"jtag tapenable $CHIP.cpu\"\n\nNote how that particular setup event handler declaration uses quotes to\nevaluate '$CHIP' when the event is configured.  Using brackets { } would\ncause it to be evaluated later, at runtime, when it might have a\ndifferent value.\n\n -- Command: jtag tapdisable dotted.name\n     If necessary, disables the tap by sending it a 'tap-disable' event.\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n -- Command: jtag tapenable dotted.name\n     If necessary, enables the tap by sending it a 'tap-enable' event.\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n -- Command: jtag tapisenabled dotted.name\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n          Note: Humans will find the 'scan_chain' command more helpful\n          for querying the state of the JTAG taps.\n\n10.7 Autoprobing\n================\n\nTAP configuration is the first thing that needs to be done after\ninterface and reset configuration.  Sometimes it's hard finding out what\nTAPs exist, or how they are identified.  Vendor documentation is not\nalways easy to find and use.\n\nTo help you get past such problems, OpenOCD has a limited _autoprobing_\nability to look at the scan chain, doing a \"blind interrogation\" and\nthen reporting the TAPs it finds.  To use this mechanism, start the\nOpenOCD server with only data that configures your JTAG interface, and\narranges to come up with a slow clock (many devices don't support fast\nJTAG clocks right when they come out of reset).\n\nFor example, your 'openocd.cfg' file might have:\n\n     source [find interface/olimex-arm-usb-tiny-h.cfg]\n     reset_config trst_and_srst\n     jtag_rclk 8\n\nWhen you start the server without any TAPs configured, it will attempt\nto autoconfigure the TAPs.  There are two parts to this:\n\n  1. _TAP discovery_ ...  After a JTAG reset (sometimes a system reset\n     may be needed too), each TAP's data registers will hold the\n     contents of either the IDCODE or BYPASS register.  If JTAG\n     communication is working, OpenOCD will see each TAP, and report\n     what '-expected-id' to use with it.\n  2. _IR Length discovery_ ...  Unfortunately JTAG does not provide a\n     reliable way to find out the value of the '-irlen' parameter to use\n     with a TAP that is discovered.  If OpenOCD can discover the length\n     of a TAP's instruction register, it will report it.  Otherwise you\n     may need to consult vendor documentation, such as chip data sheets\n     or BSDL files.\n\nIn many cases your board will have a simple scan chain with just a\nsingle device.  Here's what OpenOCD reported with one board that's a bit\nmore complex:\n\n     clock speed 8 kHz\n     There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!\n     AUTO auto0.tap - use \"jtag newtap auto0 tap -expected-id 0x2b900f0f ...\"\n     AUTO auto1.tap - use \"jtag newtap auto1 tap -expected-id 0x07926001 ...\"\n     AUTO auto2.tap - use \"jtag newtap auto2 tap -expected-id 0x0b73b02f ...\"\n     AUTO auto0.tap - use \"... -irlen 4\"\n     AUTO auto1.tap - use \"... -irlen 4\"\n     AUTO auto2.tap - use \"... -irlen 6\"\n     no gdb ports allocated as no target has been specified\n\nGiven that information, you should be able to either find some existing\nconfig files to use, or create your own.  If you create your own, you\nwould configure from the bottom up: first a 'target.cfg' file with these\nTAPs, any targets associated with them, and any on-chip resources; then\na 'board.cfg' with off-chip resources, clocking, and so forth.\n\n10.8 DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets)\n=======================================================\n\nSince OpenOCD version 0.11.0, the Debug Access Port (DAP) is no longer\nimplicitly created together with the target.  It must be explicitly\ndeclared using the 'dap create' command.  For all ARMv6-M, ARMv7 and\nARMv8 targets, the option \"'-dap' DAP_NAME\" has to be used instead of\n\"'-chain-position' DOTTED.NAME\" when the target is created.\n\nThe 'dap' command group supports the following sub-commands:\n\n -- Command: dap create dap_name -chain-position dotted.name\n          configparams...\n     Declare a DAP instance named DAP_NAME linked to the JTAG tap\n     DOTTED.NAME.  This also creates a new command ('dap_name') which is\n     used for various purposes including additional configuration.\n     There can only be one DAP for each JTAG tap in the system.\n\n     A DAP may also provide optional CONFIGPARAMS:\n\n        * '-ignore-syspwrupack'\n          Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP\n          CTRL/STAT register during initial examination and when\n          checking the sticky error bit.  This bit is normally checked\n          after setting the CSYSPWRUPREQ bit, but some devices do not\n          set the ack bit until sometime later.\n\n        * '-dp-id' NUMBER\n          Debug port identification number for SWD DPv2 multidrop.  The\n          NUMBER is written to bits 0..27 of DP TARGETSEL during DP\n          selection.  To find the id number of a single connected device\n          read DP TARGETID: 'device.dap dpreg 0x24' Use bits 0..27 of\n          TARGETID.\n\n        * '-instance-id' NUMBER\n          Instance identification number for SWD DPv2 multidrop.  The\n          NUMBER is written to bits 28..31 of DP TARGETSEL during DP\n          selection.  To find the instance number of a single connected\n          device read DP DLPIDR: 'device.dap dpreg 0x34' The instance\n          number is in bits 28..31 of DLPIDR value.\n\n -- Command: dap names\n     This command returns a list of all registered DAP objects.  It it\n     useful mainly for TCL scripting.\n\n -- Command: dap info [num]\n     Displays the ROM table for MEM-AP NUM, defaulting to the currently\n     selected AP of the currently selected target.\n\n -- Command: dap init\n     Initialize all registered DAPs.  This command is used internally\n     during initialization.  It can be issued at any time after the\n     initialization, too.\n\nThe following commands exist as subcommands of DAP instances:\n\n -- Command: $dap_name info [num]\n     Displays the ROM table for MEM-AP NUM, defaulting to the currently\n     selected AP.\n\n -- Command: $dap_name apid [num]\n     Displays ID register from AP NUM, defaulting to the currently\n     selected AP.\n\n -- Command: $dap_name apreg ap_num reg [value]\n     Displays content of a register REG from AP AP_NUM or set a new\n     value VALUE.  REG is byte address of a word register, 0, 4, 8 ...\n     0xfc.\n\n -- Command: $dap_name apsel [num]\n     Select AP NUM, defaulting to 0.\n\n -- Command: $dap_name dpreg reg [value]\n     Displays the content of DP register at address REG, or set it to a\n     new value VALUE.\n\n     In case of SWD, REG is a value in packed format dpbanksel << 4 |\n     addr and assumes values 0, 4, 8 ...  0xfc.  In case of JTAG it only\n     assumes values 0, 4, 8 and 0xc.\n\n     _Note:_ Consider using 'poll off' to avoid any disturbing\n     background activity by OpenOCD while you are operating at such\n     low-level.\n\n -- Command: $dap_name baseaddr [num]\n     Displays debug base address from MEM-AP NUM, defaulting to the\n     currently selected AP.\n\n -- Command: $dap_name memaccess [value]\n     Displays the number of extra tck cycles in the JTAG idle to use for\n     MEM-AP memory bus access [0-255], giving additional time to respond\n     to reads.  If VALUE is defined, first assigns that.\n\n -- Command: $dap_name apcsw [value [mask]]\n     Displays or changes CSW bit pattern for MEM-AP transfers.\n\n     At the begin of each memory access the CSW pattern is extended\n     (bitwise or-ed) by \"Size\" and \"AddrInc\" bit-fields according to\n     transfer requirements and the result is written to the real CSW\n     register.  All bits except dynamically updated fields \"Size\" and\n     \"AddrInc\" can be changed by changing the CSW pattern.  Refer to ARM\n     ADI v5 manual chapter 7.6.4 and appendix A for details.\n\n     Use VALUE only syntax if you want to set the new CSW pattern as a\n     whole.  The example sets HPROT1 bit (required by Cortex-M) and\n     clears the rest of the pattern:\n          kx.dap apcsw 0x2000000\n\n     If MASK is also used, the CSW pattern is changed only on bit\n     positions where the mask bit is 1.  The following example sets\n     HPROT3 (cacheable) and leaves the rest of the pattern intact.  It\n     configures memory access through DCache on Cortex-M7.\n          set CSW_HPROT3_CACHEABLE [expr {1 << 27}]\n          samv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE\n\n     Another example clears SPROT bit and leaves the rest of pattern\n     intact:\n          set CSW_SPROT [expr {1 << 30}]\n          samv.dap apcsw 0 $CSW_SPROT\n\n     _Note:_ If you want to check the real value of CSW, not CSW\n     pattern, use 'xxx.dap apreg 0'.  *Note DAP subcommand apreg::.\n\n     _Warning:_ Some of the CSW bits are vital for working memory\n     transfer.  If you set a wrong CSW pattern and MEM-AP stopped\n     working, use the following example with a proper dap name:\n          xxx.dap apcsw default\n\n -- Config Command: $dap_name ti_be_32_quirks [enable]\n     Set/get quirks mode for TI TMS450/TMS570 processors Disabled by\n     default\n\n   ---------- Footnotes ----------\n\n   (1) See the ST document titled: _STR91xFAxxx, Section 3.15 Jtag\nInterface, Page: 28/102, Figure 3: JTAG chaining inside the STR91xFA_.\n<http://eu.st.com/stonline/products/literature/ds/13495.pdf>\n\n\u001f\nFile: openocd.info,  Node: CPU Configuration,  Next: Flash Commands,  Prev: TAP Declaration,  Up: Top\n\n11 CPU Configuration\n********************\n\nThis chapter discusses how to set up GDB debug targets for CPUs.  You\ncan also access these targets without GDB (*note Architecture and Core\nCommands::, and *note Target State handling: targetstatehandling.) and\nthrough various kinds of NAND and NOR flash commands.  If you have\nmultiple CPUs you can have multiple such targets.\n\nWe'll start by looking at how to examine the targets you have, then look\nat how to add one more target and how to configure it.\n\n11.1 Target List\n================\n\nAll targets that have been set up are part of a list, where each member\nhas a name.  That name should normally be the same as the TAP name.  You\ncan display the list with the 'targets' (plural!)  command.  This\ndisplay often has only one CPU; here's what it might look like with more\nthan one:\n    TargetName         Type       Endian TapName            State\n--  ------------------ ---------- ------ ------------------ ------------\n 0* at91rm9200.cpu     arm920t    little at91rm9200.cpu     running\n 1  MyTarget           cortex_m   little mychip.foo         tap-disabled\n\nOne member of that list is the \"current target\", which is implicitly\nreferenced by many commands.  It's the one marked with a '*' near the\ntarget name.  In particular, memory addresses often refer to the address\nspace seen by that current target.  Commands like 'mdw' (memory display\nwords) and 'flash erase_address' (erase NOR flash blocks) are examples;\nand there are many more.\n\nSeveral commands let you examine the list of targets:\n\n -- Command: target current\n     Returns the name of the current target.\n\n -- Command: target names\n     Lists the names of all current targets in the list.\n          foreach t [target names] {\n              puts [format \"Target: %s\\n\" $t]\n          }\n\n -- Command: targets [name]\n     _Note: the name of this command is plural.  Other target command\n     names are singular._\n\n     With no parameter, this command displays a table of all known\n     targets in a user friendly form.\n\n     With a parameter, this command sets the current target to the given\n     target with the given NAME; this is only relevant on boards which\n     have more than one target.\n\n11.2 Target CPU Types\n=====================\n\nEach target has a \"CPU type\", as shown in the output of the 'targets'\ncommand.  You need to specify that type when calling 'target create'.\nThe CPU type indicates more than just the instruction set.  It also\nindicates how that instruction set is implemented, what kind of debug\nsupport it integrates, whether it has an MMU (and if so, what kind),\nwhat core-specific commands may be available (*note Architecture and\nCore Commands::), and more.\n\nIt's easy to see what target types are supported, since there's a\ncommand to list them.\n\n -- Command: target types\n     Lists all supported target types.  At this writing, the supported\n     CPU types are:\n\n        * 'aarch64' - this is an ARMv8-A core with an MMU.\n        * 'arm11' - this is a generation of ARMv6 cores.\n        * 'arm720t' - this is an ARMv4 core with an MMU.\n        * 'arm7tdmi' - this is an ARMv4 core.\n        * 'arm920t' - this is an ARMv4 core with an MMU.\n        * 'arm926ejs' - this is an ARMv5 core with an MMU.\n        * 'arm946e' - this is an ARMv5 core with an MMU.\n        * 'arm966e' - this is an ARMv5 core.\n        * 'arm9tdmi' - this is an ARMv4 core.\n        * 'avr' - implements Atmel's 8-bit AVR instruction set.\n          (Support for this is preliminary and incomplete.)\n        * 'avr32_ap7k' - this an AVR32 core.\n        * 'cortex_a' - this is an ARMv7-A core with an MMU.\n        * 'cortex_m' - this is an ARMv7-M core, supporting only the\n          compact Thumb2 instruction set.  Supports also ARMv6-M and\n          ARMv8-M cores\n        * 'cortex_r4' - this is an ARMv7-R core.\n        * 'dragonite' - resembles arm966e.\n        * 'dsp563xx' - implements Freescale's 24-bit DSP. (Support for\n          this is still incomplete.)\n        * 'dsp5680xx' - implements Freescale's 5680x DSP.\n        * 'esirisc' - this is an EnSilica eSi-RISC core.  The current\n          implementation supports eSi-32xx cores.\n        * 'esp32s2' - this is an Espressif SoC with single Xtensa core.\n        * 'fa526' - resembles arm920 (w/o Thumb).\n        * 'feroceon' - resembles arm926.\n        * 'hla_target' - a Cortex-M alternative to work with HL adapters\n          like ST-Link.\n        * 'ls1_sap' - this is the SAP on NXP LS102x CPUs, allowing\n          access to physical memory addresses independently of CPU\n          cores.\n        * 'mem_ap' - this is an ARM debug infrastructure Access Port\n          without a CPU, through which bus read and write cycles can be\n          generated; it may be useful for working with non-CPU hardware\n          behind an AP or during development of support for new CPUs.\n          It's possible to connect a GDB client to this target (the GDB\n          port has to be specified, *Note option -gdb-port:\n          gdbportoverride.), and a fake ARM core will be emulated to\n          comply to GDB remote protocol.\n        * 'mips_m4k' - a MIPS core.\n        * 'mips_mips64' - a MIPS64 core.\n        * 'nds32_v2' - this is an Andes NDS32 v2 core (deprecated; would\n          be removed in v0.13.0).\n        * 'nds32_v3' - this is an Andes NDS32 v3 core (deprecated; would\n          be removed in v0.13.0).\n        * 'nds32_v3m' - this is an Andes NDS32 v3m core (deprecated;\n          would be removed in v0.13.0).\n        * 'or1k' - this is an OpenRISC 1000 core.  The current\n          implementation supports three JTAG TAP cores:\n             - 'OpenCores TAP' (See:\n               <http://opencores.org/project,jtag>)\n             - 'Altera Virtual JTAG TAP' (See:\n               <http://www.altera.com/literature/ug/ug_virtualjtag.pdf>)\n             - 'Xilinx BSCAN_* virtual JTAG interface' (See:\n               <http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/spartan6_hdl.pdf>)\n          And two debug interfaces cores:\n             - 'Advanced debug interface'\n               (See: <http://opencores.org/project,adv_debug_sys>)\n             - 'SoC Debug Interface'\n               (See: <http://opencores.org/project,dbg_interface>)\n        * 'quark_d20xx' - an Intel Quark D20xx core.\n        * 'quark_x10xx' - an Intel Quark X10xx core.\n        * 'riscv' - a RISC-V core.\n        * 'stm8' - implements an STM8 core.\n        * 'testee' - a dummy target for cases without a real CPU, e.g.\n          CPLD.\n        * 'xscale' - this is actually an architecture, not a CPU type.\n          It is based on the ARMv5 architecture.\n\nTo avoid being confused by the variety of ARM based cores, remember this\nkey point: _ARM is a technology licencing company_.  (See:\n<http://www.arm.com>.)  The CPU name used by OpenOCD will reflect the\nCPU design that was licensed, not a vendor brand which incorporates that\ndesign.  Name prefixes like arm7, arm9, arm11, and cortex reflect design\ngenerations; while names like ARMv4, ARMv5, ARMv6, ARMv7 and ARMv8\nreflect an architecture version implemented by a CPU design.\n\n11.3 Target Configuration\n=========================\n\nBefore creating a \"target\", you must have added its TAP to the scan\nchain.  When you've added that TAP, you will have a 'dotted.name' which\nis used to set up the CPU support.  The chip-specific configuration file\nwill normally configure its CPU(s) right after it adds all of the chip's\nTAPs to the scan chain.\n\nAlthough you can set up a target in one step, it's often clearer if you\nuse shorter commands and do it in two steps: create it, then configure\noptional parts.  All operations on the target after it's created will\nuse a new command, created as part of target creation.\n\nThe two main things to configure after target creation are a work area,\nwhich usually has target-specific defaults even if the board setup code\noverrides them later; and event handlers (*note Target Events:\ntargetevents.), which tend to be much more board-specific.  The key\nsteps you use might look something like this\n\n     dap create mychip.dap -chain-position mychip.cpu\n     target create MyTarget cortex_m -dap mychip.dap\n     MyTarget configure -work-area-phys 0x08000 -work-area-size 8096\n     MyTarget configure -event reset-deassert-pre { jtag_rclk 5 }\n     MyTarget configure -event reset-init { myboard_reinit }\n\nYou should specify a working area if you can; typically it uses some\non-chip SRAM. Such a working area can speed up many things, including\nbulk writes to target memory; flash operations like checking to see if\nmemory needs to be erased; GDB memory checksumming; and more.\n\n     Warning: On more complex chips, the work area can become\n     inaccessible when application code (such as an operating system)\n     enables or disables the MMU. For example, the particular MMU\n     context used to access the virtual address will probably matter ...\n     and that context might not have easy access to other addresses\n     needed.  At this writing, OpenOCD doesn't have much MMU\n     intelligence.\n\nIt's often very useful to define a 'reset-init' event handler.  For\nsystems that are normally used with a boot loader, common tasks include\nupdating clocks and initializing memory controllers.  That may be needed\nto let you write the boot loader into flash, in order to \"de-brick\" your\nboard; or to load programs into external DDR memory without having run\nthe boot loader.\n\n -- Config Command: target create target_name type configparams...\n     This command creates a GDB debug target that refers to a specific\n     JTAG tap.  It enters that target into a list, and creates a new\n     command ('TARGET_NAME') which is used for various purposes\n     including additional configuration.\n\n        * TARGET_NAME ...  is the name of the debug target.  By\n          convention this should be the same as the _dotted.name_ of the\n          TAP associated with this target, which must be specified here\n          using the '-chain-position DOTTED.NAME' configparam.\n\n          This name is also used to create the target object command,\n          referred to here as '$target_name', and in other places the\n          target needs to be identified.\n        * TYPE ...  specifies the target type.  *Note target types:\n          targettypes.\n        * CONFIGPARAMS ...  all parameters accepted by '$target_name\n          configure' are permitted.  If the target is big-endian, set it\n          here with '-endian big'.\n\n          You _must_ set the '-chain-position DOTTED.NAME' or '-dap\n          DAP_NAME' here.\n\n -- Command: $target_name configure configparams...\n     The options accepted by this command may also be specified as\n     parameters to 'target create'.  Their values can later be queried\n     one at a time by using the '$target_name cget' command.\n\n     _Warning:_ changing some of these after setup is dangerous.  For\n     example, moving a target from one TAP to another; and changing its\n     endianness.\n\n        * '-chain-position' DOTTED.NAME - names the TAP used to access\n          this target.\n\n        * '-dap' DAP_NAME - names the DAP used to access this target.\n          *Note DAP declaration: dapdeclaration, on how to create and\n          manage DAP instances.\n\n        * '-endian' ('big'|'little') - specifies whether the CPU uses\n          big or little endian conventions\n\n        * '-event' EVENT_NAME EVENT_BODY - *Note Target Events:\n          targetevents.  Note that this updates a list of named event\n          handlers.  Calling this twice with two different event names\n          assigns two different handlers, but calling it twice with the\n          same event name assigns only one handler.\n\n          Current target is temporarily overridden to the event issuing\n          target before handler code starts and switched back after\n          handler is done.\n\n        * '-work-area-backup' ('0'|'1') - says whether the work area\n          gets backed up; by default, _it is not backed up._  When\n          possible, use a working_area that doesn't need to be backed\n          up, since performing a backup slows down operations.  For\n          example, the beginning of an SRAM block is likely to be used\n          by most build systems, but the end is often unused.\n\n        * '-work-area-size' SIZE - specify work are size, in bytes.  The\n          same size applies regardless of whether its physical or\n          virtual address is being used.\n\n        * '-work-area-phys' ADDRESS - set the work area base ADDRESS to\n          be used when no MMU is active.\n\n        * '-work-area-virt' ADDRESS - set the work area base ADDRESS to\n          be used when an MMU is active.  _Do not specify a value for\n          this except on targets with an MMU._ The value should normally\n          correspond to a static mapping for the '-work-area-phys'\n          address, set up by the current operating system.\n\n        * '-rtos' RTOS_TYPE - enable rtos support for target, RTOS_TYPE\n          can be one of 'auto', 'eCos', 'ThreadX', 'FreeRTOS', 'linux',\n          'ChibiOS', 'embKernel', 'mqx', 'uCOS-III', 'nuttx', 'RIOT',\n          'Zephyr' *Note RTOS Support: gdbrtossupport.\n\n        * '-defer-examine' - skip target examination at initial JTAG\n          chain scan and after a reset.  A manual call to arp_examine is\n          required to access the target for debugging.\n\n        * '-ap-num' AP_NUMBER - set DAP access port for target,\n          AP_NUMBER is the numeric index of the DAP AP the target is\n          connected to.  Use this option with systems where multiple,\n          independent cores are connected to separate access ports of\n          the same DAP.\n\n        * '-cti' CTI_NAME - set Cross-Trigger Interface (CTI) connected\n          to the target.  Currently, only the 'aarch64' target makes use\n          of this option, where it is a mandatory configuration for the\n          target run control.  *Note ARM Cross-Trigger Interface:\n          armcrosstrigger, for instruction on how to declare and control\n          a CTI instance.\n\n        * '-gdb-port' NUMBER - see command 'gdb_port' for the possible\n          values of the parameter NUMBER, which are not only numeric\n          values.  Use this option to override, for this target only,\n          the global parameter set with command 'gdb_port'.  *Note\n          command gdb_port: gdb_port.\n\n        * '-gdb-max-connections' NUMBER - EXPERIMENTAL: set the maximum\n          number of GDB connections that are allowed for the target.\n          Default is 1.  A negative value for NUMBER means unlimited\n          connections.  See *Note Using GDB as a non-intrusive memory\n          inspector: gdbmeminspect.\n\n11.4 Other $target_name Commands\n================================\n\nThe Tcl/Tk language has the concept of object commands, and OpenOCD\nadopts that same model for targets.\n\nA good Tk example is a on screen button.  Once a button is created a\nbutton has a name (a path in Tk terms) and that name is useable as a\nfirst class command.  For example in Tk, one can create a button and\nlater configure it like this:\n\n     # Create\n     button .foobar -background red -command { foo }\n     # Modify\n     .foobar configure -foreground blue\n     # Query\n     set x [.foobar cget -background]\n     # Report\n     puts [format \"The button is %s\" $x]\n\nIn OpenOCD's terms, the \"target\" is an object just like a Tcl/Tk button,\nand its object commands are invoked the same way.\n\n     str912.cpu    mww 0x1234 0x42\n     omap3530.cpu  mww 0x5555 123\n\nThe commands supported by OpenOCD target objects are:\n\n -- Command: $target_name arp_examine allow-defer\n -- Command: $target_name arp_halt\n -- Command: $target_name arp_poll\n -- Command: $target_name arp_reset\n -- Command: $target_name arp_waitstate\n     Internal OpenOCD scripts (most notably 'startup.tcl') use these to\n     deal with specific reset cases.  They are not otherwise documented\n     here.\n\n -- Command: $target_name set_reg dict\n     Set register values of the target.\n\n        * DICT ...  Tcl dictionary with pairs of register names and\n          values.\n\n     For example, the following command sets the value 0 to the program\n     counter (pc) register and 0x1000 to the stack pointer (sp)\n     register:\n\n          set_reg {pc 0 sp 0x1000}\n\n -- Command: $target_name get_reg [-force] list\n     Get register values from the target and return them as Tcl\n     dictionary with pairs of register names and values.  If option\n     \"-force\" is set, the register values are read directly from the\n     target, bypassing any caching.\n\n        * LIST ...  List of register names\n\n     For example, the following command retrieves the values from the\n     program counter (pc) and stack pointer (sp) register:\n\n          get_reg {pc sp}\n\n -- Command: $target_name write_memory address width data ['phys']\n     This function provides an efficient way to write to the target\n     memory from a Tcl script.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * DATA ...  Tcl list with the elements to write\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command writes two 32 bit words into the\n     target memory at address 0x20000000:\n\n          write_memory 0x20000000 32 {0xdeadbeef 0x00230500}\n\n -- Command: $target_name read_memory address width count ['phys']\n     This function provides an efficient way to read the target memory\n     from a Tcl script.  A Tcl list containing the requested memory\n     elements is returned by this function.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * COUNT ...  number of elements to read\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command reads two 32 bit words from the\n     target memory at address 0x20000000:\n\n          read_memory 0x20000000 32 2\n\n -- Command: $target_name cget queryparm\n     Each configuration parameter accepted by '$target_name configure'\n     can be individually queried, to return its current value.  The\n     QUERYPARM is a parameter name accepted by that command, such as\n     '-work-area-phys'.  There are a few special cases:\n\n        * '-event' EVENT_NAME - returns the handler for the event named\n          EVENT_NAME.  This is a special case because setting a handler\n          requires two parameters.\n        * '-type' - returns the target type.  This is a special case\n          because this is set using 'target create' and can't be changed\n          using '$target_name configure'.\n\n     For example, if you wanted to summarize information about all the\n     targets you might use something like this:\n\n          foreach name [target names] {\n              set y [$name cget -endian]\n              set z [$name cget -type]\n              puts [format \"Chip %d is %s, Endian: %s, type: %s\" \\\n                           $x $name $y $z]\n          }\n\n -- Command: $target_name curstate\n     Displays the current target state: 'debug-running', 'halted',\n     'reset', 'running', or 'unknown'.  (Also, *note Event Polling:\n     eventpolling.)\n\n -- Command: $target_name eventlist\n     Displays a table listing all event handlers currently associated\n     with this target.  *Note Target Events: targetevents.\n\n -- Command: $target_name invoke-event event_name\n     Invokes the handler for the event named EVENT_NAME.  (This is\n     primarily intended for use by OpenOCD framework code, for example\n     by the reset code in 'startup.tcl'.)\n\n -- Command: $target_name mdd [phys] addr [count]\n -- Command: $target_name mdw [phys] addr [count]\n -- Command: $target_name mdh [phys] addr [count]\n -- Command: $target_name mdb [phys] addr [count]\n     Display contents of address ADDR, as 64-bit doublewords ('mdd'),\n     32-bit words ('mdw'), 16-bit halfwords ('mdh'), or 8-bit bytes\n     ('mdb').  When the current target has an MMU which is present and\n     active, ADDR is interpreted as a virtual address.  Otherwise, or if\n     the optional PHYS flag is specified, ADDR is interpreted as a\n     physical address.  If COUNT is specified, displays that many units.\n     (If you want to process the data instead of displaying it, see the\n     'read_memory' primitives.)\n\n -- Command: $target_name mwd [phys] addr doubleword [count]\n -- Command: $target_name mww [phys] addr word [count]\n -- Command: $target_name mwh [phys] addr halfword [count]\n -- Command: $target_name mwb [phys] addr byte [count]\n     Writes the specified DOUBLEWORD (64 bits), WORD (32 bits), HALFWORD\n     (16 bits), or BYTE (8-bit) value, at the specified address ADDR.\n     When the current target has an MMU which is present and active,\n     ADDR is interpreted as a virtual address.  Otherwise, or if the\n     optional PHYS flag is specified, ADDR is interpreted as a physical\n     address.  If COUNT is specified, fills that many units of\n     consecutive address.\n\n11.5 Target Events\n==================\n\nAt various times, certain things can happen, or you want them to happen.\nFor example:\n   * What should happen when GDB connects?  Should your target reset?\n   * When GDB tries to flash the target, do you need to enable the flash\n     via a special command?\n   * Is using SRST appropriate (and possible) on your system?  Or\n     instead of that, do you need to issue JTAG commands to trigger\n     reset?  SRST usually resets everything on the scan chain, which can\n     be inappropriate.\n   * During reset, do you need to write to certain memory locations to\n     set up system clocks or to reconfigure the SDRAM? How about\n     configuring the watchdog timer, or other peripherals, to stop\n     running while you hold the core stopped for debugging?\n\nAll of the above items can be addressed by target event handlers.  These\nare set up by '$target_name configure -event' or 'target create ...\n-event'.\n\nThe programmer's model matches the '-command' option used in Tcl/Tk\nbuttons and events.  The two examples below act the same, but one\ncreates and invokes a small procedure while the other inlines it.\n\n     proc my_init_proc { } {\n         echo \"Disabling watchdog...\"\n         mww 0xfffffd44 0x00008000\n     }\n     mychip.cpu configure -event reset-init my_init_proc\n     mychip.cpu configure -event reset-init {\n         echo \"Disabling watchdog...\"\n         mww 0xfffffd44 0x00008000\n     }\n\nThe following target events are defined:\n\n   * debug-halted\n     The target has halted for debug reasons (i.e.: breakpoint)\n   * debug-resumed\n     The target has resumed (i.e.: GDB said run)\n   * early-halted\n     Occurs early in the halt process\n   * examine-start\n     Before target examine is called.\n   * examine-end\n     After target examine is called with no errors.\n   * examine-fail\n     After target examine fails.\n   * gdb-attach\n     When GDB connects.  Issued before any GDB communication with the\n     target starts.  GDB expects the target is halted during attachment.\n     *Note GDB as a non-intrusive memory inspector: gdbmeminspect, how\n     to connect GDB to running target.  The event can be also used to\n     set up the target so it is possible to probe flash.  Probing flash\n     is necessary during GDB connect if you want to use *note\n     programming using GDB: programmingusinggdb.  Another use of the\n     flash memory map is for GDB to automatically choose hardware or\n     software breakpoints depending on whether the breakpoint is in RAM\n     or read only memory.  Default is 'halt'\n   * gdb-detach\n     When GDB disconnects\n   * gdb-end\n     When the target has halted and GDB is not doing anything (see early\n     halt)\n   * gdb-flash-erase-start\n     Before the GDB flash process tries to erase the flash (default is\n     'reset init')\n   * gdb-flash-erase-end\n     After the GDB flash process has finished erasing the flash\n   * gdb-flash-write-start\n     Before GDB writes to the flash\n   * gdb-flash-write-end\n     After GDB writes to the flash (default is 'reset halt')\n   * gdb-start\n     Before the target steps, GDB is trying to start/resume the target\n   * halted\n     The target has halted\n   * reset-assert-pre\n     Issued as part of 'reset' processing after 'reset-start' was\n     triggered but before either SRST alone is asserted on the scan\n     chain, or 'reset-assert' is triggered.\n   * reset-assert\n     Issued as part of 'reset' processing after 'reset-assert-pre' was\n     triggered.  When such a handler is present, cores which support\n     this event will use it instead of asserting SRST. This support is\n     essential for debugging with JTAG interfaces which don't include an\n     SRST line (JTAG doesn't require SRST), and for selective reset on\n     scan chains that have multiple targets.\n   * reset-assert-post\n     Issued as part of 'reset' processing after 'reset-assert' has been\n     triggered.  or the target asserted SRST on the entire scan chain.\n   * reset-deassert-pre\n     Issued as part of 'reset' processing after 'reset-assert-post' has\n     been triggered.\n   * reset-deassert-post\n     Issued as part of 'reset' processing after 'reset-deassert-pre' has\n     been triggered and (if the target is using it) after SRST has been\n     released on the scan chain.\n   * reset-end\n     Issued as the final step in 'reset' processing.\n   * reset-init\n     Used by reset init command for board-specific initialization.  This\n     event fires after _reset-deassert-post_.\n\n     This is where you would configure PLLs and clocking, set up DRAM so\n     you can download programs that don't fit in on-chip SRAM, set up\n     pin multiplexing, and so on.  (You may be able to switch to a fast\n     JTAG clock rate here, after the target clocks are fully set up.)\n   * reset-start\n     Issued as the first step in 'reset' processing before\n     'reset-assert-pre' is called.\n\n     This is the most robust place to use 'jtag_rclk' or 'adapter speed'\n     to switch to a low JTAG clock rate, when reset disables PLLs needed\n     to use a fast clock.\n   * resume-start\n     Before any target is resumed\n   * resume-end\n     After all targets have resumed\n   * resumed\n     Target has resumed\n   * step-start\n     Before a target is single-stepped\n   * step-end\n     After single-step has completed\n   * trace-config\n     After target hardware trace configuration was changed\n   * semihosting-user-cmd-0x100\n     The target made a semihosting call with user-defined operation\n     number 0x100\n   * semihosting-user-cmd-0x101\n     The target made a semihosting call with user-defined operation\n     number 0x101\n   * semihosting-user-cmd-0x102\n     The target made a semihosting call with user-defined operation\n     number 0x102\n   * semihosting-user-cmd-0x103\n     The target made a semihosting call with user-defined operation\n     number 0x103\n   * semihosting-user-cmd-0x104\n     The target made a semihosting call with user-defined operation\n     number 0x104\n   * semihosting-user-cmd-0x105\n     The target made a semihosting call with user-defined operation\n     number 0x105\n   * semihosting-user-cmd-0x106\n     The target made a semihosting call with user-defined operation\n     number 0x106\n   * semihosting-user-cmd-0x107\n     The target made a semihosting call with user-defined operation\n     number 0x107\n\n     Note: OpenOCD events are not supposed to be preempt by another\n     event, but this is not enforced in current code.  Only the target\n     event resumed is executed with polling disabled; this avoids\n     polling to trigger the event halted, reversing the logical order of\n     execution of their handlers.  Future versions of OpenOCD will\n     prevent the event preemption and will disable the schedule of\n     polling during the event execution.  Do not rely on polling in any\n     event handler; this means, don't expect the status of a core to\n     change during the execution of the handler.  The event handler will\n     have to enable polling or use '$target_name arp_poll' to check if\n     the core has changed status.\n\n\u001f\nFile: openocd.info,  Node: Flash Commands,  Next: Flash Programming,  Prev: CPU Configuration,  Up: Top\n\n12 Flash Commands\n*****************\n\nOpenOCD has different commands for NOR and NAND flash; the \"flash\"\ncommand works with NOR flash, while the \"nand\" command works with NAND\nflash.  This partially reflects different hardware technologies: NOR\nflash usually supports direct CPU instruction and data bus access, while\ndata from a NAND flash must be copied to memory before it can be used.\n(SPI flash must also be copied to memory before use.)  However, the\ndocumentation also uses \"flash\" as a generic term; for example, \"Put\nflash configuration in board-specific files\".\n\nFlash Steps:\n  1. Configure via the command 'flash bank'\n     Do this in a board-specific configuration file, passing parameters\n     as needed by the driver.\n  2. Operate on the flash via 'flash subcommand'\n     Often commands to manipulate the flash are typed by a human, or run\n     via a script in some automated way.  Common tasks include writing a\n     boot loader, operating system, or other data.\n  3. GDB Flashing\n     Flashing via GDB requires the flash be configured via \"flash bank\",\n     and the GDB flash features be enabled.  *Note GDB Configuration:\n     gdbconfiguration.\n\nMany CPUs have the ability to \"boot\" from the first flash bank.  This\nmeans that misprogramming that bank can \"brick\" a system, so that it\ncan't boot.  JTAG tools, like OpenOCD, are often then used to \"de-brick\"\nthe board by (re)installing working boot firmware.\n\n12.1 Flash Configuration Commands\n=================================\n\n -- Config Command: flash bank name driver base size chip_width\n          bus_width target [driver_options]\n     Configures a flash bank which provides persistent storage for\n     addresses from base to base + size - 1.  These banks will often be\n     visible to GDB through the target's memory map.  In some cases,\n     configuring a flash bank will activate extra commands; see the\n     driver-specific documentation.\n\n        * NAME ...  may be used to reference the flash bank in other\n          flash commands.  A number is also available.\n        * DRIVER ...  identifies the controller driver associated with\n          the flash bank being declared.  This is usually 'cfi' for\n          external flash, or else the name of a microcontroller with\n          embedded flash memory.  *Note Flash Driver List:\n          flashdriverlist.\n        * BASE ...  Base address of the flash chip.\n        * SIZE ...  Size of the chip, in bytes.  For some drivers, this\n          value is detected from the hardware.\n        * CHIP_WIDTH ...  Width of the flash chip, in bytes; ignored for\n          most microcontroller drivers.\n        * BUS_WIDTH ...  Width of the data bus used to access the chip,\n          in bytes; ignored for most microcontroller drivers.\n        * TARGET ...  Names the target used to issue commands to the\n          flash controller.\n        * DRIVER_OPTIONS ...  drivers may support, or require,\n          additional parameters.  See the driver-specific documentation\n          for more information.\n          Note: This command is not available after OpenOCD\n          initialization has completed.  Use it in board specific\n          configuration files, not interactively.\n\n -- Command: flash banks\n     Prints a one-line summary of each device that was declared using\n     'flash bank', numbered from zero.  Note that this is the _plural_\n     form; the _singular_ form is a very different command.\n\n -- Command: flash list\n     Retrieves a list of associative arrays for each device that was\n     declared using 'flash bank', numbered from zero.  This returned\n     list can be manipulated easily from within scripts.\n\n -- Command: flash probe num\n     Identify the flash, or validate the parameters of the configured\n     flash.  Operation depends on the flash type.  The NUM parameter is\n     a value shown by 'flash banks'.  Most flash commands will\n     implicitly _autoprobe_ the bank; flash drivers can distinguish\n     between probing and autoprobing, but most don't bother.\n\n12.2 Preparing a Target before Flash Programming\n================================================\n\nThe target device should be in well defined state before the flash\nprogramming begins.\n\n_Always issue_ 'reset init' before *note Flash Programming Commands:\nflashprogrammingcommands.  Do not issue another 'reset' or 'reset halt'\nor 'resume' until the programming session is finished.\n\nIf you use *note Programming using GDB: programmingusinggdb, the target\nis prepared automatically in the event gdb-flash-erase-start\n\nThe jimtcl script 'program' calls 'reset init' explicitly.\n\n12.3 Erasing, Reading, Writing to Flash\n=======================================\n\nOne feature distinguishing NOR flash from NAND or serial flash\ntechnologies is that for read access, it acts exactly like any other\naddressable memory.  This means you can use normal memory read commands\nlike 'mdw' or 'dump_image' with it, with no special 'flash' subcommands.\n*Note Memory access: memoryaccess, and *note Image access: imageaccess.\n\nWrite access works differently.  Flash memory normally needs to be\nerased before it's written.  Erasing a sector turns all of its bits to\nones, and writing can turn ones into zeroes.  This is why there are\nspecial commands for interactive erasing and writing, and why GDB needs\nto know which parts of the address space hold NOR flash memory.\n\n     Note: Most of these erase and write commands leverage the fact that\n     NOR flash chips consume target address space.  They implicitly\n     refer to the current JTAG target, and map from an address in that\n     target's address space back to a flash bank.  A few commands use\n     abstract addressing based on bank and sector numbers, and don't\n     depend on searching the current target and its address space.\n     Avoid confusing the two command models.\n\nSome flash chips implement software protection against accidental\nwrites, since such buggy writes could in some cases \"brick\" a system.\nFor such systems, erasing and writing may require sector protection to\nbe disabled first.  Examples include CFI flash such as \"Intel Advanced\nBootblock flash\", and AT91SAM7 on-chip flash.  *Note flash protect:\nflashprotect.\n\n -- Command: flash erase_sector num first last\n     Erase sectors in bank NUM, starting at sector FIRST up to and\n     including LAST.  Sector numbering starts at 0.  Providing a LAST\n     sector of 'last' specifies \"to the end of the flash bank\".  The NUM\n     parameter is a value shown by 'flash banks'.\n\n -- Command: flash erase_address [pad] [unlock] address length\n     Erase sectors starting at ADDRESS for LENGTH bytes.  Unless 'pad'\n     is specified, address must begin a flash sector, and address +\n     length - 1 must end a sector.  Specifying 'pad' erases extra data\n     at the beginning and/or end of the specified region, as needed to\n     erase only full sectors.  The flash bank to use is inferred from\n     the ADDRESS, and the specified length must stay within that bank.\n     As a special case, when LENGTH is zero and ADDRESS is the start of\n     the bank, the whole flash is erased.  If 'unlock' is specified,\n     then the flash is unprotected before erase starts.\n\n -- Command: flash filld address double-word length\n -- Command: flash fillw address word length\n -- Command: flash fillh address halfword length\n -- Command: flash fillb address byte length\n     Fills flash memory with the specified DOUBLE-WORD (64 bits), WORD\n     (32 bits), HALFWORD (16 bits), or BYTE (8-bit) pattern, starting at\n     ADDRESS and continuing for LENGTH units (word/halfword/byte).  No\n     erasure is done before writing; when needed, that must be done\n     before issuing this command.  Writes are done in blocks of up to\n     1024 bytes, and each write is verified by reading back the data and\n     comparing it to what was written.  The flash bank to use is\n     inferred from the ADDRESS of each block, and the specified length\n     must stay within that bank.\n\n -- Command: flash mdw addr [count]\n -- Command: flash mdh addr [count]\n -- Command: flash mdb addr [count]\n     Display contents of address ADDR, as 32-bit words ('mdw'), 16-bit\n     halfwords ('mdh'), or 8-bit bytes ('mdb').  If COUNT is specified,\n     displays that many units.  Reads from flash using the flash driver,\n     therefore it enables reading from a bank not mapped in target\n     address space.  The flash bank to use is inferred from the ADDRESS\n     of each block, and the specified length must stay within that bank.\n\n -- Command: flash write_bank num filename [offset]\n     Write the binary 'filename' to flash bank NUM, starting at OFFSET\n     bytes from the beginning of the bank.  If OFFSET is omitted, start\n     at the beginning of the flash bank.  The NUM parameter is a value\n     shown by 'flash banks'.\n\n -- Command: flash read_bank num filename [offset [length]]\n     Read LENGTH bytes from the flash bank NUM starting at OFFSET and\n     write the contents to the binary 'filename'.  If OFFSET is omitted,\n     start at the beginning of the flash bank.  If LENGTH is omitted,\n     read the remaining bytes from the flash bank.  The NUM parameter is\n     a value shown by 'flash banks'.\n\n -- Command: flash verify_bank num filename [offset]\n     Compare the contents of the binary file FILENAME with the contents\n     of the flash bank NUM starting at OFFSET.  If OFFSET is omitted,\n     start at the beginning of the flash bank.  Fail if the contents do\n     not match.  The NUM parameter is a value shown by 'flash banks'.\n\n -- Command: flash write_image [erase] [unlock] filename [offset] [type]\n     Write the image 'filename' to the current target's flash bank(s).\n     Only loadable sections from the image are written.  A relocation\n     OFFSET may be specified, in which case it is added to the base\n     address for each section in the image.  The file [TYPE] can be\n     specified explicitly as 'bin' (binary), 'ihex' (Intel hex), 'elf'\n     (ELF file), 's19' (Motorola s19).  'mem', or 'builder'.  The\n     relevant flash sectors will be erased prior to programming if the\n     'erase' parameter is given.  If 'unlock' is provided, then the\n     flash banks are unlocked before erase and program.  The flash bank\n     to use is inferred from the address of each image section.\n\n          Warning: Be careful using the 'erase' flag when the flash is\n          holding data you want to preserve.  Portions of the flash\n          outside those described in the image's sections might be\n          erased with no notice.\n             * When a section of the image being written does not fill\n               out all the sectors it uses, the unwritten parts of those\n               sectors are necessarily also erased, because sectors\n               can't be partially erased.\n             * Data stored in sector \"holes\" between image sections are\n               also affected.  For example, \"'flash write_image erase\n               ...'\" of an image with one byte at the beginning of a\n               flash bank and one byte at the end erases the entire bank\n               - not just the two sectors being written.\n          Also, when flash protection is important, you must re-apply it\n          after it has been removed by the 'unlock' flag.\n\n -- Command: flash verify_image filename [offset] [type]\n     Verify the image 'filename' to the current target's flash bank(s).\n     Parameters follow the description of 'flash write_image'.  In\n     contrast to the 'verify_image' command, for banks with specific\n     verify method, that one is used instead of the usual target's read\n     memory methods.  This is necessary for flash banks not readable by\n     ordinary memory reads.  This command gives only an overall good/bad\n     result for each bank, not addresses of individual failed bytes as\n     it's intended only as quick check for successful programming.\n\n12.4 Other Flash commands\n=========================\n\n -- Command: flash erase_check num\n     Check erase state of sectors in flash bank NUM, and display that\n     status.  The NUM parameter is a value shown by 'flash banks'.\n\n -- Command: flash info num [sectors]\n     Print info about flash bank NUM, a list of protection blocks and\n     their status.  Use 'sectors' to show a list of sectors instead.\n\n     The NUM parameter is a value shown by 'flash banks'.  This command\n     will first query the hardware, it does not print cached and\n     possibly stale information.\n\n -- Command: flash protect num first last (on|off)\n     Enable ('on') or disable ('off') protection of flash blocks in\n     flash bank NUM, starting at protection block FIRST and continuing\n     up to and including LAST.  Providing a LAST block of 'last'\n     specifies \"to the end of the flash bank\".  The NUM parameter is a\n     value shown by 'flash banks'.  The protection block is usually\n     identical to a flash sector.  Some devices may utilize a protection\n     block distinct from flash sector.  See 'flash info' for a list of\n     protection blocks.\n\n -- Command: flash padded_value num value\n     Sets the default value used for padding any image sections, This\n     should normally match the flash bank erased value.  If not\n     specified by this command or the flash driver then it defaults to\n     0xff.\n\n -- Command: program filename [preverify] [verify] [reset] [exit]\n          [offset]\n     This is a helper script that simplifies using OpenOCD as a\n     standalone programmer.  The only required parameter is 'filename',\n     the others are optional.  *Note Flash Programming::.\n\n12.5 Flash Driver List\n======================\n\nAs noted above, the 'flash bank' command requires a driver name, and\nallows driver-specific options and behaviors.  Some drivers also\nactivate driver-specific commands.\n\n -- Flash Driver: virtual\n     This is a special driver that maps a previously defined bank to\n     another address.  All bank settings will be copied from the master\n     physical bank.\n\n     The VIRTUAL driver defines one mandatory parameters,\n\n        * MASTER_BANK The bank that this virtual address refers to.\n\n     So in the following example addresses 0xbfc00000 and 0x9fc00000\n     refer to the flash bank defined at address 0x1fc00000.  Any command\n     executed on the virtual banks is actually performed on the physical\n     banks.\n          flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n          flash bank vbank0 virtual 0xbfc00000 0 0 0 \\\n                     $_TARGETNAME $_FLASHNAME\n          flash bank vbank1 virtual 0x9fc00000 0 0 0 \\\n                     $_TARGETNAME $_FLASHNAME\n\n12.5.1 External Flash\n---------------------\n\n -- Flash Driver: cfi\n     The \"Common Flash Interface\" (CFI) is the main standard for\n     external NOR flash chips, each of which connects to a specific\n     external chip select on the CPU. Frequently the first such chip is\n     used to boot the system.  Your board's 'reset-init' handler might\n     need to configure additional chip selects using other commands\n     (like: 'mww' to configure a bus and its timings), or perhaps\n     configure a GPIO pin that controls the \"write protect\" pin on the\n     flash chip.  The CFI driver can use a target-specific working area\n     to significantly speed up operation.\n\n     The CFI driver can accept the following optional parameters, in any\n     order:\n\n        * JEDEC_PROBE ...  is used to detect certain non-CFI flash ROMs,\n          like AM29LV010 and similar types.\n        * X16_AS_X8 ...  when a 16-bit flash is hooked up to an 8-bit\n          bus.\n        * BUS_SWAP ...  when data bytes in a 16-bit flash needs to be\n          swapped.\n        * DATA_SWAP ...  when data bytes in a 16-bit flash needs to be\n          swapped when writing data values (i.e.  not CFI commands).\n\n     To configure two adjacent banks of 16 MBytes each, both sixteen\n     bits (two bytes) wide on a sixteen bit bus:\n\n          flash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n          flash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\n     To configure one bank of 32 MBytes built from two sixteen bit (two\n     byte) wide parts wired in parallel to create a thirty-two bit (four\n     byte) bus with doubled throughput:\n\n          flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n\n -- Flash Driver: jtagspi\n     Several FPGAs and CPLDs can retrieve their configuration\n     (bitstream) from a SPI flash connected to them.  To access this\n     flash from the host, the device is first programmed with a special\n     proxy bitstream that exposes the SPI flash on the device's JTAG\n     interface.  The flash can then be accessed through JTAG.\n\n     Since signaling between JTAG and SPI is compatible, all that is\n     required for a proxy bitstream is to connect TDI-MOSI, TDO-MISO,\n     TCK-CLK and activate the flash chip select when the JTAG state\n     machine is in SHIFT-DR. Such a bitstream for several Xilinx FPGAs\n     can be found in 'contrib/loaders/flash/fpga/xilinx_bscan_spi.py'.\n     It requires migen (https://github.com/m-labs/migen) and a Xilinx\n     toolchain to build.\n\n     This flash bank driver requires a target on a JTAG tap and will\n     access that tap directly.  Since no support from the target is\n     needed, the target can be a \"testee\" dummy.  Since the target does\n     not expose the flash memory mapping, target commands that would\n     otherwise be expected to access the flash will not work.  These\n     include all '*_image' and '$target_name m*' commands as well as\n     'program'.  Equivalent functionality is available through the\n     'flash write_bank', 'flash read_bank', and 'flash verify_bank'\n     commands.\n\n     According to device size, 1- to 4-byte addresses are sent.\n     However, some flash chips additionally have to be switched to\n     4-byte addresses by an extra command, see below.\n\n        * IR ...  is loaded into the JTAG IR to map the flash as the\n          JTAG DR. For the bitstreams generated from\n          'xilinx_bscan_spi.py' this is the USER1 instruction.\n\n          target create $_TARGETNAME testee -chain-position $_CHIPNAME.fpga\n          set _XILINX_USER1 0x02\n          flash bank $_FLASHNAME spi 0x0 0 0 0 \\\n                     $_TARGETNAME $_XILINX_USER1\n\n      -- Command: jtagspi set bank_id name total_size page_size read_cmd\n               unused pprg_cmd mass_erase_cmd sector_size\n               sector_erase_cmd\n          Sets flash parameters: NAME human readable string, TOTAL_SIZE\n          size in bytes, PAGE_SIZE is write page size.  READ_CMD and\n          PPRG_CMD are commands for read and page program, respectively.\n          MASS_ERASE_CMD, SECTOR_SIZE and SECTOR_ERASE_CMD are optional.\n               jtagspi set 0 w25q128 0x1000000 0x100 0x03 0 0x02 0xC7 0x10000 0xD8\n\n      -- Command: jtagspi cmd bank_id resp_num cmd_byte ...\n          Sends command CMD_BYTE and at most 20 following bytes and\n          reads RESP_NUM bytes afterwards.  E.g.  for 'Enter 4-byte\n          address mode'\n               jtagspi cmd 0 0 0xB7\n\n      -- Command: jtagspi always_4byte bank_id [ on | off ]\n          Some devices use 4-byte addresses for all commands except the\n          legacy 0x03 read regardless of device size.  This command\n          controls the corresponding hack.\n\n -- Flash Driver: xcf\n     Xilinx FPGAs can be configured from specialized flash ICs named\n     Platform Flash.  It is (almost) regular NOR flash with erase\n     sectors, program pages, etc.  The only difference is special\n     registers controlling its FPGA specific behavior.  They must be\n     properly configured for successful FPGA loading using additional\n     XCF driver command:\n\n      -- Command: xcf ccb <bank_id>\n          command accepts additional parameters:\n             * EXTERNAL|INTERNAL ...  selects clock source.\n             * SERIAL|PARALLEL ...  selects serial or parallel data bus\n               mode.\n             * SLAVE|MASTER ...  selects slave of master mode for flash\n               device.\n             * 40|20 ...  selects clock frequency in MHz for internal\n               clock in master mode.\n               xcf ccb 0 external parallel slave 40\n          All of them must be specified even if clock frequency is\n          pointless in slave mode.  If only bank id specified than\n          command prints current CCB register value.  Note: there is no\n          need to write this register every time you erase/program data\n          sectors because it stores in dedicated sector.\n\n      -- Command: xcf configure <bank_id>\n          Initiates FPGA loading procedure.  Useful if your board has no\n          \"configure\" button.\n               xcf configure 0\n\n     Additional driver notes:\n        * Only single revision supported.\n        * Driver automatically detects need of bit reverse, but only\n          \"bin\" (raw binary, do not confuse it with \"bit\") and \"mcs\"\n          (Intel hex) file types supported.\n        * For additional info check xapp972.pdf and ug380.pdf.\n\n -- Flash Driver: lpcspifi\n     NXP's LPC43xx and LPC18xx families include a proprietary SPI Flash\n     Interface (SPIFI) peripheral that can drive and provide memory\n     mapped access to external SPI flash devices.\n\n     The lpcspifi driver initializes this interface and provides program\n     and erase functionality for these serial flash devices.  Use of\n     this driver requires a working area of at least 1kB to be\n     configured on the target device; more than this will significantly\n     reduce flash programming times.\n\n     The setup command only requires the BASE parameter.  All other\n     parameters are ignored, and the flash size and layout are\n     configured by the driver.\n\n          flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: stmsmi\n     Some devices from STMicroelectronics (e.g.  STR75x MCU family,\n     SPEAr MPU family) include a proprietary \"Serial Memory Interface\"\n     (SMI) controller able to drive external SPI flash devices.\n     Depending on specific device and board configuration, up to 4\n     external flash devices can be connected.\n\n     SMI makes the flash content directly accessible in the CPU address\n     space; each external device is mapped in a memory bank.  CPU can\n     directly read data, execute code and boot from SMI banks.  Normal\n     OpenOCD commands like 'mdw' can be used to display the flash\n     content.\n\n     The setup command only requires the BASE parameter in order to\n     identify the memory bank.  All other parameters are ignored.\n     Additional information, like flash size, are detected\n     automatically.\n\n          flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: stmqspi\n     Some devices from STMicroelectronics include a proprietary \"QuadSPI\n     Interface\" (e.g.  STM32F4, STM32F7, STM32L4) or \"OctoSPI Interface\"\n     (e.g.  STM32L4+) controller able to drive one or even two (dual\n     mode) external SPI flash devices.  The OctoSPI is a superset of\n     QuadSPI, its presence is detected automatically.  Currently only\n     the regular command mode is supported, whereas the HyperFlash mode\n     is not.\n\n     QuadSPI/OctoSPI makes the flash contents directly accessible in the\n     CPU address space; in case of dual mode both devices must be of the\n     same type and are mapped in the same memory bank (even and odd\n     addresses interleaved).  CPU can directly read data, execute code\n     (but not boot) from QuadSPI bank.\n\n     The 'flash bank' command only requires the BASE parameter and the\n     extra parameter IO_BASE in order to identify the memory bank.  Both\n     are fixed by hardware, see datasheet or RM. All other parameters\n     are ignored.\n\n     The controller must be initialized after each reset and properly\n     configured for memory-mapped read operation for the particular\n     flash chip(s), for the full list of available register settings cf.\n     the controller's RM. This setup is quite board specific (that's why\n     booting from this memory is not possible).  The flash driver infers\n     all parameters from current controller register values when 'flash\n     probe BANK_ID' is executed.\n\n     Normal OpenOCD commands like 'mdw' can be used to display the flash\n     content, but only after proper controller initialization as\n     described above.  However, due to a silicon bug in some devices,\n     attempting to access the very last word should be avoided.\n\n     It is possible to use two (even different) flash chips\n     alternatingly, if individual bank chip selects are available.  For\n     some package variants, this is not the case due to limited pin\n     count.  To switch from one to another, adjust FSEL bit accordingly\n     and re-issue 'flash probe bank_id'.  Note that the bank base\n     address will _not_ change, so the address spaces of both devices\n     will overlap.  In dual flash mode both chips must be identical\n     regarding size and most other properties.\n\n     Block or sector protection internal to the flash chip is not\n     handled by this driver at all, but can be dealt with manually by\n     the 'cmd' command, see below.  The sector protection via 'flash\n     protect' command etc.  is completely internal to openocd, intended\n     only to prevent accidental erase or overwrite and it does not\n     persist across openocd invocations.\n\n     OpenOCD contains a hardcoded list of flash devices with their\n     properties, these are auto-detected.  If a device is not included\n     in this list, SFDP discovery is attempted.  If this fails or gives\n     inappropriate results, manual setting is required (see 'set'\n     command).\n\n          flash bank $_FLASHNAME stmqspi 0x90000000 0 0 0 \\\n                     $_TARGETNAME 0xA0001000\n          flash bank $_FLASHNAME stmqspi 0x70000000 0 0 0 \\\n                     $_TARGETNAME 0xA0001400\n\n     There are three specific commands\n      -- Command: stmqspi mass_erase bank_id\n          Clears sector protections and performs a mass erase.  Works\n          only if there is no chip specific write protection engaged.\n\n      -- Command: stmqspi set bank_id name total_size page_size read_cmd\n               fread_cmd pprg_cmd mass_erase_cmd sector_size\n               sector_erase_cmd\n          Set flash parameters: NAME human readable string, TOTAL_SIZE\n          size in bytes, PAGE_SIZE is write page size.  READ_CMD,\n          FREAD_CMD and PPRG_CMD are commands for reading and page\n          programming.  FREAD_CMD is used in DPI and QPI modes, READ_CMD\n          in normal SPI (single line) mode.  MASS_ERASE_CMD, SECTOR_SIZE\n          and SECTOR_ERASE_CMD are optional.\n\n          This command is required if chip id is not hardcoded yet and\n          e.g.  for EEPROMs or FRAMs which don't support an id command.\n\n          In dual mode parameters of both chips are set identically.\n          The parameters refer to a single chip, so the whole bank gets\n          twice the specified capacity etc.\n\n      -- Command: stmqspi cmd bank_id resp_num cmd_byte ...\n          If RESP_NUM is zero, sends command CMD_BYTE and following data\n          bytes.  In dual mode command byte is sent to _both_ chips but\n          data bytes are sent _alternatingly_ to chip 1 and 2, first to\n          flash 1, second to flash 2, etc., i.e.  the total number of\n          bytes (including cmd_byte) must be odd.\n\n          If RESP_NUM is not zero, cmd and at most four following data\n          bytes are sent, in dual mode _simultaneously_ to both chips.\n          Then RESP_NUM bytes are read interleaved from both chips\n          starting with chip 1.  In this case RESP_NUM must be even.\n\n          Note the hardware dictated subtle difference of those two\n          cases in dual-flash mode.\n\n          To check basic communication settings, issue\n               stmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 1 0x05\n               stmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 1 0x05\n          for single flash mode or\n               stmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 2 0x05\n               stmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 2 0x05\n          for dual flash mode.  This should return the status register\n          contents.\n\n          In 8-line mode, CMD_BYTE is sent twice - first time as given,\n          second time complemented.  Additionally, in 8-line mode only,\n          some commands (e.g.  Read Status) need a dummy address, e.g.\n               stmqspi cmd bank_id 1 0x05 0x00 0x00 0x00 0x00\n          should return the status register contents.\n\n -- Flash Driver: mrvlqspi\n     This driver supports QSPI flash controller of Marvell's Wireless\n     Microcontroller platform.\n\n     The flash size is autodetected based on the table of known JEDEC\n     IDs hardcoded in the OpenOCD sources.\n\n          flash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000\n\n -- Flash Driver: ath79\n     Members of ATH79 SoC family from Atheros include a SPI interface\n     with 3 chip selects.  On reset a SPI flash connected to the first\n     chip select (CS0) is made directly read-accessible in the CPU\n     address space (up to 16MBytes) and is usually used to store the\n     bootloader and operating system.  Normal OpenOCD commands like\n     'mdw' can be used to display the flash content while it is in\n     memory-mapped mode (only the first 4MBytes are accessible without\n     additional configuration on reset).\n\n     The setup command only requires the BASE parameter in order to\n     identify the memory bank.  The actual value for the base address is\n     not otherwise used by the driver.  However the mapping is passed to\n     gdb.  Thus for the memory mapped flash (chipselect CS0) the base\n     address should be the actual memory mapped base address.  For\n     unmapped chipselects (CS1 and CS2) care should be taken to use a\n     base address that does not overlap with real memory regions.\n     Additional information, like flash size, are detected\n     automatically.  An optional additional parameter sets the\n     chipselect for the bank, with the default CS0.  CS1 and CS2 require\n     additional GPIO setup before they can be used since the alternate\n     function must be enabled on the GPIO pin CS1/CS2 is routed to on\n     the given SoC.\n\n          flash bank $_FLASHNAME ath79 0xbf000000 0 0 0 $_TARGETNAME\n\n          # When using multiple chipselects the base should be different\n          # for each, otherwise the write_image command is not able to\n          # distinguish the banks.\n          flash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n          flash bank flash1 ath79 0x10000000 0 0 0 $_TARGETNAME cs1\n          flash bank flash2 ath79 0x20000000 0 0 0 $_TARGETNAME cs2\n\n -- Flash Driver: fespi\n\n     SiFive's Freedom E SPI controller, used in HiFive and other boards.\n\n          flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME\n\n12.5.2 Internal Flash (Microcontrollers)\n----------------------------------------\n\n -- Flash Driver: aduc702x\n     The ADUC702x analog microcontrollers from Analog Devices include\n     internal flash and use ARM7TDMI cores.  The aduc702x flash driver\n     works with models ADUC7019 through ADUC7028.  The setup command\n     only requires the TARGET argument since all devices in this family\n     have the same memory layout.\n\n          flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: ambiqmicro\n     All members of the Apollo microcontroller family from Ambiq Micro\n     include internal flash and use ARM's Cortex-M4 core.  The host\n     connects over USB to an FTDI interface that communicates with the\n     target using SWD.\n\n     The AMBIQMICRO driver reads the Chip Information Register detect\n     the device class of the MCU. The Flash and SRAM sizes directly\n     follow device class, and are used to set up the flash banks.  If\n     this fails, the driver will use default values set to the minimum\n     sizes of an Apollo chip.\n\n     All Apollo chips have two flash banks of the same size.  In all\n     cases the first flash bank starts at location 0, and the second\n     bank starts after the first.\n\n          # Flash bank 0\n          flash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME\n          # Flash bank 1 - same size as bank0, starts after bank 0.\n          flash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 \\\n                     $_TARGETNAME\n\n     Flash is programmed using custom entry points into the bootloader.\n     This is the only way to program the flash as no flash control\n     registers are available to the user.\n\n     The AMBIQMICRO driver adds some additional commands:\n\n      -- Command: ambiqmicro mass_erase <bank>\n          Erase entire bank.\n      -- Command: ambiqmicro page_erase <bank> <first> <last>\n          Erase device pages.\n      -- Command: ambiqmicro program_otp <bank> <offset> <count>\n          Program OTP is a one time operation to create write protected\n          flash.  The user writes sectors to SRAM starting at\n          0x10000010.  Program OTP will write these sectors from SRAM to\n          flash, and write protect the flash.\n\n -- Flash Driver: at91samd\n     All members of the ATSAM D2x, D1x, D0x, ATSAMR, ATSAML and ATSAMC\n     microcontroller families from Atmel include internal flash and use\n     ARM's Cortex-M0+ core.\n\n     Do not use for ATSAM D51 and E5x: use *Note atsame5::.\n\n     The devices have one flash bank:\n\n          flash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n\n      -- Command: at91samd chip-erase\n          Issues a complete Flash erase via the Device Service Unit\n          (DSU). This can be used to erase a chip back to its factory\n          state and does not require the processor to be halted.\n\n      -- Command: at91samd set-security\n          Secures the Flash via the Set Security Bit (SSB) command.\n          This prevents access to the Flash and can only be undone by\n          using the chip-erase command which erases the Flash contents\n          and turns off the security bit.  Warning: at this time,\n          openocd will not be able to communicate with a secured chip\n          and it is therefore not possible to chip-erase it without\n          using another tool.\n\n               at91samd set-security enable\n\n      -- Command: at91samd eeprom\n          Shows or sets the EEPROM emulation size configuration, stored\n          in the User Row of the Flash.  When setting, the EEPROM size\n          must be specified in bytes and it must be one of the permitted\n          sizes according to the datasheet.  Settings are written\n          immediately but only take effect on MCU reset.  EEPROM\n          emulation requires additional firmware support and the minimum\n          EEPROM size may not be the same as the minimum that the\n          hardware supports.  Set the EEPROM size to 0 in order to\n          disable this feature.\n\n               at91samd eeprom\n               at91samd eeprom 1024\n\n      -- Command: at91samd bootloader\n          Shows or sets the bootloader size configuration, stored in the\n          User Row of the Flash.  This is called the BOOTPROT region.\n          When setting, the bootloader size must be specified in bytes\n          and it must be one of the permitted sizes according to the\n          datasheet.  Settings are written immediately but only take\n          effect on MCU reset.  Setting the bootloader size to 0\n          disables bootloader protection.\n\n               at91samd bootloader\n               at91samd bootloader 16384\n\n      -- Command: at91samd dsu_reset_deassert\n          This command releases internal reset held by DSU and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n      -- Command: at91samd nvmuserrow\n          Writes or reads the entire 64 bit wide NVM user row register\n          which is located at 0x804000.  This register includes various\n          fuses lock-bits and factory calibration data.  Reading the\n          register is done by invoking this command without any\n          arguments.  Writing is possible by giving 1 or 2 hex values.\n          The first argument is the register value to be written and the\n          second one is an optional changemask.  Every bit which value\n          in changemask is 0 will stay unchanged.  The lock- and\n          reserved-bits are masked out and cannot be changed.\n\n               # Read user row\n               >at91samd nvmuserrow\n               NVMUSERROW: 0xFFFFFC5DD8E0C788\n               # Write 0xFFFFFC5DD8E0C788 to user row\n               >at91samd nvmuserrow 0xFFFFFC5DD8E0C788\n               # Write 0x12300 to user row but leave other bits and low\n               # byte unchanged\n               >at91samd nvmuserrow 0x12345 0xFFF00\n\n -- Flash Driver: at91sam3\n     All members of the AT91SAM3 microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M3 core.  The driver\n     currently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips.\n     Note that the driver was orginaly developed and tested using the\n     AT91SAM3U4E, using a SAM3U-EK eval board.  Support for other chips\n     in the family was cribbed from the data sheet.  _Note to future\n     readers/updaters: Please remove this worrisome comment after other\n     chips are confirmed._\n\n     The AT91SAM3U4[E/C] (256K) chips have two flash banks; most other\n     chips have one flash bank.  In all cases the flash banks are at the\n     following fixed locations:\n\n          # Flash bank 0 - all chips\n          flash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME\n          # Flash bank 1 - only 256K chips\n          flash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME\n\n     Internally, the AT91SAM3 flash memory is organized as follows.\n     Unlike the AT91SAM7 chips, these are not used as parameters to the\n     'flash bank' command:\n\n        * _N-Banks:_ 256K chips have 2 banks, others have 1 bank.\n        * _Bank Size:_ 128K/64K Per flash bank\n        * _Sectors:_ 16 or 8 per bank\n        * _SectorSize:_ 8K Per Sector\n        * _PageSize:_ 256 bytes per page.  Note that OpenOCD operates on\n          'sector' sizes, not page sizes.\n\n     The AT91SAM3 driver adds some additional commands:\n\n      -- Command: at91sam3 gpnvm\n      -- Command: at91sam3 gpnvm clear number\n      -- Command: at91sam3 gpnvm set number\n      -- Command: at91sam3 gpnvm show [all|number]\n          With no parameters, 'show' or 'show all', shows the status of\n          all GPNVM bits.  With 'show' NUMBER, displays that bit.\n\n          With 'set' NUMBER or 'clear' NUMBER, modifies that GPNVM bit.\n\n      -- Command: at91sam3 info\n          This command attempts to display information about the\n          AT91SAM3 chip.  _First_ it read the 'CHIPID_CIDR' [address\n          0x400e0740, see Section 28.2.1, page 505 of the AT91SAM3U\n          29/may/2009 datasheet, document id: doc6430A] and decodes the\n          values.  _Second_ it reads the various clock configuration\n          registers and attempts to display how it believes the chip is\n          configured.  By default, the SLOWCLK is assumed to be 32768\n          Hz, see the command 'at91sam3 slowclk'.\n\n      -- Command: at91sam3 slowclk [value]\n          This command shows/sets the slow clock frequency used in the\n          'at91sam3 info' command calculations above.\n\n -- Flash Driver: at91sam4\n     All members of the AT91SAM4 microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M4 core.  This driver\n     uses the same command names/syntax as *Note at91sam3::.\n\n -- Flash Driver: at91sam4l\n     All members of the AT91SAM4L microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M4 core.  This driver\n     uses the same command names/syntax as *Note at91sam3::.\n\n     The AT91SAM4L driver adds some additional commands:\n      -- Command: at91sam4l smap_reset_deassert\n          This command releases internal reset held by SMAP and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n -- Flash Driver: atsame5\n     All members of the SAM E54, E53, E51 and D51 microcontroller\n     families from Microchip (former Atmel) include internal flash and\n     use ARM's Cortex-M4 core.\n\n     The devices have two ECC flash banks with a swapping feature.  This\n     driver handles both banks together as it were one.  Bank swapping\n     is not supported yet.\n\n          flash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n\n      -- Command: atsame5 bootloader\n          Shows or sets the bootloader size configuration, stored in the\n          User Page of the Flash.  This is called the BOOTPROT region.\n          When setting, the bootloader size must be specified in bytes.\n          The nearest bigger protection size is used.  Settings are\n          written immediately but only take effect on MCU reset.\n          Setting the bootloader size to 0 disables bootloader\n          protection.\n\n               atsame5 bootloader\n               atsame5 bootloader 16384\n\n      -- Command: atsame5 chip-erase\n          Issues a complete Flash erase via the Device Service Unit\n          (DSU). This can be used to erase a chip back to its factory\n          state and does not require the processor to be halted.\n\n      -- Command: atsame5 dsu_reset_deassert\n          This command releases internal reset held by DSU and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n      -- Command: atsame5 userpage\n          Writes or reads the first 64 bits of NVM User Page which is\n          located at 0x804000.  This field includes various fuses.\n          Reading is done by invoking this command without any\n          arguments.  Writing is possible by giving 1 or 2 hex values.\n          The first argument is the value to be written and the second\n          one is an optional bit mask (a zero bit in the mask means the\n          bit stays unchanged).  The reserved fields are always masked\n          out and cannot be changed.\n\n               # Read\n               >atsame5 userpage\n               USER PAGE: 0xAEECFF80FE9A9239\n               # Write\n               >atsame5 userpage 0xAEECFF80FE9A9239\n               # Write 2 to SEESBLK and 4 to SEEPSZ fields but leave other\n               # bits unchanged (setup SmartEEPROM of virtual size 8192\n               # bytes)\n               >atsame5 userpage 0x4200000000 0x7f00000000\n\n -- Flash Driver: atsamv\n     All members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from\n     Atmel include internal flash and use ARM's Cortex-M7 core.  This\n     driver uses the same command names/syntax as *Note at91sam3::.\n\n          flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n\n      -- Command: atsamv gpnvm [show [all|number]]\n      -- Command: atsamv gpnvm (clr|set) number\n          With no parameters, 'show' or 'show all', shows the status of\n          all GPNVM bits.  With 'show' NUMBER, displays that bit.\n\n          With 'set' NUMBER or 'clear' NUMBER, modifies that GPNVM bit.\n\n -- Flash Driver: at91sam7\n     All members of the AT91SAM7 microcontroller family from Atmel\n     include internal flash and use ARM7TDMI cores.  The driver\n     automatically recognizes a number of these chips using the chip\n     identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME\n\n     For chips which are not recognized by the controller driver, you\n     must provide additional parameters in the following order:\n\n        * CHIP_MODEL ...  label used with 'flash info'\n        * BANKS\n        * SECTORS_PER_BANK\n        * PAGES_PER_SECTOR\n        * PAGES_SIZE\n        * NUM_NVM_BITS\n        * FREQ_KHZ ...  required if an external clock is provided,\n          optional (but recommended) when the oscillator frequency is\n          known\n\n     It is recommended that you provide zeroes for all of those values\n     except the clock frequency, so that everything except that\n     frequency will be autoconfigured.  Knowing the frequency helps\n     ensure correct timings for flash access.\n\n     The flash controller handles erases automatically on a page\n     (128/256 byte) basis, so explicit erase commands are not necessary\n     for flash programming.  However, there is an \"EraseAll\" command\n     that can erase an entire flash plane (of up to 256KB), and it will\n     be used automatically when you issue 'flash erase_sector' or 'flash\n     erase_address' commands.\n\n      -- Command: at91sam7 gpnvm bitnum (set|clear)\n          Set or clear a \"General Purpose Non-Volatile Memory\" (GPNVM)\n          bit for the processor.  Each processor has a number of such\n          bits, used for controlling features such as brownout detection\n          (so they are not truly general purpose).\n               Note: This assumes that the first flash bank (number 0)\n               is associated with the appropriate at91sam7 target.\n\n -- Flash Driver: avr\n     The AVR 8-bit microcontrollers from Atmel integrate flash memory.\n     _The current implementation is incomplete._\n\n -- Flash Driver: bluenrg-x\n     STMicroelectronics BlueNRG-1, BlueNRG-2 and BlueNRG-LP/LPS\n     Bluetooth low energy wireless system-on-chip.  They include ARM\n     Cortex-M0/M0+ core and internal flash memory.  The driver\n     automatically recognizes these chips using the chip identification\n     registers, and autoconfigures itself.\n\n          flash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n     Note that when users ask to erase all the sectors of the flash, a\n     mass erase command is used which is faster than erasing each single\n     sector one by one.\n\n          flash erase_sector 0 0 last # It will perform a mass erase\n\n     Triggering a mass erase is also useful when users want to disable\n     readout protection.\n\n -- Flash Driver: cc26xx\n     All versions of the SimpleLink CC13xx and CC26xx microcontrollers\n     from Texas Instruments include internal flash.  The cc26xx flash\n     driver supports both the CC13xx and CC26xx family of devices.  The\n     driver automatically recognizes the specific version's flash\n     parameters and autoconfigures itself.  The flash bank starts at\n     address 0.\n\n          flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: cc3220sf\n     The CC3220SF version of the SimpleLink CC32xx microcontrollers from\n     Texas Instruments includes 1MB of internal flash.  The cc3220sf\n     flash driver only supports the internal flash.  The serial flash on\n     SimpleLink boards is programmed via the bootloader over a UART\n     connection.  Security features of the CC3220SF may erase the\n     internal flash during power on reset.  Refer to documentation at\n     <www.ti.com/cc3220sf> for details on security features and\n     programming the serial flash.\n\n          flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: efm32\n     All members of the EFM32/EFR32 microcontroller family from Energy\n     Micro (now Silicon Labs) include internal flash and use Arm\n     Cortex-M3 or Cortex-M4 cores.  The driver automatically recognizes\n     a number of these chips using the chip identification register, and\n     autoconfigures itself.\n          flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\n     It supports writing to the user data page, as well as the portion\n     of the lockbits page past 512 bytes on chips with larger page\n     sizes.  The latter is used by the SiLabs bootloader/AppLoader\n     system for encryption keys.  Setting protection on these pages is\n     currently not supported.\n          flash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\n          flash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\n     A special feature of efm32 controllers is that it is possible to\n     completely disable the debug interface by writing the correct\n     values to the 'Debug Lock Word'.  OpenOCD supports this via the\n     following command:\n          efm32 debuglock num\n     The NUM parameter is a value shown by 'flash banks'.  Note that in\n     order for this command to take effect, the target needs to be\n     reset.  _The current implementation is incomplete.  Unprotecting\n     flash pages is not supported._\n\n -- Flash Driver: esirisc\n     Members of the eSi-RISC family may optionally include internal\n     flash programmed via the eSi-TSMC Flash interface.  Additional\n     parameters are required to configure the driver: 'cfg_address' is\n     the base address of the configuration register interface,\n     'clock_hz' is the expected clock frequency, and 'wait_states' is\n     the number of configured read wait states.\n\n          flash bank $_FLASHNAME esirisc base_address size_bytes 0 0 \\\n                     $_TARGETNAME cfg_address clock_hz wait_states\n\n      -- Command: esirisc flash mass_erase bank_id\n          Erase all pages in data memory for the bank identified by\n          'bank_id'.\n\n      -- Command: esirisc flash ref_erase bank_id\n          Erase the reference cell for the bank identified by 'bank_id'.\n          _This is an uncommon operation._\n\n -- Flash Driver: fm3\n     All members of the FM3 microcontroller family from Fujitsu include\n     internal flash and use ARM Cortex-M3 cores.  The FM3 driver uses\n     the TARGET parameter to select the correct bank config, it can\n     currently be one of the following: 'mb9bfxx1.cpu', 'mb9bfxx2.cpu',\n     'mb9bfxx3.cpu', 'mb9bfxx4.cpu', 'mb9bfxx5.cpu' or 'mb9bfxx6.cpu'.\n\n          flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: fm4\n     All members of the FM4 microcontroller family from Spansion\n     (formerly Fujitsu) include internal flash and use ARM Cortex-M4\n     cores.  The FM4 driver uses a FAMILY parameter to select the\n     correct bank config, it can currently be one of the following:\n     'MB9BFx64', 'MB9BFx65', 'MB9BFx66', 'MB9BFx67', 'MB9BFx68',\n     'S6E2Cx8', 'S6E2Cx9', 'S6E2CxA' or 'S6E2Dx', with 'x' treated as\n     wildcard and otherwise case (and any trailing characters) ignored.\n\n          flash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 \\\n                     $_TARGETNAME S6E2CCAJ0A\n          flash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 \\\n                     $_TARGETNAME S6E2CCAJ0A\n     _The current implementation is incomplete.  Protection is not\n     supported, nor is Chip Erase (only Sector Erase is implemented)._\n\n -- Flash Driver: kinetis\n     Kx, KLx, KVx and KE1x members of the Kinetis microcontroller family\n     from NXP (former Freescale) include internal flash and use ARM\n     Cortex-M0+ or M4 cores.  The driver automatically recognizes flash\n     size and a number of flash banks (1-4) using the chip\n     identification register, and autoconfigures itself.  Use kinetis_ke\n     driver for KE0x and KEAx devices.\n\n     The KINETIS driver defines option:\n        * -sim-base ADDR ...  base of System Integration Module where\n          chip identification resides.  Driver tries two known locations\n          if option is omitted.\n\n          flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\n\n      -- Config Command: kinetis create_banks\n          Configuration command enables automatic creation of additional\n          flash banks based on real flash layout of device.  Banks are\n          created during device probe.  Use 'flash probe 0' to force\n          probe.\n\n      -- Command: kinetis fcf_source [protection|write]\n          Select what source is used when writing to a Flash\n          Configuration Field.  'protection' mode builds FCF content\n          from protection bits previously set by 'flash protect'\n          command.  This mode is default.  MCU is protected from\n          unwanted locking by immediate writing FCF after erase of\n          relevant sector.  'write' mode enables direct write to FCF.\n          Protection cannot be set by 'flash protect' command.  FCF is\n          written along with the rest of a flash image.  _BEWARE:\n          Incorrect flash configuration may permanently lock the\n          device!_\n\n      -- Command: kinetis fopt [num]\n          Set value to write to FOPT byte of Flash Configuration Field.\n          Used in kinetis 'fcf_source protection' mode only.\n\n      -- Command: kinetis mdm check_security\n          Checks status of device security lock.  Used internally in\n          examine-end and examine-fail event.\n\n      -- Command: kinetis mdm halt\n          Issues a halt via the MDM-AP. This command can be used to\n          break a watchdog reset loop when connecting to an unsecured\n          target.\n\n      -- Command: kinetis mdm mass_erase\n          Issues a complete flash erase via the MDM-AP. This can be used\n          to erase a chip back to its factory state, removing security.\n          It does not require the processor to be halted, however the\n          target will remain in a halted state after this command\n          completes.\n\n      -- Command: kinetis nvm_partition\n          For FlexNVM devices only (KxxDX and KxxFX). Command shows or\n          sets data flash or EEPROM backup size in kilobytes, sets two\n          EEPROM blocks sizes in bytes and enables/disables loading of\n          EEPROM contents to FlexRAM during reset.\n\n          For details see device reference manual, Flash Memory Module,\n          Program Partition command.\n\n          Setting is possible only once after mass_erase.  Reset the\n          device after partition setting.\n\n          Show partition size:\n               kinetis nvm_partition info\n\n          Set 32 KB data flash, rest of FlexNVM is EEPROM backup.\n          EEPROM has two blocks of 512 and 1536 bytes and its contents\n          is loaded to FlexRAM during reset:\n               kinetis nvm_partition dataflash 32 512 1536 on\n\n          Set 16 KB EEPROM backup, rest of FlexNVM is a data flash.\n          EEPROM has two blocks of 1024 bytes and its contents is not\n          loaded to FlexRAM during reset:\n               kinetis nvm_partition eebkp 16 1024 1024 off\n\n      -- Command: kinetis mdm reset\n          Issues a reset via the MDM-AP. This causes the MCU to output a\n          low pulse on the RESET pin, which can be used to reset other\n          hardware on board.\n\n      -- Command: kinetis disable_wdog\n          For Kx devices only (KLx has different COP watchdog, it is not\n          supported).  Command disables watchdog timer.\n\n -- Flash Driver: kinetis_ke\n     KE0x and KEAx members of the Kinetis microcontroller family from\n     NXP include internal flash and use ARM Cortex-M0+.  The driver\n     automatically recognizes the KE0x sub-family using the chip\n     identification register, and autoconfigures itself.  Use kinetis\n     (not kinetis_ke) driver for KE1x devices.\n\n          flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\n      -- Command: kinetis_ke mdm check_security\n          Checks status of device security lock.  Used internally in\n          examine-end event.\n\n      -- Command: kinetis_ke mdm mass_erase\n          Issues a complete Flash erase via the MDM-AP. This can be used\n          to erase a chip back to its factory state.  Command removes\n          security lock from a device (use of SRST highly recommended).\n          It does not require the processor to be halted.\n\n      -- Command: kinetis_ke disable_wdog\n          Command disables watchdog timer.\n\n -- Flash Driver: lpc2000\n     This is the driver to support internal flash of all members of the\n     LPC11(x)00 and LPC1300 microcontroller families and most members of\n     the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000, LPC54100,\n     LPC8Nxx and NHS31xx microcontroller families from NXP.\n\n          Note: There are LPC2000 devices which are not supported by the\n          LPC2000 driver: The LPC2888 is supported by the LPC288X\n          driver.  The LPC29xx family is supported by the LPC2900\n          driver.\n\n     The LPC2000 driver defines two mandatory and two optional\n     parameters, which must appear in the following order:\n\n        * VARIANT ...  required, may be 'lpc2000_v1' (older LPC21xx and\n          LPC22xx) 'lpc2000_v2' (LPC213x, LPC214x, LPC210[123], LPC23xx\n          and LPC24xx) 'lpc1700' (LPC175x and LPC176x and LPC177x/8x)\n          'lpc4300' - available also as 'lpc1800' alias (LPC18x[2357]\n          and LPC43x[2357]) 'lpc800' (LPC8xx) 'lpc1100' (LPC11(x)xx and\n          LPC13xx) 'lpc1500' (LPC15xx) 'lpc54100' (LPC541xx) 'lpc4000'\n          (LPC40xx) or 'auto' - automatically detects flash variant and\n          size for LPC11(x)00, LPC8xx, LPC13xx, LPC17xx, LPC40xx,\n          LPC8Nxx and NHS31xx\n        * CLOCK_KHZ ...  the frequency, in kiloHertz, at which the core\n          is running\n        * 'calc_checksum' ...  optional (but you probably want to\n          provide this!), telling the driver to calculate a valid\n          checksum for the exception vector table.\n               Note: If you don't provide 'calc_checksum' when you're\n               writing the vector table, the boot ROM will almost\n               certainly ignore your flash image.  However, if you do\n               provide it, with most tool chains 'verify_image' will\n               fail.\n        * 'iap_entry' ...  optional telling the driver to use a\n          different ROM IAP entry point.\n\n     LPC flashes don't require the chip and bus width to be specified.\n\n          flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \\\n                lpc2000_v2 14765 calc_checksum\n\n      -- Command: lpc2000 part_id bank\n          Displays the four byte part identifier associated with the\n          specified flash BANK.\n\n -- Flash Driver: lpc288x\n     The LPC2888 microcontroller from NXP needs slightly different flash\n     support from its lpc2000 siblings.  The LPC288X driver defines one\n     mandatory parameter, the programming clock rate in Hz.  LPC flashes\n     don't require the chip and bus width to be specified.\n\n          flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000\n\n -- Flash Driver: lpc2900\n     This driver supports the LPC29xx ARM968E based microcontroller\n     family from NXP.\n\n     The predefined parameters BASE, SIZE, CHIP_WIDTH and BUS_WIDTH of\n     the 'flash bank' command are ignored.  Flash size and sector layout\n     are auto-configured by the driver.  The driver has one additional\n     mandatory parameter: The CPU clock rate (in kHz) at the time the\n     flash operations will take place.  Most of the time this will not\n     be the crystal frequency, but a higher PLL frequency.  The\n     'reset-init' event handler in the board script is usually the place\n     where you start the PLL.\n\n     The driver rejects flashless devices (currently the LPC2930).\n\n     The EEPROM in LPC2900 devices is not mapped directly into the\n     address space.  It must be handled much more like NAND flash\n     memory, and will therefore be handled by a separate\n     'lpc2900_eeprom' driver (not yet available).\n\n     Sector protection in terms of the LPC2900 is handled transparently.\n     Every time a sector needs to be erased or programmed, it is\n     automatically unprotected.  What is shown as protection status in\n     the 'flash info' command, is actually the LPC2900 _sector\n     security_.  This is a mechanism to prevent a sector from ever being\n     erased or programmed again.  As this is an irreversible mechanism,\n     it is handled by a special command ('lpc2900 secure_sector'), and\n     not by the standard 'flash protect' command.\n\n     Example for a 125 MHz clock frequency:\n          flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000\n\n     Some 'lpc2900'-specific commands are defined.  In the following\n     command list, the BANK parameter is the bank number as obtained by\n     the 'flash banks' command.\n\n      -- Command: lpc2900 signature bank\n          Calculates a 128-bit hash value, the _signature_, from the\n          whole flash content.  This is a hardware feature of the flash\n          block, hence the calculation is very fast.  You may use this\n          to verify the content of a programmed device against a known\n          signature.  Example:\n               lpc2900 signature 0\n                 signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317\n\n      -- Command: lpc2900 read_custom bank filename\n          Reads the 912 bytes of customer information from the flash\n          index sector, and saves it to a file in binary format.\n          Example:\n               lpc2900 read_custom 0 /path_to/customer_info.bin\n\n     The index sector of the flash is a _write-only_ sector.  It cannot\n     be erased!  In order to guard against unintentional write access,\n     all following commands need to be preceded by a successful call to\n     the 'password' command:\n\n      -- Command: lpc2900 password bank password\n          You need to use this command right before each of the\n          following commands: 'lpc2900 write_custom', 'lpc2900\n          secure_sector', 'lpc2900 secure_jtag'.\n\n          The password string is fixed to \"I_know_what_I_am_doing\".\n          Example:\n               lpc2900 password 0 I_know_what_I_am_doing\n                 Potentially dangerous operation allowed in next command!\n\n      -- Command: lpc2900 write_custom bank filename type\n          Writes the content of the file into the customer info space of\n          the flash index sector.  The filetype can be specified with\n          the TYPE field.  Possible values for TYPE are: BIN (binary),\n          IHEX (Intel hex format), ELF (ELF binary) or S19 (Motorola\n          S-records).  The file must contain a single section, and the\n          contained data length must be exactly 912 bytes.\n               Attention: This cannot be reverted!  Be careful!\n          Example:\n               lpc2900 write_custom 0 /path_to/customer_info.bin bin\n\n      -- Command: lpc2900 secure_sector bank first last\n          Secures the sector range from FIRST to LAST (including)\n          against further program and erase operations.  The sector\n          security will be effective after the next power cycle.\n               Attention: This cannot be reverted!  Be careful!\n          Secured sectors appear as _protected_ in the 'flash info'\n          command.  Example:\n               lpc2900 secure_sector 0 1 1\n               flash info 0\n                 #0 : lpc2900 at 0x20000000, size 0x000c0000, (...)\n                         #  0: 0x00000000 (0x2000 8kB) not protected\n                         #  1: 0x00002000 (0x2000 8kB) protected\n                         #  2: 0x00004000 (0x2000 8kB) not protected\n\n      -- Command: lpc2900 secure_jtag bank\n          Irreversibly disable the JTAG port.  The new JTAG security\n          setting will be effective after the next power cycle.\n               Attention: This cannot be reverted!  Be careful!\n          Examples:\n               lpc2900 secure_jtag 0\n\n -- Flash Driver: mdr\n     This drivers handles the integrated NOR flash on Milandr Cortex-M\n     based controllers.  A known limitation is that the Info memory\n     can't be read or verified as it's not memory mapped.\n\n          flash bank <name> mdr <base> <size> \\\n                0 0 <target#> TYPE PAGE_COUNT SEC_COUNT\n\n        * TYPE - 0 for main memory, 1 for info memory\n        * PAGE_COUNT - total number of pages\n        * SEC_COUNT - number of sector per page count\n\n     Example usage:\n          if { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n             flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 \\\n                   0 0 $_TARGETNAME 1 1 4\n          } else {\n             flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 \\\n                   0 0 $_TARGETNAME 0 32 4\n          }\n\n -- Flash Driver: msp432\n     All versions of the SimpleLink MSP432 microcontrollers from Texas\n     Instruments include internal flash.  The msp432 flash driver\n     automatically recognizes the specific version's flash parameters\n     and autoconfigures itself.  Main program flash starts at address 0.\n     The information flash region on MSP432P4 versions starts at address\n     0x200000.\n\n          flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\n      -- Command: msp432 mass_erase bank_id [main|all]\n          Performs a complete erase of flash.  By default, 'mass_erase'\n          will erase only the main program flash.\n\n          On MSP432P4 versions, using 'mass_erase all' will erase both\n          the main program and information flash regions.  To also erase\n          the BSL in information flash, the user must first use the\n          'bsl' command.\n\n      -- Command: msp432 bsl bank_id [unlock|lock]\n          On MSP432P4 versions, 'bsl' unlocks and locks the bootstrap\n          loader (BSL) region in information flash so that flash\n          commands can erase or write the BSL. Leave the BSL locked to\n          prevent accidentally corrupting the bootstrap loader.\n\n          To erase and program the BSL:\n               msp432 bsl unlock\n               flash erase_address 0x202000 0x2000\n               flash write_image bsl.bin 0x202000\n               msp432 bsl lock\n\n -- Flash Driver: niietcm4\n     This drivers handles the integrated NOR flash on NIIET Cortex-M4\n     based controllers.  Flash size and sector layout are\n     auto-configured by the driver.  Main flash memory is called\n     \"Bootflash\" and has main region and info region.  Info region is\n     NOT memory mapped by default, but it can replace first part of main\n     region if needed.  Full erase, single and block writes are\n     supported for both main and info regions.  There is additional not\n     memory mapped flash called \"Userflash\", which also have division\n     into regions: main and info.  Purpose of userflash - to store\n     system and user settings.  Driver has special commands to perform\n     operations with this memory.\n\n          flash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME\n\n     Some niietcm4-specific commands are defined:\n\n      -- Command: niietcm4 uflash_read_byte bank ('main'|'info') address\n          Read byte from main or info userflash region.\n\n      -- Command: niietcm4 uflash_write_byte bank ('main'|'info')\n               address value\n          Write byte to main or info userflash region.\n\n      -- Command: niietcm4 uflash_full_erase bank\n          Erase all userflash including info region.\n\n      -- Command: niietcm4 uflash_erase bank ('main'|'info')\n               first_sector last_sector\n          Erase sectors of main or info userflash region, starting at\n          sector first up to and including last.\n\n      -- Command: niietcm4 uflash_protect_check bank ('main'|'info')\n          Check sectors protect.\n\n      -- Command: niietcm4 uflash_protect bank ('main'|'info')\n               first_sector last_sector ('on'|'off')\n          Protect sectors of main or info userflash region, starting at\n          sector first up to and including last.\n\n      -- Command: niietcm4 bflash_info_remap bank ('on'|'off')\n          Enable remapping bootflash info region to 0x00000000 (or\n          0x40000000 if external memory boot used).\n\n      -- Command: niietcm4 extmem_cfg bank\n               ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh')\n               pin_num ('func1'|'func3')\n          Configure external memory interface for boot.\n\n      -- Command: niietcm4 service_mode_erase bank\n          Perform emergency erase of all flash (bootflash and\n          userflash).\n\n      -- Command: niietcm4 driver_info bank\n          Show information about flash driver.\n\n -- Flash Driver: npcx\n     All versions of the NPCX microcontroller families from Nuvoton\n     include internal flash.  The NPCX flash driver supports the NPCX\n     family of devices.  The driver automatically recognizes the\n     specific version's flash parameters and autoconfigures itself.  The\n     flash bank starts at address 0x64000000.\n\n          flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: nrf5\n     All members of the nRF51 microcontroller families from Nordic\n     Semiconductor include internal flash and use ARM Cortex-M0 core.\n     nRF52 family powered by ARM Cortex-M4 or M4F core is supported too.\n     nRF52832 is fully supported including BPROT flash protection\n     scheme.  nRF52833 and nRF52840 devices are supported with the\n     exception of security extensions (flash access control list - ACL).\n\n          flash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME\n\n     Some nrf5-specific commands are defined:\n\n      -- Command: nrf5 mass_erase\n          Erases the contents of the code memory and user information\n          configuration registers as well.  It must be noted that this\n          command works only for chips that do not have factory\n          pre-programmed region 0 code.\n\n      -- Command: nrf5 info\n          Decodes and shows information from FICR and UICR registers.\n\n -- Flash Driver: ocl\n     This driver is an implementation of the \"on chip flash loader\"\n     protocol proposed by Pavel Chromy.\n\n     It is a minimalistic command-response protocol intended to be used\n     over a DCC when communicating with an internal or external flash\n     loader running from RAM. An example implementation for AT91SAM7x is\n     available in 'contrib/loaders/flash/at91sam7x/'.\n\n          flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: pic32mx\n     The PIC32MX microcontrollers are based on the MIPS 4K cores, and\n     integrate flash memory.\n\n          flash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME\n          flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME\n\n     Some pic32mx-specific commands are defined:\n      -- Command: pic32mx pgm_word address value bank\n          Programs the specified 32-bit VALUE at the given ADDRESS in\n          the specified chip BANK.\n      -- Command: pic32mx unlock bank\n          Unlock and erase specified chip BANK.  This will remove any\n          Code Protection.\n\n -- Flash Driver: psoc4\n     All members of the PSoC 41xx/42xx microcontroller family from\n     Cypress include internal flash and use ARM Cortex-M0 cores.  The\n     driver automatically recognizes a number of these chips using the\n     chip identification register, and autoconfigures itself.\n\n     Note: Erased internal flash reads as 00.  System ROM of PSoC 4 does\n     not implement erase of a flash sector.\n\n          flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\n     psoc4-specific commands\n      -- Command: psoc4 flash_autoerase num (on|off)\n          Enables or disables autoerase mode for a flash bank.\n\n          If flash_autoerase is off, use mass_erase before flash\n          programming.  Flash erase command fails if region to erase is\n          not whole flash memory.\n\n          If flash_autoerase is on, a sector is both erased and\n          programmed in one system ROM call.  Flash erase command is\n          ignored.  This mode is suitable for gdb load.\n\n          The NUM parameter is a value shown by 'flash banks'.\n\n      -- Command: psoc4 mass_erase num\n          Erases the contents of the flash memory, protection and\n          security lock.\n\n          The NUM parameter is a value shown by 'flash banks'.\n\n -- Flash Driver: psoc5lp\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal program flash and use ARM Cortex-M3 cores.  The\n     driver probes for a number of these chips and autoconfigures\n     itself, apart from the base address.\n\n          flash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\n\n     Note: PSoC 5LP chips can be configured to have ECC enabled or\n     disabled.\n          Attention: If flash operations are performed in ECC-disabled\n          mode, they will also affect the ECC flash region.  Erasing a\n          16k flash sector in the 0x00000000 area will then also erase\n          the corresponding 2k data bytes in the 0x48000000 area.\n          Writing to the ECC data bytes in ECC-disabled mode is not\n          implemented.\n\n     Commands defined in the PSOC5LP driver:\n\n      -- Command: psoc5lp mass_erase\n          Erases all flash data and ECC/configuration bytes, all flash\n          protection rows, and all row latches in all flash arrays on\n          the device.\n\n -- Flash Driver: psoc5lp_eeprom\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal EEPROM and use ARM Cortex-M3 cores.  The driver\n     probes for a number of these chips and autoconfigures itself, apart\n     from the base address.\n\n          flash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 \\\n                     $_TARGETNAME\n\n -- Flash Driver: psoc5lp_nvl\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal Nonvolatile Latches and use ARM Cortex-M3 cores.\n     The driver probes for a number of these chips and autoconfigures\n     itself.\n\n          flash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\n     PSoC 5LP chips have multiple NV Latches:\n\n        * Device Configuration NV Latch - 4 bytes\n        * Write Once (WO) NV Latch - 4 bytes\n\n     Note: This driver only implements the Device Configuration NVL.\n\n     The PSOC5LP driver reads the ECC mode from Device Configuration\n     NVL.\n          Attention: Switching ECC mode via write to Device\n          Configuration NVL will require a reset after successful write.\n\n -- Flash Driver: psoc6\n     Supports PSoC6 (CY8C6xxx) family of Cypress microcontrollers.\n     PSoC6 is a dual-core device with CM0+ and CM4 cores.  Both cores\n     share the same Flash/RAM/MMIO address space.\n\n     Flash in PSoC6 is split into three regions:\n        * Main Flash - this is the main storage for user application.\n          Total size varies among devices, sector size: 256 kBytes, row\n          size: 512 bytes.  Supports erase operation on individual rows.\n        * Work Flash - intended to be used as storage for user data\n          (e.g.  EEPROM emulation).  Total size: 32 KBytes, sector size:\n          32 KBytes, row size: 512 bytes.\n        * Supervisory Flash - special region which contains\n          device-specific service data.  This region does not support\n          erase operation.  Only few rows can be programmed by the user,\n          most of the rows are read only.  Programming operation will\n          erase row automatically.\n\n     All three flash regions are supported by the driver.  Flash\n     geometry is detected automatically by parsing data in\n     SPCIF_GEOMETRY register.\n\n     PSoC6 is equipped with NOR Flash so erased Flash reads as 0x00.\n\n          flash bank main_flash_cm0 psoc6 0x10000000 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank work_flash_cm0 psoc6 0x14000000 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_user_cm0 psoc6 0x16000800 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_nar_cm0 psoc6 0x16001A00 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_key_cm0 psoc6 0x16005A00 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_toc2_cm0 psoc6 0x16007C00 0 0 0 \\\n                     ${TARGET}.cm0\n\n          flash bank main_flash_cm4 psoc6 0x10000000 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank work_flash_cm4 psoc6 0x14000000 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_user_cm4 psoc6 0x16000800 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_nar_cm4 psoc6 0x16001A00 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_key_cm4 psoc6 0x16005A00 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_toc2_cm4 psoc6 0x16007C00 0 0 0 \\\n                     ${TARGET}.cm4\n\n     psoc6-specific commands\n      -- Command: psoc6 reset_halt\n          Command can be used to simulate broken Vector Catch from\n          gdbinit or tcl scripts.  When invoked for CM0+ target, it will\n          set break point at application entry point and issue\n          SYSRESETREQ. This will reset both cores and all peripherals.\n          CM0+ will reset CM4 during boot anyway so this is safe.  On\n          CM4 target, VECTRESET is used instead of SYSRESETREQ to avoid\n          unwanted reset of CM0+;\n\n      -- Command: psoc6 mass_erase num\n          Erases the contents given flash bank.  The NUM parameter is a\n          value shown by 'flash banks'.  Note: only Main and Work flash\n          regions support Erase operation.\n\n -- Flash Driver: rp2040\n     Supports RP2040 \"Raspberry Pi Pico\" microcontroller.  RP2040 is a\n     dual-core device with two CM0+ cores.  Both cores share the same\n     Flash/RAM/MMIO address space.  Non-volatile storage is achieved\n     with an external QSPI flash; a Boot ROM provides helper functions.\n\n          flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n\n -- Flash Driver: sim3x\n     All members of the SiM3 microcontroller family from Silicon\n     Laboratories include internal flash and use ARM Cortex-M3 cores.\n     It supports both JTAG and SWD interface.  The SIM3X driver tries to\n     probe the device to auto detect the MCU. If this fails, it will use\n     the SIZE parameter as the size of flash bank.\n\n          flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\n     There are 2 commands defined in the SIM3X driver:\n\n      -- Command: sim3x mass_erase\n          Erases the complete flash.  This is used to unlock the flash.\n          And this command is only possible when using the SWD\n          interface.\n\n      -- Command: sim3x lock\n          Lock the flash.  To unlock use the 'sim3x mass_erase' command.\n\n -- Flash Driver: stellaris\n     All members of the Stellaris LM3Sxxx, LM4x and Tiva C\n     microcontroller families from Texas Instruments include internal\n     flash.  The driver automatically recognizes a number of these chips\n     using the chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME\n\n      -- Command: stellaris recover\n          Performs the _Recovering a \"Locked\" Device_ procedure to\n          restore the flash and its associated nonvolatile registers to\n          their factory default values (erased).  This is the only way\n          to remove flash protection or re-enable debugging if that\n          capability has been disabled.\n\n          Note that the final \"power cycle the chip\" step in this\n          procedure must be performed by hand, since OpenOCD can't do\n          it.\n               Warning: if more than one Stellaris chip is connected,\n               the procedure is applied to all of them.\n\n -- Flash Driver: stm32f1x\n     All members of the STM32F0, STM32F1 and STM32F3 microcontroller\n     families from STMicroelectronics and all members of the GD32F1x0,\n     GD32F3x0 and GD32E23x microcontroller families from GigaDevice\n     include internal flash and use ARM Cortex-M0/M3/M4/M23 cores.  The\n     driver also works with GD32VF103 powered by RISC-V core.  The\n     driver automatically recognizes a number of these chips using the\n     chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME\n\n     If you have a target with dual flash banks then define the second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n\n     Some stm32f1x-specific commands are defined:\n\n      -- Command: stm32f1x lock num\n          Locks the entire stm32 device against reading.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n      -- Command: stm32f1x unlock num\n          Unlocks the entire stm32 device for reading.  This command\n          will cause a mass erase of the entire stm32 device if\n          previously locked.  The NUM parameter is a value shown by\n          'flash banks'.\n\n      -- Command: stm32f1x mass_erase num\n          Mass erases the entire stm32 device.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n      -- Command: stm32f1x options_read num\n          Reads and displays active stm32 option bytes loaded during POR\n          or upon executing the 'stm32f1x options_load' command.  The\n          NUM parameter is a value shown by 'flash banks'.\n\n      -- Command: stm32f1x options_write num (SWWDG|HWWDG)\n               (RSTSTNDBY|NORSTSTNDBY) (RSTSTOP|NORSTSTOP) (USEROPT\n               user_data)\n          Writes the stm32 option byte with the specified values.  The\n          NUM parameter is a value shown by 'flash banks'.  The\n          USER_DATA parameter is content of higher 16 bits of the option\n          byte register (Data0 and Data1 as one 16bit number).\n\n      -- Command: stm32f1x options_load num\n          Generates a special kind of reset to re-load the stm32 option\n          bytes written by the 'stm32f1x options_write' or 'flash\n          protect' commands without having to power cycle the target.\n          Not applicable to stm32f1x devices.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n -- Flash Driver: stm32f2x\n     All members of the STM32F2, STM32F4 and STM32F7 microcontroller\n     families from STMicroelectronics include internal flash and use ARM\n     Cortex-M3/M4/M7 cores.  The driver automatically recognizes a\n     number of these chips using the chip identification register, and\n     autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\n     If you use OTP (One-Time Programmable) memory define it as a second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32f2x 0x1FFF7800 0 0 0 $_TARGETNAME\n\n      -- Command: stm32f2x otp num (enable|disable|show)\n          Enables or disables OTP write commands for bank NUM.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME\n\n     Some stm32f2x-specific commands are defined:\n\n      -- Command: stm32f2x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x mass_erase num\n          Mass erases the entire stm32f2x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32f2x options_read num\n          Reads and displays user options and (where implemented)\n          boot_addr0, boot_addr1, optcr2.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x options_write num user_options boot_addr0\n               boot_addr1\n          Writes user options and (where implemented) boot_addr0 and\n          boot_addr1 in raw format.  Warning: The meaning of the various\n          bits depends on the device, always check datasheet!  The NUM\n          parameter is a value shown by 'flash banks', USER_OPTIONS a 12\n          bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR,\n          BOOT_ADDR0 and BOOT_ADDR1 two halfwords (of FLASH_OPTCR1).\n\n      -- Command: stm32f2x optcr2_write num optcr2\n          Writes FLASH_OPTCR2 options.  Warning: Clearing PCROPi bits\n          requires a full mass erase!  The NUM parameter is a value\n          shown by 'flash banks', OPTCR2 a 32-bit word.\n\n -- Flash Driver: stm32h7x\n     All members of the STM32H7 microcontroller families from\n     STMicroelectronics include internal flash and use ARM Cortex-M7\n     core.  The driver automatically recognizes a number of these chips\n     using the chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32h7x 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32h7x 0 0x20000 0 0 $_TARGETNAME\n\n     Some stm32h7x-specific commands are defined:\n\n      -- Command: stm32h7x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32h7x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32h7x mass_erase num\n          Mass erases the entire stm32h7x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32h7x option_read num reg_offset\n          Reads an option byte register from the stm32h7x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the option byte to read from the used\n          bank registers' base.  For example: in STM32H74x/H75x the bank\n          1 registers' base is 0x52002000 and 0x52002100 for bank 2.\n\n          Example usage:\n               # read OPTSR_CUR\n               stm32h7x option_read 0 0x1c\n               # read WPSN_CUR1R\n               stm32h7x option_read 0 0x38\n               # read WPSN_CUR2R\n               stm32h7x option_read 1 0x38\n\n      -- Command: stm32h7x option_write num reg_offset value [reg_mask]\n          Writes an option byte register of the stm32h7x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the option byte to write from the used\n          bank register base, and REG_MASK is the mask to apply when\n          writing the register (only bits with a '1' will be touched).\n\n          Example usage:\n               # swap bank 1 and bank 2 in dual bank devices\n               # by setting SWAP_BANK_OPT bit in OPTSR_PRG\n               stm32h7x option_write 0 0x20 0x8000000 0x8000000\n\n -- Flash Driver: stm32lx\n     All members of the STM32L0 and STM32L1 microcontroller families\n     from STMicroelectronics include internal flash and use ARM\n     Cortex-M3 and Cortex-M0+ cores.  The driver automatically\n     recognizes a number of these chips using the chip identification\n     register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.  If you\n     use 0 as the bank base address, it tells the driver to autodetect\n     the bank location assuming you're configuring the second bank.\n\n          flash bank $_FLASHNAME stm32lx 0x08000000 0x20000 0 0 $_TARGETNAME\n\n     Some stm32lx-specific commands are defined:\n\n      -- Command: stm32lx lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32lx unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32lx mass_erase num\n          Mass erases the entire stm32lx device (all flash banks and\n          EEPROM data).  This is the only way to unlock a protected\n          flash (unless RDP Level is 2 which can't be unlocked at all).\n          The NUM parameter is a value shown by 'flash banks'.\n\n -- Flash Driver: stm32l4x\n     All members of the STM32 G0, G4, L4, L4+, L5, U5, WB and WL\n     microcontroller families from STMicroelectronics include internal\n     flash and use ARM Cortex-M0+, M4 and M33 cores.  The driver\n     automatically recognizes a number of these chips using the chip\n     identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME\n\n     If you use OTP (One-Time Programmable) memory define it as a second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32l4x 0x1FFF7000 0 0 0 $_TARGETNAME\n\n      -- Command: stm32l4x otp num (enable|disable|show)\n          Enables or disables OTP write commands for bank NUM.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n     However, specifying a wrong value might lead to a completely wrong\n     flash layout, so this feature must be used carefully.\n\n          flash bank $_FLASHNAME stm32l4x 0x08000000 0x40000 0 0 $_TARGETNAME\n\n     Some stm32l4x-specific commands are defined:\n\n      -- Command: stm32l4x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n          _Note:_ To apply the protection change immediately, use\n          'stm32l4x option_load'.\n\n      -- Command: stm32l4x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n          _Note:_ To apply the protection change immediately, use\n          'stm32l4x option_load'.\n\n      -- Command: stm32l4x mass_erase num\n          Mass erases the entire stm32l4x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32l4x option_read num reg_offset\n          Reads an option byte register from the stm32l4x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the Option byte to read.\n\n          For example to read the FLASH_OPTR register:\n               stm32l4x option_read 0 0x20\n               # Option Register (for STM32L4x): <0x40022020> = 0xffeff8aa\n               # Option Register (for STM32WBx): <0x58004020> = ...\n               # The correct flash base address will be used automatically\n\n          The above example will read out the FLASH_OPTR register which\n          contains the RDP option byte, Watchdog configuration, BOR\n          level etc.\n\n      -- Command: stm32l4x option_write num reg_offset reg_mask\n          Write an option byte register of the stm32l4x device.  The NUM\n          parameter is a value shown by 'flash banks', REG_OFFSET is the\n          register offset of the Option byte to write, and REG_MASK is\n          the mask to apply when writing the register (only bits with a\n          '1' will be touched).\n\n          _Note:_ To apply the option bytes change immediately, use\n          'stm32l4x option_load'.\n\n          For example to write the WRP1AR option bytes:\n               stm32l4x option_write 0 0x28 0x00FF0000 0x00FF00FF\n\n          The above example will write the WRP1AR option register\n          configuring the Write protection Area A for bank 1.  The above\n          example set WRP1AR_END=255, WRP1AR_START=0.  This will\n          effectively write protect all sectors in flash bank 1.\n\n      -- Command: stm32l4x wrp_info num [device_bank]\n          List the protected areas using WRP. The NUM parameter is a\n          value shown by 'flash banks'.  DEVICE_BANK parameter is\n          optional, possible values 'bank1' or 'bank2', if not\n          specified, the command will display the whole flash protected\n          areas.\n\n          Note: DEVICE_BANK is different from banks created using 'flash\n          bank'.  Devices supported in this flash driver, can have main\n          flash memory organized in single or dual-banks mode.  Thus the\n          usage of DEVICE_BANK is meaningful only in dual-bank mode, to\n          get write protected areas in a specific DEVICE_BANK\n\n      -- Command: stm32l4x option_load num\n          Forces a re-load of the option byte registers.  Will cause a\n          system reset of the device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32l4x trustzone num [enable | disable]\n          Enables or disables Global TrustZone Security, using the TZEN\n          option bit.  If neither 'enabled' nor 'disable' are specified,\n          the command will display the TrustZone status.  _Note:_ This\n          command works only with devices with TrustZone, eg.  STM32L5.\n          _Note:_ This command will perform an OBL_Launch after\n          modifying the TZEN.\n\n -- Flash Driver: str7x\n     All members of the STR7 microcontroller family from\n     STMicroelectronics include internal flash and use ARM7TDMI cores.\n     The STR7X driver defines one mandatory parameter, VARIANT, which is\n     either 'STR71x', 'STR73x' or 'STR75x'.\n\n          flash bank $_FLASHNAME str7x \\\n                0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\n\n      -- Command: str7x disable_jtag bank\n          Activate the Debug/Readout protection mechanism for the\n          specified flash bank.\n\n -- Flash Driver: str9x\n     Most members of the STR9 microcontroller family from\n     STMicroelectronics include internal flash and use ARM966E cores.\n     The str9 needs the flash controller to be configured using the\n     'str9x flash_config' command prior to Flash programming.\n\n          flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME\n          str9x flash_config 0 4 2 0 0x80000\n\n      -- Command: str9x flash_config num bbsr nbbsr bbadr nbbadr\n          Configures the str9 flash controller.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n             * BBSR - Boot Bank Size register\n             * NBBSR - Non Boot Bank Size register\n             * BBADR - Boot Bank Start Address register\n             * NBBADR - Boot Bank Start Address register\n\n -- Flash Driver: str9xpec\n\n     Only use this driver for locking/unlocking the device or\n     configuring the option bytes.  Use the standard str9 driver for\n     programming.  Before using the flash commands the turbo mode must\n     be enabled using the 'str9xpec enable_turbo' command.\n\n     Here is some background info to help you better understand how this\n     driver works.  OpenOCD has two flash drivers for the str9:\n       1. Standard driver 'str9x' programmed via the str9 core.\n          Normally used for flash programming as it is faster than the\n          'str9xpec' driver.\n       2. Direct programming 'str9xpec' using the flash controller.\n          This is an ISC compliant (IEEE 1532) tap connected in series\n          with the str9 core.  The str9 core does not need to be running\n          to program using this flash driver.  Typical use for this\n          driver is locking/unlocking the target and programming the\n          option bytes.\n\n     Before we run any commands using the 'str9xpec' driver we must\n     first disable the str9 core.  This example assumes the 'str9xpec'\n     driver has been configured for flash bank 0.\n          # assert srst, we do not want core running\n          # while accessing str9xpec flash driver\n          adapter assert srst\n          # turn off target polling\n          poll off\n          # disable str9 core\n          str9xpec enable_turbo 0\n          # read option bytes\n          str9xpec options_read 0\n          # re-enable str9 core\n          str9xpec disable_turbo 0\n          poll on\n          reset halt\n     The above example will read the str9 option bytes.  When performing\n     a unlock remember that you will not be able to halt the str9 - it\n     has been locked.  Halting the core is not required for the\n     'str9xpec' driver as mentioned above, just issue the commands above\n     manually or from a telnet prompt.\n\n     Several str9xpec-specific commands are defined:\n\n      -- Command: str9xpec disable_turbo num\n          Restore the str9 into JTAG chain.\n\n      -- Command: str9xpec enable_turbo num\n          Enable turbo mode, will simply remove the str9 from the chain\n          and talk directly to the embedded flash controller.\n\n      -- Command: str9xpec lock num\n          Lock str9 device.  The str9 will only respond to an unlock\n          command that will erase the device.\n\n      -- Command: str9xpec part_id num\n          Prints the part identifier for bank NUM.\n\n      -- Command: str9xpec options_cmap num (bank0|bank1)\n          Configure str9 boot bank.\n\n      -- Command: str9xpec options_lvdsel num (vdd|vdd_vddq)\n          Configure str9 lvd source.\n\n      -- Command: str9xpec options_lvdthd num (2.4v|2.7v)\n          Configure str9 lvd threshold.\n\n      -- Command: str9xpec options_lvdwarn bank (vdd|vdd_vddq)\n          Configure str9 lvd reset warning source.\n\n      -- Command: str9xpec options_read num\n          Read str9 option bytes.\n\n      -- Command: str9xpec options_write num\n          Write str9 option bytes.\n\n      -- Command: str9xpec unlock num\n          unlock str9 device.\n\n -- Flash Driver: swm050\n     All members of the swm050 microcontroller family from Foshan Synwit\n     Tech.\n\n          flash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\n     One swm050-specific command is defined:\n\n      -- Command: swm050 mass_erase bank_id\n          Erases the entire flash bank.\n\n -- Flash Driver: tms470\n     Most members of the TMS470 microcontroller family from Texas\n     Instruments include internal flash and use ARM7TDMI cores.  This\n     driver doesn't require the chip and bus width to be specified.\n\n     Some tms470-specific commands are defined:\n\n      -- Command: tms470 flash_keyset key0 key1 key2 key3\n          Saves programming keys in a register, to enable flash erase\n          and write commands.\n\n      -- Command: tms470 osc_megahertz clock_mhz\n          Reports the clock speed, which is used to calculate timings.\n\n      -- Command: tms470 plldis (0|1)\n          Disables (1) or enables (0) use of the PLL to speed up the\n          flash clock.\n\n -- Flash Driver: w600\n     W60x series Wi-Fi SoC from WinnerMicro are designed with ARM\n     Cortex-M3 and have 1M Byte QFLASH inside.  The W600 driver uses the\n     TARGET parameter to select the correct bank config.\n\n          flash bank $_FLASHNAME w600 0x08000000 0 0 0 $_TARGETNAMEs\n\n -- Flash Driver: xmc1xxx\n     All members of the XMC1xxx microcontroller family from Infineon.\n     This driver does not require the chip and bus width to be\n     specified.\n\n -- Flash Driver: xmc4xxx\n     All members of the XMC4xxx microcontroller family from Infineon.\n     This driver does not require the chip and bus width to be\n     specified.\n\n     Some xmc4xxx-specific commands are defined:\n\n      -- Command: xmc4xxx flash_password bank_id passwd1 passwd2\n          Saves flash protection passwords which are used to lock the\n          user flash\n\n      -- Command: xmc4xxx flash_unprotect bank_id user_level[0-1]\n          Removes Flash write protection from the selected user bank\n\n12.6 NAND Flash Commands\n========================\n\nCompared to NOR or SPI flash, NAND devices are inexpensive and high\ndensity.  Today's NAND chips, and multi-chip modules, commonly hold\nmultiple GigaBytes of data.\n\nNAND chips consist of a number of \"erase blocks\" of a given size (such\nas 128 KBytes), each of which is divided into a number of pages (of\nperhaps 512 or 2048 bytes each).  Each page of a NAND flash has an \"out\nof band\" (OOB) area to hold Error Correcting Code (ECC) and other\nmetadata, usually 16 bytes of OOB for every 512 bytes of page data.\n\nOne key characteristic of NAND flash is that its error rate is higher\nthan that of NOR flash.  In normal operation, that ECC is used to\ncorrect and detect errors.  However, NAND blocks can also wear out and\nbecome unusable; those blocks are then marked \"bad\".  NAND chips are\neven shipped from the manufacturer with a few bad blocks.  The highest\ndensity chips use a technology (MLC) that wears out more quickly, so ECC\nsupport is increasingly important as a way to detect blocks that have\nbegun to fail, and help to preserve data integrity with techniques such\nas wear leveling.\n\nSoftware is used to manage the ECC. Some controllers don't support ECC\ndirectly; in those cases, software ECC is used.  Other controllers speed\nup the ECC calculations with hardware.  Single-bit error correction\nhardware is routine.  Controllers geared for newer MLC chips may correct\n4 or more errors for every 512 bytes of data.\n\nYou will need to make sure that any data you write using OpenOCD\nincludes the appropriate kind of ECC. For example, that may mean passing\nthe 'oob_softecc' flag when writing NAND data, or ensuring that the\ncorrect hardware ECC mode is used.\n\nThe basic steps for using NAND devices include:\n  1. Declare via the command 'nand device'\n     Do this in a board-specific configuration file, passing parameters\n     as needed by the controller.\n  2. Configure each device using 'nand probe'.\n     Do this only after the associated target is set up, such as in its\n     reset-init script or in procures defined to access that device.\n  3. Operate on the flash via 'nand subcommand'\n     Often commands to manipulate the flash are typed by a human, or run\n     via a script in some automated way.  Common task include writing a\n     boot loader, operating system, or other data needed to initialize\n     or de-brick a board.\n\nNOTE: At the time this text was written, the largest NAND flash fully\nsupported by OpenOCD is 2 GiBytes (16 GiBits).  This is because the\nvariables used to hold offsets and lengths are only 32 bits wide.\n(Larger chips may work in some cases, unless an offset or length is\nlarger than 0xffffffff, the largest 32-bit unsigned integer.)  Some\nlarger devices will work, since they are actually multi-chip modules\nwith two smaller chips and individual chipselect lines.\n\n12.6.1 NAND Configuration Commands\n----------------------------------\n\nNAND chips must be declared in configuration scripts, plus some\nadditional configuration that's done after OpenOCD has initialized.\n\n -- Config Command: nand device name driver target [configparams...]\n     Declares a NAND device, which can be read and written to after it\n     has been configured through 'nand probe'.  In OpenOCD, devices are\n     single chips; this is unlike some operating systems, which may\n     manage multiple chips as if they were a single (larger) device.  In\n     some cases, configuring a device will activate extra commands; see\n     the controller-specific documentation.\n\n     NOTE: This command is not available after OpenOCD initialization\n     has completed.  Use it in board specific configuration files, not\n     interactively.\n\n        * NAME ...  may be used to reference the NAND bank in most other\n          NAND commands.  A number is also available.\n        * DRIVER ...  identifies the NAND controller driver associated\n          with the NAND device being declared.  *Note NAND Driver List:\n          nanddriverlist.\n        * TARGET ...  names the target used when issuing commands to the\n          NAND controller.\n        * CONFIGPARAMS ...  controllers may support, or require,\n          additional parameters.  See the controller-specific\n          documentation for more information.\n\n -- Command: nand list\n     Prints a summary of each device declared using 'nand device',\n     numbered from zero.  Note that un-probed devices show no details.\n          > nand list\n          #0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n                  blocksize: 131072, blocks: 8192\n          #1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n                  blocksize: 131072, blocks: 8192\n          >\n\n -- Command: nand probe num\n     Probes the specified device to determine key characteristics like\n     its page and block sizes, and how many blocks it has.  The NUM\n     parameter is the value shown by 'nand list'.  You must\n     (successfully) probe a device before you can use it with most other\n     NAND commands.\n\n12.6.2 Erasing, Reading, Writing to NAND Flash\n----------------------------------------------\n\n -- Command: nand dump num filename offset length [oob_option]\n     Reads binary data from the NAND device and writes it to the file,\n     starting at the specified offset.  The NUM parameter is the value\n     shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET and LENGTH must be exact multiples of the device's page\n     size.  They describe a data region; the OOB data associated with\n     each such page may also be accessed.\n\n     NOTE: At the time this text was written, no error correction was\n     done on the data that's read, unless raw access was disabled and\n     the underlying NAND controller driver had a 'read_page' method\n     which handled that error correction.\n\n     By default, only page data is saved to the specified file.  Use an\n     OOB_OPTION parameter to save OOB data:\n        * no oob_* parameter\n          Output file holds only page data; OOB is discarded.\n        * 'oob_raw'\n          Output file interleaves page data and OOB data; the file will\n          be longer than \"length\" by the size of the spare areas\n          associated with each data page.  Note that this kind of \"raw\"\n          access is different from what's implied by 'nand raw_access',\n          which just controls whether a hardware-aware access method is\n          used.\n        * 'oob_only'\n          Output file has only raw OOB data, and will be smaller than\n          \"length\" since it will contain only the spare areas associated\n          with each data page.\n\n -- Command: nand erase num [offset length]\n     Erases blocks on the specified NAND device, starting at the\n     specified OFFSET and continuing for LENGTH bytes.  Both of those\n     values must be exact multiples of the device's block size, and the\n     region they specify must fit entirely in the chip.  If those\n     parameters are not specified, the whole NAND chip will be erased.\n     The NUM parameter is the value shown by 'nand list'.\n\n     NOTE: This command will try to erase bad blocks, when told to do\n     so, which will probably invalidate the manufacturer's bad block\n     marker.  For the remainder of the current server session, 'nand\n     info' will still report that the block \"is\" bad.\n\n -- Command: nand write num filename offset [option...]\n     Writes binary data from the file into the specified NAND device,\n     starting at the specified offset.  Those pages should already have\n     been erased; you can't change zero bits to one bits.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET must be an exact multiple of the device's page size.\n     All data in the file will be written, assuming it doesn't run past\n     the end of the device.  Only full pages are written, and any extra\n     space in the last page will be filled with 0xff bytes.  (That\n     includes OOB data, if that's being written.)\n\n     NOTE: At the time this text was written, bad blocks are ignored.\n     That is, this routine will not skip bad blocks, but will instead\n     try to write them.  This can cause problems.\n\n     Provide at most one OPTION parameter.  With some NAND drivers, the\n     meanings of these parameters may change if 'nand raw_access' was\n     used to disable hardware ECC.\n        * no oob_* parameter\n          File has only page data, which is written.  If raw access is\n          in use, the OOB area will not be written.  Otherwise, if the\n          underlying NAND controller driver has a 'write_page' routine,\n          that routine may write the OOB with hardware-computed ECC\n          data.\n        * 'oob_only'\n          File has only raw OOB data, which is written to the OOB area.\n          Each page's data area stays untouched.  This can be a\n          dangerous option, since it can invalidate the ECC data.  You\n          may need to force raw access to use this mode.\n        * 'oob_raw'\n          File interleaves data and OOB data, both of which are written\n          If raw access is enabled, the data is written first, then the\n          un-altered OOB. Otherwise, if the underlying NAND controller\n          driver has a 'write_page' routine, that routine may modify the\n          OOB before it's written, to include hardware-computed ECC\n          data.\n        * 'oob_softecc'\n          File has only page data, which is written.  The OOB area is\n          filled with 0xff, except for a standard 1-bit software ECC\n          code stored in conventional locations.  You might need to\n          force raw access to use this mode, to prevent the underlying\n          driver from applying hardware ECC.\n        * 'oob_softecc_kw'\n          File has only page data, which is written.  The OOB area is\n          filled with 0xff, except for a 4-bit software ECC specific to\n          the boot ROM in Marvell Kirkwood SoCs.  You might need to\n          force raw access to use this mode, to prevent the underlying\n          driver from applying hardware ECC.\n\n -- Command: nand verify num filename offset [option...]\n     Verify the binary data in the file has been programmed to the\n     specified NAND device, starting at the specified offset.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET must be an exact multiple of the device's page size.\n     All data in the file will be read and compared to the contents of\n     the flash, assuming it doesn't run past the end of the device.  As\n     with 'nand write', only full pages are verified, so any extra space\n     in the last page will be filled with 0xff bytes.\n\n     The same OPTIONS accepted by 'nand write', and the file will be\n     processed similarly to produce the buffers that can be compared\n     against the contents produced from 'nand dump'.\n\n     NOTE: This will not work when the underlying NAND controller\n     driver's 'write_page' routine must update the OOB with a\n     hardware-computed ECC before the data is written.  This limitation\n     may be removed in a future release.\n\n12.6.3 Other NAND commands\n--------------------------\n\n -- Command: nand check_bad_blocks num [offset length]\n     Checks for manufacturer bad block markers on the specified NAND\n     device.  If no parameters are provided, checks the whole device;\n     otherwise, starts at the specified OFFSET and continues for LENGTH\n     bytes.  Both of those values must be exact multiples of the\n     device's block size, and the region they specify must fit entirely\n     in the chip.  The NUM parameter is the value shown by 'nand list'.\n\n     NOTE: Before using this command you should force raw access with\n     'nand raw_access enable' to ensure that the underlying driver will\n     not try to apply hardware ECC.\n\n -- Command: nand info num\n     The NUM parameter is the value shown by 'nand list'.  This prints\n     the one-line summary from \"nand list\", plus for devices which have\n     been probed this also prints any known status for each block.\n\n -- Command: nand raw_access num (enable|disable)\n     Sets or clears an flag affecting how page I/O is done.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     This flag is cleared (disabled) by default, but changing that value\n     won't affect all NAND devices.  The key factor is whether the\n     underlying driver provides 'read_page' or 'write_page' methods.  If\n     it doesn't provide those methods, the setting of this flag is\n     irrelevant; all access is effectively \"raw\".\n\n     When those methods exist, they are normally used when reading data\n     ('nand dump' or reading bad block markers) or writing it ('nand\n     write').  However, enabling raw access (setting the flag) prevents\n     use of those methods, bypassing hardware ECC logic.  This can be a\n     dangerous option, since writing blocks with the wrong ECC data can\n     cause them to be marked as bad.\n\n12.6.4 NAND Driver List\n-----------------------\n\nAs noted above, the 'nand device' command allows driver-specific options\nand behaviors.  Some controllers also activate controller-specific\ncommands.\n\n -- NAND Driver: at91sam9\n     This driver handles the NAND controllers found on AT91SAM9 family\n     chips from Atmel.  It takes two extra parameters: address of the\n     NAND chip; address of the ECC controller.\n          nand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800\n     AT91SAM9 chips support single-bit ECC hardware.  The 'write_page'\n     and 'read_page' methods are used to utilize the ECC hardware unless\n     they are disabled by using the 'nand raw_access' command.  There\n     are four additional commands that are needed to fully configure the\n     AT91SAM9 NAND controller.  Two are optional; most boards use the\n     same wiring for ALE/CLE:\n      -- Config Command: at91sam9 cle num addr_line\n          Configure the address line used for latching commands.  The\n          NUM parameter is the value shown by 'nand list'.\n      -- Config Command: at91sam9 ale num addr_line\n          Configure the address line used for latching addresses.  The\n          NUM parameter is the value shown by 'nand list'.\n\n     For the next two commands, it is assumed that the pins have already\n     been properly configured for input or output.\n      -- Config Command: at91sam9 rdy_busy num pio_base_addr pin\n          Configure the RDY/nBUSY input from the NAND device.  The NUM\n          parameter is the value shown by 'nand list'.  PIO_BASE_ADDR is\n          the base address of the PIO controller and PIN is the pin\n          number.\n      -- Config Command: at91sam9 ce num pio_base_addr pin\n          Configure the chip enable input to the NAND device.  The NUM\n          parameter is the value shown by 'nand list'.  PIO_BASE_ADDR is\n          the base address of the PIO controller and PIN is the pin\n          number.\n\n -- NAND Driver: davinci\n     This driver handles the NAND controllers found on DaVinci family\n     chips from Texas Instruments.  It takes three extra parameters:\n     address of the NAND chip; hardware ECC mode to use ('hwecc1',\n     'hwecc4', 'hwecc4_infix'); address of the AEMIF controller on this\n     processor.\n          nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000\n     All DaVinci processors support the single-bit ECC hardware, and\n     newer ones also support the four-bit ECC hardware.  The\n     'write_page' and 'read_page' methods are used to implement those\n     ECC modes, unless they are disabled using the 'nand raw_access'\n     command.\n\n -- NAND Driver: lpc3180\n     These controllers require an extra 'nand device' parameter: the\n     clock rate used by the controller.\n      -- Command: lpc3180 select num [mlc|slc]\n          Configures use of the MLC or SLC controller mode.  MLC implies\n          use of hardware ECC. The NUM parameter is the value shown by\n          'nand list'.\n\n     At this writing, this driver includes 'write_page' and 'read_page'\n     methods.  Using 'nand raw_access' to disable those methods will\n     prevent use of hardware ECC in the MLC controller mode, but won't\n     change SLC behavior.\n\n -- NAND Driver: mx3\n     This driver handles the NAND controller in i.MX31.  The mxc driver\n     should work for this chip as well.\n\n -- NAND Driver: mxc\n     This driver handles the NAND controller found in Freescale i.MX\n     chips.  It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35).\n     The driver takes 3 extra arguments, chip ('mx27', 'mx31', 'mx35'),\n     ecc ('noecc', 'hwecc') and optionally if bad block information\n     should be swapped between main area and spare area ('biswap'),\n     defaults to off.\n          nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap\n      -- Command: mxc biswap bank_num [enable|disable]\n          Turns on/off bad block information swapping from main area,\n          without parameter query status.\n\n -- NAND Driver: orion\n     These controllers require an extra 'nand device' parameter: the\n     address of the controller.\n          nand device orion 0xd8000000\n     These controllers don't define any specialized commands.  At this\n     writing, their drivers don't include 'write_page' or 'read_page'\n     methods, so 'nand raw_access' won't change any behavior.\n\n -- NAND Driver: s3c2410\n -- NAND Driver: s3c2412\n -- NAND Driver: s3c2440\n -- NAND Driver: s3c2443\n -- NAND Driver: s3c6400\n     These S3C family controllers don't have any special 'nand device'\n     options, and don't define any specialized commands.  At this\n     writing, their drivers don't include 'write_page' or 'read_page'\n     methods, so 'nand raw_access' won't change any behavior.\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/info/openocd.info-2",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nFile: openocd.info,  Node: Flash Programming,  Next: PLD/FPGA Commands,  Prev: Flash Commands,  Up: Top\n\n13 Flash Programming\n********************\n\nOpenOCD implements numerous ways to program the target flash, whether\ninternal or external.  Programming can be achieved by either using *note\nProgramming using GDB: programmingusinggdb, or using the commands given\nin *note Flash Programming Commands: flashprogrammingcommands.\n\n\nTo simplify using the flash commands directly a jimtcl script is\navailable that handles the programming and verify stage.  OpenOCD will\nprogram/verify/reset the target and optionally shutdown.\n\nThe script is executed as follows and by default the following actions\nwill be performed.\n  1. 'init' is executed.\n  2. 'reset init' is called to reset and halt the target, any 'reset\n     init' scripts are executed.\n  3. 'flash write_image' is called to erase and write any flash using\n     the filename given.\n  4. If the 'preverify' parameter is given, the target is \"verified\"\n     first and only flashed if this fails.\n  5. 'verify_image' is called if 'verify' parameter is given.\n  6. 'reset run' is called if 'reset' parameter is given.\n  7. OpenOCD is shutdown if 'exit' parameter is given.\n\nAn example of usage is given below.  *Note program::.\n\n     # program and verify using elf/hex/s19. verify and reset\n     # are optional parameters\n     openocd -f board/stm32f3discovery.cfg \\\n     \t-c \"program filename.elf verify reset exit\"\n\n     # binary files need the flash address passing\n     openocd -f board/stm32f3discovery.cfg \\\n     \t-c \"program filename.bin exit 0x08000000\"\n\n\u001f\nFile: openocd.info,  Node: PLD/FPGA Commands,  Next: General Commands,  Prev: Flash Programming,  Up: Top\n\n14 PLD/FPGA Commands\n********************\n\nProgrammable Logic Devices (PLDs) and the more flexible Field\nProgrammable Gate Arrays (FPGAs) are both types of programmable\nhardware.  OpenOCD can support programming them.  Although PLDs are\ngenerally restrictive (cells are less functional, and there are no\nspecial purpose cells for memory or computational tasks), they share the\nsame OpenOCD infrastructure.  Accordingly, both are called PLDs here.\n\n14.1 PLD/FPGA Configuration and Commands\n========================================\n\nAs it does for JTAG TAPs, debug targets, and flash chips (both NOR and\nNAND), OpenOCD maintains a list of PLDs available for use in various\ncommands.  Also, each such PLD requires a driver.\n\nThey are referenced by the number shown by the 'pld devices' command,\nand new PLDs are defined by 'pld device driver_name'.\n\n -- Config Command: pld device driver_name tap_name [driver_options]\n     Defines a new PLD device, supported by driver DRIVER_NAME, using\n     the TAP named TAP_NAME.  The driver may make use of any\n     DRIVER_OPTIONS to configure its behavior.\n\n -- Command: pld devices\n     Lists the PLDs and their numbers.\n\n -- Command: pld load num filename\n     Loads the file 'filename' into the PLD identified by NUM.  The file\n     format must be inferred by the driver.\n\n14.2 PLD/FPGA Drivers, Options, and Commands\n============================================\n\nDrivers may support PLD-specific options to the 'pld device' definition\ncommand, and may also define commands usable only with that particular\ntype of PLD.\n\n -- FPGA Driver: virtex2 [no_jstart]\n     Virtex-II is a family of FPGAs sold by Xilinx.  It supports the\n     IEEE 1532 standard for In-System Configuration (ISC).\n\n     If NO_JSTART is non-zero, the JSTART instruction is not used after\n     loading the bitstream.  While required for Series2, Series3, and\n     Series6, it breaks bitstream loading on Series7.\n\n      -- Command: virtex2 read_stat num\n          Reads and displays the Virtex-II status register (STAT) for\n          FPGA NUM.\n\n\u001f\nFile: openocd.info,  Node: General Commands,  Next: Architecture and Core Commands,  Prev: PLD/FPGA Commands,  Up: Top\n\n15 General Commands\n*******************\n\nThe commands documented in this chapter here are common commands that\nyou, as a human, may want to type and see the output of.  Configuration\ntype commands are documented elsewhere.\n\nIntent:\n   * Source Of Commands\n     OpenOCD commands can occur in a configuration script (discussed\n     elsewhere) or typed manually by a human or supplied\n     programmatically, or via one of several TCP/IP Ports.\n\n   * From the human\n     A human should interact with the telnet interface (default port:\n     4444) or via GDB (default port 3333).\n\n     To issue commands from within a GDB session, use the 'monitor'\n     command, e.g.  use 'monitor poll' to issue the 'poll' command.  All\n     output is relayed through the GDB session.\n\n   * Machine Interface The Tcl interface's intent is to be a machine\n     interface.  The default Tcl port is 5555.\n\n15.1 Server Commands\n====================\n\n -- Command: exit\n     Exits the current telnet session.\n\n -- Command: help [string]\n     With no parameters, prints help text for all commands.  Otherwise,\n     prints each helptext containing STRING.  Not every command provides\n     helptext.\n\n     Configuration commands, and commands valid at any time, are\n     explicitly noted in parenthesis.  In most cases, no such\n     restriction is listed; this indicates commands which are only\n     available after the configuration stage has completed.\n\n -- Command: usage [string]\n     With no parameters, prints usage text for all commands.  Otherwise,\n     prints all usage text of which command, help text, and usage text\n     containing STRING.  Not every command provides helptext.\n\n -- Command: sleep msec [busy]\n     Wait for at least MSEC milliseconds before resuming.  If 'busy' is\n     passed, busy-wait instead of sleeping.  (This option is strongly\n     discouraged.)  Useful in connection with script files ('script'\n     command and 'target_name' configuration).\n\n -- Command: shutdown [error]\n     Close the OpenOCD server, disconnecting all clients (GDB, telnet,\n     other).  If option 'error' is used, OpenOCD will return a non-zero\n     exit code to the parent process.\n\n     If user types CTRL-C or kills OpenOCD, the command 'shutdown' will\n     be automatically executed to cause OpenOCD to exit.\n\n     It is possible to specify, in the TCL list PRE_SHUTDOWN_COMMANDS ,\n     a set of commands to be automatically executed before 'shutdown' ,\n     e.g.:\n          lappend pre_shutdown_commands {echo \"Goodbye, my friend ...\"}\n          lappend pre_shutdown_commands {echo \"see you soon !\"}\n     The commands in the list will be executed (in the same order they\n     occupy in the list) before OpenOCD exits.  If one of the commands\n     in the list fails, then the remaining commands are not executed\n     anymore while OpenOCD will proceed to quit.\n\n -- Command: debug_level [n]\n     Display debug level.  If N (from 0..4) is provided, then set it to\n     that level.  This affects the kind of messages sent to the server\n     log.  Level 0 is error messages only; level 1 adds warnings; level\n     2 adds informational messages; level 3 adds debugging messages; and\n     level 4 adds verbose low-level debug messages.  The default is\n     level 2, but that can be overridden on the command line along with\n     the location of that log file (which is normally the server's\n     standard output).  *Note Running::.\n\n -- Command: echo [-n] message\n     Logs a message at \"user\" priority.  Option \"-n\" suppresses trailing\n     newline.\n          echo \"Downloading kernel -- please wait\"\n\n -- Command: log_output [filename | \"default\"]\n     Redirect logging to FILENAME or set it back to default output; the\n     default log output channel is stderr.\n\n -- Command: add_script_search_dir [directory]\n     Add DIRECTORY to the file/script search path.\n\n -- Config Command: bindto [NAME]\n     Specify hostname or IPv4 address on which to listen for incoming\n     TCP/IP connections.  By default, OpenOCD will listen on the\n     loopback interface only.  If your network environment is safe,\n     'bindto 0.0.0.0' can be used to cover all available interfaces.\n\n15.2 Target State handling\n==========================\n\nIn this section \"target\" refers to a CPU configured as shown earlier\n(*note CPU Configuration::).  These commands, like many, implicitly\nrefer to a current target which is used to perform the various\noperations.  The current target may be changed by using 'targets'\ncommand with the name of the target which should become current.\n\n -- Command: reg [(number|name) [(value|'force')]]\n     Access a single register by NUMBER or by its NAME.  The target must\n     generally be halted before access to CPU core registers is allowed.\n     Depending on the hardware, some other registers may be accessible\n     while the target is running.\n\n     _With no arguments_: list all available registers for the current\n     target, showing number, name, size, value, and cache status.  For\n     valid entries, a value is shown; valid entries which are also dirty\n     (and will be written back later) are flagged as such.\n\n     _With number/name_: display that register's value.  Use FORCE\n     argument to read directly from the target, bypassing any internal\n     cache.\n\n     _With both number/name and value_: set register's value.  Writes\n     may be held in a writeback cache internal to OpenOCD, so that\n     setting the value marks the register as dirty instead of\n     immediately flushing that value.  Resuming CPU execution (including\n     by single stepping) or otherwise activating the relevant module\n     will flush such values.\n\n     Cores may have surprisingly many registers in their Debug and trace\n     infrastructure:\n\n          > reg\n          ===== ARM registers\n          (0) r0 (/32): 0x0000D3C2 (dirty)\n          (1) r1 (/32): 0xFD61F31C\n          (2) r2 (/32)\n          ...\n          (164) ETM_contextid_comparator_mask (/32)\n          >\n\n -- Command: set_reg dict\n     Set register values of the target.\n\n        * DICT ...  Tcl dictionary with pairs of register names and\n          values.\n\n     For example, the following command sets the value 0 to the program\n     counter (pc) register and 0x1000 to the stack pointer (sp)\n     register:\n\n          set_reg {pc 0 sp 0x1000}\n\n -- Command: get_reg [-force] list\n     Get register values from the target and return them as Tcl\n     dictionary with pairs of register names and values.  If option\n     \"-force\" is set, the register values are read directly from the\n     target, bypassing any caching.\n\n        * LIST ...  List of register names\n\n     For example, the following command retrieves the values from the\n     program counter (pc) and stack pointer (sp) register:\n\n          get_reg {pc sp}\n\n -- Command: write_memory address width data ['phys']\n     This function provides an efficient way to write to the target\n     memory from a Tcl script.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * DATA ...  Tcl list with the elements to write\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command writes two 32 bit words into the\n     target memory at address 0x20000000:\n\n          write_memory 0x20000000 32 {0xdeadbeef 0x00230500}\n\n -- Command: read_memory address width count ['phys']\n     This function provides an efficient way to read the target memory\n     from a Tcl script.  A Tcl list containing the requested memory\n     elements is returned by this function.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * COUNT ...  number of elements to read\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command reads two 32 bit words from the\n     target memory at address 0x20000000:\n\n          read_memory 0x20000000 32 2\n\n -- Command: halt [ms]\n -- Command: wait_halt [ms]\n     The 'halt' command first sends a halt request to the target, which\n     'wait_halt' doesn't.  Otherwise these behave the same: wait up to\n     MS milliseconds, or 5 seconds if there is no parameter, for the\n     target to halt (and enter debug mode).  Using 0 as the MS parameter\n     prevents OpenOCD from waiting.\n\n          Warning: On ARM cores, software using the _wait for interrupt_\n          operation often blocks the JTAG access needed by a 'halt'\n          command.  This is because that operation also puts the core\n          into a low power mode by gating the core clock; but the core\n          clock is needed to detect JTAG clock transitions.\n\n          One partial workaround uses adaptive clocking: when the core\n          is interrupted the operation completes, then JTAG clocks are\n          accepted at least until the interrupt handler completes.\n          However, this workaround is often unusable since the\n          processor, board, and JTAG adapter must all support adaptive\n          JTAG clocking.  Also, it can't work until an interrupt is\n          issued.\n\n          A more complete workaround is to not use that operation while\n          you work with a JTAG debugger.  Tasking environments generally\n          have idle loops where the body is the _wait for interrupt_\n          operation.  (On older cores, it is a coprocessor action; newer\n          cores have a 'wfi' instruction.)  Such loops can just remove\n          that operation, at the cost of higher power consumption\n          (because the CPU is needlessly clocked).\n\n -- Command: resume [address]\n     Resume the target at its current code position, or the optional\n     ADDRESS if it is provided.  OpenOCD will wait 5 seconds for the\n     target to resume.\n\n -- Command: step [address]\n     Single-step the target at its current code position, or the\n     optional ADDRESS if it is provided.\n\n -- Command: reset\n -- Command: reset run\n -- Command: reset halt\n -- Command: reset init\n     Perform as hard a reset as possible, using SRST if possible.  _All\n     defined targets will be reset, and target events will fire during\n     the reset sequence._\n\n     The optional parameter specifies what should happen after the\n     reset.  If there is no parameter, a 'reset run' is executed.  The\n     other options will not work on all systems.  *Note Reset\n     Configuration::.\n\n        - run Let the target run\n        - halt Immediately halt the target\n        - init Immediately halt the target, and execute the reset-init\n          script\n\n -- Command: soft_reset_halt\n     Requesting target halt and executing a soft reset.  This is often\n     used when a target cannot be reset and halted.  The target, after\n     reset is released begins to execute code.  OpenOCD attempts to stop\n     the CPU and then sets the program counter back to the reset vector.\n     Unfortunately the code that was executed may have left the hardware\n     in an unknown state.\n\n -- Command: adapter assert [signal [assert|deassert signal]]\n -- Command: adapter deassert [signal [assert|deassert signal]]\n     Set values of reset signals.  Without parameters returns current\n     status of the signals.  The SIGNAL parameter values may be 'srst',\n     indicating that srst signal is to be asserted or deasserted,\n     'trst', indicating that trst signal is to be asserted or\n     deasserted.\n\n     The 'reset_config' command should already have been used to\n     configure how the board and the adapter treat these two signals,\n     and to say if either signal is even present.  *Note Reset\n     Configuration::.  Trying to assert a signal that is not present\n     triggers an error.  If a signal is present on the adapter and not\n     specified in the command, the signal will not be modified.\n\n          Note: TRST is specially handled.  It actually signifies JTAG's\n          RESET state.  So if the board doesn't support the optional\n          TRST signal, or it doesn't support it along with the specified\n          SRST value, JTAG reset is triggered with TMS and TCK signals\n          instead of the TRST signal.  And no matter how that JTAG reset\n          is triggered, once the scan chain enters RESET with TRST\n          inactive, TAP 'post-reset' events are delivered to all TAPs\n          with handlers for that event.\n\n15.3 Memory access commands\n===========================\n\nThese commands allow accesses of a specific size to the memory system.\nOften these are used to configure the current target in some special\nway.  For example - one may need to write certain values to the SDRAM\ncontroller to enable SDRAM.\n\n  1. Use the 'targets' (plural) command to change the current target.\n  2. In system level scripts these commands are deprecated.  Please use\n     their TARGET object siblings to avoid making assumptions about what\n     TAP is the current target, or about MMU configuration.\n\n -- Command: mdd [phys] addr [count]\n -- Command: mdw [phys] addr [count]\n -- Command: mdh [phys] addr [count]\n -- Command: mdb [phys] addr [count]\n     Display contents of address ADDR, as 64-bit doublewords ('mdd'),\n     32-bit words ('mdw'), 16-bit halfwords ('mdh'), or 8-bit bytes\n     ('mdb').  When the current target has an MMU which is present and\n     active, ADDR is interpreted as a virtual address.  Otherwise, or if\n     the optional PHYS flag is specified, ADDR is interpreted as a\n     physical address.  If COUNT is specified, displays that many units.\n     (If you want to process the data instead of displaying it, see the\n     'read_memory' primitives.)\n\n -- Command: mwd [phys] addr doubleword [count]\n -- Command: mww [phys] addr word [count]\n -- Command: mwh [phys] addr halfword [count]\n -- Command: mwb [phys] addr byte [count]\n     Writes the specified DOUBLEWORD (64 bits), WORD (32 bits), HALFWORD\n     (16 bits), or BYTE (8-bit) value, at the specified address ADDR.\n     When the current target has an MMU which is present and active,\n     ADDR is interpreted as a virtual address.  Otherwise, or if the\n     optional PHYS flag is specified, ADDR is interpreted as a physical\n     address.  If COUNT is specified, fills that many units of\n     consecutive address.\n\n15.4 Image loading commands\n===========================\n\n -- Command: dump_image filename address size\n     Dump SIZE bytes of target memory starting at ADDRESS to the binary\n     file named FILENAME.\n\n -- Command: fast_load\n     Loads an image stored in memory by 'fast_load_image' to the current\n     target.  Must be preceded by fast_load_image.\n\n -- Command: fast_load_image filename address [bin|ihex|elf|s19]\n     Normally you should be using 'load_image' or GDB load.  However,\n     for testing purposes or when I/O overhead is significant(OpenOCD\n     running on an embedded host), storing the image in memory and\n     uploading the image to the target can be a way to upload e.g.\n     multiple debug sessions when the binary does not change.  Arguments\n     are the same as 'load_image', but the image is stored in OpenOCD\n     host memory, i.e.  does not affect target.  This approach is also\n     useful when profiling target programming performance as I/O and\n     target programming can easily be profiled separately.\n\n -- Command: load_image filename address [[bin|ihex|elf|s19] min_addr\n          max_length]\n     Load image from file FILENAME to target memory offset by ADDRESS\n     from its load address.  The file format may optionally be specified\n     ('bin', 'ihex', 'elf', or 's19').  In addition the following\n     arguments may be specified: MIN_ADDR - ignore data below MIN_ADDR\n     (this is w.r.t.  to the target's load address + ADDRESS) MAX_LENGTH\n     - maximum number of bytes to load.\n          proc load_image_bin {fname foffset address length } {\n              # Load data from fname filename at foffset offset to\n              # target at address. Load at most length bytes.\n              load_image $fname [expr {$address - $foffset}] bin \\\n                         $address $length\n          }\n\n -- Command: test_image filename [address [bin|ihex|elf]]\n     Displays image section sizes and addresses as if FILENAME were\n     loaded into target memory starting at ADDRESS (defaults to zero).\n     The file format may optionally be specified ('bin', 'ihex', or\n     'elf')\n\n -- Command: verify_image filename address [bin|ihex|elf]\n     Verify FILENAME against target memory starting at ADDRESS.  The\n     file format may optionally be specified ('bin', 'ihex', or 'elf')\n     This will first attempt a comparison using a CRC checksum, if this\n     fails it will try a binary compare.\n\n -- Command: verify_image_checksum filename address [bin|ihex|elf]\n     Verify FILENAME against target memory starting at ADDRESS.  The\n     file format may optionally be specified ('bin', 'ihex', or 'elf')\n     This perform a comparison using a CRC checksum only\n\n15.5 Breakpoint and Watchpoint commands\n=======================================\n\nCPUs often make debug modules accessible through JTAG, with hardware\nsupport for a handful of code breakpoints and data watchpoints.  In\naddition, CPUs almost always support software breakpoints.\n\n -- Command: bp [address len [hw]]\n     With no parameters, lists all active breakpoints.  Else sets a\n     breakpoint on code execution starting at ADDRESS for LENGTH bytes.\n     This is a software breakpoint, unless 'hw' is specified in which\n     case it will be a hardware breakpoint.\n\n     (*Note arm9 vector_catch: arm9vectorcatch, or *note xscale\n     vector_catch: xscalevectorcatch, for similar mechanisms that do not\n     consume hardware breakpoints.)\n\n -- Command: rbp all | address\n     Remove the breakpoint at ADDRESS or all breakpoints.\n\n -- Command: rwp address\n     Remove data watchpoint on ADDRESS\n\n -- Command: wp [address len [(r|w|a) [value [mask]]]]\n     With no parameters, lists all active watchpoints.  Else sets a data\n     watchpoint on data from ADDRESS for LENGTH bytes.  The watch point\n     is an \"access\" watchpoint unless the 'r' or 'w' parameter is\n     provided, defining it as respectively a read or write watchpoint.\n     If a VALUE is provided, that value is used when determining if the\n     watchpoint should trigger.  The value may be first be masked using\n     MASK to mark \"don't care\" fields.\n\n15.6 Real Time Transfer (RTT)\n=============================\n\nReal Time Transfer (RTT) is an interface specified by SEGGER based on\nbasic memory reads and writes to transfer data bidirectionally between\ntarget and host.  The specification is independent of the target\narchitecture.  Every target that supports so called \"background memory\naccess\", which means that the target memory can be accessed by the\ndebugger while the target is running, can be used.  This interface is\nespecially of interest for targets without Serial Wire Output (SWO),\nsuch as ARM Cortex-M0, or where semihosting is not applicable because of\nreal-time constraints.\n\n     Note: The current implementation supports only single target\n     devices.\n\nThe data transfer between host and target device is organized through\nunidirectional up/down-channels for target-to-host and host-to-target\ncommunication, respectively.\n\n     Note: The current implementation does not respect channel buffer\n     flags.  They are used to determine what happens when writing to a\n     full buffer, for example.\n\nChannels are exposed via raw TCP/IP connections.  One or more RTT\nservers can be assigned to each channel to make them accessible to an\nunlimited number of TCP/IP connections.\n\n -- Command: rtt setup address size ID\n     Configure RTT for the currently selected target.  Once RTT is\n     started, OpenOCD searches for a control block with the identifier\n     ID starting at the memory address ADDRESS within the next SIZE\n     bytes.\n\n -- Command: rtt start\n     Start RTT. If the control block location is not known, OpenOCD\n     starts searching for it.\n\n -- Command: rtt stop\n     Stop RTT.\n\n -- Command: rtt polling_interval [interval]\n     Display the polling interval.  If INTERVAL is provided, set the\n     polling interval.  The polling interval determines (in\n     milliseconds) how often the up-channels are checked for new data.\n\n -- Command: rtt channels\n     Display a list of all channels and their properties.\n\n -- Command: rtt channellist\n     Return a list of all channels and their properties as Tcl list.\n     The list can be manipulated easily from within scripts.\n\n -- Command: rtt server start port channel\n     Start a TCP server on PORT for the channel CHANNEL.\n\n -- Command: rtt server stop port\n     Stop the TCP sever with port PORT.\n\nThe following example shows how to setup RTT using the SEGGER RTT\nimplementation on the target device.\n\n     resume\n\n     rtt setup 0x20000000 2048 \"SEGGER RTT\"\n     rtt start\n\n     rtt server start 9090 0\n\nIn this example, OpenOCD searches the control block with the ID \"SEGGER\nRTT\" starting at 0x20000000 for 2048 bytes.  The RTT channel 0 is\nexposed through the TCP/IP port 9090.\n\n15.7 Misc Commands\n==================\n\n -- Command: profile seconds filename [start end]\n     Profiling samples the CPU's program counter as quickly as possible,\n     which is useful for non-intrusive stochastic profiling.  Saves up\n     to 10000 samples in 'filename' using \"gmon.out\" format.  Optional\n     'start' and 'end' parameters allow to limit the address range.\n\n -- Command: version\n     Displays a string identifying the version of this OpenOCD server.\n\n -- Command: virt2phys virtual_address\n     Requests the current target to map the specified VIRTUAL_ADDRESS to\n     its corresponding physical address, and displays the result.\n\n -- Command: add_help_text 'command_name' 'help-string'\n     Add or replace help text on the given COMMAND_NAME.\n\n -- Command: add_usage_text 'command_name' 'help-string'\n     Add or replace usage text on the given COMMAND_NAME.\n\n\u001f\nFile: openocd.info,  Node: Architecture and Core Commands,  Next: JTAG Commands,  Prev: General Commands,  Up: Top\n\n16 Architecture and Core Commands\n*********************************\n\nMost CPUs have specialized JTAG operations to support debugging.\nOpenOCD packages most such operations in its standard command framework.\nSome of those operations don't fit well in that framework, so they are\nexposed here as architecture or implementation (core) specific commands.\n\n16.1 ARM Hardware Tracing\n=========================\n\nCPUs based on ARM cores may include standard tracing interfaces, based\non an \"Embedded Trace Module\" (ETM) which sends voluminous address and\ndata bus trace records to a \"Trace Port\".\n\n   * Development-oriented boards will sometimes provide a high speed\n     trace connector for collecting that data, when the particular CPU\n     supports such an interface.  (The standard connector is a 38-pin\n     Mictor, with both JTAG and trace port support.)  Those trace\n     connectors are supported by higher end JTAG adapters and some logic\n     analyzer modules; frequently those modules can buffer several\n     megabytes of trace data.  Configuring an ETM coupled to such an\n     external trace port belongs in the board-specific configuration\n     file.\n   * If the CPU doesn't provide an external interface, it probably has\n     an \"Embedded Trace Buffer\" (ETB) on the chip, which is a dedicated\n     SRAM. 4KBytes is one common ETB size.  Configuring an ETM coupled\n     only to an ETB belongs in the CPU-specific (target) configuration\n     file, since it works the same on all boards.\n\nETM support in OpenOCD doesn't seem to be widely used yet.\n\n     Issues: ETM support may be buggy, and at least some 'etm config'\n     parameters should be detected by asking the ETM for them.\n\n     ETM trigger events could also implement a kind of complex hardware\n     breakpoint, much more powerful than the simple watchpoint hardware\n     exported by EmbeddedICE modules.  _Such breakpoints can be\n     triggered even when using the dummy trace port driver_.\n\n     It seems like a GDB hookup should be possible, as well as tracing\n     only during specific states (perhaps _handling IRQ 23_ or _calls\n     foo()_).\n\n     There should be GUI tools to manipulate saved trace data and help\n     analyse it in conjunction with the source code.  It's unclear how\n     much of a common interface is shared with the current XScale trace\n     support, or should be shared with eventual Nexus-style trace module\n     support.\n\n     At this writing (November 2009) only ARM7, ARM9, and ARM11 support\n     for ETM modules is available.  The code should be able to work with\n     some newer cores; but not all of them support this original style\n     of JTAG access.\n\n16.1.1 ETM Configuration\n------------------------\n\nETM setup is coupled with the trace port driver configuration.\n\n -- Config Command: etm config target width mode clocking driver\n     Declares the ETM associated with TARGET, and associates it with a\n     given trace port DRIVER.  *Note Trace Port Drivers:\n     traceportdrivers.\n\n     Several of the parameters must reflect the trace port capabilities,\n     which are a function of silicon capabilities (exposed later using\n     'etm info') and of what hardware is connected to that port (such as\n     an external pod, or ETB). The WIDTH must be either 4, 8, or 16,\n     except with ETMv3.0 and newer modules which may also support 1, 2,\n     24, 32, 48, and 64 bit widths.  (With those versions, 'etm info'\n     also shows whether the selected port width and mode are supported.)\n\n     The MODE must be 'normal', 'multiplexed', or 'demultiplexed'.  The\n     CLOCKING must be 'half' or 'full'.\n\n          Warning: With ETMv3.0 and newer, the bits set with the MODE\n          and CLOCKING parameters both control the mode.  This modified\n          mode does not map to the values supported by previous ETM\n          modules, so this syntax is subject to change.\n\n          Note: You can see the ETM registers using the 'reg' command.\n          Not all possible registers are present in every ETM. Most of\n          the registers are write-only, and are used to configure what\n          CPU activities are traced.\n\n -- Command: etm info\n     Displays information about the current target's ETM. This includes\n     resource counts from the 'ETM_CONFIG' register, as well as silicon\n     capabilities (except on rather old modules).  from the\n     'ETM_SYS_CONFIG' register.\n\n -- Command: etm status\n     Displays status of the current target's ETM and trace port driver:\n     is the ETM idle, or is it collecting data?  Did trace data\n     overflow?  Was it triggered?\n\n -- Command: etm tracemode [type context_id_bits cycle_accurate\n          branch_output]\n     Displays what data that ETM will collect.  If arguments are\n     provided, first configures that data.  When the configuration\n     changes, tracing is stopped and any buffered trace data is\n     invalidated.\n\n        * TYPE ...  describing how data accesses are traced, when they\n          pass any ViewData filtering that was set up.  The value is one\n          of 'none' (save nothing), 'data' (save data), 'address' (save\n          addresses), 'all' (save data and addresses)\n        * CONTEXT_ID_BITS ...  0, 8, 16, or 32\n        * CYCLE_ACCURATE ...  'enable' or 'disable' cycle-accurate\n          instruction tracing.  Before ETMv3, enabling this causes much\n          extra data to be recorded.\n        * BRANCH_OUTPUT ...  'enable' or 'disable'.  Disable this unless\n          you need to try reconstructing the instruction trace stream\n          without an image of the code.\n\n -- Command: etm trigger_debug (enable|disable)\n     Displays whether ETM triggering debug entry (like a breakpoint) is\n     enabled or disabled, after optionally modifying that configuration.\n     The default behaviour is 'disable'.  Any change takes effect after\n     the next 'etm start'.\n\n     By using script commands to configure ETM registers, you can make\n     the processor enter debug state automatically when certain\n     conditions, more complex than supported by the breakpoint hardware,\n     happen.\n\n16.1.2 ETM Trace Operation\n--------------------------\n\nAfter setting up the ETM, you can use it to collect data.  That data can\nbe exported to files for later analysis.  It can also be parsed with\nOpenOCD, for basic sanity checking.\n\nTo configure what is being traced, you will need to write various trace\nregisters using 'reg ETM_*' commands.  For the definitions of these\nregisters, read ARM publication _IHI 0014, \"Embedded Trace Macrocell,\nArchitecture Specification\"_.  Be aware that most of the relevant\nregisters are write-only, and that ETM resources are limited.  There are\nonly a handful of address comparators, data comparators, counters, and\nso on.\n\nExamples of scenarios you might arrange to trace include:\n\n   * Code flow within a function, _excluding_ subroutines it calls.  Use\n     address range comparators to enable tracing for instruction access\n     within that function's body.\n   * Code flow within a function, _including_ subroutines it calls.  Use\n     the sequencer and address comparators to activate tracing on an\n     \"entered function\" state, then deactivate it by exiting that state\n     when the function's exit code is invoked.\n   * Code flow starting at the fifth invocation of a function, combining\n     one of the above models with a counter.\n   * CPU data accesses to the registers for a particular device, using\n     address range comparators and the ViewData logic.\n   * Such data accesses only during IRQ handling, combining the above\n     model with sequencer triggers which on entry and exit to the IRQ\n     handler.\n   * _...  more_\n\nAt this writing, September 2009, there are no Tcl utility procedures to\nhelp set up any common tracing scenarios.\n\n -- Command: etm analyze\n     Reads trace data into memory, if it wasn't already present.\n     Decodes and prints the data that was collected.\n\n -- Command: etm dump filename\n     Stores the captured trace data in 'filename'.\n\n -- Command: etm image filename [base_address] [type]\n     Opens an image file.\n\n -- Command: etm load filename\n     Loads captured trace data from 'filename'.\n\n -- Command: etm start\n     Starts trace data collection.\n\n -- Command: etm stop\n     Stops trace data collection.\n\n16.1.3 Trace Port Drivers\n-------------------------\n\nTo use an ETM trace port it must be associated with a driver.\n\n -- Trace Port Driver: dummy\n     Use the 'dummy' driver if you are configuring an ETM that's not\n     connected to anything (on-chip ETB or off-chip trace connector).\n     _This driver lets OpenOCD talk to the ETM, but it does not expose\n     any trace data collection._\n      -- Config Command: etm_dummy config target\n          Associates the ETM for TARGET with a dummy driver.\n\n -- Trace Port Driver: etb\n     Use the 'etb' driver if you are configuring an ETM to use on-chip\n     ETB memory.\n      -- Config Command: etb config target etb_tap\n          Associates the ETM for TARGET with the ETB at ETB_TAP.  You\n          can see the ETB registers using the 'reg' command.\n      -- Command: etb trigger_percent [percent]\n          This displays, or optionally changes, ETB behavior after the\n          ETM's configured _trigger_ event fires.  It controls how much\n          more trace data is saved after the (single) trace trigger\n          becomes active.\n\n             * The default corresponds to _trace around_ usage,\n               recording 50 percent data before the event and the rest\n               afterwards.\n             * The minimum value of PERCENT is 2 percent, recording\n               almost exclusively data before the trigger.  Such extreme\n               _trace before_ usage can help figure out what caused that\n               event to happen.\n             * The maximum value of PERCENT is 100 percent, recording\n               data almost exclusively after the event.  This extreme\n               _trace after_ usage might help sort out how the event\n               caused trouble.\n\n16.2 ARM Cross-Trigger Interface\n================================\n\nThe ARM Cross-Trigger Interface (CTI) is a generic CoreSight component\nthat connects event sources like tracing components or CPU cores with\neach other through a common trigger matrix (CTM). For ARMv8\narchitecture, a CTI is mandatory for core run control and each core has\nan individual CTI instance attached to it.  OpenOCD has limited support\nfor CTI using the _cti_ group of commands.\n\n -- Command: cti create cti_name -dap dap_name -ap-num apn -baseaddr\n          base_address\n     Creates a CTI instance CTI_NAME on the DAP instance DAP_NAME on\n     MEM-AP APN.  The BASE_ADDRESS must match the base address of the\n     CTI on the respective MEM-AP. All arguments are mandatory.  This\n     creates a new command '$cti_name' which is used for various\n     purposes including additional configuration.\n\n -- Command: $cti_name enable on|off\n     Enable ('on') or disable ('off') the CTI.\n\n -- Command: $cti_name dump\n     Displays a register dump of the CTI.\n\n -- Command: $cti_name write REG_NAME VALUE\n     Write VALUE to the CTI register with the symbolic name REG_NAME.\n\n -- Command: $cti_name read REG_NAME\n     Print the value read from the CTI register with the symbolic name\n     REG_NAME.\n\n -- Command: $cti_name ack EVENT\n     Acknowledge a CTI EVENT.\n\n -- Command: $cti_name channel CHANNEL_NUMBER OPERATION\n     Perform a specific channel operation, the possible operations are:\n     gate, ungate, set, clear and pulse\n\n -- Command: $cti_name testmode on|off\n     Enable ('on') or disable ('off') the integration test mode of the\n     CTI.\n\n -- Command: cti names\n     Prints a list of names of all CTI objects created.  This command is\n     mainly useful in TCL scripting.\n\n16.3 Generic ARM\n================\n\nThese commands should be available on all ARM processors.  They are\navailable in addition to other core-specific commands that may be\navailable.\n\n -- Command: arm core_state [arm|thumb]\n     Displays the core_state, optionally changing it to process either\n     'arm' or 'thumb' instructions.  The target may later be resumed in\n     the currently set core_state.  (Processors may also support the\n     Jazelle state, but that is not currently supported in OpenOCD.)\n\n -- Command: arm disassemble address [count [thumb]]\n     Disassembles COUNT instructions starting at ADDRESS.  If COUNT is\n     not specified, a single instruction is disassembled.  If 'thumb' is\n     specified, or the low bit of the address is set, Thumb2 (mixed\n     16/32-bit) instructions are used; else ARM (32-bit) instructions\n     are used.  (Processors may also support the Jazelle state, but\n     those instructions are not currently understood by OpenOCD.)\n\n     Note that all Thumb instructions are Thumb2 instructions, so older\n     processors (without Thumb2 support) will still see correct\n     disassembly of Thumb code.  Also, ThumbEE opcodes are the same as\n     Thumb2, with a handful of exceptions.  ThumbEE disassembly\n     currently has no explicit support.\n\n -- Command: arm mcr pX op1 CRn CRm op2 value\n     Write VALUE to a coprocessor PX register passing parameters CRN,\n     CRM, opcodes OPC1 and OPC2, and using the MCR instruction.\n     (Parameter sequence matches the ARM instruction, but omits an ARM\n     register.)\n\n -- Command: arm mrc pX coproc op1 CRn CRm op2\n     Read a coprocessor PX register passing parameters CRN, CRM, opcodes\n     OPC1 and OPC2, and the MRC instruction.  Returns the result so it\n     can be manipulated by Jim scripts.  (Parameter sequence matches the\n     ARM instruction, but omits an ARM register.)\n\n -- Command: arm reg\n     Display a table of all banked core registers, fetching the current\n     value from every core mode if necessary.\n\n -- Command: arm semihosting [enable|disable]\n     Display status of semihosting, after optionally changing that\n     status.\n\n     Semihosting allows for code executing on an ARM target to use the\n     I/O facilities on the host computer i.e.  the system where OpenOCD\n     is running.  The target application must be linked against a\n     library implementing the ARM semihosting convention that forwards\n     operation requests by using a special SVC instruction that is\n     trapped at the Supervisor Call vector by OpenOCD.\n\n -- Command: arm semihosting_redirect (disable | tcp <port>\n     ['debug'|'stdio'|'all') Redirect semihosting messages to a\n     specified TCP port.\n\n     This command redirects debug (READC, WRITEC and WRITE0) and stdio\n     (READ, WRITE) semihosting operations to the specified TCP port.\n     The command allows to select which type of operations to redirect\n     (debug, stdio, all (default)).  Note: for stdio operations, only\n     I/O from/to ':tt' file descriptors are redirected.\n\n -- Command: arm semihosting_cmdline [enable|disable]\n     Set the command line to be passed to the debugger.\n\n          arm semihosting_cmdline argv0 argv1 argv2 ...\n\n     This option lets one set the command line arguments to be passed to\n     the program.  The first argument (argv0) is the program name in a\n     standard C environment (argv[0]).  Depending on the program (not\n     much programs look at argv[0]), argv0 is ignored and can be any\n     string.\n\n -- Command: arm semihosting_fileio [enable|disable]\n     Display status of semihosting fileio, after optionally changing\n     that status.\n\n     Enabling this option forwards semihosting I/O to GDB process using\n     the File-I/O remote protocol extension.  This is especially useful\n     for interacting with remote files or displaying console messages in\n     the debugger.\n\n -- Command: arm semihosting_resexit [enable|disable]\n     Enable resumable SEMIHOSTING_SYS_EXIT.\n\n     When SEMIHOSTING_SYS_EXIT is called outside a debug session, things\n     are simple, the openocd process calls exit() and passes the value\n     returned by the target.\n\n     When SEMIHOSTING_SYS_EXIT is called during a debug session, by\n     default execution returns to the debugger, leaving the debugger in\n     a HALT state, similar to the state entered when encountering a\n     break.\n\n     In some use cases, it is useful to have SEMIHOSTING_SYS_EXIT return\n     normally, as any semihosting call, and do not break to the\n     debugger.  The standard allows this to happen, but the condition to\n     trigger it is a bit obscure (\"by performing an RDI_Execute request\n     or equivalent\").\n\n     To make the SEMIHOSTING_SYS_EXIT call return normally, enable this\n     option (default: disabled).\n\n -- Command: arm semihosting_read_user_param\n     Read parameter of the semihosting call from the target.  Usable in\n     semihosting-user-cmd-0x10* event handlers, returning a string.\n\n     When the target makes semihosting call with operation number from\n     range 0x100- 0x107, an optional string parameter can be passed to\n     the server.  This parameter is valid during the run of the event\n     handlers and is accessible with this command.\n\n -- Command: arm semihosting_basedir [dir]\n     Set the base directory for semihosting I/O, either an absolute path\n     or a path relative to OpenOCD working directory.  Use \".\"  for the\n     current directory.\n\n16.4 ARMv4 and ARMv5 Architecture\n=================================\n\nThe ARMv4 and ARMv5 architectures are widely used in embedded systems,\nand introduced core parts of the instruction set in use today.  That\nincludes the Thumb instruction set, introduced in the ARMv4T variant.\n\n16.4.1 ARM7 and ARM9 specific commands\n--------------------------------------\n\nThese commands are specific to ARM7 and ARM9 cores, like ARM7TDMI,\nARM720T, ARM9TDMI, ARM920T or ARM926EJ-S. They are available in addition\nto the ARM commands, and any other core-specific commands that may be\navailable.\n\n -- Command: arm7_9 dbgrq [enable|disable]\n     Displays the value of the flag controlling use of the EmbeddedIce\n     DBGRQ signal to force entry into debug mode, instead of\n     breakpoints.  If a boolean parameter is provided, first assigns\n     that flag.\n\n     This should be safe for all but ARM7TDMI-S cores (like NXP LPC).\n     This feature is enabled by default on most ARM9 cores, including\n     ARM9TDMI, ARM920T, and ARM926EJ-S.\n\n -- Command: arm7_9 dcc_downloads [enable|disable]\n     Displays the value of the flag controlling use of the debug\n     communications channel (DCC) to write larger (>128 byte) amounts of\n     memory.  If a boolean parameter is provided, first assigns that\n     flag.\n\n     DCC downloads offer a huge speed increase, but might be unsafe,\n     especially with targets running at very low speeds.  This command\n     was introduced with OpenOCD rev.  60, and requires a few bytes of\n     working area.\n\n -- Command: arm7_9 fast_memory_access [enable|disable]\n     Displays the value of the flag controlling use of memory writes and\n     reads that don't check completion of the operation.  If a boolean\n     parameter is provided, first assigns that flag.\n\n     This provides a huge speed increase, especially with USB JTAG\n     cables (FT2232), but might be unsafe if used with targets running\n     at very low speeds, like the 32kHz startup clock of an AT91RM9200.\n\n16.4.2 ARM9 specific commands\n-----------------------------\n\nARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS)\ninteger processors.  Such cores include the ARM920T, ARM926EJ-S, and\nARM966.\n\n -- Command: arm9 vector_catch [all|none|list]\n     Vector Catch hardware provides a sort of dedicated breakpoint for\n     hardware events such as reset, interrupt, and abort.  You can use\n     this to conserve normal breakpoint resources, so long as you're not\n     concerned with code that branches directly to those hardware\n     vectors.\n\n     This always finishes by listing the current configuration.  If\n     parameters are provided, it first reconfigures the vector catch\n     hardware to intercept 'all' of the hardware vectors, 'none' of\n     them, or a list with one or more of the following: 'reset' 'undef'\n     'swi' 'pabt' 'dabt' 'irq' 'fiq'.\n\n16.4.3 ARM920T specific commands\n--------------------------------\n\nThese commands are available to ARM920T based CPUs, which are\nimplementations of the ARMv4T architecture built using the ARM9TDMI\ninteger core.  They are available in addition to the ARM, ARM7/ARM9, and\nARM9 commands.\n\n -- Command: arm920t cache_info\n     Print information about the caches found.  This allows to see\n     whether your target is an ARM920T (2x16kByte cache) or ARM922T\n     (2x8kByte cache).\n\n -- Command: arm920t cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.  This uses \"physical access\" and\n     the register number is as shown in bits 38..33 of table 9-9 in the\n     ARM920T TRM. (Not all registers can be written.)\n\n -- Command: arm920t read_cache filename\n     Dump the content of ICache and DCache to a file named 'filename'.\n\n -- Command: arm920t read_mmu filename\n     Dump the content of the ITLB and DTLB to a file named 'filename'.\n\n16.4.4 ARM926ej-s specific commands\n-----------------------------------\n\nThese commands are available to ARM926ej-s based CPUs, which are\nimplementations of the ARMv5TEJ architecture based on the ARM9EJ-S\ninteger core.  They are available in addition to the ARM, ARM7/ARM9, and\nARM9 commands.\n\nThe Feroceon cores also support these commands, although they are not\nbuilt from ARM926ej-s designs.\n\n -- Command: arm926ejs cache_info\n     Print information about the caches found.\n\n16.4.5 ARM966E specific commands\n--------------------------------\n\nThese commands are available to ARM966 based CPUs, which are\nimplementations of the ARMv5TE architecture.  They are available in\naddition to the ARM, ARM7/ARM9, and ARM9 commands.\n\n -- Command: arm966e cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.  The six bit REGNUM values are\n     bits 37..32 from table 7-2 of the ARM966E-S TRM. There is no\n     current control over bits 31..30 from that table, as required for\n     BIST support.\n\n16.4.6 XScale specific commands\n-------------------------------\n\nSome notes about the debug implementation on the XScale CPUs:\n\nThe XScale CPU provides a special debug-only mini-instruction cache\n(mini-IC) in which exception vectors and target-resident debug handler\ncode are placed by OpenOCD. In order to get access to the CPU, OpenOCD\nmust point vector 0 (the reset vector) to the entry of the debug\nhandler.  However, this means that the complete first cacheline in the\nmini-IC is marked valid, which makes the CPU fetch all exception\nhandlers from the mini-IC, ignoring the code in RAM.\n\nTo address this situation, OpenOCD provides the 'xscale vector_table'\ncommand, which allows the user to explicitly write individual entries to\neither the high or low vector table stored in the mini-IC.\n\nIt is recommended to place a pc-relative indirect branch in the vector\ntable, and put the branch destination somewhere in memory.  Doing so\nmakes sure the code in the vector table stays constant regardless of\ncode layout in memory:\n     _vectors:\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             .org 0x100\n             .long real_reset_vector\n             .long real_ui_handler\n             .long real_swi_handler\n             .long real_pf_abort\n             .long real_data_abort\n             .long 0 /* unused */\n             .long real_irq_handler\n             .long real_fiq_handler\n\nAlternatively, you may choose to keep some or all of the mini-IC vector\ntable entries synced with those written to memory by your system\nsoftware.  The mini-IC can not be modified while the processor is\nexecuting, but for each vector table entry not previously defined using\nthe 'xscale vector_table' command, OpenOCD will copy the value from\nmemory to the mini-IC every time execution resumes from a halt.  This is\ndone for both high and low vector tables (although the table not in use\nmay not be mapped to valid memory, and in this case that copy operation\nwill silently fail).  This means that you will need to briefly halt\nexecution at some strategic point during system start-up; e.g., after\nthe software has initialized the vector table, but before exceptions are\nenabled.  A breakpoint can be used to accomplish this once the\nappropriate location in the start-up code has been identified.  A\nwatchpoint over the vector table region is helpful in finding the\nlocation if you're not sure.  Note that the same situation exists any\ntime the vector table is modified by the system software.\n\nThe debug handler must be placed somewhere in the address space using\nthe 'xscale debug_handler' command.  The allowed locations for the debug\nhandler are either (0x800 - 0x1fef800) or (0xfe000800 - 0xfffff800).\nThe default value is 0xfe000800.\n\nXScale has resources to support two hardware breakpoints and two\nwatchpoints.  However, the following restrictions on watchpoint\nfunctionality apply: (1) the value and mask arguments to the 'wp'\ncommand are not supported, (2) the watchpoint length must be a power of\ntwo and not less than four, and can not be greater than the watchpoint\naddress, and (3) a watchpoint with a length greater than four consumes\nall the watchpoint hardware resources.  This means that at any one time,\nyou can have enabled either two watchpoints with a length of four, or\none watchpoint with a length greater than four.\n\nThese commands are available to XScale based CPUs, which are\nimplementations of the ARMv5TE architecture.\n\n -- Command: xscale analyze_trace\n     Displays the contents of the trace buffer.\n\n -- Command: xscale cache_clean_address address\n     Changes the address used when cleaning the data cache.\n\n -- Command: xscale cache_info\n     Displays information about the CPU caches.\n\n -- Command: xscale cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.\n\n -- Command: xscale debug_handler target address\n     Changes the address used for the specified target's debug handler.\n\n -- Command: xscale dcache [enable|disable]\n     Enables or disable the CPU's data cache.\n\n -- Command: xscale dump_trace filename\n     Dumps the raw contents of the trace buffer to 'filename'.\n\n -- Command: xscale icache [enable|disable]\n     Enables or disable the CPU's instruction cache.\n\n -- Command: xscale mmu [enable|disable]\n     Enables or disable the CPU's memory management unit.\n\n -- Command: xscale trace_buffer [enable|disable [fill [n] | wrap]]\n     Displays the trace buffer status, after optionally enabling or\n     disabling the trace buffer and modifying how it is emptied.\n\n -- Command: xscale trace_image filename [offset [type]]\n     Opens a trace image from 'filename', optionally rebasing its\n     segment addresses by OFFSET.  The image TYPE may be one of 'bin'\n     (binary), 'ihex' (Intel hex), 'elf' (ELF file), 's19' (Motorola\n     s19), 'mem', or 'builder'.\n\n -- Command: xscale vector_catch [mask]\n     Display a bitmask showing the hardware vectors to catch.  If the\n     optional parameter is provided, first set the bitmask to that\n     value.\n\n     The mask bits correspond with bit 16..23 in the DCSR:\n          0x01    Trap Reset\n          0x02    Trap Undefined Instructions\n          0x04    Trap Software Interrupt\n          0x08    Trap Prefetch Abort\n          0x10    Trap Data Abort\n          0x20    reserved\n          0x40    Trap IRQ\n          0x80    Trap FIQ\n\n -- Command: xscale vector_table [(low|high) index value]\n\n     Set an entry in the mini-IC vector table.  There are two tables:\n     one for low vectors (at 0x00000000), and one for high vectors\n     (0xFFFF0000), each holding the 8 exception vectors.  INDEX can be\n     1-7, because vector 0 points to the debug handler entry and can not\n     be overwritten.  VALUE holds the 32-bit opcode that is placed in\n     the mini-IC.\n\n     Without arguments, the current settings are displayed.\n\n16.5 ARMv6 Architecture\n=======================\n\n16.5.1 ARM11 specific commands\n------------------------------\n\n -- Command: arm11 memwrite burst [enable|disable]\n     Displays the value of the memwrite burst-enable flag, which is\n     enabled by default.  If a boolean parameter is provided, first\n     assigns that flag.  Burst writes are only used for memory writes\n     larger than 1 word.  They improve performance by assuming that the\n     CPU has read each data word over JTAG and completed its write\n     before the next word arrives, instead of polling for a status flag\n     to verify that completion.  This is usually safe, because JTAG runs\n     much slower than the CPU.\n\n -- Command: arm11 memwrite error_fatal [enable|disable]\n     Displays the value of the memwrite error_fatal flag, which is\n     enabled by default.  If a boolean parameter is provided, first\n     assigns that flag.  When set, certain memory write errors cause\n     earlier transfer termination.\n\n -- Command: arm11 step_irq_enable [enable|disable]\n     Displays the value of the flag controlling whether IRQs are enabled\n     during single stepping; they are disabled by default.  If a boolean\n     parameter is provided, first assigns that.\n\n -- Command: arm11 vcr [value]\n     Displays the value of the _Vector Catch Register (VCR)_,\n     coprocessor 14 register 7.  If VALUE is defined, first assigns\n     that.\n\n     Vector Catch hardware provides dedicated breakpoints for certain\n     hardware events.  The specific bit values are core-specific (as in\n     fact is using coprocessor 14 register 7 itself) but all current\n     ARM11 cores _except the ARM1176_ use the same six bits.\n\n16.6 ARMv7 and ARMv8 Architecture\n=================================\n\n16.6.1 ARMv7-A specific commands\n--------------------------------\n\n -- Command: cortex_a cache_info\n     display information about target caches\n\n -- Command: cortex_a dacrfixup [on|off]\n     Work around issues with software breakpoints when the program text\n     is mapped read-only by the operating system.  This option sets the\n     CP15 DACR to \"all-manager\" to bypass MMU permission checks on\n     memory access.  Defaults to 'off'.\n\n -- Command: cortex_a dbginit\n     Initialize core debug Enables debug by unlocking the Software Lock\n     and clearing sticky powerdown indications\n\n -- Command: cortex_a smp [on|off]\n     Display/set the current SMP mode\n\n -- Command: cortex_a smp_gdb [core_id]\n     Display/set the current core displayed in GDB\n\n -- Command: cortex_a maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping\n\n -- Command: cache_config l2x [base way]\n     configure l2x cache\n\n -- Command: cortex_a mmu dump [0|1|addr address [num_entries]]\n     Dump the MMU translation table from TTB0 or TTB1 register, or from\n     physical memory location ADDRESS.  When dumping the table from\n     ADDRESS, print at most NUM_ENTRIES page table entries.  NUM_ENTRIES\n     is optional, if omitted, the maximum possible (4096) entries are\n     printed.\n\n16.6.2 ARMv7-R specific commands\n--------------------------------\n\n -- Command: cortex_r4 dbginit\n     Initialize core debug Enables debug by unlocking the Software Lock\n     and clearing sticky powerdown indications\n\n -- Command: cortex_r4 maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping\n\n16.6.3 ARM CoreSight TPIU and SWO specific commands\n---------------------------------------------------\n\nARM CoreSight provides several modules to generate debugging information\ninternally (ITM, DWT and ETM). Their output is directed through TPIU or\nSWO modules to be captured externally either on an SWO pin (this\nconfiguration is called SWV) or on a synchronous parallel trace port.\n\nARM CoreSight provides independent HW blocks named TPIU and SWO each\nwith its own functionality.  Embedded in Cortex-M3 and M4, ARM provides\nan optional HW block that includes both TPIU and SWO functionalities and\nis again named TPIU, which causes quite some confusion.  The registers\nmap of all the TPIU and SWO implementations allows using a single driver\nthat detects at runtime the features available.\n\nThe 'tpiu' is used for either TPIU or SWO. A convenient alias 'swo' is\navailable to help distinguish, in scripts, the commands for SWO from the\ncommands for TPIU.\n\n -- Command: swo ...\n     Alias of 'tpiu ...'.  Can be used in scripts to distinguish the\n     commands for SWO from the commands for TPIU.\n\n -- Command: tpiu create tpiu_name configparams...\n     Creates a TPIU or a SWO object.  The two commands are equivalent.\n     Add the object in a list and add new commands ('TPIU_NAME') which\n     are used for various purposes including additional configuration.\n\n        * TPIU_NAME - the name of the TPIU or SWO object.  This name is\n          also used to create the object's command, referred to here as\n          '$tpiu_name', and in other places where the TPIU or SWO needs\n          to be identified.\n        * CONFIGPARAMS - all parameters accepted by '$tpiu_name\n          configure' are permitted.\n\n          You _must_ set here the AP and MEM_AP base_address through\n          '-dap DAP_NAME', '-ap-num AP_NUMBER' and '-baseaddr\n          BASE_ADDRESS'.\n\n -- Command: tpiu names\n     Lists all the TPIU or SWO objects created so far.  The two commands\n     are equivalent.\n\n -- Command: tpiu init\n     Initialize all registered TPIU and SWO. The two commands are\n     equivalent.  These commands are used internally during\n     initialization.  They can be issued at any time after the\n     initialization, too.\n\n -- Command: $tpiu_name cget queryparm\n     Each configuration parameter accepted by '$tpiu_name configure' can\n     be individually queried, to return its current value.  The\n     QUERYPARM is a parameter name accepted by that command, such as\n     '-dap'.\n\n -- Command: $tpiu_name configure configparams...\n     The options accepted by this command may also be specified as\n     parameters to 'tpiu create'.  Their values can later be queried one\n     at a time by using the '$tpiu_name cget' command.\n\n        * '-dap' DAP_NAME - names the DAP used to access this TPIU.\n          *Note DAP declaration: dapdeclaration, on how to create and\n          manage DAP instances.\n\n        * '-ap-num' AP_NUMBER - sets DAP access port for TPIU, AP_NUMBER\n          is the numeric index of the DAP AP the TPIU is connected to.\n\n        * '-baseaddr' BASE_ADDRESS - sets the TPIU BASE_ADDRESS where to\n          access the TPIU in the DAP AP memory space.\n\n        * '-protocol' ('sync'|'uart'|'manchester') - sets the protocol\n          used for trace data:\n             - 'sync' - synchronous parallel trace output mode, using\n               PORT_WIDTH data bits (default);\n             - 'uart' - use asynchronous SWO mode with NRZ (same as\n               regular UART 8N1) coding;\n             - 'manchester' - use asynchronous SWO mode with Manchester\n               coding.\n\n        * '-event' EVENT_NAME EVENT_BODY - assigns an event handler, a\n          TCL string which is evaluated when the event is triggered.\n          The events 'pre-enable', 'post-enable', 'pre-disable' and\n          'post-disable' are defined for TPIU/SWO. A typical use case\n          for the event 'pre-enable' is to enable the trace clock of the\n          TPIU.\n\n        * '-output' ('external'|':'PORT|FILENAME|'-') - specifies the\n          destination of the trace data:\n             - 'external' - configure TPIU/SWO to let user capture trace\n               output externally, either with an additional UART or with\n               a logic analyzer (default);\n             - '-' - configure TPIU/SWO and debug adapter to gather\n               trace data and forward it to 'tcl_trace' command;\n             - ':'PORT - configure TPIU/SWO and debug adapter to gather\n               trace data, open a TCP server at port PORT and send the\n               trace data to each connected client;\n             - FILENAME - configure TPIU/SWO and debug adapter to gather\n               trace data and append it to FILENAME, which can be either\n               a regular file or a named pipe.\n\n        * '-traceclk' TRACECLKIN_FREQ - mandatory parameter.  Specifies\n          the frequency in Hz of the trace clock.  For the TPIU embedded\n          in Cortex-M3 or M4, this is usually the same frequency as\n          HCLK. For protocol 'sync' this is twice the frequency of the\n          pin data rate.\n\n        * '-pin-freq' TRACE_FREQ - specifies the expected data rate in\n          Hz of the SWO pin.  Parameter used only on protocols 'uart'\n          and 'manchester'.  Can be omitted to let the adapter driver\n          select the maximum supported rate automatically.\n\n        * '-port-width' PORT_WIDTH - sets to PORT_WIDTH the width of the\n          synchronous parallel port used for trace output.  Parameter\n          used only on protocol 'sync'.  If not specified, default value\n          is 1.\n\n        * '-formatter' ('0'|'1') - specifies if the formatter should be\n          enabled.  Parameter used only on protocol 'sync'.  If not\n          specified, default value is 0.\n\n -- Command: $tpiu_name enable\n     Uses the parameters specified by the previous '$tpiu_name\n     configure' to configure and enable the TPIU or the SWO. If\n     required, the adapter is also configured and enabled to receive the\n     trace data.  This command can be used before 'init', but it will\n     take effect only after the 'init'.\n\n -- Command: $tpiu_name disable\n     Disable the TPIU or the SWO, terminating the receiving of the trace\n     data.\n\nExample usage:\n  1. STM32L152 board is programmed with an application that configures\n     PLL to provide core clock with 24MHz frequency; to use ITM output\n     it's enough to:\n          #include <libopencm3/cm3/itm.h>\n              ...\n              \tITM_STIM8(0) = c;\n              ...\n     (the most obvious way is to use the first stimulus port for printf,\n     for that this ITM_STIM8 assignment can be used inside _write(); to\n     make it blocking to avoid data loss, add 'while (!(ITM_STIM8(0) &\n     ITM_STIM_FIFOREADY));');\n  2. An FT2232H UART is connected to the SWO pin of the board;\n  3. Commands to configure UART for 12MHz baud rate:\n          $ setserial /dev/ttyUSB1 spd_cust divisor 5\n          $ stty -F /dev/ttyUSB1 38400\n     (FT2232H's base frequency is 60MHz, spd_cust allows to alias 38400\n     baud with our custom divisor to get 12MHz)\n  4. 'itmdump -f /dev/ttyUSB1 -d1'\n  5. OpenOCD invocation line:\n          openocd -f interface/stlink.cfg \\\n          -c \"transport select hla_swd\" \\\n          -f target/stm32l1.cfg \\\n          -c \"stm32l1.tpiu configure -protocol uart\" \\\n          -c \"stm32l1.tpiu configure -traceclk 24000000 -pin-freq 12000000\" \\\n          -c \"stm32l1.tpiu enable\"\n\n16.6.4 ARMv7-M specific commands\n--------------------------------\n\n -- Command: itm port PORT (0|1|on|off)\n     Enable or disable trace output for ITM stimulus PORT (counting from\n     0).  Port 0 is enabled on target creation automatically.\n\n -- Command: itm ports (0|1|on|off)\n     Enable or disable trace output for all ITM stimulus ports.\n\n16.6.5 Cortex-M specific commands\n---------------------------------\n\n -- Command: cortex_m maskisr (auto|on|off|steponly)\n     Control masking (disabling) interrupts during target step/resume.\n\n     The 'auto' option handles interrupts during stepping in a way that\n     they get served but don't disturb the program flow.  The step\n     command first allows pending interrupt handlers to execute, then\n     disables interrupts and steps over the next instruction where the\n     core was halted.  After the step interrupts are enabled again.  If\n     the interrupt handlers don't complete within 500ms, the step\n     command leaves with the core running.\n\n     The 'steponly' option disables interrupts during single-stepping\n     but enables them during normal execution.  This can be used as a\n     partial workaround for 702596 erratum in Cortex-M7 r0p1.  See\n     \"Cortex-M7 (AT610) and Cortex-M7 with FPU (AT611) Software\n     Developer Errata Notice\" from ARM for further details.\n\n     Note that a free hardware (FPB) breakpoint is required for the\n     'auto' option.  If no breakpoint is available at the time of the\n     step, then the step is taken with interrupts enabled, i.e.  the\n     same way the 'off' option does.\n\n     Default is 'auto'.\n\n -- Command: cortex_m vector_catch [all|none|list]\n     Vector Catch hardware provides dedicated breakpoints for certain\n     hardware events.\n\n     Parameters request interception of 'all' of these hardware event\n     vectors, 'none' of them, or one or more of the following:\n     'hard_err' for a HardFault exception; 'mm_err' for a MemManage\n     exception; 'bus_err' for a BusFault exception; 'irq_err',\n     'state_err', 'chk_err', or 'nocp_err' for various UsageFault\n     exceptions; or 'reset'.  If NVIC setup code does not enable them,\n     MemManage, BusFault, and UsageFault exceptions are mapped to\n     HardFault.  UsageFault checks for divide-by-zero and unaligned\n     access must also be explicitly enabled.\n\n     This finishes by listing the current vector catch configuration.\n\n -- Command: cortex_m reset_config (sysresetreq|vectreset)\n     Control reset handling if hardware srst is not fitted *Note\n     reset_config: reset_config.\n\n        - 'sysresetreq' use AIRCR SYSRESETREQ to reset system.\n        - 'vectreset' use AIRCR VECTRESET to reset system (default).\n\n     Using 'vectreset' is a safe option for Cortex-M3, M4 and M7 cores.\n     This however has the disadvantage of only resetting the core, all\n     peripherals are unaffected.  A solution would be to use a\n     'reset-init' event handler to manually reset the peripherals.\n     *Note Target Events: targetevents.\n\n     Cortex-M0, M0+ and M1 do not support 'vectreset', use 'sysresetreq'\n     instead.\n\n16.6.6 ARMv8-A specific commands\n--------------------------------\n\n -- Command: aarch64 cache_info\n     Display information about target caches\n\n -- Command: aarch64 dbginit\n     This command enables debugging by clearing the OS Lock and sticky\n     power-down and reset indications.  It also establishes the\n     expected, basic cross-trigger configuration the aarch64 target code\n     relies on.  In a configuration file, the command would typically be\n     called from a 'reset-end' or 'reset-deassert-post' handler, to\n     re-enable debugging after a system reset.  However, normally it is\n     not necessary to use the command at all.\n\n -- Command: aarch64 disassemble address [count]\n     Disassembles COUNT instructions starting at ADDRESS.  If COUNT is\n     not specified, a single instruction is disassembled.\n\n -- Command: aarch64 smp [on|off]\n     Display, enable or disable SMP handling mode.  The state of SMP\n     handling influences the way targets in an SMP group are handled by\n     the run control.  With SMP handling enabled, issuing halt or resume\n     to one core will trigger halting or resuming of all cores in the\n     group.  The command 'target smp' defines which targets are in the\n     SMP group.  With SMP handling disabled, all targets need to be\n     treated individually.\n\n -- Command: aarch64 maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping.\n     The default configuration is 'on'.\n\n -- Command: $target_name catch_exc\n          [off|sec_el1|sec_el3|nsec_el1|nsec_el2]+\n     Cause '$target_name' to halt when an exception is taken.  Any\n     combination of Secure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is\n     valid.  The target '$target_name' will halt before taking the\n     exception.  In order to resume the target, the exception catch must\n     be disabled again with '$target_name catch_exc off'.  Issuing the\n     command without options prints the current configuration.\n\n16.7 EnSilica eSi-RISC Architecture\n===================================\n\neSi-RISC is a highly configurable microprocessor architecture for\nembedded systems provided by EnSilica.  (See:\n<http://www.ensilica.com/risc-ip/>.)\n\n16.7.1 eSi-RISC Configuration\n-----------------------------\n\n -- Command: esirisc cache_arch (harvard|von_neumann)\n     Configure the caching architecture.  Targets with the\n     'UNIFIED_ADDRESS_SPACE' option disabled employ a Harvard\n     architecture.  By default, 'von_neumann' is assumed.\n\n -- Command: esirisc hwdc (all|none|mask ...)\n     Configure hardware debug control.  The HWDC register controls which\n     exceptions return control back to the debugger.  Possible masks are\n     'all', 'none', 'reset', 'interrupt', 'syscall', 'error', and\n     'debug'.  By default, 'reset', 'error', and 'debug' are enabled.\n\n16.7.2 eSi-RISC Operation\n-------------------------\n\n -- Command: esirisc flush_caches\n     Flush instruction and data caches.  This command requires that the\n     target is halted when the command is issued and configured with an\n     instruction or data cache.\n\n16.7.3 eSi-Trace Configuration\n------------------------------\n\neSi-RISC targets may be configured with support for instruction tracing.\nTrace data may be written to an in-memory buffer or FIFO. If a FIFO is\nconfigured, DMA is typically employed to move trace data off-device\nusing a high-speed peripheral (eg.  SPI). Collected trace data is\nencoded in one of three different formats.  At a minimum, 'esirisc trace\nbuffer' or 'esirisc trace fifo' must be issued along with 'esirisc trace\nformat' before trace data can be collected.\n\nOpenOCD provides rudimentary analysis of collected trace data.  If more\ndetail is needed, collected trace data can be dumped to a file and\nprocessed by external tooling.\n\n     Issues: OpenOCD is unable to process trace data sent to a FIFO. A\n     potential workaround for this issue is to configure DMA to copy\n     trace data to an in-memory buffer, which can then be passed to the\n     'esirisc trace analyze' and 'esirisc trace dump' commands.\n\n     It is possible to corrupt trace data when using a FIFO if the\n     peripheral responsible for draining data from the FIFO is not fast\n     enough.  This can be managed by enabling flow control, however this\n     can impact timing-sensitive software operation on the CPU.\n\n -- Command: esirisc trace buffer address size [wrap]\n     Configure trace buffer using the provided address and size.  If the\n     'wrap' option is specified, trace collection will continue once the\n     end of the buffer is reached.  By default, wrap is disabled.\n\n -- Command: esirisc trace fifo address\n     Configure trace FIFO using the provided address.\n\n -- Command: esirisc trace flow_control (enable|disable)\n     Enable or disable stalling the CPU to collect trace data.  By\n     default, flow control is disabled.\n\n -- Command: esirisc trace format (full|branch|icache) pc_bits\n     Configure trace format and number of PC bits to be captured.\n     'pc_bits' must be within 1 and 31 as the LSB is not collected.  If\n     external tooling is used to analyze collected trace data, these\n     values must match.\n\n     Supported trace formats:\n        * 'full' capture full trace data, allowing execution history and\n          timing to be determined.\n        * 'branch' capture taken branch instructions and branch target\n          addresses.\n        * 'icache' capture instruction cache misses.\n\n -- Command: esirisc trace trigger start (condition) [start_data\n          start_mask]\n     Configure trigger start condition using the provided start data and\n     mask.  A brief description of each condition is provided below; for\n     more detail on how these values are used, see the eSi-RISC\n     Architecture Manual.\n\n     Supported conditions:\n        * 'none' manual tracing (see 'esirisc trace start').\n        * 'pc' start tracing if the PC matches start data and mask.\n        * 'load' start tracing if the effective address of a load\n          instruction matches start data and mask.\n        * 'store' start tracing if the effective address of a store\n          instruction matches start data and mask.\n        * 'exception' start tracing if the EID of an exception matches\n          start data and mask.\n        * 'eret' start tracing when an 'ERET' instruction is executed.\n        * 'wait' start tracing when a 'WAIT' instruction is executed.\n        * 'stop' start tracing when a 'STOP' instruction is executed.\n        * 'high' start tracing when an external signal is a logical\n          high.\n        * 'low' start tracing when an external signal is a logical low.\n\n -- Command: esirisc trace trigger stop (condition) [stop_data\n          stop_mask]\n     Configure trigger stop condition using the provided stop data and\n     mask.  A brief description of each condition is provided below; for\n     more detail on how these values are used, see the eSi-RISC\n     Architecture Manual.\n\n     Supported conditions:\n        * 'none' manual tracing (see 'esirisc trace stop').\n        * 'pc' stop tracing if the PC matches stop data and mask.\n        * 'load' stop tracing if the effective address of a load\n          instruction matches stop data and mask.\n        * 'store' stop tracing if the effective address of a store\n          instruction matches stop data and mask.\n        * 'exception' stop tracing if the EID of an exception matches\n          stop data and mask.\n        * 'eret' stop tracing when an 'ERET' instruction is executed.\n        * 'wait' stop tracing when a 'WAIT' instruction is executed.\n        * 'stop' stop tracing when a 'STOP' instruction is executed.\n\n -- Command: esirisc trace trigger delay (trigger) [cycles]\n     Configure trigger start/stop delay in clock cycles.\n\n     Supported triggers:\n        * 'none' no delay to start or stop collection.\n        * 'start' delay 'cycles' after trigger to start collection.\n        * 'stop' delay 'cycles' after trigger to stop collection.\n        * 'both' delay 'cycles' after both triggers to start or stop\n          collection.\n\n16.7.4 eSi-Trace Operation\n--------------------------\n\n -- Command: esirisc trace init\n     Initialize trace collection.  This command must be called any time\n     the configuration changes.  If a trace buffer has been configured,\n     the contents will be overwritten when trace collection starts.\n\n -- Command: esirisc trace info\n     Display trace configuration.\n\n -- Command: esirisc trace status\n     Display trace collection status.\n\n -- Command: esirisc trace start\n     Start manual trace collection.\n\n -- Command: esirisc trace stop\n     Stop manual trace collection.\n\n -- Command: esirisc trace analyze [address size]\n     Analyze collected trace data.  This command may only be used if a\n     trace buffer has been configured.  If a trace FIFO has been\n     configured, trace data must be copied to an in-memory buffer\n     identified by the 'address' and 'size' options using DMA.\n\n -- Command: esirisc trace dump [address size] filename\n     Dump collected trace data to file.  This command may only be used\n     if a trace buffer has been configured.  If a trace FIFO has been\n     configured, trace data must be copied to an in-memory buffer\n     identified by the 'address' and 'size' options using DMA.\n\n16.8 Intel Architecture\n=======================\n\nIntel Quark X10xx is the first product in the Quark family of SoCs.  It\nis an IA-32 (Pentium x86 ISA) compatible SoC. The core CPU in the X10xx\nis codenamed Lakemont.  Lakemont version 1 (LMT1) is used in X10xx.  The\nCPU TAP (Lakemont TAP) is used for software debug and the CLTAP is used\nfor SoC level operations.  Useful docs are here:\nhttps://communities.intel.com/community/makers/documentation\n   * Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for\n     doc num 330015)\n   * Intel Quark SoC X1000 Debug Operations User Guide (web search for\n     doc num 329866)\n   * Intel Quark SoC X1000 Datasheet (web search for doc num 329676)\n\n16.8.1 x86 32-bit specific commands\n-----------------------------------\n\nThe three main address spaces for x86 are memory, I/O and configuration\nspace.  These commands allow a user to read and write to the 64Kbyte I/O\naddress space.\n\n -- Command: x86_32 idw address\n     Display the contents of a 32-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 idh address\n     Display the contents of a 16-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 idb address\n     Display the contents of a 8-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 iww address\n     Write the contents of a 32-bit I/O port to address range 0x0000 -\n     0xffff.\n\n -- Command: x86_32 iwh address\n     Write the contents of a 16-bit I/O port to address range 0x0000 -\n     0xffff.\n\n -- Command: x86_32 iwb address\n     Write the contents of a 8-bit I/O port to address range 0x0000 -\n     0xffff.\n\n16.9 OpenRISC Architecture\n==========================\n\nThe OpenRISC CPU is a soft core.  It is used in a programmable SoC which\ncan be configured with any of the TAP / Debug Unit available.\n\n16.9.1 TAP and Debug Unit selection commands\n--------------------------------------------\n\n -- Command: tap_select (vjtag|mohor|xilinx_bscan)\n     Select between the Altera Virtual JTAG , Xilinx Virtual JTAG and\n     Mohor TAP.\n -- Command: du_select (adv|mohor) [option]\n     Select between the Advanced Debug Interface and the classic one.\n\n     An option can be passed as a second argument to the debug unit.\n\n     When using the Advanced Debug Interface, option = 1 means the RTL\n     core is configured with ADBG_USE_HISPEED = 1.  This configuration\n     skips status checking between bytes while doing read or write\n     bursts.\n\n16.9.2 Registers commands\n-------------------------\n\n -- Command: addreg [name] [address] [feature] [reg_group]\n     Add a new register in the cpu register list.  This register will be\n     included in the generated target descriptor file.\n\n     *[feature]* must be \"org.gnu.gdb.or1k.group[0..10]\".\n\n     *[reg_group]* can be anything.  The default register list defines\n     \"system\", \"dmmu\", \"immu\", \"dcache\", \"icache\", \"mac\", \"debug\",\n     \"perf\", \"power\", \"pic\" and \"timer\" groups.\n\n     _example:_\n          addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n16.10 RISC-V Architecture\n=========================\n\nRISC-V (http://riscv.org/) is a free and open ISA. OpenOCD supports JTAG\ndebug of RV32 and RV64 cores in heterogeneous multicore systems of up to\n32 harts.  (It's possible to increase this limit to 1024 by changing\nRISCV_MAX_HARTS in riscv.h.)  OpenOCD primarily supports 0.13 of the\nRISC-V Debug Specification, but there is also support for legacy targets\nthat implement version 0.11.\n\n16.10.1 RISC-V Terminology\n--------------------------\n\nA _hart_ is a hardware thread.  A hart may share resources (eg.  FPU)\nwith another hart, or may be a separate core.  RISC-V treats those the\nsame, and OpenOCD exposes each hart as a separate core.\n\n16.10.2 Vector Registers\n------------------------\n\nFor harts that implement the vector extension, OpenOCD provides access\nto the relevant CSRs, as well as the vector registers (v0-v31).  The\nsize of each vector register is dependent on the value of vlenb.  RISC-V\nallows each vector register to be divided into selected-width elements,\nand this division can be changed at run-time.  Because OpenOCD cannot\nupdate register definitions at run-time, it exposes each vector register\nto gdb as a union of fields of vectors so that users can easily access\nindividual bytes, shorts, words, longs, and quads inside each vector\nregister.  It is left to gdb or higher-level debuggers to present this\ndata in a more intuitive format.\n\nIn the XML register description, the vector registers (when vlenb=16)\nlook as follows:\n\n     <feature name=\"org.gnu.gdb.riscv.vector\">\n     <vector id=\"bytes\" type=\"uint8\" count=\"16\"/>\n     <vector id=\"shorts\" type=\"uint16\" count=\"8\"/>\n     <vector id=\"words\" type=\"uint32\" count=\"4\"/>\n     <vector id=\"longs\" type=\"uint64\" count=\"2\"/>\n     <vector id=\"quads\" type=\"uint128\" count=\"1\"/>\n     <union id=\"riscv_vector\">\n     <field name=\"b\" type=\"bytes\"/>\n     <field name=\"s\" type=\"shorts\"/>\n     <field name=\"w\" type=\"words\"/>\n     <field name=\"l\" type=\"longs\"/>\n     <field name=\"q\" type=\"quads\"/>\n     </union>\n     <reg name=\"v0\" bitsize=\"128\" regnum=\"4162\" save-restore=\"no\"\n             type=\"riscv_vector\" group=\"vector\"/>\n     ...\n     <reg name=\"v31\" bitsize=\"128\" regnum=\"4193\" save-restore=\"no\"\n             type=\"riscv_vector\" group=\"vector\"/>\n     </feature>\n\n16.10.3 RISC-V Debug Configuration Commands\n-------------------------------------------\n\n -- Config Command: riscv expose_csrs n[-m|=name] [...]\n     Configure which CSRs to expose in addition to the standard ones.\n     The CSRs to expose can be specified as individual register numbers\n     or register ranges (inclusive).  For the individually listed CSRs,\n     a human-readable name can optionally be set using the 'n=name'\n     syntax, which will get 'csr_' prepended to it.  If no name is\n     provided, the register will be named 'csr<n>'.\n\n     By default OpenOCD attempts to expose only CSRs that are mentioned\n     in a spec, and then only if the corresponding extension appears to\n     be implemented.  This command can be used if OpenOCD gets this\n     wrong, or if the target implements custom CSRs.\n\n          # Expose a single RISC-V CSR number 128 under the name \"csr128\":\n          $_TARGETNAME expose_csrs 128\n\n          # Expose multiple RISC-V CSRs 128..132 under names \"csr128\" through \"csr132\":\n          $_TARGETNAME expose_csrs 128-132\n\n          # Expose a single RISC-V CSR number 1996 under custom name \"csr_myregister\":\n          $_TARGETNAME expose_csrs 1996=myregister\n\n -- Config Command: riscv expose_custom n[-m|=name] [...]\n     The RISC-V Debug Specification allows targets to expose custom\n     registers through abstract commands.  (See Section 3.5.1.1 in that\n     document.)  This command configures individual registers or\n     register ranges (inclusive) that shall be exposed.  Number 0\n     indicates the first custom register, whose abstract command number\n     is 0xc000.  For individually listed registers, a human-readable\n     name can be optionally provided using the 'n=name' syntax, which\n     will get 'custom_' prepended to it.  If no name is provided, the\n     register will be named 'custom<n>'.\n\n          # Expose one RISC-V custom register with number 0xc010 (0xc000 + 16)\n          # under the name \"custom16\":\n          $_TARGETNAME expose_custom 16\n\n          # Expose a range of RISC-V custom registers with numbers 0xc010 .. 0xc018\n          # (0xc000+16 .. 0xc000+24) under the names \"custom16\" through \"custom24\":\n          $_TARGETNAME expose_custom 16-24\n\n          # Expose one RISC-V custom register with number 0xc020 (0xc000 + 32) under\n          # user-defined name \"custom_myregister\":\n          $_TARGETNAME expose_custom 32=myregister\n\n -- Command: riscv set_command_timeout_sec [seconds]\n     Set the wall-clock timeout (in seconds) for individual commands.\n     The default should work fine for all but the slowest targets (eg.\n     simulators).\n\n -- Command: riscv set_reset_timeout_sec [seconds]\n     Set the maximum time to wait for a hart to come out of reset after\n     reset is deasserted.\n\n -- Command: riscv set_scratch_ram none|[address]\n     Set the address of 16 bytes of scratch RAM the debugger can use, or\n     'none'.  This is used to access 64-bit floating point registers on\n     32-bit targets.\n\n -- Command: riscv set_mem_access method1 [method2] [method3]\n     Specify which RISC-V memory access method(s) shall be used, and in\n     which order of priority.  At least one method must be specified.\n\n     Available methods are:\n        * 'progbuf' - Use RISC-V Debug Program Buffer to access memory.\n        * 'sysbus' - Access memory via RISC-V Debug System Bus\n          interface.\n        * 'abstract' - Access memory via RISC-V Debug abstract commands.\n\n     By default, all memory access methods are enabled in the following\n     order: 'progbuf sysbus abstract'.\n\n     This command can be used to change the memory access methods if the\n     default behavior is not suitable for a particular target.\n\n -- Command: riscv set_enable_virtual on|off\n     When on, memory accesses are performed on physical or virtual\n     memory depending on the current system configuration.  When off\n     (default), all memory accessses are performed on physical memory.\n\n -- Command: riscv set_enable_virt2phys on|off\n     When on (default), memory accesses are performed on physical or\n     virtual memory depending on the current satp configuration.  When\n     off, all memory accessses are performed on physical memory.\n\n -- Command: riscv resume_order normal|reversed\n     Some software assumes all harts are executing nearly continuously.\n     Such software may be sensitive to the order that harts are resumed\n     in.  On harts that don't support hasel, this option allows the user\n     to choose the order the harts are resumed in.  If you are using\n     this option, it's probably masking a race condition problem in your\n     code.\n\n     Normal order is from lowest hart index to highest.  This is the\n     default behavior.  Reversed order is from highest hart index to\n     lowest.\n\n -- Command: riscv set_ir (idcode|dtmcs|dmi) [value]\n     Set the IR value for the specified JTAG register.  This is useful,\n     for example, when using the existing JTAG interface on a Xilinx\n     FPGA by way of BSCANE2 primitives that only permit a limited\n     selection of IR values.\n\n     When utilizing version 0.11 of the RISC-V Debug Specification,\n     'dtmcs' and 'dmi' set the IR values for the DTMCONTROL and DBUS\n     registers, respectively.\n\n -- Command: riscv use_bscan_tunnel value\n     Enable or disable use of a BSCAN tunnel to reach DM. Supply the\n     width of the DM transport TAP's instruction register to enable.\n     Supply a value of 0 to disable.\n\n -- Command: riscv set_ebreakm on|off\n     Control dcsr.ebreakm.  When on (default), M-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n -- Command: riscv set_ebreaks on|off\n     Control dcsr.ebreaks.  When on (default), S-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n -- Command: riscv set_ebreaku on|off\n     Control dcsr.ebreaku.  When on (default), U-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n16.10.4 RISC-V Authentication Commands\n--------------------------------------\n\nThe following commands can be used to authenticate to a RISC-V system.\nEg.  a trivial challenge-response protocol could be implemented as\nfollows in a configuration file, immediately following 'init':\n     set challenge [riscv authdata_read]\n     riscv authdata_write [expr {$challenge + 1}]\n\n -- Command: riscv authdata_read\n     Return the 32-bit value read from authdata.\n\n -- Command: riscv authdata_write value\n     Write the 32-bit value to authdata.\n\n16.10.5 RISC-V DMI Commands\n---------------------------\n\nThe following commands allow direct access to the Debug Module\nInterface, which can be used to interact with custom debug features.\n\n -- Command: riscv dmi_read address\n     Perform a 32-bit DMI read at address, returning the value.\n\n -- Command: riscv dmi_write address value\n     Perform a 32-bit DMI write of value at address.\n\n16.11 ARC Architecture\n======================\n\nSynopsys DesignWare ARC Processors are a family of 32-bit CPUs that SoC\ndesigners can optimize for a wide range of uses, from deeply embedded to\nhigh-performance host applications in a variety of market segments.  See\nmore at:\n<http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/Pages/default.aspx>.\nOpenOCD currently supports ARC EM processors.  There is a set\nARC-specific OpenOCD commands that allow low-level access to the core\nand provide necessary support for ARC extensibility and configurability\ncapabilities.  ARC processors has much more configuration capabilities\nthan most of the other processors and in addition there is an extension\ninterface that allows SoC designers to add custom registers and\ninstructions.  For the OpenOCD that mostly means that set of core and\nAUX registers in target will vary and is not fixed for a particular\nprocessor model.  To enable extensibility several TCL commands are\nprovided that allow to describe those optional registers in OpenOCD\nconfiguration files.  Moreover those commands allow for a dynamic target\nfeatures discovery.\n\n16.11.1 General ARC commands\n----------------------------\n\n -- Config Command: arc add-reg configparams\n\n     Add a new register to processor target.  By default newly created\n     register is marked as not existing.  CONFIGPARAMS must have\n     following required arguments:\n\n        * '-name' name\n          Name of a register.\n\n        * '-num' number\n          Architectural register number: core register number or AUX\n          register number.\n\n        * '-feature' XML_feature\n          Name of GDB XML target description feature.\n\n     CONFIGPARAMS may have following optional arguments:\n\n        * '-gdbnum' number\n          GDB register number.  It is recommended to not assign GDB\n          register number manually, because there would be a risk that\n          two register will have same number.  When register GDB number\n          is not set with this option, then register will get a previous\n          register number + 1.  This option is required only for those\n          registers that must be at particular address expected by GDB.\n\n        * '-core'\n          This option specifies that register is a core registers.  If\n          not - this is an AUX register.  AUX registers and core\n          registers reside in different address spaces.\n\n        * '-bcr'\n          This options specifies that register is a BCR register.  BCR\n          means Build Configuration Registers - this is a special type\n          of AUX registers that are read only and non-volatile, that is\n          - they never change their value.  Therefore OpenOCD never\n          invalidates values of those registers in internal caches.\n          Because BCR is a type of AUX registers, this option cannot be\n          used with '-core'.\n\n        * '-type' type_name\n          Name of type of this register.  This can be either one of the\n          basic GDB types, or a custom types described with 'arc\n          add-reg-type-[flags|struct]'.\n\n        * '-g'\n          If specified then this is a \"general\" register.  General\n          registers are always read by OpenOCD on context save (when\n          core has just been halted) and is always transferred to GDB\n          client in a response to g-packet.  Contrary to this,\n          non-general registers are read and sent to GDB client\n          on-demand.  In general it is not recommended to apply this\n          option to custom registers.\n\n -- Config Command: arc add-reg-type-flags -name name flags...\n     Adds new register type of \"flags\" class.  \"Flags\" types can contain\n     only one-bit fields.  Each flag definition looks like '-flag name\n     bit-position'.\n\n -- Config Command: arc add-reg-type-struct -name name structs...\n     Adds new register type of \"struct\" class.  \"Struct\" types can\n     contain either bit-fields or fields of other types, however at the\n     moment only bit fields are supported.  Structure bit field\n     definition looks like '-bitfield name startbit endbit'.\n\n -- Command: arc get-reg-field reg-name field-name\n     Returns value of bit-field in a register.  Register must be\n     \"struct\" register type, *Note add-reg-type-struct::.  command\n     definition.\n\n -- Command: arc set-reg-exists reg-names...\n     Specify that some register exists.  Any amount of names can be\n     passed as an argument for a single command invocation.\n\n16.11.2 ARC JTAG commands\n-------------------------\n\n -- Command: arc jtag set-aux-reg regnum value\n     This command writes value to AUX register via its number.  This\n     command access register in target directly via JTAG, bypassing any\n     OpenOCD internal caches, therefore it is unsafe to use if that\n     register can be operated by other means.\n\n -- Command: arc jtag set-core-reg regnum value\n     This command is similar to 'arc jtag set-aux-reg' but is for core\n     registers.\n\n -- Command: arc jtag get-aux-reg regnum\n     This command returns the value storded in AUX register via its\n     number.  This commands access register in target directly via JTAG,\n     bypassing any OpenOCD internal caches, therefore it is unsafe to\n     use if that register can be operated by other means.\n\n -- Command: arc jtag get-core-reg regnum\n     This command is similar to 'arc jtag get-aux-reg' but is for core\n     registers.\n\n16.12 STM8 Architecture\n=======================\n\nSTM8 (http://st.com/stm8/) is a 8-bit microcontroller platform from\nSTMicroelectronics, based on a proprietary 8-bit core architecture.\n\nOpenOCD supports debugging STM8 through the STMicroelectronics debug\nprotocol SWIM, *note SWIM: swimtransport.\n\n16.13 Xtensa Architecture\n=========================\n\nXtensa processors are based on a modular, highly flexible 32-bit RISC\narchitecture that can easily scale from a tiny, cache-less controller or\ntask engine to a high-performance SIMD/VLIW DSP provided by Cadence.\n<https://www.cadence.com/en_US/home/tools/ip/tensilica-ip/tensilica-xtensa-controllers-and-extensible-processors.html>.\n\nOpenOCD supports generic Xtensa processors implementation which can be\ncustomized by simply providing vendor-specific core configuration which\ncontrols every configurable Xtensa architecture option, e.g.  number of\naddress registers, exceptions, reduced size instructions support, memory\nbanks configuration etc.  Also OpenOCD supports SMP configurations for\nXtensa processors with any number of cores and allows to configure their\ndebug signals interconnection (so-called \"break/stall networks\") which\ncontrol how debug signals are distributed among cores.  Xtensa \"break\nnetworks\" are compatible with ARM's Cross Trigger Interface (CTI). For\ndebugging code on Xtensa chips OpenOCD uses JTAG protocol.  Currently\nOpenOCD implements several Epsressif Xtensa-based chips of ESP32 family\n(https://www.espressif.com/en/products/socs).\n\n16.13.1 General Xtensa Commands\n-------------------------------\n\n -- Command: xtensa set_permissive (0|1)\n     By default accessing memory beyond defined regions is forbidden.\n     This commnd controls memory access address check.  When set to (1),\n     skips access controls and address range check before read/write\n     memory.\n\n -- Command: xtensa maskisr (on|off)\n     Selects whether interrupts will be disabled during stepping over\n     single instruction.  The default configuration is (off).\n\n -- Command: xtensa smpbreak [none|breakinout|runstall] | [BreakIn]\n          [BreakOut] [RunStallIn] [DebugModeOut]\n     Configures debug signals connection (\"break network\") for currently\n     selected core.\n        * 'none' - Core's \"break/stall network\" is disconnected.  Core\n          is not affected by any debug signal from other cores.\n        * 'breakinout' - Core's \"break network\" is fully connected\n          (break inputs and outputs are enabled).  Core will receive\n          debug break signals from other cores and send such signals to\n          them.  For example when another core is stopped due to\n          breakpoint hit this core will be stopped too and vice versa.\n        * 'runstall' - Core's \"stall network\" is fully connected (stall\n          inputs and outputs are enabled).  This feature is not well\n          implemented and tested yet.\n        * 'BreakIn' - Core's \"break-in\" signal is enabled.  Core will\n          receive debug break signals from other cores.  For example\n          when another core is stopped due to breakpoint hit this core\n          will be stopped too.\n        * 'BreakOut' - Core's \"break-out\" signal is enabled.  Core will\n          send debug break signal to other cores.  For example when this\n          core is stopped due to breakpoint hit other cores with enabled\n          break-in signals will be stopped too.\n        * 'RunStallIn' - Core's \"runstall-in\" signal is enabled.  This\n          feature is not well implemented and tested yet.\n        * 'DebugModeOut' - Core's \"debugmode-out\" signal is enabled.\n          This feature is not well implemented and tested yet.\n\n -- Command: xtensa perfmon_enable <counter_id> <select> [mask]\n          [kernelcnt] [tracelevel]\n     Enable and start performance counter.\n        * 'counter_id' - Counter ID (0-1).\n        * 'select' - Selects performance metric to be counted by the\n          counter, e.g.  0 - CPU cycles, 2 - retired instructions.\n        * 'mask' - Selects input subsets to be counted (counter will\n          increment only once even if more than one condition\n          corresponding to a mask bit occurs).\n        * 'kernelcnt' - 0 - count events with \"CINTLEVEL <= tracelevel\",\n          1 - count events with \"CINTLEVEL > tracelevel\".\n        * 'tracelevel' - Compares this value to \"CINTLEVEL\" when\n          deciding whether to count.\n\n -- Command: xtensa perfmon_dump (counter_id)\n     Dump performance counter value.  If no argument specified, dumps\n     all counters.\n\n -- Command: xtensa tracestart [pc <pcval>/[<maskbitcount>]] [after <n>\n          [ins|words]]\n     Set up and start a HW trace.  Optionally set PC address range to\n     trigger tracing stop when reached during program execution.  This\n     command also allows to specify the amount of data to capture after\n     stop trigger activation.\n        * 'pcval' - PC value which will trigger trace data collection\n          stop.\n        * 'maskbitcount' - PC value mask.\n        * 'n' - Maximum number of instructions/words to capture after\n          trace stop trigger.\n\n -- Command: xtensa tracestop\n     Stop current trace as started by the tracestart command.\n\n -- Command: xtensa tracedump <outfile>\n     Dump trace memory to a file.\n\n16.14 Software Debug Messages and Tracing\n=========================================\n\nOpenOCD can process certain requests from target software, when the\ntarget uses appropriate libraries.  The most powerful mechanism is\nsemihosting, but there is also a lighter weight mechanism using only the\nDCC channel.\n\nCurrently 'target_request debugmsgs' is supported only for 'arm7_9' and\n'cortex_m' cores.  These messages are received as part of target\npolling, so you need to have 'poll on' active to receive them.  They are\nintrusive in that they will affect program execution times.  If that is\na problem, *note ARM Hardware Tracing: armhardwaretracing.\n\nSee 'libdcc' in the contrib dir for more details.  In addition to\nsending strings, characters, and arrays of various size integers from\nthe target, 'libdcc' also exports a software trace point mechanism.  The\ntarget being debugged may issue trace messages which include a 24-bit\n\"trace point\" number.  Trace point support includes two distinct\nmechanisms, each supported by a command:\n\n   * _History_ ...  A circular buffer of trace points can be set up, and\n     then displayed at any time.  This tracks where code has been, which\n     can be invaluable in finding out how some fault was triggered.\n\n     The buffer may overflow, since it collects records continuously.\n     It may be useful to use some of the 24 bits to represent a\n     particular event, and other bits to hold data.\n\n   * _Counting_ ...  An array of counters can be set up, and then\n     displayed at any time.  This can help establish code coverage and\n     identify hot spots.\n\n     The array of counters is directly indexed by the trace point\n     number, so trace points with higher numbers are not counted.\n\nLinux-ARM kernels have a \"Kernel low-level debugging via EmbeddedICE DCC\nchannel\" option (CONFIG_DEBUG_ICEDCC, depends on CONFIG_DEBUG_LL) which\nuses this mechanism to deliver messages before a serial console can be\nactivated.  This is not the same format used by 'libdcc'.  Other\nsoftware, such as the U-Boot boot loader, sometimes does the same thing.\n\n -- Command: target_request debugmsgs [enable|disable|charmsg]\n     Displays current handling of target DCC message requests.  These\n     messages may be sent to the debugger while the target is running.\n     The optional 'enable' and 'charmsg' parameters both enable the\n     messages, while 'disable' disables them.\n\n     With 'charmsg' the DCC words each contain one character, as used by\n     Linux with CONFIG_DEBUG_ICEDCC; otherwise the libdcc format is\n     used.\n\n -- Command: trace history [clear|count]\n     With no parameter, displays all the trace points that have\n     triggered in the order they triggered.  With the parameter 'clear',\n     erases all current trace history records.  With a COUNT parameter,\n     allocates space for that many history records.\n\n -- Command: trace point [clear|identifier]\n     With no parameter, displays all trace point identifiers and how\n     many times they have been triggered.  With the parameter 'clear',\n     erases all current trace point counters.  With a numeric IDENTIFIER\n     parameter, creates a new a trace point counter and associates it\n     with that identifier.\n\n     _Important:_ The identifier and the trace point number are not\n     related except by this command.  These trace point numbers always\n     start at zero (from server startup, or after 'trace point clear')\n     and count up from there.\n\n\u001f\nFile: openocd.info,  Node: JTAG Commands,  Next: Boundary Scan Commands,  Prev: Architecture and Core Commands,  Up: Top\n\n17 JTAG Commands\n****************\n\nMost general purpose JTAG commands have been presented earlier.  (*Note\nJTAG Speed: jtagspeed, *note Reset Configuration::, and *note TAP\nDeclaration::.)  Lower level JTAG commands, as presented here, may be\nneeded to work with targets which require special attention during\noperations such as reset or initialization.\n\nTo use these commands you will need to understand some of the basics of\nJTAG, including:\n\n   * A JTAG scan chain consists of a sequence of individual TAP devices\n     such as a CPUs.\n   * Control operations involve moving each TAP through the same\n     standard state machine (in parallel) using their shared TMS and\n     clock signals.\n   * Data transfer involves shifting data through the chain of\n     instruction or data registers of each TAP, writing new register\n     values while the reading previous ones.\n   * Data register sizes are a function of the instruction active in a\n     given TAP, while instruction register sizes are fixed for each TAP.\n     All TAPs support a BYPASS instruction with a single bit data\n     register.\n   * The way OpenOCD differentiates between TAP devices is by shifting\n     different instructions into (and out of) their instruction\n     registers.\n\n17.1 Low Level JTAG Commands\n============================\n\nThese commands are used by developers who need to access JTAG\ninstruction or data registers, possibly controlling the order of TAP\nstate transitions.  If you're not debugging OpenOCD internals, or\nbringing up a new JTAG adapter or a new type of TAP device (like a CPU\nor JTAG router), you probably won't need to use these commands.  In a\ndebug session that doesn't use JTAG for its transport protocol, these\ncommands are not available.\n\n -- Command: drscan tap [numbits value]+ [-endstate tap_state]\n     Loads the data register of TAP with a series of bit fields that\n     specify the entire register.  Each field is NUMBITS bits long with\n     a numeric VALUE (hexadecimal encouraged).  The return value holds\n     the original value of each of those fields.\n\n     For example, a 38 bit number might be specified as one field of 32\n     bits then one of 6 bits.  _For portability, never pass fields which\n     are more than 32 bits long.  Many OpenOCD implementations do not\n     support 64-bit (or larger) integer values._\n\n     All TAPs other than TAP must be in BYPASS mode.  The single bit in\n     their data registers does not matter.\n\n     When TAP_STATE is specified, the JTAG state machine is left in that\n     state.  For example DRPAUSE might be specified, so that more\n     instructions can be issued before re-entering the RUN/IDLE state.\n     If the end state is not specified, the RUN/IDLE state is entered.\n\n          Warning: OpenOCD does not record information about data\n          register lengths, so _it is important that you get the bit\n          field lengths right_.  Remember that different JTAG\n          instructions refer to different data registers, which may have\n          different lengths.  Moreover, those lengths may not be fixed;\n          the SCAN_N instruction can change the length of the register\n          accessed by the INTEST instruction (by connecting a different\n          scan chain).\n\n -- Command: flush_count\n     Returns the number of times the JTAG queue has been flushed.  This\n     may be used for performance tuning.\n\n     For example, flushing a queue over USB involves a minimum latency,\n     often several milliseconds, which does not change with the amount\n     of data which is written.  You may be able to identify performance\n     problems by finding tasks which waste bandwidth by flushing small\n     transfers too often, instead of batching them into larger\n     operations.\n\n -- Command: irscan [tap instruction]+ [-endstate tap_state]\n     For each TAP listed, loads the instruction register with its\n     associated numeric INSTRUCTION.  (The number of bits in that\n     instruction may be displayed using the 'scan_chain' command.)  For\n     other TAPs, a BYPASS instruction is loaded.\n\n     When TAP_STATE is specified, the JTAG state machine is left in that\n     state.  For example IRPAUSE might be specified, so the data\n     register can be loaded before re-entering the RUN/IDLE state.  If\n     the end state is not specified, the RUN/IDLE state is entered.\n\n          Note: OpenOCD currently supports only a single field for\n          instruction register values, unlike data register values.  For\n          TAPs where the instruction register length is more than 32\n          bits, portable scripts currently must issue only BYPASS\n          instructions.\n\n -- Command: pathmove start_state [next_state ...]\n     Start by moving to START_STATE, which must be one of the _stable_\n     states.  Unless it is the only state given, this will often be the\n     current state, so that no TCK transitions are needed.  Then, in a\n     series of single state transitions (conforming to the JTAG state\n     machine) shift to each NEXT_STATE in sequence, one per TCK cycle.\n     The final state must also be stable.\n\n -- Command: runtest NUM_CYCLES\n     Move to the RUN/IDLE state, and execute at least NUM_CYCLES of the\n     JTAG clock (TCK). Instructions often need some time to execute\n     before they take effect.\n\n -- Command: verify_ircapture (enable|disable)\n     Verify values captured during IRCAPTURE and returned during IR\n     scans.  Default is enabled, but this can be overridden by\n     'verify_jtag'.  This flag is ignored when validating JTAG chain\n     configuration.\n\n -- Command: verify_jtag (enable|disable)\n     Enables verification of DR and IR scans, to help detect programming\n     errors.  For IR scans, 'verify_ircapture' must also be enabled.\n     Default is enabled.\n\n17.2 TAP state names\n====================\n\nThe TAP_STATE names used by OpenOCD in the 'drscan', 'irscan', and\n'pathmove' commands are the same as those used in SVF boundary scan\ndocuments, except that SVF uses IDLE instead of RUN/IDLE.\n\n   * RESET ...  _stable_ (with TMS high); acts as if TRST were pulsed\n   * RUN/IDLE ...  _stable_; don't assume this always means IDLE\n   * DRSELECT\n   * DRCAPTURE\n   * DRSHIFT ...  _stable_; TDI/TDO shifting through the data register\n   * DREXIT1\n   * DRPAUSE ...  _stable_; data register ready for update or more\n     shifting\n   * DREXIT2\n   * DRUPDATE\n   * IRSELECT\n   * IRCAPTURE\n   * IRSHIFT ...  _stable_; TDI/TDO shifting through the instruction\n     register\n   * IREXIT1\n   * IRPAUSE ...  _stable_; instruction register ready for update or\n     more shifting\n   * IREXIT2\n   * IRUPDATE\n\nNote that only six of those states are fully \"stable\" in the face of TMS\nfixed (low except for RESET) and a free-running JTAG clock.  For all the\nothers, the next TCK transition changes to a new state.\n\n   * From DRSHIFT and IRSHIFT, clock transitions will produce side\n     effects by changing register contents.  The values to be latched in\n     upcoming DRUPDATE or IRUPDATE states may not be as expected.\n   * RUN/IDLE, DRPAUSE, and IRPAUSE are reasonable choices after\n     'drscan' or 'irscan' commands, since they are free of JTAG side\n     effects.\n   * RUN/IDLE may have side effects that appear at non-JTAG levels, such\n     as advancing the ARM9E-S instruction pipeline.  Consult the\n     documentation for the TAP(s) you are working with.\n\n\u001f\nFile: openocd.info,  Node: Boundary Scan Commands,  Next: Utility Commands,  Prev: JTAG Commands,  Up: Top\n\n18 Boundary Scan Commands\n*************************\n\nOne of the original purposes of JTAG was to support boundary scan based\nhardware testing.  Although its primary focus is to support On-Chip\nDebugging, OpenOCD also includes some boundary scan commands.\n\n18.1 SVF: Serial Vector Format\n==============================\n\nThe Serial Vector Format, better known as \"SVF\", is a way to represent\nJTAG test patterns in text files.  In a debug session using JTAG for its\ntransport protocol, OpenOCD supports running such test files.\n\n -- Command: svf filename [-tap TAPNAME] [[-]quiet] [[-]nil]\n          [[-]progress] [[-]ignore_error]\n     This issues a JTAG reset (Test-Logic-Reset) and then runs the SVF\n     script from 'filename'.\n\n     Arguments can be specified in any order; the optional dash doesn't\n     affect their semantics.\n\n     Command options:\n        - '-tap TAPNAME' ignore IR and DR headers and footers specified\n          by the SVF file with HIR, TIR, HDR and TDR commands; instead,\n          calculate them automatically according to the current JTAG\n          chain configuration, targeting TAPNAME;\n        - '[-]quiet' do not log every command before execution;\n        - '[-]nil' \"dry run\", i.e., do not perform any operations on the\n          real interface;\n        - '[-]progress' enable progress indication;\n        - '[-]ignore_error' continue execution despite TDO check errors.\n\n18.2 XSVF: Xilinx Serial Vector Format\n======================================\n\nThe Xilinx Serial Vector Format, better known as \"XSVF\", is a binary\nrepresentation of SVF which is optimized for use with Xilinx devices.\nIn a debug session using JTAG for its transport protocol, OpenOCD\nsupports running such test files.\n\n     Important: Not all XSVF commands are supported.\n\n -- Command: xsvf (tapname|plain) filename [virt2] [quiet]\n     This issues a JTAG reset (Test-Logic-Reset) and then runs the XSVF\n     script from 'filename'.  When a TAPNAME is specified, the commands\n     are directed at that TAP. When 'virt2' is specified, the XRUNTEST\n     command counts are interpreted as TCK cycles instead of\n     microseconds.  Unless the 'quiet' option is specified, messages are\n     logged for comments and some retries.\n\nThe OpenOCD sources also include two utility scripts for working with\nXSVF; they are not currently installed after building the software.  You\nmay find them useful:\n\n   * _svf2xsvf_ ...  converts SVF files into the extended XSVF syntax\n     understood by the 'xsvf' command; see notes below.\n   * _xsvfdump_ ...  converts XSVF files into a text output format;\n     understands the OpenOCD extensions.\n\nThe input format accepts a handful of non-standard extensions.  These\ninclude three opcodes corresponding to SVF extensions from Lattice\nSemiconductor (LCOUNT, LDELAY, LDSR), and two opcodes supporting a more\naccurate translation of SVF (XTRST, XWAITSTATE). If _xsvfdump_ shows a\nfile is using those opcodes, it probably will not be usable with other\nXSVF tools.\n\n18.3 IPDBG: JTAG-Host server\n============================\n\nIPDBG is a set of tools to debug IP-Cores.  It comprises, among others,\na logic analyzer and an arbitrary waveform generator.  These are\nsynthesize-able hardware descriptions of logic circuits in addition to\nsoftware for control, visualization and further analysis.  In a session\nusing JTAG for its transport protocol, OpenOCD supports the function of\na JTAG-Host.  The JTAG-Host is needed to connect the circuit over JTAG\nto the control-software.  For more details see <http://ipdbg.org>.\n\n -- Command: ipdbg [-start|-stop] -tap TAPNAME -hub IR_VALUE [DR_LENGTH]\n          [-port NUMBER] [-tool NUMBER] [-vir [VIR_VALUE [LENGTH\n          [INSTR_CODE]]]]\n     Starts or stops a IPDBG JTAG-Host server.  Arguments can be\n     specified in any order.\n\n     Command options:\n        * '-start|-stop' starts or stops a IPDBG JTAG-Host server\n          (default: start).\n        * '-tap TAPNAME' targeting the TAP TAPNAME.\n        * '-hub IR_VALUE' states that the JTAG hub is reachable with\n          dr-scans while the JTAG instruction register has the value\n          IR_VALUE.\n        * '-port NUMBER' tcp port number where the JTAG-Host is\n          listening.\n        * '-tool NUMBER' number of the tool/feature.  These corresponds\n          to the ports \"data_(up/down)_(0..6)\" at the JtagHub.\n        * '-vir [VIR_VALUE [LENGTH [INSTR_CODE]]]' On some devices, the\n          user data-register is only reachable if there is a specific\n          value in a second dr.  This second dr is called vir (virtual\n          ir).  With this parameter given, the IPDBG satisfies this\n          condition prior an access to the IPDBG-Hub.  The value shifted\n          into the vir is given by the first parameter VIR_VALUE\n          (default: 0x11).  The second parameter LENGTH is the length of\n          the vir data register (default: 5).  With the INSTR_CODE\n          (default: 0x00e) parameter the ir value to shift data through\n          vir can be configured.\n\nExamples:\n     ipdbg -start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4\nStarts a server listening on tcp-port 4242 which connects to tool 4.\nThe connection is through the TAP of a Xilinx Spartan 6 on USER1\ninstruction (tested with a papillion pro board).\n\n     ipdbg -start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1\nStarts a server listening on tcp-port 60000 which connects to tool 1\n(data_up_1/data_down_1).  The connection is through the TAP of a Intel\nMAX10 virtual jtag component (sld_instance_index is 0; sld_ir_width is\nsmaller than 5).\n\n\u001f\nFile: openocd.info,  Node: Utility Commands,  Next: GDB and OpenOCD,  Prev: Boundary Scan Commands,  Up: Top\n\n19 Utility Commands\n*******************\n\n19.1 RAM testing\n================\n\nThere is often a need to stress-test random access memory (RAM) for\nerrors.  OpenOCD comes with a Tcl implementation of well-known memory\ntesting procedures allowing the detection of all sorts of issues with\nelectrical wiring, defective chips, PCB layout and other common hardware\nproblems.\n\nTo use them, you usually need to initialise your RAM controller first;\nconsult your SoC's documentation to get the recommended list of register\noperations and translate them to the corresponding 'mww'/'mwb' commands.\n\nLoad the memory testing functions with\n\n     source [find tools/memtest.tcl]\n\nto get access to the following facilities:\n\n -- Command: memTestDataBus address\n     Test the data bus wiring in a memory region by performing a walking\n     1's test at a fixed address within that region.\n\n -- Command: memTestAddressBus baseaddress size\n     Perform a walking 1's test on the relevant bits of the address and\n     check for aliasing.  This test will find single-bit address\n     failures such as stuck-high, stuck-low, and shorted pins.\n\n -- Command: memTestDevice baseaddress size\n     Test the integrity of a physical memory device by performing an\n     increment/decrement test over the entire region.  In the process\n     every storage bit in the device is tested as zero and as one.\n\n -- Command: runAllMemTests baseaddress size\n     Run all of the above tests over a specified memory region.\n\n19.2 Firmware recovery helpers\n==============================\n\nOpenOCD includes an easy-to-use script to facilitate mass-market devices\nrecovery with JTAG.\n\nFor quickstart instructions run:\n     openocd -f tools/firmware-recovery.tcl -c firmware_help\n\n\u001f\nFile: openocd.info,  Node: GDB and OpenOCD,  Next: Tcl Scripting API,  Prev: Utility Commands,  Up: Top\n\n20 GDB and OpenOCD\n******************\n\nOpenOCD complies with the remote gdbserver protocol and, as such, can be\nused to debug remote targets.  Setting up GDB to work with OpenOCD can\ninvolve several components:\n\n   * The OpenOCD server support for GDB may need to be configured.\n     *Note GDB Configuration: gdbconfiguration.\n   * GDB's support for OpenOCD may need configuration, as shown in this\n     chapter.\n   * If you have a GUI environment like Eclipse, that also will probably\n     need to be configured.\n\nOf course, the version of GDB you use will need to be one which has been\nbuilt to know about the target CPU you're using.  It's probably part of\nthe tool chain you're using.  For example, if you are doing\ncross-development for ARM on an x86 PC, instead of using the native x86\n'gdb' command you might use 'arm-none-eabi-gdb' if that's the tool chain\nused to compile your code.\n\n20.1 Connecting to GDB\n======================\n\nUse GDB 6.7 or newer with OpenOCD if you run into trouble.  For instance\nGDB 6.3 has a known bug that produces bogus memory access errors, which\nhas since been fixed; see\n<http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html>\n\nOpenOCD can communicate with GDB in two ways:\n\n  1. A socket (TCP/IP) connection is typically started as follows:\n          target extended-remote localhost:3333\n     This would cause GDB to connect to the gdbserver on the local pc\n     using port 3333.\n\n     The extended remote protocol is a super-set of the remote protocol\n     and should be the preferred choice.  More details are available in\n     GDB documentation\n     <https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html>\n\n     To speed-up typing, any GDB command can be abbreviated, including\n     the extended remote command above that becomes:\n          tar ext :3333\n\n     Note: If any backward compatibility issue requires using the old\n     remote protocol in place of the extended remote one, the former\n     protocol is still available through the command:\n          target remote localhost:3333\n\n  2. A pipe connection is typically started as follows:\n          target extended-remote | \\\n                 openocd -c \"gdb_port pipe; log_output openocd.log\"\n     This would cause GDB to run OpenOCD and communicate using pipes\n     (stdin/stdout).  Using this method has the advantage of GDB\n     starting/stopping OpenOCD for the debug session.  log_output sends\n     the log output to a file to ensure that the pipe is not saturated\n     when using higher debug level outputs.\n\nTo list the available OpenOCD commands type 'monitor help' on the GDB\ncommand line.\n\n20.2 Sample GDB session startup\n===============================\n\nWith the remote protocol, GDB sessions start a little differently than\nthey do when you're debugging locally.  Here's an example showing how to\nstart a debug session with a small ARM program.  In this case the\nprogram was linked to be loaded into SRAM on a Cortex-M3.  Most programs\nwould be written into flash (address 0) and run from there.\n\n     $ arm-none-eabi-gdb example.elf\n     (gdb) target extended-remote localhost:3333\n     Remote debugging using localhost:3333\n     ...\n     (gdb) monitor reset halt\n     ...\n     (gdb) load\n     Loading section .vectors, size 0x100 lma 0x20000000\n     Loading section .text, size 0x5a0 lma 0x20000100\n     Loading section .data, size 0x18 lma 0x200006a0\n     Start address 0x2000061c, load size 1720\n     Transfer rate: 22 KB/sec, 573 bytes/write.\n     (gdb) continue\n     Continuing.\n     ...\n\nYou could then interrupt the GDB session to make the program break, type\n'where' to show the stack, 'list' to show the code around the program\ncounter, 'step' through code, set breakpoints or watchpoints, and so on.\n\n20.3 Configuring GDB for OpenOCD\n================================\n\nOpenOCD supports the gdb 'qSupported' packet, this enables information\nto be sent by the GDB remote server (i.e.  OpenOCD) to GDB. Typical\ninformation includes packet size and the device's memory map.  You do\nnot need to configure the packet size by hand, and the relevant parts of\nthe memory map should be automatically set up when you declare (NOR)\nflash banks.\n\nHowever, there are other things which GDB can't currently query.  You\nmay need to set those up by hand.  As OpenOCD starts up, you will often\nsee a line reporting something like:\n\n     Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints\n\nYou can pass that information to GDB with these commands:\n\n     set remote hardware-breakpoint-limit 6\n     set remote hardware-watchpoint-limit 4\n\nWith that particular hardware (Cortex-M3) the hardware breakpoints only\nwork for code running from flash memory.  Most other ARM systems do not\nhave such restrictions.\n\nRather than typing such commands interactively, you may prefer to save\nthem in a file and have GDB execute them as it starts, perhaps using a\n'.gdbinit' in your project directory or starting GDB using 'gdb -x\nfilename'.\n\n20.4 Programming using GDB\n==========================\n\nBy default the target memory map is sent to GDB. This can be disabled by\nthe following OpenOCD configuration option:\n     gdb_memory_map disable\nFor this to function correctly a valid flash configuration must also be\nset in OpenOCD. For faster performance you should also configure a valid\nworking area.\n\nInforming GDB of the memory map of the target will enable GDB to protect\nany flash areas of the target and use hardware breakpoints by default.\nThis means that the OpenOCD option 'gdb_breakpoint_override' is not\nrequired when using a memory map.  *Note gdb_breakpoint_override:\ngdbbreakpointoverride.\n\nTo view the configured memory map in GDB, use the GDB command 'info\nmem'.  All other unassigned addresses within GDB are treated as RAM.\n\nGDB 6.8 and higher set any memory area not in the memory map as\ninaccessible.  This can be changed to the old behaviour by using the\nfollowing GDB command\n     set mem inaccessible-by-default off\n\nIf 'gdb_flash_program enable' is also used, GDB will be able to program\nany flash memory using the vFlash interface.\n\nGDB will look at the target memory map when a load command is given, if\nany areas to be programmed lie within the target flash area the vFlash\npackets will be used.\n\nIf the target needs configuring before GDB programming, set target event\ngdb-flash-erase-start:\n     $_TARGETNAME configure -event gdb-flash-erase-start BODY\n*Note Target Events: targetevents, for other GDB programming related\nevents.\n\nTo verify any flash programming the GDB command 'compare-sections' can\nbe used.\n\n20.5 Using GDB as a non-intrusive memory inspector\n==================================================\n\nIf your project controls more than a blinking LED, let's say a heavy\nindustrial robot or an experimental nuclear reactor, stopping the\ncontrolling process just because you want to attach GDB is not a good\noption.\n\nOpenOCD does not support GDB non-stop mode (might be implemented in the\nfuture).  Though there is a possible setup where the target does not get\nstopped and GDB treats it as it were running.  If the target supports\nbackground access to memory while it is running, you can use GDB in this\nmode to inspect memory (mainly global variables) without any intrusion\nof the target process.\n\nRemove default setting of gdb-attach event.  *Note Target Events:\ntargetevents.  Place following command after target configuration:\n     $_TARGETNAME configure -event gdb-attach {}\n\nIf any of installed flash banks does not support probe on running\ntarget, switch off gdb_memory_map:\n     gdb_memory_map disable\n\nEnsure GDB is configured without interrupt-on-connect.  Some GDB\nversions set it by default, some does not.\n     set remote interrupt-on-connect off\n\nIf you switched gdb_memory_map off, you may want to setup GDB memory map\nmanually or issue 'set mem inaccessible-by-default off'\n\nNow you can issue GDB command 'target extended-remote ...' and inspect\nmemory of a running target.  Do not use GDB commands 'continue', 'step'\nor 'next' as they synchronize GDB with your target and GDB would require\nstopping the target to get the prompt back.\n\nDo not use this mode under an IDE like Eclipse as it caches values of\npreviously shown variables.\n\nIt's also possible to connect more than one GDB to the same target by\nthe target's configuration option '-gdb-max-connections'.  This allows,\nfor example, one GDB to run a script that continuously polls a set of\nvariables while other GDB can be used interactively.  Be extremely\ncareful in this case, because the two GDB can easily get out-of-sync.\n\n20.6 RTOS Support\n=================\n\nOpenOCD includes RTOS support, this will however need enabling as it\ndefaults to disabled.  It can be enabled by passing '-rtos' arg to the\ntarget.  *Note RTOS Type: rtostype.\n\n*Note Debugging Programs with Multiple Threads: (gdb)Threads, for\ndetails about relevant GDB commands.\n\n\nAn example setup is below:\n\n     $_TARGETNAME configure -rtos auto\n\nThis will attempt to auto detect the RTOS within your application.\n\nCurrently supported rtos's include:\n   * 'eCos'\n   * 'ThreadX'\n   * 'FreeRTOS'\n   * 'linux'\n   * 'ChibiOS'\n   * 'embKernel'\n   * 'mqx'\n   * 'uCOS-III'\n   * 'nuttx'\n   * 'RIOT'\n   * 'hwthread' (This is not an actual RTOS. *Note Using OpenOCD SMP\n     with GDB: usingopenocdsmpwithgdb.)\n   * 'Zephyr'\n\nBefore an RTOS can be detected, it must export certain symbols;\notherwise, it cannot be used by OpenOCD. Below is a list of the required\nsymbols for each supported RTOS.\n\n'eCos symbols'\n     Cyg_Thread::thread_list, Cyg_Scheduler_Base::current_thread.\n'ThreadX symbols'\n     _tx_thread_current_ptr, _tx_thread_created_ptr,\n     _tx_thread_created_count.\n'FreeRTOS symbols'\n     pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1,\n     xDelayedTaskList2, pxDelayedTaskList, pxOverflowDelayedTaskList,\n     xPendingReadyList, uxCurrentNumberOfTasks, uxTopUsedPriority.\n'linux symbols'\n     init_task.\n'ChibiOS symbols'\n     rlist, ch_debug, chSysInit.\n'embKernel symbols'\n     Rtos::sCurrentTask, Rtos::sListReady, Rtos::sListSleep,\n     Rtos::sListSuspended, Rtos::sMaxPriorities,\n     Rtos::sCurrentTaskCount.\n'mqx symbols'\n     _mqx_kernel_data, MQX_init_struct.\n'uC/OS-III symbols'\n     OSRunning, OSTCBCurPtr, OSTaskDbgListPtr, OSTaskQty.\n'nuttx symbols'\n     g_readytorun, g_tasklisttable.\n'RIOT symbols'\n     sched_threads, sched_num_threads, sched_active_pid, max_threads,\n     _tcb_name_offset.\n'Zephyr symbols'\n     _kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size\n\nFor most RTOS supported the above symbols will be exported by default.\nHowever for some, eg.  FreeRTOS, uC/OS-III and Zephyr, extra steps must\nbe taken.\n\nZephyr must be compiled with the DEBUG_THREAD_INFO option.  This will\ngenerate some symbols with information needed in order to build the list\nof threads.\n\nFreeRTOS and uC/OS-III RTOSes may require additional OpenOCD-specific\nfile to be linked along with the project:\n\n'FreeRTOS'\n     contrib/rtos-helpers/FreeRTOS-openocd.c\n'uC/OS-III'\n     contrib/rtos-helpers/uCOS-III-openocd.c\n\n20.7 Using OpenOCD SMP with GDB\n===============================\n\nOpenOCD includes a pseudo RTOS called _hwthread_ that presents CPU cores\n(\"hardware threads\") in an SMP system as threads to GDB. With this\nextension, GDB can be used to inspect the state of an SMP system in a\nnatural way.  After halting the system, using the GDB command 'info\nthreads' will list the context of each active CPU core in the system.\nGDB's 'thread' command can be used to switch the view to a different CPU\ncore.  The 'step' and 'stepi' commands can be used to step a specific\ncore while other cores are free-running or remain halted, depending on\nthe scheduler-locking mode configured in GDB.\n\n\u001f\nFile: openocd.info,  Node: Tcl Scripting API,  Next: FAQ,  Prev: GDB and OpenOCD,  Up: Top\n\n21 Tcl Scripting API\n********************\n\n21.1 API rules\n==============\n\nTcl commands are stateless; e.g.  the 'telnet' command has a concept of\ncurrently active target, the Tcl API proc's take this sort of state\ninformation as an argument to each proc.\n\nThere are three main types of return values: single value, name value\npair list and lists.\n\nName value pair.  The proc 'foo' below returns a name/value pair list.\n\n     >  set foo(me)  Duane\n     >  set foo(you) Oyvind\n     >  set foo(mouse) Micky\n     >  set foo(duck) Donald\n\nIf one does this:\n\n     >  set foo\n\nThe result is:\n\n     me Duane you Oyvind mouse Micky duck Donald\n\nThus, to get the names of the associative array is easy:\n\nforeach { name value } [set foo] {\n        puts \"Name: $name, Value: $value\"\n}\n\nLists returned should be relatively small.  Otherwise, a range should be\npassed in to the proc in question.\n\n21.2 Internal low-level Commands\n================================\n\nBy \"low-level\", we mean commands that a human would typically not invoke\ndirectly.\n\n   * flash banks <DRIVER> <BASE> <SIZE> <CHIP_WIDTH> <BUS_WIDTH>\n     <TARGET> ['driver options' ...]\n\n     Return information about the flash banks\n\n   * capture <COMMAND>\n\n     Run <COMMAND> and return full log output that was produced during\n     its execution.  Example:\n\n          > capture \"reset init\"\n\nOpenOCD commands can consist of two words, e.g.  \"flash banks\".  The\n'startup.tcl' \"unknown\" proc will translate this into a Tcl proc called\n\"flash_banks\".\n\n21.3 Tcl RPC server\n===================\n\nOpenOCD provides a simple RPC server that allows to run arbitrary Tcl\ncommands and receive the results.\n\nTo access it, your application needs to connect to a configured TCP port\n(see 'tcl_port').  Then it can pass any string to the interpreter\nterminating it with '0x1a' and wait for the return value (it will be\nterminated with '0x1a' as well).  This can be repeated as many times as\ndesired without reopening the connection.\n\nIt is not needed anymore to prefix the OpenOCD commands with 'ocd_' to\nget the results back.  But sometimes you might need the 'capture'\ncommand.\n\nSee 'contrib/rpc_examples/' for specific client implementations.\n\n21.4 Tcl RPC server notifications\n=================================\n\nNotifications are sent asynchronously to other commands being executed\nover the RPC server, so the port must be polled continuously.\n\nTarget event, state and reset notifications are emitted as Tcl\nassociative arrays in the following format.\n\ntype target_event event [event-name]\ntype target_state state [state-name]\ntype target_reset mode [reset-mode]\n\n -- Command: tcl_notifications [on/off]\n     Toggle output of target notifications to the current Tcl RPC\n     server.  Only available from the Tcl RPC server.  Defaults to off.\n\n21.5 Tcl RPC server trace output\n================================\n\nTrace data is sent asynchronously to other commands being executed over\nthe RPC server, so the port must be polled continuously.\n\nTarget trace data is emitted as a Tcl associative array in the following\nformat.\n\ntype target_trace data [trace-data-hex-encoded]\n\n -- Command: tcl_trace [on/off]\n     Toggle output of target trace data to the current Tcl RPC server.\n     Only available from the Tcl RPC server.  Defaults to off.\n\n     See an example application here:\n     <https://github.com/apmorton/OpenOcdTraceUtil> [OpenOcdTraceUtil]\n\n\u001f\nFile: openocd.info,  Node: FAQ,  Next: Tcl Crash Course,  Prev: Tcl Scripting API,  Up: Top\n\n22 FAQ\n******\n\n  1. RTCK, also known as: Adaptive Clocking - What is it?\n\n     In digital circuit design it is often referred to as \"clock\n     synchronisation\" the JTAG interface uses one clock (TCK or TCLK)\n     operating at some speed, your CPU target is operating at another.\n     The two clocks are not synchronised, they are \"asynchronous\"\n\n     In order for the two to work together they must be synchronised\n     well enough to work; JTAG can't go ten times faster than the CPU,\n     for example.  There are 2 basic options:\n       1. Use a special \"adaptive clocking\" circuit to change the JTAG\n          clock rate to match what the CPU currently supports.\n       2. The JTAG clock must be fixed at some speed that's enough\n          slower than the CPU clock that all TMS and TDI transitions can\n          be detected.\n\n     Does this really matter?  For some chips and some situations, this\n     is a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link; the\n     CPU has no difficulty keeping up with JTAG. Startup sequences are\n     often problematic though, as are other situations where the CPU\n     clock rate changes (perhaps to save power).\n\n     For example, Atmel AT91SAM chips start operation from reset with a\n     32kHz system clock.  Boot firmware may activate the main oscillator\n     and PLL before switching to a faster clock (perhaps that 500 MHz\n     ARM926 scenario).  If you're using JTAG to debug that startup\n     sequence, you must slow the JTAG clock to sometimes 1 to 4kHz.\n     After startup completes, JTAG can use a faster clock.\n\n     Consider also debugging a 500MHz ARM926 hand held battery powered\n     device that enters a low power \"deep sleep\" mode, at 32kHz CPU\n     clock, between keystrokes unless it has work to do.  When would\n     that 5 MHz JTAG clock be usable?\n\n     Solution #1 - A special circuit\n\n     In order to make use of this, your CPU, board, and JTAG adapter\n     must all support the RTCK feature.  Not all of them support this;\n     keep reading!\n\n     The RTCK (\"Return TCK\") signal in some ARM chips is used to help\n     with this problem.  ARM has a good description of the problem\n     described at this link:\n     <http://www.arm.com/support/faqdev/4170.html> [checked\n     28/nov/2008].  Link title: \"How does the JTAG synchronisation logic\n     work?  / how does adaptive clocking work?\".\n\n     The nice thing about adaptive clocking is that \"battery powered\n     hand held device example\" - the adaptiveness works perfectly all\n     the time.  One can set a break point or halt the system in the deep\n     power down code, slow step out until the system speeds up.\n\n     Note that adaptive clocking may also need to work at the board\n     level, when a board-level scan chain has multiple chips.  Parallel\n     clock voting schemes are good way to implement this, both within\n     and between chips, and can easily be implemented with a CPLD. It's\n     not difficult to have logic fan a module's input TCK signal out to\n     each TAP in the scan chain, and then wait until each TAP's RTCK\n     comes back with the right polarity before changing the output RTCK\n     signal.  Texas Instruments makes some clock voting logic available\n     for free (with no support) in VHDL form; see\n     <http://tiexpressdsp.com/index.php/Adaptive_Clocking>\n\n     Solution #2 - Always works - but may be slower\n\n     Often this is a perfectly acceptable solution.\n\n     In most simple terms: Often the JTAG clock must be 1/10 to 1/12 of\n     the target clock speed.  But what that \"magic division\" is varies\n     depending on the chips on your board.  ARM rule of thumb Most ARM\n     based systems require an 6:1 division; ARM11 cores use an 8:1\n     division.  Xilinx rule of thumb is 1/12 the clock speed.\n\n     Note: most full speed FT2232 based JTAG adapters are limited to a\n     maximum of 6MHz.  The ones using USB high speed chips (FT2232H)\n     often support faster clock rates (and adaptive clocking).\n\n     You can still debug the 'low power' situations - you just need to\n     either use a fixed and very slow JTAG clock rate ...  or else\n     manually adjust the clock speed at every step.  (Adjusting is\n     painful and tedious, and is not always practical.)\n\n     It is however easy to \"code your way around it\" - i.e.: Cheat a\n     little, have a special debug mode in your application that does a\n     \"high power sleep\".  If you are careful - 98% of your problems can\n     be debugged this way.\n\n     Note that on ARM you may need to avoid using the _wait for\n     interrupt_ operation in your idle loops even if you don't otherwise\n     change the CPU clock rate.  That operation gates the CPU clock, and\n     thus the JTAG clock; which prevents JTAG access.  One consequence\n     is not being able to 'halt' cores which are executing that _wait\n     for interrupt_ operation.\n\n     To set the JTAG frequency use the command:\n\n          # Example: 1.234MHz\n          adapter speed 1234\n\n  2. Win32 Pathnames Why don't backslashes work in Windows paths?\n\n     OpenOCD uses Tcl and a backslash is an escape char.  Use { and }\n     around Windows filenames.\n\n          > echo \\a\n\n          > echo {\\a}\n          \\a\n          > echo \"\\a\"\n\n          >\n\n  3. Missing: cygwin1.dll OpenOCD complains about a missing cygwin1.dll.\n\n     Make sure you have Cygwin installed, or at least a version of\n     OpenOCD that claims to come with all the necessary DLLs.  When\n     using Cygwin, try launching OpenOCD from the Cygwin shell.\n\n  4. Breakpoint Issue I'm trying to set a breakpoint using GDB (or a\n     front-end like Insight or Eclipse), but OpenOCD complains that\n     \"Info: arm7_9_common.c:213 arm7_9_add_breakpoint(): sw breakpoint\n     requested, but software breakpoints not enabled\".\n\n     GDB issues software breakpoints when a normal breakpoint is\n     requested, or to implement source-line single-stepping.  On ARMv4T\n     systems, like ARM7TDMI, ARM720T or ARM920T, software breakpoints\n     consume one of the two available hardware breakpoints.\n\n  5. LPC2000 Flash When erasing or writing LPC2000 on-chip flash, the\n     operation fails at random.\n\n     Make sure the core frequency specified in the 'flash lpc2000' line\n     matches the clock at the time you're programming the flash.  If\n     you've specified the crystal's frequency, make sure the PLL is\n     disabled.  If you've specified the full core speed (e.g.  60MHz),\n     make sure the PLL is enabled.\n\n  6. Amontec Chameleon When debugging using an Amontec Chameleon in its\n     JTAG Accelerator configuration, I keep getting \"Error:\n     amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed out\n     while waiting for end of scan, rtck was disabled\".\n\n     Make sure your PC's parallel port operates in EPP mode.  You might\n     have to try several settings in your PC BIOS (ECP, EPP, and\n     different versions of those).\n\n  7. Data Aborts When debugging with OpenOCD and GDB (plain GDB,\n     Insight, or Eclipse), I get lots of \"Error: arm7_9_common.c:1771\n     arm7_9_read_memory(): memory read caused data abort\".\n\n     The errors are non-fatal, and are the result of GDB trying to trace\n     stack frames beyond the last valid frame.  It might be possible to\n     prevent this by setting up a proper \"initial\" stack frame, if you\n     happen to know what exactly has to be done, feel free to add this\n     here.\n\n     Simple: In your startup code - push 8 registers of zeros onto the\n     stack before calling main().  What GDB is doing is \"climbing\" the\n     run time stack by reading various values on the stack using the\n     standard call frame for the target.  GDB keeps going - until one of\n     2 things happen #1 an invalid frame is found, or #2 some huge\n     number of stackframes have been processed.  By pushing zeros on the\n     stack, GDB gracefully stops.\n\n     Debugging Interrupt Service Routines - In your ISR before you call\n     your C code, do the same - artificially push some zeros onto the\n     stack, remember to pop them off when the ISR is done.\n\n     Also note: If you have a multi-threaded operating system, they\n     often do not in the interest of saving memory waste these few\n     bytes.  Painful...\n\n  8. JTAG Reset Config I get the following message in the OpenOCD\n     console (or log file): \"Warning: arm7_9_common.c:679\n     arm7_9_assert_reset(): srst resets test logic, too\".\n\n     This warning doesn't indicate any serious problem, as long as you\n     don't want to debug your core right out of reset.  Your .cfg file\n     specified 'reset_config trst_and_srst srst_pulls_trst' to tell\n     OpenOCD that either your board, your debugger or your target uC\n     (e.g.  LPC2000) can't assert the two reset signals independently.\n     With this setup, it's not possible to halt the core right out of\n     reset, everything else should work fine.\n\n  9. USB Power When using OpenOCD in conjunction with Amontec JTAGkey\n     and the Yagarto toolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the\n     debugging seems to be unstable.  When single-stepping over large\n     blocks of code, GDB and OpenOCD quit with an error message.  Is\n     there a stability issue with OpenOCD?\n\n     No, this is not a stability issue concerning OpenOCD. Most users\n     have solved this issue by simply using a self-powered USB hub,\n     which they connect their Amontec JTAGkey to.  Apparently, some\n     computers do not provide a USB power supply stable enough for the\n     Amontec JTAGkey to be operated.\n\n     Laptops running on battery have this problem too...\n\n  10. GDB Disconnects When using the Amontec JTAGkey, sometimes OpenOCD\n     crashes with the following error message: \"Error: gdb_server.c:101\n     gdb_get_char(): read: 10054\".  What does that mean and what might\n     be the reason for this?\n\n     Error code 10054 corresponds to WSAECONNRESET, which means that the\n     debugger (GDB) has closed the connection to OpenOCD. This might be\n     a GDB issue.\n\n  11. LPC2000 Flash In the configuration file in the section where flash\n     device configurations are described, there is a parameter for\n     specifying the clock frequency for LPC2000 internal flash devices\n     (e.g.  'flash bank $_FLASHNAME lpc2000 0x0 0x40000 0 0 $_TARGETNAME\n     lpc2000_v1 14746 calc_checksum'), which must be specified in\n     kilohertz.  However, I do have a quartz crystal of a frequency that\n     contains fractions of kilohertz (e.g.  14,745,600 Hz, i.e.\n     14,745.600 kHz).  Is it possible to specify real numbers for the\n     clock frequency?\n\n     No.  The clock frequency specified here must be given as an\n     integral number.  However, this clock frequency is used by the\n     In-Application-Programming (IAP) routines of the LPC2000 family\n     only, which seems to be very tolerant concerning the given clock\n     frequency, so a slight difference between the specified clock\n     frequency and the actual clock frequency will not cause any\n     trouble.\n\n  12. Command Order Do I have to keep a specific order for the commands\n     in the configuration file?\n\n     Well, yes and no.  Commands can be given in arbitrary order, yet\n     the devices listed for the JTAG scan chain must be given in the\n     right order (jtag newdevice), with the device closest to the\n     TDO-Pin being listed first.  In general, whenever objects of the\n     same type exist which require an index number, then these objects\n     must be given in the right order (jtag newtap, targets and flash\n     banks - a target references a jtag newtap and a flash bank\n     references a target).\n\n     You can use the \"scan_chain\" command to verify and display the tap\n     order.\n\n     Also, some commands can't execute until after 'init' has been\n     processed.  Such commands include 'nand probe' and everything else\n     that needs to write to controller registers, perhaps for setting up\n     DRAM and loading it with code.\n\n  13. JTAG TAP Order Do I have to declare the TAPS in some particular\n     order?\n\n     Yes; whenever you have more than one, you must declare them in the\n     same order used by the hardware.\n\n     Many newer devices have multiple JTAG TAPs.  For example:\n     STMicroelectronics STM32 chips have two TAPs, a \"boundary scan TAP\"\n     and \"Cortex-M3\" TAP. Example: The STM32 reference manual, Document\n     ID: RM0008, Section 26.5, Figure 259, page 651/681, the \"TDI\" pin\n     is connected to the boundary scan TAP, which then connects to the\n     Cortex-M3 TAP, which then connects to the TDO pin.\n\n     Thus, the proper order for the STM32 chip is: (1) The Cortex-M3,\n     then (2) The boundary scan TAP. If your board includes an\n     additional JTAG chip in the scan chain (for example a Xilinx CPLD\n     or FPGA) you could place it before or after the STM32 chip in the\n     chain.  For example:\n\n        * OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input)\n        * STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input)\n        * STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin\n        * STM32 TDO Pin (output) -> Xilinx TDI Pin (input)\n        * Xilinx TDO Pin -> OpenOCD TDO (input)\n\n     The \"jtag device\" commands would thus be in the order shown below.\n     Note:\n\n        * jtag newtap Xilinx tap -irlen ...\n        * jtag newtap stm32 cpu -irlen ...\n        * jtag newtap stm32 bs -irlen ...\n        * # Create the debug target and say where it is\n        * target create stm32.cpu -chain-position stm32.cpu ...\n\n  14. SYSCOMP Sometimes my debugging session terminates with an error.\n     When I look into the log file, I can see these error messages:\n     Error: arm7_9_common.c:561 arm7_9_execute_sys_speed(): timeout\n     waiting for SYSCOMP\n\n     TODO.\n\n\u001f\nFile: openocd.info,  Node: Tcl Crash Course,  Next: License,  Prev: FAQ,  Up: Top\n\n23 Tcl Crash Course\n*******************\n\nNot everyone knows Tcl - this is not intended to be a replacement for\nlearning Tcl, the intent of this chapter is to give you some idea of how\nthe Tcl scripts work.\n\nThis chapter is written with two audiences in mind.  (1) OpenOCD users\nwho need to understand a bit more of how Jim-Tcl works so they can do\nsomething useful, and (2) those that want to add a new command to\nOpenOCD.\n\n23.1 Tcl Rule #1\n================\n\nThere is a famous joke, it goes like this:\n  1. Rule #1: The wife is always correct\n  2. Rule #2: If you think otherwise, See Rule #1\n\nThe Tcl equal is this:\n\n  1. Rule #1: Everything is a string\n  2. Rule #2: If you think otherwise, See Rule #1\n\nAs in the famous joke, the consequences of Rule #1 are profound.  Once\nyou understand Rule #1, you will understand Tcl.\n\n23.2 Tcl Rule #1b\n=================\n\nThere is a second pair of rules.\n  1. Rule #1: Control flow does not exist.  Only commands\n     For example: the classic FOR loop or IF statement is not a control\n     flow item, they are commands, there is no such thing as control\n     flow in Tcl.\n  2. Rule #2: If you think otherwise, See Rule #1\n     Actually what happens is this: There are commands that by\n     convention, act like control flow key words in other languages.\n     One of those commands is the word \"for\", another command is \"if\".\n\n23.3 Per Rule #1 - All Results are strings\n==========================================\n\nEvery Tcl command results in a string.  The word \"result\" is used\ndeliberately.  No result is just an empty string.  Remember: Rule #1 -\nEverything is a string\n\n23.4 Tcl Quoting Operators\n==========================\n\nIn life of a Tcl script, there are two important periods of time, the\ndifference is subtle.\n  1. Parse Time\n  2. Evaluation Time\n\nThe two key items here are how \"quoted things\" work in Tcl.  Tcl has\nthree primary quoting constructs, the [square-brackets] the\n{curly-braces} and \"double-quotes\"\n\nBy now you should know $VARIABLES always start with a $DOLLAR sign.\nBTW: To set a variable, you actually use the command \"set\", as in \"set\nVARNAME VALUE\" much like the ancient BASIC language \"let x = 1\"\nstatement, but without the equal sign.\n\n   * [square-brackets]\n     [square-brackets] are command substitutions.  It operates much like\n     Unix Shell 'back-ticks'.  The result of a [square-bracket]\n     operation is exactly 1 string.  Remember Rule #1 - Everything is a\n     string.  These two statements are roughly identical:\n              # bash example\n              X=`date`\n              echo \"The Date is: $X\"\n              # Tcl example\n              set X [date]\n              puts \"The Date is: $X\"\n   * \"double-quoted-things\"\n     \"double-quoted-things\" are just simply quoted text.  $VARIABLES and\n     [square-brackets] are expanded in place - the result however is\n     exactly 1 string.  Remember Rule #1 - Everything is a string\n              set x \"Dinner\"\n              puts \"It is now \\\"[date]\\\", $x is in 1 hour\"\n   * {Curly-Braces}\n     {Curly-Braces} are magic: $VARIABLES and [square-brackets] are\n     parsed, but are NOT expanded or executed.  {Curly-Braces} are like\n     'single-quote' operators in BASH shell scripts, with the added\n     feature: {curly-braces} can be nested, single quotes can not.\n     {{{this is nested 3 times}}} NOTE: [date] is a bad example; at this\n     writing, Jim/OpenOCD does not have a date command.\n\n23.5 Consequences of Rule 1/2/3/4\n=================================\n\nThe consequences of Rule 1 are profound.\n\n23.5.1 Tokenisation & Execution.\n--------------------------------\n\nOf course, whitespace, blank lines and #comment lines are handled in the\nnormal way.\n\nAs a script is parsed, each (multi) line in the script file is tokenised\nand according to the quoting rules.  After tokenisation, that line is\nimmediately executed.\n\nMulti line statements end with one or more \"still-open\" {curly-braces}\nwhich - eventually - closes a few lines later.\n\n23.5.2 Command Execution\n------------------------\n\nRemember earlier: There are no \"control flow\" statements in Tcl.\nInstead there are COMMANDS that simply act like control flow operators.\n\nCommands are executed like this:\n\n  1. Parse the next line into (argc) and (argv[]).\n  2. Look up (argv[0]) in a table and call its function.\n  3. Repeat until End Of File.\n\nIt sort of works like this:\n         for(;;){\n             ReadAndParse( &argc, &argv );\n\n             cmdPtr = LookupCommand( argv[0] );\n\n             (*cmdPtr->Execute)( argc, argv );\n         }\n\nWhen the command \"proc\" is parsed (which creates a procedure function)\nit gets 3 parameters on the command line.  1 the name of the proc\n(function), 2 the list of parameters, and 3 the body of the function.\nNote the choice of words: LIST and BODY. The PROC command stores these\nitems in a table somewhere so it can be found by \"LookupCommand()\"\n\n23.5.3 The FOR command\n----------------------\n\nThe most interesting command to look at is the FOR command.  In Tcl, the\nFOR command is normally implemented in C. Remember, FOR is a command\njust like any other command.\n\nWhen the ascii text containing the FOR command is parsed, the parser\nproduces 5 parameter strings, (If in doubt: Refer to Rule #1) they are:\n\n  0. The ascii text 'for'\n  1. The start text\n  2. The test expression\n  3. The next text\n  4. The body text\n\nSort of reminds you of \"main( int argc, char **argv )\" does it not?\nRemember Rule #1 - Everything is a string.  The key point is this: Often\nmany of those parameters are in {curly-braces} - thus the variables\ninside are not expanded or replaced until later.\n\nRemember that every Tcl command looks like the classic \"main( argc, argv\n)\" function in C. In JimTCL - they actually look like this:\n\n     int\n     MyCommand( Jim_Interp *interp,\n                int *argc,\n                Jim_Obj * const *argvs );\n\nReal Tcl is nearly identical.  Although the newer versions have\nintroduced a byte-code parser and interpreter, but at the core, it still\noperates in the same basic way.\n\n23.5.4 FOR command implementation\n---------------------------------\n\nTo understand Tcl it is perhaps most helpful to see the FOR command.\nRemember, it is a COMMAND not a control flow structure.\n\nIn Tcl there are two underlying C helper functions.\n\nRemember Rule #1 - You are a string.\n\nThe first helper parses and executes commands found in an ascii string.\nCommands can be separated by semicolons, or newlines.  While parsing,\nvariables are expanded via the quoting rules.\n\nThe second helper evaluates an ascii string as a numerical expression\nand returns a value.\n\nHere is an example of how the FOR command could be implemented.  The\npseudo code below does not show error handling.\n     void Execute_AsciiString( void *interp, const char *string );\n\n     int Evaluate_AsciiExpression( void *interp, const char *string );\n\n     int\n     MyForCommand( void *interp,\n                   int argc,\n                   char **argv )\n     {\n        if( argc != 5 ){\n            SetResult( interp, \"WRONG number of parameters\");\n            return ERROR;\n        }\n\n        // argv[0] = the ascii string just like C\n\n        // Execute the start statement.\n        Execute_AsciiString( interp, argv[1] );\n\n        // Top of loop test\n        for(;;){\n             i = Evaluate_AsciiExpression(interp, argv[2]);\n             if( i == 0 )\n                 break;\n\n             // Execute the body\n             Execute_AsciiString( interp, argv[3] );\n\n             // Execute the LOOP part\n             Execute_AsciiString( interp, argv[4] );\n         }\n\n         // Return no error\n         SetResult( interp, \"\" );\n         return SUCCESS;\n     }\n\nEvery other command IF, WHILE, FORMAT, PUTS, EXPR, everything works in\nthe same basic way.\n\n23.6 OpenOCD Tcl Usage\n======================\n\n23.6.1 source and find commands\n-------------------------------\n\nWhere: In many configuration files\nExample: source [find FILENAME]\nRemember the parsing rules\n  1. The 'find' command is in square brackets, and is executed with the\n     parameter FILENAME. It should find and return the full path to a\n     file with that name; it uses an internal search path.  The RESULT\n     is a string, which is substituted into the command line in place of\n     the bracketed 'find' command.  (Don't try to use a FILENAME which\n     includes the \"#\" character.  That character begins Tcl comments.)\n  2. The 'source' command is executed with the resulting filename; it\n     reads a file and executes as a script.\n\n23.6.2 format command\n---------------------\n\nWhere: Generally occurs in numerous places.\nTcl has no command like printf(), instead it has format, which is really\nmore like sprintf().  Example\n         set x 6\n         set y 7\n         puts [format \"The answer: %d\" [expr {$x * $y}]]\n  1. The SET command creates 2 variables, X and Y.\n  2. The double [nested] EXPR command performs math\n     The EXPR command produces numerical result as a string.\n     Refer to Rule #1\n  3. The format command is executed, producing a single string\n     Refer to Rule #1.\n  4. The PUTS command outputs the text.\n\n23.6.3 Body or Inlined Text\n---------------------------\n\nWhere: Various TARGET scripts.\n     #1 Good\n        proc someproc {} {\n            ... multiple lines of stuff ...\n        }\n        $_TARGETNAME configure -event FOO someproc\n     #2 Good - no variables\n        $_TARGETNAME configure -event foo \"this ; that;\"\n     #3 Good Curly Braces\n        $_TARGETNAME configure -event FOO {\n             puts \"Time: [date]\"\n        }\n     #4 DANGER DANGER DANGER\n        $_TARGETNAME configure -event foo \"puts \\\"Time: [date]\\\"\"\n  1. The $_TARGETNAME is an OpenOCD variable convention.\n     $_TARGETNAME represents the last target created, the value changes\n     each time a new target is created.  Remember the parsing rules.\n     When the ascii text is parsed, the $_TARGETNAME becomes a simple\n     string, the name of the target which happens to be a TARGET\n     (object) command.\n  2. The 2nd parameter to the '-event' parameter is a TCBODY\n     There are 4 examples:\n       1. The TCLBODY is a simple string that happens to be a proc name\n       2. The TCLBODY is several simple commands separated by semicolons\n       3. The TCLBODY is a multi-line {curly-brace} quoted string\n       4. The TCLBODY is a string with variables that get expanded.\n\n     In the end, when the target event FOO occurs the TCLBODY is\n     evaluated.  Method #1 and #2 are functionally identical.  For\n     Method #3 and #4 it is more interesting.  What is the TCLBODY?\n\n     Remember the parsing rules.  In case #3, {curly-braces} mean the\n     $VARS and [square-brackets] are expanded later, when the EVENT\n     occurs, and the text is evaluated.  In case #4, they are replaced\n     before the \"Target Object Command\" is executed.  This occurs at the\n     same time $_TARGETNAME is replaced.  In case #4 the date will never\n     change.  {BTW: [date] is a bad example; at this writing,\n     Jim/OpenOCD does not have a date command}\n\n23.6.4 Global Variables\n-----------------------\n\nWhere: You might discover this when writing your own procs\nIn simple terms: Inside a PROC, if you need to access a global variable\nyou must say so.  See also \"upvar\".  Example:\n     proc myproc { } {\n          set y 0 #Local variable Y\n          global x #Global variable X\n          puts [format \"X=%d, Y=%d\" $x $y]\n     }\n\n23.7 Other Tcl Hacks\n====================\n\nDynamic variable creation\n     # Dynamically create a bunch of variables.\n     for { set x 0 } { $x < 32 } { set x [expr {$x + 1}]} {\n         # Create var name\n         set vn [format \"BIT%d\" $x]\n         # Make it a global\n         global $vn\n         # Set it.\n         set $vn [expr {1 << $x}]\n     }\nDynamic proc/command creation\n     # One \"X\" function - 5 uart functions.\n     foreach who {A B C D E}\n        proc [format \"show_uart%c\" $who] { } \"show_UARTx $who\"\n     }\n\n\u001f\nFile: openocd.info,  Node: License,  Next: OpenOCD Concept Index,  Prev: Tcl Crash Course,  Up: Top\n\nAppendix A The GNU Free Documentation License.\n**********************************************\n\n                      Version 1.2, November 2002\n\n     Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.\n     51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA\n\n     Everyone is permitted to copy and distribute verbatim copies\n     of this license document, but changing it is not allowed.\n\n  0. PREAMBLE\n\n     The purpose of this License is to make a manual, textbook, or other\n     functional and useful document \"free\" in the sense of freedom: to\n     assure everyone the effective freedom to copy and redistribute it,\n     with or without modifying it, either commercially or\n     noncommercially.  Secondarily, this License preserves for the\n     author and publisher a way to get credit for their work, while not\n     being considered responsible for modifications made by others.\n\n     This License is a kind of \"copyleft\", which means that derivative\n     works of the document must themselves be free in the same sense.\n     It complements the GNU General Public License, which is a copyleft\n     license designed for free software.\n\n     We have designed this License in order to use it for manuals for\n     free software, because free software needs free documentation: a\n     free program should come with manuals providing the same freedoms\n     that the software does.  But this License is not limited to\n     software manuals; it can be used for any textual work, regardless\n     of subject matter or whether it is published as a printed book.  We\n     recommend this License principally for works whose purpose is\n     instruction or reference.\n\n  1. APPLICABILITY AND DEFINITIONS\n\n     This License applies to any manual or other work, in any medium,\n     that contains a notice placed by the copyright holder saying it can\n     be distributed under the terms of this License.  Such a notice\n     grants a world-wide, royalty-free license, unlimited in duration,\n     to use that work under the conditions stated herein.  The\n     \"Document\", below, refers to any such manual or work.  Any member\n     of the public is a licensee, and is addressed as \"you\".  You accept\n     the license if you copy, modify or distribute the work in a way\n     requiring permission under copyright law.\n\n     A \"Modified Version\" of the Document means any work containing the\n     Document or a portion of it, either copied verbatim, or with\n     modifications and/or translated into another language.\n\n     A \"Secondary Section\" is a named appendix or a front-matter section\n     of the Document that deals exclusively with the relationship of the\n     publishers or authors of the Document to the Document's overall\n     subject (or to related matters) and contains nothing that could\n     fall directly within that overall subject.  (Thus, if the Document\n     is in part a textbook of mathematics, a Secondary Section may not\n     explain any mathematics.)  The relationship could be a matter of\n     historical connection with the subject or with related matters, or\n     of legal, commercial, philosophical, ethical or political position\n     regarding them.\n\n     The \"Invariant Sections\" are certain Secondary Sections whose\n     titles are designated, as being those of Invariant Sections, in the\n     notice that says that the Document is released under this License.\n     If a section does not fit the above definition of Secondary then it\n     is not allowed to be designated as Invariant.  The Document may\n     contain zero Invariant Sections.  If the Document does not identify\n     any Invariant Sections then there are none.\n\n     The \"Cover Texts\" are certain short passages of text that are\n     listed, as Front-Cover Texts or Back-Cover Texts, in the notice\n     that says that the Document is released under this License.  A\n     Front-Cover Text may be at most 5 words, and a Back-Cover Text may\n     be at most 25 words.\n\n     A \"Transparent\" copy of the Document means a machine-readable copy,\n     represented in a format whose specification is available to the\n     general public, that is suitable for revising the document\n     straightforwardly with generic text editors or (for images composed\n     of pixels) generic paint programs or (for drawings) some widely\n     available drawing editor, and that is suitable for input to text\n     formatters or for automatic translation to a variety of formats\n     suitable for input to text formatters.  A copy made in an otherwise\n     Transparent file format whose markup, or absence of markup, has\n     been arranged to thwart or discourage subsequent modification by\n     readers is not Transparent.  An image format is not Transparent if\n     used for any substantial amount of text.  A copy that is not\n     \"Transparent\" is called \"Opaque\".\n\n     Examples of suitable formats for Transparent copies include plain\n     ASCII without markup, Texinfo input format, LaTeX input format,\n     SGML or XML using a publicly available DTD, and standard-conforming\n     simple HTML, PostScript or PDF designed for human modification.\n     Examples of transparent image formats include PNG, XCF and JPG.\n     Opaque formats include proprietary formats that can be read and\n     edited only by proprietary word processors, SGML or XML for which\n     the DTD and/or processing tools are not generally available, and\n     the machine-generated HTML, PostScript or PDF produced by some word\n     processors for output purposes only.\n\n     The \"Title Page\" means, for a printed book, the title page itself,\n     plus such following pages as are needed to hold, legibly, the\n     material this License requires to appear in the title page.  For\n     works in formats which do not have any title page as such, \"Title\n     Page\" means the text near the most prominent appearance of the\n     work's title, preceding the beginning of the body of the text.\n\n     A section \"Entitled XYZ\" means a named subunit of the Document\n     whose title either is precisely XYZ or contains XYZ in parentheses\n     following text that translates XYZ in another language.  (Here XYZ\n     stands for a specific section name mentioned below, such as\n     \"Acknowledgements\", \"Dedications\", \"Endorsements\", or \"History\".)\n     To \"Preserve the Title\" of such a section when you modify the\n     Document means that it remains a section \"Entitled XYZ\" according\n     to this definition.\n\n     The Document may include Warranty Disclaimers next to the notice\n     which states that this License applies to the Document.  These\n     Warranty Disclaimers are considered to be included by reference in\n     this License, but only as regards disclaiming warranties: any other\n     implication that these Warranty Disclaimers may have is void and\n     has no effect on the meaning of this License.\n\n  2. VERBATIM COPYING\n\n     You may copy and distribute the Document in any medium, either\n     commercially or noncommercially, provided that this License, the\n     copyright notices, and the license notice saying this License\n     applies to the Document are reproduced in all copies, and that you\n     add no other conditions whatsoever to those of this License.  You\n     may not use technical measures to obstruct or control the reading\n     or further copying of the copies you make or distribute.  However,\n     you may accept compensation in exchange for copies.  If you\n     distribute a large enough number of copies you must also follow the\n     conditions in section 3.\n\n     You may also lend copies, under the same conditions stated above,\n     and you may publicly display copies.\n\n  3. COPYING IN QUANTITY\n\n     If you publish printed copies (or copies in media that commonly\n     have printed covers) of the Document, numbering more than 100, and\n     the Document's license notice requires Cover Texts, you must\n     enclose the copies in covers that carry, clearly and legibly, all\n     these Cover Texts: Front-Cover Texts on the front cover, and\n     Back-Cover Texts on the back cover.  Both covers must also clearly\n     and legibly identify you as the publisher of these copies.  The\n     front cover must present the full title with all words of the title\n     equally prominent and visible.  You may add other material on the\n     covers in addition.  Copying with changes limited to the covers, as\n     long as they preserve the title of the Document and satisfy these\n     conditions, can be treated as verbatim copying in other respects.\n\n     If the required texts for either cover are too voluminous to fit\n     legibly, you should put the first ones listed (as many as fit\n     reasonably) on the actual cover, and continue the rest onto\n     adjacent pages.\n\n     If you publish or distribute Opaque copies of the Document\n     numbering more than 100, you must either include a machine-readable\n     Transparent copy along with each Opaque copy, or state in or with\n     each Opaque copy a computer-network location from which the general\n     network-using public has access to download using public-standard\n     network protocols a complete Transparent copy of the Document, free\n     of added material.  If you use the latter option, you must take\n     reasonably prudent steps, when you begin distribution of Opaque\n     copies in quantity, to ensure that this Transparent copy will\n     remain thus accessible at the stated location until at least one\n     year after the last time you distribute an Opaque copy (directly or\n     through your agents or retailers) of that edition to the public.\n\n     It is requested, but not required, that you contact the authors of\n     the Document well before redistributing any large number of copies,\n     to give them a chance to provide you with an updated version of the\n     Document.\n\n  4. MODIFICATIONS\n\n     You may copy and distribute a Modified Version of the Document\n     under the conditions of sections 2 and 3 above, provided that you\n     release the Modified Version under precisely this License, with the\n     Modified Version filling the role of the Document, thus licensing\n     distribution and modification of the Modified Version to whoever\n     possesses a copy of it.  In addition, you must do these things in\n     the Modified Version:\n\n       A. Use in the Title Page (and on the covers, if any) a title\n          distinct from that of the Document, and from those of previous\n          versions (which should, if there were any, be listed in the\n          History section of the Document).  You may use the same title\n          as a previous version if the original publisher of that\n          version gives permission.\n\n       B. List on the Title Page, as authors, one or more persons or\n          entities responsible for authorship of the modifications in\n          the Modified Version, together with at least five of the\n          principal authors of the Document (all of its principal\n          authors, if it has fewer than five), unless they release you\n          from this requirement.\n\n       C. State on the Title page the name of the publisher of the\n          Modified Version, as the publisher.\n\n       D. Preserve all the copyright notices of the Document.\n\n       E. Add an appropriate copyright notice for your modifications\n          adjacent to the other copyright notices.\n\n       F. Include, immediately after the copyright notices, a license\n          notice giving the public permission to use the Modified\n          Version under the terms of this License, in the form shown in\n          the Addendum below.\n\n       G. Preserve in that license notice the full lists of Invariant\n          Sections and required Cover Texts given in the Document's\n          license notice.\n\n       H. Include an unaltered copy of this License.\n\n       I. Preserve the section Entitled \"History\", Preserve its Title,\n          and add to it an item stating at least the title, year, new\n          authors, and publisher of the Modified Version as given on the\n          Title Page.  If there is no section Entitled \"History\" in the\n          Document, create one stating the title, year, authors, and\n          publisher of the Document as given on its Title Page, then add\n          an item describing the Modified Version as stated in the\n          previous sentence.\n\n       J. Preserve the network location, if any, given in the Document\n          for public access to a Transparent copy of the Document, and\n          likewise the network locations given in the Document for\n          previous versions it was based on.  These may be placed in the\n          \"History\" section.  You may omit a network location for a work\n          that was published at least four years before the Document\n          itself, or if the original publisher of the version it refers\n          to gives permission.\n\n       K. For any section Entitled \"Acknowledgements\" or \"Dedications\",\n          Preserve the Title of the section, and preserve in the section\n          all the substance and tone of each of the contributor\n          acknowledgements and/or dedications given therein.\n\n       L. Preserve all the Invariant Sections of the Document, unaltered\n          in their text and in their titles.  Section numbers or the\n          equivalent are not considered part of the section titles.\n\n       M. Delete any section Entitled \"Endorsements\".  Such a section\n          may not be included in the Modified Version.\n\n       N. Do not retitle any existing section to be Entitled\n          \"Endorsements\" or to conflict in title with any Invariant\n          Section.\n\n       O. Preserve any Warranty Disclaimers.\n\n     If the Modified Version includes new front-matter sections or\n     appendices that qualify as Secondary Sections and contain no\n     material copied from the Document, you may at your option designate\n     some or all of these sections as invariant.  To do this, add their\n     titles to the list of Invariant Sections in the Modified Version's\n     license notice.  These titles must be distinct from any other\n     section titles.\n\n     You may add a section Entitled \"Endorsements\", provided it contains\n     nothing but endorsements of your Modified Version by various\n     parties--for example, statements of peer review or that the text\n     has been approved by an organization as the authoritative\n     definition of a standard.\n\n     You may add a passage of up to five words as a Front-Cover Text,\n     and a passage of up to 25 words as a Back-Cover Text, to the end of\n     the list of Cover Texts in the Modified Version.  Only one passage\n     of Front-Cover Text and one of Back-Cover Text may be added by (or\n     through arrangements made by) any one entity.  If the Document\n     already includes a cover text for the same cover, previously added\n     by you or by arrangement made by the same entity you are acting on\n     behalf of, you may not add another; but you may replace the old\n     one, on explicit permission from the previous publisher that added\n     the old one.\n\n     The author(s) and publisher(s) of the Document do not by this\n     License give permission to use their names for publicity for or to\n     assert or imply endorsement of any Modified Version.\n\n  5. COMBINING DOCUMENTS\n\n     You may combine the Document with other documents released under\n     this License, under the terms defined in section 4 above for\n     modified versions, provided that you include in the combination all\n     of the Invariant Sections of all of the original documents,\n     unmodified, and list them all as Invariant Sections of your\n     combined work in its license notice, and that you preserve all\n     their Warranty Disclaimers.\n\n     The combined work need only contain one copy of this License, and\n     multiple identical Invariant Sections may be replaced with a single\n     copy.  If there are multiple Invariant Sections with the same name\n     but different contents, make the title of each such section unique\n     by adding at the end of it, in parentheses, the name of the\n     original author or publisher of that section if known, or else a\n     unique number.  Make the same adjustment to the section titles in\n     the list of Invariant Sections in the license notice of the\n     combined work.\n\n     In the combination, you must combine any sections Entitled\n     \"History\" in the various original documents, forming one section\n     Entitled \"History\"; likewise combine any sections Entitled\n     \"Acknowledgements\", and any sections Entitled \"Dedications\".  You\n     must delete all sections Entitled \"Endorsements.\"\n\n  6. COLLECTIONS OF DOCUMENTS\n\n     You may make a collection consisting of the Document and other\n     documents released under this License, and replace the individual\n     copies of this License in the various documents with a single copy\n     that is included in the collection, provided that you follow the\n     rules of this License for verbatim copying of each of the documents\n     in all other respects.\n\n     You may extract a single document from such a collection, and\n     distribute it individually under this License, provided you insert\n     a copy of this License into the extracted document, and follow this\n     License in all other respects regarding verbatim copying of that\n     document.\n\n  7. AGGREGATION WITH INDEPENDENT WORKS\n\n     A compilation of the Document or its derivatives with other\n     separate and independent documents or works, in or on a volume of a\n     storage or distribution medium, is called an \"aggregate\" if the\n     copyright resulting from the compilation is not used to limit the\n     legal rights of the compilation's users beyond what the individual\n     works permit.  When the Document is included in an aggregate, this\n     License does not apply to the other works in the aggregate which\n     are not themselves derivative works of the Document.\n\n     If the Cover Text requirement of section 3 is applicable to these\n     copies of the Document, then if the Document is less than one half\n     of the entire aggregate, the Document's Cover Texts may be placed\n     on covers that bracket the Document within the aggregate, or the\n     electronic equivalent of covers if the Document is in electronic\n     form.  Otherwise they must appear on printed covers that bracket\n     the whole aggregate.\n\n  8. TRANSLATION\n\n     Translation is considered a kind of modification, so you may\n     distribute translations of the Document under the terms of section\n     4.  Replacing Invariant Sections with translations requires special\n     permission from their copyright holders, but you may include\n     translations of some or all Invariant Sections in addition to the\n     original versions of these Invariant Sections.  You may include a\n     translation of this License, and all the license notices in the\n     Document, and any Warranty Disclaimers, provided that you also\n     include the original English version of this License and the\n     original versions of those notices and disclaimers.  In case of a\n     disagreement between the translation and the original version of\n     this License or a notice or disclaimer, the original version will\n     prevail.\n\n     If a section in the Document is Entitled \"Acknowledgements\",\n     \"Dedications\", or \"History\", the requirement (section 4) to\n     Preserve its Title (section 1) will typically require changing the\n     actual title.\n\n  9. TERMINATION\n\n     You may not copy, modify, sublicense, or distribute the Document\n     except as expressly provided for under this License.  Any other\n     attempt to copy, modify, sublicense or distribute the Document is\n     void, and will automatically terminate your rights under this\n     License.  However, parties who have received copies, or rights,\n     from you under this License will not have their licenses terminated\n     so long as such parties remain in full compliance.\n\n  10. FUTURE REVISIONS OF THIS LICENSE\n\n     The Free Software Foundation may publish new, revised versions of\n     the GNU Free Documentation License from time to time.  Such new\n     versions will be similar in spirit to the present version, but may\n     differ in detail to address new problems or concerns.  See\n     <https://www.gnu.org/licenses/>.\n\n     Each version of the License is given a distinguishing version\n     number.  If the Document specifies that a particular numbered\n     version of this License \"or any later version\" applies to it, you\n     have the option of following the terms and conditions either of\n     that specified version or of any later version that has been\n     published (not as a draft) by the Free Software Foundation.  If the\n     Document does not specify a version number of this License, you may\n     choose any version ever published (not as a draft) by the Free\n     Software Foundation.\n\nADDENDUM: How to use this License for your documents\n====================================================\n\nTo use this License in a document you have written, include a copy of\nthe License in the document and put the following copyright and license\nnotices just after the title page:\n\n       Copyright (C)  YEAR  YOUR NAME.\n       Permission is granted to copy, distribute and/or modify this document\n       under the terms of the GNU Free Documentation License, Version 1.2\n       or any later version published by the Free Software Foundation;\n       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover\n       Texts.  A copy of the license is included in the section entitled ``GNU\n       Free Documentation License''.\n\nIf you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,\nreplace the \"with...Texts.\"  line with this:\n\n         with the Invariant Sections being LIST THEIR TITLES, with\n         the Front-Cover Texts being LIST, and with the Back-Cover Texts\n         being LIST.\n\nIf you have Invariant Sections without Cover Texts, or some other\ncombination of the three, merge those two alternatives to suit the\nsituation.\n\nIf your document contains nontrivial examples of program code, we\nrecommend releasing these examples in parallel under your choice of free\nsoftware license, such as the GNU General Public License, to permit\ntheir use in free software.\n\n\u001f\nFile: openocd.info,  Node: OpenOCD Concept Index,  Next: Command and Driver Index,  Prev: License,  Up: Top\n\nOpenOCD Concept Index\n*********************\n\n\u0000\b[index\u0000\b]\n* Menu:\n\n* aarch64:                               Architecture and Core Commands.\n                                                             (line  959)\n* about:                                 About.              (line    6)\n* adaptive clocking:                     Debug Adapter Configuration.\n                                                             (line 1304)\n* adaptive clocking <1>:                 FAQ.                (line    6)\n* ambiqmicro:                            Flash Commands.     (line  632)\n* apollo:                                Flash Commands.     (line  632)\n* ARC:                                   Architecture and Core Commands.\n                                                             (line 1459)\n* Architecture Specific Commands:        Architecture and Core Commands.\n                                                             (line    6)\n* ARM:                                   Architecture and Core Commands.\n                                                             (line  271)\n* ARM semihosting:                       OpenOCD Project Setup.\n                                                             (line  314)\n* ARM semihosting <1>:                   Architecture and Core Commands.\n                                                             (line  312)\n* ARM semihosting <2>:                   Architecture and Core Commands.\n                                                             (line  323)\n* ARM semihosting <3>:                   Architecture and Core Commands.\n                                                             (line  333)\n* ARM semihosting <4>:                   Architecture and Core Commands.\n                                                             (line  344)\n* ARM semihosting <5>:                   Architecture and Core Commands.\n                                                             (line  353)\n* ARM semihosting <6>:                   Architecture and Core Commands.\n                                                             (line  374)\n* ARM semihosting <7>:                   Architecture and Core Commands.\n                                                             (line  383)\n* ARM11:                                 Architecture and Core Commands.\n                                                             (line  650)\n* ARM7:                                  Architecture and Core Commands.\n                                                             (line  397)\n* ARM9:                                  Architecture and Core Commands.\n                                                             (line  397)\n* ARM9 <1>:                              Architecture and Core Commands.\n                                                             (line  435)\n* ARM920T:                               Architecture and Core Commands.\n                                                             (line  455)\n* ARM926ej-s:                            Architecture and Core Commands.\n                                                             (line  480)\n* ARM966E:                               Architecture and Core Commands.\n                                                             (line  494)\n* ARMv4:                                 Architecture and Core Commands.\n                                                             (line  390)\n* ARMv5:                                 Architecture and Core Commands.\n                                                             (line  390)\n* ARMv6:                                 Architecture and Core Commands.\n                                                             (line  646)\n* ARMv7:                                 Architecture and Core Commands.\n                                                             (line  684)\n* ARMv8:                                 Architecture and Core Commands.\n                                                             (line  683)\n* ARMv8-A:                               Architecture and Core Commands.\n                                                             (line  959)\n* at91sam3:                              Flash Commands.     (line  748)\n* at91sam4:                              Flash Commands.     (line  803)\n* at91sam4l:                             Flash Commands.     (line  808)\n* at91samd:                              Flash Commands.     (line  670)\n* ath79:                                 Flash Commands.     (line  581)\n* Atheros ath79 SPI driver:              Flash Commands.     (line  581)\n* atsame5:                               Flash Commands.     (line  819)\n* atsamv:                                Flash Commands.     (line  872)\n* autoprobe:                             TAP Declaration.    (line  323)\n* board config file:                     Config File Guidelines.\n                                                             (line   68)\n* breakpoint:                            General Commands.   (line  383)\n* bscan_spi:                             Flash Commands.     (line  329)\n* CFI:                                   Flash Commands.     (line  294)\n* command line options:                  Running.            (line    6)\n* commands:                              General Commands.   (line    6)\n* Common Flash Interface:                Flash Commands.     (line  294)\n* config command:                        Server Configuration.\n                                                             (line   13)\n* config file, board:                    Config File Guidelines.\n                                                             (line   68)\n* config file, interface:                Debug Adapter Configuration.\n                                                             (line    6)\n* config file, overview:                 OpenOCD Project Setup.\n                                                             (line  139)\n* config file, target:                   Config File Guidelines.\n                                                             (line  298)\n* config file, user:                     OpenOCD Project Setup.\n                                                             (line  139)\n* configuration stage:                   Server Configuration.\n                                                             (line   13)\n* Connecting to GDB:                     GDB and OpenOCD.    (line   27)\n* Core Specific Commands:                Architecture and Core Commands.\n                                                             (line    6)\n* Cortex-A:                              Architecture and Core Commands.\n                                                             (line  687)\n* Cortex-M:                              Architecture and Core Commands.\n                                                             (line  900)\n* Cortex-R:                              Architecture and Core Commands.\n                                                             (line  722)\n* CPU type:                              CPU Configuration.  (line   60)\n* CTI:                                   Architecture and Core Commands.\n                                                             (line  225)\n* DAP declaration:                       TAP Declaration.    (line  379)\n* DCC:                                   Architecture and Core Commands.\n                                                             (line  413)\n* DCC <1>:                               Architecture and Core Commands.\n                                                             (line 1686)\n* developers:                            Developers.         (line    6)\n* directory search:                      Running.            (line    6)\n* disassemble:                           Architecture and Core Commands.\n                                                             (line  282)\n* disassemble <1>:                       Architecture and Core Commands.\n                                                             (line  972)\n* dongles:                               Debug Adapter Hardware.\n                                                             (line    6)\n* dotted name:                           TAP Declaration.    (line   98)\n* ETB:                                   Architecture and Core Commands.\n                                                             (line   14)\n* ETM:                                   Architecture and Core Commands.\n                                                             (line   14)\n* ETM <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* event, reset-init:                     Config File Guidelines.\n                                                             (line  184)\n* events:                                Reset Configuration.\n                                                             (line  226)\n* events <1>:                            TAP Declaration.    (line  222)\n* events <2>:                            CPU Configuration.  (line  462)\n* faq:                                   FAQ.                (line    6)\n* fespi:                                 Flash Commands.     (line  614)\n* Firmware recovery:                     Utility Commands.   (line   45)\n* flash configuration:                   Flash Commands.     (line   36)\n* flash erasing:                         Flash Commands.     (line  102)\n* flash programming:                     Flash Commands.     (line  102)\n* flash protection:                      Flash Commands.     (line  230)\n* flash reading:                         Flash Commands.     (line  102)\n* flash writing:                         Flash Commands.     (line  102)\n* FPGA:                                  PLD/FPGA Commands.  (line    6)\n* Freedom E SPI:                         Flash Commands.     (line  614)\n* FTDI:                                  Debug Adapter Hardware.\n                                                             (line    6)\n* GDB:                                   Server Configuration.\n                                                             (line  173)\n* GDB <1>:                               GDB and OpenOCD.    (line    6)\n* GDB configuration:                     Server Configuration.\n                                                             (line  173)\n* GDB server:                            Server Configuration.\n                                                             (line  126)\n* GDB target:                            CPU Configuration.  (line    6)\n* Generic JTAG2SPI driver:               Flash Commands.     (line  329)\n* halt:                                  General Commands.   (line  103)\n* hwthread:                              GDB and OpenOCD.    (line  292)\n* image dumping:                         General Commands.   (line  329)\n* image loading:                         General Commands.   (line  329)\n* initialization:                        Server Configuration.\n                                                             (line    6)\n* init_board procedure:                  Config File Guidelines.\n                                                             (line  249)\n* init_targets procedure:                Config File Guidelines.\n                                                             (line  522)\n* init_target_events procedure:          Config File Guidelines.\n                                                             (line  567)\n* interface config file:                 Debug Adapter Configuration.\n                                                             (line    6)\n* IPDBG:                                 Boundary Scan Commands.\n                                                             (line   73)\n* IPDBG JTAG-Host server:                Boundary Scan Commands.\n                                                             (line   73)\n* ITM:                                   Architecture and Core Commands.\n                                                             (line  890)\n* Jim-Tcl:                               About Jim-Tcl.      (line    6)\n* jrc:                                   TAP Declaration.    (line  260)\n* JTAG:                                  About.              (line   15)\n* JTAG <1>:                              Debug Adapter Configuration.\n                                                             (line 1184)\n* JTAG autoprobe:                        TAP Declaration.    (line  323)\n* JTAG Commands:                         JTAG Commands.      (line    6)\n* JTAG Route Controller:                 TAP Declaration.    (line  260)\n* jtagspi:                               Flash Commands.     (line  329)\n* kinetis:                               Flash Commands.     (line 1040)\n* kinetis_ke:                            Flash Commands.     (line 1127)\n* libdcc:                                Architecture and Core Commands.\n                                                             (line 1686)\n* Linux-ARM DCC support:                 Architecture and Core Commands.\n                                                             (line 1686)\n* logfile:                               Running.            (line    6)\n* lpcspifi:                              Flash Commands.     (line  423)\n* memory access:                         General Commands.   (line  291)\n* message level:                         General Commands.   (line   73)\n* NAND:                                  Flash Commands.     (line 2132)\n* NAND configuration:                    Flash Commands.     (line 2187)\n* NAND erasing:                          Flash Commands.     (line 2267)\n* NAND other commands:                   Flash Commands.     (line 2358)\n* NAND programming:                      Flash Commands.     (line 2267)\n* NAND programming <1>:                  Flash Commands.     (line 2280)\n* NAND programming <2>:                  Flash Commands.     (line 2333)\n* NAND reading:                          Flash Commands.     (line 2234)\n* NAND verification:                     Flash Commands.     (line 2333)\n* NAND writing:                          Flash Commands.     (line 2280)\n* NXP SPI Flash Interface:               Flash Commands.     (line  423)\n* object command:                        CPU Configuration.  (line  307)\n* OctoSPI:                               Flash Commands.     (line  460)\n* PLD:                                   PLD/FPGA Commands.  (line    6)\n* port:                                  Server Configuration.\n                                                             (line  116)\n* printer port:                          Debug Adapter Hardware.\n                                                             (line    6)\n* profiling:                             General Commands.   (line  488)\n* Programming using GDB:                 GDB and OpenOCD.    (line  127)\n* QuadSPI:                               Flash Commands.     (line  460)\n* RAM testing:                           Utility Commands.   (line    9)\n* reset:                                 General Commands.   (line  103)\n* Reset Configuration:                   Reset Configuration.\n                                                             (line    6)\n* reset-init handler:                    Config File Guidelines.\n                                                             (line  184)\n* RPC:                                   Tcl Scripting API.  (line   65)\n* RPC Notifications:                     Tcl Scripting API.  (line   83)\n* RPC trace output:                      Tcl Scripting API.  (line  100)\n* RTCK:                                  Debug Adapter Hardware.\n                                                             (line    6)\n* RTCK <1>:                              Debug Adapter Configuration.\n                                                             (line 1304)\n* RTCK <2>:                              FAQ.                (line    6)\n* RTOS:                                  GDB and OpenOCD.    (line  292)\n* RTOS Support:                          GDB and OpenOCD.    (line  211)\n* scan chain:                            TAP Declaration.    (line   28)\n* security:                              Server Configuration.\n                                                             (line  116)\n* Serial Peripheral Interface:           Debug Adapter Configuration.\n                                                             (line 1228)\n* Serial Vector Format:                  Boundary Scan Commands.\n                                                             (line   13)\n* Serial Wire Debug:                     Debug Adapter Configuration.\n                                                             (line 1199)\n* server:                                Server Configuration.\n                                                             (line  116)\n* Single Wire Interface Module:          Debug Adapter Configuration.\n                                                             (line 1235)\n* SMI:                                   Flash Commands.     (line  440)\n* SMP:                                   Config File Guidelines.\n                                                             (line  425)\n* SMP <1>:                               GDB and OpenOCD.    (line  292)\n* SPI:                                   Debug Adapter Configuration.\n                                                             (line 1228)\n* SPI <1>:                               Flash Commands.     (line  329)\n* SPIFI:                                 Flash Commands.     (line  423)\n* STMicroelectronics QuadSPI/OctoSPI Interface: Flash Commands.\n                                                             (line  460)\n* STMicroelectronics Serial Memory Interface: Flash Commands.\n                                                             (line  440)\n* stmqspi:                               Flash Commands.     (line  460)\n* stmsmi:                                Flash Commands.     (line  440)\n* str9xpec:                              Flash Commands.     (line 1997)\n* SVF:                                   Boundary Scan Commands.\n                                                             (line   13)\n* SWD:                                   Debug Adapter Configuration.\n                                                             (line 1199)\n* SWD multi-drop:                        Debug Adapter Configuration.\n                                                             (line 1215)\n* SWIM:                                  Debug Adapter Configuration.\n                                                             (line 1235)\n* swm050:                                Flash Commands.     (line 2075)\n* SWO:                                   Architecture and Core Commands.\n                                                             (line  732)\n* SWO <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* SWV:                                   Architecture and Core Commands.\n                                                             (line  732)\n* SWV <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* TAP:                                   About.              (line   15)\n* TAP configuration:                     TAP Declaration.    (line    6)\n* TAP declaration:                       TAP Declaration.    (line    6)\n* TAP events:                            TAP Declaration.    (line  222)\n* TAP naming convention:                 TAP Declaration.    (line  121)\n* TAP state names:                       JTAG Commands.      (line  125)\n* target config file:                    Config File Guidelines.\n                                                             (line  298)\n* target events:                         CPU Configuration.  (line  462)\n* target initialization:                 General Commands.   (line  103)\n* target type:                           CPU Configuration.  (line   60)\n* target, current:                       CPU Configuration.  (line   18)\n* target, list:                          CPU Configuration.  (line   18)\n* tcl:                                   About Jim-Tcl.      (line    6)\n* Tcl:                                   Tcl Crash Course.   (line    6)\n* Tcl Scripting API:                     Tcl Scripting API.  (line    6)\n* Tcl scripts:                           Tcl Scripting API.  (line    5)\n* TCP port:                              Server Configuration.\n                                                             (line  116)\n* TPIU:                                  Architecture and Core Commands.\n                                                             (line  732)\n* tracing:                               Architecture and Core Commands.\n                                                             (line   14)\n* tracing <1>:                           Architecture and Core Commands.\n                                                             (line  732)\n* tracing <2>:                           Architecture and Core Commands.\n                                                             (line  890)\n* tracing <3>:                           Architecture and Core Commands.\n                                                             (line 1686)\n* translation:                           Config File Guidelines.\n                                                             (line  612)\n* Transport:                             Debug Adapter Configuration.\n                                                             (line 1158)\n* USB Adapter:                           Debug Adapter Hardware.\n                                                             (line    6)\n* user config file:                      OpenOCD Project Setup.\n                                                             (line  139)\n* Using GDB as a non-intrusive memory inspector: GDB and OpenOCD.\n                                                             (line  167)\n* Utility Commands:                      Utility Commands.   (line    5)\n* variable names:                        Config File Guidelines.\n                                                             (line  152)\n* vector_catch:                          OpenOCD Project Setup.\n                                                             (line  213)\n* vector_catch <1>:                      Architecture and Core Commands.\n                                                             (line  440)\n* vector_catch <2>:                      Architecture and Core Commands.\n                                                             (line  619)\n* vector_catch <3>:                      Architecture and Core Commands.\n                                                             (line  672)\n* vector_catch <4>:                      Architecture and Core Commands.\n                                                             (line  925)\n* vector_table:                          Architecture and Core Commands.\n                                                             (line  634)\n* watchpoint:                            General Commands.   (line  383)\n* wiggler:                               Debug Adapter Hardware.\n                                                             (line    6)\n* xcf:                                   Flash Commands.     (line  387)\n* Xilinx Platform flash driver:          Flash Commands.     (line  387)\n* Xilinx Serial Vector Format:           Boundary Scan Commands.\n                                                             (line   39)\n* XScale:                                Architecture and Core Commands.\n                                                             (line  508)\n* XSVF:                                  Boundary Scan Commands.\n                                                             (line   39)\n\n\u001f\nFile: openocd.info,  Node: Command and Driver Index,  Prev: OpenOCD Concept Index,  Up: Top\n\nCommand and Driver Index\n************************\n\n\u0000\b[index\u0000\b]\n* Menu:\n\n* $cti_name ack:                         Architecture and Core Commands.\n                                                             (line  253)\n* $cti_name channel:                     Architecture and Core Commands.\n                                                             (line  256)\n* $cti_name dump:                        Architecture and Core Commands.\n                                                             (line  243)\n* $cti_name enable:                      Architecture and Core Commands.\n                                                             (line  240)\n* $cti_name read:                        Architecture and Core Commands.\n                                                             (line  249)\n* $cti_name testmode:                    Architecture and Core Commands.\n                                                             (line  260)\n* $cti_name write:                       Architecture and Core Commands.\n                                                             (line  246)\n* $dap_name apcsw:                       TAP Declaration.    (line  469)\n* $dap_name apid:                        TAP Declaration.    (line  436)\n* $dap_name apreg:                       TAP Declaration.    (line  440)\n* $dap_name apsel:                       TAP Declaration.    (line  445)\n* $dap_name baseaddr:                    TAP Declaration.    (line  460)\n* $dap_name dpreg:                       TAP Declaration.    (line  448)\n* $dap_name info:                        TAP Declaration.    (line  432)\n* $dap_name memaccess:                   TAP Declaration.    (line  464)\n* $dap_name ti_be_32_quirks:             TAP Declaration.    (line  504)\n* $target_name arp_examine:              CPU Configuration.  (line  332)\n* $target_name arp_halt:                 CPU Configuration.  (line  333)\n* $target_name arp_poll:                 CPU Configuration.  (line  334)\n* $target_name arp_reset:                CPU Configuration.  (line  335)\n* $target_name arp_waitstate:            CPU Configuration.  (line  336)\n* $target_name catch_exc:                Architecture and Core Commands.\n                                                             (line  988)\n* $target_name cget:                     CPU Configuration.  (line  397)\n* $target_name configure:                CPU Configuration.  (line  221)\n* $target_name curstate:                 CPU Configuration.  (line  420)\n* $target_name eventlist:                CPU Configuration.  (line  425)\n* $target_name get_reg:                  CPU Configuration.  (line  353)\n* $target_name invoke-event:             CPU Configuration.  (line  429)\n* $target_name mdb:                      CPU Configuration.  (line  437)\n* $target_name mdd:                      CPU Configuration.  (line  434)\n* $target_name mdh:                      CPU Configuration.  (line  436)\n* $target_name mdw:                      CPU Configuration.  (line  435)\n* $target_name mwb:                      CPU Configuration.  (line  450)\n* $target_name mwd:                      CPU Configuration.  (line  447)\n* $target_name mwh:                      CPU Configuration.  (line  449)\n* $target_name mww:                      CPU Configuration.  (line  448)\n* $target_name read_memory:              CPU Configuration.  (line  381)\n* $target_name set_reg:                  CPU Configuration.  (line  341)\n* $target_name write_memory:             CPU Configuration.  (line  366)\n* $tpiu_name cget:                       Architecture and Core Commands.\n                                                             (line  778)\n* $tpiu_name configure:                  Architecture and Core Commands.\n                                                             (line  784)\n* $tpiu_name disable:                    Architecture and Core Commands.\n                                                             (line  856)\n* $tpiu_name enable:                     Architecture and Core Commands.\n                                                             (line  849)\n* aarch64 cache_info:                    Architecture and Core Commands.\n                                                             (line  959)\n* aarch64 dbginit:                       Architecture and Core Commands.\n                                                             (line  962)\n* aarch64 disassemble:                   Architecture and Core Commands.\n                                                             (line  971)\n* aarch64 maskisr:                       Architecture and Core Commands.\n                                                             (line  984)\n* aarch64 smp:                           Architecture and Core Commands.\n                                                             (line  975)\n* adapter assert:                        General Commands.   (line  264)\n* adapter deassert:                      General Commands.   (line  265)\n* adapter driver:                        Debug Adapter Configuration.\n                                                             (line   43)\n* adapter list:                          Debug Adapter Configuration.\n                                                             (line   46)\n* adapter name:                          Debug Adapter Configuration.\n                                                             (line   55)\n* adapter serial:                        Debug Adapter Configuration.\n                                                             (line   69)\n* adapter speed:                         Debug Adapter Configuration.\n                                                             (line 1287)\n* adapter srst delay:                    Reset Configuration.\n                                                             (line  126)\n* adapter srst pulse_width:              Reset Configuration.\n                                                             (line  121)\n* adapter transports:                    Debug Adapter Configuration.\n                                                             (line   49)\n* adapter usb location:                  Debug Adapter Configuration.\n                                                             (line   58)\n* addreg:                                Architecture and Core Commands.\n                                                             (line 1232)\n* add_help_text:                         General Commands.   (line  501)\n* add_script_search_dir:                 General Commands.   (line   91)\n* add_usage_text:                        General Commands.   (line  504)\n* aduc702x:                              Flash Commands.     (line  622)\n* am335xgpio:                            Debug Adapter Configuration.\n                                                             (line  877)\n* am335xgpio jtag_nums:                  Debug Adapter Configuration.\n                                                             (line  894)\n* am335xgpio led_num:                    Debug Adapter Configuration.\n                                                             (line  951)\n* am335xgpio led_on_state:               Debug Adapter Configuration.\n                                                             (line  955)\n* am335xgpio speed_coeffs:               Debug Adapter Configuration.\n                                                             (line  959)\n* am335xgpio srst_num:                   Debug Adapter Configuration.\n                                                             (line  945)\n* am335xgpio swclk_num:                  Debug Adapter Configuration.\n                                                             (line  924)\n* am335xgpio swdio_dir_num:              Debug Adapter Configuration.\n                                                             (line  934)\n* am335xgpio swdio_dir_output_state:     Debug Adapter Configuration.\n                                                             (line  941)\n* am335xgpio swdio_num:                  Debug Adapter Configuration.\n                                                             (line  929)\n* am335xgpio swd_nums:                   Debug Adapter Configuration.\n                                                             (line  919)\n* am335xgpio tck_num:                    Debug Adapter Configuration.\n                                                             (line  899)\n* am335xgpio tdi_num:                    Debug Adapter Configuration.\n                                                             (line  914)\n* am335xgpio tdo_num:                    Debug Adapter Configuration.\n                                                             (line  909)\n* am335xgpio tms_num:                    Debug Adapter Configuration.\n                                                             (line  904)\n* am335xgpio trst_num:                   Debug Adapter Configuration.\n                                                             (line  948)\n* ambiqmicro:                            Flash Commands.     (line  631)\n* ambiqmicro mass_erase:                 Flash Commands.     (line  659)\n* ambiqmicro page_erase:                 Flash Commands.     (line  661)\n* ambiqmicro program_otp:                Flash Commands.     (line  663)\n* amt_jtagaccel:                         Debug Adapter Configuration.\n                                                             (line   83)\n* arc add-reg:                           Architecture and Core Commands.\n                                                             (line 1480)\n* arc add-reg-type-flags:                Architecture and Core Commands.\n                                                             (line 1534)\n* arc add-reg-type-struct:               Architecture and Core Commands.\n                                                             (line 1539)\n* arc get-reg-field:                     Architecture and Core Commands.\n                                                             (line 1545)\n* arc jtag get-aux-reg:                  Architecture and Core Commands.\n                                                             (line 1567)\n* arc jtag get-core-reg:                 Architecture and Core Commands.\n                                                             (line 1573)\n* arc jtag set-aux-reg:                  Architecture and Core Commands.\n                                                             (line 1557)\n* arc jtag set-core-reg:                 Architecture and Core Commands.\n                                                             (line 1563)\n* arc set-reg-exists:                    Architecture and Core Commands.\n                                                             (line 1550)\n* arm core_state:                        Architecture and Core Commands.\n                                                             (line  275)\n* arm disassemble:                       Architecture and Core Commands.\n                                                             (line  281)\n* arm mcr:                               Architecture and Core Commands.\n                                                             (line  295)\n* arm mrc:                               Architecture and Core Commands.\n                                                             (line  301)\n* arm reg:                               Architecture and Core Commands.\n                                                             (line  307)\n* arm semihosting:                       Architecture and Core Commands.\n                                                             (line  311)\n* arm semihosting_basedir:               Architecture and Core Commands.\n                                                             (line  382)\n* arm semihosting_cmdline:               Architecture and Core Commands.\n                                                             (line  332)\n* arm semihosting_fileio:                Architecture and Core Commands.\n                                                             (line  343)\n* arm semihosting_read_user_param:       Architecture and Core Commands.\n                                                             (line  373)\n* arm semihosting_redirect:              Architecture and Core Commands.\n                                                             (line  322)\n* arm semihosting_resexit:               Architecture and Core Commands.\n                                                             (line  352)\n* arm-jtag-ew:                           Debug Adapter Configuration.\n                                                             (line   96)\n* arm11 memwrite burst:                  Architecture and Core Commands.\n                                                             (line  650)\n* arm11 memwrite error_fatal:            Architecture and Core Commands.\n                                                             (line  660)\n* arm11 step_irq_enable:                 Architecture and Core Commands.\n                                                             (line  666)\n* arm11 vcr:                             Architecture and Core Commands.\n                                                             (line  671)\n* arm7_9 dbgrq:                          Architecture and Core Commands.\n                                                             (line  402)\n* arm7_9 dcc_downloads:                  Architecture and Core Commands.\n                                                             (line  412)\n* arm7_9 fast_memory_access:             Architecture and Core Commands.\n                                                             (line  423)\n* arm9 vector_catch:                     Architecture and Core Commands.\n                                                             (line  439)\n* arm920t cache_info:                    Architecture and Core Commands.\n                                                             (line  460)\n* arm920t cp15:                          Architecture and Core Commands.\n                                                             (line  465)\n* arm920t read_cache:                    Architecture and Core Commands.\n                                                             (line  471)\n* arm920t read_mmu:                      Architecture and Core Commands.\n                                                             (line  474)\n* arm926ejs cache_info:                  Architecture and Core Commands.\n                                                             (line  488)\n* arm966e cp15:                          Architecture and Core Commands.\n                                                             (line  498)\n* armjtagew_info:                        Debug Adapter Configuration.\n                                                             (line  100)\n* at91rm9200:                            Debug Adapter Configuration.\n                                                             (line  103)\n* at91sam3:                              Flash Commands.     (line  747)\n* at91sam3 gpnvm:                        Flash Commands.     (line  779)\n* at91sam3 gpnvm clear:                  Flash Commands.     (line  780)\n* at91sam3 gpnvm set:                    Flash Commands.     (line  781)\n* at91sam3 gpnvm show:                   Flash Commands.     (line  782)\n* at91sam3 info:                         Flash Commands.     (line  788)\n* at91sam3 slowclk:                      Flash Commands.     (line  798)\n* at91sam4:                              Flash Commands.     (line  802)\n* at91sam4l:                             Flash Commands.     (line  807)\n* at91sam4l smap_reset_deassert:         Flash Commands.     (line  813)\n* at91sam7:                              Flash Commands.     (line  885)\n* at91sam7 gpnvm:                        Flash Commands.     (line  918)\n* at91sam9:                              Flash Commands.     (line 2399)\n* at91sam9 ale:                          Flash Commands.     (line 2413)\n* at91sam9 ce:                           Flash Commands.     (line 2424)\n* at91sam9 cle:                          Flash Commands.     (line 2410)\n* at91sam9 rdy_busy:                     Flash Commands.     (line 2419)\n* at91samd:                              Flash Commands.     (line  669)\n* at91samd bootloader:                   Flash Commands.     (line  710)\n* at91samd chip-erase:                   Flash Commands.     (line  680)\n* at91samd dsu_reset_deassert:           Flash Commands.     (line  722)\n* at91samd eeprom:                       Flash Commands.     (line  696)\n* at91samd nvmuserrow:                   Flash Commands.     (line  727)\n* at91samd set-security:                 Flash Commands.     (line  685)\n* ath79:                                 Flash Commands.     (line  580)\n* atsame5:                               Flash Commands.     (line  818)\n* atsame5 bootloader:                    Flash Commands.     (line  829)\n* atsame5 chip-erase:                    Flash Commands.     (line  841)\n* atsame5 dsu_reset_deassert:            Flash Commands.     (line  846)\n* atsame5 userpage:                      Flash Commands.     (line  851)\n* atsamv:                                Flash Commands.     (line  871)\n* atsamv gpnvm:                          Flash Commands.     (line  878)\n* atsamv gpnvm <1>:                      Flash Commands.     (line  879)\n* avr:                                   Flash Commands.     (line  926)\n* bcm2835gpio:                           Debug Adapter Configuration.\n                                                             (line  788)\n* bcm2835gpio jtag_nums:                 Debug Adapter Configuration.\n                                                             (line  804)\n* bcm2835gpio peripheral_base:           Debug Adapter Configuration.\n                                                             (line  862)\n* bcm2835gpio speed_coeffs:              Debug Adapter Configuration.\n                                                             (line  856)\n* bcm2835gpio srst_num:                  Debug Adapter Configuration.\n                                                             (line  850)\n* bcm2835gpio swclk_num:                 Debug Adapter Configuration.\n                                                             (line  834)\n* bcm2835gpio swdio_dir_num:             Debug Adapter Configuration.\n                                                             (line  844)\n* bcm2835gpio swdio_num:                 Debug Adapter Configuration.\n                                                             (line  839)\n* bcm2835gpio swd_nums:                  Debug Adapter Configuration.\n                                                             (line  829)\n* bcm2835gpio tck_num:                   Debug Adapter Configuration.\n                                                             (line  809)\n* bcm2835gpio tdi_num:                   Debug Adapter Configuration.\n                                                             (line  824)\n* bcm2835gpio tdo_num:                   Debug Adapter Configuration.\n                                                             (line  819)\n* bcm2835gpio tms_num:                   Debug Adapter Configuration.\n                                                             (line  814)\n* bcm2835gpio trst_num:                  Debug Adapter Configuration.\n                                                             (line  853)\n* bindto:                                General Commands.   (line   94)\n* bluenrg-x:                             Flash Commands.     (line  930)\n* bp:                                    General Commands.   (line  387)\n* buspirate:                             Debug Adapter Configuration.\n                                                             (line 1108)\n* buspirate led:                         Debug Adapter Configuration.\n                                                             (line 1151)\n* buspirate mode:                        Debug Adapter Configuration.\n                                                             (line 1129)\n* buspirate port:                        Debug Adapter Configuration.\n                                                             (line 1120)\n* buspirate pullup:                      Debug Adapter Configuration.\n                                                             (line 1138)\n* buspirate speed:                       Debug Adapter Configuration.\n                                                             (line 1124)\n* buspirate vreg:                        Debug Adapter Configuration.\n                                                             (line 1145)\n* cache_config l2x:                      Architecture and Core Commands.\n                                                             (line  709)\n* cc26xx:                                Flash Commands.     (line  948)\n* cc3220sf:                              Flash Commands.     (line  958)\n* cfi:                                   Flash Commands.     (line  293)\n* cmsis-dap:                             Debug Adapter Configuration.\n                                                             (line  107)\n* cmsis-dap cmd:                         Debug Adapter Configuration.\n                                                             (line  137)\n* cmsis-dap info:                        Debug Adapter Configuration.\n                                                             (line  133)\n* cmsis_dap_backend:                     Debug Adapter Configuration.\n                                                             (line  118)\n* cmsis_dap_usb interface:               Debug Adapter Configuration.\n                                                             (line  127)\n* cmsis_dap_vid_pid:                     Debug Adapter Configuration.\n                                                             (line  111)\n* command mode:                          Server Configuration.\n                                                             (line   29)\n* cortex_a cache_info:                   Architecture and Core Commands.\n                                                             (line  687)\n* cortex_a dacrfixup:                    Architecture and Core Commands.\n                                                             (line  690)\n* cortex_a dbginit:                      Architecture and Core Commands.\n                                                             (line  696)\n* cortex_a maskisr:                      Architecture and Core Commands.\n                                                             (line  706)\n* cortex_a mmu dump:                     Architecture and Core Commands.\n                                                             (line  712)\n* cortex_a smp:                          Architecture and Core Commands.\n                                                             (line  700)\n* cortex_a smp_gdb:                      Architecture and Core Commands.\n                                                             (line  703)\n* cortex_m maskisr:                      Architecture and Core Commands.\n                                                             (line  900)\n* cortex_m reset_config:                 Architecture and Core Commands.\n                                                             (line  940)\n* cortex_m vector_catch:                 Architecture and Core Commands.\n                                                             (line  924)\n* cortex_r4 dbginit:                     Architecture and Core Commands.\n                                                             (line  722)\n* cortex_r4 maskisr:                     Architecture and Core Commands.\n                                                             (line  726)\n* cti create:                            Architecture and Core Commands.\n                                                             (line  232)\n* cti names:                             Architecture and Core Commands.\n                                                             (line  264)\n* dap create:                            TAP Declaration.    (line  387)\n* dap info:                              TAP Declaration.    (line  421)\n* dap init:                              Server Configuration.\n                                                             (line   81)\n* dap init <1>:                          TAP Declaration.    (line  425)\n* dap names:                             TAP Declaration.    (line  417)\n* davinci:                               Flash Commands.     (line 2430)\n* debug_level:                           General Commands.   (line   72)\n* drscan:                                JTAG Commands.      (line   42)\n* dummy:                                 Debug Adapter Configuration.\n                                                             (line  147)\n* dummy <1>:                             Architecture and Core Commands.\n                                                             (line  190)\n* dump_image:                            General Commands.   (line  329)\n* du_select:                             Architecture and Core Commands.\n                                                             (line 1219)\n* echo:                                  General Commands.   (line   82)\n* efm32:                                 Flash Commands.     (line  970)\n* ep93xx:                                Debug Adapter Configuration.\n                                                             (line  150)\n* esirisc:                               Flash Commands.     (line  995)\n* esirisc cache_arch:                    Architecture and Core Commands.\n                                                             (line 1007)\n* esirisc flash mass_erase:              Flash Commands.     (line 1006)\n* esirisc flash ref_erase:               Flash Commands.     (line 1010)\n* esirisc flush_caches:                  Architecture and Core Commands.\n                                                             (line 1021)\n* esirisc hwdc:                          Architecture and Core Commands.\n                                                             (line 1012)\n* esirisc trace analyze:                 Architecture and Core Commands.\n                                                             (line 1149)\n* esirisc trace buffer:                  Architecture and Core Commands.\n                                                             (line 1051)\n* esirisc trace dump:                    Architecture and Core Commands.\n                                                             (line 1155)\n* esirisc trace fifo:                    Architecture and Core Commands.\n                                                             (line 1056)\n* esirisc trace flow_control:            Architecture and Core Commands.\n                                                             (line 1059)\n* esirisc trace format:                  Architecture and Core Commands.\n                                                             (line 1063)\n* esirisc trace info:                    Architecture and Core Commands.\n                                                             (line 1137)\n* esirisc trace init:                    Architecture and Core Commands.\n                                                             (line 1132)\n* esirisc trace start:                   Architecture and Core Commands.\n                                                             (line 1143)\n* esirisc trace status:                  Architecture and Core Commands.\n                                                             (line 1140)\n* esirisc trace stop:                    Architecture and Core Commands.\n                                                             (line 1146)\n* esirisc trace trigger delay:           Architecture and Core Commands.\n                                                             (line 1119)\n* esirisc trace trigger start:           Architecture and Core Commands.\n                                                             (line 1076)\n* esirisc trace trigger stop:            Architecture and Core Commands.\n                                                             (line 1099)\n* etb:                                   Architecture and Core Commands.\n                                                             (line  198)\n* etb config:                            Architecture and Core Commands.\n                                                             (line  201)\n* etb trigger_percent:                   Architecture and Core Commands.\n                                                             (line  204)\n* etm analyze:                           Architecture and Core Commands.\n                                                             (line  166)\n* etm config:                            Architecture and Core Commands.\n                                                             (line   63)\n* etm dump:                              Architecture and Core Commands.\n                                                             (line  170)\n* etm image:                             Architecture and Core Commands.\n                                                             (line  173)\n* etm info:                              Architecture and Core Commands.\n                                                             (line   89)\n* etm load:                              Architecture and Core Commands.\n                                                             (line  176)\n* etm start:                             Architecture and Core Commands.\n                                                             (line  179)\n* etm status:                            Architecture and Core Commands.\n                                                             (line   95)\n* etm stop:                              Architecture and Core Commands.\n                                                             (line  182)\n* etm tracemode:                         Architecture and Core Commands.\n                                                             (line  100)\n* etm trigger_debug:                     Architecture and Core Commands.\n                                                             (line  119)\n* etm_dummy config:                      Architecture and Core Commands.\n                                                             (line  195)\n* exit:                                  General Commands.   (line   30)\n* fast_load:                             General Commands.   (line  333)\n* fast_load_image:                       General Commands.   (line  337)\n* fespi:                                 Flash Commands.     (line  613)\n* find:                                  Config File Guidelines.\n                                                             (line   57)\n* flash bank:                            Flash Commands.     (line   36)\n* flash banks:                           Flash Commands.     (line   67)\n* flash erase_address:                   Flash Commands.     (line  135)\n* flash erase_check:                     Flash Commands.     (line  230)\n* flash erase_sector:                    Flash Commands.     (line  129)\n* flash fillb:                           Flash Commands.     (line  149)\n* flash filld:                           Flash Commands.     (line  146)\n* flash fillh:                           Flash Commands.     (line  148)\n* flash fillw:                           Flash Commands.     (line  147)\n* flash info:                            Flash Commands.     (line  234)\n* flash init:                            Server Configuration.\n                                                             (line   82)\n* flash list:                            Flash Commands.     (line   72)\n* flash mdb:                             Flash Commands.     (line  162)\n* flash mdh:                             Flash Commands.     (line  161)\n* flash mdw:                             Flash Commands.     (line  160)\n* flash padded_value:                    Flash Commands.     (line  252)\n* flash probe:                           Flash Commands.     (line   77)\n* flash protect:                         Flash Commands.     (line  242)\n* flash read_bank:                       Flash Commands.     (line  176)\n* flash verify_bank:                     Flash Commands.     (line  183)\n* flash verify_image:                    Flash Commands.     (line  217)\n* flash write_bank:                      Flash Commands.     (line  170)\n* flash write_image:                     Flash Commands.     (line  189)\n* flush_count:                           JTAG Commands.      (line   70)\n* fm3:                                   Flash Commands.     (line 1014)\n* fm4:                                   Flash Commands.     (line 1023)\n* ft232r:                                Debug Adapter Configuration.\n                                                             (line  282)\n* ft232r jtag_nums:                      Debug Adapter Configuration.\n                                                             (line  322)\n* ft232r restore_serial:                 Debug Adapter Configuration.\n                                                             (line  350)\n* ft232r srst_num:                       Debug Adapter Configuration.\n                                                             (line  346)\n* ft232r tck_num:                        Debug Adapter Configuration.\n                                                             (line  326)\n* ft232r tdi_num:                        Debug Adapter Configuration.\n                                                             (line  334)\n* ft232r tdo_num:                        Debug Adapter Configuration.\n                                                             (line  338)\n* ft232r tms_num:                        Debug Adapter Configuration.\n                                                             (line  330)\n* ft232r trst_num:                       Debug Adapter Configuration.\n                                                             (line  342)\n* ft232r vid_pid:                        Debug Adapter Configuration.\n                                                             (line  318)\n* ftdi:                                  Debug Adapter Configuration.\n                                                             (line  154)\n* ftdi channel:                          Debug Adapter Configuration.\n                                                             (line  206)\n* ftdi device_desc:                      Debug Adapter Configuration.\n                                                             (line  201)\n* ftdi get_signal:                       Debug Adapter Configuration.\n                                                             (line  263)\n* ftdi layout_init:                      Debug Adapter Configuration.\n                                                             (line  211)\n* ftdi layout_signal:                    Debug Adapter Configuration.\n                                                             (line  221)\n* ftdi set_signal:                       Debug Adapter Configuration.\n                                                             (line  257)\n* ftdi tdo_sample_edge:                  Debug Adapter Configuration.\n                                                             (line  266)\n* ftdi vid_pid:                          Debug Adapter Configuration.\n                                                             (line  196)\n* gdb_breakpoint_override:               Server Configuration.\n                                                             (line  178)\n* gdb_flash_program:                     Server Configuration.\n                                                             (line  185)\n* gdb_memory_map:                        Server Configuration.\n                                                             (line  189)\n* gdb_port:                              Server Configuration.\n                                                             (line  125)\n* gdb_report_data_abort:                 Server Configuration.\n                                                             (line  197)\n* gdb_report_register_access_error:      Server Configuration.\n                                                             (line  202)\n* gdb_save_tdesc:                        Server Configuration.\n                                                             (line  212)\n* gdb_target_description:                Server Configuration.\n                                                             (line  207)\n* get_reg:                               General Commands.   (line  155)\n* gw16012:                               Debug Adapter Configuration.\n                                                             (line  424)\n* halt:                                  General Commands.   (line  199)\n* help:                                  General Commands.   (line   33)\n* hla:                                   Debug Adapter Configuration.\n                                                             (line  662)\n* hla_command:                           Debug Adapter Configuration.\n                                                             (line  692)\n* hla_device_desc:                       Debug Adapter Configuration.\n                                                             (line  674)\n* hla_layout:                            Debug Adapter Configuration.\n                                                             (line  677)\n* hla_stlink_backend:                    Debug Adapter Configuration.\n                                                             (line  683)\n* hla_vid_pid:                           Debug Adapter Configuration.\n                                                             (line  680)\n* imx_gpio:                              Debug Adapter Configuration.\n                                                             (line  869)\n* init:                                  Server Configuration.\n                                                             (line   59)\n* init_reset:                            Reset Configuration.\n                                                             (line  258)\n* ipdbg:                                 Boundary Scan Commands.\n                                                             (line   81)\n* irscan:                                JTAG Commands.      (line   81)\n* itm port:                              Architecture and Core Commands.\n                                                             (line  890)\n* itm ports:                             Architecture and Core Commands.\n                                                             (line  894)\n* jlink:                                 Debug Adapter Configuration.\n                                                             (line  434)\n* jlink config:                          Debug Adapter Configuration.\n                                                             (line  459)\n* jlink config ip:                       Debug Adapter Configuration.\n                                                             (line  467)\n* jlink config mac:                      Debug Adapter Configuration.\n                                                             (line  464)\n* jlink config reset:                    Debug Adapter Configuration.\n                                                             (line  475)\n* jlink config targetpower:              Debug Adapter Configuration.\n                                                             (line  461)\n* jlink config usb:                      Debug Adapter Configuration.\n                                                             (line  471)\n* jlink config write:                    Debug Adapter Configuration.\n                                                             (line  477)\n* jlink emucom read:                     Debug Adapter Configuration.\n                                                             (line  487)\n* jlink emucom write:                    Debug Adapter Configuration.\n                                                             (line  480)\n* jlink freemem:                         Debug Adapter Configuration.\n                                                             (line  454)\n* jlink hwstatus:                        Debug Adapter Configuration.\n                                                             (line  451)\n* jlink jtag:                            Debug Adapter Configuration.\n                                                             (line  456)\n* jlink usb:                             Debug Adapter Configuration.\n                                                             (line  495)\n* jtag arp_init:                         Reset Configuration.\n                                                             (line  276)\n* jtag arp_init-reset:                   Reset Configuration.\n                                                             (line  286)\n* jtag cget:                             TAP Declaration.    (line  205)\n* jtag cget <1>:                         TAP Declaration.    (line  208)\n* jtag configure:                        TAP Declaration.    (line  209)\n* jtag names:                            TAP Declaration.    (line   81)\n* jtag newtap:                           TAP Declaration.    (line  113)\n* jtag tapdisable:                       TAP Declaration.    (line  303)\n* jtag tapenable:                        TAP Declaration.    (line  308)\n* jtag tapisenabled:                     TAP Declaration.    (line  313)\n* jtagspi:                               Flash Commands.     (line  328)\n* jtagspi always_4byte:                  Flash Commands.     (line  381)\n* jtagspi cmd:                           Flash Commands.     (line  375)\n* jtagspi set:                           Flash Commands.     (line  366)\n* jtag_dpi:                              Debug Adapter Configuration.\n                                                             (line 1095)\n* jtag_dpi set_address:                  Debug Adapter Configuration.\n                                                             (line 1104)\n* jtag_dpi set_port:                     Debug Adapter Configuration.\n                                                             (line 1100)\n* jtag_init:                             Server Configuration.\n                                                             (line  100)\n* jtag_ntrst_assert_width:               Reset Configuration.\n                                                             (line  133)\n* jtag_ntrst_delay:                      Reset Configuration.\n                                                             (line  138)\n* jtag_rclk:                             Debug Adapter Configuration.\n                                                             (line 1303)\n* kinetis:                               Flash Commands.     (line 1039)\n* kinetis create_banks:                  Flash Commands.     (line 1054)\n* kinetis disable_wdog:                  Flash Commands.     (line 1122)\n* kinetis fcf_source:                    Flash Commands.     (line 1060)\n* kinetis fopt:                          Flash Commands.     (line 1072)\n* kinetis mdm check_security:            Flash Commands.     (line 1076)\n* kinetis mdm halt:                      Flash Commands.     (line 1080)\n* kinetis mdm mass_erase:                Flash Commands.     (line 1085)\n* kinetis mdm reset:                     Flash Commands.     (line 1117)\n* kinetis nvm_partition:                 Flash Commands.     (line 1092)\n* kinetis_ke:                            Flash Commands.     (line 1126)\n* kinetis_ke disable_wdog:               Flash Commands.     (line 1145)\n* kinetis_ke mdm check_security:         Flash Commands.     (line 1135)\n* kinetis_ke mdm mass_erase:             Flash Commands.     (line 1139)\n* kitprog:                               Debug Adapter Configuration.\n                                                             (line  504)\n* kitprog acquire_psoc:                  Debug Adapter Configuration.\n                                                             (line  545)\n* kitprog info:                          Debug Adapter Configuration.\n                                                             (line  552)\n* kitprog_init_acquire_psoc:             Debug Adapter Configuration.\n                                                             (line  540)\n* linuxgpiod:                            Debug Adapter Configuration.\n                                                             (line  965)\n* linuxgpiod gpiochip:                   Debug Adapter Configuration.\n                                                             (line  972)\n* linuxgpiod jtag_nums:                  Debug Adapter Configuration.\n                                                             (line  979)\n* linuxgpiod led_num:                    Debug Adapter Configuration.\n                                                             (line 1033)\n* linuxgpiod srst_num:                   Debug Adapter Configuration.\n                                                             (line 1029)\n* linuxgpiod swclk_num:                  Debug Adapter Configuration.\n                                                             (line 1013)\n* linuxgpiod swdio_dir_num:              Debug Adapter Configuration.\n                                                             (line 1023)\n* linuxgpiod swdio_num:                  Debug Adapter Configuration.\n                                                             (line 1018)\n* linuxgpiod swd_nums:                   Debug Adapter Configuration.\n                                                             (line 1008)\n* linuxgpiod tck_num:                    Debug Adapter Configuration.\n                                                             (line  984)\n* linuxgpiod tdi_num:                    Debug Adapter Configuration.\n                                                             (line  999)\n* linuxgpiod tdo_num:                    Debug Adapter Configuration.\n                                                             (line  994)\n* linuxgpiod tms_num:                    Debug Adapter Configuration.\n                                                             (line  989)\n* linuxgpiod trst_num:                   Debug Adapter Configuration.\n                                                             (line 1004)\n* load_image:                            General Commands.   (line  348)\n* log_output:                            General Commands.   (line   87)\n* lpc2000:                               Flash Commands.     (line 1148)\n* lpc2000 part_id:                       Flash Commands.     (line 1189)\n* lpc288x:                               Flash Commands.     (line 1193)\n* lpc2900:                               Flash Commands.     (line 1201)\n* lpc2900 password:                      Flash Commands.     (line 1257)\n* lpc2900 read_custom:                   Flash Commands.     (line 1246)\n* lpc2900 secure_jtag:                   Flash Commands.     (line 1292)\n* lpc2900 secure_sector:                 Flash Commands.     (line 1278)\n* lpc2900 signature:                     Flash Commands.     (line 1237)\n* lpc2900 write_custom:                  Flash Commands.     (line 1267)\n* lpc3180:                               Flash Commands.     (line 2443)\n* lpc3180 select:                        Flash Commands.     (line 2446)\n* lpcspifi:                              Flash Commands.     (line  422)\n* mdb:                                   General Commands.   (line  304)\n* mdd:                                   General Commands.   (line  301)\n* mdh:                                   General Commands.   (line  303)\n* mdr:                                   Flash Commands.     (line 1299)\n* mdw:                                   General Commands.   (line  302)\n* memTestAddressBus:                     Utility Commands.   (line   29)\n* memTestDataBus:                        Utility Commands.   (line   25)\n* memTestDevice:                         Utility Commands.   (line   34)\n* mrvlqspi:                              Flash Commands.     (line  571)\n* msp432:                                Flash Commands.     (line 1320)\n* msp432 bsl:                            Flash Commands.     (line 1339)\n* msp432 mass_erase:                     Flash Commands.     (line 1330)\n* mwb:                                   General Commands.   (line  317)\n* mwd:                                   General Commands.   (line  314)\n* mwh:                                   General Commands.   (line  316)\n* mww:                                   General Commands.   (line  315)\n* mx3:                                   Flash Commands.     (line 2456)\n* mxc:                                   Flash Commands.     (line 2460)\n* mxc biswap:                            Flash Commands.     (line 2468)\n* nand check_bad_blocks:                 Flash Commands.     (line 2358)\n* nand device:                           Flash Commands.     (line 2190)\n* nand dump:                             Flash Commands.     (line 2233)\n* nand erase:                            Flash Commands.     (line 2266)\n* nand info:                             Flash Commands.     (line 2370)\n* nand init:                             Server Configuration.\n                                                             (line   83)\n* nand list:                             Flash Commands.     (line 2213)\n* nand probe:                            Flash Commands.     (line 2223)\n* nand raw_access:                       Flash Commands.     (line 2375)\n* nand verify:                           Flash Commands.     (line 2332)\n* nand write:                            Flash Commands.     (line 2279)\n* niietcm4:                              Flash Commands.     (line 1351)\n* niietcm4 bflash_info_remap:            Flash Commands.     (line 1391)\n* niietcm4 driver_info:                  Flash Commands.     (line 1404)\n* niietcm4 extmem_cfg:                   Flash Commands.     (line 1395)\n* niietcm4 service_mode_erase:           Flash Commands.     (line 1400)\n* niietcm4 uflash_erase:                 Flash Commands.     (line 1378)\n* niietcm4 uflash_full_erase:            Flash Commands.     (line 1375)\n* niietcm4 uflash_protect:               Flash Commands.     (line 1386)\n* niietcm4 uflash_protect_check:         Flash Commands.     (line 1383)\n* niietcm4 uflash_read_byte:             Flash Commands.     (line 1368)\n* niietcm4 uflash_write_byte:            Flash Commands.     (line 1371)\n* noinit:                                Server Configuration.\n                                                             (line   94)\n* npcx:                                  Flash Commands.     (line 1407)\n* nrf5:                                  Flash Commands.     (line 1416)\n* nrf5 info:                             Flash Commands.     (line 1434)\n* nrf5 mass_erase:                       Flash Commands.     (line 1428)\n* ocd_find:                              Config File Guidelines.\n                                                             (line   60)\n* ocl:                                   Flash Commands.     (line 1437)\n* opendous:                              Debug Adapter Configuration.\n                                                             (line  744)\n* openjtag:                              Debug Adapter Configuration.\n                                                             (line 1043)\n* openjtag device_desc:                  Debug Adapter Configuration.\n                                                             (line 1057)\n* openjtag variant:                      Debug Adapter Configuration.\n                                                             (line 1047)\n* orion:                                 Flash Commands.     (line 2472)\n* parport:                               Debug Adapter Configuration.\n                                                             (line  556)\n* parport cable:                         Debug Adapter Configuration.\n                                                             (line  562)\n* parport port:                          Debug Adapter Configuration.\n                                                             (line   88)\n* parport port <1>:                      Debug Adapter Configuration.\n                                                             (line  428)\n* parport port <2>:                      Debug Adapter Configuration.\n                                                             (line  591)\n* parport toggling_time:                 Debug Adapter Configuration.\n                                                             (line  601)\n* parport write_on_exit:                 Debug Adapter Configuration.\n                                                             (line  635)\n* pathmove:                              JTAG Commands.      (line   98)\n* pic32mx:                               Flash Commands.     (line 1448)\n* pic32mx pgm_word:                      Flash Commands.     (line 1456)\n* pic32mx unlock:                        Flash Commands.     (line 1459)\n* pld device:                            PLD/FPGA Commands.  (line   23)\n* pld devices:                           PLD/FPGA Commands.  (line   28)\n* pld init:                              Server Configuration.\n                                                             (line   84)\n* pld load:                              PLD/FPGA Commands.  (line   31)\n* poll:                                  Server Configuration.\n                                                             (line  252)\n* presto:                                Debug Adapter Configuration.\n                                                             (line  647)\n* profile:                               General Commands.   (line  488)\n* program:                               Flash Commands.     (line  258)\n* psoc4:                                 Flash Commands.     (line 1463)\n* psoc4 flash_autoerase:                 Flash Commands.     (line 1475)\n* psoc4 mass_erase:                      Flash Commands.     (line 1488)\n* psoc5lp:                               Flash Commands.     (line 1494)\n* psoc5lp mass_erase:                    Flash Commands.     (line 1513)\n* psoc5lp_eeprom:                        Flash Commands.     (line 1518)\n* psoc5lp_nvl:                           Flash Commands.     (line 1527)\n* psoc6:                                 Flash Commands.     (line 1547)\n* psoc6 mass_erase:                      Flash Commands.     (line 1607)\n* psoc6 reset_halt:                      Flash Commands.     (line 1598)\n* rbp:                                   General Commands.   (line  397)\n* read_memory:                           General Commands.   (line  183)\n* reg:                                   General Commands.   (line  109)\n* remote_bitbang:                        Debug Adapter Configuration.\n                                                             (line  360)\n* remote_bitbang host:                   Debug Adapter Configuration.\n                                                             (line  372)\n* remote_bitbang port:                   Debug Adapter Configuration.\n                                                             (line  368)\n* reset:                                 General Commands.   (line  238)\n* reset halt:                            General Commands.   (line  240)\n* reset init:                            General Commands.   (line  241)\n* reset run:                             General Commands.   (line  239)\n* reset_config:                          Reset Configuration.\n                                                             (line  143)\n* resume:                                General Commands.   (line  229)\n* riscv authdata_read:                   Architecture and Core Commands.\n                                                             (line 1438)\n* riscv authdata_write:                  Architecture and Core Commands.\n                                                             (line 1441)\n* riscv dmi_read:                        Architecture and Core Commands.\n                                                             (line 1450)\n* riscv dmi_write:                       Architecture and Core Commands.\n                                                             (line 1453)\n* riscv expose_csrs:                     Architecture and Core Commands.\n                                                             (line 1302)\n* riscv expose_custom:                   Architecture and Core Commands.\n                                                             (line 1324)\n* riscv resume_order:                    Architecture and Core Commands.\n                                                             (line 1387)\n* riscv set_command_timeout_sec:         Architecture and Core Commands.\n                                                             (line 1347)\n* riscv set_ebreakm:                     Architecture and Core Commands.\n                                                             (line 1414)\n* riscv set_ebreaks:                     Architecture and Core Commands.\n                                                             (line 1419)\n* riscv set_ebreaku:                     Architecture and Core Commands.\n                                                             (line 1424)\n* riscv set_enable_virt2phys:            Architecture and Core Commands.\n                                                             (line 1382)\n* riscv set_enable_virtual:              Architecture and Core Commands.\n                                                             (line 1377)\n* riscv set_ir:                          Architecture and Core Commands.\n                                                             (line 1399)\n* riscv set_mem_access:                  Architecture and Core Commands.\n                                                             (line 1361)\n* riscv set_reset_timeout_sec:           Architecture and Core Commands.\n                                                             (line 1352)\n* riscv set_scratch_ram:                 Architecture and Core Commands.\n                                                             (line 1356)\n* riscv use_bscan_tunnel:                Architecture and Core Commands.\n                                                             (line 1409)\n* rlink:                                 Debug Adapter Configuration.\n                                                             (line  650)\n* rp2040:                                Flash Commands.     (line 1612)\n* rtck:                                  Debug Adapter Configuration.\n                                                             (line   92)\n* rtt channellist:                       General Commands.   (line  461)\n* rtt channels:                          General Commands.   (line  458)\n* rtt polling_interval:                  General Commands.   (line  453)\n* rtt server start:                      General Commands.   (line  465)\n* rtt server stop:                       General Commands.   (line  468)\n* rtt setup:                             General Commands.   (line  440)\n* rtt start:                             General Commands.   (line  446)\n* rtt stop:                              General Commands.   (line  450)\n* runAllMemTests:                        Utility Commands.   (line   39)\n* runtest:                               JTAG Commands.      (line  106)\n* rwp:                                   General Commands.   (line  400)\n* s3c2410:                               Flash Commands.     (line 2480)\n* s3c2412:                               Flash Commands.     (line 2481)\n* s3c2440:                               Flash Commands.     (line 2482)\n* s3c2443:                               Flash Commands.     (line 2483)\n* s3c6400:                               Flash Commands.     (line 2484)\n* scan_chain:                            TAP Declaration.    (line   89)\n* set_reg:                               General Commands.   (line  143)\n* shutdown:                              General Commands.   (line   54)\n* sim3x:                                 Flash Commands.     (line 1620)\n* sim3x lock:                            Flash Commands.     (line 1636)\n* sim3x mass_erase:                      Flash Commands.     (line 1631)\n* sleep:                                 General Commands.   (line   48)\n* soft_reset_halt:                       General Commands.   (line  256)\n* st-link:                               Debug Adapter Configuration.\n                                                             (line  696)\n* st-link backend:                       Debug Adapter Configuration.\n                                                             (line  710)\n* st-link cmd:                           Debug Adapter Configuration.\n                                                             (line  725)\n* st-link vid_pid:                       Debug Adapter Configuration.\n                                                             (line  722)\n* stellaris:                             Flash Commands.     (line 1639)\n* stellaris recover:                     Flash Commands.     (line 1647)\n* step:                                  General Commands.   (line  234)\n* stm32f1x:                              Flash Commands.     (line 1660)\n* stm32f1x lock:                         Flash Commands.     (line 1683)\n* stm32f1x mass_erase:                   Flash Commands.     (line 1693)\n* stm32f1x options_load:                 Flash Commands.     (line 1710)\n* stm32f1x options_read:                 Flash Commands.     (line 1697)\n* stm32f1x options_write:                Flash Commands.     (line 1702)\n* stm32f1x unlock:                       Flash Commands.     (line 1687)\n* stm32f2x:                              Flash Commands.     (line 1717)\n* stm32f2x lock:                         Flash Commands.     (line 1742)\n* stm32f2x mass_erase:                   Flash Commands.     (line 1750)\n* stm32f2x optcr2_write:                 Flash Commands.     (line 1768)\n* stm32f2x options_read:                 Flash Commands.     (line 1754)\n* stm32f2x options_write:                Flash Commands.     (line 1759)\n* stm32f2x otp:                          Flash Commands.     (line 1730)\n* stm32f2x unlock:                       Flash Commands.     (line 1746)\n* stm32h7x:                              Flash Commands.     (line 1773)\n* stm32h7x lock:                         Flash Commands.     (line 1789)\n* stm32h7x mass_erase:                   Flash Commands.     (line 1797)\n* stm32h7x option_read:                  Flash Commands.     (line 1801)\n* stm32h7x option_write:                 Flash Commands.     (line 1816)\n* stm32h7x unlock:                       Flash Commands.     (line 1793)\n* stm32l4x:                              Flash Commands.     (line 1861)\n* stm32l4x lock:                         Flash Commands.     (line 1888)\n* stm32l4x mass_erase:                   Flash Commands.     (line 1902)\n* stm32l4x option_load:                  Flash Commands.     (line 1952)\n* stm32l4x option_read:                  Flash Commands.     (line 1906)\n* stm32l4x option_write:                 Flash Commands.     (line 1921)\n* stm32l4x otp:                          Flash Commands.     (line 1874)\n* stm32l4x trustzone:                    Flash Commands.     (line 1957)\n* stm32l4x unlock:                       Flash Commands.     (line 1895)\n* stm32l4x wrp_info:                     Flash Commands.     (line 1939)\n* stm32lx:                               Flash Commands.     (line 1828)\n* stm32lx lock:                          Flash Commands.     (line 1847)\n* stm32lx mass_erase:                    Flash Commands.     (line 1855)\n* stm32lx unlock:                        Flash Commands.     (line 1851)\n* stmqspi:                               Flash Commands.     (line  459)\n* stmqspi cmd:                           Flash Commands.     (line  541)\n* stmqspi mass_erase:                    Flash Commands.     (line  520)\n* stmqspi set:                           Flash Commands.     (line  524)\n* stmsmi:                                Flash Commands.     (line  439)\n* str7x:                                 Flash Commands.     (line 1965)\n* str7x disable_jtag:                    Flash Commands.     (line 1974)\n* str9x:                                 Flash Commands.     (line 1978)\n* str9x flash_config:                    Flash Commands.     (line 1987)\n* str9xpec:                              Flash Commands.     (line 1996)\n* str9xpec disable_turbo:                Flash Commands.     (line 2039)\n* str9xpec enable_turbo:                 Flash Commands.     (line 2042)\n* str9xpec lock:                         Flash Commands.     (line 2046)\n* str9xpec options_cmap:                 Flash Commands.     (line 2053)\n* str9xpec options_lvdsel:               Flash Commands.     (line 2056)\n* str9xpec options_lvdthd:               Flash Commands.     (line 2059)\n* str9xpec options_lvdwarn:              Flash Commands.     (line 2062)\n* str9xpec options_read:                 Flash Commands.     (line 2065)\n* str9xpec options_write:                Flash Commands.     (line 2068)\n* str9xpec part_id:                      Flash Commands.     (line 2050)\n* str9xpec unlock:                       Flash Commands.     (line 2071)\n* svf:                                   Boundary Scan Commands.\n                                                             (line   17)\n* swd newdap:                            Debug Adapter Configuration.\n                                                             (line 1211)\n* swm050:                                Flash Commands.     (line 2074)\n* swm050 mass_erase:                     Flash Commands.     (line 2082)\n* swo:                                   Architecture and Core Commands.\n                                                             (line  748)\n* sysfsgpio:                             Debug Adapter Configuration.\n                                                             (line 1037)\n* tap_select:                            Architecture and Core Commands.\n                                                             (line 1216)\n* target create:                         CPU Configuration.  (line  198)\n* target current:                        CPU Configuration.  (line   37)\n* target init:                           Server Configuration.\n                                                             (line   79)\n* target names:                          CPU Configuration.  (line   40)\n* target types:                          CPU Configuration.  (line   71)\n* targets:                               CPU Configuration.  (line   46)\n* target_request debugmsgs:              Architecture and Core Commands.\n                                                             (line 1725)\n* tcl_notifications:                     Tcl Scripting API.  (line   93)\n* tcl_port:                              Server Configuration.\n                                                             (line  155)\n* tcl_trace:                             Tcl Scripting API.  (line  108)\n* telnet_port:                           Server Configuration.\n                                                             (line  163)\n* test_image:                            General Commands.   (line  363)\n* tms470:                                Flash Commands.     (line 2085)\n* tms470 flash_keyset:                   Flash Commands.     (line 2092)\n* tms470 osc_megahertz:                  Flash Commands.     (line 2096)\n* tms470 plldis:                         Flash Commands.     (line 2099)\n* tpiu create:                           Architecture and Core Commands.\n                                                             (line  752)\n* tpiu init:                             Server Configuration.\n                                                             (line   85)\n* tpiu init <1>:                         Architecture and Core Commands.\n                                                             (line  772)\n* tpiu names:                            Architecture and Core Commands.\n                                                             (line  768)\n* trace history:                         Architecture and Core Commands.\n                                                             (line 1735)\n* trace point:                           Architecture and Core Commands.\n                                                             (line 1741)\n* transport init:                        Server Configuration.\n                                                             (line   80)\n* transport list:                        Debug Adapter Configuration.\n                                                             (line 1161)\n* transport select:                      Debug Adapter Configuration.\n                                                             (line 1165)\n* ulink:                                 Debug Adapter Configuration.\n                                                             (line  747)\n* usage:                                 General Commands.   (line   43)\n* usbprog:                               Debug Adapter Configuration.\n                                                             (line  653)\n* usb_blaster:                           Debug Adapter Configuration.\n                                                             (line  391)\n* usb_blaster firmware:                  Debug Adapter Configuration.\n                                                             (line  420)\n* usb_blaster lowlevel_driver:           Debug Adapter Configuration.\n                                                             (line  415)\n* usb_blaster pin:                       Debug Adapter Configuration.\n                                                             (line  405)\n* usb_blaster vid_pid:                   Debug Adapter Configuration.\n                                                             (line  397)\n* vdebug:                                Debug Adapter Configuration.\n                                                             (line 1061)\n* vdebug batching:                       Debug Adapter Configuration.\n                                                             (line 1068)\n* vdebug bfm_path:                       Debug Adapter Configuration.\n                                                             (line 1081)\n* vdebug mem_path:                       Debug Adapter Configuration.\n                                                             (line 1087)\n* vdebug polling:                        Debug Adapter Configuration.\n                                                             (line 1074)\n* vdebug server:                         Debug Adapter Configuration.\n                                                             (line 1064)\n* verify_image:                          General Commands.   (line  369)\n* verify_image_checksum:                 General Commands.   (line  375)\n* verify_ircapture:                      JTAG Commands.      (line  111)\n* verify_jtag:                           JTAG Commands.      (line  117)\n* version:                               General Commands.   (line  494)\n* virt2phys:                             General Commands.   (line  497)\n* virtex2:                               PLD/FPGA Commands.  (line   42)\n* virtex2 read_stat:                     PLD/FPGA Commands.  (line   50)\n* virtual:                               Flash Commands.     (line  271)\n* vsllink:                               Debug Adapter Configuration.\n                                                             (line  656)\n* w600:                                  Flash Commands.     (line 2103)\n* wait_halt:                             General Commands.   (line  200)\n* wp:                                    General Commands.   (line  403)\n* write_memory:                          General Commands.   (line  168)\n* x86_32 idb:                            Architecture and Core Commands.\n                                                             (line 1191)\n* x86_32 idh:                            Architecture and Core Commands.\n                                                             (line 1187)\n* x86_32 idw:                            Architecture and Core Commands.\n                                                             (line 1183)\n* x86_32 iwb:                            Architecture and Core Commands.\n                                                             (line 1203)\n* x86_32 iwh:                            Architecture and Core Commands.\n                                                             (line 1199)\n* x86_32 iww:                            Architecture and Core Commands.\n                                                             (line 1195)\n* xcf:                                   Flash Commands.     (line  386)\n* xcf ccb:                               Flash Commands.     (line  394)\n* xcf configure:                         Flash Commands.     (line  410)\n* xds110:                                Debug Adapter Configuration.\n                                                             (line  750)\n* xds110 info:                           Debug Adapter Configuration.\n                                                             (line  763)\n* xds110 supply:                         Debug Adapter Configuration.\n                                                             (line  757)\n* xlnx_pcie_xvc:                         Debug Adapter Configuration.\n                                                             (line  767)\n* xlnx_pcie_xvc config:                  Debug Adapter Configuration.\n                                                             (line  778)\n* xmc1xxx:                               Flash Commands.     (line 2110)\n* xmc4xxx:                               Flash Commands.     (line 2115)\n* xmc4xxx flash_password:                Flash Commands.     (line 2122)\n* xmc4xxx flash_unprotect:               Flash Commands.     (line 2126)\n* xscale analyze_trace:                  Architecture and Core Commands.\n                                                             (line  580)\n* xscale cache_clean_address:            Architecture and Core Commands.\n                                                             (line  583)\n* xscale cache_info:                     Architecture and Core Commands.\n                                                             (line  586)\n* xscale cp15:                           Architecture and Core Commands.\n                                                             (line  589)\n* xscale dcache:                         Architecture and Core Commands.\n                                                             (line  596)\n* xscale debug_handler:                  Architecture and Core Commands.\n                                                             (line  593)\n* xscale dump_trace:                     Architecture and Core Commands.\n                                                             (line  599)\n* xscale icache:                         Architecture and Core Commands.\n                                                             (line  602)\n* xscale mmu:                            Architecture and Core Commands.\n                                                             (line  605)\n* xscale trace_buffer:                   Architecture and Core Commands.\n                                                             (line  608)\n* xscale trace_image:                    Architecture and Core Commands.\n                                                             (line  612)\n* xscale vector_catch:                   Architecture and Core Commands.\n                                                             (line  618)\n* xscale vector_table:                   Architecture and Core Commands.\n                                                             (line  633)\n* xsvf:                                  Boundary Scan Commands.\n                                                             (line   46)\n* xtensa maskisr:                        Architecture and Core Commands.\n                                                             (line 1616)\n* xtensa perfmon_dump:                   Architecture and Core Commands.\n                                                             (line 1661)\n* xtensa perfmon_enable:                 Architecture and Core Commands.\n                                                             (line 1647)\n* xtensa set_permissive:                 Architecture and Core Commands.\n                                                             (line 1610)\n* xtensa smpbreak:                       Architecture and Core Commands.\n                                                             (line 1620)\n* xtensa tracedump:                      Architecture and Core Commands.\n                                                             (line 1680)\n* xtensa tracestart:                     Architecture and Core Commands.\n                                                             (line 1665)\n* xtensa tracestop:                      Architecture and Core Commands.\n                                                             (line 1677)\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/man/man1/openocd.1",
    "content": ".TH \"OPENOCD\" \"1\" \"November 24, 2009\"\n.SH \"NAME\"\nopenocd \\- A free and open on\\-chip debugging, in\\-system programming and\nboundary\\-scan testing tool for ARM and MIPS systems\n.SH \"SYNOPSIS\"\n.B openocd \\fR[\\fB\\-fsdlcphv\\fR] [\\fB\\-\\-file\\fR <filename>] [\\fB\\-\\-search\\fR <dirname>] [\\fB\\-\\-debug\\fR <debuglevel>] [\\fB\\-\\-log_output\\fR <filename>] [\\fB\\-\\-command\\fR <cmd>] [\\fB\\-\\-pipe\\fR] [\\fB\\-\\-help\\fR] [\\fB\\-\\-version\\fR]\n.SH \"DESCRIPTION\"\n.B OpenOCD\nis an on\\-chip debugging, in\\-system programming and boundary\\-scan\ntesting tool for various ARM and MIPS systems.\n.PP\nThe debugger uses an IEEE 1149\\-1 compliant JTAG TAP bus master to access\non\\-chip debug functionality available on ARM based microcontrollers or\nsystem-on-chip solutions. For MIPS systems the EJTAG interface is supported.\n.PP\nUser interaction is realized through a telnet command line interface,\na gdb (the GNU debugger) remote protocol server, and a simplified RPC\nconnection that can be used to interface with OpenOCD's Jim Tcl engine.\n.PP\nOpenOCD supports various different types of JTAG interfaces/programmers,\nplease check the \\fIopenocd\\fR info page for the complete list.\n.SH \"OPTIONS\"\n.TP\n.B \"\\-f, \\-\\-file <filename>\"\nThis is a shortcut for a \\fB\\-c \"[script \\fI<filename>\\fB]\"\\fR\ncommand, using a search path to load the configuration file\n.IR <filename> .\nIn order to specify multiple config files, you can use multiple\n.B \\-\\-file\narguments. If no such \\fB\\-c\\fR\noptions are included, the first config file\n.B openocd.cfg\nin the search path will be used.\n.TP\n.B \"\\-s, \\-\\-search <dirname>\"\nAdd\n.I <dirname>\nto the search path used for config files and scripts.\nThe search path begins with the current directory,\nthen includes these additional directories before other\ncomponents such as the standard OpenOCD script libraries.\n.TP\n.B \"\\-d, \\-\\-debug <debuglevel>\"\nSet debug level. Possible values are:\n.br\n.RB \"  * \" 0 \" (errors)\"\n.br\n.RB \"  * \" 1 \" (warnings)\"\n.br\n.RB \"  * \" 2 \" (informational messages)\"\n.br\n.RB \"  * \" 3 \" (debug messages)\"\n.br\nThe default level is\n.BR 2 .\n.TP\n.B \"\\-l, \\-\\-log_output <filename>\"\nRedirect log output to the file\n.IR <filename> .\nPer default the log output is printed on\n.BR stderr .\n.TP\n.B \"\\-c, \\-\\-command <cmd>\"\nAdd the command\n.I <cmd>\nto a list of commands executed on server startup.\nNote that you will need to explicitly invoke\n.I init\nif the command requires access to a target or flash.\n.TP\n.B \"\\-p, \\-\\-pipe\"\nUse pipes when talking to gdb.\n.TP\n.B \"\\-h, \\-\\-help\"\nShow a help text and exit.\n.TP\n.B \"\\-v, \\-\\-version\"\nShow version information and exit.\n.SH \"BUGS\"\nPlease report any bugs on the mailing list at\n.BR openocd\\-devel@lists.sourceforge.net .\n.SH \"LICENCE\"\n.B OpenOCD\nis covered by the GNU General Public License (GPL), version 2 or later.\n.SH \"SEE ALSO\"\n.BR jtag (1)\n.PP\nThe full documentation for\n.B openocd\nis maintained as a Texinfo manual. If the\n.BR info\n(or\n.BR pinfo )\nand\n.BR openocd\nprograms are properly installed at your site, the command\n.B info openocd\nshould give you access to the complete manual.\n.SH \"AUTHORS\"\nPlease see the file AUTHORS.\n.PP\nThis manual page was written by Uwe Hermann <uwe@hermann\\-uwe.de>.\nIt is licensed under the terms of the GNU GPL (version 2 or later).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/contrib/60-openocd.rules",
    "content": "# Copy this file to /etc/udev/rules.d/\n# If rules fail to reload automatically, you can refresh udev rules\n# with the command \"udevadm control --reload\"\n\nACTION!=\"add|change\", GOTO=\"openocd_rules_end\"\n\nSUBSYSTEM==\"gpio\", MODE=\"0660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nSUBSYSTEM!=\"usb|tty|hidraw\", GOTO=\"openocd_rules_end\"\n\n# Please keep this list sorted by VID:PID\n\n# opendous and estick\nATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"204f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232/FT245 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT2232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT4232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232H VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Original FT231XQ VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# DISTORTEC JTAG-lock-pick Tiny 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8220\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TUMPA, TUMPA Lite\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a98\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a99\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell OpenRD JTAGKey FT2232D B\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"9e90\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# XDS100v2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# XDS100v3\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OOCDLink\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"baf8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Kristech KT-Link\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bbe2\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris Evaluation Board FTDI (several)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcd9\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcda\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# egnite Turtelizer 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bdc8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Section5 ICEbear\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c140\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c141\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey and JTAGkey-tiny\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"cff8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ASIX Presto programmer\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"f1a0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Nuvoton NuLink\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5200\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5201\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI ICDI\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"c32a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK V1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3744\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3748\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2.1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3752\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics STLINK-V3\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3753\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3754\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress SuperSpeed Explorer Kit\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"0007\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in KitProg mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f139\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in CMSIS-DAP mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f138\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Infineon DAP miniWiggler v3\nATTRS{idVendor}==\"058b\", ATTRS{idProduct}==\"0043\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex LPC1768-Stick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0026\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hilscher NXHX Boards\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0028\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STR9-comStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STM32-PerformanceStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex Cortino\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0032\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Altera USB Blaster\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Altera USB Blaster2\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6810\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ashling Opella-LD\nATTRS{idVendor}==\"0B6B\", ATTRS{idProduct}==\"0040\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey-HiSpeed\nATTRS{idVendor}==\"0fbb\", ATTRS{idProduct}==\"1000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# SEGGER J-Link\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0101\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0102\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0103\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0104\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0105\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0107\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0108\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1012\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1013\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1016\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1017\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1018\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1020\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1051\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1055\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1061\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Raisonance RLink\nATTRS{idVendor}==\"138e\", ATTRS{idProduct}==\"9000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Debug Board for Neo1973\nATTRS{idVendor}==\"1457\", ATTRS{idProduct}==\"5118\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OSBDM\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0042\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0058\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"005e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0003\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0004\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-JTAG-EW\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"001e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC\nATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"06ad\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# USBprog with OpenOCD firmware\nATTRS{idVendor}==\"1781\", ATTRS{idProduct}==\"0c63\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00fd\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI XDS110 Debug Probe (Launchpads and Standalone)\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef3\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef4\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"02a5\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI Tiva-based ICDI and XDS110 probes in DFU mode\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00ff\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# isodebug v1\nATTRS{idVendor}==\"22b7\", ATTRS{idProduct}==\"150d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# PLS USB/JTAG Adapter for SPC5xxx\nATTRS{idVendor}==\"263d\", ATTRS{idProduct}==\"4001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Numato Mimas A7 - Artix 7 FPGA Board\nATTRS{idVendor}==\"2a19\", ATTRS{idProduct}==\"1009\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ambiq Micro EVK and Debug boards.\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"1106\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell Sheevaplug\nATTRS{idVendor}==\"9e88\", ATTRS{idProduct}==\"9e8f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Keil Software, Inc. ULink\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2710\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2750\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# CMSIS-DAP compatible adapters\nATTRS{product}==\"*CMSIS-DAP*\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nLABEL=\"openocd_rules_end\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/contrib/libdcc/README",
    "content": "This code is an example of using the openocd debug message system.\n\nBefore the message output is seen in the debug window, the functionality\nwill need enabling:\n\nFrom the gdb prompt:\nmonitor target_request debugmsgs enable\nmonitor trace point 1\n\nFrom the Telnet prompt:\ntarget_request debugmsgs enable\ntrace point 1\n\nTo see how many times the trace point was hit:\n(monitor) trace point 1\n\nSpen\nspen@spen-soft.co.uk\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/contrib/libdcc/dcc_stdio.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n#define TARGET_REQ_TRACEMSG\t\t\t\t\t0x00\n#define TARGET_REQ_DEBUGMSG_ASCII\t\t\t0x01\n#define TARGET_REQ_DEBUGMSG_HEXMSG(size)\t(0x01 | ((size & 0xff) << 8))\n#define TARGET_REQ_DEBUGCHAR\t\t\t\t0x02\n\n#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)\n\n/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel\n * DCRDR[7:0] is used by target for status\n * DCRDR[15:8] is used by target for write buffer\n * DCRDR[23:16] is used for by host for status\n * DCRDR[31:24] is used for by host for write buffer */\n\n#define NVIC_DBG_DATA_R\t\t(*((volatile unsigned short *)0xE000EDF8))\n\n#define\tBUSY\t1\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tint len = 4;\n\n\twhile (len--)\n\t{\n\t\t/* wait for data ready */\n\t\twhile (NVIC_DBG_DATA_R & BUSY);\n\n\t\t/* write our data and set write flag - tell host there is data*/\n\t\tNVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);\n\t\tdcc_data >>= 8;\n\t}\n}\n\n#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tunsigned long dcc_status;\n\n\tdo {\n\t\tasm volatile(\"mrc p14, 0, %0, c0, c0\" : \"=r\" (dcc_status));\n\t} while (dcc_status & 0x2);\n\n\tasm volatile(\"mcr p14, 0, %0, c1, c0\" : : \"r\" (dcc_data));\n}\n\n#else\n #error unsupported target\n#endif\n\nvoid dbg_trace_point(unsigned long number)\n{\n\tdbg_write(TARGET_REQ_TRACEMSG | (number << 8));\n}\n\nvoid dbg_write_u32(const unsigned long *val, long len)\n{\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdbg_write(*val);\n\n\t\tval++;\n\t\tlen--;\n\t}\n}\n\nvoid dbg_write_u16(const unsigned short *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 16: 0x0000);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 2;\n\t\tlen -= 2;\n\t}\n}\n\nvoid dbg_write_u8(const unsigned char *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? val[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? val[3] << 24 : 0x00);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_str(const char *msg)\n{\n\tlong len;\n\tunsigned long dcc_data;\n\n\tfor (len = 0; msg[len] && (len < 65536); len++);\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = msg[0]\n\t\t\t| ((len > 1) ? msg[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? msg[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? msg[3] << 24 : 0x00);\n\t\tdbg_write(dcc_data);\n\n\t\tmsg += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_char(char msg)\n{\n\tdbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/contrib/libdcc/dcc_stdio.h",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#ifndef DCC_STDIO_H\n#define DCC_STDIO_H\n\nvoid dbg_trace_point(unsigned long number);\n\nvoid dbg_write_u32(const unsigned long *val, long len);\nvoid dbg_write_u16(const unsigned short *val, long len);\nvoid dbg_write_u8(const unsigned char *val, long len);\n\nvoid dbg_write_str(const char *msg);\nvoid dbg_write_char(char msg);\n\n#endif\t/* DCC_STDIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/contrib/libdcc/example.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n/* enable openocd debugmsg at the gdb prompt:\n * monitor target_request debugmsgs enable\n *\n * create a trace point:\n * monitor trace point 1\n *\n * to show how often the trace point was hit:\n * monitor trace point\n*/\n\nint main(void)\n{\n\tdbg_write_str(\"hello world\");\n\n\tdbg_write_char('t');\n\tdbg_write_char('e');\n\tdbg_write_char('s');\n\tdbg_write_char('t');\n\tdbg_write_char('\\n');\n\n\tunsigned long test_u32 = 0x01234567;\n\tdbg_write_u32(&test_u32, 1);\n\n\tstatic const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF};\n\tdbg_write_u16(test_u16, 8);\n\n\tstatic const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF};\n\tdbg_write_u8(test_u8, 16);\n\n\twhile(1)\n\t{\n\t\tdbg_trace_point(0);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/bitsbytes.tcl",
    "content": "#----------------------------------------\n# Purpose - Create some $BIT variables\n#           Create $K and $M variables\n#          and some bit field extraction variables.\n# Create helper variables ...\n#    BIT0.. BIT31\n\nfor { set x 0  } { $x < 32 } { set x [expr {$x + 1}]} {\n    set vn [format \"BIT%d\" $x]\n    global $vn\n    set $vn   [expr {1 << $x}]\n}\n\n# Create K bytes values\n#    __1K ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dK\" $x]\n    global $vn\n    set $vn   [expr {1024 * $x}]\n}\n\n# Create M bytes values\n#    __1M ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dM\" $x]\n    global $vn\n    set $vn [expr {1024 * 1024 * $x}]\n}\n\nproc create_mask { MSB LSB } {\n    return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}]\n}\n\n# Cut Bits $MSB to $LSB out of this value.\n# Example: % format \"0x%08x\" [extract_bitfield 0x12345678 27 16]\n# Result:  0x02340000\n\nproc extract_bitfield { VALUE MSB LSB } {\n    return [expr {[create_mask $MSB $LSB] & $VALUE}]\n}\n\n\n# Cut bits $MSB to $LSB out of this value\n# and shift (normalize) them down to bit 0.\n#\n# Example: % format \"0x%08x\" [normalize_bitfield 0x12345678 27 16]\n# Result:  0x00000234\n#\nproc normalize_bitfield { VALUE MSB LSB } {\n    return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}]\n}\n\nproc show_normalize_bitfield { VALUE MSB LSB } {\n    set m [create_mask $MSB $LSB]\n    set mr [expr {$VALUE & $m}]\n    set sr [expr {$mr >> $LSB}]\n    echo [format \"((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d \" $VALUE $m $mr $LSB $sr $sr]\n   return $sr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/8devices-lima.cfg",
    "content": "# Product page:\n# https://www.8devices.com/products/lima\n#\n# Location of JTAG pins:\n# J2 GPIO0\tJTAG TCK\n# J2 GPIO1\tJTAG TDI\n# J2 GPIO2\tJTAG TDO\n# J2 GPIO3\tJTAG TMS\n# J2 RST\tdirectly connected to RESET_L of the SoC and can be used as\n#               JTAG SRST. Note: this pin will also reset the debug engine.\n# J1 +3,3V\tCan be use as JTAG Vref\n# J1 or J2 GND\tCan be used for JTAG GND\n#\n# This board is powered from mini USB connecter which is also used\n# as USB to UART converted based on FTDI FT230XQ chip\n\nsource [find target/qualcomm_qca4531.cfg]\n\nproc board_init { } {\n\tqca4531_ddr2_550_550_init\n}\n\n$_TARGETNAME configure -event reset-init {\n\tboard_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/actux3.cfg",
    "content": "# board config file for AcTux3/XBA IXP42x board\n# Date:   2010-12-16\n# Author: Michael Schwingen <michael@schwingen.org>\n\nreset_config trst_and_srst separate\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nsource [find target/ixp42x.cfg]\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init { init_actux3 }\n\nproc init_actux3 { } {\n    ##########################################################################\n    # setup expansion bus CS\n    ##########################################################################\n    mww 0xc4000000  0xbd113842  ;#CS0  : Flash, write enabled @0x50000000\n    mww 0xc4000004  0x94d10013  ;#CS1\n    mww 0xc4000008  0x95960003  ;#CS2\n    mww 0xc400000c  0x00000000  ;#CS3\n    mww 0xc4000010  0x80900003  ;#CS4\n    mww 0xc4000014  0x9d520003  ;#CS5\n    mww 0xc4000018  0x81860001  ;#CS6\n    mww 0xc400001c  0x80900003  ;#CS7\n\n    ixp42x_init_sdram $::IXP42x_SDRAM_16MB_4Mx16_1BANK 2100 3\n\n    #mww 0xc4000020  0xffffee ;# CFG0: remove expansion bus boot flash mirror at 0x00000000\n\n    ixp42x_set_bigendian\n\n    flash probe 0\n}\n\nproc flash_boot { {FILE \"/tftpboot/actux3/u-boot.bin\"} } {\n    echo \"writing bootloader: $FILE\"\n    flash write_image erase $FILE 0x50000000 bin\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x400000 2 2 $_TARGETNAME\n\ninit\nreset init\n\n# setup to debug u-boot in flash\nproc uboot_debug {} {\n    gdb_breakpoint_override hard\n    xscale vector_catch 0xFF\n\n    xscale vector_table low  1 0xe59ff018\n    xscale vector_table low  2 0xe59ff018\n    xscale vector_table low  3 0xe59ff018\n    xscale vector_table low  4 0xe59ff018\n    xscale vector_table low  5 0xe59ff018\n    xscale vector_table low  6 0xe59ff018\n    xscale vector_table low  7 0xe59ff018\n\n    xscale vector_table high 1 0xe59ff018\n    xscale vector_table high 2 0xe59ff018\n    xscale vector_table high 3 0xe59ff018\n    xscale vector_table high 4 0xe59ff018\n    xscale vector_table high 5 0xe59ff018\n    xscale vector_table high 6 0xe59ff018\n    xscale vector_table high 7 0xe59ff018\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/adapteva_parallella1.cfg",
    "content": "#\n# Adapteva Parallella-I board (via Porcupine-1 adapter board)\n#\n\nreset_config srst_only\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/adsp-sc584-ezbrd.cfg",
    "content": "#\n# Analog Devices ADSP-SC584-EZBRD evaluation board\n#\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\n# Analog expects users to use their proprietary ICE-1000 / ICE-2000 with all\n# ADSP-SC58x designs, but this is an ARM target (and subject to the\n# qualifications above) many ARM debug pods should be compatible.\n\n#source [find interface/cmsis-dap.cfg]\nsource [find interface/jlink.cfg]\n\n# Analog's silicon supports SWD and JTAG, but their proprietary ICE is limited\n# to JTAG.  (This is presumably why their connector pinout was modified.)\n# SWD is chosen here, as it is more efficient and doesn't require /TRST.\n\ntransport select swd\n\n# chosen speed is 'safe' choice, but your adapter may be capable of more\nadapter speed 400\n\nsource [find target/adsp-sc58x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/alphascale_asm9260_ek.cfg",
    "content": "source [find target/alphascale_asm9260t.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configure clock\"\n\t# Enable SRAM clk\n\tmww 0x80040024 0x4\n\t# Enable IRQ clk\n\tmww 0x80040034 0x100\n\t# Enable DMA0,1 clk\n\tmww 0x80040024 0x600\n\t# Make sysre syspll is enabled\n\tmww 0x80040238 0x750\n\t#CPU = PLLCLK/2\n\tmww 0x8004017C 0x2\n\t#SYSAHBCLK = CPUCLK/2\n\tmww 0x80040180 0x2\n\t# Set PLL freq to 480MHz\n\tmww 0x80040100 480\n\t# normally we shoul waiting here until we get 0x1 (0x80040104)&0x1)==0x0)\n\tsleep 100\n\n\t# select PLL as main source\n\tmww 0x80040120 0x1\n\t# disable and enable main clk to update changes?\n\tmww 0x80040124 0x0\n\tmww 0x80040124 0x1\n\n\techo \"Configure memory\"\n\t#enable EMI CLK\n\tmww 0x80040024 0x40\n\n\t# configure memory controller for internal SRAM\n\tmww 0x80700000 0x1188\n\t# change default emi clk delay\n\tmww 0x8004034C 0xA0503\n\t# make sure chip_select_register2_low has correct value (why?)\n\tmww 0x8070001c 0x20000000\n\t# set type to sdram and size to 32MB\n\tmww 0x8070005c 0xa\n\t# configure internal SDRAM timing\n\tmww 0x80700004 0x024996d9\n\t# configure Static Memory timing\n\tmww 0x80700094 0x00542b4f\n\n\techo \"Configure uart4\"\n\t# enable pinctrl clk\n\tmww 0x80040024 0x2000000\n\t# mux GPIO3_0 and GPIO3_1 to UART4\n\tmww 0x80044060 0x2\n\tmww 0x80044064 0x2\n\t# configure UART4CLKDIV\n\tmww 0x800401a8 0x1\n\t# enable uart4 clk\n\tmww 0x80040024 0x8000\n\t# clear softrst and clkgate on uart4\n\tmww 0x80010008 0xC0000000\n\t# set bandrate 115200 12M\n\tmww 0x80010030 0x00062070\n\t# enable Rx&Tx\n\tmww 0x80010024 0x301\n\t# clear hw control\n\tmww 0x80010028 0xc000\n}\n\n$_TARGETNAME configure -work-area-phys 0x21ffe000 -work-area-virt 0xc1ffe000 -work-area-size 0x1000\n$_TARGETNAME arm7_9 fast_memory_access enable\n$_TARGETNAME arm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/altera_sockit.cfg",
    "content": "#\n# Cyclone V SocKit board\n# http://www.altera.com/b/arrow-sockit.html\n#\n# Software support page:\n# http://www.rocketboards.org/\n\n# openocd does not currently support the on-board USB Blaster II.\n# Install the JTAG header and use a USB Blaster instead.\nadapter driver usb_blaster\n\nsource [find target/altera_fpgasoc.cfg]\n\n# If the USB Blaster II were supported, these settings would be needed\n#usb_blaster vid_pid 0x09fb 0x6810\n#usb_blaster device_desc \"USB-Blaster II\"\n\nadapter speed 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/am3517evm.cfg",
    "content": "# DANGER!!!! early work in progress for this PCB/target.\n#\n# The most basic operations work well enough that it is\n# useful to have this in the repository for cooperation\n# alpha testing purposes.\n#\n# TI AM3517\n#\n# http://focus.ti.com/docs/prod/folders/print/am3517.html\n# http://processors.wiki.ti.com/index.php/Debug_Access_Port_(DAP)\n# http://processors.wiki.ti.com/index.php?title=How_to_Find_the_Silicon_Revision_of_your_OMAP35x\n\nset CHIPTYPE \"am35x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit am35x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ampere_emag8180.cfg",
    "content": "#\n# OpenOCD Board Configuration for eMAG Development Platform\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure JTAG speed\n#\n\nadapter speed 2000\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nsource [find target/ampere_emag.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/arm_evaluator7t.cfg",
    "content": "# This board is from ARM and has an samsung s3c45101x01 chip\n\nsource [find target/samsung_s3c4510.cfg]\n\n#\n# FIXME:\n#  Add (A) sdram configuration\n#  Add (B) flash cfi programming configuration\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/arm_musca_a.cfg",
    "content": "#\n# Configuration script for ARM Musca-A development board\n#\n# For now we do not support Musca A flash programming using OpenOCD. However, a\n# work area is configured for flash programming speed up.\n#\n# GDB considers all memory as RAM unless target supplies a memory map.\n# OpenOCD will only send memory map if flash banks are configured. Otherwise,\n# configure GDB after connection by issuing following commands:\n# (gdb) mem 0x10200000 0x109FFFFF ro\n# (gdb) mem 0x00200000 0x009FFFFF ro\n# (gdb) set mem inaccessible-by-default off\n\n# ARM Musca A board supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME MUSCA_A\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x6ba00477\n}\n\n# Enable CPU1 debugging as a separate GDB target\nset _ENABLE_CPU1 1\n\n# Musca A1 has 32KB SRAM banks. Override default work-area-size to 8KB per CPU\nset WORKAREASIZE_CPU0 0x2000\nset WORKAREASIZE_CPU1 0x2000\n\n# Set SRAM bank 1 to be used for work area. Override here if needed.\nset WORKAREAADDR_CPU0 0x30008000\nset WORKAREAADDR_CPU1 0x3000A000\n\nsource [find target/arm_corelink_sse200.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/arty_s7.cfg",
    "content": "#\n# Arty S7: Spartan7 25/50 FPGA Board for Makers and Hobbyists\n#\n# https://www.xilinx.com/products/boards-and-kits/1-pnziih.html\n# https://store.digilentinc.com/arty-s7-spartan-7-fpga-board-for-makers-and-hobbyists/\n\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# Xilinx Spartan7-25/50 FPGA (XC7S{25,50}-CSGA324)\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n\n# Usage:\n#\n# Load Bitstream into FPGA:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    pld load 0 bitstream.bit;\\\n#    shutdown\"\n#\n# Write Bitstream to Flash:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    jtagspi_init 0 bscan_spi_xc7s??.bit;\\\n#    jtagspi_program bitstream.bin 0;\\\n#    xc7_program xc7.tap;\\\n#    shutdown\"\n#\n# jtagspi flash proxies can be found at:\n# https://github.com/quartiq/bscan_spi_bitstreams\n#\n# For the Spartan 50 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s50.bit\n# For the Spartan 25 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s25.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/asus-rt-n16.cfg",
    "content": "#\n# http://wikidevi.com/wiki/ASUS_RT-N16\n#\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4718.cfg]\n\n# External 32MB NOR Flash (Macronix MX29GL256EHTI2I-90Q)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/asus-rt-n66u.cfg",
    "content": "#\n# http://wikidevi.com/wiki/Asus_RT-N66U\n#\n\necho \"ATTENTION: you need to solder a 4.7-10k pullup resistor to pin 21 of flash IC\"\necho \"to enable JTAG, see http://wl500g.info/album.php?albumid=28&attachmentid=8991 ,\"\necho \"there is an unpopulated footprint near U8.\\n\"\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4706.cfg]\n\n# External 32MB NOR Flash (Spansion S29GL256P10TF101\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91cap7a-stk-sdram.cfg",
    "content": "# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394\n#\n# use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME cap7\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x40700f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start {\n\t# start off real slow when we're running off internal RC oscillator\n\tadapter speed 32\n}\n\nproc peek32 {address} {\n\treturn [read_memory $address 32 1]\n}\n\n# Wait for an expression to be true with a timeout\nproc wait_state {expression} {\n\tfor {set i 0} {$i < 1000} {set i [expr {$i + 1}]} {\n\t\tif {[uplevel 1 $expression] == 0} {\n\t\t\treturn\n\t\t}\n\t}\n\treturn -code 1 \"Timed out\"\n}\n\n# Use a global variable here to be able to tinker interactively with\n# post reset jtag frequency.\nglobal post_reset_khz\n# Danger!!!! Even 16MHz kinda works with this target, but\n# it needs to be as low as 2000kHz to be stable.\nset post_reset_khz 2000\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configuring master clock\"\n\t# disable watchdog\n\tmww 0xfffffd44 0xff008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# Enable main oscillator\n\tmww 0xFFFFFc20  0x00000f01\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}}\n\n\t# Set PLLA to 96MHz\n\tmww 0xFFFFFc28 0x20072801\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}}\n\n\t# Select prescaler\n\tmww 0xFFFFFC30 0x00000004\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\t# Select master clock to 48MHz\n\tmww 0xFFFFFC30 0x00000006\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\techo \"Master clock ok.\"\n\n\t# Now that we're up and running, crank up speed!\n\tglobal post_reset_khz ;\tadapter speed $post_reset_khz\n\n\techo \"Configuring the SDRAM controller...\"\n\n\t# Configure EBI Chip select for SDRAM\n\tmww 0xFFFFEF30 0x00000102\n\n\t# Enable clock on EBI PIOs\n\tmww 0xFFFFFC10 0x00000004\n\n\t# Configure PIO for SDRAM\n\tmww 0xFFFFF470 0xFFFF0000\n\tmww 0xFFFFF474 0x00000000\n\tmww 0xFFFFF404 0xFFFF0000\n\n\t# Configure SDRAMC CR\n\tmww 0xFFFFEA08 0xA63392F9\n\n\t# NOP command\n\tmww 0xFFFFEA00 0x1\n\tmww 0x20000000 0\n\n\t# Precharge All Banks command\n\tmww 0xFFFFEA00 0x2\n\tmww 0x20000000 0\n\n\t# Set 1st CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000010 0x00000001\n\n\t# Set 2nd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000020 0x00000002\n\n\t# Set 3rd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000030 0x00000003\n\n\t# Set 4th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000040 0x00000004\n\n\t# Set 5th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000050 0x00000005\n\n\t# Set 6th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000060 0x00000006\n\n\t# Set 7th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000070 0x00000007\n\n\t# Set 8th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000080 0x00000008\n\n\t# Set LMR operation\n\tmww 0xFFFFEA00 0x00000003\n\n\t# Perform LMR burst=1, lat=2\n\tmww 0x20000020 0xCAFEDEDE\n\n\t# Set Refresh Timer\n\tmww 0xFFFFEA04 0x00000203\n\n\t# Set Normal mode\n\tmww 0xFFFFEA00 0x00000000\n\tmww 0x20000000 0x00000000\n\n\t#remap internal memory at address 0x0\n\tmww 0xffffef00 0x3\n\n\techo \"SDRAM configuration ok.\"\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91eb40a.cfg",
    "content": "#Script for AT91EB40a\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\n\n#Atmel ties SRST & TRST together, at which point it makes\n#no sense to use TRST, but use TMS instead.\n#\n#The annoying thing with tying SRST & TRST together is that\n#there is no way to halt the CPU *before and during* the\n#SRST reset, which means that the CPU will run a number\n#of cycles before it can be halted(as much as milliseconds).\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n#flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME\n\n# required for usable performance. Used for lots of\n# other things than flash programming.\n$_TARGETNAME configure -work-area-phys 0x00030000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Running reset init script for AT91EB40A\"\n\t# Reset script for AT91EB40a\n\treg cpsr 0x000000D3\n\tmww 0xFFE00020 0x1\n\tmww 0xFFE00024 0x00000000\n\tmww 0xFFE00000 0x01002539\n\tmww 0xFFFFF124 0xFFFFFFFF\n\tmww 0xffff0010 0x100\n\tmww 0xffff0034 0x100\n}\n\n# This target is pretty snappy...\nadapter speed 16000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91rm9200-dk.cfg",
    "content": "#\n# This is for the \"at91rm9200-DK\" (not the EK) eval board.\n#\n# The two are probably very simular.... I have DK...\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_dk_init }\n\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME\n\n\nproc at91rm9200_dk_init { } {\n    # Try to run at 1khz... Yea, that slow!\n    # Chip is really running @ 32khz\n    adapter speed 8\n\n    mww 0xfffffc64 0xffffffff\n    ##  disable all clocks but system clock\n    mww 0xfffffc04 0xfffffffe\n    ##  disable all clocks to pioa and piob\n    mww 0xfffffc14 0xffffffc3\n    ##  master clock = slow cpu = slow\n    ##  (means the CPU is running at 32khz!)\n    mww 0xfffffc30 0\n    ##  main osc enable\n    mww 0xfffffc20 0x0000ff01\n    ##  program pllA\n    mww 0xfffffc28 0x20263e04\n    ##  program pllB\n    mww 0xfffffc2c 0x10483e0e\n    ##  let pll settle... sleep 100msec\n    sleep 100\n    ##  switch to fast clock\n    mww 0xfffffc30 0x202\n    ## Sleep some - (go read)\n    sleep 100\n\n    #========================================\n    # CPU now runs at 180mhz\n    # SYS runs at 60mhz.\n    adapter speed 40000\n    #========================================\n\n\n    ##  set memc for all memories\n    mww 0xffffff60 0x02\n    ##  program smc controller\n    mww 0xffffff70 0x3284\n    ##  init sdram\n    mww 0xffffff98 0x7fffffd0\n    ##  all banks precharge\n    mww 0xffffff80 0x02\n    ##  touch sdram chip to make it work\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    mww 0xffffff90 0x04\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    ##  Refresh, etc....\n    mww 0xffffff90 0x03\n    mww 0x20000080 0\n    mww 0xffffff94 0x1f4\n    mww 0x20000080 0\n    mww 0xffffff90 0x10\n    mww 0x20000000 0\n    mww 0xffffff00 0x01\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91rm9200-ek.cfg",
    "content": "#\n# Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>\n#\n# under GPLv2 Only\n#\n# This is for the \"at91rm9200-ek\" eval board.\n#\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_ek_init }\n\n## flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# The chip may run @ 32khz, so set a really low JTAG speed\nadapter speed 8\n\nproc at91rm9200_ek_init { } {\n\t# Try to run at 1khz... Yea, that slow!\n\t# Chip is really running @ 32khz\n\tadapter speed 8\n\n\tmww 0xfffffc64 0xffffffff\n\t## disable all clocks but system clock\n\tmww 0xfffffc04 0xfffffffe\n\t## disable all clocks to pioa and piob\n\tmww 0xfffffc14 0xffffffc3\n\t## master clock = slow cpu = slow\n\t## (means the CPU is running at 32khz!)\n\tmww 0xfffffc30 0\n\t## main osc enable\n\tmww 0xfffffc20 0x0000ff01\n\t## MC_PUP\n\tmww 0xFFFFFF50 0x00000000\n\t## MC_PUER: Memory controller protection unit disable\n\tmww 0xFFFFFF54 0x00000000\n\t## EBI_CFGR\n\tmww 0xFFFFFF64 0x00000000\n\t## SMC2_CSR[0]: 16bit, 2 TDF, 4 WS\n\tmww 0xFFFFFF70 0x00003284\n\n\t## Init Clocks\n\t## CKGR_PLLAR\n\tmww 0xFFFFFC28 0x2000BF05\n\t## PLLAR: 179,712000 MHz for PCK\n\tmww 0xFFFFFC28 0x20263E04\n\tsleep 100\n\t## PMC_MCKR\n\tmww 0xFFFFFC30 0x00000100\n\tsleep 100\n\t## ;MCKR : PCK/3 = MCK Master Clock = 59,904000MHz from PLLA\n\tmww 0xFFFFFC30 0x00000202\n\tsleep 100\n\n\t#========================================\n\t# CPU now runs at 180mhz\n\t# SYS runs at 60mhz.\n\tadapter speed 40000\n\t#========================================\n\n\t## Init SDRAM\n\t## PIOC_ASR: Configure PIOC as peripheral (D16/D31)\n\tmww 0xFFFFF870 0xFFFF0000\n\t## PIOC_BSR:\n\tmww 0xFFFFF874 0x00000000\n\t## PIOC_PDR:\n\tmww 0xFFFFF804 0xFFFF0000\n\t## EBI_CSA : CS1=SDRAM\n\tmww 0xFFFFFF60 0x00000002\n\t## EBI_CFGR:\n\tmww 0xFFFFFF64 0x00000000\n\t## SDRC_CR :\n\tmww 0xFFFFFF98 0x2188c155\n\t## SDRC_MR : Precharge All\n\tmww 0xFFFFFF90 0x00000002\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Refresh\n\tmww 0xFFFFFF90 0x00000004\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Load Mode Register\n\tmww 0xFFFFFF90 0x00000003\n\t## access SDRAM\n\tmww 0x20000080 0x00000000\n\t## SDRC_TR : Write refresh rate\n\tmww 0xFFFFFF94 0x000002E0\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Normal Mode\n\tmww 0xFFFFFF90 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91sam9261-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9261-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9261.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9261.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9261ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9261ek_reset_init { } {\n\n\t;# for ppla at 199 Mhz\n\tset config(master_pll_div)\t15\n\tset config(master_pll_mul)\t162\n\n\t;# for ppla at 239 Mhz\n\t;# set master_pll_div\t1\n\t;# set master_pll_mul\t13\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBICSA\n\tset config(matrix_ebicsa_val) [expr {$::AT91_MATRIX_DBPUC | $::AT91_MATRIX_CS1A_SDRAMC}]\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (2 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (3 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (8 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91sam9263-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9263-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9263.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9263.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9263ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9263ek_reset_init { } {\n\n\tset config(master_pll_div)\t14\n\tset config(master_pll_mul)\t171\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\tset config(sdram_piod) 1\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBI0CSA\n\n\tset val\t$::AT91_MATRIX_EBI0_DBPUC\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_VDDIOMSEL_3_3V}]\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_CS1A_SDRAMC}]\n\tset config(matrix_ebicsa_val) $val\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (1 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (2 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (1 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/at91sam9g20-ek.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n# Author: Gary Carlson (gcarlson@carlson-minot.com)\t\t\t\t\t\t#\n# Generated for Atmel AT91SAM9G20-EK evaluation board using Atmel SAM-ICE (J-Link) version 8.\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g20.cfg]\n\nset _FLASHTYPE nandflash_cs3\n\n# Set reset type.  Note that the AT91SAM9G20-EK board has the trst signal disconnected.  Therefore\n# the reset needs to be configured for \"srst_only\".  If for some reason, a zero-ohm jumper is\n# added to the board to connect the trst signal, then this parameter may need to be changed.\n\nreset_config srst_only\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init}\n$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start}\n\n# NandFlash configuration and definition\n\nnand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xfffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g20_reset_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n\tadapter speed 2                 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\thalt                            ;# Make sure processor is halted, or error will result in following steps.\n\twait_halt 10000\n\tmww 0xfffffd08 0xa5000501       ;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9g20_reset_init { } {\n\n\t# At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G20 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\tmww 0xfffffd44 0x00008000\t;# WDT_MR : disable watchdog.\n\n\t# Enable the main 18.432 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\tmww 0xfffffc28 0x202a3f01\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00000101\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 0\n\n\t# Enable faster DCC downloads and memory accesses.\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\tmww 0xffffef1c 0x000100a\n\n\t# The AT91SAM9G20-EK evaluation board has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# a number of registers.  The first step involves setting up the general I/O pins on the processor\n\t# to be able to interface and support the external memory.\n\n\tmww 0xfffffc10 0x00000010\t;# PMC_PCER : enable PIOC clock\n\tmww 0xfffff800 0x00006000\t;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n\tmww 0xfffff810 0x00004000\t;# PIOC_OER : enable output on 14\n\tmww 0xfffff814 0x00002000\t;# PIOC_ODR : disable output on 13\n    \tmww 0xfffff830 0x00004000\t;# PIOC_SODR : set 14 to disable NAND\n\n\t# The exact physical timing characteristics for the memory type used on the current board\n\t# (MT29F2G08AACWP) can be established by setting four registers in order:  SMC_SETUP3,\n\t# SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.  Computing the exact values of these registers\n\t# is a little tedious to do here.  If you have questions about how to do this, Atmel has\n\t# a decent application note #6255B that covers this process.\n\n\tmww 0xffffec30 0x00020002\t;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE\n\tmww 0xffffec34 0x04040404\t;# SMC_PULSE3 : 4 clock cycle pulse for all signals\n\tmww 0xffffec38 0x00070006\t;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle\n\tmww 0xffffec3C 0x00020003\t;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n\n\tmww 0xffffe800 0x00000001\t;# ECC_CR : reset the ECC parity registers\n\tmww 0xffffe804 0x00000002\t;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n\t# Identify NandFlash bank 0.\n\n\tnand probe nandflash_cs3\n\n\t# The AT91SAM9G20-EK evaluation board has built-in serial data flash also.\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Micron MT48LC16M16A2-75 memory (4 M x 16 bit x 4 banks).  If you use this file as a reference\n\t# for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted\n\t# into the SDRAM_CR register.  Using the memory datasheet for the -75 grade part and assuming a master clock\n\t# of 132.096 MHz then the SDCLK period is equal to 7.6 ns.  This means the device requires:\n\t#\n\t#\tCAS latency = 3 cycles\n\t#\tTXSR = 10 cycles\n\t#\tTRAS = 6 cycles\n\t#\tTRCD = 3 cycles\n\t#\tTRP = 3 cycles\n\t#\tTRC = 9 cycles\n\t#\tTWR = 2 cycles\n\t#\t9 column, 13 row, 4 banks\n\t#\trefresh equal to or less then 7.8 us for commercial/industrial rated devices\n\t#\n\t#\tThus SDRAM_CR = 0xa6339279\n\n\tmww 0xffffea08 0xa6339279\n\n\t# Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000001\n\tmww 0x20000000 0\n\n\t# Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero\n\t# value into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000002\n\tmww 0x20000000 0\n\n\t# Now issue an 'Auto-Refresh' command through the SDRAMC_MR register.  Follow this operation by writing\n\t# zero values eight times into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x3\n\tmww 0x20000000 0\n\n\t# Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting\n\t# memory location for the SDRAM.\n\n\tmww 0xffffea00 0x0\n\tmww 0x20000000 0\n\n\t# Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles).\n\n\tmww 0xffffea04 0x0000039c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_at91sam7s-ek.cfg",
    "content": "# Atmel AT91SAM7S-EK\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3784\n\nset CHIPNAME at91sam7s256\n\nsource [find target/at91sam7sx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_at91sam9260-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9260-EK eval board\n#\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9260.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198.656 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (99.328 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n\n        mww 0xffffef1c 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_at91sam9rl-ek.cfg",
    "content": "################################################################################\n#\n# Generated for Atmel AT91SAM9RL-EK evaluation board using Atmel SAM-ICE (J-Link) V6\n#\n# Atmel AT91SAM9RL : PLL = 200 MHz, MCK = 100 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9rl.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2031bf03         ;# CKGR_PLLR: Set PLL Register for 200 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLL is selected (100 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff670 0xffff0000         ;# PIO_ASR  : Select peripheral function for D16..D31 (PIOB)\n        mww 0xfffff604 0xffff0000         ;# PIO_PDR  : Disable PIO function for D16..D31 (PIOB)\n\n        mww 0xffffef20 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam3n_ek.cfg",
    "content": "\n#\n# Board configuration for Atmel's SAM3N-EK\n#\n\nreset_config srst_only\n\nset CHIPNAME at91sam3n4c\n\nadapter speed 32\n\nsource [find target/at91sam3nXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam3s_ek.cfg",
    "content": "source [find target/at91sam3sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam3u_ek.cfg",
    "content": "source [find target/at91sam3u4e.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam3x_ek.cfg",
    "content": "source [find target/at91sam3ax_8x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam4e_ek.cfg",
    "content": "# This is an SAM4E-EK board with a single SAM4E16 chip.\n# http://www.atmel.com/tools/sam4e-ek.aspx\n\n# chip name\nset CHIPNAME SAM4E16E\n\nsource [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam4l8_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4L8 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4L8-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4LC8CA\n\nsource [find target/at91sam4lXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam4s_ek.cfg",
    "content": "source [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_sam4s_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4S Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4S-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4SD32C\n\nsource [find target/at91sam4sd32x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samc20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC20 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samc21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC21 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMC21-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samd10_xplained_mini.cfg",
    "content": "#\n# Atmel SAMD10 Xplained mini evaluation kit.\n# http://www.atmel.com/tools/atsamd10-xmini.aspx\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd10d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samd11_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD11 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd11d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samd20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD20 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMD20-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samd21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_same70_xplained.cfg",
    "content": "#\n# Atmel SAME70 Xplained evaluation kit.\n# http://www.atmel.com/tools/ATSAME70-XPLD.aspx\n#\n# Connect using the EDBG chip on the dev kit over USB\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME atsame70q21\n\nsource [find target/atsamv.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samg53_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG53 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG53-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG53N19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samg55_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG55 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG55-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG55J19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_saml21_xplained_pro.cfg",
    "content": "#\n# Atmel SAML21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91saml21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samr21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMR21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samr21g18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/atmel_samv71_xplained_ultra.cfg",
    "content": "#\n# Atmel SAMV71 Xplained Ultra evaluation kit.\n# http://www.atmel.com/tools/ATSAMV71-XULT.aspx\n#\n# To connect using the EDBG chip on the dev kit over USB, you will\n# first need to source [find interface/cmsis-dap.cfg]\n# however, since this board also has a SWD+ETM connector, we don't\n# automatically source that file here.\n\nset CHIPNAME samv71\n\nsource [find target/atsamv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/avnet_ultrazed-eg.cfg",
    "content": "#\n# AVNET UltraZED EG StarterKit\n# ZynqMP UlraScale-EG plus IO Carrier with on-board digilent smt2\n#\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n# jtag transport only\ntransport select jtag\n# reset lines are not wired\nreset_config none\n\n# slow default clock\nadapter speed 1000\n\nset CHIPNAME uscale\n\nsource [find target/xilinx_zynqmp.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/balloon3-cpu.cfg",
    "content": "# Config for balloon3 board, cpu JTAG port. http://balloonboard.org/\n# The board has separate JTAG ports for cpu and CPLD/FPGA devices\n# Chaining is done on IO interfaces if desired.\n\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\n# 29LV650 64Mbit Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/bcm28155_ap.cfg",
    "content": "# BCM28155_AP\n\nadapter speed 20000\n\nset CHIPNAME bcm28155\nsource [find target/bcm281xx.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/bluefield.cfg",
    "content": "#\n# Board configuration for BlueField SoC.\n#\n\nsource [find interface/rshim.cfg]\nsource [find target/bluefield.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/bt-homehubv1.cfg",
    "content": "#\n# BT HomeHub v1\n#\n\nset partition_list {\n    CFE       { Bootloader              0xbe400000 0x00020000 }\n    firmware  { \"Kernel+rootfs\"         0xbe420000 0x007d0000 }\n    fisdir    { \"FIS Directory\"         0xbebf0000 0x0000f000 }\n    nvram     { \"Config space\"          0xbebff000 0x00001000 }\n}\n\nsource [find target/bcm6348.cfg]\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/colibri.cfg",
    "content": "# Toradex Colibri PXA270\nsource [find target/pxa270.cfg]\nreset_config trst_and_srst srst_push_pull\nadapter srst pulse_width 40\n\n# CS0 -- one bank of CFI flash, 32 MBytes\n# the bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/crossbow_tech_imote2.cfg",
    "content": "# Crossbow Technology iMote2\n\nset  CHIPNAME imote2\nsource [find target/pxa270.cfg]\n\n# longer-than-normal reset delay\nadapter srst delay 800\n\nreset_config trst_and_srst separate\n\n# works for P30 flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/csb337.cfg",
    "content": "# Cogent CSB337\n#   http://cogcomp.com/csb_csb337.htm\n\nsource [find target/at91rm9200.cfg]\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# ETM9 trace port connector present on this board, 16 data pins.\nif { [info exists ETM_DRIVER] } {\n\tetm config $_TARGETNAME 16 normal half $ETM_DRIVER\n\t# OpenOCD may someday support a real trace port driver...\n\t# system config file would need to configure it.\n} else {\n\tetm config $_TARGETNAME 16 normal half dummy\n\tetm_dummy config $_TARGETNAME\n}\n\nproc csb337_clk_init { } {\n\t# CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock\n\tadapter speed 8\n\n\t# CKGR_MOR:  start main oscillator (3.6864 MHz)\n\tmww 0xfffffc20 0xff01\n\tsleep 10\n\n\t# CKGR_PLLAR:  start PLL A for CPU and peripherals (184.32 MHz)\n\tmww 0xfffffc28 0x20313e01\n\t# CKGR_PLLBR:  start PLL B for USB timing (96 MHz, with div2)\n\tmww 0xfffffc2c 0x12703e18\n\t# let PLLs lock\n\tsleep 10\n\n\t# PMC_MCKR:  switch to CPU clock = PLLA, master clock = CPU/4\n\tmww 0xfffffc30 0x0302\n\tsleep 20\n\n\t# CPU is in Normal Mode ... allows faster JTAG clock speed\n\tadapter speed 40000\n}\n\nproc csb337_nor_init { } {\n\t# SMC_CSR0:  adjust timings (10 wait states)\n\tmww 0xffffff70 0x1100318a\n\n\tflash probe 0\n}\n\nproc csb337_sdram_init { } {\n\t# enable PIOC clock\n\tmww 0xfffffc10 0x0010\n\t# PC31..PC16 are D31..D16, with internal pullups like D15..D0\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff874 0x0\n\tmww 0xfffff804 0xffff0000\n\n\t# SDRC_CR: set timings\n\tmww 0xffffff98 0x2188b0d5\n\n\t# SDRC_MR: issue all banks precharge to SDRAM\n\tmww 0xffffff90 2\n\tmww 0x20000000 0\n\n\t# SDRC_MR: 8 autorefresh cycles\n\tmww 0xffffff90 4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# SDRC_MR: set SDRAM mode registers (CAS, burst len, etc)\n\tmww 0xffffff90 3\n\tmww 0x20000080 0\n\n\t# SDRC_TR: set refresh rate\n\tmww 0xffffff94 0x200\n\tmww 0x20000000 0\n\n\t# SDRC_MR: normal mode, 32 bit bus\n\tmww 0xffffff90 0\n\tmww 0x20000000 0\n}\n\n# The rm9200 chip has just been reset.  Bring it up far enough\n# that we can write flash or run code from SDRAM.\nproc csb337_reset_init { } {\n\tcsb337_clk_init\n\n\t# EBI_CSA:  CS0 = NOR, CS1 = SDRAM\n\tmww 0xffffff60 0x02\n\n\tcsb337_nor_init\n\tcsb337_sdram_init\n\n\t# Update CP15 control register ... we don't seem to be able to\n\t# read/modify/write its value through a TCL variable, so just\n\t# write it.  Fields are zero unless listed here ... and note\n\t# that OpenOCD numbers this register \"2\", not \"1\" (!).\n\t#\n\t#  - Core to use Async Clocking mode (so it uses 184 MHz most\n\t#    of the time instead of limiting to the master clock rate):\n\t#\tiA(31) = 1, nF(30) = 1\n\t#  - Icache on (it's disabled now, slowing i-fetches)\n\t#\tI(12) = 1\n\t#  - Reserved/ones\n\t#\t6:3 = 1\n\tarm920t cp15 2 0xc0001078\n}\n\n$_TARGETNAME configure -event reset-init {csb337_reset_init}\n\narm7_9 fast_memory_access enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/csb732.cfg",
    "content": "# The Cogent CSB732 board has a single i.MX35 chip\nsource [find target/imx35.cfg]\n\n# Determined by trial and error\nreset_config trst_and_srst combined\nadapter srst delay 200\njtag_ntrst_delay 200\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { csb732_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc csb732_init { } {\n\n\t# Disable fast writing only for init\n\tmemwrite burst disable\n\n\t# All delay loops are omitted.\n\t# We assume the interpreter latency is enough.\n\n\t# Allow access to all coprocessors\n\tarm mcr 15 0 15 1 0 0x2001\n\n\t# Disable MMU, caches, write buffer\n\tarm mcr 15 0 1 0 0 0x78\n\n\t# Grant manager access to all domains\n\tarm mcr 15 0 3 0 0 0xFFFFFFFF\n\n\t# Set ARM clock to 532 MHz, AHB to 133 MHz\n\tmww 0x53F80004 0x1000\n\n\t# Set core clock to 2 * 24 MHz * (11 + 1/12) = 532 MHz\n\tmww 0x53F8001C 0xB2C01\n\n\tset ESDMISC 0xB8001010\n\tset ESDCFG0 0xB8001004\n\tset ESDCTL0 0xB8001000\n\n\t# Enable DDR\n\tmww $ESDMISC 0x4\n\n\t# Timing\n\tmww $ESDCFG0 0x007fff3f\n\n\t# CS0\n\tmww $ESDCTL0 0x92120080\n\n\t# Precharge all dummy write\n\tmww 0x80000400 0\n\n\t# Enable CS) auto-refresh\n\tmww $ESDCTL0 0xA2120080\n\n\t# Refresh twice (dummy writes)\n\tmww 0x80000000 0\n\tmww 0x80000000 0\n\n\t# Enable CS0 load mode register\n\tmww $ESDCTL0 0xB2120080\n\n\t# Dummy writes\n\tmwb 0x80000033 0x01\n\tmwb 0x81000000 0x01\n\n\tmww $ESDCTL0 0x82226080\n\tmww 0x80000000 0\n\n\t# Re-enable fast writing\n\tmemwrite burst enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/da850evm.cfg",
    "content": "#DA850 EVM board\n# http://focus.ti.com/dsp/docs/thirdparty/catalog/devtoolsproductfolder.tsp?actionPerformed=productFolder&productId=5939\n# http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit\n\nsource [find target/omapl138.cfg]\n\nreset_config trst_and_srst separate\n\n#currently any pinmux/timing must be setup by UBL before openocd can do debug\n#TODO: implement pinmux/timing on reset like in board/dm365evm.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/digi_connectcore_wi-9c.cfg",
    "content": "######################################\n# Target: DIGI ConnectCore Wi-9C\n######################################\n\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ns9360\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set  _ENDIAN big\n}\n\n\n# What's a good fallback frequency for this board if RCLK is\n# not available??\njtag_rclk 1000\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 200\njtag_ntrst_delay 0\n\n\n######################\n# Target configuration\n######################\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x90600104 0x33313333\n\tmww 0xA0700000 0x00000001  ;# Enable the memory controller.\n\tmww 0xA0700024 0x00000006  ;# Set the refresh counter 6\n\tmww 0xA0700028 0x00000001  ;#\n\tmww 0xA0700030 0x00000001  ;# Set the precharge period\n\tmww 0xA0700034 0x00000004  ;# Active to precharge command period is 16 clock cycles\n\tmww 0xA070003C 0x00000001  ;# tAPR\n\tmww 0xA0700040 0x00000005  ;# tDAL\n\tmww 0xA0700044 0x00000001  ;# tWR\n\tmww 0xA0700048 0x00000006  ;# tRC 32 clock cycles\n\tmww 0xA070004C 0x00000006  ;# tRFC 32 clock cycles\n\tmww 0xA0700054 0x00000001  ;# tRRD\n\tmww 0xA0700058 0x00000001  ;# tMRD\n\tmww 0xA0700100 0x00004280  ;# Dynamic Config 0 (cs4)\n\tmww 0xA0700120 0x00004280  ;# Dynamic Config 1 (cs5)\n\tmww 0xA0700140 0x00004280  ;# Dynamic Config 2 (cs6)\n\tmww 0xA0700160 0x00004280  ;# Dynamic Config 3 (cs7)\n\t#\n\tmww 0xA0700104 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700124 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700144 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700164 0x00000203  ;# CAS latency is 2 at 100 MHz\n\t#\n\tmww 0xA0700020 0x00000103  ;# issue SDRAM PALL command\n\t#\n\tmww 0xA0700024 0x00000001  ;# Set the refresh counter to be as small as possible\n\t#\n\t# Add some dummy writes to give the SDRAM time to settle, it needs two\n\t# AHB clock cycles, here we poke in the debugger flag, this lets\n\t# the software know that we are in the debugger\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\t#\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\t#\n\tmww 0xA0700024 0x00000030 ;# Set the refresh counter to 30\n\tmww 0xA0700020 0x00000083 ;# Issue SDRAM MODE command\n\t#\n\t# Next we perform a read of RAM.\n\t# mw = move word.\n\tmdw 0x00022000\n\t# mw 0x00022000:P, r3  # 22000 for cas2 latency, 32000 for cas 3\n\t#\n\tmww 0xA0700020 0x00000003   ;# issue SDRAM NORMAL command\n\tmww 0xA0700100 0x00084280   ;# Enable buffer access\n\tmww 0xA0700120 0x00084280   ;# Enable buffer access\n\tmww 0xA0700140 0x00084280   ;# Enable buffer access\n\tmww 0xA0700160 0x00084280   ;# Enable buffer access\n\n\t#Set byte lane state (static mem 1)\"\n\tmww 0xA0700220 0x00000082\n\t#Flash Start\n\tmww 0xA09001F8 0x50000000\n\t#Flash Mask Reg\n\tmww 0xA09001FC 0xFF000001\n\tmww 0xA0700028 0x00000001\n\n\t#  RAMAddr = 0x00020000\n\t#  RAMSize = 0x00004000\n\n\t# Set the processor mode\n\treg cpsr 0xd3\n}\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x1000 -work-area-backup 1\n\n#####################\n# Flash configuration\n#####################\n\n#M29DW323DB - not working\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x0400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/digilent_analog_discovery.cfg",
    "content": "#\n# Digilent Analog Discovery\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY\n#\n# Config is based on data from\n# https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71\n#\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x8008 0x800b\n\nadapter speed 25000\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/digilent_atlys.cfg",
    "content": "# http://digilentinc.com/atlys/\n#\n# The Digilent Atlys normally requires proprietary tools to program and will\n# enumerate as:\n#   ID 1443:0007 Digilent Development board JTAG\n#\n# However, the ixo-usb-jtag project provides an alternative open firmware for\n# the on board programmer. When using this firmware the board will then\n# enumerate as:\n#   ID 16c0:06ad Van Ooijen Technische Informatica\n# (With SerialNumber == hw_nexys)\n#\n# See the interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/digilent_nexys_video.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Digilent Nexys Video with Xilinx Artix-7 FPGA\n# https://reference.digilentinc.com/programmable-logic/nexys-video/start\n\nadapter driver ftdi\nadapter speed 30000\n\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6010\n\n# channel 0 is dedicated for Digilent's DPTI Interface\n# channel 1 is used for JTAG\nftdi channel 1\n\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n\n# Enable sampling on falling edge for high JTAG speeds.\nftdi tdo_sample_edge falling\n\ntransport select jtag\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/digilent_zedboard.cfg",
    "content": "#\n# Digilent Zedboard Rev.C, Rev.D with Xilinx Zynq chip\n#\n# http://zedboard.com/product/zedboard\n#\n\nsource [find interface/ftdi/digilent_jtag_smt2.cfg]\n\nreset_config srst_only srst_push_pull\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/diolan_lpc4350-db1.cfg",
    "content": "#\n# Diolan LPC-4350-DB1 development board\n#\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/diolan_lpc4357-db1.cfg",
    "content": "#\n# Diolan LPC-4357-DB1 development board\n#\n\nset CHIPNAME lpc4357\n\nsource [find target/lpc4357.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dk-tm4c129.cfg",
    "content": "echo \"WARNING: board/dk-tm4c129.cfg is deprecated, please switch to board/ti_dk-tm4c129.cfg\"\n\nsource [find board/ti_dk-tm4c129.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dm355evm.cfg",
    "content": "# DM355 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html\n#   http://c6000.spectrumdigital.com/evmdm355/\n\nsource [find target/ti_dm355.cfg]\n\nreset_config trst_and_srst separate\n\n# NOTE:  disable or replace this call to dm355evm_init if you're\n# debugging new UBL code from SRAM.\n$_TARGETNAME configure -event reset-init { dm355evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm355evm_init {} {\n\tglobal dm355\n\n\techo \"Initialize DM355 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tjtag_rclk 1500\n\n\t########################\n\t# PLL1\t\t= 432 MHz (/8, x144)\n\t# ...SYSCLK1\t= 216 MHz (/2)  ... ARM, MJCP\n\t# ...SYSCLK2\t= 108 MHz (/4)  ... Peripherals\n\t# ...SYSCLK3\t= 27  MHz (/16) ... VPBE, DAC\n\t# ...SYSCLK4\t= 108 MHz (/4)  ... VPSS\n\t#\tpll1.{prediv,div1,div2} are fixed\n\t#\tpll1.postdiv set in MISC (for *this* speed grade)\n\n\tset addr [dict get $dm355 pllc1]\n\tset pll_divs [dict create]\n\tdict set pll_divs div3 16\n\tdict set pll_divs div4 4\n\tpll_v02_setup $addr 144 $pll_divs\n\n\t# ARM is now running at 216 MHz, so JTAG can go faster\n\tjtag_rclk 20000\n\n\t########################\n\t# PLL2\t\t= 342 MHz (/8, x114)\n\t# ....SYSCLK1\t= 342 MHz (/1)  ... DDR PHY at 171 MHz, 2x clock\n\t#\tpll2.{postdiv,div1} are fixed\n\n\tset addr [dict get $dm355 pllc2]\n\tset pll_divs [dict create]\n\tdict set pll_divs div1 1\n\tdict set pll_divs prediv 8\n\tpll_v02_setup $addr 114 $pll_divs\n\n\t########################\n\t# PINMUX\n\n\t# All Video Inputs\n\tdavinci_pinmux $dm355 0 0x00007f55\n\t# All Video Outputs\n\tdavinci_pinmux $dm355 1 0x00145555\n\t# EMIFA (NOTE: more could be set up for use as GPIOs)\n\tdavinci_pinmux $dm355 2 0x00000c08\n\t# SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs\n\tdavinci_pinmux $dm355 3 0x1bff55ff\n\t# MMC/SD0 instead of MS; SPI0\n\tdavinci_pinmux $dm355 4 0x00000000\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t########################\n\t# DDR2 EMIF\n\n\t# VTPIOCR impedance calibration\n\tset addr [dict get $dm355 sysbase]\n\tset addr [expr {$addr + 0x70}]\n\n\t# clear CLR, LOCK, PWRDN; wait a clock; set CLR\n\tmmw $addr 0 0x20c0\n\tmmw $addr 0x2000 0\n\n\t# wait for READY\n        while { [expr {[mrw $addr] & 0x8000}] == 0 } { sleep 1 }\n\n\t# set IO_READY; then LOCK and PWRSAVE; then PWRDN\n\tmmw $addr 0x4000 0\n\tmmw $addr 0x0180 0\n\tmmw $addr 0x0040 0\n\n\t# NOTE:  this DDR2 initialization sequence borrows from\n\t# both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec.\n\n\t# reset (then re-enable) DDR controller\n\tpsc_reset 13\n\tpsc_go\n\tpsc_enable 13\n\tpsc_go\n\n\t# now set it up for Micron MT47H64M16HR-37E @ 171 MHz\n\n\tset addr [dict get $dm355 ddr_emif]\n\n\t# DDRPHYCR1\n\tmww [expr {$addr + 0xe4}] 0x50006404\n\n\t# PBBPR -- burst priority\n\tmww [expr {$addr + 0x20}] 0xfe\n\n\t# SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0x00800000 0\n\tmmw [expr {$addr + 0x08}] 0x0013c632 0x03870fff\n\n\t# SDTIMR0, SDTIMR1\n\tmww [expr {$addr + 0x10}] 0x2a923249\n\tmww [expr {$addr + 0x14}] 0x4c17c763\n\n\t# SDCR -- relock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0 0x00008000\n\n\t# SDRCR -- refresh rate (171 MHz * 7.8usec)\n\tmww [expr {$addr + 0x0c}] 1336\n\n\t########################\n\t# ASYNC EMIF\n\n\tset addr [dict get $dm355 a_emif]\n\n\t# slow/pessimistic timings\n\tset nand_timings 0x40400204\n\t# fast (25% faster page reads)\n\t#set nand_timings 0x0400008c\n\n\t# AWCCR\n\tmww [expr {$addr + 0x04}] 0xff\n\t# CS0 == socketed NAND (default MT29F16G08FAA, 2GByte)\n\tmww [expr {$addr + 0x10}] $nand_timings\n\t# CS1 == dm9000 Ethernet\n\tmww [expr {$addr + 0x14}] 0x00a00505\n\t# NANDFCR -- only CS0 has NAND\n\tmww [expr {$addr + 0x60}] 0x01\n\n\t# default: both chipselects to the NAND socket are used\n\tnand probe 0\n\tnand probe 1\n\n\t########################\n\t# UART0\n\n\tset addr [dict get $dm355 uart0]\n\n\t# PWREMU_MGNT -- rx + tx in reset\n\tmww [expr {$addr + 0x30}] 0\n\n\t# DLL, DLH -- 115200 baud\n\tmwb [expr {$addr + 0x20}] 0x0d\n\tmwb [expr {$addr + 0x24}] 0x00\n\n\t# FCR - clear and disable FIFOs\n\tmwb [expr {$addr + 0x08}] 0x07\n\tmwb [expr {$addr + 0x08}] 0x00\n\n\t# IER - disable IRQs\n\tmwb [expr {$addr + 0x04}] 0x00\n\n\t# LCR - 8-N-1\n\tmwb [expr {$addr + 0x0c}] 0x03\n\n\t# MCR - no flow control or loopback\n\tmwb [expr {$addr + 0x10}] 0x00\n\n\t# PWREMU_MGNT -- rx + tx normal, free running during JTAG halt\n\tmww [expr {$addr + 0x30}] 0xe001\n\n\n\t########################\n\n\t# turn on icache - set I bit in cp15 register c1\n\tarm mcr 15 0 0 1 0 0x00051078\n}\n\n# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one.\n#\n# NOTE:  \"hwecc4\" here presumes that if you're using the standard 2GB NAND\n# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to\n# use \"hwecc4_infix\" for the UBL; or else (b) aren't updating anything that\n# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc.\nset _FLASHNAME $_CHIPNAME.boot\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000\n\n# FIXME\n#  - support writing UBL with its header (new layout only with new ROMs)\n#  - support writing ABL/U-Boot with its header (new layout)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dm365evm.cfg",
    "content": "# DM365 EVM board -- Beta\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html\n#   http://support.spectrumdigital.com/boards/evmdm365\n\nsource [find target/ti_dm365.cfg]\n\n# NOTE:  in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG\n# connector, so it doesn't affect generation of the reset signal.\n# Accordingly, resets require something else.  ICEpick could do it;\n# but its docs aren't generally available.\n#\n# At this writing, newer boards aren't available ... so assume no SRST.\n# Also ICEpick docs aren't available ... so we must use watchdog reset,\n# and hope the CPU isn't wedged or in a WFI loop (either of which can\n# block access to CPU and thus watchdog registers).\n\nreset_config trst_only\n$_TARGETNAME configure -event reset-assert \"davinci_wdog_reset\"\n\n# SW5.1 routes CS0: NAND vs OneNAND.\n# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand)\n# for boot-from-flash, those must agree with SW4.3:1 settings.\n\nif { [info exists CS0MODE] } {\n\t# NAND or OneNAND\n\tset CS0 $CS0MODE\n} else {\n\tset CS0 \"\"\n\techo \"WARNING:  CS0 configuration not known\"\n\tproc cs0_setup {a_emif} {}\n\tproc flashprobe {} {}\n}\n\nset a_emif [dict get $dm365 a_emif]\n\n# As shipped:  boot from NAND.\nif { $CS0 == \"NAND\" } {\n\techo \"CS0 NAND\"\n\n\t# NAND socket has two chipselects.  Default MT29F16G08FAA chip\n\t# has 1GByte on each one.\n\t# NOTE:  \"hwecc4\" here presumes that you're not updating anything\n\t# that needs infix layout (e.g. UBL, old U-Boot, etc)\n\tnand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif\n\tnand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 8 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000016\n\n\t\t# slow/pessimistic timings\n\t\tset nand_timings 0x40400204\n\t\t# fast (25% faster page reads)\n\t\t#set nand_timings 0x0400008c\n\n\t\t# CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes)\n\t\tmww [expr {$a_emif + 0x10}] $nand_timings\n\n\t\t# NANDFCR -- CS0 has NAND\n\t\tmww [expr {$a_emif + 0x60}] 0x01\n\t}\n\tproc flashprobe {} {\n\t\tnand probe 0\n\t\tnand probe 1\n\t}\n\n} elseif { $CS0 == \"OneNAND\" } {\n\techo \"CS0 OneNAND\"\n\n\t# No support for this OneNAND in OpenOCD (yet) or Linux ...\n\t# REVISIT OneNAND timings not verified to work!\n\techo \"WARNING -- OneNAND not yet tested!\"\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 16 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000055\n\n\t\t# CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes)\n\t\tmww [expr {$a_emif + 0x10}] 0x00000001\n\n\t\t# ONENANDCTRL -- CS0 has OneNAND, enable sync reads\n\t\tmww [expr {$a_emif + 0x5c}] 0x0441\n\t}\n\tproc flashprobe {} { }\n}\n\n# NOTE:  disable or replace this call to dm365evm_init if you're\n# debugging new UBL/NANDboot code from SRAM.\n$_TARGETNAME configure -event reset-init { dm365evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm365evm_init {} {\n\tglobal dm365\n\n\techo \"Initialize DM365 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tadapter speed 1500\n\n\t# FIXME -- PLL init\n\n\t########################\n\t# PINMUX setup\n\n\tdavinci_pinmux $dm365 0 0x00fd0000\n\tdavinci_pinmux $dm365 1 0x00145555\n\t# mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand\n\tdavinci_pinmux $dm365 3 0x375affff\n\tdavinci_pinmux $dm365 4 0x55556555\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t# FIXME setup DDR2 (needs PLL)\n\n\t########################\n\t# ASYNC EMIF\n\n\tset a_emif [dict get $dm365 a_emif]\n\n\t# AWCCR\n\tmww [expr {$a_emif + 0x04}] 0xff\n\t# CS0 == NAND or OneNAND\n\tcs0_setup $a_emif\n\t# CS1 == CPLD\n\tmww [expr {$a_emif + 0x14}] 0x00a00505\n\n\t# FIXME setup UART0\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dm6446evm.cfg",
    "content": "# DM6446 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm6446.html\n#   http://c6000.spectrumdigital.com/davincievm/\n# EVM is just the board; buy that at Spectrum.\n# The \"kit\" from TI also has: video camera, LCD video monitor, more.\n\nsource [find target/ti_dm6446.cfg]\n\n# J4 controls what CS2 hooks up to, usually NOR or NAND flash.\n# S3.1/S3.2 controls boot mode, which may force J4 and S3.3 settings.\n# S3.3 controls AEMIF bus width.\n\nif { [info exists J4_OPTION] } {\n\t# NOR, NAND, SRAM, ...\n\tset CS2_MODE $J4_OPTION\n} else {\n\tset CS2_MODE \"\"\n}\n\n# ARM boot:\n#  S3.1 = 0, S3.2 = 0\t==> ROM/UBL boot via NAND (J4 == NAND)\n#  S3.1 = 1, S3.2 = 0\t==> AEMIF boot (J4 == NOR or SRAM)\n#  S3.1 = 0, S3.2 = 1\t==> ROM/UBL boot via HPI\n#  S3.1 = 1, S3.2 = 1\t==> ROM/UBL boot via UART (J4 == don't care)\n# AEMIF bus width:\n#  S3.3 = 0\t\t==> 8 bit bus width\n#  S3.3 = 1\t\t==> 16 bit bus width\n# DSP boot:\n#  S3.4 = 0\t\t==> controlled by ARM\n\nif { $CS2_MODE == \"NOR\" } {\n\t# 16 Mbytes address space; 16 bit bus width\n\t# (older boards used 32MB parts, with upper 16 MB unusable)\n\tset _FLASHNAME $_CHIPNAME.flash\n\tflash bank $_FLASHNAME cfi 0x02000000 0x01000000 2 2 $_TARGETNAME\n\tproc flashprobe {} { flash probe 0 }\n} elseif { $CS2_MODE == \"NAND\" } {\n\t# 64 Mbyte small page; 8 bit bus width\n\tnand device davinci $_TARGETNAME 0x02000000 hwecc1 0x01e00000\n\tproc flashprobe {} { nand probe 0 }\n} elseif { $CS2_MODE == \"SRAM\" } {\n\t# 4 Mbyte address space; 16 bit bus width\n\t# loaded via JTAG or HPI\n\tproc flashprobe {} {}\n} else {\n\t# maybe it's HPI boot?  can't tell...\n\techo \"WARNING:  CS2/flash configuration not recognized\"\n\tproc flashprobe {} {}\n}\n\n# NOTE:  disable or replace this call to dm6446evm_init if you're\n# debugging new UBL code from SRAM (for NAND boot).\n$_TARGETNAME configure -event reset-init { dm6446evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm6446evm_init {} {\n\n\techo \"Initialize DM6446 EVM board\"\n\n\t# FIXME initialize everything:\n\t#  - PLL1\n\t#  - PLL2\n\t#  - PINMUX\n\t#  - PSC\n\t#  - DDR\n\t#  - AEMIF\n\t#  - UART0\n\t#  - icache\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dp_busblaster_v3.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v3.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c32a tap -expected-id 0x06e1c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dp_busblaster_v4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://raw.githubusercontent.com/dergraaf/busblaster_v4/master/ktlink/ktlink.svf\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v4.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c64a tap -expected-id 0x06e5c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/dptechnics_dpt-board-v1.cfg",
    "content": "# Product page:\n# https://www.dptechnics.com/en/products/dpt-board-v1.html\n#\n# JTAG is a 5 pin array located close to main module in following order:\n# 1. JTAG TCK\n# 2. JTAG TDO\n# 3. JTAG TDI\n# 4. JTAG TMS\n# 5. GND\tThe GND is located near letter G of word JTAG on board.\n#\n# Two RST pins are connected to:\n# 1. GND\n# 2. GPIO11\tthis pin is located near letter R of word RST.\n#\n# To enable EJTAG mode, GPIO11 (RST[1]) pin should be pulled up. For example\n# with 10K resistor connected to V3.3 pin.\n#\n# This board is powered from micro USB connector. No real reset pin or button, for\n# example RESET_L is available.\n\nsource [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr2_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/efikamx.cfg",
    "content": "# Genesi USA EfikaMX\n#  http://www.genesi-usa.com/products/efika\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 6000 }\n\nsource [find target/imx51.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/efm32.cfg",
    "content": "# Configuration for EFM32 boards with on-board SEGGER J-Link\n#\n# Tested with Tiny, Giant and Zero Gecko Starter Kit.\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nset CHIPNAME efm32\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/eir.cfg",
    "content": "# Elector Internet Radio board\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nsource [find target/at91sam7se512.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# WDT_MR, disable watchdog\n\tmww 0xFFFFFD44 0x00008000\n\n\t# RSTC_MR, enable user reset\n\tmww 0xfffffd08 0xa5000001\n\n\t# CKGR_MOR\n\tmww 0xFFFFFC20 0x00000601\n\tsleep 10\n\n\t# CKGR_PLLR\n\tmww 0xFFFFFC2C 0x00481c0e\n\tsleep 10\n\n\t# PMC_MCKR\n\tmww 0xFFFFFC30 0x00000007\n\tsleep 10\n\n\t# PMC_IER\n\tmww 0xFFFFFF60 0x00480100\n\n\t#\n\t# Enable SDRAM interface.\n\t#\n\n\t# Enable SDRAM control at PIO A.\n\tmww 0xfffff474 0x3f800000 ;# PIO_BSR_OFF\n\tmww 0xfffff404 0x3f800000 ;# PIO_PDR_OFF\n\n\t# Enable address bus (A0, A2-A11, A13-A17) at PIO B\n\tmww 0xfffff674 0x0003effd ;# PIO_BSR_OFF\n\tmww 0xfffff604 0x0003effd ;# PIO_PDR_OFF\n\n\t# Enable 16 bit data bus at PIO C\n\tmww 0xfffff870 0x0000ffff ;# PIO_ASR_OFF\n\tmww 0xfffff804 0x0000ffff ;# PIO_PDR_OFF\n\n\t# Enable SDRAM chip select\n\tmww 0xffffff80 0x00000002 ;# EBI_CSA_OFF\n\n\t# Set SDRAM characteristics in configuration register.\n\t# Hard coded values for MT48LC32M16A2 with 48MHz CPU.\n\tmww 0xffffffb8 0x2192215a ;# SDRAMC_CR_OFF\n\tsleep 10\n\n\t# Issue 16 bit SDRAM command: NOP\n\tmww 0xffffffb0 0x00000011 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Precharge all\n\tmww 0xffffffb0 0x00000012 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 8 auto-refresh cycles\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Set mode register\n\tmww 0xffffffb0 0x00000013 ;# SDRAMC_MR_OFF\n\tmww 0x20000014 0xcafedede\n\n\t# Set refresh rate count ???\n\tmww 0xffffffb4 0x00000013 ;# SDRAMC_TR_OFF\n\n\t# Issue 16 bit SDRAM command: Normal mode\n\tmww 0xffffffb0 0x00000010 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000180\n\n\t#\n\t# Enable external reset key.\n\t#\n\tmww 0xfffffd08 0xa5000001\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s1968.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S1968 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s1968\n#\n\n# NOTE:  to use J-Link instead of the on-board interface,\n# you may also need to reduce adapter speed to be about 1200.\n# source [find interface/jlink.cfg]\n\n# include the FT2232 interface config for on-board JTAG interface\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s1968\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s3748.cfg",
    "content": "#\n# TI/Luminary Stellaris lm3s3748 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s3748\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s3748\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s6965.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S6965 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s6965\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x5000\nset CHIPNAME lm3s6965\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s811-revb.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits (rev B and earlier)\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE: newer 811-EK boards (rev C and above) shouldn't use this.\n# use board/ek-lm3s811.cfg\nsource [find interface/ftdi/luminary-lm3s811.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s811.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\n# NOTE:  older '811-EK boards (before rev C) shouldn't use this.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s8962.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S8962 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s8962\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s8962\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s9b9x.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9B9x Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9b90\n# http://www.ti.com/tool/ek-lm3s9b92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s9b9x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm3s9d92.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9D92 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9d92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s9d92\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm4f120xl.cfg",
    "content": "#\n# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f120xl\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f120h5qr\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-lm4f232.cfg",
    "content": "#\n# TI Stellaris LM4F232 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f232\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f23x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-tm4c123gxl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c123gxl.cfg is deprecated, please switch to board/ti_ek-tm4c123gxl.cfg\"\n\nsource [find board/ti_ek-tm4c123gxl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ek-tm4c1294xl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c1294xl.cfg is deprecated, please switch to board/ti_ek-tm4c1294xl.cfg\"\n\nsource [find board/ti_ek-tm4c1294xl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/embedded-artists_lpc2478-32.cfg",
    "content": "# Embedded Artists eval board for LPC2478\n# http://www.embeddedartists.com/\n\n# Target device: LPC2478\nset CCLK 72000\nsource [find target/lpc2478.cfg]\n\n# Helper\n#\nproc read_register {register} {\n    return [read_memory $register 32 1]\n}\n\nproc init_board {} {\n    # Delays on reset lines\n    adapter srst delay 500\n    jtag_ntrst_delay 1\n\n    # Adaptive JTAG clocking through RTCK.\n    #\n    jtag_rclk 20\n\n    global _TARGETNAME\n    global _CHIPNAME\n\n    # A working area will help speeding the flash programming\n    $_TARGETNAME configure -work-area-phys 0x40000200 -work-area-size [expr {0x10000-0x200-0x20}] -work-area-backup 0\n\n    # External 16-bit flash at chip select CS0 (SST39VF3201-70, 4 MiB)\n    flash bank $_CHIPNAME.extflash cfi 0x80000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n    # Event handlers\n    #\n    $_TARGETNAME configure -event reset-start {\n        # Back to the slow JTAG clock\n        jtag_rclk 20\n    }\n\n    $_TARGETNAME configure -event reset-init {\n        arm core_state arm\n        arm7_9 dcc_downloads enable     ;# Speed up downloads by using DCC transfer\n        arm7_9 fast_memory_access enable\n\n        # Peripheral clocks\n        mww 0xE01FC0C4 0x04280FFE       ;# PCONP: (reset value)\n\n        # Map the user flash to the vector table area (0x00...0x3F)\n        mww 0xE01FC040 0x00000001       ;# MEMMAP: User flash\n\n        # Memory accelerator module\n        mww 0xE01FC004 0x00000003       ;# MAMTIM: 3 clock cycles\n        mww 0xE01FC000 0x00000002       ;# MAMCR: fully enabled\n\n        # Enable external memory bus (32-bit SDRAM at DYCS0, 16-bit flash at CS0)\n        mww 0xE002C014 0x55010115       ;# PINSEL5: P2.16=CAS, P2.17=RAS, P2.18=CLKOUT0,\n                                         # P2.20=DYCS0, P2.24=CKEOUT0, P2.28=DQMOUT0,\n                                         # P2.29=DQMOUT1, P2.30=DQMOUT2, P2.31=DQMOUT3\n        mww 0xE002C018 0x55555555       ;# PINSEL6: P3.0...P3.15=D0...D15\n        mww 0xE002C01C 0x55555555       ;# PINSEL7: P3.16...P3.31=D16...D31\n        mww 0xE002C020 0x55555555       ;# PINSEL8: P4.0...P4.15=A0...A15\n        mww 0xE002C024 0x50051555       ;# PINSEL9: P4.16...P4.22=A16...A22, P4.24=OE,\n                                         # P4.25=WE, P4.30=CS0, P4.31=CS1\n        mww 0xFFE08000 0x00000001       ;# EMCControl: Enable EMC\n\n        # Start PLL, then use faster JTAG clock\n        enable_pll\n        jtag_rclk 3000\n\n        # 16-bit flash @ CS0 (SST39VF3201-70)\n        mww 0xFFE08200 0x00080081       ;# EMCStaticConfig0: 16 bit, PB=1, buffers on\n        mww 0xFFE08204 0x00000000       ;# EMCStaticWaitWen0\n        mww 0xFFE08208 0x00000000       ;# EMCStaticWaitOen0\n        mww 0xFFE0820C 0x00000005       ;# EMCStaticWaitRd0\n        mww 0xFFE08210 0x00000005       ;# EMCStaticWaitPage0\n        mww 0xFFE08214 0x00000003       ;# EMCStaticWaitWr0\n        mww 0xFFE08218 0x00000001       ;# EMCStaticWaitTurn0\n\n        # 8-bit NAND @ CS1\n        # TODO\n\n        # 32-bit SDRAM @ DYCS0 (K4M563233G-HN75)\n        mww 0xFFE08028 0x00000001       ;# EMCDynamicReadConfig\n        mww 0xFFE08030 0x00000001       ;# EMCDynamicRP\n        mww 0xFFE08034 0x00000003       ;# EMCDynamicRAS\n        mww 0xFFE08038 0x00000005       ;# EMCDynamicSREX\n        mww 0xFFE0803C 0x00000001       ;# EMCDynamicAPR\n        mww 0xFFE08040 0x00000005       ;# EMCDynamicDAL\n        mww 0xFFE08044 0x00000001       ;# EMCDynamicWR\n        mww 0xFFE08048 0x00000005       ;# EMCDynamicRC\n        mww 0xFFE0804C 0x00000005       ;# EMCDynamicRFC\n        mww 0xFFE08050 0x00000005       ;# EMCDynamicXSR\n        mww 0xFFE08054 0x00000001       ;# EMCDynamicRRD\n        mww 0xFFE08058 0x00000001       ;# EMCDynamicMRD\n        #\n        mww 0xFFE08104 0x00000202       ;# EMCDynamicRasCas0\n        mww 0xFFE08100 0x00005488       ;# EMCDynamicConfig0\n        sleep 100\n        mww 0xFFE08020 0x00000183       ;# EMCDynamicControl: Clock on continuously, NOP\n        sleep 10\n        mww 0xFFE08020 0x00000103       ;# EMCDynamicControl: PRECHARGE-ALL\n        mww 0xFFE08024 0x00000046       ;# EMCDynamicRefresh\n        sleep 100\n        mww 0xFFE08020 0x00000083       ;# EMCDynamicControl: MODE\n        mdw 0xA0011000 1                ;# Set SDRAM mode register\n        mww 0xFFE08020 0x00000000       ;# EMCDynamicControl: NORMAL\n        mww 0xFFE08100 0x00085488       ;# EMCDynamicConfig0: Enable buffers\n    }\n\n    $_TARGETNAME configure -event gdb-attach {\n        # Without this gdb-attach will first time as probe will fail\n        reset init\n    }\n}\n\n# Enable the PLL.\n# Generate maximum CPU clock (72 MHz) Run from internal RC oscillator.\n# Note: The PLL output runs at a frequency N times the desired CPU clock.\n#       It in unavoidable that the CPU clock drops down to (4 MHz/N) during\n#       the initialization!\n#       Here: N=4\n#       Note that if the PLL is already active at the time this script is\n#       called, the effective value of N is the value of CCLKCFG at that time!\n#\nproc enable_pll {} {\n    # Disconnect PLL in case it is already connected\n    if {[expr {[read_register 0xE01FC080] & 0x03}] == 3} {\n        # Disconnect it, but leave it enabled\n        # (This MUST be done in two steps)\n        mww 0xE01FC080 0x00000001       ;# PLLCON: disconnect PLL\n        mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n        mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    }\n    # Disable PLL (as it might already be enabled at this time!)\n    mww 0xE01FC080 0x00000000       ;# PLLCON: disable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n\n    # Setup PLL to generate 288 MHz from internal RC oscillator\n    mww 0xE01FC10C 0x00000000       ;# CLKSRCSEL: IRC\n    mww 0xE01FC084 0x00000023       ;# PLLCFG: N=1, M=36\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    mww 0xE01FC080 0x00000001       ;# PLLCON: enable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    sleep 100\n    mww 0xE01FC104 0x00000003       ;# CCLKCFG: divide by 4 (72 MHz)\n    mww 0xE01FC080 0x00000003       ;# PLLCON: connect PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/emcraft_imx8m-som-bsb.cfg",
    "content": "#\n# configuration file for Emcraft IMX8M-SOM-BSB\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# SRST and TRST are wired up\nreset_config trst_and_srst\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/emcraft_twr-vf6-som-bsb.cfg",
    "content": "#\n# EmCraft Systems TWR-VF6-SOM-BSB\n#\n# http://www.emcraft.com/products/259#twr-kit\n#\n\nsource [find board/emcraft_vf6-som.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/emcraft_vf6-som.cfg",
    "content": "#\n# EmCraft Systems Vybrid VF6 SOM\n#\n# http://www.emcraft.com/products/259#som\n#\n\nset CHIPNAME vf610\nsource [find target/vybrid_vf6xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/esp32s2-kaluga-1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S2 Kaluga board.\n#\n# For example, OpenOCD can be started for ESP32-S2 debugging on\n#\n#   openocd -f board/esp32s2-kaluga-1.cfg\n#\n\nsource [find interface/ftdi/esp32s2_kaluga_v1.cfg]\nsource [find target/esp32s2.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n# On ESP32-S2, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ethernut3.cfg",
    "content": "#\n# Ethernut 3 board configuration file\n#\n# http://www.ethernut.de/en/hardware/enut3/\n\n\n# AT91R40008-66AU ARM7TDMI Microcontroller\n# 256kB internal RAM\nsource [find target/at91r40008.cfg]\n\n\n# AT49BV322A-70TU NOR Flash\n# 2M x 16 mode at address 0x10000000\n# Common flash interface supported\n#\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME\n\n\n# Micrel MIC2775-29YM5 Supervisor\n# Reset output will remain active for 280ms (maximum)\n#\nadapter srst delay 300\njtag_ntrst_delay 300\n\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\nadapter speed 16000\n\n\n# Target events\n#\n$_TARGETNAME configure -event reset-init { board_init }\n\n# Initialize board hardware\n#\nproc board_init { } {\n\tboard_remap\n\tflash probe 0\n}\n\n# Memory remap\n#\nproc board_remap {{VERBOSE 0}} {\n\t# CS0: NOR flash\n\t#      16MB @ 0x10000000\n\t#      16-bit data bus\n\t#      4 wait states\n\t#\n\tmww 0xffe00000 0x1000212d\n\n\t# CS1: Ethernet controller\n\t#      1MB @ 0x20000000\n\t#      16-bit data bus\n\t#      2 wait states\n\t#      Byte select access\n\t#\n\tmww 0xffe00004 0x20003025\n\n\t# CS2: CPLD registers\n\t#      1MB @ 0x21000000\n\t#      8-bit data bus\n\t#      2 wait states\n\t#\n\tmww 0xffe00008 0x21002026\n\n\t# CS3: Expansion bus\n\t#      1MB @ 0x22000000\n\t#      8-bit data bus\n\t#      8 wait states\n\t#\n\tmww 0xffe00010 0x22002e3e\n\n\t# Remap command\n\t#\n\tmww 0xffe00020 0x00000001\n\n\tif {$VERBOSE != 0} {\n\t\techo \"0x00000000 RAM\"\n\t\techo \"0x10000000 Flash\"\n\t\techo \"0x20000000 Ethernet\"\n\t\techo \"0x21000000 CPLD\"\n\t\techo \"0x22000000 Expansion\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/evb-lan9255.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip LAN9255 evaluation board\n# https://www.microchip.com/en-us/development-tool/EV25Y25A\n#\n\nset CHIPNAME same53\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/frdm-kl25z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL25Z128VLK4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL25Z128VLK4\n\nreset_config srst_only\n\nsource [find target/kl25.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/frdm-kl46z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL46Z256VLL4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL46Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL46Z256VLL4\n\nreset_config srst_only\n\nsource [find target/kl46.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/fsl_imx6q_sabresd.cfg",
    "content": "#\n# Board configuration file for the Freescale IMX6Q Sabre SD EVM\n#\n# This board does not have an embedded JTAG adapter, you must source\n# a suitable adapter configuration before sourcing this file.\n\n# Sabre SD has a standard ARM-20 JTAG connector with\n# nTRST and nSRST available.\nreset_config trst_and_srst\n\n# the only possible transport is JTAG\ntransport select jtag\n\n# iMX6Q POR gates JTAG and the chip is completely incommunicado\n# over JTAG for at least 10ms after nSRST is deasserted\nadapter srst delay 11\n\n# Source generic iMX6Q target configuration\nset CHIPNAME imx6q\nsource [find target/imx6.cfg]\n\n# function to apply initial configuration after a reset. It\n# provides a basic pad configuration and also DDR memory and clocks\n# sufficient to load and execute a boot loader (e.g. barebox) from\n# DDR memory. This list is extracted from the barebox flash image\n# header.\nproc apply_dcd { } {\n\tmww 0x020e05a8 0x00000030\n\tmww 0x020e05b0 0x00000030\n\tmww 0x020e0524 0x00000030\n\tmww 0x020e051c 0x00000030\n\tmww 0x020e0518 0x00000030\n\tmww 0x020e050c 0x00000030\n\tmww 0x020e05b8 0x00000030\n\tmww 0x020e05c0 0x00000030\n\tmww 0x020e05ac 0x00020030\n\tmww 0x020e05b4 0x00020030\n\tmww 0x020e0528 0x00020030\n\tmww 0x020e0520 0x00020030\n\tmww 0x020e0514 0x00020030\n\tmww 0x020e0510 0x00020030\n\tmww 0x020e05bc 0x00020030\n\tmww 0x020e05c4 0x00020030\n\tmww 0x020e056c 0x00020030\n\tmww 0x020e0578 0x00020030\n\tmww 0x020e0588 0x00020030\n\tmww 0x020e0594 0x00020030\n\tmww 0x020e057c 0x00020030\n\tmww 0x020e0590 0x00003000\n\tmww 0x020e0598 0x00003000\n\tmww 0x020e058c 0x00000000\n\tmww 0x020e059c 0x00003030\n\tmww 0x020e05a0 0x00003030\n\tmww 0x020e0784 0x00000030\n\tmww 0x020e0788 0x00000030\n\tmww 0x020e0794 0x00000030\n\tmww 0x020e079c 0x00000030\n\tmww 0x020e07a0 0x00000030\n\tmww 0x020e07a4 0x00000030\n\tmww 0x020e07a8 0x00000030\n\tmww 0x020e0748 0x00000030\n\tmww 0x020e074c 0x00000030\n\tmww 0x020e0750 0x00020000\n\tmww 0x020e0758 0x00000000\n\tmww 0x020e0774 0x00020000\n\tmww 0x020e078c 0x00000030\n\tmww 0x020e0798 0x000c0000\n\tmww 0x021b081c 0x33333333\n\tmww 0x021b0820 0x33333333\n\tmww 0x021b0824 0x33333333\n\tmww 0x021b0828 0x33333333\n\tmww 0x021b481c 0x33333333\n\tmww 0x021b4820 0x33333333\n\tmww 0x021b4824 0x33333333\n\tmww 0x021b4828 0x33333333\n\tmww 0x021b0018 0x00081740\n\tmww 0x021b001c 0x00008000\n\tmww 0x021b000c 0x555a7975\n\tmww 0x021b0010 0xff538e64\n\tmww 0x021b0014 0x01ff00db\n\tmww 0x021b002c 0x000026d2\n\tmww 0x021b0030 0x005b0e21\n\tmww 0x021b0008 0x09444040\n\tmww 0x021b0004 0x00025576\n\tmww 0x021b0040 0x00000027\n\tmww 0x021b0000 0x831a0000\n\tmww 0x021b001c 0x04088032\n\tmww 0x021b001c 0x0408803a\n\tmww 0x021b001c 0x00008033\n\tmww 0x021b001c 0x0000803b\n\tmww 0x021b001c 0x00428031\n\tmww 0x021b001c 0x00428039\n\tmww 0x021b001c 0x09408030\n\tmww 0x021b001c 0x09408038\n\tmww 0x021b001c 0x04008040\n\tmww 0x021b001c 0x04008048\n\tmww 0x021b0800 0xa1380003\n\tmww 0x021b4800 0xa1380003\n\tmww 0x021b0020 0x00005800\n\tmww 0x021b0818 0x00022227\n\tmww 0x021b4818 0x00022227\n\tmww 0x021b083c 0x434b0350\n\tmww 0x021b0840 0x034c0359\n\tmww 0x021b483c 0x434b0350\n\tmww 0x021b4840 0x03650348\n\tmww 0x021b0848 0x4436383b\n\tmww 0x021b4848 0x39393341\n\tmww 0x021b0850 0x35373933\n\tmww 0x021b4850 0x48254A36\n\tmww 0x021b080c 0x001f001f\n\tmww 0x021b0810 0x001f001f\n\tmww 0x021b480c 0x00440044\n\tmww 0x021b4810 0x00440044\n\tmww 0x021b08b8 0x00000800\n\tmww 0x021b48b8 0x00000800\n\tmww 0x021b001c 0x00000000\n\tmww 0x021b0404 0x00011006\n\tmww 0x020c4068 0x00c03f3f\n\tmww 0x020c406c 0x0030fc03\n\tmww 0x020c4070 0x0fffc000\n\tmww 0x020c4074 0x3ff00000\n\tmww 0x020c4078 0x00fff300\n\tmww 0x020c407c 0x0f0000c3\n\tmww 0x020c4080 0x000003ff\n\tmww 0x020e0010 0xf00000cf\n\tmww 0x020e0018 0x007f007f\n\tmww 0x020e001c 0x007f007f\n}\n\n# disable watchdog\nproc disable_wdog { } {\n\tmwh 0x020bc000 0x30\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc imx6q_sabresd_init { } {\n\tdisable_wdog\n\tapply_dcd\n}\n\n# prevent cortex-a code from asserting SRST again\n$_TARGETNAME.0 configure -event reset-assert { }\n# hook the init function into the reset-init event\n$_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/glyn_tonga2.cfg",
    "content": "#\n# Glyn Tonga2 SO-DIMM CPU module (Toshiba TMPA900CMXBG, ARM9)\n#\n# http://toshiba-mikrocontroller.de/sites/TMPA900CPUBOARDStarter.htm\n#\n# Hardware on the S0-DIMM module:\n#   - Toshiba TMPA900CMXBG (ARM9, ARM926EJ-S, max. 200MHz)\n#   - DDR SDRAM: Hynix H5MS5162DFR-J3M (64Mbyte, x16, 1.8V, 166/83MHz at CL3/2)\n#   - NAND flash: Samsung K9F2G08U0B-PIB0 (256M x 8 Bit, 3.3V)\n#   - Ethernet: SMSC LAN9221I-ABZJ (10/100Mbit, Non-PCI, 16 bit interface)\n#\n\nsource [find target/tmpa900.cfg]\n\n########################\n# Target configuration #\n########################\n\n# Initial JTAG speed should not exceed 1/6 of the initial CPU clock\n# frequency (24MHz). Be conservative and use 1/8 of the frequency.\n# (24MHz / 8 = 3MHz)\nadapter speed 3000\n\n$_TARGETNAME configure -event reset-start {\n\t# Upon reset, set the JTAG frequency to 3MHz again, see above.\n\techo \"Setting JTAG speed to 3MHz until clocks are initialized.\"\n\tadapter speed 3000\n\n\t# Halt the CPU.\n\thalt\n\n\t# Disable faster memory access for now.\n\tarm7_9 fast_memory_access disable\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# Setup clocks, and initialize SRAM and DDR SDRAM.\n\ttonga2_init\n\n\t# At this point the CPU is running at 192MHz, increase JTAG speed.\n\t# Tests showed that 15MHz works OK, higher speeds can cause problems,\n\t# though. Not sure if this is a CPU issue or JTAG adapter issue.\n\techo \"Increasing JTAG speed to 15MHz.\"\n\tadapter speed 15000\n\n\t# Enable faster memory access.\n\tarm7_9 fast_memory_access enable\n}\n\nproc tonga2_init { } {\n\t######################\n\t# PLL initialization #\n\t######################\n\n\t# Clock overview (see datasheet chapter 3.5.2, page 57):\n\t#   - fs: Low-frequency oscillator\n\t#   - fOSCH: High-frequency oscillator (24MHz on this board)\n\t#   - fPLL = fOSCH * multiplier (where multiplier can be 6 or 8)\n\t#   - fFCLK = fPLL / gear (where gear can be 1/2/4/8)\n\t#   - fHCLK is always fFCLK/2. fPCLK is also fFCLK/2.\n\t#\n\t# We select multiplier = 8 and gear = 1, so\n\t#   fFCLK = fOSCH * 8 / 1 = 192MHz.\n\n\t# SYSCR3 (System Control Register 3): Disable and configure PLL.\n\t#   - PLL operation control: off\n\t#   - PLL constant value setting 1: always 0, as per datasheet\n\t#   - PLL constant value setting 2: x8 (multiplier = 8)\n\tmww 0xf005000c 0x00000007\n\n\t# SYSCR4 (System Control Register 4): Configure PLL.\n\t#   - PLL constant value setting 3: 140MHz or more\n\t#   - PLL constant value setting 4: always 1, as per datasheet\n\t#   - PLL constant value setting 5: 140MHz or more\n\tmww 0xf0050010 0x00000065\n\n\t# SYSCR3 (System Control Register 3): Enable PLL.\n\t#   - PLL operation control: on\n\t#   - All other bits remain set as above.\n\tmww 0xf005000c 0x00000087\n\n\t# Wait for PLL to stabilize.\n\tsleep 10\n\n\t# SYSCR2 (System Control Register 2): Switch from fOSCH to fPLL.\n\t#   - Selection of the PLL output clock: fPLL\n\tmww 0xf0050008 0x00000002\n\n\t# SYSCR1 (System Control Register 1):\n\t#   - Clock gear programming: fc/1 (i.e., gear = 1, don't divide).\n\tmww 0xf0050004 0x00000000\n\n\t# CLKCR5 (Clock Control Register 5): Set bits 3 and 6. The datasheet\n\t# says the bits are reserved, but also recommends \"Write as one\".\n\tmww 0xf0050054 0x00000048\n\n\n\t##############################################################\n\t# Dynamic Memory Controller (DMC) / DDR SDRAM initialization #\n\t##############################################################\n\n\t# PMC (Power Management Controller):\n\t# PMCDRV (External Port \"Driverbility\" control register):\n\t# Bits DRV_MEM0/DRV_MEM1 (memory relation port drive power):\n\tmww 0xf0020260 0x00000003\t;# Select 1.8V +/- 0.1V\n\n\t# Setup DDR SDRAM timing parameters for our specific chip.\n\tmww 0xf4310014 0x00000004\t;# cas_latency = 2\n\tmww 0xf4310018 0x00000001\t;# t_dqss = 1\n\tmww 0xf431001c 0x00000002\t;# t_mrd = 2\n\tmww 0xf4310020 0x0000000a\t;# t_ras = 10\n\tmww 0xf4310024 0x0000000a\t;# t_rc = 10\n\tmww 0xf4310028 0x00000013\t;# t_rcd = 3, schedule_rcd = 2\n\tmww 0xf431002c 0x0000010a\t;# t_rfc = 10, schedule_rfc = 8\n\tmww 0xf4310030 0x00000013\t;# t_rp = 3, schedule_rp = 2\n\tmww 0xf4310034 0x00000002\t;# t_rrd = 2\n\tmww 0xf4310038 0x00000002\t;# t_wr = 2\n\tmww 0xf431003c 0x00000001\t;# t_wtr = 1\n\tmww 0xf4310040 0x0000000a\t;# t_xp = 10\n\tmww 0xf4310044 0x0000000c\t;# t_xsr = 12\n\tmww 0xf4310048 0x00000014\t;# t_esr = 20\n\n\t# dmc_memory_cfg_5 (DMC Memory Configuration register):\n\t# Set memory configuration:\n\t# column_bits = 10, row_bits = 13, ap-bit = 10, power_down_prd = 0,\n\t# auto_power_down = disable, stop_mem_clock = disable, memory_burst = 4\n\tmww 0xf431000c 0x00010012\n\n\t# dmc_user_config_5 (DMC user_config register):\n\t# Data bus width of DDR SDRAM: 16 bit\n\tmww 0xf4310304 0x00000058\n\n\t# dmc_refresh_prd_5 (DMC Refresh Period register):\n\t# Auto refresh: every 2656 (0xa60) DMCSCLK periods.\n\tmww 0xf4310010 0x00000a60\n\n\t# dmc_chip_0_cfg_5 (DMC chip_0_cfg registers):\n\t#   - SDRAM address structure: bank, row, column\n\t#   - address_match = 01000000 (start address [31:24])\n\t#   - address_mask  = 11111100 (start address [31:24] mask value)\n\tmww 0xf4310200 0x000140fc\n\n\t# Initialize the DDR SDRAM chip.\n\t# dmc_direct_cmd_5 (DMC Direct Command register).\n\t# See datasheet chapter 3.10.5.1, page 268.\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x00000000\t;# RAM init: Precharge all\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00080032\t;# RAM init: addr_13_to_0 = 0x32\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x000a0000\t;# RAM init: bank_addr = bank 2\n\n\t# dmc_id_<0-5>_cfg_5 (DMC id_<0-5>_cfg registers):\n\t# Set min./max. QoS values.\n\t#   - 0x5: Enable QoS, max. QoS = 1\n\t#   - 0xb: Enable QoS, min. QoS = 2\n\tmww 0xf4310100 0x00000005\t;# AHB0: CPU Data\n\tmww 0xf4310104 0x00000005\t;# AHB1: CPU Inst\n\tmww 0xf4310108 0x0000000b\t;# AHB2: LCDC\n\tmww 0xf431010c 0x00000005\t;# AHB3: LCDDA, USB\n\tmww 0xf4310110 0x00000005\t;# AHB4: DMA1\n\tmww 0xf4310114 0x00000005\t;# AHB5: DMA2\n\n\t# dmc_memc_cmd_5 (DMC Memory Controller Command register):\n\t# Change DMC state to ready.\n\tmww 0xf4310004 0x00000000\t;# memc_cmd = \"Go\"\n\n\t# EBI: SMC Timeout register\n\tmww 0xf00a0050 0x00000001\t;# smc_timeout = 1\n\n\n\t########################################################\n\t# Static Memory Controller (SMC) / SRAM initialization #\n\t########################################################\n\n\t# smc_set_cycles_5 (SMC Set Cycles register):\n\t# tRC = 10, tWC = 10, tCEOE = 7, tWP = 5, tPC=2, tTR=2\n\tmww 0xf4311014 0x0004afaa\n\n\t# smc_set_opmode_5 (SMC Set Opmode register):\n\t# Memory data bus width = 16 bits, async read mode, read burst\n\t# length = 1 beat, async write mode, write burst length = 1 beat,\n\t# byte enable (SMCBE0-1) timing = SMCCSn timing, memory burst boundary\n\t# split setting = burst can cross any address boundary\n\tmww 0xf4311018 0x00000001\n\n\t# smc_direct_cmd_5 (SMC Direct Command register):\n\t# cmd_type = UpdateRegs, chip_select = CS1\n\tmww 0xf4311010 0x00c00000\n\n\techo \"Clocks, SRAM, and DDR SDRAM are now initialized.\"\n}\n\n#######################\n# Flash configuration #\n#######################\n\n# TODO: Implement NAND support.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/gti/espressobin.cfg",
    "content": "# config for ESPRESSObin from\n# Globalscale Technologies Inc.\n\n# srst is isolated through missing resistor\nreset_config trst_only\n\nsource [find target/marvell/88f3720.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/gumstix-aerocore.cfg",
    "content": "# JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on\n# the first interface of a Quad FTDI chip.  nTRST is bit 4.\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\n\nftdi layout_init 0x0000 0x001b\nftdi layout_signal nTRST -data 0x0010\n\nsource [find target/stm32f4x.cfg]\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hammer.cfg",
    "content": "# Target Configuration for the TinCanTools S3C2410 Based Hammer Module\n# http://www.tincantools.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# Reset Script for the TinCanTools S3C2410 Based Hammer Module\n\t# http://www.tincantools.com\n\t#\n\t# Setup primary clocks and initialize the SDRAM\n\tmww 0x53000000 0x00000000\n\tmww 0x4a000008 0xffffffff\n\tmww 0x4a00000c 0x000007ff\n\tmww 0x4c000000 0x00ffffff\n\tmww 0x4c000014 0x00000003\n\tmww 0x4c000004 0x000a1031\n\tmww 0x48000000 0x11111122\n\tmww 0x48000004 0x00000700\n\tmww 0x48000008 0x00000700\n\tmww 0x4800000c 0x00000700\n\tmww 0x48000010 0x00000700\n\tmww 0x48000014 0x00000700\n\tmww 0x48000018 0x00000700\n\tmww 0x4800001c 0x00018005\n\tmww 0x48000020 0x00018005\n\tmww 0x48000024 0x009c0459\n\tmww 0x48000028 0x000000b2\n\tmww 0x4800002c 0x00000030\n\tmww 0x48000030 0x00000030\n\tflash probe 0\n}\n\n\n#flash configuration\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxdb500sys.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for paired K4S561632C (64MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C13261\n  mww 0x00100140 0x030D0121\n\n  puts \"Configuring SRAM nCS0 for 150ns paired Par. Flash (x32)\"\n  mww 0x00100100 0x0201000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x02000000 4 4 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxeb500hmi.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads disable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC8M32 (32MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0111\n\n  puts \"Configuring SRAM nCS0 for 150ns Par. Flash (x16)\"\n  mww 0x00100100 0x0101000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxhx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx10.cfg]\n\n# Usually it is not needed to set srst_pulls_trst\n# but sometimes it does not work without it. If you encounter\n# problems try to line below\n# reset_config trst_and_srst srst_pulls_trst\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1\n\n# Par. Flash can only be accessed if DIP switch on the board is set in proper\n# position and init_sdrambus was called. Don't call these functions if the DIP\n# switch is in invalid position, as some outputs may collide. This is why this\n# function is not called automatically\nproc flash_init { } {\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x101C0100 0x01010008\n\n  flash probe 0\n}\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\nproc init_clocks { } {\n  puts \"Enabling all clocks \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n\n  mww  0x101c0028 0x00007511\n}\n\nproc init_sdrambus { } {\n  puts \"Initializing external SDRAM Bus 16 Bit \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n  mww  0x101c0C40 0x00000050\n\n  puts \"Configuring SDRAM controller for K4S561632E (32MB) \"\n  mww 0x101C0140 0\n  sleep 100\n  #mww 0x101C0144 0x00a13262\n  mww 0x101C0144 0x00a13251\n  mww 0x101C0148 0x00000033\n  mww 0x101C0140 0x030d0121\n}\n\n$_TARGETNAME configure -event reset-init {\n  halt\n  wait_halt 1000\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  init_clocks\n#  init_sdrambus\n\n  puts \"\"\n  puts \"-------------------------------------------------\"\n  puts \"Call 'init_clocks' to enable all clocks\"\n  puts \"Call 'init_sdrambus' to enable external SDRAM bus\"\n  puts \"-------------------------------------------------\"\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\n#flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxhx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx50.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x1C000140 0\n  mww 0x1C000144 0x00A12151\n  mww 0x1C000140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x1C000100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxhx500.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sleep 100\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x00100100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hilscher_nxsb100.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n}\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hitex_lpc1768stick.cfg",
    "content": "# Hitex LPC1768 Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/hitex_lpc1768stick.cfg]\n\nsource [find target/lpc17xx.cfg]\n\n\n# startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hitex_lpc2929.cfg",
    "content": "# Hitex eval board for LPC2929/LPC2939\n# http://www.hitex.com/\n\n# Delays on reset lines\nadapter srst delay 50\njtag_ntrst_delay 1\n\n# Maximum of 1/8 of clock frequency (XTAL = 16 MHz).\n# Adaptive clocking through RTCK is not supported.\nadapter speed 2000\n\n# Target device: LPC29xx with ETB\n# The following variables are used by the LPC2900 script:\n#   HAS_ETB             Must be set to 1. The CPU on this board has ETB.\n#   FLASH_CLOCK         CPU frequency at the time of flash programming (in kHz)\nset HAS_ETB             1\nset FLASH_CLOCK         112000\nsource [find target/lpc2900.cfg]\n\n# A working area will help speeding the flash programming\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 -work-area-backup 0\n$_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work-area-backup 0\n\n# Event handlers\n$_TARGETNAME configure -event reset-start {\n  # Back to the slow JTAG clock\n  adapter speed 2000\n}\n\n# External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB)\nset _FLASHNAME $_CHIPNAME.extflash\nflash bank $_FLASHNAME cfi 0x5C000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n\n$_TARGETNAME configure -event reset-init {\n  # Flash\n  mww 0x20200010 0x00000007     ;# FBWST: 7 wait states, not cached\n\n  # Use PLL\n  mww 0xFFFF8020 0x00000001     ;# XTAL_OSC_CONTROL: enable, 1-20 MHz\n  mww 0xFFFF8070 0x01000000     ;# SYS_CLK_CONF: Crystal\n  mww 0xFFFF8028 0x00000005     ;# PLL: (power down)\n  mww 0xFFFF8028 0x01060004     ;# PLL: M=7, 2P=2 (power up)\n                                 # --> f=112 MHz, fcco=224 MHz\n  sleep 100\n  mww 0xFFFF8070 0x02000000     ;# SYS_CLK_CONF: PLL\n\n  # Increase JTAG speed\n  adapter speed 6000\n\n  # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7)\n  mww 0xE0001138 0x0000001F     ;# P1.14 = D0\n  mww 0xE000113C 0x0000001F     ;# P1.15 = D1\n  mww 0xE0001140 0x0000001F     ;# P1.16 = D2\n  mww 0xE0001144 0x0000001F     ;# P1.17 = D3\n  mww 0xE0001148 0x0000001F     ;# P1.18 = D4\n  mww 0xE000114C 0x0000001F     ;# P1.19 = D5\n  mww 0xE0001150 0x0000001F     ;# P1.20 = D6\n  mww 0xE0001154 0x0000001F     ;# P1.21 = D7\n  mww 0xE0001200 0x0000001F     ;# P2.0  = D8\n  mww 0xE0001204 0x0000001F     ;# P2.1  = D9\n  mww 0xE0001208 0x0000001F     ;# P2.2  = D10\n  mww 0xE000120C 0x0000001F     ;# P2.3  = D11\n  mww 0xE0001210 0x0000001F     ;# P2.4  = D12\n  mww 0xE0001214 0x0000001F     ;# P2.5  = D13\n  mww 0xE0001218 0x0000001F     ;# P2.6  = D14\n  mww 0xE000121C 0x0000001F     ;# P2.7  = D15\n  mww 0xE0001104 0x00000007     ;# P1.1  = A1\n  mww 0xE0001108 0x00000007     ;# P1.2  = A2\n  mww 0xE000110C 0x00000007     ;# P1.3  = A3\n  mww 0xE0001110 0x00000007     ;# P1.4  = A4\n  mww 0xE0001114 0x00000007     ;# P1.5  = A5\n  mww 0xE0001118 0x00000007     ;# P1.6  = A6\n  mww 0xE000111C 0x00000007     ;# P1.7  = A7\n  mww 0xE0001028 0x00000007     ;# P0.10 = A8\n  mww 0xE000102C 0x00000007     ;# P0.11 = A9\n  mww 0xE0001030 0x00000007     ;# P0.12 = A10\n  mww 0xE0001034 0x00000007     ;# P0.13 = A11\n  mww 0xE0001038 0x00000007     ;# P0.14 = A12\n  mww 0xE000103C 0x00000007     ;# P0.15 = A13\n  mww 0xE0001048 0x00000007     ;# P0.18 = A14\n  mww 0xE000104C 0x00000007     ;# P0.19 = A15\n  mww 0xE0001050 0x00000007     ;# P0.20 = A16\n  mww 0xE0001054 0x00000007     ;# P0.21 = A17\n  mww 0xE0001058 0x00000007     ;# P0.22 = A18\n  mww 0xE000105C 0x00000007     ;# P0.23 = A19\n  mww 0xE0001238 0x00000007     ;# P2.14 = BLS0\n  mww 0xE000123C 0x00000007     ;# P2.15 = BLS1\n  mww 0xE0001300 0x00000007     ;# P3.0  = CS6\n  mww 0xE0001304 0x00000007     ;# P3.1  = CS7\n  mww 0xE0001130 0x00000007     ;# P1.12 = OE_N\n  mww 0xE0001134 0x00000007     ;# P1.13 = WE_N\n  mww 0x600000BC 0x00000041     ;# Bank6 16-bit mode, RBLE=1\n  mww 0x600000B4 0x00000000     ;# Bank6 WSTOEN=0\n  mww 0x600000AC 0x00000005     ;# Bank6 WST1=5\n  mww 0x600000B8 0x00000001     ;# Bank6 WSTWEN=1\n  mww 0x600000B0 0x00000006     ;# Bank6 WST2=6\n  mww 0x600000A8 0x00000002     ;# Bank6 IDCY=2\n  mww 0x600000D8 0x00000041     ;# Bank7 16-bit mode, RBLE=1\n  mww 0x600000D0 0x00000000     ;# Bank7 WSTOEN=0\n  mww 0x600000C8 0x0000000A     ;# Bank7 WST1=10\n  mww 0x600000D4 0x00000001     ;# Bank7 WSTWEN=1\n  mww 0x600000CC 0x0000000C     ;# Bank7 WST2=8\n  mww 0x600000C4 0x00000002     ;# Bank7 IDCY=2\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hitex_stm32-performancestick.cfg",
    "content": "# Hitex stm32 performance stick\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/stm32-stick.cfg]\n\nset  CHIPNAME stm32_hitex\nsource [find target/stm32f1x.cfg]\n\n# configure str750 connected to jtag chain\n# FIXME -- source [find target/str750.cfg] after cleaning that up\njtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041\n\n# for some reason this board like to startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/hitex_str9-comstick.cfg",
    "content": "# Hitex STR9-comStick\n# http://www.hitex.com/index.php?id=383\n# This works for the STR9-comStick revisions STR912CS-A1 and STR912CS-A2.\n\nsource [find interface/ftdi/hitex_str9-comstick.cfg]\n\n# set jtag speed\nadapter speed 3000\n\nadapter srst delay 100\njtag_ntrst_delay 100\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\n#\n# FIXME use the standard str912 target config; that script might need\n# updating to \"-ignore-version\" for the boundary scan TAP\n#\n#\tsource [find target/str912.cfg]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # Found on STR9-comStick, revision STR912CS-A1\n   set _BSTAPID1 0x1457f041\n   # Found on STR9-comStick, revision STR912CS-A2\n   set _BSTAPID2 0x2457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID1 -expected-id $_BSTAPID2\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/iar_lpc1768.cfg",
    "content": "# Board from IAR KickStart Kit for LPC1768\n# See www.iar.com and also\n# http://www.olimex.com/dev/lpc-1766stk.html\n#\n\nsource [find target/lpc17xx.cfg]\n\n# The chip has just been reset.\n#\n$_TARGETNAME configure -event reset-init {\n\t# FIXME update the core clock to run at 100 MHz;\n\t# and update JTAG clocking similarly; then\n\t# make CCLK match,\n\n\tflash probe 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/iar_str912_sk.cfg",
    "content": "# The IAR str912-sk evaluation kick start board has an str912\n\nsource [find target/str912.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/icnova_imx53_sodimm.cfg",
    "content": "#################################################################################################\n# Author: Benjamin Tietz <benjamin.tietz@in-circuit.de>                                        ;#\n# based on work from: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com>   ;#\n# Kiwigrid GmbH                                                                                ;#\n# Generated for In-Circuit i.MX53 SO-Dimm                                                      ;#\n#################################################################################################\n\n# The In-Circuit ICnova IMX53SODIMM board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"i.MX53 SO-Dimm board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { sodimm_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc sodimm_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n#*========================================================================================== ======\n# Initialization script for 32 bit DDR3 (CS0+CS1)\n#*========================================================================================== ======\n# Remux D24/D25 to perform Flash-access\n\tmww 0x53fa818C 0x00000000 ; #EIM_RW\n\tmww 0x53fa8180 0x00000000 ; #EIM_CS0\n\tmww 0x53fa8188 0x00000000 ; #EIM_OE\n\tmww 0x53fa817C 0x00000000 ; #A16\n\tmww 0x53fa8178 0x00000000 ; #A17\n\tmww 0x53fa8174 0x00000000 ; #A18\n\tmww 0x53fa8170 0x00000000 ; #A19\n\tmww 0x53fa816C 0x00000000 ; #A20\n\tmww 0x53fa8168 0x00000000 ; #A21\n\tmww 0x53fa819C 0x00000000 ; #DA0\n\tmww 0x53fa81A0 0x00000000 ; #DA1\n\tmww 0x53fa81A4 0x00000000 ; #DA2\n\tmww 0x53fa81A8 0x00000000 ; #DA3\n\tmww 0x53fa81AC 0x00000000 ; #DA4\n\tmww 0x53fa81B0 0x00000000 ; #DA5\n\tmww 0x53fa81B4 0x00000000 ; #DA6\n\tmww 0x53fa81B8 0x00000000 ; #DA7\n\tmww 0x53fa81BC 0x00000000 ; #DA8\n\tmww 0x53fa81C0 0x00000000 ; #DA9\n\tmww 0x53fa81C4 0x00000000 ; #DA10\n\tmww 0x53fa81C8 0x00000000 ; #DA11\n\tmww 0x53fa81CC 0x00000000 ; #DA12\n\tmww 0x53fa81D0 0x00000000 ; #DA13\n\tmww 0x53fa81D4 0x00000000 ; #DA14\n\tmww 0x53fa81D8 0x00000000 ; #DA15\n\tmww 0x53fa8118 0x00000000 ; #D16\n\tmww 0x53fa811C 0x00000000 ; #D17\n\tmww 0x53fa8120 0x00000000 ; #D18\n\tmww 0x53fa8124 0x00000000 ; #D19\n\tmww 0x53fa8128 0x00000000 ; #D20\n\tmww 0x53fa812C 0x00000000 ; #D21\n\tmww 0x53fa8130 0x00000000 ; #D22\n\tmww 0x53fa8134 0x00000000 ; #D23\n\tmww 0x53fa813c 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D24\n\tmww 0x53fa8140 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D25\n\tmww 0x53fa8144 0x00000000 ; #D26\n\tmww 0x53fa8148 0x00000000 ; #D27\n\tmww 0x53fa814C 0x00000000 ; #D28\n\tmww 0x53fa8150 0x00000000 ; #D29\n\tmww 0x53fa8154 0x00000000 ; #D30\n\tmww 0x53fa8158 0x00000000 ; #D31\n\n# DDR3 IOMUX configuration\n#* Global pad control options */\n\tmww 0x53fa8554 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53fa8558 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53fa8560 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53fa8564 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n\tmww 0x53fa8568 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53fa8570 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa8574 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53fa8578 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa857c 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53fa8580 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53fa8584 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53fa8588 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53fa8590 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53fa8594 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53fa86f0 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53fa86f4 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53fa86fc 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8714 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8714 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8718 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53fa871c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53fa8720 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53fa8724 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=0 XXX\n\tmww 0x53fa8728 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53fa872c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa86f4 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL for sDQS[3:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa8714 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE for D[31:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa86fc 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8724 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=00\n\n#* Data bus byte lane pad drive strength control options */\n#\tmww 0x53fa872c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa8554 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n#\tmww 0x53fa8558 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n#\tmww 0x53fa8728 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B2DS\n#\tmww 0x53fa8560 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n#\tmww 0x53fa8568 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n#\tmww 0x53fa871c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B1DS\n#\tmww 0x53fa8594 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n#\tmww 0x53fa8590 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n#\tmww 0x53fa8718 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B0DS\n#\tmww 0x53fa8584 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n#\tmww 0x53fa857c 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\n#* SDCLK pad drive strength control options */\n#\tmww 0x53fa8578 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n#\tmww 0x53fa8570 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\n#* Control and addr bus pad drive strength control options */\n#\tmww 0x53fa8574 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n#\tmww 0x53fa8588 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n#\tmww 0x53fa86f0 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_ADDDS for DDR addr bus\n#\tmww 0x53fa8720 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_CTLDS for CSD0, CSD1, SDCKE0, SDCKE1, SDWE\n\n#\tmww 0x53fa8564 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n#\tmww 0x53fa8580 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\n# Initialize DDR3 memory - Micron MT41J128M16-187Er\n#** Keep for now, same setting as CPU3 board **#\n\tmww 0x63fd901c 0x00008000\n#\tmww 0x63fd904c 0x01680172 ; #write leveling reg 0\n#\tmww 0x63fd9050 0x0021017f ; #write leveling reg 1\n\tmww 0x63fd9088 0x32383535 ; #read delay lines\n\tmww 0x63fd9090 0x40383538 ; #write delay lines\n#\tmww 0x63fd90F8 0x00000800 ; #Measure unit\n\tmww 0x63fd907c 0x0136014d ; #DQS gating 0\n\tmww 0x63fd9080 0x01510141 ; #DQS gating 1\n#* CPU3 Board settingr\n# Enable bank interleaving, Address mirror on, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n#\tmww 0x63fd9018 0x00091740 ; #Misc register:\n#* Quick Silver board setting\n# Enable bank interleaving, Address mirror off, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n\tmww 0x63fd9018 0x00011740 ; #Misc register\n\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n#\tmww 0x63fd9000 0xc3190000 ; #Main control register\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n\tmww 0x63fd9000 0x83190000 ; #Main control register\n# tRFC=64ck;tXS=68;tXP=3;tXPDLL=10;tFAW=15;CAS=6ck\n\tmww 0x63fd900C 0x555952E3 ; #timing configuration Reg 0\n# tRCD=6;tRP=6;tRC=21;tRAS=15;tRPA=1;tWR=6;tMRD=4;tCWL=5ck\n\tmww 0x63fd9010 0xb68e8b63 ; #timing configuration Reg 1\n# tDLLK(tXSRD)=512 cycles; tRTP=4;tWTR=4;tRRD=4\n\tmww 0x63fd9014 0x01ff00db ; #timing configuration Reg 2\n\tmww 0x63fd902c 0x000026d2 ; #command delay (default)\n\tmww 0x63fd9030 0x009f0e21 ; #out of reset delays\n# Keep tAOFPD, tAONPD, tANPD, and tAXPD as default since they are bigger than calc values\n\tmww 0x63fd9008 0x12273030 ; #ODT timings\n# tCKE=3; tCKSRX=5; tCKSRE=5\n\tmww 0x63fd9004 0x0002002d\n#Power down control\n#**********************************\n#DDR device configuration:\n#**********************************\n#**********************************\n# CS0:\n#**********************************\n\tmww 0x63fd901c 0x00008032 ; #write mode reg MR2 with cs0 (see below for settings)\n# Full array self refresh\n# Rtt_WR disabled (no ODT at IO CMOS operation)\n# Manual self refresh\n# CWS=5\n\tmww 0x63fd901c 0x00008033 ; #write mode reg MR3 with cs0.\n\tmww 0x63fd901c 0x00028031 ; #write mode reg MR1 with cs0. ODS=01: out buff= RZQ/7 (see below for settings)\n# out impedance = RZQ/7\n# Rtt_nom disabled (no ODT at IO CMOS operation)\n# Aditive latency off\n# write leveling disabled\n# tdqs (differential?) disabled\n\n\tmww 0x63fd901c 0x09208030 ; #write mode reg MR0 with cs0 , with dll_rst0\n\tmww 0x63fd901c 0x04008040 ; #ZQ calibration with cs0 (A10 high indicates ZQ cal long ZQCL)\n#**********************************\n# CS1:\n#**********************************\n#\tmww 0x63fd901c 0x0000803a ; #write mode reg MR2 with cs1.\n#\tmww 0x63fd901c 0x0000803b ; #write mode reg MR3 with cs1.\n#\tmww 0x63fd901c 0x00028039 ; #write mode reg MR1 with cs1. ODS=01: out buff= RZQ/7\n#\tmww 0x63fd901c 0x09208138 ; #write mode reg MR0 with cs1.\n#\tmww 0x63fd901c 0x04008048 ; #ZQ calibration with cs1(A10 high indicates ZQ cal long ZQCL)\n#**********************************\n\n\n\tmww 0x63fd9020 0x00001800 ; # Refresh control register\n\tmww 0x63fd9040 0x04b80003 ; # ZQ HW control\n\tmww 0x63fd9058 0x00022227 ; # ODT control register\n\n\tmww 0x63fd901c 0x00000000\n\n# CLKO muxing (comment out for now till needed to avoid conflicts with intended usage of signals)\n#\tmww 0x53FA8314 = 0\n#\tmww 0x53FA8320 0x4\n#\tmww 0x53FD4060 0x01e900f0\n\n#\tdap apsel 0\n}\n\n# IRAM\n$_TARGETNAME configure -work-area-phys 0xF8000000 -work-area-size 0x20000 -work-area-backup 1\n\nflash bank mx535_nor cfi 0xf0000000 0x800000 2 2 $_TARGETNAME\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/icnova_sam9g45_sodimm.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t                                                #\n# Author: Lars Poeschel (larsi@wh2.tu-dresden.de)\t\t\t\t\t\t\t\t\t\t\t\t#\n# Generated for In-Circuit ICnova SAM9G45 SODIMM\t\t\t\t\t\t\t\t\t\t\t\t#\n# http://www.ic-board.de/product_info.php?info=p214_ICnova-SAM9G45-SODIMM.html|ICnova\t\t\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g45.cfg]\n\n# Set reset type.\n# reset_config trst_and_srst\n\n# adapter srst delay 200\n# jtag_ntrst_delay 200\n\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g45_init}\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n$_TARGETNAME configure -event reset-start {at91sam9g45_start}\n\n\n# NandFlash configuration and definition\n# Future TBD\n# Flash configuration\n# flash bank cfi <base> <size> <chip width> <bus width> <target#>\nset _FLASHNAME $_CHIPNAME.flash\n# set _NANDNAME $_CHIPNAME.nand\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n# nand device $_NANDNAME at91sam9 $_TARGETNAME 0x40000000 0xFFFFE800\n\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g45_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n    # Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\tadapter speed 4\n    # Make sure processor is halted, or error will result in following steps.\n\thalt\n\twait_halt 10000\n    # RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n}\n\n\nproc at91sam9g45_init { } {\n\n\t# At reset AT91SAM9G45 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G45 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\t# Make sure processor is halted, or error will result in following steps.\n\thalt\n\t# RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n\t# WDT_MR : disable watchdog.\n\tmww 0xfffffd44 0x00008000\n\n\t# Enable the main 15.000 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\t#mww 0xfffffc28 0x202a3f01\n\tmww 0xfffffc28 0x20c73f03\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\t#mww 0xfffffc30 0x00000101\n\tmww 0xfffffc30 0x00001301\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 6000\n\n\t# Enable faster DCC downloads.\n\n\tarm7_9 dcc_downloads enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n#\tmww 0xfffff870 0xffff0000\n#\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\t# mww 0xffffef1c 0x000100a\n\n\t# The ICnova SAM9G45 SODIMM has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# four registers in order:  SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.\n\n\t# mww 0xffffec30 0x00020002\n\t# mww 0xffffec34 0x04040404\n\t# mww 0xffffec38 0x00070007\n\t# mww 0xffffec3c 0x00030003\n\n\t# Identify NandFlash bank 0.  Disabled at the moment because a memory driver is not yet complete.\n\n#\tnand probe 0\n\n    # SMC_SETUP0 : Setup SMC for NOR Flash\n\tmww 0xffffe800 0x0012000a\n    # SMC_PULSE0\n\tmww 0xffffe804 0x3b38343b\n    # SMC_CYCLE0\n\tmww 0xffffe808 0x003f003f\n    # SMC_MODE0\n\tmww 0xffffe80c 0x00001000\n    # Identify flash bank 0\n\tflash probe 0\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Samsung K4T51083QG memory.\n\n\t# 0. Enable DDR2 Clock\n\tmww 0xfffffc00 0x4\n\t# 1. Program memory device type\n\t# 1.1 configure the DDR controller\n\tmww 0xffffe620 0x16\n\t# 1.2 program the DDR controller\n\tmww 0xffffe608 0x3d\n\n\t# 2. program memory device features\n\t# 2.1 assume timings for 7.5ns min clock period\n\tmww 0xffffe60c 0x21128226\n\t# 2.2 pSDDRC->HDDRSDRC2_T1PR\n\tmww 0xffffe610 0x02c8100e\n\t# 2.3 pSDDRC->HDDRSDRC2_T2PR\n\tmww 0xffffe614 0x01000702\n\t# 3. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 3.1 delay 200us\n\tsleep 1\n\t# jim tcl alternative: after ms\n\t# after 0.2\n\n\t# 4. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 4.1 delay 400ns\n\n\t# 5. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 5.1 delay 400ns\n\n\t# 6. set EMR operation (EMRS2)\n\tmww 0xffffe600 0x5\n\tmww 0x74000000 0x1\n\t# 6.1 delay 2 cycles\n\n\t# 7. set EMR operation (EMRS3)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 7.1 delay 2 cycles\n\n\t# 8. set EMR operation (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 8.1 delay 200 cycles (400Mhz -> 5 * 10^-7s)\n\tsleep 1\n\n\t# 9. Enable DLL Reset (set DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] | 0x80}]\n\tmww 0xffffe608 $CR\n\n\t# 10. mode register cycle to reset the DLL\n\tmww 0xffffe600 0x5\n\tmww 0x70000000 0x1\n\t# 10.1 delay 2 cycles\n\n\t# 11. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 11.1 delay 400 ns\n\n\t# 12. two auto-refresh (CBR) cycles are provided.\n\tmww 0xffffe600 0x4\n\tmww 0x70000000 0x1\n\t# 12.1 delay 10 cycles\n\t# 12.2 2nd cycle (schreiben des Mode Register sparen wir uns)\n\tmww 0x70000000 0x1\n\t# 12.3 delay 10 cycles\n\n\t# 13. disable DLL reset (clear DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffffff7f}]\n\tmww 0xffffe608 $CR\n\n\t# 14. mode register set cycle\n\tmww 0xffffe600 0x3\n\tmww 0x70000000 0x1\n\n\t# 15. program OCD field (set OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] | 0x7000}]\n\tmww 0xffffe608 $CR\n\n\t# 16. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 16.1 delay 2 cycles\n\n\t# 17. disable OCD field (clear OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffff8fff}]\n\tmww 0xffffe608 $CR\n\n\t# 18. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 18.1 delay 2 cycles\n\n\t# 19. normal mode command\n\tmww 0xffffe600 0x0\n\tmww 0x70000000 0x1\n\n\t# 20. perform write to any address\n\t#mww 0x70000000 0x1\n\n\t# 21. write refresh rate into the count field of the refresh rate register\n\tmww 0xffffe604 0x24b\n\t# 21.1 delay (500 * 6 cycles)\n\n\tarm7_9 fast_memory_access enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx27ads.cfg",
    "content": "# The IMX27 ADS eval board has a single IMX27 chip\n# Note: tested on IMX27ADS Board REV-2.6 and REV-2.8\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27ads_init }\n\n# The IMX27 ADS board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\nproc imx27ads_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\t# ========================================\n\t#  Configure PSRAM on CS5\n\t# ========================================\n\tmww 0xd8002050 0x0000dcf6\n\tmww 0xd8002054 0x444a4541\n\tmww 0xd8002058 0x44443302\n\n\t#  ========================================\n\t#         Configure16 bit NorFlash on CS0\n\t#  ========================================\n\tmww 0xd8002000 0x0000CC03\n\tmww 0xd8002004 0xa0330D01\n\tmww 0xd8002008 0x00220800\n\n\t# ========================================\n\t#  Configure CPLD on CS4\n\t# ========================================\n\tmww 0xd8002040 0x0000DCF6\n\tmww 0xd8002044 0x444A4541\n\tmww 0xd8002048 0x44443302\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\tmww 0xD8001000 0x92200000\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xA2200000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xB2200000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\tmww 0xD8001000 0x82228085\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx27lnst.cfg",
    "content": "# The Linuxstamp-mx27 is board has a single IMX27 chip\n# For further info see http://opencircuits.com/Linuxstamp_mx27#OpenOCD\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27lnst_init }\n\nproc imx27lnst_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\tadapter speed 500\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\t#mww 0xD8001000 0x92200000\n\tmww 0xD8001000 0x91120000\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xA2200000\n\tmww 0xD8001000 0xA1120000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xB2200000\n\tmww 0xD8001000 0xB1120000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\t#mww 0xD8001000 0x82228085\n\tmww 0xD8001000 0x81128080\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx28evk.cfg",
    "content": "# The IMX28EVK eval board has a IMX28 chip\n# Tested on SCH-26241 Rev D board with Olimex ARM-USB-OCD\n# Date:\t201-02-01\n# Authors: James Robinson & Fabio Estevam\n\nsource [find target/imx28.cfg]\n$_TARGETNAME configure -event gdb-attach { imx28evk_init }\n$_TARGETNAME configure -event reset-init { imx28evk_init }\n\nproc imx28evk_init { } {\n\n\thalt\n\n\t#****************************\n\t# VDDD setting\n\t#****************************\n\t# set VDDD =1.55V =(0.8v + TRIG x 0.025v), TRIG=0x1e\n\tmww 0x80044010 0x0003F503\n\tmww 0x80044040 0x0002041E\n\n\t#****************************\n\t# CLOCK set up\n\t#****************************\n\t# Power up PLL0 HW_CLKCTRL_PLL0CTRL0\n\tmww 0x80040000 0x00020000\n\t# Set up fractional dividers for CPU and EMI - HW_CLKCTRL_FRAC0\n\t# EMI - first set DIV_EMI to div-by-2 before programming frac divider\n\tmww 0x800400F0 0x80000002\n\n\n\t# CPU: CPUFRAC=19 480*18/29=454.7MHz, EMI: EMIFRAC=22, (480/2)*18/22=196.4MHz\n\tmww 0x800401B0 0x92921613\n\t# Clear the bypass bits for CPU and EMI clocks in HW_CLKCTRL_CLKSEQ_CLR\n\tmww 0x800401D8 0x00040080\n\t# HCLK = 227MHz,HW_CLKCTRL_HBUS DIV =0x2\n\tmww 0x80040060 0x00000002\n\n\t#****************************\n\t# POWER up DCDD_VDDA (DDR2)\n\t#****************************\n\t# Now set the voltage level to 1.8V HW_POWER_VDDACTRL bits TRC=0xC\n\tmww 0x80044050 0x0000270C\n\n\t#****************************\n\t# DDR2 DCDD_VDDA\n\t#****************************\n\t# First set up pin muxing and drive strength\n\t# Ungate module clock and bring out of reset HW_PINCTRL_CTRL_CLR\n\tmww 0x80018008 0xC0000000\n\n\t#****************************\n\t# EMI PAD setting\n\t#****************************\n\t# Set up drive strength for EMI pins\n\tmww 0x80019B80 0x00030000\n\t#IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\n\t# Set up pin muxing for EMI, HW_PINCTRL_MUXSEL10, 11, 12, 13\n\tmww 0x800181A8 0xFFFFFFFF\n\tmww 0x800181B8 0xFFFFFFFF\n\tmww 0x800181C8 0xFFFFFFFF\n\tmww 0x800181D8 0xFFFFFFFF\n\n\t#** Ungate EMI clock in CCM\n\tmww 0x800400F0 0x00000002\n\n\t#============================================================================\n\t# DDR Controller Registers\n\t#============================================================================\n\t# Manufacturer:    Elpida\n\t# Device Part Number:    EDE1116AEBG\n\t# Clock Freq.:     200MHz\n\t# Density:         1Gb\n\t# Chip Selects:    1\n\t# Number of Banks: 8\n\t# Row address:     13\n\t# Column address:  10\n\t#============================================================================\n\tmww 0x800E0000 0x00000000\n\tmww 0x800E0040 0x00000000\n\tmww 0x800E0054 0x00000000\n\tmww 0x800E0058 0x00000000\n\tmww 0x800E005C 0x00000000\n\tmww 0x800E0060 0x00000000\n\tmww 0x800E0064 0x00000000\n\tmww 0x800E0068 0x00010101\n\tmww 0x800E006C 0x01010101\n\tmww 0x800E0070 0x000f0f01\n\tmww 0x800E0074 0x0102020A\n\tmww 0x800E007C 0x00010101\n\tmww 0x800E0080 0x00000100\n\tmww 0x800E0084 0x00000100\n\tmww 0x800E0088 0x00000000\n\tmww 0x800E008C 0x00000002\n\tmww 0x800E0090 0x01010000\n\tmww 0x800E0094 0x07080403\n\tmww 0x800E0098 0x06005003\n\tmww 0x800E009C 0x0A0000C8\n\tmww 0x800E00A0 0x02009C40\n\tmww 0x800E00A4 0x0002030C\n\tmww 0x800E00A8 0x0036B009\n\tmww 0x800E00AC 0x031A0612\n\tmww 0x800E00B0 0x02030202\n\tmww 0x800E00B4 0x00C8001C\n\tmww 0x800E00C0 0x00011900\n\tmww 0x800E00C4 0xffff0303\n\tmww 0x800E00C8 0x00012100\n\tmww 0x800E00CC 0xffff0303\n\tmww 0x800E00D0 0x00012100\n\tmww 0x800E00D4 0xffff0303\n\tmww 0x800E00D8 0x00012100\n\tmww 0x800E00DC 0xffff0303\n\tmww 0x800E00E0 0x00000003\n\tmww 0x800E00E8 0x00000000\n\tmww 0x800E0108 0x00000612\n\tmww 0x800E010C 0x01000f02\n\tmww 0x800E0114 0x00000200\n\tmww 0x800E0118 0x00020007\n\tmww 0x800E011C 0xf4004a27\n\tmww 0x800E0120 0xf4004a27\n\tmww 0x800E012C 0x07400300\n\tmww 0x800E0130 0x07400300\n\tmww 0x800E013C 0x00000005\n\tmww 0x800E0140 0x00000000\n\tmww 0x800E0144 0x00000000\n\tmww 0x800E0148 0x01000000\n\tmww 0x800E014C 0x01020408\n\tmww 0x800E0150 0x08040201\n\tmww 0x800E0154 0x000f1133\n\tmww 0x800E015C 0x00001f04\n\tmww 0x800E0160 0x00001f04\n\tmww 0x800E016C 0x00001f04\n\tmww 0x800E0170 0x00001f04\n\tmww 0x800E0288 0x00010000\n\tmww 0x800E028C 0x00030404\n\tmww 0x800E0290 0x00000003\n\tmww 0x800E02AC 0x01010000\n\tmww 0x800E02B0 0x01000000\n\tmww 0x800E02B4 0x03030000\n\tmww 0x800E02B8 0x00010303\n\tmww 0x800E02BC 0x01020202\n\tmww 0x800E02C0 0x00000000\n\tmww 0x800E02C4 0x02030303\n\tmww 0x800E02C8 0x21002103\n\tmww 0x800E02CC 0x00061200\n\tmww 0x800E02D0 0x06120612\n\tmww 0x800E02D4 0x04420442\n\t# Mode register 0 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02D8 0x00000000\n\t# Mode register 0 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02DC 0x00040004\n\t# Mode register 1 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E0 0x00000000\n\t# Mode register 1 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02E4 0x00000000\n\t# Mode register 2 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E8 0x00000000\n\t# Mode register 2 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02EC 0x00000000\n\t# Mode register 3 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02F0 0x00000000\n\t# Mode register 3 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02F4 0xffffffff\n\n\t#**  start controller **#\n\tmww 0x800E0040 0x00000001\n\t# bit[0]: start\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx31pdk.cfg",
    "content": "# The IMX31PDK eval board has a single IMX31 chip\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx31pdk_init }\n\nproc self_test {} {\n\techo \"Running 100 iterations of test.\"\n\tdump_image /ram/test 0x80000000 0x40000\n\tfor {set i 0} {$i < 100} {set i [expr {$i+1}]} {\n\t\techo \"Iteration $i\"\n\t\treset init\n\t\tmww 0x80000000 0x12345678 0x10000\n\t\tload_image /ram/test 0x80000000 bin\n\t\tverify_image /ram/test 0x80000000 bin\n\t}\n}\n\n\n# Slow fallback frequency\n# measure_clk indicates ca. 3-4MHz.\njtag_rclk 1000\n\nproc imx31pdk_init { } {\n\n\timx3x_reset\n\n\t# This setup puts RAM at 0x80000000\n\n\tmww 0x53FC0000 0x040\n\tmww 0x53F80000 0x074B0B7D\n\n\t# 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40\n\t#mww 0x53F80004 0xFF871D50\n\t#mww 0x53F80010 0x00271C1B\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000CC03\n\tmww 0xb8002004 0xa0330D01\n\tmww 0xb8002008 0x00220800\n\n\t# Configure CPLD on CS4\n\tmww 0xb8002040 0x0000DCF6\n\tmww 0xb8002044 0x444A4541\n\tmww 0xb8002048 0x44443302\n\n\t# SDCLK\n\tmww 0x43FAC26C 0\n\n\t# CAS\n\tmww 0x43FAC270 0\n\n\t# RAS\n\tmww 0x43FAC274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43FAC27C 0x1000\n\n\t# DQM3\n\tmww 0x43FAC284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC)\n\tmww 0x43FAC288 0\n\tmww 0x43FAC28C 0\n\tmww 0x43FAC290 0\n\tmww 0x43FAC294 0\n\tmww 0x43FAC298 0\n\tmww 0x43FAC29C 0\n\tmww 0x43FAC2A0 0\n\tmww 0x43FAC2A4 0\n\tmww 0x43FAC2A8 0\n\tmww 0x43FAC2AC 0\n\tmww 0x43FAC2B0 0\n\tmww 0x43FAC2B4 0\n\tmww 0x43FAC2B8 0\n\tmww 0x43FAC2BC 0\n\tmww 0x43FAC2C0 0\n\tmww 0x43FAC2C4 0\n\tmww 0x43FAC2C8 0\n\tmww 0x43FAC2CC 0\n\tmww 0x43FAC2D0 0\n\tmww 0x43FAC2D4 0\n\tmww 0x43FAC2D8 0\n\tmww 0x43FAC2DC 0\n\n\t# Initialization script for 32 bit DDR on MX31 ADS\n\tmww 0xB8001010 0x00000004\n\tmww 0xB8001004 0x006ac73a\n\tmww 0xB8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\tmww 0xB8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\tmww 0xB8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\tmww 0xB8001000 0x82226080\n\tmww 0x80000000 0xDEADBEEF\n\tmww 0xB8001010 0x0000000c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx35pdk.cfg",
    "content": "# The IMX35PDK eval board has a single IMX35 chip\nsource [find target/imx35.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx35pdk_init }\n\n# Stick to *really* low clock rate or reset will fail\n# without RTCK / RCLK\njtag_rclk 10\n\nproc imx35pdk_init { } {\n\n\timx3x_reset\n\n\tmww 0x43f00040 0x00000000\n\tmww 0x43f00044 0x00000000\n\tmww 0x43f00048 0x00000000\n\tmww 0x43f0004C 0x00000000\n\tmww 0x43f00050 0x00000000\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00040 0x00000000\n\tmww 0x53f00044 0x00000000\n\tmww 0x53f00048 0x00000000\n\tmww 0x53f0004C 0x00000000\n\tmww 0x53f00050 0x00000000\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# clock setup\n\tmww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP\n\tmww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz.\n\n\t#=================================================\n\t# WEIM config\n\t#=================================================\n\t# CS0U\n\tmww 0xB8002000 0x0000CC03\n\t# CS0L\n\tmww 0xB8002004 0xA0330D01\n\t# CS0A\n\tmww 0xB8002008 0x00220800\n\t# CS5U\n\tmww 0xB8002050 0x0000dcf6\n\t# CS5L\n\tmww 0xB8002054 0x444a4541\n\t# CS5A\n\tmww 0xB8002058 0x44443302\n\n\t# IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR\n\tmww 0x43FAC368 0x00000006\n\tmww 0x43FAC36C 0x00000006\n\tmww 0x43FAC370 0x00000006\n\tmww 0x43FAC374 0x00000006\n\tmww 0x43FAC378 0x00000006\n\tmww 0x43FAC37C 0x00000006\n\tmww 0x43FAC380 0x00000006\n\tmww 0x43FAC384 0x00000006\n\tmww 0x43FAC388 0x00000006\n\tmww 0x43FAC38C 0x00000006\n\tmww 0x43FAC390 0x00000006\n\tmww 0x43FAC394 0x00000006\n\tmww 0x43FAC398 0x00000006\n\tmww 0x43FAC39C 0x00000006\n\tmww 0x43FAC3A0 0x00000006\n\tmww 0x43FAC3A4 0x00000006\n\tmww 0x43FAC3A8 0x00000006\n\tmww 0x43FAC3AC 0x00000006\n\tmww 0x43FAC3B0 0x00000006\n\tmww 0x43FAC3B4 0x00000006\n\tmww 0x43FAC3B8 0x00000006\n\tmww 0x43FAC3BC 0x00000006\n\tmww 0x43FAC3C0 0x00000006\n\tmww 0x43FAC3C4 0x00000006\n\tmww 0x43FAC3C8 0x00000006\n\tmww 0x43FAC3CC 0x00000006\n\tmww 0x43FAC3D0 0x00000006\n\tmww 0x43FAC3D4 0x00000006\n\tmww 0x43FAC3D8 0x00000006\n\n\t# DDR data bus SD 0 through 31\n\tmww 0x43FAC3DC 0x00000082\n\tmww 0x43FAC3E0 0x00000082\n\tmww 0x43FAC3E4 0x00000082\n\tmww 0x43FAC3E8 0x00000082\n\tmww 0x43FAC3EC 0x00000082\n\tmww 0x43FAC3F0 0x00000082\n\tmww 0x43FAC3F4 0x00000082\n\tmww 0x43FAC3F8 0x00000082\n\tmww 0x43FAC3FC 0x00000082\n\tmww 0x43FAC400 0x00000082\n\tmww 0x43FAC404 0x00000082\n\tmww 0x43FAC408 0x00000082\n\tmww 0x43FAC40C 0x00000082\n\tmww 0x43FAC410 0x00000082\n\tmww 0x43FAC414 0x00000082\n\tmww 0x43FAC418 0x00000082\n\tmww 0x43FAC41c 0x00000082\n\tmww 0x43FAC420 0x00000082\n\tmww 0x43FAC424 0x00000082\n\tmww 0x43FAC428 0x00000082\n\tmww 0x43FAC42c 0x00000082\n\tmww 0x43FAC430 0x00000082\n\tmww 0x43FAC434 0x00000082\n\tmww 0x43FAC438 0x00000082\n\tmww 0x43FAC43c 0x00000082\n\tmww 0x43FAC440 0x00000082\n\tmww 0x43FAC444 0x00000082\n\tmww 0x43FAC448 0x00000082\n\tmww 0x43FAC44c 0x00000082\n\tmww 0x43FAC450 0x00000082\n\tmww 0x43FAC454 0x00000082\n\tmww 0x43FAC458 0x00000082\n\n\t# DQM setup\n\tmww 0x43FAC45c 0x00000082\n\tmww 0x43FAC460 0x00000082\n\tmww 0x43FAC464 0x00000082\n\tmww 0x43FAC468 0x00000082\n\n\tmww 0x43FAC46c 0x00000006\n\tmww 0x43FAC470 0x00000006\n\tmww 0x43FAC474 0x00000006\n\tmww 0x43FAC478 0x00000006\n\tmww 0x43FAC47c 0x00000006\n\tmww 0x43FAC480 0x00000006\t;# CSD0\n\tmww 0x43FAC484 0x00000006\t;# CSD1\n\tmww 0x43FAC488 0x00000006\n\tmww 0x43FAC48c 0x00000006\n\tmww 0x43FAC490 0x00000006\n\tmww 0x43FAC494 0x00000006\n\tmww 0x43FAC498 0x00000006\n\tmww 0x43FAC49c 0x00000006\n\tmww 0x43FAC4A0 0x00000006\n\tmww 0x43FAC4A4 0x00000006\t;# RAS\n\tmww 0x43FAC4A8 0x00000006\t;# CAS\n\tmww 0x43FAC4Ac 0x00000006\t;# SDWE\n\tmww 0x43FAC4B0 0x00000006 \t;# SDCKE0\n\tmww 0x43FAC4B4 0x00000006  ;# SDCKE1\n\tmww 0x43FAC4B8 0x00000002  ;# SDCLK\n\n\t# SDQS0 through SDQS3\n\tmww 0x43FAC4Bc 0x00000082\n\tmww 0x43FAC4C0 0x00000082\n\tmww 0x43FAC4C4 0x00000082\n\tmww 0x43FAC4C8 0x00000082\n\n\n\t# *==================================================\n\t#  Initialization script for 32 bit DDR2 on RINGO 3DS\n\t# *==================================================\n\n\t#--------------------------------------------\n\t# Init CCM\n\t#--------------------------------------------\n\tmww 0x53F80028 0x7D000028\n\n\t#--------------------------------------------\n\t# Init IOMUX for JTAG\n\t#--------------------------------------------\n\tmww 0x43FAC5EC 0x000000C3\n\tmww 0x43FAC5F0 0x000000C3\n\tmww 0x43FAC5F4 0x000000F3\n\tmww 0x43FAC5F8 0x000000F3\n\tmww 0x43FAC5FC 0x000000F3\n\tmww 0x43FAC600 0x000000F3\n\tmww 0x43FAC604 0x000000F3\n\n\n\t# ESD_MISC : enable DDR2\n\tmww 0xB8001010 0x00000304\n\n\t#--------------------------------------------\n\t# Init 32-bit DDR2 memory on CSD0\n\t# COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25]\n\t#--------------------------------------------\n\n\t# ESD_ESDCFG0 : set timing parameters\n\tmww 0xB8001004 0x007ffC2f\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmww 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg EMR2\n\tmwb 0x84000000 0xda\n\t# DDR2 : Load reg EMR3\n\tmwb 0x86000000 0xda\n\t# DDR2 : Load reg EMR1 -- enable DLL\n\tmwb 0x82000400 0xda\n\t# DDR2 : Load reg MR -- reset DLL\n\tmwb 0x80000333 0xda\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmwb 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Manual-Refresh mode\n\tmww 0xB8001000 0xA2220000\n\t# DDR2 : Manual-Refresh 2 times\n\tmww 0x80000000 0x87654321\n\tmww 0x80000000 0x87654321\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset\n\tmwb 0x80000233 0xda\n\t# DDR2 : Load reg EMR1 -- OCD default\n\tmwb 0x82000780 0xda\n\t# DDR2 : Load reg EMR1 -- OCD exit\n\tmwb 0x82000400 0xda\t;# ODT disabled\n\n\t# ESD_ESDCTL0 : select normal-operation mode\n\t# DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit\n\t# disable PWT & PRCT\n\t# disable Auto-Refresh\n\tmww 0xB8001000 0x82220080\n\n\t## ESD_ESDCTL0 : enable Auto-Refresh\n\tmww 0xB8001000 0x82228080\n\t## ESD_ESDCTL1 : enable Auto-Refresh\n\tmww 0xB8001008 0x00002000\n\n\n\t#***********************************************\n\t# Adjust the ESDCDLY5 register\n\t#***********************************************\n\t# Vary DQS_ABS_OFFSET5 for writes\n\tmww 0xB8001020 0x00F48000\t;# this is the default value\n\tmww 0xB8001024 0x00F48000\t;# this is the default value\n\tmww 0xB8001028 0x00F48000\t;# this is the default value\n\tmww 0xB800102c 0x00F48000\t;# this is the default value\n\n\n\t#Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC)\n\tmww 0xB8001010 0x00000384\n\t# wait a while\n\tsleep 1000\n\t# now clear the force measurement bit\n\tmww 0xB8001010 0x00000304\n\n\t# dummy write to DDR memory to set DQS low\n\tmww 0x80000000 0x00000000\n\n\tmww 0x30000100 0x0\n\tmww 0x30000104 0x31024\n\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx53-m53evk.cfg",
    "content": "#######################################\n# DENX M53EVK                         #\n# http://www.denx-cs.de/?q=M53EVK     #\n# Author: Marek Vasut <marex@denx.de> #\n# Based on imx53loco.cfg              #\n#######################################\n\n# The DENX M53EVK has on-board JTAG adapter\nsource [find interface/ftdi/m53evk.cfg]\n# The DENX M53EVK board has a single i.MX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 M53EVK board lodaded.\"\n\n# Set reset type\nreset_config trst_and_srst separate trst_open_drain srst_open_drain\n\n# Run at 6 MHz\nadapter speed 6000\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { m53evk_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc m53evk_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53fa86f4 0x00000000\t ;# GRP_DDRMODE_CTL\n\tmww 0x53fa8714 0x00000000\t ;# GRP_DDRMODE\n\tmww 0x53fa86fc 0x00000000\t ;# GRP_DDRPKE\n\tmww 0x53fa8724 0x04000000\t ;# GRP_DDR_TYPE\n\n\tmww 0x53fa872c 0x00300000\t ;# GRP_B3DS\n\tmww 0x53fa8554 0x00300000\t ;# DRAM_DQM3\n\tmww 0x53fa8558 0x00300040\t ;# DRAM_SDQS3\n\n\tmww 0x53fa8728 0x00300000\t ;# GRP_B2DS\n\tmww 0x53fa8560 0x00300000\t ;# DRAM_DQM2\n\tmww 0x53fa8568 0x00300040\t ;# DRAM_SDQS2\n\n\tmww 0x53fa871c 0x00300000\t ;# GRP_B1DS\n\tmww 0x53fa8594 0x00300000\t ;# DRAM_DQM1\n\tmww 0x53fa8590 0x00300040\t ;# DRAM_SDQS1\n\n\tmww 0x53fa8718 0x00300000\t ;# GRP_B0DS\n\tmww 0x53fa8584 0x00300000\t ;# DRAM_DQM0\n\tmww 0x53fa857c 0x00300040\t ;# DRAM_SDQS0\n\n\tmww 0x53fa8578 0x00300000\t ;# DRAM_SDCLK_0\n\tmww 0x53fa8570 0x00300000\t ;# DRAM_SDCLK_1\n\n\tmww 0x53fa8574 0x00300000\t ;# DRAM_CAS\n\tmww 0x53fa8588 0x00300000\t ;# DRAM_RAS\n\tmww 0x53fa86f0 0x00300000\t ;# GRP_ADDDS\n\tmww 0x53fa8720 0x00300000\t ;# GRP_CTLDS\n\n\tmww 0x53fa8564 0x00300040\t ;# DRAM_SDODT1\n\tmww 0x53fa8580 0x00300040\t ;# DRAM_SDODT0\n\n\t# Initialize DDR2 memory\n\tmww 0x63fd9088 0x32383535\n\tmww 0x63fd9090 0x40383538\n\tmww 0x63fd907c 0x0136014d\n\tmww 0x63fd9080 0x01510141\n\n\tmww 0x63fd9018 0x00011740\n\tmww 0x63fd9000 0xc3190000\n\tmww 0x63fd900c 0x555952e3\n\tmww 0x63fd9010 0xb68e8b63\n\tmww 0x63fd9014 0x01ff00db\n\tmww 0x63fd902c 0x000026d2\n\tmww 0x63fd9030 0x009f0e21\n\tmww 0x63fd9008 0x12273030\n\tmww 0x63fd9004 0x0002002d\n\tmww 0x63fd901c 0x00008032\n\tmww 0x63fd901c 0x00008033\n\tmww 0x63fd901c 0x00028031\n\tmww 0x63fd901c 0x092080b0\n\tmww 0x63fd901c 0x04008040\n\tmww 0x63fd901c 0x0000803a\n\tmww 0x63fd901c 0x0000803b\n\tmww 0x63fd901c 0x00028039\n\tmww 0x63fd901c 0x09208138\n\tmww 0x63fd901c 0x04008048\n\tmww 0x63fd9020 0x00001800\n\tmww 0x63fd9040 0x04b80003\n\tmww 0x63fd9058 0x00022227\n\tmww 0x63fd901c 0x00000000\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx53loco.cfg",
    "content": "##################################################################################\n# Author: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com> #\n# Kiwigrid GmbH                                                                  #\n##################################################################################\n\n# The IMX53LOCO (QSB) board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 Loco board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n#adapter srst delay 200\n#jtag_ntrst_delay 200\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { loco_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc loco_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53FA8554 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53FA8558 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53FA8560 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53FA8564 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT\n\tmww 0x53FA8568 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53FA8570 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\tmww 0x53FA8574 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53FA8578 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n\tmww 0x53FA857c 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53FA8580 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53FA8584 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53FA8588 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53FA8590 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53FA8594 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53FA86f0 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53FA86f4 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53FA86fc 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n\tmww 0x53FA8714 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode\n\tmww 0x53FA8718 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53FA871c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53FA8720 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53FA8724 0x04000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL0=\n\tmww 0x53FA8728 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53FA872c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B3DS\n\n\t# Initialize DDR2 memory\n\tmww 0x63FD9088 0x35343535\t;# ESDCTL_RDDLCTL\n\tmww 0x63FD9090 0x4d444c44\t;# ESDCTL_WRDLCTL\n\tmww 0x63FD907c 0x01370138\t;# ESDCTL_DGCTRL0\n\tmww 0x63FD9080 0x013b013c\t;# ESDCTL_DGCTRL1\n\tmww 0x63FD9018 0x00011740\t;# ESDCTL_ESDMISC\n\tmww 0x63FD9000 0xc3190000\t;# ESDCTL_ESDCTL\n\tmww 0x63FD900c 0x9f5152e3\t;# ESDCTL_ESDCFG0\n\tmww 0x63FD9010 0xb68e8a63\t;# ESDCTL_ESDCFG1\n\tmww 0x63FD9014 0x01ff00db\t;# ESDCTL_ESDCFG2\n\tmww 0x63FD902c 0x000026d2\t;# ESDCTL_ESDRWD\n\tmww 0x63FD9030 0x009f0e21\t;# ESDCTL_ESDOR\n\tmww 0x63FD9008 0x12273030\t;# ESDCTL_ESDOTC\n\tmww 0x63FD9004 0x0002002d\t;# ESDCTL_ESDPDC\n\tmww 0x63FD901c 0x00008032\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00008033\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028031\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x052080b0\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008040\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803a\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803b\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028039\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x05208138\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008048\t;# ESDCTL_ESDSCR\n\tmww 0x63FD9020 0x00005800\t;# ESDCTL_ESDREF\n\tmww 0x63FD9040 0x04b80003\t;# ESDCTL_ZQHWCTRL\n\tmww 0x63FD9058 0x00022227\t;# ESDCTL_ODTCTRL\n\tmww 0x63FD901C 0x00000000\t;# ESDCTL_ESDSCR\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/imx8mp-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8MP-EVK\n#\n# Board includes FTDI-based JTAG adapter: interface/ftdi/imx8mp-evk.cfg\n#\n\ntransport select jtag\nadapter speed 1000\nreset_config srst_only\nadapter srst delay 100\n\nset CHIPNAME imx8mp\nset CHIPCORES 4\n\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/insignal_arndale.cfg",
    "content": "#\n# InSignal Arndale board\n#\n\nsource [find target/exynos5250.cfg]\n\n# Experimentally determined highest working speed\nadapter speed 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kasli.cfg",
    "content": "adapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\nftdi layout_init 0x0008 0x000b\n# adapter usb location 1:8\n\nreset_config none\ntransport select jtag\nadapter speed 25000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kc100.cfg",
    "content": "# Knovative KC-100 cable modem\n\n# TNETC4401PYP, 208-QFP U3\nsource [find target/tnetc4401.cfg]\n\n# 14-pin EJTAG on JP1. Standard pinout, 1-3-5-7-9-11 = nTRST-TDI-TDO-TMS-TCK-nSRST. Use 2 for GND.\n# Was initially disabled in hardware; had to add a solder bridge reenabling R124, R125 on back.\nreset_config trst_and_srst separate\n\n# 16Mb Intel CFI flash. Note this CPU has an internal ROM at 0x1FC0000 (phys) for cold boot.\n# All that really does is some minimal checks before jumping to external flash at 0x00000000 phys.\n# That is remapped to 0xB0000000 uncached, 0x90000000 cached.\nflash bank intel cfi 0xB0000000 0x200000 2 2 $_TARGETNAME\n\n# Perform this after a clean reboot, halt, and reset init (which should also leave it halted).\nproc kc100_dump_flash {} {\n\techo \"Probing 48 TSOP Intel CFI flash chip (2MB)...\"\n\tflash probe intel\n\techo \"Dumping 2MB flash chip to flashdump.bin.\n\tflash read_bank 0 flashdump.bin 0 0x200000\n}\n\n#TODO figure out memory init sequence to be able to dump from cached segment instead\n\n# There is also a serial console on JP2, 3-5-6 = TX-RX-GND. 9600/8/N/1.\n\n# Possibly of note, this modem's ancient ethernet port does not support Auto-MDIX.\n\n# This modem in many ways appears to be essentially a clone of the SB5120. See usbjtag.com.\n# The firmware/OS is also susceptible to many of the same procedures in \"Hacking the Cable Modem\"\n# by DerEngel (Ryan Harris), available from No Starch Press.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kc705.cfg",
    "content": "# http://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html\n\nsource [find interface/ftdi/digilent-hs1.cfg]\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\nadapter speed 25000\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/kc705.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc7k325t.bit;\\\n# jtagspi_program bitstream-kc705.bin 0;\\\n# jtagspi_program bios.bin 0xaf0000;\\\n# jtagspi_program runtime.fbi 0xb00000;\\\n# xc7_program xc7.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kcu105.cfg",
    "content": "# xilinx ultrascale\n# http://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/keil_mcb1700.cfg",
    "content": "#\n# Keil MCB1700 eval board\n#\n# http://www.keil.com/mcb1700/picture.asp\n#\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/keil_mcb2140.cfg",
    "content": "#\n# Keil MCB2140 eval board\n#\n# http://www.keil.com/mcb2140/picture.asp\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kindle2.cfg",
    "content": "# Board configuration file for Amazon Kindle Model No. D00701 and D00801\n# AKA Kindle 2nd generation and Kindle DX\n# using a Freescale MCIMX31LDVKN5D i.MX31 processor\n#\n# Pins at J9 40-Pin FFC-A:\n#  1 - GND\n# 16 - TRSTB\n# 17 - TDI\n# 18 - TMS\n# 19 - TCK\n# 20 - RTCK\n# 21 - TDO\n# 22 - DE\n# 25 - BOOT_MODE4\n# 27 - BOOT_MODE2\n\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n\n$_TARGETNAME configure -event reset-init { kindle2_init }\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n# 8MiB NOR Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xa0000000 0x800000 2 2 $_TARGETNAME\n\n# 16kiB internal SRAM\n$_TARGETNAME configure -work-area-phys 0x1fffc000 \\\n\t-work-area-size 0x4000 -work-area-backup 0\n\n# FIXME: currently SRST is not wired to the system\nreset_config trst_only\njtag_ntrst_assert_width 10\njtag_ntrst_delay 30\n\n# this is broken but enabled by default\narm11 memwrite burst disable\n\nadapter speed 1000\nftdi tdo_sample_edge falling\n\nproc kindle2_init {} {\n\timx3x_reset\n\tkindle2_clock_setup\n\tdisable_mmu_and_cache\n\tkindle2_misc_init\n\tkindle2_sdram_init\n\tarm core_state arm\n}\n\nproc kindle2_clock_setup {} {\n\t# CCMR: clock from FPM/CKIL\n\tmww 0x53f80000  0x074b0b7b\n\t# IPU_CONF\n\tmww 0x53fc0000  0x040\n\t# 398MHz\n\tmww 0x53f80004 0xff871650\n\tmww 0x53f80010 0x00331c23\n}\n\nproc kindle2_misc_init { } {\n\t# AIPS1\n\tmww 0x43f00040 0x0\n\tmww 0x43f00044 0x0\n\tmww 0x43f00048 0x0\n\tmww 0x43f0004c 0x0\n\tmww 0x43f00050 0x0\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\n\t# AIPS2\n\tmww 0x53f00040 0x0\n\tmww 0x53f00044 0x0\n\tmww 0x53f00048 0x0\n\tmww 0x53f0004c 0x0\n\tmww 0x53f00050 0x0\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000cc03\n\tmww 0xb8002004 0xa0330d01\n\tmww 0xb8002008 0x00220800\n}\n\nproc disable_mmu_and_cache {} {\n\t# Mode Supervisor, disable FIQ, IRQ and imprecise data aborts\n\treg cpsr 0x1d3\n\n\t# flush entire BTAC\n\tarm mcr 15 0 7 5 6 0\n\t# invalidate instruction and data cache\n\t# MCR CP15, 0, R1, C7, C7, 0\n\tarm mcr 15 0 7 7 0\n\n\t# clean and invalidate cache\n\tarm mcr 15 0 7 15 0\n\n\t# disable MMU and caches\n\tarm mcr 15 0 1 0 0 0\n\n\tarm mcr 15 0 15 2 4 0\n\n\t# invalidate TLBs\n\tarm mcr 15 0 8 7 0 0\n\n\t# Drain the write buffer\n\tarm mcr 15 0 7 10 4 0\n\n\t# start from AIPS 2GB region\n\tarm mcr 15 0 15 2 4 0x40000015\n}\n\nproc kindle2_sdram_init {} {\n\t#--------------------------------------------\n\t# Samsung K4X1G323PC-8GC3 32Mx32 Mobile DDR SDRAM\n\t#--------------------------------------------\n\t# SDCLK\n\tmww 0x43fac26c 0\n\n\t# CAS\n\tmww 0x43fac270 0\n\n\t# RAS\n\tmww 0x43fac274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43fac27c 0x1000\n\n\t# DQM3\n\tmww 0x43fac284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2dc)\n\tmww 0x43fac288 0\n\tmww 0x43fac28c 0\n\tmww 0x43fac290 0\n\tmww 0x43fac294 0\n\tmww 0x43fac298 0\n\tmww 0x43fac29c 0\n\tmww 0x43fac2a0 0\n\tmww 0x43fac2a4 0\n\tmww 0x43fac2a8 0\n\tmww 0x43fac2ac 0\n\tmww 0x43fac2b0 0\n\tmww 0x43fac2b4 0\n\tmww 0x43fac2b8 0\n\tmww 0x43fac2bc 0\n\tmww 0x43fac2c0 0\n\tmww 0x43fac2c4 0\n\tmww 0x43fac2c8 0\n\tmww 0x43fac2cc 0\n\tmww 0x43fac2d0 0\n\tmww 0x43fac2d4 0\n\tmww 0x43fac2d8 0\n\tmww 0x43fac2dc 0\n\n\t# ?\n\tmww 0xb8002000 0x00006602\n\tmww 0xb8002004 0x00000501\n\tmww 0xb8002008 0x00000000\n\n\t# LPDDR1 Initialization script\n\tmww 0xb8001010 0x00000002\n\tmww 0xb8001010 0x00000004\n\t# ESDCFG0: set timing parameters\n\tmww 0xb8001004 0x007fff7f\n\t# ESDCTL0: select Prechare-All mode\n\tmww 0xb8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\t# ESDCTL0: Auto Refresh\n\tmww 0xb8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\t# ESDCTL0: Load Mode Register\n\tmww 0xb8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\t# ESDCTL0: enable Auto-Refresh\n\tmww 0xb8001000 0x82226080\n\tmww 0x80000000 0xdeadbeef\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kontron_sl28.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Kontron SMARC-sAL28\n\ntransport select jtag\nreset_config srst_only srst_nogate\n\njtag newtap unknown0 tap -irlen 12\n\nset _CPUS 2\nsource [find target/ls1028a.cfg]\n\nsource [find tcl/cpld/altera-epm240.cfg]\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/kwikstik.cfg",
    "content": "#\n# Freescale KwikStik development board\n#\n\n#\n# JLINK interface is onboard\n#\nsource [find interface/jlink.cfg]\n\nsource [find target/k40.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/la_fonera-fon2200.cfg",
    "content": "source [find target/atheros_ar2315.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# LambdaConcept ECPIX-5\n# http://docs.lambdaconcept.com/ecpix-5/\n# Currently there are following board variants:\n# ECPIX-5 45F - LFE5UM5G-45F\n# ECPIX-5 85F - LFE5UM5G-85F\n#\n# This boards have two JTAG interfaces:\n# - CN4, micro USB port connected to FT2232HQ chip:\n#        ADBUS0 TCK\n#        ADBUS1 TDI\n#        ADBUS2 TDO\n#        ADBUS3 TMS\n#        BDBUS0 UART_TXD\n#        BDBUS1 UART_RXD\n#   This interface should be used with following config:\n#        interface/ftdi/lambdaconcept_ecpix-5.cfg\n# - CN3, 6 pin connector\n# See schematics for more details:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n#\n# No reset lines are implemented. So it is not possible to remote reset the FPGA\n# by using any of this interfaces\n\nsource [find interface/ftdi/lambdaconcept_ecpix-5.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lemaker_hikey.cfg",
    "content": "#\n# board configuration for LeMaker Hikey\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi6220.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/linksys-wag200g.cfg",
    "content": "#\n# Linksys WAG200G Router\n#\n# The stock firmware Flash layout is organized as follow:\n#\n#   Start       End         Device\n#   0x90000000  0x90020000  /dev/mtdblock/2\n#   0x90020000  0x900d0000  /dev/mtdblock/1\n#   0x900d0000  0x903a0000  /dev/mtdblock/0\n#   0x903a0000  0x903e0000  /dev/mtdblock/5\n#   0x903e0000  0x903f0000  /dev/mtdblock/3\n#   0x903f0000  0x90400000  /dev/mtdblock/4\n\nset partition_list {\n    adam2\t{ \"Adam2 bootloader\"\t\t0x90000000 0x00020000 }\n    kernel\t{ \"Kernel\"\t\t\t0x90020000 0x000b0000 }\n    rootfs\t{ \"Root FS\"\t\t\t0x900d0000 0x002d0000 }\n    lang\t{ \"Minix language part\"\t\t0x903a0000 0x00040000 }\n    config\t{ \"Firmware config\"\t\t0x903e0000 0x00010000 }\n    adam2env\t{ \"Adam2 environment\"\t\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 4MB MXIC 29LV320MBTC Flash (Manufacturer/Device: 0x00c2 0x227e)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/linksys-wrt54gl.cfg",
    "content": "#\n# Linksys WRT54GL v1.1\n#\n\nsource [find target/bcm5352e.cfg]\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0x1c000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x1c040000 0x003b0000 }\n    nvram\t{ \"Config space\"\t\t0x1c3f0000 0x00010000 }\n}\n\n# External 4MB NOR Flash (Intel TE28F320C3BD90 or similar)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x1c000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/linksys_nslu2.cfg",
    "content": "# This is for the LinkSys (CISCO) NSLU2 board\n# It is an Intel XSCALE IXP420 CPU.\n\nsource [find target/ixp42x.cfg]\n# The _TARGETNAME is set by the above.\n\n$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lisa-l.cfg",
    "content": "# the Lost Illusions Serendipitous Autopilot\n# http://paparazzi.enac.fr/wiki/Lisa\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/logicpd_imx27.cfg",
    "content": "# The LogicPD Eval IMX27 eval board has a single IMX27 chip\nsource [find target/imx27.cfg]\n\n# The Logic PD board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\n#\n# FIX ME, Add support to\n#\n# (A) hard reset the board.\n# (B) Initialize the SDRAM on the board\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lpc1850_spifi_generic.cfg",
    "content": "#\n# Generic LPC1850 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC1850 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc1850\n\nsource [find target/lpc1850.cfg]\n\n#A large working area greatly reduces flash write times\nset _WORKAREASIZE 0x4000\n\n$_CHIPNAME.m3 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lpc4350_spifi_generic.cfg",
    "content": "#\n# Generic LPC4350 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC4350 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/lubbock.cfg",
    "content": "# Intel \"Lubbock\" Development Board with PXA255 (dbpxa255)\n#  Obsolete; this was Intel's original PXA255 development system\n#  Board also had CPU cards for SA1100, PXA210, PXA250, and more.\n\nsource [find target/pxa255.cfg]\n\nadapter srst delay 250\njtag_ntrst_delay 250\n\n# NOTE: until after pinmux and such are set up, only CS0 is\n# available ... not 2nd bank of CFI, or FPGA, SRAM, ENET, etc.\n\n# CS0, CS1 -- two banks of CFI flash, 32 MBytes each\n# each bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME cfi 0x04000000 0x02000000 2 4 $_TARGETNAME\n\n# CS2 low -- FPGA registers\n# CS2 high -- 1 MByte SRAM at 0x0a00.0000 ... last 64K for scratch\n$_TARGETNAME configure -work-area-phys 0x0a0f0000\n\n$_TARGETNAME configure -event reset-assert-pre \\\n\t\"$_TARGETNAME configure -work-area-size 0\"\n\n# Make the hex led display a number, assuming CS2 is set up\n# and all digits have been enabled through the FPGA.\nproc hexled {u32} {\n\tmww 0x08000010 $u32\n}\n\n# CS3 -- Ethernet\n# CS4 -- SA1111\n# CS5 -- PCMCIA\n\n# NOTE:  system console normally uses the FF UART connector\n\nproc lubbock_init {target} {\n\n\techo \"Initialize PXA255 Lubbock board\"\n\n\t# (1) pinmux\n\n\t# GPSR0..GPSR2\n\tmww 0x40e00018 0x00008000\n\tmww 0x40e0001c 0x00FC0382\n\tmww 0x40e00020 0x0001FFFF\n\t# GPDR0..GPDR2\n\tmww 0x40e0000c 0x0060A800\n\tmww 0x40e00010 0x00FF0382\n\tmww 0x40e00014 0x0001C000\n\t# GAFR0_[LU]..GAFR2_[LU]\n\tmww 0x40e00054 0x98400000\n\tmww 0x40e00058 0x00002950\n\tmww 0x40e0005c 0x000A9558\n\tmww 0x40e00060 0x0005AAAA\n\tmww 0x40e00064 0xA0000000\n\tmww 0x40e00068 0x00000002\n\n\t# write PSSR, enable GPIOs\n\tmww 0x40f00000 0x00000020\n\n\t# write LED ctrl register ... ones disable\n\t# high byte, 8 hex leds; low byte, 8 discretes\n\tmwh 0x08000040 0xf0ff\n\n\thexled 0x0000\n\n\t# (2) Address space setup\n\n\t# MSC0/MSC1/MSC2\n\tmww 0x48000008 0x23f223f2\n\tmww 0x4800000c 0x3ff1a441\n\tmww 0x48000010 0x7ff97ff1\n\t# pcmcia/cf\n\tmww 0x48000014 0x00000000\n\tmww 0x48000028 0x00010504\n\tmww 0x4800002c 0x00010504\n\tmww 0x48000030 0x00010504\n\tmww 0x48000034 0x00010504\n\tmww 0x48000038 0x00004715\n\tmww 0x4800003c 0x00004715\n\n\thexled 0x1111\n\n\t# (3) SDRAM setup\n\t# REVISIT this looks dubious ... no refresh cycles\n\tmww 0x48000004 0x03CA4018\n\tmww 0x48000004 0x004B4018\n\tmww 0x48000004 0x000B4018\n\tmww 0x48000004 0x000BC018\n\tmww 0x48000000 0x00001AC8\n\tmww 0x48000000 0x00001AC9\n\n\tmww 0x48000040 0x00000000\n\n\t# FIXME -- setup:\n\t#  CLOCKS (and faster JTAG)\n\t#  enable icache\n\n\t# FIXME SRAM isn't working\n\t# $target configure -work-area-size 0x10000\n\n\thexled 0x2222\n\n\tflash probe 0\n\tflash probe 1\n\n\thexled 0xcafe\n}\n$_TARGETNAME configure -event reset-init \"lubbock_init $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/marsohod.cfg",
    "content": "#\n# Marsohod CPLD Development and Education board\n#\n# http://marsohod.org/howtostart/plata\n#\n\n# Recommended MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Altera MAXII EPM240T100C CPLD\nsource [find cpld/altera-epm240.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/marsohod2.cfg",
    "content": "#\n# Marsohod2 FPGA Development and Education board\n#\n# http://www.marsohod.org/prodmarsohod2\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Cyclone III EP3C10E144 FPGA\nsource [find fpga/altera-ep3c10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/marsohod3.cfg",
    "content": "#\n# Marsohod3 FPGA Development and Education board\n#\n# http://www.marsohod.org/plata-marsokhod3\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# MAX10 10M50SAE144C8GES FPGA\nsource [find fpga/altera-10m50.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/mbed-lpc11u24.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC11U24 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC11U24\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# NXP LPC11U24 Cortex-M0 with 32kB Flash and 8kB SRAM\nset WORKAREASIZE 0x2000\n\nsource [find target/lpc11xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/mbed-lpc1768.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC1768 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC1768\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/mcb1700.cfg",
    "content": "# Keil MCB1700 PCB with 1768\n#\n# Reset init script sets it to 100MHz\nset CCLK 100000\n\nsource [find target/lpc17xx.cfg]\n\nglobal MCB1700_CCLK\nset MCB1700_CCLK $CCLK\n\n$_TARGETNAME configure -event reset-start {\n\t# Start *real slow* as we do not know the\n    # state the boot rom left the clock in\n\tadapter speed 10\n}\n\n# Set up 100MHz clock to CPU\n$_TARGETNAME configure -event reset-init {\n    # PLL0CON: Disable PLL\n\tmww 0x400FC080 0x00000000\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n    # CCLK=PLL/4 (=100 MHz)\n\tmww 0x400FC104 0x00000003\n    # CLKSRCSEL: Clock source = internal RC oscillator\n\tmww 0x400FC10C 0x00000000\n\n    # PLL0CFG: M=50,N=1 -> PLL=400 MHz\n\tmww 0x400FC084 0x00000031\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# PLL0CON: Enable PLL\n\tmww 0x400FC080 0x00000001\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\tsleep 50\n\n    # PLL0CON: Connect PLL\n\tmww 0x400FC080 0x00000003\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# Dividing CPU clock by 8 should be pretty conservative\n\t#\n\t#\n\tglobal MCB1700_CCLK\n\tadapter speed [expr {$MCB1700_CCLK / 8}]\n\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\n\tmww 0x400FC040 0x01\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/microchip_explorer16.cfg",
    "content": "# Microchip Explorer 16 with PIC32MX360F512L PIM module.\n# http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858\n\n# TAPID for PIC32MX360F512L\nset CPUTAPID 0x30938053\n\n# use 32k working area\nset WORKAREASIZE 32768\n\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/microchip_sama5d27_som1_kit1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAMA5D27-SOM1-EK1\n# https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATSAMA5D27-SOM1-EK1\n# This board provide two jtag interfaces:\n# J11 - 10 pin interface\n# J10 - USB interface connected to the J-Link-OB.\n#       This functionality is implemented with an ATSAM3U4C microcontroller and\n#       provides JTAG functions and a bridge USB/Serial debug port (CDC).\n#\n# Jumper J7 disables the J-Link-OB-ATSAM3U4C JTAG functionality.\n# - Jumper J7 not installed: J-Link-OB-ATSAM3U4C is enabled and fully functional.\n# - Jumper J7 installed: J-Link-OB-ATSAM3U4C is disabled and an external JTAG\n#   controller can be used through the 10-pin JTAG port J11.\n\nsource [find interface/jlink.cfg]\nreset_config srst_only\n\nsource [find target/at91sama5d2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/microchip_same51_curiosity_nano.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAME51 Curiosity Nano evaluation kit.\n#\n# https://www.microchip.com/en-us/development-tool/EV76S68A\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same51\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/microchip_same54_xplained_pro.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54 Xplained Pro evaluation kit.\n# http://www.microchip.com/developmenttools/productdetails.aspx?partno=atsame54-xpro\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same54\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/microchip_saml11_xplained_pro.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L11 Xplained Pro Evaluation Kit.\n# https://www.microchip.com/DevelopmentTools/ProductDetails/dm320205\n#\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 1000\n\nset CHIPNAME saml11\nsource [find target/atsaml1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/mini2440.cfg",
    "content": "#-------------------------------------------------------------------------\n# Mini2440 Samsung s3c2440A Processor with 64MB DRAM, 64MB NAND, 2 MB N0R\n# NOTE: Configured for NAND boot (switch S2 in NANDBOOT)\n# 64 MB NAND (Samsung K9D1208V0M)\n# B Findlay  08/09\n#\n#   ----------- Important notes to help you on your way ----------\n# README:\n#     NOR/NAND Boot Switch - I have not read the vivi source, but from\n#     what I could tell from reading the registers it appears that vivi\n#     loads itself into DRAM and then flips NFCONT (0x4E000004) bits\n#     Mode (bit 0 = 1), and REG_nCE (bit 1 = 0) which maps the NAND\n#     FLASH at the bottom 64MB of memory. This essentially takes the\n#     NOR Flash out of the circuit so you can't trash it.\n#\n#     I adapted the samsung_s3c2440.cfg file which is why I did not\n#     include \"source [find target/samsung_s3c2440.cfg]\".  I believe\n#     the -work-area-phys 0x200000 is incorrect, but also had to pad\n#     some additional resets.  I didn't modify it as if it is working\n#     for someone, the work-area-phys is not used by most.\n#\n#     JTAG ADAPTER SPECIFIC\n#     IMPORTANT! Any JTAG device that uses ADAPTIVE CLOCKING will likely\n#     FAIL as the pin RTCK on the mini2440 10 pin JTAG Conn doesn't exist.\n#     This is Pin 11 (RTCK) on 20 pin JTAG connector. Therefore it is\n#     necessary to FORCE setting the clock. Normally this should be configured\n#     in the openocd.cfg file, but was placed here as it can be a tough\n#     problem to figure out.  THIS MAY NOT FIX YOUR PROBLEM.. I modified\n#     the openOCD driver jlink.c and posted it here. It may eventually end\n#     up changed in openOCD, but its a hack in the driver and really should\n#     be in the jtag layer (core.c me thinks), but haven't done it yet. My\n#     hack for jlink.c may be found here.\n#\n#     http://forum.sparkfun.com/viewtopic.php?t=16763&sid=946e65abdd3bab39cc7d90dee33ff135\n#\n#     Note: Also if you have a USB JTAG, you will need the USB library installed\n#     on your system \"libusb-dev\" or the make of openocd will fail. I *think*\n#     it's apt-get install libusb-dev.  When I made my config I only included\n#     --enable-jlink and --enable-usbdevs\n#\n#     I HAVE NOT Tested this thoroughly, so there could still be problems.\n#     But it should get you way ahead of the game from where I started.\n#     If you find problems (and fixes) please post them to\n#     openocd-development@lists.berlios.de and join the developers and\n#     check in fixes to this and anything else you find.  I do not\n#     provide support, but if you ask really nice and I see anything\n#     obvious I will tell you.. mostly just dig, fix, and submit to openocd.\n#\n#     best!   brfindla@yahoo.com   Nashua, NH USA\n#\n#     Recommended resources:\n#       - first two are the best Mini2440 resources anywhere\n#       - maintained by buserror... thanks guy!\n#\n#       http://bliterness.blogspot.com/\n#       http://code.google.com/p/mini2440/\n#\n#       others....\n#\n#       http://forum.sparkfun.com/viewforum.php?f=18\n#       http://labs.kernelconcepts.de/Publications/Micro24401/\n#       http://www.friendlyarm.net/home\n#       http://www.amontec.com/jtag_pinout.shtml\n#\n#-------------------------------------------------------------------------\n#\n#\n# Your openocd.cfg file should contain:\n# source [find interface/<yourjtag>.cfg]\n# source [find board/mini2440.cfg]\n#\n#\n#\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\n#-------------------------------------------------------------------------\n# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor : ARM920Tid(wb) rev 0 (v4l)\n# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d\n#  (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n#-------------------------------------------------------------------------\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x40000000  -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\n#-------------------------------------------------------------------------\n# JTAG ADAPTER SPECIFIC\n# IMPORTANT! See README at top of this file.\n#-------------------------------------------------------------------------\n\n    adapter speed 12000\n    jtag interface\n\n#-------------------------------------------------------------------------\n# GDB Setup\n#-------------------------------------------------------------------------\n\n    gdb_breakpoint_override hard\n\n#------------------------------------------------\n# ARM SPECIFIC\n#------------------------------------------------\n\n    targets\n  #  arm7_9 dcc_downloads enable\n  #  arm7_9 fast_memory_access enable\n\n\n    nand device s3c2440 0\n\n    adapter srst delay 100\n    jtag_ntrst_delay 100\n    reset_config trst_and_srst\n    init\n\n    echo \" \"\n    echo \"-------------------------------------------\"\n    echo \"--- login with - telnet localhost 4444  ---\"\n    echo \"--- then type help_2440                 ---\"\n    echo \"-------------------------------------------\"\n    echo \" \"\n\n\n\n#------------------------------------------------\n# Processor Initialialization\n# Note: Processor writes can only occur when\n# the state is in SYSTEM. When you call init_2440\n# one of the first lines will tell you what state\n# you are in. If a linux image is booting\n# when you run this, it will not work\n# a vivi boot loader will run with this just\n# fine. The reg values were obtained by a combination\n# of figuring them out fromt the manual, and looking\n# at post vivi values with the debugger. Don't\n# place too much faith in them, but seem to work.\n#------------------------------------------------\n\nproc init_2440 { } {\n\n    halt\n    s3c2440.cpu curstate\n\n    #-----------------------------------------------\n    # Set Processor Clocks - mini2440 xtal=12mHz\n    # we set main clock for 405mHZ\n    # we set the USB Clock for 48mHz\n    # OM2 OM3 pulled to ground so main clock and\n    # usb clock are off 12mHz xtal\n    #-----------------------------------------------\n\n    mww phys 0x4C000014 0x00000005 ;#  Clock Divider control Reg\n    mww phys 0x4C000000 0xFFFFFFFF ;#  LOCKTIME count register\n    mww phys 0x4C000008 0x00038022 ;#  UPPLCON  USB clock config Reg\n    mww phys 0x4C000004 0x0007F021 ;#  MPPLCON  Proc clock config Reg\n\n    #-----------------------------------------------\n    # Configure Memory controller\n    # BWSCON configures all banks, NAND, NOR, DRAM\n    # DRAM - 64MB - 32 bit bus, uses BANKCON6 BANKCON7\n    #-----------------------------------------------\n\n    mww phys 0x48000000 0x22111112 ;#  BWSCON - Bank and Bus Width\n    mww phys 0x48000010 0x00001112 ;#  BANKCON4 - ?\n    mww phys 0x4800001c 0x00018009 ;#  BANKCON6 - DRAM\n    mww phys 0x48000020 0x00018009 ;#  BANKCON7 - DRAM\n    mww phys 0x48000024 0x008E04EB ;#  REFRESH  - DRAM\n    mww phys 0x48000028 0x000000B2 ;#  BANKSIZE - DRAM\n    mww phys 0x4800002C 0x00000030 ;#  MRSRB6 - DRAM\n    mww phys 0x48000030 0x00000030 ;#  MRSRB7 - DRAM\n\n    #-----------------------------------------------\n    # Now port configuration for enables for memory\n    # and other stuff.\n    #-----------------------------------------------\n\n    mww phys 0x56000000\t0x007FFFFF ;#  GPACON\n\n    mww phys 0x56000010\t0x00295559 ;#  GPBCON\n    mww phys 0x56000018\t0x000003FF ;#  GPBUP (PULLUP ENABLE)\n    mww phys 0x56000014\t0x000007C2 ;#  GPBDAT\n\n    mww phys 0x56000020\t0xAAAAA6AA ;#  GPCCON\n    mww phys 0x56000028\t0x0000FFFF ;#  GPCUP\n    mww phys 0x56000024\t0x00000020 ;#  GPCDAT\n\n    mww phys 0x56000030\t0xAAAAAAAA ;#  GPDCON\n    mww phys 0x56000038\t0x0000FFFF ;#  GPDUP\n\n    mww phys 0x56000040\t0xAAAAAAAA ;#  GPECON\n    mww phys 0x56000048\t0x0000FFFF ;#  GPEUP\n\n    mww phys 0x56000050\t0x00001555 ;#  GPFCON\n    mww phys 0x56000058\t0x0000007F ;#  GPFUP\n    mww phys 0x56000054\t0x00000000 ;#  GPFDAT\n\n    mww phys 0x56000060\t0x00150114 ;#  GPGCON\n    mww phys 0x56000068\t0x0000007F ;#  GPGUP\n\n    mww phys 0x56000070\t0x0015AAAA ;#  GPHCON\n    mww phys 0x56000078\t0x000003FF ;#  GPGUP\n\n}\n\n\n\nproc flash_config { } {\n\n    #-----------------------------------------\n    # Finish Flash Configuration\n    #-----------------------------------------\n\n    halt\n\n    #flash configuration (K9D1208V0M: 512Mbit, x8, 3.3V, Mode: Normal, 1st gen)\n    nand probe 0\n    nand list\n}\n\nproc flash_uboot { } {\n\n\t# flash the u-Boot binary and reboot into it\n\tinit_2440\n\tflash_config\n\tnand erase 0 0x0 0x40000\n\tnand write 0 /tftpboot/u-boot-nand512.bin 0 oob_softecc_kw\n\tresume\n}\n\n\nproc load_uboot { } {\n        echo \" \"\n        echo \" \"\n        echo \"----------------------------------------------------------\"\n        echo \"---- Load U-Boot into RAM and execute it.              ---\"\n        echo \"---- NOTE: loads, partially runs, and hangs            ---\"\n        echo \"---- U-Boot is fine, this image runs from vivi.        ---\"\n        echo \"---- I burned u-boot into NAND so I didn't finish      ---\"\n        echo \"---- debugging it. I am leaving this here as it is     ---\"\n        echo \"---- part of the way there if you want to fix it.      ---\"\n        echo \"----                                                   ---\"\n        echo \"---- mini2440 U-boot here:                             ---\"\n        echo \"---- http://repo.or.cz/w/u-boot-openmoko/mini2440.git  ---\"\n        echo \"---- Also this:                                        ---\"\n        echo \"---- http://code.google.com/p/mini2440/wiki/MiniBringup --\"\n        echo \"----------------------------------------------------------\"\n\n\tinit_2440\n\techo \"Loading /tftpboot/u-boot-nand512.bin\"\n\tload_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"Verifying image....\"\n\tverify_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"jumping to u-boot\"\n        #bp 0x33f80068 4 hw\n        reg 0 0\n        reg 1 0\n        reg 2 0\n        reg 3 0\n        reg 4 0x33f80000\n      \tresume 0x33f80000\n}\n\n       # this may help a little bit debugging the load_uboot\nproc s {} {\n        step\n        reg\n        arm disassemble 0x33F80068 0x10\n}\n\nproc help_2440 {} {\n    echo \" \"\n    echo \" \"\n    echo \"-----------------------------------------------------------\"\n    echo \"---- The following mini2440 funcs are supported        ----\"\n    echo \"----   init_2440 - initialize clocks, DRAM, IO         ----\"\n    echo \"----   flash_config - configures nand flash            ----\"\n    echo \"----   load_uboot - loads uboot into ram               ----\"\n    echo \"----   flash_uboot - flashes uboot to nand (untested)  ----\"\n    echo \"----   help_2440 - this help display                   ----\"\n    echo \"-----------------------------------------------------------\"\n    echo \" \"\n    echo \" \"\n}\n\n\n#----------------------------------------------------------------------------\n#----------------------------------- END ------------------------------------\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/mini6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a tiny6410\n# Processor       : ARM1176\n# Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2)\n# Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787, part: 0x7b76, ver: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nproc init_6410 {} {\n\thalt\n\treg cpsr 0x1D3\n\tarm mcr 15 0 15 2 4 0x70000013\n\n\t#-----------------------------------------------\n\t# Clock and Timer Setting\n\t#-----------------------------------------------\n\tmww 0x7e004000 0\t\t;# WATCHDOG \t- Disable\n\tmww 0x7E00F120 0x0003\t\t;# MEM_SYS_CFG\t- CS0:8 bit, Mem1:32bit, CS2=NAND\n\t#mww 0x7E00F120 0x1000\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=SROMC\n\t#mww 0x7E00F120 0x1002\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=OND\n\tmww 0x7E00F900 0x805e\t\t;# OTHERS\t- Change SYNCMUX[6] to “1”\n\tsleep 1000\n\tmww 0x7E00F900 0x80de\t\t;# OTHERS\t- Assert SYNCREQ&VICSYNCEN to “1”(rb1004modify)\n\tsleep 1000\t\t\t;#\t\t- Others[11:8] to 0xF\n\tmww 0x7E00F000 0xffff\t\t;# APLL_LOCK\t- APLL LockTime\n\tmww 0x7E00F004 0xffff\t\t;# MPLL_LOCK\t- MPLL LockTime\n\tmww 0x7E00F020 0x1047310\t;# CLK_DIV0 \t- ARMCLK:HCLK:PCLK = 1:4:16\n\tmww 0x7E00F00c 0x81900302\t;# APLL_CON \t- A:400, P:3, S:2 => 400MHz\n\tmww 0x7E00F010 0x81900303\t;# MPLL_CON \t- M:400, P:3, S:3 => 200MHz\n\tmww 0x7E00F01c 0x3\t\t;# CLK_SRC \t- APLL,MPLL Clock Select\n\n\t#-----------------------------------------------\n\t# DRAM initialization\n\t#-----------------------------------------------\n\tmww 0x7e001004 0x4\t\t;# P1MEMCCMD\t- Enter the config state\n\tmww 0x7e001010 0x30C\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 100MHz\n#\tmww 0x7e001010 0x40e\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 133MHz\n\tmww 0x7e001014 0x6\t\t;# P1CASLAT\t- CAS Latency = 3\n\tmww 0x7e001018 0x1\t\t;# P1T_DQSS\n\tmww 0x7e00101c 0x2\t\t;# P1T_MRD\n\tmww 0x7e001020 0x7\t\t;# P1T_RAS\t- 45 ns\n\tmww 0x7e001024 0xA\t\t;# P1T_RC\t- 67.5 ns\n\tmww 0x7e001028 0xC\t\t;# P1T_RCD\t- 22.5 ns\n\tmww 0x7e00102C 0x10B\t\t;# P1T_RFC\t- 80 ns\n\tmww 0x7e001030 0xC\t\t;# P1T_RP\t- 22.5 ns\n\tmww 0x7e001034 0x3\t\t;# P1T_RRD\t- 15 ns\n\tmww 0x7e001038 0x3\t\t;# P1T_WR\t- 15 ns\n\tmww 0x7e00103C 0x2\t\t;# P1T_WTR\n\tmww 0x7e001040 0x2\t\t;# P1T_XP\n\tmww 0x7e001044 0x11\t\t;# P1T_XSR\t- 120 ns\n\tmww 0x7e001048 0x11\t\t;# P1T_ESR\n\n\t#-----------------------------------------------\n\t# Memory Configuration Registers\n\t#-----------------------------------------------\n\tmww 0x7e00100C 0x00010012 \t;# P1MEMCFG\t- 1 CKE, 1Chip, 4burst, Alw, AP[10],ROW/Column bit\n\tmww 0x7e00104C 0x0B41 \t\t;# P1MEMCFG2\t- Read delay 1 Cycle, mDDR, 32bit, Sync.\n\tmww 0x7e001200 0x150F0 \t\t;# CHIP_N_CFG\t- 0x150F0 for 256M, 0x150F8 for 128M\n\n\t#-----------------------------------------------\n\t# Memory Direct Commands\n\t#-----------------------------------------------\n\tmww 0x7e001008 0xc0000\t\t;# Chip0 Direct Command :NOP5\n\tmww 0x7e001008 0x0\t\t;# Chip0 Direct Command :PreCharge al\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0xA0000\t\t;# EMRS, DS:Full, PASR:Full\n\tmww 0x7e001008 0x80032\t\t;# MRS, CAS3, BL4\n\tmww 0x7e001004 0x0\t\t;# Enable DMC1\n}\n\nproc install_6410_uboot {} {\n\t# write U-boot magic number\n\tmww 0x50000000 0x24564236\n\tmww 0x50000004 0x20764316\n\tload_image u-boot_nand-ram256.bin 0x50008000 bin\n\tload_image u-boot_nand-ram256.bin 0x57E00000 bin\n\n\t#Kick in\n\treg pc 0x57E00000\n\tresume\n}\n\nproc init_6410_flash {} {\n\thalt\n\tnand probe 0\n\tnand list\n}\n\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\ngdb_breakpoint_override hard\n\ntargets\nnand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu\n\ninit\necho \" \"\necho \" \"\necho \"-------------------------------------------------------------------\"\necho \"---- The following mini6410/tiny6410 functions are available:  ----\"\necho \"----   init_6410 - initialize clock, timer, DRAM               ----\"\necho \"----   init_6410_flash - initializes NAND flash support        ----\"\necho \"----   install_6410_uboot - copies u-boot image into RAM and   ----\"\necho \"----                        runs it                            ----\"\necho \"-------------------------------------------------------------------\"\necho \" \"\necho \" \"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n\nsource [find interface/ftdi/minispartan6.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to read the device dna of the FPGA on the board;\n# openocd -f board/minispartan6.cfg -c \"init;xc6s_print_dna xc6s.tap;shutdown\"\n\n# example command to write bitstream\n# openocd -f board/minispartan6.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx??.bit;\\\n# jtagspi_program bitstream.bin 0;\\\n# xc6s_program xc6s.tap;\\\n# shutdown\"\n#\n# jtagspi flash procies can be found in the contrib/loaders/flash/fpga/\n# directory, with prebuilt versions available at\n# https://github.com/jordens/bscan_spi_bitstreams\n#\n# For the SLX25 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx25.bit\n# For the SLX9 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx9.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nds32_corvettef1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-Corvette-F1 R1.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r1/\n# ADP-Corvette-F1 R2.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r2/\n\nadapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nreset_config srst_only\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nds32_xc5.cfg",
    "content": "set _CPUTAPID 0x1000063d\nset _CHIPNAME nds32\nsource [find target/nds32v3.cfg]\n\njtag init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nds32_xc7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-XC7K160/410\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/adp-xc7k160-410/\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/netgear-dg834v3.cfg",
    "content": "#\n# Netgear DG834v3 Router\n# Internal 4Kb RAM (@0x80000000)\n# Flash is located at 0x90000000 (CS0) and RAM is located at 0x94000000 (CS1)\n#\n\nset partition_list {\n    loader\t{ \"Bootloader (ADAM2)\"\t\t0x90000000 0x00020000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x90020000 0x003d0000 }\n    config\t{ \"Bootloader config space\"\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 16MB SDRAM - disabled as we use internal sram\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n\n# External 4MB NOR Flash\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/netgear-wg102.cfg",
    "content": "source [find target/atheros_ar2313.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\tmips32 cp0 12 0 0x10400000\n\n\t# configure sdram controller\n\tmww 0xb8300004 0x0e03\n\tsleep 100\n\tmww 0xb8300004 0x0e01\n\tmww 0xb8300008 0x10\n\tsleep 500\n\tmww 0xb8300004 0x0e02\n\n\tmww 0xb8300000 0x6c0088\n\tmww 0xb8300008 0x57e\n\tmww 0xb8300004 0x0e00\n\tmww 0xb8300004 0xb00\n\n\t# configure flash\n\t#                 0x00000001 - 0x01 << FLASHCTL_IDCY_S\n\t#                 0x000000e0 - 0x07 << FLASHCTL_WST1_S\n\t# FLASHCTL_RBLE   0x00000400 - Read byte lane enable\n\t#                 0x00003800 - 0x07 << FLASHCTL_WST2_S\n\t# FLASHCTL_AC_8M  0x00060000 - Size of flash\n\t# FLASHCTL_E      0x00080000 - Flash bank enable (added)\n\t# FLASHCTL_WP     0x04000000 - write protect. If used, CFI mode wont work!!\n\t# FLASHCTL_MWx16  0x10000000 - 16bit mode. Do not use it!!\n\t# FLASHCTL_MWx8   0x00000000 - 8bit mode.\n\tmww 0xb8400000 0x000d3ce1\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbe000000 0x00400000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nordic_nrf51822_mkit.cfg",
    "content": "#\n# Nordic Semiconductor PCA10024 board (aka nRF51822-mKIT)\n#\n\nsource [find interface/cmsis-dap.cfg]\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nordic_nrf51_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF51 Development Kit (nRF6824)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nordic_nrf52_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF52 Development Kit (nRF52832)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nordic_nrf52_ftx232.cfg",
    "content": "#\n# nordic module NRF52 (nRF52832/52840) attached to an adafruit ft232h module\n# or any FT232H/FT2232H/FT4232H based board/module\n#\n\nsource [find interface/ftdi/ft232h-module-swd.cfg]\n#source [find interface/ftdi/minimodule-swd.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/novena-internal-fpga.cfg",
    "content": "#\n# Novena open hardware and F/OSS-friendly computing platform\n#\n# Design documentation:\n# http://www.kosagi.com/w/index.php?title=Novena_PVT_Design_Source\n#\n# +-------------+--------------+------+-------+---------+\n# | Pad name    | Schematic    | GPIO | sysfs | JTAG    |\n# +-------------+--------------+------+-------+---------+\n# | DISP0_DAT13 | FPGA_RESET_N | 5-07 |  135  | RESET_N |\n# | DISP0_DAT14 | FPGA_TCK     | 5-08 |  136  | TCK     |\n# | DISP0_DAT15 | FPGA_TDI     | 5-09 |  137  | TDI     |\n# | DISP0_DAT16 | FPGA_TDO     | 5-10 |  138  | TDO     |\n# | DISP0_DAT17 | FPGA_TMS     | 5-11 |  139  | TMS     |\n# +-------------+--------------+------+-------+---------+\n\nadapter driver sysfsgpio\n\ntransport select jtag\n\n# TCK TMS TDI TDO\nsysfsgpio jtag_nums 136 139 137 138\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/npcx_evb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Nuvoton NPCX Evaluation Board\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\nsource [find target/npcx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/numato_mimas_a7.cfg",
    "content": "#\n# Numato Mimas A7 - Artix 7 FPGA Board\n#\n# https://numato.com/product/mimas-a7-artix-7-fpga-development-board-with-ddr-sdram-and-gigabit-ethernet\n#\n# Note: Connect external DC power supply if programming a heavy design onto FPGA.\n#       Programming while powering via USB may lead to programming failure.\n#       Therefore, prefer external power supply.\n\nadapter driver ftdi\nftdi device_desc \"Mimas Artix 7 FPGA Module\"\nftdi vid_pid 0x2a19 0x1009\n\n# channel 0 is for custom purpose by users (like uart, fifo etc)\n# channel 1 is reserved for JTAG (by-default) or SPI (possible via changing solder jumpers)\nftdi channel 1\nftdi tdo_sample_edge falling\n\n\n# FTDI Pin Layout\n#\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | DBUS7  | DBUS6 | DBUS5 | DBUS4 | DBUS3 | DBUS2 | DBUS1 | DBUS0 |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | PROG_B | OE_N  |  NC   |  NC   |  TMS  |  TDO  |  TDI  |  TCK  |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n#\n# OE_N is JTAG buffer output enable signal (active-low)\n# PROG_B is not used, so left as input to FTDI.\n#\nftdi layout_init 0x0008 0x004b\nreset_config none\nadapter speed 30000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/numato_opsis.cfg",
    "content": "# http://opsis.hdmi2usb.tv\n#\n# The Numato Opsis is an FPGA based, open video platform.\n#\n# The board is supported via ixo-usb-jtag project. See the\n# interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_frdm-k64f.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an NXP Freedom eval board with a single MK64FN1M0VLL12 chip.\n# https://www.nxp.com/design/development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# Set working area to 16 KiB\nset WORKAREASIZE 0x4000\n\nset CHIPNAME k64f\nreset_config srst_only\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_frdm-ls1012a.cfg",
    "content": "#\n# NXP FRDM-LS1012A (Freedom)\n#\n\n#\n# NXP Kinetis K20\n#\nsource [find interface/cmsis-dap.cfg]\ntransport select jtag\n\n# Also offers a 10-pin 0.05\" CoreSight JTAG connector.\n\nsource [find target/ls1012a.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_imx7sabre.cfg",
    "content": "# NXP IMX7SABRE board\n# use on-board JTAG header\ntransport select jtag\n\n# set a safe speed, can be overridden\nadapter speed 1000\n\n# reset configuration has TRST and SRST support\nreset_config trst_and_srst srst_push_pull\n# need at least 100ms delay after SRST release for JTAG\nadapter srst delay 100\n\n# source the target file\nsource [find target/imx7.cfg]\n# import mrw proc\nsource [find mem_helper.tcl]\n\n# function to disable the on-chip watchdog\nproc imx7_disable_wdog { } {\n        # echo \"disable watchdog power-down counter\"\n        mwh phys 0x30280008 0x00\n}\n\nproc imx7_uart_dbgconf { } {\n\t# disable response to debug_req signal for uart1\n\tmww phys 0x308600b4 0x0a60\n}\n\nproc check_bits_set_32 { addr mask } {\n    while { [expr {[mrw $addr] & $mask} == 0] } { }\n}\n\nproc apply_dcd { } {\n    # echo \"apply dcd\"\n\n    mww phys 0x30340004 0x4F400005\n    # Clear then set bit30 to ensure exit from DDR retention\n    mww phys 0x30360388 0x40000000\n    mww phys 0x30360384 0x40000000\n\n    mww phys 0x30391000 0x00000002\n    mww phys 0x307a0000 0x01040001\n    mww phys 0x307a01a0 0x80400003\n    mww phys 0x307a01a4 0x00100020\n    mww phys 0x307a01a8 0x80100004\n    mww phys 0x307a0064 0x00400046\n    mww phys 0x307a0490 0x00000001\n    mww phys 0x307a00d0 0x00020083\n    mww phys 0x307a00d4 0x00690000\n    mww phys 0x307a00dc 0x09300004\n    mww phys 0x307a00e0 0x04080000\n    mww phys 0x307a00e4 0x00100004\n    mww phys 0x307a00f4 0x0000033f\n    mww phys 0x307a0100 0x09081109\n    mww phys 0x307a0104 0x0007020d\n    mww phys 0x307a0108 0x03040407\n    mww phys 0x307a010c 0x00002006\n    mww phys 0x307a0110 0x04020205\n    mww phys 0x307a0114 0x03030202\n    mww phys 0x307a0120 0x00000803\n    mww phys 0x307a0180 0x00800020\n    mww phys 0x307a0184 0x02000100\n    mww phys 0x307a0190 0x02098204\n    mww phys 0x307a0194 0x00030303\n    mww phys 0x307a0200 0x00000016\n    mww phys 0x307a0204 0x00171717\n    mww phys 0x307a0214 0x04040404\n    mww phys 0x307a0218 0x0f040404\n    mww phys 0x307a0240 0x06000604\n    mww phys 0x307a0244 0x00000001\n    mww phys 0x30391000 0x00000000\n    mww phys 0x30790000 0x17420f40\n    mww phys 0x30790004 0x10210100\n    mww phys 0x30790010 0x00060807\n    mww phys 0x307900b0 0x1010007e\n    mww phys 0x3079009c 0x00000d6e\n    mww phys 0x30790020 0x08080808\n    mww phys 0x30790030 0x08080808\n    mww phys 0x30790050 0x01000010\n    mww phys 0x30790050 0x00000010\n\n    mww phys 0x307900c0 0x0e407304\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e447306\n\n    check_bits_set_32 0x307900c4 0x1\n\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e407304\n\n\n    mww phys 0x30384130 0x00000000\n    mww phys 0x30340020 0x00000178\n    mww phys 0x30384130 0x00000002\n    mww phys 0x30790018 0x0000000f\n\n    check_bits_set_32 0x307a0004 0x1\n}\n\n# disable internal reset-assert handling to\n# allow reset-init to work\n$_TARGETNAME.0 configure -event reset-assert \"\"\n$_TARGETNAME.1 configure -event reset-assert \"\"\n$_TARGETNAME_2 configure -event reset-assert \"\"\n\n$_TARGETNAME.0 configure -event reset-init {\n    global _CHIPNAME\n    imx7_disable_wdog\n    imx7_uart_dbgconf\n    apply_dcd\n    $_CHIPNAME.dap memaccess 0\n}\n\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_lpc-link2.cfg",
    "content": "#\n# NXP LPC-Link2\n#\n# http://www.nxp.com/board/OM13054.html\n# https://www.lpcware.com/lpclink2\n# http://embeddedartists.com/products/lpcxpresso/lpclink2.php\n#\n\nsource [find target/lpc4370.cfg]\n\n# W25Q80BVSSIG w/ 1 MB flash\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_mcimx8m-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8M-EVK\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_rdb-ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046ARDB (Reference Design Board)\n# This is for the \"console\" USB port on the front panel\n# You must ensure that SW4-7 is in the \"off\" position\n\n# NXP K20\n# The firmware implements the old CMSIS-DAP v1 USB HID interface\n# You must pass --enable-cmsis-dap to ./configure to enable it\nsource [find interface/cmsis-dap.cfg]\n\ntransport select jtag\nreset_config srst_only\n\nsource [find target/ls1046a.cfg]\n\n# The adapter can't handle 10MHz\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/nxp_rdb-ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088ARDB (Reference Design Board)\n# This is for the \"main\" JTAG connector J55\n\ntransport select jtag\nreset_config srst_only\n\n# To access the CPLD, populate J48 and add `-c 'set CWTAP 1'` to your command\n# line. At the time of this writing, programming is unsupported.\nif { [info exists CWTAP] } {\n\tsource [find cpld/altera-epm240.cfg]\n} else {\n\tsource [find target/ls1088a.cfg]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_LPC2378STK.cfg",
    "content": "#####################################################\n# Olimex LPC2378STK eval board\n#\n# http://olimex.com/dev/lpc-2378stk.html\n#\n# Author: Sten, debian@sansys-electronic.com\n#####################################################\n#\n\nsource [find target/lpc2378.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_lpc_h2148.cfg",
    "content": "#\n# Olimex LPC-H2148 eval board\n#\n# http://www.olimex.com/dev/lpc-h2148.html\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_sam7_ex256.cfg",
    "content": "# Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it.\n\nsource [find target/at91sam7x256.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_sam7_la2.cfg",
    "content": "source [find target/at91sam7a2.cfg]\n\n# delays needed to get stable reads of cpu state\njtag_ntrst_delay 10\nadapter srst delay 200\n\n# board uses pullup and connects only srst\nreset_config srst_open_drain\n\n# srst is connected to NRESET of CPU and fully resets everything...\nreset_config srst_only srst_pulls_trst\n\nadapter speed 1\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 1\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# init script from http://www.mikrocontroller.net/topic/107462\n\t# AT91SAM7A2\n\t# AMC (advanced memory controller)\n\n\techo \"setting up AMC\"\n\t# AMC_CS0 - FLASH 1MB (0x40000000-0x400FFFFF) + DM9000E (0x40100000)\n\tmww 0xFFE00000 0x40003EBD\n\n\t# AMC_CS1 - RAM low 2MB (0x40400000-0x405FFFFF)\n\tmww 0xFFE00004 0x404030A9\n\n\t# AMC_CS2 - RAM high 2MB (0x40800000-0x405FFFFF)\n\t#mww 0xFFE00008 0x404030A9\n\t# changed to  0x40_8_\n\tmww 0xFFE00008 0x408030A9\n\n\t# AMC_MCR\n\tmww 0xFFE00024 0x00000004\n\n\t# AMC_RCR force remap\n\tmww 0xFFE00020 0x00000001\n\n\techo \"set up AMC\"\n\tsleep 100\n\n\t# the following base addresses from the original script did not correspond to those from datasheet\n\t# changed bases from 0xFF000000 to 0xFFF00000\n\n\t# disable watchdog, to prevent unwanted resets\n\tmww 0xFFFA0068 0x00000000\n\techo \"disabled watchdog\"\n\n\tsleep 50\n\n\t# disable PLL\n\tmww 0xFFFEC004 0x18070004\n\n\t# PLL = 10 ==> Coreclock = 6Mhz*10/2 = 30 Mhz\n\tmww 0xFFFEC010 0x762D800A\n\n\t# enable PLL\n\tmww 0xFFFEC000 0x23050004\n\techo \"set up pll\"\n\n\tsleep 100\n\tadapter speed 5000\n}\n\n$_TARGETNAME arm7_9 dcc_downloads enable\n$_TARGETNAME arm7_9 fast_memory_access enable\n\n# remap:  ram at 0, flash at 0x40000000, like reset-init above does\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\nflash bank onboard.flash cfi 0x40000000 0x00100000 2 2 at91sam7a2.cpu\n\n# boot: ram at 0x300000, flash at 0x0, useful if board is in funny configuration\n#$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n#flash bank onboard1.flash cfi 0x00000000 0x00100000 2 2 at91sam7a2.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_sam9_l9260.cfg",
    "content": "################################################################################\n# Olimex SAM9-L9260 Development Board\n#\n# http://www.olimex.com/dev/sam9-L9260.html\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     PMC configured for external 18.432 MHz crystal\n#\n# 32-bit SDRAM : 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks\n# 8-bit NAND Flash : 1 x Samsung K9F4G08U0M, 512M x 8Bit\n# Dataflash : 1 x Atmel AT45DB161D, 16Mbit\n#\n################################################################################\n\nsource [find target/at91sam9260.cfg]\n\n# NTRST_E jumper is enabled by default, so we don't need to override the reset\n# config.\n#reset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n\t# At reset, CPU runs at 32.768 kHz.  JTAG frequency must be 6 times slower if\n\t# RCLK is not supported.\n\tjtag_rclk 5\n\thalt\n\n\t# RSTC_MR : enable user reset, reset length is 64 slow clock cycles.  MMU may\n\t# be enabled... use physical address.\n\tmww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog\n\n\t##\n\t# Clock configuration for 99.328 MHz main clock.\n\t##\n    echo \"Setting up clock\"\n\tmww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable main oscillator, 512 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 15.6 ms for startup)\n\tmww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator (18.432 MHz)\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR : 18.432 MHz / 9 * 97 = 198.656 MHz, 63 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 1.9 ms for startup)\n\tmww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz)\n\n\t# Increase JTAG speed to 6 MHz if RCLK is not supported.\n\tjtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable ;# Enable faster DCC downloads.\n\n\t##\n\t# SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks.\n\t##\n    echo \"Configuring SDRAM\"\n\tmww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips\n\n\tmww 0xffffea00 0x1        ;# SDRAMC_MR : issue NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2        ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4        ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3        ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0        ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\n\tmww 0xffffea04 0x2b6      ;# SDRAMC_TR : set refresh timer count to 7 us\n\n    ##\n    # NAND Flash Configuration for 1 x Samsung K9F4G08U0M, 512M x 8Bit.\n    ##\n    echo \"Configuring NAND flash\"\n    mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock\n    mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n    mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14\n    mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13\n    mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND\n    mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13\n\n    mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before\n\n    mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE\n    mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals\n    mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle\n    mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n                               #             3 TDF cycles, no optimization\n\n    mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers\n    mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n    nand probe at91sam9260.flash\n\n    ##\n    # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit\n    ##\n    echo \"Setting up dataflash\"\n    mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI),\n                               #            2(SPI0_SPCK), and 11(SPI0_NPCS1)\n    mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2\n    mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11\n    mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock\n\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure\n    mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected\n\n    mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud,\n                               #             250ns delay before SPCK, 250ns b/n tx\n\n    mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1\n    mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0\n}\n\nnand device at91sam9260.flash at91sam9 at91sam9260.cpu 0x40000000 0xffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_stm32_h103.cfg",
    "content": "# Olimex STM32-H103 eval board\n# http://olimex.com/dev/stm32-h103.html\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_stm32_h107.cfg",
    "content": "#\n# Olimex STM32-H107\n#\n# http://olimex.com/dev/stm32-h107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_stm32_h405.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Olimex STM32-H405 eval board\n# https://www.olimex.com/Products/ARM/ST/STM32-H405/\n\n# Work-area size (RAM size) = 128kB for STM32F405RG device\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/olimex_stm32_p107.cfg",
    "content": "#\n# Olimex STM32-P107\n#\n# http://olimex.com/dev/stm32-p107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/omap2420_h4.cfg",
    "content": "# OMAP2420 SDP board (\"H4\")\n\nsource [find target/omap2420.cfg]\n\n# NOTE: this assumes you're *NOT* using a TI-14 connector.\nreset_config trst_and_srst separate\n\n# Board configs can vary a *LOT* ... parts, jumpers, etc.\n# This GP board boots from cs0 using NOR (2x32M), and also\n# has 64M NAND on cs6.\nflash bank h4.u10 cfi 0x04000000 0x02000000 2 2 $_TARGETNAME\nflash bank h4.u11 cfi 0x06000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/openrd.cfg",
    "content": "# Marvell OpenRD\n\nsource [find interface/ftdi/openrd.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc openrd_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x37543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000A33 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000004 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x00120012 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000E40F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc openrd_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\topenrd_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc openrd_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\topenrd_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/or1k_generic.cfg",
    "content": "# If you want to use the VJTAG TAP or the XILINX BSCAN,\n# you must set your FPGA TAP ID here\n\nset FPGATAPID 0x020b30dd\n\n# Choose your TAP core (VJTAG , MOHOR or XILINX_BSCAN)\nif { [info exists TAP_TYPE] == 0} {\n   set TAP_TYPE VJTAG\n}\n\n# Set your chip name\nset CHIPNAME or1200\n\nsource [find target/or1k.cfg]\n\n# Set the servers polling period to 1ms (needed to JSP Server)\npoll_period 1\n\n# Set the adapter speed\nadapter speed 3000\n\n# Enable the target description feature\ngdb_target_description enable\n\n# Add a new register in the cpu register list. This register will be\n# included in the generated target descriptor file.\n# format is addreg [name] [address] [feature] [reg_group]\naddreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n# Override default init_reset\nproc init_reset {mode} {\n\tsoft_reset_halt\n\tresume\n}\n\n# Target initialization\ninit\necho \"Halting processor\"\nhalt\n\nforeach name [target names] {\n\tset y [$name cget -endian]\n\tset z [$name cget -type]\n\tputs [format \"Chip is %s, Endian: %s, type: %s\" \\\n\t      $name $y $z]\n}\n\nset c_blue  \"\\033\\[01;34m\"\nset c_reset \"\\033\\[0m\"\n\nputs [format \"%sTarget ready...%s\" $c_blue $c_reset]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/osk5912.cfg",
    "content": "# http://omap.spectrumdigital.com/osk5912/\n\nsource [find target/omap5912.cfg]\n\n# NOTE: this assumes you're using the ARM 20-pin (\"Multi-ICE\")\n# JTAG connector, and accordingly have J1 connecting pins 1 & 2.\n# The TI-14 pin needs \"trst_only\", and J1 connecting 2 & 3.\nreset_config trst_and_srst separate\n\n# NOTE:  boards with XOMAP parts wire nSRST to nPWRON_RESET.\n# That resets everything -- including JTAG and EmbeddedICE.\n# So they must use \"reset_config srst_pulls_trst\".\n\n# NOTE:  an expansion board could add a trace connector ... if\n# it does, change this appropriately.  And reset_config too,\n# assuming JTAG_DIS reroutes JTAG to that connector.\netm config $_TARGETNAME 8 demultiplexed full dummy\netm_dummy config $_TARGETNAME\n\n# standard boards populate two 16 MB chips, but manufacturing\n# options or an expansion board could change this config.\nflash bank osk.u1 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\nflash bank osk.u2 cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\nproc osk5912_init {} {\n\tomap5912_reset\n\n\t# detect flash\n\tflash probe 0\n\tflash probe 1\n}\n$_TARGETNAME configure -event reset-init { osk5912_init }\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/phone_se_j100i.cfg",
    "content": "#\n# Sony Ericsson J100I Phone\n#\n# more information can be found on\n# http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i\n#\nsource [find target/ti_calypso.cfg]\n\n# external flash\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/phytec_lpc3250.cfg",
    "content": "source [find target/lpc3250.cfg]\n\nadapter srst delay 200\njtag_ntrst_delay 1\nadapter speed 200\nreset_config trst_and_srst separate\n\narm7_9 dcc_downloads enable\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n\n$_TARGETNAME configure -event reset-start {\n             arm7_9 fast_memory_access disable\n             adapter speed 200\n}\n\n$_TARGETNAME configure -event reset-end {\n             adapter speed 6000\n             arm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-init { phytec_lpc3250_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc phytec_lpc3250_init { } {\n        # Set clock dividers\n        #   ARMCLK = 266.5 MHz\n        #   HCLK   = 133.25 MHz\n        #   PERIPHCLK = 13.325 MHz\n        mww 0x400040BC 0\n        mww 0x40004050 0x140\n        mww 0x40004040 0x4D\n        mww 0x40004058 0x16250\n\n        # Init PLLs\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004044 0x106\n        sleep 1 busy\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004048 0x2\n\n        # Init SDRAM with 133 MHz timings\n        mww 0x40028134 0x00FFFFFF\n        mww 0x4002802C 0x00000008\n\n        mww 0x31080000 1\n        mww 0x31080008 0\n        mww 0x40004068 0x1C000\n        mww 0x31080028 0x11\n\n        mww 0x31080400 0\n        mww 0x31080440 0\n        mww 0x31080460 0\n        mww 0x31080480 0\n\n        # Delays\n        mww 0x31080030 1\n        mww 0x31080034 6\n        mww 0x31080038 10\n        mww 0x31080044 1\n        mww 0x31080048 9\n        mww 0x3108004C 12\n        mww 0x31080050 10\n        mww 0x31080054 1\n        mww 0x31080058 1\n        mww 0x3108005C 0\n\n        mww 0x31080100 0x5680\n        mww 0x31080104 0x302\n\n        # Init sequence\n        mww 0x31080020 0x193\n        sleep 1 busy\n        mww 0x31080024 1\n        mww 0x31080020 0x113\n        sleep 1 busy\n        mww 0x31080020 0x013\n        sleep 1 busy\n        mww 0x31080024 65\n        mww 0x31080020 0x093\n        mdw 0x80020000\n        mww 0x31080020 0x013\n\n        # SYS_CTRL remapping\n        mww 0x40004014 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/pic-p32mx.cfg",
    "content": "# The Olimex PIC-P32MX has a PIC32MX\n\nset CPUTAPID 0x40916053\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/pico-debug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# pico-debug is a virtual CMSIS-DAP debug adapter\n# it runs on the very same RP2040 target being debugged without additional hardware\n# https://github.com/majbthrd/pico-debug\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 4000\n\nset CHIPNAME rp2040\nsource [find target/rp2040-core0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n\nsource [find interface/ftdi/pipistrello.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/pipistrello.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx45.bit;\\\n# jtagspi_program bitstream-pistrello.bin 0;\\\n# jtagspi_program bios.bin 0x170000;\\\n# jtagspi_program runtime.fbi 0x180000;\\\n# xc6s_program xc6s.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/propox_mmnet1001.cfg",
    "content": "\n## Chip:\nset CHIPNAME at91sam9260\nset CPUTAPID 0x0792603f\nset ENDIAN little\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n\nproc at91sam_init { } {\n\n\t# at reset chip runs at 32 kHz => 1/8 * 32 kHz = 4 kHz\n\tjtag_rclk 4\n\n\t# Enable user reset and disable watchdog\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\t# Oscillator setup\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator (18.432 MHz)\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 18.432 MHz kHz => 1/8 * 18.432 MHz = 2.304 MHz\n\tjtag_rclk 2000\n\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc2c 0x207c3f0c         ;# CKGR_PLLBR: Set PLLB Register for USB usage (USB_CLK = 48 MHz)\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 198.656 MHz kHz => full speed jtag\n\tjtag_rclk 30000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\t# Configure PIO Controller for SDRAM data-lines D16-D31\n\t# PC16-PC31 = Peripheral A: D16-D32\n\tmww 0xfffff844 0xffff0000\t;# Interrupt Disable\n\tmww 0xfffff854 0xffff0000\t;# Multi-Drive Disable\n\tmww 0xfffff860 0xffff0000\t;# Pull-Up Disable\n\tmww 0xfffff870 0xffff0000\t;# PIO_ASR : Select peripheral A function for D15..D31\n\tmww 0xfffff804 0xffff0000\t;# PIO_PDR : Disable PIO function for D15..D31 (Peripheral function enable)\n\tmww 0xfffffc10 0x00000010\t;# Enable PIO-C Clock in PMC (PID=4)\n\n\t# SD-Ram setup\n\tmww 0xffffef1c 0x2\t\t\t;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\tmww 0xffffea08 0x85227259\t;# SDRAMC_CR : Configure SDRAM (IS42S32160A: 4M Words x 32 Bits x 4 Banks (512-Mbit))\n\tmww 0xffffea00 0x1\t\t\t;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2\t\t\t;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (1st)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (2nd)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (3th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (4th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (5th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (6th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (7th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (8th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3\t\t\t;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0\t\t\t;# SDRAMC_MR : Normal Mode\n\tmww 0x20000000 0\n\tmww 0xFFFFEA04 0x30d\t\t;# SDRAM Refresh Time Register\n\t\t\t\t\t\t\t\t #  datasheet: 8k refresh cycles / 64 ms\n\t\t\t\t\t\t\t\t #  MCLK / (8*1024 / 64e-3) = 100e6 / 128000 = 781 = 0x30d\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/pxa255_sst.cfg",
    "content": "# A PXA255 test board with SST 39LF400A flash\n#\n# At reset the memory map is as follows. Note that\n# the memory map changes later on as the application\n# starts...\n#\n# RAM at 0x4000000\n# Flash at 0x00000000\n#\nsource [find target/pxa255.cfg]\n\n# Target name is set by above\n$_TARGETNAME configure -work-area-phys 0x4000000 -work-area-size 0x4000 -work-area-backup 0\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width> <target> [options]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x80000 2 2 $_TARGETNAME jedec_probe\n\nproc pxa255_sst_init {} {\n\txscale cp15   15      0x00002001  ;#Enable CP0 and CP13 access\n\t#\n\t# setup GPIO\n\t#\n\tmww    0x40E00018  0x00008000  ;#CPSR0\n\tsleep   20\n\tmww    0x40E0001C  0x00000002  ;#GPSR1\n\tsleep   20\n\tmww    0x40E00020  0x00000008  ;#GPSR2\n\tsleep   20\n\tmww    0x40E0000C  0x00008000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00054  0x80000000  ;#GAFR0_L\n\tsleep   20\n\tmww    0x40E00058  0x00188010  ;#GAFR0_H\n\tsleep   20\n\tmww    0x40E0005C  0x60908018  ;#GAFR1_L\n\tsleep   20\n\tmww    0x40E0000C  0x0280E000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00010  0x821C88B2  ;#GPDR1\n\tsleep   20\n\tmww    0x40E00014  0x000F03DB  ;#GPDR2\n\tsleep   20\n\tmww    0x40E00000  0x000F03DB  ;#GPLR0\n\tsleep   20\n\n\n\tmww    0x40F00004  0x00000020  ;#PSSR\n\tsleep   20\n\n\t#\n\t# setup memory controller\n\t#\n\tmww    0x48000008  0x01111998  ;#MSC0\n\tsleep   20\n\tmww    0x48000010  0x00047ff0  ;#MSC2\n\tsleep   20\n\tmww    0x48000014  0x00000000  ;#MECR\n\tsleep   20\n\tmww    0x48000028  0x00010504  ;#MCMEM0\n\tsleep   20\n\tmww    0x4800002C  0x00010504  ;#MCMEM1\n\tsleep   20\n\tmww    0x48000030  0x00010504  ;#MCATT0\n\tsleep   20\n\tmww    0x48000034  0x00010504  ;#MCATT1\n\tsleep   20\n\tmww    0x48000038  0x00004715  ;#MCIO0\n\tsleep   20\n\tmww    0x4800003C  0x00004715  ;#MCIO1\n\tsleep   20\n\t#\n\tmww    0x48000004  0x03CA4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x004B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000BC018  ;#MDREF\n\tsleep   20\n\tmww    0x48000000  0x00001AC8  ;#MDCNFG\n\tsleep   20\n\n\tsleep   20\n\n\tmww    0x48000000  0x00001AC9  ;#MDCNFG\n\tsleep   20\n\tmww    0x48000040  0x00000000  ;#MDMRS\n\tsleep   20\n}\n\n$_TARGETNAME configure -event reset-init {pxa255_sst_init}\n\nreset_config trst_and_srst\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n#xscale debug_handler 0  0xFFFF0800      ;# debug handler base address\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/quark_d2000_refboard.cfg",
    "content": "# Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582)\n\n# the board has an onboard FTDI FT232H chip\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\n\nftdi layout_init 0x0000 0x030b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0100\n\nsource [find target/quark_d20xx.cfg]\n\nadapter speed 1000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/quark_x10xx_board.cfg",
    "content": "# There are many Quark boards that can host the quark_x10xx SoC\n# Galileo is an example board\n\nsource [find target/quark_x10xx.cfg]\n\n#default frequency but this can be adjusted at runtime\nadapter speed 4000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/quicklogic_quickfeather.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3 QuickFeather\n# https://www.quicklogic.com/products/eos-s3/quickfeather-development-kit/\n\nsource [find target/eos_s3.cfg]\n\nreset_config srst_only\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Radiona ULX3S\n# https://radiona.org/ulx3s/\n# Currently there are following board variants:\n# CS-ULX3S-01 - LFE5U 12F\n# CS-ULX3S-02 - LFE5U 45F\n# CS-ULX3S-03 - LFE5U 85F\n#\n# two JTAG interfaces:\n# - US1, micro USB port connected to FT231XQ\n#   This interface should be used with following config:\n#        interface/ft232r/radiona_ulx3s.cfg\n# - J4, 6 pin connector\n#\n# Both of this interfaces share the JTAG lines (TDI, TMS, TCK, TDO) between\n# Lattice ECP5 FPGA chip and ESP32 WiFi controller.\n# Note: TRST_N of the ESP32 is pulled up by default and can be pulled down over\n# J3 interface.\n# See schematics for more information:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v308.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v314.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v315.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nsource [find interface/ft232r/radiona_ulx3s.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/redbee.cfg",
    "content": "source [find target/mc13224v.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/reflexces_achilles_i-dev_kit_arria10.cfg",
    "content": "# Achilles Instant-Development Kit Arria 10 SoC SoM\n# https://www.reflexces.com/products-solutions/achilles-instant-development-kit-arria-10-soc-som\n#\n\nif { [info exists USE_EXTERNAL_DEBUGGER] } {\n\techo \"Using external debugger\"\n} else {\n\tsource [find interface/altera-usb-blaster2.cfg]\n\tusb_blaster device_desc \"Arria10 IDK\"\n}\n\nsource [find fpga/altera-10m50.cfg]\nsource [find target/altera_fpgasoc_arria10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_dk-s7g2.cfg",
    "content": "#\n# Renesas Synergy DK-S7G2\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# XXX 19-pin SWD+TRACE connector also available\n\n# Synergy R7FS7G27H2A01CBD\nsource [find target/renesas_s7g2.cfg]\n\n# 32 MB QSPI flash (Micron N25Q256A13EF840E)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_falcon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Renesas R-Car V3U Falcon Board Config\n\n# The Falcon board comes with either an V3U SOC.\n\necho \"\\nFalcon:\"\nif { ![info exists SOC] } {\n\tset SOC V3U\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_gr_peach.cfg",
    "content": "# Renesas RZ/A1H GR-Peach board\n\nreset_config srst_only\n\nsource [find target/renesas_r7s72100.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_porter.cfg",
    "content": "# Renesas R-Car M2 Evaluation Board\n\nset SOC M2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_salvator-xs.cfg",
    "content": "# Renesas R-Car Gen3 Salvator-X(S) Board Config\n\n# The Salvator-X(S) boards come with either an H3, M3W, or M3N SOC.\n\necho \"\\nSalvator-X(S):\"\nif { ![info exists SOC] } {\n\tset SOC H3\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_silk.cfg",
    "content": "# Renesas R-Car E2 Evaluation Board\n\nset SOC E2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/renesas_stout.cfg",
    "content": "# Renesas R-Car H2 Evaluation Board\n\nset SOC H2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/rigado_bmd300_ek.cfg",
    "content": "#\n# Rigado BMD-300 Evaluation Kit\n#\n# https://www.rigado.com/products/modules/bmd-300/\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/rpi3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 3 board with BCM2837 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2837.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/rpi4b.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 4 model B board with BCM2711 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2711.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/rsc-w910.cfg",
    "content": "# Avalue RSC-W8910 sbc\n# http://www.avalue.com.tw/products/RSC-W910.cfm\n# 2MB NOR Flash\n# 64MB SDRAM\n# 128MB NAND Flash\n\n# Based on Nuvoton nuc910\nsource [find target/nuc910.cfg]\n\n#\n# reset only behaves correctly if we use srst_pulls_trst\n#\nreset_config trst_and_srst srst_pulls_trst\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME nuc910 $_TARGETNAME\n\n#\n# Target events\n#\n\n$_TARGETNAME configure -event reset-start {adapter speed 1000}\n\n$_TARGETNAME configure -event reset-init {\n\t# switch on PLL for 200MHz operation\n\t# running from 15MHz input clock\n\n\tmww 0xB0000200 0x00000030 ;# CLKEN\n\tmww 0xB0000204 0x00000f3c ;# CLKSEL\n\tmww 0xB0000208 0x05007000 ;# CLKDIV\n\tmww 0xB000020C 0x00004f24 ;# PLLCON0\n\tmww 0xB0000210 0x00002b63 ;# PLLCON1\n\tmww 0xB000000C 0x08817fa6 ;# MFSEL\n\tsleep 10\n\n\t# we are now running @ 200MHz\n\t# enable all openocd speed tweaks\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\tadapter speed 15000\n\n\t# map nor flash to 0x20000000\n\t# map sdram to 0x00000000\n\n\tmww 0xb0001000 0x000530c1 ;# EBICON\n\tmww 0xb0001004 0x40030084 ;# ROMCON\n\tmww 0xb0001008 0x000010ee ;# SDCONF0\n\tmww 0xb000100C 0x00000000 ;# SDCONF1\n\tmww 0xb0001010 0x0000015b ;# SDTIME0\n\tmww 0xb0001014 0x0000015b ;# SDTIME1\n\tmww 0xb0001018 0x00000000 ;# EXT0CON\n\tmww 0xb000101C 0x00000000 ;# EXT1CON\n\tmww 0xb0001020 0x00000000 ;# EXT2CON\n\tmww 0xb0001024 0x00000000 ;# EXT3CON\n\tmww 0xb000102c 0x00ff0048 ;# CKSKEW\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sayma_amc.cfg",
    "content": "# Sayma AMC is an FPGA board for the µTCA AMC format\n# The board is open hardware (CERN OHL) and the gateware and software\n# running on it are open source (ARTIQ, LGPLv3+).\n#\n# https://github.com/m-labs/sinara/wiki/Sayma\n#\n# It contains a Xilinx Kintex Ultrascale 040 FPGA (xcku040).\n# There is a SCANSTA112SM JTAG router on the board which is configured to\n# automatically add devices to the JTAG svcan chain when they are added.\n# Sayma AMC is usually combined with Sayma RTM (rear transition module)\n# which features an Artix 7 FPGA.\n\nadapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n# Use this to distinguish multiple boards by topology\n#adapter usb location 5:1\n# sampling on falling edge generally seems to work and accelerates things but\n# is not fully tested\n#ftdi tdo_sample_edge falling\n# EN_USB_JTAG on ADBUS7: out, high\n# USB_nTRST on ADBUS4: out, high, but R46 is DNP\nftdi layout_init 0x0098 0x008b\n#ftdi layout_signal EN_USB -data 0x0080\n#ftdi layout_signal nTRST -data 0x0010\nreset_config none\n\nadapter speed 5000\n\ntransport select jtag\n\n# Add the RTM Artix to the chain. Note that this changes the PLD numbering.\n# Unfortunately openocd TAPs can't be disabled after they have been added and\n# before `init`.\n#source [find cpld/xilinx-xc7.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nset XILINX_USER1 0x02\nset XILINX_USER2 0x03\nset JTAGSPI_IR $XILINX_USER1\nsource [find cpld/jtagspi.cfg]\nflash bank xcu.spi1 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER2\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sheevaplug.cfg",
    "content": "# Marvell SheevaPlug\n\nsource [find interface/ftdi/sheevaplug.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc sheevaplug_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x39543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000833 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000042 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x003C0000 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000F80F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc sheevaplug_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_reflash_uboot_env { } {\n\n\t# reflash the u-Boot environment variables area\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0xa0000 0x40000\n\tnand write 0 uboot-env.bin 0xa0000 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\tsheevaplug_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sifive-e31arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e31arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sifive-e51arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e51arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sifive-hifive1-revb.cfg",
    "content": "adapter speed 4000\n\nadapter driver jlink\ntransport select jtag\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 0\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME.0\n\ninit\n\njlink jtag 3\n\nhalt\nflash protect 0 1 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/sifive-hifive1.cfg",
    "content": "adapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nSRST -oe 0x0020 -data 0x0020\n\n#Reset Stretcher logic on FE310 is ~1 second long\n#This doesn't apply if you use\n# ftdi set_signal, but still good to document\n#adapter srst delay 1500\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME\ninit\n#reset -- This type of reset is not implemented yet\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n  #Wait for the reset stretcher\n  #It will work without this, but\n  #will incur lots of delays for later commands.\n  sleep 1500\n}\nhalt\nflash protect 0 64 last off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/smdk6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x00100000 2 2 $_TARGETNAME jedec_probe\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/snps_em_sk.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.x\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# 5MHz seems to work good with all cores that might happen in 2.x\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/snps_em_sk_v1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v1.0 and v1.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\nadapter speed 10000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/snps_em_sk_v2.1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency\n# 20MHz. 7.5 MHz seems to work fine.\nadapter speed 7500\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/snps_em_sk_v2.2.cfg",
    "content": "#  Copyright (C) 2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.2\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# EM11D reportedly requires 5 MHz. Other cores and board can work faster.\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC HSDK Software Development Platform (HS38 cores)\n#\n\nsource [find interface/ftdi/snps_sdp.cfg]\nadapter speed 10000\n\n# ARCs supports only JTAG.\ntransport select jtag\n\n# Configure SoC\nsource [find target/snps_hsdk.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spansion_sk-fm4-176l-s6e2cc.cfg",
    "content": "#\n# Spansion SK-FM4-176L-S6E2CC\n#\n\n#\n# FM3 MB9AF312K\n#\nsource [find interface/cmsis-dap.cfg]\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\n#\n# FM4 S6E2CCAJ0A w/ 192 KB SRAM0\n#\nset CHIPNAME s6e2cc\nset CHIPSERIES S6E2CCAJ0A\nset WORKAREASIZE 0x30000\nsource [find target/fm4_s6e2cc.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spansion_sk-fm4-u120-9b560.cfg",
    "content": "#\n# Spansion SK-FM4-U120-9B560\n#\n\n#\n# FM3 MB9AF312K\n#\n# source [find interface/cmsis-dap.cfg]\n\n#\n# FM4 MB9BF568R w/ 64 KB SRAM0\n#\nset CHIPNAME mb9bf568\nset CHIPSERIES MB9BF568R\nset WORKAREASIZE 0x10000\nsource [find target/fm4_mb9bf.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear300evb.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0\n# http://www.st.com/spear\n#\n# Date:      2010-11-27\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear300evb_init }\n\nproc spear300evb_init {} {\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp300_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear300evb_mod.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the top layer:\n#    1. replace reset chip U4 with a STM6315SDW13F;\n# - Modifications on the bottom layer:\n#    2. add 0 ohm resistor R10. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 and solder it between R10 and R54:\n# - one pad soldered with the pad of R54 connected to 3.3V (this\n#   is the pad of R54 far from JTAG connector J4)\n# - the other pad soldered with the nearest pad of R10.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear300evb.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear310evb20.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n#\n# Check ST Application Note AN3321 on how to fix SRST on\n# the board, then use the script board/spear310evb20_mod.cfg\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n# CFI parallel NOR on EMI CS0. 2x 16bit 8M devices = 16Mbyte.\nset _FLASHNAME0 $_CHIPNAME.pnor\nflash bank $_FLASHNAME0 cfi 0x50000000 0x01000000 2 4 $_TARGETNAME\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear310evb20_init }\n\nproc spear310evb20_init {} {\n\treg pc 0xffff0020\t;# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp310_init\n\tsp310_emi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear310evb20_mod.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note AN3321.\n# - Modifications on the top layer:\n#    1. remove R137 and C57, located near the SMII PHY U18;\n#    2. remove R172 and C75, located near the SMII PHY U19;\n#    3. remove R207 and C90, located near the SMII PHY U20;\n#    4. remove C236, located near the SMII PHY U21;\n#    5. remove U12, located near the JTAG connector;\n#    6. solder together pins 7, 8 and 9 of U12;\n#    7. solder together pins 11, 12, 13, 14, 15, 16, 17 and 18 of U12.\n# - Modifications on the bottom layer:\n#    8. replace reset chip U11 with a STM6315SDW13F;\n#    9. add 0 ohm resistor R329. It is located close to JTAG connector.\n#\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear310evb20.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear320cpu.cfg",
    "content": "# Configuration for the ST SPEAr320 CPU board\n# EVAL_SPEAr320CPU Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear320cpu_init }\n\nif { [info exists DDR_CHIPS] } {\n        set _DDR_CHIPS $DDR_CHIPS\n} else {\n        set _DDR_CHIPS 1\n}\n\nproc spear320cpu_init {} {\n\tglobal _DDR_CHIPS\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\" $_DDR_CHIPS\n\tsp320_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/spear320cpu_mod.cfg",
    "content": "# Configuration for the ST SPEAr320 Evaluation board\n# EVAL_SPEAr320CPU Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the bottom layer:\n#    1. replace reset chip U7 with a STM6315SDW13F;\n#    2. add 0 ohm resistor R45. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 or 0402 and solder it between R15 and R45:\n# - one pad soldered with the pad of R15 connected to 3.3V (this\n#   is the pad of R15 closer to R45)\n# - the other pad soldered with the nearest pad of R45.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear320cpu.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_b-l475e-iot01a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an B-L475E-IOT01A Discovery kit for IoT node with a single STM32L475VGT6 chip.\n# http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000\t;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_8l152r8.cfg",
    "content": "# This is a ST NUCLEO 8L152R8 board with a single STM8L152R8T6 chip.\n# http://www.st.com/en/evaluation-tools/nucleo-8l152r8.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\nsource [find target/stm8l152.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_8s208rb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a ST NUCLEO 8S208RB board with a single STM8S208RBT6 chip.\n# https://www.st.com/en/evaluation-tools/nucleo-8s208rb.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\n# 128 KiB flash and 2 KiB EEPROM\nset FLASHEND 0x27fff\nset EEPROMEND 0x47ff\n\nsource [find target/stm8s.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_f0.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F0. Known boards at the moment:\n# STM32F030R8\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# NUCLEO-F072RB\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# STM32F091RC\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260944\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_f103rb.cfg",
    "content": "# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_f3.cfg",
    "content": "# This is an ST NUCLEO F334R8 board with a single STM32F334R8T6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260004\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_f4.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:\n# STM32F401RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000\n# STM32F411RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_f7.cfg",
    "content": "# STMicroelectronics STM32F7 Nucleo development board\n# Known boards: NUCLEO-F746ZG and NUCLEO-F767ZI\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_g0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G0. Known boards at the moment:\n# NUCLEO-G031K8\n# https://www.st.com/en/evaluation-tools/nucleo-g031k8.html\n# NUCLEO-G070RB\n# https://www.st.com/en/evaluation-tools/nucleo-g070rb.html\n# NUCLEO-G071RB\n# https://www.st.com/en/evaluation-tools/nucleo-g071rb.html\n# NUCLEO-G0B1RE\n# https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_g4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G4. Known boards at the moment:\n# NUCLEO-G431KB\n# https://www.st.com/en/evaluation-tools/nucleo-g431kb.html\n# NUCLEO-G431RB\n# https://www.st.com/en/evaluation-tools/nucleo-g431rb.html\n# NUCLEO-G474RE\n# https://www.st.com/en/evaluation-tools/nucleo-g474re.html\n# NUCLEO-G491RE\n# https://www.st.com/en/evaluation-tools/nucleo-g491re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_h743zi.cfg",
    "content": "# This is an ST NUCLEO-H743ZI board with single STM32H743ZI chip.\n# http://www.st.com/en/evaluation-tools/nucleo-h743zi.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_h745zi.cfg",
    "content": "# This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip.\n\nsource [find interface/stlink-dap.cfg]\ntransport select dapdirect_swd\n\n# STM32H745xx devices are dual core (Cortex-M7 and Cortex-M4)\nset DUAL_CORE 1\n\n# enable CTI for cross halting both cores\nset USE_CTI 1\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_l073rz.cfg",
    "content": "# This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip.\n# http://www.st.com/en/evaluation-tools/nucleo-l073rz.html\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32l0_dual_bank.cfg]\n\n# There is only system reset line and JTAG/SWD command can be issued when SRST\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_l1.cfg",
    "content": "# This is an ST NUCLEO L152RE board with a single STM32L152RET6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l1x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_l4.cfg",
    "content": "# Should work with all STM32L4 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_l5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for STM32L5 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32l5x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/st_nucleo_wb55.cfg",
    "content": "#\n# Configuration for STM32WB55 Nucleo board (STM32WB55RGV6)\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32wbx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/steval-idb007v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-1 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb008v1.html\nset CHIPNAME bluenrg-1\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/steval-idb008v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-2 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb007v1.html\nset CHIPNAME bluenrg-2\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/steval-idb011v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-LP chip.\nset CHIPNAME bluenrg-lp\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/steval-idb012v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later.\n# This is an evaluation board with a single BlueNRG-LPS chip.\nset CHIPNAME bluenrg-lps\nsource [find interface/cmsis-dap.cfg]\nsource [find target/bluenrg-x.cfg]"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/steval_pcc010.cfg",
    "content": "# Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram\n# coming with the STEVAL-PCC010 board\n# http://www.st.com/internet/evalboard/product/251530.jsp\n# or any other board with only a STM32F2x in the JTAG chain\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm320518_eval.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm320518_eval_stlink.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32100b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F100VBT6 chip.\n# http://www.st.com/internet/evalboard/product/247099.jsp\n\n# The chip has only 8KB sram\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3210b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F10x (128KB) chip.\n# http://www.st.com/internet/evalboard/product/176090.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3210c_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F107VCT chip.\n# http://www.st.com/internet/evalboard/product/217965.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3210e_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F103ZET6 chip.\n# http://www.st.com/internet/evalboard/product/204176.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n\n#\n# configure FSMC Bank 1 (NOR/PSRAM Bank 2) NOR flash\n# M29W128GL70ZA6E\n#\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME\n\nproc stm32_enable_fsmc {} {\n\n\techo \"Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)\"\n\n\t# enable gpio (defg) clocks for fsmc\n\t# RCC_APB2ENR\n\tmww 0x40021018 0x000001E0\n\n\t# enable fsmc clock\n\t# RCC_AHBENR\n\tmww 0x40021014 0x00000114\n\n\t# configure gpio to alternate function\n\t# GPIOD_CRL\n\tmww 0x40011400 0x44BB44BB\n\t# GPIOD_CRH\n\tmww 0x40011404 0xBBBBBBBB\n\n\t# GPIOE_CRL\n\tmww 0x40011800 0xBBBBB444\n\t# GPIOE_CRH\n\tmww 0x40011804 0xBBBBBBBB\n\n\t# GPIOF_CRL\n\tmww 0x40011C00 0x44BBBBBB\n\t# GPIOF_CRH\n\tmww 0x40011C04 0xBBBB4444\n\n\t# GPIOG_CRL\n\tmww 0x40012000 0x44BBBBBB\n\t# GPIOG_CRH\n\tmww 0x40012004 0x444444B4\n\n\t# setup fsmc timings\n\t# FSMC_BCR1\n\tmww 0xA0000008 0x00001058\n\n\t# FSMC_BTR1\n\tmww 0xA000000C 0x10000502\n\n\t# FSMC_BCR1 - enable fsmc\n\tmww 0xA0000008 0x00001059\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32_enable_fsmc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3220g_eval.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3220g_eval_stlink.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3241g_eval.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm3241g_eval_stlink.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32429i_eval.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32429i_eval_stlink.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32439i_eval.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32439i_eval_stlink.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm327x6g_eval.cfg",
    "content": "# STM327[4|5]6G-EVAL: This is for the STM32F7 eval boards.\n# STM32746G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261639\n# STM32756G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f0discovery.cfg",
    "content": "# This is an STM32F0 discovery board with a single STM32F051R8T6 chip.\n# http://www.st.com/internet/evalboard/product/253215.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f103c8_blue_pill.cfg",
    "content": "# STM32F103C8 \"Blue Pill\"\n\n# NOTE:\n# There is a fair bit of confusion about whether the \"Blue Pill\" has 128kB or 64kB flash size.\n# The most likely cause is that there exist a -C8 and a -CB variant of the STM32F103, where\n# the C8 has 64kB, the CB has 128kB as per specification. \"Blue Pill\" boards are manufactured\n# by a lot of different vendors, some may actually use the CB variant but from a cursory look\n# it very hard to tell them apart (\"C8\" and \"CB\" look very similar). Nevertheless, people have\n# tried using the full 128kB of flash on the C8 and found it to be working. Hence this board file\n# overrides the internal size detection. Be aware though that you may be using you particular\n# board outside of its specification. If in doubt, comment the following line.\nset FLASH_SIZE 0x20000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f334discovery.cfg",
    "content": "# This is an STM32F334 discovery board with a single STM32F334C8T6 chip.\n# As it is one of the few boards with stlink V.2-1, we source the corresponding\n# nucleo file.\n# http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260318\n\nsource [find board/st_nucleo_f3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f3discovery.cfg",
    "content": "# This is an STM32F3 discovery board with a single STM32F303VCT6 chip.\n# http://www.st.com/internet/evalboard/product/254044.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f412g-disco.cfg",
    "content": "# This is an STM32F412G discovery board with a single STM32F412ZGT6 chip.\n# http://www.st.com/en/evaluation-tools/32f412gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PG06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x000AA000 0x00055000\t;# MODER\n\tmmw 0x40021408 0x000FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f413h-disco.cfg",
    "content": "# This is an STM32F413H discovery board with a single STM32F413ZHT6 chip.\n# http://www.st.com/en/evaluation-tools/32f413hdiscovery.html\n\n#\n# Untested!!!\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PD13: BK1_IO3, PE02: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PF09:AF10:V, PF08:AF10:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V\n\tmmw 0x40021400 0x000A0000 0x00050000\t;# MODER\n\tmmw 0x40021408 0x000F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f429disc1.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f429discovery.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f469discovery.cfg",
    "content": "#\n# This is an STM32F469 discovery board with a single STM32F469NI chip.\n# http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f469i-disco.cfg",
    "content": "# This is an STM32F469I discovery board with a single STM32F469NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f469idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PF10: CLK, PB06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB06:AF10:V, PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\n\t# Port B: PB06:AF10:V\n\tmmw 0x40020400 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40020408 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000000 0x05000000\t;# AFRL\n\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x002AA000 0x00155000\t;# MODER\n\tmmw 0x40021408 0x003FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000009AA 0x00000655\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000005\t\t\t\t;# 5 WS for 160 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24002808\t\t\t\t;# 160 MHz: HSI, PLLM=8, PLLN=160, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f4discovery.cfg",
    "content": "# This is an STM32F4 discovery board with a single STM32F407VGT6 chip.\n# http://www.st.com/internet/evalboard/product/252419.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 64KB\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f723e-disco.cfg",
    "content": "# This is an STM32F723E discovery board with a single STM32F723IEK6 chip.\n# http://www.st.com/en/evaluation-tools/32f723ediscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f746g-disco.cfg",
    "content": "# This is an STM32F746G discovery board with a single STM32F746NGH6 chip.\n# http://www.st.com/en/evaluation-tools/32f746gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PD12: BK1_IO1, PD11: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V\n\tmmw 0x40020C00 0x0A800000 0x05400000\t;# MODER\n\tmmw 0x40020C08 0x0FC00000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00999000 0x00666000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f769i-disco.cfg",
    "content": "# This is an STM32F769I discovery board with a single STM32F769NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f769idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# exit qpi mode\n\tmww 0xA0001014 0x000033f5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\n\t# 1-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\n\t# 4-line qpi mode\n\tmww 0xA0001014 0x00003135\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=EQIO\n\n\t# 4-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0F283FEC\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0xA, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=4READ4B\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32f7discovery.cfg",
    "content": "# This is an STM32F7 discovery board with a single STM32F756NGH6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641\n\n# This is for using the onboard STLINK/V2-1\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h735g-disco.cfg",
    "content": "# This is a stm32h735g-dk with a single STM32H735IGK6 chip.\n# https://www.st.com/en/evaluation-tools/stm32h735g-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h735igk6\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000006FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PF10: OCSPI1_CLK, PB02: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PD05: OCSPI1_IO5,\n\t# PD04: OCSPI1_IO4, PD13: OCSPI1_IO3, PE02: OCSPI1_IO2, PD12: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF10:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V\n\t# PD04:AF10:V, PE02:AF09:V, PF10:AF09:V, PG09:AF09:V, PG06:AF10:V\n\t# Port B: PB02:AF10:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000A00 0x00000500\t;# AFRL\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x58020C00 0x0A808A00 0x05404500\t;# MODER\n\tmmw 0x58020C08 0x0FC0CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x0FC0CF00\t;# PUPDR\n\tmmw 0x58020C20 0xA0AA0000 0x50550000\t;# AFRL\n\tmmw 0x58020C24 0x00999000 0x00666000\t;# AFRH\n\t# Port E: PE02:AF09:V\n\tmmw 0x58021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802100C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58021020 0x00000900 0x00000600\t;# AFRL\n\t# Port F: PF10:AF09:V\n\tmmw 0x58021400 0x00200000 0x00100000\t;# MODER\n\tmmw 0x58021408 0x00300000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x00300000\t;# PUPDR\n\tmmw 0x58021424 0x00000900 0x00000600\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h745i-disco.cfg",
    "content": "# This is a stm32h745i-disco with a single STM32H745XIH6 chip.\n# www.st.com/en/product/stm32h745i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h745xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h747i-disco.cfg",
    "content": "# This is a stm32h747i-disco with a single STM32H747XIH6 chip.\n# www.st.com/en/product/stm32h747i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h747xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PB02:AF09:V, PD11:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h750b-disco.cfg",
    "content": "# This is a stm32h750b-dk with a single STM32H750XBH6 chip.\n# www.st.com/en/product/stm32h750b-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h750xbh6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h7b3i-disco.cfg",
    "content": "# This is a stm32h7b3i-dk with a single STM32H7B3LIH6Q chip.\n# https://www.st.com/en/evaluation-tools/stm32h7b3i-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h7b3lih6q\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PB02: OCSPI1_CLK, PC05: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PH03: OCSPI1_IO5,\n\t# PC01: OCSPI1_IO4, PF06: OCSPI1_IO3, PF07: OCSPI1_IO2, PF09: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF09:V, PC05:AF10:V, PC01:AF10:V, PD11:AF09:V, PD07:AF10:V, PF09:AF10:V\n\t# PF07:AF10:V, PF06:AF10:V, PG09:AF09:V, PG06:AF10:V, PH03:AF09:V\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port C: PC05:AF10:V, PC01:AF10:V\n\tmmw 0x58020800 0x00000808 0x00000404\t;# MODER\n\tmmw 0x58020808 0x00000C0C 0x00000000\t;# OSPEEDR\n\tmmw 0x5802080C 0x00000000 0x00000C0C\t;# PUPDR\n\tmmw 0x58020820 0x00A000A0 0x00500050\t;# AFRL\n\t# Port D: PD11:AF09:V, PD07:AF10:V\n\tmmw 0x58020C00 0x00808000 0x00404000\t;# MODER\n\tmmw 0x58020C08 0x00C0C000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x00C0C000\t;# PUPDR\n\tmmw 0x58020C20 0xA0000000 0x50000000\t;# AFRL\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF10:V, PF06:AF10:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x000CF000\t;# PUPDR\n\tmmw 0x58021420 0xAA000000 0x55000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\t# Port H: PH03:AF09:V\n\tmmw 0x58021C00 0x00000080 0x00000040\t;# MODER\n\tmmw 0x58021C08 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C0C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x58021C20 0x00009000 0x00006000\t;# AFRL\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h7x3i_eval.cfg",
    "content": "# STM32H7[4|5]3I-EVAL: this is for the H7 eval boards.\n# This is an ST EVAL-H743XI board with single STM32H743XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h743i-eval.html\n# This is an ST EVAL-H753XI board with single STM32H753XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h753i-eval.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32h7x_dual_qspi.cfg",
    "content": "# stm32h754i-disco and stm32h750b-dk dual quad qspi.\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PF10: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PD11:AF09:V, PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0028A000 0x00145000\t;# MODER\n\tmmw 0x58021408 0x003CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000009A0 0x00000650\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l0discovery.cfg",
    "content": "# This is an STM32L053 discovery board with a single STM32L053 chip.\n# http://www.st.com/web/en/catalog/tools/PF260319\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32l0.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l476g-disco.cfg",
    "content": "# This is an STM32L476G discovery board with a single STM32L476VGT6 chip.\n# http://www.st.com/en/evaluation-tools/32l476gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000    ;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000    ;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l496g-disco.cfg",
    "content": "# This is an STM32L496G discovery board with a single STM32L496AGI6 chip.\n# http://www.st.com/en/evaluation-tools/32l496gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB11: BK1_NCS, PA03: CLK, PA06: BK1_IO3, PA07: BK1_IO2, PB00: BK1_IO1, PB01: BK1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PA03:AF10:V, PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V, PA03:AF10:V\n\tmmw 0x48000000 0x0000A080 0x00005040    ;# MODER\n\tmmw 0x48000008 0x0000F0C0 0x00000000    ;# OSPEEDR\n\tmmw 0x48000020 0xAA00A000 0x55005000    ;# AFRL\n\n\t# Port B: PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\tmmw 0x48000400 0x0080000A 0x00400005    ;# MODER\n\tmmw 0x48000408 0x00C0000F 0x00000000    ;# OSPEEDR\n\tmmw 0x48000420 0x000000AA 0x00000055    ;# AFRL\n\tmmw 0x48000424 0x0000A000 0x00005000    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l4discovery.cfg",
    "content": "# Explicitly for the STM32L476 discovery board:\n# http://www.st.com/web/en/catalog/tools/PF261635\n# but perfectly functional for any other STM32L4 board connected via\n# an stlink-v2-1 interface.\n# This is for STM32L4 boards that are connected via stlink-v2-1.\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l4p5g-disco.cfg",
    "content": "# This is a STM32L4P5G discovery board with a single STM32L4R9AGI6 chip.\n# http://www.st.com/en/evaluation-tools/stm32l4p5g-dk.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x07050333\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI2\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PE11: P1_NCS, PE10: P1_CLK, PG06: P1_DQS, PD07: P1_IO7, PC03: P1_IO6, PD05: P1_IO5\n\t# PD04: P1_IO4, PA06: P1_IO3, PA07: P1_IO2, PE13: P1_IO1, PE11: P1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PC03:AF10:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\t# PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V, PG06:AF03:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V\n\tmmw 0x48000000 0x0000A000 0x00005000\t;# MODER\n\tmmw 0x48000008 0x0000F000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800000C 0x00000000 0x0000F000\t;# PUPDR\n\tmmw 0x48000020 0xAA000000 0x55000000\t;# AFRL\n\t# Port C: PC03:AF10:V\n\tmmw 0x48000800 0x00000080 0x00000040\t;# MODER\n\tmmw 0x48000808 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x4800080C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x48000820 0x0000A000 0x00005000\t;# AFRL\n\t# Port D: PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x48000C00 0x00008A00 0x00004500\t;# MODER\n\tmmw 0x48000C08 0x0000CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x48000C0C 0x00000000 0x0000CF00\t;# PUPDR\n\tmmw 0x48000C20 0xA0AA0000 0x50550000\t;# AFRL\n\t# Port E: PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0x0AA00000 0x05500000\t;# MODER\n\tmmw 0x48001008 0x0FF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800100C 0x00000000 0x0FF00000\t;# PUPDR\n\tmmw 0x48001024 0x00AAAA00 0x00555500\t;# AFRH\n\t# Port G: PG06:AF03:V\n\tmmw 0x48001800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x48001808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x00003000\t;# PUPDR\n\tmmw 0x48001820 0x03000000 0x0C000000\t;# AFRL\n\n\t# PG12: P2_NCS, PF04: P2_CLK, PF12: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PG01: P2_IO5\n\t# PG00: P2_IO4, PF03: P2_IO3, PF02: P2_IO2, PF01: P2_IO1, PF00: P2_IO0\n\n\t# PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\t# PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\n\t# Port F: PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\tmmw 0x48001400 0x020002AA 0x01000155\t;# MODER\n\tmmw 0x48001408 0x030003FF 0x00000000\t;# OSPEEDR\n\tmmw 0x4800140C 0x00000000 0x030003FF\t;# PUPDR\n\tmmw 0x48001420 0x00055555 0x000AAAAA\t;# AFRL\n\tmmw 0x48001424 0x00050000 0x000A0000\t;# AFRH\n\t# Port G: PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\tmmw 0x48001800 0x0228000A 0x01140005\t;# MODER\n\tmmw 0x48001808 0x033C000F 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x033C000F\t;# PUPDR\n\tmmw 0x48001820 0x00000055 0x000000AA\t;# AFRL\n\tmmw 0x48001824 0x00050550 0x000A0AA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 24000\n\n\toctospi_init 1\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32l4r9i-disco.cfg",
    "content": "# This is a STM32L4R9I discovery board with a single STM32L4R9AII6 chip.\n# http://www.st.com/en/evaluation-tools/32l4r9idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x00000000\t\t\t\t;# OCTOSPIM_P1CR: disable Port 1\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PG12: P2_NCS, PI06: P2_CLK, PG15: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PH10: P2_IO5,\n\t# PH09: P2_IO4, PH08: P2_IO3, PI09: P2_IO2, PI10: P2_IO1, PI11: P2_IO0\n\n\t# PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PH10:AF05:V, PH09:AF05:V\n\t# PH08:AF05:V, PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\n\t# Port G: PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V\n\tmmw 0x48001800 0x82280000 0x41140000\t;# MODER\n\tmmw 0x48001808 0xC33C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001824 0x50050550 0xA00A0AA0\t;# AFRH\n\n\t# Port H: PH10:AF05:V, PH09:AF05:V, PH08:AF05:V\n\tmmw 0x48001C00 0x002A0000 0x00150000\t;# MODER\n\tmmw 0x48001C08 0x003F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001C24 0x00000555 0x00000AAA\t;# AFRH\n\n\t# Port I: PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\tmmw 0x48002000 0x00A82000 0x00541000\t;# MODER\n\tmmw 0x48002008 0x00FC3000 0x00000000\t;# OSPEEDR\n\tmmw 0x48002020 0x05000000 0x0A000000\t;# AFRL\n\tmmw 0x48002024 0x00005550 0x0000AAA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\toctospi_init 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32ldiscovery.cfg",
    "content": "# This is an STM32L discovery board with a single STM32L152RBT6 chip.\n# http://www.st.com/internet/evalboard/product/250990.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x4000\nsource [find target/stm32l1.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32mp13x_dk.cfg",
    "content": "# board MB1635x\n# http://www.st.com/en/evaluation-tools/stm32mp135f-dk.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp13x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32mp15x_dk2.cfg",
    "content": "# board MB1272B\n# http://www.st.com/en/evaluation-tools/stm32mp157a-dk1.html\n# http://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp15x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/stm32vldiscovery.cfg",
    "content": "# This is an STM32VL discovery board with a single STM32F100RB chip.\n# http://www.st.com/internet/evalboard/product/250863.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/str910-eval.cfg",
    "content": "# str910-eval eval board\n#\n# Need reset scripts\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs    -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/telo.cfg",
    "content": "source [find target/c100.cfg]\n# basic register definition for C100\nsource [find target/c100regs.tcl]\n# board-config info\nsource [find target/c100config.tcl]\n# C100 helper functions\nsource [find target/c100helper.tcl]\n\n\n# Telo board & C100 support trst and srst\n# make the reset asserted to\n# allow RC circuit to discharge for: [ms]\nadapter srst pulse_width 100\njtag_ntrst_assert_width 100\n# don't talk to JTAG after reset for: [ms]\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst separate\n\n\n\n\n# issue telnet: reset init\n# issue gdb: monitor reset init\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 100\n\t# this will setup Telo board\n\tsetupTelo\n\t#turn up the JTAG speed\n\tadapter speed 3000\n\techo \"JTAG speek now 3MHz\"\n\techo \"type helpC100 to get help on C100\"\n}\n\n$_TARGETNAME configure -event reset-deassert-post {\n\t# Force target into ARM state.\n#\tsoft_reset_halt ;# not implemented on ARM11\n\techo \"Detected SRSRT asserted on C100.CPU\"\n\n}\n\n$_TARGETNAME configure -event reset-assert-post {\n  echo \"Assering reset\"\n  #sleep 10\n}\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\n# it's really 16MB but the upper 8mb is controller via gpio\n# openocd does not support 'complex reads/writes' to NOR\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x01000000 2 2 $_TARGETNAME\n\n# writing data to memory does not work without this\narm11 memwrite burst disable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am335xevm.cfg",
    "content": "#\n# TI AM335x Evaluation Module\n#\n# For more information please see http://www.ti.com/tool/tmdxevm3358\n#\njtag_rclk 6000\n\nsource [find target/am335x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am437x_idk.cfg",
    "content": "# Texas Instruments AM437x Industrial Development Kit\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\ntransport select jtag\nadapter speed 30000\n\nsource [find target/am437x.cfg]\n$_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 }\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am43xx_evm.cfg",
    "content": "# Works on both AM437x GP EVM and AM438x ePOS EVM\ntransport select jtag\nadapter speed 16000\n\nsource [find target/am437x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am625evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021-2022 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments am625 EVM/SK\n# Link: https://www.ti.com/lit/zip/sprr448\n#\n\n# AM625 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am625\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am642evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM642 EVM\n#\n\n# AM642 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am642\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 250\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_am654evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM654 EVM/IDK Base Board\n#\n\n# AM654 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\nif { ![info exists SOC] } {\n\tset SOC am654\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_beagleboard.cfg",
    "content": "# OMAP3 BeagleBoard\n#  http://beagleboard.org\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n\nsource [find target/omap3530.cfg]\n\n# TI-14 JTAG connector\nreset_config trst_only\n\n# Later run:  omap3_dbginit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_beagleboard_xm.cfg",
    "content": "# BeagleBoard xM (DM37x)\n#  http://beagleboard.org\n\nset CHIPTYPE \"dm37x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit dm37x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_beaglebone-base.cfg",
    "content": "# AM335x Beaglebone family base configuration\n#  http://beagleboard.org/bone\n\nsource [find target/am335x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_beaglebone.cfg",
    "content": "# AM335x Beaglebone\n#  http://beagleboard.org/bone\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\nadapter speed 16000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_beaglebone_black.cfg",
    "content": "# AM335x Beaglebone Black\n#  http://beagleboard.org/bone\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_blaze.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc13x0_launchpad.cfg",
    "content": "#\n# TI CC13x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\ntransport select jtag\nadapter speed 5500\nsource [find target/ti_cc13x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc13x2_launchpad.cfg",
    "content": "#\n# TI CC13x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc13x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc26x0_launchpad.cfg",
    "content": "#\n# TI CC26x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc26x2_launchpad.cfg",
    "content": "#\n# TI CC26x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc3200_launchxl.cfg",
    "content": "#\n# TI SimpleLink Wi-Fi CC3200 LaunchPad\n#\n# http://www.ti.com/tool/cc3200-launchxl\n#\n\nsource [find interface/ftdi/ti-icdi.cfg]\n\nif { [info exists TRANSPORT] } {\n   transport select $TRANSPORT\n} else {\n   transport select jtag\n}\n\nadapter speed 2500\n\nset WORKAREASIZE 0x40000\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc3220sf_launchpad.cfg",
    "content": "#\n# TI CC3220SF-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc3220sf.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_cc32xx_launchpad.cfg",
    "content": "#\n# TI CC32xx-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_dk-tm4c129.cfg",
    "content": "#\n# TI Tiva C DK-TM4C129X Connected Development Kit\n#\n# http://www.ti.com/tool/dk-tm4c129x\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c129xnczad\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_ek-tm4c123gxl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c123gxl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c123gh6pm\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_ek-tm4c1294xl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c1294xl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c1294ncpdt\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_j7200evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J7200 EVM\n#\n\n# J7200 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j7200\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_j721evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721E EVM\n#\n\n# J721E EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721e\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_j721s2evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721s2 EVM\n# Link(SoM): https://www.ti.com/lit/zip/sprr439\n#\n\n# J721s2 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721s2\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_msp432_launchpad.cfg",
    "content": "#\n# TI MSP432 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 10000\ntransport select swd\nsource [find target/ti_msp432.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_pandaboard.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_pandaboard_es.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4460.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_tmdx570ls20susb.cfg",
    "content": "# TMS570 Microcontroller USB Kit\n# http://www.ti.com/tool/TMDX570LS20SUSB\n\n# Board uses a FT2232H to emulate an XDS100v2 JTAG debugger\n# TODO: board also supports an SCI UART on the 2232's B Bus\nsource [find interface/ftdi/xds100v2.cfg]\n\n# Processor is TMS570LS20216\nsource [find target/ti_tms570ls20xxx.cfg]\n\nreset_config trst_only\n\n# xds100v2 config says add this to the end\ninit\nftdi set_signal PWR_RST 1\njtag arp_init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/ti_tmdx570ls31usb.cfg",
    "content": "adapter speed 1500\n\nsource [find interface/ftdi/xds100v2.cfg]\nsource [find target/ti_tms570.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/tocoding_poplar.cfg",
    "content": "#\n# board configuration for Tocoding Poplar\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\nadapter speed 10000\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi3798.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/topas910.cfg",
    "content": "######################################\n# Target:    Toshiba TOPAS910 -- TMPA910 Starterkit\n#\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa910.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topas910_init }\n\nproc topas910_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;\n#  // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/topasa900.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n# Target:    Toshiba TOPAS900 -- TMPA900 Starterkit\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa900.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topasa900_init }\n\nproc topasa900_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n# bplan settings\n#\tmww 0xf0050004 0x00000000\n#\tmww 0xf005000c 0x000000a7\n#\tsleep 10\n#\tmdw 0xf0050008\n#\tmww 0xf0050008 0x00000002\n#\tmww 0xf0050010 0x00000065\n#\tmww 0xf0050054 0x00000040\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;   // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/tp-link_tl-mr3020.cfg",
    "content": "source [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr1_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/tp-link_wdr4300.cfg",
    "content": "source [find target/atheros_ar9344.cfg]\n\nreset_config trst_only separate\n\nproc ar9344_40mhz_pll_init {} {\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x13210f00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x13210f00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_BB_DPLL_BASE_REG\n\tmww 0xb8116188 0x03000000\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\n\t# QCA_PLL_CPU_PLL_CFG_REG\n\tmww 0xb8050000 0x40021380\n\t# QCA_PLL_DDR_PLL_CFG_REG\n\tmww 0xb8050004 0x40815800\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130801C\n\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x10810F00\n\tmww 0xb81161C0 0x41C00000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0810F00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0800F00\n\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x43000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x030003E8\n\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x10810F00\n\tmww 0xb8116240 0x41680000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0810F00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0800F00\n\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x43000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000718\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x01308018\n\tmww 0xb8050008 0x01308010\n\tmww 0xb8050008 0x01308000\n\n\t# QCA_PLL_DDR_PLL_DITHER_REG\n\tmww 0xb8050044 0x78180200\n\t# QCA_PLL_CPU_PLL_DITHER_REG\n\tmww 0xb8050048 0x41C00000\n\n}\n\nproc ar9344_ddr_init {} {\n\t# QCA_DDR_CTRL_CFG_REG\n\tmww 0xb8000108 0x40\n\t# QCA_DDR_RD_DATA_THIS_CYCLE_REG\n\tmww 0xb8000018 0xFF\n\t# QCA_DDR_BURST_REG\n\tmww 0xb80000C4 0x74444444\n\t# QCA_DDR_BURST2_REG\n\tmww 0xb80000C8 0x0222\n\t# QCA_AHB_MASTER_TOUT_MAX_REG\n\tmww 0xb80000CC 0xFFFFF\n\n\t# QCA_DDR_CFG_REG\n\tmww 0xb8000000 0xC7D48CD0\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_DDR2_CFG_REG\n\tmww 0xb80000B8 0x0E59\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x10\n\tmww 0xb8000010 0x20\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x02\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x02\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x0133\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x33\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0382\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0402\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\n\t# QCA_DDR_REFRESH_REG\n\tmww 0xb8000014 0x4270\n\n\t# QCA_DDR_TAP_CTRL_0_REG\n\tmww 0xb800001C 0x0e\n\t# QCA_DDR_TAP_CTRL_1_REG\n\tmww 0xb8000020 0x0e\n\t# QCA_DDR_TAP_CTRL_2_REG\n\tmww 0xb8000024 0x0e\n\t# QCA_DDR_TAP_CTRL_3_REG\n\tmww 0xb8000028 0x0e\n}\n\n$_TARGETNAME configure -event reset-init {\n\n\t# mww 0xb806001c 0x1000000\n\tar9344_40mhz_pll_init\n\tsleep 100\n\n\t# flash remap\n\t# SPI_CONTROL_ADDR\n\tmww 0xbF000004 0x43\n\n\tar9344_ddr_init\n\tsleep 100\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0x1d000000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/twr-k60f120m.cfg",
    "content": "#\n# Freescale TWRK60F120M development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' banks\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.2 kinetis 0x00080000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.3 kinetis 0x000c0000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/twr-k60n512.cfg",
    "content": "#\n# Freescale TWRK60N512 development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' bank\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/twr-vf65gs10.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# Board has a 20 pin Cortex+ETM debug connector with only nSRST available\nreset_config srst_only\n\n# This configuration file only deals with the hardware JTAG.\n# There is has also an embedded Kinetis K20 with OpenSDA\n# where a CMSIS-DAP application can be installed.\n\n# Source generic VF6xx target configuration\nsource [find target/vybrid_vf6xx.cfg]\n\n# basic DDR memory init, setting up pad configuration\n# for DDR first then configuring the DDRMC for the\n# board\nproc ddr_init { } {\n\t# iomux ddr\n\tmww phys 0x40048220 0x00000180\n\tmww phys 0x40048224 0x00000180\n\tmww phys 0x40048228 0x00000180\n\tmww phys 0x4004822c 0x00000180\n\tmww phys 0x40048230 0x00000180\n\tmww phys 0x40048234 0x00000180\n\tmww phys 0x40048238 0x00000180\n\tmww phys 0x4004823c 0x00000180\n\tmww phys 0x40048240 0x00000180\n\tmww phys 0x40048244 0x00000180\n\tmww phys 0x40048248 0x00000180\n\tmww phys 0x4004824c 0x00000180\n\tmww phys 0x40048250 0x00000180\n\tmww phys 0x40048254 0x00000180\n\tmww phys 0x40048258 0x00000180\n\tmww phys 0x4004825c 0x00000180\n\tmww phys 0x40048260 0x00000180\n\tmww phys 0x40048264 0x00000180\n\tmww phys 0x40048268 0x00000180\n\tmww phys 0x4004826c 0x00000180\n\tmww phys 0x40048270 0x00000180\n\tmww phys 0x40048274 0x00000180\n\tmww phys 0x40048278 0x00000180\n\tmww phys 0x4004827c 0x00010180\n\tmww phys 0x40048280 0x00010180\n\tmww phys 0x40048284 0x00010180\n\tmww phys 0x40048288 0x00010180\n\tmww phys 0x4004828c 0x00010180\n\tmww phys 0x40048290 0x00010180\n\tmww phys 0x40048294 0x00010180\n\tmww phys 0x40048298 0x00010180\n\tmww phys 0x4004829c 0x00010180\n\tmww phys 0x400482a0 0x00010180\n\tmww phys 0x400482a4 0x00010180\n\tmww phys 0x400482a8 0x00010180\n\tmww phys 0x400482ac 0x00010180\n\tmww phys 0x400482b0 0x00010180\n\tmww phys 0x400482b4 0x00010180\n\tmww phys 0x400482b8 0x00010180\n\tmww phys 0x400482bc 0x00010180\n\tmww phys 0x400482c0 0x00010180\n\tmww phys 0x400482c4 0x00010180\n\tmww phys 0x400482c8 0x00010180\n\tmww phys 0x400482cc 0x00000180\n\tmww phys 0x400482d0 0x00000180\n\tmww phys 0x400482d4 0x00000180\n\tmww phys 0x400482d8 0x00000180\n\tmww phys 0x4004821c 0x000001a0\n\t# ddr_ctrl_init\n\tmww phys 0x400ae000 0x00000600\n\tmww phys 0x400ae008 0x00000020\n\tmww phys 0x400ae028 0x00013880\n\tmww phys 0x400ae02c 0x00030d40\n\tmww phys 0x400ae030 0x0000050c\n\tmww phys 0x400ae034 0x15040400\n\tmww phys 0x400ae038 0x1406040f\n\tmww phys 0x400ae040 0x04040000\n\tmww phys 0x400ae044 0x006db00c\n\tmww phys 0x400ae048 0x00000403\n\tmww phys 0x400ae050 0x01000000\n\tmww phys 0x400ae054 0x00060001\n\tmww phys 0x400ae058 0x000c0000\n\tmww phys 0x400ae05c 0x03000200\n\tmww phys 0x400ae060 0x00000006\n\tmww phys 0x400ae064 0x00010000\n\tmww phys 0x400ae068 0x0c30002c\n\tmww phys 0x400ae070 0x00000000\n\tmww phys 0x400ae074 0x00000003\n\tmww phys 0x400ae078 0x0000000a\n\tmww phys 0x400ae07c 0x003001d4\n\tmww phys 0x400ae084 0x00010000\n\tmww phys 0x400ae088 0x00050500\n\tmww phys 0x400ae098 0x00000000\n\tmww phys 0x400ae09c 0x04001002\n\tmww phys 0x400ae0a4 0x00000001\n\tmww phys 0x400ae0c0 0x00460420\n\tmww phys 0x400ae108 0x01000200\n\tmww phys 0x400ae10c 0x00000040\n\tmww phys 0x400ae114 0x00000200\n\tmww phys 0x400ae118 0x00000040\n\tmww phys 0x400ae120 0x00000000\n\tmww phys 0x400ae124 0x0a010300\n\tmww phys 0x400ae128 0x01014040\n\tmww phys 0x400ae12c 0x01010101\n\tmww phys 0x400ae130 0x03030100\n\tmww phys 0x400ae134 0x01000101\n\tmww phys 0x400ae138 0x0700000c\n\tmww phys 0x400ae13c 0x00000000\n\tmww phys 0x400ae148 0x10000000\n\tmww phys 0x400ae15c 0x01000000\n\tmww phys 0x400ae160 0x00040000\n\tmww phys 0x400ae164 0x00000002\n\tmww phys 0x400ae16c 0x00020000\n\tmww phys 0x400ae180 0x00002819\n\tmww phys 0x400ae184 0x01000000\n\tmww phys 0x400ae188 0x00000000\n\tmww phys 0x400ae18c 0x00000000\n\tmww phys 0x400ae198 0x00000000\n\tmww phys 0x400ae1a4 0x00000c00\n\tmww phys 0x400ae1a8 0x00000000\n\tmww phys 0x400ae1b8 0x0000000c\n\tmww phys 0x400ae1c8 0x00000000\n\tmww phys 0x400ae1cc 0x00000000\n\tmww phys 0x400ae1d4 0x00000000\n\tmww phys 0x400ae1d8 0x01010000\n\tmww phys 0x400ae1e0 0x02020000\n\tmww phys 0x400ae1e4 0x00000202\n\tmww phys 0x400ae1e8 0x01010064\n\tmww phys 0x400ae1ec 0x00010101\n\tmww phys 0x400ae1f0 0x00000064\n\tmww phys 0x400ae1f8 0x00000800\n\tmww phys 0x400ae210 0x00000506\n\tmww phys 0x400ae224 0x00020000\n\tmww phys 0x400ae228 0x01000000\n\tmww phys 0x400ae22c 0x04070303\n\tmww phys 0x400ae230 0x00000040\n\tmww phys 0x400ae23c 0x06000080\n\tmww phys 0x400ae240 0x04070303\n\tmww phys 0x400ae244 0x00000040\n\tmww phys 0x400ae248 0x00000040\n\tmww phys 0x400ae24c 0x000f0000\n\tmww phys 0x400ae250 0x000f0000\n\tmww phys 0x400ae25c 0x00000101\n\tmww phys 0x400ae268 0x682c4000\n\tmww phys 0x400ae26c 0x00000012\n\tmww phys 0x400ae278 0x00000006\n\tmww phys 0x400ae284 0x00010202\n\tmww phys 0x400ae400 0x00002613\n\tmww phys 0x400ae440 0x00002613\n\tmww phys 0x400ae404 0x00002615\n\tmww phys 0x400ae444 0x00002615\n\tmww phys 0x400ae408 0x00210000\n\tmww phys 0x400ae448 0x00210000\n\tmww phys 0x400ae488 0x00210000\n\tmww phys 0x400ae40c 0x0001012a\n\tmww phys 0x400ae44c 0x0001012a\n\tmww phys 0x400ae48c 0x0001012a\n\tmww phys 0x400ae410 0x00002400\n\tmww phys 0x400ae450 0x00002400\n\tmww phys 0x400ae490 0x00002400\n\tmww phys 0x400ae4c4 0x00000000\n\tmww phys 0x400ae4c8 0x00001100\n\tmww phys 0x400ae4d0 0x00010101\n\tmww phys 0x400ae000 0x00000601\n}\n\n# clock control init, setting up basic\n# clocks\nproc clock_init { } {\n\t# captured from u-boot\n\tmww phys 0x4006b040 0xffffffff\n\tmww phys 0x4006b044 0xffffffff\n\tmww phys 0x4006b048 0xffffffff\n\tmww phys 0x4006b04c 0xffffffff\n\tmww phys 0x4006b050 0xffffffff\n\tmww phys 0x4006b058 0xffffffff\n\tmww phys 0x4006b05c 0xffffffff\n\tmww phys 0x4006b060 0xffffffff\n\tmww phys 0x4006b064 0xffffffff\n\tmww phys 0x4006b068 0xffffffff\n\tmww phys 0x40050030 0x00002001\n\tmww phys 0x40050270 0x80002001\n\tmww phys 0x4006b000 0x00011005\n\tmww phys 0x4006b008 0x0001ff24\n\tmww phys 0x4006b00c 0x00000810\n\tmww phys 0x4006b010 0x00cc0000\n\tmww phys 0x4006b014 0x01000000\n\tmww phys 0x4006b018 0x20000000\n\tmww phys 0x4006b01c 0x0000001f\n\tmww phys 0x4006b020 0x00000000\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc board_init { } {\n\tclock_init\n\tddr_init\n}\n\n# hook the init function into the reset-init event\n${_TARGETNAME}0 configure -event reset-init { board_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/twr-vf65gs10_cmsisdap.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# CMSIS-DAP via USB-OTG connector\n#\nsource [find interface/cmsis-dap.cfg]\n\n# only SWD is supported by the CMSIS-DAP on this board\ntransport select swd\n\n# Source generic part of twr-vf65gs10 configuration\nsource [find board/twr-vf65gs10.cfg]\n\n# override reset configuration\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/tx25_stk5.cfg",
    "content": "# -------------------------------------------------------------------------\n# KaRo TX25 CPU Module on a StarterkitV base board\n# http://www.karo-electronics.com/tx25.html\n# -------------------------------------------------------------------------\n\n\nsource [find target/imx25.cfg]\n\n\t#-------------------------------------------------------------------------\n\t# Declare Nand\n\t#-------------------------------------------------------------------------\n\n\tnand device K9F1G08UOC mxc imx25.cpu mx25 hwecc biswap\n\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx25_init }\n\n\nproc tx25_init { } {\n\n\t#-------------------------------------------------------------------------\n\t# AIPS setup - Only setup MPROTx registers. The PACR default values are good.\n\t# Set all MPROTx to be non-bufferable, trusted for R/W,\n\t# not forced to user-mode.\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\tsleep 100\n\n\t#-------------------------------------------------------------------------\n\t# MAX (Multi-Layer AHB Crossbar Switch) setup\n\t# MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f04000 0x00043210\n\tmww 0x43f04100 0x00043210\n\tmww 0x43f04200 0x00043210\n\tmww 0x43f04300 0x00043210\n\tmww 0x43f04400 0x00043210\n\n\t# SGPCR - always park on last master\n\tmww 0x43f04010 0x10\n\tmww 0x43f04110 0x10\n\tmww 0x43f04210 0x10\n\tmww 0x43f04310 0x10\n\tmww 0x43f04410 0x10\n\n\t# MGPCR - restore default values\n\tmww 0x43f04800 0x0\n\tmww 0x43f04900 0x0\n\tmww 0x43f04a00 0x0\n\tmww 0x43f04b00 0x0\n\tmww 0x43f04c00 0x0\n\n\t# Configure M3IF registers\n\t# M3IF Control Register (M3IFCTL) for MX25\n\t# MRRP[0] = LCDC           on priority list (1 << 0)  = 0x00000001\n\t# MRRP[1] = MAX1       not on priority list (0 << 1)  = 0x00000000\n\t# MRRP[2] = MAX0       not on priority list (0 << 2)  = 0x00000000\n\t# MRRP[3] = USB HOST   not on priority list (0 << 3)  = 0x00000000\n\t# MRRP[4] = SDMA       not on priority list (0 << 4)  = 0x00000000\n\t# MRRP[5] = SD/ATA/FEC not on priority list (0 << 5)  = 0x00000000\n\t# MRRP[6] = SCMFBC     not on priority list (0 << 6)  = 0x00000000\n\t# MRRP[7] = CSI        not on priority list (0 << 7)  = 0x00000000\n\t#                                                       ----------\n\t#                                                       0x00000001\n\tmww 0xb8003000 0x00000001\n\n\t#-------------------------------------------------------------------------\n\t# configure ARM CLK\n\t#-------------------------------------------------------------------------\n\n\t# Set the Clock CTL (HRM p. 355)\n\tmww 0x53F80008 0x20034000\n\n\t# Setup Clock Gating CTL 0-2 (HRM p. 357)\n\tmww 0x53F8000C 0x1fffffff\n\tmww 0x53F80010 0xffffffff\n\tmww 0x53F80014 0x000fdfff\n\n\t#-------------------------------------------------------------------------\n\t# SDRAM initialization\n\t#-------------------------------------------------------------------------\n\n\t# set to 3.3v SDRAM\n\tmww 0x43FAC454 0x00000800\n\n\t# reset (set up ESDMISC)\n\tmww 0xB8001010 0x00000002\n\n\t# Setup for SDRAM Bank 0\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG0\n\tmww 0xB8001004 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001000 0x92116480\n\tmww 0x80000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001000 0xA2116480\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001000 0xB2116480\n\tmwb 0x80000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001000 0x82116480\n\n\t# Setup for SDRAM Bank 1\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG1\n\tmww 0xB800100C 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001008 0x92116480\n\tmww 0x90000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001008 0xA2116480\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001008 0xB2116480\n\tmwb 0x90000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001008 0x82116480\n\n\t# GPIO configuration\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43FAC02C 0x00000015\n\tmww 0x53FD0000 0x01000000\n\tmww 0x53FD0004 0x00000080\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/tx27_stk5.cfg",
    "content": "# KaRo TX27 CPU Module on a StarterkitV base board\n#\n# http://www.karo-electronics.com/tx27.html\n#\nsource [find target/imx27.cfg]\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx27_init }\n\nproc tx27_init { } {\n\t# This setup puts RAM at 0xA0000000\n\t# init_aipi (AIPI1.PSR0, AIPI2.PSR0, AIPI1.PSR1 and AIPI2.PSR1)\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t#init_max ( PORT0.MPR, #PORT0.AMPR, #PORT1.MPR, #PORT1.AMPR, #PORT2.MPR, #PORT2.AMPR)\n\tmww 0x1003F000 0x00302145\n\tmww 0x1003F004 0x00302145\n\tmww 0x1003F100 0x00302145\n\tmww 0x1003F104 0x00302145\n\tmww 0x1003F200 0x00302145\n\tmww 0x1003F204 0x00302145\n\n\t#init_drive_strength (#DSCR3, #DSCR5, #DSCR6, #DSCR7, #DSCR8 )\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\t#init_sdram_speed\n\t#mww 0xD8001010 0x00000004\n\tmww 0xD8001010 0x00000024\n\n\tmww 0xD8001004 0x00395729\n\n\tmww 0xD8001000 0x92120000\n\tmww 0xA0000400 0x0\n\n\tmww 0xD8001000 0xA2120000\n\tmww 0xA0000000 0x0\n\tmww 0xA0000000 0x0\n\n\tmww 0xD8001000 0xB2120000\n\tmdb 0xA0000000\n\tmdb 0xA0000033\n\n\tmww 0xD8001000 0x82126485\n\n\t# =============================================\n\t# Sync mode (AHB Clk = 133MHz ; BCLK = 44.3MHz)\n\t# =============================================\n\tmww 0xD8002000 0x23524E80\n\tmww 0xD8002004 0x10000D03\n\tmww 0xD8002008 0x00720900\n\n\tnand probe 0\n}\n\nnand device tx27.nand mxc $_TARGETNAME mx27 hwecc biswap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/unknown_at91sam9260.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n#\n# Unknown vendor board contains:\n#\n# Atmel AT91SAM9260 : PLLA = 192.512MHz, MCK = 96.256 MHz\n#                     OSCSEL configured for internal RC oscillator (22 to 42 kHz)\n#\n# 16-bit NOR FLASH : Intel JS28F128P30T85 128MBit\n# 32-bit SDRAM : 2 x Samsung K4S561632H-UC75, 4M x 16Bit x 4 Banks\n##################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 22 to 42 kHz.\n        # JTAG Frequency must be 6 times slower.\n        jtag_rclk 3\n        halt\n\t# RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x205dbf09         ;# CKGR_PLLAR: Set PLLA Register for 192.512MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (96.256 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xffffec00 0x01020102         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x09070806         ;# SMC_PULSE0\n\tmww 0xffffec08 0x000d000b         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00001003         ;# SMC_MODE0\n\n\tflash probe 0                     ;# Identify flash bank 0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n        mww 0xfffff860 0xffff0000         ;# PIO_PUDR : Disable D15..D31 pull-ups\n\n        mww 0xffffef1c 0x00010102         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM\n                                           #            VDDIOMSEL set for +3V3 memory\n                                           #            Disable D0..D15 pull-ups\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2a2              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/uptech_2410.cfg",
    "content": "# Target Configuration for the Uptech 2410 board.\n# This configuration should also work on smdk2410, but I haven't tested it yet.\n# Author: xionglingfeng@Gmail.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init { uptech2410_init }\n$_TARGETNAME configure -event gdb-attach { reset init }\n\nproc init_pll_sdram { } {\n\t#echo \"---------- Initializing PLL and SDRAM ---------\"\n\t#watchdog timer disable\n\tmww phys 0x53000000 0x00000000\n\n\t#disable all interrupts\n\tmww phys 0x4a000008 0xffffffff\n\n\t#disable all sub-interrupts\n\tmww phys 0x4a00001c 0x000007ff\n\n\t#clear all source pending bits\n\tmww phys 0x4a000000 0xffffffff\n\n\t#clear all sub-source pending bits\n\tmww phys 0x4a000018 0x000007ff\n\n\t#clear interrupt pending bit\n\tmww phys 0x4a000010 0xffffffff\n\n\t#PLL locktime counter\n\tmww phys 0x4c000000 0x00ffffff\n\n\t#Fin=12MHz Fout=202.8MHz\n\t#mww phys 0x4c000004 0x000a1031\n\n\t#FCLK:HCLK:PCLK = 1:2:4\n\tmww phys 0x4c000014 0x00000003\n\n\n\tmww phys 0x48000000 0x11111110\n\tmww phys 0x48000004 0x00007FFC\n\tmww phys 0x48000008 0x00007FFC\n\tmww phys 0x4800000c 0x00000700\n\tmww phys 0x48000010 0x00000700\n\tmww phys 0x48000014 0x00002E50\n\tmww phys 0x48000018 0x00002E50\n\tmww phys 0x4800001c 0x00018005\n\tmww phys 0x48000020 0x00018005\n\tmww phys 0x48000024 0x008c04e9\n\tmww phys 0x48000028 0x000000b2\n\tmww phys 0x4800002c 0x00000030\n\tmww phys 0x48000030 0x00000030\n}\n\nproc uptech2410_init { } {\n\tinit_pll_sdram\n\t#echo \"---------- Probing Nand flash ----------\"\n\tnand probe 0\n\t#echo \"---------- Enable some functions ----------\"\n}\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME s3c2410 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/vd_a53x2_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex A53x2 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CORES 2\nset _CHIPNAME a53\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x1000000\nset _CPUTAPID 0x5ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_aarch64.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/vd_m4_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m4 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m4\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\nset _CPUTAPID 0x4ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 25000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 20ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/vd_pulpissimo_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV Ibex core with Pulpissimo through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME ibex\nset _HARTID 0x20\nset _CPUTAPID 0x249511c3\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 12500\nadapter srst delay 10\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 40ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[0\\].sram_i.mem_array 0x1c000000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[1\\].sram_i.mem_array 0x1c008000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2\\[0\\].sram_i.mem_array 0x1c010000 0x80000\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x05 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/vd_swerv_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV swerv core with Swerv through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME rv32\nset _HARTID 0x00\nset _CPUTAPID 0x1000008b\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.i_ahb_ic.mem $_MEMSTART $_MEMSIZE\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/verdex.cfg",
    "content": "# Config for Gumstix Verdex XM4 and XL6P (PXA270)\n\nset CHIPNAME verdex\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz\nadapter speed 40000\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n# XL6P has 32 MB flash\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x02000000 2 2 $_TARGETNAME\n# XM4 has 16 MB flash\n#flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/voipac.cfg",
    "content": "# Config for Voipac PXA270/PXA270M module.\n\nset CHIPNAME voipac\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\nflash bank $_CHIPNAME.flash1 cfi 0x02000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/voltcraft_dso-3062c.cfg",
    "content": "#\n# Voltcraft DSO-3062C digital oscilloscope (uses a Samsung S3C2440)\n#\n# http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/\n# http://www.mikrocontroller.net/topic/249628\n# http://elinux.org/Das_Oszi\n# http://randomprojects.org/wiki/Voltcraft_DSO-3062C\n#\n\n# Enable this if your JTAG adapter supports multiple transports (JTAG or SWD).\n# Otherwise comment it out, as it will cause an OpenOCD error.\n### transport select jtag\n\nsource [find target/samsung_s3c2440.cfg]\n\nadapter speed 16000\n\n# Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit)\nnand device $_CHIPNAME.nand s3c2440 $_TARGETNAME\n\n# arm7_9 fast_memory_access enable\n# arm7_9 dcc_downloads enable\n\ninit\nreset\nhalt\nscan_chain\ntargets\nnand probe 0\nnand list\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/x300t.cfg",
    "content": "# This is for the T-Home X300T / X301T IPTV box,\n# which are based on IPTV reference designs from Kiss/Cisco KMM-3***\n#\n# It has Sigma Designs SMP8634 chip.\nsource [find target/smp8634.cfg]\n\n$_TARGETNAME configure -event reset-init { x300t_init }\n\n# 1MB CFI capable flash\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xac000000 0x100000 2 2 $_TARGETNAME\n\nproc x300t_init { } {\n\t# Setup SDRAM config and flash mapping\n\t# initialize ram\n\tmww 0xa003fffc 3\n\tmww 0xa003fffc 2\n\tmww 0xa0030000 0xE34111BA\n\tmww 0xa003fffc 0xa4444\n\tmww 0xa003fffc 0\n\n\t# remap boot vector in CPU local RAM\n\tmww 0xa006f000 0x60000\n\n\t# map flash to CPU address space REG_BASE_cpu_block+CPU_remap4\n\tmww 0x0006f010 0x48000000\n\n\t# map flash addr to REG_BASE_cpu_block + LR_XENV_LOCATION (normally done by XOS)\n\tmww 0x00061ff0 0x48000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc-2go.cfg",
    "content": "#\n# Infineon XMC 2Go\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc1100-boot-kit.cfg",
    "content": "#\n# Infineon XMC1100 Boot Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4200-application-kit-actuator.cfg",
    "content": "#\n# Infineon XMC4200 Application Kit - Actuator\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4200\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4300-relax.cfg",
    "content": "#\n# Infineon XMC4300 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4300\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4500-application-kit-general.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - General Purpose\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4500-application-kit-sdram.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - SDRAM\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4500-relax.cfg",
    "content": "#\n# Infineon XMC4500 Relax Kit / Relax Lite Kit\n#\n\n#\n# Segger J-Link Lite XMC4500 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4700-relax.cfg",
    "content": "#\n# Infineon XMC4700 Relax Lite Kit / Relax Kit for 5V Shields / Relax Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4700\nsource [find target/xmc4xxx.cfg]\n\n# Relax Kit only: N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmc4800-relax.cfg",
    "content": "#\n# Infineon XMC4800 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4800\nsource [find target/xmc4xxx.cfg]\n\n# N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/board/xmos_xk-xac-xa8_arm.cfg",
    "content": "#\n# xCORE-XA Core Module\n#\n# https://www.xmos.com/support/boards?product=17940\n#\n\n#\n# J-Link OB STM32F103\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n#\n# XS1-XAU8A-10\n#\nsource [find target/xmos_xs1-xau8a-10_arm.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/aic.tcl",
    "content": "set AIC_SMR      \t[expr {$AT91C_BASE_AIC + 0x00000000} ]\nglobal AIC_SMR\nset AIC_SVR      \t[expr {$AT91C_BASE_AIC + 0x00000080} ]\nglobal AIC_SVR\nset AIC_IVR      \t[expr {$AT91C_BASE_AIC + 0x00000100} ]\nglobal AIC_IVR\nset AIC_FVR      \t[expr {$AT91C_BASE_AIC + 0x00000104} ]\nglobal AIC_FVR\nset AIC_ISR      \t[expr {$AT91C_BASE_AIC + 0x00000108} ]\nglobal AIC_ISR\nset AIC_IPR      \t[expr {$AT91C_BASE_AIC + 0x0000010C} ]\nglobal AIC_IPR\nset AIC_IMR      \t[expr {$AT91C_BASE_AIC + 0x00000110} ]\nglobal AIC_IMR\nset AIC_CISR     \t[expr {$AT91C_BASE_AIC + 0x00000114} ]\nglobal AIC_CISR\nset AIC_IECR     \t[expr {$AT91C_BASE_AIC + 0x00000120} ]\nglobal AIC_IECR\nset AIC_IDCR     \t[expr {$AT91C_BASE_AIC + 0x00000124} ]\nglobal AIC_IDCR\nset AIC_ICCR     \t[expr {$AT91C_BASE_AIC + 0x00000128} ]\nglobal AIC_ICCR\nset AIC_ISCR     \t[expr {$AT91C_BASE_AIC + 0x0000012C} ]\nglobal AIC_ISCR\nset AIC_EOICR    \t[expr {$AT91C_BASE_AIC + 0x00000130} ]\nglobal AIC_EOICR\nset AIC_SPU      \t[expr {$AT91C_BASE_AIC + 0x00000134} ]\nglobal AIC_SPU\nset AIC_DCR      \t[expr {$AT91C_BASE_AIC + 0x00000138} ]\nglobal AIC_DCR\nset AIC_FFER     \t[expr {$AT91C_BASE_AIC + 0x00000140} ]\nglobal AIC_FFER\nset AIC_FFDR     \t[expr {$AT91C_BASE_AIC + 0x00000144} ]\nglobal AIC_FFDR\nset AIC_FFSR     \t[expr {$AT91C_BASE_AIC + 0x00000148} ]\nglobal AIC_FFSR\n\n\nproc aic_enable_disable_list { VAL ENAME DNAME } {\n    global AT91C_ID\n\n    show_mmr32_bits AT91C_ID $VAL\n\n}\n\nproc show_AIC_IPR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ PENDING\" \"irq not-pending\"\n}\n\nproc show_AIC_IMR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ ENABLED\" \"irq disabled\"\n}\n\n\nproc show_AIC { } {\n    global AIC_SMR\n    if [catch { set aaa [read_memory $AIC_SMR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SMR]\n    }\n    echo \"AIC_SMR: Mode & Type\"\n    global AT91C_ID\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo  [format \"%2d: %5s 0x%08x\"  $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n    global AIC_SVR\n    if [catch { set aaa [read_memory $AIC_SVR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SVR]\n    }\n    echo \"AIC_SVR: Vectors\"\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo [format \"%2d: %5s 0x%08x\" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n\n    foreach REG {\n\tAIC_IVR   AIC_FVR  AIC_ISR\n\tAIC_IPR  AIC_IMR  AIC_CISR  AIC_IECR AIC_IDCR\n\tAIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU  AIC_DCR\n\tAIC_FFER AIC_FFDR AIC_FFSR } {\n\tif [catch { show_mmr32_reg $REG } msg ] {\n\t    error $msg\n\t    break\n\t}\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91_pio.cfg",
    "content": "set PIO_PER\t0x00\t;# Enable Register\nset PIO_PDR\t0x04\t;# Disable Register\nset PIO_PSR\t0x08\t;# Status Register\nset PIO_OER\t0x10\t;# Output Enable Register\nset PIO_ODR\t0x14\t;# Output Disable Register\nset PIO_OSR\t0x18\t;# Output Status Register\nset PIO_IFER\t0x20\t;# Glitch Input Filter Enable\nset PIO_IFDR\t0x24\t;# Glitch Input Filter Disable\nset PIO_IFSR\t0x28\t;# Glitch Input Filter Status\nset PIO_SODR\t0x30\t;# Set Output Data Register\nset PIO_CODR\t0x34\t;# Clear Output Data Register\nset PIO_ODSR\t0x38\t;# Output Data Status Register\nset PIO_PDSR\t0x3c\t;# Pin Data Status Register\nset PIO_IER\t0x40\t;# Interrupt Enable Register\nset PIO_IDR\t0x44\t;# Interrupt Disable Register\nset PIO_IMR\t0x48\t;# Interrupt Mask Register\nset PIO_ISR\t0x4c\t;# Interrupt Status Register\nset PIO_MDER\t0x50\t;# Multi-driver Enable Register\nset PIO_MDDR\t0x54\t;# Multi-driver Disable Register\nset PIO_MDSR\t0x58\t;# Multi-driver Status Register\nset PIO_PUDR\t0x60\t;# Pull-up Disable Register\nset PIO_PUER\t0x64\t;# Pull-up Enable Register\nset PIO_PUSR\t0x68\t;# Pull-up Status Register\nset PIO_ASR\t0x70\t;# Peripheral A Select Register\nset PIO_BSR\t0x74\t;# Peripheral B Select Register\nset PIO_ABSR\t0x78\t;# AB Status Register\nset PIO_OWER\t0xa0\t;# Output Write Enable Register\nset PIO_OWDR\t0xa4\t;# Output Write Disable Register\nset PIO_OWSR\t0xa8\t;# Output Write Status Register\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91_pmc.cfg",
    "content": "set\tAT91_PMC_SCER\t\t[expr {$AT91_PMC + 0x00}]\t;# System Clock Enable Register\nset\tAT91_PMC_SCDR\t\t[expr {$AT91_PMC + 0x04}]\t;# System Clock Disable Register\n\nset\tAT91_PMC_SCSR\t\t[expr {$AT91_PMC + 0x08}]\t;# System Clock Status Register\nset\t\tAT91_PMC_PCK\t\t[expr {1 <<  0}]\t\t;# Processor Clock\nset\t\tAT91RM9200_PMC_UDP\t[expr {1 <<  1}]\t\t;# USB Devcice Port Clock [AT91RM9200 only]\nset\t\tAT91RM9200_PMC_MCKUDP\t[expr {1 <<  2}]\t\t;# USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only]\nset\t\tAT91CAP9_PMC_DDR\t[expr {1 <<  2}]\t\t;# DDR Clock [CAP9 revC & some SAM9 only]\nset\t\tAT91RM9200_PMC_UHP\t[expr {1 <<  4}]\t\t;# USB Host Port Clock [AT91RM9200 only]\nset\t\tAT91SAM926x_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91SAM926x only]\nset\t\tAT91CAP9_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91CAP9 only]\nset\t\tAT91SAM926x_PMC_UDP\t[expr {1 <<  7}]\t\t;# USB Devcice Port Clock [AT91SAM926x only]\nset\t\tAT91_PMC_PCK0\t\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1\t\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2\t\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3\t\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\t\tAT91_PMC_HCK0\t\t[expr {1 << 16}]\t\t;# AHB Clock (USB host) [AT91SAM9261 only]\nset\t\tAT91_PMC_HCK1\t\t[expr {1 << 17}]\t\t;# AHB Clock (LCD) [AT91SAM9261 only]\n\nset\tAT91_PMC_PCER\t\t[expr {$AT91_PMC + 0x10}]\t;# Peripheral Clock Enable Register\nset\tAT91_PMC_PCDR\t\t[expr {$AT91_PMC + 0x14}]\t;# Peripheral Clock Disable Register\nset\tAT91_PMC_PCSR\t\t[expr {$AT91_PMC + 0x18}]\t;# Peripheral Clock Status Register\n\nset\tAT91_CKGR_UCKR\t\t[expr {$AT91_PMC + 0x1C}]\t;# UTMI Clock Register [some SAM9, CAP9]\nset\t\tAT91_PMC_UPLLEN\t\t[expr {1   << 16}]\t\t;# UTMI PLL Enable\nset\t\tAT91_PMC_UPLLCOUNT\t[expr {0xf << 20}]\t\t;# UTMI PLL Start-up Time\nset\t\tAT91_PMC_BIASEN\t\t[expr {1   << 24}]\t\t;# UTMI BIAS Enable\nset\t\tAT91_PMC_BIASCOUNT\t[expr {0xf << 28}]\t\t;# UTMI BIAS Start-up Time\n\nset\tAT91_CKGR_MOR\t\t[expr {$AT91_PMC + 0x20}]\t;# Main Oscillator Register [not on SAM9RL]\nset\t\tAT91_PMC_MOSCEN\t\t[expr {1    << 0}]\t\t;# Main Oscillator Enable\nset\t\tAT91_PMC_OSCBYPASS\t[expr {1    << 1}]\t\t;# Oscillator Bypass [SAM9x, CAP9]\nset\t\tAT91_PMC_OSCOUNT\t[expr {0xff << 8}]\t\t;# Main Oscillator Start-up Time\n\nset\tAT91_CKGR_MCFR\t\t[expr {$AT91_PMC + 0x24}]\t;# Main Clock Frequency Register\nset\t\tAT91_PMC_MAINF\t\t[expr {0xffff <<  0}]\t\t;# Main Clock Frequency\nset\t\tAT91_PMC_MAINRDY\t[expr {1\t<< 16}]\t\t;# Main Clock Ready\n\nset\tAT91_CKGR_PLLAR\t\t[expr {$AT91_PMC + 0x28}]\t;# PLL A Register\nset\tAT91_CKGR_PLLBR\t\t[expr {$AT91_PMC + 0x2c}]\t;# PLL B Register\nset\t\tAT91_PMC_DIV\t\t[expr {0xff  <<  0}]\t\t;# Divider\nset\t\tAT91_PMC_PLLCOUNT\t[expr {0x3f  <<  8}]\t\t;# PLL Counter\nset\t\tAT91_PMC_OUT\t\t[expr {3     << 14}]\t\t;# PLL Clock Frequency Range\nset\t\tAT91_PMC_MUL\t\t[expr {0x7ff << 16}]\t\t;# PLL Multiplier\nset\t\tAT91_PMC_USBDIV\t\t[expr {3     << 28}]\t\t;# USB Divisor (PLLB only)\nset\t\t\tAT91_PMC_USBDIV_1\t\t[expr {0 << 28}]\nset\t\t\tAT91_PMC_USBDIV_2\t\t[expr {1 << 28}]\nset\t\t\tAT91_PMC_USBDIV_4\t\t[expr {2 << 28}]\nset\t\tAT91_PMC_USB96M\t\t[expr {1     << 28}]\t\t;# Divider by 2 Enable (PLLB only)\nset\t\tAT91_PMC_PLLA_WR_ERRATA\t[expr {1     << 29}]\t\t;# Bit 29 must always be set to 1 when programming the CKGR_PLLAR register\n\nset\tAT91_PMC_MCKR\t\t[expr {$AT91_PMC + 0x30}]\t;# Master Clock Register\nset\t\tAT91_PMC_CSS\t\t[expr {3 <<  0}]\t\t;# Master Clock Selection\nset\t\t\tAT91_PMC_CSS_SLOW\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_CSS_MAIN\t\t[expr {1 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLA\t\t[expr {2 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLB\t\t[expr {3 << 0}]\nset\t\t\tAT91_PMC_CSS_UPLL\t\t[expr {3 << 0}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PRES\t\t[expr {7 <<  2}]\t\t;# Master Clock Prescaler\nset\t\t\tAT91_PMC_PRES_1\t\t\t[expr {0 << 2}]\nset\t\t\tAT91_PMC_PRES_2\t\t\t[expr {1 << 2}]\nset\t\t\tAT91_PMC_PRES_4\t\t\t[expr {2 << 2}]\nset\t\t\tAT91_PMC_PRES_8\t\t\t[expr {3 << 2}]\nset\t\t\tAT91_PMC_PRES_16\t\t[expr {4 << 2}]\nset\t\t\tAT91_PMC_PRES_32\t\t[expr {5 << 2}]\nset\t\t\tAT91_PMC_PRES_64\t\t[expr {6 << 2}]\nset\t\tAT91_PMC_MDIV\t\t[expr {3 <<  8}]\t\t;# Master Clock Division\nset\t\t\tAT91RM9200_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [AT91RM9200 only]\nset\t\t\tAT91RM9200_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_3\t\t[expr {2 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_4\t\t[expr {3 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [SAM9,CAP9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_4\t\t[expr {2 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_6\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_3\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PDIV\t\t[expr {1 << 12}]\t\t;# Processor Clock Division [some SAM9 only]\nset\t\t\tAT91_PMC_PDIV_1\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PDIV_2\t\t\t[expr {1 << 12}]\nset\t\tAT91_PMC_PLLADIV2\t[expr {1 << 12}]\t\t;# PLLA divisor by 2 [some SAM9 only]\nset\t\t\tAT91_PMC_PLLADIV2_OFF\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PLLADIV2_ON\t\t[expr {1 << 12}]\n\nset\tAT91_PMC_USB\t\t[expr {$AT91_PMC + 0x38}]\t;# USB Clock Register [some SAM9 only]\nset\t\tAT91_PMC_USBS\t\t[expr {0x1 <<  0}]\t\t;# USB OHCI Input clock selection\nset\t\t\tAT91_PMC_USBS_PLLA\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_USBS_UPLL\t\t[expr {1 << 0}]\nset\t\tAT91_PMC_OHCIUSBDIV\t[expr {0xF <<  8}]\t\t;# Divider for USB OHCI Clock\n\n;# set\tAT91_PMC_PCKR(n)\t[expr {$AT91_PMC + 0x40 + ((n) * 4)}]\t;# Programmable Clock 0-N Registers\nset\t\tAT91_PMC_CSSMCK\t\t[expr {0x1 <<  8}]\t\t;# CSS or Master Clock Selection\nset\t\t\tAT91_PMC_CSSMCK_CSS\t\t[expr {0 << 8}]\nset\t\t\tAT91_PMC_CSSMCK_MCK\t\t[expr {1 << 8}]\n\nset\tAT91_PMC_IER\t\t[expr {$AT91_PMC + 0x60}]\t;# Interrupt Enable Register\nset\tAT91_PMC_IDR\t\t[expr {$AT91_PMC + 0x64}]\t;# Interrupt Disable Register\nset\tAT91_PMC_SR\t\t[expr {$AT91_PMC + 0x68}]\t;# Status Register\nset\t\tAT91_PMC_MOSCS\t\t[expr {1 <<  0}]\t\t;# MOSCS Flag\nset\t\tAT91_PMC_LOCKA\t\t[expr {1 <<  1}]\t\t;# PLLA Lock\nset\t\tAT91_PMC_LOCKB\t\t[expr {1 <<  2}]\t\t;# PLLB Lock\nset\t\tAT91_PMC_MCKRDY\t\t[expr {1 <<  3}]\t\t;# Master Clock\nset\t\tAT91_PMC_LOCKU\t\t[expr {1 <<  6}]\t\t;# UPLL Lock [some SAM9, AT91CAP9 only]\nset\t\tAT91_PMC_OSCSEL\t\t[expr {1 <<  7}]\t\t;# Slow Clock Oscillator [AT91CAP9 revC only]\nset\t\tAT91_PMC_PCK0RDY\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1RDY\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2RDY\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3RDY\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\tAT91_PMC_IMR\t\t[expr {$AT91_PMC + 0x6c}]\t;# Interrupt Mask Register\n\nset AT91_PMC_PROT\t\t[expr {$AT91_PMC + 0xe4}]\t;# Protect Register [AT91CAP9 revC only]\nset\t\tAT91_PMC_PROTKEY\t0x504d4301\t;# Activation Code\n\nset AT91_PMC_VER\t\t[expr {$AT91_PMC + 0xfc}]\t;# PMC Module Version [AT91CAP9 only]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91_rstc.cfg",
    "content": "set AT91_RSTC_CR\t\t[expr {$AT91_RSTC + 0x00}]\t;# Reset Controller Control Register\nset\t\tAT91_RSTC_PROCRST\t[expr {1 << 0}]\t\t;# Processor Reset\nset\t\tAT91_RSTC_PERRST\t[expr {1 << 2}]\t\t;# Peripheral Reset\nset\t\tAT91_RSTC_EXTRST\t[expr {1 << 3}]\t\t;# External Reset\nset\t\tAT91_RSTC_KEY\t\t[expr {0xa5 << 24}]\t\t;# KEY Password\n\nset AT91_RSTC_SR\t\t[expr {$AT91_RSTC + 0x04}]\t;# Reset Controller Status Register\nset\t\tAT91_RSTC_URSTS\t\t[expr {1 << 0}]\t\t;# User Reset Status\nset\t\tAT91_RSTC_RSTTYP\t[expr {7 << 8}]\t\t;# Reset Type\nset\t\t\tAT91_RSTC_RSTTYP_GENERAL\t[expr {0 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WAKEUP\t\t[expr {1 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WATCHDOG\t[expr {2 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_SOFTWARE\t[expr {3 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_USER\t[expr {4 << 8}]\nset\t\tAT91_RSTC_NRSTL\t\t[expr {1 << 16}]\t\t;# NRST Pin Level\nset\t\tAT91_RSTC_SRCMP\t\t[expr {1 << 17}]\t\t;# Software Reset Command in Progress\n\nset AT91_RSTC_MR\t\t[expr {$AT91_RSTC + 0x08}]\t;# Reset Controller Mode Register\nset\t\tAT91_RSTC_URSTEN\t[expr {1 << 0}]\t\t;# User Reset Enable\nset\t\tAT91_RSTC_URSTIEN\t[expr {1 << 4}]\t\t;# User Reset Interrupt Enable\nset\t\tAT91_RSTC_ERSTL\t\t[expr {0xf << 8}]\t\t;# External Reset Length\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91_wdt.cfg",
    "content": "set AT91_WDT_CR\t\t[expr {$AT91_WDT + 0x00}]\t;# Watchdog Control Register\nset\t\tAT91_WDT_WDRSTT\t\t[expr {1    << 0}]\t;# Restart\nset\t\tAT91_WDT_KEY\t\t[expr {0xa5 << 24}]\t;# KEY Password\n\nset AT91_WDT_MR\t\t[expr {$AT91_WDT + 0x04}]\t;# Watchdog Mode Register\nset\t\tAT91_WDT_WDV\t\t[expr {0xfff << 0}]\t;# Counter Value\nset\t\tAT91_WDT_WDFIEN\t\t[expr {1     << 12}]\t;# Fault Interrupt Enable\nset\t\tAT91_WDT_WDRSTEN\t[expr {1     << 13}]\t;# Reset Processor\nset\t\tAT91_WDT_WDRPROC\t[expr {1     << 14}]\t;# Timer Restart\nset\t\tAT91_WDT_WDDIS\t\t[expr {1     << 15}]\t;# Watchdog Disable\nset\t\tAT91_WDT_WDD\t\t[expr {0xfff << 16}]\t;# Delta Value\nset\t\tAT91_WDT_WDDBGHLT\t[expr {1     << 28}]\t;# Debug Halt\nset\t\tAT91_WDT_WDIDLEHLT\t[expr {1     << 29}]\t;# Idle Halt\n\nset AT91_WDT_SR\t\t[expr {$AT91_WDT + 0x08}]\t;# Watchdog Status Register\nset\t\tAT91_WDT_WDUNF\t\t[expr {1 << 0}]\t\t;# Watchdog Underflow\nset\t\tAT91_WDT_WDERR\t\t[expr {1 << 1}]\t\t;# Watchdog Error\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam7x128.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x128\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__128K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__32K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\n\n\n\nset AT91C_BASE_SYS       0xFFFFF000\nset AT91C_BASE_AIC       0xFFFFF000\nset AT91C_BASE_PDC_DBGU  0xFFFFF300\nset AT91C_BASE_DBGU      0xFFFFF200\nset AT91C_BASE_PIOA      0xFFFFF400\nset AT91C_BASE_PIOB      0xFFFFF600\nset AT91C_BASE_CKGR      0xFFFFFC20\nset AT91C_BASE_PMC       0xFFFFFC00\nset AT91C_BASE_RSTC      0xFFFFFD00\nset AT91C_BASE_RTTC      0xFFFFFD20\nset AT91C_BASE_PITC      0xFFFFFD30\nset AT91C_BASE_WDTC      0xFFFFFD40\nset AT91C_BASE_VREG      0xFFFFFD60\nset AT91C_BASE_MC        0xFFFFFF00\nset AT91C_BASE_PDC_SPI1  0xFFFE4100\nset AT91C_BASE_SPI1      0xFFFE4000\nset AT91C_BASE_PDC_SPI0  0xFFFE0100\nset AT91C_BASE_SPI0      0xFFFE0000\nset AT91C_BASE_PDC_US1   0xFFFC4100\nset AT91C_BASE_US1       0xFFFC4000\nset AT91C_BASE_PDC_US0   0xFFFC0100\nset AT91C_BASE_US0       0xFFFC0000\nset AT91C_BASE_PDC_SSC   0xFFFD4100\nset AT91C_BASE_SSC       0xFFFD4000\nset AT91C_BASE_TWI       0xFFFB8000\nset AT91C_BASE_PWMC_CH3  0xFFFCC260\nset AT91C_BASE_PWMC_CH2  0xFFFCC240\nset AT91C_BASE_PWMC_CH1  0xFFFCC220\nset AT91C_BASE_PWMC_CH0  0xFFFCC200\nset AT91C_BASE_PWMC      0xFFFCC000\nset AT91C_BASE_UDP       0xFFFB0000\nset AT91C_BASE_TC0       0xFFFA0000\nset AT91C_BASE_TC1       0xFFFA0040\nset AT91C_BASE_TC2       0xFFFA0080\nset AT91C_BASE_TCB       0xFFFA0000\nset AT91C_BASE_CAN_MB0   0xFFFD0200\nset AT91C_BASE_CAN_MB1   0xFFFD0220\nset AT91C_BASE_CAN_MB2   0xFFFD0240\nset AT91C_BASE_CAN_MB3   0xFFFD0260\nset AT91C_BASE_CAN_MB4   0xFFFD0280\nset AT91C_BASE_CAN_MB5   0xFFFD02A0\nset AT91C_BASE_CAN_MB6   0xFFFD02C0\nset AT91C_BASE_CAN_MB7   0xFFFD02E0\nset AT91C_BASE_CAN       0xFFFD0000\nset AT91C_BASE_EMAC      0xFFFDC000\nset AT91C_BASE_PDC_ADC   0xFFFD8100\nset AT91C_BASE_ADC       0xFFFD8000\n\nset AT91C_ID(0) FIQ\nset AT91C_ID(1) SYS\nset AT91C_ID(2) PIOA\nset AT91C_ID(3) PIOB\nset AT91C_ID(4) SPI0\nset AT91C_ID(5) SPI1\nset AT91C_ID(6) US0\nset AT91C_ID(7) US1\nset AT91C_ID(8) SSC\nset AT91C_ID(9) TWI\nset AT91C_ID(10) PWMC\nset AT91C_ID(11) UDP\nset AT91C_ID(12) TC0\nset AT91C_ID(13) TC1\nset AT91C_ID(14) TC2\nset AT91C_ID(15) CAN\nset AT91C_ID(16) EMAC\nset AT91C_ID(17) ADC\nset AT91C_ID(18) \"\"\nset AT91C_ID(19) \"\"\nset AT91C_ID(20) \"\"\nset AT91C_ID(21) \"\"\nset AT91C_ID(22) \"\"\nset AT91C_ID(23) \"\"\nset AT91C_ID(24) \"\"\nset AT91C_ID(25) \"\"\nset AT91C_ID(26) \"\"\nset AT91C_ID(27) \"\"\nset AT91C_ID(28) \"\"\nset AT91C_ID(29) \"\"\nset AT91C_ID(30) IRQ0\nset AT91C_ID(31) IRQ1\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam7x256.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x256\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__256K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__64K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\nset  AT91C_BASE_SYS              0xFFFFF000\nset  AT91C_BASE_AIC              0xFFFFF000\nset  AT91C_BASE_PDC_DBGU         0xFFFFF300\nset  AT91C_BASE_DBGU             0xFFFFF200\nset  AT91C_BASE_PIOA             0xFFFFF400\nset  AT91C_BASE_PIOB             0xFFFFF600\nset  AT91C_BASE_CKGR             0xFFFFFC20\nset  AT91C_BASE_PMC              0xFFFFFC00\nset  AT91C_BASE_RSTC             0xFFFFFD00\nset  AT91C_BASE_RTTC             0xFFFFFD20\nset  AT91C_BASE_PITC             0xFFFFFD30\nset  AT91C_BASE_WDTC             0xFFFFFD40\nset  AT91C_BASE_VREG             0xFFFFFD60\nset  AT91C_BASE_MC          0xFFFFFF00\nset  AT91C_BASE_PDC_SPI1      0xFFFE4100\nset  AT91C_BASE_SPI1          0xFFFE4000\nset  AT91C_BASE_PDC_SPI0      0xFFFE0100\nset  AT91C_BASE_SPI0          0xFFFE0000\nset  AT91C_BASE_PDC_US1       0xFFFC4100\nset  AT91C_BASE_US1           0xFFFC4000\nset  AT91C_BASE_PDC_US0       0xFFFC0100\nset  AT91C_BASE_US0           0xFFFC0000\nset  AT91C_BASE_PDC_SSC       0xFFFD4100\nset  AT91C_BASE_SSC           0xFFFD4000\nset  AT91C_BASE_TWI           0xFFFB8000\nset  AT91C_BASE_PWMC_CH3      0xFFFCC260\nset  AT91C_BASE_PWMC_CH2      0xFFFCC240\nset  AT91C_BASE_PWMC_CH1      0xFFFCC220\nset  AT91C_BASE_PWMC_CH0      0xFFFCC200\nset  AT91C_BASE_PWMC          0xFFFCC000\nset  AT91C_BASE_UDP           0xFFFB0000\nset  AT91C_BASE_TC0         0xFFFA0000\nset  AT91C_BASE_TC1         0xFFFA0040\nset  AT91C_BASE_TC2         0xFFFA0080\nset  AT91C_BASE_TCB             0xFFFA0000\nset  AT91C_BASE_CAN_MB0         0xFFFD0200\nset  AT91C_BASE_CAN_MB1         0xFFFD0220\nset  AT91C_BASE_CAN_MB2         0xFFFD0240\nset  AT91C_BASE_CAN_MB3         0xFFFD0260\nset  AT91C_BASE_CAN_MB4         0xFFFD0280\nset  AT91C_BASE_CAN_MB5         0xFFFD02A0\nset  AT91C_BASE_CAN_MB6         0xFFFD02C0\nset  AT91C_BASE_CAN_MB7         0xFFFD02E0\nset  AT91C_BASE_CAN             0xFFFD0000\nset  AT91C_BASE_EMAC            0xFFFDC000\nset  AT91C_BASE_PDC_ADC         0xFFFD8100\nset  AT91C_BASE_ADC             0xFFFD8000\n\nset AT91C_ID(0)   \"FIQ\"\nset AT91C_ID(1)   \"SYS\"\nset AT91C_ID(2)   \"PIOA\"\nset AT91C_ID(3)   \"PIOB\"\nset AT91C_ID(4)   \"SPI0\"\nset AT91C_ID(5)   \"SPI1\"\nset AT91C_ID(6)   \"US0\"\nset AT91C_ID(7)   \"US1\"\nset AT91C_ID(8)   \"SSC\"\nset AT91C_ID(9)   \"TWI\"\nset AT91C_ID(10)   \"PWMC\"\nset AT91C_ID(11)   \"UDP\"\nset AT91C_ID(12)   \"TC0\"\nset AT91C_ID(13)   \"TC1\"\nset AT91C_ID(14)   \"TC2\"\nset AT91C_ID(15)   \"CAN\"\nset AT91C_ID(16)   \"EMAC\"\nset AT91C_ID(17)   \"ADC\"\nset AT91C_ID(18)   \"\"\nset AT91C_ID(19)   \"\"\nset AT91C_ID(20)   \"\"\nset AT91C_ID(21)   \"\"\nset AT91C_ID(22)   \"\"\nset AT91C_ID(23)   \"\"\nset AT91C_ID(24)   \"\"\nset AT91C_ID(25)   \"\"\nset AT91C_ID(26)   \"\"\nset AT91C_ID(27)   \"\"\nset AT91C_ID(28)   \"\"\nset AT91C_ID(29)   \"\"\nset AT91C_ID(30)   \"IRQ0\"\nset AT91C_ID(31)   \"IRQ1\"\n\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9261.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9261_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9261_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9261_ID_PIOC\t4\t;# Parallel IO Controller C\nset AT91SAM9261_ID_US0\t6\t;# USART 0\nset AT91SAM9261_ID_US1\t7\t;# USART 1\nset AT91SAM9261_ID_US2\t8\t;# USART 2\nset AT91SAM9261_ID_MCI\t9\t;# Multimedia Card Interface\nset AT91SAM9261_ID_UDP\t10\t;# USB Device Port\nset AT91SAM9261_ID_TWI\t11\t;# Two-Wire Interface\nset AT91SAM9261_ID_SPI0\t12\t;# Serial Peripheral Interface 0\nset AT91SAM9261_ID_SPI1\t13\t;# Serial Peripheral Interface 1\nset AT91SAM9261_ID_SSC0\t14\t;# Serial Synchronous Controller 0\nset AT91SAM9261_ID_SSC1\t15\t;# Serial Synchronous Controller 1\nset AT91SAM9261_ID_SSC2\t16\t;# Serial Synchronous Controller 2\nset AT91SAM9261_ID_TC0\t17\t;# Timer Counter 0\nset AT91SAM9261_ID_TC1\t18\t;# Timer Counter 1\nset AT91SAM9261_ID_TC2\t19\t;# Timer Counter 2\nset AT91SAM9261_ID_UHP\t20\t;# USB Host port\nset AT91SAM9261_ID_LCDC\t21\t;# LDC Controller\nset AT91SAM9261_ID_IRQ0\t29\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9261_ID_IRQ1\t30\t;# Advanced Interrupt Controller (IRQ1)\nset AT91SAM9261_ID_IRQ2\t31\t;# Advanced Interrupt Controller (IRQ2)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9261_BASE_TCB0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC1\t\t0xfffa0040\nset AT91SAM9261_BASE_TC2\t\t0xfffa0080\nset AT91SAM9261_BASE_UDP\t\t0xfffa4000\nset AT91SAM9261_BASE_MCI\t\t0xfffa8000\nset AT91SAM9261_BASE_TWI\t\t0xfffac000\nset AT91SAM9261_BASE_US0\t\t0xfffb0000\nset AT91SAM9261_BASE_US1\t\t0xfffb4000\nset AT91SAM9261_BASE_US2\t\t0xfffb8000\nset AT91SAM9261_BASE_SSC0\t\t0xfffbc000\nset AT91SAM9261_BASE_SSC1\t\t0xfffc0000\nset AT91SAM9261_BASE_SSC2\t\t0xfffc4000\nset AT91SAM9261_BASE_SPI0\t\t0xfffc8000\nset AT91SAM9261_BASE_SPI1\t\t0xfffcc000\nset AT91_BASE_SYS\t\t\t0xffffea00\n\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_SDRAMC\t0xffffea00\nset AT91_SMC\t0xffffec00\nset AT91_MATRIX\t0xffffee00\nset AT91_AIC\t0xfffff000\nset AT91_DBGU\t0xfffff200\nset AT91_PIOA\t0xfffff400\nset AT91_PIOB\t0xfffff600\nset AT91_PIOC\t0xfffff800\nset AT91_PMC\t0xfffffc00\nset AT91_RSTC\t0xfffffd00\nset AT91_SHDWC\t0xfffffd10\nset AT91_RTT\t0xfffffd20\nset AT91_PIT\t0xfffffd30\nset AT91_WDT\t0xfffffd40\nset AT91_GPBR\t0xfffffd50\n\nset AT91_USART0\t$AT91SAM9261_BASE_US0\nset AT91_USART1\t$AT91SAM9261_BASE_US1\nset AT91_USART2\t$AT91SAM9261_BASE_US2\n\n\n#\n# Internal Memory.\n#\nset AT91SAM9261_SRAM_BASE\t0x00300000\t;# Internal SRAM base address\nset AT91SAM9261_SRAM_SIZE\t0x00028000\t;# Internal SRAM size (160Kb)\n\nset AT91SAM9261_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9261_ROM_SIZE\t0x00008000\t;# Internal ROM size (32Kb)\n\nset AT91SAM9261_UHP_BASE\t0x00500000\t;# USB Host controller\nset AT91SAM9261_LCDC_BASE\t0x00600000\t;# LDC controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9261\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9261_matrix.cfg",
    "content": "\nset AT91_MATRIX_MCFG\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register #\nset\t\tAT91_MATRIX_RCB0\t[expr {1 << 0}]\t\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t[expr {1 << 1}]\t\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x04}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x08}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x0C}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x10}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x14}]\t;# Slave Configuration Register 4\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {7    << 18}]\t;# Fixed Index of Default Master\n\nset AT91_MATRIX_TCR\t\t[expr {$AT91_MATRIX + 0x24}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_64\t\t[expr {7 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_64\t\t[expr {7 << 4}]\n\nset AT91_MATRIX_EBICSA\t[expr {$AT91_MATRIX + 0x30}]\t;# EBI Chip Select Assignment Register\nset\t\tAT91_MATRIX_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_CS4A_SMC_CF1\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_CS5A_SMC_CF2\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\n\nset AT91_MATRIX_USBPUCR\t[expr {$AT91_MATRIX + 0x34}]\t;# USB Pad Pull-Up Control Register\nset\t\tAT91_MATRIX_USBPUCR_PUON\t[expr {1 << 30}]\t;# USB Device PAD Pull-up Enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9263.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9263_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9263_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9263_ID_PIOCDE\t4\t;# Parallel IO Controller C, D and E\nset AT91SAM9263_ID_US0\t7\t;# USART 0\nset AT91SAM9263_ID_US1\t8\t;# USART 1\nset AT91SAM9263_ID_US2\t9\t;# USART 2\nset AT91SAM9263_ID_MCI0\t10\t;# Multimedia Card Interface 0\nset AT91SAM9263_ID_MCI1\t11\t;# Multimedia Card Interface 1\nset AT91SAM9263_ID_CAN\t12\t;# CAN\nset AT91SAM9263_ID_TWI\t13\t;# Two-Wire Interface\nset AT91SAM9263_ID_SPI0\t14\t;# Serial Peripheral Interface 0\nset AT91SAM9263_ID_SPI1\t15\t;# Serial Peripheral Interface 1\nset AT91SAM9263_ID_SSC0\t16\t;# Serial Synchronous Controller 0\nset AT91SAM9263_ID_SSC1\t17\t;# Serial Synchronous Controller 1\nset AT91SAM9263_ID_AC97C\t18\t;# AC97 Controller\nset AT91SAM9263_ID_TCB\t19\t;# Timer Counter 0, 1 and 2\nset AT91SAM9263_ID_PWMC\t20\t;# Pulse Width Modulation Controller\nset AT91SAM9263_ID_EMAC\t21\t;# Ethernet\nset AT91SAM9263_ID_2DGE\t23\t;# 2D Graphic Engine\nset AT91SAM9263_ID_UDP\t24\t;# USB Device Port\nset AT91SAM9263_ID_ISI\t25\t;# Image Sensor Interface\nset AT91SAM9263_ID_LCDC\t26\t;# LCD Controller\nset AT91SAM9263_ID_DMA\t27\t;# DMA Controller\nset AT91SAM9263_ID_UHP\t29\t;# USB Host port\nset AT91SAM9263_ID_IRQ0\t30\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9263_ID_IRQ1\t31\t;# Advanced Interrupt Controller (IRQ1)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9263_BASE_UDP\t\t0xfff78000\nset AT91SAM9263_BASE_TCB0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC1\t\t0xfff7c040\nset AT91SAM9263_BASE_TC2\t\t0xfff7c080\nset AT91SAM9263_BASE_MCI0\t\t0xfff80000\nset AT91SAM9263_BASE_MCI1\t\t0xfff84000\nset AT91SAM9263_BASE_TWI\t\t0xfff88000\nset AT91SAM9263_BASE_US0\t\t0xfff8c000\nset AT91SAM9263_BASE_US1\t\t0xfff90000\nset AT91SAM9263_BASE_US2\t\t0xfff94000\nset AT91SAM9263_BASE_SSC0\t\t0xfff98000\nset AT91SAM9263_BASE_SSC1\t\t0xfff9c000\nset AT91SAM9263_BASE_AC97C\t\t0xfffa0000\nset AT91SAM9263_BASE_SPI0\t\t0xfffa4000\nset AT91SAM9263_BASE_SPI1\t\t0xfffa8000\nset AT91SAM9263_BASE_CAN\t\t0xfffac000\nset AT91SAM9263_BASE_PWMC\t\t0xfffb8000\nset AT91SAM9263_BASE_EMAC\t\t0xfffbc000\nset AT91SAM9263_BASE_ISI\t\t0xfffc4000\nset AT91SAM9263_BASE_2DGE\t\t0xfffc8000\nset AT91_BASE_SYS\t\t\t0xffffe000\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_ECC0\t\t0xffffe000\nset AT91_SDRAMC0\t0xffffe200\nset AT91_SMC0\t\t0xffffe400\nset AT91_ECC1\t\t0xffffe600\nset AT91_SDRAMC1\t0xffffe800\nset AT91_SMC1\t\t0xffffea00\nset AT91_MATRIX\t\t0xffffec00\nset AT91_CCFG\t\t0xffffed10\nset AT91_DBGU\t\t0xffffee00\nset AT91_AIC\t\t0xfffff000\nset AT91_PIOA\t\t0xfffff200\nset AT91_PIOB\t\t0xfffff400\nset AT91_PIOC\t\t0xfffff600\nset AT91_PIOD\t\t0xfffff800\nset AT91_PIOE\t\t0xfffffa00\nset AT91_PMC\t\t0xfffffc00\nset AT91_RSTC\t\t0xfffffd00\nset AT91_SHDWC\t\t0xfffffd10\nset AT91_RTT0\t\t0xfffffd20\nset AT91_PIT\t\t0xfffffd30\nset AT91_WDT\t\t0xfffffd40\nset AT91_RTT1\t\t0xfffffd50\nset AT91_GPBR\t\t0xfffffd60\n\nset AT91_USART0\t$AT91SAM9263_BASE_US0\nset AT91_USART1\t$AT91SAM9263_BASE_US1\nset AT91_USART2\t$AT91SAM9263_BASE_US2\n\nset AT91_SMC\t$AT91_SMC0\nset AT91_SDRAMC\t$AT91_SDRAMC0\n\n#\n# Internal Memory.\n#\nset AT91SAM9263_SRAM0_BASE\t0x00300000\t;# Internal SRAM 0 base address\nset AT91SAM9263_SRAM0_SIZE\t0x00014000\t;# Internal SRAM 0 size (80Kb)\n\nset AT91SAM9263_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9263_ROM_SIZE\t0x00020000\t;# Internal ROM size (128Kb)\n\nset AT91SAM9263_SRAM1_BASE\t0x00500000\t;# Internal SRAM 1 base address\nset AT91SAM9263_SRAM1_SIZE\t0x00004000\t;# Internal SRAM 1 size (16Kb)\n\nset AT91SAM9263_LCDC_BASE\t0x00700000\t;# LCD Controller\nset AT91SAM9263_DMAC_BASE\t0x00800000\t;# DMA Controller\nset AT91SAM9263_UHP_BASE\t0x00a00000\t;# USB Host controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9263\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9263_matrix.cfg",
    "content": "set AT91_MATRIX_MCFG0\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register 0\nset AT91_MATRIX_MCFG1\t[expr {$AT91_MATRIX + 0x04}]\t;# Master Configuration Register 1\nset AT91_MATRIX_MCFG2\t[expr {$AT91_MATRIX + 0x08}]\t;# Master Configuration Register 2\nset AT91_MATRIX_MCFG3\t[expr {$AT91_MATRIX + 0x0C}]\t;# Master Configuration Register 3\nset AT91_MATRIX_MCFG4\t[expr {$AT91_MATRIX + 0x10}]\t;# Master Configuration Register 4\nset AT91_MATRIX_MCFG5\t[expr {$AT91_MATRIX + 0x14}]\t;# Master Configuration Register 5\nset AT91_MATRIX_MCFG6\t[expr {$AT91_MATRIX + 0x18}]\t;# Master Configuration Register 6\nset AT91_MATRIX_MCFG7\t[expr {$AT91_MATRIX + 0x1C}]\t;# Master Configuration Register 7\nset AT91_MATRIX_MCFG8\t[expr {$AT91_MATRIX + 0x20}]\t;# Master Configuration Register 8\nset\t\tAT91_MATRIX_ULBT\t[expr {7 << 0}]\t;# Undefined Length Burst Type\nset\t\t\tAT91_MATRIX_ULBT_INFINITE\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SINGLE\t\t[expr {1 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_FOUR\t\t[expr {2 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_EIGHT\t\t[expr {3 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SIXTEEN\t[expr {4 << 0}]\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x40}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x44}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x48}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x4C}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x50}]\t;# Slave Configuration Register 4\nset AT91_MATRIX_SCFG5\t[expr {$AT91_MATRIX + 0x54}]\t;# Slave Configuration Register 5\nset AT91_MATRIX_SCFG6\t[expr {$AT91_MATRIX + 0x58}]\t;# Slave Configuration Register 6\nset AT91_MATRIX_SCFG7\t[expr {$AT91_MATRIX + 0x5C}]\t;# Slave Configuration Register 7\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {0xf  << 18}]\t;# Fixed Index of Default Master\nset\t\tAT91_MATRIX_ARBT\t\t[expr {3    << 24}]\t;# Arbitration Type\nset\t\t\tAT91_MATRIX_ARBT_ROUND_ROBIN\t[expr {0 << 24}]\nset\t\t\tAT91_MATRIX_ARBT_FIXED_PRIORITY\t[expr {1 << 24}]\n\nset AT91_MATRIX_PRAS0\t[expr {$AT91_MATRIX + 0x80}]\t;# Priority Register A for Slave 0\nset AT91_MATRIX_PRBS0\t[expr {$AT91_MATRIX + 0x84}]\t;# Priority Register B for Slave 0\nset AT91_MATRIX_PRAS1\t[expr {$AT91_MATRIX + 0x88}]\t;# Priority Register A for Slave 1\nset AT91_MATRIX_PRBS1\t[expr {$AT91_MATRIX + 0x8C}]\t;# Priority Register B for Slave 1\nset AT91_MATRIX_PRAS2\t[expr {$AT91_MATRIX + 0x90}]\t;# Priority Register A for Slave 2\nset AT91_MATRIX_PRBS2\t[expr {$AT91_MATRIX + 0x94}]\t;# Priority Register B for Slave 2\nset AT91_MATRIX_PRAS3\t[expr {$AT91_MATRIX + 0x98}]\t;# Priority Register A for Slave 3\nset AT91_MATRIX_PRBS3\t[expr {$AT91_MATRIX + 0x9C}]\t;# Priority Register B for Slave 3\nset AT91_MATRIX_PRAS4\t[expr {$AT91_MATRIX + 0xA0}]\t;# Priority Register A for Slave 4\nset AT91_MATRIX_PRBS4\t[expr {$AT91_MATRIX + 0xA4}]\t;# Priority Register B for Slave 4\nset AT91_MATRIX_PRAS5\t[expr {$AT91_MATRIX + 0xA8}]\t;# Priority Register A for Slave 5\nset AT91_MATRIX_PRBS5\t[expr {$AT91_MATRIX + 0xAC}]\t;# Priority Register B for Slave 5\nset AT91_MATRIX_PRAS6\t[expr {$AT91_MATRIX + 0xB0}]\t;# Priority Register A for Slave 6\nset AT91_MATRIX_PRBS6\t[expr {$AT91_MATRIX + 0xB4}]\t;# Priority Register B for Slave 6\nset AT91_MATRIX_PRAS7\t[expr {$AT91_MATRIX + 0xB8}]\t;# Priority Register A for Slave 7\nset AT91_MATRIX_PRBS7\t[expr {$AT91_MATRIX + 0xBC}]\t;# Priority Register B for Slave 7\nset\t\tAT91_MATRIX_M0PR\t\t[expr {3 << 0}]\t\t;# Master 0 Priority\nset\t\tAT91_MATRIX_M1PR\t\t[expr {3 << 4}]\t\t;# Master 1 Priority\nset\t\tAT91_MATRIX_M2PR\t\t[expr {3 << 8}]\t\t;# Master 2 Priority\nset\t\tAT91_MATRIX_M3PR\t\t[expr {3 << 12}]\t;# Master 3 Priority\nset\t\tAT91_MATRIX_M4PR\t\t[expr {3 << 16}]\t;# Master 4 Priority\nset\t\tAT91_MATRIX_M5PR\t\t[expr {3 << 20}]\t;# Master 5 Priority\nset\t\tAT91_MATRIX_M6PR\t\t[expr {3 << 24}]\t;# Master 6 Priority\nset\t\tAT91_MATRIX_M7PR\t\t[expr {3 << 28}]\t;# Master 7 Priority\nset\t\tAT91_MATRIX_M8PR\t\t[expr {3 << 0}]\t\t;# Master 8 Priority (in Register B)\n\nset AT91_MATRIX_MRCR\t[expr {$AT91_MATRIX + 0x100}]\t;# Master Remap Control Register\nset\t\tAT91_MATRIX_RCB0\t\t[expr {1 << 0}]\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t\t[expr {1 << 1}]\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\nset\t\tAT91_MATRIX_RCB2\t\t[expr {1 << 2}]\nset\t\tAT91_MATRIX_RCB3\t\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_RCB4\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_RCB5\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_RCB6\t\t[expr {1 << 6}]\nset\t\tAT91_MATRIX_RCB7\t\t[expr {1 << 7}]\nset\t\tAT91_MATRIX_RCB8\t\t[expr {1 << 8}]\n\nset AT91_MATRIX_TCMR\t[expr {$AT91_MATRIX + 0x114}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\n\nset AT91_MATRIX_EBI0CSA\t[expr {$AT91_MATRIX + 0x120}]\t;# EBI0 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI0_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI0_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignmen\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI0_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC_CF1\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_EBI0_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC_CF2\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_EBI0_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI0_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n\nset AT91_MATRIX_EBI1CSA\t[expr {$AT91_MATRIX + 0x124}]\t;# EBI1 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI1_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI1_CS2A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI1_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI1_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9_init.cfg",
    "content": "uplevel #0 [list source [find chip/atmel/at91/at91sam9_sdramc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pmc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pio.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_rstc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_wdt.cfg]]\n\nproc at91sam9_reset_start { } {\n\n\tarm7_9 fast_memory_access disable\n\n\tjtag_rclk 8\n\thalt\n\twait_halt 10000\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | (5 << 8)}]\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9_reset_init { config } {\n\n\tmww $::AT91_WDT_MR $config(wdt_mr_val)\t;# disable watchdog\n\n\tset ckgr_mor [expr {$::AT91_PMC_MOSCEN | (255 << 8)}]\n\n\tmww $::AT91_CKGR_MOR $ckgr_mor\t;# CKGR_MOR - enable main osc.\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MOSCS}] != $::AT91_PMC_MOSCS } { sleep 1 }\n\n\tset pllar_val\t$::AT91_PMC_PLLA_WR_ERRATA ;# Bit 29 must be 1 when prog\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_OUT}]\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_PLLCOUNT}]\n\tset pllar_val\t[expr {$pllar_val | ($config(master_pll_mul) - 1) << 16}]\n\tset pllar_val\t[expr {$pllar_val | $config(master_pll_div)}]\n\n\tmww $::AT91_CKGR_PLLAR $pllar_val\t ;# CKGR_PLLA - (18.432MHz/13)*141 = 199.9 MHz\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_LOCKA}] != $::AT91_PMC_LOCKA } { sleep 1 }\n\n\t;# PCK/2 = MCK Master Clock from PLLA\n\tset mckr_val\t$::AT91_PMC_CSS_PLLA\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PRES_1}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91SAM9_PMC_MDIV_2}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PDIV_1}]\n\n\tmww $::AT91_PMC_MCKR $mckr_val\t;# PMC_MCKR (MCLK: 0x102 - (CLK/2)MHZ, 0x202 - (CLK/3)MHz)\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MCKRDY}] != $::AT91_PMC_MCKRDY } { sleep 1 }\n\n\t## switch JTAG clock to highspeed clock\n\tjtag_rclk 0\n\n\tarm7_9 dcc_downloads enable\t;# Enable faster DCC downloads\n\tarm7_9 fast_memory_access enable\n\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# user reset enable\n\n\tif { [info exists config(sdram_piod)] } {\n\t\tset pdr_addr\t[expr {$::AT91_PIOD + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOD + $::PIO_PUDR}]\n\t\tset asr_addr\t[expr {$::AT91_PIOD + $::PIO_ASR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t\tmww $asr_addr 0xffff0000\n\t} else {\n\t\tset pdr_addr\t[expr {$::AT91_PIOC + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOC + $::PIO_PUDR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t}\n\n\tmww $config(matrix_ebicsa_addr) $config(matrix_ebicsa_val)\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRAMC_MR Mode register\n\tmww $::AT91_SDRAMC_TR\t$config(sdram_tr_val)\t\t;# SDRAMC_TR - Refresh Timer register\n\tmww $::AT91_SDRAMC_CR\t$config(sdram_cr_val)\t\t;# SDRAMC_CR - Configuration register\n\tmww $::AT91_SDRAMC_MDR\t$::AT91_SDRAMC_MD_SDRAM\t\t;# Memory Device Register -> SDRAM\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_PRECHARGE\t;# SDRAMC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_REFRESH\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_LMR\t\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_TR\t1200\t\t\t\t;# SDRAM_TR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\n\tmww $::AT91_MATRIX 0xf\t\t;# MATRIX_MCFG - REMAP all masters\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9_sdramc.cfg",
    "content": "\n# SDRAM Controller (SDRAMC) registers\nset AT91_SDRAMC_MR\t\t[expr {$AT91_SDRAMC + 0x00}]\t;# SDRAM Controller Mode Register\nset\t\tAT91_SDRAMC_MODE\t[expr {0xf << 0}]\t;# Command Mode\nset\t\t\tAT91_SDRAMC_MODE_NORMAL\t\t0\nset\t\t\tAT91_SDRAMC_MODE_NOP\t\t1\nset\t\t\tAT91_SDRAMC_MODE_PRECHARGE\t2\nset\t\t\tAT91_SDRAMC_MODE_LMR\t\t3\nset\t\t\tAT91_SDRAMC_MODE_REFRESH\t4\nset\t\t\tAT91_SDRAMC_MODE_EXT_LMR\t5\nset\t\t\tAT91_SDRAMC_MODE_DEEP\t\t6\n\nset AT91_SDRAMC_TR\t\t[expr {$AT91_SDRAMC + 0x04}]\t;# SDRAM Controller Refresh Timer Register\nset\t\tAT91_SDRAMC_COUNT\t[expr {0xfff << 0}]\t\t;# Refresh Timer Counter\n\nset AT91_SDRAMC_CR\t\t[expr {$AT91_SDRAMC + 0x08}]\t;# SDRAM Controller Configuration Register\nset\t\tAT91_SDRAMC_NC\t\t[expr {3 << 0}]\t\t;# Number of Column Bits\nset\t\t\tAT91_SDRAMC_NC_8\t[expr {0 << 0}]\nset\t\t\tAT91_SDRAMC_NC_9\t[expr {1 << 0}]\nset\t\t\tAT91_SDRAMC_NC_10\t[expr {2 << 0}]\nset\t\t\tAT91_SDRAMC_NC_11\t[expr {3 << 0}]\nset\t\tAT91_SDRAMC_NR\t\t[expr {3 << 2}]\t\t;# Number of Row Bits\nset\t\t\tAT91_SDRAMC_NR_11\t[expr {0 << 2}]\nset\t\t\tAT91_SDRAMC_NR_12\t[expr {1 << 2}]\nset\t\t\tAT91_SDRAMC_NR_13\t[expr {2 << 2}]\nset\t\tAT91_SDRAMC_NB\t\t[expr {1 << 4}]\t\t;# Number of Banks\nset\t\t\tAT91_SDRAMC_NB_2\t[expr {0 << 4}]\nset\t\t\tAT91_SDRAMC_NB_4\t[expr {1 << 4}]\nset\t\tAT91_SDRAMC_CAS\t\t[expr {3 << 5}]\t\t;# CAS Latency\nset\t\t\tAT91_SDRAMC_CAS_1\t[expr {1 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_2\t[expr {2 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_3\t[expr {3 << 5}]\nset\t\tAT91_SDRAMC_DBW\t\t[expr {1 << 7}]\t\t;# Data Bus Width\nset\t\t\tAT91_SDRAMC_DBW_32\t[expr {0 << 7}]\nset\t\t\tAT91_SDRAMC_DBW_16\t[expr {1 << 7}]\nset\t\tAT91_SDRAMC_TWR\t\t[expr {0xf <<  8}]\t\t;# Write Recovery Delay\nset\t\tAT91_SDRAMC_TRC\t\t[expr {0xf << 12}]\t\t;# Row Cycle Delay\nset\t\tAT91_SDRAMC_TRP\t\t[expr {0xf << 16}]\t\t;# Row Precharge Delay\nset\t\tAT91_SDRAMC_TRCD\t[expr {0xf << 20}]\t\t;# Row to Column Delay\nset\t\tAT91_SDRAMC_TRAS\t[expr {0xf << 24}]\t\t;# Active to Precharge Delay\nset\t\tAT91_SDRAMC_TXSR\t[expr {0xf << 28}]\t\t;# Exit Self Refresh to Active Delay\n\nset AT91_SDRAMC_LPR\t\t[expr {$AT91_SDRAMC + 0x10}]\t;# SDRAM Controller Low Power Register\nset\t\tAT91_SDRAMC_LPCB\t\t[expr {3 << 0}]\t;# Low-power Configurations\nset\t\t\tAT91_SDRAMC_LPCB_DISABLE\t\t0\nset\t\t\tAT91_SDRAMC_LPCB_SELF_REFRESH\t\t1\nset\t\t\tAT91_SDRAMC_LPCB_POWER_DOWN\t\t2\nset\t\t\tAT91_SDRAMC_LPCB_DEEP_POWER_DOWN\t3\nset\t\tAT91_SDRAMC_PASR\t\t[expr {7 << 4}]\t;# Partial Array Self Refresh\nset\t\tAT91_SDRAMC_TCSR\t\t[expr {3 << 8}]\t;# Temperature Compensated Self Refresh\nset\t\tAT91_SDRAMC_DS\t\t\t[expr {3 << 10}]\t;# Drive Strength\nset\t\tAT91_SDRAMC_TIMEOUT\t\t[expr {3 << 12}]\t;# Time to define when Low Power Mode is enabled\nset\t\t\tAT91_SDRAMC_TIMEOUT_0_CLK_CYCLES\t[expr {0 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_64_CLK_CYCLES\t[expr {1 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_128_CLK_CYCLES\t[expr {2 << 12}]\n\nset AT91_SDRAMC_IER\t\t[expr {$AT91_SDRAMC + 0x14}]\t;# SDRAM Controller Interrupt Enable Register\nset AT91_SDRAMC_IDR\t\t[expr {$AT91_SDRAMC + 0x18}]\t;# SDRAM Controller Interrupt Disable Register\nset AT91_SDRAMC_IMR\t\t[expr {$AT91_SDRAMC + 0x1C}]\t;# SDRAM Controller Interrupt Mask Register\nset AT91_SDRAMC_ISR\t\t[expr {$AT91_SDRAMC + 0x20}]\t;# SDRAM Controller Interrupt Status Register\nset\t\tAT91_SDRAMC_RES\t\t[expr {1 << 0}]\t\t;# Refresh Error Status\n\nset AT91_SDRAMC_MDR\t\t[expr {$AT91_SDRAMC + 0x24}]\t;# SDRAM Memory Device Register\nset\t\tAT91_SDRAMC_MD\t\t[expr {3 << 0}]\t\t;# Memory Device Type\nset\t\t\tAT91_SDRAMC_MD_SDRAM\t\t0\nset\t\t\tAT91_SDRAMC_MD_LOW_POWER_SDRAM\t1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/at91sam9_smc.cfg",
    "content": "set\t\tAT91_SMC_READMODE\t[expr {1 <<  0}]\t\t;# Read Mode\nset\t\tAT91_SMC_WRITEMODE\t[expr {1 <<  1}]\t\t;# Write Mode\nset\t\tAT91_SMC_EXNWMODE\t[expr {3 <<  4}]\t\t;# NWAIT Mode\nset\t\t\tAT91_SMC_EXNWMODE_DISABLE\t[expr {0 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_FROZEN\t[expr {2 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_READY\t\t[expr {3 << 4}]\nset\t\tAT91_SMC_BAT\t\t[expr {1 <<  8}]\t\t;# Byte Access Type\nset\t\t\tAT91_SMC_BAT_SELECT\t\t[expr {0 << 8}]\nset\t\t\tAT91_SMC_BAT_WRITE\t\t[expr {1 << 8}]\nset\t\tAT91_SMC_DBW\t\t[expr {3 << 12}]\t\t;# Data Bus Width */\nset\t\t\tAT91_SMC_DBW_8\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_SMC_DBW_16\t\t\t[expr {1 << 12}]\nset\t\t\tAT91_SMC_DBW_32\t\t\t[expr {2 << 12}]\nset\t\tAT91_SMC_TDFMODE\t[expr {1 << 20}]\t\t;# TDF Optimization - Enabled\nset\t\tAT91_SMC_PMEN\t\t[expr {1 << 24}]\t\t;# Page Mode Enabled\nset\t\tAT91_SMC_PS\t\t[expr {3 << 28}]\t\t;# Page Size\nset\t\t\tAT91_SMC_PS_4\t\t\t[expr {0 << 28}]\nset\t\t\tAT91_SMC_PS_8\t\t\t[expr {1 << 28}]\nset\t\t\tAT91_SMC_PS_16\t\t\t[expr {2 << 28}]\nset\t\t\tAT91_SMC_PS_32\t\t\t[expr {3 << 28}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/hardware.cfg",
    "content": "# External Memory Map\nset AT91_CHIPSELECT_0\t0x10000000\nset AT91_CHIPSELECT_1\t0x20000000\nset AT91_CHIPSELECT_2\t0x30000000\nset AT91_CHIPSELECT_3\t0x40000000\nset AT91_CHIPSELECT_4\t0x50000000\nset AT91_CHIPSELECT_5\t0x60000000\nset AT91_CHIPSELECT_6\t0x70000000\nset AT91_CHIPSELECT_7\t0x80000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/pmc.tcl",
    "content": "\nif [info exists AT91C_MAINOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 18.432mhz is a common thing...\n    set AT91C_MAINOSC_FREQ 18432000\n}\nglobal AT91C_MAINOSC_FREQ\n\nif [info exists AT91C_SLOWOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 32khz is the norm\n    set AT91C_SLOWOSC_FREQ 32768\n}\nglobal AT91C_SLOWOSC_FREQ\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/rtt.tcl",
    "content": "\nset RTTC_RTMR [expr {$AT91C_BASE_RTTC + 0x00}]\nset RTTC_RTAR [expr {$AT91C_BASE_RTTC + 0x04}]\nset RTTC_RTVR [expr {$AT91C_BASE_RTTC + 0x08}]\nset RTTC_RTSR [expr {$AT91C_BASE_RTTC + 0x0c}]\nglobal RTTC_RTMR\nglobal RTTC_RTAR\nglobal RTTC_RTVR\nglobal RTTC_RTSR\n\nproc show_RTTC_RTMR_helper { NAME ADDR VAL } {\n    set rtpres [expr {$VAL & 0x0ffff}]\n    global BIT16 BIT17\n    if { $rtpres == 0 } {\n\tset rtpres 65536;\n    }\n    global AT91C_SLOWOSC_FREQ\n    # Nasty hack, make this a float by tacking a .0 on the end\n    # otherwise, jim makes the value an integer\n    set f [expr \"$AT91C_SLOWOSC_FREQ.0 / $rtpres.0\"]\n    echo [format \"\\tPrescale value: 0x%04x (%5d) => %f Hz\" $rtpres $rtpres $f]\n    if { $VAL & $BIT16 } {\n\techo \"\\tBit16 -> Alarm IRQ Enabled\"\n    } else {\n\techo \"\\tBit16 -> Alarm IRQ Disabled\"\n    }\n    if { $VAL & $BIT17 } {\n\techo \"\\tBit17 -> RTC Inc IRQ Enabled\"\n    } else {\n\techo \"\\tBit17 -> RTC Inc IRQ Disabled\"\n    }\n    # Bit 18 is write only.\n}\n\nproc show_RTTC_RTSR_helper { NAME ADDR VAL } {\n    global BIT0 BIT1\n    if { $VAL & $BIT0 } {\n\techo \"\\tBit0 -> ALARM PENDING\"\n    } else {\n\techo \"\\tBit0 -> alarm not pending\"\n    }\n    if { $VAL & $BIT1 } {\n\techo \"\\tBit0 -> RTINC PENDING\"\n    } else {\n\techo \"\\tBit0 -> rtinc not pending\"\n    }\n}\n\nproc show_RTTC { } {\n\n    show_mmr32_reg RTTC_RTMR\n    show_mmr32_reg RTTC_RTAR\n    show_mmr32_reg RTTC_RTVR\n    show_mmr32_reg RTTC_RTSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/sam9_smc.cfg",
    "content": "# Setup register\n#\n# ncs_read_setup\n# nrd_setup\n# ncs_write_setup\n# set nwe_setup\n#\n#\n# Pulse register\n#\n# ncs_read_pulse\n# nrd_pulse\n# ncs_write_pulse\n# nwe_pulse\n#\n#\n# Cycle register\n#\n# read_cycle 0\n# write_cycle 0\n#\n#\n# Mode register\n#\n# mode\n# tdf_cycles\nproc sam9_smc_config { cs smc_config } {\n\t;# Setup Register for CS n\n\tset AT91_SMC_SETUP [expr {$::AT91_SMC + 0x00 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_setup) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_setup) << 8}]\n\tset val [expr {$val | $smc_config(nrd_setup)) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_setup) << 24}]\n\tmww $AT91_SMC_SETUP $val\n\n\t;# Pulse Register for CS n\n\tset AT91_SMC_PULSE [expr {$::AT91_SMC + 0x04 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_pulse) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_pulse) << 8}]\n\tset val [expr {$val | $smc_config(nrd_pulse) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_pulse) << 24}]\n\tmww $AT91_SMC_PULSE $val\n\n\t;# Cycle Register for CS n\n\tset AT91_SMC_CYCLE [expr {$::AT91_SMC + 0x08 + $cs * 0x10}]\n\tset val [expr {$smc_config(write_cycle) << 0}]\n\tset val [expr {$val | $smc_config(read_cycle) << 16}]\n\tmww $AT91_SMC_CYCLE $val\n\n\t;# Mode Register for CS n\n\tset AT91_SMC_MODE [expr {$::AT91_SMC + 0x0c + $cs * 0x10}]\n\tset val [expr {$smc_config(mode) << 0}]\n\tset val [expr {$val | $smc_config(tdf_cycles) << 16}]\n\tmww $AT91_SMC_MODE $val\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/atmel/at91/usarts.tcl",
    "content": "# the DBGU and USARTs are 'almost' indentical'\nset DBGU_CR         [expr {$AT91C_BASE_DBGU + 0x00000000}]\nset DBGU_MR         [expr {$AT91C_BASE_DBGU + 0x00000004}]\nset DBGU_IER        [expr {$AT91C_BASE_DBGU + 0x00000008}]\nset DBGU_IDR        [expr {$AT91C_BASE_DBGU + 0x0000000C}]\nset DBGU_IMR        [expr {$AT91C_BASE_DBGU + 0x00000010}]\nset DBGU_CSR        [expr {$AT91C_BASE_DBGU + 0x00000014}]\nset DBGU_RHR        [expr {$AT91C_BASE_DBGU + 0x00000018}]\nset DBGU_THR        [expr {$AT91C_BASE_DBGU + 0x0000001C}]\nset DBGU_BRGR       [expr {$AT91C_BASE_DBGU + 0x00000020}]\n# no RTOR\n# no TTGR\n# no FIDI\n# no NER\nset DBGU_CIDR       [expr {$AT91C_BASE_DBGU + 0x00000040}]\nset DBGU_EXID       [expr {$AT91C_BASE_DBGU + 0x00000044}]\nset DBGU_FNTR       [expr {$AT91C_BASE_DBGU + 0x00000048}]\n\n\nset USx_CR           0x00000000\nset USx_MR           0x00000004\nset USx_IER          0x00000008\nset USx_IDR          0x0000000C\nset USx_IMR          0x00000010\nset USx_CSR          0x00000014\nset USx_RHR          0x00000018\nset USx_THR          0x0000001C\nset USx_BRGR         0x00000020\nset USx_RTOR         0x00000024\nset USx_TTGR         0x00000028\nset USx_FIDI         0x00000040\nset USx_NER          0x00000044\nset USx_IF           0x0000004C\n\n# Create all the uarts that exist..\n# we blow up if there are >9\n\n\nproc show_mmr_USx_MR_helper { NAME ADDR VAL } {\n    # First - just print it\n\n    set x [show_normalize_bitfield $VAL 3 0]\n    if { $x == 0 } {\n\techo \"\\tNormal operation\"\n    } else {\n\techo [format \"\\tNon Normal operation mode: 0x%02x\" $x]\n    }\n\n    set x [show_normalize_bitfield $VAL 11 9]\n    set s \"unknown\"\n    switch -exact $x {\n\t0 { set s \"Even\" }\n\t1 { set s \"Odd\" }\n\t2 { set s \"Force=0\" }\n\t3 { set s \"Force=1\" }\n\t* {\n\t    set $x [expr {$x & 6}]\n\t    switch -exact $x {\n\t\t4 { set s \"None\" }\n\t\t6 { set s \"Multidrop Mode\" }\n\t    }\n\t}\n    }\n    echo [format \"\\tParity: %s \" $s]\n\n    set x [expr {5 + [show_normalize_bitfield $VAL 7 6]}]\n    echo [format \"\\tDatabits: %d\" $x]\n\n    set x [show_normalize_bitfield $VAL 13 12]\n    switch -exact $x {\n\t0 { echo \"\\tStop bits: 1\" }\n\t1 { echo \"\\tStop bits: 1.5\" }\n\t2 { echo \"\\tStop bits: 2\" }\n\t3 { echo \"\\tStop bits: Illegal/Reserved\" }\n    }\n}\n\n# For every possbile usart...\nforeach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } {\n    set n AT91C_BASE_[set WHO]\n    set str \"\"\n\n    # Only if it exists on the chip\n    if [ info exists $n ] {\n\t# Hence: $n - is like AT91C_BASE_USx\n\t# For every sub-register\n\tforeach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF}\t{\n\t    # vn = variable name\n\t    set vn [set WHO]_[set REG]\n\t    # vn = USx_IER\n\t    # vv = variable value\n\t    set vv [expr \"$$n + [set USx_[set REG]]\"]\n\t    # And VV is the address in memory of that register\n\n\n\t    # make that VN a GLOBAL so others can find it\n\t    global $vn\n\t    set $vn $vv\n\n\t    # Create a command for this specific register.\n\t    proc show_$vn { } \"show_mmr32_reg $vn\"\n\n\t    # Add this command to the Device(as a whole) command\n\t    set str \"$str\\nshow_$vn\"\n\t}\n\t# Now - create the DEVICE(as a whole) command\n\tset fn show_$WHO\n\tproc $fn { } $str\n    }\n}\n\n# The Debug Uart is special..\nset str \"\"\n\n\n# For every sub-register\nforeach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR\n    DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} {\n\n    # Create a command for this specific register.\n    proc show_$REG { } \"show_mmr32_reg $REG\"\n\n    # Add this command to the Device(as a whole) command\n    set str \"$str\\nshow_$REG\"\n}\n\n# Now - create the DEVICE(as a whole) command\nproc show_DBGU { } $str\n\nunset str\n\nproc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/spear/quirk_no_srst.tcl",
    "content": "# Quirks to bypass missing SRST on JTAG connector\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# For boards that have JTAG SRST not connected.\n# We use \"arm9 vector_catch reset\" to catch button reset event.\n\n\n$_TARGETNAME configure -event reset-assert sp_reset_assert\n$_TARGETNAME configure -event reset-deassert-post sp_reset_deassert_post\n\n# keeps the name of the SPEAr target\nglobal sp_target_name\nset sp_target_name $_TARGETNAME\n\n# Keeps the argument of \"reset\" command (run, init, halt).\nglobal sp_reset_mode\nset sp_reset_mode \"\"\n\n# Helper procedure. Returns 0 is target is halted.\nproc sp_is_halted {} {\n\tglobal sp_target_name\n\n\treturn [expr {[string compare [$sp_target_name curstate] \"halted\" ] == 0}]\n}\n\n# wait for reset button to be pressed, causing CPU to get halted\nproc sp_reset_deassert_post {} {\n\tglobal sp_reset_mode\n\n\tset bar(0) |\n\tset bar(1) /\n\tset bar(2) -\n\tset bar(3) \\\\\n\n\tpoll on\n\techo \"====> Press reset button on the board <====\"\n\tfor {set i 0} { [sp_is_halted] == 0 } { set i [expr {$i + 1}]} {\n\t\techo -n \"$bar([expr {$i & 3}])\\r\"\n\t\tsleep 200\n\t}\n\n\t# Remove catch reset event\n\tarm9 vector_catch none\n\n\t# CPU is halted, but we typed \"reset run\" ...\n\tif { [string compare $sp_reset_mode \"run\"] == 0 } {\n\t\tresume\n\t}\n}\n\n# Override reset-assert, since no SRST available\n# Catch reset event\nproc sp_reset_assert {} {\n\tarm9 vector_catch reset\n}\n\n# Override default init_reset{mode} to catch parameter \"mode\"\nproc init_reset {mode} {\n\tglobal sp_reset_mode\n\n\tset sp_reset_mode $mode\n\n\t# We need to detect CPU get halted, so exit from halt\n\tif { [sp_is_halted] } {\n\t\techo \"Resuming CPU to detect reset\"\n\t\tresume\n\t}\n\n\t# Execute default init_reset{mode}\n\tjtag arp_init-reset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/spear/spear3xx.tcl",
    "content": "# Generic init scripts for all ST SPEAr3xx family\n# http://www.st.com/spear\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Initialize internal clock\n# Default:\n# - Crystal =  24 MHz\n# - PLL1    = 332 MHz\n# - PLL2    = 332 MHz\n# - CPU_CLK = 332 MHz\n# - DDR_CLK = 332 MHz async\n# - HCLK    = 166 MHz\n# - PCLK    =  83 MHz\nproc sp3xx_clock_default {} {\n\tmww 0xfca00000 0x00000002\t;# set sysclk slow\n\tmww 0xfca00014 0x0ffffff8\t;# set pll timeout to minimum (100us ?!?)\n\n\t# DDRCORE disable to change frequency\n\tset val [expr {([mrw 0xfca8002c] & ~0x20000000) | 0x40000000}]\n\tmww 0xfca8002c $val\n\tmww 0xfca8002c $val ;# Yes, write twice!\n\n\t# programming PLL1\n\tmww 0xfca8000c 0xa600010c\t;# M=166 P=1 N=12\n\tmww 0xfca80008 0x00001c0a\t;# power down\n\tmww 0xfca80008 0x00001c0e\t;# enable\n\tmww 0xfca80008 0x00001c06\t;# strobe\n\tmww 0xfca80008 0x00001c0e\n\twhile { [expr {[mrw 0xfca80008] & 0x01}] == 0x00 } { sleep 1 }\n\n\t# programming PLL2\n\tmww 0xfca80018 0xa600010c\t;# M=166, P=1, N=12\n\tmww 0xfca80014 0x00001c0a\t;# power down\n\tmww 0xfca80014 0x00001c0e\t;# enable\n\tmww 0xfca80014 0x00001c06\t;# strobe\n\tmww 0xfca80014 0x00001c0e\n\twhile { [expr {[mrw 0xfca80014] & 0x01}] == 0x00 } { sleep 1 }\n\n\tmww 0xfca80028 0x00000082\t;# enable plltimeen\n\tmww 0xfca80024 0x00000511\t;# set hclkdiv=\"/2\" & pclkdiv=\"/2\"\n\n\tmww 0xfca00000 0x00000004\t;# setting SYSCTL to NORMAL mode\n\twhile { [expr {[mrw 0xfca00000] & 0x20}] != 0x20 } { sleep 1 }\n\n\t# Select source of DDR clock\n\t#mmw 0xfca80020 0x10000000 0x70000000 ;# PLL1\n\tmmw 0xfca80020 0x30000000 0x70000000 ;# PLL2\n\n\t# DDRCORE enable after change frequency\n\tmmw 0xfca8002c 0x20000000 0x00000000\n}\n\nproc sp3xx_common_init {} {\n\tmww 0xfca8002c 0xfffffff8\t;# enable clock of all peripherals\n\tmww 0xfca80038 0x00000000\t;# remove reset of all peripherals\n\n\tmww 0xfca80034 0x0000ffff\t;# enable all RAS clocks\n\tmww 0xfca80040 0x00000000\t;# remove all RAS resets\n\n\tmww 0xfca800e4 0x78000008\t;# COMP1V8_REG\n\tmww 0xfca800ec 0x78000008\t;# COMP3V3_REG\n\n\tmww 0xfc000000 0x10000f5f\t;# init SMI and set HW mode\n\tmww 0xfc000000 0x00000f5f\n\n\t# Initialize Bus Interconnection Matrix\n\t# All ports Round-Robin and lowest priority\n\tmww 0xfca8007c 0x80000007\n\tmww 0xfca80080 0x80000007\n\tmww 0xfca80084 0x80000007\n\tmww 0xfca80088 0x80000007\n\tmww 0xfca8008c 0x80000007\n\tmww 0xfca80090 0x80000007\n\tmww 0xfca80094 0x80000007\n\tmww 0xfca80098 0x80000007\n\tmww 0xfca8009c 0x80000007\n}\n\n\n# Specific init scripts for ST SPEAr300\nproc sp300_init {} {\n\tmww 0x99000000 0x00003fff\t;# RAS function enable\n}\n\n\n# Specific init scripts for ST SPEAr310\nproc sp310_init {} {\n\tmww 0xb4000008 0x00002ff4\t;# RAS function enable\n\n\tmww 0xfca80050 0x00000001\t;# Enable clk mem port 1\n\n\tmww 0xfca8013c 0x2f7bc210\t;# plgpio_pad_drv\n\tmww 0xfca80140 0x017bdef6\n}\n\nproc sp310_emi_init {} {\n\t# set EMI pad strength\n\tmmw 0xfca80134 0x0e000000 0x00000000\n\tmmw 0xfca80138 0x0e739ce7 0x00000000\n\tmmw 0xfca8013c 0x00039ce7 0x00000000\n\n\t# set safe EMI timing as in BootROM\n\t#mww 0x4f000000 0x0000000f\t;# tAP_0_reg\n\t#mww 0x4f000004 0x00000000\t;# tSDP_0_reg\n\t#mww 0x4f000008 0x000000ff\t;# tDPw_0_reg\n\t#mww 0x4f00000c 0x00000111\t;# tDPr_0_reg\n\t#mww 0x4f000010 0x00000002\t;# tDCS_0_reg\n\n\t# set fast EMI timing as in Linux\n\tmww 0x4f000000 0x00000010\t;# tAP_0_reg\n\tmww 0x4f000004 0x00000005\t;# tSDP_0_reg\n\tmww 0x4f000008 0x0000000a\t;# tDPw_0_reg\n\tmww 0x4f00000c 0x0000000a\t;# tDPr_0_reg\n\tmww 0x4f000010 0x00000005\t;# tDCS_0_re\n\n\t# 32bit wide, 8/16/32bit access\n\tmww 0x4f000014 0x0000000e\t;# control_0_reg\n\tmww 0x4f000094 0x0000003f\t;# ack_reg\n}\n\n\n# Specific init scripts for ST SPEAr320\nproc sp320_init {} {\n\tmww 0xb300000c 0xffffac04\t;# RAS function enable\n\tmww 0xb3000010 0x00000001\t;# RAS mode select\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/spear/spear3xx_ddr.tcl",
    "content": "# Init scripts to configure DDR controller of SPEAr3xx\n# http://www.st.com/spear\n# Original values taken from XLoader source code\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\nproc sp3xx_ddr_init {ddr_type {ddr_chips 1}} {\n\tif { $ddr_chips != 1 && $ddr_chips != 2 } {\n\t\terror \"Only 1 or 2 DDR chips permitted. Wrong value \"$ddr_chips\n\t}\n\n\tif { $ddr_type == \"mt47h64m16_3_333_cl5_async\" } {\n\t\tddr_spr3xx_mt47h64m16_3_333_cl5_async $ddr_chips\n\t\tset ddr_size 0x08000000\n\t## add here new DDR chip definition. Prototype:\n\t#} elseif { $ddr_type == \"?????\" } {\n\t#\t????? $ddr_chips\n\t#\tset ddr_size 0x?????\n\t} else {\n\t\terror \"sp3xx_ddr_init: unrecognized DDR type \"$ddr_type\n\t}\n\n\t# MPMC START\n\tmww 0xfc60001c 0x01000100\n\n\tif { $ddr_chips == 2 } {\n\t\techo [format \\\n\t\t\t\"Double chip DDR memory. Total memory size 0x%08x byte\" \\\n\t\t\t[expr {2 * $ddr_size}]]\n\t} else {\n\t\techo [format \\\n\t\t\t\"Single chip DDR memory. Memory size 0x%08x byte\" \\\n\t\t\t$ddr_size]\n\t}\n}\n\n\n# from Xloader file ddr/spr300_mt47h64m16_3_333_cl5_async.S\nproc ddr_spr3xx_mt47h64m16_3_333_cl5_async {ddr_chips} {\n\t# DDR_PAD_REG\n\tmww 0xfca800f0 0x00003aa5\n\n\t# Use \"1:2 sync\" only when DDR clock source is PLL1 and\n\t# HCLK is half of PLL1\n\tmww 0xfc600000 0x00000001\t;# MEMCTL_AHB_SET_00 # This is async\n\tmww 0xfc600004 0x00000000\t;# MEMCTL_AHB_SET_01\n#\tmww 0xfc600000 0x02020201\t;# MEMCTL_AHB_SET_00 # This is 1:2 sync\n#\tmww 0xfc600004 0x02020202\t;# MEMCTL_AHB_SET_01\n\n\tmww 0xfc600008 0x01000000\t;# MEMCTL_RFSH_SET_00\n\tmww 0xfc60000c 0x00000101\t;# MEMCTL_DLL_SET_00\n\tmww 0xfc600010 0x00000101\t;# MEMCTL_GP_00\n\tmww 0xfc600014 0x01000000\t;# MEMCTL_GP_01\n\tmww 0xfc600018 0x00010001\t;# MEMCTL_GP_02\n\tmww 0xfc60001c 0x00000100\t;# MEMCTL_GP_03\n\tmww 0xfc600020 0x00010001\t;# MEMCTL_GP_04\n\tif { $ddr_chips == 2 } {\n\t\tmww 0xfc600024 0x01020203\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x01000102\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000202\t;# MEMCTL_AHB_SET_02\n\t} else {\n\t\tmww 0xfc600024 0x00000201\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x02000001\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000201\t;# MEMCTL_AHB_SET_02\n\t}\n\tmww 0xfc600030 0x04040105\t;# MEMCTL_AHB_SET_03\n\tmww 0xfc600034 0x03030302\t;# MEMCTL_AHB_SET_04\n\tmww 0xfc600038 0x02040101\t;# MEMCTL_AHB_SET_05\n\tmww 0xfc60003c 0x00000002\t;# MEMCTL_AHB_SET_06\n\tmww 0xfc600044 0x03000405\t;# MEMCTL_DQS_SET_0\n\tmww 0xfc600048 0x03040002\t;# MEMCTL_TIME_SET_01\n\tmww 0xfc60004c 0x04000305\t;# MEMCTL_TIME_SET_02\n\tmww 0xfc600050 0x0505053f\t;# MEMCTL_AHB_RELPR_00\n\tmww 0xfc600054 0x05050505\t;# MEMCTL_AHB_RELPR_01\n\tmww 0xfc600058 0x04040405\t;# MEMCTL_AHB_RELPR_02\n\tmww 0xfc60005c 0x04040404\t;# MEMCTL_AHB_RELPR_03\n\tmww 0xfc600060 0x03030304\t;# MEMCTL_AHB_RELPR_04\n\tmww 0xfc600064 0x03030303\t;# MEMCTL_AHB_RELPR_05\n\tmww 0xfc600068 0x02020203\t;# MEMCTL_AHB_RELPR_06\n\tmww 0xfc60006c 0x02020202\t;# MEMCTL_AHB_RELPR_07\n\tmww 0xfc600070 0x01010102\t;# MEMCTL_AHB_RELPR_08\n\tmww 0xfc600074 0x01010101\t;# MEMCTL_AHB_RELPR_09\n\tmww 0xfc600078 0x00000001\t;# MEMCTL_AHB_RELPR_10\n\tmww 0xfc600088 0x0a0c0a00\t;# MEMCTL_DQS_SET_1\n\tmww 0xfc60008c 0x0000023f\t;# MEMCTL_GP_07\n\tmww 0xfc600090 0x00050a00\t;# MEMCTL_GP_08\n\tmww 0xfc600094 0x11000000\t;# MEMCTL_GP_09\n\tmww 0xfc600098 0x00001302\t;# MEMCTL_GP_10\n\tmww 0xfc60009c 0x00001c1c\t;# MEMCTL_DLL_SET_01\n\tmww 0xfc6000a0 0x7c000000\t;# MEMCTL_DQS_OUT_SHIFT\n\tmww 0xfc6000a4 0x005c0000\t;# MEMCTL_WR_DQS_SHIFT\n\tmww 0xfc6000a8 0x2b050e00\t;# MEMCTL_TIME_SET_03\n\tmww 0xfc6000ac 0x00640064\t;# MEMCTL_AHB_PRRLX_00\n\tmww 0xfc6000b0 0x00640064\t;# MEMCTL_AHB_PRRLX_01\n\tmww 0xfc6000b4 0x00000064\t;# MEMCTL_AHB_PRRLX_02\n\tmww 0xfc6000b8 0x00000000\t;# MEMCTL_OUTRANGE_LGTH\n\tmww 0xfc6000bc 0x00200020\t;# MEMCTL_AHB_RW_SET_00\n\tmww 0xfc6000c0 0x00200020\t;# MEMCTL_AHB_RW_SET_01\n\tmww 0xfc6000c4 0x00200020\t;# MEMCTL_AHB_RW_SET_02\n\tmww 0xfc6000c8 0x00200020\t;# MEMCTL_AHB_RW_SET_03\n\tmww 0xfc6000cc 0x00200020\t;# MEMCTL_AHB_RW_SET_04\n\tmww 0xfc6000d8 0x00000a24\t;# MEMCTL_TREF\n\tmww 0xfc6000dc 0x00000000\t;# MEMCTL_EMRS3_DATA\n\tmww 0xfc6000e0 0x5b1c00c8\t;# MEMCTL_TIME_SET_04\n\tmww 0xfc6000e4 0x00c8002e\t;# MEMCTL_TIME_SET_05\n\tmww 0xfc6000e8 0x00000000\t;# MEMCTL_VERSION\n\tmww 0xfc6000ec 0x0001046b\t;# MEMCTL_TINIT\n\tmww 0xfc6000f0 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_01\n\tmww 0xfc6000f4 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_02\n\tmww 0xfc600104 0x001c0000\t;# MEMCTL_DLL_DQS_DELAY_BYPASS_0\n\tmww 0xfc600108 0x0019001c\t;# MEMCTL_DLL_SET_02\n\tmww 0xfc60010c 0x00100000\t;# MEMCTL_DLL_SET_03\n\tmww 0xfc600110 0x001e007a\t;# MEMCTL_DQS_SET_2\n\tmww 0xfc600188 0x00000000\t;# MEMCTL_USER_DEF_REG_0\n\tmww 0xfc60018c 0x00000000\t;# MEMCTL_USER_DEF_REG_1\n\tmww 0xfc600190 0x01010001\t;# MEMCTL_GP_11\n\tmww 0xfc600194 0x01000000\t;# MEMCTL_GP_12\n\tmww 0xfc600198 0x00000001\t;# MEMCTL_GP_13\n\tmww 0xfc60019c 0x00400000\t;# MEMCTL_GP_14\n\tmww 0xfc6001a0 0x00000000\t;# MEMCTL_EMRS2_DATA_X\n\tmww 0xfc6001a4 0x00000000\t;# MEMCTL_LWPWR_CNT\n\tmww 0xfc6001a8 0x00000000\t;# MEMCTL_LWPWR_REG\n\tmww 0xfc6001ac 0x00860000\t;# MEMCTL_GP_15\n\tmww 0xfc6001b0 0x00000002\t;# MEMCTL_TPDEX\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/stm32/stm32.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/cortex_m3.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nsource [find chip/st/stm32/stm32_regs.tcl]\nsource [find chip/st/stm32/stm32_rcc.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/stm32/stm32_rcc.tcl",
    "content": "\nset RCC_CR            [expr {$RCC_BASE + 0x00}]\nset RCC_CFGR          [expr {$RCC_BASE + 0x04}]\nset RCC_CIR           [expr {$RCC_BASE + 0x08}]\nset RCC_APB2RSTR      [expr {$RCC_BASE + 0x0c}]\nset RCC_APB1RSTR      [expr {$RCC_BASE + 0x10}]\nset RCC_AHBENR        [expr {$RCC_BASE + 0x14}]\nset RCC_APB2ENR       [expr {$RCC_BASE + 0x18}]\nset RCC_APB1ENR       [expr {$RCC_BASE + 0x1c}]\nset RCC_BDCR          [expr {$RCC_BASE + 0x20}]\nset RCC_CSR           [expr {$RCC_BASE + 0x24}]\n\n\nproc show_RCC_CR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CR] } msg ] {\n\terror $msg\n    }\n\n    show_mmr_bitfield  0  0 $val HSI      { OFF ON }\n    show_mmr_bitfield  1  1 $val HSIRDY   { NOTRDY RDY  }\n    show_mmr_bitfield  7  3 $val HSITRIM  { _NUMBER_ }\n    show_mmr_bitfield 15  8 $val HSICAL   { _NUMBER_ }\n    show_mmr_bitfield 16 16 $val HSEON    { OFF ON }\n    show_mmr_bitfield 17 17 $val HSERDY   { NOTRDY RDY  }\n    show_mmr_bitfield 18 18 $val HSEBYP   { NOTBYPASSED BYPASSED }\n    show_mmr_bitfield 19 19 $val CSSON    { OFF ON }\n    show_mmr_bitfield 24 24 $val PLLON    { OFF ON }\n    show_mmr_bitfield 25 25 $val PLLRDY   { NOTRDY RDY }\n}\n\nproc show_RCC_CFGR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CFGR] } msg ] {\n\terror $msg\n    }\n\n\n    show_mmr_bitfield  1  0 $val  SW     { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  3  2 $val  SWS    { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  7  4 $val  HPRE   { sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_2 sysclk_div_4 sysclk_div_8 sysclk_div_16 sysclk_div_64 sysclk_div_128 sysclk_div_256 sysclk_div_512 }\n    show_mmr_bitfield 10  8 $val  PPRE1  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 13 11 $val  PPRE2  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 15 14 $val  ADCPRE { pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div2 pclk2_div4 pclk2_div8 pclk2_div16 }\n    show_mmr_bitfield 16 16 $val  PLLSRC { HSI_div_2 HSE }\n    show_mmr_bitfield 17 17 $val  PLLXTPRE { hse_div1 hse_div2 }\n    show_mmr_bitfield 21 18 $val  PLLMUL { x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x16 }\n    show_mmr_bitfield 22 22 $val  USBPRE { div1 div1_5 }\n    show_mmr_bitfield 26 24 $val  MCO    { none none none none SysClk HSI HSE PLL_div2 }\n}\n\n\nproc show_RCC_CIR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CIR] } msg ] {\n\terror $msg\n    }\n\n}\n\nproc show_RCC_APB2RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2RSTR] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB1RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1RSTR] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) uart5\n    set bits(19) uart4\n    set bits(18) uart3\n    set bits(17) uart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_AHBENR   { } {\n    if [ catch { set val [ show_mmr32_reg RCC_AHBENR  ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) xxx\n    set bits(14) xxx\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) xxx\n    set bits(10) sdio\n    set bits(9) xxx\n    set bits(8) fsmc\n    set bits(7) xxx\n    set bits(6) crce\n    set bits(5) xxx\n    set bits(4) flitf\n    set bits(3) xxx\n    set bits(2) sram\n    set bits(1) dma2\n    set bits(0) dma1\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB2ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_APB1ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) usart5\n    set bits(19) usart4\n    set bits(18) usart3\n    set bits(17) usart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_BDCR     { } {\n    if [ catch { set val [ show_mmr32_reg RCC_BDCR    ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lseon\n    set bits(1) lserdy\n    set bits(2) lsebyp\n    set bits(8) rtcsel0\n    set bits(9) rtcsel1\n    set bits(15) rtcen\n    set bits(16) bdrst\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_CSR      { } {\n    if [ catch { set val [ show_mmr32_reg RCC_CSR     ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lsion\n    set bits(1) lsirdy\n    set bits(24) rmvf\n    set bits(26) pin\n    set bits(27) por\n    set bits(28) sft\n    set bits(29) iwdg\n    set bits(30) wwdg\n    set bits(31) lpwr\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC { } {\n\n    show_RCC_CR\n    show_RCC_CFGR\n    show_RCC_CIR\n    show_RCC_APB2RSTR\n    show_RCC_APB1RSTR\n    show_RCC_AHBENR\n    show_RCC_APB2ENR\n    show_RCC_APB1ENR\n    show_RCC_BDCR\n    show_RCC_CSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/st/stm32/stm32_regs.tcl",
    "content": "# /* Peripheral and SRAM base address in the alias region */\nset PERIPH_BB_BASE        0x42000000\nset SRAM_BB_BASE          0x22000000\n\n# /*Peripheral and SRAM base address in the bit-band region */\nset SRAM_BASE             0x20000000\nset PERIPH_BASE           0x40000000\n\n# /*FSMC registers base address */\nset FSMC_R_BASE           0xA0000000\n\n# /*Peripheral memory map */\nset APB1PERIPH_BASE       [set PERIPH_BASE]\nset APB2PERIPH_BASE       [expr {$PERIPH_BASE + 0x10000}]\nset AHBPERIPH_BASE        [expr {$PERIPH_BASE + 0x20000}]\n\nset TIM2_BASE             [expr {$APB1PERIPH_BASE + 0x0000}]\nset TIM3_BASE             [expr {$APB1PERIPH_BASE + 0x0400}]\nset TIM4_BASE             [expr {$APB1PERIPH_BASE + 0x0800}]\nset TIM5_BASE             [expr {$APB1PERIPH_BASE + 0x0C00}]\nset TIM6_BASE             [expr {$APB1PERIPH_BASE + 0x1000}]\nset TIM7_BASE             [expr {$APB1PERIPH_BASE + 0x1400}]\nset RTC_BASE              [expr {$APB1PERIPH_BASE + 0x2800}]\nset WWDG_BASE             [expr {$APB1PERIPH_BASE + 0x2C00}]\nset IWDG_BASE             [expr {$APB1PERIPH_BASE + 0x3000}]\nset SPI2_BASE             [expr {$APB1PERIPH_BASE + 0x3800}]\nset SPI3_BASE             [expr {$APB1PERIPH_BASE + 0x3C00}]\nset USART2_BASE           [expr {$APB1PERIPH_BASE + 0x4400}]\nset USART3_BASE           [expr {$APB1PERIPH_BASE + 0x4800}]\nset UART4_BASE            [expr {$APB1PERIPH_BASE + 0x4C00}]\nset UART5_BASE            [expr {$APB1PERIPH_BASE + 0x5000}]\nset I2C1_BASE             [expr {$APB1PERIPH_BASE + 0x5400}]\nset I2C2_BASE             [expr {$APB1PERIPH_BASE + 0x5800}]\nset CAN_BASE              [expr {$APB1PERIPH_BASE + 0x6400}]\nset BKP_BASE              [expr {$APB1PERIPH_BASE + 0x6C00}]\nset PWR_BASE              [expr {$APB1PERIPH_BASE + 0x7000}]\nset DAC_BASE              [expr {$APB1PERIPH_BASE + 0x7400}]\n\nset AFIO_BASE             [expr {$APB2PERIPH_BASE + 0x0000}]\nset EXTI_BASE             [expr {$APB2PERIPH_BASE + 0x0400}]\nset GPIOA_BASE            [expr {$APB2PERIPH_BASE + 0x0800}]\nset GPIOB_BASE            [expr {$APB2PERIPH_BASE + 0x0C00}]\nset GPIOC_BASE            [expr {$APB2PERIPH_BASE + 0x1000}]\nset GPIOD_BASE            [expr {$APB2PERIPH_BASE + 0x1400}]\nset GPIOE_BASE            [expr {$APB2PERIPH_BASE + 0x1800}]\nset GPIOF_BASE            [expr {$APB2PERIPH_BASE + 0x1C00}]\nset GPIOG_BASE            [expr {$APB2PERIPH_BASE + 0x2000}]\nset ADC1_BASE             [expr {$APB2PERIPH_BASE + 0x2400}]\nset ADC2_BASE             [expr {$APB2PERIPH_BASE + 0x2800}]\nset TIM1_BASE             [expr {$APB2PERIPH_BASE + 0x2C00}]\nset SPI1_BASE             [expr {$APB2PERIPH_BASE + 0x3000}]\nset TIM8_BASE             [expr {$APB2PERIPH_BASE + 0x3400}]\nset USART1_BASE           [expr {$APB2PERIPH_BASE + 0x3800}]\nset ADC3_BASE             [expr {$APB2PERIPH_BASE + 0x3C00}]\n\nset SDIO_BASE             [expr {$PERIPH_BASE + 0x18000}]\n\nset DMA1_BASE             [expr {$AHBPERIPH_BASE + 0x0000}]\nset DMA1_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0008}]\nset DMA1_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x001C}]\nset DMA1_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0030}]\nset DMA1_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0044}]\nset DMA1_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0058}]\nset DMA1_Channel6_BASE    [expr {$AHBPERIPH_BASE + 0x006C}]\nset DMA1_Channel7_BASE    [expr {$AHBPERIPH_BASE + 0x0080}]\nset DMA2_BASE             [expr {$AHBPERIPH_BASE + 0x0400}]\nset DMA2_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0408}]\nset DMA2_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x041C}]\nset DMA2_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0430}]\nset DMA2_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0444}]\nset DMA2_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0458}]\nset RCC_BASE              [expr {$AHBPERIPH_BASE + 0x1000}]\nset CRC_BASE              [expr {$AHBPERIPH_BASE + 0x3000}]\n\n# /*Flash registers base address */\nset FLASH_R_BASE          [expr {$AHBPERIPH_BASE + 0x2000}]\n# /*Flash Option Bytes base address */\nset OB_BASE               0x1FFFF800\n\n# /*FSMC Bankx registers base address */\nset FSMC_Bank1_R_BASE     [expr {$FSMC_R_BASE + 0x0000}]\nset FSMC_Bank1E_R_BASE    [expr {$FSMC_R_BASE + 0x0104}]\nset FSMC_Bank2_R_BASE     [expr {$FSMC_R_BASE + 0x0060}]\nset FSMC_Bank3_R_BASE     [expr {$FSMC_R_BASE + 0x0080}]\nset FSMC_Bank4_R_BASE     [expr {$FSMC_R_BASE + 0x00A0}]\n\n# /*Debug MCU registers base address */\nset DBGMCU_BASE           0xE0042000\n\n# /*System Control Space memory map */\nset SCS_BASE              0xE000E000\n\nset SysTick_BASE          [expr {$SCS_BASE + 0x0010}]\nset NVIC_BASE             [expr {$SCS_BASE + 0x0100}]\nset SCB_BASE              [expr {$SCS_BASE + 0x0D00}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/ti/lm3s/lm3s.tcl",
    "content": "source [find chip/ti/lm3s/lm3s_regs.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/chip/ti/lm3s/lm3s_regs.tcl",
    "content": "#*****************************************************************************\n#\n# The following are defines for the System Control register addresses.\n#\n#*****************************************************************************\n\nset SYSCTL_DID0             0x400FE000  ;# Device Identification 0\nset SYSCTL_DID1             0x400FE004  ;# Device Identification 1\nset SYSCTL_DC0              0x400FE008  ;# Device Capabilities 0\nset SYSCTL_DC1              0x400FE010  ;# Device Capabilities 1\nset SYSCTL_DC2              0x400FE014  ;# Device Capabilities 2\nset SYSCTL_DC3              0x400FE018  ;# Device Capabilities 3\nset SYSCTL_DC4              0x400FE01C  ;# Device Capabilities 4\nset SYSCTL_DC5              0x400FE020  ;# Device Capabilities 5\nset SYSCTL_DC6              0x400FE024  ;# Device Capabilities 6\nset SYSCTL_DC7              0x400FE028  ;# Device Capabilities 7\nset SYSCTL_DC8              0x400FE02C  ;# Device Capabilities 8 ADC\n                                        ;# Channels\nset SYSCTL_PBORCTL          0x400FE030  ;# Brown-Out Reset Control\nset SYSCTL_LDOPCTL          0x400FE034  ;# LDO Power Control\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\nset SYSCTL_RIS              0x400FE050  ;# Raw Interrupt Status\nset SYSCTL_IMC              0x400FE054  ;# Interrupt Mask Control\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and\n                                        ;# Clear\nset SYSCTL_RESC             0x400FE05C  ;# Reset Cause\nset SYSCTL_RCC              0x400FE060  ;# Run-Mode Clock Configuration\nset SYSCTL_PLLCFG           0x400FE064  ;# XTAL to PLL Translation\nset SYSCTL_GPIOHSCTL        0x400FE06C  ;# GPIO High-Speed Control\nset SYSCTL_GPIOHBCTL        0x400FE06C  ;# GPIO High-Performance Bus\n                                        ;# Control\nset SYSCTL_RCC2             0x400FE070  ;# Run-Mode Clock Configuration 2\nset SYSCTL_MOSCCTL          0x400FE07C  ;# Main Oscillator Control\nset SYSCTL_RCGC0            0x400FE100  ;# Run Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_RCGC1            0x400FE104  ;# Run Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_RCGC2            0x400FE108  ;# Run Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_SCGC0            0x400FE110  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_SCGC1            0x400FE114  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_SCGC2            0x400FE118  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_DCGC0            0x400FE120  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 0\nset SYSCTL_DCGC1            0x400FE124  ;# Deep-Sleep Mode Clock Gating\n                                        ;# Control Register 1\nset SYSCTL_DCGC2            0x400FE128  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 2\nset SYSCTL_DSLPCLKCFG       0x400FE144  ;# Deep Sleep Clock Configuration\nset SYSCTL_CLKVCLR          0x400FE150  ;# Clock Verification Clear\nset SYSCTL_PIOSCCAL         0x400FE150  ;# Precision Internal Oscillator\n                                        ;# Calibration\nset SYSCTL_PIOSCSTAT        0x400FE154  ;# Precision Internal Oscillator\n                                        ;# Statistics\nset SYSCTL_LDOARST          0x400FE160  ;# Allow Unregulated LDO to Reset\n                                        ;# the Part\nset SYSCTL_I2SMCLKCFG       0x400FE170  ;# I2S MCLK Configuration\nset SYSCTL_DC9              0x400FE190  ;# Device Capabilities 9 ADC\n                                        ;# Digital Comparators\nset SYSCTL_NVMSTAT          0x400FE1A0  ;# Non-Volatile Memory Information\n\nset SYSCTL_RCC_USESYSDIV    0x00400000  ;# Enable System Clock Divider\nset SYSCTL_RCC2_BYPASS2     0x00000800  ;# PLL Bypass 2\nset SYSCTL_RCC_MOSCDIS      0x00000001  ;# Main Oscillator Disable\n\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\n\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and Clear\n\nset FLASH_FMA               0x400FD000  ;# Flash Memory Address\nset FLASH_FMD               0x400FD004  ;# Flash Memory Data\nset FLASH_FMC               0x400FD008  ;# Flash Memory Control\nset FLASH_FCRIS             0x400FD00C  ;# Flash Controller Raw Interrupt Status\nset FLASH_FCIM              0x400FD010  ;# Flash Controller Interrupt Mask\nset FLASH_FCMISC            0x400FD014  ;# Flash Controller Masked Interrupt Status and Clear\nset FLASH_FMC2              0x400FD020  ;#  Flash Memory Control 2\nset FLASH_FWBVAL            0x400FD030  ;# Flash Write Buffer Valid\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/altera-5m570z-cpld.cfg",
    "content": "# Altera MAXV 5M24OZ/5M570Z CPLD\n# see MAX V Device Handbook\n# Table 6-3: 32-Bit MAX V Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0111     000 0110 1110    1\njtag newtap 5m570z tap -expected-id 0x020a60dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/altera-epm240.cfg",
    "content": "# Altera MAXII EPM240T100C CPLD\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME epm240\n}\n\n# see MAX II Device Handbook\n# Table 3-3: 32-Bit MAX II Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0001     000 0110 1110    1\njtag newtap $_CHIPNAME tap -irlen 10 \\\n\t-expected-id 0x020a10dd \\\n\t-expected-id 0x020a20dd \\\n\t-expected-id 0x020a30dd \\\n\t-expected-id 0x020a40dd \\\n\t-expected-id 0x020a50dd \\\n\t-expected-id 0x020a60dd\n\n# 200ns seems like a good speed\n# c.f. Table 5-34: MAX II JTAG Timing Parameters\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/jtagspi.cfg",
    "content": "set _USER1 0x02\n\nif { [info exists JTAGSPI_IR] } {\n\tset _JTAGSPI_IR $JTAGSPI_IR\n} else {\n\tset _JTAGSPI_IR $_USER1\n}\n\nif { [info exists TARGETNAME] } {\n\tset _TARGETNAME $TARGETNAME\n} else {\n\tset _TARGETNAME $_CHIPNAME.proxy\n}\n\nif { [info exists FLASHNAME] } {\n\tset _FLASHNAME $FLASHNAME\n} else {\n\tset _FLASHNAME $_CHIPNAME.spi\n}\n\ntarget create $_TARGETNAME testee -chain-position $_CHIPNAME.tap\nflash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR\n\nproc jtagspi_init {chain_id proxy_bit} {\n\t# load proxy bitstream $proxy_bit and probe spi flash\n\tglobal _FLASHNAME\n\tpld load $chain_id $proxy_bit\n\treset halt\n\tflash probe $_FLASHNAME\n}\n\nproc jtagspi_program {bin addr} {\n\t# write and verify binary file $bin at offset $addr\n\tglobal _FLASHNAME\n\tflash write_image erase $bin $addr\n\tflash verify_bank $_FLASHNAME $bin $addr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/lattice-lc4032ze.cfg",
    "content": "# Lattice ispMACH 4000ZE family, device LC4032ZE\n# just configure a tap\njtag newtap LC4032ZE tap -irlen 8 -expected-id  0x01806043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xc6s.cfg",
    "content": "# xilinx spartan6\n# http://www.xilinx.com/support/documentation/user_guides/ug380.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc6s\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x04000093 \\\n\t-expected-id 0x04001093 \\\n\t-expected-id 0x04002093 \\\n\t-expected-id 0x04004093 \\\n\t-expected-id 0x04024093 \\\n\t-expected-id 0x04008093 \\\n\t-expected-id 0x04028093 \\\n\t-expected-id 0x0400E093 \\\n\t-expected-id 0x0402E093 \\\n\t-expected-id 0x04011093 \\\n\t-expected-id 0x04031093 \\\n\t-expected-id 0x0401D093 \\\n\t-expected-id 0x0403D093\n\npld device virtex2 $_CHIPNAME.tap\n\nset XC6S_CFG_IN 0x05\nset XC6S_JSHUTDOWN 0x0d\nset XC6S_JPROGRAM 0x0b\nset XC6S_JSTART 0x0c\nset XC6S_BYPASS 0x3f\n\nproc xc6s_program {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JPROGRAM XC6S_JSTART XC6S_BYPASS\n\tirscan $tap $XC6S_JSHUTDOWN\n\tirscan $tap $XC6S_JPROGRAM\n\tirscan $tap $XC6S_JSTART\n\tirscan $tap $XC6S_BYPASS\n}\n\n#xtp038 and xc3sprog approach\nproc xc6s_program_iprog {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JSTART XC6S_BYPASS XC6S_CFG_IN\n\tirscan $tap $XC6S_JSHUTDOWN\n\truntest 16\n\tirscan $tap $XC6S_CFG_IN\n\t# xtp038 IPROG 16bit flipped\n\tdrscan $tap 16 0xffff 16 0x9955 16 0x66aa 16 0x850c 16 0x7000 16 0x0004\n\tirscan $tap $XC6S_JSTART\n\truntest 32\n\tirscan $tap $XC6S_BYPASS\n\truntest 1\n}\n\nset XC6S_ISC_ENABLE 0x10\nset XC6S_ISC_DISABLE 0x16\nset XC6S_ISC_DNA 0x30\n\n# Get the \"Device DNA\" from the Spartan 6.\n# Most Xilinx FPGA devices contain an embedded, unique device identifier called\n# the \"Device DNA\". The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\nproc xc6s_get_dna {tap} {\n\tglobal XC6S_ISC_ENABLE XC6S_ISC_DISABLE XC6S_ISC_DNA\n\tirscan $tap $XC6S_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC6S_ISC_DNA\n\t# Device DNA is 57 bits long, but we can only read 32bits at a time\n\t# with OpenOCD.\n\tset dna [drscan $tap 16 0 16 0 16 0 9 0]\n\truntest 64\n\tirscan $tap $XC6S_ISC_DISABLE\n\truntest 64\n\n\t# Convert the binary data into the order impact uses\n\tscan $dna \"%x %x %x %x\" v1 v2 v3 v4\n\tset bin_dna [string reverse [concat [format \"%09b\" $v4][format \"%016b\" $v3][format \"%016b\" $v2][format \"%016b\" $v1]]]\n\n\t# Return a hex version of binary\n\tscan [format \"0b%s\" $bin_dna] \"%i\" hex_dna\n\treturn $hex_dna\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xc6s_print_dna {tap} {\n\tset hex_dna [xc6s_get_dna $tap]\n\n\tputs [format \"DNA = %57b (0x%x)\\n\" $hex_dna $hex_dna]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xc7.cfg",
    "content": "# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7\n}\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x03622093 \\\n\t-expected-id 0x03620093 \\\n\t-expected-id 0x037C4093 \\\n\t-expected-id 0x0362F093 \\\n\t-expected-id 0x037C8093 \\\n\t-expected-id 0x037C7093 \\\n\t-expected-id 0x037C3093 \\\n\t-expected-id 0x0362E093 \\\n\t-expected-id 0x037C2093 \\\n\t-expected-id 0x0362D093 \\\n\t-expected-id 0x0362C093 \\\n\t-expected-id 0x03632093 \\\n\t-expected-id 0x03631093 \\\n\t-expected-id 0x03636093 \\\n\t-expected-id 0x03647093 \\\n\t-expected-id 0x0364C093 \\\n\t-expected-id 0x03651093 \\\n\t-expected-id 0x03747093 \\\n\t-expected-id 0x03656093 \\\n\t-expected-id 0x03752093 \\\n\t-expected-id 0x03751093 \\\n\t-expected-id 0x03671093 \\\n\t-expected-id 0x036B3093 \\\n\t-expected-id 0x036B7093 \\\n\t-expected-id 0x036BB093 \\\n\t-expected-id 0x036BF093 \\\n\t-expected-id 0x03667093 \\\n\t-expected-id 0x03682093 \\\n\t-expected-id 0x03687093 \\\n\t-expected-id 0x03692093 \\\n\t-expected-id 0x03691093 \\\n\t-expected-id 0x03696093 \\\n\t-expected-id 0x036D5093 \\\n\t-expected-id 0x036D9093 \\\n\t-expected-id 0x036DB093\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc xc7_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xcf-p.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF08P <v>5057093\n# XCF16P <v>5058093\n# XCF32P <v>5059093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 16 -ignore-version \\\n\t-expected-id 0x05057093 \\\n\t-expected-id 0x05058093 \\\n\t-expected-id 0x05059093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_P xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xcf-s.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF01S <v>5044093\n# XCF02S <v>5045093\n# XCF04S <v>5046093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 8 -ignore-version \\\n\t-expected-id 0x05044093 \\\n\t-expected-id 0x05045093 \\\n\t-expected-id 0x05046093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_S xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xcr3256.cfg",
    "content": "#xilinx coolrunner xcr3256\n#simple device - just configure a tap\njtag newtap xcr tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id  0x0494c093\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpld/xilinx-xcu.cfg",
    "content": "# Xilinx Ultrascale (Kintex, Virtex, Zynq)\n# https://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcu\n}\n\n# The cvarious chips in the Ultrascale family have different IR length.\n# Set $CHIP before including this file to determine the device.\narray set _XCU_DATA {\n\tXCKU025 {0x03824093 6}\n\tXCKU035 {0x03823093 6}\n\tXCKU040 {0x03822093 6}\n\tXCKU060 {0x03919093 6}\n\tXCKU095 {0x03844093 6}\n\tXCKU3P {0x04A63093 6}\n\tXCKU5P {0x04A62093 6}\n\tXCKU9P {0x0484A093 6}\n\tXCKU11P {0x04A4E093 6}\n\tXCKU13P {0x04A52093 6}\n\tXCKU15P {0x04A56093 6}\n\tXCVU065 {0x03939093 6}\n\tXCVU080 {0x03843093 6}\n\tXCVU095 {0x03842093 6}\n\tXCVU3P {0x04B39093 6}\n\tXCKU085 {0x0380F093 12}\n\tXCKU115 {0x0390D093 12}\n\tXCVU125 {0x0392D093 12}\n\tXCVU5P {0x04B2B093 12}\n\tXCVU7P {0x04B29093 12}\n\tXCVU160 {0x03933093 18}\n\tXCVU190 {0x03931093 18}\n\tXCVU440 {0x0396D093 18}\n\tXCVU9P {0x04B31093 18}\n\tXCVU11P {0x04B49093 18}\n\tXCVU13P {0x04B51093 24}\n}\n\nif { ![info exists CHIP] } {\n\terror \"set CHIP to one of \"[concat [array names _XCU_DATA]]\n}\n\nif { ![llength [array names _XCU_DATA $CHIP]] } {\n\terror \"unknown CHIP: \"$CHIP\n}\n\nset _EXPID [lindex $_XCU_DATA($CHIP) 0]\nset _IRLEN [lindex $_XCU_DATA($CHIP) 1]\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen $_IRLEN -ignore-version -expected-id $_EXPID\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XCU_JSHUTDOWN 0x0d\nset XCU_JPROGRAM 0x0b\nset XCU_JSTART 0x0c\nset XCU_BYPASS 0x3f\n\nproc xcu_program {tap} {\n\tglobal XCU_JSHUTDOWN XCU_JPROGRAM XCU_JSTART XCU_BYPASS\n\tirscan $tap $XCU_JSHUTDOWN\n\tirscan $tap $XCU_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XCU_JSTART\n\truntest 2000\n\tirscan $tap $XCU_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arc/common.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Things common to all ARCs\n\n# It is assumed that target is already halted.\nproc arc_common_reset { {target \"\"} } {\n        if { $target != \"\" } {\n                targets $target\n        }\n\n        halt\n\n        # 1. Interrupts are disabled (STATUS32.IE)\n        # 2. The status register flags are cleared.\n        # All fields, except the H bit, are set to 0 when the processor is Reset.\n\n        arc jtag set-aux-reg 0xA 0x1\n\n        # 3. The loop count, loop start, and loop end registers are cleared.\n        arc jtag set-core-reg 60 0\n        arc jtag set-aux-reg 0x2 0\n        arc jtag set-aux-reg 0x3 0\n\n        # Program execution begins at the address referenced by the four byte reset\n        # vector located at the interrupt vector base address, which is the first\n        # entry (offset 0x00) in the vector table.\n        set int_vector_base [arc jtag get-aux-reg 0x25]\n        set start_pc [read_memory $int_vector_base 32 1]\n        arc jtag set-aux-reg 0x6 $start_pc\n\n        # It is OK to do uncached writes - register cache will be invalidated by\n        # the reset_assert() function.\n}\n\n# vim:expandtab:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arc/em.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_em_examine_target { {target \"\"} } {\n\t# Will set current target\n\tarc_v2_examine_target $target\n}\n\nproc arc_em_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_em_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_em_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Set DEBUG.ED bit to enable clock in actionpoint module.\n\t# This is specific to ARC EM.\n\tset debug [arc jtag get-aux-reg 5]\n\tif { !($debug & (1 << 20)) } {\n\t\tarc jtag set-aux-reg 5 [expr {$debug | (1 << 20)}]\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arc/hs.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_hs_examine_target { target } {\n\t# Will set current target for us.\n\tarc_v2_examine_target $target\n}\n\nproc arc_hs_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_hs_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_hs_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Invalidate L2 cache if there is one.\n\tset l2_config [$target arc jtag get-aux-reg 0x901]\n\t# Will return 0, if cache is not present and register doesn't exist.\n\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\tif { ($l2_config != 0) && (($l2_ctrl & 1) == 0) } {\n\t\tputs \"L2 cache is present and not disabled\"\n\n\t\t# Wait until BUSY bit is 0.\n\t\tputs \"Invalidating L2 cache...\"\n\t\t$target arc jtag set-aux-reg 0x905 1\n\t\t# Dummy read of SLC_AUX_CACHE_CTRL bit, as described in:\n\t\t# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/arch/arc?id=c70c473396cbdec1168a6eff60e13029c0916854\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\twhile { ($l2_ctrl & 0x100) != 0 } {\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t}\n\n\t\t# Flush cache if needed. If SLC_AUX_CACHE_CTRL.IM is 1, then invalidate\n\t\t# operation already flushed everything.\n\t\tif { ($l2_ctrl & 0x40) == 0 } {\n\t\t\tputs \"Flushing L2 cache...\"\n\t\t\t$target arc jtag set-aux-reg 0x904 1\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\twhile { [expr {$l2_ctrl & 0x100}] != 0 } {\n\t\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\t}\n\t\t}\n\n\t\tputs \"L2 cache has been flushed and invalidated.\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arc/v2.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/common.tcl]\n\n# Currently 'examine_target' can only read JTAG registers and set properties -\n# but it shouldn't write any of registers - writes will be cached, but cache\n# will be invalidated before flushing after examine_target, and changes will be\n# lost.  Perhaps that would be fixed later - perhaps writes shouldn't be cached\n# after all.  But if write to register is really needed from TCL - then it\n# should be done via \"arc jtag\" for now.\nproc arc_v2_examine_target { {target \"\"} } {\n\t# Set current target, because OpenOCD event handlers don't do this for us.\n\tif { $target != \"\" } {\n\t\ttargets $target\n\t}\n\n\t# Those registers always exist. DEBUG and DEBUGI are formally optional,\n\t# however they come with JTAG interface, and so far there is no way\n\t# OpenOCD can communicate with target without JTAG interface.\n\tarc set-reg-exists identity pc status32 bta debug lp_start lp_end \\\n\t\teret erbta erstatus ecr efa\n\n\t# 32 core registers\n\tarc set-reg-exists \\\n\t\tr0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r10 r11 r12 \\\n\t\tr13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 \\\n\t\tgp fp sp ilink r30 blink lp_count pcl\n\n\t# Actionpoints\n\tif { [arc get-reg-field ap_build version] == 5 } {\n\t\tset ap_build_type [arc get-reg-field ap_build type]\n\t\t# AP_BUILD.TYPE > 0b0110 is reserved in current ISA.\n\t\t# Current ISA supports up to 8 actionpoints.\n\t\tif { $ap_build_type < 8 } {\n\t\t\t# Two LSB bits of AP_BUILD.TYPE define amount of actionpoints:\n\t\t\t# 0b00 - 2 actionpoints\n\t\t\t# 0b01 - 4 actionpoints\n\t\t\t# 0b10 - 8 actionpoints\n\t\t\t# 0b11 - reserved.\n\t\t\tset ap_num [expr {0x2 << ($ap_build_type & 3)}]\n\t\t\t# Expression on top may produce 16 action points - which is a\n\t\t\t# reserved value for now.\n\t\t\tif { $ap_num < 16 } {\n\t\t\t\t# Enable actionpoint registers\n\t\t\t\tfor {set i 0} {$i < $ap_num} {incr i} {\n\t\t\t\t\tarc set-reg-exists ap_amv$i ap_amm$i ap_ac$i\n\t\t\t\t}\n\n\t\t\t\t# Set amount of actionpoints\n\t\t\t\tarc num-actionpoints $ap_num\n\t\t\t}\n\t\t}\n\t}\n\n\t# DCCM\n\tset dccm_version [arc get-reg-field dccm_build version]\n\tif { $dccm_version == 3 || $dccm_version == 4 } {\n\t\tarc set-reg-exists aux_dccm\n\t}\n\n\t# ICCM\n\tif { [arc get-reg-field iccm_build version] == 4 } {\n\t\tarc set-reg-exists aux_iccm\n\t}\n\n\t# MPU\n\tif { [arc get-reg-field mpu_build version] >= 2 &&\n\t\t [arc get-reg-field mpu_build version] <= 4 } {\n\t\tarc set-reg-exists mpu_en mpu_ecr\n\t\tset mpu_regions [arc get-reg-field mpu_build regions]\n\t\tfor {set i 0} {$i < $mpu_regions} {incr i} {\n\t\t\tarc set-reg-exists mpu_rdp$i mpu_rdb$i\n\t\t}\n\n\t\t# Secure MPU\n\t\tif { [arc get-reg-field mpu_build version] == 4 } {\n\t\t\tarc set-reg-exists mpu_index mpu_rstart mpu_rend mpu_rper\n\t\t}\n\t}\n}\n\nproc arc_v2_init_regs { } {\n\t# XML features\n\tset core_feature \"org.gnu.gdb.arc.core.v2\"\n\tset aux_min_feature \"org.gnu.gdb.arc.aux-minimal\"\n\tset aux_other_feature \"org.gnu.gdb.arc.aux-other\"\n\n\t# Describe types\n\t# Types are sorted alphabetically according to their name.\n\tarc add-reg-type-struct -name ap_build_t -bitfield version 0 7 \\\n\t\t-bitfield type 8 11\n\tarc add-reg-type-struct -name ap_control_t -bitfield at 0 3 -bitfield tt 4 5 \\\n\t\t-bitfield m 6 6 -bitfield p 7 7 -bitfield aa 8 8 -bitfield q 9 9\n\t# Cycles field added in version 4.\n\tarc add-reg-type-struct -name dccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield size0 8 11 -bitfield size1 12 15 -bitfield cycles 17 19\n\n\tarc add-reg-type-struct -name debug_t \\\n\t\t-bitfield fh 1 1   -bitfield ah 2 2   -bitfield asr 3 10 \\\n\t\t-bitfield is 11 11 -bitfield ep 19 19 -bitfield ed 20 20 \\\n\t\t-bitfield eh 21 21 -bitfield ra 22 22 -bitfield zz 23 23 \\\n\t\t-bitfield sm 24 26 -bitfield ub 28 28 -bitfield bh 29 29 \\\n\t\t-bitfield sh 30 30 -bitfield ld 31 31\n\n\tarc add-reg-type-struct -name ecr_t \\\n\t\t-bitfield parameter 0 7 \\\n\t\t-bitfield cause 8 15 \\\n\t\t-bitfield vector 16 23 \\\n\t\t-bitfield U 30 30 \\\n\t\t-bitfield P 31 31\n\tarc add-reg-type-struct -name iccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield iccm0_size0  8 11 -bitfield iccm1_size0 12 15 \\\n\t\t-bitfield iccm0_size1 16 19 -bitfield iccm1_size1 20 23\n\tarc add-reg-type-struct -name identity_t \\\n\t\t-bitfield arcver 0 7 -bitfield arcnum 8 15 -bitfield chipid 16 31\n\tarc add-reg-type-struct -name isa_config_t -bitfield version 0 7 \\\n\t\t-bitfield pc_size 8 11 -bitfield lpc_size 12 15 -bitfield addr_size 16 19 \\\n\t\t-bitfield b 20 20 -bitfield a 21 21 -bitfield n 22 22 -bitfield l 23 23 \\\n\t\t-bitfield c 24 27 -bitfield d 28 31\n\tarc add-reg-type-struct -name mpu_build_t -bitfield version 0 7 \\\n\t\t-bitfield regions 8 15 \\\n\t\t-bitfield s 16 16 \\\n\t\t-bitfield i 17 17\n\tarc add-reg-type-struct -name mpu_ecr_t \\\n\t\t-bitfield MR 0 7 \\\n\t\t-bitfield VT 8 9 \\\n\t\t-bitfield EC_CODE 16 31\n\tarc add-reg-type-struct -name mpu_en_t \\\n\t\t-bitfield UE  3  3 -bitfield UW   4  4 -bitfield UR 5 5 \\\n\t\t-bitfield KE  6  6 -bitfield KW   7  7 -bitfield KR 8 8 \\\n\t\t-bitfield S  15 15 -bitfield SID 16 23 \\\n\t\t-bitfield EN 30 30\n\tarc add-reg-type-struct -name mpu_index_t \\\n\t\t-bitfield I 0 3 -bitfield M 30 30 -bitfield D 31 31\n\tarc add-reg-type-struct -name mpu_rper_t \\\n\t\t-bitfield V 0 0 \\\n\t\t-bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \\\n\t\t-bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \\\n\t\t-bitfield S 15 15 -bitfield SID 16 23\n\tarc add-reg-type-flags -name status32_t \\\n\t\t-flag   H  0 -flag E0   1 -flag E1   2 -flag E2  3 \\\n\t\t-flag  E3  4 -flag AE   5 -flag DE   6 -flag  U  7 \\\n\t\t-flag   V  8 -flag  C   9 -flag  N  10 -flag  Z 11 \\\n\t\t-flag   L 12 -flag DZ  13 -flag SC  14 -flag ES 15 \\\n\t\t-flag RB0 16 -flag RB1 17 -flag RB2 18 \\\n\t\t-flag  AD 19 -flag US  20 -flag IE  31\n\n\t# Core registers\n\tset core_regs {\n\t\tr0       0  uint32\n\t\tr1       1  uint32\n\t\tr2       2  uint32\n\t\tr3       3  uint32\n\t\tr4       4  uint32\n\t\tr5       5  uint32\n\t\tr6       6  uint32\n\t\tr7       7  uint32\n\t\tr8       8  uint32\n\t\tr9       9  uint32\n\t\tr10      10 uint32\n\t\tr11      11 uint32\n\t\tr12      12 uint32\n\t\tr13      13 uint32\n\t\tr14      14 uint32\n\t\tr15      15 uint32\n\t\tr16      16 uint32\n\t\tr17      17 uint32\n\t\tr18      18 uint32\n\t\tr19      19 uint32\n\t\tr20      20 uint32\n\t\tr21      21 uint32\n\t\tr22      23 uint32\n\t\tr23      24 uint32\n\t\tr24      24 uint32\n\t\tr25      25 uint32\n\t\tgp       26 data_ptr\n\t\tfp       27 data_ptr\n\t\tsp       28 data_ptr\n\t\tilink    29 code_ptr\n\t\tr30      30 uint32\n\t\tblink    31 code_ptr\n\t\tr32      32 uint32\n\t\tr33      33 uint32\n\t\tr34      34 uint32\n\t\tr35      35 uint32\n\t\tr36      36 uint32\n\t\tr37      37 uint32\n\t\tr38      38 uint32\n\t\tr39      39 uint32\n\t\tr40      40 uint32\n\t\tr41      41 uint32\n\t\tr42      42 uint32\n\t\tr43      43 uint32\n\t\tr44      44 uint32\n\t\tr45      45 uint32\n\t\tr46      46 uint32\n\t\tr47      47 uint32\n\t\tr48      48 uint32\n\t\tr49      49 uint32\n\t\tr50      50 uint32\n\t\tr51      51 uint32\n\t\tr52      52 uint32\n\t\tr53      53 uint32\n\t\tr54      54 uint32\n\t\tr55      55 uint32\n\t\tr56      56 uint32\n\t\tr57      57 uint32\n\t\taccl     58 uint32\n\t\tacch     59 uint32\n\t\tlp_count 60 uint32\n\t\tlimm     61 uint32\n\t\treserved 62 uint32\n\t\tpcl      63 code_ptr\n\t}\n\tforeach {reg count type} $core_regs {\n\t\tarc add-reg -name $reg -num $count -core -type $type -g \\\n\t\t\t-feature $core_feature\n\t}\n\n\t# AUX min\n\tset aux_min {\n\t\t0x6 pc       code_ptr\n\t\t0x2 lp_start code_ptr\n\t\t0x3 lp_end   code_ptr\n\t\t0xA status32 status32_t\n\t}\n\tforeach {num name type} $aux_min {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_min_feature -g\n\t}\n\n\t# AUX other\n\tset aux_other {\n\t\t0x004 identity\tidentity_t\n\t\t0x005 debug\t\tdebug_t\n\t\t0x018 aux_dccm\tint\n\t\t0x208 aux_iccm\tint\n\n\t\t0x220 ap_amv0\tuint32\n\t\t0x221 ap_amm0\tuint32\n\t\t0x222 ap_ac0\tap_control_t\n\t\t0x223 ap_amv1\tuint32\n\t\t0x224 ap_amm1\tuint32\n\t\t0x225 ap_ac1\tap_control_t\n\t\t0x226 ap_amv2\tuint32\n\t\t0x227 ap_amm2\tuint32\n\t\t0x228 ap_ac2\tap_control_t\n\t\t0x229 ap_amv3\tuint32\n\t\t0x22A ap_amm3\tuint32\n\t\t0x22B ap_ac3\tap_control_t\n\t\t0x22C ap_amv4\tuint32\n\t\t0x22D ap_amm4\tuint32\n\t\t0x22E ap_ac4\tap_control_t\n\t\t0x22F ap_amv5\tuint32\n\t\t0x230 ap_amm5\tuint32\n\t\t0x231 ap_ac5\tap_control_t\n\t\t0x232 ap_amv6\tuint32\n\t\t0x233 ap_amm6\tuint32\n\t\t0x234 ap_ac6\tap_control_t\n\t\t0x235 ap_amv7\tuint32\n\t\t0x236 ap_amm7\tuint32\n\t\t0x237 ap_ac7\tap_control_t\n\n\t\t0x400 eret\t\tcode_ptr\n\t\t0x401 erbta\t\tcode_ptr\n\t\t0x402 erstatus\tstatus32_t\n\t\t0x403 ecr\t\tecr_t\n\t\t0x404 efa\t\tdata_ptr\n\n\t\t0x409 mpu_en\tmpu_en_t\n\n\t\t0x412 bta\t\tcode_ptr\n\n\t\t0x420 mpu_ecr\tmpu_ecr_t\n\t\t0x422 mpu_rdb0\tint\n\t\t0x423 mpu_rdp0\tint\n\t\t0x424 mpu_rdb1\tint\n\t\t0x425 mpu_rdp1\tint\n\t\t0x426 mpu_rdb2\tint\n\t\t0x427 mpu_rdp2\tint\n\t\t0x428 mpu_rdb3\tint\n\t\t0x429 mpu_rdp3\tint\n\t\t0x42A mpu_rdb4\tint\n\t\t0x42B mpu_rdp4\tint\n\t\t0x42C mpu_rdb5\tint\n\t\t0x42D mpu_rdp5\tint\n\t\t0x42E mpu_rdb6\tint\n\t\t0x42F mpu_rdp6\tint\n\t\t0x430 mpu_rdb7\tint\n\t\t0x431 mpu_rdp7\tint\n\t\t0x432 mpu_rdb8\tint\n\t\t0x433 mpu_rdp8\tint\n\t\t0x434 mpu_rdb9\tint\n\t\t0x435 mpu_rdp9\tint\n\t\t0x436 mpu_rdb10\tint\n\t\t0x437 mpu_rdp10\tint\n\t\t0x438 mpu_rdb11\tint\n\t\t0x439 mpu_rdp11\tint\n\t\t0x43A mpu_rdb12\tint\n\t\t0x43B mpu_rdp12\tint\n\t\t0x43C mpu_rdb13\tint\n\t\t0x43D mpu_rdp13\tint\n\t\t0x43E mpu_rdb14\tint\n\t\t0x43F mpu_rdp14\tint\n\t\t0x440 mpu_rdb15\tint\n\t\t0x441 mpu_rdp15\tint\n\t\t0x448 mpu_index\tmpu_index_t\n\t\t0x449 mpu_rstart uint32\n\t\t0x44A mpu_rend\tuint32\n\t\t0x44B mpu_rper\tmpu_rper_t\n\t\t0x44C mpu_probe uint32\n\t}\n\tforeach {num name type} $aux_other {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_other_feature\n\t}\n\n\t# AUX BCR\n\tset bcr {\n\t\t0x6D mpu_build\n\t\t0x74 dccm_build\n\t\t0x76 ap_build\n\t\t0x78 iccm_build\n\t\t0xC1 isa_config\n\t}\n\tforeach {num reg} $bcr {\n\t\tarc add-reg -name $reg -num $num -type ${reg}_t -bcr -feature $aux_other_feature\n\t}\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_v2_examine_target [target current]\"\n}\n\nproc arc_v2_reset { {target \"\"} } {\n\tarc_common_reset $target\n\n\t# Disable all actionpoints.  Cannot write via regcache yet, because it will\n\t# not be flushed and all changes to registers will get lost.  Therefore has\n\t# to write directly via JTAG layer...\n\tset num_ap [arc num-actionpoints]\n\tfor {set i 0} {$i < $num_ap} {incr i} {\n\t\tarc jtag set-aux-reg [expr {0x222 + $i * 3}] 0\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arm/arm7tdmi.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm7tdmi\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arm/arm920.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm920\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arm/arm946.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm946\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arm/arm966.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm966\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/cpu/arm/cortex_m3.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   cortex_m3\nset CPU_ARCH   armv7\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/fpga/altera-10m50.cfg",
    "content": "# see MAX 10 FPGA Device Architecture\n# Table 3-1: IDCODE Information for MAX 10 Devices\n# Intel MAX 10M02 0x31810dd\n# Intel MAX 10M04 0x318a0dd\n# Intel MAX 10M08 0x31820dd\n# Intel MAX 10M16 0x31830dd\n# Intel MAX 10M25 0x31840dd\n# Intel MAX 10M40 0x318d0dd\n# Intel MAX 10M50 0x31850dd\n# Intel MAX 10M02 0x31010dd\n# Intel MAX 10M04 0x310a0dd\n# Intel MAX 10M08 0x31020dd\n# Intel MAX 10M16 0x31030dd\n# Intel MAX 10M25 0x31040dd\n# Intel MAX 10M40 0x310d0dd\n# Intel MAX 10M50 0x31050dd\n\njtag newtap 10m50 tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \\\n\t-expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \\\n\t-expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \\\n\t-expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \\\n\t-expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/fpga/altera-ep3c10.cfg",
    "content": "# Altera Cyclone III EP3C10\n# see Cyclone III Device Handbook, Volume 1;\n# Table 14–5. 32-Bit Cyclone III Device IDCODE\njtag newtap ep3c10 tap -expected-id 0x020f10dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/fpga/lattice_ecp5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp5\n}\n\n# Lattice ECP5 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/ECP5\n#\n# 0x01111043 - LAE5UM_25F/LFE5UM_25F\n# 0x01112043 - LAE5UM_45F/LFE5UM_45F\n# 0x01113043 - LAE5UM_85F/LFE5UM_85\n# 0x21111043 - LFE5U_12F\n# 0x41111043 - LFE5U_25F\n# 0x41112043 - LFE5U_45F\n# 0x41113043 - LFE5U_85F\n# 0x81111043 - LFE5UM5G-25\n# 0x81112043 - LFE5UM5G-45\n# 0x81113043 - LFE5UM5G-85\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x01111043 -expected-id 0x01112043 -expected-id 0x01113043 \\\n\t-expected-id 0x21111043 -expected-id 0x41111043 -expected-id 0x41112043 \\\n\t-expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \\\n\t-expected-id 0x81113043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/fpga/xilinx-dna.cfg",
    "content": "proc xilinx_dna_addr {chip} {\n\tarray set addrs {\n\t\tSpartan6 0x30\n\t\tSeries7 0x17\n\t}\n\treturn $addrs($chip)\n}\n\n# Get the \"Device DNA\".\n# Most Xilinx FPGA devices contain an embedded, unique device identifier.\n# The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\n# This function returns the DNA as a 64 bit integer with the 7 LSBs zeroed.\n# This is compatible with the FUSE DNA which contains all 64 bits.\nproc xilinx_get_dna {tap chip} {\n\tset XC7_ISC_ENABLE 0x10\n\tset XC7_ISC_DISABLE 0x16\n\tset XC7_ISC_DNA [xilinx_dna_addr $chip]\n\n\tirscan $tap $XC7_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC7_ISC_DNA\n\tscan [drscan $tap 32 0 32 0] \"%08x %08x\" hi lo\n\truntest 64\n\tirscan $tap $XC7_ISC_DISABLE\n\truntest 64\n\t# openocd interprets DR scans as LSB first, bit-reverse it\n\treturn [scan [string reverse [format \"%032b%032bb0\" $lo $hi]] \"%i\"]\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xilinx_print_dna {dna} {\n\tset dna [expr {$dna >> 64 - 57}]\n\techo [format \"DNA = %057b (0x%016x)\" $dna $dna]\n}\n\nproc xc7_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Series7]\n}\n\nproc xc6s_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Spartan6]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/fpga/xilinx-xadc.cfg",
    "content": "# Xilinx XADC support for 7 Series FPGAs\n#\n# The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die\n# temperature, internal power supply rail voltages as well as external\n# voltages. The XADC is available both from fabric as well as through the\n# JTAG TAP.\n#\n# This code implements access through the JTAG TAP.\n#\n# https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf\n\n# build a 32 bit DRP command for the XADC DR\nproc xadc_cmd {cmd addr data} {\n\tarray set cmds {\n\t\tNOP 0x00\n\t\tREAD 0x01\n\t\tWRITE 0x02\n\t}\n\treturn [expr {($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)}]\n}\n\n# XADC register addresses\n# Some addresses (status registers 0-3) have special function when written to.\nproc XADC {key} {\n\tarray set addrs {\n\t\tTEMP 0x00\n\t\tLOCK 0x00\n\t\tVCCINT 0x01\n\t\tVCCAUX 0x02\n\t\tVAUXEN 0x02\n\t\tVPVN 0x03\n\t\tRESET 0x03\n\t\tVREFP 0x04\n\t\tVREFN 0x05\n\t\tVCCBRAM 0x06\n\t\tSUPAOFFS 0x08\n\t\tADCAOFFS 0x09\n\t\tADCAGAIN 0x0a\n\t\tVCCPINT 0x0d\n\t\tVCCPAUX 0x0e\n\t\tVCCODDR 0x0f\n\t\tVAUX0 0x10\n\t\tVAUX1 0x11\n\t\tVAUX2 0x12\n\t\tVAUX3 0x13\n\t\tVAUX4 0x14\n\t\tVAUX5 0x15\n\t\tVAUX6 0x16\n\t\tVAUX7 0x17\n\t\tVAUX8 0x18\n\t\tVAUX9 0x19\n\t\tVAUX10 0x1a\n\t\tVAUX11 0x1b\n\t\tVAUX12 0x1c\n\t\tVAUX13 0x1d\n\t\tVAUX14 0x1e\n\t\tVAUX15 0x1f\n\t\tSUPBOFFS 0x30\n\t\tADCBOFFS 0x31\n\t\tADCBGAIN 0x32\n\t\tFLAG 0x3f\n\t\tCFG0 0x40\n\t\tCFG1 0x41\n\t\tCFG2 0x42\n\t\tSEQ0 0x48\n\t\tSEQ1 0x49\n\t\tSEQ2 0x4a\n\t\tSEQ3 0x4b\n\t\tSEQ4 0x4c\n\t\tSEQ5 0x4d\n\t\tSEQ6 0x4e\n\t\tSEQ7 0x4f\n\t\tALARM0 0x50\n\t\tALARM1 0x51\n\t\tALARM2 0x52\n\t\tALARM3 0x53\n\t\tALARM4 0x54\n\t\tALARM5 0x55\n\t\tALARM6 0x56\n\t\tALARM7 0x57\n\t\tALARM8 0x58\n\t\tALARM9 0x59\n\t\tALARM10 0x5a\n\t\tALARM11 0x5b\n\t\tALARM12 0x5c\n\t\tALARM13 0x5d\n\t\tALARM14 0x5e\n\t\tALARM15 0x5f\n\t}\n\treturn $addrs($key)\n}\n\n# Select the XADC DR\nproc xadc_select {tap} {\n\tset XADC_IR 0x37\n\tirscan $tap $XADC_IR\n\truntest 10\n}\n\n# XADC transfer\nproc xadc_xfer {tap cmd addr data} {\n\tset ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]\n\truntest 10\n\treturn [expr \"0x$ret\"]\n}\n\n# XADC register write\nproc xadc_write {tap addr data} {\n\txadc_xfer $tap WRITE $addr $data\n}\n\n# XADC register read, non-pipelined\nproc xadc_read {tap addr} {\n\txadc_xfer $tap READ $addr 0\n\treturn [xadc_xfer $tap NOP 0 0]\n}\n\n# convert 16 bit register code from ADC measurement on\n# external voltages (VAUX) to Volt\nproc xadc_volt {code} {\n\treturn [expr {$code * 1./(1 << 16)}]\n}\n\n# convert 16 bit temperature measurement to Celsius\nproc xadc_temp {code} {\n\treturn [expr {$code * 503.975/(1 << 16) - 273.15}]\n}\n\n# convert 16 bit suppply voltage measurement to Volt\nproc xadc_sup {code} {\n\treturn [expr {$code * 3./(1 << 16)}]\n}\n\n# perform a single channel measurement using default settings\nproc xadc_single {tap ch} {\n\tset cfg0 [xadc_read $tap [XADC CFG0]]\n\tset cfg1 [xadc_read $tap [XADC CFG1]]\n\t# set channel\n\txadc_write $tap [XADC CFG0] $cfg0\n\t# single channel, disable the sequencer\n\txadc_write $tap [XADC CFG1] 0x3000\n\t# leave some time for the conversion\n\truntest 100\n\tset ret [xadc_read $tap [XADC $ch]]\n\t# restore CFG0/1\n\txadc_write $tap [XADC CFG0] $cfg0\n\txadc_write $tap [XADC CFG1] $cfg1\n\treturn $ret\n}\n\n# measure all internal voltages\nproc xadc_report {tap} {\n\txadc_select $tap\n\techo \"TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C\"\n\tforeach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \\\n\t\tVCCPINT VCCPAUX VCCODDR] {\n\t\techo \"$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/altera-usb-blaster.cfg",
    "content": "#\n# Altera USB-Blaster\n#\n# http://www.altera.com/literature/ug/ug_usb_blstr.pdf\n#\n\nadapter driver usb_blaster\nusb_blaster lowlevel_driver ftdi\n# These are already the defaults.\n# usb_blaster vid_pid 0x09FB 0x6001\n# usb_blaster device_desc \"USB-Blaster\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/altera-usb-blaster2.cfg",
    "content": "#\n# Altera USB-Blaster II\n#\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x09fb 0x6010 0x09fb 0x6810\nusb_blaster lowlevel_driver ublast2\nusb_blaster firmware /path/to/quartus/blaster_6810.hex\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/arm-jtag-ew.cfg",
    "content": "#\n# Olimex ARM-JTAG-EW\n#\n# http://www.olimex.com/dev/arm-jtag-ew.html\n#\n\nadapter driver arm-jtag-ew\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/at91rm9200.cfg",
    "content": "#\n# Various Atmel AT91RM9200 boards\n#\n# TODO: URL?\n#\n\nadapter driver at91rm9200\nat91rm9200_device rea_ecr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/beaglebone-jtag-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for JTAG\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio tdo_num 20\nam335xgpio tdi_num 60\nam335xgpio tms_num 4\nam335xgpio tck_num 2\n\nam335xgpio led_num 51\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/beaglebone-swd-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for SWD\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio swclk_num 2\nam335xgpio swdio_num 4\nam335xgpio swdio_dir_num 60\nam335xgpio swdio_dir_output_state on\n\n# USR0 LED\nam335xgpio led_num 53\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/buspirate.cfg",
    "content": "#\n# Buspirate with OpenOCD support\n#\n# http://dangerousprototypes.com/bus-pirate-manual/\n#\n\nadapter driver buspirate\n\n# you need to specify port on which BP lives\n#buspirate port /dev/ttyUSB0\n\n# communication speed setting\nbuspirate speed normal ;# or fast\n\n# voltage regulator Enabled = 1 Disabled = 0\n#buspirate vreg 0\n\n# pin mode normal or open-drain (jtag only)\n#buspirate mode normal\n\n# pullup state Enabled = 1 Disabled = 0\n#buspirate pullup 0\n\n# this depends on the cable, you are safe with this option\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/calao-usb-a9260.cfg",
    "content": "#\n# CALAO Systems USB-A9260 common -C01 -C02 setup\n#\n# http://www.calao-systems.com/\n#\n# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg.\n#\n\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/chameleon.cfg",
    "content": "#\n# Amontec Chameleon POD\n#\n# http://www.amontec.com/chameleon.shtml\n#\n\nadapter driver parport\nparport cable chameleon\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/cmsis-dap.cfg",
    "content": "#\n# ARM CMSIS-DAP compliant adapter\n#\n# http://www.keil.com/support/man/docs/dapdebug/\n#\n\nadapter driver cmsis-dap\n\n# Optionally specify the serial number of CMSIS-DAP usb device.\n# adapter serial 02200201E6661E601B98E3B9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/dln-2-gpiod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use DLN-2 GPIO through linuxgpiod\n#\n# +-----------+-------------+-------------+\n# | signal    | DLN-2       | gpio offset |\n# +-----------+-------------+-------------+\n# | nSRST     | J3.1  (PA0) | 0           |\n# | TDO       | J3.2  (PA1) | 1           |\n# | TCK/SWCLK | J3.3  (PA2) | 2           |\n# | TMS/SWDIO | J3.4  (PA3) | 3           |\n# | TDI       | J3.5  (PA4) | 4           |\n# | nTRST     | J3.6  (PA5) | 5           |\n# | LED       | J3.7  (PA6) | 6           |\n# | GND       | J3.12 (GND) |             |\n# +-----------+-------------+-------------+\n\nadapter driver linuxgpiod\n\nlinuxgpiod gpiochip 0\nlinuxgpiod jtag_nums 2 3 4 1\nlinuxgpiod trst_num 5\nlinuxgpiod swd_nums 2 3\nlinuxgpiod srst_num 0\nlinuxgpiod led_num 6\n\nreset_config trst_and_srst separate srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/dummy.cfg",
    "content": "#\n# Dummy interface (for testing purposes)\n#\n\nadapter driver dummy\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/estick.cfg",
    "content": "#\n# eStick\n#\n# http://code.google.com/p/estick-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/flashlink.cfg",
    "content": "#\n# ST FlashLINK JTAG parallel cable\n#\n# http://www.st.com/internet/evalboard/product/94023.jsp\n# http://www.st.com/stonline/products/literature/um/7889.pdf\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable flashlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ft232r/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to Radiona ULX3S board:\n# \tboard/radiona_ulx3s.cfg\n# See schematics for the ft232r layout:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nadapter driver ft232r\nadapter speed 1000\nft232r_vid_pid 0x0403 0x6015\nft232r_tck_num DSR\nft232r_tms_num DCD\nft232r_tdi_num RI\nft232r_tdo_num CTS\nft232r_trst_num RTS\nft232r_srst_num DTR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ft232r.cfg",
    "content": "adapter driver ft232r\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/100ask-openjtag.cfg",
    "content": "#\n# www.100ask.org OpenJTAG\n#\n# http://www.100ask.net/OpenJTAG.html\n#\n# Schematics are available from\n# https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"USB<=>JTAG&RS232\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0f08 0x0f1b\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/ashling-opella-ld-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi tdo_sample_edge falling\nftdi layout_init 0x0A68 0xFF7B\nftdi channel 0\nftdi layout_signal JTAGOE -ndata 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/ashling-opella-ld-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi layout_init 0x0860 0x0b7b\nftdi channel 0\nftdi layout_signal JTAGOE -data 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/axm0432.cfg",
    "content": "#\n# Axiom axm0432\n#\n# http://www.axman.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Symphony SoundBite\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/c232hm.cfg",
    "content": "# FTDI USB Hi-Speed to MPSSE Cable\n#\n# http://www.ftdichip.com/Products/Cables/USBMPSSE.htm\n#\n# C232HM-DDHSL-0 and C232HM-EDSL-0 provide 3.3V and 5V on pin 1 (Red),\n# respectively.\n#\n# Adapter: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_C232HM_MPSSE_CABLE.PDF\n# Chip: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf\n# See pinout/colors at end of this file.\n#\n# Tech notes:\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf\n\nadapter driver ftdi\n#ftdi device_desc \"C232HM-DDHSL-0\"\n#ftdi device_desc \"C232HM-EDHSL-0\"\n\n# Common PID for FT232H\nftdi vid_pid 0x0403 0x6014\n\n# Layout\n# High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low)\n# Low data byte 0x08 configures TMS on ACBUS3 initially high (asserted); TCK, TDI low\n# High direction byte 0x40 configures red LED on ACBUS6 as high (output)\n# Low direction byte 0x0b configures TDO on ACBUS2 as low (input)\nftdi layout_init 0x4008 0x400b\n\n# ---A*BUS-------CCCCCCCC|DDDDDDDD\n# --------\\______76543210|76543210\n# LED\t0x4000 = 01000000|00000000 = ACBUS6\n#GPIOL0\t0x0010 = 00000000|00010000 = ADBUS4\n#GPIOL1\t0x0020 = 00000000|00100000 = ADBUS5\n#GPIOL2\t0x0040 = 00000000|01000000 = ADBUS6\n#GPIOL3\t0x0080 = 00000000|10000000 = ADBUS7\n# -ndata treats the LED as active-low for expected behavior (toggle when transferring)\nftdi layout_signal LED -ndata 0x4000\n# Available for aliasing as desired\nftdi layout_signal GPIOL0 -data 0x0010 -oe 0x0010\nftdi layout_signal GPIOL1 -data 0x0020 -oe 0x0020\nftdi layout_signal GPIOL2 -data 0x0040 -oe 0x0040\nftdi layout_signal GPIOL3 -data 0x0080 -oe 0x0080\n\n# C232HM\t\tFT232H\tJTAG/Other\n# Num\tColor\tName\tFunc\n# 1\t\tRed\t\tVCC\t\tOptionally, can power the board if it is not using its own power supply.\n# 2\t\tOrange\tADBUS0\tTCK\n# 3\t\tYellow  ADBUS1\tTDI\n# 4\t\tGreen\tADBUS2\tTDO\n# 5\t\tBrown   ADBUS3\tTMS\n# 6\t\tGrey\tADBUS4\tGPIOL0\n# 7\t\tPurple\tADBUS5\tGPIOL1\n# 8\t\tWhite\tADBUS6\tGPIOL2\n# 9\t\tBlue\tADBUS7\tGPIOL3\n# 10\tBlack\tGND\t\tConnect to ground\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/calao-usb-a9260-c01.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C01\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/calao-usb-a9260-c02.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C02\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6001\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/cortino.cfg",
    "content": "#\n# Hitex Cortino\n#\n# http://www.hitex.com/index.php?id=cortino\n#\n\nadapter driver ftdi\nftdi device_desc \"Cortino\"\nftdi vid_pid 0x0640 0x0032\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/digilent-hs1.cfg",
    "content": "# this supports JTAG-HS1 and JTAG-SMT1\n# (the later being the OEM on-board version)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6010\n# channel 1 does not have any functionality\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/digilent-hs2.cfg",
    "content": "# this supports JTAG-HS2 (and apparently Nexys4 as well)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\n\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/digilent_jtag_hs3.cfg",
    "content": "#\n# Digilent JTAG-HS3\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"Digilent USB Device\"\n\n# From Digilent support:\n# The SRST pin is [...] 0x20 and 0x10 is the /OE (active low output enable)\n\nftdi layout_init 0x2088 0x308b\nftdi layout_signal nSRST -data 0x2000 -noe 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/digilent_jtag_smt2.cfg",
    "content": "#\n# Digilent JTAG-SMT2\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,1053&Prod=JTAG-SMT2\n#\n# Config is based on data from\n# http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x20e8 0x3feb\nftdi layout_signal nSRST -data 0x2000\nftdi layout_signal GPIO2 -data 0x2000\nftdi layout_signal GPIO1 -data 0x0200\nftdi layout_signal GPIO0 -data 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/digilent_jtag_smt2_nc.cfg",
    "content": "#\n# Digilent JTAG-SMT2-NC\n#\n# http://store.digilentinc.com/jtag-smt2-nc-surface-mount-programming-module/\n# https://reference.digilentinc.com/_media/jtag_smt2nc/jtag-smt2-nc_rm.pdf\n#\n# Based on reference sheet (above) and Xilinx KCU105 schematics\n# https://www.xilinx.com/products/boards-and-kits/kcu105.html#documentation\n#\n# Note that the digilent_jtag_smt2 layout does not work and hangs while\n# the ftdi device_desc from digilent_hs2 is wrong.\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/dlp-usb1232h.cfg",
    "content": "#\n# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module\n#\n# http://www.dlpdesign.com/usb/usb1232h.shtml\n#\n# Schematics for OpenOCD usage:\n# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/dp_busblaster.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the\n# JTAG header which allows it to emulate various debugger types. It comes\n# configured as a JTAGkey device.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\necho \"Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster\nand use dp_busblaster_kt-link.cfg instead\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/dp_busblaster_kt-link.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster (with KT-Link buffer)\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://github.com/bharrisau/busblaster and is SWD-enabled.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -ndata 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/esp32s2_kaluga_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Driver for the FT2232H JTAG chip on the Espressif Kaluga-1 ESP32-S2 board\n# (and most other FT2232H and FT232H based boards)\n#\n# JTAG DIP switch (labelled SW5 in the schematic) should be \"ON\" for lines\n# labelled TCK, TDO, TDI and TWS, to connect the FT2232H to the ESP32-S2.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010 0x0403 0x6014\n\n# interface 1 is the uart\nftdi channel 0\n\n# TCK, TDI, TDO, TMS: ADBUS0-3\n# TRST/SRST: ADBUS5 (unused for now)\n# LEDs: ACBUS3-4 (inverted)\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal LED -ndata 0x0800\nftdi layout_signal LED2 -ndata 0x1000\n\n# ESP32* series chips do not have a TRST input, and the SRST line is connected\n# to the EN pin.\n# The target code doesn't handle SRST reset properly yet, so this is\n# commented out:\n# ftdi layout_signal nSRST -oe 0x0020\n# reset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/flossjtag-noeeprom.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used\n# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you\n# have several Floss-JTAG connected you have to use the USB ID to select a\n# specific one.\n#\n# If you have a Floss-JTAG WITH EEPROM that is programmed, use the\n# flossjtag.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/flossjtag.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the\n# existence of an EEPROM on Floss-JTAG containing a name. If you have several\n# Floss-JTAG adapters connected you can use the serial number to select a\n# specific device.\n#\n# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the\n# flossjtag-noeeprom.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi device_desc \"FLOSS-JTAG\"\n# adapter serial \"FJ000001\"\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x0800\nftdi layout_signal LED2 -data 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/flyswatter.cfg",
    "content": "#\n# TinCanTools Flyswatter\n#\n# http://web.archive.org/web/20150419072034/http://www.tincantools.com/JTAG/Flyswatter.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0818 0x0cfb\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/flyswatter2.cfg",
    "content": "#\n# TinCanTools Flyswatter2\n#\n# https://www.tincantools.com/product/flyswatter2/\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter2\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0538 0x057b\nftdi layout_signal LED -ndata 0x0400\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020 -noe 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/ft232h-module-swd.cfg",
    "content": "#\n# ADAFRUIT FTDI FT232H as a SWD direct connect interface\n# Any FT232H based board may work\n#\n# http://www.ftdichip.com/Products/ICs/FT232H.htm\n#\n#\n\nadapter driver ftdi\n\nftdi vid_pid 0x0403 0x6014\n\n# data MSB..LSB       direction (1:out) MSB..LSB\n# 0000'0000'0011'0000 0000'0000'0011'1011\nftdi layout_init 0x0030 0x003b\n# 0xfff8 0xfffb\n# Those signal are only required on some platforms or may required to be\n# enabled explicitly (e.g. nrf5x chips).\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\n\n# swd enable\nftdi layout_signal SWD_EN -data 0\n# tri-state (configure as input) TDO/TIO when reading\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n\n# re-configure TDO as tri-state\n#ftdi layout_signal TDO -data 0x0002 -oe 0x0002\n#ftdi layout_signal TDI -data 0x0004\n\n# Adafruit      FT232H    JTAG       SWD\n# Name  Pin     Name      Func       Func\n#  D0   J1-3    ADBUS0    TCK        SWDCLK\n#  D1   J1-4    ADBUS1    TDO/DI     SWDIO\n#  D2   J1-5    ADBUS2    TDI/DO     SWDIO\n#  D3   J1-6    ADBUS3    TMS        N/A\n#  D4   J1-7    ADBUS4    (GPIOL0)   /nSRST  optional module reset\n#  D5   J1-8    ADBUS5    (GPIOL1)   /nTRST  optional target reset\n#  D6   J1-9    ADBUS6    (GPIOL2)\n#  D7   J1-10   ADBUS7    (GPIOL3)\n#  C0   J2-1    ACBUS0    (GPIOH0)\n#  C1   J2-2    ACBUS1    (GPIOH1)\n#  C2   J2-3    ACBUS2    (GPIOH2)\n#  C3   J2-4    ACBUS3    (GPIOH3)\n#  C4   J2-5    ACBUS4    (GPIOH4)\n#  C5   J2-6    ACBUS5    (GPIOH5)\n#  C6   J2-7    ACBUS6    (GPIOH6)\n#  C7   J2-8    ACBUS7    (GPIOH7)\n#  C8   J2-9    ACBUS8\n#  C9   J2-10   ACBUS9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/gw16042.cfg",
    "content": "#\n# Gateworks GW16042 JTAG Dongle\n#\n# http://www.gateworks.com/\n#\n# Layout:  FTDI FT2232H\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO (input)\n#   ADBUS3 TMS\n#   ADBUS4 nTRST\n#   ADBUS5 nSRST\n#   ADBUS6 OE (active high) for TRST, TDI, TMS, TCK\n#   ADBUS7 NC\n#   ACBUS0-7 NC\n#   BDBUS0 RXD\n#   BDBUS1 TXD (input)\n#\n\nadapter driver ftdi\nftdi device_desc \"USB-JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0058 0x007b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hie-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Hofstädtler Industrie-Electronic (HIE) JTAG Debugger\n#\n# https://www.hofstaedtler.com/jtag\n#\n\nadapter driver ftdi\nftdi channel 0\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"HIE JTAG Debugger\"\n\nftdi layout_init 0x0c08 0x4f1b\n\n# define both Reset signals\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\n# Toggle USB LED\nftdi layout_signal LED -ndata 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hilscher_nxhx10_etm.cfg",
    "content": "#\n# Hilscher NXHX 10-ETM\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 10-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hilscher_nxhx500_etm.cfg",
    "content": "#\n# Hilscher NXHX 500-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hilscher_nxhx500_re.cfg",
    "content": "#\n# Hilscher NXHX 500-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hilscher_nxhx50_etm.cfg",
    "content": "#\n# Hilscher NXHX 50-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 50-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hilscher_nxhx50_re.cfg",
    "content": "#\n# Hilscher NXHX 50-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX50-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hitex_lpc1768stick.cfg",
    "content": "#\n# Hitex LPC1768-Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\n\nadapter driver ftdi\nftdi device_desc \"LPC1768-Stick\"\nftdi vid_pid 0x0640 0x0026\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/hitex_str9-comstick.cfg",
    "content": "#\n# Hitex STR9-comStick\n#\n# http://www.hitex.com/index.php?id=383\n#\n\nadapter driver ftdi\nftdi device_desc \"STR9-comStick\"\nftdi vid_pid 0x0640 0x002c\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/icebear.cfg",
    "content": "#\n# Section5 ICEBear\n#\n# http://section5.ch/icebear\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"ICEbear JTAG adapter\"\nftdi vid_pid 0x0403 0xc140\n\nftdi layout_init 0x0028 0x002b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/imx8mp-evk.cfg",
    "content": "#\n# Configuration file for NXP MC-IMX8MP-EVK on-board internal JTAG\n#\n# Using this interface requires enabling \"remote mode\" for the board using the\n# NXP bcu tool (see https://github.com/NXPmicro/bcu)\n#\n#\tbcu set_gpio remote_en 1 -board=imx8mpevk\n#\n# The REMOTE_EN gpio is accessible through the same FTDI adapter but it's\n# behind an I2C GPIO expander.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n\nftdi layout_init 0x00f8 0x000b\n\nftdi layout_signal RESET_B\t-data 0x0010 -oe 0x0010\n# Called SYS_nRST in schematics\nftdi layout_signal nSRST\t-data 0x0020 -oe 0x0020\nftdi layout_signal IO_nRST\t-data 0x0040 -oe 0x0040\nftdi layout_signal ONOFF_B\t-data 0x0080 -oe 0x0080\n\nftdi layout_signal GPIO1\t-data 0x0100 -oe 0x0100\nftdi layout_signal GPIO2\t-data 0x0200 -oe 0x0200\nftdi layout_signal GPIO3\t-data 0x0400 -oe 0x0400\nftdi layout_signal GPIO4\t-data 0x0800 -oe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/incircuit-icprog.cfg",
    "content": "#\n# In-Circuit's ICprog OpenOCD JTAG Adapter\n# https://shop.in-circuit.de/product_info.php?products_id=112\n#\n# Schematics available at\n# http://wiki.in-circuit.de/images/0/06/610000158A_openocd.pdf\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nSRST -noe 0x0400 -data 0x0800\nftdi layout_signal nTRST -noe 0x0100 -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/iotlab-usb.cfg",
    "content": "#\n# This is the integrated adapter as found on the IoT-LAB boards\n# https://github.com/iot-lab/iot-lab/wiki\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/isodebug.cfg",
    "content": "# isodebug v1\n# 5 kV isolated JTAG/SWD + UART adapter by Unjo AB\n\nadapter driver ftdi\nftdi vid_pid 0x22b7 0x150d\n\nftdi layout_init 0x0ff8 0xfffb\n\nftdi layout_signal LED -ndata 0x0100\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\nftdi layout_signal SWDIO_OE -data 0x0008\n\n# Mode signals, either of these needs to be high to drive the JTAG/SWD pins.\n# The power-on state is low for both signals but the init setting above sets\n# JTAG_EN high.\nftdi layout_signal SWD_EN -data 0x1000\nftdi layout_signal JTAG_EN -data 0x0800\n\n# In SWD mode, the JTAG_EN signal doubles as SWO_EN_N which switches the\n# second FTDI channel UART RxD to the SWO pin instead of the separate RxD\n# pin. Note that the default init state has this pin high so when OpenOCD\n# starts in SWD mode, SWO is by default disabled. To enable SWO tracing,\n# issue the command 'ftdi set_signal SWO_EN 1' where tracing is configured.\n# To switch back to using the separate UART, SWO_EN needs to be disabled\n# before exiting OpenOCD, or the adapter replugged.\nftdi layout_signal SWO_EN -nalias JTAG_EN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/jtag-lock-pick_tiny_2.cfg",
    "content": "#\n# DISTORTEC JTAG-lock-pick Tiny 2\n#\n# http://www.distortec.com\n#\n\nadapter driver ftdi\nftdi device_desc \"JTAG-lock-pick Tiny 2\"\nftdi vid_pid 0x0403 0x8220\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal SWDIO_OE -ndata 0x1000\nftdi layout_signal LED -ndata 0x8000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/jtagkey.cfg",
    "content": "#\n# Amontec JTAGkey\n#\n# http://www.amontec.com/jtagkey.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/jtagkey2.cfg",
    "content": "#\n# Amontec JTAGkey2\n#\n# http://www.amontec.com/jtagkey2.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/jtagkey2p.cfg",
    "content": "#\n# Amontec JTAGkey2P\n#\n# http://www.amontec.com/jtagkey2p.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2P\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/kt-link.cfg",
    "content": "#\n# Kristech KT-Link\n#\n# http://www.kristech.eu\n#\n\nadapter driver ftdi\nftdi device_desc \"KT-LINK\"\nftdi vid_pid 0x0403 0xbbe2\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -data 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to LambdaConcept ECPIX-5 board:\n# \tinterface/ftdi/lambdaconcept_ecpix-5.cfg\n# See schematics for the ftdi layout:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n\nadapter driver ftdi\nadapter speed 10000\nftdi_device_desc \"Dual RS232-HS\"\nftdi_vid_pid 0x0403 0x6010\n\nftdi_layout_init 0xfff8 0xfffb\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/lisa-l.cfg",
    "content": "#\n# Lisa/L\n#\n# http://paparazzi.enac.fr/wiki/Lisa\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Lisa/L\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x1800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/luminary-icdi.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S9B9x Evaluation Kits\n# In-Circuit Debug Interface (ICDI) Board\n#\n# Essentially all Luminary debug hardware is the same, (with both\n# JTAG and SWD support compatible with ICDI boards.  This ICDI adapter\n# configuration is JTAG-only, but the same hardware handles SWD too.\n#\n# This is a discrete ftdi based debug board which supports ARM's\n# JTAG/SWD connectors in both backwards-compatible 20-pin format and\n# in the new-style compact 10-pin.  There's also an 8-pin connector\n# with serial port support.  It's included with LM3S9B9x eval boards.\n#\n# http://www.luminarymicro.com/products/ek-lm3s9b90.html\n# http://www.luminarymicro.com/products/ek-lm3s9b92.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Luminary Micro ICDI Board\"\nftdi vid_pid 0x0403 0xbcda\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/luminary-lm3s811.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S811 Evaluation Kit\n#\n# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html\n#\n# NOTE:  this is only for boards *before* Rev C, which adds support\n# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals.\n# The \"evb_lm3s811\" layout doesn't set up those signals.\n#\n# Rev C boards work more like the other Stellaris eval boards.  They\n# need to use the \"luminary_icdi\" layout to work correctly.\n#\n\nadapter driver ftdi\nftdi device_desc \"LM3S811 Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x0088 0x008b\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/luminary.cfg",
    "content": "#\n# Luminary Micro Stellaris Evaluation Kits\n#\n# http://www.luminarymicro.com/products/evaluation_kits.html\n#\n# There are a number of evaluation kits for Stellaris Cortex-M3 chips.\n# Currently they all bundle ftdi based debug support.  When that is\n# used (instead of an external adapter), use this config file in one\n# of these two modes:\n#\n# - Eval board debug ... debug of the Stellaris chip via port A.\n#\n# - Other board debug ... same thing, but the board acts as a debug\n#   adapter for another board (using a standard ARM JTAG connector).\n#   The Stellaris chip stays in reset.\n#\n# Those support both JTAG and SWD.  SWD is an ARM-only two-wire debug\n# protocol; in 2009, OpenOCD does not support SWD.\n#\n# Port B of the ftdi chip is normally used as a serial link to the\n# Stellaris chip.  On most boards (but not older LM3S811 eval boards),\n# when SWD is used Port B may instead be used to read low-bandwidth\n# \"SWO trace\" data, including so-called \"printf style\" output from\n# firmware via the ITM module as well as profile data.\n#\n\nadapter driver ftdi\nftdi device_desc \"Stellaris Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/m53evk.cfg",
    "content": "#\n# DENX M53EVK\n#\n# http://www.denx-cs.de/?q=M53EVK\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/mbftdi.cfg",
    "content": "#\n# MBFTDI\n#\n# http://www.marsohod.org/prodmbftdi\n#\n# Also the Marsohod2 and the Marsohod3 boards\n# include a built-in MBFTDI for FPGA programming.\n# See http://www.marsohod.org/prodmarsohod2\n# and http://www.marsohod.org/plata-marsokhod3 for details.\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/minimodule-swd.cfg",
    "content": "#\n# Supports SWD using the FT2232H or FT4232H minimodule.\n# Each can support 2 SWD interfaces.\n#\n# FT2232H or FT4232H minimodule channel 0 (Channel A)\n# Connector  FTDI              Target\n# Pin        Name\n# ---------  ------            ------\n# CN2-11     VIO               VDD_IO (Or connect to CN2-5 on the minimodule instead for a 3V3 interface)\n# CN2-2      GND               GND\n# CN2-7      ADBUS0 (TCK)      SWCLK\n# CN2-9      ADBUS2 (TDI/TDO)  SWDIO\n# CN2-10     ADBUS1 (TDO/TDI)  SWDIO\n# CN2-14     ADBUS4 (GPIOL0)   nRESET\n#\n# FT2232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN3-26  -  SWCLK\n# CN3-25  -  SWDIO\n# CN3-24  -  SWDIO\n# CN3-21  -  nRESET\n#\n# FT4232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN2-18  -  SWCLK\n# CN2-17  -  SWDIO\n# CN2-20  -  SWDIO\n# CN2-22  -  nRESET\n#\n\nadapter driver ftdi\n\n#Select your module type and channel\n\n#ftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n#ftdi channel 1\n\n#ftdi device_desc \"FT4232H MiniModule\"\n#ftdi vid_pid 0x0403 0x6011\n#ftdi channel 1\n\nftdi layout_init 0x0000 0x000b\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal SWD_EN -data 0\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/minimodule.cfg",
    "content": "#\n# FTDI MiniModule\n#\n# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n\n# Every pin set as high impedance except TCK, TDI, TDO and TMS\nftdi layout_init 0x0008 0x000b\n\n# nSRST defined on pin CN2-13 of the MiniModule (pin ADBUS5 [AD5] on the FT2232H chip)\n# This choice is arbitrary. Use other GPIO pin if desired.\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n# https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf\nadapter driver ftdi\n# The miniSpartan6+ sadly doesn't have a custom device description, so we just\n# have to hope you got it right.\n#ftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 30000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/miniwiggler.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Infineon DAP miniWiggler V3\n#\n# https://www.infineon.com/cms/en/product/evaluation-boards/kit_miniwiggler_3_usb/\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 nOE (output enable)\n#   ADBUS5\n#   ADBUS6\n#   ADBUS7 Blue LED\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5\n#   ACBUS6\n#   ACBUS7\n#\n\nadapter driver ftdi\nftdi device_desc \"DAS JDS miniWiggler V3.1\"\nftdi vid_pid 0x058b 0x0043\n\nftdi channel 0\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/neodb.cfg",
    "content": "#\n# Openmoko USB JTAG/RS232 adapter\n#\n# http://wiki.openmoko.org/wiki/Debug_Board_v3\n#\n\nadapter driver ftdi\nftdi device_desc \"Debug Board for Neo1973\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\nftdi layout_signal nNOR_WP -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/ngxtech.cfg",
    "content": "#\n# NGX ARM USB JTAG\n#\n# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NGX JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/olimex-arm-jtag-swd.cfg",
    "content": "#\n# Olimex ARM JTAG SWD adapter\n# https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-SWD/\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg",
    "content": "#\n# Olimex ARM-USB-OCD-H\n#\n# http://www.olimex.com/dev/arm-usb-ocd-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-OCD-H\"\nftdi vid_pid 0x15ba 0x002b\n\nftdi layout_init 0x0908 0x0b1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/olimex-arm-usb-ocd.cfg",
    "content": "#\n# Olimex ARM-USB-OCD\n#\n# http://www.olimex.com/dev/arm-usb-ocd.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG\"\nftdi vid_pid 0x15ba 0x0003\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg",
    "content": "#\n# Olimex ARM-USB-TINY-H\n#\n# http://www.olimex.com/dev/arm-usb-tiny-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-TINY-H\"\nftdi vid_pid 0x15ba 0x002a\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/olimex-jtag-tiny.cfg",
    "content": "#\n# Olimex ARM-USB-TINY\n#\n# http://www.olimex.com/dev/arm-usb-tiny.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG TINY\"\nftdi vid_pid 0x15ba 0x0004\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/oocdlink.cfg",
    "content": "#\n# Joern Kaipf's OOCDLink\n#\n# http://www.joernonline.de/contrexx2/cms/index.php?page=126\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"OOCDLink\"\nftdi vid_pid 0x0403 0xbaf8\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/opendous_ftdi.cfg",
    "content": "#\n# Opendous\n#\n# http://code.google.com/p/opendous/wiki/JTAG\n#\n# According to the website, it is similar to jtagkey, but it uses channel B\n# (and it has a different pid number).\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/openocd-usb-hs.cfg",
    "content": "#\n# embedded projects openocd usb adapter v3\n#\n# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/openocd-usb.cfg",
    "content": "#\n# Hubert Hoegl's USB to JTAG\n#\n# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/openrd.cfg",
    "content": "#\n# Marvell OpenRD\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"OpenRD JTAGKey FT2232D B\"\nftdi vid_pid 0x0403 0x9e90\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n# http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf\nadapter driver ftdi\nftdi device_desc \"Pipistrello LX45\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/pls_spc5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# PLS SPC5-UDESTK\n#\n# https://www.st.com/en/development-tools/spc5-udestk.html\n#\n# Reference the SPC56D Discovery schematics.\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 TMS\n#   ADBUS5 RTCK\n#   ADBUS6\n#   ADBUS7 LED1\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST (external pull-down)\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5 nSRST direction (input=L, output=H, external pull-down)\n#   ACBUS6 TMS direction (input=L, output=H, external pull-up)\n#   ACBUS7 LED2\n#\n\nadapter driver ftdi\nftdi device_desc \"PLS USB/JTAG Adapter for SPC5xxx\"\nftdi vid_pid 0x263d 0x4001\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -ndata 0x2000 -oe 0x2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/redbee-econotag.cfg",
    "content": "#\n# Redwire Redbee-Econotag\n#\n# http://www.redwirellc.com/store/node/1\n#\n# The Redbee-Econotag has an onboard FT2232H with:\n#  - FT2232H channel A wired to mc13224v JTAG\n#  - FT2232H channel B wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/redbee-usb.cfg",
    "content": "#\n# Redwire Redbee-USB\n#\n# http://www.redwirellc.com\n#\n# The Redbee-USB has an onboard FT2232H with:\n#  - FT2232H channel B wired to mc13224v JTAG\n#  - FT2232H channel A wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/rowley-cc-arm-swd.cfg",
    "content": "#\n# Rowley ARM SWD Adapter\n# http://sites.fastspring.com/rowley/product/armswdadapter\n# https://drive.google.com/file/d/0Bzv7UpKpOQhnTUNNdzI5OUR4WGs/edit?usp=sharing\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/sheevaplug.cfg",
    "content": "#\n# Marvel SheevaPlug Development Kit\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"SheevaPlug JTAGKey FT2232D B\"\nftdi vid_pid 0x9e88 0x9e8f\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/signalyzer-lite.cfg",
    "content": "#\n# Xverve Signalyzer LITE (DT-USB-SLITE)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer LITE\"\nftdi vid_pid 0x0403 0xbca1\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/signalyzer.cfg",
    "content": "#\n# Xverve Signalyzer Tool (DT-USB-ST)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer\"\nftdi vid_pid 0x0403 0xbca0\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/snps_sdp.cfg",
    "content": "#  Copyright (C) 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys SDP Mainboard has embdded FT2232 chip, which is similar to Digilent\n# HS-1, except that it uses channel B for JTAG communication, instead of\n# channel A.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi layout_init 0x0088 0x008b\nftdi channel 1\n\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/steppenprobe.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Steppenprobe\n# https://github.com/diegoherranz/steppenprobe\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\n# Initial Layout\nftdi layout_init 0x0058 0x99fb\n# Signal        Data    Direction       Notes\n# TCK           0       1 (out)\n# TDI           0       1 (out)\n# TDO           0       0 (in)\n# TMS           1       1 (out)         JTAG IEEE std recommendation\n# LED           1       1 (out)         LED off\n# SWD_EN        0       1 (out)         OpenOCD sets this high for SWD\n# SWDIO_OE      1       1 (out)         Ext. buffer tristated\n# SRST          0       1 (out)         Translates to nSRST=Z\n\n# Unused        0       1 (out)\n# GPIO_A        0       0 (in)\n# GPIO_B        0       0 (in)\n# Unused        0       1 (out)\n# Unused        0       1 (out)\n# GPIO_C        0       0 (in)\n# GPIO_D        0       0 (in)\n# Unused        0       1 (out)\n\n# Signals definition\nftdi layout_signal LED -ndata 0x0010\nftdi layout_signal SWD_EN -data 0x0020\nftdi layout_signal SWDIO_OE -ndata 0x0040\nftdi layout_signal nSRST -oe 0x0080\n\nftdi layout_signal GPIO_A -data 0x0200 -oe 0x0200 -input 0x0200\nftdi layout_signal GPIO_B -data 0x0400 -oe 0x0400 -input 0x0400\nftdi layout_signal GPIO_C -data 0x2000 -oe 0x2000 -input 0x2000\nftdi layout_signal GPIO_D -data 0x4000 -oe 0x4000 -input 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/stm32-stick.cfg",
    "content": "#\n# Hitex STM32-PerformanceStick\n#\n# http://www.hitex.com/index.php?id=340\n#\n\nadapter driver ftdi\nftdi device_desc \"STM32-PerformanceStick\"\nftdi vid_pid 0x0640 0x002d\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/swd-resistor-hack.cfg",
    "content": "#\n# Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or\n# so depending on the drive capability of the target and adapter);\n# connect TDO directly to SWDIO.\n#\n# You also need to have reliable GND connection between the target and\n# adapter. Vref of the adapter should be supplied with a voltage equal\n# to the target's (preferably connect it to Vcc). You can also\n# optionally connect nSRST. Leave everything else unconnected.\n#\n# FTDI                          Target\n# ----                          ------\n# 1  - Vref   ----------------- Vcc\n# 3  - nTRST  -\n# 4  - GND    ----------------- GND\n# 5  - TDI    ---/\\470 Ohm/\\--- SWDIO\n# 7  - TMS    -\n# 9  - TCK    ----------------- SWCLK\n# 11 - RTCK   -\n# 13 - TDO    ----------------- SWDIO\n# 15 - nSRST  - - - - - - - - - nRESET\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -data 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/ti-icdi.cfg",
    "content": "#\n# This is an FTDI-based debugging solution as found on some TI boards,\n# e.g. CC3200 LaunchPad.\n#\n# The schematics are identical to luminary-icdi (including SWD\n# support) but the USB IDs are different.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0451 0xc32a\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/tigard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Tigard: An FTDI FT2232H-based multi-protocol tool for hardware hacking.\n# https://github.com/tigard-tools/tigard\n\nadapter driver ftdi\n\nftdi device_desc \"Tigard V1.1\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 1\n\nftdi layout_init 0x0038 0x003b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020\n\n# This board doesn't support open-drain reset modes since its output buffer is\n# always enabled.\nreset_config srst_push_pull trst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/tumpa-lite.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA) Lite\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a99\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/tumpa.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA)\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a98 0x0403 0x6010\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0010\n\nreset_config srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/turtelizer2-revB.cfg",
    "content": "#\n# egnite Turtelizer 2 rev B (with SRST only)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c5b\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/turtelizer2-revC.cfg",
    "content": "#\n# egnite Turtelizer 2 revC (with TRST and SRST)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c7b\nftdi layout_signal nTRST -oe 0x0020\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -ndata 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/um232h.cfg",
    "content": "#\n# FTDI UM232H as a JTAG interface\n#\n# http://www.ftdichip.com/Products/Modules/DevelopmentModules.htm#UM232H\n#\n# This should also work with a UM232H-B, but that has not been tested.\n# Note that UM232H and UM232H-B are 3.3V only.\n#\n\nadapter driver ftdi\n#ftdi device_desc \"UM232H\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0xfff8 0xfffb\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n\n# UM232H        FT232H    JTAG\n# Name  Pin     Name      Func\n# AD0   J2-6    ADBUS0    TCK\n# AD1   J2-7    ADBUS1    TDI\n# AD2   J2-8    ADBUS2    TDO\n# AD3   J2-9    ADBUS3    TMS\n# AD4   J2-10   ADBUS4    (GPIOL0)\n# AD5   J2-11   ADBUS5    (GPIOL1)\n# AD6   J2-12   ADBUS6    (GPIOL2)\n# AD7   J2-13   ADBUS7    (GPIOL3)\n# AD0   J1-14   ACBUS0    /TRST\n# AD1   J1-13   ACBUS1    /SRST\n# AD2   J1-12   ACBUS2    (GPIOH2)\n# AD3   J1-11   ACBUS3    (GPIOH3)\n# AD4   J1-10   ACBUS4    (GPIOH4)\n# AD5   J1-9    ACBUS5    (GPIOH5)\n# AD6   J1-8    ACBUS6    (GPIOH6)\n# AD7   J1-7    ACBUS7    (GPIOH7)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/vpaclink.cfg",
    "content": "#\n# Voipac VPACLink\n#\n# http://voipac.com/27M-JTG-000\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"VPACLink\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/xds100v2.cfg",
    "content": "#\n# Texas Instruments XDS100v2\n#\n# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features\n#\n# Detailed documentation is available only as CPLD verilog source code\n# to the registered TI users.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0xa6d0 0x0403 0x6010\n\nftdi layout_init 0x0038 0x597b\n\n#  8000 z - unused\n#  4000 0 > CPLD loopback          (all target side pins high-Z)\n#  2000 z < !( cable connected )   (open drain on CPLD side for $reasons)\n#  1000 0 > EMU1_oe\n#\n#   800 0 > PWR_RST = clear power-loss flag on rising edge\n#   400 z < !( power-loss flag )\n#   200 z < nSRST\n#   100 0 > nSRST_oe\n#\n#    80 z < RTCK\n#    40 0 > EMU0_oe\n#    20 1 > EMU_EN\n#    10 1 > nTRST\n#\n#     8 1 > TMS\n#     4 z < TDO\n#     2 0 > TDI\n#     1 0 > TCK\n#\n# As long as the power-loss flag is set, all target-side pins are\n# high-Z except the EMU-pins for which the opposite holds unless\n# EMU_EN is high.\n#\n# To use wait-in-reset, drive EMU0 low at power-on reset. If the\n# target normally reuses EMU0 for other purposes, clear EMU_EN to\n# keep the EMU pins high-Z until the target is power-cycled.\n#\n# The LED only turns off at USB suspend, which is also the only way to\n# set the power-loss flag manually. (Can be done in software e.g. by\n# changing the USB configuration to zero.)\n#\n\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0100\nftdi layout_signal EMU_EN -data 0x0020\nftdi layout_signal EMU0 -oe 0x0040\nftdi layout_signal EMU1 -oe 0x1000\nftdi layout_signal PWR_RST -data 0x0800\nftdi layout_signal LOOPBACK -data 0x4000\n\necho \"\\nInfo : to use this adapter you MUST add ``init; ftdi set_signal PWR_RST 1; jtag arp_init'' to the end of your config file!\\n\"\n# note: rising edge on PWR_RST is also needed after power-cycling the\n# target\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ftdi/xds100v3.cfg",
    "content": "#\n# Texas Instruments XDS100 ver 3.0\n#\n# http://processors.wiki.ti.com/index.php/XDS100\n#\n\n# Version 3.0 is the same as 2.0 as far as OpenOCD is concerned\nsource [find interface/ftdi/xds100v2.cfg]\n\n# The USB ids are different.\nftdi vid_pid 0x0403 0xa6d1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/imx-native.cfg",
    "content": "#\n# Config for using NXP IMX CPU\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches to host voltage and the cable is short enough.\n#\n#\n\nadapter driver imx_gpio\n\n# For most IMX processors 0x0209c000\nimx_gpio_peripheral_base 0x0209c000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for IMX6UL@528MHz\n# imx_gpio_speed SPEED_COEFF SPEED_OFFSET\nimx_gpio_speed_coeffs 50000 50\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo.\n# Example configuration:\n# imx_gpio_jtag_nums 6 7 8 9\n\n# SWD interface pins: swclk swdio\n# Example configuration:\nimx_gpio_swd_nums 1 6\n\n# imx_gpio_trst_num 10\n# reset_config trst_only\n\n# imx_gpio_srst_num 11\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/jlink.cfg",
    "content": "#\n# SEGGER J-Link\n#\n# http://www.segger.com/jlink.html\n#\n\nadapter driver jlink\n\n# The serial number can be used to select a specific device in case more than\n# one is connected to the host.\n#\n# Example: Select J-Link with serial number 123456789\n#\n# adapter serial 123456789\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/jtag_dpi.cfg",
    "content": "#\n# Provide support for the Cadence JTAG BFM\n#\n# Copyright (c) 2020, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\nadapter driver jtag_dpi\n\n# Set the DPI JTAG server port\nif { [info exists DPI_PORT] } {\n   set _DPI_PORT $DPI_PORT\n} else {\n   set _DPI_PORT 5555\n}\n\n# Set the DPI JTAG server address\nif { [info exists DPI_ADDRESS] } {\n   set _DPI_ADDRESS $DPI_ADDRESS\n} else {\n   set _DPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_dpi set_port $_DPI_PORT\njtag_dpi set_address $_DPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/jtag_hat_rpi2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Blinkinlabs JTAG_Hat\n#\n# https://github.com/blinkinlabs/jtag_hat\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio_peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio_speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio_jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio_swd_nums 11 25\n\n# Direction pin for SWDIO level shifting buffer\nbcm2835gpio_swdio_dir_num 6\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\nbcm2835gpio_trst_num 7\n#reset_config trst_only\n\nbcm2835gpio_srst_num 24\n#reset_config srst_only\n\n# or if you have both connected\n#reset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/jtag_vpi.cfg",
    "content": "adapter driver jtag_vpi\n\n# Set the VPI JTAG server port\nif { [info exists VPI_PORT] } {\n   set _VPI_PORT $VPI_PORT\n} else {\n   set _VPI_PORT 5555\n}\n\n# Set the VPI JTAG server address\nif { [info exists VPI_ADDRESS] } {\n   set _VPI_ADDRESS $VPI_ADDRESS\n} else {\n   set _VPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_vpi set_port $_VPI_PORT\njtag_vpi set_address $_VPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/kitprog.cfg",
    "content": "#\n# Cypress Semiconductor KitProg\n#\n# Note: This is the driver for the proprietary KitPtog protocol. If the\n# KitProg is in CMSIS-DAP mode, you should either use the cmsis-dap\n# interface driver or switch the KitProg to KitProg mode.\n#\n\nadapter driver kitprog\n\n# Optionally specify the serial number of the KitProg you want to use.\n# adapter serial 1926402735485200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/nds32-aice.cfg",
    "content": "#\n# Andes AICE\n#\n# http://www.andestech.com\n#\n\nadapter driver aice\naice desc \"Andes AICE adapter\"\n# adapter serial \"C001-42163\"\naice vid_pid 0x1CFC 0x0000\naice port aice_usb\nreset_config trst_and_srst\nadapter speed 24000\naice retry_times 50\naice count_to_check_dbger 30\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/nulink.cfg",
    "content": "#\n# Nuvoton Nu-Link in-circuit debugger/programmer\n#\n\nadapter driver hla\nhla_layout nulink\nhla_device_desc \"Nu-Link\"\nhla_vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201\n\n# Only swd is supported\ntransport select hla_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/opendous.cfg",
    "content": "#\n# opendous-jtag\n#\n# http://code.google.com/p/opendous-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/openjtag.cfg",
    "content": "#\n# OpenJTAG\n#\n# www.openjtag.org\n#\n\nadapter driver openjtag\nopenjtag device_desc \"Open JTAG Project\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/osbdm.cfg",
    "content": "#\n# P&E Micro OSBDM (aka OSJTAG) interface\n#\n# http://pemicro.com/osbdm/\n#\nadapter driver osbdm\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/parport.cfg",
    "content": "#\n# Parallel port wiggler (many clones available) on port 0x378\n#\n# Addresses: 0x378/LPT1 or 0x278/LPT2 ...\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   if {$tcl_platform(platform) eq \"windows\"} {\n      set _PARPORTADDR 0x378\n   } {\n      set _PARPORTADDR 0\n   }\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable wiggler\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/parport_dlc5.cfg",
    "content": "#\n# Xilinx Parallel Cable III 'DLC 5' (and various clones)\n#\n# http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable dlc5\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/raspberrypi-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x20000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 113714 28\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/raspberrypi2-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/rlink.cfg",
    "content": "#\n# Raisonance RLink\n#\n# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html\n#\n\nadapter driver rlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/rshim.cfg",
    "content": "#\n# BlueField SoC in-circuit debugger/programmer\n#\n\nadapter driver rshim\ntransport select dapdirect_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/stlink-dap.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n# This new interface driver creates a ST-Link wrapper for ARM-DAP named \"dapdirect\"\n# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support \"dapdirect\"\n#\n# SWIM transport is natively supported\n#\n\nadapter driver st-link\nst-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# transport select dapdirect_jtag\n# transport select dapdirect_swd\n# transport select swim\n\n# Optionally specify the serial number of usb device\n# e.g.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/stlink-v1.cfg",
    "content": "echo \"WARNING: interface/stlink-v1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/stlink-v2-1.cfg",
    "content": "echo \"WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/stlink-v2.cfg",
    "content": "echo \"WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/stlink.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n\nadapter driver hla\nhla_layout stlink\nhla_device_desc \"ST-LINK\"\nhla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# Optionally specify the serial number of ST-LINK/V2 usb device.  ST-LINK/V2\n# devices seem to have serial numbers with unreadable characters.  ST-LINK/V2\n# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial\n# number reset issues.\n# eg.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/sysfsgpio-raspberrypi.cfg",
    "content": "#\n# Config for using RaspberryPi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver sysfsgpio\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nsysfsgpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nsysfsgpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# sysfsgpio trst_num 7\n# reset_config trst_only\n\n# sysfsgpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ti-icdi.cfg",
    "content": "#\n# TI Stellaris In-Circuit Debug Interface (ICDI) Board\n#\n# This is the propriety ICDI interface used on newer boards such as\n# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232\n# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad\n# http://www.ti.com/tool/ek-lm4f232\n#\n\nadapter driver hla\nhla_layout ti-icdi\nhla_vid_pid 0x1cbe 0x00fd\n\n# Optionally specify the serial number of TI-ICDI devices, for when using\n# multiple devices. Serial numbers can be obtained using lsusb -v\n# Ex.\n# adapter serial \"0F003065\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/ulink.cfg",
    "content": "#\n# Keil ULINK running OpenULINK firmware.\n#\n# http://www.keil.com/ulink1/\n# http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362\n#\n\nadapter driver ulink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/usb-jtag.cfg",
    "content": "# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC.\n#\n# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware\n# including;\n#  * Xilinx USB Platform Cable\n#  * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards\n#  * Many fpga4fun.com boards from such as the Saxo and Xylo boards\n#  * The Numato Opsis\n#\n# Original version - http://www.ixo.de/info/usb_jtag/\n#  Updated version - http://ixo-jtag.sourceforge.net/\n#   Newest version - http://github.com/mithro/ixo-usb-jtag\n#\n# Procedure for using is;\n#  * Get the ixo-usb-jtag firmware for your hardware (or build it yourself).\n#  * Load the firmware using the fxload tool.\n#  * Use openocd.\n#\n# Unless you burn the firmware into the EEPROM on your device, power cycling\n# will require you to reload the firmware using the fxload tool. This can be\n# automated by using udev rules (which can be found in the firmware\n# repository).\n#\n# Ubuntu packages built from mithro's version (with prebuilt firmware and udev\n# rules) can be found at\n# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support\n#\n# TODO: Refactor the usb_blaster driver to allow loading firmware using any low\n# level driver. Loading firmware is currently only supported on the ublast2\n# driver but ixo-usb-jtag requires the ftdi driver.\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x16C0 0x06AD\nusb_blaster device_desc \"Van Ooijen Technische Informatica\"\n# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the\n# ftdi modes, using ublast2 will cause openocd to hang.\nusb_blaster lowlevel_driver ftdi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/usbprog.cfg",
    "content": "#\n# Embedded Projects USBprog\n#\n# http://embedded-projects.net/index.php?page_id=135\n#\n\nadapter driver usbprog\n# USBprog is broken w/short TMS sequences, this is a workaround\n# until the C code can be fixed.\ntms_sequence long\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/vdebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n\nif { [info exists VDEBUGHOST] } {\n\tset _VDEBUGHOST $VDEBUGHOST\n} else {\n\tset _VDEBUGHOST localhost\n}\nif { [info exists VDEBUGPORT] } {\n\tset _VDEBUGPORT $VDEBUGPORT\n} else {\n\tset _VDEBUGPORT 8192\n}\n\nadapter driver vdebug\n# vdebug server:port\nvdebug server $_VDEBUGHOST:$_VDEBUGPORT\n\n# example config debug level and log\n#debug_level 3\n#log_output vd_ocd.log\n\n# example config listen on all interfaces, disable tcl/telnet server\nbindto 0.0.0.0\n#gdb_port 3333\n#telnet_port disabled\ntcl_port disabled\n\n# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw\nvdebug batching 1\n\n# Polling values\nvdebug polling 100 1000"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/vsllink.cfg",
    "content": "#\n# Versaloon Link -- VSLLink\n#\n# http://www.versaloon.com/\n#\n\nadapter driver vsllink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/interface/xds110.cfg",
    "content": "#\n# Texas Instruments XDS110\n#\n# http://processors.wiki.ti.com/index.php/XDS110\n# http://processors.wiki.ti.com/index.php/Emulation_Software_Package#XDS110_Support_Utilities\n#\n\nadapter driver xds110\n\n# Use serial number option to use a specific XDS110\n# when more than one are connected to the host.\n# adapter serial 00000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/mem_helper.tcl",
    "content": "# Helper for common memory read/modify/write procedures\n\n# mrw: \"memory read word\", returns value of $reg\nproc mrw {reg} {\n\treturn [read_memory $reg 32 1]\n}\n\nadd_usage_text mrw \"address\"\nadd_help_text mrw \"Returns value of word in memory.\"\n\n# mrh: \"memory read halfword\", returns value of $reg\nproc mrh {reg} {\n\treturn [read_memory $reg 16 1]\n}\n\nadd_usage_text mrh \"address\"\nadd_help_text mrh \"Returns value of halfword in memory.\"\n\n# mrb: \"memory read byte\", returns value of $reg\nproc mrb {reg} {\n\treturn [read_memory $reg 8 1]\n}\n\nadd_usage_text mrb \"address\"\nadd_help_text mrb \"Returns value of byte in memory.\"\n\n# mmw: \"memory modify word\", updates value of $reg\n#       $reg <== ((value & ~$clearbits) | $setbits)\nproc mmw {reg setbits clearbits} {\n\tset old [mrw $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\tmww $reg $new\n}\n\nadd_usage_text mmw \"address setbits clearbits\"\nadd_help_text mmw \"Modify word in memory. new_val = (old_val & ~clearbits) | setbits;\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/memory.tcl",
    "content": "# MEMORY\n#\n# All Memory regions have two components.\n#    (1) A count of regions, in the form N_NAME\n#    (2) An array within info about each region.\n#\n# The ARRAY\n#\n#       <NAME>(  RegionNumber ,  ATTRIBUTE )\n#\n# Where <NAME> is one of:\n#\n#     N_FLASH  & FLASH   (internal memory)\n#     N_RAM    & RAM     (internal memory)\n#     N_MMREGS & MMREGS  (for memory mapped registers)\n#     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)\n# or  N_UNKNOWN & UNKNOWN for things that do not exist.\n#\n# We have 1 unknown region.\nset N_UNKNOWN 1\n# All MEMORY regions must have these attributes\n#     CS          - chip select (if internal, use -1)\nset UNKNOWN(0,CHIPSELECT) -1\n#     BASE        - base address in memory\nset UNKNOWN(0,BASE)       0\n#     LEN         - length in bytes\nset UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS\n#     HUMAN       - human name of the region\nset UNKNOWN(0,HUMAN) \"unknown\"\n#     TYPE        - one of:\n#                       flash, ram, mmr, unknown\n#                    For harvard arch:\n#                       iflash, dflash, iram, dram\nset UNKNOWN(0,TYPE)       \"unknown\"\n#     RWX         - access ablity\n#                       unix style chmod bits\n#                           0 - no access\n#                           1 - execute\n#                           2 - write\n#                           4 - read\n#                       hence: 7 - readwrite execute\nset RWX_NO_ACCESS     0\nset RWX_X_ONLY        $BIT0\nset RWX_W_ONLY        $BIT1\nset RWX_R_ONLY        $BIT2\nset RWX_RW            [expr {$RWX_R_ONLY + $RWX_W_ONLY}]\nset RWX_R_X           [expr {$RWX_R_ONLY + $RWX_X_ONLY}]\nset RWX_RWX           [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]\nset UNKNOWN(0,RWX)     $RWX_NO_ACCESS\n\n#     WIDTH       - access width\n#                      8,16,32 [0 means ANY]\nset ACCESS_WIDTH_NONE 0\nset ACCESS_WIDTH_8    $BIT0\nset ACCESS_WIDTH_16   $BIT1\nset ACCESS_WIDTH_32   $BIT2\nset ACCESS_WIDTH_ANY  [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]\nset UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE\n\nproc iswithin { ADDRESS BASE LEN } {\n    return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]\n}\n\nproc address_info { ADDRESS } {\n\n    foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {\n\tif { info exists $WHERE } {\n\t    set lmt [set N_[set WHERE]]\n\t    for { set region 0 } { $region < $lmt } { incr region } {\n\t\tif { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {\n\t\t    return  \"$WHERE $region\";\n\t\t}\n\t    }\n\t}\n    }\n\n    # Return the 'unknown'\n    return \"UNKNOWN 0\"\n}\n\nproc memread32 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n\nproc memread32_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/mmr_helpers.tcl",
    "content": "\nproc proc_exists { NAME } {\n    set n [info commands $NAME]\n    set l [string length $n]\n    return [expr {$l != 0}]\n}\n\n# Give: REGISTER name - must be a global variable.\nproc show_mmr32_reg { NAME } {\n\n    global $NAME\n    # we want $($NAME)\n    set a [set [set NAME]]\n\n    if ![catch { set v [memread32 $a] } msg ] {\n\techo [format \"%15s: (0x%08x): 0x%08x\" $NAME $a $v]\n\n\t# Was a helper defined?\n\tset fn show_${NAME}_helper\n\tif [ proc_exists $fn ] {\n\t    # Then call it\n\t    $fn $NAME $a $v\n\t}\n\treturn $v;\n    } else {\n\terror [format \"%s (%s)\" $msg $NAME ]\n    }\n}\n\n\n# Give: NAMES - an array of names accessible\n#               in the callers symbol-scope.\n#       VAL - the bits to display.\n\nproc show_mmr32_bits { NAMES VAL } {\n\n    upvar $NAMES MYNAMES\n\n    set w 5\n    foreach {IDX N} $MYNAMES {\n\tset l [string length $N]\n\tif { $l > $w } { set w $l }\n    }\n\n    for { set x 24 } { $x >= 0 } { incr x -8 } {\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    set s $MYNAMES([expr {$x + $y}])\n\t    echo -n [format \"%2d: %-*s | \" [expr {$x + $y}] $w $s ]\n\t}\n\techo \"\"\n\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    echo -n [format \"    %d%*s | \" [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] \"\"]\n\t}\n\techo \"\"\n    }\n}\n\n\nproc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } {\n    set width [expr {(($MSB - $LSB + 1) + 7) / 4}]\n    set nval [show_normalize_bitfield $VAL $MSB $LSB ]\n    set name0 [lindex $FIELDVALUES 0 ]\n    if [ string compare $name0 _NUMBER_ ] {\n\tset sval [lindex $FIELDVALUES $nval]\n    } else {\n\tset sval \"\"\n    }\n    echo [format \"%-15s: %d (0x%0*x) %s\" $FIELDNAME $nval $width $nval $sval ]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/1986ве1т.cfg",
    "content": "# 1986ВЕ1Т\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=236&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME 1986ве1т\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# use AHB-Lite SRAM for work area\n$_TARGETNAME configure -work-area-phys 0x20100000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/adsp-sc58x.cfg",
    "content": "#\n# Analog Devices ADSP-SC58x (ARM Cortex-A5 plus one or two SHARC+ DSPs)\n#\n\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ADSP-SC58x\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3BA02477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ap0.mem mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -event examine-end {\n   global _TARGETNAME\n   sc58x_enabledebug\n}\n\nproc sc58x_enabledebug {} {\n   # Enable debugging functionality by setting bits in the TAPC_DBGCTL register\n   # it is not possible to halt the target unless these bits have been set\n   ap0.mem mww 0x31131000 0xFFFF\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/aduc702x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aduc702x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n## JTAG scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# allocate the entire SRAM as working area\n$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000\n\n## flash configuration\n# only target number is needed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n## If you use the watchdog, the following code makes sure that the board\n## doesn't reboot when halted via JTAG.  Yes, on the older generation\n## AdUC702x, timer3 continues running even when the CPU is halted.\n\nproc watchdog_service {} {\n    global watchdog_hdl\n    mww 0xffff036c 0\n#    echo \"watchdog!!\"\n    set watchdog_hdl [after 500 watchdog_service]\n}\n\n$_TARGETNAME configure -event reset-halt-post {  watchdog_service }\n$_TARGETNAME configure -event resume-start { global watchdog_hdl; after cancel $watchdog_hdl }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/aducm360.cfg",
    "content": "#\n# This file was created using as references the stm32f1x.cfg and aduc702x.cfg\n#\nsource [find target/swj-dp.tcl]\n\n# Chip name\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aducm360\n}\n\n# Endianness\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# Eventually, the whole SRAM of ADuCM360 will be used (8kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# SWD/JTAG speed\nadapter speed 1000\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# allocate the working area\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME\n\nadapter srst delay 100\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/allwinner_v3s.cfg",
    "content": "# This is the config for an Allwinner V3/V3s (sun8iw8).\n#\n# Notes:\n# - Single core ARM Cortex-A7 with a maximum frequency of 1.2 GHz.\n# - Thumb-2 Technology\n# - Support NEON Advanced SIMD(Single Instruction Multiple Data)instruction\n#   for acceleration of media and signal processing functions\n# - Support Large Physical Address Extensions(LPAE)\n# - VFPv4 Floating Point Unit\n# - 32KB L1 Instruction cache and 32KB L1 Data cache\n# - 128KB L2 cache\n# - has some integrated DDR2 RAM.\n#\n# Pins related for debug and bootstrap:\n#   JTAG\n# JTAG_TMS\tPF0, SDC0_D1\n# JTAG_TDI\tPF1, SDC0_D0\n# JTAG_TDO\tPF3, SDC0_CMD\n# JTAG_TCK\tPF5, SDC0_D2\n#   UART\n# None of UART ports seems to be enabled by ROM.\n# UART0_TX\tPF2, SDC0_CLK\t\tPer default disabled\n# UART0_RX\tPF4, SDC0_D3 \t\tPer default disabled\n# UART1_TX\tPE21\t\t\tPer default disabled\n# UART1_RX\tPE22\t \t\tPer default disabled\n# UART2_TX\tPB0\t\t\tPer default disabled\n# UART2_RX\tPB1\t \t\tPer default disabled\n#\n# JTAG is enabled by default after power on on listed JTAG_* pins. So far the\n# boot sequence is:\n# Time\t\tAction\n# 0000ms\tPower ON\n# 0200ms\tJTAG enabled\n# 0220ms\tJTAG pins switched to SD mode\n#\n# The time frame of 20ms can be not enough to init and halt the CPU. In this\n# case I would recommend to set: \"adapter speed 15000\"\n# To get more or less precise timings, the board should provide reset pin,\n# or some bench power supply with remote function. In my case I used\n# EEZ H24005 with this command to power on and halt the target:\n# \"exec  echo \"*TRG\" > /dev/ttyACM0; sleep 220; reset halt\"\n# After this it is possible to enable JTAG mode again from boot loader or OS.\n# Following DAPs are available:\n# dap[0]->MEM-AP AHB\n# dap[1]->MEM-AP APB->CA7[0]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME v3s\n}\n\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# No NRST or SRST is present on the SoC. Boards may provide\n# some sort of Power cycle reset for complete board or SoC.\n# For this case we provide srst_pulls_trst so the board config\n# only needs to set srst_only.\nreset_config none srst_pulls_trst\n\njtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Add Cortex A7 core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/alphascale_asm9260t.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME asm9260t\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x079264F3\n}\n\n# And srst_pulls_trst by chip design.\nreset_config srst_pulls_trst\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/altera_fpgasoc.cfg",
    "content": "#\n# Altera cyclone V SoC family, 5Cxxx\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME fpgasoc\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga\nif { [info exists FPGA_TAPID] } {\n   set _FPGA_TAPID $FPGA_TAPID\n} else {\n   set _FPGA_TAPID 0x02d020dd\n}\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected-id $_FPGA_TAPID\n\n\n#\n# Cortex-A9 target\n#\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80110000\n# core 1  -  0x80112000\n\n# Slow speed to be sure it will work\nadapter speed 1000\n\nset _TARGETNAME1 $_CHIPNAME.cpu.0\nset _TARGETNAME2 $_CHIPNAME.cpu.1\n\n# A9 core 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80110000\n\n$_TARGETNAME1 configure -event reset-start { adapter speed 1000 }\n$_TARGETNAME1 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME1\"\n\n\n# A9 core 1\n#target create $_TARGETNAME2 cortex_a -dap $_CHIPNAME.dap \\\n#        -coreid 1 -dbgbase 0x80112000\n\n#$_TARGETNAME2 configure -event reset-start { adapter speed 1000 }\n#$_TARGETNAME2 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME2\"\n\nproc cycv_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/altera_fpgasoc_arria10.cfg",
    "content": "# Intel (Altera) Arria10 FPGA SoC\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME arria10\n}\n\n# ARM CoreSight Debug Access Port (dap HPS)\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga (tap)\n# See Intel Arria 10 Handbook\n# https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-10/a10_handbook.pdf\n# Intel Arria 10 GX 160  0x02ee20dd\n# Intel Arria 10 GX 220  0x02e220dd\n# Intel Arria 10 GX 270  0x02ee30dd\n# Intel Arria 10 GX 320  0x02e230dd\n# Intel Arria 10 GX 480  0x02e240dd\n# Intel Arria 10 GX 570  0x02ee50dd\n# Intel Arria 10 GX 660  0x02e250dd\n# Intel Arria 10 GX 900  0x02ee60dd\n# Intel Arria 10 GX 1150 0x02e660dd\n# Intel Arria 10 GT 900  0x02e260dd\n# Intel Arria 10 GT 1150 0x02e060dd\n# Intel Arria 10 SX 160  0x02e620dd\n# Intel Arria 10 SX 220  0x02e020dd\n# Intel Arria 10 SX 270  0x02e630dd\n# Intel Arria 10 SX 320  0x02e030dd\n# Intel Arria 10 SX 480  0x02e040dd\n# Intel Arria 10 SX 570  0x02e650dd\n# Intel Arria 10 SX 660  0x02e050dd\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -expected-id 0x02ee20dd -expected-id 0x02e220dd \\\n\t-expected-id 0x02ee30dd -expected-id 0x02e230dd -expected-id 0x02e240dd \\\n\t-expected-id 0x02ee50dd -expected-id 0x02e250dd -expected-id 0x02ee60dd \\\n\t-expected-id 0x02e660dd -expected-id 0x02e260dd -expected-id 0x02e060dd \\\n\t-expected-id 0x02e620dd -expected-id 0x02e020dd -expected-id 0x02e630dd \\\n\t-expected-id 0x02e030dd -expected-id 0x02e040dd -expected-id 0x02e650dd \\\n\t-expected-id 0x02e050dd\n\nset _TARGETNAME $_CHIPNAME.cpu\n\n#\n# Cortex-A9 target\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap -coreid 0\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap -coreid 1 \\\n\t-defer-examine\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/am335x.cfg",
    "content": "source [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME am335x\n}\n\n# set the taps to be enabled by default. this can be overridden\n# by setting DEFAULT_TAPS in a separate configuration file\n# or directly on the command line.\nif { [info exists DEFAULT_TAPS] } {\n\tset _DEFAULT_TAPS \"$DEFAULT_TAPS\"\n} else {\n\tset _DEFAULT_TAPS \"$_CHIPNAME.tap\"\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 12 0\"\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# M3 DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME m3_tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m3_tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 11 0\"\ndap create $_CHIPNAME.m3_dap -chain-position $_CHIPNAME.m3_tap\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0b94402f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup {\n\tglobal _DEFAULT_TAPS\n\tenable_default_taps $_DEFAULT_TAPS\n}\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n#\n# helper function that enables all taps passed as argument\n#\nproc enable_default_taps { taps } {\n\tforeach tap $taps {\n\t\tjtag tapenable $tap\n\t}\n}\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME_2 $_CHIPNAME.m3\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.m3_dap\n\n#\n# Cortex-A8 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80001000\n\n# SRAM: 64K at 0x4030.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x4000\n\n\n# when putting the target into 'reset halt', we need to disable the watchdog as\n# it would otherwise trigger while we're in JTAG\n# FIXME: unify with target/am437x.cfg\nsource [find mem_helper.tcl]\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/am437x.cfg",
    "content": "source [find target/icepick.cfg]\nsource [find mem_helper.tcl]\n\n###############################################################################\n##\t\t\t\tAM437x Registers\t\t\t     ##\n###############################################################################\nset  PRCM_BASE_ADDR                  0x44df0000\nset  REVISION_PRM                    [expr       {$PRCM_BASE_ADDR     +  0x0000}]\nset  PRM_IRQSTATUS_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0004}]\nset  PRM_IRQENABLE_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0008}]\nset  PRM_IRQSTATUS_M3                [expr       {$PRCM_BASE_ADDR     +  0x000c}]\nset  PRM_IRQENABLE_M3                [expr       {$PRCM_BASE_ADDR     +  0x0010}]\nset  PM_MPU_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0300}]\nset  PM_MPU_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0304}]\nset  RM_MPU_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0314}]\nset  RM_MPU_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0324}]\nset  PM_GFX_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0400}]\nset  PM_GFX_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0404}]\nset  RM_GFX_RSTCTRL                  [expr       {$PRCM_BASE_ADDR     +  0x0410}]\nset  RM_GFX_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0414}]\nset  RM_GFX_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0424}]\nset  RM_RTC_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0524}]\nset  RM_WKUP_RSTCTRL                 [expr       {$PRCM_BASE_ADDR     +  0x2010}]\nset  RM_WKUP_RSTST                   [expr       {$PRCM_BASE_ADDR     +  0x2014}]\nset  CM_L3_AON_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x2800}]\nset  CM_WKUP_DEBUGSS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2820}]\nset  CM_L3S_TSC_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2900}]\nset  CM_WKUP_ADC_TSC_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2920}]\nset  CM_L4_WKUP_AON_CLKSTCTRL        [expr       {$PRCM_BASE_ADDR     +  0x2a00}]\nset  CM_WKUP_L4WKUP_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2a20}]\nset  CM_WKUP_WKUP_M3_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a28}]\nset  CM_WKUP_SYNCTIMER_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a30}]\nset  CM_WKUP_CLKDIV32K_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a38}]\nset  CM_WKUP_USBPHY0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a40}]\nset  CM_WKUP_USBPHY1_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a48}]\nset  CM_WKUP_CLKSTCTRL               [expr       {$PRCM_BASE_ADDR     +  0x2b00}]\nset  CM_WKUP_TIMER0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b20}]\nset  CM_WKUP_TIMER1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b28}]\nset  CM_WKUP_WDT0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b30}]\nset  CM_WKUP_WDT1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b38}]\nset  CM_WKUP_I2C0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b40}]\nset  CM_WKUP_UART0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b48}]\nset  CM_WKUP_SMARTREFLEX0_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b50}]\nset  CM_WKUP_SMARTREFLEX1_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b58}]\nset  CM_WKUP_CONTROL_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2b60}]\nset  CM_WKUP_GPIO0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b68}]\nset  CM_CLKMODE_DPLL_CORE            [expr       {$PRCM_BASE_ADDR     +  0x2d20}]\nset  CM_IDLEST_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d24}]\nset  CM_CLKSEL_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d2c}]\nset  CM_DIV_M4_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d38}]\nset  CM_DIV_M5_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d3c}]\nset  CM_DIV_M6_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d40}]\nset  CM_SSC_DELTAMSTEP_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d48}]\nset  CM_SSC_MODFREQDIV_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d4c}]\nset  CM_CLKMODE_DPLL_MPU             [expr       {$PRCM_BASE_ADDR     +  0x2d60}]\nset  CM_IDLEST_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d64}]\nset  CM_CLKSEL_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d6c}]\nset  CM_DIV_M2_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d70}]\nset  CM_SSC_DELTAMSTEP_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d88}]\nset  CM_SSC_MODFREQDIV_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d8c}]\nset  CM_CLKMODE_DPLL_DDR             [expr       {$PRCM_BASE_ADDR     +  0x2da0}]\nset  CM_IDLEST_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2da4}]\nset  CM_CLKSEL_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2dac}]\nset  CM_DIV_M2_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db0}]\nset  CM_DIV_M4_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db8}]\nset  CM_SSC_DELTAMSTEP_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dc8}]\nset  CM_SSC_MODFREQDIV_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dcc}]\nset  CM_CLKMODE_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2de0}]\nset  CM_IDLEST_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2de4}]\nset  CM_CLKSEL_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2dec}]\nset  CM_DIV_M2_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2df0}]\nset  CM_CLKSEL2_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2e04}]\nset  CM_SSC_DELTAMSTEP_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e08}]\nset  CM_SSC_MODFREQDIV_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e0c}]\nset  CM_CLKDCOLDO_DPLL_PER           [expr       {$PRCM_BASE_ADDR     +  0x2e14}]\nset  CM_CLKMODE_DPLL_DISP            [expr       {$PRCM_BASE_ADDR     +  0x2e20}]\nset  CM_IDLEST_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e24}]\nset  CM_CLKSEL_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e2c}]\nset  CM_DIV_M2_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e30}]\nset  CM_SSC_DELTAMSTEP_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e48}]\nset  CM_SSC_MODFREQDIV_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e4c}]\nset  CM_CLKMODE_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e60}]\nset  CM_IDLEST_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e64}]\nset  CM_CLKSEL_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e6c}]\nset  CM_DIV_M2_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e70}]\nset  CM_CLKSEL2_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e84}]\nset  CM_SSC_DELTAMSTEP_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e88}]\nset  CM_SSC_MODFREQDIV_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e8c}]\nset  CM_SHADOW_FREQ_CONFIG1          [expr       {$PRCM_BASE_ADDR     +  0x2fa0}]\nset  CM_SHADOW_FREQ_CONFIG2          [expr       {$PRCM_BASE_ADDR     +  0x2fa4}]\nset  CM_CLKOUT1_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4100}]\nset  CM_DLL_CTRL                     [expr       {$PRCM_BASE_ADDR     +  0x4104}]\nset  CM_CLKOUT2_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4108}]\nset  CLKSEL_TIMER1MS_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4200}]\nset  CLKSEL_TIMER2_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4204}]\nset  CLKSEL_TIMER3_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4208}]\nset  CLKSEL_TIMER4_CLK               [expr       {$PRCM_BASE_ADDR     +  0x420c}]\nset  CLKSEL_TIMER5_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4210}]\nset  CLKSEL_TIMER6_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4214}]\nset  CLKSEL_TIMER7_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4218}]\nset  CLKSEL_TIMER8_CLK               [expr       {$PRCM_BASE_ADDR     +  0x421c}]\nset  CLKSEL_TIMER9_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4220}]\nset  CLKSEL_TIMER10_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4224}]\nset  CLKSEL_TIMER11_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4228}]\nset  CLKSEL_WDT1_CLK                 [expr       {$PRCM_BASE_ADDR     +  0x422c}]\nset  CLKSEL_SYNCTIMER_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4230}]\nset  CLKSEL_MAC_CLK                  [expr       {$PRCM_BASE_ADDR     +  0x4234}]\nset  CLKSEL_CPTS_RFT_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4238}]\nset  CLKSEL_GFX_FCLK                 [expr       {$PRCM_BASE_ADDR     +  0x423c}]\nset  CLKSEL_GPIO0_DBCLK              [expr       {$PRCM_BASE_ADDR     +  0x4240}]\nset  CLKSEL_LCDC_PIXEL_CLK           [expr       {$PRCM_BASE_ADDR     +  0x4244}]\nset  CLKSEL_ICSS_OCP_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4248}]\nset  CLKSEL_DLL_AGING_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4250}]\nset  CLKSEL_USBPHY32KHZ_GCLK         [expr       {$PRCM_BASE_ADDR     +  0x4260}]\nset  CM_MPU_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8300}]\nset  CM_MPU_MPU_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8320}]\nset  CM_GFX_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8400}]\nset  CM_GFX_GFX_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8420}]\nset  CM_RTC_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8500}]\nset  CM_RTC_RTC_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8520}]\nset  CM_PER_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8800}]\nset  CM_PER_L3_CLKCTRL               [expr       {$PRCM_BASE_ADDR     +  0x8820}]\nset  CM_PER_AES0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8828}]\nset  CM_PER_DES_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8830}]\nset  CM_PER_CRYPTODMA_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8838}]\nset  CM_PER_L3_INSTR_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8840}]\nset  CM_PER_MSTR_EXPS_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8848}]\nset  CM_PER_OCMCRAM_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8850}]\nset  CM_PER_SHA0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8858}]\nset  CM_PER_SLV_EXPS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8860}]\nset  CM_PER_VPFE0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8868}]\nset  CM_PER_VPFE1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8870}]\nset  CM_PER_TPCC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8878}]\nset  CM_PER_TPTC0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8880}]\nset  CM_PER_TPTC1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8888}]\nset  CM_PER_TPTC2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8890}]\nset  CM_PER_DLL_AGING_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8898}]\nset  CM_PER_L4HS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a0}]\nset  CM_PER_L4FW_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a8}]\nset  CM_PER_L3S_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8a00}]\nset  CM_PER_GPMC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a20}]\nset  CM_PER_IEEE5000_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8a28}]\nset  CM_PER_MCASP0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a38}]\nset  CM_PER_MCASP1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a40}]\nset  CM_PER_MMC2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a48}]\nset  CM_PER_QSPI_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a58}]\nset  CM_PER_USB_OTG_SS0_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a60}]\nset  CM_PER_USB_OTG_SS1_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a68}]\nset  CM_PER_ICSS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8b00}]\nset  CM_PER_ICSS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8b20}]\nset  CM_PER_L4LS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8c00}]\nset  CM_PER_L4LS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8c20}]\nset  CM_PER_DCAN0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c28}]\nset  CM_PER_DCAN1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c30}]\nset  CM_PER_EPWMSS0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c38}]\nset  CM_PER_EPWMSS1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c40}]\nset  CM_PER_EPWMSS2_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c48}]\nset  CM_PER_EPWMSS3_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c50}]\nset  CM_PER_EPWMSS4_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c58}]\nset  CM_PER_EPWMSS5_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c60}]\nset  CM_PER_ELM_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8c68}]\nset  CM_PER_GPIO1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c78}]\nset  CM_PER_GPIO2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c80}]\nset  CM_PER_GPIO3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c88}]\nset  CM_PER_GPIO4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c90}]\nset  CM_PER_GPIO5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c98}]\nset  CM_PER_HDQ1W_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8ca0}]\nset  CM_PER_I2C1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8ca8}]\nset  CM_PER_I2C2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cb0}]\nset  CM_PER_MAILBOX0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8cb8}]\nset  CM_PER_MMC0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc0}]\nset  CM_PER_MMC1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc8}]\nset  CM_PER_PKA_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8cd0}]\nset  CM_PER_RNG_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8ce0}]\nset  CM_PER_SPARE0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8ce8}]\nset  CM_PER_SPARE1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8cf0}]\nset  CM_PER_SPI0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d00}]\nset  CM_PER_SPI1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d08}]\nset  CM_PER_SPI2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d10}]\nset  CM_PER_SPI3_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d18}]\nset  CM_PER_SPI4_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d20}]\nset  CM_PER_SPINLOCK_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8d28}]\nset  CM_PER_TIMER2_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d30}]\nset  CM_PER_TIMER3_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d38}]\nset  CM_PER_TIMER4_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d40}]\nset  CM_PER_TIMER5_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d48}]\nset  CM_PER_TIMER6_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d50}]\nset  CM_PER_TIMER7_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d58}]\nset  CM_PER_TIMER8_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d60}]\nset  CM_PER_TIMER9_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d68}]\nset  CM_PER_TIMER10_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d70}]\nset  CM_PER_TIMER11_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d78}]\nset  CM_PER_UART1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d80}]\nset  CM_PER_UART2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d88}]\nset  CM_PER_UART3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d90}]\nset  CM_PER_UART4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d98}]\nset  CM_PER_UART5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8da0}]\nset  CM_PER_USBPHYOCP2SCP0_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8db8}]\nset  CM_PER_USBPHYOCP2SCP1_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8dc0}]\nset  CM_PER_EMIF_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8f00}]\nset  CM_PER_EMIF_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8f20}]\nset  CM_PER_DLL_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8f28}]\nset  CM_PER_EMIF_FW_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8f30}]\nset  CM_PER_OTFA_EMIF_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8f38}]\nset  CM_PER_DSS_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9200}]\nset  CM_PER_DSS_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x9220}]\nset  CM_PER_CPSW_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x9300}]\nset  CM_PER_CPGMAC0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x9320}]\nset  CM_PER_OCPWP_L3_CLKSTCTRL       [expr       {$PRCM_BASE_ADDR     +  0x9400}]\nset  CM_PER_OCPWP_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9420}]\n\nset  CONTROL_BASE_ADDR               0x44e10000\nset  CONTROL_STATUS                  [expr       {$CONTROL_BASE_ADDR  +  0x0040}]\nset  DEVICE_ID                       [expr       {$CONTROL_BASE_ADDR  +  0x0600}]\nset  DEV_FEATURE                     [expr       {$CONTROL_BASE_ADDR  +  0x0604}]\nset  DEV_ATTRIBUTE                   [expr       {$CONTROL_BASE_ADDR  +  0x0610}]\nset  MAC_ID0_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0630}]\nset  MAC_ID0_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x0634}]\nset  MAC_ID1_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0638}]\nset  MAC_ID1_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x063c}]\nset  USB_VID_PID                     [expr       {$CONTROL_BASE_ADDR  +  0x07f4}]\nset  CONTROL_CONF_ECAP0_IN_PWM0_OUT  [expr       {$CONTROL_BASE_ADDR  +  0x0964}]\nset  CONTROL_CONF_SPI4_CS0           [expr       {$CONTROL_BASE_ADDR  +  0x0a5c}]\nset  CONTROL_CONF_SPI2_SCLK          [expr       {$CONTROL_BASE_ADDR  +  0x0a60}]\nset  CONTROL_CONF_SPI2_D0            [expr       {$CONTROL_BASE_ADDR  +  0x0a64}]\nset  CONTROL_CONF_XDMA_EVENT_INTR0   [expr       {$CONTROL_BASE_ADDR  +  0x0a70}]\nset  CONTROL_CONF_XDMA_EVENT_INTR1   [expr       {$CONTROL_BASE_ADDR  +  0x0a74}]\nset  CONTROL_CONF_GPMC_A0            [expr       {$CONTROL_BASE_ADDR  +  0x0840}]\nset  DDR_IO_CTRL                     [expr       {$CONTROL_BASE_ADDR  +  0x0e04}]\nset  VTP_CTRL_REG                    [expr       {$CONTROL_BASE_ADDR  +  0x0e0c}]\nset  VREF_CTRL                       [expr       {$CONTROL_BASE_ADDR  +  0x0e14}]\nset  DDR_CKE_CTRL                    [expr       {$CONTROL_BASE_ADDR  +  0x131c}]\nset  DDR_ADDRCTRL_IOCTRL             [expr       {$CONTROL_BASE_ADDR  +  0x1404}]\nset  DDR_ADDRCTRL_WD0_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x1408}]\nset  DDR_ADDRCTRL_WD1_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x140c}]\nset  DDR_DATA0_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1440}]\nset  DDR_DATA1_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1444}]\nset  DDR_DATA2_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1448}]\nset  DDR_DATA3_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x144c}]\nset  EMIF_SDRAM_CONFIG_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1460}]\nset  EMIF_SDRAM_STATUS_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1464}]\n\nset  GPIO0_BASE_ADDR                 0x44e07000\nset  GPIO0_SYSCONFIG                 [expr       {$GPIO0_BASE_ADDR    +  0x0010}]\nset  GPIO0_SYSSTATUS                 [expr       {$GPIO0_BASE_ADDR    +  0x0114}]\nset  GPIO0_CTRL                      [expr       {$GPIO0_BASE_ADDR    +  0x0130}]\nset  GPIO0_OE                        [expr       {$GPIO0_BASE_ADDR    +  0x0134}]\nset  GPIO0_CLEARDATAOUT              [expr       {$GPIO0_BASE_ADDR    +  0x0190}]\nset  GPIO0_SETDATAOUT                [expr       {$GPIO0_BASE_ADDR    +  0x0194}]\n\nset  GPIO5_BASE_ADDR                 0x48322000\nset  GPIO5_SYSCONFIG                 [expr       {$GPIO5_BASE_ADDR    +  0x0010}]\nset  GPIO5_SYSSTATUS                 [expr       {$GPIO5_BASE_ADDR    +  0x0114}]\nset  GPIO5_CTRL                      [expr       {$GPIO5_BASE_ADDR    +  0x0130}]\nset  GPIO5_OE                        [expr       {$GPIO5_BASE_ADDR    +  0x0134}]\nset  GPIO5_CLEARDATAOUT              [expr       {$GPIO5_BASE_ADDR    +  0x0190}]\nset  GPIO5_SETDATAOUT                [expr       {$GPIO5_BASE_ADDR    +  0x0194}]\n\nset  GPIO1_BASE_ADDR                 0x4804c000\nset  GPIO1_SYSCONFIG                 [expr       {$GPIO1_BASE_ADDR    +  0x0010}]\nset  GPIO1_SYSSTATUS                 [expr       {$GPIO1_BASE_ADDR    +  0x0114}]\nset  GPIO1_CTRL                      [expr       {$GPIO1_BASE_ADDR    +  0x0130}]\nset  GPIO1_OE                        [expr       {$GPIO1_BASE_ADDR    +  0x0134}]\nset  GPIO1_CLEARDATAOUT              [expr       {$GPIO1_BASE_ADDR    +  0x0190}]\nset  GPIO1_SETDATAOUT                [expr       {$GPIO1_BASE_ADDR    +  0x0194}]\n\nset  EMIF_BASE_ADDR                  0x4c000000\nset  EMIF_STATUS                     [expr       {$EMIF_BASE_ADDR     +  0x0004}]\nset  EMIF_SDRAM_CONFIG               [expr       {$EMIF_BASE_ADDR     +  0x0008}]\nset  EMIF_SDRAM_CONFIG_2             [expr       {$EMIF_BASE_ADDR     +  0x000c}]\nset  EMIF_SDRAM_REF_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0010}]\nset  EMIF_SDRAM_REF_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0014}]\nset  EMIF_SDRAM_TIM_1                [expr       {$EMIF_BASE_ADDR     +  0x0018}]\nset  EMIF_SDRAM_TIM_1_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x001c}]\nset  EMIF_SDRAM_TIM_2                [expr       {$EMIF_BASE_ADDR     +  0x0020}]\nset  EMIF_SDRAM_TIM_2_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x0024}]\nset  EMIF_SDRAM_TIM_3                [expr       {$EMIF_BASE_ADDR     +  0x0028}]\nset  EMIF_SDRAM_TIM_3_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x002c}]\nset  EMIF_LPDDR2_NVM_TIM             [expr       {$EMIF_BASE_ADDR     +  0x0030}]\nset  EMIF_LPDDR2_NVM_TIM_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0034}]\nset  EMIF_PWR_MGMT_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x0038}]\nset  EMIF_PWR_MGMT_CTRL_SHDW         [expr       {$EMIF_BASE_ADDR     +  0x003c}]\nset  EMIF_LPDDR2_MODE_REG_DATA       [expr       {$EMIF_BASE_ADDR     +  0x0040}]\nset  EMIF_LPDDR2_MODE_REG_CFG        [expr       {$EMIF_BASE_ADDR     +  0x0050}]\nset  EMIF_OCP_CONFIG                 [expr       {$EMIF_BASE_ADDR     +  0x0054}]\nset  EMIF_OCP_CFG_VAL_1              [expr       {$EMIF_BASE_ADDR     +  0x0058}]\nset  EMIF_OCP_CFG_VAL_2              [expr       {$EMIF_BASE_ADDR     +  0x005c}]\nset  EMIF_IODFT_TLGC                 [expr       {$EMIF_BASE_ADDR     +  0x0060}]\nset  EMIF_IODFT_CTRL_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0064}]\nset  EMIF_IODFT_ADDR_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0068}]\nset  EMIF_IODFT_DATA_MISR_RSLT_1     [expr       {$EMIF_BASE_ADDR     +  0x006c}]\nset  EMIF_IODFT_DATA_MISR_RSLT_2     [expr       {$EMIF_BASE_ADDR     +  0x0070}]\nset  EMIF_IODFT_DATA_MISR_RSLT_3     [expr       {$EMIF_BASE_ADDR     +  0x0074}]\nset  EMIF_PERF_CNT_1                 [expr       {$EMIF_BASE_ADDR     +  0x0080}]\nset  EMIF_PERF_CNT_2                 [expr       {$EMIF_BASE_ADDR     +  0x0084}]\nset  EMIF_PERF_CNT_CFG               [expr       {$EMIF_BASE_ADDR     +  0x0088}]\nset  EMIF_PERF_CNT_SEL               [expr       {$EMIF_BASE_ADDR     +  0x008c}]\nset  EMIF_PERF_CNT_TIM               [expr       {$EMIF_BASE_ADDR     +  0x0090}]\nset  EMIF_MISC_REG                   [expr       {$EMIF_BASE_ADDR     +  0x0094}]\nset  EMIF_DLL_CALIB_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0098}]\nset  EMIF_DLL_CALIB_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x009c}]\nset  EMIF_IRQ_EOI                    [expr       {$EMIF_BASE_ADDR     +  0x00a0}]\nset  EMIF_IRQSTATUS_RAW_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00a4}]\nset  EMIF_IRQSTATUS_SYS              [expr       {$EMIF_BASE_ADDR     +  0x00ac}]\nset  EMIF_IRQENABLE_SET_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00b4}]\nset  EMIF_IRQENABLE_CLR_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00bc}]\nset  EMIF_ZQ_CONFIG                  [expr       {$EMIF_BASE_ADDR     +  0x00c8}]\nset  EMIF_TEMP_ALERT_CONFIG          [expr       {$EMIF_BASE_ADDR     +  0x00cc}]\nset  EMIF_OCP_ERR_LOG                [expr       {$EMIF_BASE_ADDR     +  0x00d0}]\nset  EMIF_RDWR_LVL_RMP_WIN           [expr       {$EMIF_BASE_ADDR     +  0x00d4}]\nset  EMIF_RDWR_LVL_RMP_CTRL          [expr       {$EMIF_BASE_ADDR     +  0x00d8}]\nset  EMIF_RDWR_LVL_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x00dc}]\nset  EMIF_DDR_PHY_CTRL_1             [expr       {$EMIF_BASE_ADDR     +  0x00e4}]\nset  EMIF_DDR_PHY_CTRL_1_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x00e8}]\nset  EMIF_DDR_PHY_CTRL_2             [expr       {$EMIF_BASE_ADDR     +  0x00ec}]\nset  EMIF_PRI_COS_MAP                [expr       {$EMIF_BASE_ADDR     +  0x0100}]\nset  EMIF_CONNID_COS_1_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0104}]\nset  EMIF_CONNID_COS_2_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0108}]\nset  ECC_CTRL                        [expr       {$EMIF_BASE_ADDR     +  0x0110}]\nset  ECC_ADDR_RNG_1                  [expr       {$EMIF_BASE_ADDR     +  0x0114}]\nset  ECC_ADDR_RNG_2                  [expr       {$EMIF_BASE_ADDR     +  0x0118}]\nset  EMIF_RD_WR_EXEC_THRSH           [expr       {$EMIF_BASE_ADDR     +  0x0120}]\nset  COS_CONFIG                      [expr       {$EMIF_BASE_ADDR     +  0x0124}]\n\nset  PHY_STATUS_1                    [expr       {$EMIF_BASE_ADDR     +  0x0144}]\nset  PHY_STATUS_2                    [expr       {$EMIF_BASE_ADDR     +  0x0148}]\nset  PHY_STATUS_3                    [expr       {$EMIF_BASE_ADDR     +  0x014c}]\nset  PHY_STATUS_4                    [expr       {$EMIF_BASE_ADDR     +  0x0150}]\nset  PHY_STATUS_5                    [expr       {$EMIF_BASE_ADDR     +  0x0154}]\nset  PHY_STATUS_6                    [expr       {$EMIF_BASE_ADDR     +  0x0158}]\nset  PHY_STATUS_7                    [expr       {$EMIF_BASE_ADDR     +  0x015c}]\nset  PHY_STATUS_8                    [expr       {$EMIF_BASE_ADDR     +  0x0160}]\nset  PHY_STATUS_9                    [expr       {$EMIF_BASE_ADDR     +  0x0164}]\nset  PHY_STATUS_10                   [expr       {$EMIF_BASE_ADDR     +  0x0168}]\nset  PHY_STATUS_11                   [expr       {$EMIF_BASE_ADDR     +  0x016c}]\nset  PHY_STATUS_12                   [expr       {$EMIF_BASE_ADDR     +  0x0170}]\nset  PHY_STATUS_13                   [expr       {$EMIF_BASE_ADDR     +  0x0174}]\nset  PHY_STATUS_14                   [expr       {$EMIF_BASE_ADDR     +  0x0178}]\nset  PHY_STATUS_15                   [expr       {$EMIF_BASE_ADDR     +  0x017c}]\nset  PHY_STATUS_16                   [expr       {$EMIF_BASE_ADDR     +  0x0180}]\nset  PHY_STATUS_17                   [expr       {$EMIF_BASE_ADDR     +  0x0184}]\nset  PHY_STATUS_18                   [expr       {$EMIF_BASE_ADDR     +  0x0188}]\nset  PHY_STATUS_19                   [expr       {$EMIF_BASE_ADDR     +  0x018c}]\nset  PHY_STATUS_20                   [expr       {$EMIF_BASE_ADDR     +  0x0190}]\nset  PHY_STATUS_21                   [expr       {$EMIF_BASE_ADDR     +  0x0194}]\nset  PHY_STATUS_22                   [expr       {$EMIF_BASE_ADDR     +  0x0198}]\nset  PHY_STATUS_23                   [expr       {$EMIF_BASE_ADDR     +  0x019c}]\nset  PHY_STATUS_24                   [expr       {$EMIF_BASE_ADDR     +  0x01a0}]\nset  PHY_STATUS_25                   [expr       {$EMIF_BASE_ADDR     +  0x01a4}]\nset  PHY_STATUS_26                   [expr       {$EMIF_BASE_ADDR     +  0x01a8}]\nset  PHY_STATUS_27                   [expr       {$EMIF_BASE_ADDR     +  0x01ac}]\nset  PHY_STATUS_28                   [expr       {$EMIF_BASE_ADDR     +  0x01b0}]\n\nset  EXT_PHY_CTRL_1                  [expr       {$EMIF_BASE_ADDR     +  0x0200}]\nset  EXT_PHY_CTRL_1_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0204}]\nset  EXT_PHY_CTRL_2                  [expr       {$EMIF_BASE_ADDR     +  0x0208}]\nset  EXT_PHY_CTRL_2_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x020c}]\nset  EXT_PHY_CTRL_3                  [expr       {$EMIF_BASE_ADDR     +  0x0210}]\nset  EXT_PHY_CTRL_3_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0214}]\nset  EXT_PHY_CTRL_4                  [expr       {$EMIF_BASE_ADDR     +  0x0218}]\nset  EXT_PHY_CTRL_4_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x021c}]\nset  EXT_PHY_CTRL_5                  [expr       {$EMIF_BASE_ADDR     +  0x0220}]\nset  EXT_PHY_CTRL_5_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0224}]\nset  EXT_PHY_CTRL_6                  [expr       {$EMIF_BASE_ADDR     +  0x0228}]\nset  EXT_PHY_CTRL_6_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x022c}]\nset  EXT_PHY_CTRL_7                  [expr       {$EMIF_BASE_ADDR     +  0x0230}]\nset  EXT_PHY_CTRL_7_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0234}]\nset  EXT_PHY_CTRL_8                  [expr       {$EMIF_BASE_ADDR     +  0x0238}]\nset  EXT_PHY_CTRL_8_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x023c}]\nset  EXT_PHY_CTRL_9                  [expr       {$EMIF_BASE_ADDR     +  0x0240}]\nset  EXT_PHY_CTRL_9_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0244}]\nset  EXT_PHY_CTRL_10                 [expr       {$EMIF_BASE_ADDR     +  0x0248}]\nset  EXT_PHY_CTRL_10_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x024c}]\nset  EXT_PHY_CTRL_11                 [expr       {$EMIF_BASE_ADDR     +  0x0250}]\nset  EXT_PHY_CTRL_11_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0254}]\nset  EXT_PHY_CTRL_12                 [expr       {$EMIF_BASE_ADDR     +  0x0258}]\nset  EXT_PHY_CTRL_12_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x025c}]\nset  EXT_PHY_CTRL_13                 [expr       {$EMIF_BASE_ADDR     +  0x0260}]\nset  EXT_PHY_CTRL_13_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0264}]\nset  EXT_PHY_CTRL_14                 [expr       {$EMIF_BASE_ADDR     +  0x0268}]\nset  EXT_PHY_CTRL_14_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x026c}]\nset  EXT_PHY_CTRL_15                 [expr       {$EMIF_BASE_ADDR     +  0x0270}]\nset  EXT_PHY_CTRL_15_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0274}]\nset  EXT_PHY_CTRL_16                 [expr       {$EMIF_BASE_ADDR     +  0x0278}]\nset  EXT_PHY_CTRL_16_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x027c}]\nset  EXT_PHY_CTRL_17                 [expr       {$EMIF_BASE_ADDR     +  0x0280}]\nset  EXT_PHY_CTRL_17_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0284}]\nset  EXT_PHY_CTRL_18                 [expr       {$EMIF_BASE_ADDR     +  0x0288}]\nset  EXT_PHY_CTRL_18_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x028c}]\nset  EXT_PHY_CTRL_19                 [expr       {$EMIF_BASE_ADDR     +  0x0290}]\nset  EXT_PHY_CTRL_19_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0294}]\nset  EXT_PHY_CTRL_20                 [expr       {$EMIF_BASE_ADDR     +  0x0298}]\nset  EXT_PHY_CTRL_20_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x029c}]\nset  EXT_PHY_CTRL_21                 [expr       {$EMIF_BASE_ADDR     +  0x02a0}]\nset  EXT_PHY_CTRL_21_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02a4}]\nset  EXT_PHY_CTRL_22                 [expr       {$EMIF_BASE_ADDR     +  0x02a8}]\nset  EXT_PHY_CTRL_22_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ac}]\nset  EXT_PHY_CTRL_23                 [expr       {$EMIF_BASE_ADDR     +  0x02b0}]\nset  EXT_PHY_CTRL_23_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02b4}]\nset  EXT_PHY_CTRL_24                 [expr       {$EMIF_BASE_ADDR     +  0x02b8}]\nset  EXT_PHY_CTRL_24_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02bc}]\nset  EXT_PHY_CTRL_25                 [expr       {$EMIF_BASE_ADDR     +  0x02c0}]\nset  EXT_PHY_CTRL_25_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02c4}]\nset  EXT_PHY_CTRL_26                 [expr       {$EMIF_BASE_ADDR     +  0x02c8}]\nset  EXT_PHY_CTRL_26_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02cc}]\nset  EXT_PHY_CTRL_27                 [expr       {$EMIF_BASE_ADDR     +  0x02d0}]\nset  EXT_PHY_CTRL_27_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02d4}]\nset  EXT_PHY_CTRL_28                 [expr       {$EMIF_BASE_ADDR     +  0x02d8}]\nset  EXT_PHY_CTRL_28_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02dc}]\nset  EXT_PHY_CTRL_29                 [expr       {$EMIF_BASE_ADDR     +  0x02e0}]\nset  EXT_PHY_CTRL_29_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02e4}]\nset  EXT_PHY_CTRL_30                 [expr       {$EMIF_BASE_ADDR     +  0x02e8}]\nset  EXT_PHY_CTRL_30_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ec}]\nset  EXT_PHY_CTRL_31                 [expr       {$EMIF_BASE_ADDR     +  0x02f0}]\nset  EXT_PHY_CTRL_31_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02f4}]\nset  EXT_PHY_CTRL_32                 [expr       {$EMIF_BASE_ADDR     +  0x02f8}]\nset  EXT_PHY_CTRL_32_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02fc}]\nset  EXT_PHY_CTRL_33                 [expr       {$EMIF_BASE_ADDR     +  0x0300}]\nset  EXT_PHY_CTRL_33_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0304}]\nset  EXT_PHY_CTRL_34                 [expr       {$EMIF_BASE_ADDR     +  0x0308}]\nset  EXT_PHY_CTRL_34_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x030c}]\nset  EXT_PHY_CTRL_35                 [expr       {$EMIF_BASE_ADDR     +  0x0310}]\nset  EXT_PHY_CTRL_35_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0314}]\nset  EXT_PHY_CTRL_36                 [expr       {$EMIF_BASE_ADDR     +  0x0318}]\nset  EXT_PHY_CTRL_36_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x031c}]\n\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\n\nset  RTC_BASE_ADDR                   0x44e3e000\nset  RTC_KICK0R                      [expr       {$RTC_BASE_ADDR      +  0x6c}]\nset  RTC_KICK1R                      [expr       {$RTC_BASE_ADDR      +  0x70}]\n\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME am437x\n}\n\nset JRC_MODULE\t\ticepick_d\nset DEBUGSS_MODULE\tdebugss\nset M3_MODULE\t\tm3_wakeupss\n\nset JRC_NAME\t\t$_CHIPNAME.$JRC_MODULE\nset DEBUGSS_NAME\t$_CHIPNAME.$DEBUGSS_MODULE\nset M3_NAME\t\t$_CHIPNAME.$M3_MODULE\nset _TARGETNAME\t\t$_CHIPNAME.mpuss\n\n#\n# M3 WakeupSS DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME $M3_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $M3_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 11 0\"\ndap create $M3_NAME.dap -chain-position $M3_NAME\n\n#\n# DebugSS DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x46b6902f\n}\njtag newtap $_CHIPNAME $DEBUGSS_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $DEBUGSS_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 12 0\"\ndap create $DEBUGSS_NAME.dap -chain-position $DEBUGSS_NAME\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b98c02f\n}\njtag newtap $_CHIPNAME $JRC_MODULE -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $JRC_NAME -event setup \"jtag tapenable $DEBUGSS_NAME\"\n # some TCK tycles are required to activate the DEBUG power domain\njtag configure $JRC_NAME -event post-reset \"runtest 100\"\n\n#\n# Cortex-A9 target\n#\ntarget create $_TARGETNAME cortex_a -dap $DEBUGSS_NAME.dap -coreid 0 -dbgbase 0x80000000\n\n\n# SRAM: 256K at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x40000\n\n# Disables watchdog timer after reset otherwise board won't stay in\n# halted state.\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n\nproc ceil { x y } {\n\treturn [ expr {($x + $y - 1) / $y} ]\n}\n\nproc device_type { } {\n\tglobal CONTROL_STATUS\n\n\tset tmp [ mrw $CONTROL_STATUS ]\n\tset tmp [ expr {$tmp & 0x700} ]\n\tset tmp [ expr {$tmp >> 8} ]\n\n\treturn $tmp\n}\n\nproc get_input_clock_frequency { } {\n\tglobal CONTROL_STATUS\n\n\tif { [ device_type ] != 3 } {\n\t\terror \"Unknown device type\\n\"\n\t\treturn -1\n\t}\n\n\tset freq [ mrw $CONTROL_STATUS ]\n\tset freq [ expr {$freq & 0x00c00000} ]\n\tset freq [ expr {$freq >> 22} ]\n\n\tswitch $freq {\n\t\t0 {\n\t\t\tset CLKIN 19200000\n\t\t}\n\n\t\t1 {\n\t\t\tset CLKIN 24000000\n\t\t}\n\n\t\t2 {\n\t\t\tset CLKIN 25000000\n\t\t}\n\n\t\t3 {\n\t\t\tset CLKIN 26000000\n\t\t}\n\t}\n\n\treturn $CLKIN\n}\n\nproc mpu_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_MPU\n\tglobal CM_CLKSEL_DPLL_MPU\n\tglobal CM_DIV_M2_DPLL_MPU\n\tglobal CM_IDLEST_DPLL_MPU\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_MPU ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ]\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_MPU $clksel\n\n\tset div_m2 [ expr {$div_m2 & (~0x1f)} ]\n\tset div_m2 [ expr {$div_m2 | $M2} ]\n\tmww $CM_DIV_M2_DPLL_MPU $div_m2\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x7\n\twhile { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { }\n\n\techo \"MPU DPLL locked\"\n}\n\nproc core_pll_config { CLKIN N M M4 M5 M6 } {\n\tglobal CM_CLKMODE_DPLL_CORE\n\tglobal CM_CLKSEL_DPLL_CORE\n\tglobal CM_DIV_M4_DPLL_CORE\n\tglobal CM_DIV_M5_DPLL_CORE\n\tglobal CM_DIV_M6_DPLL_CORE\n\tglobal CM_IDLEST_DPLL_CORE\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_CORE ]\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_CORE $clksel\n\tmww $CM_DIV_M4_DPLL_CORE $M4\n\tmww $CM_DIV_M5_DPLL_CORE $M5\n\tmww $CM_DIV_M6_DPLL_CORE $M6\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { }\n\n\techo \"CORE DPLL locked\"\n}\n\nproc per_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_PER\n\tglobal CM_CLKSEL_DPLL_PER\n\tglobal CM_DIV_M2_DPLL_PER\n\tglobal CM_IDLEST_DPLL_PER\n\n\tset x [ expr {$M * $CLKIN / 1000000} ]\n\tset y [ expr {($N + 1) * 250} ]\n\tset sd [ ceil $x $y ]\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_PER ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_PER ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0xff0fffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tset clksel [ expr {$clksel | ($sd << 24)} ]\n\tmww $CM_CLKSEL_DPLL_PER $clksel\n\n\tset div_m2 [ expr {0xffffff80 | $M2} ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { }\n\n\techo \"PER DPLL locked\"\n}\n\nproc ddr_pll_config { CLKIN N M M2 M4 } {\n\tglobal CM_CLKMODE_DPLL_DDR\n\tglobal CM_CLKSEL_DPLL_DDR\n\tglobal CM_DIV_M2_DPLL_DDR\n\tglobal CM_DIV_M4_DPLL_DDR\n\tglobal CM_IDLEST_DPLL_DDR\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_DDR ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ]\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_DDR $clksel\n\n\tset div_m2 [ expr {($div_m2 & 0xffffffe0) | $M2} ]\n\tmww $CM_DIV_M2_DPLL_DDR $div_m2\n\tmww $CM_DIV_M4_DPLL_DDR $M4\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { }\n\n\techo \"DDR DPLL Locked\"\n}\n\nproc config_opp100 { } {\n\tset CLKIN [ get_input_clock_frequency ]\n\n\tif { $CLKIN == -1 } {\n\t\treturn -1\n\t}\n\n\tswitch $CLKIN {\n\t\t24000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  25   1\n\t\t\tcore_pll_config  $CLKIN  2  125  10  8  4\n\t\t\tper_pll_config   $CLKIN  9  400  5\n\t\t\tddr_pll_config   $CLKIN  2  50   1   2\n\t\t}\n\n\t\t25000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  24   1\n\t\t\tcore_pll_config  $CLKIN  0  40   10  8  4\n\t\t\tper_pll_config   $CLKIN  9  384  5\n\t\t\tddr_pll_config   $CLKIN  0  16   1   2\n\t\t}\n\n\t\t26000000 {\n\t\t\tmpu_pll_config   $CLKIN  12  300  1\n\t\t\tcore_pll_config  $CLKIN  12  500  10  8  4\n\t\t\tper_pll_config   $CLKIN  12  480  5\n\t\t\tddr_pll_config   $CLKIN  12  200  1   2\n\t\t}\n\n\t\t19200000 {\n\t\t\tmpu_pll_config   $CLKIN  3   125  1\n\t\t\tcore_pll_config  $CLKIN  11  625  10  8  4\n\t\t\tper_pll_config   $CLKIN  7   400  5\n\t\t\tddr_pll_config   $CLKIN  2   125  1   2\n\t\t}\n\t}\n}\n\nproc emif_prcm_clk_enable { } {\n\tglobal CM_PER_EMIF_FW_CLKCTRL\n\tglobal CM_PER_EMIF_CLKCTRL\n\n\tmww $CM_PER_EMIF_FW_CLKCTRL 0x02\n\tmww $CM_PER_EMIF_CLKCTRL 0x02\n\n\twhile { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { }\n}\n\nproc vtp_enable { } {\n\tglobal VTP_CTRL_REG\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x40 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] & ~0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n}\n\nproc config_ddr_ioctrl { } {\n\tglobal DDR_ADDRCTRL_IOCTRL\n\tglobal DDR_ADDRCTRL_WD0_IOCTRL\n\tglobal DDR_ADDRCTRL_WD1_IOCTRL\n\tglobal DDR_CKE_CTRL\n\tglobal DDR_DATA0_IOCTRL\n\tglobal DDR_DATA1_IOCTRL\n\tglobal DDR_DATA2_IOCTRL\n\tglobal DDR_DATA3_IOCTRL\n\tglobal DDR_IO_CTRL\n\n\tmww $DDR_ADDRCTRL_IOCTRL\t0x84\n\tmww $DDR_ADDRCTRL_WD0_IOCTRL\t0x00\n\tmww $DDR_ADDRCTRL_WD1_IOCTRL\t0x00\n\tmww $DDR_DATA0_IOCTRL\t\t0x84\n\tmww $DDR_DATA1_IOCTRL\t\t0x84\n\tmww $DDR_DATA2_IOCTRL\t\t0x84\n\tmww $DDR_DATA3_IOCTRL\t\t0x84\n\n\tmww $DDR_IO_CTRL\t\t0x00\n\tmww $DDR_CKE_CTRL\t\t0x03\n}\n\nproc config_ddr_phy { } {\n\tglobal EMIF_DDR_PHY_CTRL_1\n\tglobal EMIF_DDR_PHY_CTRL_1_SHDW\n\n\tglobal EXT_PHY_CTRL_1\n\tglobal EXT_PHY_CTRL_1_SHDW\n\tglobal EXT_PHY_CTRL_2\n\tglobal EXT_PHY_CTRL_2_SHDW\n\tglobal EXT_PHY_CTRL_3\n\tglobal EXT_PHY_CTRL_3_SHDW\n\tglobal EXT_PHY_CTRL_4\n\tglobal EXT_PHY_CTRL_4_SHDW\n\tglobal EXT_PHY_CTRL_5\n\tglobal EXT_PHY_CTRL_5_SHDW\n\tglobal EXT_PHY_CTRL_6\n\tglobal EXT_PHY_CTRL_6_SHDW\n\tglobal EXT_PHY_CTRL_7\n\tglobal EXT_PHY_CTRL_7_SHDW\n\tglobal EXT_PHY_CTRL_8\n\tglobal EXT_PHY_CTRL_8_SHDW\n\tglobal EXT_PHY_CTRL_9\n\tglobal EXT_PHY_CTRL_9_SHDW\n\tglobal EXT_PHY_CTRL_10\n\tglobal EXT_PHY_CTRL_10_SHDW\n\tglobal EXT_PHY_CTRL_11\n\tglobal EXT_PHY_CTRL_11_SHDW\n\tglobal EXT_PHY_CTRL_12\n\tglobal EXT_PHY_CTRL_12_SHDW\n\tglobal EXT_PHY_CTRL_13\n\tglobal EXT_PHY_CTRL_13_SHDW\n\tglobal EXT_PHY_CTRL_14\n\tglobal EXT_PHY_CTRL_14_SHDW\n\tglobal EXT_PHY_CTRL_15\n\tglobal EXT_PHY_CTRL_15_SHDW\n\tglobal EXT_PHY_CTRL_16\n\tglobal EXT_PHY_CTRL_16_SHDW\n\tglobal EXT_PHY_CTRL_17\n\tglobal EXT_PHY_CTRL_17_SHDW\n\tglobal EXT_PHY_CTRL_18\n\tglobal EXT_PHY_CTRL_18_SHDW\n\tglobal EXT_PHY_CTRL_19\n\tglobal EXT_PHY_CTRL_19_SHDW\n\tglobal EXT_PHY_CTRL_20\n\tglobal EXT_PHY_CTRL_20_SHDW\n\tglobal EXT_PHY_CTRL_21\n\tglobal EXT_PHY_CTRL_21_SHDW\n\tglobal EXT_PHY_CTRL_22\n\tglobal EXT_PHY_CTRL_22_SHDW\n\tglobal EXT_PHY_CTRL_23\n\tglobal EXT_PHY_CTRL_23_SHDW\n\tglobal EXT_PHY_CTRL_24\n\tglobal EXT_PHY_CTRL_24_SHDW\n\tglobal EXT_PHY_CTRL_25\n\tglobal EXT_PHY_CTRL_25_SHDW\n\tglobal EXT_PHY_CTRL_26\n\tglobal EXT_PHY_CTRL_26_SHDW\n\tglobal EXT_PHY_CTRL_27\n\tglobal EXT_PHY_CTRL_27_SHDW\n\tglobal EXT_PHY_CTRL_28\n\tglobal EXT_PHY_CTRL_28_SHDW\n\tglobal EXT_PHY_CTRL_29\n\tglobal EXT_PHY_CTRL_29_SHDW\n\tglobal EXT_PHY_CTRL_30\n\tglobal EXT_PHY_CTRL_30_SHDW\n\tglobal EXT_PHY_CTRL_31\n\tglobal EXT_PHY_CTRL_31_SHDW\n\tglobal EXT_PHY_CTRL_32\n\tglobal EXT_PHY_CTRL_32_SHDW\n\tglobal EXT_PHY_CTRL_33\n\tglobal EXT_PHY_CTRL_33_SHDW\n\tglobal EXT_PHY_CTRL_34\n\tglobal EXT_PHY_CTRL_34_SHDW\n\tglobal EXT_PHY_CTRL_35\n\tglobal EXT_PHY_CTRL_35_SHDW\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\tmww $EMIF_DDR_PHY_CTRL_1\t0x8009\n\tmww $EMIF_DDR_PHY_CTRL_1_SHDW\t0x8009\n\n\tset slave_ratio\t\t0x80\n\tset gatelvl_init_ratio\t0x20\n\tset wr_dqs_slave_delay\t0x60\n\tset rd_dqs_slave_delay\t0x60\n\tset dq_offset\t\t0x40\n\tset gatelvl_init_mode\t0x01\n\tset wr_data_slave_delay\t0x80\n\tset gatelvl_num_dq0 0x0f\n\tset wrlvl_num_dq0 0x0f\n\n\tmww $EXT_PHY_CTRL_1        [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_1_SHDW   [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_26       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_26_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_31       0x00\n\tmww $EXT_PHY_CTRL_31_SHDW  0x00\n\tmww $EXT_PHY_CTRL_32       0x00\n\tmww $EXT_PHY_CTRL_32_SHDW  0x00\n\tmww $EXT_PHY_CTRL_33       0x00\n\tmww $EXT_PHY_CTRL_33_SHDW  0x00\n\tmww $EXT_PHY_CTRL_34       0x00\n\tmww $EXT_PHY_CTRL_34_SHDW  0x00\n\tmww $EXT_PHY_CTRL_35       0x00\n\tmww $EXT_PHY_CTRL_35_SHDW  0x00\n\tmww $EXT_PHY_CTRL_22       0x00\n\tmww $EXT_PHY_CTRL_22_SHDW  0x00\n\tmww $EXT_PHY_CTRL_23       [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_23_SHDW  [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24       [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24_SHDW  [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0} ]\n\tmww $EXT_PHY_CTRL_25       [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_25_SHDW  [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_36       [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n\tmww $EXT_PHY_CTRL_36_SHDW  [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n}\n\nproc config_ddr_timing { } {\n\tglobal EMIF_SDRAM_TIM_1\n\tglobal EMIF_SDRAM_TIM_2\n\tglobal EMIF_SDRAM_TIM_3\n\tglobal EMIF_SDRAM_TIM_1_SHDW\n\tglobal EMIF_SDRAM_TIM_2_SHDW\n\tglobal EMIF_SDRAM_TIM_3_SHDW\n\tglobal EMIF_ZQ_CONFIG\n\n\tmww $EMIF_SDRAM_TIM_1\t\t0xeaaad4db\n\tmww $EMIF_SDRAM_TIM_1_SHDW\t0xeaaad4db\n\n\tmww $EMIF_SDRAM_TIM_2\t\t0x266b7fda\n\tmww $EMIF_SDRAM_TIM_2_SHDW\t0x266b7fda\n\n\tmww $EMIF_SDRAM_TIM_3\t\t0x107f8678\n\tmww $EMIF_SDRAM_TIM_3_SHDW\t0x107f8678\n\n\tmww $EMIF_ZQ_CONFIG\t\t0x50074be4\n}\n\nproc config_ddr_pm { } {\n\tglobal EMIF_PWR_MGMT_CTRL\n\tglobal EMIF_PWR_MGMT_CTRL_SHDW\n\tglobal EMIF_DLL_CALIB_CTRL\n\tglobal EMIF_DLL_CALIB_CTRL_SHDW\n\tglobal EMIF_TEMP_ALERT_CONFIG\n\n\tmww $EMIF_PWR_MGMT_CTRL\t\t0x00\n\tmww $EMIF_PWR_MGMT_CTRL_SHDW\t0x00\n\tmww $EMIF_DLL_CALIB_CTRL\t0x00050000\n\tmww $EMIF_DLL_CALIB_CTRL_SHDW\t0x00050000\n\tmww $EMIF_TEMP_ALERT_CONFIG\t0x00\n}\n\nproc config_ddr_priority { } {\n\tglobal EMIF_PRI_COS_MAP\n\tglobal EMIF_CONNID_COS_1_MAP\n\tglobal EMIF_CONNID_COS_2_MAP\n\tglobal EMIF_RD_WR_EXEC_THRSH\n\tglobal COS_CONFIG\n\n\tmww $EMIF_PRI_COS_MAP       0x00\n\tmww $EMIF_CONNID_COS_1_MAP  0x00\n\tmww $EMIF_CONNID_COS_2_MAP  0x0\n\tmww $EMIF_RD_WR_EXEC_THRSH  0x0405\n\tmww $COS_CONFIG             0x00ffffff\n}\n\nproc config_ddr3 { SDRAM_CONFIG } {\n\tglobal CM_DLL_CTRL\n\tglobal EMIF_IODFT_TLGC\n\tglobal EMIF_RDWR_LVL_CTRL\n\tglobal EMIF_RDWR_LVL_RMP_CTRL\n\tglobal EMIF_SDRAM_CONFIG\n\tglobal EMIF_SDRAM_CONFIG_EXT\n\tglobal EMIF_SDRAM_REF_CTRL\n\tglobal EMIF_SDRAM_REF_CTRL_SHDW\n\tglobal EMIF_STATUS\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\temif_prcm_clk_enable\n\tvtp_enable\n\n\tset dll [ expr {[ mrw $CM_DLL_CTRL ] & ~0x01 }]\n\tmww $CM_DLL_CTRL $dll\n\twhile { !([ mrw $CM_DLL_CTRL ] & 0x04) } { }\n\n\tconfig_ddr_ioctrl\n\n\tmww $EMIF_SDRAM_CONFIG_EXT\t0xc163\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_SDRAM_REF_CTRL\t0x80003000\n\n\tconfig_ddr_phy\n\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\n\tconfig_ddr_timing\n\tconfig_ddr_pm\n\tconfig_ddr_priority\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x3000\n\tmww $EMIF_SDRAM_CONFIG\t\t$SDRAM_CONFIG\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x0c30\n\tmww $EMIF_SDRAM_REF_CTRL_SHDW\t0x0c30\n\n\tsleep 10\n\n\tset tmp [ expr {[ mrw $EXT_PHY_CTRL_36 ] | 0x0100 }]\n\tmww $EXT_PHY_CTRL_36\t\t$tmp\n\tmww $EXT_PHY_CTRL_36_SHDW\t$tmp\n\n\tmww $EMIF_RDWR_LVL_RMP_CTRL\t0x80000000\n\tmww $EMIF_RDWR_LVL_CTRL\t\t0x80000000\n\n\twhile { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { }\n\n\tif { [ mrw $EMIF_STATUS ]  & 0x70 } {\n\t\terror \"DDR3 Hardware Leveling incomplete!!!\"\n\t}\n}\n\nproc init_platform { SDRAM_CONFIG } {\n\tconfig_opp100\n\tconfig_ddr3 $SDRAM_CONFIG\n}\n\n$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 }\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/amdm37x.cfg",
    "content": "#\n# Copyright (C)   2010-2011   by Karl Kurbjun\n# Copyright (C)   2009-2011   by Øyvind Harboe\n# Copyright (C)   2009        by David Brownell\n# Copyright (C)   2009        by Magnus Lundin\n#\n# TI AM/DM37x Technical Reference Manual (Version R)\n#  http://www.ti.com/lit/ug/sprugn4r/sprugn4r.pdf\n#\n# This script is based on the AM3517 initialization.  It should be considered\n# preliminary since it needs more complete testing and only the basic\n# operations work.\n#\n\n###############################################################################\n# User modifiable parameters\n###############################################################################\n\n# This script uses the variable CHIPTYPE to determine whether this is an AM35x\n# or DM37x target. If CHIPTYPE is not set it will error out.\nif { [info exists CHIPTYPE] } {\n\n   if { [info exists CHIPNAME] } {\n      set _CHIPNAME $CHIPNAME\n   } else {\n      set _CHIPNAME $CHIPTYPE\n   }\n\n   switch $CHIPTYPE {\n      dm37x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x2b89102f -expected-id 0x1b89102f -expected-id 0x0b89102f\"\n      }\n      am35x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x0b7ae02f -expected-id 0x0b86802f\"\n      }\n      default {\n         error \"ERROR: CHIPTYPE was set, but it was not set to a valid value.  Acceptable values are \\\"dm37x\\\" or \\\"am35x\\\".\"\n      }\n   }\n} else {\n  error \"ERROR: CHIPTYPE was not defined. Please set CHIPTYPE to \\\"am35x\\\" for the AM35x or \\\"dm37x\\\" for the DM37x series in the board configuration.\"\n}\n\n# Run the adapter at the fastest acceptable speed with the slowest possible\n# core clock.\nadapter speed 10\n\n###############################################################################\n# JTAG setup\n# The OpenOCD commands are described in the TAP Declaration section\n#  http://openocd.org/doc/html/TAP-Declaration.html\n###############################################################################\n\n# The AM/DM37x has an ICEPick module in it like many of TI's other devices. More\n#  can be read about this module in sprugn4r in chapter 27:  \"Debug and\n#  Emulation\".  The module is used to route the JTAG chain to the various\n#  subsystems in the chip.\nsource [find target/icepick.cfg]\n\n# The TAP order should be described from the TDO connection in OpenOCD to the\n#  TDI pin.  The OpenOCD FAQ describes this in more detail:\n#  http://openocd.org/doc/html/FAQ.html\n\n# From SPRUGN4R CH27 the available secondary TAPs are in this order from TDO:\n#\n#  Device   |  TAP number\n#  ---------|------------\n#  DAP      |  3\n#  Sequencer|  2   Note: The sequencer is an ARM968\n#  DSP      |  1\n#  D2D      |  0\n#\n# Right now the only secondary tap enabled is the DAP so the rest are left\n# undescribed.\n\n######\n# Start of Chain Description\n# The Secondary TAPs all have enable functions defined for use with the ICEPick\n# Only the DAP is enabled.  The AM37xx does not have the Sequencer or DSP but\n# the TAP numbers for ICEPick do not change.\n#\n# TODO: A disable function should also be added.\n######\n\n# Secondary TAP: DAP is closest to the TDO output\n# The TAP enable event also needs to be described\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# These taps are only present in the DM37x series.\nif { $CHIPTYPE == \"dm37x\" } {\n   # Secondary TAP: Sequencer (ARM968) it is not in the chain by default\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME arm2 -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\n   jtag configure $_CHIPNAME.arm2 -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n   # Secondary TAP: C64x+ DSP - it is not in the chain by default (-disable)\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n   jtag configure $_CHIPNAME.dsp -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n}\n\n# Secondary TAP: D2D it is not in the chain by default (-disable)\n# The ICEPick can be used to enable it in the chain.\n# This IRLEN is probably incorrect - not sure where the documentation is.\njtag newtap $_CHIPNAME d2d -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\njtag configure $_CHIPNAME.d2d -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEPick - it is closest to TDI so last in the chain\neval \"jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f $_JRC_TAPID\"\n\n######\n# End of Chain Description\n######\n\n######\n# Start JTAG TAP events\n######\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# Enable the DAP TAP\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\n######\n# End JTAG TAP events\n######\n\n###############################################################################\n# Target Setup:\n# This section is described in the OpenOCD documentation under CPU Configuration\n#  http://openocd.org/doc/html/CPU-Configuration.html\n###############################################################################\n\n# Create the CPU target to be used with GDB:  Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# The DM37x has 64K of SRAM starting at address 0x4020_0000.  Allow the first\n# 16K to be used as a scratchpad for OpenOCD.\n\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n######\n# Start Target Reset Event Setup:\n######\n\n# Set the JTAG clock down to 10 kHz to be sure that it will work with the\n#  slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up\n#  *after* PLL and clock tree setup.\n\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 10 }\n\n# Describe the reset assert process for openocd - this is asserted with the\n# ICEPick\n$_TARGETNAME configure -event \"reset-assert\" {\n\n   global _CHIPNAME\n\n   # assert warm system reset through ICEPick\n   icepick_c_wreset $_CHIPNAME.jrc\n}\n\n# After the reset is asserted we need to re-initialize debugging and speed up\n# the JTAG clock.\n\n$_TARGETNAME configure -event reset-assert-post {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n   adapter speed 1000\n}\n\n$_TARGETNAME configure -event gdb-attach {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n\n   echo \"Halting target\"\n   halt\n}\n\n######\n# End Target Reset Event Setup:\n######\n\n###############################################################################\n# Target Functions\n# Add any functions needed for the target here\n###############################################################################\n\n# Run this to enable invasive debugging.  This is run automatically in the\n# reset sequence.\nproc amdm37x_dbginit {target} {\n   # General Cortex-A8 debug initialisation\n   cortex_a dbginit\n\n   # Enable DBGEN signal.  This signal is described in the ARM v7 TRM, but\n   # access to the signal appears to be implementation specific.  TI does not\n   # describe this register much except a quick line that states DBGEM (sic) is\n   # at this address and this bit.\n   $target mww phys 0x5401d030 0x00002000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ampere_emag.cfg",
    "content": "#\n# OpenOCD Target Configuration for eMAG ARMv8 Processor\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure defaults for target\n# Can be overriden in board configuration file\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME emag\n}\n\nif { [info exists NUMCORES] } {\n\tset _NUMCORES $NUMCORES\n} else {\n\tset _NUMCORES 32\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID ] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4BA00477\n}\n\n#\n# Configure JTAG TAP\n#\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID\nset _TAPNAME $_CHIPNAME.cpu\n\nset _DAPNAME ${_TAPNAME}_dap\nset _APNUM 1\ndap create $_DAPNAME -chain-position $_TAPNAME\n$_DAPNAME apsel $_APNUM\n\n# Create the DAP AP0 MEM-AP AHB-AP target\ntarget create AHB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 0\n\n# Create the DAP AP1 MEM-AP APB-AP target\ntarget create APB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 1\n\n#\n# Configure target CPUs\n#\n\n# Build string used to enable smp mode\nset _SMP_STR \"target smp\"\n\nfor {set _i 0} {$_i < $_NUMCORES} {incr _i} {\n\t# Format a string to reference which CPU target to use\n\tset _TARGETNAME [format \"${_TAPNAME}_%02d\" $_i]\n\n\t# Create and configure Cross Trigger Interface (CTI) - required for halt and resume\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $_DAPNAME -ap-num $_APNUM -baseaddr [expr {0xFC020000 + ($_i << 20)}]\n\n\t# Create the target\n\ttarget create $_TARGETNAME aarch64 -endian $_ENDIAN -dap $_DAPNAME -ap-num $_APNUM -cti $_CTINAME -coreid $_i\n\tset _SMP_STR \"$_SMP_STR $_TARGETNAME\"\n\n\t# Clear CTI output/input enables that are not configured by OpenOCD for aarch64\n\t$_TARGETNAME configure -event examine-start [subst {\n\t\t$_CTINAME write INEN0 0x00000000\n\t\t$_CTINAME write INEN1 0x00000000\n\t\t$_CTINAME write INEN2 0x00000000\n\t\t$_CTINAME write INEN3 0x00000000\n\t\t$_CTINAME write INEN4 0x00000000\n\t\t$_CTINAME write INEN5 0x00000000\n\t\t$_CTINAME write INEN6 0x00000000\n\t\t$_CTINAME write INEN7 0x00000000\n\t\t$_CTINAME write INEN8 0x00000000\n\n\t\t$_CTINAME write OUTEN2 0x00000000\n\t\t$_CTINAME write OUTEN3 0x00000000\n\t\t$_CTINAME write OUTEN4 0x00000000\n\t\t$_CTINAME write OUTEN5 0x00000000\n\t\t$_CTINAME write OUTEN6 0x00000000\n\t\t$_CTINAME write OUTEN7 0x00000000\n\t\t$_CTINAME write OUTEN8 0x00000000\n\t}]\n\n\t# Enable OpenOCD HWTHREAD RTOS feature for GDB thread (CPU) selection support\n\t# This feature presents CPU cores (\"hardware threads\") in an SMP system as threads to GDB\n\t$_TARGETNAME configure -rtos hwthread\n}\neval $_SMP_STR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ar71xx.cfg",
    "content": "# Atheros AR71xx MIPS 24Kc SoC.\n# tested on PB44 refererence board\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst\n\nset CHIPNAME ar71xx\n\njtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1\n\nset _TARGETNAME $CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-halt-post {\n\t#setup PLL to lowest common denominator 300/300/150 setting\n\tmww 0xb8050000 0x000f40a3\t;# reset val + CPU:3 DDR:3 AHB:0\n\tmww 0xb8050000 0x800f40a3\t;# send to PLL\n\n\t#next command will reset for PLL changes to take effect\n\tmww 0xb8050008 3\t\t;# set reset_switch and clock_switch (resets SoC)\n}\n\n$_TARGETNAME configure -event reset-init {\n\t#complete pll initialization\n\tmww 0xb8050000 0x800f0080\t;# set sw_update bit\n\tmww 0xb8050008 0\t\t;# clear reset_switch bit\n\tmww 0xb8050000 0x800f00e8       ;# clr pwrdwn & bypass\n\tmww 0xb8050008 1\t\t;# set clock_switch bit\n\tsleep 1                         ;# wait for lock\n\n\t# Setup DDR config and flash mapping\n\tmww 0xb8000000 0xefbc8cd0       ;# DDR cfg cdl val (rst: 0x5bfc8d0)\n\tmww 0xb8000004 0x8e7156a2       ;# DDR cfg2 cdl val (rst: 0x80d106a8)\n\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb800000c 0                ;# clr ext. mode register\n\tmww 0xb8000010 2 \t\t;# force auto refresh all banks\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000008 0x31             ;# set DDR mode value CAS=3\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb8000014 0x461b           ;# DDR refresh value\n\tmww 0xb8000018 0xffff           ;# DDR Read Data This Cycle value (16bit: 0xffff)\n\tmww 0xb800001c 0x7              ;# delay added to the DQS line (normal = 7)\n\tmww 0xb8000020 0\n\tmww 0xb8000024 0\n\tmww 0xb8000028 0\n}\n\n# setup working area somewhere in RAM\n$_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000\n\n# serial SPI capable flash\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/arm_corelink_sse200.cfg",
    "content": "#\n# Configuration script for Arm CoreLink SSE-200 Subsystem based IoT SoCs.\n#\n\nglobal TARGET\nset TARGET $_CHIPNAME\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n#\n# SRAM on ARM CoreLink SSE-200 can be 4 banks of 8/16/32/64 KB\n# We will configure work area assuming 8-KB bank size in SRAM bank 1.\n# Also SRAM start addresses defaults to secure mode alias.\n# These values can be overridden as per board configuration\n#\n\nglobal _WORKAREASIZE_CPU0\nif { [info exists WORKAREASIZE_CPU0] } {\n\tset _WORKAREASIZE_CPU0 $WORKAREASIZE_CPU0\n} else {\n\tset _WORKAREASIZE_CPU0 0x1000\n}\n\nglobal _WORKAREAADDR_CPU0\nif { [info exists WORKAREAADDR_CPU0] } {\n\tset _WORKAREAADDR_CPU0 $WORKAREAADDR_CPU0\n} else {\n\tset _WORKAREAADDR_CPU0 0x30008000\n}\n\n#\n# Target configuration for Cortex M33 Core 0 on ARM CoreLink SSE-200\n# Core 0 is the boot core and will always be configured.\n#\n\ntarget create ${TARGET}.CPU0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\n${TARGET}.CPU0 configure -work-area-phys $_WORKAREAADDR_CPU0 -work-area-size $_WORKAREASIZE_CPU0 -work-area-backup 0\n\n${TARGET}.CPU0 cortex_m reset_config sysresetreq\n\n#\n# Target configuration for Cortex M33 Core 1 on ARM CoreLink SSE-200\n# Core 1 is optional and locked at boot until core 0 unlocks it.\n#\n\nif { $_ENABLE_CPU1 } {\n\tglobal _WORKAREASIZE_CPU1\n\tif { [info exists WORKAREASIZE_CPU1] } {\n\t\tset _WORKAREASIZE_CPU1 $WORKAREASIZE_CPU1\n\t} else {\n\t\tset _WORKAREASIZE_CPU1 0x1000\n\t}\n\n\tglobal _WORKAREAADDR_CPU1\n\tif { [info exists WORKAREAADDR_CPU1] } {\n\t\tset _WORKAREAADDR_CPU1 $WORKAREAADDR_CPU1\n\t} else {\n\t\tset _WORKAREAADDR_CPU1 0x30009000\n\t}\n\n\ttarget create ${TARGET}.CPU1 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\n\t${TARGET}.CPU1 configure -work-area-phys $_WORKAREAADDR_CPU1 -work-area-size $_WORKAREASIZE_CPU1 -work-area-backup 0\n\n\t${TARGET}.CPU1 cortex_m reset_config vectreset\n}\n\n# Make sure the default target is the boot core\ntargets ${TARGET}.CPU0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/armada370.cfg",
    "content": "#\n# armada370 -- support for the Marvell Armada/370 CPU family\n#\n# gerg@uclinux.org, OCT-2013\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME armada370\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\nproc armada370_dbginit {target} {\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"armada370_dbginit $_TARGETNAME\"\n\ndap apsel 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at32ap7000.cfg",
    "content": "# Atmel AT32AP7000\n#\n# This is the only core in the now-inactive high end AVR32 product line,\n# with MMU, Java Acceleration, and \"pixel coprocessor\".  The AP7 line\n# is for \"Application Processors\" (AP) with 7-stage pipelines.\n#\n# Most current AVR32 parts are in the UC3 flash based microcontroller (UC)\n# product line with 3-stage pipelines and without those extras.\n#\n# All AVR32 parts provide the Nexus Class 3 on-chip debug interfaces\n# through their JTAG interfaces.\n\njtag newtap ap7 nexus -irlen 5 -expected-id 0x21e8203f\n\n# REVISIT declare an avr32 target ... needs OpenOCD infrastructure\n# for both Nexus (generic) and AVR32 (Atmel-specific).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91r40008.cfg",
    "content": "# AT91R40008 target configuration file\n\n# TRST is tied to SRST on the AT91X40 family.\nreset_config srst_only srst_pulls_trst\n\n\nif {[info exists CHIPNAME]} {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91r40008\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Setup the JTAG scan chain.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91rm9200.cfg",
    "content": "# Atmel AT91rm9200\n# http://atmel.com/products/at91/\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91rm9200\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x05b0203f\n}\n\n# Never allow the following!\nif { $_CPUTAPID == 0x15b0203f } {\n   echo \"-------------------------------------------------------\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: TapID 0x15b0203f is wrong for at91rm9200     -\"\n   echo \"- ERROR: The chip/board has a JTAG select pin/jumper  -\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: In one position (0x05b0203f) it selects the  -\"\n   echo \"- ERROR: ARM CPU, in the other position (0x1b0203f)   -\"\n   echo \"- ERROR: it selects boundary-scan not the ARM         -\"\n   echo \"- ERROR:                                              -\"\n   echo \"-------------------------------------------------------\"\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# AT91RM9200 has a 16K block of sram @ 0x0020.0000\n$_TARGETNAME configure -work-area-phys 0x00200000 \\\n\t\t-work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3XXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam3\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n    halt\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3ax_4x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000A0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3ax_8x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 512K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3ax_xx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3nXX.cfg",
    "content": "\n#\n# Configuration for Atmel's SAM3N series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME at91sam3n\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank flash0 at91sam3 0x00400000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3sXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n\nsource [find target/at91sam3XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u1c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u1e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u2c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u2e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u4c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip, it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3u4e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam3uxx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4XXX.cfg",
    "content": "#\n# script for ATMEL sam4, a Cortex-M4 chip\n#\n\n#\n# sam4 devices can support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam4\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4c32x.cfg",
    "content": "# script for ATMEL sam4c32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x01100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4cXXX.cfg",
    "content": "# script for ATMEL sam4c, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4lXX.cfg",
    "content": "# script for ATMEL sam4l, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME\n\n# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3).\n#\n# smap_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the SMAP to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post \"at91sam4l smap_reset_deassert\"\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed.\n# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio.\n# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2\n# but your mileage may vary.\nadapter speed 50\n\n# System RC oscillator RCSYS starts in 3 cycles\nadapter srst delay 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4sXX.cfg",
    "content": "# script for ATMEL sam4, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam4sd32x.cfg",
    "content": "# script for ATMEL sam4sd32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x00500000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam7a2.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7a2\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam7se512.cfg",
    "content": "# ATMEL sam7se512\n# Example: the \"Elektor Internet Radio\" - EIR\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7se512\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# The target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam7sx.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7s\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -event reset-init {\n        soft_reset_halt\n        # RSTC_CR : Reset peripherals\n        mww 0xfffffd00 0xa5000004\n        # disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=73)\n\tmww 0xffffff60 0x00490100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam7x256.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7x256\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam7x512.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME sam7x512\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\nflash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9\n######################################\n\nif { [info exists AT91_CHIPNAME] } {\n\tset _CHIPNAME $AT91_CHIPNAME\n} else {\n\terror \"you must specify a chip name\"\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0792603f\n}\n\nreset_config trst_and_srst separate trst_push_pull srst_open_drain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 300\njtag_ntrst_delay 200\n\nadapter speed 3\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9260.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9260\n}\n\nsource [find target/at91sam9.cfg]\n\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9260 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 4 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x1000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9260_ext_RAM_ext_flash.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nsource [find target/at91sam9261.cfg]\n\nreset_config trst_and_srst\n\nadapter speed 4\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\nscan_chain\n$_TARGETNAME configure -event reset-start {\n\t# at reset chip runs at 32khz\n\tadapter speed 8\n}\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n# Flash configuration\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n\n# Faster memory downloads. This is disabled automatically during\n# reset init since all reset init sequences are too short for\n# fast memory access\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\nproc at91sam_init { } {\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# Now run at anything fast... ie: 10mhz!\n\tadapter speed 10000               ;# Increase JTAG Speed to 6 MHz\n\n\tmww 0xffffec00 0x0a0a0a0a         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x0b0b0b0b         ;# SMC_PULSE0\n\tmww 0xffffec08 0x00160016         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00161003         ;# SMC_MODE0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR : Select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000         ;# PIO_PDR : Disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x2                ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\t#mww 0xffffea08 0x85227254         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S641632H-UC75 : 1M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x5d2              ;# SDRAMC_TR : Set refresh timer count to 15us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9261.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9261\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9261\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x28000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9263.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9263\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9263\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9263 has two SRAM areas,\n# one starting at 0x00300000 of 80KiB\n# and the other  starting at 0x00500000 of 16KiB.\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x14000 -work-area-backup 1\n#$_TARGETNAME configure -work-area-phys 0x00500000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9g10.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G10\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g10\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G10 has one SRAM area at 0x00300000 of 16KiB\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9g20.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G20\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g20\n}\n\nsource [find target/at91sam9.cfg]\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n\nadapter speed 5\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 16 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9g45.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G45\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g45\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G45 has one SRAM area starting at 0x00300000 of 64 KiB.\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x200000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sam9rl.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9RL\n######################################\n\nif { [info exists CHIPNAME] } {\n   set AT91_CHIPNAME $CHIPNAME\n} else {\n   set AT91_CHIPNAME at91sam9rl\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x10000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91sama5d2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The JTAG connection is disabled at reset, and during the ROM Code execution.\n# It is re-enabled when the ROM code jumps in the boot file copied from an\n# external Flash memory into the internalSRAM, or when the ROM code launches\n# the SAM-BA monitor, when no boot file has been found in any external Flash\n# memory.\n# For more JTAG related information see, :\n# https://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-sheet-ds60001476G.pdf\n#\n# If JTAGSEL pin:\n# - if enabled, boundary Scan mode is activated. JTAG ID Code value is 0x05B3F03F.\n# - if disabled, ICE mode is activated. Debug Port JTAG IDCODE value is 0x5BA00477\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME at91sama5d2\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n\t-expected-id 0x5ba00477\n\n# Cortex-A5 target\nset _TARGETNAME $_CHIPNAME.cpu_a5\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91samdXX.cfg",
    "content": "#\n# script for Atmel SAMD, SAMR, SAML or SAMC, a Cortex-M0 chip\n#\n\n#\n# samdXX devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91samd\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2)\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        at91samd dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset.\n# Other members of family usually use SYSCLK = 4 MHz after reset.\n# Datasheet does not specify SYSCLK to SWD clock ratio.\n# Usually used SYSCLK/6 is slow, testing shows that debugging can\n# work @ SYSCLK/2 but your mileage may vary.\n# This limit is most probably imposed by incorrectly handled SWD WAIT\n# on some SWD adapters.\n\nadapter speed 400\n\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at maximal clock speed. Atmel recommends\n# adapter speed less than 10 * CPU clock.\n# adapter speed 5000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/at91samg5x.cfg",
    "content": "# script for the ATMEL samg5x Cortex-M4F chip family\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atheros_ar2313.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2313\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atheros_ar2315.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2315\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atheros_ar9331.cfg",
    "content": "# The Atheros AR9331 is a highly integrated and cost effective\n# IEEE 802.11n 1x1 2.4 GHz System- on-a-Chip (SoC) for wireless\n# local area network (WLAN) AP and router platforms.\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 400 MHz\n# - External 16-bit DDR1, DDR2, or SDRAM memory interface\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin A72 on the SoC will reset internal JTAG logic.\n#\n\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO6, (B46)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO7, (A54)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO8, (A52)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (A72)\tInput only\n# SYS_RST_L\t????????\tOutput reset request or GPIO\n#   Bootstrap\n# MEM_TYPE[1]\tGPIO28, (A74)\t0 - SDRAM, 1 - DDR1 RAM, 2 - DDR2 RAM\n# MEM_TYPE[0]\tGPIO12, (A56)\n# FW_DOWNLOAD\tGPIO16, (A75)\tUsed if BOOT_FROM_SPI = 0. 0 - boot from USB\n#                               1 - boot from MDIO.\n# JTAG_MODE(JS)\tGPIO11, (B48)\t0 - JTAG (Default); 1 - EJTAG\n# BOOT_FROM_SPI\tGPIO1, (A77)\t0 - ROM boot; 1 - SPI boot\n# SEL_25M_40M\tGPIO0, (A78)\t0 - 25MHz; 1 - 40MHz\n#   UART\n# UART0_SOUT\tGPIO10, (A79)\n# UART0_SIN\tGPIO9, (B68)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9331\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\nproc disable_watchdog { } {\n\t;# disable watchdog\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n\n# Section with helpers which can be used by boards\nproc ar9331_25mhz_pll_init {} {\n\tmww 0xb8050008 0x00018004\t;# bypass PLL; AHB_POST_DIV - ratio 4\n\tmww 0xb8050004 0x00000352\t;# 34000(ns)/40ns(25MHz) = 0x352 (850)\n\tmww 0xb8050000 0x40818000\t;# Power down control for CPU PLL\n\t\t\t\t\t;# OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050010 0x001003e8\t;# CPU PLL Dither FRAC Register\n\t\t\t\t\t;# (disabled?)\n\tmww 0xb8050000 0x00818000\t;# Power on | OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050008 0x00008000\t;# remove bypass;\n\t\t\t\t\t;# AHB_POST_DIV - ratio 2\n}\n\nproc ar9331_ddr1_init {} {\n\tmww 0xb8000000 0x7fbc8cd0       ;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x133\t;# mode reg: 0x133 - default\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb800000c 0x2\t;# Extended mode register value.\n\t\t\t\t;# default 0x2 - Reset to weak driver, DLL on\n\tmww 0xb8000010 0x2\t;# Forces an EMRS update cycle\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x33\t;# mode reg: remove some bit?\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb8000014 0x4186\t;# enable refres: bit(14) - set refresh rate\n\tmww 0xb800001c 0x8\t;# This register is used along with DQ Lane 0,\n\t\t\t\t;# DQ[7:0], DQS_0\n\tmww 0xb8000020 0x9\t;# This register is used along with DQ Lane 1,\n\t\t\t\t;# DQ[15:8], DQS_1.\n\tmww 0xb8000018 0xff\t;# DDR read and capture bit mask.\n\t\t\t\t;# Each bit represents a cycle of valid data.\n}\n\nproc ar9331_ddr2_init {} {\n\tmww 0xb8000000 0x7fbc8cd0\t;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb800008c 0x00000a59\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000090 0x00000000\n\tmww 0xb8000010 0x00000010\t;# EMR2S update cycle\n\n\tmww 0xb8000094 0x00000000\n\tmww 0xb8000010 0x00000020\t;# EMR3S update cycle\n\n\tmww 0xb800000c 0x00000000\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000008 0x00000100\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000010 0x00000004\n\tmww 0xb8000010 0x00000004\t;# AUTO REFRESH cycle\n\n\tmww 0xb8000008 0x00000a33\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb800000c 0x00000382\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb800000c 0x00000402\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000014 0x00004186\t;# DDR_REFRESH\n\tmww 0xb800001c 0x00000008\t;# DDR_TAP_CTRL0\n\tmww 0xb8000020 0x00000009\t;# DDR_TAP_CTRL1\n\n\t;# DDR read and capture bit mask.\n\t;# Each bit represents a cycle of valid data.\n\t;# 0xff: use 16-bit DDR\n\tmww 0xb8000018 0x000000ff\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atheros_ar9344.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9344\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\nproc test_ar9344_uart0_tx {} {\n\techo \"configuring uart0..\"\n\tmww 0xb802000c 0x87\n\tmww 0xb8020000 0x15\n\tmww 0xb8020004 0\n\tmww 0xb802000c 7\n\tmww 0xb8020004 0\n\n\techo \"send message: hallo world\"\n\tmww 0xb8020000 0x68\n\tmww 0xb8020000 0x65\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x20\n\tmww 0xb8020000 0x77\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x72\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x64\n\tmww 0xb8020000 0x0a\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atmega128.cfg",
    "content": "# for avr\n\n   set _CHIPNAME avr\n   set _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\nreset_config srst_only\nadapter srst delay 100\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x8970203F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n\n#to use it, script will be like:\n#init\n#adapter speed 4500\n#reset init\n#verify_ircapture disable\n#\n#halt\n#wait halt\n#poll\n#avr mass_erase 0\n#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex\n#reset run\n#shutdown\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atmega128rfa1.cfg",
    "content": "set _CHIPNAME avr\nset _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\n# avr jtag docs never connect RSTN\nreset_config none\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0a70103f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atsame5x.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54, E53, E51 and D51 devices\n# with a Cortex-M4 core\n#\n\n#\n# Devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME atsame5\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (the smallest RAM size is 128kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAM DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        atsame5 dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAM E5x/D51 runs at SYSCLK = 48 MHz from RC oscillator after reset.\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at clock speed over 5000 khz. Atmel recommends\n# adapter speed less than 10 * CPU clock.\nadapter speed 2000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atsaml1x.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L1x target\n#\n# Note: These devices support SWD only.\n#\n\ntransport select swd\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME saml1x\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nswd newdap $_CHIPNAME cpu -expected-id 0x0bf11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/atsamv.cfg",
    "content": "# ATMEL SAMV, SAMS, and SAME chips are Cortex-M7 parts\n# The chips are very similar; the SAMV series just has\n# more peripherals and seems like the \"flagship\" of the\n# family. This script will work for all of them.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME samv\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bd11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 1800\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/avr32.cfg",
    "content": "set _CHIPNAME avr32\nset _ENDIAN big\n\nset _CPUTAPID 0x21e8203f\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CPUTAPID\n\nset _TARGETNAME [format \"%s.cpu\" $_CHIPNAME]\ntarget create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm2711.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom BCM2711 used in Raspberry Pi 4\n# No documentation was found on Broadcom website\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2711\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm281xx.cfg",
    "content": "# BCM281xx\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm281xx\n}\n\n\n# Main CPU DAP\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\n\n\n# Dual Cortex-A9\nset _TARGETNAME0 $_CHIPNAME.cpu0\nset _TARGETNAME1 $_CHIPNAME.cpu1\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME0 cortex_a -dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x3fe10000\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0x3fe12000\ntarget smp $_TARGETNAME0 $_TARGETNAME1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm2835.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi Model A, B, B+,\n# the Compute Module, and the Raspberry Pi Zero.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2835\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x07b7617F\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 5\nadapter speed 4000\n\ntarget create $_CHIPNAME.cpu0 arm11 -chain-position $_CHIPNAME.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm2836.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom chip used in the Raspberry Pi 2 Model B\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2836\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\ttarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -coreid $_core -dbgbase [lindex $_DBGBASE $_core]\n\t$_TARGETNAME configure -event reset-assert-post { cortex_a dbginit }\n\n\tset _smp_command \"$_smp_command $_CHIPNAME.cpu$_core\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm2837.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi 3,\n# and in later models of the Raspberry Pi 2.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837b0\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2837\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\nset _CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\t$_TARGETNAME configure -event reset-assert-post { aarch64  dbginit }\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm4706.cfg",
    "content": "set _CHIPNAME bcm4706\nset _CPUID 0x1008c17f\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm4718.cfg",
    "content": "set _CHIPNAME bcm4718\nset _LVTAPID 0x1471617f\nset _CPUID 0x0008c17f\n\nsource [find target/bcm47xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm47xx.cfg",
    "content": "echo \"Forcing reset_config to none to prevent OpenOCD from pulling SRST after the switch from LV is already performed\"\nreset_config none\n\njtag newtap $_CHIPNAME-lv tap -irlen 32 -ircapture 0x1 -irmask 0x1f -expected-id $_LVTAPID -expected-id $_CPUID\njtag configure $_CHIPNAME-lv.tap -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME-lv.tap -event tap-disable {}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"switch_lv_to_ejtag\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n\nproc switch_lv_to_ejtag {} {\n    global _CHIPNAME\n    poll 0\n    irscan $_CHIPNAME-lv.tap 0x143ff3a\n    drscan $_CHIPNAME-lv.tap 32 1\n    jtag tapdisable $_CHIPNAME-lv.tap\n    poll 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm5352e.cfg",
    "content": "set _CHIPNAME bcm5352e\nset _CPUID 0x0535217f\n\njtag newtap $_CHIPNAME cpu -irlen 8 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bcm6348.cfg",
    "content": "set _CHIPNAME bcm6348\nset _CPUID 0x0634817f\n\nadapter speed 1000\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bluefield.cfg",
    "content": "# BlueField SoC Target\n\nset _CHIPNAME bluefield\n\n# Specify the target device\n#rshim device /dev/rshim0/rshim\n\n# Main DAP\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\nadapter speed 1500\n\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Initialize the target name and command variable.\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\n# CTI relative address\nset $_TARGETNAME.cti(0) 0xC4020000\nset $_TARGETNAME.cti(1) 0xC4120000\nset $_TARGETNAME.cti(2) 0xC8020000\nset $_TARGETNAME.cti(3) 0xC8120000\nset $_TARGETNAME.cti(4) 0xCC020000\nset $_TARGETNAME.cti(5) 0xCC120000\nset $_TARGETNAME.cti(6) 0xD0020000\nset $_TARGETNAME.cti(7) 0xD0120000\nset $_TARGETNAME.cti(8) 0xD4020000\nset $_TARGETNAME.cti(9) 0xD4120000\nset $_TARGETNAME.cti(10) 0xD8020000\nset $_TARGETNAME.cti(11) 0xD8120000\nset $_TARGETNAME.cti(12) 0xDC020000\nset $_TARGETNAME.cti(13) 0xDC120000\nset $_TARGETNAME.cti(14) 0xE0020000\nset $_TARGETNAME.cti(15) 0xE0120000\n\n# Create debug targets for a number of cores starting from core '_core_start'.\n# Adjust the numbers according to board configuration.\nset _core_start 0\nset _cores 16\n\n# Create each core\nfor { set _core $_core_start } { $_core < $_core_start + $_cores } { incr _core 1 } {\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != $_core_start } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\n# Configure SMP\nif { $_cores > 1 } {\n    eval $_smp_command\n}\n\n# Make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# Examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/bluenrg-x.cfg",
    "content": "#\n# bluenrg-1/2 and bluenrg-lp devices support only SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME bluenrg-1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 24kB-256bytes\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x5F00\n}\n\nadapter speed 4000\n\nswj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\nset WDOG_VALUE 0\nset WDOG_VALUE_SET 0\n\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000100 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n# In BlueNRG-X reset pin is actually a shutdown (power-off), so define reset as none\nreset_config none\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset JTAG_IDCODE_B2 0x0200A041\nset JTAG_IDCODE_B1 0x0\n\n$_TARGETNAME configure -event halted {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        # Stop watchdog during halt, if enabled. Only Bluenrg-1/2\n        set WDOG_VALUE [mrw 0x40700008]\n        if [expr {$WDOG_VALUE & (1 << 1)}] {\n            set WDOG_VALUE_SET 1\n            mww 0x40700008 [expr {$WDOG_VALUE & 0xFFFFFFFD}]\n        }\n    }\n}\n$_TARGETNAME configure -event resumed {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        if {$WDOG_VALUE_SET} {\n            # Restore watchdog enable value after resume. Only Bluenrg-1/2\n            mww 0x40700008 $WDOG_VALUE\n            set WDOG_VALUE_SET 0\n           }\n   }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/c100.cfg",
    "content": "# c100 config.\n# This is ARM1136 dual core\n# this script only configures one core (that is used to run Linux)\n\n# assume no PLL lock, start slowly\nadapter speed 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME c100\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x27b3645b\n}\n\nif { [info exists DSPTAPID] } {\n   set _DSPTAPID $DSPTAPID\n} else {\n   set _DSPTAPID 0x27b3645b\n}\n\njtag newtap $_CHIPNAME dsp -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_DSPTAPID\n\n\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# C100's ARAM 64k SRAM\n$_TARGETNAME configure -work-area-phys 0x0a000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/c100config.tcl",
    "content": "\n# board(-config) specific parameters file.\n\n# set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ]\nproc config {label} {\n    return [dict get [configC100] $label ]\n}\n\n# show the value for the param. with label\nproc showconfig {label} {\n    echo [format \"0x%x\" [dict get [configC100] $label ]]\n}\n\n# Telo board config\n# when there are more then one board config\n# use soft links to c100board-config.tcl\n# so that only the right board-config gets\n# included (just like include/configs/board-configs.h\n# in u-boot.\nproc configC100 {} {\n    # xtal freq. 24MHz\n    dict set configC100 CFG_REFCLKFREQ\t         24000000\n\n    # Amba Clk 165MHz\n    dict set configC100 CONFIG_SYS_HZ_CLOCK      165000000\n    dict set configC100 w_amba 1\n    dict set configC100 x_amba 1\n    # y = amba_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_amba [expr {[dict get $configC100 CONFIG_SYS_HZ_CLOCK] * ( ([dict get $configC100 w_amba]+1 ) * ([dict get $configC100 x_amba]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n    # Arm Clk 450MHz, must be a multiple of 25 MHz\n    dict set configC100 CFG_ARM_CLOCK      450000000\n    dict set configC100 w_arm 0\n    dict set configC100 x_arm 1\n    # y = arm_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_arm [expr {[dict get $configC100 CFG_ARM_CLOCK] * ( ([dict get $configC100 w_arm]+1 ) * ([dict get $configC100 x_arm]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n\n}\n\n# This should be called for reset init event handler\nproc setupTelo {} {\n\n    # setup GPIO used as control signals for C100\n    setupGPIO\n    # This will allow access to lower 8MB or NOR\n    lowGPIO5\n    # setup NOR size,timing,etc.\n    setupNOR\n    # setup internals + PLL + DDR2\n    initC100\n}\n\n\nproc setupNOR {} {\n    echo \"Setting up NOR: 16MB, 16-bit wide bus, CS0\"\n    # this is taken from u-boot/boards/mindspeed/ooma-darwin/board.c:nor_hw_init()\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    # enable Expansion Bus Clock + CS0 (NOR)\n    mww $EX_CSEN_REG 0x3\n    # set the address space for CS0=16MB\n    mww $EX_CS0_SEG_REG 0x7ff\n    # set the CS0 bus width to 16-bit\n    mww $EX_CS0_CFG_REG 0x202\n    # set timings to NOR\n    mww $EX_CS0_TMG1_REG 0x03034006\n    mww $EX_CS0_TMG2_REG 0x04040002\n    #mww $EX_CS0_TMG3_REG\n    # set EBUS clock 165/5=33MHz\n    mww $EX_CLOCK_DIV_REG 0x5\n    # everything else is OK with default\n}\n\nproc bootNOR {} {\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n    set BLOCK_RESET_REG\t       [regs BLOCK_RESET_REG]\n    set DDR_RST\t\t       [regs DDR_RST]\n\n    # put DDR controller in reset (so that it comes reset in u-boot)\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $EXP_CS0_BASEADDR\n    # run\n    resume\n}\nproc setupGPIO {} {\n    echo \"Setting up GPIO block for Telo\"\n    # This is current setup for Telo (see sch. for details):\n    #GPIO0 reset for FXS-FXO IC, leave as input, the IC has internal pullup\n    #GPIO1 irq line for FXS-FXO\n    #GPIO5 addr22 for NOR flash (access to upper 8MB)\n    #GPIO17 reset for DECT module.\n    #GPIO29 CS_n for NAND\n\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n\n    # set GPIO29=GPIO17=1, GPIO5=0\n    mww $GPIO_OUTPUT_REG [expr {1<<29 | 1<<17}]\n    # enable [as output] GPIO29,GPIO17,GPIO5\n    mww $GPIO_OE_REG [expr  {1<<29 | 1<<17 | 1<<5}]\n}\n\nproc highGPIO5 {} {\n    echo \"GPIO5 high\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=1\n    mmw $GPIO_OUTPUT_REG [expr {1 << 5}] 0x0\n}\n\nproc lowGPIO5 {} {\n    echo \"GPIO5 low\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=0\n    mmw $GPIO_OUTPUT_REG 0x0 [expr {1 << 5}]\n}\n\nproc boardID {id} {\n    # so far built:\n    # 4'b1111\n    dict set boardID 15 name \"EVT1\"\n    dict set boardID 15 ddr2size 128M\n    # dict set boardID 15 nandsize 1G\n    # dict set boardID 15 norsize 16M\n    # 4'b0000\n    dict set boardID 0 name \"EVT2\"\n    dict set boardID 0 ddr2size 128M\n    # 4'b0001\n    dict set boardID 1 name \"EVT3\"\n    dict set boardID 1 ddr2size 256M\n    # 4'b1110\n    dict set boardID 14 name \"EVT3_old\"\n    dict set boardID 14 ddr2size 128M\n    # 4'b0010\n    dict set boardID 2 name \"EVT4\"\n    dict set boardID 2 ddr2size 256M\n\n    return $boardID\n}\n\n\n# converted from u-boot/boards/mindspeed/ooma-darwin/board.c:ooma_board_detect()\n# figure out what board revision this is, uses BOOTSTRAP register to read stuffed resistors\nproc ooma_board_detect {} {\n    set GPIO_BOOTSTRAP_REG\t[regs GPIO_BOOTSTRAP_REG]\n\n    # read the current value of the BOOTSTRAP pins\n    set tmp [mrw $GPIO_BOOTSTRAP_REG]\n    echo [format \"GPIO_BOOTSTRAP_REG  (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG $tmp]\n    # extract the GPBP bits\n    set gpbt [expr {($tmp &0x1C00) >> 10 | ($tmp & 0x40) >>3}]\n\n    # display board ID\n    echo [format \"This is %s (0x%x)\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # show it on serial console\n    putsUART0 [format \"This is %s (0x%x)\\n\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # return the ddr2 size, used to configure DDR2 on a given board.\n    return [dict get [boardID $gpbt] $gpbt ddr2size]\n}\n\nproc configureDDR2regs_256M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set DENALI_CTL_02_VAL 0x0100000000010100\n    set DENALI_CTL_11_VAL 0x433a32164a560a00\n\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    # 01_DATA mod [40]=1, enable BA2\n    mw64bit $DENALI_CTL_01_DATA  0x0100010100000001\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0000010100000001\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x060a020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x0000000300000206\n    mw64bit $DENALI_CTL_08_DATA  0x6400003f3f0a0209\n    mw64bit $DENALI_CTL_09_DATA  0x1a000000001a1a1a\n    mw64bit $DENALI_CTL_10_DATA  0x0120202020191a18\n    # 11_DATA mod [39-32]=16,more refresh\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000000000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x04f8000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000000002cca0000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000000000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001300c8030600\n    mw64bit $DENALI_CTL_20_DATA  0x0000000081fe00c8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c:config_board99()\n# The values are computed based on Mindspeed and Nanya datasheets\nproc configureDDR2regs_128M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n\n    set DENALI_CTL_02_VAL 0x0100010000010100\n    set DENALI_CTL_11_VAL 0x433A42124A650A37\n    # set some default values\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    mw64bit $DENALI_CTL_01_DATA  0x0100000100000101\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0201010100000201\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x050A020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x000000030E0B0205\n    mw64bit $DENALI_CTL_08_DATA  0x6427003F3F0A0209\n    mw64bit $DENALI_CTL_09_DATA  0x1A00002F00001A00\n    mw64bit $DENALI_CTL_10_DATA  0x01202020201A1A1A\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000080000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x0508000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000020472D200000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000008000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001400C8030604\n    mw64bit $DENALI_CTL_20_DATA  0x00000000823600C8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    # This is not necessary\n    #mw64bit $DENALI_CTL_11_DATA [expr {($DENALI_CTL_11_VAL  & ~0x00007F0000000000) | ($wr_dqs_shift << 40)} ]\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n\n\nproc setupUART0 {} {\n    # configure UART0 to 115200, 8N1\n    set GPIO_LOCK_REG      [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL    [regs GPIO_IOCTRL_VAL]\n    set GPIO_IOCTRL_UART0  [regs GPIO_IOCTRL_UART0]\n    set UART0_LCR\t            [regs UART0_LCR]\n    set LCR_DLAB\t\t    [regs LCR_DLAB]\n    set UART0_DLL\t\t    [regs UART0_DLL]\n    set UART0_DLH\t\t    [regs UART0_DLH]\n    set UART0_IIR\t\t    [regs UART0_IIR]\n    set UART0_IER\t\t    [regs UART0_IER]\n    set LCR_ONE_STOP\t\t    [regs LCR_ONE_STOP]\n    set LCR_CHAR_LEN_8\t\t    [regs LCR_CHAR_LEN_8]\n    set FCR_XMITRES\t\t    [regs FCR_XMITRES]\n    set FCR_RCVRRES\t\t    [regs FCR_RCVRRES]\n    set FCR_FIFOEN\t\t    [regs FCR_FIFOEN]\n    set IER_UUE\t\t\t    [regs IER_UUE]\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable UART0\n    mmw $GPIO_IOCTRL_REG $GPIO_IOCTRL_UART0 0x0\n    # baudrate  115200\n    # This should really be amba_clk/(16*115200) but amba_clk=165MHz\n    set tmp 89\n    # Enable Divisor Latch access\n    mmw  $UART0_LCR $LCR_DLAB 0x0\n    # set the divisor to $tmp\n    mww $UART0_DLL [expr {$tmp & 0xff}]\n    mww $UART0_DLH [expr {$tmp >> 8}]\n    # Disable Divisor Latch access\n    mmw  $UART0_LCR 0x0 $LCR_DLAB\n    # set the UART to 8N1\n    mmw  $UART0_LCR [expr {$LCR_ONE_STOP | $LCR_CHAR_LEN_8} ] 0x0\n    # reset FIFO\n    mmw  $UART0_IIR [expr {$FCR_XMITRES  | $FCR_RCVRRES | $FCR_FIFOEN} ] 0x0\n    #  enable FFUART\n    mww $UART0_IER $IER_UUE\n}\n\nproc putcUART0 {char} {\n\n    set UART0_LSR\t    [regs UART0_LSR]\n    set UART0_THR\t    [regs UART0_THR]\n    set LSR_TEMT\t    [regs LSR_TEMT]\n\n    # convert the 'char' to digit\n    set tmp [ scan $char %c ]\n    # /* wait for room in the tx FIFO on FFUART */\n    while {[expr {[mrw $UART0_LSR] & $LSR_TEMT}] == 0} { sleep 1 }\n    mww $UART0_THR $tmp\n    if { $char == \"\\n\" } { putcUART0 \\r }\n}\n\nproc putsUART0 {str} {\n    set index 0\n    set len [string length $str]\n    while { $index < $len } {\n\tputcUART0 [string index $str $index]\n\tset index [expr {$index + 1}]\n    }\n}\n\n\nproc trainDDR2 {} {\n    set ARAM_BASEADDR\t[regs ARAM_BASEADDR]\n\n    # you must have run 'reset init' or u-boot\n    # load the training code to ARAM\n    load_image ./images/ddr2train.bin $ARAM_BASEADDR bin\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $ARAM_BASEADDR\n    # run\n    resume\n}\n\nproc flashUBOOT {file} {\n    # this will update uboot on NOR partition\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    flash probe 0\n    echo \"Erasing sectors 0-3 for uboot\"\n    putsUART0 \"Erasing sectors 0-3 for uboot\\n\"\n    flash erase_sector 0 0 3\n    echo \"Programming u-boot\"\n    putsUART0 \"Programming u-boot...\"\n    arm11 memwrite burst enable\n    flash write_image $file $EXP_CS0_BASEADDR\n    arm11 memwrite burst disable\n    putsUART0 \"done.\\n\"\n    putsUART0 \"Rebooting, please wait!\\n\"\n    reboot\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/c100helper.tcl",
    "content": "\nproc helpC100 {} {\n    echo \"List of useful functions for C100 processor:\"\n    echo \"1)  reset init:        will set up your Telo board\"\n    echo \"2)  setupNOR:          will setup NOR access\"\n    echo \"3)  showNOR:           will show current NOR config registers for 16-bit, 16MB NOR\"\n    echo \"4)  setupGPIO:         will setup GPIOs for Telo board\"\n    echo \"5)  showGPIO:          will show current GPIO config registers\"\n    echo \"6)  highGPIO5:         will set GPIO5=NOR_addr22=1 to access upper 8MB\"\n    echo \"7)  lowGPIO5:          will set GPIO5=NOR_addr22=0 to access lower 8MB\"\n    echo \"8)  showAmbaClk:       will show current config registers for Amba Bus Clock\"\n    echo \"9)  setupAmbaClk:      will setup Amba Bus Clock=165MHz\"\n    echo \"10) showArmClk:        will show current config registers for Arm Bus Clock\"\n    echo \"11) setupArmClk:       will setup Amba Bus Clock=450MHz\"\n    echo \"12) ooma_board_detect: will show which version of Telo you have\"\n    echo \"13) setupDDR2:         will configure DDR2 controller, you must have PLLs configured\"\n    echo \"14) showDDR2:          will show DDR2 config registers\"\n    echo \"15) showWatchdog:      will show current register config for watchdog\"\n    echo \"16) reboot:            will trigger watchdog and reboot Telo (hw reset)\"\n    echo \"17) bootNOR:           will boot Telo from NOR\"\n    echo \"18) setupUART0:        will configure UART0 for 115200 8N1, PLLs have to be configured\"\n    echo \"19) putcUART0:         will print a character on UART0\"\n    echo \"20) putsUART0:         will print a string on UART0\"\n    echo \"21) trainDDR2:         will run DDR2 training program\"\n    echo \"22) flashUBOOT:        will program NOR sectors 0-3 with u-boot.bin\"\n}\n\nsource [find mem_helper.tcl]\n\n# read a 64-bit register (memory mapped)\nproc mr64bit {reg} {\n    return [read_memory $reg 32 2]\n}\n\n\n# write a 64-bit register (memory mapped)\nproc mw64bit {reg value} {\n    set high [expr {$value >> 32}]\n    set low  [expr {$value & 0xffffffff}]\n    #echo [format \"mw64bit(0x%x): 0x%08x%08x\" $reg $high $low]\n    mww $reg $low\n    mww [expr {$reg+4}] $high\n}\n\n\nproc showNOR {} {\n    echo \"This is the current NOR setup\"\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    echo [format \"EX_CSEN_REG      (0x%x): 0x%x\" $EX_CSEN_REG [mrw $EX_CSEN_REG]]\n    echo [format \"EX_CS0_SEG_REG   (0x%x): 0x%x\" $EX_CS0_SEG_REG [mrw $EX_CS0_SEG_REG]]\n    echo [format \"EX_CS0_CFG_REG   (0x%x): 0x%x\" $EX_CS0_CFG_REG [mrw $EX_CS0_CFG_REG]]\n    echo [format \"EX_CS0_TMG1_REG  (0x%x): 0x%x\" $EX_CS0_TMG1_REG [mrw $EX_CS0_TMG1_REG]]\n    echo [format \"EX_CS0_TMG2_REG  (0x%x): 0x%x\" $EX_CS0_TMG2_REG [mrw $EX_CS0_TMG2_REG]]\n    echo [format \"EX_CS0_TMG3_REG  (0x%x): 0x%x\" $EX_CS0_TMG3_REG [mrw $EX_CS0_TMG3_REG]]\n    echo [format \"EX_CLOCK_DIV_REG (0x%x): 0x%x\" $EX_CLOCK_DIV_REG [mrw $EX_CLOCK_DIV_REG]]\n    echo [format \"EX_MFSM_REG      (0x%x): 0x%x\" $EX_MFSM_REG [mrw $EX_MFSM_REG]]\n    echo [format \"EX_CSFSM_REG     (0x%x): 0x%x\" $EX_CSFSM_REG [mrw $EX_CSFSM_REG]]\n    echo [format \"EX_WRFSM_REG     (0x%x): 0x%x\" $EX_WRFSM_REG [mrw $EX_WRFSM_REG]]\n    echo [format \"EX_RDFSM_REG     (0x%x): 0x%x\" $EX_RDFSM_REG [mrw $EX_RDFSM_REG]]\n}\n\n\n\nproc showGPIO {} {\n    echo \"This is the current GPIO register setup\"\n    # GPIO outputs register\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # GPIO Output Enable register\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n    set GPIO_HI_INT_ENABLE_REG\t    [regs GPIO_HI_INT_ENABLE_REG]\n    set GPIO_LO_INT_ENABLE_REG\t    [regs GPIO_LO_INT_ENABLE_REG]\n    # GPIO input register\n    set GPIO_INPUT_REG\t\t    [regs GPIO_INPUT_REG]\n    set APB_ACCESS_WS_REG\t    [regs APB_ACCESS_WS_REG]\n    set MUX_CONF_REG\t\t    [regs MUX_CONF_REG]\n    set SYSCONF_REG\t\t    [regs SYSCONF_REG]\n    set GPIO_ARM_ID_REG\t\t    [regs GPIO_ARM_ID_REG]\n    set GPIO_BOOTSTRAP_REG\t    [regs GPIO_BOOTSTRAP_REG]\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_DEVID_REG\t\t    [regs GPIO_DEVID_REG]\n\n    echo [format \"GPIO_OUTPUT_REG       (0x%x): 0x%x\" $GPIO_OUTPUT_REG [mrw $GPIO_OUTPUT_REG]]\n    echo [format \"GPIO_OE_REG           (0x%x): 0x%x\" $GPIO_OE_REG [mrw $GPIO_OE_REG]]\n    echo [format \"GPIO_HI_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_HI_INT_ENABLE_REG [mrw $GPIO_HI_INT_ENABLE_REG]]\n    echo [format \"GPIO_LO_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_LO_INT_ENABLE_REG [mrw $GPIO_LO_INT_ENABLE_REG]]\n    echo [format \"GPIO_INPUT_REG        (0x%x): 0x%x\" $GPIO_INPUT_REG [mrw $GPIO_INPUT_REG]]\n    echo [format \"APB_ACCESS_WS_REG     (0x%x): 0x%x\" $APB_ACCESS_WS_REG [mrw $APB_ACCESS_WS_REG]]\n    echo [format \"MUX_CONF_REG          (0x%x): 0x%x\" $MUX_CONF_REG [mrw $MUX_CONF_REG]]\n    echo [format \"SYSCONF_REG           (0x%x): 0x%x\" $SYSCONF_REG [mrw $SYSCONF_REG]]\n    echo [format \"GPIO_ARM_ID_REG       (0x%x): 0x%x\" $GPIO_ARM_ID_REG [mrw $GPIO_ARM_ID_REG]]\n    echo [format \"GPIO_BOOTSTRAP_REG    (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG [mrw $GPIO_BOOTSTRAP_REG]]\n    echo [format \"GPIO_LOCK_REG         (0x%x): 0x%x\" $GPIO_LOCK_REG [mrw $GPIO_LOCK_REG]]\n    echo [format \"GPIO_IOCTRL_REG       (0x%x): 0x%x\" $GPIO_IOCTRL_REG [mrw $GPIO_IOCTRL_REG]]\n    echo [format \"GPIO_DEVID_REG        (0x%x): 0x%x\" $GPIO_DEVID_REG [mrw $GPIO_DEVID_REG]]\n}\n\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_amba_clk())\nproc showAmbaClk {} {\n    set CFG_REFCLKFREQ\t\t     [config CFG_REFCLKFREQ]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t             [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_AHB_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_AHB_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Amba PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_amba_clk())\n# this clock is useb by all peripherals (DDR2, ethernet, ebus, etc)\nproc setupAmbaClk {} {\n    set CLKCORE_PLL_STATUS           [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t    [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t    [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t    [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t    [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t    [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t    [regs DIV_BYPASS]\n    set AHBCLK_PLL_LOCK\t    [regs AHBCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t [config CFG_REFCLKFREQ]\n    set CONFIG_SYS_HZ_CLOCK      [config CONFIG_SYS_HZ_CLOCK]\n    set w    [config w_amba]\n    set x    [config x_amba]\n    set y    [config y_amba]\n\n    echo [format \"Setting Amba PLL to lock to %d MHz\" [expr {$CONFIG_SYS_HZ_CLOCK/1000000}]]\n    #echo [format \"setupAmbaClk: w= %d\" $w]\n    #echo [format \"setupAmbaClk: x= %d\" $x]\n    #echo [format \"setupAmbaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL $AHB_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_AHB_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_arm_clk())\nproc showArmClk {} {\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CLKCORE_ARM_CLK_CNTRL\t[regs CLKCORE_ARM_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t        [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_ARM_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_ARM_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Arm PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_arm_clk())\n# Arm Clock is used by two ARM1136 cores\nproc setupArmClk {} {\n    set CLKCORE_PLL_STATUS        [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_ARM_CLK_CNTRL\t  [regs CLKCORE_ARM_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t          [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t          [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t          [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t          [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t          [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t          [regs DIV_BYPASS]\n    set FCLK_PLL_LOCK\t          [regs FCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CFG_ARM_CLOCK\t\t[config CFG_ARM_CLOCK]\n    set w    [config w_arm]\n    set x    [config x_arm]\n    set y    [config y_arm]\n\n    echo [format \"Setting Arm PLL to lock to %d MHz\" [expr {$CFG_ARM_CLOCK/1000000}]]\n    #echo [format \"setupArmClk: w= %d\" $w]\n    #echo [format \"setupArmaClk: x= %d\" $x]\n    #echo [format \"setupArmaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL $ARM_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_ARM_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n\nproc setupPLL {} {\n    echo \"PLLs setup\"\n    setupAmbaClk\n    setupArmClk\n}\n\n# converted from u-boot/cpu/arm1136/bsp100.c:SoC_mem_init()\nproc setupDDR2 {} {\n    echo \"Configuring DDR2\"\n\n    set MEMORY_BASE_ADDR\t    [regs  MEMORY_BASE_ADDR]\n    set MEMORY_MAX_ADDR\t            [regs  MEMORY_MAX_ADDR]\n    set MEMORY_CR \t\t    [regs  MEMORY_CR]\n    set BLOCK_RESET_REG\t\t    [regs  BLOCK_RESET_REG]\n    set DDR_RST\t\t            [regs  DDR_RST]\n\n    # put DDR controller in reset (so that it is reset and correctly configured)\n    # this is only necessary if DDR was previously confiured\n    # and not reset.\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n\n    set M [expr {1024 * 1024}]\n    set DDR_SZ_1024M\t[expr {1024 * $M}]\n    set DDR_SZ_256M\t[expr {256 * $M}]\n    set DDR_SZ_128M\t[expr {128 * $M}]\n    set DDR_SZ_64M\t[expr {64 * $M}]\n    # ooma_board_detect returns DDR2 memory size\n    set tmp [ooma_board_detect]\n    if {$tmp == \"128M\"} {\n\techo \"DDR2 size 128MB\"\n\tset ddr_size $DDR_SZ_128M\n    } elseif {$tmp == \"256M\"} {\n\techo \"DDR2 size 256MB\"\n\tset ddr_size $DDR_SZ_256M\n    } else {\n\techo \"Don't know how to handle this DDR2 size?\"\n    }\n\n    # Memory setup register\n    mww $MEMORY_MAX_ADDR  [expr {($ddr_size - 1) + $MEMORY_BASE_ADDR}]\n    # disable ROM remap\n    mww $MEMORY_CR 0x0\n    # Take DDR controller out of reset\n    mmw $BLOCK_RESET_REG $DDR_RST 0x0\n    # min. 20 ops delay\n    sleep 1\n\n    # This will setup Denali DDR2 controller\n    if {$tmp == \"128M\"} {\n\tconfigureDDR2regs_128M\n    } elseif {$tmp == \"256M\"} {\n\tconfigureDDR2regs_256M\n    } else {\n\techo \"Don't know how to configure DDR2 setup?\"\n    }\n}\n\n\n\nproc showDDR2 {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set tmp [mr64bit $DENALI_CTL_00_DATA]\n    echo [format \"DENALI_CTL_00_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_00_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_01_DATA]\n    echo [format \"DENALI_CTL_01_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_01_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_02_DATA]\n    echo [format \"DENALI_CTL_02_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_02_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_03_DATA]\n    echo [format \"DENALI_CTL_03_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_03_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_04_DATA]\n    echo [format \"DENALI_CTL_04_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_04_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_05_DATA]\n    echo [format \"DENALI_CTL_05_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_05_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_06_DATA]\n    echo [format \"DENALI_CTL_06_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_06_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_07_DATA]\n    echo [format \"DENALI_CTL_07_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_07_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_08_DATA]\n    echo [format \"DENALI_CTL_08_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_08_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_09_DATA]\n    echo [format \"DENALI_CTL_09_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_09_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_10_DATA]\n    echo [format \"DENALI_CTL_10_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_10_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_11_DATA]\n    echo [format \"DENALI_CTL_11_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_11_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_12_DATA]\n    echo [format \"DENALI_CTL_12_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_12_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_13_DATA]\n    echo [format \"DENALI_CTL_13_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_13_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_14_DATA]\n    echo [format \"DENALI_CTL_14_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_14_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_15_DATA]\n    echo [format \"DENALI_CTL_15_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_15_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_16_DATA]\n    echo [format \"DENALI_CTL_16_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_16_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_17_DATA]\n    echo [format \"DENALI_CTL_17_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_17_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_18_DATA]\n    echo [format \"DENALI_CTL_18_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_18_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_19_DATA]\n    echo [format \"DENALI_CTL_19_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_19_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_20_DATA]\n    echo [format \"DENALI_CTL_20_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_20_DATA $tmp(1) $tmp(0)]\n\n}\n\nproc initC100 {} {\n    # this follows u-boot/cpu/arm1136/start.S\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL\t            [regs GPIO_IOCTRL_VAL]\n    set APB_ACCESS_WS_REG           [regs APB_ACCESS_WS_REG]\n    set ASA_ARAM_BASEADDR\t    [regs ASA_ARAM_BASEADDR]\n    set ASA_ARAM_TC_CR_REG\t    [regs ASA_ARAM_TC_CR_REG]\n    set ASA_EBUS_BASEADDR\t    [regs ASA_EBUS_BASEADDR]\n    set ASA_EBUS_TC_CR_REG\t    [regs ASA_EBUS_TC_CR_REG]\n    set ASA_TC_REQIDMAEN\t    [regs ASA_TC_REQIDMAEN]\n    set ASA_TC_REQTDMEN\t            [regs ASA_TC_REQTDMEN]\n    set ASA_TC_REQIPSECUSBEN        [regs ASA_TC_REQIPSECUSBEN]\n    set ASA_TC_REQARM0EN\t    [regs ASA_TC_REQARM0EN]\n    set ASA_TC_REQARM1EN\t    [regs ASA_TC_REQARM1EN]\n    set ASA_TC_REQMDMAEN\t    [regs ASA_TC_REQMDMAEN]\n    set INTC_ARM1_CONTROL_REG       [regs INTC_ARM1_CONTROL_REG]\n\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable address lines A15-A21\n    mmw $GPIO_IOCTRL_REG 0xf 0x0\n    # set ARM into supervisor mode (SVC32)\n    # disable IRQ, FIQ\n    # Do I need this in JTAG mode?\n    # it really should be done as 'and ~0x1f | 0xd3 but\n    # openocd does not support this yet\n    reg cpsr 0xd3\n    #\t/*\n    #\t * flush v4 I/D caches\n    #\t */\n    #\tmov\tr0, #0\n    #\tmcr\tp15, 0, r0, c7, c7, 0\t/* flush v3/v4 cache */\n    arm mcr 15 0 7 7 0 0x0\n    #\tmcr\tp15, 0, r0, c8, c7, 0\t/* flush v4 TLB */\n    arm mcr 15 0 8 7 0 0x0\n\n    #\t/*\n    #\t * disable MMU stuff and caches\n    #\t */\n    #\tmrc\tp15, 0, r0, c1, c0, 0\n    arm mrc 15 0 1 0 0\n    #\tbic\tr0, r0, #0x00002300\t@ clear bits 13, 9:8 (--V- --RS)\n    #\tbic\tr0, r0, #0x00000087\t@ clear bits 7, 2:0 (B--- -CAM)\n    #\torr\tr0, r0, #0x00000002\t@ set bit 2 (A) Align\n    #\torr\tr0, r0, #0x00001000\t@ set bit 12 (I) I-Cache\n    #\torr\tr0, r0, #0x00400000\t@ set bit 22 (U)\n    #\tmcr\tp15, 0, r0, c1, c0, 0\n    arm mcr 15 0 1 0 0 0x401002\n    # This is from bsp_init() in u-boot/boards/mindspeed/ooma-darwin/board.c\n    # APB init\n    #    \t// Setting APB Bus Wait states to 1, set post write\n    #\t(*(volatile u32*)(APB_ACCESS_WS_REG)) = 0x40;\n    mww $APB_ACCESS_WS_REG 0x40\n    # AHB init\n    #\t// enable all 6 masters for ARAM\n    mmw $ASA_ARAM_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n    #\t// enable all 6 masters for EBUS\n    mmw $ASA_EBUS_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n\n    # ARAM init\n    #\t// disable pipeline mode in ARAM\n    # I don't think this is documented anywhere?\n    mww $INTC_ARM1_CONTROL_REG 0x1\n    # configure clocks\n    setupPLL\n    # setupUART0 must be run before setupDDR2 as setupDDR2 uses UART.\n    setupUART0\n    # enable cache\n    # ? (u-boot does nothing here)\n    # DDR2 memory init\n    setupDDR2\n    putsUART0 \"C100 initialization complete.\\n\"\n    echo \"C100 initialization complete.\"\n}\n\n# show current state of watchdog timer\nproc showWatchdog {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    echo [format \"TIMER_WDT_HIGH_BOUND    (0x%x): 0x%x\" $TIMER_WDT_HIGH_BOUND [mrw $TIMER_WDT_HIGH_BOUND]]\n    echo [format \"TIMER_WDT_CONTROL       (0x%x): 0x%x\" $TIMER_WDT_CONTROL [mrw $TIMER_WDT_CONTROL]]\n    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/intrrupts.c:void reset_cpu (ulong ignored)\n# this will trigger watchdog reset\n# the sw. reset does not work on C100\n# watchdog reset effectively works as hw. reset\nproc reboot {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    # allow the counter to count to high value  before triggering\n    # this is because register writes are slow over JTAG and\n    # I don't want to miss the high_bound==curr_count condition\n    mww $TIMER_WDT_HIGH_BOUND  0xffffff\n    mww $TIMER_WDT_CURRENT_COUNT 0x0\n    echo \"JTAG speed lowered to 100kHz\"\n    adapter speed 100\n    mww $TIMER_WDT_CONTROL 0x1\n    # wait until the reset\n    echo -n \"Waiting for watchdog to trigger...\"\n    #while {[mrw $TIMER_WDT_CONTROL] == 1} {\n    #    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n    #    sleep 1\n    #\n    #}\n    while {[c100.cpu curstate] != \"running\"} { sleep 1}\n    echo \"done.\"\n    echo [format \"Note that C100 is in %s state, type halt to stop\" [c100.cpu curstate]]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/c100regs.tcl",
    "content": "# Note that I basically converted\n# u-boot/include/asm-arm/arch/comcerto_100.h\n# defines\n\n# this is a work-around for 'global' not working under Linux\n# access registers by calling this routine.\n# For example:\n# set EX_CS_TMG1_REG [regs EX_CS0_TMG1_REG]\nproc regs {reg} {\n    return [dict get [regsC100] $reg ]\n}\n\nproc showreg {reg} {\n    echo [format \"0x%x\" [dict get [regsC100] $reg ]]\n}\n\nproc regsC100 {} {\n#/* memcore */\n#/* device memory base addresses */\n#// device memory sizes\n#/* ARAM SIZE=64K */\ndict set regsC100 ARAM_SIZE\t\t0x00010000\ndict set regsC100 ARAM_BASEADDR\t0x0A000000\n\n#/* Hardware Interface Units */\ndict set regsC100 APB_BASEADDR\t0x10000000\n#/* APB_SIZE=16M address range */\ndict set regsC100 APB_SIZE\t\t0x01000000\n\ndict set regsC100 EXP_CS0_BASEADDR       0x20000000\ndict set regsC100 EXP_CS1_BASEADDR       0x24000000\ndict set regsC100 EXP_CS2_BASEADDR       0x28000000\ndict set regsC100 EXP_CS3_BASEADDR       0x2C000000\ndict set regsC100 EXP_CS4_BASEADDR       0x30000000\n\ndict set regsC100 DDR_BASEADDR           0x80000000\n\ndict set regsC100 TDM_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x000000}]\ndict set regsC100 PHI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x010000}]\ndict set regsC100 TDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x020000}]\ndict set regsC100 ASA_DDR_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x040000}]\ndict set regsC100 ASA_ARAM_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x048000}]\ndict set regsC100 TIMER_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x050000}]\ndict set regsC100 ASD_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x060000}]\ndict set regsC100 GPIO_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x070000}]\ndict set regsC100 UART0_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x090000}]\ndict set regsC100 UART1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x094000}]\ndict set regsC100 SPI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x098000}]\ndict set regsC100 I2C_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x09C000}]\ndict set regsC100 INTC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0A0000}]\ndict set regsC100 CLKCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 PUI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 GEMAC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0D0000}]\ndict set regsC100 IDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0E0000}]\ndict set regsC100 MEMCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0F0000}]\ndict set regsC100 ASA_EBUS_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x100000}]\ndict set regsC100 ASA_AAB_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x108000}]\ndict set regsC100 GEMAC1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x190000}]\ndict set regsC100 EBUS_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1A0000}]\ndict set regsC100 MDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1E0000}]\n\n\n#////////////////////////////////////////////////////////////\n#//\tAHB block\t\t\t\t\t\t\t\t\t\t\t    //\n#////////////////////////////////////////////////////////////\ndict set regsC100 ASA_ARAM_PRI_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_ARAM_TC_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_ARAM_TC_CR_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_ARAM_STAT_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x0C}]\n\ndict set regsC100 ASA_EBUS_PRI_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_EBUS_TC_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_EBUS_TC_CR_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_EBUS_STAT_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x0C}]\n\ndict set regsC100 IDMA_MASTER\t\t0\ndict set regsC100 TDMA_MASTER\t\t1\ndict set regsC100 USBIPSEC_MASTER\t2\ndict set regsC100 ARM0_MASTER\t\t3\ndict set regsC100 ARM1_MASTER\t\t4\ndict set regsC100 MDMA_MASTER\t\t5\n\n#define IDMA_PRIORITY(level) (level)\n#define TDM_PRIORITY(level) (level << 4)\n#define USBIPSEC_PRIORITY(level) (level << 8)\n#define ARM0_PRIORITY(level) (level << 12)\n#define ARM1_PRIORITY(level) (level << 16)\n#define MDMA_PRIORITY(level) (level << 20)\n\ndict set regsC100 ASA_TC_REQIDMAEN\t [expr {1<<18}]\ndict set regsC100 ASA_TC_REQTDMEN\t [expr {1<<19}]\ndict set regsC100 ASA_TC_REQIPSECUSBEN [expr {1<<20}]\ndict set regsC100 ASA_TC_REQARM0EN\t [expr {1<<21}]\ndict set regsC100 ASA_TC_REQARM1EN\t [expr {1<<22}]\ndict set regsC100 ASA_TC_REQMDMAEN\t [expr {1<<23}]\n\ndict set regsC100 MEMORY_BASE_ADDR\t0x80000000\ndict set regsC100 MEMORY_MAX_ADDR\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x10}]\ndict set regsC100 MEMORY_CR \t\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x14}]\ndict set regsC100 ROM_REMAP_EN\t0x1\n\n#define HAL_asb_priority(level) \\\n#*(volatile unsigned *)ASA_PRI_REG = level\n\n#define HAL_aram_priority(level) \\\n#*(volatile unsigned *)ASA_ARAM_PRI_REG = level\n\n#define HAL_aram_arbitration(arbitration_mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG |= arbitration_mask\n\n#define HAL_aram_defmaster(mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG = (*(volatile unsigned *)ASA_TC_CR_REG & 0xFFFF) | (mask << 24)\n\n#////////////////////////////////////////////////////////////\n#// INTC block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 INTC_ARM1_CONTROL_REG\t[expr {[dict get $regsC100 INTC_BASEADDR ] + 0x18}]\n\n#////////////////////////////////////////////////////////////\n#// TIMER block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 TIMER0_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x00}]\ndict set regsC100 TIMER0_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x04}]\ndict set regsC100 TIMER1_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x08}]\ndict set regsC100 TIMER1_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x0C}]\n\ndict set regsC100 TIMER2_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x18}]\ndict set regsC100 TIMER2_LBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x10}]\ndict set regsC100 TIMER2_HBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x14}]\ndict set regsC100 TIMER2_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x1C}]\n\ndict set regsC100 TIMER3_LOBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x20}]\ndict set regsC100 TIMER3_HIBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x24}]\ndict set regsC100 TIMER3_CTRL\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x28}]\ndict set regsC100 TIMER3_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x2C}]\n\ndict set regsC100 TIMER_MASK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x40}]\ndict set regsC100 TIMER_STATUS\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_ACK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_WDT_HIGH_BOUND [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD0}]\ndict set regsC100 TIMER_WDT_CONTROL\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD4}]\ndict set regsC100 TIMER_WDT_CURRENT_COUNT [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD8}]\n\n\n\n#////////////////////////////////////////////////////////////\n#//  EBUS block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 EX_SWRST_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 EX_CSEN_REG\t\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 EX_CS0_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 EX_CS1_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x0C}]\ndict set regsC100 EX_CS2_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x10}]\ndict set regsC100 EX_CS3_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x14}]\ndict set regsC100 EX_CS4_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x18}]\ndict set regsC100 EX_CS0_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x1C}]\ndict set regsC100 EX_CS1_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x20}]\ndict set regsC100 EX_CS2_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x24}]\ndict set regsC100 EX_CS3_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x28}]\ndict set regsC100 EX_CS4_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x2C}]\ndict set regsC100 EX_CS0_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x30}]\ndict set regsC100 EX_CS1_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x34}]\ndict set regsC100 EX_CS2_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x38}]\ndict set regsC100 EX_CS3_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x3C}]\ndict set regsC100 EX_CS4_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x40}]\ndict set regsC100 EX_CS0_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x44}]\ndict set regsC100 EX_CS1_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x48}]\ndict set regsC100 EX_CS2_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x4C}]\ndict set regsC100 EX_CS3_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x50}]\ndict set regsC100 EX_CS4_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x54}]\ndict set regsC100 EX_CS0_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x58}]\ndict set regsC100 EX_CS1_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x5C}]\ndict set regsC100 EX_CS2_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x60}]\ndict set regsC100 EX_CS3_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x64}]\ndict set regsC100 EX_CS4_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x68}]\ndict set regsC100 EX_CLOCK_DIV_REG\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x6C}]\n\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_CSFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x104}]\ndict set regsC100 EX_WRFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x108}]\ndict set regsC100 EX_RDFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x10C}]\n\n\ndict set regsC100 EX_CLK_EN\t\t0x00000001\ndict set regsC100 EX_CSBOOT_EN\t0x00000002\ndict set regsC100 EX_CS0_EN\t\t0x00000002\ndict set regsC100 EX_CS1_EN\t\t0x00000004\ndict set regsC100 EX_CS2_EN\t\t0x00000008\ndict set regsC100 EX_CS3_EN\t\t0x00000010\ndict set regsC100 EX_CS4_EN\t\t0x00000020\n\ndict set regsC100 EX_MEM_BUS_8\t0x00000000\ndict set regsC100 EX_MEM_BUS_16       0x00000002\ndict set regsC100 EX_MEM_BUS_32\t0x00000004\ndict set regsC100 EX_CS_HIGH\t\t0x00000008\ndict set regsC100 EX_WE_HIGH\t\t0x00000010\ndict set regsC100 EX_RE_HIGH\t\t0x00000020\ndict set regsC100 EX_ALE_MODE\t\t0x00000040\ndict set regsC100 EX_STRB_MODE\t0x00000080\ndict set regsC100 EX_DM_MODE\t\t0x00000100\ndict set regsC100 EX_NAND_MODE\t0x00000200\ndict set regsC100 EX_RDY_EN\t\t0x00000400\ndict set regsC100 EX_RDY_EDGE\t\t0x00000800\n\n#////////////////////////////////////////////////////////////\n#//  GPIO block\n#////////////////////////////////////////////////////////////\n\n# GPIO outputs register\ndict set regsC100 GPIO_OUTPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x00}]\n# GPIO Output Enable register\ndict set regsC100 GPIO_OE_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x04}]\ndict set regsC100 GPIO_HI_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x08}]\ndict set regsC100 GPIO_LO_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x0C}]\n# GPIO input register\ndict set regsC100 GPIO_INPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x10}]\ndict set regsC100 APB_ACCESS_WS_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x14}]\ndict set regsC100 MUX_CONF_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x18}]\ndict set regsC100 SYSCONF_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x1C}]\ndict set regsC100 GPIO_ARM_ID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x30}]\ndict set regsC100 GPIO_BOOTSTRAP_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x40}]\ndict set regsC100 GPIO_LOCK_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x38}]\ndict set regsC100 GPIO_IOCTRL_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x44}]\ndict set regsC100 GPIO_DEVID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x50}]\n\ndict set regsC100 GPIO_IOCTRL_A15A16\t0x00000001\ndict set regsC100 GPIO_IOCTRL_A17A18\t0x00000002\ndict set regsC100 GPIO_IOCTRL_A19A21\t0x00000004\ndict set regsC100 GPIO_IOCTRL_TMREVT0\t0x00000008\ndict set regsC100 GPIO_IOCTRL_TMREVT1\t0x00000010\ndict set regsC100 GPIO_IOCTRL_GPBT3\t0x00000020\ndict set regsC100 GPIO_IOCTRL_I2C\t0x00000040\ndict set regsC100 GPIO_IOCTRL_UART0\t0x00000080\ndict set regsC100 GPIO_IOCTRL_UART1\t0x00000100\ndict set regsC100 GPIO_IOCTRL_SPI\t0x00000200\ndict set regsC100 GPIO_IOCTRL_HBMODE\t0x00000400\n\ndict set regsC100 GPIO_IOCTRL_VAL\t0x55555555\n\ndict set regsC100 GPIO_0\t\t\t0x01\ndict set regsC100 GPIO_1\t\t\t0x02\ndict set regsC100 GPIO_2\t\t\t0x04\ndict set regsC100 GPIO_3\t\t\t0x08\ndict set regsC100 GPIO_4\t\t\t0x10\ndict set regsC100 GPIO_5\t\t\t0x20\ndict set regsC100 GPIO_6\t\t\t0x40\ndict set regsC100 GPIO_7\t\t\t0x80\n\ndict set regsC100 GPIO_RISING_EDGE\t1\ndict set regsC100 GPIO_FALLING_EDGE\t2\ndict set regsC100 GPIO_BOTH_EDGES\t3\n\n#////////////////////////////////////////////////////////////\n#// UART\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 UART0_RBR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_THR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_DLL\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_IER\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_DLH\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_IIR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_FCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_LCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x0C}]\ndict set regsC100 UART0_MCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x10}]\ndict set regsC100 UART0_LSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x14}]\ndict set regsC100 UART0_MSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x18}]\ndict set regsC100 UART0_SCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x1C}]\n\ndict set regsC100 UART1_RBR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_THR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_DLL\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_IER\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_DLH\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_IIR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_FCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_LCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x0C}]\ndict set regsC100 UART1_MCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x10}]\ndict set regsC100 UART1_LSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x14}]\ndict set regsC100 UART1_MSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x18}]\ndict set regsC100 UART1_SCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x1C}]\n\n# /* default */\ndict set regsC100 LCR_CHAR_LEN_5\t\t0x00\ndict set regsC100 LCR_CHAR_LEN_6\t\t0x01\ndict set regsC100 LCR_CHAR_LEN_7\t\t0x02\ndict set regsC100 LCR_CHAR_LEN_8\t\t0x03\n#/* One stop bit! - default */\ndict set regsC100 LCR_ONE_STOP\t\t0x00\n#/* Two stop bit! */\ndict set regsC100 LCR_TWO_STOP\t\t0x04\n#/* Parity Enable */\ndict set regsC100 LCR_PEN\t\t\t0x08\ndict set regsC100 LCR_PARITY_NONE\t\t0x00\n#/* Even Parity Select */\ndict set regsC100 LCR_EPS\t\t\t0x10\n#/* Enable Parity  Stuff */\ndict set regsC100 LCR_PS\t\t\t0x20\n#/* Start Break */\ndict set regsC100 LCR_SBRK\t\t        0x40\n#/* Parity Stuff Bit */\ndict set regsC100 LCR_PSB\t\t\t0x80\n#/* UART 16550 Divisor Latch Assess */\ndict set regsC100 LCR_DLAB\t\t        0x80\n\n#/* FIFO Error Status */\ndict set regsC100 LSR_FIFOE\t\t[expr {1 << 7}]\n#/* Transmitter Empty */\ndict set regsC100 LSR_TEMT\t\t[expr {1 << 6}]\n#/* Transmit Data Request */\ndict set regsC100 LSR_TDRQ\t\t[expr {1 << 5}]\n#/* Break Interrupt */\ndict set regsC100 LSR_BI\t\t\t[expr {1 << 4}]\n#/* Framing Error */\ndict set regsC100 LSR_FE\t\t\t[expr {1 << 3}]\n#/* Parity Error */\ndict set regsC100 LSR_PE\t\t\t[expr {1 << 2}]\n#/* Overrun Error */\ndict set regsC100 LSR_OE\t\t\t[expr {1 << 1}]\n#/* Data Ready */\ndict set regsC100 LSR_DR\t\t\t[expr {1 << 0}]\n\n#/* DMA Requests Enable */\ndict set regsC100 IER_DMAE\t\t        [expr {1 << 7}]\n#/* UART Unit Enable */\ndict set regsC100 IER_UUE\t\t\t[expr {1 << 6}]\n#/* NRZ coding Enable */\ndict set regsC100 IER_NRZE\t\t        [expr {1 << 5}]\n#/* Receiver Time Out Interrupt Enable */\ndict set regsC100 IER_RTIOE\t\t        [expr {1 << 4}]\n#/* Modem Interrupt Enable */\ndict set regsC100 IER_MIE\t\t\t[expr {1 << 3}]\n#/* Receiver Line Status Interrupt Enable */\ndict set regsC100 IER_RLSE\t\t        [expr {1 << 2}]\n#/* Transmit Data request Interrupt Enable */\ndict set regsC100 IER_TIE\t\t\t[expr {1 << 1}]\n#/* Receiver Data Available Interrupt Enable */\ndict set regsC100 IER_RAVIE\t\t        [expr {1 << 0}]\n\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES1\t\t        [expr {1 << 7}]\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES0\t\t        [expr {1 << 6}]\n#/* Time Out Detected */\ndict set regsC100 IIR_TOD\t\t\t[expr {1 << 3}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID2\t\t        [expr {1 << 2}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID1\t\t        [expr {1 << 1}]\n#/* Interrupt Pending (active low) */\ndict set regsC100 IIR_IP\t\t\t[expr {1 << 0}]\n\n#/* UART 16550 FIFO Control Register */\ndict set regsC100 FCR_FIFOEN\t\t0x01\ndict set regsC100 FCR_RCVRRES\t\t0x02\ndict set regsC100 FCR_XMITRES\t\t0x04\n\n#/* Interrupt Enable Register */\n#// UART 16550\n#// Enable Received Data Available Interrupt\ndict set regsC100 IER_RXTH\t\t0x01\n#// Enable Transmitter Empty Interrupt\ndict set regsC100 IER_TXTH\t\t0x02\n\n\n\n#////////////////////////////////////////////////////////////\n#// CLK  + RESET block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x00}]\ndict set regsC100 CLKCORE_AHB_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x04}]\ndict set regsC100 CLKCORE_PLL_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x08}]\ndict set regsC100 CLKCORE_CLKDIV_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x0C}]\ndict set regsC100 CLKCORE_TDM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x10}]\ndict set regsC100 CLKCORE_FSYNC_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x14}]\ndict set regsC100 CLKCORE_CLK_PWR_DWN\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x18}]\ndict set regsC100 CLKCORE_RNG_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x1C}]\ndict set regsC100 CLKCORE_RNG_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x20}]\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL2\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x24}]\ndict set regsC100 CLKCORE_TDM_REF_DIV_RST\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x40}]\n\ndict set regsC100 ARM_PLL_BY_CTRL\t0x80000000\ndict set regsC100 ARM_AHB_BYP\t\t0x04000000\ndict set regsC100 PLL_DISABLE\t\t0x02000000\ndict set regsC100 PLL_CLK_BYPASS\t0x01000000\n\ndict set regsC100 AHB_PLL_BY_CTRL\t0x80000000\ndict set regsC100 DIV_BYPASS\t\t0x40000000\ndict set regsC100 SYNC_MODE\t\t0x20000000\n\ndict set regsC100 EPHY_CLKDIV_BYPASS\t0x00200000\ndict set regsC100 EPHY_CLKDIV_RATIO_SHIFT\t16\ndict set regsC100 PUI_CLKDIV_BYPASS\t0x00004000\ndict set regsC100 PUI_CLKDIV_SRCCLK\t0x00002000\ndict set regsC100 PUI_CLKDIV_RATIO_SHIFT\t8\ndict set regsC100 PCI_CLKDIV_BYPASS\t0x00000020\ndict set regsC100 PCI_CLKDIV_RATIO_SHIFT\t0\n\ndict set regsC100 ARM0_CLK_PD\t\t0x00200000\ndict set regsC100 ARM1_CLK_PD\t\t0x00100000\ndict set regsC100 EPHY_CLK_PD\t\t0x00080000\ndict set regsC100 TDM_CLK_PD\t\t0x00040000\ndict set regsC100 PUI_CLK_PD\t\t0x00020000\ndict set regsC100 PCI_CLK_PD\t\t0x00010000\ndict set regsC100 MDMA_AHBCLK_PD\t0x00000400\ndict set regsC100 I2CSPI_AHBCLK_PD\t0x00000200\ndict set regsC100 UART_AHBCLK_PD\t0x00000100\ndict set regsC100 IPSEC_AHBCLK_PD\t0x00000080\ndict set regsC100 TDM_AHBCLK_PD\t0x00000040\ndict set regsC100 USB1_AHBCLK_PD\t0x00000020\ndict set regsC100 USB0_AHBCLK_PD\t0x00000010\ndict set regsC100 GEMAC1_AHBCLK_PD\t0x00000008\ndict set regsC100 GEMAC0_AHBCLK_PD\t0x00000004\ndict set regsC100 PUI_AHBCLK_PD\t0x00000002\ndict set regsC100 HIF_AHBCLK_PD\t0x00000001\n\ndict set regsC100 ARM1_DIV_BP\t\t0x00001000\ndict set regsC100 ARM1_DIV_VAL_SHIFT\t8\ndict set regsC100 ARM0_DIV_BP\t\t0x00000010\ndict set regsC100 ARM0_DIV_VAL_SHIFT\t0\n\ndict set regsC100 AHBCLK_PLL_LOCK\t0x00000002\ndict set regsC100 FCLK_PLL_LOCK\t0x00000001\n\n\n#// reset block\ndict set regsC100 BLOCK_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x100}]\ndict set regsC100 CSP_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x104}]\n\ndict set regsC100 RNG_RST\t\t0x1000\ndict set regsC100 IPSEC_RST\t\t0x0800\ndict set regsC100 DDR_RST\t\t0x0400\ndict set regsC100 USB1_PHY_RST\t0x0200\ndict set regsC100 USB0_PHY_RST\t0x0100\ndict set regsC100 USB1_RST\t\t0x0080\ndict set regsC100 USB0_RST\t\t0x0040\ndict set regsC100 GEMAC1_RST\t\t0x0020\ndict set regsC100 GEMAC0_RST\t\t0x0010\ndict set regsC100 TDM_RST\t\t0x0008\ndict set regsC100 PUI_RST\t\t0x0004\ndict set regsC100 HIF_RST\t\t0x0002\ndict set regsC100 PCI_RST\t\t0x0001\n\n#////////////////////////////////////////////////////////////////\n#//\tDDR  CONTROLLER block\n#////////////////////////////////////////////////////////////////\n\ndict set regsC100 DDR_CONFIG_BASEADDR\t0x0D000000\ndict set regsC100 DENALI_CTL_00_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x00}]\ndict set regsC100 DENALI_CTL_01_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x08}]\ndict set regsC100 DENALI_CTL_02_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x10}]\ndict set regsC100 DENALI_CTL_03_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x18}]\ndict set regsC100 DENALI_CTL_04_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x20}]\ndict set regsC100 DENALI_CTL_05_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x28}]\ndict set regsC100 DENALI_CTL_06_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x30}]\ndict set regsC100 DENALI_CTL_07_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x38}]\ndict set regsC100 DENALI_CTL_08_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x40}]\ndict set regsC100 DENALI_CTL_09_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x48}]\ndict set regsC100 DENALI_CTL_10_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x50}]\ndict set regsC100 DENALI_CTL_11_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x58}]\ndict set regsC100 DENALI_CTL_12_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x60}]\ndict set regsC100 DENALI_CTL_13_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x68}]\ndict set regsC100 DENALI_CTL_14_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x70}]\ndict set regsC100 DENALI_CTL_15_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x78}]\ndict set regsC100 DENALI_CTL_16_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x80}]\ndict set regsC100 DENALI_CTL_17_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x88}]\ndict set regsC100 DENALI_CTL_18_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x90}]\ndict set regsC100 DENALI_CTL_19_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x98}]\ndict set regsC100 DENALI_CTL_20_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0xA0}]\n\n# 32-bit value\ndict set regsC100 DENALI_READY_CHECK         [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x44}]\n# 8-bit\ndict set regsC100 DENALI_WR_DQS              [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5D}]\n# 8-bit\ndict set regsC100 DENALI_DQS_OUT             [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5A}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY0          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x4F}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY1          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x50}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY2          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x51}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY3          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x52}]\n\n\n# end of proc regsC100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/cc2538.cfg",
    "content": "# Config for Texas Instruments low power RF SoC CC2538\n# http://www.ti.com/lit/pdf/swru319\n\nadapter speed 100\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc2538\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n# A start sequence is needed to change from cJTAG (Compact JTAG) to\n# 4-pin JTAG before talking via JTAG commands\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/cs351x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME cs351x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00526fa1\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# There is 16K of SRAM on this chip\n# FIXME: flash programming is not working by using this work area. So comment this out for now.\n#$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/davinci.cfg",
    "content": "#\n# Utility code for DaVinci-family chips\n#\n\n# davinci_pinmux: assigns PINMUX$reg <== $value\nproc davinci_pinmux {soc reg value} {\n\tmww [expr {[dict get $soc sysbase] + 4 * $reg}] $value\n}\n\nsource [find mem_helper.tcl]\n\n#\n# pll_setup: initialize PLL\n#  - pll_addr ... physical addr of controller\n#  - mult ... pll multiplier\n#  - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers\n#\n# For PLLs that don't have a given register (e.g. plldiv8), or where a\n# given divider is non-programmable, caller provides *NO* config mapping.\n#\n\n# PLL version 0x02: tested on dm355\n# REVISIT: On dm6446/dm357 the PLLRST polarity is different.\nproc pll_v02_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - clear CLKMODE (bit 8) iff using on-chip oscillator\n\t# NOTE: this assumes we should clear that bit\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0100}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 4 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 5 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 6 - set PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 7 - clear PLLPWRDN (bit 1)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 8 - clear PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\t# NOTE: for dm355 PLL1, postdiv is controlled via MISC register\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult - 1) & 0xff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - optional: set plldiv1, plldiv2, ...\n\t# NOTE:  this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\t#\t- ALNCTL has everything set\n\tset go 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset go 1\n\t}\n\tif {$go != 0} {\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\n\t# 11 - wait at least 5 usec for reset to finish\n\t# (assume covered by overheads including JTAG messaging)\n\n\t# 12 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 13 - wait at least 8000 refclk cycles for PLL to lock\n\t# if we assume 24 MHz (slowest osc), that's 1/3 msec\n\tsleep 3\n\n\t# 14 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# PLL version 0x03: tested on dm365\nproc pll_v03_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_secctrl_addr [expr {$pll_addr + 0x108}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - power up the PLL\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 4 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 5 - wait at least 5 usec\n\tsleep 1\n\n\t# 6 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult / 2) & 0x1ff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - write start sequence to PLLSECCTL\n\tmww $pll_secctrl_addr 0x00470000\n\tmww $pll_secctrl_addr 0x00460000\n\tmww $pll_secctrl_addr 0x00400000\n\tmww $pll_secctrl_addr 0x00410000\n\n\t# 11 - optional: set plldiv1, plldiv2, ...\n\t# NOTE: this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\tset aln 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset aln [expr {$aln | 0x1}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0118}] 0\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset aln [expr {$aln | 0x2}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x011c}] 0\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset aln [expr {$aln | 0x4}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0120}] 0\n\t}\n\tif { [dict exists $config oscdiv] } {\n\t\tset div [dict get $config oscdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0124}] $div\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0124}] 0\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset aln [expr {$aln | 0x8}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0160}] 0\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset aln [expr {$aln | 0x10}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0164}] 0\n\t}\n\tif { [dict exists $config div6] } {\n\t\tset div [dict get $config div6]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0168}] $div\n\t\tset aln [expr {$aln | 0x20}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0168}] 0\n\t}\n\tif { [dict exists $config div7] } {\n\t\tset div [dict get $config div7]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x016c}] $div\n\t\tset aln [expr {$aln | 0x40}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x016c}] 0\n\t}\n\tif { [dict exists $config div8] } {\n\t\tset div [dict get $config div8]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0170}] $div\n\t\tset aln [expr {$aln | 0x80}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0170}] 0\n\t}\n\tif { [dict exists $config div9] } {\n\t\tset div [dict get $config div9]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0174}] $div\n\t\tset aln [expr {$aln | 0x100}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0174}] 0\n\t}\n\tif {$aln != 0} {\n\t\t# clear pllcmd.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x00\n\t\t# write alignment flags\n\t\tmww [expr {$pll_addr + 0x0140}] $aln\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\tset addr [dict get $config ctladdr]\n\twhile {[expr {[mrw $addr] & 0x0e000000}] != 0x0e000000} { sleep 1 }\n\n\t# 12 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain\n# modules can be enabled.\n\n# prepare a non-DSP module to be enabled; finish with psc_go\nproc psc_enable {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x03 0x1f\n}\n\n# prepare a non-DSP module to be reset; finish with psc_go\nproc psc_reset {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x01 0x1f\n}\n\n# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc\nproc psc_go {} {\n\tset psc_addr 0x01c41000\n\tset ptstat_addr [expr {$psc_addr + 0x0128}]\n\n\t# just in case PTSTAT.go isn't clear\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n\n\t# write PTCMD.go ... ignoring any DSP power domain\n\tmww [expr {$psc_addr + 0x0120}] 1\n\n\t# wait for PTSTAT.go to clear (again ignoring DSP power domain)\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n}\n\n#\n# A reset using only SRST is a \"Warm Reset\", resetting everything in the\n# chip except ARM emulation (and everything _outside_ the chip that hooks\n# up to SRST).  But many boards don't expose SRST via their JTAG connectors\n# (it's not present on TI-14 headers).\n#\n# From the chip-only perspective, a \"Max Reset\" is a \"Warm\" reset ... except\n# without any board-wide side effects, since it's triggered using JTAG using\n# either (a) ARM watchdog timer, or (b) ICEpick.\n#\nproc davinci_wdog_reset {} {\n\tset timer2_phys 0x01c21c00\n\n\t# NOTE -- on entry\n\t#   - JTAG communication with the ARM *must* be working OK; this\n\t#     may imply using adaptive clocking or disabling WFI-in-idle\n\t#   - current target must be the DaVinci ARM\n\t#   - that ARM core must be halted\n\t#   - timer2 clock is still enabled (PSC 29 on most chips)\n\n\t#\n\t# Part I -- run regardless of being halted via JTAG\n\t#\n\t# NOTE:  for now, we assume there's no DSP that could control the\n\t# watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog\n\t# suspend signal is controlled via ARM emulation suspend.\n\t#\n\n\t# EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n\n\t#\n\t# Part II -- in case watchdog hasn't been set up\n\t#\n\n\t# TCR: disable, force internal clock source\n\tmww phys [expr {$timer2_phys + 0x20}] 0\n\n\t# TGCR: reset, force to 64-bit wdog mode, un-reset (\"initial\" state)\n\tmww phys [expr {$timer2_phys + 0x24}] 0\n\tmww phys [expr {$timer2_phys + 0x24}] 0x110b\n\n\t# clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers\n\t# so watchdog triggers ASAP\n\tmww phys [expr {$timer2_phys + 0x10}] 0\n\tmww phys [expr {$timer2_phys + 0x14}] 0\n\tmww phys [expr {$timer2_phys + 0x18}] 0\n\tmww phys [expr {$timer2_phys + 0x1c}] 0\n\n\t# WDTCR: put into pre-active state, then active\n\tmww phys [expr {$timer2_phys + 0x28}] 0xa5c64000\n\tmww phys [expr {$timer2_phys + 0x28}] 0xda7e4000\n\n\t#\n\t# Part III -- it's ready to rumble\n\t#\n\n\t# WDTCR: write invalid WDKEY to trigger reset\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/dragonite.cfg",
    "content": "######################################\n# Target:    Marvell Dragonite CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dragonite\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x121003d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/dsp56321.cfg",
    "content": "# Script for freescale DSP56321\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp56321\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1181501d\n}\n\n#jtag speed\nadapter speed 4500\n\n#has only srst\nreset_config srst_only\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/dsp568013.cfg",
    "content": "# Script for freescale DSP568013\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568013\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2401d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\n# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations require certain instruction to be in the IR register during reset, and polling would change this)\njtag configure $_CHIPNAME.chp -event setup \"\n     jtag tapenable $_TARGETNAME\n     poll off\n\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/dsp568037.cfg",
    "content": "# Script for freescale DSP568037\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568037\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2801d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\njtag configure $_CHIPNAME.chp -event setup \"jtag tapenable $_TARGETNAME\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/efm32.cfg",
    "content": "#\n# Silicon Labs (formerly Energy Micro) EFM32 target\n#\n# Note: All EFM32 chips have SWD support, but only newer series 1\n# chips have JTAG support.\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME efm32\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nadapter speed 1000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\nflash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\nflash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/em357.cfg",
    "content": "#\n# Target configuration for the Silicon Labs EM357 chips\n#\n\n#\n# em357 family supports JTAG and SWD transports\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em357\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } else {\n      set _CPUTAPID 0x1ba00477\n   }\n}\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n  set _BSTAPID 0x069a962b\n}\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em358\n}\n\nif { [info exists FLASHSIZE] } {\n    set _FLASHSIZE $FLASHSIZE\n} else {\n    set _FLASHSIZE 0x30000\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nif { [using_jtag] } {\n    jtag newtap $_CHIPNAME bs -irlen 4 -expected-id $_BSTAPID -ircapture 0xe -irmask 0xf\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME em357 0x08000000 $_FLASHSIZE 0 0 $_TARGETNAME\n\nif { ![using_hla]} {\n# according to errata, we need to use vectreset rather than sysresetreq to avoid lockup\n# There is a bug in the chip, which means that when using external debuggers the chip\n# may lock up in certain CPU clock modes. Affected modes are operating the CPU at\n# 24MHz derived from the 24MHz crystal, or 12MHz derived from the high frequency RC\n# oscillator. If an external debugger tool asserts SYSRESETREQ, the chip will lock up and\n# require a pin reset or power cycle.\n#\n# for details, refer to:\n# http://www.silabs.com/Support%20Documents/TechnicalDocs/EM35x-Errata.pdf\n    cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/em358.cfg",
    "content": "# Target configuration for the Silicon Labs EM358 chips\n\n#\n# em357 family supports JTAG and SWD transports\n#\n\nif { ![info exists CHIPNAME] } {\n   set CHIPNAME em358\n}\n\nif { ![info exists BSTAPID] } {\n  set BSTAPID 0x069aa62b\n}\n\n# 512K of flash in the em358 chips\nset FLASHSIZE 0x80000\nsource [find target/em357.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/eos_s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3\n# https://www.quicklogic.com/products/soc/eos-s3-microcontroller/\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME eos_s3\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x80000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# For now we use SRAM only for software upload\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 4000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/epc9301.cfg",
    "content": "# Cirrus Logic EP9301 processor on an Olimex CS-E9301 board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ep9301\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nadapter srst delay 100\njtag_ntrst_delay 100\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -work-area-phys 0x80014000 -work-area-size 0x1000 -work-area-backup 1\n\n#flash configuration\n#flash bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x60000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/esi32xx.cfg",
    "content": "#\n# EnSilica eSi-32xx SoC (eSi-RISC Family)\n# http://www.ensilica.com/risc-ip/\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME esi32xx\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x11234001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME esirisc -chain-position $_CHIPNAME.cpu\n\n# Targets with the UNIFIED_ADDRESS_SPACE option disabled should set\n# CACHEARCH to 'harvard'. By default, 'von_neumann' is assumed.\nif { [info exists CACHEARCH] } {\n    $_TARGETNAME esirisc cache_arch $CACHEARCH\n}\n\nadapter speed 2000\n\nreset_config none\n\n# The default linker scripts provided by the eSi-RISC toolchain do not\n# specify attributes on memory regions, which results in incorrect\n# application of software breakpoints by GDB.\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/esp32s2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The ESP32-S2 only supports JTAG.\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME esp32s2\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x120034e5\n}\n\nset _TARGETNAME $_CHIPNAME\nset _CPUNAME cpu\nset _TAPNAME $_CHIPNAME.$_CPUNAME\n\njtag newtap $_CHIPNAME $_CPUNAME -irlen 5 -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME esp32s2 -endian little -chain-position $_TAPNAME\n\nxtensa maskisr on\n\n$_TARGETNAME configure -event reset-assert-post { soft_reset_halt }\n\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/exynos5250.cfg",
    "content": "#\n# Samsung Exynos 5250 - dual-core ARM Cortex-A15\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME exynos5250\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap\n\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/faux.cfg",
    "content": "#Script for faux target - used for testing\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00000000\n}\n\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#dummy flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME faux 0x01000000 0x200000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/feroceon.cfg",
    "content": "######################################\n# Target:    Marvell Feroceon CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME feroceon\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x20a023d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/fm3.cfg",
    "content": "# MB9BF506\n# Fujitsu Cortex-M3 with 512kB Flash and 64kB RAM\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME mb9bfxx6\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\n# delays on reset lines\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\n# Fujitsu Cortex-M3 reset configuration\nreset_config trst_only\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# MB9BF506 has 64kB of SRAM on its main system bus\n$_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0\n\n# MB9BF506 has 512kB internal FLASH\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n# 4MHz / 6 = 666kHz, so use 500\nadapter speed 500\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/fm4.cfg",
    "content": "#\n# Spansion FM4 (ARM Cortex-M4)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME fm4\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} elseif { [using_jtag] } {\n\tset _CPU_TAPID 0x4ba00477\n} else {\n\tset _CPU_TAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nadapter speed 500\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/fm4_mb9bf.cfg",
    "content": "#\n# Spansion FM4 MB9BFxxx (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# MB9BF566 M/N/R have 32 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x8000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/fm4_s6e2cc.cfg",
    "content": "#\n# Spansion FM4 S6E2CC (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# S6E2CC8 H/J/L have 96 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x18000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\nflash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/gd32e23x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for GigaDevice gd32e23x Cortex-M23 Series\n\n# https://www.gigadevice.com/microcontroller/gd32e230c8t6/\n\n#\n# gd32e23x devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32e23x\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some GD32E230s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # this is the SW-DP tap id not the jtag tap id\n   set _CPUTAPID 0x0bf11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# SWD speed (may be updated to higher value in board config file)\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Debug clock enable\n\t# RCU_APB2EN |= DBGMCUEN\n\tmmw 0x40021018 0x00400000 0\n\n\t# Stop watchdog counters during halt\n\t# DBG_CTL0 |= WWDGT_HOLD | FWDGT_HOLD | STB_HOLD | DSLP_HOLD | SLP_HOLD\n\tmmw 0x40015804 0x00000307 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/gd32vf103.cfg",
    "content": "#\n# GigaDevice GD32VF103 target\n#\n# https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/\n#\n\nsource [find mem_helper.tcl]\n\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32vf103\n}\n\n# The smallest RAM size 6kB (GD32VF103C4/T4/R4)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1800\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME\n\n# DBGMCU_CR register cannot be set in examine-end event as the running RISC-V CPU\n# does not allow the debugger to access memory.\n# Stop watchdogs at least before flash programming.\n$_TARGETNAME configure -event reset-init {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP\n\tmmw 0xE0042004 0x00000300 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/gp326xxxa.cfg",
    "content": "#\n# Support for General Plus GP326XXXA chips\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gp326xxxa\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Use internal SRAM as a work area\n$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0\n\n# The chip has both lines connected together\nreset_config trst_and_srst srst_pulls_trst\n# This delay is needed otherwise communication with the target would\n# be unreliable\nadapter srst delay 100\n\n# Set the adapter speed ridiculously low just in case we are\n# running off of a 32kHz clock\nadapter speed 2\n\nproc gp32xxxa_halt_and_reset_control_registers {} {\n\t# System control registers\n\tset P_SYSTEM_CTRL_NEW       0xD0000008\n\tset P_SYSTEM_CTRL           0xD000000C\n\tset P_SYSTEM_CLK_EN0        0xD0000010\n\tset P_SYSTEM_CLK_EN1        0xD0000014\n\tset P_SYSTEM_RESET_FLAG     0xD0000018\n\tset P_SYSTEM_CLK_CTRL       0xD000001C\n\tset P_SYSTEM_LVR_CTRL       0xD0000020\n\tset P_SYSTEM_WATCHDOG_CTRL  0xD0000024\n\tset P_SYSTEM_PLLEN          0xD000005C\n\n\t# Since we can't use SRST without pulling TRST\n\t# we can't assume the state of the clock configuration\n\t# or watchdog settings. So reset them before porceeding\n\n\t# Set the adapter speed ridiculously low just in case we are\n\t# running off of a 32kHz clock\n\tadapter speed 2\n\n\t# Disable any advanced features at this stage\n\tarm7_9 dcc_downloads disable\n\tarm7_9 fast_memory_access disable\n\n\t# Do a \"soft reset\"\n\tsoft_reset_halt\n\t# Reset all system control registers to their default \"after-reset\" values\n\tmwh $P_SYSTEM_WATCHDOG_CTRL  0x0000\n\tmwh $P_SYSTEM_LVR_CTRL       0x0000\n\n\tmwh $P_SYSTEM_CTRL_NEW       0x0001\n\tmwh $P_SYSTEM_CTRL           0x0001\n\t# Clear all reset flags by writing 1's\n\tmwh $P_SYSTEM_RESET_FLAG     0x001C\n\n\tmwh $P_SYSTEM_CLK_CTRL       0x8000\n\tmwh $P_SYSTEM_CLK_EN0        0xFFFF\n\tmwh $P_SYSTEM_CLK_EN1        0xFFFF\n\tmwh $P_SYSTEM_PLLEN          0x0010\n\n\t# Unfortunately there's no register that would allow us to\n\t# know if PLL is locked. So just wait for 100ms in hopes that\n\t# it would be enough.\n\tsleep 100\n\n\t# Now that we know that we are running at 48Mhz\n\t# Increase JTAG speed and enable speed optimization features\n\tadapter speed 5000\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/hi3798.cfg",
    "content": "# Hisilicon Hi3798 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi3798\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80020000\nset $_TARGETNAME.cti(1) 0x80120000\nset $_TARGETNAME.cti(2) 0x80220000\nset $_TARGETNAME.cti(3) 0x80320000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        #set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/hi6220.cfg",
    "content": "# Hisilicon Hi6220 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi6220\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n# declare the 8 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80198000\nset $_TARGETNAME.cti(1) 0x80199000\nset $_TARGETNAME.cti(2) 0x8019A000\nset $_TARGETNAME.cti(3) 0x8019B000\nset $_TARGETNAME.cti(4) 0x801D8000\nset $_TARGETNAME.cti(5) 0x801D9000\nset $_TARGETNAME.cti(6) 0x801DA000\nset $_TARGETNAME.cti(7) 0x801DB000\n\nset _cores 8\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ncti create cti.sys -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0x80003000\n\n# declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\n# declare the auxiliary Cortex-A7 core\ntarget create ${_TARGETNAME}.a7 cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80210000 -defer-examine\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/hilscher_netx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 10 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx10\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/hilscher_netx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 50 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx50\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# On netX50 SDRAM is not accessible at offset 0xDEAD0-0xDEADF as it is busy from\n# DMA controller at init. This function will setup a dummy DMA to free this ares\n# and must be called before using SDRAM\nproc sdram_fix { } {\n\n  mww 0x1c005830 0x00000001\n\n  mww 0x1c005104 0xBFFFFFFC\n  mww 0x1c00510c 0x00480001\n  mww 0x1c005110 0x00000001\n\n  sleep 100\n\n  mww 0x1c00510c 0\n  mww 0x1c005110 0\n  mww 0x1c005830 0x00000000\n\n\tputs \"SDRAM Fix executed!\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/hilscher_netx500.cfg",
    "content": "#Hilscher netX 500 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx500\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\n# This function must be called on netX100/500 right after halt\n# If it is called later the needed register cannot be written anymore\nproc sdram_fix { } {\n\n  set accesskey [mread32 0x00100070]\n  mww 0x00100070 $accesskey\n  mww 0x0010002c 0x00000001\n\n  if {[expr {[mread32 0x0010002c] & 0x07}] == 0x07} {\n\t puts \"SDRAM Fix was not executed. Probably your CPU halted too late and the register is already locked!\"\n  } else {\n\t puts \"SDRAM Fix succeeded!\"\n  }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/icepick.cfg",
    "content": "#\n# Copyright (C)   2011        by Karl Kurbjun\n# Copyright (C)   2009        by David Brownell\n#\n\n# Utilities for TI ICEpick-C/D used in most TI SoCs\n# Details about the ICEPick are available in the the TRM for each SoC\n# and http://processors.wiki.ti.com/index.php/ICEPICK\n\n# create \"constants\"\nproc CONST { key } {\n\n\tarray set constant {\n\t\t# define ICEPick instructions\n\t\tIR_BYPASS   0x00\n\t\tIR_ROUTER   0x02\n\t\tIR_CONNECT  0x07\n\t\tIF_BYPASS   0x3F\n\t}\n\treturn $constant($key)\n}\n\n# Instruction to connect to the icepick module\nproc icepick_c_connect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x89 -endstate DRPAUSE\n}\n\n# Instruction to disconnect to the icepick module\nproc icepick_c_disconnect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x86 -endstate DRPAUSE\n}\n\n#\n# icepick_c_router:\n#  this function is for sending router commands\n# arguments are:\n#  jrc:        TAP name for the ICEpick\n#  rw:         read/write (0 for read, 1 for write)\n#  block:      icepick or DAP\n#  register:   which register to read/write\n#  payload:    value to read/write\n# this function is for sending router commands\n#\nproc icepick_c_router {jrc rw block register payload} {\n\n\tset new_dr_value \\\n\t\t[expr { ( ($rw & 0x1) << 31)        | ( ($block & 0x7) << 28) | \\\n\t\t\t\t( ($register & 0xF) << 24)  | ( $payload & 0xFFFFFF ) } ]\n\n#\techo \"\\tNew router value:\\t0x[format %x $new_dr_value]\"\n\n\t# select router\n\tirscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE\n\n\t# ROUTER instructions are 32 bits wide\n\tset old_dr_value 0x[drscan $jrc 32 $new_dr_value -endstate DRPAUSE]\n#\techo \"\\tOld router value:\\t0x[format %x $old_dr_value]\"\n}\n\n# Configure the icepick control register\nproc icepick_c_setup {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x001000\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15 for debug tap, 16..31 for test tap\nproc icepick_c_tapenable {jrc port} {\n\n\tif { ($port >= 0) && ($port < 16) } {\n\t\t# Debug tap\"\n\t\tset tap $port\n\t\tset block 0x2\n\t} elseif { $port < 32 } {\n\t\t# Test tap\n\t\tset tap [expr {$port - 16}]\n\t\tset block 0x1\n\t} else {\n\t\techo \"ERROR: Invalid ICEPick C port number: $port\"\n\t\treturn\n\t}\n\n\t# First CONNECT to the ICEPick\n#\techo \"Connecting to ICEPick\"\n\ticepick_c_connect $jrc\n\n#\techo \"Configuring the ICEpick\"\n\ticepick_c_setup $jrc\n\n\t# NOTE: it's important not to enter RUN/IDLE state until\n\t# done sending these instructions and data to the ICEpick.\n\t# And never to enter RESET, which will disable the TAPs.\n\n\t# first enable power and clock for TAP\n\ticepick_c_router $jrc 1 $block $tap 0x110048\n\n\t# TRM states that the register should be read back here, skipped for now\n\n\t# enable debug \"default\" mode\n\ticepick_c_router $jrc 1 $block $tap 0x112048\n\n\t# TRM states that debug enable and debug mode should be read back and\n\t# confirmed - skipped for now\n\n\t# Finally select the tap\n\ticepick_c_router $jrc 1 $block $tap 0x112148\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# jrc\t== TAP name for the ICEpick\n# coreid== core id number 0..15 (not same as port number!)\nproc icepick_d_set_core_control {jrc coreid value } {\n\ticepick_c_router $jrc 1 0x6 $coreid $value\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15\n# Follow the sequence described in\n# http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf\nproc icepick_d_tapenable {jrc port coreid { value 0x2008 } } {\n\n\t# First CONNECT to the ICEPick\n\ticepick_c_connect $jrc\n\ticepick_c_setup $jrc\n\n\t# Select the port\n\ticepick_c_router $jrc 1 0x2 $port 0x2108\n\n\t# Set icepick core control for $coreid\n\ticepick_d_set_core_control $jrc $coreid $value\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# This function uses the ICEPick to send a warm system reset\nproc icepick_c_wreset {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x002101\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx.cfg",
    "content": "# utility fn's for Freescale i.MX series\n\nglobal TARGETNAME\nset TARGETNAME $_TARGETNAME\n\n# rewrite commands of the form below to arm11 mcr...\n#\tData.Set c15:0x042f %long 0x40000015\nproc setc15 {regs value} {\n\tglobal TARGETNAME\n\n\techo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n\tarm mcr 15 [expr {($regs>>12)&0x7}] [expr {($regs>>0)&0xf}] [expr {($regs>>4)&0xf}] [expr {($regs>>8)&0x7}] $value\n}\n\n\nproc imx3x_reset {} {\n\t# this reset script comes from the Freescale PDK\n\t#\n\t# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX35PDK\n\n\techo \"Target Setup: initialize DRAM controller and peripherals\"\n\n#\tData.Set c15:0x01 %long 0x00050078\n\tsetc15 0x01 0x00050078\n\n\techo \"configuring CP15 for enabling the peripheral bus\"\n#\tData.Set c15:0x042f %long 0x40000015\n\tsetc15 0x042f 0x40000015\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx21.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\n#\n# Hmmm.... should srst_pulls_trst be used here like i.MX27???\nreset_config trst_and_srst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx21\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0792611f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx25.cfg",
    "content": "#\n# imx25 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx25\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0x0f -expected-id $_ETBTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0x0 -irmask 0x0 -expected-id 0x0\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882301d\n}\njtag newtap $_CHIPNAME sdma -irlen 5 -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t\t-chain-position $_TARGETNAME\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx27.cfg",
    "content": "# page 3-34 of \"MCIMC27 Multimedia Applications Processor Reference Manual, Rev 0.3\"\n# SRST pulls TRST\n#\n# Without setting these options correctly you'll see all sorts\n# of weird errors, e.g. MOE=0xe, invalid cpsr values, reset\n# failing, etc.\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx27\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there are 2 taps\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926121\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n# REVISIT what operating environment sets up this virtual address mapping?\n$_TARGETNAME configure -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \\\n\t-work-area-size 0x8000 -work-area-backup 1\n# Internal to the chip, there is 45K of SRAM\n#\n\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx28.cfg",
    "content": "# i.MX28 config file.\n# based off of the imx21.cfg file.\n\nreset_config trst_and_srst\n\n#jtag nTRST and nSRST delay\nadapter srst delay 100\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx28\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x079264f3\n}\njtag newtap $_CHIPNAME cpu  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx31.cfg",
    "content": "# imx31 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\n\nadapter srst delay 5\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx31\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x2190101d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The \"SDMA\" - <S>mart <DMA> controller debug tap\n# Based on some IO pins - this can be disabled & removed\n# See diagram: 6-14\n#   SIGNAL NAME:\n#    SJC_MOD - controls multiplexer - disables ARM1136\n#    SDMA_BYPASS - disables SDMA    -\n#\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0xf -expected-id 0x0\n\n# Per section 40.17.1, table 40-85 the IR register is 4 bits\n# But this conflicts with Diagram 6-13, \"3bits ir and drs\"\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx35.cfg",
    "content": "# imx35 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx35\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882601d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0x0 -expected-id 0x0\n\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx51.cfg",
    "content": "# Freescale i.MX51\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx51\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190c01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx51_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx51_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx53.cfg",
    "content": "# Freescale i.MX53\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx53\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190d01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx53_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx53_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx6.cfg",
    "content": "#\n# Freescale i.MX6 series\n#\n# Supports 6Q 6D 6QP 6DP 6DL 6S 6SL 6SLL\n#\n# Some imx6 chips have Cortex-A7 or an Cortex-M and need special handling\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx6\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\n\n# List supported SJC TAPIDs from imx reference manuals:\nset _SJC_TAPID_6Q   0x0191c01d\nset _SJC_TAPID_6D   0x0191e01d\nset _SJC_TAPID_6QP  0x3191c01d\nset _SJC_TAPID_6DP  0x3191d01d\nset _SJC_TAPID_6DL  0x0891a01d\nset _SJC_TAPID_6S   0x0891b01d\nset _SJC_TAPID_6SL  0x0891f01d\nset _SJC_TAPID_6SLL 0x088c201d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6Q\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6QP \\\n        -expected-id $_SJC_TAPID_6DP \\\n        -expected-id $_SJC_TAPID_6D \\\n        -expected-id $_SJC_TAPID_6DL \\\n        -expected-id $_SJC_TAPID_6S \\\n        -expected-id $_SJC_TAPID_6SL \\\n        -expected-id $_SJC_TAPID_6SLL\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x82150000\n# core 1  -  0x82152000\n# core 2  -  0x82154000\n# core 3  -  0x82156000\nset _TARGETNAME $_CHIPNAME.cpu.0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x82150000\n\n# some TCK cycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx6_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n\n# Slow speed to be sure it will work\nadapter speed 1000\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n$_TARGETNAME configure -event reset-assert-post \"imx6_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx6sx.cfg",
    "content": "#\n# Freescale i.MX6SoloX\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6sx\n}\n\n# 2x CoreSight Debug Access Port for Cortex-M4 and Cortex-A9\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu_m4 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_m4 -chain-position $_CHIPNAME.cpu_m4\n\njtag newtap $_CHIPNAME cpu_a9 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_a9 -chain-position $_CHIPNAME.cpu_a9\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID 0x0891c01d\n}\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# Cortex-A9 (boot core)\ntarget create $_CHIPNAME.cpu_a9 cortex_a -dap $_CHIPNAME.dap_a9 \\\n        -coreid 0 -dbgbase 0x82150000\n\n# Cortex-M4 (default off)\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap_m4 \\\n        -ap-num 0 -defer-examine\n\n# AHB mem-ap target\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap_a9 -ap-num 0\n\n# Default target is Cortex-A9\ntargets $_CHIPNAME.cpu_a9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx6ul.cfg",
    "content": "#\n# Freescale i.MX6UltraLite series: 6UL 6ULL 6ULZ\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6ul\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nset _SJC_TAPID_6UL  0x0891d01d\nset _SJC_TAPID_6ULL 0x0891e01d\nset _SJC_TAPID_6ULZ 0x1891e01d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6UL\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6ULL \\\n        -expected-id $_SJC_TAPID_6ULZ \\\n\n# Create DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Main AHB bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Cortex-A7 single core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x82130000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx7.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx7\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n#\n# Cortex-A7 target\n#\n# GDB target: Cortex-A7, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80070000\n# core 1  -  0x80072000\nset _TARGETNAME $_CHIPNAME.cpu_a7\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80070000\n\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 1 -dbgbase 0x80072000 -defer-examine\n#\n# Cortex-M4 target\n#\nset _TARGETNAME_2 $_CHIPNAME.cpu_m4\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.dap -ap-num 4 \\\n        -defer-examine\n\n#\n# AHB mem-ap target\n#\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx7ulp.cfg",
    "content": "#\n# NXP i.MX7ULP: Cortex-A7 + Cortex-M4\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx7ulp\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x188e101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-A7\ntarget create $_CHIPNAME.cpu_a7 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80030000\n\n# Cortex-M4\n# Boots by default so don't defer examination\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap -ap-num 3\n\n# AHB main soc bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Default is Cortex-A7\ntargets $_CHIPNAME.cpu_a7\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx8m.cfg",
    "content": "#\n# configuration file for NXP i.MX8M family of SoCs\n#\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8m\n}\n\nif { [info exists CHIPCORES] } {\n    set _cores $CHIPCORES\n} else {\n    set _cores 1\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# the DAP tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M4 core on AP #4\ntarget create ${_CHIPNAME}.m4 cortex_m -dap ${_CHIPNAME}.dap -ap-num 4 \\\n               -defer-examine\n\n# AHB-AP for direct access to soc bus\ntarget create ${_CHIPNAME}.ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# default target is A53 core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/imx8qm.cfg",
    "content": "#\n# NXP i.MX8QuadMax\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8qm\n}\n\n# CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x1890101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# AXI: Main SOC bus on AP #0\ntarget create ${_CHIPNAME}.axi mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# 4x Cortex-A53 on AP #6\nset _A53_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _A53_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\ncti create $_CHIPNAME.a53_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 0]\ncti create $_CHIPNAME.a53_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 1]\ncti create $_CHIPNAME.a53_cti.2 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 2]\ncti create $_CHIPNAME.a53_cti.3 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 3]\ntarget create $_CHIPNAME.a53.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.0 -dbgbase [lindex $_A53_DBGBASE 0]\ntarget create $_CHIPNAME.a53.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.1 -dbgbase [lindex $_A53_DBGBASE 1] -defer-examine\ntarget create $_CHIPNAME.a53.2 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.2 -dbgbase [lindex $_A53_DBGBASE 2] -defer-examine\ntarget create $_CHIPNAME.a53.3 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.3 -dbgbase [lindex $_A53_DBGBASE 3] -defer-examine\n\n# 2x Cortex-A72 on AP #6\nset _A72_DBGBASE {0x80210000 0x80310000}\nset _A72_CTIBASE {0x80220000 0x80220000}\n\ncti create $_CHIPNAME.a72_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 0]\ncti create $_CHIPNAME.a72_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 1]\ntarget create $_CHIPNAME.a72.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.0 -dbgbase [lindex $_A72_DBGBASE 0] -defer-examine\ntarget create $_CHIPNAME.a72.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.1 -dbgbase [lindex $_A72_DBGBASE 1] -defer-examine\n\n# All Cortex-A in SMP\ntarget smp \\\n        $_CHIPNAME.a53.0 \\\n        $_CHIPNAME.a53.1 \\\n        $_CHIPNAME.a53.2 \\\n        $_CHIPNAME.a53.3 \\\n        $_CHIPNAME.a72.0 \\\n        $_CHIPNAME.a72.1\n\n# SCU: Cortex-M4 core\n# always running imx SC firmware\ntarget create ${_CHIPNAME}.scu cortex_m -dap ${_CHIPNAME}.dap -ap-num 1\n\n# AHB from SCU perspective\ntarget create ${_CHIPNAME}.scu_ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 4\n\n# Cortex-M4 M4_0 core on AP #2 (default off)\ntarget create ${_CHIPNAME}.m4_0 cortex_m -dap ${_CHIPNAME}.dap -ap-num 2 \\\n        -defer-examine\n\n# Cortex-M4 M4_1 core on AP #3 (default off)\ntarget create ${_CHIPNAME}.m4_1 cortex_m -dap ${_CHIPNAME}.dap -ap-num 3 \\\n        -defer-examine\n\n# Debug APB bus\ntarget create ${_CHIPNAME}.apb mem_ap -dap ${_CHIPNAME}.dap -ap-num 6\n\n# Default target is boot core a53.0\ntargets $_CHIPNAME.a53.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/infineon/tle987x.cfg",
    "content": "#\n# Infineon TLE987x family (Arm Cortex-M3 @ up to 40 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tle987x\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\t# JTAG not supported, only SWD\n\tset _CPU_TAPID 0\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME dap -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/is5114.cfg",
    "content": "# script for Insilica IS-5114\n# AKA: Atmel AT76C114 - an ARM946 chip\n# ATMEL sold his product line to Insilica...\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME is5114\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a little endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nreset_config trst_and_srst\n\n# Do not specify a tap id here...\njtag newtap $_CHIPNAME unknown1 -irlen 8 -ircapture 0x01 -irmask 1\n# This is the \"arm946\" chip.\njtag newtap $_CHIPNAME cpu      -irlen 4 -ircapture 0x0e -irmask 0xf\njtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1\n\n\n#arm946e-s and\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\tadapter speed 3000\n}\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ixp42x.cfg",
    "content": "#xscale ixp42x CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ixp42x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x19274013\n}\nset _CPUTAPID2 0x19275013\nset _CPUTAPID3 0x19277013\nset _CPUTAPID4 0x29274013\nset _CPUTAPID5 0x29275013\nset _CPUTAPID6 0x29277013\n\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\n# register constants for IXP42x SDRAM controller\nglobal IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\nglobal IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\nset IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\t0x0000\nset IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\t0x0001\n\nglobal IXP42x_SDRAM_CL3\nglobal IXP42x_SDRAM_CL2\nset IXP42x_SDRAM_CL3\t\t\t0x0008\nset IXP42x_SDRAM_CL2\t\t\t0x0000\n\nglobal IXP42x_SDRAM_8MB_2Mx32_1BANK\nglobal IXP42x_SDRAM_16MB_2Mx32_2BANK\nglobal IXP42x_SDRAM_16MB_4Mx16_1BANK\nglobal IXP42x_SDRAM_32MB_4Mx16_2BANK\nglobal IXP42x_SDRAM_32MB_8Mx16_1BANK\nglobal IXP42x_SDRAM_64MB_8Mx16_2BANK\nglobal IXP42x_SDRAM_64MB_16Mx16_1BANK\nglobal IXP42x_SDRAM_128MB_16Mx16_2BANK\nglobal IXP42x_SDRAM_128MB_32Mx16_1BANK\nglobal IXP42x_SDRAM_256MB_32Mx16_2BANK\n\nset IXP42x_SDRAM_8MB_2Mx32_1BANK\t0x0030\nset IXP42x_SDRAM_16MB_2Mx32_2BANK\t0x0031\nset IXP42x_SDRAM_16MB_4Mx16_1BANK\t0x0032\nset IXP42x_SDRAM_32MB_4Mx16_2BANK\t0x0033\nset IXP42x_SDRAM_32MB_8Mx16_1BANK\t0x0010\nset IXP42x_SDRAM_64MB_8Mx16_2BANK\t0x0011\nset IXP42x_SDRAM_64MB_16Mx16_1BANK\t0x0012\nset IXP42x_SDRAM_128MB_16Mx16_2BANK\t0x0013\nset IXP42x_SDRAM_128MB_32Mx16_1BANK\t0x0014\nset IXP42x_SDRAM_256MB_32Mx16_2BANK\t0x0015\n\n\n# helper function to init SDRAM on IXP42x.\n# SDRAM_CFG: one of IXP42X_SDRAM_xxx\n# REFRESH: refresh counter reload value (integer)\n# CASLAT: 2 or 3\nproc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } {\n\n    switch $CASLAT {\n\t2 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL2} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\n\t}\n\t3 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL3} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\n\t}\n\tdefault { error [format \"unsupported cas latency \\\"%s\\\" \" $CASLAT] }\n    }\n    echo [format \"\\tIXP42x SDRAM Config: 0x%x, Refresh %d \" $SDRAM_CFG $REFRESH]\n\n    mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3\n    mww 0xCC000004          0 ;# disable refresh\n    mww 0xCC000008          3 ;# NOP\n    sleep 100\n    mww 0xCC000004   $REFRESH ;# set refresh counter\n    mww 0xCC000008          2 ;# Precharge All Banks\n    sleep 100\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008    $CASCMD ;# Mode Select CL2/CL3\n}\n\nproc ixp42x_set_bigendian { } {\n    reg XSCALE_CTRL 0xF8\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/k1921vk01t.cfg",
    "content": "# K1921VK01T\n# http://niiet.ru/chips/nis?id=354\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME k1921vk01t\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME\n\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/k40.cfg",
    "content": "#\n# Freescale Kinetis K40 devices\n#\n\nset CHIPNAME k40\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/k60.cfg",
    "content": "#\n# Freescale Kinetis K60 devices\n#\n\nset CHIPNAME k60\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ke0x.cfg",
    "content": "#\n# Freescale Kinetis KE0x and KEAx series devices\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ke\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\n   # It is important that \"kinetis_ke mdm check_security\" is called for\n   # 'examine-end' event and not 'eximine-start'. Calling it in 'examine-start'\n   # causes \"kinetis_ke mdm check_security\" to fail the first time openocd\n   # calls it when it tries to connect after the CPU has been power-cycled.\n   $_CHIPNAME.cpu configure -event examine-end {\n      kinetis_ke mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ke1xf.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xF devices\n#\n\nset CHIPNAME ke\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ke1xz.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xZ devices\n#\n\nset CHIPNAME ke\n\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/kl25.cfg",
    "content": "#\n# Freescale Kinetis KL25 devices\n#\n\nset CHIPNAME kl25\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/kl46.cfg",
    "content": "#\n# Freescale Kinetis KL46 devices\n#\n\nset CHIPNAME kl46\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/klx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis KL series devices\n# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME klx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1KiB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\n# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual\n# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;\n# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ks869x.cfg",
    "content": "# ARM920T CPU\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ks869x\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set  _CPUTAPID $CPUTAPID\n} else {\n   set  _CPUTAPID 0x00922f0f\n}\n\nadapter speed 6000\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/kx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis Kx series devices\n# Also used for Cortex-M4 equipped members of KVx and KE1xF series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME kx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \" Expect problems connecting to a blank device without boot ROM.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU or boot lock-up in RESET/WDOG loop\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n   # During RESET/WDOG loop the target is sometimes falsely examined\n   $_TARGETNAME configure -event examine-end {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc11xx.cfg",
    "content": "# NXP LPC11xx Cortex-M0 with at least 1kB SRAM\nset CHIPNAME lpc11xx\nset CHIPSERIES lpc1100\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc12xx.cfg",
    "content": "# NXP LPC12xx Cortex-M0 with at least 4kB SRAM\nset CHIPNAME lpc12xx\nset CHIPSERIES lpc1200\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc13xx.cfg",
    "content": "# NXP LPC13xx Cortex-M3 with at least 4kB SRAM\nset CHIPNAME lpc13xx\nset CHIPSERIES lpc1300\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc17xx.cfg",
    "content": "# NXP LPC17xx Cortex-M3 with at least 8kB SRAM\nset CHIPNAME lpc17xx\nset CHIPSERIES lpc1700\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x2000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc1850.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc1850\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n#\n# M3 JTAG mode TAP\n#\nif { [info exists M3_JTAG_TAPID] } {\n   set _M3_JTAG_TAPID $M3_JTAG_TAPID\n} else {\n   set _M3_JTAG_TAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME m3 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_JTAG_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.m3\n\nset _TARGETNAME $_CHIPNAME.m3\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc1xxx.cfg",
    "content": "# Main file for NXP LPC1xxx/LPC40xx series Cortex-M0/0+/3/4F parts\n#\n# !!!!!!\n#\n# This file should not be included directly, rather by the lpc11xx.cfg,\n# lpc13xx.cfg, lpc17xx.cfg, etc. which set the needed variables to the\n# appropriate values.\n#\n# !!!!!!\n\n# LPC8xx chips support only SWD transport.\n# LPC11xx chips support only SWD transport.\n# LPC12xx chips support only SWD transport.\n# LPC11Uxx chips support only SWD transports.\n# LPC13xx chips support only SWD transports.\n# LPC17xx chips support both JTAG and SWD transports.\n# LPC40xx chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\terror \"CHIPNAME not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\nif { [info exists CHIPSERIES] } {\n\t# Validate chip series is supported\n\tif { $CHIPSERIES != \"lpc800\" && $CHIPSERIES != \"lpc1100\" && $CHIPSERIES != \"lpc1200\" && $CHIPSERIES != \"lpc1300\" && $CHIPSERIES != \"lpc1700\"  && $CHIPSERIES != \"lpc4000\" } {\n\t\terror \"Unsupported LPC1xxx chip series specified.\"\n\t}\n\tset _CHIPSERIES $CHIPSERIES\n} else {\n\terror \"CHIPSERIES not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\n# After reset, the chip is clocked by an internal RC oscillator.\n# When board-specific code (reset-init handler or device firmware)\n# configures another oscillator and/or PLL0, set CCLK to match; if\n# you don't, then flash erase and write operations may misbehave.\n# (The ROM code doing those updates cares about core clock speed...)\n# CCLK is the core clock frequency in KHz\nif { [info exists CCLK] } {\n\t# Allow user override\n\tset _CCLK $CCLK\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x)\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t\tset _CCLK 12000\n\t} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tset _CCLK 4000\n\t}\n}\n\nif { [info exists CPUTAPID] } {\n\t# Allow user override\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core.\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" } {\n\t\tset _CPUTAPID 0x0bb11477\n\t} elseif { $_CHIPSERIES == \"lpc1300\" || $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tif { [using_jtag] } {\n\t\t\tset _CPUTAPID 0x4ba00477\n\t\t} {\n\t\t\tset _CPUTAPID 0x2ba01477\n\t\t}\n\t}\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\terror \"WORKAREASIZE is not set. The $CHIPNAME part is available in several Flash and RAM size configurations. Please set WORKAREASIZE.\"\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# The LPC11xx devices have 2/4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC12xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC11Uxx devices have 4/6/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC13xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC17xx devices have 8/16/32/64kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC40xx devices have 16/32/64kB of SRAM in the ARMv7-ME \"Code\" area (at 0x10000000)\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n# The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000)\n# The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000)\n# The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 0x00000000)\n# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000)\n# The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000)\n# The LPC40xx devies have 64/128/256/512kB of flash memory (at 0x00000000)\n#\n# All are compatible with the \"lpc1700\" variant of the LPC2000 flash driver\n# (same cmd51 destination boundary alignment, and all three support 256 byte\n# transfers).\n#\n# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum] [iap entry]\nset _IAP_ENTRY 0\nif { [info exists IAP_ENTRY] } {\n\tset _IAP_ENTRY $IAP_ENTRY\n}\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \\\n\tauto $_CCLK calc_checksum $_IAP_ENTRY\n\nif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t# Do not remap 0x0000-0x0200 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# Table 8. System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n\t# Bit Symbol Value Description\n\t# 1:0 MAP          System memory remap\n\t#            0x0   Boot Loader Mode. Interrupt vectors are re-mapped to Boot ROM.\n\t#            0x1   User RAM Mode. Interrupt vectors are re-mapped to Static RAM.\n\t#            0x2   User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash.\n\t# 31:2 -     -     Reserved.\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x40048000 0x02\n\t}\n} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x400FC040 0x01\n\t}\n}\n\n# Run with *real slow* clock by default since the\n# boot rom could have been playing with the PLL, so\n# we have no idea what clock the target is running at.\nadapter speed 10\n\n# delays on reset lines\nadapter srst delay 200\nif {[using_jtag]} {\n jtag_ntrst_delay 200\n}\n\n# LPC8xx (Cortex-M0+ core) support SYSRESETREQ\n# LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ\n# LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ\n# LPC40xx (Cortex-M4F core) support SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2103.cfg",
    "content": "# NXP LPC2103 ARM7TDMI-S with 32kB flash and 8kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2103 {core_freq_khz adapter_freq_khz} {\n\t# 32kB flash and 8kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2103 0x4f1f0f0f 0x8000 lpc2000_v2 0x2000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2103 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2103 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2124.cfg",
    "content": "# NXP LPC2124 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2124 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2124 0x4f1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2124 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2124 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2129.cfg",
    "content": "# NXP LPC2129 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2129 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2129 0xcf1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2129 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2129 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2148.cfg",
    "content": "# NXP LPC2148 ARM7TDMI-S with 512kB flash (12kB used by bootloader) and 40kB SRAM (8kB for USB DMA), clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2148 {core_freq_khz adapter_freq_khz} {\n\t# 500kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2148 \"0x3f0f0f0f 0x4f1f0f0f\" 0x7d000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2148 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2148 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2294.cfg",
    "content": "# NXP LPC2294 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2294 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\n\t# !! TAPID unknown !!\n\tsetup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2294 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2294 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2378.cfg",
    "content": "# NXP LPC2378 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 56kB SRAM (16kB for ETH, 8kB for DMA), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2378 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2378 0x4f1f0f0f 0x7e000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2378 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2378 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2460.cfg",
    "content": "# NXP LPC2460 ARM7TDMI-S with 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2460 {core_freq_khz adapter_freq_khz} {\n\t# 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2460 0x4f1f0f0f 0 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2460 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2460 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2478.cfg",
    "content": "# NXP LPC2478 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2478 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2478 0x4f1f0f0f 0x7e000 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2478 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2478 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2900.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME lpc2900\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0596802B\n}\n\nif { [info exists HAS_ETB] } {\n} else {\n    # Set default (no ETB).\n    # Show a warning, because this should have been configured explicitly.\n    set HAS_ETB 0\n    # TODO: warning?\n}\n\nif { [info exists ETBTAPID] } {\n    set _ETBTAPID $ETBTAPID\n} else {\n    set _ETBTAPID 0x1B900F0F\n}\n\n# TRST and SRST both exist, and can be controlled independently\nreset_config trst_and_srst separate\n\n# Define the _TARGETNAME\nset _TARGETNAME $_CHIPNAME.cpu\n\n# Include the ETB tap controller if asked for.\n# Has to be done manually for newer devices (not an \"old\" LPC2917/2919).\nif { $HAS_ETB == 1 } {\n    # Clear the HAS_ETB flag. Must be set again for a new tap in the chain.\n    set HAS_ETB 0\n\n    # Add the ETB tap controller and the ARM9 core debug tap\n    jtag newtap $_CHIPNAME etb -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_ETBTAPID\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n\n    # Configure ETM and ETB\n    etm config $_TARGETNAME 8 normal full etb\n    etb config $_TARGETNAME $_CHIPNAME.etb\n\n} else {\n    # Add the ARM9 core debug tap\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n}\n\narm7_9 dbgrq enable\narm7_9 dcc_downloads enable\n\n# Flash bank configuration:\n# Flash: flash bank lpc2900 0 0 0 0 <target#> <flash clock (CLK_SYS_FMC) in kHz>\n# Flash base address, total flash size, and number of sectors are all configured automatically.\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME $FLASH_CLOCK\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc2xxx.cfg",
    "content": "# Common setup for the LPC2xxx parts\n\n# parameters:\n# - chip_name - name of the chip, e.g. lpc2103\n# - cputapids - TAP IDs of the core, should be quoted if more than one, e.g. 0x4f1f0f0f or \"0x3f0f0f0f 0x4f1f0f0f\"\n# - flash_size - size of on-chip flash (available for code, not including the bootloader) in bytes, e.g. 0x8000\n# - flash_variant - \"type\" of LPC2xxx device, lpc2000_v1 (LPC22xx and older LPC21xx) or lpc2000_v2 (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)\n# - workarea_size - size of work-area in RAM for flashing procedures, must not exceed the size of RAM available at 0x40000000, e.g. 0x2000\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size core_freq_khz adapter_freq_khz} {\n\treset_config trst_and_srst\n\n\t# reset delays\n\tadapter srst delay 100\n\tjtag_ntrst_delay 100\n\n\tadapter speed $adapter_freq_khz\n\n\tforeach i $cputapids {\n\t\tappend expected_ids \"-expected-id \" $i \" \"\n\t}\n\n\teval \"jtag newtap $chip_name cpu -irlen 4 -ircapture 0x1 -irmask 0xf $expected_ids\"\n\n\tglobal _TARGETNAME\n\tset _TARGETNAME $chip_name.cpu\n\ttarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n\t$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size $workarea_size -work-area-backup 0\n\n\tif { $flash_size > 0 } {\n\t\t# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum]\n\t\tset _FLASHNAME $chip_name.flash\n\t\tflash bank $_FLASHNAME lpc2000 0x0 $flash_size 0 0 $_TARGETNAME $flash_variant $core_freq_khz calc_checksum\n\t}\n}\n\nproc init_targets {} {\n\t# FIX!!! read out CPUTAPID here and choose right setup. In addition to the\n\t# CPUTAPID some querying of the target would be required.\n\treturn -error \"This is a generic LPC2xxx configuration file, use a specific target file.\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc3131.cfg",
    "content": "######################################\n# Target:    NXP lpc3131\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3131\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# ARM926EJS core\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926f0f\n}\n\n# Scan Tap\n# Wired to separate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module\n# JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through.\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1541E02B\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n##################################################################\n# various symbol definitions, to avoid hard-wiring addresses\n##################################################################\n\nglobal lpc313x\nset lpc313x [ dict create ]\n\n# Physical addresses for controllers and memory\ndict set lpc313x sram0\t\t\t0x11028000\ndict set lpc313x sram1\t\t\t0x11040000\ndict set lpc313x uart\t\t\t0x15001000\ndict set lpc313x cgu\t\t\t0x13004000\ndict set lpc313x ioconfig\t\t0x13003000\ndict set lpc313x sysconfig\t\t0x13002800\ndict set lpc313x wdt\t\t\t0x13002400\n\n##################################################################\n# Target configuration\n##################################################################\n\nadapter srst delay 1000\njtag_ntrst_delay 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME invoke-event halted\n\n$_TARGETNAME configure -work-area-phys [dict get $lpc313x sram0] -work-area-size 0x30000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"\\nRunning reset init script for LPC3131\\n\"\n\thalt\n\twait_halt\n\treg cpsr 0xa00000d3\t;#Supervisor mode\n\treg pc 0x11029000\n\tpoll\n\tsleep 500\n}\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc3250.cfg",
    "content": "# lpc3250 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3250\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x17900f0f\n}\n\nif { [info exists CPUTAPID_REV_A0] } {\n   set _CPUTAPID_REV_A0 $CPUTAPID_REV_A0\n} else {\n   set _CPUTAPID_REV_A0 0x17926f0f\n}\n\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1b900f0f\n}\n\njtag newtap $_CHIPNAME sjc -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_SJCTAPID\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID \\\n     -expected-id $_CPUTAPID_REV_A0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -work-area-phys 0x00000000 -work-area-size 0x7d0000 -work-area-backup 0\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc40xx.cfg",
    "content": "# NXP LPC40xx Cortex-M4F with at least 16kB SRAM\nset CHIPNAME lpc40xx\nset CHIPSERIES lpc4000\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x4000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc4350.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4350\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\nif { [using_jtag] } {\n\tswj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tdap create $_CHIPNAME.m0.dap -chain-position $_CHIPNAME.m0\n\ttarget create $_CHIPNAME.m0 cortex_m -dap $_CHIPNAME.m0.dap\n}\n\n# LPC4350 has 96+32 KB SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n\t\t\t-work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # on this CPU we should use VECTRESET to perform a soft reset and\n   # manually reset the periphery\n   # SRST or SYSRESETREQ disable the debug interface for the time of\n   # the reset and will not fit our requirements for a consistent debug\n   # session\n   cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc4357.cfg",
    "content": "#\n# NXP LPC4357\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc4357\n}\nset WORKAREASIZE 0x8000\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.flasha lpc2000 0x1A000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\nflash bank $_CHIPNAME.flashb lpc2000 0x1B000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc4370.cfg",
    "content": "#\n# NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each\n#\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4370\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} else {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\n# LPC4370 has 96+32 KB contiguous SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n                        -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME m0app -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tjtag newtap $_CHIPNAME m0sub -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\n\tdap create $_CHIPNAME.m0app.dap -chain-position $_CHIPNAME.m0app\n\tdap create $_CHIPNAME.m0sub.dap -chain-position $_CHIPNAME.m0sub\n\ttarget create $_CHIPNAME.m0app cortex_m -dap $_CHIPNAME.m0app.dap\n\ttarget create $_CHIPNAME.m0sub cortex_m -dap $_CHIPNAME.m0sub.dap\n\n\t# 32+8+32 KB SRAM\n\t$_CHIPNAME.m0app configure -work-area-phys 0x10080000 \\\n\t                           -work-area-size 0x92000 -work-area-backup 0\n\n\t# 16+2 KB M0 subsystem SRAM\n\t$_CHIPNAME.m0sub configure -work-area-phys 0x18000000 \\\n\t                           -work-area-size 0x4800 -work-area-backup 0\n\n\t# Default to the Cortex-M4\n\ttargets $_CHIPNAME.m4\n}\n\nif { ![using_hla] } {\n\tcortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc84x.cfg",
    "content": "# NXP LPC84x Cortex-M0+ with at least 8kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc84x\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1fe0\n}\n\nset IAP_ENTRY 0x0F001FF1\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc8nxx.cfg",
    "content": "# NXP LPC8Nxx NHS31xx Cortex-M0+ with 8kB SRAM\n# Copyright (C) 2018 by Jean-Christian de Rivaz\n# Based on NXP proposal https://community.nxp.com/message/1011149\n# Many thanks to Dries Moors from NXP support.\n# SWD only transport\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME lpc8nxx\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\nif {![using_hla]} {\n\t# If srst is not fitted use SYSRESETREQ to  perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\nadapter srst delay 100\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0\n\nflash bank $_CHIPNAME.flash lpc2000 0x0 0x7800 0 0 $_TARGETNAME lpc800 500\n\necho \"*********************************************************************************\"\necho \"*         !!!!! IMPORTANT NOTICE FOR LPC8Nxx and NHS31xx CHIPS !!!!!\"\necho \"* When this IC is in power-off or peep power down mode, the SWD HW block is also\"\necho \"* unpowered. These modes can be entered by firmware. The default firmware image\"\necho \"* (flashed in production) makes use of this. Best is to avoid these power modes\"\necho \"* during development, and only later add them when the functionality is complete.\"\necho \"* Hardware reset or NFC field are the only ways to connect in case the SWD is\"\necho \"* powered off. OpenOCD can do a hardware reset if you wire the adapter SRST\"\necho \"* signal to the chip RESETN pin and add the following in your configuration:\"\necho \"*     reset_config srst_only; flash init; catch init; reset\"\necho \"* But if the actual firmware immediately set the power down mode after reset,\"\necho \"* OpenOCD might be not fast enough to halt the CPU before the SWD lost power. In\"\necho \"* that case the only solution is to apply a NFC field to keep the SWD powered.\"\necho \"*********************************************************************************\"\n\n# Using soft-reset 'reset_config none' is strongly discouraged.\n# RESETN sets the system clock to 500 kHz. Unlike soft-reset does not.\n# Set the system clock to 500 kHz before reset to simulate the functionality of hw reset.\n#\nproc set_sysclk_500khz {} {\n\tset SYSCLKCTRL 0x40048020\n\tset SYSCLKUEN 0x40048024\n\tmww $SYSCLKUEN 0\n\tmmw $SYSCLKCTRL 0x8 0xe\n\tmww $SYSCLKUEN 1\n\techo \"Notice: sysclock set to 500kHz.\"\n}\n\n# Do not remap the ARM interrupt vectors to anything but the beginning of the flash.\n# Table System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n# Bit Symbol  Value   Description\n# 0   map         -   interrupt vector remap. 0 after boot.\n#                 0   interrupt vector reside in Flash\n#                 1   interrupt vector reside in SRAM\n# 5:1 offset      -   system memory remap offset. 00000b after boot.\n#            00000b   interrupt vectors in flash or remapped to SRAM but no offset\n#            00001b -\n#            00111b   interrupt vectors offset in flash or SRAM to 1K word segment\n#            01000b -\n#            11111b   interrupt vectors offset in flash to 1K word segment 8 to 31\n# 31:6                reserved\n#\nproc set_no_remap {} {\n\tmww 0x40048000 0x00\n\techo \"Notice: interrupt vector set to no remap.\"\n}\n\n$_TARGETNAME configure -event reset-init {\n\tset_sysclk_500khz\n\tset_no_remap\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lpc8xx.cfg",
    "content": "# NXP LPC8xx Cortex-M0+ with at least 1kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc8xx\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ls1012a.cfg",
    "content": "#\n# NXP LS1012A\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1012a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b2001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ncti create $_CHIPNAME.cti -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0x80420000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -dbgbase 0x80410000 -cti $_CHIPNAME.cti\n\ntarget smp $_TARGETNAME\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ls1028a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1028A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1028a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\nset _CPUS 2\n\nsource [find target/lsch3_common.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1046a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b3001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _CPU_BASE 0x80400000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < 4} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t-coreid $i {*}[expr {$i ? {-defer-examine} : {-rtos hwthread} }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\ntarget create $_CHIPNAME.sap ls1_sap -chain-position $_CHIPNAME.sap -endian big\n\nproc core_up { args } {\n    foreach core $args {\n        $::_CHIPNAME.cpu$core arp_examine\n    }\n}\n\ntargets $_CHIPNAME.cpu0\n\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1088a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nset _CPUS 8\n\nsource [find target/lsch3_common.cfg]\n\n# Seems to work OK in testing\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/lsch3_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# This contains common configuration for NXP Layerscape chassis generation 3\n\nif { ![info exists _CPUS] } {\n\terror \"_CPUS must be set to the number of cores\"\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 1\n\nset _CPU_BASE 0x81000000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < $_CPUS} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 0 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t{*}[expr {$i ? \"-coreid $i\" : \"-rtos hwthread\" }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\n# Service processor\ntarget create $_CHIPNAME.sp cortex_a -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80138000\n\n# Normally you will not need to call this, but if you are using the hard-coded\n# Reset Configuration Word (RCW) you will need to call this manually. The CPU's\n# reset vector is 0, and the boot ROM at that location contains ARMv7-A 32-bit\n# instructions. This will cause the CPU to almost immediately execute an\n# illegal instruction.\n#\n# This code is idempotent; releasing a released CPU has no effect, although it\n# will halt/resume the service processor.\nadd_help_text release_cpu \"Release a cpu which is held off\"\nproc release_cpu {cpu} {\n\tset RST_BRRL 0x1e60060\n\n\tset old [target current]\n\ttargets $::_CHIPNAME.sp\n\tset not_halted [string compare halted [$::_CHIPNAME.sp curstate]]\n\tif {$not_halted} {\n\t\thalt\n\t}\n\n\t# Release the cpu; it will start executing something bogus\n\tmem2array regs 32 $RST_BRRL 1\n\tmww $RST_BRRL [expr {$regs(0) | 1 << $cpu}]\n\n\tif {$not_halted} {\n\t\tresume\n\t}\n\ttargets $old\n}\n\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/marvell/88f3710.cfg",
    "content": "# Marvell Armada 3710\n\nset CORES 1\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/marvell/88f3720.cfg",
    "content": "# Marvell Armada 3720\n\nset CORES 2\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/marvell/88f37x0.cfg",
    "content": "# Main file for Marvell Armada 3700 series targets\n#\n# !!!!!!\n#\n# This file should not be included directly. Instead, please include\n# either marvell/88f3710.cfg or marvell/88f3720.cfg, which set the needed\n# variables to the appropriate values.\n#\n# !!!!!!\n\n# Armada 3700 supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CORES] } {\n    set _cores $CORES\n} else {\n    error \"CORES not set. Please do not include marvell/88f37x0.cfg directly, but the specific chip configuration file (marvell/88f3710.cfg, marvell/88f3720.cfg, etc.).\"\n}\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME [format a37%s0 $_cores]\n}\n\nset _ctis {0x80820000 0x80920000}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# declare the main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [lindex $_ctis $_core] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core \\\n                         -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M3 core on AP #3\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/max32620.cfg",
    "content": "# Maxim Integrated MAX32620 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -ignore-version\n} else {\n    swd newdap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32620.cpu cortex_m -chain-position max32620.cpu\nmax32620.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32620 flash base address   0x00000000\n#   max32620 flash size           0x200000 (2MB)\n#   max32620 FLC base address     0x40002000\n#   max32620 sector (page) size   0x2000 (8kB)\n#   max32620 clock speed          96 (MHz)\nflash bank max32620.flash max32xxx 0x00000000 0x200000 0 0 max32620.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/max32625.cfg",
    "content": "# Maxim Integrated MAX32625 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f71197 -ignore-version\n} else {\n    swd newdap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32625.cpu cortex_m -chain-position max32625.cpu\nmax32625.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32625 flash base address   0x00000000\n#   max32625 flash size           0x80000 (512k)\n#   max32625 FLC base address     0x40002000\n#   max32625 sector (page) size   0x2000 (8kB)\n#   max32625 clock speed          96 (MHz)\nflash bank max32625.flash max32xxx 0x00000000 0x80000 0 0 max32625.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/max3263x.cfg",
    "content": "# Maxim Integrated MAX3263X OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f76197 -ignore-version\n} else {\n    swd newdap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max3263x.cpu cortex_m -chain-position max3263x.cpu\nmax3263x.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max3263x flash base address   0x00000000\n#   max3263x flash size           0x200000 (2MB)\n#   max3263x FLC base address     0x40002000\n#   max3263x sector (page) size   0x2000 (8kB)\n#   max3263x clock speed          96 (MHz)\nflash bank max3263x.flash max32xxx 0x00000000 0x200000 0 0 max3263x.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/mc13224v.cfg",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER             freescale\nset CHIP_FAMILY            mc1322x\nset CHIP_NAME              mc13224\nset N_RAM                  1\nset RAM(0,BASE)            0x00400000\nset RAM(0,LEN)             0x18000\nset RAM(0,HUMAN)           \"internal SRAM\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS                  1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0x80000000\nset MMREGS(0,LEN)             0x00030000\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\nset N_XMEM 0\n\nset _CHIPNAME mc13224v\nset _CPUTAPID 0x1f1f001d\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nreset_config srst_only\njtag_ntrst_delay 200\n\n# rclk hasn't been working well. This maybe the mc13224v or something else.\n#adapter speed 2000\nadapter speed 2000\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n# Internal sram memory\n$_TARGETNAME configure -work-area-phys 0x00408000 \\\n                       -work-area-size 0x1000     \\\n                       -work-area-backup 1\n\n# flash support is pending (should be straightforward to implement)\n#flash bank mc1322x 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/mdr32f9q2i.cfg",
    "content": "# MDR32F9Q2I (1986ВЕ92У)\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=57&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME mdr32f9q2i\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x08000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x08000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nds32v2.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nds32v3.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nds32v3m.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nds32v5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\nset _CHIPNAME nds\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563D\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nhs31xx.cfg",
    "content": "# NXP NHS31xx Cortex-M0+ with 8kB SRAM\n\nset CHIPNAME nhs31xx\nsource [find target/lpc8nxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/npcx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton NPCX Cortex-M4 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NPCX_M4\n}\n\n# SWD DAP ID of Nuvoton NPCX Cortex-M4.\nif { [info exists CPUDAPID ] } {\n   set _CPUDAPID $CPUDAPID\n} else {\n   set _CPUDAPID 0x4BA00477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x200c0000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# Initial JTAG/SWD speed\n# For safety purposes, set for the lowest cpu clock configuration\n# 4MHz / 6 = 666KHz, so use 600KHz for it\nadapter speed 600\n\n# For safety purposes, set for the lowest cpu clock configuration\n$_TARGETNAME configure -event reset-start {adapter speed 600}\n\n# use sysresetreq to perform a system reset\ncortex_m reset_config sysresetreq\n\n# flash configuration\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nrf51.cfg",
    "content": "#\n# script for Nordic nRF51 series, a Cortex-M0 chip\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nrf51\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # The chip supports standard ARM/Cortex-M0 SYSRESETREQ signal\n   cortex_m reset_config sysresetreq\n}\n\nflash bank $_CHIPNAME.flash nrf51 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME\n\n#\n#  The chip should start up from internal 16Mhz RC, so setting adapter\n#  clock to 1Mhz should be OK\n#\nadapter speed 1000\n\nproc enable_all_ram {} {\n\t# nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks\n\t# are reliably enabled after reset on some revisions (contrary to spec.) So after\n\t# resetting we enable all banks via the RAMON register\n\tmww 0x40000524 0xF\n}\n$_TARGETNAME configure -event reset-end {  enable_all_ram }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nrf52.cfg",
    "content": "#\n# Nordic nRF52 series: ARM Cortex-M4 @ 64 MHz\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME nrf52\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nadapter speed 1000\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_hla] } {\n\techo \"\"\n\techo \"nRF52 device has a CTRL-AP dedicated to recover the device from AP lock.\"\n\techo \"A high level adapter (like a ST-Link) you are currently using cannot access\"\n\techo \"the CTRL-AP so 'nrf52_recover' command will not work.\"\n\techo \"Do not enable UICR APPROTECT.\"\n\techo \"\"\n} else {\n\tcortex_m reset_config sysresetreq\n\n\t$_TARGETNAME configure -event examine-fail nrf52_check_ap_lock\n}\n\nflash bank $_CHIPNAME.flash nrf5 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf5 0x10001000 0 1 1 $_TARGETNAME\n\n# Test if MEM-AP is locked by UICR APPROTECT\nproc nrf52_check_ap_lock {} {\n\tset dap [[target current] cget -dap]\n\tset err [catch {set APPROTECTSTATUS [$dap apreg 1 0xc]}]\n\tif {$err == 0 && $APPROTECTSTATUS != 1} {\n\t\techo \"****** WARNING ******\"\n\t\techo \"nRF52 device has AP lock engaged (see UICR APPROTECT register).\"\n\t\techo \"Debug access is denied.\"\n\t\techo \"Use 'nrf52_recover' to erase and unlock the device.\"\n\t\techo \"\"\n\t\tpoll off\n\t}\n}\n\n# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #1)\n# http://www.ebyte.com produces modules with nRF52 locked by default,\n# use nrf52_recover to enable flashing and debug.\nproc nrf52_recover {} {\n\tset target [target current]\n\tset dap [$target cget -dap]\n\n\tset IDR [$dap apreg 1 0xfc]\n\tif {$IDR != 0x02880000} {\n\t\techo \"Error: Cannot access nRF52 CTRL-AP!\"\n\t\treturn\n\t}\n\n\tpoll off\n\n\t# Reset and trigger ERASEALL task\n\t$dap apreg 1 4 0\n\t$dap apreg 1 4 1\n\n\tfor {set i 0} {1} {incr i} {\n\t\tset ERASEALLSTATUS [$dap apreg 1 8]\n\t\tif {$ERASEALLSTATUS == 0} {\n\t\t\techo \"$target device has been successfully erased and unlocked.\"\n\t\t\tbreak\n\t\t}\n\t\tif {$i == 0} {\n\t\t\techo \"Waiting for chip erase...\"\n\t\t}\n\t\tif {$i >= 150} {\n\t\t\techo \"Error: $target recovery failed.\"\n\t\t\tbreak\n\t\t}\n\t\tsleep 100\n\t}\n\n\t# Assert reset\n\t$dap apreg 1 0 1\n\n\t# Deassert reset\n\t$dap apreg 1 0 0\n\n\t# Reset ERASEALL task\n\t$dap apreg 1 4 0\n\n\tsleep 100\n\t$target arp_examine\n\tpoll on\n}\n\nadd_help_text nrf52_recover \"Mass erase and unlock nRF52 device\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/nuc910.cfg",
    "content": "#\n# Nuvoton nuc910 (previously W90P910) based soc\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nuc910\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x07926f0f\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/numicro.cfg",
    "content": "# script for Nuvoton MuMicro Cortex-M0 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NuMicro\n}\n\n# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only.\nif { [info exists CPUDAPID] } {\n\tset _CPUDAPID $CPUDAPID\n} else {\n\tset _CPUDAPID 0x0BB11477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash_aprom\nflash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_data\nflash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_ldrom\nflash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_config\nflash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME\n\n# set default SWCLK frequency\nadapter speed 1000\n\n# set default srst setting \"none\"\nreset_config none\n\n# HLA doesn't have cortex_m commands\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omap2420.cfg",
    "content": "# Texas Instruments OMAP 2420\n#\thttp://www.ti.com/omap\n# as seen in Nokia N8x0 tablets\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap2420\n}\n\n# NOTE: likes slowish clock on reset (1.5 MBit/s or less) or use RCLK\nreset_config srst_nogate\n\n# Subsidiary TAP: ARM7TDMIr4 plus imaging ... must add via ICEpick (addr 6).\njtag newtap $_CHIPNAME iva -irlen 4 -disable\n\n# Subsidiary TAP: C55x DSP ... must add via ICEpick (addr 2).\njtag newtap $_CHIPNAME dsp -irlen 38 -disable\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID\n\n# Subsidiary TAP: ARM1136jf-s with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07b3602f\n}\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\n# Primary TAP: ICEpick-B (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x01ce4801\n}\njtag newtap $_CHIPNAME jrc -irlen 2 -expected-id $_JRC_TAPID\n\n# GDB target: the ARM.\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_TARGETNAME\n\n# scratch: framebuffer, may be initially unavailable in some chips\n$_TARGETNAME configure -work-area-phys 0x40210000\n$_TARGETNAME configure -work-area-size 0x00081000\n$_TARGETNAME configure -work-area-backup 0\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\n# RM_RSTCTRL_WKUP.RST.GS - Trigger a global software reset, and\n# give it a chance to finish before we talk to the chip again.\nset RM_RSTCTRL_WKUP 0x48008450\n$_TARGETNAME configure -event reset-assert \\\n\t\"halt; $_TARGETNAME mww $RM_RSTCTRL_WKUP 2; sleep 200\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omap3530.cfg",
    "content": "# TI OMAP3530\n# http://focus.ti.com/docs/prod/folders/print/omap3530.html\n# Other OMAP3 chips remove DSP and/or the OpenGL support\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap3530\n}\n\n# ICEpick-C ... used to route Cortex, DSP, and more not shown here\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n\n# Subsidiary TAP: CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x0b6d602f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7ae02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# SRAM: 64K at 0x4020.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n###################\n\n# the reset sequence is event-driven\n# and kind of finicky...\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# have the DAP \"always\" be active\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\nproc omap3_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n     # Enable DBGU signal for OMAP353x\n     $target mww phys 0x5401d030 0x00002000\n}\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in.\n# OK to speed up *after* PLL and clock tree setup.\nadapter speed 1000\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1000 }\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  RST_GS (2) is a warm reset, like ICEpick\n# would issue.  RST_DPLL3 (4) is a cold reset.\nset PRM_RSTCTRL 0x48307250\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww $PRM_RSTCTRL 2\"\n\n$_TARGETNAME configure -event reset-assert-post \"omap3_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omap4430.cfg",
    "content": "# OMAP4430\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4430\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x3b95c02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omap4460.cfg",
    "content": "# OMAP4460\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4460\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x2b94e02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omap5912.cfg",
    "content": "# TI OMAP5912 dual core processor\n# http://focus.ti.com/docs/prod/folders/print/omap5912.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap5912\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # NOTE: validated with XOMAP5912 part\n   set _CPUTAPID 0x0692602f\n}\n\nadapter srst delay 100\n\n# NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for\n# its standalone siblings (like TMS320VC5502) of the same era\n\n#jtag scan chain\njtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81\njtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID\njtag newtap $_CHIPNAME unknown -irlen 8\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\nproc omap5912_reset {} {\n\t#\n\t# halt target\n\t#\n\tpoll\n\tsleep 1\n\thalt\n\twait_halt\n\t#\n\t# disable wdt\n\t#\n\tmww 0xfffec808 0x000000f5\n\tmww 0xfffec808 0x000000a0\n\n\tmww 0xfffeb048 0x0000aaaa\n\tsleep 500\n\tmww 0xfffeb048 0x00005555\n\tsleep 500\n}\n\n# omap5912 lcd frame buffer as working area\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n\t-work-area-size 0x3e800 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/omapl138.cfg",
    "content": "#\n# Texas Instruments DaVinci family: OMAPL138\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omapl138\n}\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID -disable\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID -disable\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7d102f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target:  the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\ngdb_breakpoint_override hard\narm7_9 dbgrq enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/or1k.cfg",
    "content": "set  _ENDIAN big\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME or1k\n}\n\nif { [info exists TAP_TYPE] } {\n   set _TAP_TYPE $TAP_TYPE\n} else {\n   puts \"You need to select a tap type\"\n   shutdown\n}\n\n# Configure the target\nif { [string compare $_TAP_TYPE \"VJTAG\"] == 0 } {\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 10 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select vjtag\n\n} elseif { [string compare $_TAP_TYPE \"XILINX_BSCAN\"] == 0 } {\n\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select xilinx_bscan\n} else {\n\t# OpenCores Mohor JTAG TAP ID\n\tset _CPUTAPID  0x14951185\n\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select mohor\n}\n\n# Select the debug unit core we are using. This debug unit as an option.\n\nset ADBG_USE_HISPEED\t\t1\nset ENABLE_JSP_SERVER\t\t2\nset ENABLE_JSP_MULTI\t\t4\n\n# If ADBG_USE_HISPEED is set (options bit 1), status bits will be skipped\n# on burst reads and writes to improve download speeds.\n# This option must match the RTL configured option.\n\ndu_select adv [expr {$ADBG_USE_HISPEED | $ENABLE_JSP_SERVER | $ENABLE_JSP_MULTI}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/pic32mx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pic32mx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x30938053\n}\n\n# default working area is 16384\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#\n# At reset the pic32mx does not allow code execution from RAM\n# we have to setup the BMX registers to allow this.\n# One limitation is that we loose the first 2k of RAM.\n#\n\nglobal _PIC32MX_DATASIZE\nglobal _WORKAREASIZE\nset _PIC32MX_DATASIZE 0x800\nset _PIC32MX_PROGSIZE [expr {$_WORKAREASIZE - $_PIC32MX_DATASIZE}]\n\n$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size $_PIC32MX_PROGSIZE -work-area-backup 0\n$_TARGETNAME configure -event reset-init {\n\t#\n\t# from reset the pic32 cannot execute code in ram - enable ram execution\n\t# minimum offset from start of ram is 2k\n\t#\n\tglobal _PIC32MX_DATASIZE\n\tglobal _WORKAREASIZE\n\n\t# BMXCON\tset 0 wait state option by clearing BMXWSDRM bit, bit 6\n\tmww 0xbf882000 0x001f0000\n\t# BMXDKPBA: 2k kernel data @ 0xa0000000\n\tmww 0xbf882010 $_PIC32MX_DATASIZE\n\t# BMXDUDBA: 14k kernel program @ 0xa0000800 - (BMXDUDBA - BMXDKPBA)\n\tmww 0xbf882020 $_WORKAREASIZE\n\t# BMXDUPBA: 0k user program - (BMXDUPBA - BMXDUDBA)\n\tmww 0xbf882030 $_WORKAREASIZE\n\n\t#\n\t# Set system clock to 8Mhz if the default clock configuration is set\n\t#\n\n\t# SYSKEY register, make sure OSCCON is locked\n\tmww 0xbf80f230 0x0\n\t# SYSKEY register, write unlock sequence\n\tmww 0xbf80f230 0xaa996655\n\tmww 0xbf80f230 0x556699aa\n\t# OSCCON register + 4, clear OSCCON FRCDIV bits: 24, 25 and 26, divided by 1\n\tmww 0xbf80f004 0x07000000\n\t# SYSKEY register, relock OSCCON\n\tmww 0xbf80f230 0x0\n}\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank2 virtual 0xbd000000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank3 virtual 0x9d000000 0 0 0 $_TARGETNAME $_FLASHNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/psoc4.cfg",
    "content": "# script for Cypress PSoC 4 devices\n\n#\n# PSoC 4 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME psoc4\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\nadapter speed 1500\n\n# Reset, bloody PSoC 4 reset\n#\n# 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.\n# High level adapter stops working after SRST and needs OpenOCD restart.\n# If your hw does not use SRST for other circuits, use sysresetreq instead\n#\n# 2) PSoC 4 executes initialization code from system ROM after reset.\n# This code subsequently jumps to user flash reset vector address.\n# Unfortunately the system ROM code is protected from reading and debugging.\n# Protection breaks vector catch VC_CORERESET used for \"reset halt\" by cortex_m.\n#\n# Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code\n# from user flash. Programming specifications states that TEST_MODE flag must be\n# set in time frame 400 usec delayed about 1 msec from reset.\n#\n# OpenOCD have no standard way how to set TEST_MODE in specified time frame.\n# As a workaround the TEST_MODE flag is set before reset instead.\n# It worked for the oldest family PSoC4100/4200 even though it is not guaranteed\n# by specification.\n#\n# Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE\n# clear TEST_MODE flag during device reset so workaround is not possible.\n# Use a KitProg adapter for these devices or \"reset halt\" will not stop\n# before executing user code.\n#\n# 3) SWD cannot be connected during system initialization after reset.\n# This might be a reason for unconnecting ST-Link v2 when deasserting reset.\n# As a workaround arp_reset deassert is not called for hla\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc psoc4_get_family_id {} {\n\tset err [catch {set romtable_pid [read_memory 0xF0000FE0 32 3]}]\n\tif { $err } {\n\t\treturn 0\n\t}\n\tif { [expr {[lindex $romtable_pid 0] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 1] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 2] & 0xffffff00 }] } {\n\t\techo \"Unexpected data in ROMTABLE\"\n\t\treturn 0\n\t}\n\tset designer_id [expr {(( [lindex $romtable_pid 1] & 0xf0 ) >> 4) | (( [lindex $romtable_pid 2] & 0xf ) << 4 ) }]\n\tif { $designer_id != 0xb4 } {\n\t\techo [format \"ROMTABLE Designer ID 0x%02x is not Cypress\" $designer_id]\n\t\treturn 0\n\t}\n\tset family_id [expr {( [lindex $romtable_pid 0] & 0xff ) | (( [lindex $romtable_pid 1] & 0xf ) << 8 ) }]\n\treturn $family_id\n}\n\nproc ocd_process_reset_inner { MODE } {\n\tglobal PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND\n\tglobal _TARGETNAME\n\n\tif { 0 != [string compare $_TARGETNAME [target names]] } {\n\t\treturn -code error \"PSoC 4 reset can handle only one $_TARGETNAME target\";\n\t}\n\tset t $_TARGETNAME\n\n\t# If this target must be halted...\n\tset halt -1\n\tif { 0 == [string compare $MODE halt] } {\n\t\tset halt 1\n\t}\n\tif { 0 == [string compare $MODE init] } {\n\t\tset halt 1;\n\t}\n\tif { 0 == [string compare $MODE run ] } {\n\t\tset halt 0;\n\t}\n\tif { $halt < 0 } {\n\t\treturn -code error \"Invalid mode: $MODE, must be one of: halt, init, or run\";\n\t}\n\n\tif { ! [info exists PSOC4_USE_ACQUIRE] } {\n\t\tif { 0 == [string compare [adapter name] kitprog ] } {\n\t\t\tset PSOC4_USE_ACQUIRE 1\n\t\t} else {\n\t\t\tset PSOC4_USE_ACQUIRE 0\n\t\t}\n\t}\n\tif { $PSOC4_USE_ACQUIRE } {\n\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t} elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {\n\t\tif { [psoc4_get_family_id] == 0x93 } {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 1\n\t\t} else {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t\t}\n\t}\n\n\t#$t invoke-event reset-start\n\t$t invoke-event reset-assert-pre\n\n\tif { $halt && $PSOC4_USE_ACQUIRE } {\n\t\tcatch { [adapter name] acquire_psoc }\n\t\t$t arp_examine\n\t} else {\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tset TEST_MODE 0x40030014\n\t\t\tif { $halt == 1 } {\n\t\t\t\tcatch { mww $TEST_MODE 0x80000000 }\n\t\t\t} else {\n\t\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t\t}\n\t\t}\n\n\t\t$t arp_reset assert 0\n\t}\n\n\t$t invoke-event reset-assert-post\n\t$t invoke-event reset-deassert-pre\n\tif {![using_hla]} {\t# workaround ST-Link v2 fails and forcing reconnect\n\t\t$t arp_reset deassert 0\n\t}\n\t$t invoke-event reset-deassert-post\n\n\t# Pass 1 - Now wait for any halt (requested as part of reset\n\t# assert/deassert) to happen.  Ideally it takes effect without\n\t# first executing any instructions.\n\tif { $halt } {\n\t\t# Now PSoC CPU should loop in system ROM\n\t\t$t arp_waitstate running 200\n\t\t$t arp_halt\n\n\t\t# Catch, but ignore any errors.\n\t\tcatch { $t arp_waitstate halted 1000 }\n\n\t\t# Did we succeed?\n\t\tset s [$t curstate]\n\n\t\tif { 0 != [string compare $s \"halted\" ] } {\n\t\t\treturn -code error [format \"TARGET: %s - Not halted\" $t]\n\t\t}\n\n\t\t# Check if PSoC CPU is stopped in system ROM\n\t\tset pc [reg pc]\n\t\tregsub {pc[^:]*: } $pc \"\" pc\n\t\tif { $pc < 0x10000000 || $pc > 0x1000ffff } {\n\t\t\tset hint \"\"\n\t\t\tset family_id [psoc4_get_family_id]\n\t\t\tif { $family_id == 0x93 } {\n\t\t\t\tset hint \", use 'reset_config none'\"\n\t\t\t} elseif { $family_id > 0x93 } {\n\t\t\t\tset hint \", use a KitProg adapter\"\n\t\t\t}\n\t\t\treturn -code error [format \"TARGET: %s - Not halted in system ROM%s\" $t $hint]\n\t\t}\n\n\t\t# Set registers to reset vector values\n\t\tset value [read_memory 0x0 32 2]\n\t\treg pc [expr {[lindex $value 1] & 0xfffffffe}]\n\t\treg msp [lindex $value 0]\n\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t}\n\t}\n\n\t#Pass 2 - if needed \"init\"\n\tif { 0 == [string compare init $MODE] } {\n\t\tset err [catch \"$t arp_waitstate halted 5000\"]\n\n\t\t# Did it halt?\n\t\tif { $err == 0 } {\n\t\t\t$t invoke-event reset-init\n\t\t}\n\t}\n\n\t$t invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/psoc5lp.cfg",
    "content": "#\n# Cypress PSoC 5LP\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc5lp\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} else {\n\tset _CPU_TAPID 0x4BA00477\n}\n\nif { [using_jtag] } {\n\tset _CPU_DAP_ID $_CPU_TAPID\n} else {\n\tset _CPU_DAP_ID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE / 2}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nsource [find mem_helper.tcl]\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure Target Device (PSoC 5LP Device Programming Specification 5.2)\n\n\tset PANTHER_DBG_CFG 0x4008000C\n\tset PANTHER_DBG_CFG_BYPASS [expr {1 << 1}]\n\tmmw $PANTHER_DBG_CFG $PANTHER_DBG_CFG_BYPASS 0\n\n\tset PM_ACT_CFG0 0x400043A0\n\tmww $PM_ACT_CFG0 0xBF\n\n\tset FASTCLK_IMO_CR 0x40004200\n\tset FASTCLK_IMO_CR_F_RANGE_2    [expr {2 << 0}]\n\tset FASTCLK_IMO_CR_F_RANGE_MASK [expr {7 << 0}]\n\tmmw $FASTCLK_IMO_CR $FASTCLK_IMO_CR_F_RANGE_2 $FASTCLK_IMO_CR_F_RANGE_MASK\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/psoc6.cfg",
    "content": "#\n# Configuration script for Cypress PSoC6 family of microcontrollers (CY8C6xxx)\n# PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share\n# the same Flash/RAM/MMIO address space.\n#\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc6\n}\n\nglobal TARGET\nset TARGET $_CHIPNAME.cpu\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Is CM0 Debugging enabled ?\nglobal _ENABLE_CM0\nif { [info exists ENABLE_CM0] } {\n\tset _ENABLE_CM0 $ENABLE_CM0\n} else {\n\tset _ENABLE_CM0 1\n}\n\n# Is CM4 Debugging enabled ?\nglobal _ENABLE_CM4\nif { [info exists ENABLE_CM4] } {\n\tset _ENABLE_CM4 $ENABLE_CM4\n} else {\n\tset _ENABLE_CM4 1\n}\n\nglobal _WORKAREASIZE_CM0\nif { [info exists WORKAREASIZE_CM0] } {\n\tset _WORKAREASIZE_CM0 $WORKAREASIZE_CM0\n} else {\n\tset _WORKAREASIZE_CM0 0x4000\n}\n\nglobal _WORKAREASIZE_CM4\nif { [info exists WORKAREASIZE_CM4] } {\n\tset _WORKAREASIZE_CM4 $WORKAREASIZE_CM4\n} else {\n\tset _WORKAREASIZE_CM4 0x4000\n}\n\nglobal _WORKAREAADDR_CM0\nif { [info exists WORKAREAADDR_CM0] } {\n\tset _WORKAREAADDR_CM0 $WORKAREAADDR_CM0\n} else {\n\tset _WORKAREAADDR_CM0 0x08000000\n}\n\nglobal _WORKAREAADDR_CM4\nif { [info exists WORKAREAADDR_CM4] } {\n\tset _WORKAREAADDR_CM4 $WORKAREAADDR_CM4\n} else {\n\tset _WORKAREAADDR_CM4 0x08000000\n}\n\nproc init_reset { mode } {\n\tglobal RESET_MODE\n\tset RESET_MODE $mode\n\n\tif {[using_jtag]} {\n\t\tjtag arp_init-reset\n\t}\n}\n\n# Utility to make 'reset halt' work as reset;halt on a target\n# It does not prevent running code after reset\nproc psoc6_deassert_post { target } {\n\t# PSoC6 cleared AP registers including TAR during reset\n\t# Force examine to synchronize OpenOCD target status\n\t$target arp_examine\n\n\tglobal RESET_MODE\n\tglobal TARGET\n\n\tif { $RESET_MODE ne \"run\" } {\n\t\t$target arp_poll\n\t\t$target arp_poll\n\t\tset st [$target curstate]\n\n\t\tif { $st eq \"reset\" } {\n\t\t\t# we assume running state follows\n\t\t\t# if reset accidentally halts, waiting is useless\n\t\t\tcatch { $target arp_waitstate running 100 }\n\t\t\tset st [$target curstate]\n\t\t}\n\n\t\tif { $st eq \"running\" } {\n\t\t\techo \"$target: Ran after reset and before halt...\"\n\t\t\tif { $target eq \"${TARGET}.cm0\" } {\n\t\t\t\t# Try to cleanly reset whole system\n\t\t\t\t# and halt the CM0 at entry point\n\t\t\t\tpsoc6 reset_halt\n\t\t\t\t$target arp_waitstate halted 100\n\t\t\t} else {\n\t\t\t\t$target arp_halt\n\t\t\t}\n\t\t}\n\t}\n}\n\nif { $_ENABLE_CM0 } {\n\ttarget create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\t${TARGET}.cm0 configure -work-area-phys $_WORKAREAADDR_CM0 -work-area-size $_WORKAREASIZE_CM0 -work-area-backup 0\n\n\tflash bank main_flash_cm0\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm0\n\tflash bank work_flash_cm0\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_user_cm0\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_nar_cm0\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_key_cm0\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_toc2_cm0\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm0\n\n\t${TARGET}.cm0 cortex_m reset_config sysresetreq\n\t${TARGET}.cm0 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm0\"\n}\n\nif { $_ENABLE_CM4 } {\n\ttarget create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\t${TARGET}.cm4 configure -work-area-phys $_WORKAREAADDR_CM4 -work-area-size $_WORKAREASIZE_CM4 -work-area-backup 0\n\n\tflash bank main_flash_cm4\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm4\n\tflash bank work_flash_cm4\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_user_cm4\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_nar_cm4\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_key_cm4\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_toc2_cm4\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm4\n\n\t${TARGET}.cm4 cortex_m reset_config vectreset\n\t${TARGET}.cm4 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm4\"\n}\n\nif { $_ENABLE_CM0 } {\n\t# Use CM0+ by default on dual-core devices\n\ttargets ${TARGET}.cm0\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 18 -expected-id 0x2e200069\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/pxa255.cfg",
    "content": "# PXA255 chip ... originally from Intel, PXA line was sold to Marvell.\n# This chip is now at end-of-life.  Final orders have been taken.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa255\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x69264013\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_CHIPNAME.cpu\n\n# PXA255 comes out of reset using 3.6864 MHz oscillator.\n# Until the PLL kicks in, keep the JTAG clock slow enough\n# that we get no errors.\nadapter speed 300\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 300 }\n\n# both TRST and SRST are *required* for debug\n# DCSR is often accessed with SRST active\nreset_config trst_and_srst separate srst_nogate\n\n# reset processing that works with PXA\nproc init_reset {mode} {\n\t# assert both resets; equivalent to power-on reset\n\tadapter assert trst assert srst\n\n\t# drop TRST after at least 32 cycles\n\tsleep 1\n\tadapter deassert trst assert srst\n\n\t# minimum 32 TCK cycles to wake up the controller\n\truntest 50\n\n\t# now the TAP will be responsive; validate scanchain\n\tjtag arp_init\n\n\t# ... and take it out of reset\n\tadapter deassert trst deassert srst\n}\n\nproc jtag_init {} {\n\tinit_reset startup\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/pxa270.cfg",
    "content": "#Marvell/Intel PXA270 Script\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa270\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n#IDs for pxa270. Are there more?\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x49265013\n}\n\nif { [info exists CPUTAPID2] } {\n   set _CPUTAPID2 $CPUTAPID2\n} else {\n  # set useful default\n   set _CPUTAPID2 0x79265013\n}\n\nif { [info exists CPUTAPID3] } {\n   set _CPUTAPID2 $CPUTAPID3\n} else {\n  # set useful default\n   set _CPUTAPID3 0x89265013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n# maps to PXA internal RAM. If you are using a PXA255\n# you must initialize SDRAM or leave this option off\n$_TARGETNAME configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/pxa3xx.cfg",
    "content": "# Marvell PXA3xx\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa3xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# IDs for all currently known PXA3xx chips\nif { [info exists CPUTAPID_PXA30X_A0] } {\n   set _CPUTAPID_PXA30X_A0 $CPUTAPID_PXA30X_A0\n} else {\n   set _CPUTAPID_PXA30X_A0 0x0E648013\n}\nif { [info exists CPUTAPID_PXA30X_A1] } {\n   set _CPUTAPID_PXA30X_A1 $CPUTAPID_PXA30X_A1\n} else {\n   set _CPUTAPID_PXA30X_A1 0x1E648013\n}\nif { [info exists CPUTAPID_PXA31X_A0] } {\n   set _CPUTAPID_PXA31X_A0 $CPUTAPID_PXA31X_A0\n} else {\n   set _CPUTAPID_PXA31X_A0 0x0E649013\n}\nif { [info exists CPUTAPID_PXA31X_A1] } {\n   set _CPUTAPID_PXA31X_A1 $CPUTAPID_PXA31X_A1\n} else {\n   set _CPUTAPID_PXA31X_A1 0x1E649013\n}\nif { [info exists CPUTAPID_PXA31X_A2] } {\n   set _CPUTAPID_PXA31X_A2 $CPUTAPID_PXA31X_A2\n} else {\n   set _CPUTAPID_PXA31X_A2 0x2E649013\n}\nif { [info exists CPUTAPID_PXA31X_B0] } {\n   set _CPUTAPID_PXA31X_B0 $CPUTAPID_PXA31X_B0\n} else {\n   set _CPUTAPID_PXA31X_B0 0x3E649013\n}\nif { [info exists CPUTAPID_PXA32X_B1] } {\n   set _CPUTAPID_PXA32X_B1 $CPUTAPID_PXA32X_B1\n} else {\n   set _CPUTAPID_PXA32X_B1 0x5E642013\n}\nif { [info exists CPUTAPID_PXA32X_B2] } {\n   set _CPUTAPID_PXA32X_B2 $CPUTAPID_PXA32X_B2\n} else {\n   set _CPUTAPID_PXA32X_B2 0x6E642013\n}\nif { [info exists CPUTAPID_PXA32X_C0] } {\n   set _CPUTAPID_PXA32X_C0 $CPUTAPID_PXA32X_C0\n} else {\n   set _CPUTAPID_PXA32X_C0 0x7E642013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 11 -ircapture 0x1 -irmask 0x7f \\\n\t-expected-id $_CPUTAPID_PXA30X_A0 \\\n\t-expected-id $_CPUTAPID_PXA30X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A0 \\\n\t-expected-id $_CPUTAPID_PXA31X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A2 \\\n\t-expected-id $_CPUTAPID_PXA31X_B0 \\\n\t-expected-id $_CPUTAPID_PXA32X_B1 \\\n\t-expected-id $_CPUTAPID_PXA32X_B2 \\\n\t-expected-id $_CPUTAPID_PXA32X_C0\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# work area in internal RAM.\n$_TARGETNAME configure -work-area-phys 0x5c030000 -work-area-size 0x10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/qualcomm_qca4531.cfg",
    "content": "# The QCA4531 is a two stream (2x2) 802.11b/g/n single-band programmable\n# Wi-Fi System-on-Chip (SoC) for the Internet of Things (IoT).\n#\n# Product page:\n# https://www.qualcomm.com/products/qca4531\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 650 MHz\n# - External 16-bit DDR1, operating at up to 200 MHz, DDR2 operating at up\n#   to 300 MHz\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin B56 on the SoC will reset internal JTAG logic.\n#\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO1, (B23)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO2, (A28)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO3, (A29)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (B56)\tInput only\n# SYS_RST_L\tGPIO17, (A79)\tOutput reset request or GPIO\n#   Bootstrap\n# JTAG_MODE\tGPIO16, (A78)\t0 - JTAG (Default); 1 - EJTAG\n# DDR_SELECT\tGPIO10, (A57)\t0 - DDR2; 1 - DDR1\n#   UART\n# UART0_SOUT\tGPIO10, (A57)\n# UART0_SIN\tGPIO9, (B49)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME qca4531\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\n# Section with helpers which can be used by boards\nproc qca4531_ddr2_550_550_init {} {\n\t# Clear reset flags for different SoC components\n\tmww 0xb806001c 0xfeceffff\n\tmww 0xb806001c 0xeeceffff\n\tmww 0xb806001c 0xe6ceffff\n\n\t# PMU configurations\n\t# Internal Switcher\n\tmww 0xb8116c40 0x633c8176\n\t# Increase the DDR voltage\n\tmww 0xb8116c44 0x10200000\n\t# XTAL Configurations\n\tmww 0xb81162c0 0x4b962100\n\tmww 0xb81162c4 0x480\n\tmww 0xb81162c8 0x04000144\n\t# Recommended PLL configurations\n\tmww 0xb81161c4 0x54086000\n\tmww 0xb8116244 0x54086000\n\n\t# PLL init\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x40001580\n\tmww 0xb8050004 0x40015800\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x00001580\n\tmww 0xb8050004 0x00015800\n\tmww 0xb8050008 0x01310000\n\tmww 0xb8050044 0x781003ff\n\tmww 0xb8050048 0x003c103f\n\n\t# DDR2 init\n\tmww 0xb8000108 0x401f0042\n\tmww 0xb80000b8 0x0000166d\n\tmww 0xb8000000 0xcfaaf33b\n\tmww 0xb800015c 0x0000000f\n\tmww 0xb8000004 0xa272efa8\n\tmww 0xb8000018 0x0000ffff\n\tmww 0xb80000c4 0x74444444\n\tmww 0xb80000c8 0x00000444\n\tmww 0xb8000004 0xa210ee28\n\tmww 0xb8000004 0xa2b2e1a8\n\tmww 0xb8000010 0x8\n\tmww 0xb80000bc 0x0\n\tmww 0xb8000010 0x10\n\tmww 0xb80000c0 0x0\n\tmww 0xb8000010 0x40\n\tmww 0xb800000c 0x2\n\tmww 0xb8000010 0x2\n\tmww 0xb8000008 0xb43\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\tmww 0xb8000008 0xa43\n\tmww 0xb8000010 0x1\n\tmww 0xb800000c 0x382\n\tmww 0xb8000010 0x2\n\tmww 0xb800000c 0x402\n\tmww 0xb8000010 0x2\n\tmww 0xb8000014 0x40be\n\tmww 0xb800001C 0x20\n\tmww 0xb8000020 0x20\n\tmww 0xb80000cc 0xfffff\n\n\t# UART GPIO programming\n\tmww 0xb8040000 0xff30b\n\tmww 0xb8040044 0x908\n\tmww 0xb8040034 0x160000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/quark_d20xx.cfg",
    "content": "if { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x38289013\n}\n\njtag newtap quark_d20xx quark -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable\njtag newtap quark_d20xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e786013 -enable\n\nproc quark_d20xx_tapenable {} {\n\techo \"enabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 1\n\truntest 10\n}\n\nproc quark_d20xx_tapdisable {} {\n\techo \"disabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 0\n\truntest 10\n}\n\nproc quark_d20xx_setup {} {\n\tjtag tapenable quark_d20xx.quark\n}\n\njtag configure quark_d20xx.quark -event tap-enable \\\n   \"quark_d20xx_tapenable\"\n\njtag configure quark_d20xx.quark -event tap-disable \\\n   \"quark_d20xx_tapdisable\"\n\ntarget create quark_d20xx.quark quark_d20xx -endian little -chain-position quark_d20xx.quark\n\nquark_d20xx.quark configure -event reset-start {\n\t# need to halt the target to write to memory\n\tif {[quark_d20xx.quark curstate] ne \"halted\"} { halt }\n\t# set resetbreak via the core tap\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x1\n\t# trigger a warm reset\n\tmww 0xb0800570 0x2\n\t# clear resetbreak\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x0\n}\n\njtag configure quark_d20xx.quark -event setup \\\n   \"quark_d20xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/quark_x10xx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME quark_x10xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x18289013\n}\n\njtag newtap quark_x10xx cpu   -irlen 8  -irmask 0xff  -expected-id   $_CPUTAPID  -disable\njtag newtap quark_x10xx cltap -irlen 8  -irmask 0xff  -expected-id   0x0e681013  -enable\n\n#openocd puts tap at front of chain not end of chain\nproc quark_x10xx_tapenable {} {\n\techo \"enabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 1\n\truntest 10\n}\n\nproc quark_x10xx_tapdisable {} {\n\techo \"disabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 0\n\truntest 10\n}\n\nproc quark_x10xx_setup {} {\n\tjtag tapenable quark_x10xx.cpu\n}\n\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"quark_x10xx_tapenable\"\n\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n   \"quark_x10xx_tapdisable\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create quark_x10xx.cpu quark_x10xx -endian $_ENDIAN -chain-position quark_x10xx.cpu\n\njtag configure $_CHIPNAME.cpu -event setup \\\n   \"quark_x10xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/readme.txt",
    "content": "Prerequisites:\nThe users of OpenOCD as well as computer programs interacting with OpenOCD are expecting that certain commands\ndo the same thing across all the targets.\n\nRules to follow when writing scripts:\n\n1. The configuration script should be defined such as , for example, the following sequences are working:\n\treset\n\tflash info <bank>\nand\n\treset\n\tflash erase_address <start> <len>\nand\n\treset init\n\tload\n\nIn most cases this can be accomplished by specifying the default startup mode as reset_init (target command\nin the configuration file).\n\n2. If the target is correctly configured, flash must be writable without any other helper commands. It is\nassumed that all write-protect mechanisms should be disabled.\n\n3. The configuration scripts should be defined such as the binary that was written to flash verifies\n(turn off remapping, checksums, etc...)\n\nflash write_image [file] <parameters>\nverify_image [file] <parameters>\n\n4. adapter speed sets the maximum speed (or alternatively RCLK). If invoked\nmultiple times only the last setting is used.\n\ninterface/xxx.cfg files are always executed *before* target/xxx.cfg\nfiles, so any adapter speed in interface/xxx.cfg will be overridden by\ntarget/xxx.cfg. adapter speed in interface/xxx.cfg would then, effectively,\nset the default JTAG speed.\n\nNote that a target/xxx.cfg file can invoke another target/yyy.cfg file,\nso one can create target subtype configurations where e.g. only\namount of DRAM, oscillator speeds differ and having a single\nconfig file for the default/common settings.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_r7s72100.cfg",
    "content": "# Renesas RZ/A1H\n# https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME r7s72100\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\n\n# Configuring only one core using DAP.\n# Base addresses of cores:\n#  core 0  -  0x80030000\nset _TARGETNAME $_CHIPNAME.ca9\ndap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME} cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x80030000\n\ntargets ${_TARGETNAME}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_rcar_gen2.cfg",
    "content": "# Renesas R-Car Generation 2 SOCs\n# - There are a combination of Cortex-A15s and Cortex-A7s for each Gen2 SOC\n# - Each SOC can boot through any of the, up to 2, core types that it has\n#   e.g. H2 can boot through Cortex-A15 or Cortex-A7\n\n# Supported Gen2 SOCs and their cores:\n# H2:  Cortex-A15 x 4, Cortex-A7 x 4\n# M2:  Cortex-A15 x 2\n# V2H: Cortex-A15 x 2\n# M2N: Cortex-A15 x 2\n# E2:                  Cortex-A7 x 2\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H2')\n# BOOT_CORE: Selects the booting core. 'CA15', or 'CA7'\n#            Defaults to 'CA15' if the SOC has one, else defaults to 'CA7'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H2\n}\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH2 {\n\t\tset _CHIPNAME r8a7790\n\t\tset _num_ca15 4\n\t\tset _num_ca7 4\n\t\tset _boot_core CA15\n\t}\n\tM2 {\n\t\tset _CHIPNAME r8a7791\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tV2H {\n\t\tset _CHIPNAME r8a7792\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tM2N {\n\t\tset _CHIPNAME r8a7793\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tE2 {\n\t\tset _CHIPNAME r8a7794\n\t\tset _num_ca15 0\n\t\tset _num_ca7 2\n\t\tset _boot_core CA7\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\necho \"\\t$_soc - $_num_ca15 CA15(s), $_num_ca7 CA7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000}\nset CA7_DBGBASE  {0x800F0000 0x800F2000 0x800F4000 0x800F6000}\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_ca {core_name dbgbase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tset _command \"target create $_TARGETNAME cortex_a -dap $_DAPNAME \\\n\t\t\t-coreid $_core -dbgbase [lindex $dbgbase $_core]\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA15] } {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 1\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n} elseif { [string equal $_boot_core CA7] } {\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 1\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n} else {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_rcar_gen3.cfg",
    "content": "# Renesas R-Car Generation 3 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, and Cortex-R7 for each Gen3 SOC\n# - Each SOC can boot through any of the, up to 3, core types that it has\n#   e.g. H3 can boot through Cortex-A57, Cortex-A53, or Cortex-R7\n\n# Supported Gen3 SOCs and their cores:\n#  H3: Cortex-A57 x 4, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3W: Cortex-A57 x 2, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3N: Cortex-A57 x 2,                 Cortex-R7 x 2 (Lock-Step)\n# V3U:                 Cortex-A76 x 8, Cortex-R52 x2 (Lock-Step)\n# V3H:                 Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# V3M:                 Cortex-A53 x 2, Cortex-R7 x 2 (Lock-Step)\n#  E3:                 Cortex-A53 x 1, Cortex-R7 x 2 (Lock-Step)\n#  D3:                 Cortex-A53 x 1\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H3')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53', or 'CR7'\n#            Defaults to 'CA57' if the SOC has one, else defaults to 'CA53'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H3\n}\n\nset _num_ca53 0\nset _num_ca57 0\nset _num_ca76 0\nset _num_cr52 0\nset _num_cr7 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH3 {\n\t\tset _CHIPNAME r8a77950\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3W {\n\t\tset _CHIPNAME r8a77960\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3N {\n\t\tset _CHIPNAME r8a77965\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tV3M {\n\t\tset _CHIPNAME r8a77970\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tV3H {\n\t\tset _CHIPNAME r8a77980\n\t\tset _num_ca57 0\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tE3 {\n\t\tset _CHIPNAME r8a77990\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tD3 {\n\t\tset _CHIPNAME r8a77995\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 0\n\t\tset _boot_core CA53\n\t}\n\tV3U {\n\t\tset _CHIPNAME r8a779a0\n\t\tset _num_ca76 8\n\t\tset _num_cr52 1\n\t\tset _boot_core CA76\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\necho \"\\t$_soc - $_num_ca76 CA76(s), $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr52 CR52(s), $_num_cr7 CR7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA76_DBGBASE {0x81410000 0x81510000 0x81610000 0x81710000 0x81c10000 0x81d10000 0x81e10000 0x81f10000}\nset CA76_CTIBASE {0x81420000 0x81520000 0x81620000 0x81720000 0x81c20000 0x81d20000 0x81e20000 0x81f20000}\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset CR52_DBGBASE 0x80c10000\nset CR52_CTIBASE 0x80c20000\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\tset _command \"target create $_TARGETNAME aarch64 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\nproc setup_cr7 {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase\n\t\tset _command \"target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase $dbgbase\"\n\t\tif { $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA76] } {\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 1\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 0\n} elseif { [string equal $_boot_core CA57] } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CA53] } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CR52] } {\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 1\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 0\n} else {\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_rcar_reset_common.cfg",
    "content": "# Renesas R-Car Gen2 Evaluation Board common settings\n\nreset_config trst_and_srst srst_nogate\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_rz_five.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/Five SoC\n#\n# General-purpose Microprocessors with RISC-V CPU Core (Andes AX45MP Single) (1.0 GHz)\n\ntransport select jtag\n\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME r9A07g043u\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_rz_g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/G2 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, Cortex-A55, Cortex-R7\n# and Cortex-M33 for each SOC\n# - Each SOC can boot through the Cortex-A5x cores\n\n# Supported RZ/G2 SOCs and their cores:\n# RZ/G2H:   Cortex-A57 x4, Cortex-A53 x4, Cortex-R7\n# RZ/G2M:   Cortex-A57 x2, Cortex-A53 x4, Cortex-R7\n# RZ/G2N:   Cortex-A57 x2,                Cortex-R7\n# RZ/G2E:                  Cortex-A53 x2, Cortex-R7\n# RZ/G2L:                  Cortex-A55 x2, Cortex-M33\n# RZ/G2LC:                 Cortex-A55 x2, Cortex-M33\n# RZ/G2UL:                 Cortex-A55 x1, Cortex-M33\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'G2L')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53' or 'CA55'\n\ntransport select jtag\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc G2L\n}\n\nset _num_ca57 0\nset _num_ca55 0\nset _num_ca53 0\nset _num_cr7 0\nset _num_cm33 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tG2H {\n\t\tset _CHIPNAME r8a774ex\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2M {\n\t\tset _CHIPNAME r8a774ax\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2N {\n\t\tset _CHIPNAME r8a774bx\n\t\tset _num_ca57 2\n\t\tset _num_ca53 0\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2E {\n\t\tset _CHIPNAME r8a774c0\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t\tset _ap_num 1\n\t}\n\tG2L {\n\t\tset _CHIPNAME r9a07g044l\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2LC {\n\t\tset _CHIPNAME r9a07g044c\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2UL {\n\t\tset _CHIPNAME r9a07g043u\n\t\tset _num_ca55 1\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\necho \"\\t$_soc - $_num_ca57 CA57(s), $_num_ca55 CA55(s), $_num_ca53 CA53(s), $_num_cr7 CR7(s), \\\n\t$_num_cm33 CM33(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID \\\n\t-ignore-version\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\necho \"$_CHIPNAME.cpu\"\n\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA55_DBGBASE {0x10E10000 0x10F10000}\nset CA55_CTIBASE {0x10E20000 0x10F20000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\nset CM33_DBGBASE 0xE000E000\nset CM33_CTIBASE 0xE0042000\n\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $::_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $::_DAPNAME -ap-num $::_ap_num \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\ttarget create $_TARGETNAME aarch64 -dap $::_DAPNAME \\\n\t\t\t-ap-num $::_ap_num -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\n\t\tif { $_core > 0 || $boot == 0 } {\n\t\t\t$_TARGETNAME configure -defer-examine\n\t\t}\n\t\tset ::smp_targets \"$::smp_targets $_TARGETNAME\"\n\t}\n}\n\nproc setup_cr7 {dbgbase ctibase} {\n\tset _TARGETNAME $::_CHIPNAME.r7\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $::_DAPNAME -ap-num 1 -baseaddr $ctibase\n\ttarget create $_TARGETNAME cortex_r4 -dap $::_DAPNAME \\\n\t\t-ap-num 1 -dbgbase $dbgbase -defer-examine\n}\n\nproc setup_cm33 {dbgbase ctibase} {\n        set _TARGETNAME $::_CHIPNAME.m33\n        set _CTINAME $_TARGETNAME.cti\n        cti create $_CTINAME -dap $::_DAPNAME -ap-num 2 -baseaddr $ctibase\n        target create $_TARGETNAME cortex_m -dap $::_DAPNAME \\\n                -ap-num 2 -dbgbase $dbgbase -defer-examine\n}\n\n# Organize target list based on the boot core\nif { $_boot_core == \"CA57\" } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA53\" } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA55\" } {\n\tsetup_a5x a55 $CA55_DBGBASE $CA55_CTIBASE $_num_ca55 1\n\tsetup_cm33 $CM33_DBGBASE $CM33_CTIBASE\n}\necho \"SMP targets:$smp_targets\"\neval \"target smp $smp_targets\"\n\nif { $_soc == \"G2L\" || $_soc == \"G2LC\" || $_soc == \"G2UL\" } {\n\ttarget create $_CHIPNAME.axi_ap mem_ap -dap $_DAPNAME -ap-num 1\n}\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/renesas_s7g2.cfg",
    "content": "#\n# Renesas Synergy S7 G2 w/ ARM Cortex-M4 @ 240 MHz\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME s7g2\n}\n\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x5ba00477\n}\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x5ba02477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\t# 640 KB On-Chip SRAM\n\tset _WORKAREASIZE 0xa0000\n}\n\n$_TARGETNAME configure -work-area-phys 0x1ffe0000 \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/rk3308.cfg",
    "content": "# Rockchip RK3308 Target\n# https://rockchip.fr/RK3308%20datasheet%20V1.5.pdf\n# https://dl.radxa.com/rockpis/docs/hw/datasheets/Rockchip%20RK3308TRM%20V1.1%20Part1-20180810.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3308\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x2ba01477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.core\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x81010000\nset $_TARGETNAME.base(1) 0x81012000\nset $_TARGETNAME.base(2) 0x81014000\nset $_TARGETNAME.base(3) 0x81016000\n\nset $_TARGETNAME.cti(0) 0x81018000\nset $_TARGETNAME.cti(1) 0x81019000\nset $_TARGETNAME.cti(2) 0x8101a000\nset $_TARGETNAME.cti(3) 0x8101b000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\"\n\n    if { $_core != 0 } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n        set _command \"$_command -defer-examine\"\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # set _command \"$_command -rtos hwthread\"\n        set _command \"$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 \\\n                                -work-area-backup 0\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/rk3399.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Rockchip RK3399 Target\n# https://rockchip.fr/RK3399%20datasheet%20V1.8.pdf\n# https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.4%20Part1.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3399\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba02477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\nset _TARGETNAME $_CHIPNAME.lcore\n# declare the 6 main application cores\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x80030000\nset $_TARGETNAME.base(1) 0x80032000\nset $_TARGETNAME.base(2) 0x80034000\nset $_TARGETNAME.base(3) 0x80036000\nset $_TARGETNAME.cti(0) 0x80038000\nset $_TARGETNAME.cti(1) 0x80039000\nset $_TARGETNAME.cti(2) 0x8003a000\nset $_TARGETNAME.cti(3) 0x8003b000\n\n\nset _TARGETNAME $_CHIPNAME.bcore\nset $_TARGETNAME.base(4) 0x80210000\nset $_TARGETNAME.base(5) 0x80310000\nset $_TARGETNAME.cti(4) 0x80220000\nset $_TARGETNAME.cti(5) 0x80320000\n\nset _cores 6\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n    if {$_core < 4} {\n        set _TARGETNAME $_CHIPNAME.lcore\n    } else {\n        set _TARGETNAME $_CHIPNAME.bcore\n    }\n\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1\n\n    target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\n\n    if { $_core != 0 } {\n        ${_TARGETNAME}$_core configure -defer-examine\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # ${_TARGETNAME}$_core configure -rtos hwthread\"\n        ${_TARGETNAME}$_core configure -work-area-size 0x30000 -work-area-phys 0xff8c0000 \\\n                                -work-area-backup 0\n    }\n    set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n}\n\ntarget smp $_smp_command\n\ntargets rk3399.lcore0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/rp2040-core0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\ntransport select swd\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME rp2040\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x01002927\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nset _FLASHSIZE 0x200000\nset _FLASHBASE 0x10000000\nflash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n\n# srst does not exist; use SYSRESETREQ to perform a soft reset\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/samsung_s3c2410.cfg",
    "content": "# Found on the 'TinCanTools' Hammer board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that cannot set TRST/SRST separately\nreset_config trst_and_srst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x30800000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/samsung_s3c2440.cfg",
    "content": "# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor       : ARM920Tid(wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/samsung_s3c2450.cfg",
    "content": "# Target configuration for the Samsung 2450 system on chip\n# Processor       : ARM926ejs (wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2450.cpu tap/device found: 0x07926F0F\n\n\n# FIX!!! what to use here?\n#\n# RCLK?\n#\n# adapter speed 0\n#\n# Really low clock during reset?\n#\n# adapter speed 1\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME s3c2450\n}\n\nif { [info exists ENDIAN] } {\n  set _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n  set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n  set _CPUTAPID $CPUTAPID\n} else {\n  set _CPUTAPID 0x07926f0f\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xE -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# FIX!!!!! should this really use srst_pulls_trst?\n# With srst_pulls_trst \"reset halt\" will not reset into the\n# halted mode, but rather \"reset run\" and then halt the target.\n#\n# However, without \"srst_pulls_trst\", then \"reset halt\" produces weird\n# errors:\n# WARNING: unknown debug reason: 0x0\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/samsung_s3c4510.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c4510\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# This appears to be a \"Version 1\" arm7tdmi.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/samsung_s3c6410.cfg",
    "content": "# -*- tcl -*-\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n# [Duane Ellis 27/nov/2008: Above 0x0032409d appears to be copy/paste from other places]\n# [and I do not believe it to be accurate, hence the 0xffffffff below]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c6410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b76f0f\n}\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nadapter srst delay 500\njtag_ntrst_delay 500\n\n#reset configuration\nreset_config trst_and_srst\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/sharp_lh79532.cfg",
    "content": "reset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lh79532\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # sharp changed the number!\n   set _CPUTAPID 0x00002061\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/sim3x.cfg",
    "content": "#\n# Silicon Laboratories SiM3x Cortex-M3\n#\n\n# SiM3x devices support both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME SiM3x\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nif { [info exists CPURAMSIZE] } {\n  set _CPURAMSIZE $CPURAMSIZE\n} else {\n# Minimum size of RAM in the Silicon Labs product matrix (8KB)\n\tset _CPURAMSIZE 0x2000\n}\n\nif { [info exists CPUROMSIZE] } {\n  set _CPUROMSIZE $CPUROMSIZE\n} else {\n# Minimum size of FLASH in the Silicon Labs product matrix (32KB)\n\tset _CPUROMSIZE 0x8000\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE $_CPURAMSIZE\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/smp8634.cfg",
    "content": "# script for Sigma Designs SMP8634 (eventually even SMP8635)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME smp8634\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x08630001\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/snps_em_sk_fpga.cfg",
    "content": "#  Copyright (C) 2014-2015,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xilinx Spartan-6 XC6SLX45  FPGA on EM Starter Kit v1.\n# Xilinx Spartan-6 XC6SLX150 FPGA on EM Starter Kit v2.\n#\n\nsource [find cpu/arc/em.tcl]\n\nset _CHIPNAME arc-em\nset _TARGETNAME $_CHIPNAME.cpu\n\n# EM SK IDENTITY is 0x200444b1\n# EM SK v2 IDENTITY is 0x200044b1\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -expected-id 0x200444b1 \\\n  -expected-id 0x200044b1\n\nset _coreid 0\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME \\\n  -coreid 0 -dbgbase $_dbgbase -endian little\n\n# There is no SRST, so do a software reset\n$_TARGETNAME configure -event reset-assert \"arc_em_reset $_TARGETNAME\"\n\narc_em_init_regs\n\n# vim:ft=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# HS Development Kit SoC.\n#\n# Contains quad-core ARC HS38.\n#\n\nsource [find cpu/arc/hs.tcl]\n\nset _coreid 0\nset _dbgbase [expr {$_coreid << 13}]\n\n# CHIPNAME will be used to choose core family (600, 700 or EM). As far as\n# OpenOCD is concerned EM and HS are identical.\nset _CHIPNAME arc-em\n\n# OpenOCD discovers JTAG TAPs in reverse order.\n\n# ARC HS38 core 4\nset _TARGETNAME $_CHIPNAME.cpu4\njtag newtap $_CHIPNAME cpu4 -irlen 4 -ircapture 0x1 -expected-id 0x200c24b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n# Flush L2$.\n$_TARGETNAME configure -event reset-assert \"arc_hs_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 4.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 3\nset _TARGETNAME $_CHIPNAME.cpu3\njtag newtap $_CHIPNAME cpu3 -irlen 4 -ircapture 0x1 -expected-id 0x200824b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 3.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 2\nset _TARGETNAME $_CHIPNAME.cpu2\njtag newtap $_CHIPNAME cpu2 -irlen 4 -ircapture 0x1 -expected-id 0x200424b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 2.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 1\nset _TARGETNAME $_CHIPNAME.cpu1\njtag newtap $_CHIPNAME cpu1 -irlen 4 -ircapture 0x1 -expected-id 0x200024b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\narc_hs_init_regs\n\n# Enable L2 cache support for core 1.\n$_TARGETNAME arc cache l2 auto 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/spear3xx.cfg",
    "content": "# Target configuration for the ST SPEAr3xx family of system on chip\n# Supported SPEAr300, SPEAr310, SPEAr320\n# http://www.st.com/spear\n#\n# Processor: ARM926ejs\n# Info:      JTAG tap: spear3xx.cpu tap/device found: 0x07926041\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME spear3xx\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x07926041\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 \\\n\t-expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# SPEAr3xx has a 8K block of sram @ 0xd280.0000\n# REVISIT: what OS puts virtual address equal to phys?\n$_TARGETNAME configure \\\n\t-work-area-virt 0xd2800000 \\\n\t-work-area-phys 0xd2800000 \\\n\t-work-area-size 0x2000 \\\n\t-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stellaris.cfg",
    "content": "# TI/Luminary Stellaris LM3S chip family\n\n# Some devices have errata in returning their device class.\n# DEVICECLASS is provided as a manual override\n# Manual setting of a device class of 0xff is not allowed\n\nglobal _DEVICECLASS\n\nif { [info exists DEVICECLASS] } {\n   set _DEVICECLASS $DEVICECLASS\n} else {\n   set _DEVICECLASS 0xff\n}\n\n# Luminary chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# For now we ignore the SPI and UART options, which\n# are usable only for ISP style initial flash programming.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lm3s\n}\n\n# CPU TAP ID 0x1ba00477 for early Sandstorm parts\n# CPU TAP ID 0x2ba00477 for later SandStorm parts, e.g. lm3s811 Rev C2\n# CPU TAP ID 0x3ba00477 for Cortex-M3 r1p2 (on Fury, DustDevil)\n# CPU TAP ID 0x4ba00477 for Cortex-M3 r2p0 (on Tempest, Firestorm)\n# CPU TAP ID 0x4ba00477 for Cortex-M4 r0p1 (on Blizzard)\n# ... we'll ignore the JTAG version field, rather than list every\n# chip revision that turns up.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0ba00477\n}\n\n# SWD DAP, and JTAG TAP, take same params for now;\n# ... even though SWD ignores all except TAPID, and\n# JTAG shouldn't need anything more then irlen. (and TAPID).\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf \\\n    -expected-id $_CPUTAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   # default to 2K working area\n   set _WORKAREASIZE 0x800\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# 8K working area at base of ram, not backed up\n#\n# NOTE: you may need or want to reconfigure the work area;\n# some parts have just 6K, and you may want to use other\n# addresses (at end of mem not beginning) or back it up.\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\n# JTAG speed ... slow enough to work with a 12 MHz RC oscillator;\n# LM3S parts don't support RTCK\n#\n# NOTE: this may be increased by a reset-init handler, after it\n# configures and enables the PLL.  Or you might need to decrease\n# this, if you're using a slower clock.\nadapter speed 500\n\nsource [find mem_helper.tcl]\n\nproc reset_peripherals {family} {\n\n\tsource [find chip/ti/lm3s/lm3s.tcl]\n\n\techo \"Resetting Core Peripherals\"\n\n\t# Disable the PLL and the system clock divider (nop if disabled)\n\tmmw $SYSCTL_RCC 0 $SYSCTL_RCC_USESYSDIV\n\tmmw $SYSCTL_RCC2 $SYSCTL_RCC2_BYPASS2 0\n\n\t# RCC and RCC2 to their reset values\n\tmww $SYSCTL_RCC [expr {0x078e3ad0 | ([mrw $SYSCTL_RCC] & $SYSCTL_RCC_MOSCDIS)}]\n\tmww $SYSCTL_RCC2 0x07806810\n\tmww $SYSCTL_RCC 0x078e3ad1\n\n\t# Reset the deep sleep clock configuration register\n\tmww $SYSCTL_DSLPCLKCFG 0x07800000\n\n\t# Reset the clock gating registers\n\tmww $SYSCTL_RCGC0 0x00000040\n\tmww $SYSCTL_RCGC1 0\n\tmww $SYSCTL_RCGC2 0\n\tmww $SYSCTL_SCGC0 0x00000040\n\tmww $SYSCTL_SCGC1 0\n\tmww $SYSCTL_SCGC2 0\n\tmww $SYSCTL_DCGC0 0x00000040\n\tmww $SYSCTL_DCGC1 0\n\tmww $SYSCTL_DCGC2 0\n\n\t# Reset the remaining SysCtl registers\n\tmww $SYSCTL_PBORCTL 0\n\tmww $SYSCTL_IMC 0\n\tmww $SYSCTL_GPIOHBCTL 0\n\tmww $SYSCTL_MOSCCTL 0\n\tmww $SYSCTL_PIOSCCAL 0\n\tmww $SYSCTL_I2SMCLKCFG 0\n\n\t# Reset the peripherals\n\tmww $SYSCTL_SRCR0 0xffffffff\n\tmww $SYSCTL_SRCR1 0xffffffff\n\tmww $SYSCTL_SRCR2 0xffffffff\n\tmww $SYSCTL_SRCR0 0\n\tmww $SYSCTL_SRCR1 0\n\tmww $SYSCTL_SRCR2 0\n\n\t# Clear any pending SysCtl interrupts\n\tmww $SYSCTL_MISC 0xffffffff\n\n\t# Wait for any pending flash operations to complete\n\twhile {[expr {[mrw $FLASH_FMC] & 0xffff}] != 0} { sleep 1 }\n\twhile {[expr {[mrw $FLASH_FMC2] & 0xffff}] != 0} { sleep 1 }\n\n\t# Reset the flash controller registers\n\tmww $FLASH_FMA 0\n\tmww $FLASH_FCIM 0\n\tmww $FLASH_FCMISC 0xffffffff\n\tmww $FLASH_FWBVAL 0\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 500\n\n\t#\n\t# When nRST is asserted on most Stellaris devices, it clears some of\n\t# the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;\n\t# and OpenOCD depends on those TRMs.  So we won't use SRST on those\n\t# chips.  (Only power-on reset should affect debug state, beyond a\n\t# few specified bits; not the chip's nRST input, wired to SRST.)\n\t#\n\t# REVISIT current errata specs don't seem to cover this issue.\n\t# Do we have more details than this email?\n\t#   https://lists.berlios.de/pipermail\n\t#\t/openocd-development/2008-August/003065.html\n\t#\n\n\tglobal _DEVICECLASS\n\n\tif {$_DEVICECLASS != 0xff} {\n\t   set device_class $_DEVICECLASS\n\t} else {\n\t   set device_class [expr {([mrw 0x400fe000] >> 16) & 0xff}]\n\t}\n\n\tif {$device_class == 0 || $device_class == 1 ||\n\t\t$device_class == 3 || $device_class == 5 || $device_class == 0xa} {\n\t\tif {![using_hla]} {\n\t\t   # Sandstorm, Fury, DustDevil, Blizzard and Snowflake are able to use NVIC SYSRESETREQ\n\t\t   cortex_m reset_config sysresetreq\n\t\t}\n\t} else {\n\t\tif {![using_hla]} {\n\t\t   # Tempest and Firestorm default to using NVIC VECTRESET\n\t\t   # peripherals will need resetting manually, see proc reset_peripherals\n\t\t   cortex_m reset_config vectreset\n\t\t}\n\t\t# reset peripherals, based on code in\n\t\t# http://www.ti.com/lit/er/spmz573a/spmz573a.pdf\n\t\treset_peripherals $device_class\n\t}\n}\n\n# flash configuration ... autodetects sizes, autoprobed\nflash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f0x.cfg",
    "content": "# script for stm32f0x family\n\n#\n# stm32 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n\tset _FLASH_SIZE $FLASH_SIZE\n} else {\n\t# autodetect size\n\tset _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # See STM Document RM0091\n  # Section 29.5.3\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f0x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f0x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\n\t# Stop watchdog counters during halt\n\tmmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f0x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 6 (48 MHz)\n\tmww 0x40021004 0x00100000   ;# RCC_CFGR = PLLMUL[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON\n\tmww 0x40022000 0x00000011   ;# FLASH_ACR = PRFTBE | LATENCY[0]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f1x.cfg",
    "content": "# script for stm32f1x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f1x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some STM32F100s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0008 Section 26.6.3\n      set _CPUTAPID 0x3ba00477\n   } {\n      # this is the SW-DP tap id not the jtag tap id\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |\n\t#              DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000307 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f2x.cfg",
    "content": "# script for stm32f2x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f2x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0033\n      # Section 32.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f3x.cfg",
    "content": "# script for stm32f3x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f3x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0316\n      # Section 29.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f3x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f3x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\n\t# Stop watchdog counters during halt\n\tmmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f3x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 8 (64 MHz)\n\tmww 0x40021004 0x00380400   ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON\n\tmww 0x40022000 0x00000012   ;# FLASH_ACR = PRFTBE | LATENCY[1]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init }\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xe0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f4x.cfg",
    "content": "# script for stm32f4x family\n\n#\n# stm32f4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (Available RAM in smallest device STM32F410)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0090\n      # Section 38.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x40021000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x40021008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x40021000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x40021008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x40021000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x40021008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure PLL to boost clock to HSI x 4 (64 MHz)\n\tmww 0x40023804 0x08012008   ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P)\n\tmww 0x40023C00 0x00000102   ;# FLASH_ACR = PRFTBE | 2(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32f7x.cfg",
    "content": "# script for stm32f7x family\n\n#\n# stm32f7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f7x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 128kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x20000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0385\n      # Section 40.6.3 - corresponds to Cortex-M7 with FPU r0p0\n      set _CPUTAPID 0x5ba00477\n   } {\n      set _CPUTAPID 0x5ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1ff0f000 0 0 0 $_TARGETNAME\n\n# On the STM32F7, the Flash is mapped at address 0x08000000 via the AXI and\n# also address 0x00200000 via the ITCM. The former mapping is read-write in\n# hardware, while the latter is read-only. By presenting an alias, we\n# accomplish two things:\n# (1) We allow writing at 0x00200000 (because the alias acts identically to the\n#     original bank), which allows code intended to run from that address to\n#     also be linked for loading at that address, simplifying linking.\n# (2) We allow the proper memory map to be delivered to GDB, which will cause\n#     it to use hardware breakpoints at the 0x00200000 mapping (correctly\n#     identifying it as Flash), which it would otherwise not do. Configuring\n#     the Flash via ITCM alias as virtual\nflash bank $_CHIPNAME.itcm-flash.alias virtual 0x00200000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# Use hardware reset.\n#\n# This target is compatible with connect_assert_srst, which may be set in a\n# board file.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# If the HSE was previously enabled and the external clock source\n\t# disappeared, RCC_CR.HSERDY can get stuck at 1 and the PLL cannot be\n\t# properly switched back to HSI. This situation persists even over a system\n\t# reset, including a pin reset via SRST. However, activating the clock\n\t# security system will detect the problem and clear HSERDY to 0, which in\n\t# turn allows the PLL to switch back to HSI properly. Since we just came\n\t# out of reset, HSEON should be 0. If HSERDY is 1, then this situation must\n\t# have happened; in that case, activate the clock security system to clear\n\t# HSERDY.\n\tif {[mrw 0x40023800] & 0x00020000} {\n\t\tmmw 0x40023800 0x00090000 0 ;# RCC_CR = CSSON | HSEON\n\t\tsleep 10                    ;# Wait for CSS to fire, if it wants to\n\t\tmmw 0x40023800 0 0x00090000 ;# RCC_CR &= ~CSSON & ~HSEON\n\t\tmww 0x4002380C 0x00800000   ;# RCC_CIR = CSSC\n\t\tsleep 1                     ;# Wait for CSSF to clear\n\t}\n\n\t# If the clock security system fired, it will pend an NMI. A pending NMI\n\t# will cause a bad time for any subsequent executing code, such as a\n\t# programming algorithm.\n\tif {[mrw 0xE000ED04] & 0x80000000} {\n\t\t# ICSR.NMIPENDSET reads as 1. Need to clear it. A pending NMI can’t be\n\t\t# cleared by any normal means (such as ICSR or NVIC). It can only be\n\t\t# cleared by entering the NMI handler or by resetting the processor.\n\t\techo \"[target current]: Clock security system generated NMI. Clearing.\"\n\n\t\t# Keep the old DEMCR value.\n\t\tset old [mrw 0xE000EDFC]\n\n\t\t# Enable vector catch on reset.\n\t\tmww 0xE000EDFC 0x01000001\n\n\t\t# Issue local reset via AIRCR.\n\t\tmww 0xE000ED0C 0x05FA0001\n\n\t\t# Restore old DEMCR value.\n\t\tmww 0xE000EDFC $old\n\t}\n\n\t# Configure PLL to boost clock to HSI x 10 (160 MHz)\n\tmww 0x40023804 0x08002808   ;# RCC_PLLCFGR 16 Mhz /10 (M) * 128 (N) /2(P)\n\tmww 0x40023C00 0x00000107   ;# FLASH_ACR = PRFTBE | 7(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmww 0x40023808 0x00009400   ;# RCC_CFGR_PPRE1 = 5(div 4), PPRE2 = 4(div 2)\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost SWD frequency\n\t# Do not boost JTAG frequency and slow down JTAG memory access or flash write algo\n\t# suffers from DAP WAITs\n\tif {[using_jtag]} {\n\t\t[[target current] cget -dap] memaccess 16\n\t} {\n\t\tadapter speed 8000\n\t}\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32g0x.cfg",
    "content": "# script for stm32g0x family\n\n#\n# stm32g0 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x1000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# Section 37.5.5 - corresponds to Cortex-M0+\n\tset _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32g0x_default_reset_start {} {\n\t# Reset clock is HSI16 (16 MHz)\n\tadapter speed 2000\n}\n\nproc stm32g0x_default_examine_end {} {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0x40015804 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n\nproc stm32g0x_default_reset_init {} {\n\t# Increase clock to 64 Mhz\n\tmmw 0x40022000 0x00000002 0x00000005\t;# FLASH_ACR: Latency = 2\n\tmww 0x4002100C 0x30000802\t\t\t\t;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2\n\tmmw 0x40021000 0x01000000 0x00000000\t;# RCC_CR |= PLLON\n\tmmw 0x40021008 0x00000002 0x00000005\t;# RCC_CFGR: SW=PLLRCLK\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32g4x.cfg",
    "content": "# script for stm32g4x family\n\n#\n# stm32g4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest current target has 32kB ram, use 16kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# See STM Document RM0440\n\t\t# Section 46.6.3 - corresponds to Cortex-M4 r0p1\n\t\tset _CPUTAPID 0x4ba00477\n\t} {\n\t\tset _CPUTAPID 0x2ba01477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n\tset a [llength [flash list]]\n\tset _QSPINAME $_CHIPNAME.qspi\n\tflash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with HSION | HSIRDY.\n\t# Use HSI 16 MHz clock, compliant even with VOS == 2.\n\t# 1 WS compliant with VOS == 2 and 16 MHz.\n\tmmw 0x40022000 0x00000001 0x0000000E\t;# FLASH_ACR: Latency = 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# RCC_CR |= HSION\n\tmmw 0x40021008 0x00000001 0x00000002\t;# RCC_CFGR: SW=HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is HSI (16 MHz)\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32h7x.cfg",
    "content": "# script for stm32h7x family\n\n#\n# stm32h7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32h7x\n}\n\nif { [info exists DUAL_BANK] } {\n\tset $_CHIPNAME.DUAL_BANK $DUAL_BANK\n\tunset DUAL_BANK\n} else {\n\tset $_CHIPNAME.DUAL_BANK 0\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists USE_CTI] } {\n\tset $_CHIPNAME.USE_CTI $USE_CTI\n\tunset USE_CTI\n} else {\n\tset $_CHIPNAME.USE_CTI 0\n}\n\n# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0\nif { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } {\n\techo \"Warning : could not use CTI with a single core device, CTI is disabled\"\n\tset $_CHIPNAME.USE_CTI 0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n\t  set _CPUTAPID 0x6ba00477\n   } {\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nif {![using_hla]} {\n\t# STM32H7 provides an APB-AP at access port 2, which allows the access to\n\t# the debug and trace features on the system APB System Debug Bus (APB-D).\n\ttarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\n\tswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00E3000\n\ttpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00F5000\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0\n\n$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0\n\nif {[set $_CHIPNAME.DUAL_BANK]} {\n\tflash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3\n\n\t$_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {[set $_CHIPNAME.DUAL_BANK]} {\n\t\tflash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1\n\t}\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_CHIPNAME.cpu0 0x5200A000\n   }\n}\n\n# Clock after reset is HSI at 64 MHz, no need of PLL\nadapter speed 1800\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# use hardware reset\n#\n# The STM32H7 does not support connect_assert_srst mode because the AXI is\n# unavailable while SRST is asserted, and that is used to access the DBGMCU\n# component at 0x5C001000 in the examine-end event handler.\n#\n# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead\n# of the default AP0, and that works with SRST asserted; however, nonzero AP\n# usage does not work with HLA, so is not done by default. That change could be\n# made in a local configuration file if connect_assert_srst mode is needed for\n# a specific application and a non-HLA adapter is in use.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n\n\tif {[set $_CHIPNAME.DUAL_CORE]} {\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable D3 and D1 DBG clocks\n\t# DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00600000 0\n\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D1 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000007 0\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D2 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000038 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB3FZ1 |= WWDG1\n\tstm32h7x_dbgmcu_mmw 0x034 0x00000040 0\n\t# DBGMCU_APB1LFZ1 |= WWDG2\n\tstm32h7x_dbgmcu_mmw 0x03C 0x00000800 0\n\t# DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2\n\tstm32h7x_dbgmcu_mmw 0x054 0x000C0000 0\n\n\t# Enable clock for tracing\n\t# DBGMCU_CR |= TRACECLKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00100000 0\n\n\t# RM0399 (id 0x450) M7+M4 with SWO Funnel\n\t# RM0433 (id 0x450) M7 with SWO Funnel\n\t# RM0455 (id 0x480) M7 without SWO Funnel\n\t# RM0468 (id 0x483) M7 without SWO Funnel\n\t# Enable CM7 and CM4 slave ports in SWO trace Funnel\n\t# Works ok also on devices single core and without SWO funnel\n\t# Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF\n\t# SWTF_CTRL |= ENS0 | ENS1\n\tstm32h7x_dbgmcu_mmw 0x3000 0x00000003 0\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# Clock after reset is HSI at 64 MHz, no need of PLL\n\tadapter speed 4000\n}\n\n# get _CHIPNAME from current target\nproc stm32h7x_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\t$_CHIPNAME.cpu1 configure -event examine-end {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tglobal $_CHIPNAME.USE_CTI\n\n\t\t# Stop watchdog counters during halt\n\t\t# DBGMCU_APB3FZ2 |= WWDG1\n\t\tstm32h7x_dbgmcu_mmw 0x038 0x00000040 0\n\t\t# DBGMCU_APB1LFZ2 |= WWDG2\n\t\tstm32h7x_dbgmcu_mmw 0x040 0x00000800 0\n\t\t# DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2\n\t\tstm32h7x_dbgmcu_mmw 0x058 0x000C0000 0\n\n\t\tif {[set $_CHIPNAME.USE_CTI]} {\n\t\t\tstm32h7x_cti_start\n\t\t}\n\t}\n}\n\n# like mrw, but with target selection\nproc stm32h7x_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32h7x_mmw {used_target reg setbits clearbits} {\n\tset old [stm32h7x_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base\n# this procedure will use the mem_ap on AP2 whenever possible\nproc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {\n\t# use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address\n\tif {![using_hla]} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tset used_target $_CHIPNAME.ap2\n\t\tset reg_addr [expr {0xE00E1000 + $reg_offset}]\n\t} {\n\t\tset used_target [target current]\n\t\tset reg_addr [expr {0x5C001000 + $reg_offset}]\n\t}\n\n\tstm32h7x_mmw $used_target $reg_addr $setbits $clearbits\n}\n\nif {[set $_CHIPNAME.USE_CTI]} {\n\t# create CTI instances for both cores\n\tcti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0043000\n\tcti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -baseaddr 0xE0043000\n\n\t$_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\n\t$_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\n\tproc stm32h7x_cti_start {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Configure Cores' CTIs to halt each other\n\t\t# TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0\n\t\t$_CHIPNAME.cti0 write INEN0 0x1\n\t\t$_CHIPNAME.cti0 write OUTEN0 0x1\n\t\t$_CHIPNAME.cti1 write INEN0 0x1\n\t\t$_CHIPNAME.cti1 write OUTEN0 0x1\n\n\t\t# enable CTIs\n\t\t$_CHIPNAME.cti0 enable on\n\t\t$_CHIPNAME.cti1 enable on\n\t}\n\n\tproc stm32h7x_cti_stop {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t$_CHIPNAME.cti0 enable off\n\t\t$_CHIPNAME.cti1 enable off\n\t}\n\n\tproc stm32h7x_cti_prepare_restart_all {} {\n\t\tstm32h7x_cti_prepare_restart cti0\n\t\tstm32h7x_cti_prepare_restart cti1\n\t}\n\n\tproc stm32h7x_cti_prepare_restart {cti} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Acknowlodge EDBGRQ at TRIGOUT0\n\t\t$_CHIPNAME.$cti write INACK 0x01\n\t\t$_CHIPNAME.$cti write INACK 0x00\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32h7x_dual_bank.cfg",
    "content": "# script for stm32h7x family (dual flash bank)\n\n# STM32H7xxxI 2Mo have a dual bank flash.\nset DUAL_BANK 1\n\nsource [find target/stm32h7x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l0.cfg",
    "content": "#\n# M0+ devices only have SW-DP, but swj-dp code works, just don't\n# set any jtag related features\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB (max ram on smallest part)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    # Arm, m0+, non-multidrop.\n    # http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16088.html\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l0_enable_HSI16 {} {\n\t# Enable HSI16 as clock source\n\techo \"STM32L0: Enabling HSI16\"\n\n\t# Set HSI16ON in RCC_CR (leave MSI enabled)\n    mmw 0x40021000 0x00000101 0\n\n\t# Set HSI16 as SYSCLK (RCC_CFGR)\n\tmmw 0x4002100c 0x00000001 0\n\n\t# Wait until System clock switches to HSI16\n\twhile { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { }\n\n\t# Increase speed\n\tadapter speed 2500\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l0_enable_HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0x40015804 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l0_dual_bank.cfg",
    "content": "source [find target/stm32l0.cfg]\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l1.cfg",
    "content": "#\n# stm32l1 devices support both JTAG and SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 10kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0038\n      # Section 30.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l_enable_HSI {} {\n\t# Enable HSI as clock source\n\techo \"STM32L: Enabling HSI\"\n\n\t# Set HSION in RCC_CR\n\tmmw 0x40023800 0x00000101 0\n\n\t# Set HSI as SYSCLK\n\tmmw 0x40023808 0x00000001 0\n\n\t# Increase JTAG speed\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l_enable_HSI\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l1x_dual_bank.cfg",
    "content": "source [find target/stm32l1.cfg]\n\n# The stm32l1x 384kb have a dual bank flash.\n# Let's add a definition for the second bank here.\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l4x.cfg",
    "content": "# script for stm32l4x family\n\n#\n# stm32l4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 40kB (Available RAM in smallest device STM32L412)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0xa000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0351\n      # Section 44.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_TARGETNAME 0xA0001400\n   }\n}\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x48001000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x48001008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x48001000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x48001008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x48001000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x48001008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 6 (4 MHz).\n\t# Use MSI 24 MHz clock, compliant even with VOS == 2.\n\t# 3 WS compliant with VOS == 2 and 24 MHz.\n\tmww 0x40022000 0x00000103   ;# FLASH_ACR = PRFTBE | 3(Latency)\n\tmww 0x40021000 0x00000099   ;# RCC_CR = MSI_ON | MSIRGSEL | MSI Range 9\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32l5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32l5x family\n# stm32l5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32l5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32l5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is MSI (4MHz) after reset, set MCU freq at 110 MHz with PLL\n\t# RCC_APB1ENR1 = PWREN\n\tmww [expr {0x40021058 + $offset}] 0x10000000\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x40021058 + $offset}]\n\t# PWR_CR1 : VOS Range 0\n\tmww [expr {0x40007000 + $offset}] 0\n\t# while (PWR_SR2 & VOSF)\n\twhile {([mrw [expr {0x40007014 + $offset}]] & 0x0400)} {}\n\t# FLASH_ACR : 5 WS for 110 MHz HCLK\n\tmww 0x40022000 0x00000005\n\t# RCC_PLLCFGR = PLLP=PLLQ=0, PLLR=00=2, PLLREN=1, PLLN=55, PLLM=0000=1, PLLSRC=MSI 4MHz\n\t# fVCO = 4 x 55 /1 = 220\n\t# SYSCLOCK = fVCO/PLLR = 220/2 = 110 MHz\n\tmww [expr {0x4002100C + $offset}] 0x01003711\n\t# RCC_CR |= PLLON\n\tmmw [expr {0x40021000 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLLRDY)\n\twhile {!([mrw [expr {0x40021000 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR |= SW_PLL\n\tmmw [expr {0x40021008 + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR & SWS) != PLL)\n\twhile {([mrw [expr {0x40021008 + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32mp13x.cfg",
    "content": "# STMicroelectronics STM32MP13x (Single Cortex-A7)\n# http://www.st.com/stm32mp1\n\n# HLA does not support custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp13x_dk.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp13x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06501041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\n\n$_CHIPNAME.cpu cortex_a maskisr on\n$_CHIPNAME.cpu cortex_a dacrfixup on\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# srst resets the debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# keep clock enabled in low-power\n\t## catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000004}\n\t# freeze watchdog 1 and 2 on core halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\n# FIXME: most of handlers below will be removed once reset framework get merged\n$_CHIPNAME.ap1 configure -event reset-deassert-pre {\n\tadapter deassert srst deassert trst\n\tcatch {dap init}\n\tcatch {$::_CHIPNAME.dap apid 1}\n}\n$_CHIPNAME.cpu configure -event reset-deassert-pre  {$::_CHIPNAME.cpu arp_examine}\n$_CHIPNAME.cpu configure -event reset-deassert-post {toggle_cpu_dbg_claim0; dbgmcu_enable_debug}\n$_CHIPNAME.ap1 configure -event examine-start       {dap init}\n$_CHIPNAME.ap1 configure -event examine-end         {dbgmcu_enable_debug}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32mp15x.cfg",
    "content": "# STMicroelectronics STM32MP15x (Single/Dual Cortex-A7 plus Cortex-M4)\n# http://www.st.com/stm32mp1\n\n# HLA does not support multi-cores nor custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp15x_dk2.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp15x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06500041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# FIXME: Cortex-M code requires target accessible during reset, but this is not possible in STM32MP1\n# so defer-examine it until the reset framework get merged\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\ntarget create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 1 -dbgbase 0xE00D2000\ntarget create $_CHIPNAME.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\ntargets $_CHIPNAME.cpu0\n\ntarget smp $_CHIPNAME.cpu0 $_CHIPNAME.cpu1\n$_CHIPNAME.cpu0 cortex_a maskisr on\n$_CHIPNAME.cpu1 cortex_a maskisr on\n$_CHIPNAME.cpu0 cortex_a dacrfixup on\n$_CHIPNAME.cpu1 cortex_a dacrfixup on\n\ncti create $_CHIPNAME.cti.sys  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0094000\ncti create $_CHIPNAME.cti.cpu0 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D8000\ncti create $_CHIPNAME.cti.cpu1 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D9000\ncti create $_CHIPNAME.cti.cm4  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE0043000\n\nswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0083000\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0093000\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# Errata \"2.3.5 Incorrect reset of glitch-free kernel clock switch\" requires\n# srst to force VDDCORE power cycle or pull srst_core. Both cases reset the\n# debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# set debug enable bits in DBGMCU_CR to get ap2 and cm4 visible\n\tcatch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000007}\n\t# freeze watchdog 1 and 2 on cores halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu0_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\nproc detect_cpu1 {} {\n\tset cpu1_prsr [$::_CHIPNAME.ap1 read_memory 0xE00D2314 32 1]\n\tset dual_core [expr {$cpu1_prsr & 1}]\n\tif {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine}\n}\n\nproc rcc_enable_traceclk {} {\n\t$::_CHIPNAME.ap2 mww 0x5000080c 0x301\n}\n\n# FIXME: most of handler below will be removed once reset framework get merged\n$_CHIPNAME.ap1  configure -event reset-deassert-pre  {adapter deassert srst deassert trst;catch {dap init};catch {$::_CHIPNAME.dap apid 1}}\n$_CHIPNAME.ap2  configure -event reset-deassert-pre  {dbgmcu_enable_debug;rcc_enable_traceclk}\n$_CHIPNAME.cpu0 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu0 arp_examine}\n$_CHIPNAME.cpu1 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu1 arp_examine allow-defer}\n$_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0}\n$_CHIPNAME.cm4  configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == \"halted\"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}}\n$_CHIPNAME.ap1  configure -event examine-start       {dap init}\n$_CHIPNAME.ap2  configure -event examine-start       {dbgmcu_enable_debug}\n$_CHIPNAME.cpu0 configure -event examine-end         {detect_cpu1}\n$_CHIPNAME.ap2  configure -event examine-end         {rcc_enable_traceclk;$::_CHIPNAME.cm4 arp_examine}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32u5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32u5x family\n# stm32u5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32u5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32u5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is at MSI 4MHz after reset, set MCU freq at 160 MHz with PLL\n\n\t# Enable voltage range 1 for frequency above 100 Mhz\n\t# RCC_AHB3ENR = PWREN\n\tmww [expr {0x46020C94 + $offset}] 0x00000004\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x46020C94 + $offset}]\n\t# PWR_VOSR : VOS Range 1\n\tmmw [expr {0x4602080C + $offset}] 0x00030000 0\n\t# while !(PWR_VOSR & VOSRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00008000)} {}\n\t# FLASH_ACR : 4 WS for 160 MHz HCLK\n\tmww [expr {0x40022000 + $offset}] 0x00000004\n\t# RCC_PLL1CFGR => PLL1MBOOST=0, PLL1M=0=/1, PLL1FRACEN=0, PLL1SRC=MSI 4MHz\n\t#                 PLL1REN=1, PLL1RGE => VCOInputRange=PLLInputRange_4_8\n\tmww [expr {0x46020C28 + $offset}] 0x00040009\n\t# Enable EPOD Booster\n\tmmw [expr {0x4602080C + $offset}] 0x00040000 0\n\t# while !(PWR_VOSR & BOOSTRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00004000)} {}\n\t# RCC_PLL1DIVR => PLL1P=PLL1Q=PLL1R=000001=/2, PLL1N=0x4F=80\n\t# fVCO = 4 x 80 /1 = 320\n\t# SYSCLOCK = fVCO/PLL1R = 320/2 = 160 MHz\n\tmww [expr {0x46020C34 + $offset}] 0x0101024F\n\t# RCC_CR |= PLL1ON\n\tmmw [expr {0x46020C00 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLL1RDY)\n\twhile {!([mrw [expr {0x46020C00 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR1 |= SW_PLL\n\tmmw [expr {0x46020C1C + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR1 & SWS) != PLL)\n\twhile {([mrw [expr {0x46020C1C + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32u5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32w108xx.cfg",
    "content": "#\n# Target configuration for the ST STM32W108xx chips\n#\n# Processor: ARM Cortex-M3\n# Date:      2013-06-09\n# Author:    Giuseppe Barba <giuseppe.barba@gmail.com>\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] == 0 } {\n   set _CHIPNAME stm32w108\n} else {\n   set _CHIPNAME $CHIPNAME\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } {\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nset _ENDIAN little\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n if { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf -expected-id _BSTAPID\n } else {\n   set _BSTAPID_1 0x169a862b\n   set _BSTAPID_2 0x269a862b\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf \\\n\t\t-expected-id $_BSTAPID_1 -expected-id $_BSTAPID_2\n }\n}\n#\n# Set Target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\n# Use the flash driver from the EM357\nset _FLASHNAME $_CHIPNAME.flash\n\n# 64k (0x10000) of flash\nflash bank $_FLASHNAME em357 0x08000000 0x10000 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32wbx.cfg",
    "content": "# script for stm32wbx family\n\n#\n# stm32wb devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32wbx\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x6ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n    # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n    # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n    # 2 WS compliant with VOS=Range1 and 24 MHz.\n    mmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTBE | 2(Latency)\n    mmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n    # Boost JTAG frequency\n    adapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n    # Reset clock is MSI (4 MHz)\n    adapter speed 500\n}\n\n$_TARGETNAME configure -event examine-end {\n    # Enable debug during low power modes (uses more power)\n    # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n    mmw 0xE0042004 0x00000007 0\n\n    # Stop watchdog counters during halt\n    # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n    mmw 0xE004203C 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n    # change this value accordingly to configure trace pins\n    # assignment\n    mmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32wlx.cfg",
    "content": "# script for stm32wlx family\n\n#\n# stm32wl devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32wlx\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists WKUP_CM0P] } {\n\tset $_CHIPNAME.WKUP_CM0P $WKUP_CM0P\n\tunset WKUP_CM0P\n} else {\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# setup the Work-area start address and size\n# Work-area is a space in RAM used for flash programming\n\n# Memory map for known devices:\n# STM32WL   x5JC   x5JB   x5J8\n#   FLASH   256    128    64\n#   SRAM1   32     16     0\n#   SRAM2   32     32     20\n\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n# Use SRAM2 as work area (some devices do not have SRAM1):\nset WORKAREASTART_CM4   0x20008000\nset WORKAREASTART_CM0P  [expr {$WORKAREASTART_CM4 + $_WORKAREASIZE}]\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0\nflash bank $_CHIPNAME.otp.cpu0   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n\t# Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n\t# 2 WS compliant with VOS=Range1 and 24 MHz.\n\tmmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTEN | 2(Latency)\n\tmmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_CHIPNAME.cpu0 configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE004203C 0x00001800 0\n\n\tset _CHIPNAME [stm32wlx_get_chipname]\n\tglobal $_CHIPNAME.WKUP_CM0P\n\n\tif {[set $_CHIPNAME.WKUP_CM0P]} {\n\t\tstm32wlx_wkup_cm0p\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event trace-config {\n\t# nothing to do\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1\n\n\t$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0P -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\tflash bank $_CHIPNAME.otp.cpu1   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {![using_hla]} {\n\t\t# if srst is not fitted use SYSRESETREQ to\n\t\t# perform a soft reset\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n\tproc stm32wlx_wkup_cm0p {} {\n\t\tset _CHIPNAME [stm32wlx_get_chipname]\n\n\t\t# enable CPU2 boot after reset and after wakeup from Stop or Standby mode\n\t\t# PWR_CR4 |= C2BOOT\n\t\tstm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0\n\t}\n}\n\n# get _CHIPNAME from current target\nproc stm32wlx_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\n# like mrw, but with target selection\nproc stm32wlx_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32wlx_mmw {used_target reg setbits clearbits} {\n\tset old [stm32wlx_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32x5x_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common script for stm32l5x and stm32u5x families\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# STM32L5x: RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers\n\t\t# STM32U5x: RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers\n\t\t# Corresponds to Cortex®-M33 JTAG debug port ID code\n\t\tset _CPUTAPID 0x0ba04477\n\t} {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x0be12477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n# use non-secure RAM by default\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# create sec/ns flash and otp memories (sizes will be probed)\nflash bank $_CHIPNAME.flash_ns      stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp           stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME\n\n# Common knowledge tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://review.openocd.org/3366\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32x5x_is_secure {} {\n\t# read Debug Security Control and Status Register (DSCSR) and check CDS (bit 16)\n\tset DSCSR [mrw 0xE000EE08]\n\treturn [expr {($DSCSR & (1 << 16)) != 0}]\n}\n\nproc stm32x5x_ahb_ap_non_secure_access {} {\n\t# SPROT=1=Non Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x4B000000 0x4F000000\n}\n\nproc stm32x5x_ahb_ap_secure_access {} {\n\t# SPROT=0=Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x0B000000 0x4F000000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 480\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0xE0044004 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0044008 0x00001800 0\n}\n\n$_TARGETNAME configure -event halted {\n\tset secure [stm32x5x_is_secure]\n\n\tif {$secure} {\n\t\tset secure_str \"Secure\"\n\t\tstm32x5x_ahb_ap_secure_access\n\t} else {\n\t\tset secure_str \"Non-Secure\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t}\n\n\t# print the secure state only when it changes\n\tset _TARGETNAME [target current]\n\tglobal $_TARGETNAME.secure\n\n\tif {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {\n\t\techo \"CPU in $secure_str state\"\n\t\t# update saved security state\n\t\tset $_TARGETNAME.secure $secure\n\t}\n}\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tset use_secure_workarea 0\n\t# check if FLASH_OPTR.TZEN is enabled\n\tset FLASH_OPTR [mrw 0x40022040]\n\tif {[expr {$FLASH_OPTR & 0x80000000}] == 0} {\n\t\techo \"TZEN option bit disabled\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t} else {\n\t\tstm32x5x_ahb_ap_secure_access\n\t\techo \"TZEN option bit enabled\"\n\n\t\t# check if FLASH_OPTR.RDP is not Level 0.5\n\t\tif {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {\n\t\t\tset use_secure_workarea 1\n\t\t}\n\t}\n\n\tset _TARGETNAME [target current]\n\tset workarea_addr [$_TARGETNAME cget -work-area-phys]\n\techo \"workarea_addr $workarea_addr\"\n\n\tif {$use_secure_workarea} {\n\t\tset workarea_addr [expr {$workarea_addr | 0x10000000}]\n\t} else {\n\t\tset workarea_addr [expr {$workarea_addr & ~0x10000000}]\n\t}\n\n\t$_TARGETNAME configure -work-area-phys $workarea_addr\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0044004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm32xl.cfg",
    "content": "# script for stm32xl family (dual flash bank)\nsource [find target/stm32f1x.cfg]\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8l.cfg",
    "content": "# script for stm8l family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8l\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set stm8l type\n$_TARGETNAME configure -enable_stm8l\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n#uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8l152.cfg",
    "content": "#config script for STM8L152\n\nset EEPROMSTART 0x1000\nset EEPROMEND 0x13ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8s.cfg",
    "content": "# script for stm8s family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8s\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n# uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8s003.cfg",
    "content": "#config script for STM8S003\n\nset FLASHEND 0x9FFF\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8s103.cfg",
    "content": "#config script for STM8S103\n\nset FLASHEND 0x9FFF\nset EEPROMEND 0x427F\nset OPTIONEND 0x480A\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/stm8s105.cfg",
    "content": "#config script for STM8S105\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/str710.cfg",
    "content": "#start slow, speed up after reset\nadapter speed 10\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str710\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 6000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x400C0000 0x00004000 0 0 $_TARGETNAME STR71x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/str730.cfg",
    "content": "#STR730 CPU\n\nadapter speed 3000\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str730\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/str750.cfg",
    "content": "#STR750 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str750\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0041\n}\n\n# jtag speed\nadapter speed 10\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n\tinit_smi\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x20000000 0x00040000 0 0 $_TARGETNAME STR75x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x200C0000 0x00004000 0 0 $_TARGETNAME STR75x\n\n# Serial NOR on SMI CS0.\nset _FLASHNAME $_CHIPNAME.snor\nflash bank $_FLASHNAME stmsmi 0x80000000 0 0 0 $_TARGETNAME\n\nsource [find mem_helper.tcl]\n\nproc init_smi {} {\n\tmmw 0x60000030 0x01000000 0x00000000; # enable clock for GPIO regs\n\tmmw 0xffffe420 0x00000001 0x00000000; # set SMI_EN bit\n\tmmw 0x90000000 0x00000001 0x00000000; # set BLOCK_EN_1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/str912.cfg",
    "content": "# script for str9\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # possible values: 0x1457f041, 0x2457f041\n   # we ignore version in check below\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID -ignore-version\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#adapter speed 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/swj-dp.tcl",
    "content": "# ARM Debug Interface V5 (ADI_V5) utility\n# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since\n# SW-DP and JTAG-DP targets don't need to switch based\n# on which transport is active.\n#\n# declare a JTAG or SWD Debug Access Point (DAP)\n# based on the transport in use with this session.\n# You can't access JTAG ops when SWD is active, etc.\n\n# params are currently what \"jtag newtap\" uses\n# because OpenOCD internals are still strongly biased\n# to JTAG ....  but for SWD, \"irlen\" etc are ignored,\n# and the internals work differently\n\n# for now, ignore non-JTAG and non-SWD transports\n# (e.g. initial flash programming via SPI or UART)\n\n# split out \"chip\" and \"tag\" so we can someday handle\n# them more uniformly irlen too...)\n\nif [catch {transport select}] {\n  echo \"Error: unable to select a session transport. Can't continue.\"\n  shutdown\n}\n\nproc swj_newdap {chip tag args} {\n if [using_jtag] {\n     eval jtag newtap $chip $tag $args\n } elseif [using_swd] {\n     eval swd newdap $chip $tag $args\n } else {\n     echo \"Error: transport '[ transport select ]' not supported by swj_newdap\"\n     shutdown\n }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/swm050.cfg",
    "content": "# Synwit SWM050\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME swm050\n}\nset _CHIPSERIES swm050\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\nadapter speed 1000\n\n$_TARGETNAME configure -event reset-init {\n\t# Stop the watchdog, just to be safe\n\tmww 0x40019000 0x00\n\t# Set clock divider value to 1\n\tmww 0x400F0000 0x01\n\t# Set system clock to 18Mhz\n\tmww 0x400F0008 0x00\n}\n\n# SWM050 (Cortex-M0 core) supports SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/test_reset_syntax_error.cfg",
    "content": "# Test script to check that syntax error in reset\n# script is reported properly.\n\n# at91eb40a target\n\n#jtag scan chain\nset _CHIPNAME syntaxtest\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\n\tsyntax error\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/test_syntax_error.cfg",
    "content": "# This script tests a syntax error in the startup\n# config script\n\nsyntax error here\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti-ar7.cfg",
    "content": "#\n# Texas Instruments AR7 SOC - used in many adsl modems.\n# http://www.linux-mips.org/wiki/AR7\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ti-ar7\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0000100f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_CHIPNAME.cpu\n\n# use onboard 4k sram as working area\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti-cjtag.cfg",
    "content": "# A start sequence to change from cJTAG to 4-pin JTAG\n# This is needed for CC2538 and CC26xx to be able to communicate through JTAG\n# Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information.\nproc ti_cjtag_to_4pin_jtag {jrc} {\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\t# Two zero bit scans and a one bit drshift\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# A two bit drhift and a 9 bit drshift\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\n\t# Set ICEPick IDCODE in data register\n\tirscan $jrc 0x04 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_calypso.cfg",
    "content": "#\n# TI Calypso (lite) G2 C035 Digital Base Band chip\n#\n# ARM7TDMIE + DSP subchip (S28C128)\n#\n# 512K SRAM Calypso\n# 256K SRAM Calypso lite\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME calypso\n}\n\nif { [info exists ENDIAN] } {\n\tset  _ENDIAN $ENDIAN\n} else {\n\tset  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3100e02f\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\njtag newtap $_CHIPNAME dsp -expected-id 0x00000000 -irlen 8\njtag newtap $_CHIPNAME arm -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# target\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position $_TARGETNAME\n\n# workarea\n\n$_TARGETNAME configure -work-area-phys 0x00800000 -work-area-size $_WORKAREASIZE -work-area-backup 1\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n$_TARGETNAME configure -event examine-start {\n\tirscan calypso.arm 0x0b -endstate DRPAUSE\n\tdrscan calypso.arm 2 2 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc13x0.cfg",
    "content": "#\n# Texas Instruments CC13x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x0\nset JRC_TAPID 0x0B9BE02F\nset WORKAREASIZE 0x4000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc13x2.cfg",
    "content": "#\n# Texas Instruments CC13x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc26x0.cfg",
    "content": "#\n# Texas Instruments CC26x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc26x0\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4BA00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B99A02F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n# A start sequence is needed to change from 2-pin cJTAG to 4-pin JTAG\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config vectreset\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc26x2.cfg",
    "content": "#\n# Texas Instruments CC26x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc26x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc3220sf.cfg",
    "content": "#\n# Texas Instruments CC3220SF - ARM Cortex-M4\n#\n# http://www.ti.com/CC3220SF\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\nsource [find target/ti_cc32xx.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n#\n# On CC32xx family of devices, sysreqreset is disabled, and vectreset is\n# blocked by the boot loader (stops in a while(1) statement). srst reset can\n# leave the target in a state that prevents debug. The following uses the\n# soft_reset_halt command to reset and halt the target. Then the PC and stack\n# are initialized from internal flash. This allows for a more reliable reset,\n# but with two caveats: it only works for the SF variant that has internal\n# flash, and it only resets the CPU and not any peripherals.\n#\n\nproc ocd_process_reset_inner { MODE } {\n\n\tsoft_reset_halt\n\n\t# Initialize MSP, PSP, and PC from vector table at flash 0x01000800\n\tset boot [read_memory 0x01000800 32 2]\n\n\treg msp [lindex $boot 0]\n\treg psp [lindex $boot 0]\n\treg pc [lindex $boot 1]\n\n\tif { 0 == [string compare $MODE run ] } {\n\t\tresume\n\t}\n\n\tcc32xx.cpu invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_cc32xx.cfg",
    "content": "#\n# Texas Instruments CC32xx - ARM Cortex-M4\n#\n# http://www.ti.com/product/CC3200\n# http://www.ti.com/product/CC3220\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc32xx\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tif {[using_jtag]} {\n\t\tset _DAP_TAPID 0x4BA00477\n\t} else {\n\t\tset _DAP_TAPID 0x2BA01477\n\t}\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\n\tjtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n} else {\n\tswj_newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\n}\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B97C02F\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\tjtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_dm355.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM355\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm355\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n#\n# Also note: when running without RTCK before the PLLs are set up, you\n# may need to slow the JTAG clock down quite a lot (under 2 MHz).\n#\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b73b02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm355\nset dm355 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm355 sram0\t\t0x00010000\ndict set dm355 sram1\t\t0x00014000\ndict set dm355 sysbase\t\t0x01c40000\ndict set dm355 pllc1\t\t0x01c40800\ndict set dm355 pllc2\t\t0x01c40c00\ndict set dm355 psc\t\t0x01c41000\ndict set dm355 gpio\t\t0x01c67000\ndict set dm355 a_emif\t\t0x01e10000\ndict set dm355 a_emif_cs0\t0x02000000\ndict set dm355 a_emif_cs1\t0x04000000\ndict set dm355 ddr_emif\t\t0x20000000\ndict set dm355 ddr\t\t0x80000000\ndict set dm355 uart0\t\t0x01c20000\ndict set dm355 uart1\t\t0x01c20400\ndict set dm355 uart2\t\t0x01e06000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm355 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_dm365.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM365\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm365\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x0792602f\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b83e02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm365\nset dm365 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm365 sram0\t\t0x00010000\ndict set dm365 sram1\t\t0x00014000\ndict set dm365 sysbase\t\t0x01c40000\ndict set dm365 pllc1\t\t0x01c40800\ndict set dm365 pllc2\t\t0x01c40c00\ndict set dm365 psc\t\t0x01c41000\ndict set dm365 gpio\t\t0x01c67000\ndict set dm365 a_emif\t\t0x01d10000\ndict set dm365 a_emif_cs0\t0x02000000\ndict set dm365 a_emif_cs1\t0x04000000\ndict set dm365 ddr_emif\t\t0x20000000\ndict set dm365 ddr\t\t0x80000000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm365 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_dm6446.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM6446\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm6446\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: unknown ... must enable via ICEpick\njtag newtap $_CHIPNAME unknown -irlen 8 -disable\njtag configure $_CHIPNAME.unknown -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\njtag configure $_CHIPNAME.dsp -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b70002f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_k3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments K3 devices:\n# * AM654x: https://www.ti.com/lit/pdf/spruid7\n#  Has 4 ARMV8 Cores and 2 R5 Cores and an M3\n# * J721E: https://www.ti.com/lit/pdf/spruil1\n#  Has 2 ARMV8 Cores and 6 R5 Cores and an M3\n# * J7200: https://www.ti.com/lit/pdf/spruiu1\n#  Has 2 ARMV8 Cores and 4 R5 Cores and an M3\n# * AM642: https://www.ti.com/lit/pdf/spruim2\n#  Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3\n#\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc am654\n}\n\n# set V8_SMP_DEBUG to non 0 value in board if you'd like to use SMP debug\nif { [info exists V8_SMP_DEBUG] } {\n\tset _v8_smp_debug $V8_SMP_DEBUG\n} else {\n\tset _v8_smp_debug 0\n}\n\n# Common Definitions\n\n# System Controller is the very first processor - all current SoCs have it.\nset CM3_CTIBASE\t\t{0x3C016000}\n\n# sysctrl power-ap unlock offsets\nset _sysctrl_ap_unlock_offsets {0xf0 0x44}\n\n# All the ARMV8s are the next processors.\n#\t\t   CL0,CORE0  CL0,CORE1  CL1,CORE0  CL1,CORE1\nset ARMV8_DBGBASE {0x90410000 0x90510000 0x90810000 0x90910000}\nset ARMV8_CTIBASE {0x90420000 0x90520000 0x90820000 0x90920000}\n\n# And we add up the R5s\n#\t\t(0)MCU 0   (1)MCU 1   (2)MAIN_0_0 (3)MAIN_0_1 (4)MAIN_1_0 (5)MAIN_1_1\nset R5_DBGBASE {0x9d010000 0x9d012000 0x9d410000 0x9d412000 0x9d510000 0x9d512000}\nset R5_CTIBASE {0x9d018000 0x9d019000 0x9d418000 0x9d419000 0x9d518000 0x9d519000}\nset R5_NAMES {mcu_r5.0 mcu_r5.1 main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\n# Finally an General Purpose(GP) MCU\nset CM4_CTIBASE\t\t{0x20001000}\n\n# General Purpose MCU (M4) may be present on some very few SoCs\nset _gp_mcu_cores 0\n# General Purpose MCU power-ap unlock offsets\nset _gp_mcu_ap_unlock_offsets {0xf0 0x60}\n\n# Set configuration overrides for each SOC\nswitch $_soc {\n\tam654 {\n\t\tset _CHIPNAME am654\n\t\tset _K3_DAP_TAPID 0x0bb5a02f\n\n\t\t# AM654 has 2 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\n\t\t# AM654 has 1 cluster of 2 R5s cores.\n\t\tset _r5_cores 2\n\t\tset R5_NAMES {mcu_r5.0 mcu_r5.1}\n\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x50}\n\t}\n\tam642 {\n\t\tset _CHIPNAME am642\n\t\tset _K3_DAP_TAPID 0x0bb3802f\n\n\t\t# AM642 has 1 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 2\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000}\n\n\t\t# AM642 has 2 cluster of 2 R5s cores.\n\t\tset _r5_cores 4\n\t\tset R5_NAMES {main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\t\tset R5_DBGBASE {0x9d410000 0x9d412000 0x9d510000 0x9d512000}\n\t\tset R5_CTIBASE {0x9d418000 0x9d419000 0x9d518000 0x9d519000}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t}\n\tam625 {\n\t\tset _CHIPNAME am625\n\t\tset _K3_DAP_TAPID 0x0bb7e02f\n\n\t\t# AM625 has 1 clusters of 4 A53 cores.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}\n\n\t\t# AM625 has 1 cluster of 1 R5s core.\n\t\tset _r5_cores 1\n\t\tset R5_NAMES {main0_r5.0}\n\t\tset R5_DBGBASE {0x9d410000}\n\t\tset R5_CTIBASE {0x9d418000}\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tj721e {\n\t\tset _CHIPNAME j721e\n\t\tset _K3_DAP_TAPID 0x0bb6402f\n\t\t# J721E has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721E has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\t}\n\tj7200 {\n\t\tset _CHIPNAME j7200\n\t\tset _K3_DAP_TAPID 0x0bb6d02f\n\n\t\t# J7200 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J7200 has 2 clusters of 2 R5 cores each.\n\t\tset _r5_cores 4\n\t\tset R5_DBGBASE {0x9d010000 0x9d012000 0x9d110000 0x9d112000}\n\t\tset R5_CTIBASE {0x9d018000 0x9d019000 0x9d118000 0x9d119000}\n\n\t\t# M3 CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t}\n\tj721s2 {\n\t\tset _CHIPNAME j721s2\n\t\tset _K3_DAP_TAPID 0x0bb7502f\n\n\t\t# J721s2 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721s2 has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tdefault {\n\t\techo \"'$_soc' is invalid!\"\n\t}\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\nset _CTINAME $_CHIPNAME.cti\n\n# sysctrl is always present\ncti create $_CTINAME.sysctrl -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]\ntarget create $_TARGETNAME.sysctrl cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine\n$_TARGETNAME.sysctrl configure -event reset-assert { }\n\nproc sysctrl_up {} {\n\t# To access sysctrl, we need to enable the JTAG access for the same.\n\t# Ensure Power-AP unlocked\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 0] 0x00190000\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 1] 0x00102098\n\n\t$::_TARGETNAME.sysctrl arp_examine\n}\n\n$_TARGETNAME.sysctrl configure -event gdb-attach {\n\tsysctrl_up\n\t# gdb-attach default rule\n\thalt 1000\n}\n\nproc _cpu_no_smp_up {} {\n\tset _current_target [target current]\n\tset _current_type [$_current_target cget -type]\n\n\t$_current_target arp_examine\n\t$_current_target $_current_type dbginit\n}\n\nproc _armv8_smp_up {} {\n\tfor { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on\n\t}\n\t# Set Default target as core 0\n\ttargets $::_TARGETNAME.$::_armv8_cpu_name.0\n}\n\nset _v8_smp_targets \"\"\n\nfor { set _core 0 } { $_core < $_armv8_cores } { incr _core } {\n\n\tcti create $_CTINAME.$_armv8_cpu_name.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $ARMV8_CTIBASE $_core]\n\n\ttarget create $_TARGETNAME.$_armv8_cpu_name.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $ARMV8_DBGBASE $_core] -cti $_CTINAME.$_armv8_cpu_name.$_core -defer-examine\n\n\tset _v8_smp_targets \"$_v8_smp_targets $_TARGETNAME.$_armv8_cpu_name.$_core\"\n\n\tif { $_v8_smp_debug == 0 } {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_cpu_no_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t} else {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_armv8_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t}\n}\n\n# Setup ARMV8 proc commands based on CPU to prevent people confusing SoCs\nset _armv8_up_cmd \"$_armv8_cpu_name\"_up\n# Available if V8_SMP_DEBUG is set to non-zero value\nset _armv8_smp_cmd \"$_armv8_cpu_name\"_smp\n\nif { $_v8_smp_debug == 0 } {\n\tproc $_armv8_up_cmd { args } {\n\t\tforeach _core $args {\n\t\t\ttargets $_core\n\t\t\t_cpu_no_smp_up\n\t\t}\n\t}\n} else {\n\tproc $_armv8_smp_cmd { args } {\n\t\t_armv8_smp_up\n\t}\n\t# Declare SMP\n\ttarget smp $:::_v8_smp_targets\n}\n\nfor { set _core 0 } { $_core < $_r5_cores } { incr _core } {\n\tset _r5_name [lindex $R5_NAMES $_core]\n\tcti create $_CTINAME.$_r5_name -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $R5_CTIBASE $_core]\n\n\t# inactive core examination will fail - wait till startup of additional core\n\ttarget create $_TARGETNAME.$_r5_name cortex_r4 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $R5_DBGBASE $_core] -ap-num 1 -defer-examine\n\n\t$_TARGETNAME.$_r5_name configure -event gdb-attach {\n\t\t_cpu_no_smp_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n\nproc r5_up { args } {\n\tforeach  _core $args {\n\t\ttargets $_core\n\t\t_cpu_no_smp_up\n\t}\n}\n\nif { $_gp_mcu_cores != 0 } {\n\tcti create $_CTINAME.gp_mcu -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]\n\ttarget create $_TARGETNAME.gp_mcu cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine\n\t$_TARGETNAME.gp_mcu configure -event reset-assert { }\n\n\tproc gp_mcu_up {} {\n\t\t# To access GP MCU, we need to enable the JTAG access for the same.\n\t\t# Ensure Power-AP unlocked\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 0] 0x00190000\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 1] 0x00102098\n\n\t\t$::_TARGETNAME.gp_mcu arp_examine\n\t}\n\n\t$_TARGETNAME.gp_mcu configure -event gdb-attach {\n\t\tgp_mcu_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_msp432.cfg",
    "content": "#\n# Texas Instruments MSP432 - ARM Cortex-M4F @ up to 48 MHz\n#\n# http://www.ti.com/MSP432\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME msp432\n}\n\nif { [info exists CPUTAPID] } {\n\tset _DAP_TAPID $CPUTAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists DAP_SWD_ID] } {\n\tset _DAP_SWD_ID $DAP_SWD_ID\n} else {\n\tset _DAP_SWD_ID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _DAP_ID $_DAP_TAPID\n} else {\n\tset _DAP_ID $_DAP_SWD_ID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_rm4x.cfg",
    "content": "source [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_tms570.cfg",
    "content": "adapter speed 1500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tms570\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN big\n}\n\n# TMS570 has an ICEpick-C on which we need the router commands.\nsource [find target/icepick.cfg]\n\n# Main DAP\n# DAP_TAPID should be set before source-ing this file\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# ICEpick-C (JTAG route controller)\n# JRC_TAPID should be set before source-ing this file\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n}\n\nset _JRC_TAPID2 0x0B7B302F\nset _JRC_TAPID3 0x0B95502F\nset _JRC_TAPID4 0x0B97102F\nset _JRC_TAPID5 0x0D8A002F\nset _JRC_TAPID6 0x2B8A002F\nset _JRC_TAPID7 0x2D8A002F\nset _JRC_TAPID8 0x3B8A002F\nset _JRC_TAPID9 0x3D8A002F\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID \\\n\t-expected-id $_JRC_TAPID2 \\\n\t-expected-id $_JRC_TAPID3 \\\n\t-expected-id $_JRC_TAPID4 \\\n\t-expected-id $_JRC_TAPID5 \\\n\t-expected-id $_JRC_TAPID6 \\\n\t-expected-id $_JRC_TAPID7 \\\n\t-expected-id $_JRC_TAPID8 \\\n\t-expected-id $_JRC_TAPID9 \\\n\t-ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-R4 target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_r4 -endian $_ENDIAN \\\n\t-dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x00001003\n\n# TMS570 uses quirky BE-32 mode\n$_CHIPNAME.dap ti_be_32_quirks 1\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\tglobal _CHIPNAME\n\n\t# assert warm system reset through ICEPick\n\ticepick_c_wreset $_CHIPNAME.jrc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_tms570ls20xxx.cfg",
    "content": "# TMS570LS20216, TMS570LS20206, TMS570LS10216\n# TMS570LS10206, TMS570LS10116, TMS570LS10106\nset DAP_TAPID 0x0B7B302F\nset JRC_TAPID 0x0B7B302F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/ti_tms570ls3137.cfg",
    "content": "# TMS570LS3137\nset DAP_TAPID 0x0B8A002F\nset JRC_TAPID 0x0B8A002F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/tmpa900.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA900\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa900\n}\n\n# Toshiba TMPA900 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA900 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (8kB): 0xf8008000\n\n# Use internal RAM-0 and RAM-1 as working area (24kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0x6000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/tmpa910.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA910\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa910\n}\n\n# Toshiba TMPA910 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA910 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (16kB): 0xf8008000\n# Internal RAM-2 (16kB): 0xf800c000\n\n# Use internal RAM-0, RAM-1, and RAM-2 as working area (48kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0xc000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/tnetc4401.cfg",
    "content": "# Texas Instruments (TI) TNETC4401, MIPS32 DOCSIS-tailored SoC (4Kc-based)\n# Used in Knovative KC-100 and Motorola Surfboard SB5120 cable modems.\n# Datasheet: https://brezn.muc.ccc.de/~mazzoo/DOCSIS/tnetc4401.pdf\ntransport select jtag\nset _TARGETNAME tnetc4401\nset _CPUTAPID 0x0000100f\njtag newtap $_TARGETNAME tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\ntarget create $_TARGETNAME mips_m4k -chain-position $_TARGETNAME.tap -endian big\n\n# May need to halt manually before calling reset init\n$_TARGETNAME configure -event reset-init {\n\thalt\n\techo \"Attempting to disable watchdog...\"\n\tmwb phys 0xa8610b00 0 256\n\thalt\n\twait_halt\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/u8500.cfg",
    "content": "#  Copyright (C) ST-Ericsson SA 2011\n#  Author : michel.jaouen@stericsson.com\n#  U8500 target\n\nproc mmu_off {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp & ~1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc mmu_on {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp | 1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc ocd_gdb_restart {target_id} {\n    global _TARGETNAME_1\n\tglobal _SMP\n    targets $_TARGETNAME_1\n\tif { $_SMP == 1 } {\n\tcortex_a smp off\n\t}\n\trst_run\n\thalt\n\tif { $_SMP == 1 } {\n\tcortex_a smp on\n\t}\n}\n\nproc smp_reg {} {\n\tglobal _TARGETNAME_1\n    global _TARGETNAME_2\n    targets $_TARGETNAME_1\n\techo \"$_TARGETNAME_1\"\n\tset pc1 [reg pc]\n\tset stck1 [reg sp_svc]\n\ttargets $_TARGETNAME_2\n\techo \"$_TARGETNAME_1\"\n\tset pc2 [reg pc]\n\tset stck2 [reg sp_svc]\n}\n\n\nproc u8500_tapenable {chip val} {\n\techo \"JTAG tap enable $chip\"\n}\n\n\nproc pwrsts { } {\n\tglobal _CHIPNAME\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\techo \"pwrsts =\"$pwrsts\n\tset a9 [expr \"0x$pwrsts & 0xc\"]\n\tset ape [expr \"0x$pwrsts & 0x3\"]\n\tif {[string equal \"0\" $ape]} {\n\t\techo \"ape off\"\n\t} else {\n\t\techo \"ape on\"\n\t}\n\techo \"$a9\"\n\tswitch $a9 {\n\t\t4 {\n\t\t\techo \"A9 in retention\"\n\t\t  }\n\t\t8 {\n\t\t\techo \"A9 100% DVFS\"\n\t\t  }\n\t\tc {\n\t\t\techo \"A9 50% DVFS\"\n\t\t}\n\t}\n}\n\nproc poll_pwrsts { } {\n\tglobal _CHIPNAME\n\tset result 1\n\tset i 0\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\twhile {[string equal \"4\" $pwrsts] && $i<20} {\n\t\tirscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 0;\n\t\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\t\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\t\tif {![string equal \"4\" $pwrsts]} {\n\t\t\tset result 1\n\t\t} else {\n\t\t\tset result 0\n\t\t\tsleep 200\n\t\t\techo \"loop $i\"\n\t\t}\n\t\tincr i\n\t}\n\treturn $result\n}\n\nproc halt_ { } {\n\tif {[poll_pwrsts]==1} {\n\t\thalt\n\t} else {\n\t\techo \"halt failed : target in retention\"\n\t}\n}\n\n\nproc u8500_dapenable {chip} {\n}\n\nproc u8500_tapdisable {chip val} {\n\techo \"JTAG tap disable $chip\"\n}\n\n\nproc enable_apetap {} {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n    global _TARGETNAME_1\n\tpoll off\n\tirscan $_CHIPNAME.jrc 0x3e\n\tdrscan $_CHIPNAME.jrc 8 0xcf\n\tjtag tapenable $_CHIPNAME.dap\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tset status [$_TARGETNAME_1 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_1 arp_examine\n\tcache_config l2x 0xa0412000 8\n\t}\n\n\tset status [$_TARGETNAME_2 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_2 arp_examine\n\t}\n\t}\n\ntcl_port 5555\ntelnet_port 4444\ngdb_port 3333\n\nif { [info exists CHIPNAME] } {\nglobal _CHIPNAME\n    set _CHIPNAME $CHIPNAME\n} else {\nglobal _CHIPNAME\n\tset _CHIPNAME u8500\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n\tset _ENDIAN little\n}\n\n\n\n# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT,\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"u8500_dapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n\t\"u8500_tapdisable $_CHIPNAME.cpu 0xc0\"\n\n\n#CLTAPC TAP JRC equivalent\nif { [info exists CLTAPC_ID] } {\n   set _CLTAPC_ID $CLTAPC_ID\n} else {\n   set _CLTAPC_ID 0x22286041\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version\n\n\nif { ![info exists TARGETNAME_1] } {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $_CHIPNAME.cpu1\n} else {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $TARGETNAME_1\n}\n\nif { [info exists DAP_DBG1] } {\n\tset _DAP_DBG1 $DAP_DBG1\n} else {\n\tset _DAP_DBG1 0x801A8000\n}\nif { [info exists DAP_DBG2] } {\n\tset _DAP_DBG2 $DAP_DBG2\n} else {\n\tset _DAP_DBG2 0x801AA000\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME_1 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux\n\n\nif { ![info exists TARGETNAME_2] } {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $_CHIPNAME.cpu2\n} else {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $TARGETNAME_2\n}\n\ntarget create $_TARGETNAME_2 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux\n\n\nif {![info exists SMP]} {\nglobal _SMP\nset _SMP 1\n} else {\nglobal _SMP\nset _SMP $SMP\n}\nglobal SMP\nif { $_SMP == 1} {\ntarget smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\n}\n\n\n\n\nproc secsts1 { } {\n\tglobal _CHIPNAME\n        irscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {![string equal \"4\" $secsts1]} {\n\techo \"APE target secured\"\n        } else {\n        echo \"APE target not secured\"\n        }\n}\n\nproc att { } {\n\tglobal _CHIPNAME\n\tjtag arp_init\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {[string equal \"4\" $secsts1]} {\n\t\tif {[poll_pwrsts]==1} {\n\t\tenable_apetap\n                } else {\n\t\techo \"target in retention\"\n\t\t}\n\t} else {\n\t\techo \"target secured\"\n\t}\n\n}\n\n\n\nproc rst_run { } {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n\tglobal _TARGETNAME_1\n\tset status [$_TARGETNAME_1 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_1\n\t}\n    set status [$_TARGETNAME_2 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_2\n\t}\n   \tpoll off\n\tjtag arp_init\n\treset\n\tsleep 20\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\twhile {![string equal \"4\" $secsts1]} {\n\t\tirscan u8500.jrc 0x3a\n\t\tdrscan u8500.jrc 4 4\n\t\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\t\techo \"secsts1 =\"$secsts1\n\t\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\t}\n\techo \"ape debugable\"\n\tenable_apetap\n\tpoll on\n\ttargets $_TARGETNAME_1\n\tdap apsel 1\n}\n\nif {![info exists MAXSPEED]} {\nglobal _MAXSPEED\nset _MAXSPEED 15000\n} else {\nglobal _MAXSPEED\nset _MAXSPEED $MAXSPEED\n}\nglobal _MAXSPEED\nadapter speed $_MAXSPEED\n\n\ngdb_breakpoint_override hard\nset mem inaccessible-by-default-off\n\njtag_ntrst_delay 100\nreset_config trst_and_srst combined\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/vd_aarch64.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm v8 64b Cortex A\n\nif {![info exists _CORES]} {\n\tset _CORES 1\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME aarch64\n}\nset _TARGETNAME $_CHIPNAME.cpu\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80810000 0x80910000}\nset CTIBASE {0x80820000 0x80920000}\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n$_CHIPNAME.dap apsel 1\n\nfor { set _core 0 } { $_core < $_CORES } { incr _core } \\\n{\n\tcti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 -baseaddr [lindex $CTIBASE $_core]\n\tset _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t-dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core\"\n\tif { $_core != 0 } {\n\t\t# non-boot core examination may fail\n\t\tset _command \"$_command -defer-examine\"\n\t\tset _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n\t} else {\n\t\tset _smp_command \"target smp $_TARGETNAME.$_core\"\n\t}\n\teval $_command\n}\neval $_smp_command\n\n# default target is core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/vd_cortex_m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# ARM Cortex M\n\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME cortex_m\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/vd_riscv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV core\n\nif {![info exists _HARTID]} {\n\tset _HARTID 0x00\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME riscv\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID\n\nriscv set_reset_timeout_sec 120\nriscv set_command_timeout_sec 120\n# prefer to use sba for system bus access\nriscv set_prefer_sba on\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/vybrid_vf6xx.cfg",
    "content": "#\n# Freescale Vybrid VF610\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME vf610\n}\n\nif { [info exists A5_JTAG_TAPID] } {\n\tset _A5_JTAG_TAPID $A5_JTAG_TAPID\n} else {\n\tset _A5_JTAG_TAPID 0x4BA00477\n}\n\nif { [info exists A5_SWD_TAPID] } {\n\tset _A5_SWD_TAPID $A5_SWD_TAPID\n} else {\n\tset _A5_SWD_TAPID 0x3BA02477\n}\n\nif { [using_jtag] } {\n\tset _A5_TAPID $_A5_JTAG_TAPID\n} else {\n\tset _A5_TAPID $_A5_SWD_TAPID\n}\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_A5_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap -dbgbase 0xc0088000\ntarget create ${_TARGETNAME}1 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/xilinx_zynqmp.cfg",
    "content": "#\n# target configuration for\n# Xilinx ZynqMP (UltraScale+ / A53)\n#\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME uscale\n}\n\n#\n# DAP tap (Quard core A53)\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# PS tap (UltraScale+)\n#\nif { [info exists PS_TAPID] } {\n    set _PS_TAPID $PS_TAPID\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -expected-id $_PS_TAPID\n} else {\n    # FPGA Programmable logic. Values take from Table 39-1 in UG1085:\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -ignore-version \\\n        -expected-id 0x04711093 \\\n        -expected-id 0x04710093 \\\n        -expected-id 0x04721093 \\\n        -expected-id 0x04720093 \\\n        -expected-id 0x04739093 \\\n        -expected-id 0x04730093 \\\n        -expected-id 0x04738093 \\\n        -expected-id 0x04740093 \\\n        -expected-id 0x04750093 \\\n        -expected-id 0x04759093 \\\n        -expected-id 0x04758093\n}\n\nset jtag_configured 0\n\njtag configure $_CHIPNAME.ps -event setup {\n    global _CHIPNAME\n    global jtag_configured\n\n    if { $jtag_configured == 0 } {\n        # add the DAP tap to the chain\n        # See https://forums.xilinx.com/t5/UltraScale-Architecture/JTAG-Chain-Configuration-for-Zynq-UltraScale-MPSoC/td-p/758924\n        irscan $_CHIPNAME.ps 0x824\n        drscan $_CHIPNAME.ps 32 0x00000003\n        runtest 100\n\n        # setup event will be re-entered through jtag arp_init\n        # break the recursion\n        set jtag_configured 1\n        # re-initialized the jtag chain\n        jtag arp_init\n    }\n}\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\nset _smp_command \"\"\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset _cores 4\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        #set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\ntarget create uscale.axi mem_ap -dap uscale.dap -ap-num 0\n\neval $_smp_command\ntargets $_TARGETNAME.0\n\nproc core_up { args } {\n    global _TARGETNAME\n    foreach core $args {\n        $_TARGETNAME.$core arp_examine\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/xmc1xxx.cfg",
    "content": "#\n# Infineon XMC1100/XMC1200/XMC1300 family (ARM Cortex-M0 @ 32 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc1000\n}\n\n#\n# Only SWD and SPD supported\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_SWD_TAPID $CPUTAPID\n} else {\n\tset _CPU_SWD_TAPID 0x0BB11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n                       -work-area-size $_WORKAREASIZE \\\n                       -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/xmc4xxx.cfg",
    "content": "#\n# Infineon XMC4100/XMC4200/XMC4400/XMC4500 family (ARM Cortex-M4 @ 80-120 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc4000\n}\n\nsource [find target/swj-dp.tcl]\n\n#\n# SWJ-DP\n#\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x4BA00477\n}\n\n#\n# SW_DP\n#\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16 kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc4xxx 0x0C000000 0 0 0 $_TARGETNAME\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/xmos_xs1-xau8a-10_arm.cfg",
    "content": "#\n# XMOS xCORE-XA XS1-XAU8A-10: ARM Cortex-M3 @ 48 MHz\n#\n# http://www.xmos.com/products/silicon/xcore-xa/xa-series\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME xcorexa\n}\n\nif { ![info exists WORKAREASIZE] } {\n\t# XS1-XAU8A-10-FB265: 128 KB SRAM\n\tset WORKAREASIZE 0x20000\n}\n\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/zynq_7000.cfg",
    "content": "#\n# Xilinx Zynq-7000 All Programmable SoC\n#\n# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm\n#\n\nset _CHIPNAME zynq\nset _TARGETNAME $_CHIPNAME.cpu\n\njtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \\\n    -expected-id 0x23727093 \\\n    -expected-id 0x13722093 \\\n    -expected-id 0x03727093 \\\n    -expected-id 0x03736093\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 0 -dbgbase 0x80090000\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 1 -dbgbase 0x80092000\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n\nadapter speed 1000\n\n${_TARGETNAME}0 configure -event reset-assert-post \"cortex_a dbginit\"\n${_TARGETNAME}1 configure -event reset-assert-post \"cortex_a dbginit\"\n\npld device virtex2 zynq_pl.bs 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc zynqpl_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/target/к1879xб1я.cfg",
    "content": "# СБИС К1879ХБ1Я\n# http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/\n\nadapter speed 1000\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME к1879хб1я\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists DSP_TAPID] } {\n    set _DSP_TAPID $DSP_TAPID\n} else {\n    set _DSP_TAPID 0x2b900f0f\n}\n\njtag newtap $_CHIPNAME dsp -irlen 4 -expected-id $_DSP_TAPID\n\nif { [info exists CPU_TAPID] } {\n    set _CPU_TAPID $CPU_TAPID\n} else {\n    set _CPU_TAPID 0x07b76f0f\n}\n\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_CHIPNAME.arm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/test/selftest.cfg",
    "content": "\nadd_help_text selftest \"run selftest using working ram <tmpfile> <address> <size>\"\n\nproc selftest {tmpfile address size} {\n\n   for {set i 0} {$i < $size } {set i [expr {$i+4}]} {\n       mww [expr {$address+$i}] $i\n   }\n\n   for {set i 0} {$i < 10 } {set i [expr {$i+1}]} {\n    echo \"Test iteration $i\"\n    dump_image $tmpfile $address $size\n\tverify_image $tmpfile $address bin\n\tload_image $tmpfile $address bin\n   }\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/test/syntax1.cfg",
    "content": "adapter srst delay 200\njtag_ntrst_delay 200\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough\nadapter assert trst assert srst\nadapter deassert trst deassert srst\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap lpc2148 one -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4f1f0f0f\n\n#target configuration\n#daemon_startup reset\n\nset _TARGETNAME [format \"%s.cpu\" lpc2148]\ntarget create lpc2148.cpu arm7tdmi -endian little -work-area-size 0x4000 -work-area-phys 0x40000000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\nsoft_reset_halt\nmvb 0xE01FC040 0x01\n}\n\n\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/tools/firmware-recovery.tcl",
    "content": "echo \"\\n\\nFirmware recovery helpers\"\necho \"Use -c firmware_help to get help\\n\"\n\nset known_boards {\n    \"asus-rt-n16\t\tASUS RT-N16\"\n    \"asus-rt-n66u\t\tASUS RT-N66U\"\n    \"linksys-wag200g\t\tLinksys WAG200G\"\n    \"linksys-wrt54gl\t\tLinksys WRT54GL v1.1\"\n    \"netgear-dg834v3\t\tNetgear DG834G v3\"\n    \"tp-link_tl-mr3020\t\tTP-LINK TL-MR3020\"\n    \"bt-homehubv1\t\tBT HomeHub v1\"\n}\n\nproc firmware_help { } {\n    echo \"\nYour OpenOCD command should look like this:\nopenocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \\\"<commands>*; shutdown\\\"\n\nWhere:\n<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2\n<commands> are firmware-recovery commands separated by semicolon\n\nSupported commands:\nfirmware_help\t\t\tget this help\nlist_boards\t\t\tlist known boards and exit\nboard <name>\t\t\tselect board you work with\nlist_partitions\t\t\tlist partitions of the currently selected board\ndump_part <name> <filename>\tsave partition's contents to a file\nerase_part <name>\t\terase the given partition\nflash_part <name> <filename>\terase, flash and verify the given partition\nram_boot <filename>\t\tload binary file to RAM and run it\nadapter speed <freq>\t\tset JTAG clock frequency in kHz\n\nFor example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:\nopenocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\\\\n\t-c \\\"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\\\"\n\\n\\n\"\n    shutdown\n}\n\n# set default, can be overridden later\nadapter speed 1000\n\nproc get_partition { name } {\n    global partition_list\n    dict get $partition_list $name\n}\n\nproc partition_desc { name } { lindex [get_partition $name] 0 }\nproc partition_start { name } { lindex [get_partition $name] 1 }\nproc partition_size { name } { lindex [get_partition $name] 2 }\n\nproc list_boards { } {\n    global known_boards\n    echo \"List of the supported boards:\\n\"\n    echo \"Board name\\t\\tDescription\"\n    echo \"-----------------------------------\"\n    foreach i $known_boards {\n\techo $i\n    }\n    echo \"\\n\\n\"\n}\n\nproc board { name } {\n    script [find board/$name.cfg]\n}\n\nproc list_partitions { } {\n    global partition_list\n    set fstr \"%-16s%-14s%-14s%s\"\n    echo \"\\nThe currently selected board is known to have these partitions:\\n\"\n    echo [format $fstr Name Start Size Description]\n    echo \"-------------------------------------------------------\"\n    for {set i 0} {$i < [llength $partition_list]} {incr i 2} {\n\tset key [lindex $partition_list $i]\n\techo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]\n    }\n    echo \"\\n\\n\"\n}\n\n# Magic to work with any targets, including semi-functional\nproc prepare_target { } {\n    init\n    catch {halt}\n    catch {reset init}\n    catch {halt}\n}\n\nproc dump_part { name filename } {\n    prepare_target\n    dump_image $filename [partition_start $name] [partition_size $name]\n}\n\nproc erase_part { name } {\n    prepare_target\n    flash erase_address [partition_start $name] [partition_size $name]\n}\n\nproc flash_part { name filename } {\n    prepare_target\n    flash write_image erase $filename [partition_start $name] bin\n    echo \"Verifying:\"\n    verify_image $filename [partition_start $name]\n}\n\nproc ram_boot { filename } {\n    global ram_boot_address\n    prepare_target\n    load_image $filename $ram_boot_address bin\n    resume $ram_boot_address\n}\n\necho \"\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/tools/memtest.tcl",
    "content": "# Algorithms by Michael Barr, released into public domain\n# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser\n\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nsource [find bitsbytes.tcl]\nsource [find memory.tcl]\n\nproc runAllMemTests { baseAddress nBytes } {\n    memTestDataBus $baseAddress\n    memTestAddressBus $baseAddress $nBytes\n    memTestDevice $baseAddress $nBytes\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDataBus()\n# *\n# * Description: Test the data bus wiring in a memory region by\n# *              performing a walking 1's test at a fixed address\n# *              within that region.  The address (and hence the\n# *              memory region) is selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first pattern that failed.\n# *\n#***********************************************************************************\nproc memTestDataBus { address } {\n    echo \"Running memTestDataBus\"\n\n    for {set i 0} {$i < 32} {incr i} {\n\t# Shift bit\n\tset pattern [expr {1 << $i}]\n\n\t# Write pattern to memory\n\tmemwrite32 $address $pattern\n\n\t# Read pattern from memory\n\tset data [memread32 $address]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data\"\n\t    return $pattern\n\t}\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestAddressBus()\n# *\n# * Description: Perform a walking 1's test on the relevant bits\n# *              of the address and check for aliasing.  This test\n# *              will find single-bit address failures such as stuck\n# *              -high, stuck-low, and shorted pins.  The base address\n# *              and size of the region are selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# *\n# * Notes:       For best results, the selected base address should\n# *              have enough LSB 0's to guarantee single address bit\n# *              changes.  For example, to test a 64-Kbyte region,\n# *              select a base address on a 64-Kbyte boundary.  Also,\n# *              select the region size as a power-of-two--if at all\n# *              possible.\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              aliasing problem was uncovered.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestAddressBus { baseAddress nBytes } {\n    set addressMask [expr {$nBytes - 1}]\n    set pattern 0xAAAAAAAA\n    set antipattern 0x55555555\n\n    echo \"Running memTestAddressBus\"\n\n    echo \"addressMask: [convertToHex $addressMask]\"\n\n    echo \"memTestAddressBus: Writing the default pattern at each of the power-of-two offsets...\"\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {\n\tset addr [expr {$baseAddress + $offset}]\n\tmemwrite32 $addr $pattern\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck high...\"\n    memwrite32 $baseAddress $antipattern\n\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck low or shorted...\"\n    memwrite32 $baseAddress $pattern\n    for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $antipattern\n\n\tset data [memread32 $baseAddress]\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n\n\tfor {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\t    set addr [expr {$baseAddress + $offset}]\n\t    set data [memread32 $baseAddress]\n\n            if {(($data != $pattern) && ($offset != $testOffset))} {\n\t\techo \"FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]\"\n\t\treturn $pattern\n\t    }\n        }\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $pattern\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDevice()\n# *\n# * Description: Test the integrity of a physical memory device by\n# *              performing an increment/decrement test over the\n# *              entire region.  In the process every storage bit\n# *              in the device is tested as zero and as one.  The\n# *              base address and the size of the region are\n# *              selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              incorrect value was read back.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestDevice { baseAddress nBytes } {\n    echo \"Running memTestDevice\"\n\n    echo \"memTestDevice: Filling memory with a known pattern...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tmemwrite32 [expr {$baseAddress + $offset}] $pattern\n    }\n\n    echo \"memTestDevice: Checking each location and inverting it for the second pass...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]\"\n\t    return $pattern\n\t}\n\n\tset antiPattern [expr {~$pattern}]\n\tmemwrite32 [expr {$baseAddress + $offset}] $antiPattern\n    }\n\n    echo \"memTestDevice: Checking each location for the inverted pattern and zeroing it...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset antiPattern [expr {~$pattern & ((1<<32) - 1)}]\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\tset dataHex [convertToHex $data]\n\tset antiPatternHex [convertToHex $antiPattern]\n\tif {$dataHex != $antiPatternHex} {\n\t    echo \"FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset\"\n\t    return $pattern\n\t}\n    }\n}\n\nproc convertToHex { value } {\n    format 0x%08x $value\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/OpenOCD_CH347/share/openocd/scripts/tools/test_cpu_speed.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Description:\n#  Measure the CPU clock frequency of an ARM Cortex-M based device.\n#\n# Return:\n#  The CPU clock frequency in Hz. A negative value indicates that the loop\n#  counter was saturated.\n#\n# Note:\n#  You may need to adapt the number of cycles for your device.\n#\nadd_help_text cortex_m_test_cpu_speed \"Measure the CPU clock frequency of an ARM Cortex-M based device\"\nadd_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}\nproc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {\n\tset loop_counter_start 0xffffffff\n\n\thalt\n\n\t# Backup registers and memory.\n\tset backup_regs [get_reg -force {pc r0 xPSR}]\n\tset backup_mem [read_memory $address 16 3]\n\n\t# We place the following code at the given address to measure the\n\t# CPU clock frequency:\n\t#\n\t# 3801: subs r0, #1\n\t# d1fd: bne #-2\n\t# e7fe: b #-4\n\twrite_memory $address 16 {0x3801 0xd1fd 0xe7fe}\n\n\tset_reg \"pc $address r0 $loop_counter_start\"\n\tresume\n\tsleep $timeout\n\thalt\n\n\t# Get the loop counter value from register r0.\n\tset loop_counter_end [dict values [get_reg r0]]\n\tset loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]\n\n\t# Restore registers and memory.\n\tset_reg $backup_regs\n\twrite_memory $address 16 $backup_mem\n\n\tif { [expr {$loop_counter_end == 0}] } {\n\t\treturn -1\n\t}\n\n\treturn [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/CH347FPGATool/README.md",
    "content": "# **简介**\n\n​\tCH347FPGADownloader是一款专用于CH347的FPGA下载软件，结合OpenOCD开源项目实现。\n\n​\t当前支持FPGA型号主要以xilinx为主，其中具体型号如下：\n\n![image-20221027190604695](README.assets/image-20221027190604695.png)\n\n# **软件使用**\n\n## **界面显示**\n\n![image-20221027190616419](README.assets/image-20221027190616419.png)\n\n## **下载设置选项**\n\n![image-20221027190632574](README.assets/image-20221027190632574.png)\n\n​\t1.“选择FPGA型号”：选择本次进行操作的FPGA型号，该选择框可编辑，可根据输入内容进行支持列表匹配；\n\n​\t2.“选择下载文件类型”：\n\n​\t\tA. BIT文件方式下载：此选择默认将BIT文件下载至FPGA RAM当中，且掉电丢失，上电需重新下载；\n\n​\t\tB. BIN文件方式下载：此选择默认将BIN文件下载至FPGA连接的FLASH当中，程序固化至FLASH，下载完毕后自动软件复位FPGA运行程序；\n\n​\t3.“选择硬件时钟”：选择CH347作为JTAG接口的TCK时钟频率，此处默认10M、15M、30M设定，若需要其他频率可手动输入；\n\n​\t4.“关于”：查看软件版本信息；\n\n​\t5.“选择下载文件”：点击根据当前下载方式来选择此次操作所需bit或bin文件，会默认记住此次选择文件路径，下次选择时进入该路径；\n\n​\t6.“下载”：BIN下载方式下将显示下载进度条，下载完毕自动隐藏，选择BIN文件下载方式时也会自定显示下载进度条；\n\n![image-20221027190647377](README.assets/image-20221027190647377.png)\n\n## **信息输出**\n\n![image-20221027190701769](README.assets/image-20221027190701769.png)\n\n​\t1.“设备信息”：动态显示CH347-JTAG接口插拔信息\n\n​\t2. “清屏”：情况当前黑色显示框中内容\n\n# **软件获取地址**\n\n[WCHSoftGroup/ch347: ch347 480Mbps high-speed USB to Jtag/I2C/SPI/Uart/GPIO etc. (github.com)](https://github.com/WCHSoftGroup/ch347/CH347FPGADownloader)"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/README.md",
    "content": "# ch347\nCH347是一款高速USB总线转接芯片，通过USB总线提供UART、I2C、SPI、JTAG等接口。\n\n## JTAG调试/下载\n\n本章节介绍如何在OpenOCD中添加CH347-JTAG接口，通过OpenOCD可操作CH347进行JTAG调试或下载应用。\n\n## 为OpenOCD添加接口\n\nOpenOCD增加CH347配置文件，用于型号识别，操作方式：\n\n### 1、目录tcl/target下添加CH347.cfg设备文件\n\n```\n    adapter driver ch347\n    ch347 vid_pid 0x1a86 0x55dd \n    adapter speed 10000\n```\n\n\n\n### 2、目录src/jtag/driver下添加ch347.c文件\n\n​\t\t此文件为设备驱动文件，提供JTAG core操作CH347的API接口函数\n\n### 3、修改配置文件\n\n**修改配置文件 configure.ac**\n1、OpenOCD根目录下configure.ac文件，添加CH347接口驱动支持：\n\n    a. m4_define([USB1_ADAPTERS]中添加CH347接口\n        m4_define([USB1_ADAPTERS],\n        [[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]],\n        [[ch347], [Mode 3 of the CH347 devices], [CH347]],\n        [[stlink], [ST-Link Programmer], [HLADAPTER_STLINK]],\n        [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]],\n        [[ulink], [Keil ULINK JTAG Programmer], [ULINK]],\n        [[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]],\n        [[ft232r], [Bitbang mode of FT232R based devices], [FT232R]],\n        [[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]],\n        [[xds110], [TI XDS110 Debug Probe], [XDS110]],\n        [[cmsis_dap_v2], [CMSIS-DAP v2 Compliant Debugger], [CMSIS_DAP_USB]],\n        [[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]],\n        [[opendous], [eStick/opendous JTAG Programmer], [OPENDOUS]],\n        [[armjtagew], [Olimex ARM-JTAG-EW Programmer], [ARMJTAGEW]],\n        [[rlink], [Raisonance RLink JTAG Programmer], [RLINK]],\n        [[usbprog], [USBProg JTAG Programmer], [USBPROG]],\n        [[aice], [Andes JTAG Programmer], [AICE]]])\n    \n    b. AC_ARG_ENABLE 部分，添加内容如下：\n        AC_ARG_ENABLE([ch347],\n         AS_HELP_STRING([--enable-ch347], [Enable building support for CH347]),\n         [build_ch347=$enableval], [build_ch347=no])\n    \n    c. AS_IF 部分，添加内容如下：\n         AS_IF([test \"x$build_ch347\" = \"xyes\"], [\n          AC_DEFINE([BUILD_CH347], [1], [1 if you want CH347.])\n         ], [\n           AC_DEFINE([BUILD_CH347], [0], [0 if you don't want CH347.])\n         ])\n    \n    d. AM_CONDITIONAL 部分，添加内容如下：\n         AM_CONDITIONAL([CH347], [test \"x$build_ch347\" = \"xyes\"])\n\n**修改src/jtag/interfaces.c**\n\n    a. 添加编译选项\n        #if BUILD_CH347 == 1\n        extern struct adapter_driver ch347_adapter_driver;\n        #endif\n    b. 在jtag接口列表结构体adapter_drivers中添加，此处由配置脚本来启用对应接口驱动\n        #if BUILD_CH347 == 1\n        \t&ch347_adapter_driver,\n        #endif\n\n**修改/src/jtag/drivers/Makefile.am**\n\n```\na. 添加编译支持\n     if CH347\n     DRIVERFILES += %D%/ch347_jtag.c\n     endif\n```\n\n### 4、编译方法\n\n**使用cygwin进行编译**\n\n```\na. 执行./bootstrap\nb. 执行./configure --prefix=/home/OpenOCD/CH347 --enable-ch347 --host=i686-w64-mingw32 CFLAGS='-g -o0'\nc. 执行make install\nd. 编译成功时/home/OpenOCD/CH347文件夹下会生成目标文件，其中bin目录下为OpenOCD可执行文件。\n```\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/bin/ch347.cfg",
    "content": "adapter driver ch347\nch347 vid_pid 0x1a86 0x55dd \n\nadapter speed 10000\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/contrib/60-openocd.rules",
    "content": "# Copy this file to /etc/udev/rules.d/\n# If rules fail to reload automatically, you can refresh udev rules\n# with the command \"udevadm control --reload\"\n\nACTION!=\"add|change\", GOTO=\"openocd_rules_end\"\n\nSUBSYSTEM==\"gpio\", MODE=\"0660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nSUBSYSTEM!=\"usb|tty|hidraw\", GOTO=\"openocd_rules_end\"\n\n# Please keep this list sorted by VID:PID\n\n# opendous and estick\nATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"204f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232/FT245 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT2232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT4232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232H VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Original FT231XQ VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# DISTORTEC JTAG-lock-pick Tiny 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8220\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TUMPA, TUMPA Lite\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a98\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a99\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell OpenRD JTAGKey FT2232D B\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"9e90\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# XDS100v2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# XDS100v3\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OOCDLink\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"baf8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Kristech KT-Link\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bbe2\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris Evaluation Board FTDI (several)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcd9\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcda\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# egnite Turtelizer 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bdc8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Section5 ICEbear\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c140\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c141\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey and JTAGkey-tiny\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"cff8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ASIX Presto programmer\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"f1a0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Nuvoton NuLink\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5200\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5201\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI ICDI\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"c32a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK V1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3744\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3748\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2.1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3752\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics STLINK-V3\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3753\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3754\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress SuperSpeed Explorer Kit\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"0007\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in KitProg mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f139\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in CMSIS-DAP mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f138\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Infineon DAP miniWiggler v3\nATTRS{idVendor}==\"058b\", ATTRS{idProduct}==\"0043\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex LPC1768-Stick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0026\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hilscher NXHX Boards\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0028\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STR9-comStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STM32-PerformanceStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex Cortino\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0032\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Altera USB Blaster\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Altera USB Blaster2\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6810\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ashling Opella-LD\nATTRS{idVendor}==\"0B6B\", ATTRS{idProduct}==\"0040\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey-HiSpeed\nATTRS{idVendor}==\"0fbb\", ATTRS{idProduct}==\"1000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# SEGGER J-Link\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0101\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0102\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0103\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0104\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0105\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0107\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0108\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1012\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1013\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1016\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1017\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1018\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1020\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1051\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1055\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1061\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Raisonance RLink\nATTRS{idVendor}==\"138e\", ATTRS{idProduct}==\"9000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Debug Board for Neo1973\nATTRS{idVendor}==\"1457\", ATTRS{idProduct}==\"5118\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OSBDM\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0042\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0058\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"005e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0003\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0004\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-JTAG-EW\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"001e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC\nATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"06ad\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# USBprog with OpenOCD firmware\nATTRS{idVendor}==\"1781\", ATTRS{idProduct}==\"0c63\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00fd\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI XDS110 Debug Probe (Launchpads and Standalone)\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef3\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef4\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"02a5\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI Tiva-based ICDI and XDS110 probes in DFU mode\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00ff\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# isodebug v1\nATTRS{idVendor}==\"22b7\", ATTRS{idProduct}==\"150d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# PLS USB/JTAG Adapter for SPC5xxx\nATTRS{idVendor}==\"263d\", ATTRS{idProduct}==\"4001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Numato Mimas A7 - Artix 7 FPGA Board\nATTRS{idVendor}==\"2a19\", ATTRS{idProduct}==\"1009\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ambiq Micro EVK and Debug boards.\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"1106\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell Sheevaplug\nATTRS{idVendor}==\"9e88\", ATTRS{idProduct}==\"9e8f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Keil Software, Inc. ULink\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2710\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2750\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# CMSIS-DAP compatible adapters\nATTRS{product}==\"*CMSIS-DAP*\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nLABEL=\"openocd_rules_end\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/contrib/libdcc/README",
    "content": "This code is an example of using the openocd debug message system.\n\nBefore the message output is seen in the debug window, the functionality\nwill need enabling:\n\nFrom the gdb prompt:\nmonitor target_request debugmsgs enable\nmonitor trace point 1\n\nFrom the Telnet prompt:\ntarget_request debugmsgs enable\ntrace point 1\n\nTo see how many times the trace point was hit:\n(monitor) trace point 1\n\nSpen\nspen@spen-soft.co.uk\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/contrib/libdcc/dcc_stdio.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n#define TARGET_REQ_TRACEMSG\t\t\t\t\t0x00\n#define TARGET_REQ_DEBUGMSG_ASCII\t\t\t0x01\n#define TARGET_REQ_DEBUGMSG_HEXMSG(size)\t(0x01 | ((size & 0xff) << 8))\n#define TARGET_REQ_DEBUGCHAR\t\t\t\t0x02\n\n#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)\n\n/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel\n * DCRDR[7:0] is used by target for status\n * DCRDR[15:8] is used by target for write buffer\n * DCRDR[23:16] is used for by host for status\n * DCRDR[31:24] is used for by host for write buffer */\n\n#define NVIC_DBG_DATA_R\t\t(*((volatile unsigned short *)0xE000EDF8))\n\n#define\tBUSY\t1\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tint len = 4;\n\n\twhile (len--)\n\t{\n\t\t/* wait for data ready */\n\t\twhile (NVIC_DBG_DATA_R & BUSY);\n\n\t\t/* write our data and set write flag - tell host there is data*/\n\t\tNVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);\n\t\tdcc_data >>= 8;\n\t}\n}\n\n#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tunsigned long dcc_status;\n\n\tdo {\n\t\tasm volatile(\"mrc p14, 0, %0, c0, c0\" : \"=r\" (dcc_status));\n\t} while (dcc_status & 0x2);\n\n\tasm volatile(\"mcr p14, 0, %0, c1, c0\" : : \"r\" (dcc_data));\n}\n\n#else\n #error unsupported target\n#endif\n\nvoid dbg_trace_point(unsigned long number)\n{\n\tdbg_write(TARGET_REQ_TRACEMSG | (number << 8));\n}\n\nvoid dbg_write_u32(const unsigned long *val, long len)\n{\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdbg_write(*val);\n\n\t\tval++;\n\t\tlen--;\n\t}\n}\n\nvoid dbg_write_u16(const unsigned short *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 16: 0x0000);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 2;\n\t\tlen -= 2;\n\t}\n}\n\nvoid dbg_write_u8(const unsigned char *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? val[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? val[3] << 24 : 0x00);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_str(const char *msg)\n{\n\tlong len;\n\tunsigned long dcc_data;\n\n\tfor (len = 0; msg[len] && (len < 65536); len++);\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = msg[0]\n\t\t\t| ((len > 1) ? msg[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? msg[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? msg[3] << 24 : 0x00);\n\t\tdbg_write(dcc_data);\n\n\t\tmsg += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_char(char msg)\n{\n\tdbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/contrib/libdcc/dcc_stdio.h",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#ifndef DCC_STDIO_H\n#define DCC_STDIO_H\n\nvoid dbg_trace_point(unsigned long number);\n\nvoid dbg_write_u32(const unsigned long *val, long len);\nvoid dbg_write_u16(const unsigned short *val, long len);\nvoid dbg_write_u8(const unsigned char *val, long len);\n\nvoid dbg_write_str(const char *msg);\nvoid dbg_write_char(char msg);\n\n#endif\t/* DCC_STDIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/contrib/libdcc/example.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n/* enable openocd debugmsg at the gdb prompt:\n * monitor target_request debugmsgs enable\n *\n * create a trace point:\n * monitor trace point 1\n *\n * to show how often the trace point was hit:\n * monitor trace point\n*/\n\nint main(void)\n{\n\tdbg_write_str(\"hello world\");\n\n\tdbg_write_char('t');\n\tdbg_write_char('e');\n\tdbg_write_char('s');\n\tdbg_write_char('t');\n\tdbg_write_char('\\n');\n\n\tunsigned long test_u32 = 0x01234567;\n\tdbg_write_u32(&test_u32, 1);\n\n\tstatic const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF};\n\tdbg_write_u16(test_u16, 8);\n\n\tstatic const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF};\n\tdbg_write_u8(test_u8, 16);\n\n\twhile(1)\n\t{\n\t\tdbg_trace_point(0);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/bitsbytes.tcl",
    "content": "#----------------------------------------\n# Purpose - Create some $BIT variables\n#           Create $K and $M variables\n#          and some bit field extraction variables.\n# Create helper variables ...\n#    BIT0.. BIT31\n\nfor { set x 0  } { $x < 32 } { set x [expr {$x + 1}]} {\n    set vn [format \"BIT%d\" $x]\n    global $vn\n    set $vn   [expr {1 << $x}]\n}\n\n# Create K bytes values\n#    __1K ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dK\" $x]\n    global $vn\n    set $vn   [expr {1024 * $x}]\n}\n\n# Create M bytes values\n#    __1M ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dM\" $x]\n    global $vn\n    set $vn [expr {1024 * 1024 * $x}]\n}\n\nproc create_mask { MSB LSB } {\n    return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}]\n}\n\n# Cut Bits $MSB to $LSB out of this value.\n# Example: % format \"0x%08x\" [extract_bitfield 0x12345678 27 16]\n# Result:  0x02340000\n\nproc extract_bitfield { VALUE MSB LSB } {\n    return [expr {[create_mask $MSB $LSB] & $VALUE}]\n}\n\n\n# Cut bits $MSB to $LSB out of this value\n# and shift (normalize) them down to bit 0.\n#\n# Example: % format \"0x%08x\" [normalize_bitfield 0x12345678 27 16]\n# Result:  0x00000234\n#\nproc normalize_bitfield { VALUE MSB LSB } {\n    return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}]\n}\n\nproc show_normalize_bitfield { VALUE MSB LSB } {\n    set m [create_mask $MSB $LSB]\n    set mr [expr {$VALUE & $m}]\n    set sr [expr {$mr >> $LSB}]\n    echo [format \"((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d \" $VALUE $m $mr $LSB $sr $sr]\n   return $sr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/8devices-lima.cfg",
    "content": "# Product page:\n# https://www.8devices.com/products/lima\n#\n# Location of JTAG pins:\n# J2 GPIO0\tJTAG TCK\n# J2 GPIO1\tJTAG TDI\n# J2 GPIO2\tJTAG TDO\n# J2 GPIO3\tJTAG TMS\n# J2 RST\tdirectly connected to RESET_L of the SoC and can be used as\n#               JTAG SRST. Note: this pin will also reset the debug engine.\n# J1 +3,3V\tCan be use as JTAG Vref\n# J1 or J2 GND\tCan be used for JTAG GND\n#\n# This board is powered from mini USB connecter which is also used\n# as USB to UART converted based on FTDI FT230XQ chip\n\nsource [find target/qualcomm_qca4531.cfg]\n\nproc board_init { } {\n\tqca4531_ddr2_550_550_init\n}\n\n$_TARGETNAME configure -event reset-init {\n\tboard_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/actux3.cfg",
    "content": "# board config file for AcTux3/XBA IXP42x board\n# Date:   2010-12-16\n# Author: Michael Schwingen <michael@schwingen.org>\n\nreset_config trst_and_srst separate\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nsource [find target/ixp42x.cfg]\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init { init_actux3 }\n\nproc init_actux3 { } {\n    ##########################################################################\n    # setup expansion bus CS\n    ##########################################################################\n    mww 0xc4000000  0xbd113842  ;#CS0  : Flash, write enabled @0x50000000\n    mww 0xc4000004  0x94d10013  ;#CS1\n    mww 0xc4000008  0x95960003  ;#CS2\n    mww 0xc400000c  0x00000000  ;#CS3\n    mww 0xc4000010  0x80900003  ;#CS4\n    mww 0xc4000014  0x9d520003  ;#CS5\n    mww 0xc4000018  0x81860001  ;#CS6\n    mww 0xc400001c  0x80900003  ;#CS7\n\n    ixp42x_init_sdram $::IXP42x_SDRAM_16MB_4Mx16_1BANK 2100 3\n\n    #mww 0xc4000020  0xffffee ;# CFG0: remove expansion bus boot flash mirror at 0x00000000\n\n    ixp42x_set_bigendian\n\n    flash probe 0\n}\n\nproc flash_boot { {FILE \"/tftpboot/actux3/u-boot.bin\"} } {\n    echo \"writing bootloader: $FILE\"\n    flash write_image erase $FILE 0x50000000 bin\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x400000 2 2 $_TARGETNAME\n\ninit\nreset init\n\n# setup to debug u-boot in flash\nproc uboot_debug {} {\n    gdb_breakpoint_override hard\n    xscale vector_catch 0xFF\n\n    xscale vector_table low  1 0xe59ff018\n    xscale vector_table low  2 0xe59ff018\n    xscale vector_table low  3 0xe59ff018\n    xscale vector_table low  4 0xe59ff018\n    xscale vector_table low  5 0xe59ff018\n    xscale vector_table low  6 0xe59ff018\n    xscale vector_table low  7 0xe59ff018\n\n    xscale vector_table high 1 0xe59ff018\n    xscale vector_table high 2 0xe59ff018\n    xscale vector_table high 3 0xe59ff018\n    xscale vector_table high 4 0xe59ff018\n    xscale vector_table high 5 0xe59ff018\n    xscale vector_table high 6 0xe59ff018\n    xscale vector_table high 7 0xe59ff018\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/adapteva_parallella1.cfg",
    "content": "#\n# Adapteva Parallella-I board (via Porcupine-1 adapter board)\n#\n\nreset_config srst_only\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/adsp-sc584-ezbrd.cfg",
    "content": "#\n# Analog Devices ADSP-SC584-EZBRD evaluation board\n#\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\n# Analog expects users to use their proprietary ICE-1000 / ICE-2000 with all\n# ADSP-SC58x designs, but this is an ARM target (and subject to the\n# qualifications above) many ARM debug pods should be compatible.\n\n#source [find interface/cmsis-dap.cfg]\nsource [find interface/jlink.cfg]\n\n# Analog's silicon supports SWD and JTAG, but their proprietary ICE is limited\n# to JTAG.  (This is presumably why their connector pinout was modified.)\n# SWD is chosen here, as it is more efficient and doesn't require /TRST.\n\ntransport select swd\n\n# chosen speed is 'safe' choice, but your adapter may be capable of more\nadapter speed 400\n\nsource [find target/adsp-sc58x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/alphascale_asm9260_ek.cfg",
    "content": "source [find target/alphascale_asm9260t.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configure clock\"\n\t# Enable SRAM clk\n\tmww 0x80040024 0x4\n\t# Enable IRQ clk\n\tmww 0x80040034 0x100\n\t# Enable DMA0,1 clk\n\tmww 0x80040024 0x600\n\t# Make sysre syspll is enabled\n\tmww 0x80040238 0x750\n\t#CPU = PLLCLK/2\n\tmww 0x8004017C 0x2\n\t#SYSAHBCLK = CPUCLK/2\n\tmww 0x80040180 0x2\n\t# Set PLL freq to 480MHz\n\tmww 0x80040100 480\n\t# normally we shoul waiting here until we get 0x1 (0x80040104)&0x1)==0x0)\n\tsleep 100\n\n\t# select PLL as main source\n\tmww 0x80040120 0x1\n\t# disable and enable main clk to update changes?\n\tmww 0x80040124 0x0\n\tmww 0x80040124 0x1\n\n\techo \"Configure memory\"\n\t#enable EMI CLK\n\tmww 0x80040024 0x40\n\n\t# configure memory controller for internal SRAM\n\tmww 0x80700000 0x1188\n\t# change default emi clk delay\n\tmww 0x8004034C 0xA0503\n\t# make sure chip_select_register2_low has correct value (why?)\n\tmww 0x8070001c 0x20000000\n\t# set type to sdram and size to 32MB\n\tmww 0x8070005c 0xa\n\t# configure internal SDRAM timing\n\tmww 0x80700004 0x024996d9\n\t# configure Static Memory timing\n\tmww 0x80700094 0x00542b4f\n\n\techo \"Configure uart4\"\n\t# enable pinctrl clk\n\tmww 0x80040024 0x2000000\n\t# mux GPIO3_0 and GPIO3_1 to UART4\n\tmww 0x80044060 0x2\n\tmww 0x80044064 0x2\n\t# configure UART4CLKDIV\n\tmww 0x800401a8 0x1\n\t# enable uart4 clk\n\tmww 0x80040024 0x8000\n\t# clear softrst and clkgate on uart4\n\tmww 0x80010008 0xC0000000\n\t# set bandrate 115200 12M\n\tmww 0x80010030 0x00062070\n\t# enable Rx&Tx\n\tmww 0x80010024 0x301\n\t# clear hw control\n\tmww 0x80010028 0xc000\n}\n\n$_TARGETNAME configure -work-area-phys 0x21ffe000 -work-area-virt 0xc1ffe000 -work-area-size 0x1000\n$_TARGETNAME arm7_9 fast_memory_access enable\n$_TARGETNAME arm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/altera_sockit.cfg",
    "content": "#\n# Cyclone V SocKit board\n# http://www.altera.com/b/arrow-sockit.html\n#\n# Software support page:\n# http://www.rocketboards.org/\n\n# openocd does not currently support the on-board USB Blaster II.\n# Install the JTAG header and use a USB Blaster instead.\nadapter driver usb_blaster\n\nsource [find target/altera_fpgasoc.cfg]\n\n# If the USB Blaster II were supported, these settings would be needed\n#usb_blaster vid_pid 0x09fb 0x6810\n#usb_blaster device_desc \"USB-Blaster II\"\n\nadapter speed 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/am3517evm.cfg",
    "content": "# DANGER!!!! early work in progress for this PCB/target.\n#\n# The most basic operations work well enough that it is\n# useful to have this in the repository for cooperation\n# alpha testing purposes.\n#\n# TI AM3517\n#\n# http://focus.ti.com/docs/prod/folders/print/am3517.html\n# http://processors.wiki.ti.com/index.php/Debug_Access_Port_(DAP)\n# http://processors.wiki.ti.com/index.php?title=How_to_Find_the_Silicon_Revision_of_your_OMAP35x\n\nset CHIPTYPE \"am35x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit am35x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ampere_emag8180.cfg",
    "content": "#\n# OpenOCD Board Configuration for eMAG Development Platform\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure JTAG speed\n#\n\nadapter speed 2000\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nsource [find target/ampere_emag.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/arm_evaluator7t.cfg",
    "content": "# This board is from ARM and has an samsung s3c45101x01 chip\n\nsource [find target/samsung_s3c4510.cfg]\n\n#\n# FIXME:\n#  Add (A) sdram configuration\n#  Add (B) flash cfi programming configuration\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/arm_musca_a.cfg",
    "content": "#\n# Configuration script for ARM Musca-A development board\n#\n# For now we do not support Musca A flash programming using OpenOCD. However, a\n# work area is configured for flash programming speed up.\n#\n# GDB considers all memory as RAM unless target supplies a memory map.\n# OpenOCD will only send memory map if flash banks are configured. Otherwise,\n# configure GDB after connection by issuing following commands:\n# (gdb) mem 0x10200000 0x109FFFFF ro\n# (gdb) mem 0x00200000 0x009FFFFF ro\n# (gdb) set mem inaccessible-by-default off\n\n# ARM Musca A board supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME MUSCA_A\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x6ba00477\n}\n\n# Enable CPU1 debugging as a separate GDB target\nset _ENABLE_CPU1 1\n\n# Musca A1 has 32KB SRAM banks. Override default work-area-size to 8KB per CPU\nset WORKAREASIZE_CPU0 0x2000\nset WORKAREASIZE_CPU1 0x2000\n\n# Set SRAM bank 1 to be used for work area. Override here if needed.\nset WORKAREAADDR_CPU0 0x30008000\nset WORKAREAADDR_CPU1 0x3000A000\n\nsource [find target/arm_corelink_sse200.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/arty_s7.cfg",
    "content": "#\n# Arty S7: Spartan7 25/50 FPGA Board for Makers and Hobbyists\n#\n# https://www.xilinx.com/products/boards-and-kits/1-pnziih.html\n# https://store.digilentinc.com/arty-s7-spartan-7-fpga-board-for-makers-and-hobbyists/\n\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# Xilinx Spartan7-25/50 FPGA (XC7S{25,50}-CSGA324)\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n\n# Usage:\n#\n# Load Bitstream into FPGA:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    pld load 0 bitstream.bit;\\\n#    shutdown\"\n#\n# Write Bitstream to Flash:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    jtagspi_init 0 bscan_spi_xc7s??.bit;\\\n#    jtagspi_program bitstream.bin 0;\\\n#    xc7_program xc7.tap;\\\n#    shutdown\"\n#\n# jtagspi flash proxies can be found at:\n# https://github.com/quartiq/bscan_spi_bitstreams\n#\n# For the Spartan 50 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s50.bit\n# For the Spartan 25 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s25.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/asus-rt-n16.cfg",
    "content": "#\n# http://wikidevi.com/wiki/ASUS_RT-N16\n#\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4718.cfg]\n\n# External 32MB NOR Flash (Macronix MX29GL256EHTI2I-90Q)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/asus-rt-n66u.cfg",
    "content": "#\n# http://wikidevi.com/wiki/Asus_RT-N66U\n#\n\necho \"ATTENTION: you need to solder a 4.7-10k pullup resistor to pin 21 of flash IC\"\necho \"to enable JTAG, see http://wl500g.info/album.php?albumid=28&attachmentid=8991 ,\"\necho \"there is an unpopulated footprint near U8.\\n\"\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4706.cfg]\n\n# External 32MB NOR Flash (Spansion S29GL256P10TF101\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91cap7a-stk-sdram.cfg",
    "content": "# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394\n#\n# use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME cap7\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x40700f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start {\n\t# start off real slow when we're running off internal RC oscillator\n\tadapter speed 32\n}\n\nproc peek32 {address} {\n\treturn [read_memory $address 32 1]\n}\n\n# Wait for an expression to be true with a timeout\nproc wait_state {expression} {\n\tfor {set i 0} {$i < 1000} {set i [expr {$i + 1}]} {\n\t\tif {[uplevel 1 $expression] == 0} {\n\t\t\treturn\n\t\t}\n\t}\n\treturn -code 1 \"Timed out\"\n}\n\n# Use a global variable here to be able to tinker interactively with\n# post reset jtag frequency.\nglobal post_reset_khz\n# Danger!!!! Even 16MHz kinda works with this target, but\n# it needs to be as low as 2000kHz to be stable.\nset post_reset_khz 2000\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configuring master clock\"\n\t# disable watchdog\n\tmww 0xfffffd44 0xff008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# Enable main oscillator\n\tmww 0xFFFFFc20  0x00000f01\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}}\n\n\t# Set PLLA to 96MHz\n\tmww 0xFFFFFc28 0x20072801\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}}\n\n\t# Select prescaler\n\tmww 0xFFFFFC30 0x00000004\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\t# Select master clock to 48MHz\n\tmww 0xFFFFFC30 0x00000006\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\techo \"Master clock ok.\"\n\n\t# Now that we're up and running, crank up speed!\n\tglobal post_reset_khz ;\tadapter speed $post_reset_khz\n\n\techo \"Configuring the SDRAM controller...\"\n\n\t# Configure EBI Chip select for SDRAM\n\tmww 0xFFFFEF30 0x00000102\n\n\t# Enable clock on EBI PIOs\n\tmww 0xFFFFFC10 0x00000004\n\n\t# Configure PIO for SDRAM\n\tmww 0xFFFFF470 0xFFFF0000\n\tmww 0xFFFFF474 0x00000000\n\tmww 0xFFFFF404 0xFFFF0000\n\n\t# Configure SDRAMC CR\n\tmww 0xFFFFEA08 0xA63392F9\n\n\t# NOP command\n\tmww 0xFFFFEA00 0x1\n\tmww 0x20000000 0\n\n\t# Precharge All Banks command\n\tmww 0xFFFFEA00 0x2\n\tmww 0x20000000 0\n\n\t# Set 1st CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000010 0x00000001\n\n\t# Set 2nd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000020 0x00000002\n\n\t# Set 3rd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000030 0x00000003\n\n\t# Set 4th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000040 0x00000004\n\n\t# Set 5th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000050 0x00000005\n\n\t# Set 6th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000060 0x00000006\n\n\t# Set 7th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000070 0x00000007\n\n\t# Set 8th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000080 0x00000008\n\n\t# Set LMR operation\n\tmww 0xFFFFEA00 0x00000003\n\n\t# Perform LMR burst=1, lat=2\n\tmww 0x20000020 0xCAFEDEDE\n\n\t# Set Refresh Timer\n\tmww 0xFFFFEA04 0x00000203\n\n\t# Set Normal mode\n\tmww 0xFFFFEA00 0x00000000\n\tmww 0x20000000 0x00000000\n\n\t#remap internal memory at address 0x0\n\tmww 0xffffef00 0x3\n\n\techo \"SDRAM configuration ok.\"\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91eb40a.cfg",
    "content": "#Script for AT91EB40a\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\n\n#Atmel ties SRST & TRST together, at which point it makes\n#no sense to use TRST, but use TMS instead.\n#\n#The annoying thing with tying SRST & TRST together is that\n#there is no way to halt the CPU *before and during* the\n#SRST reset, which means that the CPU will run a number\n#of cycles before it can be halted(as much as milliseconds).\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n#flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME\n\n# required for usable performance. Used for lots of\n# other things than flash programming.\n$_TARGETNAME configure -work-area-phys 0x00030000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Running reset init script for AT91EB40A\"\n\t# Reset script for AT91EB40a\n\treg cpsr 0x000000D3\n\tmww 0xFFE00020 0x1\n\tmww 0xFFE00024 0x00000000\n\tmww 0xFFE00000 0x01002539\n\tmww 0xFFFFF124 0xFFFFFFFF\n\tmww 0xffff0010 0x100\n\tmww 0xffff0034 0x100\n}\n\n# This target is pretty snappy...\nadapter speed 16000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91rm9200-dk.cfg",
    "content": "#\n# This is for the \"at91rm9200-DK\" (not the EK) eval board.\n#\n# The two are probably very simular.... I have DK...\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_dk_init }\n\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME\n\n\nproc at91rm9200_dk_init { } {\n    # Try to run at 1khz... Yea, that slow!\n    # Chip is really running @ 32khz\n    adapter speed 8\n\n    mww 0xfffffc64 0xffffffff\n    ##  disable all clocks but system clock\n    mww 0xfffffc04 0xfffffffe\n    ##  disable all clocks to pioa and piob\n    mww 0xfffffc14 0xffffffc3\n    ##  master clock = slow cpu = slow\n    ##  (means the CPU is running at 32khz!)\n    mww 0xfffffc30 0\n    ##  main osc enable\n    mww 0xfffffc20 0x0000ff01\n    ##  program pllA\n    mww 0xfffffc28 0x20263e04\n    ##  program pllB\n    mww 0xfffffc2c 0x10483e0e\n    ##  let pll settle... sleep 100msec\n    sleep 100\n    ##  switch to fast clock\n    mww 0xfffffc30 0x202\n    ## Sleep some - (go read)\n    sleep 100\n\n    #========================================\n    # CPU now runs at 180mhz\n    # SYS runs at 60mhz.\n    adapter speed 40000\n    #========================================\n\n\n    ##  set memc for all memories\n    mww 0xffffff60 0x02\n    ##  program smc controller\n    mww 0xffffff70 0x3284\n    ##  init sdram\n    mww 0xffffff98 0x7fffffd0\n    ##  all banks precharge\n    mww 0xffffff80 0x02\n    ##  touch sdram chip to make it work\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    mww 0xffffff90 0x04\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    ##  Refresh, etc....\n    mww 0xffffff90 0x03\n    mww 0x20000080 0\n    mww 0xffffff94 0x1f4\n    mww 0x20000080 0\n    mww 0xffffff90 0x10\n    mww 0x20000000 0\n    mww 0xffffff00 0x01\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91rm9200-ek.cfg",
    "content": "#\n# Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>\n#\n# under GPLv2 Only\n#\n# This is for the \"at91rm9200-ek\" eval board.\n#\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_ek_init }\n\n## flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# The chip may run @ 32khz, so set a really low JTAG speed\nadapter speed 8\n\nproc at91rm9200_ek_init { } {\n\t# Try to run at 1khz... Yea, that slow!\n\t# Chip is really running @ 32khz\n\tadapter speed 8\n\n\tmww 0xfffffc64 0xffffffff\n\t## disable all clocks but system clock\n\tmww 0xfffffc04 0xfffffffe\n\t## disable all clocks to pioa and piob\n\tmww 0xfffffc14 0xffffffc3\n\t## master clock = slow cpu = slow\n\t## (means the CPU is running at 32khz!)\n\tmww 0xfffffc30 0\n\t## main osc enable\n\tmww 0xfffffc20 0x0000ff01\n\t## MC_PUP\n\tmww 0xFFFFFF50 0x00000000\n\t## MC_PUER: Memory controller protection unit disable\n\tmww 0xFFFFFF54 0x00000000\n\t## EBI_CFGR\n\tmww 0xFFFFFF64 0x00000000\n\t## SMC2_CSR[0]: 16bit, 2 TDF, 4 WS\n\tmww 0xFFFFFF70 0x00003284\n\n\t## Init Clocks\n\t## CKGR_PLLAR\n\tmww 0xFFFFFC28 0x2000BF05\n\t## PLLAR: 179,712000 MHz for PCK\n\tmww 0xFFFFFC28 0x20263E04\n\tsleep 100\n\t## PMC_MCKR\n\tmww 0xFFFFFC30 0x00000100\n\tsleep 100\n\t## ;MCKR : PCK/3 = MCK Master Clock = 59,904000MHz from PLLA\n\tmww 0xFFFFFC30 0x00000202\n\tsleep 100\n\n\t#========================================\n\t# CPU now runs at 180mhz\n\t# SYS runs at 60mhz.\n\tadapter speed 40000\n\t#========================================\n\n\t## Init SDRAM\n\t## PIOC_ASR: Configure PIOC as peripheral (D16/D31)\n\tmww 0xFFFFF870 0xFFFF0000\n\t## PIOC_BSR:\n\tmww 0xFFFFF874 0x00000000\n\t## PIOC_PDR:\n\tmww 0xFFFFF804 0xFFFF0000\n\t## EBI_CSA : CS1=SDRAM\n\tmww 0xFFFFFF60 0x00000002\n\t## EBI_CFGR:\n\tmww 0xFFFFFF64 0x00000000\n\t## SDRC_CR :\n\tmww 0xFFFFFF98 0x2188c155\n\t## SDRC_MR : Precharge All\n\tmww 0xFFFFFF90 0x00000002\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Refresh\n\tmww 0xFFFFFF90 0x00000004\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Load Mode Register\n\tmww 0xFFFFFF90 0x00000003\n\t## access SDRAM\n\tmww 0x20000080 0x00000000\n\t## SDRC_TR : Write refresh rate\n\tmww 0xFFFFFF94 0x000002E0\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Normal Mode\n\tmww 0xFFFFFF90 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91sam9261-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9261-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9261.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9261.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9261ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9261ek_reset_init { } {\n\n\t;# for ppla at 199 Mhz\n\tset config(master_pll_div)\t15\n\tset config(master_pll_mul)\t162\n\n\t;# for ppla at 239 Mhz\n\t;# set master_pll_div\t1\n\t;# set master_pll_mul\t13\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBICSA\n\tset config(matrix_ebicsa_val) [expr {$::AT91_MATRIX_DBPUC | $::AT91_MATRIX_CS1A_SDRAMC}]\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (2 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (3 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (8 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91sam9263-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9263-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9263.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9263.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9263ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9263ek_reset_init { } {\n\n\tset config(master_pll_div)\t14\n\tset config(master_pll_mul)\t171\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\tset config(sdram_piod) 1\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBI0CSA\n\n\tset val\t$::AT91_MATRIX_EBI0_DBPUC\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_VDDIOMSEL_3_3V}]\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_CS1A_SDRAMC}]\n\tset config(matrix_ebicsa_val) $val\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (1 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (2 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (1 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/at91sam9g20-ek.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n# Author: Gary Carlson (gcarlson@carlson-minot.com)\t\t\t\t\t\t#\n# Generated for Atmel AT91SAM9G20-EK evaluation board using Atmel SAM-ICE (J-Link) version 8.\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g20.cfg]\n\nset _FLASHTYPE nandflash_cs3\n\n# Set reset type.  Note that the AT91SAM9G20-EK board has the trst signal disconnected.  Therefore\n# the reset needs to be configured for \"srst_only\".  If for some reason, a zero-ohm jumper is\n# added to the board to connect the trst signal, then this parameter may need to be changed.\n\nreset_config srst_only\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init}\n$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start}\n\n# NandFlash configuration and definition\n\nnand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xfffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g20_reset_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n\tadapter speed 2                 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\thalt                            ;# Make sure processor is halted, or error will result in following steps.\n\twait_halt 10000\n\tmww 0xfffffd08 0xa5000501       ;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9g20_reset_init { } {\n\n\t# At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G20 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\tmww 0xfffffd44 0x00008000\t;# WDT_MR : disable watchdog.\n\n\t# Enable the main 18.432 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\tmww 0xfffffc28 0x202a3f01\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00000101\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 0\n\n\t# Enable faster DCC downloads and memory accesses.\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\tmww 0xffffef1c 0x000100a\n\n\t# The AT91SAM9G20-EK evaluation board has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# a number of registers.  The first step involves setting up the general I/O pins on the processor\n\t# to be able to interface and support the external memory.\n\n\tmww 0xfffffc10 0x00000010\t;# PMC_PCER : enable PIOC clock\n\tmww 0xfffff800 0x00006000\t;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n\tmww 0xfffff810 0x00004000\t;# PIOC_OER : enable output on 14\n\tmww 0xfffff814 0x00002000\t;# PIOC_ODR : disable output on 13\n    \tmww 0xfffff830 0x00004000\t;# PIOC_SODR : set 14 to disable NAND\n\n\t# The exact physical timing characteristics for the memory type used on the current board\n\t# (MT29F2G08AACWP) can be established by setting four registers in order:  SMC_SETUP3,\n\t# SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.  Computing the exact values of these registers\n\t# is a little tedious to do here.  If you have questions about how to do this, Atmel has\n\t# a decent application note #6255B that covers this process.\n\n\tmww 0xffffec30 0x00020002\t;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE\n\tmww 0xffffec34 0x04040404\t;# SMC_PULSE3 : 4 clock cycle pulse for all signals\n\tmww 0xffffec38 0x00070006\t;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle\n\tmww 0xffffec3C 0x00020003\t;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n\n\tmww 0xffffe800 0x00000001\t;# ECC_CR : reset the ECC parity registers\n\tmww 0xffffe804 0x00000002\t;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n\t# Identify NandFlash bank 0.\n\n\tnand probe nandflash_cs3\n\n\t# The AT91SAM9G20-EK evaluation board has built-in serial data flash also.\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Micron MT48LC16M16A2-75 memory (4 M x 16 bit x 4 banks).  If you use this file as a reference\n\t# for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted\n\t# into the SDRAM_CR register.  Using the memory datasheet for the -75 grade part and assuming a master clock\n\t# of 132.096 MHz then the SDCLK period is equal to 7.6 ns.  This means the device requires:\n\t#\n\t#\tCAS latency = 3 cycles\n\t#\tTXSR = 10 cycles\n\t#\tTRAS = 6 cycles\n\t#\tTRCD = 3 cycles\n\t#\tTRP = 3 cycles\n\t#\tTRC = 9 cycles\n\t#\tTWR = 2 cycles\n\t#\t9 column, 13 row, 4 banks\n\t#\trefresh equal to or less then 7.8 us for commercial/industrial rated devices\n\t#\n\t#\tThus SDRAM_CR = 0xa6339279\n\n\tmww 0xffffea08 0xa6339279\n\n\t# Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000001\n\tmww 0x20000000 0\n\n\t# Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero\n\t# value into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000002\n\tmww 0x20000000 0\n\n\t# Now issue an 'Auto-Refresh' command through the SDRAMC_MR register.  Follow this operation by writing\n\t# zero values eight times into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x3\n\tmww 0x20000000 0\n\n\t# Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting\n\t# memory location for the SDRAM.\n\n\tmww 0xffffea00 0x0\n\tmww 0x20000000 0\n\n\t# Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles).\n\n\tmww 0xffffea04 0x0000039c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_at91sam7s-ek.cfg",
    "content": "# Atmel AT91SAM7S-EK\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3784\n\nset CHIPNAME at91sam7s256\n\nsource [find target/at91sam7sx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_at91sam9260-ek.cfg",
    "content": "################################################################################\n# Atmel AT91SAM9260-EK eval board\n#\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9260.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198.656 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (99.328 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n\n        mww 0xffffef1c 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_at91sam9rl-ek.cfg",
    "content": "################################################################################\n#\n# Generated for Atmel AT91SAM9RL-EK evaluation board using Atmel SAM-ICE (J-Link) V6\n#\n# Atmel AT91SAM9RL : PLL = 200 MHz, MCK = 100 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9rl.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2031bf03         ;# CKGR_PLLR: Set PLL Register for 200 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLL is selected (100 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff670 0xffff0000         ;# PIO_ASR  : Select peripheral function for D16..D31 (PIOB)\n        mww 0xfffff604 0xffff0000         ;# PIO_PDR  : Disable PIO function for D16..D31 (PIOB)\n\n        mww 0xffffef20 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam3n_ek.cfg",
    "content": "\n#\n# Board configuration for Atmel's SAM3N-EK\n#\n\nreset_config srst_only\n\nset CHIPNAME at91sam3n4c\n\nadapter speed 32\n\nsource [find target/at91sam3nXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam3s_ek.cfg",
    "content": "source [find target/at91sam3sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam3u_ek.cfg",
    "content": "source [find target/at91sam3u4e.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam3x_ek.cfg",
    "content": "source [find target/at91sam3ax_8x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam4e_ek.cfg",
    "content": "# This is an SAM4E-EK board with a single SAM4E16 chip.\n# http://www.atmel.com/tools/sam4e-ek.aspx\n\n# chip name\nset CHIPNAME SAM4E16E\n\nsource [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam4l8_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4L8 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4L8-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4LC8CA\n\nsource [find target/at91sam4lXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam4s_ek.cfg",
    "content": "source [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_sam4s_xplained_pro.cfg",
    "content": "#\n# Atmel SAM4S Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4S-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4SD32C\n\nsource [find target/at91sam4sd32x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samc20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC20 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samc21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMC21 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMC21-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samd10_xplained_mini.cfg",
    "content": "#\n# Atmel SAMD10 Xplained mini evaluation kit.\n# http://www.atmel.com/tools/atsamd10-xmini.aspx\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd10d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samd11_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD11 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd11d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samd20_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD20 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMD20-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samd21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMD21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_same70_xplained.cfg",
    "content": "#\n# Atmel SAME70 Xplained evaluation kit.\n# http://www.atmel.com/tools/ATSAME70-XPLD.aspx\n#\n# Connect using the EDBG chip on the dev kit over USB\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME atsame70q21\n\nsource [find target/atsamv.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samg53_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG53 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG53-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG53N19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samg55_xplained_pro.cfg",
    "content": "#\n# Atmel SAMG55 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG55-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG55J19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_saml21_xplained_pro.cfg",
    "content": "#\n# Atmel SAML21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91saml21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samr21_xplained_pro.cfg",
    "content": "#\n# Atmel SAMR21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samr21g18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/atmel_samv71_xplained_ultra.cfg",
    "content": "#\n# Atmel SAMV71 Xplained Ultra evaluation kit.\n# http://www.atmel.com/tools/ATSAMV71-XULT.aspx\n#\n# To connect using the EDBG chip on the dev kit over USB, you will\n# first need to source [find interface/cmsis-dap.cfg]\n# however, since this board also has a SWD+ETM connector, we don't\n# automatically source that file here.\n\nset CHIPNAME samv71\n\nsource [find target/atsamv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/avnet_ultrazed-eg.cfg",
    "content": "#\n# AVNET UltraZED EG StarterKit\n# ZynqMP UlraScale-EG plus IO Carrier with on-board digilent smt2\n#\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n# jtag transport only\ntransport select jtag\n# reset lines are not wired\nreset_config none\n\n# slow default clock\nadapter speed 1000\n\nset CHIPNAME uscale\n\nsource [find target/xilinx_zynqmp.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/balloon3-cpu.cfg",
    "content": "# Config for balloon3 board, cpu JTAG port. http://balloonboard.org/\n# The board has separate JTAG ports for cpu and CPLD/FPGA devices\n# Chaining is done on IO interfaces if desired.\n\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\n# 29LV650 64Mbit Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/bcm28155_ap.cfg",
    "content": "# BCM28155_AP\n\nadapter speed 20000\n\nset CHIPNAME bcm28155\nsource [find target/bcm281xx.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/bluefield.cfg",
    "content": "#\n# Board configuration for BlueField SoC.\n#\n\nsource [find interface/rshim.cfg]\nsource [find target/bluefield.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/bt-homehubv1.cfg",
    "content": "#\n# BT HomeHub v1\n#\n\nset partition_list {\n    CFE       { Bootloader              0xbe400000 0x00020000 }\n    firmware  { \"Kernel+rootfs\"         0xbe420000 0x007d0000 }\n    fisdir    { \"FIS Directory\"         0xbebf0000 0x0000f000 }\n    nvram     { \"Config space\"          0xbebff000 0x00001000 }\n}\n\nsource [find target/bcm6348.cfg]\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/colibri.cfg",
    "content": "# Toradex Colibri PXA270\nsource [find target/pxa270.cfg]\nreset_config trst_and_srst srst_push_pull\nadapter srst pulse_width 40\n\n# CS0 -- one bank of CFI flash, 32 MBytes\n# the bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/crossbow_tech_imote2.cfg",
    "content": "# Crossbow Technology iMote2\n\nset  CHIPNAME imote2\nsource [find target/pxa270.cfg]\n\n# longer-than-normal reset delay\nadapter srst delay 800\n\nreset_config trst_and_srst separate\n\n# works for P30 flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/csb337.cfg",
    "content": "# Cogent CSB337\n#   http://cogcomp.com/csb_csb337.htm\n\nsource [find target/at91rm9200.cfg]\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# ETM9 trace port connector present on this board, 16 data pins.\nif { [info exists ETM_DRIVER] } {\n\tetm config $_TARGETNAME 16 normal half $ETM_DRIVER\n\t# OpenOCD may someday support a real trace port driver...\n\t# system config file would need to configure it.\n} else {\n\tetm config $_TARGETNAME 16 normal half dummy\n\tetm_dummy config $_TARGETNAME\n}\n\nproc csb337_clk_init { } {\n\t# CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock\n\tadapter speed 8\n\n\t# CKGR_MOR:  start main oscillator (3.6864 MHz)\n\tmww 0xfffffc20 0xff01\n\tsleep 10\n\n\t# CKGR_PLLAR:  start PLL A for CPU and peripherals (184.32 MHz)\n\tmww 0xfffffc28 0x20313e01\n\t# CKGR_PLLBR:  start PLL B for USB timing (96 MHz, with div2)\n\tmww 0xfffffc2c 0x12703e18\n\t# let PLLs lock\n\tsleep 10\n\n\t# PMC_MCKR:  switch to CPU clock = PLLA, master clock = CPU/4\n\tmww 0xfffffc30 0x0302\n\tsleep 20\n\n\t# CPU is in Normal Mode ... allows faster JTAG clock speed\n\tadapter speed 40000\n}\n\nproc csb337_nor_init { } {\n\t# SMC_CSR0:  adjust timings (10 wait states)\n\tmww 0xffffff70 0x1100318a\n\n\tflash probe 0\n}\n\nproc csb337_sdram_init { } {\n\t# enable PIOC clock\n\tmww 0xfffffc10 0x0010\n\t# PC31..PC16 are D31..D16, with internal pullups like D15..D0\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff874 0x0\n\tmww 0xfffff804 0xffff0000\n\n\t# SDRC_CR: set timings\n\tmww 0xffffff98 0x2188b0d5\n\n\t# SDRC_MR: issue all banks precharge to SDRAM\n\tmww 0xffffff90 2\n\tmww 0x20000000 0\n\n\t# SDRC_MR: 8 autorefresh cycles\n\tmww 0xffffff90 4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# SDRC_MR: set SDRAM mode registers (CAS, burst len, etc)\n\tmww 0xffffff90 3\n\tmww 0x20000080 0\n\n\t# SDRC_TR: set refresh rate\n\tmww 0xffffff94 0x200\n\tmww 0x20000000 0\n\n\t# SDRC_MR: normal mode, 32 bit bus\n\tmww 0xffffff90 0\n\tmww 0x20000000 0\n}\n\n# The rm9200 chip has just been reset.  Bring it up far enough\n# that we can write flash or run code from SDRAM.\nproc csb337_reset_init { } {\n\tcsb337_clk_init\n\n\t# EBI_CSA:  CS0 = NOR, CS1 = SDRAM\n\tmww 0xffffff60 0x02\n\n\tcsb337_nor_init\n\tcsb337_sdram_init\n\n\t# Update CP15 control register ... we don't seem to be able to\n\t# read/modify/write its value through a TCL variable, so just\n\t# write it.  Fields are zero unless listed here ... and note\n\t# that OpenOCD numbers this register \"2\", not \"1\" (!).\n\t#\n\t#  - Core to use Async Clocking mode (so it uses 184 MHz most\n\t#    of the time instead of limiting to the master clock rate):\n\t#\tiA(31) = 1, nF(30) = 1\n\t#  - Icache on (it's disabled now, slowing i-fetches)\n\t#\tI(12) = 1\n\t#  - Reserved/ones\n\t#\t6:3 = 1\n\tarm920t cp15 2 0xc0001078\n}\n\n$_TARGETNAME configure -event reset-init {csb337_reset_init}\n\narm7_9 fast_memory_access enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/csb732.cfg",
    "content": "# The Cogent CSB732 board has a single i.MX35 chip\nsource [find target/imx35.cfg]\n\n# Determined by trial and error\nreset_config trst_and_srst combined\nadapter srst delay 200\njtag_ntrst_delay 200\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { csb732_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc csb732_init { } {\n\n\t# Disable fast writing only for init\n\tmemwrite burst disable\n\n\t# All delay loops are omitted.\n\t# We assume the interpreter latency is enough.\n\n\t# Allow access to all coprocessors\n\tarm mcr 15 0 15 1 0 0x2001\n\n\t# Disable MMU, caches, write buffer\n\tarm mcr 15 0 1 0 0 0x78\n\n\t# Grant manager access to all domains\n\tarm mcr 15 0 3 0 0 0xFFFFFFFF\n\n\t# Set ARM clock to 532 MHz, AHB to 133 MHz\n\tmww 0x53F80004 0x1000\n\n\t# Set core clock to 2 * 24 MHz * (11 + 1/12) = 532 MHz\n\tmww 0x53F8001C 0xB2C01\n\n\tset ESDMISC 0xB8001010\n\tset ESDCFG0 0xB8001004\n\tset ESDCTL0 0xB8001000\n\n\t# Enable DDR\n\tmww $ESDMISC 0x4\n\n\t# Timing\n\tmww $ESDCFG0 0x007fff3f\n\n\t# CS0\n\tmww $ESDCTL0 0x92120080\n\n\t# Precharge all dummy write\n\tmww 0x80000400 0\n\n\t# Enable CS) auto-refresh\n\tmww $ESDCTL0 0xA2120080\n\n\t# Refresh twice (dummy writes)\n\tmww 0x80000000 0\n\tmww 0x80000000 0\n\n\t# Enable CS0 load mode register\n\tmww $ESDCTL0 0xB2120080\n\n\t# Dummy writes\n\tmwb 0x80000033 0x01\n\tmwb 0x81000000 0x01\n\n\tmww $ESDCTL0 0x82226080\n\tmww 0x80000000 0\n\n\t# Re-enable fast writing\n\tmemwrite burst enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/da850evm.cfg",
    "content": "#DA850 EVM board\n# http://focus.ti.com/dsp/docs/thirdparty/catalog/devtoolsproductfolder.tsp?actionPerformed=productFolder&productId=5939\n# http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit\n\nsource [find target/omapl138.cfg]\n\nreset_config trst_and_srst separate\n\n#currently any pinmux/timing must be setup by UBL before openocd can do debug\n#TODO: implement pinmux/timing on reset like in board/dm365evm.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/digi_connectcore_wi-9c.cfg",
    "content": "######################################\n# Target: DIGI ConnectCore Wi-9C\n######################################\n\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ns9360\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set  _ENDIAN big\n}\n\n\n# What's a good fallback frequency for this board if RCLK is\n# not available??\njtag_rclk 1000\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 200\njtag_ntrst_delay 0\n\n\n######################\n# Target configuration\n######################\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x90600104 0x33313333\n\tmww 0xA0700000 0x00000001  ;# Enable the memory controller.\n\tmww 0xA0700024 0x00000006  ;# Set the refresh counter 6\n\tmww 0xA0700028 0x00000001  ;#\n\tmww 0xA0700030 0x00000001  ;# Set the precharge period\n\tmww 0xA0700034 0x00000004  ;# Active to precharge command period is 16 clock cycles\n\tmww 0xA070003C 0x00000001  ;# tAPR\n\tmww 0xA0700040 0x00000005  ;# tDAL\n\tmww 0xA0700044 0x00000001  ;# tWR\n\tmww 0xA0700048 0x00000006  ;# tRC 32 clock cycles\n\tmww 0xA070004C 0x00000006  ;# tRFC 32 clock cycles\n\tmww 0xA0700054 0x00000001  ;# tRRD\n\tmww 0xA0700058 0x00000001  ;# tMRD\n\tmww 0xA0700100 0x00004280  ;# Dynamic Config 0 (cs4)\n\tmww 0xA0700120 0x00004280  ;# Dynamic Config 1 (cs5)\n\tmww 0xA0700140 0x00004280  ;# Dynamic Config 2 (cs6)\n\tmww 0xA0700160 0x00004280  ;# Dynamic Config 3 (cs7)\n\t#\n\tmww 0xA0700104 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700124 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700144 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700164 0x00000203  ;# CAS latency is 2 at 100 MHz\n\t#\n\tmww 0xA0700020 0x00000103  ;# issue SDRAM PALL command\n\t#\n\tmww 0xA0700024 0x00000001  ;# Set the refresh counter to be as small as possible\n\t#\n\t# Add some dummy writes to give the SDRAM time to settle, it needs two\n\t# AHB clock cycles, here we poke in the debugger flag, this lets\n\t# the software know that we are in the debugger\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\t#\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\t#\n\tmww 0xA0700024 0x00000030 ;# Set the refresh counter to 30\n\tmww 0xA0700020 0x00000083 ;# Issue SDRAM MODE command\n\t#\n\t# Next we perform a read of RAM.\n\t# mw = move word.\n\tmdw 0x00022000\n\t# mw 0x00022000:P, r3  # 22000 for cas2 latency, 32000 for cas 3\n\t#\n\tmww 0xA0700020 0x00000003   ;# issue SDRAM NORMAL command\n\tmww 0xA0700100 0x00084280   ;# Enable buffer access\n\tmww 0xA0700120 0x00084280   ;# Enable buffer access\n\tmww 0xA0700140 0x00084280   ;# Enable buffer access\n\tmww 0xA0700160 0x00084280   ;# Enable buffer access\n\n\t#Set byte lane state (static mem 1)\"\n\tmww 0xA0700220 0x00000082\n\t#Flash Start\n\tmww 0xA09001F8 0x50000000\n\t#Flash Mask Reg\n\tmww 0xA09001FC 0xFF000001\n\tmww 0xA0700028 0x00000001\n\n\t#  RAMAddr = 0x00020000\n\t#  RAMSize = 0x00004000\n\n\t# Set the processor mode\n\treg cpsr 0xd3\n}\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x1000 -work-area-backup 1\n\n#####################\n# Flash configuration\n#####################\n\n#M29DW323DB - not working\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x0400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/digilent_analog_discovery.cfg",
    "content": "#\n# Digilent Analog Discovery\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY\n#\n# Config is based on data from\n# https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71\n#\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x8008 0x800b\n\nadapter speed 25000\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/digilent_atlys.cfg",
    "content": "# http://digilentinc.com/atlys/\n#\n# The Digilent Atlys normally requires proprietary tools to program and will\n# enumerate as:\n#   ID 1443:0007 Digilent Development board JTAG\n#\n# However, the ixo-usb-jtag project provides an alternative open firmware for\n# the on board programmer. When using this firmware the board will then\n# enumerate as:\n#   ID 16c0:06ad Van Ooijen Technische Informatica\n# (With SerialNumber == hw_nexys)\n#\n# See the interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/digilent_nexys_video.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Digilent Nexys Video with Xilinx Artix-7 FPGA\n# https://reference.digilentinc.com/programmable-logic/nexys-video/start\n\nadapter driver ftdi\nadapter speed 30000\n\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6010\n\n# channel 0 is dedicated for Digilent's DPTI Interface\n# channel 1 is used for JTAG\nftdi channel 1\n\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n\n# Enable sampling on falling edge for high JTAG speeds.\nftdi tdo_sample_edge falling\n\ntransport select jtag\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/digilent_zedboard.cfg",
    "content": "#\n# Digilent Zedboard Rev.C, Rev.D with Xilinx Zynq chip\n#\n# http://zedboard.com/product/zedboard\n#\n\nsource [find interface/ftdi/digilent_jtag_smt2.cfg]\n\nreset_config srst_only srst_push_pull\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/diolan_lpc4350-db1.cfg",
    "content": "#\n# Diolan LPC-4350-DB1 development board\n#\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/diolan_lpc4357-db1.cfg",
    "content": "#\n# Diolan LPC-4357-DB1 development board\n#\n\nset CHIPNAME lpc4357\n\nsource [find target/lpc4357.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dk-tm4c129.cfg",
    "content": "echo \"WARNING: board/dk-tm4c129.cfg is deprecated, please switch to board/ti_dk-tm4c129.cfg\"\n\nsource [find board/ti_dk-tm4c129.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dm355evm.cfg",
    "content": "# DM355 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html\n#   http://c6000.spectrumdigital.com/evmdm355/\n\nsource [find target/ti_dm355.cfg]\n\nreset_config trst_and_srst separate\n\n# NOTE:  disable or replace this call to dm355evm_init if you're\n# debugging new UBL code from SRAM.\n$_TARGETNAME configure -event reset-init { dm355evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm355evm_init {} {\n\tglobal dm355\n\n\techo \"Initialize DM355 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tjtag_rclk 1500\n\n\t########################\n\t# PLL1\t\t= 432 MHz (/8, x144)\n\t# ...SYSCLK1\t= 216 MHz (/2)  ... ARM, MJCP\n\t# ...SYSCLK2\t= 108 MHz (/4)  ... Peripherals\n\t# ...SYSCLK3\t= 27  MHz (/16) ... VPBE, DAC\n\t# ...SYSCLK4\t= 108 MHz (/4)  ... VPSS\n\t#\tpll1.{prediv,div1,div2} are fixed\n\t#\tpll1.postdiv set in MISC (for *this* speed grade)\n\n\tset addr [dict get $dm355 pllc1]\n\tset pll_divs [dict create]\n\tdict set pll_divs div3 16\n\tdict set pll_divs div4 4\n\tpll_v02_setup $addr 144 $pll_divs\n\n\t# ARM is now running at 216 MHz, so JTAG can go faster\n\tjtag_rclk 20000\n\n\t########################\n\t# PLL2\t\t= 342 MHz (/8, x114)\n\t# ....SYSCLK1\t= 342 MHz (/1)  ... DDR PHY at 171 MHz, 2x clock\n\t#\tpll2.{postdiv,div1} are fixed\n\n\tset addr [dict get $dm355 pllc2]\n\tset pll_divs [dict create]\n\tdict set pll_divs div1 1\n\tdict set pll_divs prediv 8\n\tpll_v02_setup $addr 114 $pll_divs\n\n\t########################\n\t# PINMUX\n\n\t# All Video Inputs\n\tdavinci_pinmux $dm355 0 0x00007f55\n\t# All Video Outputs\n\tdavinci_pinmux $dm355 1 0x00145555\n\t# EMIFA (NOTE: more could be set up for use as GPIOs)\n\tdavinci_pinmux $dm355 2 0x00000c08\n\t# SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs\n\tdavinci_pinmux $dm355 3 0x1bff55ff\n\t# MMC/SD0 instead of MS; SPI0\n\tdavinci_pinmux $dm355 4 0x00000000\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t########################\n\t# DDR2 EMIF\n\n\t# VTPIOCR impedance calibration\n\tset addr [dict get $dm355 sysbase]\n\tset addr [expr {$addr + 0x70}]\n\n\t# clear CLR, LOCK, PWRDN; wait a clock; set CLR\n\tmmw $addr 0 0x20c0\n\tmmw $addr 0x2000 0\n\n\t# wait for READY\n        while { [expr {[mrw $addr] & 0x8000}] == 0 } { sleep 1 }\n\n\t# set IO_READY; then LOCK and PWRSAVE; then PWRDN\n\tmmw $addr 0x4000 0\n\tmmw $addr 0x0180 0\n\tmmw $addr 0x0040 0\n\n\t# NOTE:  this DDR2 initialization sequence borrows from\n\t# both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec.\n\n\t# reset (then re-enable) DDR controller\n\tpsc_reset 13\n\tpsc_go\n\tpsc_enable 13\n\tpsc_go\n\n\t# now set it up for Micron MT47H64M16HR-37E @ 171 MHz\n\n\tset addr [dict get $dm355 ddr_emif]\n\n\t# DDRPHYCR1\n\tmww [expr {$addr + 0xe4}] 0x50006404\n\n\t# PBBPR -- burst priority\n\tmww [expr {$addr + 0x20}] 0xfe\n\n\t# SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0x00800000 0\n\tmmw [expr {$addr + 0x08}] 0x0013c632 0x03870fff\n\n\t# SDTIMR0, SDTIMR1\n\tmww [expr {$addr + 0x10}] 0x2a923249\n\tmww [expr {$addr + 0x14}] 0x4c17c763\n\n\t# SDCR -- relock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0 0x00008000\n\n\t# SDRCR -- refresh rate (171 MHz * 7.8usec)\n\tmww [expr {$addr + 0x0c}] 1336\n\n\t########################\n\t# ASYNC EMIF\n\n\tset addr [dict get $dm355 a_emif]\n\n\t# slow/pessimistic timings\n\tset nand_timings 0x40400204\n\t# fast (25% faster page reads)\n\t#set nand_timings 0x0400008c\n\n\t# AWCCR\n\tmww [expr {$addr + 0x04}] 0xff\n\t# CS0 == socketed NAND (default MT29F16G08FAA, 2GByte)\n\tmww [expr {$addr + 0x10}] $nand_timings\n\t# CS1 == dm9000 Ethernet\n\tmww [expr {$addr + 0x14}] 0x00a00505\n\t# NANDFCR -- only CS0 has NAND\n\tmww [expr {$addr + 0x60}] 0x01\n\n\t# default: both chipselects to the NAND socket are used\n\tnand probe 0\n\tnand probe 1\n\n\t########################\n\t# UART0\n\n\tset addr [dict get $dm355 uart0]\n\n\t# PWREMU_MGNT -- rx + tx in reset\n\tmww [expr {$addr + 0x30}] 0\n\n\t# DLL, DLH -- 115200 baud\n\tmwb [expr {$addr + 0x20}] 0x0d\n\tmwb [expr {$addr + 0x24}] 0x00\n\n\t# FCR - clear and disable FIFOs\n\tmwb [expr {$addr + 0x08}] 0x07\n\tmwb [expr {$addr + 0x08}] 0x00\n\n\t# IER - disable IRQs\n\tmwb [expr {$addr + 0x04}] 0x00\n\n\t# LCR - 8-N-1\n\tmwb [expr {$addr + 0x0c}] 0x03\n\n\t# MCR - no flow control or loopback\n\tmwb [expr {$addr + 0x10}] 0x00\n\n\t# PWREMU_MGNT -- rx + tx normal, free running during JTAG halt\n\tmww [expr {$addr + 0x30}] 0xe001\n\n\n\t########################\n\n\t# turn on icache - set I bit in cp15 register c1\n\tarm mcr 15 0 0 1 0 0x00051078\n}\n\n# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one.\n#\n# NOTE:  \"hwecc4\" here presumes that if you're using the standard 2GB NAND\n# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to\n# use \"hwecc4_infix\" for the UBL; or else (b) aren't updating anything that\n# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc.\nset _FLASHNAME $_CHIPNAME.boot\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000\n\n# FIXME\n#  - support writing UBL with its header (new layout only with new ROMs)\n#  - support writing ABL/U-Boot with its header (new layout)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dm365evm.cfg",
    "content": "# DM365 EVM board -- Beta\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html\n#   http://support.spectrumdigital.com/boards/evmdm365\n\nsource [find target/ti_dm365.cfg]\n\n# NOTE:  in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG\n# connector, so it doesn't affect generation of the reset signal.\n# Accordingly, resets require something else.  ICEpick could do it;\n# but its docs aren't generally available.\n#\n# At this writing, newer boards aren't available ... so assume no SRST.\n# Also ICEpick docs aren't available ... so we must use watchdog reset,\n# and hope the CPU isn't wedged or in a WFI loop (either of which can\n# block access to CPU and thus watchdog registers).\n\nreset_config trst_only\n$_TARGETNAME configure -event reset-assert \"davinci_wdog_reset\"\n\n# SW5.1 routes CS0: NAND vs OneNAND.\n# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand)\n# for boot-from-flash, those must agree with SW4.3:1 settings.\n\nif { [info exists CS0MODE] } {\n\t# NAND or OneNAND\n\tset CS0 $CS0MODE\n} else {\n\tset CS0 \"\"\n\techo \"WARNING:  CS0 configuration not known\"\n\tproc cs0_setup {a_emif} {}\n\tproc flashprobe {} {}\n}\n\nset a_emif [dict get $dm365 a_emif]\n\n# As shipped:  boot from NAND.\nif { $CS0 == \"NAND\" } {\n\techo \"CS0 NAND\"\n\n\t# NAND socket has two chipselects.  Default MT29F16G08FAA chip\n\t# has 1GByte on each one.\n\t# NOTE:  \"hwecc4\" here presumes that you're not updating anything\n\t# that needs infix layout (e.g. UBL, old U-Boot, etc)\n\tnand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif\n\tnand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 8 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000016\n\n\t\t# slow/pessimistic timings\n\t\tset nand_timings 0x40400204\n\t\t# fast (25% faster page reads)\n\t\t#set nand_timings 0x0400008c\n\n\t\t# CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes)\n\t\tmww [expr {$a_emif + 0x10}] $nand_timings\n\n\t\t# NANDFCR -- CS0 has NAND\n\t\tmww [expr {$a_emif + 0x60}] 0x01\n\t}\n\tproc flashprobe {} {\n\t\tnand probe 0\n\t\tnand probe 1\n\t}\n\n} elseif { $CS0 == \"OneNAND\" } {\n\techo \"CS0 OneNAND\"\n\n\t# No support for this OneNAND in OpenOCD (yet) or Linux ...\n\t# REVISIT OneNAND timings not verified to work!\n\techo \"WARNING -- OneNAND not yet tested!\"\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 16 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000055\n\n\t\t# CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes)\n\t\tmww [expr {$a_emif + 0x10}] 0x00000001\n\n\t\t# ONENANDCTRL -- CS0 has OneNAND, enable sync reads\n\t\tmww [expr {$a_emif + 0x5c}] 0x0441\n\t}\n\tproc flashprobe {} { }\n}\n\n# NOTE:  disable or replace this call to dm365evm_init if you're\n# debugging new UBL/NANDboot code from SRAM.\n$_TARGETNAME configure -event reset-init { dm365evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm365evm_init {} {\n\tglobal dm365\n\n\techo \"Initialize DM365 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tadapter speed 1500\n\n\t# FIXME -- PLL init\n\n\t########################\n\t# PINMUX setup\n\n\tdavinci_pinmux $dm365 0 0x00fd0000\n\tdavinci_pinmux $dm365 1 0x00145555\n\t# mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand\n\tdavinci_pinmux $dm365 3 0x375affff\n\tdavinci_pinmux $dm365 4 0x55556555\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t# FIXME setup DDR2 (needs PLL)\n\n\t########################\n\t# ASYNC EMIF\n\n\tset a_emif [dict get $dm365 a_emif]\n\n\t# AWCCR\n\tmww [expr {$a_emif + 0x04}] 0xff\n\t# CS0 == NAND or OneNAND\n\tcs0_setup $a_emif\n\t# CS1 == CPLD\n\tmww [expr {$a_emif + 0x14}] 0x00a00505\n\n\t# FIXME setup UART0\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dm6446evm.cfg",
    "content": "# DM6446 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm6446.html\n#   http://c6000.spectrumdigital.com/davincievm/\n# EVM is just the board; buy that at Spectrum.\n# The \"kit\" from TI also has: video camera, LCD video monitor, more.\n\nsource [find target/ti_dm6446.cfg]\n\n# J4 controls what CS2 hooks up to, usually NOR or NAND flash.\n# S3.1/S3.2 controls boot mode, which may force J4 and S3.3 settings.\n# S3.3 controls AEMIF bus width.\n\nif { [info exists J4_OPTION] } {\n\t# NOR, NAND, SRAM, ...\n\tset CS2_MODE $J4_OPTION\n} else {\n\tset CS2_MODE \"\"\n}\n\n# ARM boot:\n#  S3.1 = 0, S3.2 = 0\t==> ROM/UBL boot via NAND (J4 == NAND)\n#  S3.1 = 1, S3.2 = 0\t==> AEMIF boot (J4 == NOR or SRAM)\n#  S3.1 = 0, S3.2 = 1\t==> ROM/UBL boot via HPI\n#  S3.1 = 1, S3.2 = 1\t==> ROM/UBL boot via UART (J4 == don't care)\n# AEMIF bus width:\n#  S3.3 = 0\t\t==> 8 bit bus width\n#  S3.3 = 1\t\t==> 16 bit bus width\n# DSP boot:\n#  S3.4 = 0\t\t==> controlled by ARM\n\nif { $CS2_MODE == \"NOR\" } {\n\t# 16 Mbytes address space; 16 bit bus width\n\t# (older boards used 32MB parts, with upper 16 MB unusable)\n\tset _FLASHNAME $_CHIPNAME.flash\n\tflash bank $_FLASHNAME cfi 0x02000000 0x01000000 2 2 $_TARGETNAME\n\tproc flashprobe {} { flash probe 0 }\n} elseif { $CS2_MODE == \"NAND\" } {\n\t# 64 Mbyte small page; 8 bit bus width\n\tnand device davinci $_TARGETNAME 0x02000000 hwecc1 0x01e00000\n\tproc flashprobe {} { nand probe 0 }\n} elseif { $CS2_MODE == \"SRAM\" } {\n\t# 4 Mbyte address space; 16 bit bus width\n\t# loaded via JTAG or HPI\n\tproc flashprobe {} {}\n} else {\n\t# maybe it's HPI boot?  can't tell...\n\techo \"WARNING:  CS2/flash configuration not recognized\"\n\tproc flashprobe {} {}\n}\n\n# NOTE:  disable or replace this call to dm6446evm_init if you're\n# debugging new UBL code from SRAM (for NAND boot).\n$_TARGETNAME configure -event reset-init { dm6446evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm6446evm_init {} {\n\n\techo \"Initialize DM6446 EVM board\"\n\n\t# FIXME initialize everything:\n\t#  - PLL1\n\t#  - PLL2\n\t#  - PINMUX\n\t#  - PSC\n\t#  - DDR\n\t#  - AEMIF\n\t#  - UART0\n\t#  - icache\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dp_busblaster_v3.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v3.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c32a tap -expected-id 0x06e1c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dp_busblaster_v4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://raw.githubusercontent.com/dergraaf/busblaster_v4/master/ktlink/ktlink.svf\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v4.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c64a tap -expected-id 0x06e5c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/dptechnics_dpt-board-v1.cfg",
    "content": "# Product page:\n# https://www.dptechnics.com/en/products/dpt-board-v1.html\n#\n# JTAG is a 5 pin array located close to main module in following order:\n# 1. JTAG TCK\n# 2. JTAG TDO\n# 3. JTAG TDI\n# 4. JTAG TMS\n# 5. GND\tThe GND is located near letter G of word JTAG on board.\n#\n# Two RST pins are connected to:\n# 1. GND\n# 2. GPIO11\tthis pin is located near letter R of word RST.\n#\n# To enable EJTAG mode, GPIO11 (RST[1]) pin should be pulled up. For example\n# with 10K resistor connected to V3.3 pin.\n#\n# This board is powered from micro USB connector. No real reset pin or button, for\n# example RESET_L is available.\n\nsource [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr2_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/efikamx.cfg",
    "content": "# Genesi USA EfikaMX\n#  http://www.genesi-usa.com/products/efika\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 6000 }\n\nsource [find target/imx51.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/efm32.cfg",
    "content": "# Configuration for EFM32 boards with on-board SEGGER J-Link\n#\n# Tested with Tiny, Giant and Zero Gecko Starter Kit.\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nset CHIPNAME efm32\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/eir.cfg",
    "content": "# Elector Internet Radio board\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nsource [find target/at91sam7se512.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# WDT_MR, disable watchdog\n\tmww 0xFFFFFD44 0x00008000\n\n\t# RSTC_MR, enable user reset\n\tmww 0xfffffd08 0xa5000001\n\n\t# CKGR_MOR\n\tmww 0xFFFFFC20 0x00000601\n\tsleep 10\n\n\t# CKGR_PLLR\n\tmww 0xFFFFFC2C 0x00481c0e\n\tsleep 10\n\n\t# PMC_MCKR\n\tmww 0xFFFFFC30 0x00000007\n\tsleep 10\n\n\t# PMC_IER\n\tmww 0xFFFFFF60 0x00480100\n\n\t#\n\t# Enable SDRAM interface.\n\t#\n\n\t# Enable SDRAM control at PIO A.\n\tmww 0xfffff474 0x3f800000 ;# PIO_BSR_OFF\n\tmww 0xfffff404 0x3f800000 ;# PIO_PDR_OFF\n\n\t# Enable address bus (A0, A2-A11, A13-A17) at PIO B\n\tmww 0xfffff674 0x0003effd ;# PIO_BSR_OFF\n\tmww 0xfffff604 0x0003effd ;# PIO_PDR_OFF\n\n\t# Enable 16 bit data bus at PIO C\n\tmww 0xfffff870 0x0000ffff ;# PIO_ASR_OFF\n\tmww 0xfffff804 0x0000ffff ;# PIO_PDR_OFF\n\n\t# Enable SDRAM chip select\n\tmww 0xffffff80 0x00000002 ;# EBI_CSA_OFF\n\n\t# Set SDRAM characteristics in configuration register.\n\t# Hard coded values for MT48LC32M16A2 with 48MHz CPU.\n\tmww 0xffffffb8 0x2192215a ;# SDRAMC_CR_OFF\n\tsleep 10\n\n\t# Issue 16 bit SDRAM command: NOP\n\tmww 0xffffffb0 0x00000011 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Precharge all\n\tmww 0xffffffb0 0x00000012 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 8 auto-refresh cycles\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Set mode register\n\tmww 0xffffffb0 0x00000013 ;# SDRAMC_MR_OFF\n\tmww 0x20000014 0xcafedede\n\n\t# Set refresh rate count ???\n\tmww 0xffffffb4 0x00000013 ;# SDRAMC_TR_OFF\n\n\t# Issue 16 bit SDRAM command: Normal mode\n\tmww 0xffffffb0 0x00000010 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000180\n\n\t#\n\t# Enable external reset key.\n\t#\n\tmww 0xfffffd08 0xa5000001\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s1968.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S1968 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s1968\n#\n\n# NOTE:  to use J-Link instead of the on-board interface,\n# you may also need to reduce adapter speed to be about 1200.\n# source [find interface/jlink.cfg]\n\n# include the FT2232 interface config for on-board JTAG interface\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s1968\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s3748.cfg",
    "content": "#\n# TI/Luminary Stellaris lm3s3748 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s3748\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s3748\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s6965.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S6965 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s6965\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x5000\nset CHIPNAME lm3s6965\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s811-revb.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits (rev B and earlier)\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE: newer 811-EK boards (rev C and above) shouldn't use this.\n# use board/ek-lm3s811.cfg\nsource [find interface/ftdi/luminary-lm3s811.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s811.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\n# NOTE:  older '811-EK boards (before rev C) shouldn't use this.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s8962.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S8962 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s8962\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s8962\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s9b9x.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9B9x Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9b90\n# http://www.ti.com/tool/ek-lm3s9b92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s9b9x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm3s9d92.cfg",
    "content": "#\n# TI/Luminary Stellaris LM3S9D92 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9d92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s9d92\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm4f120xl.cfg",
    "content": "#\n# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f120xl\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f120h5qr\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-lm4f232.cfg",
    "content": "#\n# TI Stellaris LM4F232 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f232\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f23x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-tm4c123gxl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c123gxl.cfg is deprecated, please switch to board/ti_ek-tm4c123gxl.cfg\"\n\nsource [find board/ti_ek-tm4c123gxl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ek-tm4c1294xl.cfg",
    "content": "echo \"WARNING: board/ek-tm4c1294xl.cfg is deprecated, please switch to board/ti_ek-tm4c1294xl.cfg\"\n\nsource [find board/ti_ek-tm4c1294xl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/embedded-artists_lpc2478-32.cfg",
    "content": "# Embedded Artists eval board for LPC2478\n# http://www.embeddedartists.com/\n\n# Target device: LPC2478\nset CCLK 72000\nsource [find target/lpc2478.cfg]\n\n# Helper\n#\nproc read_register {register} {\n    return [read_memory $register 32 1]\n}\n\nproc init_board {} {\n    # Delays on reset lines\n    adapter srst delay 500\n    jtag_ntrst_delay 1\n\n    # Adaptive JTAG clocking through RTCK.\n    #\n    jtag_rclk 20\n\n    global _TARGETNAME\n    global _CHIPNAME\n\n    # A working area will help speeding the flash programming\n    $_TARGETNAME configure -work-area-phys 0x40000200 -work-area-size [expr {0x10000-0x200-0x20}] -work-area-backup 0\n\n    # External 16-bit flash at chip select CS0 (SST39VF3201-70, 4 MiB)\n    flash bank $_CHIPNAME.extflash cfi 0x80000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n    # Event handlers\n    #\n    $_TARGETNAME configure -event reset-start {\n        # Back to the slow JTAG clock\n        jtag_rclk 20\n    }\n\n    $_TARGETNAME configure -event reset-init {\n        arm core_state arm\n        arm7_9 dcc_downloads enable     ;# Speed up downloads by using DCC transfer\n        arm7_9 fast_memory_access enable\n\n        # Peripheral clocks\n        mww 0xE01FC0C4 0x04280FFE       ;# PCONP: (reset value)\n\n        # Map the user flash to the vector table area (0x00...0x3F)\n        mww 0xE01FC040 0x00000001       ;# MEMMAP: User flash\n\n        # Memory accelerator module\n        mww 0xE01FC004 0x00000003       ;# MAMTIM: 3 clock cycles\n        mww 0xE01FC000 0x00000002       ;# MAMCR: fully enabled\n\n        # Enable external memory bus (32-bit SDRAM at DYCS0, 16-bit flash at CS0)\n        mww 0xE002C014 0x55010115       ;# PINSEL5: P2.16=CAS, P2.17=RAS, P2.18=CLKOUT0,\n                                         # P2.20=DYCS0, P2.24=CKEOUT0, P2.28=DQMOUT0,\n                                         # P2.29=DQMOUT1, P2.30=DQMOUT2, P2.31=DQMOUT3\n        mww 0xE002C018 0x55555555       ;# PINSEL6: P3.0...P3.15=D0...D15\n        mww 0xE002C01C 0x55555555       ;# PINSEL7: P3.16...P3.31=D16...D31\n        mww 0xE002C020 0x55555555       ;# PINSEL8: P4.0...P4.15=A0...A15\n        mww 0xE002C024 0x50051555       ;# PINSEL9: P4.16...P4.22=A16...A22, P4.24=OE,\n                                         # P4.25=WE, P4.30=CS0, P4.31=CS1\n        mww 0xFFE08000 0x00000001       ;# EMCControl: Enable EMC\n\n        # Start PLL, then use faster JTAG clock\n        enable_pll\n        jtag_rclk 3000\n\n        # 16-bit flash @ CS0 (SST39VF3201-70)\n        mww 0xFFE08200 0x00080081       ;# EMCStaticConfig0: 16 bit, PB=1, buffers on\n        mww 0xFFE08204 0x00000000       ;# EMCStaticWaitWen0\n        mww 0xFFE08208 0x00000000       ;# EMCStaticWaitOen0\n        mww 0xFFE0820C 0x00000005       ;# EMCStaticWaitRd0\n        mww 0xFFE08210 0x00000005       ;# EMCStaticWaitPage0\n        mww 0xFFE08214 0x00000003       ;# EMCStaticWaitWr0\n        mww 0xFFE08218 0x00000001       ;# EMCStaticWaitTurn0\n\n        # 8-bit NAND @ CS1\n        # TODO\n\n        # 32-bit SDRAM @ DYCS0 (K4M563233G-HN75)\n        mww 0xFFE08028 0x00000001       ;# EMCDynamicReadConfig\n        mww 0xFFE08030 0x00000001       ;# EMCDynamicRP\n        mww 0xFFE08034 0x00000003       ;# EMCDynamicRAS\n        mww 0xFFE08038 0x00000005       ;# EMCDynamicSREX\n        mww 0xFFE0803C 0x00000001       ;# EMCDynamicAPR\n        mww 0xFFE08040 0x00000005       ;# EMCDynamicDAL\n        mww 0xFFE08044 0x00000001       ;# EMCDynamicWR\n        mww 0xFFE08048 0x00000005       ;# EMCDynamicRC\n        mww 0xFFE0804C 0x00000005       ;# EMCDynamicRFC\n        mww 0xFFE08050 0x00000005       ;# EMCDynamicXSR\n        mww 0xFFE08054 0x00000001       ;# EMCDynamicRRD\n        mww 0xFFE08058 0x00000001       ;# EMCDynamicMRD\n        #\n        mww 0xFFE08104 0x00000202       ;# EMCDynamicRasCas0\n        mww 0xFFE08100 0x00005488       ;# EMCDynamicConfig0\n        sleep 100\n        mww 0xFFE08020 0x00000183       ;# EMCDynamicControl: Clock on continuously, NOP\n        sleep 10\n        mww 0xFFE08020 0x00000103       ;# EMCDynamicControl: PRECHARGE-ALL\n        mww 0xFFE08024 0x00000046       ;# EMCDynamicRefresh\n        sleep 100\n        mww 0xFFE08020 0x00000083       ;# EMCDynamicControl: MODE\n        mdw 0xA0011000 1                ;# Set SDRAM mode register\n        mww 0xFFE08020 0x00000000       ;# EMCDynamicControl: NORMAL\n        mww 0xFFE08100 0x00085488       ;# EMCDynamicConfig0: Enable buffers\n    }\n\n    $_TARGETNAME configure -event gdb-attach {\n        # Without this gdb-attach will first time as probe will fail\n        reset init\n    }\n}\n\n# Enable the PLL.\n# Generate maximum CPU clock (72 MHz) Run from internal RC oscillator.\n# Note: The PLL output runs at a frequency N times the desired CPU clock.\n#       It in unavoidable that the CPU clock drops down to (4 MHz/N) during\n#       the initialization!\n#       Here: N=4\n#       Note that if the PLL is already active at the time this script is\n#       called, the effective value of N is the value of CCLKCFG at that time!\n#\nproc enable_pll {} {\n    # Disconnect PLL in case it is already connected\n    if {[expr {[read_register 0xE01FC080] & 0x03}] == 3} {\n        # Disconnect it, but leave it enabled\n        # (This MUST be done in two steps)\n        mww 0xE01FC080 0x00000001       ;# PLLCON: disconnect PLL\n        mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n        mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    }\n    # Disable PLL (as it might already be enabled at this time!)\n    mww 0xE01FC080 0x00000000       ;# PLLCON: disable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n\n    # Setup PLL to generate 288 MHz from internal RC oscillator\n    mww 0xE01FC10C 0x00000000       ;# CLKSRCSEL: IRC\n    mww 0xE01FC084 0x00000023       ;# PLLCFG: N=1, M=36\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    mww 0xE01FC080 0x00000001       ;# PLLCON: enable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    sleep 100\n    mww 0xE01FC104 0x00000003       ;# CCLKCFG: divide by 4 (72 MHz)\n    mww 0xE01FC080 0x00000003       ;# PLLCON: connect PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/emcraft_imx8m-som-bsb.cfg",
    "content": "#\n# configuration file for Emcraft IMX8M-SOM-BSB\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# SRST and TRST are wired up\nreset_config trst_and_srst\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/emcraft_twr-vf6-som-bsb.cfg",
    "content": "#\n# EmCraft Systems TWR-VF6-SOM-BSB\n#\n# http://www.emcraft.com/products/259#twr-kit\n#\n\nsource [find board/emcraft_vf6-som.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/emcraft_vf6-som.cfg",
    "content": "#\n# EmCraft Systems Vybrid VF6 SOM\n#\n# http://www.emcraft.com/products/259#som\n#\n\nset CHIPNAME vf610\nsource [find target/vybrid_vf6xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/esp32s2-kaluga-1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S2 Kaluga board.\n#\n# For example, OpenOCD can be started for ESP32-S2 debugging on\n#\n#   openocd -f board/esp32s2-kaluga-1.cfg\n#\n\nsource [find interface/ftdi/esp32s2_kaluga_v1.cfg]\nsource [find target/esp32s2.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n# On ESP32-S2, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ethernut3.cfg",
    "content": "#\n# Ethernut 3 board configuration file\n#\n# http://www.ethernut.de/en/hardware/enut3/\n\n\n# AT91R40008-66AU ARM7TDMI Microcontroller\n# 256kB internal RAM\nsource [find target/at91r40008.cfg]\n\n\n# AT49BV322A-70TU NOR Flash\n# 2M x 16 mode at address 0x10000000\n# Common flash interface supported\n#\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME\n\n\n# Micrel MIC2775-29YM5 Supervisor\n# Reset output will remain active for 280ms (maximum)\n#\nadapter srst delay 300\njtag_ntrst_delay 300\n\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\nadapter speed 16000\n\n\n# Target events\n#\n$_TARGETNAME configure -event reset-init { board_init }\n\n# Initialize board hardware\n#\nproc board_init { } {\n\tboard_remap\n\tflash probe 0\n}\n\n# Memory remap\n#\nproc board_remap {{VERBOSE 0}} {\n\t# CS0: NOR flash\n\t#      16MB @ 0x10000000\n\t#      16-bit data bus\n\t#      4 wait states\n\t#\n\tmww 0xffe00000 0x1000212d\n\n\t# CS1: Ethernet controller\n\t#      1MB @ 0x20000000\n\t#      16-bit data bus\n\t#      2 wait states\n\t#      Byte select access\n\t#\n\tmww 0xffe00004 0x20003025\n\n\t# CS2: CPLD registers\n\t#      1MB @ 0x21000000\n\t#      8-bit data bus\n\t#      2 wait states\n\t#\n\tmww 0xffe00008 0x21002026\n\n\t# CS3: Expansion bus\n\t#      1MB @ 0x22000000\n\t#      8-bit data bus\n\t#      8 wait states\n\t#\n\tmww 0xffe00010 0x22002e3e\n\n\t# Remap command\n\t#\n\tmww 0xffe00020 0x00000001\n\n\tif {$VERBOSE != 0} {\n\t\techo \"0x00000000 RAM\"\n\t\techo \"0x10000000 Flash\"\n\t\techo \"0x20000000 Ethernet\"\n\t\techo \"0x21000000 CPLD\"\n\t\techo \"0x22000000 Expansion\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/evb-lan9255.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip LAN9255 evaluation board\n# https://www.microchip.com/en-us/development-tool/EV25Y25A\n#\n\nset CHIPNAME same53\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/frdm-kl25z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL25Z128VLK4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL25Z128VLK4\n\nreset_config srst_only\n\nsource [find target/kl25.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/frdm-kl46z.cfg",
    "content": "# This is an Freescale Freedom eval board with a single MKL46Z256VLL4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL46Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL46Z256VLL4\n\nreset_config srst_only\n\nsource [find target/kl46.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/fsl_imx6q_sabresd.cfg",
    "content": "#\n# Board configuration file for the Freescale IMX6Q Sabre SD EVM\n#\n# This board does not have an embedded JTAG adapter, you must source\n# a suitable adapter configuration before sourcing this file.\n\n# Sabre SD has a standard ARM-20 JTAG connector with\n# nTRST and nSRST available.\nreset_config trst_and_srst\n\n# the only possible transport is JTAG\ntransport select jtag\n\n# iMX6Q POR gates JTAG and the chip is completely incommunicado\n# over JTAG for at least 10ms after nSRST is deasserted\nadapter srst delay 11\n\n# Source generic iMX6Q target configuration\nset CHIPNAME imx6q\nsource [find target/imx6.cfg]\n\n# function to apply initial configuration after a reset. It\n# provides a basic pad configuration and also DDR memory and clocks\n# sufficient to load and execute a boot loader (e.g. barebox) from\n# DDR memory. This list is extracted from the barebox flash image\n# header.\nproc apply_dcd { } {\n\tmww 0x020e05a8 0x00000030\n\tmww 0x020e05b0 0x00000030\n\tmww 0x020e0524 0x00000030\n\tmww 0x020e051c 0x00000030\n\tmww 0x020e0518 0x00000030\n\tmww 0x020e050c 0x00000030\n\tmww 0x020e05b8 0x00000030\n\tmww 0x020e05c0 0x00000030\n\tmww 0x020e05ac 0x00020030\n\tmww 0x020e05b4 0x00020030\n\tmww 0x020e0528 0x00020030\n\tmww 0x020e0520 0x00020030\n\tmww 0x020e0514 0x00020030\n\tmww 0x020e0510 0x00020030\n\tmww 0x020e05bc 0x00020030\n\tmww 0x020e05c4 0x00020030\n\tmww 0x020e056c 0x00020030\n\tmww 0x020e0578 0x00020030\n\tmww 0x020e0588 0x00020030\n\tmww 0x020e0594 0x00020030\n\tmww 0x020e057c 0x00020030\n\tmww 0x020e0590 0x00003000\n\tmww 0x020e0598 0x00003000\n\tmww 0x020e058c 0x00000000\n\tmww 0x020e059c 0x00003030\n\tmww 0x020e05a0 0x00003030\n\tmww 0x020e0784 0x00000030\n\tmww 0x020e0788 0x00000030\n\tmww 0x020e0794 0x00000030\n\tmww 0x020e079c 0x00000030\n\tmww 0x020e07a0 0x00000030\n\tmww 0x020e07a4 0x00000030\n\tmww 0x020e07a8 0x00000030\n\tmww 0x020e0748 0x00000030\n\tmww 0x020e074c 0x00000030\n\tmww 0x020e0750 0x00020000\n\tmww 0x020e0758 0x00000000\n\tmww 0x020e0774 0x00020000\n\tmww 0x020e078c 0x00000030\n\tmww 0x020e0798 0x000c0000\n\tmww 0x021b081c 0x33333333\n\tmww 0x021b0820 0x33333333\n\tmww 0x021b0824 0x33333333\n\tmww 0x021b0828 0x33333333\n\tmww 0x021b481c 0x33333333\n\tmww 0x021b4820 0x33333333\n\tmww 0x021b4824 0x33333333\n\tmww 0x021b4828 0x33333333\n\tmww 0x021b0018 0x00081740\n\tmww 0x021b001c 0x00008000\n\tmww 0x021b000c 0x555a7975\n\tmww 0x021b0010 0xff538e64\n\tmww 0x021b0014 0x01ff00db\n\tmww 0x021b002c 0x000026d2\n\tmww 0x021b0030 0x005b0e21\n\tmww 0x021b0008 0x09444040\n\tmww 0x021b0004 0x00025576\n\tmww 0x021b0040 0x00000027\n\tmww 0x021b0000 0x831a0000\n\tmww 0x021b001c 0x04088032\n\tmww 0x021b001c 0x0408803a\n\tmww 0x021b001c 0x00008033\n\tmww 0x021b001c 0x0000803b\n\tmww 0x021b001c 0x00428031\n\tmww 0x021b001c 0x00428039\n\tmww 0x021b001c 0x09408030\n\tmww 0x021b001c 0x09408038\n\tmww 0x021b001c 0x04008040\n\tmww 0x021b001c 0x04008048\n\tmww 0x021b0800 0xa1380003\n\tmww 0x021b4800 0xa1380003\n\tmww 0x021b0020 0x00005800\n\tmww 0x021b0818 0x00022227\n\tmww 0x021b4818 0x00022227\n\tmww 0x021b083c 0x434b0350\n\tmww 0x021b0840 0x034c0359\n\tmww 0x021b483c 0x434b0350\n\tmww 0x021b4840 0x03650348\n\tmww 0x021b0848 0x4436383b\n\tmww 0x021b4848 0x39393341\n\tmww 0x021b0850 0x35373933\n\tmww 0x021b4850 0x48254A36\n\tmww 0x021b080c 0x001f001f\n\tmww 0x021b0810 0x001f001f\n\tmww 0x021b480c 0x00440044\n\tmww 0x021b4810 0x00440044\n\tmww 0x021b08b8 0x00000800\n\tmww 0x021b48b8 0x00000800\n\tmww 0x021b001c 0x00000000\n\tmww 0x021b0404 0x00011006\n\tmww 0x020c4068 0x00c03f3f\n\tmww 0x020c406c 0x0030fc03\n\tmww 0x020c4070 0x0fffc000\n\tmww 0x020c4074 0x3ff00000\n\tmww 0x020c4078 0x00fff300\n\tmww 0x020c407c 0x0f0000c3\n\tmww 0x020c4080 0x000003ff\n\tmww 0x020e0010 0xf00000cf\n\tmww 0x020e0018 0x007f007f\n\tmww 0x020e001c 0x007f007f\n}\n\n# disable watchdog\nproc disable_wdog { } {\n\tmwh 0x020bc000 0x30\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc imx6q_sabresd_init { } {\n\tdisable_wdog\n\tapply_dcd\n}\n\n# prevent cortex-a code from asserting SRST again\n$_TARGETNAME.0 configure -event reset-assert { }\n# hook the init function into the reset-init event\n$_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/glyn_tonga2.cfg",
    "content": "#\n# Glyn Tonga2 SO-DIMM CPU module (Toshiba TMPA900CMXBG, ARM9)\n#\n# http://toshiba-mikrocontroller.de/sites/TMPA900CPUBOARDStarter.htm\n#\n# Hardware on the S0-DIMM module:\n#   - Toshiba TMPA900CMXBG (ARM9, ARM926EJ-S, max. 200MHz)\n#   - DDR SDRAM: Hynix H5MS5162DFR-J3M (64Mbyte, x16, 1.8V, 166/83MHz at CL3/2)\n#   - NAND flash: Samsung K9F2G08U0B-PIB0 (256M x 8 Bit, 3.3V)\n#   - Ethernet: SMSC LAN9221I-ABZJ (10/100Mbit, Non-PCI, 16 bit interface)\n#\n\nsource [find target/tmpa900.cfg]\n\n########################\n# Target configuration #\n########################\n\n# Initial JTAG speed should not exceed 1/6 of the initial CPU clock\n# frequency (24MHz). Be conservative and use 1/8 of the frequency.\n# (24MHz / 8 = 3MHz)\nadapter speed 3000\n\n$_TARGETNAME configure -event reset-start {\n\t# Upon reset, set the JTAG frequency to 3MHz again, see above.\n\techo \"Setting JTAG speed to 3MHz until clocks are initialized.\"\n\tadapter speed 3000\n\n\t# Halt the CPU.\n\thalt\n\n\t# Disable faster memory access for now.\n\tarm7_9 fast_memory_access disable\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# Setup clocks, and initialize SRAM and DDR SDRAM.\n\ttonga2_init\n\n\t# At this point the CPU is running at 192MHz, increase JTAG speed.\n\t# Tests showed that 15MHz works OK, higher speeds can cause problems,\n\t# though. Not sure if this is a CPU issue or JTAG adapter issue.\n\techo \"Increasing JTAG speed to 15MHz.\"\n\tadapter speed 15000\n\n\t# Enable faster memory access.\n\tarm7_9 fast_memory_access enable\n}\n\nproc tonga2_init { } {\n\t######################\n\t# PLL initialization #\n\t######################\n\n\t# Clock overview (see datasheet chapter 3.5.2, page 57):\n\t#   - fs: Low-frequency oscillator\n\t#   - fOSCH: High-frequency oscillator (24MHz on this board)\n\t#   - fPLL = fOSCH * multiplier (where multiplier can be 6 or 8)\n\t#   - fFCLK = fPLL / gear (where gear can be 1/2/4/8)\n\t#   - fHCLK is always fFCLK/2. fPCLK is also fFCLK/2.\n\t#\n\t# We select multiplier = 8 and gear = 1, so\n\t#   fFCLK = fOSCH * 8 / 1 = 192MHz.\n\n\t# SYSCR3 (System Control Register 3): Disable and configure PLL.\n\t#   - PLL operation control: off\n\t#   - PLL constant value setting 1: always 0, as per datasheet\n\t#   - PLL constant value setting 2: x8 (multiplier = 8)\n\tmww 0xf005000c 0x00000007\n\n\t# SYSCR4 (System Control Register 4): Configure PLL.\n\t#   - PLL constant value setting 3: 140MHz or more\n\t#   - PLL constant value setting 4: always 1, as per datasheet\n\t#   - PLL constant value setting 5: 140MHz or more\n\tmww 0xf0050010 0x00000065\n\n\t# SYSCR3 (System Control Register 3): Enable PLL.\n\t#   - PLL operation control: on\n\t#   - All other bits remain set as above.\n\tmww 0xf005000c 0x00000087\n\n\t# Wait for PLL to stabilize.\n\tsleep 10\n\n\t# SYSCR2 (System Control Register 2): Switch from fOSCH to fPLL.\n\t#   - Selection of the PLL output clock: fPLL\n\tmww 0xf0050008 0x00000002\n\n\t# SYSCR1 (System Control Register 1):\n\t#   - Clock gear programming: fc/1 (i.e., gear = 1, don't divide).\n\tmww 0xf0050004 0x00000000\n\n\t# CLKCR5 (Clock Control Register 5): Set bits 3 and 6. The datasheet\n\t# says the bits are reserved, but also recommends \"Write as one\".\n\tmww 0xf0050054 0x00000048\n\n\n\t##############################################################\n\t# Dynamic Memory Controller (DMC) / DDR SDRAM initialization #\n\t##############################################################\n\n\t# PMC (Power Management Controller):\n\t# PMCDRV (External Port \"Driverbility\" control register):\n\t# Bits DRV_MEM0/DRV_MEM1 (memory relation port drive power):\n\tmww 0xf0020260 0x00000003\t;# Select 1.8V +/- 0.1V\n\n\t# Setup DDR SDRAM timing parameters for our specific chip.\n\tmww 0xf4310014 0x00000004\t;# cas_latency = 2\n\tmww 0xf4310018 0x00000001\t;# t_dqss = 1\n\tmww 0xf431001c 0x00000002\t;# t_mrd = 2\n\tmww 0xf4310020 0x0000000a\t;# t_ras = 10\n\tmww 0xf4310024 0x0000000a\t;# t_rc = 10\n\tmww 0xf4310028 0x00000013\t;# t_rcd = 3, schedule_rcd = 2\n\tmww 0xf431002c 0x0000010a\t;# t_rfc = 10, schedule_rfc = 8\n\tmww 0xf4310030 0x00000013\t;# t_rp = 3, schedule_rp = 2\n\tmww 0xf4310034 0x00000002\t;# t_rrd = 2\n\tmww 0xf4310038 0x00000002\t;# t_wr = 2\n\tmww 0xf431003c 0x00000001\t;# t_wtr = 1\n\tmww 0xf4310040 0x0000000a\t;# t_xp = 10\n\tmww 0xf4310044 0x0000000c\t;# t_xsr = 12\n\tmww 0xf4310048 0x00000014\t;# t_esr = 20\n\n\t# dmc_memory_cfg_5 (DMC Memory Configuration register):\n\t# Set memory configuration:\n\t# column_bits = 10, row_bits = 13, ap-bit = 10, power_down_prd = 0,\n\t# auto_power_down = disable, stop_mem_clock = disable, memory_burst = 4\n\tmww 0xf431000c 0x00010012\n\n\t# dmc_user_config_5 (DMC user_config register):\n\t# Data bus width of DDR SDRAM: 16 bit\n\tmww 0xf4310304 0x00000058\n\n\t# dmc_refresh_prd_5 (DMC Refresh Period register):\n\t# Auto refresh: every 2656 (0xa60) DMCSCLK periods.\n\tmww 0xf4310010 0x00000a60\n\n\t# dmc_chip_0_cfg_5 (DMC chip_0_cfg registers):\n\t#   - SDRAM address structure: bank, row, column\n\t#   - address_match = 01000000 (start address [31:24])\n\t#   - address_mask  = 11111100 (start address [31:24] mask value)\n\tmww 0xf4310200 0x000140fc\n\n\t# Initialize the DDR SDRAM chip.\n\t# dmc_direct_cmd_5 (DMC Direct Command register).\n\t# See datasheet chapter 3.10.5.1, page 268.\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x00000000\t;# RAM init: Precharge all\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00080032\t;# RAM init: addr_13_to_0 = 0x32\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x000a0000\t;# RAM init: bank_addr = bank 2\n\n\t# dmc_id_<0-5>_cfg_5 (DMC id_<0-5>_cfg registers):\n\t# Set min./max. QoS values.\n\t#   - 0x5: Enable QoS, max. QoS = 1\n\t#   - 0xb: Enable QoS, min. QoS = 2\n\tmww 0xf4310100 0x00000005\t;# AHB0: CPU Data\n\tmww 0xf4310104 0x00000005\t;# AHB1: CPU Inst\n\tmww 0xf4310108 0x0000000b\t;# AHB2: LCDC\n\tmww 0xf431010c 0x00000005\t;# AHB3: LCDDA, USB\n\tmww 0xf4310110 0x00000005\t;# AHB4: DMA1\n\tmww 0xf4310114 0x00000005\t;# AHB5: DMA2\n\n\t# dmc_memc_cmd_5 (DMC Memory Controller Command register):\n\t# Change DMC state to ready.\n\tmww 0xf4310004 0x00000000\t;# memc_cmd = \"Go\"\n\n\t# EBI: SMC Timeout register\n\tmww 0xf00a0050 0x00000001\t;# smc_timeout = 1\n\n\n\t########################################################\n\t# Static Memory Controller (SMC) / SRAM initialization #\n\t########################################################\n\n\t# smc_set_cycles_5 (SMC Set Cycles register):\n\t# tRC = 10, tWC = 10, tCEOE = 7, tWP = 5, tPC=2, tTR=2\n\tmww 0xf4311014 0x0004afaa\n\n\t# smc_set_opmode_5 (SMC Set Opmode register):\n\t# Memory data bus width = 16 bits, async read mode, read burst\n\t# length = 1 beat, async write mode, write burst length = 1 beat,\n\t# byte enable (SMCBE0-1) timing = SMCCSn timing, memory burst boundary\n\t# split setting = burst can cross any address boundary\n\tmww 0xf4311018 0x00000001\n\n\t# smc_direct_cmd_5 (SMC Direct Command register):\n\t# cmd_type = UpdateRegs, chip_select = CS1\n\tmww 0xf4311010 0x00c00000\n\n\techo \"Clocks, SRAM, and DDR SDRAM are now initialized.\"\n}\n\n#######################\n# Flash configuration #\n#######################\n\n# TODO: Implement NAND support.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/gti/espressobin.cfg",
    "content": "# config for ESPRESSObin from\n# Globalscale Technologies Inc.\n\n# srst is isolated through missing resistor\nreset_config trst_only\n\nsource [find target/marvell/88f3720.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/gumstix-aerocore.cfg",
    "content": "# JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on\n# the first interface of a Quad FTDI chip.  nTRST is bit 4.\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\n\nftdi layout_init 0x0000 0x001b\nftdi layout_signal nTRST -data 0x0010\n\nsource [find target/stm32f4x.cfg]\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hammer.cfg",
    "content": "# Target Configuration for the TinCanTools S3C2410 Based Hammer Module\n# http://www.tincantools.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# Reset Script for the TinCanTools S3C2410 Based Hammer Module\n\t# http://www.tincantools.com\n\t#\n\t# Setup primary clocks and initialize the SDRAM\n\tmww 0x53000000 0x00000000\n\tmww 0x4a000008 0xffffffff\n\tmww 0x4a00000c 0x000007ff\n\tmww 0x4c000000 0x00ffffff\n\tmww 0x4c000014 0x00000003\n\tmww 0x4c000004 0x000a1031\n\tmww 0x48000000 0x11111122\n\tmww 0x48000004 0x00000700\n\tmww 0x48000008 0x00000700\n\tmww 0x4800000c 0x00000700\n\tmww 0x48000010 0x00000700\n\tmww 0x48000014 0x00000700\n\tmww 0x48000018 0x00000700\n\tmww 0x4800001c 0x00018005\n\tmww 0x48000020 0x00018005\n\tmww 0x48000024 0x009c0459\n\tmww 0x48000028 0x000000b2\n\tmww 0x4800002c 0x00000030\n\tmww 0x48000030 0x00000030\n\tflash probe 0\n}\n\n\n#flash configuration\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxdb500sys.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for paired K4S561632C (64MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C13261\n  mww 0x00100140 0x030D0121\n\n  puts \"Configuring SRAM nCS0 for 150ns paired Par. Flash (x32)\"\n  mww 0x00100100 0x0201000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x02000000 4 4 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxeb500hmi.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads disable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC8M32 (32MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0111\n\n  puts \"Configuring SRAM nCS0 for 150ns Par. Flash (x16)\"\n  mww 0x00100100 0x0101000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxhx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx10.cfg]\n\n# Usually it is not needed to set srst_pulls_trst\n# but sometimes it does not work without it. If you encounter\n# problems try to line below\n# reset_config trst_and_srst srst_pulls_trst\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1\n\n# Par. Flash can only be accessed if DIP switch on the board is set in proper\n# position and init_sdrambus was called. Don't call these functions if the DIP\n# switch is in invalid position, as some outputs may collide. This is why this\n# function is not called automatically\nproc flash_init { } {\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x101C0100 0x01010008\n\n  flash probe 0\n}\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\nproc init_clocks { } {\n  puts \"Enabling all clocks \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n\n  mww  0x101c0028 0x00007511\n}\n\nproc init_sdrambus { } {\n  puts \"Initializing external SDRAM Bus 16 Bit \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n  mww  0x101c0C40 0x00000050\n\n  puts \"Configuring SDRAM controller for K4S561632E (32MB) \"\n  mww 0x101C0140 0\n  sleep 100\n  #mww 0x101C0144 0x00a13262\n  mww 0x101C0144 0x00a13251\n  mww 0x101C0148 0x00000033\n  mww 0x101C0140 0x030d0121\n}\n\n$_TARGETNAME configure -event reset-init {\n  halt\n  wait_halt 1000\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  init_clocks\n#  init_sdrambus\n\n  puts \"\"\n  puts \"-------------------------------------------------\"\n  puts \"Call 'init_clocks' to enable all clocks\"\n  puts \"Call 'init_sdrambus' to enable external SDRAM bus\"\n  puts \"-------------------------------------------------\"\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\n#flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxhx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx50.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x1C000140 0\n  mww 0x1C000144 0x00A12151\n  mww 0x1C000140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x1C000100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxhx500.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sleep 100\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x00100100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hilscher_nxsb100.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n}\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hitex_lpc1768stick.cfg",
    "content": "# Hitex LPC1768 Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/hitex_lpc1768stick.cfg]\n\nsource [find target/lpc17xx.cfg]\n\n\n# startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hitex_lpc2929.cfg",
    "content": "# Hitex eval board for LPC2929/LPC2939\n# http://www.hitex.com/\n\n# Delays on reset lines\nadapter srst delay 50\njtag_ntrst_delay 1\n\n# Maximum of 1/8 of clock frequency (XTAL = 16 MHz).\n# Adaptive clocking through RTCK is not supported.\nadapter speed 2000\n\n# Target device: LPC29xx with ETB\n# The following variables are used by the LPC2900 script:\n#   HAS_ETB             Must be set to 1. The CPU on this board has ETB.\n#   FLASH_CLOCK         CPU frequency at the time of flash programming (in kHz)\nset HAS_ETB             1\nset FLASH_CLOCK         112000\nsource [find target/lpc2900.cfg]\n\n# A working area will help speeding the flash programming\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 -work-area-backup 0\n$_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work-area-backup 0\n\n# Event handlers\n$_TARGETNAME configure -event reset-start {\n  # Back to the slow JTAG clock\n  adapter speed 2000\n}\n\n# External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB)\nset _FLASHNAME $_CHIPNAME.extflash\nflash bank $_FLASHNAME cfi 0x5C000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n\n$_TARGETNAME configure -event reset-init {\n  # Flash\n  mww 0x20200010 0x00000007     ;# FBWST: 7 wait states, not cached\n\n  # Use PLL\n  mww 0xFFFF8020 0x00000001     ;# XTAL_OSC_CONTROL: enable, 1-20 MHz\n  mww 0xFFFF8070 0x01000000     ;# SYS_CLK_CONF: Crystal\n  mww 0xFFFF8028 0x00000005     ;# PLL: (power down)\n  mww 0xFFFF8028 0x01060004     ;# PLL: M=7, 2P=2 (power up)\n                                 # --> f=112 MHz, fcco=224 MHz\n  sleep 100\n  mww 0xFFFF8070 0x02000000     ;# SYS_CLK_CONF: PLL\n\n  # Increase JTAG speed\n  adapter speed 6000\n\n  # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7)\n  mww 0xE0001138 0x0000001F     ;# P1.14 = D0\n  mww 0xE000113C 0x0000001F     ;# P1.15 = D1\n  mww 0xE0001140 0x0000001F     ;# P1.16 = D2\n  mww 0xE0001144 0x0000001F     ;# P1.17 = D3\n  mww 0xE0001148 0x0000001F     ;# P1.18 = D4\n  mww 0xE000114C 0x0000001F     ;# P1.19 = D5\n  mww 0xE0001150 0x0000001F     ;# P1.20 = D6\n  mww 0xE0001154 0x0000001F     ;# P1.21 = D7\n  mww 0xE0001200 0x0000001F     ;# P2.0  = D8\n  mww 0xE0001204 0x0000001F     ;# P2.1  = D9\n  mww 0xE0001208 0x0000001F     ;# P2.2  = D10\n  mww 0xE000120C 0x0000001F     ;# P2.3  = D11\n  mww 0xE0001210 0x0000001F     ;# P2.4  = D12\n  mww 0xE0001214 0x0000001F     ;# P2.5  = D13\n  mww 0xE0001218 0x0000001F     ;# P2.6  = D14\n  mww 0xE000121C 0x0000001F     ;# P2.7  = D15\n  mww 0xE0001104 0x00000007     ;# P1.1  = A1\n  mww 0xE0001108 0x00000007     ;# P1.2  = A2\n  mww 0xE000110C 0x00000007     ;# P1.3  = A3\n  mww 0xE0001110 0x00000007     ;# P1.4  = A4\n  mww 0xE0001114 0x00000007     ;# P1.5  = A5\n  mww 0xE0001118 0x00000007     ;# P1.6  = A6\n  mww 0xE000111C 0x00000007     ;# P1.7  = A7\n  mww 0xE0001028 0x00000007     ;# P0.10 = A8\n  mww 0xE000102C 0x00000007     ;# P0.11 = A9\n  mww 0xE0001030 0x00000007     ;# P0.12 = A10\n  mww 0xE0001034 0x00000007     ;# P0.13 = A11\n  mww 0xE0001038 0x00000007     ;# P0.14 = A12\n  mww 0xE000103C 0x00000007     ;# P0.15 = A13\n  mww 0xE0001048 0x00000007     ;# P0.18 = A14\n  mww 0xE000104C 0x00000007     ;# P0.19 = A15\n  mww 0xE0001050 0x00000007     ;# P0.20 = A16\n  mww 0xE0001054 0x00000007     ;# P0.21 = A17\n  mww 0xE0001058 0x00000007     ;# P0.22 = A18\n  mww 0xE000105C 0x00000007     ;# P0.23 = A19\n  mww 0xE0001238 0x00000007     ;# P2.14 = BLS0\n  mww 0xE000123C 0x00000007     ;# P2.15 = BLS1\n  mww 0xE0001300 0x00000007     ;# P3.0  = CS6\n  mww 0xE0001304 0x00000007     ;# P3.1  = CS7\n  mww 0xE0001130 0x00000007     ;# P1.12 = OE_N\n  mww 0xE0001134 0x00000007     ;# P1.13 = WE_N\n  mww 0x600000BC 0x00000041     ;# Bank6 16-bit mode, RBLE=1\n  mww 0x600000B4 0x00000000     ;# Bank6 WSTOEN=0\n  mww 0x600000AC 0x00000005     ;# Bank6 WST1=5\n  mww 0x600000B8 0x00000001     ;# Bank6 WSTWEN=1\n  mww 0x600000B0 0x00000006     ;# Bank6 WST2=6\n  mww 0x600000A8 0x00000002     ;# Bank6 IDCY=2\n  mww 0x600000D8 0x00000041     ;# Bank7 16-bit mode, RBLE=1\n  mww 0x600000D0 0x00000000     ;# Bank7 WSTOEN=0\n  mww 0x600000C8 0x0000000A     ;# Bank7 WST1=10\n  mww 0x600000D4 0x00000001     ;# Bank7 WSTWEN=1\n  mww 0x600000CC 0x0000000C     ;# Bank7 WST2=8\n  mww 0x600000C4 0x00000002     ;# Bank7 IDCY=2\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hitex_stm32-performancestick.cfg",
    "content": "# Hitex stm32 performance stick\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/stm32-stick.cfg]\n\nset  CHIPNAME stm32_hitex\nsource [find target/stm32f1x.cfg]\n\n# configure str750 connected to jtag chain\n# FIXME -- source [find target/str750.cfg] after cleaning that up\njtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041\n\n# for some reason this board like to startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/hitex_str9-comstick.cfg",
    "content": "# Hitex STR9-comStick\n# http://www.hitex.com/index.php?id=383\n# This works for the STR9-comStick revisions STR912CS-A1 and STR912CS-A2.\n\nsource [find interface/ftdi/hitex_str9-comstick.cfg]\n\n# set jtag speed\nadapter speed 3000\n\nadapter srst delay 100\njtag_ntrst_delay 100\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\n#\n# FIXME use the standard str912 target config; that script might need\n# updating to \"-ignore-version\" for the boundary scan TAP\n#\n#\tsource [find target/str912.cfg]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # Found on STR9-comStick, revision STR912CS-A1\n   set _BSTAPID1 0x1457f041\n   # Found on STR9-comStick, revision STR912CS-A2\n   set _BSTAPID2 0x2457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID1 -expected-id $_BSTAPID2\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/iar_lpc1768.cfg",
    "content": "# Board from IAR KickStart Kit for LPC1768\n# See www.iar.com and also\n# http://www.olimex.com/dev/lpc-1766stk.html\n#\n\nsource [find target/lpc17xx.cfg]\n\n# The chip has just been reset.\n#\n$_TARGETNAME configure -event reset-init {\n\t# FIXME update the core clock to run at 100 MHz;\n\t# and update JTAG clocking similarly; then\n\t# make CCLK match,\n\n\tflash probe 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/iar_str912_sk.cfg",
    "content": "# The IAR str912-sk evaluation kick start board has an str912\n\nsource [find target/str912.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/icnova_imx53_sodimm.cfg",
    "content": "#################################################################################################\n# Author: Benjamin Tietz <benjamin.tietz@in-circuit.de>                                        ;#\n# based on work from: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com>   ;#\n# Kiwigrid GmbH                                                                                ;#\n# Generated for In-Circuit i.MX53 SO-Dimm                                                      ;#\n#################################################################################################\n\n# The In-Circuit ICnova IMX53SODIMM board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"i.MX53 SO-Dimm board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { sodimm_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc sodimm_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n#*========================================================================================== ======\n# Initialization script for 32 bit DDR3 (CS0+CS1)\n#*========================================================================================== ======\n# Remux D24/D25 to perform Flash-access\n\tmww 0x53fa818C 0x00000000 ; #EIM_RW\n\tmww 0x53fa8180 0x00000000 ; #EIM_CS0\n\tmww 0x53fa8188 0x00000000 ; #EIM_OE\n\tmww 0x53fa817C 0x00000000 ; #A16\n\tmww 0x53fa8178 0x00000000 ; #A17\n\tmww 0x53fa8174 0x00000000 ; #A18\n\tmww 0x53fa8170 0x00000000 ; #A19\n\tmww 0x53fa816C 0x00000000 ; #A20\n\tmww 0x53fa8168 0x00000000 ; #A21\n\tmww 0x53fa819C 0x00000000 ; #DA0\n\tmww 0x53fa81A0 0x00000000 ; #DA1\n\tmww 0x53fa81A4 0x00000000 ; #DA2\n\tmww 0x53fa81A8 0x00000000 ; #DA3\n\tmww 0x53fa81AC 0x00000000 ; #DA4\n\tmww 0x53fa81B0 0x00000000 ; #DA5\n\tmww 0x53fa81B4 0x00000000 ; #DA6\n\tmww 0x53fa81B8 0x00000000 ; #DA7\n\tmww 0x53fa81BC 0x00000000 ; #DA8\n\tmww 0x53fa81C0 0x00000000 ; #DA9\n\tmww 0x53fa81C4 0x00000000 ; #DA10\n\tmww 0x53fa81C8 0x00000000 ; #DA11\n\tmww 0x53fa81CC 0x00000000 ; #DA12\n\tmww 0x53fa81D0 0x00000000 ; #DA13\n\tmww 0x53fa81D4 0x00000000 ; #DA14\n\tmww 0x53fa81D8 0x00000000 ; #DA15\n\tmww 0x53fa8118 0x00000000 ; #D16\n\tmww 0x53fa811C 0x00000000 ; #D17\n\tmww 0x53fa8120 0x00000000 ; #D18\n\tmww 0x53fa8124 0x00000000 ; #D19\n\tmww 0x53fa8128 0x00000000 ; #D20\n\tmww 0x53fa812C 0x00000000 ; #D21\n\tmww 0x53fa8130 0x00000000 ; #D22\n\tmww 0x53fa8134 0x00000000 ; #D23\n\tmww 0x53fa813c 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D24\n\tmww 0x53fa8140 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D25\n\tmww 0x53fa8144 0x00000000 ; #D26\n\tmww 0x53fa8148 0x00000000 ; #D27\n\tmww 0x53fa814C 0x00000000 ; #D28\n\tmww 0x53fa8150 0x00000000 ; #D29\n\tmww 0x53fa8154 0x00000000 ; #D30\n\tmww 0x53fa8158 0x00000000 ; #D31\n\n# DDR3 IOMUX configuration\n#* Global pad control options */\n\tmww 0x53fa8554 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53fa8558 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53fa8560 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53fa8564 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n\tmww 0x53fa8568 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53fa8570 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa8574 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53fa8578 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa857c 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53fa8580 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53fa8584 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53fa8588 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53fa8590 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53fa8594 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53fa86f0 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53fa86f4 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53fa86fc 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8714 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8714 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8718 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53fa871c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53fa8720 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53fa8724 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=0 XXX\n\tmww 0x53fa8728 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53fa872c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa86f4 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL for sDQS[3:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa8714 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE for D[31:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa86fc 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8724 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=00\n\n#* Data bus byte lane pad drive strength control options */\n#\tmww 0x53fa872c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa8554 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n#\tmww 0x53fa8558 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n#\tmww 0x53fa8728 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B2DS\n#\tmww 0x53fa8560 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n#\tmww 0x53fa8568 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n#\tmww 0x53fa871c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B1DS\n#\tmww 0x53fa8594 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n#\tmww 0x53fa8590 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n#\tmww 0x53fa8718 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B0DS\n#\tmww 0x53fa8584 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n#\tmww 0x53fa857c 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\n#* SDCLK pad drive strength control options */\n#\tmww 0x53fa8578 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n#\tmww 0x53fa8570 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\n#* Control and addr bus pad drive strength control options */\n#\tmww 0x53fa8574 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n#\tmww 0x53fa8588 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n#\tmww 0x53fa86f0 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_ADDDS for DDR addr bus\n#\tmww 0x53fa8720 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_CTLDS for CSD0, CSD1, SDCKE0, SDCKE1, SDWE\n\n#\tmww 0x53fa8564 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n#\tmww 0x53fa8580 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\n# Initialize DDR3 memory - Micron MT41J128M16-187Er\n#** Keep for now, same setting as CPU3 board **#\n\tmww 0x63fd901c 0x00008000\n#\tmww 0x63fd904c 0x01680172 ; #write leveling reg 0\n#\tmww 0x63fd9050 0x0021017f ; #write leveling reg 1\n\tmww 0x63fd9088 0x32383535 ; #read delay lines\n\tmww 0x63fd9090 0x40383538 ; #write delay lines\n#\tmww 0x63fd90F8 0x00000800 ; #Measure unit\n\tmww 0x63fd907c 0x0136014d ; #DQS gating 0\n\tmww 0x63fd9080 0x01510141 ; #DQS gating 1\n#* CPU3 Board settingr\n# Enable bank interleaving, Address mirror on, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n#\tmww 0x63fd9018 0x00091740 ; #Misc register:\n#* Quick Silver board setting\n# Enable bank interleaving, Address mirror off, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n\tmww 0x63fd9018 0x00011740 ; #Misc register\n\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n#\tmww 0x63fd9000 0xc3190000 ; #Main control register\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n\tmww 0x63fd9000 0x83190000 ; #Main control register\n# tRFC=64ck;tXS=68;tXP=3;tXPDLL=10;tFAW=15;CAS=6ck\n\tmww 0x63fd900C 0x555952E3 ; #timing configuration Reg 0\n# tRCD=6;tRP=6;tRC=21;tRAS=15;tRPA=1;tWR=6;tMRD=4;tCWL=5ck\n\tmww 0x63fd9010 0xb68e8b63 ; #timing configuration Reg 1\n# tDLLK(tXSRD)=512 cycles; tRTP=4;tWTR=4;tRRD=4\n\tmww 0x63fd9014 0x01ff00db ; #timing configuration Reg 2\n\tmww 0x63fd902c 0x000026d2 ; #command delay (default)\n\tmww 0x63fd9030 0x009f0e21 ; #out of reset delays\n# Keep tAOFPD, tAONPD, tANPD, and tAXPD as default since they are bigger than calc values\n\tmww 0x63fd9008 0x12273030 ; #ODT timings\n# tCKE=3; tCKSRX=5; tCKSRE=5\n\tmww 0x63fd9004 0x0002002d\n#Power down control\n#**********************************\n#DDR device configuration:\n#**********************************\n#**********************************\n# CS0:\n#**********************************\n\tmww 0x63fd901c 0x00008032 ; #write mode reg MR2 with cs0 (see below for settings)\n# Full array self refresh\n# Rtt_WR disabled (no ODT at IO CMOS operation)\n# Manual self refresh\n# CWS=5\n\tmww 0x63fd901c 0x00008033 ; #write mode reg MR3 with cs0.\n\tmww 0x63fd901c 0x00028031 ; #write mode reg MR1 with cs0. ODS=01: out buff= RZQ/7 (see below for settings)\n# out impedance = RZQ/7\n# Rtt_nom disabled (no ODT at IO CMOS operation)\n# Aditive latency off\n# write leveling disabled\n# tdqs (differential?) disabled\n\n\tmww 0x63fd901c 0x09208030 ; #write mode reg MR0 with cs0 , with dll_rst0\n\tmww 0x63fd901c 0x04008040 ; #ZQ calibration with cs0 (A10 high indicates ZQ cal long ZQCL)\n#**********************************\n# CS1:\n#**********************************\n#\tmww 0x63fd901c 0x0000803a ; #write mode reg MR2 with cs1.\n#\tmww 0x63fd901c 0x0000803b ; #write mode reg MR3 with cs1.\n#\tmww 0x63fd901c 0x00028039 ; #write mode reg MR1 with cs1. ODS=01: out buff= RZQ/7\n#\tmww 0x63fd901c 0x09208138 ; #write mode reg MR0 with cs1.\n#\tmww 0x63fd901c 0x04008048 ; #ZQ calibration with cs1(A10 high indicates ZQ cal long ZQCL)\n#**********************************\n\n\n\tmww 0x63fd9020 0x00001800 ; # Refresh control register\n\tmww 0x63fd9040 0x04b80003 ; # ZQ HW control\n\tmww 0x63fd9058 0x00022227 ; # ODT control register\n\n\tmww 0x63fd901c 0x00000000\n\n# CLKO muxing (comment out for now till needed to avoid conflicts with intended usage of signals)\n#\tmww 0x53FA8314 = 0\n#\tmww 0x53FA8320 0x4\n#\tmww 0x53FD4060 0x01e900f0\n\n#\tdap apsel 0\n}\n\n# IRAM\n$_TARGETNAME configure -work-area-phys 0xF8000000 -work-area-size 0x20000 -work-area-backup 1\n\nflash bank mx535_nor cfi 0xf0000000 0x800000 2 2 $_TARGETNAME\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/icnova_sam9g45_sodimm.cfg",
    "content": "#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t                                                #\n# Author: Lars Poeschel (larsi@wh2.tu-dresden.de)\t\t\t\t\t\t\t\t\t\t\t\t#\n# Generated for In-Circuit ICnova SAM9G45 SODIMM\t\t\t\t\t\t\t\t\t\t\t\t#\n# http://www.ic-board.de/product_info.php?info=p214_ICnova-SAM9G45-SODIMM.html|ICnova\t\t\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g45.cfg]\n\n# Set reset type.\n# reset_config trst_and_srst\n\n# adapter srst delay 200\n# jtag_ntrst_delay 200\n\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g45_init}\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n$_TARGETNAME configure -event reset-start {at91sam9g45_start}\n\n\n# NandFlash configuration and definition\n# Future TBD\n# Flash configuration\n# flash bank cfi <base> <size> <chip width> <bus width> <target#>\nset _FLASHNAME $_CHIPNAME.flash\n# set _NANDNAME $_CHIPNAME.nand\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n# nand device $_NANDNAME at91sam9 $_TARGETNAME 0x40000000 0xFFFFE800\n\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g45_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n    # Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\tadapter speed 4\n    # Make sure processor is halted, or error will result in following steps.\n\thalt\n\twait_halt 10000\n    # RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n}\n\n\nproc at91sam9g45_init { } {\n\n\t# At reset AT91SAM9G45 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G45 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\t# Make sure processor is halted, or error will result in following steps.\n\thalt\n\t# RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n\t# WDT_MR : disable watchdog.\n\tmww 0xfffffd44 0x00008000\n\n\t# Enable the main 15.000 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\t#mww 0xfffffc28 0x202a3f01\n\tmww 0xfffffc28 0x20c73f03\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\t#mww 0xfffffc30 0x00000101\n\tmww 0xfffffc30 0x00001301\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 6000\n\n\t# Enable faster DCC downloads.\n\n\tarm7_9 dcc_downloads enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n#\tmww 0xfffff870 0xffff0000\n#\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\t# mww 0xffffef1c 0x000100a\n\n\t# The ICnova SAM9G45 SODIMM has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# four registers in order:  SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.\n\n\t# mww 0xffffec30 0x00020002\n\t# mww 0xffffec34 0x04040404\n\t# mww 0xffffec38 0x00070007\n\t# mww 0xffffec3c 0x00030003\n\n\t# Identify NandFlash bank 0.  Disabled at the moment because a memory driver is not yet complete.\n\n#\tnand probe 0\n\n    # SMC_SETUP0 : Setup SMC for NOR Flash\n\tmww 0xffffe800 0x0012000a\n    # SMC_PULSE0\n\tmww 0xffffe804 0x3b38343b\n    # SMC_CYCLE0\n\tmww 0xffffe808 0x003f003f\n    # SMC_MODE0\n\tmww 0xffffe80c 0x00001000\n    # Identify flash bank 0\n\tflash probe 0\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Samsung K4T51083QG memory.\n\n\t# 0. Enable DDR2 Clock\n\tmww 0xfffffc00 0x4\n\t# 1. Program memory device type\n\t# 1.1 configure the DDR controller\n\tmww 0xffffe620 0x16\n\t# 1.2 program the DDR controller\n\tmww 0xffffe608 0x3d\n\n\t# 2. program memory device features\n\t# 2.1 assume timings for 7.5ns min clock period\n\tmww 0xffffe60c 0x21128226\n\t# 2.2 pSDDRC->HDDRSDRC2_T1PR\n\tmww 0xffffe610 0x02c8100e\n\t# 2.3 pSDDRC->HDDRSDRC2_T2PR\n\tmww 0xffffe614 0x01000702\n\t# 3. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 3.1 delay 200us\n\tsleep 1\n\t# jim tcl alternative: after ms\n\t# after 0.2\n\n\t# 4. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 4.1 delay 400ns\n\n\t# 5. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 5.1 delay 400ns\n\n\t# 6. set EMR operation (EMRS2)\n\tmww 0xffffe600 0x5\n\tmww 0x74000000 0x1\n\t# 6.1 delay 2 cycles\n\n\t# 7. set EMR operation (EMRS3)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 7.1 delay 2 cycles\n\n\t# 8. set EMR operation (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 8.1 delay 200 cycles (400Mhz -> 5 * 10^-7s)\n\tsleep 1\n\n\t# 9. Enable DLL Reset (set DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] | 0x80}]\n\tmww 0xffffe608 $CR\n\n\t# 10. mode register cycle to reset the DLL\n\tmww 0xffffe600 0x5\n\tmww 0x70000000 0x1\n\t# 10.1 delay 2 cycles\n\n\t# 11. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 11.1 delay 400 ns\n\n\t# 12. two auto-refresh (CBR) cycles are provided.\n\tmww 0xffffe600 0x4\n\tmww 0x70000000 0x1\n\t# 12.1 delay 10 cycles\n\t# 12.2 2nd cycle (schreiben des Mode Register sparen wir uns)\n\tmww 0x70000000 0x1\n\t# 12.3 delay 10 cycles\n\n\t# 13. disable DLL reset (clear DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffffff7f}]\n\tmww 0xffffe608 $CR\n\n\t# 14. mode register set cycle\n\tmww 0xffffe600 0x3\n\tmww 0x70000000 0x1\n\n\t# 15. program OCD field (set OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] | 0x7000}]\n\tmww 0xffffe608 $CR\n\n\t# 16. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 16.1 delay 2 cycles\n\n\t# 17. disable OCD field (clear OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffff8fff}]\n\tmww 0xffffe608 $CR\n\n\t# 18. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 18.1 delay 2 cycles\n\n\t# 19. normal mode command\n\tmww 0xffffe600 0x0\n\tmww 0x70000000 0x1\n\n\t# 20. perform write to any address\n\t#mww 0x70000000 0x1\n\n\t# 21. write refresh rate into the count field of the refresh rate register\n\tmww 0xffffe604 0x24b\n\t# 21.1 delay (500 * 6 cycles)\n\n\tarm7_9 fast_memory_access enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx27ads.cfg",
    "content": "# The IMX27 ADS eval board has a single IMX27 chip\n# Note: tested on IMX27ADS Board REV-2.6 and REV-2.8\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27ads_init }\n\n# The IMX27 ADS board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\nproc imx27ads_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\t# ========================================\n\t#  Configure PSRAM on CS5\n\t# ========================================\n\tmww 0xd8002050 0x0000dcf6\n\tmww 0xd8002054 0x444a4541\n\tmww 0xd8002058 0x44443302\n\n\t#  ========================================\n\t#         Configure16 bit NorFlash on CS0\n\t#  ========================================\n\tmww 0xd8002000 0x0000CC03\n\tmww 0xd8002004 0xa0330D01\n\tmww 0xd8002008 0x00220800\n\n\t# ========================================\n\t#  Configure CPLD on CS4\n\t# ========================================\n\tmww 0xd8002040 0x0000DCF6\n\tmww 0xd8002044 0x444A4541\n\tmww 0xd8002048 0x44443302\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\tmww 0xD8001000 0x92200000\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xA2200000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xB2200000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\tmww 0xD8001000 0x82228085\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx27lnst.cfg",
    "content": "# The Linuxstamp-mx27 is board has a single IMX27 chip\n# For further info see http://opencircuits.com/Linuxstamp_mx27#OpenOCD\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27lnst_init }\n\nproc imx27lnst_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\tadapter speed 500\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\t#mww 0xD8001000 0x92200000\n\tmww 0xD8001000 0x91120000\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xA2200000\n\tmww 0xD8001000 0xA1120000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xB2200000\n\tmww 0xD8001000 0xB1120000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\t#mww 0xD8001000 0x82228085\n\tmww 0xD8001000 0x81128080\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx28evk.cfg",
    "content": "# The IMX28EVK eval board has a IMX28 chip\n# Tested on SCH-26241 Rev D board with Olimex ARM-USB-OCD\n# Date:\t201-02-01\n# Authors: James Robinson & Fabio Estevam\n\nsource [find target/imx28.cfg]\n$_TARGETNAME configure -event gdb-attach { imx28evk_init }\n$_TARGETNAME configure -event reset-init { imx28evk_init }\n\nproc imx28evk_init { } {\n\n\thalt\n\n\t#****************************\n\t# VDDD setting\n\t#****************************\n\t# set VDDD =1.55V =(0.8v + TRIG x 0.025v), TRIG=0x1e\n\tmww 0x80044010 0x0003F503\n\tmww 0x80044040 0x0002041E\n\n\t#****************************\n\t# CLOCK set up\n\t#****************************\n\t# Power up PLL0 HW_CLKCTRL_PLL0CTRL0\n\tmww 0x80040000 0x00020000\n\t# Set up fractional dividers for CPU and EMI - HW_CLKCTRL_FRAC0\n\t# EMI - first set DIV_EMI to div-by-2 before programming frac divider\n\tmww 0x800400F0 0x80000002\n\n\n\t# CPU: CPUFRAC=19 480*18/29=454.7MHz, EMI: EMIFRAC=22, (480/2)*18/22=196.4MHz\n\tmww 0x800401B0 0x92921613\n\t# Clear the bypass bits for CPU and EMI clocks in HW_CLKCTRL_CLKSEQ_CLR\n\tmww 0x800401D8 0x00040080\n\t# HCLK = 227MHz,HW_CLKCTRL_HBUS DIV =0x2\n\tmww 0x80040060 0x00000002\n\n\t#****************************\n\t# POWER up DCDD_VDDA (DDR2)\n\t#****************************\n\t# Now set the voltage level to 1.8V HW_POWER_VDDACTRL bits TRC=0xC\n\tmww 0x80044050 0x0000270C\n\n\t#****************************\n\t# DDR2 DCDD_VDDA\n\t#****************************\n\t# First set up pin muxing and drive strength\n\t# Ungate module clock and bring out of reset HW_PINCTRL_CTRL_CLR\n\tmww 0x80018008 0xC0000000\n\n\t#****************************\n\t# EMI PAD setting\n\t#****************************\n\t# Set up drive strength for EMI pins\n\tmww 0x80019B80 0x00030000\n\t#IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\n\t# Set up pin muxing for EMI, HW_PINCTRL_MUXSEL10, 11, 12, 13\n\tmww 0x800181A8 0xFFFFFFFF\n\tmww 0x800181B8 0xFFFFFFFF\n\tmww 0x800181C8 0xFFFFFFFF\n\tmww 0x800181D8 0xFFFFFFFF\n\n\t#** Ungate EMI clock in CCM\n\tmww 0x800400F0 0x00000002\n\n\t#============================================================================\n\t# DDR Controller Registers\n\t#============================================================================\n\t# Manufacturer:    Elpida\n\t# Device Part Number:    EDE1116AEBG\n\t# Clock Freq.:     200MHz\n\t# Density:         1Gb\n\t# Chip Selects:    1\n\t# Number of Banks: 8\n\t# Row address:     13\n\t# Column address:  10\n\t#============================================================================\n\tmww 0x800E0000 0x00000000\n\tmww 0x800E0040 0x00000000\n\tmww 0x800E0054 0x00000000\n\tmww 0x800E0058 0x00000000\n\tmww 0x800E005C 0x00000000\n\tmww 0x800E0060 0x00000000\n\tmww 0x800E0064 0x00000000\n\tmww 0x800E0068 0x00010101\n\tmww 0x800E006C 0x01010101\n\tmww 0x800E0070 0x000f0f01\n\tmww 0x800E0074 0x0102020A\n\tmww 0x800E007C 0x00010101\n\tmww 0x800E0080 0x00000100\n\tmww 0x800E0084 0x00000100\n\tmww 0x800E0088 0x00000000\n\tmww 0x800E008C 0x00000002\n\tmww 0x800E0090 0x01010000\n\tmww 0x800E0094 0x07080403\n\tmww 0x800E0098 0x06005003\n\tmww 0x800E009C 0x0A0000C8\n\tmww 0x800E00A0 0x02009C40\n\tmww 0x800E00A4 0x0002030C\n\tmww 0x800E00A8 0x0036B009\n\tmww 0x800E00AC 0x031A0612\n\tmww 0x800E00B0 0x02030202\n\tmww 0x800E00B4 0x00C8001C\n\tmww 0x800E00C0 0x00011900\n\tmww 0x800E00C4 0xffff0303\n\tmww 0x800E00C8 0x00012100\n\tmww 0x800E00CC 0xffff0303\n\tmww 0x800E00D0 0x00012100\n\tmww 0x800E00D4 0xffff0303\n\tmww 0x800E00D8 0x00012100\n\tmww 0x800E00DC 0xffff0303\n\tmww 0x800E00E0 0x00000003\n\tmww 0x800E00E8 0x00000000\n\tmww 0x800E0108 0x00000612\n\tmww 0x800E010C 0x01000f02\n\tmww 0x800E0114 0x00000200\n\tmww 0x800E0118 0x00020007\n\tmww 0x800E011C 0xf4004a27\n\tmww 0x800E0120 0xf4004a27\n\tmww 0x800E012C 0x07400300\n\tmww 0x800E0130 0x07400300\n\tmww 0x800E013C 0x00000005\n\tmww 0x800E0140 0x00000000\n\tmww 0x800E0144 0x00000000\n\tmww 0x800E0148 0x01000000\n\tmww 0x800E014C 0x01020408\n\tmww 0x800E0150 0x08040201\n\tmww 0x800E0154 0x000f1133\n\tmww 0x800E015C 0x00001f04\n\tmww 0x800E0160 0x00001f04\n\tmww 0x800E016C 0x00001f04\n\tmww 0x800E0170 0x00001f04\n\tmww 0x800E0288 0x00010000\n\tmww 0x800E028C 0x00030404\n\tmww 0x800E0290 0x00000003\n\tmww 0x800E02AC 0x01010000\n\tmww 0x800E02B0 0x01000000\n\tmww 0x800E02B4 0x03030000\n\tmww 0x800E02B8 0x00010303\n\tmww 0x800E02BC 0x01020202\n\tmww 0x800E02C0 0x00000000\n\tmww 0x800E02C4 0x02030303\n\tmww 0x800E02C8 0x21002103\n\tmww 0x800E02CC 0x00061200\n\tmww 0x800E02D0 0x06120612\n\tmww 0x800E02D4 0x04420442\n\t# Mode register 0 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02D8 0x00000000\n\t# Mode register 0 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02DC 0x00040004\n\t# Mode register 1 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E0 0x00000000\n\t# Mode register 1 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02E4 0x00000000\n\t# Mode register 2 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E8 0x00000000\n\t# Mode register 2 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02EC 0x00000000\n\t# Mode register 3 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02F0 0x00000000\n\t# Mode register 3 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02F4 0xffffffff\n\n\t#**  start controller **#\n\tmww 0x800E0040 0x00000001\n\t# bit[0]: start\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx31pdk.cfg",
    "content": "# The IMX31PDK eval board has a single IMX31 chip\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx31pdk_init }\n\nproc self_test {} {\n\techo \"Running 100 iterations of test.\"\n\tdump_image /ram/test 0x80000000 0x40000\n\tfor {set i 0} {$i < 100} {set i [expr {$i+1}]} {\n\t\techo \"Iteration $i\"\n\t\treset init\n\t\tmww 0x80000000 0x12345678 0x10000\n\t\tload_image /ram/test 0x80000000 bin\n\t\tverify_image /ram/test 0x80000000 bin\n\t}\n}\n\n\n# Slow fallback frequency\n# measure_clk indicates ca. 3-4MHz.\njtag_rclk 1000\n\nproc imx31pdk_init { } {\n\n\timx3x_reset\n\n\t# This setup puts RAM at 0x80000000\n\n\tmww 0x53FC0000 0x040\n\tmww 0x53F80000 0x074B0B7D\n\n\t# 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40\n\t#mww 0x53F80004 0xFF871D50\n\t#mww 0x53F80010 0x00271C1B\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000CC03\n\tmww 0xb8002004 0xa0330D01\n\tmww 0xb8002008 0x00220800\n\n\t# Configure CPLD on CS4\n\tmww 0xb8002040 0x0000DCF6\n\tmww 0xb8002044 0x444A4541\n\tmww 0xb8002048 0x44443302\n\n\t# SDCLK\n\tmww 0x43FAC26C 0\n\n\t# CAS\n\tmww 0x43FAC270 0\n\n\t# RAS\n\tmww 0x43FAC274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43FAC27C 0x1000\n\n\t# DQM3\n\tmww 0x43FAC284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC)\n\tmww 0x43FAC288 0\n\tmww 0x43FAC28C 0\n\tmww 0x43FAC290 0\n\tmww 0x43FAC294 0\n\tmww 0x43FAC298 0\n\tmww 0x43FAC29C 0\n\tmww 0x43FAC2A0 0\n\tmww 0x43FAC2A4 0\n\tmww 0x43FAC2A8 0\n\tmww 0x43FAC2AC 0\n\tmww 0x43FAC2B0 0\n\tmww 0x43FAC2B4 0\n\tmww 0x43FAC2B8 0\n\tmww 0x43FAC2BC 0\n\tmww 0x43FAC2C0 0\n\tmww 0x43FAC2C4 0\n\tmww 0x43FAC2C8 0\n\tmww 0x43FAC2CC 0\n\tmww 0x43FAC2D0 0\n\tmww 0x43FAC2D4 0\n\tmww 0x43FAC2D8 0\n\tmww 0x43FAC2DC 0\n\n\t# Initialization script for 32 bit DDR on MX31 ADS\n\tmww 0xB8001010 0x00000004\n\tmww 0xB8001004 0x006ac73a\n\tmww 0xB8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\tmww 0xB8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\tmww 0xB8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\tmww 0xB8001000 0x82226080\n\tmww 0x80000000 0xDEADBEEF\n\tmww 0xB8001010 0x0000000c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx35pdk.cfg",
    "content": "# The IMX35PDK eval board has a single IMX35 chip\nsource [find target/imx35.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx35pdk_init }\n\n# Stick to *really* low clock rate or reset will fail\n# without RTCK / RCLK\njtag_rclk 10\n\nproc imx35pdk_init { } {\n\n\timx3x_reset\n\n\tmww 0x43f00040 0x00000000\n\tmww 0x43f00044 0x00000000\n\tmww 0x43f00048 0x00000000\n\tmww 0x43f0004C 0x00000000\n\tmww 0x43f00050 0x00000000\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00040 0x00000000\n\tmww 0x53f00044 0x00000000\n\tmww 0x53f00048 0x00000000\n\tmww 0x53f0004C 0x00000000\n\tmww 0x53f00050 0x00000000\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# clock setup\n\tmww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP\n\tmww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz.\n\n\t#=================================================\n\t# WEIM config\n\t#=================================================\n\t# CS0U\n\tmww 0xB8002000 0x0000CC03\n\t# CS0L\n\tmww 0xB8002004 0xA0330D01\n\t# CS0A\n\tmww 0xB8002008 0x00220800\n\t# CS5U\n\tmww 0xB8002050 0x0000dcf6\n\t# CS5L\n\tmww 0xB8002054 0x444a4541\n\t# CS5A\n\tmww 0xB8002058 0x44443302\n\n\t# IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR\n\tmww 0x43FAC368 0x00000006\n\tmww 0x43FAC36C 0x00000006\n\tmww 0x43FAC370 0x00000006\n\tmww 0x43FAC374 0x00000006\n\tmww 0x43FAC378 0x00000006\n\tmww 0x43FAC37C 0x00000006\n\tmww 0x43FAC380 0x00000006\n\tmww 0x43FAC384 0x00000006\n\tmww 0x43FAC388 0x00000006\n\tmww 0x43FAC38C 0x00000006\n\tmww 0x43FAC390 0x00000006\n\tmww 0x43FAC394 0x00000006\n\tmww 0x43FAC398 0x00000006\n\tmww 0x43FAC39C 0x00000006\n\tmww 0x43FAC3A0 0x00000006\n\tmww 0x43FAC3A4 0x00000006\n\tmww 0x43FAC3A8 0x00000006\n\tmww 0x43FAC3AC 0x00000006\n\tmww 0x43FAC3B0 0x00000006\n\tmww 0x43FAC3B4 0x00000006\n\tmww 0x43FAC3B8 0x00000006\n\tmww 0x43FAC3BC 0x00000006\n\tmww 0x43FAC3C0 0x00000006\n\tmww 0x43FAC3C4 0x00000006\n\tmww 0x43FAC3C8 0x00000006\n\tmww 0x43FAC3CC 0x00000006\n\tmww 0x43FAC3D0 0x00000006\n\tmww 0x43FAC3D4 0x00000006\n\tmww 0x43FAC3D8 0x00000006\n\n\t# DDR data bus SD 0 through 31\n\tmww 0x43FAC3DC 0x00000082\n\tmww 0x43FAC3E0 0x00000082\n\tmww 0x43FAC3E4 0x00000082\n\tmww 0x43FAC3E8 0x00000082\n\tmww 0x43FAC3EC 0x00000082\n\tmww 0x43FAC3F0 0x00000082\n\tmww 0x43FAC3F4 0x00000082\n\tmww 0x43FAC3F8 0x00000082\n\tmww 0x43FAC3FC 0x00000082\n\tmww 0x43FAC400 0x00000082\n\tmww 0x43FAC404 0x00000082\n\tmww 0x43FAC408 0x00000082\n\tmww 0x43FAC40C 0x00000082\n\tmww 0x43FAC410 0x00000082\n\tmww 0x43FAC414 0x00000082\n\tmww 0x43FAC418 0x00000082\n\tmww 0x43FAC41c 0x00000082\n\tmww 0x43FAC420 0x00000082\n\tmww 0x43FAC424 0x00000082\n\tmww 0x43FAC428 0x00000082\n\tmww 0x43FAC42c 0x00000082\n\tmww 0x43FAC430 0x00000082\n\tmww 0x43FAC434 0x00000082\n\tmww 0x43FAC438 0x00000082\n\tmww 0x43FAC43c 0x00000082\n\tmww 0x43FAC440 0x00000082\n\tmww 0x43FAC444 0x00000082\n\tmww 0x43FAC448 0x00000082\n\tmww 0x43FAC44c 0x00000082\n\tmww 0x43FAC450 0x00000082\n\tmww 0x43FAC454 0x00000082\n\tmww 0x43FAC458 0x00000082\n\n\t# DQM setup\n\tmww 0x43FAC45c 0x00000082\n\tmww 0x43FAC460 0x00000082\n\tmww 0x43FAC464 0x00000082\n\tmww 0x43FAC468 0x00000082\n\n\tmww 0x43FAC46c 0x00000006\n\tmww 0x43FAC470 0x00000006\n\tmww 0x43FAC474 0x00000006\n\tmww 0x43FAC478 0x00000006\n\tmww 0x43FAC47c 0x00000006\n\tmww 0x43FAC480 0x00000006\t;# CSD0\n\tmww 0x43FAC484 0x00000006\t;# CSD1\n\tmww 0x43FAC488 0x00000006\n\tmww 0x43FAC48c 0x00000006\n\tmww 0x43FAC490 0x00000006\n\tmww 0x43FAC494 0x00000006\n\tmww 0x43FAC498 0x00000006\n\tmww 0x43FAC49c 0x00000006\n\tmww 0x43FAC4A0 0x00000006\n\tmww 0x43FAC4A4 0x00000006\t;# RAS\n\tmww 0x43FAC4A8 0x00000006\t;# CAS\n\tmww 0x43FAC4Ac 0x00000006\t;# SDWE\n\tmww 0x43FAC4B0 0x00000006 \t;# SDCKE0\n\tmww 0x43FAC4B4 0x00000006  ;# SDCKE1\n\tmww 0x43FAC4B8 0x00000002  ;# SDCLK\n\n\t# SDQS0 through SDQS3\n\tmww 0x43FAC4Bc 0x00000082\n\tmww 0x43FAC4C0 0x00000082\n\tmww 0x43FAC4C4 0x00000082\n\tmww 0x43FAC4C8 0x00000082\n\n\n\t# *==================================================\n\t#  Initialization script for 32 bit DDR2 on RINGO 3DS\n\t# *==================================================\n\n\t#--------------------------------------------\n\t# Init CCM\n\t#--------------------------------------------\n\tmww 0x53F80028 0x7D000028\n\n\t#--------------------------------------------\n\t# Init IOMUX for JTAG\n\t#--------------------------------------------\n\tmww 0x43FAC5EC 0x000000C3\n\tmww 0x43FAC5F0 0x000000C3\n\tmww 0x43FAC5F4 0x000000F3\n\tmww 0x43FAC5F8 0x000000F3\n\tmww 0x43FAC5FC 0x000000F3\n\tmww 0x43FAC600 0x000000F3\n\tmww 0x43FAC604 0x000000F3\n\n\n\t# ESD_MISC : enable DDR2\n\tmww 0xB8001010 0x00000304\n\n\t#--------------------------------------------\n\t# Init 32-bit DDR2 memory on CSD0\n\t# COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25]\n\t#--------------------------------------------\n\n\t# ESD_ESDCFG0 : set timing parameters\n\tmww 0xB8001004 0x007ffC2f\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmww 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg EMR2\n\tmwb 0x84000000 0xda\n\t# DDR2 : Load reg EMR3\n\tmwb 0x86000000 0xda\n\t# DDR2 : Load reg EMR1 -- enable DLL\n\tmwb 0x82000400 0xda\n\t# DDR2 : Load reg MR -- reset DLL\n\tmwb 0x80000333 0xda\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmwb 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Manual-Refresh mode\n\tmww 0xB8001000 0xA2220000\n\t# DDR2 : Manual-Refresh 2 times\n\tmww 0x80000000 0x87654321\n\tmww 0x80000000 0x87654321\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset\n\tmwb 0x80000233 0xda\n\t# DDR2 : Load reg EMR1 -- OCD default\n\tmwb 0x82000780 0xda\n\t# DDR2 : Load reg EMR1 -- OCD exit\n\tmwb 0x82000400 0xda\t;# ODT disabled\n\n\t# ESD_ESDCTL0 : select normal-operation mode\n\t# DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit\n\t# disable PWT & PRCT\n\t# disable Auto-Refresh\n\tmww 0xB8001000 0x82220080\n\n\t## ESD_ESDCTL0 : enable Auto-Refresh\n\tmww 0xB8001000 0x82228080\n\t## ESD_ESDCTL1 : enable Auto-Refresh\n\tmww 0xB8001008 0x00002000\n\n\n\t#***********************************************\n\t# Adjust the ESDCDLY5 register\n\t#***********************************************\n\t# Vary DQS_ABS_OFFSET5 for writes\n\tmww 0xB8001020 0x00F48000\t;# this is the default value\n\tmww 0xB8001024 0x00F48000\t;# this is the default value\n\tmww 0xB8001028 0x00F48000\t;# this is the default value\n\tmww 0xB800102c 0x00F48000\t;# this is the default value\n\n\n\t#Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC)\n\tmww 0xB8001010 0x00000384\n\t# wait a while\n\tsleep 1000\n\t# now clear the force measurement bit\n\tmww 0xB8001010 0x00000304\n\n\t# dummy write to DDR memory to set DQS low\n\tmww 0x80000000 0x00000000\n\n\tmww 0x30000100 0x0\n\tmww 0x30000104 0x31024\n\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx53-m53evk.cfg",
    "content": "#######################################\n# DENX M53EVK                         #\n# http://www.denx-cs.de/?q=M53EVK     #\n# Author: Marek Vasut <marex@denx.de> #\n# Based on imx53loco.cfg              #\n#######################################\n\n# The DENX M53EVK has on-board JTAG adapter\nsource [find interface/ftdi/m53evk.cfg]\n# The DENX M53EVK board has a single i.MX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 M53EVK board lodaded.\"\n\n# Set reset type\nreset_config trst_and_srst separate trst_open_drain srst_open_drain\n\n# Run at 6 MHz\nadapter speed 6000\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { m53evk_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc m53evk_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53fa86f4 0x00000000\t ;# GRP_DDRMODE_CTL\n\tmww 0x53fa8714 0x00000000\t ;# GRP_DDRMODE\n\tmww 0x53fa86fc 0x00000000\t ;# GRP_DDRPKE\n\tmww 0x53fa8724 0x04000000\t ;# GRP_DDR_TYPE\n\n\tmww 0x53fa872c 0x00300000\t ;# GRP_B3DS\n\tmww 0x53fa8554 0x00300000\t ;# DRAM_DQM3\n\tmww 0x53fa8558 0x00300040\t ;# DRAM_SDQS3\n\n\tmww 0x53fa8728 0x00300000\t ;# GRP_B2DS\n\tmww 0x53fa8560 0x00300000\t ;# DRAM_DQM2\n\tmww 0x53fa8568 0x00300040\t ;# DRAM_SDQS2\n\n\tmww 0x53fa871c 0x00300000\t ;# GRP_B1DS\n\tmww 0x53fa8594 0x00300000\t ;# DRAM_DQM1\n\tmww 0x53fa8590 0x00300040\t ;# DRAM_SDQS1\n\n\tmww 0x53fa8718 0x00300000\t ;# GRP_B0DS\n\tmww 0x53fa8584 0x00300000\t ;# DRAM_DQM0\n\tmww 0x53fa857c 0x00300040\t ;# DRAM_SDQS0\n\n\tmww 0x53fa8578 0x00300000\t ;# DRAM_SDCLK_0\n\tmww 0x53fa8570 0x00300000\t ;# DRAM_SDCLK_1\n\n\tmww 0x53fa8574 0x00300000\t ;# DRAM_CAS\n\tmww 0x53fa8588 0x00300000\t ;# DRAM_RAS\n\tmww 0x53fa86f0 0x00300000\t ;# GRP_ADDDS\n\tmww 0x53fa8720 0x00300000\t ;# GRP_CTLDS\n\n\tmww 0x53fa8564 0x00300040\t ;# DRAM_SDODT1\n\tmww 0x53fa8580 0x00300040\t ;# DRAM_SDODT0\n\n\t# Initialize DDR2 memory\n\tmww 0x63fd9088 0x32383535\n\tmww 0x63fd9090 0x40383538\n\tmww 0x63fd907c 0x0136014d\n\tmww 0x63fd9080 0x01510141\n\n\tmww 0x63fd9018 0x00011740\n\tmww 0x63fd9000 0xc3190000\n\tmww 0x63fd900c 0x555952e3\n\tmww 0x63fd9010 0xb68e8b63\n\tmww 0x63fd9014 0x01ff00db\n\tmww 0x63fd902c 0x000026d2\n\tmww 0x63fd9030 0x009f0e21\n\tmww 0x63fd9008 0x12273030\n\tmww 0x63fd9004 0x0002002d\n\tmww 0x63fd901c 0x00008032\n\tmww 0x63fd901c 0x00008033\n\tmww 0x63fd901c 0x00028031\n\tmww 0x63fd901c 0x092080b0\n\tmww 0x63fd901c 0x04008040\n\tmww 0x63fd901c 0x0000803a\n\tmww 0x63fd901c 0x0000803b\n\tmww 0x63fd901c 0x00028039\n\tmww 0x63fd901c 0x09208138\n\tmww 0x63fd901c 0x04008048\n\tmww 0x63fd9020 0x00001800\n\tmww 0x63fd9040 0x04b80003\n\tmww 0x63fd9058 0x00022227\n\tmww 0x63fd901c 0x00000000\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx53loco.cfg",
    "content": "##################################################################################\n# Author: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com> #\n# Kiwigrid GmbH                                                                  #\n##################################################################################\n\n# The IMX53LOCO (QSB) board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 Loco board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n#adapter srst delay 200\n#jtag_ntrst_delay 200\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { loco_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc loco_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53FA8554 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53FA8558 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53FA8560 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53FA8564 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT\n\tmww 0x53FA8568 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53FA8570 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\tmww 0x53FA8574 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53FA8578 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n\tmww 0x53FA857c 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53FA8580 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53FA8584 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53FA8588 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53FA8590 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53FA8594 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53FA86f0 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53FA86f4 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53FA86fc 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n\tmww 0x53FA8714 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode\n\tmww 0x53FA8718 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53FA871c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53FA8720 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53FA8724 0x04000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL0=\n\tmww 0x53FA8728 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53FA872c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B3DS\n\n\t# Initialize DDR2 memory\n\tmww 0x63FD9088 0x35343535\t;# ESDCTL_RDDLCTL\n\tmww 0x63FD9090 0x4d444c44\t;# ESDCTL_WRDLCTL\n\tmww 0x63FD907c 0x01370138\t;# ESDCTL_DGCTRL0\n\tmww 0x63FD9080 0x013b013c\t;# ESDCTL_DGCTRL1\n\tmww 0x63FD9018 0x00011740\t;# ESDCTL_ESDMISC\n\tmww 0x63FD9000 0xc3190000\t;# ESDCTL_ESDCTL\n\tmww 0x63FD900c 0x9f5152e3\t;# ESDCTL_ESDCFG0\n\tmww 0x63FD9010 0xb68e8a63\t;# ESDCTL_ESDCFG1\n\tmww 0x63FD9014 0x01ff00db\t;# ESDCTL_ESDCFG2\n\tmww 0x63FD902c 0x000026d2\t;# ESDCTL_ESDRWD\n\tmww 0x63FD9030 0x009f0e21\t;# ESDCTL_ESDOR\n\tmww 0x63FD9008 0x12273030\t;# ESDCTL_ESDOTC\n\tmww 0x63FD9004 0x0002002d\t;# ESDCTL_ESDPDC\n\tmww 0x63FD901c 0x00008032\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00008033\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028031\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x052080b0\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008040\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803a\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803b\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028039\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x05208138\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008048\t;# ESDCTL_ESDSCR\n\tmww 0x63FD9020 0x00005800\t;# ESDCTL_ESDREF\n\tmww 0x63FD9040 0x04b80003\t;# ESDCTL_ZQHWCTRL\n\tmww 0x63FD9058 0x00022227\t;# ESDCTL_ODTCTRL\n\tmww 0x63FD901C 0x00000000\t;# ESDCTL_ESDSCR\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/imx8mp-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8MP-EVK\n#\n# Board includes FTDI-based JTAG adapter: interface/ftdi/imx8mp-evk.cfg\n#\n\ntransport select jtag\nadapter speed 1000\nreset_config srst_only\nadapter srst delay 100\n\nset CHIPNAME imx8mp\nset CHIPCORES 4\n\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/insignal_arndale.cfg",
    "content": "#\n# InSignal Arndale board\n#\n\nsource [find target/exynos5250.cfg]\n\n# Experimentally determined highest working speed\nadapter speed 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kasli.cfg",
    "content": "adapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\nftdi layout_init 0x0008 0x000b\n# adapter usb location 1:8\n\nreset_config none\ntransport select jtag\nadapter speed 25000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kc100.cfg",
    "content": "# Knovative KC-100 cable modem\n\n# TNETC4401PYP, 208-QFP U3\nsource [find target/tnetc4401.cfg]\n\n# 14-pin EJTAG on JP1. Standard pinout, 1-3-5-7-9-11 = nTRST-TDI-TDO-TMS-TCK-nSRST. Use 2 for GND.\n# Was initially disabled in hardware; had to add a solder bridge reenabling R124, R125 on back.\nreset_config trst_and_srst separate\n\n# 16Mb Intel CFI flash. Note this CPU has an internal ROM at 0x1FC0000 (phys) for cold boot.\n# All that really does is some minimal checks before jumping to external flash at 0x00000000 phys.\n# That is remapped to 0xB0000000 uncached, 0x90000000 cached.\nflash bank intel cfi 0xB0000000 0x200000 2 2 $_TARGETNAME\n\n# Perform this after a clean reboot, halt, and reset init (which should also leave it halted).\nproc kc100_dump_flash {} {\n\techo \"Probing 48 TSOP Intel CFI flash chip (2MB)...\"\n\tflash probe intel\n\techo \"Dumping 2MB flash chip to flashdump.bin.\n\tflash read_bank 0 flashdump.bin 0 0x200000\n}\n\n#TODO figure out memory init sequence to be able to dump from cached segment instead\n\n# There is also a serial console on JP2, 3-5-6 = TX-RX-GND. 9600/8/N/1.\n\n# Possibly of note, this modem's ancient ethernet port does not support Auto-MDIX.\n\n# This modem in many ways appears to be essentially a clone of the SB5120. See usbjtag.com.\n# The firmware/OS is also susceptible to many of the same procedures in \"Hacking the Cable Modem\"\n# by DerEngel (Ryan Harris), available from No Starch Press.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kc705.cfg",
    "content": "# http://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html\n\nsource [find interface/ftdi/digilent-hs1.cfg]\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\nadapter speed 25000\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/kc705.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc7k325t.bit;\\\n# jtagspi_program bitstream-kc705.bin 0;\\\n# jtagspi_program bios.bin 0xaf0000;\\\n# jtagspi_program runtime.fbi 0xb00000;\\\n# xc7_program xc7.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kcu105.cfg",
    "content": "# xilinx ultrascale\n# http://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/keil_mcb1700.cfg",
    "content": "#\n# Keil MCB1700 eval board\n#\n# http://www.keil.com/mcb1700/picture.asp\n#\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/keil_mcb2140.cfg",
    "content": "#\n# Keil MCB2140 eval board\n#\n# http://www.keil.com/mcb2140/picture.asp\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kindle2.cfg",
    "content": "# Board configuration file for Amazon Kindle Model No. D00701 and D00801\n# AKA Kindle 2nd generation and Kindle DX\n# using a Freescale MCIMX31LDVKN5D i.MX31 processor\n#\n# Pins at J9 40-Pin FFC-A:\n#  1 - GND\n# 16 - TRSTB\n# 17 - TDI\n# 18 - TMS\n# 19 - TCK\n# 20 - RTCK\n# 21 - TDO\n# 22 - DE\n# 25 - BOOT_MODE4\n# 27 - BOOT_MODE2\n\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n\n$_TARGETNAME configure -event reset-init { kindle2_init }\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n# 8MiB NOR Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xa0000000 0x800000 2 2 $_TARGETNAME\n\n# 16kiB internal SRAM\n$_TARGETNAME configure -work-area-phys 0x1fffc000 \\\n\t-work-area-size 0x4000 -work-area-backup 0\n\n# FIXME: currently SRST is not wired to the system\nreset_config trst_only\njtag_ntrst_assert_width 10\njtag_ntrst_delay 30\n\n# this is broken but enabled by default\narm11 memwrite burst disable\n\nadapter speed 1000\nftdi tdo_sample_edge falling\n\nproc kindle2_init {} {\n\timx3x_reset\n\tkindle2_clock_setup\n\tdisable_mmu_and_cache\n\tkindle2_misc_init\n\tkindle2_sdram_init\n\tarm core_state arm\n}\n\nproc kindle2_clock_setup {} {\n\t# CCMR: clock from FPM/CKIL\n\tmww 0x53f80000  0x074b0b7b\n\t# IPU_CONF\n\tmww 0x53fc0000  0x040\n\t# 398MHz\n\tmww 0x53f80004 0xff871650\n\tmww 0x53f80010 0x00331c23\n}\n\nproc kindle2_misc_init { } {\n\t# AIPS1\n\tmww 0x43f00040 0x0\n\tmww 0x43f00044 0x0\n\tmww 0x43f00048 0x0\n\tmww 0x43f0004c 0x0\n\tmww 0x43f00050 0x0\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\n\t# AIPS2\n\tmww 0x53f00040 0x0\n\tmww 0x53f00044 0x0\n\tmww 0x53f00048 0x0\n\tmww 0x53f0004c 0x0\n\tmww 0x53f00050 0x0\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000cc03\n\tmww 0xb8002004 0xa0330d01\n\tmww 0xb8002008 0x00220800\n}\n\nproc disable_mmu_and_cache {} {\n\t# Mode Supervisor, disable FIQ, IRQ and imprecise data aborts\n\treg cpsr 0x1d3\n\n\t# flush entire BTAC\n\tarm mcr 15 0 7 5 6 0\n\t# invalidate instruction and data cache\n\t# MCR CP15, 0, R1, C7, C7, 0\n\tarm mcr 15 0 7 7 0\n\n\t# clean and invalidate cache\n\tarm mcr 15 0 7 15 0\n\n\t# disable MMU and caches\n\tarm mcr 15 0 1 0 0 0\n\n\tarm mcr 15 0 15 2 4 0\n\n\t# invalidate TLBs\n\tarm mcr 15 0 8 7 0 0\n\n\t# Drain the write buffer\n\tarm mcr 15 0 7 10 4 0\n\n\t# start from AIPS 2GB region\n\tarm mcr 15 0 15 2 4 0x40000015\n}\n\nproc kindle2_sdram_init {} {\n\t#--------------------------------------------\n\t# Samsung K4X1G323PC-8GC3 32Mx32 Mobile DDR SDRAM\n\t#--------------------------------------------\n\t# SDCLK\n\tmww 0x43fac26c 0\n\n\t# CAS\n\tmww 0x43fac270 0\n\n\t# RAS\n\tmww 0x43fac274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43fac27c 0x1000\n\n\t# DQM3\n\tmww 0x43fac284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2dc)\n\tmww 0x43fac288 0\n\tmww 0x43fac28c 0\n\tmww 0x43fac290 0\n\tmww 0x43fac294 0\n\tmww 0x43fac298 0\n\tmww 0x43fac29c 0\n\tmww 0x43fac2a0 0\n\tmww 0x43fac2a4 0\n\tmww 0x43fac2a8 0\n\tmww 0x43fac2ac 0\n\tmww 0x43fac2b0 0\n\tmww 0x43fac2b4 0\n\tmww 0x43fac2b8 0\n\tmww 0x43fac2bc 0\n\tmww 0x43fac2c0 0\n\tmww 0x43fac2c4 0\n\tmww 0x43fac2c8 0\n\tmww 0x43fac2cc 0\n\tmww 0x43fac2d0 0\n\tmww 0x43fac2d4 0\n\tmww 0x43fac2d8 0\n\tmww 0x43fac2dc 0\n\n\t# ?\n\tmww 0xb8002000 0x00006602\n\tmww 0xb8002004 0x00000501\n\tmww 0xb8002008 0x00000000\n\n\t# LPDDR1 Initialization script\n\tmww 0xb8001010 0x00000002\n\tmww 0xb8001010 0x00000004\n\t# ESDCFG0: set timing parameters\n\tmww 0xb8001004 0x007fff7f\n\t# ESDCTL0: select Prechare-All mode\n\tmww 0xb8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\t# ESDCTL0: Auto Refresh\n\tmww 0xb8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\t# ESDCTL0: Load Mode Register\n\tmww 0xb8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\t# ESDCTL0: enable Auto-Refresh\n\tmww 0xb8001000 0x82226080\n\tmww 0x80000000 0xdeadbeef\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kontron_sl28.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Kontron SMARC-sAL28\n\ntransport select jtag\nreset_config srst_only srst_nogate\n\njtag newtap unknown0 tap -irlen 12\n\nset _CPUS 2\nsource [find target/ls1028a.cfg]\n\nsource [find tcl/cpld/altera-epm240.cfg]\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/kwikstik.cfg",
    "content": "#\n# Freescale KwikStik development board\n#\n\n#\n# JLINK interface is onboard\n#\nsource [find interface/jlink.cfg]\n\nsource [find target/k40.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/la_fonera-fon2200.cfg",
    "content": "source [find target/atheros_ar2315.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# LambdaConcept ECPIX-5\n# http://docs.lambdaconcept.com/ecpix-5/\n# Currently there are following board variants:\n# ECPIX-5 45F - LFE5UM5G-45F\n# ECPIX-5 85F - LFE5UM5G-85F\n#\n# This boards have two JTAG interfaces:\n# - CN4, micro USB port connected to FT2232HQ chip:\n#        ADBUS0 TCK\n#        ADBUS1 TDI\n#        ADBUS2 TDO\n#        ADBUS3 TMS\n#        BDBUS0 UART_TXD\n#        BDBUS1 UART_RXD\n#   This interface should be used with following config:\n#        interface/ftdi/lambdaconcept_ecpix-5.cfg\n# - CN3, 6 pin connector\n# See schematics for more details:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n#\n# No reset lines are implemented. So it is not possible to remote reset the FPGA\n# by using any of this interfaces\n\nsource [find interface/ftdi/lambdaconcept_ecpix-5.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lemaker_hikey.cfg",
    "content": "#\n# board configuration for LeMaker Hikey\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi6220.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/linksys-wag200g.cfg",
    "content": "#\n# Linksys WAG200G Router\n#\n# The stock firmware Flash layout is organized as follow:\n#\n#   Start       End         Device\n#   0x90000000  0x90020000  /dev/mtdblock/2\n#   0x90020000  0x900d0000  /dev/mtdblock/1\n#   0x900d0000  0x903a0000  /dev/mtdblock/0\n#   0x903a0000  0x903e0000  /dev/mtdblock/5\n#   0x903e0000  0x903f0000  /dev/mtdblock/3\n#   0x903f0000  0x90400000  /dev/mtdblock/4\n\nset partition_list {\n    adam2\t{ \"Adam2 bootloader\"\t\t0x90000000 0x00020000 }\n    kernel\t{ \"Kernel\"\t\t\t0x90020000 0x000b0000 }\n    rootfs\t{ \"Root FS\"\t\t\t0x900d0000 0x002d0000 }\n    lang\t{ \"Minix language part\"\t\t0x903a0000 0x00040000 }\n    config\t{ \"Firmware config\"\t\t0x903e0000 0x00010000 }\n    adam2env\t{ \"Adam2 environment\"\t\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 4MB MXIC 29LV320MBTC Flash (Manufacturer/Device: 0x00c2 0x227e)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/linksys-wrt54gl.cfg",
    "content": "#\n# Linksys WRT54GL v1.1\n#\n\nsource [find target/bcm5352e.cfg]\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0x1c000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x1c040000 0x003b0000 }\n    nvram\t{ \"Config space\"\t\t0x1c3f0000 0x00010000 }\n}\n\n# External 4MB NOR Flash (Intel TE28F320C3BD90 or similar)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x1c000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/linksys_nslu2.cfg",
    "content": "# This is for the LinkSys (CISCO) NSLU2 board\n# It is an Intel XSCALE IXP420 CPU.\n\nsource [find target/ixp42x.cfg]\n# The _TARGETNAME is set by the above.\n\n$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lisa-l.cfg",
    "content": "# the Lost Illusions Serendipitous Autopilot\n# http://paparazzi.enac.fr/wiki/Lisa\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/logicpd_imx27.cfg",
    "content": "# The LogicPD Eval IMX27 eval board has a single IMX27 chip\nsource [find target/imx27.cfg]\n\n# The Logic PD board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\n#\n# FIX ME, Add support to\n#\n# (A) hard reset the board.\n# (B) Initialize the SDRAM on the board\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lpc1850_spifi_generic.cfg",
    "content": "#\n# Generic LPC1850 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC1850 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc1850\n\nsource [find target/lpc1850.cfg]\n\n#A large working area greatly reduces flash write times\nset _WORKAREASIZE 0x4000\n\n$_CHIPNAME.m3 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lpc4350_spifi_generic.cfg",
    "content": "#\n# Generic LPC4350 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC4350 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/lubbock.cfg",
    "content": "# Intel \"Lubbock\" Development Board with PXA255 (dbpxa255)\n#  Obsolete; this was Intel's original PXA255 development system\n#  Board also had CPU cards for SA1100, PXA210, PXA250, and more.\n\nsource [find target/pxa255.cfg]\n\nadapter srst delay 250\njtag_ntrst_delay 250\n\n# NOTE: until after pinmux and such are set up, only CS0 is\n# available ... not 2nd bank of CFI, or FPGA, SRAM, ENET, etc.\n\n# CS0, CS1 -- two banks of CFI flash, 32 MBytes each\n# each bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME cfi 0x04000000 0x02000000 2 4 $_TARGETNAME\n\n# CS2 low -- FPGA registers\n# CS2 high -- 1 MByte SRAM at 0x0a00.0000 ... last 64K for scratch\n$_TARGETNAME configure -work-area-phys 0x0a0f0000\n\n$_TARGETNAME configure -event reset-assert-pre \\\n\t\"$_TARGETNAME configure -work-area-size 0\"\n\n# Make the hex led display a number, assuming CS2 is set up\n# and all digits have been enabled through the FPGA.\nproc hexled {u32} {\n\tmww 0x08000010 $u32\n}\n\n# CS3 -- Ethernet\n# CS4 -- SA1111\n# CS5 -- PCMCIA\n\n# NOTE:  system console normally uses the FF UART connector\n\nproc lubbock_init {target} {\n\n\techo \"Initialize PXA255 Lubbock board\"\n\n\t# (1) pinmux\n\n\t# GPSR0..GPSR2\n\tmww 0x40e00018 0x00008000\n\tmww 0x40e0001c 0x00FC0382\n\tmww 0x40e00020 0x0001FFFF\n\t# GPDR0..GPDR2\n\tmww 0x40e0000c 0x0060A800\n\tmww 0x40e00010 0x00FF0382\n\tmww 0x40e00014 0x0001C000\n\t# GAFR0_[LU]..GAFR2_[LU]\n\tmww 0x40e00054 0x98400000\n\tmww 0x40e00058 0x00002950\n\tmww 0x40e0005c 0x000A9558\n\tmww 0x40e00060 0x0005AAAA\n\tmww 0x40e00064 0xA0000000\n\tmww 0x40e00068 0x00000002\n\n\t# write PSSR, enable GPIOs\n\tmww 0x40f00000 0x00000020\n\n\t# write LED ctrl register ... ones disable\n\t# high byte, 8 hex leds; low byte, 8 discretes\n\tmwh 0x08000040 0xf0ff\n\n\thexled 0x0000\n\n\t# (2) Address space setup\n\n\t# MSC0/MSC1/MSC2\n\tmww 0x48000008 0x23f223f2\n\tmww 0x4800000c 0x3ff1a441\n\tmww 0x48000010 0x7ff97ff1\n\t# pcmcia/cf\n\tmww 0x48000014 0x00000000\n\tmww 0x48000028 0x00010504\n\tmww 0x4800002c 0x00010504\n\tmww 0x48000030 0x00010504\n\tmww 0x48000034 0x00010504\n\tmww 0x48000038 0x00004715\n\tmww 0x4800003c 0x00004715\n\n\thexled 0x1111\n\n\t# (3) SDRAM setup\n\t# REVISIT this looks dubious ... no refresh cycles\n\tmww 0x48000004 0x03CA4018\n\tmww 0x48000004 0x004B4018\n\tmww 0x48000004 0x000B4018\n\tmww 0x48000004 0x000BC018\n\tmww 0x48000000 0x00001AC8\n\tmww 0x48000000 0x00001AC9\n\n\tmww 0x48000040 0x00000000\n\n\t# FIXME -- setup:\n\t#  CLOCKS (and faster JTAG)\n\t#  enable icache\n\n\t# FIXME SRAM isn't working\n\t# $target configure -work-area-size 0x10000\n\n\thexled 0x2222\n\n\tflash probe 0\n\tflash probe 1\n\n\thexled 0xcafe\n}\n$_TARGETNAME configure -event reset-init \"lubbock_init $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/marsohod.cfg",
    "content": "#\n# Marsohod CPLD Development and Education board\n#\n# http://marsohod.org/howtostart/plata\n#\n\n# Recommended MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Altera MAXII EPM240T100C CPLD\nsource [find cpld/altera-epm240.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/marsohod2.cfg",
    "content": "#\n# Marsohod2 FPGA Development and Education board\n#\n# http://www.marsohod.org/prodmarsohod2\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Cyclone III EP3C10E144 FPGA\nsource [find fpga/altera-ep3c10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/marsohod3.cfg",
    "content": "#\n# Marsohod3 FPGA Development and Education board\n#\n# http://www.marsohod.org/plata-marsokhod3\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# MAX10 10M50SAE144C8GES FPGA\nsource [find fpga/altera-10m50.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/mbed-lpc11u24.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC11U24 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC11U24\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# NXP LPC11U24 Cortex-M0 with 32kB Flash and 8kB SRAM\nset WORKAREASIZE 0x2000\n\nsource [find target/lpc11xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/mbed-lpc1768.cfg",
    "content": "# This is an mbed eval board with a single NXP LPC1768 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC1768\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/mcb1700.cfg",
    "content": "# Keil MCB1700 PCB with 1768\n#\n# Reset init script sets it to 100MHz\nset CCLK 100000\n\nsource [find target/lpc17xx.cfg]\n\nglobal MCB1700_CCLK\nset MCB1700_CCLK $CCLK\n\n$_TARGETNAME configure -event reset-start {\n\t# Start *real slow* as we do not know the\n    # state the boot rom left the clock in\n\tadapter speed 10\n}\n\n# Set up 100MHz clock to CPU\n$_TARGETNAME configure -event reset-init {\n    # PLL0CON: Disable PLL\n\tmww 0x400FC080 0x00000000\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n    # CCLK=PLL/4 (=100 MHz)\n\tmww 0x400FC104 0x00000003\n    # CLKSRCSEL: Clock source = internal RC oscillator\n\tmww 0x400FC10C 0x00000000\n\n    # PLL0CFG: M=50,N=1 -> PLL=400 MHz\n\tmww 0x400FC084 0x00000031\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# PLL0CON: Enable PLL\n\tmww 0x400FC080 0x00000001\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\tsleep 50\n\n    # PLL0CON: Connect PLL\n\tmww 0x400FC080 0x00000003\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# Dividing CPU clock by 8 should be pretty conservative\n\t#\n\t#\n\tglobal MCB1700_CCLK\n\tadapter speed [expr {$MCB1700_CCLK / 8}]\n\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\n\tmww 0x400FC040 0x01\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/microchip_explorer16.cfg",
    "content": "# Microchip Explorer 16 with PIC32MX360F512L PIM module.\n# http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858\n\n# TAPID for PIC32MX360F512L\nset CPUTAPID 0x30938053\n\n# use 32k working area\nset WORKAREASIZE 32768\n\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/microchip_sama5d27_som1_kit1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAMA5D27-SOM1-EK1\n# https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATSAMA5D27-SOM1-EK1\n# This board provide two jtag interfaces:\n# J11 - 10 pin interface\n# J10 - USB interface connected to the J-Link-OB.\n#       This functionality is implemented with an ATSAM3U4C microcontroller and\n#       provides JTAG functions and a bridge USB/Serial debug port (CDC).\n#\n# Jumper J7 disables the J-Link-OB-ATSAM3U4C JTAG functionality.\n# - Jumper J7 not installed: J-Link-OB-ATSAM3U4C is enabled and fully functional.\n# - Jumper J7 installed: J-Link-OB-ATSAM3U4C is disabled and an external JTAG\n#   controller can be used through the 10-pin JTAG port J11.\n\nsource [find interface/jlink.cfg]\nreset_config srst_only\n\nsource [find target/at91sama5d2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/microchip_same51_curiosity_nano.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAME51 Curiosity Nano evaluation kit.\n#\n# https://www.microchip.com/en-us/development-tool/EV76S68A\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same51\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/microchip_same54_xplained_pro.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54 Xplained Pro evaluation kit.\n# http://www.microchip.com/developmenttools/productdetails.aspx?partno=atsame54-xpro\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same54\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/microchip_saml11_xplained_pro.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L11 Xplained Pro Evaluation Kit.\n# https://www.microchip.com/DevelopmentTools/ProductDetails/dm320205\n#\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 1000\n\nset CHIPNAME saml11\nsource [find target/atsaml1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/mini2440.cfg",
    "content": "#-------------------------------------------------------------------------\n# Mini2440 Samsung s3c2440A Processor with 64MB DRAM, 64MB NAND, 2 MB N0R\n# NOTE: Configured for NAND boot (switch S2 in NANDBOOT)\n# 64 MB NAND (Samsung K9D1208V0M)\n# B Findlay  08/09\n#\n#   ----------- Important notes to help you on your way ----------\n# README:\n#     NOR/NAND Boot Switch - I have not read the vivi source, but from\n#     what I could tell from reading the registers it appears that vivi\n#     loads itself into DRAM and then flips NFCONT (0x4E000004) bits\n#     Mode (bit 0 = 1), and REG_nCE (bit 1 = 0) which maps the NAND\n#     FLASH at the bottom 64MB of memory. This essentially takes the\n#     NOR Flash out of the circuit so you can't trash it.\n#\n#     I adapted the samsung_s3c2440.cfg file which is why I did not\n#     include \"source [find target/samsung_s3c2440.cfg]\".  I believe\n#     the -work-area-phys 0x200000 is incorrect, but also had to pad\n#     some additional resets.  I didn't modify it as if it is working\n#     for someone, the work-area-phys is not used by most.\n#\n#     JTAG ADAPTER SPECIFIC\n#     IMPORTANT! Any JTAG device that uses ADAPTIVE CLOCKING will likely\n#     FAIL as the pin RTCK on the mini2440 10 pin JTAG Conn doesn't exist.\n#     This is Pin 11 (RTCK) on 20 pin JTAG connector. Therefore it is\n#     necessary to FORCE setting the clock. Normally this should be configured\n#     in the openocd.cfg file, but was placed here as it can be a tough\n#     problem to figure out.  THIS MAY NOT FIX YOUR PROBLEM.. I modified\n#     the openOCD driver jlink.c and posted it here. It may eventually end\n#     up changed in openOCD, but its a hack in the driver and really should\n#     be in the jtag layer (core.c me thinks), but haven't done it yet. My\n#     hack for jlink.c may be found here.\n#\n#     http://forum.sparkfun.com/viewtopic.php?t=16763&sid=946e65abdd3bab39cc7d90dee33ff135\n#\n#     Note: Also if you have a USB JTAG, you will need the USB library installed\n#     on your system \"libusb-dev\" or the make of openocd will fail. I *think*\n#     it's apt-get install libusb-dev.  When I made my config I only included\n#     --enable-jlink and --enable-usbdevs\n#\n#     I HAVE NOT Tested this thoroughly, so there could still be problems.\n#     But it should get you way ahead of the game from where I started.\n#     If you find problems (and fixes) please post them to\n#     openocd-development@lists.berlios.de and join the developers and\n#     check in fixes to this and anything else you find.  I do not\n#     provide support, but if you ask really nice and I see anything\n#     obvious I will tell you.. mostly just dig, fix, and submit to openocd.\n#\n#     best!   brfindla@yahoo.com   Nashua, NH USA\n#\n#     Recommended resources:\n#       - first two are the best Mini2440 resources anywhere\n#       - maintained by buserror... thanks guy!\n#\n#       http://bliterness.blogspot.com/\n#       http://code.google.com/p/mini2440/\n#\n#       others....\n#\n#       http://forum.sparkfun.com/viewforum.php?f=18\n#       http://labs.kernelconcepts.de/Publications/Micro24401/\n#       http://www.friendlyarm.net/home\n#       http://www.amontec.com/jtag_pinout.shtml\n#\n#-------------------------------------------------------------------------\n#\n#\n# Your openocd.cfg file should contain:\n# source [find interface/<yourjtag>.cfg]\n# source [find board/mini2440.cfg]\n#\n#\n#\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\n#-------------------------------------------------------------------------\n# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor : ARM920Tid(wb) rev 0 (v4l)\n# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d\n#  (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n#-------------------------------------------------------------------------\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x40000000  -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\n#-------------------------------------------------------------------------\n# JTAG ADAPTER SPECIFIC\n# IMPORTANT! See README at top of this file.\n#-------------------------------------------------------------------------\n\n    adapter speed 12000\n    jtag interface\n\n#-------------------------------------------------------------------------\n# GDB Setup\n#-------------------------------------------------------------------------\n\n    gdb_breakpoint_override hard\n\n#------------------------------------------------\n# ARM SPECIFIC\n#------------------------------------------------\n\n    targets\n  #  arm7_9 dcc_downloads enable\n  #  arm7_9 fast_memory_access enable\n\n\n    nand device s3c2440 0\n\n    adapter srst delay 100\n    jtag_ntrst_delay 100\n    reset_config trst_and_srst\n    init\n\n    echo \" \"\n    echo \"-------------------------------------------\"\n    echo \"--- login with - telnet localhost 4444  ---\"\n    echo \"--- then type help_2440                 ---\"\n    echo \"-------------------------------------------\"\n    echo \" \"\n\n\n\n#------------------------------------------------\n# Processor Initialialization\n# Note: Processor writes can only occur when\n# the state is in SYSTEM. When you call init_2440\n# one of the first lines will tell you what state\n# you are in. If a linux image is booting\n# when you run this, it will not work\n# a vivi boot loader will run with this just\n# fine. The reg values were obtained by a combination\n# of figuring them out fromt the manual, and looking\n# at post vivi values with the debugger. Don't\n# place too much faith in them, but seem to work.\n#------------------------------------------------\n\nproc init_2440 { } {\n\n    halt\n    s3c2440.cpu curstate\n\n    #-----------------------------------------------\n    # Set Processor Clocks - mini2440 xtal=12mHz\n    # we set main clock for 405mHZ\n    # we set the USB Clock for 48mHz\n    # OM2 OM3 pulled to ground so main clock and\n    # usb clock are off 12mHz xtal\n    #-----------------------------------------------\n\n    mww phys 0x4C000014 0x00000005 ;#  Clock Divider control Reg\n    mww phys 0x4C000000 0xFFFFFFFF ;#  LOCKTIME count register\n    mww phys 0x4C000008 0x00038022 ;#  UPPLCON  USB clock config Reg\n    mww phys 0x4C000004 0x0007F021 ;#  MPPLCON  Proc clock config Reg\n\n    #-----------------------------------------------\n    # Configure Memory controller\n    # BWSCON configures all banks, NAND, NOR, DRAM\n    # DRAM - 64MB - 32 bit bus, uses BANKCON6 BANKCON7\n    #-----------------------------------------------\n\n    mww phys 0x48000000 0x22111112 ;#  BWSCON - Bank and Bus Width\n    mww phys 0x48000010 0x00001112 ;#  BANKCON4 - ?\n    mww phys 0x4800001c 0x00018009 ;#  BANKCON6 - DRAM\n    mww phys 0x48000020 0x00018009 ;#  BANKCON7 - DRAM\n    mww phys 0x48000024 0x008E04EB ;#  REFRESH  - DRAM\n    mww phys 0x48000028 0x000000B2 ;#  BANKSIZE - DRAM\n    mww phys 0x4800002C 0x00000030 ;#  MRSRB6 - DRAM\n    mww phys 0x48000030 0x00000030 ;#  MRSRB7 - DRAM\n\n    #-----------------------------------------------\n    # Now port configuration for enables for memory\n    # and other stuff.\n    #-----------------------------------------------\n\n    mww phys 0x56000000\t0x007FFFFF ;#  GPACON\n\n    mww phys 0x56000010\t0x00295559 ;#  GPBCON\n    mww phys 0x56000018\t0x000003FF ;#  GPBUP (PULLUP ENABLE)\n    mww phys 0x56000014\t0x000007C2 ;#  GPBDAT\n\n    mww phys 0x56000020\t0xAAAAA6AA ;#  GPCCON\n    mww phys 0x56000028\t0x0000FFFF ;#  GPCUP\n    mww phys 0x56000024\t0x00000020 ;#  GPCDAT\n\n    mww phys 0x56000030\t0xAAAAAAAA ;#  GPDCON\n    mww phys 0x56000038\t0x0000FFFF ;#  GPDUP\n\n    mww phys 0x56000040\t0xAAAAAAAA ;#  GPECON\n    mww phys 0x56000048\t0x0000FFFF ;#  GPEUP\n\n    mww phys 0x56000050\t0x00001555 ;#  GPFCON\n    mww phys 0x56000058\t0x0000007F ;#  GPFUP\n    mww phys 0x56000054\t0x00000000 ;#  GPFDAT\n\n    mww phys 0x56000060\t0x00150114 ;#  GPGCON\n    mww phys 0x56000068\t0x0000007F ;#  GPGUP\n\n    mww phys 0x56000070\t0x0015AAAA ;#  GPHCON\n    mww phys 0x56000078\t0x000003FF ;#  GPGUP\n\n}\n\n\n\nproc flash_config { } {\n\n    #-----------------------------------------\n    # Finish Flash Configuration\n    #-----------------------------------------\n\n    halt\n\n    #flash configuration (K9D1208V0M: 512Mbit, x8, 3.3V, Mode: Normal, 1st gen)\n    nand probe 0\n    nand list\n}\n\nproc flash_uboot { } {\n\n\t# flash the u-Boot binary and reboot into it\n\tinit_2440\n\tflash_config\n\tnand erase 0 0x0 0x40000\n\tnand write 0 /tftpboot/u-boot-nand512.bin 0 oob_softecc_kw\n\tresume\n}\n\n\nproc load_uboot { } {\n        echo \" \"\n        echo \" \"\n        echo \"----------------------------------------------------------\"\n        echo \"---- Load U-Boot into RAM and execute it.              ---\"\n        echo \"---- NOTE: loads, partially runs, and hangs            ---\"\n        echo \"---- U-Boot is fine, this image runs from vivi.        ---\"\n        echo \"---- I burned u-boot into NAND so I didn't finish      ---\"\n        echo \"---- debugging it. I am leaving this here as it is     ---\"\n        echo \"---- part of the way there if you want to fix it.      ---\"\n        echo \"----                                                   ---\"\n        echo \"---- mini2440 U-boot here:                             ---\"\n        echo \"---- http://repo.or.cz/w/u-boot-openmoko/mini2440.git  ---\"\n        echo \"---- Also this:                                        ---\"\n        echo \"---- http://code.google.com/p/mini2440/wiki/MiniBringup --\"\n        echo \"----------------------------------------------------------\"\n\n\tinit_2440\n\techo \"Loading /tftpboot/u-boot-nand512.bin\"\n\tload_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"Verifying image....\"\n\tverify_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"jumping to u-boot\"\n        #bp 0x33f80068 4 hw\n        reg 0 0\n        reg 1 0\n        reg 2 0\n        reg 3 0\n        reg 4 0x33f80000\n      \tresume 0x33f80000\n}\n\n       # this may help a little bit debugging the load_uboot\nproc s {} {\n        step\n        reg\n        arm disassemble 0x33F80068 0x10\n}\n\nproc help_2440 {} {\n    echo \" \"\n    echo \" \"\n    echo \"-----------------------------------------------------------\"\n    echo \"---- The following mini2440 funcs are supported        ----\"\n    echo \"----   init_2440 - initialize clocks, DRAM, IO         ----\"\n    echo \"----   flash_config - configures nand flash            ----\"\n    echo \"----   load_uboot - loads uboot into ram               ----\"\n    echo \"----   flash_uboot - flashes uboot to nand (untested)  ----\"\n    echo \"----   help_2440 - this help display                   ----\"\n    echo \"-----------------------------------------------------------\"\n    echo \" \"\n    echo \" \"\n}\n\n\n#----------------------------------------------------------------------------\n#----------------------------------- END ------------------------------------\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/mini6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a tiny6410\n# Processor       : ARM1176\n# Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2)\n# Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787, part: 0x7b76, ver: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nproc init_6410 {} {\n\thalt\n\treg cpsr 0x1D3\n\tarm mcr 15 0 15 2 4 0x70000013\n\n\t#-----------------------------------------------\n\t# Clock and Timer Setting\n\t#-----------------------------------------------\n\tmww 0x7e004000 0\t\t;# WATCHDOG \t- Disable\n\tmww 0x7E00F120 0x0003\t\t;# MEM_SYS_CFG\t- CS0:8 bit, Mem1:32bit, CS2=NAND\n\t#mww 0x7E00F120 0x1000\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=SROMC\n\t#mww 0x7E00F120 0x1002\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=OND\n\tmww 0x7E00F900 0x805e\t\t;# OTHERS\t- Change SYNCMUX[6] to “1”\n\tsleep 1000\n\tmww 0x7E00F900 0x80de\t\t;# OTHERS\t- Assert SYNCREQ&VICSYNCEN to “1”(rb1004modify)\n\tsleep 1000\t\t\t;#\t\t- Others[11:8] to 0xF\n\tmww 0x7E00F000 0xffff\t\t;# APLL_LOCK\t- APLL LockTime\n\tmww 0x7E00F004 0xffff\t\t;# MPLL_LOCK\t- MPLL LockTime\n\tmww 0x7E00F020 0x1047310\t;# CLK_DIV0 \t- ARMCLK:HCLK:PCLK = 1:4:16\n\tmww 0x7E00F00c 0x81900302\t;# APLL_CON \t- A:400, P:3, S:2 => 400MHz\n\tmww 0x7E00F010 0x81900303\t;# MPLL_CON \t- M:400, P:3, S:3 => 200MHz\n\tmww 0x7E00F01c 0x3\t\t;# CLK_SRC \t- APLL,MPLL Clock Select\n\n\t#-----------------------------------------------\n\t# DRAM initialization\n\t#-----------------------------------------------\n\tmww 0x7e001004 0x4\t\t;# P1MEMCCMD\t- Enter the config state\n\tmww 0x7e001010 0x30C\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 100MHz\n#\tmww 0x7e001010 0x40e\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 133MHz\n\tmww 0x7e001014 0x6\t\t;# P1CASLAT\t- CAS Latency = 3\n\tmww 0x7e001018 0x1\t\t;# P1T_DQSS\n\tmww 0x7e00101c 0x2\t\t;# P1T_MRD\n\tmww 0x7e001020 0x7\t\t;# P1T_RAS\t- 45 ns\n\tmww 0x7e001024 0xA\t\t;# P1T_RC\t- 67.5 ns\n\tmww 0x7e001028 0xC\t\t;# P1T_RCD\t- 22.5 ns\n\tmww 0x7e00102C 0x10B\t\t;# P1T_RFC\t- 80 ns\n\tmww 0x7e001030 0xC\t\t;# P1T_RP\t- 22.5 ns\n\tmww 0x7e001034 0x3\t\t;# P1T_RRD\t- 15 ns\n\tmww 0x7e001038 0x3\t\t;# P1T_WR\t- 15 ns\n\tmww 0x7e00103C 0x2\t\t;# P1T_WTR\n\tmww 0x7e001040 0x2\t\t;# P1T_XP\n\tmww 0x7e001044 0x11\t\t;# P1T_XSR\t- 120 ns\n\tmww 0x7e001048 0x11\t\t;# P1T_ESR\n\n\t#-----------------------------------------------\n\t# Memory Configuration Registers\n\t#-----------------------------------------------\n\tmww 0x7e00100C 0x00010012 \t;# P1MEMCFG\t- 1 CKE, 1Chip, 4burst, Alw, AP[10],ROW/Column bit\n\tmww 0x7e00104C 0x0B41 \t\t;# P1MEMCFG2\t- Read delay 1 Cycle, mDDR, 32bit, Sync.\n\tmww 0x7e001200 0x150F0 \t\t;# CHIP_N_CFG\t- 0x150F0 for 256M, 0x150F8 for 128M\n\n\t#-----------------------------------------------\n\t# Memory Direct Commands\n\t#-----------------------------------------------\n\tmww 0x7e001008 0xc0000\t\t;# Chip0 Direct Command :NOP5\n\tmww 0x7e001008 0x0\t\t;# Chip0 Direct Command :PreCharge al\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0xA0000\t\t;# EMRS, DS:Full, PASR:Full\n\tmww 0x7e001008 0x80032\t\t;# MRS, CAS3, BL4\n\tmww 0x7e001004 0x0\t\t;# Enable DMC1\n}\n\nproc install_6410_uboot {} {\n\t# write U-boot magic number\n\tmww 0x50000000 0x24564236\n\tmww 0x50000004 0x20764316\n\tload_image u-boot_nand-ram256.bin 0x50008000 bin\n\tload_image u-boot_nand-ram256.bin 0x57E00000 bin\n\n\t#Kick in\n\treg pc 0x57E00000\n\tresume\n}\n\nproc init_6410_flash {} {\n\thalt\n\tnand probe 0\n\tnand list\n}\n\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\ngdb_breakpoint_override hard\n\ntargets\nnand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu\n\ninit\necho \" \"\necho \" \"\necho \"-------------------------------------------------------------------\"\necho \"---- The following mini6410/tiny6410 functions are available:  ----\"\necho \"----   init_6410 - initialize clock, timer, DRAM               ----\"\necho \"----   init_6410_flash - initializes NAND flash support        ----\"\necho \"----   install_6410_uboot - copies u-boot image into RAM and   ----\"\necho \"----                        runs it                            ----\"\necho \"-------------------------------------------------------------------\"\necho \" \"\necho \" \"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n\nsource [find interface/ftdi/minispartan6.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to read the device dna of the FPGA on the board;\n# openocd -f board/minispartan6.cfg -c \"init;xc6s_print_dna xc6s.tap;shutdown\"\n\n# example command to write bitstream\n# openocd -f board/minispartan6.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx??.bit;\\\n# jtagspi_program bitstream.bin 0;\\\n# xc6s_program xc6s.tap;\\\n# shutdown\"\n#\n# jtagspi flash procies can be found in the contrib/loaders/flash/fpga/\n# directory, with prebuilt versions available at\n# https://github.com/jordens/bscan_spi_bitstreams\n#\n# For the SLX25 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx25.bit\n# For the SLX9 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx9.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nds32_corvettef1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-Corvette-F1 R1.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r1/\n# ADP-Corvette-F1 R2.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r2/\n\nadapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nreset_config srst_only\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nds32_xc5.cfg",
    "content": "set _CPUTAPID 0x1000063d\nset _CHIPNAME nds32\nsource [find target/nds32v3.cfg]\n\njtag init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nds32_xc7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-XC7K160/410\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/adp-xc7k160-410/\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/netgear-dg834v3.cfg",
    "content": "#\n# Netgear DG834v3 Router\n# Internal 4Kb RAM (@0x80000000)\n# Flash is located at 0x90000000 (CS0) and RAM is located at 0x94000000 (CS1)\n#\n\nset partition_list {\n    loader\t{ \"Bootloader (ADAM2)\"\t\t0x90000000 0x00020000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x90020000 0x003d0000 }\n    config\t{ \"Bootloader config space\"\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 16MB SDRAM - disabled as we use internal sram\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n\n# External 4MB NOR Flash\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/netgear-wg102.cfg",
    "content": "source [find target/atheros_ar2313.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\tmips32 cp0 12 0 0x10400000\n\n\t# configure sdram controller\n\tmww 0xb8300004 0x0e03\n\tsleep 100\n\tmww 0xb8300004 0x0e01\n\tmww 0xb8300008 0x10\n\tsleep 500\n\tmww 0xb8300004 0x0e02\n\n\tmww 0xb8300000 0x6c0088\n\tmww 0xb8300008 0x57e\n\tmww 0xb8300004 0x0e00\n\tmww 0xb8300004 0xb00\n\n\t# configure flash\n\t#                 0x00000001 - 0x01 << FLASHCTL_IDCY_S\n\t#                 0x000000e0 - 0x07 << FLASHCTL_WST1_S\n\t# FLASHCTL_RBLE   0x00000400 - Read byte lane enable\n\t#                 0x00003800 - 0x07 << FLASHCTL_WST2_S\n\t# FLASHCTL_AC_8M  0x00060000 - Size of flash\n\t# FLASHCTL_E      0x00080000 - Flash bank enable (added)\n\t# FLASHCTL_WP     0x04000000 - write protect. If used, CFI mode wont work!!\n\t# FLASHCTL_MWx16  0x10000000 - 16bit mode. Do not use it!!\n\t# FLASHCTL_MWx8   0x00000000 - 8bit mode.\n\tmww 0xb8400000 0x000d3ce1\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbe000000 0x00400000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nordic_nrf51822_mkit.cfg",
    "content": "#\n# Nordic Semiconductor PCA10024 board (aka nRF51822-mKIT)\n#\n\nsource [find interface/cmsis-dap.cfg]\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nordic_nrf51_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF51 Development Kit (nRF6824)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nordic_nrf52_dk.cfg",
    "content": "#\n# Nordic Semiconductor NRF52 Development Kit (nRF52832)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nordic_nrf52_ftx232.cfg",
    "content": "#\n# nordic module NRF52 (nRF52832/52840) attached to an adafruit ft232h module\n# or any FT232H/FT2232H/FT4232H based board/module\n#\n\nsource [find interface/ftdi/ft232h-module-swd.cfg]\n#source [find interface/ftdi/minimodule-swd.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/novena-internal-fpga.cfg",
    "content": "#\n# Novena open hardware and F/OSS-friendly computing platform\n#\n# Design documentation:\n# http://www.kosagi.com/w/index.php?title=Novena_PVT_Design_Source\n#\n# +-------------+--------------+------+-------+---------+\n# | Pad name    | Schematic    | GPIO | sysfs | JTAG    |\n# +-------------+--------------+------+-------+---------+\n# | DISP0_DAT13 | FPGA_RESET_N | 5-07 |  135  | RESET_N |\n# | DISP0_DAT14 | FPGA_TCK     | 5-08 |  136  | TCK     |\n# | DISP0_DAT15 | FPGA_TDI     | 5-09 |  137  | TDI     |\n# | DISP0_DAT16 | FPGA_TDO     | 5-10 |  138  | TDO     |\n# | DISP0_DAT17 | FPGA_TMS     | 5-11 |  139  | TMS     |\n# +-------------+--------------+------+-------+---------+\n\nadapter driver sysfsgpio\n\ntransport select jtag\n\n# TCK TMS TDI TDO\nsysfsgpio jtag_nums 136 139 137 138\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/npcx_evb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Nuvoton NPCX Evaluation Board\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\nsource [find target/npcx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/numato_mimas_a7.cfg",
    "content": "#\n# Numato Mimas A7 - Artix 7 FPGA Board\n#\n# https://numato.com/product/mimas-a7-artix-7-fpga-development-board-with-ddr-sdram-and-gigabit-ethernet\n#\n# Note: Connect external DC power supply if programming a heavy design onto FPGA.\n#       Programming while powering via USB may lead to programming failure.\n#       Therefore, prefer external power supply.\n\nadapter driver ftdi\nftdi device_desc \"Mimas Artix 7 FPGA Module\"\nftdi vid_pid 0x2a19 0x1009\n\n# channel 0 is for custom purpose by users (like uart, fifo etc)\n# channel 1 is reserved for JTAG (by-default) or SPI (possible via changing solder jumpers)\nftdi channel 1\nftdi tdo_sample_edge falling\n\n\n# FTDI Pin Layout\n#\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | DBUS7  | DBUS6 | DBUS5 | DBUS4 | DBUS3 | DBUS2 | DBUS1 | DBUS0 |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | PROG_B | OE_N  |  NC   |  NC   |  TMS  |  TDO  |  TDI  |  TCK  |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n#\n# OE_N is JTAG buffer output enable signal (active-low)\n# PROG_B is not used, so left as input to FTDI.\n#\nftdi layout_init 0x0008 0x004b\nreset_config none\nadapter speed 30000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/numato_opsis.cfg",
    "content": "# http://opsis.hdmi2usb.tv\n#\n# The Numato Opsis is an FPGA based, open video platform.\n#\n# The board is supported via ixo-usb-jtag project. See the\n# interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_frdm-k64f.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an NXP Freedom eval board with a single MK64FN1M0VLL12 chip.\n# https://www.nxp.com/design/development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# Set working area to 16 KiB\nset WORKAREASIZE 0x4000\n\nset CHIPNAME k64f\nreset_config srst_only\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_frdm-ls1012a.cfg",
    "content": "#\n# NXP FRDM-LS1012A (Freedom)\n#\n\n#\n# NXP Kinetis K20\n#\nsource [find interface/cmsis-dap.cfg]\ntransport select jtag\n\n# Also offers a 10-pin 0.05\" CoreSight JTAG connector.\n\nsource [find target/ls1012a.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_imx7sabre.cfg",
    "content": "# NXP IMX7SABRE board\n# use on-board JTAG header\ntransport select jtag\n\n# set a safe speed, can be overridden\nadapter speed 1000\n\n# reset configuration has TRST and SRST support\nreset_config trst_and_srst srst_push_pull\n# need at least 100ms delay after SRST release for JTAG\nadapter srst delay 100\n\n# source the target file\nsource [find target/imx7.cfg]\n# import mrw proc\nsource [find mem_helper.tcl]\n\n# function to disable the on-chip watchdog\nproc imx7_disable_wdog { } {\n        # echo \"disable watchdog power-down counter\"\n        mwh phys 0x30280008 0x00\n}\n\nproc imx7_uart_dbgconf { } {\n\t# disable response to debug_req signal for uart1\n\tmww phys 0x308600b4 0x0a60\n}\n\nproc check_bits_set_32 { addr mask } {\n    while { [expr {[mrw $addr] & $mask} == 0] } { }\n}\n\nproc apply_dcd { } {\n    # echo \"apply dcd\"\n\n    mww phys 0x30340004 0x4F400005\n    # Clear then set bit30 to ensure exit from DDR retention\n    mww phys 0x30360388 0x40000000\n    mww phys 0x30360384 0x40000000\n\n    mww phys 0x30391000 0x00000002\n    mww phys 0x307a0000 0x01040001\n    mww phys 0x307a01a0 0x80400003\n    mww phys 0x307a01a4 0x00100020\n    mww phys 0x307a01a8 0x80100004\n    mww phys 0x307a0064 0x00400046\n    mww phys 0x307a0490 0x00000001\n    mww phys 0x307a00d0 0x00020083\n    mww phys 0x307a00d4 0x00690000\n    mww phys 0x307a00dc 0x09300004\n    mww phys 0x307a00e0 0x04080000\n    mww phys 0x307a00e4 0x00100004\n    mww phys 0x307a00f4 0x0000033f\n    mww phys 0x307a0100 0x09081109\n    mww phys 0x307a0104 0x0007020d\n    mww phys 0x307a0108 0x03040407\n    mww phys 0x307a010c 0x00002006\n    mww phys 0x307a0110 0x04020205\n    mww phys 0x307a0114 0x03030202\n    mww phys 0x307a0120 0x00000803\n    mww phys 0x307a0180 0x00800020\n    mww phys 0x307a0184 0x02000100\n    mww phys 0x307a0190 0x02098204\n    mww phys 0x307a0194 0x00030303\n    mww phys 0x307a0200 0x00000016\n    mww phys 0x307a0204 0x00171717\n    mww phys 0x307a0214 0x04040404\n    mww phys 0x307a0218 0x0f040404\n    mww phys 0x307a0240 0x06000604\n    mww phys 0x307a0244 0x00000001\n    mww phys 0x30391000 0x00000000\n    mww phys 0x30790000 0x17420f40\n    mww phys 0x30790004 0x10210100\n    mww phys 0x30790010 0x00060807\n    mww phys 0x307900b0 0x1010007e\n    mww phys 0x3079009c 0x00000d6e\n    mww phys 0x30790020 0x08080808\n    mww phys 0x30790030 0x08080808\n    mww phys 0x30790050 0x01000010\n    mww phys 0x30790050 0x00000010\n\n    mww phys 0x307900c0 0x0e407304\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e447306\n\n    check_bits_set_32 0x307900c4 0x1\n\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e407304\n\n\n    mww phys 0x30384130 0x00000000\n    mww phys 0x30340020 0x00000178\n    mww phys 0x30384130 0x00000002\n    mww phys 0x30790018 0x0000000f\n\n    check_bits_set_32 0x307a0004 0x1\n}\n\n# disable internal reset-assert handling to\n# allow reset-init to work\n$_TARGETNAME.0 configure -event reset-assert \"\"\n$_TARGETNAME.1 configure -event reset-assert \"\"\n$_TARGETNAME_2 configure -event reset-assert \"\"\n\n$_TARGETNAME.0 configure -event reset-init {\n    global _CHIPNAME\n    imx7_disable_wdog\n    imx7_uart_dbgconf\n    apply_dcd\n    $_CHIPNAME.dap memaccess 0\n}\n\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_lpc-link2.cfg",
    "content": "#\n# NXP LPC-Link2\n#\n# http://www.nxp.com/board/OM13054.html\n# https://www.lpcware.com/lpclink2\n# http://embeddedartists.com/products/lpcxpresso/lpclink2.php\n#\n\nsource [find target/lpc4370.cfg]\n\n# W25Q80BVSSIG w/ 1 MB flash\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_mcimx8m-evk.cfg",
    "content": "#\n# configuration file for NXP MC-IMX8M-EVK\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_rdb-ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046ARDB (Reference Design Board)\n# This is for the \"console\" USB port on the front panel\n# You must ensure that SW4-7 is in the \"off\" position\n\n# NXP K20\n# The firmware implements the old CMSIS-DAP v1 USB HID interface\n# You must pass --enable-cmsis-dap to ./configure to enable it\nsource [find interface/cmsis-dap.cfg]\n\ntransport select jtag\nreset_config srst_only\n\nsource [find target/ls1046a.cfg]\n\n# The adapter can't handle 10MHz\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/nxp_rdb-ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088ARDB (Reference Design Board)\n# This is for the \"main\" JTAG connector J55\n\ntransport select jtag\nreset_config srst_only\n\n# To access the CPLD, populate J48 and add `-c 'set CWTAP 1'` to your command\n# line. At the time of this writing, programming is unsupported.\nif { [info exists CWTAP] } {\n\tsource [find cpld/altera-epm240.cfg]\n} else {\n\tsource [find target/ls1088a.cfg]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_LPC2378STK.cfg",
    "content": "#####################################################\n# Olimex LPC2378STK eval board\n#\n# http://olimex.com/dev/lpc-2378stk.html\n#\n# Author: Sten, debian@sansys-electronic.com\n#####################################################\n#\n\nsource [find target/lpc2378.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_lpc_h2148.cfg",
    "content": "#\n# Olimex LPC-H2148 eval board\n#\n# http://www.olimex.com/dev/lpc-h2148.html\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_sam7_ex256.cfg",
    "content": "# Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it.\n\nsource [find target/at91sam7x256.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_sam7_la2.cfg",
    "content": "source [find target/at91sam7a2.cfg]\n\n# delays needed to get stable reads of cpu state\njtag_ntrst_delay 10\nadapter srst delay 200\n\n# board uses pullup and connects only srst\nreset_config srst_open_drain\n\n# srst is connected to NRESET of CPU and fully resets everything...\nreset_config srst_only srst_pulls_trst\n\nadapter speed 1\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 1\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# init script from http://www.mikrocontroller.net/topic/107462\n\t# AT91SAM7A2\n\t# AMC (advanced memory controller)\n\n\techo \"setting up AMC\"\n\t# AMC_CS0 - FLASH 1MB (0x40000000-0x400FFFFF) + DM9000E (0x40100000)\n\tmww 0xFFE00000 0x40003EBD\n\n\t# AMC_CS1 - RAM low 2MB (0x40400000-0x405FFFFF)\n\tmww 0xFFE00004 0x404030A9\n\n\t# AMC_CS2 - RAM high 2MB (0x40800000-0x405FFFFF)\n\t#mww 0xFFE00008 0x404030A9\n\t# changed to  0x40_8_\n\tmww 0xFFE00008 0x408030A9\n\n\t# AMC_MCR\n\tmww 0xFFE00024 0x00000004\n\n\t# AMC_RCR force remap\n\tmww 0xFFE00020 0x00000001\n\n\techo \"set up AMC\"\n\tsleep 100\n\n\t# the following base addresses from the original script did not correspond to those from datasheet\n\t# changed bases from 0xFF000000 to 0xFFF00000\n\n\t# disable watchdog, to prevent unwanted resets\n\tmww 0xFFFA0068 0x00000000\n\techo \"disabled watchdog\"\n\n\tsleep 50\n\n\t# disable PLL\n\tmww 0xFFFEC004 0x18070004\n\n\t# PLL = 10 ==> Coreclock = 6Mhz*10/2 = 30 Mhz\n\tmww 0xFFFEC010 0x762D800A\n\n\t# enable PLL\n\tmww 0xFFFEC000 0x23050004\n\techo \"set up pll\"\n\n\tsleep 100\n\tadapter speed 5000\n}\n\n$_TARGETNAME arm7_9 dcc_downloads enable\n$_TARGETNAME arm7_9 fast_memory_access enable\n\n# remap:  ram at 0, flash at 0x40000000, like reset-init above does\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\nflash bank onboard.flash cfi 0x40000000 0x00100000 2 2 at91sam7a2.cpu\n\n# boot: ram at 0x300000, flash at 0x0, useful if board is in funny configuration\n#$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n#flash bank onboard1.flash cfi 0x00000000 0x00100000 2 2 at91sam7a2.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_sam9_l9260.cfg",
    "content": "################################################################################\n# Olimex SAM9-L9260 Development Board\n#\n# http://www.olimex.com/dev/sam9-L9260.html\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     PMC configured for external 18.432 MHz crystal\n#\n# 32-bit SDRAM : 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks\n# 8-bit NAND Flash : 1 x Samsung K9F4G08U0M, 512M x 8Bit\n# Dataflash : 1 x Atmel AT45DB161D, 16Mbit\n#\n################################################################################\n\nsource [find target/at91sam9260.cfg]\n\n# NTRST_E jumper is enabled by default, so we don't need to override the reset\n# config.\n#reset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n\t# At reset, CPU runs at 32.768 kHz.  JTAG frequency must be 6 times slower if\n\t# RCLK is not supported.\n\tjtag_rclk 5\n\thalt\n\n\t# RSTC_MR : enable user reset, reset length is 64 slow clock cycles.  MMU may\n\t# be enabled... use physical address.\n\tmww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog\n\n\t##\n\t# Clock configuration for 99.328 MHz main clock.\n\t##\n    echo \"Setting up clock\"\n\tmww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable main oscillator, 512 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 15.6 ms for startup)\n\tmww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator (18.432 MHz)\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR : 18.432 MHz / 9 * 97 = 198.656 MHz, 63 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 1.9 ms for startup)\n\tmww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz)\n\n\t# Increase JTAG speed to 6 MHz if RCLK is not supported.\n\tjtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable ;# Enable faster DCC downloads.\n\n\t##\n\t# SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks.\n\t##\n    echo \"Configuring SDRAM\"\n\tmww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips\n\n\tmww 0xffffea00 0x1        ;# SDRAMC_MR : issue NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2        ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4        ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3        ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0        ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\n\tmww 0xffffea04 0x2b6      ;# SDRAMC_TR : set refresh timer count to 7 us\n\n    ##\n    # NAND Flash Configuration for 1 x Samsung K9F4G08U0M, 512M x 8Bit.\n    ##\n    echo \"Configuring NAND flash\"\n    mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock\n    mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n    mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14\n    mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13\n    mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND\n    mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13\n\n    mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before\n\n    mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE\n    mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals\n    mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle\n    mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n                               #             3 TDF cycles, no optimization\n\n    mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers\n    mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n    nand probe at91sam9260.flash\n\n    ##\n    # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit\n    ##\n    echo \"Setting up dataflash\"\n    mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI),\n                               #            2(SPI0_SPCK), and 11(SPI0_NPCS1)\n    mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2\n    mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11\n    mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock\n\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure\n    mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected\n\n    mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud,\n                               #             250ns delay before SPCK, 250ns b/n tx\n\n    mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1\n    mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0\n}\n\nnand device at91sam9260.flash at91sam9 at91sam9260.cpu 0x40000000 0xffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_stm32_h103.cfg",
    "content": "# Olimex STM32-H103 eval board\n# http://olimex.com/dev/stm32-h103.html\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_stm32_h107.cfg",
    "content": "#\n# Olimex STM32-H107\n#\n# http://olimex.com/dev/stm32-h107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_stm32_h405.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Olimex STM32-H405 eval board\n# https://www.olimex.com/Products/ARM/ST/STM32-H405/\n\n# Work-area size (RAM size) = 128kB for STM32F405RG device\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/olimex_stm32_p107.cfg",
    "content": "#\n# Olimex STM32-P107\n#\n# http://olimex.com/dev/stm32-p107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/omap2420_h4.cfg",
    "content": "# OMAP2420 SDP board (\"H4\")\n\nsource [find target/omap2420.cfg]\n\n# NOTE: this assumes you're *NOT* using a TI-14 connector.\nreset_config trst_and_srst separate\n\n# Board configs can vary a *LOT* ... parts, jumpers, etc.\n# This GP board boots from cs0 using NOR (2x32M), and also\n# has 64M NAND on cs6.\nflash bank h4.u10 cfi 0x04000000 0x02000000 2 2 $_TARGETNAME\nflash bank h4.u11 cfi 0x06000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/openrd.cfg",
    "content": "# Marvell OpenRD\n\nsource [find interface/ftdi/openrd.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc openrd_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x37543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000A33 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000004 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x00120012 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000E40F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc openrd_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\topenrd_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc openrd_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\topenrd_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/or1k_generic.cfg",
    "content": "# If you want to use the VJTAG TAP or the XILINX BSCAN,\n# you must set your FPGA TAP ID here\n\nset FPGATAPID 0x020b30dd\n\n# Choose your TAP core (VJTAG , MOHOR or XILINX_BSCAN)\nif { [info exists TAP_TYPE] == 0} {\n   set TAP_TYPE VJTAG\n}\n\n# Set your chip name\nset CHIPNAME or1200\n\nsource [find target/or1k.cfg]\n\n# Set the servers polling period to 1ms (needed to JSP Server)\npoll_period 1\n\n# Set the adapter speed\nadapter speed 3000\n\n# Enable the target description feature\ngdb_target_description enable\n\n# Add a new register in the cpu register list. This register will be\n# included in the generated target descriptor file.\n# format is addreg [name] [address] [feature] [reg_group]\naddreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n# Override default init_reset\nproc init_reset {mode} {\n\tsoft_reset_halt\n\tresume\n}\n\n# Target initialization\ninit\necho \"Halting processor\"\nhalt\n\nforeach name [target names] {\n\tset y [$name cget -endian]\n\tset z [$name cget -type]\n\tputs [format \"Chip is %s, Endian: %s, type: %s\" \\\n\t      $name $y $z]\n}\n\nset c_blue  \"\\033\\[01;34m\"\nset c_reset \"\\033\\[0m\"\n\nputs [format \"%sTarget ready...%s\" $c_blue $c_reset]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/osk5912.cfg",
    "content": "# http://omap.spectrumdigital.com/osk5912/\n\nsource [find target/omap5912.cfg]\n\n# NOTE: this assumes you're using the ARM 20-pin (\"Multi-ICE\")\n# JTAG connector, and accordingly have J1 connecting pins 1 & 2.\n# The TI-14 pin needs \"trst_only\", and J1 connecting 2 & 3.\nreset_config trst_and_srst separate\n\n# NOTE:  boards with XOMAP parts wire nSRST to nPWRON_RESET.\n# That resets everything -- including JTAG and EmbeddedICE.\n# So they must use \"reset_config srst_pulls_trst\".\n\n# NOTE:  an expansion board could add a trace connector ... if\n# it does, change this appropriately.  And reset_config too,\n# assuming JTAG_DIS reroutes JTAG to that connector.\netm config $_TARGETNAME 8 demultiplexed full dummy\netm_dummy config $_TARGETNAME\n\n# standard boards populate two 16 MB chips, but manufacturing\n# options or an expansion board could change this config.\nflash bank osk.u1 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\nflash bank osk.u2 cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\nproc osk5912_init {} {\n\tomap5912_reset\n\n\t# detect flash\n\tflash probe 0\n\tflash probe 1\n}\n$_TARGETNAME configure -event reset-init { osk5912_init }\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/phone_se_j100i.cfg",
    "content": "#\n# Sony Ericsson J100I Phone\n#\n# more information can be found on\n# http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i\n#\nsource [find target/ti_calypso.cfg]\n\n# external flash\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/phytec_lpc3250.cfg",
    "content": "source [find target/lpc3250.cfg]\n\nadapter srst delay 200\njtag_ntrst_delay 1\nadapter speed 200\nreset_config trst_and_srst separate\n\narm7_9 dcc_downloads enable\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n\n$_TARGETNAME configure -event reset-start {\n             arm7_9 fast_memory_access disable\n             adapter speed 200\n}\n\n$_TARGETNAME configure -event reset-end {\n             adapter speed 6000\n             arm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-init { phytec_lpc3250_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc phytec_lpc3250_init { } {\n        # Set clock dividers\n        #   ARMCLK = 266.5 MHz\n        #   HCLK   = 133.25 MHz\n        #   PERIPHCLK = 13.325 MHz\n        mww 0x400040BC 0\n        mww 0x40004050 0x140\n        mww 0x40004040 0x4D\n        mww 0x40004058 0x16250\n\n        # Init PLLs\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004044 0x106\n        sleep 1 busy\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004048 0x2\n\n        # Init SDRAM with 133 MHz timings\n        mww 0x40028134 0x00FFFFFF\n        mww 0x4002802C 0x00000008\n\n        mww 0x31080000 1\n        mww 0x31080008 0\n        mww 0x40004068 0x1C000\n        mww 0x31080028 0x11\n\n        mww 0x31080400 0\n        mww 0x31080440 0\n        mww 0x31080460 0\n        mww 0x31080480 0\n\n        # Delays\n        mww 0x31080030 1\n        mww 0x31080034 6\n        mww 0x31080038 10\n        mww 0x31080044 1\n        mww 0x31080048 9\n        mww 0x3108004C 12\n        mww 0x31080050 10\n        mww 0x31080054 1\n        mww 0x31080058 1\n        mww 0x3108005C 0\n\n        mww 0x31080100 0x5680\n        mww 0x31080104 0x302\n\n        # Init sequence\n        mww 0x31080020 0x193\n        sleep 1 busy\n        mww 0x31080024 1\n        mww 0x31080020 0x113\n        sleep 1 busy\n        mww 0x31080020 0x013\n        sleep 1 busy\n        mww 0x31080024 65\n        mww 0x31080020 0x093\n        mdw 0x80020000\n        mww 0x31080020 0x013\n\n        # SYS_CTRL remapping\n        mww 0x40004014 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/pic-p32mx.cfg",
    "content": "# The Olimex PIC-P32MX has a PIC32MX\n\nset CPUTAPID 0x40916053\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/pico-debug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# pico-debug is a virtual CMSIS-DAP debug adapter\n# it runs on the very same RP2040 target being debugged without additional hardware\n# https://github.com/majbthrd/pico-debug\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 4000\n\nset CHIPNAME rp2040\nsource [find target/rp2040-core0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n\nsource [find interface/ftdi/pipistrello.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/pipistrello.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx45.bit;\\\n# jtagspi_program bitstream-pistrello.bin 0;\\\n# jtagspi_program bios.bin 0x170000;\\\n# jtagspi_program runtime.fbi 0x180000;\\\n# xc6s_program xc6s.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/propox_mmnet1001.cfg",
    "content": "\n## Chip:\nset CHIPNAME at91sam9260\nset CPUTAPID 0x0792603f\nset ENDIAN little\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n\nproc at91sam_init { } {\n\n\t# at reset chip runs at 32 kHz => 1/8 * 32 kHz = 4 kHz\n\tjtag_rclk 4\n\n\t# Enable user reset and disable watchdog\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\t# Oscillator setup\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator (18.432 MHz)\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 18.432 MHz kHz => 1/8 * 18.432 MHz = 2.304 MHz\n\tjtag_rclk 2000\n\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc2c 0x207c3f0c         ;# CKGR_PLLBR: Set PLLB Register for USB usage (USB_CLK = 48 MHz)\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 198.656 MHz kHz => full speed jtag\n\tjtag_rclk 30000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\t# Configure PIO Controller for SDRAM data-lines D16-D31\n\t# PC16-PC31 = Peripheral A: D16-D32\n\tmww 0xfffff844 0xffff0000\t;# Interrupt Disable\n\tmww 0xfffff854 0xffff0000\t;# Multi-Drive Disable\n\tmww 0xfffff860 0xffff0000\t;# Pull-Up Disable\n\tmww 0xfffff870 0xffff0000\t;# PIO_ASR : Select peripheral A function for D15..D31\n\tmww 0xfffff804 0xffff0000\t;# PIO_PDR : Disable PIO function for D15..D31 (Peripheral function enable)\n\tmww 0xfffffc10 0x00000010\t;# Enable PIO-C Clock in PMC (PID=4)\n\n\t# SD-Ram setup\n\tmww 0xffffef1c 0x2\t\t\t;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\tmww 0xffffea08 0x85227259\t;# SDRAMC_CR : Configure SDRAM (IS42S32160A: 4M Words x 32 Bits x 4 Banks (512-Mbit))\n\tmww 0xffffea00 0x1\t\t\t;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2\t\t\t;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (1st)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (2nd)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (3th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (4th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (5th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (6th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (7th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (8th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3\t\t\t;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0\t\t\t;# SDRAMC_MR : Normal Mode\n\tmww 0x20000000 0\n\tmww 0xFFFFEA04 0x30d\t\t;# SDRAM Refresh Time Register\n\t\t\t\t\t\t\t\t #  datasheet: 8k refresh cycles / 64 ms\n\t\t\t\t\t\t\t\t #  MCLK / (8*1024 / 64e-3) = 100e6 / 128000 = 781 = 0x30d\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/pxa255_sst.cfg",
    "content": "# A PXA255 test board with SST 39LF400A flash\n#\n# At reset the memory map is as follows. Note that\n# the memory map changes later on as the application\n# starts...\n#\n# RAM at 0x4000000\n# Flash at 0x00000000\n#\nsource [find target/pxa255.cfg]\n\n# Target name is set by above\n$_TARGETNAME configure -work-area-phys 0x4000000 -work-area-size 0x4000 -work-area-backup 0\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width> <target> [options]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x80000 2 2 $_TARGETNAME jedec_probe\n\nproc pxa255_sst_init {} {\n\txscale cp15   15      0x00002001  ;#Enable CP0 and CP13 access\n\t#\n\t# setup GPIO\n\t#\n\tmww    0x40E00018  0x00008000  ;#CPSR0\n\tsleep   20\n\tmww    0x40E0001C  0x00000002  ;#GPSR1\n\tsleep   20\n\tmww    0x40E00020  0x00000008  ;#GPSR2\n\tsleep   20\n\tmww    0x40E0000C  0x00008000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00054  0x80000000  ;#GAFR0_L\n\tsleep   20\n\tmww    0x40E00058  0x00188010  ;#GAFR0_H\n\tsleep   20\n\tmww    0x40E0005C  0x60908018  ;#GAFR1_L\n\tsleep   20\n\tmww    0x40E0000C  0x0280E000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00010  0x821C88B2  ;#GPDR1\n\tsleep   20\n\tmww    0x40E00014  0x000F03DB  ;#GPDR2\n\tsleep   20\n\tmww    0x40E00000  0x000F03DB  ;#GPLR0\n\tsleep   20\n\n\n\tmww    0x40F00004  0x00000020  ;#PSSR\n\tsleep   20\n\n\t#\n\t# setup memory controller\n\t#\n\tmww    0x48000008  0x01111998  ;#MSC0\n\tsleep   20\n\tmww    0x48000010  0x00047ff0  ;#MSC2\n\tsleep   20\n\tmww    0x48000014  0x00000000  ;#MECR\n\tsleep   20\n\tmww    0x48000028  0x00010504  ;#MCMEM0\n\tsleep   20\n\tmww    0x4800002C  0x00010504  ;#MCMEM1\n\tsleep   20\n\tmww    0x48000030  0x00010504  ;#MCATT0\n\tsleep   20\n\tmww    0x48000034  0x00010504  ;#MCATT1\n\tsleep   20\n\tmww    0x48000038  0x00004715  ;#MCIO0\n\tsleep   20\n\tmww    0x4800003C  0x00004715  ;#MCIO1\n\tsleep   20\n\t#\n\tmww    0x48000004  0x03CA4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x004B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000BC018  ;#MDREF\n\tsleep   20\n\tmww    0x48000000  0x00001AC8  ;#MDCNFG\n\tsleep   20\n\n\tsleep   20\n\n\tmww    0x48000000  0x00001AC9  ;#MDCNFG\n\tsleep   20\n\tmww    0x48000040  0x00000000  ;#MDMRS\n\tsleep   20\n}\n\n$_TARGETNAME configure -event reset-init {pxa255_sst_init}\n\nreset_config trst_and_srst\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n#xscale debug_handler 0  0xFFFF0800      ;# debug handler base address\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/quark_d2000_refboard.cfg",
    "content": "# Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582)\n\n# the board has an onboard FTDI FT232H chip\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\n\nftdi layout_init 0x0000 0x030b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0100\n\nsource [find target/quark_d20xx.cfg]\n\nadapter speed 1000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/quark_x10xx_board.cfg",
    "content": "# There are many Quark boards that can host the quark_x10xx SoC\n# Galileo is an example board\n\nsource [find target/quark_x10xx.cfg]\n\n#default frequency but this can be adjusted at runtime\nadapter speed 4000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/quicklogic_quickfeather.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3 QuickFeather\n# https://www.quicklogic.com/products/eos-s3/quickfeather-development-kit/\n\nsource [find target/eos_s3.cfg]\n\nreset_config srst_only\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Radiona ULX3S\n# https://radiona.org/ulx3s/\n# Currently there are following board variants:\n# CS-ULX3S-01 - LFE5U 12F\n# CS-ULX3S-02 - LFE5U 45F\n# CS-ULX3S-03 - LFE5U 85F\n#\n# two JTAG interfaces:\n# - US1, micro USB port connected to FT231XQ\n#   This interface should be used with following config:\n#        interface/ft232r/radiona_ulx3s.cfg\n# - J4, 6 pin connector\n#\n# Both of this interfaces share the JTAG lines (TDI, TMS, TCK, TDO) between\n# Lattice ECP5 FPGA chip and ESP32 WiFi controller.\n# Note: TRST_N of the ESP32 is pulled up by default and can be pulled down over\n# J3 interface.\n# See schematics for more information:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v308.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v314.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v315.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nsource [find interface/ft232r/radiona_ulx3s.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/redbee.cfg",
    "content": "source [find target/mc13224v.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/reflexces_achilles_i-dev_kit_arria10.cfg",
    "content": "# Achilles Instant-Development Kit Arria 10 SoC SoM\n# https://www.reflexces.com/products-solutions/achilles-instant-development-kit-arria-10-soc-som\n#\n\nif { [info exists USE_EXTERNAL_DEBUGGER] } {\n\techo \"Using external debugger\"\n} else {\n\tsource [find interface/altera-usb-blaster2.cfg]\n\tusb_blaster device_desc \"Arria10 IDK\"\n}\n\nsource [find fpga/altera-10m50.cfg]\nsource [find target/altera_fpgasoc_arria10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_dk-s7g2.cfg",
    "content": "#\n# Renesas Synergy DK-S7G2\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# XXX 19-pin SWD+TRACE connector also available\n\n# Synergy R7FS7G27H2A01CBD\nsource [find target/renesas_s7g2.cfg]\n\n# 32 MB QSPI flash (Micron N25Q256A13EF840E)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_falcon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Renesas R-Car V3U Falcon Board Config\n\n# The Falcon board comes with either an V3U SOC.\n\necho \"\\nFalcon:\"\nif { ![info exists SOC] } {\n\tset SOC V3U\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_gr_peach.cfg",
    "content": "# Renesas RZ/A1H GR-Peach board\n\nreset_config srst_only\n\nsource [find target/renesas_r7s72100.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_porter.cfg",
    "content": "# Renesas R-Car M2 Evaluation Board\n\nset SOC M2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_salvator-xs.cfg",
    "content": "# Renesas R-Car Gen3 Salvator-X(S) Board Config\n\n# The Salvator-X(S) boards come with either an H3, M3W, or M3N SOC.\n\necho \"\\nSalvator-X(S):\"\nif { ![info exists SOC] } {\n\tset SOC H3\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_silk.cfg",
    "content": "# Renesas R-Car E2 Evaluation Board\n\nset SOC E2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/renesas_stout.cfg",
    "content": "# Renesas R-Car H2 Evaluation Board\n\nset SOC H2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/rigado_bmd300_ek.cfg",
    "content": "#\n# Rigado BMD-300 Evaluation Kit\n#\n# https://www.rigado.com/products/modules/bmd-300/\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/rpi3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 3 board with BCM2837 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2837.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/rpi4b.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 4 model B board with BCM2711 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2711.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/rsc-w910.cfg",
    "content": "# Avalue RSC-W8910 sbc\n# http://www.avalue.com.tw/products/RSC-W910.cfm\n# 2MB NOR Flash\n# 64MB SDRAM\n# 128MB NAND Flash\n\n# Based on Nuvoton nuc910\nsource [find target/nuc910.cfg]\n\n#\n# reset only behaves correctly if we use srst_pulls_trst\n#\nreset_config trst_and_srst srst_pulls_trst\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME nuc910 $_TARGETNAME\n\n#\n# Target events\n#\n\n$_TARGETNAME configure -event reset-start {adapter speed 1000}\n\n$_TARGETNAME configure -event reset-init {\n\t# switch on PLL for 200MHz operation\n\t# running from 15MHz input clock\n\n\tmww 0xB0000200 0x00000030 ;# CLKEN\n\tmww 0xB0000204 0x00000f3c ;# CLKSEL\n\tmww 0xB0000208 0x05007000 ;# CLKDIV\n\tmww 0xB000020C 0x00004f24 ;# PLLCON0\n\tmww 0xB0000210 0x00002b63 ;# PLLCON1\n\tmww 0xB000000C 0x08817fa6 ;# MFSEL\n\tsleep 10\n\n\t# we are now running @ 200MHz\n\t# enable all openocd speed tweaks\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\tadapter speed 15000\n\n\t# map nor flash to 0x20000000\n\t# map sdram to 0x00000000\n\n\tmww 0xb0001000 0x000530c1 ;# EBICON\n\tmww 0xb0001004 0x40030084 ;# ROMCON\n\tmww 0xb0001008 0x000010ee ;# SDCONF0\n\tmww 0xb000100C 0x00000000 ;# SDCONF1\n\tmww 0xb0001010 0x0000015b ;# SDTIME0\n\tmww 0xb0001014 0x0000015b ;# SDTIME1\n\tmww 0xb0001018 0x00000000 ;# EXT0CON\n\tmww 0xb000101C 0x00000000 ;# EXT1CON\n\tmww 0xb0001020 0x00000000 ;# EXT2CON\n\tmww 0xb0001024 0x00000000 ;# EXT3CON\n\tmww 0xb000102c 0x00ff0048 ;# CKSKEW\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sayma_amc.cfg",
    "content": "# Sayma AMC is an FPGA board for the µTCA AMC format\n# The board is open hardware (CERN OHL) and the gateware and software\n# running on it are open source (ARTIQ, LGPLv3+).\n#\n# https://github.com/m-labs/sinara/wiki/Sayma\n#\n# It contains a Xilinx Kintex Ultrascale 040 FPGA (xcku040).\n# There is a SCANSTA112SM JTAG router on the board which is configured to\n# automatically add devices to the JTAG svcan chain when they are added.\n# Sayma AMC is usually combined with Sayma RTM (rear transition module)\n# which features an Artix 7 FPGA.\n\nadapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n# Use this to distinguish multiple boards by topology\n#adapter usb location 5:1\n# sampling on falling edge generally seems to work and accelerates things but\n# is not fully tested\n#ftdi tdo_sample_edge falling\n# EN_USB_JTAG on ADBUS7: out, high\n# USB_nTRST on ADBUS4: out, high, but R46 is DNP\nftdi layout_init 0x0098 0x008b\n#ftdi layout_signal EN_USB -data 0x0080\n#ftdi layout_signal nTRST -data 0x0010\nreset_config none\n\nadapter speed 5000\n\ntransport select jtag\n\n# Add the RTM Artix to the chain. Note that this changes the PLD numbering.\n# Unfortunately openocd TAPs can't be disabled after they have been added and\n# before `init`.\n#source [find cpld/xilinx-xc7.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nset XILINX_USER1 0x02\nset XILINX_USER2 0x03\nset JTAGSPI_IR $XILINX_USER1\nsource [find cpld/jtagspi.cfg]\nflash bank xcu.spi1 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER2\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sheevaplug.cfg",
    "content": "# Marvell SheevaPlug\n\nsource [find interface/ftdi/sheevaplug.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc sheevaplug_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x39543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000833 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000042 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x003C0000 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000F80F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc sheevaplug_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_reflash_uboot_env { } {\n\n\t# reflash the u-Boot environment variables area\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0xa0000 0x40000\n\tnand write 0 uboot-env.bin 0xa0000 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\tsheevaplug_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sifive-e31arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e31arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sifive-e51arty.cfg",
    "content": "#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e51arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sifive-hifive1-revb.cfg",
    "content": "adapter speed 4000\n\nadapter driver jlink\ntransport select jtag\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 0\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME.0\n\ninit\n\njlink jtag 3\n\nhalt\nflash protect 0 1 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/sifive-hifive1.cfg",
    "content": "adapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nSRST -oe 0x0020 -data 0x0020\n\n#Reset Stretcher logic on FE310 is ~1 second long\n#This doesn't apply if you use\n# ftdi set_signal, but still good to document\n#adapter srst delay 1500\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME\ninit\n#reset -- This type of reset is not implemented yet\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n  #Wait for the reset stretcher\n  #It will work without this, but\n  #will incur lots of delays for later commands.\n  sleep 1500\n}\nhalt\nflash protect 0 64 last off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/smdk6410.cfg",
    "content": "# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x00100000 2 2 $_TARGETNAME jedec_probe\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/snps_em_sk.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.x\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# 5MHz seems to work good with all cores that might happen in 2.x\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/snps_em_sk_v1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v1.0 and v1.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\nadapter speed 10000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/snps_em_sk_v2.1.cfg",
    "content": "#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency\n# 20MHz. 7.5 MHz seems to work fine.\nadapter speed 7500\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/snps_em_sk_v2.2.cfg",
    "content": "#  Copyright (C) 2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.2\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# EM11D reportedly requires 5 MHz. Other cores and board can work faster.\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys DesignWare ARC HSDK Software Development Platform (HS38 cores)\n#\n\nsource [find interface/ftdi/snps_sdp.cfg]\nadapter speed 10000\n\n# ARCs supports only JTAG.\ntransport select jtag\n\n# Configure SoC\nsource [find target/snps_hsdk.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spansion_sk-fm4-176l-s6e2cc.cfg",
    "content": "#\n# Spansion SK-FM4-176L-S6E2CC\n#\n\n#\n# FM3 MB9AF312K\n#\nsource [find interface/cmsis-dap.cfg]\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\n#\n# FM4 S6E2CCAJ0A w/ 192 KB SRAM0\n#\nset CHIPNAME s6e2cc\nset CHIPSERIES S6E2CCAJ0A\nset WORKAREASIZE 0x30000\nsource [find target/fm4_s6e2cc.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spansion_sk-fm4-u120-9b560.cfg",
    "content": "#\n# Spansion SK-FM4-U120-9B560\n#\n\n#\n# FM3 MB9AF312K\n#\n# source [find interface/cmsis-dap.cfg]\n\n#\n# FM4 MB9BF568R w/ 64 KB SRAM0\n#\nset CHIPNAME mb9bf568\nset CHIPSERIES MB9BF568R\nset WORKAREASIZE 0x10000\nsource [find target/fm4_mb9bf.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear300evb.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0\n# http://www.st.com/spear\n#\n# Date:      2010-11-27\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear300evb_init }\n\nproc spear300evb_init {} {\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp300_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear300evb_mod.cfg",
    "content": "# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the top layer:\n#    1. replace reset chip U4 with a STM6315SDW13F;\n# - Modifications on the bottom layer:\n#    2. add 0 ohm resistor R10. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 and solder it between R10 and R54:\n# - one pad soldered with the pad of R54 connected to 3.3V (this\n#   is the pad of R54 far from JTAG connector J4)\n# - the other pad soldered with the nearest pad of R10.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear300evb.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear310evb20.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n#\n# Check ST Application Note AN3321 on how to fix SRST on\n# the board, then use the script board/spear310evb20_mod.cfg\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n# CFI parallel NOR on EMI CS0. 2x 16bit 8M devices = 16Mbyte.\nset _FLASHNAME0 $_CHIPNAME.pnor\nflash bank $_FLASHNAME0 cfi 0x50000000 0x01000000 2 4 $_TARGETNAME\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear310evb20_init }\n\nproc spear310evb20_init {} {\n\treg pc 0xffff0020\t;# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp310_init\n\tsp310_emi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear310evb20_mod.cfg",
    "content": "# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note AN3321.\n# - Modifications on the top layer:\n#    1. remove R137 and C57, located near the SMII PHY U18;\n#    2. remove R172 and C75, located near the SMII PHY U19;\n#    3. remove R207 and C90, located near the SMII PHY U20;\n#    4. remove C236, located near the SMII PHY U21;\n#    5. remove U12, located near the JTAG connector;\n#    6. solder together pins 7, 8 and 9 of U12;\n#    7. solder together pins 11, 12, 13, 14, 15, 16, 17 and 18 of U12.\n# - Modifications on the bottom layer:\n#    8. replace reset chip U11 with a STM6315SDW13F;\n#    9. add 0 ohm resistor R329. It is located close to JTAG connector.\n#\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear310evb20.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear320cpu.cfg",
    "content": "# Configuration for the ST SPEAr320 CPU board\n# EVAL_SPEAr320CPU Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear320cpu_init }\n\nif { [info exists DDR_CHIPS] } {\n        set _DDR_CHIPS $DDR_CHIPS\n} else {\n        set _DDR_CHIPS 1\n}\n\nproc spear320cpu_init {} {\n\tglobal _DDR_CHIPS\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\" $_DDR_CHIPS\n\tsp320_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/spear320cpu_mod.cfg",
    "content": "# Configuration for the ST SPEAr320 Evaluation board\n# EVAL_SPEAr320CPU Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the bottom layer:\n#    1. replace reset chip U7 with a STM6315SDW13F;\n#    2. add 0 ohm resistor R45. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 or 0402 and solder it between R15 and R45:\n# - one pad soldered with the pad of R15 connected to 3.3V (this\n#   is the pad of R15 closer to R45)\n# - the other pad soldered with the nearest pad of R45.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear320cpu.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_b-l475e-iot01a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an B-L475E-IOT01A Discovery kit for IoT node with a single STM32L475VGT6 chip.\n# http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000\t;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_8l152r8.cfg",
    "content": "# This is a ST NUCLEO 8L152R8 board with a single STM8L152R8T6 chip.\n# http://www.st.com/en/evaluation-tools/nucleo-8l152r8.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\nsource [find target/stm8l152.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_8s208rb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a ST NUCLEO 8S208RB board with a single STM8S208RBT6 chip.\n# https://www.st.com/en/evaluation-tools/nucleo-8s208rb.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\n# 128 KiB flash and 2 KiB EEPROM\nset FLASHEND 0x27fff\nset EEPROMEND 0x47ff\n\nsource [find target/stm8s.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_f0.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F0. Known boards at the moment:\n# STM32F030R8\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# NUCLEO-F072RB\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# STM32F091RC\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260944\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_f103rb.cfg",
    "content": "# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_f3.cfg",
    "content": "# This is an ST NUCLEO F334R8 board with a single STM32F334R8T6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260004\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_f4.cfg",
    "content": "# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:\n# STM32F401RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000\n# STM32F411RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_f7.cfg",
    "content": "# STMicroelectronics STM32F7 Nucleo development board\n# Known boards: NUCLEO-F746ZG and NUCLEO-F767ZI\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_g0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G0. Known boards at the moment:\n# NUCLEO-G031K8\n# https://www.st.com/en/evaluation-tools/nucleo-g031k8.html\n# NUCLEO-G070RB\n# https://www.st.com/en/evaluation-tools/nucleo-g070rb.html\n# NUCLEO-G071RB\n# https://www.st.com/en/evaluation-tools/nucleo-g071rb.html\n# NUCLEO-G0B1RE\n# https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_g4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G4. Known boards at the moment:\n# NUCLEO-G431KB\n# https://www.st.com/en/evaluation-tools/nucleo-g431kb.html\n# NUCLEO-G431RB\n# https://www.st.com/en/evaluation-tools/nucleo-g431rb.html\n# NUCLEO-G474RE\n# https://www.st.com/en/evaluation-tools/nucleo-g474re.html\n# NUCLEO-G491RE\n# https://www.st.com/en/evaluation-tools/nucleo-g491re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_h743zi.cfg",
    "content": "# This is an ST NUCLEO-H743ZI board with single STM32H743ZI chip.\n# http://www.st.com/en/evaluation-tools/nucleo-h743zi.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_h745zi.cfg",
    "content": "# This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip.\n\nsource [find interface/stlink-dap.cfg]\ntransport select dapdirect_swd\n\n# STM32H745xx devices are dual core (Cortex-M7 and Cortex-M4)\nset DUAL_CORE 1\n\n# enable CTI for cross halting both cores\nset USE_CTI 1\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_l073rz.cfg",
    "content": "# This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip.\n# http://www.st.com/en/evaluation-tools/nucleo-l073rz.html\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32l0_dual_bank.cfg]\n\n# There is only system reset line and JTAG/SWD command can be issued when SRST\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_l1.cfg",
    "content": "# This is an ST NUCLEO L152RE board with a single STM32L152RET6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l1x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_l4.cfg",
    "content": "# Should work with all STM32L4 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_l5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for STM32L5 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32l5x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/st_nucleo_wb55.cfg",
    "content": "#\n# Configuration for STM32WB55 Nucleo board (STM32WB55RGV6)\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32wbx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/steval-idb007v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-1 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb008v1.html\nset CHIPNAME bluenrg-1\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/steval-idb008v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-2 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb007v1.html\nset CHIPNAME bluenrg-2\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/steval-idb011v1.cfg",
    "content": "# This is an evaluation board with a single BlueNRG-LP chip.\nset CHIPNAME bluenrg-lp\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/steval-idb012v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later.\n# This is an evaluation board with a single BlueNRG-LPS chip.\nset CHIPNAME bluenrg-lps\nsource [find interface/cmsis-dap.cfg]\nsource [find target/bluenrg-x.cfg]"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/steval_pcc010.cfg",
    "content": "# Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram\n# coming with the STEVAL-PCC010 board\n# http://www.st.com/internet/evalboard/product/251530.jsp\n# or any other board with only a STM32F2x in the JTAG chain\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm320518_eval.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm320518_eval_stlink.cfg",
    "content": "# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32100b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F100VBT6 chip.\n# http://www.st.com/internet/evalboard/product/247099.jsp\n\n# The chip has only 8KB sram\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3210b_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F10x (128KB) chip.\n# http://www.st.com/internet/evalboard/product/176090.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3210c_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F107VCT chip.\n# http://www.st.com/internet/evalboard/product/217965.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3210e_eval.cfg",
    "content": "# This is an STM32 eval board with a single STM32F103ZET6 chip.\n# http://www.st.com/internet/evalboard/product/204176.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n\n#\n# configure FSMC Bank 1 (NOR/PSRAM Bank 2) NOR flash\n# M29W128GL70ZA6E\n#\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME\n\nproc stm32_enable_fsmc {} {\n\n\techo \"Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)\"\n\n\t# enable gpio (defg) clocks for fsmc\n\t# RCC_APB2ENR\n\tmww 0x40021018 0x000001E0\n\n\t# enable fsmc clock\n\t# RCC_AHBENR\n\tmww 0x40021014 0x00000114\n\n\t# configure gpio to alternate function\n\t# GPIOD_CRL\n\tmww 0x40011400 0x44BB44BB\n\t# GPIOD_CRH\n\tmww 0x40011404 0xBBBBBBBB\n\n\t# GPIOE_CRL\n\tmww 0x40011800 0xBBBBB444\n\t# GPIOE_CRH\n\tmww 0x40011804 0xBBBBBBBB\n\n\t# GPIOF_CRL\n\tmww 0x40011C00 0x44BBBBBB\n\t# GPIOF_CRH\n\tmww 0x40011C04 0xBBBB4444\n\n\t# GPIOG_CRL\n\tmww 0x40012000 0x44BBBBBB\n\t# GPIOG_CRH\n\tmww 0x40012004 0x444444B4\n\n\t# setup fsmc timings\n\t# FSMC_BCR1\n\tmww 0xA0000008 0x00001058\n\n\t# FSMC_BTR1\n\tmww 0xA000000C 0x10000502\n\n\t# FSMC_BCR1 - enable fsmc\n\tmww 0xA0000008 0x00001059\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32_enable_fsmc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3220g_eval.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3220g_eval_stlink.cfg",
    "content": "# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3241g_eval.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm3241g_eval_stlink.cfg",
    "content": "# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32429i_eval.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32429i_eval_stlink.cfg",
    "content": "# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32439i_eval.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32439i_eval_stlink.cfg",
    "content": "# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm327x6g_eval.cfg",
    "content": "# STM327[4|5]6G-EVAL: This is for the STM32F7 eval boards.\n# STM32746G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261639\n# STM32756G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f0discovery.cfg",
    "content": "# This is an STM32F0 discovery board with a single STM32F051R8T6 chip.\n# http://www.st.com/internet/evalboard/product/253215.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f103c8_blue_pill.cfg",
    "content": "# STM32F103C8 \"Blue Pill\"\n\n# NOTE:\n# There is a fair bit of confusion about whether the \"Blue Pill\" has 128kB or 64kB flash size.\n# The most likely cause is that there exist a -C8 and a -CB variant of the STM32F103, where\n# the C8 has 64kB, the CB has 128kB as per specification. \"Blue Pill\" boards are manufactured\n# by a lot of different vendors, some may actually use the CB variant but from a cursory look\n# it very hard to tell them apart (\"C8\" and \"CB\" look very similar). Nevertheless, people have\n# tried using the full 128kB of flash on the C8 and found it to be working. Hence this board file\n# overrides the internal size detection. Be aware though that you may be using you particular\n# board outside of its specification. If in doubt, comment the following line.\nset FLASH_SIZE 0x20000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f334discovery.cfg",
    "content": "# This is an STM32F334 discovery board with a single STM32F334C8T6 chip.\n# As it is one of the few boards with stlink V.2-1, we source the corresponding\n# nucleo file.\n# http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260318\n\nsource [find board/st_nucleo_f3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f3discovery.cfg",
    "content": "# This is an STM32F3 discovery board with a single STM32F303VCT6 chip.\n# http://www.st.com/internet/evalboard/product/254044.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f412g-disco.cfg",
    "content": "# This is an STM32F412G discovery board with a single STM32F412ZGT6 chip.\n# http://www.st.com/en/evaluation-tools/32f412gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PG06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x000AA000 0x00055000\t;# MODER\n\tmmw 0x40021408 0x000FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f413h-disco.cfg",
    "content": "# This is an STM32F413H discovery board with a single STM32F413ZHT6 chip.\n# http://www.st.com/en/evaluation-tools/32f413hdiscovery.html\n\n#\n# Untested!!!\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PD13: BK1_IO3, PE02: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PF09:AF10:V, PF08:AF10:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V\n\tmmw 0x40021400 0x000A0000 0x00050000\t;# MODER\n\tmmw 0x40021408 0x000F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f429disc1.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f429discovery.cfg",
    "content": "#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f469discovery.cfg",
    "content": "#\n# This is an STM32F469 discovery board with a single STM32F469NI chip.\n# http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f469i-disco.cfg",
    "content": "# This is an STM32F469I discovery board with a single STM32F469NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f469idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PF10: CLK, PB06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB06:AF10:V, PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\n\t# Port B: PB06:AF10:V\n\tmmw 0x40020400 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40020408 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000000 0x05000000\t;# AFRL\n\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x002AA000 0x00155000\t;# MODER\n\tmmw 0x40021408 0x003FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000009AA 0x00000655\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000005\t\t\t\t;# 5 WS for 160 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24002808\t\t\t\t;# 160 MHz: HSI, PLLM=8, PLLN=160, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f4discovery.cfg",
    "content": "# This is an STM32F4 discovery board with a single STM32F407VGT6 chip.\n# http://www.st.com/internet/evalboard/product/252419.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 64KB\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f723e-disco.cfg",
    "content": "# This is an STM32F723E discovery board with a single STM32F723IEK6 chip.\n# http://www.st.com/en/evaluation-tools/32f723ediscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f746g-disco.cfg",
    "content": "# This is an STM32F746G discovery board with a single STM32F746NGH6 chip.\n# http://www.st.com/en/evaluation-tools/32f746gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PD12: BK1_IO1, PD11: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V\n\tmmw 0x40020C00 0x0A800000 0x05400000\t;# MODER\n\tmmw 0x40020C08 0x0FC00000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00999000 0x00666000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f769i-disco.cfg",
    "content": "# This is an STM32F769I discovery board with a single STM32F769NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f769idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# exit qpi mode\n\tmww 0xA0001014 0x000033f5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\n\t# 1-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\n\t# 4-line qpi mode\n\tmww 0xA0001014 0x00003135\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=EQIO\n\n\t# 4-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0F283FEC\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0xA, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=4READ4B\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32f7discovery.cfg",
    "content": "# This is an STM32F7 discovery board with a single STM32F756NGH6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641\n\n# This is for using the onboard STLINK/V2-1\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h735g-disco.cfg",
    "content": "# This is a stm32h735g-dk with a single STM32H735IGK6 chip.\n# https://www.st.com/en/evaluation-tools/stm32h735g-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h735igk6\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000006FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PF10: OCSPI1_CLK, PB02: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PD05: OCSPI1_IO5,\n\t# PD04: OCSPI1_IO4, PD13: OCSPI1_IO3, PE02: OCSPI1_IO2, PD12: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF10:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V\n\t# PD04:AF10:V, PE02:AF09:V, PF10:AF09:V, PG09:AF09:V, PG06:AF10:V\n\t# Port B: PB02:AF10:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000A00 0x00000500\t;# AFRL\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x58020C00 0x0A808A00 0x05404500\t;# MODER\n\tmmw 0x58020C08 0x0FC0CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x0FC0CF00\t;# PUPDR\n\tmmw 0x58020C20 0xA0AA0000 0x50550000\t;# AFRL\n\tmmw 0x58020C24 0x00999000 0x00666000\t;# AFRH\n\t# Port E: PE02:AF09:V\n\tmmw 0x58021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802100C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58021020 0x00000900 0x00000600\t;# AFRL\n\t# Port F: PF10:AF09:V\n\tmmw 0x58021400 0x00200000 0x00100000\t;# MODER\n\tmmw 0x58021408 0x00300000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x00300000\t;# PUPDR\n\tmmw 0x58021424 0x00000900 0x00000600\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h745i-disco.cfg",
    "content": "# This is a stm32h745i-disco with a single STM32H745XIH6 chip.\n# www.st.com/en/product/stm32h745i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h745xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h747i-disco.cfg",
    "content": "# This is a stm32h747i-disco with a single STM32H747XIH6 chip.\n# www.st.com/en/product/stm32h747i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h747xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PB02:AF09:V, PD11:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h750b-disco.cfg",
    "content": "# This is a stm32h750b-dk with a single STM32H750XBH6 chip.\n# www.st.com/en/product/stm32h750b-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h750xbh6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h7b3i-disco.cfg",
    "content": "# This is a stm32h7b3i-dk with a single STM32H7B3LIH6Q chip.\n# https://www.st.com/en/evaluation-tools/stm32h7b3i-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h7b3lih6q\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PB02: OCSPI1_CLK, PC05: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PH03: OCSPI1_IO5,\n\t# PC01: OCSPI1_IO4, PF06: OCSPI1_IO3, PF07: OCSPI1_IO2, PF09: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF09:V, PC05:AF10:V, PC01:AF10:V, PD11:AF09:V, PD07:AF10:V, PF09:AF10:V\n\t# PF07:AF10:V, PF06:AF10:V, PG09:AF09:V, PG06:AF10:V, PH03:AF09:V\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port C: PC05:AF10:V, PC01:AF10:V\n\tmmw 0x58020800 0x00000808 0x00000404\t;# MODER\n\tmmw 0x58020808 0x00000C0C 0x00000000\t;# OSPEEDR\n\tmmw 0x5802080C 0x00000000 0x00000C0C\t;# PUPDR\n\tmmw 0x58020820 0x00A000A0 0x00500050\t;# AFRL\n\t# Port D: PD11:AF09:V, PD07:AF10:V\n\tmmw 0x58020C00 0x00808000 0x00404000\t;# MODER\n\tmmw 0x58020C08 0x00C0C000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x00C0C000\t;# PUPDR\n\tmmw 0x58020C20 0xA0000000 0x50000000\t;# AFRL\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF10:V, PF06:AF10:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x000CF000\t;# PUPDR\n\tmmw 0x58021420 0xAA000000 0x55000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\t# Port H: PH03:AF09:V\n\tmmw 0x58021C00 0x00000080 0x00000040\t;# MODER\n\tmmw 0x58021C08 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C0C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x58021C20 0x00009000 0x00006000\t;# AFRL\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h7x3i_eval.cfg",
    "content": "# STM32H7[4|5]3I-EVAL: this is for the H7 eval boards.\n# This is an ST EVAL-H743XI board with single STM32H743XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h743i-eval.html\n# This is an ST EVAL-H753XI board with single STM32H753XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h753i-eval.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32h7x_dual_qspi.cfg",
    "content": "# stm32h754i-disco and stm32h750b-dk dual quad qspi.\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PF10: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PD11:AF09:V, PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0028A000 0x00145000\t;# MODER\n\tmmw 0x58021408 0x003CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000009A0 0x00000650\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l0discovery.cfg",
    "content": "# This is an STM32L053 discovery board with a single STM32L053 chip.\n# http://www.st.com/web/en/catalog/tools/PF260319\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32l0.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l476g-disco.cfg",
    "content": "# This is an STM32L476G discovery board with a single STM32L476VGT6 chip.\n# http://www.st.com/en/evaluation-tools/32l476gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000    ;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000    ;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l496g-disco.cfg",
    "content": "# This is an STM32L496G discovery board with a single STM32L496AGI6 chip.\n# http://www.st.com/en/evaluation-tools/32l496gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB11: BK1_NCS, PA03: CLK, PA06: BK1_IO3, PA07: BK1_IO2, PB00: BK1_IO1, PB01: BK1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PA03:AF10:V, PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V, PA03:AF10:V\n\tmmw 0x48000000 0x0000A080 0x00005040    ;# MODER\n\tmmw 0x48000008 0x0000F0C0 0x00000000    ;# OSPEEDR\n\tmmw 0x48000020 0xAA00A000 0x55005000    ;# AFRL\n\n\t# Port B: PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\tmmw 0x48000400 0x0080000A 0x00400005    ;# MODER\n\tmmw 0x48000408 0x00C0000F 0x00000000    ;# OSPEEDR\n\tmmw 0x48000420 0x000000AA 0x00000055    ;# AFRL\n\tmmw 0x48000424 0x0000A000 0x00005000    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l4discovery.cfg",
    "content": "# Explicitly for the STM32L476 discovery board:\n# http://www.st.com/web/en/catalog/tools/PF261635\n# but perfectly functional for any other STM32L4 board connected via\n# an stlink-v2-1 interface.\n# This is for STM32L4 boards that are connected via stlink-v2-1.\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l4p5g-disco.cfg",
    "content": "# This is a STM32L4P5G discovery board with a single STM32L4R9AGI6 chip.\n# http://www.st.com/en/evaluation-tools/stm32l4p5g-dk.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x07050333\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI2\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PE11: P1_NCS, PE10: P1_CLK, PG06: P1_DQS, PD07: P1_IO7, PC03: P1_IO6, PD05: P1_IO5\n\t# PD04: P1_IO4, PA06: P1_IO3, PA07: P1_IO2, PE13: P1_IO1, PE11: P1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PC03:AF10:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\t# PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V, PG06:AF03:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V\n\tmmw 0x48000000 0x0000A000 0x00005000\t;# MODER\n\tmmw 0x48000008 0x0000F000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800000C 0x00000000 0x0000F000\t;# PUPDR\n\tmmw 0x48000020 0xAA000000 0x55000000\t;# AFRL\n\t# Port C: PC03:AF10:V\n\tmmw 0x48000800 0x00000080 0x00000040\t;# MODER\n\tmmw 0x48000808 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x4800080C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x48000820 0x0000A000 0x00005000\t;# AFRL\n\t# Port D: PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x48000C00 0x00008A00 0x00004500\t;# MODER\n\tmmw 0x48000C08 0x0000CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x48000C0C 0x00000000 0x0000CF00\t;# PUPDR\n\tmmw 0x48000C20 0xA0AA0000 0x50550000\t;# AFRL\n\t# Port E: PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0x0AA00000 0x05500000\t;# MODER\n\tmmw 0x48001008 0x0FF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800100C 0x00000000 0x0FF00000\t;# PUPDR\n\tmmw 0x48001024 0x00AAAA00 0x00555500\t;# AFRH\n\t# Port G: PG06:AF03:V\n\tmmw 0x48001800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x48001808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x00003000\t;# PUPDR\n\tmmw 0x48001820 0x03000000 0x0C000000\t;# AFRL\n\n\t# PG12: P2_NCS, PF04: P2_CLK, PF12: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PG01: P2_IO5\n\t# PG00: P2_IO4, PF03: P2_IO3, PF02: P2_IO2, PF01: P2_IO1, PF00: P2_IO0\n\n\t# PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\t# PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\n\t# Port F: PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\tmmw 0x48001400 0x020002AA 0x01000155\t;# MODER\n\tmmw 0x48001408 0x030003FF 0x00000000\t;# OSPEEDR\n\tmmw 0x4800140C 0x00000000 0x030003FF\t;# PUPDR\n\tmmw 0x48001420 0x00055555 0x000AAAAA\t;# AFRL\n\tmmw 0x48001424 0x00050000 0x000A0000\t;# AFRH\n\t# Port G: PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\tmmw 0x48001800 0x0228000A 0x01140005\t;# MODER\n\tmmw 0x48001808 0x033C000F 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x033C000F\t;# PUPDR\n\tmmw 0x48001820 0x00000055 0x000000AA\t;# AFRL\n\tmmw 0x48001824 0x00050550 0x000A0AA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 24000\n\n\toctospi_init 1\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32l4r9i-disco.cfg",
    "content": "# This is a STM32L4R9I discovery board with a single STM32L4R9AII6 chip.\n# http://www.st.com/en/evaluation-tools/32l4r9idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x00000000\t\t\t\t;# OCTOSPIM_P1CR: disable Port 1\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PG12: P2_NCS, PI06: P2_CLK, PG15: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PH10: P2_IO5,\n\t# PH09: P2_IO4, PH08: P2_IO3, PI09: P2_IO2, PI10: P2_IO1, PI11: P2_IO0\n\n\t# PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PH10:AF05:V, PH09:AF05:V\n\t# PH08:AF05:V, PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\n\t# Port G: PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V\n\tmmw 0x48001800 0x82280000 0x41140000\t;# MODER\n\tmmw 0x48001808 0xC33C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001824 0x50050550 0xA00A0AA0\t;# AFRH\n\n\t# Port H: PH10:AF05:V, PH09:AF05:V, PH08:AF05:V\n\tmmw 0x48001C00 0x002A0000 0x00150000\t;# MODER\n\tmmw 0x48001C08 0x003F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001C24 0x00000555 0x00000AAA\t;# AFRH\n\n\t# Port I: PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\tmmw 0x48002000 0x00A82000 0x00541000\t;# MODER\n\tmmw 0x48002008 0x00FC3000 0x00000000\t;# OSPEEDR\n\tmmw 0x48002020 0x05000000 0x0A000000\t;# AFRL\n\tmmw 0x48002024 0x00005550 0x0000AAA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\toctospi_init 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32ldiscovery.cfg",
    "content": "# This is an STM32L discovery board with a single STM32L152RBT6 chip.\n# http://www.st.com/internet/evalboard/product/250990.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x4000\nsource [find target/stm32l1.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32mp13x_dk.cfg",
    "content": "# board MB1635x\n# http://www.st.com/en/evaluation-tools/stm32mp135f-dk.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp13x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32mp15x_dk2.cfg",
    "content": "# board MB1272B\n# http://www.st.com/en/evaluation-tools/stm32mp157a-dk1.html\n# http://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp15x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/stm32vldiscovery.cfg",
    "content": "# This is an STM32VL discovery board with a single STM32F100RB chip.\n# http://www.st.com/internet/evalboard/product/250863.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/str910-eval.cfg",
    "content": "# str910-eval eval board\n#\n# Need reset scripts\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs    -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/telo.cfg",
    "content": "source [find target/c100.cfg]\n# basic register definition for C100\nsource [find target/c100regs.tcl]\n# board-config info\nsource [find target/c100config.tcl]\n# C100 helper functions\nsource [find target/c100helper.tcl]\n\n\n# Telo board & C100 support trst and srst\n# make the reset asserted to\n# allow RC circuit to discharge for: [ms]\nadapter srst pulse_width 100\njtag_ntrst_assert_width 100\n# don't talk to JTAG after reset for: [ms]\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst separate\n\n\n\n\n# issue telnet: reset init\n# issue gdb: monitor reset init\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 100\n\t# this will setup Telo board\n\tsetupTelo\n\t#turn up the JTAG speed\n\tadapter speed 3000\n\techo \"JTAG speek now 3MHz\"\n\techo \"type helpC100 to get help on C100\"\n}\n\n$_TARGETNAME configure -event reset-deassert-post {\n\t# Force target into ARM state.\n#\tsoft_reset_halt ;# not implemented on ARM11\n\techo \"Detected SRSRT asserted on C100.CPU\"\n\n}\n\n$_TARGETNAME configure -event reset-assert-post {\n  echo \"Assering reset\"\n  #sleep 10\n}\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\n# it's really 16MB but the upper 8mb is controller via gpio\n# openocd does not support 'complex reads/writes' to NOR\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x01000000 2 2 $_TARGETNAME\n\n# writing data to memory does not work without this\narm11 memwrite burst disable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am335xevm.cfg",
    "content": "#\n# TI AM335x Evaluation Module\n#\n# For more information please see http://www.ti.com/tool/tmdxevm3358\n#\njtag_rclk 6000\n\nsource [find target/am335x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am437x_idk.cfg",
    "content": "# Texas Instruments AM437x Industrial Development Kit\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\ntransport select jtag\nadapter speed 30000\n\nsource [find target/am437x.cfg]\n$_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 }\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am43xx_evm.cfg",
    "content": "# Works on both AM437x GP EVM and AM438x ePOS EVM\ntransport select jtag\nadapter speed 16000\n\nsource [find target/am437x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am625evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021-2022 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments am625 EVM/SK\n# Link: https://www.ti.com/lit/zip/sprr448\n#\n\n# AM625 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am625\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am642evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM642 EVM\n#\n\n# AM642 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am642\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 250\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_am654evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM654 EVM/IDK Base Board\n#\n\n# AM654 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\nif { ![info exists SOC] } {\n\tset SOC am654\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_beagleboard.cfg",
    "content": "# OMAP3 BeagleBoard\n#  http://beagleboard.org\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n\nsource [find target/omap3530.cfg]\n\n# TI-14 JTAG connector\nreset_config trst_only\n\n# Later run:  omap3_dbginit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_beagleboard_xm.cfg",
    "content": "# BeagleBoard xM (DM37x)\n#  http://beagleboard.org\n\nset CHIPTYPE \"dm37x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit dm37x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_beaglebone-base.cfg",
    "content": "# AM335x Beaglebone family base configuration\n#  http://beagleboard.org/bone\n\nsource [find target/am335x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_beaglebone.cfg",
    "content": "# AM335x Beaglebone\n#  http://beagleboard.org/bone\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\nadapter speed 16000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_beaglebone_black.cfg",
    "content": "# AM335x Beaglebone Black\n#  http://beagleboard.org/bone\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_blaze.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc13x0_launchpad.cfg",
    "content": "#\n# TI CC13x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\ntransport select jtag\nadapter speed 5500\nsource [find target/ti_cc13x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc13x2_launchpad.cfg",
    "content": "#\n# TI CC13x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc13x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc26x0_launchpad.cfg",
    "content": "#\n# TI CC26x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc26x2_launchpad.cfg",
    "content": "#\n# TI CC26x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc3200_launchxl.cfg",
    "content": "#\n# TI SimpleLink Wi-Fi CC3200 LaunchPad\n#\n# http://www.ti.com/tool/cc3200-launchxl\n#\n\nsource [find interface/ftdi/ti-icdi.cfg]\n\nif { [info exists TRANSPORT] } {\n   transport select $TRANSPORT\n} else {\n   transport select jtag\n}\n\nadapter speed 2500\n\nset WORKAREASIZE 0x40000\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc3220sf_launchpad.cfg",
    "content": "#\n# TI CC3220SF-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc3220sf.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_cc32xx_launchpad.cfg",
    "content": "#\n# TI CC32xx-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_dk-tm4c129.cfg",
    "content": "#\n# TI Tiva C DK-TM4C129X Connected Development Kit\n#\n# http://www.ti.com/tool/dk-tm4c129x\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c129xnczad\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_ek-tm4c123gxl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c123gxl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c123gh6pm\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_ek-tm4c1294xl.cfg",
    "content": "#\n# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c1294xl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c1294ncpdt\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_j7200evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J7200 EVM\n#\n\n# J7200 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j7200\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_j721evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721E EVM\n#\n\n# J721E EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721e\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_j721s2evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721s2 EVM\n# Link(SoM): https://www.ti.com/lit/zip/sprr439\n#\n\n# J721s2 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721s2\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_msp432_launchpad.cfg",
    "content": "#\n# TI MSP432 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 10000\ntransport select swd\nsource [find target/ti_msp432.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_pandaboard.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_pandaboard_es.cfg",
    "content": "jtag_rclk 6000\n\nsource [find target/omap4460.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_tmdx570ls20susb.cfg",
    "content": "# TMS570 Microcontroller USB Kit\n# http://www.ti.com/tool/TMDX570LS20SUSB\n\n# Board uses a FT2232H to emulate an XDS100v2 JTAG debugger\n# TODO: board also supports an SCI UART on the 2232's B Bus\nsource [find interface/ftdi/xds100v2.cfg]\n\n# Processor is TMS570LS20216\nsource [find target/ti_tms570ls20xxx.cfg]\n\nreset_config trst_only\n\n# xds100v2 config says add this to the end\ninit\nftdi set_signal PWR_RST 1\njtag arp_init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/ti_tmdx570ls31usb.cfg",
    "content": "adapter speed 1500\n\nsource [find interface/ftdi/xds100v2.cfg]\nsource [find target/ti_tms570.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/tocoding_poplar.cfg",
    "content": "#\n# board configuration for Tocoding Poplar\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\nadapter speed 10000\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi3798.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/topas910.cfg",
    "content": "######################################\n# Target:    Toshiba TOPAS910 -- TMPA910 Starterkit\n#\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa910.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topas910_init }\n\nproc topas910_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;\n#  // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/topasa900.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n# Target:    Toshiba TOPAS900 -- TMPA900 Starterkit\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa900.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topasa900_init }\n\nproc topasa900_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n# bplan settings\n#\tmww 0xf0050004 0x00000000\n#\tmww 0xf005000c 0x000000a7\n#\tsleep 10\n#\tmdw 0xf0050008\n#\tmww 0xf0050008 0x00000002\n#\tmww 0xf0050010 0x00000065\n#\tmww 0xf0050054 0x00000040\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;   // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/tp-link_tl-mr3020.cfg",
    "content": "source [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr1_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/tp-link_wdr4300.cfg",
    "content": "source [find target/atheros_ar9344.cfg]\n\nreset_config trst_only separate\n\nproc ar9344_40mhz_pll_init {} {\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x13210f00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x13210f00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_BB_DPLL_BASE_REG\n\tmww 0xb8116188 0x03000000\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\n\t# QCA_PLL_CPU_PLL_CFG_REG\n\tmww 0xb8050000 0x40021380\n\t# QCA_PLL_DDR_PLL_CFG_REG\n\tmww 0xb8050004 0x40815800\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130801C\n\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x10810F00\n\tmww 0xb81161C0 0x41C00000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0810F00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0800F00\n\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x43000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x030003E8\n\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x10810F00\n\tmww 0xb8116240 0x41680000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0810F00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0800F00\n\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x43000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000718\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x01308018\n\tmww 0xb8050008 0x01308010\n\tmww 0xb8050008 0x01308000\n\n\t# QCA_PLL_DDR_PLL_DITHER_REG\n\tmww 0xb8050044 0x78180200\n\t# QCA_PLL_CPU_PLL_DITHER_REG\n\tmww 0xb8050048 0x41C00000\n\n}\n\nproc ar9344_ddr_init {} {\n\t# QCA_DDR_CTRL_CFG_REG\n\tmww 0xb8000108 0x40\n\t# QCA_DDR_RD_DATA_THIS_CYCLE_REG\n\tmww 0xb8000018 0xFF\n\t# QCA_DDR_BURST_REG\n\tmww 0xb80000C4 0x74444444\n\t# QCA_DDR_BURST2_REG\n\tmww 0xb80000C8 0x0222\n\t# QCA_AHB_MASTER_TOUT_MAX_REG\n\tmww 0xb80000CC 0xFFFFF\n\n\t# QCA_DDR_CFG_REG\n\tmww 0xb8000000 0xC7D48CD0\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_DDR2_CFG_REG\n\tmww 0xb80000B8 0x0E59\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x10\n\tmww 0xb8000010 0x20\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x02\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x02\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x0133\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x33\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0382\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0402\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\n\t# QCA_DDR_REFRESH_REG\n\tmww 0xb8000014 0x4270\n\n\t# QCA_DDR_TAP_CTRL_0_REG\n\tmww 0xb800001C 0x0e\n\t# QCA_DDR_TAP_CTRL_1_REG\n\tmww 0xb8000020 0x0e\n\t# QCA_DDR_TAP_CTRL_2_REG\n\tmww 0xb8000024 0x0e\n\t# QCA_DDR_TAP_CTRL_3_REG\n\tmww 0xb8000028 0x0e\n}\n\n$_TARGETNAME configure -event reset-init {\n\n\t# mww 0xb806001c 0x1000000\n\tar9344_40mhz_pll_init\n\tsleep 100\n\n\t# flash remap\n\t# SPI_CONTROL_ADDR\n\tmww 0xbF000004 0x43\n\n\tar9344_ddr_init\n\tsleep 100\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0x1d000000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/twr-k60f120m.cfg",
    "content": "#\n# Freescale TWRK60F120M development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' banks\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.2 kinetis 0x00080000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.3 kinetis 0x000c0000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/twr-k60n512.cfg",
    "content": "#\n# Freescale TWRK60N512 development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' bank\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/twr-vf65gs10.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# Board has a 20 pin Cortex+ETM debug connector with only nSRST available\nreset_config srst_only\n\n# This configuration file only deals with the hardware JTAG.\n# There is has also an embedded Kinetis K20 with OpenSDA\n# where a CMSIS-DAP application can be installed.\n\n# Source generic VF6xx target configuration\nsource [find target/vybrid_vf6xx.cfg]\n\n# basic DDR memory init, setting up pad configuration\n# for DDR first then configuring the DDRMC for the\n# board\nproc ddr_init { } {\n\t# iomux ddr\n\tmww phys 0x40048220 0x00000180\n\tmww phys 0x40048224 0x00000180\n\tmww phys 0x40048228 0x00000180\n\tmww phys 0x4004822c 0x00000180\n\tmww phys 0x40048230 0x00000180\n\tmww phys 0x40048234 0x00000180\n\tmww phys 0x40048238 0x00000180\n\tmww phys 0x4004823c 0x00000180\n\tmww phys 0x40048240 0x00000180\n\tmww phys 0x40048244 0x00000180\n\tmww phys 0x40048248 0x00000180\n\tmww phys 0x4004824c 0x00000180\n\tmww phys 0x40048250 0x00000180\n\tmww phys 0x40048254 0x00000180\n\tmww phys 0x40048258 0x00000180\n\tmww phys 0x4004825c 0x00000180\n\tmww phys 0x40048260 0x00000180\n\tmww phys 0x40048264 0x00000180\n\tmww phys 0x40048268 0x00000180\n\tmww phys 0x4004826c 0x00000180\n\tmww phys 0x40048270 0x00000180\n\tmww phys 0x40048274 0x00000180\n\tmww phys 0x40048278 0x00000180\n\tmww phys 0x4004827c 0x00010180\n\tmww phys 0x40048280 0x00010180\n\tmww phys 0x40048284 0x00010180\n\tmww phys 0x40048288 0x00010180\n\tmww phys 0x4004828c 0x00010180\n\tmww phys 0x40048290 0x00010180\n\tmww phys 0x40048294 0x00010180\n\tmww phys 0x40048298 0x00010180\n\tmww phys 0x4004829c 0x00010180\n\tmww phys 0x400482a0 0x00010180\n\tmww phys 0x400482a4 0x00010180\n\tmww phys 0x400482a8 0x00010180\n\tmww phys 0x400482ac 0x00010180\n\tmww phys 0x400482b0 0x00010180\n\tmww phys 0x400482b4 0x00010180\n\tmww phys 0x400482b8 0x00010180\n\tmww phys 0x400482bc 0x00010180\n\tmww phys 0x400482c0 0x00010180\n\tmww phys 0x400482c4 0x00010180\n\tmww phys 0x400482c8 0x00010180\n\tmww phys 0x400482cc 0x00000180\n\tmww phys 0x400482d0 0x00000180\n\tmww phys 0x400482d4 0x00000180\n\tmww phys 0x400482d8 0x00000180\n\tmww phys 0x4004821c 0x000001a0\n\t# ddr_ctrl_init\n\tmww phys 0x400ae000 0x00000600\n\tmww phys 0x400ae008 0x00000020\n\tmww phys 0x400ae028 0x00013880\n\tmww phys 0x400ae02c 0x00030d40\n\tmww phys 0x400ae030 0x0000050c\n\tmww phys 0x400ae034 0x15040400\n\tmww phys 0x400ae038 0x1406040f\n\tmww phys 0x400ae040 0x04040000\n\tmww phys 0x400ae044 0x006db00c\n\tmww phys 0x400ae048 0x00000403\n\tmww phys 0x400ae050 0x01000000\n\tmww phys 0x400ae054 0x00060001\n\tmww phys 0x400ae058 0x000c0000\n\tmww phys 0x400ae05c 0x03000200\n\tmww phys 0x400ae060 0x00000006\n\tmww phys 0x400ae064 0x00010000\n\tmww phys 0x400ae068 0x0c30002c\n\tmww phys 0x400ae070 0x00000000\n\tmww phys 0x400ae074 0x00000003\n\tmww phys 0x400ae078 0x0000000a\n\tmww phys 0x400ae07c 0x003001d4\n\tmww phys 0x400ae084 0x00010000\n\tmww phys 0x400ae088 0x00050500\n\tmww phys 0x400ae098 0x00000000\n\tmww phys 0x400ae09c 0x04001002\n\tmww phys 0x400ae0a4 0x00000001\n\tmww phys 0x400ae0c0 0x00460420\n\tmww phys 0x400ae108 0x01000200\n\tmww phys 0x400ae10c 0x00000040\n\tmww phys 0x400ae114 0x00000200\n\tmww phys 0x400ae118 0x00000040\n\tmww phys 0x400ae120 0x00000000\n\tmww phys 0x400ae124 0x0a010300\n\tmww phys 0x400ae128 0x01014040\n\tmww phys 0x400ae12c 0x01010101\n\tmww phys 0x400ae130 0x03030100\n\tmww phys 0x400ae134 0x01000101\n\tmww phys 0x400ae138 0x0700000c\n\tmww phys 0x400ae13c 0x00000000\n\tmww phys 0x400ae148 0x10000000\n\tmww phys 0x400ae15c 0x01000000\n\tmww phys 0x400ae160 0x00040000\n\tmww phys 0x400ae164 0x00000002\n\tmww phys 0x400ae16c 0x00020000\n\tmww phys 0x400ae180 0x00002819\n\tmww phys 0x400ae184 0x01000000\n\tmww phys 0x400ae188 0x00000000\n\tmww phys 0x400ae18c 0x00000000\n\tmww phys 0x400ae198 0x00000000\n\tmww phys 0x400ae1a4 0x00000c00\n\tmww phys 0x400ae1a8 0x00000000\n\tmww phys 0x400ae1b8 0x0000000c\n\tmww phys 0x400ae1c8 0x00000000\n\tmww phys 0x400ae1cc 0x00000000\n\tmww phys 0x400ae1d4 0x00000000\n\tmww phys 0x400ae1d8 0x01010000\n\tmww phys 0x400ae1e0 0x02020000\n\tmww phys 0x400ae1e4 0x00000202\n\tmww phys 0x400ae1e8 0x01010064\n\tmww phys 0x400ae1ec 0x00010101\n\tmww phys 0x400ae1f0 0x00000064\n\tmww phys 0x400ae1f8 0x00000800\n\tmww phys 0x400ae210 0x00000506\n\tmww phys 0x400ae224 0x00020000\n\tmww phys 0x400ae228 0x01000000\n\tmww phys 0x400ae22c 0x04070303\n\tmww phys 0x400ae230 0x00000040\n\tmww phys 0x400ae23c 0x06000080\n\tmww phys 0x400ae240 0x04070303\n\tmww phys 0x400ae244 0x00000040\n\tmww phys 0x400ae248 0x00000040\n\tmww phys 0x400ae24c 0x000f0000\n\tmww phys 0x400ae250 0x000f0000\n\tmww phys 0x400ae25c 0x00000101\n\tmww phys 0x400ae268 0x682c4000\n\tmww phys 0x400ae26c 0x00000012\n\tmww phys 0x400ae278 0x00000006\n\tmww phys 0x400ae284 0x00010202\n\tmww phys 0x400ae400 0x00002613\n\tmww phys 0x400ae440 0x00002613\n\tmww phys 0x400ae404 0x00002615\n\tmww phys 0x400ae444 0x00002615\n\tmww phys 0x400ae408 0x00210000\n\tmww phys 0x400ae448 0x00210000\n\tmww phys 0x400ae488 0x00210000\n\tmww phys 0x400ae40c 0x0001012a\n\tmww phys 0x400ae44c 0x0001012a\n\tmww phys 0x400ae48c 0x0001012a\n\tmww phys 0x400ae410 0x00002400\n\tmww phys 0x400ae450 0x00002400\n\tmww phys 0x400ae490 0x00002400\n\tmww phys 0x400ae4c4 0x00000000\n\tmww phys 0x400ae4c8 0x00001100\n\tmww phys 0x400ae4d0 0x00010101\n\tmww phys 0x400ae000 0x00000601\n}\n\n# clock control init, setting up basic\n# clocks\nproc clock_init { } {\n\t# captured from u-boot\n\tmww phys 0x4006b040 0xffffffff\n\tmww phys 0x4006b044 0xffffffff\n\tmww phys 0x4006b048 0xffffffff\n\tmww phys 0x4006b04c 0xffffffff\n\tmww phys 0x4006b050 0xffffffff\n\tmww phys 0x4006b058 0xffffffff\n\tmww phys 0x4006b05c 0xffffffff\n\tmww phys 0x4006b060 0xffffffff\n\tmww phys 0x4006b064 0xffffffff\n\tmww phys 0x4006b068 0xffffffff\n\tmww phys 0x40050030 0x00002001\n\tmww phys 0x40050270 0x80002001\n\tmww phys 0x4006b000 0x00011005\n\tmww phys 0x4006b008 0x0001ff24\n\tmww phys 0x4006b00c 0x00000810\n\tmww phys 0x4006b010 0x00cc0000\n\tmww phys 0x4006b014 0x01000000\n\tmww phys 0x4006b018 0x20000000\n\tmww phys 0x4006b01c 0x0000001f\n\tmww phys 0x4006b020 0x00000000\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc board_init { } {\n\tclock_init\n\tddr_init\n}\n\n# hook the init function into the reset-init event\n${_TARGETNAME}0 configure -event reset-init { board_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/twr-vf65gs10_cmsisdap.cfg",
    "content": "#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# CMSIS-DAP via USB-OTG connector\n#\nsource [find interface/cmsis-dap.cfg]\n\n# only SWD is supported by the CMSIS-DAP on this board\ntransport select swd\n\n# Source generic part of twr-vf65gs10 configuration\nsource [find board/twr-vf65gs10.cfg]\n\n# override reset configuration\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/tx25_stk5.cfg",
    "content": "# -------------------------------------------------------------------------\n# KaRo TX25 CPU Module on a StarterkitV base board\n# http://www.karo-electronics.com/tx25.html\n# -------------------------------------------------------------------------\n\n\nsource [find target/imx25.cfg]\n\n\t#-------------------------------------------------------------------------\n\t# Declare Nand\n\t#-------------------------------------------------------------------------\n\n\tnand device K9F1G08UOC mxc imx25.cpu mx25 hwecc biswap\n\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx25_init }\n\n\nproc tx25_init { } {\n\n\t#-------------------------------------------------------------------------\n\t# AIPS setup - Only setup MPROTx registers. The PACR default values are good.\n\t# Set all MPROTx to be non-bufferable, trusted for R/W,\n\t# not forced to user-mode.\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\tsleep 100\n\n\t#-------------------------------------------------------------------------\n\t# MAX (Multi-Layer AHB Crossbar Switch) setup\n\t# MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f04000 0x00043210\n\tmww 0x43f04100 0x00043210\n\tmww 0x43f04200 0x00043210\n\tmww 0x43f04300 0x00043210\n\tmww 0x43f04400 0x00043210\n\n\t# SGPCR - always park on last master\n\tmww 0x43f04010 0x10\n\tmww 0x43f04110 0x10\n\tmww 0x43f04210 0x10\n\tmww 0x43f04310 0x10\n\tmww 0x43f04410 0x10\n\n\t# MGPCR - restore default values\n\tmww 0x43f04800 0x0\n\tmww 0x43f04900 0x0\n\tmww 0x43f04a00 0x0\n\tmww 0x43f04b00 0x0\n\tmww 0x43f04c00 0x0\n\n\t# Configure M3IF registers\n\t# M3IF Control Register (M3IFCTL) for MX25\n\t# MRRP[0] = LCDC           on priority list (1 << 0)  = 0x00000001\n\t# MRRP[1] = MAX1       not on priority list (0 << 1)  = 0x00000000\n\t# MRRP[2] = MAX0       not on priority list (0 << 2)  = 0x00000000\n\t# MRRP[3] = USB HOST   not on priority list (0 << 3)  = 0x00000000\n\t# MRRP[4] = SDMA       not on priority list (0 << 4)  = 0x00000000\n\t# MRRP[5] = SD/ATA/FEC not on priority list (0 << 5)  = 0x00000000\n\t# MRRP[6] = SCMFBC     not on priority list (0 << 6)  = 0x00000000\n\t# MRRP[7] = CSI        not on priority list (0 << 7)  = 0x00000000\n\t#                                                       ----------\n\t#                                                       0x00000001\n\tmww 0xb8003000 0x00000001\n\n\t#-------------------------------------------------------------------------\n\t# configure ARM CLK\n\t#-------------------------------------------------------------------------\n\n\t# Set the Clock CTL (HRM p. 355)\n\tmww 0x53F80008 0x20034000\n\n\t# Setup Clock Gating CTL 0-2 (HRM p. 357)\n\tmww 0x53F8000C 0x1fffffff\n\tmww 0x53F80010 0xffffffff\n\tmww 0x53F80014 0x000fdfff\n\n\t#-------------------------------------------------------------------------\n\t# SDRAM initialization\n\t#-------------------------------------------------------------------------\n\n\t# set to 3.3v SDRAM\n\tmww 0x43FAC454 0x00000800\n\n\t# reset (set up ESDMISC)\n\tmww 0xB8001010 0x00000002\n\n\t# Setup for SDRAM Bank 0\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG0\n\tmww 0xB8001004 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001000 0x92116480\n\tmww 0x80000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001000 0xA2116480\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001000 0xB2116480\n\tmwb 0x80000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001000 0x82116480\n\n\t# Setup for SDRAM Bank 1\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG1\n\tmww 0xB800100C 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001008 0x92116480\n\tmww 0x90000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001008 0xA2116480\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001008 0xB2116480\n\tmwb 0x90000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001008 0x82116480\n\n\t# GPIO configuration\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43FAC02C 0x00000015\n\tmww 0x53FD0000 0x01000000\n\tmww 0x53FD0004 0x00000080\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/tx27_stk5.cfg",
    "content": "# KaRo TX27 CPU Module on a StarterkitV base board\n#\n# http://www.karo-electronics.com/tx27.html\n#\nsource [find target/imx27.cfg]\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx27_init }\n\nproc tx27_init { } {\n\t# This setup puts RAM at 0xA0000000\n\t# init_aipi (AIPI1.PSR0, AIPI2.PSR0, AIPI1.PSR1 and AIPI2.PSR1)\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t#init_max ( PORT0.MPR, #PORT0.AMPR, #PORT1.MPR, #PORT1.AMPR, #PORT2.MPR, #PORT2.AMPR)\n\tmww 0x1003F000 0x00302145\n\tmww 0x1003F004 0x00302145\n\tmww 0x1003F100 0x00302145\n\tmww 0x1003F104 0x00302145\n\tmww 0x1003F200 0x00302145\n\tmww 0x1003F204 0x00302145\n\n\t#init_drive_strength (#DSCR3, #DSCR5, #DSCR6, #DSCR7, #DSCR8 )\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\t#init_sdram_speed\n\t#mww 0xD8001010 0x00000004\n\tmww 0xD8001010 0x00000024\n\n\tmww 0xD8001004 0x00395729\n\n\tmww 0xD8001000 0x92120000\n\tmww 0xA0000400 0x0\n\n\tmww 0xD8001000 0xA2120000\n\tmww 0xA0000000 0x0\n\tmww 0xA0000000 0x0\n\n\tmww 0xD8001000 0xB2120000\n\tmdb 0xA0000000\n\tmdb 0xA0000033\n\n\tmww 0xD8001000 0x82126485\n\n\t# =============================================\n\t# Sync mode (AHB Clk = 133MHz ; BCLK = 44.3MHz)\n\t# =============================================\n\tmww 0xD8002000 0x23524E80\n\tmww 0xD8002004 0x10000D03\n\tmww 0xD8002008 0x00720900\n\n\tnand probe 0\n}\n\nnand device tx27.nand mxc $_TARGETNAME mx27 hwecc biswap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/unknown_at91sam9260.cfg",
    "content": "# Thanks to Pieter Conradie for this script!\n#\n# Unknown vendor board contains:\n#\n# Atmel AT91SAM9260 : PLLA = 192.512MHz, MCK = 96.256 MHz\n#                     OSCSEL configured for internal RC oscillator (22 to 42 kHz)\n#\n# 16-bit NOR FLASH : Intel JS28F128P30T85 128MBit\n# 32-bit SDRAM : 2 x Samsung K4S561632H-UC75, 4M x 16Bit x 4 Banks\n##################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 22 to 42 kHz.\n        # JTAG Frequency must be 6 times slower.\n        jtag_rclk 3\n        halt\n\t# RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x205dbf09         ;# CKGR_PLLAR: Set PLLA Register for 192.512MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (96.256 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xffffec00 0x01020102         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x09070806         ;# SMC_PULSE0\n\tmww 0xffffec08 0x000d000b         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00001003         ;# SMC_MODE0\n\n\tflash probe 0                     ;# Identify flash bank 0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n        mww 0xfffff860 0xffff0000         ;# PIO_PUDR : Disable D15..D31 pull-ups\n\n        mww 0xffffef1c 0x00010102         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM\n                                           #            VDDIOMSEL set for +3V3 memory\n                                           #            Disable D0..D15 pull-ups\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2a2              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/uptech_2410.cfg",
    "content": "# Target Configuration for the Uptech 2410 board.\n# This configuration should also work on smdk2410, but I haven't tested it yet.\n# Author: xionglingfeng@Gmail.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init { uptech2410_init }\n$_TARGETNAME configure -event gdb-attach { reset init }\n\nproc init_pll_sdram { } {\n\t#echo \"---------- Initializing PLL and SDRAM ---------\"\n\t#watchdog timer disable\n\tmww phys 0x53000000 0x00000000\n\n\t#disable all interrupts\n\tmww phys 0x4a000008 0xffffffff\n\n\t#disable all sub-interrupts\n\tmww phys 0x4a00001c 0x000007ff\n\n\t#clear all source pending bits\n\tmww phys 0x4a000000 0xffffffff\n\n\t#clear all sub-source pending bits\n\tmww phys 0x4a000018 0x000007ff\n\n\t#clear interrupt pending bit\n\tmww phys 0x4a000010 0xffffffff\n\n\t#PLL locktime counter\n\tmww phys 0x4c000000 0x00ffffff\n\n\t#Fin=12MHz Fout=202.8MHz\n\t#mww phys 0x4c000004 0x000a1031\n\n\t#FCLK:HCLK:PCLK = 1:2:4\n\tmww phys 0x4c000014 0x00000003\n\n\n\tmww phys 0x48000000 0x11111110\n\tmww phys 0x48000004 0x00007FFC\n\tmww phys 0x48000008 0x00007FFC\n\tmww phys 0x4800000c 0x00000700\n\tmww phys 0x48000010 0x00000700\n\tmww phys 0x48000014 0x00002E50\n\tmww phys 0x48000018 0x00002E50\n\tmww phys 0x4800001c 0x00018005\n\tmww phys 0x48000020 0x00018005\n\tmww phys 0x48000024 0x008c04e9\n\tmww phys 0x48000028 0x000000b2\n\tmww phys 0x4800002c 0x00000030\n\tmww phys 0x48000030 0x00000030\n}\n\nproc uptech2410_init { } {\n\tinit_pll_sdram\n\t#echo \"---------- Probing Nand flash ----------\"\n\tnand probe 0\n\t#echo \"---------- Enable some functions ----------\"\n}\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME s3c2410 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/vd_a53x2_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex A53x2 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CORES 2\nset _CHIPNAME a53\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x1000000\nset _CPUTAPID 0x5ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_aarch64.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/vd_m4_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m4 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m4\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\nset _CPUTAPID 0x4ba00477\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 25000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 20ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/vd_pulpissimo_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV Ibex core with Pulpissimo through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME ibex\nset _HARTID 0x20\nset _CPUTAPID 0x249511c3\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 12500\nadapter srst delay 10\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 40ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[0\\].sram_i.mem_array 0x1c000000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[1\\].sram_i.mem_array 0x1c008000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2\\[0\\].sram_i.mem_array 0x1c010000 0x80000\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x05 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/vd_swerv_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV swerv core with Swerv through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME rv32\nset _HARTID 0x00\nset _CPUTAPID 0x1000008b\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\n\n# vdebug select transport\n#transport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.i_ahb_ic.mem $_MEMSTART $_MEMSIZE\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/verdex.cfg",
    "content": "# Config for Gumstix Verdex XM4 and XL6P (PXA270)\n\nset CHIPNAME verdex\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz\nadapter speed 40000\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n# XL6P has 32 MB flash\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x02000000 2 2 $_TARGETNAME\n# XM4 has 16 MB flash\n#flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/voipac.cfg",
    "content": "# Config for Voipac PXA270/PXA270M module.\n\nset CHIPNAME voipac\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\nflash bank $_CHIPNAME.flash1 cfi 0x02000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/voltcraft_dso-3062c.cfg",
    "content": "#\n# Voltcraft DSO-3062C digital oscilloscope (uses a Samsung S3C2440)\n#\n# http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/\n# http://www.mikrocontroller.net/topic/249628\n# http://elinux.org/Das_Oszi\n# http://randomprojects.org/wiki/Voltcraft_DSO-3062C\n#\n\n# Enable this if your JTAG adapter supports multiple transports (JTAG or SWD).\n# Otherwise comment it out, as it will cause an OpenOCD error.\n### transport select jtag\n\nsource [find target/samsung_s3c2440.cfg]\n\nadapter speed 16000\n\n# Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit)\nnand device $_CHIPNAME.nand s3c2440 $_TARGETNAME\n\n# arm7_9 fast_memory_access enable\n# arm7_9 dcc_downloads enable\n\ninit\nreset\nhalt\nscan_chain\ntargets\nnand probe 0\nnand list\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/x300t.cfg",
    "content": "# This is for the T-Home X300T / X301T IPTV box,\n# which are based on IPTV reference designs from Kiss/Cisco KMM-3***\n#\n# It has Sigma Designs SMP8634 chip.\nsource [find target/smp8634.cfg]\n\n$_TARGETNAME configure -event reset-init { x300t_init }\n\n# 1MB CFI capable flash\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xac000000 0x100000 2 2 $_TARGETNAME\n\nproc x300t_init { } {\n\t# Setup SDRAM config and flash mapping\n\t# initialize ram\n\tmww 0xa003fffc 3\n\tmww 0xa003fffc 2\n\tmww 0xa0030000 0xE34111BA\n\tmww 0xa003fffc 0xa4444\n\tmww 0xa003fffc 0\n\n\t# remap boot vector in CPU local RAM\n\tmww 0xa006f000 0x60000\n\n\t# map flash to CPU address space REG_BASE_cpu_block+CPU_remap4\n\tmww 0x0006f010 0x48000000\n\n\t# map flash addr to REG_BASE_cpu_block + LR_XENV_LOCATION (normally done by XOS)\n\tmww 0x00061ff0 0x48000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc-2go.cfg",
    "content": "#\n# Infineon XMC 2Go\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc1100-boot-kit.cfg",
    "content": "#\n# Infineon XMC1100 Boot Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4200-application-kit-actuator.cfg",
    "content": "#\n# Infineon XMC4200 Application Kit - Actuator\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4200\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4300-relax.cfg",
    "content": "#\n# Infineon XMC4300 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4300\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4500-application-kit-general.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - General Purpose\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4500-application-kit-sdram.cfg",
    "content": "#\n# Infineon XMC4500 Application Kit - SDRAM\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4500-relax.cfg",
    "content": "#\n# Infineon XMC4500 Relax Kit / Relax Lite Kit\n#\n\n#\n# Segger J-Link Lite XMC4500 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4700-relax.cfg",
    "content": "#\n# Infineon XMC4700 Relax Lite Kit / Relax Kit for 5V Shields / Relax Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4700\nsource [find target/xmc4xxx.cfg]\n\n# Relax Kit only: N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmc4800-relax.cfg",
    "content": "#\n# Infineon XMC4800 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4800\nsource [find target/xmc4xxx.cfg]\n\n# N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/board/xmos_xk-xac-xa8_arm.cfg",
    "content": "#\n# xCORE-XA Core Module\n#\n# https://www.xmos.com/support/boards?product=17940\n#\n\n#\n# J-Link OB STM32F103\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n#\n# XS1-XAU8A-10\n#\nsource [find target/xmos_xs1-xau8a-10_arm.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/aic.tcl",
    "content": "set AIC_SMR      \t[expr {$AT91C_BASE_AIC + 0x00000000} ]\nglobal AIC_SMR\nset AIC_SVR      \t[expr {$AT91C_BASE_AIC + 0x00000080} ]\nglobal AIC_SVR\nset AIC_IVR      \t[expr {$AT91C_BASE_AIC + 0x00000100} ]\nglobal AIC_IVR\nset AIC_FVR      \t[expr {$AT91C_BASE_AIC + 0x00000104} ]\nglobal AIC_FVR\nset AIC_ISR      \t[expr {$AT91C_BASE_AIC + 0x00000108} ]\nglobal AIC_ISR\nset AIC_IPR      \t[expr {$AT91C_BASE_AIC + 0x0000010C} ]\nglobal AIC_IPR\nset AIC_IMR      \t[expr {$AT91C_BASE_AIC + 0x00000110} ]\nglobal AIC_IMR\nset AIC_CISR     \t[expr {$AT91C_BASE_AIC + 0x00000114} ]\nglobal AIC_CISR\nset AIC_IECR     \t[expr {$AT91C_BASE_AIC + 0x00000120} ]\nglobal AIC_IECR\nset AIC_IDCR     \t[expr {$AT91C_BASE_AIC + 0x00000124} ]\nglobal AIC_IDCR\nset AIC_ICCR     \t[expr {$AT91C_BASE_AIC + 0x00000128} ]\nglobal AIC_ICCR\nset AIC_ISCR     \t[expr {$AT91C_BASE_AIC + 0x0000012C} ]\nglobal AIC_ISCR\nset AIC_EOICR    \t[expr {$AT91C_BASE_AIC + 0x00000130} ]\nglobal AIC_EOICR\nset AIC_SPU      \t[expr {$AT91C_BASE_AIC + 0x00000134} ]\nglobal AIC_SPU\nset AIC_DCR      \t[expr {$AT91C_BASE_AIC + 0x00000138} ]\nglobal AIC_DCR\nset AIC_FFER     \t[expr {$AT91C_BASE_AIC + 0x00000140} ]\nglobal AIC_FFER\nset AIC_FFDR     \t[expr {$AT91C_BASE_AIC + 0x00000144} ]\nglobal AIC_FFDR\nset AIC_FFSR     \t[expr {$AT91C_BASE_AIC + 0x00000148} ]\nglobal AIC_FFSR\n\n\nproc aic_enable_disable_list { VAL ENAME DNAME } {\n    global AT91C_ID\n\n    show_mmr32_bits AT91C_ID $VAL\n\n}\n\nproc show_AIC_IPR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ PENDING\" \"irq not-pending\"\n}\n\nproc show_AIC_IMR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ ENABLED\" \"irq disabled\"\n}\n\n\nproc show_AIC { } {\n    global AIC_SMR\n    if [catch { set aaa [read_memory $AIC_SMR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SMR]\n    }\n    echo \"AIC_SMR: Mode & Type\"\n    global AT91C_ID\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo  [format \"%2d: %5s 0x%08x\"  $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n    global AIC_SVR\n    if [catch { set aaa [read_memory $AIC_SVR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SVR]\n    }\n    echo \"AIC_SVR: Vectors\"\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo [format \"%2d: %5s 0x%08x\" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n\n    foreach REG {\n\tAIC_IVR   AIC_FVR  AIC_ISR\n\tAIC_IPR  AIC_IMR  AIC_CISR  AIC_IECR AIC_IDCR\n\tAIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU  AIC_DCR\n\tAIC_FFER AIC_FFDR AIC_FFSR } {\n\tif [catch { show_mmr32_reg $REG } msg ] {\n\t    error $msg\n\t    break\n\t}\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91_pio.cfg",
    "content": "set PIO_PER\t0x00\t;# Enable Register\nset PIO_PDR\t0x04\t;# Disable Register\nset PIO_PSR\t0x08\t;# Status Register\nset PIO_OER\t0x10\t;# Output Enable Register\nset PIO_ODR\t0x14\t;# Output Disable Register\nset PIO_OSR\t0x18\t;# Output Status Register\nset PIO_IFER\t0x20\t;# Glitch Input Filter Enable\nset PIO_IFDR\t0x24\t;# Glitch Input Filter Disable\nset PIO_IFSR\t0x28\t;# Glitch Input Filter Status\nset PIO_SODR\t0x30\t;# Set Output Data Register\nset PIO_CODR\t0x34\t;# Clear Output Data Register\nset PIO_ODSR\t0x38\t;# Output Data Status Register\nset PIO_PDSR\t0x3c\t;# Pin Data Status Register\nset PIO_IER\t0x40\t;# Interrupt Enable Register\nset PIO_IDR\t0x44\t;# Interrupt Disable Register\nset PIO_IMR\t0x48\t;# Interrupt Mask Register\nset PIO_ISR\t0x4c\t;# Interrupt Status Register\nset PIO_MDER\t0x50\t;# Multi-driver Enable Register\nset PIO_MDDR\t0x54\t;# Multi-driver Disable Register\nset PIO_MDSR\t0x58\t;# Multi-driver Status Register\nset PIO_PUDR\t0x60\t;# Pull-up Disable Register\nset PIO_PUER\t0x64\t;# Pull-up Enable Register\nset PIO_PUSR\t0x68\t;# Pull-up Status Register\nset PIO_ASR\t0x70\t;# Peripheral A Select Register\nset PIO_BSR\t0x74\t;# Peripheral B Select Register\nset PIO_ABSR\t0x78\t;# AB Status Register\nset PIO_OWER\t0xa0\t;# Output Write Enable Register\nset PIO_OWDR\t0xa4\t;# Output Write Disable Register\nset PIO_OWSR\t0xa8\t;# Output Write Status Register\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91_pmc.cfg",
    "content": "set\tAT91_PMC_SCER\t\t[expr {$AT91_PMC + 0x00}]\t;# System Clock Enable Register\nset\tAT91_PMC_SCDR\t\t[expr {$AT91_PMC + 0x04}]\t;# System Clock Disable Register\n\nset\tAT91_PMC_SCSR\t\t[expr {$AT91_PMC + 0x08}]\t;# System Clock Status Register\nset\t\tAT91_PMC_PCK\t\t[expr {1 <<  0}]\t\t;# Processor Clock\nset\t\tAT91RM9200_PMC_UDP\t[expr {1 <<  1}]\t\t;# USB Devcice Port Clock [AT91RM9200 only]\nset\t\tAT91RM9200_PMC_MCKUDP\t[expr {1 <<  2}]\t\t;# USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only]\nset\t\tAT91CAP9_PMC_DDR\t[expr {1 <<  2}]\t\t;# DDR Clock [CAP9 revC & some SAM9 only]\nset\t\tAT91RM9200_PMC_UHP\t[expr {1 <<  4}]\t\t;# USB Host Port Clock [AT91RM9200 only]\nset\t\tAT91SAM926x_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91SAM926x only]\nset\t\tAT91CAP9_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91CAP9 only]\nset\t\tAT91SAM926x_PMC_UDP\t[expr {1 <<  7}]\t\t;# USB Devcice Port Clock [AT91SAM926x only]\nset\t\tAT91_PMC_PCK0\t\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1\t\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2\t\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3\t\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\t\tAT91_PMC_HCK0\t\t[expr {1 << 16}]\t\t;# AHB Clock (USB host) [AT91SAM9261 only]\nset\t\tAT91_PMC_HCK1\t\t[expr {1 << 17}]\t\t;# AHB Clock (LCD) [AT91SAM9261 only]\n\nset\tAT91_PMC_PCER\t\t[expr {$AT91_PMC + 0x10}]\t;# Peripheral Clock Enable Register\nset\tAT91_PMC_PCDR\t\t[expr {$AT91_PMC + 0x14}]\t;# Peripheral Clock Disable Register\nset\tAT91_PMC_PCSR\t\t[expr {$AT91_PMC + 0x18}]\t;# Peripheral Clock Status Register\n\nset\tAT91_CKGR_UCKR\t\t[expr {$AT91_PMC + 0x1C}]\t;# UTMI Clock Register [some SAM9, CAP9]\nset\t\tAT91_PMC_UPLLEN\t\t[expr {1   << 16}]\t\t;# UTMI PLL Enable\nset\t\tAT91_PMC_UPLLCOUNT\t[expr {0xf << 20}]\t\t;# UTMI PLL Start-up Time\nset\t\tAT91_PMC_BIASEN\t\t[expr {1   << 24}]\t\t;# UTMI BIAS Enable\nset\t\tAT91_PMC_BIASCOUNT\t[expr {0xf << 28}]\t\t;# UTMI BIAS Start-up Time\n\nset\tAT91_CKGR_MOR\t\t[expr {$AT91_PMC + 0x20}]\t;# Main Oscillator Register [not on SAM9RL]\nset\t\tAT91_PMC_MOSCEN\t\t[expr {1    << 0}]\t\t;# Main Oscillator Enable\nset\t\tAT91_PMC_OSCBYPASS\t[expr {1    << 1}]\t\t;# Oscillator Bypass [SAM9x, CAP9]\nset\t\tAT91_PMC_OSCOUNT\t[expr {0xff << 8}]\t\t;# Main Oscillator Start-up Time\n\nset\tAT91_CKGR_MCFR\t\t[expr {$AT91_PMC + 0x24}]\t;# Main Clock Frequency Register\nset\t\tAT91_PMC_MAINF\t\t[expr {0xffff <<  0}]\t\t;# Main Clock Frequency\nset\t\tAT91_PMC_MAINRDY\t[expr {1\t<< 16}]\t\t;# Main Clock Ready\n\nset\tAT91_CKGR_PLLAR\t\t[expr {$AT91_PMC + 0x28}]\t;# PLL A Register\nset\tAT91_CKGR_PLLBR\t\t[expr {$AT91_PMC + 0x2c}]\t;# PLL B Register\nset\t\tAT91_PMC_DIV\t\t[expr {0xff  <<  0}]\t\t;# Divider\nset\t\tAT91_PMC_PLLCOUNT\t[expr {0x3f  <<  8}]\t\t;# PLL Counter\nset\t\tAT91_PMC_OUT\t\t[expr {3     << 14}]\t\t;# PLL Clock Frequency Range\nset\t\tAT91_PMC_MUL\t\t[expr {0x7ff << 16}]\t\t;# PLL Multiplier\nset\t\tAT91_PMC_USBDIV\t\t[expr {3     << 28}]\t\t;# USB Divisor (PLLB only)\nset\t\t\tAT91_PMC_USBDIV_1\t\t[expr {0 << 28}]\nset\t\t\tAT91_PMC_USBDIV_2\t\t[expr {1 << 28}]\nset\t\t\tAT91_PMC_USBDIV_4\t\t[expr {2 << 28}]\nset\t\tAT91_PMC_USB96M\t\t[expr {1     << 28}]\t\t;# Divider by 2 Enable (PLLB only)\nset\t\tAT91_PMC_PLLA_WR_ERRATA\t[expr {1     << 29}]\t\t;# Bit 29 must always be set to 1 when programming the CKGR_PLLAR register\n\nset\tAT91_PMC_MCKR\t\t[expr {$AT91_PMC + 0x30}]\t;# Master Clock Register\nset\t\tAT91_PMC_CSS\t\t[expr {3 <<  0}]\t\t;# Master Clock Selection\nset\t\t\tAT91_PMC_CSS_SLOW\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_CSS_MAIN\t\t[expr {1 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLA\t\t[expr {2 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLB\t\t[expr {3 << 0}]\nset\t\t\tAT91_PMC_CSS_UPLL\t\t[expr {3 << 0}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PRES\t\t[expr {7 <<  2}]\t\t;# Master Clock Prescaler\nset\t\t\tAT91_PMC_PRES_1\t\t\t[expr {0 << 2}]\nset\t\t\tAT91_PMC_PRES_2\t\t\t[expr {1 << 2}]\nset\t\t\tAT91_PMC_PRES_4\t\t\t[expr {2 << 2}]\nset\t\t\tAT91_PMC_PRES_8\t\t\t[expr {3 << 2}]\nset\t\t\tAT91_PMC_PRES_16\t\t[expr {4 << 2}]\nset\t\t\tAT91_PMC_PRES_32\t\t[expr {5 << 2}]\nset\t\t\tAT91_PMC_PRES_64\t\t[expr {6 << 2}]\nset\t\tAT91_PMC_MDIV\t\t[expr {3 <<  8}]\t\t;# Master Clock Division\nset\t\t\tAT91RM9200_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [AT91RM9200 only]\nset\t\t\tAT91RM9200_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_3\t\t[expr {2 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_4\t\t[expr {3 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [SAM9,CAP9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_4\t\t[expr {2 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_6\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_3\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PDIV\t\t[expr {1 << 12}]\t\t;# Processor Clock Division [some SAM9 only]\nset\t\t\tAT91_PMC_PDIV_1\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PDIV_2\t\t\t[expr {1 << 12}]\nset\t\tAT91_PMC_PLLADIV2\t[expr {1 << 12}]\t\t;# PLLA divisor by 2 [some SAM9 only]\nset\t\t\tAT91_PMC_PLLADIV2_OFF\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PLLADIV2_ON\t\t[expr {1 << 12}]\n\nset\tAT91_PMC_USB\t\t[expr {$AT91_PMC + 0x38}]\t;# USB Clock Register [some SAM9 only]\nset\t\tAT91_PMC_USBS\t\t[expr {0x1 <<  0}]\t\t;# USB OHCI Input clock selection\nset\t\t\tAT91_PMC_USBS_PLLA\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_USBS_UPLL\t\t[expr {1 << 0}]\nset\t\tAT91_PMC_OHCIUSBDIV\t[expr {0xF <<  8}]\t\t;# Divider for USB OHCI Clock\n\n;# set\tAT91_PMC_PCKR(n)\t[expr {$AT91_PMC + 0x40 + ((n) * 4)}]\t;# Programmable Clock 0-N Registers\nset\t\tAT91_PMC_CSSMCK\t\t[expr {0x1 <<  8}]\t\t;# CSS or Master Clock Selection\nset\t\t\tAT91_PMC_CSSMCK_CSS\t\t[expr {0 << 8}]\nset\t\t\tAT91_PMC_CSSMCK_MCK\t\t[expr {1 << 8}]\n\nset\tAT91_PMC_IER\t\t[expr {$AT91_PMC + 0x60}]\t;# Interrupt Enable Register\nset\tAT91_PMC_IDR\t\t[expr {$AT91_PMC + 0x64}]\t;# Interrupt Disable Register\nset\tAT91_PMC_SR\t\t[expr {$AT91_PMC + 0x68}]\t;# Status Register\nset\t\tAT91_PMC_MOSCS\t\t[expr {1 <<  0}]\t\t;# MOSCS Flag\nset\t\tAT91_PMC_LOCKA\t\t[expr {1 <<  1}]\t\t;# PLLA Lock\nset\t\tAT91_PMC_LOCKB\t\t[expr {1 <<  2}]\t\t;# PLLB Lock\nset\t\tAT91_PMC_MCKRDY\t\t[expr {1 <<  3}]\t\t;# Master Clock\nset\t\tAT91_PMC_LOCKU\t\t[expr {1 <<  6}]\t\t;# UPLL Lock [some SAM9, AT91CAP9 only]\nset\t\tAT91_PMC_OSCSEL\t\t[expr {1 <<  7}]\t\t;# Slow Clock Oscillator [AT91CAP9 revC only]\nset\t\tAT91_PMC_PCK0RDY\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1RDY\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2RDY\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3RDY\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\tAT91_PMC_IMR\t\t[expr {$AT91_PMC + 0x6c}]\t;# Interrupt Mask Register\n\nset AT91_PMC_PROT\t\t[expr {$AT91_PMC + 0xe4}]\t;# Protect Register [AT91CAP9 revC only]\nset\t\tAT91_PMC_PROTKEY\t0x504d4301\t;# Activation Code\n\nset AT91_PMC_VER\t\t[expr {$AT91_PMC + 0xfc}]\t;# PMC Module Version [AT91CAP9 only]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91_rstc.cfg",
    "content": "set AT91_RSTC_CR\t\t[expr {$AT91_RSTC + 0x00}]\t;# Reset Controller Control Register\nset\t\tAT91_RSTC_PROCRST\t[expr {1 << 0}]\t\t;# Processor Reset\nset\t\tAT91_RSTC_PERRST\t[expr {1 << 2}]\t\t;# Peripheral Reset\nset\t\tAT91_RSTC_EXTRST\t[expr {1 << 3}]\t\t;# External Reset\nset\t\tAT91_RSTC_KEY\t\t[expr {0xa5 << 24}]\t\t;# KEY Password\n\nset AT91_RSTC_SR\t\t[expr {$AT91_RSTC + 0x04}]\t;# Reset Controller Status Register\nset\t\tAT91_RSTC_URSTS\t\t[expr {1 << 0}]\t\t;# User Reset Status\nset\t\tAT91_RSTC_RSTTYP\t[expr {7 << 8}]\t\t;# Reset Type\nset\t\t\tAT91_RSTC_RSTTYP_GENERAL\t[expr {0 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WAKEUP\t\t[expr {1 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WATCHDOG\t[expr {2 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_SOFTWARE\t[expr {3 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_USER\t[expr {4 << 8}]\nset\t\tAT91_RSTC_NRSTL\t\t[expr {1 << 16}]\t\t;# NRST Pin Level\nset\t\tAT91_RSTC_SRCMP\t\t[expr {1 << 17}]\t\t;# Software Reset Command in Progress\n\nset AT91_RSTC_MR\t\t[expr {$AT91_RSTC + 0x08}]\t;# Reset Controller Mode Register\nset\t\tAT91_RSTC_URSTEN\t[expr {1 << 0}]\t\t;# User Reset Enable\nset\t\tAT91_RSTC_URSTIEN\t[expr {1 << 4}]\t\t;# User Reset Interrupt Enable\nset\t\tAT91_RSTC_ERSTL\t\t[expr {0xf << 8}]\t\t;# External Reset Length\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91_wdt.cfg",
    "content": "set AT91_WDT_CR\t\t[expr {$AT91_WDT + 0x00}]\t;# Watchdog Control Register\nset\t\tAT91_WDT_WDRSTT\t\t[expr {1    << 0}]\t;# Restart\nset\t\tAT91_WDT_KEY\t\t[expr {0xa5 << 24}]\t;# KEY Password\n\nset AT91_WDT_MR\t\t[expr {$AT91_WDT + 0x04}]\t;# Watchdog Mode Register\nset\t\tAT91_WDT_WDV\t\t[expr {0xfff << 0}]\t;# Counter Value\nset\t\tAT91_WDT_WDFIEN\t\t[expr {1     << 12}]\t;# Fault Interrupt Enable\nset\t\tAT91_WDT_WDRSTEN\t[expr {1     << 13}]\t;# Reset Processor\nset\t\tAT91_WDT_WDRPROC\t[expr {1     << 14}]\t;# Timer Restart\nset\t\tAT91_WDT_WDDIS\t\t[expr {1     << 15}]\t;# Watchdog Disable\nset\t\tAT91_WDT_WDD\t\t[expr {0xfff << 16}]\t;# Delta Value\nset\t\tAT91_WDT_WDDBGHLT\t[expr {1     << 28}]\t;# Debug Halt\nset\t\tAT91_WDT_WDIDLEHLT\t[expr {1     << 29}]\t;# Idle Halt\n\nset AT91_WDT_SR\t\t[expr {$AT91_WDT + 0x08}]\t;# Watchdog Status Register\nset\t\tAT91_WDT_WDUNF\t\t[expr {1 << 0}]\t\t;# Watchdog Underflow\nset\t\tAT91_WDT_WDERR\t\t[expr {1 << 1}]\t\t;# Watchdog Error\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam7x128.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x128\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__128K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__32K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\n\n\n\nset AT91C_BASE_SYS       0xFFFFF000\nset AT91C_BASE_AIC       0xFFFFF000\nset AT91C_BASE_PDC_DBGU  0xFFFFF300\nset AT91C_BASE_DBGU      0xFFFFF200\nset AT91C_BASE_PIOA      0xFFFFF400\nset AT91C_BASE_PIOB      0xFFFFF600\nset AT91C_BASE_CKGR      0xFFFFFC20\nset AT91C_BASE_PMC       0xFFFFFC00\nset AT91C_BASE_RSTC      0xFFFFFD00\nset AT91C_BASE_RTTC      0xFFFFFD20\nset AT91C_BASE_PITC      0xFFFFFD30\nset AT91C_BASE_WDTC      0xFFFFFD40\nset AT91C_BASE_VREG      0xFFFFFD60\nset AT91C_BASE_MC        0xFFFFFF00\nset AT91C_BASE_PDC_SPI1  0xFFFE4100\nset AT91C_BASE_SPI1      0xFFFE4000\nset AT91C_BASE_PDC_SPI0  0xFFFE0100\nset AT91C_BASE_SPI0      0xFFFE0000\nset AT91C_BASE_PDC_US1   0xFFFC4100\nset AT91C_BASE_US1       0xFFFC4000\nset AT91C_BASE_PDC_US0   0xFFFC0100\nset AT91C_BASE_US0       0xFFFC0000\nset AT91C_BASE_PDC_SSC   0xFFFD4100\nset AT91C_BASE_SSC       0xFFFD4000\nset AT91C_BASE_TWI       0xFFFB8000\nset AT91C_BASE_PWMC_CH3  0xFFFCC260\nset AT91C_BASE_PWMC_CH2  0xFFFCC240\nset AT91C_BASE_PWMC_CH1  0xFFFCC220\nset AT91C_BASE_PWMC_CH0  0xFFFCC200\nset AT91C_BASE_PWMC      0xFFFCC000\nset AT91C_BASE_UDP       0xFFFB0000\nset AT91C_BASE_TC0       0xFFFA0000\nset AT91C_BASE_TC1       0xFFFA0040\nset AT91C_BASE_TC2       0xFFFA0080\nset AT91C_BASE_TCB       0xFFFA0000\nset AT91C_BASE_CAN_MB0   0xFFFD0200\nset AT91C_BASE_CAN_MB1   0xFFFD0220\nset AT91C_BASE_CAN_MB2   0xFFFD0240\nset AT91C_BASE_CAN_MB3   0xFFFD0260\nset AT91C_BASE_CAN_MB4   0xFFFD0280\nset AT91C_BASE_CAN_MB5   0xFFFD02A0\nset AT91C_BASE_CAN_MB6   0xFFFD02C0\nset AT91C_BASE_CAN_MB7   0xFFFD02E0\nset AT91C_BASE_CAN       0xFFFD0000\nset AT91C_BASE_EMAC      0xFFFDC000\nset AT91C_BASE_PDC_ADC   0xFFFD8100\nset AT91C_BASE_ADC       0xFFFD8000\n\nset AT91C_ID(0) FIQ\nset AT91C_ID(1) SYS\nset AT91C_ID(2) PIOA\nset AT91C_ID(3) PIOB\nset AT91C_ID(4) SPI0\nset AT91C_ID(5) SPI1\nset AT91C_ID(6) US0\nset AT91C_ID(7) US1\nset AT91C_ID(8) SSC\nset AT91C_ID(9) TWI\nset AT91C_ID(10) PWMC\nset AT91C_ID(11) UDP\nset AT91C_ID(12) TC0\nset AT91C_ID(13) TC1\nset AT91C_ID(14) TC2\nset AT91C_ID(15) CAN\nset AT91C_ID(16) EMAC\nset AT91C_ID(17) ADC\nset AT91C_ID(18) \"\"\nset AT91C_ID(19) \"\"\nset AT91C_ID(20) \"\"\nset AT91C_ID(21) \"\"\nset AT91C_ID(22) \"\"\nset AT91C_ID(23) \"\"\nset AT91C_ID(24) \"\"\nset AT91C_ID(25) \"\"\nset AT91C_ID(26) \"\"\nset AT91C_ID(27) \"\"\nset AT91C_ID(28) \"\"\nset AT91C_ID(29) \"\"\nset AT91C_ID(30) IRQ0\nset AT91C_ID(31) IRQ1\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam7x256.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x256\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__256K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__64K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\nset  AT91C_BASE_SYS              0xFFFFF000\nset  AT91C_BASE_AIC              0xFFFFF000\nset  AT91C_BASE_PDC_DBGU         0xFFFFF300\nset  AT91C_BASE_DBGU             0xFFFFF200\nset  AT91C_BASE_PIOA             0xFFFFF400\nset  AT91C_BASE_PIOB             0xFFFFF600\nset  AT91C_BASE_CKGR             0xFFFFFC20\nset  AT91C_BASE_PMC              0xFFFFFC00\nset  AT91C_BASE_RSTC             0xFFFFFD00\nset  AT91C_BASE_RTTC             0xFFFFFD20\nset  AT91C_BASE_PITC             0xFFFFFD30\nset  AT91C_BASE_WDTC             0xFFFFFD40\nset  AT91C_BASE_VREG             0xFFFFFD60\nset  AT91C_BASE_MC          0xFFFFFF00\nset  AT91C_BASE_PDC_SPI1      0xFFFE4100\nset  AT91C_BASE_SPI1          0xFFFE4000\nset  AT91C_BASE_PDC_SPI0      0xFFFE0100\nset  AT91C_BASE_SPI0          0xFFFE0000\nset  AT91C_BASE_PDC_US1       0xFFFC4100\nset  AT91C_BASE_US1           0xFFFC4000\nset  AT91C_BASE_PDC_US0       0xFFFC0100\nset  AT91C_BASE_US0           0xFFFC0000\nset  AT91C_BASE_PDC_SSC       0xFFFD4100\nset  AT91C_BASE_SSC           0xFFFD4000\nset  AT91C_BASE_TWI           0xFFFB8000\nset  AT91C_BASE_PWMC_CH3      0xFFFCC260\nset  AT91C_BASE_PWMC_CH2      0xFFFCC240\nset  AT91C_BASE_PWMC_CH1      0xFFFCC220\nset  AT91C_BASE_PWMC_CH0      0xFFFCC200\nset  AT91C_BASE_PWMC          0xFFFCC000\nset  AT91C_BASE_UDP           0xFFFB0000\nset  AT91C_BASE_TC0         0xFFFA0000\nset  AT91C_BASE_TC1         0xFFFA0040\nset  AT91C_BASE_TC2         0xFFFA0080\nset  AT91C_BASE_TCB             0xFFFA0000\nset  AT91C_BASE_CAN_MB0         0xFFFD0200\nset  AT91C_BASE_CAN_MB1         0xFFFD0220\nset  AT91C_BASE_CAN_MB2         0xFFFD0240\nset  AT91C_BASE_CAN_MB3         0xFFFD0260\nset  AT91C_BASE_CAN_MB4         0xFFFD0280\nset  AT91C_BASE_CAN_MB5         0xFFFD02A0\nset  AT91C_BASE_CAN_MB6         0xFFFD02C0\nset  AT91C_BASE_CAN_MB7         0xFFFD02E0\nset  AT91C_BASE_CAN             0xFFFD0000\nset  AT91C_BASE_EMAC            0xFFFDC000\nset  AT91C_BASE_PDC_ADC         0xFFFD8100\nset  AT91C_BASE_ADC             0xFFFD8000\n\nset AT91C_ID(0)   \"FIQ\"\nset AT91C_ID(1)   \"SYS\"\nset AT91C_ID(2)   \"PIOA\"\nset AT91C_ID(3)   \"PIOB\"\nset AT91C_ID(4)   \"SPI0\"\nset AT91C_ID(5)   \"SPI1\"\nset AT91C_ID(6)   \"US0\"\nset AT91C_ID(7)   \"US1\"\nset AT91C_ID(8)   \"SSC\"\nset AT91C_ID(9)   \"TWI\"\nset AT91C_ID(10)   \"PWMC\"\nset AT91C_ID(11)   \"UDP\"\nset AT91C_ID(12)   \"TC0\"\nset AT91C_ID(13)   \"TC1\"\nset AT91C_ID(14)   \"TC2\"\nset AT91C_ID(15)   \"CAN\"\nset AT91C_ID(16)   \"EMAC\"\nset AT91C_ID(17)   \"ADC\"\nset AT91C_ID(18)   \"\"\nset AT91C_ID(19)   \"\"\nset AT91C_ID(20)   \"\"\nset AT91C_ID(21)   \"\"\nset AT91C_ID(22)   \"\"\nset AT91C_ID(23)   \"\"\nset AT91C_ID(24)   \"\"\nset AT91C_ID(25)   \"\"\nset AT91C_ID(26)   \"\"\nset AT91C_ID(27)   \"\"\nset AT91C_ID(28)   \"\"\nset AT91C_ID(29)   \"\"\nset AT91C_ID(30)   \"IRQ0\"\nset AT91C_ID(31)   \"IRQ1\"\n\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9261.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9261_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9261_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9261_ID_PIOC\t4\t;# Parallel IO Controller C\nset AT91SAM9261_ID_US0\t6\t;# USART 0\nset AT91SAM9261_ID_US1\t7\t;# USART 1\nset AT91SAM9261_ID_US2\t8\t;# USART 2\nset AT91SAM9261_ID_MCI\t9\t;# Multimedia Card Interface\nset AT91SAM9261_ID_UDP\t10\t;# USB Device Port\nset AT91SAM9261_ID_TWI\t11\t;# Two-Wire Interface\nset AT91SAM9261_ID_SPI0\t12\t;# Serial Peripheral Interface 0\nset AT91SAM9261_ID_SPI1\t13\t;# Serial Peripheral Interface 1\nset AT91SAM9261_ID_SSC0\t14\t;# Serial Synchronous Controller 0\nset AT91SAM9261_ID_SSC1\t15\t;# Serial Synchronous Controller 1\nset AT91SAM9261_ID_SSC2\t16\t;# Serial Synchronous Controller 2\nset AT91SAM9261_ID_TC0\t17\t;# Timer Counter 0\nset AT91SAM9261_ID_TC1\t18\t;# Timer Counter 1\nset AT91SAM9261_ID_TC2\t19\t;# Timer Counter 2\nset AT91SAM9261_ID_UHP\t20\t;# USB Host port\nset AT91SAM9261_ID_LCDC\t21\t;# LDC Controller\nset AT91SAM9261_ID_IRQ0\t29\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9261_ID_IRQ1\t30\t;# Advanced Interrupt Controller (IRQ1)\nset AT91SAM9261_ID_IRQ2\t31\t;# Advanced Interrupt Controller (IRQ2)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9261_BASE_TCB0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC1\t\t0xfffa0040\nset AT91SAM9261_BASE_TC2\t\t0xfffa0080\nset AT91SAM9261_BASE_UDP\t\t0xfffa4000\nset AT91SAM9261_BASE_MCI\t\t0xfffa8000\nset AT91SAM9261_BASE_TWI\t\t0xfffac000\nset AT91SAM9261_BASE_US0\t\t0xfffb0000\nset AT91SAM9261_BASE_US1\t\t0xfffb4000\nset AT91SAM9261_BASE_US2\t\t0xfffb8000\nset AT91SAM9261_BASE_SSC0\t\t0xfffbc000\nset AT91SAM9261_BASE_SSC1\t\t0xfffc0000\nset AT91SAM9261_BASE_SSC2\t\t0xfffc4000\nset AT91SAM9261_BASE_SPI0\t\t0xfffc8000\nset AT91SAM9261_BASE_SPI1\t\t0xfffcc000\nset AT91_BASE_SYS\t\t\t0xffffea00\n\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_SDRAMC\t0xffffea00\nset AT91_SMC\t0xffffec00\nset AT91_MATRIX\t0xffffee00\nset AT91_AIC\t0xfffff000\nset AT91_DBGU\t0xfffff200\nset AT91_PIOA\t0xfffff400\nset AT91_PIOB\t0xfffff600\nset AT91_PIOC\t0xfffff800\nset AT91_PMC\t0xfffffc00\nset AT91_RSTC\t0xfffffd00\nset AT91_SHDWC\t0xfffffd10\nset AT91_RTT\t0xfffffd20\nset AT91_PIT\t0xfffffd30\nset AT91_WDT\t0xfffffd40\nset AT91_GPBR\t0xfffffd50\n\nset AT91_USART0\t$AT91SAM9261_BASE_US0\nset AT91_USART1\t$AT91SAM9261_BASE_US1\nset AT91_USART2\t$AT91SAM9261_BASE_US2\n\n\n#\n# Internal Memory.\n#\nset AT91SAM9261_SRAM_BASE\t0x00300000\t;# Internal SRAM base address\nset AT91SAM9261_SRAM_SIZE\t0x00028000\t;# Internal SRAM size (160Kb)\n\nset AT91SAM9261_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9261_ROM_SIZE\t0x00008000\t;# Internal ROM size (32Kb)\n\nset AT91SAM9261_UHP_BASE\t0x00500000\t;# USB Host controller\nset AT91SAM9261_LCDC_BASE\t0x00600000\t;# LDC controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9261\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9261_matrix.cfg",
    "content": "\nset AT91_MATRIX_MCFG\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register #\nset\t\tAT91_MATRIX_RCB0\t[expr {1 << 0}]\t\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t[expr {1 << 1}]\t\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x04}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x08}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x0C}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x10}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x14}]\t;# Slave Configuration Register 4\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {7    << 18}]\t;# Fixed Index of Default Master\n\nset AT91_MATRIX_TCR\t\t[expr {$AT91_MATRIX + 0x24}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_64\t\t[expr {7 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_64\t\t[expr {7 << 4}]\n\nset AT91_MATRIX_EBICSA\t[expr {$AT91_MATRIX + 0x30}]\t;# EBI Chip Select Assignment Register\nset\t\tAT91_MATRIX_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_CS4A_SMC_CF1\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_CS5A_SMC_CF2\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\n\nset AT91_MATRIX_USBPUCR\t[expr {$AT91_MATRIX + 0x34}]\t;# USB Pad Pull-Up Control Register\nset\t\tAT91_MATRIX_USBPUCR_PUON\t[expr {1 << 30}]\t;# USB Device PAD Pull-up Enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9263.cfg",
    "content": "#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9263_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9263_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9263_ID_PIOCDE\t4\t;# Parallel IO Controller C, D and E\nset AT91SAM9263_ID_US0\t7\t;# USART 0\nset AT91SAM9263_ID_US1\t8\t;# USART 1\nset AT91SAM9263_ID_US2\t9\t;# USART 2\nset AT91SAM9263_ID_MCI0\t10\t;# Multimedia Card Interface 0\nset AT91SAM9263_ID_MCI1\t11\t;# Multimedia Card Interface 1\nset AT91SAM9263_ID_CAN\t12\t;# CAN\nset AT91SAM9263_ID_TWI\t13\t;# Two-Wire Interface\nset AT91SAM9263_ID_SPI0\t14\t;# Serial Peripheral Interface 0\nset AT91SAM9263_ID_SPI1\t15\t;# Serial Peripheral Interface 1\nset AT91SAM9263_ID_SSC0\t16\t;# Serial Synchronous Controller 0\nset AT91SAM9263_ID_SSC1\t17\t;# Serial Synchronous Controller 1\nset AT91SAM9263_ID_AC97C\t18\t;# AC97 Controller\nset AT91SAM9263_ID_TCB\t19\t;# Timer Counter 0, 1 and 2\nset AT91SAM9263_ID_PWMC\t20\t;# Pulse Width Modulation Controller\nset AT91SAM9263_ID_EMAC\t21\t;# Ethernet\nset AT91SAM9263_ID_2DGE\t23\t;# 2D Graphic Engine\nset AT91SAM9263_ID_UDP\t24\t;# USB Device Port\nset AT91SAM9263_ID_ISI\t25\t;# Image Sensor Interface\nset AT91SAM9263_ID_LCDC\t26\t;# LCD Controller\nset AT91SAM9263_ID_DMA\t27\t;# DMA Controller\nset AT91SAM9263_ID_UHP\t29\t;# USB Host port\nset AT91SAM9263_ID_IRQ0\t30\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9263_ID_IRQ1\t31\t;# Advanced Interrupt Controller (IRQ1)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9263_BASE_UDP\t\t0xfff78000\nset AT91SAM9263_BASE_TCB0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC1\t\t0xfff7c040\nset AT91SAM9263_BASE_TC2\t\t0xfff7c080\nset AT91SAM9263_BASE_MCI0\t\t0xfff80000\nset AT91SAM9263_BASE_MCI1\t\t0xfff84000\nset AT91SAM9263_BASE_TWI\t\t0xfff88000\nset AT91SAM9263_BASE_US0\t\t0xfff8c000\nset AT91SAM9263_BASE_US1\t\t0xfff90000\nset AT91SAM9263_BASE_US2\t\t0xfff94000\nset AT91SAM9263_BASE_SSC0\t\t0xfff98000\nset AT91SAM9263_BASE_SSC1\t\t0xfff9c000\nset AT91SAM9263_BASE_AC97C\t\t0xfffa0000\nset AT91SAM9263_BASE_SPI0\t\t0xfffa4000\nset AT91SAM9263_BASE_SPI1\t\t0xfffa8000\nset AT91SAM9263_BASE_CAN\t\t0xfffac000\nset AT91SAM9263_BASE_PWMC\t\t0xfffb8000\nset AT91SAM9263_BASE_EMAC\t\t0xfffbc000\nset AT91SAM9263_BASE_ISI\t\t0xfffc4000\nset AT91SAM9263_BASE_2DGE\t\t0xfffc8000\nset AT91_BASE_SYS\t\t\t0xffffe000\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_ECC0\t\t0xffffe000\nset AT91_SDRAMC0\t0xffffe200\nset AT91_SMC0\t\t0xffffe400\nset AT91_ECC1\t\t0xffffe600\nset AT91_SDRAMC1\t0xffffe800\nset AT91_SMC1\t\t0xffffea00\nset AT91_MATRIX\t\t0xffffec00\nset AT91_CCFG\t\t0xffffed10\nset AT91_DBGU\t\t0xffffee00\nset AT91_AIC\t\t0xfffff000\nset AT91_PIOA\t\t0xfffff200\nset AT91_PIOB\t\t0xfffff400\nset AT91_PIOC\t\t0xfffff600\nset AT91_PIOD\t\t0xfffff800\nset AT91_PIOE\t\t0xfffffa00\nset AT91_PMC\t\t0xfffffc00\nset AT91_RSTC\t\t0xfffffd00\nset AT91_SHDWC\t\t0xfffffd10\nset AT91_RTT0\t\t0xfffffd20\nset AT91_PIT\t\t0xfffffd30\nset AT91_WDT\t\t0xfffffd40\nset AT91_RTT1\t\t0xfffffd50\nset AT91_GPBR\t\t0xfffffd60\n\nset AT91_USART0\t$AT91SAM9263_BASE_US0\nset AT91_USART1\t$AT91SAM9263_BASE_US1\nset AT91_USART2\t$AT91SAM9263_BASE_US2\n\nset AT91_SMC\t$AT91_SMC0\nset AT91_SDRAMC\t$AT91_SDRAMC0\n\n#\n# Internal Memory.\n#\nset AT91SAM9263_SRAM0_BASE\t0x00300000\t;# Internal SRAM 0 base address\nset AT91SAM9263_SRAM0_SIZE\t0x00014000\t;# Internal SRAM 0 size (80Kb)\n\nset AT91SAM9263_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9263_ROM_SIZE\t0x00020000\t;# Internal ROM size (128Kb)\n\nset AT91SAM9263_SRAM1_BASE\t0x00500000\t;# Internal SRAM 1 base address\nset AT91SAM9263_SRAM1_SIZE\t0x00004000\t;# Internal SRAM 1 size (16Kb)\n\nset AT91SAM9263_LCDC_BASE\t0x00700000\t;# LCD Controller\nset AT91SAM9263_DMAC_BASE\t0x00800000\t;# DMA Controller\nset AT91SAM9263_UHP_BASE\t0x00a00000\t;# USB Host controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9263\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9263_matrix.cfg",
    "content": "set AT91_MATRIX_MCFG0\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register 0\nset AT91_MATRIX_MCFG1\t[expr {$AT91_MATRIX + 0x04}]\t;# Master Configuration Register 1\nset AT91_MATRIX_MCFG2\t[expr {$AT91_MATRIX + 0x08}]\t;# Master Configuration Register 2\nset AT91_MATRIX_MCFG3\t[expr {$AT91_MATRIX + 0x0C}]\t;# Master Configuration Register 3\nset AT91_MATRIX_MCFG4\t[expr {$AT91_MATRIX + 0x10}]\t;# Master Configuration Register 4\nset AT91_MATRIX_MCFG5\t[expr {$AT91_MATRIX + 0x14}]\t;# Master Configuration Register 5\nset AT91_MATRIX_MCFG6\t[expr {$AT91_MATRIX + 0x18}]\t;# Master Configuration Register 6\nset AT91_MATRIX_MCFG7\t[expr {$AT91_MATRIX + 0x1C}]\t;# Master Configuration Register 7\nset AT91_MATRIX_MCFG8\t[expr {$AT91_MATRIX + 0x20}]\t;# Master Configuration Register 8\nset\t\tAT91_MATRIX_ULBT\t[expr {7 << 0}]\t;# Undefined Length Burst Type\nset\t\t\tAT91_MATRIX_ULBT_INFINITE\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SINGLE\t\t[expr {1 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_FOUR\t\t[expr {2 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_EIGHT\t\t[expr {3 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SIXTEEN\t[expr {4 << 0}]\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x40}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x44}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x48}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x4C}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x50}]\t;# Slave Configuration Register 4\nset AT91_MATRIX_SCFG5\t[expr {$AT91_MATRIX + 0x54}]\t;# Slave Configuration Register 5\nset AT91_MATRIX_SCFG6\t[expr {$AT91_MATRIX + 0x58}]\t;# Slave Configuration Register 6\nset AT91_MATRIX_SCFG7\t[expr {$AT91_MATRIX + 0x5C}]\t;# Slave Configuration Register 7\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {0xf  << 18}]\t;# Fixed Index of Default Master\nset\t\tAT91_MATRIX_ARBT\t\t[expr {3    << 24}]\t;# Arbitration Type\nset\t\t\tAT91_MATRIX_ARBT_ROUND_ROBIN\t[expr {0 << 24}]\nset\t\t\tAT91_MATRIX_ARBT_FIXED_PRIORITY\t[expr {1 << 24}]\n\nset AT91_MATRIX_PRAS0\t[expr {$AT91_MATRIX + 0x80}]\t;# Priority Register A for Slave 0\nset AT91_MATRIX_PRBS0\t[expr {$AT91_MATRIX + 0x84}]\t;# Priority Register B for Slave 0\nset AT91_MATRIX_PRAS1\t[expr {$AT91_MATRIX + 0x88}]\t;# Priority Register A for Slave 1\nset AT91_MATRIX_PRBS1\t[expr {$AT91_MATRIX + 0x8C}]\t;# Priority Register B for Slave 1\nset AT91_MATRIX_PRAS2\t[expr {$AT91_MATRIX + 0x90}]\t;# Priority Register A for Slave 2\nset AT91_MATRIX_PRBS2\t[expr {$AT91_MATRIX + 0x94}]\t;# Priority Register B for Slave 2\nset AT91_MATRIX_PRAS3\t[expr {$AT91_MATRIX + 0x98}]\t;# Priority Register A for Slave 3\nset AT91_MATRIX_PRBS3\t[expr {$AT91_MATRIX + 0x9C}]\t;# Priority Register B for Slave 3\nset AT91_MATRIX_PRAS4\t[expr {$AT91_MATRIX + 0xA0}]\t;# Priority Register A for Slave 4\nset AT91_MATRIX_PRBS4\t[expr {$AT91_MATRIX + 0xA4}]\t;# Priority Register B for Slave 4\nset AT91_MATRIX_PRAS5\t[expr {$AT91_MATRIX + 0xA8}]\t;# Priority Register A for Slave 5\nset AT91_MATRIX_PRBS5\t[expr {$AT91_MATRIX + 0xAC}]\t;# Priority Register B for Slave 5\nset AT91_MATRIX_PRAS6\t[expr {$AT91_MATRIX + 0xB0}]\t;# Priority Register A for Slave 6\nset AT91_MATRIX_PRBS6\t[expr {$AT91_MATRIX + 0xB4}]\t;# Priority Register B for Slave 6\nset AT91_MATRIX_PRAS7\t[expr {$AT91_MATRIX + 0xB8}]\t;# Priority Register A for Slave 7\nset AT91_MATRIX_PRBS7\t[expr {$AT91_MATRIX + 0xBC}]\t;# Priority Register B for Slave 7\nset\t\tAT91_MATRIX_M0PR\t\t[expr {3 << 0}]\t\t;# Master 0 Priority\nset\t\tAT91_MATRIX_M1PR\t\t[expr {3 << 4}]\t\t;# Master 1 Priority\nset\t\tAT91_MATRIX_M2PR\t\t[expr {3 << 8}]\t\t;# Master 2 Priority\nset\t\tAT91_MATRIX_M3PR\t\t[expr {3 << 12}]\t;# Master 3 Priority\nset\t\tAT91_MATRIX_M4PR\t\t[expr {3 << 16}]\t;# Master 4 Priority\nset\t\tAT91_MATRIX_M5PR\t\t[expr {3 << 20}]\t;# Master 5 Priority\nset\t\tAT91_MATRIX_M6PR\t\t[expr {3 << 24}]\t;# Master 6 Priority\nset\t\tAT91_MATRIX_M7PR\t\t[expr {3 << 28}]\t;# Master 7 Priority\nset\t\tAT91_MATRIX_M8PR\t\t[expr {3 << 0}]\t\t;# Master 8 Priority (in Register B)\n\nset AT91_MATRIX_MRCR\t[expr {$AT91_MATRIX + 0x100}]\t;# Master Remap Control Register\nset\t\tAT91_MATRIX_RCB0\t\t[expr {1 << 0}]\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t\t[expr {1 << 1}]\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\nset\t\tAT91_MATRIX_RCB2\t\t[expr {1 << 2}]\nset\t\tAT91_MATRIX_RCB3\t\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_RCB4\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_RCB5\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_RCB6\t\t[expr {1 << 6}]\nset\t\tAT91_MATRIX_RCB7\t\t[expr {1 << 7}]\nset\t\tAT91_MATRIX_RCB8\t\t[expr {1 << 8}]\n\nset AT91_MATRIX_TCMR\t[expr {$AT91_MATRIX + 0x114}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\n\nset AT91_MATRIX_EBI0CSA\t[expr {$AT91_MATRIX + 0x120}]\t;# EBI0 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI0_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI0_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignmen\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI0_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC_CF1\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_EBI0_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC_CF2\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_EBI0_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI0_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n\nset AT91_MATRIX_EBI1CSA\t[expr {$AT91_MATRIX + 0x124}]\t;# EBI1 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI1_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI1_CS2A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI1_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI1_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_init.cfg",
    "content": "uplevel #0 [list source [find chip/atmel/at91/at91sam9_sdramc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pmc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pio.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_rstc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_wdt.cfg]]\n\nproc at91sam9_reset_start { } {\n\n\tarm7_9 fast_memory_access disable\n\n\tjtag_rclk 8\n\thalt\n\twait_halt 10000\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | (5 << 8)}]\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9_reset_init { config } {\n\n\tmww $::AT91_WDT_MR $config(wdt_mr_val)\t;# disable watchdog\n\n\tset ckgr_mor [expr {$::AT91_PMC_MOSCEN | (255 << 8)}]\n\n\tmww $::AT91_CKGR_MOR $ckgr_mor\t;# CKGR_MOR - enable main osc.\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MOSCS}] != $::AT91_PMC_MOSCS } { sleep 1 }\n\n\tset pllar_val\t$::AT91_PMC_PLLA_WR_ERRATA ;# Bit 29 must be 1 when prog\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_OUT}]\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_PLLCOUNT}]\n\tset pllar_val\t[expr {$pllar_val | ($config(master_pll_mul) - 1) << 16}]\n\tset pllar_val\t[expr {$pllar_val | $config(master_pll_div)}]\n\n\tmww $::AT91_CKGR_PLLAR $pllar_val\t ;# CKGR_PLLA - (18.432MHz/13)*141 = 199.9 MHz\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_LOCKA}] != $::AT91_PMC_LOCKA } { sleep 1 }\n\n\t;# PCK/2 = MCK Master Clock from PLLA\n\tset mckr_val\t$::AT91_PMC_CSS_PLLA\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PRES_1}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91SAM9_PMC_MDIV_2}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PDIV_1}]\n\n\tmww $::AT91_PMC_MCKR $mckr_val\t;# PMC_MCKR (MCLK: 0x102 - (CLK/2)MHZ, 0x202 - (CLK/3)MHz)\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MCKRDY}] != $::AT91_PMC_MCKRDY } { sleep 1 }\n\n\t## switch JTAG clock to highspeed clock\n\tjtag_rclk 0\n\n\tarm7_9 dcc_downloads enable\t;# Enable faster DCC downloads\n\tarm7_9 fast_memory_access enable\n\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# user reset enable\n\n\tif { [info exists config(sdram_piod)] } {\n\t\tset pdr_addr\t[expr {$::AT91_PIOD + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOD + $::PIO_PUDR}]\n\t\tset asr_addr\t[expr {$::AT91_PIOD + $::PIO_ASR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t\tmww $asr_addr 0xffff0000\n\t} else {\n\t\tset pdr_addr\t[expr {$::AT91_PIOC + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOC + $::PIO_PUDR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t}\n\n\tmww $config(matrix_ebicsa_addr) $config(matrix_ebicsa_val)\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRAMC_MR Mode register\n\tmww $::AT91_SDRAMC_TR\t$config(sdram_tr_val)\t\t;# SDRAMC_TR - Refresh Timer register\n\tmww $::AT91_SDRAMC_CR\t$config(sdram_cr_val)\t\t;# SDRAMC_CR - Configuration register\n\tmww $::AT91_SDRAMC_MDR\t$::AT91_SDRAMC_MD_SDRAM\t\t;# Memory Device Register -> SDRAM\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_PRECHARGE\t;# SDRAMC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_REFRESH\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_LMR\t\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_TR\t1200\t\t\t\t;# SDRAM_TR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\n\tmww $::AT91_MATRIX 0xf\t\t;# MATRIX_MCFG - REMAP all masters\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_sdramc.cfg",
    "content": "\n# SDRAM Controller (SDRAMC) registers\nset AT91_SDRAMC_MR\t\t[expr {$AT91_SDRAMC + 0x00}]\t;# SDRAM Controller Mode Register\nset\t\tAT91_SDRAMC_MODE\t[expr {0xf << 0}]\t;# Command Mode\nset\t\t\tAT91_SDRAMC_MODE_NORMAL\t\t0\nset\t\t\tAT91_SDRAMC_MODE_NOP\t\t1\nset\t\t\tAT91_SDRAMC_MODE_PRECHARGE\t2\nset\t\t\tAT91_SDRAMC_MODE_LMR\t\t3\nset\t\t\tAT91_SDRAMC_MODE_REFRESH\t4\nset\t\t\tAT91_SDRAMC_MODE_EXT_LMR\t5\nset\t\t\tAT91_SDRAMC_MODE_DEEP\t\t6\n\nset AT91_SDRAMC_TR\t\t[expr {$AT91_SDRAMC + 0x04}]\t;# SDRAM Controller Refresh Timer Register\nset\t\tAT91_SDRAMC_COUNT\t[expr {0xfff << 0}]\t\t;# Refresh Timer Counter\n\nset AT91_SDRAMC_CR\t\t[expr {$AT91_SDRAMC + 0x08}]\t;# SDRAM Controller Configuration Register\nset\t\tAT91_SDRAMC_NC\t\t[expr {3 << 0}]\t\t;# Number of Column Bits\nset\t\t\tAT91_SDRAMC_NC_8\t[expr {0 << 0}]\nset\t\t\tAT91_SDRAMC_NC_9\t[expr {1 << 0}]\nset\t\t\tAT91_SDRAMC_NC_10\t[expr {2 << 0}]\nset\t\t\tAT91_SDRAMC_NC_11\t[expr {3 << 0}]\nset\t\tAT91_SDRAMC_NR\t\t[expr {3 << 2}]\t\t;# Number of Row Bits\nset\t\t\tAT91_SDRAMC_NR_11\t[expr {0 << 2}]\nset\t\t\tAT91_SDRAMC_NR_12\t[expr {1 << 2}]\nset\t\t\tAT91_SDRAMC_NR_13\t[expr {2 << 2}]\nset\t\tAT91_SDRAMC_NB\t\t[expr {1 << 4}]\t\t;# Number of Banks\nset\t\t\tAT91_SDRAMC_NB_2\t[expr {0 << 4}]\nset\t\t\tAT91_SDRAMC_NB_4\t[expr {1 << 4}]\nset\t\tAT91_SDRAMC_CAS\t\t[expr {3 << 5}]\t\t;# CAS Latency\nset\t\t\tAT91_SDRAMC_CAS_1\t[expr {1 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_2\t[expr {2 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_3\t[expr {3 << 5}]\nset\t\tAT91_SDRAMC_DBW\t\t[expr {1 << 7}]\t\t;# Data Bus Width\nset\t\t\tAT91_SDRAMC_DBW_32\t[expr {0 << 7}]\nset\t\t\tAT91_SDRAMC_DBW_16\t[expr {1 << 7}]\nset\t\tAT91_SDRAMC_TWR\t\t[expr {0xf <<  8}]\t\t;# Write Recovery Delay\nset\t\tAT91_SDRAMC_TRC\t\t[expr {0xf << 12}]\t\t;# Row Cycle Delay\nset\t\tAT91_SDRAMC_TRP\t\t[expr {0xf << 16}]\t\t;# Row Precharge Delay\nset\t\tAT91_SDRAMC_TRCD\t[expr {0xf << 20}]\t\t;# Row to Column Delay\nset\t\tAT91_SDRAMC_TRAS\t[expr {0xf << 24}]\t\t;# Active to Precharge Delay\nset\t\tAT91_SDRAMC_TXSR\t[expr {0xf << 28}]\t\t;# Exit Self Refresh to Active Delay\n\nset AT91_SDRAMC_LPR\t\t[expr {$AT91_SDRAMC + 0x10}]\t;# SDRAM Controller Low Power Register\nset\t\tAT91_SDRAMC_LPCB\t\t[expr {3 << 0}]\t;# Low-power Configurations\nset\t\t\tAT91_SDRAMC_LPCB_DISABLE\t\t0\nset\t\t\tAT91_SDRAMC_LPCB_SELF_REFRESH\t\t1\nset\t\t\tAT91_SDRAMC_LPCB_POWER_DOWN\t\t2\nset\t\t\tAT91_SDRAMC_LPCB_DEEP_POWER_DOWN\t3\nset\t\tAT91_SDRAMC_PASR\t\t[expr {7 << 4}]\t;# Partial Array Self Refresh\nset\t\tAT91_SDRAMC_TCSR\t\t[expr {3 << 8}]\t;# Temperature Compensated Self Refresh\nset\t\tAT91_SDRAMC_DS\t\t\t[expr {3 << 10}]\t;# Drive Strength\nset\t\tAT91_SDRAMC_TIMEOUT\t\t[expr {3 << 12}]\t;# Time to define when Low Power Mode is enabled\nset\t\t\tAT91_SDRAMC_TIMEOUT_0_CLK_CYCLES\t[expr {0 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_64_CLK_CYCLES\t[expr {1 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_128_CLK_CYCLES\t[expr {2 << 12}]\n\nset AT91_SDRAMC_IER\t\t[expr {$AT91_SDRAMC + 0x14}]\t;# SDRAM Controller Interrupt Enable Register\nset AT91_SDRAMC_IDR\t\t[expr {$AT91_SDRAMC + 0x18}]\t;# SDRAM Controller Interrupt Disable Register\nset AT91_SDRAMC_IMR\t\t[expr {$AT91_SDRAMC + 0x1C}]\t;# SDRAM Controller Interrupt Mask Register\nset AT91_SDRAMC_ISR\t\t[expr {$AT91_SDRAMC + 0x20}]\t;# SDRAM Controller Interrupt Status Register\nset\t\tAT91_SDRAMC_RES\t\t[expr {1 << 0}]\t\t;# Refresh Error Status\n\nset AT91_SDRAMC_MDR\t\t[expr {$AT91_SDRAMC + 0x24}]\t;# SDRAM Memory Device Register\nset\t\tAT91_SDRAMC_MD\t\t[expr {3 << 0}]\t\t;# Memory Device Type\nset\t\t\tAT91_SDRAMC_MD_SDRAM\t\t0\nset\t\t\tAT91_SDRAMC_MD_LOW_POWER_SDRAM\t1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/at91sam9_smc.cfg",
    "content": "set\t\tAT91_SMC_READMODE\t[expr {1 <<  0}]\t\t;# Read Mode\nset\t\tAT91_SMC_WRITEMODE\t[expr {1 <<  1}]\t\t;# Write Mode\nset\t\tAT91_SMC_EXNWMODE\t[expr {3 <<  4}]\t\t;# NWAIT Mode\nset\t\t\tAT91_SMC_EXNWMODE_DISABLE\t[expr {0 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_FROZEN\t[expr {2 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_READY\t\t[expr {3 << 4}]\nset\t\tAT91_SMC_BAT\t\t[expr {1 <<  8}]\t\t;# Byte Access Type\nset\t\t\tAT91_SMC_BAT_SELECT\t\t[expr {0 << 8}]\nset\t\t\tAT91_SMC_BAT_WRITE\t\t[expr {1 << 8}]\nset\t\tAT91_SMC_DBW\t\t[expr {3 << 12}]\t\t;# Data Bus Width */\nset\t\t\tAT91_SMC_DBW_8\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_SMC_DBW_16\t\t\t[expr {1 << 12}]\nset\t\t\tAT91_SMC_DBW_32\t\t\t[expr {2 << 12}]\nset\t\tAT91_SMC_TDFMODE\t[expr {1 << 20}]\t\t;# TDF Optimization - Enabled\nset\t\tAT91_SMC_PMEN\t\t[expr {1 << 24}]\t\t;# Page Mode Enabled\nset\t\tAT91_SMC_PS\t\t[expr {3 << 28}]\t\t;# Page Size\nset\t\t\tAT91_SMC_PS_4\t\t\t[expr {0 << 28}]\nset\t\t\tAT91_SMC_PS_8\t\t\t[expr {1 << 28}]\nset\t\t\tAT91_SMC_PS_16\t\t\t[expr {2 << 28}]\nset\t\t\tAT91_SMC_PS_32\t\t\t[expr {3 << 28}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/hardware.cfg",
    "content": "# External Memory Map\nset AT91_CHIPSELECT_0\t0x10000000\nset AT91_CHIPSELECT_1\t0x20000000\nset AT91_CHIPSELECT_2\t0x30000000\nset AT91_CHIPSELECT_3\t0x40000000\nset AT91_CHIPSELECT_4\t0x50000000\nset AT91_CHIPSELECT_5\t0x60000000\nset AT91_CHIPSELECT_6\t0x70000000\nset AT91_CHIPSELECT_7\t0x80000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/pmc.tcl",
    "content": "\nif [info exists AT91C_MAINOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 18.432mhz is a common thing...\n    set AT91C_MAINOSC_FREQ 18432000\n}\nglobal AT91C_MAINOSC_FREQ\n\nif [info exists AT91C_SLOWOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 32khz is the norm\n    set AT91C_SLOWOSC_FREQ 32768\n}\nglobal AT91C_SLOWOSC_FREQ\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/rtt.tcl",
    "content": "\nset RTTC_RTMR [expr {$AT91C_BASE_RTTC + 0x00}]\nset RTTC_RTAR [expr {$AT91C_BASE_RTTC + 0x04}]\nset RTTC_RTVR [expr {$AT91C_BASE_RTTC + 0x08}]\nset RTTC_RTSR [expr {$AT91C_BASE_RTTC + 0x0c}]\nglobal RTTC_RTMR\nglobal RTTC_RTAR\nglobal RTTC_RTVR\nglobal RTTC_RTSR\n\nproc show_RTTC_RTMR_helper { NAME ADDR VAL } {\n    set rtpres [expr {$VAL & 0x0ffff}]\n    global BIT16 BIT17\n    if { $rtpres == 0 } {\n\tset rtpres 65536;\n    }\n    global AT91C_SLOWOSC_FREQ\n    # Nasty hack, make this a float by tacking a .0 on the end\n    # otherwise, jim makes the value an integer\n    set f [expr \"$AT91C_SLOWOSC_FREQ.0 / $rtpres.0\"]\n    echo [format \"\\tPrescale value: 0x%04x (%5d) => %f Hz\" $rtpres $rtpres $f]\n    if { $VAL & $BIT16 } {\n\techo \"\\tBit16 -> Alarm IRQ Enabled\"\n    } else {\n\techo \"\\tBit16 -> Alarm IRQ Disabled\"\n    }\n    if { $VAL & $BIT17 } {\n\techo \"\\tBit17 -> RTC Inc IRQ Enabled\"\n    } else {\n\techo \"\\tBit17 -> RTC Inc IRQ Disabled\"\n    }\n    # Bit 18 is write only.\n}\n\nproc show_RTTC_RTSR_helper { NAME ADDR VAL } {\n    global BIT0 BIT1\n    if { $VAL & $BIT0 } {\n\techo \"\\tBit0 -> ALARM PENDING\"\n    } else {\n\techo \"\\tBit0 -> alarm not pending\"\n    }\n    if { $VAL & $BIT1 } {\n\techo \"\\tBit0 -> RTINC PENDING\"\n    } else {\n\techo \"\\tBit0 -> rtinc not pending\"\n    }\n}\n\nproc show_RTTC { } {\n\n    show_mmr32_reg RTTC_RTMR\n    show_mmr32_reg RTTC_RTAR\n    show_mmr32_reg RTTC_RTVR\n    show_mmr32_reg RTTC_RTSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/sam9_smc.cfg",
    "content": "# Setup register\n#\n# ncs_read_setup\n# nrd_setup\n# ncs_write_setup\n# set nwe_setup\n#\n#\n# Pulse register\n#\n# ncs_read_pulse\n# nrd_pulse\n# ncs_write_pulse\n# nwe_pulse\n#\n#\n# Cycle register\n#\n# read_cycle 0\n# write_cycle 0\n#\n#\n# Mode register\n#\n# mode\n# tdf_cycles\nproc sam9_smc_config { cs smc_config } {\n\t;# Setup Register for CS n\n\tset AT91_SMC_SETUP [expr {$::AT91_SMC + 0x00 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_setup) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_setup) << 8}]\n\tset val [expr {$val | $smc_config(nrd_setup)) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_setup) << 24}]\n\tmww $AT91_SMC_SETUP $val\n\n\t;# Pulse Register for CS n\n\tset AT91_SMC_PULSE [expr {$::AT91_SMC + 0x04 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_pulse) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_pulse) << 8}]\n\tset val [expr {$val | $smc_config(nrd_pulse) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_pulse) << 24}]\n\tmww $AT91_SMC_PULSE $val\n\n\t;# Cycle Register for CS n\n\tset AT91_SMC_CYCLE [expr {$::AT91_SMC + 0x08 + $cs * 0x10}]\n\tset val [expr {$smc_config(write_cycle) << 0}]\n\tset val [expr {$val | $smc_config(read_cycle) << 16}]\n\tmww $AT91_SMC_CYCLE $val\n\n\t;# Mode Register for CS n\n\tset AT91_SMC_MODE [expr {$::AT91_SMC + 0x0c + $cs * 0x10}]\n\tset val [expr {$smc_config(mode) << 0}]\n\tset val [expr {$val | $smc_config(tdf_cycles) << 16}]\n\tmww $AT91_SMC_MODE $val\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/atmel/at91/usarts.tcl",
    "content": "# the DBGU and USARTs are 'almost' indentical'\nset DBGU_CR         [expr {$AT91C_BASE_DBGU + 0x00000000}]\nset DBGU_MR         [expr {$AT91C_BASE_DBGU + 0x00000004}]\nset DBGU_IER        [expr {$AT91C_BASE_DBGU + 0x00000008}]\nset DBGU_IDR        [expr {$AT91C_BASE_DBGU + 0x0000000C}]\nset DBGU_IMR        [expr {$AT91C_BASE_DBGU + 0x00000010}]\nset DBGU_CSR        [expr {$AT91C_BASE_DBGU + 0x00000014}]\nset DBGU_RHR        [expr {$AT91C_BASE_DBGU + 0x00000018}]\nset DBGU_THR        [expr {$AT91C_BASE_DBGU + 0x0000001C}]\nset DBGU_BRGR       [expr {$AT91C_BASE_DBGU + 0x00000020}]\n# no RTOR\n# no TTGR\n# no FIDI\n# no NER\nset DBGU_CIDR       [expr {$AT91C_BASE_DBGU + 0x00000040}]\nset DBGU_EXID       [expr {$AT91C_BASE_DBGU + 0x00000044}]\nset DBGU_FNTR       [expr {$AT91C_BASE_DBGU + 0x00000048}]\n\n\nset USx_CR           0x00000000\nset USx_MR           0x00000004\nset USx_IER          0x00000008\nset USx_IDR          0x0000000C\nset USx_IMR          0x00000010\nset USx_CSR          0x00000014\nset USx_RHR          0x00000018\nset USx_THR          0x0000001C\nset USx_BRGR         0x00000020\nset USx_RTOR         0x00000024\nset USx_TTGR         0x00000028\nset USx_FIDI         0x00000040\nset USx_NER          0x00000044\nset USx_IF           0x0000004C\n\n# Create all the uarts that exist..\n# we blow up if there are >9\n\n\nproc show_mmr_USx_MR_helper { NAME ADDR VAL } {\n    # First - just print it\n\n    set x [show_normalize_bitfield $VAL 3 0]\n    if { $x == 0 } {\n\techo \"\\tNormal operation\"\n    } else {\n\techo [format \"\\tNon Normal operation mode: 0x%02x\" $x]\n    }\n\n    set x [show_normalize_bitfield $VAL 11 9]\n    set s \"unknown\"\n    switch -exact $x {\n\t0 { set s \"Even\" }\n\t1 { set s \"Odd\" }\n\t2 { set s \"Force=0\" }\n\t3 { set s \"Force=1\" }\n\t* {\n\t    set $x [expr {$x & 6}]\n\t    switch -exact $x {\n\t\t4 { set s \"None\" }\n\t\t6 { set s \"Multidrop Mode\" }\n\t    }\n\t}\n    }\n    echo [format \"\\tParity: %s \" $s]\n\n    set x [expr {5 + [show_normalize_bitfield $VAL 7 6]}]\n    echo [format \"\\tDatabits: %d\" $x]\n\n    set x [show_normalize_bitfield $VAL 13 12]\n    switch -exact $x {\n\t0 { echo \"\\tStop bits: 1\" }\n\t1 { echo \"\\tStop bits: 1.5\" }\n\t2 { echo \"\\tStop bits: 2\" }\n\t3 { echo \"\\tStop bits: Illegal/Reserved\" }\n    }\n}\n\n# For every possbile usart...\nforeach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } {\n    set n AT91C_BASE_[set WHO]\n    set str \"\"\n\n    # Only if it exists on the chip\n    if [ info exists $n ] {\n\t# Hence: $n - is like AT91C_BASE_USx\n\t# For every sub-register\n\tforeach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF}\t{\n\t    # vn = variable name\n\t    set vn [set WHO]_[set REG]\n\t    # vn = USx_IER\n\t    # vv = variable value\n\t    set vv [expr \"$$n + [set USx_[set REG]]\"]\n\t    # And VV is the address in memory of that register\n\n\n\t    # make that VN a GLOBAL so others can find it\n\t    global $vn\n\t    set $vn $vv\n\n\t    # Create a command for this specific register.\n\t    proc show_$vn { } \"show_mmr32_reg $vn\"\n\n\t    # Add this command to the Device(as a whole) command\n\t    set str \"$str\\nshow_$vn\"\n\t}\n\t# Now - create the DEVICE(as a whole) command\n\tset fn show_$WHO\n\tproc $fn { } $str\n    }\n}\n\n# The Debug Uart is special..\nset str \"\"\n\n\n# For every sub-register\nforeach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR\n    DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} {\n\n    # Create a command for this specific register.\n    proc show_$REG { } \"show_mmr32_reg $REG\"\n\n    # Add this command to the Device(as a whole) command\n    set str \"$str\\nshow_$REG\"\n}\n\n# Now - create the DEVICE(as a whole) command\nproc show_DBGU { } $str\n\nunset str\n\nproc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/spear/quirk_no_srst.tcl",
    "content": "# Quirks to bypass missing SRST on JTAG connector\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# For boards that have JTAG SRST not connected.\n# We use \"arm9 vector_catch reset\" to catch button reset event.\n\n\n$_TARGETNAME configure -event reset-assert sp_reset_assert\n$_TARGETNAME configure -event reset-deassert-post sp_reset_deassert_post\n\n# keeps the name of the SPEAr target\nglobal sp_target_name\nset sp_target_name $_TARGETNAME\n\n# Keeps the argument of \"reset\" command (run, init, halt).\nglobal sp_reset_mode\nset sp_reset_mode \"\"\n\n# Helper procedure. Returns 0 is target is halted.\nproc sp_is_halted {} {\n\tglobal sp_target_name\n\n\treturn [expr {[string compare [$sp_target_name curstate] \"halted\" ] == 0}]\n}\n\n# wait for reset button to be pressed, causing CPU to get halted\nproc sp_reset_deassert_post {} {\n\tglobal sp_reset_mode\n\n\tset bar(0) |\n\tset bar(1) /\n\tset bar(2) -\n\tset bar(3) \\\\\n\n\tpoll on\n\techo \"====> Press reset button on the board <====\"\n\tfor {set i 0} { [sp_is_halted] == 0 } { set i [expr {$i + 1}]} {\n\t\techo -n \"$bar([expr {$i & 3}])\\r\"\n\t\tsleep 200\n\t}\n\n\t# Remove catch reset event\n\tarm9 vector_catch none\n\n\t# CPU is halted, but we typed \"reset run\" ...\n\tif { [string compare $sp_reset_mode \"run\"] == 0 } {\n\t\tresume\n\t}\n}\n\n# Override reset-assert, since no SRST available\n# Catch reset event\nproc sp_reset_assert {} {\n\tarm9 vector_catch reset\n}\n\n# Override default init_reset{mode} to catch parameter \"mode\"\nproc init_reset {mode} {\n\tglobal sp_reset_mode\n\n\tset sp_reset_mode $mode\n\n\t# We need to detect CPU get halted, so exit from halt\n\tif { [sp_is_halted] } {\n\t\techo \"Resuming CPU to detect reset\"\n\t\tresume\n\t}\n\n\t# Execute default init_reset{mode}\n\tjtag arp_init-reset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/spear/spear3xx.tcl",
    "content": "# Generic init scripts for all ST SPEAr3xx family\n# http://www.st.com/spear\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Initialize internal clock\n# Default:\n# - Crystal =  24 MHz\n# - PLL1    = 332 MHz\n# - PLL2    = 332 MHz\n# - CPU_CLK = 332 MHz\n# - DDR_CLK = 332 MHz async\n# - HCLK    = 166 MHz\n# - PCLK    =  83 MHz\nproc sp3xx_clock_default {} {\n\tmww 0xfca00000 0x00000002\t;# set sysclk slow\n\tmww 0xfca00014 0x0ffffff8\t;# set pll timeout to minimum (100us ?!?)\n\n\t# DDRCORE disable to change frequency\n\tset val [expr {([mrw 0xfca8002c] & ~0x20000000) | 0x40000000}]\n\tmww 0xfca8002c $val\n\tmww 0xfca8002c $val ;# Yes, write twice!\n\n\t# programming PLL1\n\tmww 0xfca8000c 0xa600010c\t;# M=166 P=1 N=12\n\tmww 0xfca80008 0x00001c0a\t;# power down\n\tmww 0xfca80008 0x00001c0e\t;# enable\n\tmww 0xfca80008 0x00001c06\t;# strobe\n\tmww 0xfca80008 0x00001c0e\n\twhile { [expr {[mrw 0xfca80008] & 0x01}] == 0x00 } { sleep 1 }\n\n\t# programming PLL2\n\tmww 0xfca80018 0xa600010c\t;# M=166, P=1, N=12\n\tmww 0xfca80014 0x00001c0a\t;# power down\n\tmww 0xfca80014 0x00001c0e\t;# enable\n\tmww 0xfca80014 0x00001c06\t;# strobe\n\tmww 0xfca80014 0x00001c0e\n\twhile { [expr {[mrw 0xfca80014] & 0x01}] == 0x00 } { sleep 1 }\n\n\tmww 0xfca80028 0x00000082\t;# enable plltimeen\n\tmww 0xfca80024 0x00000511\t;# set hclkdiv=\"/2\" & pclkdiv=\"/2\"\n\n\tmww 0xfca00000 0x00000004\t;# setting SYSCTL to NORMAL mode\n\twhile { [expr {[mrw 0xfca00000] & 0x20}] != 0x20 } { sleep 1 }\n\n\t# Select source of DDR clock\n\t#mmw 0xfca80020 0x10000000 0x70000000 ;# PLL1\n\tmmw 0xfca80020 0x30000000 0x70000000 ;# PLL2\n\n\t# DDRCORE enable after change frequency\n\tmmw 0xfca8002c 0x20000000 0x00000000\n}\n\nproc sp3xx_common_init {} {\n\tmww 0xfca8002c 0xfffffff8\t;# enable clock of all peripherals\n\tmww 0xfca80038 0x00000000\t;# remove reset of all peripherals\n\n\tmww 0xfca80034 0x0000ffff\t;# enable all RAS clocks\n\tmww 0xfca80040 0x00000000\t;# remove all RAS resets\n\n\tmww 0xfca800e4 0x78000008\t;# COMP1V8_REG\n\tmww 0xfca800ec 0x78000008\t;# COMP3V3_REG\n\n\tmww 0xfc000000 0x10000f5f\t;# init SMI and set HW mode\n\tmww 0xfc000000 0x00000f5f\n\n\t# Initialize Bus Interconnection Matrix\n\t# All ports Round-Robin and lowest priority\n\tmww 0xfca8007c 0x80000007\n\tmww 0xfca80080 0x80000007\n\tmww 0xfca80084 0x80000007\n\tmww 0xfca80088 0x80000007\n\tmww 0xfca8008c 0x80000007\n\tmww 0xfca80090 0x80000007\n\tmww 0xfca80094 0x80000007\n\tmww 0xfca80098 0x80000007\n\tmww 0xfca8009c 0x80000007\n}\n\n\n# Specific init scripts for ST SPEAr300\nproc sp300_init {} {\n\tmww 0x99000000 0x00003fff\t;# RAS function enable\n}\n\n\n# Specific init scripts for ST SPEAr310\nproc sp310_init {} {\n\tmww 0xb4000008 0x00002ff4\t;# RAS function enable\n\n\tmww 0xfca80050 0x00000001\t;# Enable clk mem port 1\n\n\tmww 0xfca8013c 0x2f7bc210\t;# plgpio_pad_drv\n\tmww 0xfca80140 0x017bdef6\n}\n\nproc sp310_emi_init {} {\n\t# set EMI pad strength\n\tmmw 0xfca80134 0x0e000000 0x00000000\n\tmmw 0xfca80138 0x0e739ce7 0x00000000\n\tmmw 0xfca8013c 0x00039ce7 0x00000000\n\n\t# set safe EMI timing as in BootROM\n\t#mww 0x4f000000 0x0000000f\t;# tAP_0_reg\n\t#mww 0x4f000004 0x00000000\t;# tSDP_0_reg\n\t#mww 0x4f000008 0x000000ff\t;# tDPw_0_reg\n\t#mww 0x4f00000c 0x00000111\t;# tDPr_0_reg\n\t#mww 0x4f000010 0x00000002\t;# tDCS_0_reg\n\n\t# set fast EMI timing as in Linux\n\tmww 0x4f000000 0x00000010\t;# tAP_0_reg\n\tmww 0x4f000004 0x00000005\t;# tSDP_0_reg\n\tmww 0x4f000008 0x0000000a\t;# tDPw_0_reg\n\tmww 0x4f00000c 0x0000000a\t;# tDPr_0_reg\n\tmww 0x4f000010 0x00000005\t;# tDCS_0_re\n\n\t# 32bit wide, 8/16/32bit access\n\tmww 0x4f000014 0x0000000e\t;# control_0_reg\n\tmww 0x4f000094 0x0000003f\t;# ack_reg\n}\n\n\n# Specific init scripts for ST SPEAr320\nproc sp320_init {} {\n\tmww 0xb300000c 0xffffac04\t;# RAS function enable\n\tmww 0xb3000010 0x00000001\t;# RAS mode select\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/spear/spear3xx_ddr.tcl",
    "content": "# Init scripts to configure DDR controller of SPEAr3xx\n# http://www.st.com/spear\n# Original values taken from XLoader source code\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\nproc sp3xx_ddr_init {ddr_type {ddr_chips 1}} {\n\tif { $ddr_chips != 1 && $ddr_chips != 2 } {\n\t\terror \"Only 1 or 2 DDR chips permitted. Wrong value \"$ddr_chips\n\t}\n\n\tif { $ddr_type == \"mt47h64m16_3_333_cl5_async\" } {\n\t\tddr_spr3xx_mt47h64m16_3_333_cl5_async $ddr_chips\n\t\tset ddr_size 0x08000000\n\t## add here new DDR chip definition. Prototype:\n\t#} elseif { $ddr_type == \"?????\" } {\n\t#\t????? $ddr_chips\n\t#\tset ddr_size 0x?????\n\t} else {\n\t\terror \"sp3xx_ddr_init: unrecognized DDR type \"$ddr_type\n\t}\n\n\t# MPMC START\n\tmww 0xfc60001c 0x01000100\n\n\tif { $ddr_chips == 2 } {\n\t\techo [format \\\n\t\t\t\"Double chip DDR memory. Total memory size 0x%08x byte\" \\\n\t\t\t[expr {2 * $ddr_size}]]\n\t} else {\n\t\techo [format \\\n\t\t\t\"Single chip DDR memory. Memory size 0x%08x byte\" \\\n\t\t\t$ddr_size]\n\t}\n}\n\n\n# from Xloader file ddr/spr300_mt47h64m16_3_333_cl5_async.S\nproc ddr_spr3xx_mt47h64m16_3_333_cl5_async {ddr_chips} {\n\t# DDR_PAD_REG\n\tmww 0xfca800f0 0x00003aa5\n\n\t# Use \"1:2 sync\" only when DDR clock source is PLL1 and\n\t# HCLK is half of PLL1\n\tmww 0xfc600000 0x00000001\t;# MEMCTL_AHB_SET_00 # This is async\n\tmww 0xfc600004 0x00000000\t;# MEMCTL_AHB_SET_01\n#\tmww 0xfc600000 0x02020201\t;# MEMCTL_AHB_SET_00 # This is 1:2 sync\n#\tmww 0xfc600004 0x02020202\t;# MEMCTL_AHB_SET_01\n\n\tmww 0xfc600008 0x01000000\t;# MEMCTL_RFSH_SET_00\n\tmww 0xfc60000c 0x00000101\t;# MEMCTL_DLL_SET_00\n\tmww 0xfc600010 0x00000101\t;# MEMCTL_GP_00\n\tmww 0xfc600014 0x01000000\t;# MEMCTL_GP_01\n\tmww 0xfc600018 0x00010001\t;# MEMCTL_GP_02\n\tmww 0xfc60001c 0x00000100\t;# MEMCTL_GP_03\n\tmww 0xfc600020 0x00010001\t;# MEMCTL_GP_04\n\tif { $ddr_chips == 2 } {\n\t\tmww 0xfc600024 0x01020203\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x01000102\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000202\t;# MEMCTL_AHB_SET_02\n\t} else {\n\t\tmww 0xfc600024 0x00000201\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x02000001\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000201\t;# MEMCTL_AHB_SET_02\n\t}\n\tmww 0xfc600030 0x04040105\t;# MEMCTL_AHB_SET_03\n\tmww 0xfc600034 0x03030302\t;# MEMCTL_AHB_SET_04\n\tmww 0xfc600038 0x02040101\t;# MEMCTL_AHB_SET_05\n\tmww 0xfc60003c 0x00000002\t;# MEMCTL_AHB_SET_06\n\tmww 0xfc600044 0x03000405\t;# MEMCTL_DQS_SET_0\n\tmww 0xfc600048 0x03040002\t;# MEMCTL_TIME_SET_01\n\tmww 0xfc60004c 0x04000305\t;# MEMCTL_TIME_SET_02\n\tmww 0xfc600050 0x0505053f\t;# MEMCTL_AHB_RELPR_00\n\tmww 0xfc600054 0x05050505\t;# MEMCTL_AHB_RELPR_01\n\tmww 0xfc600058 0x04040405\t;# MEMCTL_AHB_RELPR_02\n\tmww 0xfc60005c 0x04040404\t;# MEMCTL_AHB_RELPR_03\n\tmww 0xfc600060 0x03030304\t;# MEMCTL_AHB_RELPR_04\n\tmww 0xfc600064 0x03030303\t;# MEMCTL_AHB_RELPR_05\n\tmww 0xfc600068 0x02020203\t;# MEMCTL_AHB_RELPR_06\n\tmww 0xfc60006c 0x02020202\t;# MEMCTL_AHB_RELPR_07\n\tmww 0xfc600070 0x01010102\t;# MEMCTL_AHB_RELPR_08\n\tmww 0xfc600074 0x01010101\t;# MEMCTL_AHB_RELPR_09\n\tmww 0xfc600078 0x00000001\t;# MEMCTL_AHB_RELPR_10\n\tmww 0xfc600088 0x0a0c0a00\t;# MEMCTL_DQS_SET_1\n\tmww 0xfc60008c 0x0000023f\t;# MEMCTL_GP_07\n\tmww 0xfc600090 0x00050a00\t;# MEMCTL_GP_08\n\tmww 0xfc600094 0x11000000\t;# MEMCTL_GP_09\n\tmww 0xfc600098 0x00001302\t;# MEMCTL_GP_10\n\tmww 0xfc60009c 0x00001c1c\t;# MEMCTL_DLL_SET_01\n\tmww 0xfc6000a0 0x7c000000\t;# MEMCTL_DQS_OUT_SHIFT\n\tmww 0xfc6000a4 0x005c0000\t;# MEMCTL_WR_DQS_SHIFT\n\tmww 0xfc6000a8 0x2b050e00\t;# MEMCTL_TIME_SET_03\n\tmww 0xfc6000ac 0x00640064\t;# MEMCTL_AHB_PRRLX_00\n\tmww 0xfc6000b0 0x00640064\t;# MEMCTL_AHB_PRRLX_01\n\tmww 0xfc6000b4 0x00000064\t;# MEMCTL_AHB_PRRLX_02\n\tmww 0xfc6000b8 0x00000000\t;# MEMCTL_OUTRANGE_LGTH\n\tmww 0xfc6000bc 0x00200020\t;# MEMCTL_AHB_RW_SET_00\n\tmww 0xfc6000c0 0x00200020\t;# MEMCTL_AHB_RW_SET_01\n\tmww 0xfc6000c4 0x00200020\t;# MEMCTL_AHB_RW_SET_02\n\tmww 0xfc6000c8 0x00200020\t;# MEMCTL_AHB_RW_SET_03\n\tmww 0xfc6000cc 0x00200020\t;# MEMCTL_AHB_RW_SET_04\n\tmww 0xfc6000d8 0x00000a24\t;# MEMCTL_TREF\n\tmww 0xfc6000dc 0x00000000\t;# MEMCTL_EMRS3_DATA\n\tmww 0xfc6000e0 0x5b1c00c8\t;# MEMCTL_TIME_SET_04\n\tmww 0xfc6000e4 0x00c8002e\t;# MEMCTL_TIME_SET_05\n\tmww 0xfc6000e8 0x00000000\t;# MEMCTL_VERSION\n\tmww 0xfc6000ec 0x0001046b\t;# MEMCTL_TINIT\n\tmww 0xfc6000f0 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_01\n\tmww 0xfc6000f4 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_02\n\tmww 0xfc600104 0x001c0000\t;# MEMCTL_DLL_DQS_DELAY_BYPASS_0\n\tmww 0xfc600108 0x0019001c\t;# MEMCTL_DLL_SET_02\n\tmww 0xfc60010c 0x00100000\t;# MEMCTL_DLL_SET_03\n\tmww 0xfc600110 0x001e007a\t;# MEMCTL_DQS_SET_2\n\tmww 0xfc600188 0x00000000\t;# MEMCTL_USER_DEF_REG_0\n\tmww 0xfc60018c 0x00000000\t;# MEMCTL_USER_DEF_REG_1\n\tmww 0xfc600190 0x01010001\t;# MEMCTL_GP_11\n\tmww 0xfc600194 0x01000000\t;# MEMCTL_GP_12\n\tmww 0xfc600198 0x00000001\t;# MEMCTL_GP_13\n\tmww 0xfc60019c 0x00400000\t;# MEMCTL_GP_14\n\tmww 0xfc6001a0 0x00000000\t;# MEMCTL_EMRS2_DATA_X\n\tmww 0xfc6001a4 0x00000000\t;# MEMCTL_LWPWR_CNT\n\tmww 0xfc6001a8 0x00000000\t;# MEMCTL_LWPWR_REG\n\tmww 0xfc6001ac 0x00860000\t;# MEMCTL_GP_15\n\tmww 0xfc6001b0 0x00000002\t;# MEMCTL_TPDEX\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/stm32/stm32.tcl",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/cortex_m3.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nsource [find chip/st/stm32/stm32_regs.tcl]\nsource [find chip/st/stm32/stm32_rcc.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/stm32/stm32_rcc.tcl",
    "content": "\nset RCC_CR            [expr {$RCC_BASE + 0x00}]\nset RCC_CFGR          [expr {$RCC_BASE + 0x04}]\nset RCC_CIR           [expr {$RCC_BASE + 0x08}]\nset RCC_APB2RSTR      [expr {$RCC_BASE + 0x0c}]\nset RCC_APB1RSTR      [expr {$RCC_BASE + 0x10}]\nset RCC_AHBENR        [expr {$RCC_BASE + 0x14}]\nset RCC_APB2ENR       [expr {$RCC_BASE + 0x18}]\nset RCC_APB1ENR       [expr {$RCC_BASE + 0x1c}]\nset RCC_BDCR          [expr {$RCC_BASE + 0x20}]\nset RCC_CSR           [expr {$RCC_BASE + 0x24}]\n\n\nproc show_RCC_CR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CR] } msg ] {\n\terror $msg\n    }\n\n    show_mmr_bitfield  0  0 $val HSI      { OFF ON }\n    show_mmr_bitfield  1  1 $val HSIRDY   { NOTRDY RDY  }\n    show_mmr_bitfield  7  3 $val HSITRIM  { _NUMBER_ }\n    show_mmr_bitfield 15  8 $val HSICAL   { _NUMBER_ }\n    show_mmr_bitfield 16 16 $val HSEON    { OFF ON }\n    show_mmr_bitfield 17 17 $val HSERDY   { NOTRDY RDY  }\n    show_mmr_bitfield 18 18 $val HSEBYP   { NOTBYPASSED BYPASSED }\n    show_mmr_bitfield 19 19 $val CSSON    { OFF ON }\n    show_mmr_bitfield 24 24 $val PLLON    { OFF ON }\n    show_mmr_bitfield 25 25 $val PLLRDY   { NOTRDY RDY }\n}\n\nproc show_RCC_CFGR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CFGR] } msg ] {\n\terror $msg\n    }\n\n\n    show_mmr_bitfield  1  0 $val  SW     { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  3  2 $val  SWS    { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  7  4 $val  HPRE   { sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_2 sysclk_div_4 sysclk_div_8 sysclk_div_16 sysclk_div_64 sysclk_div_128 sysclk_div_256 sysclk_div_512 }\n    show_mmr_bitfield 10  8 $val  PPRE1  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 13 11 $val  PPRE2  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 15 14 $val  ADCPRE { pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div2 pclk2_div4 pclk2_div8 pclk2_div16 }\n    show_mmr_bitfield 16 16 $val  PLLSRC { HSI_div_2 HSE }\n    show_mmr_bitfield 17 17 $val  PLLXTPRE { hse_div1 hse_div2 }\n    show_mmr_bitfield 21 18 $val  PLLMUL { x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x16 }\n    show_mmr_bitfield 22 22 $val  USBPRE { div1 div1_5 }\n    show_mmr_bitfield 26 24 $val  MCO    { none none none none SysClk HSI HSE PLL_div2 }\n}\n\n\nproc show_RCC_CIR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CIR] } msg ] {\n\terror $msg\n    }\n\n}\n\nproc show_RCC_APB2RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2RSTR] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB1RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1RSTR] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) uart5\n    set bits(19) uart4\n    set bits(18) uart3\n    set bits(17) uart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_AHBENR   { } {\n    if [ catch { set val [ show_mmr32_reg RCC_AHBENR  ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) xxx\n    set bits(14) xxx\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) xxx\n    set bits(10) sdio\n    set bits(9) xxx\n    set bits(8) fsmc\n    set bits(7) xxx\n    set bits(6) crce\n    set bits(5) xxx\n    set bits(4) flitf\n    set bits(3) xxx\n    set bits(2) sram\n    set bits(1) dma2\n    set bits(0) dma1\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB2ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_APB1ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) usart5\n    set bits(19) usart4\n    set bits(18) usart3\n    set bits(17) usart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_BDCR     { } {\n    if [ catch { set val [ show_mmr32_reg RCC_BDCR    ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lseon\n    set bits(1) lserdy\n    set bits(2) lsebyp\n    set bits(8) rtcsel0\n    set bits(9) rtcsel1\n    set bits(15) rtcen\n    set bits(16) bdrst\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_CSR      { } {\n    if [ catch { set val [ show_mmr32_reg RCC_CSR     ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lsion\n    set bits(1) lsirdy\n    set bits(24) rmvf\n    set bits(26) pin\n    set bits(27) por\n    set bits(28) sft\n    set bits(29) iwdg\n    set bits(30) wwdg\n    set bits(31) lpwr\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC { } {\n\n    show_RCC_CR\n    show_RCC_CFGR\n    show_RCC_CIR\n    show_RCC_APB2RSTR\n    show_RCC_APB1RSTR\n    show_RCC_AHBENR\n    show_RCC_APB2ENR\n    show_RCC_APB1ENR\n    show_RCC_BDCR\n    show_RCC_CSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/st/stm32/stm32_regs.tcl",
    "content": "# /* Peripheral and SRAM base address in the alias region */\nset PERIPH_BB_BASE        0x42000000\nset SRAM_BB_BASE          0x22000000\n\n# /*Peripheral and SRAM base address in the bit-band region */\nset SRAM_BASE             0x20000000\nset PERIPH_BASE           0x40000000\n\n# /*FSMC registers base address */\nset FSMC_R_BASE           0xA0000000\n\n# /*Peripheral memory map */\nset APB1PERIPH_BASE       [set PERIPH_BASE]\nset APB2PERIPH_BASE       [expr {$PERIPH_BASE + 0x10000}]\nset AHBPERIPH_BASE        [expr {$PERIPH_BASE + 0x20000}]\n\nset TIM2_BASE             [expr {$APB1PERIPH_BASE + 0x0000}]\nset TIM3_BASE             [expr {$APB1PERIPH_BASE + 0x0400}]\nset TIM4_BASE             [expr {$APB1PERIPH_BASE + 0x0800}]\nset TIM5_BASE             [expr {$APB1PERIPH_BASE + 0x0C00}]\nset TIM6_BASE             [expr {$APB1PERIPH_BASE + 0x1000}]\nset TIM7_BASE             [expr {$APB1PERIPH_BASE + 0x1400}]\nset RTC_BASE              [expr {$APB1PERIPH_BASE + 0x2800}]\nset WWDG_BASE             [expr {$APB1PERIPH_BASE + 0x2C00}]\nset IWDG_BASE             [expr {$APB1PERIPH_BASE + 0x3000}]\nset SPI2_BASE             [expr {$APB1PERIPH_BASE + 0x3800}]\nset SPI3_BASE             [expr {$APB1PERIPH_BASE + 0x3C00}]\nset USART2_BASE           [expr {$APB1PERIPH_BASE + 0x4400}]\nset USART3_BASE           [expr {$APB1PERIPH_BASE + 0x4800}]\nset UART4_BASE            [expr {$APB1PERIPH_BASE + 0x4C00}]\nset UART5_BASE            [expr {$APB1PERIPH_BASE + 0x5000}]\nset I2C1_BASE             [expr {$APB1PERIPH_BASE + 0x5400}]\nset I2C2_BASE             [expr {$APB1PERIPH_BASE + 0x5800}]\nset CAN_BASE              [expr {$APB1PERIPH_BASE + 0x6400}]\nset BKP_BASE              [expr {$APB1PERIPH_BASE + 0x6C00}]\nset PWR_BASE              [expr {$APB1PERIPH_BASE + 0x7000}]\nset DAC_BASE              [expr {$APB1PERIPH_BASE + 0x7400}]\n\nset AFIO_BASE             [expr {$APB2PERIPH_BASE + 0x0000}]\nset EXTI_BASE             [expr {$APB2PERIPH_BASE + 0x0400}]\nset GPIOA_BASE            [expr {$APB2PERIPH_BASE + 0x0800}]\nset GPIOB_BASE            [expr {$APB2PERIPH_BASE + 0x0C00}]\nset GPIOC_BASE            [expr {$APB2PERIPH_BASE + 0x1000}]\nset GPIOD_BASE            [expr {$APB2PERIPH_BASE + 0x1400}]\nset GPIOE_BASE            [expr {$APB2PERIPH_BASE + 0x1800}]\nset GPIOF_BASE            [expr {$APB2PERIPH_BASE + 0x1C00}]\nset GPIOG_BASE            [expr {$APB2PERIPH_BASE + 0x2000}]\nset ADC1_BASE             [expr {$APB2PERIPH_BASE + 0x2400}]\nset ADC2_BASE             [expr {$APB2PERIPH_BASE + 0x2800}]\nset TIM1_BASE             [expr {$APB2PERIPH_BASE + 0x2C00}]\nset SPI1_BASE             [expr {$APB2PERIPH_BASE + 0x3000}]\nset TIM8_BASE             [expr {$APB2PERIPH_BASE + 0x3400}]\nset USART1_BASE           [expr {$APB2PERIPH_BASE + 0x3800}]\nset ADC3_BASE             [expr {$APB2PERIPH_BASE + 0x3C00}]\n\nset SDIO_BASE             [expr {$PERIPH_BASE + 0x18000}]\n\nset DMA1_BASE             [expr {$AHBPERIPH_BASE + 0x0000}]\nset DMA1_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0008}]\nset DMA1_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x001C}]\nset DMA1_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0030}]\nset DMA1_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0044}]\nset DMA1_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0058}]\nset DMA1_Channel6_BASE    [expr {$AHBPERIPH_BASE + 0x006C}]\nset DMA1_Channel7_BASE    [expr {$AHBPERIPH_BASE + 0x0080}]\nset DMA2_BASE             [expr {$AHBPERIPH_BASE + 0x0400}]\nset DMA2_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0408}]\nset DMA2_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x041C}]\nset DMA2_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0430}]\nset DMA2_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0444}]\nset DMA2_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0458}]\nset RCC_BASE              [expr {$AHBPERIPH_BASE + 0x1000}]\nset CRC_BASE              [expr {$AHBPERIPH_BASE + 0x3000}]\n\n# /*Flash registers base address */\nset FLASH_R_BASE          [expr {$AHBPERIPH_BASE + 0x2000}]\n# /*Flash Option Bytes base address */\nset OB_BASE               0x1FFFF800\n\n# /*FSMC Bankx registers base address */\nset FSMC_Bank1_R_BASE     [expr {$FSMC_R_BASE + 0x0000}]\nset FSMC_Bank1E_R_BASE    [expr {$FSMC_R_BASE + 0x0104}]\nset FSMC_Bank2_R_BASE     [expr {$FSMC_R_BASE + 0x0060}]\nset FSMC_Bank3_R_BASE     [expr {$FSMC_R_BASE + 0x0080}]\nset FSMC_Bank4_R_BASE     [expr {$FSMC_R_BASE + 0x00A0}]\n\n# /*Debug MCU registers base address */\nset DBGMCU_BASE           0xE0042000\n\n# /*System Control Space memory map */\nset SCS_BASE              0xE000E000\n\nset SysTick_BASE          [expr {$SCS_BASE + 0x0010}]\nset NVIC_BASE             [expr {$SCS_BASE + 0x0100}]\nset SCB_BASE              [expr {$SCS_BASE + 0x0D00}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/ti/lm3s/lm3s.tcl",
    "content": "source [find chip/ti/lm3s/lm3s_regs.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/chip/ti/lm3s/lm3s_regs.tcl",
    "content": "#*****************************************************************************\n#\n# The following are defines for the System Control register addresses.\n#\n#*****************************************************************************\n\nset SYSCTL_DID0             0x400FE000  ;# Device Identification 0\nset SYSCTL_DID1             0x400FE004  ;# Device Identification 1\nset SYSCTL_DC0              0x400FE008  ;# Device Capabilities 0\nset SYSCTL_DC1              0x400FE010  ;# Device Capabilities 1\nset SYSCTL_DC2              0x400FE014  ;# Device Capabilities 2\nset SYSCTL_DC3              0x400FE018  ;# Device Capabilities 3\nset SYSCTL_DC4              0x400FE01C  ;# Device Capabilities 4\nset SYSCTL_DC5              0x400FE020  ;# Device Capabilities 5\nset SYSCTL_DC6              0x400FE024  ;# Device Capabilities 6\nset SYSCTL_DC7              0x400FE028  ;# Device Capabilities 7\nset SYSCTL_DC8              0x400FE02C  ;# Device Capabilities 8 ADC\n                                        ;# Channels\nset SYSCTL_PBORCTL          0x400FE030  ;# Brown-Out Reset Control\nset SYSCTL_LDOPCTL          0x400FE034  ;# LDO Power Control\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\nset SYSCTL_RIS              0x400FE050  ;# Raw Interrupt Status\nset SYSCTL_IMC              0x400FE054  ;# Interrupt Mask Control\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and\n                                        ;# Clear\nset SYSCTL_RESC             0x400FE05C  ;# Reset Cause\nset SYSCTL_RCC              0x400FE060  ;# Run-Mode Clock Configuration\nset SYSCTL_PLLCFG           0x400FE064  ;# XTAL to PLL Translation\nset SYSCTL_GPIOHSCTL        0x400FE06C  ;# GPIO High-Speed Control\nset SYSCTL_GPIOHBCTL        0x400FE06C  ;# GPIO High-Performance Bus\n                                        ;# Control\nset SYSCTL_RCC2             0x400FE070  ;# Run-Mode Clock Configuration 2\nset SYSCTL_MOSCCTL          0x400FE07C  ;# Main Oscillator Control\nset SYSCTL_RCGC0            0x400FE100  ;# Run Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_RCGC1            0x400FE104  ;# Run Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_RCGC2            0x400FE108  ;# Run Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_SCGC0            0x400FE110  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_SCGC1            0x400FE114  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_SCGC2            0x400FE118  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_DCGC0            0x400FE120  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 0\nset SYSCTL_DCGC1            0x400FE124  ;# Deep-Sleep Mode Clock Gating\n                                        ;# Control Register 1\nset SYSCTL_DCGC2            0x400FE128  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 2\nset SYSCTL_DSLPCLKCFG       0x400FE144  ;# Deep Sleep Clock Configuration\nset SYSCTL_CLKVCLR          0x400FE150  ;# Clock Verification Clear\nset SYSCTL_PIOSCCAL         0x400FE150  ;# Precision Internal Oscillator\n                                        ;# Calibration\nset SYSCTL_PIOSCSTAT        0x400FE154  ;# Precision Internal Oscillator\n                                        ;# Statistics\nset SYSCTL_LDOARST          0x400FE160  ;# Allow Unregulated LDO to Reset\n                                        ;# the Part\nset SYSCTL_I2SMCLKCFG       0x400FE170  ;# I2S MCLK Configuration\nset SYSCTL_DC9              0x400FE190  ;# Device Capabilities 9 ADC\n                                        ;# Digital Comparators\nset SYSCTL_NVMSTAT          0x400FE1A0  ;# Non-Volatile Memory Information\n\nset SYSCTL_RCC_USESYSDIV    0x00400000  ;# Enable System Clock Divider\nset SYSCTL_RCC2_BYPASS2     0x00000800  ;# PLL Bypass 2\nset SYSCTL_RCC_MOSCDIS      0x00000001  ;# Main Oscillator Disable\n\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\n\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and Clear\n\nset FLASH_FMA               0x400FD000  ;# Flash Memory Address\nset FLASH_FMD               0x400FD004  ;# Flash Memory Data\nset FLASH_FMC               0x400FD008  ;# Flash Memory Control\nset FLASH_FCRIS             0x400FD00C  ;# Flash Controller Raw Interrupt Status\nset FLASH_FCIM              0x400FD010  ;# Flash Controller Interrupt Mask\nset FLASH_FCMISC            0x400FD014  ;# Flash Controller Masked Interrupt Status and Clear\nset FLASH_FMC2              0x400FD020  ;#  Flash Memory Control 2\nset FLASH_FWBVAL            0x400FD030  ;# Flash Write Buffer Valid\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/altera-5m570z-cpld.cfg",
    "content": "# Altera MAXV 5M24OZ/5M570Z CPLD\n# see MAX V Device Handbook\n# Table 6-3: 32-Bit MAX V Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0111     000 0110 1110    1\njtag newtap 5m570z tap -expected-id 0x020a60dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/altera-epm240.cfg",
    "content": "# Altera MAXII EPM240T100C CPLD\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME epm240\n}\n\n# see MAX II Device Handbook\n# Table 3-3: 32-Bit MAX II Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0001     000 0110 1110    1\njtag newtap $_CHIPNAME tap -irlen 10 \\\n\t-expected-id 0x020a10dd \\\n\t-expected-id 0x020a20dd \\\n\t-expected-id 0x020a30dd \\\n\t-expected-id 0x020a40dd \\\n\t-expected-id 0x020a50dd \\\n\t-expected-id 0x020a60dd\n\n# 200ns seems like a good speed\n# c.f. Table 5-34: MAX II JTAG Timing Parameters\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/jtagspi.cfg",
    "content": "set _USER1 0x02\n\nif { [info exists JTAGSPI_IR] } {\n\tset _JTAGSPI_IR $JTAGSPI_IR\n} else {\n\tset _JTAGSPI_IR $_USER1\n}\n\nif { [info exists TARGETNAME] } {\n\tset _TARGETNAME $TARGETNAME\n} else {\n\tset _TARGETNAME $_CHIPNAME.proxy\n}\n\nif { [info exists FLASHNAME] } {\n\tset _FLASHNAME $FLASHNAME\n} else {\n\tset _FLASHNAME $_CHIPNAME.spi\n}\n\ntarget create $_TARGETNAME testee -chain-position $_CHIPNAME.tap\nflash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR\n\nproc jtagspi_init {chain_id proxy_bit} {\n\t# load proxy bitstream $proxy_bit and probe spi flash\n\tglobal _FLASHNAME\n\tpld load $chain_id $proxy_bit\n\treset halt\n\tflash probe $_FLASHNAME\n}\n\nproc jtagspi_program {bin addr} {\n\t# write and verify binary file $bin at offset $addr\n\tglobal _FLASHNAME\n\tflash write_image erase $bin $addr\n\tflash verify_bank $_FLASHNAME $bin $addr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/lattice-lc4032ze.cfg",
    "content": "# Lattice ispMACH 4000ZE family, device LC4032ZE\n# just configure a tap\njtag newtap LC4032ZE tap -irlen 8 -expected-id  0x01806043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xc6s.cfg",
    "content": "# xilinx spartan6\n# http://www.xilinx.com/support/documentation/user_guides/ug380.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc6s\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x04000093 \\\n\t-expected-id 0x04001093 \\\n\t-expected-id 0x04002093 \\\n\t-expected-id 0x04004093 \\\n\t-expected-id 0x04024093 \\\n\t-expected-id 0x04008093 \\\n\t-expected-id 0x04028093 \\\n\t-expected-id 0x0400E093 \\\n\t-expected-id 0x0402E093 \\\n\t-expected-id 0x04011093 \\\n\t-expected-id 0x04031093 \\\n\t-expected-id 0x0401D093 \\\n\t-expected-id 0x0403D093\n\npld device virtex2 $_CHIPNAME.tap\n\nset XC6S_CFG_IN 0x05\nset XC6S_JSHUTDOWN 0x0d\nset XC6S_JPROGRAM 0x0b\nset XC6S_JSTART 0x0c\nset XC6S_BYPASS 0x3f\n\nproc xc6s_program {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JPROGRAM XC6S_JSTART XC6S_BYPASS\n\tirscan $tap $XC6S_JSHUTDOWN\n\tirscan $tap $XC6S_JPROGRAM\n\tirscan $tap $XC6S_JSTART\n\tirscan $tap $XC6S_BYPASS\n}\n\n#xtp038 and xc3sprog approach\nproc xc6s_program_iprog {tap} {\n\tglobal XC6S_JSHUTDOWN XC6S_JSTART XC6S_BYPASS XC6S_CFG_IN\n\tirscan $tap $XC6S_JSHUTDOWN\n\truntest 16\n\tirscan $tap $XC6S_CFG_IN\n\t# xtp038 IPROG 16bit flipped\n\tdrscan $tap 16 0xffff 16 0x9955 16 0x66aa 16 0x850c 16 0x7000 16 0x0004\n\tirscan $tap $XC6S_JSTART\n\truntest 32\n\tirscan $tap $XC6S_BYPASS\n\truntest 1\n}\n\nset XC6S_ISC_ENABLE 0x10\nset XC6S_ISC_DISABLE 0x16\nset XC6S_ISC_DNA 0x30\n\n# Get the \"Device DNA\" from the Spartan 6.\n# Most Xilinx FPGA devices contain an embedded, unique device identifier called\n# the \"Device DNA\". The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\nproc xc6s_get_dna {tap} {\n\tglobal XC6S_ISC_ENABLE XC6S_ISC_DISABLE XC6S_ISC_DNA\n\tirscan $tap $XC6S_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC6S_ISC_DNA\n\t# Device DNA is 57 bits long, but we can only read 32bits at a time\n\t# with OpenOCD.\n\tset dna [drscan $tap 16 0 16 0 16 0 9 0]\n\truntest 64\n\tirscan $tap $XC6S_ISC_DISABLE\n\truntest 64\n\n\t# Convert the binary data into the order impact uses\n\tscan $dna \"%x %x %x %x\" v1 v2 v3 v4\n\tset bin_dna [string reverse [concat [format \"%09b\" $v4][format \"%016b\" $v3][format \"%016b\" $v2][format \"%016b\" $v1]]]\n\n\t# Return a hex version of binary\n\tscan [format \"0b%s\" $bin_dna] \"%i\" hex_dna\n\treturn $hex_dna\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xc6s_print_dna {tap} {\n\tset hex_dna [xc6s_get_dna $tap]\n\n\tputs [format \"DNA = %57b (0x%x)\\n\" $hex_dna $hex_dna]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xc7.cfg",
    "content": "# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7\n}\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x03622093 \\\n\t-expected-id 0x03620093 \\\n\t-expected-id 0x037C4093 \\\n\t-expected-id 0x0362F093 \\\n\t-expected-id 0x037C8093 \\\n\t-expected-id 0x037C7093 \\\n\t-expected-id 0x037C3093 \\\n\t-expected-id 0x0362E093 \\\n\t-expected-id 0x037C2093 \\\n\t-expected-id 0x0362D093 \\\n\t-expected-id 0x0362C093 \\\n\t-expected-id 0x03632093 \\\n\t-expected-id 0x03631093 \\\n\t-expected-id 0x03636093 \\\n\t-expected-id 0x03647093 \\\n\t-expected-id 0x0364C093 \\\n\t-expected-id 0x03651093 \\\n\t-expected-id 0x03747093 \\\n\t-expected-id 0x03656093 \\\n\t-expected-id 0x03752093 \\\n\t-expected-id 0x03751093 \\\n\t-expected-id 0x03671093 \\\n\t-expected-id 0x036B3093 \\\n\t-expected-id 0x036B7093 \\\n\t-expected-id 0x036BB093 \\\n\t-expected-id 0x036BF093 \\\n\t-expected-id 0x03667093 \\\n\t-expected-id 0x03682093 \\\n\t-expected-id 0x03687093 \\\n\t-expected-id 0x03692093 \\\n\t-expected-id 0x03691093 \\\n\t-expected-id 0x03696093 \\\n\t-expected-id 0x036D5093 \\\n\t-expected-id 0x036D9093 \\\n\t-expected-id 0x036DB093\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc xc7_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xcf-p.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF08P <v>5057093\n# XCF16P <v>5058093\n# XCF32P <v>5059093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 16 -ignore-version \\\n\t-expected-id 0x05057093 \\\n\t-expected-id 0x05058093 \\\n\t-expected-id 0x05059093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_P xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xcf-s.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF01S <v>5044093\n# XCF02S <v>5045093\n# XCF04S <v>5046093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 8 -ignore-version \\\n\t-expected-id 0x05044093 \\\n\t-expected-id 0x05045093 \\\n\t-expected-id 0x05046093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_S xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xcr3256.cfg",
    "content": "#xilinx coolrunner xcr3256\n#simple device - just configure a tap\njtag newtap xcr tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id  0x0494c093\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpld/xilinx-xcu.cfg",
    "content": "# Xilinx Ultrascale (Kintex, Virtex, Zynq)\n# https://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcu\n}\n\n# The cvarious chips in the Ultrascale family have different IR length.\n# Set $CHIP before including this file to determine the device.\narray set _XCU_DATA {\n\tXCKU025 {0x03824093 6}\n\tXCKU035 {0x03823093 6}\n\tXCKU040 {0x03822093 6}\n\tXCKU060 {0x03919093 6}\n\tXCKU095 {0x03844093 6}\n\tXCKU3P {0x04A63093 6}\n\tXCKU5P {0x04A62093 6}\n\tXCKU9P {0x0484A093 6}\n\tXCKU11P {0x04A4E093 6}\n\tXCKU13P {0x04A52093 6}\n\tXCKU15P {0x04A56093 6}\n\tXCVU065 {0x03939093 6}\n\tXCVU080 {0x03843093 6}\n\tXCVU095 {0x03842093 6}\n\tXCVU3P {0x04B39093 6}\n\tXCKU085 {0x0380F093 12}\n\tXCKU115 {0x0390D093 12}\n\tXCVU125 {0x0392D093 12}\n\tXCVU5P {0x04B2B093 12}\n\tXCVU7P {0x04B29093 12}\n\tXCVU160 {0x03933093 18}\n\tXCVU190 {0x03931093 18}\n\tXCVU440 {0x0396D093 18}\n\tXCVU9P {0x04B31093 18}\n\tXCVU11P {0x04B49093 18}\n\tXCVU13P {0x04B51093 24}\n}\n\nif { ![info exists CHIP] } {\n\terror \"set CHIP to one of \"[concat [array names _XCU_DATA]]\n}\n\nif { ![llength [array names _XCU_DATA $CHIP]] } {\n\terror \"unknown CHIP: \"$CHIP\n}\n\nset _EXPID [lindex $_XCU_DATA($CHIP) 0]\nset _IRLEN [lindex $_XCU_DATA($CHIP) 1]\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen $_IRLEN -ignore-version -expected-id $_EXPID\n\npld device virtex2 $_CHIPNAME.tap 1\n\nset XCU_JSHUTDOWN 0x0d\nset XCU_JPROGRAM 0x0b\nset XCU_JSTART 0x0c\nset XCU_BYPASS 0x3f\n\nproc xcu_program {tap} {\n\tglobal XCU_JSHUTDOWN XCU_JPROGRAM XCU_JSTART XCU_BYPASS\n\tirscan $tap $XCU_JSHUTDOWN\n\tirscan $tap $XCU_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XCU_JSTART\n\truntest 2000\n\tirscan $tap $XCU_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arc/common.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Things common to all ARCs\n\n# It is assumed that target is already halted.\nproc arc_common_reset { {target \"\"} } {\n        if { $target != \"\" } {\n                targets $target\n        }\n\n        halt\n\n        # 1. Interrupts are disabled (STATUS32.IE)\n        # 2. The status register flags are cleared.\n        # All fields, except the H bit, are set to 0 when the processor is Reset.\n\n        arc jtag set-aux-reg 0xA 0x1\n\n        # 3. The loop count, loop start, and loop end registers are cleared.\n        arc jtag set-core-reg 60 0\n        arc jtag set-aux-reg 0x2 0\n        arc jtag set-aux-reg 0x3 0\n\n        # Program execution begins at the address referenced by the four byte reset\n        # vector located at the interrupt vector base address, which is the first\n        # entry (offset 0x00) in the vector table.\n        set int_vector_base [arc jtag get-aux-reg 0x25]\n        set start_pc [read_memory $int_vector_base 32 1]\n        arc jtag set-aux-reg 0x6 $start_pc\n\n        # It is OK to do uncached writes - register cache will be invalidated by\n        # the reset_assert() function.\n}\n\n# vim:expandtab:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arc/em.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_em_examine_target { {target \"\"} } {\n\t# Will set current target\n\tarc_v2_examine_target $target\n}\n\nproc arc_em_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_em_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_em_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Set DEBUG.ED bit to enable clock in actionpoint module.\n\t# This is specific to ARC EM.\n\tset debug [arc jtag get-aux-reg 5]\n\tif { !($debug & (1 << 20)) } {\n\t\tarc jtag set-aux-reg 5 [expr {$debug | (1 << 20)}]\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arc/hs.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_hs_examine_target { target } {\n\t# Will set current target for us.\n\tarc_v2_examine_target $target\n}\n\nproc arc_hs_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_hs_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_hs_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Invalidate L2 cache if there is one.\n\tset l2_config [$target arc jtag get-aux-reg 0x901]\n\t# Will return 0, if cache is not present and register doesn't exist.\n\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\tif { ($l2_config != 0) && (($l2_ctrl & 1) == 0) } {\n\t\tputs \"L2 cache is present and not disabled\"\n\n\t\t# Wait until BUSY bit is 0.\n\t\tputs \"Invalidating L2 cache...\"\n\t\t$target arc jtag set-aux-reg 0x905 1\n\t\t# Dummy read of SLC_AUX_CACHE_CTRL bit, as described in:\n\t\t# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/arch/arc?id=c70c473396cbdec1168a6eff60e13029c0916854\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\twhile { ($l2_ctrl & 0x100) != 0 } {\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t}\n\n\t\t# Flush cache if needed. If SLC_AUX_CACHE_CTRL.IM is 1, then invalidate\n\t\t# operation already flushed everything.\n\t\tif { ($l2_ctrl & 0x40) == 0 } {\n\t\t\tputs \"Flushing L2 cache...\"\n\t\t\t$target arc jtag set-aux-reg 0x904 1\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\twhile { [expr {$l2_ctrl & 0x100}] != 0 } {\n\t\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\t}\n\t\t}\n\n\t\tputs \"L2 cache has been flushed and invalidated.\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arc/v2.tcl",
    "content": "#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find cpu/arc/common.tcl]\n\n# Currently 'examine_target' can only read JTAG registers and set properties -\n# but it shouldn't write any of registers - writes will be cached, but cache\n# will be invalidated before flushing after examine_target, and changes will be\n# lost.  Perhaps that would be fixed later - perhaps writes shouldn't be cached\n# after all.  But if write to register is really needed from TCL - then it\n# should be done via \"arc jtag\" for now.\nproc arc_v2_examine_target { {target \"\"} } {\n\t# Set current target, because OpenOCD event handlers don't do this for us.\n\tif { $target != \"\" } {\n\t\ttargets $target\n\t}\n\n\t# Those registers always exist. DEBUG and DEBUGI are formally optional,\n\t# however they come with JTAG interface, and so far there is no way\n\t# OpenOCD can communicate with target without JTAG interface.\n\tarc set-reg-exists identity pc status32 bta debug lp_start lp_end \\\n\t\teret erbta erstatus ecr efa\n\n\t# 32 core registers\n\tarc set-reg-exists \\\n\t\tr0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r10 r11 r12 \\\n\t\tr13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 \\\n\t\tgp fp sp ilink r30 blink lp_count pcl\n\n\t# Actionpoints\n\tif { [arc get-reg-field ap_build version] == 5 } {\n\t\tset ap_build_type [arc get-reg-field ap_build type]\n\t\t# AP_BUILD.TYPE > 0b0110 is reserved in current ISA.\n\t\t# Current ISA supports up to 8 actionpoints.\n\t\tif { $ap_build_type < 8 } {\n\t\t\t# Two LSB bits of AP_BUILD.TYPE define amount of actionpoints:\n\t\t\t# 0b00 - 2 actionpoints\n\t\t\t# 0b01 - 4 actionpoints\n\t\t\t# 0b10 - 8 actionpoints\n\t\t\t# 0b11 - reserved.\n\t\t\tset ap_num [expr {0x2 << ($ap_build_type & 3)}]\n\t\t\t# Expression on top may produce 16 action points - which is a\n\t\t\t# reserved value for now.\n\t\t\tif { $ap_num < 16 } {\n\t\t\t\t# Enable actionpoint registers\n\t\t\t\tfor {set i 0} {$i < $ap_num} {incr i} {\n\t\t\t\t\tarc set-reg-exists ap_amv$i ap_amm$i ap_ac$i\n\t\t\t\t}\n\n\t\t\t\t# Set amount of actionpoints\n\t\t\t\tarc num-actionpoints $ap_num\n\t\t\t}\n\t\t}\n\t}\n\n\t# DCCM\n\tset dccm_version [arc get-reg-field dccm_build version]\n\tif { $dccm_version == 3 || $dccm_version == 4 } {\n\t\tarc set-reg-exists aux_dccm\n\t}\n\n\t# ICCM\n\tif { [arc get-reg-field iccm_build version] == 4 } {\n\t\tarc set-reg-exists aux_iccm\n\t}\n\n\t# MPU\n\tif { [arc get-reg-field mpu_build version] >= 2 &&\n\t\t [arc get-reg-field mpu_build version] <= 4 } {\n\t\tarc set-reg-exists mpu_en mpu_ecr\n\t\tset mpu_regions [arc get-reg-field mpu_build regions]\n\t\tfor {set i 0} {$i < $mpu_regions} {incr i} {\n\t\t\tarc set-reg-exists mpu_rdp$i mpu_rdb$i\n\t\t}\n\n\t\t# Secure MPU\n\t\tif { [arc get-reg-field mpu_build version] == 4 } {\n\t\t\tarc set-reg-exists mpu_index mpu_rstart mpu_rend mpu_rper\n\t\t}\n\t}\n}\n\nproc arc_v2_init_regs { } {\n\t# XML features\n\tset core_feature \"org.gnu.gdb.arc.core.v2\"\n\tset aux_min_feature \"org.gnu.gdb.arc.aux-minimal\"\n\tset aux_other_feature \"org.gnu.gdb.arc.aux-other\"\n\n\t# Describe types\n\t# Types are sorted alphabetically according to their name.\n\tarc add-reg-type-struct -name ap_build_t -bitfield version 0 7 \\\n\t\t-bitfield type 8 11\n\tarc add-reg-type-struct -name ap_control_t -bitfield at 0 3 -bitfield tt 4 5 \\\n\t\t-bitfield m 6 6 -bitfield p 7 7 -bitfield aa 8 8 -bitfield q 9 9\n\t# Cycles field added in version 4.\n\tarc add-reg-type-struct -name dccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield size0 8 11 -bitfield size1 12 15 -bitfield cycles 17 19\n\n\tarc add-reg-type-struct -name debug_t \\\n\t\t-bitfield fh 1 1   -bitfield ah 2 2   -bitfield asr 3 10 \\\n\t\t-bitfield is 11 11 -bitfield ep 19 19 -bitfield ed 20 20 \\\n\t\t-bitfield eh 21 21 -bitfield ra 22 22 -bitfield zz 23 23 \\\n\t\t-bitfield sm 24 26 -bitfield ub 28 28 -bitfield bh 29 29 \\\n\t\t-bitfield sh 30 30 -bitfield ld 31 31\n\n\tarc add-reg-type-struct -name ecr_t \\\n\t\t-bitfield parameter 0 7 \\\n\t\t-bitfield cause 8 15 \\\n\t\t-bitfield vector 16 23 \\\n\t\t-bitfield U 30 30 \\\n\t\t-bitfield P 31 31\n\tarc add-reg-type-struct -name iccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield iccm0_size0  8 11 -bitfield iccm1_size0 12 15 \\\n\t\t-bitfield iccm0_size1 16 19 -bitfield iccm1_size1 20 23\n\tarc add-reg-type-struct -name identity_t \\\n\t\t-bitfield arcver 0 7 -bitfield arcnum 8 15 -bitfield chipid 16 31\n\tarc add-reg-type-struct -name isa_config_t -bitfield version 0 7 \\\n\t\t-bitfield pc_size 8 11 -bitfield lpc_size 12 15 -bitfield addr_size 16 19 \\\n\t\t-bitfield b 20 20 -bitfield a 21 21 -bitfield n 22 22 -bitfield l 23 23 \\\n\t\t-bitfield c 24 27 -bitfield d 28 31\n\tarc add-reg-type-struct -name mpu_build_t -bitfield version 0 7 \\\n\t\t-bitfield regions 8 15 \\\n\t\t-bitfield s 16 16 \\\n\t\t-bitfield i 17 17\n\tarc add-reg-type-struct -name mpu_ecr_t \\\n\t\t-bitfield MR 0 7 \\\n\t\t-bitfield VT 8 9 \\\n\t\t-bitfield EC_CODE 16 31\n\tarc add-reg-type-struct -name mpu_en_t \\\n\t\t-bitfield UE  3  3 -bitfield UW   4  4 -bitfield UR 5 5 \\\n\t\t-bitfield KE  6  6 -bitfield KW   7  7 -bitfield KR 8 8 \\\n\t\t-bitfield S  15 15 -bitfield SID 16 23 \\\n\t\t-bitfield EN 30 30\n\tarc add-reg-type-struct -name mpu_index_t \\\n\t\t-bitfield I 0 3 -bitfield M 30 30 -bitfield D 31 31\n\tarc add-reg-type-struct -name mpu_rper_t \\\n\t\t-bitfield V 0 0 \\\n\t\t-bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \\\n\t\t-bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \\\n\t\t-bitfield S 15 15 -bitfield SID 16 23\n\tarc add-reg-type-flags -name status32_t \\\n\t\t-flag   H  0 -flag E0   1 -flag E1   2 -flag E2  3 \\\n\t\t-flag  E3  4 -flag AE   5 -flag DE   6 -flag  U  7 \\\n\t\t-flag   V  8 -flag  C   9 -flag  N  10 -flag  Z 11 \\\n\t\t-flag   L 12 -flag DZ  13 -flag SC  14 -flag ES 15 \\\n\t\t-flag RB0 16 -flag RB1 17 -flag RB2 18 \\\n\t\t-flag  AD 19 -flag US  20 -flag IE  31\n\n\t# Core registers\n\tset core_regs {\n\t\tr0       0  uint32\n\t\tr1       1  uint32\n\t\tr2       2  uint32\n\t\tr3       3  uint32\n\t\tr4       4  uint32\n\t\tr5       5  uint32\n\t\tr6       6  uint32\n\t\tr7       7  uint32\n\t\tr8       8  uint32\n\t\tr9       9  uint32\n\t\tr10      10 uint32\n\t\tr11      11 uint32\n\t\tr12      12 uint32\n\t\tr13      13 uint32\n\t\tr14      14 uint32\n\t\tr15      15 uint32\n\t\tr16      16 uint32\n\t\tr17      17 uint32\n\t\tr18      18 uint32\n\t\tr19      19 uint32\n\t\tr20      20 uint32\n\t\tr21      21 uint32\n\t\tr22      23 uint32\n\t\tr23      24 uint32\n\t\tr24      24 uint32\n\t\tr25      25 uint32\n\t\tgp       26 data_ptr\n\t\tfp       27 data_ptr\n\t\tsp       28 data_ptr\n\t\tilink    29 code_ptr\n\t\tr30      30 uint32\n\t\tblink    31 code_ptr\n\t\tr32      32 uint32\n\t\tr33      33 uint32\n\t\tr34      34 uint32\n\t\tr35      35 uint32\n\t\tr36      36 uint32\n\t\tr37      37 uint32\n\t\tr38      38 uint32\n\t\tr39      39 uint32\n\t\tr40      40 uint32\n\t\tr41      41 uint32\n\t\tr42      42 uint32\n\t\tr43      43 uint32\n\t\tr44      44 uint32\n\t\tr45      45 uint32\n\t\tr46      46 uint32\n\t\tr47      47 uint32\n\t\tr48      48 uint32\n\t\tr49      49 uint32\n\t\tr50      50 uint32\n\t\tr51      51 uint32\n\t\tr52      52 uint32\n\t\tr53      53 uint32\n\t\tr54      54 uint32\n\t\tr55      55 uint32\n\t\tr56      56 uint32\n\t\tr57      57 uint32\n\t\taccl     58 uint32\n\t\tacch     59 uint32\n\t\tlp_count 60 uint32\n\t\tlimm     61 uint32\n\t\treserved 62 uint32\n\t\tpcl      63 code_ptr\n\t}\n\tforeach {reg count type} $core_regs {\n\t\tarc add-reg -name $reg -num $count -core -type $type -g \\\n\t\t\t-feature $core_feature\n\t}\n\n\t# AUX min\n\tset aux_min {\n\t\t0x6 pc       code_ptr\n\t\t0x2 lp_start code_ptr\n\t\t0x3 lp_end   code_ptr\n\t\t0xA status32 status32_t\n\t}\n\tforeach {num name type} $aux_min {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_min_feature -g\n\t}\n\n\t# AUX other\n\tset aux_other {\n\t\t0x004 identity\tidentity_t\n\t\t0x005 debug\t\tdebug_t\n\t\t0x018 aux_dccm\tint\n\t\t0x208 aux_iccm\tint\n\n\t\t0x220 ap_amv0\tuint32\n\t\t0x221 ap_amm0\tuint32\n\t\t0x222 ap_ac0\tap_control_t\n\t\t0x223 ap_amv1\tuint32\n\t\t0x224 ap_amm1\tuint32\n\t\t0x225 ap_ac1\tap_control_t\n\t\t0x226 ap_amv2\tuint32\n\t\t0x227 ap_amm2\tuint32\n\t\t0x228 ap_ac2\tap_control_t\n\t\t0x229 ap_amv3\tuint32\n\t\t0x22A ap_amm3\tuint32\n\t\t0x22B ap_ac3\tap_control_t\n\t\t0x22C ap_amv4\tuint32\n\t\t0x22D ap_amm4\tuint32\n\t\t0x22E ap_ac4\tap_control_t\n\t\t0x22F ap_amv5\tuint32\n\t\t0x230 ap_amm5\tuint32\n\t\t0x231 ap_ac5\tap_control_t\n\t\t0x232 ap_amv6\tuint32\n\t\t0x233 ap_amm6\tuint32\n\t\t0x234 ap_ac6\tap_control_t\n\t\t0x235 ap_amv7\tuint32\n\t\t0x236 ap_amm7\tuint32\n\t\t0x237 ap_ac7\tap_control_t\n\n\t\t0x400 eret\t\tcode_ptr\n\t\t0x401 erbta\t\tcode_ptr\n\t\t0x402 erstatus\tstatus32_t\n\t\t0x403 ecr\t\tecr_t\n\t\t0x404 efa\t\tdata_ptr\n\n\t\t0x409 mpu_en\tmpu_en_t\n\n\t\t0x412 bta\t\tcode_ptr\n\n\t\t0x420 mpu_ecr\tmpu_ecr_t\n\t\t0x422 mpu_rdb0\tint\n\t\t0x423 mpu_rdp0\tint\n\t\t0x424 mpu_rdb1\tint\n\t\t0x425 mpu_rdp1\tint\n\t\t0x426 mpu_rdb2\tint\n\t\t0x427 mpu_rdp2\tint\n\t\t0x428 mpu_rdb3\tint\n\t\t0x429 mpu_rdp3\tint\n\t\t0x42A mpu_rdb4\tint\n\t\t0x42B mpu_rdp4\tint\n\t\t0x42C mpu_rdb5\tint\n\t\t0x42D mpu_rdp5\tint\n\t\t0x42E mpu_rdb6\tint\n\t\t0x42F mpu_rdp6\tint\n\t\t0x430 mpu_rdb7\tint\n\t\t0x431 mpu_rdp7\tint\n\t\t0x432 mpu_rdb8\tint\n\t\t0x433 mpu_rdp8\tint\n\t\t0x434 mpu_rdb9\tint\n\t\t0x435 mpu_rdp9\tint\n\t\t0x436 mpu_rdb10\tint\n\t\t0x437 mpu_rdp10\tint\n\t\t0x438 mpu_rdb11\tint\n\t\t0x439 mpu_rdp11\tint\n\t\t0x43A mpu_rdb12\tint\n\t\t0x43B mpu_rdp12\tint\n\t\t0x43C mpu_rdb13\tint\n\t\t0x43D mpu_rdp13\tint\n\t\t0x43E mpu_rdb14\tint\n\t\t0x43F mpu_rdp14\tint\n\t\t0x440 mpu_rdb15\tint\n\t\t0x441 mpu_rdp15\tint\n\t\t0x448 mpu_index\tmpu_index_t\n\t\t0x449 mpu_rstart uint32\n\t\t0x44A mpu_rend\tuint32\n\t\t0x44B mpu_rper\tmpu_rper_t\n\t\t0x44C mpu_probe uint32\n\t}\n\tforeach {num name type} $aux_other {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_other_feature\n\t}\n\n\t# AUX BCR\n\tset bcr {\n\t\t0x6D mpu_build\n\t\t0x74 dccm_build\n\t\t0x76 ap_build\n\t\t0x78 iccm_build\n\t\t0xC1 isa_config\n\t}\n\tforeach {num reg} $bcr {\n\t\tarc add-reg -name $reg -num $num -type ${reg}_t -bcr -feature $aux_other_feature\n\t}\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_v2_examine_target [target current]\"\n}\n\nproc arc_v2_reset { {target \"\"} } {\n\tarc_common_reset $target\n\n\t# Disable all actionpoints.  Cannot write via regcache yet, because it will\n\t# not be flushed and all changes to registers will get lost.  Therefore has\n\t# to write directly via JTAG layer...\n\tset num_ap [arc num-actionpoints]\n\tfor {set i 0} {$i < $num_ap} {incr i} {\n\t\tarc jtag set-aux-reg [expr {0x222 + $i * 3}] 0\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arm/arm7tdmi.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm7tdmi\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arm/arm920.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm920\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arm/arm946.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm946\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arm/arm966.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   arm966\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/cpu/arm/cortex_m3.tcl",
    "content": "set CPU_TYPE   arm\nset CPU_NAME   cortex_m3\nset CPU_ARCH   armv7\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/altera-10m50.cfg",
    "content": "# see MAX 10 FPGA Device Architecture\n# Table 3-1: IDCODE Information for MAX 10 Devices\n# Intel MAX 10M02 0x31810dd\n# Intel MAX 10M04 0x318a0dd\n# Intel MAX 10M08 0x31820dd\n# Intel MAX 10M16 0x31830dd\n# Intel MAX 10M25 0x31840dd\n# Intel MAX 10M40 0x318d0dd\n# Intel MAX 10M50 0x31850dd\n# Intel MAX 10M02 0x31010dd\n# Intel MAX 10M04 0x310a0dd\n# Intel MAX 10M08 0x31020dd\n# Intel MAX 10M16 0x31030dd\n# Intel MAX 10M25 0x31040dd\n# Intel MAX 10M40 0x310d0dd\n# Intel MAX 10M50 0x31050dd\n\njtag newtap 10m50 tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \\\n\t-expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \\\n\t-expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \\\n\t-expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \\\n\t-expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/altera-ep3c10.cfg",
    "content": "# Altera Cyclone III EP3C10\n# see Cyclone III Device Handbook, Volume 1;\n# Table 14–5. 32-Bit Cyclone III Device IDCODE\njtag newtap ep3c10 tap -expected-id 0x020f10dd -irlen 10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/altera-ep4ce10.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ecp4\n}\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id -0x020f10ddc"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/lattice_ecp5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp5\n}\n\n# Lattice ECP5 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/ECP5\n#\n# 0x01111043 - LAE5UM_25F/LFE5UM_25F\n# 0x01112043 - LAE5UM_45F/LFE5UM_45F\n# 0x01113043 - LAE5UM_85F/LFE5UM_85\n# 0x21111043 - LFE5U_12F\n# 0x41111043 - LFE5U_25F\n# 0x41112043 - LFE5U_45F\n# 0x41113043 - LFE5U_85F\n# 0x81111043 - LFE5UM5G-25\n# 0x81112043 - LFE5UM5G-45\n# 0x81113043 - LFE5UM5G-85\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x01111043 -expected-id 0x01112043 -expected-id 0x01113043 \\\n\t-expected-id 0x21111043 -expected-id 0x41111043 -expected-id 0x41112043 \\\n\t-expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \\\n\t-expected-id 0x81113043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/xilinx-dna.cfg",
    "content": "proc xilinx_dna_addr {chip} {\n\tarray set addrs {\n\t\tSpartan6 0x30\n\t\tSeries7 0x17\n\t}\n\treturn $addrs($chip)\n}\n\n# Get the \"Device DNA\".\n# Most Xilinx FPGA devices contain an embedded, unique device identifier.\n# The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\n# This function returns the DNA as a 64 bit integer with the 7 LSBs zeroed.\n# This is compatible with the FUSE DNA which contains all 64 bits.\nproc xilinx_get_dna {tap chip} {\n\tset XC7_ISC_ENABLE 0x10\n\tset XC7_ISC_DISABLE 0x16\n\tset XC7_ISC_DNA [xilinx_dna_addr $chip]\n\n\tirscan $tap $XC7_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC7_ISC_DNA\n\tscan [drscan $tap 32 0 32 0] \"%08x %08x\" hi lo\n\truntest 64\n\tirscan $tap $XC7_ISC_DISABLE\n\truntest 64\n\t# openocd interprets DR scans as LSB first, bit-reverse it\n\treturn [scan [string reverse [format \"%032b%032bb0\" $lo $hi]] \"%i\"]\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xilinx_print_dna {dna} {\n\tset dna [expr {$dna >> 64 - 57}]\n\techo [format \"DNA = %057b (0x%016x)\" $dna $dna]\n}\n\nproc xc7_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Series7]\n}\n\nproc xc6s_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Spartan6]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/fpga/xilinx-xadc.cfg",
    "content": "# Xilinx XADC support for 7 Series FPGAs\n#\n# The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die\n# temperature, internal power supply rail voltages as well as external\n# voltages. The XADC is available both from fabric as well as through the\n# JTAG TAP.\n#\n# This code implements access through the JTAG TAP.\n#\n# https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf\n\n# build a 32 bit DRP command for the XADC DR\nproc xadc_cmd {cmd addr data} {\n\tarray set cmds {\n\t\tNOP 0x00\n\t\tREAD 0x01\n\t\tWRITE 0x02\n\t}\n\treturn [expr {($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)}]\n}\n\n# XADC register addresses\n# Some addresses (status registers 0-3) have special function when written to.\nproc XADC {key} {\n\tarray set addrs {\n\t\tTEMP 0x00\n\t\tLOCK 0x00\n\t\tVCCINT 0x01\n\t\tVCCAUX 0x02\n\t\tVAUXEN 0x02\n\t\tVPVN 0x03\n\t\tRESET 0x03\n\t\tVREFP 0x04\n\t\tVREFN 0x05\n\t\tVCCBRAM 0x06\n\t\tSUPAOFFS 0x08\n\t\tADCAOFFS 0x09\n\t\tADCAGAIN 0x0a\n\t\tVCCPINT 0x0d\n\t\tVCCPAUX 0x0e\n\t\tVCCODDR 0x0f\n\t\tVAUX0 0x10\n\t\tVAUX1 0x11\n\t\tVAUX2 0x12\n\t\tVAUX3 0x13\n\t\tVAUX4 0x14\n\t\tVAUX5 0x15\n\t\tVAUX6 0x16\n\t\tVAUX7 0x17\n\t\tVAUX8 0x18\n\t\tVAUX9 0x19\n\t\tVAUX10 0x1a\n\t\tVAUX11 0x1b\n\t\tVAUX12 0x1c\n\t\tVAUX13 0x1d\n\t\tVAUX14 0x1e\n\t\tVAUX15 0x1f\n\t\tSUPBOFFS 0x30\n\t\tADCBOFFS 0x31\n\t\tADCBGAIN 0x32\n\t\tFLAG 0x3f\n\t\tCFG0 0x40\n\t\tCFG1 0x41\n\t\tCFG2 0x42\n\t\tSEQ0 0x48\n\t\tSEQ1 0x49\n\t\tSEQ2 0x4a\n\t\tSEQ3 0x4b\n\t\tSEQ4 0x4c\n\t\tSEQ5 0x4d\n\t\tSEQ6 0x4e\n\t\tSEQ7 0x4f\n\t\tALARM0 0x50\n\t\tALARM1 0x51\n\t\tALARM2 0x52\n\t\tALARM3 0x53\n\t\tALARM4 0x54\n\t\tALARM5 0x55\n\t\tALARM6 0x56\n\t\tALARM7 0x57\n\t\tALARM8 0x58\n\t\tALARM9 0x59\n\t\tALARM10 0x5a\n\t\tALARM11 0x5b\n\t\tALARM12 0x5c\n\t\tALARM13 0x5d\n\t\tALARM14 0x5e\n\t\tALARM15 0x5f\n\t}\n\treturn $addrs($key)\n}\n\n# Select the XADC DR\nproc xadc_select {tap} {\n\tset XADC_IR 0x37\n\tirscan $tap $XADC_IR\n\truntest 10\n}\n\n# XADC transfer\nproc xadc_xfer {tap cmd addr data} {\n\tset ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]\n\truntest 10\n\treturn [expr \"0x$ret\"]\n}\n\n# XADC register write\nproc xadc_write {tap addr data} {\n\txadc_xfer $tap WRITE $addr $data\n}\n\n# XADC register read, non-pipelined\nproc xadc_read {tap addr} {\n\txadc_xfer $tap READ $addr 0\n\treturn [xadc_xfer $tap NOP 0 0]\n}\n\n# convert 16 bit register code from ADC measurement on\n# external voltages (VAUX) to Volt\nproc xadc_volt {code} {\n\treturn [expr {$code * 1./(1 << 16)}]\n}\n\n# convert 16 bit temperature measurement to Celsius\nproc xadc_temp {code} {\n\treturn [expr {$code * 503.975/(1 << 16) - 273.15}]\n}\n\n# convert 16 bit suppply voltage measurement to Volt\nproc xadc_sup {code} {\n\treturn [expr {$code * 3./(1 << 16)}]\n}\n\n# perform a single channel measurement using default settings\nproc xadc_single {tap ch} {\n\tset cfg0 [xadc_read $tap [XADC CFG0]]\n\tset cfg1 [xadc_read $tap [XADC CFG1]]\n\t# set channel\n\txadc_write $tap [XADC CFG0] $cfg0\n\t# single channel, disable the sequencer\n\txadc_write $tap [XADC CFG1] 0x3000\n\t# leave some time for the conversion\n\truntest 100\n\tset ret [xadc_read $tap [XADC $ch]]\n\t# restore CFG0/1\n\txadc_write $tap [XADC CFG0] $cfg0\n\txadc_write $tap [XADC CFG1] $cfg1\n\treturn $ret\n}\n\n# measure all internal voltages\nproc xadc_report {tap} {\n\txadc_select $tap\n\techo \"TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C\"\n\tforeach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \\\n\t\tVCCPINT VCCPAUX VCCODDR] {\n\t\techo \"$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/altera-usb-blaster.cfg",
    "content": "#\n# Altera USB-Blaster\n#\n# http://www.altera.com/literature/ug/ug_usb_blstr.pdf\n#\n\nadapter driver usb_blaster\nusb_blaster lowlevel_driver ftdi\n# These are already the defaults.\n# usb_blaster vid_pid 0x09FB 0x6001\n# usb_blaster device_desc \"USB-Blaster\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/altera-usb-blaster2.cfg",
    "content": "#\n# Altera USB-Blaster II\n#\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x09fb 0x6010 0x09fb 0x6810\nusb_blaster lowlevel_driver ublast2\nusb_blaster firmware /path/to/quartus/blaster_6810.hex\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/arm-jtag-ew.cfg",
    "content": "#\n# Olimex ARM-JTAG-EW\n#\n# http://www.olimex.com/dev/arm-jtag-ew.html\n#\n\nadapter driver arm-jtag-ew\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/at91rm9200.cfg",
    "content": "#\n# Various Atmel AT91RM9200 boards\n#\n# TODO: URL?\n#\n\nadapter driver at91rm9200\nat91rm9200_device rea_ecr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/beaglebone-jtag-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for JTAG\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio tdo_num 20\nam335xgpio tdi_num 60\nam335xgpio tms_num 4\nam335xgpio tck_num 2\n\nam335xgpio led_num 51\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/beaglebone-swd-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for SWD\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\nam335xgpio swclk_num 2\nam335xgpio swdio_num 4\nam335xgpio swdio_dir_num 60\nam335xgpio swdio_dir_output_state on\n\n# USR0 LED\nam335xgpio led_num 53\nam335xgpio led_on_state on\n\nam335xgpio srst_num 65\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/buspirate.cfg",
    "content": "#\n# Buspirate with OpenOCD support\n#\n# http://dangerousprototypes.com/bus-pirate-manual/\n#\n\nadapter driver buspirate\n\n# you need to specify port on which BP lives\n#buspirate port /dev/ttyUSB0\n\n# communication speed setting\nbuspirate speed normal ;# or fast\n\n# voltage regulator Enabled = 1 Disabled = 0\n#buspirate vreg 0\n\n# pin mode normal or open-drain (jtag only)\n#buspirate mode normal\n\n# pullup state Enabled = 1 Disabled = 0\n#buspirate pullup 0\n\n# this depends on the cable, you are safe with this option\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/calao-usb-a9260.cfg",
    "content": "#\n# CALAO Systems USB-A9260 common -C01 -C02 setup\n#\n# http://www.calao-systems.com/\n#\n# See calao-usb-a9260-c01.cfg and calao-usb-a9260-c02.cfg.\n#\n\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/chameleon.cfg",
    "content": "#\n# Amontec Chameleon POD\n#\n# http://www.amontec.com/chameleon.shtml\n#\n\nadapter driver parport\nparport cable chameleon\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/cmsis-dap.cfg",
    "content": "#\n# ARM CMSIS-DAP compliant adapter\n#\n# http://www.keil.com/support/man/docs/dapdebug/\n#\n\nadapter driver cmsis-dap\n\n# Optionally specify the serial number of CMSIS-DAP usb device.\n# adapter serial 02200201E6661E601B98E3B9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/dln-2-gpiod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use DLN-2 GPIO through linuxgpiod\n#\n# +-----------+-------------+-------------+\n# | signal    | DLN-2       | gpio offset |\n# +-----------+-------------+-------------+\n# | nSRST     | J3.1  (PA0) | 0           |\n# | TDO       | J3.2  (PA1) | 1           |\n# | TCK/SWCLK | J3.3  (PA2) | 2           |\n# | TMS/SWDIO | J3.4  (PA3) | 3           |\n# | TDI       | J3.5  (PA4) | 4           |\n# | nTRST     | J3.6  (PA5) | 5           |\n# | LED       | J3.7  (PA6) | 6           |\n# | GND       | J3.12 (GND) |             |\n# +-----------+-------------+-------------+\n\nadapter driver linuxgpiod\n\nlinuxgpiod gpiochip 0\nlinuxgpiod jtag_nums 2 3 4 1\nlinuxgpiod trst_num 5\nlinuxgpiod swd_nums 2 3\nlinuxgpiod srst_num 0\nlinuxgpiod led_num 6\n\nreset_config trst_and_srst separate srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/dummy.cfg",
    "content": "#\n# Dummy interface (for testing purposes)\n#\n\nadapter driver dummy\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/estick.cfg",
    "content": "#\n# eStick\n#\n# http://code.google.com/p/estick-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/flashlink.cfg",
    "content": "#\n# ST FlashLINK JTAG parallel cable\n#\n# http://www.st.com/internet/evalboard/product/94023.jsp\n# http://www.st.com/stonline/products/literature/um/7889.pdf\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable flashlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ft232r/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to Radiona ULX3S board:\n# \tboard/radiona_ulx3s.cfg\n# See schematics for the ft232r layout:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nadapter driver ft232r\nadapter speed 1000\nft232r_vid_pid 0x0403 0x6015\nft232r_tck_num DSR\nft232r_tms_num DCD\nft232r_tdi_num RI\nft232r_tdo_num CTS\nft232r_trst_num RTS\nft232r_srst_num DTR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ft232r.cfg",
    "content": "adapter driver ft232r\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/100ask-openjtag.cfg",
    "content": "#\n# www.100ask.org OpenJTAG\n#\n# http://www.100ask.net/OpenJTAG.html\n#\n# Schematics are available from\n# https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"USB<=>JTAG&RS232\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0f08 0x0f1b\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/ashling-opella-ld-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi tdo_sample_edge falling\nftdi layout_init 0x0A68 0xFF7B\nftdi channel 0\nftdi layout_signal JTAGOE -ndata 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/ashling-opella-ld-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi layout_init 0x0860 0x0b7b\nftdi channel 0\nftdi layout_signal JTAGOE -data 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/axm0432.cfg",
    "content": "#\n# Axiom axm0432\n#\n# http://www.axman.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Symphony SoundBite\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/c232hm.cfg",
    "content": "# FTDI USB Hi-Speed to MPSSE Cable\n#\n# http://www.ftdichip.com/Products/Cables/USBMPSSE.htm\n#\n# C232HM-DDHSL-0 and C232HM-EDSL-0 provide 3.3V and 5V on pin 1 (Red),\n# respectively.\n#\n# Adapter: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_C232HM_MPSSE_CABLE.PDF\n# Chip: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf\n# See pinout/colors at end of this file.\n#\n# Tech notes:\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf\n\nadapter driver ftdi\n#ftdi device_desc \"C232HM-DDHSL-0\"\n#ftdi device_desc \"C232HM-EDHSL-0\"\n\n# Common PID for FT232H\nftdi vid_pid 0x0403 0x6014\n\n# Layout\n# High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low)\n# Low data byte 0x08 configures TMS on ACBUS3 initially high (asserted); TCK, TDI low\n# High direction byte 0x40 configures red LED on ACBUS6 as high (output)\n# Low direction byte 0x0b configures TDO on ACBUS2 as low (input)\nftdi layout_init 0x4008 0x400b\n\n# ---A*BUS-------CCCCCCCC|DDDDDDDD\n# --------\\______76543210|76543210\n# LED\t0x4000 = 01000000|00000000 = ACBUS6\n#GPIOL0\t0x0010 = 00000000|00010000 = ADBUS4\n#GPIOL1\t0x0020 = 00000000|00100000 = ADBUS5\n#GPIOL2\t0x0040 = 00000000|01000000 = ADBUS6\n#GPIOL3\t0x0080 = 00000000|10000000 = ADBUS7\n# -ndata treats the LED as active-low for expected behavior (toggle when transferring)\nftdi layout_signal LED -ndata 0x4000\n# Available for aliasing as desired\nftdi layout_signal GPIOL0 -data 0x0010 -oe 0x0010\nftdi layout_signal GPIOL1 -data 0x0020 -oe 0x0020\nftdi layout_signal GPIOL2 -data 0x0040 -oe 0x0040\nftdi layout_signal GPIOL3 -data 0x0080 -oe 0x0080\n\n# C232HM\t\tFT232H\tJTAG/Other\n# Num\tColor\tName\tFunc\n# 1\t\tRed\t\tVCC\t\tOptionally, can power the board if it is not using its own power supply.\n# 2\t\tOrange\tADBUS0\tTCK\n# 3\t\tYellow  ADBUS1\tTDI\n# 4\t\tGreen\tADBUS2\tTDO\n# 5\t\tBrown   ADBUS3\tTMS\n# 6\t\tGrey\tADBUS4\tGPIOL0\n# 7\t\tPurple\tADBUS5\tGPIOL1\n# 8\t\tWhite\tADBUS6\tGPIOL2\n# 9\t\tBlue\tADBUS7\tGPIOL3\n# 10\tBlack\tGND\t\tConnect to ground\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/calao-usb-a9260-c01.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C01\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/calao-usb-a9260-c02.cfg",
    "content": "#\n# CALAO Systems USB-A9260-C02\n#\n# http://www.calao-systems.com/\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6001\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\nscript interface/calao-usb-a9260.cfg\nscript target/at91sam9260minimal.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/cortino.cfg",
    "content": "#\n# Hitex Cortino\n#\n# http://www.hitex.com/index.php?id=cortino\n#\n\nadapter driver ftdi\nftdi device_desc \"Cortino\"\nftdi vid_pid 0x0640 0x0032\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/digilent-hs1.cfg",
    "content": "# this supports JTAG-HS1 and JTAG-SMT1\n# (the later being the OEM on-board version)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6010\n# channel 1 does not have any functionality\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/digilent-hs2.cfg",
    "content": "# this supports JTAG-HS2 (and apparently Nexys4 as well)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\n\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_hs3.cfg",
    "content": "#\n# Digilent JTAG-HS3\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"Digilent USB Device\"\n\n# From Digilent support:\n# The SRST pin is [...] 0x20 and 0x10 is the /OE (active low output enable)\n\nftdi layout_init 0x2088 0x308b\nftdi layout_signal nSRST -data 0x2000 -noe 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_smt2.cfg",
    "content": "#\n# Digilent JTAG-SMT2\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,1053&Prod=JTAG-SMT2\n#\n# Config is based on data from\n# http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x20e8 0x3feb\nftdi layout_signal nSRST -data 0x2000\nftdi layout_signal GPIO2 -data 0x2000\nftdi layout_signal GPIO1 -data 0x0200\nftdi layout_signal GPIO0 -data 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/digilent_jtag_smt2_nc.cfg",
    "content": "#\n# Digilent JTAG-SMT2-NC\n#\n# http://store.digilentinc.com/jtag-smt2-nc-surface-mount-programming-module/\n# https://reference.digilentinc.com/_media/jtag_smt2nc/jtag-smt2-nc_rm.pdf\n#\n# Based on reference sheet (above) and Xilinx KCU105 schematics\n# https://www.xilinx.com/products/boards-and-kits/kcu105.html#documentation\n#\n# Note that the digilent_jtag_smt2 layout does not work and hangs while\n# the ftdi device_desc from digilent_hs2 is wrong.\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/dlp-usb1232h.cfg",
    "content": "#\n# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module\n#\n# http://www.dlpdesign.com/usb/usb1232h.shtml\n#\n# Schematics for OpenOCD usage:\n# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/dp_busblaster.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the\n# JTAG header which allows it to emulate various debugger types. It comes\n# configured as a JTAGkey device.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\necho \"Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster\nand use dp_busblaster_kt-link.cfg instead\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/dp_busblaster_kt-link.cfg",
    "content": "#\n# Dangerous Prototypes - Bus Blaster (with KT-Link buffer)\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://github.com/bharrisau/busblaster and is SWD-enabled.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -ndata 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/esp32s2_kaluga_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Driver for the FT2232H JTAG chip on the Espressif Kaluga-1 ESP32-S2 board\n# (and most other FT2232H and FT232H based boards)\n#\n# JTAG DIP switch (labelled SW5 in the schematic) should be \"ON\" for lines\n# labelled TCK, TDO, TDI and TWS, to connect the FT2232H to the ESP32-S2.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010 0x0403 0x6014\n\n# interface 1 is the uart\nftdi channel 0\n\n# TCK, TDI, TDO, TMS: ADBUS0-3\n# TRST/SRST: ADBUS5 (unused for now)\n# LEDs: ACBUS3-4 (inverted)\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal LED -ndata 0x0800\nftdi layout_signal LED2 -ndata 0x1000\n\n# ESP32* series chips do not have a TRST input, and the SRST line is connected\n# to the EN pin.\n# The target code doesn't handle SRST reset properly yet, so this is\n# commented out:\n# ftdi layout_signal nSRST -oe 0x0020\n# reset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/flossjtag-noeeprom.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used\n# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you\n# have several Floss-JTAG connected you have to use the USB ID to select a\n# specific one.\n#\n# If you have a Floss-JTAG WITH EEPROM that is programmed, use the\n# flossjtag.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/flossjtag.cfg",
    "content": "#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the\n# existence of an EEPROM on Floss-JTAG containing a name. If you have several\n# Floss-JTAG adapters connected you can use the serial number to select a\n# specific device.\n#\n# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the\n# flossjtag-noeeprom.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi device_desc \"FLOSS-JTAG\"\n# adapter serial \"FJ000001\"\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x0800\nftdi layout_signal LED2 -data 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/flyswatter.cfg",
    "content": "#\n# TinCanTools Flyswatter\n#\n# http://web.archive.org/web/20150419072034/http://www.tincantools.com/JTAG/Flyswatter.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0818 0x0cfb\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/flyswatter2.cfg",
    "content": "#\n# TinCanTools Flyswatter2\n#\n# https://www.tincantools.com/product/flyswatter2/\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter2\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0538 0x057b\nftdi layout_signal LED -ndata 0x0400\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020 -noe 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/ft232h-module-swd.cfg",
    "content": "#\n# ADAFRUIT FTDI FT232H as a SWD direct connect interface\n# Any FT232H based board may work\n#\n# http://www.ftdichip.com/Products/ICs/FT232H.htm\n#\n#\n\nadapter driver ftdi\n\nftdi vid_pid 0x0403 0x6014\n\n# data MSB..LSB       direction (1:out) MSB..LSB\n# 0000'0000'0011'0000 0000'0000'0011'1011\nftdi layout_init 0x0030 0x003b\n# 0xfff8 0xfffb\n# Those signal are only required on some platforms or may required to be\n# enabled explicitly (e.g. nrf5x chips).\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\n\n# swd enable\nftdi layout_signal SWD_EN -data 0\n# tri-state (configure as input) TDO/TIO when reading\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n\n# re-configure TDO as tri-state\n#ftdi layout_signal TDO -data 0x0002 -oe 0x0002\n#ftdi layout_signal TDI -data 0x0004\n\n# Adafruit      FT232H    JTAG       SWD\n# Name  Pin     Name      Func       Func\n#  D0   J1-3    ADBUS0    TCK        SWDCLK\n#  D1   J1-4    ADBUS1    TDO/DI     SWDIO\n#  D2   J1-5    ADBUS2    TDI/DO     SWDIO\n#  D3   J1-6    ADBUS3    TMS        N/A\n#  D4   J1-7    ADBUS4    (GPIOL0)   /nSRST  optional module reset\n#  D5   J1-8    ADBUS5    (GPIOL1)   /nTRST  optional target reset\n#  D6   J1-9    ADBUS6    (GPIOL2)\n#  D7   J1-10   ADBUS7    (GPIOL3)\n#  C0   J2-1    ACBUS0    (GPIOH0)\n#  C1   J2-2    ACBUS1    (GPIOH1)\n#  C2   J2-3    ACBUS2    (GPIOH2)\n#  C3   J2-4    ACBUS3    (GPIOH3)\n#  C4   J2-5    ACBUS4    (GPIOH4)\n#  C5   J2-6    ACBUS5    (GPIOH5)\n#  C6   J2-7    ACBUS6    (GPIOH6)\n#  C7   J2-8    ACBUS7    (GPIOH7)\n#  C8   J2-9    ACBUS8\n#  C9   J2-10   ACBUS9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/gw16042.cfg",
    "content": "#\n# Gateworks GW16042 JTAG Dongle\n#\n# http://www.gateworks.com/\n#\n# Layout:  FTDI FT2232H\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO (input)\n#   ADBUS3 TMS\n#   ADBUS4 nTRST\n#   ADBUS5 nSRST\n#   ADBUS6 OE (active high) for TRST, TDI, TMS, TCK\n#   ADBUS7 NC\n#   ACBUS0-7 NC\n#   BDBUS0 RXD\n#   BDBUS1 TXD (input)\n#\n\nadapter driver ftdi\nftdi device_desc \"USB-JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0058 0x007b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hie-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Hofstädtler Industrie-Electronic (HIE) JTAG Debugger\n#\n# https://www.hofstaedtler.com/jtag\n#\n\nadapter driver ftdi\nftdi channel 0\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"HIE JTAG Debugger\"\n\nftdi layout_init 0x0c08 0x4f1b\n\n# define both Reset signals\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\n# Toggle USB LED\nftdi layout_signal LED -ndata 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx10_etm.cfg",
    "content": "#\n# Hilscher NXHX 10-ETM\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 10-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx500_etm.cfg",
    "content": "#\n# Hilscher NXHX 500-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx500_re.cfg",
    "content": "#\n# Hilscher NXHX 500-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx50_etm.cfg",
    "content": "#\n# Hilscher NXHX 50-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 50-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hilscher_nxhx50_re.cfg",
    "content": "#\n# Hilscher NXHX 50-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX50-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hitex_lpc1768stick.cfg",
    "content": "#\n# Hitex LPC1768-Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\n\nadapter driver ftdi\nftdi device_desc \"LPC1768-Stick\"\nftdi vid_pid 0x0640 0x0026\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/hitex_str9-comstick.cfg",
    "content": "#\n# Hitex STR9-comStick\n#\n# http://www.hitex.com/index.php?id=383\n#\n\nadapter driver ftdi\nftdi device_desc \"STR9-comStick\"\nftdi vid_pid 0x0640 0x002c\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/icebear.cfg",
    "content": "#\n# Section5 ICEBear\n#\n# http://section5.ch/icebear\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"ICEbear JTAG adapter\"\nftdi vid_pid 0x0403 0xc140\n\nftdi layout_init 0x0028 0x002b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/imx8mp-evk.cfg",
    "content": "#\n# Configuration file for NXP MC-IMX8MP-EVK on-board internal JTAG\n#\n# Using this interface requires enabling \"remote mode\" for the board using the\n# NXP bcu tool (see https://github.com/NXPmicro/bcu)\n#\n#\tbcu set_gpio remote_en 1 -board=imx8mpevk\n#\n# The REMOTE_EN gpio is accessible through the same FTDI adapter but it's\n# behind an I2C GPIO expander.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n\nftdi layout_init 0x00f8 0x000b\n\nftdi layout_signal RESET_B\t-data 0x0010 -oe 0x0010\n# Called SYS_nRST in schematics\nftdi layout_signal nSRST\t-data 0x0020 -oe 0x0020\nftdi layout_signal IO_nRST\t-data 0x0040 -oe 0x0040\nftdi layout_signal ONOFF_B\t-data 0x0080 -oe 0x0080\n\nftdi layout_signal GPIO1\t-data 0x0100 -oe 0x0100\nftdi layout_signal GPIO2\t-data 0x0200 -oe 0x0200\nftdi layout_signal GPIO3\t-data 0x0400 -oe 0x0400\nftdi layout_signal GPIO4\t-data 0x0800 -oe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/incircuit-icprog.cfg",
    "content": "#\n# In-Circuit's ICprog OpenOCD JTAG Adapter\n# https://shop.in-circuit.de/product_info.php?products_id=112\n#\n# Schematics available at\n# http://wiki.in-circuit.de/images/0/06/610000158A_openocd.pdf\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nSRST -noe 0x0400 -data 0x0800\nftdi layout_signal nTRST -noe 0x0100 -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/iotlab-usb.cfg",
    "content": "#\n# This is the integrated adapter as found on the IoT-LAB boards\n# https://github.com/iot-lab/iot-lab/wiki\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/isodebug.cfg",
    "content": "# isodebug v1\n# 5 kV isolated JTAG/SWD + UART adapter by Unjo AB\n\nadapter driver ftdi\nftdi vid_pid 0x22b7 0x150d\n\nftdi layout_init 0x0ff8 0xfffb\n\nftdi layout_signal LED -ndata 0x0100\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\nftdi layout_signal SWDIO_OE -data 0x0008\n\n# Mode signals, either of these needs to be high to drive the JTAG/SWD pins.\n# The power-on state is low for both signals but the init setting above sets\n# JTAG_EN high.\nftdi layout_signal SWD_EN -data 0x1000\nftdi layout_signal JTAG_EN -data 0x0800\n\n# In SWD mode, the JTAG_EN signal doubles as SWO_EN_N which switches the\n# second FTDI channel UART RxD to the SWO pin instead of the separate RxD\n# pin. Note that the default init state has this pin high so when OpenOCD\n# starts in SWD mode, SWO is by default disabled. To enable SWO tracing,\n# issue the command 'ftdi set_signal SWO_EN 1' where tracing is configured.\n# To switch back to using the separate UART, SWO_EN needs to be disabled\n# before exiting OpenOCD, or the adapter replugged.\nftdi layout_signal SWO_EN -nalias JTAG_EN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/jtag-lock-pick_tiny_2.cfg",
    "content": "#\n# DISTORTEC JTAG-lock-pick Tiny 2\n#\n# http://www.distortec.com\n#\n\nadapter driver ftdi\nftdi device_desc \"JTAG-lock-pick Tiny 2\"\nftdi vid_pid 0x0403 0x8220\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal SWDIO_OE -ndata 0x1000\nftdi layout_signal LED -ndata 0x8000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/jtagkey.cfg",
    "content": "#\n# Amontec JTAGkey\n#\n# http://www.amontec.com/jtagkey.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/jtagkey2.cfg",
    "content": "#\n# Amontec JTAGkey2\n#\n# http://www.amontec.com/jtagkey2.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/jtagkey2p.cfg",
    "content": "#\n# Amontec JTAGkey2P\n#\n# http://www.amontec.com/jtagkey2p.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2P\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/kt-link.cfg",
    "content": "#\n# Kristech KT-Link\n#\n# http://www.kristech.eu\n#\n\nadapter driver ftdi\nftdi device_desc \"KT-LINK\"\nftdi vid_pid 0x0403 0xbbe2\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -data 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to LambdaConcept ECPIX-5 board:\n# \tinterface/ftdi/lambdaconcept_ecpix-5.cfg\n# See schematics for the ftdi layout:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n\nadapter driver ftdi\nadapter speed 10000\nftdi_device_desc \"Dual RS232-HS\"\nftdi_vid_pid 0x0403 0x6010\n\nftdi_layout_init 0xfff8 0xfffb\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/lisa-l.cfg",
    "content": "#\n# Lisa/L\n#\n# http://paparazzi.enac.fr/wiki/Lisa\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Lisa/L\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x1800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/luminary-icdi.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S9B9x Evaluation Kits\n# In-Circuit Debug Interface (ICDI) Board\n#\n# Essentially all Luminary debug hardware is the same, (with both\n# JTAG and SWD support compatible with ICDI boards.  This ICDI adapter\n# configuration is JTAG-only, but the same hardware handles SWD too.\n#\n# This is a discrete ftdi based debug board which supports ARM's\n# JTAG/SWD connectors in both backwards-compatible 20-pin format and\n# in the new-style compact 10-pin.  There's also an 8-pin connector\n# with serial port support.  It's included with LM3S9B9x eval boards.\n#\n# http://www.luminarymicro.com/products/ek-lm3s9b90.html\n# http://www.luminarymicro.com/products/ek-lm3s9b92.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Luminary Micro ICDI Board\"\nftdi vid_pid 0x0403 0xbcda\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/luminary-lm3s811.cfg",
    "content": "#\n# Luminary Micro Stellaris LM3S811 Evaluation Kit\n#\n# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html\n#\n# NOTE:  this is only for boards *before* Rev C, which adds support\n# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals.\n# The \"evb_lm3s811\" layout doesn't set up those signals.\n#\n# Rev C boards work more like the other Stellaris eval boards.  They\n# need to use the \"luminary_icdi\" layout to work correctly.\n#\n\nadapter driver ftdi\nftdi device_desc \"LM3S811 Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x0088 0x008b\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/luminary.cfg",
    "content": "#\n# Luminary Micro Stellaris Evaluation Kits\n#\n# http://www.luminarymicro.com/products/evaluation_kits.html\n#\n# There are a number of evaluation kits for Stellaris Cortex-M3 chips.\n# Currently they all bundle ftdi based debug support.  When that is\n# used (instead of an external adapter), use this config file in one\n# of these two modes:\n#\n# - Eval board debug ... debug of the Stellaris chip via port A.\n#\n# - Other board debug ... same thing, but the board acts as a debug\n#   adapter for another board (using a standard ARM JTAG connector).\n#   The Stellaris chip stays in reset.\n#\n# Those support both JTAG and SWD.  SWD is an ARM-only two-wire debug\n# protocol; in 2009, OpenOCD does not support SWD.\n#\n# Port B of the ftdi chip is normally used as a serial link to the\n# Stellaris chip.  On most boards (but not older LM3S811 eval boards),\n# when SWD is used Port B may instead be used to read low-bandwidth\n# \"SWO trace\" data, including so-called \"printf style\" output from\n# firmware via the ITM module as well as profile data.\n#\n\nadapter driver ftdi\nftdi device_desc \"Stellaris Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/m53evk.cfg",
    "content": "#\n# DENX M53EVK\n#\n# http://www.denx-cs.de/?q=M53EVK\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/mbftdi.cfg",
    "content": "#\n# MBFTDI\n#\n# http://www.marsohod.org/prodmbftdi\n#\n# Also the Marsohod2 and the Marsohod3 boards\n# include a built-in MBFTDI for FPGA programming.\n# See http://www.marsohod.org/prodmarsohod2\n# and http://www.marsohod.org/plata-marsokhod3 for details.\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/minimodule-swd.cfg",
    "content": "#\n# Supports SWD using the FT2232H or FT4232H minimodule.\n# Each can support 2 SWD interfaces.\n#\n# FT2232H or FT4232H minimodule channel 0 (Channel A)\n# Connector  FTDI              Target\n# Pin        Name\n# ---------  ------            ------\n# CN2-11     VIO               VDD_IO (Or connect to CN2-5 on the minimodule instead for a 3V3 interface)\n# CN2-2      GND               GND\n# CN2-7      ADBUS0 (TCK)      SWCLK\n# CN2-9      ADBUS2 (TDI/TDO)  SWDIO\n# CN2-10     ADBUS1 (TDO/TDI)  SWDIO\n# CN2-14     ADBUS4 (GPIOL0)   nRESET\n#\n# FT2232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN3-26  -  SWCLK\n# CN3-25  -  SWDIO\n# CN3-24  -  SWDIO\n# CN3-21  -  nRESET\n#\n# FT4232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN2-18  -  SWCLK\n# CN2-17  -  SWDIO\n# CN2-20  -  SWDIO\n# CN2-22  -  nRESET\n#\n\nadapter driver ftdi\n\n#Select your module type and channel\n\n#ftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n#ftdi channel 1\n\n#ftdi device_desc \"FT4232H MiniModule\"\n#ftdi vid_pid 0x0403 0x6011\n#ftdi channel 1\n\nftdi layout_init 0x0000 0x000b\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal SWD_EN -data 0\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/minimodule.cfg",
    "content": "#\n# FTDI MiniModule\n#\n# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n\n# Every pin set as high impedance except TCK, TDI, TDO and TMS\nftdi layout_init 0x0008 0x000b\n\n# nSRST defined on pin CN2-13 of the MiniModule (pin ADBUS5 [AD5] on the FT2232H chip)\n# This choice is arbitrary. Use other GPIO pin if desired.\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/minispartan6.cfg",
    "content": "# https://www.scarabhardware.com/minispartan6/\n# https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf\nadapter driver ftdi\n# The miniSpartan6+ sadly doesn't have a custom device description, so we just\n# have to hope you got it right.\n#ftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 30000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/miniwiggler.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Infineon DAP miniWiggler V3\n#\n# https://www.infineon.com/cms/en/product/evaluation-boards/kit_miniwiggler_3_usb/\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 nOE (output enable)\n#   ADBUS5\n#   ADBUS6\n#   ADBUS7 Blue LED\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5\n#   ACBUS6\n#   ACBUS7\n#\n\nadapter driver ftdi\nftdi device_desc \"DAS JDS miniWiggler V3.1\"\nftdi vid_pid 0x058b 0x0043\n\nftdi channel 0\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/neodb.cfg",
    "content": "#\n# Openmoko USB JTAG/RS232 adapter\n#\n# http://wiki.openmoko.org/wiki/Debug_Board_v3\n#\n\nadapter driver ftdi\nftdi device_desc \"Debug Board for Neo1973\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\nftdi layout_signal nNOR_WP -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/ngxtech.cfg",
    "content": "#\n# NGX ARM USB JTAG\n#\n# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NGX JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-jtag-swd.cfg",
    "content": "#\n# Olimex ARM JTAG SWD adapter\n# https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-SWD/\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-ocd-h.cfg",
    "content": "#\n# Olimex ARM-USB-OCD-H\n#\n# http://www.olimex.com/dev/arm-usb-ocd-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-OCD-H\"\nftdi vid_pid 0x15ba 0x002b\n\nftdi layout_init 0x0908 0x0b1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-ocd.cfg",
    "content": "#\n# Olimex ARM-USB-OCD\n#\n# http://www.olimex.com/dev/arm-usb-ocd.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG\"\nftdi vid_pid 0x15ba 0x0003\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg",
    "content": "#\n# Olimex ARM-USB-TINY-H\n#\n# http://www.olimex.com/dev/arm-usb-tiny-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-TINY-H\"\nftdi vid_pid 0x15ba 0x002a\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/olimex-jtag-tiny.cfg",
    "content": "#\n# Olimex ARM-USB-TINY\n#\n# http://www.olimex.com/dev/arm-usb-tiny.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG TINY\"\nftdi vid_pid 0x15ba 0x0004\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/oocdlink.cfg",
    "content": "#\n# Joern Kaipf's OOCDLink\n#\n# http://www.joernonline.de/contrexx2/cms/index.php?page=126\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"OOCDLink\"\nftdi vid_pid 0x0403 0xbaf8\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/opendous_ftdi.cfg",
    "content": "#\n# Opendous\n#\n# http://code.google.com/p/opendous/wiki/JTAG\n#\n# According to the website, it is similar to jtagkey, but it uses channel B\n# (and it has a different pid number).\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/openocd-usb-hs.cfg",
    "content": "#\n# embedded projects openocd usb adapter v3\n#\n# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/openocd-usb.cfg",
    "content": "#\n# Hubert Hoegl's USB to JTAG\n#\n# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/openrd.cfg",
    "content": "#\n# Marvell OpenRD\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"OpenRD JTAGKey FT2232D B\"\nftdi vid_pid 0x0403 0x9e90\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/pipistrello.cfg",
    "content": "# http://pipistrello.saanlima.com/\n# http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf\nadapter driver ftdi\nftdi device_desc \"Pipistrello LX45\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/pls_spc5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# PLS SPC5-UDESTK\n#\n# https://www.st.com/en/development-tools/spc5-udestk.html\n#\n# Reference the SPC56D Discovery schematics.\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 TMS\n#   ADBUS5 RTCK\n#   ADBUS6\n#   ADBUS7 LED1\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST (external pull-down)\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5 nSRST direction (input=L, output=H, external pull-down)\n#   ACBUS6 TMS direction (input=L, output=H, external pull-up)\n#   ACBUS7 LED2\n#\n\nadapter driver ftdi\nftdi device_desc \"PLS USB/JTAG Adapter for SPC5xxx\"\nftdi vid_pid 0x263d 0x4001\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -ndata 0x2000 -oe 0x2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/redbee-econotag.cfg",
    "content": "#\n# Redwire Redbee-Econotag\n#\n# http://www.redwirellc.com/store/node/1\n#\n# The Redbee-Econotag has an onboard FT2232H with:\n#  - FT2232H channel A wired to mc13224v JTAG\n#  - FT2232H channel B wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/redbee-usb.cfg",
    "content": "#\n# Redwire Redbee-USB\n#\n# http://www.redwirellc.com\n#\n# The Redbee-USB has an onboard FT2232H with:\n#  - FT2232H channel B wired to mc13224v JTAG\n#  - FT2232H channel A wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/rowley-cc-arm-swd.cfg",
    "content": "#\n# Rowley ARM SWD Adapter\n# http://sites.fastspring.com/rowley/product/armswdadapter\n# https://drive.google.com/file/d/0Bzv7UpKpOQhnTUNNdzI5OUR4WGs/edit?usp=sharing\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/sheevaplug.cfg",
    "content": "#\n# Marvel SheevaPlug Development Kit\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"SheevaPlug JTAGKey FT2232D B\"\nftdi vid_pid 0x9e88 0x9e8f\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/signalyzer-lite.cfg",
    "content": "#\n# Xverve Signalyzer LITE (DT-USB-SLITE)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer LITE\"\nftdi vid_pid 0x0403 0xbca1\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/signalyzer.cfg",
    "content": "#\n# Xverve Signalyzer Tool (DT-USB-ST)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer\"\nftdi vid_pid 0x0403 0xbca0\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/snps_sdp.cfg",
    "content": "#  Copyright (C) 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Synopsys SDP Mainboard has embdded FT2232 chip, which is similar to Digilent\n# HS-1, except that it uses channel B for JTAG communication, instead of\n# channel A.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi layout_init 0x0088 0x008b\nftdi channel 1\n\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/steppenprobe.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Steppenprobe\n# https://github.com/diegoherranz/steppenprobe\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\n# Initial Layout\nftdi layout_init 0x0058 0x99fb\n# Signal        Data    Direction       Notes\n# TCK           0       1 (out)\n# TDI           0       1 (out)\n# TDO           0       0 (in)\n# TMS           1       1 (out)         JTAG IEEE std recommendation\n# LED           1       1 (out)         LED off\n# SWD_EN        0       1 (out)         OpenOCD sets this high for SWD\n# SWDIO_OE      1       1 (out)         Ext. buffer tristated\n# SRST          0       1 (out)         Translates to nSRST=Z\n\n# Unused        0       1 (out)\n# GPIO_A        0       0 (in)\n# GPIO_B        0       0 (in)\n# Unused        0       1 (out)\n# Unused        0       1 (out)\n# GPIO_C        0       0 (in)\n# GPIO_D        0       0 (in)\n# Unused        0       1 (out)\n\n# Signals definition\nftdi layout_signal LED -ndata 0x0010\nftdi layout_signal SWD_EN -data 0x0020\nftdi layout_signal SWDIO_OE -ndata 0x0040\nftdi layout_signal nSRST -oe 0x0080\n\nftdi layout_signal GPIO_A -data 0x0200 -oe 0x0200 -input 0x0200\nftdi layout_signal GPIO_B -data 0x0400 -oe 0x0400 -input 0x0400\nftdi layout_signal GPIO_C -data 0x2000 -oe 0x2000 -input 0x2000\nftdi layout_signal GPIO_D -data 0x4000 -oe 0x4000 -input 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/stm32-stick.cfg",
    "content": "#\n# Hitex STM32-PerformanceStick\n#\n# http://www.hitex.com/index.php?id=340\n#\n\nadapter driver ftdi\nftdi device_desc \"STM32-PerformanceStick\"\nftdi vid_pid 0x0640 0x002d\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/swd-resistor-hack.cfg",
    "content": "#\n# Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or\n# so depending on the drive capability of the target and adapter);\n# connect TDO directly to SWDIO.\n#\n# You also need to have reliable GND connection between the target and\n# adapter. Vref of the adapter should be supplied with a voltage equal\n# to the target's (preferably connect it to Vcc). You can also\n# optionally connect nSRST. Leave everything else unconnected.\n#\n# FTDI                          Target\n# ----                          ------\n# 1  - Vref   ----------------- Vcc\n# 3  - nTRST  -\n# 4  - GND    ----------------- GND\n# 5  - TDI    ---/\\470 Ohm/\\--- SWDIO\n# 7  - TMS    -\n# 9  - TCK    ----------------- SWCLK\n# 11 - RTCK   -\n# 13 - TDO    ----------------- SWDIO\n# 15 - nSRST  - - - - - - - - - nRESET\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -data 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/ti-icdi.cfg",
    "content": "#\n# This is an FTDI-based debugging solution as found on some TI boards,\n# e.g. CC3200 LaunchPad.\n#\n# The schematics are identical to luminary-icdi (including SWD\n# support) but the USB IDs are different.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0451 0xc32a\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/tigard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Tigard: An FTDI FT2232H-based multi-protocol tool for hardware hacking.\n# https://github.com/tigard-tools/tigard\n\nadapter driver ftdi\n\nftdi device_desc \"Tigard V1.1\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 1\n\nftdi layout_init 0x0038 0x003b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020\n\n# This board doesn't support open-drain reset modes since its output buffer is\n# always enabled.\nreset_config srst_push_pull trst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/tumpa-lite.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA) Lite\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a99\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/tumpa.cfg",
    "content": "#\n# TIAO USB Multi-Protocol Adapter (TUMPA)\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a98 0x0403 0x6010\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0010\n\nreset_config srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/turtelizer2-revB.cfg",
    "content": "#\n# egnite Turtelizer 2 rev B (with SRST only)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c5b\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/turtelizer2-revC.cfg",
    "content": "#\n# egnite Turtelizer 2 revC (with TRST and SRST)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c7b\nftdi layout_signal nTRST -oe 0x0020\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -ndata 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/um232h.cfg",
    "content": "#\n# FTDI UM232H as a JTAG interface\n#\n# http://www.ftdichip.com/Products/Modules/DevelopmentModules.htm#UM232H\n#\n# This should also work with a UM232H-B, but that has not been tested.\n# Note that UM232H and UM232H-B are 3.3V only.\n#\n\nadapter driver ftdi\n#ftdi device_desc \"UM232H\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0xfff8 0xfffb\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n\n# UM232H        FT232H    JTAG\n# Name  Pin     Name      Func\n# AD0   J2-6    ADBUS0    TCK\n# AD1   J2-7    ADBUS1    TDI\n# AD2   J2-8    ADBUS2    TDO\n# AD3   J2-9    ADBUS3    TMS\n# AD4   J2-10   ADBUS4    (GPIOL0)\n# AD5   J2-11   ADBUS5    (GPIOL1)\n# AD6   J2-12   ADBUS6    (GPIOL2)\n# AD7   J2-13   ADBUS7    (GPIOL3)\n# AD0   J1-14   ACBUS0    /TRST\n# AD1   J1-13   ACBUS1    /SRST\n# AD2   J1-12   ACBUS2    (GPIOH2)\n# AD3   J1-11   ACBUS3    (GPIOH3)\n# AD4   J1-10   ACBUS4    (GPIOH4)\n# AD5   J1-9    ACBUS5    (GPIOH5)\n# AD6   J1-8    ACBUS6    (GPIOH6)\n# AD7   J1-7    ACBUS7    (GPIOH7)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/vpaclink.cfg",
    "content": "#\n# Voipac VPACLink\n#\n# http://voipac.com/27M-JTG-000\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"VPACLink\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/xds100v2.cfg",
    "content": "#\n# Texas Instruments XDS100v2\n#\n# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features\n#\n# Detailed documentation is available only as CPLD verilog source code\n# to the registered TI users.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0xa6d0 0x0403 0x6010\n\nftdi layout_init 0x0038 0x597b\n\n#  8000 z - unused\n#  4000 0 > CPLD loopback          (all target side pins high-Z)\n#  2000 z < !( cable connected )   (open drain on CPLD side for $reasons)\n#  1000 0 > EMU1_oe\n#\n#   800 0 > PWR_RST = clear power-loss flag on rising edge\n#   400 z < !( power-loss flag )\n#   200 z < nSRST\n#   100 0 > nSRST_oe\n#\n#    80 z < RTCK\n#    40 0 > EMU0_oe\n#    20 1 > EMU_EN\n#    10 1 > nTRST\n#\n#     8 1 > TMS\n#     4 z < TDO\n#     2 0 > TDI\n#     1 0 > TCK\n#\n# As long as the power-loss flag is set, all target-side pins are\n# high-Z except the EMU-pins for which the opposite holds unless\n# EMU_EN is high.\n#\n# To use wait-in-reset, drive EMU0 low at power-on reset. If the\n# target normally reuses EMU0 for other purposes, clear EMU_EN to\n# keep the EMU pins high-Z until the target is power-cycled.\n#\n# The LED only turns off at USB suspend, which is also the only way to\n# set the power-loss flag manually. (Can be done in software e.g. by\n# changing the USB configuration to zero.)\n#\n\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0100\nftdi layout_signal EMU_EN -data 0x0020\nftdi layout_signal EMU0 -oe 0x0040\nftdi layout_signal EMU1 -oe 0x1000\nftdi layout_signal PWR_RST -data 0x0800\nftdi layout_signal LOOPBACK -data 0x4000\n\necho \"\\nInfo : to use this adapter you MUST add ``init; ftdi set_signal PWR_RST 1; jtag arp_init'' to the end of your config file!\\n\"\n# note: rising edge on PWR_RST is also needed after power-cycling the\n# target\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ftdi/xds100v3.cfg",
    "content": "#\n# Texas Instruments XDS100 ver 3.0\n#\n# http://processors.wiki.ti.com/index.php/XDS100\n#\n\n# Version 3.0 is the same as 2.0 as far as OpenOCD is concerned\nsource [find interface/ftdi/xds100v2.cfg]\n\n# The USB ids are different.\nftdi vid_pid 0x0403 0xa6d1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/imx-native.cfg",
    "content": "#\n# Config for using NXP IMX CPU\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches to host voltage and the cable is short enough.\n#\n#\n\nadapter driver imx_gpio\n\n# For most IMX processors 0x0209c000\nimx_gpio_peripheral_base 0x0209c000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for IMX6UL@528MHz\n# imx_gpio_speed SPEED_COEFF SPEED_OFFSET\nimx_gpio_speed_coeffs 50000 50\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo.\n# Example configuration:\n# imx_gpio_jtag_nums 6 7 8 9\n\n# SWD interface pins: swclk swdio\n# Example configuration:\nimx_gpio_swd_nums 1 6\n\n# imx_gpio_trst_num 10\n# reset_config trst_only\n\n# imx_gpio_srst_num 11\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/jlink.cfg",
    "content": "#\n# SEGGER J-Link\n#\n# http://www.segger.com/jlink.html\n#\n\nadapter driver jlink\n\n# The serial number can be used to select a specific device in case more than\n# one is connected to the host.\n#\n# Example: Select J-Link with serial number 123456789\n#\n# adapter serial 123456789\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/jtag_dpi.cfg",
    "content": "#\n# Provide support for the Cadence JTAG BFM\n#\n# Copyright (c) 2020, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\nadapter driver jtag_dpi\n\n# Set the DPI JTAG server port\nif { [info exists DPI_PORT] } {\n   set _DPI_PORT $DPI_PORT\n} else {\n   set _DPI_PORT 5555\n}\n\n# Set the DPI JTAG server address\nif { [info exists DPI_ADDRESS] } {\n   set _DPI_ADDRESS $DPI_ADDRESS\n} else {\n   set _DPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_dpi set_port $_DPI_PORT\njtag_dpi set_address $_DPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/jtag_hat_rpi2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Blinkinlabs JTAG_Hat\n#\n# https://github.com/blinkinlabs/jtag_hat\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio_peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio_speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio_jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio_swd_nums 11 25\n\n# Direction pin for SWDIO level shifting buffer\nbcm2835gpio_swdio_dir_num 6\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\nbcm2835gpio_trst_num 7\n#reset_config trst_only\n\nbcm2835gpio_srst_num 24\n#reset_config srst_only\n\n# or if you have both connected\n#reset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/jtag_vpi.cfg",
    "content": "adapter driver jtag_vpi\n\n# Set the VPI JTAG server port\nif { [info exists VPI_PORT] } {\n   set _VPI_PORT $VPI_PORT\n} else {\n   set _VPI_PORT 5555\n}\n\n# Set the VPI JTAG server address\nif { [info exists VPI_ADDRESS] } {\n   set _VPI_ADDRESS $VPI_ADDRESS\n} else {\n   set _VPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_vpi set_port $_VPI_PORT\njtag_vpi set_address $_VPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/kitprog.cfg",
    "content": "#\n# Cypress Semiconductor KitProg\n#\n# Note: This is the driver for the proprietary KitPtog protocol. If the\n# KitProg is in CMSIS-DAP mode, you should either use the cmsis-dap\n# interface driver or switch the KitProg to KitProg mode.\n#\n\nadapter driver kitprog\n\n# Optionally specify the serial number of the KitProg you want to use.\n# adapter serial 1926402735485200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/nds32-aice.cfg",
    "content": "#\n# Andes AICE\n#\n# http://www.andestech.com\n#\n\nadapter driver aice\naice desc \"Andes AICE adapter\"\n# adapter serial \"C001-42163\"\naice vid_pid 0x1CFC 0x0000\naice port aice_usb\nreset_config trst_and_srst\nadapter speed 24000\naice retry_times 50\naice count_to_check_dbger 30\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/nulink.cfg",
    "content": "#\n# Nuvoton Nu-Link in-circuit debugger/programmer\n#\n\nadapter driver hla\nhla_layout nulink\nhla_device_desc \"Nu-Link\"\nhla_vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201\n\n# Only swd is supported\ntransport select hla_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/opendous.cfg",
    "content": "#\n# opendous-jtag\n#\n# http://code.google.com/p/opendous-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/openjtag.cfg",
    "content": "#\n# OpenJTAG\n#\n# www.openjtag.org\n#\n\nadapter driver openjtag\nopenjtag device_desc \"Open JTAG Project\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/osbdm.cfg",
    "content": "#\n# P&E Micro OSBDM (aka OSJTAG) interface\n#\n# http://pemicro.com/osbdm/\n#\nadapter driver osbdm\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/parport.cfg",
    "content": "#\n# Parallel port wiggler (many clones available) on port 0x378\n#\n# Addresses: 0x378/LPT1 or 0x278/LPT2 ...\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   if {$tcl_platform(platform) eq \"windows\"} {\n      set _PARPORTADDR 0x378\n   } {\n      set _PARPORTADDR 0\n   }\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable wiggler\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/parport_dlc5.cfg",
    "content": "#\n# Xilinx Parallel Cable III 'DLC 5' (and various clones)\n#\n# http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable dlc5\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/raspberrypi-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x20000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 113714 28\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/raspberrypi2-native.cfg",
    "content": "#\n# Config for using Raspberry Pi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nbcm2835gpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nbcm2835gpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# bcm2835gpio trst_num 7\n# reset_config trst_only\n\n# bcm2835gpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/rlink.cfg",
    "content": "#\n# Raisonance RLink\n#\n# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html\n#\n\nadapter driver rlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/rshim.cfg",
    "content": "#\n# BlueField SoC in-circuit debugger/programmer\n#\n\nadapter driver rshim\ntransport select dapdirect_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/stlink-dap.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n# This new interface driver creates a ST-Link wrapper for ARM-DAP named \"dapdirect\"\n# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support \"dapdirect\"\n#\n# SWIM transport is natively supported\n#\n\nadapter driver st-link\nst-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# transport select dapdirect_jtag\n# transport select dapdirect_swd\n# transport select swim\n\n# Optionally specify the serial number of usb device\n# e.g.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/stlink-v1.cfg",
    "content": "echo \"WARNING: interface/stlink-v1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/stlink-v2-1.cfg",
    "content": "echo \"WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/stlink-v2.cfg",
    "content": "echo \"WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/stlink.cfg",
    "content": "#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n\nadapter driver hla\nhla_layout stlink\nhla_device_desc \"ST-LINK\"\nhla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754\n\n# Optionally specify the serial number of ST-LINK/V2 usb device.  ST-LINK/V2\n# devices seem to have serial numbers with unreadable characters.  ST-LINK/V2\n# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial\n# number reset issues.\n# eg.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/sysfsgpio-raspberrypi.cfg",
    "content": "#\n# Config for using RaspberryPi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver sysfsgpio\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nsysfsgpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nsysfsgpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# sysfsgpio trst_num 7\n# reset_config trst_only\n\n# sysfsgpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ti-icdi.cfg",
    "content": "#\n# TI Stellaris In-Circuit Debug Interface (ICDI) Board\n#\n# This is the propriety ICDI interface used on newer boards such as\n# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232\n# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad\n# http://www.ti.com/tool/ek-lm4f232\n#\n\nadapter driver hla\nhla_layout ti-icdi\nhla_vid_pid 0x1cbe 0x00fd\n\n# Optionally specify the serial number of TI-ICDI devices, for when using\n# multiple devices. Serial numbers can be obtained using lsusb -v\n# Ex.\n# adapter serial \"0F003065\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/ulink.cfg",
    "content": "#\n# Keil ULINK running OpenULINK firmware.\n#\n# http://www.keil.com/ulink1/\n# http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362\n#\n\nadapter driver ulink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/usb-jtag.cfg",
    "content": "# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC.\n#\n# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware\n# including;\n#  * Xilinx USB Platform Cable\n#  * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards\n#  * Many fpga4fun.com boards from such as the Saxo and Xylo boards\n#  * The Numato Opsis\n#\n# Original version - http://www.ixo.de/info/usb_jtag/\n#  Updated version - http://ixo-jtag.sourceforge.net/\n#   Newest version - http://github.com/mithro/ixo-usb-jtag\n#\n# Procedure for using is;\n#  * Get the ixo-usb-jtag firmware for your hardware (or build it yourself).\n#  * Load the firmware using the fxload tool.\n#  * Use openocd.\n#\n# Unless you burn the firmware into the EEPROM on your device, power cycling\n# will require you to reload the firmware using the fxload tool. This can be\n# automated by using udev rules (which can be found in the firmware\n# repository).\n#\n# Ubuntu packages built from mithro's version (with prebuilt firmware and udev\n# rules) can be found at\n# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support\n#\n# TODO: Refactor the usb_blaster driver to allow loading firmware using any low\n# level driver. Loading firmware is currently only supported on the ublast2\n# driver but ixo-usb-jtag requires the ftdi driver.\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x16C0 0x06AD\nusb_blaster device_desc \"Van Ooijen Technische Informatica\"\n# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the\n# ftdi modes, using ublast2 will cause openocd to hang.\nusb_blaster lowlevel_driver ftdi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/usbprog.cfg",
    "content": "#\n# Embedded Projects USBprog\n#\n# http://embedded-projects.net/index.php?page_id=135\n#\n\nadapter driver usbprog\n# USBprog is broken w/short TMS sequences, this is a workaround\n# until the C code can be fixed.\ntms_sequence long\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/vdebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n\nif { [info exists VDEBUGHOST] } {\n\tset _VDEBUGHOST $VDEBUGHOST\n} else {\n\tset _VDEBUGHOST localhost\n}\nif { [info exists VDEBUGPORT] } {\n\tset _VDEBUGPORT $VDEBUGPORT\n} else {\n\tset _VDEBUGPORT 8192\n}\n\nadapter driver vdebug\n# vdebug server:port\nvdebug server $_VDEBUGHOST:$_VDEBUGPORT\n\n# example config debug level and log\n#debug_level 3\n#log_output vd_ocd.log\n\n# example config listen on all interfaces, disable tcl/telnet server\nbindto 0.0.0.0\n#gdb_port 3333\n#telnet_port disabled\ntcl_port disabled\n\n# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw\nvdebug batching 1\n\n# Polling values\nvdebug polling 100 1000"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/vsllink.cfg",
    "content": "#\n# Versaloon Link -- VSLLink\n#\n# http://www.versaloon.com/\n#\n\nadapter driver vsllink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/interface/xds110.cfg",
    "content": "#\n# Texas Instruments XDS110\n#\n# http://processors.wiki.ti.com/index.php/XDS110\n# http://processors.wiki.ti.com/index.php/Emulation_Software_Package#XDS110_Support_Utilities\n#\n\nadapter driver xds110\n\n# Use serial number option to use a specific XDS110\n# when more than one are connected to the host.\n# adapter serial 00000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/mem_helper.tcl",
    "content": "# Helper for common memory read/modify/write procedures\n\n# mrw: \"memory read word\", returns value of $reg\nproc mrw {reg} {\n\treturn [read_memory $reg 32 1]\n}\n\nadd_usage_text mrw \"address\"\nadd_help_text mrw \"Returns value of word in memory.\"\n\n# mrh: \"memory read halfword\", returns value of $reg\nproc mrh {reg} {\n\treturn [read_memory $reg 16 1]\n}\n\nadd_usage_text mrh \"address\"\nadd_help_text mrh \"Returns value of halfword in memory.\"\n\n# mrb: \"memory read byte\", returns value of $reg\nproc mrb {reg} {\n\treturn [read_memory $reg 8 1]\n}\n\nadd_usage_text mrb \"address\"\nadd_help_text mrb \"Returns value of byte in memory.\"\n\n# mmw: \"memory modify word\", updates value of $reg\n#       $reg <== ((value & ~$clearbits) | $setbits)\nproc mmw {reg setbits clearbits} {\n\tset old [mrw $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\tmww $reg $new\n}\n\nadd_usage_text mmw \"address setbits clearbits\"\nadd_help_text mmw \"Modify word in memory. new_val = (old_val & ~clearbits) | setbits;\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/memory.tcl",
    "content": "# MEMORY\n#\n# All Memory regions have two components.\n#    (1) A count of regions, in the form N_NAME\n#    (2) An array within info about each region.\n#\n# The ARRAY\n#\n#       <NAME>(  RegionNumber ,  ATTRIBUTE )\n#\n# Where <NAME> is one of:\n#\n#     N_FLASH  & FLASH   (internal memory)\n#     N_RAM    & RAM     (internal memory)\n#     N_MMREGS & MMREGS  (for memory mapped registers)\n#     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)\n# or  N_UNKNOWN & UNKNOWN for things that do not exist.\n#\n# We have 1 unknown region.\nset N_UNKNOWN 1\n# All MEMORY regions must have these attributes\n#     CS          - chip select (if internal, use -1)\nset UNKNOWN(0,CHIPSELECT) -1\n#     BASE        - base address in memory\nset UNKNOWN(0,BASE)       0\n#     LEN         - length in bytes\nset UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS\n#     HUMAN       - human name of the region\nset UNKNOWN(0,HUMAN) \"unknown\"\n#     TYPE        - one of:\n#                       flash, ram, mmr, unknown\n#                    For harvard arch:\n#                       iflash, dflash, iram, dram\nset UNKNOWN(0,TYPE)       \"unknown\"\n#     RWX         - access ablity\n#                       unix style chmod bits\n#                           0 - no access\n#                           1 - execute\n#                           2 - write\n#                           4 - read\n#                       hence: 7 - readwrite execute\nset RWX_NO_ACCESS     0\nset RWX_X_ONLY        $BIT0\nset RWX_W_ONLY        $BIT1\nset RWX_R_ONLY        $BIT2\nset RWX_RW            [expr {$RWX_R_ONLY + $RWX_W_ONLY}]\nset RWX_R_X           [expr {$RWX_R_ONLY + $RWX_X_ONLY}]\nset RWX_RWX           [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]\nset UNKNOWN(0,RWX)     $RWX_NO_ACCESS\n\n#     WIDTH       - access width\n#                      8,16,32 [0 means ANY]\nset ACCESS_WIDTH_NONE 0\nset ACCESS_WIDTH_8    $BIT0\nset ACCESS_WIDTH_16   $BIT1\nset ACCESS_WIDTH_32   $BIT2\nset ACCESS_WIDTH_ANY  [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]\nset UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE\n\nproc iswithin { ADDRESS BASE LEN } {\n    return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]\n}\n\nproc address_info { ADDRESS } {\n\n    foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {\n\tif { info exists $WHERE } {\n\t    set lmt [set N_[set WHERE]]\n\t    for { set region 0 } { $region < $lmt } { incr region } {\n\t\tif { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {\n\t\t    return  \"$WHERE $region\";\n\t\t}\n\t    }\n\t}\n    }\n\n    # Return the 'unknown'\n    return \"UNKNOWN 0\"\n}\n\nproc memread32 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n\nproc memread32_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/mmr_helpers.tcl",
    "content": "\nproc proc_exists { NAME } {\n    set n [info commands $NAME]\n    set l [string length $n]\n    return [expr {$l != 0}]\n}\n\n# Give: REGISTER name - must be a global variable.\nproc show_mmr32_reg { NAME } {\n\n    global $NAME\n    # we want $($NAME)\n    set a [set [set NAME]]\n\n    if ![catch { set v [memread32 $a] } msg ] {\n\techo [format \"%15s: (0x%08x): 0x%08x\" $NAME $a $v]\n\n\t# Was a helper defined?\n\tset fn show_${NAME}_helper\n\tif [ proc_exists $fn ] {\n\t    # Then call it\n\t    $fn $NAME $a $v\n\t}\n\treturn $v;\n    } else {\n\terror [format \"%s (%s)\" $msg $NAME ]\n    }\n}\n\n\n# Give: NAMES - an array of names accessible\n#               in the callers symbol-scope.\n#       VAL - the bits to display.\n\nproc show_mmr32_bits { NAMES VAL } {\n\n    upvar $NAMES MYNAMES\n\n    set w 5\n    foreach {IDX N} $MYNAMES {\n\tset l [string length $N]\n\tif { $l > $w } { set w $l }\n    }\n\n    for { set x 24 } { $x >= 0 } { incr x -8 } {\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    set s $MYNAMES([expr {$x + $y}])\n\t    echo -n [format \"%2d: %-*s | \" [expr {$x + $y}] $w $s ]\n\t}\n\techo \"\"\n\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    echo -n [format \"    %d%*s | \" [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] \"\"]\n\t}\n\techo \"\"\n    }\n}\n\n\nproc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } {\n    set width [expr {(($MSB - $LSB + 1) + 7) / 4}]\n    set nval [show_normalize_bitfield $VAL $MSB $LSB ]\n    set name0 [lindex $FIELDVALUES 0 ]\n    if [ string compare $name0 _NUMBER_ ] {\n\tset sval [lindex $FIELDVALUES $nval]\n    } else {\n\tset sval \"\"\n    }\n    echo [format \"%-15s: %d (0x%0*x) %s\" $FIELDNAME $nval $width $nval $sval ]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/1986ве1т.cfg",
    "content": "# 1986ВЕ1Т\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=236&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME 1986ве1т\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# use AHB-Lite SRAM for work area\n$_TARGETNAME configure -work-area-phys 0x20100000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/adsp-sc58x.cfg",
    "content": "#\n# Analog Devices ADSP-SC58x (ARM Cortex-A5 plus one or two SHARC+ DSPs)\n#\n\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ADSP-SC58x\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3BA02477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ap0.mem mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -event examine-end {\n   global _TARGETNAME\n   sc58x_enabledebug\n}\n\nproc sc58x_enabledebug {} {\n   # Enable debugging functionality by setting bits in the TAPC_DBGCTL register\n   # it is not possible to halt the target unless these bits have been set\n   ap0.mem mww 0x31131000 0xFFFF\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/aduc702x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aduc702x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n## JTAG scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# allocate the entire SRAM as working area\n$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000\n\n## flash configuration\n# only target number is needed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n## If you use the watchdog, the following code makes sure that the board\n## doesn't reboot when halted via JTAG.  Yes, on the older generation\n## AdUC702x, timer3 continues running even when the CPU is halted.\n\nproc watchdog_service {} {\n    global watchdog_hdl\n    mww 0xffff036c 0\n#    echo \"watchdog!!\"\n    set watchdog_hdl [after 500 watchdog_service]\n}\n\n$_TARGETNAME configure -event reset-halt-post {  watchdog_service }\n$_TARGETNAME configure -event resume-start { global watchdog_hdl; after cancel $watchdog_hdl }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/aducm360.cfg",
    "content": "#\n# This file was created using as references the stm32f1x.cfg and aduc702x.cfg\n#\nsource [find target/swj-dp.tcl]\n\n# Chip name\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aducm360\n}\n\n# Endianness\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# Eventually, the whole SRAM of ADuCM360 will be used (8kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# SWD/JTAG speed\nadapter speed 1000\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# allocate the working area\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME\n\nadapter srst delay 100\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/allwinner_v3s.cfg",
    "content": "# This is the config for an Allwinner V3/V3s (sun8iw8).\n#\n# Notes:\n# - Single core ARM Cortex-A7 with a maximum frequency of 1.2 GHz.\n# - Thumb-2 Technology\n# - Support NEON Advanced SIMD(Single Instruction Multiple Data)instruction\n#   for acceleration of media and signal processing functions\n# - Support Large Physical Address Extensions(LPAE)\n# - VFPv4 Floating Point Unit\n# - 32KB L1 Instruction cache and 32KB L1 Data cache\n# - 128KB L2 cache\n# - has some integrated DDR2 RAM.\n#\n# Pins related for debug and bootstrap:\n#   JTAG\n# JTAG_TMS\tPF0, SDC0_D1\n# JTAG_TDI\tPF1, SDC0_D0\n# JTAG_TDO\tPF3, SDC0_CMD\n# JTAG_TCK\tPF5, SDC0_D2\n#   UART\n# None of UART ports seems to be enabled by ROM.\n# UART0_TX\tPF2, SDC0_CLK\t\tPer default disabled\n# UART0_RX\tPF4, SDC0_D3 \t\tPer default disabled\n# UART1_TX\tPE21\t\t\tPer default disabled\n# UART1_RX\tPE22\t \t\tPer default disabled\n# UART2_TX\tPB0\t\t\tPer default disabled\n# UART2_RX\tPB1\t \t\tPer default disabled\n#\n# JTAG is enabled by default after power on on listed JTAG_* pins. So far the\n# boot sequence is:\n# Time\t\tAction\n# 0000ms\tPower ON\n# 0200ms\tJTAG enabled\n# 0220ms\tJTAG pins switched to SD mode\n#\n# The time frame of 20ms can be not enough to init and halt the CPU. In this\n# case I would recommend to set: \"adapter speed 15000\"\n# To get more or less precise timings, the board should provide reset pin,\n# or some bench power supply with remote function. In my case I used\n# EEZ H24005 with this command to power on and halt the target:\n# \"exec  echo \"*TRG\" > /dev/ttyACM0; sleep 220; reset halt\"\n# After this it is possible to enable JTAG mode again from boot loader or OS.\n# Following DAPs are available:\n# dap[0]->MEM-AP AHB\n# dap[1]->MEM-AP APB->CA7[0]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME v3s\n}\n\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# No NRST or SRST is present on the SoC. Boards may provide\n# some sort of Power cycle reset for complete board or SoC.\n# For this case we provide srst_pulls_trst so the board config\n# only needs to set srst_only.\nreset_config none srst_pulls_trst\n\njtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Add Cortex A7 core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/alphascale_asm9260t.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME asm9260t\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x079264F3\n}\n\n# And srst_pulls_trst by chip design.\nreset_config srst_pulls_trst\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/altera_fpgasoc.cfg",
    "content": "#\n# Altera cyclone V SoC family, 5Cxxx\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME fpgasoc\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga\nif { [info exists FPGA_TAPID] } {\n   set _FPGA_TAPID $FPGA_TAPID\n} else {\n   set _FPGA_TAPID 0x02d020dd\n}\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected-id $_FPGA_TAPID\n\n\n#\n# Cortex-A9 target\n#\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80110000\n# core 1  -  0x80112000\n\n# Slow speed to be sure it will work\nadapter speed 1000\n\nset _TARGETNAME1 $_CHIPNAME.cpu.0\nset _TARGETNAME2 $_CHIPNAME.cpu.1\n\n# A9 core 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80110000\n\n$_TARGETNAME1 configure -event reset-start { adapter speed 1000 }\n$_TARGETNAME1 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME1\"\n\n\n# A9 core 1\n#target create $_TARGETNAME2 cortex_a -dap $_CHIPNAME.dap \\\n#        -coreid 1 -dbgbase 0x80112000\n\n#$_TARGETNAME2 configure -event reset-start { adapter speed 1000 }\n#$_TARGETNAME2 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME2\"\n\nproc cycv_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/altera_fpgasoc_arria10.cfg",
    "content": "# Intel (Altera) Arria10 FPGA SoC\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME arria10\n}\n\n# ARM CoreSight Debug Access Port (dap HPS)\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga (tap)\n# See Intel Arria 10 Handbook\n# https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-10/a10_handbook.pdf\n# Intel Arria 10 GX 160  0x02ee20dd\n# Intel Arria 10 GX 220  0x02e220dd\n# Intel Arria 10 GX 270  0x02ee30dd\n# Intel Arria 10 GX 320  0x02e230dd\n# Intel Arria 10 GX 480  0x02e240dd\n# Intel Arria 10 GX 570  0x02ee50dd\n# Intel Arria 10 GX 660  0x02e250dd\n# Intel Arria 10 GX 900  0x02ee60dd\n# Intel Arria 10 GX 1150 0x02e660dd\n# Intel Arria 10 GT 900  0x02e260dd\n# Intel Arria 10 GT 1150 0x02e060dd\n# Intel Arria 10 SX 160  0x02e620dd\n# Intel Arria 10 SX 220  0x02e020dd\n# Intel Arria 10 SX 270  0x02e630dd\n# Intel Arria 10 SX 320  0x02e030dd\n# Intel Arria 10 SX 480  0x02e040dd\n# Intel Arria 10 SX 570  0x02e650dd\n# Intel Arria 10 SX 660  0x02e050dd\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -expected-id 0x02ee20dd -expected-id 0x02e220dd \\\n\t-expected-id 0x02ee30dd -expected-id 0x02e230dd -expected-id 0x02e240dd \\\n\t-expected-id 0x02ee50dd -expected-id 0x02e250dd -expected-id 0x02ee60dd \\\n\t-expected-id 0x02e660dd -expected-id 0x02e260dd -expected-id 0x02e060dd \\\n\t-expected-id 0x02e620dd -expected-id 0x02e020dd -expected-id 0x02e630dd \\\n\t-expected-id 0x02e030dd -expected-id 0x02e040dd -expected-id 0x02e650dd \\\n\t-expected-id 0x02e050dd\n\nset _TARGETNAME $_CHIPNAME.cpu\n\n#\n# Cortex-A9 target\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap -coreid 0\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap -coreid 1 \\\n\t-defer-examine\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/am335x.cfg",
    "content": "source [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME am335x\n}\n\n# set the taps to be enabled by default. this can be overridden\n# by setting DEFAULT_TAPS in a separate configuration file\n# or directly on the command line.\nif { [info exists DEFAULT_TAPS] } {\n\tset _DEFAULT_TAPS \"$DEFAULT_TAPS\"\n} else {\n\tset _DEFAULT_TAPS \"$_CHIPNAME.tap\"\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 12 0\"\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# M3 DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME m3_tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m3_tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 11 0\"\ndap create $_CHIPNAME.m3_dap -chain-position $_CHIPNAME.m3_tap\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0b94402f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup {\n\tglobal _DEFAULT_TAPS\n\tenable_default_taps $_DEFAULT_TAPS\n}\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n#\n# helper function that enables all taps passed as argument\n#\nproc enable_default_taps { taps } {\n\tforeach tap $taps {\n\t\tjtag tapenable $tap\n\t}\n}\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME_2 $_CHIPNAME.m3\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.m3_dap\n\n#\n# Cortex-A8 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80001000\n\n# SRAM: 64K at 0x4030.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x4000\n\n\n# when putting the target into 'reset halt', we need to disable the watchdog as\n# it would otherwise trigger while we're in JTAG\n# FIXME: unify with target/am437x.cfg\nsource [find mem_helper.tcl]\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/am437x.cfg",
    "content": "source [find target/icepick.cfg]\nsource [find mem_helper.tcl]\n\n###############################################################################\n##\t\t\t\tAM437x Registers\t\t\t     ##\n###############################################################################\nset  PRCM_BASE_ADDR                  0x44df0000\nset  REVISION_PRM                    [expr       {$PRCM_BASE_ADDR     +  0x0000}]\nset  PRM_IRQSTATUS_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0004}]\nset  PRM_IRQENABLE_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0008}]\nset  PRM_IRQSTATUS_M3                [expr       {$PRCM_BASE_ADDR     +  0x000c}]\nset  PRM_IRQENABLE_M3                [expr       {$PRCM_BASE_ADDR     +  0x0010}]\nset  PM_MPU_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0300}]\nset  PM_MPU_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0304}]\nset  RM_MPU_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0314}]\nset  RM_MPU_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0324}]\nset  PM_GFX_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0400}]\nset  PM_GFX_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0404}]\nset  RM_GFX_RSTCTRL                  [expr       {$PRCM_BASE_ADDR     +  0x0410}]\nset  RM_GFX_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0414}]\nset  RM_GFX_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0424}]\nset  RM_RTC_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0524}]\nset  RM_WKUP_RSTCTRL                 [expr       {$PRCM_BASE_ADDR     +  0x2010}]\nset  RM_WKUP_RSTST                   [expr       {$PRCM_BASE_ADDR     +  0x2014}]\nset  CM_L3_AON_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x2800}]\nset  CM_WKUP_DEBUGSS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2820}]\nset  CM_L3S_TSC_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2900}]\nset  CM_WKUP_ADC_TSC_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2920}]\nset  CM_L4_WKUP_AON_CLKSTCTRL        [expr       {$PRCM_BASE_ADDR     +  0x2a00}]\nset  CM_WKUP_L4WKUP_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2a20}]\nset  CM_WKUP_WKUP_M3_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a28}]\nset  CM_WKUP_SYNCTIMER_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a30}]\nset  CM_WKUP_CLKDIV32K_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a38}]\nset  CM_WKUP_USBPHY0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a40}]\nset  CM_WKUP_USBPHY1_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a48}]\nset  CM_WKUP_CLKSTCTRL               [expr       {$PRCM_BASE_ADDR     +  0x2b00}]\nset  CM_WKUP_TIMER0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b20}]\nset  CM_WKUP_TIMER1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b28}]\nset  CM_WKUP_WDT0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b30}]\nset  CM_WKUP_WDT1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b38}]\nset  CM_WKUP_I2C0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b40}]\nset  CM_WKUP_UART0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b48}]\nset  CM_WKUP_SMARTREFLEX0_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b50}]\nset  CM_WKUP_SMARTREFLEX1_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b58}]\nset  CM_WKUP_CONTROL_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2b60}]\nset  CM_WKUP_GPIO0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b68}]\nset  CM_CLKMODE_DPLL_CORE            [expr       {$PRCM_BASE_ADDR     +  0x2d20}]\nset  CM_IDLEST_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d24}]\nset  CM_CLKSEL_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d2c}]\nset  CM_DIV_M4_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d38}]\nset  CM_DIV_M5_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d3c}]\nset  CM_DIV_M6_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d40}]\nset  CM_SSC_DELTAMSTEP_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d48}]\nset  CM_SSC_MODFREQDIV_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d4c}]\nset  CM_CLKMODE_DPLL_MPU             [expr       {$PRCM_BASE_ADDR     +  0x2d60}]\nset  CM_IDLEST_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d64}]\nset  CM_CLKSEL_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d6c}]\nset  CM_DIV_M2_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d70}]\nset  CM_SSC_DELTAMSTEP_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d88}]\nset  CM_SSC_MODFREQDIV_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d8c}]\nset  CM_CLKMODE_DPLL_DDR             [expr       {$PRCM_BASE_ADDR     +  0x2da0}]\nset  CM_IDLEST_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2da4}]\nset  CM_CLKSEL_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2dac}]\nset  CM_DIV_M2_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db0}]\nset  CM_DIV_M4_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db8}]\nset  CM_SSC_DELTAMSTEP_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dc8}]\nset  CM_SSC_MODFREQDIV_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dcc}]\nset  CM_CLKMODE_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2de0}]\nset  CM_IDLEST_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2de4}]\nset  CM_CLKSEL_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2dec}]\nset  CM_DIV_M2_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2df0}]\nset  CM_CLKSEL2_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2e04}]\nset  CM_SSC_DELTAMSTEP_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e08}]\nset  CM_SSC_MODFREQDIV_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e0c}]\nset  CM_CLKDCOLDO_DPLL_PER           [expr       {$PRCM_BASE_ADDR     +  0x2e14}]\nset  CM_CLKMODE_DPLL_DISP            [expr       {$PRCM_BASE_ADDR     +  0x2e20}]\nset  CM_IDLEST_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e24}]\nset  CM_CLKSEL_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e2c}]\nset  CM_DIV_M2_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e30}]\nset  CM_SSC_DELTAMSTEP_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e48}]\nset  CM_SSC_MODFREQDIV_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e4c}]\nset  CM_CLKMODE_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e60}]\nset  CM_IDLEST_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e64}]\nset  CM_CLKSEL_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e6c}]\nset  CM_DIV_M2_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e70}]\nset  CM_CLKSEL2_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e84}]\nset  CM_SSC_DELTAMSTEP_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e88}]\nset  CM_SSC_MODFREQDIV_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e8c}]\nset  CM_SHADOW_FREQ_CONFIG1          [expr       {$PRCM_BASE_ADDR     +  0x2fa0}]\nset  CM_SHADOW_FREQ_CONFIG2          [expr       {$PRCM_BASE_ADDR     +  0x2fa4}]\nset  CM_CLKOUT1_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4100}]\nset  CM_DLL_CTRL                     [expr       {$PRCM_BASE_ADDR     +  0x4104}]\nset  CM_CLKOUT2_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4108}]\nset  CLKSEL_TIMER1MS_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4200}]\nset  CLKSEL_TIMER2_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4204}]\nset  CLKSEL_TIMER3_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4208}]\nset  CLKSEL_TIMER4_CLK               [expr       {$PRCM_BASE_ADDR     +  0x420c}]\nset  CLKSEL_TIMER5_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4210}]\nset  CLKSEL_TIMER6_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4214}]\nset  CLKSEL_TIMER7_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4218}]\nset  CLKSEL_TIMER8_CLK               [expr       {$PRCM_BASE_ADDR     +  0x421c}]\nset  CLKSEL_TIMER9_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4220}]\nset  CLKSEL_TIMER10_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4224}]\nset  CLKSEL_TIMER11_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4228}]\nset  CLKSEL_WDT1_CLK                 [expr       {$PRCM_BASE_ADDR     +  0x422c}]\nset  CLKSEL_SYNCTIMER_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4230}]\nset  CLKSEL_MAC_CLK                  [expr       {$PRCM_BASE_ADDR     +  0x4234}]\nset  CLKSEL_CPTS_RFT_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4238}]\nset  CLKSEL_GFX_FCLK                 [expr       {$PRCM_BASE_ADDR     +  0x423c}]\nset  CLKSEL_GPIO0_DBCLK              [expr       {$PRCM_BASE_ADDR     +  0x4240}]\nset  CLKSEL_LCDC_PIXEL_CLK           [expr       {$PRCM_BASE_ADDR     +  0x4244}]\nset  CLKSEL_ICSS_OCP_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4248}]\nset  CLKSEL_DLL_AGING_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4250}]\nset  CLKSEL_USBPHY32KHZ_GCLK         [expr       {$PRCM_BASE_ADDR     +  0x4260}]\nset  CM_MPU_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8300}]\nset  CM_MPU_MPU_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8320}]\nset  CM_GFX_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8400}]\nset  CM_GFX_GFX_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8420}]\nset  CM_RTC_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8500}]\nset  CM_RTC_RTC_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8520}]\nset  CM_PER_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8800}]\nset  CM_PER_L3_CLKCTRL               [expr       {$PRCM_BASE_ADDR     +  0x8820}]\nset  CM_PER_AES0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8828}]\nset  CM_PER_DES_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8830}]\nset  CM_PER_CRYPTODMA_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8838}]\nset  CM_PER_L3_INSTR_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8840}]\nset  CM_PER_MSTR_EXPS_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8848}]\nset  CM_PER_OCMCRAM_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8850}]\nset  CM_PER_SHA0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8858}]\nset  CM_PER_SLV_EXPS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8860}]\nset  CM_PER_VPFE0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8868}]\nset  CM_PER_VPFE1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8870}]\nset  CM_PER_TPCC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8878}]\nset  CM_PER_TPTC0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8880}]\nset  CM_PER_TPTC1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8888}]\nset  CM_PER_TPTC2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8890}]\nset  CM_PER_DLL_AGING_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8898}]\nset  CM_PER_L4HS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a0}]\nset  CM_PER_L4FW_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a8}]\nset  CM_PER_L3S_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8a00}]\nset  CM_PER_GPMC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a20}]\nset  CM_PER_IEEE5000_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8a28}]\nset  CM_PER_MCASP0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a38}]\nset  CM_PER_MCASP1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a40}]\nset  CM_PER_MMC2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a48}]\nset  CM_PER_QSPI_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a58}]\nset  CM_PER_USB_OTG_SS0_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a60}]\nset  CM_PER_USB_OTG_SS1_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a68}]\nset  CM_PER_ICSS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8b00}]\nset  CM_PER_ICSS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8b20}]\nset  CM_PER_L4LS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8c00}]\nset  CM_PER_L4LS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8c20}]\nset  CM_PER_DCAN0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c28}]\nset  CM_PER_DCAN1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c30}]\nset  CM_PER_EPWMSS0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c38}]\nset  CM_PER_EPWMSS1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c40}]\nset  CM_PER_EPWMSS2_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c48}]\nset  CM_PER_EPWMSS3_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c50}]\nset  CM_PER_EPWMSS4_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c58}]\nset  CM_PER_EPWMSS5_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c60}]\nset  CM_PER_ELM_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8c68}]\nset  CM_PER_GPIO1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c78}]\nset  CM_PER_GPIO2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c80}]\nset  CM_PER_GPIO3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c88}]\nset  CM_PER_GPIO4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c90}]\nset  CM_PER_GPIO5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c98}]\nset  CM_PER_HDQ1W_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8ca0}]\nset  CM_PER_I2C1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8ca8}]\nset  CM_PER_I2C2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cb0}]\nset  CM_PER_MAILBOX0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8cb8}]\nset  CM_PER_MMC0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc0}]\nset  CM_PER_MMC1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc8}]\nset  CM_PER_PKA_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8cd0}]\nset  CM_PER_RNG_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8ce0}]\nset  CM_PER_SPARE0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8ce8}]\nset  CM_PER_SPARE1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8cf0}]\nset  CM_PER_SPI0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d00}]\nset  CM_PER_SPI1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d08}]\nset  CM_PER_SPI2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d10}]\nset  CM_PER_SPI3_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d18}]\nset  CM_PER_SPI4_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d20}]\nset  CM_PER_SPINLOCK_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8d28}]\nset  CM_PER_TIMER2_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d30}]\nset  CM_PER_TIMER3_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d38}]\nset  CM_PER_TIMER4_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d40}]\nset  CM_PER_TIMER5_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d48}]\nset  CM_PER_TIMER6_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d50}]\nset  CM_PER_TIMER7_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d58}]\nset  CM_PER_TIMER8_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d60}]\nset  CM_PER_TIMER9_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d68}]\nset  CM_PER_TIMER10_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d70}]\nset  CM_PER_TIMER11_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d78}]\nset  CM_PER_UART1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d80}]\nset  CM_PER_UART2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d88}]\nset  CM_PER_UART3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d90}]\nset  CM_PER_UART4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d98}]\nset  CM_PER_UART5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8da0}]\nset  CM_PER_USBPHYOCP2SCP0_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8db8}]\nset  CM_PER_USBPHYOCP2SCP1_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8dc0}]\nset  CM_PER_EMIF_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8f00}]\nset  CM_PER_EMIF_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8f20}]\nset  CM_PER_DLL_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8f28}]\nset  CM_PER_EMIF_FW_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8f30}]\nset  CM_PER_OTFA_EMIF_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8f38}]\nset  CM_PER_DSS_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9200}]\nset  CM_PER_DSS_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x9220}]\nset  CM_PER_CPSW_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x9300}]\nset  CM_PER_CPGMAC0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x9320}]\nset  CM_PER_OCPWP_L3_CLKSTCTRL       [expr       {$PRCM_BASE_ADDR     +  0x9400}]\nset  CM_PER_OCPWP_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9420}]\n\nset  CONTROL_BASE_ADDR               0x44e10000\nset  CONTROL_STATUS                  [expr       {$CONTROL_BASE_ADDR  +  0x0040}]\nset  DEVICE_ID                       [expr       {$CONTROL_BASE_ADDR  +  0x0600}]\nset  DEV_FEATURE                     [expr       {$CONTROL_BASE_ADDR  +  0x0604}]\nset  DEV_ATTRIBUTE                   [expr       {$CONTROL_BASE_ADDR  +  0x0610}]\nset  MAC_ID0_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0630}]\nset  MAC_ID0_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x0634}]\nset  MAC_ID1_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0638}]\nset  MAC_ID1_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x063c}]\nset  USB_VID_PID                     [expr       {$CONTROL_BASE_ADDR  +  0x07f4}]\nset  CONTROL_CONF_ECAP0_IN_PWM0_OUT  [expr       {$CONTROL_BASE_ADDR  +  0x0964}]\nset  CONTROL_CONF_SPI4_CS0           [expr       {$CONTROL_BASE_ADDR  +  0x0a5c}]\nset  CONTROL_CONF_SPI2_SCLK          [expr       {$CONTROL_BASE_ADDR  +  0x0a60}]\nset  CONTROL_CONF_SPI2_D0            [expr       {$CONTROL_BASE_ADDR  +  0x0a64}]\nset  CONTROL_CONF_XDMA_EVENT_INTR0   [expr       {$CONTROL_BASE_ADDR  +  0x0a70}]\nset  CONTROL_CONF_XDMA_EVENT_INTR1   [expr       {$CONTROL_BASE_ADDR  +  0x0a74}]\nset  CONTROL_CONF_GPMC_A0            [expr       {$CONTROL_BASE_ADDR  +  0x0840}]\nset  DDR_IO_CTRL                     [expr       {$CONTROL_BASE_ADDR  +  0x0e04}]\nset  VTP_CTRL_REG                    [expr       {$CONTROL_BASE_ADDR  +  0x0e0c}]\nset  VREF_CTRL                       [expr       {$CONTROL_BASE_ADDR  +  0x0e14}]\nset  DDR_CKE_CTRL                    [expr       {$CONTROL_BASE_ADDR  +  0x131c}]\nset  DDR_ADDRCTRL_IOCTRL             [expr       {$CONTROL_BASE_ADDR  +  0x1404}]\nset  DDR_ADDRCTRL_WD0_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x1408}]\nset  DDR_ADDRCTRL_WD1_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x140c}]\nset  DDR_DATA0_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1440}]\nset  DDR_DATA1_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1444}]\nset  DDR_DATA2_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1448}]\nset  DDR_DATA3_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x144c}]\nset  EMIF_SDRAM_CONFIG_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1460}]\nset  EMIF_SDRAM_STATUS_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1464}]\n\nset  GPIO0_BASE_ADDR                 0x44e07000\nset  GPIO0_SYSCONFIG                 [expr       {$GPIO0_BASE_ADDR    +  0x0010}]\nset  GPIO0_SYSSTATUS                 [expr       {$GPIO0_BASE_ADDR    +  0x0114}]\nset  GPIO0_CTRL                      [expr       {$GPIO0_BASE_ADDR    +  0x0130}]\nset  GPIO0_OE                        [expr       {$GPIO0_BASE_ADDR    +  0x0134}]\nset  GPIO0_CLEARDATAOUT              [expr       {$GPIO0_BASE_ADDR    +  0x0190}]\nset  GPIO0_SETDATAOUT                [expr       {$GPIO0_BASE_ADDR    +  0x0194}]\n\nset  GPIO5_BASE_ADDR                 0x48322000\nset  GPIO5_SYSCONFIG                 [expr       {$GPIO5_BASE_ADDR    +  0x0010}]\nset  GPIO5_SYSSTATUS                 [expr       {$GPIO5_BASE_ADDR    +  0x0114}]\nset  GPIO5_CTRL                      [expr       {$GPIO5_BASE_ADDR    +  0x0130}]\nset  GPIO5_OE                        [expr       {$GPIO5_BASE_ADDR    +  0x0134}]\nset  GPIO5_CLEARDATAOUT              [expr       {$GPIO5_BASE_ADDR    +  0x0190}]\nset  GPIO5_SETDATAOUT                [expr       {$GPIO5_BASE_ADDR    +  0x0194}]\n\nset  GPIO1_BASE_ADDR                 0x4804c000\nset  GPIO1_SYSCONFIG                 [expr       {$GPIO1_BASE_ADDR    +  0x0010}]\nset  GPIO1_SYSSTATUS                 [expr       {$GPIO1_BASE_ADDR    +  0x0114}]\nset  GPIO1_CTRL                      [expr       {$GPIO1_BASE_ADDR    +  0x0130}]\nset  GPIO1_OE                        [expr       {$GPIO1_BASE_ADDR    +  0x0134}]\nset  GPIO1_CLEARDATAOUT              [expr       {$GPIO1_BASE_ADDR    +  0x0190}]\nset  GPIO1_SETDATAOUT                [expr       {$GPIO1_BASE_ADDR    +  0x0194}]\n\nset  EMIF_BASE_ADDR                  0x4c000000\nset  EMIF_STATUS                     [expr       {$EMIF_BASE_ADDR     +  0x0004}]\nset  EMIF_SDRAM_CONFIG               [expr       {$EMIF_BASE_ADDR     +  0x0008}]\nset  EMIF_SDRAM_CONFIG_2             [expr       {$EMIF_BASE_ADDR     +  0x000c}]\nset  EMIF_SDRAM_REF_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0010}]\nset  EMIF_SDRAM_REF_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0014}]\nset  EMIF_SDRAM_TIM_1                [expr       {$EMIF_BASE_ADDR     +  0x0018}]\nset  EMIF_SDRAM_TIM_1_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x001c}]\nset  EMIF_SDRAM_TIM_2                [expr       {$EMIF_BASE_ADDR     +  0x0020}]\nset  EMIF_SDRAM_TIM_2_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x0024}]\nset  EMIF_SDRAM_TIM_3                [expr       {$EMIF_BASE_ADDR     +  0x0028}]\nset  EMIF_SDRAM_TIM_3_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x002c}]\nset  EMIF_LPDDR2_NVM_TIM             [expr       {$EMIF_BASE_ADDR     +  0x0030}]\nset  EMIF_LPDDR2_NVM_TIM_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0034}]\nset  EMIF_PWR_MGMT_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x0038}]\nset  EMIF_PWR_MGMT_CTRL_SHDW         [expr       {$EMIF_BASE_ADDR     +  0x003c}]\nset  EMIF_LPDDR2_MODE_REG_DATA       [expr       {$EMIF_BASE_ADDR     +  0x0040}]\nset  EMIF_LPDDR2_MODE_REG_CFG        [expr       {$EMIF_BASE_ADDR     +  0x0050}]\nset  EMIF_OCP_CONFIG                 [expr       {$EMIF_BASE_ADDR     +  0x0054}]\nset  EMIF_OCP_CFG_VAL_1              [expr       {$EMIF_BASE_ADDR     +  0x0058}]\nset  EMIF_OCP_CFG_VAL_2              [expr       {$EMIF_BASE_ADDR     +  0x005c}]\nset  EMIF_IODFT_TLGC                 [expr       {$EMIF_BASE_ADDR     +  0x0060}]\nset  EMIF_IODFT_CTRL_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0064}]\nset  EMIF_IODFT_ADDR_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0068}]\nset  EMIF_IODFT_DATA_MISR_RSLT_1     [expr       {$EMIF_BASE_ADDR     +  0x006c}]\nset  EMIF_IODFT_DATA_MISR_RSLT_2     [expr       {$EMIF_BASE_ADDR     +  0x0070}]\nset  EMIF_IODFT_DATA_MISR_RSLT_3     [expr       {$EMIF_BASE_ADDR     +  0x0074}]\nset  EMIF_PERF_CNT_1                 [expr       {$EMIF_BASE_ADDR     +  0x0080}]\nset  EMIF_PERF_CNT_2                 [expr       {$EMIF_BASE_ADDR     +  0x0084}]\nset  EMIF_PERF_CNT_CFG               [expr       {$EMIF_BASE_ADDR     +  0x0088}]\nset  EMIF_PERF_CNT_SEL               [expr       {$EMIF_BASE_ADDR     +  0x008c}]\nset  EMIF_PERF_CNT_TIM               [expr       {$EMIF_BASE_ADDR     +  0x0090}]\nset  EMIF_MISC_REG                   [expr       {$EMIF_BASE_ADDR     +  0x0094}]\nset  EMIF_DLL_CALIB_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0098}]\nset  EMIF_DLL_CALIB_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x009c}]\nset  EMIF_IRQ_EOI                    [expr       {$EMIF_BASE_ADDR     +  0x00a0}]\nset  EMIF_IRQSTATUS_RAW_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00a4}]\nset  EMIF_IRQSTATUS_SYS              [expr       {$EMIF_BASE_ADDR     +  0x00ac}]\nset  EMIF_IRQENABLE_SET_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00b4}]\nset  EMIF_IRQENABLE_CLR_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00bc}]\nset  EMIF_ZQ_CONFIG                  [expr       {$EMIF_BASE_ADDR     +  0x00c8}]\nset  EMIF_TEMP_ALERT_CONFIG          [expr       {$EMIF_BASE_ADDR     +  0x00cc}]\nset  EMIF_OCP_ERR_LOG                [expr       {$EMIF_BASE_ADDR     +  0x00d0}]\nset  EMIF_RDWR_LVL_RMP_WIN           [expr       {$EMIF_BASE_ADDR     +  0x00d4}]\nset  EMIF_RDWR_LVL_RMP_CTRL          [expr       {$EMIF_BASE_ADDR     +  0x00d8}]\nset  EMIF_RDWR_LVL_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x00dc}]\nset  EMIF_DDR_PHY_CTRL_1             [expr       {$EMIF_BASE_ADDR     +  0x00e4}]\nset  EMIF_DDR_PHY_CTRL_1_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x00e8}]\nset  EMIF_DDR_PHY_CTRL_2             [expr       {$EMIF_BASE_ADDR     +  0x00ec}]\nset  EMIF_PRI_COS_MAP                [expr       {$EMIF_BASE_ADDR     +  0x0100}]\nset  EMIF_CONNID_COS_1_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0104}]\nset  EMIF_CONNID_COS_2_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0108}]\nset  ECC_CTRL                        [expr       {$EMIF_BASE_ADDR     +  0x0110}]\nset  ECC_ADDR_RNG_1                  [expr       {$EMIF_BASE_ADDR     +  0x0114}]\nset  ECC_ADDR_RNG_2                  [expr       {$EMIF_BASE_ADDR     +  0x0118}]\nset  EMIF_RD_WR_EXEC_THRSH           [expr       {$EMIF_BASE_ADDR     +  0x0120}]\nset  COS_CONFIG                      [expr       {$EMIF_BASE_ADDR     +  0x0124}]\n\nset  PHY_STATUS_1                    [expr       {$EMIF_BASE_ADDR     +  0x0144}]\nset  PHY_STATUS_2                    [expr       {$EMIF_BASE_ADDR     +  0x0148}]\nset  PHY_STATUS_3                    [expr       {$EMIF_BASE_ADDR     +  0x014c}]\nset  PHY_STATUS_4                    [expr       {$EMIF_BASE_ADDR     +  0x0150}]\nset  PHY_STATUS_5                    [expr       {$EMIF_BASE_ADDR     +  0x0154}]\nset  PHY_STATUS_6                    [expr       {$EMIF_BASE_ADDR     +  0x0158}]\nset  PHY_STATUS_7                    [expr       {$EMIF_BASE_ADDR     +  0x015c}]\nset  PHY_STATUS_8                    [expr       {$EMIF_BASE_ADDR     +  0x0160}]\nset  PHY_STATUS_9                    [expr       {$EMIF_BASE_ADDR     +  0x0164}]\nset  PHY_STATUS_10                   [expr       {$EMIF_BASE_ADDR     +  0x0168}]\nset  PHY_STATUS_11                   [expr       {$EMIF_BASE_ADDR     +  0x016c}]\nset  PHY_STATUS_12                   [expr       {$EMIF_BASE_ADDR     +  0x0170}]\nset  PHY_STATUS_13                   [expr       {$EMIF_BASE_ADDR     +  0x0174}]\nset  PHY_STATUS_14                   [expr       {$EMIF_BASE_ADDR     +  0x0178}]\nset  PHY_STATUS_15                   [expr       {$EMIF_BASE_ADDR     +  0x017c}]\nset  PHY_STATUS_16                   [expr       {$EMIF_BASE_ADDR     +  0x0180}]\nset  PHY_STATUS_17                   [expr       {$EMIF_BASE_ADDR     +  0x0184}]\nset  PHY_STATUS_18                   [expr       {$EMIF_BASE_ADDR     +  0x0188}]\nset  PHY_STATUS_19                   [expr       {$EMIF_BASE_ADDR     +  0x018c}]\nset  PHY_STATUS_20                   [expr       {$EMIF_BASE_ADDR     +  0x0190}]\nset  PHY_STATUS_21                   [expr       {$EMIF_BASE_ADDR     +  0x0194}]\nset  PHY_STATUS_22                   [expr       {$EMIF_BASE_ADDR     +  0x0198}]\nset  PHY_STATUS_23                   [expr       {$EMIF_BASE_ADDR     +  0x019c}]\nset  PHY_STATUS_24                   [expr       {$EMIF_BASE_ADDR     +  0x01a0}]\nset  PHY_STATUS_25                   [expr       {$EMIF_BASE_ADDR     +  0x01a4}]\nset  PHY_STATUS_26                   [expr       {$EMIF_BASE_ADDR     +  0x01a8}]\nset  PHY_STATUS_27                   [expr       {$EMIF_BASE_ADDR     +  0x01ac}]\nset  PHY_STATUS_28                   [expr       {$EMIF_BASE_ADDR     +  0x01b0}]\n\nset  EXT_PHY_CTRL_1                  [expr       {$EMIF_BASE_ADDR     +  0x0200}]\nset  EXT_PHY_CTRL_1_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0204}]\nset  EXT_PHY_CTRL_2                  [expr       {$EMIF_BASE_ADDR     +  0x0208}]\nset  EXT_PHY_CTRL_2_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x020c}]\nset  EXT_PHY_CTRL_3                  [expr       {$EMIF_BASE_ADDR     +  0x0210}]\nset  EXT_PHY_CTRL_3_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0214}]\nset  EXT_PHY_CTRL_4                  [expr       {$EMIF_BASE_ADDR     +  0x0218}]\nset  EXT_PHY_CTRL_4_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x021c}]\nset  EXT_PHY_CTRL_5                  [expr       {$EMIF_BASE_ADDR     +  0x0220}]\nset  EXT_PHY_CTRL_5_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0224}]\nset  EXT_PHY_CTRL_6                  [expr       {$EMIF_BASE_ADDR     +  0x0228}]\nset  EXT_PHY_CTRL_6_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x022c}]\nset  EXT_PHY_CTRL_7                  [expr       {$EMIF_BASE_ADDR     +  0x0230}]\nset  EXT_PHY_CTRL_7_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0234}]\nset  EXT_PHY_CTRL_8                  [expr       {$EMIF_BASE_ADDR     +  0x0238}]\nset  EXT_PHY_CTRL_8_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x023c}]\nset  EXT_PHY_CTRL_9                  [expr       {$EMIF_BASE_ADDR     +  0x0240}]\nset  EXT_PHY_CTRL_9_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0244}]\nset  EXT_PHY_CTRL_10                 [expr       {$EMIF_BASE_ADDR     +  0x0248}]\nset  EXT_PHY_CTRL_10_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x024c}]\nset  EXT_PHY_CTRL_11                 [expr       {$EMIF_BASE_ADDR     +  0x0250}]\nset  EXT_PHY_CTRL_11_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0254}]\nset  EXT_PHY_CTRL_12                 [expr       {$EMIF_BASE_ADDR     +  0x0258}]\nset  EXT_PHY_CTRL_12_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x025c}]\nset  EXT_PHY_CTRL_13                 [expr       {$EMIF_BASE_ADDR     +  0x0260}]\nset  EXT_PHY_CTRL_13_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0264}]\nset  EXT_PHY_CTRL_14                 [expr       {$EMIF_BASE_ADDR     +  0x0268}]\nset  EXT_PHY_CTRL_14_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x026c}]\nset  EXT_PHY_CTRL_15                 [expr       {$EMIF_BASE_ADDR     +  0x0270}]\nset  EXT_PHY_CTRL_15_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0274}]\nset  EXT_PHY_CTRL_16                 [expr       {$EMIF_BASE_ADDR     +  0x0278}]\nset  EXT_PHY_CTRL_16_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x027c}]\nset  EXT_PHY_CTRL_17                 [expr       {$EMIF_BASE_ADDR     +  0x0280}]\nset  EXT_PHY_CTRL_17_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0284}]\nset  EXT_PHY_CTRL_18                 [expr       {$EMIF_BASE_ADDR     +  0x0288}]\nset  EXT_PHY_CTRL_18_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x028c}]\nset  EXT_PHY_CTRL_19                 [expr       {$EMIF_BASE_ADDR     +  0x0290}]\nset  EXT_PHY_CTRL_19_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0294}]\nset  EXT_PHY_CTRL_20                 [expr       {$EMIF_BASE_ADDR     +  0x0298}]\nset  EXT_PHY_CTRL_20_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x029c}]\nset  EXT_PHY_CTRL_21                 [expr       {$EMIF_BASE_ADDR     +  0x02a0}]\nset  EXT_PHY_CTRL_21_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02a4}]\nset  EXT_PHY_CTRL_22                 [expr       {$EMIF_BASE_ADDR     +  0x02a8}]\nset  EXT_PHY_CTRL_22_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ac}]\nset  EXT_PHY_CTRL_23                 [expr       {$EMIF_BASE_ADDR     +  0x02b0}]\nset  EXT_PHY_CTRL_23_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02b4}]\nset  EXT_PHY_CTRL_24                 [expr       {$EMIF_BASE_ADDR     +  0x02b8}]\nset  EXT_PHY_CTRL_24_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02bc}]\nset  EXT_PHY_CTRL_25                 [expr       {$EMIF_BASE_ADDR     +  0x02c0}]\nset  EXT_PHY_CTRL_25_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02c4}]\nset  EXT_PHY_CTRL_26                 [expr       {$EMIF_BASE_ADDR     +  0x02c8}]\nset  EXT_PHY_CTRL_26_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02cc}]\nset  EXT_PHY_CTRL_27                 [expr       {$EMIF_BASE_ADDR     +  0x02d0}]\nset  EXT_PHY_CTRL_27_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02d4}]\nset  EXT_PHY_CTRL_28                 [expr       {$EMIF_BASE_ADDR     +  0x02d8}]\nset  EXT_PHY_CTRL_28_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02dc}]\nset  EXT_PHY_CTRL_29                 [expr       {$EMIF_BASE_ADDR     +  0x02e0}]\nset  EXT_PHY_CTRL_29_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02e4}]\nset  EXT_PHY_CTRL_30                 [expr       {$EMIF_BASE_ADDR     +  0x02e8}]\nset  EXT_PHY_CTRL_30_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ec}]\nset  EXT_PHY_CTRL_31                 [expr       {$EMIF_BASE_ADDR     +  0x02f0}]\nset  EXT_PHY_CTRL_31_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02f4}]\nset  EXT_PHY_CTRL_32                 [expr       {$EMIF_BASE_ADDR     +  0x02f8}]\nset  EXT_PHY_CTRL_32_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02fc}]\nset  EXT_PHY_CTRL_33                 [expr       {$EMIF_BASE_ADDR     +  0x0300}]\nset  EXT_PHY_CTRL_33_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0304}]\nset  EXT_PHY_CTRL_34                 [expr       {$EMIF_BASE_ADDR     +  0x0308}]\nset  EXT_PHY_CTRL_34_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x030c}]\nset  EXT_PHY_CTRL_35                 [expr       {$EMIF_BASE_ADDR     +  0x0310}]\nset  EXT_PHY_CTRL_35_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0314}]\nset  EXT_PHY_CTRL_36                 [expr       {$EMIF_BASE_ADDR     +  0x0318}]\nset  EXT_PHY_CTRL_36_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x031c}]\n\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\n\nset  RTC_BASE_ADDR                   0x44e3e000\nset  RTC_KICK0R                      [expr       {$RTC_BASE_ADDR      +  0x6c}]\nset  RTC_KICK1R                      [expr       {$RTC_BASE_ADDR      +  0x70}]\n\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME am437x\n}\n\nset JRC_MODULE\t\ticepick_d\nset DEBUGSS_MODULE\tdebugss\nset M3_MODULE\t\tm3_wakeupss\n\nset JRC_NAME\t\t$_CHIPNAME.$JRC_MODULE\nset DEBUGSS_NAME\t$_CHIPNAME.$DEBUGSS_MODULE\nset M3_NAME\t\t$_CHIPNAME.$M3_MODULE\nset _TARGETNAME\t\t$_CHIPNAME.mpuss\n\n#\n# M3 WakeupSS DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME $M3_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $M3_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 11 0\"\ndap create $M3_NAME.dap -chain-position $M3_NAME\n\n#\n# DebugSS DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x46b6902f\n}\njtag newtap $_CHIPNAME $DEBUGSS_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $DEBUGSS_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 12 0\"\ndap create $DEBUGSS_NAME.dap -chain-position $DEBUGSS_NAME\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b98c02f\n}\njtag newtap $_CHIPNAME $JRC_MODULE -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $JRC_NAME -event setup \"jtag tapenable $DEBUGSS_NAME\"\n # some TCK tycles are required to activate the DEBUG power domain\njtag configure $JRC_NAME -event post-reset \"runtest 100\"\n\n#\n# Cortex-A9 target\n#\ntarget create $_TARGETNAME cortex_a -dap $DEBUGSS_NAME.dap -coreid 0 -dbgbase 0x80000000\n\n\n# SRAM: 256K at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x40000\n\n# Disables watchdog timer after reset otherwise board won't stay in\n# halted state.\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n\nproc ceil { x y } {\n\treturn [ expr {($x + $y - 1) / $y} ]\n}\n\nproc device_type { } {\n\tglobal CONTROL_STATUS\n\n\tset tmp [ mrw $CONTROL_STATUS ]\n\tset tmp [ expr {$tmp & 0x700} ]\n\tset tmp [ expr {$tmp >> 8} ]\n\n\treturn $tmp\n}\n\nproc get_input_clock_frequency { } {\n\tglobal CONTROL_STATUS\n\n\tif { [ device_type ] != 3 } {\n\t\terror \"Unknown device type\\n\"\n\t\treturn -1\n\t}\n\n\tset freq [ mrw $CONTROL_STATUS ]\n\tset freq [ expr {$freq & 0x00c00000} ]\n\tset freq [ expr {$freq >> 22} ]\n\n\tswitch $freq {\n\t\t0 {\n\t\t\tset CLKIN 19200000\n\t\t}\n\n\t\t1 {\n\t\t\tset CLKIN 24000000\n\t\t}\n\n\t\t2 {\n\t\t\tset CLKIN 25000000\n\t\t}\n\n\t\t3 {\n\t\t\tset CLKIN 26000000\n\t\t}\n\t}\n\n\treturn $CLKIN\n}\n\nproc mpu_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_MPU\n\tglobal CM_CLKSEL_DPLL_MPU\n\tglobal CM_DIV_M2_DPLL_MPU\n\tglobal CM_IDLEST_DPLL_MPU\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_MPU ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ]\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_MPU $clksel\n\n\tset div_m2 [ expr {$div_m2 & (~0x1f)} ]\n\tset div_m2 [ expr {$div_m2 | $M2} ]\n\tmww $CM_DIV_M2_DPLL_MPU $div_m2\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x7\n\twhile { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { }\n\n\techo \"MPU DPLL locked\"\n}\n\nproc core_pll_config { CLKIN N M M4 M5 M6 } {\n\tglobal CM_CLKMODE_DPLL_CORE\n\tglobal CM_CLKSEL_DPLL_CORE\n\tglobal CM_DIV_M4_DPLL_CORE\n\tglobal CM_DIV_M5_DPLL_CORE\n\tglobal CM_DIV_M6_DPLL_CORE\n\tglobal CM_IDLEST_DPLL_CORE\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_CORE ]\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_CORE $clksel\n\tmww $CM_DIV_M4_DPLL_CORE $M4\n\tmww $CM_DIV_M5_DPLL_CORE $M5\n\tmww $CM_DIV_M6_DPLL_CORE $M6\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { }\n\n\techo \"CORE DPLL locked\"\n}\n\nproc per_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_PER\n\tglobal CM_CLKSEL_DPLL_PER\n\tglobal CM_DIV_M2_DPLL_PER\n\tglobal CM_IDLEST_DPLL_PER\n\n\tset x [ expr {$M * $CLKIN / 1000000} ]\n\tset y [ expr {($N + 1) * 250} ]\n\tset sd [ ceil $x $y ]\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_PER ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_PER ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0xff0fffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tset clksel [ expr {$clksel | ($sd << 24)} ]\n\tmww $CM_CLKSEL_DPLL_PER $clksel\n\n\tset div_m2 [ expr {0xffffff80 | $M2} ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { }\n\n\techo \"PER DPLL locked\"\n}\n\nproc ddr_pll_config { CLKIN N M M2 M4 } {\n\tglobal CM_CLKMODE_DPLL_DDR\n\tglobal CM_CLKSEL_DPLL_DDR\n\tglobal CM_DIV_M2_DPLL_DDR\n\tglobal CM_DIV_M4_DPLL_DDR\n\tglobal CM_IDLEST_DPLL_DDR\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_DDR ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ]\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_DDR $clksel\n\n\tset div_m2 [ expr {($div_m2 & 0xffffffe0) | $M2} ]\n\tmww $CM_DIV_M2_DPLL_DDR $div_m2\n\tmww $CM_DIV_M4_DPLL_DDR $M4\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { }\n\n\techo \"DDR DPLL Locked\"\n}\n\nproc config_opp100 { } {\n\tset CLKIN [ get_input_clock_frequency ]\n\n\tif { $CLKIN == -1 } {\n\t\treturn -1\n\t}\n\n\tswitch $CLKIN {\n\t\t24000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  25   1\n\t\t\tcore_pll_config  $CLKIN  2  125  10  8  4\n\t\t\tper_pll_config   $CLKIN  9  400  5\n\t\t\tddr_pll_config   $CLKIN  2  50   1   2\n\t\t}\n\n\t\t25000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  24   1\n\t\t\tcore_pll_config  $CLKIN  0  40   10  8  4\n\t\t\tper_pll_config   $CLKIN  9  384  5\n\t\t\tddr_pll_config   $CLKIN  0  16   1   2\n\t\t}\n\n\t\t26000000 {\n\t\t\tmpu_pll_config   $CLKIN  12  300  1\n\t\t\tcore_pll_config  $CLKIN  12  500  10  8  4\n\t\t\tper_pll_config   $CLKIN  12  480  5\n\t\t\tddr_pll_config   $CLKIN  12  200  1   2\n\t\t}\n\n\t\t19200000 {\n\t\t\tmpu_pll_config   $CLKIN  3   125  1\n\t\t\tcore_pll_config  $CLKIN  11  625  10  8  4\n\t\t\tper_pll_config   $CLKIN  7   400  5\n\t\t\tddr_pll_config   $CLKIN  2   125  1   2\n\t\t}\n\t}\n}\n\nproc emif_prcm_clk_enable { } {\n\tglobal CM_PER_EMIF_FW_CLKCTRL\n\tglobal CM_PER_EMIF_CLKCTRL\n\n\tmww $CM_PER_EMIF_FW_CLKCTRL 0x02\n\tmww $CM_PER_EMIF_CLKCTRL 0x02\n\n\twhile { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { }\n}\n\nproc vtp_enable { } {\n\tglobal VTP_CTRL_REG\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x40 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] & ~0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n}\n\nproc config_ddr_ioctrl { } {\n\tglobal DDR_ADDRCTRL_IOCTRL\n\tglobal DDR_ADDRCTRL_WD0_IOCTRL\n\tglobal DDR_ADDRCTRL_WD1_IOCTRL\n\tglobal DDR_CKE_CTRL\n\tglobal DDR_DATA0_IOCTRL\n\tglobal DDR_DATA1_IOCTRL\n\tglobal DDR_DATA2_IOCTRL\n\tglobal DDR_DATA3_IOCTRL\n\tglobal DDR_IO_CTRL\n\n\tmww $DDR_ADDRCTRL_IOCTRL\t0x84\n\tmww $DDR_ADDRCTRL_WD0_IOCTRL\t0x00\n\tmww $DDR_ADDRCTRL_WD1_IOCTRL\t0x00\n\tmww $DDR_DATA0_IOCTRL\t\t0x84\n\tmww $DDR_DATA1_IOCTRL\t\t0x84\n\tmww $DDR_DATA2_IOCTRL\t\t0x84\n\tmww $DDR_DATA3_IOCTRL\t\t0x84\n\n\tmww $DDR_IO_CTRL\t\t0x00\n\tmww $DDR_CKE_CTRL\t\t0x03\n}\n\nproc config_ddr_phy { } {\n\tglobal EMIF_DDR_PHY_CTRL_1\n\tglobal EMIF_DDR_PHY_CTRL_1_SHDW\n\n\tglobal EXT_PHY_CTRL_1\n\tglobal EXT_PHY_CTRL_1_SHDW\n\tglobal EXT_PHY_CTRL_2\n\tglobal EXT_PHY_CTRL_2_SHDW\n\tglobal EXT_PHY_CTRL_3\n\tglobal EXT_PHY_CTRL_3_SHDW\n\tglobal EXT_PHY_CTRL_4\n\tglobal EXT_PHY_CTRL_4_SHDW\n\tglobal EXT_PHY_CTRL_5\n\tglobal EXT_PHY_CTRL_5_SHDW\n\tglobal EXT_PHY_CTRL_6\n\tglobal EXT_PHY_CTRL_6_SHDW\n\tglobal EXT_PHY_CTRL_7\n\tglobal EXT_PHY_CTRL_7_SHDW\n\tglobal EXT_PHY_CTRL_8\n\tglobal EXT_PHY_CTRL_8_SHDW\n\tglobal EXT_PHY_CTRL_9\n\tglobal EXT_PHY_CTRL_9_SHDW\n\tglobal EXT_PHY_CTRL_10\n\tglobal EXT_PHY_CTRL_10_SHDW\n\tglobal EXT_PHY_CTRL_11\n\tglobal EXT_PHY_CTRL_11_SHDW\n\tglobal EXT_PHY_CTRL_12\n\tglobal EXT_PHY_CTRL_12_SHDW\n\tglobal EXT_PHY_CTRL_13\n\tglobal EXT_PHY_CTRL_13_SHDW\n\tglobal EXT_PHY_CTRL_14\n\tglobal EXT_PHY_CTRL_14_SHDW\n\tglobal EXT_PHY_CTRL_15\n\tglobal EXT_PHY_CTRL_15_SHDW\n\tglobal EXT_PHY_CTRL_16\n\tglobal EXT_PHY_CTRL_16_SHDW\n\tglobal EXT_PHY_CTRL_17\n\tglobal EXT_PHY_CTRL_17_SHDW\n\tglobal EXT_PHY_CTRL_18\n\tglobal EXT_PHY_CTRL_18_SHDW\n\tglobal EXT_PHY_CTRL_19\n\tglobal EXT_PHY_CTRL_19_SHDW\n\tglobal EXT_PHY_CTRL_20\n\tglobal EXT_PHY_CTRL_20_SHDW\n\tglobal EXT_PHY_CTRL_21\n\tglobal EXT_PHY_CTRL_21_SHDW\n\tglobal EXT_PHY_CTRL_22\n\tglobal EXT_PHY_CTRL_22_SHDW\n\tglobal EXT_PHY_CTRL_23\n\tglobal EXT_PHY_CTRL_23_SHDW\n\tglobal EXT_PHY_CTRL_24\n\tglobal EXT_PHY_CTRL_24_SHDW\n\tglobal EXT_PHY_CTRL_25\n\tglobal EXT_PHY_CTRL_25_SHDW\n\tglobal EXT_PHY_CTRL_26\n\tglobal EXT_PHY_CTRL_26_SHDW\n\tglobal EXT_PHY_CTRL_27\n\tglobal EXT_PHY_CTRL_27_SHDW\n\tglobal EXT_PHY_CTRL_28\n\tglobal EXT_PHY_CTRL_28_SHDW\n\tglobal EXT_PHY_CTRL_29\n\tglobal EXT_PHY_CTRL_29_SHDW\n\tglobal EXT_PHY_CTRL_30\n\tglobal EXT_PHY_CTRL_30_SHDW\n\tglobal EXT_PHY_CTRL_31\n\tglobal EXT_PHY_CTRL_31_SHDW\n\tglobal EXT_PHY_CTRL_32\n\tglobal EXT_PHY_CTRL_32_SHDW\n\tglobal EXT_PHY_CTRL_33\n\tglobal EXT_PHY_CTRL_33_SHDW\n\tglobal EXT_PHY_CTRL_34\n\tglobal EXT_PHY_CTRL_34_SHDW\n\tglobal EXT_PHY_CTRL_35\n\tglobal EXT_PHY_CTRL_35_SHDW\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\tmww $EMIF_DDR_PHY_CTRL_1\t0x8009\n\tmww $EMIF_DDR_PHY_CTRL_1_SHDW\t0x8009\n\n\tset slave_ratio\t\t0x80\n\tset gatelvl_init_ratio\t0x20\n\tset wr_dqs_slave_delay\t0x60\n\tset rd_dqs_slave_delay\t0x60\n\tset dq_offset\t\t0x40\n\tset gatelvl_init_mode\t0x01\n\tset wr_data_slave_delay\t0x80\n\tset gatelvl_num_dq0 0x0f\n\tset wrlvl_num_dq0 0x0f\n\n\tmww $EXT_PHY_CTRL_1        [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_1_SHDW   [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_26       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_26_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_31       0x00\n\tmww $EXT_PHY_CTRL_31_SHDW  0x00\n\tmww $EXT_PHY_CTRL_32       0x00\n\tmww $EXT_PHY_CTRL_32_SHDW  0x00\n\tmww $EXT_PHY_CTRL_33       0x00\n\tmww $EXT_PHY_CTRL_33_SHDW  0x00\n\tmww $EXT_PHY_CTRL_34       0x00\n\tmww $EXT_PHY_CTRL_34_SHDW  0x00\n\tmww $EXT_PHY_CTRL_35       0x00\n\tmww $EXT_PHY_CTRL_35_SHDW  0x00\n\tmww $EXT_PHY_CTRL_22       0x00\n\tmww $EXT_PHY_CTRL_22_SHDW  0x00\n\tmww $EXT_PHY_CTRL_23       [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_23_SHDW  [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24       [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24_SHDW  [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0} ]\n\tmww $EXT_PHY_CTRL_25       [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_25_SHDW  [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_36       [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n\tmww $EXT_PHY_CTRL_36_SHDW  [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n}\n\nproc config_ddr_timing { } {\n\tglobal EMIF_SDRAM_TIM_1\n\tglobal EMIF_SDRAM_TIM_2\n\tglobal EMIF_SDRAM_TIM_3\n\tglobal EMIF_SDRAM_TIM_1_SHDW\n\tglobal EMIF_SDRAM_TIM_2_SHDW\n\tglobal EMIF_SDRAM_TIM_3_SHDW\n\tglobal EMIF_ZQ_CONFIG\n\n\tmww $EMIF_SDRAM_TIM_1\t\t0xeaaad4db\n\tmww $EMIF_SDRAM_TIM_1_SHDW\t0xeaaad4db\n\n\tmww $EMIF_SDRAM_TIM_2\t\t0x266b7fda\n\tmww $EMIF_SDRAM_TIM_2_SHDW\t0x266b7fda\n\n\tmww $EMIF_SDRAM_TIM_3\t\t0x107f8678\n\tmww $EMIF_SDRAM_TIM_3_SHDW\t0x107f8678\n\n\tmww $EMIF_ZQ_CONFIG\t\t0x50074be4\n}\n\nproc config_ddr_pm { } {\n\tglobal EMIF_PWR_MGMT_CTRL\n\tglobal EMIF_PWR_MGMT_CTRL_SHDW\n\tglobal EMIF_DLL_CALIB_CTRL\n\tglobal EMIF_DLL_CALIB_CTRL_SHDW\n\tglobal EMIF_TEMP_ALERT_CONFIG\n\n\tmww $EMIF_PWR_MGMT_CTRL\t\t0x00\n\tmww $EMIF_PWR_MGMT_CTRL_SHDW\t0x00\n\tmww $EMIF_DLL_CALIB_CTRL\t0x00050000\n\tmww $EMIF_DLL_CALIB_CTRL_SHDW\t0x00050000\n\tmww $EMIF_TEMP_ALERT_CONFIG\t0x00\n}\n\nproc config_ddr_priority { } {\n\tglobal EMIF_PRI_COS_MAP\n\tglobal EMIF_CONNID_COS_1_MAP\n\tglobal EMIF_CONNID_COS_2_MAP\n\tglobal EMIF_RD_WR_EXEC_THRSH\n\tglobal COS_CONFIG\n\n\tmww $EMIF_PRI_COS_MAP       0x00\n\tmww $EMIF_CONNID_COS_1_MAP  0x00\n\tmww $EMIF_CONNID_COS_2_MAP  0x0\n\tmww $EMIF_RD_WR_EXEC_THRSH  0x0405\n\tmww $COS_CONFIG             0x00ffffff\n}\n\nproc config_ddr3 { SDRAM_CONFIG } {\n\tglobal CM_DLL_CTRL\n\tglobal EMIF_IODFT_TLGC\n\tglobal EMIF_RDWR_LVL_CTRL\n\tglobal EMIF_RDWR_LVL_RMP_CTRL\n\tglobal EMIF_SDRAM_CONFIG\n\tglobal EMIF_SDRAM_CONFIG_EXT\n\tglobal EMIF_SDRAM_REF_CTRL\n\tglobal EMIF_SDRAM_REF_CTRL_SHDW\n\tglobal EMIF_STATUS\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\temif_prcm_clk_enable\n\tvtp_enable\n\n\tset dll [ expr {[ mrw $CM_DLL_CTRL ] & ~0x01 }]\n\tmww $CM_DLL_CTRL $dll\n\twhile { !([ mrw $CM_DLL_CTRL ] & 0x04) } { }\n\n\tconfig_ddr_ioctrl\n\n\tmww $EMIF_SDRAM_CONFIG_EXT\t0xc163\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_SDRAM_REF_CTRL\t0x80003000\n\n\tconfig_ddr_phy\n\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\n\tconfig_ddr_timing\n\tconfig_ddr_pm\n\tconfig_ddr_priority\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x3000\n\tmww $EMIF_SDRAM_CONFIG\t\t$SDRAM_CONFIG\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x0c30\n\tmww $EMIF_SDRAM_REF_CTRL_SHDW\t0x0c30\n\n\tsleep 10\n\n\tset tmp [ expr {[ mrw $EXT_PHY_CTRL_36 ] | 0x0100 }]\n\tmww $EXT_PHY_CTRL_36\t\t$tmp\n\tmww $EXT_PHY_CTRL_36_SHDW\t$tmp\n\n\tmww $EMIF_RDWR_LVL_RMP_CTRL\t0x80000000\n\tmww $EMIF_RDWR_LVL_CTRL\t\t0x80000000\n\n\twhile { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { }\n\n\tif { [ mrw $EMIF_STATUS ]  & 0x70 } {\n\t\terror \"DDR3 Hardware Leveling incomplete!!!\"\n\t}\n}\n\nproc init_platform { SDRAM_CONFIG } {\n\tconfig_opp100\n\tconfig_ddr3 $SDRAM_CONFIG\n}\n\n$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 }\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/amdm37x.cfg",
    "content": "#\n# Copyright (C)   2010-2011   by Karl Kurbjun\n# Copyright (C)   2009-2011   by Øyvind Harboe\n# Copyright (C)   2009        by David Brownell\n# Copyright (C)   2009        by Magnus Lundin\n#\n# TI AM/DM37x Technical Reference Manual (Version R)\n#  http://www.ti.com/lit/ug/sprugn4r/sprugn4r.pdf\n#\n# This script is based on the AM3517 initialization.  It should be considered\n# preliminary since it needs more complete testing and only the basic\n# operations work.\n#\n\n###############################################################################\n# User modifiable parameters\n###############################################################################\n\n# This script uses the variable CHIPTYPE to determine whether this is an AM35x\n# or DM37x target. If CHIPTYPE is not set it will error out.\nif { [info exists CHIPTYPE] } {\n\n   if { [info exists CHIPNAME] } {\n      set _CHIPNAME $CHIPNAME\n   } else {\n      set _CHIPNAME $CHIPTYPE\n   }\n\n   switch $CHIPTYPE {\n      dm37x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x2b89102f -expected-id 0x1b89102f -expected-id 0x0b89102f\"\n      }\n      am35x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x0b7ae02f -expected-id 0x0b86802f\"\n      }\n      default {\n         error \"ERROR: CHIPTYPE was set, but it was not set to a valid value.  Acceptable values are \\\"dm37x\\\" or \\\"am35x\\\".\"\n      }\n   }\n} else {\n  error \"ERROR: CHIPTYPE was not defined. Please set CHIPTYPE to \\\"am35x\\\" for the AM35x or \\\"dm37x\\\" for the DM37x series in the board configuration.\"\n}\n\n# Run the adapter at the fastest acceptable speed with the slowest possible\n# core clock.\nadapter speed 10\n\n###############################################################################\n# JTAG setup\n# The OpenOCD commands are described in the TAP Declaration section\n#  http://openocd.org/doc/html/TAP-Declaration.html\n###############################################################################\n\n# The AM/DM37x has an ICEPick module in it like many of TI's other devices. More\n#  can be read about this module in sprugn4r in chapter 27:  \"Debug and\n#  Emulation\".  The module is used to route the JTAG chain to the various\n#  subsystems in the chip.\nsource [find target/icepick.cfg]\n\n# The TAP order should be described from the TDO connection in OpenOCD to the\n#  TDI pin.  The OpenOCD FAQ describes this in more detail:\n#  http://openocd.org/doc/html/FAQ.html\n\n# From SPRUGN4R CH27 the available secondary TAPs are in this order from TDO:\n#\n#  Device   |  TAP number\n#  ---------|------------\n#  DAP      |  3\n#  Sequencer|  2   Note: The sequencer is an ARM968\n#  DSP      |  1\n#  D2D      |  0\n#\n# Right now the only secondary tap enabled is the DAP so the rest are left\n# undescribed.\n\n######\n# Start of Chain Description\n# The Secondary TAPs all have enable functions defined for use with the ICEPick\n# Only the DAP is enabled.  The AM37xx does not have the Sequencer or DSP but\n# the TAP numbers for ICEPick do not change.\n#\n# TODO: A disable function should also be added.\n######\n\n# Secondary TAP: DAP is closest to the TDO output\n# The TAP enable event also needs to be described\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# These taps are only present in the DM37x series.\nif { $CHIPTYPE == \"dm37x\" } {\n   # Secondary TAP: Sequencer (ARM968) it is not in the chain by default\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME arm2 -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\n   jtag configure $_CHIPNAME.arm2 -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n   # Secondary TAP: C64x+ DSP - it is not in the chain by default (-disable)\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n   jtag configure $_CHIPNAME.dsp -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n}\n\n# Secondary TAP: D2D it is not in the chain by default (-disable)\n# The ICEPick can be used to enable it in the chain.\n# This IRLEN is probably incorrect - not sure where the documentation is.\njtag newtap $_CHIPNAME d2d -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\njtag configure $_CHIPNAME.d2d -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEPick - it is closest to TDI so last in the chain\neval \"jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f $_JRC_TAPID\"\n\n######\n# End of Chain Description\n######\n\n######\n# Start JTAG TAP events\n######\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# Enable the DAP TAP\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\n######\n# End JTAG TAP events\n######\n\n###############################################################################\n# Target Setup:\n# This section is described in the OpenOCD documentation under CPU Configuration\n#  http://openocd.org/doc/html/CPU-Configuration.html\n###############################################################################\n\n# Create the CPU target to be used with GDB:  Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# The DM37x has 64K of SRAM starting at address 0x4020_0000.  Allow the first\n# 16K to be used as a scratchpad for OpenOCD.\n\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n######\n# Start Target Reset Event Setup:\n######\n\n# Set the JTAG clock down to 10 kHz to be sure that it will work with the\n#  slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up\n#  *after* PLL and clock tree setup.\n\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 10 }\n\n# Describe the reset assert process for openocd - this is asserted with the\n# ICEPick\n$_TARGETNAME configure -event \"reset-assert\" {\n\n   global _CHIPNAME\n\n   # assert warm system reset through ICEPick\n   icepick_c_wreset $_CHIPNAME.jrc\n}\n\n# After the reset is asserted we need to re-initialize debugging and speed up\n# the JTAG clock.\n\n$_TARGETNAME configure -event reset-assert-post {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n   adapter speed 1000\n}\n\n$_TARGETNAME configure -event gdb-attach {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n\n   echo \"Halting target\"\n   halt\n}\n\n######\n# End Target Reset Event Setup:\n######\n\n###############################################################################\n# Target Functions\n# Add any functions needed for the target here\n###############################################################################\n\n# Run this to enable invasive debugging.  This is run automatically in the\n# reset sequence.\nproc amdm37x_dbginit {target} {\n   # General Cortex-A8 debug initialisation\n   cortex_a dbginit\n\n   # Enable DBGEN signal.  This signal is described in the ARM v7 TRM, but\n   # access to the signal appears to be implementation specific.  TI does not\n   # describe this register much except a quick line that states DBGEM (sic) is\n   # at this address and this bit.\n   $target mww phys 0x5401d030 0x00002000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ampere_emag.cfg",
    "content": "#\n# OpenOCD Target Configuration for eMAG ARMv8 Processor\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n# This program is free software; you can redistribute it and/or\n# modify it under the terms of the GNU General Public License as\n# published by the Free Software Foundation; either version 2 of\n# the License, or (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program;\n#\n#\n\n#\n# Configure defaults for target\n# Can be overriden in board configuration file\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME emag\n}\n\nif { [info exists NUMCORES] } {\n\tset _NUMCORES $NUMCORES\n} else {\n\tset _NUMCORES 32\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID ] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4BA00477\n}\n\n#\n# Configure JTAG TAP\n#\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID\nset _TAPNAME $_CHIPNAME.cpu\n\nset _DAPNAME ${_TAPNAME}_dap\nset _APNUM 1\ndap create $_DAPNAME -chain-position $_TAPNAME\n$_DAPNAME apsel $_APNUM\n\n# Create the DAP AP0 MEM-AP AHB-AP target\ntarget create AHB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 0\n\n# Create the DAP AP1 MEM-AP APB-AP target\ntarget create APB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 1\n\n#\n# Configure target CPUs\n#\n\n# Build string used to enable smp mode\nset _SMP_STR \"target smp\"\n\nfor {set _i 0} {$_i < $_NUMCORES} {incr _i} {\n\t# Format a string to reference which CPU target to use\n\tset _TARGETNAME [format \"${_TAPNAME}_%02d\" $_i]\n\n\t# Create and configure Cross Trigger Interface (CTI) - required for halt and resume\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $_DAPNAME -ap-num $_APNUM -baseaddr [expr {0xFC020000 + ($_i << 20)}]\n\n\t# Create the target\n\ttarget create $_TARGETNAME aarch64 -endian $_ENDIAN -dap $_DAPNAME -ap-num $_APNUM -cti $_CTINAME -coreid $_i\n\tset _SMP_STR \"$_SMP_STR $_TARGETNAME\"\n\n\t# Clear CTI output/input enables that are not configured by OpenOCD for aarch64\n\t$_TARGETNAME configure -event examine-start [subst {\n\t\t$_CTINAME write INEN0 0x00000000\n\t\t$_CTINAME write INEN1 0x00000000\n\t\t$_CTINAME write INEN2 0x00000000\n\t\t$_CTINAME write INEN3 0x00000000\n\t\t$_CTINAME write INEN4 0x00000000\n\t\t$_CTINAME write INEN5 0x00000000\n\t\t$_CTINAME write INEN6 0x00000000\n\t\t$_CTINAME write INEN7 0x00000000\n\t\t$_CTINAME write INEN8 0x00000000\n\n\t\t$_CTINAME write OUTEN2 0x00000000\n\t\t$_CTINAME write OUTEN3 0x00000000\n\t\t$_CTINAME write OUTEN4 0x00000000\n\t\t$_CTINAME write OUTEN5 0x00000000\n\t\t$_CTINAME write OUTEN6 0x00000000\n\t\t$_CTINAME write OUTEN7 0x00000000\n\t\t$_CTINAME write OUTEN8 0x00000000\n\t}]\n\n\t# Enable OpenOCD HWTHREAD RTOS feature for GDB thread (CPU) selection support\n\t# This feature presents CPU cores (\"hardware threads\") in an SMP system as threads to GDB\n\t$_TARGETNAME configure -rtos hwthread\n}\neval $_SMP_STR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ar71xx.cfg",
    "content": "# Atheros AR71xx MIPS 24Kc SoC.\n# tested on PB44 refererence board\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst\n\nset CHIPNAME ar71xx\n\njtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1\n\nset _TARGETNAME $CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-halt-post {\n\t#setup PLL to lowest common denominator 300/300/150 setting\n\tmww 0xb8050000 0x000f40a3\t;# reset val + CPU:3 DDR:3 AHB:0\n\tmww 0xb8050000 0x800f40a3\t;# send to PLL\n\n\t#next command will reset for PLL changes to take effect\n\tmww 0xb8050008 3\t\t;# set reset_switch and clock_switch (resets SoC)\n}\n\n$_TARGETNAME configure -event reset-init {\n\t#complete pll initialization\n\tmww 0xb8050000 0x800f0080\t;# set sw_update bit\n\tmww 0xb8050008 0\t\t;# clear reset_switch bit\n\tmww 0xb8050000 0x800f00e8       ;# clr pwrdwn & bypass\n\tmww 0xb8050008 1\t\t;# set clock_switch bit\n\tsleep 1                         ;# wait for lock\n\n\t# Setup DDR config and flash mapping\n\tmww 0xb8000000 0xefbc8cd0       ;# DDR cfg cdl val (rst: 0x5bfc8d0)\n\tmww 0xb8000004 0x8e7156a2       ;# DDR cfg2 cdl val (rst: 0x80d106a8)\n\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb800000c 0                ;# clr ext. mode register\n\tmww 0xb8000010 2 \t\t;# force auto refresh all banks\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000008 0x31             ;# set DDR mode value CAS=3\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb8000014 0x461b           ;# DDR refresh value\n\tmww 0xb8000018 0xffff           ;# DDR Read Data This Cycle value (16bit: 0xffff)\n\tmww 0xb800001c 0x7              ;# delay added to the DQS line (normal = 7)\n\tmww 0xb8000020 0\n\tmww 0xb8000024 0\n\tmww 0xb8000028 0\n}\n\n# setup working area somewhere in RAM\n$_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000\n\n# serial SPI capable flash\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/arm_corelink_sse200.cfg",
    "content": "#\n# Configuration script for Arm CoreLink SSE-200 Subsystem based IoT SoCs.\n#\n\nglobal TARGET\nset TARGET $_CHIPNAME\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n#\n# SRAM on ARM CoreLink SSE-200 can be 4 banks of 8/16/32/64 KB\n# We will configure work area assuming 8-KB bank size in SRAM bank 1.\n# Also SRAM start addresses defaults to secure mode alias.\n# These values can be overridden as per board configuration\n#\n\nglobal _WORKAREASIZE_CPU0\nif { [info exists WORKAREASIZE_CPU0] } {\n\tset _WORKAREASIZE_CPU0 $WORKAREASIZE_CPU0\n} else {\n\tset _WORKAREASIZE_CPU0 0x1000\n}\n\nglobal _WORKAREAADDR_CPU0\nif { [info exists WORKAREAADDR_CPU0] } {\n\tset _WORKAREAADDR_CPU0 $WORKAREAADDR_CPU0\n} else {\n\tset _WORKAREAADDR_CPU0 0x30008000\n}\n\n#\n# Target configuration for Cortex M33 Core 0 on ARM CoreLink SSE-200\n# Core 0 is the boot core and will always be configured.\n#\n\ntarget create ${TARGET}.CPU0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\n${TARGET}.CPU0 configure -work-area-phys $_WORKAREAADDR_CPU0 -work-area-size $_WORKAREASIZE_CPU0 -work-area-backup 0\n\n${TARGET}.CPU0 cortex_m reset_config sysresetreq\n\n#\n# Target configuration for Cortex M33 Core 1 on ARM CoreLink SSE-200\n# Core 1 is optional and locked at boot until core 0 unlocks it.\n#\n\nif { $_ENABLE_CPU1 } {\n\tglobal _WORKAREASIZE_CPU1\n\tif { [info exists WORKAREASIZE_CPU1] } {\n\t\tset _WORKAREASIZE_CPU1 $WORKAREASIZE_CPU1\n\t} else {\n\t\tset _WORKAREASIZE_CPU1 0x1000\n\t}\n\n\tglobal _WORKAREAADDR_CPU1\n\tif { [info exists WORKAREAADDR_CPU1] } {\n\t\tset _WORKAREAADDR_CPU1 $WORKAREAADDR_CPU1\n\t} else {\n\t\tset _WORKAREAADDR_CPU1 0x30009000\n\t}\n\n\ttarget create ${TARGET}.CPU1 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\n\t${TARGET}.CPU1 configure -work-area-phys $_WORKAREAADDR_CPU1 -work-area-size $_WORKAREASIZE_CPU1 -work-area-backup 0\n\n\t${TARGET}.CPU1 cortex_m reset_config vectreset\n}\n\n# Make sure the default target is the boot core\ntargets ${TARGET}.CPU0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/armada370.cfg",
    "content": "#\n# armada370 -- support for the Marvell Armada/370 CPU family\n#\n# gerg@uclinux.org, OCT-2013\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME armada370\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\nproc armada370_dbginit {target} {\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"armada370_dbginit $_TARGETNAME\"\n\ndap apsel 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at32ap7000.cfg",
    "content": "# Atmel AT32AP7000\n#\n# This is the only core in the now-inactive high end AVR32 product line,\n# with MMU, Java Acceleration, and \"pixel coprocessor\".  The AP7 line\n# is for \"Application Processors\" (AP) with 7-stage pipelines.\n#\n# Most current AVR32 parts are in the UC3 flash based microcontroller (UC)\n# product line with 3-stage pipelines and without those extras.\n#\n# All AVR32 parts provide the Nexus Class 3 on-chip debug interfaces\n# through their JTAG interfaces.\n\njtag newtap ap7 nexus -irlen 5 -expected-id 0x21e8203f\n\n# REVISIT declare an avr32 target ... needs OpenOCD infrastructure\n# for both Nexus (generic) and AVR32 (Atmel-specific).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91r40008.cfg",
    "content": "# AT91R40008 target configuration file\n\n# TRST is tied to SRST on the AT91X40 family.\nreset_config srst_only srst_pulls_trst\n\n\nif {[info exists CHIPNAME]} {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91r40008\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Setup the JTAG scan chain.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91rm9200.cfg",
    "content": "# Atmel AT91rm9200\n# http://atmel.com/products/at91/\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91rm9200\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x05b0203f\n}\n\n# Never allow the following!\nif { $_CPUTAPID == 0x15b0203f } {\n   echo \"-------------------------------------------------------\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: TapID 0x15b0203f is wrong for at91rm9200     -\"\n   echo \"- ERROR: The chip/board has a JTAG select pin/jumper  -\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: In one position (0x05b0203f) it selects the  -\"\n   echo \"- ERROR: ARM CPU, in the other position (0x1b0203f)   -\"\n   echo \"- ERROR: it selects boundary-scan not the ARM         -\"\n   echo \"- ERROR:                                              -\"\n   echo \"-------------------------------------------------------\"\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# AT91RM9200 has a 16K block of sram @ 0x0020.0000\n$_TARGETNAME configure -work-area-phys 0x00200000 \\\n\t\t-work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3XXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam3\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n    halt\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3ax_4x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000A0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3ax_8x.cfg",
    "content": "# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 512K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3ax_xx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3nXX.cfg",
    "content": "\n#\n# Configuration for Atmel's SAM3N series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME at91sam3n\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank flash0 at91sam3 0x00400000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3sXX.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n\nsource [find target/at91sam3XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u1c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u1e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u2c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u2e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u4c.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip, it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3u4e.cfg",
    "content": "# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam3uxx.cfg",
    "content": "# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4XXX.cfg",
    "content": "#\n# script for ATMEL sam4, a Cortex-M4 chip\n#\n\n#\n# sam4 devices can support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam4\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4c32x.cfg",
    "content": "# script for ATMEL sam4c32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x01100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4cXXX.cfg",
    "content": "# script for ATMEL sam4c, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4lXX.cfg",
    "content": "# script for ATMEL sam4l, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME\n\n# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3).\n#\n# smap_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the SMAP to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post \"at91sam4l smap_reset_deassert\"\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed.\n# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio.\n# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2\n# but your mileage may vary.\nadapter speed 50\n\n# System RC oscillator RCSYS starts in 3 cycles\nadapter srst delay 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4sXX.cfg",
    "content": "# script for ATMEL sam4, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam4sd32x.cfg",
    "content": "# script for ATMEL sam4sd32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x00500000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam7a2.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7a2\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam7se512.cfg",
    "content": "# ATMEL sam7se512\n# Example: the \"Elektor Internet Radio\" - EIR\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7se512\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# The target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam7sx.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7s\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -event reset-init {\n        soft_reset_halt\n        # RSTC_CR : Reset peripherals\n        mww 0xfffffd00 0xa5000004\n        # disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=73)\n\tmww 0xffffff60 0x00490100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam7x256.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7x256\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam7x512.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME sam7x512\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\nflash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9\n######################################\n\nif { [info exists AT91_CHIPNAME] } {\n\tset _CHIPNAME $AT91_CHIPNAME\n} else {\n\terror \"you must specify a chip name\"\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0792603f\n}\n\nreset_config trst_and_srst separate trst_push_pull srst_open_drain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 300\njtag_ntrst_delay 200\n\nadapter speed 3\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9260.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9260\n}\n\nsource [find target/at91sam9.cfg]\n\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9260 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 4 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x1000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9260_ext_RAM_ext_flash.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nsource [find target/at91sam9261.cfg]\n\nreset_config trst_and_srst\n\nadapter speed 4\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\nscan_chain\n$_TARGETNAME configure -event reset-start {\n\t# at reset chip runs at 32khz\n\tadapter speed 8\n}\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n# Flash configuration\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n\n# Faster memory downloads. This is disabled automatically during\n# reset init since all reset init sequences are too short for\n# fast memory access\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\nproc at91sam_init { } {\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# Now run at anything fast... ie: 10mhz!\n\tadapter speed 10000               ;# Increase JTAG Speed to 6 MHz\n\n\tmww 0xffffec00 0x0a0a0a0a         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x0b0b0b0b         ;# SMC_PULSE0\n\tmww 0xffffec08 0x00160016         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00161003         ;# SMC_MODE0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR : Select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000         ;# PIO_PDR : Disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x2                ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\t#mww 0xffffea08 0x85227254         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S641632H-UC75 : 1M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x5d2              ;# SDRAMC_TR : Set refresh timer count to 15us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9261.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9261\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9261\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x28000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9263.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9263\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9263\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9263 has two SRAM areas,\n# one starting at 0x00300000 of 80KiB\n# and the other  starting at 0x00500000 of 16KiB.\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x14000 -work-area-backup 1\n#$_TARGETNAME configure -work-area-phys 0x00500000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9g10.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G10\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g10\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G10 has one SRAM area at 0x00300000 of 16KiB\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9g20.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G20\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g20\n}\n\nsource [find target/at91sam9.cfg]\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n\nadapter speed 5\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 16 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9g45.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9G45\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g45\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G45 has one SRAM area starting at 0x00300000 of 64 KiB.\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x200000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sam9rl.cfg",
    "content": "######################################\n# Target:    Atmel AT91SAM9RL\n######################################\n\nif { [info exists CHIPNAME] } {\n   set AT91_CHIPNAME $CHIPNAME\n} else {\n   set AT91_CHIPNAME at91sam9rl\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x10000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91sama5d2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The JTAG connection is disabled at reset, and during the ROM Code execution.\n# It is re-enabled when the ROM code jumps in the boot file copied from an\n# external Flash memory into the internalSRAM, or when the ROM code launches\n# the SAM-BA monitor, when no boot file has been found in any external Flash\n# memory.\n# For more JTAG related information see, :\n# https://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-sheet-ds60001476G.pdf\n#\n# If JTAGSEL pin:\n# - if enabled, boundary Scan mode is activated. JTAG ID Code value is 0x05B3F03F.\n# - if disabled, ICE mode is activated. Debug Port JTAG IDCODE value is 0x5BA00477\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME at91sama5d2\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n\t-expected-id 0x5ba00477\n\n# Cortex-A5 target\nset _TARGETNAME $_CHIPNAME.cpu_a5\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91samdXX.cfg",
    "content": "#\n# script for Atmel SAMD, SAMR, SAML or SAMC, a Cortex-M0 chip\n#\n\n#\n# samdXX devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91samd\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2)\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        at91samd dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset.\n# Other members of family usually use SYSCLK = 4 MHz after reset.\n# Datasheet does not specify SYSCLK to SWD clock ratio.\n# Usually used SYSCLK/6 is slow, testing shows that debugging can\n# work @ SYSCLK/2 but your mileage may vary.\n# This limit is most probably imposed by incorrectly handled SWD WAIT\n# on some SWD adapters.\n\nadapter speed 400\n\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at maximal clock speed. Atmel recommends\n# adapter speed less than 10 * CPU clock.\n# adapter speed 5000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/at91samg5x.cfg",
    "content": "# script for the ATMEL samg5x Cortex-M4F chip family\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atheros_ar2313.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2313\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atheros_ar2315.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2315\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atheros_ar9331.cfg",
    "content": "# The Atheros AR9331 is a highly integrated and cost effective\n# IEEE 802.11n 1x1 2.4 GHz System- on-a-Chip (SoC) for wireless\n# local area network (WLAN) AP and router platforms.\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 400 MHz\n# - External 16-bit DDR1, DDR2, or SDRAM memory interface\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin A72 on the SoC will reset internal JTAG logic.\n#\n\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO6, (B46)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO7, (A54)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO8, (A52)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (A72)\tInput only\n# SYS_RST_L\t????????\tOutput reset request or GPIO\n#   Bootstrap\n# MEM_TYPE[1]\tGPIO28, (A74)\t0 - SDRAM, 1 - DDR1 RAM, 2 - DDR2 RAM\n# MEM_TYPE[0]\tGPIO12, (A56)\n# FW_DOWNLOAD\tGPIO16, (A75)\tUsed if BOOT_FROM_SPI = 0. 0 - boot from USB\n#                               1 - boot from MDIO.\n# JTAG_MODE(JS)\tGPIO11, (B48)\t0 - JTAG (Default); 1 - EJTAG\n# BOOT_FROM_SPI\tGPIO1, (A77)\t0 - ROM boot; 1 - SPI boot\n# SEL_25M_40M\tGPIO0, (A78)\t0 - 25MHz; 1 - 40MHz\n#   UART\n# UART0_SOUT\tGPIO10, (A79)\n# UART0_SIN\tGPIO9, (B68)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9331\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\nproc disable_watchdog { } {\n\t;# disable watchdog\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n\n# Section with helpers which can be used by boards\nproc ar9331_25mhz_pll_init {} {\n\tmww 0xb8050008 0x00018004\t;# bypass PLL; AHB_POST_DIV - ratio 4\n\tmww 0xb8050004 0x00000352\t;# 34000(ns)/40ns(25MHz) = 0x352 (850)\n\tmww 0xb8050000 0x40818000\t;# Power down control for CPU PLL\n\t\t\t\t\t;# OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050010 0x001003e8\t;# CPU PLL Dither FRAC Register\n\t\t\t\t\t;# (disabled?)\n\tmww 0xb8050000 0x00818000\t;# Power on | OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050008 0x00008000\t;# remove bypass;\n\t\t\t\t\t;# AHB_POST_DIV - ratio 2\n}\n\nproc ar9331_ddr1_init {} {\n\tmww 0xb8000000 0x7fbc8cd0       ;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x133\t;# mode reg: 0x133 - default\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb800000c 0x2\t;# Extended mode register value.\n\t\t\t\t;# default 0x2 - Reset to weak driver, DLL on\n\tmww 0xb8000010 0x2\t;# Forces an EMRS update cycle\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x33\t;# mode reg: remove some bit?\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb8000014 0x4186\t;# enable refres: bit(14) - set refresh rate\n\tmww 0xb800001c 0x8\t;# This register is used along with DQ Lane 0,\n\t\t\t\t;# DQ[7:0], DQS_0\n\tmww 0xb8000020 0x9\t;# This register is used along with DQ Lane 1,\n\t\t\t\t;# DQ[15:8], DQS_1.\n\tmww 0xb8000018 0xff\t;# DDR read and capture bit mask.\n\t\t\t\t;# Each bit represents a cycle of valid data.\n}\n\nproc ar9331_ddr2_init {} {\n\tmww 0xb8000000 0x7fbc8cd0\t;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb800008c 0x00000a59\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000090 0x00000000\n\tmww 0xb8000010 0x00000010\t;# EMR2S update cycle\n\n\tmww 0xb8000094 0x00000000\n\tmww 0xb8000010 0x00000020\t;# EMR3S update cycle\n\n\tmww 0xb800000c 0x00000000\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000008 0x00000100\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000010 0x00000004\n\tmww 0xb8000010 0x00000004\t;# AUTO REFRESH cycle\n\n\tmww 0xb8000008 0x00000a33\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb800000c 0x00000382\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb800000c 0x00000402\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000014 0x00004186\t;# DDR_REFRESH\n\tmww 0xb800001c 0x00000008\t;# DDR_TAP_CTRL0\n\tmww 0xb8000020 0x00000009\t;# DDR_TAP_CTRL1\n\n\t;# DDR read and capture bit mask.\n\t;# Each bit represents a cycle of valid data.\n\t;# 0xff: use 16-bit DDR\n\tmww 0xb8000018 0x000000ff\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atheros_ar9344.cfg",
    "content": "if { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9344\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\nproc test_ar9344_uart0_tx {} {\n\techo \"configuring uart0..\"\n\tmww 0xb802000c 0x87\n\tmww 0xb8020000 0x15\n\tmww 0xb8020004 0\n\tmww 0xb802000c 7\n\tmww 0xb8020004 0\n\n\techo \"send message: hallo world\"\n\tmww 0xb8020000 0x68\n\tmww 0xb8020000 0x65\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x20\n\tmww 0xb8020000 0x77\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x72\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x64\n\tmww 0xb8020000 0x0a\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atmega128.cfg",
    "content": "# for avr\n\n   set _CHIPNAME avr\n   set _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\nreset_config srst_only\nadapter srst delay 100\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x8970203F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n\n#to use it, script will be like:\n#init\n#adapter speed 4500\n#reset init\n#verify_ircapture disable\n#\n#halt\n#wait halt\n#poll\n#avr mass_erase 0\n#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex\n#reset run\n#shutdown\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atmega128rfa1.cfg",
    "content": "set _CHIPNAME avr\nset _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\n# avr jtag docs never connect RSTN\nreset_config none\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0a70103f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atsame5x.cfg",
    "content": "#\n# Microchip (former Atmel) SAM E54, E53, E51 and D51 devices\n# with a Cortex-M4 core\n#\n\n#\n# Devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME atsame5\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (the smallest RAM size is 128kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAM DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        atsame5 dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAM E5x/D51 runs at SYSCLK = 48 MHz from RC oscillator after reset.\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at clock speed over 5000 khz. Atmel recommends\n# adapter speed less than 10 * CPU clock.\nadapter speed 2000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atsaml1x.cfg",
    "content": "#\n# Microchip (formerly Atmel) SAM L1x target\n#\n# Note: These devices support SWD only.\n#\n\ntransport select swd\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME saml1x\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nswd newdap $_CHIPNAME cpu -expected-id 0x0bf11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/atsamv.cfg",
    "content": "# ATMEL SAMV, SAMS, and SAME chips are Cortex-M7 parts\n# The chips are very similar; the SAMV series just has\n# more peripherals and seems like the \"flagship\" of the\n# family. This script will work for all of them.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME samv\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bd11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 1800\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/avr32.cfg",
    "content": "set _CHIPNAME avr32\nset _ENDIAN big\n\nset _CPUTAPID 0x21e8203f\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CPUTAPID\n\nset _TARGETNAME [format \"%s.cpu\" $_CHIPNAME]\ntarget create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm2711.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom BCM2711 used in Raspberry Pi 4\n# No documentation was found on Broadcom website\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2711\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm281xx.cfg",
    "content": "# BCM281xx\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm281xx\n}\n\n\n# Main CPU DAP\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\n\n\n# Dual Cortex-A9\nset _TARGETNAME0 $_CHIPNAME.cpu0\nset _TARGETNAME1 $_CHIPNAME.cpu1\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME0 cortex_a -dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x3fe10000\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0x3fe12000\ntarget smp $_TARGETNAME0 $_TARGETNAME1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm2835.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi Model A, B, B+,\n# the Compute Module, and the Raspberry Pi Zero.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2835\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x07b7617F\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 5\nadapter speed 4000\n\ntarget create $_CHIPNAME.cpu0 arm11 -chain-position $_CHIPNAME.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm2836.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom chip used in the Raspberry Pi 2 Model B\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2836\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\ttarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -coreid $_core -dbgbase [lindex $_DBGBASE $_core]\n\t$_TARGETNAME configure -event reset-assert-post { cortex_a dbginit }\n\n\tset _smp_command \"$_smp_command $_CHIPNAME.cpu$_core\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm2837.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi 3,\n# and in later models of the Raspberry Pi 2.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837b0\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2837\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\nset _CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\t$_TARGETNAME configure -event reset-assert-post { aarch64  dbginit }\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm4706.cfg",
    "content": "set _CHIPNAME bcm4706\nset _CPUID 0x1008c17f\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm4718.cfg",
    "content": "set _CHIPNAME bcm4718\nset _LVTAPID 0x1471617f\nset _CPUID 0x0008c17f\n\nsource [find target/bcm47xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm47xx.cfg",
    "content": "echo \"Forcing reset_config to none to prevent OpenOCD from pulling SRST after the switch from LV is already performed\"\nreset_config none\n\njtag newtap $_CHIPNAME-lv tap -irlen 32 -ircapture 0x1 -irmask 0x1f -expected-id $_LVTAPID -expected-id $_CPUID\njtag configure $_CHIPNAME-lv.tap -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME-lv.tap -event tap-disable {}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"switch_lv_to_ejtag\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n\nproc switch_lv_to_ejtag {} {\n    global _CHIPNAME\n    poll 0\n    irscan $_CHIPNAME-lv.tap 0x143ff3a\n    drscan $_CHIPNAME-lv.tap 32 1\n    jtag tapdisable $_CHIPNAME-lv.tap\n    poll 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm5352e.cfg",
    "content": "set _CHIPNAME bcm5352e\nset _CPUID 0x0535217f\n\njtag newtap $_CHIPNAME cpu -irlen 8 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bcm6348.cfg",
    "content": "set _CHIPNAME bcm6348\nset _CPUID 0x0634817f\n\nadapter speed 1000\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bluefield.cfg",
    "content": "# BlueField SoC Target\n\nset _CHIPNAME bluefield\n\n# Specify the target device\n#rshim device /dev/rshim0/rshim\n\n# Main DAP\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\nadapter speed 1500\n\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Initialize the target name and command variable.\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\n# CTI relative address\nset $_TARGETNAME.cti(0) 0xC4020000\nset $_TARGETNAME.cti(1) 0xC4120000\nset $_TARGETNAME.cti(2) 0xC8020000\nset $_TARGETNAME.cti(3) 0xC8120000\nset $_TARGETNAME.cti(4) 0xCC020000\nset $_TARGETNAME.cti(5) 0xCC120000\nset $_TARGETNAME.cti(6) 0xD0020000\nset $_TARGETNAME.cti(7) 0xD0120000\nset $_TARGETNAME.cti(8) 0xD4020000\nset $_TARGETNAME.cti(9) 0xD4120000\nset $_TARGETNAME.cti(10) 0xD8020000\nset $_TARGETNAME.cti(11) 0xD8120000\nset $_TARGETNAME.cti(12) 0xDC020000\nset $_TARGETNAME.cti(13) 0xDC120000\nset $_TARGETNAME.cti(14) 0xE0020000\nset $_TARGETNAME.cti(15) 0xE0120000\n\n# Create debug targets for a number of cores starting from core '_core_start'.\n# Adjust the numbers according to board configuration.\nset _core_start 0\nset _cores 16\n\n# Create each core\nfor { set _core $_core_start } { $_core < $_core_start + $_cores } { incr _core 1 } {\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != $_core_start } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\n# Configure SMP\nif { $_cores > 1 } {\n    eval $_smp_command\n}\n\n# Make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# Examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/bluenrg-x.cfg",
    "content": "#\n# bluenrg-1/2 and bluenrg-lp devices support only SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME bluenrg-1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 24kB-256bytes\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x5F00\n}\n\nadapter speed 4000\n\nswj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\nset WDOG_VALUE 0\nset WDOG_VALUE_SET 0\n\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000100 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n# In BlueNRG-X reset pin is actually a shutdown (power-off), so define reset as none\nreset_config none\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset JTAG_IDCODE_B2 0x0200A041\nset JTAG_IDCODE_B1 0x0\n\n$_TARGETNAME configure -event halted {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        # Stop watchdog during halt, if enabled. Only Bluenrg-1/2\n        set WDOG_VALUE [mrw 0x40700008]\n        if [expr {$WDOG_VALUE & (1 << 1)}] {\n            set WDOG_VALUE_SET 1\n            mww 0x40700008 [expr {$WDOG_VALUE & 0xFFFFFFFD}]\n        }\n    }\n}\n$_TARGETNAME configure -event resumed {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        if {$WDOG_VALUE_SET} {\n            # Restore watchdog enable value after resume. Only Bluenrg-1/2\n            mww 0x40700008 $WDOG_VALUE\n            set WDOG_VALUE_SET 0\n           }\n   }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/c100.cfg",
    "content": "# c100 config.\n# This is ARM1136 dual core\n# this script only configures one core (that is used to run Linux)\n\n# assume no PLL lock, start slowly\nadapter speed 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME c100\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x27b3645b\n}\n\nif { [info exists DSPTAPID] } {\n   set _DSPTAPID $DSPTAPID\n} else {\n   set _DSPTAPID 0x27b3645b\n}\n\njtag newtap $_CHIPNAME dsp -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_DSPTAPID\n\n\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# C100's ARAM 64k SRAM\n$_TARGETNAME configure -work-area-phys 0x0a000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/c100config.tcl",
    "content": "\n# board(-config) specific parameters file.\n\n# set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ]\nproc config {label} {\n    return [dict get [configC100] $label ]\n}\n\n# show the value for the param. with label\nproc showconfig {label} {\n    echo [format \"0x%x\" [dict get [configC100] $label ]]\n}\n\n# Telo board config\n# when there are more then one board config\n# use soft links to c100board-config.tcl\n# so that only the right board-config gets\n# included (just like include/configs/board-configs.h\n# in u-boot.\nproc configC100 {} {\n    # xtal freq. 24MHz\n    dict set configC100 CFG_REFCLKFREQ\t         24000000\n\n    # Amba Clk 165MHz\n    dict set configC100 CONFIG_SYS_HZ_CLOCK      165000000\n    dict set configC100 w_amba 1\n    dict set configC100 x_amba 1\n    # y = amba_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_amba [expr {[dict get $configC100 CONFIG_SYS_HZ_CLOCK] * ( ([dict get $configC100 w_amba]+1 ) * ([dict get $configC100 x_amba]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n    # Arm Clk 450MHz, must be a multiple of 25 MHz\n    dict set configC100 CFG_ARM_CLOCK      450000000\n    dict set configC100 w_arm 0\n    dict set configC100 x_arm 1\n    # y = arm_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_arm [expr {[dict get $configC100 CFG_ARM_CLOCK] * ( ([dict get $configC100 w_arm]+1 ) * ([dict get $configC100 x_arm]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n\n}\n\n# This should be called for reset init event handler\nproc setupTelo {} {\n\n    # setup GPIO used as control signals for C100\n    setupGPIO\n    # This will allow access to lower 8MB or NOR\n    lowGPIO5\n    # setup NOR size,timing,etc.\n    setupNOR\n    # setup internals + PLL + DDR2\n    initC100\n}\n\n\nproc setupNOR {} {\n    echo \"Setting up NOR: 16MB, 16-bit wide bus, CS0\"\n    # this is taken from u-boot/boards/mindspeed/ooma-darwin/board.c:nor_hw_init()\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    # enable Expansion Bus Clock + CS0 (NOR)\n    mww $EX_CSEN_REG 0x3\n    # set the address space for CS0=16MB\n    mww $EX_CS0_SEG_REG 0x7ff\n    # set the CS0 bus width to 16-bit\n    mww $EX_CS0_CFG_REG 0x202\n    # set timings to NOR\n    mww $EX_CS0_TMG1_REG 0x03034006\n    mww $EX_CS0_TMG2_REG 0x04040002\n    #mww $EX_CS0_TMG3_REG\n    # set EBUS clock 165/5=33MHz\n    mww $EX_CLOCK_DIV_REG 0x5\n    # everything else is OK with default\n}\n\nproc bootNOR {} {\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n    set BLOCK_RESET_REG\t       [regs BLOCK_RESET_REG]\n    set DDR_RST\t\t       [regs DDR_RST]\n\n    # put DDR controller in reset (so that it comes reset in u-boot)\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $EXP_CS0_BASEADDR\n    # run\n    resume\n}\nproc setupGPIO {} {\n    echo \"Setting up GPIO block for Telo\"\n    # This is current setup for Telo (see sch. for details):\n    #GPIO0 reset for FXS-FXO IC, leave as input, the IC has internal pullup\n    #GPIO1 irq line for FXS-FXO\n    #GPIO5 addr22 for NOR flash (access to upper 8MB)\n    #GPIO17 reset for DECT module.\n    #GPIO29 CS_n for NAND\n\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n\n    # set GPIO29=GPIO17=1, GPIO5=0\n    mww $GPIO_OUTPUT_REG [expr {1<<29 | 1<<17}]\n    # enable [as output] GPIO29,GPIO17,GPIO5\n    mww $GPIO_OE_REG [expr  {1<<29 | 1<<17 | 1<<5}]\n}\n\nproc highGPIO5 {} {\n    echo \"GPIO5 high\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=1\n    mmw $GPIO_OUTPUT_REG [expr {1 << 5}] 0x0\n}\n\nproc lowGPIO5 {} {\n    echo \"GPIO5 low\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=0\n    mmw $GPIO_OUTPUT_REG 0x0 [expr {1 << 5}]\n}\n\nproc boardID {id} {\n    # so far built:\n    # 4'b1111\n    dict set boardID 15 name \"EVT1\"\n    dict set boardID 15 ddr2size 128M\n    # dict set boardID 15 nandsize 1G\n    # dict set boardID 15 norsize 16M\n    # 4'b0000\n    dict set boardID 0 name \"EVT2\"\n    dict set boardID 0 ddr2size 128M\n    # 4'b0001\n    dict set boardID 1 name \"EVT3\"\n    dict set boardID 1 ddr2size 256M\n    # 4'b1110\n    dict set boardID 14 name \"EVT3_old\"\n    dict set boardID 14 ddr2size 128M\n    # 4'b0010\n    dict set boardID 2 name \"EVT4\"\n    dict set boardID 2 ddr2size 256M\n\n    return $boardID\n}\n\n\n# converted from u-boot/boards/mindspeed/ooma-darwin/board.c:ooma_board_detect()\n# figure out what board revision this is, uses BOOTSTRAP register to read stuffed resistors\nproc ooma_board_detect {} {\n    set GPIO_BOOTSTRAP_REG\t[regs GPIO_BOOTSTRAP_REG]\n\n    # read the current value of the BOOTSTRAP pins\n    set tmp [mrw $GPIO_BOOTSTRAP_REG]\n    echo [format \"GPIO_BOOTSTRAP_REG  (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG $tmp]\n    # extract the GPBP bits\n    set gpbt [expr {($tmp &0x1C00) >> 10 | ($tmp & 0x40) >>3}]\n\n    # display board ID\n    echo [format \"This is %s (0x%x)\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # show it on serial console\n    putsUART0 [format \"This is %s (0x%x)\\n\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # return the ddr2 size, used to configure DDR2 on a given board.\n    return [dict get [boardID $gpbt] $gpbt ddr2size]\n}\n\nproc configureDDR2regs_256M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set DENALI_CTL_02_VAL 0x0100000000010100\n    set DENALI_CTL_11_VAL 0x433a32164a560a00\n\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    # 01_DATA mod [40]=1, enable BA2\n    mw64bit $DENALI_CTL_01_DATA  0x0100010100000001\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0000010100000001\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x060a020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x0000000300000206\n    mw64bit $DENALI_CTL_08_DATA  0x6400003f3f0a0209\n    mw64bit $DENALI_CTL_09_DATA  0x1a000000001a1a1a\n    mw64bit $DENALI_CTL_10_DATA  0x0120202020191a18\n    # 11_DATA mod [39-32]=16,more refresh\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000000000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x04f8000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000000002cca0000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000000000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001300c8030600\n    mw64bit $DENALI_CTL_20_DATA  0x0000000081fe00c8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c:config_board99()\n# The values are computed based on Mindspeed and Nanya datasheets\nproc configureDDR2regs_128M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n\n    set DENALI_CTL_02_VAL 0x0100010000010100\n    set DENALI_CTL_11_VAL 0x433A42124A650A37\n    # set some default values\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    mw64bit $DENALI_CTL_01_DATA  0x0100000100000101\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0201010100000201\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x050A020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x000000030E0B0205\n    mw64bit $DENALI_CTL_08_DATA  0x6427003F3F0A0209\n    mw64bit $DENALI_CTL_09_DATA  0x1A00002F00001A00\n    mw64bit $DENALI_CTL_10_DATA  0x01202020201A1A1A\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000080000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x0508000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000020472D200000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000008000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001400C8030604\n    mw64bit $DENALI_CTL_20_DATA  0x00000000823600C8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    # This is not necessary\n    #mw64bit $DENALI_CTL_11_DATA [expr {($DENALI_CTL_11_VAL  & ~0x00007F0000000000) | ($wr_dqs_shift << 40)} ]\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n\n\nproc setupUART0 {} {\n    # configure UART0 to 115200, 8N1\n    set GPIO_LOCK_REG      [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL    [regs GPIO_IOCTRL_VAL]\n    set GPIO_IOCTRL_UART0  [regs GPIO_IOCTRL_UART0]\n    set UART0_LCR\t            [regs UART0_LCR]\n    set LCR_DLAB\t\t    [regs LCR_DLAB]\n    set UART0_DLL\t\t    [regs UART0_DLL]\n    set UART0_DLH\t\t    [regs UART0_DLH]\n    set UART0_IIR\t\t    [regs UART0_IIR]\n    set UART0_IER\t\t    [regs UART0_IER]\n    set LCR_ONE_STOP\t\t    [regs LCR_ONE_STOP]\n    set LCR_CHAR_LEN_8\t\t    [regs LCR_CHAR_LEN_8]\n    set FCR_XMITRES\t\t    [regs FCR_XMITRES]\n    set FCR_RCVRRES\t\t    [regs FCR_RCVRRES]\n    set FCR_FIFOEN\t\t    [regs FCR_FIFOEN]\n    set IER_UUE\t\t\t    [regs IER_UUE]\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable UART0\n    mmw $GPIO_IOCTRL_REG $GPIO_IOCTRL_UART0 0x0\n    # baudrate  115200\n    # This should really be amba_clk/(16*115200) but amba_clk=165MHz\n    set tmp 89\n    # Enable Divisor Latch access\n    mmw  $UART0_LCR $LCR_DLAB 0x0\n    # set the divisor to $tmp\n    mww $UART0_DLL [expr {$tmp & 0xff}]\n    mww $UART0_DLH [expr {$tmp >> 8}]\n    # Disable Divisor Latch access\n    mmw  $UART0_LCR 0x0 $LCR_DLAB\n    # set the UART to 8N1\n    mmw  $UART0_LCR [expr {$LCR_ONE_STOP | $LCR_CHAR_LEN_8} ] 0x0\n    # reset FIFO\n    mmw  $UART0_IIR [expr {$FCR_XMITRES  | $FCR_RCVRRES | $FCR_FIFOEN} ] 0x0\n    #  enable FFUART\n    mww $UART0_IER $IER_UUE\n}\n\nproc putcUART0 {char} {\n\n    set UART0_LSR\t    [regs UART0_LSR]\n    set UART0_THR\t    [regs UART0_THR]\n    set LSR_TEMT\t    [regs LSR_TEMT]\n\n    # convert the 'char' to digit\n    set tmp [ scan $char %c ]\n    # /* wait for room in the tx FIFO on FFUART */\n    while {[expr {[mrw $UART0_LSR] & $LSR_TEMT}] == 0} { sleep 1 }\n    mww $UART0_THR $tmp\n    if { $char == \"\\n\" } { putcUART0 \\r }\n}\n\nproc putsUART0 {str} {\n    set index 0\n    set len [string length $str]\n    while { $index < $len } {\n\tputcUART0 [string index $str $index]\n\tset index [expr {$index + 1}]\n    }\n}\n\n\nproc trainDDR2 {} {\n    set ARAM_BASEADDR\t[regs ARAM_BASEADDR]\n\n    # you must have run 'reset init' or u-boot\n    # load the training code to ARAM\n    load_image ./images/ddr2train.bin $ARAM_BASEADDR bin\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $ARAM_BASEADDR\n    # run\n    resume\n}\n\nproc flashUBOOT {file} {\n    # this will update uboot on NOR partition\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    flash probe 0\n    echo \"Erasing sectors 0-3 for uboot\"\n    putsUART0 \"Erasing sectors 0-3 for uboot\\n\"\n    flash erase_sector 0 0 3\n    echo \"Programming u-boot\"\n    putsUART0 \"Programming u-boot...\"\n    arm11 memwrite burst enable\n    flash write_image $file $EXP_CS0_BASEADDR\n    arm11 memwrite burst disable\n    putsUART0 \"done.\\n\"\n    putsUART0 \"Rebooting, please wait!\\n\"\n    reboot\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/c100helper.tcl",
    "content": "\nproc helpC100 {} {\n    echo \"List of useful functions for C100 processor:\"\n    echo \"1)  reset init:        will set up your Telo board\"\n    echo \"2)  setupNOR:          will setup NOR access\"\n    echo \"3)  showNOR:           will show current NOR config registers for 16-bit, 16MB NOR\"\n    echo \"4)  setupGPIO:         will setup GPIOs for Telo board\"\n    echo \"5)  showGPIO:          will show current GPIO config registers\"\n    echo \"6)  highGPIO5:         will set GPIO5=NOR_addr22=1 to access upper 8MB\"\n    echo \"7)  lowGPIO5:          will set GPIO5=NOR_addr22=0 to access lower 8MB\"\n    echo \"8)  showAmbaClk:       will show current config registers for Amba Bus Clock\"\n    echo \"9)  setupAmbaClk:      will setup Amba Bus Clock=165MHz\"\n    echo \"10) showArmClk:        will show current config registers for Arm Bus Clock\"\n    echo \"11) setupArmClk:       will setup Amba Bus Clock=450MHz\"\n    echo \"12) ooma_board_detect: will show which version of Telo you have\"\n    echo \"13) setupDDR2:         will configure DDR2 controller, you must have PLLs configured\"\n    echo \"14) showDDR2:          will show DDR2 config registers\"\n    echo \"15) showWatchdog:      will show current register config for watchdog\"\n    echo \"16) reboot:            will trigger watchdog and reboot Telo (hw reset)\"\n    echo \"17) bootNOR:           will boot Telo from NOR\"\n    echo \"18) setupUART0:        will configure UART0 for 115200 8N1, PLLs have to be configured\"\n    echo \"19) putcUART0:         will print a character on UART0\"\n    echo \"20) putsUART0:         will print a string on UART0\"\n    echo \"21) trainDDR2:         will run DDR2 training program\"\n    echo \"22) flashUBOOT:        will program NOR sectors 0-3 with u-boot.bin\"\n}\n\nsource [find mem_helper.tcl]\n\n# read a 64-bit register (memory mapped)\nproc mr64bit {reg} {\n    return [read_memory $reg 32 2]\n}\n\n\n# write a 64-bit register (memory mapped)\nproc mw64bit {reg value} {\n    set high [expr {$value >> 32}]\n    set low  [expr {$value & 0xffffffff}]\n    #echo [format \"mw64bit(0x%x): 0x%08x%08x\" $reg $high $low]\n    mww $reg $low\n    mww [expr {$reg+4}] $high\n}\n\n\nproc showNOR {} {\n    echo \"This is the current NOR setup\"\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    echo [format \"EX_CSEN_REG      (0x%x): 0x%x\" $EX_CSEN_REG [mrw $EX_CSEN_REG]]\n    echo [format \"EX_CS0_SEG_REG   (0x%x): 0x%x\" $EX_CS0_SEG_REG [mrw $EX_CS0_SEG_REG]]\n    echo [format \"EX_CS0_CFG_REG   (0x%x): 0x%x\" $EX_CS0_CFG_REG [mrw $EX_CS0_CFG_REG]]\n    echo [format \"EX_CS0_TMG1_REG  (0x%x): 0x%x\" $EX_CS0_TMG1_REG [mrw $EX_CS0_TMG1_REG]]\n    echo [format \"EX_CS0_TMG2_REG  (0x%x): 0x%x\" $EX_CS0_TMG2_REG [mrw $EX_CS0_TMG2_REG]]\n    echo [format \"EX_CS0_TMG3_REG  (0x%x): 0x%x\" $EX_CS0_TMG3_REG [mrw $EX_CS0_TMG3_REG]]\n    echo [format \"EX_CLOCK_DIV_REG (0x%x): 0x%x\" $EX_CLOCK_DIV_REG [mrw $EX_CLOCK_DIV_REG]]\n    echo [format \"EX_MFSM_REG      (0x%x): 0x%x\" $EX_MFSM_REG [mrw $EX_MFSM_REG]]\n    echo [format \"EX_CSFSM_REG     (0x%x): 0x%x\" $EX_CSFSM_REG [mrw $EX_CSFSM_REG]]\n    echo [format \"EX_WRFSM_REG     (0x%x): 0x%x\" $EX_WRFSM_REG [mrw $EX_WRFSM_REG]]\n    echo [format \"EX_RDFSM_REG     (0x%x): 0x%x\" $EX_RDFSM_REG [mrw $EX_RDFSM_REG]]\n}\n\n\n\nproc showGPIO {} {\n    echo \"This is the current GPIO register setup\"\n    # GPIO outputs register\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # GPIO Output Enable register\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n    set GPIO_HI_INT_ENABLE_REG\t    [regs GPIO_HI_INT_ENABLE_REG]\n    set GPIO_LO_INT_ENABLE_REG\t    [regs GPIO_LO_INT_ENABLE_REG]\n    # GPIO input register\n    set GPIO_INPUT_REG\t\t    [regs GPIO_INPUT_REG]\n    set APB_ACCESS_WS_REG\t    [regs APB_ACCESS_WS_REG]\n    set MUX_CONF_REG\t\t    [regs MUX_CONF_REG]\n    set SYSCONF_REG\t\t    [regs SYSCONF_REG]\n    set GPIO_ARM_ID_REG\t\t    [regs GPIO_ARM_ID_REG]\n    set GPIO_BOOTSTRAP_REG\t    [regs GPIO_BOOTSTRAP_REG]\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_DEVID_REG\t\t    [regs GPIO_DEVID_REG]\n\n    echo [format \"GPIO_OUTPUT_REG       (0x%x): 0x%x\" $GPIO_OUTPUT_REG [mrw $GPIO_OUTPUT_REG]]\n    echo [format \"GPIO_OE_REG           (0x%x): 0x%x\" $GPIO_OE_REG [mrw $GPIO_OE_REG]]\n    echo [format \"GPIO_HI_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_HI_INT_ENABLE_REG [mrw $GPIO_HI_INT_ENABLE_REG]]\n    echo [format \"GPIO_LO_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_LO_INT_ENABLE_REG [mrw $GPIO_LO_INT_ENABLE_REG]]\n    echo [format \"GPIO_INPUT_REG        (0x%x): 0x%x\" $GPIO_INPUT_REG [mrw $GPIO_INPUT_REG]]\n    echo [format \"APB_ACCESS_WS_REG     (0x%x): 0x%x\" $APB_ACCESS_WS_REG [mrw $APB_ACCESS_WS_REG]]\n    echo [format \"MUX_CONF_REG          (0x%x): 0x%x\" $MUX_CONF_REG [mrw $MUX_CONF_REG]]\n    echo [format \"SYSCONF_REG           (0x%x): 0x%x\" $SYSCONF_REG [mrw $SYSCONF_REG]]\n    echo [format \"GPIO_ARM_ID_REG       (0x%x): 0x%x\" $GPIO_ARM_ID_REG [mrw $GPIO_ARM_ID_REG]]\n    echo [format \"GPIO_BOOTSTRAP_REG    (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG [mrw $GPIO_BOOTSTRAP_REG]]\n    echo [format \"GPIO_LOCK_REG         (0x%x): 0x%x\" $GPIO_LOCK_REG [mrw $GPIO_LOCK_REG]]\n    echo [format \"GPIO_IOCTRL_REG       (0x%x): 0x%x\" $GPIO_IOCTRL_REG [mrw $GPIO_IOCTRL_REG]]\n    echo [format \"GPIO_DEVID_REG        (0x%x): 0x%x\" $GPIO_DEVID_REG [mrw $GPIO_DEVID_REG]]\n}\n\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_amba_clk())\nproc showAmbaClk {} {\n    set CFG_REFCLKFREQ\t\t     [config CFG_REFCLKFREQ]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t             [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_AHB_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_AHB_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Amba PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_amba_clk())\n# this clock is useb by all peripherals (DDR2, ethernet, ebus, etc)\nproc setupAmbaClk {} {\n    set CLKCORE_PLL_STATUS           [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t    [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t    [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t    [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t    [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t    [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t    [regs DIV_BYPASS]\n    set AHBCLK_PLL_LOCK\t    [regs AHBCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t [config CFG_REFCLKFREQ]\n    set CONFIG_SYS_HZ_CLOCK      [config CONFIG_SYS_HZ_CLOCK]\n    set w    [config w_amba]\n    set x    [config x_amba]\n    set y    [config y_amba]\n\n    echo [format \"Setting Amba PLL to lock to %d MHz\" [expr {$CONFIG_SYS_HZ_CLOCK/1000000}]]\n    #echo [format \"setupAmbaClk: w= %d\" $w]\n    #echo [format \"setupAmbaClk: x= %d\" $x]\n    #echo [format \"setupAmbaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL $AHB_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_AHB_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_arm_clk())\nproc showArmClk {} {\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CLKCORE_ARM_CLK_CNTRL\t[regs CLKCORE_ARM_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t        [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_ARM_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_ARM_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Arm PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_arm_clk())\n# Arm Clock is used by two ARM1136 cores\nproc setupArmClk {} {\n    set CLKCORE_PLL_STATUS        [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_ARM_CLK_CNTRL\t  [regs CLKCORE_ARM_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t          [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t          [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t          [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t          [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t          [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t          [regs DIV_BYPASS]\n    set FCLK_PLL_LOCK\t          [regs FCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CFG_ARM_CLOCK\t\t[config CFG_ARM_CLOCK]\n    set w    [config w_arm]\n    set x    [config x_arm]\n    set y    [config y_arm]\n\n    echo [format \"Setting Arm PLL to lock to %d MHz\" [expr {$CFG_ARM_CLOCK/1000000}]]\n    #echo [format \"setupArmClk: w= %d\" $w]\n    #echo [format \"setupArmaClk: x= %d\" $x]\n    #echo [format \"setupArmaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL $ARM_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_ARM_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n\nproc setupPLL {} {\n    echo \"PLLs setup\"\n    setupAmbaClk\n    setupArmClk\n}\n\n# converted from u-boot/cpu/arm1136/bsp100.c:SoC_mem_init()\nproc setupDDR2 {} {\n    echo \"Configuring DDR2\"\n\n    set MEMORY_BASE_ADDR\t    [regs  MEMORY_BASE_ADDR]\n    set MEMORY_MAX_ADDR\t            [regs  MEMORY_MAX_ADDR]\n    set MEMORY_CR \t\t    [regs  MEMORY_CR]\n    set BLOCK_RESET_REG\t\t    [regs  BLOCK_RESET_REG]\n    set DDR_RST\t\t            [regs  DDR_RST]\n\n    # put DDR controller in reset (so that it is reset and correctly configured)\n    # this is only necessary if DDR was previously confiured\n    # and not reset.\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n\n    set M [expr {1024 * 1024}]\n    set DDR_SZ_1024M\t[expr {1024 * $M}]\n    set DDR_SZ_256M\t[expr {256 * $M}]\n    set DDR_SZ_128M\t[expr {128 * $M}]\n    set DDR_SZ_64M\t[expr {64 * $M}]\n    # ooma_board_detect returns DDR2 memory size\n    set tmp [ooma_board_detect]\n    if {$tmp == \"128M\"} {\n\techo \"DDR2 size 128MB\"\n\tset ddr_size $DDR_SZ_128M\n    } elseif {$tmp == \"256M\"} {\n\techo \"DDR2 size 256MB\"\n\tset ddr_size $DDR_SZ_256M\n    } else {\n\techo \"Don't know how to handle this DDR2 size?\"\n    }\n\n    # Memory setup register\n    mww $MEMORY_MAX_ADDR  [expr {($ddr_size - 1) + $MEMORY_BASE_ADDR}]\n    # disable ROM remap\n    mww $MEMORY_CR 0x0\n    # Take DDR controller out of reset\n    mmw $BLOCK_RESET_REG $DDR_RST 0x0\n    # min. 20 ops delay\n    sleep 1\n\n    # This will setup Denali DDR2 controller\n    if {$tmp == \"128M\"} {\n\tconfigureDDR2regs_128M\n    } elseif {$tmp == \"256M\"} {\n\tconfigureDDR2regs_256M\n    } else {\n\techo \"Don't know how to configure DDR2 setup?\"\n    }\n}\n\n\n\nproc showDDR2 {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set tmp [mr64bit $DENALI_CTL_00_DATA]\n    echo [format \"DENALI_CTL_00_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_00_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_01_DATA]\n    echo [format \"DENALI_CTL_01_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_01_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_02_DATA]\n    echo [format \"DENALI_CTL_02_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_02_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_03_DATA]\n    echo [format \"DENALI_CTL_03_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_03_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_04_DATA]\n    echo [format \"DENALI_CTL_04_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_04_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_05_DATA]\n    echo [format \"DENALI_CTL_05_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_05_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_06_DATA]\n    echo [format \"DENALI_CTL_06_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_06_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_07_DATA]\n    echo [format \"DENALI_CTL_07_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_07_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_08_DATA]\n    echo [format \"DENALI_CTL_08_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_08_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_09_DATA]\n    echo [format \"DENALI_CTL_09_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_09_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_10_DATA]\n    echo [format \"DENALI_CTL_10_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_10_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_11_DATA]\n    echo [format \"DENALI_CTL_11_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_11_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_12_DATA]\n    echo [format \"DENALI_CTL_12_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_12_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_13_DATA]\n    echo [format \"DENALI_CTL_13_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_13_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_14_DATA]\n    echo [format \"DENALI_CTL_14_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_14_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_15_DATA]\n    echo [format \"DENALI_CTL_15_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_15_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_16_DATA]\n    echo [format \"DENALI_CTL_16_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_16_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_17_DATA]\n    echo [format \"DENALI_CTL_17_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_17_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_18_DATA]\n    echo [format \"DENALI_CTL_18_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_18_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_19_DATA]\n    echo [format \"DENALI_CTL_19_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_19_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_20_DATA]\n    echo [format \"DENALI_CTL_20_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_20_DATA $tmp(1) $tmp(0)]\n\n}\n\nproc initC100 {} {\n    # this follows u-boot/cpu/arm1136/start.S\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL\t            [regs GPIO_IOCTRL_VAL]\n    set APB_ACCESS_WS_REG           [regs APB_ACCESS_WS_REG]\n    set ASA_ARAM_BASEADDR\t    [regs ASA_ARAM_BASEADDR]\n    set ASA_ARAM_TC_CR_REG\t    [regs ASA_ARAM_TC_CR_REG]\n    set ASA_EBUS_BASEADDR\t    [regs ASA_EBUS_BASEADDR]\n    set ASA_EBUS_TC_CR_REG\t    [regs ASA_EBUS_TC_CR_REG]\n    set ASA_TC_REQIDMAEN\t    [regs ASA_TC_REQIDMAEN]\n    set ASA_TC_REQTDMEN\t            [regs ASA_TC_REQTDMEN]\n    set ASA_TC_REQIPSECUSBEN        [regs ASA_TC_REQIPSECUSBEN]\n    set ASA_TC_REQARM0EN\t    [regs ASA_TC_REQARM0EN]\n    set ASA_TC_REQARM1EN\t    [regs ASA_TC_REQARM1EN]\n    set ASA_TC_REQMDMAEN\t    [regs ASA_TC_REQMDMAEN]\n    set INTC_ARM1_CONTROL_REG       [regs INTC_ARM1_CONTROL_REG]\n\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable address lines A15-A21\n    mmw $GPIO_IOCTRL_REG 0xf 0x0\n    # set ARM into supervisor mode (SVC32)\n    # disable IRQ, FIQ\n    # Do I need this in JTAG mode?\n    # it really should be done as 'and ~0x1f | 0xd3 but\n    # openocd does not support this yet\n    reg cpsr 0xd3\n    #\t/*\n    #\t * flush v4 I/D caches\n    #\t */\n    #\tmov\tr0, #0\n    #\tmcr\tp15, 0, r0, c7, c7, 0\t/* flush v3/v4 cache */\n    arm mcr 15 0 7 7 0 0x0\n    #\tmcr\tp15, 0, r0, c8, c7, 0\t/* flush v4 TLB */\n    arm mcr 15 0 8 7 0 0x0\n\n    #\t/*\n    #\t * disable MMU stuff and caches\n    #\t */\n    #\tmrc\tp15, 0, r0, c1, c0, 0\n    arm mrc 15 0 1 0 0\n    #\tbic\tr0, r0, #0x00002300\t@ clear bits 13, 9:8 (--V- --RS)\n    #\tbic\tr0, r0, #0x00000087\t@ clear bits 7, 2:0 (B--- -CAM)\n    #\torr\tr0, r0, #0x00000002\t@ set bit 2 (A) Align\n    #\torr\tr0, r0, #0x00001000\t@ set bit 12 (I) I-Cache\n    #\torr\tr0, r0, #0x00400000\t@ set bit 22 (U)\n    #\tmcr\tp15, 0, r0, c1, c0, 0\n    arm mcr 15 0 1 0 0 0x401002\n    # This is from bsp_init() in u-boot/boards/mindspeed/ooma-darwin/board.c\n    # APB init\n    #    \t// Setting APB Bus Wait states to 1, set post write\n    #\t(*(volatile u32*)(APB_ACCESS_WS_REG)) = 0x40;\n    mww $APB_ACCESS_WS_REG 0x40\n    # AHB init\n    #\t// enable all 6 masters for ARAM\n    mmw $ASA_ARAM_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n    #\t// enable all 6 masters for EBUS\n    mmw $ASA_EBUS_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n\n    # ARAM init\n    #\t// disable pipeline mode in ARAM\n    # I don't think this is documented anywhere?\n    mww $INTC_ARM1_CONTROL_REG 0x1\n    # configure clocks\n    setupPLL\n    # setupUART0 must be run before setupDDR2 as setupDDR2 uses UART.\n    setupUART0\n    # enable cache\n    # ? (u-boot does nothing here)\n    # DDR2 memory init\n    setupDDR2\n    putsUART0 \"C100 initialization complete.\\n\"\n    echo \"C100 initialization complete.\"\n}\n\n# show current state of watchdog timer\nproc showWatchdog {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    echo [format \"TIMER_WDT_HIGH_BOUND    (0x%x): 0x%x\" $TIMER_WDT_HIGH_BOUND [mrw $TIMER_WDT_HIGH_BOUND]]\n    echo [format \"TIMER_WDT_CONTROL       (0x%x): 0x%x\" $TIMER_WDT_CONTROL [mrw $TIMER_WDT_CONTROL]]\n    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/intrrupts.c:void reset_cpu (ulong ignored)\n# this will trigger watchdog reset\n# the sw. reset does not work on C100\n# watchdog reset effectively works as hw. reset\nproc reboot {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    # allow the counter to count to high value  before triggering\n    # this is because register writes are slow over JTAG and\n    # I don't want to miss the high_bound==curr_count condition\n    mww $TIMER_WDT_HIGH_BOUND  0xffffff\n    mww $TIMER_WDT_CURRENT_COUNT 0x0\n    echo \"JTAG speed lowered to 100kHz\"\n    adapter speed 100\n    mww $TIMER_WDT_CONTROL 0x1\n    # wait until the reset\n    echo -n \"Waiting for watchdog to trigger...\"\n    #while {[mrw $TIMER_WDT_CONTROL] == 1} {\n    #    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n    #    sleep 1\n    #\n    #}\n    while {[c100.cpu curstate] != \"running\"} { sleep 1}\n    echo \"done.\"\n    echo [format \"Note that C100 is in %s state, type halt to stop\" [c100.cpu curstate]]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/c100regs.tcl",
    "content": "# Note that I basically converted\n# u-boot/include/asm-arm/arch/comcerto_100.h\n# defines\n\n# this is a work-around for 'global' not working under Linux\n# access registers by calling this routine.\n# For example:\n# set EX_CS_TMG1_REG [regs EX_CS0_TMG1_REG]\nproc regs {reg} {\n    return [dict get [regsC100] $reg ]\n}\n\nproc showreg {reg} {\n    echo [format \"0x%x\" [dict get [regsC100] $reg ]]\n}\n\nproc regsC100 {} {\n#/* memcore */\n#/* device memory base addresses */\n#// device memory sizes\n#/* ARAM SIZE=64K */\ndict set regsC100 ARAM_SIZE\t\t0x00010000\ndict set regsC100 ARAM_BASEADDR\t0x0A000000\n\n#/* Hardware Interface Units */\ndict set regsC100 APB_BASEADDR\t0x10000000\n#/* APB_SIZE=16M address range */\ndict set regsC100 APB_SIZE\t\t0x01000000\n\ndict set regsC100 EXP_CS0_BASEADDR       0x20000000\ndict set regsC100 EXP_CS1_BASEADDR       0x24000000\ndict set regsC100 EXP_CS2_BASEADDR       0x28000000\ndict set regsC100 EXP_CS3_BASEADDR       0x2C000000\ndict set regsC100 EXP_CS4_BASEADDR       0x30000000\n\ndict set regsC100 DDR_BASEADDR           0x80000000\n\ndict set regsC100 TDM_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x000000}]\ndict set regsC100 PHI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x010000}]\ndict set regsC100 TDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x020000}]\ndict set regsC100 ASA_DDR_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x040000}]\ndict set regsC100 ASA_ARAM_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x048000}]\ndict set regsC100 TIMER_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x050000}]\ndict set regsC100 ASD_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x060000}]\ndict set regsC100 GPIO_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x070000}]\ndict set regsC100 UART0_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x090000}]\ndict set regsC100 UART1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x094000}]\ndict set regsC100 SPI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x098000}]\ndict set regsC100 I2C_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x09C000}]\ndict set regsC100 INTC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0A0000}]\ndict set regsC100 CLKCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 PUI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 GEMAC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0D0000}]\ndict set regsC100 IDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0E0000}]\ndict set regsC100 MEMCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0F0000}]\ndict set regsC100 ASA_EBUS_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x100000}]\ndict set regsC100 ASA_AAB_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x108000}]\ndict set regsC100 GEMAC1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x190000}]\ndict set regsC100 EBUS_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1A0000}]\ndict set regsC100 MDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1E0000}]\n\n\n#////////////////////////////////////////////////////////////\n#//\tAHB block\t\t\t\t\t\t\t\t\t\t\t    //\n#////////////////////////////////////////////////////////////\ndict set regsC100 ASA_ARAM_PRI_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_ARAM_TC_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_ARAM_TC_CR_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_ARAM_STAT_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x0C}]\n\ndict set regsC100 ASA_EBUS_PRI_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_EBUS_TC_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_EBUS_TC_CR_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_EBUS_STAT_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x0C}]\n\ndict set regsC100 IDMA_MASTER\t\t0\ndict set regsC100 TDMA_MASTER\t\t1\ndict set regsC100 USBIPSEC_MASTER\t2\ndict set regsC100 ARM0_MASTER\t\t3\ndict set regsC100 ARM1_MASTER\t\t4\ndict set regsC100 MDMA_MASTER\t\t5\n\n#define IDMA_PRIORITY(level) (level)\n#define TDM_PRIORITY(level) (level << 4)\n#define USBIPSEC_PRIORITY(level) (level << 8)\n#define ARM0_PRIORITY(level) (level << 12)\n#define ARM1_PRIORITY(level) (level << 16)\n#define MDMA_PRIORITY(level) (level << 20)\n\ndict set regsC100 ASA_TC_REQIDMAEN\t [expr {1<<18}]\ndict set regsC100 ASA_TC_REQTDMEN\t [expr {1<<19}]\ndict set regsC100 ASA_TC_REQIPSECUSBEN [expr {1<<20}]\ndict set regsC100 ASA_TC_REQARM0EN\t [expr {1<<21}]\ndict set regsC100 ASA_TC_REQARM1EN\t [expr {1<<22}]\ndict set regsC100 ASA_TC_REQMDMAEN\t [expr {1<<23}]\n\ndict set regsC100 MEMORY_BASE_ADDR\t0x80000000\ndict set regsC100 MEMORY_MAX_ADDR\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x10}]\ndict set regsC100 MEMORY_CR \t\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x14}]\ndict set regsC100 ROM_REMAP_EN\t0x1\n\n#define HAL_asb_priority(level) \\\n#*(volatile unsigned *)ASA_PRI_REG = level\n\n#define HAL_aram_priority(level) \\\n#*(volatile unsigned *)ASA_ARAM_PRI_REG = level\n\n#define HAL_aram_arbitration(arbitration_mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG |= arbitration_mask\n\n#define HAL_aram_defmaster(mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG = (*(volatile unsigned *)ASA_TC_CR_REG & 0xFFFF) | (mask << 24)\n\n#////////////////////////////////////////////////////////////\n#// INTC block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 INTC_ARM1_CONTROL_REG\t[expr {[dict get $regsC100 INTC_BASEADDR ] + 0x18}]\n\n#////////////////////////////////////////////////////////////\n#// TIMER block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 TIMER0_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x00}]\ndict set regsC100 TIMER0_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x04}]\ndict set regsC100 TIMER1_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x08}]\ndict set regsC100 TIMER1_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x0C}]\n\ndict set regsC100 TIMER2_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x18}]\ndict set regsC100 TIMER2_LBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x10}]\ndict set regsC100 TIMER2_HBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x14}]\ndict set regsC100 TIMER2_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x1C}]\n\ndict set regsC100 TIMER3_LOBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x20}]\ndict set regsC100 TIMER3_HIBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x24}]\ndict set regsC100 TIMER3_CTRL\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x28}]\ndict set regsC100 TIMER3_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x2C}]\n\ndict set regsC100 TIMER_MASK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x40}]\ndict set regsC100 TIMER_STATUS\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_ACK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_WDT_HIGH_BOUND [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD0}]\ndict set regsC100 TIMER_WDT_CONTROL\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD4}]\ndict set regsC100 TIMER_WDT_CURRENT_COUNT [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD8}]\n\n\n\n#////////////////////////////////////////////////////////////\n#//  EBUS block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 EX_SWRST_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 EX_CSEN_REG\t\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 EX_CS0_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 EX_CS1_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x0C}]\ndict set regsC100 EX_CS2_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x10}]\ndict set regsC100 EX_CS3_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x14}]\ndict set regsC100 EX_CS4_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x18}]\ndict set regsC100 EX_CS0_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x1C}]\ndict set regsC100 EX_CS1_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x20}]\ndict set regsC100 EX_CS2_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x24}]\ndict set regsC100 EX_CS3_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x28}]\ndict set regsC100 EX_CS4_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x2C}]\ndict set regsC100 EX_CS0_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x30}]\ndict set regsC100 EX_CS1_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x34}]\ndict set regsC100 EX_CS2_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x38}]\ndict set regsC100 EX_CS3_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x3C}]\ndict set regsC100 EX_CS4_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x40}]\ndict set regsC100 EX_CS0_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x44}]\ndict set regsC100 EX_CS1_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x48}]\ndict set regsC100 EX_CS2_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x4C}]\ndict set regsC100 EX_CS3_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x50}]\ndict set regsC100 EX_CS4_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x54}]\ndict set regsC100 EX_CS0_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x58}]\ndict set regsC100 EX_CS1_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x5C}]\ndict set regsC100 EX_CS2_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x60}]\ndict set regsC100 EX_CS3_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x64}]\ndict set regsC100 EX_CS4_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x68}]\ndict set regsC100 EX_CLOCK_DIV_REG\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x6C}]\n\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_CSFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x104}]\ndict set regsC100 EX_WRFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x108}]\ndict set regsC100 EX_RDFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x10C}]\n\n\ndict set regsC100 EX_CLK_EN\t\t0x00000001\ndict set regsC100 EX_CSBOOT_EN\t0x00000002\ndict set regsC100 EX_CS0_EN\t\t0x00000002\ndict set regsC100 EX_CS1_EN\t\t0x00000004\ndict set regsC100 EX_CS2_EN\t\t0x00000008\ndict set regsC100 EX_CS3_EN\t\t0x00000010\ndict set regsC100 EX_CS4_EN\t\t0x00000020\n\ndict set regsC100 EX_MEM_BUS_8\t0x00000000\ndict set regsC100 EX_MEM_BUS_16       0x00000002\ndict set regsC100 EX_MEM_BUS_32\t0x00000004\ndict set regsC100 EX_CS_HIGH\t\t0x00000008\ndict set regsC100 EX_WE_HIGH\t\t0x00000010\ndict set regsC100 EX_RE_HIGH\t\t0x00000020\ndict set regsC100 EX_ALE_MODE\t\t0x00000040\ndict set regsC100 EX_STRB_MODE\t0x00000080\ndict set regsC100 EX_DM_MODE\t\t0x00000100\ndict set regsC100 EX_NAND_MODE\t0x00000200\ndict set regsC100 EX_RDY_EN\t\t0x00000400\ndict set regsC100 EX_RDY_EDGE\t\t0x00000800\n\n#////////////////////////////////////////////////////////////\n#//  GPIO block\n#////////////////////////////////////////////////////////////\n\n# GPIO outputs register\ndict set regsC100 GPIO_OUTPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x00}]\n# GPIO Output Enable register\ndict set regsC100 GPIO_OE_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x04}]\ndict set regsC100 GPIO_HI_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x08}]\ndict set regsC100 GPIO_LO_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x0C}]\n# GPIO input register\ndict set regsC100 GPIO_INPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x10}]\ndict set regsC100 APB_ACCESS_WS_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x14}]\ndict set regsC100 MUX_CONF_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x18}]\ndict set regsC100 SYSCONF_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x1C}]\ndict set regsC100 GPIO_ARM_ID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x30}]\ndict set regsC100 GPIO_BOOTSTRAP_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x40}]\ndict set regsC100 GPIO_LOCK_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x38}]\ndict set regsC100 GPIO_IOCTRL_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x44}]\ndict set regsC100 GPIO_DEVID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x50}]\n\ndict set regsC100 GPIO_IOCTRL_A15A16\t0x00000001\ndict set regsC100 GPIO_IOCTRL_A17A18\t0x00000002\ndict set regsC100 GPIO_IOCTRL_A19A21\t0x00000004\ndict set regsC100 GPIO_IOCTRL_TMREVT0\t0x00000008\ndict set regsC100 GPIO_IOCTRL_TMREVT1\t0x00000010\ndict set regsC100 GPIO_IOCTRL_GPBT3\t0x00000020\ndict set regsC100 GPIO_IOCTRL_I2C\t0x00000040\ndict set regsC100 GPIO_IOCTRL_UART0\t0x00000080\ndict set regsC100 GPIO_IOCTRL_UART1\t0x00000100\ndict set regsC100 GPIO_IOCTRL_SPI\t0x00000200\ndict set regsC100 GPIO_IOCTRL_HBMODE\t0x00000400\n\ndict set regsC100 GPIO_IOCTRL_VAL\t0x55555555\n\ndict set regsC100 GPIO_0\t\t\t0x01\ndict set regsC100 GPIO_1\t\t\t0x02\ndict set regsC100 GPIO_2\t\t\t0x04\ndict set regsC100 GPIO_3\t\t\t0x08\ndict set regsC100 GPIO_4\t\t\t0x10\ndict set regsC100 GPIO_5\t\t\t0x20\ndict set regsC100 GPIO_6\t\t\t0x40\ndict set regsC100 GPIO_7\t\t\t0x80\n\ndict set regsC100 GPIO_RISING_EDGE\t1\ndict set regsC100 GPIO_FALLING_EDGE\t2\ndict set regsC100 GPIO_BOTH_EDGES\t3\n\n#////////////////////////////////////////////////////////////\n#// UART\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 UART0_RBR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_THR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_DLL\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_IER\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_DLH\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_IIR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_FCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_LCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x0C}]\ndict set regsC100 UART0_MCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x10}]\ndict set regsC100 UART0_LSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x14}]\ndict set regsC100 UART0_MSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x18}]\ndict set regsC100 UART0_SCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x1C}]\n\ndict set regsC100 UART1_RBR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_THR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_DLL\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_IER\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_DLH\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_IIR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_FCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_LCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x0C}]\ndict set regsC100 UART1_MCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x10}]\ndict set regsC100 UART1_LSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x14}]\ndict set regsC100 UART1_MSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x18}]\ndict set regsC100 UART1_SCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x1C}]\n\n# /* default */\ndict set regsC100 LCR_CHAR_LEN_5\t\t0x00\ndict set regsC100 LCR_CHAR_LEN_6\t\t0x01\ndict set regsC100 LCR_CHAR_LEN_7\t\t0x02\ndict set regsC100 LCR_CHAR_LEN_8\t\t0x03\n#/* One stop bit! - default */\ndict set regsC100 LCR_ONE_STOP\t\t0x00\n#/* Two stop bit! */\ndict set regsC100 LCR_TWO_STOP\t\t0x04\n#/* Parity Enable */\ndict set regsC100 LCR_PEN\t\t\t0x08\ndict set regsC100 LCR_PARITY_NONE\t\t0x00\n#/* Even Parity Select */\ndict set regsC100 LCR_EPS\t\t\t0x10\n#/* Enable Parity  Stuff */\ndict set regsC100 LCR_PS\t\t\t0x20\n#/* Start Break */\ndict set regsC100 LCR_SBRK\t\t        0x40\n#/* Parity Stuff Bit */\ndict set regsC100 LCR_PSB\t\t\t0x80\n#/* UART 16550 Divisor Latch Assess */\ndict set regsC100 LCR_DLAB\t\t        0x80\n\n#/* FIFO Error Status */\ndict set regsC100 LSR_FIFOE\t\t[expr {1 << 7}]\n#/* Transmitter Empty */\ndict set regsC100 LSR_TEMT\t\t[expr {1 << 6}]\n#/* Transmit Data Request */\ndict set regsC100 LSR_TDRQ\t\t[expr {1 << 5}]\n#/* Break Interrupt */\ndict set regsC100 LSR_BI\t\t\t[expr {1 << 4}]\n#/* Framing Error */\ndict set regsC100 LSR_FE\t\t\t[expr {1 << 3}]\n#/* Parity Error */\ndict set regsC100 LSR_PE\t\t\t[expr {1 << 2}]\n#/* Overrun Error */\ndict set regsC100 LSR_OE\t\t\t[expr {1 << 1}]\n#/* Data Ready */\ndict set regsC100 LSR_DR\t\t\t[expr {1 << 0}]\n\n#/* DMA Requests Enable */\ndict set regsC100 IER_DMAE\t\t        [expr {1 << 7}]\n#/* UART Unit Enable */\ndict set regsC100 IER_UUE\t\t\t[expr {1 << 6}]\n#/* NRZ coding Enable */\ndict set regsC100 IER_NRZE\t\t        [expr {1 << 5}]\n#/* Receiver Time Out Interrupt Enable */\ndict set regsC100 IER_RTIOE\t\t        [expr {1 << 4}]\n#/* Modem Interrupt Enable */\ndict set regsC100 IER_MIE\t\t\t[expr {1 << 3}]\n#/* Receiver Line Status Interrupt Enable */\ndict set regsC100 IER_RLSE\t\t        [expr {1 << 2}]\n#/* Transmit Data request Interrupt Enable */\ndict set regsC100 IER_TIE\t\t\t[expr {1 << 1}]\n#/* Receiver Data Available Interrupt Enable */\ndict set regsC100 IER_RAVIE\t\t        [expr {1 << 0}]\n\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES1\t\t        [expr {1 << 7}]\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES0\t\t        [expr {1 << 6}]\n#/* Time Out Detected */\ndict set regsC100 IIR_TOD\t\t\t[expr {1 << 3}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID2\t\t        [expr {1 << 2}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID1\t\t        [expr {1 << 1}]\n#/* Interrupt Pending (active low) */\ndict set regsC100 IIR_IP\t\t\t[expr {1 << 0}]\n\n#/* UART 16550 FIFO Control Register */\ndict set regsC100 FCR_FIFOEN\t\t0x01\ndict set regsC100 FCR_RCVRRES\t\t0x02\ndict set regsC100 FCR_XMITRES\t\t0x04\n\n#/* Interrupt Enable Register */\n#// UART 16550\n#// Enable Received Data Available Interrupt\ndict set regsC100 IER_RXTH\t\t0x01\n#// Enable Transmitter Empty Interrupt\ndict set regsC100 IER_TXTH\t\t0x02\n\n\n\n#////////////////////////////////////////////////////////////\n#// CLK  + RESET block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x00}]\ndict set regsC100 CLKCORE_AHB_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x04}]\ndict set regsC100 CLKCORE_PLL_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x08}]\ndict set regsC100 CLKCORE_CLKDIV_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x0C}]\ndict set regsC100 CLKCORE_TDM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x10}]\ndict set regsC100 CLKCORE_FSYNC_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x14}]\ndict set regsC100 CLKCORE_CLK_PWR_DWN\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x18}]\ndict set regsC100 CLKCORE_RNG_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x1C}]\ndict set regsC100 CLKCORE_RNG_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x20}]\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL2\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x24}]\ndict set regsC100 CLKCORE_TDM_REF_DIV_RST\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x40}]\n\ndict set regsC100 ARM_PLL_BY_CTRL\t0x80000000\ndict set regsC100 ARM_AHB_BYP\t\t0x04000000\ndict set regsC100 PLL_DISABLE\t\t0x02000000\ndict set regsC100 PLL_CLK_BYPASS\t0x01000000\n\ndict set regsC100 AHB_PLL_BY_CTRL\t0x80000000\ndict set regsC100 DIV_BYPASS\t\t0x40000000\ndict set regsC100 SYNC_MODE\t\t0x20000000\n\ndict set regsC100 EPHY_CLKDIV_BYPASS\t0x00200000\ndict set regsC100 EPHY_CLKDIV_RATIO_SHIFT\t16\ndict set regsC100 PUI_CLKDIV_BYPASS\t0x00004000\ndict set regsC100 PUI_CLKDIV_SRCCLK\t0x00002000\ndict set regsC100 PUI_CLKDIV_RATIO_SHIFT\t8\ndict set regsC100 PCI_CLKDIV_BYPASS\t0x00000020\ndict set regsC100 PCI_CLKDIV_RATIO_SHIFT\t0\n\ndict set regsC100 ARM0_CLK_PD\t\t0x00200000\ndict set regsC100 ARM1_CLK_PD\t\t0x00100000\ndict set regsC100 EPHY_CLK_PD\t\t0x00080000\ndict set regsC100 TDM_CLK_PD\t\t0x00040000\ndict set regsC100 PUI_CLK_PD\t\t0x00020000\ndict set regsC100 PCI_CLK_PD\t\t0x00010000\ndict set regsC100 MDMA_AHBCLK_PD\t0x00000400\ndict set regsC100 I2CSPI_AHBCLK_PD\t0x00000200\ndict set regsC100 UART_AHBCLK_PD\t0x00000100\ndict set regsC100 IPSEC_AHBCLK_PD\t0x00000080\ndict set regsC100 TDM_AHBCLK_PD\t0x00000040\ndict set regsC100 USB1_AHBCLK_PD\t0x00000020\ndict set regsC100 USB0_AHBCLK_PD\t0x00000010\ndict set regsC100 GEMAC1_AHBCLK_PD\t0x00000008\ndict set regsC100 GEMAC0_AHBCLK_PD\t0x00000004\ndict set regsC100 PUI_AHBCLK_PD\t0x00000002\ndict set regsC100 HIF_AHBCLK_PD\t0x00000001\n\ndict set regsC100 ARM1_DIV_BP\t\t0x00001000\ndict set regsC100 ARM1_DIV_VAL_SHIFT\t8\ndict set regsC100 ARM0_DIV_BP\t\t0x00000010\ndict set regsC100 ARM0_DIV_VAL_SHIFT\t0\n\ndict set regsC100 AHBCLK_PLL_LOCK\t0x00000002\ndict set regsC100 FCLK_PLL_LOCK\t0x00000001\n\n\n#// reset block\ndict set regsC100 BLOCK_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x100}]\ndict set regsC100 CSP_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x104}]\n\ndict set regsC100 RNG_RST\t\t0x1000\ndict set regsC100 IPSEC_RST\t\t0x0800\ndict set regsC100 DDR_RST\t\t0x0400\ndict set regsC100 USB1_PHY_RST\t0x0200\ndict set regsC100 USB0_PHY_RST\t0x0100\ndict set regsC100 USB1_RST\t\t0x0080\ndict set regsC100 USB0_RST\t\t0x0040\ndict set regsC100 GEMAC1_RST\t\t0x0020\ndict set regsC100 GEMAC0_RST\t\t0x0010\ndict set regsC100 TDM_RST\t\t0x0008\ndict set regsC100 PUI_RST\t\t0x0004\ndict set regsC100 HIF_RST\t\t0x0002\ndict set regsC100 PCI_RST\t\t0x0001\n\n#////////////////////////////////////////////////////////////////\n#//\tDDR  CONTROLLER block\n#////////////////////////////////////////////////////////////////\n\ndict set regsC100 DDR_CONFIG_BASEADDR\t0x0D000000\ndict set regsC100 DENALI_CTL_00_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x00}]\ndict set regsC100 DENALI_CTL_01_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x08}]\ndict set regsC100 DENALI_CTL_02_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x10}]\ndict set regsC100 DENALI_CTL_03_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x18}]\ndict set regsC100 DENALI_CTL_04_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x20}]\ndict set regsC100 DENALI_CTL_05_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x28}]\ndict set regsC100 DENALI_CTL_06_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x30}]\ndict set regsC100 DENALI_CTL_07_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x38}]\ndict set regsC100 DENALI_CTL_08_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x40}]\ndict set regsC100 DENALI_CTL_09_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x48}]\ndict set regsC100 DENALI_CTL_10_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x50}]\ndict set regsC100 DENALI_CTL_11_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x58}]\ndict set regsC100 DENALI_CTL_12_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x60}]\ndict set regsC100 DENALI_CTL_13_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x68}]\ndict set regsC100 DENALI_CTL_14_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x70}]\ndict set regsC100 DENALI_CTL_15_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x78}]\ndict set regsC100 DENALI_CTL_16_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x80}]\ndict set regsC100 DENALI_CTL_17_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x88}]\ndict set regsC100 DENALI_CTL_18_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x90}]\ndict set regsC100 DENALI_CTL_19_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x98}]\ndict set regsC100 DENALI_CTL_20_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0xA0}]\n\n# 32-bit value\ndict set regsC100 DENALI_READY_CHECK         [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x44}]\n# 8-bit\ndict set regsC100 DENALI_WR_DQS              [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5D}]\n# 8-bit\ndict set regsC100 DENALI_DQS_OUT             [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5A}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY0          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x4F}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY1          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x50}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY2          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x51}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY3          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x52}]\n\n\n# end of proc regsC100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/cc2538.cfg",
    "content": "# Config for Texas Instruments low power RF SoC CC2538\n# http://www.ti.com/lit/pdf/swru319\n\nadapter speed 100\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc2538\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n# A start sequence is needed to change from cJTAG (Compact JTAG) to\n# 4-pin JTAG before talking via JTAG commands\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/cs351x.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME cs351x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00526fa1\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# There is 16K of SRAM on this chip\n# FIXME: flash programming is not working by using this work area. So comment this out for now.\n#$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/davinci.cfg",
    "content": "#\n# Utility code for DaVinci-family chips\n#\n\n# davinci_pinmux: assigns PINMUX$reg <== $value\nproc davinci_pinmux {soc reg value} {\n\tmww [expr {[dict get $soc sysbase] + 4 * $reg}] $value\n}\n\nsource [find mem_helper.tcl]\n\n#\n# pll_setup: initialize PLL\n#  - pll_addr ... physical addr of controller\n#  - mult ... pll multiplier\n#  - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers\n#\n# For PLLs that don't have a given register (e.g. plldiv8), or where a\n# given divider is non-programmable, caller provides *NO* config mapping.\n#\n\n# PLL version 0x02: tested on dm355\n# REVISIT: On dm6446/dm357 the PLLRST polarity is different.\nproc pll_v02_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - clear CLKMODE (bit 8) iff using on-chip oscillator\n\t# NOTE: this assumes we should clear that bit\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0100}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 4 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 5 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 6 - set PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 7 - clear PLLPWRDN (bit 1)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 8 - clear PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\t# NOTE: for dm355 PLL1, postdiv is controlled via MISC register\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult - 1) & 0xff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - optional: set plldiv1, plldiv2, ...\n\t# NOTE:  this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\t#\t- ALNCTL has everything set\n\tset go 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset go 1\n\t}\n\tif {$go != 0} {\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\n\t# 11 - wait at least 5 usec for reset to finish\n\t# (assume covered by overheads including JTAG messaging)\n\n\t# 12 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 13 - wait at least 8000 refclk cycles for PLL to lock\n\t# if we assume 24 MHz (slowest osc), that's 1/3 msec\n\tsleep 3\n\n\t# 14 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# PLL version 0x03: tested on dm365\nproc pll_v03_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_secctrl_addr [expr {$pll_addr + 0x108}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - power up the PLL\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 4 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 5 - wait at least 5 usec\n\tsleep 1\n\n\t# 6 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult / 2) & 0x1ff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - write start sequence to PLLSECCTL\n\tmww $pll_secctrl_addr 0x00470000\n\tmww $pll_secctrl_addr 0x00460000\n\tmww $pll_secctrl_addr 0x00400000\n\tmww $pll_secctrl_addr 0x00410000\n\n\t# 11 - optional: set plldiv1, plldiv2, ...\n\t# NOTE: this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\tset aln 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset aln [expr {$aln | 0x1}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0118}] 0\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset aln [expr {$aln | 0x2}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x011c}] 0\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset aln [expr {$aln | 0x4}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0120}] 0\n\t}\n\tif { [dict exists $config oscdiv] } {\n\t\tset div [dict get $config oscdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0124}] $div\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0124}] 0\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset aln [expr {$aln | 0x8}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0160}] 0\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset aln [expr {$aln | 0x10}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0164}] 0\n\t}\n\tif { [dict exists $config div6] } {\n\t\tset div [dict get $config div6]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0168}] $div\n\t\tset aln [expr {$aln | 0x20}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0168}] 0\n\t}\n\tif { [dict exists $config div7] } {\n\t\tset div [dict get $config div7]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x016c}] $div\n\t\tset aln [expr {$aln | 0x40}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x016c}] 0\n\t}\n\tif { [dict exists $config div8] } {\n\t\tset div [dict get $config div8]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0170}] $div\n\t\tset aln [expr {$aln | 0x80}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0170}] 0\n\t}\n\tif { [dict exists $config div9] } {\n\t\tset div [dict get $config div9]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0174}] $div\n\t\tset aln [expr {$aln | 0x100}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0174}] 0\n\t}\n\tif {$aln != 0} {\n\t\t# clear pllcmd.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x00\n\t\t# write alignment flags\n\t\tmww [expr {$pll_addr + 0x0140}] $aln\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\tset addr [dict get $config ctladdr]\n\twhile {[expr {[mrw $addr] & 0x0e000000}] != 0x0e000000} { sleep 1 }\n\n\t# 12 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain\n# modules can be enabled.\n\n# prepare a non-DSP module to be enabled; finish with psc_go\nproc psc_enable {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x03 0x1f\n}\n\n# prepare a non-DSP module to be reset; finish with psc_go\nproc psc_reset {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x01 0x1f\n}\n\n# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc\nproc psc_go {} {\n\tset psc_addr 0x01c41000\n\tset ptstat_addr [expr {$psc_addr + 0x0128}]\n\n\t# just in case PTSTAT.go isn't clear\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n\n\t# write PTCMD.go ... ignoring any DSP power domain\n\tmww [expr {$psc_addr + 0x0120}] 1\n\n\t# wait for PTSTAT.go to clear (again ignoring DSP power domain)\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n}\n\n#\n# A reset using only SRST is a \"Warm Reset\", resetting everything in the\n# chip except ARM emulation (and everything _outside_ the chip that hooks\n# up to SRST).  But many boards don't expose SRST via their JTAG connectors\n# (it's not present on TI-14 headers).\n#\n# From the chip-only perspective, a \"Max Reset\" is a \"Warm\" reset ... except\n# without any board-wide side effects, since it's triggered using JTAG using\n# either (a) ARM watchdog timer, or (b) ICEpick.\n#\nproc davinci_wdog_reset {} {\n\tset timer2_phys 0x01c21c00\n\n\t# NOTE -- on entry\n\t#   - JTAG communication with the ARM *must* be working OK; this\n\t#     may imply using adaptive clocking or disabling WFI-in-idle\n\t#   - current target must be the DaVinci ARM\n\t#   - that ARM core must be halted\n\t#   - timer2 clock is still enabled (PSC 29 on most chips)\n\n\t#\n\t# Part I -- run regardless of being halted via JTAG\n\t#\n\t# NOTE:  for now, we assume there's no DSP that could control the\n\t# watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog\n\t# suspend signal is controlled via ARM emulation suspend.\n\t#\n\n\t# EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n\n\t#\n\t# Part II -- in case watchdog hasn't been set up\n\t#\n\n\t# TCR: disable, force internal clock source\n\tmww phys [expr {$timer2_phys + 0x20}] 0\n\n\t# TGCR: reset, force to 64-bit wdog mode, un-reset (\"initial\" state)\n\tmww phys [expr {$timer2_phys + 0x24}] 0\n\tmww phys [expr {$timer2_phys + 0x24}] 0x110b\n\n\t# clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers\n\t# so watchdog triggers ASAP\n\tmww phys [expr {$timer2_phys + 0x10}] 0\n\tmww phys [expr {$timer2_phys + 0x14}] 0\n\tmww phys [expr {$timer2_phys + 0x18}] 0\n\tmww phys [expr {$timer2_phys + 0x1c}] 0\n\n\t# WDTCR: put into pre-active state, then active\n\tmww phys [expr {$timer2_phys + 0x28}] 0xa5c64000\n\tmww phys [expr {$timer2_phys + 0x28}] 0xda7e4000\n\n\t#\n\t# Part III -- it's ready to rumble\n\t#\n\n\t# WDTCR: write invalid WDKEY to trigger reset\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/dragonite.cfg",
    "content": "######################################\n# Target:    Marvell Dragonite CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dragonite\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x121003d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/dsp56321.cfg",
    "content": "# Script for freescale DSP56321\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp56321\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1181501d\n}\n\n#jtag speed\nadapter speed 4500\n\n#has only srst\nreset_config srst_only\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/dsp568013.cfg",
    "content": "# Script for freescale DSP568013\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568013\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2401d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\n# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations require certain instruction to be in the IR register during reset, and polling would change this)\njtag configure $_CHIPNAME.chp -event setup \"\n     jtag tapenable $_TARGETNAME\n     poll off\n\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/dsp568037.cfg",
    "content": "# Script for freescale DSP568037\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568037\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2801d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\njtag configure $_CHIPNAME.chp -event setup \"jtag tapenable $_TARGETNAME\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/efm32.cfg",
    "content": "#\n# Silicon Labs (formerly Energy Micro) EFM32 target\n#\n# Note: All EFM32 chips have SWD support, but only newer series 1\n# chips have JTAG support.\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME efm32\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nadapter speed 1000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\nflash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\nflash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/em357.cfg",
    "content": "#\n# Target configuration for the Silicon Labs EM357 chips\n#\n\n#\n# em357 family supports JTAG and SWD transports\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em357\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } else {\n      set _CPUTAPID 0x1ba00477\n   }\n}\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n  set _BSTAPID 0x069a962b\n}\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em358\n}\n\nif { [info exists FLASHSIZE] } {\n    set _FLASHSIZE $FLASHSIZE\n} else {\n    set _FLASHSIZE 0x30000\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nif { [using_jtag] } {\n    jtag newtap $_CHIPNAME bs -irlen 4 -expected-id $_BSTAPID -ircapture 0xe -irmask 0xf\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME em357 0x08000000 $_FLASHSIZE 0 0 $_TARGETNAME\n\nif { ![using_hla]} {\n# according to errata, we need to use vectreset rather than sysresetreq to avoid lockup\n# There is a bug in the chip, which means that when using external debuggers the chip\n# may lock up in certain CPU clock modes. Affected modes are operating the CPU at\n# 24MHz derived from the 24MHz crystal, or 12MHz derived from the high frequency RC\n# oscillator. If an external debugger tool asserts SYSRESETREQ, the chip will lock up and\n# require a pin reset or power cycle.\n#\n# for details, refer to:\n# http://www.silabs.com/Support%20Documents/TechnicalDocs/EM35x-Errata.pdf\n    cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/em358.cfg",
    "content": "# Target configuration for the Silicon Labs EM358 chips\n\n#\n# em357 family supports JTAG and SWD transports\n#\n\nif { ![info exists CHIPNAME] } {\n   set CHIPNAME em358\n}\n\nif { ![info exists BSTAPID] } {\n  set BSTAPID 0x069aa62b\n}\n\n# 512K of flash in the em358 chips\nset FLASHSIZE 0x80000\nsource [find target/em357.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/eos_s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3\n# https://www.quicklogic.com/products/soc/eos-s3-microcontroller/\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME eos_s3\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x80000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# For now we use SRAM only for software upload\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 4000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/epc9301.cfg",
    "content": "# Cirrus Logic EP9301 processor on an Olimex CS-E9301 board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ep9301\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nadapter srst delay 100\njtag_ntrst_delay 100\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -work-area-phys 0x80014000 -work-area-size 0x1000 -work-area-backup 1\n\n#flash configuration\n#flash bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x60000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/esi32xx.cfg",
    "content": "#\n# EnSilica eSi-32xx SoC (eSi-RISC Family)\n# http://www.ensilica.com/risc-ip/\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME esi32xx\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x11234001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME esirisc -chain-position $_CHIPNAME.cpu\n\n# Targets with the UNIFIED_ADDRESS_SPACE option disabled should set\n# CACHEARCH to 'harvard'. By default, 'von_neumann' is assumed.\nif { [info exists CACHEARCH] } {\n    $_TARGETNAME esirisc cache_arch $CACHEARCH\n}\n\nadapter speed 2000\n\nreset_config none\n\n# The default linker scripts provided by the eSi-RISC toolchain do not\n# specify attributes on memory regions, which results in incorrect\n# application of software breakpoints by GDB.\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/esp32s2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The ESP32-S2 only supports JTAG.\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME esp32s2\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x120034e5\n}\n\nset _TARGETNAME $_CHIPNAME\nset _CPUNAME cpu\nset _TAPNAME $_CHIPNAME.$_CPUNAME\n\njtag newtap $_CHIPNAME $_CPUNAME -irlen 5 -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME esp32s2 -endian little -chain-position $_TAPNAME\n\nxtensa maskisr on\n\n$_TARGETNAME configure -event reset-assert-post { soft_reset_halt }\n\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/exynos5250.cfg",
    "content": "#\n# Samsung Exynos 5250 - dual-core ARM Cortex-A15\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME exynos5250\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap\n\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/faux.cfg",
    "content": "#Script for faux target - used for testing\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00000000\n}\n\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#dummy flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME faux 0x01000000 0x200000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/feroceon.cfg",
    "content": "######################################\n# Target:    Marvell Feroceon CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME feroceon\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x20a023d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/fm3.cfg",
    "content": "# MB9BF506\n# Fujitsu Cortex-M3 with 512kB Flash and 64kB RAM\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME mb9bfxx6\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\n# delays on reset lines\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\n# Fujitsu Cortex-M3 reset configuration\nreset_config trst_only\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# MB9BF506 has 64kB of SRAM on its main system bus\n$_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0\n\n# MB9BF506 has 512kB internal FLASH\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n# 4MHz / 6 = 666kHz, so use 500\nadapter speed 500\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/fm4.cfg",
    "content": "#\n# Spansion FM4 (ARM Cortex-M4)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME fm4\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} elseif { [using_jtag] } {\n\tset _CPU_TAPID 0x4ba00477\n} else {\n\tset _CPU_TAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nadapter speed 500\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/fm4_mb9bf.cfg",
    "content": "#\n# Spansion FM4 MB9BFxxx (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# MB9BF566 M/N/R have 32 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x8000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/fm4_s6e2cc.cfg",
    "content": "#\n# Spansion FM4 S6E2CC (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# S6E2CC8 H/J/L have 96 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x18000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\nflash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/gd32e23x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for GigaDevice gd32e23x Cortex-M23 Series\n\n# https://www.gigadevice.com/microcontroller/gd32e230c8t6/\n\n#\n# gd32e23x devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32e23x\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some GD32E230s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # this is the SW-DP tap id not the jtag tap id\n   set _CPUTAPID 0x0bf11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# SWD speed (may be updated to higher value in board config file)\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Debug clock enable\n\t# RCU_APB2EN |= DBGMCUEN\n\tmmw 0x40021018 0x00400000 0\n\n\t# Stop watchdog counters during halt\n\t# DBG_CTL0 |= WWDGT_HOLD | FWDGT_HOLD | STB_HOLD | DSLP_HOLD | SLP_HOLD\n\tmmw 0x40015804 0x00000307 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/gd32vf103.cfg",
    "content": "#\n# GigaDevice GD32VF103 target\n#\n# https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/\n#\n\nsource [find mem_helper.tcl]\n\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32vf103\n}\n\n# The smallest RAM size 6kB (GD32VF103C4/T4/R4)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1800\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME\n\n# DBGMCU_CR register cannot be set in examine-end event as the running RISC-V CPU\n# does not allow the debugger to access memory.\n# Stop watchdogs at least before flash programming.\n$_TARGETNAME configure -event reset-init {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP\n\tmmw 0xE0042004 0x00000300 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/gp326xxxa.cfg",
    "content": "#\n# Support for General Plus GP326XXXA chips\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gp326xxxa\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Use internal SRAM as a work area\n$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0\n\n# The chip has both lines connected together\nreset_config trst_and_srst srst_pulls_trst\n# This delay is needed otherwise communication with the target would\n# be unreliable\nadapter srst delay 100\n\n# Set the adapter speed ridiculously low just in case we are\n# running off of a 32kHz clock\nadapter speed 2\n\nproc gp32xxxa_halt_and_reset_control_registers {} {\n\t# System control registers\n\tset P_SYSTEM_CTRL_NEW       0xD0000008\n\tset P_SYSTEM_CTRL           0xD000000C\n\tset P_SYSTEM_CLK_EN0        0xD0000010\n\tset P_SYSTEM_CLK_EN1        0xD0000014\n\tset P_SYSTEM_RESET_FLAG     0xD0000018\n\tset P_SYSTEM_CLK_CTRL       0xD000001C\n\tset P_SYSTEM_LVR_CTRL       0xD0000020\n\tset P_SYSTEM_WATCHDOG_CTRL  0xD0000024\n\tset P_SYSTEM_PLLEN          0xD000005C\n\n\t# Since we can't use SRST without pulling TRST\n\t# we can't assume the state of the clock configuration\n\t# or watchdog settings. So reset them before porceeding\n\n\t# Set the adapter speed ridiculously low just in case we are\n\t# running off of a 32kHz clock\n\tadapter speed 2\n\n\t# Disable any advanced features at this stage\n\tarm7_9 dcc_downloads disable\n\tarm7_9 fast_memory_access disable\n\n\t# Do a \"soft reset\"\n\tsoft_reset_halt\n\t# Reset all system control registers to their default \"after-reset\" values\n\tmwh $P_SYSTEM_WATCHDOG_CTRL  0x0000\n\tmwh $P_SYSTEM_LVR_CTRL       0x0000\n\n\tmwh $P_SYSTEM_CTRL_NEW       0x0001\n\tmwh $P_SYSTEM_CTRL           0x0001\n\t# Clear all reset flags by writing 1's\n\tmwh $P_SYSTEM_RESET_FLAG     0x001C\n\n\tmwh $P_SYSTEM_CLK_CTRL       0x8000\n\tmwh $P_SYSTEM_CLK_EN0        0xFFFF\n\tmwh $P_SYSTEM_CLK_EN1        0xFFFF\n\tmwh $P_SYSTEM_PLLEN          0x0010\n\n\t# Unfortunately there's no register that would allow us to\n\t# know if PLL is locked. So just wait for 100ms in hopes that\n\t# it would be enough.\n\tsleep 100\n\n\t# Now that we know that we are running at 48Mhz\n\t# Increase JTAG speed and enable speed optimization features\n\tadapter speed 5000\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/hi3798.cfg",
    "content": "# Hisilicon Hi3798 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi3798\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80020000\nset $_TARGETNAME.cti(1) 0x80120000\nset $_TARGETNAME.cti(2) 0x80220000\nset $_TARGETNAME.cti(3) 0x80320000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        #set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/hi6220.cfg",
    "content": "# Hisilicon Hi6220 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi6220\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n# declare the 8 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80198000\nset $_TARGETNAME.cti(1) 0x80199000\nset $_TARGETNAME.cti(2) 0x8019A000\nset $_TARGETNAME.cti(3) 0x8019B000\nset $_TARGETNAME.cti(4) 0x801D8000\nset $_TARGETNAME.cti(5) 0x801D9000\nset $_TARGETNAME.cti(6) 0x801DA000\nset $_TARGETNAME.cti(7) 0x801DB000\n\nset _cores 8\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ncti create cti.sys -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0x80003000\n\n# declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\n# declare the auxiliary Cortex-A7 core\ntarget create ${_TARGETNAME}.a7 cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80210000 -defer-examine\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/hilscher_netx10.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 10 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx10\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/hilscher_netx50.cfg",
    "content": "################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 50 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx50\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# On netX50 SDRAM is not accessible at offset 0xDEAD0-0xDEADF as it is busy from\n# DMA controller at init. This function will setup a dummy DMA to free this ares\n# and must be called before using SDRAM\nproc sdram_fix { } {\n\n  mww 0x1c005830 0x00000001\n\n  mww 0x1c005104 0xBFFFFFFC\n  mww 0x1c00510c 0x00480001\n  mww 0x1c005110 0x00000001\n\n  sleep 100\n\n  mww 0x1c00510c 0\n  mww 0x1c005110 0\n  mww 0x1c005830 0x00000000\n\n\tputs \"SDRAM Fix executed!\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/hilscher_netx500.cfg",
    "content": "#Hilscher netX 500 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx500\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\n# This function must be called on netX100/500 right after halt\n# If it is called later the needed register cannot be written anymore\nproc sdram_fix { } {\n\n  set accesskey [mread32 0x00100070]\n  mww 0x00100070 $accesskey\n  mww 0x0010002c 0x00000001\n\n  if {[expr {[mread32 0x0010002c] & 0x07}] == 0x07} {\n\t puts \"SDRAM Fix was not executed. Probably your CPU halted too late and the register is already locked!\"\n  } else {\n\t puts \"SDRAM Fix succeeded!\"\n  }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/icepick.cfg",
    "content": "#\n# Copyright (C)   2011        by Karl Kurbjun\n# Copyright (C)   2009        by David Brownell\n#\n\n# Utilities for TI ICEpick-C/D used in most TI SoCs\n# Details about the ICEPick are available in the the TRM for each SoC\n# and http://processors.wiki.ti.com/index.php/ICEPICK\n\n# create \"constants\"\nproc CONST { key } {\n\n\tarray set constant {\n\t\t# define ICEPick instructions\n\t\tIR_BYPASS   0x00\n\t\tIR_ROUTER   0x02\n\t\tIR_CONNECT  0x07\n\t\tIF_BYPASS   0x3F\n\t}\n\treturn $constant($key)\n}\n\n# Instruction to connect to the icepick module\nproc icepick_c_connect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x89 -endstate DRPAUSE\n}\n\n# Instruction to disconnect to the icepick module\nproc icepick_c_disconnect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x86 -endstate DRPAUSE\n}\n\n#\n# icepick_c_router:\n#  this function is for sending router commands\n# arguments are:\n#  jrc:        TAP name for the ICEpick\n#  rw:         read/write (0 for read, 1 for write)\n#  block:      icepick or DAP\n#  register:   which register to read/write\n#  payload:    value to read/write\n# this function is for sending router commands\n#\nproc icepick_c_router {jrc rw block register payload} {\n\n\tset new_dr_value \\\n\t\t[expr { ( ($rw & 0x1) << 31)        | ( ($block & 0x7) << 28) | \\\n\t\t\t\t( ($register & 0xF) << 24)  | ( $payload & 0xFFFFFF ) } ]\n\n#\techo \"\\tNew router value:\\t0x[format %x $new_dr_value]\"\n\n\t# select router\n\tirscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE\n\n\t# ROUTER instructions are 32 bits wide\n\tset old_dr_value 0x[drscan $jrc 32 $new_dr_value -endstate DRPAUSE]\n#\techo \"\\tOld router value:\\t0x[format %x $old_dr_value]\"\n}\n\n# Configure the icepick control register\nproc icepick_c_setup {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x001000\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15 for debug tap, 16..31 for test tap\nproc icepick_c_tapenable {jrc port} {\n\n\tif { ($port >= 0) && ($port < 16) } {\n\t\t# Debug tap\"\n\t\tset tap $port\n\t\tset block 0x2\n\t} elseif { $port < 32 } {\n\t\t# Test tap\n\t\tset tap [expr {$port - 16}]\n\t\tset block 0x1\n\t} else {\n\t\techo \"ERROR: Invalid ICEPick C port number: $port\"\n\t\treturn\n\t}\n\n\t# First CONNECT to the ICEPick\n#\techo \"Connecting to ICEPick\"\n\ticepick_c_connect $jrc\n\n#\techo \"Configuring the ICEpick\"\n\ticepick_c_setup $jrc\n\n\t# NOTE: it's important not to enter RUN/IDLE state until\n\t# done sending these instructions and data to the ICEpick.\n\t# And never to enter RESET, which will disable the TAPs.\n\n\t# first enable power and clock for TAP\n\ticepick_c_router $jrc 1 $block $tap 0x110048\n\n\t# TRM states that the register should be read back here, skipped for now\n\n\t# enable debug \"default\" mode\n\ticepick_c_router $jrc 1 $block $tap 0x112048\n\n\t# TRM states that debug enable and debug mode should be read back and\n\t# confirmed - skipped for now\n\n\t# Finally select the tap\n\ticepick_c_router $jrc 1 $block $tap 0x112148\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# jrc\t== TAP name for the ICEpick\n# coreid== core id number 0..15 (not same as port number!)\nproc icepick_d_set_core_control {jrc coreid value } {\n\ticepick_c_router $jrc 1 0x6 $coreid $value\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15\n# Follow the sequence described in\n# http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf\nproc icepick_d_tapenable {jrc port coreid { value 0x2008 } } {\n\n\t# First CONNECT to the ICEPick\n\ticepick_c_connect $jrc\n\ticepick_c_setup $jrc\n\n\t# Select the port\n\ticepick_c_router $jrc 1 0x2 $port 0x2108\n\n\t# Set icepick core control for $coreid\n\ticepick_d_set_core_control $jrc $coreid $value\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# This function uses the ICEPick to send a warm system reset\nproc icepick_c_wreset {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x002101\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx.cfg",
    "content": "# utility fn's for Freescale i.MX series\n\nglobal TARGETNAME\nset TARGETNAME $_TARGETNAME\n\n# rewrite commands of the form below to arm11 mcr...\n#\tData.Set c15:0x042f %long 0x40000015\nproc setc15 {regs value} {\n\tglobal TARGETNAME\n\n\techo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n\tarm mcr 15 [expr {($regs>>12)&0x7}] [expr {($regs>>0)&0xf}] [expr {($regs>>4)&0xf}] [expr {($regs>>8)&0x7}] $value\n}\n\n\nproc imx3x_reset {} {\n\t# this reset script comes from the Freescale PDK\n\t#\n\t# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX35PDK\n\n\techo \"Target Setup: initialize DRAM controller and peripherals\"\n\n#\tData.Set c15:0x01 %long 0x00050078\n\tsetc15 0x01 0x00050078\n\n\techo \"configuring CP15 for enabling the peripheral bus\"\n#\tData.Set c15:0x042f %long 0x40000015\n\tsetc15 0x042f 0x40000015\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx21.cfg",
    "content": "#use combined on interfaces or targets that can't set TRST/SRST separately\n#\n# Hmmm.... should srst_pulls_trst be used here like i.MX27???\nreset_config trst_and_srst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx21\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0792611f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx25.cfg",
    "content": "#\n# imx25 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx25\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0x0f -expected-id $_ETBTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0x0 -irmask 0x0 -expected-id 0x0\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882301d\n}\njtag newtap $_CHIPNAME sdma -irlen 5 -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t\t-chain-position $_TARGETNAME\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx27.cfg",
    "content": "# page 3-34 of \"MCIMC27 Multimedia Applications Processor Reference Manual, Rev 0.3\"\n# SRST pulls TRST\n#\n# Without setting these options correctly you'll see all sorts\n# of weird errors, e.g. MOE=0xe, invalid cpsr values, reset\n# failing, etc.\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx27\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there are 2 taps\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926121\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n# REVISIT what operating environment sets up this virtual address mapping?\n$_TARGETNAME configure -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \\\n\t-work-area-size 0x8000 -work-area-backup 1\n# Internal to the chip, there is 45K of SRAM\n#\n\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx28.cfg",
    "content": "# i.MX28 config file.\n# based off of the imx21.cfg file.\n\nreset_config trst_and_srst\n\n#jtag nTRST and nSRST delay\nadapter srst delay 100\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx28\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x079264f3\n}\njtag newtap $_CHIPNAME cpu  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx31.cfg",
    "content": "# imx31 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\n\nadapter srst delay 5\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx31\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x2190101d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The \"SDMA\" - <S>mart <DMA> controller debug tap\n# Based on some IO pins - this can be disabled & removed\n# See diagram: 6-14\n#   SIGNAL NAME:\n#    SJC_MOD - controls multiplexer - disables ARM1136\n#    SDMA_BYPASS - disables SDMA    -\n#\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0xf -expected-id 0x0\n\n# Per section 40.17.1, table 40-85 the IR register is 4 bits\n# But this conflicts with Diagram 6-13, \"3bits ir and drs\"\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx35.cfg",
    "content": "# imx35 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx35\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882601d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0x0 -expected-id 0x0\n\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx51.cfg",
    "content": "# Freescale i.MX51\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx51\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190c01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx51_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx51_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx53.cfg",
    "content": "# Freescale i.MX53\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx53\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190d01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx53_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx53_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx6.cfg",
    "content": "#\n# Freescale i.MX6 series\n#\n# Supports 6Q 6D 6QP 6DP 6DL 6S 6SL 6SLL\n#\n# Some imx6 chips have Cortex-A7 or an Cortex-M and need special handling\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx6\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\n\n# List supported SJC TAPIDs from imx reference manuals:\nset _SJC_TAPID_6Q   0x0191c01d\nset _SJC_TAPID_6D   0x0191e01d\nset _SJC_TAPID_6QP  0x3191c01d\nset _SJC_TAPID_6DP  0x3191d01d\nset _SJC_TAPID_6DL  0x0891a01d\nset _SJC_TAPID_6S   0x0891b01d\nset _SJC_TAPID_6SL  0x0891f01d\nset _SJC_TAPID_6SLL 0x088c201d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6Q\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6QP \\\n        -expected-id $_SJC_TAPID_6DP \\\n        -expected-id $_SJC_TAPID_6D \\\n        -expected-id $_SJC_TAPID_6DL \\\n        -expected-id $_SJC_TAPID_6S \\\n        -expected-id $_SJC_TAPID_6SL \\\n        -expected-id $_SJC_TAPID_6SLL\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x82150000\n# core 1  -  0x82152000\n# core 2  -  0x82154000\n# core 3  -  0x82156000\nset _TARGETNAME $_CHIPNAME.cpu.0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x82150000\n\n# some TCK cycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx6_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n\n# Slow speed to be sure it will work\nadapter speed 1000\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n$_TARGETNAME configure -event reset-assert-post \"imx6_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx6sx.cfg",
    "content": "#\n# Freescale i.MX6SoloX\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6sx\n}\n\n# 2x CoreSight Debug Access Port for Cortex-M4 and Cortex-A9\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu_m4 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_m4 -chain-position $_CHIPNAME.cpu_m4\n\njtag newtap $_CHIPNAME cpu_a9 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_a9 -chain-position $_CHIPNAME.cpu_a9\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID 0x0891c01d\n}\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# Cortex-A9 (boot core)\ntarget create $_CHIPNAME.cpu_a9 cortex_a -dap $_CHIPNAME.dap_a9 \\\n        -coreid 0 -dbgbase 0x82150000\n\n# Cortex-M4 (default off)\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap_m4 \\\n        -ap-num 0 -defer-examine\n\n# AHB mem-ap target\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap_a9 -ap-num 0\n\n# Default target is Cortex-A9\ntargets $_CHIPNAME.cpu_a9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx6ul.cfg",
    "content": "#\n# Freescale i.MX6UltraLite series: 6UL 6ULL 6ULZ\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6ul\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nset _SJC_TAPID_6UL  0x0891d01d\nset _SJC_TAPID_6ULL 0x0891e01d\nset _SJC_TAPID_6ULZ 0x1891e01d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6UL\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6ULL \\\n        -expected-id $_SJC_TAPID_6ULZ \\\n\n# Create DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Main AHB bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Cortex-A7 single core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x82130000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx7.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx7\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n#\n# Cortex-A7 target\n#\n# GDB target: Cortex-A7, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80070000\n# core 1  -  0x80072000\nset _TARGETNAME $_CHIPNAME.cpu_a7\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80070000\n\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 1 -dbgbase 0x80072000 -defer-examine\n#\n# Cortex-M4 target\n#\nset _TARGETNAME_2 $_CHIPNAME.cpu_m4\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.dap -ap-num 4 \\\n        -defer-examine\n\n#\n# AHB mem-ap target\n#\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx7ulp.cfg",
    "content": "#\n# NXP i.MX7ULP: Cortex-A7 + Cortex-M4\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx7ulp\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x188e101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-A7\ntarget create $_CHIPNAME.cpu_a7 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80030000\n\n# Cortex-M4\n# Boots by default so don't defer examination\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap -ap-num 3\n\n# AHB main soc bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Default is Cortex-A7\ntargets $_CHIPNAME.cpu_a7\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx8m.cfg",
    "content": "#\n# configuration file for NXP i.MX8M family of SoCs\n#\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8m\n}\n\nif { [info exists CHIPCORES] } {\n    set _cores $CHIPCORES\n} else {\n    set _cores 1\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# the DAP tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M4 core on AP #4\ntarget create ${_CHIPNAME}.m4 cortex_m -dap ${_CHIPNAME}.dap -ap-num 4 \\\n               -defer-examine\n\n# AHB-AP for direct access to soc bus\ntarget create ${_CHIPNAME}.ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# default target is A53 core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/imx8qm.cfg",
    "content": "#\n# NXP i.MX8QuadMax\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8qm\n}\n\n# CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x1890101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# AXI: Main SOC bus on AP #0\ntarget create ${_CHIPNAME}.axi mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# 4x Cortex-A53 on AP #6\nset _A53_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _A53_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\ncti create $_CHIPNAME.a53_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 0]\ncti create $_CHIPNAME.a53_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 1]\ncti create $_CHIPNAME.a53_cti.2 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 2]\ncti create $_CHIPNAME.a53_cti.3 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 3]\ntarget create $_CHIPNAME.a53.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.0 -dbgbase [lindex $_A53_DBGBASE 0]\ntarget create $_CHIPNAME.a53.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.1 -dbgbase [lindex $_A53_DBGBASE 1] -defer-examine\ntarget create $_CHIPNAME.a53.2 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.2 -dbgbase [lindex $_A53_DBGBASE 2] -defer-examine\ntarget create $_CHIPNAME.a53.3 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.3 -dbgbase [lindex $_A53_DBGBASE 3] -defer-examine\n\n# 2x Cortex-A72 on AP #6\nset _A72_DBGBASE {0x80210000 0x80310000}\nset _A72_CTIBASE {0x80220000 0x80220000}\n\ncti create $_CHIPNAME.a72_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 0]\ncti create $_CHIPNAME.a72_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 1]\ntarget create $_CHIPNAME.a72.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.0 -dbgbase [lindex $_A72_DBGBASE 0] -defer-examine\ntarget create $_CHIPNAME.a72.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.1 -dbgbase [lindex $_A72_DBGBASE 1] -defer-examine\n\n# All Cortex-A in SMP\ntarget smp \\\n        $_CHIPNAME.a53.0 \\\n        $_CHIPNAME.a53.1 \\\n        $_CHIPNAME.a53.2 \\\n        $_CHIPNAME.a53.3 \\\n        $_CHIPNAME.a72.0 \\\n        $_CHIPNAME.a72.1\n\n# SCU: Cortex-M4 core\n# always running imx SC firmware\ntarget create ${_CHIPNAME}.scu cortex_m -dap ${_CHIPNAME}.dap -ap-num 1\n\n# AHB from SCU perspective\ntarget create ${_CHIPNAME}.scu_ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 4\n\n# Cortex-M4 M4_0 core on AP #2 (default off)\ntarget create ${_CHIPNAME}.m4_0 cortex_m -dap ${_CHIPNAME}.dap -ap-num 2 \\\n        -defer-examine\n\n# Cortex-M4 M4_1 core on AP #3 (default off)\ntarget create ${_CHIPNAME}.m4_1 cortex_m -dap ${_CHIPNAME}.dap -ap-num 3 \\\n        -defer-examine\n\n# Debug APB bus\ntarget create ${_CHIPNAME}.apb mem_ap -dap ${_CHIPNAME}.dap -ap-num 6\n\n# Default target is boot core a53.0\ntargets $_CHIPNAME.a53.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/infineon/tle987x.cfg",
    "content": "#\n# Infineon TLE987x family (Arm Cortex-M3 @ up to 40 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tle987x\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\t# JTAG not supported, only SWD\n\tset _CPU_TAPID 0\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME dap -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/is5114.cfg",
    "content": "# script for Insilica IS-5114\n# AKA: Atmel AT76C114 - an ARM946 chip\n# ATMEL sold his product line to Insilica...\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME is5114\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a little endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nreset_config trst_and_srst\n\n# Do not specify a tap id here...\njtag newtap $_CHIPNAME unknown1 -irlen 8 -ircapture 0x01 -irmask 1\n# This is the \"arm946\" chip.\njtag newtap $_CHIPNAME cpu      -irlen 4 -ircapture 0x0e -irmask 0xf\njtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1\n\n\n#arm946e-s and\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\tadapter speed 3000\n}\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ixp42x.cfg",
    "content": "#xscale ixp42x CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ixp42x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x19274013\n}\nset _CPUTAPID2 0x19275013\nset _CPUTAPID3 0x19277013\nset _CPUTAPID4 0x29274013\nset _CPUTAPID5 0x29275013\nset _CPUTAPID6 0x29277013\n\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\n# register constants for IXP42x SDRAM controller\nglobal IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\nglobal IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\nset IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\t0x0000\nset IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\t0x0001\n\nglobal IXP42x_SDRAM_CL3\nglobal IXP42x_SDRAM_CL2\nset IXP42x_SDRAM_CL3\t\t\t0x0008\nset IXP42x_SDRAM_CL2\t\t\t0x0000\n\nglobal IXP42x_SDRAM_8MB_2Mx32_1BANK\nglobal IXP42x_SDRAM_16MB_2Mx32_2BANK\nglobal IXP42x_SDRAM_16MB_4Mx16_1BANK\nglobal IXP42x_SDRAM_32MB_4Mx16_2BANK\nglobal IXP42x_SDRAM_32MB_8Mx16_1BANK\nglobal IXP42x_SDRAM_64MB_8Mx16_2BANK\nglobal IXP42x_SDRAM_64MB_16Mx16_1BANK\nglobal IXP42x_SDRAM_128MB_16Mx16_2BANK\nglobal IXP42x_SDRAM_128MB_32Mx16_1BANK\nglobal IXP42x_SDRAM_256MB_32Mx16_2BANK\n\nset IXP42x_SDRAM_8MB_2Mx32_1BANK\t0x0030\nset IXP42x_SDRAM_16MB_2Mx32_2BANK\t0x0031\nset IXP42x_SDRAM_16MB_4Mx16_1BANK\t0x0032\nset IXP42x_SDRAM_32MB_4Mx16_2BANK\t0x0033\nset IXP42x_SDRAM_32MB_8Mx16_1BANK\t0x0010\nset IXP42x_SDRAM_64MB_8Mx16_2BANK\t0x0011\nset IXP42x_SDRAM_64MB_16Mx16_1BANK\t0x0012\nset IXP42x_SDRAM_128MB_16Mx16_2BANK\t0x0013\nset IXP42x_SDRAM_128MB_32Mx16_1BANK\t0x0014\nset IXP42x_SDRAM_256MB_32Mx16_2BANK\t0x0015\n\n\n# helper function to init SDRAM on IXP42x.\n# SDRAM_CFG: one of IXP42X_SDRAM_xxx\n# REFRESH: refresh counter reload value (integer)\n# CASLAT: 2 or 3\nproc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } {\n\n    switch $CASLAT {\n\t2 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL2} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\n\t}\n\t3 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL3} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\n\t}\n\tdefault { error [format \"unsupported cas latency \\\"%s\\\" \" $CASLAT] }\n    }\n    echo [format \"\\tIXP42x SDRAM Config: 0x%x, Refresh %d \" $SDRAM_CFG $REFRESH]\n\n    mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3\n    mww 0xCC000004          0 ;# disable refresh\n    mww 0xCC000008          3 ;# NOP\n    sleep 100\n    mww 0xCC000004   $REFRESH ;# set refresh counter\n    mww 0xCC000008          2 ;# Precharge All Banks\n    sleep 100\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008    $CASCMD ;# Mode Select CL2/CL3\n}\n\nproc ixp42x_set_bigendian { } {\n    reg XSCALE_CTRL 0xF8\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/k1921vk01t.cfg",
    "content": "# K1921VK01T\n# http://niiet.ru/chips/nis?id=354\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME k1921vk01t\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME\n\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/k40.cfg",
    "content": "#\n# Freescale Kinetis K40 devices\n#\n\nset CHIPNAME k40\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/k60.cfg",
    "content": "#\n# Freescale Kinetis K60 devices\n#\n\nset CHIPNAME k60\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ke0x.cfg",
    "content": "#\n# Freescale Kinetis KE0x and KEAx series devices\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ke\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\n   # It is important that \"kinetis_ke mdm check_security\" is called for\n   # 'examine-end' event and not 'eximine-start'. Calling it in 'examine-start'\n   # causes \"kinetis_ke mdm check_security\" to fail the first time openocd\n   # calls it when it tries to connect after the CPU has been power-cycled.\n   $_CHIPNAME.cpu configure -event examine-end {\n      kinetis_ke mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ke1xf.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xF devices\n#\n\nset CHIPNAME ke\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ke1xz.cfg",
    "content": "#\n# NXP (Freescale) Kinetis KE1xZ devices\n#\n\nset CHIPNAME ke\n\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/kl25.cfg",
    "content": "#\n# Freescale Kinetis KL25 devices\n#\n\nset CHIPNAME kl25\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/kl46.cfg",
    "content": "#\n# Freescale Kinetis KL46 devices\n#\n\nset CHIPNAME kl46\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/klx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis KL series devices\n# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME klx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1KiB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\n# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual\n# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;\n# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ks869x.cfg",
    "content": "# ARM920T CPU\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ks869x\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set  _CPUTAPID $CPUTAPID\n} else {\n   set  _CPUTAPID 0x00922f0f\n}\n\nadapter speed 6000\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/kx.cfg",
    "content": "#\n# NXP (former Freescale) Kinetis Kx series devices\n# Also used for Cortex-M4 equipped members of KVx and KE1xF series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME kx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \" Expect problems connecting to a blank device without boot ROM.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU or boot lock-up in RESET/WDOG loop\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n   # During RESET/WDOG loop the target is sometimes falsely examined\n   $_TARGETNAME configure -event examine-end {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc11xx.cfg",
    "content": "# NXP LPC11xx Cortex-M0 with at least 1kB SRAM\nset CHIPNAME lpc11xx\nset CHIPSERIES lpc1100\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc12xx.cfg",
    "content": "# NXP LPC12xx Cortex-M0 with at least 4kB SRAM\nset CHIPNAME lpc12xx\nset CHIPSERIES lpc1200\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc13xx.cfg",
    "content": "# NXP LPC13xx Cortex-M3 with at least 4kB SRAM\nset CHIPNAME lpc13xx\nset CHIPSERIES lpc1300\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc17xx.cfg",
    "content": "# NXP LPC17xx Cortex-M3 with at least 8kB SRAM\nset CHIPNAME lpc17xx\nset CHIPSERIES lpc1700\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x2000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc1850.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc1850\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n#\n# M3 JTAG mode TAP\n#\nif { [info exists M3_JTAG_TAPID] } {\n   set _M3_JTAG_TAPID $M3_JTAG_TAPID\n} else {\n   set _M3_JTAG_TAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME m3 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_JTAG_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.m3\n\nset _TARGETNAME $_CHIPNAME.m3\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc1xxx.cfg",
    "content": "# Main file for NXP LPC1xxx/LPC40xx series Cortex-M0/0+/3/4F parts\n#\n# !!!!!!\n#\n# This file should not be included directly, rather by the lpc11xx.cfg,\n# lpc13xx.cfg, lpc17xx.cfg, etc. which set the needed variables to the\n# appropriate values.\n#\n# !!!!!!\n\n# LPC8xx chips support only SWD transport.\n# LPC11xx chips support only SWD transport.\n# LPC12xx chips support only SWD transport.\n# LPC11Uxx chips support only SWD transports.\n# LPC13xx chips support only SWD transports.\n# LPC17xx chips support both JTAG and SWD transports.\n# LPC40xx chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\terror \"CHIPNAME not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\nif { [info exists CHIPSERIES] } {\n\t# Validate chip series is supported\n\tif { $CHIPSERIES != \"lpc800\" && $CHIPSERIES != \"lpc1100\" && $CHIPSERIES != \"lpc1200\" && $CHIPSERIES != \"lpc1300\" && $CHIPSERIES != \"lpc1700\"  && $CHIPSERIES != \"lpc4000\" } {\n\t\terror \"Unsupported LPC1xxx chip series specified.\"\n\t}\n\tset _CHIPSERIES $CHIPSERIES\n} else {\n\terror \"CHIPSERIES not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\n# After reset, the chip is clocked by an internal RC oscillator.\n# When board-specific code (reset-init handler or device firmware)\n# configures another oscillator and/or PLL0, set CCLK to match; if\n# you don't, then flash erase and write operations may misbehave.\n# (The ROM code doing those updates cares about core clock speed...)\n# CCLK is the core clock frequency in KHz\nif { [info exists CCLK] } {\n\t# Allow user override\n\tset _CCLK $CCLK\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x)\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t\tset _CCLK 12000\n\t} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tset _CCLK 4000\n\t}\n}\n\nif { [info exists CPUTAPID] } {\n\t# Allow user override\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core.\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" } {\n\t\tset _CPUTAPID 0x0bb11477\n\t} elseif { $_CHIPSERIES == \"lpc1300\" || $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tif { [using_jtag] } {\n\t\t\tset _CPUTAPID 0x4ba00477\n\t\t} {\n\t\t\tset _CPUTAPID 0x2ba01477\n\t\t}\n\t}\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\terror \"WORKAREASIZE is not set. The $CHIPNAME part is available in several Flash and RAM size configurations. Please set WORKAREASIZE.\"\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# The LPC11xx devices have 2/4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC12xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC11Uxx devices have 4/6/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC13xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC17xx devices have 8/16/32/64kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC40xx devices have 16/32/64kB of SRAM in the ARMv7-ME \"Code\" area (at 0x10000000)\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n# The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000)\n# The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000)\n# The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 0x00000000)\n# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000)\n# The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000)\n# The LPC40xx devies have 64/128/256/512kB of flash memory (at 0x00000000)\n#\n# All are compatible with the \"lpc1700\" variant of the LPC2000 flash driver\n# (same cmd51 destination boundary alignment, and all three support 256 byte\n# transfers).\n#\n# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum] [iap entry]\nset _IAP_ENTRY 0\nif { [info exists IAP_ENTRY] } {\n\tset _IAP_ENTRY $IAP_ENTRY\n}\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \\\n\tauto $_CCLK calc_checksum $_IAP_ENTRY\n\nif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t# Do not remap 0x0000-0x0200 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# Table 8. System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n\t# Bit Symbol Value Description\n\t# 1:0 MAP          System memory remap\n\t#            0x0   Boot Loader Mode. Interrupt vectors are re-mapped to Boot ROM.\n\t#            0x1   User RAM Mode. Interrupt vectors are re-mapped to Static RAM.\n\t#            0x2   User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash.\n\t# 31:2 -     -     Reserved.\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x40048000 0x02\n\t}\n} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x400FC040 0x01\n\t}\n}\n\n# Run with *real slow* clock by default since the\n# boot rom could have been playing with the PLL, so\n# we have no idea what clock the target is running at.\nadapter speed 10\n\n# delays on reset lines\nadapter srst delay 200\nif {[using_jtag]} {\n jtag_ntrst_delay 200\n}\n\n# LPC8xx (Cortex-M0+ core) support SYSRESETREQ\n# LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ\n# LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ\n# LPC40xx (Cortex-M4F core) support SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2103.cfg",
    "content": "# NXP LPC2103 ARM7TDMI-S with 32kB flash and 8kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2103 {core_freq_khz adapter_freq_khz} {\n\t# 32kB flash and 8kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2103 0x4f1f0f0f 0x8000 lpc2000_v2 0x2000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2103 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2103 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2124.cfg",
    "content": "# NXP LPC2124 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2124 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2124 0x4f1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2124 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2124 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2129.cfg",
    "content": "# NXP LPC2129 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2129 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2129 0xcf1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2129 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2129 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2148.cfg",
    "content": "# NXP LPC2148 ARM7TDMI-S with 512kB flash (12kB used by bootloader) and 40kB SRAM (8kB for USB DMA), clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2148 {core_freq_khz adapter_freq_khz} {\n\t# 500kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2148 \"0x3f0f0f0f 0x4f1f0f0f\" 0x7d000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2148 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2148 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2294.cfg",
    "content": "# NXP LPC2294 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2294 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\n\t# !! TAPID unknown !!\n\tsetup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2294 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2294 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2378.cfg",
    "content": "# NXP LPC2378 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 56kB SRAM (16kB for ETH, 8kB for DMA), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2378 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2378 0x4f1f0f0f 0x7e000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2378 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2378 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2460.cfg",
    "content": "# NXP LPC2460 ARM7TDMI-S with 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2460 {core_freq_khz adapter_freq_khz} {\n\t# 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2460 0x4f1f0f0f 0 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2460 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2460 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2478.cfg",
    "content": "# NXP LPC2478 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2478 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2478 0x4f1f0f0f 0x7e000 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2478 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2478 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2900.cfg",
    "content": "\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME lpc2900\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0596802B\n}\n\nif { [info exists HAS_ETB] } {\n} else {\n    # Set default (no ETB).\n    # Show a warning, because this should have been configured explicitly.\n    set HAS_ETB 0\n    # TODO: warning?\n}\n\nif { [info exists ETBTAPID] } {\n    set _ETBTAPID $ETBTAPID\n} else {\n    set _ETBTAPID 0x1B900F0F\n}\n\n# TRST and SRST both exist, and can be controlled independently\nreset_config trst_and_srst separate\n\n# Define the _TARGETNAME\nset _TARGETNAME $_CHIPNAME.cpu\n\n# Include the ETB tap controller if asked for.\n# Has to be done manually for newer devices (not an \"old\" LPC2917/2919).\nif { $HAS_ETB == 1 } {\n    # Clear the HAS_ETB flag. Must be set again for a new tap in the chain.\n    set HAS_ETB 0\n\n    # Add the ETB tap controller and the ARM9 core debug tap\n    jtag newtap $_CHIPNAME etb -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_ETBTAPID\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n\n    # Configure ETM and ETB\n    etm config $_TARGETNAME 8 normal full etb\n    etb config $_TARGETNAME $_CHIPNAME.etb\n\n} else {\n    # Add the ARM9 core debug tap\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n}\n\narm7_9 dbgrq enable\narm7_9 dcc_downloads enable\n\n# Flash bank configuration:\n# Flash: flash bank lpc2900 0 0 0 0 <target#> <flash clock (CLK_SYS_FMC) in kHz>\n# Flash base address, total flash size, and number of sectors are all configured automatically.\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME $FLASH_CLOCK\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc2xxx.cfg",
    "content": "# Common setup for the LPC2xxx parts\n\n# parameters:\n# - chip_name - name of the chip, e.g. lpc2103\n# - cputapids - TAP IDs of the core, should be quoted if more than one, e.g. 0x4f1f0f0f or \"0x3f0f0f0f 0x4f1f0f0f\"\n# - flash_size - size of on-chip flash (available for code, not including the bootloader) in bytes, e.g. 0x8000\n# - flash_variant - \"type\" of LPC2xxx device, lpc2000_v1 (LPC22xx and older LPC21xx) or lpc2000_v2 (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)\n# - workarea_size - size of work-area in RAM for flashing procedures, must not exceed the size of RAM available at 0x40000000, e.g. 0x2000\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size core_freq_khz adapter_freq_khz} {\n\treset_config trst_and_srst\n\n\t# reset delays\n\tadapter srst delay 100\n\tjtag_ntrst_delay 100\n\n\tadapter speed $adapter_freq_khz\n\n\tforeach i $cputapids {\n\t\tappend expected_ids \"-expected-id \" $i \" \"\n\t}\n\n\teval \"jtag newtap $chip_name cpu -irlen 4 -ircapture 0x1 -irmask 0xf $expected_ids\"\n\n\tglobal _TARGETNAME\n\tset _TARGETNAME $chip_name.cpu\n\ttarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n\t$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size $workarea_size -work-area-backup 0\n\n\tif { $flash_size > 0 } {\n\t\t# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum]\n\t\tset _FLASHNAME $chip_name.flash\n\t\tflash bank $_FLASHNAME lpc2000 0x0 $flash_size 0 0 $_TARGETNAME $flash_variant $core_freq_khz calc_checksum\n\t}\n}\n\nproc init_targets {} {\n\t# FIX!!! read out CPUTAPID here and choose right setup. In addition to the\n\t# CPUTAPID some querying of the target would be required.\n\treturn -error \"This is a generic LPC2xxx configuration file, use a specific target file.\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc3131.cfg",
    "content": "######################################\n# Target:    NXP lpc3131\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3131\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# ARM926EJS core\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926f0f\n}\n\n# Scan Tap\n# Wired to separate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module\n# JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through.\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1541E02B\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n##################################################################\n# various symbol definitions, to avoid hard-wiring addresses\n##################################################################\n\nglobal lpc313x\nset lpc313x [ dict create ]\n\n# Physical addresses for controllers and memory\ndict set lpc313x sram0\t\t\t0x11028000\ndict set lpc313x sram1\t\t\t0x11040000\ndict set lpc313x uart\t\t\t0x15001000\ndict set lpc313x cgu\t\t\t0x13004000\ndict set lpc313x ioconfig\t\t0x13003000\ndict set lpc313x sysconfig\t\t0x13002800\ndict set lpc313x wdt\t\t\t0x13002400\n\n##################################################################\n# Target configuration\n##################################################################\n\nadapter srst delay 1000\njtag_ntrst_delay 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME invoke-event halted\n\n$_TARGETNAME configure -work-area-phys [dict get $lpc313x sram0] -work-area-size 0x30000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"\\nRunning reset init script for LPC3131\\n\"\n\thalt\n\twait_halt\n\treg cpsr 0xa00000d3\t;#Supervisor mode\n\treg pc 0x11029000\n\tpoll\n\tsleep 500\n}\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc3250.cfg",
    "content": "# lpc3250 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3250\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x17900f0f\n}\n\nif { [info exists CPUTAPID_REV_A0] } {\n   set _CPUTAPID_REV_A0 $CPUTAPID_REV_A0\n} else {\n   set _CPUTAPID_REV_A0 0x17926f0f\n}\n\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1b900f0f\n}\n\njtag newtap $_CHIPNAME sjc -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_SJCTAPID\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID \\\n     -expected-id $_CPUTAPID_REV_A0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -work-area-phys 0x00000000 -work-area-size 0x7d0000 -work-area-backup 0\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc40xx.cfg",
    "content": "# NXP LPC40xx Cortex-M4F with at least 16kB SRAM\nset CHIPNAME lpc40xx\nset CHIPSERIES lpc4000\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x4000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc4350.cfg",
    "content": "source [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4350\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\nif { [using_jtag] } {\n\tswj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tdap create $_CHIPNAME.m0.dap -chain-position $_CHIPNAME.m0\n\ttarget create $_CHIPNAME.m0 cortex_m -dap $_CHIPNAME.m0.dap\n}\n\n# LPC4350 has 96+32 KB SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n\t\t\t-work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # on this CPU we should use VECTRESET to perform a soft reset and\n   # manually reset the periphery\n   # SRST or SYSRESETREQ disable the debug interface for the time of\n   # the reset and will not fit our requirements for a consistent debug\n   # session\n   cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc4357.cfg",
    "content": "#\n# NXP LPC4357\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc4357\n}\nset WORKAREASIZE 0x8000\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.flasha lpc2000 0x1A000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\nflash bank $_CHIPNAME.flashb lpc2000 0x1B000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc4370.cfg",
    "content": "#\n# NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each\n#\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4370\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} else {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\n# LPC4370 has 96+32 KB contiguous SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n                        -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME m0app -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tjtag newtap $_CHIPNAME m0sub -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\n\tdap create $_CHIPNAME.m0app.dap -chain-position $_CHIPNAME.m0app\n\tdap create $_CHIPNAME.m0sub.dap -chain-position $_CHIPNAME.m0sub\n\ttarget create $_CHIPNAME.m0app cortex_m -dap $_CHIPNAME.m0app.dap\n\ttarget create $_CHIPNAME.m0sub cortex_m -dap $_CHIPNAME.m0sub.dap\n\n\t# 32+8+32 KB SRAM\n\t$_CHIPNAME.m0app configure -work-area-phys 0x10080000 \\\n\t                           -work-area-size 0x92000 -work-area-backup 0\n\n\t# 16+2 KB M0 subsystem SRAM\n\t$_CHIPNAME.m0sub configure -work-area-phys 0x18000000 \\\n\t                           -work-area-size 0x4800 -work-area-backup 0\n\n\t# Default to the Cortex-M4\n\ttargets $_CHIPNAME.m4\n}\n\nif { ![using_hla] } {\n\tcortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc84x.cfg",
    "content": "# NXP LPC84x Cortex-M0+ with at least 8kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc84x\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1fe0\n}\n\nset IAP_ENTRY 0x0F001FF1\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc8nxx.cfg",
    "content": "# NXP LPC8Nxx NHS31xx Cortex-M0+ with 8kB SRAM\n# Copyright (C) 2018 by Jean-Christian de Rivaz\n# Based on NXP proposal https://community.nxp.com/message/1011149\n# Many thanks to Dries Moors from NXP support.\n# SWD only transport\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME lpc8nxx\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\nif {![using_hla]} {\n\t# If srst is not fitted use SYSRESETREQ to  perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\nadapter srst delay 100\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0\n\nflash bank $_CHIPNAME.flash lpc2000 0x0 0x7800 0 0 $_TARGETNAME lpc800 500\n\necho \"*********************************************************************************\"\necho \"*         !!!!! IMPORTANT NOTICE FOR LPC8Nxx and NHS31xx CHIPS !!!!!\"\necho \"* When this IC is in power-off or peep power down mode, the SWD HW block is also\"\necho \"* unpowered. These modes can be entered by firmware. The default firmware image\"\necho \"* (flashed in production) makes use of this. Best is to avoid these power modes\"\necho \"* during development, and only later add them when the functionality is complete.\"\necho \"* Hardware reset or NFC field are the only ways to connect in case the SWD is\"\necho \"* powered off. OpenOCD can do a hardware reset if you wire the adapter SRST\"\necho \"* signal to the chip RESETN pin and add the following in your configuration:\"\necho \"*     reset_config srst_only; flash init; catch init; reset\"\necho \"* But if the actual firmware immediately set the power down mode after reset,\"\necho \"* OpenOCD might be not fast enough to halt the CPU before the SWD lost power. In\"\necho \"* that case the only solution is to apply a NFC field to keep the SWD powered.\"\necho \"*********************************************************************************\"\n\n# Using soft-reset 'reset_config none' is strongly discouraged.\n# RESETN sets the system clock to 500 kHz. Unlike soft-reset does not.\n# Set the system clock to 500 kHz before reset to simulate the functionality of hw reset.\n#\nproc set_sysclk_500khz {} {\n\tset SYSCLKCTRL 0x40048020\n\tset SYSCLKUEN 0x40048024\n\tmww $SYSCLKUEN 0\n\tmmw $SYSCLKCTRL 0x8 0xe\n\tmww $SYSCLKUEN 1\n\techo \"Notice: sysclock set to 500kHz.\"\n}\n\n# Do not remap the ARM interrupt vectors to anything but the beginning of the flash.\n# Table System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n# Bit Symbol  Value   Description\n# 0   map         -   interrupt vector remap. 0 after boot.\n#                 0   interrupt vector reside in Flash\n#                 1   interrupt vector reside in SRAM\n# 5:1 offset      -   system memory remap offset. 00000b after boot.\n#            00000b   interrupt vectors in flash or remapped to SRAM but no offset\n#            00001b -\n#            00111b   interrupt vectors offset in flash or SRAM to 1K word segment\n#            01000b -\n#            11111b   interrupt vectors offset in flash to 1K word segment 8 to 31\n# 31:6                reserved\n#\nproc set_no_remap {} {\n\tmww 0x40048000 0x00\n\techo \"Notice: interrupt vector set to no remap.\"\n}\n\n$_TARGETNAME configure -event reset-init {\n\tset_sysclk_500khz\n\tset_no_remap\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lpc8xx.cfg",
    "content": "# NXP LPC8xx Cortex-M0+ with at least 1kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc8xx\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ls1012a.cfg",
    "content": "#\n# NXP LS1012A\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1012a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b2001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ncti create $_CHIPNAME.cti -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0x80420000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -dbgbase 0x80410000 -cti $_CHIPNAME.cti\n\ntarget smp $_TARGETNAME\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ls1028a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1028A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1028a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\nset _CPUS 2\n\nsource [find target/lsch3_common.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1046a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b3001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _CPU_BASE 0x80400000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < 4} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t-coreid $i {*}[expr {$i ? {-defer-examine} : {-rtos hwthread} }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\ntarget create $_CHIPNAME.sap ls1_sap -chain-position $_CHIPNAME.sap -endian big\n\nproc core_up { args } {\n    foreach core $args {\n        $::_CHIPNAME.cpu$core arp_examine\n    }\n}\n\ntargets $_CHIPNAME.cpu0\n\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1088a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nset _CPUS 8\n\nsource [find target/lsch3_common.cfg]\n\n# Seems to work OK in testing\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/lsch3_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# This contains common configuration for NXP Layerscape chassis generation 3\n\nif { ![info exists _CPUS] } {\n\terror \"_CPUS must be set to the number of cores\"\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 1\n\nset _CPU_BASE 0x81000000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < $_CPUS} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 0 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t{*}[expr {$i ? \"-coreid $i\" : \"-rtos hwthread\" }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\n# Service processor\ntarget create $_CHIPNAME.sp cortex_a -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80138000\n\n# Normally you will not need to call this, but if you are using the hard-coded\n# Reset Configuration Word (RCW) you will need to call this manually. The CPU's\n# reset vector is 0, and the boot ROM at that location contains ARMv7-A 32-bit\n# instructions. This will cause the CPU to almost immediately execute an\n# illegal instruction.\n#\n# This code is idempotent; releasing a released CPU has no effect, although it\n# will halt/resume the service processor.\nadd_help_text release_cpu \"Release a cpu which is held off\"\nproc release_cpu {cpu} {\n\tset RST_BRRL 0x1e60060\n\n\tset old [target current]\n\ttargets $::_CHIPNAME.sp\n\tset not_halted [string compare halted [$::_CHIPNAME.sp curstate]]\n\tif {$not_halted} {\n\t\thalt\n\t}\n\n\t# Release the cpu; it will start executing something bogus\n\tmem2array regs 32 $RST_BRRL 1\n\tmww $RST_BRRL [expr {$regs(0) | 1 << $cpu}]\n\n\tif {$not_halted} {\n\t\tresume\n\t}\n\ttargets $old\n}\n\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/marvell/88f3710.cfg",
    "content": "# Marvell Armada 3710\n\nset CORES 1\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/marvell/88f3720.cfg",
    "content": "# Marvell Armada 3720\n\nset CORES 2\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/marvell/88f37x0.cfg",
    "content": "# Main file for Marvell Armada 3700 series targets\n#\n# !!!!!!\n#\n# This file should not be included directly. Instead, please include\n# either marvell/88f3710.cfg or marvell/88f3720.cfg, which set the needed\n# variables to the appropriate values.\n#\n# !!!!!!\n\n# Armada 3700 supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CORES] } {\n    set _cores $CORES\n} else {\n    error \"CORES not set. Please do not include marvell/88f37x0.cfg directly, but the specific chip configuration file (marvell/88f3710.cfg, marvell/88f3720.cfg, etc.).\"\n}\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME [format a37%s0 $_cores]\n}\n\nset _ctis {0x80820000 0x80920000}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# declare the main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [lindex $_ctis $_core] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core \\\n                         -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        # set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M3 core on AP #3\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/max32620.cfg",
    "content": "# Maxim Integrated MAX32620 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -ignore-version\n} else {\n    swd newdap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32620.cpu cortex_m -chain-position max32620.cpu\nmax32620.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32620 flash base address   0x00000000\n#   max32620 flash size           0x200000 (2MB)\n#   max32620 FLC base address     0x40002000\n#   max32620 sector (page) size   0x2000 (8kB)\n#   max32620 clock speed          96 (MHz)\nflash bank max32620.flash max32xxx 0x00000000 0x200000 0 0 max32620.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/max32625.cfg",
    "content": "# Maxim Integrated MAX32625 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f71197 -ignore-version\n} else {\n    swd newdap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max32625.cpu cortex_m -chain-position max32625.cpu\nmax32625.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32625 flash base address   0x00000000\n#   max32625 flash size           0x80000 (512k)\n#   max32625 FLC base address     0x40002000\n#   max32625 sector (page) size   0x2000 (8kB)\n#   max32625 clock speed          96 (MHz)\nflash bank max32625.flash max32xxx 0x00000000 0x80000 0 0 max32625.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/max3263x.cfg",
    "content": "# Maxim Integrated MAX3263X OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f76197 -ignore-version\n} else {\n    swd newdap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\n# target configuration\ntarget create max3263x.cpu cortex_m -chain-position max3263x.cpu\nmax3263x.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max3263x flash base address   0x00000000\n#   max3263x flash size           0x200000 (2MB)\n#   max3263x FLC base address     0x40002000\n#   max3263x sector (page) size   0x2000 (8kB)\n#   max3263x clock speed          96 (MHz)\nflash bank max3263x.flash max32xxx 0x00000000 0x200000 0 0 max3263x.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/mc13224v.cfg",
    "content": "source [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER             freescale\nset CHIP_FAMILY            mc1322x\nset CHIP_NAME              mc13224\nset N_RAM                  1\nset RAM(0,BASE)            0x00400000\nset RAM(0,LEN)             0x18000\nset RAM(0,HUMAN)           \"internal SRAM\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS                  1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0x80000000\nset MMREGS(0,LEN)             0x00030000\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\nset N_XMEM 0\n\nset _CHIPNAME mc13224v\nset _CPUTAPID 0x1f1f001d\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nreset_config srst_only\njtag_ntrst_delay 200\n\n# rclk hasn't been working well. This maybe the mc13224v or something else.\n#adapter speed 2000\nadapter speed 2000\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n# Internal sram memory\n$_TARGETNAME configure -work-area-phys 0x00408000 \\\n                       -work-area-size 0x1000     \\\n                       -work-area-backup 1\n\n# flash support is pending (should be straightforward to implement)\n#flash bank mc1322x 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/mdr32f9q2i.cfg",
    "content": "# MDR32F9Q2I (1986ВЕ92У)\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=57&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME mdr32f9q2i\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x08000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x08000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nds32v2.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v2 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nds32v3.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3 -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nds32v3m.cfg",
    "content": "#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\njtag newtap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME nds32_v3m -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nds32v5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\nset _CHIPNAME nds\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563D\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nhs31xx.cfg",
    "content": "# NXP NHS31xx Cortex-M0+ with 8kB SRAM\n\nset CHIPNAME nhs31xx\nsource [find target/lpc8nxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/npcx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton NPCX Cortex-M4 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NPCX_M4\n}\n\n# SWD DAP ID of Nuvoton NPCX Cortex-M4.\nif { [info exists CPUDAPID ] } {\n   set _CPUDAPID $CPUDAPID\n} else {\n   set _CPUDAPID 0x4BA00477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x200c0000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# Initial JTAG/SWD speed\n# For safety purposes, set for the lowest cpu clock configuration\n# 4MHz / 6 = 666KHz, so use 600KHz for it\nadapter speed 600\n\n# For safety purposes, set for the lowest cpu clock configuration\n$_TARGETNAME configure -event reset-start {adapter speed 600}\n\n# use sysresetreq to perform a system reset\ncortex_m reset_config sysresetreq\n\n# flash configuration\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nrf51.cfg",
    "content": "#\n# script for Nordic nRF51 series, a Cortex-M0 chip\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nrf51\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # The chip supports standard ARM/Cortex-M0 SYSRESETREQ signal\n   cortex_m reset_config sysresetreq\n}\n\nflash bank $_CHIPNAME.flash nrf51 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME\n\n#\n#  The chip should start up from internal 16Mhz RC, so setting adapter\n#  clock to 1Mhz should be OK\n#\nadapter speed 1000\n\nproc enable_all_ram {} {\n\t# nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks\n\t# are reliably enabled after reset on some revisions (contrary to spec.) So after\n\t# resetting we enable all banks via the RAMON register\n\tmww 0x40000524 0xF\n}\n$_TARGETNAME configure -event reset-end {  enable_all_ram }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nrf52.cfg",
    "content": "#\n# Nordic nRF52 series: ARM Cortex-M4 @ 64 MHz\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME nrf52\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nadapter speed 1000\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_hla] } {\n\techo \"\"\n\techo \"nRF52 device has a CTRL-AP dedicated to recover the device from AP lock.\"\n\techo \"A high level adapter (like a ST-Link) you are currently using cannot access\"\n\techo \"the CTRL-AP so 'nrf52_recover' command will not work.\"\n\techo \"Do not enable UICR APPROTECT.\"\n\techo \"\"\n} else {\n\tcortex_m reset_config sysresetreq\n\n\t$_TARGETNAME configure -event examine-fail nrf52_check_ap_lock\n}\n\nflash bank $_CHIPNAME.flash nrf5 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf5 0x10001000 0 1 1 $_TARGETNAME\n\n# Test if MEM-AP is locked by UICR APPROTECT\nproc nrf52_check_ap_lock {} {\n\tset dap [[target current] cget -dap]\n\tset err [catch {set APPROTECTSTATUS [$dap apreg 1 0xc]}]\n\tif {$err == 0 && $APPROTECTSTATUS != 1} {\n\t\techo \"****** WARNING ******\"\n\t\techo \"nRF52 device has AP lock engaged (see UICR APPROTECT register).\"\n\t\techo \"Debug access is denied.\"\n\t\techo \"Use 'nrf52_recover' to erase and unlock the device.\"\n\t\techo \"\"\n\t\tpoll off\n\t}\n}\n\n# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #1)\n# http://www.ebyte.com produces modules with nRF52 locked by default,\n# use nrf52_recover to enable flashing and debug.\nproc nrf52_recover {} {\n\tset target [target current]\n\tset dap [$target cget -dap]\n\n\tset IDR [$dap apreg 1 0xfc]\n\tif {$IDR != 0x02880000} {\n\t\techo \"Error: Cannot access nRF52 CTRL-AP!\"\n\t\treturn\n\t}\n\n\tpoll off\n\n\t# Reset and trigger ERASEALL task\n\t$dap apreg 1 4 0\n\t$dap apreg 1 4 1\n\n\tfor {set i 0} {1} {incr i} {\n\t\tset ERASEALLSTATUS [$dap apreg 1 8]\n\t\tif {$ERASEALLSTATUS == 0} {\n\t\t\techo \"$target device has been successfully erased and unlocked.\"\n\t\t\tbreak\n\t\t}\n\t\tif {$i == 0} {\n\t\t\techo \"Waiting for chip erase...\"\n\t\t}\n\t\tif {$i >= 150} {\n\t\t\techo \"Error: $target recovery failed.\"\n\t\t\tbreak\n\t\t}\n\t\tsleep 100\n\t}\n\n\t# Assert reset\n\t$dap apreg 1 0 1\n\n\t# Deassert reset\n\t$dap apreg 1 0 0\n\n\t# Reset ERASEALL task\n\t$dap apreg 1 4 0\n\n\tsleep 100\n\t$target arp_examine\n\tpoll on\n}\n\nadd_help_text nrf52_recover \"Mass erase and unlock nRF52 device\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/nuc910.cfg",
    "content": "#\n# Nuvoton nuc910 (previously W90P910) based soc\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nuc910\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x07926f0f\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/numicro.cfg",
    "content": "# script for Nuvoton MuMicro Cortex-M0 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NuMicro\n}\n\n# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only.\nif { [info exists CPUDAPID] } {\n\tset _CPUDAPID $CPUDAPID\n} else {\n\tset _CPUDAPID 0x0BB11477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash_aprom\nflash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_data\nflash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_ldrom\nflash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_config\nflash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME\n\n# set default SWCLK frequency\nadapter speed 1000\n\n# set default srst setting \"none\"\nreset_config none\n\n# HLA doesn't have cortex_m commands\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omap2420.cfg",
    "content": "# Texas Instruments OMAP 2420\n#\thttp://www.ti.com/omap\n# as seen in Nokia N8x0 tablets\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap2420\n}\n\n# NOTE: likes slowish clock on reset (1.5 MBit/s or less) or use RCLK\nreset_config srst_nogate\n\n# Subsidiary TAP: ARM7TDMIr4 plus imaging ... must add via ICEpick (addr 6).\njtag newtap $_CHIPNAME iva -irlen 4 -disable\n\n# Subsidiary TAP: C55x DSP ... must add via ICEpick (addr 2).\njtag newtap $_CHIPNAME dsp -irlen 38 -disable\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID\n\n# Subsidiary TAP: ARM1136jf-s with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07b3602f\n}\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\n# Primary TAP: ICEpick-B (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x01ce4801\n}\njtag newtap $_CHIPNAME jrc -irlen 2 -expected-id $_JRC_TAPID\n\n# GDB target: the ARM.\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_TARGETNAME\n\n# scratch: framebuffer, may be initially unavailable in some chips\n$_TARGETNAME configure -work-area-phys 0x40210000\n$_TARGETNAME configure -work-area-size 0x00081000\n$_TARGETNAME configure -work-area-backup 0\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\n# RM_RSTCTRL_WKUP.RST.GS - Trigger a global software reset, and\n# give it a chance to finish before we talk to the chip again.\nset RM_RSTCTRL_WKUP 0x48008450\n$_TARGETNAME configure -event reset-assert \\\n\t\"halt; $_TARGETNAME mww $RM_RSTCTRL_WKUP 2; sleep 200\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omap3530.cfg",
    "content": "# TI OMAP3530\n# http://focus.ti.com/docs/prod/folders/print/omap3530.html\n# Other OMAP3 chips remove DSP and/or the OpenGL support\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap3530\n}\n\n# ICEpick-C ... used to route Cortex, DSP, and more not shown here\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n\n# Subsidiary TAP: CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x0b6d602f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7ae02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# SRAM: 64K at 0x4020.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n###################\n\n# the reset sequence is event-driven\n# and kind of finicky...\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# have the DAP \"always\" be active\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\nproc omap3_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n     # Enable DBGU signal for OMAP353x\n     $target mww phys 0x5401d030 0x00002000\n}\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in.\n# OK to speed up *after* PLL and clock tree setup.\nadapter speed 1000\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1000 }\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  RST_GS (2) is a warm reset, like ICEpick\n# would issue.  RST_DPLL3 (4) is a cold reset.\nset PRM_RSTCTRL 0x48307250\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww $PRM_RSTCTRL 2\"\n\n$_TARGETNAME configure -event reset-assert-post \"omap3_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omap4430.cfg",
    "content": "# OMAP4430\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4430\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x3b95c02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omap4460.cfg",
    "content": "# OMAP4460\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4460\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x2b94e02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omap5912.cfg",
    "content": "# TI OMAP5912 dual core processor\n# http://focus.ti.com/docs/prod/folders/print/omap5912.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap5912\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # NOTE: validated with XOMAP5912 part\n   set _CPUTAPID 0x0692602f\n}\n\nadapter srst delay 100\n\n# NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for\n# its standalone siblings (like TMS320VC5502) of the same era\n\n#jtag scan chain\njtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81\njtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID\njtag newtap $_CHIPNAME unknown -irlen 8\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\nproc omap5912_reset {} {\n\t#\n\t# halt target\n\t#\n\tpoll\n\tsleep 1\n\thalt\n\twait_halt\n\t#\n\t# disable wdt\n\t#\n\tmww 0xfffec808 0x000000f5\n\tmww 0xfffec808 0x000000a0\n\n\tmww 0xfffeb048 0x0000aaaa\n\tsleep 500\n\tmww 0xfffeb048 0x00005555\n\tsleep 500\n}\n\n# omap5912 lcd frame buffer as working area\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n\t-work-area-size 0x3e800 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/omapl138.cfg",
    "content": "#\n# Texas Instruments DaVinci family: OMAPL138\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omapl138\n}\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID -disable\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID -disable\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7d102f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target:  the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\ngdb_breakpoint_override hard\narm7_9 dbgrq enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/or1k.cfg",
    "content": "set  _ENDIAN big\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME or1k\n}\n\nif { [info exists TAP_TYPE] } {\n   set _TAP_TYPE $TAP_TYPE\n} else {\n   puts \"You need to select a tap type\"\n   shutdown\n}\n\n# Configure the target\nif { [string compare $_TAP_TYPE \"VJTAG\"] == 0 } {\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 10 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select vjtag\n\n} elseif { [string compare $_TAP_TYPE \"XILINX_BSCAN\"] == 0 } {\n\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select xilinx_bscan\n} else {\n\t# OpenCores Mohor JTAG TAP ID\n\tset _CPUTAPID  0x14951185\n\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select mohor\n}\n\n# Select the debug unit core we are using. This debug unit as an option.\n\nset ADBG_USE_HISPEED\t\t1\nset ENABLE_JSP_SERVER\t\t2\nset ENABLE_JSP_MULTI\t\t4\n\n# If ADBG_USE_HISPEED is set (options bit 1), status bits will be skipped\n# on burst reads and writes to improve download speeds.\n# This option must match the RTL configured option.\n\ndu_select adv [expr {$ADBG_USE_HISPEED | $ENABLE_JSP_SERVER | $ENABLE_JSP_MULTI}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/pic32mx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pic32mx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x30938053\n}\n\n# default working area is 16384\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#\n# At reset the pic32mx does not allow code execution from RAM\n# we have to setup the BMX registers to allow this.\n# One limitation is that we loose the first 2k of RAM.\n#\n\nglobal _PIC32MX_DATASIZE\nglobal _WORKAREASIZE\nset _PIC32MX_DATASIZE 0x800\nset _PIC32MX_PROGSIZE [expr {$_WORKAREASIZE - $_PIC32MX_DATASIZE}]\n\n$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size $_PIC32MX_PROGSIZE -work-area-backup 0\n$_TARGETNAME configure -event reset-init {\n\t#\n\t# from reset the pic32 cannot execute code in ram - enable ram execution\n\t# minimum offset from start of ram is 2k\n\t#\n\tglobal _PIC32MX_DATASIZE\n\tglobal _WORKAREASIZE\n\n\t# BMXCON\tset 0 wait state option by clearing BMXWSDRM bit, bit 6\n\tmww 0xbf882000 0x001f0000\n\t# BMXDKPBA: 2k kernel data @ 0xa0000000\n\tmww 0xbf882010 $_PIC32MX_DATASIZE\n\t# BMXDUDBA: 14k kernel program @ 0xa0000800 - (BMXDUDBA - BMXDKPBA)\n\tmww 0xbf882020 $_WORKAREASIZE\n\t# BMXDUPBA: 0k user program - (BMXDUPBA - BMXDUDBA)\n\tmww 0xbf882030 $_WORKAREASIZE\n\n\t#\n\t# Set system clock to 8Mhz if the default clock configuration is set\n\t#\n\n\t# SYSKEY register, make sure OSCCON is locked\n\tmww 0xbf80f230 0x0\n\t# SYSKEY register, write unlock sequence\n\tmww 0xbf80f230 0xaa996655\n\tmww 0xbf80f230 0x556699aa\n\t# OSCCON register + 4, clear OSCCON FRCDIV bits: 24, 25 and 26, divided by 1\n\tmww 0xbf80f004 0x07000000\n\t# SYSKEY register, relock OSCCON\n\tmww 0xbf80f230 0x0\n}\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank2 virtual 0xbd000000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank3 virtual 0x9d000000 0 0 0 $_TARGETNAME $_FLASHNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/psoc4.cfg",
    "content": "# script for Cypress PSoC 4 devices\n\n#\n# PSoC 4 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME psoc4\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\nadapter speed 1500\n\n# Reset, bloody PSoC 4 reset\n#\n# 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.\n# High level adapter stops working after SRST and needs OpenOCD restart.\n# If your hw does not use SRST for other circuits, use sysresetreq instead\n#\n# 2) PSoC 4 executes initialization code from system ROM after reset.\n# This code subsequently jumps to user flash reset vector address.\n# Unfortunately the system ROM code is protected from reading and debugging.\n# Protection breaks vector catch VC_CORERESET used for \"reset halt\" by cortex_m.\n#\n# Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code\n# from user flash. Programming specifications states that TEST_MODE flag must be\n# set in time frame 400 usec delayed about 1 msec from reset.\n#\n# OpenOCD have no standard way how to set TEST_MODE in specified time frame.\n# As a workaround the TEST_MODE flag is set before reset instead.\n# It worked for the oldest family PSoC4100/4200 even though it is not guaranteed\n# by specification.\n#\n# Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE\n# clear TEST_MODE flag during device reset so workaround is not possible.\n# Use a KitProg adapter for these devices or \"reset halt\" will not stop\n# before executing user code.\n#\n# 3) SWD cannot be connected during system initialization after reset.\n# This might be a reason for unconnecting ST-Link v2 when deasserting reset.\n# As a workaround arp_reset deassert is not called for hla\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc psoc4_get_family_id {} {\n\tset err [catch {set romtable_pid [read_memory 0xF0000FE0 32 3]}]\n\tif { $err } {\n\t\treturn 0\n\t}\n\tif { [expr {[lindex $romtable_pid 0] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 1] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 2] & 0xffffff00 }] } {\n\t\techo \"Unexpected data in ROMTABLE\"\n\t\treturn 0\n\t}\n\tset designer_id [expr {(( [lindex $romtable_pid 1] & 0xf0 ) >> 4) | (( [lindex $romtable_pid 2] & 0xf ) << 4 ) }]\n\tif { $designer_id != 0xb4 } {\n\t\techo [format \"ROMTABLE Designer ID 0x%02x is not Cypress\" $designer_id]\n\t\treturn 0\n\t}\n\tset family_id [expr {( [lindex $romtable_pid 0] & 0xff ) | (( [lindex $romtable_pid 1] & 0xf ) << 8 ) }]\n\treturn $family_id\n}\n\nproc ocd_process_reset_inner { MODE } {\n\tglobal PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND\n\tglobal _TARGETNAME\n\n\tif { 0 != [string compare $_TARGETNAME [target names]] } {\n\t\treturn -code error \"PSoC 4 reset can handle only one $_TARGETNAME target\";\n\t}\n\tset t $_TARGETNAME\n\n\t# If this target must be halted...\n\tset halt -1\n\tif { 0 == [string compare $MODE halt] } {\n\t\tset halt 1\n\t}\n\tif { 0 == [string compare $MODE init] } {\n\t\tset halt 1;\n\t}\n\tif { 0 == [string compare $MODE run ] } {\n\t\tset halt 0;\n\t}\n\tif { $halt < 0 } {\n\t\treturn -code error \"Invalid mode: $MODE, must be one of: halt, init, or run\";\n\t}\n\n\tif { ! [info exists PSOC4_USE_ACQUIRE] } {\n\t\tif { 0 == [string compare [adapter name] kitprog ] } {\n\t\t\tset PSOC4_USE_ACQUIRE 1\n\t\t} else {\n\t\t\tset PSOC4_USE_ACQUIRE 0\n\t\t}\n\t}\n\tif { $PSOC4_USE_ACQUIRE } {\n\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t} elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {\n\t\tif { [psoc4_get_family_id] == 0x93 } {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 1\n\t\t} else {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t\t}\n\t}\n\n\t#$t invoke-event reset-start\n\t$t invoke-event reset-assert-pre\n\n\tif { $halt && $PSOC4_USE_ACQUIRE } {\n\t\tcatch { [adapter name] acquire_psoc }\n\t\t$t arp_examine\n\t} else {\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tset TEST_MODE 0x40030014\n\t\t\tif { $halt == 1 } {\n\t\t\t\tcatch { mww $TEST_MODE 0x80000000 }\n\t\t\t} else {\n\t\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t\t}\n\t\t}\n\n\t\t$t arp_reset assert 0\n\t}\n\n\t$t invoke-event reset-assert-post\n\t$t invoke-event reset-deassert-pre\n\tif {![using_hla]} {\t# workaround ST-Link v2 fails and forcing reconnect\n\t\t$t arp_reset deassert 0\n\t}\n\t$t invoke-event reset-deassert-post\n\n\t# Pass 1 - Now wait for any halt (requested as part of reset\n\t# assert/deassert) to happen.  Ideally it takes effect without\n\t# first executing any instructions.\n\tif { $halt } {\n\t\t# Now PSoC CPU should loop in system ROM\n\t\t$t arp_waitstate running 200\n\t\t$t arp_halt\n\n\t\t# Catch, but ignore any errors.\n\t\tcatch { $t arp_waitstate halted 1000 }\n\n\t\t# Did we succeed?\n\t\tset s [$t curstate]\n\n\t\tif { 0 != [string compare $s \"halted\" ] } {\n\t\t\treturn -code error [format \"TARGET: %s - Not halted\" $t]\n\t\t}\n\n\t\t# Check if PSoC CPU is stopped in system ROM\n\t\tset pc [reg pc]\n\t\tregsub {pc[^:]*: } $pc \"\" pc\n\t\tif { $pc < 0x10000000 || $pc > 0x1000ffff } {\n\t\t\tset hint \"\"\n\t\t\tset family_id [psoc4_get_family_id]\n\t\t\tif { $family_id == 0x93 } {\n\t\t\t\tset hint \", use 'reset_config none'\"\n\t\t\t} elseif { $family_id > 0x93 } {\n\t\t\t\tset hint \", use a KitProg adapter\"\n\t\t\t}\n\t\t\treturn -code error [format \"TARGET: %s - Not halted in system ROM%s\" $t $hint]\n\t\t}\n\n\t\t# Set registers to reset vector values\n\t\tset value [read_memory 0x0 32 2]\n\t\treg pc [expr {[lindex $value 1] & 0xfffffffe}]\n\t\treg msp [lindex $value 0]\n\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t}\n\t}\n\n\t#Pass 2 - if needed \"init\"\n\tif { 0 == [string compare init $MODE] } {\n\t\tset err [catch \"$t arp_waitstate halted 5000\"]\n\n\t\t# Did it halt?\n\t\tif { $err == 0 } {\n\t\t\t$t invoke-event reset-init\n\t\t}\n\t}\n\n\t$t invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/psoc5lp.cfg",
    "content": "#\n# Cypress PSoC 5LP\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc5lp\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} else {\n\tset _CPU_TAPID 0x4BA00477\n}\n\nif { [using_jtag] } {\n\tset _CPU_DAP_ID $_CPU_TAPID\n} else {\n\tset _CPU_DAP_ID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE / 2}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nsource [find mem_helper.tcl]\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure Target Device (PSoC 5LP Device Programming Specification 5.2)\n\n\tset PANTHER_DBG_CFG 0x4008000C\n\tset PANTHER_DBG_CFG_BYPASS [expr {1 << 1}]\n\tmmw $PANTHER_DBG_CFG $PANTHER_DBG_CFG_BYPASS 0\n\n\tset PM_ACT_CFG0 0x400043A0\n\tmww $PM_ACT_CFG0 0xBF\n\n\tset FASTCLK_IMO_CR 0x40004200\n\tset FASTCLK_IMO_CR_F_RANGE_2    [expr {2 << 0}]\n\tset FASTCLK_IMO_CR_F_RANGE_MASK [expr {7 << 0}]\n\tmmw $FASTCLK_IMO_CR $FASTCLK_IMO_CR_F_RANGE_2 $FASTCLK_IMO_CR_F_RANGE_MASK\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/psoc6.cfg",
    "content": "#\n# Configuration script for Cypress PSoC6 family of microcontrollers (CY8C6xxx)\n# PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share\n# the same Flash/RAM/MMIO address space.\n#\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc6\n}\n\nglobal TARGET\nset TARGET $_CHIPNAME.cpu\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Is CM0 Debugging enabled ?\nglobal _ENABLE_CM0\nif { [info exists ENABLE_CM0] } {\n\tset _ENABLE_CM0 $ENABLE_CM0\n} else {\n\tset _ENABLE_CM0 1\n}\n\n# Is CM4 Debugging enabled ?\nglobal _ENABLE_CM4\nif { [info exists ENABLE_CM4] } {\n\tset _ENABLE_CM4 $ENABLE_CM4\n} else {\n\tset _ENABLE_CM4 1\n}\n\nglobal _WORKAREASIZE_CM0\nif { [info exists WORKAREASIZE_CM0] } {\n\tset _WORKAREASIZE_CM0 $WORKAREASIZE_CM0\n} else {\n\tset _WORKAREASIZE_CM0 0x4000\n}\n\nglobal _WORKAREASIZE_CM4\nif { [info exists WORKAREASIZE_CM4] } {\n\tset _WORKAREASIZE_CM4 $WORKAREASIZE_CM4\n} else {\n\tset _WORKAREASIZE_CM4 0x4000\n}\n\nglobal _WORKAREAADDR_CM0\nif { [info exists WORKAREAADDR_CM0] } {\n\tset _WORKAREAADDR_CM0 $WORKAREAADDR_CM0\n} else {\n\tset _WORKAREAADDR_CM0 0x08000000\n}\n\nglobal _WORKAREAADDR_CM4\nif { [info exists WORKAREAADDR_CM4] } {\n\tset _WORKAREAADDR_CM4 $WORKAREAADDR_CM4\n} else {\n\tset _WORKAREAADDR_CM4 0x08000000\n}\n\nproc init_reset { mode } {\n\tglobal RESET_MODE\n\tset RESET_MODE $mode\n\n\tif {[using_jtag]} {\n\t\tjtag arp_init-reset\n\t}\n}\n\n# Utility to make 'reset halt' work as reset;halt on a target\n# It does not prevent running code after reset\nproc psoc6_deassert_post { target } {\n\t# PSoC6 cleared AP registers including TAR during reset\n\t# Force examine to synchronize OpenOCD target status\n\t$target arp_examine\n\n\tglobal RESET_MODE\n\tglobal TARGET\n\n\tif { $RESET_MODE ne \"run\" } {\n\t\t$target arp_poll\n\t\t$target arp_poll\n\t\tset st [$target curstate]\n\n\t\tif { $st eq \"reset\" } {\n\t\t\t# we assume running state follows\n\t\t\t# if reset accidentally halts, waiting is useless\n\t\t\tcatch { $target arp_waitstate running 100 }\n\t\t\tset st [$target curstate]\n\t\t}\n\n\t\tif { $st eq \"running\" } {\n\t\t\techo \"$target: Ran after reset and before halt...\"\n\t\t\tif { $target eq \"${TARGET}.cm0\" } {\n\t\t\t\t# Try to cleanly reset whole system\n\t\t\t\t# and halt the CM0 at entry point\n\t\t\t\tpsoc6 reset_halt\n\t\t\t\t$target arp_waitstate halted 100\n\t\t\t} else {\n\t\t\t\t$target arp_halt\n\t\t\t}\n\t\t}\n\t}\n}\n\nif { $_ENABLE_CM0 } {\n\ttarget create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\t${TARGET}.cm0 configure -work-area-phys $_WORKAREAADDR_CM0 -work-area-size $_WORKAREASIZE_CM0 -work-area-backup 0\n\n\tflash bank main_flash_cm0\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm0\n\tflash bank work_flash_cm0\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_user_cm0\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_nar_cm0\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_key_cm0\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_toc2_cm0\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm0\n\n\t${TARGET}.cm0 cortex_m reset_config sysresetreq\n\t${TARGET}.cm0 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm0\"\n}\n\nif { $_ENABLE_CM4 } {\n\ttarget create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\t${TARGET}.cm4 configure -work-area-phys $_WORKAREAADDR_CM4 -work-area-size $_WORKAREASIZE_CM4 -work-area-backup 0\n\n\tflash bank main_flash_cm4\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm4\n\tflash bank work_flash_cm4\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_user_cm4\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_nar_cm4\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_key_cm4\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_toc2_cm4\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm4\n\n\t${TARGET}.cm4 cortex_m reset_config vectreset\n\t${TARGET}.cm4 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm4\"\n}\n\nif { $_ENABLE_CM0 } {\n\t# Use CM0+ by default on dual-core devices\n\ttargets ${TARGET}.cm0\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 18 -expected-id 0x2e200069\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/pxa255.cfg",
    "content": "# PXA255 chip ... originally from Intel, PXA line was sold to Marvell.\n# This chip is now at end-of-life.  Final orders have been taken.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa255\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x69264013\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_CHIPNAME.cpu\n\n# PXA255 comes out of reset using 3.6864 MHz oscillator.\n# Until the PLL kicks in, keep the JTAG clock slow enough\n# that we get no errors.\nadapter speed 300\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 300 }\n\n# both TRST and SRST are *required* for debug\n# DCSR is often accessed with SRST active\nreset_config trst_and_srst separate srst_nogate\n\n# reset processing that works with PXA\nproc init_reset {mode} {\n\t# assert both resets; equivalent to power-on reset\n\tadapter assert trst assert srst\n\n\t# drop TRST after at least 32 cycles\n\tsleep 1\n\tadapter deassert trst assert srst\n\n\t# minimum 32 TCK cycles to wake up the controller\n\truntest 50\n\n\t# now the TAP will be responsive; validate scanchain\n\tjtag arp_init\n\n\t# ... and take it out of reset\n\tadapter deassert trst deassert srst\n}\n\nproc jtag_init {} {\n\tinit_reset startup\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/pxa270.cfg",
    "content": "#Marvell/Intel PXA270 Script\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa270\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n#IDs for pxa270. Are there more?\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x49265013\n}\n\nif { [info exists CPUTAPID2] } {\n   set _CPUTAPID2 $CPUTAPID2\n} else {\n  # set useful default\n   set _CPUTAPID2 0x79265013\n}\n\nif { [info exists CPUTAPID3] } {\n   set _CPUTAPID2 $CPUTAPID3\n} else {\n  # set useful default\n   set _CPUTAPID3 0x89265013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n# maps to PXA internal RAM. If you are using a PXA255\n# you must initialize SDRAM or leave this option off\n$_TARGETNAME configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/pxa3xx.cfg",
    "content": "# Marvell PXA3xx\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa3xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# IDs for all currently known PXA3xx chips\nif { [info exists CPUTAPID_PXA30X_A0] } {\n   set _CPUTAPID_PXA30X_A0 $CPUTAPID_PXA30X_A0\n} else {\n   set _CPUTAPID_PXA30X_A0 0x0E648013\n}\nif { [info exists CPUTAPID_PXA30X_A1] } {\n   set _CPUTAPID_PXA30X_A1 $CPUTAPID_PXA30X_A1\n} else {\n   set _CPUTAPID_PXA30X_A1 0x1E648013\n}\nif { [info exists CPUTAPID_PXA31X_A0] } {\n   set _CPUTAPID_PXA31X_A0 $CPUTAPID_PXA31X_A0\n} else {\n   set _CPUTAPID_PXA31X_A0 0x0E649013\n}\nif { [info exists CPUTAPID_PXA31X_A1] } {\n   set _CPUTAPID_PXA31X_A1 $CPUTAPID_PXA31X_A1\n} else {\n   set _CPUTAPID_PXA31X_A1 0x1E649013\n}\nif { [info exists CPUTAPID_PXA31X_A2] } {\n   set _CPUTAPID_PXA31X_A2 $CPUTAPID_PXA31X_A2\n} else {\n   set _CPUTAPID_PXA31X_A2 0x2E649013\n}\nif { [info exists CPUTAPID_PXA31X_B0] } {\n   set _CPUTAPID_PXA31X_B0 $CPUTAPID_PXA31X_B0\n} else {\n   set _CPUTAPID_PXA31X_B0 0x3E649013\n}\nif { [info exists CPUTAPID_PXA32X_B1] } {\n   set _CPUTAPID_PXA32X_B1 $CPUTAPID_PXA32X_B1\n} else {\n   set _CPUTAPID_PXA32X_B1 0x5E642013\n}\nif { [info exists CPUTAPID_PXA32X_B2] } {\n   set _CPUTAPID_PXA32X_B2 $CPUTAPID_PXA32X_B2\n} else {\n   set _CPUTAPID_PXA32X_B2 0x6E642013\n}\nif { [info exists CPUTAPID_PXA32X_C0] } {\n   set _CPUTAPID_PXA32X_C0 $CPUTAPID_PXA32X_C0\n} else {\n   set _CPUTAPID_PXA32X_C0 0x7E642013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 11 -ircapture 0x1 -irmask 0x7f \\\n\t-expected-id $_CPUTAPID_PXA30X_A0 \\\n\t-expected-id $_CPUTAPID_PXA30X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A0 \\\n\t-expected-id $_CPUTAPID_PXA31X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A2 \\\n\t-expected-id $_CPUTAPID_PXA31X_B0 \\\n\t-expected-id $_CPUTAPID_PXA32X_B1 \\\n\t-expected-id $_CPUTAPID_PXA32X_B2 \\\n\t-expected-id $_CPUTAPID_PXA32X_C0\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# work area in internal RAM.\n$_TARGETNAME configure -work-area-phys 0x5c030000 -work-area-size 0x10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/qualcomm_qca4531.cfg",
    "content": "# The QCA4531 is a two stream (2x2) 802.11b/g/n single-band programmable\n# Wi-Fi System-on-Chip (SoC) for the Internet of Things (IoT).\n#\n# Product page:\n# https://www.qualcomm.com/products/qca4531\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 650 MHz\n# - External 16-bit DDR1, operating at up to 200 MHz, DDR2 operating at up\n#   to 300 MHz\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin B56 on the SoC will reset internal JTAG logic.\n#\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO1, (B23)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO2, (A28)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO3, (A29)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (B56)\tInput only\n# SYS_RST_L\tGPIO17, (A79)\tOutput reset request or GPIO\n#   Bootstrap\n# JTAG_MODE\tGPIO16, (A78)\t0 - JTAG (Default); 1 - EJTAG\n# DDR_SELECT\tGPIO10, (A57)\t0 - DDR2; 1 - DDR1\n#   UART\n# UART0_SOUT\tGPIO10, (A57)\n# UART0_SIN\tGPIO9, (B49)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME qca4531\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\n# Section with helpers which can be used by boards\nproc qca4531_ddr2_550_550_init {} {\n\t# Clear reset flags for different SoC components\n\tmww 0xb806001c 0xfeceffff\n\tmww 0xb806001c 0xeeceffff\n\tmww 0xb806001c 0xe6ceffff\n\n\t# PMU configurations\n\t# Internal Switcher\n\tmww 0xb8116c40 0x633c8176\n\t# Increase the DDR voltage\n\tmww 0xb8116c44 0x10200000\n\t# XTAL Configurations\n\tmww 0xb81162c0 0x4b962100\n\tmww 0xb81162c4 0x480\n\tmww 0xb81162c8 0x04000144\n\t# Recommended PLL configurations\n\tmww 0xb81161c4 0x54086000\n\tmww 0xb8116244 0x54086000\n\n\t# PLL init\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x40001580\n\tmww 0xb8050004 0x40015800\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x00001580\n\tmww 0xb8050004 0x00015800\n\tmww 0xb8050008 0x01310000\n\tmww 0xb8050044 0x781003ff\n\tmww 0xb8050048 0x003c103f\n\n\t# DDR2 init\n\tmww 0xb8000108 0x401f0042\n\tmww 0xb80000b8 0x0000166d\n\tmww 0xb8000000 0xcfaaf33b\n\tmww 0xb800015c 0x0000000f\n\tmww 0xb8000004 0xa272efa8\n\tmww 0xb8000018 0x0000ffff\n\tmww 0xb80000c4 0x74444444\n\tmww 0xb80000c8 0x00000444\n\tmww 0xb8000004 0xa210ee28\n\tmww 0xb8000004 0xa2b2e1a8\n\tmww 0xb8000010 0x8\n\tmww 0xb80000bc 0x0\n\tmww 0xb8000010 0x10\n\tmww 0xb80000c0 0x0\n\tmww 0xb8000010 0x40\n\tmww 0xb800000c 0x2\n\tmww 0xb8000010 0x2\n\tmww 0xb8000008 0xb43\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\tmww 0xb8000008 0xa43\n\tmww 0xb8000010 0x1\n\tmww 0xb800000c 0x382\n\tmww 0xb8000010 0x2\n\tmww 0xb800000c 0x402\n\tmww 0xb8000010 0x2\n\tmww 0xb8000014 0x40be\n\tmww 0xb800001C 0x20\n\tmww 0xb8000020 0x20\n\tmww 0xb80000cc 0xfffff\n\n\t# UART GPIO programming\n\tmww 0xb8040000 0xff30b\n\tmww 0xb8040044 0x908\n\tmww 0xb8040034 0x160000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/quark_d20xx.cfg",
    "content": "if { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x38289013\n}\n\njtag newtap quark_d20xx quark -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable\njtag newtap quark_d20xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e786013 -enable\n\nproc quark_d20xx_tapenable {} {\n\techo \"enabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 1\n\truntest 10\n}\n\nproc quark_d20xx_tapdisable {} {\n\techo \"disabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 0\n\truntest 10\n}\n\nproc quark_d20xx_setup {} {\n\tjtag tapenable quark_d20xx.quark\n}\n\njtag configure quark_d20xx.quark -event tap-enable \\\n   \"quark_d20xx_tapenable\"\n\njtag configure quark_d20xx.quark -event tap-disable \\\n   \"quark_d20xx_tapdisable\"\n\ntarget create quark_d20xx.quark quark_d20xx -endian little -chain-position quark_d20xx.quark\n\nquark_d20xx.quark configure -event reset-start {\n\t# need to halt the target to write to memory\n\tif {[quark_d20xx.quark curstate] ne \"halted\"} { halt }\n\t# set resetbreak via the core tap\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x1\n\t# trigger a warm reset\n\tmww 0xb0800570 0x2\n\t# clear resetbreak\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x0\n}\n\njtag configure quark_d20xx.quark -event setup \\\n   \"quark_d20xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/quark_x10xx.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME quark_x10xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x18289013\n}\n\njtag newtap quark_x10xx cpu   -irlen 8  -irmask 0xff  -expected-id   $_CPUTAPID  -disable\njtag newtap quark_x10xx cltap -irlen 8  -irmask 0xff  -expected-id   0x0e681013  -enable\n\n#openocd puts tap at front of chain not end of chain\nproc quark_x10xx_tapenable {} {\n\techo \"enabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 1\n\truntest 10\n}\n\nproc quark_x10xx_tapdisable {} {\n\techo \"disabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 0\n\truntest 10\n}\n\nproc quark_x10xx_setup {} {\n\tjtag tapenable quark_x10xx.cpu\n}\n\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"quark_x10xx_tapenable\"\n\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n   \"quark_x10xx_tapdisable\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create quark_x10xx.cpu quark_x10xx -endian $_ENDIAN -chain-position quark_x10xx.cpu\n\njtag configure $_CHIPNAME.cpu -event setup \\\n   \"quark_x10xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/readme.txt",
    "content": "Prerequisites:\nThe users of OpenOCD as well as computer programs interacting with OpenOCD are expecting that certain commands\ndo the same thing across all the targets.\n\nRules to follow when writing scripts:\n\n1. The configuration script should be defined such as , for example, the following sequences are working:\n\treset\n\tflash info <bank>\nand\n\treset\n\tflash erase_address <start> <len>\nand\n\treset init\n\tload\n\nIn most cases this can be accomplished by specifying the default startup mode as reset_init (target command\nin the configuration file).\n\n2. If the target is correctly configured, flash must be writable without any other helper commands. It is\nassumed that all write-protect mechanisms should be disabled.\n\n3. The configuration scripts should be defined such as the binary that was written to flash verifies\n(turn off remapping, checksums, etc...)\n\nflash write_image [file] <parameters>\nverify_image [file] <parameters>\n\n4. adapter speed sets the maximum speed (or alternatively RCLK). If invoked\nmultiple times only the last setting is used.\n\ninterface/xxx.cfg files are always executed *before* target/xxx.cfg\nfiles, so any adapter speed in interface/xxx.cfg will be overridden by\ntarget/xxx.cfg. adapter speed in interface/xxx.cfg would then, effectively,\nset the default JTAG speed.\n\nNote that a target/xxx.cfg file can invoke another target/yyy.cfg file,\nso one can create target subtype configurations where e.g. only\namount of DRAM, oscillator speeds differ and having a single\nconfig file for the default/common settings.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_r7s72100.cfg",
    "content": "# Renesas RZ/A1H\n# https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME r7s72100\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\n\n# Configuring only one core using DAP.\n# Base addresses of cores:\n#  core 0  -  0x80030000\nset _TARGETNAME $_CHIPNAME.ca9\ndap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME} cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x80030000\n\ntargets ${_TARGETNAME}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_rcar_gen2.cfg",
    "content": "# Renesas R-Car Generation 2 SOCs\n# - There are a combination of Cortex-A15s and Cortex-A7s for each Gen2 SOC\n# - Each SOC can boot through any of the, up to 2, core types that it has\n#   e.g. H2 can boot through Cortex-A15 or Cortex-A7\n\n# Supported Gen2 SOCs and their cores:\n# H2:  Cortex-A15 x 4, Cortex-A7 x 4\n# M2:  Cortex-A15 x 2\n# V2H: Cortex-A15 x 2\n# M2N: Cortex-A15 x 2\n# E2:                  Cortex-A7 x 2\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H2')\n# BOOT_CORE: Selects the booting core. 'CA15', or 'CA7'\n#            Defaults to 'CA15' if the SOC has one, else defaults to 'CA7'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H2\n}\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH2 {\n\t\tset _CHIPNAME r8a7790\n\t\tset _num_ca15 4\n\t\tset _num_ca7 4\n\t\tset _boot_core CA15\n\t}\n\tM2 {\n\t\tset _CHIPNAME r8a7791\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tV2H {\n\t\tset _CHIPNAME r8a7792\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tM2N {\n\t\tset _CHIPNAME r8a7793\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tE2 {\n\t\tset _CHIPNAME r8a7794\n\t\tset _num_ca15 0\n\t\tset _num_ca7 2\n\t\tset _boot_core CA7\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\necho \"\\t$_soc - $_num_ca15 CA15(s), $_num_ca7 CA7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000}\nset CA7_DBGBASE  {0x800F0000 0x800F2000 0x800F4000 0x800F6000}\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_ca {core_name dbgbase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tset _command \"target create $_TARGETNAME cortex_a -dap $_DAPNAME \\\n\t\t\t-coreid $_core -dbgbase [lindex $dbgbase $_core]\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA15] } {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 1\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n} elseif { [string equal $_boot_core CA7] } {\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 1\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n} else {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_rcar_gen3.cfg",
    "content": "# Renesas R-Car Generation 3 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, and Cortex-R7 for each Gen3 SOC\n# - Each SOC can boot through any of the, up to 3, core types that it has\n#   e.g. H3 can boot through Cortex-A57, Cortex-A53, or Cortex-R7\n\n# Supported Gen3 SOCs and their cores:\n#  H3: Cortex-A57 x 4, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3W: Cortex-A57 x 2, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3N: Cortex-A57 x 2,                 Cortex-R7 x 2 (Lock-Step)\n# V3U:                 Cortex-A76 x 8, Cortex-R52 x2 (Lock-Step)\n# V3H:                 Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# V3M:                 Cortex-A53 x 2, Cortex-R7 x 2 (Lock-Step)\n#  E3:                 Cortex-A53 x 1, Cortex-R7 x 2 (Lock-Step)\n#  D3:                 Cortex-A53 x 1\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H3')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53', or 'CR7'\n#            Defaults to 'CA57' if the SOC has one, else defaults to 'CA53'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H3\n}\n\nset _num_ca53 0\nset _num_ca57 0\nset _num_ca76 0\nset _num_cr52 0\nset _num_cr7 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH3 {\n\t\tset _CHIPNAME r8a77950\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3W {\n\t\tset _CHIPNAME r8a77960\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3N {\n\t\tset _CHIPNAME r8a77965\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tV3M {\n\t\tset _CHIPNAME r8a77970\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tV3H {\n\t\tset _CHIPNAME r8a77980\n\t\tset _num_ca57 0\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tE3 {\n\t\tset _CHIPNAME r8a77990\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tD3 {\n\t\tset _CHIPNAME r8a77995\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 0\n\t\tset _boot_core CA53\n\t}\n\tV3U {\n\t\tset _CHIPNAME r8a779a0\n\t\tset _num_ca76 8\n\t\tset _num_cr52 1\n\t\tset _boot_core CA76\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\necho \"\\t$_soc - $_num_ca76 CA76(s), $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr52 CR52(s), $_num_cr7 CR7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA76_DBGBASE {0x81410000 0x81510000 0x81610000 0x81710000 0x81c10000 0x81d10000 0x81e10000 0x81f10000}\nset CA76_CTIBASE {0x81420000 0x81520000 0x81620000 0x81720000 0x81c20000 0x81d20000 0x81e20000 0x81f20000}\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset CR52_DBGBASE 0x80c10000\nset CR52_CTIBASE 0x80c20000\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\tset _command \"target create $_TARGETNAME aarch64 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\nproc setup_cr7 {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase\n\t\tset _command \"target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase $dbgbase\"\n\t\tif { $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA76] } {\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 1\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 0\n} elseif { [string equal $_boot_core CA57] } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CA53] } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CR52] } {\n\tsetup_cr7 r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 1\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 0\n} else {\n\tsetup_cr7 r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_rcar_reset_common.cfg",
    "content": "# Renesas R-Car Gen2 Evaluation Board common settings\n\nreset_config trst_and_srst srst_nogate\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_rz_five.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/Five SoC\n#\n# General-purpose Microprocessors with RISC-V CPU Core (Andes AX45MP Single) (1.0 GHz)\n\ntransport select jtag\n\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME r9A07g043u\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_rz_g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/G2 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, Cortex-A55, Cortex-R7\n# and Cortex-M33 for each SOC\n# - Each SOC can boot through the Cortex-A5x cores\n\n# Supported RZ/G2 SOCs and their cores:\n# RZ/G2H:   Cortex-A57 x4, Cortex-A53 x4, Cortex-R7\n# RZ/G2M:   Cortex-A57 x2, Cortex-A53 x4, Cortex-R7\n# RZ/G2N:   Cortex-A57 x2,                Cortex-R7\n# RZ/G2E:                  Cortex-A53 x2, Cortex-R7\n# RZ/G2L:                  Cortex-A55 x2, Cortex-M33\n# RZ/G2LC:                 Cortex-A55 x2, Cortex-M33\n# RZ/G2UL:                 Cortex-A55 x1, Cortex-M33\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'G2L')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53' or 'CA55'\n\ntransport select jtag\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc G2L\n}\n\nset _num_ca57 0\nset _num_ca55 0\nset _num_ca53 0\nset _num_cr7 0\nset _num_cm33 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tG2H {\n\t\tset _CHIPNAME r8a774ex\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2M {\n\t\tset _CHIPNAME r8a774ax\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2N {\n\t\tset _CHIPNAME r8a774bx\n\t\tset _num_ca57 2\n\t\tset _num_ca53 0\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2E {\n\t\tset _CHIPNAME r8a774c0\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t\tset _ap_num 1\n\t}\n\tG2L {\n\t\tset _CHIPNAME r9a07g044l\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2LC {\n\t\tset _CHIPNAME r9a07g044c\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2UL {\n\t\tset _CHIPNAME r9a07g043u\n\t\tset _num_ca55 1\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\necho \"\\t$_soc - $_num_ca57 CA57(s), $_num_ca55 CA55(s), $_num_ca53 CA53(s), $_num_cr7 CR7(s), \\\n\t$_num_cm33 CM33(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID \\\n\t-ignore-version\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\necho \"$_CHIPNAME.cpu\"\n\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA55_DBGBASE {0x10E10000 0x10F10000}\nset CA55_CTIBASE {0x10E20000 0x10F20000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\nset CM33_DBGBASE 0xE000E000\nset CM33_CTIBASE 0xE0042000\n\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $::_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $::_DAPNAME -ap-num $::_ap_num \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\ttarget create $_TARGETNAME aarch64 -dap $::_DAPNAME \\\n\t\t\t-ap-num $::_ap_num -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\n\t\tif { $_core > 0 || $boot == 0 } {\n\t\t\t$_TARGETNAME configure -defer-examine\n\t\t}\n\t\tset ::smp_targets \"$::smp_targets $_TARGETNAME\"\n\t}\n}\n\nproc setup_cr7 {dbgbase ctibase} {\n\tset _TARGETNAME $::_CHIPNAME.r7\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $::_DAPNAME -ap-num 1 -baseaddr $ctibase\n\ttarget create $_TARGETNAME cortex_r4 -dap $::_DAPNAME \\\n\t\t-ap-num 1 -dbgbase $dbgbase -defer-examine\n}\n\nproc setup_cm33 {dbgbase ctibase} {\n        set _TARGETNAME $::_CHIPNAME.m33\n        set _CTINAME $_TARGETNAME.cti\n        cti create $_CTINAME -dap $::_DAPNAME -ap-num 2 -baseaddr $ctibase\n        target create $_TARGETNAME cortex_m -dap $::_DAPNAME \\\n                -ap-num 2 -dbgbase $dbgbase -defer-examine\n}\n\n# Organize target list based on the boot core\nif { $_boot_core == \"CA57\" } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA53\" } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA55\" } {\n\tsetup_a5x a55 $CA55_DBGBASE $CA55_CTIBASE $_num_ca55 1\n\tsetup_cm33 $CM33_DBGBASE $CM33_CTIBASE\n}\necho \"SMP targets:$smp_targets\"\neval \"target smp $smp_targets\"\n\nif { $_soc == \"G2L\" || $_soc == \"G2LC\" || $_soc == \"G2UL\" } {\n\ttarget create $_CHIPNAME.axi_ap mem_ap -dap $_DAPNAME -ap-num 1\n}\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/renesas_s7g2.cfg",
    "content": "#\n# Renesas Synergy S7 G2 w/ ARM Cortex-M4 @ 240 MHz\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME s7g2\n}\n\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x5ba00477\n}\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x5ba02477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\t# 640 KB On-Chip SRAM\n\tset _WORKAREASIZE 0xa0000\n}\n\n$_TARGETNAME configure -work-area-phys 0x1ffe0000 \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/rk3308.cfg",
    "content": "# Rockchip RK3308 Target\n# https://rockchip.fr/RK3308%20datasheet%20V1.5.pdf\n# https://dl.radxa.com/rockpis/docs/hw/datasheets/Rockchip%20RK3308TRM%20V1.1%20Part1-20180810.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3308\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x2ba01477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.core\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x81010000\nset $_TARGETNAME.base(1) 0x81012000\nset $_TARGETNAME.base(2) 0x81014000\nset $_TARGETNAME.base(3) 0x81016000\n\nset $_TARGETNAME.cti(0) 0x81018000\nset $_TARGETNAME.cti(1) 0x81019000\nset $_TARGETNAME.cti(2) 0x8101a000\nset $_TARGETNAME.cti(3) 0x8101b000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\"\n\n    if { $_core != 0 } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n        set _command \"$_command -defer-examine\"\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # set _command \"$_command -rtos hwthread\"\n        set _command \"$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 \\\n                                -work-area-backup 0\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/rk3399.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Rockchip RK3399 Target\n# https://rockchip.fr/RK3399%20datasheet%20V1.8.pdf\n# https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.4%20Part1.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3399\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba02477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\nset _TARGETNAME $_CHIPNAME.lcore\n# declare the 6 main application cores\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x80030000\nset $_TARGETNAME.base(1) 0x80032000\nset $_TARGETNAME.base(2) 0x80034000\nset $_TARGETNAME.base(3) 0x80036000\nset $_TARGETNAME.cti(0) 0x80038000\nset $_TARGETNAME.cti(1) 0x80039000\nset $_TARGETNAME.cti(2) 0x8003a000\nset $_TARGETNAME.cti(3) 0x8003b000\n\n\nset _TARGETNAME $_CHIPNAME.bcore\nset $_TARGETNAME.base(4) 0x80210000\nset $_TARGETNAME.base(5) 0x80310000\nset $_TARGETNAME.cti(4) 0x80220000\nset $_TARGETNAME.cti(5) 0x80320000\n\nset _cores 6\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n    if {$_core < 4} {\n        set _TARGETNAME $_CHIPNAME.lcore\n    } else {\n        set _TARGETNAME $_CHIPNAME.bcore\n    }\n\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1\n\n    target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\n\n    if { $_core != 0 } {\n        ${_TARGETNAME}$_core configure -defer-examine\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # ${_TARGETNAME}$_core configure -rtos hwthread\"\n        ${_TARGETNAME}$_core configure -work-area-size 0x30000 -work-area-phys 0xff8c0000 \\\n                                -work-area-backup 0\n    }\n    set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n}\n\ntarget smp $_smp_command\n\ntargets rk3399.lcore0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/rp2040-core0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\ntransport select swd\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME rp2040\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x01002927\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nset _FLASHSIZE 0x200000\nset _FLASHBASE 0x10000000\nflash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n\n# srst does not exist; use SYSRESETREQ to perform a soft reset\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/samsung_s3c2410.cfg",
    "content": "# Found on the 'TinCanTools' Hammer board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that cannot set TRST/SRST separately\nreset_config trst_and_srst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x30800000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/samsung_s3c2440.cfg",
    "content": "# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor       : ARM920Tid(wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/samsung_s3c2450.cfg",
    "content": "# Target configuration for the Samsung 2450 system on chip\n# Processor       : ARM926ejs (wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2450.cpu tap/device found: 0x07926F0F\n\n\n# FIX!!! what to use here?\n#\n# RCLK?\n#\n# adapter speed 0\n#\n# Really low clock during reset?\n#\n# adapter speed 1\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME s3c2450\n}\n\nif { [info exists ENDIAN] } {\n  set _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n  set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n  set _CPUTAPID $CPUTAPID\n} else {\n  set _CPUTAPID 0x07926f0f\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xE -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# FIX!!!!! should this really use srst_pulls_trst?\n# With srst_pulls_trst \"reset halt\" will not reset into the\n# halted mode, but rather \"reset run\" and then halt the target.\n#\n# However, without \"srst_pulls_trst\", then \"reset halt\" produces weird\n# errors:\n# WARNING: unknown debug reason: 0x0\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/samsung_s3c4510.cfg",
    "content": "if { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c4510\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# This appears to be a \"Version 1\" arm7tdmi.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/samsung_s3c6410.cfg",
    "content": "# -*- tcl -*-\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n# [Duane Ellis 27/nov/2008: Above 0x0032409d appears to be copy/paste from other places]\n# [and I do not believe it to be accurate, hence the 0xffffffff below]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c6410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b76f0f\n}\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nadapter srst delay 500\njtag_ntrst_delay 500\n\n#reset configuration\nreset_config trst_and_srst\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/sharp_lh79532.cfg",
    "content": "reset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lh79532\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # sharp changed the number!\n   set _CPUTAPID 0x00002061\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/sim3x.cfg",
    "content": "#\n# Silicon Laboratories SiM3x Cortex-M3\n#\n\n# SiM3x devices support both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME SiM3x\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nif { [info exists CPURAMSIZE] } {\n  set _CPURAMSIZE $CPURAMSIZE\n} else {\n# Minimum size of RAM in the Silicon Labs product matrix (8KB)\n\tset _CPURAMSIZE 0x2000\n}\n\nif { [info exists CPUROMSIZE] } {\n  set _CPUROMSIZE $CPUROMSIZE\n} else {\n# Minimum size of FLASH in the Silicon Labs product matrix (32KB)\n\tset _CPUROMSIZE 0x8000\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE $_CPURAMSIZE\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/smp8634.cfg",
    "content": "# script for Sigma Designs SMP8634 (eventually even SMP8635)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME smp8634\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x08630001\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/snps_em_sk_fpga.cfg",
    "content": "#  Copyright (C) 2014-2015,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n#  SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xilinx Spartan-6 XC6SLX45  FPGA on EM Starter Kit v1.\n# Xilinx Spartan-6 XC6SLX150 FPGA on EM Starter Kit v2.\n#\n\nsource [find cpu/arc/em.tcl]\n\nset _CHIPNAME arc-em\nset _TARGETNAME $_CHIPNAME.cpu\n\n# EM SK IDENTITY is 0x200444b1\n# EM SK v2 IDENTITY is 0x200044b1\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -expected-id 0x200444b1 \\\n  -expected-id 0x200044b1\n\nset _coreid 0\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME \\\n  -coreid 0 -dbgbase $_dbgbase -endian little\n\n# There is no SRST, so do a software reset\n$_TARGETNAME configure -event reset-assert \"arc_em_reset $_TARGETNAME\"\n\narc_em_init_regs\n\n# vim:ft=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/snps_hsdk.cfg",
    "content": "#  Copyright (C) 2019,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n#\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# HS Development Kit SoC.\n#\n# Contains quad-core ARC HS38.\n#\n\nsource [find cpu/arc/hs.tcl]\n\nset _coreid 0\nset _dbgbase [expr {$_coreid << 13}]\n\n# CHIPNAME will be used to choose core family (600, 700 or EM). As far as\n# OpenOCD is concerned EM and HS are identical.\nset _CHIPNAME arc-em\n\n# OpenOCD discovers JTAG TAPs in reverse order.\n\n# ARC HS38 core 4\nset _TARGETNAME $_CHIPNAME.cpu4\njtag newtap $_CHIPNAME cpu4 -irlen 4 -ircapture 0x1 -expected-id 0x200c24b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n# Flush L2$.\n$_TARGETNAME configure -event reset-assert \"arc_hs_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 4.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 3\nset _TARGETNAME $_CHIPNAME.cpu3\njtag newtap $_CHIPNAME cpu3 -irlen 4 -ircapture 0x1 -expected-id 0x200824b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 3.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 2\nset _TARGETNAME $_CHIPNAME.cpu2\njtag newtap $_CHIPNAME cpu2 -irlen 4 -ircapture 0x1 -expected-id 0x200424b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 2.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 1\nset _TARGETNAME $_CHIPNAME.cpu1\njtag newtap $_CHIPNAME cpu1 -irlen 4 -ircapture 0x1 -expected-id 0x200024b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\narc_hs_init_regs\n\n# Enable L2 cache support for core 1.\n$_TARGETNAME arc cache l2 auto 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/spear3xx.cfg",
    "content": "# Target configuration for the ST SPEAr3xx family of system on chip\n# Supported SPEAr300, SPEAr310, SPEAr320\n# http://www.st.com/spear\n#\n# Processor: ARM926ejs\n# Info:      JTAG tap: spear3xx.cpu tap/device found: 0x07926041\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME spear3xx\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x07926041\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 \\\n\t-expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# SPEAr3xx has a 8K block of sram @ 0xd280.0000\n# REVISIT: what OS puts virtual address equal to phys?\n$_TARGETNAME configure \\\n\t-work-area-virt 0xd2800000 \\\n\t-work-area-phys 0xd2800000 \\\n\t-work-area-size 0x2000 \\\n\t-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stellaris.cfg",
    "content": "# TI/Luminary Stellaris LM3S chip family\n\n# Some devices have errata in returning their device class.\n# DEVICECLASS is provided as a manual override\n# Manual setting of a device class of 0xff is not allowed\n\nglobal _DEVICECLASS\n\nif { [info exists DEVICECLASS] } {\n   set _DEVICECLASS $DEVICECLASS\n} else {\n   set _DEVICECLASS 0xff\n}\n\n# Luminary chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# For now we ignore the SPI and UART options, which\n# are usable only for ISP style initial flash programming.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lm3s\n}\n\n# CPU TAP ID 0x1ba00477 for early Sandstorm parts\n# CPU TAP ID 0x2ba00477 for later SandStorm parts, e.g. lm3s811 Rev C2\n# CPU TAP ID 0x3ba00477 for Cortex-M3 r1p2 (on Fury, DustDevil)\n# CPU TAP ID 0x4ba00477 for Cortex-M3 r2p0 (on Tempest, Firestorm)\n# CPU TAP ID 0x4ba00477 for Cortex-M4 r0p1 (on Blizzard)\n# ... we'll ignore the JTAG version field, rather than list every\n# chip revision that turns up.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0ba00477\n}\n\n# SWD DAP, and JTAG TAP, take same params for now;\n# ... even though SWD ignores all except TAPID, and\n# JTAG shouldn't need anything more then irlen. (and TAPID).\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf \\\n    -expected-id $_CPUTAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   # default to 2K working area\n   set _WORKAREASIZE 0x800\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# 8K working area at base of ram, not backed up\n#\n# NOTE: you may need or want to reconfigure the work area;\n# some parts have just 6K, and you may want to use other\n# addresses (at end of mem not beginning) or back it up.\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\n# JTAG speed ... slow enough to work with a 12 MHz RC oscillator;\n# LM3S parts don't support RTCK\n#\n# NOTE: this may be increased by a reset-init handler, after it\n# configures and enables the PLL.  Or you might need to decrease\n# this, if you're using a slower clock.\nadapter speed 500\n\nsource [find mem_helper.tcl]\n\nproc reset_peripherals {family} {\n\n\tsource [find chip/ti/lm3s/lm3s.tcl]\n\n\techo \"Resetting Core Peripherals\"\n\n\t# Disable the PLL and the system clock divider (nop if disabled)\n\tmmw $SYSCTL_RCC 0 $SYSCTL_RCC_USESYSDIV\n\tmmw $SYSCTL_RCC2 $SYSCTL_RCC2_BYPASS2 0\n\n\t# RCC and RCC2 to their reset values\n\tmww $SYSCTL_RCC [expr {0x078e3ad0 | ([mrw $SYSCTL_RCC] & $SYSCTL_RCC_MOSCDIS)}]\n\tmww $SYSCTL_RCC2 0x07806810\n\tmww $SYSCTL_RCC 0x078e3ad1\n\n\t# Reset the deep sleep clock configuration register\n\tmww $SYSCTL_DSLPCLKCFG 0x07800000\n\n\t# Reset the clock gating registers\n\tmww $SYSCTL_RCGC0 0x00000040\n\tmww $SYSCTL_RCGC1 0\n\tmww $SYSCTL_RCGC2 0\n\tmww $SYSCTL_SCGC0 0x00000040\n\tmww $SYSCTL_SCGC1 0\n\tmww $SYSCTL_SCGC2 0\n\tmww $SYSCTL_DCGC0 0x00000040\n\tmww $SYSCTL_DCGC1 0\n\tmww $SYSCTL_DCGC2 0\n\n\t# Reset the remaining SysCtl registers\n\tmww $SYSCTL_PBORCTL 0\n\tmww $SYSCTL_IMC 0\n\tmww $SYSCTL_GPIOHBCTL 0\n\tmww $SYSCTL_MOSCCTL 0\n\tmww $SYSCTL_PIOSCCAL 0\n\tmww $SYSCTL_I2SMCLKCFG 0\n\n\t# Reset the peripherals\n\tmww $SYSCTL_SRCR0 0xffffffff\n\tmww $SYSCTL_SRCR1 0xffffffff\n\tmww $SYSCTL_SRCR2 0xffffffff\n\tmww $SYSCTL_SRCR0 0\n\tmww $SYSCTL_SRCR1 0\n\tmww $SYSCTL_SRCR2 0\n\n\t# Clear any pending SysCtl interrupts\n\tmww $SYSCTL_MISC 0xffffffff\n\n\t# Wait for any pending flash operations to complete\n\twhile {[expr {[mrw $FLASH_FMC] & 0xffff}] != 0} { sleep 1 }\n\twhile {[expr {[mrw $FLASH_FMC2] & 0xffff}] != 0} { sleep 1 }\n\n\t# Reset the flash controller registers\n\tmww $FLASH_FMA 0\n\tmww $FLASH_FCIM 0\n\tmww $FLASH_FCMISC 0xffffffff\n\tmww $FLASH_FWBVAL 0\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 500\n\n\t#\n\t# When nRST is asserted on most Stellaris devices, it clears some of\n\t# the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;\n\t# and OpenOCD depends on those TRMs.  So we won't use SRST on those\n\t# chips.  (Only power-on reset should affect debug state, beyond a\n\t# few specified bits; not the chip's nRST input, wired to SRST.)\n\t#\n\t# REVISIT current errata specs don't seem to cover this issue.\n\t# Do we have more details than this email?\n\t#   https://lists.berlios.de/pipermail\n\t#\t/openocd-development/2008-August/003065.html\n\t#\n\n\tglobal _DEVICECLASS\n\n\tif {$_DEVICECLASS != 0xff} {\n\t   set device_class $_DEVICECLASS\n\t} else {\n\t   set device_class [expr {([mrw 0x400fe000] >> 16) & 0xff}]\n\t}\n\n\tif {$device_class == 0 || $device_class == 1 ||\n\t\t$device_class == 3 || $device_class == 5 || $device_class == 0xa} {\n\t\tif {![using_hla]} {\n\t\t   # Sandstorm, Fury, DustDevil, Blizzard and Snowflake are able to use NVIC SYSRESETREQ\n\t\t   cortex_m reset_config sysresetreq\n\t\t}\n\t} else {\n\t\tif {![using_hla]} {\n\t\t   # Tempest and Firestorm default to using NVIC VECTRESET\n\t\t   # peripherals will need resetting manually, see proc reset_peripherals\n\t\t   cortex_m reset_config vectreset\n\t\t}\n\t\t# reset peripherals, based on code in\n\t\t# http://www.ti.com/lit/er/spmz573a/spmz573a.pdf\n\t\treset_peripherals $device_class\n\t}\n}\n\n# flash configuration ... autodetects sizes, autoprobed\nflash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f0x.cfg",
    "content": "# script for stm32f0x family\n\n#\n# stm32 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n\tset _FLASH_SIZE $FLASH_SIZE\n} else {\n\t# autodetect size\n\tset _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # See STM Document RM0091\n  # Section 29.5.3\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f0x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f0x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\n\t# Stop watchdog counters during halt\n\tmmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f0x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 6 (48 MHz)\n\tmww 0x40021004 0x00100000   ;# RCC_CFGR = PLLMUL[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON\n\tmww 0x40022000 0x00000011   ;# FLASH_ACR = PRFTBE | LATENCY[0]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f1x.cfg",
    "content": "# script for stm32f1x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f1x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some STM32F100s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0008 Section 26.6.3\n      set _CPUTAPID 0x3ba00477\n   } {\n      # this is the SW-DP tap id not the jtag tap id\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |\n\t#              DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000307 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f2x.cfg",
    "content": "# script for stm32f2x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f2x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0033\n      # Section 32.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f3x.cfg",
    "content": "# script for stm32f3x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f3x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0316\n      # Section 29.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f3x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f3x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\n\t# Stop watchdog counters during halt\n\tmmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f3x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 8 (64 MHz)\n\tmww 0x40021004 0x00380400   ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON\n\tmww 0x40022000 0x00000012   ;# FLASH_ACR = PRFTBE | LATENCY[1]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init }\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xe0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f4x.cfg",
    "content": "# script for stm32f4x family\n\n#\n# stm32f4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (Available RAM in smallest device STM32F410)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0090\n      # Section 38.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x40021000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x40021008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x40021000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x40021008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x40021000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x40021008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure PLL to boost clock to HSI x 4 (64 MHz)\n\tmww 0x40023804 0x08012008   ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P)\n\tmww 0x40023C00 0x00000102   ;# FLASH_ACR = PRFTBE | 2(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32f7x.cfg",
    "content": "# script for stm32f7x family\n\n#\n# stm32f7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f7x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 128kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x20000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0385\n      # Section 40.6.3 - corresponds to Cortex-M7 with FPU r0p0\n      set _CPUTAPID 0x5ba00477\n   } {\n      set _CPUTAPID 0x5ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1ff0f000 0 0 0 $_TARGETNAME\n\n# On the STM32F7, the Flash is mapped at address 0x08000000 via the AXI and\n# also address 0x00200000 via the ITCM. The former mapping is read-write in\n# hardware, while the latter is read-only. By presenting an alias, we\n# accomplish two things:\n# (1) We allow writing at 0x00200000 (because the alias acts identically to the\n#     original bank), which allows code intended to run from that address to\n#     also be linked for loading at that address, simplifying linking.\n# (2) We allow the proper memory map to be delivered to GDB, which will cause\n#     it to use hardware breakpoints at the 0x00200000 mapping (correctly\n#     identifying it as Flash), which it would otherwise not do. Configuring\n#     the Flash via ITCM alias as virtual\nflash bank $_CHIPNAME.itcm-flash.alias virtual 0x00200000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# Use hardware reset.\n#\n# This target is compatible with connect_assert_srst, which may be set in a\n# board file.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# If the HSE was previously enabled and the external clock source\n\t# disappeared, RCC_CR.HSERDY can get stuck at 1 and the PLL cannot be\n\t# properly switched back to HSI. This situation persists even over a system\n\t# reset, including a pin reset via SRST. However, activating the clock\n\t# security system will detect the problem and clear HSERDY to 0, which in\n\t# turn allows the PLL to switch back to HSI properly. Since we just came\n\t# out of reset, HSEON should be 0. If HSERDY is 1, then this situation must\n\t# have happened; in that case, activate the clock security system to clear\n\t# HSERDY.\n\tif {[mrw 0x40023800] & 0x00020000} {\n\t\tmmw 0x40023800 0x00090000 0 ;# RCC_CR = CSSON | HSEON\n\t\tsleep 10                    ;# Wait for CSS to fire, if it wants to\n\t\tmmw 0x40023800 0 0x00090000 ;# RCC_CR &= ~CSSON & ~HSEON\n\t\tmww 0x4002380C 0x00800000   ;# RCC_CIR = CSSC\n\t\tsleep 1                     ;# Wait for CSSF to clear\n\t}\n\n\t# If the clock security system fired, it will pend an NMI. A pending NMI\n\t# will cause a bad time for any subsequent executing code, such as a\n\t# programming algorithm.\n\tif {[mrw 0xE000ED04] & 0x80000000} {\n\t\t# ICSR.NMIPENDSET reads as 1. Need to clear it. A pending NMI can’t be\n\t\t# cleared by any normal means (such as ICSR or NVIC). It can only be\n\t\t# cleared by entering the NMI handler or by resetting the processor.\n\t\techo \"[target current]: Clock security system generated NMI. Clearing.\"\n\n\t\t# Keep the old DEMCR value.\n\t\tset old [mrw 0xE000EDFC]\n\n\t\t# Enable vector catch on reset.\n\t\tmww 0xE000EDFC 0x01000001\n\n\t\t# Issue local reset via AIRCR.\n\t\tmww 0xE000ED0C 0x05FA0001\n\n\t\t# Restore old DEMCR value.\n\t\tmww 0xE000EDFC $old\n\t}\n\n\t# Configure PLL to boost clock to HSI x 10 (160 MHz)\n\tmww 0x40023804 0x08002808   ;# RCC_PLLCFGR 16 Mhz /10 (M) * 128 (N) /2(P)\n\tmww 0x40023C00 0x00000107   ;# FLASH_ACR = PRFTBE | 7(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmww 0x40023808 0x00009400   ;# RCC_CFGR_PPRE1 = 5(div 4), PPRE2 = 4(div 2)\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost SWD frequency\n\t# Do not boost JTAG frequency and slow down JTAG memory access or flash write algo\n\t# suffers from DAP WAITs\n\tif {[using_jtag]} {\n\t\t[[target current] cget -dap] memaccess 16\n\t} {\n\t\tadapter speed 8000\n\t}\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32g0x.cfg",
    "content": "# script for stm32g0x family\n\n#\n# stm32g0 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x1000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# Section 37.5.5 - corresponds to Cortex-M0+\n\tset _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32g0x_default_reset_start {} {\n\t# Reset clock is HSI16 (16 MHz)\n\tadapter speed 2000\n}\n\nproc stm32g0x_default_examine_end {} {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0x40015804 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n\nproc stm32g0x_default_reset_init {} {\n\t# Increase clock to 64 Mhz\n\tmmw 0x40022000 0x00000002 0x00000005\t;# FLASH_ACR: Latency = 2\n\tmww 0x4002100C 0x30000802\t\t\t\t;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2\n\tmmw 0x40021000 0x01000000 0x00000000\t;# RCC_CR |= PLLON\n\tmmw 0x40021008 0x00000002 0x00000005\t;# RCC_CFGR: SW=PLLRCLK\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32g4x.cfg",
    "content": "# script for stm32g4x family\n\n#\n# stm32g4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest current target has 32kB ram, use 16kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# See STM Document RM0440\n\t\t# Section 46.6.3 - corresponds to Cortex-M4 r0p1\n\t\tset _CPUTAPID 0x4ba00477\n\t} {\n\t\tset _CPUTAPID 0x2ba01477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n\tset a [llength [flash list]]\n\tset _QSPINAME $_CHIPNAME.qspi\n\tflash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with HSION | HSIRDY.\n\t# Use HSI 16 MHz clock, compliant even with VOS == 2.\n\t# 1 WS compliant with VOS == 2 and 16 MHz.\n\tmmw 0x40022000 0x00000001 0x0000000E\t;# FLASH_ACR: Latency = 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# RCC_CR |= HSION\n\tmmw 0x40021008 0x00000001 0x00000002\t;# RCC_CFGR: SW=HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is HSI (16 MHz)\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32h7x.cfg",
    "content": "# script for stm32h7x family\n\n#\n# stm32h7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32h7x\n}\n\nif { [info exists DUAL_BANK] } {\n\tset $_CHIPNAME.DUAL_BANK $DUAL_BANK\n\tunset DUAL_BANK\n} else {\n\tset $_CHIPNAME.DUAL_BANK 0\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists USE_CTI] } {\n\tset $_CHIPNAME.USE_CTI $USE_CTI\n\tunset USE_CTI\n} else {\n\tset $_CHIPNAME.USE_CTI 0\n}\n\n# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0\nif { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } {\n\techo \"Warning : could not use CTI with a single core device, CTI is disabled\"\n\tset $_CHIPNAME.USE_CTI 0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n\t  set _CPUTAPID 0x6ba00477\n   } {\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nif {![using_hla]} {\n\t# STM32H7 provides an APB-AP at access port 2, which allows the access to\n\t# the debug and trace features on the system APB System Debug Bus (APB-D).\n\ttarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\n\tswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00E3000\n\ttpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00F5000\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0\n\n$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0\n\nif {[set $_CHIPNAME.DUAL_BANK]} {\n\tflash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3\n\n\t$_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {[set $_CHIPNAME.DUAL_BANK]} {\n\t\tflash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1\n\t}\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_CHIPNAME.cpu0 0x5200A000\n   }\n}\n\n# Clock after reset is HSI at 64 MHz, no need of PLL\nadapter speed 1800\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# use hardware reset\n#\n# The STM32H7 does not support connect_assert_srst mode because the AXI is\n# unavailable while SRST is asserted, and that is used to access the DBGMCU\n# component at 0x5C001000 in the examine-end event handler.\n#\n# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead\n# of the default AP0, and that works with SRST asserted; however, nonzero AP\n# usage does not work with HLA, so is not done by default. That change could be\n# made in a local configuration file if connect_assert_srst mode is needed for\n# a specific application and a non-HLA adapter is in use.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n\n\tif {[set $_CHIPNAME.DUAL_CORE]} {\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable D3 and D1 DBG clocks\n\t# DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00600000 0\n\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D1 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000007 0\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D2 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000038 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB3FZ1 |= WWDG1\n\tstm32h7x_dbgmcu_mmw 0x034 0x00000040 0\n\t# DBGMCU_APB1LFZ1 |= WWDG2\n\tstm32h7x_dbgmcu_mmw 0x03C 0x00000800 0\n\t# DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2\n\tstm32h7x_dbgmcu_mmw 0x054 0x000C0000 0\n\n\t# Enable clock for tracing\n\t# DBGMCU_CR |= TRACECLKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00100000 0\n\n\t# RM0399 (id 0x450) M7+M4 with SWO Funnel\n\t# RM0433 (id 0x450) M7 with SWO Funnel\n\t# RM0455 (id 0x480) M7 without SWO Funnel\n\t# RM0468 (id 0x483) M7 without SWO Funnel\n\t# Enable CM7 and CM4 slave ports in SWO trace Funnel\n\t# Works ok also on devices single core and without SWO funnel\n\t# Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF\n\t# SWTF_CTRL |= ENS0 | ENS1\n\tstm32h7x_dbgmcu_mmw 0x3000 0x00000003 0\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# Clock after reset is HSI at 64 MHz, no need of PLL\n\tadapter speed 4000\n}\n\n# get _CHIPNAME from current target\nproc stm32h7x_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\t$_CHIPNAME.cpu1 configure -event examine-end {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tglobal $_CHIPNAME.USE_CTI\n\n\t\t# Stop watchdog counters during halt\n\t\t# DBGMCU_APB3FZ2 |= WWDG1\n\t\tstm32h7x_dbgmcu_mmw 0x038 0x00000040 0\n\t\t# DBGMCU_APB1LFZ2 |= WWDG2\n\t\tstm32h7x_dbgmcu_mmw 0x040 0x00000800 0\n\t\t# DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2\n\t\tstm32h7x_dbgmcu_mmw 0x058 0x000C0000 0\n\n\t\tif {[set $_CHIPNAME.USE_CTI]} {\n\t\t\tstm32h7x_cti_start\n\t\t}\n\t}\n}\n\n# like mrw, but with target selection\nproc stm32h7x_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32h7x_mmw {used_target reg setbits clearbits} {\n\tset old [stm32h7x_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base\n# this procedure will use the mem_ap on AP2 whenever possible\nproc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {\n\t# use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address\n\tif {![using_hla]} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tset used_target $_CHIPNAME.ap2\n\t\tset reg_addr [expr {0xE00E1000 + $reg_offset}]\n\t} {\n\t\tset used_target [target current]\n\t\tset reg_addr [expr {0x5C001000 + $reg_offset}]\n\t}\n\n\tstm32h7x_mmw $used_target $reg_addr $setbits $clearbits\n}\n\nif {[set $_CHIPNAME.USE_CTI]} {\n\t# create CTI instances for both cores\n\tcti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0043000\n\tcti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -baseaddr 0xE0043000\n\n\t$_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\n\t$_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\n\tproc stm32h7x_cti_start {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Configure Cores' CTIs to halt each other\n\t\t# TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0\n\t\t$_CHIPNAME.cti0 write INEN0 0x1\n\t\t$_CHIPNAME.cti0 write OUTEN0 0x1\n\t\t$_CHIPNAME.cti1 write INEN0 0x1\n\t\t$_CHIPNAME.cti1 write OUTEN0 0x1\n\n\t\t# enable CTIs\n\t\t$_CHIPNAME.cti0 enable on\n\t\t$_CHIPNAME.cti1 enable on\n\t}\n\n\tproc stm32h7x_cti_stop {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t$_CHIPNAME.cti0 enable off\n\t\t$_CHIPNAME.cti1 enable off\n\t}\n\n\tproc stm32h7x_cti_prepare_restart_all {} {\n\t\tstm32h7x_cti_prepare_restart cti0\n\t\tstm32h7x_cti_prepare_restart cti1\n\t}\n\n\tproc stm32h7x_cti_prepare_restart {cti} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Acknowlodge EDBGRQ at TRIGOUT0\n\t\t$_CHIPNAME.$cti write INACK 0x01\n\t\t$_CHIPNAME.$cti write INACK 0x00\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32h7x_dual_bank.cfg",
    "content": "# script for stm32h7x family (dual flash bank)\n\n# STM32H7xxxI 2Mo have a dual bank flash.\nset DUAL_BANK 1\n\nsource [find target/stm32h7x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l0.cfg",
    "content": "#\n# M0+ devices only have SW-DP, but swj-dp code works, just don't\n# set any jtag related features\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB (max ram on smallest part)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    # Arm, m0+, non-multidrop.\n    # http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16088.html\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l0_enable_HSI16 {} {\n\t# Enable HSI16 as clock source\n\techo \"STM32L0: Enabling HSI16\"\n\n\t# Set HSI16ON in RCC_CR (leave MSI enabled)\n    mmw 0x40021000 0x00000101 0\n\n\t# Set HSI16 as SYSCLK (RCC_CFGR)\n\tmmw 0x4002100c 0x00000001 0\n\n\t# Wait until System clock switches to HSI16\n\twhile { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { }\n\n\t# Increase speed\n\tadapter speed 2500\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l0_enable_HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0x40015804 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l0_dual_bank.cfg",
    "content": "source [find target/stm32l0.cfg]\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l1.cfg",
    "content": "#\n# stm32l1 devices support both JTAG and SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 10kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0038\n      # Section 30.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l_enable_HSI {} {\n\t# Enable HSI as clock source\n\techo \"STM32L: Enabling HSI\"\n\n\t# Set HSION in RCC_CR\n\tmmw 0x40023800 0x00000101 0\n\n\t# Set HSI as SYSCLK\n\tmmw 0x40023808 0x00000001 0\n\n\t# Increase JTAG speed\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l_enable_HSI\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l1x_dual_bank.cfg",
    "content": "source [find target/stm32l1.cfg]\n\n# The stm32l1x 384kb have a dual bank flash.\n# Let's add a definition for the second bank here.\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l4x.cfg",
    "content": "# script for stm32l4x family\n\n#\n# stm32l4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 40kB (Available RAM in smallest device STM32L412)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0xa000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0351\n      # Section 44.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_TARGETNAME 0xA0001400\n   }\n}\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\nproc proc_post_enable {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x48001000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x48001008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x48001000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x48001008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x48001000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x48001008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event post-enable \"proc_post_enable $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 6 (4 MHz).\n\t# Use MSI 24 MHz clock, compliant even with VOS == 2.\n\t# 3 WS compliant with VOS == 2 and 24 MHz.\n\tmww 0x40022000 0x00000103   ;# FLASH_ACR = PRFTBE | 3(Latency)\n\tmww 0x40021000 0x00000099   ;# RCC_CR = MSI_ON | MSIRGSEL | MSI Range 9\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32l5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32l5x family\n# stm32l5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32l5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32l5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is MSI (4MHz) after reset, set MCU freq at 110 MHz with PLL\n\t# RCC_APB1ENR1 = PWREN\n\tmww [expr {0x40021058 + $offset}] 0x10000000\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x40021058 + $offset}]\n\t# PWR_CR1 : VOS Range 0\n\tmww [expr {0x40007000 + $offset}] 0\n\t# while (PWR_SR2 & VOSF)\n\twhile {([mrw [expr {0x40007014 + $offset}]] & 0x0400)} {}\n\t# FLASH_ACR : 5 WS for 110 MHz HCLK\n\tmww 0x40022000 0x00000005\n\t# RCC_PLLCFGR = PLLP=PLLQ=0, PLLR=00=2, PLLREN=1, PLLN=55, PLLM=0000=1, PLLSRC=MSI 4MHz\n\t# fVCO = 4 x 55 /1 = 220\n\t# SYSCLOCK = fVCO/PLLR = 220/2 = 110 MHz\n\tmww [expr {0x4002100C + $offset}] 0x01003711\n\t# RCC_CR |= PLLON\n\tmmw [expr {0x40021000 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLLRDY)\n\twhile {!([mrw [expr {0x40021000 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR |= SW_PLL\n\tmmw [expr {0x40021008 + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR & SWS) != PLL)\n\twhile {([mrw [expr {0x40021008 + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32mp13x.cfg",
    "content": "# STMicroelectronics STM32MP13x (Single Cortex-A7)\n# http://www.st.com/stm32mp1\n\n# HLA does not support custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp13x_dk.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp13x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06501041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\n\n$_CHIPNAME.cpu cortex_a maskisr on\n$_CHIPNAME.cpu cortex_a dacrfixup on\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# srst resets the debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# keep clock enabled in low-power\n\t## catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000004}\n\t# freeze watchdog 1 and 2 on core halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\n# FIXME: most of handlers below will be removed once reset framework get merged\n$_CHIPNAME.ap1 configure -event reset-deassert-pre {\n\tadapter deassert srst deassert trst\n\tcatch {dap init}\n\tcatch {$::_CHIPNAME.dap apid 1}\n}\n$_CHIPNAME.cpu configure -event reset-deassert-pre  {$::_CHIPNAME.cpu arp_examine}\n$_CHIPNAME.cpu configure -event reset-deassert-post {toggle_cpu_dbg_claim0; dbgmcu_enable_debug}\n$_CHIPNAME.ap1 configure -event examine-start       {dap init}\n$_CHIPNAME.ap1 configure -event examine-end         {dbgmcu_enable_debug}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32mp15x.cfg",
    "content": "# STMicroelectronics STM32MP15x (Single/Dual Cortex-A7 plus Cortex-M4)\n# http://www.st.com/stm32mp1\n\n# HLA does not support multi-cores nor custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp15x_dk2.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp15x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06500041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# FIXME: Cortex-M code requires target accessible during reset, but this is not possible in STM32MP1\n# so defer-examine it until the reset framework get merged\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\ntarget create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 1 -dbgbase 0xE00D2000\ntarget create $_CHIPNAME.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\ntargets $_CHIPNAME.cpu0\n\ntarget smp $_CHIPNAME.cpu0 $_CHIPNAME.cpu1\n$_CHIPNAME.cpu0 cortex_a maskisr on\n$_CHIPNAME.cpu1 cortex_a maskisr on\n$_CHIPNAME.cpu0 cortex_a dacrfixup on\n$_CHIPNAME.cpu1 cortex_a dacrfixup on\n\ncti create $_CHIPNAME.cti.sys  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0094000\ncti create $_CHIPNAME.cti.cpu0 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D8000\ncti create $_CHIPNAME.cti.cpu1 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D9000\ncti create $_CHIPNAME.cti.cm4  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE0043000\n\nswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0083000\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0093000\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# Errata \"2.3.5 Incorrect reset of glitch-free kernel clock switch\" requires\n# srst to force VDDCORE power cycle or pull srst_core. Both cases reset the\n# debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# set debug enable bits in DBGMCU_CR to get ap2 and cm4 visible\n\tcatch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000007}\n\t# freeze watchdog 1 and 2 on cores halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu0_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\nproc detect_cpu1 {} {\n\tset cpu1_prsr [$::_CHIPNAME.ap1 read_memory 0xE00D2314 32 1]\n\tset dual_core [expr {$cpu1_prsr & 1}]\n\tif {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine}\n}\n\nproc rcc_enable_traceclk {} {\n\t$::_CHIPNAME.ap2 mww 0x5000080c 0x301\n}\n\n# FIXME: most of handler below will be removed once reset framework get merged\n$_CHIPNAME.ap1  configure -event reset-deassert-pre  {adapter deassert srst deassert trst;catch {dap init};catch {$::_CHIPNAME.dap apid 1}}\n$_CHIPNAME.ap2  configure -event reset-deassert-pre  {dbgmcu_enable_debug;rcc_enable_traceclk}\n$_CHIPNAME.cpu0 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu0 arp_examine}\n$_CHIPNAME.cpu1 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu1 arp_examine allow-defer}\n$_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0}\n$_CHIPNAME.cm4  configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == \"halted\"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}}\n$_CHIPNAME.ap1  configure -event examine-start       {dap init}\n$_CHIPNAME.ap2  configure -event examine-start       {dbgmcu_enable_debug}\n$_CHIPNAME.cpu0 configure -event examine-end         {detect_cpu1}\n$_CHIPNAME.ap2  configure -event examine-end         {rcc_enable_traceclk;$::_CHIPNAME.cm4 arp_examine}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32u5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32u5x family\n# stm32u5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32u5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32u5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is at MSI 4MHz after reset, set MCU freq at 160 MHz with PLL\n\n\t# Enable voltage range 1 for frequency above 100 Mhz\n\t# RCC_AHB3ENR = PWREN\n\tmww [expr {0x46020C94 + $offset}] 0x00000004\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x46020C94 + $offset}]\n\t# PWR_VOSR : VOS Range 1\n\tmmw [expr {0x4602080C + $offset}] 0x00030000 0\n\t# while !(PWR_VOSR & VOSRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00008000)} {}\n\t# FLASH_ACR : 4 WS for 160 MHz HCLK\n\tmww [expr {0x40022000 + $offset}] 0x00000004\n\t# RCC_PLL1CFGR => PLL1MBOOST=0, PLL1M=0=/1, PLL1FRACEN=0, PLL1SRC=MSI 4MHz\n\t#                 PLL1REN=1, PLL1RGE => VCOInputRange=PLLInputRange_4_8\n\tmww [expr {0x46020C28 + $offset}] 0x00040009\n\t# Enable EPOD Booster\n\tmmw [expr {0x4602080C + $offset}] 0x00040000 0\n\t# while !(PWR_VOSR & BOOSTRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00004000)} {}\n\t# RCC_PLL1DIVR => PLL1P=PLL1Q=PLL1R=000001=/2, PLL1N=0x4F=80\n\t# fVCO = 4 x 80 /1 = 320\n\t# SYSCLOCK = fVCO/PLL1R = 320/2 = 160 MHz\n\tmww [expr {0x46020C34 + $offset}] 0x0101024F\n\t# RCC_CR |= PLL1ON\n\tmmw [expr {0x46020C00 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLL1RDY)\n\twhile {!([mrw [expr {0x46020C00 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR1 |= SW_PLL\n\tmmw [expr {0x46020C1C + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR1 & SWS) != PLL)\n\twhile {([mrw [expr {0x46020C1C + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32u5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32w108xx.cfg",
    "content": "#\n# Target configuration for the ST STM32W108xx chips\n#\n# Processor: ARM Cortex-M3\n# Date:      2013-06-09\n# Author:    Giuseppe Barba <giuseppe.barba@gmail.com>\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] == 0 } {\n   set _CHIPNAME stm32w108\n} else {\n   set _CHIPNAME $CHIPNAME\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } {\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nset _ENDIAN little\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n if { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf -expected-id _BSTAPID\n } else {\n   set _BSTAPID_1 0x169a862b\n   set _BSTAPID_2 0x269a862b\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf \\\n\t\t-expected-id $_BSTAPID_1 -expected-id $_BSTAPID_2\n }\n}\n#\n# Set Target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\n# Use the flash driver from the EM357\nset _FLASHNAME $_CHIPNAME.flash\n\n# 64k (0x10000) of flash\nflash bank $_FLASHNAME em357 0x08000000 0x10000 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32wbx.cfg",
    "content": "# script for stm32wbx family\n\n#\n# stm32wb devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32wbx\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x6ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n    # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n    # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n    # 2 WS compliant with VOS=Range1 and 24 MHz.\n    mmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTBE | 2(Latency)\n    mmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n    # Boost JTAG frequency\n    adapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n    # Reset clock is MSI (4 MHz)\n    adapter speed 500\n}\n\n$_TARGETNAME configure -event examine-end {\n    # Enable debug during low power modes (uses more power)\n    # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n    mmw 0xE0042004 0x00000007 0\n\n    # Stop watchdog counters during halt\n    # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n    mmw 0xE004203C 0x00001800 0\n}\n\n$_TARGETNAME configure -event trace-config {\n    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n    # change this value accordingly to configure trace pins\n    # assignment\n    mmw 0xE0042004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32wlx.cfg",
    "content": "# script for stm32wlx family\n\n#\n# stm32wl devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32wlx\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists WKUP_CM0P] } {\n\tset $_CHIPNAME.WKUP_CM0P $WKUP_CM0P\n\tunset WKUP_CM0P\n} else {\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# setup the Work-area start address and size\n# Work-area is a space in RAM used for flash programming\n\n# Memory map for known devices:\n# STM32WL   x5JC   x5JB   x5J8\n#   FLASH   256    128    64\n#   SRAM1   32     16     0\n#   SRAM2   32     32     20\n\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n# Use SRAM2 as work area (some devices do not have SRAM1):\nset WORKAREASTART_CM4   0x20008000\nset WORKAREASTART_CM0P  [expr {$WORKAREASTART_CM4 + $_WORKAREASIZE}]\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0\nflash bank $_CHIPNAME.otp.cpu0   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n\t# Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n\t# 2 WS compliant with VOS=Range1 and 24 MHz.\n\tmmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTEN | 2(Latency)\n\tmmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_CHIPNAME.cpu0 configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE004203C 0x00001800 0\n\n\tset _CHIPNAME [stm32wlx_get_chipname]\n\tglobal $_CHIPNAME.WKUP_CM0P\n\n\tif {[set $_CHIPNAME.WKUP_CM0P]} {\n\t\tstm32wlx_wkup_cm0p\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event trace-config {\n\t# nothing to do\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1\n\n\t$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0P -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\tflash bank $_CHIPNAME.otp.cpu1   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {![using_hla]} {\n\t\t# if srst is not fitted use SYSRESETREQ to\n\t\t# perform a soft reset\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n\tproc stm32wlx_wkup_cm0p {} {\n\t\tset _CHIPNAME [stm32wlx_get_chipname]\n\n\t\t# enable CPU2 boot after reset and after wakeup from Stop or Standby mode\n\t\t# PWR_CR4 |= C2BOOT\n\t\tstm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0\n\t}\n}\n\n# get _CHIPNAME from current target\nproc stm32wlx_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\n# like mrw, but with target selection\nproc stm32wlx_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32wlx_mmw {used_target reg setbits clearbits} {\n\tset old [stm32wlx_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32x5x_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common script for stm32l5x and stm32u5x families\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# STM32L5x: RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers\n\t\t# STM32U5x: RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers\n\t\t# Corresponds to Cortex®-M33 JTAG debug port ID code\n\t\tset _CPUTAPID 0x0ba04477\n\t} {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x0be12477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n# use non-secure RAM by default\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# create sec/ns flash and otp memories (sizes will be probed)\nflash bank $_CHIPNAME.flash_ns      stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp           stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME\n\n# Common knowledge tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://review.openocd.org/3366\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32x5x_is_secure {} {\n\t# read Debug Security Control and Status Register (DSCSR) and check CDS (bit 16)\n\tset DSCSR [mrw 0xE000EE08]\n\treturn [expr {($DSCSR & (1 << 16)) != 0}]\n}\n\nproc stm32x5x_ahb_ap_non_secure_access {} {\n\t# SPROT=1=Non Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x4B000000 0x4F000000\n}\n\nproc stm32x5x_ahb_ap_secure_access {} {\n\t# SPROT=0=Secure access, Priv=1\n\t[[target current] cget -dap] apcsw 0x0B000000 0x4F000000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 480\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0xE0044004 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0044008 0x00001800 0\n}\n\n$_TARGETNAME configure -event halted {\n\tset secure [stm32x5x_is_secure]\n\n\tif {$secure} {\n\t\tset secure_str \"Secure\"\n\t\tstm32x5x_ahb_ap_secure_access\n\t} else {\n\t\tset secure_str \"Non-Secure\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t}\n\n\t# print the secure state only when it changes\n\tset _TARGETNAME [target current]\n\tglobal $_TARGETNAME.secure\n\n\tif {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {\n\t\techo \"CPU in $secure_str state\"\n\t\t# update saved security state\n\t\tset $_TARGETNAME.secure $secure\n\t}\n}\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tset use_secure_workarea 0\n\t# check if FLASH_OPTR.TZEN is enabled\n\tset FLASH_OPTR [mrw 0x40022040]\n\tif {[expr {$FLASH_OPTR & 0x80000000}] == 0} {\n\t\techo \"TZEN option bit disabled\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t} else {\n\t\tstm32x5x_ahb_ap_secure_access\n\t\techo \"TZEN option bit enabled\"\n\n\t\t# check if FLASH_OPTR.RDP is not Level 0.5\n\t\tif {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {\n\t\t\tset use_secure_workarea 1\n\t\t}\n\t}\n\n\tset _TARGETNAME [target current]\n\tset workarea_addr [$_TARGETNAME cget -work-area-phys]\n\techo \"workarea_addr $workarea_addr\"\n\n\tif {$use_secure_workarea} {\n\t\tset workarea_addr [expr {$workarea_addr | 0x10000000}]\n\t} else {\n\t\tset workarea_addr [expr {$workarea_addr & ~0x10000000}]\n\t}\n\n\t$_TARGETNAME configure -work-area-phys $workarea_addr\n}\n\n$_TARGETNAME configure -event trace-config {\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0044004 0x00000020 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm32xl.cfg",
    "content": "# script for stm32xl family (dual flash bank)\nsource [find target/stm32f1x.cfg]\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8l.cfg",
    "content": "# script for stm8l family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8l\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set stm8l type\n$_TARGETNAME configure -enable_stm8l\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n#uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8l152.cfg",
    "content": "#config script for STM8L152\n\nset EEPROMSTART 0x1000\nset EEPROMEND 0x13ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8s.cfg",
    "content": "# script for stm8s family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8s\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n# uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8s003.cfg",
    "content": "#config script for STM8S003\n\nset FLASHEND 0x9FFF\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8s103.cfg",
    "content": "#config script for STM8S103\n\nset FLASHEND 0x9FFF\nset EEPROMEND 0x427F\nset OPTIONEND 0x480A\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/stm8s105.cfg",
    "content": "#config script for STM8S105\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/str710.cfg",
    "content": "#start slow, speed up after reset\nadapter speed 10\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str710\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 6000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x400C0000 0x00004000 0 0 $_TARGETNAME STR71x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/str730.cfg",
    "content": "#STR730 CPU\n\nadapter speed 3000\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str730\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/str750.cfg",
    "content": "#STR750 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str750\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0041\n}\n\n# jtag speed\nadapter speed 10\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n\tinit_smi\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x20000000 0x00040000 0 0 $_TARGETNAME STR75x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x200C0000 0x00004000 0 0 $_TARGETNAME STR75x\n\n# Serial NOR on SMI CS0.\nset _FLASHNAME $_CHIPNAME.snor\nflash bank $_FLASHNAME stmsmi 0x80000000 0 0 0 $_TARGETNAME\n\nsource [find mem_helper.tcl]\n\nproc init_smi {} {\n\tmmw 0x60000030 0x01000000 0x00000000; # enable clock for GPIO regs\n\tmmw 0xffffe420 0x00000001 0x00000000; # set SMI_EN bit\n\tmmw 0x90000000 0x00000001 0x00000000; # set BLOCK_EN_1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/str912.cfg",
    "content": "# script for str9\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # possible values: 0x1457f041, 0x2457f041\n   # we ignore version in check below\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID -ignore-version\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#adapter speed 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/swj-dp.tcl",
    "content": "# ARM Debug Interface V5 (ADI_V5) utility\n# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since\n# SW-DP and JTAG-DP targets don't need to switch based\n# on which transport is active.\n#\n# declare a JTAG or SWD Debug Access Point (DAP)\n# based on the transport in use with this session.\n# You can't access JTAG ops when SWD is active, etc.\n\n# params are currently what \"jtag newtap\" uses\n# because OpenOCD internals are still strongly biased\n# to JTAG ....  but for SWD, \"irlen\" etc are ignored,\n# and the internals work differently\n\n# for now, ignore non-JTAG and non-SWD transports\n# (e.g. initial flash programming via SPI or UART)\n\n# split out \"chip\" and \"tag\" so we can someday handle\n# them more uniformly irlen too...)\n\nif [catch {transport select}] {\n  echo \"Error: unable to select a session transport. Can't continue.\"\n  shutdown\n}\n\nproc swj_newdap {chip tag args} {\n if [using_jtag] {\n     eval jtag newtap $chip $tag $args\n } elseif [using_swd] {\n     eval swd newdap $chip $tag $args\n } else {\n     echo \"Error: transport '[ transport select ]' not supported by swj_newdap\"\n     shutdown\n }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/swm050.cfg",
    "content": "# Synwit SWM050\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME swm050\n}\nset _CHIPSERIES swm050\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\nadapter speed 1000\n\n$_TARGETNAME configure -event reset-init {\n\t# Stop the watchdog, just to be safe\n\tmww 0x40019000 0x00\n\t# Set clock divider value to 1\n\tmww 0x400F0000 0x01\n\t# Set system clock to 18Mhz\n\tmww 0x400F0008 0x00\n}\n\n# SWM050 (Cortex-M0 core) supports SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/test_reset_syntax_error.cfg",
    "content": "# Test script to check that syntax error in reset\n# script is reported properly.\n\n# at91eb40a target\n\n#jtag scan chain\nset _CHIPNAME syntaxtest\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\n\tsyntax error\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/test_syntax_error.cfg",
    "content": "# This script tests a syntax error in the startup\n# config script\n\nsyntax error here\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti-ar7.cfg",
    "content": "#\n# Texas Instruments AR7 SOC - used in many adsl modems.\n# http://www.linux-mips.org/wiki/AR7\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ti-ar7\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0000100f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_CHIPNAME.cpu\n\n# use onboard 4k sram as working area\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti-cjtag.cfg",
    "content": "# A start sequence to change from cJTAG to 4-pin JTAG\n# This is needed for CC2538 and CC26xx to be able to communicate through JTAG\n# Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information.\nproc ti_cjtag_to_4pin_jtag {jrc} {\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\t# Two zero bit scans and a one bit drshift\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# A two bit drhift and a 9 bit drshift\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\n\t# Set ICEPick IDCODE in data register\n\tirscan $jrc 0x04 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_calypso.cfg",
    "content": "#\n# TI Calypso (lite) G2 C035 Digital Base Band chip\n#\n# ARM7TDMIE + DSP subchip (S28C128)\n#\n# 512K SRAM Calypso\n# 256K SRAM Calypso lite\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME calypso\n}\n\nif { [info exists ENDIAN] } {\n\tset  _ENDIAN $ENDIAN\n} else {\n\tset  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3100e02f\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\njtag newtap $_CHIPNAME dsp -expected-id 0x00000000 -irlen 8\njtag newtap $_CHIPNAME arm -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# target\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position $_TARGETNAME\n\n# workarea\n\n$_TARGETNAME configure -work-area-phys 0x00800000 -work-area-size $_WORKAREASIZE -work-area-backup 1\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n$_TARGETNAME configure -event examine-start {\n\tirscan calypso.arm 0x0b -endstate DRPAUSE\n\tdrscan calypso.arm 2 2 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc13x0.cfg",
    "content": "#\n# Texas Instruments CC13x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x0\nset JRC_TAPID 0x0B9BE02F\nset WORKAREASIZE 0x4000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc13x2.cfg",
    "content": "#\n# Texas Instruments CC13x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc26x0.cfg",
    "content": "#\n# Texas Instruments CC26x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc26x0\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4BA00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B99A02F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n# A start sequence is needed to change from 2-pin cJTAG to 4-pin JTAG\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config vectreset\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc26x2.cfg",
    "content": "#\n# Texas Instruments CC26x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc26x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc3220sf.cfg",
    "content": "#\n# Texas Instruments CC3220SF - ARM Cortex-M4\n#\n# http://www.ti.com/CC3220SF\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\nsource [find target/ti_cc32xx.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n#\n# On CC32xx family of devices, sysreqreset is disabled, and vectreset is\n# blocked by the boot loader (stops in a while(1) statement). srst reset can\n# leave the target in a state that prevents debug. The following uses the\n# soft_reset_halt command to reset and halt the target. Then the PC and stack\n# are initialized from internal flash. This allows for a more reliable reset,\n# but with two caveats: it only works for the SF variant that has internal\n# flash, and it only resets the CPU and not any peripherals.\n#\n\nproc ocd_process_reset_inner { MODE } {\n\n\tsoft_reset_halt\n\n\t# Initialize MSP, PSP, and PC from vector table at flash 0x01000800\n\tset boot [read_memory 0x01000800 32 2]\n\n\treg msp [lindex $boot 0]\n\treg psp [lindex $boot 0]\n\treg pc [lindex $boot 1]\n\n\tif { 0 == [string compare $MODE run ] } {\n\t\tresume\n\t}\n\n\tcc32xx.cpu invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_cc32xx.cfg",
    "content": "#\n# Texas Instruments CC32xx - ARM Cortex-M4\n#\n# http://www.ti.com/product/CC3200\n# http://www.ti.com/product/CC3220\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc32xx\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tif {[using_jtag]} {\n\t\tset _DAP_TAPID 0x4BA00477\n\t} else {\n\t\tset _DAP_TAPID 0x2BA01477\n\t}\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\n\tjtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n} else {\n\tswj_newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\n}\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B97C02F\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\tjtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_dm355.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM355\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm355\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n#\n# Also note: when running without RTCK before the PLLs are set up, you\n# may need to slow the JTAG clock down quite a lot (under 2 MHz).\n#\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b73b02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm355\nset dm355 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm355 sram0\t\t0x00010000\ndict set dm355 sram1\t\t0x00014000\ndict set dm355 sysbase\t\t0x01c40000\ndict set dm355 pllc1\t\t0x01c40800\ndict set dm355 pllc2\t\t0x01c40c00\ndict set dm355 psc\t\t0x01c41000\ndict set dm355 gpio\t\t0x01c67000\ndict set dm355 a_emif\t\t0x01e10000\ndict set dm355 a_emif_cs0\t0x02000000\ndict set dm355 a_emif_cs1\t0x04000000\ndict set dm355 ddr_emif\t\t0x20000000\ndict set dm355 ddr\t\t0x80000000\ndict set dm355 uart0\t\t0x01c20000\ndict set dm355 uart1\t\t0x01c20400\ndict set dm355 uart2\t\t0x01e06000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm355 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_dm365.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM365\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm365\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x0792602f\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b83e02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm365\nset dm365 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm365 sram0\t\t0x00010000\ndict set dm365 sram1\t\t0x00014000\ndict set dm365 sysbase\t\t0x01c40000\ndict set dm365 pllc1\t\t0x01c40800\ndict set dm365 pllc2\t\t0x01c40c00\ndict set dm365 psc\t\t0x01c41000\ndict set dm365 gpio\t\t0x01c67000\ndict set dm365 a_emif\t\t0x01d10000\ndict set dm365 a_emif_cs0\t0x02000000\ndict set dm365 a_emif_cs1\t0x04000000\ndict set dm365 ddr_emif\t\t0x20000000\ndict set dm365 ddr\t\t0x80000000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm365 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_dm6446.cfg",
    "content": "#\n# Texas Instruments DaVinci family: TMS320DM6446\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm6446\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: unknown ... must enable via ICEpick\njtag newtap $_CHIPNAME unknown -irlen 8 -disable\njtag configure $_CHIPNAME.unknown -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\njtag configure $_CHIPNAME.dsp -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b70002f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_k3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments K3 devices:\n# * AM654x: https://www.ti.com/lit/pdf/spruid7\n#  Has 4 ARMV8 Cores and 2 R5 Cores and an M3\n# * J721E: https://www.ti.com/lit/pdf/spruil1\n#  Has 2 ARMV8 Cores and 6 R5 Cores and an M3\n# * J7200: https://www.ti.com/lit/pdf/spruiu1\n#  Has 2 ARMV8 Cores and 4 R5 Cores and an M3\n# * AM642: https://www.ti.com/lit/pdf/spruim2\n#  Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3\n#\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc am654\n}\n\n# set V8_SMP_DEBUG to non 0 value in board if you'd like to use SMP debug\nif { [info exists V8_SMP_DEBUG] } {\n\tset _v8_smp_debug $V8_SMP_DEBUG\n} else {\n\tset _v8_smp_debug 0\n}\n\n# Common Definitions\n\n# System Controller is the very first processor - all current SoCs have it.\nset CM3_CTIBASE\t\t{0x3C016000}\n\n# sysctrl power-ap unlock offsets\nset _sysctrl_ap_unlock_offsets {0xf0 0x44}\n\n# All the ARMV8s are the next processors.\n#\t\t   CL0,CORE0  CL0,CORE1  CL1,CORE0  CL1,CORE1\nset ARMV8_DBGBASE {0x90410000 0x90510000 0x90810000 0x90910000}\nset ARMV8_CTIBASE {0x90420000 0x90520000 0x90820000 0x90920000}\n\n# And we add up the R5s\n#\t\t(0)MCU 0   (1)MCU 1   (2)MAIN_0_0 (3)MAIN_0_1 (4)MAIN_1_0 (5)MAIN_1_1\nset R5_DBGBASE {0x9d010000 0x9d012000 0x9d410000 0x9d412000 0x9d510000 0x9d512000}\nset R5_CTIBASE {0x9d018000 0x9d019000 0x9d418000 0x9d419000 0x9d518000 0x9d519000}\nset R5_NAMES {mcu_r5.0 mcu_r5.1 main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\n# Finally an General Purpose(GP) MCU\nset CM4_CTIBASE\t\t{0x20001000}\n\n# General Purpose MCU (M4) may be present on some very few SoCs\nset _gp_mcu_cores 0\n# General Purpose MCU power-ap unlock offsets\nset _gp_mcu_ap_unlock_offsets {0xf0 0x60}\n\n# Set configuration overrides for each SOC\nswitch $_soc {\n\tam654 {\n\t\tset _CHIPNAME am654\n\t\tset _K3_DAP_TAPID 0x0bb5a02f\n\n\t\t# AM654 has 2 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\n\t\t# AM654 has 1 cluster of 2 R5s cores.\n\t\tset _r5_cores 2\n\t\tset R5_NAMES {mcu_r5.0 mcu_r5.1}\n\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x50}\n\t}\n\tam642 {\n\t\tset _CHIPNAME am642\n\t\tset _K3_DAP_TAPID 0x0bb3802f\n\n\t\t# AM642 has 1 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 2\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000}\n\n\t\t# AM642 has 2 cluster of 2 R5s cores.\n\t\tset _r5_cores 4\n\t\tset R5_NAMES {main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\t\tset R5_DBGBASE {0x9d410000 0x9d412000 0x9d510000 0x9d512000}\n\t\tset R5_CTIBASE {0x9d418000 0x9d419000 0x9d518000 0x9d519000}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t}\n\tam625 {\n\t\tset _CHIPNAME am625\n\t\tset _K3_DAP_TAPID 0x0bb7e02f\n\n\t\t# AM625 has 1 clusters of 4 A53 cores.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}\n\n\t\t# AM625 has 1 cluster of 1 R5s core.\n\t\tset _r5_cores 1\n\t\tset R5_NAMES {main0_r5.0}\n\t\tset R5_DBGBASE {0x9d410000}\n\t\tset R5_CTIBASE {0x9d418000}\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tj721e {\n\t\tset _CHIPNAME j721e\n\t\tset _K3_DAP_TAPID 0x0bb6402f\n\t\t# J721E has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721E has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\t}\n\tj7200 {\n\t\tset _CHIPNAME j7200\n\t\tset _K3_DAP_TAPID 0x0bb6d02f\n\n\t\t# J7200 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J7200 has 2 clusters of 2 R5 cores each.\n\t\tset _r5_cores 4\n\t\tset R5_DBGBASE {0x9d010000 0x9d012000 0x9d110000 0x9d112000}\n\t\tset R5_CTIBASE {0x9d018000 0x9d019000 0x9d118000 0x9d119000}\n\n\t\t# M3 CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t}\n\tj721s2 {\n\t\tset _CHIPNAME j721s2\n\t\tset _K3_DAP_TAPID 0x0bb7502f\n\n\t\t# J721s2 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721s2 has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tdefault {\n\t\techo \"'$_soc' is invalid!\"\n\t}\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\nset _CTINAME $_CHIPNAME.cti\n\n# sysctrl is always present\ncti create $_CTINAME.sysctrl -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]\ntarget create $_TARGETNAME.sysctrl cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine\n$_TARGETNAME.sysctrl configure -event reset-assert { }\n\nproc sysctrl_up {} {\n\t# To access sysctrl, we need to enable the JTAG access for the same.\n\t# Ensure Power-AP unlocked\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 0] 0x00190000\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 1] 0x00102098\n\n\t$::_TARGETNAME.sysctrl arp_examine\n}\n\n$_TARGETNAME.sysctrl configure -event gdb-attach {\n\tsysctrl_up\n\t# gdb-attach default rule\n\thalt 1000\n}\n\nproc _cpu_no_smp_up {} {\n\tset _current_target [target current]\n\tset _current_type [$_current_target cget -type]\n\n\t$_current_target arp_examine\n\t$_current_target $_current_type dbginit\n}\n\nproc _armv8_smp_up {} {\n\tfor { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on\n\t}\n\t# Set Default target as core 0\n\ttargets $::_TARGETNAME.$::_armv8_cpu_name.0\n}\n\nset _v8_smp_targets \"\"\n\nfor { set _core 0 } { $_core < $_armv8_cores } { incr _core } {\n\n\tcti create $_CTINAME.$_armv8_cpu_name.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $ARMV8_CTIBASE $_core]\n\n\ttarget create $_TARGETNAME.$_armv8_cpu_name.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $ARMV8_DBGBASE $_core] -cti $_CTINAME.$_armv8_cpu_name.$_core -defer-examine\n\n\tset _v8_smp_targets \"$_v8_smp_targets $_TARGETNAME.$_armv8_cpu_name.$_core\"\n\n\tif { $_v8_smp_debug == 0 } {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_cpu_no_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t} else {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_armv8_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t}\n}\n\n# Setup ARMV8 proc commands based on CPU to prevent people confusing SoCs\nset _armv8_up_cmd \"$_armv8_cpu_name\"_up\n# Available if V8_SMP_DEBUG is set to non-zero value\nset _armv8_smp_cmd \"$_armv8_cpu_name\"_smp\n\nif { $_v8_smp_debug == 0 } {\n\tproc $_armv8_up_cmd { args } {\n\t\tforeach _core $args {\n\t\t\ttargets $_core\n\t\t\t_cpu_no_smp_up\n\t\t}\n\t}\n} else {\n\tproc $_armv8_smp_cmd { args } {\n\t\t_armv8_smp_up\n\t}\n\t# Declare SMP\n\ttarget smp $:::_v8_smp_targets\n}\n\nfor { set _core 0 } { $_core < $_r5_cores } { incr _core } {\n\tset _r5_name [lindex $R5_NAMES $_core]\n\tcti create $_CTINAME.$_r5_name -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $R5_CTIBASE $_core]\n\n\t# inactive core examination will fail - wait till startup of additional core\n\ttarget create $_TARGETNAME.$_r5_name cortex_r4 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $R5_DBGBASE $_core] -ap-num 1 -defer-examine\n\n\t$_TARGETNAME.$_r5_name configure -event gdb-attach {\n\t\t_cpu_no_smp_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n\nproc r5_up { args } {\n\tforeach  _core $args {\n\t\ttargets $_core\n\t\t_cpu_no_smp_up\n\t}\n}\n\nif { $_gp_mcu_cores != 0 } {\n\tcti create $_CTINAME.gp_mcu -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]\n\ttarget create $_TARGETNAME.gp_mcu cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine\n\t$_TARGETNAME.gp_mcu configure -event reset-assert { }\n\n\tproc gp_mcu_up {} {\n\t\t# To access GP MCU, we need to enable the JTAG access for the same.\n\t\t# Ensure Power-AP unlocked\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 0] 0x00190000\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 1] 0x00102098\n\n\t\t$::_TARGETNAME.gp_mcu arp_examine\n\t}\n\n\t$_TARGETNAME.gp_mcu configure -event gdb-attach {\n\t\tgp_mcu_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_msp432.cfg",
    "content": "#\n# Texas Instruments MSP432 - ARM Cortex-M4F @ up to 48 MHz\n#\n# http://www.ti.com/MSP432\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME msp432\n}\n\nif { [info exists CPUTAPID] } {\n\tset _DAP_TAPID $CPUTAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists DAP_SWD_ID] } {\n\tset _DAP_SWD_ID $DAP_SWD_ID\n} else {\n\tset _DAP_SWD_ID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _DAP_ID $_DAP_TAPID\n} else {\n\tset _DAP_ID $_DAP_SWD_ID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_rm4x.cfg",
    "content": "source [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_tms570.cfg",
    "content": "adapter speed 1500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tms570\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN big\n}\n\n# TMS570 has an ICEpick-C on which we need the router commands.\nsource [find target/icepick.cfg]\n\n# Main DAP\n# DAP_TAPID should be set before source-ing this file\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# ICEpick-C (JTAG route controller)\n# JRC_TAPID should be set before source-ing this file\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n}\n\nset _JRC_TAPID2 0x0B7B302F\nset _JRC_TAPID3 0x0B95502F\nset _JRC_TAPID4 0x0B97102F\nset _JRC_TAPID5 0x0D8A002F\nset _JRC_TAPID6 0x2B8A002F\nset _JRC_TAPID7 0x2D8A002F\nset _JRC_TAPID8 0x3B8A002F\nset _JRC_TAPID9 0x3D8A002F\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID \\\n\t-expected-id $_JRC_TAPID2 \\\n\t-expected-id $_JRC_TAPID3 \\\n\t-expected-id $_JRC_TAPID4 \\\n\t-expected-id $_JRC_TAPID5 \\\n\t-expected-id $_JRC_TAPID6 \\\n\t-expected-id $_JRC_TAPID7 \\\n\t-expected-id $_JRC_TAPID8 \\\n\t-expected-id $_JRC_TAPID9 \\\n\t-ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-R4 target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_r4 -endian $_ENDIAN \\\n\t-dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x00001003\n\n# TMS570 uses quirky BE-32 mode\n$_CHIPNAME.dap ti_be_32_quirks 1\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\tglobal _CHIPNAME\n\n\t# assert warm system reset through ICEPick\n\ticepick_c_wreset $_CHIPNAME.jrc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_tms570ls20xxx.cfg",
    "content": "# TMS570LS20216, TMS570LS20206, TMS570LS10216\n# TMS570LS10206, TMS570LS10116, TMS570LS10106\nset DAP_TAPID 0x0B7B302F\nset JRC_TAPID 0x0B7B302F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/ti_tms570ls3137.cfg",
    "content": "# TMS570LS3137\nset DAP_TAPID 0x0B8A002F\nset JRC_TAPID 0x0B8A002F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/tmpa900.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA900\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa900\n}\n\n# Toshiba TMPA900 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA900 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (8kB): 0xf8008000\n\n# Use internal RAM-0 and RAM-1 as working area (24kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0x6000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/tmpa910.cfg",
    "content": "######################################\n# Target:    Toshiba TMPA910\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa910\n}\n\n# Toshiba TMPA910 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA910 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (16kB): 0xf8008000\n# Internal RAM-2 (16kB): 0xf800c000\n\n# Use internal RAM-0, RAM-1, and RAM-2 as working area (48kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0xc000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/tnetc4401.cfg",
    "content": "# Texas Instruments (TI) TNETC4401, MIPS32 DOCSIS-tailored SoC (4Kc-based)\n# Used in Knovative KC-100 and Motorola Surfboard SB5120 cable modems.\n# Datasheet: https://brezn.muc.ccc.de/~mazzoo/DOCSIS/tnetc4401.pdf\ntransport select jtag\nset _TARGETNAME tnetc4401\nset _CPUTAPID 0x0000100f\njtag newtap $_TARGETNAME tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\ntarget create $_TARGETNAME mips_m4k -chain-position $_TARGETNAME.tap -endian big\n\n# May need to halt manually before calling reset init\n$_TARGETNAME configure -event reset-init {\n\thalt\n\techo \"Attempting to disable watchdog...\"\n\tmwb phys 0xa8610b00 0 256\n\thalt\n\twait_halt\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/u8500.cfg",
    "content": "#  Copyright (C) ST-Ericsson SA 2011\n#  Author : michel.jaouen@stericsson.com\n#  U8500 target\n\nproc mmu_off {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp & ~1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc mmu_on {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp | 1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc ocd_gdb_restart {target_id} {\n    global _TARGETNAME_1\n\tglobal _SMP\n    targets $_TARGETNAME_1\n\tif { $_SMP == 1 } {\n\tcortex_a smp off\n\t}\n\trst_run\n\thalt\n\tif { $_SMP == 1 } {\n\tcortex_a smp on\n\t}\n}\n\nproc smp_reg {} {\n\tglobal _TARGETNAME_1\n    global _TARGETNAME_2\n    targets $_TARGETNAME_1\n\techo \"$_TARGETNAME_1\"\n\tset pc1 [reg pc]\n\tset stck1 [reg sp_svc]\n\ttargets $_TARGETNAME_2\n\techo \"$_TARGETNAME_1\"\n\tset pc2 [reg pc]\n\tset stck2 [reg sp_svc]\n}\n\n\nproc u8500_tapenable {chip val} {\n\techo \"JTAG tap enable $chip\"\n}\n\n\nproc pwrsts { } {\n\tglobal _CHIPNAME\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\techo \"pwrsts =\"$pwrsts\n\tset a9 [expr \"0x$pwrsts & 0xc\"]\n\tset ape [expr \"0x$pwrsts & 0x3\"]\n\tif {[string equal \"0\" $ape]} {\n\t\techo \"ape off\"\n\t} else {\n\t\techo \"ape on\"\n\t}\n\techo \"$a9\"\n\tswitch $a9 {\n\t\t4 {\n\t\t\techo \"A9 in retention\"\n\t\t  }\n\t\t8 {\n\t\t\techo \"A9 100% DVFS\"\n\t\t  }\n\t\tc {\n\t\t\techo \"A9 50% DVFS\"\n\t\t}\n\t}\n}\n\nproc poll_pwrsts { } {\n\tglobal _CHIPNAME\n\tset result 1\n\tset i 0\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\twhile {[string equal \"4\" $pwrsts] && $i<20} {\n\t\tirscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 0;\n\t\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\t\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\t\tif {![string equal \"4\" $pwrsts]} {\n\t\t\tset result 1\n\t\t} else {\n\t\t\tset result 0\n\t\t\tsleep 200\n\t\t\techo \"loop $i\"\n\t\t}\n\t\tincr i\n\t}\n\treturn $result\n}\n\nproc halt_ { } {\n\tif {[poll_pwrsts]==1} {\n\t\thalt\n\t} else {\n\t\techo \"halt failed : target in retention\"\n\t}\n}\n\n\nproc u8500_dapenable {chip} {\n}\n\nproc u8500_tapdisable {chip val} {\n\techo \"JTAG tap disable $chip\"\n}\n\n\nproc enable_apetap {} {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n    global _TARGETNAME_1\n\tpoll off\n\tirscan $_CHIPNAME.jrc 0x3e\n\tdrscan $_CHIPNAME.jrc 8 0xcf\n\tjtag tapenable $_CHIPNAME.dap\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tset status [$_TARGETNAME_1 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_1 arp_examine\n\tcache_config l2x 0xa0412000 8\n\t}\n\n\tset status [$_TARGETNAME_2 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_2 arp_examine\n\t}\n\t}\n\ntcl_port 5555\ntelnet_port 4444\ngdb_port 3333\n\nif { [info exists CHIPNAME] } {\nglobal _CHIPNAME\n    set _CHIPNAME $CHIPNAME\n} else {\nglobal _CHIPNAME\n\tset _CHIPNAME u8500\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n\tset _ENDIAN little\n}\n\n\n\n# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT,\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"u8500_dapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n\t\"u8500_tapdisable $_CHIPNAME.cpu 0xc0\"\n\n\n#CLTAPC TAP JRC equivalent\nif { [info exists CLTAPC_ID] } {\n   set _CLTAPC_ID $CLTAPC_ID\n} else {\n   set _CLTAPC_ID 0x22286041\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version\n\n\nif { ![info exists TARGETNAME_1] } {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $_CHIPNAME.cpu1\n} else {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $TARGETNAME_1\n}\n\nif { [info exists DAP_DBG1] } {\n\tset _DAP_DBG1 $DAP_DBG1\n} else {\n\tset _DAP_DBG1 0x801A8000\n}\nif { [info exists DAP_DBG2] } {\n\tset _DAP_DBG2 $DAP_DBG2\n} else {\n\tset _DAP_DBG2 0x801AA000\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME_1 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux\n\n\nif { ![info exists TARGETNAME_2] } {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $_CHIPNAME.cpu2\n} else {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $TARGETNAME_2\n}\n\ntarget create $_TARGETNAME_2 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux\n\n\nif {![info exists SMP]} {\nglobal _SMP\nset _SMP 1\n} else {\nglobal _SMP\nset _SMP $SMP\n}\nglobal SMP\nif { $_SMP == 1} {\ntarget smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\n}\n\n\n\n\nproc secsts1 { } {\n\tglobal _CHIPNAME\n        irscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {![string equal \"4\" $secsts1]} {\n\techo \"APE target secured\"\n        } else {\n        echo \"APE target not secured\"\n        }\n}\n\nproc att { } {\n\tglobal _CHIPNAME\n\tjtag arp_init\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {[string equal \"4\" $secsts1]} {\n\t\tif {[poll_pwrsts]==1} {\n\t\tenable_apetap\n                } else {\n\t\techo \"target in retention\"\n\t\t}\n\t} else {\n\t\techo \"target secured\"\n\t}\n\n}\n\n\n\nproc rst_run { } {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n\tglobal _TARGETNAME_1\n\tset status [$_TARGETNAME_1 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_1\n\t}\n    set status [$_TARGETNAME_2 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_2\n\t}\n   \tpoll off\n\tjtag arp_init\n\treset\n\tsleep 20\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\twhile {![string equal \"4\" $secsts1]} {\n\t\tirscan u8500.jrc 0x3a\n\t\tdrscan u8500.jrc 4 4\n\t\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\t\techo \"secsts1 =\"$secsts1\n\t\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\t}\n\techo \"ape debugable\"\n\tenable_apetap\n\tpoll on\n\ttargets $_TARGETNAME_1\n\tdap apsel 1\n}\n\nif {![info exists MAXSPEED]} {\nglobal _MAXSPEED\nset _MAXSPEED 15000\n} else {\nglobal _MAXSPEED\nset _MAXSPEED $MAXSPEED\n}\nglobal _MAXSPEED\nadapter speed $_MAXSPEED\n\n\ngdb_breakpoint_override hard\nset mem inaccessible-by-default-off\n\njtag_ntrst_delay 100\nreset_config trst_and_srst combined\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/vd_aarch64.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm v8 64b Cortex A\n\nif {![info exists _CORES]} {\n\tset _CORES 1\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME aarch64\n}\nset _TARGETNAME $_CHIPNAME.cpu\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80810000 0x80910000}\nset CTIBASE {0x80820000 0x80920000}\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n$_CHIPNAME.dap apsel 1\n\nfor { set _core 0 } { $_core < $_CORES } { incr _core } \\\n{\n\tcti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 -baseaddr [lindex $CTIBASE $_core]\n\tset _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t-dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core\"\n\tif { $_core != 0 } {\n\t\t# non-boot core examination may fail\n\t\tset _command \"$_command -defer-examine\"\n\t\tset _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n\t} else {\n\t\tset _smp_command \"target smp $_TARGETNAME.$_core\"\n\t}\n\teval $_command\n}\neval $_smp_command\n\n# default target is core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/vd_cortex_m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# ARM Cortex M\n\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME cortex_m\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/vd_riscv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV core\n\nif {![info exists _HARTID]} {\n\tset _HARTID 0x00\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME riscv\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID\n\nriscv set_reset_timeout_sec 120\nriscv set_command_timeout_sec 120\n# prefer to use sba for system bus access\nriscv set_prefer_sba on\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/vybrid_vf6xx.cfg",
    "content": "#\n# Freescale Vybrid VF610\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME vf610\n}\n\nif { [info exists A5_JTAG_TAPID] } {\n\tset _A5_JTAG_TAPID $A5_JTAG_TAPID\n} else {\n\tset _A5_JTAG_TAPID 0x4BA00477\n}\n\nif { [info exists A5_SWD_TAPID] } {\n\tset _A5_SWD_TAPID $A5_SWD_TAPID\n} else {\n\tset _A5_SWD_TAPID 0x3BA02477\n}\n\nif { [using_jtag] } {\n\tset _A5_TAPID $_A5_JTAG_TAPID\n} else {\n\tset _A5_TAPID $_A5_SWD_TAPID\n}\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_A5_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap -dbgbase 0xc0088000\ntarget create ${_TARGETNAME}1 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/xilinx_zynqmp.cfg",
    "content": "#\n# target configuration for\n# Xilinx ZynqMP (UltraScale+ / A53)\n#\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME uscale\n}\n\n#\n# DAP tap (Quard core A53)\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# PS tap (UltraScale+)\n#\nif { [info exists PS_TAPID] } {\n    set _PS_TAPID $PS_TAPID\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -expected-id $_PS_TAPID\n} else {\n    # FPGA Programmable logic. Values take from Table 39-1 in UG1085:\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -ignore-version \\\n        -expected-id 0x04711093 \\\n        -expected-id 0x04710093 \\\n        -expected-id 0x04721093 \\\n        -expected-id 0x04720093 \\\n        -expected-id 0x04739093 \\\n        -expected-id 0x04730093 \\\n        -expected-id 0x04738093 \\\n        -expected-id 0x04740093 \\\n        -expected-id 0x04750093 \\\n        -expected-id 0x04759093 \\\n        -expected-id 0x04758093\n}\n\nset jtag_configured 0\n\njtag configure $_CHIPNAME.ps -event setup {\n    global _CHIPNAME\n    global jtag_configured\n\n    if { $jtag_configured == 0 } {\n        # add the DAP tap to the chain\n        # See https://forums.xilinx.com/t5/UltraScale-Architecture/JTAG-Chain-Configuration-for-Zynq-UltraScale-MPSoC/td-p/758924\n        irscan $_CHIPNAME.ps 0x824\n        drscan $_CHIPNAME.ps 32 0x00000003\n        runtest 100\n\n        # setup event will be re-entered through jtag arp_init\n        # break the recursion\n        set jtag_configured 1\n        # re-initialized the jtag chain\n        jtag arp_init\n    }\n}\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\nset _smp_command \"\"\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset _cores 4\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        # uncomment when \"hawt\" rtos is merged\n        #set _command \"$_command -rtos hawt\"\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\ntarget create uscale.axi mem_ap -dap uscale.dap -ap-num 0\n\neval $_smp_command\ntargets $_TARGETNAME.0\n\nproc core_up { args } {\n    global _TARGETNAME\n    foreach core $args {\n        $_TARGETNAME.$core arp_examine\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/xmc1xxx.cfg",
    "content": "#\n# Infineon XMC1100/XMC1200/XMC1300 family (ARM Cortex-M0 @ 32 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc1000\n}\n\n#\n# Only SWD and SPD supported\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_SWD_TAPID $CPUTAPID\n} else {\n\tset _CPU_SWD_TAPID 0x0BB11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n                       -work-area-size $_WORKAREASIZE \\\n                       -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/xmc4xxx.cfg",
    "content": "#\n# Infineon XMC4100/XMC4200/XMC4400/XMC4500 family (ARM Cortex-M4 @ 80-120 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc4000\n}\n\nsource [find target/swj-dp.tcl]\n\n#\n# SWJ-DP\n#\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x4BA00477\n}\n\n#\n# SW_DP\n#\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16 kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc4xxx 0x0C000000 0 0 0 $_TARGETNAME\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/xmos_xs1-xau8a-10_arm.cfg",
    "content": "#\n# XMOS xCORE-XA XS1-XAU8A-10: ARM Cortex-M3 @ 48 MHz\n#\n# http://www.xmos.com/products/silicon/xcore-xa/xa-series\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME xcorexa\n}\n\nif { ![info exists WORKAREASIZE] } {\n\t# XS1-XAU8A-10-FB265: 128 KB SRAM\n\tset WORKAREASIZE 0x20000\n}\n\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/zynq_7000.cfg",
    "content": "#\n# Xilinx Zynq-7000 All Programmable SoC\n#\n# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm\n#\n\nset _CHIPNAME zynq\nset _TARGETNAME $_CHIPNAME.cpu\n\njtag newtap zynq_pl bs -irlen 6 -ircapture 0x1 -irmask 0x03 \\\n    -expected-id 0x23727093 \\\n    -expected-id 0x13722093 \\\n    -expected-id 0x03727093 \\\n    -expected-id 0x03736093\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 0 -dbgbase 0x80090000\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 1 -dbgbase 0x80092000\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n\nadapter speed 1000\n\n${_TARGETNAME}0 configure -event reset-assert-post \"cortex_a dbginit\"\n${_TARGETNAME}1 configure -event reset-assert-post \"cortex_a dbginit\"\n\npld device virtex2 zynq_pl.bs 1\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc zynqpl_program {tap} {\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/target/к1879xб1я.cfg",
    "content": "# СБИС К1879ХБ1Я\n# http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/\n\nadapter speed 1000\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME к1879хб1я\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists DSP_TAPID] } {\n    set _DSP_TAPID $DSP_TAPID\n} else {\n    set _DSP_TAPID 0x2b900f0f\n}\n\njtag newtap $_CHIPNAME dsp -irlen 4 -expected-id $_DSP_TAPID\n\nif { [info exists CPU_TAPID] } {\n    set _CPU_TAPID $CPU_TAPID\n} else {\n    set _CPU_TAPID 0x07b76f0f\n}\n\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_CHIPNAME.arm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/test/selftest.cfg",
    "content": "\nadd_help_text selftest \"run selftest using working ram <tmpfile> <address> <size>\"\n\nproc selftest {tmpfile address size} {\n\n   for {set i 0} {$i < $size } {set i [expr {$i+4}]} {\n       mww [expr {$address+$i}] $i\n   }\n\n   for {set i 0} {$i < 10 } {set i [expr {$i+1}]} {\n    echo \"Test iteration $i\"\n    dump_image $tmpfile $address $size\n\tverify_image $tmpfile $address bin\n\tload_image $tmpfile $address bin\n   }\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/test/syntax1.cfg",
    "content": "adapter srst delay 200\njtag_ntrst_delay 200\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough\nadapter assert trst assert srst\nadapter deassert trst deassert srst\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap lpc2148 one -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4f1f0f0f\n\n#target configuration\n#daemon_startup reset\n\nset _TARGETNAME [format \"%s.cpu\" lpc2148]\ntarget create lpc2148.cpu arm7tdmi -endian little -work-area-size 0x4000 -work-area-phys 0x40000000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\nsoft_reset_halt\nmvb 0xE01FC040 0x01\n}\n\n\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/tools/firmware-recovery.tcl",
    "content": "echo \"\\n\\nFirmware recovery helpers\"\necho \"Use -c firmware_help to get help\\n\"\n\nset known_boards {\n    \"asus-rt-n16\t\tASUS RT-N16\"\n    \"asus-rt-n66u\t\tASUS RT-N66U\"\n    \"linksys-wag200g\t\tLinksys WAG200G\"\n    \"linksys-wrt54gl\t\tLinksys WRT54GL v1.1\"\n    \"netgear-dg834v3\t\tNetgear DG834G v3\"\n    \"tp-link_tl-mr3020\t\tTP-LINK TL-MR3020\"\n    \"bt-homehubv1\t\tBT HomeHub v1\"\n}\n\nproc firmware_help { } {\n    echo \"\nYour OpenOCD command should look like this:\nopenocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \\\"<commands>*; shutdown\\\"\n\nWhere:\n<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2\n<commands> are firmware-recovery commands separated by semicolon\n\nSupported commands:\nfirmware_help\t\t\tget this help\nlist_boards\t\t\tlist known boards and exit\nboard <name>\t\t\tselect board you work with\nlist_partitions\t\t\tlist partitions of the currently selected board\ndump_part <name> <filename>\tsave partition's contents to a file\nerase_part <name>\t\terase the given partition\nflash_part <name> <filename>\terase, flash and verify the given partition\nram_boot <filename>\t\tload binary file to RAM and run it\nadapter speed <freq>\t\tset JTAG clock frequency in kHz\n\nFor example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:\nopenocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\\\\n\t-c \\\"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\\\"\n\\n\\n\"\n    shutdown\n}\n\n# set default, can be overridden later\nadapter speed 1000\n\nproc get_partition { name } {\n    global partition_list\n    dict get $partition_list $name\n}\n\nproc partition_desc { name } { lindex [get_partition $name] 0 }\nproc partition_start { name } { lindex [get_partition $name] 1 }\nproc partition_size { name } { lindex [get_partition $name] 2 }\n\nproc list_boards { } {\n    global known_boards\n    echo \"List of the supported boards:\\n\"\n    echo \"Board name\\t\\tDescription\"\n    echo \"-----------------------------------\"\n    foreach i $known_boards {\n\techo $i\n    }\n    echo \"\\n\\n\"\n}\n\nproc board { name } {\n    script [find board/$name.cfg]\n}\n\nproc list_partitions { } {\n    global partition_list\n    set fstr \"%-16s%-14s%-14s%s\"\n    echo \"\\nThe currently selected board is known to have these partitions:\\n\"\n    echo [format $fstr Name Start Size Description]\n    echo \"-------------------------------------------------------\"\n    for {set i 0} {$i < [llength $partition_list]} {incr i 2} {\n\tset key [lindex $partition_list $i]\n\techo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]\n    }\n    echo \"\\n\\n\"\n}\n\n# Magic to work with any targets, including semi-functional\nproc prepare_target { } {\n    init\n    catch {halt}\n    catch {reset init}\n    catch {halt}\n}\n\nproc dump_part { name filename } {\n    prepare_target\n    dump_image $filename [partition_start $name] [partition_size $name]\n}\n\nproc erase_part { name } {\n    prepare_target\n    flash erase_address [partition_start $name] [partition_size $name]\n}\n\nproc flash_part { name filename } {\n    prepare_target\n    flash write_image erase $filename [partition_start $name] bin\n    echo \"Verifying:\"\n    verify_image $filename [partition_start $name]\n}\n\nproc ram_boot { filename } {\n    global ram_boot_address\n    prepare_target\n    load_image $filename $ram_boot_address bin\n    resume $ram_boot_address\n}\n\necho \"\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/tools/memtest.tcl",
    "content": "# Algorithms by Michael Barr, released into public domain\n# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser\n\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nsource [find bitsbytes.tcl]\nsource [find memory.tcl]\n\nproc runAllMemTests { baseAddress nBytes } {\n    memTestDataBus $baseAddress\n    memTestAddressBus $baseAddress $nBytes\n    memTestDevice $baseAddress $nBytes\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDataBus()\n# *\n# * Description: Test the data bus wiring in a memory region by\n# *              performing a walking 1's test at a fixed address\n# *              within that region.  The address (and hence the\n# *              memory region) is selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first pattern that failed.\n# *\n#***********************************************************************************\nproc memTestDataBus { address } {\n    echo \"Running memTestDataBus\"\n\n    for {set i 0} {$i < 32} {incr i} {\n\t# Shift bit\n\tset pattern [expr {1 << $i}]\n\n\t# Write pattern to memory\n\tmemwrite32 $address $pattern\n\n\t# Read pattern from memory\n\tset data [memread32 $address]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data\"\n\t    return $pattern\n\t}\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestAddressBus()\n# *\n# * Description: Perform a walking 1's test on the relevant bits\n# *              of the address and check for aliasing.  This test\n# *              will find single-bit address failures such as stuck\n# *              -high, stuck-low, and shorted pins.  The base address\n# *              and size of the region are selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# *\n# * Notes:       For best results, the selected base address should\n# *              have enough LSB 0's to guarantee single address bit\n# *              changes.  For example, to test a 64-Kbyte region,\n# *              select a base address on a 64-Kbyte boundary.  Also,\n# *              select the region size as a power-of-two--if at all\n# *              possible.\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              aliasing problem was uncovered.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestAddressBus { baseAddress nBytes } {\n    set addressMask [expr {$nBytes - 1}]\n    set pattern 0xAAAAAAAA\n    set antipattern 0x55555555\n\n    echo \"Running memTestAddressBus\"\n\n    echo \"addressMask: [convertToHex $addressMask]\"\n\n    echo \"memTestAddressBus: Writing the default pattern at each of the power-of-two offsets...\"\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {\n\tset addr [expr {$baseAddress + $offset}]\n\tmemwrite32 $addr $pattern\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck high...\"\n    memwrite32 $baseAddress $antipattern\n\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck low or shorted...\"\n    memwrite32 $baseAddress $pattern\n    for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $antipattern\n\n\tset data [memread32 $baseAddress]\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n\n\tfor {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\t    set addr [expr {$baseAddress + $offset}]\n\t    set data [memread32 $baseAddress]\n\n            if {(($data != $pattern) && ($offset != $testOffset))} {\n\t\techo \"FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]\"\n\t\treturn $pattern\n\t    }\n        }\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $pattern\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDevice()\n# *\n# * Description: Test the integrity of a physical memory device by\n# *              performing an increment/decrement test over the\n# *              entire region.  In the process every storage bit\n# *              in the device is tested as zero and as one.  The\n# *              base address and the size of the region are\n# *              selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              incorrect value was read back.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestDevice { baseAddress nBytes } {\n    echo \"Running memTestDevice\"\n\n    echo \"memTestDevice: Filling memory with a known pattern...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tmemwrite32 [expr {$baseAddress + $offset}] $pattern\n    }\n\n    echo \"memTestDevice: Checking each location and inverting it for the second pass...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]\"\n\t    return $pattern\n\t}\n\n\tset antiPattern [expr {~$pattern}]\n\tmemwrite32 [expr {$baseAddress + $offset}] $antiPattern\n    }\n\n    echo \"memTestDevice: Checking each location for the inverted pattern and zeroing it...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset antiPattern [expr {~$pattern & ((1<<32) - 1)}]\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\tset dataHex [convertToHex $data]\n\tset antiPatternHex [convertToHex $antiPattern]\n\tif {$dataHex != $antiPatternHex} {\n\t    echo \"FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset\"\n\t    return $pattern\n\t}\n    }\n}\n\nproc convertToHex { value } {\n    format 0x%08x $value\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/scripts/tools/test_cpu_speed.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Description:\n#  Measure the CPU clock frequency of an ARM Cortex-M based device.\n#\n# Return:\n#  The CPU clock frequency in Hz. A negative value indicates that the loop\n#  counter was saturated.\n#\n# Note:\n#  You may need to adapt the number of cycles for your device.\n#\nadd_help_text cortex_m_test_cpu_speed \"Measure the CPU clock frequency of an ARM Cortex-M based device\"\nadd_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}\nproc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {\n\tset loop_counter_start 0xffffffff\n\n\thalt\n\n\t# Backup registers and memory.\n\tset backup_regs [get_reg -force {pc r0 xPSR}]\n\tset backup_mem [read_memory $address 16 3]\n\n\t# We place the following code at the given address to measure the\n\t# CPU clock frequency:\n\t#\n\t# 3801: subs r0, #1\n\t# d1fd: bne #-2\n\t# e7fe: b #-4\n\twrite_memory $address 16 {0x3801 0xd1fd 0xe7fe}\n\n\tset_reg \"pc $address r0 $loop_counter_start\"\n\tresume\n\tsleep $timeout\n\thalt\n\n\t# Get the loop counter value from register r0.\n\tset loop_counter_end [dict values [get_reg r0]]\n\tset loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]\n\n\t# Restore registers and memory.\n\tset_reg $backup_regs\n\twrite_memory $address 16 $backup_mem\n\n\tif { [expr {$loop_counter_end == 0}] } {\n\t\treturn -1\n\t}\n\n\treturn [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/share/info/dir",
    "content": "This is the file .../info/dir, which contains the\ntopmost node of the Info hierarchy, called (dir)Top.\nThe first time you invoke Info you start off looking at this node.\n\u001f\nFile: dir,\tNode: Top\tThis is the top of the INFO tree\n\n  This (the Directory node) gives a menu of major topics.\n  Typing \"q\" exits, \"H\" lists all Info commands, \"d\" returns here,\n  \"h\" gives a primer for first-timers,\n  \"mEmacs<Return>\" visits the Emacs manual, etc.\n\n  In Emacs, you can click mouse button 2 on a menu item or cross reference\n  to select it.\n\n* Menu:\n\nDevelopment\n* OpenOCD: (openocd).           OpenOCD User's Guide\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/share/info/openocd.info",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nIndirect:\nopenocd.info-1: 986\nopenocd.info-2: 336375\n\u001f\nTag Table:\n(Indirect)\nNode: Top986\nNode: About3443\nNode: Developers7775\nNode: Debug Adapter Hardware11115\nNode: About Jim-Tcl23272\nNode: Running25417\nNode: OpenOCD Project Setup30813\nRef: OpenOCD Project Setup-Footnote-150765\nRef: OpenOCD Project Setup-Footnote-251105\nRef: OpenOCD Project Setup-Footnote-351373\nNode: Config File Guidelines51701\nRef: theinitboardprocedure62880\nRef: definecputargetsworkinginsmp69740\nRef: theinittargetsprocedure74220\nRef: theinittargeteventsprocedure76039\nRef: translatingconfigurationfiles77892\nRef: Config File Guidelines-Footnote-179143\nNode: Server Configuration79218\nRef: configurationstage79540\nRef: enteringtherunstage81015\nRef: tcpipports84468\nRef: gdb_port84963\nRef: gdbconfiguration87221\nRef: gdbbreakpointoverride87536\nRef: gdbflashprogram87905\nRef: eventpolling89384\nNode: Debug Adapter Configuration91816\nRef: adapter_usb_location94131\nRef: hla_interface122277\nRef: st_link_dap_interface123830\nRef: swimtransport148030\nRef: jtagspeed148797\nNode: Reset Configuration151759\nRef: srstandtrstissues154687\nRef: reset_config158869\nNode: TAP Declaration166781\nRef: enablinganddisablingtaps178689\nRef: autoprobing181336\nRef: dapdeclaration183991\nRef: dap_create184505\nRef: DAP subcommand apreg186750\nRef: TAP Declaration-Footnote-1189681\nNode: CPU Configuration189881\nRef: targettypes192775\nRef: targetconfiguration197095\nRef: rtostype202889\nRef: gdbportoverride204038\nRef: targetcurstate209063\nRef: targetevents211051\nNode: Flash Commands218097\nRef: norconfiguration219630\nRef: flashprogrammingcommands222867\nRef: flashprotect230643\nRef: program231465\nRef: flashdriverlist231745\nRef: at91samd251325\nRef: at91sam3255006\nRef: atsame5258360\nRef: nandconfiguration320278\nRef: nanddriverlist330660\nNode: Flash Programming336375\nNode: PLD/FPGA Commands337988\nNode: General Commands340152\nRef: debuglevel343120\nRef: targetstatehandling344425\nRef: resetcommand350250\nRef: memoryaccess352669\nRef: imageaccess354537\nNode: Architecture and Core Commands362228\nRef: armhardwaretracing362698\nRef: traceportdrivers370608\nRef: armcrosstrigger372339\nRef: arm9vectorcatch381733\nRef: xscalevectorcatch389604\nRef: add-reg-type-struct429891\nRef: softwaredebugmessagesandtracing436790\nNode: JTAG Commands440249\nNode: Boundary Scan Commands447727\nNode: Utility Commands453407\nNode: GDB and OpenOCD455252\nRef: programmingusinggdb460364\nRef: gdbmeminspect462010\nRef: gdbrtossupport463947\nRef: usingopenocdsmpwithgdb466389\nNode: Tcl Scripting API467063\nNode: FAQ470546\nRef: faqrtck470656\nRef: faqtaporder482547\nNode: Tcl Crash Course484313\nNode: License496321\nNode: OpenOCD Concept Index518733\nNode: Command and Driver Index542795\n\u001f\nEnd Tag Table\n\n\u001f\nLocal Variables:\ncoding: utf-8\nEnd:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/share/info/openocd.info-1",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nFile: openocd.info,  Node: Top,  Next: About,  Up: (dir)\n\nOpenOCD User's Guide\n********************\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\n\n* Menu:\n\n* About::                            About OpenOCD\n* Developers::                       OpenOCD Developer Resources\n* Debug Adapter Hardware::           Debug Adapter Hardware\n* About Jim-Tcl::                    About Jim-Tcl\n* Running::                          Running OpenOCD\n* OpenOCD Project Setup::            OpenOCD Project Setup\n* Config File Guidelines::           Config File Guidelines\n* Server Configuration::             Server Configuration\n* Debug Adapter Configuration::      Debug Adapter Configuration\n* Reset Configuration::              Reset Configuration\n* TAP Declaration::                  TAP Declaration\n* CPU Configuration::                CPU Configuration\n* Flash Commands::                   Flash Commands\n* Flash Programming::                Flash Programming\n* PLD/FPGA Commands::                PLD/FPGA Commands\n* General Commands::                 General Commands\n* Architecture and Core Commands::   Architecture and Core Commands\n* JTAG Commands::                    JTAG Commands\n* Boundary Scan Commands::           Boundary Scan Commands\n* Utility Commands::                 Utility Commands\n* GDB and OpenOCD::                  Using GDB and OpenOCD\n* Tcl Scripting API::                Tcl Scripting API\n* FAQ::                              Frequently Asked Questions\n* Tcl Crash Course::                 Tcl Crash Course\n* License::                          GNU Free Documentation License\n\n* OpenOCD Concept Index::            Concept Index\n* Command and Driver Index::         Command and Driver Index\n\n\u001f\nFile: openocd.info,  Node: About,  Next: Developers,  Prev: Top,  Up: Top\n\nAbout\n*****\n\nOpenOCD was created by Dominic Rath as part of a 2005 diploma thesis\nwritten at the University of Applied Sciences Augsburg\n(<http://www.hs-augsburg.de>).  Since that time, the project has grown\ninto an active open-source project, supported by a diverse community of\nsoftware and hardware developers from around the world.\n\nWhat is OpenOCD?\n================\n\nThe Open On-Chip Debugger (OpenOCD) aims to provide debugging, in-system\nprogramming and boundary-scan testing for embedded target devices.\n\nIt does so with the assistance of a \"debug adapter\", which is a small\nhardware module which helps provide the right kind of electrical\nsignaling to the target being debugged.  These are required since the\ndebug host (on which OpenOCD runs) won't usually have native support for\nsuch signaling, or the connector needed to hook up to the target.\n\nSuch debug adapters support one or more \"transport\" protocols, each of\nwhich involves different electrical signaling (and uses different\nmessaging protocols on top of that signaling).  There are many types of\ndebug adapter, and little uniformity in what they are called.  (There\nare also product naming differences.)\n\nThese adapters are sometimes packaged as discrete dongles, which may\ngenerically be called \"hardware interface dongles\".  Some development\nboards also integrate them directly, which may let the development board\nconnect directly to the debug host over USB (and sometimes also to power\nit over USB).\n\nFor example, a \"JTAG Adapter\" supports JTAG signaling, and is used to\ncommunicate with JTAG (IEEE 1149.1) compliant TAPs on your target board.\nA \"TAP\" is a \"Test Access Port\", a module which processes special\ninstructions and data.  TAPs are daisy-chained within and between chips\nand boards.  JTAG supports debugging and boundary scan operations.\n\nThere are also \"SWD Adapters\" that support Serial Wire Debug (SWD)\nsignaling to communicate with some newer ARM cores, as well as debug\nadapters which support both JTAG and SWD transports.  SWD supports only\ndebugging, whereas JTAG also supports boundary scan operations.\n\nFor some chips, there are also \"Programming Adapters\" supporting special\ntransports used only to write code to flash memory, without support for\non-chip debugging or boundary scan.  (At this writing, OpenOCD does not\nsupport such non-debug adapters.)\n\nDongles: OpenOCD currently supports many types of hardware dongles:\nUSB-based, parallel port-based, and other standalone boxes that run\nOpenOCD internally.  *Note Debug Adapter Hardware::.\n\nGDB Debug: It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T,\nARM922T, ARM926EJ-S, ARM966E-S), XScale (PXA25x, IXP42x), Cortex-M3\n(Stellaris LM3, STMicroelectronics STM32 and Energy Micro EFM32) and\nIntel Quark (x10xx) based cores to be debugged via the GDB protocol.\n\nFlash Programming: Flash writing is supported for external\nCFI-compatible NOR flashes (Intel and AMD/Spansion command set) and\nseveral internal flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7,\nAT91SAM3U, STR7x, STR9x, LM3, STM32x and EFM32).  Preliminary support\nfor various NAND flash controllers (LPC3180, Orion, S3C24xx, more) is\nincluded.\n\nOpenOCD Web Site\n================\n\nThe OpenOCD web site provides the latest public news from the community:\n\n<http://openocd.org/>\n\nLatest User's Guide:\n====================\n\nThe user's guide you are now reading may not be the latest one\navailable.  A version for more recent code may be available.  Its HTML\nform is published regularly at:\n\n<http://openocd.org/doc/html/index.html>\n\nPDF form is likewise published at:\n\n<http://openocd.org/doc/pdf/openocd.pdf>\n\nOpenOCD User's Forum\n====================\n\nThere is an OpenOCD forum (phpBB) hosted by SparkFun, which might be\nhelpful to you.  Note that if you want anything to come to the attention\nof developers, you should post it to the OpenOCD Developer Mailing List\ninstead of this forum.\n\n<http://forum.sparkfun.com/viewforum.php?f=18>\n\nOpenOCD User's Mailing List\n===========================\n\nThe OpenOCD User Mailing List provides the primary means of\ncommunication between users:\n\n<https://lists.sourceforge.net/mailman/listinfo/openocd-user>\n\nOpenOCD IRC\n===========\n\nSupport can also be found on irc: <irc://irc.libera.chat/openocd>\n\n\u001f\nFile: openocd.info,  Node: Developers,  Next: Debug Adapter Hardware,  Prev: About,  Up: Top\n\n1 OpenOCD Developer Resources\n*****************************\n\nIf you are interested in improving the state of OpenOCD's debugging and\ntesting support, new contributions will be welcome.  Motivated\ndevelopers can produce new target, flash or interface drivers, improve\nthe documentation, as well as more conventional bug fixes and\nenhancements.\n\nThe resources in this chapter are available for developers wishing to\nexplore or expand the OpenOCD source code.\n\n1.1 OpenOCD Git Repository\n==========================\n\nDuring the 0.3.x release cycle, OpenOCD switched from Subversion to a\nGit repository hosted at SourceForge.  The repository URL is:\n\n<git://git.code.sf.net/p/openocd/code>\n\nor via http\n\n<http://git.code.sf.net/p/openocd/code>\n\nYou may prefer to use a mirror and the HTTP protocol:\n\n<http://repo.or.cz/r/openocd.git>\n\nWith standard Git tools, use 'git clone' to initialize a local\nrepository, and 'git pull' to update it.  There are also gitweb pages\nletting you browse the repository with a web browser, or download\narbitrary snapshots without needing a Git client:\n\n<http://repo.or.cz/w/openocd.git>\n\nThe 'README' file contains the instructions for building the project\nfrom the repository or a snapshot.\n\nDevelopers that want to contribute patches to the OpenOCD system are\nstrongly encouraged to work against mainline.  Patches created against\nolder versions may require additional work from their submitter in order\nto be updated for newer releases.\n\n1.2 Doxygen Developer Manual\n============================\n\nDuring the 0.2.x release cycle, the OpenOCD project began providing a\nDoxygen reference manual.  This document contains more technical\ninformation about the software internals, development processes, and\nsimilar documentation:\n\n<http://openocd.org/doc/doxygen/html/index.html>\n\nThis document is a work-in-progress, but contributions would be welcome\nto fill in the gaps.  All of the source files are provided in-tree,\nlisted in the Doxyfile configuration at the top of the source tree.\n\n1.3 Gerrit Review System\n========================\n\nAll changes in the OpenOCD Git repository go through the web-based\nGerrit Code Review System:\n\n<https://review.openocd.org/>\n\nAfter a one-time registration and repository setup, anyone can push\ncommits from their local Git repository directly into Gerrit.  All users\nand developers are encouraged to review, test, discuss and vote for\nchanges in Gerrit.  The feedback provides the basis for a maintainer to\neventually submit the change to the main Git repository.\n\nThe 'HACKING' file, also available as the Patch Guide in the Doxygen\nDeveloper Manual, contains basic information about how to connect a\nrepository to Gerrit, prepare and push patches.  Patch authors are\nexpected to maintain their changes while they're in Gerrit, respond to\nfeedback and if necessary rework and push improved versions of the\nchange.\n\n1.4 OpenOCD Developer Mailing List\n==================================\n\nThe OpenOCD Developer Mailing List provides the primary means of\ncommunication between developers:\n\n<https://lists.sourceforge.net/mailman/listinfo/openocd-devel>\n\n1.5 OpenOCD Bug Tracker\n=======================\n\nThe OpenOCD Bug Tracker is hosted on SourceForge:\n\n<http://bugs.openocd.org/>\n\n\u001f\nFile: openocd.info,  Node: Debug Adapter Hardware,  Next: About Jim-Tcl,  Prev: Developers,  Up: Top\n\n2 Debug Adapter Hardware\n************************\n\nDefined: dongle: A small device that plugs into a computer and serves as\nan adapter ....  [snip]\n\nIn the OpenOCD case, this generally refers to a small adapter that\nattaches to your computer via USB or the parallel port.\n\n2.1 Choosing a Dongle\n=====================\n\nThere are several things you should keep in mind when choosing a dongle.\n\n  1. Transport Does it support the kind of communication that you need?\n     OpenOCD focuses mostly on JTAG. Your version may also support other\n     ways to communicate with target devices.\n  2. Voltage What voltage is your target - 1.8, 2.8, 3.3, or 5V? Does\n     your dongle support it?  You might need a level converter.\n  3. Pinout What pinout does your target board use?  Does your dongle\n     support it?  You may be able to use jumper wires, or an \"octopus\"\n     connector, to convert pinouts.\n  4. Connection Does your computer have the USB, parallel, or Ethernet\n     port needed?\n  5. RTCK Do you expect to use it with ARM chips and boards with RTCK\n     support (also known as \"adaptive clocking\")?\n\n2.2 USB FT2232 Based\n====================\n\nThere are many USB JTAG dongles on the market, many of them based on a\nchip from \"Future Technology Devices International\" (FTDI) known as the\nFTDI FT2232; this is a USB full speed (12 Mbps) chip.  See:\n<http://www.ftdichip.com> for more information.  In summer 2009, USB\nhigh speed (480 Mbps) versions of these FTDI chips started to become\navailable in JTAG adapters.  Around 2012, a new variant appeared -\nFT232H - this is a single-channel version of FT2232H. (Adapters using\nthose high speed FT2232H or FT232H chips may support adaptive clocking.)\n\nThe FT2232 chips are flexible enough to support some other transport\noptions, such as SWD or the SPI variants used to program some chips.\nThey have two communications channels, and one can be used for a UART\nadapter at the same time the other one is used to provide a debug\nadapter.\n\nAlso, some development boards integrate an FT2232 chip to serve as a\nbuilt-in low-cost debug adapter and USB-to-serial solution.\n\n   * usbjtag\n     Link\n     <http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html>\n   * jtagkey\n     See: <http://www.amontec.com/jtagkey.shtml>\n   * jtagkey2\n     See: <http://www.amontec.com/jtagkey2.shtml>\n   * oocdlink\n     See: <http://www.oocdlink.com> By Joern Kaipf\n   * signalyzer\n     See: <http://www.signalyzer.com>\n   * Stellaris Eval Boards\n     See: <http://www.ti.com> - The Stellaris eval boards bundle\n     FT2232-based JTAG and SWD support, which can be used to debug the\n     Stellaris chips.  Using separate JTAG adapters is optional.  These\n     boards can also be used in a \"pass through\" mode as JTAG adapters\n     to other target boards, disabling the Stellaris chip.\n   * TI/Luminary ICDI\n     See: <http://www.ti.com> - TI/Luminary In-Circuit Debug Interface\n     (ICDI) Boards are included in Stellaris LM3S9B9x Evaluation Kits.\n     Like the non-detachable FT2232 support on the other Stellaris eval\n     boards, they can be used to debug other target boards.\n   * olimex-jtag\n     See: <http://www.olimex.com>\n   * Flyswatter/Flyswatter2\n     See: <http://www.tincantools.com>\n   * turtelizer2\n     See: Turtelizer 2\n     (http://www.ethernut.de/en/hardware/turtelizer/index.html), or\n     <http://www.ethernut.de>\n   * comstick\n     Link: <http://www.hitex.com/index.php?id=383>\n   * stm32stick\n     Link <http://www.hitex.com/stm32-stick>\n   * axm0432_jtag\n     Axiom AXM-0432 Link <http://www.axman.com> - NOTE: This JTAG does\n     not appear to be available anymore as of April 2012.\n   * cortino\n     Link <http://www.hitex.com/index.php?id=cortino>\n   * dlp-usb1232h\n     Link <http://www.dlpdesign.com/usb/usb1232h.shtml>\n   * digilent-hs1\n     Link <http://www.digilentinc.com/Products/Detail.cfm?Prod=JTAG-HS1>\n   * opendous\n     Link <http://code.google.com/p/opendous/wiki/JTAG> FT2232H-based\n     (OpenHardware).\n   * JTAG-lock-pick Tiny 2\n     Link <http://www.distortec.com/jtag-lock-pick-tiny-2> FT232H-based\n\n   * GW16042\n     Link:\n     <http://shop.gateworks.com/index.php?route=product/product&path=70_80&product_id=64>\n     FT2232H-based\n\n2.3 USB-JTAG / Altera USB-Blaster compatibles\n=============================================\n\nThese devices also show up as FTDI devices, but are not\nprotocol-compatible with the FT2232 devices.  They are, however,\nprotocol-compatible among themselves.  USB-JTAG devices typically\nconsist of a FT245 followed by a CPLD that understands a particular\nprotocol, or emulates this protocol using some other hardware.\n\nThey may appear under different USB VID/PID depending on the particular\nproduct.  The driver can be configured to search for any VID/PID pair\n(see the section on driver commands).\n\n   * USB-JTAG Kolja Waschk's USB Blaster-compatible adapter\n     Link: <http://ixo-jtag.sourceforge.net/>\n   * Altera USB-Blaster\n     Link: <http://www.altera.com/literature/ug/ug_usb_blstr.pdf>\n\n2.4 USB J-Link based\n====================\n\nThere are several OEM versions of the SEGGER J-Link adapter.  It is an\nexample of a microcontroller based JTAG adapter, it uses an AT91SAM764\ninternally.\n\n   * SEGGER J-Link\n     Link: <http://www.segger.com/jlink.html>\n   * Atmel SAM-ICE (Only works with Atmel chips!)\n     Link: <http://www.atmel.com/tools/atmelsam-ice.aspx>\n   * IAR J-Link\n\n2.5 USB RLINK based\n===================\n\nRaisonance has an adapter called RLink.  It exists in a stripped-down\nform on the STM32 Primer, permanently attached to the JTAG lines.  It\nalso exists on the STM32 Primer2, but that is wired for SWD and not\nJTAG, thus not supported.\n\n   * Raisonance RLink\n     Link:\n     <http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html>\n   * STM32 Primer\n     Link: <http://www.stm32circle.com/resources/stm32primer.php>\n   * STM32 Primer2\n     Link: <http://www.stm32circle.com/resources/stm32primer2.php>\n\n2.6 USB ST-LINK based\n=====================\n\nSTMicroelectronics has an adapter called ST-LINK. They only work with\nSTMicroelectronics chips, notably STM32 and STM8.\n\n   * ST-LINK\n     This is available standalone and as part of some kits, eg.\n     STM32VLDISCOVERY.\n     Link: <http://www.st.com/internet/evalboard/product/219866.jsp>\n   * ST-LINK/V2\n     This is available standalone and as part of some kits, eg.\n     STM32F4DISCOVERY.\n     Link: <http://www.st.com/internet/evalboard/product/251168.jsp>\n   * STLINK-V3\n     This is available standalone and as part of some kits.\n     Link: <http://www.st.com/stlink-v3>\n\nFor info the original ST-LINK enumerates using the mass storage usb\nclass; however, its implementation is completely broken.  The result is\nthis causes issues under Linux.  The simplest solution is to get Linux\nto ignore the ST-LINK using one of the following methods:\n   * modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n   * add \"options usb-storage quirks=483:3744:i\" to /etc/modprobe.conf\n\n2.7 USB TI/Stellaris ICDI based\n===============================\n\nTexas Instruments has an adapter called ICDI. It is not to be confused\nwith the FTDI based adapters that were originally fitted to their\nevaluation boards.  This is the adapter fitted to the Stellaris\nLaunchPad.\n\n2.8 USB Nuvoton Nu-Link\n=======================\n\nNuvoton has an adapter called Nu-Link.  It is available either as\nstand-alone dongle and embedded on development boards.  It supports SWD,\nserial port bridge and mass storage for firmware update.  Both Nu-Link\nv1 and v2 are supported.\n\n2.9 USB CMSIS-DAP based\n=======================\n\nARM has released a interface standard called CMSIS-DAP that simplifies\nconnecting debuggers to ARM Cortex based targets\n<http://www.keil.com/support/man/docs/dapdebug/dapdebug_introduction.htm>.\n\n2.10 USB Other\n==============\n\n   * USBprog\n     Link: <http://shop.embedded-projects.net/> - which uses an Atmel\n     MEGA32 and a UBN9604\n\n   * USB - Presto\n     Link: <http://tools.asix.net/prg_presto.htm>\n\n   * Versaloon-Link\n     Link: <http://www.versaloon.com>\n\n   * ARM-JTAG-EW\n     Link: <http://www.olimex.com/dev/arm-jtag-ew.html>\n\n   * Buspirate\n     Link: <http://dangerousprototypes.com/bus-pirate-manual/>\n\n   * opendous\n     Link: <http://code.google.com/p/opendous-jtag/> - which uses an\n     AT90USB162\n\n   * estick\n     Link: <http://code.google.com/p/estick-jtag/>\n\n   * Keil ULINK v1\n     Link: <http://www.keil.com/ulink1/>\n\n   * TI XDS110 Debug Probe\n     Link:\n     <https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds110.html>\n\n     Link:\n     <https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html#xds110-support-utilities>\n\n2.11 IBM PC Parallel Printer Port Based\n=======================================\n\nThe two well-known \"JTAG Parallel Ports\" cables are the Xilinx DLC5 and\nthe Macraigor Wiggler.  There are many clones and variations of these on\nthe market.\n\nNote that parallel ports are becoming much less common, so if you have\nthe choice you should probably avoid these adapters in favor of\nUSB-based ones.\n\n   * Wiggler - There are many clones of this.\n     Link: <http://www.macraigor.com/wiggler.htm>\n\n   * DLC5 - From XILINX - There are many clones of this\n     Link: Search the web for: \"XILINX DLC5\" - it is no longer produced,\n     PDF schematics are easily found and it is easy to make.\n\n   * Amontec - JTAG Accelerator\n     Link: <http://www.amontec.com/jtag_accelerator.shtml>\n\n   * Wiggler2\n     Link:\n     <http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag>\n\n   * Wiggler_ntrst_inverted\n     Yet another variation - See the source code, src/jtag/parport.c\n\n   * old_amt_wiggler\n     Unknown - probably not on the market today\n\n   * arm-jtag\n     Link: Most likely <http://www.olimex.com/dev/arm-jtag.html>\n     [another wiggler clone]\n\n   * chameleon\n     Link: <http://www.amontec.com/chameleon.shtml>\n\n   * Triton\n     Unknown.\n\n   * Lattice\n     ispDownload from Lattice Semiconductor\n     <http://www.latticesemi.com/lit/docs/devtools/dlcable.pdf>\n\n   * flashlink\n     From STMicroelectronics;\n     Link:\n     <http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/DM00039500.pdf>\n\n2.12 Other...\n=============\n\n   * ep93xx\n     An EP93xx based Linux machine using the GPIO pins directly.\n\n   * at91rm9200\n     Like the EP93xx - but an ATMEL AT91RM9200 based solution using the\n     GPIO pins on the chip.\n\n   * bcm2835gpio\n     A BCM2835-based board (e.g.  Raspberry Pi) using the GPIO pins of\n     the expansion header.\n\n   * imx_gpio\n     A NXP i.MX-based board (e.g.  Wandboard) using the GPIO pins\n     (should work on any i.MX processor).\n\n   * am335xgpio\n     A Texas Instruments AM335x-based board (e.g.  BeagleBone Black)\n     using the GPIO pins of the expansion headers.\n\n   * jtag_vpi\n     A JTAG driver acting as a client for the JTAG VPI server interface.\n\n     Link: <http://github.com/fjullien/jtag_vpi>\n\n   * vdebug\n     A driver for Cadence virtual Debug Interface to emulated or\n     simulated targets.  It implements a client connecting to the vdebug\n     server, which in turn communicates with the emulated or simulated\n     RTL model through a transactor.  The current version supports only\n     JTAG as a transport, but other virtual transports, like DAP are\n     planned.\n\n   * jtag_dpi\n     A JTAG driver acting as a client for the SystemVerilog Direct\n     Programming Interface (DPI) for JTAG devices.  DPI allows OpenOCD\n     to connect to the JTAG interface of a hardware model written in\n     SystemVerilog, for example, on an emulation model of target\n     hardware.\n\n   * xlnx_pcie_xvc\n     A JTAG driver exposing Xilinx Virtual Cable over PCI Express to\n     OpenOCD as JTAG/SWD interface.\n\n   * linuxgpiod\n     A bitbang JTAG driver using Linux GPIO through library libgpiod.\n\n   * sysfsgpio\n     A bitbang JTAG driver using Linux legacy sysfs GPIO. This is\n     deprecated from Linux v5.3; prefer using linuxgpiod.\n\n\u001f\nFile: openocd.info,  Node: About Jim-Tcl,  Next: Running,  Prev: Debug Adapter Hardware,  Up: Top\n\n3 About Jim-Tcl\n***************\n\nOpenOCD uses a small \"Tcl Interpreter\" known as Jim-Tcl.  This\nprogramming language provides a simple and extensible command\ninterpreter.\n\nAll commands presented in this Guide are extensions to Jim-Tcl.  You can\nuse them as simple commands, without needing to learn much of anything\nabout Tcl.  Alternatively, you can write Tcl programs with them.\n\nYou can learn more about Jim at its website, <http://jim.tcl.tk>.  There\nis an active and responsive community, get on the mailing list if you\nhave any questions.  Jim-Tcl maintainers also lurk on the OpenOCD\nmailing list.\n\n   * Jim vs.  Tcl\n     Jim-Tcl is a stripped down version of the well known Tcl language,\n     which can be found here: <http://www.tcl.tk>.  Jim-Tcl has far\n     fewer features.  Jim-Tcl is several dozens of .C files and .H files\n     and implements the basic Tcl command set.  In contrast: Tcl 8.6 is\n     a 4.2 MB .zip file containing 1540 files.\n\n   * Missing Features\n     Our practice has been: Add/clone the real Tcl feature if/when\n     needed.  We welcome Jim-Tcl improvements, not bloat.  Also there\n     are a large number of optional Jim-Tcl features that are not\n     enabled in OpenOCD.\n\n   * Scripts\n     OpenOCD configuration scripts are Jim-Tcl Scripts.  OpenOCD's\n     command interpreter today is a mixture of (newer) Jim-Tcl commands,\n     and the (older) original command interpreter.\n\n   * Commands\n     At the OpenOCD telnet command line (or via the GDB monitor command)\n     one can type a Tcl for() loop, set variables, etc.  Some of the\n     commands documented in this guide are implemented as Tcl scripts,\n     from a 'startup.tcl' file internal to the server.\n\n   * Historical Note\n     Jim-Tcl was introduced to OpenOCD in spring 2008.  Fall 2010,\n     before OpenOCD 0.5 release, OpenOCD switched to using Jim-Tcl as a\n     Git submodule, which greatly simplified upgrading Jim-Tcl to\n     benefit from new features and bugfixes in Jim-Tcl.\n\n   * Need a crash course in Tcl?\n     *Note Tcl Crash Course::.\n\n\u001f\nFile: openocd.info,  Node: Running,  Next: OpenOCD Project Setup,  Prev: About Jim-Tcl,  Up: Top\n\n4 Running\n*********\n\nProperly installing OpenOCD sets up your operating system to grant it\naccess to the debug adapters.  On Linux, this usually involves\ninstalling a file in '/etc/udev/rules.d,' so OpenOCD has permissions.\nAn example rules file that works for many common adapters is shipped\nwith OpenOCD in the 'contrib' directory.  MS-Windows needs complex and\nconfusing driver configuration for every peripheral.  Such issues are\nunique to each operating system, and are not detailed in this User's\nGuide.\n\nThen later you will invoke the OpenOCD server, with various options to\ntell it how each debug session should work.  The '--help' option shows:\nbash$ openocd --help\n\n--help       | -h       display this help\n--version    | -v       display OpenOCD version\n--file       | -f       use configuration file <name>\n--search     | -s       dir to search for config files and scripts\n--debug      | -d       set debug level to 3\n             | -d<n>    set debug level to <level>\n--log_output | -l       redirect log output to file <name>\n--command    | -c       run <command>\n\nIf you don't give any '-f' or '-c' options, OpenOCD tries to read the\nconfiguration file 'openocd.cfg'.  To specify one or more different\nconfiguration files, use '-f' options.  For example:\n\n     openocd -f config1.cfg -f config2.cfg -f config3.cfg\n\nConfiguration files and scripts are searched for in\n  1. the current directory,\n  2. any search dir specified on the command line using the '-s' option,\n  3. any search dir specified using the 'add_script_search_dir' command,\n  4. a directory in the 'OPENOCD_SCRIPTS' environment variable (if set),\n  5. '%APPDATA%/OpenOCD' (only on Windows),\n  6. '$HOME/Library/Preferences/org.openocd' (only on Darwin),\n  7. '$XDG_CONFIG_HOME/openocd' ('$XDG_CONFIG_HOME' defaults to\n     '$HOME/.config'),\n  8. '$HOME/.openocd',\n  9. the site wide script library '$pkgdatadir/site' and\n  10. the OpenOCD-supplied script library '$pkgdatadir/scripts'.\nThe first found file with a matching file name will be used.\n\n     Note: Don't try to use configuration script names or paths which\n     include the \"#\" character.  That character begins Tcl comments.\n\n4.1 Simple setup, no customization\n==================================\n\nIn the best case, you can use two scripts from one of the script\nlibraries, hook up your JTAG adapter, and start the server ...  and your\nJTAG setup will just work \"out of the box\".  Always try to start by\nreusing those scripts, but assume you'll need more customization even if\nthis works.  *Note OpenOCD Project Setup::.\n\nIf you find a script for your JTAG adapter, and for your board or\ntarget, you may be able to hook up your JTAG adapter then start the\nserver with some variation of one of the following:\n\n     openocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg\n     openocd -f interface/ftdi/ADAPTER.cfg -f board/MYBOARD.cfg\n\nYou might also need to configure which reset signals are present, using\n'-c 'reset_config trst_and_srst'' or something similar.  If all goes\nwell you'll see output something like\n\n     Open On-Chip Debugger 0.4.0 (2010-01-14-15:06)\n     For bug reports, read\n             http://openocd.org/doc/doxygen/bugs.html\n     Info : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477\n            (mfg: 0x23b, part: 0xba00, ver: 0x3)\n\nSeeing that \"tap/device found\" message, and no warnings, means the JTAG\ncommunication is working.  That's a key milestone, but you'll probably\nneed more project-specific setup.\n\n4.2 What OpenOCD does as it starts\n==================================\n\nOpenOCD starts by processing the configuration commands provided on the\ncommand line or, if there were no '-c command' or '-f file.cfg' options\ngiven, in 'openocd.cfg'.  *Note Configuration Stage: configurationstage.\nAt the end of the configuration stage it verifies the JTAG scan chain\ndefined using those commands; your configuration should ensure that this\nalways succeeds.  Normally, OpenOCD then starts running as a server.\nAlternatively, commands may be used to terminate the configuration stage\nearly, perform work (such as updating some flash memory), and then shut\ndown without acting as a server.\n\nOnce OpenOCD starts running as a server, it waits for connections from\nclients (Telnet, GDB, RPC) and processes the commands issued through\nthose channels.\n\nIf you are having problems, you can enable internal debug messages via\nthe '-d' option.\n\nAlso it is possible to interleave Jim-Tcl commands w/config scripts\nusing the '-c' command line switch.\n\nTo enable debug output (when reporting problems or working on OpenOCD\nitself), use the '-d' command line switch.  This sets the 'debug_level'\nto \"3\", outputting the most information, including debug messages.  The\ndefault setting is \"2\", outputting only informational messages, warnings\nand errors.  You can also change this setting from within a telnet or\ngdb session using 'debug_level<n>' (*note debug_level: debuglevel.).\n\nYou can redirect all output from the server to a file using the '-l\n<logfile>' switch.\n\nNote!  OpenOCD will launch the GDB & telnet server even if it can not\nestablish a connection with the target.  In general, it is possible for\nthe JTAG controller to be unresponsive until the target is set up\ncorrectly via e.g.  GDB monitor commands in a GDB init script.\n\n\u001f\nFile: openocd.info,  Node: OpenOCD Project Setup,  Next: Config File Guidelines,  Prev: Running,  Up: Top\n\n5 OpenOCD Project Setup\n***********************\n\nTo use OpenOCD with your development projects, you need to do more than\njust connect the JTAG adapter hardware (dongle) to your development\nboard and start the OpenOCD server.  You also need to configure your\nOpenOCD server so that it knows about your adapter and board, and helps\nyour work.  You may also want to connect OpenOCD to GDB, possibly using\nEclipse or some other GUI.\n\n5.1 Hooking up the JTAG Adapter\n===============================\n\nToday's most common case is a dongle with a JTAG cable on one side (such\nas a ribbon cable with a 10-pin or 20-pin IDC connector) and a USB cable\non the other.  Instead of USB, some dongles use Ethernet; older ones may\nuse a PC parallel port, or even a serial port.\n\n  1. _Start with power to your target board turned off_, and nothing\n     connected to your JTAG adapter.  If you're particularly paranoid,\n     unplug power to the board.  It's important to have the ground\n     signal properly set up, unless you are using a JTAG adapter which\n     provides galvanic isolation between the target board and the\n     debugging host.\n\n  2. _Be sure it's the right kind of JTAG connector._  If your dongle\n     has a 20-pin ARM connector, you need some kind of adapter (or\n     octopus, see below) to hook it up to boards using 14-pin or 10-pin\n     connectors ...  or to 20-pin connectors which don't use ARM's\n     pinout.\n\n     In the same vein, make sure the voltage levels are compatible.  Not\n     all JTAG adapters have the level shifters needed to work with 1.2\n     Volt boards.\n\n  3. _Be certain the cable is properly oriented_ or you might damage\n     your board.  In most cases there are only two possible ways to\n     connect the cable.  Connect the JTAG cable from your adapter to the\n     board.  Be sure it's firmly connected.\n\n     In the best case, the connector is keyed to physically prevent you\n     from inserting it wrong.  This is most often done using a slot on\n     the board's male connector housing, which must match a key on the\n     JTAG cable's female connector.  If there's no housing, then you\n     must look carefully and make sure pin 1 on the cable hooks up to\n     pin 1 on the board.  Ribbon cables are frequently all grey except\n     for a wire on one edge, which is red.  The red wire is pin 1.\n\n     Sometimes dongles provide cables where one end is an \"octopus\" of\n     color coded single-wire connectors, instead of a connector block.\n     These are great when converting from one JTAG pinout to another,\n     but are tedious to set up.  Use these with connector pinout\n     diagrams to help you match up the adapter signals to the right\n     board pins.\n\n  4. _Connect the adapter's other end_ once the JTAG cable is connected.\n     A USB, parallel, or serial port connector will go to the host which\n     you are using to run OpenOCD. For Ethernet, consult the\n     documentation and your network administrator.\n\n     For USB-based JTAG adapters you have an easy sanity check at this\n     point: does the host operating system see the JTAG adapter?  If\n     you're running Linux, try the 'lsusb' command.  If that host is an\n     MS-Windows host, you'll need to install a driver before OpenOCD\n     works.\n\n  5. _Connect the adapter's power supply, if needed._  This step is\n     primarily for non-USB adapters, but sometimes USB adapters need\n     extra power.\n\n  6. _Power up the target board._  Unless you just let the magic smoke\n     escape, you're now ready to set up the OpenOCD server so you can\n     use JTAG to work with that board.\n\nTalk with the OpenOCD server using telnet ('telnet localhost 4444' on\nmany systems) or GDB. *Note GDB and OpenOCD::.\n\n5.2 Project Directory\n=====================\n\nThere are many ways you can configure OpenOCD and start it up.\n\nA simple way to organize them all involves keeping a single directory\nfor your work with a given board.  When you start OpenOCD from that\ndirectory, it searches there first for configuration files, scripts,\nfiles accessed through semihosting, and for code you upload to the\ntarget board.  It is also the natural place to write files, such as log\nfiles and data you download from the board.\n\n5.3 Configuration Basics\n========================\n\nThere are two basic ways of configuring OpenOCD, and a variety of ways\nyou can mix them.  Think of the difference as just being how you start\nthe server:\n\n   * Many '-f file' or '-c command' options on the command line\n   * No options, but a \"user config file\" in the current directory named\n     'openocd.cfg'\n\nHere is an example 'openocd.cfg' file for a setup using a Signalyzer\nFT2232-based JTAG adapter to talk to a board with an Atmel AT91SAM7X256\nmicrocontroller:\n\n     source [find interface/ftdi/signalyzer.cfg]\n\n     # GDB can also flash my flash!\n     gdb_memory_map enable\n     gdb_flash_program enable\n\n     source [find target/sam7x256.cfg]\n\nHere is the command line equivalent of that configuration:\n\n     openocd -f interface/ftdi/signalyzer.cfg \\\n             -c \"gdb_memory_map enable\" \\\n             -c \"gdb_flash_program enable\" \\\n             -f target/sam7x256.cfg\n\nYou could wrap such long command lines in shell scripts, each supporting\na different development task.  One might re-flash the board with a\nspecific firmware version.  Another might set up a particular debugging\nor run-time environment.\n\n     Important: At this writing (October 2009) the command line method\n     has problems with how it treats variables.  For example, after '-c\n     \"set VAR value\"', or doing the same in a script, the variable VAR\n     will have no value that can be tested in a later script.\n\nHere we will focus on the simpler solution: one user config file,\nincluding basic configuration plus any TCL procedures to simplify your\nwork.\n\n5.4 User Config Files\n=====================\n\nA user configuration file ties together all the parts of a project in\none place.  One of the following will match your situation best:\n\n   * Ideally almost everything comes from configuration files provided\n     by someone else.  For example, OpenOCD distributes a 'scripts'\n     directory (probably in '/usr/share/openocd/scripts' on Linux).\n     Board and tool vendors can provide these too, as can individual\n     user sites; the '-s' command line option lets you say where to find\n     these files.  (*Note Running::.)  The AT91SAM7X256 example above\n     works this way.\n\n     Three main types of non-user configuration file each have their own\n     subdirectory in the 'scripts' directory:\n\n       1. interface - one for each different debug adapter;\n       2. board - one for each different board\n       3. target - the chips which integrate CPUs and other JTAG TAPs\n\n     Best case: include just two files, and they handle everything else.\n     The first is an interface config file.  The second is\n     board-specific, and it sets up the JTAG TAPs and their GDB targets\n     (by deferring to some 'target.cfg' file), declares all flash\n     memory, and leaves you nothing to do except meet your deadline:\n\n          source [find interface/olimex-jtag-tiny.cfg]\n          source [find board/csb337.cfg]\n\n     Boards with a single microcontroller often won't need more than the\n     target config file, as in the AT91SAM7X256 example.  That's because\n     there is no external memory (flash, DDR RAM), and the board\n     differences are encapsulated by application code.\n\n   * Maybe you don't know yet what your board looks like to JTAG. Once\n     you know the 'interface.cfg' file to use, you may need help from\n     OpenOCD to discover what's on the board.  Once you find the JTAG\n     TAPs, you can just search for appropriate target and board\n     configuration files ...  or write your own, from the bottom up.\n     *Note Autoprobing: autoprobing.\n\n   * You can often reuse some standard config files but need to write a\n     few new ones, probably a 'board.cfg' file.  You will be using\n     commands described later in this User's Guide, and working with the\n     guidelines in the next chapter.\n\n     For example, there may be configuration files for your JTAG adapter\n     and target chip, but you need a new board-specific config file\n     giving access to your particular flash chips.  Or you might need to\n     write another target chip configuration file for a new chip built\n     around the Cortex-M3 core.\n\n          Note: When you write new configuration files, please submit\n          them for inclusion in the next OpenOCD release.  For example,\n          a 'board/newboard.cfg' file will help the next users of that\n          board, and a 'target/newcpu.cfg' will help support users of\n          any board using that chip.\n\n   * You may need to write some C code.  It may be as simple as\n     supporting a new FT2232 or parport based adapter; a bit more\n     involved, like a NAND or NOR flash controller driver; or a big\n     piece of work like supporting a new chip architecture.\n\nReuse the existing config files when you can.  Look first in the\n'scripts/boards' area, then 'scripts/targets'.  You may find a board\nconfiguration that's a good example to follow.\n\nWhen you write config files, separate the reusable parts (things every\nuser of that interface, chip, or board needs) from ones specific to your\nenvironment and debugging approach.\n\n   * For example, a 'gdb-attach' event handler that invokes the 'reset\n     init' command will interfere with debugging early boot code, which\n     performs some of the same actions that the 'reset-init' event\n     handler does.\n\n   * Likewise, the 'arm9 vector_catch' command (or its siblings 'xscale\n     vector_catch' and 'cortex_m vector_catch') can be a time-saver\n     during some debug sessions, but don't make everyone use that\n     either.  Keep those kinds of debugging aids in your user config\n     file, along with messaging and tracing setup.  (*Note Software\n     Debug Messages and Tracing: softwaredebugmessagesandtracing.)\n\n   * You might need to override some defaults.  For example, you might\n     need to move, shrink, or back up the target's work area if your\n     application needs much SRAM.\n\n   * TCP/IP port configuration is another example of something which is\n     environment-specific, and should only appear in a user config file.\n     *Note TCP/IP Ports: tcpipports.\n\n5.5 Project-Specific Utilities\n==============================\n\nA few project-specific utility routines may well speed up your work.\nWrite them, and keep them in your project's user config file.\n\nFor example, if you are making a boot loader work on a board, it's nice\nto be able to debug the \"after it's loaded to RAM\" parts separately from\nthe finicky early code which sets up the DDR RAM controller and clocks.\nA script like this one, or a more GDB-aware sibling, may help:\n\n     proc ramboot { } {\n         # Reset, running the target's \"reset-init\" scripts\n         # to initialize clocks and the DDR RAM controller.\n         # Leave the CPU halted.\n         reset init\n\n         # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM.\n         load_image u-boot.bin 0x20000000\n\n         # Start running.\n         resume 0x20000000\n     }\n\nThen once that code is working you will need to make it boot from NOR\nflash; a different utility would help.  Alternatively, some developers\nwrite to flash using GDB. (You might use a similar script if you're\nworking with a flash based microcontroller application instead of a boot\nloader.)\n\n     proc newboot { } {\n         # Reset, leaving the CPU halted. The \"reset-init\" event\n         # proc gives faster access to the CPU and to NOR flash;\n         # \"reset halt\" would be slower.\n         reset init\n\n         # Write standard version of U-Boot into the first two\n         # sectors of NOR flash ... the standard version should\n         # do the same lowlevel init as \"reset-init\".\n         flash protect 0 0 1 off\n         flash erase_sector 0 0 1\n         flash write_bank 0 u-boot.bin 0x0\n         flash protect 0 0 1 on\n\n         # Reboot from scratch using that new boot loader.\n         reset run\n     }\n\nYou may need more complicated utility procedures when booting from NAND.\nThat often involves an extra bootloader stage, running from on-chip SRAM\nto perform DDR RAM setup so it can load the main bootloader code (which\nwon't fit into that SRAM).\n\nOther helper scripts might be used to write production system images,\ninvolving considerably more than just a three stage bootloader.\n\n5.6 Target Software Changes\n===========================\n\nSometimes you may want to make some small changes to the software you're\ndeveloping, to help make JTAG debugging work better.  For example, in C\nor assembly language code you might use '#ifdef JTAG_DEBUG' (or its\nconverse) around code handling issues like:\n\n   * Watchdog Timers...  Watchdog timers are typically used to\n     automatically reset systems if some application task doesn't\n     periodically reset the timer.  (The assumption is that the system\n     has locked up if the task can't run.)  When a JTAG debugger halts\n     the system, that task won't be able to run and reset the timer ...\n     potentially causing resets in the middle of your debug sessions.\n\n     It's rarely a good idea to disable such watchdogs, since their\n     usage needs to be debugged just like all other parts of your\n     firmware.  That might however be your only option.\n\n     Look instead for chip-specific ways to stop the watchdog from\n     counting while the system is in a debug halt state.  It may be\n     simplest to set that non-counting mode in your debugger startup\n     scripts.  You may however need a different approach when, for\n     example, a motor could be physically damaged by firmware remaining\n     inactive in a debug halt state.  That might involve a type of\n     firmware mode where that \"non-counting\" mode is disabled at the\n     beginning then re-enabled at the end; a watchdog reset might fire\n     and complicate the debug session, but hardware (or people) would be\n     protected.(1)\n\n   * ARM Semihosting...  When linked with a special runtime library\n     provided with many toolchains(2), your target code can use I/O\n     facilities on the debug host.  That library provides a small set of\n     system calls which are handled by OpenOCD. It can let the debugger\n     provide your system console and a file system, helping with early\n     debugging or providing a more capable environment for\n     sometimes-complex tasks like installing system firmware onto NAND\n     or SPI flash.\n\n   * ARM Wait-For-Interrupt...  Many ARM chips synchronize the JTAG\n     clock using the core clock.  Low power states which stop that core\n     clock thus prevent JTAG access.  Idle loops in tasking environments\n     often enter those low power states via the 'WFI' instruction (or\n     its coprocessor equivalent, before ARMv7).\n\n     You may want to _disable that instruction_ in source code, or\n     otherwise prevent using that state, to ensure you can get JTAG\n     access at any time.(3)  For example, the OpenOCD 'halt' command may\n     not work for an idle processor otherwise.\n\n   * Delay after reset...  Not all chips have good support for debugger\n     access right after reset; many LPC2xxx chips have issues here.\n     Similarly, applications that reconfigure pins used for JTAG access\n     as they start will also block debugger access.\n\n     To work with boards like this, _enable a short delay loop_ the\n     first thing after reset, before \"real\" startup activities.  For\n     example, one second's delay is usually more than enough time for a\n     JTAG debugger to attach, so that early code execution can be\n     debugged or firmware can be replaced.\n\n   * Debug Communications Channel (DCC)... Some processors include\n     mechanisms to send messages over JTAG. Many ARM cores support\n     these, as do some cores from other vendors.  (OpenOCD may be able\n     to use this DCC internally, speeding up some operations like\n     writing to memory.)\n\n     Your application may want to deliver various debugging messages\n     over JTAG, by _linking with a small library of code_ provided with\n     OpenOCD and using the utilities there to send various kinds of\n     message.  *Note Software Debug Messages and Tracing:\n     softwaredebugmessagesandtracing.\n\n5.7 Target Hardware Setup\n=========================\n\nChip vendors often provide software development boards which are highly\nconfigurable, so that they can support all options that product boards\nmay require.  _Make sure that any jumpers or switches match the system\nconfiguration you are working with._\n\nCommon issues include:\n\n   * JTAG setup ...  Boards may support more than one JTAG\n     configuration.  Examples include jumpers controlling pullups versus\n     pulldowns on the nTRST and/or nSRST signals, and choice of\n     connectors (e.g.  which of two headers on the base board, or one\n     from a daughtercard).  For some Texas Instruments boards, you may\n     need to jumper the EMU0 and EMU1 signals (which OpenOCD won't\n     currently control).\n\n   * Boot Modes ...  Complex chips often support multiple boot modes,\n     controlled by external jumpers.  Make sure this is set up\n     correctly.  For example many i.MX boards from NXP need to be\n     jumpered to \"ATX mode\" to start booting using the on-chip ROM, when\n     using second stage bootloader code stored in a NAND flash chip.\n\n     Such explicit configuration is common, and not limited to booting\n     from NAND. You might also need to set jumpers to start booting\n     using code loaded from an MMC/SD card; external SPI flash;\n     Ethernet, UART, or USB links; NOR flash; OneNAND flash; some\n     external host; or various other sources.\n\n   * Memory Addressing ...  Boards which support multiple boot modes may\n     also have jumpers to configure memory addressing.  One board, for\n     example, jumpers external chipselect 0 (used for booting) to\n     address either a large SRAM (which must be pre-loaded via JTAG),\n     NOR flash, or NAND flash.  When it's jumpered to address NAND\n     flash, that board must also be told to start booting from on-chip\n     ROM.\n\n     Your 'board.cfg' file may also need to be told this jumper\n     configuration, so that it can know whether to declare NOR flash\n     using 'flash bank' or instead declare NAND flash with 'nand\n     device'; and likewise which probe to perform in its 'reset-init'\n     handler.\n\n     A closely related issue is bus width.  Jumpers might need to\n     distinguish between 8 bit or 16 bit bus access for the flash used\n     to start booting.\n\n   * Peripheral Access ...  Development boards generally provide access\n     to every peripheral on the chip, sometimes in multiple modes (such\n     as by providing multiple audio codec chips).  This interacts with\n     software configuration of pin multiplexing, where for example a\n     given pin may be routed either to the MMC/SD controller or the GPIO\n     controller.  It also often interacts with configuration jumpers.\n     One jumper may be used to route signals to an MMC/SD card slot or\n     an expansion bus (which might in turn affect booting); others might\n     control which audio or video codecs are used.\n\nPlus you should of course have 'reset-init' event handlers which set up\nthe hardware to match that jumper configuration.  That includes in\nparticular any oscillator or PLL used to clock the CPU, and any memory\ncontrollers needed to access external memory and peripherals.  Without\nsuch handlers, you won't be able to access those resources without\nworking target firmware which can do that setup ...  this can be awkward\nwhen you're trying to debug that target firmware.  Even if there's a ROM\nbootloader which handles a few issues, it rarely provides full access to\nall board-specific capabilities.\n\n   ---------- Footnotes ----------\n\n   (1) Note that many systems support a \"monitor mode\" debug that is a\nsomewhat cleaner way to address such issues.  You can think of it as\nonly halting part of the system, maybe just one task, instead of the\nwhole thing.  At this writing, January 2010, OpenOCD based debugging\ndoes not support monitor mode debug, only \"halt mode\" debug.\n\n   (2) See chapter 8 \"Semihosting\" in ARM DUI 0203I\n(http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf),\nthe \"RealView Compilation Tools Developer Guide\".  The CodeSourcery EABI\ntoolchain also includes a semihosting library.\n\n   (3) As a more polite alternative, some processors have special\ndebug-oriented registers which can be used to change various features\nincluding how the low power states are clocked while debugging.  The\nSTM32 DBGMCU_CR register is an example; at the cost of extra power\nconsumption, JTAG can be used during low power states.\n\n\u001f\nFile: openocd.info,  Node: Config File Guidelines,  Next: Server Configuration,  Prev: OpenOCD Project Setup,  Up: Top\n\n6 Config File Guidelines\n************************\n\nThis chapter is aimed at any user who needs to write a config file,\nincluding developers and integrators of OpenOCD and any user who needs\nto get a new board working smoothly.  It provides guidelines for\ncreating those files.\n\nYou should find the following directories under $(INSTALLDIR)/scripts,\nwith config files maintained upstream.  Use them as-is where you can; or\nas models for new files.\n   * 'interface' ...  These are for debug adapters.  Files that specify\n     configuration to use specific JTAG, SWD and other adapters go here.\n   * 'board' ...  Think Circuit Board, PWA, PCB, they go by many names.\n     Board files contain initialization items that are specific to a\n     board.\n\n     They reuse target configuration files, since the same\n     microprocessor chips are used on many boards, but support for\n     external parts varies widely.  For example, the SDRAM\n     initialization sequence for the board, or the type of external\n     flash and what address it uses.  Any initialization sequence to\n     enable that external flash or SDRAM should be found in the board\n     file.  Boards may also contain multiple targets: two CPUs; or a CPU\n     and an FPGA.\n   * 'target' ...  Think chip.  The \"target\" directory represents the\n     JTAG TAPs on a chip which OpenOCD should control, not a board.  Two\n     common types of targets are ARM chips and FPGA or CPLD chips.  When\n     a chip has multiple TAPs (maybe it has both ARM and DSP cores), the\n     target config file defines all of them.\n   * _more_ ...  browse for other library files which may be useful.\n     For example, there are various generic and CPU-specific utilities.\n\nThe 'openocd.cfg' user config file may override features in any of the\nabove files by setting variables before sourcing the target file, or by\nadding commands specific to their situation.\n\n6.1 Interface Config Files\n==========================\n\nThe user config file should be able to source one of these files with a\ncommand like this:\n\n     source [find interface/FOOBAR.cfg]\n\nA preconfigured interface file should exist for every debug adapter in\nuse today with OpenOCD. That said, perhaps some of these config files\nhave only been used by the developer who created it.\n\nA separate chapter gives information about how to set these up.  *Note\nDebug Adapter Configuration::.  Read the OpenOCD source code (and\nDeveloper's Guide) if you have a new kind of hardware interface and need\nto provide a driver for it.\n\n -- Command: find 'filename'\n     Prints full path to FILENAME according to OpenOCD search rules.\n\n -- Command: ocd_find 'filename'\n     Prints full path to FILENAME according to OpenOCD search rules.\n     This is a low level function used by the 'find'.  Usually you want\n     to use 'find', instead.\n\n6.2 Board Config Files\n======================\n\nThe user config file should be able to source one of these files with a\ncommand like this:\n\n     source [find board/FOOBAR.cfg]\n\nThe point of a board config file is to package everything about a given\nboard that user config files need to know.  In summary the board files\nshould contain (if present)\n\n  1. One or more 'source [find target/...cfg]' statements\n  2. NOR flash configuration (*note NOR Configuration:\n     norconfiguration.)\n  3. NAND flash configuration (*note NAND Configuration:\n     nandconfiguration.)\n  4. Target 'reset' handlers for SDRAM and I/O configuration\n  5. JTAG adapter reset configuration (*note Reset Configuration::)\n  6. All things that are not \"inside a chip\"\n\nGeneric things inside target chips belong in target config files, not\nboard config files.  So for example a 'reset-init' event handler should\nknow board-specific oscillator and PLL parameters, which it passes to\ntarget-specific utility code.\n\nThe most complex task of a board config file is creating such a\n'reset-init' event handler.  Define those handlers last, after you\nverify the rest of the board configuration works.\n\n6.2.1 Communication Between Config files\n----------------------------------------\n\nIn addition to target-specific utility code, another way that board and\ntarget config files communicate is by following a convention on how to\nuse certain variables.\n\nThe full Tcl/Tk language supports \"namespaces\", but Jim-Tcl does not.\nThus the rule we follow in OpenOCD is this: Variables that begin with a\nleading underscore are temporary in nature, and can be modified and used\nat will within a target configuration file.\n\nComplex board config files can do the things like this, for a board with\nthree chips:\n\n     # Chip #1: PXA270 for network side, big endian\n     set CHIPNAME network\n     set ENDIAN big\n     source [find target/pxa270.cfg]\n     # on return: _TARGETNAME = network.cpu\n     # other commands can refer to the \"network.cpu\" target.\n     $_TARGETNAME configure .... events for this CPU..\n\n     # Chip #2: PXA270 for video side, little endian\n     set CHIPNAME video\n     set ENDIAN little\n     source [find target/pxa270.cfg]\n     # on return: _TARGETNAME = video.cpu\n     # other commands can refer to the \"video.cpu\" target.\n     $_TARGETNAME configure .... events for this CPU..\n\n     # Chip #3: Xilinx FPGA for glue logic\n     set CHIPNAME xilinx\n     unset ENDIAN\n     source [find target/spartan3.cfg]\n\nThat example is oversimplified because it doesn't show any flash memory,\nor the 'reset-init' event handlers to initialize external DRAM or\n(assuming it needs it) load a configuration into the FPGA. Such features\nare usually needed for low-level work with many boards, where \"low\nlevel\" implies that the board initialization software may not be\nworking.  (That's a common reason to need JTAG tools.  Another is to\nenable working with microcontroller-based systems, which often have no\ndebugging support except a JTAG connector.)\n\nTarget config files may also export utility functions to board and user\nconfig files.  Such functions should use name prefixes, to help avoid\nnaming collisions.\n\nBoard files could also accept input variables from user config files.\nFor example, there might be a 'J4_JUMPER' setting used to identify what\nkind of flash memory a development board is using, or how to set up\nother clocks and peripherals.\n\n6.2.2 Variable Naming Convention\n--------------------------------\n\nMost boards have only one instance of a chip.  However, it should be\neasy to create a board with more than one such chip (as shown above).\nAccordingly, we encourage these conventions for naming variables\nassociated with different 'target.cfg' files, to promote consistency and\nso that board files can override target defaults.\n\nInputs to target config files include:\n\n   * 'CHIPNAME' ...  This gives a name to the overall chip, and is used\n     as part of tap identifier dotted names.  While the default is\n     normally provided by the chip manufacturer, board files may need to\n     distinguish between instances of a chip.\n   * 'ENDIAN' ...  By default 'little' - although chips may hard-wire\n     'big'.  Chips that can't change endianness don't need to use this\n     variable.\n   * 'CPUTAPID' ...  When OpenOCD examines the JTAG chain, it can be\n     told verify the chips against the JTAG IDCODE register.  The target\n     file will hold one or more defaults, but sometimes the chip in a\n     board will use a different ID (perhaps a newer revision).\n\nOutputs from target config files include:\n\n   * '_TARGETNAME' ...  By convention, this variable is created by the\n     target configuration script.  The board configuration file may make\n     use of this variable to configure things like a \"reset init\"\n     script, or other things specific to that board and that target.  If\n     the chip has 2 targets, the names are '_TARGETNAME0',\n     '_TARGETNAME1', ...  etc.\n\n6.2.3 The reset-init Event Handler\n----------------------------------\n\nBoard config files run in the OpenOCD configuration stage; they can't\nuse TAPs or targets, since they haven't been fully set up yet.  This\nmeans you can't write memory or access chip registers; you can't even\nverify that a flash chip is present.  That's done later in event\nhandlers, of which the target 'reset-init' handler is one of the most\nimportant.\n\nExcept on microcontrollers, the basic job of 'reset-init' event handlers\nis setting up flash and DRAM, as normally handled by boot loaders.\nMicrocontrollers rarely use boot loaders; they run right out of their\non-chip flash and SRAM memory.  But they may want to use one of these\nhandlers too, if just for developer convenience.\n\n     Note: Because this is so very board-specific, and chip-specific, no\n     examples are included here.  Instead, look at the board config\n     files distributed with OpenOCD. If you have a boot loader, its\n     source code will help; so will configuration files for other JTAG\n     tools (*note Translating Configuration Files:\n     translatingconfigurationfiles.).\n\nSome of this code could probably be shared between different boards.\nFor example, setting up a DRAM controller often doesn't differ by much\nexcept the bus width (16 bits or 32?)  and memory timings, so a reusable\nTCL procedure loaded by the 'target.cfg' file might take those as\nparameters.  Similarly with oscillator, PLL, and clock setup; and\ndisabling the watchdog.  Structure the code cleanly, and provide\ncomments to help the next developer doing such work.  (_You might be\nthat next person_ trying to reuse init code!)\n\nThe last thing normally done in a 'reset-init' handler is probing\nwhatever flash memory was configured.  For most chips that needs to be\ndone while the associated target is halted, either because JTAG memory\naccess uses the CPU or to prevent conflicting CPU access.\n\n6.2.4 JTAG Clock Rate\n---------------------\n\nBefore your 'reset-init' handler has set up the PLLs and clocking, you\nmay need to run with a low JTAG clock rate.  *Note JTAG Speed:\njtagspeed.  Then you'd increase that rate after your handler has made it\npossible to use the faster JTAG clock.  When the initial low speed is\nboard-specific, for example because it depends on a board-specific\noscillator speed, then you should probably set it up in the board config\nfile; if it's target-specific, it belongs in the target config file.\n\nFor most ARM-based processors the fastest JTAG clock(1) is one sixth of\nthe CPU clock; or one eighth for ARM11 cores.  Consult chip\ndocumentation to determine the peak JTAG clock rate, which might be less\nthan that.\n\n     Warning: On most ARMs, JTAG clock detection is coupled to the core\n     clock, so software using a 'wait for interrupt' operation blocks\n     JTAG access.  Adaptive clocking provides a partial workaround, but\n     a more complete solution just avoids using that instruction with\n     JTAG debuggers.\n\nIf both the chip and the board support adaptive clocking, use the\n'jtag_rclk' command, in case your board is used with JTAG adapter which\nalso supports it.  Otherwise use 'adapter speed'.  Set the slow rate at\nthe beginning of the reset sequence, and the faster rate as soon as the\nclocks are at full speed.\n\n6.2.5 The init_board procedure\n------------------------------\n\nThe concept of 'init_board' procedure is very similar to 'init_targets'\n(*Note The init_targets procedure: theinittargetsprocedure.)  - it's a\nreplacement of \"linear\" configuration scripts.  This procedure is meant\nto be executed when OpenOCD enters run stage (*Note Entering the Run\nStage: enteringtherunstage,) after 'init_targets'.  The idea to have\nseparate 'init_targets' and 'init_board' procedures is to allow the\nfirst one to configure everything target specific (internal flash,\ninternal RAM, etc.)  and the second one to configure everything board\nspecific (reset signals, chip frequency, reset-init event handler,\nexternal memory, etc.).  Additionally \"linear\" board config file will\nmost likely fail when target config file uses 'init_targets' scheme\n(\"linear\" script is executed before 'init' and 'init_targets' - after),\nso separating these two configuration stages is very convenient, as the\neasiest way to overcome this problem is to convert board config file to\nuse 'init_board' procedure.  Board config scripts don't need to override\n'init_targets' defined in target config files when they only need to add\nsome specifics.\n\nJust as 'init_targets', the 'init_board' procedure can be overridden by\n\"next level\" script (which sources the original), allowing greater code\nreuse.\n\n     ### board_file.cfg ###\n\n     # source target file that does most of the config in init_targets\n     source [find target/target.cfg]\n\n     proc enable_fast_clock {} {\n         # enables fast on-board clock source\n         # configures the chip to use it\n     }\n\n     # initialize only board specifics - reset, clock, adapter frequency\n     proc init_board {} {\n         reset_config trst_and_srst trst_pulls_srst\n\n         $_TARGETNAME configure -event reset-start {\n             adapter speed 100\n         }\n\n         $_TARGETNAME configure -event reset-init {\n             enable_fast_clock\n             adapter speed 10000\n         }\n     }\n\n6.3 Target Config Files\n=======================\n\nBoard config files communicate with target config files using naming\nconventions as described above, and may source one or more target config\nfiles like this:\n\n     source [find target/FOOBAR.cfg]\n\nThe point of a target config file is to package everything about a given\nchip that board config files need to know.  In summary the target files\nshould contain\n\n  1. Set defaults\n  2. Add TAPs to the scan chain\n  3. Add CPU targets (includes GDB support)\n  4. CPU/Chip/CPU-Core specific features\n  5. On-Chip flash\n\nAs a rule of thumb, a target file sets up only one chip.  For a\nmicrocontroller, that will often include a single TAP, which is a CPU\nneeding a GDB target, and its on-chip flash.\n\nMore complex chips may include multiple TAPs, and the target config file\nmay need to define them all before OpenOCD can talk to the chip.  For\nexample, some phone chips have JTAG scan chains that include an ARM core\nfor operating system use, a DSP, another ARM core embedded in an image\nprocessing engine, and other processing engines.\n\n6.3.1 Default Value Boiler Plate Code\n-------------------------------------\n\nAll target configuration files should start with code like this, letting\nboard config files express environment-specific differences in how\nthings should be set up.\n\n     # Boards may override chip names, perhaps based on role,\n     # but the default should match what the vendor uses\n     if { [info exists CHIPNAME] } {\n        set  _CHIPNAME $CHIPNAME\n     } else {\n        set  _CHIPNAME sam7x256\n     }\n\n     # ONLY use ENDIAN with targets that can change it.\n     if { [info exists ENDIAN] } {\n        set  _ENDIAN $ENDIAN\n     } else {\n        set  _ENDIAN little\n     }\n\n     # TAP identifiers may change as chips mature, for example with\n     # new revision fields (the \"3\" here). Pick a good default; you\n     # can pass several such identifiers to the \"jtag newtap\" command.\n     if { [info exists CPUTAPID ] } {\n        set _CPUTAPID $CPUTAPID\n     } else {\n        set _CPUTAPID 0x3f0f0f0f\n     }\n\n_Remember:_ Board config files may include multiple target config files,\nor the same target file multiple times (changing at least 'CHIPNAME').\n\nLikewise, the target configuration file should define '_TARGETNAME' (or\n'_TARGETNAME0' etc) and use it later on when defining debug targets:\n\n     set _TARGETNAME $_CHIPNAME.cpu\n     target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n6.3.2 Adding TAPs to the Scan Chain\n-----------------------------------\n\nAfter the \"defaults\" are set up, add the TAPs on each chip to the JTAG\nscan chain.  *Note TAP Declaration::, and the naming convention for\ntaps.\n\nIn the simplest case the chip has only one TAP, probably for a CPU or\nFPGA. The config file for the Atmel AT91SAM7X256 looks (in part) like\nthis:\n\n     jtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nA board with two such at91sam7 chips would be able to source such a\nconfig file twice, with different values for 'CHIPNAME', so it adds a\ndifferent TAP each time.\n\nIf there are nonzero '-expected-id' values, OpenOCD attempts to verify\nthe actual tap id against those values.  It will issue error messages if\nthere is mismatch, which can help to pinpoint problems in OpenOCD\nconfigurations.\n\n     JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f\n                     (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)\n     ERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f\n     ERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1\n     ERROR:      got: mfg: 0x787, part: 0xf0f0, ver: 0x3\n\nThere are more complex examples too, with chips that have multiple TAPs.\nOnes worth looking at include:\n\n   * 'target/omap3530.cfg' - with disabled ARM and DSP, plus a JRC to\n     enable them\n   * 'target/str912.cfg' - with flash, CPU, and boundary scan\n   * 'target/ti_dm355.cfg' - with ETM, ARM, and JRC (this JRC is not\n     currently used)\n\n6.3.3 Add CPU targets\n---------------------\n\nAfter adding a TAP for a CPU, you should set it up so that GDB and other\ncommands can use it.  *Note CPU Configuration::.  For the at91sam7\nexample above, the command can look like this; note that '$_ENDIAN' is\nnot needed, since OpenOCD defaults to little endian, and this chip\ndoesn't support changing that.\n\n     set _TARGETNAME $_CHIPNAME.cpu\n     target create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\nWork areas are small RAM areas associated with CPU targets.  They are\nused by OpenOCD to speed up downloads, and to download small snippets of\ncode to program flash chips.  If the chip includes a form of\n\"on-chip-ram\" - and many do - define a work area if you can.  Again\nusing the at91sam7 as an example, this can look like:\n\n     $_TARGETNAME configure -work-area-phys 0x00200000 \\\n                  -work-area-size 0x4000 -work-area-backup 0\n\n6.3.4 Define CPU targets working in SMP\n---------------------------------------\n\nAfter setting targets, you can define a list of targets working in SMP.\n\n     set _TARGETNAME_1 $_CHIPNAME.cpu1\n     set _TARGETNAME_2 $_CHIPNAME.cpu2\n     target create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \\\n     -coreid 0 -dbgbase $_DAP_DBG1\n     target create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \\\n     -coreid 1 -dbgbase $_DAP_DBG2\n     #define 2 targets working in smp.\n     target smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\nIn the above example on cortex_a, 2 cpus are working in SMP. In SMP only\none GDB instance is created and :\n   * a set of hardware breakpoint sets the same breakpoint on all\n     targets in the list.\n   * halt command triggers the halt of all targets in the list.\n   * resume command triggers the write context and the restart of all\n     targets in the list.\n   * following a breakpoint: the target stopped by the breakpoint is\n     displayed to the GDB session.\n   * dedicated GDB serial protocol packets are implemented for\n     switching/retrieving the target displayed by the GDB session *note\n     Using OpenOCD SMP with GDB: usingopenocdsmpwithgdb.\n\nThe SMP behaviour can be disabled/enabled dynamically.  On cortex_a\nfollowing command have been implemented.\n   * cortex_a smp on : enable SMP mode, behaviour is as described above.\n   * cortex_a smp off : disable SMP mode, the current target is the one\n     displayed in the GDB session, only this target is now controlled by\n     GDB session.  This behaviour is useful during system boot up.\n   * cortex_a smp : display current SMP mode.\n   * cortex_a smp_gdb : display/fix the core id displayed in GDB session\n     see following example.\n\n     >cortex_a smp_gdb\n     gdb coreid  0 -> -1\n     #0 : coreid 0 is displayed to GDB ,\n     #-> -1 : next resume triggers a real resume\n     > cortex_a smp_gdb 1\n     gdb coreid  0 -> 1\n     #0 :coreid 0 is displayed to GDB ,\n     #->1  : next resume displays coreid 1 to GDB\n     > resume\n     > cortex_a smp_gdb\n     gdb coreid  1 -> 1\n     #1 :coreid 1 is displayed to GDB ,\n     #->1 : next resume displays coreid 1 to GDB\n     > cortex_a smp_gdb -1\n     gdb coreid  1 -> -1\n     #1 :coreid 1 is displayed to GDB,\n     #->-1 : next resume triggers a real resume\n\n6.3.5 Chip Reset Setup\n----------------------\n\nAs a rule, you should put the 'reset_config' command into the board\nfile.  Most things you think you know about a chip can be tweaked by the\nboard.\n\nSome chips have specific ways the TRST and SRST signals are managed.  In\nthe unusual case that these are _chip specific_ and can never be changed\nby board wiring, they could go here.  For example, some chips can't\nsupport JTAG debugging without both signals.\n\nProvide a 'reset-assert' event handler if you can.  Such a handler uses\nJTAG operations to reset the target, letting this target config be used\nin systems which don't provide the optional SRST signal, or on systems\nwhere you don't want to reset all targets at once.  Such a handler might\nwrite to chip registers to force a reset, use a JRC to do that\n(preferable - the target may be wedged!), or force a watchdog timer to\ntrigger.  (For Cortex-M targets, this is not necessary.  The target\ndriver knows how to use trigger an NVIC reset when SRST is not\navailable.)\n\nSome chips need special attention during reset handling if they're going\nto be used with JTAG. An example might be needing to send some commands\nright after the target's TAP has been reset, providing a\n'reset-deassert-post' event handler that writes a chip register to\nreport that JTAG debugging is being done.  Another would be\nreconfiguring the watchdog so that it stops counting while the core is\nhalted in the debugger.\n\nJTAG clocking constraints often change during reset, and in some cases\ntarget config files (rather than board config files) are the right\nplaces to handle some of those issues.  For example, immediately after\nreset most chips run using a slower clock than they will use later.\nThat means that after reset (and potentially, as OpenOCD first starts\nup) they must use a slower JTAG clock rate than they will use later.\n*Note JTAG Speed: jtagspeed.\n\n     Important: When you are debugging code that runs right after chip\n     reset, getting these issues right is critical.  In particular, if\n     you see intermittent failures when OpenOCD verifies the scan chain\n     after reset, look at how you are setting up JTAG clocking.\n\n6.3.6 The init_targets procedure\n--------------------------------\n\nTarget config files can either be \"linear\" (script executed line-by-line\nwhen parsed in configuration stage, *Note Configuration Stage:\nconfigurationstage,) or they can contain a special procedure called\n'init_targets', which will be executed when entering run stage (after\nparsing all config files or after 'init' command, *Note Entering the Run\nStage: enteringtherunstage.)  Such procedure can be overridden by \"next\nlevel\" script (which sources the original).  This concept facilitates\ncode reuse when basic target config files provide generic configuration\nprocedures and 'init_targets' procedure, which can then be sourced and\nenhanced or changed in a \"more specific\" target config file.  This is\nnot possible with \"linear\" config scripts, because sourcing them\nexecutes every initialization commands they provide.\n\n     ### generic_file.cfg ###\n\n     proc setup_my_chip {chip_name flash_size ram_size} {\n         # basic initialization procedure ...\n     }\n\n     proc init_targets {} {\n         # initializes generic chip with 4kB of flash and 1kB of RAM\n         setup_my_chip MY_GENERIC_CHIP 4096 1024\n     }\n\n     ### specific_file.cfg ###\n\n     source [find target/generic_file.cfg]\n\n     proc init_targets {} {\n         # initializes specific chip with 128kB of flash and 64kB of RAM\n         setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536\n     }\n\nThe easiest way to convert \"linear\" config files to 'init_targets'\nversion is to enclose every line of \"code\" (i.e.  not 'source' commands,\nprocedures, etc.)  in this procedure.\n\nFor an example of this scheme see LPC2000 target config files.\n\nThe 'init_boards' procedure is a similar concept concerning board config\nfiles (*Note The init_board procedure: theinitboardprocedure.)\n\n6.3.7 The init_target_events procedure\n--------------------------------------\n\nA special procedure called 'init_target_events' is run just after\n'init_targets' (*Note The init_targets procedure:\ntheinittargetsprocedure.)  and before 'init_board' (*Note The init_board\nprocedure: theinitboardprocedure.)  It is used to set up default target\nevents for the targets that do not have those events already assigned.\n\n6.3.8 ARM Core Specific Hacks\n-----------------------------\n\nIf the chip has a DCC, enable it.  If the chip is an ARM9 with some\nspecial high speed download features - enable it.\n\nIf present, the MMU, the MPU and the CACHE should be disabled.\n\nSome ARM cores are equipped with trace support, which permits\nexamination of the instruction and data bus activity.  Trace activity is\ncontrolled through an \"Embedded Trace Module\" (ETM) on one of the core's\nscan chains.  The ETM emits voluminous data through a \"trace port\".\n(*Note ARM Hardware Tracing: armhardwaretracing.)  If you are using an\nexternal trace port, configure it in your board config file.  If you are\nusing an on-chip \"Embedded Trace Buffer\" (ETB), configure it in your\ntarget config file.\n\n     etm config $_TARGETNAME 16 normal full etb\n     etb config $_TARGETNAME $_CHIPNAME.etb\n\n6.3.9 Internal Flash Configuration\n----------------------------------\n\nThis applies ONLY TO MICROCONTROLLERS that have flash built in.\n\nNever ever in the \"target configuration file\" define any type of flash\nthat is external to the chip.  (For example a BOOT flash on Chip Select\n0.)  Such flash information goes in a board file - not the TARGET (chip)\nfile.\n\nExamples:\n   * at91sam7x256 - has 256K flash YES enable it.\n   * str912 - has flash internal YES enable it.\n   * imx27 - uses boot flash on CS0 - it goes in the board file.\n   * pxa270 - again - CS0 flash - it goes in the board file.\n\n6.4 Translating Configuration Files\n===================================\n\nIf you have a configuration file for another hardware debugger or\ntoolset (Abatron, BDI2000, BDI3000, CCS, Lauterbach, SEGGER, Macraigor,\netc.), translating it into OpenOCD syntax is often quite\nstraightforward.  The most tricky part of creating a configuration\nscript is oftentimes the reset init sequence where e.g.  PLLs, DRAM and\nthe like is set up.\n\nOne trick that you can use when translating is to write small Tcl\nprocedures to translate the syntax into OpenOCD syntax.  This can avoid\nmanual translation errors and make it easier to convert other scripts\nlater on.\n\nExample of transforming quirky arguments to a simple search and replace\njob:\n\n     #   Lauterbach syntax(?)\n     #\n     #       Data.Set c15:0x042f %long 0x40000015\n     #\n     #   OpenOCD syntax when using procedure below.\n     #\n     #       setc15 0x01 0x00050078\n\n     proc setc15 {regs value} {\n         global TARGETNAME\n\n         echo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n         arm mcr 15 [expr {($regs >> 12) & 0x7}] \\\n             [expr {($regs >> 0) & 0xf}] [expr {($regs >> 4) & 0xf}] \\\n             [expr {($regs >> 8) & 0x7}] $value\n     }\n\n   ---------- Footnotes ----------\n\n   (1) A FAQ <http://www.arm.com/support/faqdev/4170.html> gives\ndetails.\n\n\u001f\nFile: openocd.info,  Node: Server Configuration,  Next: Debug Adapter Configuration,  Prev: Config File Guidelines,  Up: Top\n\n7 Server Configuration\n**********************\n\nThe commands here are commonly found in the openocd.cfg file and are\nused to specify what TCP/IP ports are used, and how GDB should be\nsupported.\n\n7.1 Configuration Stage\n=======================\n\nWhen the OpenOCD server process starts up, it enters a _configuration\nstage_ which is the only time that certain commands, _configuration\ncommands_, may be issued.  Normally, configuration commands are only\navailable inside startup scripts.\n\nIn this manual, the definition of a configuration command is presented\nas a _Config Command_, not as a _Command_ which may be issued\ninteractively.  The runtime 'help' command also highlights configuration\ncommands, and those which may be issued at any time.\n\nThose configuration commands include declaration of TAPs, flash banks,\nthe interface used for JTAG communication, and other basic setup.  The\nserver must leave the configuration stage before it may access or\nactivate TAPs.  After it leaves this stage, configuration commands may\nno longer be issued.\n\n -- Command: command mode [command_name]\n     Returns the command modes allowed by a command: 'any', 'config', or\n     'exec'.  If no command is specified, returns the current command\n     mode.  Returns 'unknown' if an unknown command is given.  Command\n     can be multiple tokens.  (command valid any time)\n\n     In this document, the modes are described as stages, 'config' and\n     'exec' mode correspond configuration stage and run stage.  'any'\n     means the command can be executed in either stages.  *Note\n     Configuration Stage: configurationstage, and *Note Entering the Run\n     Stage: enteringtherunstage.\n\n7.2 Entering the Run Stage\n==========================\n\nThe first thing OpenOCD does after leaving the configuration stage is to\nverify that it can talk to the scan chain (list of TAPs) which has been\nconfigured.  It will warn if it doesn't find TAPs it expects to find, or\nfinds TAPs that aren't supposed to be there.  You should see no errors\nat this point.  If you see errors, resolve them by correcting the\ncommands you used to configure the server.  Common errors include using\nan initial JTAG speed that's too fast, and not providing the right\nIDCODE values for the TAPs on the scan chain.\n\nOnce OpenOCD has entered the run stage, a number of commands become\navailable.  A number of these relate to the debug targets you may have\ndeclared.  For example, the 'mww' command will not be available until a\ntarget has been successfully instantiated.  If you want to use those\ncommands, you may need to force entry to the run stage.\n\n -- Config Command: init\n     This command terminates the configuration stage and enters the run\n     stage.  This helps when you need to have the startup scripts manage\n     tasks such as resetting the target, programming flash, etc.  To\n     reset the CPU upon startup, add \"init\" and \"reset\" at the end of\n     the config script or at the end of the OpenOCD command line using\n     the '-c' command line switch.\n\n     If this command does not appear in any startup/configuration file\n     OpenOCD executes the command for you after processing all\n     configuration files and/or command line options.\n\n     NOTE: This command normally occurs near the end of your openocd.cfg\n     file to force OpenOCD to \"initialize\" and make the targets ready.\n     For example: If your openocd.cfg file needs to read/write memory on\n     your target, 'init' must occur before the memory read/write\n     commands.  This includes 'nand probe'.\n\n     'init' calls the following internal OpenOCD commands to initialize\n     corresponding subsystems:\n      -- Config Command: target init\n      -- Command: transport init\n      -- Command: dap init\n      -- Config Command: flash init\n      -- Config Command: nand init\n      -- Config Command: pld init\n      -- Command: tpiu init\n\n     At last, 'init' executes all the commands that are specified in the\n     TCL list POST_INIT_COMMANDS.  The commands are executed in the same\n     order they occupy in the list.  If one of the commands fails, then\n     the error is propagated and OpenOCD fails too.\n          lappend post_init_commands {echo \"OpenOCD successfully initialized.\"}\n          lappend post_init_commands {echo \"Have fun with OpenOCD !\"}\n\n -- Config Command: noinit\n     Prevent OpenOCD from implicit 'init' call at the end of startup.\n     Allows issuing configuration commands over telnet or Tcl\n     connection.  When you are done with configuration use 'init' to\n     enter the run stage.\n\n -- Overridable Procedure: jtag_init\n     This is invoked at server startup to verify that it can talk to the\n     scan chain (list of TAPs) which has been configured.\n\n     The default implementation first tries 'jtag arp_init', which uses\n     only a lightweight JTAG reset before examining the scan chain.  If\n     that fails, it tries again, using a harder reset from the\n     overridable procedure 'init_reset'.\n\n     Implementations must have verified the JTAG scan chain before they\n     return.  This is done by calling 'jtag arp_init' (or 'jtag\n     arp_init-reset').\n\n7.3 TCP/IP Ports\n================\n\nThe OpenOCD server accepts remote commands in several syntaxes.  Each\nsyntax uses a different TCP/IP port, which you may specify only during\nconfiguration (before those ports are opened).\n\nFor reasons including security, you may wish to prevent remote access\nusing one or more of these ports.  In such cases, just specify the\nrelevant port number as \"disabled\".  If you disable all access through\nTCP/IP, you will need to use the command line '-pipe' option.\n\n -- Config Command: gdb_port [number]\n     Normally gdb listens to a TCP/IP port, but GDB can also communicate\n     via pipes(stdin/out or named pipes).  The name \"gdb_port\" stuck\n     because it covers probably more than 90% of the normal use cases.\n\n     No arguments reports GDB port.  \"pipe\" means listen to stdin output\n     to stdout, an integer is base port number, \"disabled\" disables the\n     gdb server.\n\n     When using \"pipe\", also use log_output to redirect the log output\n     to a file so as not to flood the stdin/out pipes.\n\n     Any other string is interpreted as named pipe to listen to.  Output\n     pipe is the same name as input pipe, but with 'o' appended, e.g.\n     /var/gdb, /var/gdbo.\n\n     The GDB port for the first target will be the base port, the second\n     target will listen on gdb_port + 1, and so on.  When not specified\n     during the configuration stage, the port NUMBER defaults to 3333.\n     When NUMBER is not a numeric value, incrementing it to compute the\n     next port number does not work.  In this case, specify the proper\n     NUMBER for each target by using the option '-gdb-port' of the\n     commands 'target create' or '$target_name configure'.  *Note option\n     -gdb-port: gdbportoverride.\n\n     Note: when using \"gdb_port pipe\", increasing the default remote\n     timeout in gdb (with 'set remotetimeout') is recommended.  An\n     insufficient timeout may cause initialization to fail with \"Unknown\n     remote qXfer reply: OK\".\n\n -- Config Command: tcl_port [number]\n     Specify or query the port used for a simplified RPC connection that\n     can be used by clients to issue TCL commands and get the output\n     from the Tcl engine.  Intended as a machine interface.  When not\n     specified during the configuration stage, the port NUMBER defaults\n     to 6666.  When specified as \"disabled\", this service is not\n     activated.\n\n -- Config Command: telnet_port [number]\n     Specify or query the port on which to listen for incoming telnet\n     connections.  This port is intended for interaction with one human\n     through TCL commands.  When not specified during the configuration\n     stage, the port NUMBER defaults to 4444.  When specified as\n     \"disabled\", this service is not activated.\n\n7.4 GDB Configuration\n=====================\n\nYou can reconfigure some GDB behaviors if needed.  The ones listed here\nare static and global.  *Note Target Configuration: targetconfiguration,\nabout configuring individual targets.  *Note Target Events:\ntargetevents, about configuring target-specific event handling.\n\n -- Command: gdb_breakpoint_override [hard|soft|disable]\n     Force breakpoint type for gdb 'break' commands.  This option\n     supports GDB GUIs which don't distinguish hard versus soft\n     breakpoints, if the default OpenOCD and GDB behaviour is not\n     sufficient.  GDB normally uses hardware breakpoints if the memory\n     map has been set up for flash regions.\n\n -- Config Command: gdb_flash_program (enable|disable)\n     Set to 'enable' to cause OpenOCD to program the flash memory when a\n     vFlash packet is received.  The default behaviour is 'enable'.\n\n -- Config Command: gdb_memory_map (enable|disable)\n     Set to 'enable' to cause OpenOCD to send the memory configuration\n     to GDB when requested.  GDB will then know when to set hardware\n     breakpoints, and program flash using the GDB load command.\n     'gdb_flash_program enable' must also be enabled for flash\n     programming to work.  Default behaviour is 'enable'.  *Note\n     gdb_flash_program: gdbflashprogram.\n\n -- Config Command: gdb_report_data_abort (enable|disable)\n     Specifies whether data aborts cause an error to be reported by GDB\n     memory read packets.  The default behaviour is 'disable'; use\n     'enable' see these errors reported.\n\n -- Config Command: gdb_report_register_access_error (enable|disable)\n     Specifies whether register accesses requested by GDB register\n     read/write packets report errors or not.  The default behaviour is\n     'disable'; use 'enable' see these errors reported.\n\n -- Config Command: gdb_target_description (enable|disable)\n     Set to 'enable' to cause OpenOCD to send the target descriptions to\n     gdb via qXfer:features:read packet.  The default behaviour is\n     'enable'.\n\n -- Command: gdb_save_tdesc\n     Saves the target description file to the local file system.\n\n     The file name is target_name.xml.\n\n7.5 Event Polling\n=================\n\nHardware debuggers are parts of asynchronous systems, where significant\nevents can happen at any time.  The OpenOCD server needs to detect some\nof these events, so it can report them to through TCL command line or to\nGDB.\n\nExamples of such events include:\n\n   * One of the targets can stop running ...  maybe it triggers a code\n     breakpoint or data watchpoint, or halts itself.\n   * Messages may be sent over \"debug message\" channels ...  many\n     targets support such messages sent over JTAG, for receipt by the\n     person debugging or tools.\n   * Loss of power ...  some adapters can detect these events.\n   * Resets not issued through JTAG ...  such reset sources can include\n     button presses or other system hardware, sometimes including the\n     target itself (perhaps through a watchdog).\n   * Debug instrumentation sometimes supports event triggering such as\n     \"trace buffer full\" (so it can quickly be emptied) or other signals\n     (to correlate with code behavior).\n\nNone of those events are signaled through standard JTAG signals.\nHowever, most conventions for JTAG connectors include voltage level and\nsystem reset (SRST) signal detection.  Some connectors also include\ninstrumentation signals, which can imply events when those signals are\ninputs.\n\nIn general, OpenOCD needs to periodically check for those events, either\nby looking at the status of signals on the JTAG connector or by sending\nsynchronous \"tell me your status\" JTAG requests to the various active\ntargets.  There is a command to manage and monitor that polling, which\nis normally done in the background.\n\n -- Command: poll [on|off]\n     Poll the current target for its current state.  (Also, *note target\n     curstate: targetcurstate.)  If that target is in debug mode,\n     architecture specific information about the current state is\n     printed.  An optional parameter allows background polling to be\n     enabled and disabled.\n\n     You could use this from the TCL command shell, or from GDB using\n     'monitor poll' command.  Leave background polling enabled while\n     you're using GDB.\n          > poll\n          background polling: on\n          target state: halted\n          target halted in ARM state due to debug-request, \\\n                         current mode: Supervisor\n          cpsr: 0x800000d3 pc: 0x11081bfc\n          MMU: disabled, D-Cache: disabled, I-Cache: enabled\n          >\n\n\u001f\nFile: openocd.info,  Node: Debug Adapter Configuration,  Next: Reset Configuration,  Prev: Server Configuration,  Up: Top\n\n8 Debug Adapter Configuration\n*****************************\n\nCorrectly installing OpenOCD includes making your operating system give\nOpenOCD access to debug adapters.  Once that has been done, Tcl commands\nare used to select which one is used, and to configure how it is used.\n\n     Note: Because OpenOCD started out with a focus purely on JTAG, you\n     may find places where it wrongly presumes JTAG is the only\n     transport protocol in use.  Be aware that recent versions of\n     OpenOCD are removing that limitation.  JTAG remains more functional\n     than most other transports.  Other transports do not support\n     boundary scan operations, or may be specific to a given chip\n     vendor.  Some might be usable only for programming flash memory,\n     instead of also for debugging.\n\nDebug Adapters/Interfaces/Dongles are normally configured through\ncommands in an interface configuration file which is sourced by your\n'openocd.cfg' file, or through a command line '-f interface/....cfg'\noption.\n\n     source [find interface/olimex-jtag-tiny.cfg]\n\nThese commands tell OpenOCD what type of JTAG adapter you have, and how\nto talk to it.  A few cases are so simple that you only need to say what\ndriver to use:\n\n     # jlink interface\n     adapter driver jlink\n\nMost adapters need a bit more configuration than that.\n\n8.1 Adapter Configuration\n=========================\n\nThe 'adapter driver' command tells OpenOCD what type of debug adapter\nyou are using.  Depending on the type of adapter, you may need to use\none or more additional commands to further identify or configure the\nadapter.\n\n -- Config Command: adapter driver name\n     Use the adapter driver NAME to connect to the target.\n\n -- Command: adapter list\n     List the debug adapter drivers that have been built into the\n     running copy of OpenOCD.\n -- Config Command: adapter transports transport_name+\n     Specifies the transports supported by this debug adapter.  The\n     adapter driver builds-in similar knowledge; use this only when\n     external configuration (such as jumpering) changes what the\n     hardware can support.\n\n -- Command: adapter name\n     Returns the name of the debug adapter driver being used.\n\n -- Config Command: adapter usb location [<bus>-<port>[.<port>]...]\n     Displays or specifies the physical USB port of the adapter to use.\n     The path roots at BUS and walks down the physical ports, with each\n     PORT option specifying a deeper level in the bus topology, the last\n     PORT denoting where the target adapter is actually plugged.  The\n     USB bus topology can be queried with the command _lsusb -t_ or\n     _dmesg_.\n\n     This command is only available if your libusb1 is at least version\n     1.0.16.\n\n -- Config Command: adapter serial serial_string\n     Specifies the SERIAL_STRING of the adapter to use.  If this command\n     is not specified, serial strings are not checked.  Only the\n     following adapter drivers use the serial string from this command:\n     aice (aice_usb), arm-jtag-ew, cmsis_dap, ft232r, ftdi, hla (stlink,\n     ti-icdi), jlink, kitprog, opendus, openjtag, osbdm, presto, rlink,\n     st-link, usb_blaster (ublast2), usbprog, vsllink, xds110.\n\n8.2 Interface Drivers\n=====================\n\nEach of the interface drivers listed here must be explicitly enabled\nwhen OpenOCD is configured, in order to be made available at run time.\n\n -- Interface Driver: amt_jtagaccel\n     Amontec Chameleon in its JTAG Accelerator configuration, connected\n     to a PC's EPP mode parallel port.  This defines some\n     driver-specific commands:\n\n      -- Config Command: parport port number\n          Specifies either the address of the I/O port (default: 0x378\n          for LPT1) or the number of the '/dev/parport' device.\n\n      -- Config Command: rtck [enable|disable]\n          Displays status of RTCK option.  Optionally sets that option\n          first.\n\n -- Interface Driver: arm-jtag-ew\n     Olimex ARM-JTAG-EW USB adapter This has one driver-specific\n     command:\n\n      -- Command: armjtagew_info\n          Logs some status\n\n -- Interface Driver: at91rm9200\n     Supports bitbanged JTAG from the local system, presuming that\n     system is an Atmel AT91rm9200 and a specific set of GPIOs is used.\n\n -- Interface Driver: cmsis-dap\n     ARM CMSIS-DAP compliant based adapter v1 (USB HID based) or v2 (USB\n     bulk).\n\n      -- Config Command: cmsis_dap_vid_pid [vid pid]+\n          The vendor ID and product ID of the CMSIS-DAP device.  If not\n          specified the driver will attempt to auto detect the CMSIS-DAP\n          device.  Currently, up to eight [VID, PID] pairs may be given,\n          e.g.\n               cmsis_dap_vid_pid 0xc251 0xf001 0x0d28 0x0204\n\n      -- Config Command: cmsis_dap_backend [auto|usb_bulk|hid]\n          Specifies how to communicate with the adapter:\n\n             - 'hid' Use HID generic reports - CMSIS-DAP v1\n             - 'usb_bulk' Use USB bulk - CMSIS-DAP v2\n             - 'auto' First try USB bulk CMSIS-DAP v2, if not found try\n               HID CMSIS-DAP v1.  This is the default if\n               'cmsis_dap_backend' is not specified.\n\n      -- Config Command: cmsis_dap_usb interface [number]\n          Specifies the NUMBER of the USB interface to use in v2 mode\n          (USB bulk).  In most cases need not to be specified and\n          interfaces are searched by interface string or for user class\n          interface.\n\n      -- Command: cmsis-dap info\n          Display various device information, like hardware version,\n          firmware version, current bus status.\n\n      -- Command: cmsis-dap cmd number number ...\n          Execute an arbitrary CMSIS-DAP command.  Use for adapter\n          testing or for handling of an adapter vendor specific command\n          from a Tcl script.\n\n          Take given numbers as bytes, assemble a CMSIS-DAP protocol\n          command packet from them and send it to the adapter.  The\n          first 4 bytes of the adapter response are logged.  See\n          <https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__Commands__gr.html>\n\n -- Interface Driver: dummy\n     A dummy software-only driver for debugging.\n\n -- Interface Driver: ep93xx\n     Cirrus Logic EP93xx based single-board computer bit-banging (in\n     development)\n\n -- Interface Driver: ftdi\n     This driver is for adapters using the MPSSE (Multi-Protocol\n     Synchronous Serial Engine) mode built into many FTDI chips, such as\n     the FT2232, FT4232 and FT232H.\n\n     The driver is using libusb-1.0 in asynchronous mode to talk to the\n     FTDI device, bypassing intermediate libraries like libftdi.\n\n     Support for new FTDI based adapters can be added completely through\n     configuration files, without the need to patch and rebuild OpenOCD.\n\n     The driver uses a signal abstraction to enable Tcl configuration\n     files to define outputs for one or several FTDI GPIO. These outputs\n     can then be controlled using the 'ftdi set_signal' command.\n     Special signal names are reserved for nTRST, nSRST and LED (for\n     blink) so that they, if defined, will be used for their customary\n     purpose.  Inputs can be read using the 'ftdi get_signal' command.\n\n     To support SWD, a signal named SWD_EN must be defined.  It is set\n     to 1 when the SWD protocol is selected.  When set, the adapter\n     should route the SWDIO pin to the data input.  An SWDIO_OE signal,\n     if defined, will be set to 1 or 0 as required by the protocol, to\n     tell the adapter to drive the data output onto the SWDIO pin or\n     keep the SWDIO pin Hi-Z, respectively.\n\n     Depending on the type of buffer attached to the FTDI GPIO, the\n     outputs have to be controlled differently.  In order to support\n     tristateable signals such as nSRST, both a data GPIO and an\n     output-enable GPIO can be specified for each signal.  The following\n     output buffer configurations are supported:\n\n        - Push-pull with one FTDI output as (non-)inverted data line\n        - Open drain with one FTDI output as (non-)inverted\n          output-enable\n        - Tristate with one FTDI output as (non-)inverted data line and\n          another FTDI output as (non-)inverted output-enable\n        - Unbuffered, using the FTDI GPIO as a tristate output directly\n          by switching data and direction as necessary\n\n     These interfaces have several commands, used to configure the\n     driver before initializing the JTAG scan chain:\n\n      -- Config Command: ftdi vid_pid [vid pid]+\n          The vendor ID and product ID of the adapter.  Up to eight\n          [VID, PID] pairs may be given, e.g.\n               ftdi vid_pid 0x0403 0xcff8 0x15ba 0x0003\n\n      -- Config Command: ftdi device_desc description\n          Provides the USB device description (the _iProduct string_) of\n          the adapter.  If not specified, the device description is\n          ignored during device selection.\n\n      -- Config Command: ftdi channel channel\n          Selects the channel of the FTDI device to use for MPSSE\n          operations.  Most adapters use the default, channel 0, but\n          there are exceptions.\n\n      -- Config Command: ftdi layout_init data direction\n          Specifies the initial values of the FTDI GPIO data and\n          direction registers.  Each value is a 16-bit number\n          corresponding to the concatenation of the high and low FTDI\n          GPIO registers.  The values should be selected based on the\n          schematics of the adapter, such that all signals are set to\n          safe levels with minimal impact on the target system.  Avoid\n          floating inputs, conflicting outputs and initially asserted\n          reset signals.\n\n      -- Command: ftdi layout_signal name [-data|-ndata data_mask]\n               [-input|-ninput input_mask] [-oe|-noe oe_mask]\n               [-alias|-nalias name]\n          Creates a signal with the specified NAME, controlled by one or\n          more FTDI GPIO pins via a range of possible buffer\n          connections.  The masks are FTDI GPIO register bitmasks to\n          tell the driver the connection and type of the output buffer\n          driving the respective signal.  DATA_MASK is the bitmask for\n          the pin(s) connected to the data input of the output buffer.\n          '-ndata' is used with inverting data inputs and '-data' with\n          non-inverting inputs.  The '-oe' (or '-noe') option tells\n          where the output-enable (or not-output-enable) input to the\n          output buffer is connected.  The options '-input' and\n          '-ninput' specify the bitmask for pins to be read with the\n          method 'ftdi get_signal'.\n\n          Both DATA_MASK and OE_MASK need not be specified.  For\n          example, a simple open-collector transistor driver would be\n          specified with '-oe' only.  In that case the signal can only\n          be set to drive low or to Hi-Z and the driver will complain if\n          the signal is set to drive high.  Which means that if it's a\n          reset signal, 'reset_config' must be specified as\n          'srst_open_drain', not 'srst_push_pull'.\n\n          A special case is provided when '-data' and '-oe' is set to\n          the same bitmask.  Then the FTDI pin is considered being\n          connected straight to the target without any buffer.  The FTDI\n          pin is then switched between output and input as necessary to\n          provide the full set of low, high and Hi-Z characteristics.\n          In all other cases, the pins specified in a signal definition\n          are always driven by the FTDI.\n\n          If '-alias' or '-nalias' is used, the signal is created\n          identical (or with data inverted) to an already specified\n          signal NAME.\n\n      -- Command: ftdi set_signal name 0|1|z\n          Set a previously defined signal to the specified level.\n             - '0', drive low\n             - '1', drive high\n             - 'z', set to high-impedance\n\n      -- Command: ftdi get_signal name\n          Get the value of a previously defined signal.\n\n      -- Command: ftdi tdo_sample_edge rising|falling\n          Configure TCK edge at which the adapter samples the value of\n          the TDO signal\n\n          Due to signal propagation delays, sampling TDO on rising TCK\n          can become quite peculiar at high JTAG clock speeds.  However,\n          FTDI chips offer a possibility to sample TDO on falling edge\n          of TCK. With some board/adapter configurations, this may\n          increase stability at higher JTAG clocks.\n             - 'rising', sample TDO on rising edge of TCK - this is the\n               default\n             - 'falling', sample TDO on falling edge of TCK\n\n     For example adapter definitions, see the configuration files\n     shipped in the 'interface/ftdi' directory.\n\n -- Interface Driver: ft232r\n     This driver is implementing synchronous bitbang mode of an FTDI\n     FT232R, FT230X, FT231X and similar USB UART bridge ICs by reusing\n     RS232 signals as GPIO. It currently doesn't support using CBUS pins\n     as GPIO.\n\n     List of connections (default physical pin numbers for FT232R in\n     28-pin SSOP package):\n        - RXD(5) - TDI\n        - TXD(1) - TCK\n        - RTS(3) - TDO\n        - CTS(11) - TMS\n        - DTR(2) - TRST\n        - DCD(10) - SRST\n\n     User can change default pinout by supplying configuration commands\n     with GPIO numbers or RS232 signal names.  GPIO numbers correspond\n     to bit numbers in FTDI GPIO register.  They differ from physical\n     pin numbers.  For details see actual FTDI chip datasheets.  Every\n     JTAG line must be configured to unique GPIO number different than\n     any other JTAG line, even those lines that are sometimes not used\n     like TRST or SRST.\n\n     FT232R\n        - bit 7 - RI\n        - bit 6 - DCD\n        - bit 5 - DSR\n        - bit 4 - DTR\n        - bit 3 - CTS\n        - bit 2 - RTS\n        - bit 1 - RXD\n        - bit 0 - TXD\n\n     These interfaces have several commands, used to configure the\n     driver before initializing the JTAG scan chain:\n\n      -- Config Command: ft232r vid_pid VID PID\n          The vendor ID and product ID of the adapter.  If not\n          specified, default 0x0403:0x6001 is used.\n\n      -- Config Command: ft232r jtag_nums TCK TMS TDI TDO\n          Set four JTAG GPIO numbers at once.  If not specified, default\n          0 3 1 2 or TXD CTS RXD RTS is used.\n\n      -- Config Command: ft232r tck_num TCK\n          Set TCK GPIO number.  If not specified, default 0 or TXD is\n          used.\n\n      -- Config Command: ft232r tms_num TMS\n          Set TMS GPIO number.  If not specified, default 3 or CTS is\n          used.\n\n      -- Config Command: ft232r tdi_num TDI\n          Set TDI GPIO number.  If not specified, default 1 or RXD is\n          used.\n\n      -- Config Command: ft232r tdo_num TDO\n          Set TDO GPIO number.  If not specified, default 2 or RTS is\n          used.\n\n      -- Config Command: ft232r trst_num TRST\n          Set TRST GPIO number.  If not specified, default 4 or DTR is\n          used.\n\n      -- Config Command: ft232r srst_num SRST\n          Set SRST GPIO number.  If not specified, default 6 or DCD is\n          used.\n\n      -- Config Command: ft232r restore_serial WORD\n          Restore serial port after JTAG. This USB bitmode control word\n          (16-bit) will be sent before quit.  Lower byte should set GPIO\n          direction register to a \"sane\" state: 0x15 for TXD RTS DTR as\n          outputs (1), others as inputs (0).  Higher byte is usually 0\n          to disable bitbang mode.  When kernel driver reattaches,\n          serial port should continue to work.  Value 0xFFFF disables\n          sending control word and serial port, then kernel driver will\n          not reattach.  If not specified, default 0xFFFF is used.\n\n -- Interface Driver: remote_bitbang\n     Drive JTAG from a remote process.  This sets up a UNIX or TCP\n     socket connection with a remote process and sends ASCII encoded\n     bitbang requests to that process instead of directly driving JTAG.\n\n     The remote_bitbang driver is useful for debugging software running\n     on processors which are being simulated.\n\n      -- Config Command: remote_bitbang port number\n          Specifies the TCP port of the remote process to connect to or\n          0 to use UNIX sockets instead of TCP.\n\n      -- Config Command: remote_bitbang host hostname\n          Specifies the hostname of the remote process to connect to\n          using TCP, or the name of the UNIX socket to use if\n          remote_bitbang port is 0.\n\n     For example, to connect remotely via TCP to the host foobar you\n     might have something like:\n\n          adapter driver remote_bitbang\n          remote_bitbang port 3335\n          remote_bitbang host foobar\n\n     To connect to another process running locally via UNIX sockets with\n     socket named mysocket:\n\n          adapter driver remote_bitbang\n          remote_bitbang port 0\n          remote_bitbang host mysocket\n\n -- Interface Driver: usb_blaster\n     USB JTAG/USB-Blaster compatibles over one of the userspace\n     libraries for FTDI chips.  These interfaces have several commands,\n     used to configure the driver before initializing the JTAG scan\n     chain:\n\n      -- Config Command: usb_blaster vid_pid vid pid\n          The vendor ID and product ID of the FTDI FT245 device.  If not\n          specified, default values are used.  Currently, only one VID,\n          PID pair may be given, e.g.  for Altera USB-Blaster (default):\n               usb_blaster vid_pid 0x09FB 0x6001\n          The following VID/PID is for Kolja Waschk's USB JTAG:\n               usb_blaster vid_pid 0x16C0 0x06AD\n\n      -- Command: usb_blaster pin (pin6|pin8) (0|1|s|t)\n          Sets the state or function of the unused GPIO pins on\n          USB-Blasters (pins 6 and 8 on the female JTAG header).  These\n          pins can be used as SRST and/or TRST provided the appropriate\n          connections are made on the target board.\n\n          For example, to use pin 6 as SRST:\n               usb_blaster pin pin6 s\n               reset_config srst_only\n\n      -- Config Command: usb_blaster lowlevel_driver (ftdi|ublast2)\n          Chooses the low level access method for the adapter.  If not\n          specified, 'ftdi' is selected unless it wasn't enabled during\n          the configure stage.  USB-Blaster II needs 'ublast2'.\n\n      -- Config Command: usb_blaster firmware PATH\n          This command specifies PATH to access USB-Blaster II firmware\n          image.  To be used with USB-Blaster II only.\n\n -- Interface Driver: gw16012\n     Gateworks GW16012 JTAG programmer.  This has one driver-specific\n     command:\n\n      -- Config Command: parport port [port_number]\n          Display either the address of the I/O port (default: 0x378 for\n          LPT1) or the number of the '/dev/parport' device.  If a\n          parameter is provided, first switch to use that port.  This is\n          a write-once setting.\n\n -- Interface Driver: jlink\n     SEGGER J-Link family of USB adapters.  It currently supports JTAG\n     and SWD transports.\n\n          Compatibility Note: SEGGER released many firmware versions for\n          the many hardware versions they produced.  OpenOCD was\n          extensively tested and intended to run on all of them, but\n          some combinations were reported as incompatible.  As a general\n          recommendation, it is advisable to use the latest firmware\n          version available for each hardware version.  However the\n          current V8 is a moving target, and SEGGER firmware versions\n          released after the OpenOCD was released may not be compatible.\n          In such cases it is recommended to revert to the last known\n          functional version.  For 0.5.0, this is from \"Feb 8 2012\n          14:30:39\", packed with 4.42c.  For 0.6.0, the last known\n          version is from \"May 3 2012 18:36:22\", packed with 4.46f.\n\n      -- Command: jlink hwstatus\n          Display various hardware related information, for example\n          target voltage and pin states.\n      -- Command: jlink freemem\n          Display free device internal memory.\n      -- Command: jlink jtag [2|3]\n          Set the JTAG command version to be used.  Without argument,\n          show the actual JTAG command version.\n      -- Command: jlink config\n          Display the device configuration.\n      -- Command: jlink config targetpower [on|off]\n          Set the target power state on JTAG-pin 19.  Without argument,\n          show the target power state.\n      -- Command: jlink config mac [ff:ff:ff:ff:ff:ff]\n          Set the MAC address of the device.  Without argument, show the\n          MAC address.\n      -- Command: jlink config ip [A.B.C.D(/E|F.G.H.I)]\n          Set the IP configuration of the device, where A.B.C.D is the\n          IP address, E the bit of the subnet mask and F.G.H.I the\n          subnet mask.  Without arguments, show the IP configuration.\n      -- Command: jlink config usb [0 to 3]\n          Set the USB address of the device.  This will also change the\n          USB Product ID (PID) of the device.  Without argument, show\n          the USB address.\n      -- Command: jlink config reset\n          Reset the current configuration.\n      -- Command: jlink config write\n          Write the current configuration to the internal persistent\n          storage.\n      -- Command: jlink emucom write <channel> <data>\n          Write data to an EMUCOM channel.  The data needs to be encoded\n          as hexadecimal pairs.\n\n          The following example shows how to write the three bytes 0xaa,\n          0x0b and 0x23 to the EMUCOM channel 0x10:\n               > jlink emucom write 0x10 aa0b23\n      -- Command: jlink emucom read <channel> <length>\n          Read data from an EMUCOM channel.  The read data is encoded as\n          hexadecimal pairs.\n\n          The following example shows how to read 4 bytes from the\n          EMUCOM channel 0x0:\n               > jlink emucom read 0x0 4\n               77a90000\n      -- Config Command: jlink usb <0 to 3>\n          Set the USB address of the interface, in case more than one\n          adapter is connected to the host.  If not specified, USB\n          addresses are not considered.  Device selection via USB\n          address is not always unambiguous.  It is recommended to use\n          the serial number instead, if possible.\n\n          As a configuration command, it can be used only before 'init'.\n\n -- Interface Driver: kitprog\n     This driver is for Cypress Semiconductor's KitProg adapters.  The\n     KitProg is an SWD-only adapter that is designed to be used with\n     Cypress's PSoC and PRoC device families, but it is possible to use\n     it with some other devices.  If you are using this adapter with a\n     PSoC or a PRoC, you may need to add 'kitprog_init_acquire_psoc' or\n     'kitprog acquire_psoc' to your configuration script.\n\n     Note that this driver is for the proprietary KitProg protocol, not\n     the CMSIS-DAP mode introduced in firmware 2.14.  If the KitProg is\n     in CMSIS-DAP mode, it cannot be used with this driver, and must\n     either be used with the cmsis-dap driver or switched back to\n     KitProg mode.  See the Cypress KitProg User Guide for instructions\n     on how to switch KitProg modes.\n\n     Known limitations:\n        * The frequency of SWCLK cannot be configured, and varies\n          between 1.6 MHz and 2.7 MHz.\n        * For firmware versions below 2.14, \"JTAG to SWD\" sequences are\n          replaced by \"SWD line reset\" in the driver.  This is for two\n          reasons.  First, the KitProg does not support sending\n          arbitrary SWD sequences, and only firmware 2.14 and later\n          implement both \"JTAG to SWD\" and \"SWD line reset\" in firmware.\n          Earlier firmware versions only implement \"SWD line reset\".\n          Second, due to a firmware quirk, an SWD sequence must be sent\n          after every target reset in order to re-establish\n          communications with the target.\n        * Due in part to the limitation above, KitProg devices with\n          firmware below version 2.14 will need to use\n          'kitprog_init_acquire_psoc' in order to communicate with PSoC\n          5LP devices.  This is because, assuming debug is not disabled\n          on the PSoC, the PSoC 5LP needs its JTAG interface switched to\n          SWD mode before communication can begin, but prior to firmware\n          2.14, \"JTAG to SWD\" could only be sent with an acquisition\n          sequence.\n\n      -- Config Command: kitprog_init_acquire_psoc\n          Indicate that a PSoC acquisition sequence needs to be run\n          during adapter init.  Please be aware that the acquisition\n          sequence hard-resets the target.\n\n      -- Command: kitprog acquire_psoc\n          Run a PSoC acquisition sequence immediately.  Typically, this\n          should not be used outside of the target-specific\n          configuration scripts since it hard-resets the target as a\n          side-effect.  This is necessary for \"reset halt\" on some PSoC\n          4 series devices.\n\n      -- Command: kitprog info\n          Display various adapter information, such as the hardware\n          version, firmware version, and target voltage.\n\n -- Interface Driver: parport\n     Supports PC parallel port bit-banging cables: Wigglers, PLD\n     download cable, and more.  These interfaces have several commands,\n     used to configure the driver before initializing the JTAG scan\n     chain:\n\n      -- Config Command: parport cable name\n          Set the layout of the parallel port cable used to connect to\n          the target.  This is a write-once setting.  Currently valid\n          cable NAME values include:\n\n             - altium Altium Universal JTAG cable.\n             - arm-jtag Same as original wiggler except SRST and TRST\n               connections reversed and TRST is also inverted.\n             - chameleon The Amontec Chameleon's CPLD when operated in\n               configuration mode.  This is only used to program the\n               Chameleon itself, not a connected target.\n             - dlc5 The Xilinx Parallel cable III.\n             - flashlink The ST Parallel cable.\n             - lattice Lattice ispDOWNLOAD Cable\n             - old_amt_wiggler The Wiggler configuration that comes with\n               some versions of Amontec's Chameleon Programmer.  The new\n               version available from the website uses the original\n               Wiggler layout ('WIGGLER')\n             - triton The parallel port adapter found on the \"Karo\n               Triton 1 Development Board\".  This is also the layout\n               used by the HollyGates design (see\n               <http://www.lartmaker.nl/projects/jtag/>).\n             - wiggler The original Wiggler layout, also supported by\n               several clones, such as the Olimex ARM-JTAG\n             - wiggler2 Same as original wiggler except an led is fitted\n               on D5.\n             - wiggler_ntrst_inverted Same as original wiggler except\n               TRST is inverted.\n\n      -- Config Command: parport port [port_number]\n          Display either the address of the I/O port (default: 0x378 for\n          LPT1) or the number of the '/dev/parport' device.  If a\n          parameter is provided, first switch to use that port.  This is\n          a write-once setting.\n\n          When using PPDEV to access the parallel port, use the number\n          of the parallel port: 'parport port 0' (the default).  If\n          'parport port 0x378' is specified you may encounter a problem.\n\n      -- Config Command: parport toggling_time [nanoseconds]\n          Displays how many nanoseconds the hardware needs to toggle\n          TCK; the parport driver uses this value to obey the 'adapter\n          speed' configuration.  When the optional NANOSECONDS parameter\n          is given, that setting is changed before displaying the\n          current value.\n\n          The default setting should work reasonably well on commodity\n          PC hardware.  However, you may want to calibrate for your\n          specific hardware.\n               Tip: To measure the toggling time with a logic analyzer\n               or a digital storage oscilloscope, follow the procedure\n               below:\n                    > parport toggling_time 1000\n                    > adapter speed 500\n               This sets the maximum JTAG clock speed of the hardware,\n               but the actual speed probably deviates from the requested\n               500 kHz.  Now, measure the time between the two closest\n               spaced TCK transitions.  You can use 'runtest 1000' or\n               something similar to generate a large set of samples.\n               Update the setting to match your measurement:\n                    > parport toggling_time <measured nanoseconds>\n               Now the clock speed will be a better match for 'adapter\n               speed' command given in OpenOCD scripts and event\n               handlers.\n\n               You can do something similar with many digital\n               multimeters, but note that you'll probably need to run\n               the clock continuously for several seconds before it\n               decides what clock rate to show.  Adjust the toggling\n               time up or down until the measured clock rate is a good\n               match with the rate you specified in the 'adapter speed'\n               command; be conservative.\n\n      -- Config Command: parport write_on_exit (on|off)\n          This will configure the parallel driver to write a known\n          cable-specific value to the parallel interface on exiting\n          OpenOCD.\n\n     For example, the interface configuration file for a classic\n     \"Wiggler\" cable on LPT2 might look something like this:\n\n          adapter driver parport\n          parport port 0x278\n          parport cable wiggler\n\n -- Interface Driver: presto\n     ASIX PRESTO USB JTAG programmer.\n\n -- Interface Driver: rlink\n     Raisonance RLink USB adapter\n\n -- Interface Driver: usbprog\n     usbprog is a freely programmable USB adapter.\n\n -- Interface Driver: vsllink\n     vsllink is part of Versaloon which is a versatile USB programmer.\n\n          Note: This defines quite a few driver-specific commands, which\n          are not currently documented here.\n\n -- Interface Driver: hla\n     This is a driver that supports multiple High Level Adapters.  This\n     type of adapter does not expose some of the lower level api's that\n     OpenOCD would normally use to access the target.\n\n     Currently supported adapters include the STMicroelectronics\n     ST-LINK, TI ICDI and Nuvoton Nu-Link.  ST-LINK firmware version >=\n     V2.J21.S4 recommended due to issues with earlier versions of\n     firmware where serial number is reset after first use.  Suggest\n     using ST firmware update utility to upgrade ST-LINK firmware even\n     if current version reported is V2.J21.S4.\n\n      -- Config Command: hla_device_desc description\n          Currently Not Supported.\n\n      -- Config Command: hla_layout (stlink|icdi|nulink)\n          Specifies the adapter layout to use.\n\n      -- Config Command: hla_vid_pid [vid pid]+\n          Pairs of vendor IDs and product IDs of the device.\n\n      -- Config Command: hla_stlink_backend (usb | tcp [port])\n          _ST-Link only:_ Choose between 'exclusive' USB communication\n          (the default backend) or 'shared' mode using ST-Link TCP\n          server (the default port is 7184).\n\n          _Note:_ ST-Link TCP server is a binary application provided by\n          ST available from ST-LINK server software module\n          (https://www.st.com/en/development-tools/st-link-server.html).\n\n      -- Command: hla_command command\n          Execute a custom adapter-specific command.  The COMMAND string\n          is passed as is to the underlying adapter layout handler.\n\n -- Interface Driver: st-link\n     This is a driver that supports STMicroelectronics adapters\n     ST-LINK/V2 (from firmware V2J24) and STLINK-V3, thanks to a new API\n     that provides directly access the arm ADIv5 DAP.\n\n     The new API provide access to multiple AP on the same DAP, but the\n     maximum number of the AP port is limited by the specific firmware\n     version (e.g.  firmware V2J29 has 3 as maximum AP number, while\n     V2J32 has 8).  An error is returned for any AP number above the\n     maximum allowed value.\n\n     _Note:_ Either these same adapters and their older versions are\n     also supported by *note the hla interface driver: hla_interface.\n\n      -- Config Command: st-link backend (usb | tcp [port])\n          Choose between 'exclusive' USB communication (the default\n          backend) or 'shared' mode using ST-Link TCP server (the\n          default port is 7184).\n\n          _Note:_ ST-Link TCP server is a binary application provided by\n          ST available from ST-LINK server software module\n          (https://www.st.com/en/development-tools/st-link-server.html).\n\n          _Note:_ ST-Link TCP server does not support the SWIM\n          transport.\n\n      -- Config Command: st-link vid_pid [vid pid]+\n          Pairs of vendor IDs and product IDs of the device.\n\n      -- Command: st-link cmd rx_n (tx_byte)+\n          Sends an arbitrary command composed by the sequence of bytes\n          TX_BYTE and receives RX_N bytes.\n\n          For example, the command to read the target's supply voltage\n          is one byte 0xf7 followed by 15 bytes zero.  It returns 8\n          bytes, where the first 4 bytes represent the ADC sampling of\n          the reference voltage 1.2V and the last 4 bytes represent the\n          ADC sampling of half the target's supply voltage.\n               > st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n               0xf1 0x05 0x00 0x00 0x0b 0x08 0x00 0x00\n          The result can be converted to Volts (ignoring the most\n          significant bytes, always zero)\n               > set a [st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n               > set n [expr {[lindex $a 4] + 256 * [lindex $a 5]}]\n               > set d [expr {[lindex $a 0] + 256 * [lindex $a 1]}]\n               > echo [expr {2 * 1.2 * $n / $d}]\n               3.24891518738\n\n -- Interface Driver: opendous\n     opendous-jtag is a freely programmable USB adapter.\n\n -- Interface Driver: ulink\n     This is the Keil ULINK v1 JTAG debugger.\n\n -- Interface Driver: xds110\n     The XDS110 is included as the embedded debug probe on many Texas\n     Instruments LaunchPad evaluation boards.  The XDS110 is also\n     available as a stand-alone USB debug probe with the added\n     capability to supply power to the target board.  The following\n     commands are supported by the XDS110 driver:\n\n      -- Config Command: xds110 supply voltage_in_millivolts\n          Available only on the XDS110 stand-alone probe.  Sets the\n          voltage level of the XDS110 power supply.  A value of 0 leaves\n          the supply off.  Otherwise, the supply can be set to any value\n          in the range 1800 to 3600 millivolts.\n\n      -- Command: xds110 info\n          Displays information about the connected XDS110 debug probe\n          (e.g.  firmware version).\n\n -- Interface Driver: xlnx_pcie_xvc\n     This driver supports the Xilinx Virtual Cable (XVC) over PCI\n     Express.  It is commonly found in Xilinx based PCI Express designs.\n     It allows debugging fabric based JTAG/SWD devices such as\n     Cortex-M1/M3 microcontrollers.  Access to this is exposed via\n     extended capability registers in the PCI Express configuration\n     space.\n\n     For more information see Xilinx PG245 (Section on From_PCIE_to_JTAG\n     mode).\n\n      -- Config Command: xlnx_pcie_xvc config device\n          Specifies the PCI Express device via parameter DEVICE to use.\n\n          The correct value for DEVICE can be obtained by looking at the\n          output of lscpi -D (first column) for the corresponding\n          device.\n\n          The string will be of the format \"DDDD:BB:SS.F\" such as\n          \"0000:65:00.1\".\n\n -- Interface Driver: bcm2835gpio\n     This SoC is present in Raspberry Pi which is a cheap single-board\n     computer exposing some GPIOs on its expansion header.\n\n     The driver accesses memory-mapped GPIO peripheral registers\n     directly for maximum performance, but the only possible race\n     condition is for the pins' modes/muxing (which is highly unlikely),\n     so it should be able to coexist nicely with both sysfs bitbanging\n     and various peripherals' kernel drivers.  The driver restores the\n     previous configuration on exit.\n\n     GPIO numbers >= 32 can't be used for performance reasons.\n\n     See 'interface/raspberrypi-native.cfg' for a sample config and\n     pinout.\n\n      -- Config Command: bcm2835gpio jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: bcm2835gpio tck_num TCK\n          Set TCK GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tms_num TMS\n          Set TMS GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tdo_num TDO\n          Set TDO GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio tdi_num TDI\n          Set TDI GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio jtag_nums'.\n\n      -- Config Command: bcm2835gpio swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: bcm2835gpio swclk_num SWCLK\n          Set SWCLK GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio swd_nums'.\n\n      -- Config Command: bcm2835gpio swdio_num SWDIO\n          Set SWDIO GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'bcm2835gpio swd_nums'.\n\n      -- Config Command: bcm2835gpio swdio_dir_num SWDIO DIR\n          Set SWDIO direction control pin GPIO number.  If specified,\n          this pin can be used to control the direction of an external\n          buffer on the SWDIO pin (set=output mode, clear=input mode).\n          If not specified, this feature is disabled.\n\n      -- Config Command: bcm2835gpio srst_num SRST\n          Set SRST GPIO number.  Must be specified to enable SRST.\n\n      -- Config Command: bcm2835gpio trst_num TRST\n          Set TRST GPIO number.  Must be specified to enable TRST.\n\n      -- Config Command: bcm2835gpio speed_coeffs SPEED_COEFF\n               SPEED_OFFSET\n          Set SPEED_COEFF and SPEED_OFFSET for delay calculations.  If\n          unspecified, speed_coeff defaults to 113714, and speed_offset\n          defaults to 28.\n\n      -- Config Command: bcm2835gpio peripheral_base BASE\n          Set the peripheral base register address to access GPIOs.  For\n          the RPi1, use 0x20000000.  For RPi2 and RPi3, use 0x3F000000.\n          For RPi4, use 0xFE000000.  A full list can be found in the\n          official guide\n          (https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md).\n\n -- Interface Driver: imx_gpio\n     i.MX SoC is present in many community boards.  Wandboard is an\n     example of the one which is most popular.\n\n     This driver is mostly the same as bcm2835gpio.\n\n     See 'interface/imx-native.cfg' for a sample config and pinout.\n\n -- Interface Driver: am335xgpio The AM335x SoC is present in BeagleBone\n     Black and BeagleBone Green single-board computers which expose some\n     of the GPIOs on the two expansion headers.\n\n     For maximum performance the driver accesses memory-mapped GPIO\n     peripheral registers directly.  The memory mapping requires read\n     and write permission to kernel memory; if /dev/gpiomem exists it\n     will be used, otherwise /dev/mem will be used.  The driver restores\n     the GPIO state on exit.\n\n     All four GPIO ports are available.  GPIOs numbered 0 to 31 are\n     mapped to GPIO port 0, GPIO numbers 32 to 63 are mapped to GPIO\n     port 1 and so on.\n\n     See 'interface/beaglebone-swd-native.cfg' for a sample\n     configuration file.\n\n      -- Config Command: am335xgpio jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: am335xgpio tck_num TCK\n          Set TCK GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tms_num TMS\n          Set TMS GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tdo_num TDO\n          Set TDO GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio tdi_num TDI\n          Set TDI GPIO number.  Must be specified to enable JTAG\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio jtag_nums'.\n\n      -- Config Command: am335xgpio swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: am335xgpio swclk_num SWCLK\n          Set SWCLK GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio swd_nums'.\n\n      -- Config Command: am335xgpio swdio_num SWDIO\n          Set SWDIO GPIO number.  Must be specified to enable SWD\n          transport.  Can also be specified using the configuration\n          command 'am335xgpio swd_nums'.\n\n      -- Config Command: am335xgpio swdio_dir_num SWDIO_DIR\n          Set SWDIO direction control pin GPIO number.  If specified,\n          this pin can be used to control the direction of an external\n          buffer on the SWDIO pin.  The direction control state can be\n          set with the command 'am335xgpio swdio_dir_output_state'.  If\n          not specified this feature is disabled.\n\n      -- Config Command: am335xgpio swdio_dir_output_state OUTPUT_STATE\n          Set the state required for an external SWDIO buffer to be an\n          output.  Valid values are 'on' (default) and 'off'.\n\n      -- Config Command: am335xgpio srst_num SRST\n          Set SRST GPIO number.  Must be specified to enable SRST.\n\n      -- Config Command: am335xgpio trst_num TRST\n          Set TRST GPIO number.  Must be specified to enable TRST.\n\n      -- Config Command: am335xgpio led_num LED\n          Set activity LED GPIO number.  If not specified an activity\n          LED is not enabled.\n\n      -- Config Command: am335xgpio led_on_state ON_STATE\n          Set required logic level for the LED to be on.  Valid values\n          are 'on' (default) and 'off'.\n\n      -- Config Command: am335xgpio speed_coeffs SPEED_COEFF\n               SPEED_OFFSET\n          Set SPEED_COEFF and SPEED_OFFSET for delay calculations.  If\n          unspecified speed_coeff defaults to 600000 and speed_offset\n          defaults to 575.\n\n -- Interface Driver: linuxgpiod\n     Linux provides userspace access to GPIO through libgpiod since\n     Linux kernel version v4.6.  The driver emulates either JTAG or SWD\n     transport through bitbanging.\n\n     See 'interface/dln-2-gpiod.cfg' for a sample config.\n\n      -- Config Command: linuxgpiod gpiochip CHIP\n          Set the GPIO chip number for all GPIOs used by linuxgpiod.  If\n          GPIOs use different GPIO chips then the individual GPIO\n          configuration commands (i.e., not 'linuxgpiod jtag_nums' or\n          'linuxgpiod swd_nums') can be used to set chip numbers\n          independently for each GPIO.\n\n      -- Config Command: linuxgpiod jtag_nums TCK TMS TDI TDO\n          Set JTAG transport GPIO numbers for TCK, TMS, TDI, and TDO (in\n          that order).  Must be specified to enable JTAG transport.\n          These pins can also be specified individually.\n\n      -- Config Command: linuxgpiod tck_num [CHIP] TCK\n          Set TCK GPIO number, and optionally TCK chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tms_num [CHIP] TMS\n          Set TMS GPIO number, and optionally TMS chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tdo_num [CHIP] TDO\n          Set TDO GPIO number, and optionally TDO chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod tdi_num [CHIP] TDI\n          Set TDI GPIO number, and optionally TDI chip number.  Must be\n          specified to enable JTAG transport.  Can also be specified\n          using the configuration command 'linuxgpiod jtag_nums'.\n\n      -- Config Command: linuxgpiod trst_num [CHIP] TRST\n          Set TRST GPIO number, and optionally TRST chip number.  Must\n          be specified to enable TRST.\n\n      -- Config Command: linuxgpiod swd_nums SWCLK SWDIO\n          Set SWD transport GPIO numbers for SWCLK and SWDIO (in that\n          order).  Must be specified to enable SWD transport.  These\n          pins can also be specified individually.\n\n      -- Config Command: linuxgpiod swclk_num [CHIP] SWCLK\n          Set SWCLK GPIO number, and optionally SWCLK chip number.  Must\n          be specified to enable SWD transport.  Can also be specified\n          using the configuration command 'linuxgpiod swd_nums'.\n\n      -- Config Command: linuxgpiod swdio_num [CHIP] SWDIO\n          Set SWDIO GPIO number, and optionally SWDIO chip number.  Must\n          be specified to enable SWD transport.  Can also be specified\n          using the configuration command 'linuxgpiod swd_nums'.\n\n      -- Config Command: linuxgpiod swdio_dir_num [CHIP] SWDIO_DIR\n          Set SWDIO direction control GPIO number, and optionally SWDIO\n          direction control chip number.  If specified, this GPIO can be\n          used to control the direction of an external buffer connected\n          to the SWDIO GPIO (set=output mode, clear=input mode).\n\n      -- Config Command: linuxgpiod srst_num [CHIP] SRST\n          Set SRST GPIO number, and optionally SRST chip number.  Must\n          be specified to enable SRST.\n\n      -- Config Command: linuxgpiod led_num [CHIP] LED\n          Set activity LED GPIO number, and optionally activity LED chip\n          number.  If not specified an activity LED is not enabled.\n\n -- Interface Driver: sysfsgpio\n     Linux legacy userspace access to GPIO through sysfs is deprecated\n     from Linux kernel version v5.3.  Prefer using linuxgpiod, instead.\n\n     See 'interface/sysfsgpio-raspberrypi.cfg' for a sample config.\n\n -- Interface Driver: openjtag\n     OpenJTAG compatible USB adapter.  This defines some driver-specific\n     commands:\n\n      -- Config Command: openjtag variant variant\n          Specifies the variant of the OpenJTAG adapter (see\n          <http://www.openjtag.org/>).  Currently valid VARIANT values\n          include:\n\n             - standard Standard variant (default).\n             - cy7c65215 Cypress CY7C65215 Dual Channel USB-Serial\n               Bridge Controller (see\n               <http://www.cypress.com/?rID=82870>).\n\n      -- Config Command: openjtag device_desc string\n          The USB device description string of the adapter.  This value\n          is only used with the standard variant.\n\n -- Interface Driver: vdebug\n     Cadence Virtual Debug Interface driver.\n\n      -- Config Command: vdebug server host:port\n          Specifies the host and TCP port number where the vdebug server\n          runs.\n\n      -- Config Command: vdebug batching value\n          Specifies the batching method for the vdebug request.\n          Possible values are 0 for no batching 1 or wr to batch write\n          transactions together (default) 2 or rw to batch both read and\n          write transactions\n\n      -- Config Command: vdebug polling min max\n          Takes two values, representing the polling interval in ms.\n          Lower values mean faster debugger responsiveness, but lower\n          emulation performance.  The minimum should be around 10,\n          maximum should not exceed 1000, which is the default gdb and\n          keepalive timeout value.\n\n      -- Config Command: vdebug bfm_path path clk_period\n          Specifies the hierarchical path and input clk period of the\n          vdebug BFM in the design.  The hierarchical path uses Verilog\n          notation top.inst.inst The clock period must include the unit,\n          for instance 40ns.\n\n      -- Config Command: vdebug mem_path path base size\n          Specifies the hierarchical path to the design memory instance\n          for backdoor access.  Up to 4 memories can be specified.  The\n          hierarchical path uses Verilog notation.  The base specifies\n          start address in the design address space, size its size in\n          bytes.  Both values can use hexadecimal notation with prefix\n          0x.\n\n -- Interface Driver: jtag_dpi\n     SystemVerilog Direct Programming Interface (DPI) compatible driver\n     for JTAG devices in emulation.  The driver acts as a client for the\n     SystemVerilog DPI server interface.\n\n      -- Config Command: jtag_dpi set_port port\n          Specifies the TCP/IP port number of the SystemVerilog DPI\n          server interface.\n\n      -- Config Command: jtag_dpi set_address address\n          Specifies the TCP/IP address of the SystemVerilog DPI server\n          interface.\n\n -- Interface Driver: buspirate\n\n     This driver is for the Bus Pirate (see\n     <http://dangerousprototypes.com/docs/Bus_Pirate>) and compatible\n     devices.  It uses a simple data protocol over a serial port\n     connection.\n\n     Most hardware development boards have a UART, a real serial port,\n     or a virtual USB serial device, so this driver allows you to start\n     building your own JTAG adapter without the complexity of a custom\n     USB connection.\n\n      -- Config Command: buspirate port serial_port\n          Specify the serial port's filename.  For example:\n               buspirate port /dev/ttyUSB0\n\n      -- Config Command: buspirate speed (normal|fast)\n          Set the communication speed to 115k (normal) or 1M (fast).\n          For example:\n               buspirate speed normal\n\n      -- Config Command: buspirate mode (normal|open-drain)\n          Set the Bus Pirate output mode.\n             - In normal mode (push/pull), do not enable the pull-ups,\n               and do not connect I/O header pin VPU to JTAG VREF.\n             - In open drain mode, you will then need to enable the\n               pull-ups.\n          For example:\n               buspirate mode normal\n\n      -- Config Command: buspirate pullup (0|1)\n          Whether to connect (1) or not (0) the I/O header pin VPU (JTAG\n          VREF) to the pull-up/pull-down resistors on MOSI (JTAG TDI),\n          CLK (JTAG TCK), MISO (JTAG TDO) and CS (JTAG TMS). For\n          example:\n               buspirate pullup 0\n\n      -- Config Command: buspirate vreg (0|1)\n          Whether to enable (1) or disable (0) the built-in voltage\n          regulator, which can be used to supply power to a test circuit\n          through I/O header pins +3V3 and +5V. For example:\n               buspirate vreg 0\n\n      -- Command: buspirate led (0|1)\n          Turns the Bus Pirate's LED on (1) or off (0).  For example:\n          buspirate led 1\n\n8.3 Transport Configuration\n===========================\n\nAs noted earlier, depending on the version of OpenOCD you use, and the\ndebug adapter you are using, several transports may be available to\ncommunicate with debug targets (or perhaps to program flash memory).\n -- Command: transport list\n     displays the names of the transports supported by this version of\n     OpenOCD.\n\n -- Command: transport select transport_name\n     Select which of the supported transports to use in this OpenOCD\n     session.\n\n     When invoked with 'transport_name', attempts to select the named\n     transport.  The transport must be supported by the debug adapter\n     hardware and by the version of OpenOCD you are using (including the\n     adapter's driver).\n\n     If no transport has been selected and no 'transport_name' is\n     provided, 'transport select' auto-selects the first transport\n     supported by the debug adapter.\n\n     'transport select' always returns the name of the session's\n     selected transport, if any.\n\n8.3.1 JTAG Transport\n--------------------\n\nJTAG is the original transport supported by OpenOCD, and most of the\nOpenOCD commands support it.  JTAG transports expose a chain of one or\nmore Test Access Points (TAPs), each of which must be explicitly\ndeclared.  JTAG supports both debugging and boundary scan testing.\nFlash programming support is built on top of debug support.\n\nJTAG transport is selected with the command 'transport select jtag'.\nUnless your adapter uses either *note the hla interface driver:\nhla_interface. (in which case the command is 'transport select\nhla_jtag') or *note the st-link interface driver: st_link_dap_interface.\n(in which case the command is 'transport select dapdirect_jtag').\n\n8.3.2 SWD Transport\n-------------------\n\nSWD (Serial Wire Debug) is an ARM-specific transport which exposes one\nDebug Access Point (DAP, which must be explicitly declared.  (SWD uses\nfewer signal wires than JTAG.) SWD is debug-oriented, and does not\nsupport boundary scan testing.  Flash programming support is built on\ntop of debug support.  (Some processors support both JTAG and SWD.)\n\nSWD transport is selected with the command 'transport select swd'.\nUnless your adapter uses either *note the hla interface driver:\nhla_interface. (in which case the command is 'transport select hla_swd')\nor *note the st-link interface driver: st_link_dap_interface. (in which\ncase the command is 'transport select dapdirect_swd').\n\n -- Config Command: swd newdap ...\n     Declares a single DAP which uses SWD transport.  Parameters are\n     currently the same as \"jtag newtap\" but this is expected to change.\n\nThe newer SWD devices (SW-DP v2 or SWJ-DP v2) support the multi-drop\nextension of SWD protocol: two or more devices can be connected to one\nSWD adapter.  SWD transport works in multi-drop mode if *note DAP:\ndap_create. is configured with both '-dp-id' and '-instance-id'\nparameters regardless how many DAPs are created.\n\nNot all adapters and adapter drivers support SWD multi-drop.  Only the\nfollowing adapter drivers are SWD multi-drop capable: cmsis_dap (use an\nadapter with CMSIS-DAP version 2.0), ftdi, all bitbang based.\n\n8.3.3 SPI Transport\n-------------------\n\nThe Serial Peripheral Interface (SPI) is a general purpose transport\nwhich uses four wire signaling.  Some processors use it as part of a\nsolution for flash programming.\n\n8.3.4 SWIM Transport\n--------------------\n\nThe Single Wire Interface Module (SWIM) is a low-pin-count debug\nprotocol used by the STMicroelectronics MCU family STM8 and documented\nin the User Manual UM470\n(https://www.st.com/resource/en/user_manual/cd00173911.pdf).\n\nSWIM does not support boundary scan testing nor multiple cores.\n\nThe SWIM transport is selected with the command 'transport select swim'.\n\nThe concept of TAPs does not fit in the protocol since SWIM does not\nimplement a scan chain.  Nevertheless, the current SW model of OpenOCD\nrequires defining a virtual SWIM TAP through the command 'swim newtap\nbasename tap_type'.  The TAP definition must precede the target\ndefinition command 'target create target_name stm8 -chain-position\nbasename.tap_type'.\n\n8.4 JTAG Speed\n==============\n\nJTAG clock setup is part of system setup.  It _does not belong with\ninterface setup_ since any interface only knows a few of the constraints\nfor the JTAG clock speed.  Sometimes the JTAG speed is changed during\nthe target initialization process: (1) slow at reset, (2) program the\nCPU clocks, (3) run fast.  Both the \"slow\" and \"fast\" clock rates are\nfunctions of the oscillators used, the chip, the board design, and\nsometimes power management software that may be active.\n\nThe speed used during reset, and the scan chain verification which\nfollows reset, can be adjusted using a 'reset-start' target event\nhandler.  It can then be reconfigured to a faster speed by a\n'reset-init' target event handler after it reprograms those CPU clocks,\nor manually (if something else, such as a boot loader, sets up those\nclocks).  *Note Target Events: targetevents.  When the initial low JTAG\nspeed is a chip characteristic, perhaps because of a required oscillator\nspeed, provide such a handler in the target config file.  When that\nspeed is a function of a board-specific characteristic such as which\nspeed oscillator is used, it belongs in the board config file instead.\nIn both cases it's safest to also set the initial JTAG clock rate to\nthat same slow speed, so that OpenOCD never starts up using a clock\nspeed that's faster than the scan chain can support.\n\n     jtag_rclk 3000\n     $_TARGET.cpu configure -event reset-start { jtag_rclk 3000 }\n\nIf your system supports adaptive clocking (RTCK), configuring JTAG to\nuse that is probably the most robust approach.  However, it introduces\ndelays to synchronize clocks; so it may not be the fastest solution.\n\nNOTE: Script writers should consider using 'jtag_rclk' instead of\n'adapter speed', but only for (ARM) cores and boards which support\nadaptive clocking.\n\n -- Command: adapter speed max_speed_kHz\n     A non-zero speed is in KHZ. Hence: 3000 is 3mhz.  JTAG interfaces\n     usually support a limited number of speeds.  The speed actually\n     used won't be faster than the speed specified.\n\n     Chip data sheets generally include a top JTAG clock rate.  The\n     actual rate is often a function of a CPU core clock, and is\n     normally less than that peak rate.  For example, most ARM cores\n     accept at most one sixth of the CPU clock.\n\n     Speed 0 (khz) selects RTCK method.  *Note FAQ RTCK: faqrtck.  If\n     your system uses RTCK, you won't need to change the JTAG clocking\n     after setup.  Not all interfaces, boards, or targets support\n     \"rtck\".  If the interface device can not support it, an error is\n     returned when you try to use RTCK.\n\n -- Function: jtag_rclk fallback_speed_kHz\n     This Tcl proc (defined in 'startup.tcl') attempts to enable\n     RTCK/RCLK. If that fails (maybe the interface, board, or target\n     doesn't support it), falls back to the specified frequency.\n          # Fall back to 3mhz if RTCK is not supported\n          jtag_rclk 3000\n\n\u001f\nFile: openocd.info,  Node: Reset Configuration,  Next: TAP Declaration,  Prev: Debug Adapter Configuration,  Up: Top\n\n9 Reset Configuration\n*********************\n\nEvery system configuration may require a different reset configuration.\nThis can also be quite confusing.  Resets also interact with RESET-INIT\nevent handlers, which do things like setting up clocks and DRAM, and\nJTAG clock rates.  (*Note JTAG Speed: jtagspeed.)  They can also\ninteract with JTAG routers.  Please see the various board files for\nexamples.\n\n     Note: To maintainers and integrators: Reset configuration touches\n     several things at once.  Normally the board configuration file\n     should define it and assume that the JTAG adapter supports\n     everything that's wired up to the board's JTAG connector.\n\n     However, the target configuration file could also make note of\n     something the silicon vendor has done inside the chip, which will\n     be true for most (or all) boards using that chip.  And when the\n     JTAG adapter doesn't support everything, the user configuration\n     file will need to override parts of the reset configuration\n     provided by other files.\n\n9.1 Types of Reset\n==================\n\nThere are many kinds of reset possible through JTAG, but they may not\nall work with a given board and adapter.  That's part of why reset\nconfiguration can be error prone.\n\n   * _System Reset_ ...  the _SRST_ hardware signal resets all chips\n     connected to the JTAG adapter, such as processors, power management\n     chips, and I/O controllers.  Normally resets triggered with this\n     signal behave exactly like pressing a RESET button.\n   * _JTAG TAP Reset_ ...  the _TRST_ hardware signal resets just the\n     TAP controllers connected to the JTAG adapter.  Such resets should\n     not be visible to the rest of the system; resetting a device's TAP\n     controller just puts that controller into a known state.\n   * _Emulation Reset_ ...  many devices can be reset through JTAG\n     commands.  These resets are often distinguishable from system\n     resets, either explicitly (a \"reset reason\" register says so) or\n     implicitly (not all parts of the chip get reset).\n   * _Other Resets_ ...  system-on-chip devices often support several\n     other types of reset.  You may need to arrange that a watchdog\n     timer stops while debugging, preventing a watchdog reset.  There\n     may be individual module resets.\n\nIn the best case, OpenOCD can hold SRST, then reset the TAPs via TRST\nand send commands through JTAG to halt the CPU at the reset vector\nbefore the 1st instruction is executed.  Then when it finally releases\nthe SRST signal, the system is halted under debugger control before any\ncode has executed.  This is the behavior required to support the 'reset\nhalt' and 'reset init' commands; after 'reset init' a board-specific\nscript might do things like setting up DRAM. (*Note Reset Command:\nresetcommand.)\n\n9.2 SRST and TRST Issues\n========================\n\nBecause SRST and TRST are hardware signals, they can have a variety of\nsystem-specific constraints.  Some of the most common issues are:\n\n   * _Signal not available_ ...  Some boards don't wire SRST or TRST to\n     the JTAG connector.  Some JTAG adapters don't support such signals\n     even if they are wired up.  Use the 'reset_config' SIGNALS options\n     to say when either of those signals is not connected.  When SRST is\n     not available, your code might not be able to rely on controllers\n     having been fully reset during code startup.  Missing TRST is not a\n     problem, since JTAG-level resets can be triggered using with TMS\n     signaling.\n\n   * _Signals shorted_ ...  Sometimes a chip, board, or adapter will\n     connect SRST to TRST, instead of keeping them separate.  Use the\n     'reset_config' COMBINATION options to say when those signals aren't\n     properly independent.\n\n   * _Timing_ ...  Reset circuitry like a resistor/capacitor delay\n     circuit, reset supervisor, or on-chip features can extend the\n     effect of a JTAG adapter's reset for some time after the adapter\n     stops issuing the reset.  For example, there may be chip or board\n     requirements that all reset pulses last for at least a certain\n     amount of time; and reset buttons commonly have hardware\n     debouncing.  Use the 'adapter srst delay' and 'jtag_ntrst_delay'\n     commands to say when extra delays are needed.\n\n   * _Drive type_ ...  Reset lines often have a pullup resistor, letting\n     the JTAG interface treat them as open-drain signals.  But that's\n     not a requirement, so the adapter may need to use push/pull output\n     drivers.  Also, with weak pullups it may be advisable to drive\n     signals to both levels (push/pull) to minimize rise times.  Use the\n     'reset_config' TRST_TYPE and SRST_TYPE parameters to say how to\n     drive reset signals.\n\n   * _Special initialization_ ...  Targets sometimes need special JTAG\n     initialization sequences to handle chip-specific issues (not\n     limited to errata).  For example, certain JTAG commands might need\n     to be issued while the system as a whole is in a reset state (SRST\n     active) but the JTAG scan chain is usable (TRST inactive).  Many\n     systems treat combined assertion of SRST and TRST as a trigger for\n     a harder reset than SRST alone.  Such custom reset handling is\n     discussed later in this chapter.\n\nThere can also be other issues.  Some devices don't fully conform to the\nJTAG specifications.  Trivial system-specific differences are common,\nsuch as SRST and TRST using slightly different names.  There are also\nvendors who distribute key JTAG documentation for their chips only to\ndevelopers who have signed a Non-Disclosure Agreement (NDA).\n\nSometimes there are chip-specific extensions like a requirement to use\nthe normally-optional TRST signal (precluding use of JTAG adapters which\ndon't pass TRST through), or needing extra steps to complete a TAP\nreset.\n\nIn short, SRST and especially TRST handling may be very finicky, needing\nto cope with both architecture and board specific constraints.\n\n9.3 Commands for Handling Resets\n================================\n\n -- Command: adapter srst pulse_width milliseconds\n     Minimum amount of time (in milliseconds) OpenOCD should wait after\n     asserting nSRST (active-low system reset) before allowing it to be\n     deasserted.\n\n -- Command: adapter srst delay milliseconds\n     How long (in milliseconds) OpenOCD should wait after deasserting\n     nSRST (active-low system reset) before starting new JTAG\n     operations.  When a board has a reset button connected to SRST line\n     it will probably have hardware debouncing, implying you should use\n     this.\n\n -- Command: jtag_ntrst_assert_width milliseconds\n     Minimum amount of time (in milliseconds) OpenOCD should wait after\n     asserting nTRST (active-low JTAG TAP reset) before allowing it to\n     be deasserted.\n\n -- Command: jtag_ntrst_delay milliseconds\n     How long (in milliseconds) OpenOCD should wait after deasserting\n     nTRST (active-low JTAG TAP reset) before starting new JTAG\n     operations.\n\n -- Command: reset_config mode_flag ...\n     This command displays or modifies the reset configuration of your\n     combination of JTAG board and target in target configuration\n     scripts.\n\n     Information earlier in this section describes the kind of problems\n     the command is intended to address (*note SRST and TRST Issues:\n     srstandtrstissues.).  As a rule this command belongs only in board\n     config files, describing issues like _board doesn't connect TRST_;\n     or in user config files, addressing limitations derived from a\n     particular combination of interface and board.  (An unlikely\n     example would be using a TRST-only adapter with a board that only\n     wires up SRST.)\n\n     The MODE_FLAG options can be specified in any order, but only one\n     of each type - SIGNALS, COMBINATION, GATES, TRST_TYPE, SRST_TYPE\n     and CONNECT_TYPE - may be specified at a time.  If you don't\n     provide a new value for a given type, its previous value (perhaps\n     the default) is unchanged.  For example, this means that you don't\n     need to say anything at all about TRST just to declare that if the\n     JTAG adapter should want to drive SRST, it must explicitly be\n     driven high ('srst_push_pull').\n\n        * SIGNALS can specify which of the reset signals are connected.\n          For example, If the JTAG interface provides SRST, but the\n          board doesn't connect that signal properly, then OpenOCD can't\n          use it.  Possible values are 'none' (the default),\n          'trst_only', 'srst_only' and 'trst_and_srst'.\n\n               Tip: If your board provides SRST and/or TRST through the\n               JTAG connector, you must declare that so those signals\n               can be used.\n\n        * The COMBINATION is an optional value specifying broken reset\n          signal implementations.  The default behaviour if no option\n          given is 'separate', indicating everything behaves normally.\n          'srst_pulls_trst' states that the test logic is reset together\n          with the reset of the system (e.g.  NXP LPC2000, \"broken\"\n          board layout), 'trst_pulls_srst' says that the system is reset\n          together with the test logic (only hypothetical, I haven't\n          seen hardware with such a bug, and can be worked around).\n          'combined' implies both 'srst_pulls_trst' and\n          'trst_pulls_srst'.\n\n        * The GATES tokens control flags that describe some cases where\n          JTAG may be unavailable during reset.  'srst_gates_jtag'\n          (default) indicates that asserting SRST gates the JTAG clock.\n          This means that no communication can happen on JTAG while SRST\n          is asserted.  Its converse is 'srst_nogate', indicating that\n          JTAG commands can safely be issued while SRST is active.\n\n        * The CONNECT_TYPE tokens control flags that describe some cases\n          where SRST is asserted while connecting to the target.\n          'srst_nogate' is required to use this option.\n          'connect_deassert_srst' (default) indicates that SRST will not\n          be asserted while connecting to the target.  Its converse is\n          'connect_assert_srst', indicating that SRST will be asserted\n          before any target connection.  Only some targets support this\n          feature, STM32 and STR9 are examples.  This feature is useful\n          if you are unable to connect to your target due to incorrect\n          options byte config or illegal program execution.\n\n     The optional TRST_TYPE and SRST_TYPE parameters allow the driver\n     mode of each reset line to be specified.  These values only affect\n     JTAG interfaces with support for different driver modes, like the\n     Amontec JTAGkey and JTAG Accelerator.  Also, they are necessarily\n     ignored if the relevant signal (TRST or SRST) is not connected.\n\n        * Possible TRST_TYPE driver modes for the test reset signal\n          (TRST) are the default 'trst_push_pull', and\n          'trst_open_drain'.  Most boards connect this signal to a\n          pulldown, so the JTAG TAPs never leave reset unless they are\n          hooked up to a JTAG adapter.\n\n        * Possible SRST_TYPE driver modes for the system reset signal\n          (SRST) are the default 'srst_open_drain', and\n          'srst_push_pull'.  Most boards connect this signal to a\n          pullup, and allow the signal to be pulled low by various\n          events including system power-up and pressing a reset button.\n\n9.4 Custom Reset Handling\n=========================\n\nOpenOCD has several ways to help support the various reset mechanisms\nprovided by chip and board vendors.  The commands shown in the previous\nsection give standard parameters.  There are also _event handlers_\nassociated with TAPs or Targets.  Those handlers are Tcl procedures you\ncan provide, which are invoked at particular points in the reset\nsequence.\n\n_When SRST is not an option_ you must set up a 'reset-assert' event\nhandler for your target.  For example, some JTAG adapters don't include\nthe SRST signal; and some boards have multiple targets, and you won't\nalways want to reset everything at once.\n\nAfter configuring those mechanisms, you might still find your board\ndoesn't start up or reset correctly.  For example, maybe it needs a\nslightly different sequence of SRST and/or TRST manipulations, because\nof quirks that the 'reset_config' mechanism doesn't address; or\nasserting both might trigger a stronger reset, which needs special\nattention.\n\nExperiment with lower level operations, such as 'adapter assert',\n'adapter deassert' and the 'jtag arp_*' operations shown here, to find a\nsequence of operations that works.  *Note JTAG Commands::.  When you\nfind a working sequence, it can be used to override 'jtag_init', which\nfires during OpenOCD startup (*note Configuration Stage:\nconfigurationstage.); or 'init_reset', which fires during reset\nprocessing.\n\nYou might also want to provide some project-specific reset schemes.  For\nexample, on a multi-target board the standard 'reset' command would\nreset all targets, but you may need the ability to reset only one target\nat time and thus want to avoid using the board-wide SRST signal.\n\n -- Overridable Procedure: init_reset mode\n     This is invoked near the beginning of the 'reset' command, usually\n     to provide as much of a cold (power-up) reset as practical.  By\n     default it is also invoked from 'jtag_init' if the scan chain does\n     not respond to pure JTAG operations.  The MODE parameter is the\n     parameter given to the low level reset command ('halt', 'init', or\n     'run'), 'setup', or potentially some other value.\n\n     The default implementation just invokes 'jtag arp_init-reset'.\n     Replacements will normally build on low level JTAG operations such\n     as 'adapter assert' and 'adapter deassert'.  Operations here must\n     not address individual TAPs (or their associated targets) until the\n     JTAG scan chain has first been verified to work.\n\n     Implementations must have verified the JTAG scan chain before they\n     return.  This is done by calling 'jtag arp_init' (or 'jtag\n     arp_init-reset').\n\n -- Command: jtag arp_init\n     This validates the scan chain using just the four standard JTAG\n     signals (TMS, TCK, TDI, TDO). It starts by issuing a JTAG-only\n     reset.  Then it performs checks to verify that the scan chain\n     configuration matches the TAPs it can observe.  Those checks\n     include checking IDCODE values for each active TAP, and verifying\n     the length of their instruction registers using TAP '-ircapture'\n     and '-irmask' values.  If these tests all pass, TAP 'setup' events\n     are issued to all TAPs with handlers for that event.\n\n -- Command: jtag arp_init-reset\n     This uses TRST and SRST to try resetting everything on the JTAG\n     scan chain (and anything else connected to SRST). It then invokes\n     the logic of 'jtag arp_init'.\n\n\u001f\nFile: openocd.info,  Node: TAP Declaration,  Next: CPU Configuration,  Prev: Reset Configuration,  Up: Top\n\n10 TAP Declaration\n******************\n\n_Test Access Ports_ (TAPs) are the core of JTAG. TAPs serve many roles,\nincluding:\n\n   * Debug Target A CPU TAP can be used as a GDB debug target.\n   * Flash Programming Some chips program the flash directly via JTAG.\n     Others do it indirectly, making a CPU do it.\n   * Program Download Using the same CPU support GDB uses, you can\n     initialize a DRAM controller, download code to DRAM, and then start\n     running that code.\n   * Boundary Scan Most chips support boundary scan, which helps test\n     for board assembly problems like solder bridges and missing\n     connections.\n\nOpenOCD must know about the active TAPs on your board(s).  Setting up\nthe TAPs is the core task of your configuration files.  Once those TAPs\nare set up, you can pass their names to code which sets up CPUs and\nexports them as GDB targets, probes flash memory, performs low-level\nJTAG operations, and more.\n\n10.1 Scan Chains\n================\n\nTAPs are part of a hardware \"scan chain\", which is a daisy chain of\nTAPs.  They also need to be added to OpenOCD's software mirror of that\nhardware list, giving each member a name and associating other data with\nit.  Simple scan chains, with a single TAP, are common in systems with a\nsingle microcontroller or microprocessor.  More complex chips may have\nseveral TAPs internally.  Very complex scan chains might have a dozen or\nmore TAPs: several in one chip, more in the next, and connecting to\nother boards with their own chips and TAPs.\n\nYou can display the list with the 'scan_chain' command.  (Don't confuse\nthis with the list displayed by the 'targets' command, presented in the\nnext chapter.  That only displays TAPs for CPUs which are configured as\ndebugging targets.)  Here's what the scan chain might look like for a\nchip more than one TAP:\n\n   TapName            Enabled IdCode     Expected   IrLen IrCap IrMask\n-- ------------------ ------- ---------- ---------- ----- ----- ------\n 0 omap5912.dsp          Y    0x03df1d81 0x03df1d81    38 0x01  0x03\n 1 omap5912.arm          Y    0x0692602f 0x0692602f     4 0x01  0x0f\n 2 omap5912.unknown      Y    0x00000000 0x00000000     8 0x01  0x03\n\nOpenOCD can detect some of that information, but not all of it.  *Note\nAutoprobing: autoprobing.  Unfortunately, those TAPs can't always be\nautoconfigured, because not all devices provide good support for that.\nJTAG doesn't require supporting IDCODE instructions, and chips with JTAG\nrouters may not link TAPs into the chain until they are told to do so.\n\nThe configuration mechanism currently supported by OpenOCD requires\nexplicit configuration of all TAP devices using 'jtag newtap' commands,\nas detailed later in this chapter.  A command like this would declare\none tap and name it 'chip1.cpu':\n\n     jtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477\n\nEach target configuration file lists the TAPs provided by a given chip.\nBoard configuration files combine all the targets on a board, and so\nforth.  Note that _the order in which TAPs are declared is very\nimportant._  That declaration order must match the order in the JTAG\nscan chain, both inside a single chip and between them.  *Note FAQ TAP\nOrder: faqtaporder.\n\nFor example, the STMicroelectronics STR912 chip has three separate\nTAPs(1).  To configure those taps, 'target/str912.cfg' includes commands\nsomething like this:\n\n     jtag newtap str912 flash ... params ...\n     jtag newtap str912 cpu ... params ...\n     jtag newtap str912 bs ... params ...\n\nActual config files typically use a variable such as '$_CHIPNAME'\ninstead of literals like 'str912', to support more than one chip of each\ntype.  *Note Config File Guidelines::.\n\n -- Command: jtag names\n     Returns the names of all current TAPs in the scan chain.  Use 'jtag\n     cget' or 'jtag tapisenabled' to examine attributes and state of\n     each TAP.\n          foreach t [jtag names] {\n              puts [format \"TAP: %s\\n\" $t]\n          }\n\n -- Command: scan_chain\n     Displays the TAPs in the scan chain configuration, and their\n     status.  The set of TAPs listed by this command is fixed by exiting\n     the OpenOCD configuration stage, but systems with a JTAG router can\n     enable or disable TAPs dynamically.\n\n10.2 TAP Names\n==============\n\nWhen TAP objects are declared with 'jtag newtap', a \"dotted.name\" is\ncreated for the TAP, combining the name of a module (usually a chip) and\na label for the TAP. For example: 'xilinx.tap', 'str912.flash',\n'omap3530.jrc', 'dm6446.dsp', or 'stm32.cpu'.  Many other commands use\nthat dotted.name to manipulate or refer to the TAP. For example, CPU\nconfiguration uses the name, as does declaration of NAND or NOR flash\nbanks.\n\nThe components of a dotted name should follow \"C\" symbol name rules:\nstart with an alphabetic character, then numbers and underscores are OK;\nwhile others (including dots!)  are not.\n\n10.3 TAP Declaration Commands\n=============================\n\n -- Config Command: jtag newtap chipname tapname configparams...\n     Declares a new TAP with the dotted name CHIPNAME.TAPNAME, and\n     configured according to the various CONFIGPARAMS.\n\n     The CHIPNAME is a symbolic name for the chip.  Conventionally\n     target config files use '$_CHIPNAME', defaulting to the model name\n     given by the chip vendor but overridable.\n\n     The TAPNAME reflects the role of that TAP, and should follow this\n     convention:\n\n        * 'bs' - For boundary scan if this is a separate TAP;\n        * 'cpu' - The main CPU of the chip, alternatively 'arm' and\n          'dsp' on chips with both ARM and DSP CPUs, 'arm1' and 'arm2'\n          on chips with two ARMs, and so forth;\n        * 'etb' - For an embedded trace buffer (example: an ARM ETB11);\n        * 'flash' - If the chip has a flash TAP, like the str912;\n        * 'jrc' - For JTAG route controller (example: the ICEPick\n          modules on many Texas Instruments chips, like the OMAP3530 on\n          Beagleboards);\n        * 'tap' - Should be used only for FPGA- or CPLD-like devices\n          with a single TAP;\n        * 'unknownN' - If you have no idea what the TAP is for (N is a\n          number);\n        * _when in doubt_ - Use the chip maker's name in their data\n          sheet.  For example, the Freescale i.MX31 has a SDMA (Smart\n          DMA) with a JTAG TAP; that TAP should be named 'sdma'.\n\n     Every TAP requires at least the following CONFIGPARAMS:\n\n        * '-irlen' NUMBER\n          The length in bits of the instruction register, such as 4 or 5\n          bits.\n\n     A TAP may also provide optional CONFIGPARAMS:\n\n        * '-disable' (or '-enable')\n          Use the '-disable' parameter to flag a TAP which is not linked\n          into the scan chain after a reset using either TRST or the\n          JTAG state machine's RESET state.  You may use '-enable' to\n          highlight the default state (the TAP is linked in).  *Note\n          Enabling and Disabling TAPs: enablinganddisablingtaps.\n        * '-expected-id' NUMBER\n          A non-zero NUMBER represents a 32-bit IDCODE which you expect\n          to find when the scan chain is examined.  These codes are not\n          required by all JTAG devices.  _Repeat the option_ as many\n          times as required if more than one ID code could appear (for\n          example, multiple versions).  Specify NUMBER as zero to\n          suppress warnings about IDCODE values that were found but not\n          included in the list.\n\n          Provide this value if at all possible, since it lets OpenOCD\n          tell when the scan chain it sees isn't right.  These values\n          are provided in vendors' chip documentation, usually a\n          technical reference manual.  Sometimes you may need to probe\n          the JTAG hardware to find these values.  *Note Autoprobing:\n          autoprobing.\n        * '-ignore-version'\n          Specify this to ignore the JTAG version field in the\n          '-expected-id' option.  When vendors put out multiple versions\n          of a chip, or use the same JTAG-level ID for several\n          largely-compatible chips, it may be more practical to ignore\n          the version field than to update config files to handle all of\n          the various chip IDs.  The version field is defined as bit\n          28-31 of the IDCODE.\n        * '-ignore-bypass'\n          Specify this to ignore the 'bypass' bit of the idcode.  Some\n          vendor put an invalid idcode regarding this bit.  Specify this\n          to ignore this bit and to not consider this tap in bypass\n          mode.\n        * '-ircapture' NUMBER\n          The bit pattern loaded by the TAP into the JTAG shift register\n          on entry to the IRCAPTURE state, such as 0x01.  JTAG requires\n          the two LSBs of this value to be 01.  By default, '-ircapture'\n          and '-irmask' are set up to verify that two-bit value.  You\n          may provide additional bits if you know them, or indicate that\n          a TAP doesn't conform to the JTAG specification.\n        * '-irmask' NUMBER\n          A mask used with '-ircapture' to verify that instruction scans\n          work correctly.  Such scans are not used by OpenOCD except to\n          verify that there seems to be no problems with JTAG scan chain\n          operations.\n        * '-ignore-syspwrupack'\n          Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP\n          CTRL/STAT register during initial examination and when\n          checking the sticky error bit.  This bit is normally checked\n          after setting the CSYSPWRUPREQ bit, but some devices do not\n          set the ack bit until sometime later.\n\n10.4 Other TAP commands\n=======================\n\n -- Command: jtag cget dotted.name -idcode\n     Get the value of the IDCODE found in hardware.\n\n -- Command: jtag cget dotted.name -event event_name\n -- Command: jtag configure dotted.name -event event_name handler\n     At this writing this TAP attribute mechanism is limited and used\n     mostly for event handling.  (It is not a direct analogue of the\n     'cget'/'configure' mechanism for debugger targets.)  See the next\n     section for information about the available events.\n\n     The 'configure' subcommand assigns an event handler, a TCL string\n     which is evaluated when the event is triggered.  The 'cget'\n     subcommand returns that handler.\n\n10.5 TAP Events\n===============\n\nOpenOCD includes two event mechanisms.  The one presented here applies\nto all JTAG TAPs.  The other applies to debugger targets, which are\nassociated with certain TAPs.\n\nThe TAP events currently defined are:\n\n   * post-reset\n     The TAP has just completed a JTAG reset.  The tap may still be in\n     the JTAG RESET state.  Handlers for these events might perform\n     initialization sequences such as issuing TCK cycles, TMS sequences\n     to ensure exit from the ARM SWD mode, and more.\n\n     Because the scan chain has not yet been verified, handlers for\n     these events _should not issue commands which scan the JTAG IR or\n     DR registers_ of any particular target.  NOTE: As this is written\n     (September 2009), nothing prevents such access.\n   * setup\n     The scan chain has been reset and verified.  This handler may\n     enable TAPs as needed.\n   * tap-disable\n     The TAP needs to be disabled.  This handler should implement 'jtag\n     tapdisable' by issuing the relevant JTAG commands.\n   * tap-enable\n     The TAP needs to be enabled.  This handler should implement 'jtag\n     tapenable' by issuing the relevant JTAG commands.\n\nIf you need some action after each JTAG reset which isn't actually\nspecific to any TAP (since you can't yet trust the scan chain's contents\nto be accurate), you might:\n\n     jtag configure CHIP.jrc -event post-reset {\n       echo \"JTAG Reset done\"\n       ... non-scan jtag operations to be done after reset\n     }\n\n10.6 Enabling and Disabling TAPs\n================================\n\nIn some systems, a \"JTAG Route Controller\" (JRC) is used to enable\nand/or disable specific JTAG TAPs.  Many ARM-based chips from Texas\nInstruments include an \"ICEPick\" module, which is a JRC. Such chips\ninclude DaVinci and OMAP3 processors.\n\nA given TAP may not be visible until the JRC has been told to link it\ninto the scan chain; and if the JRC has been told to unlink that TAP, it\nwill no longer be visible.  Such routers address problems that JTAG\n\"bypass mode\" ignores, such as:\n\n   * The scan chain can only go as fast as its slowest TAP.\n   * Having many TAPs slows instruction scans, since all TAPs receive\n     new instructions.\n   * TAPs in the scan chain must be powered up, which wastes power and\n     prevents debugging some power management mechanisms.\n\nThe IEEE 1149.1 JTAG standard has no concept of a \"disabled\" tap, as\nimplied by the existence of JTAG routers.  However, the upcoming IEEE\n1149.7 framework (layered on top of JTAG) does include a kind of JTAG\nrouter functionality.\n\nIn OpenOCD, tap enabling/disabling is invoked by the Tcl commands shown\nbelow, and is implemented using TAP event handlers.  So for example,\nwhen defining a TAP for a CPU connected to a JTAG router, your\n'target.cfg' file should define TAP event handlers using code that looks\nsomething like this:\n\n     jtag configure CHIP.cpu -event tap-enable {\n       ... jtag operations using CHIP.jrc\n     }\n     jtag configure CHIP.cpu -event tap-disable {\n       ... jtag operations using CHIP.jrc\n     }\n\nThen you might want that CPU's TAP enabled almost all the time:\n\n     jtag configure $CHIP.jrc -event setup \"jtag tapenable $CHIP.cpu\"\n\nNote how that particular setup event handler declaration uses quotes to\nevaluate '$CHIP' when the event is configured.  Using brackets { } would\ncause it to be evaluated later, at runtime, when it might have a\ndifferent value.\n\n -- Command: jtag tapdisable dotted.name\n     If necessary, disables the tap by sending it a 'tap-disable' event.\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n -- Command: jtag tapenable dotted.name\n     If necessary, enables the tap by sending it a 'tap-enable' event.\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n -- Command: jtag tapisenabled dotted.name\n     Returns the string \"1\" if the tap specified by DOTTED.NAME is\n     enabled, and \"0\" if it is disabled.\n\n          Note: Humans will find the 'scan_chain' command more helpful\n          for querying the state of the JTAG taps.\n\n10.7 Autoprobing\n================\n\nTAP configuration is the first thing that needs to be done after\ninterface and reset configuration.  Sometimes it's hard finding out what\nTAPs exist, or how they are identified.  Vendor documentation is not\nalways easy to find and use.\n\nTo help you get past such problems, OpenOCD has a limited _autoprobing_\nability to look at the scan chain, doing a \"blind interrogation\" and\nthen reporting the TAPs it finds.  To use this mechanism, start the\nOpenOCD server with only data that configures your JTAG interface, and\narranges to come up with a slow clock (many devices don't support fast\nJTAG clocks right when they come out of reset).\n\nFor example, your 'openocd.cfg' file might have:\n\n     source [find interface/olimex-arm-usb-tiny-h.cfg]\n     reset_config trst_and_srst\n     jtag_rclk 8\n\nWhen you start the server without any TAPs configured, it will attempt\nto autoconfigure the TAPs.  There are two parts to this:\n\n  1. _TAP discovery_ ...  After a JTAG reset (sometimes a system reset\n     may be needed too), each TAP's data registers will hold the\n     contents of either the IDCODE or BYPASS register.  If JTAG\n     communication is working, OpenOCD will see each TAP, and report\n     what '-expected-id' to use with it.\n  2. _IR Length discovery_ ...  Unfortunately JTAG does not provide a\n     reliable way to find out the value of the '-irlen' parameter to use\n     with a TAP that is discovered.  If OpenOCD can discover the length\n     of a TAP's instruction register, it will report it.  Otherwise you\n     may need to consult vendor documentation, such as chip data sheets\n     or BSDL files.\n\nIn many cases your board will have a simple scan chain with just a\nsingle device.  Here's what OpenOCD reported with one board that's a bit\nmore complex:\n\n     clock speed 8 kHz\n     There are no enabled taps. AUTO PROBING MIGHT NOT WORK!!\n     AUTO auto0.tap - use \"jtag newtap auto0 tap -expected-id 0x2b900f0f ...\"\n     AUTO auto1.tap - use \"jtag newtap auto1 tap -expected-id 0x07926001 ...\"\n     AUTO auto2.tap - use \"jtag newtap auto2 tap -expected-id 0x0b73b02f ...\"\n     AUTO auto0.tap - use \"... -irlen 4\"\n     AUTO auto1.tap - use \"... -irlen 4\"\n     AUTO auto2.tap - use \"... -irlen 6\"\n     no gdb ports allocated as no target has been specified\n\nGiven that information, you should be able to either find some existing\nconfig files to use, or create your own.  If you create your own, you\nwould configure from the bottom up: first a 'target.cfg' file with these\nTAPs, any targets associated with them, and any on-chip resources; then\na 'board.cfg' with off-chip resources, clocking, and so forth.\n\n10.8 DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets)\n=======================================================\n\nSince OpenOCD version 0.11.0, the Debug Access Port (DAP) is no longer\nimplicitly created together with the target.  It must be explicitly\ndeclared using the 'dap create' command.  For all ARMv6-M, ARMv7 and\nARMv8 targets, the option \"'-dap' DAP_NAME\" has to be used instead of\n\"'-chain-position' DOTTED.NAME\" when the target is created.\n\nThe 'dap' command group supports the following sub-commands:\n\n -- Command: dap create dap_name -chain-position dotted.name\n          configparams...\n     Declare a DAP instance named DAP_NAME linked to the JTAG tap\n     DOTTED.NAME.  This also creates a new command ('dap_name') which is\n     used for various purposes including additional configuration.\n     There can only be one DAP for each JTAG tap in the system.\n\n     A DAP may also provide optional CONFIGPARAMS:\n\n        * '-ignore-syspwrupack'\n          Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP\n          CTRL/STAT register during initial examination and when\n          checking the sticky error bit.  This bit is normally checked\n          after setting the CSYSPWRUPREQ bit, but some devices do not\n          set the ack bit until sometime later.\n\n        * '-dp-id' NUMBER\n          Debug port identification number for SWD DPv2 multidrop.  The\n          NUMBER is written to bits 0..27 of DP TARGETSEL during DP\n          selection.  To find the id number of a single connected device\n          read DP TARGETID: 'device.dap dpreg 0x24' Use bits 0..27 of\n          TARGETID.\n\n        * '-instance-id' NUMBER\n          Instance identification number for SWD DPv2 multidrop.  The\n          NUMBER is written to bits 28..31 of DP TARGETSEL during DP\n          selection.  To find the instance number of a single connected\n          device read DP DLPIDR: 'device.dap dpreg 0x34' The instance\n          number is in bits 28..31 of DLPIDR value.\n\n -- Command: dap names\n     This command returns a list of all registered DAP objects.  It it\n     useful mainly for TCL scripting.\n\n -- Command: dap info [num]\n     Displays the ROM table for MEM-AP NUM, defaulting to the currently\n     selected AP of the currently selected target.\n\n -- Command: dap init\n     Initialize all registered DAPs.  This command is used internally\n     during initialization.  It can be issued at any time after the\n     initialization, too.\n\nThe following commands exist as subcommands of DAP instances:\n\n -- Command: $dap_name info [num]\n     Displays the ROM table for MEM-AP NUM, defaulting to the currently\n     selected AP.\n\n -- Command: $dap_name apid [num]\n     Displays ID register from AP NUM, defaulting to the currently\n     selected AP.\n\n -- Command: $dap_name apreg ap_num reg [value]\n     Displays content of a register REG from AP AP_NUM or set a new\n     value VALUE.  REG is byte address of a word register, 0, 4, 8 ...\n     0xfc.\n\n -- Command: $dap_name apsel [num]\n     Select AP NUM, defaulting to 0.\n\n -- Command: $dap_name dpreg reg [value]\n     Displays the content of DP register at address REG, or set it to a\n     new value VALUE.\n\n     In case of SWD, REG is a value in packed format dpbanksel << 4 |\n     addr and assumes values 0, 4, 8 ...  0xfc.  In case of JTAG it only\n     assumes values 0, 4, 8 and 0xc.\n\n     _Note:_ Consider using 'poll off' to avoid any disturbing\n     background activity by OpenOCD while you are operating at such\n     low-level.\n\n -- Command: $dap_name baseaddr [num]\n     Displays debug base address from MEM-AP NUM, defaulting to the\n     currently selected AP.\n\n -- Command: $dap_name memaccess [value]\n     Displays the number of extra tck cycles in the JTAG idle to use for\n     MEM-AP memory bus access [0-255], giving additional time to respond\n     to reads.  If VALUE is defined, first assigns that.\n\n -- Command: $dap_name apcsw [value [mask]]\n     Displays or changes CSW bit pattern for MEM-AP transfers.\n\n     At the begin of each memory access the CSW pattern is extended\n     (bitwise or-ed) by \"Size\" and \"AddrInc\" bit-fields according to\n     transfer requirements and the result is written to the real CSW\n     register.  All bits except dynamically updated fields \"Size\" and\n     \"AddrInc\" can be changed by changing the CSW pattern.  Refer to ARM\n     ADI v5 manual chapter 7.6.4 and appendix A for details.\n\n     Use VALUE only syntax if you want to set the new CSW pattern as a\n     whole.  The example sets HPROT1 bit (required by Cortex-M) and\n     clears the rest of the pattern:\n          kx.dap apcsw 0x2000000\n\n     If MASK is also used, the CSW pattern is changed only on bit\n     positions where the mask bit is 1.  The following example sets\n     HPROT3 (cacheable) and leaves the rest of the pattern intact.  It\n     configures memory access through DCache on Cortex-M7.\n          set CSW_HPROT3_CACHEABLE [expr {1 << 27}]\n          samv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE\n\n     Another example clears SPROT bit and leaves the rest of pattern\n     intact:\n          set CSW_SPROT [expr {1 << 30}]\n          samv.dap apcsw 0 $CSW_SPROT\n\n     _Note:_ If you want to check the real value of CSW, not CSW\n     pattern, use 'xxx.dap apreg 0'.  *Note DAP subcommand apreg::.\n\n     _Warning:_ Some of the CSW bits are vital for working memory\n     transfer.  If you set a wrong CSW pattern and MEM-AP stopped\n     working, use the following example with a proper dap name:\n          xxx.dap apcsw default\n\n -- Config Command: $dap_name ti_be_32_quirks [enable]\n     Set/get quirks mode for TI TMS450/TMS570 processors Disabled by\n     default\n\n   ---------- Footnotes ----------\n\n   (1) See the ST document titled: _STR91xFAxxx, Section 3.15 Jtag\nInterface, Page: 28/102, Figure 3: JTAG chaining inside the STR91xFA_.\n<http://eu.st.com/stonline/products/literature/ds/13495.pdf>\n\n\u001f\nFile: openocd.info,  Node: CPU Configuration,  Next: Flash Commands,  Prev: TAP Declaration,  Up: Top\n\n11 CPU Configuration\n********************\n\nThis chapter discusses how to set up GDB debug targets for CPUs.  You\ncan also access these targets without GDB (*note Architecture and Core\nCommands::, and *note Target State handling: targetstatehandling.) and\nthrough various kinds of NAND and NOR flash commands.  If you have\nmultiple CPUs you can have multiple such targets.\n\nWe'll start by looking at how to examine the targets you have, then look\nat how to add one more target and how to configure it.\n\n11.1 Target List\n================\n\nAll targets that have been set up are part of a list, where each member\nhas a name.  That name should normally be the same as the TAP name.  You\ncan display the list with the 'targets' (plural!)  command.  This\ndisplay often has only one CPU; here's what it might look like with more\nthan one:\n    TargetName         Type       Endian TapName            State\n--  ------------------ ---------- ------ ------------------ ------------\n 0* at91rm9200.cpu     arm920t    little at91rm9200.cpu     running\n 1  MyTarget           cortex_m   little mychip.foo         tap-disabled\n\nOne member of that list is the \"current target\", which is implicitly\nreferenced by many commands.  It's the one marked with a '*' near the\ntarget name.  In particular, memory addresses often refer to the address\nspace seen by that current target.  Commands like 'mdw' (memory display\nwords) and 'flash erase_address' (erase NOR flash blocks) are examples;\nand there are many more.\n\nSeveral commands let you examine the list of targets:\n\n -- Command: target current\n     Returns the name of the current target.\n\n -- Command: target names\n     Lists the names of all current targets in the list.\n          foreach t [target names] {\n              puts [format \"Target: %s\\n\" $t]\n          }\n\n -- Command: targets [name]\n     _Note: the name of this command is plural.  Other target command\n     names are singular._\n\n     With no parameter, this command displays a table of all known\n     targets in a user friendly form.\n\n     With a parameter, this command sets the current target to the given\n     target with the given NAME; this is only relevant on boards which\n     have more than one target.\n\n11.2 Target CPU Types\n=====================\n\nEach target has a \"CPU type\", as shown in the output of the 'targets'\ncommand.  You need to specify that type when calling 'target create'.\nThe CPU type indicates more than just the instruction set.  It also\nindicates how that instruction set is implemented, what kind of debug\nsupport it integrates, whether it has an MMU (and if so, what kind),\nwhat core-specific commands may be available (*note Architecture and\nCore Commands::), and more.\n\nIt's easy to see what target types are supported, since there's a\ncommand to list them.\n\n -- Command: target types\n     Lists all supported target types.  At this writing, the supported\n     CPU types are:\n\n        * 'aarch64' - this is an ARMv8-A core with an MMU.\n        * 'arm11' - this is a generation of ARMv6 cores.\n        * 'arm720t' - this is an ARMv4 core with an MMU.\n        * 'arm7tdmi' - this is an ARMv4 core.\n        * 'arm920t' - this is an ARMv4 core with an MMU.\n        * 'arm926ejs' - this is an ARMv5 core with an MMU.\n        * 'arm946e' - this is an ARMv5 core with an MMU.\n        * 'arm966e' - this is an ARMv5 core.\n        * 'arm9tdmi' - this is an ARMv4 core.\n        * 'avr' - implements Atmel's 8-bit AVR instruction set.\n          (Support for this is preliminary and incomplete.)\n        * 'avr32_ap7k' - this an AVR32 core.\n        * 'cortex_a' - this is an ARMv7-A core with an MMU.\n        * 'cortex_m' - this is an ARMv7-M core, supporting only the\n          compact Thumb2 instruction set.  Supports also ARMv6-M and\n          ARMv8-M cores\n        * 'cortex_r4' - this is an ARMv7-R core.\n        * 'dragonite' - resembles arm966e.\n        * 'dsp563xx' - implements Freescale's 24-bit DSP. (Support for\n          this is still incomplete.)\n        * 'dsp5680xx' - implements Freescale's 5680x DSP.\n        * 'esirisc' - this is an EnSilica eSi-RISC core.  The current\n          implementation supports eSi-32xx cores.\n        * 'esp32s2' - this is an Espressif SoC with single Xtensa core.\n        * 'fa526' - resembles arm920 (w/o Thumb).\n        * 'feroceon' - resembles arm926.\n        * 'hla_target' - a Cortex-M alternative to work with HL adapters\n          like ST-Link.\n        * 'ls1_sap' - this is the SAP on NXP LS102x CPUs, allowing\n          access to physical memory addresses independently of CPU\n          cores.\n        * 'mem_ap' - this is an ARM debug infrastructure Access Port\n          without a CPU, through which bus read and write cycles can be\n          generated; it may be useful for working with non-CPU hardware\n          behind an AP or during development of support for new CPUs.\n          It's possible to connect a GDB client to this target (the GDB\n          port has to be specified, *Note option -gdb-port:\n          gdbportoverride.), and a fake ARM core will be emulated to\n          comply to GDB remote protocol.\n        * 'mips_m4k' - a MIPS core.\n        * 'mips_mips64' - a MIPS64 core.\n        * 'nds32_v2' - this is an Andes NDS32 v2 core (deprecated; would\n          be removed in v0.13.0).\n        * 'nds32_v3' - this is an Andes NDS32 v3 core (deprecated; would\n          be removed in v0.13.0).\n        * 'nds32_v3m' - this is an Andes NDS32 v3m core (deprecated;\n          would be removed in v0.13.0).\n        * 'or1k' - this is an OpenRISC 1000 core.  The current\n          implementation supports three JTAG TAP cores:\n             - 'OpenCores TAP' (See:\n               <http://opencores.org/project,jtag>)\n             - 'Altera Virtual JTAG TAP' (See:\n               <http://www.altera.com/literature/ug/ug_virtualjtag.pdf>)\n             - 'Xilinx BSCAN_* virtual JTAG interface' (See:\n               <http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/spartan6_hdl.pdf>)\n          And two debug interfaces cores:\n             - 'Advanced debug interface'\n               (See: <http://opencores.org/project,adv_debug_sys>)\n             - 'SoC Debug Interface'\n               (See: <http://opencores.org/project,dbg_interface>)\n        * 'quark_d20xx' - an Intel Quark D20xx core.\n        * 'quark_x10xx' - an Intel Quark X10xx core.\n        * 'riscv' - a RISC-V core.\n        * 'stm8' - implements an STM8 core.\n        * 'testee' - a dummy target for cases without a real CPU, e.g.\n          CPLD.\n        * 'xscale' - this is actually an architecture, not a CPU type.\n          It is based on the ARMv5 architecture.\n\nTo avoid being confused by the variety of ARM based cores, remember this\nkey point: _ARM is a technology licencing company_.  (See:\n<http://www.arm.com>.)  The CPU name used by OpenOCD will reflect the\nCPU design that was licensed, not a vendor brand which incorporates that\ndesign.  Name prefixes like arm7, arm9, arm11, and cortex reflect design\ngenerations; while names like ARMv4, ARMv5, ARMv6, ARMv7 and ARMv8\nreflect an architecture version implemented by a CPU design.\n\n11.3 Target Configuration\n=========================\n\nBefore creating a \"target\", you must have added its TAP to the scan\nchain.  When you've added that TAP, you will have a 'dotted.name' which\nis used to set up the CPU support.  The chip-specific configuration file\nwill normally configure its CPU(s) right after it adds all of the chip's\nTAPs to the scan chain.\n\nAlthough you can set up a target in one step, it's often clearer if you\nuse shorter commands and do it in two steps: create it, then configure\noptional parts.  All operations on the target after it's created will\nuse a new command, created as part of target creation.\n\nThe two main things to configure after target creation are a work area,\nwhich usually has target-specific defaults even if the board setup code\noverrides them later; and event handlers (*note Target Events:\ntargetevents.), which tend to be much more board-specific.  The key\nsteps you use might look something like this\n\n     dap create mychip.dap -chain-position mychip.cpu\n     target create MyTarget cortex_m -dap mychip.dap\n     MyTarget configure -work-area-phys 0x08000 -work-area-size 8096\n     MyTarget configure -event reset-deassert-pre { jtag_rclk 5 }\n     MyTarget configure -event reset-init { myboard_reinit }\n\nYou should specify a working area if you can; typically it uses some\non-chip SRAM. Such a working area can speed up many things, including\nbulk writes to target memory; flash operations like checking to see if\nmemory needs to be erased; GDB memory checksumming; and more.\n\n     Warning: On more complex chips, the work area can become\n     inaccessible when application code (such as an operating system)\n     enables or disables the MMU. For example, the particular MMU\n     context used to access the virtual address will probably matter ...\n     and that context might not have easy access to other addresses\n     needed.  At this writing, OpenOCD doesn't have much MMU\n     intelligence.\n\nIt's often very useful to define a 'reset-init' event handler.  For\nsystems that are normally used with a boot loader, common tasks include\nupdating clocks and initializing memory controllers.  That may be needed\nto let you write the boot loader into flash, in order to \"de-brick\" your\nboard; or to load programs into external DDR memory without having run\nthe boot loader.\n\n -- Config Command: target create target_name type configparams...\n     This command creates a GDB debug target that refers to a specific\n     JTAG tap.  It enters that target into a list, and creates a new\n     command ('TARGET_NAME') which is used for various purposes\n     including additional configuration.\n\n        * TARGET_NAME ...  is the name of the debug target.  By\n          convention this should be the same as the _dotted.name_ of the\n          TAP associated with this target, which must be specified here\n          using the '-chain-position DOTTED.NAME' configparam.\n\n          This name is also used to create the target object command,\n          referred to here as '$target_name', and in other places the\n          target needs to be identified.\n        * TYPE ...  specifies the target type.  *Note target types:\n          targettypes.\n        * CONFIGPARAMS ...  all parameters accepted by '$target_name\n          configure' are permitted.  If the target is big-endian, set it\n          here with '-endian big'.\n\n          You _must_ set the '-chain-position DOTTED.NAME' or '-dap\n          DAP_NAME' here.\n\n -- Command: $target_name configure configparams...\n     The options accepted by this command may also be specified as\n     parameters to 'target create'.  Their values can later be queried\n     one at a time by using the '$target_name cget' command.\n\n     _Warning:_ changing some of these after setup is dangerous.  For\n     example, moving a target from one TAP to another; and changing its\n     endianness.\n\n        * '-chain-position' DOTTED.NAME - names the TAP used to access\n          this target.\n\n        * '-dap' DAP_NAME - names the DAP used to access this target.\n          *Note DAP declaration: dapdeclaration, on how to create and\n          manage DAP instances.\n\n        * '-endian' ('big'|'little') - specifies whether the CPU uses\n          big or little endian conventions\n\n        * '-event' EVENT_NAME EVENT_BODY - *Note Target Events:\n          targetevents.  Note that this updates a list of named event\n          handlers.  Calling this twice with two different event names\n          assigns two different handlers, but calling it twice with the\n          same event name assigns only one handler.\n\n          Current target is temporarily overridden to the event issuing\n          target before handler code starts and switched back after\n          handler is done.\n\n        * '-work-area-backup' ('0'|'1') - says whether the work area\n          gets backed up; by default, _it is not backed up._  When\n          possible, use a working_area that doesn't need to be backed\n          up, since performing a backup slows down operations.  For\n          example, the beginning of an SRAM block is likely to be used\n          by most build systems, but the end is often unused.\n\n        * '-work-area-size' SIZE - specify work are size, in bytes.  The\n          same size applies regardless of whether its physical or\n          virtual address is being used.\n\n        * '-work-area-phys' ADDRESS - set the work area base ADDRESS to\n          be used when no MMU is active.\n\n        * '-work-area-virt' ADDRESS - set the work area base ADDRESS to\n          be used when an MMU is active.  _Do not specify a value for\n          this except on targets with an MMU._ The value should normally\n          correspond to a static mapping for the '-work-area-phys'\n          address, set up by the current operating system.\n\n        * '-rtos' RTOS_TYPE - enable rtos support for target, RTOS_TYPE\n          can be one of 'auto', 'eCos', 'ThreadX', 'FreeRTOS', 'linux',\n          'ChibiOS', 'embKernel', 'mqx', 'uCOS-III', 'nuttx', 'RIOT',\n          'Zephyr' *Note RTOS Support: gdbrtossupport.\n\n        * '-defer-examine' - skip target examination at initial JTAG\n          chain scan and after a reset.  A manual call to arp_examine is\n          required to access the target for debugging.\n\n        * '-ap-num' AP_NUMBER - set DAP access port for target,\n          AP_NUMBER is the numeric index of the DAP AP the target is\n          connected to.  Use this option with systems where multiple,\n          independent cores are connected to separate access ports of\n          the same DAP.\n\n        * '-cti' CTI_NAME - set Cross-Trigger Interface (CTI) connected\n          to the target.  Currently, only the 'aarch64' target makes use\n          of this option, where it is a mandatory configuration for the\n          target run control.  *Note ARM Cross-Trigger Interface:\n          armcrosstrigger, for instruction on how to declare and control\n          a CTI instance.\n\n        * '-gdb-port' NUMBER - see command 'gdb_port' for the possible\n          values of the parameter NUMBER, which are not only numeric\n          values.  Use this option to override, for this target only,\n          the global parameter set with command 'gdb_port'.  *Note\n          command gdb_port: gdb_port.\n\n        * '-gdb-max-connections' NUMBER - EXPERIMENTAL: set the maximum\n          number of GDB connections that are allowed for the target.\n          Default is 1.  A negative value for NUMBER means unlimited\n          connections.  See *Note Using GDB as a non-intrusive memory\n          inspector: gdbmeminspect.\n\n11.4 Other $target_name Commands\n================================\n\nThe Tcl/Tk language has the concept of object commands, and OpenOCD\nadopts that same model for targets.\n\nA good Tk example is a on screen button.  Once a button is created a\nbutton has a name (a path in Tk terms) and that name is useable as a\nfirst class command.  For example in Tk, one can create a button and\nlater configure it like this:\n\n     # Create\n     button .foobar -background red -command { foo }\n     # Modify\n     .foobar configure -foreground blue\n     # Query\n     set x [.foobar cget -background]\n     # Report\n     puts [format \"The button is %s\" $x]\n\nIn OpenOCD's terms, the \"target\" is an object just like a Tcl/Tk button,\nand its object commands are invoked the same way.\n\n     str912.cpu    mww 0x1234 0x42\n     omap3530.cpu  mww 0x5555 123\n\nThe commands supported by OpenOCD target objects are:\n\n -- Command: $target_name arp_examine allow-defer\n -- Command: $target_name arp_halt\n -- Command: $target_name arp_poll\n -- Command: $target_name arp_reset\n -- Command: $target_name arp_waitstate\n     Internal OpenOCD scripts (most notably 'startup.tcl') use these to\n     deal with specific reset cases.  They are not otherwise documented\n     here.\n\n -- Command: $target_name set_reg dict\n     Set register values of the target.\n\n        * DICT ...  Tcl dictionary with pairs of register names and\n          values.\n\n     For example, the following command sets the value 0 to the program\n     counter (pc) register and 0x1000 to the stack pointer (sp)\n     register:\n\n          set_reg {pc 0 sp 0x1000}\n\n -- Command: $target_name get_reg [-force] list\n     Get register values from the target and return them as Tcl\n     dictionary with pairs of register names and values.  If option\n     \"-force\" is set, the register values are read directly from the\n     target, bypassing any caching.\n\n        * LIST ...  List of register names\n\n     For example, the following command retrieves the values from the\n     program counter (pc) and stack pointer (sp) register:\n\n          get_reg {pc sp}\n\n -- Command: $target_name write_memory address width data ['phys']\n     This function provides an efficient way to write to the target\n     memory from a Tcl script.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * DATA ...  Tcl list with the elements to write\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command writes two 32 bit words into the\n     target memory at address 0x20000000:\n\n          write_memory 0x20000000 32 {0xdeadbeef 0x00230500}\n\n -- Command: $target_name read_memory address width count ['phys']\n     This function provides an efficient way to read the target memory\n     from a Tcl script.  A Tcl list containing the requested memory\n     elements is returned by this function.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * COUNT ...  number of elements to read\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command reads two 32 bit words from the\n     target memory at address 0x20000000:\n\n          read_memory 0x20000000 32 2\n\n -- Command: $target_name cget queryparm\n     Each configuration parameter accepted by '$target_name configure'\n     can be individually queried, to return its current value.  The\n     QUERYPARM is a parameter name accepted by that command, such as\n     '-work-area-phys'.  There are a few special cases:\n\n        * '-event' EVENT_NAME - returns the handler for the event named\n          EVENT_NAME.  This is a special case because setting a handler\n          requires two parameters.\n        * '-type' - returns the target type.  This is a special case\n          because this is set using 'target create' and can't be changed\n          using '$target_name configure'.\n\n     For example, if you wanted to summarize information about all the\n     targets you might use something like this:\n\n          foreach name [target names] {\n              set y [$name cget -endian]\n              set z [$name cget -type]\n              puts [format \"Chip %d is %s, Endian: %s, type: %s\" \\\n                           $x $name $y $z]\n          }\n\n -- Command: $target_name curstate\n     Displays the current target state: 'debug-running', 'halted',\n     'reset', 'running', or 'unknown'.  (Also, *note Event Polling:\n     eventpolling.)\n\n -- Command: $target_name eventlist\n     Displays a table listing all event handlers currently associated\n     with this target.  *Note Target Events: targetevents.\n\n -- Command: $target_name invoke-event event_name\n     Invokes the handler for the event named EVENT_NAME.  (This is\n     primarily intended for use by OpenOCD framework code, for example\n     by the reset code in 'startup.tcl'.)\n\n -- Command: $target_name mdd [phys] addr [count]\n -- Command: $target_name mdw [phys] addr [count]\n -- Command: $target_name mdh [phys] addr [count]\n -- Command: $target_name mdb [phys] addr [count]\n     Display contents of address ADDR, as 64-bit doublewords ('mdd'),\n     32-bit words ('mdw'), 16-bit halfwords ('mdh'), or 8-bit bytes\n     ('mdb').  When the current target has an MMU which is present and\n     active, ADDR is interpreted as a virtual address.  Otherwise, or if\n     the optional PHYS flag is specified, ADDR is interpreted as a\n     physical address.  If COUNT is specified, displays that many units.\n     (If you want to process the data instead of displaying it, see the\n     'read_memory' primitives.)\n\n -- Command: $target_name mwd [phys] addr doubleword [count]\n -- Command: $target_name mww [phys] addr word [count]\n -- Command: $target_name mwh [phys] addr halfword [count]\n -- Command: $target_name mwb [phys] addr byte [count]\n     Writes the specified DOUBLEWORD (64 bits), WORD (32 bits), HALFWORD\n     (16 bits), or BYTE (8-bit) value, at the specified address ADDR.\n     When the current target has an MMU which is present and active,\n     ADDR is interpreted as a virtual address.  Otherwise, or if the\n     optional PHYS flag is specified, ADDR is interpreted as a physical\n     address.  If COUNT is specified, fills that many units of\n     consecutive address.\n\n11.5 Target Events\n==================\n\nAt various times, certain things can happen, or you want them to happen.\nFor example:\n   * What should happen when GDB connects?  Should your target reset?\n   * When GDB tries to flash the target, do you need to enable the flash\n     via a special command?\n   * Is using SRST appropriate (and possible) on your system?  Or\n     instead of that, do you need to issue JTAG commands to trigger\n     reset?  SRST usually resets everything on the scan chain, which can\n     be inappropriate.\n   * During reset, do you need to write to certain memory locations to\n     set up system clocks or to reconfigure the SDRAM? How about\n     configuring the watchdog timer, or other peripherals, to stop\n     running while you hold the core stopped for debugging?\n\nAll of the above items can be addressed by target event handlers.  These\nare set up by '$target_name configure -event' or 'target create ...\n-event'.\n\nThe programmer's model matches the '-command' option used in Tcl/Tk\nbuttons and events.  The two examples below act the same, but one\ncreates and invokes a small procedure while the other inlines it.\n\n     proc my_init_proc { } {\n         echo \"Disabling watchdog...\"\n         mww 0xfffffd44 0x00008000\n     }\n     mychip.cpu configure -event reset-init my_init_proc\n     mychip.cpu configure -event reset-init {\n         echo \"Disabling watchdog...\"\n         mww 0xfffffd44 0x00008000\n     }\n\nThe following target events are defined:\n\n   * debug-halted\n     The target has halted for debug reasons (i.e.: breakpoint)\n   * debug-resumed\n     The target has resumed (i.e.: GDB said run)\n   * early-halted\n     Occurs early in the halt process\n   * examine-start\n     Before target examine is called.\n   * examine-end\n     After target examine is called with no errors.\n   * examine-fail\n     After target examine fails.\n   * gdb-attach\n     When GDB connects.  Issued before any GDB communication with the\n     target starts.  GDB expects the target is halted during attachment.\n     *Note GDB as a non-intrusive memory inspector: gdbmeminspect, how\n     to connect GDB to running target.  The event can be also used to\n     set up the target so it is possible to probe flash.  Probing flash\n     is necessary during GDB connect if you want to use *note\n     programming using GDB: programmingusinggdb.  Another use of the\n     flash memory map is for GDB to automatically choose hardware or\n     software breakpoints depending on whether the breakpoint is in RAM\n     or read only memory.  Default is 'halt'\n   * gdb-detach\n     When GDB disconnects\n   * gdb-end\n     When the target has halted and GDB is not doing anything (see early\n     halt)\n   * gdb-flash-erase-start\n     Before the GDB flash process tries to erase the flash (default is\n     'reset init')\n   * gdb-flash-erase-end\n     After the GDB flash process has finished erasing the flash\n   * gdb-flash-write-start\n     Before GDB writes to the flash\n   * gdb-flash-write-end\n     After GDB writes to the flash (default is 'reset halt')\n   * gdb-start\n     Before the target steps, GDB is trying to start/resume the target\n   * halted\n     The target has halted\n   * reset-assert-pre\n     Issued as part of 'reset' processing after 'reset-start' was\n     triggered but before either SRST alone is asserted on the scan\n     chain, or 'reset-assert' is triggered.\n   * reset-assert\n     Issued as part of 'reset' processing after 'reset-assert-pre' was\n     triggered.  When such a handler is present, cores which support\n     this event will use it instead of asserting SRST. This support is\n     essential for debugging with JTAG interfaces which don't include an\n     SRST line (JTAG doesn't require SRST), and for selective reset on\n     scan chains that have multiple targets.\n   * reset-assert-post\n     Issued as part of 'reset' processing after 'reset-assert' has been\n     triggered.  or the target asserted SRST on the entire scan chain.\n   * reset-deassert-pre\n     Issued as part of 'reset' processing after 'reset-assert-post' has\n     been triggered.\n   * reset-deassert-post\n     Issued as part of 'reset' processing after 'reset-deassert-pre' has\n     been triggered and (if the target is using it) after SRST has been\n     released on the scan chain.\n   * reset-end\n     Issued as the final step in 'reset' processing.\n   * reset-init\n     Used by reset init command for board-specific initialization.  This\n     event fires after _reset-deassert-post_.\n\n     This is where you would configure PLLs and clocking, set up DRAM so\n     you can download programs that don't fit in on-chip SRAM, set up\n     pin multiplexing, and so on.  (You may be able to switch to a fast\n     JTAG clock rate here, after the target clocks are fully set up.)\n   * reset-start\n     Issued as the first step in 'reset' processing before\n     'reset-assert-pre' is called.\n\n     This is the most robust place to use 'jtag_rclk' or 'adapter speed'\n     to switch to a low JTAG clock rate, when reset disables PLLs needed\n     to use a fast clock.\n   * resume-start\n     Before any target is resumed\n   * resume-end\n     After all targets have resumed\n   * resumed\n     Target has resumed\n   * step-start\n     Before a target is single-stepped\n   * step-end\n     After single-step has completed\n   * trace-config\n     After target hardware trace configuration was changed\n   * semihosting-user-cmd-0x100\n     The target made a semihosting call with user-defined operation\n     number 0x100\n   * semihosting-user-cmd-0x101\n     The target made a semihosting call with user-defined operation\n     number 0x101\n   * semihosting-user-cmd-0x102\n     The target made a semihosting call with user-defined operation\n     number 0x102\n   * semihosting-user-cmd-0x103\n     The target made a semihosting call with user-defined operation\n     number 0x103\n   * semihosting-user-cmd-0x104\n     The target made a semihosting call with user-defined operation\n     number 0x104\n   * semihosting-user-cmd-0x105\n     The target made a semihosting call with user-defined operation\n     number 0x105\n   * semihosting-user-cmd-0x106\n     The target made a semihosting call with user-defined operation\n     number 0x106\n   * semihosting-user-cmd-0x107\n     The target made a semihosting call with user-defined operation\n     number 0x107\n\n     Note: OpenOCD events are not supposed to be preempt by another\n     event, but this is not enforced in current code.  Only the target\n     event resumed is executed with polling disabled; this avoids\n     polling to trigger the event halted, reversing the logical order of\n     execution of their handlers.  Future versions of OpenOCD will\n     prevent the event preemption and will disable the schedule of\n     polling during the event execution.  Do not rely on polling in any\n     event handler; this means, don't expect the status of a core to\n     change during the execution of the handler.  The event handler will\n     have to enable polling or use '$target_name arp_poll' to check if\n     the core has changed status.\n\n\u001f\nFile: openocd.info,  Node: Flash Commands,  Next: Flash Programming,  Prev: CPU Configuration,  Up: Top\n\n12 Flash Commands\n*****************\n\nOpenOCD has different commands for NOR and NAND flash; the \"flash\"\ncommand works with NOR flash, while the \"nand\" command works with NAND\nflash.  This partially reflects different hardware technologies: NOR\nflash usually supports direct CPU instruction and data bus access, while\ndata from a NAND flash must be copied to memory before it can be used.\n(SPI flash must also be copied to memory before use.)  However, the\ndocumentation also uses \"flash\" as a generic term; for example, \"Put\nflash configuration in board-specific files\".\n\nFlash Steps:\n  1. Configure via the command 'flash bank'\n     Do this in a board-specific configuration file, passing parameters\n     as needed by the driver.\n  2. Operate on the flash via 'flash subcommand'\n     Often commands to manipulate the flash are typed by a human, or run\n     via a script in some automated way.  Common tasks include writing a\n     boot loader, operating system, or other data.\n  3. GDB Flashing\n     Flashing via GDB requires the flash be configured via \"flash bank\",\n     and the GDB flash features be enabled.  *Note GDB Configuration:\n     gdbconfiguration.\n\nMany CPUs have the ability to \"boot\" from the first flash bank.  This\nmeans that misprogramming that bank can \"brick\" a system, so that it\ncan't boot.  JTAG tools, like OpenOCD, are often then used to \"de-brick\"\nthe board by (re)installing working boot firmware.\n\n12.1 Flash Configuration Commands\n=================================\n\n -- Config Command: flash bank name driver base size chip_width\n          bus_width target [driver_options]\n     Configures a flash bank which provides persistent storage for\n     addresses from base to base + size - 1.  These banks will often be\n     visible to GDB through the target's memory map.  In some cases,\n     configuring a flash bank will activate extra commands; see the\n     driver-specific documentation.\n\n        * NAME ...  may be used to reference the flash bank in other\n          flash commands.  A number is also available.\n        * DRIVER ...  identifies the controller driver associated with\n          the flash bank being declared.  This is usually 'cfi' for\n          external flash, or else the name of a microcontroller with\n          embedded flash memory.  *Note Flash Driver List:\n          flashdriverlist.\n        * BASE ...  Base address of the flash chip.\n        * SIZE ...  Size of the chip, in bytes.  For some drivers, this\n          value is detected from the hardware.\n        * CHIP_WIDTH ...  Width of the flash chip, in bytes; ignored for\n          most microcontroller drivers.\n        * BUS_WIDTH ...  Width of the data bus used to access the chip,\n          in bytes; ignored for most microcontroller drivers.\n        * TARGET ...  Names the target used to issue commands to the\n          flash controller.\n        * DRIVER_OPTIONS ...  drivers may support, or require,\n          additional parameters.  See the driver-specific documentation\n          for more information.\n          Note: This command is not available after OpenOCD\n          initialization has completed.  Use it in board specific\n          configuration files, not interactively.\n\n -- Command: flash banks\n     Prints a one-line summary of each device that was declared using\n     'flash bank', numbered from zero.  Note that this is the _plural_\n     form; the _singular_ form is a very different command.\n\n -- Command: flash list\n     Retrieves a list of associative arrays for each device that was\n     declared using 'flash bank', numbered from zero.  This returned\n     list can be manipulated easily from within scripts.\n\n -- Command: flash probe num\n     Identify the flash, or validate the parameters of the configured\n     flash.  Operation depends on the flash type.  The NUM parameter is\n     a value shown by 'flash banks'.  Most flash commands will\n     implicitly _autoprobe_ the bank; flash drivers can distinguish\n     between probing and autoprobing, but most don't bother.\n\n12.2 Preparing a Target before Flash Programming\n================================================\n\nThe target device should be in well defined state before the flash\nprogramming begins.\n\n_Always issue_ 'reset init' before *note Flash Programming Commands:\nflashprogrammingcommands.  Do not issue another 'reset' or 'reset halt'\nor 'resume' until the programming session is finished.\n\nIf you use *note Programming using GDB: programmingusinggdb, the target\nis prepared automatically in the event gdb-flash-erase-start\n\nThe jimtcl script 'program' calls 'reset init' explicitly.\n\n12.3 Erasing, Reading, Writing to Flash\n=======================================\n\nOne feature distinguishing NOR flash from NAND or serial flash\ntechnologies is that for read access, it acts exactly like any other\naddressable memory.  This means you can use normal memory read commands\nlike 'mdw' or 'dump_image' with it, with no special 'flash' subcommands.\n*Note Memory access: memoryaccess, and *note Image access: imageaccess.\n\nWrite access works differently.  Flash memory normally needs to be\nerased before it's written.  Erasing a sector turns all of its bits to\nones, and writing can turn ones into zeroes.  This is why there are\nspecial commands for interactive erasing and writing, and why GDB needs\nto know which parts of the address space hold NOR flash memory.\n\n     Note: Most of these erase and write commands leverage the fact that\n     NOR flash chips consume target address space.  They implicitly\n     refer to the current JTAG target, and map from an address in that\n     target's address space back to a flash bank.  A few commands use\n     abstract addressing based on bank and sector numbers, and don't\n     depend on searching the current target and its address space.\n     Avoid confusing the two command models.\n\nSome flash chips implement software protection against accidental\nwrites, since such buggy writes could in some cases \"brick\" a system.\nFor such systems, erasing and writing may require sector protection to\nbe disabled first.  Examples include CFI flash such as \"Intel Advanced\nBootblock flash\", and AT91SAM7 on-chip flash.  *Note flash protect:\nflashprotect.\n\n -- Command: flash erase_sector num first last\n     Erase sectors in bank NUM, starting at sector FIRST up to and\n     including LAST.  Sector numbering starts at 0.  Providing a LAST\n     sector of 'last' specifies \"to the end of the flash bank\".  The NUM\n     parameter is a value shown by 'flash banks'.\n\n -- Command: flash erase_address [pad] [unlock] address length\n     Erase sectors starting at ADDRESS for LENGTH bytes.  Unless 'pad'\n     is specified, address must begin a flash sector, and address +\n     length - 1 must end a sector.  Specifying 'pad' erases extra data\n     at the beginning and/or end of the specified region, as needed to\n     erase only full sectors.  The flash bank to use is inferred from\n     the ADDRESS, and the specified length must stay within that bank.\n     As a special case, when LENGTH is zero and ADDRESS is the start of\n     the bank, the whole flash is erased.  If 'unlock' is specified,\n     then the flash is unprotected before erase starts.\n\n -- Command: flash filld address double-word length\n -- Command: flash fillw address word length\n -- Command: flash fillh address halfword length\n -- Command: flash fillb address byte length\n     Fills flash memory with the specified DOUBLE-WORD (64 bits), WORD\n     (32 bits), HALFWORD (16 bits), or BYTE (8-bit) pattern, starting at\n     ADDRESS and continuing for LENGTH units (word/halfword/byte).  No\n     erasure is done before writing; when needed, that must be done\n     before issuing this command.  Writes are done in blocks of up to\n     1024 bytes, and each write is verified by reading back the data and\n     comparing it to what was written.  The flash bank to use is\n     inferred from the ADDRESS of each block, and the specified length\n     must stay within that bank.\n\n -- Command: flash mdw addr [count]\n -- Command: flash mdh addr [count]\n -- Command: flash mdb addr [count]\n     Display contents of address ADDR, as 32-bit words ('mdw'), 16-bit\n     halfwords ('mdh'), or 8-bit bytes ('mdb').  If COUNT is specified,\n     displays that many units.  Reads from flash using the flash driver,\n     therefore it enables reading from a bank not mapped in target\n     address space.  The flash bank to use is inferred from the ADDRESS\n     of each block, and the specified length must stay within that bank.\n\n -- Command: flash write_bank num filename [offset]\n     Write the binary 'filename' to flash bank NUM, starting at OFFSET\n     bytes from the beginning of the bank.  If OFFSET is omitted, start\n     at the beginning of the flash bank.  The NUM parameter is a value\n     shown by 'flash banks'.\n\n -- Command: flash read_bank num filename [offset [length]]\n     Read LENGTH bytes from the flash bank NUM starting at OFFSET and\n     write the contents to the binary 'filename'.  If OFFSET is omitted,\n     start at the beginning of the flash bank.  If LENGTH is omitted,\n     read the remaining bytes from the flash bank.  The NUM parameter is\n     a value shown by 'flash banks'.\n\n -- Command: flash verify_bank num filename [offset]\n     Compare the contents of the binary file FILENAME with the contents\n     of the flash bank NUM starting at OFFSET.  If OFFSET is omitted,\n     start at the beginning of the flash bank.  Fail if the contents do\n     not match.  The NUM parameter is a value shown by 'flash banks'.\n\n -- Command: flash write_image [erase] [unlock] filename [offset] [type]\n     Write the image 'filename' to the current target's flash bank(s).\n     Only loadable sections from the image are written.  A relocation\n     OFFSET may be specified, in which case it is added to the base\n     address for each section in the image.  The file [TYPE] can be\n     specified explicitly as 'bin' (binary), 'ihex' (Intel hex), 'elf'\n     (ELF file), 's19' (Motorola s19).  'mem', or 'builder'.  The\n     relevant flash sectors will be erased prior to programming if the\n     'erase' parameter is given.  If 'unlock' is provided, then the\n     flash banks are unlocked before erase and program.  The flash bank\n     to use is inferred from the address of each image section.\n\n          Warning: Be careful using the 'erase' flag when the flash is\n          holding data you want to preserve.  Portions of the flash\n          outside those described in the image's sections might be\n          erased with no notice.\n             * When a section of the image being written does not fill\n               out all the sectors it uses, the unwritten parts of those\n               sectors are necessarily also erased, because sectors\n               can't be partially erased.\n             * Data stored in sector \"holes\" between image sections are\n               also affected.  For example, \"'flash write_image erase\n               ...'\" of an image with one byte at the beginning of a\n               flash bank and one byte at the end erases the entire bank\n               - not just the two sectors being written.\n          Also, when flash protection is important, you must re-apply it\n          after it has been removed by the 'unlock' flag.\n\n -- Command: flash verify_image filename [offset] [type]\n     Verify the image 'filename' to the current target's flash bank(s).\n     Parameters follow the description of 'flash write_image'.  In\n     contrast to the 'verify_image' command, for banks with specific\n     verify method, that one is used instead of the usual target's read\n     memory methods.  This is necessary for flash banks not readable by\n     ordinary memory reads.  This command gives only an overall good/bad\n     result for each bank, not addresses of individual failed bytes as\n     it's intended only as quick check for successful programming.\n\n12.4 Other Flash commands\n=========================\n\n -- Command: flash erase_check num\n     Check erase state of sectors in flash bank NUM, and display that\n     status.  The NUM parameter is a value shown by 'flash banks'.\n\n -- Command: flash info num [sectors]\n     Print info about flash bank NUM, a list of protection blocks and\n     their status.  Use 'sectors' to show a list of sectors instead.\n\n     The NUM parameter is a value shown by 'flash banks'.  This command\n     will first query the hardware, it does not print cached and\n     possibly stale information.\n\n -- Command: flash protect num first last (on|off)\n     Enable ('on') or disable ('off') protection of flash blocks in\n     flash bank NUM, starting at protection block FIRST and continuing\n     up to and including LAST.  Providing a LAST block of 'last'\n     specifies \"to the end of the flash bank\".  The NUM parameter is a\n     value shown by 'flash banks'.  The protection block is usually\n     identical to a flash sector.  Some devices may utilize a protection\n     block distinct from flash sector.  See 'flash info' for a list of\n     protection blocks.\n\n -- Command: flash padded_value num value\n     Sets the default value used for padding any image sections, This\n     should normally match the flash bank erased value.  If not\n     specified by this command or the flash driver then it defaults to\n     0xff.\n\n -- Command: program filename [preverify] [verify] [reset] [exit]\n          [offset]\n     This is a helper script that simplifies using OpenOCD as a\n     standalone programmer.  The only required parameter is 'filename',\n     the others are optional.  *Note Flash Programming::.\n\n12.5 Flash Driver List\n======================\n\nAs noted above, the 'flash bank' command requires a driver name, and\nallows driver-specific options and behaviors.  Some drivers also\nactivate driver-specific commands.\n\n -- Flash Driver: virtual\n     This is a special driver that maps a previously defined bank to\n     another address.  All bank settings will be copied from the master\n     physical bank.\n\n     The VIRTUAL driver defines one mandatory parameters,\n\n        * MASTER_BANK The bank that this virtual address refers to.\n\n     So in the following example addresses 0xbfc00000 and 0x9fc00000\n     refer to the flash bank defined at address 0x1fc00000.  Any command\n     executed on the virtual banks is actually performed on the physical\n     banks.\n          flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n          flash bank vbank0 virtual 0xbfc00000 0 0 0 \\\n                     $_TARGETNAME $_FLASHNAME\n          flash bank vbank1 virtual 0x9fc00000 0 0 0 \\\n                     $_TARGETNAME $_FLASHNAME\n\n12.5.1 External Flash\n---------------------\n\n -- Flash Driver: cfi\n     The \"Common Flash Interface\" (CFI) is the main standard for\n     external NOR flash chips, each of which connects to a specific\n     external chip select on the CPU. Frequently the first such chip is\n     used to boot the system.  Your board's 'reset-init' handler might\n     need to configure additional chip selects using other commands\n     (like: 'mww' to configure a bus and its timings), or perhaps\n     configure a GPIO pin that controls the \"write protect\" pin on the\n     flash chip.  The CFI driver can use a target-specific working area\n     to significantly speed up operation.\n\n     The CFI driver can accept the following optional parameters, in any\n     order:\n\n        * JEDEC_PROBE ...  is used to detect certain non-CFI flash ROMs,\n          like AM29LV010 and similar types.\n        * X16_AS_X8 ...  when a 16-bit flash is hooked up to an 8-bit\n          bus.\n        * BUS_SWAP ...  when data bytes in a 16-bit flash needs to be\n          swapped.\n        * DATA_SWAP ...  when data bytes in a 16-bit flash needs to be\n          swapped when writing data values (i.e.  not CFI commands).\n\n     To configure two adjacent banks of 16 MBytes each, both sixteen\n     bits (two bytes) wide on a sixteen bit bus:\n\n          flash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n          flash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\n     To configure one bank of 32 MBytes built from two sixteen bit (two\n     byte) wide parts wired in parallel to create a thirty-two bit (four\n     byte) bus with doubled throughput:\n\n          flash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n\n -- Flash Driver: jtagspi\n     Several FPGAs and CPLDs can retrieve their configuration\n     (bitstream) from a SPI flash connected to them.  To access this\n     flash from the host, the device is first programmed with a special\n     proxy bitstream that exposes the SPI flash on the device's JTAG\n     interface.  The flash can then be accessed through JTAG.\n\n     Since signaling between JTAG and SPI is compatible, all that is\n     required for a proxy bitstream is to connect TDI-MOSI, TDO-MISO,\n     TCK-CLK and activate the flash chip select when the JTAG state\n     machine is in SHIFT-DR. Such a bitstream for several Xilinx FPGAs\n     can be found in 'contrib/loaders/flash/fpga/xilinx_bscan_spi.py'.\n     It requires migen (https://github.com/m-labs/migen) and a Xilinx\n     toolchain to build.\n\n     This flash bank driver requires a target on a JTAG tap and will\n     access that tap directly.  Since no support from the target is\n     needed, the target can be a \"testee\" dummy.  Since the target does\n     not expose the flash memory mapping, target commands that would\n     otherwise be expected to access the flash will not work.  These\n     include all '*_image' and '$target_name m*' commands as well as\n     'program'.  Equivalent functionality is available through the\n     'flash write_bank', 'flash read_bank', and 'flash verify_bank'\n     commands.\n\n     According to device size, 1- to 4-byte addresses are sent.\n     However, some flash chips additionally have to be switched to\n     4-byte addresses by an extra command, see below.\n\n        * IR ...  is loaded into the JTAG IR to map the flash as the\n          JTAG DR. For the bitstreams generated from\n          'xilinx_bscan_spi.py' this is the USER1 instruction.\n\n          target create $_TARGETNAME testee -chain-position $_CHIPNAME.fpga\n          set _XILINX_USER1 0x02\n          flash bank $_FLASHNAME spi 0x0 0 0 0 \\\n                     $_TARGETNAME $_XILINX_USER1\n\n      -- Command: jtagspi set bank_id name total_size page_size read_cmd\n               unused pprg_cmd mass_erase_cmd sector_size\n               sector_erase_cmd\n          Sets flash parameters: NAME human readable string, TOTAL_SIZE\n          size in bytes, PAGE_SIZE is write page size.  READ_CMD and\n          PPRG_CMD are commands for read and page program, respectively.\n          MASS_ERASE_CMD, SECTOR_SIZE and SECTOR_ERASE_CMD are optional.\n               jtagspi set 0 w25q128 0x1000000 0x100 0x03 0 0x02 0xC7 0x10000 0xD8\n\n      -- Command: jtagspi cmd bank_id resp_num cmd_byte ...\n          Sends command CMD_BYTE and at most 20 following bytes and\n          reads RESP_NUM bytes afterwards.  E.g.  for 'Enter 4-byte\n          address mode'\n               jtagspi cmd 0 0 0xB7\n\n      -- Command: jtagspi always_4byte bank_id [ on | off ]\n          Some devices use 4-byte addresses for all commands except the\n          legacy 0x03 read regardless of device size.  This command\n          controls the corresponding hack.\n\n -- Flash Driver: xcf\n     Xilinx FPGAs can be configured from specialized flash ICs named\n     Platform Flash.  It is (almost) regular NOR flash with erase\n     sectors, program pages, etc.  The only difference is special\n     registers controlling its FPGA specific behavior.  They must be\n     properly configured for successful FPGA loading using additional\n     XCF driver command:\n\n      -- Command: xcf ccb <bank_id>\n          command accepts additional parameters:\n             * EXTERNAL|INTERNAL ...  selects clock source.\n             * SERIAL|PARALLEL ...  selects serial or parallel data bus\n               mode.\n             * SLAVE|MASTER ...  selects slave of master mode for flash\n               device.\n             * 40|20 ...  selects clock frequency in MHz for internal\n               clock in master mode.\n               xcf ccb 0 external parallel slave 40\n          All of them must be specified even if clock frequency is\n          pointless in slave mode.  If only bank id specified than\n          command prints current CCB register value.  Note: there is no\n          need to write this register every time you erase/program data\n          sectors because it stores in dedicated sector.\n\n      -- Command: xcf configure <bank_id>\n          Initiates FPGA loading procedure.  Useful if your board has no\n          \"configure\" button.\n               xcf configure 0\n\n     Additional driver notes:\n        * Only single revision supported.\n        * Driver automatically detects need of bit reverse, but only\n          \"bin\" (raw binary, do not confuse it with \"bit\") and \"mcs\"\n          (Intel hex) file types supported.\n        * For additional info check xapp972.pdf and ug380.pdf.\n\n -- Flash Driver: lpcspifi\n     NXP's LPC43xx and LPC18xx families include a proprietary SPI Flash\n     Interface (SPIFI) peripheral that can drive and provide memory\n     mapped access to external SPI flash devices.\n\n     The lpcspifi driver initializes this interface and provides program\n     and erase functionality for these serial flash devices.  Use of\n     this driver requires a working area of at least 1kB to be\n     configured on the target device; more than this will significantly\n     reduce flash programming times.\n\n     The setup command only requires the BASE parameter.  All other\n     parameters are ignored, and the flash size and layout are\n     configured by the driver.\n\n          flash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: stmsmi\n     Some devices from STMicroelectronics (e.g.  STR75x MCU family,\n     SPEAr MPU family) include a proprietary \"Serial Memory Interface\"\n     (SMI) controller able to drive external SPI flash devices.\n     Depending on specific device and board configuration, up to 4\n     external flash devices can be connected.\n\n     SMI makes the flash content directly accessible in the CPU address\n     space; each external device is mapped in a memory bank.  CPU can\n     directly read data, execute code and boot from SMI banks.  Normal\n     OpenOCD commands like 'mdw' can be used to display the flash\n     content.\n\n     The setup command only requires the BASE parameter in order to\n     identify the memory bank.  All other parameters are ignored.\n     Additional information, like flash size, are detected\n     automatically.\n\n          flash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: stmqspi\n     Some devices from STMicroelectronics include a proprietary \"QuadSPI\n     Interface\" (e.g.  STM32F4, STM32F7, STM32L4) or \"OctoSPI Interface\"\n     (e.g.  STM32L4+) controller able to drive one or even two (dual\n     mode) external SPI flash devices.  The OctoSPI is a superset of\n     QuadSPI, its presence is detected automatically.  Currently only\n     the regular command mode is supported, whereas the HyperFlash mode\n     is not.\n\n     QuadSPI/OctoSPI makes the flash contents directly accessible in the\n     CPU address space; in case of dual mode both devices must be of the\n     same type and are mapped in the same memory bank (even and odd\n     addresses interleaved).  CPU can directly read data, execute code\n     (but not boot) from QuadSPI bank.\n\n     The 'flash bank' command only requires the BASE parameter and the\n     extra parameter IO_BASE in order to identify the memory bank.  Both\n     are fixed by hardware, see datasheet or RM. All other parameters\n     are ignored.\n\n     The controller must be initialized after each reset and properly\n     configured for memory-mapped read operation for the particular\n     flash chip(s), for the full list of available register settings cf.\n     the controller's RM. This setup is quite board specific (that's why\n     booting from this memory is not possible).  The flash driver infers\n     all parameters from current controller register values when 'flash\n     probe BANK_ID' is executed.\n\n     Normal OpenOCD commands like 'mdw' can be used to display the flash\n     content, but only after proper controller initialization as\n     described above.  However, due to a silicon bug in some devices,\n     attempting to access the very last word should be avoided.\n\n     It is possible to use two (even different) flash chips\n     alternatingly, if individual bank chip selects are available.  For\n     some package variants, this is not the case due to limited pin\n     count.  To switch from one to another, adjust FSEL bit accordingly\n     and re-issue 'flash probe bank_id'.  Note that the bank base\n     address will _not_ change, so the address spaces of both devices\n     will overlap.  In dual flash mode both chips must be identical\n     regarding size and most other properties.\n\n     Block or sector protection internal to the flash chip is not\n     handled by this driver at all, but can be dealt with manually by\n     the 'cmd' command, see below.  The sector protection via 'flash\n     protect' command etc.  is completely internal to openocd, intended\n     only to prevent accidental erase or overwrite and it does not\n     persist across openocd invocations.\n\n     OpenOCD contains a hardcoded list of flash devices with their\n     properties, these are auto-detected.  If a device is not included\n     in this list, SFDP discovery is attempted.  If this fails or gives\n     inappropriate results, manual setting is required (see 'set'\n     command).\n\n          flash bank $_FLASHNAME stmqspi 0x90000000 0 0 0 \\\n                     $_TARGETNAME 0xA0001000\n          flash bank $_FLASHNAME stmqspi 0x70000000 0 0 0 \\\n                     $_TARGETNAME 0xA0001400\n\n     There are three specific commands\n      -- Command: stmqspi mass_erase bank_id\n          Clears sector protections and performs a mass erase.  Works\n          only if there is no chip specific write protection engaged.\n\n      -- Command: stmqspi set bank_id name total_size page_size read_cmd\n               fread_cmd pprg_cmd mass_erase_cmd sector_size\n               sector_erase_cmd\n          Set flash parameters: NAME human readable string, TOTAL_SIZE\n          size in bytes, PAGE_SIZE is write page size.  READ_CMD,\n          FREAD_CMD and PPRG_CMD are commands for reading and page\n          programming.  FREAD_CMD is used in DPI and QPI modes, READ_CMD\n          in normal SPI (single line) mode.  MASS_ERASE_CMD, SECTOR_SIZE\n          and SECTOR_ERASE_CMD are optional.\n\n          This command is required if chip id is not hardcoded yet and\n          e.g.  for EEPROMs or FRAMs which don't support an id command.\n\n          In dual mode parameters of both chips are set identically.\n          The parameters refer to a single chip, so the whole bank gets\n          twice the specified capacity etc.\n\n      -- Command: stmqspi cmd bank_id resp_num cmd_byte ...\n          If RESP_NUM is zero, sends command CMD_BYTE and following data\n          bytes.  In dual mode command byte is sent to _both_ chips but\n          data bytes are sent _alternatingly_ to chip 1 and 2, first to\n          flash 1, second to flash 2, etc., i.e.  the total number of\n          bytes (including cmd_byte) must be odd.\n\n          If RESP_NUM is not zero, cmd and at most four following data\n          bytes are sent, in dual mode _simultaneously_ to both chips.\n          Then RESP_NUM bytes are read interleaved from both chips\n          starting with chip 1.  In this case RESP_NUM must be even.\n\n          Note the hardware dictated subtle difference of those two\n          cases in dual-flash mode.\n\n          To check basic communication settings, issue\n               stmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 1 0x05\n               stmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 1 0x05\n          for single flash mode or\n               stmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 2 0x05\n               stmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 2 0x05\n          for dual flash mode.  This should return the status register\n          contents.\n\n          In 8-line mode, CMD_BYTE is sent twice - first time as given,\n          second time complemented.  Additionally, in 8-line mode only,\n          some commands (e.g.  Read Status) need a dummy address, e.g.\n               stmqspi cmd bank_id 1 0x05 0x00 0x00 0x00 0x00\n          should return the status register contents.\n\n -- Flash Driver: mrvlqspi\n     This driver supports QSPI flash controller of Marvell's Wireless\n     Microcontroller platform.\n\n     The flash size is autodetected based on the table of known JEDEC\n     IDs hardcoded in the OpenOCD sources.\n\n          flash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000\n\n -- Flash Driver: ath79\n     Members of ATH79 SoC family from Atheros include a SPI interface\n     with 3 chip selects.  On reset a SPI flash connected to the first\n     chip select (CS0) is made directly read-accessible in the CPU\n     address space (up to 16MBytes) and is usually used to store the\n     bootloader and operating system.  Normal OpenOCD commands like\n     'mdw' can be used to display the flash content while it is in\n     memory-mapped mode (only the first 4MBytes are accessible without\n     additional configuration on reset).\n\n     The setup command only requires the BASE parameter in order to\n     identify the memory bank.  The actual value for the base address is\n     not otherwise used by the driver.  However the mapping is passed to\n     gdb.  Thus for the memory mapped flash (chipselect CS0) the base\n     address should be the actual memory mapped base address.  For\n     unmapped chipselects (CS1 and CS2) care should be taken to use a\n     base address that does not overlap with real memory regions.\n     Additional information, like flash size, are detected\n     automatically.  An optional additional parameter sets the\n     chipselect for the bank, with the default CS0.  CS1 and CS2 require\n     additional GPIO setup before they can be used since the alternate\n     function must be enabled on the GPIO pin CS1/CS2 is routed to on\n     the given SoC.\n\n          flash bank $_FLASHNAME ath79 0xbf000000 0 0 0 $_TARGETNAME\n\n          # When using multiple chipselects the base should be different\n          # for each, otherwise the write_image command is not able to\n          # distinguish the banks.\n          flash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n          flash bank flash1 ath79 0x10000000 0 0 0 $_TARGETNAME cs1\n          flash bank flash2 ath79 0x20000000 0 0 0 $_TARGETNAME cs2\n\n -- Flash Driver: fespi\n\n     SiFive's Freedom E SPI controller, used in HiFive and other boards.\n\n          flash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME\n\n12.5.2 Internal Flash (Microcontrollers)\n----------------------------------------\n\n -- Flash Driver: aduc702x\n     The ADUC702x analog microcontrollers from Analog Devices include\n     internal flash and use ARM7TDMI cores.  The aduc702x flash driver\n     works with models ADUC7019 through ADUC7028.  The setup command\n     only requires the TARGET argument since all devices in this family\n     have the same memory layout.\n\n          flash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: ambiqmicro\n     All members of the Apollo microcontroller family from Ambiq Micro\n     include internal flash and use ARM's Cortex-M4 core.  The host\n     connects over USB to an FTDI interface that communicates with the\n     target using SWD.\n\n     The AMBIQMICRO driver reads the Chip Information Register detect\n     the device class of the MCU. The Flash and SRAM sizes directly\n     follow device class, and are used to set up the flash banks.  If\n     this fails, the driver will use default values set to the minimum\n     sizes of an Apollo chip.\n\n     All Apollo chips have two flash banks of the same size.  In all\n     cases the first flash bank starts at location 0, and the second\n     bank starts after the first.\n\n          # Flash bank 0\n          flash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME\n          # Flash bank 1 - same size as bank0, starts after bank 0.\n          flash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 \\\n                     $_TARGETNAME\n\n     Flash is programmed using custom entry points into the bootloader.\n     This is the only way to program the flash as no flash control\n     registers are available to the user.\n\n     The AMBIQMICRO driver adds some additional commands:\n\n      -- Command: ambiqmicro mass_erase <bank>\n          Erase entire bank.\n      -- Command: ambiqmicro page_erase <bank> <first> <last>\n          Erase device pages.\n      -- Command: ambiqmicro program_otp <bank> <offset> <count>\n          Program OTP is a one time operation to create write protected\n          flash.  The user writes sectors to SRAM starting at\n          0x10000010.  Program OTP will write these sectors from SRAM to\n          flash, and write protect the flash.\n\n -- Flash Driver: at91samd\n     All members of the ATSAM D2x, D1x, D0x, ATSAMR, ATSAML and ATSAMC\n     microcontroller families from Atmel include internal flash and use\n     ARM's Cortex-M0+ core.\n\n     Do not use for ATSAM D51 and E5x: use *Note atsame5::.\n\n     The devices have one flash bank:\n\n          flash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n\n      -- Command: at91samd chip-erase\n          Issues a complete Flash erase via the Device Service Unit\n          (DSU). This can be used to erase a chip back to its factory\n          state and does not require the processor to be halted.\n\n      -- Command: at91samd set-security\n          Secures the Flash via the Set Security Bit (SSB) command.\n          This prevents access to the Flash and can only be undone by\n          using the chip-erase command which erases the Flash contents\n          and turns off the security bit.  Warning: at this time,\n          openocd will not be able to communicate with a secured chip\n          and it is therefore not possible to chip-erase it without\n          using another tool.\n\n               at91samd set-security enable\n\n      -- Command: at91samd eeprom\n          Shows or sets the EEPROM emulation size configuration, stored\n          in the User Row of the Flash.  When setting, the EEPROM size\n          must be specified in bytes and it must be one of the permitted\n          sizes according to the datasheet.  Settings are written\n          immediately but only take effect on MCU reset.  EEPROM\n          emulation requires additional firmware support and the minimum\n          EEPROM size may not be the same as the minimum that the\n          hardware supports.  Set the EEPROM size to 0 in order to\n          disable this feature.\n\n               at91samd eeprom\n               at91samd eeprom 1024\n\n      -- Command: at91samd bootloader\n          Shows or sets the bootloader size configuration, stored in the\n          User Row of the Flash.  This is called the BOOTPROT region.\n          When setting, the bootloader size must be specified in bytes\n          and it must be one of the permitted sizes according to the\n          datasheet.  Settings are written immediately but only take\n          effect on MCU reset.  Setting the bootloader size to 0\n          disables bootloader protection.\n\n               at91samd bootloader\n               at91samd bootloader 16384\n\n      -- Command: at91samd dsu_reset_deassert\n          This command releases internal reset held by DSU and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n      -- Command: at91samd nvmuserrow\n          Writes or reads the entire 64 bit wide NVM user row register\n          which is located at 0x804000.  This register includes various\n          fuses lock-bits and factory calibration data.  Reading the\n          register is done by invoking this command without any\n          arguments.  Writing is possible by giving 1 or 2 hex values.\n          The first argument is the register value to be written and the\n          second one is an optional changemask.  Every bit which value\n          in changemask is 0 will stay unchanged.  The lock- and\n          reserved-bits are masked out and cannot be changed.\n\n               # Read user row\n               >at91samd nvmuserrow\n               NVMUSERROW: 0xFFFFFC5DD8E0C788\n               # Write 0xFFFFFC5DD8E0C788 to user row\n               >at91samd nvmuserrow 0xFFFFFC5DD8E0C788\n               # Write 0x12300 to user row but leave other bits and low\n               # byte unchanged\n               >at91samd nvmuserrow 0x12345 0xFFF00\n\n -- Flash Driver: at91sam3\n     All members of the AT91SAM3 microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M3 core.  The driver\n     currently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips.\n     Note that the driver was orginaly developed and tested using the\n     AT91SAM3U4E, using a SAM3U-EK eval board.  Support for other chips\n     in the family was cribbed from the data sheet.  _Note to future\n     readers/updaters: Please remove this worrisome comment after other\n     chips are confirmed._\n\n     The AT91SAM3U4[E/C] (256K) chips have two flash banks; most other\n     chips have one flash bank.  In all cases the flash banks are at the\n     following fixed locations:\n\n          # Flash bank 0 - all chips\n          flash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME\n          # Flash bank 1 - only 256K chips\n          flash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME\n\n     Internally, the AT91SAM3 flash memory is organized as follows.\n     Unlike the AT91SAM7 chips, these are not used as parameters to the\n     'flash bank' command:\n\n        * _N-Banks:_ 256K chips have 2 banks, others have 1 bank.\n        * _Bank Size:_ 128K/64K Per flash bank\n        * _Sectors:_ 16 or 8 per bank\n        * _SectorSize:_ 8K Per Sector\n        * _PageSize:_ 256 bytes per page.  Note that OpenOCD operates on\n          'sector' sizes, not page sizes.\n\n     The AT91SAM3 driver adds some additional commands:\n\n      -- Command: at91sam3 gpnvm\n      -- Command: at91sam3 gpnvm clear number\n      -- Command: at91sam3 gpnvm set number\n      -- Command: at91sam3 gpnvm show [all|number]\n          With no parameters, 'show' or 'show all', shows the status of\n          all GPNVM bits.  With 'show' NUMBER, displays that bit.\n\n          With 'set' NUMBER or 'clear' NUMBER, modifies that GPNVM bit.\n\n      -- Command: at91sam3 info\n          This command attempts to display information about the\n          AT91SAM3 chip.  _First_ it read the 'CHIPID_CIDR' [address\n          0x400e0740, see Section 28.2.1, page 505 of the AT91SAM3U\n          29/may/2009 datasheet, document id: doc6430A] and decodes the\n          values.  _Second_ it reads the various clock configuration\n          registers and attempts to display how it believes the chip is\n          configured.  By default, the SLOWCLK is assumed to be 32768\n          Hz, see the command 'at91sam3 slowclk'.\n\n      -- Command: at91sam3 slowclk [value]\n          This command shows/sets the slow clock frequency used in the\n          'at91sam3 info' command calculations above.\n\n -- Flash Driver: at91sam4\n     All members of the AT91SAM4 microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M4 core.  This driver\n     uses the same command names/syntax as *Note at91sam3::.\n\n -- Flash Driver: at91sam4l\n     All members of the AT91SAM4L microcontroller family from Atmel\n     include internal flash and use ARM's Cortex-M4 core.  This driver\n     uses the same command names/syntax as *Note at91sam3::.\n\n     The AT91SAM4L driver adds some additional commands:\n      -- Command: at91sam4l smap_reset_deassert\n          This command releases internal reset held by SMAP and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n -- Flash Driver: atsame5\n     All members of the SAM E54, E53, E51 and D51 microcontroller\n     families from Microchip (former Atmel) include internal flash and\n     use ARM's Cortex-M4 core.\n\n     The devices have two ECC flash banks with a swapping feature.  This\n     driver handles both banks together as it were one.  Bank swapping\n     is not supported yet.\n\n          flash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n\n      -- Command: atsame5 bootloader\n          Shows or sets the bootloader size configuration, stored in the\n          User Page of the Flash.  This is called the BOOTPROT region.\n          When setting, the bootloader size must be specified in bytes.\n          The nearest bigger protection size is used.  Settings are\n          written immediately but only take effect on MCU reset.\n          Setting the bootloader size to 0 disables bootloader\n          protection.\n\n               atsame5 bootloader\n               atsame5 bootloader 16384\n\n      -- Command: atsame5 chip-erase\n          Issues a complete Flash erase via the Device Service Unit\n          (DSU). This can be used to erase a chip back to its factory\n          state and does not require the processor to be halted.\n\n      -- Command: atsame5 dsu_reset_deassert\n          This command releases internal reset held by DSU and prepares\n          reset vector catch in case of reset halt.  Command is used\n          internally in event reset-deassert-post.\n\n      -- Command: atsame5 userpage\n          Writes or reads the first 64 bits of NVM User Page which is\n          located at 0x804000.  This field includes various fuses.\n          Reading is done by invoking this command without any\n          arguments.  Writing is possible by giving 1 or 2 hex values.\n          The first argument is the value to be written and the second\n          one is an optional bit mask (a zero bit in the mask means the\n          bit stays unchanged).  The reserved fields are always masked\n          out and cannot be changed.\n\n               # Read\n               >atsame5 userpage\n               USER PAGE: 0xAEECFF80FE9A9239\n               # Write\n               >atsame5 userpage 0xAEECFF80FE9A9239\n               # Write 2 to SEESBLK and 4 to SEEPSZ fields but leave other\n               # bits unchanged (setup SmartEEPROM of virtual size 8192\n               # bytes)\n               >atsame5 userpage 0x4200000000 0x7f00000000\n\n -- Flash Driver: atsamv\n     All members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from\n     Atmel include internal flash and use ARM's Cortex-M7 core.  This\n     driver uses the same command names/syntax as *Note at91sam3::.\n\n          flash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n\n      -- Command: atsamv gpnvm [show [all|number]]\n      -- Command: atsamv gpnvm (clr|set) number\n          With no parameters, 'show' or 'show all', shows the status of\n          all GPNVM bits.  With 'show' NUMBER, displays that bit.\n\n          With 'set' NUMBER or 'clear' NUMBER, modifies that GPNVM bit.\n\n -- Flash Driver: at91sam7\n     All members of the AT91SAM7 microcontroller family from Atmel\n     include internal flash and use ARM7TDMI cores.  The driver\n     automatically recognizes a number of these chips using the chip\n     identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME\n\n     For chips which are not recognized by the controller driver, you\n     must provide additional parameters in the following order:\n\n        * CHIP_MODEL ...  label used with 'flash info'\n        * BANKS\n        * SECTORS_PER_BANK\n        * PAGES_PER_SECTOR\n        * PAGES_SIZE\n        * NUM_NVM_BITS\n        * FREQ_KHZ ...  required if an external clock is provided,\n          optional (but recommended) when the oscillator frequency is\n          known\n\n     It is recommended that you provide zeroes for all of those values\n     except the clock frequency, so that everything except that\n     frequency will be autoconfigured.  Knowing the frequency helps\n     ensure correct timings for flash access.\n\n     The flash controller handles erases automatically on a page\n     (128/256 byte) basis, so explicit erase commands are not necessary\n     for flash programming.  However, there is an \"EraseAll\" command\n     that can erase an entire flash plane (of up to 256KB), and it will\n     be used automatically when you issue 'flash erase_sector' or 'flash\n     erase_address' commands.\n\n      -- Command: at91sam7 gpnvm bitnum (set|clear)\n          Set or clear a \"General Purpose Non-Volatile Memory\" (GPNVM)\n          bit for the processor.  Each processor has a number of such\n          bits, used for controlling features such as brownout detection\n          (so they are not truly general purpose).\n               Note: This assumes that the first flash bank (number 0)\n               is associated with the appropriate at91sam7 target.\n\n -- Flash Driver: avr\n     The AVR 8-bit microcontrollers from Atmel integrate flash memory.\n     _The current implementation is incomplete._\n\n -- Flash Driver: bluenrg-x\n     STMicroelectronics BlueNRG-1, BlueNRG-2 and BlueNRG-LP/LPS\n     Bluetooth low energy wireless system-on-chip.  They include ARM\n     Cortex-M0/M0+ core and internal flash memory.  The driver\n     automatically recognizes these chips using the chip identification\n     registers, and autoconfigures itself.\n\n          flash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n     Note that when users ask to erase all the sectors of the flash, a\n     mass erase command is used which is faster than erasing each single\n     sector one by one.\n\n          flash erase_sector 0 0 last # It will perform a mass erase\n\n     Triggering a mass erase is also useful when users want to disable\n     readout protection.\n\n -- Flash Driver: cc26xx\n     All versions of the SimpleLink CC13xx and CC26xx microcontrollers\n     from Texas Instruments include internal flash.  The cc26xx flash\n     driver supports both the CC13xx and CC26xx family of devices.  The\n     driver automatically recognizes the specific version's flash\n     parameters and autoconfigures itself.  The flash bank starts at\n     address 0.\n\n          flash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: cc3220sf\n     The CC3220SF version of the SimpleLink CC32xx microcontrollers from\n     Texas Instruments includes 1MB of internal flash.  The cc3220sf\n     flash driver only supports the internal flash.  The serial flash on\n     SimpleLink boards is programmed via the bootloader over a UART\n     connection.  Security features of the CC3220SF may erase the\n     internal flash during power on reset.  Refer to documentation at\n     <www.ti.com/cc3220sf> for details on security features and\n     programming the serial flash.\n\n          flash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: efm32\n     All members of the EFM32/EFR32 microcontroller family from Energy\n     Micro (now Silicon Labs) include internal flash and use Arm\n     Cortex-M3 or Cortex-M4 cores.  The driver automatically recognizes\n     a number of these chips using the chip identification register, and\n     autoconfigures itself.\n          flash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\n     It supports writing to the user data page, as well as the portion\n     of the lockbits page past 512 bytes on chips with larger page\n     sizes.  The latter is used by the SiLabs bootloader/AppLoader\n     system for encryption keys.  Setting protection on these pages is\n     currently not supported.\n          flash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\n          flash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\n     A special feature of efm32 controllers is that it is possible to\n     completely disable the debug interface by writing the correct\n     values to the 'Debug Lock Word'.  OpenOCD supports this via the\n     following command:\n          efm32 debuglock num\n     The NUM parameter is a value shown by 'flash banks'.  Note that in\n     order for this command to take effect, the target needs to be\n     reset.  _The current implementation is incomplete.  Unprotecting\n     flash pages is not supported._\n\n -- Flash Driver: esirisc\n     Members of the eSi-RISC family may optionally include internal\n     flash programmed via the eSi-TSMC Flash interface.  Additional\n     parameters are required to configure the driver: 'cfg_address' is\n     the base address of the configuration register interface,\n     'clock_hz' is the expected clock frequency, and 'wait_states' is\n     the number of configured read wait states.\n\n          flash bank $_FLASHNAME esirisc base_address size_bytes 0 0 \\\n                     $_TARGETNAME cfg_address clock_hz wait_states\n\n      -- Command: esirisc flash mass_erase bank_id\n          Erase all pages in data memory for the bank identified by\n          'bank_id'.\n\n      -- Command: esirisc flash ref_erase bank_id\n          Erase the reference cell for the bank identified by 'bank_id'.\n          _This is an uncommon operation._\n\n -- Flash Driver: fm3\n     All members of the FM3 microcontroller family from Fujitsu include\n     internal flash and use ARM Cortex-M3 cores.  The FM3 driver uses\n     the TARGET parameter to select the correct bank config, it can\n     currently be one of the following: 'mb9bfxx1.cpu', 'mb9bfxx2.cpu',\n     'mb9bfxx3.cpu', 'mb9bfxx4.cpu', 'mb9bfxx5.cpu' or 'mb9bfxx6.cpu'.\n\n          flash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: fm4\n     All members of the FM4 microcontroller family from Spansion\n     (formerly Fujitsu) include internal flash and use ARM Cortex-M4\n     cores.  The FM4 driver uses a FAMILY parameter to select the\n     correct bank config, it can currently be one of the following:\n     'MB9BFx64', 'MB9BFx65', 'MB9BFx66', 'MB9BFx67', 'MB9BFx68',\n     'S6E2Cx8', 'S6E2Cx9', 'S6E2CxA' or 'S6E2Dx', with 'x' treated as\n     wildcard and otherwise case (and any trailing characters) ignored.\n\n          flash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 \\\n                     $_TARGETNAME S6E2CCAJ0A\n          flash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 \\\n                     $_TARGETNAME S6E2CCAJ0A\n     _The current implementation is incomplete.  Protection is not\n     supported, nor is Chip Erase (only Sector Erase is implemented)._\n\n -- Flash Driver: kinetis\n     Kx, KLx, KVx and KE1x members of the Kinetis microcontroller family\n     from NXP (former Freescale) include internal flash and use ARM\n     Cortex-M0+ or M4 cores.  The driver automatically recognizes flash\n     size and a number of flash banks (1-4) using the chip\n     identification register, and autoconfigures itself.  Use kinetis_ke\n     driver for KE0x and KEAx devices.\n\n     The KINETIS driver defines option:\n        * -sim-base ADDR ...  base of System Integration Module where\n          chip identification resides.  Driver tries two known locations\n          if option is omitted.\n\n          flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\n\n      -- Config Command: kinetis create_banks\n          Configuration command enables automatic creation of additional\n          flash banks based on real flash layout of device.  Banks are\n          created during device probe.  Use 'flash probe 0' to force\n          probe.\n\n      -- Command: kinetis fcf_source [protection|write]\n          Select what source is used when writing to a Flash\n          Configuration Field.  'protection' mode builds FCF content\n          from protection bits previously set by 'flash protect'\n          command.  This mode is default.  MCU is protected from\n          unwanted locking by immediate writing FCF after erase of\n          relevant sector.  'write' mode enables direct write to FCF.\n          Protection cannot be set by 'flash protect' command.  FCF is\n          written along with the rest of a flash image.  _BEWARE:\n          Incorrect flash configuration may permanently lock the\n          device!_\n\n      -- Command: kinetis fopt [num]\n          Set value to write to FOPT byte of Flash Configuration Field.\n          Used in kinetis 'fcf_source protection' mode only.\n\n      -- Command: kinetis mdm check_security\n          Checks status of device security lock.  Used internally in\n          examine-end and examine-fail event.\n\n      -- Command: kinetis mdm halt\n          Issues a halt via the MDM-AP. This command can be used to\n          break a watchdog reset loop when connecting to an unsecured\n          target.\n\n      -- Command: kinetis mdm mass_erase\n          Issues a complete flash erase via the MDM-AP. This can be used\n          to erase a chip back to its factory state, removing security.\n          It does not require the processor to be halted, however the\n          target will remain in a halted state after this command\n          completes.\n\n      -- Command: kinetis nvm_partition\n          For FlexNVM devices only (KxxDX and KxxFX). Command shows or\n          sets data flash or EEPROM backup size in kilobytes, sets two\n          EEPROM blocks sizes in bytes and enables/disables loading of\n          EEPROM contents to FlexRAM during reset.\n\n          For details see device reference manual, Flash Memory Module,\n          Program Partition command.\n\n          Setting is possible only once after mass_erase.  Reset the\n          device after partition setting.\n\n          Show partition size:\n               kinetis nvm_partition info\n\n          Set 32 KB data flash, rest of FlexNVM is EEPROM backup.\n          EEPROM has two blocks of 512 and 1536 bytes and its contents\n          is loaded to FlexRAM during reset:\n               kinetis nvm_partition dataflash 32 512 1536 on\n\n          Set 16 KB EEPROM backup, rest of FlexNVM is a data flash.\n          EEPROM has two blocks of 1024 bytes and its contents is not\n          loaded to FlexRAM during reset:\n               kinetis nvm_partition eebkp 16 1024 1024 off\n\n      -- Command: kinetis mdm reset\n          Issues a reset via the MDM-AP. This causes the MCU to output a\n          low pulse on the RESET pin, which can be used to reset other\n          hardware on board.\n\n      -- Command: kinetis disable_wdog\n          For Kx devices only (KLx has different COP watchdog, it is not\n          supported).  Command disables watchdog timer.\n\n -- Flash Driver: kinetis_ke\n     KE0x and KEAx members of the Kinetis microcontroller family from\n     NXP include internal flash and use ARM Cortex-M0+.  The driver\n     automatically recognizes the KE0x sub-family using the chip\n     identification register, and autoconfigures itself.  Use kinetis\n     (not kinetis_ke) driver for KE1x devices.\n\n          flash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\n      -- Command: kinetis_ke mdm check_security\n          Checks status of device security lock.  Used internally in\n          examine-end event.\n\n      -- Command: kinetis_ke mdm mass_erase\n          Issues a complete Flash erase via the MDM-AP. This can be used\n          to erase a chip back to its factory state.  Command removes\n          security lock from a device (use of SRST highly recommended).\n          It does not require the processor to be halted.\n\n      -- Command: kinetis_ke disable_wdog\n          Command disables watchdog timer.\n\n -- Flash Driver: lpc2000\n     This is the driver to support internal flash of all members of the\n     LPC11(x)00 and LPC1300 microcontroller families and most members of\n     the LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000, LPC54100,\n     LPC8Nxx and NHS31xx microcontroller families from NXP.\n\n          Note: There are LPC2000 devices which are not supported by the\n          LPC2000 driver: The LPC2888 is supported by the LPC288X\n          driver.  The LPC29xx family is supported by the LPC2900\n          driver.\n\n     The LPC2000 driver defines two mandatory and two optional\n     parameters, which must appear in the following order:\n\n        * VARIANT ...  required, may be 'lpc2000_v1' (older LPC21xx and\n          LPC22xx) 'lpc2000_v2' (LPC213x, LPC214x, LPC210[123], LPC23xx\n          and LPC24xx) 'lpc1700' (LPC175x and LPC176x and LPC177x/8x)\n          'lpc4300' - available also as 'lpc1800' alias (LPC18x[2357]\n          and LPC43x[2357]) 'lpc800' (LPC8xx) 'lpc1100' (LPC11(x)xx and\n          LPC13xx) 'lpc1500' (LPC15xx) 'lpc54100' (LPC541xx) 'lpc4000'\n          (LPC40xx) or 'auto' - automatically detects flash variant and\n          size for LPC11(x)00, LPC8xx, LPC13xx, LPC17xx, LPC40xx,\n          LPC8Nxx and NHS31xx\n        * CLOCK_KHZ ...  the frequency, in kiloHertz, at which the core\n          is running\n        * 'calc_checksum' ...  optional (but you probably want to\n          provide this!), telling the driver to calculate a valid\n          checksum for the exception vector table.\n               Note: If you don't provide 'calc_checksum' when you're\n               writing the vector table, the boot ROM will almost\n               certainly ignore your flash image.  However, if you do\n               provide it, with most tool chains 'verify_image' will\n               fail.\n        * 'iap_entry' ...  optional telling the driver to use a\n          different ROM IAP entry point.\n\n     LPC flashes don't require the chip and bus width to be specified.\n\n          flash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \\\n                lpc2000_v2 14765 calc_checksum\n\n      -- Command: lpc2000 part_id bank\n          Displays the four byte part identifier associated with the\n          specified flash BANK.\n\n -- Flash Driver: lpc288x\n     The LPC2888 microcontroller from NXP needs slightly different flash\n     support from its lpc2000 siblings.  The LPC288X driver defines one\n     mandatory parameter, the programming clock rate in Hz.  LPC flashes\n     don't require the chip and bus width to be specified.\n\n          flash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000\n\n -- Flash Driver: lpc2900\n     This driver supports the LPC29xx ARM968E based microcontroller\n     family from NXP.\n\n     The predefined parameters BASE, SIZE, CHIP_WIDTH and BUS_WIDTH of\n     the 'flash bank' command are ignored.  Flash size and sector layout\n     are auto-configured by the driver.  The driver has one additional\n     mandatory parameter: The CPU clock rate (in kHz) at the time the\n     flash operations will take place.  Most of the time this will not\n     be the crystal frequency, but a higher PLL frequency.  The\n     'reset-init' event handler in the board script is usually the place\n     where you start the PLL.\n\n     The driver rejects flashless devices (currently the LPC2930).\n\n     The EEPROM in LPC2900 devices is not mapped directly into the\n     address space.  It must be handled much more like NAND flash\n     memory, and will therefore be handled by a separate\n     'lpc2900_eeprom' driver (not yet available).\n\n     Sector protection in terms of the LPC2900 is handled transparently.\n     Every time a sector needs to be erased or programmed, it is\n     automatically unprotected.  What is shown as protection status in\n     the 'flash info' command, is actually the LPC2900 _sector\n     security_.  This is a mechanism to prevent a sector from ever being\n     erased or programmed again.  As this is an irreversible mechanism,\n     it is handled by a special command ('lpc2900 secure_sector'), and\n     not by the standard 'flash protect' command.\n\n     Example for a 125 MHz clock frequency:\n          flash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000\n\n     Some 'lpc2900'-specific commands are defined.  In the following\n     command list, the BANK parameter is the bank number as obtained by\n     the 'flash banks' command.\n\n      -- Command: lpc2900 signature bank\n          Calculates a 128-bit hash value, the _signature_, from the\n          whole flash content.  This is a hardware feature of the flash\n          block, hence the calculation is very fast.  You may use this\n          to verify the content of a programmed device against a known\n          signature.  Example:\n               lpc2900 signature 0\n                 signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317\n\n      -- Command: lpc2900 read_custom bank filename\n          Reads the 912 bytes of customer information from the flash\n          index sector, and saves it to a file in binary format.\n          Example:\n               lpc2900 read_custom 0 /path_to/customer_info.bin\n\n     The index sector of the flash is a _write-only_ sector.  It cannot\n     be erased!  In order to guard against unintentional write access,\n     all following commands need to be preceded by a successful call to\n     the 'password' command:\n\n      -- Command: lpc2900 password bank password\n          You need to use this command right before each of the\n          following commands: 'lpc2900 write_custom', 'lpc2900\n          secure_sector', 'lpc2900 secure_jtag'.\n\n          The password string is fixed to \"I_know_what_I_am_doing\".\n          Example:\n               lpc2900 password 0 I_know_what_I_am_doing\n                 Potentially dangerous operation allowed in next command!\n\n      -- Command: lpc2900 write_custom bank filename type\n          Writes the content of the file into the customer info space of\n          the flash index sector.  The filetype can be specified with\n          the TYPE field.  Possible values for TYPE are: BIN (binary),\n          IHEX (Intel hex format), ELF (ELF binary) or S19 (Motorola\n          S-records).  The file must contain a single section, and the\n          contained data length must be exactly 912 bytes.\n               Attention: This cannot be reverted!  Be careful!\n          Example:\n               lpc2900 write_custom 0 /path_to/customer_info.bin bin\n\n      -- Command: lpc2900 secure_sector bank first last\n          Secures the sector range from FIRST to LAST (including)\n          against further program and erase operations.  The sector\n          security will be effective after the next power cycle.\n               Attention: This cannot be reverted!  Be careful!\n          Secured sectors appear as _protected_ in the 'flash info'\n          command.  Example:\n               lpc2900 secure_sector 0 1 1\n               flash info 0\n                 #0 : lpc2900 at 0x20000000, size 0x000c0000, (...)\n                         #  0: 0x00000000 (0x2000 8kB) not protected\n                         #  1: 0x00002000 (0x2000 8kB) protected\n                         #  2: 0x00004000 (0x2000 8kB) not protected\n\n      -- Command: lpc2900 secure_jtag bank\n          Irreversibly disable the JTAG port.  The new JTAG security\n          setting will be effective after the next power cycle.\n               Attention: This cannot be reverted!  Be careful!\n          Examples:\n               lpc2900 secure_jtag 0\n\n -- Flash Driver: mdr\n     This drivers handles the integrated NOR flash on Milandr Cortex-M\n     based controllers.  A known limitation is that the Info memory\n     can't be read or verified as it's not memory mapped.\n\n          flash bank <name> mdr <base> <size> \\\n                0 0 <target#> TYPE PAGE_COUNT SEC_COUNT\n\n        * TYPE - 0 for main memory, 1 for info memory\n        * PAGE_COUNT - total number of pages\n        * SEC_COUNT - number of sector per page count\n\n     Example usage:\n          if { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n             flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 \\\n                   0 0 $_TARGETNAME 1 1 4\n          } else {\n             flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 \\\n                   0 0 $_TARGETNAME 0 32 4\n          }\n\n -- Flash Driver: msp432\n     All versions of the SimpleLink MSP432 microcontrollers from Texas\n     Instruments include internal flash.  The msp432 flash driver\n     automatically recognizes the specific version's flash parameters\n     and autoconfigures itself.  Main program flash starts at address 0.\n     The information flash region on MSP432P4 versions starts at address\n     0x200000.\n\n          flash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\n      -- Command: msp432 mass_erase bank_id [main|all]\n          Performs a complete erase of flash.  By default, 'mass_erase'\n          will erase only the main program flash.\n\n          On MSP432P4 versions, using 'mass_erase all' will erase both\n          the main program and information flash regions.  To also erase\n          the BSL in information flash, the user must first use the\n          'bsl' command.\n\n      -- Command: msp432 bsl bank_id [unlock|lock]\n          On MSP432P4 versions, 'bsl' unlocks and locks the bootstrap\n          loader (BSL) region in information flash so that flash\n          commands can erase or write the BSL. Leave the BSL locked to\n          prevent accidentally corrupting the bootstrap loader.\n\n          To erase and program the BSL:\n               msp432 bsl unlock\n               flash erase_address 0x202000 0x2000\n               flash write_image bsl.bin 0x202000\n               msp432 bsl lock\n\n -- Flash Driver: niietcm4\n     This drivers handles the integrated NOR flash on NIIET Cortex-M4\n     based controllers.  Flash size and sector layout are\n     auto-configured by the driver.  Main flash memory is called\n     \"Bootflash\" and has main region and info region.  Info region is\n     NOT memory mapped by default, but it can replace first part of main\n     region if needed.  Full erase, single and block writes are\n     supported for both main and info regions.  There is additional not\n     memory mapped flash called \"Userflash\", which also have division\n     into regions: main and info.  Purpose of userflash - to store\n     system and user settings.  Driver has special commands to perform\n     operations with this memory.\n\n          flash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME\n\n     Some niietcm4-specific commands are defined:\n\n      -- Command: niietcm4 uflash_read_byte bank ('main'|'info') address\n          Read byte from main or info userflash region.\n\n      -- Command: niietcm4 uflash_write_byte bank ('main'|'info')\n               address value\n          Write byte to main or info userflash region.\n\n      -- Command: niietcm4 uflash_full_erase bank\n          Erase all userflash including info region.\n\n      -- Command: niietcm4 uflash_erase bank ('main'|'info')\n               first_sector last_sector\n          Erase sectors of main or info userflash region, starting at\n          sector first up to and including last.\n\n      -- Command: niietcm4 uflash_protect_check bank ('main'|'info')\n          Check sectors protect.\n\n      -- Command: niietcm4 uflash_protect bank ('main'|'info')\n               first_sector last_sector ('on'|'off')\n          Protect sectors of main or info userflash region, starting at\n          sector first up to and including last.\n\n      -- Command: niietcm4 bflash_info_remap bank ('on'|'off')\n          Enable remapping bootflash info region to 0x00000000 (or\n          0x40000000 if external memory boot used).\n\n      -- Command: niietcm4 extmem_cfg bank\n               ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh')\n               pin_num ('func1'|'func3')\n          Configure external memory interface for boot.\n\n      -- Command: niietcm4 service_mode_erase bank\n          Perform emergency erase of all flash (bootflash and\n          userflash).\n\n      -- Command: niietcm4 driver_info bank\n          Show information about flash driver.\n\n -- Flash Driver: npcx\n     All versions of the NPCX microcontroller families from Nuvoton\n     include internal flash.  The NPCX flash driver supports the NPCX\n     family of devices.  The driver automatically recognizes the\n     specific version's flash parameters and autoconfigures itself.  The\n     flash bank starts at address 0x64000000.\n\n          flash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n\n -- Flash Driver: nrf5\n     All members of the nRF51 microcontroller families from Nordic\n     Semiconductor include internal flash and use ARM Cortex-M0 core.\n     nRF52 family powered by ARM Cortex-M4 or M4F core is supported too.\n     nRF52832 is fully supported including BPROT flash protection\n     scheme.  nRF52833 and nRF52840 devices are supported with the\n     exception of security extensions (flash access control list - ACL).\n\n          flash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME\n\n     Some nrf5-specific commands are defined:\n\n      -- Command: nrf5 mass_erase\n          Erases the contents of the code memory and user information\n          configuration registers as well.  It must be noted that this\n          command works only for chips that do not have factory\n          pre-programmed region 0 code.\n\n      -- Command: nrf5 info\n          Decodes and shows information from FICR and UICR registers.\n\n -- Flash Driver: ocl\n     This driver is an implementation of the \"on chip flash loader\"\n     protocol proposed by Pavel Chromy.\n\n     It is a minimalistic command-response protocol intended to be used\n     over a DCC when communicating with an internal or external flash\n     loader running from RAM. An example implementation for AT91SAM7x is\n     available in 'contrib/loaders/flash/at91sam7x/'.\n\n          flash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME\n\n -- Flash Driver: pic32mx\n     The PIC32MX microcontrollers are based on the MIPS 4K cores, and\n     integrate flash memory.\n\n          flash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME\n          flash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME\n\n     Some pic32mx-specific commands are defined:\n      -- Command: pic32mx pgm_word address value bank\n          Programs the specified 32-bit VALUE at the given ADDRESS in\n          the specified chip BANK.\n      -- Command: pic32mx unlock bank\n          Unlock and erase specified chip BANK.  This will remove any\n          Code Protection.\n\n -- Flash Driver: psoc4\n     All members of the PSoC 41xx/42xx microcontroller family from\n     Cypress include internal flash and use ARM Cortex-M0 cores.  The\n     driver automatically recognizes a number of these chips using the\n     chip identification register, and autoconfigures itself.\n\n     Note: Erased internal flash reads as 00.  System ROM of PSoC 4 does\n     not implement erase of a flash sector.\n\n          flash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\n     psoc4-specific commands\n      -- Command: psoc4 flash_autoerase num (on|off)\n          Enables or disables autoerase mode for a flash bank.\n\n          If flash_autoerase is off, use mass_erase before flash\n          programming.  Flash erase command fails if region to erase is\n          not whole flash memory.\n\n          If flash_autoerase is on, a sector is both erased and\n          programmed in one system ROM call.  Flash erase command is\n          ignored.  This mode is suitable for gdb load.\n\n          The NUM parameter is a value shown by 'flash banks'.\n\n      -- Command: psoc4 mass_erase num\n          Erases the contents of the flash memory, protection and\n          security lock.\n\n          The NUM parameter is a value shown by 'flash banks'.\n\n -- Flash Driver: psoc5lp\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal program flash and use ARM Cortex-M3 cores.  The\n     driver probes for a number of these chips and autoconfigures\n     itself, apart from the base address.\n\n          flash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\n\n     Note: PSoC 5LP chips can be configured to have ECC enabled or\n     disabled.\n          Attention: If flash operations are performed in ECC-disabled\n          mode, they will also affect the ECC flash region.  Erasing a\n          16k flash sector in the 0x00000000 area will then also erase\n          the corresponding 2k data bytes in the 0x48000000 area.\n          Writing to the ECC data bytes in ECC-disabled mode is not\n          implemented.\n\n     Commands defined in the PSOC5LP driver:\n\n      -- Command: psoc5lp mass_erase\n          Erases all flash data and ECC/configuration bytes, all flash\n          protection rows, and all row latches in all flash arrays on\n          the device.\n\n -- Flash Driver: psoc5lp_eeprom\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal EEPROM and use ARM Cortex-M3 cores.  The driver\n     probes for a number of these chips and autoconfigures itself, apart\n     from the base address.\n\n          flash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 \\\n                     $_TARGETNAME\n\n -- Flash Driver: psoc5lp_nvl\n     All members of the PSoC 5LP microcontroller family from Cypress\n     include internal Nonvolatile Latches and use ARM Cortex-M3 cores.\n     The driver probes for a number of these chips and autoconfigures\n     itself.\n\n          flash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\n     PSoC 5LP chips have multiple NV Latches:\n\n        * Device Configuration NV Latch - 4 bytes\n        * Write Once (WO) NV Latch - 4 bytes\n\n     Note: This driver only implements the Device Configuration NVL.\n\n     The PSOC5LP driver reads the ECC mode from Device Configuration\n     NVL.\n          Attention: Switching ECC mode via write to Device\n          Configuration NVL will require a reset after successful write.\n\n -- Flash Driver: psoc6\n     Supports PSoC6 (CY8C6xxx) family of Cypress microcontrollers.\n     PSoC6 is a dual-core device with CM0+ and CM4 cores.  Both cores\n     share the same Flash/RAM/MMIO address space.\n\n     Flash in PSoC6 is split into three regions:\n        * Main Flash - this is the main storage for user application.\n          Total size varies among devices, sector size: 256 kBytes, row\n          size: 512 bytes.  Supports erase operation on individual rows.\n        * Work Flash - intended to be used as storage for user data\n          (e.g.  EEPROM emulation).  Total size: 32 KBytes, sector size:\n          32 KBytes, row size: 512 bytes.\n        * Supervisory Flash - special region which contains\n          device-specific service data.  This region does not support\n          erase operation.  Only few rows can be programmed by the user,\n          most of the rows are read only.  Programming operation will\n          erase row automatically.\n\n     All three flash regions are supported by the driver.  Flash\n     geometry is detected automatically by parsing data in\n     SPCIF_GEOMETRY register.\n\n     PSoC6 is equipped with NOR Flash so erased Flash reads as 0x00.\n\n          flash bank main_flash_cm0 psoc6 0x10000000 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank work_flash_cm0 psoc6 0x14000000 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_user_cm0 psoc6 0x16000800 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_nar_cm0 psoc6 0x16001A00 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_key_cm0 psoc6 0x16005A00 0 0 0 \\\n                     ${TARGET}.cm0\n          flash bank super_flash_toc2_cm0 psoc6 0x16007C00 0 0 0 \\\n                     ${TARGET}.cm0\n\n          flash bank main_flash_cm4 psoc6 0x10000000 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank work_flash_cm4 psoc6 0x14000000 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_user_cm4 psoc6 0x16000800 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_nar_cm4 psoc6 0x16001A00 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_key_cm4 psoc6 0x16005A00 0 0 0 \\\n                     ${TARGET}.cm4\n          flash bank super_flash_toc2_cm4 psoc6 0x16007C00 0 0 0 \\\n                     ${TARGET}.cm4\n\n     psoc6-specific commands\n      -- Command: psoc6 reset_halt\n          Command can be used to simulate broken Vector Catch from\n          gdbinit or tcl scripts.  When invoked for CM0+ target, it will\n          set break point at application entry point and issue\n          SYSRESETREQ. This will reset both cores and all peripherals.\n          CM0+ will reset CM4 during boot anyway so this is safe.  On\n          CM4 target, VECTRESET is used instead of SYSRESETREQ to avoid\n          unwanted reset of CM0+;\n\n      -- Command: psoc6 mass_erase num\n          Erases the contents given flash bank.  The NUM parameter is a\n          value shown by 'flash banks'.  Note: only Main and Work flash\n          regions support Erase operation.\n\n -- Flash Driver: rp2040\n     Supports RP2040 \"Raspberry Pi Pico\" microcontroller.  RP2040 is a\n     dual-core device with two CM0+ cores.  Both cores share the same\n     Flash/RAM/MMIO address space.  Non-volatile storage is achieved\n     with an external QSPI flash; a Boot ROM provides helper functions.\n\n          flash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n\n -- Flash Driver: sim3x\n     All members of the SiM3 microcontroller family from Silicon\n     Laboratories include internal flash and use ARM Cortex-M3 cores.\n     It supports both JTAG and SWD interface.  The SIM3X driver tries to\n     probe the device to auto detect the MCU. If this fails, it will use\n     the SIZE parameter as the size of flash bank.\n\n          flash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\n     There are 2 commands defined in the SIM3X driver:\n\n      -- Command: sim3x mass_erase\n          Erases the complete flash.  This is used to unlock the flash.\n          And this command is only possible when using the SWD\n          interface.\n\n      -- Command: sim3x lock\n          Lock the flash.  To unlock use the 'sim3x mass_erase' command.\n\n -- Flash Driver: stellaris\n     All members of the Stellaris LM3Sxxx, LM4x and Tiva C\n     microcontroller families from Texas Instruments include internal\n     flash.  The driver automatically recognizes a number of these chips\n     using the chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME\n\n      -- Command: stellaris recover\n          Performs the _Recovering a \"Locked\" Device_ procedure to\n          restore the flash and its associated nonvolatile registers to\n          their factory default values (erased).  This is the only way\n          to remove flash protection or re-enable debugging if that\n          capability has been disabled.\n\n          Note that the final \"power cycle the chip\" step in this\n          procedure must be performed by hand, since OpenOCD can't do\n          it.\n               Warning: if more than one Stellaris chip is connected,\n               the procedure is applied to all of them.\n\n -- Flash Driver: stm32f1x\n     All members of the STM32F0, STM32F1 and STM32F3 microcontroller\n     families from STMicroelectronics and all members of the GD32F1x0,\n     GD32F3x0 and GD32E23x microcontroller families from GigaDevice\n     include internal flash and use ARM Cortex-M0/M3/M4/M23 cores.  The\n     driver also works with GD32VF103 powered by RISC-V core.  The\n     driver automatically recognizes a number of these chips using the\n     chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME\n\n     If you have a target with dual flash banks then define the second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n\n     Some stm32f1x-specific commands are defined:\n\n      -- Command: stm32f1x lock num\n          Locks the entire stm32 device against reading.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n      -- Command: stm32f1x unlock num\n          Unlocks the entire stm32 device for reading.  This command\n          will cause a mass erase of the entire stm32 device if\n          previously locked.  The NUM parameter is a value shown by\n          'flash banks'.\n\n      -- Command: stm32f1x mass_erase num\n          Mass erases the entire stm32 device.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n      -- Command: stm32f1x options_read num\n          Reads and displays active stm32 option bytes loaded during POR\n          or upon executing the 'stm32f1x options_load' command.  The\n          NUM parameter is a value shown by 'flash banks'.\n\n      -- Command: stm32f1x options_write num (SWWDG|HWWDG)\n               (RSTSTNDBY|NORSTSTNDBY) (RSTSTOP|NORSTSTOP) (USEROPT\n               user_data)\n          Writes the stm32 option byte with the specified values.  The\n          NUM parameter is a value shown by 'flash banks'.  The\n          USER_DATA parameter is content of higher 16 bits of the option\n          byte register (Data0 and Data1 as one 16bit number).\n\n      -- Command: stm32f1x options_load num\n          Generates a special kind of reset to re-load the stm32 option\n          bytes written by the 'stm32f1x options_write' or 'flash\n          protect' commands without having to power cycle the target.\n          Not applicable to stm32f1x devices.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n -- Flash Driver: stm32f2x\n     All members of the STM32F2, STM32F4 and STM32F7 microcontroller\n     families from STMicroelectronics include internal flash and use ARM\n     Cortex-M3/M4/M7 cores.  The driver automatically recognizes a\n     number of these chips using the chip identification register, and\n     autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\n     If you use OTP (One-Time Programmable) memory define it as a second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32f2x 0x1FFF7800 0 0 0 $_TARGETNAME\n\n      -- Command: stm32f2x otp num (enable|disable|show)\n          Enables or disables OTP write commands for bank NUM.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME\n\n     Some stm32f2x-specific commands are defined:\n\n      -- Command: stm32f2x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x mass_erase num\n          Mass erases the entire stm32f2x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32f2x options_read num\n          Reads and displays user options and (where implemented)\n          boot_addr0, boot_addr1, optcr2.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32f2x options_write num user_options boot_addr0\n               boot_addr1\n          Writes user options and (where implemented) boot_addr0 and\n          boot_addr1 in raw format.  Warning: The meaning of the various\n          bits depends on the device, always check datasheet!  The NUM\n          parameter is a value shown by 'flash banks', USER_OPTIONS a 12\n          bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR,\n          BOOT_ADDR0 and BOOT_ADDR1 two halfwords (of FLASH_OPTCR1).\n\n      -- Command: stm32f2x optcr2_write num optcr2\n          Writes FLASH_OPTCR2 options.  Warning: Clearing PCROPi bits\n          requires a full mass erase!  The NUM parameter is a value\n          shown by 'flash banks', OPTCR2 a 32-bit word.\n\n -- Flash Driver: stm32h7x\n     All members of the STM32H7 microcontroller families from\n     STMicroelectronics include internal flash and use ARM Cortex-M7\n     core.  The driver automatically recognizes a number of these chips\n     using the chip identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32h7x 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n\n          flash bank $_FLASHNAME stm32h7x 0 0x20000 0 0 $_TARGETNAME\n\n     Some stm32h7x-specific commands are defined:\n\n      -- Command: stm32h7x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32h7x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32h7x mass_erase num\n          Mass erases the entire stm32h7x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32h7x option_read num reg_offset\n          Reads an option byte register from the stm32h7x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the option byte to read from the used\n          bank registers' base.  For example: in STM32H74x/H75x the bank\n          1 registers' base is 0x52002000 and 0x52002100 for bank 2.\n\n          Example usage:\n               # read OPTSR_CUR\n               stm32h7x option_read 0 0x1c\n               # read WPSN_CUR1R\n               stm32h7x option_read 0 0x38\n               # read WPSN_CUR2R\n               stm32h7x option_read 1 0x38\n\n      -- Command: stm32h7x option_write num reg_offset value [reg_mask]\n          Writes an option byte register of the stm32h7x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the option byte to write from the used\n          bank register base, and REG_MASK is the mask to apply when\n          writing the register (only bits with a '1' will be touched).\n\n          Example usage:\n               # swap bank 1 and bank 2 in dual bank devices\n               # by setting SWAP_BANK_OPT bit in OPTSR_PRG\n               stm32h7x option_write 0 0x20 0x8000000 0x8000000\n\n -- Flash Driver: stm32lx\n     All members of the STM32L0 and STM32L1 microcontroller families\n     from STMicroelectronics include internal flash and use ARM\n     Cortex-M3 and Cortex-M0+ cores.  The driver automatically\n     recognizes a number of these chips using the chip identification\n     register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.  If you\n     use 0 as the bank base address, it tells the driver to autodetect\n     the bank location assuming you're configuring the second bank.\n\n          flash bank $_FLASHNAME stm32lx 0x08000000 0x20000 0 0 $_TARGETNAME\n\n     Some stm32lx-specific commands are defined:\n\n      -- Command: stm32lx lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32lx unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32lx mass_erase num\n          Mass erases the entire stm32lx device (all flash banks and\n          EEPROM data).  This is the only way to unlock a protected\n          flash (unless RDP Level is 2 which can't be unlocked at all).\n          The NUM parameter is a value shown by 'flash banks'.\n\n -- Flash Driver: stm32l4x\n     All members of the STM32 G0, G4, L4, L4+, L5, U5, WB and WL\n     microcontroller families from STMicroelectronics include internal\n     flash and use ARM Cortex-M0+, M4 and M33 cores.  The driver\n     automatically recognizes a number of these chips using the chip\n     identification register, and autoconfigures itself.\n\n          flash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME\n\n     If you use OTP (One-Time Programmable) memory define it as a second\n     bank as per the following example.\n          flash bank $_FLASHNAME stm32l4x 0x1FFF7000 0 0 0 $_TARGETNAME\n\n      -- Command: stm32l4x otp num (enable|disable|show)\n          Enables or disables OTP write commands for bank NUM.  The NUM\n          parameter is a value shown by 'flash banks'.\n\n     Note that some devices have been found that have a flash size\n     register that contains an invalid value, to workaround this issue\n     you can override the probed value used by the flash driver.\n     However, specifying a wrong value might lead to a completely wrong\n     flash layout, so this feature must be used carefully.\n\n          flash bank $_FLASHNAME stm32l4x 0x08000000 0x40000 0 0 $_TARGETNAME\n\n     Some stm32l4x-specific commands are defined:\n\n      -- Command: stm32l4x lock num\n          Locks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n          _Note:_ To apply the protection change immediately, use\n          'stm32l4x option_load'.\n\n      -- Command: stm32l4x unlock num\n          Unlocks the entire stm32 device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n          _Note:_ To apply the protection change immediately, use\n          'stm32l4x option_load'.\n\n      -- Command: stm32l4x mass_erase num\n          Mass erases the entire stm32l4x device.  The NUM parameter is\n          a value shown by 'flash banks'.\n\n      -- Command: stm32l4x option_read num reg_offset\n          Reads an option byte register from the stm32l4x device.  The\n          NUM parameter is a value shown by 'flash banks', REG_OFFSET is\n          the register offset of the Option byte to read.\n\n          For example to read the FLASH_OPTR register:\n               stm32l4x option_read 0 0x20\n               # Option Register (for STM32L4x): <0x40022020> = 0xffeff8aa\n               # Option Register (for STM32WBx): <0x58004020> = ...\n               # The correct flash base address will be used automatically\n\n          The above example will read out the FLASH_OPTR register which\n          contains the RDP option byte, Watchdog configuration, BOR\n          level etc.\n\n      -- Command: stm32l4x option_write num reg_offset reg_mask\n          Write an option byte register of the stm32l4x device.  The NUM\n          parameter is a value shown by 'flash banks', REG_OFFSET is the\n          register offset of the Option byte to write, and REG_MASK is\n          the mask to apply when writing the register (only bits with a\n          '1' will be touched).\n\n          _Note:_ To apply the option bytes change immediately, use\n          'stm32l4x option_load'.\n\n          For example to write the WRP1AR option bytes:\n               stm32l4x option_write 0 0x28 0x00FF0000 0x00FF00FF\n\n          The above example will write the WRP1AR option register\n          configuring the Write protection Area A for bank 1.  The above\n          example set WRP1AR_END=255, WRP1AR_START=0.  This will\n          effectively write protect all sectors in flash bank 1.\n\n      -- Command: stm32l4x wrp_info num [device_bank]\n          List the protected areas using WRP. The NUM parameter is a\n          value shown by 'flash banks'.  DEVICE_BANK parameter is\n          optional, possible values 'bank1' or 'bank2', if not\n          specified, the command will display the whole flash protected\n          areas.\n\n          Note: DEVICE_BANK is different from banks created using 'flash\n          bank'.  Devices supported in this flash driver, can have main\n          flash memory organized in single or dual-banks mode.  Thus the\n          usage of DEVICE_BANK is meaningful only in dual-bank mode, to\n          get write protected areas in a specific DEVICE_BANK\n\n      -- Command: stm32l4x option_load num\n          Forces a re-load of the option byte registers.  Will cause a\n          system reset of the device.  The NUM parameter is a value\n          shown by 'flash banks'.\n\n      -- Command: stm32l4x trustzone num [enable | disable]\n          Enables or disables Global TrustZone Security, using the TZEN\n          option bit.  If neither 'enabled' nor 'disable' are specified,\n          the command will display the TrustZone status.  _Note:_ This\n          command works only with devices with TrustZone, eg.  STM32L5.\n          _Note:_ This command will perform an OBL_Launch after\n          modifying the TZEN.\n\n -- Flash Driver: str7x\n     All members of the STR7 microcontroller family from\n     STMicroelectronics include internal flash and use ARM7TDMI cores.\n     The STR7X driver defines one mandatory parameter, VARIANT, which is\n     either 'STR71x', 'STR73x' or 'STR75x'.\n\n          flash bank $_FLASHNAME str7x \\\n                0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\n\n      -- Command: str7x disable_jtag bank\n          Activate the Debug/Readout protection mechanism for the\n          specified flash bank.\n\n -- Flash Driver: str9x\n     Most members of the STR9 microcontroller family from\n     STMicroelectronics include internal flash and use ARM966E cores.\n     The str9 needs the flash controller to be configured using the\n     'str9x flash_config' command prior to Flash programming.\n\n          flash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME\n          str9x flash_config 0 4 2 0 0x80000\n\n      -- Command: str9x flash_config num bbsr nbbsr bbadr nbbadr\n          Configures the str9 flash controller.  The NUM parameter is a\n          value shown by 'flash banks'.\n\n             * BBSR - Boot Bank Size register\n             * NBBSR - Non Boot Bank Size register\n             * BBADR - Boot Bank Start Address register\n             * NBBADR - Boot Bank Start Address register\n\n -- Flash Driver: str9xpec\n\n     Only use this driver for locking/unlocking the device or\n     configuring the option bytes.  Use the standard str9 driver for\n     programming.  Before using the flash commands the turbo mode must\n     be enabled using the 'str9xpec enable_turbo' command.\n\n     Here is some background info to help you better understand how this\n     driver works.  OpenOCD has two flash drivers for the str9:\n       1. Standard driver 'str9x' programmed via the str9 core.\n          Normally used for flash programming as it is faster than the\n          'str9xpec' driver.\n       2. Direct programming 'str9xpec' using the flash controller.\n          This is an ISC compliant (IEEE 1532) tap connected in series\n          with the str9 core.  The str9 core does not need to be running\n          to program using this flash driver.  Typical use for this\n          driver is locking/unlocking the target and programming the\n          option bytes.\n\n     Before we run any commands using the 'str9xpec' driver we must\n     first disable the str9 core.  This example assumes the 'str9xpec'\n     driver has been configured for flash bank 0.\n          # assert srst, we do not want core running\n          # while accessing str9xpec flash driver\n          adapter assert srst\n          # turn off target polling\n          poll off\n          # disable str9 core\n          str9xpec enable_turbo 0\n          # read option bytes\n          str9xpec options_read 0\n          # re-enable str9 core\n          str9xpec disable_turbo 0\n          poll on\n          reset halt\n     The above example will read the str9 option bytes.  When performing\n     a unlock remember that you will not be able to halt the str9 - it\n     has been locked.  Halting the core is not required for the\n     'str9xpec' driver as mentioned above, just issue the commands above\n     manually or from a telnet prompt.\n\n     Several str9xpec-specific commands are defined:\n\n      -- Command: str9xpec disable_turbo num\n          Restore the str9 into JTAG chain.\n\n      -- Command: str9xpec enable_turbo num\n          Enable turbo mode, will simply remove the str9 from the chain\n          and talk directly to the embedded flash controller.\n\n      -- Command: str9xpec lock num\n          Lock str9 device.  The str9 will only respond to an unlock\n          command that will erase the device.\n\n      -- Command: str9xpec part_id num\n          Prints the part identifier for bank NUM.\n\n      -- Command: str9xpec options_cmap num (bank0|bank1)\n          Configure str9 boot bank.\n\n      -- Command: str9xpec options_lvdsel num (vdd|vdd_vddq)\n          Configure str9 lvd source.\n\n      -- Command: str9xpec options_lvdthd num (2.4v|2.7v)\n          Configure str9 lvd threshold.\n\n      -- Command: str9xpec options_lvdwarn bank (vdd|vdd_vddq)\n          Configure str9 lvd reset warning source.\n\n      -- Command: str9xpec options_read num\n          Read str9 option bytes.\n\n      -- Command: str9xpec options_write num\n          Write str9 option bytes.\n\n      -- Command: str9xpec unlock num\n          unlock str9 device.\n\n -- Flash Driver: swm050\n     All members of the swm050 microcontroller family from Foshan Synwit\n     Tech.\n\n          flash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\n     One swm050-specific command is defined:\n\n      -- Command: swm050 mass_erase bank_id\n          Erases the entire flash bank.\n\n -- Flash Driver: tms470\n     Most members of the TMS470 microcontroller family from Texas\n     Instruments include internal flash and use ARM7TDMI cores.  This\n     driver doesn't require the chip and bus width to be specified.\n\n     Some tms470-specific commands are defined:\n\n      -- Command: tms470 flash_keyset key0 key1 key2 key3\n          Saves programming keys in a register, to enable flash erase\n          and write commands.\n\n      -- Command: tms470 osc_megahertz clock_mhz\n          Reports the clock speed, which is used to calculate timings.\n\n      -- Command: tms470 plldis (0|1)\n          Disables (1) or enables (0) use of the PLL to speed up the\n          flash clock.\n\n -- Flash Driver: w600\n     W60x series Wi-Fi SoC from WinnerMicro are designed with ARM\n     Cortex-M3 and have 1M Byte QFLASH inside.  The W600 driver uses the\n     TARGET parameter to select the correct bank config.\n\n          flash bank $_FLASHNAME w600 0x08000000 0 0 0 $_TARGETNAMEs\n\n -- Flash Driver: xmc1xxx\n     All members of the XMC1xxx microcontroller family from Infineon.\n     This driver does not require the chip and bus width to be\n     specified.\n\n -- Flash Driver: xmc4xxx\n     All members of the XMC4xxx microcontroller family from Infineon.\n     This driver does not require the chip and bus width to be\n     specified.\n\n     Some xmc4xxx-specific commands are defined:\n\n      -- Command: xmc4xxx flash_password bank_id passwd1 passwd2\n          Saves flash protection passwords which are used to lock the\n          user flash\n\n      -- Command: xmc4xxx flash_unprotect bank_id user_level[0-1]\n          Removes Flash write protection from the selected user bank\n\n12.6 NAND Flash Commands\n========================\n\nCompared to NOR or SPI flash, NAND devices are inexpensive and high\ndensity.  Today's NAND chips, and multi-chip modules, commonly hold\nmultiple GigaBytes of data.\n\nNAND chips consist of a number of \"erase blocks\" of a given size (such\nas 128 KBytes), each of which is divided into a number of pages (of\nperhaps 512 or 2048 bytes each).  Each page of a NAND flash has an \"out\nof band\" (OOB) area to hold Error Correcting Code (ECC) and other\nmetadata, usually 16 bytes of OOB for every 512 bytes of page data.\n\nOne key characteristic of NAND flash is that its error rate is higher\nthan that of NOR flash.  In normal operation, that ECC is used to\ncorrect and detect errors.  However, NAND blocks can also wear out and\nbecome unusable; those blocks are then marked \"bad\".  NAND chips are\neven shipped from the manufacturer with a few bad blocks.  The highest\ndensity chips use a technology (MLC) that wears out more quickly, so ECC\nsupport is increasingly important as a way to detect blocks that have\nbegun to fail, and help to preserve data integrity with techniques such\nas wear leveling.\n\nSoftware is used to manage the ECC. Some controllers don't support ECC\ndirectly; in those cases, software ECC is used.  Other controllers speed\nup the ECC calculations with hardware.  Single-bit error correction\nhardware is routine.  Controllers geared for newer MLC chips may correct\n4 or more errors for every 512 bytes of data.\n\nYou will need to make sure that any data you write using OpenOCD\nincludes the appropriate kind of ECC. For example, that may mean passing\nthe 'oob_softecc' flag when writing NAND data, or ensuring that the\ncorrect hardware ECC mode is used.\n\nThe basic steps for using NAND devices include:\n  1. Declare via the command 'nand device'\n     Do this in a board-specific configuration file, passing parameters\n     as needed by the controller.\n  2. Configure each device using 'nand probe'.\n     Do this only after the associated target is set up, such as in its\n     reset-init script or in procures defined to access that device.\n  3. Operate on the flash via 'nand subcommand'\n     Often commands to manipulate the flash are typed by a human, or run\n     via a script in some automated way.  Common task include writing a\n     boot loader, operating system, or other data needed to initialize\n     or de-brick a board.\n\nNOTE: At the time this text was written, the largest NAND flash fully\nsupported by OpenOCD is 2 GiBytes (16 GiBits).  This is because the\nvariables used to hold offsets and lengths are only 32 bits wide.\n(Larger chips may work in some cases, unless an offset or length is\nlarger than 0xffffffff, the largest 32-bit unsigned integer.)  Some\nlarger devices will work, since they are actually multi-chip modules\nwith two smaller chips and individual chipselect lines.\n\n12.6.1 NAND Configuration Commands\n----------------------------------\n\nNAND chips must be declared in configuration scripts, plus some\nadditional configuration that's done after OpenOCD has initialized.\n\n -- Config Command: nand device name driver target [configparams...]\n     Declares a NAND device, which can be read and written to after it\n     has been configured through 'nand probe'.  In OpenOCD, devices are\n     single chips; this is unlike some operating systems, which may\n     manage multiple chips as if they were a single (larger) device.  In\n     some cases, configuring a device will activate extra commands; see\n     the controller-specific documentation.\n\n     NOTE: This command is not available after OpenOCD initialization\n     has completed.  Use it in board specific configuration files, not\n     interactively.\n\n        * NAME ...  may be used to reference the NAND bank in most other\n          NAND commands.  A number is also available.\n        * DRIVER ...  identifies the NAND controller driver associated\n          with the NAND device being declared.  *Note NAND Driver List:\n          nanddriverlist.\n        * TARGET ...  names the target used when issuing commands to the\n          NAND controller.\n        * CONFIGPARAMS ...  controllers may support, or require,\n          additional parameters.  See the controller-specific\n          documentation for more information.\n\n -- Command: nand list\n     Prints a summary of each device declared using 'nand device',\n     numbered from zero.  Note that un-probed devices show no details.\n          > nand list\n          #0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n                  blocksize: 131072, blocks: 8192\n          #1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n                  blocksize: 131072, blocks: 8192\n          >\n\n -- Command: nand probe num\n     Probes the specified device to determine key characteristics like\n     its page and block sizes, and how many blocks it has.  The NUM\n     parameter is the value shown by 'nand list'.  You must\n     (successfully) probe a device before you can use it with most other\n     NAND commands.\n\n12.6.2 Erasing, Reading, Writing to NAND Flash\n----------------------------------------------\n\n -- Command: nand dump num filename offset length [oob_option]\n     Reads binary data from the NAND device and writes it to the file,\n     starting at the specified offset.  The NUM parameter is the value\n     shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET and LENGTH must be exact multiples of the device's page\n     size.  They describe a data region; the OOB data associated with\n     each such page may also be accessed.\n\n     NOTE: At the time this text was written, no error correction was\n     done on the data that's read, unless raw access was disabled and\n     the underlying NAND controller driver had a 'read_page' method\n     which handled that error correction.\n\n     By default, only page data is saved to the specified file.  Use an\n     OOB_OPTION parameter to save OOB data:\n        * no oob_* parameter\n          Output file holds only page data; OOB is discarded.\n        * 'oob_raw'\n          Output file interleaves page data and OOB data; the file will\n          be longer than \"length\" by the size of the spare areas\n          associated with each data page.  Note that this kind of \"raw\"\n          access is different from what's implied by 'nand raw_access',\n          which just controls whether a hardware-aware access method is\n          used.\n        * 'oob_only'\n          Output file has only raw OOB data, and will be smaller than\n          \"length\" since it will contain only the spare areas associated\n          with each data page.\n\n -- Command: nand erase num [offset length]\n     Erases blocks on the specified NAND device, starting at the\n     specified OFFSET and continuing for LENGTH bytes.  Both of those\n     values must be exact multiples of the device's block size, and the\n     region they specify must fit entirely in the chip.  If those\n     parameters are not specified, the whole NAND chip will be erased.\n     The NUM parameter is the value shown by 'nand list'.\n\n     NOTE: This command will try to erase bad blocks, when told to do\n     so, which will probably invalidate the manufacturer's bad block\n     marker.  For the remainder of the current server session, 'nand\n     info' will still report that the block \"is\" bad.\n\n -- Command: nand write num filename offset [option...]\n     Writes binary data from the file into the specified NAND device,\n     starting at the specified offset.  Those pages should already have\n     been erased; you can't change zero bits to one bits.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET must be an exact multiple of the device's page size.\n     All data in the file will be written, assuming it doesn't run past\n     the end of the device.  Only full pages are written, and any extra\n     space in the last page will be filled with 0xff bytes.  (That\n     includes OOB data, if that's being written.)\n\n     NOTE: At the time this text was written, bad blocks are ignored.\n     That is, this routine will not skip bad blocks, but will instead\n     try to write them.  This can cause problems.\n\n     Provide at most one OPTION parameter.  With some NAND drivers, the\n     meanings of these parameters may change if 'nand raw_access' was\n     used to disable hardware ECC.\n        * no oob_* parameter\n          File has only page data, which is written.  If raw access is\n          in use, the OOB area will not be written.  Otherwise, if the\n          underlying NAND controller driver has a 'write_page' routine,\n          that routine may write the OOB with hardware-computed ECC\n          data.\n        * 'oob_only'\n          File has only raw OOB data, which is written to the OOB area.\n          Each page's data area stays untouched.  This can be a\n          dangerous option, since it can invalidate the ECC data.  You\n          may need to force raw access to use this mode.\n        * 'oob_raw'\n          File interleaves data and OOB data, both of which are written\n          If raw access is enabled, the data is written first, then the\n          un-altered OOB. Otherwise, if the underlying NAND controller\n          driver has a 'write_page' routine, that routine may modify the\n          OOB before it's written, to include hardware-computed ECC\n          data.\n        * 'oob_softecc'\n          File has only page data, which is written.  The OOB area is\n          filled with 0xff, except for a standard 1-bit software ECC\n          code stored in conventional locations.  You might need to\n          force raw access to use this mode, to prevent the underlying\n          driver from applying hardware ECC.\n        * 'oob_softecc_kw'\n          File has only page data, which is written.  The OOB area is\n          filled with 0xff, except for a 4-bit software ECC specific to\n          the boot ROM in Marvell Kirkwood SoCs.  You might need to\n          force raw access to use this mode, to prevent the underlying\n          driver from applying hardware ECC.\n\n -- Command: nand verify num filename offset [option...]\n     Verify the binary data in the file has been programmed to the\n     specified NAND device, starting at the specified offset.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     Use a complete path name for FILENAME, so you don't depend on the\n     directory used to start the OpenOCD server.\n\n     The OFFSET must be an exact multiple of the device's page size.\n     All data in the file will be read and compared to the contents of\n     the flash, assuming it doesn't run past the end of the device.  As\n     with 'nand write', only full pages are verified, so any extra space\n     in the last page will be filled with 0xff bytes.\n\n     The same OPTIONS accepted by 'nand write', and the file will be\n     processed similarly to produce the buffers that can be compared\n     against the contents produced from 'nand dump'.\n\n     NOTE: This will not work when the underlying NAND controller\n     driver's 'write_page' routine must update the OOB with a\n     hardware-computed ECC before the data is written.  This limitation\n     may be removed in a future release.\n\n12.6.3 Other NAND commands\n--------------------------\n\n -- Command: nand check_bad_blocks num [offset length]\n     Checks for manufacturer bad block markers on the specified NAND\n     device.  If no parameters are provided, checks the whole device;\n     otherwise, starts at the specified OFFSET and continues for LENGTH\n     bytes.  Both of those values must be exact multiples of the\n     device's block size, and the region they specify must fit entirely\n     in the chip.  The NUM parameter is the value shown by 'nand list'.\n\n     NOTE: Before using this command you should force raw access with\n     'nand raw_access enable' to ensure that the underlying driver will\n     not try to apply hardware ECC.\n\n -- Command: nand info num\n     The NUM parameter is the value shown by 'nand list'.  This prints\n     the one-line summary from \"nand list\", plus for devices which have\n     been probed this also prints any known status for each block.\n\n -- Command: nand raw_access num (enable|disable)\n     Sets or clears an flag affecting how page I/O is done.  The NUM\n     parameter is the value shown by 'nand list'.\n\n     This flag is cleared (disabled) by default, but changing that value\n     won't affect all NAND devices.  The key factor is whether the\n     underlying driver provides 'read_page' or 'write_page' methods.  If\n     it doesn't provide those methods, the setting of this flag is\n     irrelevant; all access is effectively \"raw\".\n\n     When those methods exist, they are normally used when reading data\n     ('nand dump' or reading bad block markers) or writing it ('nand\n     write').  However, enabling raw access (setting the flag) prevents\n     use of those methods, bypassing hardware ECC logic.  This can be a\n     dangerous option, since writing blocks with the wrong ECC data can\n     cause them to be marked as bad.\n\n12.6.4 NAND Driver List\n-----------------------\n\nAs noted above, the 'nand device' command allows driver-specific options\nand behaviors.  Some controllers also activate controller-specific\ncommands.\n\n -- NAND Driver: at91sam9\n     This driver handles the NAND controllers found on AT91SAM9 family\n     chips from Atmel.  It takes two extra parameters: address of the\n     NAND chip; address of the ECC controller.\n          nand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800\n     AT91SAM9 chips support single-bit ECC hardware.  The 'write_page'\n     and 'read_page' methods are used to utilize the ECC hardware unless\n     they are disabled by using the 'nand raw_access' command.  There\n     are four additional commands that are needed to fully configure the\n     AT91SAM9 NAND controller.  Two are optional; most boards use the\n     same wiring for ALE/CLE:\n      -- Config Command: at91sam9 cle num addr_line\n          Configure the address line used for latching commands.  The\n          NUM parameter is the value shown by 'nand list'.\n      -- Config Command: at91sam9 ale num addr_line\n          Configure the address line used for latching addresses.  The\n          NUM parameter is the value shown by 'nand list'.\n\n     For the next two commands, it is assumed that the pins have already\n     been properly configured for input or output.\n      -- Config Command: at91sam9 rdy_busy num pio_base_addr pin\n          Configure the RDY/nBUSY input from the NAND device.  The NUM\n          parameter is the value shown by 'nand list'.  PIO_BASE_ADDR is\n          the base address of the PIO controller and PIN is the pin\n          number.\n      -- Config Command: at91sam9 ce num pio_base_addr pin\n          Configure the chip enable input to the NAND device.  The NUM\n          parameter is the value shown by 'nand list'.  PIO_BASE_ADDR is\n          the base address of the PIO controller and PIN is the pin\n          number.\n\n -- NAND Driver: davinci\n     This driver handles the NAND controllers found on DaVinci family\n     chips from Texas Instruments.  It takes three extra parameters:\n     address of the NAND chip; hardware ECC mode to use ('hwecc1',\n     'hwecc4', 'hwecc4_infix'); address of the AEMIF controller on this\n     processor.\n          nand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000\n     All DaVinci processors support the single-bit ECC hardware, and\n     newer ones also support the four-bit ECC hardware.  The\n     'write_page' and 'read_page' methods are used to implement those\n     ECC modes, unless they are disabled using the 'nand raw_access'\n     command.\n\n -- NAND Driver: lpc3180\n     These controllers require an extra 'nand device' parameter: the\n     clock rate used by the controller.\n      -- Command: lpc3180 select num [mlc|slc]\n          Configures use of the MLC or SLC controller mode.  MLC implies\n          use of hardware ECC. The NUM parameter is the value shown by\n          'nand list'.\n\n     At this writing, this driver includes 'write_page' and 'read_page'\n     methods.  Using 'nand raw_access' to disable those methods will\n     prevent use of hardware ECC in the MLC controller mode, but won't\n     change SLC behavior.\n\n -- NAND Driver: mx3\n     This driver handles the NAND controller in i.MX31.  The mxc driver\n     should work for this chip as well.\n\n -- NAND Driver: mxc\n     This driver handles the NAND controller found in Freescale i.MX\n     chips.  It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35).\n     The driver takes 3 extra arguments, chip ('mx27', 'mx31', 'mx35'),\n     ecc ('noecc', 'hwecc') and optionally if bad block information\n     should be swapped between main area and spare area ('biswap'),\n     defaults to off.\n          nand device mx35.nand mxc imx35.cpu mx35 hwecc biswap\n      -- Command: mxc biswap bank_num [enable|disable]\n          Turns on/off bad block information swapping from main area,\n          without parameter query status.\n\n -- NAND Driver: orion\n     These controllers require an extra 'nand device' parameter: the\n     address of the controller.\n          nand device orion 0xd8000000\n     These controllers don't define any specialized commands.  At this\n     writing, their drivers don't include 'write_page' or 'read_page'\n     methods, so 'nand raw_access' won't change any behavior.\n\n -- NAND Driver: s3c2410\n -- NAND Driver: s3c2412\n -- NAND Driver: s3c2440\n -- NAND Driver: s3c2443\n -- NAND Driver: s3c6400\n     These S3C family controllers don't have any special 'nand device'\n     options, and don't define any specialized commands.  At this\n     writing, their drivers don't include 'write_page' or 'read_page'\n     methods, so 'nand raw_access' won't change any behavior.\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/share/info/openocd.info-2",
    "content": "This is openocd.info, produced by makeinfo version 6.8 from\nopenocd.texi.\n\nThis User's Guide documents release 0.11.0+dev, dated 8 June 2022, of\nthe Open On-Chip Debugger (OpenOCD).\n\n   * Copyright (C) 2008 The OpenOCD Project\n   * Copyright (C) 2007-2008 Spencer Oliver <spen@spen-soft.co.uk>\n   * Copyright (C) 2008-2010 Oyvind Harboe <oyvind.harboe@zylin.com>\n   * Copyright (C) 2008 Duane Ellis <openocd@duaneellis.com>\n   * Copyright (C) 2009-2010 David Brownell\n\n     Permission is granted to copy, distribute and/or modify this\n     document under the terms of the GNU Free Documentation License,\n     Version 1.2 or any later version published by the Free Software\n     Foundation; with no Invariant Sections, no Front-Cover Texts, and\n     no Back-Cover Texts.  A copy of the license is included in the\n     section entitled \"GNU Free Documentation License\".\nINFO-DIR-SECTION Development\nSTART-INFO-DIR-ENTRY\n* OpenOCD: (openocd).      OpenOCD User's Guide\nEND-INFO-DIR-ENTRY\n\n\u001f\nFile: openocd.info,  Node: Flash Programming,  Next: PLD/FPGA Commands,  Prev: Flash Commands,  Up: Top\n\n13 Flash Programming\n********************\n\nOpenOCD implements numerous ways to program the target flash, whether\ninternal or external.  Programming can be achieved by either using *note\nProgramming using GDB: programmingusinggdb, or using the commands given\nin *note Flash Programming Commands: flashprogrammingcommands.\n\n\nTo simplify using the flash commands directly a jimtcl script is\navailable that handles the programming and verify stage.  OpenOCD will\nprogram/verify/reset the target and optionally shutdown.\n\nThe script is executed as follows and by default the following actions\nwill be performed.\n  1. 'init' is executed.\n  2. 'reset init' is called to reset and halt the target, any 'reset\n     init' scripts are executed.\n  3. 'flash write_image' is called to erase and write any flash using\n     the filename given.\n  4. If the 'preverify' parameter is given, the target is \"verified\"\n     first and only flashed if this fails.\n  5. 'verify_image' is called if 'verify' parameter is given.\n  6. 'reset run' is called if 'reset' parameter is given.\n  7. OpenOCD is shutdown if 'exit' parameter is given.\n\nAn example of usage is given below.  *Note program::.\n\n     # program and verify using elf/hex/s19. verify and reset\n     # are optional parameters\n     openocd -f board/stm32f3discovery.cfg \\\n     \t-c \"program filename.elf verify reset exit\"\n\n     # binary files need the flash address passing\n     openocd -f board/stm32f3discovery.cfg \\\n     \t-c \"program filename.bin exit 0x08000000\"\n\n\u001f\nFile: openocd.info,  Node: PLD/FPGA Commands,  Next: General Commands,  Prev: Flash Programming,  Up: Top\n\n14 PLD/FPGA Commands\n********************\n\nProgrammable Logic Devices (PLDs) and the more flexible Field\nProgrammable Gate Arrays (FPGAs) are both types of programmable\nhardware.  OpenOCD can support programming them.  Although PLDs are\ngenerally restrictive (cells are less functional, and there are no\nspecial purpose cells for memory or computational tasks), they share the\nsame OpenOCD infrastructure.  Accordingly, both are called PLDs here.\n\n14.1 PLD/FPGA Configuration and Commands\n========================================\n\nAs it does for JTAG TAPs, debug targets, and flash chips (both NOR and\nNAND), OpenOCD maintains a list of PLDs available for use in various\ncommands.  Also, each such PLD requires a driver.\n\nThey are referenced by the number shown by the 'pld devices' command,\nand new PLDs are defined by 'pld device driver_name'.\n\n -- Config Command: pld device driver_name tap_name [driver_options]\n     Defines a new PLD device, supported by driver DRIVER_NAME, using\n     the TAP named TAP_NAME.  The driver may make use of any\n     DRIVER_OPTIONS to configure its behavior.\n\n -- Command: pld devices\n     Lists the PLDs and their numbers.\n\n -- Command: pld load num filename\n     Loads the file 'filename' into the PLD identified by NUM.  The file\n     format must be inferred by the driver.\n\n14.2 PLD/FPGA Drivers, Options, and Commands\n============================================\n\nDrivers may support PLD-specific options to the 'pld device' definition\ncommand, and may also define commands usable only with that particular\ntype of PLD.\n\n -- FPGA Driver: virtex2 [no_jstart]\n     Virtex-II is a family of FPGAs sold by Xilinx.  It supports the\n     IEEE 1532 standard for In-System Configuration (ISC).\n\n     If NO_JSTART is non-zero, the JSTART instruction is not used after\n     loading the bitstream.  While required for Series2, Series3, and\n     Series6, it breaks bitstream loading on Series7.\n\n      -- Command: virtex2 read_stat num\n          Reads and displays the Virtex-II status register (STAT) for\n          FPGA NUM.\n\n\u001f\nFile: openocd.info,  Node: General Commands,  Next: Architecture and Core Commands,  Prev: PLD/FPGA Commands,  Up: Top\n\n15 General Commands\n*******************\n\nThe commands documented in this chapter here are common commands that\nyou, as a human, may want to type and see the output of.  Configuration\ntype commands are documented elsewhere.\n\nIntent:\n   * Source Of Commands\n     OpenOCD commands can occur in a configuration script (discussed\n     elsewhere) or typed manually by a human or supplied\n     programmatically, or via one of several TCP/IP Ports.\n\n   * From the human\n     A human should interact with the telnet interface (default port:\n     4444) or via GDB (default port 3333).\n\n     To issue commands from within a GDB session, use the 'monitor'\n     command, e.g.  use 'monitor poll' to issue the 'poll' command.  All\n     output is relayed through the GDB session.\n\n   * Machine Interface The Tcl interface's intent is to be a machine\n     interface.  The default Tcl port is 5555.\n\n15.1 Server Commands\n====================\n\n -- Command: exit\n     Exits the current telnet session.\n\n -- Command: help [string]\n     With no parameters, prints help text for all commands.  Otherwise,\n     prints each helptext containing STRING.  Not every command provides\n     helptext.\n\n     Configuration commands, and commands valid at any time, are\n     explicitly noted in parenthesis.  In most cases, no such\n     restriction is listed; this indicates commands which are only\n     available after the configuration stage has completed.\n\n -- Command: usage [string]\n     With no parameters, prints usage text for all commands.  Otherwise,\n     prints all usage text of which command, help text, and usage text\n     containing STRING.  Not every command provides helptext.\n\n -- Command: sleep msec [busy]\n     Wait for at least MSEC milliseconds before resuming.  If 'busy' is\n     passed, busy-wait instead of sleeping.  (This option is strongly\n     discouraged.)  Useful in connection with script files ('script'\n     command and 'target_name' configuration).\n\n -- Command: shutdown [error]\n     Close the OpenOCD server, disconnecting all clients (GDB, telnet,\n     other).  If option 'error' is used, OpenOCD will return a non-zero\n     exit code to the parent process.\n\n     If user types CTRL-C or kills OpenOCD, the command 'shutdown' will\n     be automatically executed to cause OpenOCD to exit.\n\n     It is possible to specify, in the TCL list PRE_SHUTDOWN_COMMANDS ,\n     a set of commands to be automatically executed before 'shutdown' ,\n     e.g.:\n          lappend pre_shutdown_commands {echo \"Goodbye, my friend ...\"}\n          lappend pre_shutdown_commands {echo \"see you soon !\"}\n     The commands in the list will be executed (in the same order they\n     occupy in the list) before OpenOCD exits.  If one of the commands\n     in the list fails, then the remaining commands are not executed\n     anymore while OpenOCD will proceed to quit.\n\n -- Command: debug_level [n]\n     Display debug level.  If N (from 0..4) is provided, then set it to\n     that level.  This affects the kind of messages sent to the server\n     log.  Level 0 is error messages only; level 1 adds warnings; level\n     2 adds informational messages; level 3 adds debugging messages; and\n     level 4 adds verbose low-level debug messages.  The default is\n     level 2, but that can be overridden on the command line along with\n     the location of that log file (which is normally the server's\n     standard output).  *Note Running::.\n\n -- Command: echo [-n] message\n     Logs a message at \"user\" priority.  Option \"-n\" suppresses trailing\n     newline.\n          echo \"Downloading kernel -- please wait\"\n\n -- Command: log_output [filename | \"default\"]\n     Redirect logging to FILENAME or set it back to default output; the\n     default log output channel is stderr.\n\n -- Command: add_script_search_dir [directory]\n     Add DIRECTORY to the file/script search path.\n\n -- Config Command: bindto [NAME]\n     Specify hostname or IPv4 address on which to listen for incoming\n     TCP/IP connections.  By default, OpenOCD will listen on the\n     loopback interface only.  If your network environment is safe,\n     'bindto 0.0.0.0' can be used to cover all available interfaces.\n\n15.2 Target State handling\n==========================\n\nIn this section \"target\" refers to a CPU configured as shown earlier\n(*note CPU Configuration::).  These commands, like many, implicitly\nrefer to a current target which is used to perform the various\noperations.  The current target may be changed by using 'targets'\ncommand with the name of the target which should become current.\n\n -- Command: reg [(number|name) [(value|'force')]]\n     Access a single register by NUMBER or by its NAME.  The target must\n     generally be halted before access to CPU core registers is allowed.\n     Depending on the hardware, some other registers may be accessible\n     while the target is running.\n\n     _With no arguments_: list all available registers for the current\n     target, showing number, name, size, value, and cache status.  For\n     valid entries, a value is shown; valid entries which are also dirty\n     (and will be written back later) are flagged as such.\n\n     _With number/name_: display that register's value.  Use FORCE\n     argument to read directly from the target, bypassing any internal\n     cache.\n\n     _With both number/name and value_: set register's value.  Writes\n     may be held in a writeback cache internal to OpenOCD, so that\n     setting the value marks the register as dirty instead of\n     immediately flushing that value.  Resuming CPU execution (including\n     by single stepping) or otherwise activating the relevant module\n     will flush such values.\n\n     Cores may have surprisingly many registers in their Debug and trace\n     infrastructure:\n\n          > reg\n          ===== ARM registers\n          (0) r0 (/32): 0x0000D3C2 (dirty)\n          (1) r1 (/32): 0xFD61F31C\n          (2) r2 (/32)\n          ...\n          (164) ETM_contextid_comparator_mask (/32)\n          >\n\n -- Command: set_reg dict\n     Set register values of the target.\n\n        * DICT ...  Tcl dictionary with pairs of register names and\n          values.\n\n     For example, the following command sets the value 0 to the program\n     counter (pc) register and 0x1000 to the stack pointer (sp)\n     register:\n\n          set_reg {pc 0 sp 0x1000}\n\n -- Command: get_reg [-force] list\n     Get register values from the target and return them as Tcl\n     dictionary with pairs of register names and values.  If option\n     \"-force\" is set, the register values are read directly from the\n     target, bypassing any caching.\n\n        * LIST ...  List of register names\n\n     For example, the following command retrieves the values from the\n     program counter (pc) and stack pointer (sp) register:\n\n          get_reg {pc sp}\n\n -- Command: write_memory address width data ['phys']\n     This function provides an efficient way to write to the target\n     memory from a Tcl script.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * DATA ...  Tcl list with the elements to write\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command writes two 32 bit words into the\n     target memory at address 0x20000000:\n\n          write_memory 0x20000000 32 {0xdeadbeef 0x00230500}\n\n -- Command: read_memory address width count ['phys']\n     This function provides an efficient way to read the target memory\n     from a Tcl script.  A Tcl list containing the requested memory\n     elements is returned by this function.\n\n        * ADDRESS ...  target memory address\n        * WIDTH ...  memory access bit size, can be 8, 16, 32 or 64\n        * COUNT ...  number of elements to read\n        * ['phys'] ...  treat the memory address as physical instead of\n          virtual address\n\n     For example, the following command reads two 32 bit words from the\n     target memory at address 0x20000000:\n\n          read_memory 0x20000000 32 2\n\n -- Command: halt [ms]\n -- Command: wait_halt [ms]\n     The 'halt' command first sends a halt request to the target, which\n     'wait_halt' doesn't.  Otherwise these behave the same: wait up to\n     MS milliseconds, or 5 seconds if there is no parameter, for the\n     target to halt (and enter debug mode).  Using 0 as the MS parameter\n     prevents OpenOCD from waiting.\n\n          Warning: On ARM cores, software using the _wait for interrupt_\n          operation often blocks the JTAG access needed by a 'halt'\n          command.  This is because that operation also puts the core\n          into a low power mode by gating the core clock; but the core\n          clock is needed to detect JTAG clock transitions.\n\n          One partial workaround uses adaptive clocking: when the core\n          is interrupted the operation completes, then JTAG clocks are\n          accepted at least until the interrupt handler completes.\n          However, this workaround is often unusable since the\n          processor, board, and JTAG adapter must all support adaptive\n          JTAG clocking.  Also, it can't work until an interrupt is\n          issued.\n\n          A more complete workaround is to not use that operation while\n          you work with a JTAG debugger.  Tasking environments generally\n          have idle loops where the body is the _wait for interrupt_\n          operation.  (On older cores, it is a coprocessor action; newer\n          cores have a 'wfi' instruction.)  Such loops can just remove\n          that operation, at the cost of higher power consumption\n          (because the CPU is needlessly clocked).\n\n -- Command: resume [address]\n     Resume the target at its current code position, or the optional\n     ADDRESS if it is provided.  OpenOCD will wait 5 seconds for the\n     target to resume.\n\n -- Command: step [address]\n     Single-step the target at its current code position, or the\n     optional ADDRESS if it is provided.\n\n -- Command: reset\n -- Command: reset run\n -- Command: reset halt\n -- Command: reset init\n     Perform as hard a reset as possible, using SRST if possible.  _All\n     defined targets will be reset, and target events will fire during\n     the reset sequence._\n\n     The optional parameter specifies what should happen after the\n     reset.  If there is no parameter, a 'reset run' is executed.  The\n     other options will not work on all systems.  *Note Reset\n     Configuration::.\n\n        - run Let the target run\n        - halt Immediately halt the target\n        - init Immediately halt the target, and execute the reset-init\n          script\n\n -- Command: soft_reset_halt\n     Requesting target halt and executing a soft reset.  This is often\n     used when a target cannot be reset and halted.  The target, after\n     reset is released begins to execute code.  OpenOCD attempts to stop\n     the CPU and then sets the program counter back to the reset vector.\n     Unfortunately the code that was executed may have left the hardware\n     in an unknown state.\n\n -- Command: adapter assert [signal [assert|deassert signal]]\n -- Command: adapter deassert [signal [assert|deassert signal]]\n     Set values of reset signals.  Without parameters returns current\n     status of the signals.  The SIGNAL parameter values may be 'srst',\n     indicating that srst signal is to be asserted or deasserted,\n     'trst', indicating that trst signal is to be asserted or\n     deasserted.\n\n     The 'reset_config' command should already have been used to\n     configure how the board and the adapter treat these two signals,\n     and to say if either signal is even present.  *Note Reset\n     Configuration::.  Trying to assert a signal that is not present\n     triggers an error.  If a signal is present on the adapter and not\n     specified in the command, the signal will not be modified.\n\n          Note: TRST is specially handled.  It actually signifies JTAG's\n          RESET state.  So if the board doesn't support the optional\n          TRST signal, or it doesn't support it along with the specified\n          SRST value, JTAG reset is triggered with TMS and TCK signals\n          instead of the TRST signal.  And no matter how that JTAG reset\n          is triggered, once the scan chain enters RESET with TRST\n          inactive, TAP 'post-reset' events are delivered to all TAPs\n          with handlers for that event.\n\n15.3 Memory access commands\n===========================\n\nThese commands allow accesses of a specific size to the memory system.\nOften these are used to configure the current target in some special\nway.  For example - one may need to write certain values to the SDRAM\ncontroller to enable SDRAM.\n\n  1. Use the 'targets' (plural) command to change the current target.\n  2. In system level scripts these commands are deprecated.  Please use\n     their TARGET object siblings to avoid making assumptions about what\n     TAP is the current target, or about MMU configuration.\n\n -- Command: mdd [phys] addr [count]\n -- Command: mdw [phys] addr [count]\n -- Command: mdh [phys] addr [count]\n -- Command: mdb [phys] addr [count]\n     Display contents of address ADDR, as 64-bit doublewords ('mdd'),\n     32-bit words ('mdw'), 16-bit halfwords ('mdh'), or 8-bit bytes\n     ('mdb').  When the current target has an MMU which is present and\n     active, ADDR is interpreted as a virtual address.  Otherwise, or if\n     the optional PHYS flag is specified, ADDR is interpreted as a\n     physical address.  If COUNT is specified, displays that many units.\n     (If you want to process the data instead of displaying it, see the\n     'read_memory' primitives.)\n\n -- Command: mwd [phys] addr doubleword [count]\n -- Command: mww [phys] addr word [count]\n -- Command: mwh [phys] addr halfword [count]\n -- Command: mwb [phys] addr byte [count]\n     Writes the specified DOUBLEWORD (64 bits), WORD (32 bits), HALFWORD\n     (16 bits), or BYTE (8-bit) value, at the specified address ADDR.\n     When the current target has an MMU which is present and active,\n     ADDR is interpreted as a virtual address.  Otherwise, or if the\n     optional PHYS flag is specified, ADDR is interpreted as a physical\n     address.  If COUNT is specified, fills that many units of\n     consecutive address.\n\n15.4 Image loading commands\n===========================\n\n -- Command: dump_image filename address size\n     Dump SIZE bytes of target memory starting at ADDRESS to the binary\n     file named FILENAME.\n\n -- Command: fast_load\n     Loads an image stored in memory by 'fast_load_image' to the current\n     target.  Must be preceded by fast_load_image.\n\n -- Command: fast_load_image filename address [bin|ihex|elf|s19]\n     Normally you should be using 'load_image' or GDB load.  However,\n     for testing purposes or when I/O overhead is significant(OpenOCD\n     running on an embedded host), storing the image in memory and\n     uploading the image to the target can be a way to upload e.g.\n     multiple debug sessions when the binary does not change.  Arguments\n     are the same as 'load_image', but the image is stored in OpenOCD\n     host memory, i.e.  does not affect target.  This approach is also\n     useful when profiling target programming performance as I/O and\n     target programming can easily be profiled separately.\n\n -- Command: load_image filename address [[bin|ihex|elf|s19] min_addr\n          max_length]\n     Load image from file FILENAME to target memory offset by ADDRESS\n     from its load address.  The file format may optionally be specified\n     ('bin', 'ihex', 'elf', or 's19').  In addition the following\n     arguments may be specified: MIN_ADDR - ignore data below MIN_ADDR\n     (this is w.r.t.  to the target's load address + ADDRESS) MAX_LENGTH\n     - maximum number of bytes to load.\n          proc load_image_bin {fname foffset address length } {\n              # Load data from fname filename at foffset offset to\n              # target at address. Load at most length bytes.\n              load_image $fname [expr {$address - $foffset}] bin \\\n                         $address $length\n          }\n\n -- Command: test_image filename [address [bin|ihex|elf]]\n     Displays image section sizes and addresses as if FILENAME were\n     loaded into target memory starting at ADDRESS (defaults to zero).\n     The file format may optionally be specified ('bin', 'ihex', or\n     'elf')\n\n -- Command: verify_image filename address [bin|ihex|elf]\n     Verify FILENAME against target memory starting at ADDRESS.  The\n     file format may optionally be specified ('bin', 'ihex', or 'elf')\n     This will first attempt a comparison using a CRC checksum, if this\n     fails it will try a binary compare.\n\n -- Command: verify_image_checksum filename address [bin|ihex|elf]\n     Verify FILENAME against target memory starting at ADDRESS.  The\n     file format may optionally be specified ('bin', 'ihex', or 'elf')\n     This perform a comparison using a CRC checksum only\n\n15.5 Breakpoint and Watchpoint commands\n=======================================\n\nCPUs often make debug modules accessible through JTAG, with hardware\nsupport for a handful of code breakpoints and data watchpoints.  In\naddition, CPUs almost always support software breakpoints.\n\n -- Command: bp [address len [hw]]\n     With no parameters, lists all active breakpoints.  Else sets a\n     breakpoint on code execution starting at ADDRESS for LENGTH bytes.\n     This is a software breakpoint, unless 'hw' is specified in which\n     case it will be a hardware breakpoint.\n\n     (*Note arm9 vector_catch: arm9vectorcatch, or *note xscale\n     vector_catch: xscalevectorcatch, for similar mechanisms that do not\n     consume hardware breakpoints.)\n\n -- Command: rbp all | address\n     Remove the breakpoint at ADDRESS or all breakpoints.\n\n -- Command: rwp address\n     Remove data watchpoint on ADDRESS\n\n -- Command: wp [address len [(r|w|a) [value [mask]]]]\n     With no parameters, lists all active watchpoints.  Else sets a data\n     watchpoint on data from ADDRESS for LENGTH bytes.  The watch point\n     is an \"access\" watchpoint unless the 'r' or 'w' parameter is\n     provided, defining it as respectively a read or write watchpoint.\n     If a VALUE is provided, that value is used when determining if the\n     watchpoint should trigger.  The value may be first be masked using\n     MASK to mark \"don't care\" fields.\n\n15.6 Real Time Transfer (RTT)\n=============================\n\nReal Time Transfer (RTT) is an interface specified by SEGGER based on\nbasic memory reads and writes to transfer data bidirectionally between\ntarget and host.  The specification is independent of the target\narchitecture.  Every target that supports so called \"background memory\naccess\", which means that the target memory can be accessed by the\ndebugger while the target is running, can be used.  This interface is\nespecially of interest for targets without Serial Wire Output (SWO),\nsuch as ARM Cortex-M0, or where semihosting is not applicable because of\nreal-time constraints.\n\n     Note: The current implementation supports only single target\n     devices.\n\nThe data transfer between host and target device is organized through\nunidirectional up/down-channels for target-to-host and host-to-target\ncommunication, respectively.\n\n     Note: The current implementation does not respect channel buffer\n     flags.  They are used to determine what happens when writing to a\n     full buffer, for example.\n\nChannels are exposed via raw TCP/IP connections.  One or more RTT\nservers can be assigned to each channel to make them accessible to an\nunlimited number of TCP/IP connections.\n\n -- Command: rtt setup address size ID\n     Configure RTT for the currently selected target.  Once RTT is\n     started, OpenOCD searches for a control block with the identifier\n     ID starting at the memory address ADDRESS within the next SIZE\n     bytes.\n\n -- Command: rtt start\n     Start RTT. If the control block location is not known, OpenOCD\n     starts searching for it.\n\n -- Command: rtt stop\n     Stop RTT.\n\n -- Command: rtt polling_interval [interval]\n     Display the polling interval.  If INTERVAL is provided, set the\n     polling interval.  The polling interval determines (in\n     milliseconds) how often the up-channels are checked for new data.\n\n -- Command: rtt channels\n     Display a list of all channels and their properties.\n\n -- Command: rtt channellist\n     Return a list of all channels and their properties as Tcl list.\n     The list can be manipulated easily from within scripts.\n\n -- Command: rtt server start port channel\n     Start a TCP server on PORT for the channel CHANNEL.\n\n -- Command: rtt server stop port\n     Stop the TCP sever with port PORT.\n\nThe following example shows how to setup RTT using the SEGGER RTT\nimplementation on the target device.\n\n     resume\n\n     rtt setup 0x20000000 2048 \"SEGGER RTT\"\n     rtt start\n\n     rtt server start 9090 0\n\nIn this example, OpenOCD searches the control block with the ID \"SEGGER\nRTT\" starting at 0x20000000 for 2048 bytes.  The RTT channel 0 is\nexposed through the TCP/IP port 9090.\n\n15.7 Misc Commands\n==================\n\n -- Command: profile seconds filename [start end]\n     Profiling samples the CPU's program counter as quickly as possible,\n     which is useful for non-intrusive stochastic profiling.  Saves up\n     to 10000 samples in 'filename' using \"gmon.out\" format.  Optional\n     'start' and 'end' parameters allow to limit the address range.\n\n -- Command: version\n     Displays a string identifying the version of this OpenOCD server.\n\n -- Command: virt2phys virtual_address\n     Requests the current target to map the specified VIRTUAL_ADDRESS to\n     its corresponding physical address, and displays the result.\n\n -- Command: add_help_text 'command_name' 'help-string'\n     Add or replace help text on the given COMMAND_NAME.\n\n -- Command: add_usage_text 'command_name' 'help-string'\n     Add or replace usage text on the given COMMAND_NAME.\n\n\u001f\nFile: openocd.info,  Node: Architecture and Core Commands,  Next: JTAG Commands,  Prev: General Commands,  Up: Top\n\n16 Architecture and Core Commands\n*********************************\n\nMost CPUs have specialized JTAG operations to support debugging.\nOpenOCD packages most such operations in its standard command framework.\nSome of those operations don't fit well in that framework, so they are\nexposed here as architecture or implementation (core) specific commands.\n\n16.1 ARM Hardware Tracing\n=========================\n\nCPUs based on ARM cores may include standard tracing interfaces, based\non an \"Embedded Trace Module\" (ETM) which sends voluminous address and\ndata bus trace records to a \"Trace Port\".\n\n   * Development-oriented boards will sometimes provide a high speed\n     trace connector for collecting that data, when the particular CPU\n     supports such an interface.  (The standard connector is a 38-pin\n     Mictor, with both JTAG and trace port support.)  Those trace\n     connectors are supported by higher end JTAG adapters and some logic\n     analyzer modules; frequently those modules can buffer several\n     megabytes of trace data.  Configuring an ETM coupled to such an\n     external trace port belongs in the board-specific configuration\n     file.\n   * If the CPU doesn't provide an external interface, it probably has\n     an \"Embedded Trace Buffer\" (ETB) on the chip, which is a dedicated\n     SRAM. 4KBytes is one common ETB size.  Configuring an ETM coupled\n     only to an ETB belongs in the CPU-specific (target) configuration\n     file, since it works the same on all boards.\n\nETM support in OpenOCD doesn't seem to be widely used yet.\n\n     Issues: ETM support may be buggy, and at least some 'etm config'\n     parameters should be detected by asking the ETM for them.\n\n     ETM trigger events could also implement a kind of complex hardware\n     breakpoint, much more powerful than the simple watchpoint hardware\n     exported by EmbeddedICE modules.  _Such breakpoints can be\n     triggered even when using the dummy trace port driver_.\n\n     It seems like a GDB hookup should be possible, as well as tracing\n     only during specific states (perhaps _handling IRQ 23_ or _calls\n     foo()_).\n\n     There should be GUI tools to manipulate saved trace data and help\n     analyse it in conjunction with the source code.  It's unclear how\n     much of a common interface is shared with the current XScale trace\n     support, or should be shared with eventual Nexus-style trace module\n     support.\n\n     At this writing (November 2009) only ARM7, ARM9, and ARM11 support\n     for ETM modules is available.  The code should be able to work with\n     some newer cores; but not all of them support this original style\n     of JTAG access.\n\n16.1.1 ETM Configuration\n------------------------\n\nETM setup is coupled with the trace port driver configuration.\n\n -- Config Command: etm config target width mode clocking driver\n     Declares the ETM associated with TARGET, and associates it with a\n     given trace port DRIVER.  *Note Trace Port Drivers:\n     traceportdrivers.\n\n     Several of the parameters must reflect the trace port capabilities,\n     which are a function of silicon capabilities (exposed later using\n     'etm info') and of what hardware is connected to that port (such as\n     an external pod, or ETB). The WIDTH must be either 4, 8, or 16,\n     except with ETMv3.0 and newer modules which may also support 1, 2,\n     24, 32, 48, and 64 bit widths.  (With those versions, 'etm info'\n     also shows whether the selected port width and mode are supported.)\n\n     The MODE must be 'normal', 'multiplexed', or 'demultiplexed'.  The\n     CLOCKING must be 'half' or 'full'.\n\n          Warning: With ETMv3.0 and newer, the bits set with the MODE\n          and CLOCKING parameters both control the mode.  This modified\n          mode does not map to the values supported by previous ETM\n          modules, so this syntax is subject to change.\n\n          Note: You can see the ETM registers using the 'reg' command.\n          Not all possible registers are present in every ETM. Most of\n          the registers are write-only, and are used to configure what\n          CPU activities are traced.\n\n -- Command: etm info\n     Displays information about the current target's ETM. This includes\n     resource counts from the 'ETM_CONFIG' register, as well as silicon\n     capabilities (except on rather old modules).  from the\n     'ETM_SYS_CONFIG' register.\n\n -- Command: etm status\n     Displays status of the current target's ETM and trace port driver:\n     is the ETM idle, or is it collecting data?  Did trace data\n     overflow?  Was it triggered?\n\n -- Command: etm tracemode [type context_id_bits cycle_accurate\n          branch_output]\n     Displays what data that ETM will collect.  If arguments are\n     provided, first configures that data.  When the configuration\n     changes, tracing is stopped and any buffered trace data is\n     invalidated.\n\n        * TYPE ...  describing how data accesses are traced, when they\n          pass any ViewData filtering that was set up.  The value is one\n          of 'none' (save nothing), 'data' (save data), 'address' (save\n          addresses), 'all' (save data and addresses)\n        * CONTEXT_ID_BITS ...  0, 8, 16, or 32\n        * CYCLE_ACCURATE ...  'enable' or 'disable' cycle-accurate\n          instruction tracing.  Before ETMv3, enabling this causes much\n          extra data to be recorded.\n        * BRANCH_OUTPUT ...  'enable' or 'disable'.  Disable this unless\n          you need to try reconstructing the instruction trace stream\n          without an image of the code.\n\n -- Command: etm trigger_debug (enable|disable)\n     Displays whether ETM triggering debug entry (like a breakpoint) is\n     enabled or disabled, after optionally modifying that configuration.\n     The default behaviour is 'disable'.  Any change takes effect after\n     the next 'etm start'.\n\n     By using script commands to configure ETM registers, you can make\n     the processor enter debug state automatically when certain\n     conditions, more complex than supported by the breakpoint hardware,\n     happen.\n\n16.1.2 ETM Trace Operation\n--------------------------\n\nAfter setting up the ETM, you can use it to collect data.  That data can\nbe exported to files for later analysis.  It can also be parsed with\nOpenOCD, for basic sanity checking.\n\nTo configure what is being traced, you will need to write various trace\nregisters using 'reg ETM_*' commands.  For the definitions of these\nregisters, read ARM publication _IHI 0014, \"Embedded Trace Macrocell,\nArchitecture Specification\"_.  Be aware that most of the relevant\nregisters are write-only, and that ETM resources are limited.  There are\nonly a handful of address comparators, data comparators, counters, and\nso on.\n\nExamples of scenarios you might arrange to trace include:\n\n   * Code flow within a function, _excluding_ subroutines it calls.  Use\n     address range comparators to enable tracing for instruction access\n     within that function's body.\n   * Code flow within a function, _including_ subroutines it calls.  Use\n     the sequencer and address comparators to activate tracing on an\n     \"entered function\" state, then deactivate it by exiting that state\n     when the function's exit code is invoked.\n   * Code flow starting at the fifth invocation of a function, combining\n     one of the above models with a counter.\n   * CPU data accesses to the registers for a particular device, using\n     address range comparators and the ViewData logic.\n   * Such data accesses only during IRQ handling, combining the above\n     model with sequencer triggers which on entry and exit to the IRQ\n     handler.\n   * _...  more_\n\nAt this writing, September 2009, there are no Tcl utility procedures to\nhelp set up any common tracing scenarios.\n\n -- Command: etm analyze\n     Reads trace data into memory, if it wasn't already present.\n     Decodes and prints the data that was collected.\n\n -- Command: etm dump filename\n     Stores the captured trace data in 'filename'.\n\n -- Command: etm image filename [base_address] [type]\n     Opens an image file.\n\n -- Command: etm load filename\n     Loads captured trace data from 'filename'.\n\n -- Command: etm start\n     Starts trace data collection.\n\n -- Command: etm stop\n     Stops trace data collection.\n\n16.1.3 Trace Port Drivers\n-------------------------\n\nTo use an ETM trace port it must be associated with a driver.\n\n -- Trace Port Driver: dummy\n     Use the 'dummy' driver if you are configuring an ETM that's not\n     connected to anything (on-chip ETB or off-chip trace connector).\n     _This driver lets OpenOCD talk to the ETM, but it does not expose\n     any trace data collection._\n      -- Config Command: etm_dummy config target\n          Associates the ETM for TARGET with a dummy driver.\n\n -- Trace Port Driver: etb\n     Use the 'etb' driver if you are configuring an ETM to use on-chip\n     ETB memory.\n      -- Config Command: etb config target etb_tap\n          Associates the ETM for TARGET with the ETB at ETB_TAP.  You\n          can see the ETB registers using the 'reg' command.\n      -- Command: etb trigger_percent [percent]\n          This displays, or optionally changes, ETB behavior after the\n          ETM's configured _trigger_ event fires.  It controls how much\n          more trace data is saved after the (single) trace trigger\n          becomes active.\n\n             * The default corresponds to _trace around_ usage,\n               recording 50 percent data before the event and the rest\n               afterwards.\n             * The minimum value of PERCENT is 2 percent, recording\n               almost exclusively data before the trigger.  Such extreme\n               _trace before_ usage can help figure out what caused that\n               event to happen.\n             * The maximum value of PERCENT is 100 percent, recording\n               data almost exclusively after the event.  This extreme\n               _trace after_ usage might help sort out how the event\n               caused trouble.\n\n16.2 ARM Cross-Trigger Interface\n================================\n\nThe ARM Cross-Trigger Interface (CTI) is a generic CoreSight component\nthat connects event sources like tracing components or CPU cores with\neach other through a common trigger matrix (CTM). For ARMv8\narchitecture, a CTI is mandatory for core run control and each core has\nan individual CTI instance attached to it.  OpenOCD has limited support\nfor CTI using the _cti_ group of commands.\n\n -- Command: cti create cti_name -dap dap_name -ap-num apn -baseaddr\n          base_address\n     Creates a CTI instance CTI_NAME on the DAP instance DAP_NAME on\n     MEM-AP APN.  The BASE_ADDRESS must match the base address of the\n     CTI on the respective MEM-AP. All arguments are mandatory.  This\n     creates a new command '$cti_name' which is used for various\n     purposes including additional configuration.\n\n -- Command: $cti_name enable on|off\n     Enable ('on') or disable ('off') the CTI.\n\n -- Command: $cti_name dump\n     Displays a register dump of the CTI.\n\n -- Command: $cti_name write REG_NAME VALUE\n     Write VALUE to the CTI register with the symbolic name REG_NAME.\n\n -- Command: $cti_name read REG_NAME\n     Print the value read from the CTI register with the symbolic name\n     REG_NAME.\n\n -- Command: $cti_name ack EVENT\n     Acknowledge a CTI EVENT.\n\n -- Command: $cti_name channel CHANNEL_NUMBER OPERATION\n     Perform a specific channel operation, the possible operations are:\n     gate, ungate, set, clear and pulse\n\n -- Command: $cti_name testmode on|off\n     Enable ('on') or disable ('off') the integration test mode of the\n     CTI.\n\n -- Command: cti names\n     Prints a list of names of all CTI objects created.  This command is\n     mainly useful in TCL scripting.\n\n16.3 Generic ARM\n================\n\nThese commands should be available on all ARM processors.  They are\navailable in addition to other core-specific commands that may be\navailable.\n\n -- Command: arm core_state [arm|thumb]\n     Displays the core_state, optionally changing it to process either\n     'arm' or 'thumb' instructions.  The target may later be resumed in\n     the currently set core_state.  (Processors may also support the\n     Jazelle state, but that is not currently supported in OpenOCD.)\n\n -- Command: arm disassemble address [count [thumb]]\n     Disassembles COUNT instructions starting at ADDRESS.  If COUNT is\n     not specified, a single instruction is disassembled.  If 'thumb' is\n     specified, or the low bit of the address is set, Thumb2 (mixed\n     16/32-bit) instructions are used; else ARM (32-bit) instructions\n     are used.  (Processors may also support the Jazelle state, but\n     those instructions are not currently understood by OpenOCD.)\n\n     Note that all Thumb instructions are Thumb2 instructions, so older\n     processors (without Thumb2 support) will still see correct\n     disassembly of Thumb code.  Also, ThumbEE opcodes are the same as\n     Thumb2, with a handful of exceptions.  ThumbEE disassembly\n     currently has no explicit support.\n\n -- Command: arm mcr pX op1 CRn CRm op2 value\n     Write VALUE to a coprocessor PX register passing parameters CRN,\n     CRM, opcodes OPC1 and OPC2, and using the MCR instruction.\n     (Parameter sequence matches the ARM instruction, but omits an ARM\n     register.)\n\n -- Command: arm mrc pX coproc op1 CRn CRm op2\n     Read a coprocessor PX register passing parameters CRN, CRM, opcodes\n     OPC1 and OPC2, and the MRC instruction.  Returns the result so it\n     can be manipulated by Jim scripts.  (Parameter sequence matches the\n     ARM instruction, but omits an ARM register.)\n\n -- Command: arm reg\n     Display a table of all banked core registers, fetching the current\n     value from every core mode if necessary.\n\n -- Command: arm semihosting [enable|disable]\n     Display status of semihosting, after optionally changing that\n     status.\n\n     Semihosting allows for code executing on an ARM target to use the\n     I/O facilities on the host computer i.e.  the system where OpenOCD\n     is running.  The target application must be linked against a\n     library implementing the ARM semihosting convention that forwards\n     operation requests by using a special SVC instruction that is\n     trapped at the Supervisor Call vector by OpenOCD.\n\n -- Command: arm semihosting_redirect (disable | tcp <port>\n     ['debug'|'stdio'|'all') Redirect semihosting messages to a\n     specified TCP port.\n\n     This command redirects debug (READC, WRITEC and WRITE0) and stdio\n     (READ, WRITE) semihosting operations to the specified TCP port.\n     The command allows to select which type of operations to redirect\n     (debug, stdio, all (default)).  Note: for stdio operations, only\n     I/O from/to ':tt' file descriptors are redirected.\n\n -- Command: arm semihosting_cmdline [enable|disable]\n     Set the command line to be passed to the debugger.\n\n          arm semihosting_cmdline argv0 argv1 argv2 ...\n\n     This option lets one set the command line arguments to be passed to\n     the program.  The first argument (argv0) is the program name in a\n     standard C environment (argv[0]).  Depending on the program (not\n     much programs look at argv[0]), argv0 is ignored and can be any\n     string.\n\n -- Command: arm semihosting_fileio [enable|disable]\n     Display status of semihosting fileio, after optionally changing\n     that status.\n\n     Enabling this option forwards semihosting I/O to GDB process using\n     the File-I/O remote protocol extension.  This is especially useful\n     for interacting with remote files or displaying console messages in\n     the debugger.\n\n -- Command: arm semihosting_resexit [enable|disable]\n     Enable resumable SEMIHOSTING_SYS_EXIT.\n\n     When SEMIHOSTING_SYS_EXIT is called outside a debug session, things\n     are simple, the openocd process calls exit() and passes the value\n     returned by the target.\n\n     When SEMIHOSTING_SYS_EXIT is called during a debug session, by\n     default execution returns to the debugger, leaving the debugger in\n     a HALT state, similar to the state entered when encountering a\n     break.\n\n     In some use cases, it is useful to have SEMIHOSTING_SYS_EXIT return\n     normally, as any semihosting call, and do not break to the\n     debugger.  The standard allows this to happen, but the condition to\n     trigger it is a bit obscure (\"by performing an RDI_Execute request\n     or equivalent\").\n\n     To make the SEMIHOSTING_SYS_EXIT call return normally, enable this\n     option (default: disabled).\n\n -- Command: arm semihosting_read_user_param\n     Read parameter of the semihosting call from the target.  Usable in\n     semihosting-user-cmd-0x10* event handlers, returning a string.\n\n     When the target makes semihosting call with operation number from\n     range 0x100- 0x107, an optional string parameter can be passed to\n     the server.  This parameter is valid during the run of the event\n     handlers and is accessible with this command.\n\n -- Command: arm semihosting_basedir [dir]\n     Set the base directory for semihosting I/O, either an absolute path\n     or a path relative to OpenOCD working directory.  Use \".\"  for the\n     current directory.\n\n16.4 ARMv4 and ARMv5 Architecture\n=================================\n\nThe ARMv4 and ARMv5 architectures are widely used in embedded systems,\nand introduced core parts of the instruction set in use today.  That\nincludes the Thumb instruction set, introduced in the ARMv4T variant.\n\n16.4.1 ARM7 and ARM9 specific commands\n--------------------------------------\n\nThese commands are specific to ARM7 and ARM9 cores, like ARM7TDMI,\nARM720T, ARM9TDMI, ARM920T or ARM926EJ-S. They are available in addition\nto the ARM commands, and any other core-specific commands that may be\navailable.\n\n -- Command: arm7_9 dbgrq [enable|disable]\n     Displays the value of the flag controlling use of the EmbeddedIce\n     DBGRQ signal to force entry into debug mode, instead of\n     breakpoints.  If a boolean parameter is provided, first assigns\n     that flag.\n\n     This should be safe for all but ARM7TDMI-S cores (like NXP LPC).\n     This feature is enabled by default on most ARM9 cores, including\n     ARM9TDMI, ARM920T, and ARM926EJ-S.\n\n -- Command: arm7_9 dcc_downloads [enable|disable]\n     Displays the value of the flag controlling use of the debug\n     communications channel (DCC) to write larger (>128 byte) amounts of\n     memory.  If a boolean parameter is provided, first assigns that\n     flag.\n\n     DCC downloads offer a huge speed increase, but might be unsafe,\n     especially with targets running at very low speeds.  This command\n     was introduced with OpenOCD rev.  60, and requires a few bytes of\n     working area.\n\n -- Command: arm7_9 fast_memory_access [enable|disable]\n     Displays the value of the flag controlling use of memory writes and\n     reads that don't check completion of the operation.  If a boolean\n     parameter is provided, first assigns that flag.\n\n     This provides a huge speed increase, especially with USB JTAG\n     cables (FT2232), but might be unsafe if used with targets running\n     at very low speeds, like the 32kHz startup clock of an AT91RM9200.\n\n16.4.2 ARM9 specific commands\n-----------------------------\n\nARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS)\ninteger processors.  Such cores include the ARM920T, ARM926EJ-S, and\nARM966.\n\n -- Command: arm9 vector_catch [all|none|list]\n     Vector Catch hardware provides a sort of dedicated breakpoint for\n     hardware events such as reset, interrupt, and abort.  You can use\n     this to conserve normal breakpoint resources, so long as you're not\n     concerned with code that branches directly to those hardware\n     vectors.\n\n     This always finishes by listing the current configuration.  If\n     parameters are provided, it first reconfigures the vector catch\n     hardware to intercept 'all' of the hardware vectors, 'none' of\n     them, or a list with one or more of the following: 'reset' 'undef'\n     'swi' 'pabt' 'dabt' 'irq' 'fiq'.\n\n16.4.3 ARM920T specific commands\n--------------------------------\n\nThese commands are available to ARM920T based CPUs, which are\nimplementations of the ARMv4T architecture built using the ARM9TDMI\ninteger core.  They are available in addition to the ARM, ARM7/ARM9, and\nARM9 commands.\n\n -- Command: arm920t cache_info\n     Print information about the caches found.  This allows to see\n     whether your target is an ARM920T (2x16kByte cache) or ARM922T\n     (2x8kByte cache).\n\n -- Command: arm920t cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.  This uses \"physical access\" and\n     the register number is as shown in bits 38..33 of table 9-9 in the\n     ARM920T TRM. (Not all registers can be written.)\n\n -- Command: arm920t read_cache filename\n     Dump the content of ICache and DCache to a file named 'filename'.\n\n -- Command: arm920t read_mmu filename\n     Dump the content of the ITLB and DTLB to a file named 'filename'.\n\n16.4.4 ARM926ej-s specific commands\n-----------------------------------\n\nThese commands are available to ARM926ej-s based CPUs, which are\nimplementations of the ARMv5TEJ architecture based on the ARM9EJ-S\ninteger core.  They are available in addition to the ARM, ARM7/ARM9, and\nARM9 commands.\n\nThe Feroceon cores also support these commands, although they are not\nbuilt from ARM926ej-s designs.\n\n -- Command: arm926ejs cache_info\n     Print information about the caches found.\n\n16.4.5 ARM966E specific commands\n--------------------------------\n\nThese commands are available to ARM966 based CPUs, which are\nimplementations of the ARMv5TE architecture.  They are available in\naddition to the ARM, ARM7/ARM9, and ARM9 commands.\n\n -- Command: arm966e cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.  The six bit REGNUM values are\n     bits 37..32 from table 7-2 of the ARM966E-S TRM. There is no\n     current control over bits 31..30 from that table, as required for\n     BIST support.\n\n16.4.6 XScale specific commands\n-------------------------------\n\nSome notes about the debug implementation on the XScale CPUs:\n\nThe XScale CPU provides a special debug-only mini-instruction cache\n(mini-IC) in which exception vectors and target-resident debug handler\ncode are placed by OpenOCD. In order to get access to the CPU, OpenOCD\nmust point vector 0 (the reset vector) to the entry of the debug\nhandler.  However, this means that the complete first cacheline in the\nmini-IC is marked valid, which makes the CPU fetch all exception\nhandlers from the mini-IC, ignoring the code in RAM.\n\nTo address this situation, OpenOCD provides the 'xscale vector_table'\ncommand, which allows the user to explicitly write individual entries to\neither the high or low vector table stored in the mini-IC.\n\nIt is recommended to place a pc-relative indirect branch in the vector\ntable, and put the branch destination somewhere in memory.  Doing so\nmakes sure the code in the vector table stays constant regardless of\ncode layout in memory:\n     _vectors:\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             ldr     pc,[pc,#0x100-8]\n             .org 0x100\n             .long real_reset_vector\n             .long real_ui_handler\n             .long real_swi_handler\n             .long real_pf_abort\n             .long real_data_abort\n             .long 0 /* unused */\n             .long real_irq_handler\n             .long real_fiq_handler\n\nAlternatively, you may choose to keep some or all of the mini-IC vector\ntable entries synced with those written to memory by your system\nsoftware.  The mini-IC can not be modified while the processor is\nexecuting, but for each vector table entry not previously defined using\nthe 'xscale vector_table' command, OpenOCD will copy the value from\nmemory to the mini-IC every time execution resumes from a halt.  This is\ndone for both high and low vector tables (although the table not in use\nmay not be mapped to valid memory, and in this case that copy operation\nwill silently fail).  This means that you will need to briefly halt\nexecution at some strategic point during system start-up; e.g., after\nthe software has initialized the vector table, but before exceptions are\nenabled.  A breakpoint can be used to accomplish this once the\nappropriate location in the start-up code has been identified.  A\nwatchpoint over the vector table region is helpful in finding the\nlocation if you're not sure.  Note that the same situation exists any\ntime the vector table is modified by the system software.\n\nThe debug handler must be placed somewhere in the address space using\nthe 'xscale debug_handler' command.  The allowed locations for the debug\nhandler are either (0x800 - 0x1fef800) or (0xfe000800 - 0xfffff800).\nThe default value is 0xfe000800.\n\nXScale has resources to support two hardware breakpoints and two\nwatchpoints.  However, the following restrictions on watchpoint\nfunctionality apply: (1) the value and mask arguments to the 'wp'\ncommand are not supported, (2) the watchpoint length must be a power of\ntwo and not less than four, and can not be greater than the watchpoint\naddress, and (3) a watchpoint with a length greater than four consumes\nall the watchpoint hardware resources.  This means that at any one time,\nyou can have enabled either two watchpoints with a length of four, or\none watchpoint with a length greater than four.\n\nThese commands are available to XScale based CPUs, which are\nimplementations of the ARMv5TE architecture.\n\n -- Command: xscale analyze_trace\n     Displays the contents of the trace buffer.\n\n -- Command: xscale cache_clean_address address\n     Changes the address used when cleaning the data cache.\n\n -- Command: xscale cache_info\n     Displays information about the CPU caches.\n\n -- Command: xscale cp15 regnum [value]\n     Display cp15 register REGNUM; else if a VALUE is provided, that\n     value is written to that register.\n\n -- Command: xscale debug_handler target address\n     Changes the address used for the specified target's debug handler.\n\n -- Command: xscale dcache [enable|disable]\n     Enables or disable the CPU's data cache.\n\n -- Command: xscale dump_trace filename\n     Dumps the raw contents of the trace buffer to 'filename'.\n\n -- Command: xscale icache [enable|disable]\n     Enables or disable the CPU's instruction cache.\n\n -- Command: xscale mmu [enable|disable]\n     Enables or disable the CPU's memory management unit.\n\n -- Command: xscale trace_buffer [enable|disable [fill [n] | wrap]]\n     Displays the trace buffer status, after optionally enabling or\n     disabling the trace buffer and modifying how it is emptied.\n\n -- Command: xscale trace_image filename [offset [type]]\n     Opens a trace image from 'filename', optionally rebasing its\n     segment addresses by OFFSET.  The image TYPE may be one of 'bin'\n     (binary), 'ihex' (Intel hex), 'elf' (ELF file), 's19' (Motorola\n     s19), 'mem', or 'builder'.\n\n -- Command: xscale vector_catch [mask]\n     Display a bitmask showing the hardware vectors to catch.  If the\n     optional parameter is provided, first set the bitmask to that\n     value.\n\n     The mask bits correspond with bit 16..23 in the DCSR:\n          0x01    Trap Reset\n          0x02    Trap Undefined Instructions\n          0x04    Trap Software Interrupt\n          0x08    Trap Prefetch Abort\n          0x10    Trap Data Abort\n          0x20    reserved\n          0x40    Trap IRQ\n          0x80    Trap FIQ\n\n -- Command: xscale vector_table [(low|high) index value]\n\n     Set an entry in the mini-IC vector table.  There are two tables:\n     one for low vectors (at 0x00000000), and one for high vectors\n     (0xFFFF0000), each holding the 8 exception vectors.  INDEX can be\n     1-7, because vector 0 points to the debug handler entry and can not\n     be overwritten.  VALUE holds the 32-bit opcode that is placed in\n     the mini-IC.\n\n     Without arguments, the current settings are displayed.\n\n16.5 ARMv6 Architecture\n=======================\n\n16.5.1 ARM11 specific commands\n------------------------------\n\n -- Command: arm11 memwrite burst [enable|disable]\n     Displays the value of the memwrite burst-enable flag, which is\n     enabled by default.  If a boolean parameter is provided, first\n     assigns that flag.  Burst writes are only used for memory writes\n     larger than 1 word.  They improve performance by assuming that the\n     CPU has read each data word over JTAG and completed its write\n     before the next word arrives, instead of polling for a status flag\n     to verify that completion.  This is usually safe, because JTAG runs\n     much slower than the CPU.\n\n -- Command: arm11 memwrite error_fatal [enable|disable]\n     Displays the value of the memwrite error_fatal flag, which is\n     enabled by default.  If a boolean parameter is provided, first\n     assigns that flag.  When set, certain memory write errors cause\n     earlier transfer termination.\n\n -- Command: arm11 step_irq_enable [enable|disable]\n     Displays the value of the flag controlling whether IRQs are enabled\n     during single stepping; they are disabled by default.  If a boolean\n     parameter is provided, first assigns that.\n\n -- Command: arm11 vcr [value]\n     Displays the value of the _Vector Catch Register (VCR)_,\n     coprocessor 14 register 7.  If VALUE is defined, first assigns\n     that.\n\n     Vector Catch hardware provides dedicated breakpoints for certain\n     hardware events.  The specific bit values are core-specific (as in\n     fact is using coprocessor 14 register 7 itself) but all current\n     ARM11 cores _except the ARM1176_ use the same six bits.\n\n16.6 ARMv7 and ARMv8 Architecture\n=================================\n\n16.6.1 ARMv7-A specific commands\n--------------------------------\n\n -- Command: cortex_a cache_info\n     display information about target caches\n\n -- Command: cortex_a dacrfixup [on|off]\n     Work around issues with software breakpoints when the program text\n     is mapped read-only by the operating system.  This option sets the\n     CP15 DACR to \"all-manager\" to bypass MMU permission checks on\n     memory access.  Defaults to 'off'.\n\n -- Command: cortex_a dbginit\n     Initialize core debug Enables debug by unlocking the Software Lock\n     and clearing sticky powerdown indications\n\n -- Command: cortex_a smp [on|off]\n     Display/set the current SMP mode\n\n -- Command: cortex_a smp_gdb [core_id]\n     Display/set the current core displayed in GDB\n\n -- Command: cortex_a maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping\n\n -- Command: cache_config l2x [base way]\n     configure l2x cache\n\n -- Command: cortex_a mmu dump [0|1|addr address [num_entries]]\n     Dump the MMU translation table from TTB0 or TTB1 register, or from\n     physical memory location ADDRESS.  When dumping the table from\n     ADDRESS, print at most NUM_ENTRIES page table entries.  NUM_ENTRIES\n     is optional, if omitted, the maximum possible (4096) entries are\n     printed.\n\n16.6.2 ARMv7-R specific commands\n--------------------------------\n\n -- Command: cortex_r4 dbginit\n     Initialize core debug Enables debug by unlocking the Software Lock\n     and clearing sticky powerdown indications\n\n -- Command: cortex_r4 maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping\n\n16.6.3 ARM CoreSight TPIU and SWO specific commands\n---------------------------------------------------\n\nARM CoreSight provides several modules to generate debugging information\ninternally (ITM, DWT and ETM). Their output is directed through TPIU or\nSWO modules to be captured externally either on an SWO pin (this\nconfiguration is called SWV) or on a synchronous parallel trace port.\n\nARM CoreSight provides independent HW blocks named TPIU and SWO each\nwith its own functionality.  Embedded in Cortex-M3 and M4, ARM provides\nan optional HW block that includes both TPIU and SWO functionalities and\nis again named TPIU, which causes quite some confusion.  The registers\nmap of all the TPIU and SWO implementations allows using a single driver\nthat detects at runtime the features available.\n\nThe 'tpiu' is used for either TPIU or SWO. A convenient alias 'swo' is\navailable to help distinguish, in scripts, the commands for SWO from the\ncommands for TPIU.\n\n -- Command: swo ...\n     Alias of 'tpiu ...'.  Can be used in scripts to distinguish the\n     commands for SWO from the commands for TPIU.\n\n -- Command: tpiu create tpiu_name configparams...\n     Creates a TPIU or a SWO object.  The two commands are equivalent.\n     Add the object in a list and add new commands ('TPIU_NAME') which\n     are used for various purposes including additional configuration.\n\n        * TPIU_NAME - the name of the TPIU or SWO object.  This name is\n          also used to create the object's command, referred to here as\n          '$tpiu_name', and in other places where the TPIU or SWO needs\n          to be identified.\n        * CONFIGPARAMS - all parameters accepted by '$tpiu_name\n          configure' are permitted.\n\n          You _must_ set here the AP and MEM_AP base_address through\n          '-dap DAP_NAME', '-ap-num AP_NUMBER' and '-baseaddr\n          BASE_ADDRESS'.\n\n -- Command: tpiu names\n     Lists all the TPIU or SWO objects created so far.  The two commands\n     are equivalent.\n\n -- Command: tpiu init\n     Initialize all registered TPIU and SWO. The two commands are\n     equivalent.  These commands are used internally during\n     initialization.  They can be issued at any time after the\n     initialization, too.\n\n -- Command: $tpiu_name cget queryparm\n     Each configuration parameter accepted by '$tpiu_name configure' can\n     be individually queried, to return its current value.  The\n     QUERYPARM is a parameter name accepted by that command, such as\n     '-dap'.\n\n -- Command: $tpiu_name configure configparams...\n     The options accepted by this command may also be specified as\n     parameters to 'tpiu create'.  Their values can later be queried one\n     at a time by using the '$tpiu_name cget' command.\n\n        * '-dap' DAP_NAME - names the DAP used to access this TPIU.\n          *Note DAP declaration: dapdeclaration, on how to create and\n          manage DAP instances.\n\n        * '-ap-num' AP_NUMBER - sets DAP access port for TPIU, AP_NUMBER\n          is the numeric index of the DAP AP the TPIU is connected to.\n\n        * '-baseaddr' BASE_ADDRESS - sets the TPIU BASE_ADDRESS where to\n          access the TPIU in the DAP AP memory space.\n\n        * '-protocol' ('sync'|'uart'|'manchester') - sets the protocol\n          used for trace data:\n             - 'sync' - synchronous parallel trace output mode, using\n               PORT_WIDTH data bits (default);\n             - 'uart' - use asynchronous SWO mode with NRZ (same as\n               regular UART 8N1) coding;\n             - 'manchester' - use asynchronous SWO mode with Manchester\n               coding.\n\n        * '-event' EVENT_NAME EVENT_BODY - assigns an event handler, a\n          TCL string which is evaluated when the event is triggered.\n          The events 'pre-enable', 'post-enable', 'pre-disable' and\n          'post-disable' are defined for TPIU/SWO. A typical use case\n          for the event 'pre-enable' is to enable the trace clock of the\n          TPIU.\n\n        * '-output' ('external'|':'PORT|FILENAME|'-') - specifies the\n          destination of the trace data:\n             - 'external' - configure TPIU/SWO to let user capture trace\n               output externally, either with an additional UART or with\n               a logic analyzer (default);\n             - '-' - configure TPIU/SWO and debug adapter to gather\n               trace data and forward it to 'tcl_trace' command;\n             - ':'PORT - configure TPIU/SWO and debug adapter to gather\n               trace data, open a TCP server at port PORT and send the\n               trace data to each connected client;\n             - FILENAME - configure TPIU/SWO and debug adapter to gather\n               trace data and append it to FILENAME, which can be either\n               a regular file or a named pipe.\n\n        * '-traceclk' TRACECLKIN_FREQ - mandatory parameter.  Specifies\n          the frequency in Hz of the trace clock.  For the TPIU embedded\n          in Cortex-M3 or M4, this is usually the same frequency as\n          HCLK. For protocol 'sync' this is twice the frequency of the\n          pin data rate.\n\n        * '-pin-freq' TRACE_FREQ - specifies the expected data rate in\n          Hz of the SWO pin.  Parameter used only on protocols 'uart'\n          and 'manchester'.  Can be omitted to let the adapter driver\n          select the maximum supported rate automatically.\n\n        * '-port-width' PORT_WIDTH - sets to PORT_WIDTH the width of the\n          synchronous parallel port used for trace output.  Parameter\n          used only on protocol 'sync'.  If not specified, default value\n          is 1.\n\n        * '-formatter' ('0'|'1') - specifies if the formatter should be\n          enabled.  Parameter used only on protocol 'sync'.  If not\n          specified, default value is 0.\n\n -- Command: $tpiu_name enable\n     Uses the parameters specified by the previous '$tpiu_name\n     configure' to configure and enable the TPIU or the SWO. If\n     required, the adapter is also configured and enabled to receive the\n     trace data.  This command can be used before 'init', but it will\n     take effect only after the 'init'.\n\n -- Command: $tpiu_name disable\n     Disable the TPIU or the SWO, terminating the receiving of the trace\n     data.\n\nExample usage:\n  1. STM32L152 board is programmed with an application that configures\n     PLL to provide core clock with 24MHz frequency; to use ITM output\n     it's enough to:\n          #include <libopencm3/cm3/itm.h>\n              ...\n              \tITM_STIM8(0) = c;\n              ...\n     (the most obvious way is to use the first stimulus port for printf,\n     for that this ITM_STIM8 assignment can be used inside _write(); to\n     make it blocking to avoid data loss, add 'while (!(ITM_STIM8(0) &\n     ITM_STIM_FIFOREADY));');\n  2. An FT2232H UART is connected to the SWO pin of the board;\n  3. Commands to configure UART for 12MHz baud rate:\n          $ setserial /dev/ttyUSB1 spd_cust divisor 5\n          $ stty -F /dev/ttyUSB1 38400\n     (FT2232H's base frequency is 60MHz, spd_cust allows to alias 38400\n     baud with our custom divisor to get 12MHz)\n  4. 'itmdump -f /dev/ttyUSB1 -d1'\n  5. OpenOCD invocation line:\n          openocd -f interface/stlink.cfg \\\n          -c \"transport select hla_swd\" \\\n          -f target/stm32l1.cfg \\\n          -c \"stm32l1.tpiu configure -protocol uart\" \\\n          -c \"stm32l1.tpiu configure -traceclk 24000000 -pin-freq 12000000\" \\\n          -c \"stm32l1.tpiu enable\"\n\n16.6.4 ARMv7-M specific commands\n--------------------------------\n\n -- Command: itm port PORT (0|1|on|off)\n     Enable or disable trace output for ITM stimulus PORT (counting from\n     0).  Port 0 is enabled on target creation automatically.\n\n -- Command: itm ports (0|1|on|off)\n     Enable or disable trace output for all ITM stimulus ports.\n\n16.6.5 Cortex-M specific commands\n---------------------------------\n\n -- Command: cortex_m maskisr (auto|on|off|steponly)\n     Control masking (disabling) interrupts during target step/resume.\n\n     The 'auto' option handles interrupts during stepping in a way that\n     they get served but don't disturb the program flow.  The step\n     command first allows pending interrupt handlers to execute, then\n     disables interrupts and steps over the next instruction where the\n     core was halted.  After the step interrupts are enabled again.  If\n     the interrupt handlers don't complete within 500ms, the step\n     command leaves with the core running.\n\n     The 'steponly' option disables interrupts during single-stepping\n     but enables them during normal execution.  This can be used as a\n     partial workaround for 702596 erratum in Cortex-M7 r0p1.  See\n     \"Cortex-M7 (AT610) and Cortex-M7 with FPU (AT611) Software\n     Developer Errata Notice\" from ARM for further details.\n\n     Note that a free hardware (FPB) breakpoint is required for the\n     'auto' option.  If no breakpoint is available at the time of the\n     step, then the step is taken with interrupts enabled, i.e.  the\n     same way the 'off' option does.\n\n     Default is 'auto'.\n\n -- Command: cortex_m vector_catch [all|none|list]\n     Vector Catch hardware provides dedicated breakpoints for certain\n     hardware events.\n\n     Parameters request interception of 'all' of these hardware event\n     vectors, 'none' of them, or one or more of the following:\n     'hard_err' for a HardFault exception; 'mm_err' for a MemManage\n     exception; 'bus_err' for a BusFault exception; 'irq_err',\n     'state_err', 'chk_err', or 'nocp_err' for various UsageFault\n     exceptions; or 'reset'.  If NVIC setup code does not enable them,\n     MemManage, BusFault, and UsageFault exceptions are mapped to\n     HardFault.  UsageFault checks for divide-by-zero and unaligned\n     access must also be explicitly enabled.\n\n     This finishes by listing the current vector catch configuration.\n\n -- Command: cortex_m reset_config (sysresetreq|vectreset)\n     Control reset handling if hardware srst is not fitted *Note\n     reset_config: reset_config.\n\n        - 'sysresetreq' use AIRCR SYSRESETREQ to reset system.\n        - 'vectreset' use AIRCR VECTRESET to reset system (default).\n\n     Using 'vectreset' is a safe option for Cortex-M3, M4 and M7 cores.\n     This however has the disadvantage of only resetting the core, all\n     peripherals are unaffected.  A solution would be to use a\n     'reset-init' event handler to manually reset the peripherals.\n     *Note Target Events: targetevents.\n\n     Cortex-M0, M0+ and M1 do not support 'vectreset', use 'sysresetreq'\n     instead.\n\n16.6.6 ARMv8-A specific commands\n--------------------------------\n\n -- Command: aarch64 cache_info\n     Display information about target caches\n\n -- Command: aarch64 dbginit\n     This command enables debugging by clearing the OS Lock and sticky\n     power-down and reset indications.  It also establishes the\n     expected, basic cross-trigger configuration the aarch64 target code\n     relies on.  In a configuration file, the command would typically be\n     called from a 'reset-end' or 'reset-deassert-post' handler, to\n     re-enable debugging after a system reset.  However, normally it is\n     not necessary to use the command at all.\n\n -- Command: aarch64 disassemble address [count]\n     Disassembles COUNT instructions starting at ADDRESS.  If COUNT is\n     not specified, a single instruction is disassembled.\n\n -- Command: aarch64 smp [on|off]\n     Display, enable or disable SMP handling mode.  The state of SMP\n     handling influences the way targets in an SMP group are handled by\n     the run control.  With SMP handling enabled, issuing halt or resume\n     to one core will trigger halting or resuming of all cores in the\n     group.  The command 'target smp' defines which targets are in the\n     SMP group.  With SMP handling disabled, all targets need to be\n     treated individually.\n\n -- Command: aarch64 maskisr [on|off]\n     Selects whether interrupts will be processed when single stepping.\n     The default configuration is 'on'.\n\n -- Command: $target_name catch_exc\n          [off|sec_el1|sec_el3|nsec_el1|nsec_el2]+\n     Cause '$target_name' to halt when an exception is taken.  Any\n     combination of Secure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is\n     valid.  The target '$target_name' will halt before taking the\n     exception.  In order to resume the target, the exception catch must\n     be disabled again with '$target_name catch_exc off'.  Issuing the\n     command without options prints the current configuration.\n\n16.7 EnSilica eSi-RISC Architecture\n===================================\n\neSi-RISC is a highly configurable microprocessor architecture for\nembedded systems provided by EnSilica.  (See:\n<http://www.ensilica.com/risc-ip/>.)\n\n16.7.1 eSi-RISC Configuration\n-----------------------------\n\n -- Command: esirisc cache_arch (harvard|von_neumann)\n     Configure the caching architecture.  Targets with the\n     'UNIFIED_ADDRESS_SPACE' option disabled employ a Harvard\n     architecture.  By default, 'von_neumann' is assumed.\n\n -- Command: esirisc hwdc (all|none|mask ...)\n     Configure hardware debug control.  The HWDC register controls which\n     exceptions return control back to the debugger.  Possible masks are\n     'all', 'none', 'reset', 'interrupt', 'syscall', 'error', and\n     'debug'.  By default, 'reset', 'error', and 'debug' are enabled.\n\n16.7.2 eSi-RISC Operation\n-------------------------\n\n -- Command: esirisc flush_caches\n     Flush instruction and data caches.  This command requires that the\n     target is halted when the command is issued and configured with an\n     instruction or data cache.\n\n16.7.3 eSi-Trace Configuration\n------------------------------\n\neSi-RISC targets may be configured with support for instruction tracing.\nTrace data may be written to an in-memory buffer or FIFO. If a FIFO is\nconfigured, DMA is typically employed to move trace data off-device\nusing a high-speed peripheral (eg.  SPI). Collected trace data is\nencoded in one of three different formats.  At a minimum, 'esirisc trace\nbuffer' or 'esirisc trace fifo' must be issued along with 'esirisc trace\nformat' before trace data can be collected.\n\nOpenOCD provides rudimentary analysis of collected trace data.  If more\ndetail is needed, collected trace data can be dumped to a file and\nprocessed by external tooling.\n\n     Issues: OpenOCD is unable to process trace data sent to a FIFO. A\n     potential workaround for this issue is to configure DMA to copy\n     trace data to an in-memory buffer, which can then be passed to the\n     'esirisc trace analyze' and 'esirisc trace dump' commands.\n\n     It is possible to corrupt trace data when using a FIFO if the\n     peripheral responsible for draining data from the FIFO is not fast\n     enough.  This can be managed by enabling flow control, however this\n     can impact timing-sensitive software operation on the CPU.\n\n -- Command: esirisc trace buffer address size [wrap]\n     Configure trace buffer using the provided address and size.  If the\n     'wrap' option is specified, trace collection will continue once the\n     end of the buffer is reached.  By default, wrap is disabled.\n\n -- Command: esirisc trace fifo address\n     Configure trace FIFO using the provided address.\n\n -- Command: esirisc trace flow_control (enable|disable)\n     Enable or disable stalling the CPU to collect trace data.  By\n     default, flow control is disabled.\n\n -- Command: esirisc trace format (full|branch|icache) pc_bits\n     Configure trace format and number of PC bits to be captured.\n     'pc_bits' must be within 1 and 31 as the LSB is not collected.  If\n     external tooling is used to analyze collected trace data, these\n     values must match.\n\n     Supported trace formats:\n        * 'full' capture full trace data, allowing execution history and\n          timing to be determined.\n        * 'branch' capture taken branch instructions and branch target\n          addresses.\n        * 'icache' capture instruction cache misses.\n\n -- Command: esirisc trace trigger start (condition) [start_data\n          start_mask]\n     Configure trigger start condition using the provided start data and\n     mask.  A brief description of each condition is provided below; for\n     more detail on how these values are used, see the eSi-RISC\n     Architecture Manual.\n\n     Supported conditions:\n        * 'none' manual tracing (see 'esirisc trace start').\n        * 'pc' start tracing if the PC matches start data and mask.\n        * 'load' start tracing if the effective address of a load\n          instruction matches start data and mask.\n        * 'store' start tracing if the effective address of a store\n          instruction matches start data and mask.\n        * 'exception' start tracing if the EID of an exception matches\n          start data and mask.\n        * 'eret' start tracing when an 'ERET' instruction is executed.\n        * 'wait' start tracing when a 'WAIT' instruction is executed.\n        * 'stop' start tracing when a 'STOP' instruction is executed.\n        * 'high' start tracing when an external signal is a logical\n          high.\n        * 'low' start tracing when an external signal is a logical low.\n\n -- Command: esirisc trace trigger stop (condition) [stop_data\n          stop_mask]\n     Configure trigger stop condition using the provided stop data and\n     mask.  A brief description of each condition is provided below; for\n     more detail on how these values are used, see the eSi-RISC\n     Architecture Manual.\n\n     Supported conditions:\n        * 'none' manual tracing (see 'esirisc trace stop').\n        * 'pc' stop tracing if the PC matches stop data and mask.\n        * 'load' stop tracing if the effective address of a load\n          instruction matches stop data and mask.\n        * 'store' stop tracing if the effective address of a store\n          instruction matches stop data and mask.\n        * 'exception' stop tracing if the EID of an exception matches\n          stop data and mask.\n        * 'eret' stop tracing when an 'ERET' instruction is executed.\n        * 'wait' stop tracing when a 'WAIT' instruction is executed.\n        * 'stop' stop tracing when a 'STOP' instruction is executed.\n\n -- Command: esirisc trace trigger delay (trigger) [cycles]\n     Configure trigger start/stop delay in clock cycles.\n\n     Supported triggers:\n        * 'none' no delay to start or stop collection.\n        * 'start' delay 'cycles' after trigger to start collection.\n        * 'stop' delay 'cycles' after trigger to stop collection.\n        * 'both' delay 'cycles' after both triggers to start or stop\n          collection.\n\n16.7.4 eSi-Trace Operation\n--------------------------\n\n -- Command: esirisc trace init\n     Initialize trace collection.  This command must be called any time\n     the configuration changes.  If a trace buffer has been configured,\n     the contents will be overwritten when trace collection starts.\n\n -- Command: esirisc trace info\n     Display trace configuration.\n\n -- Command: esirisc trace status\n     Display trace collection status.\n\n -- Command: esirisc trace start\n     Start manual trace collection.\n\n -- Command: esirisc trace stop\n     Stop manual trace collection.\n\n -- Command: esirisc trace analyze [address size]\n     Analyze collected trace data.  This command may only be used if a\n     trace buffer has been configured.  If a trace FIFO has been\n     configured, trace data must be copied to an in-memory buffer\n     identified by the 'address' and 'size' options using DMA.\n\n -- Command: esirisc trace dump [address size] filename\n     Dump collected trace data to file.  This command may only be used\n     if a trace buffer has been configured.  If a trace FIFO has been\n     configured, trace data must be copied to an in-memory buffer\n     identified by the 'address' and 'size' options using DMA.\n\n16.8 Intel Architecture\n=======================\n\nIntel Quark X10xx is the first product in the Quark family of SoCs.  It\nis an IA-32 (Pentium x86 ISA) compatible SoC. The core CPU in the X10xx\nis codenamed Lakemont.  Lakemont version 1 (LMT1) is used in X10xx.  The\nCPU TAP (Lakemont TAP) is used for software debug and the CLTAP is used\nfor SoC level operations.  Useful docs are here:\nhttps://communities.intel.com/community/makers/documentation\n   * Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for\n     doc num 330015)\n   * Intel Quark SoC X1000 Debug Operations User Guide (web search for\n     doc num 329866)\n   * Intel Quark SoC X1000 Datasheet (web search for doc num 329676)\n\n16.8.1 x86 32-bit specific commands\n-----------------------------------\n\nThe three main address spaces for x86 are memory, I/O and configuration\nspace.  These commands allow a user to read and write to the 64Kbyte I/O\naddress space.\n\n -- Command: x86_32 idw address\n     Display the contents of a 32-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 idh address\n     Display the contents of a 16-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 idb address\n     Display the contents of a 8-bit I/O port from address range 0x0000\n     - 0xffff.\n\n -- Command: x86_32 iww address\n     Write the contents of a 32-bit I/O port to address range 0x0000 -\n     0xffff.\n\n -- Command: x86_32 iwh address\n     Write the contents of a 16-bit I/O port to address range 0x0000 -\n     0xffff.\n\n -- Command: x86_32 iwb address\n     Write the contents of a 8-bit I/O port to address range 0x0000 -\n     0xffff.\n\n16.9 OpenRISC Architecture\n==========================\n\nThe OpenRISC CPU is a soft core.  It is used in a programmable SoC which\ncan be configured with any of the TAP / Debug Unit available.\n\n16.9.1 TAP and Debug Unit selection commands\n--------------------------------------------\n\n -- Command: tap_select (vjtag|mohor|xilinx_bscan)\n     Select between the Altera Virtual JTAG , Xilinx Virtual JTAG and\n     Mohor TAP.\n -- Command: du_select (adv|mohor) [option]\n     Select between the Advanced Debug Interface and the classic one.\n\n     An option can be passed as a second argument to the debug unit.\n\n     When using the Advanced Debug Interface, option = 1 means the RTL\n     core is configured with ADBG_USE_HISPEED = 1.  This configuration\n     skips status checking between bytes while doing read or write\n     bursts.\n\n16.9.2 Registers commands\n-------------------------\n\n -- Command: addreg [name] [address] [feature] [reg_group]\n     Add a new register in the cpu register list.  This register will be\n     included in the generated target descriptor file.\n\n     *[feature]* must be \"org.gnu.gdb.or1k.group[0..10]\".\n\n     *[reg_group]* can be anything.  The default register list defines\n     \"system\", \"dmmu\", \"immu\", \"dcache\", \"icache\", \"mac\", \"debug\",\n     \"perf\", \"power\", \"pic\" and \"timer\" groups.\n\n     _example:_\n          addreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n16.10 RISC-V Architecture\n=========================\n\nRISC-V (http://riscv.org/) is a free and open ISA. OpenOCD supports JTAG\ndebug of RV32 and RV64 cores in heterogeneous multicore systems of up to\n32 harts.  (It's possible to increase this limit to 1024 by changing\nRISCV_MAX_HARTS in riscv.h.)  OpenOCD primarily supports 0.13 of the\nRISC-V Debug Specification, but there is also support for legacy targets\nthat implement version 0.11.\n\n16.10.1 RISC-V Terminology\n--------------------------\n\nA _hart_ is a hardware thread.  A hart may share resources (eg.  FPU)\nwith another hart, or may be a separate core.  RISC-V treats those the\nsame, and OpenOCD exposes each hart as a separate core.\n\n16.10.2 Vector Registers\n------------------------\n\nFor harts that implement the vector extension, OpenOCD provides access\nto the relevant CSRs, as well as the vector registers (v0-v31).  The\nsize of each vector register is dependent on the value of vlenb.  RISC-V\nallows each vector register to be divided into selected-width elements,\nand this division can be changed at run-time.  Because OpenOCD cannot\nupdate register definitions at run-time, it exposes each vector register\nto gdb as a union of fields of vectors so that users can easily access\nindividual bytes, shorts, words, longs, and quads inside each vector\nregister.  It is left to gdb or higher-level debuggers to present this\ndata in a more intuitive format.\n\nIn the XML register description, the vector registers (when vlenb=16)\nlook as follows:\n\n     <feature name=\"org.gnu.gdb.riscv.vector\">\n     <vector id=\"bytes\" type=\"uint8\" count=\"16\"/>\n     <vector id=\"shorts\" type=\"uint16\" count=\"8\"/>\n     <vector id=\"words\" type=\"uint32\" count=\"4\"/>\n     <vector id=\"longs\" type=\"uint64\" count=\"2\"/>\n     <vector id=\"quads\" type=\"uint128\" count=\"1\"/>\n     <union id=\"riscv_vector\">\n     <field name=\"b\" type=\"bytes\"/>\n     <field name=\"s\" type=\"shorts\"/>\n     <field name=\"w\" type=\"words\"/>\n     <field name=\"l\" type=\"longs\"/>\n     <field name=\"q\" type=\"quads\"/>\n     </union>\n     <reg name=\"v0\" bitsize=\"128\" regnum=\"4162\" save-restore=\"no\"\n             type=\"riscv_vector\" group=\"vector\"/>\n     ...\n     <reg name=\"v31\" bitsize=\"128\" regnum=\"4193\" save-restore=\"no\"\n             type=\"riscv_vector\" group=\"vector\"/>\n     </feature>\n\n16.10.3 RISC-V Debug Configuration Commands\n-------------------------------------------\n\n -- Config Command: riscv expose_csrs n[-m|=name] [...]\n     Configure which CSRs to expose in addition to the standard ones.\n     The CSRs to expose can be specified as individual register numbers\n     or register ranges (inclusive).  For the individually listed CSRs,\n     a human-readable name can optionally be set using the 'n=name'\n     syntax, which will get 'csr_' prepended to it.  If no name is\n     provided, the register will be named 'csr<n>'.\n\n     By default OpenOCD attempts to expose only CSRs that are mentioned\n     in a spec, and then only if the corresponding extension appears to\n     be implemented.  This command can be used if OpenOCD gets this\n     wrong, or if the target implements custom CSRs.\n\n          # Expose a single RISC-V CSR number 128 under the name \"csr128\":\n          $_TARGETNAME expose_csrs 128\n\n          # Expose multiple RISC-V CSRs 128..132 under names \"csr128\" through \"csr132\":\n          $_TARGETNAME expose_csrs 128-132\n\n          # Expose a single RISC-V CSR number 1996 under custom name \"csr_myregister\":\n          $_TARGETNAME expose_csrs 1996=myregister\n\n -- Config Command: riscv expose_custom n[-m|=name] [...]\n     The RISC-V Debug Specification allows targets to expose custom\n     registers through abstract commands.  (See Section 3.5.1.1 in that\n     document.)  This command configures individual registers or\n     register ranges (inclusive) that shall be exposed.  Number 0\n     indicates the first custom register, whose abstract command number\n     is 0xc000.  For individually listed registers, a human-readable\n     name can be optionally provided using the 'n=name' syntax, which\n     will get 'custom_' prepended to it.  If no name is provided, the\n     register will be named 'custom<n>'.\n\n          # Expose one RISC-V custom register with number 0xc010 (0xc000 + 16)\n          # under the name \"custom16\":\n          $_TARGETNAME expose_custom 16\n\n          # Expose a range of RISC-V custom registers with numbers 0xc010 .. 0xc018\n          # (0xc000+16 .. 0xc000+24) under the names \"custom16\" through \"custom24\":\n          $_TARGETNAME expose_custom 16-24\n\n          # Expose one RISC-V custom register with number 0xc020 (0xc000 + 32) under\n          # user-defined name \"custom_myregister\":\n          $_TARGETNAME expose_custom 32=myregister\n\n -- Command: riscv set_command_timeout_sec [seconds]\n     Set the wall-clock timeout (in seconds) for individual commands.\n     The default should work fine for all but the slowest targets (eg.\n     simulators).\n\n -- Command: riscv set_reset_timeout_sec [seconds]\n     Set the maximum time to wait for a hart to come out of reset after\n     reset is deasserted.\n\n -- Command: riscv set_scratch_ram none|[address]\n     Set the address of 16 bytes of scratch RAM the debugger can use, or\n     'none'.  This is used to access 64-bit floating point registers on\n     32-bit targets.\n\n -- Command: riscv set_mem_access method1 [method2] [method3]\n     Specify which RISC-V memory access method(s) shall be used, and in\n     which order of priority.  At least one method must be specified.\n\n     Available methods are:\n        * 'progbuf' - Use RISC-V Debug Program Buffer to access memory.\n        * 'sysbus' - Access memory via RISC-V Debug System Bus\n          interface.\n        * 'abstract' - Access memory via RISC-V Debug abstract commands.\n\n     By default, all memory access methods are enabled in the following\n     order: 'progbuf sysbus abstract'.\n\n     This command can be used to change the memory access methods if the\n     default behavior is not suitable for a particular target.\n\n -- Command: riscv set_enable_virtual on|off\n     When on, memory accesses are performed on physical or virtual\n     memory depending on the current system configuration.  When off\n     (default), all memory accessses are performed on physical memory.\n\n -- Command: riscv set_enable_virt2phys on|off\n     When on (default), memory accesses are performed on physical or\n     virtual memory depending on the current satp configuration.  When\n     off, all memory accessses are performed on physical memory.\n\n -- Command: riscv resume_order normal|reversed\n     Some software assumes all harts are executing nearly continuously.\n     Such software may be sensitive to the order that harts are resumed\n     in.  On harts that don't support hasel, this option allows the user\n     to choose the order the harts are resumed in.  If you are using\n     this option, it's probably masking a race condition problem in your\n     code.\n\n     Normal order is from lowest hart index to highest.  This is the\n     default behavior.  Reversed order is from highest hart index to\n     lowest.\n\n -- Command: riscv set_ir (idcode|dtmcs|dmi) [value]\n     Set the IR value for the specified JTAG register.  This is useful,\n     for example, when using the existing JTAG interface on a Xilinx\n     FPGA by way of BSCANE2 primitives that only permit a limited\n     selection of IR values.\n\n     When utilizing version 0.11 of the RISC-V Debug Specification,\n     'dtmcs' and 'dmi' set the IR values for the DTMCONTROL and DBUS\n     registers, respectively.\n\n -- Command: riscv use_bscan_tunnel value\n     Enable or disable use of a BSCAN tunnel to reach DM. Supply the\n     width of the DM transport TAP's instruction register to enable.\n     Supply a value of 0 to disable.\n\n -- Command: riscv set_ebreakm on|off\n     Control dcsr.ebreakm.  When on (default), M-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n -- Command: riscv set_ebreaks on|off\n     Control dcsr.ebreaks.  When on (default), S-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n -- Command: riscv set_ebreaku on|off\n     Control dcsr.ebreaku.  When on (default), U-mode ebreak\n     instructions trap to OpenOCD. When off, they generate a breakpoint\n     exception handled internally.\n\n16.10.4 RISC-V Authentication Commands\n--------------------------------------\n\nThe following commands can be used to authenticate to a RISC-V system.\nEg.  a trivial challenge-response protocol could be implemented as\nfollows in a configuration file, immediately following 'init':\n     set challenge [riscv authdata_read]\n     riscv authdata_write [expr {$challenge + 1}]\n\n -- Command: riscv authdata_read\n     Return the 32-bit value read from authdata.\n\n -- Command: riscv authdata_write value\n     Write the 32-bit value to authdata.\n\n16.10.5 RISC-V DMI Commands\n---------------------------\n\nThe following commands allow direct access to the Debug Module\nInterface, which can be used to interact with custom debug features.\n\n -- Command: riscv dmi_read address\n     Perform a 32-bit DMI read at address, returning the value.\n\n -- Command: riscv dmi_write address value\n     Perform a 32-bit DMI write of value at address.\n\n16.11 ARC Architecture\n======================\n\nSynopsys DesignWare ARC Processors are a family of 32-bit CPUs that SoC\ndesigners can optimize for a wide range of uses, from deeply embedded to\nhigh-performance host applications in a variety of market segments.  See\nmore at:\n<http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/Pages/default.aspx>.\nOpenOCD currently supports ARC EM processors.  There is a set\nARC-specific OpenOCD commands that allow low-level access to the core\nand provide necessary support for ARC extensibility and configurability\ncapabilities.  ARC processors has much more configuration capabilities\nthan most of the other processors and in addition there is an extension\ninterface that allows SoC designers to add custom registers and\ninstructions.  For the OpenOCD that mostly means that set of core and\nAUX registers in target will vary and is not fixed for a particular\nprocessor model.  To enable extensibility several TCL commands are\nprovided that allow to describe those optional registers in OpenOCD\nconfiguration files.  Moreover those commands allow for a dynamic target\nfeatures discovery.\n\n16.11.1 General ARC commands\n----------------------------\n\n -- Config Command: arc add-reg configparams\n\n     Add a new register to processor target.  By default newly created\n     register is marked as not existing.  CONFIGPARAMS must have\n     following required arguments:\n\n        * '-name' name\n          Name of a register.\n\n        * '-num' number\n          Architectural register number: core register number or AUX\n          register number.\n\n        * '-feature' XML_feature\n          Name of GDB XML target description feature.\n\n     CONFIGPARAMS may have following optional arguments:\n\n        * '-gdbnum' number\n          GDB register number.  It is recommended to not assign GDB\n          register number manually, because there would be a risk that\n          two register will have same number.  When register GDB number\n          is not set with this option, then register will get a previous\n          register number + 1.  This option is required only for those\n          registers that must be at particular address expected by GDB.\n\n        * '-core'\n          This option specifies that register is a core registers.  If\n          not - this is an AUX register.  AUX registers and core\n          registers reside in different address spaces.\n\n        * '-bcr'\n          This options specifies that register is a BCR register.  BCR\n          means Build Configuration Registers - this is a special type\n          of AUX registers that are read only and non-volatile, that is\n          - they never change their value.  Therefore OpenOCD never\n          invalidates values of those registers in internal caches.\n          Because BCR is a type of AUX registers, this option cannot be\n          used with '-core'.\n\n        * '-type' type_name\n          Name of type of this register.  This can be either one of the\n          basic GDB types, or a custom types described with 'arc\n          add-reg-type-[flags|struct]'.\n\n        * '-g'\n          If specified then this is a \"general\" register.  General\n          registers are always read by OpenOCD on context save (when\n          core has just been halted) and is always transferred to GDB\n          client in a response to g-packet.  Contrary to this,\n          non-general registers are read and sent to GDB client\n          on-demand.  In general it is not recommended to apply this\n          option to custom registers.\n\n -- Config Command: arc add-reg-type-flags -name name flags...\n     Adds new register type of \"flags\" class.  \"Flags\" types can contain\n     only one-bit fields.  Each flag definition looks like '-flag name\n     bit-position'.\n\n -- Config Command: arc add-reg-type-struct -name name structs...\n     Adds new register type of \"struct\" class.  \"Struct\" types can\n     contain either bit-fields or fields of other types, however at the\n     moment only bit fields are supported.  Structure bit field\n     definition looks like '-bitfield name startbit endbit'.\n\n -- Command: arc get-reg-field reg-name field-name\n     Returns value of bit-field in a register.  Register must be\n     \"struct\" register type, *Note add-reg-type-struct::.  command\n     definition.\n\n -- Command: arc set-reg-exists reg-names...\n     Specify that some register exists.  Any amount of names can be\n     passed as an argument for a single command invocation.\n\n16.11.2 ARC JTAG commands\n-------------------------\n\n -- Command: arc jtag set-aux-reg regnum value\n     This command writes value to AUX register via its number.  This\n     command access register in target directly via JTAG, bypassing any\n     OpenOCD internal caches, therefore it is unsafe to use if that\n     register can be operated by other means.\n\n -- Command: arc jtag set-core-reg regnum value\n     This command is similar to 'arc jtag set-aux-reg' but is for core\n     registers.\n\n -- Command: arc jtag get-aux-reg regnum\n     This command returns the value storded in AUX register via its\n     number.  This commands access register in target directly via JTAG,\n     bypassing any OpenOCD internal caches, therefore it is unsafe to\n     use if that register can be operated by other means.\n\n -- Command: arc jtag get-core-reg regnum\n     This command is similar to 'arc jtag get-aux-reg' but is for core\n     registers.\n\n16.12 STM8 Architecture\n=======================\n\nSTM8 (http://st.com/stm8/) is a 8-bit microcontroller platform from\nSTMicroelectronics, based on a proprietary 8-bit core architecture.\n\nOpenOCD supports debugging STM8 through the STMicroelectronics debug\nprotocol SWIM, *note SWIM: swimtransport.\n\n16.13 Xtensa Architecture\n=========================\n\nXtensa processors are based on a modular, highly flexible 32-bit RISC\narchitecture that can easily scale from a tiny, cache-less controller or\ntask engine to a high-performance SIMD/VLIW DSP provided by Cadence.\n<https://www.cadence.com/en_US/home/tools/ip/tensilica-ip/tensilica-xtensa-controllers-and-extensible-processors.html>.\n\nOpenOCD supports generic Xtensa processors implementation which can be\ncustomized by simply providing vendor-specific core configuration which\ncontrols every configurable Xtensa architecture option, e.g.  number of\naddress registers, exceptions, reduced size instructions support, memory\nbanks configuration etc.  Also OpenOCD supports SMP configurations for\nXtensa processors with any number of cores and allows to configure their\ndebug signals interconnection (so-called \"break/stall networks\") which\ncontrol how debug signals are distributed among cores.  Xtensa \"break\nnetworks\" are compatible with ARM's Cross Trigger Interface (CTI). For\ndebugging code on Xtensa chips OpenOCD uses JTAG protocol.  Currently\nOpenOCD implements several Epsressif Xtensa-based chips of ESP32 family\n(https://www.espressif.com/en/products/socs).\n\n16.13.1 General Xtensa Commands\n-------------------------------\n\n -- Command: xtensa set_permissive (0|1)\n     By default accessing memory beyond defined regions is forbidden.\n     This commnd controls memory access address check.  When set to (1),\n     skips access controls and address range check before read/write\n     memory.\n\n -- Command: xtensa maskisr (on|off)\n     Selects whether interrupts will be disabled during stepping over\n     single instruction.  The default configuration is (off).\n\n -- Command: xtensa smpbreak [none|breakinout|runstall] | [BreakIn]\n          [BreakOut] [RunStallIn] [DebugModeOut]\n     Configures debug signals connection (\"break network\") for currently\n     selected core.\n        * 'none' - Core's \"break/stall network\" is disconnected.  Core\n          is not affected by any debug signal from other cores.\n        * 'breakinout' - Core's \"break network\" is fully connected\n          (break inputs and outputs are enabled).  Core will receive\n          debug break signals from other cores and send such signals to\n          them.  For example when another core is stopped due to\n          breakpoint hit this core will be stopped too and vice versa.\n        * 'runstall' - Core's \"stall network\" is fully connected (stall\n          inputs and outputs are enabled).  This feature is not well\n          implemented and tested yet.\n        * 'BreakIn' - Core's \"break-in\" signal is enabled.  Core will\n          receive debug break signals from other cores.  For example\n          when another core is stopped due to breakpoint hit this core\n          will be stopped too.\n        * 'BreakOut' - Core's \"break-out\" signal is enabled.  Core will\n          send debug break signal to other cores.  For example when this\n          core is stopped due to breakpoint hit other cores with enabled\n          break-in signals will be stopped too.\n        * 'RunStallIn' - Core's \"runstall-in\" signal is enabled.  This\n          feature is not well implemented and tested yet.\n        * 'DebugModeOut' - Core's \"debugmode-out\" signal is enabled.\n          This feature is not well implemented and tested yet.\n\n -- Command: xtensa perfmon_enable <counter_id> <select> [mask]\n          [kernelcnt] [tracelevel]\n     Enable and start performance counter.\n        * 'counter_id' - Counter ID (0-1).\n        * 'select' - Selects performance metric to be counted by the\n          counter, e.g.  0 - CPU cycles, 2 - retired instructions.\n        * 'mask' - Selects input subsets to be counted (counter will\n          increment only once even if more than one condition\n          corresponding to a mask bit occurs).\n        * 'kernelcnt' - 0 - count events with \"CINTLEVEL <= tracelevel\",\n          1 - count events with \"CINTLEVEL > tracelevel\".\n        * 'tracelevel' - Compares this value to \"CINTLEVEL\" when\n          deciding whether to count.\n\n -- Command: xtensa perfmon_dump (counter_id)\n     Dump performance counter value.  If no argument specified, dumps\n     all counters.\n\n -- Command: xtensa tracestart [pc <pcval>/[<maskbitcount>]] [after <n>\n          [ins|words]]\n     Set up and start a HW trace.  Optionally set PC address range to\n     trigger tracing stop when reached during program execution.  This\n     command also allows to specify the amount of data to capture after\n     stop trigger activation.\n        * 'pcval' - PC value which will trigger trace data collection\n          stop.\n        * 'maskbitcount' - PC value mask.\n        * 'n' - Maximum number of instructions/words to capture after\n          trace stop trigger.\n\n -- Command: xtensa tracestop\n     Stop current trace as started by the tracestart command.\n\n -- Command: xtensa tracedump <outfile>\n     Dump trace memory to a file.\n\n16.14 Software Debug Messages and Tracing\n=========================================\n\nOpenOCD can process certain requests from target software, when the\ntarget uses appropriate libraries.  The most powerful mechanism is\nsemihosting, but there is also a lighter weight mechanism using only the\nDCC channel.\n\nCurrently 'target_request debugmsgs' is supported only for 'arm7_9' and\n'cortex_m' cores.  These messages are received as part of target\npolling, so you need to have 'poll on' active to receive them.  They are\nintrusive in that they will affect program execution times.  If that is\na problem, *note ARM Hardware Tracing: armhardwaretracing.\n\nSee 'libdcc' in the contrib dir for more details.  In addition to\nsending strings, characters, and arrays of various size integers from\nthe target, 'libdcc' also exports a software trace point mechanism.  The\ntarget being debugged may issue trace messages which include a 24-bit\n\"trace point\" number.  Trace point support includes two distinct\nmechanisms, each supported by a command:\n\n   * _History_ ...  A circular buffer of trace points can be set up, and\n     then displayed at any time.  This tracks where code has been, which\n     can be invaluable in finding out how some fault was triggered.\n\n     The buffer may overflow, since it collects records continuously.\n     It may be useful to use some of the 24 bits to represent a\n     particular event, and other bits to hold data.\n\n   * _Counting_ ...  An array of counters can be set up, and then\n     displayed at any time.  This can help establish code coverage and\n     identify hot spots.\n\n     The array of counters is directly indexed by the trace point\n     number, so trace points with higher numbers are not counted.\n\nLinux-ARM kernels have a \"Kernel low-level debugging via EmbeddedICE DCC\nchannel\" option (CONFIG_DEBUG_ICEDCC, depends on CONFIG_DEBUG_LL) which\nuses this mechanism to deliver messages before a serial console can be\nactivated.  This is not the same format used by 'libdcc'.  Other\nsoftware, such as the U-Boot boot loader, sometimes does the same thing.\n\n -- Command: target_request debugmsgs [enable|disable|charmsg]\n     Displays current handling of target DCC message requests.  These\n     messages may be sent to the debugger while the target is running.\n     The optional 'enable' and 'charmsg' parameters both enable the\n     messages, while 'disable' disables them.\n\n     With 'charmsg' the DCC words each contain one character, as used by\n     Linux with CONFIG_DEBUG_ICEDCC; otherwise the libdcc format is\n     used.\n\n -- Command: trace history [clear|count]\n     With no parameter, displays all the trace points that have\n     triggered in the order they triggered.  With the parameter 'clear',\n     erases all current trace history records.  With a COUNT parameter,\n     allocates space for that many history records.\n\n -- Command: trace point [clear|identifier]\n     With no parameter, displays all trace point identifiers and how\n     many times they have been triggered.  With the parameter 'clear',\n     erases all current trace point counters.  With a numeric IDENTIFIER\n     parameter, creates a new a trace point counter and associates it\n     with that identifier.\n\n     _Important:_ The identifier and the trace point number are not\n     related except by this command.  These trace point numbers always\n     start at zero (from server startup, or after 'trace point clear')\n     and count up from there.\n\n\u001f\nFile: openocd.info,  Node: JTAG Commands,  Next: Boundary Scan Commands,  Prev: Architecture and Core Commands,  Up: Top\n\n17 JTAG Commands\n****************\n\nMost general purpose JTAG commands have been presented earlier.  (*Note\nJTAG Speed: jtagspeed, *note Reset Configuration::, and *note TAP\nDeclaration::.)  Lower level JTAG commands, as presented here, may be\nneeded to work with targets which require special attention during\noperations such as reset or initialization.\n\nTo use these commands you will need to understand some of the basics of\nJTAG, including:\n\n   * A JTAG scan chain consists of a sequence of individual TAP devices\n     such as a CPUs.\n   * Control operations involve moving each TAP through the same\n     standard state machine (in parallel) using their shared TMS and\n     clock signals.\n   * Data transfer involves shifting data through the chain of\n     instruction or data registers of each TAP, writing new register\n     values while the reading previous ones.\n   * Data register sizes are a function of the instruction active in a\n     given TAP, while instruction register sizes are fixed for each TAP.\n     All TAPs support a BYPASS instruction with a single bit data\n     register.\n   * The way OpenOCD differentiates between TAP devices is by shifting\n     different instructions into (and out of) their instruction\n     registers.\n\n17.1 Low Level JTAG Commands\n============================\n\nThese commands are used by developers who need to access JTAG\ninstruction or data registers, possibly controlling the order of TAP\nstate transitions.  If you're not debugging OpenOCD internals, or\nbringing up a new JTAG adapter or a new type of TAP device (like a CPU\nor JTAG router), you probably won't need to use these commands.  In a\ndebug session that doesn't use JTAG for its transport protocol, these\ncommands are not available.\n\n -- Command: drscan tap [numbits value]+ [-endstate tap_state]\n     Loads the data register of TAP with a series of bit fields that\n     specify the entire register.  Each field is NUMBITS bits long with\n     a numeric VALUE (hexadecimal encouraged).  The return value holds\n     the original value of each of those fields.\n\n     For example, a 38 bit number might be specified as one field of 32\n     bits then one of 6 bits.  _For portability, never pass fields which\n     are more than 32 bits long.  Many OpenOCD implementations do not\n     support 64-bit (or larger) integer values._\n\n     All TAPs other than TAP must be in BYPASS mode.  The single bit in\n     their data registers does not matter.\n\n     When TAP_STATE is specified, the JTAG state machine is left in that\n     state.  For example DRPAUSE might be specified, so that more\n     instructions can be issued before re-entering the RUN/IDLE state.\n     If the end state is not specified, the RUN/IDLE state is entered.\n\n          Warning: OpenOCD does not record information about data\n          register lengths, so _it is important that you get the bit\n          field lengths right_.  Remember that different JTAG\n          instructions refer to different data registers, which may have\n          different lengths.  Moreover, those lengths may not be fixed;\n          the SCAN_N instruction can change the length of the register\n          accessed by the INTEST instruction (by connecting a different\n          scan chain).\n\n -- Command: flush_count\n     Returns the number of times the JTAG queue has been flushed.  This\n     may be used for performance tuning.\n\n     For example, flushing a queue over USB involves a minimum latency,\n     often several milliseconds, which does not change with the amount\n     of data which is written.  You may be able to identify performance\n     problems by finding tasks which waste bandwidth by flushing small\n     transfers too often, instead of batching them into larger\n     operations.\n\n -- Command: irscan [tap instruction]+ [-endstate tap_state]\n     For each TAP listed, loads the instruction register with its\n     associated numeric INSTRUCTION.  (The number of bits in that\n     instruction may be displayed using the 'scan_chain' command.)  For\n     other TAPs, a BYPASS instruction is loaded.\n\n     When TAP_STATE is specified, the JTAG state machine is left in that\n     state.  For example IRPAUSE might be specified, so the data\n     register can be loaded before re-entering the RUN/IDLE state.  If\n     the end state is not specified, the RUN/IDLE state is entered.\n\n          Note: OpenOCD currently supports only a single field for\n          instruction register values, unlike data register values.  For\n          TAPs where the instruction register length is more than 32\n          bits, portable scripts currently must issue only BYPASS\n          instructions.\n\n -- Command: pathmove start_state [next_state ...]\n     Start by moving to START_STATE, which must be one of the _stable_\n     states.  Unless it is the only state given, this will often be the\n     current state, so that no TCK transitions are needed.  Then, in a\n     series of single state transitions (conforming to the JTAG state\n     machine) shift to each NEXT_STATE in sequence, one per TCK cycle.\n     The final state must also be stable.\n\n -- Command: runtest NUM_CYCLES\n     Move to the RUN/IDLE state, and execute at least NUM_CYCLES of the\n     JTAG clock (TCK). Instructions often need some time to execute\n     before they take effect.\n\n -- Command: verify_ircapture (enable|disable)\n     Verify values captured during IRCAPTURE and returned during IR\n     scans.  Default is enabled, but this can be overridden by\n     'verify_jtag'.  This flag is ignored when validating JTAG chain\n     configuration.\n\n -- Command: verify_jtag (enable|disable)\n     Enables verification of DR and IR scans, to help detect programming\n     errors.  For IR scans, 'verify_ircapture' must also be enabled.\n     Default is enabled.\n\n17.2 TAP state names\n====================\n\nThe TAP_STATE names used by OpenOCD in the 'drscan', 'irscan', and\n'pathmove' commands are the same as those used in SVF boundary scan\ndocuments, except that SVF uses IDLE instead of RUN/IDLE.\n\n   * RESET ...  _stable_ (with TMS high); acts as if TRST were pulsed\n   * RUN/IDLE ...  _stable_; don't assume this always means IDLE\n   * DRSELECT\n   * DRCAPTURE\n   * DRSHIFT ...  _stable_; TDI/TDO shifting through the data register\n   * DREXIT1\n   * DRPAUSE ...  _stable_; data register ready for update or more\n     shifting\n   * DREXIT2\n   * DRUPDATE\n   * IRSELECT\n   * IRCAPTURE\n   * IRSHIFT ...  _stable_; TDI/TDO shifting through the instruction\n     register\n   * IREXIT1\n   * IRPAUSE ...  _stable_; instruction register ready for update or\n     more shifting\n   * IREXIT2\n   * IRUPDATE\n\nNote that only six of those states are fully \"stable\" in the face of TMS\nfixed (low except for RESET) and a free-running JTAG clock.  For all the\nothers, the next TCK transition changes to a new state.\n\n   * From DRSHIFT and IRSHIFT, clock transitions will produce side\n     effects by changing register contents.  The values to be latched in\n     upcoming DRUPDATE or IRUPDATE states may not be as expected.\n   * RUN/IDLE, DRPAUSE, and IRPAUSE are reasonable choices after\n     'drscan' or 'irscan' commands, since they are free of JTAG side\n     effects.\n   * RUN/IDLE may have side effects that appear at non-JTAG levels, such\n     as advancing the ARM9E-S instruction pipeline.  Consult the\n     documentation for the TAP(s) you are working with.\n\n\u001f\nFile: openocd.info,  Node: Boundary Scan Commands,  Next: Utility Commands,  Prev: JTAG Commands,  Up: Top\n\n18 Boundary Scan Commands\n*************************\n\nOne of the original purposes of JTAG was to support boundary scan based\nhardware testing.  Although its primary focus is to support On-Chip\nDebugging, OpenOCD also includes some boundary scan commands.\n\n18.1 SVF: Serial Vector Format\n==============================\n\nThe Serial Vector Format, better known as \"SVF\", is a way to represent\nJTAG test patterns in text files.  In a debug session using JTAG for its\ntransport protocol, OpenOCD supports running such test files.\n\n -- Command: svf filename [-tap TAPNAME] [[-]quiet] [[-]nil]\n          [[-]progress] [[-]ignore_error]\n     This issues a JTAG reset (Test-Logic-Reset) and then runs the SVF\n     script from 'filename'.\n\n     Arguments can be specified in any order; the optional dash doesn't\n     affect their semantics.\n\n     Command options:\n        - '-tap TAPNAME' ignore IR and DR headers and footers specified\n          by the SVF file with HIR, TIR, HDR and TDR commands; instead,\n          calculate them automatically according to the current JTAG\n          chain configuration, targeting TAPNAME;\n        - '[-]quiet' do not log every command before execution;\n        - '[-]nil' \"dry run\", i.e., do not perform any operations on the\n          real interface;\n        - '[-]progress' enable progress indication;\n        - '[-]ignore_error' continue execution despite TDO check errors.\n\n18.2 XSVF: Xilinx Serial Vector Format\n======================================\n\nThe Xilinx Serial Vector Format, better known as \"XSVF\", is a binary\nrepresentation of SVF which is optimized for use with Xilinx devices.\nIn a debug session using JTAG for its transport protocol, OpenOCD\nsupports running such test files.\n\n     Important: Not all XSVF commands are supported.\n\n -- Command: xsvf (tapname|plain) filename [virt2] [quiet]\n     This issues a JTAG reset (Test-Logic-Reset) and then runs the XSVF\n     script from 'filename'.  When a TAPNAME is specified, the commands\n     are directed at that TAP. When 'virt2' is specified, the XRUNTEST\n     command counts are interpreted as TCK cycles instead of\n     microseconds.  Unless the 'quiet' option is specified, messages are\n     logged for comments and some retries.\n\nThe OpenOCD sources also include two utility scripts for working with\nXSVF; they are not currently installed after building the software.  You\nmay find them useful:\n\n   * _svf2xsvf_ ...  converts SVF files into the extended XSVF syntax\n     understood by the 'xsvf' command; see notes below.\n   * _xsvfdump_ ...  converts XSVF files into a text output format;\n     understands the OpenOCD extensions.\n\nThe input format accepts a handful of non-standard extensions.  These\ninclude three opcodes corresponding to SVF extensions from Lattice\nSemiconductor (LCOUNT, LDELAY, LDSR), and two opcodes supporting a more\naccurate translation of SVF (XTRST, XWAITSTATE). If _xsvfdump_ shows a\nfile is using those opcodes, it probably will not be usable with other\nXSVF tools.\n\n18.3 IPDBG: JTAG-Host server\n============================\n\nIPDBG is a set of tools to debug IP-Cores.  It comprises, among others,\na logic analyzer and an arbitrary waveform generator.  These are\nsynthesize-able hardware descriptions of logic circuits in addition to\nsoftware for control, visualization and further analysis.  In a session\nusing JTAG for its transport protocol, OpenOCD supports the function of\na JTAG-Host.  The JTAG-Host is needed to connect the circuit over JTAG\nto the control-software.  For more details see <http://ipdbg.org>.\n\n -- Command: ipdbg [-start|-stop] -tap TAPNAME -hub IR_VALUE [DR_LENGTH]\n          [-port NUMBER] [-tool NUMBER] [-vir [VIR_VALUE [LENGTH\n          [INSTR_CODE]]]]\n     Starts or stops a IPDBG JTAG-Host server.  Arguments can be\n     specified in any order.\n\n     Command options:\n        * '-start|-stop' starts or stops a IPDBG JTAG-Host server\n          (default: start).\n        * '-tap TAPNAME' targeting the TAP TAPNAME.\n        * '-hub IR_VALUE' states that the JTAG hub is reachable with\n          dr-scans while the JTAG instruction register has the value\n          IR_VALUE.\n        * '-port NUMBER' tcp port number where the JTAG-Host is\n          listening.\n        * '-tool NUMBER' number of the tool/feature.  These corresponds\n          to the ports \"data_(up/down)_(0..6)\" at the JtagHub.\n        * '-vir [VIR_VALUE [LENGTH [INSTR_CODE]]]' On some devices, the\n          user data-register is only reachable if there is a specific\n          value in a second dr.  This second dr is called vir (virtual\n          ir).  With this parameter given, the IPDBG satisfies this\n          condition prior an access to the IPDBG-Hub.  The value shifted\n          into the vir is given by the first parameter VIR_VALUE\n          (default: 0x11).  The second parameter LENGTH is the length of\n          the vir data register (default: 5).  With the INSTR_CODE\n          (default: 0x00e) parameter the ir value to shift data through\n          vir can be configured.\n\nExamples:\n     ipdbg -start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4\nStarts a server listening on tcp-port 4242 which connects to tool 4.\nThe connection is through the TAP of a Xilinx Spartan 6 on USER1\ninstruction (tested with a papillion pro board).\n\n     ipdbg -start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1\nStarts a server listening on tcp-port 60000 which connects to tool 1\n(data_up_1/data_down_1).  The connection is through the TAP of a Intel\nMAX10 virtual jtag component (sld_instance_index is 0; sld_ir_width is\nsmaller than 5).\n\n\u001f\nFile: openocd.info,  Node: Utility Commands,  Next: GDB and OpenOCD,  Prev: Boundary Scan Commands,  Up: Top\n\n19 Utility Commands\n*******************\n\n19.1 RAM testing\n================\n\nThere is often a need to stress-test random access memory (RAM) for\nerrors.  OpenOCD comes with a Tcl implementation of well-known memory\ntesting procedures allowing the detection of all sorts of issues with\nelectrical wiring, defective chips, PCB layout and other common hardware\nproblems.\n\nTo use them, you usually need to initialise your RAM controller first;\nconsult your SoC's documentation to get the recommended list of register\noperations and translate them to the corresponding 'mww'/'mwb' commands.\n\nLoad the memory testing functions with\n\n     source [find tools/memtest.tcl]\n\nto get access to the following facilities:\n\n -- Command: memTestDataBus address\n     Test the data bus wiring in a memory region by performing a walking\n     1's test at a fixed address within that region.\n\n -- Command: memTestAddressBus baseaddress size\n     Perform a walking 1's test on the relevant bits of the address and\n     check for aliasing.  This test will find single-bit address\n     failures such as stuck-high, stuck-low, and shorted pins.\n\n -- Command: memTestDevice baseaddress size\n     Test the integrity of a physical memory device by performing an\n     increment/decrement test over the entire region.  In the process\n     every storage bit in the device is tested as zero and as one.\n\n -- Command: runAllMemTests baseaddress size\n     Run all of the above tests over a specified memory region.\n\n19.2 Firmware recovery helpers\n==============================\n\nOpenOCD includes an easy-to-use script to facilitate mass-market devices\nrecovery with JTAG.\n\nFor quickstart instructions run:\n     openocd -f tools/firmware-recovery.tcl -c firmware_help\n\n\u001f\nFile: openocd.info,  Node: GDB and OpenOCD,  Next: Tcl Scripting API,  Prev: Utility Commands,  Up: Top\n\n20 GDB and OpenOCD\n******************\n\nOpenOCD complies with the remote gdbserver protocol and, as such, can be\nused to debug remote targets.  Setting up GDB to work with OpenOCD can\ninvolve several components:\n\n   * The OpenOCD server support for GDB may need to be configured.\n     *Note GDB Configuration: gdbconfiguration.\n   * GDB's support for OpenOCD may need configuration, as shown in this\n     chapter.\n   * If you have a GUI environment like Eclipse, that also will probably\n     need to be configured.\n\nOf course, the version of GDB you use will need to be one which has been\nbuilt to know about the target CPU you're using.  It's probably part of\nthe tool chain you're using.  For example, if you are doing\ncross-development for ARM on an x86 PC, instead of using the native x86\n'gdb' command you might use 'arm-none-eabi-gdb' if that's the tool chain\nused to compile your code.\n\n20.1 Connecting to GDB\n======================\n\nUse GDB 6.7 or newer with OpenOCD if you run into trouble.  For instance\nGDB 6.3 has a known bug that produces bogus memory access errors, which\nhas since been fixed; see\n<http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html>\n\nOpenOCD can communicate with GDB in two ways:\n\n  1. A socket (TCP/IP) connection is typically started as follows:\n          target extended-remote localhost:3333\n     This would cause GDB to connect to the gdbserver on the local pc\n     using port 3333.\n\n     The extended remote protocol is a super-set of the remote protocol\n     and should be the preferred choice.  More details are available in\n     GDB documentation\n     <https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html>\n\n     To speed-up typing, any GDB command can be abbreviated, including\n     the extended remote command above that becomes:\n          tar ext :3333\n\n     Note: If any backward compatibility issue requires using the old\n     remote protocol in place of the extended remote one, the former\n     protocol is still available through the command:\n          target remote localhost:3333\n\n  2. A pipe connection is typically started as follows:\n          target extended-remote | \\\n                 openocd -c \"gdb_port pipe; log_output openocd.log\"\n     This would cause GDB to run OpenOCD and communicate using pipes\n     (stdin/stdout).  Using this method has the advantage of GDB\n     starting/stopping OpenOCD for the debug session.  log_output sends\n     the log output to a file to ensure that the pipe is not saturated\n     when using higher debug level outputs.\n\nTo list the available OpenOCD commands type 'monitor help' on the GDB\ncommand line.\n\n20.2 Sample GDB session startup\n===============================\n\nWith the remote protocol, GDB sessions start a little differently than\nthey do when you're debugging locally.  Here's an example showing how to\nstart a debug session with a small ARM program.  In this case the\nprogram was linked to be loaded into SRAM on a Cortex-M3.  Most programs\nwould be written into flash (address 0) and run from there.\n\n     $ arm-none-eabi-gdb example.elf\n     (gdb) target extended-remote localhost:3333\n     Remote debugging using localhost:3333\n     ...\n     (gdb) monitor reset halt\n     ...\n     (gdb) load\n     Loading section .vectors, size 0x100 lma 0x20000000\n     Loading section .text, size 0x5a0 lma 0x20000100\n     Loading section .data, size 0x18 lma 0x200006a0\n     Start address 0x2000061c, load size 1720\n     Transfer rate: 22 KB/sec, 573 bytes/write.\n     (gdb) continue\n     Continuing.\n     ...\n\nYou could then interrupt the GDB session to make the program break, type\n'where' to show the stack, 'list' to show the code around the program\ncounter, 'step' through code, set breakpoints or watchpoints, and so on.\n\n20.3 Configuring GDB for OpenOCD\n================================\n\nOpenOCD supports the gdb 'qSupported' packet, this enables information\nto be sent by the GDB remote server (i.e.  OpenOCD) to GDB. Typical\ninformation includes packet size and the device's memory map.  You do\nnot need to configure the packet size by hand, and the relevant parts of\nthe memory map should be automatically set up when you declare (NOR)\nflash banks.\n\nHowever, there are other things which GDB can't currently query.  You\nmay need to set those up by hand.  As OpenOCD starts up, you will often\nsee a line reporting something like:\n\n     Info : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints\n\nYou can pass that information to GDB with these commands:\n\n     set remote hardware-breakpoint-limit 6\n     set remote hardware-watchpoint-limit 4\n\nWith that particular hardware (Cortex-M3) the hardware breakpoints only\nwork for code running from flash memory.  Most other ARM systems do not\nhave such restrictions.\n\nRather than typing such commands interactively, you may prefer to save\nthem in a file and have GDB execute them as it starts, perhaps using a\n'.gdbinit' in your project directory or starting GDB using 'gdb -x\nfilename'.\n\n20.4 Programming using GDB\n==========================\n\nBy default the target memory map is sent to GDB. This can be disabled by\nthe following OpenOCD configuration option:\n     gdb_memory_map disable\nFor this to function correctly a valid flash configuration must also be\nset in OpenOCD. For faster performance you should also configure a valid\nworking area.\n\nInforming GDB of the memory map of the target will enable GDB to protect\nany flash areas of the target and use hardware breakpoints by default.\nThis means that the OpenOCD option 'gdb_breakpoint_override' is not\nrequired when using a memory map.  *Note gdb_breakpoint_override:\ngdbbreakpointoverride.\n\nTo view the configured memory map in GDB, use the GDB command 'info\nmem'.  All other unassigned addresses within GDB are treated as RAM.\n\nGDB 6.8 and higher set any memory area not in the memory map as\ninaccessible.  This can be changed to the old behaviour by using the\nfollowing GDB command\n     set mem inaccessible-by-default off\n\nIf 'gdb_flash_program enable' is also used, GDB will be able to program\nany flash memory using the vFlash interface.\n\nGDB will look at the target memory map when a load command is given, if\nany areas to be programmed lie within the target flash area the vFlash\npackets will be used.\n\nIf the target needs configuring before GDB programming, set target event\ngdb-flash-erase-start:\n     $_TARGETNAME configure -event gdb-flash-erase-start BODY\n*Note Target Events: targetevents, for other GDB programming related\nevents.\n\nTo verify any flash programming the GDB command 'compare-sections' can\nbe used.\n\n20.5 Using GDB as a non-intrusive memory inspector\n==================================================\n\nIf your project controls more than a blinking LED, let's say a heavy\nindustrial robot or an experimental nuclear reactor, stopping the\ncontrolling process just because you want to attach GDB is not a good\noption.\n\nOpenOCD does not support GDB non-stop mode (might be implemented in the\nfuture).  Though there is a possible setup where the target does not get\nstopped and GDB treats it as it were running.  If the target supports\nbackground access to memory while it is running, you can use GDB in this\nmode to inspect memory (mainly global variables) without any intrusion\nof the target process.\n\nRemove default setting of gdb-attach event.  *Note Target Events:\ntargetevents.  Place following command after target configuration:\n     $_TARGETNAME configure -event gdb-attach {}\n\nIf any of installed flash banks does not support probe on running\ntarget, switch off gdb_memory_map:\n     gdb_memory_map disable\n\nEnsure GDB is configured without interrupt-on-connect.  Some GDB\nversions set it by default, some does not.\n     set remote interrupt-on-connect off\n\nIf you switched gdb_memory_map off, you may want to setup GDB memory map\nmanually or issue 'set mem inaccessible-by-default off'\n\nNow you can issue GDB command 'target extended-remote ...' and inspect\nmemory of a running target.  Do not use GDB commands 'continue', 'step'\nor 'next' as they synchronize GDB with your target and GDB would require\nstopping the target to get the prompt back.\n\nDo not use this mode under an IDE like Eclipse as it caches values of\npreviously shown variables.\n\nIt's also possible to connect more than one GDB to the same target by\nthe target's configuration option '-gdb-max-connections'.  This allows,\nfor example, one GDB to run a script that continuously polls a set of\nvariables while other GDB can be used interactively.  Be extremely\ncareful in this case, because the two GDB can easily get out-of-sync.\n\n20.6 RTOS Support\n=================\n\nOpenOCD includes RTOS support, this will however need enabling as it\ndefaults to disabled.  It can be enabled by passing '-rtos' arg to the\ntarget.  *Note RTOS Type: rtostype.\n\n*Note Debugging Programs with Multiple Threads: (gdb)Threads, for\ndetails about relevant GDB commands.\n\n\nAn example setup is below:\n\n     $_TARGETNAME configure -rtos auto\n\nThis will attempt to auto detect the RTOS within your application.\n\nCurrently supported rtos's include:\n   * 'eCos'\n   * 'ThreadX'\n   * 'FreeRTOS'\n   * 'linux'\n   * 'ChibiOS'\n   * 'embKernel'\n   * 'mqx'\n   * 'uCOS-III'\n   * 'nuttx'\n   * 'RIOT'\n   * 'hwthread' (This is not an actual RTOS. *Note Using OpenOCD SMP\n     with GDB: usingopenocdsmpwithgdb.)\n   * 'Zephyr'\n\nBefore an RTOS can be detected, it must export certain symbols;\notherwise, it cannot be used by OpenOCD. Below is a list of the required\nsymbols for each supported RTOS.\n\n'eCos symbols'\n     Cyg_Thread::thread_list, Cyg_Scheduler_Base::current_thread.\n'ThreadX symbols'\n     _tx_thread_current_ptr, _tx_thread_created_ptr,\n     _tx_thread_created_count.\n'FreeRTOS symbols'\n     pxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1,\n     xDelayedTaskList2, pxDelayedTaskList, pxOverflowDelayedTaskList,\n     xPendingReadyList, uxCurrentNumberOfTasks, uxTopUsedPriority.\n'linux symbols'\n     init_task.\n'ChibiOS symbols'\n     rlist, ch_debug, chSysInit.\n'embKernel symbols'\n     Rtos::sCurrentTask, Rtos::sListReady, Rtos::sListSleep,\n     Rtos::sListSuspended, Rtos::sMaxPriorities,\n     Rtos::sCurrentTaskCount.\n'mqx symbols'\n     _mqx_kernel_data, MQX_init_struct.\n'uC/OS-III symbols'\n     OSRunning, OSTCBCurPtr, OSTaskDbgListPtr, OSTaskQty.\n'nuttx symbols'\n     g_readytorun, g_tasklisttable.\n'RIOT symbols'\n     sched_threads, sched_num_threads, sched_active_pid, max_threads,\n     _tcb_name_offset.\n'Zephyr symbols'\n     _kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size\n\nFor most RTOS supported the above symbols will be exported by default.\nHowever for some, eg.  FreeRTOS, uC/OS-III and Zephyr, extra steps must\nbe taken.\n\nZephyr must be compiled with the DEBUG_THREAD_INFO option.  This will\ngenerate some symbols with information needed in order to build the list\nof threads.\n\nFreeRTOS and uC/OS-III RTOSes may require additional OpenOCD-specific\nfile to be linked along with the project:\n\n'FreeRTOS'\n     contrib/rtos-helpers/FreeRTOS-openocd.c\n'uC/OS-III'\n     contrib/rtos-helpers/uCOS-III-openocd.c\n\n20.7 Using OpenOCD SMP with GDB\n===============================\n\nOpenOCD includes a pseudo RTOS called _hwthread_ that presents CPU cores\n(\"hardware threads\") in an SMP system as threads to GDB. With this\nextension, GDB can be used to inspect the state of an SMP system in a\nnatural way.  After halting the system, using the GDB command 'info\nthreads' will list the context of each active CPU core in the system.\nGDB's 'thread' command can be used to switch the view to a different CPU\ncore.  The 'step' and 'stepi' commands can be used to step a specific\ncore while other cores are free-running or remain halted, depending on\nthe scheduler-locking mode configured in GDB.\n\n\u001f\nFile: openocd.info,  Node: Tcl Scripting API,  Next: FAQ,  Prev: GDB and OpenOCD,  Up: Top\n\n21 Tcl Scripting API\n********************\n\n21.1 API rules\n==============\n\nTcl commands are stateless; e.g.  the 'telnet' command has a concept of\ncurrently active target, the Tcl API proc's take this sort of state\ninformation as an argument to each proc.\n\nThere are three main types of return values: single value, name value\npair list and lists.\n\nName value pair.  The proc 'foo' below returns a name/value pair list.\n\n     >  set foo(me)  Duane\n     >  set foo(you) Oyvind\n     >  set foo(mouse) Micky\n     >  set foo(duck) Donald\n\nIf one does this:\n\n     >  set foo\n\nThe result is:\n\n     me Duane you Oyvind mouse Micky duck Donald\n\nThus, to get the names of the associative array is easy:\n\nforeach { name value } [set foo] {\n        puts \"Name: $name, Value: $value\"\n}\n\nLists returned should be relatively small.  Otherwise, a range should be\npassed in to the proc in question.\n\n21.2 Internal low-level Commands\n================================\n\nBy \"low-level\", we mean commands that a human would typically not invoke\ndirectly.\n\n   * flash banks <DRIVER> <BASE> <SIZE> <CHIP_WIDTH> <BUS_WIDTH>\n     <TARGET> ['driver options' ...]\n\n     Return information about the flash banks\n\n   * capture <COMMAND>\n\n     Run <COMMAND> and return full log output that was produced during\n     its execution.  Example:\n\n          > capture \"reset init\"\n\nOpenOCD commands can consist of two words, e.g.  \"flash banks\".  The\n'startup.tcl' \"unknown\" proc will translate this into a Tcl proc called\n\"flash_banks\".\n\n21.3 Tcl RPC server\n===================\n\nOpenOCD provides a simple RPC server that allows to run arbitrary Tcl\ncommands and receive the results.\n\nTo access it, your application needs to connect to a configured TCP port\n(see 'tcl_port').  Then it can pass any string to the interpreter\nterminating it with '0x1a' and wait for the return value (it will be\nterminated with '0x1a' as well).  This can be repeated as many times as\ndesired without reopening the connection.\n\nIt is not needed anymore to prefix the OpenOCD commands with 'ocd_' to\nget the results back.  But sometimes you might need the 'capture'\ncommand.\n\nSee 'contrib/rpc_examples/' for specific client implementations.\n\n21.4 Tcl RPC server notifications\n=================================\n\nNotifications are sent asynchronously to other commands being executed\nover the RPC server, so the port must be polled continuously.\n\nTarget event, state and reset notifications are emitted as Tcl\nassociative arrays in the following format.\n\ntype target_event event [event-name]\ntype target_state state [state-name]\ntype target_reset mode [reset-mode]\n\n -- Command: tcl_notifications [on/off]\n     Toggle output of target notifications to the current Tcl RPC\n     server.  Only available from the Tcl RPC server.  Defaults to off.\n\n21.5 Tcl RPC server trace output\n================================\n\nTrace data is sent asynchronously to other commands being executed over\nthe RPC server, so the port must be polled continuously.\n\nTarget trace data is emitted as a Tcl associative array in the following\nformat.\n\ntype target_trace data [trace-data-hex-encoded]\n\n -- Command: tcl_trace [on/off]\n     Toggle output of target trace data to the current Tcl RPC server.\n     Only available from the Tcl RPC server.  Defaults to off.\n\n     See an example application here:\n     <https://github.com/apmorton/OpenOcdTraceUtil> [OpenOcdTraceUtil]\n\n\u001f\nFile: openocd.info,  Node: FAQ,  Next: Tcl Crash Course,  Prev: Tcl Scripting API,  Up: Top\n\n22 FAQ\n******\n\n  1. RTCK, also known as: Adaptive Clocking - What is it?\n\n     In digital circuit design it is often referred to as \"clock\n     synchronisation\" the JTAG interface uses one clock (TCK or TCLK)\n     operating at some speed, your CPU target is operating at another.\n     The two clocks are not synchronised, they are \"asynchronous\"\n\n     In order for the two to work together they must be synchronised\n     well enough to work; JTAG can't go ten times faster than the CPU,\n     for example.  There are 2 basic options:\n       1. Use a special \"adaptive clocking\" circuit to change the JTAG\n          clock rate to match what the CPU currently supports.\n       2. The JTAG clock must be fixed at some speed that's enough\n          slower than the CPU clock that all TMS and TDI transitions can\n          be detected.\n\n     Does this really matter?  For some chips and some situations, this\n     is a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link; the\n     CPU has no difficulty keeping up with JTAG. Startup sequences are\n     often problematic though, as are other situations where the CPU\n     clock rate changes (perhaps to save power).\n\n     For example, Atmel AT91SAM chips start operation from reset with a\n     32kHz system clock.  Boot firmware may activate the main oscillator\n     and PLL before switching to a faster clock (perhaps that 500 MHz\n     ARM926 scenario).  If you're using JTAG to debug that startup\n     sequence, you must slow the JTAG clock to sometimes 1 to 4kHz.\n     After startup completes, JTAG can use a faster clock.\n\n     Consider also debugging a 500MHz ARM926 hand held battery powered\n     device that enters a low power \"deep sleep\" mode, at 32kHz CPU\n     clock, between keystrokes unless it has work to do.  When would\n     that 5 MHz JTAG clock be usable?\n\n     Solution #1 - A special circuit\n\n     In order to make use of this, your CPU, board, and JTAG adapter\n     must all support the RTCK feature.  Not all of them support this;\n     keep reading!\n\n     The RTCK (\"Return TCK\") signal in some ARM chips is used to help\n     with this problem.  ARM has a good description of the problem\n     described at this link:\n     <http://www.arm.com/support/faqdev/4170.html> [checked\n     28/nov/2008].  Link title: \"How does the JTAG synchronisation logic\n     work?  / how does adaptive clocking work?\".\n\n     The nice thing about adaptive clocking is that \"battery powered\n     hand held device example\" - the adaptiveness works perfectly all\n     the time.  One can set a break point or halt the system in the deep\n     power down code, slow step out until the system speeds up.\n\n     Note that adaptive clocking may also need to work at the board\n     level, when a board-level scan chain has multiple chips.  Parallel\n     clock voting schemes are good way to implement this, both within\n     and between chips, and can easily be implemented with a CPLD. It's\n     not difficult to have logic fan a module's input TCK signal out to\n     each TAP in the scan chain, and then wait until each TAP's RTCK\n     comes back with the right polarity before changing the output RTCK\n     signal.  Texas Instruments makes some clock voting logic available\n     for free (with no support) in VHDL form; see\n     <http://tiexpressdsp.com/index.php/Adaptive_Clocking>\n\n     Solution #2 - Always works - but may be slower\n\n     Often this is a perfectly acceptable solution.\n\n     In most simple terms: Often the JTAG clock must be 1/10 to 1/12 of\n     the target clock speed.  But what that \"magic division\" is varies\n     depending on the chips on your board.  ARM rule of thumb Most ARM\n     based systems require an 6:1 division; ARM11 cores use an 8:1\n     division.  Xilinx rule of thumb is 1/12 the clock speed.\n\n     Note: most full speed FT2232 based JTAG adapters are limited to a\n     maximum of 6MHz.  The ones using USB high speed chips (FT2232H)\n     often support faster clock rates (and adaptive clocking).\n\n     You can still debug the 'low power' situations - you just need to\n     either use a fixed and very slow JTAG clock rate ...  or else\n     manually adjust the clock speed at every step.  (Adjusting is\n     painful and tedious, and is not always practical.)\n\n     It is however easy to \"code your way around it\" - i.e.: Cheat a\n     little, have a special debug mode in your application that does a\n     \"high power sleep\".  If you are careful - 98% of your problems can\n     be debugged this way.\n\n     Note that on ARM you may need to avoid using the _wait for\n     interrupt_ operation in your idle loops even if you don't otherwise\n     change the CPU clock rate.  That operation gates the CPU clock, and\n     thus the JTAG clock; which prevents JTAG access.  One consequence\n     is not being able to 'halt' cores which are executing that _wait\n     for interrupt_ operation.\n\n     To set the JTAG frequency use the command:\n\n          # Example: 1.234MHz\n          adapter speed 1234\n\n  2. Win32 Pathnames Why don't backslashes work in Windows paths?\n\n     OpenOCD uses Tcl and a backslash is an escape char.  Use { and }\n     around Windows filenames.\n\n          > echo \\a\n\n          > echo {\\a}\n          \\a\n          > echo \"\\a\"\n\n          >\n\n  3. Missing: cygwin1.dll OpenOCD complains about a missing cygwin1.dll.\n\n     Make sure you have Cygwin installed, or at least a version of\n     OpenOCD that claims to come with all the necessary DLLs.  When\n     using Cygwin, try launching OpenOCD from the Cygwin shell.\n\n  4. Breakpoint Issue I'm trying to set a breakpoint using GDB (or a\n     front-end like Insight or Eclipse), but OpenOCD complains that\n     \"Info: arm7_9_common.c:213 arm7_9_add_breakpoint(): sw breakpoint\n     requested, but software breakpoints not enabled\".\n\n     GDB issues software breakpoints when a normal breakpoint is\n     requested, or to implement source-line single-stepping.  On ARMv4T\n     systems, like ARM7TDMI, ARM720T or ARM920T, software breakpoints\n     consume one of the two available hardware breakpoints.\n\n  5. LPC2000 Flash When erasing or writing LPC2000 on-chip flash, the\n     operation fails at random.\n\n     Make sure the core frequency specified in the 'flash lpc2000' line\n     matches the clock at the time you're programming the flash.  If\n     you've specified the crystal's frequency, make sure the PLL is\n     disabled.  If you've specified the full core speed (e.g.  60MHz),\n     make sure the PLL is enabled.\n\n  6. Amontec Chameleon When debugging using an Amontec Chameleon in its\n     JTAG Accelerator configuration, I keep getting \"Error:\n     amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed out\n     while waiting for end of scan, rtck was disabled\".\n\n     Make sure your PC's parallel port operates in EPP mode.  You might\n     have to try several settings in your PC BIOS (ECP, EPP, and\n     different versions of those).\n\n  7. Data Aborts When debugging with OpenOCD and GDB (plain GDB,\n     Insight, or Eclipse), I get lots of \"Error: arm7_9_common.c:1771\n     arm7_9_read_memory(): memory read caused data abort\".\n\n     The errors are non-fatal, and are the result of GDB trying to trace\n     stack frames beyond the last valid frame.  It might be possible to\n     prevent this by setting up a proper \"initial\" stack frame, if you\n     happen to know what exactly has to be done, feel free to add this\n     here.\n\n     Simple: In your startup code - push 8 registers of zeros onto the\n     stack before calling main().  What GDB is doing is \"climbing\" the\n     run time stack by reading various values on the stack using the\n     standard call frame for the target.  GDB keeps going - until one of\n     2 things happen #1 an invalid frame is found, or #2 some huge\n     number of stackframes have been processed.  By pushing zeros on the\n     stack, GDB gracefully stops.\n\n     Debugging Interrupt Service Routines - In your ISR before you call\n     your C code, do the same - artificially push some zeros onto the\n     stack, remember to pop them off when the ISR is done.\n\n     Also note: If you have a multi-threaded operating system, they\n     often do not in the interest of saving memory waste these few\n     bytes.  Painful...\n\n  8. JTAG Reset Config I get the following message in the OpenOCD\n     console (or log file): \"Warning: arm7_9_common.c:679\n     arm7_9_assert_reset(): srst resets test logic, too\".\n\n     This warning doesn't indicate any serious problem, as long as you\n     don't want to debug your core right out of reset.  Your .cfg file\n     specified 'reset_config trst_and_srst srst_pulls_trst' to tell\n     OpenOCD that either your board, your debugger or your target uC\n     (e.g.  LPC2000) can't assert the two reset signals independently.\n     With this setup, it's not possible to halt the core right out of\n     reset, everything else should work fine.\n\n  9. USB Power When using OpenOCD in conjunction with Amontec JTAGkey\n     and the Yagarto toolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the\n     debugging seems to be unstable.  When single-stepping over large\n     blocks of code, GDB and OpenOCD quit with an error message.  Is\n     there a stability issue with OpenOCD?\n\n     No, this is not a stability issue concerning OpenOCD. Most users\n     have solved this issue by simply using a self-powered USB hub,\n     which they connect their Amontec JTAGkey to.  Apparently, some\n     computers do not provide a USB power supply stable enough for the\n     Amontec JTAGkey to be operated.\n\n     Laptops running on battery have this problem too...\n\n  10. GDB Disconnects When using the Amontec JTAGkey, sometimes OpenOCD\n     crashes with the following error message: \"Error: gdb_server.c:101\n     gdb_get_char(): read: 10054\".  What does that mean and what might\n     be the reason for this?\n\n     Error code 10054 corresponds to WSAECONNRESET, which means that the\n     debugger (GDB) has closed the connection to OpenOCD. This might be\n     a GDB issue.\n\n  11. LPC2000 Flash In the configuration file in the section where flash\n     device configurations are described, there is a parameter for\n     specifying the clock frequency for LPC2000 internal flash devices\n     (e.g.  'flash bank $_FLASHNAME lpc2000 0x0 0x40000 0 0 $_TARGETNAME\n     lpc2000_v1 14746 calc_checksum'), which must be specified in\n     kilohertz.  However, I do have a quartz crystal of a frequency that\n     contains fractions of kilohertz (e.g.  14,745,600 Hz, i.e.\n     14,745.600 kHz).  Is it possible to specify real numbers for the\n     clock frequency?\n\n     No.  The clock frequency specified here must be given as an\n     integral number.  However, this clock frequency is used by the\n     In-Application-Programming (IAP) routines of the LPC2000 family\n     only, which seems to be very tolerant concerning the given clock\n     frequency, so a slight difference between the specified clock\n     frequency and the actual clock frequency will not cause any\n     trouble.\n\n  12. Command Order Do I have to keep a specific order for the commands\n     in the configuration file?\n\n     Well, yes and no.  Commands can be given in arbitrary order, yet\n     the devices listed for the JTAG scan chain must be given in the\n     right order (jtag newdevice), with the device closest to the\n     TDO-Pin being listed first.  In general, whenever objects of the\n     same type exist which require an index number, then these objects\n     must be given in the right order (jtag newtap, targets and flash\n     banks - a target references a jtag newtap and a flash bank\n     references a target).\n\n     You can use the \"scan_chain\" command to verify and display the tap\n     order.\n\n     Also, some commands can't execute until after 'init' has been\n     processed.  Such commands include 'nand probe' and everything else\n     that needs to write to controller registers, perhaps for setting up\n     DRAM and loading it with code.\n\n  13. JTAG TAP Order Do I have to declare the TAPS in some particular\n     order?\n\n     Yes; whenever you have more than one, you must declare them in the\n     same order used by the hardware.\n\n     Many newer devices have multiple JTAG TAPs.  For example:\n     STMicroelectronics STM32 chips have two TAPs, a \"boundary scan TAP\"\n     and \"Cortex-M3\" TAP. Example: The STM32 reference manual, Document\n     ID: RM0008, Section 26.5, Figure 259, page 651/681, the \"TDI\" pin\n     is connected to the boundary scan TAP, which then connects to the\n     Cortex-M3 TAP, which then connects to the TDO pin.\n\n     Thus, the proper order for the STM32 chip is: (1) The Cortex-M3,\n     then (2) The boundary scan TAP. If your board includes an\n     additional JTAG chip in the scan chain (for example a Xilinx CPLD\n     or FPGA) you could place it before or after the STM32 chip in the\n     chain.  For example:\n\n        * OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input)\n        * STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input)\n        * STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin\n        * STM32 TDO Pin (output) -> Xilinx TDI Pin (input)\n        * Xilinx TDO Pin -> OpenOCD TDO (input)\n\n     The \"jtag device\" commands would thus be in the order shown below.\n     Note:\n\n        * jtag newtap Xilinx tap -irlen ...\n        * jtag newtap stm32 cpu -irlen ...\n        * jtag newtap stm32 bs -irlen ...\n        * # Create the debug target and say where it is\n        * target create stm32.cpu -chain-position stm32.cpu ...\n\n  14. SYSCOMP Sometimes my debugging session terminates with an error.\n     When I look into the log file, I can see these error messages:\n     Error: arm7_9_common.c:561 arm7_9_execute_sys_speed(): timeout\n     waiting for SYSCOMP\n\n     TODO.\n\n\u001f\nFile: openocd.info,  Node: Tcl Crash Course,  Next: License,  Prev: FAQ,  Up: Top\n\n23 Tcl Crash Course\n*******************\n\nNot everyone knows Tcl - this is not intended to be a replacement for\nlearning Tcl, the intent of this chapter is to give you some idea of how\nthe Tcl scripts work.\n\nThis chapter is written with two audiences in mind.  (1) OpenOCD users\nwho need to understand a bit more of how Jim-Tcl works so they can do\nsomething useful, and (2) those that want to add a new command to\nOpenOCD.\n\n23.1 Tcl Rule #1\n================\n\nThere is a famous joke, it goes like this:\n  1. Rule #1: The wife is always correct\n  2. Rule #2: If you think otherwise, See Rule #1\n\nThe Tcl equal is this:\n\n  1. Rule #1: Everything is a string\n  2. Rule #2: If you think otherwise, See Rule #1\n\nAs in the famous joke, the consequences of Rule #1 are profound.  Once\nyou understand Rule #1, you will understand Tcl.\n\n23.2 Tcl Rule #1b\n=================\n\nThere is a second pair of rules.\n  1. Rule #1: Control flow does not exist.  Only commands\n     For example: the classic FOR loop or IF statement is not a control\n     flow item, they are commands, there is no such thing as control\n     flow in Tcl.\n  2. Rule #2: If you think otherwise, See Rule #1\n     Actually what happens is this: There are commands that by\n     convention, act like control flow key words in other languages.\n     One of those commands is the word \"for\", another command is \"if\".\n\n23.3 Per Rule #1 - All Results are strings\n==========================================\n\nEvery Tcl command results in a string.  The word \"result\" is used\ndeliberately.  No result is just an empty string.  Remember: Rule #1 -\nEverything is a string\n\n23.4 Tcl Quoting Operators\n==========================\n\nIn life of a Tcl script, there are two important periods of time, the\ndifference is subtle.\n  1. Parse Time\n  2. Evaluation Time\n\nThe two key items here are how \"quoted things\" work in Tcl.  Tcl has\nthree primary quoting constructs, the [square-brackets] the\n{curly-braces} and \"double-quotes\"\n\nBy now you should know $VARIABLES always start with a $DOLLAR sign.\nBTW: To set a variable, you actually use the command \"set\", as in \"set\nVARNAME VALUE\" much like the ancient BASIC language \"let x = 1\"\nstatement, but without the equal sign.\n\n   * [square-brackets]\n     [square-brackets] are command substitutions.  It operates much like\n     Unix Shell 'back-ticks'.  The result of a [square-bracket]\n     operation is exactly 1 string.  Remember Rule #1 - Everything is a\n     string.  These two statements are roughly identical:\n              # bash example\n              X=`date`\n              echo \"The Date is: $X\"\n              # Tcl example\n              set X [date]\n              puts \"The Date is: $X\"\n   * \"double-quoted-things\"\n     \"double-quoted-things\" are just simply quoted text.  $VARIABLES and\n     [square-brackets] are expanded in place - the result however is\n     exactly 1 string.  Remember Rule #1 - Everything is a string\n              set x \"Dinner\"\n              puts \"It is now \\\"[date]\\\", $x is in 1 hour\"\n   * {Curly-Braces}\n     {Curly-Braces} are magic: $VARIABLES and [square-brackets] are\n     parsed, but are NOT expanded or executed.  {Curly-Braces} are like\n     'single-quote' operators in BASH shell scripts, with the added\n     feature: {curly-braces} can be nested, single quotes can not.\n     {{{this is nested 3 times}}} NOTE: [date] is a bad example; at this\n     writing, Jim/OpenOCD does not have a date command.\n\n23.5 Consequences of Rule 1/2/3/4\n=================================\n\nThe consequences of Rule 1 are profound.\n\n23.5.1 Tokenisation & Execution.\n--------------------------------\n\nOf course, whitespace, blank lines and #comment lines are handled in the\nnormal way.\n\nAs a script is parsed, each (multi) line in the script file is tokenised\nand according to the quoting rules.  After tokenisation, that line is\nimmediately executed.\n\nMulti line statements end with one or more \"still-open\" {curly-braces}\nwhich - eventually - closes a few lines later.\n\n23.5.2 Command Execution\n------------------------\n\nRemember earlier: There are no \"control flow\" statements in Tcl.\nInstead there are COMMANDS that simply act like control flow operators.\n\nCommands are executed like this:\n\n  1. Parse the next line into (argc) and (argv[]).\n  2. Look up (argv[0]) in a table and call its function.\n  3. Repeat until End Of File.\n\nIt sort of works like this:\n         for(;;){\n             ReadAndParse( &argc, &argv );\n\n             cmdPtr = LookupCommand( argv[0] );\n\n             (*cmdPtr->Execute)( argc, argv );\n         }\n\nWhen the command \"proc\" is parsed (which creates a procedure function)\nit gets 3 parameters on the command line.  1 the name of the proc\n(function), 2 the list of parameters, and 3 the body of the function.\nNote the choice of words: LIST and BODY. The PROC command stores these\nitems in a table somewhere so it can be found by \"LookupCommand()\"\n\n23.5.3 The FOR command\n----------------------\n\nThe most interesting command to look at is the FOR command.  In Tcl, the\nFOR command is normally implemented in C. Remember, FOR is a command\njust like any other command.\n\nWhen the ascii text containing the FOR command is parsed, the parser\nproduces 5 parameter strings, (If in doubt: Refer to Rule #1) they are:\n\n  0. The ascii text 'for'\n  1. The start text\n  2. The test expression\n  3. The next text\n  4. The body text\n\nSort of reminds you of \"main( int argc, char **argv )\" does it not?\nRemember Rule #1 - Everything is a string.  The key point is this: Often\nmany of those parameters are in {curly-braces} - thus the variables\ninside are not expanded or replaced until later.\n\nRemember that every Tcl command looks like the classic \"main( argc, argv\n)\" function in C. In JimTCL - they actually look like this:\n\n     int\n     MyCommand( Jim_Interp *interp,\n                int *argc,\n                Jim_Obj * const *argvs );\n\nReal Tcl is nearly identical.  Although the newer versions have\nintroduced a byte-code parser and interpreter, but at the core, it still\noperates in the same basic way.\n\n23.5.4 FOR command implementation\n---------------------------------\n\nTo understand Tcl it is perhaps most helpful to see the FOR command.\nRemember, it is a COMMAND not a control flow structure.\n\nIn Tcl there are two underlying C helper functions.\n\nRemember Rule #1 - You are a string.\n\nThe first helper parses and executes commands found in an ascii string.\nCommands can be separated by semicolons, or newlines.  While parsing,\nvariables are expanded via the quoting rules.\n\nThe second helper evaluates an ascii string as a numerical expression\nand returns a value.\n\nHere is an example of how the FOR command could be implemented.  The\npseudo code below does not show error handling.\n     void Execute_AsciiString( void *interp, const char *string );\n\n     int Evaluate_AsciiExpression( void *interp, const char *string );\n\n     int\n     MyForCommand( void *interp,\n                   int argc,\n                   char **argv )\n     {\n        if( argc != 5 ){\n            SetResult( interp, \"WRONG number of parameters\");\n            return ERROR;\n        }\n\n        // argv[0] = the ascii string just like C\n\n        // Execute the start statement.\n        Execute_AsciiString( interp, argv[1] );\n\n        // Top of loop test\n        for(;;){\n             i = Evaluate_AsciiExpression(interp, argv[2]);\n             if( i == 0 )\n                 break;\n\n             // Execute the body\n             Execute_AsciiString( interp, argv[3] );\n\n             // Execute the LOOP part\n             Execute_AsciiString( interp, argv[4] );\n         }\n\n         // Return no error\n         SetResult( interp, \"\" );\n         return SUCCESS;\n     }\n\nEvery other command IF, WHILE, FORMAT, PUTS, EXPR, everything works in\nthe same basic way.\n\n23.6 OpenOCD Tcl Usage\n======================\n\n23.6.1 source and find commands\n-------------------------------\n\nWhere: In many configuration files\nExample: source [find FILENAME]\nRemember the parsing rules\n  1. The 'find' command is in square brackets, and is executed with the\n     parameter FILENAME. It should find and return the full path to a\n     file with that name; it uses an internal search path.  The RESULT\n     is a string, which is substituted into the command line in place of\n     the bracketed 'find' command.  (Don't try to use a FILENAME which\n     includes the \"#\" character.  That character begins Tcl comments.)\n  2. The 'source' command is executed with the resulting filename; it\n     reads a file and executes as a script.\n\n23.6.2 format command\n---------------------\n\nWhere: Generally occurs in numerous places.\nTcl has no command like printf(), instead it has format, which is really\nmore like sprintf().  Example\n         set x 6\n         set y 7\n         puts [format \"The answer: %d\" [expr {$x * $y}]]\n  1. The SET command creates 2 variables, X and Y.\n  2. The double [nested] EXPR command performs math\n     The EXPR command produces numerical result as a string.\n     Refer to Rule #1\n  3. The format command is executed, producing a single string\n     Refer to Rule #1.\n  4. The PUTS command outputs the text.\n\n23.6.3 Body or Inlined Text\n---------------------------\n\nWhere: Various TARGET scripts.\n     #1 Good\n        proc someproc {} {\n            ... multiple lines of stuff ...\n        }\n        $_TARGETNAME configure -event FOO someproc\n     #2 Good - no variables\n        $_TARGETNAME configure -event foo \"this ; that;\"\n     #3 Good Curly Braces\n        $_TARGETNAME configure -event FOO {\n             puts \"Time: [date]\"\n        }\n     #4 DANGER DANGER DANGER\n        $_TARGETNAME configure -event foo \"puts \\\"Time: [date]\\\"\"\n  1. The $_TARGETNAME is an OpenOCD variable convention.\n     $_TARGETNAME represents the last target created, the value changes\n     each time a new target is created.  Remember the parsing rules.\n     When the ascii text is parsed, the $_TARGETNAME becomes a simple\n     string, the name of the target which happens to be a TARGET\n     (object) command.\n  2. The 2nd parameter to the '-event' parameter is a TCBODY\n     There are 4 examples:\n       1. The TCLBODY is a simple string that happens to be a proc name\n       2. The TCLBODY is several simple commands separated by semicolons\n       3. The TCLBODY is a multi-line {curly-brace} quoted string\n       4. The TCLBODY is a string with variables that get expanded.\n\n     In the end, when the target event FOO occurs the TCLBODY is\n     evaluated.  Method #1 and #2 are functionally identical.  For\n     Method #3 and #4 it is more interesting.  What is the TCLBODY?\n\n     Remember the parsing rules.  In case #3, {curly-braces} mean the\n     $VARS and [square-brackets] are expanded later, when the EVENT\n     occurs, and the text is evaluated.  In case #4, they are replaced\n     before the \"Target Object Command\" is executed.  This occurs at the\n     same time $_TARGETNAME is replaced.  In case #4 the date will never\n     change.  {BTW: [date] is a bad example; at this writing,\n     Jim/OpenOCD does not have a date command}\n\n23.6.4 Global Variables\n-----------------------\n\nWhere: You might discover this when writing your own procs\nIn simple terms: Inside a PROC, if you need to access a global variable\nyou must say so.  See also \"upvar\".  Example:\n     proc myproc { } {\n          set y 0 #Local variable Y\n          global x #Global variable X\n          puts [format \"X=%d, Y=%d\" $x $y]\n     }\n\n23.7 Other Tcl Hacks\n====================\n\nDynamic variable creation\n     # Dynamically create a bunch of variables.\n     for { set x 0 } { $x < 32 } { set x [expr {$x + 1}]} {\n         # Create var name\n         set vn [format \"BIT%d\" $x]\n         # Make it a global\n         global $vn\n         # Set it.\n         set $vn [expr {1 << $x}]\n     }\nDynamic proc/command creation\n     # One \"X\" function - 5 uart functions.\n     foreach who {A B C D E}\n        proc [format \"show_uart%c\" $who] { } \"show_UARTx $who\"\n     }\n\n\u001f\nFile: openocd.info,  Node: License,  Next: OpenOCD Concept Index,  Prev: Tcl Crash Course,  Up: Top\n\nAppendix A The GNU Free Documentation License.\n**********************************************\n\n                      Version 1.2, November 2002\n\n     Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.\n     51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA\n\n     Everyone is permitted to copy and distribute verbatim copies\n     of this license document, but changing it is not allowed.\n\n  0. PREAMBLE\n\n     The purpose of this License is to make a manual, textbook, or other\n     functional and useful document \"free\" in the sense of freedom: to\n     assure everyone the effective freedom to copy and redistribute it,\n     with or without modifying it, either commercially or\n     noncommercially.  Secondarily, this License preserves for the\n     author and publisher a way to get credit for their work, while not\n     being considered responsible for modifications made by others.\n\n     This License is a kind of \"copyleft\", which means that derivative\n     works of the document must themselves be free in the same sense.\n     It complements the GNU General Public License, which is a copyleft\n     license designed for free software.\n\n     We have designed this License in order to use it for manuals for\n     free software, because free software needs free documentation: a\n     free program should come with manuals providing the same freedoms\n     that the software does.  But this License is not limited to\n     software manuals; it can be used for any textual work, regardless\n     of subject matter or whether it is published as a printed book.  We\n     recommend this License principally for works whose purpose is\n     instruction or reference.\n\n  1. APPLICABILITY AND DEFINITIONS\n\n     This License applies to any manual or other work, in any medium,\n     that contains a notice placed by the copyright holder saying it can\n     be distributed under the terms of this License.  Such a notice\n     grants a world-wide, royalty-free license, unlimited in duration,\n     to use that work under the conditions stated herein.  The\n     \"Document\", below, refers to any such manual or work.  Any member\n     of the public is a licensee, and is addressed as \"you\".  You accept\n     the license if you copy, modify or distribute the work in a way\n     requiring permission under copyright law.\n\n     A \"Modified Version\" of the Document means any work containing the\n     Document or a portion of it, either copied verbatim, or with\n     modifications and/or translated into another language.\n\n     A \"Secondary Section\" is a named appendix or a front-matter section\n     of the Document that deals exclusively with the relationship of the\n     publishers or authors of the Document to the Document's overall\n     subject (or to related matters) and contains nothing that could\n     fall directly within that overall subject.  (Thus, if the Document\n     is in part a textbook of mathematics, a Secondary Section may not\n     explain any mathematics.)  The relationship could be a matter of\n     historical connection with the subject or with related matters, or\n     of legal, commercial, philosophical, ethical or political position\n     regarding them.\n\n     The \"Invariant Sections\" are certain Secondary Sections whose\n     titles are designated, as being those of Invariant Sections, in the\n     notice that says that the Document is released under this License.\n     If a section does not fit the above definition of Secondary then it\n     is not allowed to be designated as Invariant.  The Document may\n     contain zero Invariant Sections.  If the Document does not identify\n     any Invariant Sections then there are none.\n\n     The \"Cover Texts\" are certain short passages of text that are\n     listed, as Front-Cover Texts or Back-Cover Texts, in the notice\n     that says that the Document is released under this License.  A\n     Front-Cover Text may be at most 5 words, and a Back-Cover Text may\n     be at most 25 words.\n\n     A \"Transparent\" copy of the Document means a machine-readable copy,\n     represented in a format whose specification is available to the\n     general public, that is suitable for revising the document\n     straightforwardly with generic text editors or (for images composed\n     of pixels) generic paint programs or (for drawings) some widely\n     available drawing editor, and that is suitable for input to text\n     formatters or for automatic translation to a variety of formats\n     suitable for input to text formatters.  A copy made in an otherwise\n     Transparent file format whose markup, or absence of markup, has\n     been arranged to thwart or discourage subsequent modification by\n     readers is not Transparent.  An image format is not Transparent if\n     used for any substantial amount of text.  A copy that is not\n     \"Transparent\" is called \"Opaque\".\n\n     Examples of suitable formats for Transparent copies include plain\n     ASCII without markup, Texinfo input format, LaTeX input format,\n     SGML or XML using a publicly available DTD, and standard-conforming\n     simple HTML, PostScript or PDF designed for human modification.\n     Examples of transparent image formats include PNG, XCF and JPG.\n     Opaque formats include proprietary formats that can be read and\n     edited only by proprietary word processors, SGML or XML for which\n     the DTD and/or processing tools are not generally available, and\n     the machine-generated HTML, PostScript or PDF produced by some word\n     processors for output purposes only.\n\n     The \"Title Page\" means, for a printed book, the title page itself,\n     plus such following pages as are needed to hold, legibly, the\n     material this License requires to appear in the title page.  For\n     works in formats which do not have any title page as such, \"Title\n     Page\" means the text near the most prominent appearance of the\n     work's title, preceding the beginning of the body of the text.\n\n     A section \"Entitled XYZ\" means a named subunit of the Document\n     whose title either is precisely XYZ or contains XYZ in parentheses\n     following text that translates XYZ in another language.  (Here XYZ\n     stands for a specific section name mentioned below, such as\n     \"Acknowledgements\", \"Dedications\", \"Endorsements\", or \"History\".)\n     To \"Preserve the Title\" of such a section when you modify the\n     Document means that it remains a section \"Entitled XYZ\" according\n     to this definition.\n\n     The Document may include Warranty Disclaimers next to the notice\n     which states that this License applies to the Document.  These\n     Warranty Disclaimers are considered to be included by reference in\n     this License, but only as regards disclaiming warranties: any other\n     implication that these Warranty Disclaimers may have is void and\n     has no effect on the meaning of this License.\n\n  2. VERBATIM COPYING\n\n     You may copy and distribute the Document in any medium, either\n     commercially or noncommercially, provided that this License, the\n     copyright notices, and the license notice saying this License\n     applies to the Document are reproduced in all copies, and that you\n     add no other conditions whatsoever to those of this License.  You\n     may not use technical measures to obstruct or control the reading\n     or further copying of the copies you make or distribute.  However,\n     you may accept compensation in exchange for copies.  If you\n     distribute a large enough number of copies you must also follow the\n     conditions in section 3.\n\n     You may also lend copies, under the same conditions stated above,\n     and you may publicly display copies.\n\n  3. COPYING IN QUANTITY\n\n     If you publish printed copies (or copies in media that commonly\n     have printed covers) of the Document, numbering more than 100, and\n     the Document's license notice requires Cover Texts, you must\n     enclose the copies in covers that carry, clearly and legibly, all\n     these Cover Texts: Front-Cover Texts on the front cover, and\n     Back-Cover Texts on the back cover.  Both covers must also clearly\n     and legibly identify you as the publisher of these copies.  The\n     front cover must present the full title with all words of the title\n     equally prominent and visible.  You may add other material on the\n     covers in addition.  Copying with changes limited to the covers, as\n     long as they preserve the title of the Document and satisfy these\n     conditions, can be treated as verbatim copying in other respects.\n\n     If the required texts for either cover are too voluminous to fit\n     legibly, you should put the first ones listed (as many as fit\n     reasonably) on the actual cover, and continue the rest onto\n     adjacent pages.\n\n     If you publish or distribute Opaque copies of the Document\n     numbering more than 100, you must either include a machine-readable\n     Transparent copy along with each Opaque copy, or state in or with\n     each Opaque copy a computer-network location from which the general\n     network-using public has access to download using public-standard\n     network protocols a complete Transparent copy of the Document, free\n     of added material.  If you use the latter option, you must take\n     reasonably prudent steps, when you begin distribution of Opaque\n     copies in quantity, to ensure that this Transparent copy will\n     remain thus accessible at the stated location until at least one\n     year after the last time you distribute an Opaque copy (directly or\n     through your agents or retailers) of that edition to the public.\n\n     It is requested, but not required, that you contact the authors of\n     the Document well before redistributing any large number of copies,\n     to give them a chance to provide you with an updated version of the\n     Document.\n\n  4. MODIFICATIONS\n\n     You may copy and distribute a Modified Version of the Document\n     under the conditions of sections 2 and 3 above, provided that you\n     release the Modified Version under precisely this License, with the\n     Modified Version filling the role of the Document, thus licensing\n     distribution and modification of the Modified Version to whoever\n     possesses a copy of it.  In addition, you must do these things in\n     the Modified Version:\n\n       A. Use in the Title Page (and on the covers, if any) a title\n          distinct from that of the Document, and from those of previous\n          versions (which should, if there were any, be listed in the\n          History section of the Document).  You may use the same title\n          as a previous version if the original publisher of that\n          version gives permission.\n\n       B. List on the Title Page, as authors, one or more persons or\n          entities responsible for authorship of the modifications in\n          the Modified Version, together with at least five of the\n          principal authors of the Document (all of its principal\n          authors, if it has fewer than five), unless they release you\n          from this requirement.\n\n       C. State on the Title page the name of the publisher of the\n          Modified Version, as the publisher.\n\n       D. Preserve all the copyright notices of the Document.\n\n       E. Add an appropriate copyright notice for your modifications\n          adjacent to the other copyright notices.\n\n       F. Include, immediately after the copyright notices, a license\n          notice giving the public permission to use the Modified\n          Version under the terms of this License, in the form shown in\n          the Addendum below.\n\n       G. Preserve in that license notice the full lists of Invariant\n          Sections and required Cover Texts given in the Document's\n          license notice.\n\n       H. Include an unaltered copy of this License.\n\n       I. Preserve the section Entitled \"History\", Preserve its Title,\n          and add to it an item stating at least the title, year, new\n          authors, and publisher of the Modified Version as given on the\n          Title Page.  If there is no section Entitled \"History\" in the\n          Document, create one stating the title, year, authors, and\n          publisher of the Document as given on its Title Page, then add\n          an item describing the Modified Version as stated in the\n          previous sentence.\n\n       J. Preserve the network location, if any, given in the Document\n          for public access to a Transparent copy of the Document, and\n          likewise the network locations given in the Document for\n          previous versions it was based on.  These may be placed in the\n          \"History\" section.  You may omit a network location for a work\n          that was published at least four years before the Document\n          itself, or if the original publisher of the version it refers\n          to gives permission.\n\n       K. For any section Entitled \"Acknowledgements\" or \"Dedications\",\n          Preserve the Title of the section, and preserve in the section\n          all the substance and tone of each of the contributor\n          acknowledgements and/or dedications given therein.\n\n       L. Preserve all the Invariant Sections of the Document, unaltered\n          in their text and in their titles.  Section numbers or the\n          equivalent are not considered part of the section titles.\n\n       M. Delete any section Entitled \"Endorsements\".  Such a section\n          may not be included in the Modified Version.\n\n       N. Do not retitle any existing section to be Entitled\n          \"Endorsements\" or to conflict in title with any Invariant\n          Section.\n\n       O. Preserve any Warranty Disclaimers.\n\n     If the Modified Version includes new front-matter sections or\n     appendices that qualify as Secondary Sections and contain no\n     material copied from the Document, you may at your option designate\n     some or all of these sections as invariant.  To do this, add their\n     titles to the list of Invariant Sections in the Modified Version's\n     license notice.  These titles must be distinct from any other\n     section titles.\n\n     You may add a section Entitled \"Endorsements\", provided it contains\n     nothing but endorsements of your Modified Version by various\n     parties--for example, statements of peer review or that the text\n     has been approved by an organization as the authoritative\n     definition of a standard.\n\n     You may add a passage of up to five words as a Front-Cover Text,\n     and a passage of up to 25 words as a Back-Cover Text, to the end of\n     the list of Cover Texts in the Modified Version.  Only one passage\n     of Front-Cover Text and one of Back-Cover Text may be added by (or\n     through arrangements made by) any one entity.  If the Document\n     already includes a cover text for the same cover, previously added\n     by you or by arrangement made by the same entity you are acting on\n     behalf of, you may not add another; but you may replace the old\n     one, on explicit permission from the previous publisher that added\n     the old one.\n\n     The author(s) and publisher(s) of the Document do not by this\n     License give permission to use their names for publicity for or to\n     assert or imply endorsement of any Modified Version.\n\n  5. COMBINING DOCUMENTS\n\n     You may combine the Document with other documents released under\n     this License, under the terms defined in section 4 above for\n     modified versions, provided that you include in the combination all\n     of the Invariant Sections of all of the original documents,\n     unmodified, and list them all as Invariant Sections of your\n     combined work in its license notice, and that you preserve all\n     their Warranty Disclaimers.\n\n     The combined work need only contain one copy of this License, and\n     multiple identical Invariant Sections may be replaced with a single\n     copy.  If there are multiple Invariant Sections with the same name\n     but different contents, make the title of each such section unique\n     by adding at the end of it, in parentheses, the name of the\n     original author or publisher of that section if known, or else a\n     unique number.  Make the same adjustment to the section titles in\n     the list of Invariant Sections in the license notice of the\n     combined work.\n\n     In the combination, you must combine any sections Entitled\n     \"History\" in the various original documents, forming one section\n     Entitled \"History\"; likewise combine any sections Entitled\n     \"Acknowledgements\", and any sections Entitled \"Dedications\".  You\n     must delete all sections Entitled \"Endorsements.\"\n\n  6. COLLECTIONS OF DOCUMENTS\n\n     You may make a collection consisting of the Document and other\n     documents released under this License, and replace the individual\n     copies of this License in the various documents with a single copy\n     that is included in the collection, provided that you follow the\n     rules of this License for verbatim copying of each of the documents\n     in all other respects.\n\n     You may extract a single document from such a collection, and\n     distribute it individually under this License, provided you insert\n     a copy of this License into the extracted document, and follow this\n     License in all other respects regarding verbatim copying of that\n     document.\n\n  7. AGGREGATION WITH INDEPENDENT WORKS\n\n     A compilation of the Document or its derivatives with other\n     separate and independent documents or works, in or on a volume of a\n     storage or distribution medium, is called an \"aggregate\" if the\n     copyright resulting from the compilation is not used to limit the\n     legal rights of the compilation's users beyond what the individual\n     works permit.  When the Document is included in an aggregate, this\n     License does not apply to the other works in the aggregate which\n     are not themselves derivative works of the Document.\n\n     If the Cover Text requirement of section 3 is applicable to these\n     copies of the Document, then if the Document is less than one half\n     of the entire aggregate, the Document's Cover Texts may be placed\n     on covers that bracket the Document within the aggregate, or the\n     electronic equivalent of covers if the Document is in electronic\n     form.  Otherwise they must appear on printed covers that bracket\n     the whole aggregate.\n\n  8. TRANSLATION\n\n     Translation is considered a kind of modification, so you may\n     distribute translations of the Document under the terms of section\n     4.  Replacing Invariant Sections with translations requires special\n     permission from their copyright holders, but you may include\n     translations of some or all Invariant Sections in addition to the\n     original versions of these Invariant Sections.  You may include a\n     translation of this License, and all the license notices in the\n     Document, and any Warranty Disclaimers, provided that you also\n     include the original English version of this License and the\n     original versions of those notices and disclaimers.  In case of a\n     disagreement between the translation and the original version of\n     this License or a notice or disclaimer, the original version will\n     prevail.\n\n     If a section in the Document is Entitled \"Acknowledgements\",\n     \"Dedications\", or \"History\", the requirement (section 4) to\n     Preserve its Title (section 1) will typically require changing the\n     actual title.\n\n  9. TERMINATION\n\n     You may not copy, modify, sublicense, or distribute the Document\n     except as expressly provided for under this License.  Any other\n     attempt to copy, modify, sublicense or distribute the Document is\n     void, and will automatically terminate your rights under this\n     License.  However, parties who have received copies, or rights,\n     from you under this License will not have their licenses terminated\n     so long as such parties remain in full compliance.\n\n  10. FUTURE REVISIONS OF THIS LICENSE\n\n     The Free Software Foundation may publish new, revised versions of\n     the GNU Free Documentation License from time to time.  Such new\n     versions will be similar in spirit to the present version, but may\n     differ in detail to address new problems or concerns.  See\n     <https://www.gnu.org/licenses/>.\n\n     Each version of the License is given a distinguishing version\n     number.  If the Document specifies that a particular numbered\n     version of this License \"or any later version\" applies to it, you\n     have the option of following the terms and conditions either of\n     that specified version or of any later version that has been\n     published (not as a draft) by the Free Software Foundation.  If the\n     Document does not specify a version number of this License, you may\n     choose any version ever published (not as a draft) by the Free\n     Software Foundation.\n\nADDENDUM: How to use this License for your documents\n====================================================\n\nTo use this License in a document you have written, include a copy of\nthe License in the document and put the following copyright and license\nnotices just after the title page:\n\n       Copyright (C)  YEAR  YOUR NAME.\n       Permission is granted to copy, distribute and/or modify this document\n       under the terms of the GNU Free Documentation License, Version 1.2\n       or any later version published by the Free Software Foundation;\n       with no Invariant Sections, no Front-Cover Texts, and no Back-Cover\n       Texts.  A copy of the license is included in the section entitled ``GNU\n       Free Documentation License''.\n\nIf you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,\nreplace the \"with...Texts.\"  line with this:\n\n         with the Invariant Sections being LIST THEIR TITLES, with\n         the Front-Cover Texts being LIST, and with the Back-Cover Texts\n         being LIST.\n\nIf you have Invariant Sections without Cover Texts, or some other\ncombination of the three, merge those two alternatives to suit the\nsituation.\n\nIf your document contains nontrivial examples of program code, we\nrecommend releasing these examples in parallel under your choice of free\nsoftware license, such as the GNU General Public License, to permit\ntheir use in free software.\n\n\u001f\nFile: openocd.info,  Node: OpenOCD Concept Index,  Next: Command and Driver Index,  Prev: License,  Up: Top\n\nOpenOCD Concept Index\n*********************\n\n\u0000\b[index\u0000\b]\n* Menu:\n\n* aarch64:                               Architecture and Core Commands.\n                                                             (line  959)\n* about:                                 About.              (line    6)\n* adaptive clocking:                     Debug Adapter Configuration.\n                                                             (line 1304)\n* adaptive clocking <1>:                 FAQ.                (line    6)\n* ambiqmicro:                            Flash Commands.     (line  632)\n* apollo:                                Flash Commands.     (line  632)\n* ARC:                                   Architecture and Core Commands.\n                                                             (line 1459)\n* Architecture Specific Commands:        Architecture and Core Commands.\n                                                             (line    6)\n* ARM:                                   Architecture and Core Commands.\n                                                             (line  271)\n* ARM semihosting:                       OpenOCD Project Setup.\n                                                             (line  314)\n* ARM semihosting <1>:                   Architecture and Core Commands.\n                                                             (line  312)\n* ARM semihosting <2>:                   Architecture and Core Commands.\n                                                             (line  323)\n* ARM semihosting <3>:                   Architecture and Core Commands.\n                                                             (line  333)\n* ARM semihosting <4>:                   Architecture and Core Commands.\n                                                             (line  344)\n* ARM semihosting <5>:                   Architecture and Core Commands.\n                                                             (line  353)\n* ARM semihosting <6>:                   Architecture and Core Commands.\n                                                             (line  374)\n* ARM semihosting <7>:                   Architecture and Core Commands.\n                                                             (line  383)\n* ARM11:                                 Architecture and Core Commands.\n                                                             (line  650)\n* ARM7:                                  Architecture and Core Commands.\n                                                             (line  397)\n* ARM9:                                  Architecture and Core Commands.\n                                                             (line  397)\n* ARM9 <1>:                              Architecture and Core Commands.\n                                                             (line  435)\n* ARM920T:                               Architecture and Core Commands.\n                                                             (line  455)\n* ARM926ej-s:                            Architecture and Core Commands.\n                                                             (line  480)\n* ARM966E:                               Architecture and Core Commands.\n                                                             (line  494)\n* ARMv4:                                 Architecture and Core Commands.\n                                                             (line  390)\n* ARMv5:                                 Architecture and Core Commands.\n                                                             (line  390)\n* ARMv6:                                 Architecture and Core Commands.\n                                                             (line  646)\n* ARMv7:                                 Architecture and Core Commands.\n                                                             (line  684)\n* ARMv8:                                 Architecture and Core Commands.\n                                                             (line  683)\n* ARMv8-A:                               Architecture and Core Commands.\n                                                             (line  959)\n* at91sam3:                              Flash Commands.     (line  748)\n* at91sam4:                              Flash Commands.     (line  803)\n* at91sam4l:                             Flash Commands.     (line  808)\n* at91samd:                              Flash Commands.     (line  670)\n* ath79:                                 Flash Commands.     (line  581)\n* Atheros ath79 SPI driver:              Flash Commands.     (line  581)\n* atsame5:                               Flash Commands.     (line  819)\n* atsamv:                                Flash Commands.     (line  872)\n* autoprobe:                             TAP Declaration.    (line  323)\n* board config file:                     Config File Guidelines.\n                                                             (line   68)\n* breakpoint:                            General Commands.   (line  383)\n* bscan_spi:                             Flash Commands.     (line  329)\n* CFI:                                   Flash Commands.     (line  294)\n* command line options:                  Running.            (line    6)\n* commands:                              General Commands.   (line    6)\n* Common Flash Interface:                Flash Commands.     (line  294)\n* config command:                        Server Configuration.\n                                                             (line   13)\n* config file, board:                    Config File Guidelines.\n                                                             (line   68)\n* config file, interface:                Debug Adapter Configuration.\n                                                             (line    6)\n* config file, overview:                 OpenOCD Project Setup.\n                                                             (line  139)\n* config file, target:                   Config File Guidelines.\n                                                             (line  298)\n* config file, user:                     OpenOCD Project Setup.\n                                                             (line  139)\n* configuration stage:                   Server Configuration.\n                                                             (line   13)\n* Connecting to GDB:                     GDB and OpenOCD.    (line   27)\n* Core Specific Commands:                Architecture and Core Commands.\n                                                             (line    6)\n* Cortex-A:                              Architecture and Core Commands.\n                                                             (line  687)\n* Cortex-M:                              Architecture and Core Commands.\n                                                             (line  900)\n* Cortex-R:                              Architecture and Core Commands.\n                                                             (line  722)\n* CPU type:                              CPU Configuration.  (line   60)\n* CTI:                                   Architecture and Core Commands.\n                                                             (line  225)\n* DAP declaration:                       TAP Declaration.    (line  379)\n* DCC:                                   Architecture and Core Commands.\n                                                             (line  413)\n* DCC <1>:                               Architecture and Core Commands.\n                                                             (line 1686)\n* developers:                            Developers.         (line    6)\n* directory search:                      Running.            (line    6)\n* disassemble:                           Architecture and Core Commands.\n                                                             (line  282)\n* disassemble <1>:                       Architecture and Core Commands.\n                                                             (line  972)\n* dongles:                               Debug Adapter Hardware.\n                                                             (line    6)\n* dotted name:                           TAP Declaration.    (line   98)\n* ETB:                                   Architecture and Core Commands.\n                                                             (line   14)\n* ETM:                                   Architecture and Core Commands.\n                                                             (line   14)\n* ETM <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* event, reset-init:                     Config File Guidelines.\n                                                             (line  184)\n* events:                                Reset Configuration.\n                                                             (line  226)\n* events <1>:                            TAP Declaration.    (line  222)\n* events <2>:                            CPU Configuration.  (line  462)\n* faq:                                   FAQ.                (line    6)\n* fespi:                                 Flash Commands.     (line  614)\n* Firmware recovery:                     Utility Commands.   (line   45)\n* flash configuration:                   Flash Commands.     (line   36)\n* flash erasing:                         Flash Commands.     (line  102)\n* flash programming:                     Flash Commands.     (line  102)\n* flash protection:                      Flash Commands.     (line  230)\n* flash reading:                         Flash Commands.     (line  102)\n* flash writing:                         Flash Commands.     (line  102)\n* FPGA:                                  PLD/FPGA Commands.  (line    6)\n* Freedom E SPI:                         Flash Commands.     (line  614)\n* FTDI:                                  Debug Adapter Hardware.\n                                                             (line    6)\n* GDB:                                   Server Configuration.\n                                                             (line  173)\n* GDB <1>:                               GDB and OpenOCD.    (line    6)\n* GDB configuration:                     Server Configuration.\n                                                             (line  173)\n* GDB server:                            Server Configuration.\n                                                             (line  126)\n* GDB target:                            CPU Configuration.  (line    6)\n* Generic JTAG2SPI driver:               Flash Commands.     (line  329)\n* halt:                                  General Commands.   (line  103)\n* hwthread:                              GDB and OpenOCD.    (line  292)\n* image dumping:                         General Commands.   (line  329)\n* image loading:                         General Commands.   (line  329)\n* initialization:                        Server Configuration.\n                                                             (line    6)\n* init_board procedure:                  Config File Guidelines.\n                                                             (line  249)\n* init_targets procedure:                Config File Guidelines.\n                                                             (line  522)\n* init_target_events procedure:          Config File Guidelines.\n                                                             (line  567)\n* interface config file:                 Debug Adapter Configuration.\n                                                             (line    6)\n* IPDBG:                                 Boundary Scan Commands.\n                                                             (line   73)\n* IPDBG JTAG-Host server:                Boundary Scan Commands.\n                                                             (line   73)\n* ITM:                                   Architecture and Core Commands.\n                                                             (line  890)\n* Jim-Tcl:                               About Jim-Tcl.      (line    6)\n* jrc:                                   TAP Declaration.    (line  260)\n* JTAG:                                  About.              (line   15)\n* JTAG <1>:                              Debug Adapter Configuration.\n                                                             (line 1184)\n* JTAG autoprobe:                        TAP Declaration.    (line  323)\n* JTAG Commands:                         JTAG Commands.      (line    6)\n* JTAG Route Controller:                 TAP Declaration.    (line  260)\n* jtagspi:                               Flash Commands.     (line  329)\n* kinetis:                               Flash Commands.     (line 1040)\n* kinetis_ke:                            Flash Commands.     (line 1127)\n* libdcc:                                Architecture and Core Commands.\n                                                             (line 1686)\n* Linux-ARM DCC support:                 Architecture and Core Commands.\n                                                             (line 1686)\n* logfile:                               Running.            (line    6)\n* lpcspifi:                              Flash Commands.     (line  423)\n* memory access:                         General Commands.   (line  291)\n* message level:                         General Commands.   (line   73)\n* NAND:                                  Flash Commands.     (line 2132)\n* NAND configuration:                    Flash Commands.     (line 2187)\n* NAND erasing:                          Flash Commands.     (line 2267)\n* NAND other commands:                   Flash Commands.     (line 2358)\n* NAND programming:                      Flash Commands.     (line 2267)\n* NAND programming <1>:                  Flash Commands.     (line 2280)\n* NAND programming <2>:                  Flash Commands.     (line 2333)\n* NAND reading:                          Flash Commands.     (line 2234)\n* NAND verification:                     Flash Commands.     (line 2333)\n* NAND writing:                          Flash Commands.     (line 2280)\n* NXP SPI Flash Interface:               Flash Commands.     (line  423)\n* object command:                        CPU Configuration.  (line  307)\n* OctoSPI:                               Flash Commands.     (line  460)\n* PLD:                                   PLD/FPGA Commands.  (line    6)\n* port:                                  Server Configuration.\n                                                             (line  116)\n* printer port:                          Debug Adapter Hardware.\n                                                             (line    6)\n* profiling:                             General Commands.   (line  488)\n* Programming using GDB:                 GDB and OpenOCD.    (line  127)\n* QuadSPI:                               Flash Commands.     (line  460)\n* RAM testing:                           Utility Commands.   (line    9)\n* reset:                                 General Commands.   (line  103)\n* Reset Configuration:                   Reset Configuration.\n                                                             (line    6)\n* reset-init handler:                    Config File Guidelines.\n                                                             (line  184)\n* RPC:                                   Tcl Scripting API.  (line   65)\n* RPC Notifications:                     Tcl Scripting API.  (line   83)\n* RPC trace output:                      Tcl Scripting API.  (line  100)\n* RTCK:                                  Debug Adapter Hardware.\n                                                             (line    6)\n* RTCK <1>:                              Debug Adapter Configuration.\n                                                             (line 1304)\n* RTCK <2>:                              FAQ.                (line    6)\n* RTOS:                                  GDB and OpenOCD.    (line  292)\n* RTOS Support:                          GDB and OpenOCD.    (line  211)\n* scan chain:                            TAP Declaration.    (line   28)\n* security:                              Server Configuration.\n                                                             (line  116)\n* Serial Peripheral Interface:           Debug Adapter Configuration.\n                                                             (line 1228)\n* Serial Vector Format:                  Boundary Scan Commands.\n                                                             (line   13)\n* Serial Wire Debug:                     Debug Adapter Configuration.\n                                                             (line 1199)\n* server:                                Server Configuration.\n                                                             (line  116)\n* Single Wire Interface Module:          Debug Adapter Configuration.\n                                                             (line 1235)\n* SMI:                                   Flash Commands.     (line  440)\n* SMP:                                   Config File Guidelines.\n                                                             (line  425)\n* SMP <1>:                               GDB and OpenOCD.    (line  292)\n* SPI:                                   Debug Adapter Configuration.\n                                                             (line 1228)\n* SPI <1>:                               Flash Commands.     (line  329)\n* SPIFI:                                 Flash Commands.     (line  423)\n* STMicroelectronics QuadSPI/OctoSPI Interface: Flash Commands.\n                                                             (line  460)\n* STMicroelectronics Serial Memory Interface: Flash Commands.\n                                                             (line  440)\n* stmqspi:                               Flash Commands.     (line  460)\n* stmsmi:                                Flash Commands.     (line  440)\n* str9xpec:                              Flash Commands.     (line 1997)\n* SVF:                                   Boundary Scan Commands.\n                                                             (line   13)\n* SWD:                                   Debug Adapter Configuration.\n                                                             (line 1199)\n* SWD multi-drop:                        Debug Adapter Configuration.\n                                                             (line 1215)\n* SWIM:                                  Debug Adapter Configuration.\n                                                             (line 1235)\n* swm050:                                Flash Commands.     (line 2075)\n* SWO:                                   Architecture and Core Commands.\n                                                             (line  732)\n* SWO <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* SWV:                                   Architecture and Core Commands.\n                                                             (line  732)\n* SWV <1>:                               Architecture and Core Commands.\n                                                             (line  890)\n* TAP:                                   About.              (line   15)\n* TAP configuration:                     TAP Declaration.    (line    6)\n* TAP declaration:                       TAP Declaration.    (line    6)\n* TAP events:                            TAP Declaration.    (line  222)\n* TAP naming convention:                 TAP Declaration.    (line  121)\n* TAP state names:                       JTAG Commands.      (line  125)\n* target config file:                    Config File Guidelines.\n                                                             (line  298)\n* target events:                         CPU Configuration.  (line  462)\n* target initialization:                 General Commands.   (line  103)\n* target type:                           CPU Configuration.  (line   60)\n* target, current:                       CPU Configuration.  (line   18)\n* target, list:                          CPU Configuration.  (line   18)\n* tcl:                                   About Jim-Tcl.      (line    6)\n* Tcl:                                   Tcl Crash Course.   (line    6)\n* Tcl Scripting API:                     Tcl Scripting API.  (line    6)\n* Tcl scripts:                           Tcl Scripting API.  (line    5)\n* TCP port:                              Server Configuration.\n                                                             (line  116)\n* TPIU:                                  Architecture and Core Commands.\n                                                             (line  732)\n* tracing:                               Architecture and Core Commands.\n                                                             (line   14)\n* tracing <1>:                           Architecture and Core Commands.\n                                                             (line  732)\n* tracing <2>:                           Architecture and Core Commands.\n                                                             (line  890)\n* tracing <3>:                           Architecture and Core Commands.\n                                                             (line 1686)\n* translation:                           Config File Guidelines.\n                                                             (line  612)\n* Transport:                             Debug Adapter Configuration.\n                                                             (line 1158)\n* USB Adapter:                           Debug Adapter Hardware.\n                                                             (line    6)\n* user config file:                      OpenOCD Project Setup.\n                                                             (line  139)\n* Using GDB as a non-intrusive memory inspector: GDB and OpenOCD.\n                                                             (line  167)\n* Utility Commands:                      Utility Commands.   (line    5)\n* variable names:                        Config File Guidelines.\n                                                             (line  152)\n* vector_catch:                          OpenOCD Project Setup.\n                                                             (line  213)\n* vector_catch <1>:                      Architecture and Core Commands.\n                                                             (line  440)\n* vector_catch <2>:                      Architecture and Core Commands.\n                                                             (line  619)\n* vector_catch <3>:                      Architecture and Core Commands.\n                                                             (line  672)\n* vector_catch <4>:                      Architecture and Core Commands.\n                                                             (line  925)\n* vector_table:                          Architecture and Core Commands.\n                                                             (line  634)\n* watchpoint:                            General Commands.   (line  383)\n* wiggler:                               Debug Adapter Hardware.\n                                                             (line    6)\n* xcf:                                   Flash Commands.     (line  387)\n* Xilinx Platform flash driver:          Flash Commands.     (line  387)\n* Xilinx Serial Vector Format:           Boundary Scan Commands.\n                                                             (line   39)\n* XScale:                                Architecture and Core Commands.\n                                                             (line  508)\n* XSVF:                                  Boundary Scan Commands.\n                                                             (line   39)\n\n\u001f\nFile: openocd.info,  Node: Command and Driver Index,  Prev: OpenOCD Concept Index,  Up: Top\n\nCommand and Driver Index\n************************\n\n\u0000\b[index\u0000\b]\n* Menu:\n\n* $cti_name ack:                         Architecture and Core Commands.\n                                                             (line  253)\n* $cti_name channel:                     Architecture and Core Commands.\n                                                             (line  256)\n* $cti_name dump:                        Architecture and Core Commands.\n                                                             (line  243)\n* $cti_name enable:                      Architecture and Core Commands.\n                                                             (line  240)\n* $cti_name read:                        Architecture and Core Commands.\n                                                             (line  249)\n* $cti_name testmode:                    Architecture and Core Commands.\n                                                             (line  260)\n* $cti_name write:                       Architecture and Core Commands.\n                                                             (line  246)\n* $dap_name apcsw:                       TAP Declaration.    (line  469)\n* $dap_name apid:                        TAP Declaration.    (line  436)\n* $dap_name apreg:                       TAP Declaration.    (line  440)\n* $dap_name apsel:                       TAP Declaration.    (line  445)\n* $dap_name baseaddr:                    TAP Declaration.    (line  460)\n* $dap_name dpreg:                       TAP Declaration.    (line  448)\n* $dap_name info:                        TAP Declaration.    (line  432)\n* $dap_name memaccess:                   TAP Declaration.    (line  464)\n* $dap_name ti_be_32_quirks:             TAP Declaration.    (line  504)\n* $target_name arp_examine:              CPU Configuration.  (line  332)\n* $target_name arp_halt:                 CPU Configuration.  (line  333)\n* $target_name arp_poll:                 CPU Configuration.  (line  334)\n* $target_name arp_reset:                CPU Configuration.  (line  335)\n* $target_name arp_waitstate:            CPU Configuration.  (line  336)\n* $target_name catch_exc:                Architecture and Core Commands.\n                                                             (line  988)\n* $target_name cget:                     CPU Configuration.  (line  397)\n* $target_name configure:                CPU Configuration.  (line  221)\n* $target_name curstate:                 CPU Configuration.  (line  420)\n* $target_name eventlist:                CPU Configuration.  (line  425)\n* $target_name get_reg:                  CPU Configuration.  (line  353)\n* $target_name invoke-event:             CPU Configuration.  (line  429)\n* $target_name mdb:                      CPU Configuration.  (line  437)\n* $target_name mdd:                      CPU Configuration.  (line  434)\n* $target_name mdh:                      CPU Configuration.  (line  436)\n* $target_name mdw:                      CPU Configuration.  (line  435)\n* $target_name mwb:                      CPU Configuration.  (line  450)\n* $target_name mwd:                      CPU Configuration.  (line  447)\n* $target_name mwh:                      CPU Configuration.  (line  449)\n* $target_name mww:                      CPU Configuration.  (line  448)\n* $target_name read_memory:              CPU Configuration.  (line  381)\n* $target_name set_reg:                  CPU Configuration.  (line  341)\n* $target_name write_memory:             CPU Configuration.  (line  366)\n* $tpiu_name cget:                       Architecture and Core Commands.\n                                                             (line  778)\n* $tpiu_name configure:                  Architecture and Core Commands.\n                                                             (line  784)\n* $tpiu_name disable:                    Architecture and Core Commands.\n                                                             (line  856)\n* $tpiu_name enable:                     Architecture and Core Commands.\n                                                             (line  849)\n* aarch64 cache_info:                    Architecture and Core Commands.\n                                                             (line  959)\n* aarch64 dbginit:                       Architecture and Core Commands.\n                                                             (line  962)\n* aarch64 disassemble:                   Architecture and Core Commands.\n                                                             (line  971)\n* aarch64 maskisr:                       Architecture and Core Commands.\n                                                             (line  984)\n* aarch64 smp:                           Architecture and Core Commands.\n                                                             (line  975)\n* adapter assert:                        General Commands.   (line  264)\n* adapter deassert:                      General Commands.   (line  265)\n* adapter driver:                        Debug Adapter Configuration.\n                                                             (line   43)\n* adapter list:                          Debug Adapter Configuration.\n                                                             (line   46)\n* adapter name:                          Debug Adapter Configuration.\n                                                             (line   55)\n* adapter serial:                        Debug Adapter Configuration.\n                                                             (line   69)\n* adapter speed:                         Debug Adapter Configuration.\n                                                             (line 1287)\n* adapter srst delay:                    Reset Configuration.\n                                                             (line  126)\n* adapter srst pulse_width:              Reset Configuration.\n                                                             (line  121)\n* adapter transports:                    Debug Adapter Configuration.\n                                                             (line   49)\n* adapter usb location:                  Debug Adapter Configuration.\n                                                             (line   58)\n* addreg:                                Architecture and Core Commands.\n                                                             (line 1232)\n* add_help_text:                         General Commands.   (line  501)\n* add_script_search_dir:                 General Commands.   (line   91)\n* add_usage_text:                        General Commands.   (line  504)\n* aduc702x:                              Flash Commands.     (line  622)\n* am335xgpio:                            Debug Adapter Configuration.\n                                                             (line  877)\n* am335xgpio jtag_nums:                  Debug Adapter Configuration.\n                                                             (line  894)\n* am335xgpio led_num:                    Debug Adapter Configuration.\n                                                             (line  951)\n* am335xgpio led_on_state:               Debug Adapter Configuration.\n                                                             (line  955)\n* am335xgpio speed_coeffs:               Debug Adapter Configuration.\n                                                             (line  959)\n* am335xgpio srst_num:                   Debug Adapter Configuration.\n                                                             (line  945)\n* am335xgpio swclk_num:                  Debug Adapter Configuration.\n                                                             (line  924)\n* am335xgpio swdio_dir_num:              Debug Adapter Configuration.\n                                                             (line  934)\n* am335xgpio swdio_dir_output_state:     Debug Adapter Configuration.\n                                                             (line  941)\n* am335xgpio swdio_num:                  Debug Adapter Configuration.\n                                                             (line  929)\n* am335xgpio swd_nums:                   Debug Adapter Configuration.\n                                                             (line  919)\n* am335xgpio tck_num:                    Debug Adapter Configuration.\n                                                             (line  899)\n* am335xgpio tdi_num:                    Debug Adapter Configuration.\n                                                             (line  914)\n* am335xgpio tdo_num:                    Debug Adapter Configuration.\n                                                             (line  909)\n* am335xgpio tms_num:                    Debug Adapter Configuration.\n                                                             (line  904)\n* am335xgpio trst_num:                   Debug Adapter Configuration.\n                                                             (line  948)\n* ambiqmicro:                            Flash Commands.     (line  631)\n* ambiqmicro mass_erase:                 Flash Commands.     (line  659)\n* ambiqmicro page_erase:                 Flash Commands.     (line  661)\n* ambiqmicro program_otp:                Flash Commands.     (line  663)\n* amt_jtagaccel:                         Debug Adapter Configuration.\n                                                             (line   83)\n* arc add-reg:                           Architecture and Core Commands.\n                                                             (line 1480)\n* arc add-reg-type-flags:                Architecture and Core Commands.\n                                                             (line 1534)\n* arc add-reg-type-struct:               Architecture and Core Commands.\n                                                             (line 1539)\n* arc get-reg-field:                     Architecture and Core Commands.\n                                                             (line 1545)\n* arc jtag get-aux-reg:                  Architecture and Core Commands.\n                                                             (line 1567)\n* arc jtag get-core-reg:                 Architecture and Core Commands.\n                                                             (line 1573)\n* arc jtag set-aux-reg:                  Architecture and Core Commands.\n                                                             (line 1557)\n* arc jtag set-core-reg:                 Architecture and Core Commands.\n                                                             (line 1563)\n* arc set-reg-exists:                    Architecture and Core Commands.\n                                                             (line 1550)\n* arm core_state:                        Architecture and Core Commands.\n                                                             (line  275)\n* arm disassemble:                       Architecture and Core Commands.\n                                                             (line  281)\n* arm mcr:                               Architecture and Core Commands.\n                                                             (line  295)\n* arm mrc:                               Architecture and Core Commands.\n                                                             (line  301)\n* arm reg:                               Architecture and Core Commands.\n                                                             (line  307)\n* arm semihosting:                       Architecture and Core Commands.\n                                                             (line  311)\n* arm semihosting_basedir:               Architecture and Core Commands.\n                                                             (line  382)\n* arm semihosting_cmdline:               Architecture and Core Commands.\n                                                             (line  332)\n* arm semihosting_fileio:                Architecture and Core Commands.\n                                                             (line  343)\n* arm semihosting_read_user_param:       Architecture and Core Commands.\n                                                             (line  373)\n* arm semihosting_redirect:              Architecture and Core Commands.\n                                                             (line  322)\n* arm semihosting_resexit:               Architecture and Core Commands.\n                                                             (line  352)\n* arm-jtag-ew:                           Debug Adapter Configuration.\n                                                             (line   96)\n* arm11 memwrite burst:                  Architecture and Core Commands.\n                                                             (line  650)\n* arm11 memwrite error_fatal:            Architecture and Core Commands.\n                                                             (line  660)\n* arm11 step_irq_enable:                 Architecture and Core Commands.\n                                                             (line  666)\n* arm11 vcr:                             Architecture and Core Commands.\n                                                             (line  671)\n* arm7_9 dbgrq:                          Architecture and Core Commands.\n                                                             (line  402)\n* arm7_9 dcc_downloads:                  Architecture and Core Commands.\n                                                             (line  412)\n* arm7_9 fast_memory_access:             Architecture and Core Commands.\n                                                             (line  423)\n* arm9 vector_catch:                     Architecture and Core Commands.\n                                                             (line  439)\n* arm920t cache_info:                    Architecture and Core Commands.\n                                                             (line  460)\n* arm920t cp15:                          Architecture and Core Commands.\n                                                             (line  465)\n* arm920t read_cache:                    Architecture and Core Commands.\n                                                             (line  471)\n* arm920t read_mmu:                      Architecture and Core Commands.\n                                                             (line  474)\n* arm926ejs cache_info:                  Architecture and Core Commands.\n                                                             (line  488)\n* arm966e cp15:                          Architecture and Core Commands.\n                                                             (line  498)\n* armjtagew_info:                        Debug Adapter Configuration.\n                                                             (line  100)\n* at91rm9200:                            Debug Adapter Configuration.\n                                                             (line  103)\n* at91sam3:                              Flash Commands.     (line  747)\n* at91sam3 gpnvm:                        Flash Commands.     (line  779)\n* at91sam3 gpnvm clear:                  Flash Commands.     (line  780)\n* at91sam3 gpnvm set:                    Flash Commands.     (line  781)\n* at91sam3 gpnvm show:                   Flash Commands.     (line  782)\n* at91sam3 info:                         Flash Commands.     (line  788)\n* at91sam3 slowclk:                      Flash Commands.     (line  798)\n* at91sam4:                              Flash Commands.     (line  802)\n* at91sam4l:                             Flash Commands.     (line  807)\n* at91sam4l smap_reset_deassert:         Flash Commands.     (line  813)\n* at91sam7:                              Flash Commands.     (line  885)\n* at91sam7 gpnvm:                        Flash Commands.     (line  918)\n* at91sam9:                              Flash Commands.     (line 2399)\n* at91sam9 ale:                          Flash Commands.     (line 2413)\n* at91sam9 ce:                           Flash Commands.     (line 2424)\n* at91sam9 cle:                          Flash Commands.     (line 2410)\n* at91sam9 rdy_busy:                     Flash Commands.     (line 2419)\n* at91samd:                              Flash Commands.     (line  669)\n* at91samd bootloader:                   Flash Commands.     (line  710)\n* at91samd chip-erase:                   Flash Commands.     (line  680)\n* at91samd dsu_reset_deassert:           Flash Commands.     (line  722)\n* at91samd eeprom:                       Flash Commands.     (line  696)\n* at91samd nvmuserrow:                   Flash Commands.     (line  727)\n* at91samd set-security:                 Flash Commands.     (line  685)\n* ath79:                                 Flash Commands.     (line  580)\n* atsame5:                               Flash Commands.     (line  818)\n* atsame5 bootloader:                    Flash Commands.     (line  829)\n* atsame5 chip-erase:                    Flash Commands.     (line  841)\n* atsame5 dsu_reset_deassert:            Flash Commands.     (line  846)\n* atsame5 userpage:                      Flash Commands.     (line  851)\n* atsamv:                                Flash Commands.     (line  871)\n* atsamv gpnvm:                          Flash Commands.     (line  878)\n* atsamv gpnvm <1>:                      Flash Commands.     (line  879)\n* avr:                                   Flash Commands.     (line  926)\n* bcm2835gpio:                           Debug Adapter Configuration.\n                                                             (line  788)\n* bcm2835gpio jtag_nums:                 Debug Adapter Configuration.\n                                                             (line  804)\n* bcm2835gpio peripheral_base:           Debug Adapter Configuration.\n                                                             (line  862)\n* bcm2835gpio speed_coeffs:              Debug Adapter Configuration.\n                                                             (line  856)\n* bcm2835gpio srst_num:                  Debug Adapter Configuration.\n                                                             (line  850)\n* bcm2835gpio swclk_num:                 Debug Adapter Configuration.\n                                                             (line  834)\n* bcm2835gpio swdio_dir_num:             Debug Adapter Configuration.\n                                                             (line  844)\n* bcm2835gpio swdio_num:                 Debug Adapter Configuration.\n                                                             (line  839)\n* bcm2835gpio swd_nums:                  Debug Adapter Configuration.\n                                                             (line  829)\n* bcm2835gpio tck_num:                   Debug Adapter Configuration.\n                                                             (line  809)\n* bcm2835gpio tdi_num:                   Debug Adapter Configuration.\n                                                             (line  824)\n* bcm2835gpio tdo_num:                   Debug Adapter Configuration.\n                                                             (line  819)\n* bcm2835gpio tms_num:                   Debug Adapter Configuration.\n                                                             (line  814)\n* bcm2835gpio trst_num:                  Debug Adapter Configuration.\n                                                             (line  853)\n* bindto:                                General Commands.   (line   94)\n* bluenrg-x:                             Flash Commands.     (line  930)\n* bp:                                    General Commands.   (line  387)\n* buspirate:                             Debug Adapter Configuration.\n                                                             (line 1108)\n* buspirate led:                         Debug Adapter Configuration.\n                                                             (line 1151)\n* buspirate mode:                        Debug Adapter Configuration.\n                                                             (line 1129)\n* buspirate port:                        Debug Adapter Configuration.\n                                                             (line 1120)\n* buspirate pullup:                      Debug Adapter Configuration.\n                                                             (line 1138)\n* buspirate speed:                       Debug Adapter Configuration.\n                                                             (line 1124)\n* buspirate vreg:                        Debug Adapter Configuration.\n                                                             (line 1145)\n* cache_config l2x:                      Architecture and Core Commands.\n                                                             (line  709)\n* cc26xx:                                Flash Commands.     (line  948)\n* cc3220sf:                              Flash Commands.     (line  958)\n* cfi:                                   Flash Commands.     (line  293)\n* cmsis-dap:                             Debug Adapter Configuration.\n                                                             (line  107)\n* cmsis-dap cmd:                         Debug Adapter Configuration.\n                                                             (line  137)\n* cmsis-dap info:                        Debug Adapter Configuration.\n                                                             (line  133)\n* cmsis_dap_backend:                     Debug Adapter Configuration.\n                                                             (line  118)\n* cmsis_dap_usb interface:               Debug Adapter Configuration.\n                                                             (line  127)\n* cmsis_dap_vid_pid:                     Debug Adapter Configuration.\n                                                             (line  111)\n* command mode:                          Server Configuration.\n                                                             (line   29)\n* cortex_a cache_info:                   Architecture and Core Commands.\n                                                             (line  687)\n* cortex_a dacrfixup:                    Architecture and Core Commands.\n                                                             (line  690)\n* cortex_a dbginit:                      Architecture and Core Commands.\n                                                             (line  696)\n* cortex_a maskisr:                      Architecture and Core Commands.\n                                                             (line  706)\n* cortex_a mmu dump:                     Architecture and Core Commands.\n                                                             (line  712)\n* cortex_a smp:                          Architecture and Core Commands.\n                                                             (line  700)\n* cortex_a smp_gdb:                      Architecture and Core Commands.\n                                                             (line  703)\n* cortex_m maskisr:                      Architecture and Core Commands.\n                                                             (line  900)\n* cortex_m reset_config:                 Architecture and Core Commands.\n                                                             (line  940)\n* cortex_m vector_catch:                 Architecture and Core Commands.\n                                                             (line  924)\n* cortex_r4 dbginit:                     Architecture and Core Commands.\n                                                             (line  722)\n* cortex_r4 maskisr:                     Architecture and Core Commands.\n                                                             (line  726)\n* cti create:                            Architecture and Core Commands.\n                                                             (line  232)\n* cti names:                             Architecture and Core Commands.\n                                                             (line  264)\n* dap create:                            TAP Declaration.    (line  387)\n* dap info:                              TAP Declaration.    (line  421)\n* dap init:                              Server Configuration.\n                                                             (line   81)\n* dap init <1>:                          TAP Declaration.    (line  425)\n* dap names:                             TAP Declaration.    (line  417)\n* davinci:                               Flash Commands.     (line 2430)\n* debug_level:                           General Commands.   (line   72)\n* drscan:                                JTAG Commands.      (line   42)\n* dummy:                                 Debug Adapter Configuration.\n                                                             (line  147)\n* dummy <1>:                             Architecture and Core Commands.\n                                                             (line  190)\n* dump_image:                            General Commands.   (line  329)\n* du_select:                             Architecture and Core Commands.\n                                                             (line 1219)\n* echo:                                  General Commands.   (line   82)\n* efm32:                                 Flash Commands.     (line  970)\n* ep93xx:                                Debug Adapter Configuration.\n                                                             (line  150)\n* esirisc:                               Flash Commands.     (line  995)\n* esirisc cache_arch:                    Architecture and Core Commands.\n                                                             (line 1007)\n* esirisc flash mass_erase:              Flash Commands.     (line 1006)\n* esirisc flash ref_erase:               Flash Commands.     (line 1010)\n* esirisc flush_caches:                  Architecture and Core Commands.\n                                                             (line 1021)\n* esirisc hwdc:                          Architecture and Core Commands.\n                                                             (line 1012)\n* esirisc trace analyze:                 Architecture and Core Commands.\n                                                             (line 1149)\n* esirisc trace buffer:                  Architecture and Core Commands.\n                                                             (line 1051)\n* esirisc trace dump:                    Architecture and Core Commands.\n                                                             (line 1155)\n* esirisc trace fifo:                    Architecture and Core Commands.\n                                                             (line 1056)\n* esirisc trace flow_control:            Architecture and Core Commands.\n                                                             (line 1059)\n* esirisc trace format:                  Architecture and Core Commands.\n                                                             (line 1063)\n* esirisc trace info:                    Architecture and Core Commands.\n                                                             (line 1137)\n* esirisc trace init:                    Architecture and Core Commands.\n                                                             (line 1132)\n* esirisc trace start:                   Architecture and Core Commands.\n                                                             (line 1143)\n* esirisc trace status:                  Architecture and Core Commands.\n                                                             (line 1140)\n* esirisc trace stop:                    Architecture and Core Commands.\n                                                             (line 1146)\n* esirisc trace trigger delay:           Architecture and Core Commands.\n                                                             (line 1119)\n* esirisc trace trigger start:           Architecture and Core Commands.\n                                                             (line 1076)\n* esirisc trace trigger stop:            Architecture and Core Commands.\n                                                             (line 1099)\n* etb:                                   Architecture and Core Commands.\n                                                             (line  198)\n* etb config:                            Architecture and Core Commands.\n                                                             (line  201)\n* etb trigger_percent:                   Architecture and Core Commands.\n                                                             (line  204)\n* etm analyze:                           Architecture and Core Commands.\n                                                             (line  166)\n* etm config:                            Architecture and Core Commands.\n                                                             (line   63)\n* etm dump:                              Architecture and Core Commands.\n                                                             (line  170)\n* etm image:                             Architecture and Core Commands.\n                                                             (line  173)\n* etm info:                              Architecture and Core Commands.\n                                                             (line   89)\n* etm load:                              Architecture and Core Commands.\n                                                             (line  176)\n* etm start:                             Architecture and Core Commands.\n                                                             (line  179)\n* etm status:                            Architecture and Core Commands.\n                                                             (line   95)\n* etm stop:                              Architecture and Core Commands.\n                                                             (line  182)\n* etm tracemode:                         Architecture and Core Commands.\n                                                             (line  100)\n* etm trigger_debug:                     Architecture and Core Commands.\n                                                             (line  119)\n* etm_dummy config:                      Architecture and Core Commands.\n                                                             (line  195)\n* exit:                                  General Commands.   (line   30)\n* fast_load:                             General Commands.   (line  333)\n* fast_load_image:                       General Commands.   (line  337)\n* fespi:                                 Flash Commands.     (line  613)\n* find:                                  Config File Guidelines.\n                                                             (line   57)\n* flash bank:                            Flash Commands.     (line   36)\n* flash banks:                           Flash Commands.     (line   67)\n* flash erase_address:                   Flash Commands.     (line  135)\n* flash erase_check:                     Flash Commands.     (line  230)\n* flash erase_sector:                    Flash Commands.     (line  129)\n* flash fillb:                           Flash Commands.     (line  149)\n* flash filld:                           Flash Commands.     (line  146)\n* flash fillh:                           Flash Commands.     (line  148)\n* flash fillw:                           Flash Commands.     (line  147)\n* flash info:                            Flash Commands.     (line  234)\n* flash init:                            Server Configuration.\n                                                             (line   82)\n* flash list:                            Flash Commands.     (line   72)\n* flash mdb:                             Flash Commands.     (line  162)\n* flash mdh:                             Flash Commands.     (line  161)\n* flash mdw:                             Flash Commands.     (line  160)\n* flash padded_value:                    Flash Commands.     (line  252)\n* flash probe:                           Flash Commands.     (line   77)\n* flash protect:                         Flash Commands.     (line  242)\n* flash read_bank:                       Flash Commands.     (line  176)\n* flash verify_bank:                     Flash Commands.     (line  183)\n* flash verify_image:                    Flash Commands.     (line  217)\n* flash write_bank:                      Flash Commands.     (line  170)\n* flash write_image:                     Flash Commands.     (line  189)\n* flush_count:                           JTAG Commands.      (line   70)\n* fm3:                                   Flash Commands.     (line 1014)\n* fm4:                                   Flash Commands.     (line 1023)\n* ft232r:                                Debug Adapter Configuration.\n                                                             (line  282)\n* ft232r jtag_nums:                      Debug Adapter Configuration.\n                                                             (line  322)\n* ft232r restore_serial:                 Debug Adapter Configuration.\n                                                             (line  350)\n* ft232r srst_num:                       Debug Adapter Configuration.\n                                                             (line  346)\n* ft232r tck_num:                        Debug Adapter Configuration.\n                                                             (line  326)\n* ft232r tdi_num:                        Debug Adapter Configuration.\n                                                             (line  334)\n* ft232r tdo_num:                        Debug Adapter Configuration.\n                                                             (line  338)\n* ft232r tms_num:                        Debug Adapter Configuration.\n                                                             (line  330)\n* ft232r trst_num:                       Debug Adapter Configuration.\n                                                             (line  342)\n* ft232r vid_pid:                        Debug Adapter Configuration.\n                                                             (line  318)\n* ftdi:                                  Debug Adapter Configuration.\n                                                             (line  154)\n* ftdi channel:                          Debug Adapter Configuration.\n                                                             (line  206)\n* ftdi device_desc:                      Debug Adapter Configuration.\n                                                             (line  201)\n* ftdi get_signal:                       Debug Adapter Configuration.\n                                                             (line  263)\n* ftdi layout_init:                      Debug Adapter Configuration.\n                                                             (line  211)\n* ftdi layout_signal:                    Debug Adapter Configuration.\n                                                             (line  221)\n* ftdi set_signal:                       Debug Adapter Configuration.\n                                                             (line  257)\n* ftdi tdo_sample_edge:                  Debug Adapter Configuration.\n                                                             (line  266)\n* ftdi vid_pid:                          Debug Adapter Configuration.\n                                                             (line  196)\n* gdb_breakpoint_override:               Server Configuration.\n                                                             (line  178)\n* gdb_flash_program:                     Server Configuration.\n                                                             (line  185)\n* gdb_memory_map:                        Server Configuration.\n                                                             (line  189)\n* gdb_port:                              Server Configuration.\n                                                             (line  125)\n* gdb_report_data_abort:                 Server Configuration.\n                                                             (line  197)\n* gdb_report_register_access_error:      Server Configuration.\n                                                             (line  202)\n* gdb_save_tdesc:                        Server Configuration.\n                                                             (line  212)\n* gdb_target_description:                Server Configuration.\n                                                             (line  207)\n* get_reg:                               General Commands.   (line  155)\n* gw16012:                               Debug Adapter Configuration.\n                                                             (line  424)\n* halt:                                  General Commands.   (line  199)\n* help:                                  General Commands.   (line   33)\n* hla:                                   Debug Adapter Configuration.\n                                                             (line  662)\n* hla_command:                           Debug Adapter Configuration.\n                                                             (line  692)\n* hla_device_desc:                       Debug Adapter Configuration.\n                                                             (line  674)\n* hla_layout:                            Debug Adapter Configuration.\n                                                             (line  677)\n* hla_stlink_backend:                    Debug Adapter Configuration.\n                                                             (line  683)\n* hla_vid_pid:                           Debug Adapter Configuration.\n                                                             (line  680)\n* imx_gpio:                              Debug Adapter Configuration.\n                                                             (line  869)\n* init:                                  Server Configuration.\n                                                             (line   59)\n* init_reset:                            Reset Configuration.\n                                                             (line  258)\n* ipdbg:                                 Boundary Scan Commands.\n                                                             (line   81)\n* irscan:                                JTAG Commands.      (line   81)\n* itm port:                              Architecture and Core Commands.\n                                                             (line  890)\n* itm ports:                             Architecture and Core Commands.\n                                                             (line  894)\n* jlink:                                 Debug Adapter Configuration.\n                                                             (line  434)\n* jlink config:                          Debug Adapter Configuration.\n                                                             (line  459)\n* jlink config ip:                       Debug Adapter Configuration.\n                                                             (line  467)\n* jlink config mac:                      Debug Adapter Configuration.\n                                                             (line  464)\n* jlink config reset:                    Debug Adapter Configuration.\n                                                             (line  475)\n* jlink config targetpower:              Debug Adapter Configuration.\n                                                             (line  461)\n* jlink config usb:                      Debug Adapter Configuration.\n                                                             (line  471)\n* jlink config write:                    Debug Adapter Configuration.\n                                                             (line  477)\n* jlink emucom read:                     Debug Adapter Configuration.\n                                                             (line  487)\n* jlink emucom write:                    Debug Adapter Configuration.\n                                                             (line  480)\n* jlink freemem:                         Debug Adapter Configuration.\n                                                             (line  454)\n* jlink hwstatus:                        Debug Adapter Configuration.\n                                                             (line  451)\n* jlink jtag:                            Debug Adapter Configuration.\n                                                             (line  456)\n* jlink usb:                             Debug Adapter Configuration.\n                                                             (line  495)\n* jtag arp_init:                         Reset Configuration.\n                                                             (line  276)\n* jtag arp_init-reset:                   Reset Configuration.\n                                                             (line  286)\n* jtag cget:                             TAP Declaration.    (line  205)\n* jtag cget <1>:                         TAP Declaration.    (line  208)\n* jtag configure:                        TAP Declaration.    (line  209)\n* jtag names:                            TAP Declaration.    (line   81)\n* jtag newtap:                           TAP Declaration.    (line  113)\n* jtag tapdisable:                       TAP Declaration.    (line  303)\n* jtag tapenable:                        TAP Declaration.    (line  308)\n* jtag tapisenabled:                     TAP Declaration.    (line  313)\n* jtagspi:                               Flash Commands.     (line  328)\n* jtagspi always_4byte:                  Flash Commands.     (line  381)\n* jtagspi cmd:                           Flash Commands.     (line  375)\n* jtagspi set:                           Flash Commands.     (line  366)\n* jtag_dpi:                              Debug Adapter Configuration.\n                                                             (line 1095)\n* jtag_dpi set_address:                  Debug Adapter Configuration.\n                                                             (line 1104)\n* jtag_dpi set_port:                     Debug Adapter Configuration.\n                                                             (line 1100)\n* jtag_init:                             Server Configuration.\n                                                             (line  100)\n* jtag_ntrst_assert_width:               Reset Configuration.\n                                                             (line  133)\n* jtag_ntrst_delay:                      Reset Configuration.\n                                                             (line  138)\n* jtag_rclk:                             Debug Adapter Configuration.\n                                                             (line 1303)\n* kinetis:                               Flash Commands.     (line 1039)\n* kinetis create_banks:                  Flash Commands.     (line 1054)\n* kinetis disable_wdog:                  Flash Commands.     (line 1122)\n* kinetis fcf_source:                    Flash Commands.     (line 1060)\n* kinetis fopt:                          Flash Commands.     (line 1072)\n* kinetis mdm check_security:            Flash Commands.     (line 1076)\n* kinetis mdm halt:                      Flash Commands.     (line 1080)\n* kinetis mdm mass_erase:                Flash Commands.     (line 1085)\n* kinetis mdm reset:                     Flash Commands.     (line 1117)\n* kinetis nvm_partition:                 Flash Commands.     (line 1092)\n* kinetis_ke:                            Flash Commands.     (line 1126)\n* kinetis_ke disable_wdog:               Flash Commands.     (line 1145)\n* kinetis_ke mdm check_security:         Flash Commands.     (line 1135)\n* kinetis_ke mdm mass_erase:             Flash Commands.     (line 1139)\n* kitprog:                               Debug Adapter Configuration.\n                                                             (line  504)\n* kitprog acquire_psoc:                  Debug Adapter Configuration.\n                                                             (line  545)\n* kitprog info:                          Debug Adapter Configuration.\n                                                             (line  552)\n* kitprog_init_acquire_psoc:             Debug Adapter Configuration.\n                                                             (line  540)\n* linuxgpiod:                            Debug Adapter Configuration.\n                                                             (line  965)\n* linuxgpiod gpiochip:                   Debug Adapter Configuration.\n                                                             (line  972)\n* linuxgpiod jtag_nums:                  Debug Adapter Configuration.\n                                                             (line  979)\n* linuxgpiod led_num:                    Debug Adapter Configuration.\n                                                             (line 1033)\n* linuxgpiod srst_num:                   Debug Adapter Configuration.\n                                                             (line 1029)\n* linuxgpiod swclk_num:                  Debug Adapter Configuration.\n                                                             (line 1013)\n* linuxgpiod swdio_dir_num:              Debug Adapter Configuration.\n                                                             (line 1023)\n* linuxgpiod swdio_num:                  Debug Adapter Configuration.\n                                                             (line 1018)\n* linuxgpiod swd_nums:                   Debug Adapter Configuration.\n                                                             (line 1008)\n* linuxgpiod tck_num:                    Debug Adapter Configuration.\n                                                             (line  984)\n* linuxgpiod tdi_num:                    Debug Adapter Configuration.\n                                                             (line  999)\n* linuxgpiod tdo_num:                    Debug Adapter Configuration.\n                                                             (line  994)\n* linuxgpiod tms_num:                    Debug Adapter Configuration.\n                                                             (line  989)\n* linuxgpiod trst_num:                   Debug Adapter Configuration.\n                                                             (line 1004)\n* load_image:                            General Commands.   (line  348)\n* log_output:                            General Commands.   (line   87)\n* lpc2000:                               Flash Commands.     (line 1148)\n* lpc2000 part_id:                       Flash Commands.     (line 1189)\n* lpc288x:                               Flash Commands.     (line 1193)\n* lpc2900:                               Flash Commands.     (line 1201)\n* lpc2900 password:                      Flash Commands.     (line 1257)\n* lpc2900 read_custom:                   Flash Commands.     (line 1246)\n* lpc2900 secure_jtag:                   Flash Commands.     (line 1292)\n* lpc2900 secure_sector:                 Flash Commands.     (line 1278)\n* lpc2900 signature:                     Flash Commands.     (line 1237)\n* lpc2900 write_custom:                  Flash Commands.     (line 1267)\n* lpc3180:                               Flash Commands.     (line 2443)\n* lpc3180 select:                        Flash Commands.     (line 2446)\n* lpcspifi:                              Flash Commands.     (line  422)\n* mdb:                                   General Commands.   (line  304)\n* mdd:                                   General Commands.   (line  301)\n* mdh:                                   General Commands.   (line  303)\n* mdr:                                   Flash Commands.     (line 1299)\n* mdw:                                   General Commands.   (line  302)\n* memTestAddressBus:                     Utility Commands.   (line   29)\n* memTestDataBus:                        Utility Commands.   (line   25)\n* memTestDevice:                         Utility Commands.   (line   34)\n* mrvlqspi:                              Flash Commands.     (line  571)\n* msp432:                                Flash Commands.     (line 1320)\n* msp432 bsl:                            Flash Commands.     (line 1339)\n* msp432 mass_erase:                     Flash Commands.     (line 1330)\n* mwb:                                   General Commands.   (line  317)\n* mwd:                                   General Commands.   (line  314)\n* mwh:                                   General Commands.   (line  316)\n* mww:                                   General Commands.   (line  315)\n* mx3:                                   Flash Commands.     (line 2456)\n* mxc:                                   Flash Commands.     (line 2460)\n* mxc biswap:                            Flash Commands.     (line 2468)\n* nand check_bad_blocks:                 Flash Commands.     (line 2358)\n* nand device:                           Flash Commands.     (line 2190)\n* nand dump:                             Flash Commands.     (line 2233)\n* nand erase:                            Flash Commands.     (line 2266)\n* nand info:                             Flash Commands.     (line 2370)\n* nand init:                             Server Configuration.\n                                                             (line   83)\n* nand list:                             Flash Commands.     (line 2213)\n* nand probe:                            Flash Commands.     (line 2223)\n* nand raw_access:                       Flash Commands.     (line 2375)\n* nand verify:                           Flash Commands.     (line 2332)\n* nand write:                            Flash Commands.     (line 2279)\n* niietcm4:                              Flash Commands.     (line 1351)\n* niietcm4 bflash_info_remap:            Flash Commands.     (line 1391)\n* niietcm4 driver_info:                  Flash Commands.     (line 1404)\n* niietcm4 extmem_cfg:                   Flash Commands.     (line 1395)\n* niietcm4 service_mode_erase:           Flash Commands.     (line 1400)\n* niietcm4 uflash_erase:                 Flash Commands.     (line 1378)\n* niietcm4 uflash_full_erase:            Flash Commands.     (line 1375)\n* niietcm4 uflash_protect:               Flash Commands.     (line 1386)\n* niietcm4 uflash_protect_check:         Flash Commands.     (line 1383)\n* niietcm4 uflash_read_byte:             Flash Commands.     (line 1368)\n* niietcm4 uflash_write_byte:            Flash Commands.     (line 1371)\n* noinit:                                Server Configuration.\n                                                             (line   94)\n* npcx:                                  Flash Commands.     (line 1407)\n* nrf5:                                  Flash Commands.     (line 1416)\n* nrf5 info:                             Flash Commands.     (line 1434)\n* nrf5 mass_erase:                       Flash Commands.     (line 1428)\n* ocd_find:                              Config File Guidelines.\n                                                             (line   60)\n* ocl:                                   Flash Commands.     (line 1437)\n* opendous:                              Debug Adapter Configuration.\n                                                             (line  744)\n* openjtag:                              Debug Adapter Configuration.\n                                                             (line 1043)\n* openjtag device_desc:                  Debug Adapter Configuration.\n                                                             (line 1057)\n* openjtag variant:                      Debug Adapter Configuration.\n                                                             (line 1047)\n* orion:                                 Flash Commands.     (line 2472)\n* parport:                               Debug Adapter Configuration.\n                                                             (line  556)\n* parport cable:                         Debug Adapter Configuration.\n                                                             (line  562)\n* parport port:                          Debug Adapter Configuration.\n                                                             (line   88)\n* parport port <1>:                      Debug Adapter Configuration.\n                                                             (line  428)\n* parport port <2>:                      Debug Adapter Configuration.\n                                                             (line  591)\n* parport toggling_time:                 Debug Adapter Configuration.\n                                                             (line  601)\n* parport write_on_exit:                 Debug Adapter Configuration.\n                                                             (line  635)\n* pathmove:                              JTAG Commands.      (line   98)\n* pic32mx:                               Flash Commands.     (line 1448)\n* pic32mx pgm_word:                      Flash Commands.     (line 1456)\n* pic32mx unlock:                        Flash Commands.     (line 1459)\n* pld device:                            PLD/FPGA Commands.  (line   23)\n* pld devices:                           PLD/FPGA Commands.  (line   28)\n* pld init:                              Server Configuration.\n                                                             (line   84)\n* pld load:                              PLD/FPGA Commands.  (line   31)\n* poll:                                  Server Configuration.\n                                                             (line  252)\n* presto:                                Debug Adapter Configuration.\n                                                             (line  647)\n* profile:                               General Commands.   (line  488)\n* program:                               Flash Commands.     (line  258)\n* psoc4:                                 Flash Commands.     (line 1463)\n* psoc4 flash_autoerase:                 Flash Commands.     (line 1475)\n* psoc4 mass_erase:                      Flash Commands.     (line 1488)\n* psoc5lp:                               Flash Commands.     (line 1494)\n* psoc5lp mass_erase:                    Flash Commands.     (line 1513)\n* psoc5lp_eeprom:                        Flash Commands.     (line 1518)\n* psoc5lp_nvl:                           Flash Commands.     (line 1527)\n* psoc6:                                 Flash Commands.     (line 1547)\n* psoc6 mass_erase:                      Flash Commands.     (line 1607)\n* psoc6 reset_halt:                      Flash Commands.     (line 1598)\n* rbp:                                   General Commands.   (line  397)\n* read_memory:                           General Commands.   (line  183)\n* reg:                                   General Commands.   (line  109)\n* remote_bitbang:                        Debug Adapter Configuration.\n                                                             (line  360)\n* remote_bitbang host:                   Debug Adapter Configuration.\n                                                             (line  372)\n* remote_bitbang port:                   Debug Adapter Configuration.\n                                                             (line  368)\n* reset:                                 General Commands.   (line  238)\n* reset halt:                            General Commands.   (line  240)\n* reset init:                            General Commands.   (line  241)\n* reset run:                             General Commands.   (line  239)\n* reset_config:                          Reset Configuration.\n                                                             (line  143)\n* resume:                                General Commands.   (line  229)\n* riscv authdata_read:                   Architecture and Core Commands.\n                                                             (line 1438)\n* riscv authdata_write:                  Architecture and Core Commands.\n                                                             (line 1441)\n* riscv dmi_read:                        Architecture and Core Commands.\n                                                             (line 1450)\n* riscv dmi_write:                       Architecture and Core Commands.\n                                                             (line 1453)\n* riscv expose_csrs:                     Architecture and Core Commands.\n                                                             (line 1302)\n* riscv expose_custom:                   Architecture and Core Commands.\n                                                             (line 1324)\n* riscv resume_order:                    Architecture and Core Commands.\n                                                             (line 1387)\n* riscv set_command_timeout_sec:         Architecture and Core Commands.\n                                                             (line 1347)\n* riscv set_ebreakm:                     Architecture and Core Commands.\n                                                             (line 1414)\n* riscv set_ebreaks:                     Architecture and Core Commands.\n                                                             (line 1419)\n* riscv set_ebreaku:                     Architecture and Core Commands.\n                                                             (line 1424)\n* riscv set_enable_virt2phys:            Architecture and Core Commands.\n                                                             (line 1382)\n* riscv set_enable_virtual:              Architecture and Core Commands.\n                                                             (line 1377)\n* riscv set_ir:                          Architecture and Core Commands.\n                                                             (line 1399)\n* riscv set_mem_access:                  Architecture and Core Commands.\n                                                             (line 1361)\n* riscv set_reset_timeout_sec:           Architecture and Core Commands.\n                                                             (line 1352)\n* riscv set_scratch_ram:                 Architecture and Core Commands.\n                                                             (line 1356)\n* riscv use_bscan_tunnel:                Architecture and Core Commands.\n                                                             (line 1409)\n* rlink:                                 Debug Adapter Configuration.\n                                                             (line  650)\n* rp2040:                                Flash Commands.     (line 1612)\n* rtck:                                  Debug Adapter Configuration.\n                                                             (line   92)\n* rtt channellist:                       General Commands.   (line  461)\n* rtt channels:                          General Commands.   (line  458)\n* rtt polling_interval:                  General Commands.   (line  453)\n* rtt server start:                      General Commands.   (line  465)\n* rtt server stop:                       General Commands.   (line  468)\n* rtt setup:                             General Commands.   (line  440)\n* rtt start:                             General Commands.   (line  446)\n* rtt stop:                              General Commands.   (line  450)\n* runAllMemTests:                        Utility Commands.   (line   39)\n* runtest:                               JTAG Commands.      (line  106)\n* rwp:                                   General Commands.   (line  400)\n* s3c2410:                               Flash Commands.     (line 2480)\n* s3c2412:                               Flash Commands.     (line 2481)\n* s3c2440:                               Flash Commands.     (line 2482)\n* s3c2443:                               Flash Commands.     (line 2483)\n* s3c6400:                               Flash Commands.     (line 2484)\n* scan_chain:                            TAP Declaration.    (line   89)\n* set_reg:                               General Commands.   (line  143)\n* shutdown:                              General Commands.   (line   54)\n* sim3x:                                 Flash Commands.     (line 1620)\n* sim3x lock:                            Flash Commands.     (line 1636)\n* sim3x mass_erase:                      Flash Commands.     (line 1631)\n* sleep:                                 General Commands.   (line   48)\n* soft_reset_halt:                       General Commands.   (line  256)\n* st-link:                               Debug Adapter Configuration.\n                                                             (line  696)\n* st-link backend:                       Debug Adapter Configuration.\n                                                             (line  710)\n* st-link cmd:                           Debug Adapter Configuration.\n                                                             (line  725)\n* st-link vid_pid:                       Debug Adapter Configuration.\n                                                             (line  722)\n* stellaris:                             Flash Commands.     (line 1639)\n* stellaris recover:                     Flash Commands.     (line 1647)\n* step:                                  General Commands.   (line  234)\n* stm32f1x:                              Flash Commands.     (line 1660)\n* stm32f1x lock:                         Flash Commands.     (line 1683)\n* stm32f1x mass_erase:                   Flash Commands.     (line 1693)\n* stm32f1x options_load:                 Flash Commands.     (line 1710)\n* stm32f1x options_read:                 Flash Commands.     (line 1697)\n* stm32f1x options_write:                Flash Commands.     (line 1702)\n* stm32f1x unlock:                       Flash Commands.     (line 1687)\n* stm32f2x:                              Flash Commands.     (line 1717)\n* stm32f2x lock:                         Flash Commands.     (line 1742)\n* stm32f2x mass_erase:                   Flash Commands.     (line 1750)\n* stm32f2x optcr2_write:                 Flash Commands.     (line 1768)\n* stm32f2x options_read:                 Flash Commands.     (line 1754)\n* stm32f2x options_write:                Flash Commands.     (line 1759)\n* stm32f2x otp:                          Flash Commands.     (line 1730)\n* stm32f2x unlock:                       Flash Commands.     (line 1746)\n* stm32h7x:                              Flash Commands.     (line 1773)\n* stm32h7x lock:                         Flash Commands.     (line 1789)\n* stm32h7x mass_erase:                   Flash Commands.     (line 1797)\n* stm32h7x option_read:                  Flash Commands.     (line 1801)\n* stm32h7x option_write:                 Flash Commands.     (line 1816)\n* stm32h7x unlock:                       Flash Commands.     (line 1793)\n* stm32l4x:                              Flash Commands.     (line 1861)\n* stm32l4x lock:                         Flash Commands.     (line 1888)\n* stm32l4x mass_erase:                   Flash Commands.     (line 1902)\n* stm32l4x option_load:                  Flash Commands.     (line 1952)\n* stm32l4x option_read:                  Flash Commands.     (line 1906)\n* stm32l4x option_write:                 Flash Commands.     (line 1921)\n* stm32l4x otp:                          Flash Commands.     (line 1874)\n* stm32l4x trustzone:                    Flash Commands.     (line 1957)\n* stm32l4x unlock:                       Flash Commands.     (line 1895)\n* stm32l4x wrp_info:                     Flash Commands.     (line 1939)\n* stm32lx:                               Flash Commands.     (line 1828)\n* stm32lx lock:                          Flash Commands.     (line 1847)\n* stm32lx mass_erase:                    Flash Commands.     (line 1855)\n* stm32lx unlock:                        Flash Commands.     (line 1851)\n* stmqspi:                               Flash Commands.     (line  459)\n* stmqspi cmd:                           Flash Commands.     (line  541)\n* stmqspi mass_erase:                    Flash Commands.     (line  520)\n* stmqspi set:                           Flash Commands.     (line  524)\n* stmsmi:                                Flash Commands.     (line  439)\n* str7x:                                 Flash Commands.     (line 1965)\n* str7x disable_jtag:                    Flash Commands.     (line 1974)\n* str9x:                                 Flash Commands.     (line 1978)\n* str9x flash_config:                    Flash Commands.     (line 1987)\n* str9xpec:                              Flash Commands.     (line 1996)\n* str9xpec disable_turbo:                Flash Commands.     (line 2039)\n* str9xpec enable_turbo:                 Flash Commands.     (line 2042)\n* str9xpec lock:                         Flash Commands.     (line 2046)\n* str9xpec options_cmap:                 Flash Commands.     (line 2053)\n* str9xpec options_lvdsel:               Flash Commands.     (line 2056)\n* str9xpec options_lvdthd:               Flash Commands.     (line 2059)\n* str9xpec options_lvdwarn:              Flash Commands.     (line 2062)\n* str9xpec options_read:                 Flash Commands.     (line 2065)\n* str9xpec options_write:                Flash Commands.     (line 2068)\n* str9xpec part_id:                      Flash Commands.     (line 2050)\n* str9xpec unlock:                       Flash Commands.     (line 2071)\n* svf:                                   Boundary Scan Commands.\n                                                             (line   17)\n* swd newdap:                            Debug Adapter Configuration.\n                                                             (line 1211)\n* swm050:                                Flash Commands.     (line 2074)\n* swm050 mass_erase:                     Flash Commands.     (line 2082)\n* swo:                                   Architecture and Core Commands.\n                                                             (line  748)\n* sysfsgpio:                             Debug Adapter Configuration.\n                                                             (line 1037)\n* tap_select:                            Architecture and Core Commands.\n                                                             (line 1216)\n* target create:                         CPU Configuration.  (line  198)\n* target current:                        CPU Configuration.  (line   37)\n* target init:                           Server Configuration.\n                                                             (line   79)\n* target names:                          CPU Configuration.  (line   40)\n* target types:                          CPU Configuration.  (line   71)\n* targets:                               CPU Configuration.  (line   46)\n* target_request debugmsgs:              Architecture and Core Commands.\n                                                             (line 1725)\n* tcl_notifications:                     Tcl Scripting API.  (line   93)\n* tcl_port:                              Server Configuration.\n                                                             (line  155)\n* tcl_trace:                             Tcl Scripting API.  (line  108)\n* telnet_port:                           Server Configuration.\n                                                             (line  163)\n* test_image:                            General Commands.   (line  363)\n* tms470:                                Flash Commands.     (line 2085)\n* tms470 flash_keyset:                   Flash Commands.     (line 2092)\n* tms470 osc_megahertz:                  Flash Commands.     (line 2096)\n* tms470 plldis:                         Flash Commands.     (line 2099)\n* tpiu create:                           Architecture and Core Commands.\n                                                             (line  752)\n* tpiu init:                             Server Configuration.\n                                                             (line   85)\n* tpiu init <1>:                         Architecture and Core Commands.\n                                                             (line  772)\n* tpiu names:                            Architecture and Core Commands.\n                                                             (line  768)\n* trace history:                         Architecture and Core Commands.\n                                                             (line 1735)\n* trace point:                           Architecture and Core Commands.\n                                                             (line 1741)\n* transport init:                        Server Configuration.\n                                                             (line   80)\n* transport list:                        Debug Adapter Configuration.\n                                                             (line 1161)\n* transport select:                      Debug Adapter Configuration.\n                                                             (line 1165)\n* ulink:                                 Debug Adapter Configuration.\n                                                             (line  747)\n* usage:                                 General Commands.   (line   43)\n* usbprog:                               Debug Adapter Configuration.\n                                                             (line  653)\n* usb_blaster:                           Debug Adapter Configuration.\n                                                             (line  391)\n* usb_blaster firmware:                  Debug Adapter Configuration.\n                                                             (line  420)\n* usb_blaster lowlevel_driver:           Debug Adapter Configuration.\n                                                             (line  415)\n* usb_blaster pin:                       Debug Adapter Configuration.\n                                                             (line  405)\n* usb_blaster vid_pid:                   Debug Adapter Configuration.\n                                                             (line  397)\n* vdebug:                                Debug Adapter Configuration.\n                                                             (line 1061)\n* vdebug batching:                       Debug Adapter Configuration.\n                                                             (line 1068)\n* vdebug bfm_path:                       Debug Adapter Configuration.\n                                                             (line 1081)\n* vdebug mem_path:                       Debug Adapter Configuration.\n                                                             (line 1087)\n* vdebug polling:                        Debug Adapter Configuration.\n                                                             (line 1074)\n* vdebug server:                         Debug Adapter Configuration.\n                                                             (line 1064)\n* verify_image:                          General Commands.   (line  369)\n* verify_image_checksum:                 General Commands.   (line  375)\n* verify_ircapture:                      JTAG Commands.      (line  111)\n* verify_jtag:                           JTAG Commands.      (line  117)\n* version:                               General Commands.   (line  494)\n* virt2phys:                             General Commands.   (line  497)\n* virtex2:                               PLD/FPGA Commands.  (line   42)\n* virtex2 read_stat:                     PLD/FPGA Commands.  (line   50)\n* virtual:                               Flash Commands.     (line  271)\n* vsllink:                               Debug Adapter Configuration.\n                                                             (line  656)\n* w600:                                  Flash Commands.     (line 2103)\n* wait_halt:                             General Commands.   (line  200)\n* wp:                                    General Commands.   (line  403)\n* write_memory:                          General Commands.   (line  168)\n* x86_32 idb:                            Architecture and Core Commands.\n                                                             (line 1191)\n* x86_32 idh:                            Architecture and Core Commands.\n                                                             (line 1187)\n* x86_32 idw:                            Architecture and Core Commands.\n                                                             (line 1183)\n* x86_32 iwb:                            Architecture and Core Commands.\n                                                             (line 1203)\n* x86_32 iwh:                            Architecture and Core Commands.\n                                                             (line 1199)\n* x86_32 iww:                            Architecture and Core Commands.\n                                                             (line 1195)\n* xcf:                                   Flash Commands.     (line  386)\n* xcf ccb:                               Flash Commands.     (line  394)\n* xcf configure:                         Flash Commands.     (line  410)\n* xds110:                                Debug Adapter Configuration.\n                                                             (line  750)\n* xds110 info:                           Debug Adapter Configuration.\n                                                             (line  763)\n* xds110 supply:                         Debug Adapter Configuration.\n                                                             (line  757)\n* xlnx_pcie_xvc:                         Debug Adapter Configuration.\n                                                             (line  767)\n* xlnx_pcie_xvc config:                  Debug Adapter Configuration.\n                                                             (line  778)\n* xmc1xxx:                               Flash Commands.     (line 2110)\n* xmc4xxx:                               Flash Commands.     (line 2115)\n* xmc4xxx flash_password:                Flash Commands.     (line 2122)\n* xmc4xxx flash_unprotect:               Flash Commands.     (line 2126)\n* xscale analyze_trace:                  Architecture and Core Commands.\n                                                             (line  580)\n* xscale cache_clean_address:            Architecture and Core Commands.\n                                                             (line  583)\n* xscale cache_info:                     Architecture and Core Commands.\n                                                             (line  586)\n* xscale cp15:                           Architecture and Core Commands.\n                                                             (line  589)\n* xscale dcache:                         Architecture and Core Commands.\n                                                             (line  596)\n* xscale debug_handler:                  Architecture and Core Commands.\n                                                             (line  593)\n* xscale dump_trace:                     Architecture and Core Commands.\n                                                             (line  599)\n* xscale icache:                         Architecture and Core Commands.\n                                                             (line  602)\n* xscale mmu:                            Architecture and Core Commands.\n                                                             (line  605)\n* xscale trace_buffer:                   Architecture and Core Commands.\n                                                             (line  608)\n* xscale trace_image:                    Architecture and Core Commands.\n                                                             (line  612)\n* xscale vector_catch:                   Architecture and Core Commands.\n                                                             (line  618)\n* xscale vector_table:                   Architecture and Core Commands.\n                                                             (line  633)\n* xsvf:                                  Boundary Scan Commands.\n                                                             (line   46)\n* xtensa maskisr:                        Architecture and Core Commands.\n                                                             (line 1616)\n* xtensa perfmon_dump:                   Architecture and Core Commands.\n                                                             (line 1661)\n* xtensa perfmon_enable:                 Architecture and Core Commands.\n                                                             (line 1647)\n* xtensa set_permissive:                 Architecture and Core Commands.\n                                                             (line 1610)\n* xtensa smpbreak:                       Architecture and Core Commands.\n                                                             (line 1620)\n* xtensa tracedump:                      Architecture and Core Commands.\n                                                             (line 1680)\n* xtensa tracestart:                     Architecture and Core Commands.\n                                                             (line 1665)\n* xtensa tracestop:                      Architecture and Core Commands.\n                                                             (line 1677)\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_CH347/share/man/man1/openocd.1",
    "content": ".TH \"OPENOCD\" \"1\" \"November 24, 2009\"\n.SH \"NAME\"\nopenocd \\- A free and open on\\-chip debugging, in\\-system programming and\nboundary\\-scan testing tool for ARM and MIPS systems\n.SH \"SYNOPSIS\"\n.B openocd \\fR[\\fB\\-fsdlcphv\\fR] [\\fB\\-\\-file\\fR <filename>] [\\fB\\-\\-search\\fR <dirname>] [\\fB\\-\\-debug\\fR <debuglevel>] [\\fB\\-\\-log_output\\fR <filename>] [\\fB\\-\\-command\\fR <cmd>] [\\fB\\-\\-pipe\\fR] [\\fB\\-\\-help\\fR] [\\fB\\-\\-version\\fR]\n.SH \"DESCRIPTION\"\n.B OpenOCD\nis an on\\-chip debugging, in\\-system programming and boundary\\-scan\ntesting tool for various ARM and MIPS systems.\n.PP\nThe debugger uses an IEEE 1149\\-1 compliant JTAG TAP bus master to access\non\\-chip debug functionality available on ARM based microcontrollers or\nsystem-on-chip solutions. For MIPS systems the EJTAG interface is supported.\n.PP\nUser interaction is realized through a telnet command line interface,\na gdb (the GNU debugger) remote protocol server, and a simplified RPC\nconnection that can be used to interface with OpenOCD's Jim Tcl engine.\n.PP\nOpenOCD supports various different types of JTAG interfaces/programmers,\nplease check the \\fIopenocd\\fR info page for the complete list.\n.SH \"OPTIONS\"\n.TP\n.B \"\\-f, \\-\\-file <filename>\"\nThis is a shortcut for a \\fB\\-c \"[script \\fI<filename>\\fB]\"\\fR\ncommand, using a search path to load the configuration file\n.IR <filename> .\nIn order to specify multiple config files, you can use multiple\n.B \\-\\-file\narguments. If no such \\fB\\-c\\fR\noptions are included, the first config file\n.B openocd.cfg\nin the search path will be used.\n.TP\n.B \"\\-s, \\-\\-search <dirname>\"\nAdd\n.I <dirname>\nto the search path used for config files and scripts.\nThe search path begins with the current directory,\nthen includes these additional directories before other\ncomponents such as the standard OpenOCD script libraries.\n.TP\n.B \"\\-d, \\-\\-debug <debuglevel>\"\nSet debug level. Possible values are:\n.br\n.RB \"  * \" 0 \" (errors)\"\n.br\n.RB \"  * \" 1 \" (warnings)\"\n.br\n.RB \"  * \" 2 \" (informational messages)\"\n.br\n.RB \"  * \" 3 \" (debug messages)\"\n.br\nThe default level is\n.BR 2 .\n.TP\n.B \"\\-l, \\-\\-log_output <filename>\"\nRedirect log output to the file\n.IR <filename> .\nPer default the log output is printed on\n.BR stderr .\n.TP\n.B \"\\-c, \\-\\-command <cmd>\"\nAdd the command\n.I <cmd>\nto a list of commands executed on server startup.\nNote that you will need to explicitly invoke\n.I init\nif the command requires access to a target or flash.\n.TP\n.B \"\\-p, \\-\\-pipe\"\nUse pipes when talking to gdb.\n.TP\n.B \"\\-h, \\-\\-help\"\nShow a help text and exit.\n.TP\n.B \"\\-v, \\-\\-version\"\nShow version information and exit.\n.SH \"BUGS\"\nPlease report any bugs on the mailing list at\n.BR openocd\\-devel@lists.sourceforge.net .\n.SH \"LICENCE\"\n.B OpenOCD\nis covered by the GNU General Public License (GPL), version 2 or later.\n.SH \"SEE ALSO\"\n.BR jtag (1)\n.PP\nThe full documentation for\n.B openocd\nis maintained as a Texinfo manual. If the\n.BR info\n(or\n.BR pinfo )\nand\n.BR openocd\nprograms are properly installed at your site, the command\n.B info openocd\nshould give you access to the complete manual.\n.SH \"AUTHORS\"\nPlease see the file AUTHORS.\n.PP\nThis manual page was written by Uwe Hermann <uwe@hermann\\-uwe.de>.\nIt is licensed under the terms of the GNU GPL (version 2 or later).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/.checkpatch.conf",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n--max-line-length=120\n--tab-size=4\n--show-types\n--strict\n\n--typedefsfile tools/scripts/typedefs.txt\n\n--ignore AVOID_EXTERNS\n--ignore BLOCK_COMMENT_STYLE\n--ignore COMPLEX_MACRO\n--ignore CONST_STRUCT\n--ignore ENOSYS\n--ignore FILE_PATH_CHANGES\n--ignore GERRIT_CHANGE_ID\n--ignore LINE_SPACING\n--ignore LOGICAL_CONTINUATIONS\n--ignore MACRO_WITH_FLOW_CONTROL\n--ignore NEW_TYPEDEFS\n--ignore PARENTHESIS_ALIGNMENT\n--ignore PREFER_DEFINED_ATTRIBUTE_MACRO\n--ignore PREFER_FALLTHROUGH\n--ignore PREFER_KERNEL_TYPES\n--ignore SPLIT_STRING\n--ignore SSCANF_TO_KSTRTO\n--ignore SWITCH_CASE_INDENT_LEVEL\n--ignore TRACING_LOGGING\n--ignore VOLATILE\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/.gitignore",
    "content": "# stuff \"git status\" should ignore\n\n# build output\n.libs\n.deps\n.dirstamp\n*.o\n*.o.??????\n*.a\n*.lo\n*.la\n*.in\n\n# generated source files\nsrc/jtag/minidriver_imp.h\nsrc/jtag/jtag_minidriver.h\n\n# OpenULINK driver files generated by SDCC\nsrc/jtag/drivers/OpenULINK/*.rel\nsrc/jtag/drivers/OpenULINK/*.asm\nsrc/jtag/drivers/OpenULINK/*.lst\nsrc/jtag/drivers/OpenULINK/*.sym\nsrc/jtag/drivers/OpenULINK/*.map\nsrc/jtag/drivers/OpenULINK/*.mem\nsrc/jtag/drivers/OpenULINK/*.lk\nsrc/jtag/drivers/OpenULINK/*.ihx\nsrc/jtag/drivers/OpenULINK/*.rst\n\n# editor files\n*.swp\n\nsrc/startup.tcl\nstartup_tcl.inc\nxscale_debug.inc\n\nbin2char\nbin2char.exe\n\ndoc/openocd.aux\ndoc/openocd.cp\ndoc/openocd.cps\ndoc/openocd.fn\ndoc/openocd.fns\ndoc/openocd.html\ndoc/openocd.info\ndoc/openocd.info-1\ndoc/openocd.info-2\ndoc/openocd.ky\ndoc/openocd.log\ndoc/openocd.pdf\ndoc/openocd.pg\ndoc/openocd.toc\ndoc/openocd.tp\ndoc/openocd.vr\ndoc/version.texi\nsrc/openocd\nsrc/openocd.exe\n\n# configure/autotools output\n/build-aux/\naclocal.m4\nautom4te.cache\nconfig.h\nconfig.log\nconfig.status\nconfigure\ndoxygen\ndoxygen.log\nDoxyfile\nlibtool\nMakefile\n!contrib/loaders/**/Makefile\nstamp-h1\nstamp-vti\nINSTALL\nNOTES\n\n# coexist with quilt\npatches\n*.patch\n\n# Eclipse stuff\n.project\n.cproject\n.settings\n\n# Emacs temp files\n*~\n\n# Emacs TAGS file\nTAGS\n\n# CScope database files\n*cscope.out\n\n# ctags tag files\ntags\n\n# GNU Global tag files\nGPATH\nGRTAGS\nGTAGS\n\n# checkpatch script files\n.checkpatch-camelcase.*\n\n# clangd (e.g. for advanced code completion and linting) generates cache files\n# into .cache\n.cache\n\n# A compile_commands.json can be generated using bear and will help tools such\n# as clangd to locate header files and use correct $CFLAGS\ncompile_commands.json\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/.gitmodules",
    "content": "[submodule \"tools/git2cl\"]\n\tpath = tools/git2cl\n\turl = https://git.savannah.nongnu.org/git/git2cl.git\n[submodule \"jimtcl\"]\n\tpath = jimtcl\n\turl = https://github.com/msteveb/jimtcl.git\n[submodule \"src/jtag/drivers/libjaylink\"]\n\tpath = src/jtag/drivers/libjaylink\n\turl = https://gitlab.zapb.de/libjaylink/libjaylink.git\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/.travis.yml",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright Marek Vasut <marex@denx.de>\n\n# OpenOCD on Travis CI - https://travis-ci.org/\n\nsudo: required\ndist: bionic\n\narch:\n  - amd64\n  - arm64\n  - ppc64le\n  - s390x\n\naddons:\n  apt:\n    sources:\n      - sourceline: 'ppa:ubuntu-toolchain-r/test'\n      - sourceline: 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'\n        key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'\n    packages:\n      - libftdi-dev\n      - libhidapi-dev\n      - libjaylink-dev\n\nenv:\n  - CC=gcc-9\n  - CC=clang-9\n\nlanguage: c\n\ngit:\n  depth: 1\n  autocrlf: input\n\nscript:\n  - $mingw64 ${CC} --version\n  - $mingw64 env\n  - $mingw64 ./bootstrap\n  - $mingw64 ./configure\n  - $mingw64 make\n\nbefore_install:\n  - |-\n    case $TRAVIS_OS_NAME in\n      linux)\n        sudo apt install ${CC} libusb-1.0-0-dev\n        ;;\n      osx)\n        brew install libtool automake libusb libusb-compat hidapi libftdi\n        ;;\n      windows)\n        [[ ! -f C:/tools/msys64/msys2_shell.cmd ]] && rm -rf C:/tools/msys64\n        choco uninstall -y mingw\n        choco upgrade --no-progress -y msys2\n        export msys2='cmd //C RefreshEnv.cmd '\n        export msys2+='& set MSYS=winsymlinks:nativestrict '\n        export msys2+='& C:\\\\tools\\\\msys64\\\\msys2_shell.cmd -defterm -no-start'\n        export mingw64=\"$msys2 -mingw64 -full-path -here -c \\$\\* --\"\n        export msys2+=\" -msys2 -c \\$\\* --\"\n        $msys2 pacman --sync --noconfirm --needed mingw-w64-x86_64-toolchain autoconf autoconf-archive automake automake-wrapper binutils gcc gettext git libtool m4 make pkg-config tcl texinfo mingw-w64-x86_64-libusb mingw-w64-x86_64-libusb-compat-git mingw-w64-x86_64-libjaylink-git mingw-w64-x86_64-libftdi mingw-w64-x86_64-hidapi mingw-w64-x86_64-clang\n        ## FIXME: Also build for i686?\n        ## Install more MSYS2 packages from https://packages.msys2.org/base here\n        taskkill //IM gpg-agent.exe //F  # https://travis-ci.community/t/4967\n        export PATH=/C/tools/msys64/mingw64/bin:$PATH\n        export MAKE=mingw32-make  # so that Autotools can find it\n        ;;\n    esac\n\nbefore_cache:\n- |-\n    case $TRAVIS_OS_NAME in\n      windows)\n        # https://unix.stackexchange.com/a/137322/107554\n        $msys2 pacman --sync --clean --noconfirm\n        ;;\n    esac\n\ncache:\n    directories:\n    - $HOME/AppData/Local/Temp/chocolatey\n    - /C/tools/msys64\n\nmatrix:\n  include:\n    - os: osx\n      env:\n        - CC=clang\n    - os: windows\n      env:\n        - CC=gcc\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/AUTHORS",
    "content": "Dominic Rath <Dominic.Rath@gmx.de>\nMagnus Lundin <lundin@mlu.mine.nu>\nMichael Fischer <fischermi@t-online.de>\nSpencer Oliver <spen@spen-soft.co.uk>\nCarsten Schlote <schlote@vahanus.net>\nØyvind Harboe <oyvind.harboe@zylin.com>\nDuane Ellis <openocd@duaneellis.com>\nMichael Schwingen <michael@schwingen.org>\nRick Altherr <kc8apf@users.berlios.de>\nDavid Brownell <dbrownell@users.sourceforge.net>\nVincint Palatin <vpalatin@users.berlios.de>\nZachary T Welch <zw@superlucidity.net>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/AUTHORS.ChangeLog",
    "content": "drath:Dominic Rath <Dominic.Rath@gmx.de>\nmlu:Magnus Lundin <lundin@mlu.mine.nu>\nmifi:Michael Fischer <fischermi@t-online.de>\nntfreak:Spencer Oliver <spen@spen-soft.co.uk>\nduane:Duane Ellis <openocd@duaneellis.com>\noharboe:Øyvind Harboe <oyvind.harboe@zylin.com>\nkc8apf:Rick Altherr <kc8apf@users.berlios.de>\nzwelch:Zachary T Welch <zw@superlucidity.net>\nvpalatin:Vincent Palatin <vpalatin@users.berlios.de>\nbodylove:Carsten Schlote <schlote@vahanus.net>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/BUGS",
    "content": "// This file is part of the Doxygen Developer Manual\n/** @page bugs Bug Reporting\n\nPlease report bugs by subscribing to the OpenOCD mailing list and\nposting a message with your report:\n\n\topenocd-devel@lists.sourceforge.net\n\nAlso, please check the bug database to see if a ticket for\nthe bug has already been opened.  You might be asked to open\nsuch a ticket, or to update an existing ticket with more data.\n\n\thttp://bugs.openocd.org/\n\nTo minimize work for OpenOCD developers, you should try to include\nall of the information listed below.  If you feel that some of the\nitems below are unnecessary for a clear bug report, you may leave\nthem out; likewise, feel free to include additional information\nthat may be important.\n\n- Target PCB/board description\n- Configuration scripts\n- OpenOCD command line\n- List of commands issued or GDB operations performed\n- Expected result\n- Actual result\n- Logs using <code>debug_level 3</code> (or with '-d 3' on the command line)\n- If the report is for a regression:\n  - Include logs for both working and broken versions.\n  - Find the precise version that caused the regression by binary search.\n    You can use \"git bisect\" to expedite this binary search:\n    http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html\n\nIf possible, please develop and attach a patch that helps to expose or\nsolve the reported problem.  See the HACKING file for information\nabout that process.\n\nAttach all files directly to your posting.  The mailing list knows to\ntransform attachments to links, but attachments must be less than 300KB\nin total.\n\n@section bugscrashdump Obtaining Crash Backtraces\n\nIf OpenOCD is crashing, there are two very effective things you can do to\nimprove your chances of getting help on the development mailing list.\n\nTry to reproduce the problem using the dummy JTAG interface to allow other developers to replicate\nyour problem robustly and use GDB to get a trace:@par\n@code\n% OPENOCDSRC/configure --enable-dummy ...\n% openocd -f interface/dummy.cfg -f target/xxx.cfg\n=> SEGFAULT\n% gdb --args openocd ....\n(gdb) run\n(gdb) bt\n=> here a stack trace is dumped.\n@endcode\n\n@section bugsintreedebug Running and Debugging In-Tree\n\nTo run or debug the in-tree executable (not recommended), you must\nuse libtool to set up the correct shared library paths:\n@code\n  libtool gdb --args openocd ....\n@endcode\nor the more pedantic (and forward-compatible):\n@code\n  libtool --mode=execute gdb --args openocd ....\n@endcode\n\n */\n/** @file\nThis file contains the @ref bugs page.\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/COPYING",
    "content": "OpenOCD is provided under:\n\n\tSPDX-License-Identifier: GPL-2.0-or-later\n\nBeing under the terms of the GNU General Public License version 2 or\nlater, according with:\n\n\tLICENSES/preferred/GPL-2.0\n\nIn addition, other licenses may also apply. Please see:\n\n\tLICENSES/license-rules.txt\n\nfor more details.\n\nAll contributions to OpenOCD are subject to this COPYING file.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/ChangeLog",
    "content": "Retired in favor of git log.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/HACKING",
    "content": "// This file is part of the Doxygen Developer Manual\n/** @page patchguide Patch Guidelines\n\n\\attention You can't send patches to the mailing list anymore at all. Nowadays\nyou are expected to send patches to the OpenOCD Gerrit GIT server for a\nreview.\n\n\\attention If you already have a Gerrit account and want to try a\ndifferent sign in method, please first sign in as usually, press your\nname in the upper-right corner, go to @a Settings, select @a\nIdentities pane, press <em>Link Another Identity</em> button. In case\nyou already have duplicated accounts, ask administrators for manual\nmerging.\n\n\\attention If you're behind a corporate wall with http only access to the\nworld, you can still use these instructions!\n\n@section gerrit Submitting patches to the OpenOCD Gerrit server\n\nOpenOCD is to some extent a \"self service\" open source project, so to\ncontribute, you must follow the standard procedures to have the best\npossible chance to get your changes accepted.\n\nThe procedure to create a patch is essentially:\n\n- make the changes\n- create a commit\n- send the changes to the Gerrit server for review\n- correct the patch and re-send it according to review feedback\n\nYour patch (or commit) should be a \"good patch\": focus it on a single\nissue, and make it easily reviewable. Don't make\nit so large that it's hard to review; split large\npatches into smaller ones (this will also help\nto track down bugs later). All patches should\nbe \"clean\", which includes preserving the existing\ncoding style and updating documentation as needed. When adding a new\ncommand, the corresponding documentation should be added to\n@c doc/openocd.texi in the same commit. OpenOCD runs on both Little\nEndian and Big Endian hosts so the code can't count on specific byte\nordering (in other words, must be endian-clean).\n\nThere are several additional methods of improving the quality of your\npatch:\n\n- Runtime testing with Valgrind Memcheck\n\n  This helps to spot memory leaks, undefined behaviour due to\n  uninitialized data or wrong indexing, memory corruption, etc.\n\n- Clang Static Analyzer\n\n  Using this tool uncovers many different kinds of bugs in C code,\n  with problematic execution paths fully explained. It is a part of\n  standard Clang installation.\n\n  To generate a report, run this in the OpenOCD source directory:\n  @code\n  mkdir build-scanbuild; cd build-scanbuild\n  scan-build ../configure\n  scan-build make CFLAGS=\"-std=gnu99 -I. -I../../jimtcl\"\n  @endcode\n\n- Runtime testing with sanitizers\n\n  Both GCC and LLVM/Clang include advanced instrumentation options to\n  detect undefined behaviour and many kinds of memory\n  errors. Available with @c -fsanitize=* command arguments.\n\n  Example usage:\n  @code\n  mkdir build-sanitizers; cd build-sanitizers\n  ../configure CC=clang CFLAGS=\"-fno-omit-frame-pointer \\\n               -fsanitize=address -fsanitize=undefined -ggdb3\"\n  make\n  export ASAN_OPTIONS=detect_stack_use_after_return=1\n  src/openocd -s ../tcl -f /path/to/openocd.cfg\n  @endcode\n\n- Sparse Static Analyzer\n\n  Using this tool allows identifying some bug in C code.\n  In the future, OpenOCD would use the sparse attribute 'bitwise' to\n  detect incorrect endianness assignments.\n\n  Example usage:\n  @code\n  mkdir build-sparse; cd build-sparse\n  ../configure CC=cgcc CFLAGS=\"-Wsparse-all -Wno-declaration-after-statement \\\n\t   -Wno-unknown-attribute -Wno-transparent-union -Wno-tautological-compare \\\n       -Wno-vla -Wno-flexible-array-array -D__FLT_EVAL_METHOD__=0\"\n  make\n  @endcode\n\nPlease consider performing these additional checks where appropriate\n(especially Clang Static Analyzer for big portions of new code) and\nmention the results (e.g. \"Valgrind-clean, no new Clang analyzer\nwarnings\") in the commit message.\n\nSay in the commit message if it's a bugfix (describe the bug) or a new\nfeature. Don't expect patches to merge immediately\nfor the next release. Be ready to rework patches\nin response to feedback.\n\nAdd yourself to the GPL copyright for non-trivial changes.\n\n@section stepbystep Step by step procedure\n\n-# Create a Gerrit account at: https://review.openocd.org\n  - On subsequent sign ins, use the full URL prefaced with 'http://'\n    For example: http://user_identifier.open_id_provider.com\n  -# Add a username to your profile.\n     After creating the Gerrit account and signing in, you will need to\n     add a username to your profile. To do this, go to 'Settings', and\n     add a username of your choice.\n     Your username will be required in step 3 and substituted wherever\n     the string 'USERNAME' is found.\n  -# Create an SSH public key following the directions on github:\n     https://help.github.com/articles/generating-ssh-keys . You can skip step 3\n     (adding key to Github account) and 4 (testing) - these are useful only if\n     you actually use Github or want to test whether the new key works fine.\n  -# Add this new SSH key to your Gerrit account:\n     go to 'Settings' > 'SSH Public Keys', paste the contents of\n     ~/.ssh/id_rsa.pub into the text field (if it's not visible click on\n     'Add Key ...' button) and confirm by clicking 'Add' button.\n-# Clone the git repository, rather than just download the source:\n @code\n git clone git://git.code.sf.net/p/openocd/code openocd\n @endcode\n   or if you have problems with the \"git:\" protocol, use\n   the slower http protocol:\n @code\n git clone http://git.code.sf.net/p/openocd/code openocd\n @endcode\n-# Set up Gerrit with your local repository. All this does it\nto instruct git locally how to send off the changes.\n  -# Add a new remote to git using Gerrit username:\n@code\ngit remote add review ssh://USERNAME@review.openocd.org:29418/openocd.git\ngit config remote.review.push HEAD:refs/for/master\n@endcode\n  Or with http only:\n@code\ngit remote add review https://USERNAME@review.openocd.org/p/openocd.git\ngit config remote.review.push HEAD:refs/for/master\n@endcode\n  The http password is configured from your gerrit settings - https://review.openocd.org/#/settings/http-password.\n  \\note If you want to simplify http access you can also add your http password to the url as follows:\n@code\ngit remote add review https://USERNAME:PASSWORD@review.openocd.org/p/openocd.git\n@endcode\n  \\note All contributions should be pushed to @c refs/for/master on the\nGerrit server, even if you plan to use several local branches for different\ntopics. It is possible because @c for/master is not a traditional Git\nbranch.\n  -# You will need to install this hook, we will look into a better solution:\n@code\nscp -p -P 29418 USERNAME@review.openocd.org:hooks/commit-msg .git/hooks/\n@endcode\n  Or with http only:\n@code\nwget https://review.openocd.org/tools/hooks/commit-msg\nmv commit-msg .git/hooks\nchmod +x .git/hooks/commit-msg\n@endcode\n  \\note A script exists to simplify the two items above. Execute:\n@code\ntools/initial.sh <username>\n@endcode\nWith @<username@> being your Gerrit username.\n-# Set up git with your name and email:\n@code\ngit config --global user.name \"John Smith\"\ngit config --global user.email \"john@smith.org\"\n@endcode\n-# Work on your patches. Split the work into\n   multiple small patches that can be reviewed and\n   applied separately and safely to the OpenOCD\n   repository.\n@code\nwhile(!done) {\n  work - edit files using your favorite editor.\n  run \"git commit -s -a\" to commit all changes.\n  run tools/checkpatch.sh to verify your patch style is ok.\n}\n@endcode\n   \\note use \"git add .\" before commit to add new files.\n\n   \\note check @ref checkpatch for hint about checkpatch script\n\n   Commit message template, notice the short first line.\n   The field '<c>specify touched area</c>'\n   should identify the main part or subsystem the patch touches.\n@code{.unparsed}\nspecify touched area: short comment\n<blank line>\nLonger comments over several lines, explaining (where applicable) the\nreason for the patch and the general idea the solution is based on,\nany major design decisions, etc. Limit each comment line's length to 75\ncharacters; since 75 it's too short for a URL, you can put the URL in a\nseparate line preceded by 'Link: '.\n<blank line>\nSigned-off-by: ...\n@endcode\n   Examples:\n@code{.unparsed}\nflash/nor/atsame5: add SAME59 support\n\nAdd new device ID\n@endcode\n@code{.unparsed}\nflash/nor: flash driver for XYZ123\n\nAdd new flash driver for internal flash of ...\n@endcode\n@code{.unparsed}\ntarget/cortex_m: fix segmentation fault in cmd 'soft_reset_halt'\n\nsoft_reset_halt command failed reproducibly under following conditions: ...\nTest for NULL pointer and return error ...\n\nReported-by: John Reporter <rep9876@gmail.com>\nFixes: 123456789abc (\"target: the commit where the problem started\")\nBugLink: https://sourceforge.net/p/openocd/tickets/999/\n@endcode\n@code{.unparsed}\ndoc: fix typos\n@endcode\n   See \"git log\" for more examples.\n\n-# Next you need to make sure that your patches\n   are on top of the latest stuff on the server and\n   that there are no conflicts:\n@code\ngit pull --rebase origin master\n@endcode\n-# Send the patches to the Gerrit server for review:\n@code\ngit push review\n@endcode\n-# Forgot something, want to add more? Just make the changes and do:\n@code\ngit commit --amend\ngit push review\n@endcode\n\nFurther reading: http://www.coreboot.org/Git\n\n@section checkpatch About checkpatch script\n\nOpenOCD source code includes the script checkpatch to let developers to\nverify their patches before submitting them for review (see @ref gerrit).\n\nEvery patch for OpenOCD project that is submitted for review on Gerrit\nis tested by Jenkins. Jenkins will run the checkpatch script to analyze\neach patch.\nIf the script highlights either errors or warnings, Gerrit will add the\nscore \"-1\" to the patch and maintainers will probably ignore the patch,\nwaiting for the developer to send a fixed version.\n\nThe script checkpatch verifies the SPDX tag for new files against a very\nshort list of license tags.\nIf the license of your contribution is not listed there, but compatible\nwith OpenOCD license, please alert the maintainers or add the missing\nlicense in the first patch of your patch series.\n\nThe script checkpatch has been originally developed for the Linux kernel\nsource code, thus includes specific tests and checks related to Linux\ncoding style and to Linux code structure. While the script has been\nadapted for OpenOCD specificities, it still includes some Linux related\ntest. It is then possible that it triggers sometimes some <em>false\npositive</em>!\n\nIf you think that the error identified by checkpatch is a false\npositive, please report it to the openocd-devel mailing list or prepare\na patch for fixing checkpatch and send it to Gerrit for review.\n\n\\attention The procedure below is allowed only for <em>exceptional\ncases</em>. Do not use it to submit normal patches.\n\nThere are <em>exceptional cases</em> in which you need to skip some of\nthe tests from checkpatch in order to pass the approval from Gerrit.\n\nFor example, a patch that modify one line inside a big comment block\nwill not show the beginning or the end of the comment block. This can\nprevent checkpatch to detect the comment block. Checkpatch can wrongly\nconsider the modified comment line as a code line, triggering a set of\nfalse errors.\n\nOnly for <em>exceptional cases</em>, it is allowed to submit patches\nto Gerrit with the special field 'Checkpatch-ignore:' in the commit\nmessage. This field will cause checkpatch to ignore the error types\nlisted in the field, only for the patch itself.\nThe error type is printed by checkpatch on failure.\nFor example the names of Windows APIs mix lower and upper case chars,\nin violation of OpenOCD coding style, triggering a 'CAMELCASE' error:\n@code\nCHECK:CAMELCASE: Avoid CamelCase: <WSAGetLastError>\n#96105: FILE: src/helper/log.c:505:\n+       error_code = WSAGetLastError();\n@endcode\nAdding in the commit message of the patch the line:\n@code\nCheckpatch-ignore: CAMELCASE\n@endcode\nwill force checkpatch to ignore the CAMELCASE error.\n\n@section timeline When can I expect my contribution to be committed?\n\nThe code review is intended to take as long as a week or two to allow\nmaintainers and contributors who work on OpenOCD only in their spare\ntime opportunity to perform a review and raise objections.\n\nWith Gerrit much of the urgency of getting things committed has been\nremoved as the work in progress is safely stored in Gerrit and\navailable if someone needs to build on your work before it is\nsubmitted to the official repository.\n\nAnother factor that contributes to the desire for longer cool-off\ntimes (the time a patch lies around without any further changes or\ncomments), it means that the chances of quality regression on the\nmaster branch will be much reduced.\n\nIf a contributor pushes a patch, it is considered good form if another\ncontributor actually approves and submits that patch.\n\nIt should be noted that a negative review in Gerrit (\"-1\" or \"-2\") may (but does\nnot have to) be disregarded if all conditions listed below are met:\n\n- the concerns raised in the review have been addressed (or explained),\n- reviewer does not re-examine the change in a month,\n- reviewer does not answer e-mails for another month.\n\n@section browsing Browsing Patches\nAll OpenOCD patches can be reviewed <a href=\"https://review.openocd.org/\">here</a>.\n\n@section reviewing Reviewing Patches\nFrom the main <a href=\"https://review.openocd.org/#/q/status:open,n,z\">Review\npage</a> select the patch you want to review and click on that patch. On the\nappearing page select the download method (top right). Apply the\npatch. After building and testing you can leave a note with the \"Reply\"\nbutton and mark the patch with -1, 0 and +1.\n*/\n/** @file\nThis file contains the @ref patchguide page.\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/exceptions/eCos-exception-2.0",
    "content": "SPDX-Exception-Identifier: eCos-exception-2.0\nSPDX-URL: https://spdx.org/licenses/eCos-exception-2.0.html\nSPDX-Licenses: GPL-2.0-only, GPL-2.0-or-later\nUsage-Guide:\n  This exception is used together with one of the above SPDX-Licenses.\n  To use this exception add it with the keyword WITH to one of the\n  identifiers in the SPDX-Licenses tag:\n    SPDX-License-Identifier: <SPDX-License> WITH eCos-exception-2.0\nLicense-Text:\n\nAs a special exception, if other files instantiate templates or use\nmacros or inline functions from this file, or you compile this\nfile and link it with other works to produce a work based on this\nfile, this file does not by itself cause the resulting work to be\ncovered by the GNU General Public License. However the source code for\nthis file must still be made available in accordance with section (3)\nof the GNU General Public License.\n\nThis exception does not invalidate any other reasons why a work based on\nthis file might be covered by the GNU General Public License.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/license-rules.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\nOpenOCD licensing rules\n=======================\n\nThe OpenOCD source code is provided under the terms of the GNU General\nPublic License version 2 or later (GPL-2.0-or-later), as provided in\nLICENSES/preferred/GPL-2.0.\n\nThe OpenOCD documentation is provided under the terms of the GNU Free\nDocumentation License version 1.2 or later without Invariant Sections\n(GFDL-1.2-no-invariants-or-later).\n\nFew stand-alone applications coexist in the same code tree of OpenOCD\nand are provided under the terms of the GNU General Public License\nversion 3 (GPL-3.0), as provided in LICENSES/stand-alone/GPL-3.0.\n\nThis documentation file provides a description of how each source file\nshould be annotated to make its license clear and unambiguous.\nIt doesn't replace the OpenOCD's license.\n\nThe license described in the COPYING file applies to the OpenOCD source\nas a whole, though individual source files can have a different license\nwhich is required to be compatible with the GPL-2.0:\n\n    GPL-1.0-or-later  : GNU General Public License v1.0 or later\n    GPL-2.0-or-later  : GNU General Public License v2.0 or later\n    LGPL-2.0          : GNU Library General Public License v2 only\n    LGPL-2.0-or-later : GNU Library General Public License v2 or later\n    LGPL-2.1          : GNU Lesser General Public License v2.1 only\n    LGPL-2.1-or-later : GNU Lesser General Public License v2.1 or later\n\nAside from that, individual files can be provided under a dual license,\ne.g. one of the compatible GPL variants and alternatively under a\npermissive license like BSD, MIT etc.\n\nThe common way of expressing the license of a source file is to add the\nmatching boilerplate text into the top comment of the file. Due to\nformatting, typos etc. these \"boilerplates\" are hard to validate for\ntools which are used in the context of license compliance.\n\nAn alternative to boilerplate text is the use of Software Package Data\nExchange (SPDX) license identifiers in each source file. SPDX license\nidentifiers are machine parsable and precise shorthands for the license\nunder which the content of the file is contributed. SPDX license\nidentifiers are managed by the SPDX Workgroup at the Linux Foundation and\nhave been agreed on by partners throughout the industry, tool vendors, and\nlegal teams. For further information see https://spdx.org/\n\nOpenOCD requires the precise SPDX identifier in all source files.\nThe valid identifiers used in OpenOCD are explained in the section\n`License identifiers` and have been retrieved from the official SPDX\nlicense list at https://spdx.org/licenses/ along with the license texts.\n\nLicense identifier syntax\n-------------------------\n\n1. Placement:\n\n   The SPDX license identifier in OpenOCD files shall be added at the\n   first possible line in a file which can contain a comment. For the\n   majority of files this is the first line, except for scripts which\n   require the '#!PATH_TO_INTERPRETER' in the first line. For those\n   scripts the SPDX identifier goes into the second line.\n\n2. Style:\n\n   The SPDX license identifier is added in form of a comment. The comment\n   style depends on the file type::\n\n      C source:  // SPDX-License-Identifier: <SPDX License Expression>\n      C header:  /* SPDX-License-Identifier: <SPDX License Expression> */\n      ASM:       /* SPDX-License-Identifier: <SPDX License Expression> */\n      makefiles: # SPDX-License-Identifier: <SPDX License Expression>\n      scripts:   # SPDX-License-Identifier: <SPDX License Expression>\n      texinfo:   @c SPDX-License-Identifier: <SPDX License Expression>\n      text:      # SPDX-License-Identifier: <SPDX License Expression>\n\n   If a specific tool cannot handle the standard comment style, then the\n   appropriate comment mechanism which the tool accepts shall be used. This\n   is the reason for having the \"/\\* \\*/\" style comment in C header\n   files. There was build breakage observed with generated .lds files where\n   'ld' failed to parse the C++ comment. This has been fixed by now, but\n   there are still older assembler tools which cannot handle C++ style\n   comments.\n\n3. Syntax:\n\n   A <SPDX License Expression> is either an SPDX short form license\n   identifier found on the SPDX License List, or the combination of two\n   SPDX short form license identifiers separated by \"WITH\" when a license\n   exception applies. When multiple licenses apply, an expression consists\n   of keywords \"AND\", \"OR\" separating sub-expressions and surrounded by\n   \"(\", \")\" .\n\n   License identifiers for licenses like [L]GPL with the 'or later' option\n   are constructed by using a \"-or-later\":\n\n      // SPDX-License-Identifier: GPL-2.0-or-later\n      // SPDX-License-Identifier: LGPL-2.1-or-later\n\n   WITH should be used when there is a modifier to a license needed.\n   Exceptions can only be used with particular License identifiers. The\n   valid License identifiers are listed in the tags of the exception text\n   file.\n\n   OR should be used if the file is dual licensed and only one license is\n   to be selected. For example, some source files are available under dual\n   licenses:\n\n      // SPDX-License-Identifier: GPL-2.0-or-later OR BSD-1-Clause\n      // SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause\n      // SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause\n\n   AND should be used if the file has multiple licenses whose terms all\n   apply to use the file. For example, if code is inherited from another\n   project and permission has been given to put it in OpenOCD, but the\n   original license terms need to remain in effect::\n\n      // SPDX-License-Identifier: GPL-2.0-or-later AND MIT\n\nLicense identifiers\n-------------------\n\nThe licenses currently used, as well as the licenses for code added to\nOpenOCD, can be broken down into:\n\n1. `Preferred licenses`:\n\n   Whenever possible these licenses should be used as they are known to be\n   fully compatible and widely used. These licenses are available from the\n   directory:\n\n      LICENSES/preferred/\n\n   in the OpenOCD source tree.\n\n   The files in this directory contain the full license text and\n   `Metatags`. The file names are identical to the SPDX license\n   identifier which shall be used for the license in source files.\n\n   Examples:\n\n      LICENSES/preferred/GPL-2.0\n\n   Contains the GPL version 2 license text and the required metatags.\n\n   `Metatags`:\n\n   The following meta tags must be available in a license file:\n\n   - Valid-License-Identifier:\n\n     One or more lines which declare which License Identifiers are valid\n     inside the project to reference this particular license text. Usually\n     this is a single valid identifier, but e.g. for licenses with the 'or\n     later' options two identifiers are valid.\n\n   - SPDX-URL:\n\n     The URL of the SPDX page which contains additional information related\n     to the license.\n\n   - Usage-Guidance:\n\n     Freeform text for usage advice. The text must include correct examples\n     for the SPDX license identifiers as they should be put into source\n     files according to the `License identifier syntax` guidelines.\n\n   - License-Text:\n\n     All text after this tag is treated as the original license text\n\n   File format examples::\n\n      Valid-License-Identifier: GPL-2.0\n      Valid-License-Identifier: GPL-2.0-only\n      Valid-License-Identifier: GPL-2.0-or-later\n      SPDX-URL: https://spdx.org/licenses/GPL-2.0.html\n      Usage-Guide:\n        To use this license in source code, put one of the following SPDX\n        tag/value pairs into a comment according to the placement\n        guidelines in the licensing rules documentation.\n        For 'GNU General Public License (GPL) version 2 only' use:\n          SPDX-License-Identifier: GPL-2.0\n        or\n          SPDX-License-Identifier: GPL-2.0-only\n        For 'GNU General Public License (GPL) version 2 or any later version' use:\n          SPDX-License-Identifier: GPL-2.0-or-later\n      License-Text:\n        Full license text\n\n2. Exceptions:\n\n   Some licenses can be amended with exceptions which grant certain rights\n   which the original license does not.  These exceptions are available\n   from the directory::\n\n      LICENSES/exceptions/\n\n   in the OpenOCD source tree.  The files in this directory contain the full\n   exception text and the required `Exception Metatags`_.\n\n   Examples::\n\n      LICENSES/exceptions/eCos-exception-2.0\n\n   Exception Metatags:\n\n   The following meta tags must be available in an exception file:\n\n   - SPDX-Exception-Identifier:\n\n     One exception identifier which can be used with SPDX license\n     identifiers.\n\n   - SPDX-URL:\n\n     The URL of the SPDX page which contains additional information related\n     to the exception.\n\n   - SPDX-Licenses:\n\n     A comma separated list of SPDX license identifiers for which the\n     exception can be used.\n\n   - Usage-Guidance:\n\n     Freeform text for usage advice. The text must be followed by correct\n     examples for the SPDX license identifiers as they should be put into\n     source files according to the `License identifier syntax`_ guidelines.\n\n   - Exception-Text:\n\n     All text after this tag is treated as the original exception text\n\n   File format examples::\n\n      SPDX-Exception-Identifier: eCos-exception-2.0\n      SPDX-URL: https://spdx.org/licenses/eCos-exception-2.0.html\n      SPDX-Licenses: GPL-2.0-only, GPL-2.0-or-later\n      Usage-Guide:\n        This exception is used together with one of the above SPDX-Licenses.\n        To use this exception add it with the keyword WITH to one of the\n        identifiers in the SPDX-Licenses tag:\n          SPDX-License-Identifier: <SPDX-License> WITH eCos-exception-2.0\n      License-Text:\n        Full license text\n\n3. Stand-alone licenses:\n\n   These licenses should only be used for stand-alone applications that are\n   distributed with OpenOCD but are not included in the OpenOCD binary.\n   These licenses are available from the directory:\n\n     LICENSES/stand-alone/\n\n   in the OpenOCD source tree.\n\n   Examples:\n\n     SPDX-License-Identifier: GPL-3.0\n\nThe format and requirements of the license files in the other sub-directories\nof directory\n\n   LICENSES\n\nhave to follow the same format and requirements of the `Preferred licenses`.\n\nAll SPDX license identifiers and exceptions must have a corresponding file\nin the LICENSES subdirectories. This is required to allow tool\nverification (e.g. checkpatch.pl) and to have the licenses ready to read\nand extract right from the source, which is recommended by various FOSS\norganizations, e.g. the `FSFE REUSE initiative <https://reuse.software/>`.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/BSD-1-Clause",
    "content": "Valid-License-Identifier: BSD-1-Clause\nSPDX-URL: https://spdx.org/licenses/BSD-1-Clause.html\nUsage-Guide:\n  To use the BSD 1-clause License put the following SPDX\n  tag/value pair into a comment according to the placement guidelines in\n  the licensing rules documentation:\n    SPDX-License-Identifier: BSD-1-Clause\nLicense-Text:\n\nCopyright (c) <year> <owner> . All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/BSD-2-Clause",
    "content": "Valid-License-Identifier: BSD-2-Clause\nSPDX-URL: https://spdx.org/licenses/BSD-2-Clause.html\nUsage-Guide:\n  To use the BSD 2-clause \"Simplified\" License put the following SPDX\n  tag/value pair into a comment according to the placement guidelines in\n  the licensing rules documentation:\n    SPDX-License-Identifier: BSD-2-Clause\nLicense-Text:\n\nCopyright (c) <year> <owner> . All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/BSD-2-Clause-Views",
    "content": "Valid-License-Identifier: BSD-2-Clause-Views\nSPDX-URL: https://spdx.org/licenses/BSD-2-Clause-Views.html\nUsage-Guide:\n  To use the BSD 2-clause with views sentence License put the following SPDX\n  tag/value pair into a comment according to the placement guidelines in\n  the licensing rules documentation:\n    SPDX-License-Identifier: BSD-2-Clause-Views\nLicense-Text:\n\nCopyright (c) <year> <owner> . All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n\nThe views and conclusions contained in the software and documentation\nare those of the authors and should not be interpreted as representing\nofficial policies, either expressed or implied, of the copyright holders\nor contributors.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/BSD-3-Clause",
    "content": "Valid-License-Identifier: BSD-3-Clause\nSPDX-URL: https://spdx.org/licenses/BSD-3-Clause.html\nUsage-Guide:\n  To use the BSD 3-clause \"New\" or \"Revised\" License put the following SPDX\n  tag/value pair into a comment according to the placement guidelines in\n  the licensing rules documentation:\n    SPDX-License-Identifier: BSD-3-Clause\nLicense-Text:\n\nCopyright (c) <year> <owner> . All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from this\n   software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/BSD-Source-Code",
    "content": "Valid-License-Identifier: BSD-Source-Code\nSPDX-URL: https://spdx.org/licenses/BSD-Source-Code.html\nUsage-Guide:\n  To use the BSD Source Code Attribution License put the following SPDX\n  tag/value pair into a comment according to the placement guidelines in\n  the licensing rules documentation:\n    SPDX-License-Identifier: BSD-Source-Code\nLicense-Text:\n\nCopyright (c) <year> <owner> . All rights reserved.\n\nRedistribution and use of this software in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright notice,\n   this list of conditions and the following disclaimer.\n\n * Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from this\n   software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\nLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\nCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\nSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\nINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\nCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\nARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/GFDL-1.2",
    "content": "Valid-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\nValid-License-Identifier: GFDL-1.2-no-invariants-or-later\nSPDX-URL: https://spdx.org/licenses/GFDL-1.2-no-invariants-or-later.html\nUsage-Guide:\n  The GNU Free Documentation License should only be used without\n  Invariant Sections, Front-Cover Texts or Back-Cover Texts.\n  It should not be used for new documents.\n  To use the license in source code, put the following SPDX tag/value pair\n  into a comment according to the placement guidelines in the licensing\n  rules documentation:\n    SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n  or\n    SPDX-License-Identifier: GFDL-1.2-no-invariants-or-later\nLicense-Text:\n\n                GNU Free Documentation License\n                  Version 1.2, November 2002\n\n\n Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.\n     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n\n0. PREAMBLE\n\nThe purpose of this License is to make a manual, textbook, or other\nfunctional and useful document \"free\" in the sense of freedom: to\nassure everyone the effective freedom to copy and redistribute it,\nwith or without modifying it, either commercially or noncommercially.\nSecondarily, this License preserves for the author and publisher a way\nto get credit for their work, while not being considered responsible\nfor modifications made by others.\n\nThis License is a kind of \"copyleft\", which means that derivative\nworks of the document must themselves be free in the same sense.  It\ncomplements the GNU General Public License, which is a copyleft\nlicense designed for free software.\n\nWe have designed this License in order to use it for manuals for free\nsoftware, because free software needs free documentation: a free\nprogram should come with manuals providing the same freedoms that the\nsoftware does.  But this License is not limited to software manuals;\nit can be used for any textual work, regardless of subject matter or\nwhether it is published as a printed book.  We recommend this License\nprincipally for works whose purpose is instruction or reference.\n\n\n1. APPLICABILITY AND DEFINITIONS\n\nThis License applies to any manual or other work, in any medium, that\ncontains a notice placed by the copyright holder saying it can be\ndistributed under the terms of this License.  Such a notice grants a\nworld-wide, royalty-free license, unlimited in duration, to use that\nwork under the conditions stated herein.  The \"Document\", below,\nrefers to any such manual or work.  Any member of the public is a\nlicensee, and is addressed as \"you\".  You accept the license if you\ncopy, modify or distribute the work in a way requiring permission\nunder copyright law.\n\nA \"Modified Version\" of the Document means any work containing the\nDocument or a portion of it, either copied verbatim, or with\nmodifications and/or translated into another language.\n\nA \"Secondary Section\" is a named appendix or a front-matter section of\nthe Document that deals exclusively with the relationship of the\npublishers or authors of the Document to the Document's overall subject\n(or to related matters) and contains nothing that could fall directly\nwithin that overall subject.  (Thus, if the Document is in part a\ntextbook of mathematics, a Secondary Section may not explain any\nmathematics.)  The relationship could be a matter of historical\nconnection with the subject or with related matters, or of legal,\ncommercial, philosophical, ethical or political position regarding\nthem.\n\nThe \"Invariant Sections\" are certain Secondary Sections whose titles\nare designated, as being those of Invariant Sections, in the notice\nthat says that the Document is released under this License.  If a\nsection does not fit the above definition of Secondary then it is not\nallowed to be designated as Invariant.  The Document may contain zero\nInvariant Sections.  If the Document does not identify any Invariant\nSections then there are none.\n\nThe \"Cover Texts\" are certain short passages of text that are listed,\nas Front-Cover Texts or Back-Cover Texts, in the notice that says that\nthe Document is released under this License.  A Front-Cover Text may\nbe at most 5 words, and a Back-Cover Text may be at most 25 words.\n\nA \"Transparent\" copy of the Document means a machine-readable copy,\nrepresented in a format whose specification is available to the\ngeneral public, that is suitable for revising the document\nstraightforwardly with generic text editors or (for images composed of\npixels) generic paint programs or (for drawings) some widely available\ndrawing editor, and that is suitable for input to text formatters or\nfor automatic translation to a variety of formats suitable for input\nto text formatters.  A copy made in an otherwise Transparent file\nformat whose markup, or absence of markup, has been arranged to thwart\nor discourage subsequent modification by readers is not Transparent.\nAn image format is not Transparent if used for any substantial amount\nof text.  A copy that is not \"Transparent\" is called \"Opaque\".\n\nExamples of suitable formats for Transparent copies include plain\nASCII without markup, Texinfo input format, LaTeX input format, SGML\nor XML using a publicly available DTD, and standard-conforming simple\nHTML, PostScript or PDF designed for human modification.  Examples of\ntransparent image formats include PNG, XCF and JPG.  Opaque formats\ninclude proprietary formats that can be read and edited only by\nproprietary word processors, SGML or XML for which the DTD and/or\nprocessing tools are not generally available, and the\nmachine-generated HTML, PostScript or PDF produced by some word\nprocessors for output purposes only.\n\nThe \"Title Page\" means, for a printed book, the title page itself,\nplus such following pages as are needed to hold, legibly, the material\nthis License requires to appear in the title page.  For works in\nformats which do not have any title page as such, \"Title Page\" means\nthe text near the most prominent appearance of the work's title,\npreceding the beginning of the body of the text.\n\nA section \"Entitled XYZ\" means a named subunit of the Document whose\ntitle either is precisely XYZ or contains XYZ in parentheses following\ntext that translates XYZ in another language.  (Here XYZ stands for a\nspecific section name mentioned below, such as \"Acknowledgements\",\n\"Dedications\", \"Endorsements\", or \"History\".)  To \"Preserve the Title\"\nof such a section when you modify the Document means that it remains a\nsection \"Entitled XYZ\" according to this definition.\n\nThe Document may include Warranty Disclaimers next to the notice which\nstates that this License applies to the Document.  These Warranty\nDisclaimers are considered to be included by reference in this\nLicense, but only as regards disclaiming warranties: any other\nimplication that these Warranty Disclaimers may have is void and has\nno effect on the meaning of this License.\n\n\n2. VERBATIM COPYING\n\nYou may copy and distribute the Document in any medium, either\ncommercially or noncommercially, provided that this License, the\ncopyright notices, and the license notice saying this License applies\nto the Document are reproduced in all copies, and that you add no other\nconditions whatsoever to those of this License.  You may not use\ntechnical measures to obstruct or control the reading or further\ncopying of the copies you make or distribute.  However, you may accept\ncompensation in exchange for copies.  If you distribute a large enough\nnumber of copies you must also follow the conditions in section 3.\n\nYou may also lend copies, under the same conditions stated above, and\nyou may publicly display copies.\n\n\n3. COPYING IN QUANTITY\n\nIf you publish printed copies (or copies in media that commonly have\nprinted covers) of the Document, numbering more than 100, and the\nDocument's license notice requires Cover Texts, you must enclose the\ncopies in covers that carry, clearly and legibly, all these Cover\nTexts: Front-Cover Texts on the front cover, and Back-Cover Texts on\nthe back cover.  Both covers must also clearly and legibly identify\nyou as the publisher of these copies.  The front cover must present\nthe full title with all words of the title equally prominent and\nvisible.  You may add other material on the covers in addition.\nCopying with changes limited to the covers, as long as they preserve\nthe title of the Document and satisfy these conditions, can be treated\nas verbatim copying in other respects.\n\nIf the required texts for either cover are too voluminous to fit\nlegibly, you should put the first ones listed (as many as fit\nreasonably) on the actual cover, and continue the rest onto adjacent\npages.\n\nIf you publish or distribute Opaque copies of the Document numbering\nmore than 100, you must either include a machine-readable Transparent\ncopy along with each Opaque copy, or state in or with each Opaque copy\na computer-network location from which the general network-using\npublic has access to download using public-standard network protocols\na complete Transparent copy of the Document, free of added material.\nIf you use the latter option, you must take reasonably prudent steps,\nwhen you begin distribution of Opaque copies in quantity, to ensure\nthat this Transparent copy will remain thus accessible at the stated\nlocation until at least one year after the last time you distribute an\nOpaque copy (directly or through your agents or retailers) of that\nedition to the public.\n\nIt is requested, but not required, that you contact the authors of the\nDocument well before redistributing any large number of copies, to give\nthem a chance to provide you with an updated version of the Document.\n\n\n4. MODIFICATIONS\n\nYou may copy and distribute a Modified Version of the Document under\nthe conditions of sections 2 and 3 above, provided that you release\nthe Modified Version under precisely this License, with the Modified\nVersion filling the role of the Document, thus licensing distribution\nand modification of the Modified Version to whoever possesses a copy\nof it.  In addition, you must do these things in the Modified Version:\n\nA. Use in the Title Page (and on the covers, if any) a title distinct\n   from that of the Document, and from those of previous versions\n   (which should, if there were any, be listed in the History section\n   of the Document).  You may use the same title as a previous version\n   if the original publisher of that version gives permission.\nB. List on the Title Page, as authors, one or more persons or entities\n   responsible for authorship of the modifications in the Modified\n   Version, together with at least five of the principal authors of the\n   Document (all of its principal authors, if it has fewer than five),\n   unless they release you from this requirement.\nC. State on the Title page the name of the publisher of the\n   Modified Version, as the publisher.\nD. Preserve all the copyright notices of the Document.\nE. Add an appropriate copyright notice for your modifications\n   adjacent to the other copyright notices.\nF. Include, immediately after the copyright notices, a license notice\n   giving the public permission to use the Modified Version under the\n   terms of this License, in the form shown in the Addendum below.\nG. Preserve in that license notice the full lists of Invariant Sections\n   and required Cover Texts given in the Document's license notice.\nH. Include an unaltered copy of this License.\nI. Preserve the section Entitled \"History\", Preserve its Title, and add\n   to it an item stating at least the title, year, new authors, and\n   publisher of the Modified Version as given on the Title Page.  If\n   there is no section Entitled \"History\" in the Document, create one\n   stating the title, year, authors, and publisher of the Document as\n   given on its Title Page, then add an item describing the Modified\n   Version as stated in the previous sentence.\nJ. Preserve the network location, if any, given in the Document for\n   public access to a Transparent copy of the Document, and likewise\n   the network locations given in the Document for previous versions\n   it was based on.  These may be placed in the \"History\" section.\n   You may omit a network location for a work that was published at\n   least four years before the Document itself, or if the original\n   publisher of the version it refers to gives permission.\nK. For any section Entitled \"Acknowledgements\" or \"Dedications\",\n   Preserve the Title of the section, and preserve in the section all\n   the substance and tone of each of the contributor acknowledgements\n   and/or dedications given therein.\nL. Preserve all the Invariant Sections of the Document,\n   unaltered in their text and in their titles.  Section numbers\n   or the equivalent are not considered part of the section titles.\nM. Delete any section Entitled \"Endorsements\".  Such a section\n   may not be included in the Modified Version.\nN. Do not retitle any existing section to be Entitled \"Endorsements\"\n   or to conflict in title with any Invariant Section.\nO. Preserve any Warranty Disclaimers.\n\nIf the Modified Version includes new front-matter sections or\nappendices that qualify as Secondary Sections and contain no material\ncopied from the Document, you may at your option designate some or all\nof these sections as invariant.  To do this, add their titles to the\nlist of Invariant Sections in the Modified Version's license notice.\nThese titles must be distinct from any other section titles.\n\nYou may add a section Entitled \"Endorsements\", provided it contains\nnothing but endorsements of your Modified Version by various\nparties--for example, statements of peer review or that the text has\nbeen approved by an organization as the authoritative definition of a\nstandard.\n\nYou may add a passage of up to five words as a Front-Cover Text, and a\npassage of up to 25 words as a Back-Cover Text, to the end of the list\nof Cover Texts in the Modified Version.  Only one passage of\nFront-Cover Text and one of Back-Cover Text may be added by (or\nthrough arrangements made by) any one entity.  If the Document already\nincludes a cover text for the same cover, previously added by you or\nby arrangement made by the same entity you are acting on behalf of,\nyou may not add another; but you may replace the old one, on explicit\npermission from the previous publisher that added the old one.\n\nThe author(s) and publisher(s) of the Document do not by this License\ngive permission to use their names for publicity for or to assert or\nimply endorsement of any Modified Version.\n\n\n5. COMBINING DOCUMENTS\n\nYou may combine the Document with other documents released under this\nLicense, under the terms defined in section 4 above for modified\nversions, provided that you include in the combination all of the\nInvariant Sections of all of the original documents, unmodified, and\nlist them all as Invariant Sections of your combined work in its\nlicense notice, and that you preserve all their Warranty Disclaimers.\n\nThe combined work need only contain one copy of this License, and\nmultiple identical Invariant Sections may be replaced with a single\ncopy.  If there are multiple Invariant Sections with the same name but\ndifferent contents, make the title of each such section unique by\nadding at the end of it, in parentheses, the name of the original\nauthor or publisher of that section if known, or else a unique number.\nMake the same adjustment to the section titles in the list of\nInvariant Sections in the license notice of the combined work.\n\nIn the combination, you must combine any sections Entitled \"History\"\nin the various original documents, forming one section Entitled\n\"History\"; likewise combine any sections Entitled \"Acknowledgements\",\nand any sections Entitled \"Dedications\".  You must delete all sections\nEntitled \"Endorsements\".\n\n\n6. COLLECTIONS OF DOCUMENTS\n\nYou may make a collection consisting of the Document and other documents\nreleased under this License, and replace the individual copies of this\nLicense in the various documents with a single copy that is included in\nthe collection, provided that you follow the rules of this License for\nverbatim copying of each of the documents in all other respects.\n\nYou may extract a single document from such a collection, and distribute\nit individually under this License, provided you insert a copy of this\nLicense into the extracted document, and follow this License in all\nother respects regarding verbatim copying of that document.\n\n\n7. AGGREGATION WITH INDEPENDENT WORKS\n\nA compilation of the Document or its derivatives with other separate\nand independent documents or works, in or on a volume of a storage or\ndistribution medium, is called an \"aggregate\" if the copyright\nresulting from the compilation is not used to limit the legal rights\nof the compilation's users beyond what the individual works permit.\nWhen the Document is included in an aggregate, this License does not\napply to the other works in the aggregate which are not themselves\nderivative works of the Document.\n\nIf the Cover Text requirement of section 3 is applicable to these\ncopies of the Document, then if the Document is less than one half of\nthe entire aggregate, the Document's Cover Texts may be placed on\ncovers that bracket the Document within the aggregate, or the\nelectronic equivalent of covers if the Document is in electronic form.\nOtherwise they must appear on printed covers that bracket the whole\naggregate.\n\n\n8. TRANSLATION\n\nTranslation is considered a kind of modification, so you may\ndistribute translations of the Document under the terms of section 4.\nReplacing Invariant Sections with translations requires special\npermission from their copyright holders, but you may include\ntranslations of some or all Invariant Sections in addition to the\noriginal versions of these Invariant Sections.  You may include a\ntranslation of this License, and all the license notices in the\nDocument, and any Warranty Disclaimers, provided that you also include\nthe original English version of this License and the original versions\nof those notices and disclaimers.  In case of a disagreement between\nthe translation and the original version of this License or a notice\nor disclaimer, the original version will prevail.\n\nIf a section in the Document is Entitled \"Acknowledgements\",\n\"Dedications\", or \"History\", the requirement (section 4) to Preserve\nits Title (section 1) will typically require changing the actual\ntitle.\n\n\n9. TERMINATION\n\nYou may not copy, modify, sublicense, or distribute the Document except\nas expressly provided for under this License.  Any other attempt to\ncopy, modify, sublicense or distribute the Document is void, and will\nautomatically terminate your rights under this License.  However,\nparties who have received copies, or rights, from you under this\nLicense will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n\n10. FUTURE REVISIONS OF THIS LICENSE\n\nThe Free Software Foundation may publish new, revised versions\nof the GNU Free Documentation License from time to time.  Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.  See\nhttps://www.gnu.org/licenses/.\n\nEach version of the License is given a distinguishing version number.\nIf the Document specifies that a particular numbered version of this\nLicense \"or any later version\" applies to it, you have the option of\nfollowing the terms and conditions either of that specified version or\nof any later version that has been published (not as a draft) by the\nFree Software Foundation.  If the Document does not specify a version\nnumber of this License, you may choose any version ever published (not\nas a draft) by the Free Software Foundation.\n\n\nADDENDUM: How to use this License for your documents\n\nTo use this License in a document you have written, include a copy of\nthe License in the document and put the following copyright and\nlicense notices just after the title page:\n\n    Copyright (c)  YEAR  YOUR NAME.\n    Permission is granted to copy, distribute and/or modify this document\n    under the terms of the GNU Free Documentation License, Version 1.2\n    or any later version published by the Free Software Foundation;\n    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.\n    A copy of the license is included in the section entitled \"GNU\n    Free Documentation License\".\n\nIf you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,\nreplace the \"with...Texts.\" line with this:\n\n    with the Invariant Sections being LIST THEIR TITLES, with the\n    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.\n\nIf you have Invariant Sections without Cover Texts, or some other\ncombination of the three, merge those two alternatives to suit the\nsituation.\n\nIf your document contains nontrivial examples of program code, we\nrecommend releasing these examples in parallel under your choice of\nfree software license, such as the GNU General Public License,\nto permit their use in free software.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/GPL-2.0",
    "content": "Valid-License-Identifier: GPL-2.0\nValid-License-Identifier: GPL-2.0-only\nValid-License-Identifier: GPL-2.0-or-later\nSPDX-URL: https://spdx.org/licenses/GPL-2.0.html\nUsage-Guide:\n  To use this license in source code, put one of the following SPDX\n  tag/value pairs into a comment according to the placement\n  guidelines in the licensing rules documentation.\n  For 'GNU General Public License (GPL) version 2 only' use:\n    SPDX-License-Identifier: GPL-2.0\n  or\n    SPDX-License-Identifier: GPL-2.0-only\n  For 'GNU General Public License (GPL) version 2 or any later version' use:\n    SPDX-License-Identifier: GPL-2.0-or-later\nLicense-Text:\n\n                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/MIT",
    "content": "Valid-License-Identifier: MIT\nSPDX-URL: https://spdx.org/licenses/MIT.html\nUsage-Guide:\n  To use the MIT License put the following SPDX tag/value pair into a\n  comment according to the placement guidelines in the licensing rules\n  documentation:\n    SPDX-License-Identifier: MIT\nLicense-Text:\n\nMIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a\ncopy of this software and associated documentation files (the \"Software\"),\nto deal in the Software without restriction, including without limitation\nthe rights to use, copy, modify, merge, publish, distribute, sublicense,\nand/or sell copies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\nDEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/preferred/gfdl-1.2.texi.readme",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\nThe texinfo version of the license gfdl-1.2 is distributed in the\nfile doc/fdl.texi .\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/LICENSES/stand-alone/GPL-3.0",
    "content": "Valid-License-Identifier: GPL-3.0\nValid-License-Identifier: GPL-3.0-only\nValid-License-Identifier: GPL-3.0-or-later\nSPDX-URL: https://spdx.org/licenses/GPL-3.0.html\nUsage-Guide:\n  To use this license in source code, put one of the following SPDX\n  tag/value pairs into a comment according to the placement\n  guidelines in the licensing rules documentation.\n  For 'GNU General Public License (GPL) version 3 only' use:\n    SPDX-License-Identifier: GPL-3.0\n  or\n    SPDX-License-Identifier: GPL-3.0-only\n  For 'GNU General Public License (GPL) version 3 or any later version' use:\n    SPDX-License-Identifier: GPL-3.0-or-later\nLicense-Text:\n\n                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<https://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# not a GNU package. You can remove this line, if\n# have all needed files, that a GNU package needs\nAUTOMAKE_OPTIONS = gnu 1.6\n\n.DELETE_ON_ERROR:\n\n# make sure we pass the correct jimtcl flags to distcheck\nDISTCHECK_CONFIGURE_FLAGS = --disable-install-jim\n\n# do not run Jim Tcl tests (esp. during distcheck)\ncheck-recursive: SUBDIRS :=\n\nnobase_dist_pkgdata_DATA = \\\n\tcontrib/libdcc/dcc_stdio.c \\\n\tcontrib/libdcc/dcc_stdio.h \\\n\tcontrib/libdcc/example.c \\\n\tcontrib/libdcc/README \\\n\tcontrib/60-openocd.rules\n\nSUBDIRS =\nDIST_SUBDIRS =\nbin_PROGRAMS =\nnoinst_LTLIBRARIES =\ninfo_TEXINFOS =\ndist_man_MANS =\nEXTRA_DIST =\nDISTCLEANFILES =\n\nif INTERNAL_JIMTCL\nSUBDIRS += jimtcl\nDIST_SUBDIRS += jimtcl\nEXTRA_DIST += jimtcl/configure.gnu\n# jimtcl from 0.79 to 0.82 miss cleaning jsmn.o\nDISTCLEANFILES += jimtcl/jsmn/jsmn.o\nendif\n\n# common flags used in openocd build\nAM_CFLAGS = $(GCC_WARNINGS)\n\nAM_CPPFLAGS = $(HOST_CPPFLAGS)\\\n\t\t\t  -I$(top_srcdir)/src \\\n\t\t\t  -I$(top_builddir)/src \\\n\t\t\t  -DPKGDATADIR=\\\"$(pkgdatadir)\\\" \\\n\t\t\t  -DBINDIR=\\\"$(bindir)\\\"\n\nif INTERNAL_JIMTCL\nAM_CPPFLAGS += -I$(top_srcdir)/jimtcl \\\n\t\t\t   -I$(top_builddir)/jimtcl\nendif\nEXTRA_DIST += \\\n\tBUGS \\\n\tHACKING \\\n\tNEWTAPS \\\n\tREADME.Windows \\\n\tREADME.macOS \\\n\t$(EXTRA_DIST_NEWS) \\\n\tDoxyfile.in \\\n\tLICENSES/license-rules.txt \\\n\tLICENSES/exceptions/eCos-exception-2.0 \\\n\tLICENSES/preferred/BSD-1-Clause \\\n\tLICENSES/preferred/BSD-2-Clause \\\n\tLICENSES/preferred/BSD-2-Clause-Views \\\n\tLICENSES/preferred/BSD-3-Clause \\\n\tLICENSES/preferred/BSD-Source-Code \\\n\tLICENSES/preferred/GFDL-1.2 \\\n\tLICENSES/preferred/gfdl-1.2.texi.readme \\\n\tLICENSES/preferred/GPL-2.0 \\\n\tLICENSES/preferred/MIT \\\n\tLICENSES/stand-alone/GPL-3.0 \\\n\ttools/logger.pl \\\n\ttools/rlink_make_speed_table \\\n\ttools/st7_dtc_as \\\n\tcontrib\n\nlibtool: $(LIBTOOL_DEPS)\n\t$(SHELL) ./config.status --recheck\n\ndocs: pdf html doxygen\n\nDoxyfile: $(srcdir)/Doxyfile.in\n\t@echo \"Creating $@ from $<...\"\n\t@( \\\n\t  echo \"### @@@ -= DO NOT EDIT THIS FILE =- @@@ ###\" && \\\n\t  echo \"### @@@ Make changes to Doxyfile.in @@@ ###\" && \\\n\t  sed -e 's,@srcdir\\@,$(srcdir),' \\\n\t    -e 's,@builddir\\@,$(builddir),' \\\n\t    -e 's,@doxygen_as_html\\@,$(doxygen_as_html),' \\\n\t    -e 's,@doxygen_as_pdf\\@,$(doxygen_as_pdf),' $< \\\n\t) > $@\n\nTHE_MANUAL = doxygen/latex/refman.pdf\n\ndoxygen::\n\t$(MAKE) Doxyfile\n\tdoxygen Doxyfile 2>&1 | perl $(srcdir)/tools/logger.pl > doxygen.log\n\t@if [ -f doxygen/latex/refman.tex ]; then \\\n\t\techo \"Creating $(THE_MANUAL)...\"; \\\n\t\t$(MAKE) $(THE_MANUAL); \\\n\telse \\\n\t\techo \"Skipping Doxygen PDF...\"; \\\n\tfi\n\n$(THE_MANUAL): %.pdf: %.tex\n\t-cd $$(dirname $*) && pdflatex $$(basename $*)\n\t-cd $$(dirname $*) && pdflatex $$(basename $*)\n\nTCL_PATH = tcl\n# command to find paths of script files, relative to TCL_PATH\nTCL_FILES = find $(srcdir)/$(TCL_PATH) -name '*.cfg' -o -name '*.tcl' -o -name '*.txt' | \\\n\t\tsed -e 's,^$(srcdir)/$(TCL_PATH),,'\n\ndist-hook:\n\tif test -d $(srcdir)/.git -a \\( ! -e $(distdir)/ChangeLog -o -w $(distdir)/ChangeLog \\) ; then \\\n\t\tgit --git-dir $(srcdir)/.git log | $(srcdir)/tools/git2cl/git2cl > $(distdir)/ChangeLog ; \\\n\tfi\n\tfor i in $$($(TCL_FILES)); do \\\n\t\tj=\"$(distdir)/$(TCL_PATH)/$$i\" && \\\n\t\tmkdir -p \"$$(dirname $$j)\" && \\\n\t\t$(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \\\n\tdone\n\ninstall-data-hook:\n\tfor i in $$($(TCL_FILES)); do \\\n\t\tj=\"$(DESTDIR)$(pkgdatadir)/scripts/$$i\" && \\\n\t\tmkdir -p \"$$(dirname $$j)\" && \\\n\t\t$(INSTALL_DATA) $(srcdir)/$(TCL_PATH)/$$i $$j; \\\n\tdone\n\nuninstall-hook:\n\trm -rf $(DESTDIR)$(pkgdatadir)/scripts\n\ndistclean-local:\n\trm -rf Doxyfile doxygen\n\t-rm -f $(srcdir)/jimtcl/configure.gnu\n\nDISTCLEANFILES += doxygen.log\n\nMETASOURCES = AUTO\n\nBUILT_SOURCES =\nCLEANFILES =\n\nMAINTAINERCLEANFILES = \\\n\t%D%/INSTALL \\\n\t%D%/configure \\\n\t%D%/Makefile.in \\\n\t%D%/depcomp \\\n\t%D%/config.guess \\\n\t%D%/config.sub \\\n\t%D%/config.h.in \\\n\t%D%/config.h.in~ \\\n\t%D%/compile \\\n\t%D%/ltmain.sh \\\n\t%D%/missing \\\n\t%D%/aclocal.m4 \\\n\t%D%/install-sh \\\n\t%D%/texinfo.tex\n\ninclude src/Makefile.am\ninclude doc/Makefile.am\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\nBoundary Scan:\n\nTarget Layer:\n\nFlash Layer:\n\nBoard, Target, and Interface Configuration Scripts:\n\nServer Layer:\n\nRTOS:\n\nDocumentation:\n\nBuild and Release:\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.x.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.10.0",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\t* New driver for J-Link adapters based on libjaylink\n          (including support for FPGA configuration, SWO and EMUCOM)\n\t* FTDI improvements to work at 30MHz clock\n\t* BCM2835 native driver SWD and Raspberry Pi2 support\n\t* BCM2835 is set to 4ma drive, slow slew rate\n\t* ixo-usb-jtag (emulation of an Altera Bus Blaster I on\n          Cypress FX2 IC) support\n\t* JTAG pass-through mode for CMSIS-DAP (including support for\n          FPGA configuration)\n\t* OpenJTAG support for Cypress CY7C65215\n\t* connect_assert_srst support for SWD\n\t* Xilinx Virtex-II Series7 bitstream loading support\n\t* Use JEP106 data to decode IDs\n\t* Deprecated \"ft2232\" driver removed (use \"ftdi\" instead)\n\t* GPL-incompatible FTDI D2XX library support dropped (Presto,\n          OpenJTAG and USB-Blaster I are using libftdi only now)\n\t* ZY1000 support dropped (unmaintained since long)\n\t* oocd_trace support dropped\n\nBoundary Scan:\n\nTarget Layer:\n\t* ARMv7-A, Cortex-M, Cortex-A/R important fixes and\n          improvements (allowing e.g. simultaneous debugging of A8 and\n          M3 cores, JTAG WAIT support etc.)\n\t* ARM Cortex-A,R allow interrupt disable during single-step\n          (maskisr command)\n\t* Semihosting support for ARMv7-A\n\t* ARM Cortex-M7 support\n\t* Intel Quark mcu D2000 support\n\t* Freescale LS102x SAP support\n\t* ThreadX RTOS support on ARM926E-JS\n\t* Cortex-M RTOS stack alignment fixes\n\t* FreeRTOS FPU support\n\t* uC/OS-III RTOS support\n\t* bridging semihosting to GDB's File-I/O support\n\t* -defer-examine option added to target create command\n\t* verify_image_checksum command added\n\nFlash Layer:\n\t* Atmel SAM4S, SAM4N, SAM4C support\n\t* Atmel SAMV, SAMS, SAME (Cortex-M7) support\n\t* Atmel AT91SAMD handle reset run/halt in DSU, other fixes\n\t* Atmel AT91SAML21, SAML22, SAMC20/SAMC21, SAMD09 support\n\t* ST STM32F4x support\n\t* ST STM32F74x/76x/77x, STM32L4 support\n\t* ST STM32L0 categories 1, 2 and 5 support\n\t* Kinetis K02, K21, K22, K24, K26, K63, K64, K66 support\n\t* Kinetis KE, KVx, K8x families support\n\t* Kinetis FlexNVM handling\n\t* Kinetis flash protection, security, mass_erase improvements\n\t* Infineon XMC4xxx family support\n\t* Infineon XMC1000 flash driver\n\t* Energy Micro EFM32 Happy Gecko support\n\t* Energy Micro EFM32 debug interface lock support\n\t* Analog Devices ADuCM360 support\n\t* Unified Nuvoton NuMicro flash driver\n\t* NIIET K1921VK01T (Cortex-M4) support\n\t* Nordic Semiconductor nRF51 improvements\n\t* Spansion FM4 flash (including MB9BFx64/x65, S6E2DH) driver\n\t* Ambiq Micro Apollo flash driver\n\t* PIC32MX new device IDs, 17x/27x flash support\n\t* read_bank() and verify_bank() NOR flash internal API to\n          allow reading (and verifying) non-memory-mapped devices\n\t* JTAGSPI driver to access SPI NOR flashes via a trivial\n          FPGA proxy\n\t* Milandr read/verify for Info memory support\n\t* Various discrete SPI NOR flashes support\n\t* CFI 16-bit flash reversed endianness support\n\nBoard, Target, and Interface Configuration Scripts:\n\t* Digilent JTAG-HS2, JTAG-HS3 interfaces configs\n\t* FTDI UM232H module as JTAG interface config\n\t* 100ask's OpenJTAG interface config\n\t* MBFTDI interface config\n\t* XDS100v3 interface config\n\t* Freescale Vybrid VF6xx target config\n\t* EmCraft VF6 SOM and baseboard configs\n\t* Freescale SabreSD board config\n\t* Freescale VF65GS10 tower board config\n\t* Pipistrello Xilinx Spartan6 LX45 FPGA board config\n\t* miniSpartan6+ board config\n\t* Xilinx Kintex7 Development board config\n\t* Parallella-I board config\n\t* Digilent Atlys and Analog Discovery board configs\n\t* Numato Opsis board config\n\t* Xilinx Spartan 6 FPGA \"Device DNA\" reading support\n\t* Altera 10M50 FPGA (MAX10 family) target config\n\t* Altera EPM240 CPLD (MAXII family) target config\n\t* Marsohod2, Marsohod3 FPGA, Marsohod CPLD boards configs\n\t* Novena's integrated FPGA board config\n\t* XMOS XS1-XAU8A-10's ARM core config\n\t* XMOS xCORE-XA Core Module board config\n\t* Exynos5250 target config\n\t* Arndale board config\n\t* FM4 MB9BFxxx family configs\n\t* Spansion SK-FM4-U120-9B560 board config\n\t* Diolan LPC4357-DB1 board config\n\t* ST STM32F469 discovery board config\n\t* ST STM32F7-DISCO, STM327[4|5]6G-EVAL boards configs\n\t* ST STM32L4 discovery, NUCLEO L476RG, STM32F429I-DISC1 boards\n          configs\n\t* Atheros AR2313, AR2315 targets config\n\t* Netgear WP102 board config\n\t* La Fonera FON2200 board config\n\t* Linksys WAG200G board config\n\t* LPC-Link2 board config\n\t* NXP LPC4370 target config\n\t* Atmel SAMV, SAMS, SAME target configs\n\t* Atmel SAM E70 Xplained, SAM V71 Xplained Ultra boards\n          configs\n\t* Nordic nRF52 target config\n\t* Nordic nRF51-DK, nRF52-DK boards configs\n\t* Infineon XMC4700 Relax Kit, XMC4800 Relax EtherCAT Kit,\n          XMC4300 Relax EtherCAT Kit boards configs\n\t* Renesas S7G2 target config\n\t* Renesas DK-S7G2 board config\n\t* Altera EP3C10 FPGA (Cyclone III family) target config\n\t* TI MSP432P4xx target config\n\t* Cypress PSoC 5LP target config\n\t* Analog Devices ADSP-SC58x target config (Cortex-A5 core only)\n\nServer Layer:\n\t* tcl_trace command for async target trace output via Tcl RPC\n\nDocumentation:\n\nBuild and Release:\n\t* Various fixes thanks to http://coccinellery.org/\n\t* libftdi is now autodetected with pkgconfig\n\t* Releases should now support reproducible builds\n\t* Conversion to non-recursive make, requires automake >= 1.14\n\t* Udev rules modified to add uaccess tag and moved to\n          60-openocd.rules\n\t* Support searching for scripts relative to the openocd binary\n          for all major architectures\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.10.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.11.0",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\t* add debug level 4 for verbose I/O debug\n\t* bitbang, add read buffer to improve performance\n\t* Cadence SystemVerilog Direct Programming Interface (DPI) adapter driver\n\t* CMSIS-DAP v2 (USB bulk based) adapter driver\n\t* Cypress KitProg adapter driver\n\t* FTDI FT232R sync bitbang adapter driver\n\t* Linux GPIOD bitbang adapter driver through libgpiod\n\t* Mellanox rshim USB or PCIe adapter driver\n\t* Nuvoton Nu-Link and Nu-Link2 adapter drivers\n\t* NXP IMX GPIO mmap based adapter driver\n\t* ST-Link consolidate all versions in single config\n\t* ST-Link read properly old USB serial numbers\n\t* STLink/V3 support (for ST devices only !)\n\t* STM8 SWIM transport\n\t* TI XDS110 adapter driver\n\t* Xilinx XVC/PCIe adapter driver\n\nBoundary Scan:\n\nTarget Layer:\n\t* 64 bit address support\n\t* ARCv2 target support\n\t* ARM Cortex-A hypervisor mode support\n\t* ARM Cortex-M fast PC sampling support for profiling\n\t* ARM generic CTI support\n\t* ARM generic mem-ap target support\n\t* ARMv7-A MMU tools\n\t* ARMv7m traces add TCP stream server\n\t* ARMv8 AARCH64 target support and semihosting support\n\t* ARMv8 AARCH64 disassembler support through capstone library\n\t* ARMv8-M target support\n\t* EnSilica eSi-RISC target support, including instruction tracing\n          eSi-Trace support\n\t* MIPS64 target support\n\t* Motorola SREC S6 record image file support\n\t* RISC-V target support\n\t* SEGGER Real Time Transfer (RTT) initial support (for single target,\n\t  Cortex-M only)\n\t* ST STM8 target support\n\t* Various MIPS32 target improvements\n\nFlash Layer:\n\t* Atheros (ath79) SPI interface support\n\t* Atmel atmega128rfa1 support\n\t* Atmel SAM D21, D51, DA1, E51, E53, E54, G55, R30 support\n\t* Atmel SAMC2?N* support\n\t* Cypress PSoC5LP, PSoC6 support\n\t* EnSilica eSi-RISC support\n\t* Foshan Synwit Tech SWM050 support\n\t* Maxim Integrated MAX32XXX support\n\t* Nordic Semiconductor nRF51822, nRF52810, nRF52832 support\n\t* NXP Kinetis K27, K28, KE1x, KEAx, KL28, KL8x, KV5x, KWx support\n\t* Renesas RPC HF support\n\t* SH QSPI support\n\t* SiFive Freedom E support\n\t* Silicon Labs EFR-family, EZR32HG support\n\t* ST BlueNRG support\n\t* ST STM32 QUAD/OCTO-SPI interface support for Flash, FRAM and EEPROM\n\t* ST STM32F72x, STM32F4x3, STM32H7xx support\n\t* ST STM32G0xx, STM32G4xx, STM32L4x, STM32WB, STM32WL support\n\t* ST STM32L5x support (non secure mode)\n\t* TI CC13xx, CC26xx, CC32xx support\n\t* TI MSP432 support\n\t* Winner Micro w600 support\n\t* Xilinx XCF platform support\n\t* Various discrete SPI NOR flashes support\n\nBoard, Target, and Interface Configuration Scripts:\n\t* 8devices LIMA board config\n\t* Achilles Instant-Development Kit Arria 10 board config\n\t* Amazon Kindle 2 and DX board config\n\t* Analog Devices ADSP-SC58x, ADSP-SC584-EZBRD board config\n\t* Andes Technology ADP-XC7KFF676 board config\n\t* Andes Technology Corvette-F1 board config\n\t* ARM Musca A board config\n\t* Arty Spartan 7 FPGA board config\n\t* Atmel SAMD10 Xplained mini board config\n\t* Atmel SAMD11 Xplained Pro board config\n\t* Atmel SAM G55 Xplained Pro board config\n\t* AVNET UltraZED EG StarterKit board config\n\t* Blue Pill STM32F103C8 board config\n\t* DP Busblaster v4.1a board config\n\t* DPTechnics DPT-Board-v1 board config\n\t* Emcraft imx8 SOM BSB board config\n\t* Globalscale ESPRESSObin board config\n\t* Kasli board config\n\t* Kintex Ultrascale XCKU040 board config\n\t* Knovative KC-100 board config\n\t* LeMaker HiKey board config\n\t* Microchip (Atmel) SAME54 Xplained Pro board config\n\t* Microchip (Atmel) SAML11 Xplained Pro board config\n\t* Nordic module NRF52 board config\n\t* Numato Lab Mimas A7 board config\n\t* NXP Freedom FRDM-LS1012A board config\n\t* NXP IMX7SABRE board config\n\t* NXP IMX8MP-EVK board config\n\t* NXP MC-IMX8M-EVK board config\n\t* QuickLogic QuickFeather board config\n\t* Renesas R-Car E2, H2, M2 board config\n\t* Renesas R-Car Salvator-X(S) board config\n\t* Renesas RZ/A1H GR-Peach board config\n\t* Rigado BMD-300 board config\n\t* Sayma AMC board config\n\t* Sifive e31arty, e51arty, hifive1 board config\n\t* ST B-L475E-IOT01A board config\n\t* ST BlueNRG idb007v1, idb008v1, idb011v1 board config\n\t* ST STM32F412g discovery board config\n\t* ST STM32F413h discovery board config\n\t* ST STM32F469i discovery board config\n\t* ST STM32F7 Nucleo board config\n\t* ST STM32F723e discovery board config\n\t* ST STM32F746g discovery board config\n\t* ST STM32F769i discovery board config\n\t* ST STM32H735g discovery board config\n\t* ST STM32H743zi Nucleo board config\n\t* ST STM32H745i discovery board config\n\t* ST STM32H747i discovery board config\n\t* ST STM32H750b discovery board config\n\t* ST STM32H7b3i discovery board config\n\t* ST STM32H7x_dual_qspi board config\n\t* ST STM32H7x3i Eval boards config\n\t* ST STM32L073 Nucleo board config\n\t* ST STM32L476g discovery board config\n\t* ST STM32L496g discovery board config\n\t* ST STM32L4p5g discovery board config\n\t* ST STM32L4r9i discovery board config\n\t* ST STM32L5 Nucleo board config\n\t* ST STM32MP15x DK2 board config\n\t* ST STM32WB Nucleo board config\n\t* ST STM8L152R8 Nucleo board config\n\t* Synopsys DesignWare ARC EM board config\n\t* Synopsys DesignWare ARC HSDK board config\n\t* TI BeagleBone family boards config\n\t* TI CC13xx, CC26xx, CC32xx LaunchPad board config\n\t* TI MSP432 LaunchPad board config\n\t* Tocoding Poplar board config\n\t* TP-Link WDR4300 board config\n\t* Allwinner V3s target config\n\t* Andes Technology NDS V5 target config\n\t* Atmel atmega128rfa1 target config\n\t* ARM corelink SSE-200 target config\n\t* Atheros_ar9344 target config\n\t* Cypress PSoC5LP, PSoC6 target config\n\t* EnSilica eSi-RISC target config\n\t* Foshan Synwit Tech SWM050 target config\n\t* GigaDevice GD32VF103 target config\n\t* Hisilicon Hi3798 target config\n\t* Hisilicon Hi6220 target config\n\t* Infineon TLE987x target config\n\t* Marvell Armada 3700 target config\n\t* Maxim Integrated MAX32XXX target config\n\t* Mellanox BlueField target config\n\t* Microchip (Atmel) SAME5x, SAML1x target config\n\t* NXP IMX6SX, IMX6UL, IMX7, IMX7ULP, IMX8 target config\n\t* NXP Kinetis KE1xZ, KE1xF target config\n\t* NXP LPC84x, LPC8Nxx, LS1012A, NHS31xx target config\n\t* Qualcomm QCA4531 target config\n\t* QuickLogic EOS S3 target config\n\t* Renesas R-Car E2, H2, M2 target config\n\t* Renesas R-Car Gen3 target config\n\t* Renesas RZ/A1H target config\n\t* Rockchip RK3308 target config\n\t* ST BlueNRG target config\n\t* ST STM32G0, STM32G4, STM32H7, STM32L0, STM32L5 target config\n\t* ST STM32MP15x target config\n\t* ST STM32WBx, STM32WLEx target config\n\t* ST STM8L152, S003, S103, S105 target config\n\t* Synopsys DesignWare ARC EM target config\n\t* Synopsys DesignWare ARC HS Development Kit SoC target config\n\t* TI CC13xx, CC26xx, CC32xx target config\n\t* TI TNETC4401 target config\n\t* Xilinx UltraScale+ target config\n\t* Altera 5M570Z (MAXV family) CPLD config\n\t* Xilinx Ultrascale, XCF CPLD config\n\t* Intel (Altera) Arria10 FPGA config\n\t* Cadence SystemVerilog Direct Programming Interface (DPI) interface config\n\t* Cypress KitProg interface config\n\t* Digilent SMT2 NC interface config\n\t* DLN-2 example of Linux GPIOD interface config\n\t* FTDI C232HM interface config\n\t* HIE JTAG Debugger interface config\n\t* In-Circuit's ICprog interface config\n\t* isodebug isolated JTAG/SWD+UART interface config\n\t* Mellanox rshim USB or PCIe interface config\n\t* Nuvoton Nu-Link interface config\n\t* NXP IMX GPIO mmap based interface config\n\t* Steppenprobe open hardware interface config\n\t* TI XDS110 interface config\n\nServer Layer:\n\t* 64 bit address support\n\t* default bind to IPv4 localhost\n\t* gdb: allow multiple connections\n\t* gdb: architecture element support\n\t* gdb: vCont, vRun support\n\t* telnet: handle Ctrl+A, Ctrl+E and Ctrl+K\n\nRTOS:\n\t* Chromium-EC rtos support\n\t* hwthread pseudo rtos support\n\t* NuttX rtos support\n\t* RIOT rtos support\n\nDocumentation:\n\t* Improve STM32 flash driver\n\t* Various typo fix and improvements\n\nBuild and Release:\n\t* Add libutil to support jimtcl version 0.80\n\t* Clang warning fixes\n\t* GitHub workflow for Win32 snapshot binaries\n\t* Handle Tcl return values consistently\n\t* Mitigation for CVE-2018-5704: Prevent some forms of Cross\n          Protocol Scripting attacks\n\t* Support for libftdi 1.5\n\t* Travis-CI basic support\n\t* Update libjaylink to version 0.2.0\n\t* Update jimtcl to version 0.79\n\t* Use external (optional) library capstone for ARM and AARCH64 disassembly\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.11.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.12.0",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\t* add default to adapter speed when unspecified (100 kHz)\n\t* AM335X gpio (BeagleBones) adapter driver\n\t* BCM2835 support for SWD\n\t* Cadence Virtual Debug (vdebug) adapter driver\n\t* CMSIS-DAP support for SWO and SWD multidrop\n\t* Espressif USB JTAG Programmer adapter driver\n\t* Remote bitbang support for Windows host\n\t* ST-LINK add TCP server support to adapter driver\n\t* SWD multidrop support\n\nBoundary Scan:\n\nTarget Layer:\n\t* aarch64: support watchpoints\n\t* arm: support independent TPIU and SWO for trace\n\t* arm adi v5: support Large Physical Address Extension\n\t* arm adi v6: support added, for jtag and swd transport\n\t* cortex_a: support watchpoints\n\t* elf 64bit load support\n\t* Espressif: support ESP32, ESP32-S2 and ESP32-S3 cores\n\t* semihosting: support user defined operations\n\t* Xtensa: support Xtensa LX architecture via JTAG and ADIv5 DAP\n\nFlash Layer:\n\t* Atmel/Microchip SAM E51G18A, E51G19A, R35J18B, LAN9255 support\n\t* GigaDevice GD32E23x, GD32F1x0/3x0, GD32VF103 support\n\t* Nuvoton NPCX series support\n\t* onsemi RSL10 support\n\t* Raspberry Pi Pico RP2040 support\n\t* ST BlueNRG-LPS support\n\t* ST STM32 G05x, G06x, G0Bx, G0Cx, U57x, U58x, WB1x, WL5x support\n\t* ST STM32 G0, G4, L4, L4+, L5, WB, WL OTP support\n\nBoard, Target, and Interface Configuration Scripts:\n\t* Ampere Computing eMAG8180, Altra (\"Quicksilver\") and Altra Max (\"Mystique\") board config\n\t* Cadence KC705 FPGA (Xtensa Development Platform) via JTAG and ADIv5 DAP board config\n\t* Digilent Nexys Video board config\n\t* Espressif ESP32 ETHERNET-KIT and WROVER-KIT board config\n\t* Espressif ESP32 via ESP USB Bridge generic board config\n\t* Espressif ESP32-S2 Kaluga 1 board config\n\t* Espressif ESP32-S2 with ESP USB Bridge board config\n\t* Espressif ESP32-S3 example board config\n\t* Kontron SMARC-sAL28 board config\n\t* LambdaConcept ECPIX-5 board config\n\t* Microchip ATSAMA5D27-SOM1-EK1 board config\n\t* Microchip EVB-LAN9255 board config\n\t* Microchip SAME51 Curiosity Nano board config\n\t* NXP FRDM-K64F, LS1046ARDB and LS1088ARDB board config\n\t* NXP RT6XX board config\n\t* Olimex H405 board config\n\t* Radiona ULX3S board config\n\t* Raspberry Pi 3 and Raspberry Pi 4 model B board config\n\t* Raspberry Pi Pico-Debug board config\n\t* Renesas R-Car V3U Falcon board config\n\t* ST BlueNRG-LPS steval-idb012v1 board config\n\t* ST NUCLEO-8S208RB board config\n\t* ST NUCLEO-G031K8, NUCLEO-G070RB, NUCLEO-G071RB board config\n\t* ST NUCLEO-G431KB, NUCLEO-G431RB, NUCLEO-G474RE board config\n\t* ST STM32MP13x-DK board config\n\t* TI AM625 EVM, AM642 EVM and AM654 EVM board config\n\t* TI J721E EVM, J721S2 EVM and J7200 EVM board config\n\t* Ampere Computing eMAG, Altra (\"Quicksilver\") and Altra Max (\"Mystique\") target config\n\t* Cadence Xtensa generic and Xtensa VDebug target config\n\t* Broadcom BCM2711, BCM2835, BCM2836 and BCM2837 target config\n\t* Espressif ESP32, ESP32-S2 and ESP32-S3 target config\n\t* Microchip ATSAMA5D2 series target config\n\t* NanoXplore NG-Ultra SoC target config\n\t* NXP IMX8QM target config\n\t* NXP LS1028A, LS1046A and LS1088A target config\n\t* NXP RT600 (Xtensa HiFi DSP) target config\n\t* onsemi RSL10 target config\n\t* Raspberry Pi Pico RP2040 target config\n\t* Renesas R8A779A0 V3U target config\n\t* Renesas RZ/Five target config\n\t* Renesas RZ/G2 MPU family target config\n\t* Rockchip RK3399 target config\n\t* ST BlueNRG-LPS target config\n\t* ST STM32MP13x target config\n\t* TI AM625, AM654, J721E and J721S2 target config\n\t* Ashling Opella-LD interface config\n\t* Aspeed AST2600 linuxgpiod based interface config\n\t* Blinkinlabs JTAG_Hat interface config\n\t* Cadence Virtual Debug (vdebug) interface config\n\t* Espressif ESP32-S2 Kaluga 1 board's interface config\n\t* Espressif USB Bridge jtag interface config\n\t* Infineon DAP miniWiggler V3 interface config\n\t* PLS SPC5 interface config\n\t* Tigard interface config\n\t* Lattice MachXO3 family FPGA config\n\nServer Layer:\n\t* GDB: add per-target remote protocol extensions\n\t* GDB: more 'Z' packets support\n\t* IPDBG JtagHost server functionality\n\t* semihosting: I/O redirection to TCP server\n\t* telnet: support for command's autocomplete\n\nRTOS:\n\t* 'none' rtos support\n\t* Zephyr rtos support\n\nDocumentation:\n\nBuild and Release:\n\t* Add json extension to jimtcl build\n\t* Drop dependency from libusb0\n\t* Drop repository repo.or.cz for submodules\n\t* Move gerrit to https://review.openocd.org/\n\t* Require autoconf 2.69 or newer\n\t* Update jep106 to revision JEP106BF.01\n\t* Update jimtcl to version 0.81\n\t* Update libjaylink to version 0.3.1\n\t* New configure flag '--enable-jimtcl-maintainer' for jimtcl build\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.12.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.2.0",
    "content": "The OpenOCD 0.2.0 source archive release includes numerous improvements\nthat were made since the initial 0.1.0 source archive release.  Many\ncontributors helped make this release a great success, and the community\nof developers and maintainers look forward to any response.\n\nIn addition to the list of changes below, countless bug fixing and\ncleaning was performed across the tree.  Various TCL command parameters\nmust past stricter value checks, and many more error conditions have\nbeen handled correctly.  These efforts helped to make the 0.2.0 release\nmore stable and robust, though some changes may expose latent bugs in\nyour existing configuration scripts.\n\nThis release does not maintain backward compatibility in all respects,\nso some target or configuration scripts may need to be updated.  In some\ncases, you may also see warnings; resolve those, because they indicate\ncommands that will be removed in the future.\n\nThe following areas of OpenOCD functionality changed in this release:\n\nJTAG Layer:\n- Improves modularity: core, TCL, driver commands, and interface have\n  been separated, encapsulated, and documented for developers.  Mostly.\n- Improves JTAG TAP transition tables:\n   * Makes TAP paths variable length, rather than being fixed at 7 steps.\n   * Fixes problems with some targets that did not like longer paths.\n- Improves JTAG driver/minidriver modularity and encapsulation.\n- New drivers:\n   * Adds stub minidriver for developing new embedded JTAG interfaces.\n- Improves drivers:\n   * ft2232+ftd2xx:\n      + Adds initial high-speed device support: --enable-ftd2xx-highspeed\n      + Supports more types of FTDI-based devices.\n   * jlink:\n      + Works with more versions of the firmware (v3 and newer)\n      + Supports dynamically detects device capabilities and limits\n   * vsllink:\n      + Supports very long scan chains\n   * amtjtagaccel:\n      + Fixes broken ID code detection problems.\n\nTarget Layer:\n- New devices: AVR, FA526\n- Improved support: ARM ADI, ARM11, MIPS\n- Numerous other bug fixes and improvements\n\nFlash Layer:\n- Improved drivers: mflash\n- New drivers: AT91SAM3, AVR, Davinci NAND\n\nBoard, Interface, and Target Configuration Scripts:\n- Many new and improved targets and boards are now available.\n- Better separation of \"board\" and \"target\" configuration\n- Moved all TCL files to top-level \"tcl\" directory in the source tree\n- Installation moved from '$pkglibdir/' to '$pkgdatadir/scripts/'.\n- Site-specific files should be installed under '$pkgdatadir/site/';\n  files that exist this tree will be used in preference to default\n  distribution configurations in '$pkgdatadir/scripts/'.\n\nDocumentation:\n- Updated User Guide:     http://openocd.berlios.de/doc/html/index.html\n   * Partially re-written and re-organized.\n   * Standardized presentation for all commands.\n   * Covers many drivers and commands that were previously omitted.\n   * New index for commands and drivers.\n- Added Developer Manual: http://openocd.berlios.de/doc/doxygen/index.html\n   * Now includes architecture, technical primers, style guides, and more.\n   * Available in-tree and on-line.\n\nBuild and Release:\n- Increased configuration and compilation warning coverage.\n   * Use --disable-werror to work around build errors caused by warnings.\n- Use libtool to produce helper libraries as a step toward \"libopenocd\".\n- New processes and scripting to facilitate future source releases.\n\nFor more details about what has changed since 0.1.0, see the ChangeLog\nassociated with this release.\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.3.0",
    "content": "This file should include highlights of the changes made in the\nOpenOCD openocd-0.3.0 source archive release.  See the repository\nhistory for details about what changed, including bugfixes and\nother issues not mentioned here.\n\nJTAG Layer:\n    FT2232H (high speed USB) support doesn't need separate configuration\n    New FT2232H JTAG adapters:  Amontec, Olimex, Signalyzer\n    New reset_config options for SRST gating the JTAG clock (or not)\n    TAP declaration no longer requires ircapture and mask attributes\n    Scan chain setup should be more robust, with better diagnostics\n    New TAP events:\n\t\"post-reset\" for TAP-invariant setup code (TAPs not usable yet)\n\t\"setup\" for use once TAPs are addressable (e.g. with ICEpick)\n    Overridable Tcl \"init_reset\" and \"jtag_init\" procedures\n    Simple \"autoprobe\" mechanism to help simplify server setup\n\nBoundary Scan:\n    SVF bugfixes ... parsing fixes, better STATE switch conformance\n    XSVF bugfixes ... be more correct, handle Xilinx tool output\n\nTarget Layer:\n    Warn on use of obsolete numeric target IDs\n    New commands for use with Cortex-M3 processors:\n\t\"cortex_m3 disassemble\" ... Thumb2 disassembly (UAL format)\n\t\"cortex_m3 vector_catch\" ... traps certain hardware faults\n\t\twithout tying up breakpoint resources\n    If you're willing to help debug it\n\tVERY EARLY Cortex-A8 and ARMv7A support\n\tUpdated BeagleBoard.org hardware support\n\tyou may need to explicitly \"reset\" after connect-to-Beagle\n    New commands for use with XScale processors: \"xscale vector_table\"\n    ARM\n\tbugfixes to single-stepping Thumb code\n\tETM: unavailable registers are not listed\n\tETB, ETM: report actual hardware status\n    ARM9\n\tname change:  \"arm9 vector_catch\" not \"arm9tdmi vector_catch\"\n    ARM11\n\tsingle stepping support for i.MX31\n\tbugfix for missing \"arm11\" prefix on \"arm11 memwrite ...\"\n    GDB support\n\tgdb_attach command is gone\n\nFlash Layer:\n    The lpc2000 driver handles the new NXP LPC1700 (Cortex-M3) chips\n    New drivers:\n\tlpc2900, for NXP LPC2900 chips (ARM968 based)\n\tmx3_nand, for imx31\n    New \"last\" flag for NOR \"flash erase_sector\" and \"flash protect\"\n    The \"nand erase N\" command now erases all of bank N\n    Speed up davinci_nand by about 3x\n\nBoard, Target, and Interface Configuration Scripts:\n    Amontec JTAGkey2 support\n    Cleanup and additions for the TI/Luminary Stellaris scripts\n    LPC1768 target (and flash) support\n\tKeil MCB1700 eval board\n    Samsung s3c2450\n\tMini2440 board\n    Numeric TAP and Target identifiers now trigger warnings\n    PXA255 partially enumerates\n\nDocumentation:\n    Capture more debugging and setup advice\n    Notes on target source code changes that may help debugging\n\nBuild and Release:\n    Repository moved from SVN at Berlios to GIT at SourceForge\n    Clean builds on (32-bit) Cygwin\n    Clean builds on 64-bit MinGW\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.4.0",
    "content": "This file includes highlights of the changes made in the\nOpenOCD 0.4.0 source archive release.  See the repository\nhistory for details about what changed, including bugfixes\nand other issues not mentioned here.\n\nJTAG Layer:\n\tSupport KT-Link JTAG adapter.\n\tSupport USB-JTAG, Altera USB-Blaster and compatibles.\n\nBoundary Scan:\n\nTarget Layer:\n\tGeneral\n\t\t- Removed commands which have been obsolete for at least\n\t\t  a year (from both documentation and, sometimes, code).\n\t\t- new \"reset-assert\" event, for systems without SRST\n\tARM\n\t\t- supports \"reset-assert\" event (except on Cortex-M3)\n\t\t- renamed \"armv4_5\" command prefix as \"arm\"\n\t\t- recognize TrustZone \"Secure Monitor\" mode\n\t\t- \"arm regs\" command output changed\n\t\t- register names use \"sp\" not \"r13\"\n\t\t- add top-level \"mcr\" and \"mrc\" commands, replacing\n\t\t  various core-specific operations\n\t\t- basic semihosting support (ARM7/ARM9 only, for now)\n\tARM11\n\t\t- Should act much more like other ARM cores:\n\t\t   * Preliminary ETM and ETB hookup\n\t\t   * accelerated \"flash erase_check\"\n\t\t   * accelerated GDB memory checksum\n\t\t   * support \"arm regs\" command\n\t\t   * can access all core modes and registers\n\t\t   * watchpoint support\n\t\t- Shares some core debug code with Cortex-A8\n\tCortex-A8\n\t\t- Should act much more like other ARM cores:\n\t\t   * support \"arm regs\" command\n\t\t   * can access all core modes and registers\n\t\t   * watchpoint support\n\t\t- Shares some core debug code with ARM11\n\tCortex-M3\n\t\t- Exposed DWT registers like cycle counter\n\t\t- vector_catch settings not clobbered by resets\n\t\t- no longer interferes with firmware's fault handling\n\tETM, ETB\n\t\t- \"trigger_percent\" command moved ETM --> ETB\n\t\t- \"etm trigger_debug\" command added\n\tMIPS\n\t\t- use fastdata writes\n\tFreescale DSP563xx cores (partial support)\n\nFlash Layer:\n\t'flash bank' and 'nand device' take <bank_name> as first argument.\n\tWith this, flash/NAND commands allow referencing banks by name:\n\t\t- <bank_name>: reference the bank with its defined name\n\t\t- <driver_name>[.N]: reference the driver's Nth bank\n\tNew 'nand verify' command to check bank against an image file.\n\tThe \"flash erase_address\" command now rejects partial sectors;\n\t\tpreviously it would silently erase extra data.  If you\n\t\twant to erase the rest of the first and/or last sectors\n\t\tinstead of failing, you must pass an explicit \"pad\" flag.\n\tNew at91sam9 NAND controller driver.\n\tNew s3c64xx NAND controller driver.\n\nBoard, Target, and Interface Configuration Scripts:\n\tARM9\n\t\t- ETM and ETB hookup for iMX2* targets\n\tAdd $HOME/.openocd to the search path.\n\tHandle Rev C of LM3S811 eval boards.\n\t\t- use \"luminary-lm3s811.cfg\" for older boards\n\t\t- use \"luminary.cfg\" for RevC and newer\n\nCore Jim/TCL Scripting:\n\tNew 'usage' command to provide terse command help.\n\tImproved command 'help' command output (sorted and indented).\n\tImproved command handling:\n\t\t- Most boolean settings now accept any of the following:\n\t\t  on/off, enable/disable, true/false, yes/no, 1/0\n\t\t- More error checking and reporting.\n\nDocumentation:\n\tNew built-in command development documentation and primer.\n\nBuild and Release:\n\tUse --enable-doxygen-pdf to build PDF developer documentation.\n\tConsider upgrading to libftdi 0.17 if you use that library; it\n\t\tincludes bugfixes which improve FT2232H support.\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.5.0",
    "content": "This file includes highlights of the changes made in the\nOpenOCD 0.5.0 source archive release.  See the repository\nhistory for details about what changed, including bugfixes\nand other issues not mentioned here.\n\nJTAG Layer:\n\tNew driver for \"Bus Pirate\"\n\tRename various commands so they're not JTAG-specific\n\t   There are migration procedures for most of these, but you should\n\t   convert your scripts to the new names, since those procedures\n\t   will not be around forever.\n\t\tjtag jinterface ... is now adapter_name\n\t   \tjtag_khz\t... is now adapter_khz\n\t\tjtag_nsrst_delay ... is now adapter_nsrst_delay\n\t\tjtag_nsrst_assert_width ... is now adapter_nsrst_assert_width\n\tSupport Voipac VPACLink JTAG Adapter.\n\nBoundary Scan:\n\nTransport framework core ... supporting future work for SWD, SPI, and other\nnon-JTAG ways to debug targets or program flash.\n\nTarget Layer:\n\tARM:\n\t\t- basic semihosting support for ARMv7M.\n\t\t- renamed \"armv7m\" command prefix as \"arm\"\n\tMIPS:\n\t\t- \"ejtag_srst\" variant removed. The same functionality is\n\t\t  obtained by using \"reset_config none\".\n\t\t- added PIC32MX software reset support, this means srst is not\n\t\t  required to be connected anymore.\n\tOTHER:\n\t\t- preliminary AVR32 AP7000 support.\n\nFlash Layer:\n\tNew \"stellaris recover\" command, implements the procedure\n\t\tto recover locked devices (restoring non-volatile\n\t\tstate to the factory defaults, including erasing\n\t\tthe flash and its protection bits, and possibly\n\t\tre-enabling hardware debugging).\n\tPIC32MX now uses algorithm for flash programming, this\n\t\thas increased the performance by approx 96%.\n\tNew 'pic32mx unlock' cmd to remove readout protection.\n\tNew STM32 Value Line Support.\n\tNew 'virtual' flash driver, used to associate other addresses\n\t\twith a flash bank. See pic32mx.cfg for usage.\n\tNew iMX27 NAND flash controller driver.\n\nBoard, Target, and Interface Configuration Scripts:\n\tSupport IAR LPC1768 kickstart board (by Olimex)\n\tSupport Voipac PXA270/PXA270M module.\n\tNew $PARPORTADDR tcl variable used to change default\n\t\tparallel port address used.\n\tRemove lm3s811.cfg; use \"stellaris.cfg\" instead\n\nCore Jim/TCL Scripting:\n\tNew \"add_script_search_dir\" command, behaviour is the same\n\t\tas the \"-s\" cmd line option.\n\nDocumentation:\n\nBuild and Release:\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.6.0",
    "content": "This file includes highlights of the changes made in the\nOpenOCD  source archive release.  See the\nrepository history for details about what changed, including\nbugfixes and other issues not mentioned here.\n\nJTAG Layer:\n\tNew STLINK V1/V2 JTAG/SWD adapter support.\n\tNew OSJTAG adapter support.\n\tNew Tincantools Flyswatter2 support.\n\tImproved ULINK driver.\n\tImproved RLINK driver.\n\tSupport for adapters based on FT232H chips.\n\tNew experimental driver for FTDI based adapters, using libusb-1.0 in asynchronous mode.\n\nBoundary Scan:\n\nTarget Layer:\n\tNew Cortex-M0 support.\n\tNew Cortex-M4 support.\n\tImproved Working area algorithm.\n\tNew RTOS support. Currently linux, FreeRTOS, ThreadX and eCos.\n\tConnecting under reset to Cortex-Mx and MIPS chips.\n\nFlash Layer:\n\tNew SST39WF1601 support.\n\tNew EN29LV800BB support.\n\tNew async algorithm support for selected targets, stm32, stellaris and pic32.\n\tNew Atmel SAM3S, SAM3N support.\n\tNew ST STM32L support.\n\tNew Microchip PIC32MX1xx/2xx support.\n\tNew Freescale Kinetis K40 support.\n\nBoard, Target, and Interface Configuration Scripts:\n\tSupport Dangerous Prototypes Bus Blaster.\n\tSupport ST SPEAr Family.\n\tSupport Gumstix Verdex boards.\n\tSupport TI Beaglebone.\n\nDocumentation:\n\tImproved HACKING info for submitting patches.\n\tFixed numerous broken links.\n\nBuild and Release:\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.7.0",
    "content": "This file includes highlights of the changes made in the\nOpenOCD  source archive release.  See the\nrepository history for details about what changed, including\nbugfixes and other issues not mentioned here.\n\nJTAG Layer:\n\tNew TI ICDI adapter support.\n\tSupport Latest OSBDM firmware.\n\tImproved MIPS EJTAG Support.\n\nBoundary Scan:\n\nTarget Layer:\n\tNew ARMv7R and Cortex-R4 support.\n\tAdded ChibiOS/RT support.\n\nFlash Layer:\n\tNew NXP LPC1850 support.\n\tNew NXP LPC4300 support.\n\tNew NXP SPIFI support.\n\tNew Energy Micro EFM32 support.\n\tNew ST STM32W support.\n\tNew ST STM32f2 write protection and lock/unlock support.\n\tAbility to override STM32 flash bank size.\n\nBoard, Target, and Interface Configuration Scripts:\n\tSupport Freescale i.MX6 series targets.\n\nDocumentation:\n\tNew MIPS debugging info.\n\nBuild and Release:\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.8.0",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\t* New CMSIS-DAP driver\n\t* Andes AICE debug adapter support\n\t* New OpenJTAG driver\n\t* New BCM2835 (RaspberryPi) driver\n\t* JTAG VPI client driver (for OpenRISC Reference Platform SoC)\n\t* Xilinx BSCAN_* for OpenRISC support\n\t* ST-LINKv2-1 support\n\t* ST-LINKv2 SWO tracing support (UART emulation)\n\t* JLink-OB (onboard) support\n\t* Altera USB Blaster driver rewrite, initial Blaster II\n\t  support\n\t* ULINK driver ported to libusb-1.0, OpenULINK build fixes\n\t* Support up to 64 bit IR lengths\n\t* SVF playback (FPGA programming) fixes\n\t* \"ftdi\" interface driver got extensive testing and is now\n\t  recommended over the old ft2232 implementation\n\nBoundary Scan:\n\nTarget Layer:\n\t* New target: Andes nds32\n\t* New target: OpenRISC OR1K\n\t* New target: Intel Quark X10xx\n\t* MIPS EJTAG 1.5/2.0 support\n\t* MIPS speed improvements\n\t* Cortex-M, Cortex-A (MEM-AP, APB-AP) targets working with BE\n\t  hosts now\n\t* XScale vector_catch support, reset fixes\n\t* dsp563xx ad-hoc breakpoint/watchpoint support\n\t* RTOS support for embKernel\n\t* Target profiling improvements\n\t* Memory access functions testbench\n\nFlash Layer:\n\t* STM32 family sync with reference manuals, other bugfixes\n\t* STM32F401, STM32F07x support\n\t* Atmel SAM4L, SAMG5x support\n\t* at91sam3sd8{a,b}, at91sam3s8{a,b,c}, at91sam4s,\n\t  at91sam3n0{a,b,0a,0b} support, bugfixes\n\t* Atmel SAMD support\n\t* Milandr 1986ВЕ* support\n\t* Kinetis KL, K21 support\n\t* Nuvoton NuMicro MINI5{1,2,4} support\n\t* Nuvoton NUC910 series support\n\t* NXP LPC43xx, LPC2000 fixes\n\t* NXP LPC800, LPC810 support\n\t* More ATmega parts supported\n\t* Fujitsu MB9Ax family support\n\t* EFM32 Wonder Gecko family support\n\t* Nordic nRF51 support\n\nBoard, Target, and Interface Configuration Scripts:\n\t* STM32W108xx generic target config\n\t* STM32F429 discovery board config\n\t* STM32 Nucleo boards configs\n\t* DENX M53EVK board config\n\t* Altera Cyclone V SoC, SoCkit config\n\t* New TI Launchpads board configs\n\t* TI am43xx devices, AM437x GP EVM, AM438x ePOS EVM board\n\t  configs\n\t* Marvell Armada 370 family initial support\n\t* TI TMDX570LS31USB (TMS570, Cortex-R4) support scripts\n\t* Freescale FRDM-KL25Z, KL46Z board configs\n\t* Digilent Zedboard config\n\t* Asus RT-N16, Linksys WRT54GL, BT HomeHub board configs\n\t* Atmel Xplained initial support\n\t* Broadcom bcm28155_ap board config\n\t* TUMPA, TUMPA Lite interface configs\n\t* Digilent JTAG-SMT2 interface config\n\t* New RAM testing functions\n\t* Easy-to-use firmware recovery helpers targetting ordinary\n\t  users with common equipment\n\nServer Layer:\n\t* Auto-generation of GDB target description for ARMv7-M,\n\t  ARM4, nds32, OR1K, Quark\n\t* GDB File-I/O Remote Protocol extension support\n\t* Default GDB flashing events handlers to initialise and reset\n\t  the target automatically when \"load\" is used\n\nDocumentation:\n\t* Extensive README* changes\n\t* The official User's Guide was proofread\n\t* Example cross-build script\n\t* RTOS documentation improvements\n\t* Tcl RPC documentation and examples added\n\nBuild and Release:\n\t* *BSD, OS X, clang, ARM, windows build fixes\n\t* New pkg-config support changes the way libusb (and other\n\t  dependencies) are handled. Many adapter drivers are now\n\t  selected automatically during the configure stage.\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.8.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWS-0.9.0",
    "content": "This file includes highlights of the changes made in the OpenOCD\nsource archive release.\n\nJTAG Layer:\n\t* SWD support with FTDI, Versaloon, J-Link, sysfsgpio\n\t* CMSIS-DAP massive speed and stability improvements\n\t* Versaloon driver ported to libusb-1.0\n\t* STLink can reestablish communication with a target that was\n          disconnected or rebooted\n\t* STLink FAULT and WAIT SWD handling improved\n\t* New hla_serial command to distinguish between several HLA\n          adapters attached to a single machine\n\t* Serial number support for CMSIS-DAP and J-Link adapters\n\t* Support for more J-Link adapters\n\t* TAP autoprobing improvements\n\t* Big speedup for SVF playback with USB Blaster\n\nBoundary Scan:\n\nTarget Layer:\n\t* Stability improvements for targets that get disconnected or\n          rebooted during a debug session\n\t* MIPS speed and reliability improvements\n\t* MIPS 1.5/2.0 fixes\n\t* ARMv7-R improvements\n\t* Cortex-A improvements, A7, A15 MPCores support\n\t* FPU support for ARMv7-M (Cortex-M4F)\n\t* TPIU/ITM support (including SWO/SWV tracing), can be\n          captured with external tools or STLink\n\t* JTAG Serial Port (Advanced Debug System softcore) support\n\t* Profiling support for OpenRISC\n\t* ChibiOS/RT 3.0 support (with and without FPU)\n\t* FreeRTOS current versions support\n\t* Freescale MQX RTOS support\n\t* GDB target description support for MIPS\n\t* The last created target is auto-selected as the current\n\nFlash Layer:\n\t* nRF51 async loader to improve flashing performance and stability\n\t* Cypress PSoC 41xx/42xx and CCG1 families flash driver\n\t* Silabs SiM3 family flash driver\n\t* Marvell Wireless Microcontroller SPI flash driver\n\t* Kinetis mass erase (part unsecuring) implemented\n\t* lpcspifi stability fixes\n\t* STM32 family sync with reference manuals, L0 support, bugfixes\n\t* LPC2000 driver automatically determines part and flash size\n\t* NXP LPC11(x)xx, LPC13xx, LPC15xx, LPC8xx, LPC5410x, LPC407x support\n\t* Atmel SAMD, SAMR, SAML21 devices support\n\t* Atmel SAM4E16 support\n\t* ZeroGecko family support\n\t* TI Tiva C Blizzard and Snowflake families support\n\t* Nuvoton NuMicro M051 support\n\t* EZR32 support in EFM32 driver\n\nBoard, Target, and Interface Configuration Scripts:\n\t* Normal target configs can work with HLA (STLink, ICDI) adapters\n\t* STM32 discovery and Nucleo boards configs\n\t* Gumstix AeroCore board config\n\t* General Plus GP326XXXA target config\n\t* Micrel KS869x target config\n\t* ASUS RT-N66U board config\n\t* Atmel SAM4E-EK board config\n\t* Atmel AT91SAM4L proper reset handling implemented\n\t* TI OMAP/AM 3505, 3517 target configs\n\t* nRF51822-mKIT board config\n\t* RC Module К1879ХБ1Я target config\n\t* TI TMDX570LS20SUSB board config\n\t* TI TMS570 USB Kit board config\n\t* TI CC2538, CC26xx target configs\n\t* TI AM437x major config improvements, DDR support\n\t* TI AM437X IDK board config\n\t* TI SimpleLink Wi-Fi CC3200 LaunchPad configs\n\t* Silicon Labs EM357, EM358 target configs\n\t* Infineon XMC1000, XMC4000 family targets and boards configs\n\t* Atheros AR9331 target config\n\t* TP-LINK TL-MR3020 board config\n\t* Alphascale asm9260t target and eval kit configs\n\t* Olimex SAM7-LA2 (AT91SAM7A2) board config\n\t* EFM32 Gecko boards configs\n\t* Spansion FM4 target and SK-FM4-176L-S6E2CC board configs\n\t* LPC1xxx target configs were restructured\n\t* IoT-LAB debug adapter config\n\t* DP BusBlaster KT-Link compatible config\n\nServer Layer:\n\t* Polling period can be configured\n\t* \"shutdown\" command has an immediate effect\n\t* The \"program\" command doesn't lead to a shutdown by\n          default, use optional \"exit\" parameter for the old behaviour\n\t* Proper OS signal handling was implemented\n\t* Async target notifications for the Tcl RPC\n\nDocumentation:\n\nBuild and Release:\n\n\nThis release also contains a number of other important functional and\ncosmetic bugfixes. For more details about what has changed since the\nlast release, see the git repository history:\n\nhttp://sourceforge.net/p/openocd/code/ci/v0.9.0/log/?path=\n\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/NEWTAPS",
    "content": "Reporting Unknown JTAG TAP IDS\n------------------------------\n\nIf OpenOCD reports an UNKNOWN or Unexpected Tap ID please report it to\nthe development mailing list - However - keep reading.\n\nopenocd-devel@lists.sourceforge.net.\n\n========================================\n\nAbout \"UNEXPECTED\" tap ids.\n\n  Before reporting an \"UNEXPECTED TAP ID\" - take a closer look.\n  Perhaps you have your OpenOCD configured the wrong way, maybe you\n  have the tap configured the wrong way? Or something else is wrong.\n  (Remember: OpenOCD does not stop if the tap is not present)\n\n  This \"tap id check\" is there for a purpose.\n  The goal is to help get the *right* configuration.\n\nThe idea is this:\n\n  Every JTAG tap is suppose to have \"a unique 32bit tap id\" number.\n  They are suppose to be \"sort of unique\" but they are not.  There are\n  no guarantees.\n\nVersion Number Changes:\n\n  Sometimes, the tap ID only differs by VERSION number. If so - it's\n  not a big deal.  Please do report this information.  We'd like to\n  know about it.\n\n  For example\n\nError:  ERROR: Tap: s3c4510.cpu - Expected id: 0x3f0f0f0f, Got: 0x1f0f0f0f\nError:  ERROR: expected: mfg: 0x787, part: 0xf0f0, ver: 0x3\nError:  ERROR:      got: mfg: 0x787, part: 0xf0f0, ver: 0x1\n\n========================================\n\nUpdating the Tap ID number your self\n\n  Why do this? You just want the warning to go away.  And don't want\n  to update your version/instance of OpenOCD.\n\n  On simple systems, to fix this problem, in your \"openocd.cfg\" file,\n  override the tap id.  Depending on the tap, add one of these 3\n  commands:\n\n\tset CPUTAPID   newvalue\n  or\tset BSTAPID    newvalue\n  or\tset FLASHTAPID newvalue\n  or\tset ETMTAPID   newvalue\n\n  Where \"newvalue\" is the new value you are seeing.\n\n  On complex systems, (with many taps and chips) you probably have a\n  custom configuration file. Its is more complicated, you're going to\n  have to read through the configuration files\n\n========================================\n\nWhat to send:\n\nCut & paste the output of OpenOCD that pointed you at this file.\n\nPlease include the VERSION number of OpenOCD you are using.\n\nAnd please include the information below.\n\n========================================\n\nA) The JTAG TAP ID code.\n\nThis is always a 32bit hex number.\n\nExamples:\n    0x1f0f0f0f - is an old ARM7TDMI\n    0x3f0f0f0f - is a newer ARM7TDMI\n    0x3ba00477 - is an ARM Cortex-M3\n\nSome chips have multiple JTAG taps - be sure to list\neach one individually - ORDER is important!\n\n========================================\nB) The maker of the part\n\nExamples:\n    Xilinx, Atmel, ST Micro Systems, Freescale\n\n========================================\nC) The family of parts it belongs to\n\nExamples:\n   \"NXP LPC Series\"\n   \"Atmel SAM7 Series\"\n\n========================================\n\nD) The actual part number on the package\n\n   For example: \"S3C45101x01\"\n\n========================================\n\nE) What type of board it is.\n\nie: a \"commercial off the self eval board\" that one can purchase (as\nopposed to your private internal custom board)\n\nFor example: ST Micro systems has Eval boards, so does Analog Devices\n\nOr - if it is inside something \"hackers like to hack\" that information\nis helpful too.\n\nFor example: A consumer GPS unit or a cellphone\n\n========================================\n\n(F)   The maker of the board\n        ie: Olimex, LogicPD, Freescale(eval board)\n\n========================================\n\n(G)   Identifying information on the board.\n\n      Not good:   \"iar red ST eval board\"\n\n      Really good: \"IAR STR912-SK evaluation board\"\n\n========================================\n\n(H) Are there other interesting (JTAG) chips on the board?\n\n    ie: An FPGA or CPLD ...\n\n========================================\n\n(I) What target config files need updating?\n\n    In fact it's best if you submit a patch with those\n    updates.  Most of the other information listed here\n    is just to help create a good patch.\n\n========================================\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/README",
    "content": "Welcome to OpenOCD!\n===================\n\nOpenOCD provides on-chip programming and debugging support with a\nlayered architecture of JTAG interface and TAP support including:\n\n- (X)SVF playback to facilitate automated boundary scan and FPGA/CPLD\n  programming;\n- debug target support (e.g. ARM, MIPS): single-stepping,\n  breakpoints/watchpoints, gprof profiling, etc;\n- flash chip drivers (e.g. CFI, NAND, internal flash);\n- embedded TCL interpreter for easy scripting.\n\nSeveral network interfaces are available for interacting with OpenOCD:\ntelnet, TCL, and GDB. The GDB server enables OpenOCD to function as a\n\"remote target\" for source-level debugging of embedded systems using\nthe GNU GDB program (and the others who talk GDB protocol, e.g. IDA\nPro).\n\nThis README file contains an overview of the following topics:\n\n- quickstart instructions,\n- how to find and build more OpenOCD documentation,\n- list of the supported hardware,\n- the installation and build process,\n- packaging tips.\n\n\n============================\nQuickstart for the impatient\n============================\n\nIf you have a popular board then just start OpenOCD with its config,\ne.g.:\n\n  openocd -f board/stm32f4discovery.cfg\n\nIf you are connecting a particular adapter with some specific target,\nyou need to source both the jtag interface and the target configs,\ne.g.:\n\n  openocd -f interface/ftdi/jtagkey2.cfg -c \"transport select jtag\" \\\n          -f target/ti_calypso.cfg\n\n  openocd -f interface/stlink.cfg -c \"transport select hla_swd\" \\\n          -f target/stm32l0.cfg\n\nAfter OpenOCD startup, connect GDB with\n\n  (gdb) target extended-remote localhost:3333\n\n\n=====================\nOpenOCD Documentation\n=====================\n\nIn addition to the in-tree documentation, the latest manuals may be\nviewed online at the following URLs:\n\n  OpenOCD User's Guide:\n    http://openocd.org/doc/html/index.html\n\n  OpenOCD Developer's Manual:\n    http://openocd.org/doc/doxygen/html/index.html\n\nThese reflect the latest development versions, so the following section\nintroduces how to build the complete documentation from the package.\n\nFor more information, refer to these documents or contact the developers\nby subscribing to the OpenOCD developer mailing list:\n\n\topenocd-devel@lists.sourceforge.net\n\nBuilding the OpenOCD Documentation\n----------------------------------\n\nBy default the OpenOCD build process prepares documentation in the\n\"Info format\" and installs it the standard way, so that \"info openocd\"\ncan access it.\n\nAdditionally, the OpenOCD User's Guide can be produced in the\nfollowing different formats:\n\n  # If PDFVIEWER is set, this creates and views the PDF User Guide.\n  make pdf && ${PDFVIEWER} doc/openocd.pdf\n\n  # If HTMLVIEWER is set, this creates and views the HTML User Guide.\n  make html && ${HTMLVIEWER} doc/openocd.html/index.html\n\nThe OpenOCD Developer Manual contains information about the internal\narchitecture and other details about the code:\n\n  # NB! make sure doxygen is installed, type doxygen --version\n  make doxygen && ${HTMLVIEWER} doxygen/index.html\n\n\n==================\nSupported hardware\n==================\n\nJTAG adapters\n-------------\n\nAM335x, ARM-JTAG-EW, ARM-USB-OCD, ARM-USB-TINY, AT91RM9200, axm0432, BCM2835,\nBus Blaster, Buspirate, Cadence DPI, Cadence vdebug, Chameleon, CMSIS-DAP,\nCortino, Cypress KitProg, DENX, Digilent JTAG-SMT2, DLC 5, DLP-USB1232H,\nembedded projects, Espressif USB JTAG Programmer,\neStick, FlashLINK, FlossJTAG, Flyswatter, Flyswatter2,\nFTDI FT232R, Gateworks, Hoegl, ICDI, ICEBear, J-Link, JTAG VPI, JTAGkey,\nJTAGkey2, JTAG-lock-pick, KT-Link, Linux GPIOD, Lisa/L, LPC1768-Stick,\nMellanox rshim, MiniModule, NGX, Nuvoton Nu-Link, Nu-Link2, NXHX, NXP IMX GPIO,\nOOCDLink, Opendous, OpenJTAG, Openmoko, OpenRD, OSBDM, Presto, Redbee,\nRemote Bitbang, RLink, SheevaPlug devkit, Stellaris evkits,\nST-LINK (SWO tracing supported), STM32-PerformanceStick, STR9-comStick,\nsysfsgpio, Tigard, TI XDS110, TUMPA, Turtelizer, ULINK, USB-A9260, USB-Blaster,\nUSB-JTAG, USBprog, VPACLink, VSLLink, Wiggler, XDS100v2, Xilinx XVC/PCIe,\nXverve.\n\nDebug targets\n-------------\n\nARM: AArch64, ARM11, ARM7, ARM9, Cortex-A/R (v7-A/R), Cortex-M (ARMv{6/7/8}-M),\nFA526, Feroceon/Dragonite, XScale.\nARCv2, AVR32, DSP563xx, DSP5680xx, EnSilica eSi-RISC, EJTAG (MIPS32, MIPS64),\nESP32, ESP32-S2, ESP32-S3, Intel Quark, LS102x-SAP, RISC-V, ST STM8,\nXtensa.\n\nFlash drivers\n-------------\n\nADUC702x, AT91SAM, AT91SAM9 (NAND), ATH79, ATmega128RFA1, Atmel SAM, AVR, CFI,\nDSP5680xx, EFM32, EM357, eSi-RISC, eSi-TSMC, EZR32HG, FM3, FM4, Freedom E SPI,\nGD32, i.MX31, Kinetis, LPC8xx/LPC1xxx/LPC2xxx/LPC541xx, LPC2900, LPC3180, LPC32xx,\nLPCSPIFI, Marvell QSPI, MAX32, Milandr, MXC, NIIET, nRF51, nRF52 , NuMicro,\nNUC910, Nuvoton NPCX, onsemi RSL10, Orion/Kirkwood, PIC32mx, PSoC4/5LP/6,\nRaspberry RP2040, Renesas RPC HF and SH QSPI,\nS3C24xx, S3C6400, SiM3x, SiFive Freedom E, Stellaris, ST BlueNRG, STM32,\nSTM32 QUAD/OCTO-SPI for Flash/FRAM/EEPROM, STMSMI, STR7x, STR9x, SWM050,\nTI CC13xx, TI CC26xx, TI CC32xx, TI MSP432, Winner Micro w600, Xilinx XCF,\nXMC1xxx, XMC4xxx.\n\n\n==================\nInstalling OpenOCD\n==================\n\nA Note to OpenOCD Users\n-----------------------\n\nIf you would rather be working \"with\" OpenOCD rather than \"on\" it, your\noperating system or JTAG interface supplier may provide binaries for\nyou in a convenient-enough package.\n\nSuch packages may be more stable than git mainline, where\nbleeding-edge development takes place. These \"Packagers\" produce\nbinary releases of OpenOCD after the developers produces new \"release\"\nversions of the source code. Previous versions of OpenOCD cannot be\nused to diagnose problems with the current release, so users are\nencouraged to keep in contact with their distribution package\nmaintainers or interface vendors to ensure suitable upgrades appear\nregularly.\n\nUsers of these binary versions of OpenOCD must contact their Packager to\nask for support or newer versions of the binaries; the OpenOCD\ndevelopers do not support packages directly.\n\nA Note to OpenOCD Packagers\n---------------------------\n\nYou are a PACKAGER of OpenOCD if you:\n\n- Sell dongles and include pre-built binaries;\n- Supply tools or IDEs (a development solution integrating OpenOCD);\n- Build packages (e.g. RPM or DEB files for a GNU/Linux distribution).\n\nAs a PACKAGER, you will experience first reports of most issues.\nWhen you fix those problems for your users, your solution may help\nprevent hundreds (if not thousands) of other questions from other users.\n\nIf something does not work for you, please work to inform the OpenOCD\ndevelopers know how to improve the system or documentation to avoid\nfuture problems, and follow-up to help us ensure the issue will be fully\nresolved in our future releases.\n\nThat said, the OpenOCD developers would also like you to follow a few\nsuggestions:\n\n- Send patches, including config files, upstream, participate in the\n  discussions;\n- Enable all the options OpenOCD supports, even those unrelated to your\n  particular hardware;\n- Use \"ftdi\" interface adapter driver for the FTDI-based devices.\n\n\n================\nBuilding OpenOCD\n================\n\nThe INSTALL file contains generic instructions for running 'configure'\nand compiling the OpenOCD source code. That file is provided by\ndefault for all GNU autotools packages. If you are not familiar with\nthe GNU autotools, then you should read those instructions first.\n\nThe remainder of this document tries to provide some instructions for\nthose looking for a quick-install.\n\nOpenOCD Dependencies\n--------------------\n\nGCC or Clang is currently required to build OpenOCD. The developers\nhave begun to enforce strict code warnings (-Wall, -Werror, -Wextra,\nand more) and use C99-specific features: inline functions, named\ninitializers, mixing declarations with code, and other tricks. While\nit may be possible to use other compilers, they must be somewhat\nmodern and could require extending support to conditionally remove\nGCC-specific extensions.\n\nYou'll also need:\n\n- make\n- libtool\n- pkg-config >= 0.23 or pkgconf\n\nOpenOCD uses jimtcl library; build from git can retrieve jimtcl as git\nsubmodule.\n\nAdditionally, for building from git:\n\n- autoconf >= 2.69\n- automake >= 1.14\n- texinfo >= 5.0\n\nOptional USB-based adapter drivers need libusb-1.0.\n\nOptional USB-Blaster, ASIX Presto and OpenJTAG interface adapter\ndrivers need:\n  - libftdi: http://www.intra2net.com/en/developer/libftdi/index.php\n\nOptional CMSIS-DAP adapter driver needs HIDAPI library.\n\nOptional linuxgpiod adapter driver needs libgpiod library.\n\nOptional J-Link adapter driver needs libjaylink library.\n\nOptional ARM disassembly needs capstone library.\n\nOptional development script checkpatch needs:\n\n- perl\n- python\n- python-ply\n\nPermissions delegation\n----------------------\n\nRunning OpenOCD with root/administrative permissions is strongly\ndiscouraged for security reasons.\n\nFor USB devices on GNU/Linux you should use the contrib/60-openocd.rules\nfile. It probably belongs somewhere in /etc/udev/rules.d, but\nconsult your operating system documentation to be sure. Do not forget\nto add yourself to the \"plugdev\" group.\n\nFor parallel port adapters on GNU/Linux and FreeBSD please change your\n\"ppdev\" (parport* or ppi*) device node permissions accordingly.\n\nFor parport adapters on Windows you need to run install_giveio.bat\n(it's also possible to use \"ioperm\" with Cygwin instead) to give\nordinary users permissions for accessing the \"LPT\" registers directly.\n\nCompiling OpenOCD\n-----------------\n\nTo build OpenOCD, use the following sequence of commands:\n\n  ./bootstrap (when building from the git repository)\n  ./configure [options]\n  make\n  sudo make install\n\nThe 'configure' step generates the Makefiles required to build\nOpenOCD, usually with one or more options provided to it. The first\n'make' step will build OpenOCD and place the final executable in\n'./src/'. The final (optional) step, ``make install'', places all of\nthe files in the required location.\n\nTo see the list of all the supported options, run\n  ./configure --help\n\nCross-compiling Options\n-----------------------\n\nCross-compiling is supported the standard autotools way, you just need\nto specify the cross-compiling target triplet in the --host option,\ne.g. for cross-building for Windows 32-bit with MinGW on Debian:\n\n  ./configure --host=i686-w64-mingw32 [options]\n\nTo make pkg-config work nicely for cross-compiling, you might need an\nadditional wrapper script as described at\n\n  https://autotools.io/pkgconfig/cross-compiling.html\n\nThis is needed to tell pkg-config where to look for the target\nlibraries that OpenOCD depends on. Alternatively, you can specify\n*_CFLAGS and *_LIBS environment variables directly, see \"./configure\n--help\" for the details.\n\nFor a more or less complete script that does all this for you, see\n\n  contrib/cross-build.sh\n\nParallel Port Dongles\n---------------------\n\nIf you want to access the parallel port using the PPDEV interface you\nhave to specify both --enable-parport AND --enable-parport-ppdev, since\nthe later option is an option to the parport driver.\n\nThe same is true for the --enable-parport-giveio option, you have to\nuse both the --enable-parport AND the --enable-parport-giveio option\nif you want to use giveio instead of ioperm parallel port access\nmethod.\n\n\n==========================\nObtaining OpenOCD From GIT\n==========================\n\nYou can download the current GIT version with a GIT client of your\nchoice from the main repository:\n\n   git://git.code.sf.net/p/openocd/code\n\nYou may prefer to use a mirror:\n\n   http://repo.or.cz/r/openocd.git\n   git://repo.or.cz/openocd.git\n\nUsing the GIT command line client, you might use the following command\nto set up a local copy of the current repository (make sure there is no\ndirectory called \"openocd\" in the current directory):\n\n   git clone git://git.code.sf.net/p/openocd/code openocd\n\nThen you can update that at your convenience using\n\n   git pull\n\nThere is also a gitweb interface, which you can use either to browse\nthe repository or to download arbitrary snapshots using HTTP:\n\n   http://repo.or.cz/w/openocd.git\n\nSnapshots are compressed tarballs of the source tree, about 1.3 MBytes\neach at this writing.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/README.Windows",
    "content": "Building OpenOCD for Windows\n----------------------------\n\nYou can build OpenOCD for Windows natively with either MinGW-w64/MSYS\nor Cygwin (plain MinGW might work with --disable-werror but is not\nrecommended as it doesn't provide enough C99 compatibility).\nAlternatively, one can cross-compile it using MinGW-w64 on a *nix\nhost. See README for the generic instructions.\n\nAlso, the MSYS2 project provides both ready-made binaries and an easy\nway to self-compile from their software repository out of the box.\n\nNative MinGW-w64/MSYS compilation\n-----------------------------\n\nAs MSYS doesn't come with pkg-config pre-installed, you need to add it\nmanually. The easiest way to do that is to download pkg-config-lite\nfrom:\n\n  http://sourceforge.net/projects/pkgconfiglite/\n\nThen simply unzip the archive to the root directory of your MinGW-w64\ninstallation.\n\nUSB adapters\n------------\n\nFor the adapters that use a HID-based protocol, e.g. CMSIS-DAP, you do\nnot need to perform any additional configuration.\n\nFor all the others you usually need to have WinUSB.sys (or\nlibusbK.sys) driver installed. Some vendor software (e.g. for\nST-LINKv2) does it on its own. For the other cases the easiest way to\nassign WinUSB to a device is to use the latest Zadig installer:\n\n  http://zadig.akeo.ie\n\nWhen using a composite USB device, it's often necessary to assign\nWinUSB.sys to the composite parent instead of the specific\ninterface. To do that one needs to activate an advanced option in the\nZadig installer.\n\nIf you need to use the same adapter with other applications that may\nrequire another driver, a solution for Windows Vista and above is to\nactivate the IgnoreHWSerNum registry setting for the USB device.\n\nThat setting forces Windows to associate the driver per port instead of\nper serial number, the same behaviour as when the device does not contain\na serial number. So different drivers can be installed for the adapter on\ndifferent ports and you just need to plug the adapter into the correct\nport depending on which application to use.\n\nFor more information, see:\n\n  https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-device-specific-registry-settings\n  http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/README.macOS",
    "content": "Building OpenOCD for macOS\n--------------------------\n\nThere are a few prerequisites you will need first:\n\n- Xcode (install from the AppStore)\n- Command Line Tools (install from Xcode -> Preferences -> Downloads)\n- Gentoo Prefix (http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap.xml)\n  or\n- Homebrew (http://mxcl.github.io/homebrew/)\n  or\n- MacPorts (http://www.macports.org/install.php)\n\n\nIf you're building manually you need Texinfo version 5.0 or later. The\nsimplest way to get it is to use Homebrew (brew install texinfo) and\nthen ``export PATH=/usr/local/opt/texinfo/bin:$PATH``.\n\n\nWith Gentoo Prefix you can build the release version or the latest\ndevel version (-9999) the usual way described in the Gentoo\ndocumentation. Alternatively, install the prerequisites and build\nmanually from the sources.\n\n\nWith Homebrew you can either run:\n  brew install [--HEAD] openocd (where optional --HEAD asks brew to\n                                 install the current git version)\n    or\n  brew install libtool automake libusb [hidapi] [libftdi]\n    (to install the needed dependencies and then proceed with the\n     manual building procedure)\n\n\nFor building with MacPorts you need to run:\n  sudo port install libtool automake autoconf pkgconfig \\\n    libusb [libftdi1]\n\nYou should also specify LDFLAGS and CPPFLAGS to allow configure to use\nMacPorts' libraries, so run configure like this:\n  LDFLAGS=-L/opt/local/lib CPPFLAGS=-I/opt/local/include ./configure [options]\n\n\nSee README for the generic building instructions.\n\nIf you're using a USB adapter and have a driver kext matched to it,\nyou will need to unload it prior to running OpenOCD. E.g. with Apple\ndriver (OS X 10.9 or later) for FTDI run:\n  sudo kextunload -b com.apple.driver.AppleUSBFTDI\nfor FTDI vendor driver use:\n  sudo kextunload FTDIUSBSerialDriver.kext\n\nTo learn more on the topic please refer to the official libusb FAQ:\nhttps://github.com/libusb/libusb/wiki/FAQ\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/TODO",
    "content": "// This file is part of the Doxygen Developer Manual\n/** @page tasks Pending and Open Tasks\n\nThis page lists pending and open tasks being considered or worked upon\nby the OpenOCD community.\n\n@section thelist The List\n\nMost items are open for the taking, but please post to the mailing list\nbefore spending much time working on anything lists here.  The community\nmay have evolved an idea since it was added here.\n\nFeel free to send patches to add or clarify items on this list, too.\n\n@section thelisttcl TCL\n\nThis section provides possible things to improve with OpenOCD's TCL support.\n\n- Fix problem with incorrect line numbers reported for a syntax\n  error in a reset init event.\n\n- organize the TCL configurations:\n  - provide more directory structure for boards/targets?\n  - factor configurations into layers (encapsulation and re-use)\n\n- Fix handling of variables between multiple command line \"-c\" and \"-f\"\n  parameters.  Currently variables assigned through one such parameter\n  command/script are unset before the next one is invoked.\n\n- Isolate all TCL command support:\n  - Pure C CLI implementations using --disable-builtin-tcl.\n    - Allow developers to build new dongles using OpenOCD's JTAG core.\n    - At first, provide only low-level JTAG support; target layer and\n      above rely heavily on scripting event mechanisms.\n  - Allow full TCL support? add --with-tcl=/path/to/installed/tcl\n  - Move TCL support out of foo.[ch] and into foo_tcl.[ch] (other ideas?)\n    - See src/jtag/core.c and src/jtag/tcl.c for an example.\n    - allow some of these TCL command modules to be dynamically loadable?\n\n@section thelistadapter Adapter\n\nThis section list issues that need to be resolved in the Adapter layer.\n\n@subsection thelistadapterrework Code restructuring\n\nThis section lists pending reworks to complete the restructure from the\nold JTAG centric implementation to a generic Adapter layer.\nThis restructuring is very invasive and will prevent the merge of several\nchanges pending in gerrit.\n\n- rename folder src/jtag/ to src/adapter/\n- rename var \"jtag\" to \"adapter\" in src/jtag/core.c\n- split content of src/adapter/ in the different protocols jtag.[ch],\n  swd.[ch], ...\n- wrap the calls to adapter->transport_ops->api() with transport_api()\n  and reduce the visibility of global var \"adapter\"\n- complete the migration of JTAG-only drivers to adapter->reset()\n- try to remove JTAG_SLEEP also from JTAG mode?\n- tap_set_state(TAP_RESET) is already done in src/jtag/core.c. No need\n  to replicate it in the drivers, apart in case the driver sets TRST\n  independently\n- add .hla_ops to \"adapter\"\n- HLA is a API level (.hla_ops). Transport should simply be {jtag,swd},\n  not {hla_jtag,hla_swd}.\n\n@subsection thelistadapterjtagcore JTAG Core\n\nThe following tasks have been suggested for cleaning up the JTAG layer:\n\n- use tap_set_state everywhere to allow logging TAP state transitions\n- Encapsulate cmd_queue_cur_state and related variable handling.\n- add slick 32 bit versions of jtag_add_xxx_scan() that avoids\nbuf_set_u32() calls and other evidence of poor impedance match between\nAPI and calling code. New API should cut down # of lines in calling\ncode by 100's and make things clearer. Also potentially be supported\ndirectly in minidriver API for better embedded host performance.\n\nThe following tasks have been suggested for adding new core JTAG support:\n\n- Improve autodetection of TAPs by supporting tcl escape procedures that\n  can configure discovered TAPs based on IDCODE value ... they could:\n    - Remove guessing for irlen\n    - Allow non-default irmask/ircapture values\n- SPI/UART emulation:\n  - (ab)use bit-banging JTAG interfaces to emulate SPI/UART\n  - allow SPI to program flash, MCUs, etc.\n\n@subsection thelistadapterinterfaces Interface drivers\n\nThere are some known bugs to fix in Interface drivers:\n\n- For JTAG_STATEMOVE to TAP_RESET, all drivers must ignore the current\n  recorded state.  The tap_get_state() call won't necessarily return\n  the correct value, especially at server startup.  Fix is easy:  in\n  that case, always issue five clocks with TMS high.\n  - amt_jtagaccel.c\n  - arm-jtag-ew.c\n  - bitbang.c\n  - bitq.c\n  - gw16012.c\n  - jlink.c\n  - usbprog.c\n  - vsllink.c\n  - rlink/rlink.c\n- bug: USBprog is broken with new tms sequence; it needs 7-clock cycles.\n  Fix promised from  Peter Denison openwrt at marshadder.org\n  Workaround: use \"tms_sequence long\" @par\n  https://lists.berlios.de/pipermail/openocd-development/2009-July/009426.html\n\nThe following tasks have been suggested for improving OpenOCD's JTAG\ninterface support:\n\n- rework USB communication to be more robust.  Two possible options are:\n  -# use libusb-1.0.1 with libusb-compat-0.1.1 (non-blocking I/O wrapper)\n  -# rewrite implementation to use non-blocking I/O\n- J-Link driver:\n  - fix to work with long scan chains, such as R.Doss's svf test.\n- Autodetect USB based adapters; this should be easy on Linux.  If there's\n  more than one, list the options; otherwise, just select that one.\n\nThe following tasks have been suggested for adding new JTAG interfaces:\n\n- TCP driver: allow client/server for remote JTAG interface control.\nThis requires a client and a server. The server is built into the\nnormal OpenOCD and takes commands from the client and executes\nthem on the interface returning the result of TCP/IP. The client\nis an OpenOCD which is built with a TCP/IP minidriver. The use\nof a minidriver is required to capture all the jtag_add_xxx()\nfn's at a high enough level and repackage these cmd's as\nTCP/IP packets handled by the server.\n\n@section thelistbs Boundary Scan Support\n\n- add STAPL support?\n- add BSDL support?\n\nA few possible options for the above:\n  -# Fake a TCL equivalent?\n  -# Integrate an existing library?\n  -# Write a new C implementation a la Jim?\n\nOnce the above are completed:\n- add support for programming flash using boundary scan techniques\n- add integration with a modified gerber view program:\n  - provide means to view the PCB and select pins and traces\n  - allow use-cases such as the following:\n    - @b Stimulus\n      -# Double-click on a pin (or trace) with the mouse.\n    - @b Effects\n      -# The trace starts blinking, and\n      -# OpenOCD toggles the pin(s) 0/1.\n\n@section thelisttargets Target Support\n\n- Many common ARM cores could be autodetected using IDCODE\n- general layer cleanup: @par\n  https://lists.berlios.de/pipermail/openocd-development/2009-May/006590.html\n- regression: \"reset halt\" between 729(works) and 788(fails): @par\nhttps://lists.berlios.de/pipermail/openocd-development/2009-July/009206.html\n- registers\n  - add flush-value operation, call them all on resume/reset\n- mcr/mrc target->type support\n  - missing from ARM920t, ARM966e, XScale.\n  It's possible that the current syntax is unable to support read-modify-write\n  operations(see arm966e).\n  - mcr/mrc - retire cp15 commands when there the mrc/mrc commands have been\n  tested from: arm926ejs, arm720t, cortex_a8\n- ARM7/9:\n  - clean up \"arm9tdmi vector_catch\". Available for some arm7 cores? @par\nhttps://lists.berlios.de/pipermail/openocd-development/2009-October/011488.html\nhttps://lists.berlios.de/pipermail/openocd-development/2009-October/011506.html\n  - add reset option to allow programming embedded ice while srst is asserted.\n  Some CPUs will gate the JTAG clock when srst is asserted and in this case,\n  it is necessary to program embedded ice and then assert srst afterwards.\n- ARM926EJS:\n  - reset run/halt/step is not robust; needs testing to map out problems.\n- ARM11 improvements (MB?)\n  - add support for asserting srst to reset the core.\n  - Single stepping works, but should automatically\n  use hardware stepping if available.\n  - mdb can return garbage data if read byte operation fails for\n  a memory region(16 & 32 byte access modes may be supported). Is this\n  a bug in the .MX31 PDK init script? Try on i.MX31 PDK:\n  mdw 0xb80005f0 0x8, mdh 0xb80005f0 0x10, mdb 0xb80005f0 0x20. mdb returns\n  garabage.\n  - implement missing functionality (grep FNC_INFO_NOTIMPLEMENTED ...)\n- Thumb2 single stepping: ARM1156T2 needs simulator support\n- Cortex-A8 support (ML)\n  - add target implementation (ML)\n- Cortex-M3 support\n  - when stepping, only write dirtied registers (be faster)\n  - when connecting to halted core, fetch registers (startup is quirky)\n- Generic ARM run_algorithm() interface\n  - tagged struct wrapping ARM instructions and metadata\n  - not revision-specific (current: ARMv4+ARMv5 -or- ARMv6 -or- ARMv7)\n  - usable with at least arm_nandwrite() and generic CFI drivers\n- ETM\n  - don't show FIFOFULL registers if they're not supported\n  - use comparators to get more breakpoints and watchpoints\n  - add \"etm drivers\" command\n  - trace driver init() via examine() paths only, not setup()/reset\n- MC1322x support (JW/DE?)\n  - integrate and test support from JW (and DE?)\n  - get working with a known good interface (i.e. not today's jlink)\n- STR9x: (ZW)\n  - improvements to str912.cfg to be more general purpose\n- AVR: (SQ)\n  - independently verify implementation\n  - incrementally improve working prototype in trunk. (SQ)\n  - work out how to debug this target\n  - AVR debugging protocol.\n- FPGA:\n  - Altera Nios Soft-CPU support\n- Coldfire (suggested by NC)\n  - can we draw from the BDM project?  @par\n    http://bdm.sourceforge.net/\n\n    or the OSBDM package @par\n    http://forums.freescale.com/freescale/board/message?board.id=OSBDM08&thread.id=422\n\n@section thelistsvf SVF/XSVF\n\n- develop SVF unit tests\n- develop XSVF unit tests\n\n@section thelistflash Flash Support\n\n- finish documentation for the following flash drivers:\n  - avr\n  - pic32mx\n  - ocl\n  - str9xpec\n\n- Don't expect writing all-ones to be a safe way to write without\n  changing bit values.  Minimally it loses on flash modules with\n  internal ECC, where it may change the ECC.\n  - NOR flash_write_unlock() does that between sectors\n  - there may be other cases too\n\n- Make sure all commands accept either a bank name or a bank number,\n  and be sure both identifiers show up in \"flash banks\" and \"nand list\".\n  Right now the user-friendly names are pretty much hidden...\n\n@subsection thelistflashcfi CFI\n\n- finish implementing bus width/chip width handling (suggested by NC)\n- factor vendor-specific code into separate source files\n  - add new callback interface for vendor-specific code\n- investigate/implement \"thin wrapper\" to use eCos CFI drivers (ØH)\n\n@section thelistdebug Debugger Support\n\n- add support for masks in watchpoints? @par\n  https://lists.berlios.de/pipermail/openocd-development/2009-October/011507.html\n- breakpoints can get lost in some circumstances: @par\n  https://lists.berlios.de/pipermail/openocd-development/2009-June/008853.html\n- add support for masks in watchpoints. The trick is that GDB does not\n  support a breakpoint mask in the remote protocol. One way to work around\n  this is to add a separate command \"watchpoint_mask add/rem <addr> <mask>\", that\n  is run to register a list of masks that the gdb_server knows to use with\n  a particular watchpoint address.\n- integrate Keil AGDI interface to OpenOCD? (submitted by Dario Vecchio)\n\n@section thelisttesting Testing Suite\n\nThis section includes several related groups of ideas:\n- @ref thelistunittests\n- @ref thelistsmoketests\n- @ref thelisttestreports\n- @ref thelisttestgenerichw\n\n@subsection thelistunittests Unit Tests\n\n- add testing skeleton to provide frameworks for adding tests\n- implement server unit tests\n- implement JTAG core unit tests\n- implement JTAG interface unit tests\n- implement flash unit tests\n- implement target unit tests\n\n@subsection thelistsmoketests Smoke Test Tools\n\n-# extend 'make check' with a smoketest app\n  - checks for OOCD_TEST_CONFIG, etc. in environment (or config file)\n  - if properly set, runs the smoke test with specified parameters\n    - openocd -f ${OOCD_TEST_CONFIG}\n    - implies a modular test suite (see below)\n  - should be able to run some minimal tests with dummy interface:\n    - compare results of baseline sanity checks with expected results\n\n-# builds a more complete test suite:\n  - existing testing/examples/ look like a great start\n  - all targets should be tested fully and for all capabilities\n    - we do NOT want a \"lowest common denominator\" test suite\n    - ... but can we start with one to get going?\n  - probably requires one test configuration file per board/target\n    - modularization can occur here, just like with targets/boards/chips\n    - coverage can increase over time, building up bundles of tests\n\n-# add new 'smoketest' Makefile target:\n  - calls 'make check' (and the smoketest app)\n  - gather inputs and output into a report file\n\n@subsection thelisttestreports Test Feedback Tools\n\nThese ideas were first introduced here: @par\n  https://lists.berlios.de/pipermail/openocd-development/2009-May/006358.html\n\n- provide report submission scripts for e-mail and web forms\n- add new Makefile targets to post the report:\n  - 'checkreportsend' -- send to list via e-mail (via sendmail)\n  - 'checkreportpost' -- send web form (via curl or other script)\n\n@subsection thelisttestgenerichw Generic Hardware Tester\n\n- implement VHDL to use for FPGA-based JTAG TAP testing device\n- develop test suite that utilizes this testing device\n\n@section thelistautotools Autotools Build System\n\n- make entire configure process require less user consideration:\n  - automatically detect the features that are available, unless\n    options were specifically provided to configure\n  - provide a report of the drivers that will be build at the end of\n    running configure, so the users can verify which drivers will be\n    built during 'make' (and their options) .\n- eliminate sources of confusion in @c bootstrap script:\n  -# Make @c bootstrap call 'configure --enable-maintainer-mode \\<opts\\>'?\n  -# Add @c buildstrap script to assist with bootstrap and configure steps.\n- automatically build tool-chains required for cross-compiling\n  - produce mingw32, arm-elf, others using in-tree scripts\n  - build all required target code from sources\n- make JTAG and USB debug output a run-time configuration option\n\n@section thelistarchitecture Architectural Tasks\n\nThe following architectural tasks need to be accomplished and should be\nfairly easy to complete:\n\n\n- use dynamic allocations for working memory. Scan & fix code\nfor excessive stack allocations. take linux/scripts/checkstack.pl and\nsee what the worst offenders are. Dynamic stack allocations are found\nat the bottom of the list below.  Example, on amd64:\n\n $ objdump -d | checkstack.pl | head -10\n 0x004311e3 image_open [openocd]:                      13464\n 0x00431301 image_open [openocd]:                      13464\n 0x004237a4 target_array2mem [openocd]:                        4376\n 0x0042382b target_array2mem [openocd]:                        4376\n 0x00423e74 target_mem2array [openocd]:                        4360\n 0x00423ef9 target_mem2array [openocd]:                        4360\n 0x00404aed handle_svf_command [openocd]:              2248\n 0x00404b7e handle_svf_command [openocd]:              2248\n 0x00413581 handle_flash_fill_command [openocd]:               2200\n 0x004135fa handle_flash_fill_command [openocd]:               2200\n- clean-up code to match style guides\n- factor code to eliminate duplicated functionality\n- rewrite code that uses casts to access 16-bit and larger types\n  from unaligned memory addresses\n- libopenocd support: @par\n    https://lists.berlios.de/pipermail/openocd-development/2009-May/006405.html\n- review and clean up interface/target/flash APIs\n\nThe following strategic tasks will require ambition, knowledge, and time\nto complete:\n\n- overhaul use of types to improve 32/64-bit portability\n  - types for both host and target word sizes?\n  - can we use GDB's CORE_TYPE support?\n- Allow N:M:P mapping of servers, targets, and interfaces\n- loadable module support for interface/target/flash drivers and commands\n  - support both static and dynamic modules.\n  - should probably use libltdl for dynamic library handing.\n\n@section thelistadmin Documentation Tasks\n\n- Develop milestone and release guidelines, processes, and scripts.\n- Develop \"style\" guidelines (and scripts) for maintainers:\n  - reviewing patches\n  - committing to git\n- Review Users' Guide for documentation errors or omissions\n  - \"capture\" and \"ocd_find\" commands\n- Update Developer's Manual (doxygen output)\n  - Add documentation describing the architecture of each module\n  - Provide more Technical Primers to bootstrap contributor knowledge\n\n*/\n/** @file\nThis file contains the @ref thelist page.\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/bootstrap",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Run the autotools bootstrap sequence to create the configure script\n\n# Abort execution on error\nset -e\n\nif which libtoolize > /dev/null; then\n    libtoolize=\"libtoolize\"\nelif which glibtoolize >/dev/null; then\n    libtoolize=\"glibtoolize\"\nelse\n    echo \"$0: Error: libtool is required\" >&2\n    exit 1\nfi\n\nif [ \"$1\" = \"nosubmodule\" ]; then\n    SKIP_SUBMODULE=1\nelif [ -n \"$1\" ]; then\n    echo \"$0: Illegal argument $1\"\n    echo \"USAGE: $0 [nosubmodule]\"  \n    exit 1\nfi\n\n# bootstrap the autotools\n(\nset -x\naclocal --warnings=all\n# Apparently, not all versions of libtoolize support option --warnings=all .\n${libtoolize} --automake --copy\nautoconf --warnings=all\nautoheader --warnings=all\nautomake --warnings=all --gnu --add-missing --copy\n)\n\nif [ -n \"$SKIP_SUBMODULE\" ]; then\n    echo \"Skipping submodule setup\"\nelse\n    echo \"Setting up submodules\"\n    git submodule init\n    git submodule update\nfi\n\nif [ -x src/jtag/drivers/libjaylink/autogen.sh ]; then\n    (\n    cd src/jtag/drivers/libjaylink\n    ./autogen.sh\n    )\nfi\n\necho \"Bootstrap complete. Quick build instructions:\"\necho \"./configure ....\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/config_subdir.m4",
    "content": "dnl AC_CONFIG_SUBDIRS does not allow configure options to be passed\ndnl to subdirs, this function allows that by creating a configure.gnu\ndnl script that prepends configure options and then calls the real\ndnl configure script\nAC_DEFUN([AX_CONFIG_SUBDIR_OPTION],\n[\nAC_CONFIG_SUBDIRS([$1])\n\nm4_ifblank([$2], [rm -f $srcdir/$1/configure.gnu],\n[echo -e '#!/bin/sh\\nexec \"`dirname \"'\\$'0\"`/configure\" '\"$2\"' \"'\\$'@\"' > \"$srcdir/$1/configure.gnu\"\n])\n])\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/configure.ac",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nAC_PREREQ([2.69])\nAC_INIT([openocd], [0.12.0+dev],\n  [OpenOCD Mailing List <openocd-devel@lists.sourceforge.net>])\nAC_CONFIG_SRCDIR([src/openocd.c])\nAC_CONFIG_AUX_DIR([build-aux])\n\nm4_include([config_subdir.m4])dnl\n\n# check for makeinfo before calling AM_INIT_AUTOMAKE\nAC_CHECK_PROG([MAKEINFO], [makeinfo], [makeinfo])\nAS_IF([test \"x$MAKEINFO\" = \"x\"], [\n  MAKEINFO='echo makeinfo missing; true'\n  AC_MSG_WARN([Info documentation will not be built.])\n])\nAC_SUBST([MAKEINFO])\n\nAM_INIT_AUTOMAKE([-Wall -Wno-portability dist-bzip2 dist-zip subdir-objects])\n\nAC_CONFIG_HEADERS([config.h])\n\nAC_LANG([C])\nAC_PROG_CC\n# autoconf 2.70 obsoletes AC_PROG_CC_C99 and includes it in AC_PROG_CC\nm4_version_prereq([2.70],[],[AC_PROG_CC_C99])\nAM_PROG_CC_C_O\nAC_PROG_RANLIB\n\n# If macro PKG_PROG_PKG_CONFIG is not available, Autoconf generates a misleading error message,\n# so check for existence first, and otherwise provide helpful advice.\nm4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal(m4_normalize([\n  Macro PKG_PROG_PKG_CONFIG is not available.\n  It is usually defined in file pkg.m4 provided by package pkg-config.]))])\nPKG_PROG_PKG_CONFIG([0.23])\n\ndnl disable checks for C++, Fortran and GNU Java Compiler\nm4_defun([_LT_AC_LANG_CXX_CONFIG], [:])\nm4_defun([_LT_AC_LANG_F77_CONFIG], [:])\nm4_defun([_LT_AC_LANG_GCJ_CONFIG], [:])\nAC_DISABLE_SHARED\nLT_INIT\nAC_SUBST([LIBTOOL_DEPS])\n\ndnl configure checks required for Jim files (these are obsolete w/ C99)\nAC_C_CONST\nAC_TYPE_LONG_LONG_INT\n\nAC_SEARCH_LIBS([ioperm], [ioperm])\nAC_SEARCH_LIBS([dlopen], [dl])\nAC_SEARCH_LIBS([openpty], [util])\n\nAC_CHECK_HEADERS([sys/socket.h])\nAC_CHECK_HEADERS([elf.h])\nAC_EGREP_HEADER(Elf64_Ehdr, [elf.h], [\n  AC_DEFINE([HAVE_ELF64], [1], [Define to 1 if the system has the type `Elf64_Ehdr'.])\n])\nAC_CHECK_HEADERS([fcntl.h])\nAC_CHECK_HEADERS([malloc.h])\nAC_CHECK_HEADERS([netdb.h])\nAC_CHECK_HEADERS([poll.h])\nAC_CHECK_HEADERS([strings.h])\nAC_CHECK_HEADERS([sys/ioctl.h])\nAC_CHECK_HEADERS([sys/param.h])\nAC_CHECK_HEADERS([sys/select.h])\nAC_CHECK_HEADERS([sys/stat.h])\nAC_CHECK_HEADERS([sys/sysctl.h])\nAC_CHECK_HEADERS([sys/time.h])\nAC_CHECK_HEADERS([sys/types.h])\nAC_CHECK_HEADERS([unistd.h])\nAC_CHECK_HEADERS([arpa/inet.h netinet/in.h netinet/tcp.h], [], [], [dnl\n#include <stdio.h>\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <stddef.h>\n#else\n# ifdef HAVE_STDLIB_H\n#  include <stdlib.h>\n# endif\n#endif\n#ifdef HAVE_SYS_SOCKET_H\n# include <sys/socket.h>\n#endif\n])\n\nAC_HEADER_ASSERT\nAC_HEADER_STDBOOL\n\nAC_C_BIGENDIAN\n\nAC_CHECK_FUNCS([strndup])\nAC_CHECK_FUNCS([strnlen])\nAC_CHECK_FUNCS([gettimeofday])\nAC_CHECK_FUNCS([usleep])\nAC_CHECK_FUNCS([realpath])\n\n# guess-rev.sh only exists in the repository, not in the released archives\nAC_MSG_CHECKING([whether to build a release])\nAS_IF([test -x \"$srcdir/guess-rev.sh\"], [\n  build_release=no\n], [\n  build_release=yes\n])\nAC_MSG_RESULT([$build_release])\n\n# Adapter drivers\n# 1st column -- configure option\n# 2nd column -- description\n# 3rd column -- symbol used for both config.h and automake\nm4_define([ADAPTER_ARG], [m4_argn([1], $1)])\nm4_define([ADAPTER_DESC], [m4_argn([2], $1)])\nm4_define([ADAPTER_SYM], [m4_argn([3], $1)])\nm4_define([ADAPTER_VAR], [enable_[]ADAPTER_ARG($1)])\nm4_define([ADAPTER_OPT], [m4_translit(ADAPTER_ARG($1), [_], [-])])\n\nm4_define([USB1_ADAPTERS],\n\t[[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]],\n\t[[stlink], [ST-Link Programmer], [HLADAPTER_STLINK]],\n\t[[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]],\n\t[[ulink], [Keil ULINK JTAG Programmer], [ULINK]],\n\t[[usb_blaster_2], [Altera USB-Blaster II Compatible], [USB_BLASTER_2]],\n\t[[ft232r], [Bitbang mode of FT232R based devices], [FT232R]],\n\t[[vsllink], [Versaloon-Link JTAG Programmer], [VSLLINK]],\n\t[[xds110], [TI XDS110 Debug Probe], [XDS110]],\n\t[[cmsis_dap_v2], [CMSIS-DAP v2 Compliant Debugger], [CMSIS_DAP_USB]],\n\t[[osbdm], [OSBDM (JTAG only) Programmer], [OSBDM]],\n\t[[opendous], [eStick/opendous JTAG Programmer], [OPENDOUS]],\n\t[[armjtagew], [Olimex ARM-JTAG-EW Programmer], [ARMJTAGEW]],\n\t[[rlink], [Raisonance RLink JTAG Programmer], [RLINK]],\n\t[[usbprog], [USBProg JTAG Programmer], [USBPROG]],\n\t[[esp_usb_jtag], [Espressif JTAG Programmer], [ESP_USB_JTAG]],\n  [[ch347], [Mode 3 of the CH347 devices], [CH347]]])\n\nm4_define([HIDAPI_ADAPTERS],\n\t[[[cmsis_dap], [CMSIS-DAP Compliant Debugger], [CMSIS_DAP_HID]],\n\t[[nulink], [Nu-Link Programmer], [HLADAPTER_NULINK]]])\n\nm4_define([HIDAPI_USB1_ADAPTERS],\n\t[[[kitprog], [Cypress KitProg Programmer], [KITPROG]]])\n\nm4_define([LIBFTDI_ADAPTERS],\n\t[[[usb_blaster], [Altera USB-Blaster Compatible], [USB_BLASTER]],\n\t[[presto], [ASIX Presto Adapter], [PRESTO]]])\n\nm4_define([LIBFTDI_USB1_ADAPTERS],\n\t[[[openjtag], [OpenJTAG Adapter], [OPENJTAG]]])\n\nm4_define([LIBGPIOD_ADAPTERS],\n\t[[[linuxgpiod], [Linux GPIO bitbang through libgpiod], [LINUXGPIOD]]])\n\nm4_define([LIBJAYLINK_ADAPTERS],\n\t[[[jlink], [SEGGER J-Link Programmer], [JLINK]]])\n\nm4_define([PCIE_ADAPTERS],\n\t[[[xlnx_pcie_xvc], [Xilinx XVC/PCIe], [XLNX_PCIE_XVC]]])\n\nm4_define([SERIAL_PORT_ADAPTERS],\n\t[[[buspirate], [Bus Pirate], [BUS_PIRATE]]])\n\nm4_define([OPTIONAL_LIBRARIES],\n\t[[[capstone], [Use Capstone disassembly framework], []]])\n\nAC_ARG_ENABLE([doxygen-html],\n  AS_HELP_STRING([--disable-doxygen-html],\n    [Disable building Doxygen manual as HTML.]),\n  [doxygen_as_html=$enableval], [doxygen_as_html=yes])\nAC_SUBST([doxygen_as_html])\nAC_MSG_CHECKING([whether to build Doxygen as HTML])\nAC_MSG_RESULT([$doxygen_as_html])\n\nAC_ARG_ENABLE([doxygen-pdf],\n  AS_HELP_STRING([--enable-doxygen-pdf],\n    [Enable building Doxygen manual as PDF.]),\n  [doxygen_as_pdf=$enableval], [doxygen_as_pdf=no])\nAC_SUBST([doxygen_as_pdf])\nAC_MSG_CHECKING([whether to build Doxygen as PDF])\nAC_MSG_RESULT([$doxygen_as_pdf])\n\nAC_ARG_ENABLE([gccwarnings],\n  AS_HELP_STRING([--disable-gccwarnings], [Disable compiler warnings]),\n  [gcc_warnings=$enableval], [gcc_warnings=yes])\n\nAC_ARG_ENABLE([wextra],\n  AS_HELP_STRING([--disable-wextra], [Disable extra compiler warnings]),\n  [gcc_wextra=$enableval], [gcc_wextra=$gcc_warnings])\n\nAC_ARG_ENABLE([werror],\n  AS_HELP_STRING([--disable-werror], [Do not treat warnings as errors]),\n  [gcc_werror=$enableval], [gcc_werror=$gcc_warnings])\n\n# set default verbose options, overridden by following options\ndebug_usb_io=no\ndebug_usb_comms=no\n\nAC_ARG_ENABLE([verbose],\n  AS_HELP_STRING([--enable-verbose],\n      [Enable verbose JTAG I/O messages (for debugging).]),\n  [\n  debug_usb_io=$enableval\n  debug_usb_comms=$enableval\n  ], [])\n\nAC_ARG_ENABLE([verbose_usb_io],\n  AS_HELP_STRING([--enable-verbose-usb-io],\n      [Enable verbose USB I/O messages (for debugging)]),\n  [debug_usb_io=$enableval], [])\n\nAC_ARG_ENABLE([verbose_usb_comms],\n  AS_HELP_STRING([--enable-verbose-usb-comms],\n      [Enable verbose USB communication messages (for debugging)]),\n  [debug_usb_comms=$enableval], [])\n\nAC_MSG_CHECKING([whether to enable verbose USB I/O messages]);\nAC_MSG_RESULT([$debug_usb_io])\nAS_IF([test \"x$debug_usb_io\" = \"xyes\"], [\n  AC_DEFINE([_DEBUG_USB_IO_],[1], [Print verbose USB I/O messages])\n])\n\nAC_MSG_CHECKING([whether to enable verbose USB communication messages]);\nAC_MSG_RESULT([$debug_usb_comms])\nAS_IF([test \"x$debug_usb_comms\" = \"xyes\"], [\n  AC_DEFINE([_DEBUG_USB_COMMS_],[1], [Print verbose USB communication messages])\n])\n\ndebug_malloc=no\nAC_ARG_ENABLE([malloc_logging],\n  AS_HELP_STRING([--enable-malloc-logging],\n      [Include free space in logging messages (requires malloc.h).]),\n  [debug_malloc=$enableval], [])\n\nAC_MSG_CHECKING([whether to enable malloc free space logging]);\nAC_MSG_RESULT([$debug_malloc])\nAS_IF([test \"x$debug_malloc\" = \"xyes\"], [\n  AC_DEFINE([_DEBUG_FREE_SPACE_],[1], [Include malloc free space in logging])\n])\n\nAC_ARG_ENABLE([dummy],\n  AS_HELP_STRING([--enable-dummy], [Enable building the dummy port driver]),\n  [build_dummy=$enableval], [build_dummy=no])\n\nAC_ARG_ENABLE([rshim],\n  AS_HELP_STRING([--enable-rshim], [Enable building the rshim driver]),\n  [build_rshim=$enableval], [build_rshim=no])\n\nm4_define([AC_ARG_ADAPTERS], [\n  m4_foreach([adapter], [$1],\n\t[AC_ARG_ENABLE(ADAPTER_OPT([adapter]),\n\t\tAS_HELP_STRING([--enable-ADAPTER_OPT([adapter])],\n\t\t\t[Enable building support for the ]ADAPTER_DESC([adapter])[ (default is $2)]),\n\t\t[], [ADAPTER_VAR([adapter])=$2])\n  ])\n])\n\nAC_ARG_ADAPTERS([\n  USB1_ADAPTERS,\n  HIDAPI_ADAPTERS,\n  HIDAPI_USB1_ADAPTERS,\n  LIBFTDI_ADAPTERS,\n  LIBFTDI_USB1_ADAPTERS\n  LIBGPIOD_ADAPTERS,\n  SERIAL_PORT_ADAPTERS,\n  LIBJAYLINK_ADAPTERS\n  ],[auto])\n\nAC_ARG_ENABLE([parport],\n  AS_HELP_STRING([--enable-parport], [Enable building the pc parallel port driver]),\n  [build_parport=$enableval], [build_parport=no])\n\nAC_ARG_ENABLE([parport_ppdev],\n  AS_HELP_STRING([--disable-parport-ppdev],\n      [Disable use of ppdev (/dev/parportN) for parport (for x86 only)]),\n    [parport_use_ppdev=$enableval], [parport_use_ppdev=yes])\n\nAC_ARG_ENABLE([parport_giveio],\n    AS_HELP_STRING([--enable-parport-giveio],\n      [Enable use of giveio for parport (for CygWin only)]),\n    [parport_use_giveio=$enableval], [parport_use_giveio=])\n\nAC_ARG_ENABLE([jtag_vpi],\n  AS_HELP_STRING([--enable-jtag_vpi], [Enable building support for JTAG VPI]),\n  [build_jtag_vpi=$enableval], [build_jtag_vpi=no])\n\nAC_ARG_ENABLE([vdebug],\n  AS_HELP_STRING([--enable-vdebug], [Enable building support for Cadence Virtual Debug Interface]),\n  [build_vdebug=$enableval], [build_vdebug=no])\n\nAC_ARG_ENABLE([jtag_dpi],\n  AS_HELP_STRING([--enable-jtag_dpi], [Enable building support for JTAG DPI]),\n  [build_jtag_dpi=$enableval], [build_jtag_dpi=no])\n\nAC_ARG_ENABLE([amtjtagaccel],\n  AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]),\n  [build_amtjtagaccel=$enableval], [build_amtjtagaccel=no])\n\nAS_CASE([\"${host_cpu}\"],\n  [arm*|aarch64], [\n    AC_ARG_ENABLE([bcm2835gpio],\n      AS_HELP_STRING([--enable-bcm2835gpio], [Enable building support for bitbanging on BCM2835 (as found in Raspberry Pi)]),\n      [build_bcm2835gpio=$enableval], [build_bcm2835gpio=no])\n    AC_ARG_ENABLE([imx_gpio],\n      AS_HELP_STRING([--enable-imx_gpio], [Enable building support for bitbanging on NXP IMX processors]),\n      [build_imx_gpio=$enableval], [build_imx_gpio=no])\n    AC_ARG_ENABLE([am335xgpio],\n      AS_HELP_STRING([--enable-am335xgpio], [Enable building support for bitbanging on AM335x (as found in Beaglebones)]),\n      [build_am335xgpio=$enableval], [build_am335xgpio=no])\n  ],\n  [\n    build_bcm2835gpio=no\n    build_imx_gpio=no\n    build_am335xgpio=no\n])\n\nAS_CASE([\"${host_cpu}\"],\n  [arm*], [\n    AC_ARG_ENABLE([ep93xx],\n      AS_HELP_STRING([--enable-ep93xx], [Enable building support for EP93xx based SBCs]),\n      [build_ep93xx=$enableval], [build_ep93xx=no])\n\n    AC_ARG_ENABLE([at91rm9200],\n      AS_HELP_STRING([--enable-at91rm9200], [Enable building support for AT91RM9200 based SBCs]),\n      [build_at91rm9200=$enableval], [build_at91rm9200=no])\n  ],\n  [\n    build_ep93xx=no\n    build_at91rm9200=no\n])\n\nAC_ARG_ENABLE([gw16012],\n  AS_HELP_STRING([--enable-gw16012], [Enable building support for the Gateworks GW16012 JTAG Programmer]),\n  [build_gw16012=$enableval], [build_gw16012=no])\n\nAC_ARG_ENABLE([sysfsgpio],\n  AS_HELP_STRING([--enable-sysfsgpio], [Enable building support for programming driven via sysfs gpios.]),\n  [build_sysfsgpio=$enableval], [build_sysfsgpio=no])\n\nAC_ARG_ENABLE([xlnx_pcie_xvc],\n  AS_HELP_STRING([--enable-xlnx-pcie-xvc], [Enable building support for Xilinx XVC/PCIe.]),\n  [build_xlnx_pcie_xvc=$enableval], [build_xlnx_pcie_xvc=no])\n\nAS_CASE([$host_os],\n  [linux*], [],\n  [\n    AS_IF([test \"x$build_sysfsgpio\" = \"xyes\"], [\n      AC_MSG_ERROR([sysfsgpio is only available on linux])\n    ])\n\n    AS_IF([test \"x$enable_linuxgpiod\" = \"xyes\"], [\n      AC_MSG_ERROR([linuxgpiod is only available on linux])\n    ])\n\n    AS_IF([test \"x$build_xlnx_pcie_xvc\" = \"xyes\"], [\n      AC_MSG_ERROR([xlnx_pcie_xvc is only available on linux])\n    ])\n\n    AS_CASE([$host_os], [freebsd*], [],\n    [\n      AS_IF([test \"x$build_rshim\" = \"xyes\"], [\n        AC_MSG_ERROR([build_rshim is only available on linux or freebsd])\n      ])\n    ])\n])\n\nAC_ARG_ENABLE([internal-jimtcl],\n  AS_HELP_STRING([--disable-internal-jimtcl], [Disable building internal jimtcl]),\n  [use_internal_jimtcl=$enableval], [use_internal_jimtcl=yes])\n\nAC_ARG_ENABLE([jimtcl-maintainer],\n  AS_HELP_STRING([--enable-jimtcl-maintainer], [Enable maintainer mode when building internal jimtcl]),\n  [use_internal_jimtcl_maintainer=$enableval], [use_internal_jimtcl_maintainer=no])\n\nAC_ARG_ENABLE([internal-libjaylink],\n  AS_HELP_STRING([--enable-internal-libjaylink],\n  [Enable building internal libjaylink]),\n  [use_internal_libjaylink=$enableval], [use_internal_libjaylink=no])\n\nAC_ARG_ENABLE([remote-bitbang],\n  AS_HELP_STRING([--enable-remote-bitbang], [Enable building support for the Remote Bitbang jtag driver]),\n  [build_remote_bitbang=$enableval], [build_remote_bitbang=no])\n\nAS_CASE([\"${host_cpu}\"],\n  [i?86|x86*], [],\n  [\n    AS_IF([test \"x$parport_use_ppdev\" = \"xno\"], [\n      AC_MSG_WARN([--disable-parport-ppdev is not supported by the host CPU])\n    ])\n    parport_use_ppdev=yes\n])\n\nAS_CASE([$host],\n  [*-cygwin*], [\n    is_win32=yes\n    parport_use_ppdev=no\n\n    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[return __MINGW32__;]])],\n      [is_mingw=yes],[is_mingw=no])\n    AS_IF([test \"x$is_mingw\" = \"xyes\"], [\n      AS_IF([test \"x$parport_use_giveio\" = \"xno\"], [\n        AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts])\n      ])\n      parport_use_giveio=yes\n      is_cygwin=no\n    ], [\n      is_cygwin=yes\n      # sys/io.h needed under cygwin for parport access\n      AS_IF([test \"x$build_parport\" = \"xyes\"], [\n        AC_CHECK_HEADERS([sys/io.h],[],AC_MSG_ERROR([Please install the cygwin ioperm package]))\n      ])\n    ])\n  ],\n  [*-mingw* | *-msys*], [\n    is_mingw=yes\n    is_win32=yes\n    parport_use_ppdev=no\n\n    AS_IF([test \"x$parport_use_giveio\" = \"xno\"], [\n      AC_MSG_WARN([--disable-parport-giveio is not supported by MinGW32 hosts])\n    ])\n    parport_use_giveio=yes\n\n    AS_IF([test \"x$enable_buspirate\" = \"xyes\"], [\n      AC_MSG_ERROR([buspirate currently not supported by MinGW32 hosts])\n    ])\n\n    # In case enable_buspirate=auto, make sure it will not be built.\n    enable_buspirate=no\n\n    AC_SUBST([HOST_CPPFLAGS], [-D__USE_MINGW_ANSI_STDIO])\n  ],\n  [*darwin*], [\n    is_darwin=yes\n\n    AS_IF([test \"x$parport_use_giveio\" = \"xyes\"], [\n      AC_MSG_WARN([--enable-parport-giveio cannot be used by Darwin hosts])\n    ])\n    parport_use_giveio=no\n  ],\n  [\n    AS_IF([test \"x$parport_use_giveio\" = \"xyes\"], [\n      AC_MSG_WARN([--enable-parport-giveio cannot be used by ]$host[ hosts])\n    ])\n    parport_use_giveio=no\n])\n\nAS_IF([test \"x$is_cygwin\" = \"xyes\"], [\n    AC_DEFINE([IS_CYGWIN], [1], [1 if building for Cygwin.])\n], [\n    AC_DEFINE([IS_CYGWIN], [0], [0 if not building for Cygwin.])\n])\n\nAS_IF([test \"x$is_mingw\" = \"xyes\"], [\n    AC_DEFINE([IS_MINGW], [1], [1 if building for Mingw.])\n], [\n    AC_DEFINE([IS_MINGW], [0], [0 if not building for Mingw.])\n])\n\nAS_IF([test \"x$is_win32\" = \"xyes\"], [\n    AC_DEFINE([IS_WIN32], [1], [1 if building for Win32.])\n], [\n    AC_DEFINE([IS_WIN32], [0], [0 if not building for Win32.])\n])\n\nAS_IF([test \"x$is_darwin\" = \"xyes\"], [\n    AC_DEFINE([IS_DARWIN], [1], [1 if building for Darwin.])\n], [\n    AC_DEFINE([IS_DARWIN], [0], [0 if not building for Darwin.])\n])\n\nAS_IF([test \"x$build_parport\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_PARPORT], [1], [1 if you want parport.])\n], [\n  AC_DEFINE([BUILD_PARPORT], [0], [0 if you don't want parport.])\n])\n\nAS_IF([test \"x$build_rshim\" = \"xyes\"], [\n  AC_DEFINE([BUILD_RSHIM], [1], [1 if you want to debug BlueField SoC via rshim.])\n], [\n  AC_DEFINE([BUILD_RSHIM], [0], [0 if you don't want to debug BlueField SoC via rshim.])\n])\n\nAS_IF([test \"x$build_dummy\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_DUMMY], [1], [1 if you want dummy driver.])\n], [\n  AC_DEFINE([BUILD_DUMMY], [0], [0 if you don't want dummy driver.])\n])\n\nAS_IF([test \"x$build_ep93xx\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_EP93XX], [1], [1 if you want ep93xx.])\n], [\n  AC_DEFINE([BUILD_EP93XX], [0], [0 if you don't want ep93xx.])\n])\n\nAS_IF([test \"x$build_at91rm9200\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_AT91RM9200], [1], [1 if you want at91rm9200.])\n], [\n  AC_DEFINE([BUILD_AT91RM9200], [0], [0 if you don't want at91rm9200.])\n])\n\nAS_IF([test \"x$build_bcm2835gpio\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_BCM2835GPIO], [1], [1 if you want bcm2835gpio.])\n], [\n  AC_DEFINE([BUILD_BCM2835GPIO], [0], [0 if you don't want bcm2835gpio.])\n])\n\nAS_IF([test \"x$build_imx_gpio\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_IMX_GPIO], [1], [1 if you want imx_gpio.])\n], [\n  AC_DEFINE([BUILD_IMX_GPIO], [0], [0 if you don't want imx_gpio.])\n])\n\nAS_IF([test \"x$build_am335xgpio\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_AM335XGPIO], [1], [1 if you want am335xgpio.])\n], [\n  AC_DEFINE([BUILD_AM335XGPIO], [0], [0 if you don't want am335xgpio.])\n])\n\nAS_IF([test \"x$parport_use_ppdev\" = \"xyes\"], [\n  AC_DEFINE([PARPORT_USE_PPDEV], [1], [1 if you want parport to use ppdev.])\n], [\n  AC_DEFINE([PARPORT_USE_PPDEV], [0], [0 if you don't want parport to use ppdev.])\n])\n\nAS_IF([test \"x$parport_use_giveio\" = \"xyes\"], [\n  AC_DEFINE([PARPORT_USE_GIVEIO], [1], [1 if you want parport to use giveio.])\n], [\n  AC_DEFINE([PARPORT_USE_GIVEIO], [0], [0 if you don't want parport to use giveio.])\n])\n\nAS_IF([test \"x$build_jtag_vpi\" = \"xyes\"], [\n  AC_DEFINE([BUILD_JTAG_VPI], [1], [1 if you want JTAG VPI.])\n], [\n  AC_DEFINE([BUILD_JTAG_VPI], [0], [0 if you don't want JTAG VPI.])\n])\n\nAS_IF([test \"x$build_vdebug\" = \"xyes\"], [\n  AC_DEFINE([BUILD_VDEBUG], [1], [1 if you want Cadence vdebug interface.])\n], [\n  AC_DEFINE([BUILD_VDEBUG], [0], [0 if you don't want Cadence vdebug interface.])\n])\n\nAS_IF([test \"x$build_jtag_dpi\" = \"xyes\"], [\n  AC_DEFINE([BUILD_JTAG_DPI], [1], [1 if you want JTAG DPI.])\n], [\n  AC_DEFINE([BUILD_JTAG_DPI], [0], [0 if you don't want JTAG DPI.])\n])\n\n\nAS_IF([test \"x$build_amtjtagaccel\" = \"xyes\"], [\n  AC_DEFINE([BUILD_AMTJTAGACCEL], [1], [1 if you want the Amontec JTAG-Accelerator driver.])\n], [\n  AC_DEFINE([BUILD_AMTJTAGACCEL], [0], [0 if you don't want the Amontec JTAG-Accelerator driver.])\n])\n\nAS_IF([test \"x$build_gw16012\" = \"xyes\"], [\n  AC_DEFINE([BUILD_GW16012], [1], [1 if you want the Gateworks GW16012 driver.])\n], [\n  AC_DEFINE([BUILD_GW16012], [0], [0 if you don't want the Gateworks GW16012 driver.])\n])\n\nAS_IF([test \"x$enable_buspirate\" != \"xno\"], [\n  AC_DEFINE([BUILD_BUSPIRATE], [1], [1 if you want the Buspirate JTAG driver.])\n], [\n  AC_DEFINE([BUILD_BUSPIRATE], [0], [0 if you don't want the Buspirate JTAG driver.])\n])\n\nAS_IF([test \"x$use_internal_jimtcl\" = \"xyes\"], [\n  AS_IF([test -f \"$srcdir/jimtcl/configure\"], [\n    AS_IF([test \"x$use_internal_jimtcl_maintainer\" = \"xyes\"], [\n      jimtcl_config_options=\"--disable-install-jim --with-ext=json --minimal --disable-ssl --maintainer\"\n    ], [\n      jimtcl_config_options=\"--disable-install-jim --with-ext=json --minimal --disable-ssl\"\n    ])\n    AX_CONFIG_SUBDIR_OPTION([jimtcl], [$jimtcl_config_options])\n  ], [\n    AC_MSG_ERROR([jimtcl not found, run git submodule init and git submodule update.])\n  ])\n])\n\nAS_IF([test \"x$build_remote_bitbang\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_REMOTE_BITBANG], [1], [1 if you want the Remote Bitbang JTAG driver.])\n], [\n  AC_DEFINE([BUILD_REMOTE_BITBANG], [0], [0 if you don't want the Remote Bitbang JTAG driver.])\n])\n\nAS_IF([test \"x$build_sysfsgpio\" = \"xyes\"], [\n  build_bitbang=yes\n  AC_DEFINE([BUILD_SYSFSGPIO], [1], [1 if you want the SysfsGPIO driver.])\n], [\n  AC_DEFINE([BUILD_SYSFSGPIO], [0], [0 if you don't want SysfsGPIO driver.])\n])\n\nAS_IF([test \"x$build_xlnx_pcie_xvc\" = \"xyes\"], [\n  build_xlnx_pcie_xvc=yes\n  AC_DEFINE([BUILD_XLNX_PCIE_XVC], [1], [1 if you want the Xilinx XVC/PCIe driver.])\n], [\n  AC_DEFINE([BUILD_XLNX_PCIE_XVC], [0], [0 if you don't want Xilinx XVC/PCIe driver.])\n])\n\nPKG_CHECK_MODULES([LIBUSB1], [libusb-1.0], [\n\tuse_libusb1=yes\n\tAC_DEFINE([HAVE_LIBUSB1], [1], [Define if you have libusb-1.x])\n\tLIBUSB1_CFLAGS=`echo $LIBUSB1_CFLAGS | sed 's/-I/-isystem /'`\n\tAC_MSG_NOTICE([libusb-1.0 header bug workaround: LIBUSB1_CFLAGS changed to \"$LIBUSB1_CFLAGS\"])\n\tPKG_CHECK_EXISTS([libusb-1.0 >= 1.0.16],\n\t\t[AC_DEFINE([HAVE_LIBUSB_GET_PORT_NUMBERS], [1], [Define if your libusb has libusb_get_port_numbers()])])\n  ], [\n\tuse_libusb1=no\n\tAC_MSG_WARN([libusb-1.x not found, trying legacy libusb-0.1 as a fallback; consider installing libusb-1.x instead])\n])\n\nAC_ARG_WITH([capstone],\n\t\tAS_HELP_STRING([--with-capstone], [Use Capstone disassembly library (default=auto)])\n\t, [\n\t\tenable_capstone=$withval\n\t], [\n\t\tenable_capstone=auto\n])\n\nAS_IF([test \"x$enable_capstone\" != xno], [\n\tPKG_CHECK_MODULES([CAPSTONE], [capstone], [\n\t\tAC_DEFINE([HAVE_CAPSTONE], [1], [1 if you have Capstone disassembly framework.])\n\t], [\n\t\tif test \"x$enable_capstone\" != xauto; then\n\t\t\tAC_MSG_ERROR([--with-capstone was given, but test for Capstone failed])\n\t\tfi\n\t\tenable_capstone=no\n\t])\n])\n\nAS_IF([test \"x$enable_capstone\" == xno], [\n\tAC_DEFINE([HAVE_CAPSTONE], [0], [0 if you don't have Capstone disassembly framework.])\n])\n\nfor hidapi_lib in hidapi hidapi-hidraw hidapi-libusb; do\n\tPKG_CHECK_MODULES([HIDAPI],[$hidapi_lib],[\n\t\tuse_hidapi=yes\n\t\tbreak\n\t],[\n\t\tuse_hidapi=no\n\t])\ndone\n\nPKG_CHECK_MODULES([LIBFTDI], [libftdi1], [\n\tuse_libftdi=yes\n\tPKG_CHECK_EXISTS([libftdi1 >= 1.5],\n\t\t[AC_DEFINE([HAVE_LIBFTDI_TCIOFLUSH], [1], [Define if your libftdi has ftdi_tcioflush()])])\n  ], [\n\tPKG_CHECK_MODULES([LIBFTDI], [libftdi], [use_libftdi=yes], [use_libftdi=no])\n])\n\nPKG_CHECK_MODULES([LIBGPIOD], [libgpiod], [use_libgpiod=yes], [use_libgpiod=no])\n\nPKG_CHECK_MODULES([LIBJAYLINK], [libjaylink >= 0.2],\n\t[use_libjaylink=yes], [use_libjaylink=no])\n\nm4_define([PROCESS_ADAPTERS], [\n  m4_foreach([adapter], [$1], [\n\tAS_IF([test $2], [\n\t\tAS_IF([test \"x$ADAPTER_VAR([adapter])\" != \"xno\"], [\n\t\t\tAC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [1], [1 if you want the ]ADAPTER_DESC([adapter]).)\n\t\t], [\n\t\t\tAC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [0], [0 if you do not want the ]ADAPTER_DESC([adapter]).)\n\t\t])\n\t], [\n\t\tAS_IF([test \"x$ADAPTER_VAR([adapter])\" = \"xyes\"], [\n\t\t\tAC_MSG_ERROR([$3 is required for the ADAPTER_DESC([adapter])])\n\t\t])\n\t\tADAPTER_VAR([adapter])=no\n\t\tAC_DEFINE([BUILD_]ADAPTER_SYM([adapter]), [0], [0 if you do not want the ]ADAPTER_DESC([adapter]).)\n\t])\n\tAM_CONDITIONAL(ADAPTER_SYM([adapter]), [test \"x$ADAPTER_VAR([adapter])\" != \"xno\"])\n  ])\n])\n\nPROCESS_ADAPTERS([USB1_ADAPTERS], [\"x$use_libusb1\" = \"xyes\"], [libusb-1.x])\nPROCESS_ADAPTERS([HIDAPI_ADAPTERS], [\"x$use_hidapi\" = \"xyes\"], [hidapi])\nPROCESS_ADAPTERS([HIDAPI_USB1_ADAPTERS], [\"x$use_hidapi\" = \"xyes\" -a \"x$use_libusb1\" = \"xyes\"], [hidapi and libusb-1.x])\nPROCESS_ADAPTERS([LIBFTDI_ADAPTERS], [\"x$use_libftdi\" = \"xyes\"], [libftdi])\nPROCESS_ADAPTERS([LIBFTDI_USB1_ADAPTERS], [\"x$use_libftdi\" = \"xyes\" -a \"x$use_libusb1\" = \"xyes\"], [libftdi and libusb-1.x])\nPROCESS_ADAPTERS([LIBGPIOD_ADAPTERS], [\"x$use_libgpiod\" = \"xyes\"], [libgpiod])\nPROCESS_ADAPTERS([LIBJAYLINK_ADAPTERS], [\"x$use_internal_libjaylink\" = \"xyes\" -o \"x$use_libjaylink\" = \"xyes\"], [libjaylink-0.2])\n\nAS_IF([test \"x$enable_linuxgpiod\" != \"xno\"], [\n  build_bitbang=yes\n])\n\nAS_IF([test \"x$enable_stlink\" != \"xno\" -o \"x$enable_ti_icdi\" != \"xno\" -o \"x$enable_nulink\" != \"xno\"], [\n\tAC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the High Level JTAG driver.])\n\tAM_CONDITIONAL([HLADAPTER], [true])\n], [\n\tAC_DEFINE([BUILD_HLADAPTER], [0], [0 if you want the High Level JTAG driver.])\n\tAM_CONDITIONAL([HLADAPTER], [false])\n])\nAM_CONDITIONAL([HLADAPTER_STLINK], [test \"x$enable_stlink\" != \"xno\"])\nAM_CONDITIONAL([HLADAPTER_ICDI], [test \"x$enable_ti_icdi\" != \"xno\"])\nAM_CONDITIONAL([HLADAPTER_NULINK], [test \"x$enable_nulink\" != \"xno\"])\n\nAS_IF([test \"x$enable_jlink\" != \"xno\"], [\n  AS_IF([test \"x$use_internal_libjaylink\" = \"xyes\"], [\n    AS_IF([test -f \"$srcdir/src/jtag/drivers/libjaylink/configure.ac\"], [\n      AX_CONFIG_SUBDIR_OPTION([src/jtag/drivers/libjaylink],\n\t\t[--enable-subproject-build])\n    ], [\n      AC_MSG_ERROR([Internal libjaylink not found, run 'git submodule init' and 'git submodule update'.])\n    ])\n  ])\n])\n\n# Presto needs the bitq module\nAS_IF([test \"x$enable_presto\" != \"xno\"], [\n  build_bitq=yes\n])\n\n# esp-usb-jtag also needs the bitq module\nAS_IF([test \"x$enable_esp_usb_jtag\" != \"xno\"], [\n  build_bitq=yes\n])\n\nAM_CONDITIONAL([RELEASE], [test \"x$build_release\" = \"xyes\"])\nAM_CONDITIONAL([PARPORT], [test \"x$build_parport\" = \"xyes\"])\nAM_CONDITIONAL([DUMMY], [test \"x$build_dummy\" = \"xyes\"])\nAM_CONDITIONAL([GIVEIO], [test \"x$parport_use_giveio\" = \"xyes\"])\nAM_CONDITIONAL([EP93XX], [test \"x$build_ep93xx\" = \"xyes\"])\nAM_CONDITIONAL([AT91RM9200], [test \"x$build_at91rm9200\" = \"xyes\"])\nAM_CONDITIONAL([BCM2835GPIO], [test \"x$build_bcm2835gpio\" = \"xyes\"])\nAM_CONDITIONAL([IMX_GPIO], [test \"x$build_imx_gpio\" = \"xyes\"])\nAM_CONDITIONAL([AM335XGPIO], [test \"x$build_am335xgpio\" = \"xyes\"])\nAM_CONDITIONAL([BITBANG], [test \"x$build_bitbang\" = \"xyes\"])\nAM_CONDITIONAL([JTAG_VPI], [test \"x$build_jtag_vpi\" = \"xyes\"])\nAM_CONDITIONAL([VDEBUG], [test \"x$build_vdebug\" = \"xyes\"])\nAM_CONDITIONAL([JTAG_DPI], [test \"x$build_jtag_dpi\" = \"xyes\"])\nAM_CONDITIONAL([USB_BLASTER_DRIVER], [test \"x$enable_usb_blaster\" != \"xno\" -o \"x$enable_usb_blaster_2\" != \"xno\"])\nAM_CONDITIONAL([AMTJTAGACCEL], [test \"x$build_amtjtagaccel\" = \"xyes\"])\nAM_CONDITIONAL([GW16012], [test \"x$build_gw16012\" = \"xyes\"])\nAM_CONDITIONAL([REMOTE_BITBANG], [test \"x$build_remote_bitbang\" = \"xyes\"])\nAM_CONDITIONAL([BUSPIRATE], [test \"x$enable_buspirate\" != \"xno\"])\nAM_CONDITIONAL([SYSFSGPIO], [test \"x$build_sysfsgpio\" = \"xyes\"])\nAM_CONDITIONAL([XLNX_PCIE_XVC], [test \"x$build_xlnx_pcie_xvc\" = \"xyes\"])\nAM_CONDITIONAL([USE_LIBUSB1], [test \"x$use_libusb1\" = \"xyes\"])\nAM_CONDITIONAL([IS_CYGWIN], [test \"x$is_cygwin\" = \"xyes\"])\nAM_CONDITIONAL([IS_MINGW], [test \"x$is_mingw\" = \"xyes\"])\nAM_CONDITIONAL([IS_WIN32], [test \"x$is_win32\" = \"xyes\"])\nAM_CONDITIONAL([IS_DARWIN], [test \"x$is_darwin\" = \"xyes\"])\nAM_CONDITIONAL([BITQ], [test \"x$build_bitq\" = \"xyes\"])\nAM_CONDITIONAL([USE_LIBFTDI], [test \"x$use_libftdi\" = \"xyes\"])\nAM_CONDITIONAL([USE_LIBGPIOD], [test \"x$use_libgpiod\" = \"xyes\"])\nAM_CONDITIONAL([USE_HIDAPI], [test \"x$use_hidapi\" = \"xyes\"])\nAM_CONDITIONAL([USE_LIBJAYLINK], [test \"x$use_libjaylink\" = \"xyes\"])\nAM_CONDITIONAL([RSHIM], [test \"x$build_rshim\" = \"xyes\"])\nAM_CONDITIONAL([HAVE_CAPSTONE], [test \"x$enable_capstone\" != \"xno\"])\n\nAM_CONDITIONAL([INTERNAL_JIMTCL], [test \"x$use_internal_jimtcl\" = \"xyes\"])\nAM_CONDITIONAL([INTERNAL_LIBJAYLINK], [test \"x$use_internal_libjaylink\" = \"xyes\"])\n\n# Look for environ alternatives.  Possibility #1: is environ in unistd.h or stdlib.h?\nAC_MSG_CHECKING([for environ in unistd.h and stdlib.h])\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM([[\n#define _GNU_SOURCE\n#include <unistd.h>\n#include <stdlib.h>\n  ]], [[char **ep = environ;]]\n  )], [\n    AC_MSG_RESULT([yes])\n    has_environ=yes\n  ], [\n    AC_MSG_RESULT([no])\n\n    # Possibility #2: can environ be found in an available library?\n    AC_MSG_CHECKING([for extern environ])\n    AC_LINK_IFELSE([AC_LANG_PROGRAM([[\n    extern char **environ;\n    ]], [[char **ep = environ;]]\n      )], [\n        AC_DEFINE(NEED_ENVIRON_EXTERN, [1], [Must declare 'environ' to use it.])\n        has_environ=yes\n      ], [\n        has_environ=no\n      ])\n    AC_MSG_RESULT([${has_environ}])\n  ])\n\nAS_IF([test \"x${has_environ}\" != \"xyes\" ], [\n  AC_MSG_FAILURE([Could not find 'environ' in unistd.h or available libraries.])\n])\n\nAC_DEFINE([_GNU_SOURCE],[1],[Use GNU C library extensions (e.g. stdndup).])\n\n# set default gcc warnings\nGCC_WARNINGS=\"-Wall -Wstrict-prototypes -Wformat-security -Wshadow\"\nAS_IF([test \"x${gcc_wextra}\" = \"xyes\"], [\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wextra -Wno-unused-parameter\"\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wbad-function-cast\"\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wcast-align\"\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wredundant-decls\"\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wpointer-arith\"\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Wundef\"\n])\nAS_IF([test \"x${gcc_werror}\" = \"xyes\"], [\n  GCC_WARNINGS=\"${GCC_WARNINGS} -Werror\"\n])\n\n# override default gcc cflags\nAS_IF([test \"x$gcc_warnings\" = \"xyes\"], [\n  AC_SUBST([GCC_WARNINGS], [$GCC_WARNINGS])\n])\n\nAC_SUBST(EXTRA_DIST_NEWS, [\"$(echo $srcdir/NEWS-*)\"])\n\nAC_CONFIG_FILES([\n  Makefile\n])\nAC_OUTPUT\n\nAS_IF([test \"x$enable_jlink\" != \"xno\"], [\n  AS_IF([test \"x$use_internal_libjaylink\" = \"xyes\"], [\n    AC_MSG_WARN([Using the internal libjaylink is deprecated and will not be possible in the future.])\n  ]])\n)\n\necho\necho\necho OpenOCD configuration summary\necho --------------------------------------------------\nm4_foreach([adapter], [USB1_ADAPTERS,\n\tHIDAPI_ADAPTERS, HIDAPI_USB1_ADAPTERS, LIBFTDI_ADAPTERS,\n\tLIBFTDI_USB1_ADAPTERS,\n\tLIBGPIOD_ADAPTERS,\n\tLIBJAYLINK_ADAPTERS, PCIE_ADAPTERS, SERIAL_PORT_ADAPTERS,\n\tOPTIONAL_LIBRARIES],\n\t[s=m4_format([\"%-40s\"], ADAPTER_DESC([adapter]))\n\tAS_CASE([$ADAPTER_VAR([adapter])],\n\t\t[auto], [\n\t\t\techo \"$s\"yes '(auto)'\n\t\t],\n\t\t[yes], [\n\t\t\techo \"$s\"yes\n\t\t],\n\t\t[no], [\n\t\t\techo \"$s\"no\n\t])\n])\necho\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/60-openocd.rules",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Copy this file to /etc/udev/rules.d/\n# If rules fail to reload automatically, you can refresh udev rules\n# with the command \"udevadm control --reload\"\n\nACTION!=\"add|change\", GOTO=\"openocd_rules_end\"\n\nSUBSYSTEM==\"gpio\", MODE=\"0660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nSUBSYSTEM!=\"usb|tty|hidraw\", GOTO=\"openocd_rules_end\"\n\n# Please keep this list sorted by VID:PID\n\n# opendous and estick\nATTRS{idVendor}==\"03eb\", ATTRS{idProduct}==\"204f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232/FT245 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT2232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT4232 VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Original FT232H VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Original FT231XQ VID:PID\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"6015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# DISTORTEC JTAG-lock-pick Tiny 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8220\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TUMPA, TUMPA Lite\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a98\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"8a99\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell OpenRD JTAGKey FT2232D B\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"9e90\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# XDS100v2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# XDS100v3\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"a6d1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OOCDLink\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"baf8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Kristech KT-Link\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bbe2\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Xverve Signalyzer Tool (DT-USB-ST), Signalyzer LITE (DT-USB-SLITE)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bca1\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris Evaluation Board FTDI (several)\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcd9\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface FTDI (ICDI) Board\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bcda\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# egnite Turtelizer 2\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"bdc8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Section5 ICEbear\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c140\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"c141\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey and JTAGkey-tiny\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"cff8\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ASIX Presto programmer\nATTRS{idVendor}==\"0403\", ATTRS{idProduct}==\"f1a0\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Nuvoton NuLink\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"511d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5200\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"5201\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI ICDI\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"c32a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK V1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3744\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3748\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics ST-LINK/V2.1\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3752\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# STMicroelectronics STLINK-V3\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"374f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3753\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3754\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3755\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"3757\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress SuperSpeed Explorer Kit\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"0007\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in KitProg mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f139\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Cypress KitProg in CMSIS-DAP mode\nATTRS{idVendor}==\"04b4\", ATTRS{idProduct}==\"f138\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Infineon DAP miniWiggler v3\nATTRS{idVendor}==\"058b\", ATTRS{idProduct}==\"0043\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex LPC1768-Stick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0026\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hilscher NXHX Boards\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0028\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STR9-comStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002c\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex STM32-PerformanceStick\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"002d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Hitex Cortino\nATTRS{idVendor}==\"0640\", ATTRS{idProduct}==\"0032\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Altera USB Blaster\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n# Altera USB Blaster2\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"09fb\", ATTRS{idProduct}==\"6810\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ashling Opella-LD\nATTRS{idVendor}==\"0B6B\", ATTRS{idProduct}==\"0040\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Amontec JTAGkey-HiSpeed\nATTRS{idVendor}==\"0fbb\", ATTRS{idProduct}==\"1000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# SEGGER J-Link\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0101\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0102\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0103\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0104\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0105\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0107\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"0108\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1012\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1013\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1014\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1015\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1016\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1017\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1018\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1020\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1051\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1055\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1366\", ATTRS{idProduct}==\"1061\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Raisonance RLink\nATTRS{idVendor}==\"138e\", ATTRS{idProduct}==\"9000\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Debug Board for Neo1973\nATTRS{idVendor}==\"1457\", ATTRS{idProduct}==\"5118\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# OSBDM\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0042\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"0058\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"15a2\", ATTRS{idProduct}==\"005e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0003\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"0004\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-JTAG-EW\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"001e\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-TINY-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002a\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Olimex ARM-USB-OCD-H\nATTRS{idVendor}==\"15ba\", ATTRS{idProduct}==\"002b\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC\nATTRS{idVendor}==\"16c0\", ATTRS{idProduct}==\"06ad\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# USBprog with OpenOCD firmware\nATTRS{idVendor}==\"1781\", ATTRS{idProduct}==\"0c63\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI/Luminary Stellaris In-Circuit Debug Interface (ICDI) Board\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00fd\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI XDS110 Debug Probe (Launchpads and Standalone)\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef3\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"0451\", ATTRS{idProduct}==\"bef4\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"02a5\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# TI Tiva-based ICDI and XDS110 probes in DFU mode\nATTRS{idVendor}==\"1cbe\", ATTRS{idProduct}==\"00ff\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# isodebug v1\nATTRS{idVendor}==\"22b7\", ATTRS{idProduct}==\"150d\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# PLS USB/JTAG Adapter for SPC5xxx\nATTRS{idVendor}==\"263d\", ATTRS{idProduct}==\"4001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Numato Mimas A7 - Artix 7 FPGA Board\nATTRS{idVendor}==\"2a19\", ATTRS{idProduct}==\"1009\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Ambiq Micro EVK and Debug boards.\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6010\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"6011\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"2aec\", ATTRS{idProduct}==\"1106\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Espressif USB JTAG/serial debug units\nATTRS{idVendor}==\"303a\", ATTRS{idProduct}==\"1001\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"303a\", ATTRS{idProduct}==\"1002\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Marvell Sheevaplug\nATTRS{idVendor}==\"9e88\", ATTRS{idProduct}==\"9e8f\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# Keil Software, Inc. ULink\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2710\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\nATTRS{idVendor}==\"c251\", ATTRS{idProduct}==\"2750\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\n# CMSIS-DAP compatible adapters\nATTRS{product}==\"*CMSIS-DAP*\", MODE=\"660\", GROUP=\"plugdev\", TAG+=\"uaccess\"\n\nLABEL=\"openocd_rules_end\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/buildroot/openocd_be_defconfig",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nBR2_armeb=y\nBR2_cortex_a7=y\nBR2_TOOLCHAIN_EXTERNAL=y\nBR2_PACKAGE_OPENOCD=y\nBR2_PACKAGE_OPENOCD_FTDI=y\nBR2_PACKAGE_OPENOCD_STLINK=y\nBR2_PACKAGE_OPENOCD_TI_ICDI=y\nBR2_PACKAGE_OPENOCD_ULINK=y\nBR2_PACKAGE_OPENOCD_UBLASTER2=y\nBR2_PACKAGE_OPENOCD_JLINK=y\nBR2_PACKAGE_OPENOCD_OSDBM=y\nBR2_PACKAGE_OPENOCD_OPENDOUS=y\nBR2_PACKAGE_OPENOCD_VSLLINK=y\nBR2_PACKAGE_OPENOCD_USBPROG=y\nBR2_PACKAGE_OPENOCD_RLINK=y\nBR2_PACKAGE_OPENOCD_ARMEW=y\nBR2_PACKAGE_OPENOCD_XDS110=y\nBR2_PACKAGE_OPENOCD_PARPORT=y\nBR2_PACKAGE_OPENOCD_VPI=y\nBR2_PACKAGE_OPENOCD_UBLASTER=y\nBR2_PACKAGE_OPENOCD_AMTJT=y\nBR2_PACKAGE_OPENOCD_GW16012=y\nBR2_PACKAGE_OPENOCD_PRESTO=y\nBR2_PACKAGE_OPENOCD_OPENJTAG=y\nBR2_PACKAGE_OPENOCD_BUSPIRATE=y\nBR2_PACKAGE_OPENOCD_SYSFS=y\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/coresight-trace.txt",
    "content": "+OpenOCD and CoreSight Tracing\n+\nMany recent ARM chips  (Using e..g. Cortex-M3 and\nCortex-M4 cores) support CoreSight debug/trace.\nThis note sketches an approach currently planned for those cores\nwith OpenOCD.\n\n This tracing data can help debug and tune ARM software, but not\nall cores support tracing.  Some support more extensive tracing\nother cores with trace support +should be able to use the same\napproach and maybe some of the same analysis code.\n\n+the Cortex-M3 is assumed here to be the\n+core in use, for simplicity and to reflect current OpenOCD users.\n\n\nThis note summarizes a software model to generate, collect, and\nanalyze such trace data .  That is not fully implemented as of early\nJanuary 2011, +and thus is not *yet* usable.\n+\n+\n+Some microcontroller cores support a low pin-count Single-wire trace,\nwith a mode where +trace data is emitted (usually to a UART.  To use\nthis mode, +SWD must be in use.\n+At this writing, OpenOCD SWD support is not yet complete either.\n\n(There are also multi-wire trace ports requiring more complex debug\nadapters than OpenOCD currently supports, and offering richer data.\n+\n+\n+* ENABLING involves activating  SWD and (single wire) trace.\n+\n+current expectations are that OpenOCD itself will handle enabling;\nactivating single wire trace involves a debug adapter interaction, and\ncollecting that trace data requires particular (re)wiring.\n+\n+* CONFIGURATION involves setting up ITM  and/or ETM modules to emit the\n+desired data from the Cortex core.  (This might include dumping\n+event counters printf-style messages; code profiling; and more.  Not all\n+cores offer the same trace capabilities.\n+\n+current expectations are that Tcl scripts will be used to configure these\n+modules for the desired tracing, by direct writes to registers.  In some\n+cases (as with RTOS event tracking and similar messaging, this might\n+be  augmented or replaced by user code running on the ARM core.\n+\n+COLLECTION involves reading that trace data, probably through UART, and\n+saving it in a useful format to analyse  For now, deferred analysis modes\nare assumed, not than real-time or interactive ones.\n+\n+\n+current expectations are to to dump data in text using contrib/itmdump.c\n+or derived tools, and to post-process it into reports.  Such reports might\n+include program messaging (such as application data streams via ITM, maybe\n+using printf type messaging; code coverage analysis or so forth.  Recent\n+versions of CMSIS software reserve some ITM codespace for RTOS  event\ntracing and include ITM messaging support.\nClearly some of that data would be valuable for interactive debugging.\n+\n+Should someone get ambitious, GUI reports should be possible.  GNU tools\n+for simpler reports like gprof may be simpler to support at first.\n+In any case, OpenOCD is not currently GUI-oriented.  Accordingly, we now\n+expect any such graphics to come from postprocessing.\n\n measurements for RTOS event timings should also be easy to collect.\n+Examples include context and message switch times, as well as times\nfor application interactions.\n+\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/cross-build.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an example of how to do a cross-build of OpenOCD using pkg-config.\n# Cross-building with pkg-config is deceptively hard and most guides and\n# tutorials are incomplete or give bad advice. Some of the traps that are easy\n# to fall in but handled by this script are:\n#\n#  * Polluting search paths and flags with values from the build system.\n#  * Faulty pkg-config wrappers shipped with distribution packaged cross-\n#    toolchains.\n#  * Build failing because pkg-config discards some paths even though they are\n#    correctly listed in the .pc file.\n#  * Getting successfully built binaries that cannot find runtime data because\n#    paths refer to the build file system.\n#\n# This script is probably more useful as a reference than as a complete build\n# tool but for some configurations it may be usable as-is. It only cross-builds\n# libusb-1.0, hidapi, libftdi and capstone from source, but the script can be\n# extended to build other prerequisites in a similar manner.\n#\n# Usage:\n# export LIBUSB1_SRC=/path/to/libusb-1.0\n# export HIDAPI_SRC=/path/to/hidapi\n# export OPENOCD_CONFIG=\"--enable-...\"\n# cd /work/dir\n# /path/to/openocd/contrib/cross-build.sh <host-triplet>\n#\n# For static linking, a workaround is to\n# export LIBUSB1_CONFIG=\"--enable-static --disable-shared\"\n#\n# All the paths must not contain any spaces.\n\nset -e -x\n\nWORK_DIR=$PWD\n\n## Source code paths, customize as necessary\n: ${OPENOCD_SRC:=\"`dirname \"$0\"`/..\"}\n: ${LIBUSB1_SRC:=/path/to/libusb1}\n: ${HIDAPI_SRC:=/path/to/hidapi}\n: ${LIBFTDI_SRC:=/path/to/libftdi}\n: ${CAPSTONE_SRC:=/path/to/capstone}\n: ${LIBJAYLINK_SRC:=/path/to/libjaylink}\n\nOPENOCD_SRC=`readlink -m $OPENOCD_SRC`\nLIBUSB1_SRC=`readlink -m $LIBUSB1_SRC`\nHIDAPI_SRC=`readlink -m $HIDAPI_SRC`\nLIBFTDI_SRC=`readlink -m $LIBFTDI_SRC`\nCAPSTONE_SRC=`readlink -m $CAPSTONE_SRC`\nLIBJAYLINK_SRC=`readlink -m $LIBJAYLINK_SRC`\n\nHOST_TRIPLET=$1\nBUILD_DIR=$WORK_DIR/$HOST_TRIPLET-build\nLIBUSB1_BUILD_DIR=$BUILD_DIR/libusb1\nHIDAPI_BUILD_DIR=$BUILD_DIR/hidapi\nLIBFTDI_BUILD_DIR=$BUILD_DIR/libftdi\nCAPSTONE_BUILD_DIR=$BUILD_DIR/capstone\nLIBJAYLINK_BUILD_DIR=$BUILD_DIR/libjaylink\nOPENOCD_BUILD_DIR=$BUILD_DIR/openocd\n\n## Root of host file tree\nSYSROOT=$WORK_DIR/$HOST_TRIPLET-root\n\n## Install location within host file tree\n: ${PREFIX=/usr}\n\n## Make parallel jobs\n: ${MAKE_JOBS:=1}\n\n## OpenOCD-only install dir for packaging\n: ${OPENOCD_TAG:=`git --git-dir=$OPENOCD_SRC/.git describe --tags`}\nPACKAGE_DIR=$WORK_DIR/openocd_${OPENOCD_TAG}_${HOST_TRIPLET}\n\n#######\n\n# Create pkg-config wrapper and make sure it's used\nexport PKG_CONFIG=$WORK_DIR/$HOST_TRIPLET-pkg-config\n\ncat > $PKG_CONFIG <<EOF\n#!/bin/sh\n\nSYSROOT=$SYSROOT\n\nexport PKG_CONFIG_DIR=\nexport PKG_CONFIG_LIBDIR=\\${SYSROOT}$PREFIX/lib/pkgconfig:\\${SYSROOT}$PREFIX/share/pkgconfig\nexport PKG_CONFIG_SYSROOT_DIR=\\${SYSROOT}\n\n# The following have to be set to avoid pkg-config to strip /usr/include and /usr/lib from paths\n# before they are prepended with the sysroot path. Feels like a pkg-config bug.\nexport PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=\nexport PKG_CONFIG_ALLOW_SYSTEM_LIBS=\n\nexec pkg-config \"\\$@\"\nEOF\nchmod +x $PKG_CONFIG\n\n# Clear out work dir\nrm -rf $SYSROOT $BUILD_DIR\nmkdir -p $SYSROOT\n\n# libusb-1.0 build & install into sysroot\nif [ -d $LIBUSB1_SRC ] ; then\n  mkdir -p $LIBUSB1_BUILD_DIR\n  cd $LIBUSB1_BUILD_DIR\n  $LIBUSB1_SRC/configure --build=`$LIBUSB1_SRC/config.guess` --host=$HOST_TRIPLET \\\n  --with-sysroot=$SYSROOT --prefix=$PREFIX \\\n  $LIBUSB1_CONFIG\n  make -j $MAKE_JOBS\n  make install DESTDIR=$SYSROOT\nfi\n\n# hidapi build & install into sysroot\nif [ -d $HIDAPI_SRC ] ; then\n  mkdir -p $HIDAPI_BUILD_DIR\n  cd $HIDAPI_BUILD_DIR\n  $HIDAPI_SRC/configure --build=`$HIDAPI_SRC/config.guess` --host=$HOST_TRIPLET \\\n    --with-sysroot=$SYSROOT --prefix=$PREFIX \\\n    $HIDAPI_CONFIG\n  make -j $MAKE_JOBS\n  make install DESTDIR=$SYSROOT\nfi\n\n# libftdi build & install into sysroot\nif [ -d $LIBFTDI_SRC ] ; then\n  mkdir -p $LIBFTDI_BUILD_DIR\n  cd $LIBFTDI_BUILD_DIR\n  # note : libftdi versions < 1.5 requires libusb1 static\n  #   hint use : # export LIBUSB1_CONFIG=\"--enable-static ...\"\n  #   not needed since libftdi-1.5 when LIBFTDI_CONFIG=\"-DSTATICLIBS=OFF ...\"\n\n  # fix <toolchain>.cmake file\n  ESCAPED_SYSROOT=$(printf '%s\\n' \"$SYSROOT\" | sed -e 's/[\\/&]/\\\\&/g')\n  sed -i -E \"s/(SET\\(CMAKE_FIND_ROOT_PATH\\s+).+\\)/\\1${ESCAPED_SYSROOT})/\" \\\n    ${LIBFTDI_SRC}/cmake/Toolchain-${HOST_TRIPLET}.cmake\n\n  cmake $LIBFTDI_CONFIG \\\n    -DCMAKE_TOOLCHAIN_FILE=${LIBFTDI_SRC}/cmake/Toolchain-${HOST_TRIPLET}.cmake \\\n    -DCMAKE_INSTALL_PREFIX=${PREFIX} \\\n    -DPKG_CONFIG_EXECUTABLE=`which pkg-config` \\\n    $LIBFTDI_SRC\n  make install DESTDIR=$SYSROOT\nfi\n\n# capstone build & install into sysroot\nif [ -d $CAPSTONE_SRC ] ; then\n  mkdir -p $CAPSTONE_BUILD_DIR\n  cd $CAPSTONE_BUILD_DIR\n  cp -r $CAPSTONE_SRC/* .\n  make install DESTDIR=$SYSROOT PREFIX=$PREFIX \\\n    CROSS=\"${HOST_TRIPLET}-\" \\\n    $CAPSTONE_CONFIG\n  # fix the generated capstone.pc\n  CAPSTONE_PC_FILE=${SYSROOT}${PREFIX}/lib/pkgconfig/capstone.pc\n  sed -i '/^libdir=/d' $CAPSTONE_PC_FILE\n  sed -i '/^includedir=/d' $CAPSTONE_PC_FILE\n  sed -i '/^archive=/d' $CAPSTONE_PC_FILE\n  sed -i '1s;^;prefix=/usr \\\nexec_prefix=${prefix} \\\nlibdir=${exec_prefix}/lib \\\nincludedir=${prefix}/include/capstone\\n\\n;' $CAPSTONE_PC_FILE\nfi\n\n# libjaylink build & install into sysroot\nif [ -d $LIBJAYLINK_SRC ] ; then\n  mkdir -p $LIBJAYLINK_BUILD_DIR\n  cd $LIBJAYLINK_BUILD_DIR\n  $LIBJAYLINK_SRC/configure --build=`$LIBJAYLINK_SRC/config.guess` --host=$HOST_TRIPLET \\\n    --with-sysroot=$SYSROOT --prefix=$PREFIX \\\n    $LIBJAYLINK_CONFIG\n  make -j $MAKE_JOBS\n  make install DESTDIR=$SYSROOT\nfi\n\n# OpenOCD build & install into sysroot\nmkdir -p $OPENOCD_BUILD_DIR\ncd $OPENOCD_BUILD_DIR\n$OPENOCD_SRC/configure --build=`$OPENOCD_SRC/config.guess` --host=$HOST_TRIPLET \\\n--with-sysroot=$SYSROOT --prefix=$PREFIX \\\n$OPENOCD_CONFIG\nmake -j $MAKE_JOBS\nmake install-strip DESTDIR=$SYSROOT\n\n# Separate OpenOCD install w/o dependencies. OpenOCD will have to be linked\n# statically or have dependencies packaged/installed separately.\nmake install-strip DESTDIR=$PACKAGE_DIR\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/gen-stellaris-part-header.pl",
    "content": "#!/usr/bin/perl\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Automatically generates the StellarisParts struct in src/flash/nor/stellaris.c\n# Uses the header files from TI/Luminary's StellarisWare complete Firmware Development Package\n# available from: http://www.luminarymicro.com/products/software_updates.html\n\n$comment = \"// Autogenerated by contrib/gen-stellaris-part-header.pl\n// From Stellaris Firmware Development Package revision\";\n\n$struct_header = \"static const struct {\n\tuint8_t class;\n\tuint8_t partno;\n\tconst char *partname;\n} StellarisParts[] = {\n\";\n\n$struct_footer = \"\\t{0xFF, 0x00, \\\"Unknown Part\\\"}\\n};\\n\";\n\n$#ARGV == 1 || die \"Usage: $0 <inc directory> <output file>\\n\";\n-d $ARGV[0] || die $ARGV[0].\" is not a directory\\n\";\n$dir = $ARGV[0];\n-f $ARGV[1] || die $ARGV[1].\" is not a file\\n\";\n$file = $ARGV[1];\nprint STDERR \"Scanning $dir, Updating $file\\n\";\n\nopendir(DIR, $dir) || die \"can't open $dir: $!\";\n@files = readdir(DIR);\nclosedir(DIR);\n\n@header_files = sort(grep(/lm.+\\.h/, @files));\n\n$ver = 0;\n$new_struct = $struct_header;\nprocess_file(@header_files);\n$new_struct .= $struct_footer;\n\n$dump = \"$comment $ver\\n$new_struct\";\n{\n\tlocal($/, *INPUT);\n\topen(INPUT, $file) || die \"can't open $file: $!\";\n\t$contents = <INPUT>;\n\tclose(INPUT);\n}\n\n$old_struct = qr/((^\\/\\/.*?\\n)*)\\Q$struct_header\\E.*?$struct_footer/sm;\n$contents =~ s/$old_struct/$dump/;\nopen(OUTPUT, \">$file\") || die \"can't open file $file for writing: $!\";\nprint OUTPUT $contents;\nclose(OUTPUT);\n\nsub process_file {\n\tforeach $h_file (@_) {\n\t\t($base) = ($h_file =~ m/lm..(.{3,7})\\.h/ig);\n\t\t$base = uc($base);\n\t\tlocal($/, *FILE);\n\t\topen(FILE, \"$dir/$h_file\");\n\t\t$content = <FILE>;\n\t\tclose(FILE);\n\t\t$invalid = 0;\n\t\tif ($content =~ /This is part of revision (\\d+) of/) {\n\t\t\tif ($ver != 0 and $ver != $1) {\n\t\t\t\tprint STDERR \"File version mismatch: $ver != $1\\n\";\n\t\t\t\t$ver = max($ver, $1);\n\t\t\t} else {\n\t\t\t\t$ver = $1;\n\t\t\t}\n\t\t}\n\n\t\tif ($content =~ /SYSCTL_DID0_CLASS_[^M].+?0x(\\S+)/s) {\n\t\t\t$class = hex($1) >> 16;\n\t\t} else {\n\t\t\t# attempt another way to get class\n\t\t\tif ($content =~ /\\s(\\S+)-class/) {\n\t\t\t\t$class = getclass($1);\n\t\t\t\tif ($class eq 0xFF) {\n\t\t\t\t\tprint STDERR \"$h_file unknown class\\n\";\n\t\t\t\t\t$invalid = 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprint STDERR \"$h_file is missing SYSCTL_DID0_CLASS_\\n\";\n\t\t\t\t$class = 0;\n\t\t\t\t$invalid = 1;\n\t\t\t}\n\t\t}\n\n\t\tif ($content =~ /SYSCTL_DID1_PRTNO_$base.+0x(\\S+)/) {\n\t\t\t$prtno = hex($1);\n\t\t\t$base = \"LM3S\" . $base;\n\t\t} else {\n\t\t\t# LM4F have a changed header\n\t\t\tif ($content =~ /SYSCTL_DID1_PRTNO_LM4F$base.+?0x(\\S+)/s) {\n\t\t\t\t$prtno = hex($1);\n\t\t\t\t$base = \"LM4F\" . $base;\n\t\t\t} else {\n\t\t\t\tprint STDERR \"$h_file is missing SYSCTL_DID1_PRTNO\\n\";\n\t\t\t\t$prtno = 0;\n\t\t\t\t$invalid = 1;\n\t\t\t}\n\t\t}\n\t\t$new_member = sprintf \"{0x%02X, 0x%02X, \\\"%s\\\"},\", $class, $prtno >> 16, $base;\n\t\tif ($invalid == 1) {\n\t\t\t#$new_struct .= \"\\t//$new_member\\t// Invalid\\n\";\n\t\t} else {\n\t\t\t$new_struct .= \"\\t$new_member\\n\";\n\t\t}\n\t}\n}\n\nsub getclass {\n\t$class = $_[0];\n\tif ($class =~ /Sandstorm/i) {\n\t\treturn 0;\n\t} elsif ($class =~ /Fury/i) {\n\t\treturn 1;\n\t} elsif ($class =~ /DustDevil/i) {\n\t\treturn 3;\n\t} elsif ($class =~ /Tempest/i) {\n\t\treturn 4;\n\t} elsif ($class =~ /Blizzard/i) {\n\t\treturn 5;\n\t} elsif ($class =~ /Firestorm/i) {\n\t\treturn 6;\n\t}\n\treturn 0xFF;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/itmdump.c",
    "content": "// SPDX-License-Identifier: GPL-3.0-or-later\n\n/* Copyright (C) 2010 by David Brownell */\n\n/*\n * Simple utility to parse and dump ARM Cortex-M3 SWO trace output.  Once the\n * mechanisms work right, this information can be used for various purposes\n * including profiling (particularly easy for flat PC-sample profiles) and\n * for debugging.\n *\n * SWO is the Single Wire Output found on some ARM cores, most notably on the\n * Cortex-M3.  It combines data from several sources:\n *\n *  - Software trace (ITM):  so-called \"printf-style\" application messaging\n *    using \"ITM stimulus ports\"; and differential timestamps.\n *  - Hardware trace (DWT):  for profiling counters and comparator matches.\n *  - TPIU may issue sync packets.\n *\n * The trace data format is defined in Appendix E, \"Debug ITM and DWT packet\n * protocol\", of the ARMv7-M Architecture Reference Manual (DDI 0403C).  It\n * is a superset of the ITM data format from the Coresight TRM.\n *\n * The trace data has two encodings.  The working assumption is that data\n * gets into this program using the UART encoding.\n */\n\n#include <errno.h>\n#include <libgen.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\nunsigned int dump_swit;\n\n/* Example ITM trace word (0xWWXXYYZZ) parsing for task events, sent\n * on port 31 (Reserved for \"the\" RTOS in CMSIS v1.30)\n *   WWXX: event code (0..3 pre-assigned, 4..15 reserved)\n *   YY:   task priority\n *   ZZ:   task number\n *\n * NOTE that this specific encoding could be space-optimized; and that\n * trace data streams could also be history-sensitive.\n */\nstatic void show_task(int port, unsigned data)\n{\n\tunsigned code = data >> 16;\n\tchar buf[16];\n\n\tif (dump_swit)\n\t\treturn;\n\n\tswitch (code) {\n\tcase 0:\n\t\tstrcpy(buf, \"run\");\n\t\tbreak;\n\tcase 1:\n\t\tstrcpy(buf, \"block\");\n\t\tbreak;\n\tcase 2:\n\t\tstrcpy(buf, \"create\");\n\t\tbreak;\n\tcase 3:\n\t\tstrcpy(buf, \"destroy\");\n\t\tbreak;\n\t/* 4..15 reserved for other infrastructure ops */\n\tdefault:\n\t\tsprintf(buf, \"code %d\", code);\n\t\tbreak;\n\t}\n\tprintf(\"TASK %d, pri %d: %s\",\n\t\t(data >> 0) & 0xff,\n\t\t(data >> 8) & 0xff,\n\t\tbuf);\n}\n\nstatic void show_reserved(FILE *f, char *label, int c)\n{\n\tunsigned i;\n\n\tif (dump_swit)\n\t\treturn;\n\n\tprintf(\"%s - %#02x\", label, c);\n\n\tfor (i = 0; (c & 0x80) && i < 4; i++) {\n\t\tc = fgetc(f);\n\t\tif (c == EOF) {\n\t\t\tprintf(\"(ERROR %d - %s) \", errno, strerror(errno));\n\t\t\tbreak;\n\t\t}\n\t\tprintf(\" %#02x\", c);\n\t}\n\n\tprintf(\"\\n\");\n}\n\nstatic bool read_varlen(FILE *f, int c, unsigned *value)\n{\n\tunsigned size;\n\tunsigned char buf[4];\n\n\t*value = 0;\n\n\tswitch (c & 3) {\n\tcase 3:\n\t\tsize = 4;\n\t\tbreak;\n\tcase 2:\n\t\tsize = 2;\n\t\tbreak;\n\tcase 1:\n\t\tsize = 1;\n\t\tbreak;\n\tdefault:\n\t\tprintf(\"INVALID SIZE\\n\");\n\t\treturn false;\n\t}\n\n\tmemset(buf, 0, sizeof buf);\n\tif (fread(buf, 1, size, f) != size)\n\t\tgoto err;\n\n\t*value =  (buf[3] << 24)\n\t\t+ (buf[2] << 16)\n\t\t+ (buf[1] << 8)\n\t\t+ (buf[0] << 0);\n\treturn true;\n\nerr:\n\tprintf(\"(ERROR %d - %s)\\n\", errno, strerror(errno));\n\treturn false;\n}\n\nstatic void show_hard(FILE *f, int c)\n{\n\tunsigned type = c >> 3;\n\tunsigned value;\n\tchar *label;\n\n\tif (dump_swit)\n\t\treturn;\n\n\tprintf(\"DWT - \");\n\n\tif (!read_varlen(f, c, &value))\n\t\treturn;\n\tprintf(\"%#x\", value);\n\n\tswitch (type) {\n\tcase 0:\t\t\t\t/* event counter wrapping */\n\t\tprintf(\"overflow %s%s%s%s%s%s\",\n\t\t\t(value & (1 << 5)) ? \"cyc \" : \"\",\n\t\t\t(value & (1 << 4)) ? \"fold \" : \"\",\n\t\t\t(value & (1 << 3)) ? \"lsu \" : \"\",\n\t\t\t(value & (1 << 2)) ? \"slp \" : \"\",\n\t\t\t(value & (1 << 1)) ? \"exc \" : \"\",\n\t\t\t(value & (1 << 0)) ? \"cpi \" : \"\");\n\t\tbreak;\n\tcase 1:\t\t\t\t/* exception tracing */\n\t\tswitch (value >> 12) {\n\t\tcase 1:\n\t\t\tlabel = \"entry to\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tlabel = \"exit from\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tlabel = \"return to\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tlabel = \"?\";\n\t\t\tbreak;\n\t\t}\n\t\tprintf(\"%s exception %d\", label, value & 0x1ff);\n\t\tbreak;\n\tcase 2:\t\t\t\t/* PC sampling */\n\t\tif (c == 0x15)\n\t\t\tprintf(\"PC - sleep\");\n\t\telse\n\t\t\tprintf(\"PC - %#08x\", value);\n\t\tbreak;\n\tcase 8:\t\t\t\t/* data tracing, pc value */\n\tcase 10:\n\tcase 12:\n\tcase 14:\n\t\tprintf(\"Data trace %d, PC %#08x\", (c >> 4) & 3, value);\n\t\t/* optionally followed by data value */\n\t\tbreak;\n\tcase 9:\t\t\t\t/* data tracing, address offset */\n\tcase 11:\n\tcase 13:\n\tcase 15:\n\t\tprintf(\"Data trace %d, address offset %#04x\",\n\t\t\t\t(c >> 4) & 3, value);\n\t\t/* always followed by data value */\n\t\tbreak;\n\tcase 16 ... 23:\t\t\t/* data tracing, data value */\n\t\tprintf(\"Data trace %d, \", (c >> 4) & 3);\n\t\tlabel = (c & 0x8) ? \"write\" : \"read\";\n\t\tswitch (c & 3) {\n\t\tcase 3:\n\t\t\tprintf(\"word %s, value %#08x\", label, value);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tprintf(\"halfword %s, value %#04x\", label, value);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tprintf(\"byte %s, value %#02x\", label, value);\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tprintf(\"UNDEFINED, rawtype: %x\", type);\n\t\tbreak;\n\t}\n\n\tprintf(\"\\n\");\n\treturn;\n}\n\n/*\n * Table of SWIT (SoftWare InstrumentTation) message dump formats, for\n * ITM port 0..31 application data.\n *\n * Eventually this should be customizable; all usage is application defined.\n *\n * REVISIT there can be up to 256 trace ports, via \"ITM Extension\" packets\n */\nstruct {\n\tint port;\n\tvoid (*show)(int port, unsigned data);\n} format[] = {\n\t{ .port = 31,  .show = show_task, },\n};\n\nstatic void show_swit(FILE *f, int c)\n{\n\tunsigned port = c >> 3;\n\tunsigned value = 0;\n\tunsigned i;\n\n\tif (port + 1 == dump_swit) {\n\t\tif (!read_varlen(f, c, &value))\n\t\t\treturn;\n\t\tprintf(\"%c\", value);\n\t\treturn;\n\t}\n\n\tif (!read_varlen(f, c, &value))\n\t\treturn;\n\n\tif (dump_swit)\n\t\treturn;\n\n\tprintf(\"SWIT %u - \", port);\n\n\tprintf(\"%#08x\", value);\n\n\tfor (i = 0; i < sizeof(format) / sizeof(format[0]); i++) {\n\t\tif (format[i].port == port) {\n\t\t\tprintf(\", \");\n\t\t\tformat[i].show(port, value);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tprintf(\"\\n\");\n\treturn;\n}\n\nstatic void show_timestamp(FILE *f, int c)\n{\n\tunsigned counter = 0;\n\tchar *label = \"\";\n\tbool delayed = false;\n\n\tif (dump_swit)\n\t\treturn;\n\n\tprintf(\"TIMESTAMP - \");\n\n\t/* Format 2: header only */\n\tif (!(c & 0x80)) {\n\t\tswitch (c) {\n\t\tcase 0:\t\t/* sync packet -- coding error! */\n\t\tcase 0x70:\t/* overflow -- ditto! */\n\t\t\tprintf(\"ERROR - %#02x\\n\", c);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* synchronous to ITM */\n\t\t\tcounter = c >> 4;\n\t\t\tgoto done;\n\t\t}\n\t\treturn;\n\t}\n\n\t/* Format 1:  one to four bytes of data too */\n\tswitch (c >> 4) {\n\tdefault:\n\t\tlabel = \", reserved control\\n\";\n\t\tbreak;\n\tcase 0xc:\n\t\t/* synchronous to ITM */\n\t\tbreak;\n\tcase 0xd:\n\t\tlabel = \", timestamp delayed\";\n\t\tdelayed = true;\n\t\tbreak;\n\tcase 0xe:\n\t\tlabel = \", packet delayed\";\n\t\tdelayed = true;\n\t\tbreak;\n\tcase 0xf:\n\t\tlabel = \", packet and timestamp delayed\";\n\t\tdelayed = true;\n\t\tbreak;\n\t}\n\n\tc = fgetc(f);\n\tif (c == EOF)\n\t\tgoto err;\n\tcounter = c & 0x7f;\n\tif (!(c & 0x80))\n\t\tgoto done;\n\n\tc = fgetc(f);\n\tif (c == EOF)\n\t\tgoto err;\n\tcounter |= (c & 0x7f) << 7;\n\tif (!(c & 0x80))\n\t\tgoto done;\n\n\tc = fgetc(f);\n\tif (c == EOF)\n\t\tgoto err;\n\tcounter |= (c & 0x7f) << 14;\n\tif (!(c & 0x80))\n\t\tgoto done;\n\n\tc = fgetc(f);\n\tif (c == EOF)\n\t\tgoto err;\n\tcounter |= (c & 0x7f) << 21;\n\ndone:\n\t/* REVISIT should we try to convert from delta values?  */\n\tprintf(\"+%u%s\\n\", counter, label);\n\treturn;\n\nerr:\n\tprintf(\"(ERROR %d - %s) \", errno, strerror(errno));\n\tgoto done;\n}\n\nint main(int argc, char **argv)\n{\n\tFILE *f = stdin;\n\tint c;\n\n\t/* parse arguments */\n\twhile ((c = getopt(argc, argv, \"f:d:\")) != EOF) {\n\t\tswitch (c) {\n\t\tcase 'f':\n\t\t\t/* e.g. from UART connected to /dev/ttyUSB0 */\n\t\t\tf = fopen(optarg, \"r\");\n\t\t\tif (!f) {\n\t\t\t\tperror(optarg);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'd':\n\t\t\tdump_swit = atoi(optarg);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfprintf(stderr, \"usage: %s [-f input]\",\n\t\t\t\tbasename(argv[0]));\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t/* Parse data ... records have a header then data bytes.\n\t * NOTE: we assume getc() deals in 8-bit bytes.\n\t */\n\tbool overflow = false;\n\n\twhile ((c = getc(f)) != EOF) {\n\n\t\t/* Sync packet ... 7 zeroes, 0x80 */\n\t\tif (c == 0) {\n\t\t\tint i;\n\n\t\t\tfor (i = 0; i < 6; i++) {\n\t\t\t\tc = fgetc(f);\n\t\t\t\tif (c == EOF)\n\t\t\t\t\tbreak;\n\t\t\t\tif (c != 0)\n\t\t\t\t\tgoto bad_sync;\n\t\t\t}\n\t\t\tc = fgetc(f);\n\t\t\tif (c == 0x80) {\n\t\t\t\tprintf(\"SYNC\\n\");\n\t\t\t\tcontinue;\n\t\t\t}\nbad_sync:\n\t\t\tprintf(\"BAD SYNC\\n\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Overflow packet */\n\t\tif (c == 0x70) {\n\t\t\t/* REVISIT later, report just what overflowed!\n\t\t\t * Timestamp and SWIT can happen.  Non-ITM too?\n\t\t\t */\n\t\t\toverflow = true;\n\t\t\tprintf(\"OVERFLOW ...\\n\");\n\t\t\tcontinue;\n\t\t}\n\t\toverflow = false;\n\n\t\tswitch (c & 0x0f) {\n\t\tcase 0x00:\t\t/* Timestamp */\n\t\t\tshow_timestamp(f, c);\n\t\t\tbreak;\n\t\tcase 0x04:\t\t/* \"Reserved\" */\n\t\t\tshow_reserved(f, \"RESERVED\", c);\n\t\t\tbreak;\n\t\tcase 0x08:\t\t/* ITM Extension */\n\t\t\t/* FIXME someday, handle these ...  */\n\t\t\tshow_reserved(f, \"ITM EXT\", c);\n\t\t\tbreak;\n\t\tcase 0x0c:\t\t/* DWT Extension */\n\t\t\tshow_reserved(f, \"DWT EXT\", c);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif (c & 4)\n\t\t\t\tshow_hard(f, c);\n\t\t\telse\n\t\t\t\tshow_swit(f, c);\n\t\t\tbreak;\n\t\t}\n\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/libdcc/README",
    "content": "This code is an example of using the openocd debug message system.\n\nBefore the message output is seen in the debug window, the functionality\nwill need enabling:\n\nFrom the gdb prompt:\nmonitor target_request debugmsgs enable\nmonitor trace point 1\n\nFrom the Telnet prompt:\ntarget_request debugmsgs enable\ntrace point 1\n\nTo see how many times the trace point was hit:\n(monitor) trace point 1\n\nSpen\nspen@spen-soft.co.uk\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/libdcc/dcc_stdio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n#define TARGET_REQ_TRACEMSG\t\t\t\t\t0x00\n#define TARGET_REQ_DEBUGMSG_ASCII\t\t\t0x01\n#define TARGET_REQ_DEBUGMSG_HEXMSG(size)\t(0x01 | ((size & 0xff) << 8))\n#define TARGET_REQ_DEBUGCHAR\t\t\t\t0x02\n\n#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_6SM__)\n\n/* we use the System Control Block DCRDR reg to simulate a arm7_9 dcc channel\n * DCRDR[7:0] is used by target for status\n * DCRDR[15:8] is used by target for write buffer\n * DCRDR[23:16] is used for by host for status\n * DCRDR[31:24] is used for by host for write buffer */\n\n#define NVIC_DBG_DATA_R\t\t(*((volatile unsigned short *)0xE000EDF8))\n\n#define\tBUSY\t1\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tint len = 4;\n\n\twhile (len--)\n\t{\n\t\t/* wait for data ready */\n\t\twhile (NVIC_DBG_DATA_R & BUSY);\n\n\t\t/* write our data and set write flag - tell host there is data*/\n\t\tNVIC_DBG_DATA_R = (unsigned short)(((dcc_data & 0xff) << 8) | BUSY);\n\t\tdcc_data >>= 8;\n\t}\n}\n\n#elif defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5T__)\n\nvoid dbg_write(unsigned long dcc_data)\n{\n\tunsigned long dcc_status;\n\n\tdo {\n\t\tasm volatile(\"mrc p14, 0, %0, c0, c0\" : \"=r\" (dcc_status));\n\t} while (dcc_status & 0x2);\n\n\tasm volatile(\"mcr p14, 0, %0, c1, c0\" : : \"r\" (dcc_data));\n}\n\n#else\n #error unsupported target\n#endif\n\nvoid dbg_trace_point(unsigned long number)\n{\n\tdbg_write(TARGET_REQ_TRACEMSG | (number << 8));\n}\n\nvoid dbg_write_u32(const unsigned long *val, long len)\n{\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(4) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdbg_write(*val);\n\n\t\tval++;\n\t\tlen--;\n\t}\n}\n\nvoid dbg_write_u16(const unsigned short *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(2) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 16: 0x0000);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 2;\n\t\tlen -= 2;\n\t}\n}\n\nvoid dbg_write_u8(const unsigned char *val, long len)\n{\n\tunsigned long dcc_data;\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_HEXMSG(1) | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = val[0]\n\t\t\t| ((len > 1) ? val[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? val[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? val[3] << 24 : 0x00);\n\n\t\tdbg_write(dcc_data);\n\n\t\tval += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_str(const char *msg)\n{\n\tlong len;\n\tunsigned long dcc_data;\n\n\tfor (len = 0; msg[len] && (len < 65536); len++);\n\n\tdbg_write(TARGET_REQ_DEBUGMSG_ASCII | ((len & 0xffff) << 16));\n\n\twhile (len > 0)\n\t{\n\t\tdcc_data = msg[0]\n\t\t\t| ((len > 1) ? msg[1] << 8 : 0x00)\n\t\t\t| ((len > 2) ? msg[2] << 16 : 0x00)\n\t\t\t| ((len > 3) ? msg[3] << 24 : 0x00);\n\t\tdbg_write(dcc_data);\n\n\t\tmsg += 4;\n\t\tlen -= 4;\n\t}\n}\n\nvoid dbg_write_char(char msg)\n{\n\tdbg_write(TARGET_REQ_DEBUGCHAR | ((msg & 0xff) << 16));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/libdcc/dcc_stdio.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef DCC_STDIO_H\n#define DCC_STDIO_H\n\nvoid dbg_trace_point(unsigned long number);\n\nvoid dbg_write_u32(const unsigned long *val, long len);\nvoid dbg_write_u16(const unsigned short *val, long len);\nvoid dbg_write_u8(const unsigned char *val, long len);\n\nvoid dbg_write_str(const char *msg);\nvoid dbg_write_char(char msg);\n\n#endif\t/* DCC_STDIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/libdcc/example.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *   Copyright (C) 2008 by Frederik Kriewtz                                *\n *   frederik@kriewitz.eu                                                  *\n ***************************************************************************/\n\n#include \"dcc_stdio.h\"\n\n/* enable openocd debugmsg at the gdb prompt:\n * monitor target_request debugmsgs enable\n *\n * create a trace point:\n * monitor trace point 1\n *\n * to show how often the trace point was hit:\n * monitor trace point\n*/\n\nint main(void)\n{\n\tdbg_write_str(\"hello world\");\n\n\tdbg_write_char('t');\n\tdbg_write_char('e');\n\tdbg_write_char('s');\n\tdbg_write_char('t');\n\tdbg_write_char('\\n');\n\n\tunsigned long test_u32 = 0x01234567;\n\tdbg_write_u32(&test_u32, 1);\n\n\tstatic const unsigned short test_u16[] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x0123, 0x4567, 0x89AB, 0xCDEF};\n\tdbg_write_u16(test_u16, 8);\n\n\tstatic const unsigned char test_u8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0XDD, 0xEE, 0xFF};\n\tdbg_write_u8(test_u8, 16);\n\n\twhile(1)\n\t{\n\t\tdbg_trace_point(0);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/list_example.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n/* Copyright (C) 2021 by Andreas Fritiofson <andreas.fritiofson@gmail.com> */\n\n/*\n * Simple example of using a circular doubly linked list through list.h\n *\n * gcc -I ../src/ list_example.c -o list_example\n */\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <assert.h>\n#include <helper/list.h>\n\nstatic LIST_HEAD(threads);\n\nstruct thread {\n\tint id;\n\tuint64_t tcb_address;\n\tstruct list_head lh;\n};\n\nvoid insert(struct thread *t)\n{\n\tlist_add_tail(&t->lh, &threads);\n}\n\nvoid remove(struct thread *t)\n{\n\tlist_del(&t->lh);\n}\n\nstruct thread *lookup_id(int id)\n{\n\tstruct thread *t;\n\tlist_for_each_entry(t, &threads, lh) {\n\t\tif (t->id == id)\n\t\t\treturn t;\n\t}\n\treturn NULL;\n}\n\nstruct thread *lookup_tcb(uint64_t addr)\n{\n\tstruct thread *t;\n\tlist_for_each_entry(t, &threads, lh) {\n\t\tif (t->tcb_address == addr)\n\t\t\treturn t;\n\t}\n\treturn NULL;\n}\n\nint main(void)\n{\n\tstruct thread t1 = { .id = 1, .tcb_address = 111111111 };\n\tstruct thread t2 = { .id = 2, .tcb_address = 222222222 };\n\tstruct thread t3 = { .id = 3, .tcb_address = 333333333 };\n\n\tinsert(&t1);\n\tinsert(&t2);\n\tassert(lookup_id(1) == &t1);\n\tassert(lookup_tcb(111111111) == &t1);\n\tassert(lookup_id(2) == &t2);\n\tassert(lookup_id(42) == NULL);\n\tremove(&t1);\n\tassert(lookup_id(1) == NULL);\n\tinsert(&t3);\n\tremove(&t2);\n\tassert(lookup_id(3) == &t3);\n\tassert(lookup_tcb(333333333) == &t3);\n\tassert(lookup_id(2) == NULL);\n\tremove(&t3);\n\tassert(list_empty(&threads));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/README",
    "content": "Included in these directories are the src to the various ram loaders used\nwithin openocd.\n\n** target checksum loaders **\n\nchecksum/armv4_5_crc.s :\n - ARMv4 and ARMv5 checksum loader : see target/arm_crc_code.c:arm_crc_code\n\nchecksum/armv7m_crc.s :\n - ARMv7m checksum loader : see target/armv7m.c:cortex_m_crc_code\n\nchecksum/mips32.s :\n - MIPS32 checksum loader : see target/mips32.c:mips_crc_code\n\n** target flash loaders **\n\nflash/pic32mx.s :\n - Microchip PIC32 flash loader : see flash/nor/pic32mx.c:pic32mx_flash_write_code\n\nflash/stellaris.s :\n - TI Stellaris flash loader : see flash/nor/stellaris.c:stellaris_write_code\n\nflash/stm32x.s :\n - ST STM32 flash loader : see flash/nor/stm32x.c:stm32x_flash_write_code\n\nflash/str7x.s :\n - ST STR7 flash loader : see flash/nor/str7x.c:str7x_flash_write_code\n\nflash/str9x.s :\n - ST STR9 flash loader : see flash/nor/str9x.c:str9x_flash_write_code\n\nSpencer Oliver\nspen@spen-soft.co.uk\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/armv4_5_crc.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x00,0x20,0xa0,0xe1,0x00,0x00,0xe0,0xe3,0x01,0x30,0xa0,0xe1,0x00,0x40,0xa0,0xe3,\n0x0b,0x00,0x00,0xea,0x04,0x10,0xd2,0xe7,0x30,0x70,0x9f,0xe5,0x01,0x0c,0x20,0xe0,\n0x00,0x50,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x80,0x60,0xa0,0xe1,0x01,0x50,0x85,0xe2,\n0x06,0x00,0xa0,0xe1,0x07,0x00,0x26,0xb0,0x08,0x00,0x55,0xe3,0xf8,0xff,0xff,0x1a,\n0x01,0x40,0x84,0xe2,0x03,0x00,0x54,0xe1,0xf1,0xff,0xff,0x1a,0x70,0x00,0x20,0xe1,\n0xb7,0x1d,0xc1,0x04,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/armv4_5_crc.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n\tr0 - address in - crc out\n\tr1 - char count\n*/\n\n\t.text\n\t.arm\n\n_start:\nmain:\n\tmov\t\tr2, r0\n\tmov\t\tr0, #0xffffffff\t/* crc */\n\tmov\t\tr3, r1\n\tmov\t\tr4, #0\n\tb\t\tncomp\nnbyte:\n\tldrb\tr1, [r2, r4]\n\tldr\t\tr7, CRC32XOR\n\teor\t\tr0, r0, r1, asl #24\n\tmov\t\tr5, #0\nloop:\n\tcmp\t\tr0, #0\n\tmov\t\tr6, r0, asl #1\n\tadd\t\tr5, r5, #1\n\tmov\t\tr0, r6\n\teorlt\tr0, r6, r7\n\tcmp\t\tr5, #8\n\tbne\t\tloop\n\tadd\t\tr4, r4, #1\nncomp:\n\tcmp\t\tr4, r3\n\tbne\t\tnbyte\nend:\n\tbkpt\t#0\n\nCRC32XOR:\t.word\t0x04c11db7\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/armv7m_crc.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x02,0x46,0x00,0x20,0xc0,0x43,0x0a,0x4e,0x0b,0x46,0x00,0x24,0x0d,0xe0,0x11,0x5d,\n0x09,0x06,0x48,0x40,0x00,0x25,0x00,0x28,0x02,0xda,0x40,0x00,0x70,0x40,0x00,0xe0,\n0x40,0x00,0x01,0x35,0x08,0x2d,0xf6,0xd1,0x01,0x34,0x9c,0x42,0xef,0xd1,0x00,0xbe,\n0xb7,0x1d,0xc1,0x04,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/armv7m_crc.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n\tparameters:\n\tr0 - address in - crc out\n\tr1 - char count\n*/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n\t.align\t2\n\n_start:\nmain:\n\tmov\t\tr2, r0\n\tmovs\tr0, #0\n\tmvns\tr0, r0\n\tldr\t\tr6, CRC32XOR\n\tmov\t\tr3, r1\n\tmovs\tr4, #0\n\tb\t\tncomp\nnbyte:\n\tldrb\tr1, [r2, r4]\n\tlsls\tr1, r1, #24\n\teors\tr0, r0, r1\n\tmovs\tr5, #0\nloop:\n\tcmp\t\tr0, #0\n\tbge\t\tnotset\n\tlsls\tr0, r0, #1\n\teors\tr0, r0, r6\n\tb\t\tcont\nnotset:\n\tlsls\tr0, r0, #1\ncont:\n\tadds\tr5, r5, #1\n\tcmp\t\tr5, #8\n\tbne\t\tloop\n\tadds\tr4, r4, #1\nncomp:\n\tcmp\t\tr4, r3\n\tbne\t\tnbyte\n\tbkpt\t#0\n\n\t.align\t2\n\nCRC32XOR:\t.word\t0x04c11db7\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/mips32.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.global main\n\t.text\n\t.set noreorder\n\n/* params:\n * $a0 address in\n * $a1 byte count\n * vars\n * $a0 crc\n * $a1 crc data byte\n * temps:\n * t3 v0 a3 a2 t0 v1\n */\n\n.ent main\nmain:\n\taddiu\t$t4, $a0, 0\t\t/* address in */\n\taddiu\t$t2, $a1, 0\t\t/* count */\n\n\taddiu\t$a0, $zero, 0xffffffff /* a0 crc - result */\n\n\tbeq\t\t$zero, $zero, ncomp\n\taddiu\t$t3, $zero, 0\t/* clear bytes read */\n\nnbyte:\n\tlb\t\t$a1, ($t4)\t\t/* load byte from source address */\n\taddi\t$t4, $t4, 1\t\t/* inc byte count */\n\ncrc:\n\tsll\t\t$a1, $a1, 24\n\tlui\t\t$v0, 0x04c1\n\txor\t\t$a0, $a0, $a1\n\tori\t\t$a3, $v0, 0x1db7\n\taddu\t$a2, $zero, $zero /* clear bit count */\nloop:\n\tsll\t\t$t0, $a0, 1\n\taddiu\t$a2, $a2, 1\t\t/* inc bit count */\n\tslti\t$a0, $a0, 0\n\txor\t\t$t1, $t0, $a3\n\tmovn\t$t0, $t1, $a0\n\tslti\t$v1, $a2, 8\t\t/* 8bits processed */\n\tbne\t\t$v1, $zero, loop\n\taddu\t$a0, $t0, $zero\n\nncomp:\n\tbne\t\t$t2, $t3, nbyte\t/* all bytes processed */\n\taddiu\t$t3, $t3, 1\n\nwait:\n\tsdbbp\n\n.end main\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/riscv32_crc.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0xb3,0x05,0xb5,0x00,0x93,0x07,0xf0,0xff,0x17,0x07,0x00,0x00,0x13,0x07,0x47,0x04,\n0x63,0x1a,0xb5,0x00,0x13,0x85,0x07,0x00,0x73,0x00,0x10,0x00,0x13,0x85,0x07,0x00,\n0x67,0x80,0x00,0x00,0x03,0x46,0x05,0x00,0x93,0x96,0x87,0x00,0x93,0xd7,0x87,0x01,\n0xb3,0xc7,0xc7,0x00,0x93,0x97,0x27,0x00,0xb3,0x07,0xf7,0x00,0x83,0xa7,0x07,0x00,\n0x13,0x05,0x15,0x00,0xb3,0xc7,0xf6,0x00,0x6f,0xf0,0x9f,0xfc,0x00,0x00,0x00,0x00,\n0xb7,0x1d,0xc1,0x04,0x6e,0x3b,0x82,0x09,0xd9,0x26,0x43,0x0d,0xdc,0x76,0x04,0x13,\n0x6b,0x6b,0xc5,0x17,0xb2,0x4d,0x86,0x1a,0x05,0x50,0x47,0x1e,0xb8,0xed,0x08,0x26,\n0x0f,0xf0,0xc9,0x22,0xd6,0xd6,0x8a,0x2f,0x61,0xcb,0x4b,0x2b,0x64,0x9b,0x0c,0x35,\n0xd3,0x86,0xcd,0x31,0x0a,0xa0,0x8e,0x3c,0xbd,0xbd,0x4f,0x38,0x70,0xdb,0x11,0x4c,\n0xc7,0xc6,0xd0,0x48,0x1e,0xe0,0x93,0x45,0xa9,0xfd,0x52,0x41,0xac,0xad,0x15,0x5f,\n0x1b,0xb0,0xd4,0x5b,0xc2,0x96,0x97,0x56,0x75,0x8b,0x56,0x52,0xc8,0x36,0x19,0x6a,\n0x7f,0x2b,0xd8,0x6e,0xa6,0x0d,0x9b,0x63,0x11,0x10,0x5a,0x67,0x14,0x40,0x1d,0x79,\n0xa3,0x5d,0xdc,0x7d,0x7a,0x7b,0x9f,0x70,0xcd,0x66,0x5e,0x74,0xe0,0xb6,0x23,0x98,\n0x57,0xab,0xe2,0x9c,0x8e,0x8d,0xa1,0x91,0x39,0x90,0x60,0x95,0x3c,0xc0,0x27,0x8b,\n0x8b,0xdd,0xe6,0x8f,0x52,0xfb,0xa5,0x82,0xe5,0xe6,0x64,0x86,0x58,0x5b,0x2b,0xbe,\n0xef,0x46,0xea,0xba,0x36,0x60,0xa9,0xb7,0x81,0x7d,0x68,0xb3,0x84,0x2d,0x2f,0xad,\n0x33,0x30,0xee,0xa9,0xea,0x16,0xad,0xa4,0x5d,0x0b,0x6c,0xa0,0x90,0x6d,0x32,0xd4,\n0x27,0x70,0xf3,0xd0,0xfe,0x56,0xb0,0xdd,0x49,0x4b,0x71,0xd9,0x4c,0x1b,0x36,0xc7,\n0xfb,0x06,0xf7,0xc3,0x22,0x20,0xb4,0xce,0x95,0x3d,0x75,0xca,0x28,0x80,0x3a,0xf2,\n0x9f,0x9d,0xfb,0xf6,0x46,0xbb,0xb8,0xfb,0xf1,0xa6,0x79,0xff,0xf4,0xf6,0x3e,0xe1,\n0x43,0xeb,0xff,0xe5,0x9a,0xcd,0xbc,0xe8,0x2d,0xd0,0x7d,0xec,0x77,0x70,0x86,0x34,\n0xc0,0x6d,0x47,0x30,0x19,0x4b,0x04,0x3d,0xae,0x56,0xc5,0x39,0xab,0x06,0x82,0x27,\n0x1c,0x1b,0x43,0x23,0xc5,0x3d,0x00,0x2e,0x72,0x20,0xc1,0x2a,0xcf,0x9d,0x8e,0x12,\n0x78,0x80,0x4f,0x16,0xa1,0xa6,0x0c,0x1b,0x16,0xbb,0xcd,0x1f,0x13,0xeb,0x8a,0x01,\n0xa4,0xf6,0x4b,0x05,0x7d,0xd0,0x08,0x08,0xca,0xcd,0xc9,0x0c,0x07,0xab,0x97,0x78,\n0xb0,0xb6,0x56,0x7c,0x69,0x90,0x15,0x71,0xde,0x8d,0xd4,0x75,0xdb,0xdd,0x93,0x6b,\n0x6c,0xc0,0x52,0x6f,0xb5,0xe6,0x11,0x62,0x02,0xfb,0xd0,0x66,0xbf,0x46,0x9f,0x5e,\n0x08,0x5b,0x5e,0x5a,0xd1,0x7d,0x1d,0x57,0x66,0x60,0xdc,0x53,0x63,0x30,0x9b,0x4d,\n0xd4,0x2d,0x5a,0x49,0x0d,0x0b,0x19,0x44,0xba,0x16,0xd8,0x40,0x97,0xc6,0xa5,0xac,\n0x20,0xdb,0x64,0xa8,0xf9,0xfd,0x27,0xa5,0x4e,0xe0,0xe6,0xa1,0x4b,0xb0,0xa1,0xbf,\n0xfc,0xad,0x60,0xbb,0x25,0x8b,0x23,0xb6,0x92,0x96,0xe2,0xb2,0x2f,0x2b,0xad,0x8a,\n0x98,0x36,0x6c,0x8e,0x41,0x10,0x2f,0x83,0xf6,0x0d,0xee,0x87,0xf3,0x5d,0xa9,0x99,\n0x44,0x40,0x68,0x9d,0x9d,0x66,0x2b,0x90,0x2a,0x7b,0xea,0x94,0xe7,0x1d,0xb4,0xe0,\n0x50,0x00,0x75,0xe4,0x89,0x26,0x36,0xe9,0x3e,0x3b,0xf7,0xed,0x3b,0x6b,0xb0,0xf3,\n0x8c,0x76,0x71,0xf7,0x55,0x50,0x32,0xfa,0xe2,0x4d,0xf3,0xfe,0x5f,0xf0,0xbc,0xc6,\n0xe8,0xed,0x7d,0xc2,0x31,0xcb,0x3e,0xcf,0x86,0xd6,0xff,0xcb,0x83,0x86,0xb8,0xd5,\n0x34,0x9b,0x79,0xd1,0xed,0xbd,0x3a,0xdc,0x5a,0xa0,0xfb,0xd8,0xee,0xe0,0x0c,0x69,\n0x59,0xfd,0xcd,0x6d,0x80,0xdb,0x8e,0x60,0x37,0xc6,0x4f,0x64,0x32,0x96,0x08,0x7a,\n0x85,0x8b,0xc9,0x7e,0x5c,0xad,0x8a,0x73,0xeb,0xb0,0x4b,0x77,0x56,0x0d,0x04,0x4f,\n0xe1,0x10,0xc5,0x4b,0x38,0x36,0x86,0x46,0x8f,0x2b,0x47,0x42,0x8a,0x7b,0x00,0x5c,\n0x3d,0x66,0xc1,0x58,0xe4,0x40,0x82,0x55,0x53,0x5d,0x43,0x51,0x9e,0x3b,0x1d,0x25,\n0x29,0x26,0xdc,0x21,0xf0,0x00,0x9f,0x2c,0x47,0x1d,0x5e,0x28,0x42,0x4d,0x19,0x36,\n0xf5,0x50,0xd8,0x32,0x2c,0x76,0x9b,0x3f,0x9b,0x6b,0x5a,0x3b,0x26,0xd6,0x15,0x03,\n0x91,0xcb,0xd4,0x07,0x48,0xed,0x97,0x0a,0xff,0xf0,0x56,0x0e,0xfa,0xa0,0x11,0x10,\n0x4d,0xbd,0xd0,0x14,0x94,0x9b,0x93,0x19,0x23,0x86,0x52,0x1d,0x0e,0x56,0x2f,0xf1,\n0xb9,0x4b,0xee,0xf5,0x60,0x6d,0xad,0xf8,0xd7,0x70,0x6c,0xfc,0xd2,0x20,0x2b,0xe2,\n0x65,0x3d,0xea,0xe6,0xbc,0x1b,0xa9,0xeb,0x0b,0x06,0x68,0xef,0xb6,0xbb,0x27,0xd7,\n0x01,0xa6,0xe6,0xd3,0xd8,0x80,0xa5,0xde,0x6f,0x9d,0x64,0xda,0x6a,0xcd,0x23,0xc4,\n0xdd,0xd0,0xe2,0xc0,0x04,0xf6,0xa1,0xcd,0xb3,0xeb,0x60,0xc9,0x7e,0x8d,0x3e,0xbd,\n0xc9,0x90,0xff,0xb9,0x10,0xb6,0xbc,0xb4,0xa7,0xab,0x7d,0xb0,0xa2,0xfb,0x3a,0xae,\n0x15,0xe6,0xfb,0xaa,0xcc,0xc0,0xb8,0xa7,0x7b,0xdd,0x79,0xa3,0xc6,0x60,0x36,0x9b,\n0x71,0x7d,0xf7,0x9f,0xa8,0x5b,0xb4,0x92,0x1f,0x46,0x75,0x96,0x1a,0x16,0x32,0x88,\n0xad,0x0b,0xf3,0x8c,0x74,0x2d,0xb0,0x81,0xc3,0x30,0x71,0x85,0x99,0x90,0x8a,0x5d,\n0x2e,0x8d,0x4b,0x59,0xf7,0xab,0x08,0x54,0x40,0xb6,0xc9,0x50,0x45,0xe6,0x8e,0x4e,\n0xf2,0xfb,0x4f,0x4a,0x2b,0xdd,0x0c,0x47,0x9c,0xc0,0xcd,0x43,0x21,0x7d,0x82,0x7b,\n0x96,0x60,0x43,0x7f,0x4f,0x46,0x00,0x72,0xf8,0x5b,0xc1,0x76,0xfd,0x0b,0x86,0x68,\n0x4a,0x16,0x47,0x6c,0x93,0x30,0x04,0x61,0x24,0x2d,0xc5,0x65,0xe9,0x4b,0x9b,0x11,\n0x5e,0x56,0x5a,0x15,0x87,0x70,0x19,0x18,0x30,0x6d,0xd8,0x1c,0x35,0x3d,0x9f,0x02,\n0x82,0x20,0x5e,0x06,0x5b,0x06,0x1d,0x0b,0xec,0x1b,0xdc,0x0f,0x51,0xa6,0x93,0x37,\n0xe6,0xbb,0x52,0x33,0x3f,0x9d,0x11,0x3e,0x88,0x80,0xd0,0x3a,0x8d,0xd0,0x97,0x24,\n0x3a,0xcd,0x56,0x20,0xe3,0xeb,0x15,0x2d,0x54,0xf6,0xd4,0x29,0x79,0x26,0xa9,0xc5,\n0xce,0x3b,0x68,0xc1,0x17,0x1d,0x2b,0xcc,0xa0,0x00,0xea,0xc8,0xa5,0x50,0xad,0xd6,\n0x12,0x4d,0x6c,0xd2,0xcb,0x6b,0x2f,0xdf,0x7c,0x76,0xee,0xdb,0xc1,0xcb,0xa1,0xe3,\n0x76,0xd6,0x60,0xe7,0xaf,0xf0,0x23,0xea,0x18,0xed,0xe2,0xee,0x1d,0xbd,0xa5,0xf0,\n0xaa,0xa0,0x64,0xf4,0x73,0x86,0x27,0xf9,0xc4,0x9b,0xe6,0xfd,0x09,0xfd,0xb8,0x89,\n0xbe,0xe0,0x79,0x8d,0x67,0xc6,0x3a,0x80,0xd0,0xdb,0xfb,0x84,0xd5,0x8b,0xbc,0x9a,\n0x62,0x96,0x7d,0x9e,0xbb,0xb0,0x3e,0x93,0x0c,0xad,0xff,0x97,0xb1,0x10,0xb0,0xaf,\n0x06,0x0d,0x71,0xab,0xdf,0x2b,0x32,0xa6,0x68,0x36,0xf3,0xa2,0x6d,0x66,0xb4,0xbc,\n0xda,0x7b,0x75,0xb8,0x03,0x5d,0x36,0xb5,0xb4,0x40,0xf7,0xb1,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/riscv64_crc.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x93,0x07,0xf0,0xff,0x93,0x06,0xf0,0xff,0x17,0x06,0x00,0x00,0x13,0x06,0x06,0x05,\n0x9b,0x85,0xf5,0xff,0x63,0x9a,0xd5,0x00,0x13,0x85,0x07,0x00,0x73,0x00,0x10,0x00,\n0x13,0x85,0x07,0x00,0x67,0x80,0x00,0x00,0x83,0x48,0x05,0x00,0x1b,0xd7,0x87,0x01,\n0x1b,0x98,0x87,0x00,0x33,0x47,0x17,0x01,0x13,0x17,0x27,0x00,0x33,0x07,0xe6,0x00,\n0x83,0x27,0x07,0x00,0x13,0x05,0x15,0x00,0xb3,0xc7,0x07,0x01,0x9b,0x87,0x07,0x00,\n0x6f,0xf0,0x1f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb7,0x1d,0xc1,0x04,\n0x6e,0x3b,0x82,0x09,0xd9,0x26,0x43,0x0d,0xdc,0x76,0x04,0x13,0x6b,0x6b,0xc5,0x17,\n0xb2,0x4d,0x86,0x1a,0x05,0x50,0x47,0x1e,0xb8,0xed,0x08,0x26,0x0f,0xf0,0xc9,0x22,\n0xd6,0xd6,0x8a,0x2f,0x61,0xcb,0x4b,0x2b,0x64,0x9b,0x0c,0x35,0xd3,0x86,0xcd,0x31,\n0x0a,0xa0,0x8e,0x3c,0xbd,0xbd,0x4f,0x38,0x70,0xdb,0x11,0x4c,0xc7,0xc6,0xd0,0x48,\n0x1e,0xe0,0x93,0x45,0xa9,0xfd,0x52,0x41,0xac,0xad,0x15,0x5f,0x1b,0xb0,0xd4,0x5b,\n0xc2,0x96,0x97,0x56,0x75,0x8b,0x56,0x52,0xc8,0x36,0x19,0x6a,0x7f,0x2b,0xd8,0x6e,\n0xa6,0x0d,0x9b,0x63,0x11,0x10,0x5a,0x67,0x14,0x40,0x1d,0x79,0xa3,0x5d,0xdc,0x7d,\n0x7a,0x7b,0x9f,0x70,0xcd,0x66,0x5e,0x74,0xe0,0xb6,0x23,0x98,0x57,0xab,0xe2,0x9c,\n0x8e,0x8d,0xa1,0x91,0x39,0x90,0x60,0x95,0x3c,0xc0,0x27,0x8b,0x8b,0xdd,0xe6,0x8f,\n0x52,0xfb,0xa5,0x82,0xe5,0xe6,0x64,0x86,0x58,0x5b,0x2b,0xbe,0xef,0x46,0xea,0xba,\n0x36,0x60,0xa9,0xb7,0x81,0x7d,0x68,0xb3,0x84,0x2d,0x2f,0xad,0x33,0x30,0xee,0xa9,\n0xea,0x16,0xad,0xa4,0x5d,0x0b,0x6c,0xa0,0x90,0x6d,0x32,0xd4,0x27,0x70,0xf3,0xd0,\n0xfe,0x56,0xb0,0xdd,0x49,0x4b,0x71,0xd9,0x4c,0x1b,0x36,0xc7,0xfb,0x06,0xf7,0xc3,\n0x22,0x20,0xb4,0xce,0x95,0x3d,0x75,0xca,0x28,0x80,0x3a,0xf2,0x9f,0x9d,0xfb,0xf6,\n0x46,0xbb,0xb8,0xfb,0xf1,0xa6,0x79,0xff,0xf4,0xf6,0x3e,0xe1,0x43,0xeb,0xff,0xe5,\n0x9a,0xcd,0xbc,0xe8,0x2d,0xd0,0x7d,0xec,0x77,0x70,0x86,0x34,0xc0,0x6d,0x47,0x30,\n0x19,0x4b,0x04,0x3d,0xae,0x56,0xc5,0x39,0xab,0x06,0x82,0x27,0x1c,0x1b,0x43,0x23,\n0xc5,0x3d,0x00,0x2e,0x72,0x20,0xc1,0x2a,0xcf,0x9d,0x8e,0x12,0x78,0x80,0x4f,0x16,\n0xa1,0xa6,0x0c,0x1b,0x16,0xbb,0xcd,0x1f,0x13,0xeb,0x8a,0x01,0xa4,0xf6,0x4b,0x05,\n0x7d,0xd0,0x08,0x08,0xca,0xcd,0xc9,0x0c,0x07,0xab,0x97,0x78,0xb0,0xb6,0x56,0x7c,\n0x69,0x90,0x15,0x71,0xde,0x8d,0xd4,0x75,0xdb,0xdd,0x93,0x6b,0x6c,0xc0,0x52,0x6f,\n0xb5,0xe6,0x11,0x62,0x02,0xfb,0xd0,0x66,0xbf,0x46,0x9f,0x5e,0x08,0x5b,0x5e,0x5a,\n0xd1,0x7d,0x1d,0x57,0x66,0x60,0xdc,0x53,0x63,0x30,0x9b,0x4d,0xd4,0x2d,0x5a,0x49,\n0x0d,0x0b,0x19,0x44,0xba,0x16,0xd8,0x40,0x97,0xc6,0xa5,0xac,0x20,0xdb,0x64,0xa8,\n0xf9,0xfd,0x27,0xa5,0x4e,0xe0,0xe6,0xa1,0x4b,0xb0,0xa1,0xbf,0xfc,0xad,0x60,0xbb,\n0x25,0x8b,0x23,0xb6,0x92,0x96,0xe2,0xb2,0x2f,0x2b,0xad,0x8a,0x98,0x36,0x6c,0x8e,\n0x41,0x10,0x2f,0x83,0xf6,0x0d,0xee,0x87,0xf3,0x5d,0xa9,0x99,0x44,0x40,0x68,0x9d,\n0x9d,0x66,0x2b,0x90,0x2a,0x7b,0xea,0x94,0xe7,0x1d,0xb4,0xe0,0x50,0x00,0x75,0xe4,\n0x89,0x26,0x36,0xe9,0x3e,0x3b,0xf7,0xed,0x3b,0x6b,0xb0,0xf3,0x8c,0x76,0x71,0xf7,\n0x55,0x50,0x32,0xfa,0xe2,0x4d,0xf3,0xfe,0x5f,0xf0,0xbc,0xc6,0xe8,0xed,0x7d,0xc2,\n0x31,0xcb,0x3e,0xcf,0x86,0xd6,0xff,0xcb,0x83,0x86,0xb8,0xd5,0x34,0x9b,0x79,0xd1,\n0xed,0xbd,0x3a,0xdc,0x5a,0xa0,0xfb,0xd8,0xee,0xe0,0x0c,0x69,0x59,0xfd,0xcd,0x6d,\n0x80,0xdb,0x8e,0x60,0x37,0xc6,0x4f,0x64,0x32,0x96,0x08,0x7a,0x85,0x8b,0xc9,0x7e,\n0x5c,0xad,0x8a,0x73,0xeb,0xb0,0x4b,0x77,0x56,0x0d,0x04,0x4f,0xe1,0x10,0xc5,0x4b,\n0x38,0x36,0x86,0x46,0x8f,0x2b,0x47,0x42,0x8a,0x7b,0x00,0x5c,0x3d,0x66,0xc1,0x58,\n0xe4,0x40,0x82,0x55,0x53,0x5d,0x43,0x51,0x9e,0x3b,0x1d,0x25,0x29,0x26,0xdc,0x21,\n0xf0,0x00,0x9f,0x2c,0x47,0x1d,0x5e,0x28,0x42,0x4d,0x19,0x36,0xf5,0x50,0xd8,0x32,\n0x2c,0x76,0x9b,0x3f,0x9b,0x6b,0x5a,0x3b,0x26,0xd6,0x15,0x03,0x91,0xcb,0xd4,0x07,\n0x48,0xed,0x97,0x0a,0xff,0xf0,0x56,0x0e,0xfa,0xa0,0x11,0x10,0x4d,0xbd,0xd0,0x14,\n0x94,0x9b,0x93,0x19,0x23,0x86,0x52,0x1d,0x0e,0x56,0x2f,0xf1,0xb9,0x4b,0xee,0xf5,\n0x60,0x6d,0xad,0xf8,0xd7,0x70,0x6c,0xfc,0xd2,0x20,0x2b,0xe2,0x65,0x3d,0xea,0xe6,\n0xbc,0x1b,0xa9,0xeb,0x0b,0x06,0x68,0xef,0xb6,0xbb,0x27,0xd7,0x01,0xa6,0xe6,0xd3,\n0xd8,0x80,0xa5,0xde,0x6f,0x9d,0x64,0xda,0x6a,0xcd,0x23,0xc4,0xdd,0xd0,0xe2,0xc0,\n0x04,0xf6,0xa1,0xcd,0xb3,0xeb,0x60,0xc9,0x7e,0x8d,0x3e,0xbd,0xc9,0x90,0xff,0xb9,\n0x10,0xb6,0xbc,0xb4,0xa7,0xab,0x7d,0xb0,0xa2,0xfb,0x3a,0xae,0x15,0xe6,0xfb,0xaa,\n0xcc,0xc0,0xb8,0xa7,0x7b,0xdd,0x79,0xa3,0xc6,0x60,0x36,0x9b,0x71,0x7d,0xf7,0x9f,\n0xa8,0x5b,0xb4,0x92,0x1f,0x46,0x75,0x96,0x1a,0x16,0x32,0x88,0xad,0x0b,0xf3,0x8c,\n0x74,0x2d,0xb0,0x81,0xc3,0x30,0x71,0x85,0x99,0x90,0x8a,0x5d,0x2e,0x8d,0x4b,0x59,\n0xf7,0xab,0x08,0x54,0x40,0xb6,0xc9,0x50,0x45,0xe6,0x8e,0x4e,0xf2,0xfb,0x4f,0x4a,\n0x2b,0xdd,0x0c,0x47,0x9c,0xc0,0xcd,0x43,0x21,0x7d,0x82,0x7b,0x96,0x60,0x43,0x7f,\n0x4f,0x46,0x00,0x72,0xf8,0x5b,0xc1,0x76,0xfd,0x0b,0x86,0x68,0x4a,0x16,0x47,0x6c,\n0x93,0x30,0x04,0x61,0x24,0x2d,0xc5,0x65,0xe9,0x4b,0x9b,0x11,0x5e,0x56,0x5a,0x15,\n0x87,0x70,0x19,0x18,0x30,0x6d,0xd8,0x1c,0x35,0x3d,0x9f,0x02,0x82,0x20,0x5e,0x06,\n0x5b,0x06,0x1d,0x0b,0xec,0x1b,0xdc,0x0f,0x51,0xa6,0x93,0x37,0xe6,0xbb,0x52,0x33,\n0x3f,0x9d,0x11,0x3e,0x88,0x80,0xd0,0x3a,0x8d,0xd0,0x97,0x24,0x3a,0xcd,0x56,0x20,\n0xe3,0xeb,0x15,0x2d,0x54,0xf6,0xd4,0x29,0x79,0x26,0xa9,0xc5,0xce,0x3b,0x68,0xc1,\n0x17,0x1d,0x2b,0xcc,0xa0,0x00,0xea,0xc8,0xa5,0x50,0xad,0xd6,0x12,0x4d,0x6c,0xd2,\n0xcb,0x6b,0x2f,0xdf,0x7c,0x76,0xee,0xdb,0xc1,0xcb,0xa1,0xe3,0x76,0xd6,0x60,0xe7,\n0xaf,0xf0,0x23,0xea,0x18,0xed,0xe2,0xee,0x1d,0xbd,0xa5,0xf0,0xaa,0xa0,0x64,0xf4,\n0x73,0x86,0x27,0xf9,0xc4,0x9b,0xe6,0xfd,0x09,0xfd,0xb8,0x89,0xbe,0xe0,0x79,0x8d,\n0x67,0xc6,0x3a,0x80,0xd0,0xdb,0xfb,0x84,0xd5,0x8b,0xbc,0x9a,0x62,0x96,0x7d,0x9e,\n0xbb,0xb0,0x3e,0x93,0x0c,0xad,0xff,0x97,0xb1,0x10,0xb0,0xaf,0x06,0x0d,0x71,0xab,\n0xdf,0x2b,0x32,0xa6,0x68,0x36,0xf3,0xa2,0x6d,0x66,0xb4,0xbc,0xda,0x7b,0x75,0xb8,\n0x03,0x5d,0x36,0xb5,0xb4,0x40,0xf7,0xb1,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/checksum/riscv_crc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/* Copyright (C) 2009-2021 Free Software Foundation, Inc. */\n\n/* Copied from https://github.com/gcc-mirror/gcc/blob/master/libiberty/crc32.c\n * and then tweaked a little. */\n\n/* This table was generated by the following program.\n   #include <stdio.h>\n   int\n   main ()\n   {\n     unsigned int i, j;\n     unsigned int c;\n     int table[256];\n     for (i = 0; i < 256; i++)\n       {\n\t for (c = i << 24, j = 8; j > 0; --j)\n\t   c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);\n\t table[i] = c;\n       }\n     printf (\"static const unsigned int crc32_table[] =\\n{\\n\");\n     for (i = 0; i < 256; i += 4)\n       {\n\t printf (\"  0x%08x, 0x%08x, 0x%08x, 0x%08x\",\n\t\t table[i + 0], table[i + 1], table[i + 2], table[i + 3]);\n\t if (i + 4 < 256)\n\t   putchar (',');\n\t putchar ('\\n');\n       }\n     printf (\"};\\n\");\n     return 0;\n   }\n   For more information on CRC, see, e.g.,\n   http://www.ross.net/crc/download/crc_v3.txt.  */\n\nstatic const unsigned int crc32_table[] = {\n\t0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,\n\t0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,\n\t0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,\n\t0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,\n\t0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,\n\t0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,\n\t0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,\n\t0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,\n\t0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,\n\t0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,\n\t0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,\n\t0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,\n\t0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,\n\t0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,\n\t0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,\n\t0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,\n\t0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,\n\t0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,\n\t0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,\n\t0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,\n\t0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,\n\t0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,\n\t0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,\n\t0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,\n\t0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,\n\t0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,\n\t0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,\n\t0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,\n\t0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,\n\t0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,\n\t0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,\n\t0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,\n\t0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,\n\t0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,\n\t0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,\n\t0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,\n\t0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,\n\t0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,\n\t0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,\n\t0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,\n\t0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,\n\t0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,\n\t0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,\n\t0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,\n\t0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,\n\t0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,\n\t0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,\n\t0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,\n\t0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,\n\t0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,\n\t0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,\n\t0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,\n\t0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,\n\t0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,\n\t0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,\n\t0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,\n\t0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,\n\t0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,\n\t0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,\n\t0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,\n\t0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,\n\t0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,\n\t0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,\n\t0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4\n};\n\n/*\n@deftypefn Extension {unsigned int} crc32 (const unsigned char *@var{buf}, @\n  int @var{len}, unsigned int @var{init})\nCompute the 32-bit CRC of @var{buf} which has length @var{len}.  The\nstarting value is 0xffffffff.\nThis is used by the @command{gdb} remote protocol for the @samp{qCRC}\ncommand.\nThis CRC can be specified as:\n  Width  : 32\n  Poly   : 0x04c11db7\n  Init   : 0xffffffff\n  RefIn  : false\n  RefOut : false\n  XorOut : 0\nThis differs from the \"standard\" CRC-32 algorithm in that the values\nare not reflected, and there is no final XOR value.  These differences\nmake it easy to compose the values of multiple blocks.\n@end deftypefn\n*/\n\n#include <stdint.h>\n\nunsigned int\nxcrc32(const unsigned char *buf, int len)\n{\n\tuint32_t crc = 0xffffffff;\n\twhile (len--) {\n\t\tcrc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];\n\t\tbuf++;\n\t}\n\tasm(\"mv a0, %0;\"\n\t\t\t\"ebreak;\"\n\t\t\t:\n\t\t\t: \"r\"(crc));\n\treturn crc;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/debug/xscale/debug_handler.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n#include \"protocol.h\"\n\n    .text\n    .align  4\n\n@ Disable thumb mode\n    .code 32\n\n@ send word to debugger\n.macro m_send_to_debugger reg\n1:\n\tmrc p14, 0, r15, c14, c0, 0\n\tbvs 1b\n\tmcr p14, 0, \\reg, c8, c0, 0\n.endm\n\n@ receive word from debugger\n.macro m_receive_from_debugger reg\n1:\n\tmrc p14, 0, r15, c14, c0, 0\n\tbpl 1b\n\tmrc p14, 0, \\reg, c9, c0, 0\n.endm\n\n@ save register on debugger, small\n.macro m_small_save_reg reg\n\tmov r0, \\reg\n\tbl send_to_debugger\n.endm\n\n@ save status register on debugger, small\n.macro m_small_save_psr\n\tmrs r0, spsr\n\tbl send_to_debugger\n.endm\n\n@ wait for all outstanding coprocessor accesses to complete\n.macro m_cpwait\n\tmrc p15, 0, r0, c2, c0, 0\n\tmov r0, r0\n\tsub pc, pc, #4\n.endm\n\n.global reset_handler\n.global undef_handler\n.global swi_handler\n.global prefetch_abort_handler\n.global data_abort_handler\n.global irq_handler\n.global fiq_handler\n\n.section .part1 , \"ax\"\n\nreset_handler:\n\t@ read DCSR\n\tmrc p14, 0, r13, c10, c0\n\t@ check if global enable bit (GE) is set\n\tands r13, r13, #0x80000000\n\n\tbne debug_handler\n\n\t@ set global enable bit (GE)\n\tmov r13, #0xc0000000\n\tmcr p14, 0, r13, c10, c0\n\ndebug_handler:\n\n\t@ save r0 without modifying other registers\n\tm_send_to_debugger r0\n\n\t@ save lr (program PC) without branching (use macro)\n\tm_send_to_debugger r14\n\n\t@ save non-banked registers and spsr (program CPSR)\n\tm_small_save_reg r1\n\tm_small_save_reg r2\n\tm_small_save_reg r3\n\tm_small_save_reg r4\n\tm_small_save_reg r5\n\tm_small_save_reg r6\n\tm_small_save_reg r7\n\tm_small_save_psr\n\n\tmrs r0, spsr\n\n\t@ prepare program PSR for debug use (clear Thumb, set I/F to disable interrupts)\n\tbic r0, r0, #PSR_T\n\torr r0, r0, #(PSR_I | PSR_F)\n\n\t@ examine mode bits\n\tand r1, r0, #MODE_MASK\n\tcmp r1, #MODE_USR\n\n\tbne not_user_mode\n\n\t@ replace USR mode with SYS\n\tbic r0, r0, #MODE_MASK\n\torr r0, r0, #MODE_SYS\n\nnot_user_mode:\n\n\tb save_banked_registers\n\n@ command loop\n@ wait for command from debugger, than execute desired function\nget_command:\n\tbl receive_from_debugger\n\n\t@ 0x0n - register access\n\tcmp r0, #0x0\n\tbeq get_banked_registers\n\n\tcmp r0, #0x1\n\tbeq set_banked_registers\n\n\t@ 0x1n - read memory\n\tcmp r0, #0x11\n\tbeq read_byte\n\n\tcmp r0, #0x12\n\tbeq read_half_word\n\n\tcmp r0, #0x14\n\tbeq read_word\n\n\t@ 0x2n - write memory\n\tcmp r0, #0x21\n\tbeq write_byte\n\n\tcmp r0, #0x22\n\tbeq write_half_word\n\n\tcmp r0, #0x24\n\tbeq write_word\n\n\t@ 0x3n - program execution\n\tcmp r0, #0x30\n\tbeq resume\n\n\tcmp r0, #0x31\n\tbeq resume_w_trace\n\n\t@ 0x4n - coprocessor access\n\tcmp r0, #0x40\n\tbeq read_cp_reg\n\n\tcmp r0, #0x41\n\tbeq write_cp_reg\n\n\t@ 0x5n - cache and mmu functions\n\tcmp r0, #0x50\n\tbeq clean_d_cache\n\n\tcmp r0, #0x51\n\tbeq invalidate_d_cache\n\n\tcmp r0, #0x52\n\tbeq invalidate_i_cache\n\n\tcmp r0, #0x53\n\tbeq cpwait\n\n\t@ 0x6n - misc functions\n\tcmp r0, #0x60\n\tbeq clear_sa\n\n\tcmp r0, #0x61\n\tbeq read_trace_buffer\n\n\tcmp r0, #0x62\n\tbeq clean_trace_buffer\n\n\t@ return (back to get_command)\n\tb get_command\n\n@ ----\n\n@ resume program execution\nresume:\n\t@ restore CPSR (SPSR_dbg)\n\tbl receive_from_debugger\n\tmsr spsr, r0\n\n\t@ restore registers (r7 - r0)\n\tbl receive_from_debugger @ r7\n\tmov r7, r0\n\tbl receive_from_debugger @ r6\n\tmov r6, r0\n\tbl receive_from_debugger @ r5\n\tmov r5, r0\n\tbl receive_from_debugger @ r4\n\tmov r4, r0\n\tbl receive_from_debugger @ r3\n\tmov r3, r0\n\tbl receive_from_debugger @ r2\n\tmov r2, r0\n\tbl receive_from_debugger @ r1\n\tmov r1, r0\n\tbl receive_from_debugger @ r0\n\n\t@ resume addresss\n\tm_receive_from_debugger lr\n\n\t@ branch back to application code, restoring CPSR\n\tsubs pc, lr, #0\n\n@ get banked registers\n@ receive mode bits from host, then run into save_banked_registers to\n\nget_banked_registers:\n\tbl receive_from_debugger\n\n@ save banked registers\n@ r0[4:0]: desired mode bits\nsave_banked_registers:\n\t@ backup CPSR\n\tmrs r7, cpsr\n\tmsr cpsr_c, r0\n\tnop\n\n\t@ keep current mode bits in r1 for later use\n\tand r1, r0, #MODE_MASK\n\n\t@ backup banked registers\n\tm_send_to_debugger r8\n\tm_send_to_debugger r9\n\tm_send_to_debugger r10\n\tm_send_to_debugger r11\n\tm_send_to_debugger r12\n\tm_send_to_debugger r13\n\tm_send_to_debugger r14\n\n\t@ if not in SYS mode (or USR, which we replaced with SYS before)\n\tcmp r1, #MODE_SYS\n\n\tbeq no_spsr_to_save\n\n\t@ backup SPSR\n\tmrs r0, spsr\n\tm_send_to_debugger r0\n\nno_spsr_to_save:\n\n\t@ restore CPSR for SDS\n\tmsr cpsr_c, r7\n\tnop\n\n   \t@ return\n\tb get_command\n\n@ ----\n\n\n@ set banked registers\n@ receive mode bits from host, then run into save_banked_registers to\n\nset_banked_registers:\n\tbl receive_from_debugger\n\n@ restore banked registers\n@ r0[4:0]: desired mode bits\nrestore_banked_registers:\n\t@ backup CPSR\n\tmrs r7, cpsr\n\tmsr cpsr_c, r0\n\tnop\n\n\t@ keep current mode bits in r1 for later use\n\tand r1, r0, #MODE_MASK\n\n\t@ set banked registers\n\tm_receive_from_debugger r8\n\tm_receive_from_debugger r9\n\tm_receive_from_debugger r10\n\tm_receive_from_debugger r11\n\tm_receive_from_debugger r12\n\tm_receive_from_debugger r13\n\tm_receive_from_debugger r14\n\n\t@ if not in SYS mode (or USR, which we replaced with SYS before)\n\tcmp r1, #MODE_SYS\n\n\tbeq no_spsr_to_restore\n\n\t@ set SPSR\n\tm_receive_from_debugger r0\n\tmsr spsr, r0\n\nno_spsr_to_restore:\n\n\t@ restore CPSR for SDS\n\tmsr cpsr_c, r7\n\tnop\n\n   \t@ return\n\tb get_command\n\n@ ----\n\nread_byte:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nrb_loop:\n\tldrb r0, [r2], #1\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tbl send_to_debugger\n\n\tsubs r1, r1, #1\n\tbne rb_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nread_half_word:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nrh_loop:\n\tldrh r0, [r2], #2\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tbl send_to_debugger\n\n\tsubs r1, r1, #1\n\tbne rh_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nread_word:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nrw_loop:\n\tldr r0, [r2], #4\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tbl send_to_debugger\n\n\tsubs r1, r1, #1\n\tbne rw_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nwrite_byte:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nwb_loop:\n\tbl receive_from_debugger\n\tstrb r0, [r2], #1\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tsubs r1, r1, #1\n\tbne wb_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nwrite_half_word:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nwh_loop:\n\tbl receive_from_debugger\n\tstrh r0, [r2], #2\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tsubs r1, r1, #1\n\tbne wh_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nwrite_word:\n\t@ r2: address\n\tbl receive_from_debugger\n\tmov r2, r0\n\n\t@ r1: count\n\tbl receive_from_debugger\n\tmov r1, r0\n\nww_loop:\n\tbl receive_from_debugger\n\tstr r0, [r2], #4\n\n\t@ drain write- (and fill-) buffer to work around XScale errata\n\tmcr p15, 0, r8, c7, c10, 4\n\n\tsubs r1, r1, #1\n\tbne ww_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\nclear_sa:\n\t@ read DCSR\n\tmrc p14, 0, r0, c10, c0\n\n\t@ clear SA bit\n\tbic r0, r0, #0x20\n\n\t@ write DCSR\n\tmcr p14, 0, r0, c10, c0\n\n\t@ return\n\tb get_command\n\n@ ----\n\nclean_d_cache:\n\t@ r0: cache clean area\n\tbl receive_from_debugger\n\n\tmov r1, #1024\nclean_loop:\n\tmcr p15, 0, r0, c7, c2, 5\n\tadd r0, r0, #32\n\tsubs r1, r1, #1\n\tbne clean_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\ninvalidate_d_cache:\n\tmcr p15, 0, r0, c7, c6, 0\n\n\t@ return\n\tb get_command\n\n@ ----\n\ninvalidate_i_cache:\n\tmcr p15, 0, r0, c7, c5, 0\n\n\t@ return\n\tb get_command\n\n@ ----\n\ncpwait:\n\tm_cpwait\n\n\t@return\n\tb get_command\n\n@ ----\n\n.section .part2 , \"ax\"\n\nread_cp_reg:\n\t@ requested cp register\n\tbl receive_from_debugger\n\n\tadr r1, read_cp_table\n\tadd pc, r1, r0, lsl #3\n\nread_cp_table:\n\tmrc p15, 0, r0, c0, c0, 0  @ XSCALE_MAINID\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c0, c0, 1  @ XSCALE_CACHETYPE\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c1, c0, 0  @ XSCALE_CTRL\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c1, c0, 1  @ XSCALE_AUXCTRL\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c2, c0, 0  @ XSCALE_TTB\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c3, c0, 0  @ XSCALE_DAC\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c5, c0, 0  @ XSCALE_FSR\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c6, c0, 0  @ XSCALE_FAR\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c13, c0, 0  @ XSCALE_PID\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c15, c0, 0  @ XSCALE_CP_ACCESS\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c14, c8, 0  @ XSCALE_IBCR0\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c14, c9, 0  @ XSCALE_IBCR1\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c14, c0, 0  @ XSCALE_DBR0\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c14, c3, 0  @ XSCALE_DBR1\n\tb read_cp_reg_reply\n\tmrc p15, 0, r0, c14, c4, 0  @ XSCALE_DBCON\n\tb read_cp_reg_reply\n\tmrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG\n\tb read_cp_reg_reply\n\tmrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0\n\tb read_cp_reg_reply\n\tmrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1\n\tb read_cp_reg_reply\n\tmrc p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR\n\tb read_cp_reg_reply\n\nread_cp_reg_reply:\n\tbl send_to_debugger\n\n\t@ return\n\tb get_command\n\n@ ----\n\nwrite_cp_reg:\n\t@ requested cp register\n\tbl receive_from_debugger\n\tmov r1, r0\n\n\t@ value to be written\n\tbl receive_from_debugger\n\n\tadr r2, write_cp_table\n\tadd pc, r2, r1, lsl #3\n\nwrite_cp_table:\n\tmcr p15, 0, r0, c0, c0, 0  @ XSCALE_MAINID (0x0)\n\tb get_command\n\tmcr p15, 0, r0, c0, c0, 1  @ XSCALE_CACHETYPE (0x1)\n\tb get_command\n\tmcr p15, 0, r0, c1, c0, 0  @ XSCALE_CTRL (0x2)\n\tb get_command\n\tmcr p15, 0, r0, c1, c0, 1  @ XSCALE_AUXCTRL (0x3)\n\tb get_command\n\tmcr p15, 0, r0, c2, c0, 0  @ XSCALE_TTB (0x4)\n\tb get_command\n\tmcr p15, 0, r0, c3, c0, 0  @ XSCALE_DAC (0x5)\n\tb get_command\n\tmcr p15, 0, r0, c5, c0, 0  @ XSCALE_FSR (0x6)\n\tb get_command\n\tmcr p15, 0, r0, c6, c0, 0  @ XSCALE_FAR (0x7)\n\tb get_command\n\tmcr p15, 0, r0, c13, c0, 0  @ XSCALE_PID (0x8)\n\tb get_command\n\tmcr p15, 0, r0, c15, c0, 0  @ XSCALE_CP_ACCESS (0x9)\n\tb get_command\n\tmcr p15, 0, r0, c14, c8, 0  @ XSCALE_IBCR0 (0xa)\n\tb get_command\n\tmcr p15, 0, r0, c14, c9, 0  @ XSCALE_IBCR1 (0xb)\n\tb get_command\n\tmcr p15, 0, r0, c14, c0, 0  @ XSCALE_DBR0 (0xc)\n\tb get_command\n\tmcr p15, 0, r0, c14, c3, 0  @ XSCALE_DBR1 (0xd)\n\tb get_command\n\tmcr p15, 0, r0, c14, c4, 0  @ XSCALE_DBCON (0xe)\n\tb get_command\n\tmcr p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG (0xf)\n\tb get_command\n\tmcr p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)\n\tb get_command\n\tmcr p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)\n\tb get_command\n\tmcr p14, 0, r0, c10, c0, 0 @ XSCALE_DCSR (0x12)\n\tb get_command\n\n@ ----\n\nread_trace_buffer:\n\n\t@ dump 256 entries from trace buffer\n\tmov\tr1, #256\nread_tb_loop:\n\tmrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG\n\tbl send_to_debugger\n\tsubs r1, r1, #1\n\tbne read_tb_loop\n\n\t@ dump checkpoint register 0\n\tmrc p14, 0, r0, c12, c0, 0 @ XSCALE_CHKPT0 (0x10)\n\tbl send_to_debugger\n\n\t@ dump checkpoint register 1\n\tmrc p14, 0, r0, c13, c0, 0 @ XSCALE_CHKPT1 (0x11)\n\tbl send_to_debugger\n\n\t@ return\n\tb get_command\n\n@ ----\n\nclean_trace_buffer:\n\n\t@ clean 256 entries from trace buffer\n\tmov\tr1, #256\nclean_tb_loop:\n\tmrc p14, 0, r0, c11, c0, 0 @ XSCALE_TBREG\n\tsubs r1, r1, #1\n\tbne clean_tb_loop\n\n\t@ return\n\tb get_command\n\n@ ----\n\n\n@ resume program execution with trace buffer enabled\nresume_w_trace:\n\t@ restore CPSR (SPSR_dbg)\n\tbl receive_from_debugger\n\tmsr spsr, r0\n\n\t@ restore registers (r7 - r0)\n\tbl receive_from_debugger @ r7\n\tmov r7, r0\n\tbl receive_from_debugger @ r6\n\tmov r6, r0\n\tbl receive_from_debugger @ r5\n\tmov r5, r0\n\tbl receive_from_debugger @ r4\n\tmov r4, r0\n\tbl receive_from_debugger @ r3\n\tmov r3, r0\n\tbl receive_from_debugger @ r2\n\tmov r2, r0\n\tbl receive_from_debugger @ r1\n\tmov r1, r0\n\tbl receive_from_debugger @ r0\n\n\t@ resume addresss\n\tm_receive_from_debugger lr\n\n\tmrc p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR\n\torr r13, r13, #1\n\tmcr p14, 0, r13, c10, c0, 0 @ XSCALE_DCSR\n\n\t@ branch back to application code, restoring CPSR\n\tsubs pc, lr, #0\n\nundef_handler:\nswi_handler:\nprefetch_abort_handler:\ndata_abort_handler:\nirq_handler:\nfiq_handler:\n1:\n\tb 1b\n\nsend_to_debugger:\n\tm_send_to_debugger r0\n\tmov pc, lr\n\nreceive_from_debugger:\n\tm_receive_from_debugger r0\n\tmov pc, lr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/debug/xscale/debug_handler.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x10,0xde,0x1a,0xee,0x02,0xd1,0x1d,0xe2,0x01,0x00,0x00,0x1a,0x03,0xd1,0xa0,0xe3,\n0x10,0xde,0x0a,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0x0e,0x08,0xee,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0xee,0x08,0xee,0x01,0x00,0xa0,0xe1,\n0x70,0x01,0x00,0xeb,0x02,0x00,0xa0,0xe1,0x6e,0x01,0x00,0xeb,0x03,0x00,0xa0,0xe1,\n0x6c,0x01,0x00,0xeb,0x04,0x00,0xa0,0xe1,0x6a,0x01,0x00,0xeb,0x05,0x00,0xa0,0xe1,\n0x68,0x01,0x00,0xeb,0x06,0x00,0xa0,0xe1,0x66,0x01,0x00,0xeb,0x07,0x00,0xa0,0xe1,\n0x64,0x01,0x00,0xeb,0x00,0x00,0x4f,0xe1,0x62,0x01,0x00,0xeb,0x00,0x00,0x4f,0xe1,\n0x20,0x00,0xc0,0xe3,0xc0,0x00,0x80,0xe3,0x1f,0x10,0x00,0xe2,0x10,0x00,0x51,0xe3,\n0x01,0x00,0x00,0x1a,0x1f,0x00,0xc0,0xe3,0x1f,0x00,0x80,0xe3,0x3d,0x00,0x00,0xea,\n0x5c,0x01,0x00,0xeb,0x00,0x00,0x50,0xe3,0x39,0x00,0x00,0x0a,0x01,0x00,0x50,0xe3,\n0x5a,0x00,0x00,0x0a,0x11,0x00,0x50,0xe3,0x7b,0x00,0x00,0x0a,0x12,0x00,0x50,0xe3,\n0x83,0x00,0x00,0x0a,0x14,0x00,0x50,0xe3,0x8b,0x00,0x00,0x0a,0x21,0x00,0x50,0xe3,\n0x93,0x00,0x00,0x0a,0x22,0x00,0x50,0xe3,0x9b,0x00,0x00,0x0a,0x24,0x00,0x50,0xe3,\n0xa3,0x00,0x00,0x0a,0x30,0x00,0x50,0xe3,0x14,0x00,0x00,0x0a,0x31,0x00,0x50,0xe3,\n0x2b,0x01,0x00,0x0a,0x40,0x00,0x50,0xe3,0xc4,0x00,0x00,0x0a,0x41,0x00,0x50,0xe3,\n0xed,0x00,0x00,0x0a,0x50,0x00,0x50,0xe3,0xa7,0x00,0x00,0x0a,0x51,0x00,0x50,0xe3,\n0xac,0x00,0x00,0x0a,0x52,0x00,0x50,0xe3,0xac,0x00,0x00,0x0a,0x53,0x00,0x50,0xe3,\n0xac,0x00,0x00,0x0a,0x60,0x00,0x50,0xe3,0x9b,0x00,0x00,0x0a,0x61,0x00,0x50,0xe3,\n0x0c,0x01,0x00,0x0a,0x62,0x00,0x50,0xe3,0x14,0x01,0x00,0x0a,0xd7,0xff,0xff,0xea,\n0x34,0x01,0x00,0xeb,0x00,0xf0,0x69,0xe1,0x32,0x01,0x00,0xeb,0x00,0x70,0xa0,0xe1,\n0x30,0x01,0x00,0xeb,0x00,0x60,0xa0,0xe1,0x2e,0x01,0x00,0xeb,0x00,0x50,0xa0,0xe1,\n0x2c,0x01,0x00,0xeb,0x00,0x40,0xa0,0xe1,0x2a,0x01,0x00,0xeb,0x00,0x30,0xa0,0xe1,\n0x28,0x01,0x00,0xeb,0x00,0x20,0xa0,0xe1,0x26,0x01,0x00,0xeb,0x00,0x10,0xa0,0xe1,\n0x24,0x01,0x00,0xeb,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0xee,0x19,0xee,\n0x00,0xf0,0x5e,0xe2,0x1f,0x01,0x00,0xeb,0x00,0x70,0x0f,0xe1,0x00,0xf0,0x21,0xe1,\n0x00,0x00,0xa0,0xe1,0x1f,0x10,0x00,0xe2,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,\n0x10,0x8e,0x08,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0x9e,0x08,0xee,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0xae,0x08,0xee,0x10,0xfe,0x1e,0xee,\n0xfd,0xff,0xff,0x6a,0x10,0xbe,0x08,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,\n0x10,0xce,0x08,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0xde,0x08,0xee,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,0x10,0xee,0x08,0xee,0x1f,0x00,0x51,0xe3,\n0x03,0x00,0x00,0x0a,0x00,0x00,0x4f,0xe1,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,\n0x10,0x0e,0x08,0xee,0x07,0xf0,0x21,0xe1,0x00,0x00,0xa0,0xe1,0x9f,0xff,0xff,0xea,\n0xfc,0x00,0x00,0xeb,0x00,0x70,0x0f,0xe1,0x00,0xf0,0x21,0xe1,0x00,0x00,0xa0,0xe1,\n0x1f,0x10,0x00,0xe2,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0x8e,0x19,0xee,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0x9e,0x19,0xee,0x10,0xfe,0x1e,0xee,\n0xfd,0xff,0xff,0x5a,0x10,0xae,0x19,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,\n0x10,0xbe,0x19,0xee,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0xce,0x19,0xee,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0xde,0x19,0xee,0x10,0xfe,0x1e,0xee,\n0xfd,0xff,0xff,0x5a,0x10,0xee,0x19,0xee,0x1f,0x00,0x51,0xe3,0x03,0x00,0x00,0x0a,\n0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,0x10,0x0e,0x19,0xee,0x00,0xf0,0x69,0xe1,\n0x07,0xf0,0x21,0xe1,0x00,0x00,0xa0,0xe1,0x7c,0xff,0xff,0xea,0xd9,0x00,0x00,0xeb,\n0x00,0x20,0xa0,0xe1,0xd7,0x00,0x00,0xeb,0x00,0x10,0xa0,0xe1,0x01,0x00,0xd2,0xe4,\n0x9a,0x8f,0x07,0xee,0xcf,0x00,0x00,0xeb,0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,\n0x72,0xff,0xff,0xea,0xcf,0x00,0x00,0xeb,0x00,0x20,0xa0,0xe1,0xcd,0x00,0x00,0xeb,\n0x00,0x10,0xa0,0xe1,0xb2,0x00,0xd2,0xe0,0x9a,0x8f,0x07,0xee,0xc5,0x00,0x00,0xeb,\n0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,0x68,0xff,0xff,0xea,0xc5,0x00,0x00,0xeb,\n0x00,0x20,0xa0,0xe1,0xc3,0x00,0x00,0xeb,0x00,0x10,0xa0,0xe1,0x04,0x00,0x92,0xe4,\n0x9a,0x8f,0x07,0xee,0xbb,0x00,0x00,0xeb,0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,\n0x5e,0xff,0xff,0xea,0xbb,0x00,0x00,0xeb,0x00,0x20,0xa0,0xe1,0xb9,0x00,0x00,0xeb,\n0x00,0x10,0xa0,0xe1,0xb7,0x00,0x00,0xeb,0x01,0x00,0xc2,0xe4,0x9a,0x8f,0x07,0xee,\n0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,0x54,0xff,0xff,0xea,0xb1,0x00,0x00,0xeb,\n0x00,0x20,0xa0,0xe1,0xaf,0x00,0x00,0xeb,0x00,0x10,0xa0,0xe1,0xad,0x00,0x00,0xeb,\n0xb2,0x00,0xc2,0xe0,0x9a,0x8f,0x07,0xee,0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,\n0x4a,0xff,0xff,0xea,0xa7,0x00,0x00,0xeb,0x00,0x20,0xa0,0xe1,0xa5,0x00,0x00,0xeb,\n0x00,0x10,0xa0,0xe1,0xa3,0x00,0x00,0xeb,0x04,0x00,0x82,0xe4,0x9a,0x8f,0x07,0xee,\n0x01,0x10,0x51,0xe2,0xfa,0xff,0xff,0x1a,0x40,0xff,0xff,0xea,0x10,0x0e,0x1a,0xee,\n0x20,0x00,0xc0,0xe3,0x10,0x0e,0x0a,0xee,0x3c,0xff,0xff,0xea,0x99,0x00,0x00,0xeb,\n0x01,0x1b,0xa0,0xe3,0xb2,0x0f,0x07,0xee,0x20,0x00,0x80,0xe2,0x01,0x10,0x51,0xe2,\n0xfb,0xff,0xff,0x1a,0x35,0xff,0xff,0xea,0x16,0x0f,0x07,0xee,0x33,0xff,0xff,0xea,\n0x15,0x0f,0x07,0xee,0x31,0xff,0xff,0xea,0x10,0x0f,0x12,0xee,0x00,0x00,0xa0,0xe1,\n0x04,0xf0,0x4f,0xe2,0x2d,0xff,0xff,0xea,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x80,0x00,0x00,0xeb,0x00,0x10,0x8f,0xe2,0x80,0xf1,0x81,0xe0,0x10,0x0f,0x10,0xee,\n0x23,0x00,0x00,0xea,0x30,0x0f,0x10,0xee,0x21,0x00,0x00,0xea,0x10,0x0f,0x11,0xee,\n0x1f,0x00,0x00,0xea,0x30,0x0f,0x11,0xee,0x1d,0x00,0x00,0xea,0x10,0x0f,0x12,0xee,\n0x1b,0x00,0x00,0xea,0x10,0x0f,0x13,0xee,0x19,0x00,0x00,0xea,0x10,0x0f,0x15,0xee,\n0x17,0x00,0x00,0xea,0x10,0x0f,0x16,0xee,0x15,0x00,0x00,0xea,0x10,0x0f,0x1d,0xee,\n0x13,0x00,0x00,0xea,0x10,0x0f,0x1f,0xee,0x11,0x00,0x00,0xea,0x18,0x0f,0x1e,0xee,\n0x0f,0x00,0x00,0xea,0x19,0x0f,0x1e,0xee,0x0d,0x00,0x00,0xea,0x10,0x0f,0x1e,0xee,\n0x0b,0x00,0x00,0xea,0x13,0x0f,0x1e,0xee,0x09,0x00,0x00,0xea,0x14,0x0f,0x1e,0xee,\n0x07,0x00,0x00,0xea,0x10,0x0e,0x1b,0xee,0x05,0x00,0x00,0xea,0x10,0x0e,0x1c,0xee,\n0x03,0x00,0x00,0xea,0x10,0x0e,0x1d,0xee,0x01,0x00,0x00,0xea,0x10,0x0e,0x1a,0xee,\n0xff,0xff,0xff,0xea,0x53,0x00,0x00,0xeb,0xf8,0xfe,0xff,0xea,0x55,0x00,0x00,0xeb,\n0x00,0x10,0xa0,0xe1,0x53,0x00,0x00,0xeb,0x00,0x20,0x8f,0xe2,0x81,0xf1,0x82,0xe0,\n0x10,0x0f,0x00,0xee,0xf1,0xfe,0xff,0xea,0x30,0x0f,0x00,0xee,0xef,0xfe,0xff,0xea,\n0x10,0x0f,0x01,0xee,0xed,0xfe,0xff,0xea,0x30,0x0f,0x01,0xee,0xeb,0xfe,0xff,0xea,\n0x10,0x0f,0x02,0xee,0xe9,0xfe,0xff,0xea,0x10,0x0f,0x03,0xee,0xe7,0xfe,0xff,0xea,\n0x10,0x0f,0x05,0xee,0xe5,0xfe,0xff,0xea,0x10,0x0f,0x06,0xee,0xe3,0xfe,0xff,0xea,\n0x10,0x0f,0x0d,0xee,0xe1,0xfe,0xff,0xea,0x10,0x0f,0x0f,0xee,0xdf,0xfe,0xff,0xea,\n0x18,0x0f,0x0e,0xee,0xdd,0xfe,0xff,0xea,0x19,0x0f,0x0e,0xee,0xdb,0xfe,0xff,0xea,\n0x10,0x0f,0x0e,0xee,0xd9,0xfe,0xff,0xea,0x13,0x0f,0x0e,0xee,0xd7,0xfe,0xff,0xea,\n0x14,0x0f,0x0e,0xee,0xd5,0xfe,0xff,0xea,0x10,0x0e,0x0b,0xee,0xd3,0xfe,0xff,0xea,\n0x10,0x0e,0x0c,0xee,0xd1,0xfe,0xff,0xea,0x10,0x0e,0x0d,0xee,0xcf,0xfe,0xff,0xea,\n0x10,0x0e,0x0a,0xee,0xcd,0xfe,0xff,0xea,0x01,0x1c,0xa0,0xe3,0x10,0x0e,0x1b,0xee,\n0x24,0x00,0x00,0xeb,0x01,0x10,0x51,0xe2,0xfb,0xff,0xff,0x1a,0x10,0x0e,0x1c,0xee,\n0x20,0x00,0x00,0xeb,0x10,0x0e,0x1d,0xee,0x1e,0x00,0x00,0xeb,0xc3,0xfe,0xff,0xea,\n0x01,0x1c,0xa0,0xe3,0x10,0x0e,0x1b,0xee,0x01,0x10,0x51,0xe2,0xfc,0xff,0xff,0x1a,\n0xbe,0xfe,0xff,0xea,0x1b,0x00,0x00,0xeb,0x00,0xf0,0x69,0xe1,0x19,0x00,0x00,0xeb,\n0x00,0x70,0xa0,0xe1,0x17,0x00,0x00,0xeb,0x00,0x60,0xa0,0xe1,0x15,0x00,0x00,0xeb,\n0x00,0x50,0xa0,0xe1,0x13,0x00,0x00,0xeb,0x00,0x40,0xa0,0xe1,0x11,0x00,0x00,0xeb,\n0x00,0x30,0xa0,0xe1,0x0f,0x00,0x00,0xeb,0x00,0x20,0xa0,0xe1,0x0d,0x00,0x00,0xeb,\n0x00,0x10,0xa0,0xe1,0x0b,0x00,0x00,0xeb,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,\n0x10,0xee,0x19,0xee,0x10,0xde,0x1a,0xee,0x01,0xd0,0x8d,0xe3,0x10,0xde,0x0a,0xee,\n0x00,0xf0,0x5e,0xe2,0xfe,0xff,0xff,0xea,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x6a,\n0x10,0x0e,0x08,0xee,0x0e,0xf0,0xa0,0xe1,0x10,0xfe,0x1e,0xee,0xfd,0xff,0xff,0x5a,\n0x10,0x0e,0x19,0xee,0x0e,0xf0,0xa0,0xe1,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/debug/xscale/debug_handler.ld",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/* identify the Entry Point  */\nENTRY(reset_handler)\n\n/* specify the mini-ICache memory areas  */\nMEMORY\n{\n\tmini_icache_0 (x)  \t\t\t\t: ORIGIN = 0x0, LENGTH = 1024\t/* first part of mini icache (sets 0-31) */\n\tmini_icache_1 (x)  \t\t\t\t: ORIGIN = 0x400, LENGTH = 1024\t/* second part of mini icache (sets 0-31) */\n}\n\n/* now define the output sections  */\nSECTIONS\n{\n\t.part1 :\n\t{\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\t*(.part1)\n\t} >mini_icache_0\n\n\t.part2 :\n\t{\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\tLONG(0)\n\t\t*(.part2)\n\t\tFILL(0x0)\n\t} >mini_icache_1\n\n\t/DISCARD/ :\n\t{\n\t\t*(.text)\n\t\t*(.glue_7)\n\t\t*(.glue_7t)\n\t\t*(.data)\n\t\t*(.bss)\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/debug/xscale/protocol.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#define REG_R0 0\n#define REG_R1 1\n#define REG_R2 2\n#define REG_R3 3\n#define REG_R4 4\n#define REG_R5 5\n#define REG_R6 6\n#define REG_R7 7\n#define REG_R8 8\n#define REG_R9 9\n#define REG_R10 10\n#define REG_R11 11\n#define REG_R12 12\n#define REG_R13 13\n#define REG_R14 14\n#define REG_R15 15\n#define REG_CPSR 16\n#define REG_SPSR 17\n\n#define MODE_USR 0x10\n#define MODE_FIQ 0x11\n#define MODE_IRQ 0x12\n#define MODE_SVC 0x13\n#define MODE_ABT 0x17\n#define MODE_UND 0x1b\n#define MODE_SYS 0x1f\n\n#define MODE_ANY 0x40\n#define MODE_CURRENT 0x80\n\n#define MODE_MASK 0x1f\n#define PSR_I 0x80\n#define PSR_F 0x40\n#define PSR_T 0x20\n\n#define XSCALE_DBG_MAINID 0x0\n#define XSCALE_DBG_CACHETYPE 0x1\n#define XSCALE_DBG_CTRL 0x2\n#define XSCALE_DBG_AUXCTRL 0x3\n#define XSCALE_DBG_TTB 0x4\n#define XSCALE_DBG_DAC 0x5\n#define XSCALE_DBG_FSR 0x6\n#define XSCALE_DBG_FAR 0x7\n#define XSCALE_DBG_PID 0x8\n#define XSCALE_DBG_CPACCESS 0x9\n#define XSCALE_DBG_IBCR0 0xa\n#define XSCALE_DBG_IBCR1 0xb\n#define XSCALE_DBG_DBR0 0xc\n#define XSCALE_DBG_DBR1 0xd\n#define XSCALE_DBG_DBCON 0xe\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/armv4_5_erase_check.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x01,0x30,0xd0,0xe4,0x03,0x20,0x02,0xe0,0x01,0x10,0x51,0xe2,0xfb,0xff,0xff,0x1a,\n0x70,0x00,0x20,0xe1,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/armv4_5_erase_check.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n\tparameters:\n\tr0 - address in\n\tr1 - byte count\n\tr2 - mask - result out\n*/\n\n\t.text\n\t.arm\n\nloop:\n\tldrb r3, [r0], #1\n\tand r2, r2, r3\n\tsubs r1, r1, #1\n\tbne loop\nend:\n\tbkpt\t#0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/armv7m_erase_check.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x02,0x68,0x12,0x42,0x0d,0xd0,0x43,0x68,0x1c,0x68,0x04,0x33,0x8c,0x42,0x05,0xd1,\n0x01,0x3a,0xf9,0xd1,0x01,0x24,0x04,0x60,0x08,0x30,0xf1,0xe7,0x00,0x24,0xfa,0xe7,\n0x00,0x00,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/armv7m_erase_check.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n\tparameters:\n\tr0 - pointer to struct { uint32_t size_in_result_out, uint32_t addr }\n\tr1 - value to check\n*/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n\t.align\t2\n\nBLOCK_SIZE_RESULT\t= 0\nBLOCK_ADDRESS\t\t= 4\nSIZEOF_STRUCT_BLOCK\t= 8\n\nstart:\nblock_loop:\n\tldr\tr2, [r0, #BLOCK_SIZE_RESULT]\t/* get size */\n\ttst\tr2, r2\n\tbeq\tdone\n\n\tldr\tr3, [r0, #BLOCK_ADDRESS]\t/* get address */\n\nword_loop:\n\tldr\tr4, [r3]\t/* read word */\n\tadds\tr3, #4\n\n\tcmp\tr4, r1\n\tbne\tnot_erased\n\n\tsubs\tr2, #1\n\tbne\tword_loop\n\n\tmovs\tr4, #1\t\t/* block is erased */\nsave_result:\n\tstr\tr4, [r0, #BLOCK_SIZE_RESULT]\n\tadds\tr0, #SIZEOF_STRUCT_BLOCK\n\tb\tblock_loop\n\nnot_erased:\n\tmovs\tr4, #0\n\tb\tsave_result\n\n/* Avoid padding at .text segment end. Otherwise exit point check fails. */\n        .skip   ( . - start + 2) & 2, 0\n\ndone:\n\tbkpt\t#0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/stm8_erase_check.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x00,0x80,0x00,0x00,0x80,0x00,0x96,0xcf,0x00,0x22,0x1e,0x01,0x16,0x04,0xa6,0xff,\n0x90,0x5d,0x26,0x04,0x0d,0x03,0x27,0x17,0x90,0x5d,0x26,0x02,0x0a,0x03,0x90,0x5a,\n0x92,0xbc,0x00,0x00,0xa1,0xff,0x26,0x07,0x5c,0x26,0xe5,0x0c,0x00,0x20,0xe1,0x1f,\n0x01,0x17,0x04,0x8b,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/erase_check/stm8_erase_check.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n *   Copyright (C) 2017 Ake Rehnman\n *   ake.rehnman(at)gmail.com\n */\n;;\n;; erase check memory code\n;;\n .org 0x0\n;; start address\n start_addr: .byte 0x00\n       .word 0x8000\n;; byte count\n byte_cnt: .byte 0x00\n       .word 0x8000\n;\n; SP must point to start_addr on entry\n; first relocate start_addr to the location\n; we are running at\nstart:\n\tldw X,SP\n\tldw .cont+2,X\n\tldw X,(start_addr+1,SP)\t;start addr\n\tldw Y,(byte_cnt+1,SP)\t;count\n\tld A,#0xff\n;\n; if count == 0 return\n.L1:\n\ttnzw Y\n\tjrne .decrcnt\t;continue if low word != 0\n\ttnz (byte_cnt,SP)\t;high byte\n\tjreq .exit\t;goto exit\n;\n; decrement count (byte_cnt)\n.decrcnt:\n\ttnzw Y\t;low word count\n\tjrne .decr1\n\tdec (byte_cnt,SP)\t;high byte\n.decr1:\n\tdecw Y;\tdecr low word\n;\n; first check if [start_addr] is 0xff\n.cont:\n\tldf A, [start_addr.e]\n\tcp A,#0xff\n\tjrne .exit ;exit if not 0xff\n;\n; increment start_addr (addr)\n\tincw X\n\tjrne .L1\n\tinc (start_addr,SP)\t;increment high byte\n\tjra .L1\n;\n.exit:\n\tldw (start_addr+1,SP),X\t;start addr\n\tldw (byte_cnt+1,SP),Y\t;count\n\tbreak\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_intel_16.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* algorithm register usage:\n * r0: source address (in RAM)\n * r1: target address (in Flash)\n * r2: count\n * r3: flash write command\n * r4: status byte (returned to host)\n * r5: busy test pattern\n * r6: error test pattern\n */\n\nloop:\n\tldrh\tr4, [r0], #2\n\tstrh\tr3, [r1]\n\tstrh\tr4, [r1]\nbusy:\n\tldrh\tr4, [r1]\n\tand\t\tr7, r4, r5\n\tcmp\t\tr7, r5\n\tbne\t\tbusy\n\ttst\t\tr4, r6\n\tbne\t\tdone\n\tsubs\tr2, r2, #1\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #2\n\tb\t\tloop\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_intel_32.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* algorithm register usage:\n * r0: source address (in RAM)\n * r1: target address (in Flash)\n * r2: count\n * r3: flash write command\n * r4: status byte (returned to host)\n * r5: busy test pattern\n * r6: error test pattern\n */\n\nloop:\n\tldr\t\tr4, [r0], #4\n\tstr\t\tr3, [r1]\n\tstr\t\tr4, [r1]\nbusy:\n\tldr\t\tr4, [r1]\n\tand\t\tr7, r4, r5\n\tcmp\t\tr7, r5\n\tbne\t\tbusy\n\ttst\t\tr4, r6\n\tbne\t\tdone\n\tsubs\tr2, r2, #1\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #4\n\tb\t\tloop\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_intel_8.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* algorithm register usage:\n * r0: source address (in RAM)\n * r1: target address (in Flash)\n * r2: count\n * r3: flash write command\n * r4: status byte (returned to host)\n * r5: busy test pattern\n * r6: error test pattern\n */\n\nloop:\n\tldrb\tr4, [r0], #1\n\tstrb\tr3, [r1]\n\tstrb\tr4, [r1]\nbusy:\n\tldrb\tr4, [r1]\n\tand\t\tr7, r4, r5\n\tcmp\t\tr7, r5\n\tbne\t\tbusy\n\ttst\t\tr4, r6\n\tbne\t\tdone\n\tsubs\tr2, r2, #1\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #1\n\tb\t\tloop\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_span_16.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift) */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldrh\tr5, [r0], #2\n\tstrh\tr9, [r8]\n\tstrh\tr11, [r10]\n\tstrh\tr3, [r8]\n\tstrh\tr5, [r1]\n\tnop\nbusy:\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tands\tr6, r6, r4, lsr #2\n\tbeq\t\tbusy\t\t\t/* b if DQ5 low */\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tmov\t\tr5, #0\t\t\t/* 0x0 - return 0x00, error */\n\tbne\t\tdone\ncont:\n\tsubs\tr2, r2, #1\t\t/* 0x1 */\n\tmoveq\tr5, #128\t\t/* 0x80 */\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #2\t\t/* 0x2 */\n\tb\t\tcode\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift) */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldrh\tr5, [r0], #2\n\tstrh\tr9, [r8]\n\tstrh\tr11, [r10]\n\tstrh\tr3, [r8]\n\tstrh\tr5, [r1]\n\tnop\nbusy:\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, #0x80\n\tbne\t\tbusy\n\tsubs\tr2, r2, #1\t/* 0x1 */\n\tmoveq\tr5, #128\t/* 0x80 */\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #2\t/* 0x2 */\n\tb\t\tcode\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_span_32.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift) */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldr\t\tr5, [r0], #4\n\tstr\t\tr9, [r8]\n\tstr\t\tr11, [r10]\n\tstr\t\tr3, [r8]\n\tstr\t\tr5, [r1]\n\tnop\nbusy:\n\tldr\t\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tands\tr6, r6, r4, lsr #2\n\tbeq\t\tbusy\t\t\t/* b if DQ5 low */\n\tldr\t\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tmov\t\tr5, #0\t\t\t/* 0x0 - return 0x00, error */\n\tbne\t\tdone\ncont:\n\tsubs\tr2, r2, #1\t\t/* 0x1 */\n\tmoveq\tr5, #128\t\t/* 0x80 */\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #4\t\t/* 0x4 */\n\tb\t\tcode\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv4_5_cfi_span_8.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4\n\n\t.section .init\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift) */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldrb\tr5, [r0], #1\n\tstrb\tr9, [r8]\n\tstrb\tr11, [r10]\n\tstrb\tr3, [r8]\n\tstrb\tr5, [r1]\n\tnop\nbusy:\n\tldrb\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tands\tr6, r6, r4, lsr #2\n\tbeq\t\tbusy\t\t\t/* b if DQ5 low */\n\tldrb\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tmov\t\tr5, #0\t\t\t/* 0x0 - return 0x00, error */\n\tbne\t\tdone\ncont:\n\tsubs\tr2, r2, #1\t\t/* 0x1 */\n\tmoveq\tr5, #128\t\t/* 0x80 */\n\tbeq\t\tdone\n\tadd\t\tr1, r1, #1\t\t/* 0x1 */\n\tb\t\tcode\ndone:\n\tb\t\tdone\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv7m_cfi_span_16.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.arch armv7-m\n\t.thumb\n\t.thumb_func\n\n\t.align 2\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift) */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldrh\tr5, [r0], #2\n\tstrh\tr9, [r8]\n\tstrh\tr11, [r10]\n\tstrh\tr3, [r8]\n\tstrh\tr5, [r1]\n\tnop\nbusy:\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tands\tr6, r6, r4, lsr #2\n\tbeq\t\tbusy\t\t\t/* b if DQ5 low */\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbeq\t\tcont\t\t\t/* b if DQ7 == Data7 */\n\tmov\t\tr5, #0\t\t\t/* 0x0 - return 0x00, error */\n\tbne\t\tdone\ncont:\n\tsubs\tr2, r2, #1\t\t/* 0x1 */\n\tbeq \tsuccess\n\tadd\t\tr1, r1, #2\t\t/* 0x2 */\n\tb\t\tcode\n\nsuccess:\n\tmov \tr5, #128\t\t/* 0x80 */\n\tb \tdone\n\ndone:\n\tbkpt #0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv7m_cfi_span_16_dq7.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2010 Spencer Oliver                                     *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.arch armv7-m\n\t.thumb\n\t.thumb_func\n\n\t.align 2\n\n/* input parameters - */\n/*\tR0 = source address */\n/*\tR1 = destination address */\n/*\tR2 = number of writes */\n/*\tR3 = flash write command */\n/*\tR4 = constant to mask DQ7 bits */\n/* output parameters - */\n/*\tR5 = 0x80 ok 0x00 bad */\n/* temp registers - */\n/*\tR6 = value read from flash to test status */\n/*\tR7 = holding register */\n/* unlock registers - */\n/*  R8 = unlock1_addr */\n/*  R9 = unlock1_cmd */\n/*  R10 = unlock2_addr */\n/*  R11 = unlock2_cmd */\n\ncode:\n\tldrh\tr5, [r0], #2\n\tstrh\tr9, [r8]\n\tstrh\tr11, [r10]\n\tstrh\tr3, [r8]\n\tstrh\tr5, [r1]\n\tnop\nbusy:\n\tldrh\tr6, [r1]\n\teor\t\tr7, r5, r6\n\tands\tr7, r4, r7\n\tbne\t\tbusy\n\tsubs\tr2, r2, #1\t/* 0x1 */\n\tbeq\t\tsuccess\n\tadd\t\tr1, r1, #2\t/* 0x2 */\n\tb\t\tcode\n\nsuccess:\n\tmov\t\tr5, #128\t/* 0x80 */\n\tb\t\tdone\n\ndone:\n\tbkpt #0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/armv7m_io.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013 by Henrik Nilsson                                  *\n *   henrik.nilsson@bytequest.se                                           *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.arch armv7-m\n\t.thumb\n\t.thumb_func\n\n\t.align 4\n\n/* Inputs:\n *  r0\tbuffer address\n *  r1\tNAND data address (byte wide)\n *  r2\tbuffer length\n */\nread:\n\tldrb\tr3, [r1]\n\tstrb\tr3, [r0], #1\n\tsubs\tr2, r2, #1\n\tbne\t\tread\n\ndone_read:\n\tbkpt #0\n\n\t.align 4\n\n/* Inputs:\n *  r0\tNAND data address (byte wide)\n *  r1\tbuffer address\n *  r2\tbuffer length\n */\nwrite:\n\tldrb\tr3, [r1], #1\n\tstrb\tr3, [r0]\n\tsubs\tr2, r2, #1\n\tbne\t\twrite\n\ndone_write:\n\tbkpt #0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/at91sam7x_ocl_flash.script",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsoft_reset_halt\nload_image at91sam7x_ocl.bin 0x200000\nresume 0x200000\nflash probe 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/at91sam7x_ram.ld",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n****************************************************************************\n*\n*  History:\n*\n*  30.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0100;\n\n\nMEMORY\n{\n  ram : org = 0x00200000, len = 64k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n\n    . = ALIGN(256);\n\n    PROVIDE (__stack_start = .);\n\n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);\n  } > ram\n\n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/crt.s",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n****************************************************************************\n*\n*  History:\n*\n*  18.12.06  mifi   First Version\n*                   The hardware initialization is based on the startup file\n*                   crtat91sam7x256_rom.S from NutOS 4.2.1.\n*                   Therefore partial copyright by egnite Software GmbH.\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */\n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Privileged Operating Mode  */\n   ARM_MODE_MASK  = 0x1F\n\n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n\n/*\n * Register Base Address\n */\n   AIC_BASE         = 0xFFFFF000\n   AIC_EOICR_OFF    = 0x130\n   AIC_IDCR_OFF     = 0x124\n\n   RSTC_MR          = 0xFFFFFD08\n   RSTC_KEY         = 0xA5000000\n   RSTC_URSTEN      = 0x00000001\n\n   WDT_BASE         = 0xFFFFFD40\n   WDT_MR_OFF       = 0x00000004\n   WDT_WDDIS        = 0x00008000\n\n   MC_BASE          = 0xFFFFFF00\n   MC_FMR_OFF       = 0x00000060\n   MC_FWS_1FWS      = 0x00480100\n\n   .section .vectors,\"ax\"\n   .code 32\n\n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n   .section .init, \"ax\"\n   .code 32\n\n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n   /*\n    * The watchdog is enabled after processor reset. Disable it.\n    */\n   ldr   r1, =WDT_BASE\n   ldr   r0, =WDT_WDDIS\n   str   r0, [r1, #WDT_MR_OFF]\n\n\n   /*\n    * Enable user reset: assertion length programmed to 1ms\n    */\n   ldr   r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8))\n   ldr   r1, =RSTC_MR\n   str   r0, [r1, #0]\n\n\n   /*\n    * Use 2 cycles for flash access.\n    */\n   ldr   r1, =MC_BASE\n   ldr   r0, =MC_FWS_1FWS\n   str   r0, [r1, #MC_FMR_OFF]\n\n\n   /*\n    * Disable all interrupts. Useful for debugging w/o target reset.\n    */\n   ldr   r1, =AIC_BASE\n   mvn   r0, #0\n   str   r0, [r1, #AIC_EOICR_OFF]\n   str   r0, [r1, #AIC_IDCR_OFF]\n\n\n   /*\n    * Setup a stack for each mode\n    */\n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */\n   ldr   sp, =__stack_und_end\n\n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n\n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */\n   ldr   sp, =__stack_fiq_end\n\n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */\n   ldr   sp, =__stack_irq_end\n\n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n\n\n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n\n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n\nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction\n\n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n\nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n\nIRQHandler:\n   b IRQHandler\n\nFIQHandler:\n   b FIQHandler\n\n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/dcc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#include \"dcc.h\"\n\n\n/* debug channel read (debugger->MCU) */\nuint32 dcc_rd(void)\n{\n\tvolatile uint32 dcc_reg;\n\n\tdo {\n\t\tasm volatile (\"mrc p14, 0, %0, C0, C0\" : \"=r\" (dcc_reg) :);\n\t} while ((dcc_reg&1) == 0);\n\n\tasm volatile (\"mrc p14, 0, %0, C1, C0\" : \"=r\" (dcc_reg) :);\n\treturn dcc_reg;\n}\n\n\n/* debug channel write (MCU->debugger) */\nint dcc_wr(uint32 data)\n{\n\tvolatile uint32 dcc_reg;\n\n\tdo {\n\t\tasm volatile (\"mrc p14, 0, %0, C0, C0\" : \"=r\" (dcc_reg) :);\n\t\t/* operation controlled by master, cancel operation\n\t\t\t upon reception of data for immediate response */\n\t\tif (dcc_reg&1) return -1;\n\t} while (dcc_reg&2);\n\n\tasm volatile (\"mcr p14, 0, %0, C1, C0\" : : \"r\" (data));\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/dcc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#ifndef dccH\n#define dccH\n\n#include \"platform.h\"\n\n/* debug channel read (debugger->MCU) */\nuint32 dcc_rd(void);\n\n/* debug channel write (MCU->debugger) */\nint dcc_wr(uint32 data);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/main.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#include \"platform.h\"\n\n#include <flash/nor/ocl.h>\n#include \"dcc.h\"\n#include \"samflash.h\"\n\n\n#define BUFSIZE 1024 /* words, i.e. 4 KiB */\nuint32 buffer[1024];\n\nvoid cmd_flash(uint32 cmd)\n{\n\tunsigned int len;\n\tuint32 adr;\n\tuint32 chksum;\n\tunsigned int bi; /* buffer index */\n\tunsigned int bi_start; /* receive start mark */\n\tunsigned int bi_end; /* receive end mark */\n\tunsigned int ofs;\n\tint pagenum;\n\tint result;\n\n\tadr = dcc_rd();\n\tlen = cmd&0xffff;\n\tofs = adr%flash_page_size;\n\tbi_start = ofs/4;\n\tbi_end = (ofs + len + 3)/4;\n\n\tif (bi_end > BUFSIZE) {\n\t\tdcc_wr(OCL_BUFF_OVER);\n\t\treturn;\n\t}\n\n\tchksum = OCL_CHKS_INIT;\n\tfor (bi = 0; bi < bi_end; bi++) chksum^=buffer[bi]=dcc_rd();\n\n\tif (dcc_rd() != chksum) {\n\t\tdcc_wr(OCL_CHKS_FAIL);\n\t\treturn;\n\t}\n\n\t/* fill in unused positions with unprogrammed values */\n\tfor (bi = 0; bi < bi_start; bi++) buffer[bi]=0xffffffff;\n\tfor (bi = bi_end; bi%flash_page_size; bi++) buffer[bi]=0xffffffff;\n\n\tresult = 0;\n\tpagenum = adr/flash_page_size;\n\tfor (bi = 0; bi < bi_end; bi += flash_page_size/4) {\n\t\tresult = flash_page_program(buffer + bi, pagenum++);\n\t\tif (result) break;\n\t}\n\n\t/* verify written data */\n\tif (!result) result = flash_verify(adr, len, ((uint8 *)buffer) + ofs);\n\n\tdcc_wr(OCL_CMD_DONE | result);\n}\n\n\nint main (void)\n{\n\tuint32 cmd;\n\n\tfor (;;) {\n\t\tcmd = dcc_rd();\n\t\tswitch (cmd&OCL_CMD_MASK) {\n\t\t\tcase OCL_PROBE:\n\t\t\t\tdcc_wr(OCL_CMD_DONE | flash_init());\n\t\t\t\tdcc_wr(0x100000); /* base */\n\t\t\t\tdcc_wr(flash_page_count*flash_page_size); /* size */\n\t\t\t\tdcc_wr(1); /* num_sectors */\n\t\t\t\tdcc_wr(4096 | ((unsigned long) flash_page_size << 16)); /* buflen and bufalign */\n\t\t\t\tbreak;\n\t\t\tcase OCL_ERASE_ALL:\n\t\t\t\tdcc_wr(OCL_CMD_DONE | flash_erase_all());\n\t\t\t\tbreak;\n\t\t\tcase OCL_FLASH_BLOCK:\n\t\t\t\tcmd_flash(cmd);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t/* unknown command */\n\t\t\t\tdcc_wr(OCL_CMD_ERR);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn 0; /* we shall never get here, just to suppress compiler warning */\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/makefile",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n##############################################################################################\n# Start of default section\n#\n\nTRGT = arm-elf-\nCC   = $(TRGT)gcc\nCP   = $(TRGT)objcopy\nAS   = $(TRGT)gcc -x assembler-with-cpp\nHEX  = $(CP) -O ihex\nBIN  = $(CP) -O binary\nOBJDUMP = $(TRGT)objdump\n\nMCU  = arm7tdmi\n\n# List all default C defines here, like -D_DEBUG=1\nDDEFS =\n\n# List all default ASM defines here, like -D_DEBUG=1\nDADEFS =\n\n# List all default directories to look for include files here\nDINCDIR =\n\n# List the default directory to look for the libraries here\nDLIBDIR =\n\n# List all default libraries here\nDLIBS =\n\n#\n# End of default section\n##############################################################################################\n\n##############################################################################################\n# Start of user section\n#\n\n# Define project name here\nPROJECT = at91sam7x_ocl\n\n# Define linker script file here\nLDSCRIPT= at91sam7x_ram.ld\n\n# List all user C define here, like -D_DEBUG=1\nUDEFS =\n\n# Define ASM defines here\nUADEFS =\n\n# List C source files here\nSRC  = main.c dcc.c samflash.c\n\n# List ASM source files here\nASRC = crt.s\n\n# List all user directories here\nUINCDIR =\n\n# List the user directory to look for the libraries here\nULIBDIR =\n\n# List all user libraries here\nULIBS =\n\n# Define optimisation level here\nOPT = -O2\n\n#\n# End of user defines\n##############################################################################################\n\n\nINCDIR  = $(patsubst %,-I%,$(DINCDIR) $(UINCDIR))\nLIBDIR  = $(patsubst %,-L%,$(DLIBDIR) $(ULIBDIR))\nDEFS    = $(DDEFS) $(UDEFS)\nADEFS   = $(DADEFS) $(UADEFS)\nOBJS    = $(ASRC:.s=.o) $(SRC:.c=.o)\nLIBS    = $(DLIBS) $(ULIBS)\nMCFLAGS = -mcpu=$(MCU)\n\nASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS)\nCPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb-interwork -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)\nLDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR)\n\n# Generate dependency information\n#CPFLAGS += -MD -MP -MF .dep/$(@F).d\n\n#\n# makefile rules\n#\n\nall: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).lst\n\n%o : %c\n\t$(CC) -c $(CPFLAGS) -I . $(INCDIR) $< -o $@\n\n%o : %s\n\t$(AS) -c $(ASFLAGS) $< -o $@\n\n%elf: $(OBJS)\n\t$(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $@\n\n%hex: %elf\n\t$(HEX) $< $@\n\n%bin: %elf\n\t$(BIN) $< $@\n\n%.lst: %.elf\n\t$(OBJDUMP) -h -S $< > $@\n\nclean:\n\t-rm -f $(OBJS)\n\t-rm -f $(PROJECT).elf\n\t-rm -f $(PROJECT).map\n\t-rm -f $(PROJECT).hex\n\t-rm -f $(PROJECT).bin\n\t-rm -f $(PROJECT).lst\n\t-rm -f $(SRC:.c=.c.bak)\n\t-rm -f $(SRC:.c=.lst)\n\t-rm -f $(ASRC:.s=.s.bak)\n\t-rm -f $(ASRC:.s=.lst)\n\t-rm -fR .dep\n\n#\n# Include the dependency files, should be the last of the makefile\n#\n#-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)\n\n# *** EOF ***\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/ocl.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#ifndef OCL_H\n#define OCL_H\n\n/* command/response mask */\n#define OCL_CMD_MASK 0xFFFF0000L\n\n/* commands */\n#define OCL_FLASH_BLOCK 0x0CFB0000L\n#define OCL_ERASE_BLOCK 0x0CEB0000L\n#define OCL_ERASE_ALL 0x0CEA0000L\n#define OCL_PROBE 0x0CBE0000L\n\n/* responses */\n#define OCL_CMD_DONE 0x0ACD0000L\n#define OCL_CMD_ERR 0x0ACE0000L\n#define OCL_CHKS_FAIL 0x0ACF0000L\n#define OCL_BUFF_OVER 0x0AB00000L\n\n#define OCL_CHKS_INIT 0xC100CD0CL\n\n#endif /* OCL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/platform.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#ifndef platformH\n#define platformH\n\n#include \"samregs.h\"\n\n\n#define outb(_reg, _val)  (*((volatile unsigned char *)(_reg)) = (_val))\n#define outw(_reg, _val)  (*((volatile unsigned short *)(_reg)) = (_val))\n#define outr(_reg, _val)  (*((volatile unsigned int *)(_reg)) = (_val))\n\n#define inb(_reg)   (*((volatile unsigned char *)(_reg)))\n#define inw(_reg)   (*((volatile unsigned short *)(_reg)))\n#define inr(_reg)   (*((volatile unsigned int *)(_reg)))\n\n#define _BV(bit)    (1 << (bit))\n\n\ntypedef signed char int8;\ntypedef unsigned char uint8;\n\ntypedef signed short int16;\ntypedef unsigned short uint16;\n\ntypedef signed int int32;\ntypedef unsigned int uint32;\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/samflash.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#include \"samflash.h\"\n\n\nunsigned int flash_page_count = 1024;\nunsigned int flash_page_size = 256;\n\n/* pages per lock bit */\nunsigned int flash_lock_pages = 1024/16;\n\n\n/* detect chip and set loader parameters */\nint flash_init(void)\n{\n\tunsigned int nvpsiz;\n\n\tnvpsiz = (inr(DBGU_CIDR) >> 8)&0xf;\n\n\tswitch (nvpsiz) {\n\t\tcase 3:\n\t\t\t/* AT91SAM7x32 */\n\t\t\tflash_page_count = 256;\n\t\t\tflash_page_size = 128;\n\t\t\tflash_lock_pages = 256/8;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\t/* AT91SAM7x64 */\n\t\t\tflash_page_count = 512;\n\t\t\tflash_page_size = 128;\n\t\t\tflash_lock_pages = 512/16;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\t/* AT91SAM7x128*/\n\t\t\tflash_page_count = 512;\n\t\t\tflash_page_size = 256;\n\t\t\tflash_lock_pages = 512/8;\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\t/* AT91SAM7x256 */\n\t\t\tflash_page_count = 1024;\n\t\t\tflash_page_size = 256;\n\t\t\tflash_lock_pages = 1024/16;\n\t\t\tbreak;\n\t\tcase 10:\n\t\t\t/* AT91SAM7x512 */\n\t\t\tflash_page_count = 2048;\n\t\t\tflash_page_size = 256;\n\t\t\tflash_lock_pages = 2048/32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn FLASH_STAT_INITE;\n\t}\n\treturn FLASH_STAT_OK;\n}\n\n\n/* program single flash page */\nint flash_page_program(uint32 *data, int page_num)\n{\n\tint i;\n\tint efc_ofs;\n\n\tuint32 *flash_ptr;\n\tuint32 *data_ptr;\n\n\t/* select proper controller */\n\tif (page_num >= 1024) efc_ofs = 0x10;\n\telse efc_ofs = 0;\n\n\t/* wait until FLASH is ready, just for sure */\n\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t/* calculate page address, only lower 8 bits are used to address the latch,\n\t\t but the upper part of address is needed for writing to proper EFC */\n\tflash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));\n\tdata_ptr = data;\n\n\t/* copy data to latch */\n\tfor (i = flash_page_size/4; i; i--) {\n\t\t/* we do not use memcpy to be sure that only 32 bit access is used */\n\t\t*(flash_ptr++)=*(data_ptr++);\n\t}\n\n\t/* page number and page write command to FCR */\n\toutr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | MC_KEY | MC_FCMD_WP);\n\n\t/* wait until it's done */\n\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t/* check for errors */\n\tif ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;\n\tif ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;\n\n#if 0\n\t/* verify written data */\n\tflash_ptr = (uint32 *)(FLASH_AREA_ADDR + (page_num*flash_page_size));\n\tdata_ptr = data;\n\n\tfor (i = flash_page_size/4; i; i--) {\n\t\tif (*(flash_ptr++)!=*(data_ptr++)) return FLASH_STAT_VERIFE;\n\t}\n#endif\n\n\treturn FLASH_STAT_OK;\n}\n\n\nint flash_erase_plane(int efc_ofs)\n{\n\tunsigned int lockbits;\n\tint page_num;\n\n\tpage_num = 0;\n\tlockbits = inr(MC_FSR + efc_ofs) >> 16;\n\twhile (lockbits) {\n\t\tif (lockbits&1) {\n\n\t\t\t/* wait until FLASH is ready, just for sure */\n\t\t\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t\t\toutr(MC_FCR + efc_ofs, ((page_num&0x3ff) << 8) | 0x5a000004);\n\n\t\t\t/* wait until it's done */\n\t\t\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t\t\t/* check for errors */\n\t\t\tif ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;\n\t\t\tif ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;\n\n\t\t}\n\t\tif ((page_num += flash_lock_pages) > flash_page_count) break;\n\t\tlockbits>>=1;\n\t}\n\n\t/* wait until FLASH is ready, just for sure */\n\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t/* erase all command to FCR */\n\toutr(MC_FCR + efc_ofs, 0x5a000008);\n\n\t/* wait until it's done */\n\twhile ((inr(MC_FSR + efc_ofs)&MC_FRDY) == 0);\n\n\t/* check for errors */\n\tif ((inr(MC_FSR + efc_ofs)&MC_PROGE)) return FLASH_STAT_PROGE;\n\tif ((inr(MC_FSR + efc_ofs)&MC_LOCKE)) return FLASH_STAT_LOCKE;\n\n\t/* set no erase before programming */\n\toutr(MC_FMR + efc_ofs, inr(MC_FMR + efc_ofs) | 0x80);\n\n\treturn FLASH_STAT_OK;\n}\n\n\n/* erase whole chip */\nint flash_erase_all(void)\n{\n\tint result;\n\n\tif ((result = flash_erase_plane(0)) != FLASH_STAT_OK) return result;\n\n\t/* the second flash controller, if any */\n\tif (flash_page_count > 1024) result = flash_erase_plane(0x10);\n\n\treturn result;\n}\n\n\nint flash_verify(uint32 adr, unsigned int len, uint8 *src)\n{\n\tunsigned char *flash_ptr;\n\n\tflash_ptr = (uint8 *)FLASH_AREA_ADDR + adr;\n\tfor (;len; len--) {\n\t\tif (*(flash_ptr++)!=*(src++)) return FLASH_STAT_VERIFE;\n\t}\n\treturn FLASH_STAT_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/samflash.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n#ifndef samflashH\n#define samflashH\n\n#include \"platform.h\"\n\n#define FLASH_AREA_ADDR 0x100000\n\n#define FLASH_STAT_OK 0\n#define FLASH_STAT_PROGE 1\n#define FLASH_STAT_LOCKE 2\n#define FLASH_STAT_VERIFE 3\n#define FLASH_STAT_INITE 4\n\nextern unsigned int flash_page_count;\nextern unsigned int flash_page_size; /* words */\n\n/* detect chip and set loader parameters */\nint flash_init(void);\n\n/* program single flash page */\nint flash_page_program(uint32 *data, int page_num);\n\n/* erase whole chip */\nint flash_erase_all(void);\n\n/* verify written data */\nint flash_verify(uint32 adr, unsigned int len, uint8 *src);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/at91sam7x/samregs.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/*\n * Copyright (C) 2005-2006 by egnite Software GmbH. All rights reserved.\n *\n * For additional information see http://www.ethernut.de/\n */\n\n\n#ifndef samregsH\n#define samregsH\n\n\n/*\n * Register definitions below copied from NutOS\n */\n\n#define DBGU_BASE       0xFFFFF200      /*!< \\brief DBGU base address. */\n\n#define DBGU_CIDR_OFF           0x00000040      /*!< \\brief DBGU chip ID register offset. */\n#define DBGU_CIDR   (DBGU_BASE + DBGU_CIDR_OFF) /*!< \\brief DBGU chip ID register. */\n\n\n#define MC_BASE         0xFFFFFF00      /*!< \\brief Memory controller base. */\n\n#define MC_FMR_OFF              0x00000060      /*!< \\brief MC flash mode register offset. */\n#define MC_FMR      (MC_BASE + MC_FMR_OFF)      /*!< \\brief MC flash mode register address. */\n#define MC_FRDY                 0x00000001      /*!< \\brief Flash ready. */\n#define MC_LOCKE                0x00000004      /*!< \\brief Lock error. */\n#define MC_PROGE                0x00000008      /*!< \\brief Programming error. */\n#define MC_NEBP                 0x00000080      /*!< \\brief No erase before programming. */\n#define MC_FWS_MASK             0x00000300      /*!< \\brief Flash wait state mask. */\n#define MC_FWS_1R2W             0x00000000      /*!< \\brief 1 cycle for read, 2 for write operations. */\n#define MC_FWS_2R3W             0x00000100      /*!< \\brief 2 cycles for read, 3 for write operations. */\n#define MC_FWS_3R4W             0x00000200      /*!< \\brief 3 cycles for read, 4 for write operations. */\n#define MC_FWS_4R4W             0x00000300      /*!< \\brief 4 cycles for read and write operations. */\n#define MC_FMCN_MASK            0x00FF0000      /*!< \\brief Flash microsecond cycle number mask. */\n\n#define MC_FCR_OFF              0x00000064      /*!< \\brief MC flash command register offset. */\n#define MC_FCR      (MC_BASE + MC_FCR_OFF)      /*!< \\brief MC flash command register address. */\n#define MC_FCMD_MASK            0x0000000F      /*!< \\brief Flash command mask. */\n#define MC_FCMD_NOP             0x00000000      /*!< \\brief No command. */\n#define MC_FCMD_WP              0x00000001      /*!< \\brief Write page. */\n#define MC_FCMD_SLB             0x00000002      /*!< \\brief Set lock bit. */\n#define MC_FCMD_WPL             0x00000003      /*!< \\brief Write page and lock. */\n#define MC_FCMD_CLB             0x00000004      /*!< \\brief Clear lock bit. */\n#define MC_FCMD_EA              0x00000008      /*!< \\brief Erase all. */\n#define MC_FCMD_SGPB            0x0000000B      /*!< \\brief Set general purpose NVM bit. */\n#define MC_FCMD_CGPB            0x0000000D      /*!< \\brief Clear general purpose NVM bit. */\n#define MC_FCMD_SSB             0x0000000F      /*!< \\brief Set security bit. */\n#define MC_PAGEN_MASK           0x0003FF00      /*!< \\brief Page number mask. */\n#define MC_KEY                  0x5A000000      /*!< \\brief Writing protect key. */\n\n#define MC_FSR_OFF              0x00000068      /*!< \\brief MC flash status register offset. */\n#define MC_FSR      (MC_BASE + MC_FSR_OFF)      /*!< \\brief MC flash status register address. */\n#define MC_SECURITY             0x00000010      /*!< \\brief Security bit status. */\n\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/* To be built with arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m0 -O3 bluenrgx.c */\n/* Then postprocess output of command \"arm-none-eabi-objdump -d bluenrgx.o\" to make a C array of bytes */\n\n#include <stdint.h>\n#include \"../../../../src/flash/nor/bluenrg-x.h\"\n\n/* Status Values ----------------------------------------------------------*/\n#define SUCCESS             0\n#define ERR_UNALIGNED       1\n#define ERR_INVALID_ADDRESS 2\n#define ERR_INVALID_TYPE    3\n#define ERR_WRITE_PROTECTED 4\n#define ERR_WRITE_FAILED    5\n#define ERR_ERASE_REQUIRED  6\n#define ERR_VERIFY_FAILED   7\n\n#define MFB_MASS_ERASE 0x01\n#define MFB_PAGE_ERASE 0x02\n\n#define DO_ERASE  0x0100\n#define DO_VERIFY 0x0200\n\n#define MFB_BOTTOM                (0x10040000)\n#define MFB_SIZE_B(regs_base)     ((16 * (((*(volatile uint32_t *)(regs_base + FLASH_SIZE_REG)) + 1) >> 12)) * 1024)\n#define MFB_SIZE_W                (MFB_SIZE_B/4)\n#define MFB_TOP                   (MFB_BOTTOM+MFB_SIZE_B-1)\n#define MFB_PAGE_SIZE_B           (2048)\n#define MFB_PAGE_SIZE_W           (MFB_PAGE_SIZE_B/4)\n\n#define AREA_ERROR 0x01\n#define AREA_MFB   0x04\n\ntypedef struct {\n\tvolatile uint8_t *wp;\n\tuint8_t *rp;\n} work_area_t;\n\n/* Flash Commands --------------------------------------------------------*/\nstatic inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t address, uint8_t **data,\n\t\t\t\t\t\t\t\t uint32_t writeLength, uint32_t flash_regs_base)\n{\n\tuint32_t index, flash_word[4];\n\tuint8_t i;\n\n\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQMASK)) = 0;\n\tfor (index = 0; index < writeLength; index += (FLASH_WORD_LEN*4)) {\n\t\tfor (i = 0; i < 4; i++)\n\t\t\tflash_word[i] = (*(uint32_t *) (*data + i*4));\n\n\t\t/* Clear the IRQ flags */\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) = 0x0000003F;\n\t\t/* Load the flash address to write */\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_ADDRESS)) = (uint16_t)((address + index - MFB_BOTTOM) >> 2);\n\t\t/* Prepare and load the data to flash */\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA0)) = flash_word[0];\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA1)) = flash_word[1];\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA2)) = flash_word[2];\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA3)) = flash_word[3];\n\t\t/* Flash write command */\n\t\t*((volatile uint32_t *)(flash_regs_base + FLASH_REG_COMMAND)) = FLASH_CMD_BURSTWRITE;\n\t\t/* Wait the end of the flash write command */\n\t\twhile ((*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) & FLASH_INT_CMDDONE) == 0)\n\t\t\t;\n\t\t*data += (FLASH_WORD_LEN * 4);\n\t}\n\n\treturn SUCCESS;\n}\n\n__attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p,\n\t\t\t\t\t\t\t    uint8_t *fifo_end,\n\t\t\t\t\t\t\t    uint8_t *target_address,\n\t\t\t\t\t\t\t    uint32_t count,\n\t\t\t\t\t\t\t    uint32_t flash_regs_base)\n{\n\tuint32_t retval;\n\tvolatile work_area_t *work_area = (work_area_t *) work_area_p;\n\tuint8_t *fifo_start = (uint8_t *) work_area->rp;\n\n\twhile (count) {\n\t\tvolatile int32_t fifo_linear_size;\n\n\t\t/* Wait for some data in the FIFO */\n\t\twhile (work_area->rp == work_area->wp)\n\t\t\t;\n\t\tif (work_area->wp == 0) {\n\t\t\t/* Aborted by other party */\n\t\t\tbreak;\n\t\t}\n\t\tif (work_area->rp > work_area->wp) {\n\t\t\tfifo_linear_size = fifo_end-work_area->rp;\n\t\t} else {\n\t\t\tfifo_linear_size = (work_area->wp - work_area->rp);\n\t\t\tif (fifo_linear_size < 0)\n\t\t\t\tfifo_linear_size = 0;\n\t\t}\n\t\tif (fifo_linear_size < 16) {\n\t\t\t/* We should never get here */\n\t\t\tcontinue;\n\t\t}\n\n\t\tretval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size, flash_regs_base);\n\t\tif (retval != SUCCESS) {\n\t\t\twork_area->rp = (uint8_t *)retval;\n\t\t\tbreak;\n\t\t}\n\t\ttarget_address += fifo_linear_size;\n\t\tif (work_area->rp >= fifo_end)\n\t\t\twork_area->rp = fifo_start;\n\t\tcount -= fifo_linear_size;\n\t}\n\t__asm(\"bkpt 0\");\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x05,0x93,0x43,0x68,0x14,0x9e,0x09,0x93,0x05,0x9b,0x05,0x00,0x07,0x91,0x06,0x92,\n0x01,0x24,0xb1,0x46,0x00,0x2b,0x68,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0,\n0x2b,0x68,0x00,0x2b,0x61,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x5e,0xd9,0x6b,0x68,\n0x07,0x9a,0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x4a,0x46,0x00,0x21,0x03,0x93,0xd1,0x60,\n0x00,0x2b,0x42,0xd0,0x40,0x22,0x4a,0x44,0x90,0x46,0x44,0x22,0x4a,0x44,0x00,0x92,\n0x48,0x22,0x4a,0x44,0x93,0x46,0x4c,0x22,0x27,0x4f,0x4a,0x44,0xbc,0x46,0x4e,0x46,\n0x92,0x46,0x06,0x99,0x4b,0x46,0x61,0x44,0x08,0x00,0x00,0x99,0x18,0x36,0x6a,0x68,\n0x08,0x95,0x8c,0x46,0x55,0x46,0xda,0x46,0xb3,0x46,0x10,0x33,0x04,0x92,0x11,0x68,\n0x5e,0x46,0x00,0x91,0x51,0x68,0x97,0x68,0x01,0x91,0xd1,0x68,0x02,0x91,0x3f,0x21,\n0x19,0x60,0x81,0x03,0x09,0x0c,0x31,0x60,0x46,0x46,0x00,0x99,0x31,0x60,0x66,0x46,\n0x01,0x99,0x31,0x60,0x56,0x46,0x02,0x99,0x37,0x60,0x29,0x60,0xcc,0x26,0x49,0x46,\n0x0e,0x60,0x19,0x68,0x0c,0x42,0xfc,0xd0,0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,\n0x51,0x1a,0x8e,0x42,0xdb,0xd8,0x08,0x9d,0x6a,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,\n0x63,0x44,0x06,0x93,0x07,0x9a,0x6b,0x68,0x9a,0x42,0x01,0xd8,0x09,0x9b,0x6b,0x60,\n0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,0x96,0xd1,0x00,0xbe,0x2b,0x68,0x6a,0x68,\n0x9b,0x1a,0x9f,0xd5,0x90,0xe7,0xc0,0x46,0x00,0x00,0xfc,0xef,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/cc26x0/cc26x0r2f.lds",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n/* Entry Point */\nENTRY( entry )\n\n/* System memory map */\nMEMORY\n{\n\t/* Application is stored in and executes from SRAM */\n\tPROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x1BD8\n\tBUFFERS (RWX) : ORIGIN = 0x20001BD8, LENGTH = 0x3028\n}\n\n/* Section allocation in memory */\nSECTIONS\n{\n\t.text :\n\t{\n\t\t_text = .;\n\t\t*(.entry*)\n\t\t*(.text*)\n\t\t_etext = .;\n\t} > PROGRAM\n\n\t.data :\n\t{\t_data = .;\n\t\t*(.rodata*)\n\t\t*(.data*)\n\t\t_edata = .;\n\t}\n\n\t.bss :\n\t{\n\t\t__bss_start__ = .;\n\t\t_bss = .;\n\t\t*(.bss*)\n\t\t*(COMMON)\n\t\t_ebss = .;\n\t\t__bss_end__ = .;\n\t} > PROGRAM\n\n\t.stack :\n\t{\n\t\t_stack = .;\n\t\t*(.stack*)\n\t\t_estack = .;\n\t} > PROGRAM\n\n\t.buffers :\n\t{\n\t\t_buffers = .;\n\t\t*(.buffers.g_cfg)\n\t\t*(.buffers.g_buf1)\n\t\t*(.buffers.g_buf2)\n\t\t*(.buffers*)\n\t\t_ebuffers = .;\n\t} > BUFFERS\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/cc26x0_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x08,0xb5,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0xdf,0xf8,0x1c,0xd0,0x07,0x48,\n0x07,0x49,0x4f,0xf0,0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,\n0x00,0xf0,0xa8,0xf9,0xfe,0xe7,0x00,0x00,0xf0,0x0e,0x00,0x20,0x54,0x13,0x00,0x20,\n0x98,0x13,0x00,0x20,0x08,0xb5,0x07,0x4b,0x07,0x48,0x03,0x33,0x1b,0x1a,0x06,0x2b,\n0x04,0xd9,0x06,0x4b,0x00,0x2b,0x01,0xd0,0x00,0xf0,0x5c,0xf8,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0xc0,0x46,0x50,0x13,0x00,0x20,0x50,0x13,0x00,0x20,0x00,0x00,0x00,0x00,\n0x08,0x48,0x09,0x49,0x09,0x1a,0x89,0x10,0x08,0xb5,0xcb,0x0f,0x59,0x18,0x49,0x10,\n0x04,0xd0,0x06,0x4b,0x00,0x2b,0x01,0xd0,0x00,0xf0,0x44,0xf8,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0xc0,0x46,0x50,0x13,0x00,0x20,0x50,0x13,0x00,0x20,0x00,0x00,0x00,0x00,\n0x10,0xb5,0x08,0x4c,0x23,0x78,0x00,0x2b,0x09,0xd1,0xff,0xf7,0xcb,0xff,0x06,0x4b,\n0x00,0x2b,0x02,0xd0,0x05,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbc,\n0x01,0xbc,0x00,0x47,0x54,0x13,0x00,0x20,0x00,0x00,0x00,0x00,0xe0,0x0e,0x00,0x20,\n0x08,0xb5,0x0b,0x4b,0x00,0x2b,0x03,0xd0,0x0a,0x48,0x0b,0x49,0xaf,0xf3,0x00,0x80,\n0x0a,0x48,0x03,0x68,0x00,0x2b,0x04,0xd1,0xff,0xf7,0xc2,0xff,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0x07,0x4b,0x00,0x2b,0xf7,0xd0,0x00,0xf0,0x0c,0xf8,0xf4,0xe7,0xc0,0x46,\n0x00,0x00,0x00,0x00,0xe0,0x0e,0x00,0x20,0x58,0x13,0x00,0x20,0x4c,0x13,0x00,0x20,\n0x00,0x00,0x00,0x00,0x18,0x47,0xc0,0x46,0xd4,0x30,0x9f,0xe5,0x00,0x00,0x53,0xe3,\n0xc8,0x30,0x9f,0x05,0x03,0xd0,0xa0,0xe1,0x00,0x20,0x0f,0xe1,0x0f,0x00,0x12,0xe3,\n0x15,0x00,0x00,0x0a,0xd1,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0xaa,0x4d,0xe2,\n0x0a,0x30,0xa0,0xe1,0xd7,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0x3a,0x43,0xe2,\n0xdb,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0x3a,0x43,0xe2,0xd2,0xf0,0x21,0xe3,\n0x03,0xd0,0xa0,0xe1,0x02,0x3a,0x43,0xe2,0xd3,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,\n0x02,0x39,0x43,0xe2,0xff,0x30,0xc3,0xe3,0xff,0x3c,0xc3,0xe3,0x04,0x30,0x03,0xe5,\n0x00,0x20,0x53,0xe9,0xc0,0x20,0x82,0xe3,0x02,0xf0,0x21,0xe1,0x01,0xa8,0x43,0xe2,\n0x00,0x10,0xb0,0xe3,0x01,0xb0,0xa0,0xe1,0x01,0x70,0xa0,0xe1,0x5c,0x00,0x9f,0xe5,\n0x5c,0x20,0x9f,0xe5,0x00,0x20,0x52,0xe0,0x01,0x30,0x8f,0xe2,0x13,0xff,0x2f,0xe1,\n0x00,0xf0,0x42,0xfd,0x10,0x4b,0x00,0x2b,0x01,0xd0,0xfe,0x46,0x9f,0x46,0x0f,0x4b,\n0x00,0x2b,0x01,0xd0,0xfe,0x46,0x9f,0x46,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,\n0x0d,0x48,0x00,0xf0,0x89,0xfc,0x00,0xf0,0xc3,0xfc,0x20,0x00,0x29,0x00,0x00,0xf0,\n0xd1,0xf8,0x00,0xf0,0x8b,0xfc,0x7b,0x46,0x18,0x47,0x00,0x00,0x11,0x00,0x00,0xef,\n0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x54,0x13,0x00,0x20,0x98,0x13,0x00,0x20,0x15,0x0b,0x00,0x20,0x70,0xb5,0x04,0x46,\n0x0e,0x46,0x15,0x46,0x00,0x21,0x28,0x22,0x00,0xf0,0x0e,0xfd,0x26,0x61,0x65,0x62,\n0x00,0x21,0x20,0x22,0x02,0x48,0x00,0xf0,0x07,0xfd,0x00,0x20,0x70,0xbd,0x00,0xbf,\n0x70,0x13,0x00,0x20,0x10,0xb5,0x01,0x20,0x00,0xf0,0xac,0xf9,0x04,0x46,0x28,0xb9,\n0x01,0x21,0x20,0x22,0x03,0x48,0x00,0xf0,0xf7,0xfc,0x01,0xe0,0x40,0xf2,0x01,0x14,\n0x20,0x46,0x10,0xbd,0x70,0x13,0x00,0x20,0x01,0x39,0xf8,0xb5,0x04,0x0b,0x08,0x44,\n0x05,0x0b,0x26,0x03,0xac,0x42,0x14,0xd8,0x0b,0x4f,0xe3,0x5d,0x6b,0xb9,0x30,0x46,\n0x00,0xf0,0xfc,0xf8,0x38,0xb1,0x00,0x04,0x00,0xf4,0x7f,0x00,0x40,0xea,0x04,0x60,\n0x40,0xf4,0x81,0x70,0xf8,0xbd,0x01,0x23,0xe3,0x55,0x01,0x34,0x06,0xf5,0x80,0x56,\n0xe8,0xe7,0x00,0x20,0xf8,0xbd,0x00,0xbf,0x70,0x13,0x00,0x20,0x2d,0xe9,0xf0,0x4f,\n0x0d,0x46,0x53,0x1e,0x85,0xb0,0x0b,0x44,0x02,0x90,0x4f,0xea,0x11,0x38,0x1b,0x0b,\n0x16,0x46,0x23,0x48,0x00,0x21,0x20,0x22,0x01,0x93,0x4f,0xea,0x08,0x37,0x00,0xf0,\n0xbb,0xfc,0x4f,0xf0,0x00,0x09,0xc5,0xf3,0x0b,0x0c,0x01,0x9b,0x98,0x45,0x33,0xd8,\n0x74,0x19,0x07,0xf5,0x80,0x5a,0x54,0x45,0x98,0xbf,0x34,0x46,0xdf,0xf8,0x64,0xb0,\n0x88,0xbf,0xc4,0xf3,0x0b,0x04,0x39,0x46,0x4f,0xf4,0x80,0x52,0x58,0x46,0x88,0xbf,\n0x34,0x1b,0xcd,0xf8,0x0c,0xc0,0x00,0xf0,0x5f,0xfc,0xdd,0xf8,0x0c,0xc0,0x02,0x9b,\n0x0b,0xeb,0x0c,0x00,0x03,0xeb,0x09,0x01,0x22,0x46,0x00,0xf0,0x55,0xfc,0x38,0x46,\n0x4f,0xf4,0x80,0x51,0x08,0xf1,0x01,0x08,0xff,0xf7,0x9e,0xff,0x68,0xb9,0x39,0x46,\n0x58,0x46,0x4f,0xf4,0x80,0x52,0x25,0x44,0x00,0xf0,0xae,0xf8,0x36,0x1b,0xc5,0xf3,\n0x0b,0x0c,0xa1,0x44,0x57,0x46,0xc8,0xe7,0x00,0x20,0x05,0xb0,0xbd,0xe8,0xf0,0x8f,\n0x70,0x13,0x00,0x20,0x00,0x3c,0x00,0x20,0xb2,0xf5,0x80,0x5f,0xf8,0xb5,0x07,0x46,\n0x0e,0x46,0x15,0x46,0x0b,0xd8,0x08,0x46,0x11,0x46,0xff,0xf7,0x7d,0xff,0x04,0x46,\n0x40,0xb9,0x38,0x46,0x31,0x46,0x2a,0x46,0x00,0xf0,0x8e,0xf8,0x02,0xe0,0x4f,0xf4,\n0x82,0x70,0xf8,0xbd,0x20,0x46,0xf8,0xbd,0x08,0xb5,0x00,0xf0,0x85,0xf8,0x00,0x20,\n0x08,0xbd,0x00,0x00,0xf8,0xb5,0x31,0x48,0x31,0x49,0x32,0x4a,0x32,0x4c,0xff,0xf7,\n0x3d,0xff,0x00,0x23,0x23,0x60,0x22,0x68,0x2c,0x4f,0x14,0x23,0x03,0xfb,0x02,0x73,\n0x08,0x33,0x5b,0x68,0x00,0x2b,0xf7,0xd0,0x2c,0x4b,0x1a,0x68,0x11,0x07,0xfb,0xd4,\n0x2b,0x4d,0x2c,0x4e,0x2a,0x68,0x32,0x60,0x42,0xf0,0x33,0x02,0x2a,0x60,0x1a,0x68,\n0x12,0x07,0xfc,0xd4,0x21,0x68,0x14,0x22,0x02,0xfb,0x01,0x73,0x98,0x68,0x13,0x46,\n0x01,0x38,0x04,0x28,0x26,0xd8,0xdf,0xe8,0x00,0xf0,0x03,0x06,0x0e,0x16,0x1e,0x00,\n0xff,0xf7,0x28,0xff,0x20,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0xc2,0xff,0x18,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0xa2,0xff,0x10,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0x44,0xff,0x08,0xe0,0x4b,0x43,0xfa,0x18,0xf8,0x58,0x51,0x68,0xff,0xf7,\n0x1b,0xff,0x01,0xe0,0x40,0xf2,0x05,0x10,0x33,0x68,0x2b,0x60,0x0b,0x4b,0x1b,0x68,\n0x1b,0x07,0xfb,0xd4,0x22,0x68,0x14,0x23,0x03,0xfb,0x02,0x77,0xfb,0x68,0xf8,0x60,\n0x00,0xb1,0xfe,0xe7,0x82,0xf0,0x01,0x02,0x22,0x60,0xa4,0xe7,0xd8,0x1b,0x00,0x20,\n0x00,0x1c,0x00,0x20,0x00,0x2c,0x00,0x20,0x90,0x13,0x00,0x20,0x00,0x40,0x03,0x40,\n0x04,0x40,0x03,0x40,0x94,0x13,0x00,0x20,0xfe,0xe7,0x00,0x00,0x08,0xb5,0x04,0x4b,\n0x1b,0x68,0x5b,0x69,0x98,0x47,0x03,0x4b,0x00,0x22,0x1a,0x60,0x08,0xbd,0x00,0xbf,\n0xa8,0x01,0x00,0x10,0x84,0x04,0x60,0x42,0x08,0xb5,0x04,0x4b,0x1b,0x68,0x9b,0x69,\n0x98,0x47,0x03,0x4b,0x00,0x22,0x1a,0x60,0x08,0xbd,0x00,0xbf,0xa8,0x01,0x00,0x10,\n0x84,0x04,0x60,0x42,0x10,0xb5,0x33,0x4b,0x33,0x48,0x1b,0x68,0x33,0x4a,0x13,0xf0,\n0x02,0x0f,0x03,0x68,0x43,0xf0,0x02,0x03,0x03,0x60,0x13,0x68,0x01,0x68,0x19,0xd0,\n0x21,0xf4,0xe1,0x72,0xc3,0xf3,0xc1,0x04,0x22,0xf0,0x01,0x02,0x22,0x43,0xc3,0xf3,\n0xc0,0x11,0x42,0xea,0x01,0x22,0xc3,0xf3,0x41,0x11,0x42,0xea,0x81,0x12,0x02,0x60,\n0x02,0x68,0xd4,0x07,0x03,0xd5,0x26,0x4a,0x12,0x68,0x50,0x07,0xfb,0xd5,0x03,0xf0,\n0x07,0x03,0x18,0xe0,0x21,0xf4,0xe1,0x72,0xc3,0xf3,0xc1,0x24,0x22,0xf0,0x01,0x02,\n0xc3,0xf3,0xc0,0x31,0x22,0x43,0x42,0xea,0x01,0x22,0xc3,0xf3,0x41,0x31,0x42,0xea,\n0x81,0x12,0x02,0x60,0x02,0x68,0xd1,0x07,0x03,0xd5,0x19,0x4a,0x12,0x68,0x52,0x07,\n0xfb,0xd5,0xc3,0xf3,0x02,0x23,0x4a,0xf6,0xaa,0x22,0x16,0x49,0x16,0x48,0x0a,0x60,\n0x02,0x68,0x1b,0x03,0xb3,0xf5,0xe0,0x4f,0x22,0xf4,0xe2,0x42,0x18,0xbf,0x43,0xf4,\n0x80,0x73,0x13,0x43,0x03,0x60,0x45,0xf2,0xaa,0x53,0x0b,0x60,0x0f,0x4b,0x10,0x49,\n0x01,0x22,0x1a,0x60,0x00,0x22,0x0a,0x60,0x1a,0x60,0x05,0x22,0xc3,0xf8,0x58,0x22,\n0x4f,0xf0,0xff,0x32,0xc1,0xf8,0x8c,0x22,0xc1,0xf8,0x90,0x22,0x02,0x22,0xc3,0xf8,\n0x58,0x22,0x10,0xbd,0x00,0x00,0x09,0x40,0x24,0x00,0x03,0x40,0x08,0x13,0x00,0x50,\n0x1c,0x00,0x03,0x40,0x64,0x20,0x03,0x40,0xa8,0x20,0x03,0x40,0x30,0x20,0x03,0x40,\n0x34,0x20,0x03,0x40,0x2d,0xe9,0xf8,0x4f,0xd4,0x4d,0x29,0x68,0x11,0xf0,0x01,0x01,\n0x40,0xf0,0x95,0x81,0xdf,0xf8,0x90,0xe3,0x05,0x27,0xd1,0x4b,0xce,0xf8,0x00,0x70,\n0x1b,0x68,0x4f,0xf4,0x40,0x72,0xc3,0xf3,0x03,0x23,0x01,0x33,0xb2,0xfb,0xf3,0xf3,\n0xdf,0xf8,0x78,0xc3,0xdf,0xf8,0x78,0x83,0xdc,0xf8,0x00,0x20,0xd8,0xf8,0x00,0x40,\n0x92,0xb2,0x5a,0x43,0xc2,0xf3,0x8f,0x16,0x22,0x0c,0x12,0x04,0x32,0x43,0xc8,0xf8,\n0x00,0x20,0xc4,0x4a,0xc4,0x4c,0x12,0x68,0x26,0x68,0x5a,0x43,0xc3,0x4e,0x92,0x09,\n0x22,0x60,0x32,0x68,0x54,0xf8,0x24,0x8c,0xc2,0xf3,0x07,0x42,0x5a,0x43,0x28,0xf0,\n0xff,0x08,0xc2,0xf3,0x87,0x12,0xdf,0xf8,0x3c,0x93,0x42,0xea,0x08,0x02,0xdf,0xf8,\n0x38,0x83,0x44,0xf8,0x24,0x2c,0xd9,0xf8,0x00,0xa0,0xd8,0xf8,0x00,0x20,0xca,0xf3,\n0x07,0x4a,0x22,0xf0,0xff,0x02,0x4a,0xea,0x02,0x02,0xc8,0xf8,0x00,0x20,0xd9,0xf8,\n0x00,0x20,0xdf,0xf8,0x18,0xa3,0x12,0x0e,0x5a,0x43,0xda,0xf8,0x00,0x80,0x92,0x00,\n0x28,0xf4,0x7f,0x48,0x02,0xf4,0x7f,0x42,0x42,0xea,0x08,0x02,0xdf,0xf8,0x00,0x83,\n0xca,0xf8,0x00,0x20,0xd8,0xf8,0x00,0x20,0xae,0xf5,0x09,0x7e,0x4f,0xea,0x12,0x6b,\n0x0b,0xfb,0x03,0xfb,0xda,0xf8,0x04,0x20,0xcb,0xf3,0x8f,0x1b,0x12,0x0c,0x12,0x04,\n0x4b,0xea,0x02,0x02,0xca,0xf8,0x04,0x20,0xd9,0xf8,0x00,0x20,0xc2,0xf3,0x07,0x22,\n0x53,0x43,0x9f,0x4a,0x9b,0x00,0xd2,0xf8,0x00,0x90,0x03,0xf4,0x7f,0x43,0x29,0xf4,\n0x7f,0x49,0x43,0xea,0x09,0x03,0xdf,0xf8,0xbc,0x92,0x13,0x60,0xd9,0xf8,0x00,0xa0,\n0x52,0xf8,0x24,0x3c,0x4f,0xea,0x1a,0x6a,0x23,0xf4,0x7f,0x43,0x43,0xea,0x0a,0x23,\n0x42,0xf8,0x24,0x3c,0xd9,0xf8,0x00,0xa0,0x52,0xf8,0x24,0x3c,0xca,0xf3,0x07,0x4a,\n0x23,0xf0,0xff,0x03,0x4a,0xea,0x03,0x03,0x42,0xf8,0x24,0x3c,0xd9,0xf8,0x00,0xa0,\n0x52,0xf8,0x1c,0x3c,0x0a,0xf4,0x7f,0x4a,0x23,0xf4,0x7f,0x43,0x4a,0xea,0x03,0x03,\n0x42,0xf8,0x1c,0x3c,0xd9,0xf8,0x00,0x90,0x52,0xf8,0x1c,0x3c,0x5f,0xfa,0x89,0xf9,\n0x23,0xf0,0xff,0x03,0x49,0xea,0x03,0x03,0xdf,0xf8,0x5c,0x92,0x42,0xf8,0x1c,0x3c,\n0x32,0x68,0xd9,0xf8,0x00,0x30,0x02,0xf4,0x70,0x42,0x23,0xf4,0x70,0x43,0x13,0x43,\n0xc9,0xf8,0x00,0x30,0xd8,0xf8,0x00,0x20,0xdf,0xf8,0x40,0x82,0x02,0xf4,0x70,0x42,\n0xd8,0xf8,0x00,0x30,0x23,0xf4,0x70,0x43,0x13,0x43,0xc8,0xf8,0x00,0x30,0x32,0x68,\n0x54,0xf8,0x24,0x3c,0x12,0x0e,0x23,0xf4,0x7f,0x43,0x43,0xea,0x02,0x23,0x44,0xf8,\n0x24,0x3c,0x70,0x4b,0x1b,0x68,0x62,0x6a,0xc3,0xf3,0x0b,0x06,0x22,0xf4,0x7f,0x63,\n0x23,0xf0,0x0f,0x03,0x33,0x43,0x6c,0x4e,0x63,0x62,0x32,0x68,0x63,0x6a,0x02,0xf4,\n0x70,0x22,0x23,0xf4,0x70,0x23,0x13,0x43,0x63,0x62,0x68,0x4c,0x22,0x68,0xd8,0xf8,\n0x58,0x30,0xc2,0xf3,0x83,0x42,0x23,0xf4,0x70,0x23,0x43,0xea,0x02,0x43,0xc8,0xf8,\n0x58,0x30,0xdc,0xf8,0x00,0x30,0xd8,0xf8,0x58,0x20,0xc3,0xf3,0x0b,0x4c,0x22,0xf4,\n0x7f,0x63,0x23,0xf0,0x0f,0x03,0x4c,0xea,0x03,0x03,0xc8,0xf8,0x58,0x30,0x23,0x68,\n0xd8,0xf8,0x5c,0x20,0x4f,0xea,0xd3,0x5c,0x22,0xf0,0xff,0x73,0x23,0xf4,0x80,0x33,\n0x43,0xea,0x0c,0x43,0xc8,0xf8,0x5c,0x30,0x33,0x68,0x55,0x4a,0x0f,0x33,0x03,0xf0,\n0x0f,0x03,0x13,0x60,0x26,0x68,0x53,0x68,0xc6,0xf3,0x80,0x56,0x23,0xf4,0x00,0x03,\n0x43,0xea,0xc6,0x53,0x53,0x60,0x53,0x68,0x4e,0x4e,0x43,0xf4,0x80,0x43,0x53,0x60,\n0x02,0x23,0xce,0xf8,0x24,0x32,0x4a,0xf6,0xaa,0x23,0xdf,0xf8,0x74,0xc1,0xce,0xf8,\n0x00,0x30,0xdc,0xf8,0x00,0x30,0x32,0x68,0x03,0xf0,0x0f,0x08,0x22,0xf4,0x7f,0x02,\n0x42,0xea,0x08,0x42,0xc3,0xf3,0x03,0x23,0x42,0xea,0x03,0x53,0xdf,0xf8,0x54,0x81,\n0x33,0x60,0xd8,0xf8,0x00,0x30,0x32,0x68,0xc3,0xf3,0x03,0x49,0x22,0xf0,0xff,0x02,\n0x49,0xea,0x02,0x02,0xc3,0xf3,0x03,0x63,0x42,0xea,0x03,0x13,0x33,0x60,0xdc,0xf8,\n0x00,0x60,0xdf,0xf8,0x34,0xc1,0x06,0xf4,0x70,0x22,0xdc,0xf8,0x00,0x30,0x23,0xf4,\n0x7f,0x03,0x1a,0x43,0xc6,0xf3,0x03,0x63,0x42,0xea,0x03,0x53,0x32,0x4e,0xcc,0xf8,\n0x00,0x30,0x32,0x68,0x5c,0xf8,0x08,0x3c,0xc2,0xf3,0x03,0x22,0x23,0xf0,0x0f,0x03,\n0x13,0x43,0x4c,0xf8,0x08,0x3c,0xd8,0xf8,0x00,0x20,0xdc,0xf8,0x08,0x30,0x02,0xf4,\n0xf8,0x52,0x23,0xf4,0xf8,0x53,0x13,0x43,0xcc,0xf8,0x08,0x30,0x32,0x68,0xdc,0xf8,\n0x0c,0x30,0x12,0x0b,0x02,0xf4,0x70,0x42,0x23,0xf4,0x70,0x43,0x13,0x43,0xcc,0xf8,\n0x0c,0x30,0x32,0x68,0x21,0x4e,0xc2,0xf3,0x04,0x42,0x33,0x68,0x23,0xf0,0x1f,0x03,\n0x13,0x43,0x33,0x60,0x22,0x68,0x1e,0x4c,0xc2,0xf3,0x01,0x42,0x23,0x68,0x23,0xf4,\n0x40,0x13,0x43,0xea,0x02,0x53,0x23,0x60,0x45,0xf2,0xaa,0x53,0x19,0x4a,0xce,0xf8,\n0x00,0x30,0x17,0x60,0x2b,0x68,0x43,0xf0,0x01,0x03,0x2b,0x60,0x11,0x60,0x16,0x4b,\n0x16,0x4c,0x1b,0x68,0x16,0x4a,0x13,0xf0,0x02,0x0f,0x23,0x68,0x15,0x4d,0x43,0xf0,\n0x02,0x03,0x23,0x60,0x13,0x68,0x21,0x68,0x59,0xd0,0x3f,0xe0,0x40,0x00,0x03,0x40,\n0x00,0x20,0x03,0x40,0x8c,0x11,0x00,0x50,0x44,0x22,0x03,0x40,0x74,0x11,0x00,0x50,\n0x34,0x22,0x03,0x40,0x84,0x11,0x00,0x50,0x80,0x11,0x00,0x50,0xb0,0x12,0x00,0x50,\n0x78,0x22,0x03,0x40,0x84,0x20,0x03,0x40,0x98,0x11,0x00,0x50,0x98,0x20,0x03,0x40,\n0xa8,0x20,0x03,0x40,0x3c,0x00,0x03,0x40,0x00,0x00,0x09,0x40,0x24,0x00,0x03,0x40,\n0x08,0x13,0x00,0x50,0x1c,0x00,0x03,0x40,0x88,0x22,0x03,0x40,0x88,0x11,0x00,0x50,\n0x40,0x22,0x03,0x40,0x78,0x11,0x00,0x50,0x24,0x22,0x03,0x40,0x28,0x22,0x03,0x40,\n0x7c,0x11,0x00,0x50,0x70,0x11,0x00,0x50,0x1c,0x22,0x03,0x40,0x14,0x22,0x03,0x40,\n0x90,0x11,0x00,0x50,0x94,0x11,0x00,0x50,0x88,0x20,0x03,0x40,0x21,0xf4,0xe1,0x72,\n0xc3,0xf3,0xc1,0x46,0x22,0xf0,0x01,0x02,0xc3,0xf3,0xc0,0x51,0x32,0x43,0x42,0xea,\n0x01,0x22,0xc3,0xf3,0x41,0x51,0x42,0xea,0x81,0x12,0x22,0x60,0x22,0x68,0xd7,0x07,\n0x02,0xd5,0x2a,0x68,0x56,0x07,0xfc,0xd5,0xc3,0xf3,0x02,0x43,0x16,0xe0,0xc3,0xf3,\n0xc1,0x62,0xde,0x0f,0x42,0xea,0x06,0x26,0x21,0xf4,0xe1,0x72,0x22,0xf0,0x01,0x02,\n0x32,0x43,0xc3,0xf3,0x41,0x71,0x42,0xea,0x81,0x12,0x22,0x60,0x22,0x68,0xd4,0x07,\n0x02,0xd5,0x2a,0x68,0x51,0x07,0xfc,0xd5,0xc3,0xf3,0x02,0x63,0x4a,0xf6,0xaa,0x22,\n0x3a,0x49,0x3b,0x4c,0x0a,0x60,0x22,0x68,0x1b,0x03,0xb3,0xf5,0xe0,0x4f,0x22,0xf4,\n0xe2,0x42,0x18,0xbf,0x43,0xf4,0x80,0x73,0x13,0x43,0x23,0x60,0x45,0xf2,0xaa,0x53,\n0x4f,0xf6,0xff,0x74,0x0b,0x60,0x33,0x4b,0x00,0x21,0x01,0x22,0x19,0x60,0x43,0xf8,\n0x20,0x2c,0x31,0x4a,0x4f,0xf0,0x05,0x0e,0x14,0x60,0x30,0x4c,0x43,0xf8,0x20,0x1c,\n0x02,0xf5,0xec,0x72,0x10,0x23,0xc4,0xf8,0x00,0xe0,0x13,0x60,0x2c,0x4b,0x15,0x26,\n0x1e,0x60,0x02,0x26,0x26,0x60,0x2b,0x4e,0x37,0x68,0xc4,0xf8,0x00,0xe0,0xdf,0xf8,\n0xb4,0xe0,0xce,0xf8,0x00,0x10,0xce,0xf8,0x04,0x10,0x18,0xb1,0x31,0x68,0x41,0xf4,\n0x00,0x01,0x31,0x60,0x02,0x21,0x05,0x20,0x21,0x60,0x20,0x60,0x08,0x20,0x10,0x60,\n0x15,0x22,0x1a,0x60,0x21,0x60,0x2b,0x68,0x9a,0x07,0xfc,0xd4,0x1e,0x4b,0x1b,0x68,\n0x13,0xf0,0x10,0x0f,0x14,0xbf,0x04,0x25,0x00,0x25,0xff,0xf7,0x1b,0xfd,0x3b,0x02,\n0x07,0xd4,0x05,0x23,0x23,0x60,0x33,0x68,0x23,0xf4,0x00,0x03,0x33,0x60,0x02,0x23,\n0x23,0x60,0xbd,0xb9,0x15,0x4b,0x16,0x48,0x19,0x68,0x03,0xf5,0x10,0x53,0x04,0x33,\n0x1a,0x68,0xc9,0xb2,0x02,0xf0,0x0f,0x02,0x51,0x43,0x1b,0x68,0x14,0x22,0x03,0xf0,\n0x0f,0x03,0x9b,0x02,0xc3,0xeb,0x81,0x21,0x01,0xf6,0xd8,0x71,0xbd,0xe8,0xf8,0x4f,\n0xff,0xf7,0xea,0xbc,0x28,0x46,0xbd,0xe8,0xf8,0x8f,0x00,0xbf,0x64,0x20,0x03,0x40,\n0xa8,0x20,0x03,0x40,0x50,0x20,0x03,0x40,0x34,0x20,0x03,0x40,0x88,0x22,0x03,0x40,\n0xb4,0x22,0x03,0x40,0x7c,0x22,0x03,0x40,0x54,0x20,0x03,0x40,0x2c,0x00,0x03,0x40,\n0xf4,0x0e,0x00,0x20,0xc0,0x22,0x03,0x40,0x08,0xb5,0x01,0x1c,0x00,0x22,0x00,0x20,\n0x00,0x23,0x00,0xf0,0xeb,0xf8,0x08,0xbc,0x02,0xbc,0x08,0x47,0x10,0xb5,0x00,0x21,\n0x04,0x1c,0x00,0xf0,0x5d,0xf9,0x05,0x4b,0x18,0x68,0xc3,0x6b,0x00,0x2b,0x01,0xd0,\n0x00,0xf0,0x06,0xf8,0x20,0x1c,0xff,0xf7,0xa7,0xfc,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x18,0x47,0xc0,0x46,0x38,0xb5,0x0a,0x4b,0x0a,0x4c,0xe4,0x1a,0xa4,0x10,0x0a,0xd0,\n0x09,0x4a,0xa5,0x18,0xad,0x00,0xed,0x18,0x2b,0x68,0x01,0x3c,0x00,0xf0,0x0e,0xf8,\n0x04,0x3d,0x00,0x2c,0xf8,0xd1,0x00,0xf0,0xcd,0xf9,0x38,0xbc,0x01,0xbc,0x00,0x47,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x3f,0x18,0x47,0xc0,0x46,\n0x70,0xb5,0x10,0x4e,0x10,0x4d,0xad,0x1b,0xad,0x10,0x00,0x24,0x00,0x2d,0x06,0xd0,\n0xa3,0x00,0xf3,0x58,0x01,0x34,0x00,0xf0,0x1d,0xf8,0xa5,0x42,0xf8,0xd1,0x00,0xf0,\n0xab,0xf9,0x0a,0x4e,0x0a,0x4d,0xad,0x1b,0xad,0x10,0x00,0x24,0x00,0x2d,0x06,0xd0,\n0xa3,0x00,0xf3,0x58,0x01,0x34,0x00,0xf0,0x0d,0xf8,0xa5,0x42,0xf8,0xd1,0x70,0xbc,\n0x01,0xbc,0x00,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x18,0x47,0xc0,0x46,0x70,0xb5,0x0f,0x2a,0x34,0xd9,0x04,0x1c,\n0x0c,0x43,0x0b,0x1c,0xa4,0x07,0x33,0xd1,0x15,0x1c,0x04,0x1c,0x10,0x3d,0x2d,0x09,\n0x01,0x35,0x2d,0x01,0x49,0x19,0x1e,0x68,0x26,0x60,0x5e,0x68,0x66,0x60,0x9e,0x68,\n0xa6,0x60,0xde,0x68,0x10,0x33,0xe6,0x60,0x10,0x34,0x99,0x42,0xf3,0xd1,0x0f,0x23,\n0x45,0x19,0x13,0x40,0x03,0x2b,0x1d,0xd9,0x1c,0x1f,0x00,0x23,0xa4,0x08,0x01,0x34,\n0xa4,0x00,0xce,0x58,0xee,0x50,0x04,0x33,0xa3,0x42,0xfa,0xd1,0xed,0x18,0xc9,0x18,\n0x03,0x23,0x1a,0x40,0x05,0xd0,0x00,0x23,0xcc,0x5c,0xec,0x54,0x01,0x33,0x93,0x42,\n0xfa,0xd1,0x70,0xbc,0x02,0xbc,0x08,0x47,0x05,0x1c,0x00,0x2a,0xf3,0xd1,0xf8,0xe7,\n0x05,0x1c,0xf0,0xe7,0x1a,0x1c,0xf8,0xe7,0x70,0xb5,0x83,0x07,0x43,0xd0,0x54,0x1e,\n0x00,0x2a,0x3d,0xd0,0x0d,0x06,0x2d,0x0e,0x03,0x1c,0x03,0x26,0x03,0xe0,0x62,0x1e,\n0x00,0x2c,0x35,0xd0,0x14,0x1c,0x01,0x33,0x5a,0x1e,0x15,0x70,0x33,0x42,0xf6,0xd1,\n0x03,0x2c,0x24,0xd9,0xff,0x25,0x0d,0x40,0x2a,0x02,0x15,0x43,0x2a,0x04,0x15,0x43,\n0x0f,0x2c,0x11,0xd9,0x26,0x1c,0x10,0x3e,0x36,0x09,0x01,0x36,0x36,0x01,0x1a,0x1c,\n0x9b,0x19,0x15,0x60,0x55,0x60,0x95,0x60,0xd5,0x60,0x10,0x32,0x93,0x42,0xf8,0xd1,\n0x0f,0x22,0x14,0x40,0x03,0x2c,0x0a,0xd9,0x26,0x1f,0xb6,0x08,0x01,0x36,0xb6,0x00,\n0x1a,0x1c,0x9b,0x19,0x20,0xc2,0x93,0x42,0xfc,0xd1,0x03,0x22,0x14,0x40,0x00,0x2c,\n0x06,0xd0,0x09,0x06,0x1c,0x19,0x09,0x0e,0x19,0x70,0x01,0x33,0xa3,0x42,0xfb,0xd1,\n0x70,0xbc,0x02,0xbc,0x08,0x47,0x14,0x1c,0x03,0x1c,0xc9,0xe7,0xf8,0xb5,0x44,0x46,\n0x5f,0x46,0x56,0x46,0x4d,0x46,0x9b,0x46,0x30,0x4b,0xf0,0xb4,0x1c,0x68,0xa4,0x23,\n0x5b,0x00,0x05,0x1c,0xe0,0x58,0x0e,0x1c,0x90,0x46,0x00,0x28,0x4d,0xd0,0x43,0x68,\n0x1f,0x2b,0x0f,0xdc,0x5c,0x1c,0x00,0x2d,0x23,0xd1,0x02,0x33,0x9b,0x00,0x44,0x60,\n0x1e,0x50,0x00,0x20,0x3c,0xbc,0x90,0x46,0x99,0x46,0xa2,0x46,0xab,0x46,0xf8,0xbc,\n0x02,0xbc,0x08,0x47,0x22,0x4b,0x00,0x2b,0x3c,0xd0,0xc8,0x20,0x40,0x00,0xaf,0xf3,\n0x00,0x80,0x00,0x28,0x36,0xd0,0xa4,0x22,0x00,0x23,0x52,0x00,0xa1,0x58,0x43,0x60,\n0x01,0x60,0xa0,0x50,0x40,0x32,0x83,0x50,0x04,0x32,0x83,0x50,0x01,0x24,0x00,0x2d,\n0xdb,0xd0,0x9a,0x00,0x91,0x46,0x81,0x44,0x42,0x46,0x88,0x21,0x4f,0x46,0x7a,0x50,\n0xc4,0x22,0x52,0x00,0x90,0x46,0x80,0x44,0x42,0x46,0x87,0x39,0x99,0x40,0x12,0x68,\n0x0a,0x43,0x94,0x46,0x8a,0x46,0x42,0x46,0x61,0x46,0x11,0x60,0x84,0x22,0x49,0x46,\n0x5f,0x46,0x52,0x00,0x8f,0x50,0x02,0x2d,0xbf,0xd1,0x02,0x1c,0x55,0x46,0x8d,0x32,\n0xff,0x32,0x11,0x68,0x0d,0x43,0x15,0x60,0xb7,0xe7,0x20,0x1c,0x4d,0x30,0xff,0x30,\n0xe0,0x50,0xac,0xe7,0x01,0x20,0x40,0x42,0xb4,0xe7,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x08,0xb5,0x04,0x4b,0x00,0x2b,0x02,0xd0,0x03,0x48,0xff,0xf7,\n0x9b,0xfe,0x08,0xbc,0x01,0xbc,0x00,0x47,0x00,0x00,0x00,0x00,0x15,0x0b,0x00,0x20,\n0xf0,0xb5,0x56,0x46,0x5f,0x46,0x4d,0x46,0x44,0x46,0xf0,0xb4,0x0e,0x1c,0x3f,0x4b,\n0x1b,0x68,0x87,0xb0,0x03,0x93,0x49,0x33,0xff,0x33,0x01,0x90,0x04,0x93,0xa4,0x22,\n0x03,0x9b,0x52,0x00,0x9f,0x58,0x00,0x2f,0x4d,0xd0,0x04,0x9b,0x98,0x46,0x00,0x23,\n0x9b,0x46,0xc4,0x23,0x5b,0x00,0x9c,0x46,0xbc,0x44,0x63,0x46,0x02,0x93,0xc6,0x23,\n0x5b,0x00,0x9a,0x46,0x7c,0x68,0xa5,0x00,0x7d,0x19,0xba,0x44,0x01,0x3c,0x08,0xd5,\n0x27,0xe0,0x6b,0x1d,0xff,0x33,0x1b,0x68,0xb3,0x42,0x04,0xd0,0x04,0x3d,0x01,0x3c,\n0x1f,0xd3,0x00,0x2e,0xf5,0xd1,0x7b,0x68,0x01,0x3b,0x6a,0x68,0xa3,0x42,0x3e,0xd0,\n0x5b,0x46,0x6b,0x60,0x00,0x2a,0xf1,0xd0,0x7b,0x68,0x99,0x46,0x01,0x23,0xa3,0x40,\n0x02,0x99,0x09,0x68,0x05,0x91,0x19,0x42,0x26,0xd1,0x00,0xf0,0x43,0xf8,0x7b,0x68,\n0x4b,0x45,0xc4,0xd1,0x43,0x46,0x1b,0x68,0xbb,0x42,0xc0,0xd1,0x04,0x3d,0x01,0x3c,\n0xdf,0xd2,0x1b,0x4b,0x00,0x2b,0x0e,0xd0,0x7b,0x68,0x00,0x2b,0x27,0xd1,0x3b,0x68,\n0x00,0x2b,0x28,0xd0,0x42,0x46,0x38,0x1c,0x13,0x60,0xaf,0xf3,0x00,0x80,0x43,0x46,\n0x1f,0x68,0x00,0x2f,0xb5,0xd1,0x07,0xb0,0x3c,0xbc,0x90,0x46,0x99,0x46,0xa2,0x46,\n0xab,0x46,0xf0,0xbc,0x01,0xbc,0x00,0x47,0x51,0x46,0x09,0x68,0x19,0x42,0x08,0xd1,\n0x2b,0x1c,0x84,0x33,0x19,0x68,0x01,0x98,0x00,0xf0,0x14,0xf8,0xcf,0xe7,0x7c,0x60,\n0xc0,0xe7,0x2b,0x1c,0x84,0x33,0x18,0x68,0x00,0xf0,0x0c,0xf8,0xc7,0xe7,0x3b,0x68,\n0xb8,0x46,0x1f,0x1c,0xdd,0xe7,0x00,0x23,0xfa,0xe7,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x10,0x47,0xc0,0x46,0xf8,0xb5,0xc0,0x46,0xf8,0xbc,0x08,0xbc,\n0x9e,0x46,0x70,0x47,0xf8,0xb5,0xc0,0x46,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,\n0x00,0x00,0x00,0x00,0x24,0xf2,0xff,0x7f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x28,0x15,0x00,0x20,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,\n0xc5,0xc5,0xc5,0xff,0xc5,0xc5,0xc5,0xff,0x43,0x00,0x00,0x00,0x18,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x12,0x00,0x20,\n0x6c,0x12,0x00,0x20,0xd4,0x12,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,\n0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x18,0x0f,0x00,0x20,0xc1,0x00,0x00,0x20,0x91,0x00,0x00,0x20,0x00,0x00,0x00,0x00,\n0x95,0x0d,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/cc26x2/cc26x2r1f.lds",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n/* Entry Point */\nENTRY( entry )\n\n/* System memory map */\nMEMORY\n{\n\t/* Application is stored in and executes from SRAM */\n\tPROGRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x1FD8\n\tBUFFERS (RWX) : ORIGIN = 0x20001FD8, LENGTH = 0x6028\n}\n\n/* Section allocation in memory */\nSECTIONS\n{\n\t.text :\n\t{\n\t\t_text = .;\n\t\t*(.entry*)\n\t\t*(.text*)\n\t\t_etext = .;\n\t} > PROGRAM\n\n\t.data :\n\t{\t_data = .;\n\t\t*(.rodata*)\n\t\t*(.data*)\n\t\t_edata = .;\n\t}\n\n\t.bss :\n\t{\n\t\t__bss_start__ = .;\n\t\t_bss = .;\n\t\t*(.bss*)\n\t\t*(COMMON)\n\t\t_ebss = .;\n\t\t__bss_end__ = .;\n\t} > PROGRAM\n\n\t.stack :\n\t{\n\t\t_stack = .;\n\t\t*(.stack*)\n\t\t_estack = .;\n\t} > PROGRAM\n\n\t.buffers :\n\t{\n\t\t_buffers = .;\n\t\t*(.buffers.g_cfg)\n\t\t*(.buffers.g_buf1)\n\t\t*(.buffers.g_buf2)\n\t\t*(.buffers*)\n\t\t_ebuffers = .;\n\t} > BUFFERS\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/cc26x2_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x08,0xb5,0x00,0xbf,0x00,0xbf,0x00,0xbf,0x00,0xbf,0xdf,0xf8,0x1c,0xd0,0x07,0x48,\n0x07,0x49,0x4f,0xf0,0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,\n0x00,0xf0,0xa8,0xf9,0xfe,0xe7,0x00,0x00,0xf0,0x0e,0x00,0x20,0x54,0x13,0x00,0x20,\n0xfc,0x13,0x00,0x20,0x08,0xb5,0x07,0x4b,0x07,0x48,0x03,0x33,0x1b,0x1a,0x06,0x2b,\n0x04,0xd9,0x06,0x4b,0x00,0x2b,0x01,0xd0,0x00,0xf0,0x5c,0xf8,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0xc0,0x46,0x50,0x13,0x00,0x20,0x50,0x13,0x00,0x20,0x00,0x00,0x00,0x00,\n0x08,0x48,0x09,0x49,0x09,0x1a,0x89,0x10,0x08,0xb5,0xcb,0x0f,0x59,0x18,0x49,0x10,\n0x04,0xd0,0x06,0x4b,0x00,0x2b,0x01,0xd0,0x00,0xf0,0x44,0xf8,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0xc0,0x46,0x50,0x13,0x00,0x20,0x50,0x13,0x00,0x20,0x00,0x00,0x00,0x00,\n0x10,0xb5,0x08,0x4c,0x23,0x78,0x00,0x2b,0x09,0xd1,0xff,0xf7,0xcb,0xff,0x06,0x4b,\n0x00,0x2b,0x02,0xd0,0x05,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbc,\n0x01,0xbc,0x00,0x47,0x54,0x13,0x00,0x20,0x00,0x00,0x00,0x00,0xe0,0x0e,0x00,0x20,\n0x08,0xb5,0x0b,0x4b,0x00,0x2b,0x03,0xd0,0x0a,0x48,0x0b,0x49,0xaf,0xf3,0x00,0x80,\n0x0a,0x48,0x03,0x68,0x00,0x2b,0x04,0xd1,0xff,0xf7,0xc2,0xff,0x08,0xbc,0x01,0xbc,\n0x00,0x47,0x07,0x4b,0x00,0x2b,0xf7,0xd0,0x00,0xf0,0x0c,0xf8,0xf4,0xe7,0xc0,0x46,\n0x00,0x00,0x00,0x00,0xe0,0x0e,0x00,0x20,0x58,0x13,0x00,0x20,0x4c,0x13,0x00,0x20,\n0x00,0x00,0x00,0x00,0x18,0x47,0xc0,0x46,0xd4,0x30,0x9f,0xe5,0x00,0x00,0x53,0xe3,\n0xc8,0x30,0x9f,0x05,0x03,0xd0,0xa0,0xe1,0x00,0x20,0x0f,0xe1,0x0f,0x00,0x12,0xe3,\n0x15,0x00,0x00,0x0a,0xd1,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0xaa,0x4d,0xe2,\n0x0a,0x30,0xa0,0xe1,0xd7,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0x3a,0x43,0xe2,\n0xdb,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,0x01,0x3a,0x43,0xe2,0xd2,0xf0,0x21,0xe3,\n0x03,0xd0,0xa0,0xe1,0x02,0x3a,0x43,0xe2,0xd3,0xf0,0x21,0xe3,0x03,0xd0,0xa0,0xe1,\n0x02,0x39,0x43,0xe2,0xff,0x30,0xc3,0xe3,0xff,0x3c,0xc3,0xe3,0x04,0x30,0x03,0xe5,\n0x00,0x20,0x53,0xe9,0xc0,0x20,0x82,0xe3,0x02,0xf0,0x21,0xe1,0x01,0xa8,0x43,0xe2,\n0x00,0x10,0xb0,0xe3,0x01,0xb0,0xa0,0xe1,0x01,0x70,0xa0,0xe1,0x5c,0x00,0x9f,0xe5,\n0x5c,0x20,0x9f,0xe5,0x00,0x20,0x52,0xe0,0x01,0x30,0x8f,0xe2,0x13,0xff,0x2f,0xe1,\n0x00,0xf0,0x42,0xfd,0x10,0x4b,0x00,0x2b,0x01,0xd0,0xfe,0x46,0x9f,0x46,0x0f,0x4b,\n0x00,0x2b,0x01,0xd0,0xfe,0x46,0x9f,0x46,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,\n0x0d,0x48,0x00,0xf0,0x89,0xfc,0x00,0xf0,0xc3,0xfc,0x20,0x00,0x29,0x00,0x00,0xf0,\n0xd1,0xf8,0x00,0xf0,0x8b,0xfc,0x7b,0x46,0x18,0x47,0x00,0x00,0x11,0x00,0x00,0xef,\n0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x54,0x13,0x00,0x20,0xfc,0x13,0x00,0x20,0x15,0x0b,0x00,0x20,0x70,0xb5,0x04,0x46,\n0x0e,0x46,0x15,0x46,0x00,0x21,0x28,0x22,0x00,0xf0,0x0e,0xfd,0x26,0x61,0x65,0x62,\n0x00,0x21,0x84,0x22,0x02,0x48,0x00,0xf0,0x07,0xfd,0x00,0x20,0x70,0xbd,0x00,0xbf,\n0x70,0x13,0x00,0x20,0x10,0xb5,0x01,0x20,0x00,0xf0,0xac,0xf9,0x04,0x46,0x28,0xb9,\n0x01,0x21,0x84,0x22,0x03,0x48,0x00,0xf0,0xf7,0xfc,0x01,0xe0,0x40,0xf2,0x01,0x14,\n0x20,0x46,0x10,0xbd,0x70,0x13,0x00,0x20,0x01,0x39,0xf8,0xb5,0x44,0x0b,0x08,0x44,\n0x45,0x0b,0x66,0x03,0xac,0x42,0x14,0xd8,0x0b,0x4f,0xe3,0x5d,0x6b,0xb9,0x30,0x46,\n0x00,0xf0,0xfc,0xf8,0x38,0xb1,0x00,0x04,0x00,0xf4,0x7f,0x00,0x40,0xea,0x04,0x60,\n0x40,0xf4,0x81,0x70,0xf8,0xbd,0x01,0x23,0xe3,0x55,0x01,0x34,0x06,0xf5,0x00,0x56,\n0xe8,0xe7,0x00,0x20,0xf8,0xbd,0x00,0xbf,0x70,0x13,0x00,0x20,0x2d,0xe9,0xf0,0x4f,\n0x53,0x1e,0x85,0xb0,0x0b,0x44,0x02,0x90,0x0d,0x46,0x4f,0xea,0x51,0x38,0x5b,0x0b,\n0x16,0x46,0x23,0x48,0x01,0x93,0x00,0x21,0x84,0x22,0x00,0xf0,0xbd,0xfc,0x4f,0xea,\n0x48,0x37,0xc5,0xf3,0x0c,0x0c,0x4f,0xf0,0x00,0x09,0x01,0x9b,0x98,0x45,0x32,0xd8,\n0x74,0x19,0xdf,0xf8,0x70,0xb0,0xcd,0xf8,0x0c,0xc0,0x07,0xf5,0x00,0x5a,0x54,0x45,\n0x88,0xbf,0xc4,0xf3,0x0c,0x04,0x39,0x46,0x4f,0xf4,0x00,0x52,0x58,0x46,0x8c,0xbf,\n0x34,0x1b,0x34,0x46,0x00,0xf0,0x60,0xfc,0xdd,0xf8,0x0c,0xc0,0x02,0x9b,0x0b,0xeb,\n0x0c,0x00,0x03,0xeb,0x09,0x01,0x22,0x46,0x00,0xf0,0x56,0xfc,0x38,0x46,0x4f,0xf4,\n0x00,0x51,0x08,0xf1,0x01,0x08,0xff,0xf7,0x9f,0xff,0x68,0xb9,0x39,0x46,0x58,0x46,\n0x4f,0xf4,0x00,0x52,0x25,0x44,0x00,0xf0,0xaf,0xf8,0x36,0x1b,0xc5,0xf3,0x0c,0x0c,\n0xa1,0x44,0x57,0x46,0xc9,0xe7,0x00,0x20,0x05,0xb0,0xbd,0xe8,0xf0,0x8f,0x00,0xbf,\n0x70,0x13,0x00,0x20,0x00,0x60,0x00,0x20,0xb2,0xf5,0x00,0x5f,0xf8,0xb5,0x07,0x46,\n0x0e,0x46,0x15,0x46,0x0b,0xd8,0x08,0x46,0x11,0x46,0xff,0xf7,0x7d,0xff,0x04,0x46,\n0x40,0xb9,0x38,0x46,0x31,0x46,0x2a,0x46,0x00,0xf0,0x8e,0xf8,0x02,0xe0,0x4f,0xf4,\n0x82,0x70,0xf8,0xbd,0x20,0x46,0xf8,0xbd,0x08,0xb5,0x00,0xf0,0x85,0xf8,0x00,0x20,\n0x08,0xbd,0x00,0x00,0xf8,0xb5,0x31,0x48,0x31,0x49,0x32,0x4a,0x32,0x4c,0xff,0xf7,\n0x3d,0xff,0x00,0x23,0x23,0x60,0x22,0x68,0x2c,0x4f,0x14,0x23,0x03,0xfb,0x02,0x73,\n0x08,0x33,0x5b,0x68,0x00,0x2b,0xf7,0xd0,0x2c,0x4b,0x1a,0x68,0x11,0x07,0xfb,0xd4,\n0x2b,0x4d,0x2c,0x4e,0x2a,0x68,0x32,0x60,0x42,0xf0,0x33,0x02,0x2a,0x60,0x1a,0x68,\n0x12,0x07,0xfc,0xd4,0x21,0x68,0x14,0x22,0x02,0xfb,0x01,0x73,0x98,0x68,0x01,0x38,\n0x13,0x46,0x04,0x28,0x26,0xd8,0xdf,0xe8,0x00,0xf0,0x03,0x06,0x0e,0x16,0x1e,0x00,\n0xff,0xf7,0x28,0xff,0x20,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0xc2,0xff,0x18,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0xa2,0xff,0x10,0xe0,0x4b,0x43,0xfa,0x18,0x10,0x69,0xf9,0x58,0x52,0x68,\n0xff,0xf7,0x44,0xff,0x08,0xe0,0x4b,0x43,0xfa,0x18,0xf8,0x58,0x51,0x68,0xff,0xf7,\n0x1b,0xff,0x01,0xe0,0x40,0xf2,0x05,0x10,0x33,0x68,0x2b,0x60,0x0b,0x4b,0x1b,0x68,\n0x1b,0x07,0xfb,0xd4,0x22,0x68,0x14,0x23,0x03,0xfb,0x02,0x77,0xfb,0x68,0xf8,0x60,\n0x00,0xb1,0xfe,0xe7,0x82,0xf0,0x01,0x02,0x22,0x60,0xa4,0xe7,0xd8,0x1f,0x00,0x20,\n0x00,0x20,0x00,0x20,0x00,0x40,0x00,0x20,0xf4,0x13,0x00,0x20,0x00,0x40,0x03,0x40,\n0x04,0x40,0x03,0x40,0xf8,0x13,0x00,0x20,0xfe,0xe7,0x00,0x00,0x08,0xb5,0x04,0x4b,\n0x1b,0x68,0x5b,0x69,0x98,0x47,0x03,0x4b,0x00,0x22,0x1a,0x60,0x08,0xbd,0x00,0xbf,\n0xa8,0x01,0x00,0x10,0x84,0x04,0x60,0x42,0x08,0xb5,0x04,0x4b,0x1b,0x68,0x9b,0x69,\n0x98,0x47,0x03,0x4b,0x00,0x22,0x1a,0x60,0x08,0xbd,0x00,0xbf,0xa8,0x01,0x00,0x10,\n0x84,0x04,0x60,0x42,0x10,0xb5,0x33,0x4b,0x33,0x48,0x1b,0x68,0x33,0x4a,0x13,0xf0,\n0x02,0x0f,0x03,0x68,0x43,0xf0,0x02,0x03,0x03,0x60,0x13,0x68,0x01,0x68,0x19,0xd0,\n0x21,0xf4,0xe1,0x72,0xc3,0xf3,0xc1,0x04,0x22,0xf0,0x01,0x02,0x22,0x43,0xc3,0xf3,\n0xc0,0x11,0x42,0xea,0x01,0x22,0xc3,0xf3,0x41,0x11,0x42,0xea,0x81,0x12,0x02,0x60,\n0x02,0x68,0xd4,0x07,0x03,0xd5,0x26,0x4a,0x12,0x68,0x50,0x07,0xfb,0xd5,0x03,0xf0,\n0x07,0x03,0x18,0xe0,0x21,0xf4,0xe1,0x72,0xc3,0xf3,0xc1,0x24,0x22,0xf0,0x01,0x02,\n0xc3,0xf3,0xc0,0x31,0x22,0x43,0x42,0xea,0x01,0x22,0xc3,0xf3,0x41,0x31,0x42,0xea,\n0x81,0x12,0x02,0x60,0x02,0x68,0xd1,0x07,0x03,0xd5,0x19,0x4a,0x12,0x68,0x52,0x07,\n0xfb,0xd5,0xc3,0xf3,0x02,0x23,0x17,0x49,0x17,0x48,0x4a,0xf6,0xaa,0x22,0x0a,0x60,\n0x02,0x68,0x1b,0x03,0xb3,0xf5,0xe0,0x4f,0x22,0xf4,0xe2,0x42,0x18,0xbf,0x43,0xf4,\n0x80,0x73,0x13,0x43,0x03,0x60,0x45,0xf2,0xaa,0x53,0x0b,0x60,0x0f,0x4b,0x10,0x49,\n0x01,0x22,0x1a,0x60,0x00,0x22,0x0a,0x60,0x1a,0x60,0x05,0x22,0xc3,0xf8,0x58,0x22,\n0x4f,0xf0,0xff,0x32,0xc1,0xf8,0x8c,0x22,0xc1,0xf8,0x90,0x22,0x02,0x22,0xc3,0xf8,\n0x58,0x22,0x10,0xbd,0x10,0x00,0x09,0x40,0x24,0x00,0x03,0x40,0x08,0x13,0x00,0x50,\n0x1c,0x00,0x03,0x40,0x64,0x20,0x03,0x40,0xa8,0x20,0x03,0x40,0x30,0x20,0x03,0x40,\n0x34,0x20,0x03,0x40,0x2d,0xe9,0xf8,0x4f,0xd4,0x4d,0x29,0x68,0x11,0xf0,0x01,0x01,\n0x40,0xf0,0x95,0x81,0xdf,0xf8,0x90,0xe3,0xd1,0x4b,0xdf,0xf8,0x90,0xc3,0xdf,0xf8,\n0x90,0x83,0xdf,0xf8,0x90,0x93,0x05,0x27,0xce,0xf8,0x00,0x70,0x1b,0x68,0xc3,0xf3,\n0x03,0x23,0x4f,0xf4,0x40,0x72,0x01,0x33,0xb2,0xfb,0xf3,0xf3,0xdc,0xf8,0x00,0x20,\n0xd8,0xf8,0x00,0x40,0x92,0xb2,0x5a,0x43,0xc2,0xf3,0x8f,0x16,0x22,0x0c,0x12,0x04,\n0x32,0x43,0xc8,0xf8,0x00,0x20,0xc3,0x4a,0xc3,0x4c,0x12,0x68,0x26,0x68,0xc3,0x4e,\n0x5a,0x43,0x92,0x09,0x22,0x60,0x32,0x68,0x54,0xf8,0x24,0x8c,0xc2,0xf3,0x07,0x42,\n0x5a,0x43,0x28,0xf0,0xff,0x08,0xc2,0xf3,0x87,0x12,0x42,0xea,0x08,0x02,0xdf,0xf8,\n0x38,0x83,0x44,0xf8,0x24,0x2c,0xd9,0xf8,0x00,0xa0,0xd8,0xf8,0x00,0x20,0xca,0xf3,\n0x07,0x4a,0x22,0xf0,0xff,0x02,0x4a,0xea,0x02,0x02,0xc8,0xf8,0x00,0x20,0xd9,0xf8,\n0x00,0x20,0xdf,0xf8,0x18,0xa3,0x12,0x0e,0xda,0xf8,0x00,0x80,0x5a,0x43,0x92,0x00,\n0x28,0xf4,0x7f,0x48,0x02,0xf4,0x7f,0x42,0x42,0xea,0x08,0x02,0xdf,0xf8,0x00,0x83,\n0xca,0xf8,0x00,0x20,0xd8,0xf8,0x00,0x20,0x4f,0xea,0x12,0x6b,0xda,0xf8,0x04,0x20,\n0x0b,0xfb,0x03,0xfb,0x12,0x0c,0xcb,0xf3,0x8f,0x1b,0x12,0x04,0x4b,0xea,0x02,0x02,\n0xca,0xf8,0x04,0x20,0xd9,0xf8,0x00,0x20,0xc2,0xf3,0x07,0x22,0x53,0x43,0xa0,0x4a,\n0xd2,0xf8,0x00,0x90,0x9b,0x00,0x29,0xf4,0x7f,0x49,0x03,0xf4,0x7f,0x43,0x43,0xea,\n0x09,0x03,0xdf,0xf8,0xc0,0x92,0x13,0x60,0xd9,0xf8,0x00,0xa0,0x52,0xf8,0x24,0x3c,\n0x4f,0xea,0x1a,0x6a,0x23,0xf4,0x7f,0x43,0x43,0xea,0x0a,0x23,0x42,0xf8,0x24,0x3c,\n0xd9,0xf8,0x00,0xa0,0x52,0xf8,0x24,0x3c,0xca,0xf3,0x07,0x4a,0x23,0xf0,0xff,0x03,\n0x4a,0xea,0x03,0x03,0x42,0xf8,0x24,0x3c,0xd9,0xf8,0x00,0xa0,0x52,0xf8,0x1c,0x3c,\n0x0a,0xf4,0x7f,0x4a,0x23,0xf4,0x7f,0x43,0x4a,0xea,0x03,0x03,0x42,0xf8,0x1c,0x3c,\n0xd9,0xf8,0x00,0x90,0x52,0xf8,0x1c,0x3c,0x5f,0xfa,0x89,0xf9,0x23,0xf0,0xff,0x03,\n0x49,0xea,0x03,0x03,0xdf,0xf8,0x60,0x92,0x42,0xf8,0x1c,0x3c,0x32,0x68,0xd9,0xf8,\n0x00,0x30,0x02,0xf4,0x70,0x42,0x23,0xf4,0x70,0x43,0x13,0x43,0xc9,0xf8,0x00,0x30,\n0xd8,0xf8,0x00,0x20,0xdf,0xf8,0x44,0x82,0xd8,0xf8,0x00,0x30,0x02,0xf4,0x70,0x42,\n0x23,0xf4,0x70,0x43,0x13,0x43,0xc8,0xf8,0x00,0x30,0x32,0x68,0x54,0xf8,0x24,0x3c,\n0x12,0x0e,0x23,0xf4,0x7f,0x43,0x43,0xea,0x02,0x23,0x44,0xf8,0x24,0x3c,0x71,0x4b,\n0x1b,0x68,0x62,0x6a,0xc3,0xf3,0x0b,0x06,0x22,0xf4,0x7f,0x63,0x23,0xf0,0x0f,0x03,\n0x33,0x43,0x6d,0x4e,0x63,0x62,0x32,0x68,0x63,0x6a,0x02,0xf4,0x70,0x22,0x23,0xf4,\n0x70,0x23,0x13,0x43,0x63,0x62,0x69,0x4c,0x22,0x68,0xd8,0xf8,0x58,0x30,0xc2,0xf3,\n0x83,0x42,0x23,0xf4,0x70,0x23,0x43,0xea,0x02,0x43,0xc8,0xf8,0x58,0x30,0xdc,0xf8,\n0x00,0x30,0xd8,0xf8,0x58,0x20,0xc3,0xf3,0x0b,0x4c,0x22,0xf4,0x7f,0x63,0x23,0xf0,\n0x0f,0x03,0x4c,0xea,0x03,0x03,0xc8,0xf8,0x58,0x30,0x23,0x68,0xd8,0xf8,0x5c,0x20,\n0x4f,0xea,0xd3,0x5c,0x22,0xf0,0xff,0x73,0x23,0xf4,0x80,0x33,0x43,0xea,0x0c,0x43,\n0xc8,0xf8,0x5c,0x30,0x33,0x68,0x56,0x4a,0xdf,0xf8,0xa4,0xc1,0x0f,0x33,0x03,0xf0,\n0x0f,0x03,0x13,0x60,0x26,0x68,0x53,0x68,0xc6,0xf3,0x80,0x56,0x23,0xf4,0x00,0x03,\n0x43,0xea,0xc6,0x53,0x53,0x60,0x53,0x68,0x4e,0x4e,0x43,0xf4,0x80,0x43,0x53,0x60,\n0x02,0x23,0xce,0xf8,0x00,0x30,0xae,0xf5,0x09,0x7e,0x4a,0xf6,0xaa,0x23,0xce,0xf8,\n0x00,0x30,0xdc,0xf8,0x00,0x30,0x32,0x68,0x03,0xf0,0x0f,0x08,0x22,0xf4,0x7f,0x02,\n0x42,0xea,0x08,0x42,0xc3,0xf3,0x03,0x23,0x42,0xea,0x03,0x53,0xdf,0xf8,0x54,0x81,\n0x33,0x60,0xd8,0xf8,0x00,0x30,0x32,0x68,0xc3,0xf3,0x03,0x49,0x22,0xf0,0xff,0x02,\n0x49,0xea,0x02,0x02,0xc3,0xf3,0x03,0x63,0x42,0xea,0x03,0x13,0x33,0x60,0xdc,0xf8,\n0x00,0x60,0xdf,0xf8,0x34,0xc1,0xdc,0xf8,0x00,0x30,0x06,0xf4,0x70,0x22,0x23,0xf4,\n0x7f,0x03,0x1a,0x43,0xc6,0xf3,0x03,0x63,0x42,0xea,0x03,0x53,0x32,0x4e,0xcc,0xf8,\n0x00,0x30,0x32,0x68,0x5c,0xf8,0x08,0x3c,0xc2,0xf3,0x03,0x22,0x23,0xf0,0x0f,0x03,\n0x13,0x43,0x4c,0xf8,0x08,0x3c,0xd8,0xf8,0x00,0x20,0xdc,0xf8,0x08,0x30,0x02,0xf4,\n0xf8,0x52,0x23,0xf4,0xf8,0x53,0x13,0x43,0xcc,0xf8,0x08,0x30,0x32,0x68,0xdc,0xf8,\n0x0c,0x30,0x12,0x0b,0x02,0xf4,0x70,0x42,0x23,0xf4,0x70,0x43,0x13,0x43,0xcc,0xf8,\n0x0c,0x30,0x32,0x68,0x21,0x4e,0x33,0x68,0xc2,0xf3,0x04,0x42,0x23,0xf0,0x1f,0x03,\n0x13,0x43,0x33,0x60,0x22,0x68,0x1e,0x4c,0x23,0x68,0xc2,0xf3,0x01,0x42,0x23,0xf4,\n0x40,0x13,0x43,0xea,0x02,0x53,0x1b,0x4a,0x23,0x60,0x45,0xf2,0xaa,0x53,0xce,0xf8,\n0x00,0x30,0x17,0x60,0x2b,0x68,0x43,0xf0,0x01,0x03,0x2b,0x60,0x11,0x60,0x16,0x4b,\n0x16,0x4c,0x1b,0x68,0x16,0x4a,0x17,0x4d,0x13,0xf0,0x02,0x0f,0x23,0x68,0x43,0xf0,\n0x02,0x03,0x23,0x60,0x13,0x68,0x21,0x68,0x59,0xd0,0x3f,0xe0,0x40,0x00,0x03,0x40,\n0x00,0x20,0x03,0x40,0x8c,0x11,0x00,0x50,0x44,0x22,0x03,0x40,0x74,0x11,0x00,0x50,\n0x34,0x22,0x03,0x40,0x84,0x11,0x00,0x50,0x80,0x11,0x00,0x50,0xb0,0x12,0x00,0x50,\n0x78,0x22,0x03,0x40,0x84,0x20,0x03,0x40,0x98,0x11,0x00,0x50,0x98,0x20,0x03,0x40,\n0xa8,0x20,0x03,0x40,0x3c,0x00,0x03,0x40,0x10,0x00,0x09,0x40,0x24,0x00,0x03,0x40,\n0x08,0x13,0x00,0x50,0x1c,0x00,0x03,0x40,0x88,0x22,0x03,0x40,0x88,0x11,0x00,0x50,\n0x40,0x22,0x03,0x40,0x78,0x11,0x00,0x50,0x24,0x22,0x03,0x40,0x28,0x22,0x03,0x40,\n0x7c,0x11,0x00,0x50,0x70,0x11,0x00,0x50,0x1c,0x22,0x03,0x40,0x14,0x22,0x03,0x40,\n0x90,0x11,0x00,0x50,0x94,0x11,0x00,0x50,0x88,0x20,0x03,0x40,0x21,0xf4,0xe1,0x72,\n0xc3,0xf3,0xc1,0x46,0x22,0xf0,0x01,0x02,0xc3,0xf3,0xc0,0x51,0x32,0x43,0x42,0xea,\n0x01,0x22,0xc3,0xf3,0x41,0x51,0x42,0xea,0x81,0x12,0x22,0x60,0x22,0x68,0xd7,0x07,\n0x02,0xd5,0x2a,0x68,0x56,0x07,0xfc,0xd5,0xc3,0xf3,0x02,0x43,0x16,0xe0,0xc3,0xf3,\n0xc1,0x62,0xde,0x0f,0x42,0xea,0x06,0x26,0x21,0xf4,0xe1,0x72,0x22,0xf0,0x01,0x02,\n0x32,0x43,0xc3,0xf3,0x41,0x71,0x42,0xea,0x81,0x12,0x22,0x60,0x22,0x68,0xd4,0x07,\n0x02,0xd5,0x2a,0x68,0x51,0x07,0xfc,0xd5,0xc3,0xf3,0x02,0x63,0x3b,0x49,0x3c,0x4c,\n0x4a,0xf6,0xaa,0x22,0x0a,0x60,0x22,0x68,0x1b,0x03,0xb3,0xf5,0xe0,0x4f,0x22,0xf4,\n0xe2,0x42,0x18,0xbf,0x43,0xf4,0x80,0x73,0x13,0x43,0x23,0x60,0x45,0xf2,0xaa,0x53,\n0x0b,0x60,0x34,0x4b,0x00,0x21,0x01,0x22,0x19,0x60,0x43,0xf8,0x20,0x2c,0x32,0x4a,\n0x4f,0xf6,0xff,0x74,0x14,0x60,0x31,0x4c,0x43,0xf8,0x20,0x1c,0x02,0xf5,0xec,0x72,\n0x4f,0xf0,0x05,0x0e,0x10,0x23,0xc4,0xf8,0x00,0xe0,0x13,0x60,0x2c,0x4b,0x15,0x26,\n0x1e,0x60,0x02,0x26,0x26,0x60,0x2b,0x4e,0x37,0x68,0xc4,0xf8,0x00,0xe0,0xdf,0xf8,\n0xb4,0xe0,0xce,0xf8,0x00,0x10,0xce,0xf8,0x04,0x10,0x18,0xb1,0x31,0x68,0x41,0xf4,\n0x00,0x01,0x31,0x60,0x02,0x21,0x05,0x20,0x21,0x60,0x20,0x60,0x08,0x20,0x10,0x60,\n0x15,0x22,0x1a,0x60,0x21,0x60,0x2b,0x68,0x9a,0x07,0xfc,0xd4,0x1e,0x4b,0x1b,0x68,\n0x13,0xf0,0x10,0x0f,0x14,0xbf,0x04,0x25,0x00,0x25,0xff,0xf7,0x1b,0xfd,0x3b,0x02,\n0x07,0xd4,0x05,0x23,0x23,0x60,0x33,0x68,0x23,0xf4,0x00,0x03,0x33,0x60,0x02,0x23,\n0x23,0x60,0xc5,0xb9,0x15,0x4b,0x16,0x48,0x19,0x68,0x03,0xf5,0x10,0x53,0x04,0x33,\n0x1a,0x68,0x1b,0x68,0x02,0xf0,0x0f,0x02,0xc9,0xb2,0x03,0xf0,0x0f,0x03,0x51,0x43,\n0x9b,0x02,0xc3,0xeb,0x81,0x21,0x01,0xf5,0xfe,0x51,0x18,0x31,0x14,0x22,0xbd,0xe8,\n0xf8,0x4f,0xff,0xf7,0xe9,0xbc,0x28,0x46,0xbd,0xe8,0xf8,0x8f,0x64,0x20,0x03,0x40,\n0xa8,0x20,0x03,0x40,0x50,0x20,0x03,0x40,0x34,0x20,0x03,0x40,0x88,0x22,0x03,0x40,\n0xb4,0x22,0x03,0x40,0x7c,0x22,0x03,0x40,0x54,0x20,0x03,0x40,0x2c,0x00,0x03,0x40,\n0xf4,0x0e,0x00,0x20,0xc0,0x22,0x03,0x40,0x08,0xb5,0x01,0x1c,0x00,0x22,0x00,0x20,\n0x00,0x23,0x00,0xf0,0xeb,0xf8,0x08,0xbc,0x02,0xbc,0x08,0x47,0x10,0xb5,0x00,0x21,\n0x04,0x1c,0x00,0xf0,0x5d,0xf9,0x05,0x4b,0x18,0x68,0xc3,0x6b,0x00,0x2b,0x01,0xd0,\n0x00,0xf0,0x06,0xf8,0x20,0x1c,0xff,0xf7,0xa7,0xfc,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x18,0x47,0xc0,0x46,0x38,0xb5,0x0a,0x4b,0x0a,0x4c,0xe4,0x1a,0xa4,0x10,0x0a,0xd0,\n0x09,0x4a,0xa5,0x18,0xad,0x00,0xed,0x18,0x2b,0x68,0x01,0x3c,0x00,0xf0,0x0e,0xf8,\n0x04,0x3d,0x00,0x2c,0xf8,0xd1,0x00,0xf0,0xcd,0xf9,0x38,0xbc,0x01,0xbc,0x00,0x47,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x3f,0x18,0x47,0xc0,0x46,\n0x70,0xb5,0x10,0x4e,0x10,0x4d,0xad,0x1b,0xad,0x10,0x00,0x24,0x00,0x2d,0x06,0xd0,\n0xa3,0x00,0xf3,0x58,0x01,0x34,0x00,0xf0,0x1d,0xf8,0xa5,0x42,0xf8,0xd1,0x00,0xf0,\n0xab,0xf9,0x0a,0x4e,0x0a,0x4d,0xad,0x1b,0xad,0x10,0x00,0x24,0x00,0x2d,0x06,0xd0,\n0xa3,0x00,0xf3,0x58,0x01,0x34,0x00,0xf0,0x0d,0xf8,0xa5,0x42,0xf8,0xd1,0x70,0xbc,\n0x01,0xbc,0x00,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x18,0x47,0xc0,0x46,0x70,0xb5,0x0f,0x2a,0x34,0xd9,0x04,0x1c,\n0x0c,0x43,0x0b,0x1c,0xa4,0x07,0x33,0xd1,0x15,0x1c,0x04,0x1c,0x10,0x3d,0x2d,0x09,\n0x01,0x35,0x2d,0x01,0x49,0x19,0x1e,0x68,0x26,0x60,0x5e,0x68,0x66,0x60,0x9e,0x68,\n0xa6,0x60,0xde,0x68,0x10,0x33,0xe6,0x60,0x10,0x34,0x99,0x42,0xf3,0xd1,0x0f,0x23,\n0x45,0x19,0x13,0x40,0x03,0x2b,0x1d,0xd9,0x1c,0x1f,0x00,0x23,0xa4,0x08,0x01,0x34,\n0xa4,0x00,0xce,0x58,0xee,0x50,0x04,0x33,0xa3,0x42,0xfa,0xd1,0xed,0x18,0xc9,0x18,\n0x03,0x23,0x1a,0x40,0x05,0xd0,0x00,0x23,0xcc,0x5c,0xec,0x54,0x01,0x33,0x93,0x42,\n0xfa,0xd1,0x70,0xbc,0x02,0xbc,0x08,0x47,0x05,0x1c,0x00,0x2a,0xf3,0xd1,0xf8,0xe7,\n0x05,0x1c,0xf0,0xe7,0x1a,0x1c,0xf8,0xe7,0x70,0xb5,0x83,0x07,0x43,0xd0,0x54,0x1e,\n0x00,0x2a,0x3d,0xd0,0x0d,0x06,0x2d,0x0e,0x03,0x1c,0x03,0x26,0x03,0xe0,0x62,0x1e,\n0x00,0x2c,0x35,0xd0,0x14,0x1c,0x01,0x33,0x5a,0x1e,0x15,0x70,0x33,0x42,0xf6,0xd1,\n0x03,0x2c,0x24,0xd9,0xff,0x25,0x0d,0x40,0x2a,0x02,0x15,0x43,0x2a,0x04,0x15,0x43,\n0x0f,0x2c,0x11,0xd9,0x26,0x1c,0x10,0x3e,0x36,0x09,0x01,0x36,0x36,0x01,0x1a,0x1c,\n0x9b,0x19,0x15,0x60,0x55,0x60,0x95,0x60,0xd5,0x60,0x10,0x32,0x93,0x42,0xf8,0xd1,\n0x0f,0x22,0x14,0x40,0x03,0x2c,0x0a,0xd9,0x26,0x1f,0xb6,0x08,0x01,0x36,0xb6,0x00,\n0x1a,0x1c,0x9b,0x19,0x20,0xc2,0x93,0x42,0xfc,0xd1,0x03,0x22,0x14,0x40,0x00,0x2c,\n0x06,0xd0,0x09,0x06,0x1c,0x19,0x09,0x0e,0x19,0x70,0x01,0x33,0xa3,0x42,0xfb,0xd1,\n0x70,0xbc,0x02,0xbc,0x08,0x47,0x14,0x1c,0x03,0x1c,0xc9,0xe7,0xf8,0xb5,0x44,0x46,\n0x5f,0x46,0x56,0x46,0x4d,0x46,0x9b,0x46,0x30,0x4b,0xf0,0xb4,0x1c,0x68,0xa4,0x23,\n0x5b,0x00,0x05,0x1c,0xe0,0x58,0x0e,0x1c,0x90,0x46,0x00,0x28,0x4d,0xd0,0x43,0x68,\n0x1f,0x2b,0x0f,0xdc,0x5c,0x1c,0x00,0x2d,0x23,0xd1,0x02,0x33,0x9b,0x00,0x44,0x60,\n0x1e,0x50,0x00,0x20,0x3c,0xbc,0x90,0x46,0x99,0x46,0xa2,0x46,0xab,0x46,0xf8,0xbc,\n0x02,0xbc,0x08,0x47,0x22,0x4b,0x00,0x2b,0x3c,0xd0,0xc8,0x20,0x40,0x00,0xaf,0xf3,\n0x00,0x80,0x00,0x28,0x36,0xd0,0xa4,0x22,0x00,0x23,0x52,0x00,0xa1,0x58,0x43,0x60,\n0x01,0x60,0xa0,0x50,0x40,0x32,0x83,0x50,0x04,0x32,0x83,0x50,0x01,0x24,0x00,0x2d,\n0xdb,0xd0,0x9a,0x00,0x91,0x46,0x81,0x44,0x42,0x46,0x88,0x21,0x4f,0x46,0x7a,0x50,\n0xc4,0x22,0x52,0x00,0x90,0x46,0x80,0x44,0x42,0x46,0x87,0x39,0x99,0x40,0x12,0x68,\n0x0a,0x43,0x94,0x46,0x8a,0x46,0x42,0x46,0x61,0x46,0x11,0x60,0x84,0x22,0x49,0x46,\n0x5f,0x46,0x52,0x00,0x8f,0x50,0x02,0x2d,0xbf,0xd1,0x02,0x1c,0x55,0x46,0x8d,0x32,\n0xff,0x32,0x11,0x68,0x0d,0x43,0x15,0x60,0xb7,0xe7,0x20,0x1c,0x4d,0x30,0xff,0x30,\n0xe0,0x50,0xac,0xe7,0x01,0x20,0x40,0x42,0xb4,0xe7,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x08,0xb5,0x04,0x4b,0x00,0x2b,0x02,0xd0,0x03,0x48,0xff,0xf7,\n0x9b,0xfe,0x08,0xbc,0x01,0xbc,0x00,0x47,0x00,0x00,0x00,0x00,0x15,0x0b,0x00,0x20,\n0xf0,0xb5,0x56,0x46,0x5f,0x46,0x4d,0x46,0x44,0x46,0xf0,0xb4,0x0e,0x1c,0x3f,0x4b,\n0x1b,0x68,0x87,0xb0,0x03,0x93,0x49,0x33,0xff,0x33,0x01,0x90,0x04,0x93,0xa4,0x22,\n0x03,0x9b,0x52,0x00,0x9f,0x58,0x00,0x2f,0x4d,0xd0,0x04,0x9b,0x98,0x46,0x00,0x23,\n0x9b,0x46,0xc4,0x23,0x5b,0x00,0x9c,0x46,0xbc,0x44,0x63,0x46,0x02,0x93,0xc6,0x23,\n0x5b,0x00,0x9a,0x46,0x7c,0x68,0xa5,0x00,0x7d,0x19,0xba,0x44,0x01,0x3c,0x08,0xd5,\n0x27,0xe0,0x6b,0x1d,0xff,0x33,0x1b,0x68,0xb3,0x42,0x04,0xd0,0x04,0x3d,0x01,0x3c,\n0x1f,0xd3,0x00,0x2e,0xf5,0xd1,0x7b,0x68,0x01,0x3b,0x6a,0x68,0xa3,0x42,0x3e,0xd0,\n0x5b,0x46,0x6b,0x60,0x00,0x2a,0xf1,0xd0,0x7b,0x68,0x99,0x46,0x01,0x23,0xa3,0x40,\n0x02,0x99,0x09,0x68,0x05,0x91,0x19,0x42,0x26,0xd1,0x00,0xf0,0x43,0xf8,0x7b,0x68,\n0x4b,0x45,0xc4,0xd1,0x43,0x46,0x1b,0x68,0xbb,0x42,0xc0,0xd1,0x04,0x3d,0x01,0x3c,\n0xdf,0xd2,0x1b,0x4b,0x00,0x2b,0x0e,0xd0,0x7b,0x68,0x00,0x2b,0x27,0xd1,0x3b,0x68,\n0x00,0x2b,0x28,0xd0,0x42,0x46,0x38,0x1c,0x13,0x60,0xaf,0xf3,0x00,0x80,0x43,0x46,\n0x1f,0x68,0x00,0x2f,0xb5,0xd1,0x07,0xb0,0x3c,0xbc,0x90,0x46,0x99,0x46,0xa2,0x46,\n0xab,0x46,0xf0,0xbc,0x01,0xbc,0x00,0x47,0x51,0x46,0x09,0x68,0x19,0x42,0x08,0xd1,\n0x2b,0x1c,0x84,0x33,0x19,0x68,0x01,0x98,0x00,0xf0,0x14,0xf8,0xcf,0xe7,0x7c,0x60,\n0xc0,0xe7,0x2b,0x1c,0x84,0x33,0x18,0x68,0x00,0xf0,0x0c,0xf8,0xc7,0xe7,0x3b,0x68,\n0xb8,0x46,0x1f,0x1c,0xdd,0xe7,0x00,0x23,0xfa,0xe7,0xc0,0x46,0x0c,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x10,0x47,0xc0,0x46,0xf8,0xb5,0xc0,0x46,0xf8,0xbc,0x08,0xbc,\n0x9e,0x46,0x70,0x47,0xf8,0xb5,0xc0,0x46,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,\n0x00,0x00,0x00,0x00,0x24,0xf2,0xff,0x7f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x8c,0x15,0x00,0x20,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,0xff,0xc5,0xff,0xff,0xff,\n0xc5,0xc5,0xc5,0xff,0xc5,0xc5,0xc5,0xff,0x43,0x00,0x00,0x00,0x18,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x12,0x00,0x20,\n0x6c,0x12,0x00,0x20,0xd4,0x12,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0f,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,\n0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x18,0x0f,0x00,0x20,0xc1,0x00,0x00,0x20,0x91,0x00,0x00,0x20,0x00,0x00,0x00,0x00,\n0x95,0x0d,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/flash.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"flash.h\"\n\n/******************************************************************************\n*\n* Defines for accesses to the security control in the customer configuration\n* area in flash top sector.\n*\n******************************************************************************/\n#define CCFG_OFFSET_SECURITY CCFG_O_BL_CONFIG\n#define CCFG_SIZE_SECURITY   0x00000014\n\n/******************************************************************************\n*\n* Default values for security control in customer configuration area in flash\n* top sector.\n*\n******************************************************************************/\nconst uint8_t g_ccfg_default_sec[] = {\n\t0xFF, 0xFF, 0xFF, 0xC5,\n\t0xFF, 0xFF, 0xFF, 0xFF,\n\t0xC5, 0xFF, 0xFF, 0xFF,\n\t0xC5, 0xC5, 0xC5, 0xFF,\n\t0xC5, 0xC5, 0xC5, 0xFF\n};\n\ntypedef uint32_t (*flash_prg_pntr_t) (uint8_t *, uint32_t, uint32_t);\ntypedef uint32_t (*flash_sector_erase_pntr_t) (uint32_t);\n\n/******************************************************************************\n*\n* Function prototypes for static functions\n*\n******************************************************************************/\nstatic void issue_fsm_command(flash_state_command_t command);\nstatic void enable_sectors_for_write(void);\nstatic uint32_t scale_cycle_values(uint32_t specified_timing,\n\tuint32_t scale_value);\nstatic void set_write_mode(void);\nstatic void trim_for_write(void);\nstatic void set_read_mode(void);\n\n/******************************************************************************\n*\n* Erase a flash sector\n*\n******************************************************************************/\nuint32_t flash_sector_erase(uint32_t sector_address)\n{\n\tuint32_t error_return;\n\tflash_sector_erase_pntr_t func_pntr;\n\n\t/* Call ROM function */\n\tfunc_pntr = (uint32_t (*)(uint32_t))(ROM_API_FLASH_TABLE[5]);\n\terror_return = func_pntr(sector_address);\n\n\t/* Enable standby because ROM function might have disabled it */\n\tHWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;\n\n\t/* Return status of operation. */\n\treturn error_return;\n}\n\n/******************************************************************************\n*\n* Erase all unprotected sectors in the flash main bank\n*\n******************************************************************************/\nuint32_t flash_bank_erase(bool force_precondition)\n{\n\tuint32_t error_return;\n\tuint32_t sector_address;\n\tuint32_t reg_val;\n\n\t/* Enable all sectors for erase. */\n\tenable_sectors_for_write();\n\n\t/* Clear the Status register. */\n\tissue_fsm_command(FAPI_CLEAR_STATUS);\n\n\t/* Enable erase of all sectors and enable precondition if required. */\n\treg_val = HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE);\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0x00000000;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0x00000000;\n\tif (force_precondition)\n\t\tHWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=\n\t\t\tFLASH_FSM_ST_MACHINE_DO_PRECOND;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;\n\n\t/* Issue the bank erase command to the FSM. */\n\tissue_fsm_command(FAPI_ERASE_BANK);\n\n\t/* Wait for erase to finish. */\n\twhile (flash_check_fsm_for_ready() == FAPI_STATUS_FSM_BUSY)\n\t\t;\n\n\t/* Update status. */\n\terror_return = flash_check_fsm_for_error();\n\n\t/* Disable sectors for erase. */\n\tflash_disable_sectors_for_write();\n\n\t/* Set configured precondition mode since it may have been forced on. */\n\tif (!(reg_val & FLASH_FSM_ST_MACHINE_DO_PRECOND)) {\n\t\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &=\n\t\t\t~FLASH_FSM_ST_MACHINE_DO_PRECOND;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;\n\t}\n\n\t/* Program security data to default values in the customer configuration */\n\t/* area within the flash top sector if erase was successful. */\n\tif (error_return == FAPI_STATUS_SUCCESS) {\n\t\tsector_address = FLASHMEM_BASE + flash_size_get() -\n\t\t\t\t\t\t\tflash_sector_size_get();\n\t\terror_return = flash_program((uint8_t *)g_ccfg_default_sec,\n\t\t\t\t\t\t\t(sector_address + CCFG_OFFSET_SECURITY),\n\t\t\t\t\t\t\tCCFG_SIZE_SECURITY);\n\t}\n\n\t/* Return status of operation. */\n\treturn error_return;\n}\n\n/******************************************************************************\n*\n* Programs unprotected main bank flash sectors\n*\n******************************************************************************/\nuint32_t flash_program(uint8_t *data_buffer, uint32_t address, uint32_t count)\n{\n\tuint32_t error_return;\n\tflash_prg_pntr_t func_pntr;\n\n\t/* Call ROM function */\n\tfunc_pntr = (uint32_t (*)(uint8_t *, uint32_t, uint32_t))\n\t\t\t\t\t(ROM_API_FLASH_TABLE[6]);\n\terror_return = func_pntr(data_buffer, address, count);\n\n\t/* Enable standby because ROM function might have disabled it */\n\tHWREGBITW(FLASH_BASE + FLASH_O_CFG, FLASH_CFG_DIS_STANDBY_BITN) = 0;\n\n\t/* Return status of operation. */\n\treturn error_return;\n}\n\n/******************************************************************************\n*\n* Disables all sectors for erase and programming on the active bank\n*\n******************************************************************************/\nvoid flash_disable_sectors_for_write(void)\n{\n\t/* Configure flash back to read mode */\n\tset_read_mode();\n\n\t/* Disable Level 1 Protection. */\n\tHWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;\n\n\t/* Disable all sectors for erase and programming. */\n\tHWREG(FLASH_BASE + FLASH_O_FBSE) = 0x0000;\n\n\t/* Enable Level 1 Protection. */\n\tHWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;\n\n\t/* Protect sectors from sector erase. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_SECTOR1) = 0xFFFFFFFF;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_SECTOR2) = 0xFFFFFFFF;\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;\n}\n\n/******************************************************************************\n*\n* Issues a command to the Flash State Machine.\n*\n******************************************************************************/\nstatic void issue_fsm_command(flash_state_command_t command)\n{\n\t/* Enable write to FSM register. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;\n\n\t/* Issue FSM command. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_CMD) = command;\n\n\t/* Start command execute. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_EXECUTE) = FLASH_CMD_EXEC;\n\n\t/* Disable write to FSM register. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;\n}\n\n/******************************************************************************\n*\n* Enables all sectors for erase and programming on the active bank.\n*\n* This function disables the idle reading power reduction mode, selects the\n* flash bank and enables all sectors for erase and programming on the active\n* bank.\n* Sectors may be protected from programming depending on the value of the\n* FLASH_O_FSM_BSLPx registers.\n* Sectors may be protected from erase depending on the value of the\n* FLASH_O_FSM_BSLEx registers. Additional sector erase protection is set by\n* the FLASH_O_FSM_SECTOR1 register.\n*\n******************************************************************************/\nstatic void enable_sectors_for_write(void)\n{\n\t/* Trim flash module for program/erase operation. */\n\ttrim_for_write();\n\n\t/* Configure flash to write mode */\n\tset_write_mode();\n\n\t/* Select flash bank. */\n\tHWREG(FLASH_BASE + FLASH_O_FMAC) = 0x00;\n\n\t/* Disable Level 1 Protection. */\n\tHWREG(FLASH_BASE + FLASH_O_FBPROT) = FLASH_FBPROT_PROTL1DIS;\n\n\t/* Enable all sectors for erase and programming. */\n\tHWREG(FLASH_BASE + FLASH_O_FBSE) = 0xFFFF;\n\n\t/* Enable Level 1 Protection */\n\tHWREG(FLASH_BASE + FLASH_O_FBPROT) = 0;\n}\n\n/******************************************************************************\n*\n* Trims the Flash Bank and Flash Pump for program/erase functionality\n*\n* This trimming will make it possible to perform erase and program operations\n* of the flash. Trim values are loaded from factory configuration area\n* (referred to as FCGF1). The trimming done by this function is valid until\n* reset of the flash module.\n*\n* Some registers shall be written with a value that is a number of FCLK\n* cycles. The trim values controlling these registers have a value of\n* number of half us. FCLK = SysClk / ((RWAIT+1) x 2).\n*\n******************************************************************************/\nstatic void trim_for_write(void)\n{\n\tuint32_t value;\n\tuint32_t temp_val;\n\tuint32_t fclk_scale;\n\tuint32_t rwait;\n\n\t/* Return if flash is already trimmed for program/erase operations. */\n\tif (HWREG(FLASH_BASE + FLASH_O_FWFLAG) & FW_WRT_TRIMMED)\n\t\treturn;\n\n\t/* Configure the FSM registers */\n\n\t/* Enable access to the FSM registers. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_ENABLE;\n\n\t/* Determine the scaling value to be used on timing related trim values. */\n\t/* The value is based on the flash module clock frequency and RWAIT */\n\trwait = (HWREG(FLASH_BASE + FLASH_O_FRDCTL) &\n\t\t\t\tFLASH_FRDCTL_RWAIT_M) >> FLASH_FRDCTL_RWAIT_S;\n\tfclk_scale = (16 * FLASH_MODULE_CLK_FREQ) / (rwait + 1);\n\n\t/* Configure Program pulse width bits 15:0. */\n\t/* (FCFG1 offset 0x188 bits 15:0). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &\n\t\t\t\tFCFG1_FLASH_PROG_EP_PROGRAM_PW_M) >>\n\t\t\t\tFCFG1_FLASH_PROG_EP_PROGRAM_PW_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PW) &\n\t\t~FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M) |\n\t\t((value << FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S) &\n\t\tFLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M);\n\n\t/* Configure Erase pulse width bits 31:0. */\n\t/* (FCFG1 offset 0x18C bits 31:0). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_ERA_PW) &\n\t\t\t\tFCFG1_FLASH_ERA_PW_ERASE_PW_M) >>\n\t\t\t\tFCFG1_FLASH_ERA_PW_ERASE_PW_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PW) &\n\t\t~FLASH_FSM_ERA_PW_FSM_ERA_PW_M) |\n\t\t((value << FLASH_FSM_ERA_PW_FSM_ERA_PW_S) &\n\t\tFLASH_FSM_ERA_PW_FSM_ERA_PW_M);\n\n\t/* Configure no of flash clock cycles from EXECUTEZ going low to the the\n\t   verify data can be read in the program verify mode bits 7:0. */\n\t/* (FCFG1 offset 0x174 bits 23:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &\n\t\t\t\tFCFG1_FLASH_C_E_P_R_PV_ACCESS_M) >>\n\t\t\t\tFCFG1_FLASH_C_E_P_R_PV_ACCESS_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &\n\t\t~FLASH_FSM_EX_VAL_EXE_VALD_M) |\n\t\t((value << FLASH_FSM_EX_VAL_EXE_VALD_S) &\n\t\tFLASH_FSM_EX_VAL_EXE_VALD_M);\n\n\t/* Configure the number of flash clocks from the start of the Read mode at\n\t   the end of the operations until the FSM clears the BUSY bit in FMSTAT. */\n\t/* (FCFG1 offset 0x178 bits 23:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &\n\t\t\t\tFCFG1_FLASH_P_R_PV_RH_M) >>\n\t\t\t\tFCFG1_FLASH_P_R_PV_RH_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_RD_H) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_RD_H) &\n\t\t~FLASH_FSM_RD_H_RD_H_M) |\n\t\t((value << FLASH_FSM_RD_H_RD_H_S) &\n\t\tFLASH_FSM_RD_H_RD_H_M);\n\n\t/* Configure Program hold time */\n\t/* (FCFG1 offset 0x178 bits 31:24). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &\n\t\t\t\tFCFG1_FLASH_P_R_PV_PH_M) >>\n\t\t\t\tFCFG1_FLASH_P_R_PV_PH_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_P_OH) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_P_OH) &\n\t\t~FLASH_FSM_P_OH_PGM_OH_M) |\n\t\t((value << FLASH_FSM_P_OH_PGM_OH_S) &\n\t\tFLASH_FSM_P_OH_PGM_OH_M);\n\n\t/* Configure Erase hold time */\n\t/* (FCFG1 offset 0x17C bits 31:24). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &\n\t\t\t\tFCFG1_FLASH_EH_SEQ_EH_M) >>\n\t\t\t\tFCFG1_FLASH_EH_SEQ_EH_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_OH) &\n\t\t~FLASH_FSM_ERA_OH_ERA_OH_M) |\n\t\t((value << FLASH_FSM_ERA_OH_ERA_OH_S) &\n\t\tFLASH_FSM_ERA_OH_ERA_OH_M);\n\n\t/* Configure Program verify row switch time */\n\t/* (FCFG1 offset0x178 bits 15:8). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_P_R_PV) &\n\t\t\t\tFCFG1_FLASH_P_R_PV_PVH_M) >>\n\t\t\t\tFCFG1_FLASH_P_R_PV_PVH_S;\n\n\tvalue = scale_cycle_values(value, fclk_scale);\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VH) &\n\t\t~FLASH_FSM_PE_VH_PGM_VH_M) |\n\t\t((value << FLASH_FSM_PE_VH_PGM_VH_S) &\n\t\tFLASH_FSM_PE_VH_PGM_VH_M);\n\n\t/* Configure Program Operation Setup time */\n\t/* (FCFG1 offset 0x170 bits 31:24). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &\n\t\t\t\tFCFG1_FLASH_E_P_PSU_M) >>\n\t\t\t\tFCFG1_FLASH_E_P_PSU_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &\n\t\t~FLASH_FSM_PE_OSU_PGM_OSU_M) |\n\t\t((value << FLASH_FSM_PE_OSU_PGM_OSU_S) &\n\t\tFLASH_FSM_PE_OSU_PGM_OSU_M);\n\n\t/* Configure Erase Operation Setup time */\n\t/* (FCGF1 offset 0x170 bits 23:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &\n\t\t\t\tFCFG1_FLASH_E_P_ESU_M) >>\n\t\t\t\tFCFG1_FLASH_E_P_ESU_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PE_OSU) &\n\t\t~FLASH_FSM_PE_OSU_ERA_OSU_M) |\n\t\t((value << FLASH_FSM_PE_OSU_ERA_OSU_S) &\n\t\tFLASH_FSM_PE_OSU_ERA_OSU_M);\n\n\t/* Confgure Program Verify Setup time */\n\t/* (FCFG1 offset 0x170 bits 15:8). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &\n\t\t\t\tFCFG1_FLASH_E_P_PVSU_M) >>\n\t\t\t\tFCFG1_FLASH_E_P_PVSU_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &\n\t\t~FLASH_FSM_PE_VSU_PGM_VSU_M) |\n\t\t((value << FLASH_FSM_PE_VSU_PGM_VSU_S) &\n\t\tFLASH_FSM_PE_VSU_PGM_VSU_M);\n\n\t/* Configure Erase Verify Setup time */\n\t/* (FCFG1 offset 0x170 bits 7:0). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_E_P) &\n\t\t\t\tFCFG1_FLASH_E_P_EVSU_M) >>\n\t\t\t\tFCFG1_FLASH_E_P_EVSU_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PE_VSU) &\n\t\t~FLASH_FSM_PE_VSU_ERA_VSU_M) |\n\t\t((value << FLASH_FSM_PE_VSU_ERA_VSU_S) &\n\t\tFLASH_FSM_PE_VSU_ERA_VSU_M);\n\n\t/* Configure Addr to EXECUTEZ low setup time */\n\t/* (FCFG1 offset 0x174 bits 15:12). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &\n\t\t\t\tFCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_M) >>\n\t\t\t\tFCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_CMP_VSU) &\n\t\t~FLASH_FSM_CMP_VSU_ADD_EXZ_M) |\n\t\t((value << FLASH_FSM_CMP_VSU_ADD_EXZ_S) &\n\t\tFLASH_FSM_CMP_VSU_ADD_EXZ_M);\n\n\t/* Configure Voltage Status Count */\n\t/* (FCFG1 offset 0x17C bits 15:12). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_EH_SEQ) &\n\t\t\t\tFCFG1_FLASH_EH_SEQ_VSTAT_M) >>\n\t\t\t\tFCFG1_FLASH_EH_SEQ_VSTAT_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_VSTAT) &\n\t\t~FLASH_FSM_VSTAT_VSTAT_CNT_M) |\n\t\t((value << FLASH_FSM_VSTAT_VSTAT_CNT_S) &\n\t\tFLASH_FSM_VSTAT_VSTAT_CNT_M);\n\n\t/* Configure Repeat Verify action setup */\n\t/* (FCFG1 offset 0x174 bits 31:24). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_C_E_P_R) &\n\t\t\t\tFCFG1_FLASH_C_E_P_R_RVSU_M) >>\n\t\t\t\tFCFG1_FLASH_C_E_P_R_RVSU_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_EX_VAL) &\n\t\t~FLASH_FSM_EX_VAL_REP_VSU_M) |\n\t\t((value << FLASH_FSM_EX_VAL_REP_VSU_S) &\n\t\tFLASH_FSM_EX_VAL_REP_VSU_M);\n\n\t/* Configure Maximum Programming Pulses */\n\t/* (FCFG1 offset 0x184 bits 15:0). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PP) &\n\t\t\t\tFCFG1_FLASH_PP_MAX_PP_M) >>\n\t\t\t\tFCFG1_FLASH_PP_MAX_PP_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &\n\t\t~FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M) |\n\t\t((value << FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S) &\n\t\tFLASH_FSM_PRG_PUL_MAX_PRG_PUL_M);\n\n\t/* Configure Beginning level for VHVCT used during erase modes */\n\t/* (FCFG1 offset 0x180 bits 31:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &\n\t\t\t\tFCFG1_FLASH_VHV_E_VHV_E_START_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_E_VHV_E_START_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_PRG_PUL) &\n\t\t~FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M) |\n\t\t((value << FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S) &\n\t\tFLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M);\n\n\t/* Configure Maximum EC Level */\n\t/* (FCFG1 offset 0x2B0 bits 21:18). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_M) >>\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &\n\t\t~FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M) |\n\t\t((value << FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S) &\n\t\tFLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M);\n\n\t/* Configure Maximum Erase Pulses */\n\t/* (FCFG1 offset 0x188 bits 31:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_PROG_EP) &\n\t\t\t\tFCFG1_FLASH_PROG_EP_MAX_EP_M) >>\n\t\t\t\tFCFG1_FLASH_PROG_EP_MAX_EP_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_ERA_PUL) &\n\t\t~FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M) |\n\t\t((value << FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S) &\n\t\tFLASH_FSM_ERA_PUL_MAX_ERA_PUL_M);\n\n\t/* Configure the VHVCT Step Size. This is the number of erase pulses that\n\t   must be completed for each level before the FSM increments the\n\t   CUR_EC_LEVEL to the next higher level. Actual erase pulses per level\n\t   equals (EC_STEP_SIZE +1). The stepping is only needed for the VHVCT\n\t   voltage. */\n\t/* (FCFG1 offset 0x2B0 bits 31:23). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_M) >>\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_STEP_SIZE) &\n\t\t~FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M) |\n\t\t((value << FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S) &\n\t\tFLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M);\n\n\t/* Configure the hight of each EC step. This is the number of counts that\n\t   the CUR_EC_LEVEL will increment when going to a new level. Actual count\n\t   size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the VHVCT\n\t   voltage.\n\t   The read trim value is decremented by 1 before written to the register\n\t   since actual counts equals (register value + 1). */\n\t/* (FCFG1 offset 0x180 bits 15:0). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_E) &\n\t\t\t\tFCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_EC_STEP_HEIGHT) = ((value - 1) &\n\t\tFLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M);\n\n\t/* Configure Precondition used in erase operations */\n\t/* (FCFG1 offset 0x2B0 bit 22). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_DO_PRECOND_M) >>\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_DO_PRECOND_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) &\n\t\t~FLASH_FSM_ST_MACHINE_DO_PRECOND_M) |\n\t\t((value << FLASH_FSM_ST_MACHINE_DO_PRECOND_S) &\n\t\tFLASH_FSM_ST_MACHINE_DO_PRECOND_M);\n\n\t/* Enable the recommended Good Time function. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_ST_MACHINE) |=\n\t\tFLASH_FSM_ST_MACHINE_ONE_TIME_GOOD;\n\n\t/* Disable write access to FSM registers. */\n\tHWREG(FLASH_BASE + FLASH_O_FSM_WR_ENA) = FSM_REG_WRT_DISABLE;\n\n\t/* Configure the voltage registers */\n\n\t/* Unlock voltage registers (0x2080 - 0x2098). */\n\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;\n\n\t/* Configure voltage level for the specified pump voltage of high\n\t   voltage supply input during erase operation VHVCT_E and TRIM13_E */\n\t/* (FCFG1 offset 0x190 bits[3:0] and bits[11:8]). */\n\ttemp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);\n\n\tvalue = ((temp_val & FCFG1_FLASH_VHV_TRIM13_E_M)>>\n\t\t\t\tFCFG1_FLASH_VHV_TRIM13_E_S) << FLASH_FVHVCT1_TRIM13_E_S;\n\tvalue |= ((temp_val & FCFG1_FLASH_VHV_VHV_E_M)>>\n\t\t\t\tFCFG1_FLASH_VHV_VHV_E_S) << FLASH_FVHVCT1_VHVCT_E_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &\n\t\t~(FLASH_FVHVCT1_TRIM13_E_M | FLASH_FVHVCT1_VHVCT_E_M)) | value;\n\n\t/* Configure voltage level for the specified pump voltage of high voltage\n\t   supply input during program verify operation VHVCT_PV and TRIM13_PV */\n\t/* (OTP offset 0x194 bits[19:16] and bits[27:24]). */\n\ttemp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV);\n\n\tvalue = ((temp_val & FCFG1_FLASH_VHV_PV_TRIM13_PV_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_PV_TRIM13_PV_S) << FLASH_FVHVCT1_TRIM13_PV_S;\n\tvalue |= ((temp_val & FCFG1_FLASH_VHV_PV_VHV_PV_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_PV_VHV_PV_S) << FLASH_FVHVCT1_VHVCT_PV_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVHVCT1) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT1) &\n\t\t~(FLASH_FVHVCT1_TRIM13_PV_M | FLASH_FVHVCT1_VHVCT_PV_M)) | value;\n\n\t/* Configure voltage level for the specified pump voltage of high voltage\n\t   supply input during program operation VHVCT_P and TRIM13_P */\n\t/* (FCFG1 offset 0x190 bits[19:16] and bits[27:24]). */\n\ttemp_val = HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV);\n\n\tvalue = ((temp_val & FCFG1_FLASH_VHV_TRIM13_P_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_TRIM13_P_S) << FLASH_FVHVCT2_TRIM13_P_S;\n\tvalue |= ((temp_val & FCFG1_FLASH_VHV_VHV_P_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_VHV_P_S) << FLASH_FVHVCT2_VHVCT_P_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVHVCT2) = (HWREG(FLASH_BASE + FLASH_O_FVHVCT2) &\n\t\t~(FLASH_FVHVCT2_TRIM13_P_M | FLASH_FVHVCT2_VHVCT_P_M)) | value;\n\n\t/* Configure voltage level for the specified pump voltage of wordline power\n\t   supply for read mode */\n\t/* (FCFG1 offset 0x198 Bits 15:8). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &\n\t\t\t\tFCFG1_FLASH_V_V_READ_M) >> FCFG1_FLASH_V_V_READ_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVREADCT) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FVREADCT) &\n\t\t~FLASH_FVREADCT_VREADCT_M) |\n\t\t((value << FLASH_FVREADCT_VREADCT_S) &\n\t\tFLASH_FVREADCT_VREADCT_M);\n\n\t/* Configure the voltage level for the VCG 2.5 CT pump voltage */\n\t/* (FCFG1 offset 0x194 bits 15:8). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_VHV_PV) &\n\t\t\t\tFCFG1_FLASH_VHV_PV_VCG2P5_M) >>\n\t\t\t\tFCFG1_FLASH_VHV_PV_VCG2P5_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVNVCT) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FVNVCT) &\n\t\t~FLASH_FVNVCT_VCG2P5CT_M) |\n\t\t((value << FLASH_FVNVCT_VCG2P5CT_S) &\n\t\tFLASH_FVNVCT_VCG2P5CT_M);\n\n\t/* Configure the voltage level for the specified pump voltage of high\n\t   current power input during program operation */\n\t/* (FCFG1 offset 0x198 bits 31:24). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &\n\t\t\t\tFCFG1_FLASH_V_VSL_P_M) >>\n\t\t\t\tFCFG1_FLASH_V_VSL_P_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVSLP) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FVSLP) &\n\t\t~FLASH_FVSLP_VSL_P_M) |\n\t\t((value << FLASH_FVSLP_VSL_P_S) &\n\t\tFLASH_FVSLP_VSL_P_M);\n\n\t/* Configure the voltage level for the specified pump voltage of wordline\n\t   power supply during programming operations */\n\t/* (OTP offset 0x198 bits 23:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_V) &\n\t\t\t\tFCFG1_FLASH_V_VWL_P_M) >>\n\t\t\t\tFCFG1_FLASH_V_VWL_P_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FVWLCT) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FVWLCT) &\n\t\t~FLASH_FVWLCT_VWLCT_P_M) |\n\t\t((value << FLASH_FVWLCT_VWLCT_P_S) &\n\t\tFLASH_FVWLCT_VWLCT_P_M);\n\n\t/* Configure the pump's TRIM_1P7 port pins. */\n\t/* (FCFG1 offset 0x2B0 bits 17:16). */\n\tvalue = (HWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA3) &\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_TRIM_1P7_M) >>\n\t\t\t\tFCFG1_FLASH_OTP_DATA3_TRIM_1P7_S;\n\n\tHWREG(FLASH_BASE + FLASH_O_FSEQPMP) =\n\t\t(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &\n\t\t~FLASH_FSEQPMP_TRIM_1P7_M) |\n\t\t((value << FLASH_FSEQPMP_TRIM_1P7_S) &\n\t\tFLASH_FSEQPMP_TRIM_1P7_M);\n\n\t/* Lock the voltage registers. */\n\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;\n\n\t/* Set trimmed flag. */\n\tHWREG(FLASH_BASE + FLASH_O_FWLOCK) = 5;\n\tHWREG(FLASH_BASE + FLASH_O_FWFLAG) |= FW_WRT_TRIMMED;\n\tHWREG(FLASH_BASE + FLASH_O_FWLOCK) = 0;\n}\n\n/******************************************************************************\n*\n* Used to scale the TI OTP values based on the FClk scaling value.\n*\n******************************************************************************/\nstatic uint32_t scale_cycle_values(uint32_t specified_timing,\n\tuint32_t scale_value)\n{\n\tuint32_t scaled_value = (specified_timing * scale_value) >> 6;\n\treturn scaled_value;\n}\n\n/******************************************************************************\n*\n* Used to set flash in read mode.\n*\n* Flash is configured with values loaded from OTP dependent on the current\n* regulator mode.\n*\n******************************************************************************/\nstatic void set_read_mode(void)\n{\n\tuint32_t trim_value;\n\tuint32_t value;\n\n\t/* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,\n\t   VIN_AT_X and VIN_BY_PASS for read mode */\n\tif (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &\n\t\tAON_PMCTL_PWRCTL_EXT_REG_MODE) {\n\n\t\t/* Select trim values for external regulator mode:\n\t\t   Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 7)\n\t\t   Configure STANDBY_PW_SEL   (OTP offset 0x308 bit 6:5)\n\t\t   Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;\n\n\t\ttrim_value =\n\t\t\tHWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);\n\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_MODE_SEL_S;\n\n\t\tvalue |= ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_PW_SEL_S;\n\n\t\t/* Configure DIS_STANDBY (OTP offset 0x308 bit 4).\n\t\t   Configure DIS_IDLE    (OTP offset 0x308 bit 3). */\n\t\tvalue |= ((trim_value &\n\t\t\t\t\t(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M |\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M)) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_DIS_IDLE_S;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &\n\t\t\t~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |\n\t\t\tFLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;\n\n\t\t/* Check if sample and hold functionality is disabled. */\n\t\tif (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {\n\t\t\t/* Wait for disabled sample and hold functionality to be stable. */\n\t\t\twhile (!(HWREG(FLASH_BASE+FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))\n\t\t\t\t;\n\t\t}\n\n\t\t/* Configure VIN_AT_X (OTP offset 0x308 bits 2:0) */\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S) <<\n\t\t\t\t\tFLASH_FSEQPMP_VIN_AT_X_S;\n\n\t\t/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.\n\t\t   If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise\n\t\t   VIN_BY_PASS should be 1 */\n\t\tif (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_S) != 0x7)\n\t\t\tvalue |= FLASH_FSEQPMP_VIN_BY_PASS;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSEQPMP) =\n\t\t\t(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &\n\t\t\t~(FLASH_FSEQPMP_VIN_BY_PASS_M |\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_M)) | value;\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;\n\t} else {\n\n\t\t/* Select trim values for internal regulator mode:\n\t\t   Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 15)\n\t\t   COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 14:13)\n\t\t   Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;\n\n\t\ttrim_value =\n\t\t\tHWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);\n\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_MODE_SEL_S;\n\n\t\tvalue |= ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_PW_SEL_S;\n\n\t\t/* Configure DIS_STANDBY (OTP offset 0x308 bit 12).\n\t\t   Configure DIS_IDLE    (OTP offset 0x308 bit 11). */\n\t\tvalue |= ((trim_value &\n\t\t\t\t\t(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M |\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M)) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S) <<\n\t\t\t\t\tFLASH_CFG_DIS_IDLE_S;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &\n\t\t\t~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |\n\t\t\tFLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;\n\n\t\t/* Check if sample and hold functionality is disabled. */\n\t\tif (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {\n\t\t\t/* Wait for disabled sample and hold functionality to be stable. */\n\t\t\twhile (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))\n\t\t\t\t;\n\t\t}\n\n\t\t/* Configure VIN_AT_X (OTP offset 0x308 bits 10:8) */\n\t\tvalue = (((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S) <<\n\t\t\t\t\tFLASH_FSEQPMP_VIN_AT_X_S);\n\n\t\t/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.\n\t\t   If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise\n\t\t   VIN_BY_PASS should be 1 */\n\t\tif (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_S) != 0x7)\n\t\t\tvalue |= FLASH_FSEQPMP_VIN_BY_PASS;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSEQPMP) =\n\t\t\t(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &\n\t\t\t~(FLASH_FSEQPMP_VIN_BY_PASS_M |\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_M)) | value;\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;\n\t}\n}\n\n/******************************************************************************\n*\n* Used to set flash in write mode.\n*\n* Flash is configured with values loaded from OTP dependent on the current\n* regulator mode.\n*\n******************************************************************************/\nstatic void set_write_mode(void)\n{\n\tuint32_t trim_value;\n\tuint32_t value;\n\n\t/* Configure the STANDBY_MODE_SEL, STANDBY_PW_SEL, DIS_STANDBY, DIS_IDLE,\n\t   VIN_AT_X and VIN_BY_PASS for program/erase mode */\n\tif (HWREG(AON_PMCTL_BASE + AON_PMCTL_O_PWRCTL) &\n\t\tAON_PMCTL_PWRCTL_EXT_REG_MODE) {\n\n\t\t/* Select trim values for external regulator mode:\n\t\t   Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 23)\n\t\t   Configure STANDBY_PW_SEL   (OTP offset 0x308 bit 22:21)\n\t\t   Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;\n\n\t\ttrim_value =\n\t\t\tHWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);\n\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_MODE_SEL_S;\n\n\t\tvalue |= ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_PW_SEL_S;\n\n\t\t/* Configure DIS_STANDBY (OTP offset 0x308 bit 20).\n\t\t   Configure DIS_IDLE    (OTP offset 0x308 bit 19). */\n\t\tvalue |= ((trim_value &\n\t\t\t\t\t(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M |\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M)) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_DIS_IDLE_S;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &\n\t\t\t~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |\n\t\t\tFLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;\n\n\t\t/* Check if sample and hold functionality is disabled. */\n\t\tif (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {\n\t\t\t/* Wait for disabled sample and hold functionality to be stable. */\n\t\t\twhile (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))\n\t\t\t\t;\n\t\t}\n\n\t\t/* Configure VIN_AT_X (OTP offset 0x308 bits 18:16) */\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S) <<\n\t\t\t\t\tFLASH_FSEQPMP_VIN_AT_X_S;\n\n\t\t/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.\n\t\t   If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise\n\t\t   VIN_BY_PASS should be 1 */\n\t\tif (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_S) != 0x7)\n\t\t\tvalue |= FLASH_FSEQPMP_VIN_BY_PASS;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSEQPMP) =\n\t\t\t(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &\n\t\t\t~(FLASH_FSEQPMP_VIN_BY_PASS_M |\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_M)) | value;\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;\n\t} else {\n\t\t/* Select trim values for internal regulator mode:\n\t\t   Configure STANDBY_MODE_SEL (OTP offset 0x308 bit 31)\n\t\t   COnfigure STANDBY_PW_SEL   (OTP offset 0x308 bit 30:29)\n\t\t   Must be done while the register bit field CONFIG.DIS_STANDBY = 1 */\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) |= FLASH_CFG_DIS_STANDBY;\n\n\t\ttrim_value =\n\t\t\tHWREG(FLASH_CFG_BASE + FCFG1_OFFSET + FCFG1_O_FLASH_OTP_DATA4);\n\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_MODE_SEL_S;\n\n\t\tvalue |= ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_STANDBY_PW_SEL_S;\n\n\t\t/* Configure DIS_STANDBY (OTP offset 0x308 bit 28).\n\t\t   Configure DIS_IDLE    (OTP offset 0x308 bit 27). */\n\t\tvalue |= ((trim_value &\n\t\t\t\t\t(FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M |\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M)) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S) <<\n\t\t\t\t\tFLASH_CFG_DIS_IDLE_S;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_CFG) = (HWREG(FLASH_BASE + FLASH_O_CFG) &\n\t\t\t~(FLASH_CFG_STANDBY_MODE_SEL_M | FLASH_CFG_STANDBY_PW_SEL_M |\n\t\t\tFLASH_CFG_DIS_STANDBY_M | FLASH_CFG_DIS_IDLE_M)) | value;\n\n\t\t/* Check if sample and hold functionality is disabled. */\n\t\tif (HWREG(FLASH_BASE + FLASH_O_CFG) & FLASH_CFG_DIS_IDLE) {\n\t\t\t/* Wait for disabled sample and hold functionality to be stable. */\n\t\t\twhile (!(HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_SAMHOLD_DIS))\n\t\t\t\t;\n\t\t}\n\n\t\t/* Configure VIN_AT_X (OTP offset 0x308 bits 26:24) */\n\t\tvalue = ((trim_value &\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M) >>\n\t\t\t\t\tFCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S) <<\n\t\t\t\t\tFLASH_FSEQPMP_VIN_AT_X_S;\n\n\t\t/* Configure VIN_BY_PASS which is dependent on the VIN_AT_X value.\n\t\t   If VIN_AT_X = 7 then VIN_BY_PASS should be 0 otherwise\n\t\t   VIN_BY_PASS should be 1 */\n\t\tif (((value & FLASH_FSEQPMP_VIN_AT_X_M) >>\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_S) != 0x7)\n\t\t\tvalue |= FLASH_FSEQPMP_VIN_BY_PASS;\n\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0xAAAA;\n\t\tHWREG(FLASH_BASE + FLASH_O_FSEQPMP) =\n\t\t\t(HWREG(FLASH_BASE + FLASH_O_FSEQPMP) &\n\t\t\t~(FLASH_FSEQPMP_VIN_BY_PASS_M |\n\t\t\tFLASH_FSEQPMP_VIN_AT_X_M)) | value;\n\t\tHWREG(FLASH_BASE + FLASH_O_FLOCK) = 0x55AA;\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/flash.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2016-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H\n#define OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"hw_regs.h\"\n\n/* Location of flash in memory map */\n#define FLASHMEM_BASE 0\n\n/* Defines to access flash API calls in ROM */\n#define ROM_API_TABLE       ((uint32_t *) 0x10000180)\n#define ROM_VERSION         (ROM_API_TABLE[0])\n#define ROM_API_FLASH_TABLE ((uint32_t *) (ROM_API_TABLE[10]))\n\n#if defined(DEVICE_CC26X2)\n\n/* Agama (CC26x2) specific definitions */\n\n#define FLASH_ERASE_SIZE       8192\n/* Agama (and Agama 1M) has a maximum of 132 flash sectors (1056KB / 8KB) */\n#define FLASH_MAX_SECTOR_COUNT 132\n#define FLASH_SECTOR_BASE_M    0xFFFFE000\n\n/* Bootloader Configuration */\n#define CCFG_O_BL_CONFIG 0x00001FD8\n\n#elif defined(DEVICE_CC26X0)\n\n/* Chameleon (CC26x0) specific definitions */\n\n#define FLASH_ERASE_SIZE       4096\n/* Chameleon has a maximum of 32 flash sectors (128KB / 4KB) */\n#define FLASH_MAX_SECTOR_COUNT 32\n#define FLASH_SECTOR_BASE_M    0xFFFFF000\n\n/* Bootloader Configuration */\n#define CCFG_O_BL_CONFIG 0x00000FD8\n\n#else\n#error No DEVICE defined.\n#endif\n\n/******************************************************************************\n*\n* Values that can be returned from the API functions\n*\n******************************************************************************/\n#define FAPI_STATUS_SUCCESS   0x00000000 /* Function completed successfully */\n#define FAPI_STATUS_FSM_BUSY  0x00000001 /* FSM is Busy */\n#define FAPI_STATUS_FSM_READY 0x00000002 /* FSM is Ready */\n#define FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH \\\n\t\t\t\t\t\t\t  0x00000003 /* Incorrect parameter value */\n#define FAPI_STATUS_FSM_ERROR 0x00000004 /* Operation failed */\n\n/******************************************************************************\n*\n* Define used by the flash programming and erase functions\n*\n******************************************************************************/\n#define ADDR_OFFSET (0x1F800000 - FLASHMEM_BASE)\n\n/******************************************************************************\n*\n* Define used for access to factory configuration area.\n*\n******************************************************************************/\n#define FCFG1_OFFSET 0x1000\n\n/******************************************************************************\n*\n* Define for the clock frequency input to the flash module in number of MHz\n*\n******************************************************************************/\n#define FLASH_MODULE_CLK_FREQ 48\n\n/******************************************************************************\n*\n* Defined values for Flash State Machine commands\n*\n******************************************************************************/\ntypedef enum {\n\tFAPI_PROGRAM_DATA    = 0x0002, /* Program data. */\n\tFAPI_ERASE_SECTOR    = 0x0006, /* Erase sector. */\n\tFAPI_ERASE_BANK      = 0x0008, /* Erase bank. */\n\tFAPI_VALIDATE_SECTOR = 0x000E, /* Validate sector. */\n\tFAPI_CLEAR_STATUS    = 0x0010, /* Clear status. */\n\tFAPI_PROGRAM_RESUME  = 0x0014, /* Program resume. */\n\tFAPI_ERASE_RESUME    = 0x0016, /* Erase resume. */\n\tFAPI_CLEAR_MORE      = 0x0018, /* Clear more. */\n\tFAPI_PROGRAM_SECTOR  = 0x0020, /* Program sector. */\n\tFAPI_ERASE_OTP       = 0x0030  /* Erase OTP. */\n} flash_state_command_t;\n\n/******************************************************************************\n*\n* Defines for values written to the FLASH_O_FSM_WR_ENA register\n*\n******************************************************************************/\n#define FSM_REG_WRT_ENABLE  5\n#define FSM_REG_WRT_DISABLE 2\n\n/******************************************************************************\n*\n* Defines for the bank power mode field the FLASH_O_FBFALLBACK register\n*\n******************************************************************************/\n#define FBFALLBACK_SLEEP      0\n#define FBFALLBACK_DEEP_STDBY 1\n#define FBFALLBACK_ACTIVE     3\n\n/******************************************************************************\n*\n* Defines for the bank grace period and pump grace period\n*\n******************************************************************************/\n#define FLASH_BAGP 0x14\n#define FLASH_PAGP 0x14\n\n/******************************************************************************\n*\n* Defines for the FW flag bits in the FLASH_O_FWFLAG register\n*\n******************************************************************************/\n#define FW_WRT_TRIMMED 0x00000001\n\n/******************************************************************************\n*\n* Defines used by the flash programming functions\n*\n******************************************************************************/\ntypedef volatile uint8_t fwp_write_byte;\n#define FWPWRITE_BYTE_ADDRESS \\\n\t((fwp_write_byte *)((FLASH_BASE + FLASH_O_FWPWRITE0)))\n\n/******************************************************************************\n*\n* Define for FSM command execution\n*\n******************************************************************************/\n#define FLASH_CMD_EXEC 0x15\n\n/******************************************************************************\n*\n* Get size of a flash sector in number of bytes.\n*\n* This function will return the size of a flash sector in number of bytes.\n*\n* Returns size of a flash sector in number of bytes.\n*\n******************************************************************************/\nstatic inline uint32_t flash_sector_size_get(void)\n{\n\tuint32_t sector_size_in_kbyte;\n\n\tsector_size_in_kbyte = (HWREG(FLASH_BASE + FLASH_O_FCFG_B0_SSIZE0) &\n\t\tFLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_M) >>\n\t\tFLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_S;\n\n\t/* Return flash sector size in number of bytes. */\n\treturn sector_size_in_kbyte * 1024;\n}\n\n/******************************************************************************\n*\n* Get the size of the flash.\n*\n* This function returns the size of the flash main bank in number of bytes.\n*\n* Returns the flash size in number of bytes.\n*\n******************************************************************************/\nstatic inline uint32_t flash_size_get(void)\n{\n\tuint32_t num_of_sectors;\n\n\t/* Get number of flash sectors */\n\tnum_of_sectors = (HWREG(FLASH_BASE + FLASH_O_FLASH_SIZE) &\n\t\t\t\t\t\tFLASH_FLASH_SIZE_SECTORS_M) >>\n\t\t\t\t\t\tFLASH_FLASH_SIZE_SECTORS_S;\n\n\t/* Return flash size in number of bytes */\n\treturn num_of_sectors * flash_sector_size_get();\n}\n\n/******************************************************************************\n*\n* Checks if the Flash state machine has detected an error.\n*\n* This function returns the status of the Flash State Machine indicating if\n* an error is detected or not. Primary use is to check if an Erase or\n* Program operation has failed.\n*\n* Please note that code can not execute in flash while any part of the flash\n* is being programmed or erased. This function must be called from ROM or\n* SRAM while any part of the flash is being programmed or erased.\n*\n* Returns status of Flash state machine:\n* FAPI_STATUS_FSM_ERROR\n* FAPI_STATUS_SUCCESS\n*\n******************************************************************************/\nstatic inline uint32_t flash_check_fsm_for_error(void)\n{\n\tif (HWREG(FLASH_BASE + FLASH_O_FMSTAT) & FLASH_FMSTAT_CSTAT)\n\t\treturn FAPI_STATUS_FSM_ERROR;\n\telse\n\t\treturn FAPI_STATUS_SUCCESS;\n}\n\n/******************************************************************************\n*\n* Checks if the Flash state machine is ready.\n*\n* This function returns the status of the Flash State Machine indicating if\n* it is ready to accept a new command or not. Primary use is to check if an\n* Erase or Program operation has finished.\n*\n* Please note that code can not execute in flash while any part of the flash\n* is being programmed or erased. This function must be called from ROM or\n* SRAM while any part of the flash is being programmed or erased.\n*\n* Returns readiness status of Flash state machine:\n* FAPI_STATUS_FSM_READY\n* FAPI_STATUS_FSM_BUSY\n*\n******************************************************************************/\nstatic inline uint32_t flash_check_fsm_for_ready(void)\n{\n\tif (HWREG(FLASH_BASE + FLASH_O_STAT) & FLASH_STAT_BUSY)\n\t\treturn FAPI_STATUS_FSM_BUSY;\n\telse\n\t\treturn FAPI_STATUS_FSM_READY;\n}\n\n/******************************************************************************\n*\n* Erase a flash sector.\n*\n* This function will erase the specified flash sector. The function will\n* not return until the flash sector has been erased or an error condition\n* occurred. If flash top sector is erased the function will program the\n* device security data bytes with default values. The device security\n* data located in the customer configuration area of the flash top sector,\n* must have valid values at all times. These values affect the configuration\n* of the device during boot.\n*\n* Please note that code can not execute in flash while any part of the flash\n* is being programmed or erased. This function must only be executed from ROM\n* or SRAM.\n*\n* sector_address is the starting address in flash of the sector to be\n* erased.\n*\n* Returns the status of the sector erase:\n* FAPI_STATUS_SUCCESS                     : Success.\n* FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Invalid argument.\n* FAPI_STATUS_FSM_ERROR                   : Programming error was encountered.\n*\n******************************************************************************/\nextern uint32_t flash_sector_erase(uint32_t sector_address);\n\n/******************************************************************************\n*\n* Erase all unprotected sectors in the flash main bank.\n*\n* This function will erase all unprotected flash sectors. The function will\n* not return until the flash sectors has been erased or an error condition\n* occurred. Since the flash top sector is erased the function will program\n* the device security data bytes with default values. The device security\n* data located in the customer configuration area of the flash top sector,\n* must have valid values at all times. These values affect the configuration\n* of the device during boot. The execution time of the operation increases if\n* erase precondition is forced. This will cause the flash module to first\n* program all 1 bits in the bank to 0 before the actual erase is started.\n*\n* force_precondition controls if erase precondition should be forced.\n*\n* Returns the status of the sector erase:\n* FAPI_STATUS_SUCCESS   : Success\n* FAPI_STATUS_FSM_ERROR : Erase error was encountered.\n*\n******************************************************************************/\nextern uint32_t flash_bank_erase(bool force_precondition);\n\n/******************************************************************************\n*\n* Programs unprotected main bank flash sectors.\n*\n* This function will program a sequence of bytes into the on-chip flash.\n* Programming each location consists of the result of an AND operation\n* of the new data and the existing data; in other words bits that contain\n* 1 can remain 1 or be changed to 0, but bits that are 0 cannot be changed\n* to 1.  Therefore, a byte can be programmed multiple times as long as these\n* rules are followed; if a program operation attempts to change a 0 bit to\n* a 1 bit, that bit will not have its value changed.\n*\n* This function will not return until the data has been programmed or an\n* programming error has occurred.\n*\n* Please note that code can not execute in flash while any part of the flash\n* is being programmed or erased. This function must only be executed from ROM\n* or SRAM.\n*\n* The data_buffer pointer cannot point to flash.\n*\n* data_buffer is a pointer to the data to be programmed.\n* address is the starting address in flash to be programmed.\n* count is the number of bytes to be programmed.\n*\n* Returns status of the flash programming:\n* FAPI_STATUS_SUCCESS                     : Success.\n* FAPI_STATUS_INCORRECT_DATABUFFER_LENGTH : Too many bytes were requested.\n* FAPI_STATUS_FSM_ERROR                   : Programming error was encountered.\n*\n******************************************************************************/\nextern uint32_t flash_program(uint8_t *data_buffer, uint32_t address,\n\tuint32_t count);\n\n/******************************************************************************\n*\n* Disables all sectors for erase and programming on the active bank.\n*\n* This function disables all sectors for erase and programming on the active\n* bank and enables the Idle Reading Power reduction mode if no low power\n* mode is configured. Furthermore, an additional level of protection from\n* erase is enabled.\n*\n* Please note that code can not execute in flash while any part of the flash\n* is being programmed or erased.\n*\n******************************************************************************/\nextern void flash_disable_sectors_for_write(void);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* #ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASH_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/flashloader.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"flashloader.h\"\n#include \"flash.h\"\n\n/* Array holding erased state of the flash sectors. */\nstatic bool g_is_erased[FLASH_MAX_SECTOR_COUNT];\n\nextern uint8_t g_retain_buf[];\n\nuint32_t flashloader_init(struct flash_params *params, uint8_t *buf1,\n\tuint8_t *buf2)\n{\n\t/* Initialize params buffers */\n\tmemset((void *)params, 0, 2 * sizeof(struct flash_params));\n\tparams[0].buf_addr = (uint32_t)buf1;\n\tparams[1].buf_addr = (uint32_t)buf2;\n\n\t/* Mark all sectors at \"not erased\" */\n\tmemset(g_is_erased, false, sizeof(g_is_erased));\n\n\treturn STATUS_OK;\n}\n\nuint32_t flashloader_erase_and_program(uint8_t *src, uint32_t address,\n\tuint32_t byte_count)\n{\n\tif (byte_count > BUFFER_LEN)\n\t\treturn STATUS_FAILED_INVALID_ARGUMENTS;\n\n\t/* Erase affected sectors */\n\tuint32_t status = flashloader_erase_sectors(address, byte_count);\n\n\tif (status != STATUS_OK)\n\t\treturn status;\n\n\t/* Program data */\n\tstatus = flashloader_program(src, address, byte_count);\n\n\treturn status;\n}\n\nuint32_t flashloader_program_with_retain(uint8_t *src, uint32_t address,\n\tuint32_t byte_count)\n{\n#if (BUFFER_LEN > FLASH_ERASE_SIZE)\n#error Buffer size cannot be larger than the flash sector size!\n#endif\n\n\tuint32_t first_sector_idx;\n\tuint32_t last_sector_idx;\n\tuint32_t status = STATUS_OK;\n\tuint32_t i;\n\n\tfirst_sector_idx = flashloader_address_to_sector(address);\n\tlast_sector_idx = flashloader_address_to_sector(address + byte_count - 1);\n\n\t/* Mark all sectors as \"not erased\" before starting */\n\tmemset(g_is_erased, false, sizeof(g_is_erased));\n\n\tuint32_t sec_offset = address % FLASH_ERASE_SIZE;\n\tuint32_t curr_count;\n\tuint32_t src_offset = 0;\n\n\tfor (i = first_sector_idx; i <= last_sector_idx; i++) {\n\n\t\t/* Chop off at sector boundary if data goes into the next sector. */\n\t\tcurr_count = byte_count;\n\t\tif ((address + byte_count) > ((i+1) * FLASH_ERASE_SIZE))\n\t\t\tcurr_count -= (address + byte_count) % FLASH_ERASE_SIZE;\n\n\t\t/* Copy flash sector to retain buffer */\n\t\tmemcpy(g_retain_buf, (void *)(i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);\n\n\t\t/* Copy data buffer to retain buffer */\n\t\tmemcpy(&g_retain_buf[sec_offset], &src[src_offset], curr_count);\n\n\t\t/* Erase and program from retain buffer */\n\t\tstatus = flashloader_erase_and_program(g_retain_buf,\n\t\t\t\t\t(i * FLASH_ERASE_SIZE), FLASH_ERASE_SIZE);\n\t\tif (status != STATUS_OK)\n\t\t\treturn status;\n\n\t\taddress += curr_count;\n\t\tsec_offset = address % FLASH_ERASE_SIZE;\n\t\tbyte_count -= curr_count;\n\t\tsrc_offset += curr_count;\n\t}\n\n\treturn status;\n}\n\nuint32_t flashloader_erase_all(void)\n{\n\tif (flash_bank_erase(true) != FAPI_STATUS_SUCCESS)\n\t\treturn STATUS_FAILED_ERASE_ALL;\n\n\tmemset(g_is_erased, true, sizeof(g_is_erased));\n\n\treturn STATUS_OK;\n}\n\nuint32_t flashloader_erase_sectors(uint32_t address, uint32_t byte_count)\n{\n\tuint32_t first_sector_idx;\n\tuint32_t last_sector_idx;\n\tuint32_t status;\n\tuint32_t idx;\n\n\t/* Floor address to the start of the sector and convert to sector number */\n\tfirst_sector_idx = flashloader_address_to_sector(address);\n\tlast_sector_idx = flashloader_address_to_sector(address + byte_count - 1);\n\n\t/*  Erase given sector(s) */\n\tfor (idx = first_sector_idx; idx <= last_sector_idx; idx++) {\n\n\t\t/* Only erase sectors that haven't already been erased */\n\t\tif (g_is_erased[idx] == false) {\n\t\t\tstatus = flash_sector_erase(idx * FLASH_ERASE_SIZE);\n\t\t\tif (status != FAPI_STATUS_SUCCESS) {\n\t\t\t\tstatus = (STATUS_FAILED_SECTOR_ERASE |\n\t\t\t\t\t\t((idx << STATUS_EXT_INFO_S) & STATUS_EXT_INFO_M) |\n\t\t\t\t\t\t((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));\n\t\t\t\treturn status;\n\t\t\t}\n\t\t\tg_is_erased[idx] = true;\n\t\t}\n\t}\n\n\treturn STATUS_OK;\n}\n\nuint32_t flashloader_program(uint8_t *src, uint32_t address,\n\tuint32_t byte_count)\n{\n\tuint32_t status = flash_program(src, address, byte_count);\n\tif (status != FAPI_STATUS_SUCCESS) {\n\t\tstatus = (STATUS_FAILED_PROGRAM |\n\t\t\t\t\t((status << STATUS_ROM_CODE_S) & STATUS_ROM_CODE_M));\n\t}\n\n\treturn STATUS_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/flashloader.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H\n#define OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <string.h>\n#include \"flash.h\"\n\n/* Number of elements in an array */\n#define NELEMS(a) (sizeof(a) / sizeof(a[0]))\n\nstruct __attribute__((__packed__)) flash_params {\n\tuint32_t dest;     /* Destination address in flash */\n\tuint32_t len;      /* Number of bytes */\n\tuint32_t cmd;      /* Command */\n\tuint32_t full;     /* Handshake signal. Is buffer ready? */\n\tuint32_t buf_addr; /* Address of data buffer. */\n};\n\ntypedef enum {\n\tCMD_NO_ACTION = 0,                     /* No action, default value */\n\tCMD_ERASE_ALL = 1,                     /* Erase all unprotected sectors */\n\tCMD_PROGRAM = 2,                       /* Program data */\n\tCMD_ERASE_AND_PROGRAM = 3,             /* Erase and program data */\n\tCMD_ERASE_AND_PROGRAM_WITH_RETAIN = 4, /* Erase and program, but retain */\n\t\t\t\t\t\t\t\t\t\t   /* sector data outside given range */\n\tCMD_ERASE_SECTORS = 5                  /* Erase unprotected sectors */\n} flash_commands_t;\n\ntypedef enum {\n\tBUFFER_EMPTY = 0x0,      /* No data in buffer, flags last task complete */\n\tBUFFER_FULL = 0xFFFFFFFF /* Buffer has data, flags next task to start */\n} flash_handshake_t;\n\n#define STATUS_FLASHLOADER_STATUS_M 0x0000FFFF\n#define STATUS_FLASHLOADER_STATUS_S 0\n#define STATUS_ROM_CODE_M           0x00FF0000\n#define STATUS_ROM_CODE_S           16\n#define STATUS_EXT_INFO_M           0xFF000000\n#define STATUS_EXT_INFO_S           24\n\ntypedef enum {\n\tSTATUS_OK = 0,\n\tSTATUS_FAILED_ERASE_ALL = 0x101,\n\tSTATUS_FAILED_SECTOR_ERASE = 0x102,\n\tSTATUS_FAILED_PROGRAM = 0x103,\n\tSTATUS_FAILED_INVALID_ARGUMENTS = 0x104,\n\tSTATUS_FAILED_UNKNOWN_COMMAND = 0x105,\n} flash_status_t;\n\n/* The buffer size used by the flashloader. The size of 1 flash sector. */\n#define BUFFER_LEN FLASH_ERASE_SIZE\n\n/*\n* This function initializes the flashloader. The application must\n* allocate memory for the two data buffers and the flash_params structures.\n*\n* params Pointer an flash_params array with 2 elements.\n* buf1   Pointer to data buffer 1\n* buf2   Pointer to data buffer 2\n*\n* Returns STATUS_OK\n*\n*/\nextern uint32_t flashloader_init(struct flash_params *params, uint8_t *buf1,\n\tuint8_t *buf2);\n\n/*\n* Erase and program the necessary sectors. Data outside the given\n* range will be deleted.\n*\n* src        Pointer to buffer containing the data.\n* address    Start address in device flash\n* byte_count The number of bytes to program\n*\n* Returns STATUS_OK on success. For status on failure:\n* See flashloader_program() and flashloader_erase_sectors().\n*\n*/\nextern uint32_t flashloader_erase_and_program(uint8_t *src, uint32_t address,\n\tuint32_t byte_count);\n\n/*\n* Erase and program the device sectors. Data outside the given\n* data range will be kept unchanged.\n*\n* src        Pointer to buffer containing the data.\n* address    Start address in device flash\n* byte_count The number of bytes to program\n*\n* Returns STATUS_OK on success. For status on failure:\n* See flashloader_program() and flashloader_erase_sectors().\n*\n*/\nextern uint32_t flashloader_program_with_retain(uint8_t *src, uint32_t address,\n\tuint32_t byte_count);\n\n/*\n* Erases all flash sectors (that are not write-protected).\n*\n* Returns STATUS_OK on success.\n*\n*/\nextern uint32_t flashloader_erase_all(void);\n\n/*\n* Erases the flash sectors affected by the given range.\n*\n* This function only erases sectors that are not already erased.\n*\n* start_addr The first address in the range.\n* byte_count The number of bytes in the range.\n*\n* Returns STATUS_OK on success. Returns a combined status on failure:\n* [31:24] The sector that failed.\n* [23:16] ROM function status code. 0 means success.\n* [16: 0] STATUS_FAILED_SECTOR_ERASE\n*\n*/\nextern uint32_t flashloader_erase_sectors(uint32_t start_addr,\n\tuint32_t byte_count);\n\n/*\n* Program the given range.\n*\n* This function does not erase anything, it assumes the sectors are ready to\n* be programmed.\n*\n* src        Pointer to buffer containing the data.\n* address    Start address in device flash\n* byte_count The number of bytes to program\n*\n* Returns STATUS_OK on success. Returns a combined status value on failure:\n* [31:16] ROM function status code. 0 means success.\n* [15:0 ] STATUS_FAILED_PROGRAM\n*\n*/\nextern uint32_t flashloader_program(uint8_t *src, uint32_t address,\n\tuint32_t byte_count);\n\n/*\n* Convert the input address into a sector number.\n*\n* address The address.\n*\n* Returns the flash sector which the address resides in. The first sector\n* is sector 0.\n*\n*/\nstatic inline uint32_t flashloader_address_to_sector(uint32_t address)\n\t{ return (address / FLASH_ERASE_SIZE); };\n\n#endif /* #ifndef OPENOCD_LOADERS_FLASH_CC26XX_FLASHLOADER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/hw_regs.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_CC26XX_HW_REGS_H\n#define OPENOCD_LOADERS_FLASH_CC26XX_HW_REGS_H\n\n/******************************************************************************\n*\n* Macros for direct hardware access.\n*\n* If using these macros the programmer should be aware of any limitations to\n* the address accessed i.e. if it supports word and/or byte access.\n*\n******************************************************************************/\n/* Word (32 bit) access to address x */\n/* Read example  : my32BitVar = HWREG(base_addr + offset) ; */\n/* Write example : HWREG(base_addr + offset) = my32BitVar ; */\n#define HWREG(x) (*((volatile unsigned long *)(x)))\n\n/* Half word (16 bit) access to address x */\n/* Read example  : my16BitVar = HWREGH(base_addr + offset) ; */\n/* Write example : HWREGH(base_addr + offset) = my16BitVar ; */\n#define HWREGH(x) (*((volatile unsigned short *)(x)))\n\n/* Byte (8 bit) access to address x */\n/* Read example  : my8BitVar = HWREGB(base_addr + offset) ; */\n/* Write example : HWREGB(base_addr + offset) = my8BitVar ; */\n#define HWREGB(x) (*((volatile unsigned char *)(x)))\n\n/******************************************************************************\n*\n* Macro for access to bit-band supported addresses via the bit-band region.\n*\n* Macro calculates the corresponding address to access in the bit-band region\n* based on the actual address of the memory/register and the bit number.\n*\n* Do NOT use this macro to access the bit-band region directly!\n*\n******************************************************************************/\n/* Bit-band access to address x bit number b using word access (32 bit) */\n#define HWREGBITW(x, b) \\\n\tHWREG(((unsigned long)(x) & 0xF0000000) | 0x02000000 | \\\n\t\t(((unsigned long)(x) & 0x000FFFFF) << 5) | ((b) << 2))\n\n/******************************************************************************\n*\n* Memory mapped components base address definitions\n*\n******************************************************************************/\n#define FLASH_BASE                                                  0x40030000\n#define FLASH_CFG_BASE                                              0x50000000\n#define AON_PMCTL_BASE                                              0x40090000\n\n/******************************************************************************\n*\n* This section defines the register offsets of FLASH component\n*\n******************************************************************************/\n\n/* FMC and Efuse Status */\n#define FLASH_O_STAT                                                0x0000001C\n\n/* Configuration */\n#define FLASH_O_CFG                                                 0x00000024\n\n/* Flash Size Configuration */\n#define FLASH_O_FLASH_SIZE                                          0x0000002C\n\n/* Firmware Lock */\n#define FLASH_O_FWLOCK                                              0x0000003C\n\n/* Firmware Flags */\n#define FLASH_O_FWFLAG                                              0x00000040\n\n/* FMC Read Control */\n#define FLASH_O_FRDCTL                                              0x00002000\n\n/* FMC Bank Protection */\n#define FLASH_O_FBPROT                                              0x00002030\n\n/* FMC Bank Sector Enable */\n#define FLASH_O_FBSE                                                0x00002034\n\n/* FMC Module Access Control */\n#define FLASH_O_FMAC                                                0x00002050\n\n/* FMC Module Status */\n#define FLASH_O_FMSTAT                                              0x00002054\n\n/* FMC Flash Lock */\n#define FLASH_O_FLOCK                                               0x00002064\n\n/* FMC VREADCT Trim */\n#define FLASH_O_FVREADCT                                            0x00002080\n\n/* FMC VHVCT1 Trim */\n#define FLASH_O_FVHVCT1                                             0x00002084\n\n/* FMC VHVCT2 Trim */\n#define FLASH_O_FVHVCT2                                             0x00002088\n\n/* FMC VNVCT Trim */\n#define FLASH_O_FVNVCT                                              0x00002090\n\n/* FMC VSL_P Trim */\n#define FLASH_O_FVSLP                                               0x00002094\n\n/* FMC VWLCT Trim */\n#define FLASH_O_FVWLCT                                              0x00002098\n\n/* FMC Sequential Pump Information */\n#define FLASH_O_FSEQPMP                                             0x000020A8\n\n/* FMC FSM Command */\n#define FLASH_O_FSM_CMD                                             0x0000220C\n\n/* FMC FSM Program/Erase Operation Setup */\n#define FLASH_O_FSM_PE_OSU                                          0x00002210\n\n/* FMC FSM Voltage Status Setup */\n#define FLASH_O_FSM_VSTAT                                           0x00002214\n\n/* FMC FSM Program/Erase Verify Setup */\n#define FLASH_O_FSM_PE_VSU                                          0x00002218\n\n/* FMC FSM Compare Verify Setup */\n#define FLASH_O_FSM_CMP_VSU                                         0x0000221C\n\n/* FMC FSM EXECUTEZ to Valid Data */\n#define FLASH_O_FSM_EX_VAL                                          0x00002220\n\n/* FMC FSM Read Mode Hold */\n#define FLASH_O_FSM_RD_H                                            0x00002224\n\n/* FMC FSM Program Hold */\n#define FLASH_O_FSM_P_OH                                            0x00002228\n\n/* FMC FSM Erase Operation Hold */\n#define FLASH_O_FSM_ERA_OH                                          0x0000222C\n\n/* FMC FSM Program/Erase Verify Hold */\n#define FLASH_O_FSM_PE_VH                                           0x00002234\n\n/* FMC FSM Program Pulse Width */\n#define FLASH_O_FSM_PRG_PW                                          0x00002240\n\n/* FMC FSM Erase Pulse Width */\n#define FLASH_O_FSM_ERA_PW                                          0x00002244\n\n/* FMC FSM Maximum Programming Pulses */\n#define FLASH_O_FSM_PRG_PUL                                         0x00002268\n\n/* FMC FSM Maximum Erase Pulses */\n#define FLASH_O_FSM_ERA_PUL                                         0x0000226C\n\n/* FMC FSM EC Step Size */\n#define FLASH_O_FSM_STEP_SIZE                                       0x00002270\n\n/* FMC FSM EC Step Height */\n#define FLASH_O_FSM_EC_STEP_HEIGHT                                  0x00002278\n\n/* FMC FSM_ST_MACHINE */\n#define FLASH_O_FSM_ST_MACHINE                                      0x0000227C\n\n/* FMC FSM Register Write Enable */\n#define FLASH_O_FSM_WR_ENA                                          0x00002288\n\n/* FMC FSM Command Execute */\n#define FLASH_O_FSM_EXECUTE                                         0x000022B4\n\n/* FMC FSM Sector Erased 1 */\n#define FLASH_O_FSM_SECTOR1                                         0x000022C0\n\n/* FMC FSM Sector Erased  2 */\n#define FLASH_O_FSM_SECTOR2                                         0x000022C4\n\n/* FMC Flash Bank 0 Starting Address */\n#define FLASH_O_FCFG_B0_START                                       0x00002410\n\n/* FMC Flash Bank 0 Sector Size 0 */\n#define FLASH_O_FCFG_B0_SSIZE0                                      0x00002430\n\n/******************************************************************************\n*\n* Register: FLASH_O_STAT\n*\n******************************************************************************/\n/* Field:     [2] SAMHOLD_DIS\n*\n* Status indicator of flash sample and hold sequencing logic. This bit will go\n* to 1 some delay after CFG.DIS_IDLE is set to 1.\n* 0: Not disabled\n* 1: Sample and hold disabled and stable */\n#define FLASH_STAT_SAMHOLD_DIS                                      0x00000004\n\n/* Field:     [1] BUSY\n*\n* Fast version of the FMC FMSTAT.BUSY bit.\n* This flag is valid immediately after the operation setting it (FMSTAT.BUSY\n* is delayed some cycles)\n* 0 : Not busy\n* 1 : Busy */\n#define FLASH_STAT_BUSY                                             0x00000002\n\n/******************************************************************************\n*\n* Register: FLASH_O_CFG\n*\n******************************************************************************/\n/* Field:     [8] STANDBY_MODE_SEL\n*\n* [Configured by boot firmware]\n* STANDBY mode selection control. This bit, in conjunction with\n* STANDBY_PW_SEL, determine which 1 of 4 sub-modes is selected for control of\n* the behavior and timing of the STANDBY input to the pump.\n*\n* 0 : Legacy PG1 behavior is selected when STANDBY_PW_SEL = 00. This is\n* referred to as sub-mode 1. When STANDBY_PW_SEL != 00, then sub-mode 2\n* behavior is selected. STANDBY will be glitchy in these modes.\n* 1 : STANDBY pulse-width counter modes selected. In these two modes (referred\n* to as sub-mode 3 and sub-mode 4), the low time pulse width of the STANDBY\n* signal to the pump, is controlled by a programmable timer. STANDBY will not\n* be glitchy in these modes. */\n#define FLASH_CFG_STANDBY_MODE_SEL_M                                0x00000100\n#define FLASH_CFG_STANDBY_MODE_SEL_S                                         8\n\n/* Field:   [7:6] STANDBY_PW_SEL\n*\n* [Configured by boot firmware]\n* STANDBY pulse width counter selection control. These bits, in conjunction\n* with STANDBY_MODE_SEL, determine which 1 of 4 sub-modes is selected for\n* control of the behavior and timing of the STANDBY input to the pump.\n*\n* 00 : Legacy PG1 behavior is selected when STANDBY_MODE_SEL=0. Sub-mode 4 is\n* selected when STANDBY_MODE_SEL=1. In sub-mode 4, STANDBY will be low for at\n* least 9 pump clock cycles.\n* 01 : Sub-mode 2 or 3 is selected, and STANDBY will be low for at least 9\n* pump clock cycles.\n* 10: Sub-mode 2 or 3 is selected, and STANDBY will be low for at least 5 pump\n* clock cycles.\n* 11: Sub-mode 2 or 3 is selected, and STANDBY will be low for at least 13\n* pump clock cycles. */\n#define FLASH_CFG_STANDBY_PW_SEL_M                                  0x000000C0\n#define FLASH_CFG_STANDBY_PW_SEL_S                                           6\n\n/* Field:     [1] DIS_STANDBY\n*\n* [Configured by boot firmware]\n* Disable standby functionality in read idle state */\n#define FLASH_CFG_DIS_STANDBY                                       0x00000002\n#define FLASH_CFG_DIS_STANDBY_BITN                                           1\n#define FLASH_CFG_DIS_STANDBY_M                                     0x00000002\n\n/* Field:     [0] DIS_IDLE\n*\n* [Configured by boot firmware]\n* Disable sample and hold functionality in read idle state */\n#define FLASH_CFG_DIS_IDLE                                          0x00000001\n#define FLASH_CFG_DIS_IDLE_M                                        0x00000001\n#define FLASH_CFG_DIS_IDLE_S                                                 0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FLASH_SIZE\n*\n******************************************************************************/\n/* Field:   [7:0] SECTORS\n*\n* [Configured by boot firmware]\n* Flash size. The number of flash sectors in the configured device. Read\n* access to sectors equal to this number or higher will result in an error.\n* The CCFG area is the sector (SECTORS - 1) Writing to this register is\n* disabled by the CFG.CONFIGURED bit. */\n#define FLASH_FLASH_SIZE_SECTORS_M                                  0x000000FF\n#define FLASH_FLASH_SIZE_SECTORS_S                                           0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FRDCTL\n*\n******************************************************************************/\n/* Field:  [11:8] RWAIT\n*\n* [Configured by boot firmware]\n* FMC Wait State. This field determines the FLCLK period during FMC controlled\n*  flash accesses:\n* - During power up/ power down / low power mode\n* - During FSM operations like program, erase\n* - During software interface mode (see  FLOCK , FBSTROBES registers)\n* FLCLK_period = HCLK_period X (RWAIT + 1),\n* FSM state machine operations are usually twice this amount. This value\n* should never be set less than 2. */\n#define FLASH_FRDCTL_RWAIT_M                                        0x00000F00\n#define FLASH_FRDCTL_RWAIT_S                                                 8\n\n/******************************************************************************\n*\n* Register: FLASH_O_FBPROT\n*\n******************************************************************************/\n/* Field:     [0] PROTL1DIS\n*\n* Level 1 Protection Disable bit. Setting this bit disables protection from\n* writing to the FBAC.OTPPROTDIS bits as well as the Sector Enable registers\n* FBSE for all banks. Clearing this bit enables protection and disables write\n* access to the FBAC.OTPPROTDIS register bits and FBSE register. */\n#define FLASH_FBPROT_PROTL1DIS                                      0x00000001\n\n/******************************************************************************\n*\n* Register: FLASH_O_FMSTAT\n*\n******************************************************************************/\n/* Field:     [4] CSTAT\n*\n* Command Status. Once the FSM starts any failure will set this bit. When set,\n* this bit informs the host that the program, erase, or validate sector\n* command failed and the command was stopped. This bit is cleared by the\n* Clear_Status command. For some errors, this will be the only indication of\n* an FSM error because the cause does not fall within the other error bit\n* types. */\n#define FLASH_FMSTAT_CSTAT                                          0x00000010\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVREADCT\n*\n******************************************************************************/\n/* Field:   [3:0] VREADCT\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of\n* wordline power supply for read mode. */\n#define FLASH_FVREADCT_VREADCT_M                                    0x0000000F\n#define FLASH_FVREADCT_VREADCT_S                                             0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVHVCT1\n*\n******************************************************************************/\n/* Field: [23:20] TRIM13_E\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during erase operation. */\n#define FLASH_FVHVCT1_TRIM13_E_M                                    0x00F00000\n#define FLASH_FVHVCT1_TRIM13_E_S                                            20\n\n/* Field: [19:16] VHVCT_E\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during erase operation. */\n#define FLASH_FVHVCT1_VHVCT_E_M                                     0x000F0000\n#define FLASH_FVHVCT1_VHVCT_E_S                                             16\n\n/* Field:   [7:4] TRIM13_PV\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during program verify operation. */\n#define FLASH_FVHVCT1_TRIM13_PV_M                                   0x000000F0\n#define FLASH_FVHVCT1_TRIM13_PV_S                                            4\n\n/* Field:   [3:0] VHVCT_PV\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during program verify operation. */\n#define FLASH_FVHVCT1_VHVCT_PV_M                                    0x0000000F\n#define FLASH_FVHVCT1_VHVCT_PV_S                                             0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVHVCT2\n*\n******************************************************************************/\n/* Field: [23:20] TRIM13_P\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during program operation. */\n#define FLASH_FVHVCT2_TRIM13_P_M                                    0x00F00000\n#define FLASH_FVHVCT2_TRIM13_P_S                                            20\n\n/* Field: [19:16] VHVCT_P\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* voltage supply input during program operation. */\n#define FLASH_FVHVCT2_VHVCT_P_M                                     0x000F0000\n#define FLASH_FVHVCT2_VHVCT_P_S                                             16\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVNVCT\n*\n******************************************************************************/\n/* Field:  [12:8] VCG2P5CT\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the VCG 2.5 CT pump voltage. */\n#define FLASH_FVNVCT_VCG2P5CT_M                                     0x00001F00\n#define FLASH_FVNVCT_VCG2P5CT_S                                              8\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVSLP\n*\n******************************************************************************/\n/* Field: [15:12] VSL_P\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of high\n* current power input during program operation. */\n#define FLASH_FVSLP_VSL_P_M                                         0x0000F000\n#define FLASH_FVSLP_VSL_P_S                                                 12\n\n/******************************************************************************\n*\n* Register: FLASH_O_FVWLCT\n*\n******************************************************************************/\n/* Field:   [4:0] VWLCT_P\n*\n* [Configured by boot firmware]\n* These bits control the voltage level for the specified pump voltage of\n* wordline power supply during programming operations. */\n#define FLASH_FVWLCT_VWLCT_P_M                                      0x0000001F\n#define FLASH_FVWLCT_VWLCT_P_S                                               0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSEQPMP\n*\n******************************************************************************/\n/* Field: [21:20] TRIM_1P7\n*\n* [Configured by boot firmware]\n* This register goes directly to the pump's TRIM_1P7 port pins. */\n#define FLASH_FSEQPMP_TRIM_1P7_M                                    0x00300000\n#define FLASH_FSEQPMP_TRIM_1P7_S                                            20\n\n/* Field: [14:12] VIN_AT_X\n*\n* This register controls to the pump's VIN_AT_XPX port pins with the following\n* encoding;\n*\n* If VIN_BY_PASS=0 then pump VIN_AT_XPX is equal to VIN_AT_XIN input ports\n* from the BATMON logic after clocking through synchronizers and the sequence\n* checker FSM logic contained in the flash wrapper.\n*\n* If VIN_BY_PASS=1 and VIN_AT_X=???\n*\n* 0: then all pump VIN_AT_XPX signals are 0.\n* 1: then pump VIN_AT_1P7 is set.\n* 2: then pump VIN_AT_2P1 is also set.\n* 3: then pump VIN_AT_2P4 is also set.\n* 4-7: then pump VIN_AT_3P0 is also set (ie all VIN_AT_XPX signals are 1). */\n#define FLASH_FSEQPMP_VIN_AT_X_M                                    0x00007000\n#define FLASH_FSEQPMP_VIN_AT_X_S                                            12\n\n/* Field:     [8] VIN_BY_PASS\n*\n* [Configured by boot firmware]\n*\n* When this bit is a zero, the pump's VIN_AT_XPX ports comes from the FMC\n* input port VIN_AT_XIN.\n*\n* When this bit is a one, the pump's VIN_AT_XPX ports comes from the VIN_AT_X\n* bits in 14:12. */\n#define FLASH_FSEQPMP_VIN_BY_PASS                                   0x00000100\n#define FLASH_FSEQPMP_VIN_BY_PASS_M                                 0x00000100\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_PE_OSU\n*\n******************************************************************************/\n/* Field:  [15:8] PGM_OSU\n*\n* [Configured by boot firmware]\n* Program Operation Setup time. This determines the flash clocks from the mode\n* change to program, to the start of the program pulse. */\n#define FLASH_FSM_PE_OSU_PGM_OSU_M                                  0x0000FF00\n#define FLASH_FSM_PE_OSU_PGM_OSU_S                                           8\n\n/* Field:   [7:0] ERA_OSU\n*\n* [Configured by boot firmware]\n* Erase Operation Setup time. This determines the flash clocks from the mode\n* change to erase, to the start of the erase pulse. */\n#define FLASH_FSM_PE_OSU_ERA_OSU_M                                  0x000000FF\n#define FLASH_FSM_PE_OSU_ERA_OSU_S                                           0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_VSTAT\n*\n******************************************************************************/\n/* Field: [15:12] VSTAT_CNT\n*\n* [Configured by boot firmware]\n* Voltage Status Count. Gives the number of consecutive HCLK pulses that must\n* be out of range before a voltage-out-of-range status error is given in\n* FMSTAT.VOLSTAT. One pulse in range will reset the counter. This is mainly a\n* glitch filter on the voltage status pump signal. */\n#define FLASH_FSM_VSTAT_VSTAT_CNT_M                                 0x0000F000\n#define FLASH_FSM_VSTAT_VSTAT_CNT_S                                         12\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_PE_VSU\n*\n******************************************************************************/\n/* Field:  [15:8] PGM_VSU\n*\n* [Configured by boot firmware]\n* Program Verify Setup time. This determines the flash clocks from the mode\n* change to program verify, to the change of address and the beginning of the\n* address setup time. */\n#define FLASH_FSM_PE_VSU_PGM_VSU_M                                  0x0000FF00\n#define FLASH_FSM_PE_VSU_PGM_VSU_S                                           8\n\n/* Field:   [7:0] ERA_VSU\n*\n* [Configured by boot firmware]\n* Erase Verify Setup time. This determines the flash clocks from the mode\n* change to erase verify, to the change of address and the beginning of the\n* address setup time. */\n#define FLASH_FSM_PE_VSU_ERA_VSU_M                                  0x000000FF\n#define FLASH_FSM_PE_VSU_ERA_VSU_S                                           0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_CMP_VSU\n*\n******************************************************************************/\n/* Field: [15:12] ADD_EXZ\n*\n* [Configured by boot firmware]\n* Address to EXECUTEZ low setup time. This determines the flash clocks from\n* the row address change to the time EXECUTEZ goes low. All operations use\n* this value. */\n#define FLASH_FSM_CMP_VSU_ADD_EXZ_M                                 0x0000F000\n#define FLASH_FSM_CMP_VSU_ADD_EXZ_S                                         12\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_EX_VAL\n*\n******************************************************************************/\n/* Field:  [15:8] REP_VSU\n*\n* [Configured by boot firmware]\n* Repeat Verify action setup. If a program or erase operation advances to the\n* program_verify or erase_verify then this special shorter mode transition\n* time will be used in place of FSM_PE_VSU.PGM_VSU or FSM_PE_VSU.ERA_VSU\n* times. */\n#define FLASH_FSM_EX_VAL_REP_VSU_M                                  0x0000FF00\n#define FLASH_FSM_EX_VAL_REP_VSU_S                                           8\n\n/* Field:   [7:0] EXE_VALD\n*\n* [Configured by boot firmware]\n* EXECUTEZ low to valid Data. Determines the number of Flash clock cycles from\n* EXECUTEZ going low to the time the verify data can be read in the program\n* verify mode. Erase and compact verify is always a constant value which is\n* currently set at one flash clock. This value must be greater than 0. */\n#define FLASH_FSM_EX_VAL_EXE_VALD_M                                 0x000000FF\n#define FLASH_FSM_EX_VAL_EXE_VALD_S                                          0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_RD_H\n*\n******************************************************************************/\n/* Field:   [7:0] RD_H\n*\n* [Configured by boot firmware]\n* Read mode hold. This determines the number of flash clocks from the start of\n* the Read mode at the end of the operations until the FSM clears the\n* FMSTAT.BUSY. Writing a zero to this register will result in a value of 1.\n* The reset value of this register is 0x3Ah before FMC version 3.0.10.0 and\n* 0x5Ah after this version. */\n#define FLASH_FSM_RD_H_RD_H_M                                       0x000000FF\n#define FLASH_FSM_RD_H_RD_H_S                                                0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_P_OH\n*\n******************************************************************************/\n/* Field:  [15:8] PGM_OH\n*\n* [Configured by boot firmware]\n* EXECUTEZ high to mode change. This value determines the flash clocks from\n* the EXECUTEZ going high at the end of a program operation to the time the\n* mode can change. This value must be greater than or equal to one. */\n#define FLASH_FSM_P_OH_PGM_OH_M                                     0x0000FF00\n#define FLASH_FSM_P_OH_PGM_OH_S                                              8\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_ERA_OH\n*\n******************************************************************************/\n/* Field:  [15:0] ERA_OH\n*\n* [Configured by boot firmware]\n* EXECUTEZ high to mode change. Determines the flash clocks from EXECUTEZ\n* going high at the end of an erase operation to the time the mode can change.\n* If a bank erase is happening, then this is the time to when the TEZ and TCR\n* values for bank erase are released. The mode changes 10 flash clocks after\n* they are released. This value must be greater than or equal to one. */\n#define FLASH_FSM_ERA_OH_ERA_OH_M                                   0x0000FFFF\n#define FLASH_FSM_ERA_OH_ERA_OH_S                                            0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_PE_VH\n*\n******************************************************************************/\n/* Field:  [15:8] PGM_VH\n*\n* [Configured by boot firmware]\n* Program Verify Hold. This register determines the flash clocks from EXECUTEZ\n* going high after a program verify to a mode change. This value must be\n* greater than or equal to one */\n#define FLASH_FSM_PE_VH_PGM_VH_M                                    0x0000FF00\n#define FLASH_FSM_PE_VH_PGM_VH_S                                             8\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_PRG_PW\n*\n******************************************************************************/\n/* Field:  [15:0] PROG_PUL_WIDTH\n*\n* [Configured by boot firmware]\n* Program Pulse width.This register gives the number of flash clocks that the\n* EXECUTEZ signal is low in a program operation. */\n#define FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_M                           0x0000FFFF\n#define FLASH_FSM_PRG_PW_PROG_PUL_WIDTH_S                                    0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_ERA_PW\n*\n******************************************************************************/\n/* Field:  [31:0] FSM_ERA_PW\n*\n* [Configured by boot firmware]\n* Erase Pulse width. This register gives the number flash clocks that the\n* EXECUTEZ signal is low in an erase operation. */\n#define FLASH_FSM_ERA_PW_FSM_ERA_PW_M                               0xFFFFFFFF\n#define FLASH_FSM_ERA_PW_FSM_ERA_PW_S                                        0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_PRG_PUL\n*\n******************************************************************************/\n/* Field: [19:16] BEG_EC_LEVEL\n*\n* [Configured by boot firmware]\n* Beginning level for VHVCT. This determines the beginning level for VHVCT\n* that is used during erase modes. The pump voltage control registers supply\n* the other values that do not change during FSM operations. The reset value\n* is the same as FVHVCT1.VHVCT_E. */\n#define FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_M                            0x000F0000\n#define FLASH_FSM_PRG_PUL_BEG_EC_LEVEL_S                                    16\n\n/* Field:  [11:0] MAX_PRG_PUL\n*\n* [Configured by boot firmware]\n* Maximum Programming Pulses. This register contains the maximum number of\n* programming pulses allowed at one address. If it takes any more than this\n* amount during a programming operation then the FSM will exit with an error\n* and with the program violation, FMSTAT.PGV set, and the general error set,\n* FMSTAT.CSTAT. Setting FSM_ST_MACHINE.OVERRIDE to 0 will allow more than this\n* maximum value to occur without an error. During pre-conditioning for an\n* erase operation the FSM programs all the bits to zero. If the maximum number\n* of programming pulses is reached for an address, the FSM will continue with\n* the next address and set the FMSTAT.PCV and the general error FMSTAT.CSTAT.\n* If the FSM_ST_MACHINE.PREC_STOP_EN is set then the FSM will stop with errors\n* when more than the maximum number of pulses is needed. The\n* FSM_ST_MACHINE.OVERRIDE bit will take priority over the\n* FSM_ST_MACHINE.PREC_STOP_EN and continue doing pulses without setting the\n* error bits. Suspend operations will count a pulse if the program operation\n* began no matter how long the pulse lasted before is was suspended. Frequent\n* suspend or auto-suspend operations could result in max_pulse count error. */\n#define FLASH_FSM_PRG_PUL_MAX_PRG_PUL_M                             0x00000FFF\n#define FLASH_FSM_PRG_PUL_MAX_PRG_PUL_S                                      0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_ERA_PUL\n*\n******************************************************************************/\n/* Field: [19:16] MAX_EC_LEVEL\n*\n* [Configured by boot firmware]\n* Maximum VHVCT Level. This determines the maximum level for VHVCT that is\n* used during erase modes. The FSM will stop advancing VHVCT once it counts up\n* to the MAX_EC_LEVEL level from the beginning level. The MAX_EC_LEVEL +\n* FSM_EC_STEP_HEIGHT.EC_STEP_HEIGHT must be less than 0x200. The reset value\n* is the same as FVHVCT1.VHVCT_E. */\n#define FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_M                            0x000F0000\n#define FLASH_FSM_ERA_PUL_MAX_EC_LEVEL_S                                    16\n\n/* Field:  [11:0] MAX_ERA_PUL\n*\n* [Configured by boot firmware]\n* Maximum Erase Pulses. This register contains the maximum number of erase\n* pulses allowed at one address. If it takes any more than this amount the FSM\n* will exit with an error and with both the FMSTAT.EV and FMSTAT.CSTAT bits\n* set. Setting FSM_ST_MACHINE.OVERRIDE to 1 will allow more than this maximum\n* value to occur without an error. Suspend operations will count a pulse if\n* the erase operation began no matter how long the pulse lasted before is was\n* suspended. Frequent suspend or auto-suspend operations could result in\n* max_pulse count error. */\n#define FLASH_FSM_ERA_PUL_MAX_ERA_PUL_M                             0x00000FFF\n#define FLASH_FSM_ERA_PUL_MAX_ERA_PUL_S                                      0\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_STEP_SIZE\n*\n******************************************************************************/\n/* Field: [24:16] EC_STEP_SIZE\n*\n* [Configured by boot firmware]\n* VHVCT Step Size. This is the number of erase pulses that must be completed\n* for each level before the FSM increments the FSM_PUL_CNTR.CUR_EC_LEVEL to\n* the next higher level. Actual erase pulses per level equals (EC_STEP_SIZE\n* +1). The stepping is only needed for the VHVCT voltage. */\n#define FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_M                          0x01FF0000\n#define FLASH_FSM_STEP_SIZE_EC_STEP_SIZE_S                                  16\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_EC_STEP_HEIGHT\n*\n******************************************************************************/\n/* Field:   [3:0] EC_STEP_HEIGHT\n*\n* [Configured by boot firmware]\n* Height of each EC step. This is the number of counts that the\n* FSM_PUL_CNTR.CUR_EC_LEVEL will increment when going to a new level. Actual\n* count size equals (EC_STEP_HEIGHT + 1). The stepping applies only to the\n* VHVCT voltage. If adding the height to the FSM_PUL_CNTR.CUR_EC_LEVEL results\n* in a value higher than the FSM_ERA_PUL.MAX_EC_LEVEL then the\n* FSM_PUL_CNTR.CUR_EC_LEVEL will be lowered to the MAX LEVEL before it is used\n* in the next erase pulse. */\n#define FLASH_FSM_EC_STEP_HEIGHT_EC_STEP_HEIGHT_M                   0x0000000F\n\n/******************************************************************************\n*\n* Register: FLASH_O_FSM_ST_MACHINE\n*\n******************************************************************************/\n/* Field:    [23] DO_PRECOND\n*\n* [Configured by boot firmware]\n* Do preconditioning. When this bit is a one, the FSM will precondition the\n* sector or bank before doing an erase operation. When zero, the FSM will just\n* begin with the erase verify and skip the preconditioning. */\n#define FLASH_FSM_ST_MACHINE_DO_PRECOND                             0x00800000\n#define FLASH_FSM_ST_MACHINE_DO_PRECOND_M                           0x00800000\n#define FLASH_FSM_ST_MACHINE_DO_PRECOND_S                                   23\n\n/* Field:    [14] ONE_TIME_GOOD\n*\n* [Configured by boot firmware]\n* One Time Good function. If this bit is a one then the 'One Time Good'\n* function is enabled for all program operations. This includes operations\n* inside the erase functions and other functions. When zero, this function is\n* disabled for all modes. When doing the One Time Good function, the FSM will\n* attempt to program a location with data. If a desired zero bit reads back\n* from the flash one time as good then that bit is blocked from writing a zero\n* to the flash array again for this address. When the address changes, all\n* bits are unblocked. This prevents a bit from reading 0 in one programming\n* pulse and then 1 in the next programming pulse. On the second time the bit\n* would get a programming pulse even though it read 0 in an earlier read. If\n* this bit is a zero then the zero bits will be masked for each program verify\n* operation. It is recommended for this bit to be set to 1. */\n#define FLASH_FSM_ST_MACHINE_ONE_TIME_GOOD                          0x00004000\n\n/******************************************************************************\n*\n* Register: FLASH_O_FCFG_B0_SSIZE0\n*\n******************************************************************************/\n/* Field:   [3:0] B0_SECT_SIZE\n*\n* Size of sectors in Bank 0. Common sector size for all sectors in the bank in\n* 1K bytes multiples.\n* 0x0: 0K bytes\n* 0x1: 1K bytes(FLES)\n* 0x2: 2K bytes\n* 0x4: 4K bytes (FLEE)\n* ...\n* 0xF: 15K bytes */\n#define FLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_M                         0x0000000F\n#define FLASH_FCFG_B0_SSIZE0_B0_SECT_SIZE_S                                  0\n\n/******************************************************************************\n*\n* This section defines the register offsets of FCFG1 component\n*\n******************************************************************************/\n\n/* Flash Erase and Program Setup Time */\n#define FCFG1_O_FLASH_E_P                                           0x00000170\n\n/* Flash Compaction, Execute, Program and Read */\n#define FCFG1_O_FLASH_C_E_P_R                                       0x00000174\n\n/* Flash Program, Read, and Program Verify */\n#define FCFG1_O_FLASH_P_R_PV                                        0x00000178\n\n/* Flash Erase Hold and Sequence */\n#define FCFG1_O_FLASH_EH_SEQ                                        0x0000017C\n\n/* Flash VHV Erase */\n#define FCFG1_O_FLASH_VHV_E                                         0x00000180\n\n/* Flash Program Pulse */\n#define FCFG1_O_FLASH_PP                                            0x00000184\n\n/* Flash Program and Erase Pulse */\n#define FCFG1_O_FLASH_PROG_EP                                       0x00000188\n\n/* Flash Erase Pulse Width */\n#define FCFG1_O_FLASH_ERA_PW                                        0x0000018C\n\n/* Flash VHV */\n#define FCFG1_O_FLASH_VHV                                           0x00000190\n\n/* Flash VHV Program Verify */\n#define FCFG1_O_FLASH_VHV_PV                                        0x00000194\n\n/* Flash Voltages */\n#define FCFG1_O_FLASH_V                                             0x00000198\n\n/* Flash OTP Data 3 */\n#define FCFG1_O_FLASH_OTP_DATA3                                     0x000002B0\n\n/* Flash OTP Data 4 */\n#define FCFG1_O_FLASH_OTP_DATA4                                     0x00000308\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_E_P\n*\n******************************************************************************/\n/* Field: [31:24] PSU\n*\n* Program setup time in cycles. Value will be written to\n* FLASH:FSM_PE_OSU.PGM_OSU by the flash device driver when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_E_P_PSU_M                                       0xFF000000\n#define FCFG1_FLASH_E_P_PSU_S                                               24\n\n/* Field: [23:16] ESU\n*\n* Erase setup time in cycles. Value will be written to\n* FLASH:FSM_PE_OSU.ERA_OSU by the flash device driver when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_E_P_ESU_M                                       0x00FF0000\n#define FCFG1_FLASH_E_P_ESU_S                                               16\n\n/* Field:  [15:8] PVSU\n*\n* Program verify setup time in cycles. Value will be written to\n* FLASH:FSM_PE_VSU.PGM_VSU by the flash device driver when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_E_P_PVSU_M                                      0x0000FF00\n#define FCFG1_FLASH_E_P_PVSU_S                                               8\n\n/* Field:   [7:0] EVSU\n*\n* Erase verify setup time in cycles. Value will be written to\n* FLASH:FSM_PE_VSU.ERA_VSU by the flash device driver when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_E_P_EVSU_M                                      0x000000FF\n#define FCFG1_FLASH_E_P_EVSU_S                                               0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_C_E_P_R\n*\n******************************************************************************/\n/* Field: [31:24] RVSU\n*\n* Repeat verify setup time in cycles. Used for repeated verifies during\n* program and erase. Value will be written to FLASH:FSM_EX_VAL.REP_VSU by the\n* flash device driver when an erase/program operation is initiated. */\n#define FCFG1_FLASH_C_E_P_R_RVSU_M                                  0xFF000000\n#define FCFG1_FLASH_C_E_P_R_RVSU_S                                          24\n\n/* Field: [23:16] PV_ACCESS\n*\n* Program verify EXECUTEZ-&#62;data valid time in half-microseconds. Value\n* will be converted to number of FCLK cycles by by flash device driver and the\n* converted value is written to FLASH:FSM_EX_VAL.EXE_VALD when an\n* erase/program operation is initiated. */\n#define FCFG1_FLASH_C_E_P_R_PV_ACCESS_M                             0x00FF0000\n#define FCFG1_FLASH_C_E_P_R_PV_ACCESS_S                                     16\n\n/* Field: [15:12] A_EXEZ_SETUP\n*\n* Address-&#62;EXECUTEZ setup time in cycles. Value will be written to\n* FLASH:FSM_CMP_VSU.ADD_EXZ by the flash device driver when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_M                          0x0000F000\n#define FCFG1_FLASH_C_E_P_R_A_EXEZ_SETUP_S                                  12\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_P_R_PV\n*\n******************************************************************************/\n/* Field: [31:24] PH\n*\n* Program hold time in half-microseconds after SAFELV goes high. Value will be\n* converted to number of FCLK cycles by the flash device driver and the\n* converted value is written to FLASH:FSM_P_OH.PGM_OH when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_P_R_PV_PH_M                                     0xFF000000\n#define FCFG1_FLASH_P_R_PV_PH_S                                             24\n\n/* Field: [23:16] RH\n*\n* Read hold/mode transition time in cycles. Value will be written to the RD_H\n* field bits[7:0] of the FSM_RD_H register in the flash module by the flash\n* device driver when an erase/program operation is initiated. */\n#define FCFG1_FLASH_P_R_PV_RH_M                                     0x00FF0000\n#define FCFG1_FLASH_P_R_PV_RH_S                                             16\n\n/* Field:  [15:8] PVH\n*\n* Program verify hold time in half-microseconds after SAFELV goes high. Value\n* will be converted to number of FCLK cycles by the flash device driver and\n* the converted value is written to FLASH:FSM_PE_VH.PGM_VH when an\n* erase/program operation is initiated. */\n#define FCFG1_FLASH_P_R_PV_PVH_M                                    0x0000FF00\n#define FCFG1_FLASH_P_R_PV_PVH_S                                             8\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_EH_SEQ\n*\n******************************************************************************/\n/* Field: [31:24] EH\n*\n* Erase hold time in half-microseconds after SAFELV goes high. Value will be\n* converted to number of FCLK cycles by the flash device driver and the\n* converted value is written to FLASH:FSM_ERA_OH.ERA_OH when an erase/program\n* operation is initiated. */\n#define FCFG1_FLASH_EH_SEQ_EH_M                                     0xFF000000\n#define FCFG1_FLASH_EH_SEQ_EH_S                                             24\n\n/* Field: [15:12] VSTAT\n*\n* Max number of HCLK cycles allowed for pump brown-out. Value will be written\n* to FLASH:FSM_VSTAT.VSTAT_CNT when an erase/program operation is initiated. */\n#define FCFG1_FLASH_EH_SEQ_VSTAT_M                                  0x0000F000\n#define FCFG1_FLASH_EH_SEQ_VSTAT_S                                          12\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_VHV_E\n*\n******************************************************************************/\n/* Field: [31:16] VHV_E_START\n*\n* Starting VHV-Erase CT for stairstep erase. Value will be written to\n* FLASH:FSM_PRG_PUL.BEG_EC_LEVEL when erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_E_VHV_E_START_M                             0xFFFF0000\n#define FCFG1_FLASH_VHV_E_VHV_E_START_S                                     16\n\n/* Field:  [15:0] VHV_E_STEP_HIGHT\n*\n* Number of VHV CTs to step after each erase pulse (up to the max). The actual\n* FMC register value should be one less than this since the FMC starts\n* counting from zero. Value will be written to\n* FLASH:FSM_EC_STEP_HEIGHT.EC_STEP_HEIGHT when an erase/program operation is\n* initiated. */\n#define FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_M                        0x0000FFFF\n#define FCFG1_FLASH_VHV_E_VHV_E_STEP_HIGHT_S                                 0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_PP\n*\n******************************************************************************/\n/* Field:  [15:0] MAX_PP\n*\n* Max program pulse limit per program operation. Value will be written to\n* FLASH:FSM_PRG_PUL.MAX_PRG_PUL when an erase/program operation is initiated. */\n#define FCFG1_FLASH_PP_MAX_PP_M                                     0x0000FFFF\n#define FCFG1_FLASH_PP_MAX_PP_S                                              0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_PROG_EP\n*\n******************************************************************************/\n/* Field: [31:16] MAX_EP\n*\n* Max erase pulse limit per erase operation. Value will be written to\n* FLASH:FSM_ERA_PUL.MAX_ERA_PUL when an erase/program operation is initiated. */\n#define FCFG1_FLASH_PROG_EP_MAX_EP_M                                0xFFFF0000\n#define FCFG1_FLASH_PROG_EP_MAX_EP_S                                        16\n\n/* Field:  [15:0] PROGRAM_PW\n*\n* Program pulse width in half-microseconds. Value will be converted to number\n* of FCLK cycles by the flash device driver and the converted value is written\n* to FLASH:FSM_PRG_PW.PROG_PUL_WIDTH when a erase/program operation is\n* initiated. */\n#define FCFG1_FLASH_PROG_EP_PROGRAM_PW_M                            0x0000FFFF\n#define FCFG1_FLASH_PROG_EP_PROGRAM_PW_S                                     0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_ERA_PW\n*\n******************************************************************************/\n/* Field:  [31:0] ERASE_PW\n*\n* Erase pulse width in half-microseconds. Value will be converted to number of\n* FCLK cycles by the flash device driver and the converted value is written to\n* FLASH:FSM_ERA_PW.FSM_ERA_PW when a erase/program operation is initiated. */\n#define FCFG1_FLASH_ERA_PW_ERASE_PW_M                               0xFFFFFFFF\n#define FCFG1_FLASH_ERA_PW_ERASE_PW_S                                        0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_VHV\n*\n******************************************************************************/\n/* Field: [27:24] TRIM13_P\n*\n* Value will be written to FLASH:FVHVCT2.TRIM13_P by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_TRIM13_P_M                                  0x0F000000\n#define FCFG1_FLASH_VHV_TRIM13_P_S                                          24\n\n/* Field: [19:16] VHV_P\n*\n* Value will be written to FLASH:FVHVCT2.VHVCT_P by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_VHV_P_M                                     0x000F0000\n#define FCFG1_FLASH_VHV_VHV_P_S                                             16\n\n/* Field:  [11:8] TRIM13_E\n*\n* Value will be written to FLASH:FVHVCT1.TRIM13_E by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_TRIM13_E_M                                  0x00000F00\n#define FCFG1_FLASH_VHV_TRIM13_E_S                                           8\n\n/* Field:   [3:0] VHV_E\n*\n* Value will be written to FLASH:FVHVCT1.VHVCT_E by the flash device driver\n* when an erase/program operation is initiated */\n#define FCFG1_FLASH_VHV_VHV_E_M                                     0x0000000F\n#define FCFG1_FLASH_VHV_VHV_E_S                                              0\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_VHV_PV\n*\n******************************************************************************/\n/* Field: [27:24] TRIM13_PV\n*\n* Value will be written to FLASH:FVHVCT1.TRIM13_PV by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_PV_TRIM13_PV_M                              0x0F000000\n#define FCFG1_FLASH_VHV_PV_TRIM13_PV_S                                      24\n\n/* Field: [19:16] VHV_PV\n*\n* Value will be written to FLASH:FVHVCT1.VHVCT_PV by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_PV_VHV_PV_M                                 0x000F0000\n#define FCFG1_FLASH_VHV_PV_VHV_PV_S                                         16\n\n/* Field:  [15:8] VCG2P5\n*\n* Control gate voltage during read, read margin, and erase verify. Value will\n* be written to FLASH:FVNVCT.VCG2P5CT by the flash device driver when an\n* erase/program operation is initiated. */\n#define FCFG1_FLASH_VHV_PV_VCG2P5_M                                 0x0000FF00\n#define FCFG1_FLASH_VHV_PV_VCG2P5_S                                          8\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_V\n*\n******************************************************************************/\n/* Field: [31:24] VSL_P\n*\n* Sourceline voltage applied to the selected block during programming. Value\n* will be written to FLASH:FVSLP.VSL_P by the flash device driver when an\n* erase/program operation is initiated. */\n#define FCFG1_FLASH_V_VSL_P_M                                       0xFF000000\n#define FCFG1_FLASH_V_VSL_P_S                                               24\n\n/* Field: [23:16] VWL_P\n*\n* Wordline voltage applied to the selected half-row during programming. Value\n* will be written to  FLASH:FVWLCT.VWLCT_P by the flash device driver when an\n* erase/program operation is initiated. */\n#define FCFG1_FLASH_V_VWL_P_M                                       0x00FF0000\n#define FCFG1_FLASH_V_VWL_P_S                                               16\n\n/* Field:  [15:8] V_READ\n*\n* Wordline voltage applied to the selected block during reads and verifies.\n* Value will be written to FLASH:FVREADCT.VREADCT by the flash device driver\n* when an erase/program operation is initiated. */\n#define FCFG1_FLASH_V_V_READ_M                                      0x0000FF00\n#define FCFG1_FLASH_V_V_READ_S                                               8\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_OTP_DATA3\n*\n******************************************************************************/\n/* Field: [31:23] EC_STEP_SIZE\n*\n* Value will be written to FLASH:FSM_STEP_SIZE.EC_STEP_SIZE by the flash\n* device driver when a erase/program operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_M                        0xFF800000\n#define FCFG1_FLASH_OTP_DATA3_EC_STEP_SIZE_S                                23\n\n/* Field:    [22] DO_PRECOND\n*\n* Value will be written to FLASH:FSM_ST_MACHINE.DO_PRECOND by the flash device\n* driver when a erase/program operation is initiated.\n*\n* Note that during a Total Erase operation the flash bank will always be\n* erased with Precondition enabled independent of the value of this FCFG1 bit\n* field. */\n#define FCFG1_FLASH_OTP_DATA3_DO_PRECOND_M                          0x00400000\n#define FCFG1_FLASH_OTP_DATA3_DO_PRECOND_S                                  22\n\n/* Field: [21:18] MAX_EC_LEVEL\n*\n* Value will be written to FLASH:FSM_ERA_PUL.MAX_EC_LEVEL by the flash device\n* driver when a erase/program operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_M                        0x003C0000\n#define FCFG1_FLASH_OTP_DATA3_MAX_EC_LEVEL_S                                18\n\n/* Field: [17:16] TRIM_1P7\n*\n* Value will be written to FLASH:FSEQPMP.TRIM_1P7 by the flash device driver\n* when a erase/program operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA3_TRIM_1P7_M                            0x00030000\n#define FCFG1_FLASH_OTP_DATA3_TRIM_1P7_S                                    16\n\n/******************************************************************************\n*\n* Register: FCFG1_O_FLASH_OTP_DATA4\n*\n******************************************************************************/\n/* Field:    [31] STANDBY_MODE_SEL_INT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.STANDBY_MODE_SEL by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_M            0x80000000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_WRT_S                    31\n\n/* Field: [30:29] STANDBY_PW_SEL_INT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.STANDBY_PW_SEL by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_M              0x60000000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_WRT_S                      29\n\n/* Field:    [28] DIS_STANDBY_INT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.DIS_STANDBY by flash device driver FW when a flash write operation\n* is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_WRT_M                 0x10000000\n\n/* Field:    [27] DIS_IDLE_INT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.DIS_IDLE by flash device driver FW when a flash write operation is\n* initiated. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_M                    0x08000000\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_WRT_S                            27\n\n/* Field: [26:24] VIN_AT_X_INT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:FSEQPMP.VIN_AT_X by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_M                    0x07000000\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_WRT_S                            24\n\n/* Field:    [23] STANDBY_MODE_SEL_EXT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.STANDBY_MODE_SEL by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_M            0x00800000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_WRT_S                    23\n\n/* Field: [22:21] STANDBY_PW_SEL_EXT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.STANDBY_PW_SEL by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_M              0x00600000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_WRT_S                      21\n\n/* Field:    [20] DIS_STANDBY_EXT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.DIS_STANDBY by flash device driver FW when a flash write operation\n* is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_WRT_M                 0x00100000\n\n/* Field:    [19] DIS_IDLE_EXT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.DIS_IDLE by flash device driver FW when a flash write operation is\n* initiated. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_M                    0x00080000\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_WRT_S                            19\n\n/* Field: [18:16] VIN_AT_X_EXT_WRT\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:FSEQPMP.VIN_AT_X by flash device driver FW when a flash write\n* operation is initiated. */\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_M                    0x00070000\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_WRT_S                            16\n\n/* Field:    [15] STANDBY_MODE_SEL_INT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.STANDBY_MODE_SEL both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_M             0x00008000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_INT_RD_S                     15\n\n/* Field: [14:13] STANDBY_PW_SEL_INT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.STANDBY_PW_SEL both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_M               0x00006000\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_INT_RD_S                       13\n\n/* Field:    [12] DIS_STANDBY_INT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.DIS_STANDBY both by boot FW while in safezone, and by flash device\n* driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_INT_RD_M                  0x00001000\n\n/* Field:    [11] DIS_IDLE_INT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:CFG.DIS_IDLE both by boot FW while in safezone, and by flash device\n* driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_M                     0x00000800\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_INT_RD_S                             11\n\n/* Field:  [10:8] VIN_AT_X_INT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 0, this value will be written to\n* FLASH:FSEQPMP.VIN_AT_X both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_M                     0x00000700\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_INT_RD_S                              8\n\n/* Field:     [7] STANDBY_MODE_SEL_EXT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.STANDBY_MODE_SEL both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_M             0x00000080\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_MODE_SEL_EXT_RD_S                      7\n\n/* Field:   [6:5] STANDBY_PW_SEL_EXT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.STANDBY_PW_SEL both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_M               0x00000060\n#define FCFG1_FLASH_OTP_DATA4_STANDBY_PW_SEL_EXT_RD_S                        5\n\n/* Field:     [4] DIS_STANDBY_EXT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.DIS_STANDBY both by boot FW while in safezone, and by flash device\n* driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_STANDBY_EXT_RD_M                  0x00000010\n\n/* Field:     [3] DIS_IDLE_EXT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:CFG.DIS_IDLE both by boot FW while in safezone, and by flash device\n* driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_M                     0x00000008\n#define FCFG1_FLASH_OTP_DATA4_DIS_IDLE_EXT_RD_S                              3\n\n/* Field:   [2:0] VIN_AT_X_EXT_RD\n*\n* If AON_PMCTL:PWRCTL.EXT_REG_MODE = 1, this value will be written to\n* FLASH:FSEQPMP.VIN_AT_X both by boot FW while in safezone, and by flash\n* device driver FW after completion of a flash write operation. */\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_M                     0x00000007\n#define FCFG1_FLASH_OTP_DATA4_VIN_AT_X_EXT_RD_S                              0\n\n/******************************************************************************\n*\n* This section defines the register offsets of AON_PMCTL component\n*\n******************************************************************************/\n\n/* Power Management Control */\n#if defined(DEVICE_CC26X2)\n/* Agama (CC26x2) specific definition */\n#define AON_PMCTL_O_PWRCTL                                          0x00000010\n#elif defined(DEVICE_CC26X0)\n/* Chameleon (CC26x0) specific definition */\n#define AON_PMCTL_O_PWRCTL                                          0x00000000\n#endif\n\n/* Field:     [1] EXT_REG_MODE\n*\n* Status of source for VDDRsupply:\n*\n* 0: DCDC or GLDO are generating VDDR\n* 1: DCDC and GLDO are bypassed and an external regulator supplies VDDR */\n#define AON_PMCTL_PWRCTL_EXT_REG_MODE                               0x00000002\n\n#endif /* #ifndef OPENOCD_LOADERS_FLASH_CC26XX_HW_REGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/main.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"flashloader.h\"\n\n/* Data buffers used by host to communicate with flashloader */\n\n/* Flashloader parameter structure. */\n__attribute__ ((section(\".buffers.g_cfg\")))\nvolatile struct flash_params g_cfg[2];\n/* Data buffer 1. */\n__attribute__ ((section(\".buffers.g_buf1\")))\nuint8_t g_buf1[BUFFER_LEN];\n/* Data buffer 2. */\n__attribute__ ((section(\".buffers.g_buf2\")))\nuint8_t g_buf2[BUFFER_LEN];\n\n/* Buffer used for program with retain feature */\n__attribute__ ((section(\".buffers.g_retain_buf\")))\nuint8_t g_retain_buf[BUFFER_LEN];\n\nuint32_t g_curr_buf; /* Current buffer used. */\nuint32_t g_vims_ctl; /* Saved flash cache state. */\n\n/******************************************************************************\n*\n* This function stores the current VIMS configuration before\n* - disabling VIMS flash cache\n* - flushing the flash line buffers.\n*\n* Note Not using driverlib calls because it requires using \"NO_ROM\" define in\n*      order to work for both Cha. R1 and R2 using the same code. Manually\n*      doing the steps to minimize code footprint.\n*\n******************************************************************************/\nstatic void disable_flash_cache()\n{\n\t/* 1. Make sure VIMS is not currently changing mode (VIMS:STAT register) */\n\twhile ((HWREG(0x40034000) & 0x00000008) == 0x8)\n\t\t;\n\n\t/* Save current VIMS:CTL state */\n\tg_vims_ctl = HWREG(0x40034004);\n\n\t/* 2. Set VIMS mode to OFF and disable flash line buffers */\n\tuint32_t new_vims_ctl = g_vims_ctl | 0x33;\n\tHWREG(0x40034004) = new_vims_ctl;\n\n\t/* 3. Wait for VIMS to have changed mode (VIMS:STAT register) */\n\twhile ((HWREG(0x40034000) & 0x00000008) == 0x8)\n\t\t;\n}\n\n/******************************************************************************\n*\n* This function restores the VIMS configuration saved off by\n* disable_flash_cache().\n*\n* Note Not using driverlib calls because it requires using \"NO_ROM\" define in\n*      order to work for both Cha. R1 and R2 using the same code. Manually\n*      doing the steps to minimize code footprint.\n*\n******************************************************************************/\nstatic void restore_cache_state()\n{\n\tHWREG(0x40034004) = g_vims_ctl;\n\n\t/* Wait for VIMS to have changed mode (VIMS:STAT register) */\n\twhile ((HWREG(0x40034000) & 0x00000008) == 0x8)\n\t\t;\n}\n\n/******************************************************************************\n*\n* CC13xx/CC26xx flashloader main function.\n*\n******************************************************************************/\nint main(void)\n{\n\tflashloader_init((struct flash_params *)g_cfg, g_buf1, g_buf2);\n\n\tg_curr_buf = 0; /* start with the first buffer */\n\tuint32_t status;\n\n\twhile (1) {\n\t\t/* Wait for host to signal buffer is ready */\n\t\twhile (g_cfg[g_curr_buf].full == BUFFER_EMPTY)\n\t\t\t;\n\n\t\tdisable_flash_cache();\n\n\t\t/* Perform requested task */\n\t\tswitch (g_cfg[g_curr_buf].cmd) {\n\t\t\tcase CMD_ERASE_ALL:\n\t\t\t\tstatus = flashloader_erase_all();\n\t\t\t\tbreak;\n\t\t\tcase CMD_PROGRAM:\n\t\t\t\tstatus =\n\t\t\t\t\tflashloader_program(\n\t\t\t\t\t\t(uint8_t *)g_cfg[g_curr_buf].buf_addr,\n\t\t\t\t\t\tg_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);\n\t\t\t\tbreak;\n\t\t\tcase CMD_ERASE_AND_PROGRAM:\n\t\t\t\tstatus =\n\t\t\t\t\tflashloader_erase_and_program(\n\t\t\t\t\t\t(uint8_t *)g_cfg[g_curr_buf].buf_addr,\n\t\t\t\t\t\tg_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);\n\t\t\t\tbreak;\n\t\t\tcase CMD_ERASE_AND_PROGRAM_WITH_RETAIN:\n\t\t\t\tstatus =\n\t\t\t\t\tflashloader_program_with_retain(\n\t\t\t\t\t\t(uint8_t *)g_cfg[g_curr_buf].buf_addr,\n\t\t\t\t\t\tg_cfg[g_curr_buf].dest, g_cfg[g_curr_buf].len);\n\t\t\t\tbreak;\n\t\t\tcase CMD_ERASE_SECTORS:\n\t\t\t\tstatus =\n\t\t\t\t\tflashloader_erase_sectors(g_cfg[g_curr_buf].dest,\n\t\t\t\t\t\tg_cfg[g_curr_buf].len);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tstatus = STATUS_FAILED_UNKNOWN_COMMAND;\n\t\t\t\tbreak;\n\t\t}\n\n\t\trestore_cache_state();\n\n\t\t/* Enter infinite loop on error condition */\n\t\tif (status != STATUS_OK) {\n\t\t\tg_cfg[g_curr_buf].full = status;\n\t\t\twhile (1)\n\t\t\t\t;\n\t\t}\n\n\t\t/* Mark current task complete, and begin looking at next buffer */\n\t\tg_cfg[g_curr_buf].full = BUFFER_EMPTY;\n\t\tg_curr_buf ^= 1;\n\t}\n}\n\nvoid _exit(int status)\n{\n\t/* Enter infinite loop on hitting an exit condition */\n\t(void)status; /* Unused parameter */\n\twhile (1)\n\t\t;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc26xx/startup.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n\n/******************************************************************************\n*\n* The entry point for the application startup code.\n*\n******************************************************************************/\nextern int main(void);\n\n/******************************************************************************\n*\n* Reserve space for the system stack.\n*\n******************************************************************************/\n__attribute__ ((section(\".stack\")))\nstatic uint32_t stack[100];\nconst uint32_t stack_pntr = (uint32_t)stack + sizeof(stack);\n\n/******************************************************************************\n*\n* The following are constructs created by the linker indicating where\n* the \"bss\" and \"ebss\" segments reside in memory.\n*\n******************************************************************************/\nextern uint32_t _bss;\nextern uint32_t _ebss;\n\n/******************************************************************************\n*\n* This is the entry point that handles setting the stack within the allowed\n* workspace, initializing the .bss segment, and then jumping to main.\n*\n******************************************************************************/\n__attribute__ ((section(\".entry\")))\nvoid entry(void)\n{\n\t/* Workaround for ITT instructions. */\n\t__asm(\"\t\tNOP\");\n\t__asm(\"\t\tNOP\");\n\t__asm(\"\t\tNOP\");\n\t__asm(\"\t\tNOP\");\n\n\t/* Initialize stack pointer */\n\t__asm(\"\t\tldr\t\tsp, =stack_pntr\");\n\n\t/* Zero fill the bss segment. */\n\t__asm(\"\t\tldr     r0, =_bss\\n\"\n\t\t  \"\t\tldr     r1, =_ebss\\n\"\n\t\t  \"\t\tmov     r2, #0\\n\"\n\t\t  \"\t\t.thumb_func\\n\"\n\t\t  \"\tzero_loop:\\n\"\n\t\t  \"\t\tcmp\t\tr0, r1\\n\"\n\t\t  \"\t\tit\t\tlt\\n\"\n\t\t  \"\t\tstrlt\tr2, [r0], #4\\n\"\n\t\t  \"\t\tblt\t\tzero_loop\");\n\n\t/* Call the application's entry point. */\n\tmain();\n\n\t/* If we ever return, enter an infinite loop */\n\twhile (1)\n\t\t;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc3220sf/cc3220sf.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xdf,0xf8,0x7c,0xa0,0xdf,0xf8,0x7c,0xb0,0xdf,0xf8,0x7c,0xc0,0x01,0xf0,0x7f,0x03,\n0x00,0x2b,0x1e,0xd1,0x4f,0xf0,0x00,0x04,0xcc,0xf8,0x00,0x10,0x03,0x68,0xcb,0xf8,\n0x00,0x30,0x0b,0xf1,0x04,0x0b,0x00,0xf1,0x04,0x00,0xa2,0xf1,0x01,0x02,0x04,0xf1,\n0x01,0x04,0x01,0xf1,0x04,0x01,0x00,0x2a,0x01,0xd0,0x20,0x2c,0xee,0xd1,0xcc,0xf8,\n0x20,0xa0,0xdc,0xf8,0x20,0x30,0x13,0xf0,0x01,0x0f,0xfa,0xd1,0x00,0x2a,0xd7,0xd1,\n0x13,0xe0,0xcc,0xf8,0x00,0x10,0x03,0x68,0xcc,0xf8,0x04,0x30,0xcc,0xf8,0x08,0xa0,\n0xdc,0xf8,0x08,0x30,0x13,0xf0,0x01,0x0f,0xfa,0xd1,0xa2,0xf1,0x01,0x02,0x00,0xf1,\n0x04,0x00,0x01,0xf1,0x04,0x01,0x00,0x2a,0xc2,0xd1,0x00,0xbe,0x01,0xbe,0xfc,0xe7,\n0x01,0x00,0x42,0xa4,0x00,0xd1,0x0f,0x40,0x00,0xd0,0x0f,0x40,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cc3220sf/cc3220sf.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n\t/* Params:\n\t * r0 = buffer start address (in)\n\t * r1 = flash destination address (in)\n\t * r2 = number of words to write (in/out)\n\t */\n\n\t.text\n\t.cpu cortex-m4\n\t.code 16\n\t.thumb\n\t.syntax unified\n\n\t.align 2\n\n\t/* r3 = scratchpad\n\t * r4 = buffer word counter\n\t * r10 = flash programming key\n\t * r11 = base FWB address\n\t * r12 = base flash regs address\n\t */\n\nstart:\n\tldr \tr10, =0xa4420001\t/* flash programming key */\n\tldr \tr11, =0x400fd100\t/* base of FWB */\n\tldr \tr12, =0x400fd000\t/* base of flash regs */\n\tand \tr3, r1, #0x7f\t\t/* is the dest address 32 word aligned? */\n\tcmp \tr3, #0\n\tbne \tprogram_word\t\t/* if not aligned do one word at a time */\n\n\t/* program using the write buffers */\nprogram_buffer:\n\tmov \tr4, #0\t\t\t\t/* start the buffer word counter at 0 */\n\tstr \tr1, [r12]\t\t\t/* store the dest addr in FMA */\nfill_buffer:\n\tldr \tr3, [r0]\t\t\t/* get the word to write to FWB */\n\tstr \tr3, [r11]\t\t\t/* store the word in the FWB */\n\tadd \tr11, r11, #4\t\t/* increment the FWB pointer */\n\tadd \tr0, r0, #4\t\t\t/* increment the source pointer */\n\tsub \tr2, r2, #1\t\t\t/* decrement the total word counter */\n\tadd \tr4, r4, #1\t\t\t/* increment the buffer word counter */\n\tadd \tr1, r1, #4\t\t\t/* increment the dest pointer */\n\tcmp \tr2, #0\t\t\t\t/* is the total word counter now 0? */\n\tbeq \tbuffer_ready\t\t/* go to end if total word counter is 0 */\n\tcmp \tr4, #32\t\t\t\t/* is the buffer word counter now 32? */\n\tbne \tfill_buffer\t\t\t/* go to continue to fill buffer */\nbuffer_ready:\n\tstr \tr10, [r12, #0x20]\t/* store the key and write bit to FMC2 */\nwait_buffer_done:\n\tldr \tr3, [r12, #0x20]\t/* read FMC2 */\n\ttst \tr3, #1\t\t\t\t/* see if the write bit is cleared */\n\tbne \twait_buffer_done\t/* go to read FMC2 if bit not cleared */\n\tcmp \tr2, #0\t\t\t\t/* is the total word counter now 0? */\n\tbne \tstart\t\t\t\t/* go if there is more to program */\n\tb   \texit\n\n\t/* program just one word */\nprogram_word:\n\tstr \tr1, [r12]\t\t\t/* store the dest addr in FMA */\n\tldr \tr3, [r0]\t\t\t/* get the word to write to FMD */\n\tstr \tr3, [r12, #0x4]\t\t/* store the word in FMD */\n\tstr \tr10, [r12, #0x8]\t/* store the key and write bit to FMC */\nwait_word_done:\n\tldr \tr3, [r12, #0x8]\t\t/* read FMC */\n\ttst \tr3, #1\t\t\t\t/* see if the write bit is cleared */\n\tbne \twait_word_done\t\t/* go to read FMC if bit not cleared */\n\tsub \tr2, r2, #1\t\t\t/* decrement the total word counter */\n\tadd \tr0, r0, #4\t\t\t/* increment the source pointer */\n\tadd \tr1, r1, #4\t\t\t/* increment the dest pointer */\n\tcmp \tr2, #0\t\t\t\t/* is the total word counter now 0 */\n\tbne \tstart\t\t\t\t/* go if there is more to program */\n\n\t/* end */\nexit:\n\tbkpt\t#0\n\tbkpt\t#1\n\tb   \texit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/cortex-m0.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2014 by Angus Gratton                                   *\n *   Derived from stm32f1x.S:\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *   Copyright (C) 2013 by Roman Dmitrienko                                *\n *   me@iamroman.org                                                       *\n ***************************************************************************/\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Written for NRF51822 (src/flash/nor/nrf51.c) however the NRF NVMC is\n * very generic (CPU blocks during flash writes), so this is actually\n * just a generic word-oriented copy routine for Cortex-M0 (also\n * suitable for Cortex-M0+/M3/M4.)\n *\n * To assemble:\n * arm-none-eabi-gcc -c cortex-m0.S\n *\n * To disassemble:\n * arm-none-eabi-objdump -o cortex-m0.o\n *\n * Thanks to Jens Bauer for providing advice on some of the tweaks.\n */\n\n\t/* Params:\n\t * r0 - byte count (in)\n\t * r1 - workarea start\n\t * r2 - workarea end\n\t * r3 - target address\n\t * Clobbered:\n\t * r4 - rp\n\t * r5 - wp, tmp\n\t */\n\nwait_fifo:\n\tldr \tr5, [r1, #0]\t/* read wp */\n\tcmp \tr5, #0\t        /* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr4, [r1, #4]\t/* read rp */\n\tcmp \tr4, r5\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\n\tldmia\tr4!, {r5}\t/* \"*target_address++ = *rp++\" */\n        stmia   r3!, {r5}\n\n        cmp \tr4, r2\t\t/* wrap rp at end of work area buffer */\n\tbcc\tno_wrap\n\tmov\tr4, r1\n\tadds\tr4, #8          /* skip rp,wp at start of work area */\nno_wrap:\n\tstr \tr4, [r1, #4]\t/* write back rp */\n\tsubs\tr0, #4          /* decrement byte count */\n\tbne     wait_fifo\t/* loop if not done */\nexit:\n\tbkpt    #0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/efm32.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *   Copyright (C) 2013 by Roman Dmitrienko                                *\n *   me@iamroman.org                                                       *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n\t/* Params:\n\t * r0 - flash base (in), status (out)\n\t * r1 - count (word-32bit)\n\t * r2 - workarea start\n\t * r3 - workarea end\n\t * r4 - target address\n\t * Clobbered:\n\t * r5 - rp\n\t * r6 - wp, tmp\n\t * r7 - tmp\n\t */\n\n/* offsets of registers from flash reg base */\n#define EFM32_MSC_WRITECTRL_OFFSET      0x008\n#define EFM32_MSC_WRITECMD_OFFSET       0x00c\n#define EFM32_MSC_ADDRB_OFFSET          0x010\n#define EFM32_MSC_WDATA_OFFSET          0x018\n#define EFM32_MSC_STATUS_OFFSET         0x01c\n\n\t/* set WREN to 1 */\n\tmovs    r6, #1\n\tstr     r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET]\n\nwait_fifo:\n\tldr     r6, [r2, #0]    /* read wp */\n\tcmp     r6, #0          /* abort if wp == 0 */\n\tbeq     exit\n\tldr     r5, [r2, #4]    /* read rp */\n\tcmp     r5, r6          /* wait until rp != wp */\n\tbeq     wait_fifo\n\n\t/* store address in MSC_ADDRB */\n\tstr     r4, [r0, #EFM32_MSC_ADDRB_OFFSET]\n\t/* set LADDRIM bit */\n\tmovs    r6, #1\n\tstr     r6, [r0, #EFM32_MSC_WRITECMD_OFFSET]\n\t/* check status for INVADDR and/or LOCKED */\n\tldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET]\n\tmovs    r7, #6\n\ttst     r6, r7\n\tbne     error\n\n\t/* wait for WDATAREADY */\nwait_wdataready:\n\tldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET]\n\tmovs    r7, #8\n\ttst     r6, r7\n\tbeq     wait_wdataready\n\n\t/* load data to WDATA */\n\tldr     r6, [r5]\n\tstr     r6, [r0, #EFM32_MSC_WDATA_OFFSET]\n\t/* set WRITEONCE bit */\n\tmovs    r6, #8\n\tstr     r6, [r0, #EFM32_MSC_WRITECMD_OFFSET]\n\n\tadds    r5, #4          /* rp++ */\n\tadds    r4, #4          /* target_address++ */\n\n\t/* wait until BUSY flag is reset */\nbusy:\n\tldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET]\n\tmovs    r7, #1\n\ttst     r6, r7\n\tbne     busy\n\n\tcmp     r5, r3          /* wrap rp at end of buffer */\n\tbcc     no_wrap\n\tmov     r5, r2\n\tadds    r5, #8\nno_wrap:\n\tstr     r5, [r2, #4]    /* store rp */\n\tsubs    r1, r1, #1      /* decrement word count */\n\tcmp     r1, #0\n\tbeq     exit            /* loop if not done */\n\tb       wait_fifo\nerror:\n\tmovs    r0, #0\n\tstr     r0, [r2, #4]    /* set rp = 0 on error */\nexit:\n\tmov     r0, r6          /* return status in r0 */\n\tbkpt    #0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fespi/riscv.lds",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\nOUTPUT_ARCH( \"riscv\" )\n\nSECTIONS\n{\n  . = 0x12340000;\n  .text :\n  {\n    *(.text.entry)\n    *(.text)\n  }\n  .data : { *(.data) }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fespi/riscv32_fespi.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x17,0x01,0x00,0x00,0x13,0x01,0xc1,0x31,0xef,0x00,0x80,0x10,0x73,0x00,0x10,0x00,\n0x93,0x07,0x90,0x3e,0x93,0x87,0xf7,0xff,0x63,0x96,0x07,0x00,0x13,0x05,0x10,0x00,\n0x67,0x80,0x00,0x00,0x03,0x27,0x45,0x07,0x13,0x77,0x17,0x00,0xe3,0x04,0x07,0xfe,\n0x13,0x05,0x00,0x00,0x67,0x80,0x00,0x00,0x93,0x07,0x90,0x3e,0x93,0x87,0xf7,0xff,\n0x63,0x96,0x07,0x00,0x13,0x05,0x10,0x00,0x67,0x80,0x00,0x00,0x03,0x27,0x85,0x04,\n0xe3,0x46,0x07,0xfe,0x23,0x24,0xb5,0x04,0x13,0x05,0x00,0x00,0x67,0x80,0x00,0x00,\n0x83,0x27,0x05,0x04,0x13,0x01,0x41,0xff,0x23,0x22,0x81,0x00,0x23,0x24,0x11,0x00,\n0x23,0x20,0x91,0x00,0x93,0xf7,0x77,0xff,0x23,0x20,0xf5,0x04,0x93,0x07,0x20,0x00,\n0x23,0x2c,0xf5,0x00,0x93,0x05,0x50,0x00,0x13,0x04,0x05,0x00,0xef,0xf0,0xdf,0xfa,\n0x93,0x07,0x90,0x3e,0x63,0x00,0x05,0x02,0x83,0x20,0x81,0x00,0x03,0x24,0x41,0x00,\n0x83,0x24,0x01,0x00,0x13,0x01,0xc1,0x00,0x67,0x80,0x00,0x00,0x03,0x27,0xc4,0x04,\n0x63,0x5a,0x07,0x00,0x93,0x87,0xf7,0xff,0xe3,0x9a,0x07,0xfe,0x13,0x05,0x10,0x00,\n0x6f,0xf0,0x9f,0xfd,0x93,0x04,0x90,0x3e,0x93,0x84,0xf4,0xff,0xe3,0x88,0x04,0xfe,\n0x93,0x05,0x00,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0x1f,0xf6,0xe3,0x1e,0x05,0xfa,\n0x13,0x07,0x90,0x3e,0x13,0x07,0xf7,0xff,0xe3,0x0a,0x07,0xfc,0x83,0x27,0xc4,0x04,\n0xe3,0xca,0x07,0xfe,0x93,0xf7,0x17,0x00,0xe3,0x98,0x07,0xfc,0x23,0x2c,0x04,0x00,\n0x83,0x27,0x04,0x04,0x93,0xe7,0x87,0x00,0x23,0x20,0xf4,0x04,0x6f,0xf0,0xdf,0xf8,\n0x13,0x01,0x41,0xfd,0x23,0x22,0x81,0x02,0x23,0x20,0x91,0x02,0x23,0x24,0x11,0x02,\n0x13,0x04,0x05,0x00,0x23,0x26,0xb1,0x00,0x23,0x28,0xc1,0x00,0x23,0x20,0xd1,0x00,\n0x23,0x22,0xe1,0x00,0x23,0x2a,0xf1,0x00,0xef,0xf0,0x9f,0xed,0x93,0x04,0x05,0x00,\n0x63,0x16,0x05,0x04,0x83,0x27,0x04,0x06,0x13,0x05,0x04,0x00,0x93,0xf7,0xe7,0xff,\n0x23,0x20,0xf4,0x06,0xef,0xf0,0xdf,0xf0,0x93,0x04,0x05,0x00,0x63,0x12,0x05,0x02,\n0x83,0x27,0xc1,0x00,0x03,0x27,0x01,0x00,0x93,0x87,0xf7,0xff,0xb3,0xf7,0xe7,0x00,\n0x03,0x47,0x41,0x01,0x23,0x2c,0xe1,0x00,0x03,0x27,0x41,0x00,0x63,0x14,0x07,0x02,\n0x83,0x27,0x04,0x06,0x93,0xe7,0x17,0x00,0x23,0x20,0xf4,0x06,0x83,0x20,0x81,0x02,\n0x03,0x24,0x41,0x02,0x13,0x85,0x04,0x00,0x83,0x24,0x01,0x02,0x13,0x01,0xc1,0x02,\n0x67,0x80,0x00,0x00,0x83,0x26,0x41,0x00,0x03,0x27,0x41,0x00,0x23,0x24,0xd1,0x00,\n0x83,0x26,0xc1,0x00,0x33,0x07,0xf7,0x00,0x63,0xf6,0xe6,0x00,0xb3,0x87,0xf6,0x40,\n0x23,0x24,0xf1,0x00,0x93,0x05,0x60,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0xdf,0xe6,\n0x63,0x1e,0x05,0x0c,0x13,0x05,0x04,0x00,0xef,0xf0,0x9f,0xe3,0x63,0x18,0x05,0x0c,\n0x83,0x25,0x81,0x01,0x93,0x07,0x20,0x00,0x23,0x2c,0xf4,0x00,0x13,0x05,0x04,0x00,\n0xef,0xf0,0x9f,0xe4,0x63,0x1c,0x05,0x0a,0x83,0x27,0x41,0x01,0x93,0xf7,0x07,0x10,\n0x63,0x9c,0x07,0x08,0x83,0x27,0x01,0x00,0x13,0x05,0x04,0x00,0x93,0xd5,0x07,0x01,\n0x93,0xf5,0xf5,0x0f,0xef,0xf0,0x5f,0xe2,0x63,0x1a,0x05,0x08,0x83,0x27,0x01,0x00,\n0x13,0x05,0x04,0x00,0x93,0xd5,0x87,0x00,0x93,0xf5,0xf5,0x0f,0xef,0xf0,0xdf,0xe0,\n0x63,0x1e,0x05,0x06,0x83,0x45,0x01,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0xdf,0xdf,\n0x63,0x16,0x05,0x06,0x03,0x26,0x01,0x01,0x83,0x27,0x81,0x00,0xb3,0x07,0xf6,0x00,\n0x63,0x12,0xf6,0x06,0x13,0x05,0x04,0x00,0x23,0x28,0xc1,0x00,0xef,0xf0,0x5f,0xdb,\n0x63,0x16,0x05,0x04,0x23,0x2c,0x04,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0x5f,0xdf,\n0x63,0x1e,0x05,0x02,0x83,0x27,0x01,0x00,0x03,0x27,0x81,0x00,0xb3,0x87,0xe7,0x00,\n0x23,0x20,0xf1,0x00,0x83,0x27,0x41,0x00,0xb3,0x87,0xe7,0x40,0x23,0x22,0xf1,0x00,\n0x93,0x07,0x00,0x00,0x6f,0xf0,0x5f,0xee,0x83,0x27,0x01,0x00,0x13,0x05,0x04,0x00,\n0x93,0xd5,0x87,0x01,0xef,0xf0,0x5f,0xd9,0xe3,0x0e,0x05,0xf4,0x93,0x04,0x05,0x00,\n0x6f,0xf0,0x1f,0xed,0x83,0x45,0x06,0x00,0x13,0x05,0x04,0x00,0x23,0x2e,0xf1,0x00,\n0x23,0x28,0xc1,0x00,0xef,0xf0,0x5f,0xd7,0x03,0x26,0x01,0x01,0x83,0x27,0xc1,0x01,\n0x13,0x06,0x16,0x00,0xe3,0x0e,0x05,0xf6,0x6f,0xf0,0x5f,0xfd,0x09,0x53,0x67,0x08,\n0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,\n0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,\n0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,\n0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,0x09,0x53,0x67,0x08,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fespi/riscv64_fespi.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x17,0x01,0x00,0x00,0x13,0x01,0x81,0x38,0xef,0x00,0x40,0x12,0x73,0x00,0x10,0x00,\n0x93,0x07,0x90,0x3e,0x9b,0x87,0xf7,0xff,0x63,0x96,0x07,0x00,0x13,0x05,0x10,0x00,\n0x67,0x80,0x00,0x00,0x03,0x27,0x45,0x07,0x13,0x77,0x17,0x00,0xe3,0x04,0x07,0xfe,\n0x13,0x05,0x00,0x00,0x67,0x80,0x00,0x00,0x93,0x07,0x90,0x3e,0x9b,0x87,0xf7,0xff,\n0x63,0x96,0x07,0x00,0x13,0x05,0x10,0x00,0x67,0x80,0x00,0x00,0x03,0x27,0x85,0x04,\n0x93,0x16,0x07,0x02,0xe3,0xc4,0x06,0xfe,0x9b,0x85,0x05,0x00,0x23,0x24,0xb5,0x04,\n0x13,0x05,0x00,0x00,0x67,0x80,0x00,0x00,0x83,0x27,0x05,0x04,0x13,0x01,0x01,0xfe,\n0x23,0x38,0x81,0x00,0x9b,0x87,0x07,0x00,0x23,0x3c,0x11,0x00,0x23,0x34,0x91,0x00,\n0x93,0xf7,0x77,0xff,0x23,0x20,0xf5,0x04,0x93,0x07,0x20,0x00,0x23,0x2c,0xf5,0x00,\n0x93,0x05,0x50,0x00,0x13,0x04,0x05,0x00,0xef,0xf0,0x1f,0xfa,0x93,0x07,0x90,0x3e,\n0x63,0x02,0x05,0x02,0x83,0x30,0x81,0x01,0x03,0x34,0x01,0x01,0x83,0x34,0x81,0x00,\n0x13,0x01,0x01,0x02,0x67,0x80,0x00,0x00,0x03,0x27,0xc4,0x04,0x93,0x16,0x07,0x02,\n0x63,0xda,0x06,0x00,0x9b,0x87,0xf7,0xff,0xe3,0x98,0x07,0xfe,0x13,0x05,0x10,0x00,\n0x6f,0xf0,0x5f,0xfd,0x93,0x04,0x90,0x3e,0x9b,0x84,0xf4,0xff,0xe3,0x88,0x04,0xfe,\n0x93,0x05,0x00,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0x1f,0xf5,0xe3,0x1c,0x05,0xfa,\n0x93,0x07,0x90,0x3e,0x9b,0x87,0xf7,0xff,0xe3,0x8a,0x07,0xfc,0x83,0x26,0xc4,0x04,\n0x13,0x96,0x06,0x02,0x1b,0x87,0x06,0x00,0xe3,0x46,0x06,0xfe,0x93,0x77,0x17,0x00,\n0xe3,0x94,0x07,0xfc,0x23,0x2c,0x04,0x00,0x83,0x27,0x04,0x04,0x9b,0x87,0x07,0x00,\n0x93,0xe7,0x87,0x00,0x23,0x20,0xf4,0x04,0x6f,0xf0,0xdf,0xf7,0x13,0x01,0x01,0xfa,\n0x23,0x38,0x81,0x04,0x23,0x34,0x91,0x04,0x23,0x30,0x21,0x05,0x23,0x3c,0x31,0x03,\n0x23,0x38,0x41,0x03,0x23,0x34,0x51,0x03,0x23,0x30,0x61,0x03,0x23,0x3c,0x11,0x04,\n0x23,0x3c,0x71,0x01,0x23,0x38,0x81,0x01,0x23,0x34,0x91,0x01,0x23,0x30,0xa1,0x01,\n0x13,0x04,0x05,0x00,0x93,0x8a,0x05,0x00,0x13,0x0b,0x06,0x00,0x13,0x89,0x06,0x00,\n0x13,0x0a,0x07,0x00,0x93,0x89,0x07,0x00,0xef,0xf0,0x9f,0xe9,0x93,0x04,0x05,0x00,\n0x63,0x1a,0x05,0x04,0x83,0x27,0x04,0x06,0x13,0x05,0x04,0x00,0x9b,0x87,0x07,0x00,\n0x93,0xf7,0xe7,0xff,0x23,0x20,0xf4,0x06,0xef,0xf0,0x1f,0xed,0x93,0x04,0x05,0x00,\n0x63,0x12,0x05,0x02,0x9b,0x86,0xfa,0xff,0xb3,0x76,0xd9,0x00,0x93,0xfc,0xf9,0x0f,\n0x93,0xf9,0x09,0x10,0x9b,0x86,0x06,0x00,0x13,0x0c,0x20,0x00,0x9b,0x89,0x09,0x00,\n0x63,0x18,0x0a,0x04,0x83,0x27,0x04,0x06,0x9b,0x87,0x07,0x00,0x93,0xe7,0x17,0x00,\n0x23,0x20,0xf4,0x06,0x83,0x30,0x81,0x05,0x03,0x34,0x01,0x05,0x03,0x39,0x01,0x04,\n0x83,0x39,0x81,0x03,0x03,0x3a,0x01,0x03,0x83,0x3a,0x81,0x02,0x03,0x3b,0x01,0x02,\n0x83,0x3b,0x81,0x01,0x03,0x3c,0x01,0x01,0x83,0x3c,0x81,0x00,0x03,0x3d,0x01,0x00,\n0x13,0x85,0x04,0x00,0x83,0x34,0x81,0x04,0x13,0x01,0x01,0x06,0x67,0x80,0x00,0x00,\n0xbb,0x07,0xda,0x00,0x93,0x0b,0x0a,0x00,0x63,0xf4,0xfa,0x00,0xbb,0x8b,0xda,0x40,\n0x93,0x05,0x60,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0x1f,0xe1,0x63,0x1a,0x05,0x0a,\n0x13,0x05,0x04,0x00,0xef,0xf0,0xdf,0xdd,0x63,0x14,0x05,0x0a,0x23,0x2c,0x84,0x01,\n0x93,0x85,0x0c,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0x1f,0xdf,0x63,0x1a,0x05,0x08,\n0x63,0x90,0x09,0x08,0x9b,0x55,0x09,0x01,0x93,0xf5,0xf5,0x0f,0x13,0x05,0x04,0x00,\n0xef,0xf0,0x9f,0xdd,0x63,0x1e,0x05,0x06,0x9b,0x55,0x89,0x00,0x93,0xf5,0xf5,0x0f,\n0x13,0x05,0x04,0x00,0xef,0xf0,0x5f,0xdc,0x63,0x14,0x05,0x06,0x93,0x75,0xf9,0x0f,\n0x13,0x05,0x04,0x00,0xef,0xf0,0x5f,0xdb,0x63,0x1c,0x05,0x04,0x13,0x0d,0x00,0x00,\n0x9b,0x07,0x0d,0x00,0x63,0xea,0x77,0x05,0x13,0x05,0x04,0x00,0xef,0xf0,0x5f,0xd7,\n0x63,0x10,0x05,0x04,0x23,0x2c,0x04,0x00,0x13,0x05,0x04,0x00,0xef,0xf0,0xdf,0xdb,\n0x63,0x18,0x05,0x02,0x93,0x97,0x0b,0x02,0x93,0xd7,0x07,0x02,0x33,0x0b,0xfb,0x00,\n0x3b,0x09,0x79,0x01,0x3b,0x0a,0x7a,0x41,0x93,0x06,0x00,0x00,0x6f,0xf0,0x5f,0xef,\n0x9b,0x55,0x89,0x01,0x13,0x05,0x04,0x00,0xef,0xf0,0x1f,0xd6,0xe3,0x0c,0x05,0xf6,\n0x93,0x04,0x05,0x00,0x6f,0xf0,0x1f,0xee,0xb3,0x07,0xab,0x01,0x83,0xc5,0x07,0x00,\n0x13,0x05,0x04,0x00,0x13,0x0d,0x1d,0x00,0xef,0xf0,0x1f,0xd4,0xe3,0x0a,0x05,0xf8,\n0x6f,0xf0,0x1f,0xfe,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n0x09,0x53,0x67,0x08,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fespi/riscv_fespi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdio.h>\n\n#include \"../../../../src/flash/nor/spi.h\"\n\n/* Register offsets */\n\n#define FESPI_REG_SCKDIV          0x00\n#define FESPI_REG_SCKMODE         0x04\n#define FESPI_REG_CSID            0x10\n#define FESPI_REG_CSDEF           0x14\n#define FESPI_REG_CSMODE          0x18\n\n#define FESPI_REG_DCSSCK          0x28\n#define FESPI_REG_DSCKCS          0x2a\n#define FESPI_REG_DINTERCS        0x2c\n#define FESPI_REG_DINTERXFR       0x2e\n\n#define FESPI_REG_FMT             0x40\n#define FESPI_REG_TXFIFO          0x48\n#define FESPI_REG_RXFIFO          0x4c\n#define FESPI_REG_TXCTRL          0x50\n#define FESPI_REG_RXCTRL          0x54\n\n#define FESPI_REG_FCTRL           0x60\n#define FESPI_REG_FFMT            0x64\n\n#define FESPI_REG_IE              0x70\n#define FESPI_REG_IP              0x74\n\n/* Fields */\n\n#define FESPI_SCK_POL             0x1\n#define FESPI_SCK_PHA             0x2\n\n#define FESPI_FMT_PROTO(x)        ((x) & 0x3)\n#define FESPI_FMT_ENDIAN(x)       (((x) & 0x1) << 2)\n#define FESPI_FMT_DIR(x)          (((x) & 0x1) << 3)\n#define FESPI_FMT_LEN(x)          (((x) & 0xf) << 16)\n\n/* TXCTRL register */\n#define FESPI_TXWM(x)             ((x) & 0xffff)\n/* RXCTRL register */\n#define FESPI_RXWM(x)             ((x) & 0xffff)\n\n#define FESPI_IP_TXWM             0x1\n#define FESPI_IP_RXWM             0x2\n\n#define FESPI_FCTRL_EN            0x1\n\n#define FESPI_INSN_CMD_EN         0x1\n#define FESPI_INSN_ADDR_LEN(x)    (((x) & 0x7) << 1)\n#define FESPI_INSN_PAD_CNT(x)     (((x) & 0xf) << 4)\n#define FESPI_INSN_CMD_PROTO(x)   (((x) & 0x3) << 8)\n#define FESPI_INSN_ADDR_PROTO(x)  (((x) & 0x3) << 10)\n#define FESPI_INSN_DATA_PROTO(x)  (((x) & 0x3) << 12)\n#define FESPI_INSN_CMD_CODE(x)    (((x) & 0xff) << 16)\n#define FESPI_INSN_PAD_CODE(x)    (((x) & 0xff) << 24)\n\n/* Values */\n\n#define FESPI_CSMODE_AUTO         0\n#define FESPI_CSMODE_HOLD         2\n#define FESPI_CSMODE_OFF          3\n\n#define FESPI_DIR_RX              0\n#define FESPI_DIR_TX              1\n\n#define FESPI_PROTO_S             0\n#define FESPI_PROTO_D             1\n#define FESPI_PROTO_Q             2\n\n#define FESPI_ENDIAN_MSB          0\n#define FESPI_ENDIAN_LSB          1\n\n/* Timeouts we use, in number of status checks. */\n#define TIMEOUT\t\t\t1000\n\n/* #define DEBUG to make the return error codes provide enough information to\n * reconstruct the stack from where the error occurred. This is not enabled\n * usually to reduce the program size. */\n#ifdef DEBUG\n#define ERROR_STACK(x)\t\t(x)\n#define ERROR_FESPI_TXWM_WAIT\t0x10\n#define ERROR_FESPI_TX\t\t0x100\n#define ERROR_FESPI_RX\t\t0x1000\n#define ERROR_FESPI_WIP\t\t0x50000\n#else\n#define ERROR_STACK(x)\t\t0\n#define ERROR_FESPI_TXWM_WAIT\t1\n#define ERROR_FESPI_TX\t\t1\n#define ERROR_FESPI_RX\t\t1\n#define ERROR_FESPI_WIP\t\t1\n#endif\n\n#define ERROR_OK\t\t0\n\nstatic int fespi_txwm_wait(volatile uint32_t *ctrl_base);\nstatic void fespi_disable_hw_mode(volatile uint32_t *ctrl_base);\nstatic void fespi_enable_hw_mode(volatile uint32_t *ctrl_base);\nstatic int fespi_wip(volatile uint32_t *ctrl_base);\nstatic int fespi_write_buffer(volatile uint32_t *ctrl_base,\n\t\tconst uint8_t *buffer, unsigned offset, unsigned len,\n\t\tuint32_t flash_info);\n\n/* Can set bits 3:0 in result. */\n/* flash_info contains:\n *   bits 7:0 -- pprog_cmd\n *   bit 8    -- 0 means send 3 bytes after pprog_cmd, 1 means send 4 bytes\n *               after pprog_cmd\n */\nint flash_fespi(volatile uint32_t *ctrl_base, uint32_t page_size,\n\t\tconst uint8_t *buffer, unsigned offset, uint32_t count,\n\t\tuint32_t flash_info)\n{\n\tint result;\n\n\tresult = fespi_txwm_wait(ctrl_base);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x1);\n\n\t/* Disable Hardware accesses*/\n\tfespi_disable_hw_mode(ctrl_base);\n\n\t/* poll WIP */\n\tresult = fespi_wip(ctrl_base);\n\tif (result != ERROR_OK) {\n\t\tresult |= ERROR_STACK(0x2);\n\t\tgoto err;\n\t}\n\n\t/* Assume page_size is a power of two so we don't need the modulus code. */\n\tuint32_t page_offset = offset & (page_size - 1);\n\n\t/* central part, aligned words */\n\twhile (count > 0) {\n\t\tuint32_t cur_count;\n\t\t/* clip block at page boundary */\n\t\tif (page_offset + count > page_size)\n\t\t\tcur_count = page_size - page_offset;\n\t\telse\n\t\t\tcur_count = count;\n\n\t\tresult = fespi_write_buffer(ctrl_base, buffer, offset, cur_count, flash_info);\n\t\tif (result != ERROR_OK) {\n\t\t\tresult |= ERROR_STACK(0x3);\n\t\t\tgoto err;\n\t\t}\n\n\t\tpage_offset = 0;\n\t\tbuffer += cur_count;\n\t\toffset += cur_count;\n\t\tcount -= cur_count;\n\t}\n\nerr:\n\t/* Switch to HW mode before return to prompt */\n\tfespi_enable_hw_mode(ctrl_base);\n\n\treturn result;\n}\n\nstatic uint32_t fespi_read_reg(volatile uint32_t *ctrl_base, unsigned address)\n{\n\treturn ctrl_base[address / 4];\n}\n\nstatic void fespi_write_reg(volatile uint32_t *ctrl_base, unsigned address, uint32_t value)\n{\n\tctrl_base[address / 4] = value;\n}\n\nstatic void fespi_disable_hw_mode(volatile uint32_t *ctrl_base)\n{\n\tuint32_t fctrl = fespi_read_reg(ctrl_base, FESPI_REG_FCTRL);\n\tfespi_write_reg(ctrl_base, FESPI_REG_FCTRL, fctrl & ~FESPI_FCTRL_EN);\n}\n\nstatic void fespi_enable_hw_mode(volatile uint32_t *ctrl_base)\n{\n\tuint32_t fctrl = fespi_read_reg(ctrl_base, FESPI_REG_FCTRL);\n\tfespi_write_reg(ctrl_base, FESPI_REG_FCTRL, fctrl | FESPI_FCTRL_EN);\n}\n\n/* Can set bits 7:4 in result. */\nstatic int fespi_txwm_wait(volatile uint32_t *ctrl_base)\n{\n\tunsigned timeout = TIMEOUT;\n\n\twhile (timeout--) {\n\t\tuint32_t ip = fespi_read_reg(ctrl_base, FESPI_REG_IP);\n\t\tif (ip & FESPI_IP_TXWM)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_FESPI_TXWM_WAIT;\n}\n\nstatic void fespi_set_dir(volatile uint32_t *ctrl_base, bool dir)\n{\n\tuint32_t fmt = fespi_read_reg(ctrl_base, FESPI_REG_FMT);\n\tfespi_write_reg(ctrl_base, FESPI_REG_FMT,\n\t\t\t(fmt & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir));\n}\n\n/* Can set bits 11:8 in result. */\nstatic int fespi_tx(volatile uint32_t *ctrl_base, uint8_t in)\n{\n\tunsigned timeout = TIMEOUT;\n\n\twhile (timeout--) {\n\t\tuint32_t txfifo = fespi_read_reg(ctrl_base, FESPI_REG_TXFIFO);\n\t\tif (!(txfifo >> 31)) {\n\t\t\tfespi_write_reg(ctrl_base, FESPI_REG_TXFIFO, in);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\treturn ERROR_FESPI_TX;\n}\n\n/* Can set bits 15:12 in result. */\nstatic int fespi_rx(volatile uint32_t *ctrl_base, uint8_t *out)\n{\n\tunsigned timeout = TIMEOUT;\n\n\twhile (timeout--) {\n\t\tuint32_t value = fespi_read_reg(ctrl_base, FESPI_REG_RXFIFO);\n\t\tif (!(value >> 31)) {\n\t\t\tif (out)\n\t\t\t\t*out = value & 0xff;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FESPI_RX;\n}\n\n/* Can set bits 19:16 in result. */\nstatic int fespi_wip(volatile uint32_t *ctrl_base)\n{\n\tfespi_set_dir(ctrl_base, FESPI_DIR_RX);\n\n\tfespi_write_reg(ctrl_base, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD);\n\n\tint result = fespi_tx(ctrl_base, SPIFLASH_READ_STATUS);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x10000);\n\tresult = fespi_rx(ctrl_base, NULL);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x20000);\n\n\tunsigned timeout = TIMEOUT;\n\twhile (timeout--) {\n\t\tresult = fespi_tx(ctrl_base, 0);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result | ERROR_STACK(0x30000);\n\t\tuint8_t rx;\n\t\tresult = fespi_rx(ctrl_base, &rx);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result | ERROR_STACK(0x40000);\n\t\tif ((rx & SPIFLASH_BSY_BIT) == 0) {\n\t\t\tfespi_write_reg(ctrl_base, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO);\n\t\t\tfespi_set_dir(ctrl_base, FESPI_DIR_TX);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FESPI_WIP;\n}\n\n/* Can set bits 23:20 in result. */\nstatic int fespi_write_buffer(volatile uint32_t *ctrl_base,\n\t\tconst uint8_t *buffer, unsigned offset, unsigned len,\n\t\tuint32_t flash_info)\n{\n\tint result = fespi_tx(ctrl_base, SPIFLASH_WRITE_ENABLE);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x100000);\n\tresult = fespi_txwm_wait(ctrl_base);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x200000);\n\n\tfespi_write_reg(ctrl_base, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD);\n\n\tresult = fespi_tx(ctrl_base, flash_info & 0xff);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x300000);\n\n\tif (flash_info & 0x100) {\n\t\tresult = fespi_tx(ctrl_base, offset >> 24);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result | ERROR_STACK(0x400000);\n\t}\n\tresult = fespi_tx(ctrl_base, offset >> 16);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x400000);\n\tresult = fespi_tx(ctrl_base, offset >> 8);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x500000);\n\tresult = fespi_tx(ctrl_base, offset);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x600000);\n\n\tfor (unsigned i = 0; i < len; i++) {\n\t\tresult = fespi_tx(ctrl_base, buffer[i]);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result | ERROR_STACK(0x700000);\n\t}\n\n\tresult = fespi_txwm_wait(ctrl_base);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x800000);\n\n\tfespi_write_reg(ctrl_base, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO);\n\n\tresult = fespi_wip(ctrl_base);\n\tif (result != ERROR_OK)\n\t\treturn result | ERROR_STACK(0x900000);\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fespi/riscv_wrapper.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#if __riscv_xlen == 64\n# define LREG ld\n# define SREG sd\n# define REGBYTES 8\n#else\n# define LREG lw\n# define SREG sw\n# define REGBYTES 4\n#endif\n\n\t\t.section .text.entry\n\t\t.global _start\n_start:\n\t\tlla\t\tsp, stack_end\n\t\tjal \tflash_fespi\n\t\tebreak\n\n\t\t.section .data\n\t\t.balign REGBYTES\nstack:\n\t\t.fill\t16, REGBYTES, 0x8675309\nstack_end:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fm4/erase.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Spansion FM4 flash sector erase algorithm\n *\n * Copyright (c) 2015 Andreas Färber\n *\n * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series\n */\n\n#include \"fm4.h\"\n\n#define RESULT_OKAY\t0\n#define RESULT_NONE\t1\n#define RESULT_TIMEOUT\t2\n\n\t.macro busy_wait, res, addr, tmp1, tmp2, tmp3\n\n\tldrb\t\\tmp1, [\\addr] /* ignore */\n1001:\n\tldrb\t\\tmp1, [\\addr]\n\tldrb\t\\tmp2, [\\addr]\n\n\tand\t\\tmp3, \\tmp1, #FLASH_TOGG\n\tand\t\\tmp2, \\tmp2, #FLASH_TOGG\n\tcmp\t\\tmp3, \\tmp2\n\tbeq\t1010f\n\n\tand\t\\tmp2, \\tmp1, #FLASH_TLOV\n\tcmp\t\\tmp2, #0\n\tbeq\t1001b\n\n\tldrb\t\\tmp1, [\\addr]\n\tldrb\t\\tmp2, [\\addr]\n\n\tand\t\\tmp3, \\tmp1, #FLASH_TOGG\n\tand\t\\tmp2, \\tmp2, #FLASH_TOGG\n\tcmp\t\\tmp3, \\tmp2\n\tbeq\t1010f\n\n\tmov\t\\res, #RESULT_TIMEOUT\n\tbkpt\t#0\n1010:\n\tmov\t\\res, #RESULT_OKAY\n\n\t.endm\n\n\n\t.macro erase, cmdseqaddr1, cmdseqaddr2, sa, res, tmp1, tmp2, tmp3\n\n\tmov\t\\res, #RESULT_NONE\n\n\tmov\t\\tmp1, #0xAA\n\tstrh\t\\tmp1, [\\cmdseqaddr1]\n\tmov\t\\tmp2, #0x55\n\tstrh\t\\tmp2, [\\cmdseqaddr2]\n\tmov\t\\tmp3, #0x80\n\tstrh\t\\tmp3, [\\cmdseqaddr1]\n\tstrh\t\\tmp1, [\\cmdseqaddr1]\n\tstrh\t\\tmp2, [\\cmdseqaddr2]\n\tmov\t\\tmp3, #0x30\n\tstrh\t\\tmp3, [\\sa]\n\n\tbusy_wait \\res, \\sa, \\tmp1, \\tmp2, \\tmp3\n\n\t.endm\n\n\n\t/* r0 = 0xAA8\n\t * r1 = 0x554\n\t * r2 = SA\n\t * r3 = result\n\t */\nerase:\n\terase r0, r1, r2, r3, r4, r5, r6\n\n\tbkpt\t#0\n\ndata:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fm4/erase.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x4f,0xf0,0x01,0x03,0x4f,0xf0,0xaa,0x04,0x04,0x80,0x4f,0xf0,0x55,0x05,0x0d,0x80,\n0x4f,0xf0,0x80,0x06,0x06,0x80,0x04,0x80,0x0d,0x80,0x4f,0xf0,0x30,0x06,0x16,0x80,\n0x14,0x78,0x14,0x78,0x15,0x78,0x04,0xf0,0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42,\n0x0e,0xd0,0x04,0xf0,0x20,0x05,0x00,0x2d,0xf3,0xd0,0x14,0x78,0x15,0x78,0x04,0xf0,\n0x40,0x06,0x05,0xf0,0x40,0x05,0xae,0x42,0x02,0xd0,0x4f,0xf0,0x02,0x03,0x00,0xbe,\n0x4f,0xf0,0x00,0x03,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fm4/fm4.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Spansion FM4 flash macros\n *\n * Copyright (c) 2015 Andreas Färber\n *\n * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series\n */\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m4\n\t.thumb\n\t.thumb_func\n\n\n#define FLASH_DPOL\t(1 << 7)\n#define FLASH_TOGG\t(1 << 6)\n#define FLASH_TLOV\t(1 << 5)\n#define FLASH_TOGG2\t(1 << 2)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fm4/write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Spansion FM4 flash write algorithm\n *\n * Copyright (c) 2015 Andreas Färber\n *\n * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series\n */\n\n#include \"fm4.h\"\n\n#define RESULT_OKAY\t0\n#define RESULT_NONE\t1\n#define RESULT_TIMEOUT\t2\n\n\t.macro busy_wait, res, addr, data, tmp1, tmp2, tmp3\n\n\tldrb\t\\tmp1, [\\addr] /* ignore */\n\tand\t\\tmp2, \\data, #FLASH_DPOL\n1001:\n\tldrb\t\\tmp1, [\\addr]\n\tand\t\\tmp3, \\tmp1, #FLASH_DPOL\n\tcmp\t\\tmp3, \\tmp2\n\tbeq\t1010f\n\n\tand\t\\tmp3, \\tmp1, #FLASH_TLOV\n\tcmp\t\\tmp3, #0\n\tbeq\t1001b\n\n\tldrb\t\\tmp1, [\\addr]\n\tand\t\\tmp3, \\tmp1, #FLASH_DPOL\n\tcmp\t\\tmp3, \\tmp2\n\tbeq\t1010f\n\n\tmov\t\\res, #RESULT_TIMEOUT\n\tbkpt\t#0\n1010:\n\t.endm\n\n\n\t.macro write_one, res, cmdseqaddr1, cmdseqaddr2, pa, pd, tmp1, tmp2, tmp3\n\n\tmov\t\\tmp1, #0xAA\n\tstrh\t\\tmp1, [\\cmdseqaddr1]\n\tmov\t\\tmp1, #0x55\n\tstrh\t\\tmp1, [\\cmdseqaddr2]\n\tmov\t\\tmp1, #0xA0\n\tstrh\t\\tmp1, [\\cmdseqaddr1]\n\tstrh\t\\pd, [\\pa]\n\n\tbusy_wait \\res, \\pa, \\pd, \\tmp1, \\tmp2, \\tmp3\n\n\t.endm\n\n\n\t.macro write, cmdseqaddr1, cmdseqaddr2, dest, src, cnt, res, tmp1, tmp2, tmp3, tmp4\n\n\tmov\t\\res, #RESULT_NONE\n2001:\n\tcbz\t\\cnt, 2010f\n\n\tldrh\t\\tmp1, [\\src]\n\twrite_one \\res, \\cmdseqaddr1, \\cmdseqaddr2, \\dest, \\tmp1, \\tmp2, \\tmp3, \\tmp4\n\n\tsub\t\\cnt, \\cnt, #1\n\tadd\t\\dest, \\dest, #2\n\tadd\t\\src, \\src, #2\n\tb\t2001b\n2010:\n\tmov\t\\res, #RESULT_OKAY\n\t.endm\n\n\n\t/* r0 = 0xAA8\n\t * r1 = 0x554\n\t * r2 = dest\n\t * r3 = src\n\t * r4 = cnt\n\t * r5 = result\n\t */\nwrite:\n\twrite r0, r1, r2, r3, r4, r5, r6, r7, r8, r9\n\n\tbkpt\t#0\n\ndata:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fm4/write.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x4f,0xf0,0x01,0x05,0x34,0xb3,0x1e,0x88,0x4f,0xf0,0xaa,0x07,0x07,0x80,0x4f,0xf0,\n0x55,0x07,0x0f,0x80,0x4f,0xf0,0xa0,0x07,0x07,0x80,0x16,0x80,0x17,0x78,0x06,0xf0,\n0x80,0x08,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x0c,0xd0,0x07,0xf0,0x20,0x09,\n0xb9,0xf1,0x00,0x0f,0xf5,0xd0,0x17,0x78,0x07,0xf0,0x80,0x09,0xc1,0x45,0x02,0xd0,\n0x4f,0xf0,0x02,0x05,0x00,0xbe,0xa4,0xf1,0x01,0x04,0x02,0xf1,0x02,0x02,0x03,0xf1,\n0x02,0x03,0xd7,0xe7,0x4f,0xf0,0x00,0x05,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/fpga/xilinx_bscan_spi.py",
    "content": "#!/usr/bin/python3\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2015 Robert Jordens <jordens@gmail.com>\n\nimport unittest\n\nimport migen as mg\nimport migen.build.generic_platform as mb\nfrom migen.genlib import io\nfrom migen.build import xilinx\n\n\n\"\"\"\nThis migen script produces proxy bitstreams to allow programming SPI flashes\nbehind FPGAs.\n\nBitstream binaries built with this script are available at:\nhttps://github.com/jordens/bscan_spi_bitstreams\n\nA JTAG2SPI transfer consists of:\n\n1. an arbitrary number of 0 bits (from BYPASS registers in front of the\n   JTAG2SPI DR)\n2. a marker bit (1) indicating the start of the JTAG2SPI transaction\n3. 32 bits (big endian) describing the length of the SPI transaction\n4. a number of SPI clock cycles (corresponding to 3.) with CS_N asserted\n5. an arbitrary number of cycles (to shift MISO/TDO data through subsequent\n   BYPASS registers)\n\nNotes:\n\n* The JTAG2SPI DR is 1 bit long (due to different sampling edges of\n  {MISO,MOSI}/{TDO,TDI}).\n* MOSI is TDI with half a cycle delay.\n* TDO is MISO with half a cycle delay.\n* CAPTURE-DR needs to be performed before SHIFT-DR on the BYPASSed TAPs in\n  JTAG chain to clear the BYPASS registers to 0.\n\nhttps://github.com/m-labs/migen\n\"\"\"\n\n\nclass JTAG2SPI(mg.Module):\n    def __init__(self, spi=None, bits=32):\n        self.jtag = mg.Record([\n            (\"sel\", 1),\n            (\"shift\", 1),\n            (\"capture\", 1),\n            (\"tck\", 1),\n            (\"tdi\", 1),\n            (\"tdo\", 1),\n        ])\n        self.cs_n = mg.TSTriple()\n        self.clk = mg.TSTriple()\n        self.mosi = mg.TSTriple()\n        self.miso = mg.TSTriple()\n\n        # # #\n\n        self.cs_n.o.reset = mg.Constant(1)\n        self.mosi.o.reset_less = True\n        bits = mg.Signal(bits, reset_less=True)\n        head = mg.Signal(max=len(bits), reset=len(bits) - 1)\n        self.clock_domains.cd_sys = mg.ClockDomain()\n        self.submodules.fsm = mg.FSM(\"IDLE\")\n        if spi is not None:\n            self.specials += [\n                    self.cs_n.get_tristate(spi.cs_n),\n                    self.mosi.get_tristate(spi.mosi),\n                    self.miso.get_tristate(spi.miso),\n            ]\n            if hasattr(spi, \"clk\"):  # 7 Series drive it fixed\n                self.specials += self.clk.get_tristate(spi.clk)\n                # self.specials += io.DDROutput(1, 0, spi.clk, self.clk.o)\n        self.comb += [\n                self.cd_sys.rst.eq(self.jtag.sel & self.jtag.capture),\n                self.cd_sys.clk.eq(self.jtag.tck),\n                self.cs_n.oe.eq(self.jtag.sel),\n                self.clk.oe.eq(self.jtag.sel),\n                self.mosi.oe.eq(self.jtag.sel),\n                self.miso.oe.eq(0),\n                # Do not suppress CLK toggles outside CS_N asserted.\n                # Xilinx USRCCLK0 requires three dummy cycles to do anything\n                # https://www.xilinx.com/support/answers/52626.html\n                # This is fine since CS_N changes only on falling CLK.\n                self.clk.o.eq(~self.jtag.tck),\n                self.jtag.tdo.eq(self.miso.i),\n        ]\n        # Latency calculation (in half cycles):\n        # 0 (falling TCK, rising CLK):\n        #   JTAG adapter: set TDI\n        # 1 (rising TCK, falling CLK):\n        #   JTAG2SPI: sample TDI -> set MOSI\n        #   SPI: set MISO\n        # 2 (falling TCK, rising CLK):\n        #   SPI: sample MOSI\n        #   JTAG2SPI (BSCAN primitive): sample MISO -> set TDO\n        # 3 (rising TCK, falling CLK):\n        #   JTAG adapter: sample TDO\n        self.fsm.act(\"IDLE\",\n                mg.If(self.jtag.tdi & self.jtag.sel & self.jtag.shift,\n                    mg.NextState(\"HEAD\")\n                )\n        )\n        self.fsm.act(\"HEAD\",\n                mg.If(head == 0,\n                    mg.NextState(\"XFER\")\n                )\n        )\n        self.fsm.act(\"XFER\",\n                mg.If(bits == 0,\n                    mg.NextState(\"IDLE\")\n                ),\n        )\n        self.sync += [\n                self.mosi.o.eq(self.jtag.tdi),\n                self.cs_n.o.eq(~self.fsm.ongoing(\"XFER\")),\n                mg.If(self.fsm.ongoing(\"HEAD\"),\n                    bits.eq(mg.Cat(self.jtag.tdi, bits)),\n                    head.eq(head - 1)\n                ),\n                mg.If(self.fsm.ongoing(\"XFER\"),\n                    bits.eq(bits - 1)\n                )\n        ]\n\n\nclass JTAG2SPITest(unittest.TestCase):\n    def setUp(self):\n        self.bits = 8\n        self.dut = JTAG2SPI(bits=self.bits)\n\n    def test_instantiate(self):\n        pass\n\n    def test_initial_conditions(self):\n        def check():\n            yield\n            self.assertEqual((yield self.dut.cs_n.oe), 0)\n            self.assertEqual((yield self.dut.mosi.oe), 0)\n            self.assertEqual((yield self.dut.miso.oe), 0)\n            self.assertEqual((yield self.dut.clk.oe), 0)\n        mg.run_simulation(self.dut, check())\n\n    def test_enable(self):\n        def check():\n            yield self.dut.jtag.sel.eq(1)\n            yield self.dut.jtag.shift.eq(1)\n            yield\n            self.assertEqual((yield self.dut.cs_n.oe), 1)\n            self.assertEqual((yield self.dut.mosi.oe), 1)\n            self.assertEqual((yield self.dut.miso.oe), 0)\n            self.assertEqual((yield self.dut.clk.oe), 1)\n        mg.run_simulation(self.dut, check())\n\n    def run_seq(self, tdi, tdo, spi=None):\n        yield self.dut.jtag.sel.eq(1)\n        yield\n        yield self.dut.jtag.shift.eq(1)\n        for di in tdi:\n            yield self.dut.jtag.tdi.eq(di)\n            yield\n            tdo.append((yield self.dut.jtag.tdo))\n            if spi is not None:\n                v = []\n                for k in \"cs_n clk mosi miso\".split():\n                    t = getattr(self.dut, k)\n                    v.append(\"{}>\".format((yield t.o)) if (yield t.oe)\n                            else \"<{}\".format((yield t.i)))\n                spi.append(\" \".join(v))\n        yield self.dut.jtag.sel.eq(0)\n        yield\n        yield self.dut.jtag.shift.eq(0)\n        yield\n\n    def test_shift(self):\n        bits = 8\n        data = 0x81\n        tdi = [0, 0, 1]  # dummy from BYPASS TAPs and marker\n        tdi += [((bits - 1) >> j) & 1 for j in range(self.bits - 1, -1, -1)]\n        tdi += [(data >> j) & 1 for j in range(bits)]\n        tdi += [0, 0, 0, 0]  # dummy from BYPASS TAPs\n        tdo = []\n        spi = []\n        mg.run_simulation(self.dut, self.run_seq(tdi, tdo, spi))\n        # print(tdo)\n        for l in spi:\n            print(l)\n\n\nclass Spartan3(mg.Module):\n    macro = \"BSCAN_SPARTAN3\"\n    toolchain = \"ise\"\n\n    def __init__(self, platform):\n        platform.toolchain.bitgen_opt += \" -g compress -g UnusedPin:Pullup\"\n        self.submodules.j2s = j2s = JTAG2SPI(platform.request(\"spiflash\"))\n        self.specials += [\n                mg.Instance(\n                    self.macro,\n                    o_SHIFT=j2s.jtag.shift, o_SEL1=j2s.jtag.sel,\n                    o_CAPTURE=j2s.jtag.capture,\n                    o_DRCK1=j2s.jtag.tck,\n                    o_TDI=j2s.jtag.tdi, i_TDO1=j2s.jtag.tdo,\n                    i_TDO2=0),\n        ]\n        platform.add_period_constraint(j2s.jtag.tck, 6)\n\n\nclass Spartan3A(Spartan3):\n    macro = \"BSCAN_SPARTAN3A\"\n\n\nclass Spartan6(mg.Module):\n    toolchain = \"ise\"\n\n    def __init__(self, platform):\n        platform.toolchain.bitgen_opt += \" -g compress -g UnusedPin:Pullup\"\n        self.submodules.j2s = j2s = JTAG2SPI(platform.request(\"spiflash\"))\n        # clk = mg.Signal()\n        self.specials += [\n                mg.Instance(\n                    \"BSCAN_SPARTAN6\", p_JTAG_CHAIN=1,\n                    o_SHIFT=j2s.jtag.shift, o_SEL=j2s.jtag.sel,\n                    o_CAPTURE=j2s.jtag.capture,\n                    o_DRCK=j2s.jtag.tck,\n                    o_TDI=j2s.jtag.tdi, i_TDO=j2s.jtag.tdo),\n                # mg.Instance(\"BUFG\", i_I=clk, o_O=j2s.jtag.tck)\n        ]\n        platform.add_period_constraint(j2s.jtag.tck, 6)\n\n\nclass Series7(mg.Module):\n    toolchain = \"vivado\"\n\n    def __init__(self, platform):\n        platform.toolchain.bitstream_commands.extend([\n            \"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]\",\n            \"set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design]\"\n        ])\n        self.submodules.j2s = j2s = JTAG2SPI(platform.request(\"spiflash\"))\n        # clk = mg.Signal()\n        self.specials += [\n                mg.Instance(\n                    \"BSCANE2\", p_JTAG_CHAIN=1,\n                    o_SHIFT=j2s.jtag.shift, o_SEL=j2s.jtag.sel,\n                    o_CAPTURE=j2s.jtag.capture,\n                    o_DRCK=j2s.jtag.tck,\n                    o_TDI=j2s.jtag.tdi, i_TDO=j2s.jtag.tdo),\n                mg.Instance(\n                    \"STARTUPE2\", i_CLK=0, i_GSR=0, i_GTS=0,\n                    i_KEYCLEARB=0, i_PACK=1,\n                    i_USRCCLKO=j2s.clk.o, i_USRCCLKTS=~j2s.clk.oe,\n                    i_USRDONEO=1, i_USRDONETS=1),\n                # mg.Instance(\"BUFG\", i_I=clk, o_O=j2s.jtag.tck)\n        ]\n        platform.add_period_constraint(j2s.jtag.tck, 6)\n        try:\n            self.comb += [\n                    platform.request(\"user_sma_gpio_p\").eq(j2s.cs_n.i),\n                    platform.request(\"user_sma_gpio_n\").eq(j2s.clk.o),\n                    platform.request(\"user_sma_clock_p\").eq(j2s.mosi.o),\n                    platform.request(\"user_sma_clock_n\").eq(j2s.miso.i),\n            ]\n        except mb.ConstraintError:\n            pass\n\n\nclass Ultrascale(mg.Module):\n    toolchain = \"vivado\"\n\n    def __init__(self, platform):\n        platform.toolchain.bitstream_commands.extend([\n            \"set_property BITSTREAM.GENERAL.COMPRESS True [current_design]\",\n            \"set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design]\",\n        ])\n        self.submodules.j2s0 = j2s0 = JTAG2SPI()\n        self.submodules.j2s1 = j2s1 = JTAG2SPI(platform.request(\"spiflash\"))\n        di = mg.Signal(4)\n        self.comb += mg.Cat(j2s0.mosi.i, j2s0.miso.i).eq(di)\n        self.specials += [\n                mg.Instance(\"BSCANE2\", p_JTAG_CHAIN=1,\n                    o_SHIFT=j2s0.jtag.shift, o_SEL=j2s0.jtag.sel,\n                    o_CAPTURE=j2s0.jtag.capture,\n                    o_DRCK=j2s0.jtag.tck,\n                    o_TDI=j2s0.jtag.tdi, i_TDO=j2s0.jtag.tdo),\n                mg.Instance(\"BSCANE2\", p_JTAG_CHAIN=2,\n                    o_SHIFT=j2s1.jtag.shift, o_SEL=j2s1.jtag.sel,\n                    o_CAPTURE=j2s1.jtag.capture,\n                    o_DRCK=j2s1.jtag.tck,\n                    o_TDI=j2s1.jtag.tdi, i_TDO=j2s1.jtag.tdo),\n                mg.Instance(\"STARTUPE3\", i_GSR=0, i_GTS=0,\n                    i_KEYCLEARB=0, i_PACK=1,\n                    i_USRDONEO=1, i_USRDONETS=1,\n                    i_USRCCLKO=mg.Mux(j2s0.clk.oe, j2s0.clk.o, j2s1.clk.o),\n                    i_USRCCLKTS=~(j2s0.clk.oe | j2s1.clk.oe),\n                    i_FCSBO=j2s0.cs_n.o, i_FCSBTS=~j2s0.cs_n.oe,\n                    o_DI=di,\n                    i_DO=mg.Cat(j2s0.mosi.o, j2s0.miso.o, 0, 0),\n                    i_DTS=mg.Cat(~j2s0.mosi.oe, ~j2s0.miso.oe, 1, 1))\n        ]\n        platform.add_period_constraint(j2s0.jtag.tck, 6)\n        platform.add_period_constraint(j2s1.jtag.tck, 6)\n\n\nclass XilinxBscanSpi(xilinx.XilinxPlatform):\n    packages = {\n        # (package-speedgrade, id): [cs_n, clk, mosi, miso, *pullups]\n        (\"cp132\", 1): [\"M2\", \"N12\", \"N2\", \"N8\"],\n        (\"fg320\", 1): [\"U3\", \"U16\", \"T4\", \"N10\"],\n        (\"fg320\", 2): [\"V3\", \"U16\", \"T11\", \"V16\"],\n        (\"fg484\", 1): [\"Y4\", \"AA20\", \"AB14\", \"AB20\"],\n        (\"fgg484\", 1): [\"Y4\", \"AA20\", \"AB14\", \"AB20\"],\n        (\"fgg400\", 1): [\"Y2\", \"Y19\", \"W12\", \"W18\"],\n        (\"ftg256\", 1): [\"T2\", \"R14\", \"P10\", \"T14\"],\n        (\"ft256\", 1): [\"T2\", \"R14\", \"P10\", \"T14\"],\n        (\"fg400\", 1): [\"Y2\", \"Y19\", \"W12\", \"W18\"],\n        (\"cs484\", 1): [\"U7\", \"V17\", \"V13\", \"W17\"],\n        (\"qg144-2\", 1): [\"P38\", \"P70\", \"P64\", \"P65\", \"P62\", \"P61\"],\n        (\"cpg196-2\", 1): [\"P2\", \"N13\", \"P11\", \"N11\", \"N10\", \"P10\"],\n        (\"cpg236-1\", 1): [\"K19\", None, \"D18\", \"D19\", \"G18\", \"F18\"],\n        (\"csg484-2\", 1): [\"AB5\", \"W17\", \"AB17\", \"Y17\", \"V13\", \"W13\"],\n        (\"csg324-2\", 1): [\"V3\", \"R15\", \"T13\", \"R13\", \"T14\", \"V14\"],\n        (\"csg324-1\", 1): [\"L13\", None, \"K17\", \"K18\", \"L14\", \"M14\"],\n        (\"fbg484-1\", 1): [\"T19\", None, \"P22\", \"R22\", \"P21\", \"R21\"],\n        (\"fbg484-1\", 2): [\"L16\", None, \"H18\", \"H19\", \"G18\", \"F19\"],\n        (\"fbg676-1\", 1): [\"C23\", None, \"B24\", \"A25\", \"B22\", \"A22\"],\n        (\"ffg901-1\", 1): [\"V26\", None, \"R30\", \"T30\", \"R28\", \"T28\"],\n        (\"ffg900-1\", 1): [\"U19\", None, \"P24\", \"R25\", \"R20\", \"R21\"],\n        (\"ffg1156-1\", 1): [\"V30\", None, \"AA33\", \"AA34\", \"Y33\", \"Y34\"],\n        (\"ffg1157-1\", 1): [\"AL33\", None, \"AN33\", \"AN34\", \"AK34\", \"AL34\"],\n        (\"ffg1158-1\", 1): [\"C24\", None, \"A23\", \"A24\", \"B26\", \"A26\"],\n        (\"ffg1926-1\", 1): [\"AK33\", None, \"AN34\", \"AN35\", \"AJ34\", \"AK34\"],\n        (\"fhg1761-1\", 1): [\"AL36\", None, \"AM36\", \"AN36\", \"AJ36\", \"AJ37\"],\n        (\"flg1155-1\", 1): [\"AL28\", None, \"AE28\", \"AF28\", \"AJ29\", \"AJ30\"],\n        (\"flg1932-1\", 1): [\"V32\", None, \"T33\", \"R33\", \"U31\", \"T31\"],\n        (\"flg1926-1\", 1): [\"AK33\", None, \"AN34\", \"AN35\", \"AJ34\", \"AK34\"],\n\n        (\"ffva1156-2-e\", 1): [\"G26\", None, \"M20\", \"L20\", \"R21\", \"R22\"],\n        (\"ffva1156-2-e\", \"sayma\"): [\"K21\", None, \"M20\", \"L20\", \"R21\", \"R22\"],\n    }\n\n    pinouts = {\n        # bitstreams are named by die, package does not matter, speed grade\n        # should not matter.\n        #\n        # chip: (package, id, standard, class)\n        \"xc3s100e\": (\"cp132\", 1, \"LVCMOS33\", Spartan3),\n        \"xc3s1200e\": (\"fg320\", 1, \"LVCMOS33\", Spartan3),\n        \"xc3s1400a\": (\"fg484\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s1400an\": (\"fgg484\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s1600e\": (\"fg320\", 1, \"LVCMOS33\", Spartan3),\n        \"xc3s200a\": (\"fg320\", 2, \"LVCMOS33\", Spartan3A),\n        \"xc3s200an\": (\"ftg256\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s250e\": (\"cp132\", 1, \"LVCMOS33\", Spartan3),\n        \"xc3s400a\": (\"fg320\", 2, \"LVCMOS33\", Spartan3A),\n        \"xc3s400an\": (\"fgg400\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s500e\": (\"cp132\", 1, \"LVCMOS33\", Spartan3),\n        \"xc3s50a\": (\"ft256\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s50an\": (\"ftg256\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s700a\": (\"fg400\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3s700an\": (\"fgg484\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3sd1800a\": (\"cs484\", 1, \"LVCMOS33\", Spartan3A),\n        \"xc3sd3400a\": (\"cs484\", 1, \"LVCMOS33\", Spartan3A),\n\n        \"xc6slx100\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx100t\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx150\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx150t\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx16\": (\"cpg196-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx25\": (\"csg324-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx25t\": (\"csg324-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx45\": (\"csg324-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx45t\": (\"csg324-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx4\": (\"cpg196-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx4t\": (\"qg144-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx75\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx75t\": (\"csg484-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx9\": (\"cpg196-2\", 1, \"LVCMOS33\", Spartan6),\n        \"xc6slx9t\": (\"qg144-2\", 1, \"LVCMOS33\", Spartan6),\n\n        \"xc7a100t\": (\"csg324-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7a15t\": (\"cpg236-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7a200t\": (\"fbg484-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7a35t\": (\"cpg236-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7a50t\": (\"cpg236-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7a75t\": (\"csg324-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k160t\": (\"fbg484-1\", 2, \"LVCMOS25\", Series7),\n        \"xc7k325t\": (\"fbg676-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k325t-debug\": (\"ffg900-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k355t\": (\"ffg901-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k410t\": (\"fbg676-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k420t\": (\"ffg1156-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k480t\": (\"ffg1156-1\", 1, \"LVCMOS25\", Series7),\n        \"xc7k70t\": (\"fbg484-1\", 2, \"LVCMOS25\", Series7),\n        \"xc7v2000t\": (\"fhg1761-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7v585t\": (\"ffg1157-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vh580t\": (\"flg1155-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vh870t\": (\"flg1932-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx1140t\": (\"flg1926-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx330t\": (\"ffg1157-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx415t\": (\"ffg1157-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx485t\": (\"ffg1157-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx550t\": (\"ffg1158-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx690t\": (\"ffg1157-1\", 1, \"LVCMOS18\", Series7),\n        \"xc7vx980t\": (\"ffg1926-1\", 1, \"LVCMOS18\", Series7),\n\n        \"xcku040\": (\"ffva1156-2-e\", 1, \"LVCMOS18\", Ultrascale),\n        \"xcku040-sayma\": (\"ffva1156-2-e\", \"sayma\", \"LVCMOS18\", Ultrascale),\n    }\n\n    def __init__(self, device, pins, std, toolchain=\"ise\"):\n        ios = [self.make_spi(0, pins, std, toolchain)]\n        if device == \"xc7k325t-ffg900-1\":  # debug\n            ios += [\n                (\"user_sma_clock_p\", 0, mb.Pins(\"L25\"), mb.IOStandard(\"LVCMOS25\")),\n                (\"user_sma_clock_n\", 0, mb.Pins(\"K25\"), mb.IOStandard(\"LVCMOS25\")),\n                (\"user_sma_gpio_p\", 0, mb.Pins(\"Y23\"), mb.IOStandard(\"LVCMOS25\")),\n                (\"user_sma_gpio_n\", 0, mb.Pins(\"Y24\"), mb.IOStandard(\"LVCMOS25\")),\n            ]\n        xilinx.XilinxPlatform.__init__(self, device, ios, toolchain=toolchain)\n\n    @staticmethod\n    def make_spi(i, pins, std, toolchain):\n        pu = \"PULLUP\" if toolchain == \"ise\" else \"PULLUP TRUE\"\n        pd = \"PULLDOWN\" if toolchain == \"ise\" else \"PULLDOWN TRUE\"\n        cs_n, clk, mosi, miso = pins[:4]\n        io = [\"spiflash\", i,\n            mb.Subsignal(\"cs_n\", mb.Pins(cs_n), mb.Misc(pu)),\n            mb.Subsignal(\"mosi\", mb.Pins(mosi), mb.Misc(pu)),\n            mb.Subsignal(\"miso\", mb.Pins(miso), mb.Misc(pu)),\n            mb.IOStandard(std),\n            ]\n        if clk:\n            io.append(mb.Subsignal(\"clk\", mb.Pins(clk), mb.Misc(pd)))\n        for i, p in enumerate(pins[4:]):\n            io.append(mb.Subsignal(\"pullup{}\".format(i), mb.Pins(p),\n                                mb.Misc(pu)))\n        return io\n\n    @classmethod\n    def make(cls, target, errors=False):\n        pkg, id, std, Top = cls.pinouts[target]\n        pins = cls.packages[(pkg, id)]\n        device = target.split(\"-\", 1)[0]\n        platform = cls(\"{}-{}\".format(device, pkg), pins, std, Top.toolchain)\n        top = Top(platform)\n        name = \"bscan_spi_{}\".format(target)\n        try:\n            platform.build(top, build_name=name)\n        except Exception as e:\n            print((\"ERROR: xilinx_bscan_spi build failed \"\n                  \"for {}: {}\").format(target, e))\n            if errors:\n                raise\n\n\nif __name__ == \"__main__\":\n    import argparse\n    import multiprocessing\n    p = argparse.ArgumentParser(description=\"build bscan_spi bitstreams \"\n                                \"for openocd jtagspi flash driver\")\n    p.add_argument(\"device\", nargs=\"*\",\n                   default=sorted(list(XilinxBscanSpi.pinouts)),\n                   help=\"build for these devices (default: %(default)s)\")\n    p.add_argument(\"-p\", \"--parallel\", default=1, type=int,\n                   help=\"number of parallel builds (default: %(default)s)\")\n    args = p.parse_args()\n    pool = multiprocessing.Pool(args.parallel)\n    pool.map(XilinxBscanSpi.make, args.device, chunksize=1)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/gd32vf103/gd32vf103.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#include <stdint.h>\n\n#define FLASH_BSY\t(1 << 0)\n#define FLASH_PGERR\t(1 << 2)\n#define FLASH_WRPRTERR\t(1 << 4)\n\nvoid flash_write(volatile uint32_t *flash_sr,\n\t\tuint32_t hwords_count,\n\t\tuint16_t *buffer,\n\t\tuint16_t *target_addr) __attribute__((naked));\n\nvoid flash_write(volatile uint32_t *flash_sr,\n\t\tuint32_t hwords_count,\n\t\tuint16_t *buffer,\n\t\tuint16_t *target_addr)\n{\n\tdo {\n\t\t*target_addr = *buffer++;\n\n\t\tregister uint32_t sr;\n\t\tdo {\n\t\t\tsr = *flash_sr;\n\t\t} while (sr & FLASH_BSY);\n\n\t\tif (sr & (FLASH_PGERR | FLASH_WRPRTERR))\n\t\t\tbreak;\n\n\t\ttarget_addr++;\n\t} while (--hwords_count);\n\tasm(\"ebreak\");\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/gd32vf103/gd32vf103.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x83,0x57,0x06,0x00,0x13,0x06,0x26,0x00,0x23,0x90,0xf6,0x00,0x83,0x27,0x05,0x00,\n0x13,0xf7,0x17,0x00,0xe3,0x1c,0x07,0xfe,0x93,0xf7,0x47,0x01,0x63,0x98,0x07,0x00,\n0x93,0x85,0xf5,0xff,0x93,0x86,0x26,0x00,0xe3,0x9c,0x05,0xfc,0x73,0x00,0x10,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/k1921vk01t.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Bogdan Kolbov                                   *\n *   kolbov@niiet.ru                                                       *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m4\n\t.thumb\n\t.thumb_func\n\n/* K1921VK01T has 128-bitwidth flash, so it`s able to load 4x32-bit words at the time.\n * And only after all words loaded we can start write\n */\n\n/* Registers addresses */\n#define FLASH_FMA\t0x00\t\t/* Address reg */\n#define FLASH_FMD1\t0x04\t\t/* Data1 reg */\n#define FLASH_FMC\t0x08\t\t/* Command reg */\n#define FLASH_FCIS\t0x0C\t\t/* Operation Status reg */\n#define FLASH_FCIC\t0x14\t\t/* Operation Status Clear reg */\n#define FLASH_FMD2\t0x50\t\t/* Data2 reg */\n#define FLASH_FMD3\t0x54\t\t/* Data3 reg */\n#define FLASH_FMD4\t0x58\t\t/* Data4 reg*/\n\n\t/* Params:\n\t * r0 - write cmd (in), status (out)\n\t * r1 - count\n\t * r2 - workarea start\n\t * r3 - workarea end\n\t * r4 - target address\n\t * Clobbered:\n\t * r5 - rp\n\t * r6 - wp, tmp\n\t * r7 - flash base\n\t */\n\nldr     r7, =#0xA001C000  /* Flash reg base*/\n\nwait_fifo:\n\tldr\t\tr6, [r2, #0]\t/* read wp */\n\tcmp\t\tr6, #0\t\t\t/* abort if wp == 0 */\n\tbeq\t\texit\n\tldr\t\tr5, [r2, #4]\t/* read rp */\n\tcmp\t\tr5, r6\t\t\t/* wait until rp != wp */\n\tbeq\t\twait_fifo\n\n\nload_data:\n\tldr r6, [r5]\t\t\t/* read data1 */\n\tstr r6, [r7, #FLASH_FMD1]\n\tadds\tr5, #4\n\n\tldr r6, [r5]\t\t\t/* read data2 */\n\tstr r6, [r7, #FLASH_FMD2]\n\tadds\tr5, #4\n\n\tldr r6, [r5]\t\t\t/* read data3 */\n\tstr r6, [r7, #FLASH_FMD3]\n\tadds\tr5, #4\n\n\tldr r6, [r5]\t\t\t/* read data4 */\n\tstr r6, [r7, #FLASH_FMD4]\n\tadds\tr5, #4\n\nstart_write:\n\tstr r4, [r7, #FLASH_FMA]\t\t/* set addr */\n\tadds\tr4, #16\n\tstr r0, [r7, #FLASH_FMC]\t\t/* write cmd */\n\nbusy:\n\tldr\t\tr6, [r7, #FLASH_FCIS]\t/* wait until flag set */\n\tcmp\t\tr6, #0x0\n\tbeq\t\tbusy\n\n\tcmp\t\tr6, #2\t\t\t/* check the error bit */\n\tbeq\t\terror\n\n\tmovs\tr6, #1\t\t\t/* clear flags */\n\tstr r6, [r7, #FLASH_FCIC]\n\n\tcmp \tr5, r3\t\t\t/* wrap rp at end of buffer */\n\tbcc\tno_wrap\n\tmov\tr5, r2\n\tadds\tr5, #8\nno_wrap:\n\tstr \tr5, [r2, #4]\t/* store rp */\n\tsubs\tr1, r1, #1\t\t/* decrement 16-byte block count */\n\tcmp     r1, #0\n\tbeq     exit\t\t/* loop if not done */\n\tb\twait_fifo\n\nerror:\n\tmovs\tr0, #0\n\tstr\t\tr0, [r2, #4]\t/* set rp = 0 on error */\nexit:\n\tmov\t\tr0, r6\t\t\t/* return status in r0 */\n\tbkpt\t#0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis/kinetis_flash.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x16,0x68,0x00,0x2e,0x1f,0xd0,0x55,0x68,0xb5,0x42,0xf9,0xd0,0x60,0x60,0x06,0x27,\n0xe7,0x71,0x2f,0x68,0xa7,0x60,0x80,0x27,0x27,0x70,0x04,0x35,0x9d,0x42,0x01,0xd3,\n0x15,0x1c,0x08,0x35,0x55,0x60,0x16,0x68,0x00,0x2e,0x0c,0xd0,0x26,0x78,0x3e,0x42,\n0xf9,0xd0,0x70,0x27,0x3e,0x42,0x04,0xd1,0x04,0x30,0x01,0x39,0x00,0x29,0xdf,0xd1,\n0x01,0xe0,0x00,0x25,0x55,0x60,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis/kinetis_flash.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Ivan Meleca                                     *\n *   ivan@artekit.eu                                                       *\n *                                                                         *\n *   Copyright (C) 2016 by Tomas Vanek                                     *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n\t/* Params:\n\t * r0 = flash destination address in/out\n\t * r1 = longword count\n\t * r2 = workarea start address\n\t * r3 = workarea end address\n\t * r4 = FTFx base\n\t */\n\n\t.text\n\t.cpu cortex-m0plus\n\t.code 16\n\t.thumb_func\n\n\t.align\t2\n\n\t/* r5 = rp\n\t * r6 = wp, tmp\n\t * r7 = tmp\n\t */\n\n\t/* old longword algo: 6.680 KiB/s @ adapter_khz 2000\n\t * this async algo: 19.808 KiB/s @ adapter_khz 2000\n\t */\n\nFTFx_FSTAT =\t0\nFTFx_FCCOB3 =\t4\nFTFx_FCCOB0 =\t7\nFTFx_FCCOB7 =\t8\n\nwait_fifo:\n\tldr \tr6, [r2, #0]\t/* read wp */\n\tcmp \tr6, #0\t\t/* abort if wp == 0 */\n\tbeq \texit\n\n\tldr \tr5, [r2, #4]\t/* read rp */\n\tcmp \tr5, r6\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\n\tstr\tr0, [r4, #FTFx_FCCOB3] /* set flash address */\n\tmov\tr7, #6\n\tstrb\tr7, [r4, #FTFx_FCCOB0] /* flash command */\n\n\tldr\tr7, [r5]\t/* set longword data = *rp */\n\tstr\tr7, [r4, #FTFx_FCCOB7]\n\n\tmov\tr7, #128\n\tstrb\tr7, [r4, #FTFx_FSTAT]\n\n\tadd\tr5, #4\t\t/* rp += 4 */\n\tcmp     r5, r3\t\t/* Wrap? */\n\tbcc     no_wrap\n\tmov     r5, r2\n\tadd   \tr5, #8\n\nno_wrap:\n\tstr     r5, [r2, #4]\t/* Store rp */\n\nwait_ccif:\n\tldr     r6, [r2, #0]    /* read wp */\n\tcmp     r6, #0          /* abort if wp == 0 */\n\tbeq     exit\n\n\tldrb\tr6, [r4, #FTFx_FSTAT]\n\ttst\tr6, r7\n\tbeq\twait_ccif\n\n\tmov\tr7, #0x70\n\ttst\tr6, r7\n\tbne\terror\n\n\tadd\tr0, #4\t\t/* flash address += 4, do not increment before err check */\n\n\tsub\tr1, #1\t\t/* word_count-- */\n\tcmp\tr1, #0\n\tbne\twait_fifo\n\tb\texit\n\nerror:\n\tmov\tr5, #0\n\tstr     r5, [r2, #4]    /* set rp = 0 on error */\n\nexit:\n\tbkpt    #0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x16,0x68,0x00,0x2e,0xfe,0xd0,0x55,0x68,0xb5,0x42,0xf9,0xd0,0x2f,0x4e,0x30,0x27,\n0x37,0x70,0x2f,0x4e,0x00,0x27,0x37,0x70,0x2e,0x4e,0x06,0x27,0x37,0x70,0x07,0x0c,\n0x2d,0x4e,0x37,0x70,0x2a,0x4e,0x01,0x27,0x37,0x70,0xc7,0xb2,0x2a,0x4e,0x37,0x70,\n0x07,0x0a,0x28,0x4e,0x37,0x70,0x26,0x4e,0x02,0x27,0x37,0x70,0x6f,0x78,0x25,0x4e,\n0x37,0x70,0x2f,0x78,0x24,0x4e,0x37,0x70,0x21,0x4e,0x03,0x27,0x37,0x70,0xef,0x78,\n0x20,0x4e,0x37,0x70,0xaf,0x78,0x20,0x4e,0x37,0x70,0x01,0x39,0x04,0x30,0x04,0x35,\n0x9d,0x42,0x01,0xd3,0x15,0x1c,0x08,0x35,0x00,0x29,0x1b,0xd0,0x16,0x68,0xae,0x42,\n0x18,0xd0,0x17,0x4e,0x04,0x27,0x37,0x70,0x6f,0x78,0x16,0x4e,0x37,0x70,0x2f,0x78,\n0x15,0x4e,0x37,0x70,0x12,0x4e,0x05,0x27,0x37,0x70,0xef,0x78,0x11,0x4e,0x37,0x70,\n0xaf,0x78,0x11,0x4e,0x37,0x70,0x01,0x39,0x04,0x30,0x04,0x35,0x9d,0x42,0x01,0xd3,\n0x15,0x1c,0x08,0x35,0x09,0x4e,0x80,0x27,0x37,0x70,0x08,0x4e,0x36,0x78,0x3e,0x42,\n0xfb,0xd0,0x30,0x27,0x3e,0x42,0x04,0xd1,0x00,0x26,0x55,0x60,0x00,0x29,0x02,0xd0,\n0x9e,0xe7,0x00,0x20,0x50,0x60,0x30,0x1c,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Ivan Meleca                                     *\n *   ivan@artekit.eu                                                       *\n ***************************************************************************/\n\n\t/* Params:\n\t * r0 = flash destination address, status\n\t * r1 = longword count\n\t * r2 = workarea start address\n\t * r3 = workarea end address\n\t */\n\n\t.text\n\t.cpu cortex-m0plus\n\t.code 16\n\t.thumb_func\n\n\t.align\t2\n\n\t/* r5 = rp\n\t * r6 = wp, tmp\n\t * r7 = tmp\n\t */\n\nwait_fifo:\n\tldr \tr6, [r2, #0]\t/* read wp */\n\tcmp \tr6, #0\t\t\t/* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr5, [r2, #4]\t/* read rp */\n\tcmp \tr5, r6\t\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\n\tldr\t\tr6, fstat\t\t/* Clear error flags */\n\tmov\t\tr7, #48\n\tstrb\tr7, [r6]\n\n\tldr\t\tr6, fccobix\t\t/* FCCOBIX = 0 */\n\tmov\t\tr7, #0\n\tstrb\tr7, [r6]\n\n\tldr \tr6, fccobhi\t\t/* Program FLASH command */\n\tmov\t\tr7, #6\t\t\t/* FCCOBHI = 6 */\n\tstrb\tr7, [r6]\n\n\tlsr\t\tr7, r0, #16\t\t/* FCCOBLO = flash destination address >> 16 */\n\tldr\t\tr6, fccoblo\n\tstrb\tr7, [r6]\n\n\tldr\t\tr6, fccobix\t\t/* Index for lower byte address bits[15:0] */\n\tmov\t\tr7, #1\n\tstrb\tr7, [r6]\t\t/* FCCOBIX = 1*/\n\n\tuxtb\tr7, r0\t\t\t/* Memory address bits[15:0] */\n\tldr \tr6, fccoblo\n\tstrb\tr7, [r6]\t\t/* FCCOBLO = flash destination address */\n\n\tlsr\t\tr7, r0, #8\n\tldr\t\tr6, fccobhi\n\tstrb\tr7, [r6]\t\t/* FCCOBHI = flash destination address >> 8 */\n\n\tldr\t\tr6, fccobix\t\t/* FCCOBIX = 2 */\n\tmov\t\tr7, #2\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #1]\t/* FCCOBHI = rp >> 8 */\n\tldr\t\tr6, fccobhi\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5]\t\t/* FCCOBLO = rp */\n\tldr \tr6, fccoblo\n\tstrb\tr7, [r6]\n\n\tldr\t\tr6, fccobix\t\t/* FCCOBIX = 3 */\n\tmov\t\tr7, #3\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #3]\t/* FCCOBHI = rp >> 24 */\n\tldr\t\tr6, fccobhi\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #2]\t/* FCCOBLO = rp >> 16 */\n\tldr\t\tr6, fccoblo\n\tstrb\tr7, [r6]\n\n\tsub\t\tr1, r1, #1\t\t/* Two words (4 bytes) queued, decrement counter */\n\tadd\t\tr0, r0, #4\t\t/* flash address += 4 */\n\tadd\t\tr5, r5, #4\t\t/* rp += 4 */\n\n\tcmp     r5, r3\t\t\t/* Wrap? */\n\tbcc     no_wrap\n\tmov     r5, r2\n\tadd   \tr5, r5, #8\n\nno_wrap:\n\tcmp\t\tr1, #0\t\t\t/* Done? */\n\tbeq\t\texecute\n\n\tldr \tr6, [r2, #0]\t/* read wp */\n\tcmp \tr6, r5\n\tbeq\t\texecute\t\t\t/* execute if rp == wp */\n\n\tldr\t\tr6, fccobix\t\t/* FCCOBIX = 4 */\n\tmov\t\tr7, #4\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #1]\t/* FCCOBHI = rp >> 8 */\n\tldr\t\tr6, fccobhi\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5]\t\t/* FCCOBLO = rp */\n\tldr \tr6, fccoblo\n\tstrb\tr7, [r6]\n\n\tldr\t\tr6, fccobix\t\t/* FCCOBIX = 5 */\n\tmov\t\tr7, #5\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #3]\t/* FCCOBHI = rp >> 24 */\n\tldr\t\tr6, fccobhi\n\tstrb\tr7, [r6]\n\n\tldrb\tr7, [r5, #2]\t/* FCCOBLO = rp >> 16 */\n\tldr\t\tr6, fccoblo\n\tstrb\tr7, [r6]\n\n\tsub\t\tr1, r1, #1\t\t/* Two words (4 bytes) queued, decrement counter */\n\tadd\t\tr0, r0, #4\t\t/* flash address += 4 */\n\tadd\t\tr5, r5, #4\t\t/* rp += 4 */\n\n\tcmp     r5, r3\t\t\t/* Wrap? */\n\tbcc     execute\n\tmov     r5, r2\n\tadd   \tr5, r5, #8\n\nexecute:\n\tldr\t\tr6, fstat\t\t/* Launch the command */\n\tmov\t\tr7, #128\n\tstrb\tr7, [r6]\n\nwait_busy:\n\tldr\t\tr6, fstat\n\tldrb\tr6, [r6]\t\t/* Wait until finished */\n\ttst\t\tr6, r7\n\tbeq\t\twait_busy\n\n\tmov\t\tr7, #48\t\t\t/* Check error */\n\ttst\t\tr6, r7\n\tbne\t\terror\n\n\tmov\t\tr6, #0\t\t\t/* Clear error */\n\n\tstr     r5, [r2, #4]\t/* Store rp */\n\n\tcmp\t\tr1, #0\t\t\t/* Done? */\n\tbeq\t\tdone\n\tb\t\twait_fifo\n\nerror:\n\tmov\t\tr0, #0\n\tstr     r0, [r2, #4]    /* set rp = 0 on error */\n\ndone:\n\tmov\t\tr0, r6\t\t\t/* Set result code */\n\tbkpt    #0\n\n\t.align\t2\nfstat:\n\t.word\t0\nfccobix:\n\t.word\t0\nfccobhi:\n\t.word\t0\nfccoblo:\n\t.word\t0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x07,0x4b,0x7f,0x22,0x1d,0x78,0x5c,0x78,0x2a,0x40,0x06,0x4d,0x98,0x88,0xd9,0x88,\n0x5d,0x80,0x05,0x4d,0x5d,0x80,0x5c,0x70,0x98,0x80,0xd9,0x80,0x1a,0x70,0x00,0xbe,\n0x00,0x20,0x05,0x40,0xc5,0x20,0x00,0x00,0xd9,0x28,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Ivan Meleca                                     *\n *   ivan@artekit.eu                                                       *\n ***************************************************************************/\n\n\t.text\n\t.cpu cortex-m0plus\n\t.code 16\n\t.thumb_func\n\n\t.align\t2\n\n\tldr\t\tr3, wdog_cs1\n\tmov\t\tr2, #127\n\tldrb\tr5, [r3]\n\tldrb\tr4, [r3, #1]\n\tand\t\tr2, r5\n\tldr\t\tr5, unlock1\n\tldrh\tr0, [r3, #4]\n\tldrh\tr1, [r3, #6]\n\tstrh\tr5, [r3, #2]\n\tldr\t\tr5, unlock2\n\tstrh\tr5, [r3, #2]\n\tstrb\tr4, [r3, #1]\n\tstrh\tr0, [r3, #4]\n\tstrh\tr1, [r3, #6]\n\tstrb\tr2, [r3]\n\tbkpt\t#0\n\n\t.align\t2\n\nwdog_cs1:\n\t.word\t0x40052000\t// Watchdog Control and Status Register 1\nunlock1:\n\t.word\t0x20C5\t\t// 1st unlock word\nunlock2:\n\t.word\t0x28D9\t\t// 2nd unlock word\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/lpcspifi_erase.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m3\n\t.thumb\n\t.thumb_func\n\n/*\n * Params :\n * r0 = start address, status (out)\n * r1 = count\n * r2 = erase command\n * r3 = block size\n */\n\n#define SSP_BASE_HIGH\t\t\t\t0x4008\n#define SSP_BASE_LOW\t\t\t\t0x3000\n#define SSP_CR0_OFFSET\t\t\t\t0x00\n#define SSP_CR1_OFFSET\t\t\t\t0x04\n#define SSP_DATA_OFFSET \t\t\t0x08\n#define SSP_CPSR_OFFSET \t\t\t0x10\n#define SSP_SR_OFFSET\t\t\t\t0x0c\n\n#define SSP_CLOCK_BASE_HIGH \t\t0x4005\n#define SSP_CLOCK_BASE_LOW \t\t\t0x0000\n#define SSP_BRANCH_CLOCK_BASE_HIGH \t0x4005\n#define SSP_BRANCH_CLOCK_BASE_LOW\t0x2000\n#define SSP_BASE_CLOCK_OFFSET\t\t0x94\n#define SSP_BRANCH_CLOCK_OFFSET\t\t0x700\n\n#define IOCONFIG_BASE_HIGH\t\t\t0x4008\n#define IOCONFIG_BASE_LOW\t\t\t0x6000\n#define IOCONFIG_SCK_OFFSET\t\t\t0x18c\n#define IOCONFIG_HOLD_OFFSET\t\t0x190\n#define IOCONFIG_WP_OFFSET\t\t\t0x194\n#define IOCONFIG_MISO_OFFSET\t\t0x198\n#define IOCONFIG_MOSI_OFFSET\t\t0x19c\n#define IOCONFIG_CS_OFFSET\t\t\t0x1a0\n\n#define IO_BASE_HIGH \t\t\t\t0x400f\n#define IO_BASE_LOW \t\t\t\t0x4000\n#define IO_CS_OFFSET \t\t\t\t0xab\n#define IODIR_BASE_HIGH \t\t\t0x400f\n#define IODIR_BASE_LOW\t\t\t\t0x6000\n#define IO_CS_DIR_OFFSET \t\t\t0x14\n\n\nsetup: /* Initialize SSP pins and module */\n\tmov.w\tr10, #IOCONFIG_BASE_LOW\n\tmovt\tr10, #IOCONFIG_BASE_HIGH\n\tmov.w\tr8, #0xea\n\tstr.w\tr8, [r10, #IOCONFIG_SCK_OFFSET]\t\t/* Configure SCK pin function */\n\tmov.w\tr8, #0x40\n\tstr.w\tr8, [r10, #IOCONFIG_HOLD_OFFSET]\t/* Configure /HOLD pin function */\n\tmov.w\tr8, #0x40\n\tstr.w\tr8, [r10, #IOCONFIG_WP_OFFSET]\t\t/* Configure /WP pin function */\n\tmov.w\tr8, #0xed\n\tstr.w\tr8, [r10, #IOCONFIG_MISO_OFFSET]\t/* Configure MISO pin function */\n\tmov.w\tr8, #0xed\n\tstr.w\tr8, [r10, #IOCONFIG_MOSI_OFFSET]\t/* Configure MOSI pin function */\n\tmov.w\tr8, #0x44\n\tstr.w\tr8, [r10, #IOCONFIG_CS_OFFSET]\t\t/* Configure CS pin function */\n\n\tmov.w\tr10, #IODIR_BASE_LOW\n\tmovt\tr10, #IODIR_BASE_HIGH\n\tmov.w\tr8, #0x800\n\tstr \tr8, [r10, #IO_CS_DIR_OFFSET]\t\t/* Set CS as output */\n\tmov.w\tr10, #IO_BASE_LOW\n\tmovt\tr10, #IO_BASE_HIGH\n\tmov.w\tr8, #0xff\n\tstr.w\tr8, [r10, #IO_CS_OFFSET]\t\t\t/* Set CS high */\n\n\tmov.w \tr10, #SSP_CLOCK_BASE_LOW\n\tmovt \tr10, #SSP_CLOCK_BASE_HIGH\n\tmov.w \tr8, #0x0000\n\tmovt \tr8, #0x0100\n\tstr.w \tr8, [r10, #SSP_BASE_CLOCK_OFFSET] \t/* Configure SSP0 base clock (use 12 MHz IRC) */\n\n\tmov.w \tr10, #SSP_BRANCH_CLOCK_BASE_LOW\n\tmovt \tr10, #SSP_BRANCH_CLOCK_BASE_HIGH\n\tmov.w \tr8, #0x01\n\tstr.w \tr8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */\n\n\tmov.w \tr10, #SSP_BASE_LOW\n\tmovt\tr10, #SSP_BASE_HIGH\n\tmov.w \tr8, #0x07\n\tstr.w \tr8, [r10, #SSP_CR0_OFFSET] \t\t\t/* Set clock postscale */\n\tmov.w \tr8, #0x02\n\tstr.w \tr8, [r10, #SSP_CPSR_OFFSET] \t\t/* Set clock prescale */\n\tstr.w \tr8, [r10, #SSP_CR1_OFFSET] \t\t\t/* Enable SSP in SPI mode */\nwrite_enable:\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x06 \t\t/* Send the write enable command */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x05 \t\t/* Get status register */\n\tbl \t\twrite_data\n\tmov.w \tr9, #0x00 \t\t/* Dummy data to clock in status */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\n\ttst \tr9, #0x02 \t\t/* If the WE bit isn't set, we have a problem. */\n\tbeq \terror\nerase:\n\tbl \t\tcs_down\n\tmov.w \tr9, r2 \t\t\t/* Send the erase command */\n\tbl \t\twrite_data\nwrite_address:\n\tlsr \tr9, r0, #16 \t/* Send the current 24-bit write address, MSB first */\n\tbl \t\twrite_data\n\tlsr \tr9, r0, #8\n\tbl \t\twrite_data\n\tmov.w \tr9, r0\n\tbl \t\twrite_data\n\tbl \t\tcs_up\nwait_flash_busy:\t\t\t/* Wait for the flash to finish the previous erase */\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x05 \t\t/* Get status register */\n\tbl \t\twrite_data\n\tmov.w \tr9, #0x00 \t\t/* Dummy data to clock in status */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\ttst \tr9, #0x01 \t\t/* If it isn't done, keep waiting */\n\tbne \twait_flash_busy\n\n\tsubs\tr1, r1, #1\t\t\t\t\t/* decrement count */\n\tcbz\t\tr1, exit \t\t\t\t\t/* Exit if we have written everything */\n\tadd \tr0, r3\t\t\t\t\t\t/* Move the address up by the block size */\n\tb \t\twrite_enable \t\t\t\t/* Start a new block erase */\nwrite_data: \t\t\t\t\t\t\t/* Send/receive 1 byte of data over SSP */\n\tmov.w\tr10, #SSP_BASE_LOW\n\tmovt\tr10, #SSP_BASE_HIGH\n\tstr.w \tr9, [r10, #SSP_DATA_OFFSET]\t/* Write supplied data to the SSP data reg */\nwait_transmit:\n\tldr \tr9, [r10, #SSP_SR_OFFSET] \t/* Check SSP status */\n\ttst \tr9, #0x0010\t\t\t\t\t/* Check if BSY bit is set */\n\tbne \twait_transmit \t\t\t\t/* If still transmitting, keep waiting */\n\tldr \tr9, [r10, #SSP_DATA_OFFSET]\t/* Load received data */\n\tbx \t\tlr \t\t\t\t\t\t\t/* Exit subroutine */\ncs_up:\n\tmov.w \tr8, #0xff\n\tb \t\tcs_write\ncs_down:\n\tmov.w \tr8, #0x0000\ncs_write:\n\tmov.w \tr10, #IO_BASE_LOW\n\tmovt\tr10, #IO_BASE_HIGH\n\tstr.w \tr8, [r10, #IO_CS_OFFSET]\n\tbx \t\tlr\nerror:\n\tmovs\tr0, #0\nexit:\n\tbkpt \t#0x00\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/lpcspifi_init.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2012 by George Harris  \t\t                           *\n *   george@luminairecoffee.com                                            *\n ***************************************************************************/\n\n/***************************************************************************\n*\tThis is an algorithm for the LPC43xx family (and probably the LPC18xx  *\n*\tfamily as well, though they have not been tested) that will initialize *\n*\tmemory-mapped SPI flash accesses. Unfortunately NXP has published      *\n*\tneither the ROM source code that performs this initialization nor the  *\n*\tregister descriptions necessary to do so, so this code is necessary to *\n*\tcall into the ROM SPIFI API.                                           *\n***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.arch armv7-m\n\t.thumb\n\t.thumb_func\n\n\t.align 2\n\n/*\n * Params :\n * r0 = spifi clock speed\n */\n\n#define IOCONFIG_BASE_HIGH          0x4008\n#define IOCONFIG_BASE_LOW           0x6000\n#define IOCONFIG_SCK_OFFSET         0x18c\n#define IOCONFIG_HOLD_OFFSET        0x190\n#define IOCONFIG_WP_OFFSET          0x194\n#define IOCONFIG_MISO_OFFSET        0x198\n#define IOCONFIG_MOSI_OFFSET        0x19c\n#define IOCONFIG_CS_OFFSET          0x1a0\n\n#define SPIFI_ROM_TABLE_BASE_HIGH   0x1040\n#define SPIFI_ROM_TABLE_BASE_LOW    0x0118\n\ncode:\n\tmov.w \tr8, r0\n\tsub\t\tsp, #0x84\n\tadd\t\tr7, sp, #0x0\n\t/* Initialize SPIFI pins */\n\tmov.w\tr3, #IOCONFIG_BASE_LOW\n\tmovt\tr3, #IOCONFIG_BASE_HIGH\n\tmov.w\tr2, #0xf3\n\tstr.w \tr2, [r3, #IOCONFIG_SCK_OFFSET]\n\tmov.w\tr3, #IOCONFIG_BASE_LOW\n\tmovt\tr3, #IOCONFIG_BASE_HIGH\n\tmov.w\tr2, #IOCONFIG_BASE_LOW\n\tmovt\tr2, #IOCONFIG_BASE_HIGH\n\tmov.w\tr1, #IOCONFIG_BASE_LOW\n\tmovt\tr1, #IOCONFIG_BASE_HIGH\n\tmov.w\tr0, #IOCONFIG_BASE_LOW\n\tmovt\tr0, #IOCONFIG_BASE_HIGH\n\tmov.w\tr4, #0xd3\n\tstr.w\tr4, [r0, #IOCONFIG_MOSI_OFFSET]\n\tmov\tr0, r4\n\tstr.w\tr0, [r1, #IOCONFIG_MISO_OFFSET]\n\tmov\tr1, r0\n\tstr.w\tr1, [r2, #IOCONFIG_WP_OFFSET]\n\tstr.w\tr1, [r3, #IOCONFIG_HOLD_OFFSET]\n\tmov.w\tr3, #IOCONFIG_BASE_LOW\n\tmovt\tr3, #IOCONFIG_BASE_HIGH\n\tmov.w\tr2, #0x13\n\tstr.w\tr2, [r3, #IOCONFIG_CS_OFFSET]\n\n\t/* Perform SPIFI init. See spifi_rom_api.h (in NXP lpc43xx driver package) for details */\n\t/* on initialization arguments. */\n\tmovw \tr3, #SPIFI_ROM_TABLE_BASE_LOW      /* The ROM API table is located @ 0x10400118, and\t\t\t*/\n\tmovt \tr3, #SPIFI_ROM_TABLE_BASE_HIGH     /* the first pointer in the struct is to the init function. */\n\tldr \tr3, [r3, #0x0]\n\tldr \tr4, [r3, #0x0]\t\t                 /* Grab the init function pointer from the table */\n\t/* Set up function arguments */\n\tmovw \tr0, #0x3b4\n\tmovt \tr0, #0x1000\t\t    \t              /* Pointer to a SPIFI data struct that we don't care about */\n\tmov.w \tr1, #0x3                        /* \"csHigh\". Not 100% sure what this does. */\n\tmov.w \tr2, #0xc0 \t\t\t              /* The configuration word: S_RCVCLOCK | S_FULLCLK */\n\tmov.w \tr3, r8 \t\t\t\t              /* SPIFI clock speed (12MHz) */\n\tblx \tr4\t\t\t\t\t                    /* Call the init function */\n\tb \t\tdone\n\ndone:\n\tbkpt \t#0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/lpcspifi_write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m3\n\t.thumb\n\t.thumb_func\n\n/*\n * Params :\n * r0 = workarea start, status (out)\n * r1 = workarea end\n * r2 = target address (offset from flash base)\n * r3 = count (bytes)\n * r4 = page size\n * Clobbered:\n * r7 - rp\n * r8 - wp, tmp\n * r9 - send/receive data\n * r10 - temp\n * r11 - current page end address\n */\n\n/*\n * This code is embedded within: src/flash/nor/lpcspifi.c as a \"C\" array.\n *\n * To rebuild:\n *   arm-none-eabi-gcc -c lpcspifi_write.S\n *   arm-none-eabi-objcopy -O binary lpcspifi_write.o lpcspifi_write.bin\n *   xxd -c 8 -i lpcspifi_write.bin > lpcspifi_write.txt\n *\n * Then read and edit this result into the \"C\" source.\n */\n\n#define SSP_BASE_HIGH\t\t\t\t0x4008\n#define SSP_BASE_LOW\t\t\t\t0x3000\n#define SSP_CR0_OFFSET\t\t\t\t0x00\n#define SSP_CR1_OFFSET\t\t\t\t0x04\n#define SSP_DATA_OFFSET \t\t\t0x08\n#define SSP_CPSR_OFFSET \t\t\t0x10\n#define SSP_SR_OFFSET\t\t\t\t0x0c\n\n#define SSP_CLOCK_BASE_HIGH \t\t0x4005\n#define SSP_CLOCK_BASE_LOW \t\t\t0x0000\n#define SSP_BRANCH_CLOCK_BASE_HIGH \t0x4005\n#define SSP_BRANCH_CLOCK_BASE_LOW\t0x2000\n#define SSP_BASE_CLOCK_OFFSET\t\t0x94\n#define SSP_BRANCH_CLOCK_OFFSET\t\t0x700\n\n#define IOCONFIG_BASE_HIGH\t\t\t0x4008\n#define IOCONFIG_BASE_LOW\t\t\t0x6000\n#define IOCONFIG_SCK_OFFSET\t\t\t0x18c\n#define IOCONFIG_HOLD_OFFSET\t\t0x190\n#define IOCONFIG_WP_OFFSET\t\t\t0x194\n#define IOCONFIG_MISO_OFFSET\t\t0x198\n#define IOCONFIG_MOSI_OFFSET\t\t0x19c\n#define IOCONFIG_CS_OFFSET\t\t\t0x1a0\n\n#define IO_BASE_HIGH \t\t\t\t0x400f\n#define IO_BASE_LOW \t\t\t\t0x4000\n#define IO_CS_OFFSET \t\t\t\t0xab\n#define IODIR_BASE_HIGH \t\t\t0x400f\n#define IODIR_BASE_LOW\t\t\t\t0x6000\n#define IO_CS_DIR_OFFSET \t\t\t0x14\n\n\nsetup: /* Initialize SSP pins and module */\n\tmov.w\tr10, #IOCONFIG_BASE_LOW\n\tmovt\tr10, #IOCONFIG_BASE_HIGH\n\tmov.w\tr8, #0xea\n\tstr.w\tr8, [r10, #IOCONFIG_SCK_OFFSET]\t\t/* Configure SCK pin function */\n\tmov.w\tr8, #0x40\n\tstr.w\tr8, [r10, #IOCONFIG_HOLD_OFFSET]\t/* Configure /HOLD pin function */\n\tmov.w\tr8, #0x40\n\tstr.w\tr8, [r10, #IOCONFIG_WP_OFFSET]\t\t/* Configure /WP pin function */\n\tmov.w\tr8, #0xed\n\tstr.w\tr8, [r10, #IOCONFIG_MISO_OFFSET]\t/* Configure MISO pin function */\n\tmov.w\tr8, #0xed\n\tstr.w\tr8, [r10, #IOCONFIG_MOSI_OFFSET]\t/* Configure MOSI pin function */\n\tmov.w\tr8, #0x44\n\tstr.w\tr8, [r10, #IOCONFIG_CS_OFFSET]\t\t/* Configure CS pin function */\n\n\tmov.w\tr10, #IODIR_BASE_LOW\n\tmovt\tr10, #IODIR_BASE_HIGH\n\tmov.w\tr8, #0x800\n\tstr \tr8, [r10, #IO_CS_DIR_OFFSET]\t\t/* Set CS as output */\n\tmov.w\tr10, #IO_BASE_LOW\n\tmovt\tr10, #IO_BASE_HIGH\n\tmov.w\tr8, #0xff\n\tstr.w\tr8, [r10, #IO_CS_OFFSET]\t\t\t/* Set CS high */\n\n\tmov.w \tr10, #SSP_CLOCK_BASE_LOW\n\tmovt \tr10, #SSP_CLOCK_BASE_HIGH\n\tmov.w \tr8, #0x0000\n\tmovt \tr8, #0x0100\n\tstr.w \tr8, [r10, #SSP_BASE_CLOCK_OFFSET] \t/* Configure SSP0 base clock (use 12 MHz IRC) */\n\n\tmov.w \tr10, #SSP_BRANCH_CLOCK_BASE_LOW\n\tmovt \tr10, #SSP_BRANCH_CLOCK_BASE_HIGH\n\tmov.w \tr8, #0x01\n\tstr.w \tr8, [r10, #SSP_BRANCH_CLOCK_OFFSET] /* Configure (enable) SSP0 branch clock */\n\n\tmov.w \tr10, #SSP_BASE_LOW\n\tmovt\tr10, #SSP_BASE_HIGH\n\tmov.w \tr8, #0x07\n\tstr.w \tr8, [r10, #SSP_CR0_OFFSET] \t\t\t/* Set clock postscale */\n\tmov.w \tr8, #0x02\n\tstr.w \tr8, [r10, #SSP_CPSR_OFFSET] \t\t/* Set clock prescale */\n\tstr.w \tr8, [r10, #SSP_CR1_OFFSET] \t\t\t/* Enable SSP in SPI mode */\n\n\tmov.w \tr11, #0x00\nfind_next_page_boundary:\n\tadd \tr11, r4\t\t\t/* Increment to the next page */\n\tcmp \tr11, r2\n\t/* If we have not reached the next page boundary after the target address, keep going */\n\tbls \tfind_next_page_boundary\nwrite_enable:\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x06 \t\t/* Send the write enable command */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x05 \t\t/* Get status register */\n\tbl \t\twrite_data\n\tmov.w \tr9, #0x00 \t\t/* Dummy data to clock in status */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\n\ttst \tr9, #0x02 \t\t/* If the WE bit isn't set, we have a problem. */\n\tbeq \terror\npage_program:\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x02 \t\t/* Send the page program command */\n\tbl \t\twrite_data\nwrite_address:\n\tlsr \tr9, r2, #16 \t/* Send the current 24-bit write address, MSB first */\n\tbl \t\twrite_data\n\tlsr \tr9, r2, #8\n\tbl \t\twrite_data\n\tmov.w \tr9, r2\n\tbl \t\twrite_data\nwait_fifo:\n\tldr \tr8, [r0]  \t\t/* read the write pointer */\n\tcmp \tr8, #0 \t\t\t/* if it's zero, we're gonzo */\n\tbeq \texit\n\tldr \tr7, [r0, #4] \t/* read the read pointer */\n\tcmp \tr7, r8 \t\t\t/* wait until they are not equal */\n\tbeq \twait_fifo\nwrite:\n\tldrb \tr9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */\n\tbl \t\twrite_data \t\t/* send the byte to the flash chip */\n\n\tcmp \tr7, r1\t\t\t/* wrap the read pointer if it is at the end */\n\tit  \tcs\n\taddcs\tr7, r0, #8\t\t/* skip loader args */\n\tstr \tr7, [r0, #4]\t/* store the new read pointer */\n\tsubs\tr3, r3, #1\t\t/* decrement count */\n\tcbz\t\tr3, exit \t\t/* Exit if we have written everything */\n\n\tadd \tr2, #1 \t\t\t/* Increment flash address by 1 */\n\tcmp \tr11, r2   \t\t/* See if we have reached the end of a page */\n\tbne \twait_fifo \t\t/* If not, keep writing bytes */\n\tbl \t\tcs_up\t\t\t/* Otherwise, end the command and keep going w/ the next page */\n\tadd \tr11, r4 \t\t/* Move up the end-of-page address by the page size*/\nwait_flash_busy:\t\t\t/* Wait for the flash to finish the previous page write */\n\tbl \t\tcs_down\n\tmov.w \tr9, #0x05 \t\t\t\t\t/* Get status register */\n\tbl \t\twrite_data\n\tmov.w \tr9, #0x00 \t\t\t\t\t/* Dummy data to clock in status */\n\tbl \t\twrite_data\n\tbl \t\tcs_up\n\ttst \tr9, #0x01 \t\t\t\t\t/* If it isn't done, keep waiting */\n\tbne \twait_flash_busy\n\tb \t\twrite_enable \t\t\t\t/* If it is done, start a new page write */\nwrite_data: \t\t\t\t\t\t\t/* Send/receive 1 byte of data over SSP */\n\tmov.w\tr10, #SSP_BASE_LOW\n\tmovt\tr10, #SSP_BASE_HIGH\n\tstr.w \tr9, [r10, #SSP_DATA_OFFSET]\t/* Write supplied data to the SSP data reg */\nwait_transmit:\n\tldr \tr9, [r10, #SSP_SR_OFFSET] \t/* Check SSP status */\n\ttst \tr9, #0x0010\t\t\t\t\t/* Check if BSY bit is set */\n\tbne \twait_transmit \t\t\t\t/* If still transmitting, keep waiting */\n\tldr \tr9, [r10, #SSP_DATA_OFFSET]\t/* Load received data */\n\tbx \t\tlr \t\t\t\t\t\t\t/* Exit subroutine */\ncs_up:\n\tmov.w \tr8, #0xff\n\tb \t\tcs_write\ncs_down:\n\tmov.w \tr8, #0x0000\ncs_write:\n\tmov.w \tr10, #IO_BASE_LOW\n\tmovt\tr10, #IO_BASE_HIGH\n\tstr.w \tr8, [r10, #IO_CS_OFFSET]\n\tbx \t\tlr\nerror:\n\tmovs\tr0, #0\n\tstr \tr0, [r2, #4]\t/* set rp = 0 on error */\nexit:\n\tbl \t\tcs_up\t\t\t/* end the command before returning */\n\tmov \tr0, r6\n\tbkpt \t#0x00\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/max32xxx/max32xxx.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xdf,0xf8,0x44,0x40,0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x1a,0xd0,0x47,0x68,\n0x47,0x45,0xf7,0xd0,0x22,0x60,0x02,0xf1,0x04,0x02,0x57,0xf8,0x04,0x8b,0xc4,0xf8,\n0x30,0x80,0xa5,0x68,0x45,0xf0,0x01,0x05,0xa5,0x60,0xd4,0xf8,0x08,0x80,0x18,0xf0,\n0x01,0x0f,0xfa,0xd1,0x8f,0x42,0x28,0xbf,0x00,0xf1,0x08,0x07,0x47,0x60,0x01,0x3b,\n0x03,0xb1,0xdf,0xe7,0x00,0xbe,0x00,0xbf,0x00,0x00,0x00,0x40,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/max32xxx/max32xxx.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 by Maxim Integrated                                *\n *   Kevin Gillespie <kevin.gillespie@maximintegrated.com                  *\n ***************************************************************************/\n\n.text\n.syntax unified\n.cpu cortex-m3\n.thumb\n.thumb_func\n\n/*\n * Params :\n * r0 = workarea start\n * r1 = workarea end\n * r2 = target address\n * r3 = count (32bit words)\n * r4 = pFLASH_CTRL_BASE\n *\n * Clobbered:\n * r5 = FLASHWRITECMD\n * r7 - rp\n * r8 - wp, tmp\n */\n\nwrite:\n\nwait_fifo:\nldr \tr8, [r0, #0]\t/* read wp */\ncmp \tr8, #0\t\t\t/* abort if wp == 0 */\nbeq \texit\nldr \tr7, [r0, #4]\t/* read rp */\ncmp \tr7, r8\t\t\t/* wait until rp != wp */\nbeq \twait_fifo\n\nmainloop:\nstr\t\tr2, [r4, #0x00]\t/* FLSH_ADDR - write address */\nadd\t\tr2, r2, #4\t\t/* increment target address */\nldr\t\tr8, [r7], #4\nstr\t\tr8, [r4, #0x30]\t/* FLSH_DATA0 - write data */\nldr\t\tr5, [r4, #0x08]\t/* FLSH_CN */\norr\t\tr5, r5, #1\nstr\t\tr5, [r4, #0x08]\t/* FLSH_CN - enable write */\nbusy:\nldr\t\tr8, [r4, #0x08]\t/* FLSH_CN */\ntst\t\tr8, #1\nbne\t\tbusy\n\ncmp \tr7, r1\t\t\t/* wrap rp at end of buffer */\nit  \tcs\naddcs\tr7, r0, #8\t\t/* skip loader args */\nstr \tr7, [r0, #4]\t/* store rp */\nsubs\tr3, r3, #1\t\t/* decrement word count */\ncbz \tr3, exit\t\t/* loop if not done */\nb\t\twait_fifo\nexit:\nbkpt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/mdr32fx.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *                                                                         *\n *   Copyright (C) 2013 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\t.global write\n\n\t/* Params:\n\t * r0 - flash base (in), status (out)\n\t * r1 - count (32bit)\n\t * r2 - workarea start\n\t * r3 - workarea end\n\t * r4 - target address\n\t * Clobbered:\n\t * r5 - rp\n\t * r6 - wp, tmp\n\t * r7 - current FLASH_CMD\n\t */\n\n#define FLASH_CMD\t0x00\n#define FLASH_ADR\t0x04\n#define FLASH_DI\t0x08\n\n#define FLASH_NVSTR\t(1 << 13)\n#define FLASH_PROG\t(1 << 12)\n#define FLASH_MAS1\t(1 << 11)\n#define FLASH_ERASE\t(1 << 10)\n#define FLASH_SE\t(1 << 8)\n#define FLASH_YE\t(1 << 7)\n#define FLASH_XE\t(1 << 6)\n\n\tldr\tr7, [r0, #FLASH_CMD]\nwait_fifo:\n\tldr \tr6, [r2, #0]\t/* read wp */\n\tcmp \tr6, #0\t\t\t/* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr5, [r2, #4]\t/* read rp */\n\tcmp \tr5, r6\t\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\n\tldr\tr6, [r5]\t/* \"*target_address++ = *rp++\" */\n\tstr\tr4, [r0, #FLASH_ADR]\n\tstr\tr6, [r0, #FLASH_DI]\n\n\tldr\tr6, =(FLASH_XE | FLASH_PROG)\n\torrs\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\t# wait 5us\n\tmovs\tr6, #5\n\tbl\tdelay\n\tldr\tr6, =#FLASH_NVSTR\n\torrs\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\t# wait 10us\n\tmovs\tr6, #13\n\tbl\tdelay\n\tmovs\tr6, #FLASH_YE\n\torrs\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\t# wait 40us\n\tmovs\tr6, #61\n\tbl\tdelay\n\tmovs\tr6, #FLASH_YE\n\tbics\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\tldr\tr6, =#FLASH_PROG\n\tbics\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\t# wait 5us\n\tmovs\tr6, #5\n\tbl\tdelay\n\tldr\tr6, =#(FLASH_XE | FLASH_NVSTR)\n\tbics\tr7, r7, r6\n\tstr\tr7, [r0, #FLASH_CMD]\n\n\tadds\tr5, #4\n\tadds\tr4, #4\n\n\tcmp \tr5, r3\t\t\t/* wrap rp at end of buffer */\n\tbcc\tno_wrap\n\tmov\tr5, r2\n\tadds\tr5, #8\nno_wrap:\n\tstr \tr5, [r2, #4]\t/* store rp */\n\tsubs\tr1, r1, #1\t\t/* decrement word count */\n\tcmp     r1, #0\n\tbeq     exit\t\t/* loop if not done */\n\tb\twait_fifo\nexit:\n\tmov\t\tr0, r6\t\t\t/* return status in r0 */\n\tbkpt\t#0\n\n\t/* r6 - in\n\t * for r6 == 1 it'll take:\n\t *  1 (prepare operand) + 4 (bl) + 2 (subs+cmp) + 1 (bne) + 3 (b) ->\n\t *  11 tacts == 1.4us with 8MHz\n\t * every extra iteration will take 5 tacts == 0.6us */\ndelay:\n\tsubs\tr6, r6, #1\n\tcmp\tr6, #0\n\tbne\tdelay\n\tbx\tlr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/mrvlqspi_write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com>                *\n *                                                                         *\n *   Adapted from (contrib/loaders/flash/lpcspifi_write.S):                *\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m3\n\t.thumb\n\t.thumb_func\n\n/*\n * For compilation:\n * arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -c contrib/loaders/flash/mrvlqspi_write.S\n * arm-none-eabi-objcopy -O binary mrvlqspi_write.o code.bin\n * Copy code.bin into mrvlqspi flash driver\n */\n\n/*\n * Params :\n * r0 = workarea start, status (out)\n * r1 = workarea end\n * r2 = target address (offset from flash base)\n * r3 = count (bytes)\n * r4 = page size\n * r5 = qspi base address\n * Clobbered:\n * r7 - rp\n * r8 - wp, tmp\n * r9 - send/receive data\n * r10 - current page end address\n */\n\n#define CNTL\t0x0\n#define CONF\t0x4\n#define DOUT\t0x8\n#define DIN\t0xc\n#define INSTR   0x10\n#define ADDR    0x14\n#define RDMODE  0x18\n#define HDRCNT\t0x1c\n#define DINCNT  0x20\n\n#define SS_EN (1 << 0)\n#define XFER_RDY (1 << 1)\n#define RFIFO_EMPTY (1 << 4)\n#define WFIFO_EMPTY (1 << 6)\n#define WFIFO_FULL (1 << 7)\n#define FIFO_FLUSH (1 << 9)\n#define RW_EN (1 << 13)\n#define XFER_STOP (1 << 14)\n#define XFER_START (1 << 15)\n\n#define INS_WRITE_ENABLE 0x06\n#define INS_READ_STATUS 0x05\n#define INS_PAGE_PROGRAM 0x02\n\ninit:\n\tmov.w \tr10, #0x00\nfind_next_page_boundary:\n\tadd \tr10, r4\t\t/* Increment to the next page */\n\tcmp \tr10, r2\n\t/* If we have not reached the next page boundary after the target address, keep going */\n\tbls \tfind_next_page_boundary\nwrite_enable:\n\t/* Flush read/write fifos */\n\tbl \tflush_fifo\n\n\t/* Instruction byte 1 */\n\tmovs \tr8, #0x1\n\tstr \tr8, [r5, #HDRCNT]\n\n\t/* Set write enable instruction */\n\tmovs \tr8, #INS_WRITE_ENABLE\n\tstr \tr8, [r5, #INSTR]\n\n\tmovs\tr9, #0x1\n\tbl\tstart_tx\n\tbl \tstop_tx\npage_program:\n\t/* Instruction byte 1, Addr byte 3 */\n\tmovs \tr8, #0x31\n\tstr \tr8, [r5, #HDRCNT]\n\t/* Todo: set addr and data pin to single */\nwrite_address:\n\tmov \tr8, r2\n\tstr \tr8, [r5, #ADDR]\n\t/* Set page program instruction */\n\tmovs \tr8, #INS_PAGE_PROGRAM\n\tstr \tr8, [r5, #INSTR]\n\t/* Start write transfer */\n\tmovs\tr9, #0x1\n\tbl\tstart_tx\nwait_fifo:\n\tldr \tr8, [r0]  \t/* read the write pointer */\n\tcmp \tr8, #0 \t\t/* if it's zero, we're gonzo */\n\tbeq \texit\n\tldr \tr7, [r0, #4] \t/* read the read pointer */\n\tcmp \tr7, r8 \t\t/* wait until they are not equal */\n\tbeq \twait_fifo\nwrite:\n\tldrb \tr9, [r7], #0x01 /* Load one byte from the FIFO, increment the read pointer by 1 */\n\tbl \twrite_data \t/* send the byte to the flash chip */\n\n\tcmp \tr7, r1\t\t/* wrap the read pointer if it is at the end */\n\tit  \tcs\n\taddcs\tr7, r0, #8\t/* skip loader args */\n\tstr \tr7, [r0, #4]\t/* store the new read pointer */\n\tsubs\tr3, r3, #1\t/* decrement count */\n\tcmp\tr3, #0 \t\t/* Exit if we have written everything */\n\tbeq\twrite_wait\n\tadd \tr2, #1 \t\t/* Increment flash address by 1 */\n\tcmp \tr10, r2   \t/* See if we have reached the end of a page */\n\tbne \twait_fifo \t/* If not, keep writing bytes */\nwrite_wait:\n\tbl \tstop_tx\t\t/* Otherwise, end the command and keep going w/ the next page */\n\tadd \tr10, r4 \t/* Move up the end-of-page address by the page size*/\ncheck_flash_busy:\t\t/* Wait for the flash to finish the previous page write */\n\t/* Flush read/write fifos */\n\tbl \tflush_fifo\n\t/* Instruction byte 1 */\n\tmovs \tr8, #0x1\n\tstr \tr8, [r5, #HDRCNT]\n\t/* Continuous data in of status register */\n\tmovs\tr8, #0x0\n\tstr \tr8, [r5, #DINCNT]\n\t/* Set write enable instruction */\n\tmovs \tr8, #INS_READ_STATUS\n\tstr \tr8, [r5, #INSTR]\n\t/* Start read transfer */\n\tmovs\tr9, #0x0\n\tbl\tstart_tx\nwait_flash_busy:\n\tbl \tread_data\n\tand.w\tr9, r9, #0x1\n\tcmp\tr9, #0x0\n\tbne.n\twait_flash_busy\n\tbl \tstop_tx\n\tcmp\tr3, #0\n\tbne.n \twrite_enable \t/* If it is done, start a new page write */\n\tb\texit\t\t/* All data written, exit */\n\nwrite_data: \t\t\t/* Send/receive 1 byte of data over QSPI */\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #24\n\tbmi.n\twrite_data\n\tstr \tr9, [r5, #DOUT]\n\tbx\tlr\n\nread_data:\t\t\t/* Read 1 byte of data over QSPI */\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #27\n\tbmi.n\tread_data\n\tldr\tr9, [r5, #DIN]\n\tbx\tlr\n\nflush_fifo:\t\t\t/* Flush read write fifos */\n\tldr\tr8, [r5, #CONF]\n\torr.w   r8, r8, #FIFO_FLUSH\n\tstr     r8, [r5, #CONF]\nflush_reset:\n\tldr\tr8, [r5, #CONF]\n\tlsls    r8, r8, #22\n\tbmi.n\tflush_reset\n\tbx\tlr\n\nstart_tx:\n\tldr\tr8, [r5, #CNTL]\n\torr.w\tr8, r8, #SS_EN\n\tstr\tr8, [r5, #CNTL]\nxfer_rdy:\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #30\n\tbpl.n\txfer_rdy\n\tldr\tr8, [r5, #CONF]\n\tbfi\tr8, r9, #13, #1\n\torr.w\tr8, r8, #XFER_START\n\tstr\tr8, [r5, #CONF]\n\tbx lr\n\nstop_tx:\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #30\n\tbpl.n\tstop_tx\nwfifo_wait:\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #25\n\tbpl.n\twfifo_wait\n\tldr\tr8, [r5, #CONF]\n\torr.w\tr8, r8, #XFER_STOP\n\tstr\tr8, [r5, #CONF]\nxfer_start:\n\tldr\tr8, [r5, #CONF]\n\tlsls\tr8, r8, #16\n\tbmi.n \txfer_start\nss_disable:\n\t# Disable SS_EN\n\tldr\tr8, [r5, #CNTL]\n\tbic.w\tr8, r8, #SS_EN\n\tstr\tr8, [r5, #CNTL]\nwait:\n\tldr\tr8, [r5, #CNTL]\n\tlsls    r8, r8, #30\n\tbpl.n\twait\n\tbx \tlr\n\nerror:\n\tmovs\tr0, #0\n\tstr \tr0, [r2, #4]\t/* set rp = 0 on error */\nexit:\n\tmov \tr0, r6\n\tbkpt \t#0x00\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/MSP432E4_FlashLibIf.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H\n#define OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n/* RAM loader */\nstatic const uint32_t RAM_LOADER_START   = 0x20000000u; /* Code space */\nstatic const uint32_t RAM_LOADER_MAIN    = 0x20000110u; /* Code space */\nstatic const uint32_t RAM_LOADER_BUFFER1 = 0x20002000u; /* SBUS data space */\nstatic const uint32_t RAM_LOADER_BUFFER2 = 0x20003000u; /* SBUS data space */\nstatic const uint32_t RAM_LOADER_STACK   = 0x20002000u; /* SBUS data space */\n\n/* Address for flash function to be executed */\nstatic const uint32_t FLASH_FUNCTION_ADDRESS = 0x20000150u;\n\nenum flash_command {\n\tFLASH_NO_COMMAND = 0,\n\tFLASH_MASS_ERASE = 1,\n\tFLASH_SECTOR_ERASE = 2,\n\tFLASH_PROGRAM = 4,\n\tFLASH_INIT = 8,\n\tFLASH_EXIT = 16,\n\tFLASH_CONTINUOUS_PROGRAM = 32\n};\n\n/* Address for algorithm program and flash buffer */\nstatic const uint32_t DST_ADDRESS             = 0x2000015Cu;\nstatic const uint32_t SRC_LENGTH_ADDRESS      = 0x20000160u;\nstatic const uint32_t BUFFER1_STATUS_REGISTER = 0x20000164u;\nstatic const uint32_t BUFFER2_STATUS_REGISTER = 0x20000168u;\nstatic const uint32_t BUFFER_INACTIVE         = 0x00000000u;\nstatic const uint32_t BUFFER_ACTIVE           = 0x00000001u;\nstatic const uint32_t BUFFER_DATA_READY       = 0x00000010u;\nstatic const size_t   SRC_LENGTH_MAX          = 4096u;\n\n/* Erase options */\nstatic const uint32_t ERASE_PARAM_ADDRESS = 0x2000016Cu;\nstatic const uint32_t ERASE_MAIN          = 0x00000001u;\nstatic const uint32_t ERASE_INFO          = 0x00000002u;\n\n/* Unlock BSL */\nstatic const uint32_t UNLOCK_BSL_ADDRESS  = 0x20000170u;\nstatic const uint32_t LOCK_BSL_KEY        = 0x00000000u;\nstatic const uint32_t UNLOCK_BSL_KEY      = 0x0000000Bu;\n\n/* Address for return code */\nstatic const uint32_t RETURN_CODE_ADDRESS = 0x20000154u;\n\n/* Return codes */\nstatic const uint32_t FLASH_BUSY          = 0x00000001u;\nstatic const uint32_t FLASH_SUCCESS       = 0x00000ACEu;\nstatic const uint32_t FLASH_ERROR         = 0x0000DEADu;\nstatic const uint32_t FLASH_TIMEOUT_ERROR = 0xDEAD0000u;\nstatic const uint32_t FLASH_VERIFY_ERROR  = 0xDEADDEADu;\nstatic const uint32_t FLASH_WRONG_COMMAND = 0x00000BADu;\nstatic const uint32_t FLASH_POWER_ERROR   = 0x00DEAD00u;\n\n/* Device ID address */\nstatic const uint32_t DEVICE_ID_ADDRESS   = 0x0020100Cu;\nstatic const uint32_t PC_REGISTER         = 15u;\nstatic const uint32_t SP_REGISTER         = 13u;\n\n/* CS silicon and boot code revisions */\nstatic const uint32_t SILICON_REV_ADDRESS = 0x00201010u;\nstatic const uint32_t SILICON_REV_A       = 0x00000041u;\nstatic const uint32_t SILICON_REV_B       = 0x00000042u;\nstatic const uint32_t SILICON_REV_C       = 0x00000043u;\nstatic const uint32_t SILICON_REV_D       = 0x00000044u;\nstatic const uint32_t SILICON_REV_E       = 0x00000045u;\nstatic const uint32_t SILICON_REV_F       = 0x00000046u;\nstatic const uint32_t SILICON_REV_G       = 0x00000047u;\nstatic const uint32_t SILICON_REV_H       = 0x00000048u;\nstatic const uint32_t SILICON_REV_I       = 0x00000049u;\nstatic const uint32_t SILICON_REV_B_WRONG = 0x00004100u;\n\nstruct flash_interface {\n\tvolatile uint32_t FLASH_FUNCTION;\n\tvolatile uint32_t RETURN_CODE;\n\tvolatile uint32_t _RESERVED0;\n\tvolatile uint32_t DST_ADDRESS;\n\tvolatile uint32_t SRC_LENGTH;\n\tvolatile uint32_t BUFFER1_STATUS_REGISTER;\n\tvolatile uint32_t BUFFER2_STATUS_REGISTER;\n\tvolatile uint32_t ERASE_PARAM;\n\tvolatile uint32_t UNLOCK_BSL;\n};\n\n#define FLASH_LOADER_BASE ((uint32_t)0x20000150u)\n#define FLASH_LOADER      ((struct flash_interface *) FLASH_LOADER_BASE)\n\n#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432E4_FLASHLIBIF_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/MSP432P4_FlashLibIf.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2014-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H\n#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H\n\n#include <stddef.h>\n#include <stdint.h>\n\n/* RAM loader */\nstatic const uint32_t RAM_LOADER_START   = 0x01000000u; /* Code space */\nstatic const uint32_t RAM_LOADER_MAIN    = 0x01000110u; /* Code space */\nstatic const uint32_t RAM_LOADER_BUFFER1 = 0x20002000u; /* SBUS data space */\nstatic const uint32_t RAM_LOADER_BUFFER2 = 0x20003000u; /* SBUS data space */\nstatic const uint32_t RAM_LOADER_STACK   = 0x20002000u; /* SBUS data space */\n\n/* Address for flash function to be executed */\nstatic const uint32_t FLASH_FUNCTION_ADDRESS = 0x20000150u;\n\nenum flash_command {\n\tFLASH_NO_COMMAND = 0,\n\tFLASH_MASS_ERASE = 1,\n\tFLASH_SECTOR_ERASE = 2,\n\tFLASH_PROGRAM = 4,\n\tFLASH_INIT = 8,\n\tFLASH_EXIT = 16,\n\tFLASH_CONTINUOUS_PROGRAM = 32\n};\n\n/* Address for algorithm program and flash buffer */\nstatic const uint32_t DST_ADDRESS             = 0x2000015Cu;\nstatic const uint32_t SRC_LENGTH_ADDRESS      = 0x20000160u;\nstatic const uint32_t BUFFER1_STATUS_REGISTER = 0x20000164u;\nstatic const uint32_t BUFFER2_STATUS_REGISTER = 0x20000168u;\nstatic const uint32_t BUFFER_INACTIVE         = 0x00000000u;\nstatic const uint32_t BUFFER_ACTIVE           = 0x00000001u;\nstatic const uint32_t BUFFER_DATA_READY       = 0x00000010u;\nstatic const size_t   SRC_LENGTH_MAX          = 4096u;\n\n/* erase options */\nstatic const uint32_t ERASE_PARAM_ADDRESS = 0x2000016Cu;\nstatic const uint32_t ERASE_MAIN          = 0x00000001u;\nstatic const uint32_t ERASE_INFO          = 0x00000002u;\n\n/* Unlock BSL */\nstatic const uint32_t UNLOCK_BSL_ADDRESS  = 0x20000170u;\nstatic const uint32_t LOCK_BSL_KEY        = 0x00000000u;\nstatic const uint32_t UNLOCK_BSL_KEY      = 0x0000000Bu;\n\n/* Address for return code */\nstatic const uint32_t RETURN_CODE_ADDRESS = 0x20000154u;\n\n/* Return codes */\nstatic const uint32_t FLASH_BUSY          = 0x00000001u;\nstatic const uint32_t FLASH_SUCCESS       = 0x00000ACEu;\nstatic const uint32_t FLASH_ERROR         = 0x0000DEADu;\nstatic const uint32_t FLASH_TIMEOUT_ERROR = 0xDEAD0000u;\nstatic const uint32_t FLASH_VERIFY_ERROR  = 0xDEADDEADu;\nstatic const uint32_t FLASH_WRONG_COMMAND = 0x00000BADu;\nstatic const uint32_t FLASH_POWER_ERROR   = 0x00DEAD00u;\n\n/* Device ID address */\nstatic const uint32_t DEVICE_ID_ADDRESS = 0x0020100Cu;\nstatic const uint32_t PC_REGISTER       = 15u;\nstatic const uint32_t SP_REGISTER       = 13u;\n\n/* CS silicon and boot code revisions */\nstatic const uint32_t SILICON_REV_ADDRESS = 0x00201010u;\nstatic const uint32_t SILICON_REV_A       = 0x00000041u;\nstatic const uint32_t SILICON_REV_B       = 0x00000042u;\nstatic const uint32_t SILICON_REV_C       = 0x00000043u;\nstatic const uint32_t SILICON_REV_D       = 0x00000044u;\nstatic const uint32_t SILICON_REV_E       = 0x00000045u;\nstatic const uint32_t SILICON_REV_F       = 0x00000046u;\nstatic const uint32_t SILICON_REV_G       = 0x00000047u;\nstatic const uint32_t SILICON_REV_H       = 0x00000048u;\nstatic const uint32_t SILICON_REV_I       = 0x00000049u;\nstatic const uint32_t SILICON_REV_B_WRONG = 0x00004100u;\n\nstruct flash_interface {\n\tvolatile uint32_t FLASH_FUNCTION;\n\tvolatile uint32_t RETURN_CODE;\n\tvolatile uint32_t _RESERVED0;\n\tvolatile uint32_t DST_ADDRESS;\n\tvolatile uint32_t SRC_LENGTH;\n\tvolatile uint32_t BUFFER1_STATUS_REGISTER;\n\tvolatile uint32_t BUFFER2_STATUS_REGISTER;\n\tvolatile uint32_t ERASE_PARAM;\n\tvolatile uint32_t UNLOCK_BSL;\n};\n\n#define FLASH_LOADER_BASE ((uint32_t)0x20000150u)\n#define FLASH_LOADER      ((struct flash_interface *) FLASH_LOADER_BASE)\n\n#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P4_FLASHLIBIF_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/driverlib.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"driverlib.h\"\n\n/*\n * Wrapper function for the CPSID instruction.\n * Returns the state of PRIMASK on entry.\n */\nuint32_t __attribute__((naked)) cpu_cpsid(void)\n{\n\tuint32_t ret;\n\n\t/* Read PRIMASK and disable interrupts. */\n\t__asm(\"    mrs     r0, PRIMASK\\n\"\n\t\t  \"    cpsid   i\\n\"\n\t\t  \"    bx      lr\\n\"\n\t\t\t: \"=r\" (ret));\n\n\t/*\n\t * The return is handled in the inline assembly, but the compiler will\n\t * still complain if there is not an explicit return here (despite the fact\n\t * that this does not result in any code being produced because of the\n\t * naked attribute).\n\t */\n\treturn ret;\n}\n\n/* Wrapper function for the CPUWFI instruction. */\nvoid __attribute__((naked)) cpu_wfi(void)\n{\n\t/* Wait for the next interrupt. */\n\t__asm(\"    wfi\\n\"\n\t\t  \"    bx      lr\\n\");\n}\n\n/* Power Control Module APIs */\n#if defined(PCM)\n\nstatic bool __pcm_set_core_voltage_level_advanced(uint_fast8_t voltage_level,\n\tuint32_t time_out, bool blocking)\n{\n\tuint8_t power_mode;\n\tuint8_t current_voltage_level;\n\tuint32_t reg_value;\n\tbool bool_timeout;\n\n\t/* Getting current power mode and level */\n\tpower_mode = pcm_get_power_mode();\n\tcurrent_voltage_level = pcm_get_core_voltage_level();\n\n\tbool_timeout = time_out > 0 ? true : false;\n\n\t/* If we are already at the power mode they requested, return */\n\tif (current_voltage_level == voltage_level)\n\t\treturn true;\n\n\twhile (current_voltage_level != voltage_level) {\n\n\t\treg_value = PCM->CTL0;\n\n\t\tswitch (pcm_get_power_state()) {\n\t\t\tcase PCM_AM_LF_VCORE1:\n\t\t\tcase PCM_AM_DCDC_VCORE1:\n\t\t\tcase PCM_AM_LDO_VCORE0:\n\t\t\t\tPCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE1)\n\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));\n\t\t\t\tbreak;\n\t\t\tcase PCM_AM_LF_VCORE0:\n\t\t\tcase PCM_AM_DCDC_VCORE0:\n\t\t\tcase PCM_AM_LDO_VCORE1:\n\t\t\t\tPCM->CTL0 = (PCM_KEY | (PCM_AM_LDO_VCORE0)\n\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (blocking) {\n\t\t\twhile (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) {\n\t\t\t\tif (bool_timeout && !(--time_out))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t} else\n\t\t\treturn true;\n\n\t\tcurrent_voltage_level = pcm_get_core_voltage_level();\n\t}\n\n\t/* Changing the power mode if we are stuck in LDO mode */\n\tif (power_mode != pcm_get_power_mode()) {\n\t\tif (power_mode == PCM_DCDC_MODE)\n\t\t\treturn pcm_set_power_mode(PCM_DCDC_MODE);\n\t\telse\n\t\t\treturn pcm_set_power_mode(PCM_LF_MODE);\n\t}\n\n\treturn true;\n}\n\nbool pcm_set_core_voltage_level(uint_fast8_t voltage_level)\n{\n\treturn __pcm_set_core_voltage_level_advanced(voltage_level, 0, true);\n}\n\nuint8_t pcm_get_power_mode(void)\n{\n\tuint8_t current_power_state;\n\n\tcurrent_power_state = pcm_get_power_state();\n\n\tswitch (current_power_state) {\n\t\tcase PCM_AM_LDO_VCORE0:\n\t\tcase PCM_AM_LDO_VCORE1:\n\t\tcase PCM_LPM0_LDO_VCORE0:\n\t\tcase PCM_LPM0_LDO_VCORE1:\n\t\tdefault:\n\t\t\treturn PCM_LDO_MODE;\n\t\tcase PCM_AM_DCDC_VCORE0:\n\t\tcase PCM_AM_DCDC_VCORE1:\n\t\tcase PCM_LPM0_DCDC_VCORE0:\n\t\tcase PCM_LPM0_DCDC_VCORE1:\n\t\t\treturn PCM_DCDC_MODE;\n\t\tcase PCM_LPM0_LF_VCORE0:\n\t\tcase PCM_LPM0_LF_VCORE1:\n\t\tcase PCM_AM_LF_VCORE1:\n\t\tcase PCM_AM_LF_VCORE0:\n\t\t\treturn PCM_LF_MODE;\n\t}\n}\n\nuint8_t pcm_get_core_voltage_level(void)\n{\n\tuint8_t current_power_state = pcm_get_power_state();\n\n\tswitch (current_power_state) {\n\t\tcase PCM_AM_LDO_VCORE0:\n\t\tcase PCM_AM_DCDC_VCORE0:\n\t\tcase PCM_AM_LF_VCORE0:\n\t\tcase PCM_LPM0_LDO_VCORE0:\n\t\tcase PCM_LPM0_DCDC_VCORE0:\n\t\tcase PCM_LPM0_LF_VCORE0:\n\t\tdefault:\n\t\t\treturn PCM_VCORE0;\n\t\tcase PCM_AM_LDO_VCORE1:\n\t\tcase PCM_AM_DCDC_VCORE1:\n\t\tcase PCM_AM_LF_VCORE1:\n\t\tcase PCM_LPM0_LDO_VCORE1:\n\t\tcase PCM_LPM0_DCDC_VCORE1:\n\t\tcase PCM_LPM0_LF_VCORE1:\n\t\t\treturn PCM_VCORE1;\n\t\tcase PCM_LPM3:\n\t\t\treturn PCM_VCORELPM3;\n\t}\n}\n\nstatic bool __pcm_set_power_mode_advanced(uint_fast8_t power_mode,\n\tuint32_t time_out, bool blocking)\n{\n\tuint8_t current_power_mode;\n\tuint8_t current_power_state;\n\tuint32_t reg_value;\n\tbool bool_timeout;\n\n\t/* Getting Current Power Mode */\n\tcurrent_power_mode = pcm_get_power_mode();\n\n\t/* If the power mode being set it the same as the current mode, return */\n\tif (power_mode == current_power_mode)\n\t\treturn true;\n\n\tcurrent_power_state = pcm_get_power_state();\n\n\tbool_timeout = time_out > 0 ? true : false;\n\n\t/* Go through the while loop while we haven't achieved the power mode */\n\twhile (current_power_mode != power_mode) {\n\n\t\treg_value = PCM->CTL0;\n\n\t\tswitch (current_power_state) {\n\t\t\tcase PCM_AM_DCDC_VCORE0:\n\t\t\tcase PCM_AM_LF_VCORE0:\n\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE0\n\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));\n\t\t\t\tbreak;\n\t\t\tcase PCM_AM_LF_VCORE1:\n\t\t\tcase PCM_AM_DCDC_VCORE1:\n\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_LDO_VCORE1\n\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_AMR_MASK)));\n\t\t\t\tbreak;\n\t\t\tcase PCM_AM_LDO_VCORE1: {\n\t\t\t\tif (power_mode == PCM_DCDC_MODE) {\n\t\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE1\n\t\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK\n\t\t\t\t\t\t| PCM_CTL0_AMR_MASK)));\n\t\t\t\t} else if (power_mode == PCM_LF_MODE) {\n\t\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE1\n\t\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK\n\t\t\t\t\t\t| PCM_CTL0_AMR_MASK)));\n\t\t\t\t} else\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase PCM_AM_LDO_VCORE0: {\n\t\t\t\tif (power_mode == PCM_DCDC_MODE) {\n\t\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_DCDC_VCORE0\n\t\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK\n\t\t\t\t\t\t| PCM_CTL0_AMR_MASK)));\n\t\t\t\t} else if (power_mode == PCM_LF_MODE) {\n\t\t\t\t\tPCM->CTL0 = (PCM_KEY | PCM_AM_LF_VCORE0\n\t\t\t\t\t\t| (reg_value & ~(PCM_CTL0_KEY_MASK\n\t\t\t\t\t\t| PCM_CTL0_AMR_MASK)));\n\t\t\t\t} else\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (blocking) {\n\t\t\twhile (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS)) {\n\t\t\t\tif (bool_timeout && !(--time_out))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t} else\n\t\t\treturn true;\n\n\t\tcurrent_power_mode = pcm_get_power_mode();\n\t\tcurrent_power_state = pcm_get_power_state();\n\t}\n\n\treturn true;\n}\n\nbool pcm_set_power_mode(uint_fast8_t power_mode)\n{\n\treturn __pcm_set_power_mode_advanced(power_mode, 0, true);\n}\n\nstatic bool __pcm_set_power_state_advanced(uint_fast8_t power_state,\n\tuint32_t timeout, bool blocking)\n{\n\tuint8_t current_power_state;\n\tcurrent_power_state = pcm_get_power_state();\n\n\tif (current_power_state == power_state)\n\t\treturn true;\n\n\tswitch (power_state) {\n\t\tcase PCM_AM_LDO_VCORE0:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_LDO_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_AM_LDO_VCORE1:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_LDO_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_AM_DCDC_VCORE0:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_DCDC_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_AM_DCDC_VCORE1:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_DCDC_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_AM_LF_VCORE0:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_LF_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_AM_LF_VCORE1:\n\t\t\treturn __pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\t\tblocking) && __pcm_set_power_mode_advanced(PCM_LF_MODE,\n\t\t\t\t\ttimeout, blocking);\n\t\tcase PCM_LPM0_LDO_VCORE0:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_LDO_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM0_LDO_VCORE1:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_LDO_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM0_DCDC_VCORE0:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_DCDC_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM0_DCDC_VCORE1:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_DCDC_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM0_LF_VCORE0:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE0, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_LF_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM0_LF_VCORE1:\n\t\t\tif (!__pcm_set_core_voltage_level_advanced(PCM_VCORE1, timeout,\n\t\t\t\tblocking) || !__pcm_set_power_mode_advanced(PCM_LF_MODE,\n\t\t\t\ttimeout, blocking))\n\t\t\t\tbreak;\n\t\t\treturn pcm_goto_lpm0();\n\t\tcase PCM_LPM3:\n\t\t\treturn pcm_goto_lpm3();\n\t\tcase PCM_LPM4:\n\t\t\treturn pcm_goto_lpm4();\n\t\tcase PCM_LPM45:\n\t\t\treturn pcm_shutdown_device(PCM_LPM45);\n\t\tcase PCM_LPM35_VCORE0:\n\t\t\treturn pcm_shutdown_device(PCM_LPM35_VCORE0);\n\t\tdefault:\n\t\t\treturn false;\n\t}\n\n\treturn false;\n}\n\nbool pcm_set_power_state(uint_fast8_t power_state)\n{\n\treturn __pcm_set_power_state_advanced(power_state, 0, true);\n}\n\nbool pcm_shutdown_device(uint32_t shutdown_mode)\n{\n\tuint32_t shutdown_mode_bits = (shutdown_mode == PCM_LPM45) ?\n\t\tPCM_CTL0_LPMR_12 : PCM_CTL0_LPMR_10;\n\n\t/* If a power transition is occurring, return false */\n\tif (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))\n\t\treturn false;\n\n\t/* Initiating the shutdown */\n\tSCB->SCR |= SCB_SCR_SLEEPDEEP_MSK;\n\n\tPCM->CTL0 = (PCM_KEY | shutdown_mode_bits\n\t\t| (PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)));\n\n\tcpu_wfi();\n\n\treturn true;\n}\n\nbool pcm_goto_lpm4(void)\n{\n\t/* Disabling RTC_C and WDT_A */\n\twdt_a_hold_timer();\n\trtc_c_hold_clock();\n\n\t/* LPM4 is just LPM3 with WDT_A/RTC_C disabled... */\n\treturn pcm_goto_lpm3();\n}\n\nbool pcm_goto_lpm0(void)\n{\n\t/* If we are in the middle of a state transition, return false */\n\tif (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))\n\t\treturn false;\n\n\tSCB->SCR &= ~SCB_SCR_SLEEPDEEP_MSK;\n\n\tcpu_wfi();\n\n\treturn true;\n}\n\nbool pcm_goto_lpm3(void)\n{\n\tuint_fast8_t current_power_state;\n\tuint_fast8_t current_power_mode;\n\n\t/* If we are in the middle of a state transition, return false */\n\tif (BITBAND_PERI(PCM->CTL1, PCM_CTL1_PMR_BUSY_OFS))\n\t\treturn false;\n\n\t/* If we are in the middle of a shutdown, return false */\n\tif ((PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_10\n\t\t|| (PCM->CTL0 & PCM_CTL0_LPMR_MASK) == PCM_CTL0_LPMR_12)\n\t\treturn false;\n\n\tcurrent_power_mode = pcm_get_power_mode();\n\tcurrent_power_state = pcm_get_power_state();\n\n\tif (current_power_mode == PCM_DCDC_MODE)\n\t\tpcm_set_power_mode(PCM_LDO_MODE);\n\n\t/* Clearing the SDR */\n\tPCM->CTL0 =\n\t\t(PCM->CTL0 & ~(PCM_CTL0_KEY_MASK | PCM_CTL0_LPMR_MASK)) | PCM_KEY;\n\n\t/* Setting the sleep deep bit */\n\tSCB->SCR |= SCB_SCR_SLEEPDEEP_MSK;\n\n\tcpu_wfi();\n\n\tSCB->SCR &= ~SCB_SCR_SLEEPDEEP_MSK;\n\n\treturn pcm_set_power_state(current_power_state);\n}\n\nuint8_t pcm_get_power_state(void)\n{\n\treturn (PCM->CTL0 & PCM_CTL0_CPM_MASK) >> PCM_CTL0_CPM_OFS;\n}\n\n#endif\n\n/* Real Time Clock APIs */\n#if defined(RTC_C)\n\nvoid rtc_c_hold_clock(void)\n{\n\tRTC_C->CTL0 = (RTC_C->CTL0 & ~RTC_C_CTL0_KEY_MASK) | RTC_C_KEY;\n\tBITBAND_PERI(RTC_C->CTL13, RTC_C_CTL13_HOLD_OFS) = 1;\n\tBITBAND_PERI(RTC_C->CTL0, RTC_C_CTL0_KEY_OFS) = 0;\n}\n\n#endif\n\n/* Watch Dog Timer APIs */\n#if defined(WDT_A)\n\nvoid wdt_a_hold_timer(void)\n{\n\t/* Set Hold bit */\n\tuint8_t new_wdt_status = (WDT_A->CTL | WDT_A_CTL_HOLD);\n\n\tWDT_A->CTL = WDT_A_CTL_PW + new_wdt_status;\n}\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/driverlib.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H\n#define OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#if defined(__MSP432E4X__)\n#include \"msp432e4x.h\"\n#elif defined(__MSP432P401X__)\n#include \"msp432p401x.h\"\n#elif defined(__MSP432P411X__)\n#include \"msp432p411x.h\"\n#else\n#error \"Failed to match a device specific include file\"\n#endif\n\n/* Structure type to access the System Control Block (SCB). */\nstruct SCB_Type {\n\tvolatile uint32_t CPUID;         /* CPUID Base Register */\n\tvolatile uint32_t ICSR;          /* Interrupt Control and State Register */\n\tvolatile uint32_t VTOR;          /* Vector Table Offset Register */\n\tvolatile uint32_t AIRCR;         /* Application Interrupt and Reset Control */\n\tvolatile uint32_t SCR;           /* System Control Register */\n\tvolatile uint32_t CCR;           /* Configuration Control Register */\n\tvolatile uint8_t  SHP[12U];      /* System Handlers Priority Registers */\n\tvolatile uint32_t SHCSR;         /* System Handler Control and State */\n\tvolatile uint32_t CFSR;          /* Configurable Fault Status Register */\n\tvolatile uint32_t HFSR;          /* HardFault Status Register */\n\tvolatile uint32_t DFSR;          /* Debug Fault Status Register */\n\tvolatile uint32_t MMFAR;         /* MemManage Fault Address Register */\n\tvolatile uint32_t BFAR;          /* BusFault Address Register */\n\tvolatile uint32_t AFSR;          /* Auxiliary Fault Status Register */\n\tvolatile uint32_t PFR[2U];       /* Processor Feature Register */\n\tvolatile uint32_t DFR;           /* Debug Feature Register */\n\tvolatile uint32_t ADR;           /* Auxiliary Feature Register */\n\tvolatile uint32_t MMFR[4U];      /* Memory Model Feature Register */\n\tvolatile uint32_t ISAR[5U];      /* Instruction Set Attributes Register */\n\t\t\t uint32_t RESERVED0[5U];\n\tvolatile uint32_t CPACR;         /* Coprocessor Access Control Register */\n};\n\n/* SCB:SCR register bits */\n#define SCB_SCR_SLEEPDEEP_POS 2U\n#define SCB_SCR_SLEEPDEEP_MSK (1UL << SCB_SCR_SLEEPDEEP_POS)\n\n/* Memory mapping of Core Hardware */\n#define SCS_BASE (0xE000E000UL)         /* System Control Space Base Address */\n#define SCB_BASE (SCS_BASE +  0x0D00UL) /* System Control Block Base Address */\n#define SCB ((struct SCB_Type *)SCB_BASE) /* SCB configuration struct */\n\n/* Definitions of standard bits */\n#define BIT0   (uint16_t)(0x0001)\n#define BIT1   (uint16_t)(0x0002)\n#define BIT2   (uint16_t)(0x0004)\n#define BIT3   (uint16_t)(0x0008)\n#define BIT4   (uint16_t)(0x0010)\n#define BIT5   (uint16_t)(0x0020)\n#define BIT6   (uint16_t)(0x0040)\n#define BIT7   (uint16_t)(0x0080)\n#define BIT8   (uint16_t)(0x0100)\n#define BIT9   (uint16_t)(0x0200)\n#define BITA   (uint16_t)(0x0400)\n#define BITB   (uint16_t)(0x0800)\n#define BITC   (uint16_t)(0x1000)\n#define BITD   (uint16_t)(0x2000)\n#define BITE   (uint16_t)(0x4000)\n#define BITF   (uint16_t)(0x8000)\n#define BIT(x) ((uint16_t)1 << (x))\n\n/* CPU Module prototypes */\nextern uint32_t cpu_cpsid(void);\nextern void cpu_wfi(void);\n\n/* Clock Signal Module constants */\n#define CS_DCO_FREQUENCY_3  CS_CTL0_DCORSEL_1\n#define CS_DCO_FREQUENCY_24 CS_CTL0_DCORSEL_4\n\n/* Power Control Module constants */\n#define PCM_KEY              0x695A0000\n#define PCM_AM_LDO_VCORE0    0x00\n#define PCM_AM_LDO_VCORE1    0x01\n#define PCM_AM_DCDC_VCORE0   0x04\n#define PCM_AM_DCDC_VCORE1   0x05\n#define PCM_AM_LF_VCORE0     0x08\n#define PCM_AM_LF_VCORE1     0x09\n#define PCM_LPM0_LDO_VCORE0  0x10\n#define PCM_LPM0_LDO_VCORE1  0x11\n#define PCM_LPM0_DCDC_VCORE0 0x14\n#define PCM_LPM0_DCDC_VCORE1 0x15\n#define PCM_LPM0_LF_VCORE0   0x18\n#define PCM_LPM0_LF_VCORE1   0x19\n#define PCM_LPM3             0x20\n#define PCM_LPM4             0x21\n#define PCM_LPM35_VCORE0     0xC0\n#define PCM_LPM45            0xA0\n#define PCM_VCORE0           0x00\n#define PCM_VCORE1           0x01\n#define PCM_VCORELPM3        0x02\n#define PCM_LDO_MODE         0x00\n#define PCM_DCDC_MODE        0x01\n#define PCM_LF_MODE          0x02\n\n/* Power Control Module prototypes */\nextern bool pcm_set_core_voltage_level(uint_fast8_t voltage_level);\nextern uint8_t pcm_get_core_voltage_level(void);\nextern bool pcm_set_power_mode(uint_fast8_t power_mode);\nextern uint8_t pcm_get_power_mode(void);\nextern bool pcm_set_power_state(uint_fast8_t power_state);\nextern uint8_t pcm_get_power_state(void);\nextern bool pcm_shutdown_device(uint32_t shutdown_mode);\nextern bool pcm_goto_lpm0(void);\nextern bool pcm_goto_lpm3(void);\nextern bool pcm_goto_lpm4(void);\n\n/* ROM API Function Pointers */\n#define ROM_API_TABLE         ((unsigned long *)0x02000800)\n#define ROM_FLASH_CTL_TABLE   ((unsigned long *)(ROM_API_TABLE[7]))\n#define ROM_PCM_TABLE         ((unsigned long *)(ROM_API_TABLE[13]))\n#define ROM_WDT_TABLE         ((unsigned long *)(ROM_API_TABLE[25]))\n#define ROM_SYS_CTL_A_TABLE   ((unsigned long *)(ROM_API_TABLE[26]))\n#define ROM_FLASH_CTL_A_TABLE ((unsigned long *)(ROM_API_TABLE[27]))\n\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_UNPROTECT_SECTOR \\\n\t((bool (*)(uint_fast8_t memory_space, \\\n\t\tuint32_t sector_mask))ROM_FLASH_CTL_TABLE[4])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_PROTECT_SECTOR \\\n\t((bool (*)(uint_fast8_t memory_space, \\\n\t\tuint32_t sector_mask))ROM_FLASH_CTL_TABLE[5])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_PERFORM_MASS_ERASE \\\n\t((bool (*)(void))ROM_FLASH_CTL_TABLE[8])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_ERASE_SECTOR \\\n\t((bool (*)(uint32_t addr))ROM_FLASH_CTL_TABLE[9])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_PROGRAM_MEMORY \\\n\t((bool (*)(void *src, void *dest, uint32_t length))ROM_FLASH_CTL_TABLE[10])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_SET_WAIT_STATE \\\n\t((void (*)(uint32_t bank, uint32_t wait_state))ROM_FLASH_CTL_TABLE[21])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_FLASH_CTL_GET_WAIT_STATE \\\n\t((uint32_t (*)(uint32_t bank))ROM_FLASH_CTL_TABLE[22])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_PCM_SET_CORE_VOLTAGE_LEVEL \\\n\t((bool (*)(uint_fast8_t voltage_level))ROM_PCM_TABLE[0])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_PCM_GET_CORE_VOLTAGE_LEVEL \\\n\t((uint8_t (*)(void))ROM_PCM_TABLE[1])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_PCM_SET_POWER_STATE \\\n\t((bool (*)(uint_fast8_t power_state))ROM_PCM_TABLE[6])\n#endif\n#if defined(__MSP432P401X__)\n#define ROM_PCM_GET_POWER_STATE \\\n\t((uint8_t (*)(void))ROM_PCM_TABLE[8])\n#endif\n#if defined(__MSP432P401X__) || defined(__MSP432P411X__)\n#define ROM_WDT_A_HOLD_TIMER \\\n\t((void (*)(void))ROM_WDT_TABLE[0])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_SYS_CTL_A_GET_FLASH_SIZE \\\n\t((uint_least32_t (*)(void))ROM_SYS_CTL_A_TABLE[1])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE \\\n\t((uint_least32_t (*)(void))ROM_SYS_CTL_A_TABLE[18])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_UNPROTECT_MEMORY \\\n\t((bool (*)(uint32_t start_addr, uint32_t end_addr))ROM_FLASH_CTL_A_TABLE[4])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_PROTECT_MEMORY \\\n\t((bool (*)(uint32_t start_addr, uint32_t end_addr))ROM_FLASH_CTL_A_TABLE[5])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_PERFORM_MASS_ERASE \\\n\t((bool (*)(void))ROM_FLASH_CTL_A_TABLE[8])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_ERASE_SECTOR \\\n\t((bool (*)(uint32_t addr))ROM_FLASH_CTL_A_TABLE[9])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_PROGRAM_MEMORY \\\n\t((bool (*)(void *src, void *dest, uint32_t length)) \\\n\t\tROM_FLASH_CTL_A_TABLE[10])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_SET_WAIT_STATE \\\n\t((void (*)(uint32_t bank, uint32_t wait_state))ROM_FLASH_CTL_A_TABLE[21])\n#endif\n#if defined(__MSP432P411X__)\n#define ROM_FLASH_CTL_A_GET_WAIT_STATE \\\n\t((uint32_t (*)(uint32_t bank))ROM_FLASH_CTL_A_TABLE[22])\n#endif\n\n/* Map API functions to ROM or locally built functions */\n#ifdef ROM_FLASH_CTL_UNPROTECT_SECTOR\n#define MAP_FLASH_CTL_UNPROTECT_SECTOR ROM_FLASH_CTL_UNPROTECT_SECTOR\n#else\n#define MAP_FLASH_CTL_UNPROTECT_SECTOR flash_ctl_unprotect_sector\n#endif\n#ifdef ROM_FLASH_CTL_PROTECT_SECTOR\n#define MAP_FLASH_CTL_PROTECT_SECTOR ROM_FLASH_CTL_PROTECT_SECTOR\n#else\n#define MAP_FLASH_CTL_PROTECT_SECTOR flash_ctl_protect_sector\n#endif\n#ifdef ROM_FLASH_CTL_PERFORM_MASS_ERASE\n#define MAP_FLASH_CTL_PERFORM_MASS_ERASE ROM_FLASH_CTL_PERFORM_MASS_ERASE\n#else\n#define MAP_FLASH_CTL_PERFORM_MASS_ERASE flash_ctl_perform_mass_erase\n#endif\n#ifdef ROM_FLASH_CTL_ERASE_SECTOR\n#define MAP_FLASH_CTL_ERASE_SECTOR ROM_FLASH_CTL_ERASE_SECTOR\n#else\n#define MAP_FLASH_CTL_ERASE_SECTOR flash_ctl_erase_sector\n#endif\n#ifdef ROM_FLASH_CTL_PROGRAM_MEMORY\n#define MAP_FLASH_CTL_PROGRAM_MEMORY ROM_FLASH_CTL_PROGRAM_MEMORY\n#else\n#define MAP_FLASH_CTL_PROGRAM_MEMORY flash_ctl_program_memory\n#endif\n#ifdef ROM_FLASH_CTL_SET_WAIT_STATE\n#define MAP_FLASH_CTL_SET_WAIT_STATE ROM_FLASH_CTL_SET_WAIT_STATE\n#else\n#define MAP_FLASH_CTL_SET_WAIT_STATE flash_ctl_set_wait_state\n#endif\n#ifdef ROM_FLASH_CTL_GET_WAIT_STATE\n#define MAP_FLASH_CTL_GET_WAIT_STATE ROM_FLASH_CTL_GET_WAIT_STATE\n#else\n#define MAP_FLASH_CTL_GET_WAIT_STATE flash_ctl_get_wait_state\n#endif\n#ifdef ROM_PCM_SET_CORE_VOLTAGE_LEVEL\n#define MAP_PCM_SET_CORE_VOLTAGE_LEVEL ROM_PCM_SET_CORE_VOLTAGE_LEVEL\n#else\n#define MAP_PCM_SET_CORE_VOLTAGE_LEVEL pcm_set_core_voltage_level\n#endif\n#ifdef ROM_PCM_GET_CORE_VOLTAGE_LEVEL\n#define MAP_PCM_GET_CORE_VOLTAGE_LEVEL ROM_PCM_GET_CORE_VOLTAGE_LEVEL\n#else\n#define MAP_PCM_GET_CORE_VOLTAGE_LEVEL pcm_get_core_voltage_level\n#endif\n#ifdef ROM_PCM_SET_POWER_STATE\n#define MAP_PCM_SET_POWER_STATE ROM_PCM_SET_POWER_STATE\n#else\n#define MAP_PCM_SET_POWER_STATE pcm_set_power_state\n#endif\n#ifdef ROM_PCM_GET_POWER_STATE\n#define MAP_PCM_GET_POWER_STATE ROM_PCM_GET_POWER_STATE\n#else\n#define MAP_PCM_GET_POWER_STATE pcm_get_power_state\n#endif\n#ifdef ROM_WDT_A_HOLD_TIMER\n#define MAP_WDT_A_HOLD_TIMER ROM_WDT_A_HOLD_TIMER\n#else\n#define MAP_WDT_A_HOLD_TIMER wdt_a_hold_timer\n#endif\n#ifdef ROM_SYS_CTL_A_GET_FLASH_SIZE\n#define MAP_SYS_CTL_A_GET_FLASH_SIZE ROM_SYS_CTL_A_GET_FLASH_SIZE\n#else\n#define MAP_SYS_CTL_A_GET_FLASH_SIZE sys_ctl_a_get_flash_size\n#endif\n#ifdef ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE\n#define MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE ROM_SYS_CTL_A_GET_INFO_FLASH_SIZE\n#else\n#define MAP_SYS_CTL_A_GET_INFO_FLASH_SIZE sys_ctl_a_get_info_flash_size\n#endif\n#ifdef ROM_FLASH_CTL_A_UNPROTECT_MEMORY\n#define MAP_FLASH_CTL_A_UNPROTECT_MEMORY ROM_FLASH_CTL_A_UNPROTECT_MEMORY\n#else\n#define MAP_FLASH_CTL_A_UNPROTECT_MEMORY flash_ctl_a_unprotect_memory\n#endif\n#ifdef ROM_FLASH_CTL_A_PROTECT_MEMORY\n#define MAP_FLASH_CTL_A_PROTECT_MEMORY ROM_FLASH_CTL_A_PROTECT_MEMORY\n#else\n#define MAP_FLASH_CTL_A_PROTECT_MEMORY flash_ctl_a_protect_memory\n#endif\n#ifdef ROM_FLASH_CTL_A_PERFORM_MASS_ERASE\n#define MAP_FLASH_CTL_A_PERFORM_MASS_ERASE ROM_FLASH_CTL_A_PERFORM_MASS_ERASE\n#else\n#define MAP_FLASH_CTL_A_PERFORM_MASS_ERASE flash_ctl_a_perform_mass_erase\n#endif\n#ifdef ROM_FLASH_CTL_A_ERASE_SECTOR\n#define MAP_FLASH_CTL_A_ERASE_SECTOR ROM_FLASH_CTL_A_ERASE_SECTOR\n#else\n#define MAP_FLASH_CTL_A_ERASE_SECTOR flash_ctl_a_erase_sector\n#endif\n#ifdef ROM_FLASH_CTL_A_PROGRAM_MEMORY\n#define MAP_FLASH_CTL_A_PROGRAM_MEMORY ROM_FLASH_CTL_A_PROGRAM_MEMORY\n#else\n#define MAP_FLASH_CTL_A_PROGRAM_MEMORY flash_ctl_a_program_memory\n#endif\n#ifdef ROM_FLASH_CTL_A_SET_WAIT_STATE\n#define MAP_FLASH_CTL_A_SET_WAIT_STATE ROM_FLASH_CTL_A_SET_WAIT_STATE\n#else\n#define MAP_FLASH_CTL_A_SET_WAIT_STATE flash_ctl_a_set_wait_state\n#endif\n#ifdef ROM_FLASH_CTL_A_GET_WAIT_STATE\n#define MAP_FLASH_CTL_A_GET_WAIT_STATE ROM_FLASH_CTL_A_GET_WAIT_STATE\n#else\n#define MAP_FLASH_CTL_A_GET_WAIT_STATE flash_ctl_a_get_wait_state\n#endif\n\n/* Real Time Clock Module prototypes */\nextern void rtc_c_hold_clock(void);\n\n/* Watchdog Timer Module prototypes */\nextern void wdt_a_hold_timer(void);\n\n#if defined(__MCU_HAS_FLCTL_A__)\n#define FLASH_A_BANK0                0x00\n#define FLASH_A_BANK1                0x01\n#define __INFO_FLASH_A_TECH_START__  0x00200000\n#define __INFO_FLASH_A_TECH_MIDDLE__ 0x00204000\n#endif\n\n#if defined(__MCU_HAS_FLCTL__)\n#define FLASH_BANK0 0x00\n#define FLASH_BANK1 0x01\n#define FLASH_MAIN_MEMORY_SPACE_BANK0 0x01\n#define FLASH_MAIN_MEMORY_SPACE_BANK1 0x02\n#define FLASH_INFO_MEMORY_SPACE_BANK0 0x03\n#define FLASH_INFO_MEMORY_SPACE_BANK1 0x04\n#define FLASH_SECTOR0 FLCTL_BANK0_MAIN_WEPROT_PROT0\n#define FLASH_SECTOR1 FLCTL_BANK0_MAIN_WEPROT_PROT1\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPENOCD_LOADERS_FLASH_MSP432_DRIVERLIB_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/main_msp432e4x.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"driverlib.h\"\n\n#include \"MSP432E4_FlashLibIf.h\"\n\n/* Local prototypes */\nvoid msp432_flash_init(void);\nvoid msp432_flash_mass_erase(void);\nvoid msp432_flash_sector_erase(void);\nvoid msp432_flash_write(void);\nvoid msp432_flash_continous_write(void);\nvoid msp432_flash_exit(void);\n\nint main(void)\n{\n\t/* Disable interrupts */\n\t__asm(\"  cpsid i\");\n\n\t/* Halt watchdog */\n\tSYSCTL->RCGCWD &= ~(SYSCTL_RCGCWD_R1 + SYSCTL_RCGCWD_R0);\n\n\twhile (1) {\n\t\tswitch (FLASH_LOADER->FLASH_FUNCTION) {\n\t\t\tcase FLASH_INIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_init();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_MASS_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_mass_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_SECTOR_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_sector_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_PROGRAM:\n\t\t\tcase FLASH_CONTINUOUS_PROGRAM:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_continous_write();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_EXIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_exit();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_NO_COMMAND:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Initialize flash */\nvoid msp432_flash_init(void)\n{\n\tSCB->VTOR = 0x20000000;\n\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Erase entire flash */\nvoid msp432_flash_mass_erase(void)\n{\n\tbool success = false;\n\n\t/* Clear the flash access and error interrupts. */\n\tFLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |\n\t\t\t\t\t\t  FLASH_FCMISC_ERMISC | FLASH_FCMISC_PMISC);\n\n\t/* Trigger mass erase */\n\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_MERASE;\n\twhile (FLASH_CTRL->FMC & FLASH_FMC_MERASE)\n\t\t;\n\n\t/* Return an error if an access violation occurred. */\n\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |\n\t\t\t\tFLASH_FCRIS_ERRIS));\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Erase one flash sector */\nvoid msp432_flash_sector_erase(void)\n{\n\tbool success = false;\n\n\t/* Clear the flash access and error interrupts. */\n\tFLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |\n\t\t\t\t\t\t  FLASH_FCMISC_ERMISC | FLASH_FCMISC_PMISC);\n\n\t/* Set 16kB aligned flash page address to be erased (16kB block) */\n\tFLASH_CTRL->FMA = FLASH_LOADER->DST_ADDRESS;\n\t/* Trigger sector erase (erase flash page) */\n\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_ERASE;\n\twhile (FLASH_CTRL->FMC & FLASH_FMC_ERASE)\n\t\t;\n\n\t/* Return an error if an access violation occurred. */\n\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS | FLASH_FCRIS_VOLTRIS |\n\t\t\t\tFLASH_FCRIS_ERRIS));\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Write data to flash */\nvoid msp432_flash_continous_write(void)\n{\n\tbool buffer1_in_use = false;\n\tbool buffer2_in_use = false;\n\tuint32_t *src_address = NULL;\n\tbool success = true;\n\tuint32_t i = 0;\n\tuint32_t address = FLASH_LOADER->DST_ADDRESS;\n\tuint32_t data_to_write = FLASH_LOADER->SRC_LENGTH;\n\tint32_t write_package = 0;\n\n\t/* Clear the flash access and error interrupts. */\n\tFLASH_CTRL->FCMISC = (FLASH_FCMISC_AMISC | FLASH_FCMISC_VOLTMISC |\n\t\tFLASH_FCMISC_INVDMISC | FLASH_FCMISC_PROGMISC | FLASH_FCMISC_PMISC);\n\tdo {\n\t\tif (data_to_write > SRC_LENGTH_MAX) {\n\t\t\twrite_package = SRC_LENGTH_MAX;\n\t\t\tdata_to_write -= write_package;\n\t\t} else {\n\t\t\twrite_package = data_to_write;\n\t\t\tdata_to_write -= write_package;\n\t\t}\n\t\twhile (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&\n\t\t\t!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))\n\t\t\t;\n\n\t\tif (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address  = (uint32_t *) RAM_LOADER_BUFFER1;\n\t\t\tbuffer1_in_use = true;\n\t\t} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address  = (uint32_t *) RAM_LOADER_BUFFER2;\n\t\t\tbuffer2_in_use = true;\n\t\t}\n\n\t\t/*\n\t\t * The flash hardware can only write complete words to flash. If\n\t\t * an unaligned address is passed in, we must do a read-modify-write\n\t\t * on a word with enough bytes to align the rest of the buffer. And\n\t\t * if less than a whole word remains at the end, we must also do a\n\t\t * read-modify-write on a final word to finish up.\n\t\t */\n\t\tif (0 != (address & 0x3)) {\n\t\t\tuint32_t head;\n\t\t\tuint8_t *ui8head = (uint8_t *)&head;\n\t\t\tuint8_t *buffer = (uint8_t *)src_address;\n\n\t\t\t/* Get starting offset for data to write (will be 1 to 3) */\n\t\t\tuint32_t head_offset = address & 0x03;\n\n\t\t\t/* Get the aligned address to write this first word to */\n\t\t\tuint32_t head_address = address & 0xfffffffc;\n\n\t\t\t/* Retrieve what is already in flash at the head address */\n\t\t\thead = *(uint32_t *)head_address;\n\n\t\t\t/* Substitute in the new data to write */\n\t\t\twhile ((write_package > 0) && (head_offset < 4)) {\n\t\t\t\tui8head[head_offset] = *buffer;\n\t\t\t\thead_offset++;\n\t\t\t\taddress++;\n\t\t\t\tbuffer++;\n\t\t\t\twrite_package--;\n\t\t\t}\n\t\t\tsrc_address = (uint32_t *)buffer;\n\n\t\t\tFLASH_CTRL->FMD = head;\n\t\t\tFLASH_CTRL->FMA = head_address;\n\t\t\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;\n\n\t\t\t/* Wait until the word has been programmed. */\n\t\t\twhile (FLASH_CTRL->FMC & FLASH_FMC_WRITE)\n\t\t\t\t;\n\n\t\t\t/* Return an error if an access violation occurred. */\n\t\t\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |\n\t\t\t\tFLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));\n\t\t}\n\n\t\t/* Program a word at a time until aligned on 32-word boundary */\n\t\twhile ((write_package >= 4) && ((address & 0x7f) != 0) && success) {\n\t\t\tFLASH_CTRL->FMD = *src_address++;\n\t\t\tFLASH_CTRL->FMA = address;\n\t\t\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;\n\n\t\t\t/* Wait until the word has been programmed. */\n\t\t\twhile (FLASH_CTRL->FMC & FLASH_FMC_WRITE)\n\t\t\t\t;\n\n\t\t\t/* Prepare for next word to write */\n\t\t\twrite_package -= 4;\n\t\t\taddress += 4;\n\n\t\t\t/* Return an error if an access violation occurred. */\n\t\t\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |\n\t\t\t\tFLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));\n\t\t}\n\n\t\t/* Program data in 32-word blocks */\n\t\twhile ((write_package >= 32) && success) {\n\t\t\t/* Loop over the words in this 32-word block. */\n\t\t\ti = 0;\n\t\t\tdo {\n\t\t\t\tFLASH_CTRL->FWBN[i] = *src_address++;\n\t\t\t\twrite_package -= 4;\n\t\t\t\ti++;\n\t\t\t} while ((write_package > 0) && (i < 32));\n\t\t\tFLASH_CTRL->FMA = address;\n\t\t\tFLASH_CTRL->FMC2 = FLASH_FMC_WRKEY | FLASH_FMC2_WRBUF;\n\n\t\t\t/* Wait until the write buffer has been programmed. */\n\t\t\twhile (FLASH_CTRL->FMC2 & FLASH_FMC2_WRBUF)\n\t\t\t\t;\n\n\t\t\t/* Increment destination address by words written */\n\t\t\taddress += 128;\n\n\t\t\t/* Return an error if an access violation occurred. */\n\t\t\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |\n\t\t\t\tFLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));\n\t\t}\n\n\t\t/* Program a word at a time on left over data */\n\t\twhile ((write_package >= 4) && success) {\n\t\t\tFLASH_CTRL->FMD = *src_address++;\n\t\t\tFLASH_CTRL->FMA = address;\n\t\t\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;\n\n\t\t\t/* Wait until the word has been programmed. */\n\t\t\twhile (FLASH_CTRL->FMC & FLASH_FMC_WRITE)\n\t\t\t\t;\n\n\t\t\t/* Prepare for next word to write */\n\t\t\twrite_package -= 4;\n\t\t\taddress += 4;\n\n\t\t\t/* Return an error if an access violation occurred. */\n\t\t\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |\n\t\t\t\tFLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));\n\t\t}\n\n\t\tif ((write_package > 0) && success) {\n\t\t\tuint32_t tail;\n\t\t\tuint8_t *ui8tail = (uint8_t *)&tail;\n\t\t\tuint8_t *buffer = (uint8_t *)src_address;\n\n\t\t\t/* Set starting offset for data to write */\n\t\t\tuint32_t tail_offset = 0;\n\n\t\t\t/* Get the address to write this last word to */\n\t\t\tuint32_t tail_address = address;\n\n\t\t\t/* Retrieve what is already in flash at the tail address */\n\t\t\ttail = *(uint32_t *)address;\n\n\t\t\t/* Substitute in the new data to write */\n\t\t\twhile (write_package > 0) {\n\t\t\t\tui8tail[tail_offset] = *buffer;\n\t\t\t\ttail_offset++;\n\t\t\t\taddress++;\n\t\t\t\tbuffer++;\n\t\t\t\twrite_package--;\n\t\t\t}\n\n\t\t\tFLASH_CTRL->FMD = tail;\n\t\t\tFLASH_CTRL->FMA = tail_address;\n\t\t\tFLASH_CTRL->FMC = FLASH_FMC_WRKEY | FLASH_FMC_WRITE;\n\n\t\t\t/* Wait until the word has been programmed. */\n\t\t\twhile (FLASH_CTRL->FMC & FLASH_FMC_WRITE)\n\t\t\t\t;\n\n\t\t\t/* Return an error if an access violation occurred. */\n\t\t\tsuccess = !(FLASH_CTRL->FCRIS & (FLASH_FCRIS_ARIS |\n\t\t\t\tFLASH_FCRIS_ERIS | FLASH_FCRIS_INVDRIS | FLASH_FCRIS_PROGRIS));\n\t\t}\n\n\t\tif (buffer1_in_use) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER &=\n\t\t\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer1_in_use = false;\n\t\t} else if (buffer2_in_use) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER &=\n\t\t\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer2_in_use = false;\n\t\t}\n\t} while (success && data_to_write);\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Exit flash programming */\nvoid msp432_flash_exit(void)\n{\n\tSCB->VTOR = 0x00000000;\n\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/main_msp432p401x.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"driverlib.h\"\n\n#include \"MSP432P4_FlashLibIf.h\"\n\n/* Number of erase repeats until timeout */\n#define FLASH_MAX_REPEATS 5\n\n/* Local prototypes */\nvoid msp432_flash_init(void);\nvoid msp432_flash_mass_erase(void);\nvoid msp432_flash_sector_erase(void);\nvoid msp432_flash_write(void);\nvoid msp432_flash_continous_write(void);\nvoid msp432_flash_exit(void);\nvoid unlock_flash_sectors(void);\nvoid unlock_all_flash_sectors(void);\nvoid lock_all_flash_sectors(void);\nvoid __cs_set_dco_frequency_range(uint32_t dco_freq);\nstatic bool program_device(void *src, void *dest, uint32_t length);\n\nstruct backup_params {\n\tuint32_t BANK0_WAIT_RESTORE;\n\tuint32_t BANK1_WAIT_RESTORE;\n\tuint32_t CS_DC0_FREQ_RESTORE;\n\tuint8_t  VCORE_LEVEL_RESTORE;\n\tuint8_t  PCM_VCORE_LEVEL_RESTORE;\n};\n\n#define BACKUP_PARAMS ((struct backup_params *) 0x20000180)\n\n/* Main with trampoline */\nint main(void)\n{\n\t/* Halt watchdog */\n\tMAP_WDT_A_HOLD_TIMER();\n\n\t/* Disable interrupts */\n\tcpu_cpsid();\n\n\twhile (1) {\n\t\tswitch (FLASH_LOADER->FLASH_FUNCTION) {\n\t\t\tcase FLASH_INIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_init();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_MASS_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_mass_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_SECTOR_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_sector_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_PROGRAM:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_write();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_CONTINUOUS_PROGRAM:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_continous_write();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_EXIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_exit();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_NO_COMMAND:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Initialize flash */\nvoid msp432_flash_init(void)\n{\n\tbool success = false;\n\n\t/* Point to vector table in RAM */\n\tSCB->VTOR = (uint32_t)0x01000000;\n\n\t/* backup system parameters */\n\tBACKUP_PARAMS->BANK0_WAIT_RESTORE =\n\t\tMAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK0);\n\tBACKUP_PARAMS->BANK1_WAIT_RESTORE =\n\t\tMAP_FLASH_CTL_GET_WAIT_STATE(FLASH_BANK1);\n\tBACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();\n\tBACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();\n\tBACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;\n\n\t/* set parameters for flashing */\n\tsuccess = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);\n\n\t/* Set Flash wait states to 2 */\n\tMAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0, 2);\n\tMAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1, 2);\n\n\t/* Set CPU speed to 24MHz */\n\t__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);\n\n\tif (!success) {\n\t\t/* Indicate failed power switch */\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;\n\t} else\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Erase entire flash */\nvoid msp432_flash_mass_erase(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_flash_sectors();\n\n\t/* Allow some mass erase repeats before timeout with error */\n\tint erase_repeats = FLASH_MAX_REPEATS;\n\twhile (!success && (erase_repeats > 0)) {\n\t\t/* Mass erase with post-verify */\n\t\tsuccess = MAP_FLASH_CTL_PERFORM_MASS_ERASE();\n\t\terase_repeats--;\n\t}\n\n\tif (erase_repeats == 0)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n}\n\n/* Erase one flash sector */\nvoid msp432_flash_sector_erase(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_all_flash_sectors();\n\n\t/* Allow some sector erase repeats before timeout with error */\n\tint erase_repeats = FLASH_MAX_REPEATS;\n\twhile (!success && (erase_repeats > 0)) {\n\t\t/* Sector erase with post-verify */\n\t\tsuccess = MAP_FLASH_CTL_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);\n\t\terase_repeats--;\n\t}\n\n\tif (erase_repeats == 0)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n}\n\n/* Write data to flash with the help of DriverLib */\nvoid msp432_flash_write(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_all_flash_sectors();\n\n\twhile (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))\n\t\t;\n\n\tFLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;\n\n\t/* Program memory */\n\tsuccess = program_device((uint32_t *)RAM_LOADER_BUFFER1,\n\t\t(void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);\n\n\tFLASH_LOADER->BUFFER1_STATUS_REGISTER &=\n\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Write data to flash with the help of DriverLib with auto-increment */\nvoid msp432_flash_continous_write(void)\n{\n\tbool buffer1_in_use = false;\n\tbool buffer2_in_use = false;\n\tuint32_t *src_address = NULL;\n\tbool success = false;\n\n\tuint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;\n\tuint32_t write_package = 0;\n\tuint32_t start_addr = FLASH_LOADER->DST_ADDRESS;\n\n\twhile (bytes_to_write > 0) {\n\t\tif (bytes_to_write > SRC_LENGTH_MAX) {\n\t\t\twrite_package = SRC_LENGTH_MAX;\n\t\t\tbytes_to_write -= write_package;\n\t\t} else {\n\t\t\twrite_package = bytes_to_write;\n\t\t\tbytes_to_write -= write_package;\n\t\t}\n\t\tunlock_all_flash_sectors();\n\n\t\twhile (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&\n\t\t\t!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))\n\t\t\t;\n\n\t\tif (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address = (uint32_t *)RAM_LOADER_BUFFER1;\n\t\t\tbuffer1_in_use = true;\n\t\t} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address = (uint32_t *)RAM_LOADER_BUFFER2;\n\t\t\tbuffer2_in_use = true;\n\t\t}\n\t\tif (buffer1_in_use || buffer2_in_use) {\n\t\t\tsuccess = program_device(src_address,\n\t\t\t\t(void *)start_addr, write_package);\n\n\t\t\tif (buffer1_in_use)\n\t\t\t\tP6->OUT &= ~BIT4; /* Program from B1 */\n\t\t\telse if (buffer2_in_use)\n\t\t\t\tP3->OUT &= ~BIT6; /* Program from B1 */\n\n\t\t\tstart_addr += write_package;\n\t\t}\n\t\tif (buffer1_in_use) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER &=\n\t\t\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer1_in_use = false;\n\t\t} else if (buffer2_in_use) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER &=\n\t\t\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer2_in_use = false;\n\t\t}\n\t\t/* Block flash writes */\n\t\tlock_all_flash_sectors();\n\n\t\tif (!success) {\n\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Unlock Main/Info Flash sectors */\nvoid unlock_flash_sectors(void)\n{\n\tif (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN) {\n\t\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0,\n\t\t\t0xFFFFFFFF);\n\t\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1,\n\t\t\t0xFFFFFFFF);\n\t}\n\tif (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {\n\t\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,\n\t\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n\t\tif (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)\n\t\t\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,\n\t\t\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n\t}\n}\n\n/* Unlock All Flash sectors */\nvoid unlock_all_flash_sectors(void)\n{\n\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);\n\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);\n\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,\n\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n\tif (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)\n\t\tMAP_FLASH_CTL_UNPROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,\n\t\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n}\n\n\n/* Lock all Flash sectors */\nvoid lock_all_flash_sectors(void)\n{\n\tMAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK0, 0xFFFFFFFF);\n\tMAP_FLASH_CTL_PROTECT_SECTOR(FLASH_MAIN_MEMORY_SPACE_BANK1, 0xFFFFFFFF);\n\tMAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK0,\n\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n\tMAP_FLASH_CTL_PROTECT_SECTOR(FLASH_INFO_MEMORY_SPACE_BANK1,\n\t\tFLASH_SECTOR0 | FLASH_SECTOR1);\n}\n\n\n/* Force DCO frequency range */\nvoid __cs_set_dco_frequency_range(uint32_t dco_freq)\n{\n\t/* Unlocking the CS Module */\n\tCS->KEY = CS_KEY_VAL;\n\n\t/* Resetting Tuning Parameters and Setting the frequency */\n\tCS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;\n\n\t/* Locking the CS Module */\n\tCS->KEY = 0;\n}\n\n/* Exit flash programming */\nvoid msp432_flash_exit(void)\n{\n\tbool success = false;\n\n\t/* Restore modified registers, in reverse order */\n\t__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);\n\n\tMAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK0,\n\t\tBACKUP_PARAMS->BANK0_WAIT_RESTORE);\n\tMAP_FLASH_CTL_SET_WAIT_STATE(FLASH_BANK1,\n\t\tBACKUP_PARAMS->BANK1_WAIT_RESTORE);\n\n\tsuccess = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);\n\n\tsuccess &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(\n\t\tBACKUP_PARAMS->VCORE_LEVEL_RESTORE);\n\n\t__cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);\n\n\t/* Point to vector table in Flash */\n\tSCB->VTOR = (uint32_t)0x00000000;\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\nstatic bool program_device(void *src, void *dest, uint32_t length)\n{\n\treturn MAP_FLASH_CTL_PROGRAM_MEMORY(src, dest, length);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/main_msp432p411x.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n#include <stdbool.h>\n#include \"driverlib.h\"\n\n#include \"MSP432P4_FlashLibIf.h\"\n\n/* Number of erase repeats until timeout */\n#define FLASH_MAX_REPEATS 5\n\n/* Local prototypes */\nvoid msp432_flash_init(void);\nvoid msp432_flash_mass_erase(void);\nvoid msp432_flash_sector_erase(void);\nvoid msp432_flash_write(void);\nvoid msp432_flash_continous_write(void);\nvoid msp432_flash_exit(void);\nvoid unlock_flash_sectors(void);\nvoid unlock_all_flash_sectors(void);\nvoid lock_all_flash_sectors(void);\nvoid __cs_set_dco_frequency_range(uint32_t dco_freq);\nstatic bool program_device(void *src, void *dest, uint32_t length);\n\nstruct backup_params {\n\tuint32_t BANK0_WAIT_RESTORE;\n\tuint32_t BANK1_WAIT_RESTORE;\n\tuint32_t CS_DC0_FREQ_RESTORE;\n\tuint8_t  VCORE_LEVEL_RESTORE;\n\tuint8_t  PCM_VCORE_LEVEL_RESTORE;\n};\n\n#define BACKUP_PARAMS      ((struct backup_params *) 0x20000180)\n#define INFO_FLASH_START  __INFO_FLASH_A_TECH_START__\n#define INFO_FLASH_MIDDLE __INFO_FLASH_A_TECH_MIDDLE__\n#define BSL_FLASH_START   BSL_API_TABLE_ADDR\n\n/* Main with trampoline */\nint main(void)\n{\n\t/* Halt watchdog */\n\tMAP_WDT_A_HOLD_TIMER();\n\n\t/* Disable interrupts */\n\tcpu_cpsid();\n\n\twhile (1) {\n\t\tswitch (FLASH_LOADER->FLASH_FUNCTION) {\n\t\t\tcase FLASH_INIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_init();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_MASS_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_mass_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_SECTOR_ERASE:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_sector_erase();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_PROGRAM:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_write();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_CONTINUOUS_PROGRAM:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_continous_write();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_EXIT:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_BUSY;\n\t\t\t\tmsp432_flash_exit();\n\t\t\t\tFLASH_LOADER->FLASH_FUNCTION = 0;\n\t\t\t\tbreak;\n\t\t\tcase FLASH_NO_COMMAND:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_WRONG_COMMAND;\n\t\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Initialize flash */\nvoid msp432_flash_init(void)\n{\n\tbool success = false;\n\n\t/* Point to vector table in RAM */\n\tSCB->VTOR = (uint32_t)0x01000000;\n\n\t/* backup system parameters */\n\tBACKUP_PARAMS->BANK0_WAIT_RESTORE =\n\t\tMAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK0);\n\tBACKUP_PARAMS->BANK1_WAIT_RESTORE =\n\t\tMAP_FLASH_CTL_A_GET_WAIT_STATE(FLASH_A_BANK1);\n\tBACKUP_PARAMS->VCORE_LEVEL_RESTORE = MAP_PCM_GET_CORE_VOLTAGE_LEVEL();\n\tBACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE = MAP_PCM_GET_POWER_STATE();\n\tBACKUP_PARAMS->CS_DC0_FREQ_RESTORE = CS->CTL0 & CS_CTL0_DCORSEL_MASK;\n\n\t/* set parameters for flashing */\n\tsuccess = MAP_PCM_SET_POWER_STATE(PCM_AM_LDO_VCORE0);\n\n\t/* Set Flash wait states to 2 */\n\tMAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0, 2);\n\tMAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1, 2);\n\n\t/* Set CPU speed to 24MHz */\n\t__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_24);\n\n\tif (!success) {\n\t\t/* Indicate failed power switch */\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_POWER_ERROR;\n\t} else\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Erase entire flash */\nvoid msp432_flash_mass_erase(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_flash_sectors();\n\n\t/* Allow some mass erase repeats before timeout with error */\n\tint erase_repeats = FLASH_MAX_REPEATS;\n\twhile (!success && (erase_repeats > 0)) {\n\t\t/* Mass erase with post-verify */\n\t\tsuccess = ROM_FLASH_CTL_A_PERFORM_MASS_ERASE();\n\t\terase_repeats--;\n\t}\n\n\tif (erase_repeats == 0)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_VERIFY_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n}\n\n/* Erase one flash sector */\nvoid msp432_flash_sector_erase(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_all_flash_sectors();\n\n\t/* Allow some sector erase repeats before timeout with error */\n\tint erase_repeats = FLASH_MAX_REPEATS;\n\twhile (!success && (erase_repeats > 0)) {\n\t\t/* Sector erase with post-verify */\n\t\tsuccess = MAP_FLASH_CTL_A_ERASE_SECTOR(FLASH_LOADER->DST_ADDRESS);\n\t\terase_repeats--;\n\t}\n\n\tif (erase_repeats == 0)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n}\n\n/* Write data to flash with the help of DriverLib */\nvoid msp432_flash_write(void)\n{\n\tbool success = false;\n\n\t/* Allow flash writes */\n\tunlock_all_flash_sectors();\n\n\twhile (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY))\n\t\t;\n\n\tFLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;\n\n\t/* Program memory */\n\tsuccess = program_device((uint32_t *)RAM_LOADER_BUFFER1,\n\t\t(void *)FLASH_LOADER->DST_ADDRESS, FLASH_LOADER->SRC_LENGTH);\n\n\tFLASH_LOADER->BUFFER1_STATUS_REGISTER &=\n\t\t~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\n\t/* Block flash writes */\n\tlock_all_flash_sectors();\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Write data to flash with the help of DriverLib with auto-increment */\nvoid msp432_flash_continous_write(void)\n{\n\tbool buffer1_in_use = false;\n\tbool buffer2_in_use = false;\n\tuint32_t *src_address = NULL;\n\tbool success = false;\n\n\tuint32_t bytes_to_write = FLASH_LOADER->SRC_LENGTH;\n\tuint32_t write_package = 0;\n\tuint32_t start_addr = FLASH_LOADER->DST_ADDRESS;\n\n\twhile (bytes_to_write > 0) {\n\t\tif (bytes_to_write > SRC_LENGTH_MAX) {\n\t\t\twrite_package = SRC_LENGTH_MAX;\n\t\t\tbytes_to_write -= write_package;\n\t\t} else {\n\t\t\twrite_package = bytes_to_write;\n\t\t\tbytes_to_write -= write_package;\n\t\t}\n\t\tunlock_all_flash_sectors();\n\t\twhile (!(FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) &&\n\t\t\t!(FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY))\n\t\t\t;\n\n\t\tif (FLASH_LOADER->BUFFER1_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address = (uint32_t *) RAM_LOADER_BUFFER1;\n\t\t\tbuffer1_in_use = true;\n\t\t} else if (FLASH_LOADER->BUFFER2_STATUS_REGISTER & BUFFER_DATA_READY) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER |= BUFFER_ACTIVE;\n\t\t\tsrc_address = (uint32_t *) RAM_LOADER_BUFFER2;\n\t\t\tbuffer2_in_use = true;\n\t\t}\n\t\tif (buffer1_in_use || buffer2_in_use) {\n\t\t\tsuccess = program_device(src_address, (void *) start_addr, write_package);\n\t\t\tstart_addr += write_package;\n\t\t}\n\t\tif (buffer1_in_use) {\n\t\t\tFLASH_LOADER->BUFFER1_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer1_in_use = false;\n\t\t} else if (buffer2_in_use) {\n\t\t\tFLASH_LOADER->BUFFER2_STATUS_REGISTER &= ~(BUFFER_ACTIVE | BUFFER_DATA_READY);\n\t\t\tbuffer2_in_use = false;\n\t\t}\n\t\t/* Block flash writes */\n\t\tlock_all_flash_sectors();\n\n\t\tif (!success) {\n\t\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\n/* Unlock Main/Info Flash sectors */\nvoid unlock_flash_sectors(void)\n{\n\tif (FLASH_LOADER->ERASE_PARAM & ERASE_MAIN)\n\t\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +\n\t\t\tMAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);\n\n\tif (FLASH_LOADER->ERASE_PARAM & ERASE_INFO) {\n\t\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);\n\t\tif (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)\n\t\t\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,\n\t\t\t\tINFO_FLASH_MIDDLE - 1);\n\t\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE, INFO_FLASH_MIDDLE +\n\t\t\tMAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);\n\t}\n}\n\n/* Unlock All Flash sectors */\nvoid unlock_all_flash_sectors(void)\n{\n\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(FLASH_BASE, FLASH_BASE +\n\t\tMAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);\n\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_START, TLV_BASE - 1);\n\tif (FLASH_LOADER->UNLOCK_BSL == UNLOCK_BSL_KEY)\n\t\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(BSL_FLASH_START,\n\t\t\tINFO_FLASH_MIDDLE - 1);\n\tMAP_FLASH_CTL_A_UNPROTECT_MEMORY(INFO_FLASH_MIDDLE,  INFO_FLASH_MIDDLE +\n\t\tMAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);\n}\n\n/* Lock all Flash sectors */\nvoid lock_all_flash_sectors(void)\n{\n\tMAP_FLASH_CTL_A_PROTECT_MEMORY(FLASH_BASE, FLASH_BASE +\n\t\tMAP_SYS_CTL_A_GET_FLASH_SIZE() - 1);\n\tMAP_FLASH_CTL_A_PROTECT_MEMORY(INFO_FLASH_START, INFO_FLASH_START +\n\t\tMAP_SYS_CTL_A_GET_INFO_FLASH_SIZE() - 1);\n}\n\n/* Force DCO frequency range */\nvoid __cs_set_dco_frequency_range(uint32_t dco_freq)\n{\n\t/* Unlocking the CS Module */\n\tCS->KEY = CS_KEY_VAL;\n\n\t/* Resetting Tuning Parameters and Setting the frequency */\n\tCS->CTL0 = (CS->CTL0 & ~CS_CTL0_DCORSEL_MASK) | dco_freq;\n\n\t/* Locking the CS Module */\n\tCS->KEY = 0;\n}\n\n/* Exit flash programming */\nvoid msp432_flash_exit(void)\n{\n\tbool success = false;\n\n\t/* Restore modified registers, in reverse order */\n\t__cs_set_dco_frequency_range(CS_DCO_FREQUENCY_3);\n\n\tMAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK0,\n\t\tBACKUP_PARAMS->BANK0_WAIT_RESTORE);\n\tMAP_FLASH_CTL_A_SET_WAIT_STATE(FLASH_A_BANK1,\n\t\tBACKUP_PARAMS->BANK1_WAIT_RESTORE);\n\n\tsuccess = MAP_PCM_SET_POWER_STATE(BACKUP_PARAMS->PCM_VCORE_LEVEL_RESTORE);\n\n\tsuccess &= MAP_PCM_SET_CORE_VOLTAGE_LEVEL(\n\t\tBACKUP_PARAMS->VCORE_LEVEL_RESTORE);\n\n\t__cs_set_dco_frequency_range(BACKUP_PARAMS->CS_DC0_FREQ_RESTORE);\n\n\t/* Point to vector table in Flash */\n\tSCB->VTOR = (uint32_t)0x00000000;\n\n\tif (!success)\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_ERROR;\n\telse\n\t\tFLASH_LOADER->RETURN_CODE = FLASH_SUCCESS;\n}\n\nstatic bool program_device(void *src, void *dest, uint32_t length)\n{\n\tuint32_t dst_address = (uint32_t)dest;\n\n\t/* Flash main memory first, then information memory */\n\tif ((dst_address < INFO_FLASH_START) && ((dst_address + length) >\n\t\tINFO_FLASH_START)) {\n\t\tuint32_t block_length = INFO_FLASH_START - dst_address;\n\t\tuint32_t src_address = (uint32_t)src;\n\t\t/* Main memory block */\n\t\tbool success = MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, block_length);\n\n\t\tsrc_address = src_address + block_length;\n\t\tblock_length = length - block_length;\n\t\t/* Information memory block */\n\t\tsuccess &= MAP_FLASH_CTL_A_PROGRAM_MEMORY((void *)src_address,\n\t\t\t(void *)INFO_FLASH_START, block_length);\n\t\treturn success;\n\t} else\n\t\treturn MAP_FLASH_CTL_A_PROGRAM_MEMORY(src, dest, length);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432e4x/msp432e4x.lds",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\nMEMORY {\n\tMAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00100000\n\tSRAM_CODE_0(RWX): ORIGIN = 0x20000000, LENGTH = 0x00000110\n\tSRAM_CODE_1(RWX): ORIGIN = 0x20000110, LENGTH = 0x00000030\n\tSRAM_CODE_2(RWX): ORIGIN = 0x20000150, LENGTH = 0x00000040\n\tSRAM_CODE_3(RWX): ORIGIN = 0x20000190, LENGTH = 0x00000F70\n\tSRAM_CODE_4(RWX): ORIGIN = 0x20001170, LENGTH = 0x00000200\n\tSRAM_DATA  (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000\n}\n\nREGION_ALIAS(\"REGION_INTVECT\", SRAM_CODE_0);\nREGION_ALIAS(\"REGION_RESET\", SRAM_CODE_1);\nREGION_ALIAS(\"REGION_DESCRIPTOR\", SRAM_CODE_2);\nREGION_ALIAS(\"REGION_TEXT\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_BSS\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_DATA\", SRAM_DATA);\nREGION_ALIAS(\"REGION_STACK\", SRAM_CODE_4);\nREGION_ALIAS(\"REGION_HEAP\", SRAM_DATA);\nREGION_ALIAS(\"REGION_ARM_EXIDX\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_ARM_EXTAB\", SRAM_CODE_3);\n\nSECTIONS {\n\t/* section for the interrupt vector area */\n\t.intvecs : {\n\t\tKEEP (*(.intvecs))\n\t} > REGION_INTVECT\n\n\tPROVIDE (_vtable_base_address =\n\t\tDEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);\n\n\t.vtable (_vtable_base_address) : AT (_vtable_base_address) {\n\t\tKEEP (*(.vtable))\n\t} > REGION_DATA\n\n\t.descriptor :{\n\t\tFILL(0x00000000);\n\t\t. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;\n\t\tBYTE(0x00);\n\t\t__ROM_AT = .;\n\t} > REGION_DESCRIPTOR\n\n\t.reset : {\n\t\tKEEP(*(.reset))\n\t} > REGION_RESET AT> REGION_RESET\n\n\t.text : {\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP (*(.text))\n\t\t*(.text.*)\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.ctors))\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.dtors))\n\t\t. = ALIGN(0x4);\n\t\t__init_array_start = .;\n\t\tKEEP (*(.init_array*))\n\t\t__init_array_end = .;\n\t\tKEEP (*(.init))\n\t\tKEEP (*(.fini*))\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.rodata : {\n\t\t*(.rodata)\n\t\t*(.rodata.*)\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.ARM.exidx : {\n\t\t__exidx_start = .;\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t\t__exidx_end = .;\n\t} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX\n\n\t.ARM.extab : {\n\t\tKEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))\n\t} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB\n\n\t__etext = .;\n\n\t.data : {\n\t\t__data_load__ = LOADADDR (.data);\n\t\t__data_start__ = .;\n\t\tKEEP (*(.data))\n\t\tKEEP (*(.data*))\n\t\t. = ALIGN (4);\n\t\t__data_end__ = .;\n\t} > REGION_DATA AT> REGION_TEXT\n\n\t.bss : {\n\t\t__bss_start__ = .;\n\t\t*(.shbss)\n\t\tKEEP (*(.bss))\n\t\t*(.bss.*)\n\t\t*(COMMON)\n\t\t. = ALIGN (4);\n\t\t__bss_end__ = .;\n\t} > REGION_BSS AT> REGION_BSS\n\n\t.heap : {\n\t\t__heap_start__ = .;\n\t\tend = __heap_start__;\n\t\t_end = end;\n\t\t__end = end;\n\t\tKEEP (*(.heap))\n\t\t__heap_end__ = .;\n\t\t__HeapLimit = __heap_end__;\n\t} > REGION_HEAP AT> REGION_HEAP\n\n\t.stack (NOLOAD) : ALIGN(0x8) {\n\t\t_stack = .;\n\t\tKEEP(*(.stack))\n\t} > REGION_STACK AT> REGION_STACK\n\n\t__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);\n\tPROVIDE(__stack = __stack_top);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432e4x.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H\n#define OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Register map for FLASH_CTRL peripheral (FLASH_CTRL) */\nstruct flash_ctrl {\n\tvolatile uint32_t FMA;       /* Flash Memory Address */\n\tvolatile uint32_t FMD;       /* Flash Memory Data */\n\tvolatile uint32_t FMC;       /* Flash Memory Control */\n\tvolatile uint32_t FCRIS;     /* Flash Controller Raw Interrupt Status */\n\tvolatile uint32_t FCIM;      /* Flash Controller Interrupt Mask */\n\tvolatile uint32_t FCMISC;    /* Flash Cont. Masked Int. Status and Clear */\n\tvolatile uint32_t RESERVED0[2];\n\tvolatile uint32_t FMC2;      /* Flash Memory Control 2 */\n\tvolatile uint32_t RESERVED1[3];\n\tvolatile uint32_t FWBVAL;    /* Flash Write Buffer Valid */\n\tvolatile uint32_t RESERVED2[2];\n\tvolatile uint32_t FLPEKEY;   /* Flash Program/Erase Key */\n\tvolatile uint32_t RESERVED3[48];\n\tvolatile uint32_t FWBN[32];  /* Flash Write Buffer n */\n};\n\n/* Register map for SYSCTL peripheral (SYSCTL) */\nstruct sys_ctrl {\n\tvolatile uint32_t DID0;      /* Device Identification 0 */\n\tvolatile uint32_t DID1;      /* Device Identification 1 */\n\tvolatile uint32_t RESERVED0[12];\n\tvolatile uint32_t PTBOCTL;   /* Power-Temp Brown Out Control */\n\tvolatile uint32_t RESERVED1[5];\n\tvolatile uint32_t RIS;       /* Raw Interrupt Status */\n\tvolatile uint32_t IMC;       /* Interrupt Mask Control */\n\tvolatile uint32_t MISC;      /* Masked Interrupt Status and Clear */\n\tvolatile uint32_t RESC;      /* Reset Cause */\n\tvolatile uint32_t PWRTC;     /* Power-Temperature Cause */\n\tvolatile uint32_t NMIC;      /* NMI Cause Register */\n\tvolatile uint32_t RESERVED2[5];\n\tvolatile uint32_t MOSCCTL;   /* Main Oscillator Control */\n\tvolatile uint32_t RESERVED3[12];\n\tvolatile uint32_t RSCLKCFG;  /* Run and Sleep Mode Configuration Register */\n\tvolatile uint32_t RESERVED4[3];\n\tvolatile uint32_t MEMTIM0;   /* Memory Timing Register 0 for Main Flash */\n\tvolatile uint32_t RESERVED5[29];\n\tvolatile uint32_t ALTCLKCFG; /* Alternate Clock Configuration */\n\tvolatile uint32_t RESERVED6[2];\n\tunion {\n\t\tvolatile uint32_t DSLPCLKCFG; /* Deep Sleep Clock Configuration */\n\t\tvolatile uint32_t DSCLKCFG;   /* Deep Sleep Clock Register */\n\t};\n\tvolatile uint32_t DIVSCLK;   /* Divisor and Source Clock Configuration */\n\tvolatile uint32_t SYSPROP;   /* System Properties */\n\tvolatile uint32_t PIOSCCAL;  /* Precision Internal Oscillator Calibration */\n\tvolatile uint32_t PIOSCSTAT; /* Precision Internal Oscillator Statistics */\n\tvolatile uint32_t RESERVED7[2];\n\tvolatile uint32_t PLLFREQ0;  /* PLL Frequency 0 */\n\tvolatile uint32_t PLLFREQ1;  /* PLL Frequency 1 */\n\tvolatile uint32_t PLLSTAT;   /* PLL Status */\n\tvolatile uint32_t RESERVED8[7];\n\tvolatile uint32_t SLPPWRCFG; /* Sleep Power Configuration */\n\tvolatile uint32_t DSLPPWRCFG; /* Deep-Sleep Power Configuration */\n\tvolatile uint32_t RESERVED9[4];\n\tvolatile uint32_t NVMSTAT;   /* Non-Volatile Memory Information */\n\tvolatile uint32_t RESERVED10[4];\n\tvolatile uint32_t LDOSPCTL;  /* LDO Sleep Power Control */\n\tvolatile uint32_t RESERVED11;\n\tvolatile uint32_t LDODPCTL;  /* LDO Deep-Sleep Power Control */\n\tvolatile uint32_t RESERVED12[6];\n\tvolatile uint32_t RESBEHAVCTL; /* Reset Behavior Control Register */\n\tvolatile uint32_t RESERVED13[6];\n\tvolatile uint32_t HSSR;      /* Hardware System Service Request */\n\tvolatile uint32_t RESERVED14[34];\n\tvolatile uint32_t USBPDS;    /* USB Power Domain Status */\n\tvolatile uint32_t USBMPC;    /* USB Memory Power Control */\n\tvolatile uint32_t EMACPDS;   /* Ethernet MAC Power Domain Status */\n\tvolatile uint32_t EMACMPC;   /* Ethernet MAC Memory Power Control */\n\tvolatile uint32_t RESERVED15;\n\tvolatile uint32_t LCDMPC;    /* LCD Memory Power Control */\n\tvolatile uint32_t RESERVED16[26];\n\tvolatile uint32_t PPWD;      /* Watchdog Timer Peripheral Present */\n\tvolatile uint32_t PPTIMER;   /* General-Purpose Timer Peripheral Present */\n\tvolatile uint32_t PPGPIO;    /* General-Purpose I/O Peripheral Present */\n\tvolatile uint32_t PPDMA;     /* Micro DMA Peripheral Present */\n\tvolatile uint32_t PPEPI;     /* EPI Peripheral Present */\n\tvolatile uint32_t PPHIB;     /* Hibernation Peripheral Present */\n\tvolatile uint32_t PPUART;    /* UART Peripheral Present */\n\tvolatile uint32_t PPSSI;     /* Synchronous Serial Inter. Periph. Present */\n\tvolatile uint32_t PPI2C;     /* Inter-Integrated Circuit Periph. Present */\n\tvolatile uint32_t RESERVED17;\n\tvolatile uint32_t PPUSB;     /* Universal Serial Bus Peripheral Present */\n\tvolatile uint32_t RESERVED18;\n\tvolatile uint32_t PPEPHY;    /* Ethernet PHY Peripheral Present */\n\tvolatile uint32_t PPCAN;     /* Controller Area Network Periph. Present */\n\tvolatile uint32_t PPADC;     /* Analog-to-Dig. Converter Periph. Present */\n\tvolatile uint32_t PPACMP;    /* Analog Comparator Peripheral Present */\n\tvolatile uint32_t PPPWM;     /* Pulse Width Modulator Peripheral Present */\n\tvolatile uint32_t PPQEI;     /* Quadrature Encoder Inter. Periph. Present */\n\tvolatile uint32_t RESERVED19[4];\n\tvolatile uint32_t PPEEPROM;  /* EEPROM Peripheral Present */\n\tvolatile uint32_t RESERVED20[6];\n\tvolatile uint32_t PPCCM;     /* CRC/Cryptographic Modules Periph. Present */\n\tvolatile uint32_t RESERVED21[6];\n\tvolatile uint32_t PPLCD;     /* LCD Peripheral Present */\n\tvolatile uint32_t RESERVED22;\n\tvolatile uint32_t PPOWIRE;   /* 1-Wire Peripheral Present */\n\tvolatile uint32_t PPEMAC;    /* Ethernet MAC Peripheral Present */\n\tvolatile uint32_t RESERVED23[88];\n\tvolatile uint32_t SRWD;      /* Watchdog Timer Software Reset */\n\tvolatile uint32_t SRTIMER;   /* General-Purpose Timer Software Reset */\n\tvolatile uint32_t SRGPIO;    /* General-Purpose I/O Software Reset */\n\tvolatile uint32_t SRDMA;     /* Micro Direct Memory Access Software Reset */\n\tvolatile uint32_t SREPI;     /* EPI Software Reset */\n\tvolatile uint32_t SRHIB;     /* Hibernation Software Reset */\n\tvolatile uint32_t SRUART;    /* UART Software Reset */\n\tvolatile uint32_t SRSSI;     /* Synchronous Serial Inter. Software Reset */\n\tvolatile uint32_t SRI2C;     /* Inter-Integrated Circuit Software Reset */\n\tvolatile uint32_t RESERVED24;\n\tvolatile uint32_t SRUSB;     /* Universal Serial Bus Software Reset */\n\tvolatile uint32_t RESERVED25;\n\tvolatile uint32_t SREPHY;    /* Ethernet PHY Software Reset */\n\tvolatile uint32_t SRCAN;     /* Controller Area Network Software Reset */\n\tvolatile uint32_t SRADC;     /* Analog-to-Dig. Converter Software Reset */\n\tvolatile uint32_t SRACMP;    /* Analog Comparator Software Reset */\n\tvolatile uint32_t SRPWM;     /* Pulse Width Modulator Software Reset */\n\tvolatile uint32_t SRQEI;     /* Quadrature Encoder Inter. Software Reset */\n\tvolatile uint32_t RESERVED26[4];\n\tvolatile uint32_t SREEPROM;  /* EEPROM Software Reset */\n\tvolatile uint32_t RESERVED27[6];\n\tvolatile uint32_t SRCCM;     /* CRC/Cryptographic Modules Software Reset */\n\tvolatile uint32_t RESERVED28[6];\n\tvolatile uint32_t SRLCD;     /* LCD Controller Software Reset */\n\tvolatile uint32_t RESERVED29;\n\tvolatile uint32_t SROWIRE;   /* 1-Wire Software Reset */\n\tvolatile uint32_t SREMAC;    /* Ethernet MAC Software Reset */\n\tvolatile uint32_t RESERVED30[24];\n\tvolatile uint32_t RCGCWD;    /* Watchdog Run Mode Clock Gating Control */\n};\n\n/* Peripheral Memory Map */\n#define FLASH_CTRL_BASE 0x400FD000UL\n#define SYSCTL_BASE     0x400FE000UL\n\n/* Peripheral Declarations */\n#define FLASH_CTRL ((struct flash_ctrl *) FLASH_CTRL_BASE)\n#define SYSCTL     ((struct sys_ctrl *) SYSCTL_BASE)\n\n/* The following are defines for the bit fields in the FLASH_FMC register. */\n#define FLASH_FMC_WRKEY  0xA4420000 /* FLASH write key */\n#define FLASH_FMC_COMT   0x00000008 /* Commit Register Value */\n#define FLASH_FMC_MERASE 0x00000004 /* Mass Erase Flash Memory */\n#define FLASH_FMC_ERASE  0x00000002 /* Erase a Page of Flash Memory */\n#define FLASH_FMC_WRITE  0x00000001 /* Write a Word into Flash Memory */\n\n/* The following are defines for the bit fields in the FLASH_FCRIS register. */\n#define FLASH_FCRIS_PROGRIS 0x00002000 /* Program Verify Raw Interrupt Status */\n#define FLASH_FCRIS_ERRIS   0x00000800 /* Erase Verify Raw Interrupt Status */\n#define FLASH_FCRIS_INVDRIS 0x00000400 /* Invalid Data Raw Interrupt Status */\n#define FLASH_FCRIS_VOLTRIS 0x00000200 /* Pump Voltage Raw Interrupt Status */\n#define FLASH_FCRIS_ERIS    0x00000004 /* EEPROM Raw Interrupt Status */\n#define FLASH_FCRIS_PRIS    0x00000002 /* Programming Raw Interrupt Status */\n#define FLASH_FCRIS_ARIS    0x00000001 /* Access Raw Interrupt Status */\n\n/* The following are defines for the bit fields in the FLASH_FCIM register. */\n#define FLASH_FCIM_PROGMASK 0x00002000 /* PROGVER Interrupt Mask */\n#define FLASH_FCIM_ERMASK   0x00000800 /* ERVER Interrupt Mask */\n#define FLASH_FCIM_INVDMASK 0x00000400 /* Invalid Data Interrupt Mask */\n#define FLASH_FCIM_VOLTMASK 0x00000200 /* VOLT Interrupt Mask */\n#define FLASH_FCIM_EMASK    0x00000004 /* EEPROM Interrupt Mask */\n#define FLASH_FCIM_PMASK    0x00000002 /* Programming Interrupt Mask */\n#define FLASH_FCIM_AMASK    0x00000001 /* Access Interrupt Mask */\n\n/* The following are defines for the bit fields in the FLASH_FCMISC register. */\n#define FLASH_FCMISC_PROGMISC 0x00002000 /* PROGVER Interrupt Status/Clear */\n#define FLASH_FCMISC_ERMISC   0x00000800 /* ERVER Interrupt Status/Clear */\n#define FLASH_FCMISC_INVDMISC 0x00000400 /* Invalid Data Int. Status/Clear */\n#define FLASH_FCMISC_VOLTMISC 0x00000200 /* VOLT Interrupt Status/Clear */\n#define FLASH_FCMISC_EMISC    0x00000004 /* EEPROM Interrupt Status/Clear */\n#define FLASH_FCMISC_PMISC    0x00000002 /* Programming Int. Status/Clear */\n#define FLASH_FCMISC_AMISC    0x00000001 /* Access Interrupt Status/Clear */\n\n/* The following are defines for the bit fields in the FLASH_FMC2 register. */\n#define FLASH_FMC2_WRBUF 0x00000001 /* Buffered Flash Memory Write */\n\n/* The following are defines for the bit fields in the SYSCTL_RCGCWD reg. */\n#define SYSCTL_RCGCWD_R1 0x00000002 /* Watchdog 1 Run Mode Clock Gating Cont. */\n#define SYSCTL_RCGCWD_R0 0x00000001 /* Watchdog 0 Run Mode Clock Gating Cont. */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif  /* OPENOCD_LOADERS_FLASH_MSP432_MSP432E4X_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432e4x_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x70,0x13,0x00,0x20,0x11,0x01,0x00,0x20,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,\n0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc9,0x0a,0x00,0x20,\n0xc9,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,0xc9,0x0a,0x00,0x20,0xc9,0x0a,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x41,0xf2,0x00,0x70,0xc2,0xf2,0x00,0x00,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,\n0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x16,0xbc,\n0x34,0x0f,0x00,0x20,0x50,0x0f,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,\n0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,\n0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,\n0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,\n0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,\n0x34,0x0f,0x00,0x20,0x00,0x00,0x00,0x00,0xf8,0x0a,0x00,0x20,0x08,0xb5,0x08,0x4b,\n0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,\n0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,\n0x00,0x00,0x00,0x00,0xf8,0x0a,0x00,0x20,0x38,0x0f,0x00,0x20,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,\n0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,\n0x13,0xf9,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,\n0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0xb0,0xf8,\n0x00,0xf0,0xda,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0x70,0xfb,0x00,0xf0,0xae,0xf8,\n0x00,0x00,0x08,0x00,0x70,0x13,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x34,0x0f,0x00,0x20,0x50,0x0f,0x00,0x20,0xfd,0x03,0x00,0x20,0x84,0x46,0x41,0xea,\n0x00,0x03,0x13,0xf0,0x03,0x03,0x6d,0xd1,0x40,0x3a,0x41,0xd3,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x40,0x3a,0xbd,0xd2,\n0x30,0x32,0x11,0xd3,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,0x40,0xf8,0x04,0x3b,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x10,0x3a,0xed,0xd2,0x0c,0x32,0x05,0xd3,0x51,0xf8,0x04,0x3b,\n0x40,0xf8,0x04,0x3b,0x04,0x3a,0xf9,0xd2,0x04,0x32,0x08,0xd0,0xd2,0x07,0x1c,0xbf,\n0x11,0xf8,0x01,0x3b,0x00,0xf8,0x01,0x3b,0x01,0xd3,0x0b,0x88,0x03,0x80,0x60,0x46,\n0x70,0x47,0x00,0xbf,0x08,0x2a,0x13,0xd3,0x8b,0x07,0x8d,0xd0,0x10,0xf0,0x03,0x03,\n0x8a,0xd0,0xc3,0xf1,0x04,0x03,0xd2,0x1a,0xdb,0x07,0x1c,0xbf,0x11,0xf8,0x01,0x3b,\n0x00,0xf8,0x01,0x3b,0x80,0xd3,0x31,0xf8,0x02,0x3b,0x20,0xf8,0x02,0x3b,0x7b,0xe7,\n0x04,0x3a,0xd9,0xd3,0x01,0x3a,0x11,0xf8,0x01,0x3b,0x00,0xf8,0x01,0x3b,0xf9,0xd2,\n0x0b,0x78,0x03,0x70,0x4b,0x78,0x43,0x70,0x8b,0x78,0x83,0x70,0x60,0x46,0x70,0x47,\n0x01,0x46,0x00,0x20,0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,\n0x04,0x46,0x00,0xf0,0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,\n0x20,0x46,0x00,0xf0,0x55,0xf9,0x00,0xbf,0xf4,0x0a,0x00,0x20,0x38,0xb5,0x08,0x4b,\n0x08,0x4d,0xed,0x1a,0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,\n0x04,0x3d,0x98,0x47,0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0x60,0xbb,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,\n0xb6,0x10,0x18,0xbf,0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,\n0xa6,0x42,0xf9,0xd1,0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0x43,0xfb,0xb6,0x10,\n0x18,0xbf,0x00,0x24,0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,\n0xf9,0xd1,0x70,0xbd,0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0xd4,0x0a,0x00,0x20,0xcc,0x0a,0x00,0x20,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,\n0x00,0x2a,0x41,0xd0,0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,\n0x03,0xf8,0x01,0x5b,0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,\n0x05,0x25,0x0f,0x2c,0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,\n0x10,0x3e,0x0f,0x2e,0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,\n0x42,0xf8,0x04,0x5c,0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,\n0x0f,0x02,0x04,0xf0,0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,\n0x22,0x46,0x04,0x3a,0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,\n0x03,0x02,0x04,0x32,0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,\n0x03,0xf8,0x01,0x1b,0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,\n0xc2,0xe7,0x00,0xbf,0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,\n0x06,0x46,0x88,0x46,0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,\n0x43,0x1c,0x7e,0xb1,0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,\n0x88,0x71,0x01,0xfa,0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,\n0x08,0x91,0x1e,0xd0,0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,\n0xf0,0x87,0x14,0x4b,0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,\n0xd0,0xb1,0xd5,0xf8,0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,\n0x38,0x46,0x01,0x23,0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,\n0xd0,0xe7,0xd4,0xf8,0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,\n0xa6,0x74,0xc5,0xf8,0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,\n0xf4,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,\n0x07,0xbf,0x70,0x47,0x00,0x00,0x00,0x00,0xfd,0x03,0x00,0x20,0x2d,0xe9,0xf0,0x4f,\n0x31,0x4b,0x83,0xb0,0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,\n0x01,0x93,0x00,0x9b,0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,\n0x65,0x1e,0x0e,0xd4,0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,\n0xd4,0xf8,0x00,0x31,0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,\n0xf5,0xd1,0x22,0x4b,0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,\n0x34,0xd0,0x38,0x46,0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,\n0x00,0x2f,0xdc,0xd1,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,\n0xab,0x42,0x0c,0xbf,0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,\n0x88,0x31,0xd7,0xf8,0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,\n0x7b,0x68,0x5b,0x45,0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,\n0xd7,0xf8,0x8c,0x31,0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,\n0xee,0xe7,0xd4,0xf8,0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,\n0x00,0x2f,0xac,0xd1,0xce,0xe7,0x00,0xbf,0xf4,0x0a,0x00,0x20,0x00,0x00,0x00,0x00,\n0xfe,0xe7,0x00,0xbf,0x2d,0xe9,0xf0,0x4f,0xa8,0x4b,0xa9,0x4a,0xde,0x68,0xd3,0xf8,\n0x10,0xb0,0x85,0xb0,0x42,0xf2,0x03,0x61,0x00,0x24,0x99,0x46,0xa5,0x4b,0x51,0x61,\n0x15,0x46,0x90,0x46,0x00,0x94,0xbb,0xf5,0x80,0x5f,0x93,0xbf,0x5f,0x46,0xab,0xf5,\n0x80,0x5b,0x4f,0xf4,0x80,0x57,0x4f,0xf0,0x00,0x0b,0x03,0xe0,0xd9,0xf8,0x18,0x20,\n0xd2,0x06,0x03,0xd4,0xd9,0xf8,0x14,0x20,0xd1,0x06,0xf7,0xd5,0xd9,0xf8,0x14,0x20,\n0x12,0xf0,0x10,0x02,0x00,0xf0,0xb9,0x80,0xd9,0xf8,0x14,0x20,0x42,0xf0,0x01,0x02,\n0xc9,0xf8,0x14,0x20,0x4f,0xf0,0x20,0x24,0x4f,0xf0,0x01,0x0a,0x16,0xf0,0x03,0x02,\n0x00,0xf0,0xa9,0x80,0x26,0xf0,0x03,0x0c,0xdc,0xf8,0x00,0x10,0x03,0x91,0x47,0xb3,\n0x21,0x46,0x78,0x1e,0x11,0xf8,0x01,0xeb,0x01,0x91,0x04,0xa9,0x11,0x44,0x01,0xf8,\n0x04,0xec,0x02,0xf1,0x01,0x01,0x06,0xf1,0x01,0x0e,0x00,0xf0,0x01,0x81,0x04,0x29,\n0x00,0xf0,0xfe,0x80,0x04,0xa8,0x01,0x44,0x60,0x78,0x01,0xf8,0x04,0x0c,0xb9,0x1e,\n0x00,0x29,0x06,0xf1,0x02,0x00,0x04,0xf1,0x02,0x0e,0x40,0xf3,0xec,0x80,0x01,0x2a,\n0x40,0xf0,0xe9,0x80,0xa2,0x78,0x8d,0xf8,0x0f,0x20,0x03,0x99,0x03,0x36,0x03,0x3f,\n0x03,0x34,0x78,0x4a,0x69,0x60,0xc5,0xf8,0x00,0xc0,0xaa,0x60,0xaa,0x68,0xd0,0x07,\n0xfc,0xd4,0xd8,0xf8,0x0c,0x10,0x42,0xf2,0x05,0x42,0x0a,0x40,0xb2,0xfa,0x82,0xf2,\n0x52,0x09,0x03,0x2f,0x1a,0xdd,0x71,0x06,0x79,0xd0,0x00,0x2a,0x75,0xd0,0x54,0xf8,\n0x04,0x2b,0x6a,0x60,0x2e,0x60,0xab,0x60,0xaa,0x68,0xd2,0x07,0xfc,0xd4,0xd8,0xf8,\n0x0c,0x10,0x04,0x3f,0x42,0xf2,0x05,0x42,0x03,0x2f,0x02,0xea,0x01,0x02,0x06,0xf1,\n0x04,0x06,0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,0xe4,0xdc,0x00,0x2f,0x15,0xdc,\n0xba,0xf1,0x00,0x0f,0x33,0xd0,0xd9,0xf8,0x14,0x10,0x21,0xf0,0x11,0x01,0xc9,0xf8,\n0x14,0x10,0x00,0x2a,0x38,0xd0,0xbb,0xf1,0x00,0x0f,0x7f,0xf4,0x6c,0xaf,0x57,0x4b,\n0x40,0xf6,0xce,0x22,0x5a,0x60,0x05,0xb0,0xbd,0xe8,0xf0,0x8f,0x00,0x2a,0xe7,0xd0,\n0x04,0xa8,0x32,0x68,0x40,0xf8,0x04,0x2d,0x21,0x46,0x3a,0x46,0x01,0x93,0xff,0xf7,\n0x45,0xfd,0x03,0x9a,0x4f,0x4b,0x6a,0x60,0x2e,0x60,0xab,0x60,0x01,0x9b,0x37,0x44,\n0xaa,0x68,0xd2,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x10,0x42,0xf2,0x05,0x42,0x0a,0x40,\n0x3e,0x46,0xb2,0xfa,0x82,0xf2,0x52,0x09,0xba,0xf1,0x00,0x0f,0xcb,0xd1,0x00,0x99,\n0x00,0x29,0xce,0xd0,0xd9,0xf8,0x18,0x10,0xcd,0xf8,0x00,0xa0,0x21,0xf0,0x11,0x01,\n0xc9,0xf8,0x18,0x10,0x00,0x2a,0xc6,0xd1,0x3c,0x4b,0x4d,0xf6,0xad,0x62,0x5a,0x60,\n0x05,0xb0,0xbd,0xe8,0xf0,0x8f,0x01,0x22,0x93,0xe7,0xd9,0xf8,0x18,0x10,0x11,0xf0,\n0x10,0x01,0x5e,0xd0,0xd9,0xf8,0x18,0x10,0x37,0x4c,0x41,0xf0,0x01,0x01,0x92,0x46,\n0x01,0x22,0xc9,0xf8,0x18,0x10,0x00,0x92,0x40,0xe7,0x00,0x22,0xa0,0xe7,0x1f,0x2f,\n0x32,0xdd,0x00,0x2a,0xf9,0xd0,0x07,0xf1,0xff,0x3e,0x2e,0xf0,0x03,0x0e,0x0e,0xf1,\n0x04,0x0e,0xa6,0x44,0x39,0x46,0x04,0xf1,0x80,0x0c,0x00,0x22,0x01,0xe0,0x64,0x45,\n0x0b,0xd0,0x54,0xf8,0x04,0x7b,0x02,0xf1,0x40,0x00,0x74,0x45,0xa1,0xf1,0x04,0x01,\n0x45,0xf8,0x20,0x70,0x02,0xf1,0x01,0x02,0xf1,0xd1,0x2e,0x60,0x0f,0x46,0x2b,0x62,\n0x2a,0x6a,0xd0,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x00,0x42,0xf2,0x05,0x42,0x1f,0x29,\n0x02,0xea,0x00,0x02,0x06,0xf1,0x80,0x06,0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,\n0xcf,0xdc,0x03,0x29,0x7f,0xf7,0x6a,0xaf,0x00,0x2a,0xc6,0xd0,0x54,0xf8,0x04,0x2b,\n0x6a,0x60,0x2e,0x60,0xab,0x60,0xaa,0x68,0xd1,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x10,\n0x04,0x3f,0x42,0xf2,0x05,0x42,0x03,0x2f,0x02,0xea,0x01,0x02,0x06,0xf1,0x04,0x06,\n0xb2,0xfa,0x82,0xf2,0x4f,0xea,0x52,0x12,0xe6,0xdc,0x00,0x2f,0x7f,0xf7,0x50,0xaf,\n0x64,0xe7,0x8a,0x46,0xea,0xe6,0x0f,0x46,0x74,0x46,0x06,0x46,0x03,0x99,0x18,0xe7,\n0x01,0x9c,0x03,0x99,0x07,0x46,0x76,0x46,0x13,0xe7,0x00,0xbf,0x50,0x01,0x00,0x20,\n0x00,0xd0,0x0f,0x40,0x01,0x00,0x42,0xa4,0x00,0x30,0x00,0x20,0x80,0xb5,0x72,0xb6,\n0x52,0x4a,0x53,0x4c,0xd2,0xf8,0x00,0x36,0x52,0x4d,0x53,0x4f,0x53,0x4e,0x23,0xf0,\n0x03,0x03,0xc2,0xf8,0x00,0x36,0xa0,0x46,0x2b,0x68,0x20,0x2b,0x00,0xf2,0x8d,0x80,\n0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,0x79,0x09,0x00,0x20,0x75,0x0a,0x00,0x20,\n0x4b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x3d,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x21,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x0d,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,\n0x9b,0x0a,0x00,0x20,0x9b,0x0a,0x00,0x20,0x3d,0x0a,0x00,0x20,0x2c,0x49,0x00,0x23,\n0x01,0x20,0x40,0xf6,0xce,0x22,0x68,0x60,0x8b,0x60,0x6a,0x60,0x2b,0x60,0xab,0xe7,\n0x27,0x49,0x4f,0xf0,0x01,0x0e,0x4f,0xf0,0x00,0x50,0x40,0xf6,0xce,0x22,0x00,0x23,\n0xc5,0xf8,0x04,0xe0,0x88,0x60,0x6a,0x60,0x2b,0x60,0x9d,0xe7,0x01,0x23,0x6b,0x60,\n0xff,0xf7,0x30,0xfe,0x00,0x23,0x2b,0x60,0x96,0xe7,0x40,0xf6,0x03,0x23,0x01,0x22,\n0x6a,0x60,0x63,0x61,0xeb,0x68,0x23,0x60,0xa7,0x60,0xa3,0x68,0x9b,0x07,0xfc,0xd4,\n0xd8,0xf8,0x0c,0x20,0x40,0xf6,0x01,0x23,0x13,0x40,0xd3,0xb9,0x40,0xf6,0xce,0x23,\n0x6b,0x60,0xe7,0xe7,0x01,0x22,0x40,0xf6,0x03,0x23,0x6a,0x60,0x63,0x61,0xa6,0x60,\n0xa3,0x68,0x5a,0x07,0xfc,0xd4,0xd8,0xf8,0x0c,0x20,0x40,0xf6,0x01,0x23,0x13,0x40,\n0x00,0x2b,0xeb,0xd0,0x0b,0x4b,0x6b,0x60,0xd4,0xe7,0x40,0xf6,0xad,0x33,0x6b,0x60,\n0x6a,0xe7,0x4d,0xf6,0xad,0x63,0x6b,0x60,0xcc,0xe7,0x00,0xbf,0x00,0xe0,0x0f,0x40,\n0x00,0xd0,0x0f,0x40,0x50,0x01,0x00,0x20,0x02,0x00,0x42,0xa4,0x04,0x00,0x42,0xa4,\n0x00,0xed,0x00,0xe0,0xad,0xde,0xad,0xde,0xfe,0xe7,0x00,0xbf,0xfd,0x01,0x00,0x20,\n0xb9,0x05,0x00,0x20,0xf8,0xb5,0x00,0xbf,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,\n0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x20,0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,\n0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,0x3c,0xf7,0xff,0x7f,0x01,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf4,0x22,0x00,0x20,\n0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x0a,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,\n0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x08,0x20,0x00,0x20,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p401x/msp432p401x.lds",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\nMEMORY {\n\tMAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00040000\n\tINFO_FLASH (RX) : ORIGIN = 0x00200000, LENGTH = 0x00004000\n\tSRAM_CODE_0(RWX): ORIGIN = 0x01000000, LENGTH = 0x00000110\n\tSRAM_CODE_1(RWX): ORIGIN = 0x01000110, LENGTH = 0x00000030\n\tSRAM_CODE_2(RWX): ORIGIN = 0x01000150, LENGTH = 0x00000040\n\tSRAM_CODE_3(RWX): ORIGIN = 0x01000190, LENGTH = 0x00000F70\n\tSRAM_CODE_4(RWX): ORIGIN = 0x01001170, LENGTH = 0x00000200\n\tSRAM_DATA  (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000\n}\n\nREGION_ALIAS(\"REGION_INTVECT\", SRAM_CODE_0);\nREGION_ALIAS(\"REGION_RESET\", SRAM_CODE_1);\nREGION_ALIAS(\"REGION_DESCRIPTOR\", SRAM_CODE_2);\nREGION_ALIAS(\"REGION_TEXT\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_BSS\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_DATA\", SRAM_DATA);\nREGION_ALIAS(\"REGION_STACK\", SRAM_CODE_4);\nREGION_ALIAS(\"REGION_HEAP\", SRAM_DATA);\nREGION_ALIAS(\"REGION_ARM_EXIDX\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_ARM_EXTAB\", SRAM_CODE_3);\n\n\nSECTIONS {\n\t/* section for the interrupt vector area */\n\t.intvecs : {\n\t\tKEEP (*(.intvecs))\n\t} > REGION_INTVECT\n\n\tPROVIDE (_vtable_base_address =\n\t\tDEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);\n\n\t.vtable (_vtable_base_address) : AT (_vtable_base_address) {\n\t\tKEEP (*(.vtable))\n\t} > REGION_DATA\n\n\t.descriptor :{\n\t\tFILL(0x00000000);\n\t\t. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;\n\t\tBYTE(0x00);\n\t\t__ROM_AT = .;\n\t} > REGION_DESCRIPTOR\n\n\t.reset : {\n\t\tKEEP(*(.reset))\n\t} > REGION_RESET AT> REGION_RESET\n\n\t.text : {\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP (*(.text))\n\t\t*(.text.*)\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.ctors))\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.dtors))\n\t\t. = ALIGN(0x4);\n\t\t__init_array_start = .;\n\t\tKEEP (*(.init_array*))\n\t\t__init_array_end = .;\n\t\tKEEP (*(.init))\n\t\tKEEP (*(.fini*))\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.rodata : {\n\t\t*(.rodata)\n\t\t*(.rodata.*)\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.ARM.exidx : {\n\t\t__exidx_start = .;\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t\t__exidx_end = .;\n\t} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX\n\n\t.ARM.extab : {\n\t\tKEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))\n\t} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB\n\n\t__etext = .;\n\n\t.data : {\n\t\t__data_load__ = LOADADDR (.data);\n\t\t__data_start__ = .;\n\t\tKEEP (*(.data))\n\t\tKEEP (*(.data*))\n\t\t. = ALIGN (4);\n\t\t__data_end__ = .;\n\t} > REGION_DATA AT> REGION_TEXT\n\n\t.bss : {\n\t\t__bss_start__ = .;\n\t\t*(.shbss)\n\t\tKEEP (*(.bss))\n\t\t*(.bss.*)\n\t\t*(COMMON)\n\t\t. = ALIGN (4);\n\t\t__bss_end__ = .;\n\t} > REGION_BSS AT> REGION_BSS\n\n\t.heap : {\n\t\t__heap_start__ = .;\n\t\tend = __heap_start__;\n\t\t_end = end;\n\t\t__end = end;\n\t\tKEEP (*(.heap))\n\t\t__heap_end__ = .;\n\t\t__HeapLimit = __heap_end__;\n\t} > REGION_HEAP AT> REGION_HEAP\n\n\t.stack (NOLOAD) : ALIGN(0x8) {\n\t\t_stack = .;\n\t\tKEEP(*(.stack))\n\t} > REGION_STACK AT> REGION_STACK\n\n\t__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);\n\tPROVIDE(__stack = __stack_top);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p401x.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H\n#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#define __MCU_HAS_FLCTL__ /* Module FLCTL is available */\n\n/* Device and peripheral memory map */\n#define FLASH_BASE  ((uint32_t)0x00000000)     /* Flash memory start address */\n#define SRAM_BASE   ((uint32_t)0x20000000)     /* SRAM memory start address */\n#define PERIPH_BASE ((uint32_t)0x40000000)     /* Peripherals start address */\n#define CS_BASE     (PERIPH_BASE + 0x00010400) /* Address of module CS regs. */\n#define DIO_BASE    (PERIPH_BASE + 0x00004C00) /* Address of module DIO regs. */\n\n/* Register map for Clock Signal peripheral (CS) */\nstruct cs {\n\tvolatile uint32_t KEY;  /* Key Register */\n\tvolatile uint32_t CTL0; /* Control 0 Register */\n\tvolatile uint32_t CTL1; /* Control 1 Register */\n\tvolatile uint32_t CTL2; /* Control 2 Register */\n\tvolatile uint32_t CTL3; /* Control 3 Register */\n};\n\n/* Register map for DIO port (odd interrupt) */\nstruct dio_port_odd_int {\n\tvolatile uint8_t IN;  /* Port Input */\n\tuint8_t RESERVED0;\n\tvolatile uint8_t OUT; /* Port Output */\n};\n\n/* Register map for DIO port (even interrupt) */\nstruct dio_port_even_int {\n\tuint8_t RESERVED0;\n\tvolatile uint8_t IN;  /* Port Input */\n\tuint8_t RESERVED1;\n\tvolatile uint8_t OUT; /* Port Output */\n};\n\n/* Peripheral declarations */\n#define CS ((struct cs *) CS_BASE)\n#define P3 ((struct dio_port_odd_int *) (DIO_BASE + 0x0020))\n#define P6 ((struct dio_port_even_int *) (DIO_BASE + 0x0040))\n\n/* Peripheral bit definitions */\n\n/* DCORSEL Bit Mask */\n#define CS_CTL0_DCORSEL_MASK ((uint32_t)0x00070000)\n/* Nominal DCO Frequency Range (MHz): 2 to 4 */\n#define CS_CTL0_DCORSEL_1 ((uint32_t)0x00010000)\n/* Nominal DCO Frequency Range (MHz): 16 to 32 */\n#define CS_CTL0_DCORSEL_4 ((uint32_t)0x00040000)\n/* CS control key value */\n#define CS_KEY_VAL ((uint32_t)0x0000695A)\n\n/* Protects Sector 0 from program or erase */\n#define FLCTL_BANK0_MAIN_WEPROT_PROT0 ((uint32_t)0x00000001)\n/* Protects Sector 1 from program or erase */\n#define FLCTL_BANK0_MAIN_WEPROT_PROT1 ((uint32_t)0x00000002)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P401X_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p401x_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x70,0x13,0x00,0x01,0x11,0x01,0x00,0x01,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,\n0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa1,0x0a,0x00,0x01,\n0xa1,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0xa1,0x0a,0x00,0x01,0xa1,0x0a,0x00,0x01,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x41,0xf2,0x00,0x70,0xc0,0xf2,0x00,0x10,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,\n0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0x96,0xbb,\n0x0c,0x0f,0x00,0x01,0x28,0x0f,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,\n0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,\n0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,\n0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,\n0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,\n0x0c,0x0f,0x00,0x01,0x00,0x00,0x00,0x00,0xd0,0x0a,0x00,0x01,0x08,0xb5,0x08,0x4b,\n0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,\n0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,\n0x00,0x00,0x00,0x00,0xd0,0x0a,0x00,0x01,0x10,0x0f,0x00,0x01,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,\n0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,\n0x79,0xf8,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,\n0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0x16,0xf8,\n0x00,0xf0,0x40,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0xf0,0xfa,0x00,0xf0,0x14,0xf8,\n0x00,0x00,0x08,0x00,0x70,0x13,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x0c,0x0f,0x00,0x01,0x28,0x0f,0x00,0x01,0xc9,0x02,0x00,0x01,0x01,0x46,0x00,0x20,\n0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,0x04,0x46,0x00,0xf0,\n0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,0x20,0x46,0x00,0xf0,\n0x55,0xf9,0x00,0xbf,0xcc,0x0a,0x00,0x01,0x38,0xb5,0x08,0x4b,0x08,0x4d,0xed,0x1a,\n0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,0x04,0x3d,0x98,0x47,\n0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0xe6,0xbb,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,0xb6,0x10,0x18,0xbf,\n0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,\n0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0xc9,0xfb,0xb6,0x10,0x18,0xbf,0x00,0x24,\n0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,0x70,0xbd,\n0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xac,0x0a,0x00,0x01,\n0xa4,0x0a,0x00,0x01,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,0x00,0x2a,0x41,0xd0,\n0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,0x03,0xf8,0x01,0x5b,\n0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,0x05,0x25,0x0f,0x2c,\n0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,0x10,0x3e,0x0f,0x2e,\n0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,0x42,0xf8,0x04,0x5c,\n0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,0x0f,0x02,0x04,0xf0,\n0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,0x22,0x46,0x04,0x3a,\n0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,0x03,0x02,0x04,0x32,\n0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,0x03,0xf8,0x01,0x1b,\n0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,0xc2,0xe7,0x00,0xbf,\n0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,0x06,0x46,0x88,0x46,\n0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,0x43,0x1c,0x7e,0xb1,\n0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,0x88,0x71,0x01,0xfa,\n0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,0x08,0x91,0x1e,0xd0,\n0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,0xf0,0x87,0x14,0x4b,\n0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,0xd0,0xb1,0xd5,0xf8,\n0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,0x38,0x46,0x01,0x23,\n0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,0xd0,0xe7,0xd4,0xf8,\n0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,0xa6,0x74,0xc5,0xf8,\n0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,0xcc,0x0a,0x00,0x01,\n0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,0x07,0xbf,0x70,0x47,\n0x00,0x00,0x00,0x00,0xc9,0x02,0x00,0x01,0x2d,0xe9,0xf0,0x4f,0x31,0x4b,0x83,0xb0,\n0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,0x01,0x93,0x00,0x9b,\n0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,0x65,0x1e,0x0e,0xd4,\n0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,0xd4,0xf8,0x00,0x31,\n0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,0xf5,0xd1,0x22,0x4b,\n0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,0x34,0xd0,0x38,0x46,\n0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,0x00,0x2f,0xdc,0xd1,\n0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,0xab,0x42,0x0c,0xbf,\n0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,0x88,0x31,0xd7,0xf8,\n0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,0x7b,0x68,0x5b,0x45,\n0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,0xd7,0xf8,0x8c,0x31,\n0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,0xee,0xe7,0xd4,0xf8,\n0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,0x00,0x2f,0xac,0xd1,\n0xce,0xe7,0x00,0xbf,0xcc,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0xfe,0xe7,0x00,0xbf,\n0xef,0xf3,0x10,0x80,0x72,0xb6,0x70,0x47,0xf8,0xb5,0x20,0x4e,0x20,0x4a,0x33,0x68,\n0x20,0x4d,0x21,0x4f,0x21,0x4c,0x4f,0xf0,0x80,0x71,0x91,0x60,0x9b,0x6d,0x00,0x20,\n0x98,0x47,0x33,0x68,0x28,0x60,0x9b,0x6d,0x01,0x20,0x98,0x47,0x3b,0x68,0x68,0x60,\n0x5b,0x68,0x98,0x47,0x3b,0x68,0x28,0x73,0x1b,0x6a,0x98,0x47,0x63,0x68,0x3a,0x68,\n0x68,0x73,0x03,0xf4,0xe0,0x23,0xab,0x60,0x93,0x69,0x00,0x20,0x98,0x47,0x33,0x68,\n0x02,0x21,0x5b,0x6d,0x05,0x46,0x00,0x20,0x98,0x47,0x33,0x68,0x01,0x20,0x5b,0x6d,\n0x02,0x21,0x98,0x47,0x46,0xf6,0x5a,0x13,0x23,0x60,0x63,0x68,0x23,0xf4,0xe0,0x23,\n0x43,0xf4,0x80,0x23,0x00,0x22,0x63,0x60,0x22,0x60,0x09,0x4b,0x1d,0xb1,0x40,0xf6,\n0xce,0x22,0x5a,0x60,0xf8,0xbd,0x07,0x4a,0x5a,0x60,0xf8,0xbd,0x1c,0x08,0x00,0x02,\n0x00,0xed,0x00,0xe0,0x80,0x01,0x00,0x20,0x34,0x08,0x00,0x02,0x00,0x04,0x01,0x40,\n0x50,0x01,0x00,0x20,0x00,0xad,0xde,0x00,0x2d,0xe9,0xf8,0x4f,0x4e,0x4c,0x25,0x69,\n0xe7,0x68,0x00,0x2d,0x6d,0xd0,0xdf,0xf8,0x38,0xb1,0xdf,0xf8,0x38,0xa1,0xdf,0xf8,\n0x38,0x91,0x4f,0xf0,0x00,0x08,0xdb,0xf8,0x00,0x30,0xb5,0xf5,0x80,0x5f,0x1b,0x69,\n0x4f,0xf0,0xff,0x31,0x4f,0xf0,0x01,0x00,0x93,0xbf,0x2e,0x46,0xa5,0xf5,0x80,0x55,\n0x4f,0xf4,0x80,0x56,0x00,0x25,0x98,0x47,0xdb,0xf8,0x00,0x30,0x4f,0xf0,0xff,0x31,\n0x1b,0x69,0x02,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x03,0x20,0x1b,0x69,0x01,0x46,\n0x98,0x47,0x23,0x6a,0x0b,0x2b,0x03,0xd1,0x60,0xe0,0xa3,0x69,0xd9,0x06,0x02,0xd4,\n0x63,0x69,0xd8,0x06,0xf9,0xd5,0x63,0x69,0xda,0x06,0x3c,0xd5,0x63,0x69,0xdb,0xf8,\n0x00,0x20,0x43,0xf0,0x01,0x03,0x63,0x61,0x93,0x6a,0x39,0x46,0x4f,0xf0,0x20,0x20,\n0x32,0x46,0x98,0x47,0x99,0xf8,0x03,0x30,0x03,0xf0,0xef,0x03,0x89,0xf8,0x03,0x30,\n0x63,0x69,0x23,0xf0,0x11,0x03,0x80,0x46,0x37,0x44,0x63,0x61,0xdb,0xf8,0x00,0x30,\n0x4f,0xf0,0xff,0x31,0x5b,0x69,0x01,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x4f,0xf0,\n0xff,0x31,0x5b,0x69,0x02,0x20,0x98,0x47,0xdb,0xf8,0x00,0x30,0x03,0x20,0x5b,0x69,\n0x01,0x46,0x98,0x47,0xdb,0xf8,0x00,0x30,0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,\n0xb8,0xf1,0x00,0x0f,0x29,0xd0,0x00,0x2d,0x9d,0xd1,0x17,0x4b,0x40,0xf6,0xce,0x22,\n0x5a,0x60,0xbd,0xe8,0xf8,0x8f,0xa3,0x69,0xdb,0x06,0xd7,0xd5,0xa3,0x69,0xdb,0xf8,\n0x00,0x20,0x12,0x48,0x43,0xf0,0x01,0x03,0xa3,0x61,0x93,0x6a,0x39,0x46,0x32,0x46,\n0x98,0x47,0x9a,0xf8,0x02,0x30,0x03,0xf0,0xbf,0x03,0x8a,0xf8,0x02,0x30,0xa3,0x69,\n0x23,0xf0,0x11,0x03,0x80,0x46,0x37,0x44,0xa3,0x61,0xbf,0xe7,0xdb,0xf8,0x00,0x30,\n0x03,0x21,0x1b,0x69,0x04,0x20,0x98,0x47,0x9a,0xe7,0x03,0x4b,0x4d,0xf6,0xad,0x62,\n0x5a,0x60,0xbd,0xe8,0xf8,0x8f,0x00,0xbf,0x50,0x01,0x00,0x20,0x00,0x30,0x00,0x20,\n0x1c,0x08,0x00,0x02,0x20,0x4c,0x00,0x40,0x40,0x4c,0x00,0x40,0x13,0x4b,0xdb,0x69,\n0xda,0x07,0x70,0xb5,0x14,0xd4,0x11,0x4c,0xe3,0x69,0x9b,0x07,0x00,0xd4,0x70,0xbd,\n0x0f,0x4d,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,0x98,0x47,0x23,0x6a,0x0b,0x2b,\n0xf5,0xd1,0x2b,0x68,0x04,0x20,0x1b,0x69,0x03,0x21,0xbd,0xe8,0x70,0x40,0x18,0x47,\n0x07,0x4c,0x23,0x68,0x4f,0xf0,0xff,0x31,0x1b,0x69,0x01,0x20,0x98,0x47,0x23,0x68,\n0x4f,0xf0,0xff,0x31,0x1b,0x69,0x02,0x20,0x98,0x47,0xdc,0xe7,0x50,0x01,0x00,0x20,\n0x1c,0x08,0x00,0x02,0x2d,0xe9,0xf8,0x43,0x1e,0x4c,0x1f,0x4d,0x1f,0x4f,0x29,0x68,\n0x3a,0x68,0xdf,0xf8,0x84,0x90,0x46,0xf6,0x5a,0x18,0xc4,0xf8,0x00,0x80,0x63,0x68,\n0x23,0xf4,0xe0,0x23,0x00,0x26,0x43,0xf4,0x80,0x33,0x63,0x60,0x26,0x60,0x53,0x6d,\n0x30,0x46,0x98,0x47,0x3b,0x68,0x69,0x68,0x5b,0x6d,0x01,0x20,0x98,0x47,0xd9,0xf8,\n0x00,0x30,0x68,0x7b,0x9b,0x69,0x98,0x47,0xd9,0xf8,0x00,0x30,0x07,0x46,0x1b,0x68,\n0x28,0x7b,0x98,0x47,0xc4,0xf8,0x00,0x80,0x63,0x68,0xaa,0x68,0x0c,0x49,0x23,0xf4,\n0xe0,0x23,0x13,0x43,0x63,0x60,0x26,0x60,0x0a,0x4b,0x8e,0x60,0x28,0xb1,0x27,0xb1,\n0x40,0xf6,0xce,0x22,0x5a,0x60,0xbd,0xe8,0xf8,0x83,0x4d,0xf6,0xad,0x62,0x5a,0x60,\n0xbd,0xe8,0xf8,0x83,0x00,0x04,0x01,0x40,0x80,0x01,0x00,0x20,0x1c,0x08,0x00,0x02,\n0x00,0xed,0x00,0xe0,0x50,0x01,0x00,0x20,0x34,0x08,0x00,0x02,0x8c,0x4b,0x8d,0x4c,\n0x1b,0x68,0x8d,0x4d,0x1b,0x68,0x80,0xb5,0x98,0x47,0xff,0xf7,0x81,0xfe,0x27,0x46,\n0x23,0x68,0x20,0x2b,0x00,0xf2,0xeb,0x80,0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,\n0x71,0x08,0x00,0x01,0xff,0x09,0x00,0x01,0xb9,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x2f,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x21,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x13,0x09,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,0x4f,0x0a,0x00,0x01,\n0x05,0x09,0x00,0x01,0x01,0x23,0x63,0x60,0xff,0xf7,0x86,0xfe,0x00,0x23,0x23,0x60,\n0xae,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x55,0xff,0x00,0x23,0x23,0x60,0xa7,0xe7,\n0x01,0x23,0x63,0x60,0xff,0xf7,0x28,0xfe,0x00,0x23,0x23,0x60,0xa0,0xe7,0x2b,0x68,\n0x01,0x20,0x60,0x60,0x1b,0x69,0x4f,0xf0,0xff,0x31,0x98,0x47,0x2b,0x68,0x4f,0xf0,\n0xff,0x31,0x1b,0x69,0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,\n0x98,0x47,0x23,0x6a,0x0b,0x2b,0x00,0xf0,0x82,0x80,0x63,0x69,0xdb,0x06,0xfc,0xd5,\n0x7b,0x69,0x28,0x68,0x43,0xf0,0x01,0x03,0x7b,0x61,0xf9,0x68,0x83,0x6a,0x3a,0x69,\n0x4f,0xf0,0x20,0x20,0x98,0x47,0x7b,0x69,0x2a,0x68,0x23,0xf0,0x11,0x03,0x7b,0x61,\n0x53,0x69,0x06,0x46,0x4f,0xf0,0xff,0x31,0x01,0x20,0x98,0x47,0x2b,0x68,0x4f,0xf0,\n0xff,0x31,0x5b,0x69,0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x5b,0x69,0x01,0x46,\n0x98,0x47,0x2b,0x68,0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,0x00,0x2e,0x52,0xd0,\n0x40,0xf6,0xce,0x23,0x7b,0x60,0xb0,0xe7,0x2b,0x68,0x01,0x20,0x60,0x60,0x1b,0x69,\n0x4f,0xf0,0xff,0x31,0x98,0x47,0x2b,0x68,0x4f,0xf0,0xff,0x31,0x1b,0x69,0x02,0x20,\n0x98,0x47,0x2b,0x68,0x03,0x20,0x1b,0x69,0x01,0x46,0x98,0x47,0x23,0x6a,0x0b,0x2b,\n0x43,0xd0,0x05,0x26,0x2b,0x68,0xe0,0x68,0x5b,0x6a,0x98,0x47,0x01,0x3e,0x00,0x28,\n0x47,0xd1,0x00,0x2e,0xf6,0xd1,0x4d,0xf6,0xad,0x63,0x63,0x60,0x0e,0xe0,0x01,0x23,\n0x63,0x60,0xff,0xf7,0xb3,0xfe,0x05,0x26,0x2b,0x68,0x1b,0x6a,0x98,0x47,0x01,0x3e,\n0x00,0x28,0x30,0xd1,0x00,0x2e,0xf7,0xd1,0x20,0x4b,0x63,0x60,0x2b,0x68,0x4f,0xf0,\n0xff,0x31,0x5b,0x69,0x01,0x20,0x98,0x47,0x2b,0x68,0x4f,0xf0,0xff,0x31,0x5b,0x69,\n0x02,0x20,0x98,0x47,0x2b,0x68,0x03,0x20,0x5b,0x69,0x01,0x46,0x98,0x47,0x2b,0x68,\n0x04,0x20,0x5b,0x69,0x03,0x21,0x98,0x47,0x00,0x23,0x23,0x60,0x10,0xe7,0x40,0xf6,\n0xad,0x33,0x63,0x60,0x0c,0xe7,0x4d,0xf6,0xad,0x63,0x7b,0x60,0x5d,0xe7,0x2b,0x68,\n0x03,0x21,0x1b,0x69,0x04,0x20,0x98,0x47,0x77,0xe7,0x2b,0x68,0x03,0x21,0x1b,0x69,\n0x04,0x20,0x98,0x47,0xb5,0xe7,0x00,0x2e,0xce,0xd0,0x40,0xf6,0xce,0x23,0x63,0x60,\n0xcc,0xe7,0x00,0x2e,0xb7,0xd0,0x40,0xf6,0xce,0x23,0x7b,0x60,0xc6,0xe7,0x00,0xbf,\n0x64,0x08,0x00,0x02,0x50,0x01,0x00,0x20,0x1c,0x08,0x00,0x02,0xad,0xde,0xad,0xde,\n0xfe,0xe7,0x00,0xbf,0xfd,0x01,0x00,0x01,0x85,0x04,0x00,0x01,0xf8,0xb5,0x00,0xbf,\n0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x01,\n0xf8,0xbc,0x08,0xbc,0x9e,0x46,0x70,0x47,0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,\n0x64,0xf7,0xff,0x7f,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0xf4,0x22,0x00,0x20,0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0xc8,0x0a,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x0e,0x33,0xcd,0xab,0x34,0x12,0x6d,0xe6,0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x20,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p411x/msp432p411x.lds",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\nMEMORY {\n\tMAIN_FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x00200000\n\tINFO_FLASH (RX) : ORIGIN = 0x00200000, LENGTH = 0x00008000\n\tSRAM_CODE_0(RWX): ORIGIN = 0x01000000, LENGTH = 0x00000110\n\tSRAM_CODE_1(RWX): ORIGIN = 0x01000110, LENGTH = 0x00000030\n\tSRAM_CODE_2(RWX): ORIGIN = 0x01000150, LENGTH = 0x00000040\n\tSRAM_CODE_3(RWX): ORIGIN = 0x01000190, LENGTH = 0x00001E70\n\tSRAM_CODE_4(RWX): ORIGIN = 0x01002000, LENGTH = 0x00000200\n\tSRAM_DATA  (RW) : ORIGIN = 0x20002000, LENGTH = 0x00001000\n}\n\nREGION_ALIAS(\"REGION_INTVECT\", SRAM_CODE_0);\nREGION_ALIAS(\"REGION_RESET\", SRAM_CODE_1);\nREGION_ALIAS(\"REGION_DESCRIPTOR\", SRAM_CODE_2);\nREGION_ALIAS(\"REGION_TEXT\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_BSS\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_DATA\", SRAM_DATA);\nREGION_ALIAS(\"REGION_STACK\", SRAM_CODE_4);\nREGION_ALIAS(\"REGION_HEAP\", SRAM_DATA);\nREGION_ALIAS(\"REGION_ARM_EXIDX\", SRAM_CODE_3);\nREGION_ALIAS(\"REGION_ARM_EXTAB\", SRAM_CODE_3);\n\nSECTIONS {\n\t/* section for the interrupt vector area */\n\t.intvecs : {\n\t\tKEEP (*(.intvecs))\n\t} > REGION_INTVECT\n\n\tPROVIDE (_vtable_base_address =\n\t\tDEFINED(_vtable_base_address) ? _vtable_base_address : 0x20000000);\n\n\t.vtable (_vtable_base_address) : AT (_vtable_base_address) {\n\t\tKEEP (*(.vtable))\n\t} > REGION_DATA\n\n\t.descriptor :{\n\t\tFILL(0x00000000);\n\t\t. = ORIGIN(REGION_DESCRIPTOR) + LENGTH(REGION_DESCRIPTOR) - 1;\n\t\tBYTE(0x00);\n\t\t__ROM_AT = .;\n\t} > REGION_DESCRIPTOR\n\n\t.reset : {\n\t\tKEEP(*(.reset))\n\t} > REGION_RESET AT> REGION_RESET\n\n\t.text : {\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP (*(.text))\n\t\t*(.text.*)\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.ctors))\n\t\t. = ALIGN(0x4);\n\t\tKEEP (*(.dtors))\n\t\t. = ALIGN(0x4);\n\t\t__init_array_start = .;\n\t\tKEEP (*(.init_array*))\n\t\t__init_array_end = .;\n\t\tKEEP (*(.init))\n\t\tKEEP (*(.fini*))\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.rodata : {\n\t\t*(.rodata)\n\t\t*(.rodata.*)\n\t} > REGION_TEXT AT> REGION_TEXT\n\n\t.ARM.exidx : {\n\t\t__exidx_start = .;\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t\t__exidx_end = .;\n\t} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX\n\n\t.ARM.extab : {\n\t\tKEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))\n\t} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB\n\n\t__etext = .;\n\n\t.data : {\n\t\t__data_load__ = LOADADDR (.data);\n\t\t__data_start__ = .;\n\t\tKEEP (*(.data))\n\t\tKEEP (*(.data*))\n\t\t. = ALIGN (4);\n\t\t__data_end__ = .;\n\t} > REGION_DATA AT> REGION_TEXT\n\n\t.bss : {\n\t\t__bss_start__ = .;\n\t\t*(.shbss)\n\t\tKEEP (*(.bss))\n\t\t*(.bss.*)\n\t\t*(COMMON)\n\t\t. = ALIGN (4);\n\t\t__bss_end__ = .;\n\t} > REGION_BSS AT> REGION_BSS\n\n\t.heap : {\n\t\t__heap_start__ = .;\n\t\tend = __heap_start__;\n\t\t_end = end;\n\t\t__end = end;\n\t\tKEEP (*(.heap))\n\t\t__heap_end__ = .;\n\t\t__HeapLimit = __heap_end__;\n\t} > REGION_HEAP AT> REGION_HEAP\n\n\t.stack (NOLOAD) : ALIGN(0x8) {\n\t\t_stack = .;\n\t\tKEEP(*(.stack))\n\t} > REGION_STACK AT> REGION_STACK\n\n\t__stack_top = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);\n\tPROVIDE(__stack = __stack_top);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p411x.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/******************************************************************************\n*\n* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#ifndef OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H\n#define OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H\n\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/* Available Peripherals */\n#define __MCU_HAS_FLCTL_A__  /* Module FLCTL_A is available */\n#define __MCU_HAS_SYSCTL_A__ /* Module SYSCTL_A is available */\n\n/* Device and Peripheral Memory Map */\n#define FLASH_BASE        ((uint32_t)0x00000000)     /* Flash memory address */\n#define PERIPH_BASE       ((uint32_t)0x40000000)     /* Peripherals address */\n#define CS_BASE           (PERIPH_BASE + 0x00010400) /* Address of CS regs. */\n#define PCM_BASE          (PERIPH_BASE + 0x00010000) /* Address of PCM regs. */\n#define RTC_C_BASE        (PERIPH_BASE + 0x00004400) /* Address of RTC_C regs */\n#define TLV_BASE          ((uint32_t)0x00201000)     /* Address of TLV regs. */\n#define WDT_A_BASE        (PERIPH_BASE + 0x00004800) /* Address of WDT_A regs */\n#define BITBAND_PERI_BASE ((uint32_t)(0x42000000))\n\n/*\n * Peripherals with 8-bit or 16-bit register access allow only 8-bit or\n * 16-bit bit band access, so cast to 8 bit always\n */\n#define BITBAND_PERI(x, b) (*((volatile  uint8_t *) (BITBAND_PERI_BASE + \\\n\t(((uint32_t)(uint32_t *)&(x)) - PERIPH_BASE)*32 + (b)*4)))\n\n/* Register map for CLock Signal peripheral (CS) */\nstruct cs {\n\tvolatile uint32_t KEY;  /* Key Register */\n\tvolatile uint32_t CTL0; /* Control 0 Register */\n\tvolatile uint32_t CTL1; /* Control 1 Register */\n\tvolatile uint32_t CTL2; /* Control 2 Register */\n\tvolatile uint32_t CTL3; /* Control 3 Register */\n};\n\n/* Register map for Power Control Module peripheral (PCM) */\nstruct pcm {\n\tvolatile uint32_t CTL0;   /* Control 0 Register */\n\tvolatile uint32_t CTL1;   /* Control 1 Register */\n\tvolatile uint32_t IE;     /* Interrupt Enable Register */\n\tvolatile uint32_t IFG;    /* Interrupt Flag Register */\n\tvolatile uint32_t CLRIFG; /* Clear Interrupt Flag Register */\n};\n\n/* Register map for Real-Time Clock peripheral (RTC_C) */\nstruct rtc_c {\n\tvolatile uint16_t CTL0;    /* RTCCTL0 Register */\n\tvolatile uint16_t CTL13;   /* RTCCTL13 Register */\n\tvolatile uint16_t OCAL;    /* RTCOCAL Register */\n\tvolatile uint16_t TCMP;    /* RTCTCMP Register */\n\tvolatile uint16_t PS0CTL;  /* RTC Prescale Timer 0 Control Register */\n\tvolatile uint16_t PS1CTL;  /* RTC Prescale Timer 1 Control Register */\n\tvolatile uint16_t PS;      /* Real-Time Clock Prescale Timer Register */\n\tvolatile uint16_t IV;      /* Real-Time Clock Interrupt Vector Register */\n\tvolatile uint16_t TIM0;    /* RTCTIM0 Register  Hexadecimal Format */\n\tvolatile uint16_t TIM1;    /* Real-Time Clock Hour, Day of Week */\n\tvolatile uint16_t DATE;    /* RTCDATE - Hexadecimal Format */\n\tvolatile uint16_t YEAR;    /* RTCYEAR Register - Hexadecimal Format */\n\tvolatile uint16_t AMINHR;  /* RTCMINHR - Hexadecimal Format */\n\tvolatile uint16_t ADOWDAY; /* RTCADOWDAY - Hexadecimal Format */\n\tvolatile uint16_t BIN2BCD; /* Binary-to-BCD Conversion Register */\n\tvolatile uint16_t BCD2BIN; /* BCD-to-Binary Conversion Register */\n};\n\n/* Register map for Watchdog Timer peripheral (WDT_A) */\nstruct wdt_a {\n\tuint16_t RESERVED0[6];\n\tvolatile uint16_t CTL; /* Watchdog Timer Control Register */\n};\n\n/* Peripheral Declarations */\n#define CS    ((struct cs *) CS_BASE)\n#define PCM   ((struct pcm *) PCM_BASE)\n#define RTC_C ((struct rtc_c *) RTC_C_BASE)\n#define WDT_A ((struct wdt_a *) WDT_A_BASE)\n\n/* Peripheral Register Bit Definitions */\n\n/* DCORSEL Bit Mask */\n#define CS_CTL0_DCORSEL_MASK  ((uint32_t)0x00070000)\n/* Nominal DCO Frequency Range (MHz): 2 to 4 */\n#define CS_CTL0_DCORSEL_1     ((uint32_t)0x00010000)\n/* Nominal DCO Frequency Range (MHz): 16 to 32 */\n#define CS_CTL0_DCORSEL_4     ((uint32_t)0x00040000)\n/* CS control key value */\n#define CS_KEY_VAL            ((uint32_t)0x0000695A)\n\n/* AMR Bit Mask */\n#define PCM_CTL0_AMR_MASK     ((uint32_t)0x0000000F)\n/* LPMR Bit Mask */\n#define PCM_CTL0_LPMR_MASK    ((uint32_t)0x000000F0)\n/* LPM3.5. Core voltage setting 0. */\n#define PCM_CTL0_LPMR_10      ((uint32_t)0x000000A0)\n/* LPM4.5 */\n#define PCM_CTL0_LPMR_12      ((uint32_t)0x000000C0)\n/* CPM Bit Offset */\n#define PCM_CTL0_CPM_OFS      (8)\n/* CPM Bit Mask */\n#define PCM_CTL0_CPM_MASK     ((uint32_t)0x00003F00)\n/* PCMKEY Bit Mask */\n#define PCM_CTL0_KEY_MASK     ((uint32_t)0xFFFF0000)\n/* PMR_BUSY Bit Offset */\n#define PCM_CTL1_PMR_BUSY_OFS (8)\n\n/* RTCKEY Bit Offset */\n#define RTC_C_CTL0_KEY_OFS    (8)\n/* RTCKEY Bit Mask */\n#define RTC_C_CTL0_KEY_MASK   ((uint16_t)0xFF00)\n/* RTCHOLD Bit Offset */\n#define RTC_C_CTL13_HOLD_OFS  (6)\n/* RTC_C Key Value for RTC_C write access */\n#define RTC_C_KEY             ((uint16_t)0xA500)\n\n/* Watchdog timer hold */\n#define WDT_A_CTL_HOLD        ((uint16_t)0x0080)\n/* WDT Key Value for WDT write access */\n#define WDT_A_CTL_PW          ((uint16_t)0x5A00)\n\n/* Address of BSL API table */\n#define BSL_API_TABLE_ADDR    ((uint32_t)0x00202000)\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* OPENOCD_LOADERS_FLASH_MSP432_MSP432P411X_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/msp432p411x_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x00,0x22,0x00,0x01,0x11,0x01,0x00,0x01,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,\n0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x12,0x00,0x01,\n0x0d,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0x0d,0x12,0x00,0x01,0x0d,0x12,0x00,0x01,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x41,0xf2,0x00,0x70,0xc0,0xf2,0x00,0x10,0x85,0x46,0x05,0x48,0x05,0x49,0x4f,0xf0,\n0x00,0x02,0x88,0x42,0xb8,0xbf,0x40,0xf8,0x04,0x2b,0xfa,0xdb,0x00,0xf0,0xaa,0xbf,\n0x78,0x16,0x00,0x01,0x94,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x04,0x4b,0x05,0x48,0x1b,0x1a,0x06,0x2b,0x02,0xd9,0x04,0x4b,0x03,0xb1,0x18,0x47,\n0x70,0x47,0x00,0xbf,0x37,0x24,0x00,0x20,0x34,0x24,0x00,0x20,0x00,0x00,0x00,0x00,\n0x05,0x49,0x06,0x48,0x09,0x1a,0x89,0x10,0x01,0xeb,0xd1,0x71,0x49,0x10,0x02,0xd0,\n0x03,0x4b,0x03,0xb1,0x18,0x47,0x70,0x47,0x34,0x24,0x00,0x20,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x10,0xb5,0x06,0x4c,0x23,0x78,0x43,0xb9,0xff,0xf7,0xd8,0xff,\n0x04,0x4b,0x13,0xb1,0x04,0x48,0xaf,0xf3,0x00,0x80,0x01,0x23,0x23,0x70,0x10,0xbd,\n0x78,0x16,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x12,0x00,0x01,0x08,0xb5,0x08,0x4b,\n0x1b,0xb1,0x08,0x48,0x08,0x49,0xaf,0xf3,0x00,0x80,0x08,0x48,0x03,0x68,0x13,0xb9,\n0xbd,0xe8,0x08,0x40,0xcc,0xe7,0x06,0x4b,0x00,0x2b,0xf9,0xd0,0x98,0x47,0xf7,0xe7,\n0x00,0x00,0x00,0x00,0x3c,0x12,0x00,0x01,0x7c,0x16,0x00,0x01,0x34,0x24,0x00,0x20,\n0x00,0x00,0x00,0x00,0x13,0x4b,0x00,0x2b,0x08,0xbf,0x11,0x4b,0x9d,0x46,0xa3,0xf5,\n0x80,0x3a,0x00,0x21,0x8b,0x46,0x0f,0x46,0x11,0x48,0x12,0x4a,0x12,0x1a,0x00,0xf0,\n0x79,0xf8,0x0d,0x4b,0x00,0x2b,0x00,0xd0,0x98,0x47,0x0c,0x4b,0x00,0x2b,0x00,0xd0,\n0x98,0x47,0x00,0x20,0x00,0x21,0x04,0x00,0x0d,0x00,0x0b,0x48,0x00,0xf0,0x16,0xf8,\n0x00,0xf0,0x40,0xf8,0x20,0x00,0x29,0x00,0x00,0xf0,0x04,0xff,0x00,0xf0,0x14,0xf8,\n0x00,0x00,0x08,0x00,0x00,0x22,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x78,0x16,0x00,0x01,0x94,0x16,0x00,0x01,0xc9,0x02,0x00,0x01,0x01,0x46,0x00,0x20,\n0x02,0x46,0x03,0x46,0x00,0xf0,0x9c,0xb8,0x08,0xb5,0x00,0x21,0x04,0x46,0x00,0xf0,\n0xf3,0xf8,0x04,0x4b,0x18,0x68,0xc3,0x6b,0x03,0xb1,0x98,0x47,0x20,0x46,0x00,0xf0,\n0x55,0xf9,0x00,0xbf,0x38,0x12,0x00,0x01,0x38,0xb5,0x08,0x4b,0x08,0x4d,0xed,0x1a,\n0xac,0x10,0x18,0xbf,0xed,0x18,0x05,0xd0,0x01,0x3c,0x55,0xf8,0x04,0x3d,0x98,0x47,\n0x00,0x2c,0xf9,0xd1,0xbd,0xe8,0x38,0x40,0x00,0xf0,0x9c,0xbf,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x70,0xb5,0x0f,0x4e,0x0f,0x4d,0x76,0x1b,0xb6,0x10,0x18,0xbf,\n0x00,0x24,0x05,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,\n0x0a,0x4e,0x0b,0x4d,0x76,0x1b,0x00,0xf0,0x7f,0xff,0xb6,0x10,0x18,0xbf,0x00,0x24,\n0x06,0xd0,0x01,0x34,0x55,0xf8,0x04,0x3b,0x98,0x47,0xa6,0x42,0xf9,0xd1,0x70,0xbd,\n0x70,0xbd,0x00,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x12,0x00,0x01,\n0x10,0x12,0x00,0x01,0x70,0xb4,0x84,0x07,0x46,0xd0,0x54,0x1e,0x00,0x2a,0x41,0xd0,\n0xcd,0xb2,0x03,0x46,0x02,0xe0,0x62,0x1e,0xe4,0xb3,0x14,0x46,0x03,0xf8,0x01,0x5b,\n0x9a,0x07,0xf8,0xd1,0x03,0x2c,0x2e,0xd9,0xcd,0xb2,0x45,0xea,0x05,0x25,0x0f,0x2c,\n0x45,0xea,0x05,0x45,0x19,0xd9,0x03,0xf1,0x10,0x02,0x26,0x46,0x10,0x3e,0x0f,0x2e,\n0x42,0xf8,0x10,0x5c,0x42,0xf8,0x0c,0x5c,0x42,0xf8,0x08,0x5c,0x42,0xf8,0x04,0x5c,\n0x02,0xf1,0x10,0x02,0xf2,0xd8,0xa4,0xf1,0x10,0x02,0x22,0xf0,0x0f,0x02,0x04,0xf0,\n0x0f,0x04,0x10,0x32,0x03,0x2c,0x13,0x44,0x0d,0xd9,0x1e,0x46,0x22,0x46,0x04,0x3a,\n0x03,0x2a,0x46,0xf8,0x04,0x5b,0xfa,0xd8,0x22,0x1f,0x22,0xf0,0x03,0x02,0x04,0x32,\n0x13,0x44,0x04,0xf0,0x03,0x04,0x2c,0xb1,0xc9,0xb2,0x1c,0x44,0x03,0xf8,0x01,0x1b,\n0xa3,0x42,0xfb,0xd1,0x70,0xbc,0x70,0x47,0x14,0x46,0x03,0x46,0xc2,0xe7,0x00,0xbf,\n0x2d,0xe9,0xf0,0x47,0x25,0x4c,0x25,0x68,0xd5,0xf8,0x48,0x41,0x06,0x46,0x88,0x46,\n0x92,0x46,0x99,0x46,0xcc,0xb3,0x60,0x68,0x1f,0x28,0x18,0xdc,0x43,0x1c,0x7e,0xb1,\n0x04,0xeb,0x80,0x05,0x01,0x21,0xc5,0xf8,0x88,0xa0,0xd4,0xf8,0x88,0x71,0x01,0xfa,\n0x00,0xf2,0x17,0x43,0x02,0x2e,0xc4,0xf8,0x88,0x71,0xc5,0xf8,0x08,0x91,0x1e,0xd0,\n0x02,0x30,0x63,0x60,0x44,0xf8,0x20,0x80,0x00,0x20,0xbd,0xe8,0xf0,0x87,0x14,0x4b,\n0x03,0xb3,0x4f,0xf4,0xc8,0x70,0xaf,0xf3,0x00,0x80,0x04,0x46,0xd0,0xb1,0xd5,0xf8,\n0x48,0x31,0x00,0x27,0x80,0xe8,0x88,0x00,0xc5,0xf8,0x48,0x41,0x38,0x46,0x01,0x23,\n0xc4,0xf8,0x88,0x71,0xc4,0xf8,0x8c,0x71,0x00,0x2e,0xe1,0xd0,0xd0,0xe7,0xd4,0xf8,\n0x8c,0x11,0x0a,0x43,0xc4,0xf8,0x8c,0x21,0xda,0xe7,0x05,0xf5,0xa6,0x74,0xc5,0xf8,\n0x48,0x41,0xc0,0xe7,0x4f,0xf0,0xff,0x30,0xbd,0xe8,0xf0,0x87,0x38,0x12,0x00,0x01,\n0x00,0x00,0x00,0x00,0x02,0x4b,0x13,0xb1,0x02,0x48,0xff,0xf7,0x07,0xbf,0x70,0x47,\n0x00,0x00,0x00,0x00,0xc9,0x02,0x00,0x01,0x2d,0xe9,0xf0,0x4f,0x31,0x4b,0x83,0xb0,\n0x1b,0x68,0x00,0x93,0x03,0xf5,0xa4,0x73,0x81,0x46,0x0e,0x46,0x01,0x93,0x00,0x9b,\n0xd3,0xf8,0x48,0x71,0x27,0xb3,0xdd,0xf8,0x04,0xa0,0x7c,0x68,0x65,0x1e,0x0e,0xd4,\n0x01,0x34,0x07,0xeb,0x84,0x04,0x4f,0xf0,0x00,0x08,0xe6,0xb1,0xd4,0xf8,0x00,0x31,\n0xb3,0x42,0x18,0xd0,0x01,0x3d,0x6b,0x1c,0xa4,0xf1,0x04,0x04,0xf5,0xd1,0x22,0x4b,\n0x73,0xb1,0x7b,0x68,0x00,0x2b,0x36,0xd1,0x3b,0x68,0x00,0x2b,0x34,0xd0,0x38,0x46,\n0xca,0xf8,0x00,0x30,0xaf,0xf3,0x00,0x80,0xda,0xf8,0x00,0x70,0x00,0x2f,0xdc,0xd1,\n0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x7b,0x68,0x22,0x68,0x01,0x3b,0xab,0x42,0x0c,0xbf,\n0x7d,0x60,0xc4,0xf8,0x00,0x80,0x00,0x2a,0xdc,0xd0,0xd7,0xf8,0x88,0x31,0xd7,0xf8,\n0x04,0xb0,0x01,0x21,0xa9,0x40,0x19,0x42,0x08,0xd1,0x90,0x47,0x7b,0x68,0x5b,0x45,\n0xbd,0xd1,0xda,0xf8,0x00,0x30,0xbb,0x42,0xcc,0xd0,0xb8,0xe7,0xd7,0xf8,0x8c,0x31,\n0x19,0x42,0x04,0xd1,0x48,0x46,0xd4,0xf8,0x80,0x10,0x90,0x47,0xee,0xe7,0xd4,0xf8,\n0x80,0x00,0x90,0x47,0xea,0xe7,0x3b,0x68,0xba,0x46,0x1f,0x46,0x00,0x2f,0xac,0xd1,\n0xce,0xe7,0x00,0xbf,0x38,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0xfe,0xe7,0x00,0xbf,\n0x4f,0x4a,0x13,0x68,0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x70,0xb4,\n0x00,0xf2,0x8c,0x80,0x01,0x22,0x02,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x61,0xd0,\n0x02,0x23,0x98,0x42,0x31,0xd0,0x46,0x4b,0x1b,0x68,0xc3,0xf3,0x05,0x23,0x44,0x4c,\n0x44,0x49,0x01,0x25,0x22,0x68,0x09,0x2b,0x10,0xd8,0xdf,0xe8,0x03,0xf0,0x05,0x35,\n0x0f,0x0f,0x45,0x29,0x0f,0x0f,0x45,0x29,0x01,0x28,0x63,0xd0,0x02,0x28,0x73,0xd1,\n0x4f,0xf6,0xf0,0x76,0x3c,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,\n0xff,0x02,0x00,0x2b,0xfa,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,\n0x15,0x2b,0x05,0xd8,0x05,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x38,0xd0,0x02,0x22,\n0x23,0x68,0x90,0x42,0xc3,0xf3,0x05,0x23,0xd4,0xd1,0x01,0x20,0x70,0xbc,0x70,0x47,\n0x4f,0xf6,0xf0,0x76,0x2d,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,\n0xff,0x02,0x00,0x2b,0xda,0xd1,0xde,0xe7,0x01,0x28,0x27,0xd0,0x02,0x28,0x43,0xd1,\n0x4f,0xf6,0xf0,0x76,0x26,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,\n0xff,0x02,0x00,0x2b,0xca,0xd1,0xce,0xe7,0x4f,0xf6,0xf0,0x73,0x13,0x40,0x43,0xf0,\n0xd2,0x43,0x43,0xf4,0xb4,0x03,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,\n0xbc,0xd1,0xc0,0xe7,0x13,0xf0,0x03,0x1f,0x14,0xbf,0x13,0x46,0x00,0x23,0x98,0xe7,\n0x13,0xf0,0x03,0x1f,0x14,0xbf,0x01,0x22,0x00,0x22,0xc1,0xe7,0x4f,0xf6,0xf0,0x76,\n0x14,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,\n0xa4,0xd1,0xa8,0xe7,0x4f,0xf6,0xf0,0x76,0x0f,0x4b,0x16,0x40,0x33,0x43,0x23,0x60,\n0x0b,0x78,0x03,0xf0,0xff,0x02,0x00,0x2b,0x98,0xd1,0x9c,0xe7,0x00,0x28,0xac,0xd0,\n0x13,0x68,0xc3,0xf3,0x05,0x23,0x7a,0xe7,0x00,0x20,0x70,0xbc,0x70,0x47,0x00,0xbf,\n0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,0x08,0x00,0x5a,0x69,0x01,0x00,0x5a,0x69,\n0x09,0x00,0x5a,0x69,0x05,0x00,0x5a,0x69,0x04,0x00,0x5a,0x69,0x4a,0x4b,0x1b,0x68,\n0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0xf0,0xb4,0x7e,0xd8,0x01,0x22,\n0x02,0xfa,0x03,0xf3,0x13,0xf0,0x30,0x1f,0x5f,0xd0,0x02,0x26,0x42,0x4b,0x1b,0x68,\n0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,0x69,0xd8,0x01,0x22,0x02,0xfa,\n0x03,0xf3,0x03,0xf0,0x11,0x31,0x21,0xf0,0x10,0x21,0x00,0x29,0x68,0xd1,0x00,0x2b,\n0xb4,0xbf,0x02,0x23,0x00,0x23,0x98,0x42,0x5d,0xd0,0x37,0x4c,0x37,0x49,0x01,0x25,\n0x22,0x68,0x23,0x68,0xc3,0xf3,0x05,0x23,0x09,0x2b,0x0e,0xd8,0x05,0xfa,0x03,0xf3,\n0x13,0xf4,0x89,0x7f,0x41,0xd1,0x40,0xf2,0x21,0x27,0x1f,0x40,0x2f,0xb1,0x4f,0xf6,\n0xf0,0x77,0x2f,0x4b,0x17,0x40,0x3b,0x43,0x23,0x60,0x0b,0x78,0x03,0xf0,0xff,0x02,\n0x00,0x2b,0xfa,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,\n0x29,0xd8,0x05,0xfa,0x03,0xf3,0x03,0xf0,0x11,0x37,0x27,0xf0,0x10,0x27,0x6f,0xbb,\n0x00,0x2b,0xb4,0xbf,0x02,0x23,0x00,0x23,0x98,0x42,0xd1,0xd1,0x1e,0x4b,0x1b,0x68,\n0xc3,0xf3,0x05,0x23,0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x06,0xd8,0x01,0x22,0x02,0xfa,\n0x03,0xf3,0x13,0xf0,0x30,0x1f,0x25,0xd0,0x02,0x22,0x96,0x42,0x1b,0xd0,0x01,0x2e,\n0x25,0xd0,0x02,0x20,0xf0,0xbc,0xff,0xf7,0xe3,0xbe,0x13,0xf0,0x03,0x1f,0x14,0xbf,\n0x16,0x46,0x00,0x26,0x9a,0xe7,0x13,0x46,0xde,0xe7,0x4f,0xf6,0xf0,0x73,0x13,0x40,\n0x43,0xf0,0xd2,0x43,0x43,0xf4,0xb4,0x03,0x23,0x60,0xbe,0xe7,0x01,0x23,0xd3,0xe7,\n0x00,0x23,0x98,0x42,0xa1,0xd1,0x01,0x20,0xf0,0xbc,0x70,0x47,0x00,0x26,0x85,0xe7,\n0x13,0x46,0x98,0xe7,0x13,0xf0,0x03,0x1f,0x08,0xbf,0x00,0x22,0xd5,0xe7,0x30,0x46,\n0xf0,0xbc,0xff,0xf7,0xbd,0xbe,0x00,0xbf,0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,\n0x01,0x00,0x5a,0x69,0xef,0xf3,0x10,0x80,0x72,0xb6,0x70,0x47,0x30,0xbf,0x70,0x47,\n0x04,0x4a,0x08,0xb5,0x13,0x69,0x23,0xf0,0x04,0x03,0x13,0x61,0xff,0xf7,0xf6,0xff,\n0x01,0x20,0x08,0xbd,0x00,0xed,0x00,0xe0,0xff,0xf7,0x50,0xbf,0x0b,0x4b,0x1b,0x68,\n0xc3,0xf3,0x05,0x23,0x01,0x3b,0xdb,0xb2,0x1f,0x2b,0x0c,0xd8,0x01,0x20,0x00,0xfa,\n0x03,0xf2,0x02,0xf0,0x11,0x33,0x23,0xf0,0x10,0x23,0x2b,0xb9,0x00,0x2a,0xb4,0xbf,\n0x02,0x20,0x00,0x20,0x70,0x47,0x00,0x20,0x70,0x47,0x00,0xbf,0x00,0x00,0x01,0x40,\n0x2d,0xe9,0xf8,0x43,0x7b,0x4e,0x7c,0x4c,0xdf,0xf8,0x00,0x82,0x7b,0x4f,0x7c,0x4d,\n0x33,0x78,0x00,0x2b,0x43,0xd1,0x23,0x68,0x03,0xf0,0xf0,0x03,0xa0,0x2b,0x3e,0xd0,\n0x23,0x68,0x03,0xf0,0xf0,0x03,0xc0,0x2b,0x39,0xd0,0x23,0x68,0xc3,0xf3,0x05,0x23,\n0x04,0x3b,0xdb,0xb2,0x15,0x2b,0x08,0xd8,0x01,0x22,0x02,0xfa,0x03,0xf3,0x13,0xf0,\n0x30,0x10,0x02,0xd1,0x13,0xf0,0x03,0x1f,0x55,0xd1,0x23,0x68,0xc3,0xf3,0x05,0x29,\n0x22,0x68,0x4f,0xf6,0x0f,0x73,0x13,0x40,0x43,0xf0,0xd2,0x43,0x43,0xf4,0xb4,0x03,\n0x23,0x60,0x2b,0x69,0x43,0xf0,0x04,0x03,0x2b,0x61,0xff,0xf7,0x9f,0xff,0x2b,0x69,\n0x23,0xf0,0x04,0x03,0x2b,0x61,0x23,0x68,0xc3,0xf3,0x05,0x23,0x4b,0x45,0x29,0xd0,\n0xb9,0xf1,0x11,0x0f,0x6b,0xd0,0x0d,0xd9,0xb9,0xf1,0x19,0x0f,0x72,0xd0,0x4b,0xd9,\n0xb9,0xf1,0x21,0x0f,0x35,0xd0,0x02,0xd8,0xb9,0xf1,0x20,0x0f,0xb8,0xd0,0x00,0x20,\n0xbd,0xe8,0xf8,0x83,0xb9,0xf1,0x05,0x0f,0x6f,0xd0,0x16,0xd9,0xb9,0xf1,0x09,0x0f,\n0x00,0xf0,0x8c,0x80,0xb9,0xf1,0x10,0x0f,0x00,0xf0,0x81,0x80,0xb9,0xf1,0x08,0x0f,\n0xed,0xd1,0x00,0x20,0xff,0xf7,0xd2,0xfe,0x98,0xb1,0x02,0x20,0xbd,0xe8,0xf8,0x43,\n0xff,0xf7,0x1e,0xbe,0x01,0x20,0xbd,0xe8,0xf8,0x83,0xb9,0xf1,0x01,0x0f,0x68,0xd0,\n0x5d,0xd3,0xb9,0xf1,0x04,0x0f,0xda,0xd1,0x00,0x20,0xff,0xf7,0xbf,0xfe,0x00,0x28,\n0x50,0xd1,0xbd,0xe8,0xf8,0x83,0x23,0x68,0xc3,0xf3,0x05,0x29,0xff,0xf7,0x08,0xfe,\n0xa6,0xe7,0x40,0x49,0x40,0x4a,0x8b,0x89,0x03,0xf0,0x7f,0x03,0x43,0xf4,0xb5,0x43,\n0x8b,0x81,0x13,0x88,0xdb,0xb2,0x43,0xf4,0x25,0x43,0x01,0x20,0x00,0x21,0x13,0x80,\n0x88,0xf8,0x00,0x00,0x39,0x70,0x72,0xe7,0xb9,0xf1,0x15,0x0f,0x5b,0xd0,0xb9,0xf1,\n0x18,0x0f,0x51,0xd0,0xb9,0xf1,0x14,0x0f,0xb1,0xd1,0x00,0x20,0xff,0xf7,0x96,0xfe,\n0x00,0x28,0xac,0xd0,0x01,0x20,0xff,0xf7,0xe3,0xfd,0x00,0x28,0xa7,0xd0,0x29,0x4b,\n0x1b,0x78,0x00,0x2b,0xa3,0xd1,0xbd,0xe8,0xf8,0x43,0xff,0xf7,0x29,0xbf,0x01,0x20,\n0xff,0xf7,0x84,0xfe,0x00,0x28,0x9a,0xd0,0x00,0x20,0xff,0xf7,0xd1,0xfd,0x00,0x28,\n0xed,0xd1,0x94,0xe7,0x01,0x20,0xff,0xf7,0x79,0xfe,0x00,0x28,0x8f,0xd0,0x02,0x20,\n0xff,0xf7,0xc6,0xfd,0x00,0x28,0xe2,0xd1,0x89,0xe7,0x01,0x20,0xff,0xf7,0x6e,0xfe,\n0x00,0x28,0xae,0xd0,0x01,0x20,0xbd,0xe8,0xf8,0x43,0xff,0xf7,0xb9,0xbd,0x00,0x20,\n0xff,0xf7,0x64,0xfe,0x00,0x28,0xa4,0xd0,0x00,0x20,0xbd,0xe8,0xf8,0x43,0xff,0xf7,\n0xaf,0xbd,0x48,0x46,0xff,0xf7,0x5a,0xfe,0x00,0x28,0x9a,0xd0,0xf4,0xe7,0x00,0x20,\n0xff,0xf7,0x54,0xfe,0x00,0x28,0x3f,0xf4,0x6a,0xaf,0xcd,0xe7,0x01,0x20,0xff,0xf7,\n0x4d,0xfe,0x00,0x28,0x8d,0xd0,0x78,0xe7,0x00,0x20,0xff,0xf7,0x47,0xfe,0x00,0x28,\n0x3f,0xf4,0x5d,0xaf,0xcb,0xe7,0x01,0x20,0xff,0xf7,0x40,0xfe,0x00,0x28,0x3f,0xf4,\n0x56,0xaf,0xa7,0xe7,0xa0,0x00,0x20,0x42,0x00,0x00,0x01,0x40,0x20,0x80,0x08,0x42,\n0x00,0xed,0x00,0xe0,0x00,0x48,0x00,0x40,0x00,0x44,0x00,0x40,0x58,0x80,0x08,0x42,\n0x6b,0x49,0x30,0xb5,0x0a,0x68,0xc2,0xf3,0x05,0x22,0x90,0x42,0x83,0xb0,0x21,0xd0,\n0x11,0x28,0x00,0xf0,0xbf,0x80,0x20,0xd9,0x19,0x28,0x00,0xf0,0x95,0x80,0x3a,0xd9,\n0x21,0x28,0x5d,0xd0,0x55,0xd9,0xa0,0x28,0x00,0xf0,0x86,0x80,0xc0,0x28,0x1e,0xd1,\n0x60,0x4b,0x1b,0x78,0xdb,0xb9,0x60,0x48,0x5d,0x49,0x02,0x69,0x5f,0x4b,0x42,0xf0,\n0x04,0x02,0x02,0x61,0x08,0x68,0x4f,0xf6,0x0f,0x72,0x02,0x40,0x13,0x43,0x0b,0x60,\n0xff,0xf7,0xa4,0xfe,0x01,0x20,0x03,0xb0,0x30,0xbd,0x05,0x28,0x00,0xf0,0xa1,0x80,\n0x08,0xd9,0x09,0x28,0x62,0xd0,0x10,0x28,0x55,0xd0,0x08,0x28,0x4c,0xd0,0x00,0x20,\n0x03,0xb0,0x30,0xbd,0x01,0x28,0x00,0xf0,0x87,0x80,0x7d,0xd3,0x04,0x28,0xf6,0xd1,\n0x00,0x20,0xff,0xf7,0xeb,0xfd,0x00,0x28,0xe5,0xd0,0x01,0x20,0x03,0xb0,0xbd,0xe8,\n0x30,0x40,0xff,0xf7,0x35,0xbd,0x15,0x28,0x67,0xd0,0x18,0x28,0x5f,0xd0,0x14,0x28,\n0xe5,0xd1,0x00,0x20,0xff,0xf7,0xda,0xfd,0x00,0x28,0xe0,0xd0,0x01,0x20,0xff,0xf7,\n0x27,0xfd,0x00,0x28,0xdb,0xd0,0x3f,0x4b,0x1b,0x78,0x00,0x2b,0xd7,0xd1,0x3e,0x4a,\n0x01,0x90,0x13,0x69,0x23,0xf0,0x04,0x03,0x13,0x61,0xff,0xf7,0x67,0xfe,0x01,0x98,\n0xc1,0xe7,0x20,0x28,0xcb,0xd1,0x03,0xb0,0xbd,0xe8,0x30,0x40,0xff,0xf7,0x88,0xbe,\n0x37,0x49,0x38,0x4a,0x8b,0x89,0x38,0x4c,0x38,0x48,0x03,0xf0,0x7f,0x03,0x43,0xf4,\n0xb5,0x43,0x8b,0x81,0x13,0x88,0xdb,0xb2,0x43,0xf4,0x25,0x43,0x01,0x25,0x00,0x21,\n0x13,0x80,0x25,0x70,0x01,0x70,0xe6,0xe7,0x00,0x20,0xff,0xf7,0xa7,0xfd,0x00,0x28,\n0xa1,0xd0,0x02,0x20,0xba,0xe7,0x00,0x20,0xff,0xf7,0xa0,0xfd,0x00,0x28,0xa6,0xd0,\n0x00,0x20,0xff,0xf7,0xed,0xfc,0x00,0x28,0xc5,0xd1,0xa0,0xe7,0x01,0x20,0xff,0xf7,\n0x95,0xfd,0x00,0x28,0x8f,0xd0,0xec,0xe7,0x1e,0x4b,0x1b,0x78,0x00,0x2b,0x96,0xd1,\n0x1d,0x48,0x23,0x4b,0x02,0x69,0x7a,0xe7,0x01,0x20,0xff,0xf7,0x87,0xfd,0x00,0x28,\n0x8d,0xd0,0x02,0x20,0xff,0xf7,0xd4,0xfc,0x00,0x28,0xac,0xd1,0x87,0xe7,0x00,0x20,\n0xff,0xf7,0x7c,0xfd,0x00,0x28,0x82,0xd0,0xf3,0xe7,0x01,0x20,0xff,0xf7,0x76,0xfd,\n0x00,0x28,0x3f,0xf4,0x7c,0xaf,0x99,0xe7,0x00,0x20,0xff,0xf7,0x6f,0xfd,0x00,0x28,\n0x3f,0xf4,0x69,0xaf,0x00,0x20,0x81,0xe7,0xff,0xf7,0x68,0xfd,0x00,0x28,0x3f,0xf4,\n0x62,0xaf,0xf7,0xe7,0x01,0x20,0xff,0xf7,0x61,0xfd,0x00,0x28,0x3f,0xf4,0x67,0xaf,\n0xbe,0xe7,0x01,0x20,0xff,0xf7,0x5a,0xfd,0x00,0x28,0x3f,0xf4,0x54,0xaf,0x6c,0xe7,\n0x00,0x00,0x01,0x40,0xa0,0x00,0x20,0x42,0x00,0xed,0x00,0xe0,0xa0,0x00,0x5a,0x69,\n0x00,0x48,0x00,0x40,0x00,0x44,0x00,0x40,0x58,0x80,0x08,0x42,0x20,0x80,0x08,0x42,\n0xc0,0x00,0x5a,0x69,0x02,0x4b,0x18,0x68,0xc0,0xf3,0x05,0x20,0x70,0x47,0x00,0xbf,\n0x00,0x00,0x01,0x40,0x70,0xb5,0x1e,0x4e,0x1e,0x4a,0x33,0x68,0x1e,0x4d,0x1f,0x4c,\n0x4f,0xf0,0x80,0x71,0x91,0x60,0x9b,0x6d,0x00,0x20,0x98,0x47,0x33,0x68,0x28,0x60,\n0x9b,0x6d,0x01,0x20,0x98,0x47,0x68,0x60,0xff,0xf7,0xd8,0xfd,0x28,0x73,0xff,0xf7,\n0xe1,0xff,0x63,0x68,0x68,0x73,0x03,0xf4,0xe0,0x23,0xab,0x60,0x00,0x20,0xff,0xf7,\n0xef,0xfe,0x33,0x68,0x02,0x21,0x5b,0x6d,0x05,0x46,0x00,0x20,0x98,0x47,0x33,0x68,\n0x01,0x20,0x5b,0x6d,0x02,0x21,0x98,0x47,0x46,0xf6,0x5a,0x13,0x23,0x60,0x63,0x68,\n0x23,0xf4,0xe0,0x23,0x43,0xf4,0x80,0x23,0x00,0x22,0x63,0x60,0x22,0x60,0x08,0x4b,\n0x1d,0xb1,0x40,0xf6,0xce,0x22,0x5a,0x60,0x70,0xbd,0x06,0x4a,0x5a,0x60,0x70,0xbd,\n0x6c,0x08,0x00,0x02,0x00,0xed,0x00,0xe0,0x80,0x01,0x00,0x20,0x00,0x04,0x01,0x40,\n0x50,0x01,0x00,0x20,0x00,0xad,0xde,0x00,0x19,0x4b,0xdb,0x69,0xda,0x07,0x70,0xb5,\n0x1d,0xd4,0x17,0x4c,0xe3,0x69,0x9b,0x07,0x00,0xd4,0x70,0xbd,0x15,0x4d,0x16,0x49,\n0x2b,0x68,0x4f,0xf4,0x00,0x10,0x1b,0x69,0x98,0x47,0x23,0x6a,0x0b,0x2b,0x19,0xd0,\n0x12,0x4b,0x10,0x4a,0x1b,0x68,0x12,0x68,0x9b,0x6c,0x14,0x69,0x98,0x47,0x10,0x49,\n0x23,0x46,0x01,0x44,0xbd,0xe8,0x70,0x40,0x4f,0xf4,0x01,0x10,0x18,0x47,0x0b,0x4b,\n0x08,0x4a,0x1b,0x68,0x12,0x68,0x5b,0x68,0x14,0x69,0x98,0x47,0x41,0x1e,0x00,0x20,\n0xa0,0x47,0xd6,0xe7,0x2b,0x68,0x06,0x49,0x1b,0x69,0x06,0x48,0x98,0x47,0xdf,0xe7,\n0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0xff,0x0f,0x20,0x00,0x68,0x08,0x00,0x02,\n0xff,0x3f,0x20,0x00,0x00,0x20,0x20,0x00,0x14,0x4b,0x70,0xb5,0x14,0x4c,0x1b,0x68,\n0x22,0x68,0x5b,0x68,0x15,0x69,0x98,0x47,0x41,0x1e,0x00,0x20,0xa8,0x47,0x23,0x68,\n0x10,0x49,0x1b,0x69,0x4f,0xf4,0x00,0x10,0x98,0x47,0x0f,0x4b,0x1b,0x6a,0x0b,0x2b,\n0x0e,0xd0,0x0a,0x4b,0x0a,0x4a,0x1b,0x68,0x12,0x68,0x9b,0x6c,0x14,0x69,0x98,0x47,\n0x0a,0x49,0x23,0x46,0x01,0x44,0xbd,0xe8,0x70,0x40,0x4f,0xf4,0x01,0x10,0x18,0x47,\n0x23,0x68,0x06,0x49,0x1b,0x69,0x06,0x48,0x98,0x47,0xea,0xe7,0x68,0x08,0x00,0x02,\n0x6c,0x08,0x00,0x02,0xff,0x0f,0x20,0x00,0x50,0x01,0x00,0x20,0xff,0x3f,0x20,0x00,\n0x00,0x20,0x20,0x00,0x2d,0xe9,0xf0,0x41,0xff,0xf7,0xc6,0xff,0x2d,0x49,0x4b,0x69,\n0x2c,0x4a,0xdb,0x06,0xfb,0xd5,0x53,0x69,0x43,0xf0,0x01,0x03,0x53,0x61,0xd4,0x68,\n0x15,0x69,0xb4,0xf5,0x00,0x1f,0x03,0xd2,0x2b,0x19,0xb3,0xf5,0x00,0x1f,0x2d,0xd8,\n0x25,0x4b,0x1b,0x68,0x21,0x46,0x2a,0x46,0x9b,0x6a,0x4f,0xf0,0x20,0x20,0x98,0x47,\n0x07,0x46,0x20,0x4c,0x21,0x4e,0x63,0x69,0x1f,0x4d,0x31,0x68,0x2a,0x68,0x23,0xf0,\n0x11,0x03,0x63,0x61,0x4b,0x68,0xd2,0xf8,0x14,0x80,0x98,0x47,0x41,0x1e,0x00,0x20,\n0xc0,0x47,0x33,0x68,0x2a,0x68,0x9b,0x6c,0x55,0x69,0x98,0x47,0x18,0x49,0x01,0x44,\n0x4f,0xf4,0x00,0x10,0xa8,0x47,0x27,0xb1,0x40,0xf6,0xce,0x23,0x63,0x60,0xbd,0xe8,\n0xf0,0x81,0x4d,0xf6,0xad,0x63,0x63,0x60,0xbd,0xe8,0xf0,0x81,0xdf,0xf8,0x38,0x80,\n0xd8,0xf8,0x00,0x30,0xc4,0xf5,0x00,0x17,0x3a,0x46,0x9b,0x6a,0x21,0x46,0x4f,0xf0,\n0x20,0x20,0x98,0x47,0xd8,0xf8,0x00,0x30,0x06,0x46,0xc4,0xf1,0x20,0x20,0xea,0x1b,\n0x9b,0x6a,0x00,0xf5,0x00,0x10,0x4f,0xf4,0x00,0x11,0x98,0x47,0x30,0x40,0xc7,0xb2,\n0xbf,0xe7,0x00,0xbf,0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0x68,0x08,0x00,0x02,\n0xff,0xff,0x1f,0x00,0x2d,0xe9,0xf0,0x4f,0x4f,0x4c,0x26,0x69,0xe7,0x68,0x83,0xb0,\n0x00,0x2e,0x59,0xd0,0x4f,0xf0,0x00,0x09,0xca,0x46,0xcd,0xf8,0x00,0x90,0xb6,0xf5,\n0x80,0x5f,0x93,0xbf,0xb0,0x46,0xa6,0xf5,0x80,0x56,0x4f,0xf4,0x80,0x58,0x00,0x26,\n0xff,0xf7,0x4a,0xff,0x02,0xe0,0xa3,0x69,0xdb,0x06,0x02,0xd4,0x63,0x69,0xda,0x06,\n0xf9,0xd5,0x65,0x69,0x15,0xf0,0x10,0x05,0x41,0xd0,0x63,0x69,0x43,0xf0,0x01,0x03,\n0x63,0x61,0x4f,0xf0,0x20,0x2a,0x01,0x25,0x3c,0x4b,0x9f,0x42,0x08,0xeb,0x07,0x09,\n0x3b,0x4b,0x02,0xd8,0xb9,0xf5,0x00,0x1f,0x4c,0xd8,0x1b,0x68,0x39,0x46,0x42,0x46,\n0x9b,0x6a,0x50,0x46,0x98,0x47,0x4f,0x46,0x81,0x46,0x00,0x2d,0x39,0xd0,0x63,0x69,\n0x23,0xf0,0x11,0x03,0x63,0x61,0xdf,0xf8,0xcc,0x80,0x31,0x4d,0xd8,0xf8,0x00,0x20,\n0x2b,0x68,0x52,0x68,0xd3,0xf8,0x14,0xb0,0x90,0x47,0x41,0x1e,0x00,0x20,0xd8,0x47,\n0xd8,0xf8,0x00,0x30,0x2a,0x68,0x9b,0x6c,0x55,0x69,0x98,0x47,0x27,0x49,0x01,0x44,\n0x4f,0xf4,0x00,0x10,0xa8,0x47,0xb9,0xf1,0x00,0x0f,0x3e,0xd0,0x00,0x2e,0xae,0xd1,\n0x21,0x4b,0x40,0xf6,0xce,0x22,0x5a,0x60,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0xa3,0x69,\n0x13,0xf0,0x10,0x03,0x08,0xd0,0xa3,0x69,0xdf,0xf8,0x7c,0xa0,0x43,0xf0,0x01,0x03,\n0xa3,0x61,0x01,0x23,0x00,0x93,0xb7,0xe7,0x00,0x9a,0x00,0x2a,0xcb,0xd0,0x1d,0x46,\n0xb2,0xe7,0x00,0x9b,0x00,0x2b,0xc6,0xd0,0xa3,0x69,0x00,0x95,0x23,0xf0,0x11,0x03,\n0xa3,0x61,0xc0,0xe7,0x1a,0x68,0x01,0x93,0xc7,0xf5,0x00,0x1b,0xd2,0xf8,0x28,0xc0,\n0x39,0x46,0x5a,0x46,0x50,0x46,0xe0,0x47,0x01,0x9b,0x19,0x68,0x07,0x46,0xd1,0xf8,\n0x28,0xc0,0xcb,0xeb,0x08,0x02,0x0a,0xeb,0x0b,0x00,0x4f,0xf4,0x00,0x11,0xe0,0x47,\n0x38,0x40,0x4f,0x46,0x5f,0xfa,0x80,0xf9,0x9f,0xe7,0x03,0x4b,0x4d,0xf6,0xad,0x62,\n0x5a,0x60,0x03,0xb0,0xbd,0xe8,0xf0,0x8f,0x50,0x01,0x00,0x20,0xff,0xff,0x1f,0x00,\n0x6c,0x08,0x00,0x02,0x68,0x08,0x00,0x02,0x00,0x30,0x00,0x20,0x2d,0xe9,0xf0,0x41,\n0x1b,0x4c,0x1c,0x4d,0x1c,0x4f,0x29,0x68,0x3a,0x68,0x46,0xf6,0x5a,0x18,0xc4,0xf8,\n0x00,0x80,0x63,0x68,0x23,0xf4,0xe0,0x23,0x00,0x26,0x43,0xf4,0x80,0x33,0x63,0x60,\n0x26,0x60,0x53,0x6d,0x30,0x46,0x98,0x47,0x3b,0x68,0x69,0x68,0x5b,0x6d,0x01,0x20,\n0x98,0x47,0x68,0x7b,0xff,0xf7,0x1c,0xfd,0x07,0x46,0x28,0x7b,0xff,0xf7,0xf4,0xfb,\n0xc4,0xf8,0x00,0x80,0x63,0x68,0xaa,0x68,0x0c,0x49,0x23,0xf4,0xe0,0x23,0x13,0x43,\n0x63,0x60,0x26,0x60,0x0a,0x4b,0x8e,0x60,0x28,0xb1,0x27,0xb1,0x40,0xf6,0xce,0x22,\n0x5a,0x60,0xbd,0xe8,0xf0,0x81,0x4d,0xf6,0xad,0x62,0x5a,0x60,0xbd,0xe8,0xf0,0x81,\n0x00,0x04,0x01,0x40,0x80,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,0x00,0xed,0x00,0xe0,\n0x50,0x01,0x00,0x20,0x5b,0x4b,0x5c,0x4c,0x1b,0x68,0x5c,0x4e,0x1b,0x68,0x80,0xb5,\n0x98,0x47,0xff,0xf7,0xb7,0xfb,0x27,0x46,0x23,0x68,0x20,0x2b,0x00,0xf2,0x99,0x80,\n0x01,0xa2,0x52,0xf8,0x23,0xf0,0x00,0xbf,0x99,0x10,0x00,0x01,0x89,0x11,0x00,0x01,\n0x65,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x57,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x49,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x3b,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,\n0xd3,0x11,0x00,0x01,0xd3,0x11,0x00,0x01,0x2d,0x11,0x00,0x01,0x01,0x23,0x63,0x60,\n0xff,0xf7,0xb8,0xfe,0x00,0x23,0x23,0x60,0xae,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,\n0x5d,0xff,0x00,0x23,0x23,0x60,0xa7,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x82,0xfd,\n0x00,0x23,0x23,0x60,0xa0,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0x3b,0xfe,0x00,0x23,\n0x23,0x60,0x99,0xe7,0x01,0x23,0x63,0x60,0xff,0xf7,0xfe,0xfd,0x05,0x25,0x33,0x68,\n0xe0,0x68,0x5b,0x6a,0x98,0x47,0x01,0x3d,0x00,0x28,0x2e,0xd1,0x00,0x2d,0xf6,0xd1,\n0x4d,0xf6,0xad,0x63,0x63,0x60,0x0d,0xe0,0x01,0x23,0x63,0x60,0xff,0xf7,0xac,0xfd,\n0x05,0x25,0x33,0x68,0x1b,0x6a,0x98,0x47,0x01,0x3d,0x20,0xbb,0x00,0x2d,0xf8,0xd1,\n0x17,0x4b,0x63,0x60,0x17,0x4d,0x32,0x68,0x2b,0x68,0xd2,0xf8,0x14,0x80,0x5b,0x68,\n0x98,0x47,0x41,0x1e,0x00,0x20,0xc0,0x47,0x2b,0x68,0x32,0x68,0x9b,0x6c,0x55,0x69,\n0x98,0x47,0x11,0x49,0x01,0x44,0x4f,0xf4,0x00,0x10,0xa8,0x47,0x00,0x23,0x23,0x60,\n0x62,0xe7,0x40,0xf6,0xad,0x33,0x63,0x60,0x5e,0xe7,0x00,0x2d,0xd0,0xd0,0x40,0xf6,\n0xce,0x23,0x7b,0x60,0xde,0xe7,0x00,0x2d,0xda,0xd0,0x40,0xf6,0xce,0x23,0x63,0x60,\n0xd8,0xe7,0x00,0xbf,0x64,0x08,0x00,0x02,0x50,0x01,0x00,0x20,0x6c,0x08,0x00,0x02,\n0xad,0xde,0xad,0xde,0x68,0x08,0x00,0x02,0xff,0xff,0x1f,0x00,0xfe,0xe7,0x00,0xbf,\n0xfd,0x01,0x00,0x01,0x85,0x04,0x00,0x01,0xf8,0xb5,0x00,0xbf,0xf8,0xbc,0x08,0xbc,\n0x9e,0x46,0x70,0x47,0xf8,0xb5,0x00,0xbf,0xd5,0x01,0x00,0x01,0xf8,0xbc,0x08,0xbc,\n0x9e,0x46,0x70,0x47,0x43,0x00,0x00,0x00,0x08,0x20,0x00,0x20,0xf8,0xef,0xff,0x7f,\n0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0xf4,0x22,0x00,0x20,0x5c,0x23,0x00,0x20,0xc4,0x23,0x00,0x20,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x34,0x12,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x33,0xcd,0xab,\n0x34,0x12,0x6d,0xe6,0xec,0xde,0x05,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x20,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/startup_msp432e4.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2017-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n\n/* Entry point for the application. */\nextern int main();\n\n/* Reserve space for the system stack. */\nextern uint32_t __stack_top;\n\ntypedef void(*pFunc)(void);\n\n/* Interrupt handler prototypes */\nvoid default_handler(void);\nvoid reset_handler(void);\n\n/*\n * The vector table.  Note that the proper constructs must be placed on this to\n * ensure that it ends up at physical address 0x0000.0000 or at the start of\n * the program if located at a start address other than 0.\n */\nvoid (* const intr_vectors[])(void) __attribute__((section(\".intvecs\"))) = {\n\t(pFunc)&__stack_top, /* The initial stack pointer */\n\treset_handler,       /* The reset handler         */\n\tdefault_handler,     /* The NMI handler           */\n\tdefault_handler,     /* The hard fault handler    */\n\tdefault_handler,     /* The MPU fault handler     */\n\tdefault_handler,     /* The bus fault handler     */\n\tdefault_handler,     /* The usage fault handler   */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\tdefault_handler,     /* SVCall handler            */\n\tdefault_handler,     /* Debug monitor handler     */\n\t0,                   /* Reserved                  */\n\tdefault_handler,     /* The PendSV handler        */\n\tdefault_handler      /* The SysTick handler       */\n};\n\n/*\n * The following are constructs created by the linker, indicating where\n * the \"data\" and \"bss\" segments reside in memory.  The initializers for\n * the \"data\" segment resides immediately following the \"text\" segment.\n */\nextern uint32_t __bss_start__;\nextern uint32_t __bss_end__;\n\n/*\n * This is the code that gets called when the processor first starts execution\n * following a reset event.  Only the absolutely necessary set is performed,\n * after which the application supplied entry() routine is called.  Any fancy\n * actions (such as making decisions based on the reset cause register, and\n * resetting the bits in that register) are left solely in the hands of the\n * application.\n */\n__attribute__((section(\".reset\"))) __attribute__((naked))\nvoid reset_handler(void)\n{\n\t/* Set stack pointer */\n\t__asm(\"    MOVW.W  r0, #0x1700\\n\"\n\t\t  \"    MOVT.W  r0, #0x2000\\n\"\n\t\t  \"    mov     sp, r0\\n\");\n\n\t/* Zero fill the bss segment. */\n\t__asm(\"    ldr     r0, =__bss_start__\\n\"\n\t\t  \"    ldr     r1, =__bss_end__\\n\"\n\t\t  \"    mov     r2, #0\\n\"\n\t\t  \"    .thumb_func\\n\"\n\t\t  \"zero_loop:\\n\"\n\t\t  \"    cmp     r0, r1\\n\"\n\t\t  \"    it      lt\\n\"\n\t\t  \"    strlt   r2, [r0], #4\\n\"\n\t\t  \"    blt     zero_loop\");\n\n\t/* Call the application's entry point. */\n\tmain();\n}\n\n/*\n * This is the code that gets called when the processor receives an unexpected\n * interrupt.  This simply enters an infinite loop, preserving the system state\n * for examination by a debugger.\n */\nvoid default_handler(void)\n{\n\t/* Enter an infinite loop. */\n\twhile (1)\n\t\t;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/msp432/startup_msp432p4.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n*\n* Copyright (C) 2012-2018 Texas Instruments Incorporated - http://www.ti.com/\n*\n******************************************************************************/\n\n#include <stdint.h>\n\n/* Entry point for the application. */\nextern int main();\n\n/* Reserve space for the system stack. */\nextern uint32_t __stack_top;\n\ntypedef void(*pFunc)(void);\n\n/* Interrupt handler prototypes */\nvoid default_handler(void);\nvoid reset_handler(void);\n\n/*\n * The vector table.  Note that the proper constructs must be placed on this to\n * ensure that it ends up at physical address 0x0000.0000 or at the start of\n * the program if located at a start address other than 0.\n */\nvoid (* const intr_vectors[])(void) __attribute__((section(\".intvecs\"))) = {\n\t(pFunc)&__stack_top, /* The initial stack pointer */\n\treset_handler,       /* The reset handler         */\n\tdefault_handler,     /* The NMI handler           */\n\tdefault_handler,     /* The hard fault handler    */\n\tdefault_handler,     /* The MPU fault handler     */\n\tdefault_handler,     /* The bus fault handler     */\n\tdefault_handler,     /* The usage fault handler   */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\t0,                   /* Reserved                  */\n\tdefault_handler,     /* SVCall handler            */\n\tdefault_handler,     /* Debug monitor handler     */\n\t0,                   /* Reserved                  */\n\tdefault_handler,     /* The PendSV handler        */\n\tdefault_handler      /* The SysTick handler       */\n};\n\n/*\n * The following are constructs created by the linker, indicating where\n * the \"data\" and \"bss\" segments reside in memory.  The initializers for\n * the \"data\" segment resides immediately following the \"text\" segment.\n */\nextern uint32_t __bss_start__;\nextern uint32_t __bss_end__;\n\n/*\n * This is the code that gets called when the processor first starts execution\n * following a reset event.  Only the absolutely necessary set is performed,\n * after which the application supplied entry() routine is called.  Any fancy\n * actions (such as making decisions based on the reset cause register, and\n * resetting the bits in that register) are left solely in the hands of the\n * application.\n */\n__attribute__((section(\".reset\"))) __attribute__((naked))\nvoid reset_handler(void)\n{\n\t/* Set stack pointer */\n\t__asm(\"    MOVW.W  r0, #0x1700\\n\"\n\t\t  \"    MOVT.W  r0, #0x0100\\n\"\n\t\t  \"    mov     sp, r0\\n\");\n\n\t/* Zero fill the bss segment. */\n\t__asm(\"    ldr     r0, =__bss_start__\\n\"\n\t\t  \"    ldr     r1, =__bss_end__\\n\"\n\t\t  \"    mov     r2, #0\\n\"\n\t\t  \"    .thumb_func\\n\"\n\t\t  \"zero_loop:\\n\"\n\t\t  \"    cmp     r0, r1\\n\"\n\t\t  \"    it      lt\\n\"\n\t\t  \"    strlt   r2, [r0], #4\\n\"\n\t\t  \"    blt     zero_loop\");\n\n\t/* Call the application's entry point. */\n\tmain();\n}\n\n/*\n * This is the code that gets called when the processor receives an unexpected\n * interrupt.  This simply enters an infinite loop, preserving the system state\n * for examination by a debugger.\n */\nvoid default_handler(void)\n{\n\t/* Enter an infinite loop. */\n\twhile (1)\n\t\t;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/npcx/npcx_algo.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x08,0xb5,0xdf,0xf8,0x08,0xd0,0x00,0xf0,0x2f,0xf9,0x00,0x00,0x48,0x15,0x0c,0x20,\n0x03,0x4b,0x18,0x70,0x19,0x72,0x08,0x33,0x1a,0x78,0xd2,0x09,0xfc,0xd1,0x70,0x47,\n0x16,0x00,0x02,0x40,0x70,0xb5,0x11,0x4c,0x23,0x78,0x03,0xf0,0xfd,0x03,0x23,0x70,\n0xc0,0x21,0x05,0x20,0xff,0xf7,0xec,0xff,0x0d,0x4a,0x0e,0x49,0x6f,0xf0,0x7f,0x43,\n0x6f,0xf0,0x2e,0x05,0x10,0x46,0x15,0x70,0x06,0x78,0xf6,0x09,0xfc,0xd1,0x0e,0x78,\n0xf6,0x07,0x01,0xd5,0x01,0x3b,0xf6,0xd1,0x22,0x78,0x42,0xf0,0x02,0x02,0x00,0x2b,\n0x22,0x70,0x0c,0xbf,0x03,0x20,0x00,0x20,0x70,0xbd,0x00,0xbf,0x1f,0x00,0x02,0x40,\n0x1e,0x00,0x02,0x40,0x1a,0x00,0x02,0x40,0x08,0xb5,0xc0,0x21,0x06,0x20,0xff,0xf7,\n0xc7,0xff,0xff,0xf7,0xcf,0xff,0x28,0xb9,0x03,0x4b,0x1b,0x78,0x13,0xf0,0x02,0x0f,\n0x08,0xbf,0x02,0x20,0x08,0xbd,0x00,0xbf,0x1a,0x00,0x02,0x40,0xf8,0xb5,0x12,0x4c,\n0x23,0x78,0x03,0xf0,0xfd,0x03,0x23,0x70,0x10,0x4b,0x17,0x46,0xc0,0xf3,0x07,0x42,\n0x1a,0x70,0xc0,0xf3,0x07,0x22,0xc0,0xb2,0x03,0xf8,0x01,0x2c,0x0e,0x46,0x03,0xf8,\n0x02,0x0c,0xe8,0x21,0x02,0x20,0xff,0xf7,0xa3,0xff,0x00,0x25,0xae,0x42,0x04,0xd8,\n0x23,0x78,0x43,0xf0,0x02,0x03,0x23,0x70,0xf8,0xbd,0x78,0x5d,0xe0,0x21,0xff,0xf7,\n0x97,0xff,0x01,0x35,0xf2,0xe7,0x00,0xbf,0x1f,0x00,0x02,0x40,0x19,0x00,0x02,0x40,\n0x70,0x47,0x2d,0xe9,0xf0,0x41,0x00,0xf1,0xff,0x06,0x26,0xf0,0xff,0x06,0x34,0x1a,\n0x8c,0x42,0x28,0xbf,0x0c,0x46,0x80,0x46,0x0d,0x46,0x17,0x46,0x5c,0xb1,0xff,0xf7,\n0xb3,0xff,0x58,0xb9,0x3a,0x46,0xa1,0xb2,0x40,0x46,0xff,0xf7,0xbf,0xff,0xff,0xf7,\n0x81,0xff,0x18,0xb9,0x27,0x44,0x2c,0x1b,0x14,0xb9,0x20,0x46,0xbd,0xe8,0xf0,0x81,\n0xb4,0xf5,0x80,0x7f,0x25,0x46,0x28,0xbf,0x4f,0xf4,0x80,0x75,0xff,0xf7,0x9c,0xff,\n0x00,0x28,0xf3,0xd1,0x3a,0x46,0xa9,0xb2,0x30,0x46,0xff,0xf7,0xa7,0xff,0xff,0xf7,\n0x69,0xff,0x00,0x28,0xea,0xd1,0x2f,0x44,0x2e,0x44,0x64,0x1b,0xe4,0xe7,0x00,0x00,\n0x2d,0xe9,0xf0,0x47,0x14,0x4e,0x15,0x4f,0xdf,0xf8,0x54,0x80,0x05,0x46,0x0c,0x46,\n0x8a,0x46,0x05,0xeb,0x04,0x09,0xa9,0xeb,0x0a,0x09,0xba,0xf1,0x00,0x0f,0x02,0xd1,\n0x50,0x46,0xbd,0xe8,0xf0,0x87,0xff,0xf7,0x77,0xff,0x00,0x28,0xf9,0xd1,0xc9,0xf3,\n0x07,0x43,0x33,0x70,0xc9,0xf3,0x07,0x23,0x5f,0xfa,0x89,0xf9,0x3b,0x70,0xc8,0x21,\n0x20,0x20,0x88,0xf8,0x00,0x90,0xff,0xf7,0x33,0xff,0xff,0xf7,0x3b,0xff,0x00,0x28,\n0xe7,0xd1,0xaa,0xf5,0x80,0x5a,0xdc,0xe7,0x19,0x00,0x02,0x40,0x18,0x00,0x02,0x40,\n0x17,0x00,0x02,0x40,0x08,0xb5,0xff,0xf7,0x57,0xff,0x38,0xb9,0xc0,0x21,0xc7,0x20,\n0xff,0xf7,0x1e,0xff,0xbd,0xe8,0x08,0x40,0xff,0xf7,0x24,0xbf,0x08,0xbd,0x00,0x00,\n0x38,0xb5,0xff,0xf7,0x49,0xff,0x04,0x46,0xc0,0xb9,0x0d,0x4b,0x0d,0x4d,0xf2,0x21,\n0x28,0x70,0x18,0x70,0x01,0x20,0xff,0xf7,0x0b,0xff,0xff,0xf7,0x13,0xff,0x04,0x46,\n0x60,0xb9,0xc1,0x21,0x05,0x20,0xff,0xf7,0x03,0xff,0x2b,0x78,0x2b,0xb9,0xc1,0x21,\n0x35,0x20,0xff,0xf7,0xfd,0xfe,0x2b,0x78,0x03,0xb1,0x02,0x24,0x20,0x46,0x38,0xbd,\n0x1b,0x00,0x02,0x40,0x1a,0x00,0x02,0x40,0x10,0xb5,0xc3,0x21,0x04,0x46,0x9f,0x20,\n0xff,0xf7,0xee,0xfe,0x06,0x4b,0x07,0x4a,0x19,0x78,0x01,0x33,0x00,0x20,0x1b,0x78,\n0x12,0x78,0x1b,0x02,0x43,0xea,0x01,0x43,0x13,0x43,0x23,0x60,0x10,0xbd,0x00,0xbf,\n0x1a,0x00,0x02,0x40,0x1c,0x00,0x02,0x40,0x08,0xb5,0x10,0x22,0x00,0x21,0x00,0xf0,\n0x4d,0xf8,0x00,0x20,0x08,0xbd,0x00,0x00,0x73,0xb5,0x21,0x48,0x20,0x4c,0xff,0xf7,\n0xf3,0xff,0x20,0x4a,0x13,0x78,0x43,0xf0,0x80,0x03,0x13,0x70,0xff,0xf7,0xb0,0xff,\n0x05,0x46,0x58,0xb9,0x1c,0x4e,0xe3,0x68,0x00,0x2b,0xfc,0xd0,0xa3,0x68,0x01,0x3b,\n0x03,0x2b,0x2a,0xd8,0xdf,0xe8,0x03,0xf0,0x04,0x18,0x20,0x23,0xe5,0x60,0xfd,0xe7,\n0x01,0xa8,0xff,0xf7,0xc1,0xff,0xa8,0xb9,0x01,0x9b,0x33,0x70,0x1a,0x0a,0x1b,0x0c,\n0x72,0x70,0xb3,0x70,0xf0,0x70,0x23,0x7b,0x25,0x73,0x63,0x7b,0x65,0x73,0xa3,0x7b,\n0xa5,0x73,0xe3,0x7b,0xe5,0x73,0xde,0xe7,0x20,0x68,0x61,0x68,0xff,0xf7,0x48,0xff,\n0x00,0x28,0xf0,0xd0,0xe0,0x60,0xfe,0xe7,0xff,0xf7,0x74,0xff,0xf8,0xe7,0x20,0x68,\n0x61,0x68,0x32,0x46,0xff,0xf7,0x05,0xff,0xf2,0xe7,0x01,0x20,0xf2,0xe7,0x00,0xbf,\n0x00,0x00,0x0c,0x20,0x10,0x30,0x0c,0x40,0x10,0x00,0x0c,0x20,0xf0,0xb5,0x05,0x00,\n0x83,0x07,0x4e,0xd0,0x54,0x1e,0x00,0x2a,0x46,0xd0,0x0a,0x06,0x12,0x0e,0x03,0x00,\n0x03,0x26,0x02,0xe0,0x01,0x35,0x01,0x3c,0x3e,0xd3,0x01,0x33,0x2a,0x70,0x33,0x42,\n0xf8,0xd1,0x03,0x2c,0x2f,0xd9,0xff,0x22,0x0a,0x40,0x15,0x02,0x15,0x43,0x2a,0x04,\n0x15,0x43,0x0f,0x2c,0x38,0xd9,0x27,0x00,0x10,0x3f,0x3f,0x09,0x3e,0x01,0xb4,0x46,\n0x1e,0x00,0x1a,0x00,0x10,0x36,0x66,0x44,0x15,0x60,0x55,0x60,0x95,0x60,0xd5,0x60,\n0x10,0x32,0xb2,0x42,0xf8,0xd1,0x0f,0x26,0x0c,0x22,0x01,0x37,0x3f,0x01,0x26,0x40,\n0xdb,0x19,0x37,0x00,0x22,0x42,0x1a,0xd0,0x3e,0x1f,0xb6,0x08,0xb4,0x00,0xa4,0x46,\n0x1a,0x00,0x1c,0x1d,0x64,0x44,0x20,0xc2,0xa2,0x42,0xfc,0xd1,0x03,0x24,0x01,0x36,\n0xb6,0x00,0x9b,0x19,0x3c,0x40,0x00,0x2c,0x06,0xd0,0x09,0x06,0x1c,0x19,0x09,0x0e,\n0x19,0x70,0x01,0x33,0x9c,0x42,0xfb,0xd1,0xf0,0xbc,0x02,0xbc,0x08,0x47,0x34,0x00,\n0xf1,0xe7,0x14,0x00,0x03,0x00,0xbc,0xe7,0x27,0x00,0xdd,0xe7,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/npcx/npcx_flash.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2020 by Nuvoton Technology Corporation\n * Mulin Chao <mlchao@nuvoton.com>\n * Wealian Liao <WHLIAO@nuvoton.com>\n */\n\n#include <stdint.h>\n#include <string.h>\n#include \"npcx_flash.h\"\n\n/*----------------------------------------------------------------------------\n *                             NPCX flash driver\n *----------------------------------------------------------------------------*/\nstatic void flash_execute_cmd(uint8_t code, uint8_t cts)\n{\n\t/* Set UMA code */\n\tNPCX_UMA_CODE = code;\n\t/* Execute UMA flash transaction by CTS setting */\n\tNPCX_UMA_CTS = cts;\n\t/* Wait for transaction completed */\n\twhile (NPCX_IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE))\n\t\t;\n}\n\nstatic void flash_cs_level(uint8_t level)\n{\n\t/* Program chip select pin to high/low level */\n\tif (level)\n\t\tNPCX_SET_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1);\n\telse\n\t\tNPCX_CLEAR_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1);\n}\n\nstatic void flash_set_address(uint32_t dest_addr)\n{\n\tuint8_t *addr = (uint8_t *)&dest_addr;\n\n\t/* Set target flash address */\n\tNPCX_UMA_AB2 = addr[2];\n\tNPCX_UMA_AB1 = addr[1];\n\tNPCX_UMA_AB0 = addr[0];\n}\n\nvoid delay(uint32_t i)\n{\n\twhile (i--)\n\t\t;\n}\n\nstatic int flash_wait_ready(uint32_t timeout)\n{\n\t/* Chip Select down. -- Burst mode */\n\tflash_cs_level(0);\n\n\t/* Command for Read status register */\n\tflash_execute_cmd(NPCX_CMD_READ_STATUS_REG, NPCX_MASK_CMD_ONLY);\n\twhile (timeout > 0) {\n\t\t/* Read status register */\n\t\tNPCX_UMA_CTS = NPCX_MASK_RD_1BYTE;\n\t\twhile (NPCX_IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE))\n\t\t\t;\n\n\t\tif (!(NPCX_UMA_DB0 & NPCX_SPI_FLASH_SR1_BUSY))\n\t\t\tbreak;\n\n\t\tif (--timeout > 0)\n\t\t\tdelay(100);\n\n\t}; /* Wait for Busy clear */\n\n\t/* Chip Select high. */\n\tflash_cs_level(1);\n\n\tif (timeout == 0)\n\t\treturn NPCX_FLASH_STATUS_FAILED_TIMEOUT;\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\nstatic int flash_write_enable(void)\n{\n\t/* Write enable command */\n\tflash_execute_cmd(NPCX_CMD_WRITE_EN, NPCX_MASK_CMD_ONLY);\n\n\t/* Wait for flash is not busy */\n\tint status = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\tif (NPCX_UMA_DB0 & NPCX_SPI_FLASH_SR1_WEL)\n\t\treturn NPCX_FLASH_STATUS_OK;\n\telse\n\t\treturn NPCX_FLASH_STATUS_FAILED;\n}\n\nstatic void flash_burst_write(uint32_t dest_addr, uint16_t bytes,\n\t\tconst uint8_t *data)\n{\n\t/* Chip Select down -- Burst mode */\n\tflash_cs_level(0);\n\n\t/* Set write address */\n\tflash_set_address(dest_addr);\n\t/* Start programming */\n\tflash_execute_cmd(NPCX_CMD_FLASH_PROGRAM, NPCX_MASK_CMD_WR_ADR);\n\tfor (uint32_t i = 0; i < bytes; i++) {\n\t\tflash_execute_cmd(*data, NPCX_MASK_CMD_WR_ONLY);\n\t\tdata++;\n\t}\n\n\t/* Chip Select up */\n\tflash_cs_level(1);\n}\n\n/* The data to write cannot cross 256 Bytes boundary */\nstatic int flash_program_write(uint32_t addr, uint32_t size,\n\t\tconst uint8_t *data)\n{\n\tint status = flash_write_enable();\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\tflash_burst_write(addr, size, data);\n\treturn flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);\n}\n\nint flash_physical_write(uint32_t offset, uint32_t size, const uint8_t *data)\n{\n\tint status;\n\tuint32_t trunk_start = (offset + 0xff) & ~0xff;\n\n\t/* write head */\n\tuint32_t dest_addr = offset;\n\tuint32_t write_len = ((trunk_start - offset) > size) ? size : (trunk_start - offset);\n\n\tif (write_len) {\n\t\tstatus = flash_program_write(dest_addr, write_len, data);\n\t\tif (status != NPCX_FLASH_STATUS_OK)\n\t\t\treturn status;\n\t\tdata += write_len;\n\t}\n\n\tdest_addr = trunk_start;\n\tsize -= write_len;\n\n\t/* write remaining data*/\n\twhile (size > 0) {\n\t\twrite_len = (size > NPCX_FLASH_WRITE_SIZE) ?\n\t\t\t\t\tNPCX_FLASH_WRITE_SIZE : size;\n\n\t\tstatus = flash_program_write(dest_addr, write_len, data);\n\t\tif (status != NPCX_FLASH_STATUS_OK)\n\t\t\treturn status;\n\n\t\tdata      += write_len;\n\t\tdest_addr += write_len;\n\t\tsize      -= write_len;\n\t}\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\nint flash_physical_erase(uint32_t offset, uint32_t size)\n{\n\t/* Alignment has been checked in upper layer */\n\tfor (; size > 0; size -= NPCX_FLASH_ERASE_SIZE,\n\t\toffset += NPCX_FLASH_ERASE_SIZE) {\n\t\t/* Enable write */\n\t\tint status = flash_write_enable();\n\t\tif (status != NPCX_FLASH_STATUS_OK)\n\t\t\treturn status;\n\n\t\t/* Set erase address */\n\t\tflash_set_address(offset);\n\t\t/* Start erase */\n\t\tflash_execute_cmd(NPCX_CMD_SECTOR_ERASE, NPCX_MASK_CMD_ADR);\n\t\t/* Wait erase completed */\n\t\tstatus = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);\n\t\tif (status != NPCX_FLASH_STATUS_OK)\n\t\t\treturn status;\n\t}\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\nint flash_physical_erase_all(void)\n{\n\t/* Enable write */\n\tint status = flash_write_enable();\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\t/* Start erase */\n\tflash_execute_cmd(NPCX_CMD_CHIP_ERASE, NPCX_MASK_CMD_ONLY);\n\n\t/* Wait erase completed */\n\tstatus = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\nint flash_physical_clear_stsreg(void)\n{\n\t/* Enable write */\n\tint status = flash_write_enable();\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\tNPCX_UMA_DB0 = 0x0;\n\tNPCX_UMA_DB1 = 0x0;\n\n\t/* Write status register 1/2 */\n\tflash_execute_cmd(NPCX_CMD_WRITE_STATUS_REG, NPCX_MASK_CMD_WR_2BYTE);\n\n\t/* Wait writing completed */\n\tstatus = flash_wait_ready(NPCX_FLASH_ABORT_TIMEOUT);\n\tif (status != NPCX_FLASH_STATUS_OK)\n\t\treturn status;\n\n\t/* Read status register 1/2 for checking */\n\tflash_execute_cmd(NPCX_CMD_READ_STATUS_REG, NPCX_MASK_CMD_RD_1BYTE);\n\tif (NPCX_UMA_DB0 != 0x00)\n\t\treturn NPCX_FLASH_STATUS_FAILED;\n\tflash_execute_cmd(NPCX_CMD_READ_STATUS_REG2, NPCX_MASK_CMD_RD_1BYTE);\n\tif (NPCX_UMA_DB0 != 0x00)\n\t\treturn NPCX_FLASH_STATUS_FAILED;\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\nint flash_get_id(uint32_t *id)\n{\n\tflash_execute_cmd(NPCX_CMD_READ_ID, NPCX_MASK_CMD_RD_3BYTE);\n\t*id = NPCX_UMA_DB0 << 16 | NPCX_UMA_DB1 << 8 | NPCX_UMA_DB2;\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\n/*----------------------------------------------------------------------------\n *                             flash loader function\n *----------------------------------------------------------------------------*/\nuint32_t flashloader_init(struct npcx_flash_params *params)\n{\n\t/* Initialize params buffers */\n\tmemset(params, 0, sizeof(struct npcx_flash_params));\n\n\treturn NPCX_FLASH_STATUS_OK;\n}\n\n/*----------------------------------------------------------------------------\n *                                      Functions\n *----------------------------------------------------------------------------*/\n/* flashloader parameter structure */\n__attribute__ ((section(\".buffers.g_cfg\")))\nvolatile struct npcx_flash_params g_cfg;\n/* data buffer */\n__attribute__ ((section(\".buffers.g_buf\")))\nuint8_t g_buf[NPCX_FLASH_LOADER_BUFFER_SIZE];\n\nint main(void)\n{\n\tuint32_t id;\n\n\t/* set buffer */\n\tflashloader_init((struct npcx_flash_params *)&g_cfg);\n\n\t/* Avoid F_CS0 toggles while programming the internal flash. */\n\tNPCX_SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI);\n\n\t/* clear flash status registers */\n\tint status = flash_physical_clear_stsreg();\n\tif (status != NPCX_FLASH_STATUS_OK) {\n\t\twhile (1)\n\t\t\tg_cfg.sync = status;\n\t}\n\n\twhile (1) {\n\t\t/* wait command*/\n\t\twhile (g_cfg.sync == NPCX_FLASH_LOADER_WAIT)\n\t\t\t;\n\n\t\t/* command handler */\n\t\tswitch (g_cfg.cmd) {\n\t\tcase NPCX_FLASH_CMD_GET_FLASH_ID:\n\t\t\tstatus = flash_get_id(&id);\n\t\t\tif (status == NPCX_FLASH_STATUS_OK) {\n\t\t\t\tg_buf[0] = id & 0xff;\n\t\t\t\tg_buf[1] = (id >> 8) & 0xff;\n\t\t\t\tg_buf[2] = (id >> 16) & 0xff;\n\t\t\t\tg_buf[3] = 0x00;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase NPCX_FLASH_CMD_ERASE_SECTORS:\n\t\t\tstatus = flash_physical_erase(g_cfg.addr, g_cfg.len);\n\t\t\tbreak;\n\t\tcase NPCX_FLASH_CMD_ERASE_ALL:\n\t\t\tstatus = flash_physical_erase_all();\n\t\t\tbreak;\n\t\tcase NPCX_FLASH_CMD_PROGRAM:\n\t\t\tstatus = flash_physical_write(g_cfg.addr,\n\t\t\t\t\t\t\tg_cfg.len,\n\t\t\t\t\t\t\tg_buf);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tstatus = NPCX_FLASH_STATUS_FAILED_UNKNOWN_COMMAND;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* clear & set result for next command */\n\t\tif (status != NPCX_FLASH_STATUS_OK) {\n\t\t\tg_cfg.sync = status;\n\t\t\twhile (1)\n\t\t\t\t;\n\t\t} else {\n\t\t\tg_cfg.sync = NPCX_FLASH_LOADER_WAIT;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n__attribute__ ((section(\".stack\")))\n__attribute__ ((used))\nstatic uint32_t stack[NPCX_FLASH_LOADER_STACK_SIZE / 4];\nextern uint32_t _estack;\nextern uint32_t _bss;\nextern uint32_t _ebss;\n\n__attribute__ ((section(\".entry\")))\nvoid entry(void)\n{\n\t/* set sp from end of stack */\n\t__asm(\" ldr sp, =_estack - 4\");\n\n\tmain();\n\n\t__asm(\" bkpt #0x00\");\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/npcx/npcx_flash.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2020 by Nuvoton Technology Corporation\n * Mulin Chao <mlchao@nuvoton.com>\n * Wealian Liao <WHLIAO@nuvoton.com>\n */\n\n#ifndef OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_H\n#define OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_H\n\n#include \"npcx_flash_config.h\"\n\n/* Bit functions */\n#define NPCX_SET_BIT(reg, bit)           ((reg) |= (0x1 << (bit)))\n#define NPCX_CLEAR_BIT(reg, bit)         ((reg) &= (~(0x1 << (bit))))\n#define NPCX_IS_BIT_SET(reg, bit)        (((reg) >> (bit)) & (0x1))\n\n/* Field functions */\n#define NPCX_GET_POS_FIELD(pos, size)    (pos)\n#define NPCX_GET_SIZE_FIELD(pos, size)   (size)\n#define NPCX_FIELD_POS(field)            NPCX_GET_POS_##field\n#define NPCX_FIELD_SIZE(field)           NPCX_GET_SIZE_##field\n/* Read field functions */\n#define NPCX_GET_FIELD(reg, field) \\\n\t_NPCX_GET_FIELD_((reg), NPCX_FIELD_POS(field), NPCX_FIELD_SIZE(field))\n#define _NPCX_GET_FIELD_(reg, f_pos, f_size) \\\n\t(((reg) >> (f_pos)) & ((1 << (f_size)) - 1))\n/* Write field functions */\n#define NPCX_SET_FIELD(reg, field, value) \\\n\t_NPCX_SET_FIELD_((reg), NPCX_FIELD_POS(field), NPCX_FIELD_SIZE(field), (value))\n#define _NPCX_SET_FIELD_(reg, f_pos, f_size, value) \\\n\t((reg) = ((reg) & (~(((1 << (f_size)) - 1) << (f_pos)))) | ((value) << (f_pos)))\n\n/* Register definitions */\n#define NPCX_REG32_ADDR(addr)            ((volatile uint32_t *)(addr))\n#define NPCX_REG16_ADDR(addr)            ((volatile uint16_t *)(addr))\n#define NPCX_REG8_ADDR(addr)             ((volatile uint8_t  *)(addr))\n\n#define NPCX_HW_BYTE(addr)               (*NPCX_REG8_ADDR(addr))\n#define NPCX_HW_WORD(addr)               (*NPCX_REG16_ADDR(addr))\n#define NPCX_HW_DWORD(addr)              (*NPCX_REG32_ADDR(addr))\n\n/* Devalt */\n#define NPCX_SCFG_BASE_ADDR  0x400C3000\n#define NPCX_DEVCNT          NPCX_HW_BYTE(NPCX_SCFG_BASE_ADDR + 0x000)\n#define NPCX_DEVALT(n)\t     NPCX_HW_BYTE(NPCX_SCFG_BASE_ADDR + 0x010 + (n))\n\n#define NPCX_DEVCNT_HIF_TYP_SEL_FIELD    FIELD(2, 2)\n#define NPCX_DEVCNT_JEN0_HEN             4\n#define NPCX_DEVCNT_JEN1_HEN             5\n#define NPCX_DEVCNT_F_SPI_TRIS           6\n\n/* Pin-mux for SPI/FIU */\n#define NPCX_DEVALT0_SPIP_SL             0\n#define NPCX_DEVALT0_GPIO_NO_SPIP        3\n#define NPCX_DEVALT0_F_SPI_CS1_2         4\n#define NPCX_DEVALT0_F_SPI_CS1_1         5\n#define NPCX_DEVALT0_F_SPI_QUAD          6\n#define NPCX_DEVALT0_NO_F_SPI            7\n\n/* Flash Interface Unit (FIU) registers */\n#define NPCX_FIU_BASE_ADDR   0x40020000\n#define NPCX_FIU_CFG         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x000)\n#define NPCX_BURST_CFG       NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x001)\n#define NPCX_RESP_CFG        NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x002)\n#define NPCX_SPI_FL_CFG      NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x014)\n#define NPCX_UMA_CODE        NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x016)\n#define NPCX_UMA_AB0         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x017)\n#define NPCX_UMA_AB1         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x018)\n#define NPCX_UMA_AB2         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x019)\n#define NPCX_UMA_DB0         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01A)\n#define NPCX_UMA_DB1         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01B)\n#define NPCX_UMA_DB2         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01C)\n#define NPCX_UMA_DB3         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01D)\n#define NPCX_UMA_CTS         NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01E)\n#define NPCX_UMA_ECTS        NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x01F)\n#define NPCX_UMA_DB0_3      NPCX_HW_DWORD(NPCX_FIU_BASE_ADDR + 0x020)\n#define NPCX_FIU_RD_CMD      NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x030)\n#define NPCX_FIU_DMM_CYC     NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x032)\n#define NPCX_FIU_EXT_CFG     NPCX_HW_BYTE(NPCX_FIU_BASE_ADDR + 0x033)\n#define NPCX_FIU_UMA_AB0_3  NPCX_HW_DWORD(NPCX_FIU_BASE_ADDR + 0x034)\n\n/* FIU register fields */\n#define NPCX_RESP_CFG_IAD_EN             0\n#define NPCX_RESP_CFG_DEV_SIZE_EX        2\n#define NPCX_UMA_CTS_A_SIZE              3\n#define NPCX_UMA_CTS_C_SIZE              4\n#define NPCX_UMA_CTS_RD_WR               5\n#define NPCX_UMA_CTS_DEV_NUM             6\n#define NPCX_UMA_CTS_EXEC_DONE           7\n#define NPCX_UMA_ECTS_SW_CS0             0\n#define NPCX_UMA_ECTS_SW_CS1             1\n#define NPCX_UMA_ECTS_SEC_CS             2\n#define NPCX_UMA_ECTS_UMA_LOCK           3\n\n/* Flash UMA commands for npcx internal SPI flash */\n#define NPCX_CMD_READ_ID                 0x9F\n#define NPCX_CMD_READ_MAN_DEV_ID         0x90\n#define NPCX_CMD_WRITE_EN                0x06\n#define NPCX_CMD_WRITE_STATUS            0x50\n#define NPCX_CMD_READ_STATUS_REG         0x05\n#define NPCX_CMD_READ_STATUS_REG2        0x35\n#define NPCX_CMD_WRITE_STATUS_REG        0x01\n#define NPCX_CMD_FLASH_PROGRAM           0x02\n#define NPCX_CMD_SECTOR_ERASE            0x20\n#define NPCX_CMD_PROGRAM_UINT_SIZE       0x08\n#define NPCX_CMD_PAGE_SIZE               0x00\n#define NPCX_CMD_READ_ID_TYPE            0x47\n#define NPCX_CMD_FAST_READ               0x0B\n#define NPCX_CMD_CHIP_ERASE              0xC7\n\n/*\n * Status registers for SPI flash\n */\n#define NPCX_SPI_FLASH_SR2_SUS           (1 << 7)\n#define NPCX_SPI_FLASH_SR2_CMP           (1 << 6)\n#define NPCX_SPI_FLASH_SR2_LB3           (1 << 5)\n#define NPCX_SPI_FLASH_SR2_LB2           (1 << 4)\n#define NPCX_SPI_FLASH_SR2_LB1           (1 << 3)\n#define NPCX_SPI_FLASH_SR2_QE            (1 << 1)\n#define NPCX_SPI_FLASH_SR2_SRP1          (1 << 0)\n#define NPCX_SPI_FLASH_SR1_SRP0          (1 << 7)\n#define NPCX_SPI_FLASH_SR1_SEC           (1 << 6)\n#define NPCX_SPI_FLASH_SR1_TB            (1 << 5)\n#define NPCX_SPI_FLASH_SR1_BP2           (1 << 4)\n#define NPCX_SPI_FLASH_SR1_BP1           (1 << 3)\n#define NPCX_SPI_FLASH_SR1_BP0           (1 << 2)\n#define NPCX_SPI_FLASH_SR1_WEL           (1 << 1)\n#define NPCX_SPI_FLASH_SR1_BUSY          (1 << 0)\n\n#define NPCX_MASK_CMD_ONLY               (0xC0)\n#define NPCX_MASK_CMD_ADR                (0xC0 | 0x08)\n#define NPCX_MASK_CMD_ADR_WR             (0xC0 | 0x20 | 0x08 | 0x01)\n#define NPCX_MASK_RD_1BYTE               (0xC0 | 0x10 | 0x01)\n#define NPCX_MASK_RD_2BYTE               (0xC0 | 0x10 | 0x02)\n#define NPCX_MASK_RD_3BYTE               (0xC0 | 0x10 | 0x03)\n#define NPCX_MASK_RD_4BYTE               (0xC0 | 0x10 | 0x04)\n#define NPCX_MASK_CMD_RD_1BYTE           (0xC0 | 0x01)\n#define NPCX_MASK_CMD_RD_2BYTE           (0xC0 | 0x02)\n#define NPCX_MASK_CMD_RD_3BYTE           (0xC0 | 0x03)\n#define NPCX_MASK_CMD_RD_4BYTE           (0xC0 | 0x04)\n#define NPCX_MASK_CMD_WR_ONLY            (0xC0 | 0x20)\n#define NPCX_MASK_CMD_WR_1BYTE           (0xC0 | 0x20 | 0x10 | 0x01)\n#define NPCX_MASK_CMD_WR_2BYTE           (0xC0 | 0x20 | 0x10 | 0x02)\n#define NPCX_MASK_CMD_WR_ADR             (0xC0 | 0x20 | 0x08)\n\n/* Flash loader parameters */\nstruct __attribute__((__packed__)) npcx_flash_params {\n\tuint32_t addr; /* Address in flash */\n\tuint32_t len;  /* Number of bytes */\n\tuint32_t cmd;  /* Command */\n\tuint32_t sync; /* Handshake signal */\n};\n\n/* Flash trigger signal */\nenum npcx_flash_handshake {\n\tNPCX_FLASH_LOADER_WAIT    = 0x0,       /* Idle */\n\tNPCX_FLASH_LOADER_EXECUTE = 0xFFFFFFFF /* Execute Command */\n};\n\n/* Flash loader command */\nenum npcx_flash_commands {\n\tNPCX_FLASH_CMD_NO_ACTION = 0, /* No action, default value */\n\tNPCX_FLASH_CMD_GET_FLASH_ID,  /* Get the internal flash ID */\n\tNPCX_FLASH_CMD_ERASE_SECTORS, /* Erase unprotected sectors */\n\tNPCX_FLASH_CMD_ERASE_ALL,     /* Erase all */\n\tNPCX_FLASH_CMD_PROGRAM,       /* Program data */\n};\n\n/* Status */\nenum npcx_flash_status {\n\tNPCX_FLASH_STATUS_OK = 0,\n\tNPCX_FLASH_STATUS_FAILED_UNKNOWN_COMMAND,\n\tNPCX_FLASH_STATUS_FAILED,\n\tNPCX_FLASH_STATUS_FAILED_TIMEOUT,\n};\n\n#endif /* OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/npcx/npcx_flash.lds",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#include \"npcx_flash_config.h\"\n\n/* Application memory map */\nMEMORY {\n\t/* buffer + parameters */\n    BUFFER (RWX)  : ORIGIN = NPCX_FLASH_LOADER_PARAMS_ADDR,\n                      LENGTH = NPCX_FLASH_LOADER_PARAMS_SIZE + NPCX_FLASH_LOADER_BUFFER_SIZE\n\n    PROGRAM (RWX)  : ORIGIN = NPCX_FLASH_LOADER_PROGRAM_ADDR,\n                     LENGTH = NPCX_FLASH_LOADER_PROGRAM_SIZE\n}\n\n/* Sections used for flashing */\nSECTIONS\n{\n\t.buffers (NOLOAD) :\n\t{\n\t\t_buffers = .;\n\t\t*(.buffers.g_cfg)\n\t\t*(.buffers.g_buf)\n\t\t*(.buffers*)\n\t\t_ebuffers = .;\n\t} > BUFFER\n\n\t.text :\n\t{\n\t\t_text = .;\n\t\t*(.entry*)\n\t\t*(.text*)\n\t\t_etext = .;\n\t} > PROGRAM\n\n\t.data :\n\t{\t_data = .;\n\t\t*(.rodata*)\n\t\t*(.data*)\n\t\t_edata = .;\n\t} > PROGRAM\n\n\t.bss :\n\t{\n\t\t__bss_start__ = .;\n\t\t_bss = .;\n\t\t*(.bss*)\n\t\t*(COMMON)\n\t\t_ebss = .;\n\t\t__bss_end__ = .;\n\t} > PROGRAM\n\n\t.stack (NOLOAD) :\n\t{\n\t\t_stack = .;\n\t\t*(.stack*)\n\t\t_estack = .;\n\t} > PROGRAM\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/npcx/npcx_flash_config.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2021 by Nuvoton Technology Corporation\n * Mulin Chao <mlchao@nuvoton.com>\n * Wealian Liao <WHLIAO@nuvoton.com>\n */\n\n#ifndef OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_CONFIG_H\n#define OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_CONFIG_H\n\n#define NPCX_FLASH_ABORT_TIMEOUT 0xFFFFFF\n\n/* NPCX chip information */\n#define NPCX_FLASH_WRITE_SIZE 256L   /* One page size for write */\n#define NPCX_FLASH_ERASE_SIZE 0x1000\n\n/* NPCX flash loader information */\n#define NPCX_FLASH_LOADER_WORKING_ADDR 0x200C0000\n#define NPCX_FLASH_LOADER_PARAMS_ADDR NPCX_FLASH_LOADER_WORKING_ADDR\n#define NPCX_FLASH_LOADER_PARAMS_SIZE 16\n#define NPCX_FLASH_LOADER_BUFFER_ADDR (NPCX_FLASH_LOADER_PARAMS_ADDR + NPCX_FLASH_LOADER_PARAMS_SIZE)\n#define NPCX_FLASH_LOADER_BUFFER_SIZE NPCX_FLASH_ERASE_SIZE\n#define NPCX_FLASH_LOADER_PROGRAM_ADDR (NPCX_FLASH_LOADER_BUFFER_ADDR + NPCX_FLASH_LOADER_BUFFER_SIZE)\n#define NPCX_FLASH_LOADER_PROGRAM_SIZE 0x1000\n\n/* Stack size in byte. 4 byte size alignment */\n#define NPCX_FLASH_LOADER_STACK_SIZE 400\n\n\n#endif /* OPENOCD_LOADERS_FLASH_NPCX_NPCX_FLASH_CONFIG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/nrf5/nrf5.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2014 Angus Gratton                                      *\n *   gus@projectgus.com                                                    *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\n/*\n * Params :\n * r0 = byte count\n * r1 = buffer start\n * r2 = buffer end\n * r3 = target address\n * r6 = watchdog refresh value\n * r7 = watchdog refresh register address\n */\n\n\t.thumb_func\n\t.global _start\n_start:\nwait_fifo:\n\t// Kick the watchdog\n\tstr\tr6, [r7, #0]\n\t// Load write pointer\n\tldr\tr5, [r1, #0]\n\t// Abort if it is NULL\n\tcmp\tr5, #0\n\tbeq.n\texit\n\t// Load read pointer\n\tldr\tr4, [r1, #4]\n\t// Continue waiting if it equals the write pointer\n\tcmp\tr4, r5\n\tbeq.n\twait_fifo\n\t// Copy one word from buffer to target, and increment pointers\n\tldmia\tr4!, {r5}\n\tstmia\tr3!, {r5}\n\t// If at end of buffer, wrap back to buffer start\n\tcmp\tr4, r2\n\tbcc.n   no_wrap\n\tmov\tr4, r1\n\tadds\tr4, #8\nno_wrap:\n\t// Update read pointer inside the buffer\n\tstr\tr4, [r1, #4]\n\t// Deduce the word transferred from the byte count\n\tsubs\tr0, #4\n\t// Start again\n\tbne.n   wait_fifo\nexit:\n\t// Wait for OpenOCD\n\tbkpt\t#0x00\n\n\t.pool\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/nrf5/nrf5.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x3e,0x60,0x0d,0x68,0x00,0x2d,0x0b,0xd0,0x4c,0x68,0xac,0x42,0xf8,0xd0,0x20,0xcc,\n0x20,0xc3,0x94,0x42,0x01,0xd3,0x0c,0x46,0x08,0x34,0x4c,0x60,0x04,0x38,0xef,0xd1,\n0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/numicro/numicro_m0.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   Copyright (C) 2017 Zale Yu                                            *\n *   CYYU@nuvoton.com                                                      *\n *                                                                         *\n *   Copyright (C) 2022 Jian-Hong Pan                                      *\n *   chienhung.pan@gmail.com                                               *\n ***************************************************************************/\n\n\t.text\n\t.cpu cortex-m0\n\t.thumb\n\n\t/* Params:\n\t * r0 - workarea buffer / result\n\t * r1 - target address\n\t * r2 - wordcount\n\t * Clobbered:\n\t * r4 - tmp\n\t * r5 - tmp\n\t * r6 - tmp\n\t * r7 - tmp\n\t */\n\n.L1:\n\t/* for(register uint32_t i=0;i<wcount;i++){ */\n\tmov\tr4, r0\n\tmov\tr3, #0\n.L2:\n\tsub\tr5, r1, r0\n\tadd\tr7, r4, r5\n\tcmp\tr3, r2\n\tbeq\t.L7\n.L4:\n\t/* NUMICRO_FLASH_ISPADR = faddr; */\n\tldr\tr6, .L8\n\tstr\tr7, [r6]\n\t/* NUMICRO_FLASH_ISPDAT = *pLW; */\n\tldmia\tr4!, {r7}\n\tldr\tr5, .L8+4\n\tstr\tr7, [r5]\n\t/* faddr += 4; */\n\t/* pLW++; */\n\t/*  Trigger write action  */\n\t/* NUMICRO_FLASH_ISPTRG = ISPTRG_ISPGO; */\n\tldr\tr5, .L8+8\n\tmov\tr6, #1\n\tstr\tr6, [r5]\n.L3:\n\t/* while((NUMICRO_FLASH_ISPTRG & ISPTRG_ISPGO) == ISPTRG_ISPGO){}; */\n\tldr\tr7, [r5]\n\tlsl\tr7, r7, #31\n\tbmi\t.L3\n\n\tadd\tr3, r3, #1\n\tb\t.L2\n.L7:\n\t/* return (NUMICRO_FLASH_ISPCON & ISPCON_ISPFF); */\n\tldr\tr3, .L8+12\n\tldr\tr0, [r3]\n\tmov\tr1, #64\n\tand\tr0, r1\n.L9:\n\tbkpt\t#0\n.L8:\n\t.word\t0x5000C004\n\t.word\t0x5000C008\n\t.word\t0x5000C010\n\t.word\t0x5000C000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/numicro/numicro_m0.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x04,0x1c,0x00,0x23,0x0d,0x1a,0x67,0x19,0x93,0x42,0x0c,0xd0,0x08,0x4e,0x37,0x60,\n0x80,0xcc,0x08,0x4d,0x2f,0x60,0x08,0x4d,0x01,0x26,0x2e,0x60,0x2f,0x68,0xff,0x07,\n0xfc,0xd4,0x01,0x33,0xee,0xe7,0x05,0x4b,0x18,0x68,0x40,0x21,0x08,0x40,0x00,0xbe,\n0x04,0xc0,0x00,0x50,0x08,0xc0,0x00,0x50,0x10,0xc0,0x00,0x50,0x00,0xc0,0x00,0x50,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/numicro/numicro_m4.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 Zale Yu                                            *\n *   CYYU@nuvoton.com                                                      *\n *                                                                         *\n *   Copyright (C) 2022 Jian-Hong Pan                                      *\n *   chienhung.pan@gmail.com                                               *\n ***************************************************************************/\n\n\t.text\n\t.cpu cortex-m4\n\t.thumb\n\n\t/* Params:\n\t * r0 - workarea buffer / result\n\t * r1 - target address\n\t * r2 - wordcount\n\t * Clobbered:\n\t * r4 - tmp\n\t * r5 - tmp\n\t * r6 - tmp\n\t * r7 - tmp\n\t */\n\n.L1:\n\t/* for(register uint32_t i=0;i<wcount;i++){ */\n\tmov\tr4, r0\n\tmov\tr3, #0\n.L2:\n\tsub\tr5, r1, r0\n\tadd\tr7, r4, r5\n\tcmp\tr3, r2\n\tbeq\t.L7\n.L4:\n\t/* NUMICRO_FLASH_ISPADR = faddr; */\n\tldr\tr6, .L8\n\tstr\tr7, [r6]\n\t/* NUMICRO_FLASH_ISPDAT = *pLW; */\n\tldmia\tr4!, {r7}\n\tldr\tr5, .L8+4\n\tstr\tr7, [r5]\n\t/* faddr += 4; */\n\t/* pLW++; */\n\t/*  Trigger write action  */\n\t/* NUMICRO_FLASH_ISPTRG = ISPTRG_ISPGO; */\n\tldr\tr5, .L8+8\n\tmov\tr6, #1\n\tstr\tr6, [r5]\n.L3:\n\t/* while((NUMICRO_FLASH_ISPTRG & ISPTRG_ISPGO) == ISPTRG_ISPGO){}; */\n\tldr\tr7, [r5]\n\tlsl\tr7, r7, #31\n\tbmi\t.L3\n\n\tadd\tr3, r3, #1\n\tb\t.L2\n.L7:\n\t/* return (NUMICRO_FLASH_ISPCON & ISPCON_ISPFF); */\n\tldr\tr3, .L8+12\n\tldr\tr0, [r3]\n\tmov\tr1, #64\n\tand\tr0, r1\n.L9:\n\tbkpt\t#0\n.L8:\n\t.word\t0x4000C004\n\t.word\t0x4000C008\n\t.word\t0x4000C010\n\t.word\t0x4000C000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/numicro/numicro_m4.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x04,0x1c,0x00,0x23,0x0d,0x1a,0x67,0x19,0x93,0x42,0x0c,0xd0,0x08,0x4e,0x37,0x60,\n0x80,0xcc,0x08,0x4d,0x2f,0x60,0x08,0x4d,0x01,0x26,0x2e,0x60,0x2f,0x68,0xff,0x07,\n0xfc,0xd4,0x01,0x33,0xee,0xe7,0x05,0x4b,0x18,0x68,0x40,0x21,0x08,0x40,0x00,0xbe,\n0x04,0xc0,0x00,0x40,0x08,0xc0,0x00,0x40,0x10,0xc0,0x00,0x40,0x00,0xc0,0x00,0x40,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/pic32mx.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arch m4k\n\t.set noreorder\n\t.set noat\n\n/* params:\n * $a0 src adr - ram + result\n * $a1 dest adr - flash\n * $a2 count (32bit words)\n * vars\n *\n * temps:\n * $t0, $t1, $t2, $t3, $t4, $t5\n * $s0, $s1, $s3, $s4, $s5\n */\n\n\t.type main, @function\n\t.global main\n\n.ent main\nmain:\n\t/* setup constants */\n\tlui\t\t$t0, 0xaa99\n\tori\t\t$t0, 0x6655\t\t\t\t/* NVMKEY1 */\n\tlui\t\t$t1, 0x5566\n\tori\t\t$t1, 0x99AA\t\t\t\t/* NVMKEY2 */\n\tlui\t\t$t2, 0xBF80\n\tori\t\t$t2, 0xF400\t\t\t\t/* NVMCON */\n\tori\t\t$t3, $zero, 0x4003\t\t/* NVMCON row write cmd */\n\tori\t\t$t4, $zero, 0x8000\t\t/* NVMCON start cmd */\n\nwrite_row:\n\t/* can we perform a row write: 128 32bit words */\n\tsltiu\t$s3, $a2, 128\n\tbne\t\t$s3, $zero, write_word\n\tori\t\t$t5, $zero, 0x4000\t\t/* NVMCON clear cmd */\n\n\t/* perform row write 512 bytes */\n\tsw\t\t$a1, 32($t2)\t/* set NVMADDR with dest addr - real addr */\n\tsw\t\t$a0, 64($t2)\t/* set NVMSRCADDR with src addr - real addr */\n\n\tbal\t\tprogflash\n\taddiu\t$a0, $a0, 512\n\taddiu\t$a1, $a1, 512\n\tbeq\t\t$zero, $zero, write_row\n\taddiu\t$a2, $a2, -128\n\nwrite_word:\n\t/* write 32bit words */\n\tlui\t\t$s5, 0xa000\n\tori\t\t$s5, 0x0000\n\tor\t\t$a0, $a0, $s5\t\t\t/* convert to virtual addr */\n\n\tbeq\t\t$zero, $zero, next_word\n\tori\t\t$t3, $zero, 0x4001\t\t/* NVMCON word write cmd */\n\nprog_word:\n\tlw\t\t$s4, 0($a0)\t\t/* load data - from virtual addr */\n\tsw\t\t$s4, 48($t2)\t/* set NVMDATA with data */\n\tsw\t\t$a1, 32($t2)\t/* set NVMADDR with dest addr - real addr */\n\n\tbal\t\tprogflash\n\taddiu\t$a0, $a0, 4\n\taddiu\t$a1, $a1, 4\n\taddiu\t$a2, $a2, -1\nnext_word:\n\tbne\t\t$a2, $zero, prog_word\n\tnop\n\ndone:\n\tbeq\t\t$zero, $zero, exit\n\taddiu\t$a0, $zero, 0\n\nerror:\n\t/* save result to $a0 */\n\taddiu\t$a0, $s1, 0\n\nexit:\n\tsdbbp\n.end main\n\n\t.type progflash, @function\n\t.global progflash\n\n.ent progflash\nprogflash:\n\tsw\t\t$t3, 0($t2)\t\t/* set NVMWREN */\n\tsw\t\t$t0, 16($t2)\t/* write NVMKEY1 */\n\tsw\t\t$t1, 16($t2)\t/* write NVMKEY2 */\n\tsw\t\t$t4, 8($t2)\t\t/* start operation */\n\nwaitflash:\n\tlw\t\t$s0, 0($t2)\n\tand\t\t$s0, $s0, $t4\n\tbne\t\t$s0, $zero, waitflash\n\tnop\n\n\t/* following is to comply with errata #34\n\t * 500ns delay required */\n\tnop\n\tnop\n\tnop\n\tnop\n\t/* check for errors */\n\tlw\t\t$s1, 0($t2)\n\tandi\t$s1, $zero, 0x3000\n\tbne\t\t$s1, $zero, error\n\tsw\t\t$t5, 4($t2)\t\t/* clear NVMWREN */\n\tjr\t\t$ra\n\tnop\n\n.end progflash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/rsl10/rom_launcher.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Toms Stūrmanis                                  *\n *   toms.sturmanis@gmail.com                                              *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m4\n\t.thumb\n    .align 8\n\n/*\n * Params :\n * r0-r2 = arguments\n * r3 = target address in rom\n */\n\n\t.thumb_func\n\t.global _start\n_start:\nlaunch_program_in_rom:\n    // variables are already set, address to jump is in r3\n    blx r3\nexit:\n\t// Wait for OpenOCD\n\tbkpt\t#0x00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/rsl10/rom_launcher.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x98,0x47,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/sh_qspi/sh_qspi.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/*\n * SH QSPI (Quad SPI) driver\n * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>\n */\n\n#define BIT(n)\t\t(1UL << (n))\n/* SH QSPI register bit masks <REG>_<BIT> */\n#define SPCR_MSTR\t0x08\n#define SPCR_SPE\t0x40\n#define SPSR_SPRFF\t0x80\n#define SPSR_SPTEF\t0x20\n#define SPPCR_IO3FV\t0x04\n#define SPPCR_IO2FV\t0x02\n#define SPPCR_IO1FV\t0x01\n#define SPBDCR_RXBC0\tBIT(0)\n#define SPCMD_SCKDEN\tBIT(15)\n#define SPCMD_SLNDEN\tBIT(14)\n#define SPCMD_SPNDEN\tBIT(13)\n#define SPCMD_SSLKP\tBIT(7)\n#define SPCMD_BRDV0\tBIT(2)\n#define SPCMD_INIT1\tSPCMD_SCKDEN | SPCMD_SLNDEN | \\\n\t\t\tSPCMD_SPNDEN | SPCMD_SSLKP | \\\n\t\t\tSPCMD_BRDV0\n#define SPCMD_INIT2\tSPCMD_SPNDEN | SPCMD_SSLKP | \\\n\t\t\tSPCMD_BRDV0\n#define SPBFCR_TXRST\tBIT(7)\n#define SPBFCR_RXRST\tBIT(6)\n#define SPBFCR_TXTRG\t0x30\n#define SPBFCR_RXTRG\t0x07\n\n/* SH QSPI register set */\n#define SH_QSPI_SPCR\t\t0x00\n#define SH_QSPI_SSLP\t\t0x01\n#define SH_QSPI_SPPCR\t\t0x02\n#define SH_QSPI_SPSR\t\t0x03\n#define SH_QSPI_SPDR\t\t0x04\n#define SH_QSPI_SPSCR\t\t0x08\n#define SH_QSPI_SPSSR\t\t0x09\n#define SH_QSPI_SPBR\t\t0x0a\n#define SH_QSPI_SPDCR\t\t0x0b\n#define SH_QSPI_SPCKD\t\t0x0c\n#define SH_QSPI_SSLND\t\t0x0d\n#define SH_QSPI_SPND\t\t0x0e\n#define SH_QSPI_DUMMY0\t\t0x0f\n#define SH_QSPI_SPCMD0\t\t0x10\n#define SH_QSPI_SPCMD1\t\t0x12\n#define SH_QSPI_SPCMD2\t\t0x14\n#define SH_QSPI_SPCMD3\t\t0x16\n#define SH_QSPI_SPBFCR\t\t0x18\n#define SH_QSPI_DUMMY1\t\t0x19\n#define SH_QSPI_SPBDCR\t\t0x1a\n#define SH_QSPI_SPBMUL0\t\t0x1c\n#define SH_QSPI_SPBMUL1\t\t0x20\n#define SH_QSPI_SPBMUL2\t\t0x24\n#define SH_QSPI_SPBMUL3\t\t0x28\n\n.syntax unified\n.arm\n.text\n\n.macro wait_for_spsr, spsrbit\n\t1:\tldrb\tr12, [r0, #SH_QSPI_SPSR]\n\t\ttst\tr12, \\spsrbit\n\t\tbeq\t1b\n.endm\n\n.macro sh_qspi_xfer\n\tbl\tsh_qspi_cs_activate\n\tstr\tr6, [r0, SH_QSPI_SPBMUL0]\n\tbl\tsh_qspi_xfer_common\n\tbl\tsh_qspi_cs_deactivate\n.endm\n\n.macro sh_qspi_write_enable\n\tldr\tr4,\t=SPIFLASH_WRITE_ENABLE\n\tadr\tr5,\t_start\n\tadd\tr4,\tr5\n\tmov\tr5,\t#0x0\n\tmov\tr6,\t#0x1\n\tsh_qspi_xfer\n.endm\n\n.macro sh_qspi_wait_till_ready\n\t1:\tldr\tr4,\t=SPIFLASH_READ_STATUS\n\t\tadr\tr5,\t_start\n\t\tadd\tr4,\tr5\n\t\tmov\tr5,\t#0x0\n\t\tmov\tr6,\t#0x2\n\t\tsh_qspi_xfer\n\t\tand\tr13,\t#0x1\n\t\tcmp\tr13,\t#0x1\n\t\tbeq\t1b\n.endm\n\n/*\n * r0: controller base address\n * r1: data buffer base address\n * r2: BIT(31) -- page program (not read)\n *     BIT(30) -- 4-byte address (not 3-byte)\n *     BIT(29) -- 512-byte page (not 256-byte)\n *     BIT(27:20) -- SF command\n *     BIT(19:0)  -- amount of data to read/write\n * r3: SF target address\n *\n * r7: data size\n * r8: page size\n *\n * r14: lr, link register\n * r15: pc, program counter\n *\n * Clobber: r4, r5, r6, r7, r8\n */\n\n.global _start\n_start:\n\tbic\tr7,\tr2, #0xff000000\n\tbic\tr7,\tr7, #0x00f00000\n\n\tand\tr8,\tr2, #(1 << 31)\n\tcmp\tr8,\t#(1 << 31)\n\tbeq\tdo_page_program\n\n/* fast read */\n\n\tbl\tsh_qspi_cs_activate\n\n\tbl\tsh_qspi_setup_command\n\tadd\tr8, r6, r7\n\tstr\tr8, [r0, SH_QSPI_SPBMUL0]\n\tbl\tsh_qspi_xfer_common\n\n\tmov\tr4,\t#0x0\n\tmov\tr5,\tr1\n\tmov\tr6,\tr7\n\tbl\tsh_qspi_xfer_common\n\n\tbl\tsh_qspi_cs_deactivate\n\n\tb end\n\ndo_page_program:\n\n\tmov\tr8,\t#0x100\n\ttst\tr2,\t(1 << 29)\n\tmovne\tr8,\t#0x200\n\ndo_pp_next_page:\n\t/* Check if less then page bytes left. */\n\tcmp\tr7,\tr8\n\tmovlt\tr8,\tr7\n\n\tsh_qspi_write_enable\n\n\tbl\tsh_qspi_cs_activate\n\n\tbl\tsh_qspi_setup_command\n\tstr\tr6, [r0, SH_QSPI_SPBMUL0]\n\tbl\tsh_qspi_xfer_common\n\n\tmov\tr4,\tr1\n\tmov\tr5,\t#0x0\n\tmov\tr6,\tr8\n\n\tbl\tsh_qspi_xfer_common\n\n\tbl\tsh_qspi_cs_deactivate\n\n\tsh_qspi_wait_till_ready\n\n\tadd\tr1,\tr8\n\tadd\tr3,\tr8\n\tsub\tr7,\tr8\n\tcmp\tr7,\t#0\n\n\tbne\tdo_pp_next_page\n\nend:\n\tbkpt\t#0\n\nsh_qspi_cs_activate:\n\t/* Set master mode only */\n\tmov\tr12,\t#SPCR_MSTR\n\tstrb\tr12,\t[r0, SH_QSPI_SPCR]\n\n\t/* Set command */\n\tmov\tr12,\t#SPCMD_INIT1\n\tstrh\tr12,\t[r0, SH_QSPI_SPCMD0]\n\n\t/* Reset transfer and receive Buffer */\n\tldrb\tr12,\t[r0, SH_QSPI_SPSCR]\n\torr\tr12,\t#(SPBFCR_TXRST | SPBFCR_RXRST)\n\tstrb\tr12,\t[r0, SH_QSPI_SPBFCR]\n\n\t/* Clear transfer and receive Buffer control bit */\n\tldrb\tr12,\t[r0, SH_QSPI_SPBFCR]\n\tbic\tr12,\t#(SPBFCR_TXRST | SPBFCR_RXRST)\n\tstrb\tr12,\t[r0, SH_QSPI_SPBFCR]\n\n\t/* Set sequence control method. Use sequence0 only */\n\tmov\tr12,\t#0x00\n\tstrb\tr12,\t[r0, SH_QSPI_SPSCR]\n\n\t/* Enable SPI function */\n\tldrb\tr12,\t[r0, SH_QSPI_SPCR]\n\torr\tr12,\t#SPCR_SPE\n\tstrb\tr12,\t[r0, SH_QSPI_SPCR]\n\n\tmov\tpc,\tlr\n\nsh_qspi_cs_deactivate:\n\t/* Disable SPI function */\n\tldrb\tr12,\t[r0, SH_QSPI_SPCR]\n\tbic\tr12,\t#SPCR_SPE\n\tstrb\tr12,\t[r0, SH_QSPI_SPCR]\n\n\tmov\tpc,\tlr\n\n/*\n * r0, controller base address\n * r4, tx buffer\n * r5, rx buffer\n * r6, xfer len, non-zero\n *\n * Upon exit, r13 contains the last byte in SPDR\n *\n * Clobber: r11, r12, r13\n */\nsh_qspi_xfer_common:\nprepcopy:\n\tldr\tr13, [r0, #SH_QSPI_SPBFCR]\n\torr\tr13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)\n\tmov\tr11, #32\n\tcmp\tr6, #32\n\n\tbiclt\tr13, #(SPBFCR_TXTRG | SPBFCR_RXTRG)\n\tmovlt\tr11, #1\n\ncopy:\n\tstr\tr13, [r0, #SH_QSPI_SPBFCR]\n\n\twait_for_spsr SPSR_SPTEF\n\n\tmov\tr12, r11\n\tmov\tr13, #0\n\tcmp\tr4, #0\n\tbeq\t3f\n\n2:\tldrb\tr13, [r4], #1\n\tstrb\tr13, [r0, #SH_QSPI_SPDR]\n\tsubs\tr12, #1\n\tbne\t2b\n\tb\t4f\n\n3:\tstrb\tr13, [r0, #SH_QSPI_SPDR]\n\tsubs\tr12, #1\n\tbne\t3b\n\n4:\twait_for_spsr SPSR_SPRFF\n\n\tmov\tr12, r11\n\tcmp\tr5, #0\n\tbeq\t6f\n\n5:\tldrb\tr13, [r0, #SH_QSPI_SPDR]\n\tstrb\tr13, [r5], #1\n\tsubs\tr12, #1\n\tbne\t5b\n\tb\t7f\n\n6:\tldrb\tr13, [r0, #SH_QSPI_SPDR]\n\tsubs\tr12, #1\n\tbne\t6b\n\n7:\tsubs\tr6, r11\n\tbne\tprepcopy\n\n\tmov\tpc,\tlr\n\nsh_qspi_setup_command:\n\tldr\tr4,\t=SPIFLASH_SCRATCH_DATA\n\tadr\tr5,\t_start\n\tadd\tr4,\tr5\n\tand\tr12,\tr2, #0x0ff00000\n\tlsr\tr12,\t#20\n\tstrb\tr12,\t[r4]\n\tmov\tr12,\tr3\n\tstrb\tr12,\t[r4, #4]\n\tlsr\tr12,\t#8\n\tstrb\tr12,\t[r4, #3]\n\tlsr\tr12,\t#8\n\tstrb\tr12,\t[r4, #2]\n\tlsr\tr12,\t#8\n\tstrb\tr12,\t[r4, #1]\n\tlsr\tr12,\t#8\n\tmov\tr5,\t#0x0\n\tmov\tr6,\t#0x4\n\ttst\tr2,\t(1 << 30)\n\tmovne\tr6,\t#0x5\n\n\tmov\tpc,\tlr\n\nSPIFLASH_READ_STATUS:\t.byte\t0x05 /* Read Status Register */\nSPIFLASH_WRITE_ENABLE:\t.byte\t0x06 /* Write Enable */\nSPIFLASH_NOOP:\t\t.byte\t0x00\nSPIFLASH_SCRATCH_DATA:\t.byte\t0x00, 0x0, 0x0, 0x0, 0x0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/sh_qspi/sh_qspi.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xff,0x74,0xc2,0xe3,0x0f,0x76,0xc7,0xe3,0x02,0x81,0x02,0xe2,0x02,0x01,0x58,0xe3,\n0x0a,0x00,0x00,0x0a,0x32,0x00,0x00,0xeb,0x6c,0x00,0x00,0xeb,0x07,0x80,0x86,0xe0,\n0x1c,0x80,0x80,0xe5,0x42,0x00,0x00,0xeb,0x00,0x40,0xa0,0xe3,0x01,0x50,0xa0,0xe1,\n0x07,0x60,0xa0,0xe1,0x3e,0x00,0x00,0xeb,0x39,0x00,0x00,0xeb,0x27,0x00,0x00,0xea,\n0x01,0x8c,0xa0,0xe3,0x02,0x02,0x12,0xe3,0x02,0x8c,0xa0,0x13,0x08,0x00,0x57,0xe1,\n0x07,0x80,0xa0,0xb1,0xcc,0x41,0x9f,0xe5,0x60,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,\n0x00,0x50,0xa0,0xe3,0x01,0x60,0xa0,0xe3,0x1d,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,\n0x2f,0x00,0x00,0xeb,0x2a,0x00,0x00,0xeb,0x19,0x00,0x00,0xeb,0x53,0x00,0x00,0xeb,\n0x1c,0x60,0x80,0xe5,0x2a,0x00,0x00,0xeb,0x01,0x40,0xa0,0xe1,0x00,0x50,0xa0,0xe3,\n0x08,0x60,0xa0,0xe1,0x26,0x00,0x00,0xeb,0x21,0x00,0x00,0xeb,0x88,0x41,0x9f,0xe5,\n0xa8,0x50,0x4f,0xe2,0x05,0x40,0x84,0xe0,0x00,0x50,0xa0,0xe3,0x02,0x60,0xa0,0xe3,\n0x0b,0x00,0x00,0xeb,0x1c,0x60,0x80,0xe5,0x1d,0x00,0x00,0xeb,0x18,0x00,0x00,0xeb,\n0x01,0xd0,0x0d,0xe2,0x01,0x00,0x5d,0xe3,0xf3,0xff,0xff,0x0a,0x08,0x10,0x81,0xe0,\n0x08,0x30,0x83,0xe0,0x08,0x70,0x47,0xe0,0x00,0x00,0x57,0xe3,0xda,0xff,0xff,0x1a,\n0x70,0x00,0x20,0xe1,0x08,0xc0,0xa0,0xe3,0x00,0xc0,0xc0,0xe5,0x84,0xc0,0x0e,0xe3,\n0xb0,0xc1,0xc0,0xe1,0x08,0xc0,0xd0,0xe5,0xc0,0xc0,0x8c,0xe3,0x18,0xc0,0xc0,0xe5,\n0x18,0xc0,0xd0,0xe5,0xc0,0xc0,0xcc,0xe3,0x18,0xc0,0xc0,0xe5,0x00,0xc0,0xa0,0xe3,\n0x08,0xc0,0xc0,0xe5,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0x8c,0xe3,0x00,0xc0,0xc0,0xe5,\n0x0e,0xf0,0xa0,0xe1,0x00,0xc0,0xd0,0xe5,0x40,0xc0,0xcc,0xe3,0x00,0xc0,0xc0,0xe5,\n0x0e,0xf0,0xa0,0xe1,0x18,0xd0,0x90,0xe5,0x37,0xd0,0x8d,0xe3,0x20,0xb0,0xa0,0xe3,\n0x20,0x00,0x56,0xe3,0x37,0xd0,0xcd,0xb3,0x01,0xb0,0xa0,0xb3,0x18,0xd0,0x80,0xe5,\n0x03,0xc0,0xd0,0xe5,0x20,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,\n0x00,0xd0,0xa0,0xe3,0x00,0x00,0x54,0xe3,0x04,0x00,0x00,0x0a,0x01,0xd0,0xd4,0xe4,\n0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,\n0x04,0xd0,0xc0,0xe5,0x01,0xc0,0x5c,0xe2,0xfc,0xff,0xff,0x1a,0x03,0xc0,0xd0,0xe5,\n0x80,0x00,0x1c,0xe3,0xfc,0xff,0xff,0x0a,0x0b,0xc0,0xa0,0xe1,0x00,0x00,0x55,0xe3,\n0x04,0x00,0x00,0x0a,0x04,0xd0,0xd0,0xe5,0x01,0xd0,0xc5,0xe4,0x01,0xc0,0x5c,0xe2,\n0xfb,0xff,0xff,0x1a,0x02,0x00,0x00,0xea,0x04,0xd0,0xd0,0xe5,0x01,0xc0,0x5c,0xe2,\n0xfc,0xff,0xff,0x1a,0x0b,0x60,0x56,0xe0,0xd9,0xff,0xff,0x1a,0x0e,0xf0,0xa0,0xe1,\n0x58,0x40,0x9f,0xe5,0x77,0x5f,0x4f,0xe2,0x05,0x40,0x84,0xe0,0xff,0xc6,0x02,0xe2,\n0x2c,0xca,0xa0,0xe1,0x00,0xc0,0xc4,0xe5,0x03,0xc0,0xa0,0xe1,0x04,0xc0,0xc4,0xe5,\n0x2c,0xc4,0xa0,0xe1,0x03,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x02,0xc0,0xc4,0xe5,\n0x2c,0xc4,0xa0,0xe1,0x01,0xc0,0xc4,0xe5,0x2c,0xc4,0xa0,0xe1,0x00,0x50,0xa0,0xe3,\n0x04,0x60,0xa0,0xe3,0x01,0x01,0x12,0xe3,0x05,0x60,0xa0,0x13,0x0e,0xf0,0xa0,0xe1,\n0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x02,0x00,0x00,0x20,0x02,0x00,0x00,\n0x23,0x02,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/sh_qspi/sh_qspi.ld",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\nOUTPUT_FORMAT(\"elf32-littlearm\", \"elf32-littlearm\", \"elf32-littlearm\")\nOUTPUT_ARCH(arm)\nENTRY(_start)\nSECTIONS\n{\n\t. = 0x0;\n\t. = ALIGN(4);\n\t.text : {\n\t\tsh_qspi.o (.text*)\n\t\t*(.text*)\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/sim3x.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2014 by Ladislav Bábel                                  *\n *   ladababel@seznam.cz                                                   *\n ***************************************************************************/\n\n#define INITIAL_UNLOCK    0x5A\n#define MULTIPLE_UNLOCK   0xF2\n\n#define FLASHCTRL_KEY     0x4002E0C0\n#define FLASHCTRL_CONFIG  0x4002E000\n#define FLASHCTRL_WRADDR  0x4002E0A0\n#define FLASHCTRL_WRDATA  0x4002E0B0\n#define BUSYF             0x00100000\n\n\n\t\t/* Write the initial unlock value to KEY (0xA5) */\n\t\tmovs    r6, #INITIAL_UNLOCK\n\t\tstr     r6, [r0, #FLASHCTRL_KEY]\n\n\t\t/* Write the multiple unlock value to KEY (0xF2) */\n\t\tmovs    r6, #MULTIPLE_UNLOCK\n\t\tstr     r6, [r0, #FLASHCTRL_KEY]\n\nwait_fifo:\n\t\tldr     r6, [r2, #0]\n\t\tcmp\t    r6, #0\n\t\tbeq     exit\n\t\tldr     r5, [r2, #4]\n\t\tcmp     r5, r6\n\t\tbeq     wait_fifo\n\n\t\t/* wait for BUSYF flag */\nwait_busy1:\n\t\tldr     r6, [r0, #FLASHCTRL_CONFIG]\n\t\ttst     r6, #BUSYF\n\t\tbne     wait_busy1\n\n\t\t/* Write the destination address to WRADDR */\n\t\tstr     r4, [r0, #FLASHCTRL_WRADDR]\n\n\t\t/* Write the data half-word to WRDATA in right-justified format */\n\t\tldrh    r6, [r5]\n\t\tstr     r6, [r0, #FLASHCTRL_WRDATA]\n\n\t\tadds    r5, #2\n\t\tadds    r4, #2\n\n\t\t/* wrap rp at end of buffer */\n\t\tcmp     r5, r3\n\t\tbcc     no_wrap\n\t\tmov     r5, r2\n\t\tadds    r5, #8\n\nno_wrap:\n\t\tstr     r5, [r2, #4]\n\t\tsubs    r1, r1, #1\n\t\tcmp     r1, #0\n\t\tbeq     exit\n\t\tb       wait_fifo\n\nexit:\n\t\tmovs    r6, #MULTIPLE_LOCK\n\t\tstr     r6, [r0, #FLASHCTRL_KEY]\n\n\t\t/* wait for BUSYF flag */\nwait_busy2:\n\t\tldr     r6, [r0, #FLASHCTRL_CONFIG]\n\t\ttst     r6, #BUSYF\n\t\tbne     wait_busy2\n\n\t\tbkpt    #0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stellaris.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m3\n\t.thumb\n\t.thumb_func\n\n/*\n * Params :\n * r0 = workarea start\n * r1 = workarea end\n * r2 = target address\n * r3 = count (32bit words)\n *\n * Clobbered:\n * r4 = pFLASH_CTRL_BASE\n * r5 = FLASHWRITECMD\n * r7 - rp\n * r8 - wp, tmp\n */\n\nwrite:\n\tldr \tr4, pFLASH_CTRL_BASE\n\tldr \tr5, FLASHWRITECMD\n\nwait_fifo:\n\tldr \tr8, [r0, #0]\t/* read wp */\n\tcmp \tr8, #0\t\t\t/* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr7, [r0, #4]\t/* read rp */\n\tcmp \tr7, r8\t\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\nmainloop:\n\tstr\t\tr2, [r4, #0]\t/* FMA - write address */\n\tadd\t\tr2, r2, #4\t\t/* increment target address */\n\tldr\t\tr8, [r7], #4\n\tstr\t\tr8, [r4, #4]\t/* FMD - write data */\n\tstr\t\tr5, [r4, #8]\t/* FMC - enable write */\nbusy:\n\tldr\t\tr8, [r4, #8]\n\ttst\t\tr8, #1\n\tbne\t\tbusy\n\n\tcmp \tr7, r1\t\t\t/* wrap rp at end of buffer */\n\tit  \tcs\n\taddcs\tr7, r0, #8\t\t/* skip loader args */\n\tstr \tr7, [r0, #4]\t/* store rp */\n\tsubs\tr3, r3, #1\t\t/* decrement word count */\n\tcbz \tr3, exit\t\t/* loop if not done */\n\tb\t\twait_fifo\nexit:\n\tbkpt\t#0\n\npFLASH_CTRL_BASE: .word 0x400FD000\nFLASHWRITECMD: .word 0xA4420001\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32f1x.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\n\t/* Params:\n\t * r0 - flash base (in), status (out)\n\t * r1 - count (halfword-16bit)\n\t * r2 - workarea start\n\t * r3 - workarea end\n\t * r4 - target address\n\t * Clobbered:\n\t * r5 - rp\n\t * r6 - wp, tmp\n\t * r7 - tmp\n\t */\n\n#define STM32_FLASH_SR_OFFSET 0x0c /* offset of SR register from flash reg base */\n\n\t.thumb_func\n\t.global _start\n_start:\nwait_fifo:\n\tldr \tr6, [r2, #0]\t/* read wp */\n\tcmp \tr6, #0\t\t\t/* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr5, [r2, #4]\t/* read rp */\n\tcmp \tr5, r6\t\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\tldrh\tr6, [r5]\t/* \"*target_address++ = *rp++\" */\n\tstrh\tr6, [r4]\n\tadds\tr5, #2\n\tadds\tr4, #2\nbusy:\n\tldr \tr6, [r0, #STM32_FLASH_SR_OFFSET]\t/* wait until BSY flag is reset */\n\tmovs\tr7, #1\n\ttst \tr6, r7\n\tbne \tbusy\n\tmovs\tr7, #0x14\t\t/* check the error bits */\n\ttst \tr6, r7\n\tbne \terror\n\tcmp \tr5, r3\t\t\t/* wrap rp at end of buffer */\n\tbcc\tno_wrap\n\tmov\tr5, r2\n\tadds\tr5, #8\nno_wrap:\n\tstr \tr5, [r2, #4]\t/* store rp */\n\tsubs\tr1, r1, #1\t\t/* decrement halfword count */\n\tcmp     r1, #0\n\tbeq     exit\t\t/* loop if not done */\n\tb\twait_fifo\nerror:\n\tmovs\tr0, #0\n\tstr \tr0, [r2, #4]\t/* set rp = 0 on error */\nexit:\n\tmov\t\tr0, r6\t\t\t/* return status in r0 */\n\tbkpt\t#0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32f1x.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x16,0x68,0x00,0x2e,0x18,0xd0,0x55,0x68,0xb5,0x42,0xf9,0xd0,0x2e,0x88,0x26,0x80,\n0x02,0x35,0x02,0x34,0xc6,0x68,0x01,0x27,0x3e,0x42,0xfb,0xd1,0x14,0x27,0x3e,0x42,\n0x08,0xd1,0x9d,0x42,0x01,0xd3,0x15,0x46,0x08,0x35,0x55,0x60,0x01,0x39,0x00,0x29,\n0x02,0xd0,0xe5,0xe7,0x00,0x20,0x50,0x60,0x30,0x46,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32f2x.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m3\n\t.thumb\n\n/*\n * Params :\n * r0 = workarea start, status (out)\n * r1 = workarea end\n * r2 = target address\n * r3 = count (16bit words)\n * r4 = flash base\n *\n * Clobbered:\n * r6 - temp\n * r7 - rp\n * r8 - wp, tmp\n */\n\n#define STM32_FLASH_CR_OFFSET\t0x10\t\t\t/* offset of CR register in FLASH struct */\n#define STM32_FLASH_SR_OFFSET\t0x0c\t\t\t/* offset of SR register in FLASH struct */\n\n#define STM32_PROG16\t\t0x101\t\t\t/* PG | PSIZE_16*/\n\n\t.thumb_func\n\t.global\t_start\n_start:\nwait_fifo:\n\tldr \tr8, [r0, #0]\t/* read wp */\n\tcmp \tr8, #0\t\t\t/* abort if wp == 0 */\n\tbeq \texit\n\tldr \tr7, [r0, #4]\t/* read rp */\n\tcmp \tr7, r8\t\t\t/* wait until rp != wp */\n\tbeq \twait_fifo\n\n\tldr\t\tr6, =STM32_PROG16\n\tstr\t\tr6, [r4, #STM32_FLASH_CR_OFFSET]\n\tldrh \tr6, [r7], #0x02\t\t\t\t\t\t/* read one half-word from src, increment ptr */\n\tstrh \tr6, [r2], #0x02\t\t\t\t\t\t/* write one half-word from src, increment ptr */\n\tdsb\nbusy:\n\tldr \tr6, [r4, #STM32_FLASH_SR_OFFSET]\n\ttst \tr6, #0x10000\t\t\t\t\t\t/* BSY (bit16) == 1 => operation in progress */\n\tbne \tbusy\t\t\t\t\t\t\t\t/* wait more... */\n\ttst\t\tr6, #0xf0\t\t\t\t\t\t\t/* PGSERR | PGPERR | PGAERR | WRPERR */\n\tbne\t\terror\t\t\t\t\t\t\t\t/* fail... */\n\n\tcmp \tr7, r1\t\t\t/* wrap rp at end of buffer */\n\tit  \tcs\n\taddcs\tr7, r0, #8\t\t/* skip loader args */\n\tstr \tr7, [r0, #4]\t/* store rp */\n\tsubs\tr3, r3, #1\t\t/* decrement halfword count */\n\tcbz \tr3, exit\t\t/* loop if not done */\n\tb\t\twait_fifo\nerror:\n\tmovs\tr1, #0\n\tstr\t\tr1, [r0, #4]\t/* set rp = 0 on error */\nexit:\n\tmov\t\tr0, r6\t\t\t/* return status in r0 */\n\tbkpt\t#0x00\n\n\t.pool\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32f2x.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xd0,0xf8,0x00,0x80,0xb8,0xf1,0x00,0x0f,0x1b,0xd0,0x47,0x68,0x47,0x45,0xf7,0xd0,\n0x0d,0x4e,0x26,0x61,0x37,0xf8,0x02,0x6b,0x22,0xf8,0x02,0x6b,0xbf,0xf3,0x4f,0x8f,\n0xe6,0x68,0x16,0xf4,0x80,0x3f,0xfb,0xd1,0x16,0xf0,0xf0,0x0f,0x07,0xd1,0x8f,0x42,\n0x28,0xbf,0x00,0xf1,0x08,0x07,0x47,0x60,0x01,0x3b,0x13,0xb1,0xe0,0xe7,0x00,0x21,\n0x41,0x60,0x30,0x46,0x00,0xbe,0x00,0x00,0x01,0x01,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32h7x.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 by STMicroelectronics                              *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m4\n\t.thumb\n\n/*\n * Code limitations:\n * The workarea must have size multiple of 4 bytes, since R/W\n * operations are all at 32 bits.\n * The workarea must be big enough to contain rp, wp and data, thus the minimum\n * workarea size is: min_wa_size = sizeof(rp, wp, data) = 4 + 4 + sizeof(data).\n *  - for 0x450 devices: sizeof(data) = 32 bytes, thus min_wa_size = 40 bytes.\n *  - for 0x480 devices: sizeof(data) = 16 bytes, thus min_wa_size = 24 bytes.\n * To benefit from concurrent host write-to-buffer and target\n * write-to-flash, the workarea must be way bigger than the minimum.\n *\n * To avoid confusions the write word size is got from .block_size member of\n * struct stm32h7x_part_info defined in stm32h7x.c\n*/\n\n/*\n * Params :\n * r0 = workarea start, status (out)\n * r1 = workarea end\n * r2 = target address\n * r3 = count (of write words)\n * r4 = size of write word\n * r5 = flash reg base\n *\n * Clobbered:\n * r6 - rp\n * r7 - wp, status, tmp\n * r8 - loop index, tmp\n */\n\n#define STM32_FLASH_CR_OFFSET\t0x0C\t/* offset of CR register in FLASH struct */\n#define STM32_FLASH_SR_OFFSET\t0x10\t/* offset of SR register in FLASH struct */\n#define STM32_CR_PROG\t\t\t0x00000002\t/* PG */\n#define STM32_SR_QW_MASK\t\t0x00000004\t/* QW */\n#define STM32_SR_ERROR_MASK\t\t0x07ee0000\t/* DBECCERR | SNECCERR | RDSERR | RDPERR | OPERR\n\t\t\t\t\t\t\t\t\t\t\t   | INCERR | STRBERR | PGSERR | WRPERR */\n\n\t.thumb_func\n\t.global _start\n_start:\n\tldr\t\tr6, [r0, #4]\t\t/* read rp */\n\nwait_fifo:\n\tldr\t\tr7, [r0, #0]\t\t/* read wp */\n\tcbz\t\tr7, exit\t\t\t/* abort if wp == 0, status = 0 */\n\tsubs\tr7, r7, r6\t\t\t/* number of bytes available for read in r7 */\n\tittt\tmi\t\t\t\t\t/* if wrapped around */\n\taddmi\tr7, r1\t\t\t\t/* add size of buffer */\n\tsubmi\tr7, r0\n\tsubmi\tr7, #8\n\tcmp\t\tr7, r4\t\t\t\t/* wait until data buffer is full */\n\tbcc\t\twait_fifo\n\n\tmov\t\tr7, #STM32_CR_PROG\n\tstr\t\tr7, [r5, #STM32_FLASH_CR_OFFSET]\n\n\tmov\t\tr8, #4\n\tudiv\tr8, r4, r8\t\t\t/* number of words is size of write word divided by 4*/\nwrite_flash:\n\tdsb\n\tldr\t\tr7, [r6], #0x04\t\t/* read one word from src, increment ptr */\n\tstr\t\tr7, [r2], #0x04\t\t/* write one word to dst, increment ptr */\n\tdsb\n\tcmp\t\tr6, r1\t\t\t\t/* if rp >= end of buffer ... */\n\tit\t\tcs\n\taddcs\tr6, r0, #8\t\t\t/* ... then wrap at buffer start */\n\tsubs\tr8, r8, #1\t\t\t/* decrement loop index */\n\tbne\t\twrite_flash\t\t\t/* loop if not done */\n\nbusy:\n\tldr\t\tr7, [r5, #STM32_FLASH_SR_OFFSET]\n\ttst\t\tr7, #STM32_SR_QW_MASK\n\tbne\t\tbusy\t\t\t\t/* operation in progress, wait ... */\n\n\tldr\t\tr8, =STM32_SR_ERROR_MASK\n\ttst\t\tr7, r8\n\tbne\t\terror\t\t\t\t/* fail... */\n\n\tstr\t\tr6, [r0, #4]\t\t/* store rp */\n\tsubs\tr3, r3, #1\t\t\t/* decrement count */\n\tbne\t\twait_fifo\t\t\t/* loop if not done */\n\tb\t\texit\n\nerror:\n\tmovs\tr8, #0\n\tstr\t\tr8, [r0, #4]\t\t/* set rp = 0 on error */\n\nexit:\n\tmov\t\tr0, r7\t\t\t\t/* return status in r0 */\n\tbkpt\t#0x00\n\n\t.pool\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32h7x.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x46,0x68,0x07,0x68,0x6f,0xb3,0xbf,0x1b,0x42,0xbf,0x7f,0x18,0x3f,0x1a,0x08,0x3f,\n0xa7,0x42,0xf6,0xd3,0x4f,0xf0,0x02,0x07,0xef,0x60,0x4f,0xf0,0x04,0x08,0xb4,0xfb,\n0xf8,0xf8,0xbf,0xf3,0x4f,0x8f,0x56,0xf8,0x04,0x7b,0x42,0xf8,0x04,0x7b,0xbf,0xf3,\n0x4f,0x8f,0x8e,0x42,0x28,0xbf,0x00,0xf1,0x08,0x06,0xb8,0xf1,0x01,0x08,0xf0,0xd1,\n0x2f,0x69,0x17,0xf0,0x04,0x0f,0xfb,0xd1,0xdf,0xf8,0x1c,0x80,0x17,0xea,0x08,0x0f,\n0x03,0xd1,0x46,0x60,0x01,0x3b,0xd4,0xd1,0x03,0xe0,0x5f,0xf0,0x00,0x08,0xc0,0xf8,\n0x04,0x80,0x38,0x46,0x00,0xbe,0x00,0x00,0x00,0x00,0xee,0x07,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32l4x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/**\n * Copyright (C) 2021 Tarek BOCHKATI\n *   tarek.bouchkati@st.com\n */\n\n#define OPENOCD_CONTRIB_LOADERS_FLASH_STM32_STM32L4X\n\n#include <stdint.h>\n#include \"../../../../src/flash/nor/stm32l4x.h\"\n\nstatic inline __attribute__((always_inline))\nvoid copy_buffer_u32(uint32_t *dst, uint32_t *src, int len)\n{\n\tfor (int i = 0; i < len; i++)\n\t\tdst[i] = src[i];\n}\n\n/* this function is assumes that fifo_size is multiple of flash_word_size\n * this condition is ensured by target_run_flash_async_algorithm\n */\n\nvoid write(volatile struct stm32l4_work_area *work_area,\n\t\t   uint8_t *fifo_end,\n\t\t   uint8_t *target_address,\n\t\t   uint32_t count)\n{\n\tvolatile uint32_t *flash_sr = (uint32_t *) work_area->params.flash_sr_addr;\n\tvolatile uint32_t *flash_cr = (uint32_t *) work_area->params.flash_cr_addr;\n\n\t/* optimization to avoid reading from memory each time */\n\tuint8_t *rp_cache  = work_area->fifo.rp;\n\n\t/* fifo_start is used to wrap when we reach fifo_end */\n\tuint8_t *fifo_start = rp_cache;\n\n\t/* enable flash programming */\n\t*flash_cr = FLASH_PG;\n\n\twhile (count) {\n\t\t/* optimization to avoid reading from memory each time */\n\t\tuint8_t *wp_cache  = work_area->fifo.wp;\n\t\tif (wp_cache == 0)\n\t\t\tbreak; /* aborted by target_run_flash_async_algorithm */\n\n\t\tint32_t fifo_size = wp_cache - rp_cache;\n\t\tif (fifo_size < 0) {\n\t\t\t/* consider the linear fifo, we will wrap later */\n\t\t\tfifo_size = fifo_end - rp_cache;\n\t\t}\n\n\t\t/* wait for at least a flash word */\n\t\twhile (fifo_size >= work_area->params.flash_word_size) {\n\t\t\tcopy_buffer_u32((uint32_t *)target_address,\n\t\t\t\t\t(uint32_t *)rp_cache,\n\t\t\t\t\twork_area->params.flash_word_size / 4);\n\n\t\t\t/* update target_address and rp_cache */\n\t\t\ttarget_address += work_area->params.flash_word_size;\n\t\t\trp_cache += work_area->params.flash_word_size;\n\n\t\t\t/* wait for the busy flag */\n\t\t\twhile (*flash_sr & work_area->params.flash_sr_bsy_mask)\n\t\t\t\t;\n\n\t\t\tif (*flash_sr & FLASH_ERROR) {\n\t\t\t\twork_area->fifo.rp = 0; /* set rp to zero 0 on error */\n\t\t\t\tgoto write_end;\n\t\t\t}\n\n\t\t\t/* wrap if reach the fifo_end, and update rp in memory */\n\t\t\tif (rp_cache >= fifo_end)\n\t\t\t\trp_cache = fifo_start;\n\n\t\t\t/* flush the rp cache value,\n\t\t\t * so target_run_flash_async_algorithm can fill the circular fifo */\n\t\t\twork_area->fifo.rp = rp_cache;\n\n\t\t\t/* update fifo_size and count */\n\t\t\tfifo_size -= work_area->params.flash_word_size;\n\t\t\tcount--;\n\t\t}\n\t}\n\nwrite_end:\n\t/* disable flash programming */\n\t*flash_cr = 0;\n\n\t/* soft break the loader */\n\t__asm(\"bkpt 0\");\n}\n\n/* by enabling this define 'DEBUG':\n * the main() function can help help debugging the loader algo\n * note: the application should be linked into RAM */\n\n/* #define DEBUG */\n\n#ifdef DEBUG\n/* device selector: STM32L5 | STM32U5 | STM32WB | STM32WL | STM32WL_CPU2 | STM32G0Bx | ... */\n#define STM32U5\n\n/* when using a secure device, and want to test the secure programming enable this define */\n/* #define SECURE */\n\n#if defined(STM32U5)\n#  define FLASH_WORD_SIZE   16\n#else\n#  define FLASH_WORD_SIZE   8\n#endif\n\n#if defined(STM32WB) || defined(STM32WL)\n#  define FLASH_BASE        0x58004000\n#else\n#  define FLASH_BASE        0x40022000\n#endif\n\n#if defined(STM32G0Bx)\n#  define FLASH_BSY_MASK      (FLASH_BSY | FLASH_BSY2)\n#else\n#  define FLASH_BSY_MASK      FLASH_BSY\n#endif\n\n#if defined(STM32L5) || defined(STM32U5)\n#  ifdef SECURE\n#    define FLASH_KEYR_OFFSET 0x0c\n#    define FLASH_SR_OFFSET   0x24\n#    define FLASH_CR_OFFSET   0x2c\n#  else\n#    define FLASH_KEYR_OFFSET 0x08\n#    define FLASH_SR_OFFSET   0x20\n#    define FLASH_CR_OFFSET   0x28\n#  endif\n#elif defined(STM32WL_CPU2)\n#  define FLASH_KEYR_OFFSET 0x08\n#  define FLASH_SR_OFFSET   0x60\n#  define FLASH_CR_OFFSET   0x64\n#else\n#  define FLASH_KEYR_OFFSET 0x08\n#  define FLASH_SR_OFFSET   0x10\n#  define FLASH_CR_OFFSET   0x14\n#endif\n\n#define FLASH_KEYR        (uint32_t *)((FLASH_BASE) + (FLASH_KEYR_OFFSET))\n#define FLASH_SR          (uint32_t *)((FLASH_BASE) + (FLASH_SR_OFFSET))\n#define FLASH_CR          (uint32_t *)((FLASH_BASE) + (FLASH_CR_OFFSET))\n\nint main()\n{\n\tconst uint32_t count = 2;\n\tconst uint32_t buf_size = count * FLASH_WORD_SIZE;\n\tconst uint32_t work_area_size = sizeof(struct stm32l4_work_area) + buf_size;\n\n\tuint8_t work_area_buf[work_area_size];\n\tstruct stm32l4_work_area *workarea = (struct stm32l4_work_area *)work_area_buf;\n\n\t/* fill the workarea struct */\n\tworkarea->params.flash_sr_addr = (uint32_t)(FLASH_SR);\n\tworkarea->params.flash_cr_addr = (uint32_t)(FLASH_CR);\n\tworkarea->params.flash_word_size = FLASH_WORD_SIZE;\n\tworkarea->params.flash_sr_bsy_mask = FLASH_BSY_MASK;\n\t/* note: the workarea->stack is not used, in this configuration */\n\n\t/* programming the existing memory raw content in workarea->fifo.buf */\n\t/* feel free to fill the memory with magical values ... */\n\n\tworkarea->fifo.wp =  (uint8_t *)(&workarea->fifo.buf + buf_size);\n\tworkarea->fifo.rp =  (uint8_t *)&workarea->fifo.buf;\n\n\t/* unlock the flash */\n\t*FLASH_KEYR = KEY1;\n\t*FLASH_KEYR = KEY2;\n\n\t/* erase sector 0 */\n\t*FLASH_CR = FLASH_PER | FLASH_STRT;\n\twhile (*FLASH_SR & FLASH_BSY)\n\t\t;\n\n\t/* flash address, should be aligned to FLASH_WORD_SIZE */\n\tuint8_t *target_address = (uint8_t *) 0x8000000;\n\n\twrite(workarea,\n\t\t  (uint8_t *)(workarea + work_area_size),\n\t\t  target_address,\n\t\t  count);\n\n\twhile (1)\n\t\t;\n}\n#endif /* DEBUG */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32l4x.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xf0,0xb5,0x87,0xb0,0x07,0x68,0x01,0x93,0x43,0x68,0x04,0x91,0x02,0x93,0x83,0x6f,\n0x02,0x99,0x03,0x93,0x01,0x23,0x0b,0x60,0x03,0x9b,0x01,0x99,0x00,0x29,0x1f,0xd0,\n0x41,0x6f,0x00,0x29,0x1c,0xd0,0xc9,0x1a,0x01,0xd5,0x04,0x99,0xc9,0x1a,0x84,0x68,\n0x8c,0x42,0xf2,0xd8,0x85,0x68,0xac,0x08,0x05,0x94,0x00,0x24,0x05,0x9d,0xa5,0x42,\n0x14,0xdc,0x84,0x68,0x12,0x19,0x84,0x68,0x1b,0x19,0x3c,0x68,0xc5,0x68,0x2e,0x00,\n0x26,0x40,0x25,0x42,0xf9,0xd1,0xfa,0x25,0x3c,0x68,0x2c,0x42,0x0b,0xd0,0x86,0x67,\n0x00,0x23,0x02,0x9a,0x13,0x60,0x00,0xbe,0x07,0xb0,0xf0,0xbd,0xa6,0x00,0x9d,0x59,\n0x01,0x34,0x95,0x51,0xe2,0xe7,0x04,0x9c,0x9c,0x42,0x00,0xd8,0x03,0x9b,0x83,0x67,\n0x84,0x68,0x09,0x1b,0x01,0x9c,0x01,0x3c,0x01,0x94,0xd0,0xe7,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32lx.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2011 Clement Burin des Roziers                          *\n *   clement.burin-des-roziers@hikob.com                                   *\n *                                                                         *\n *   Copyright (C) 2017 Armin van der Togt                                 *\n *   armin@otheruse.nl                                                     *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\n/*\nParameters\n\tr0 - destination address\n\tr1 - source address\n\tr2 - half pages\n\tr3 - bytes per half page\n\tr4 - flash base\nVariables\n\tr0 - destination write pointer\n\tr1 - source read pointer\n\tr2 - source limit address\n\tr3 - bytes per half page\n\tr4 - flash base\n\tr5 - pages left in current half page\n\tr6 - temporary r/w\n*/\n\n/* offsets of registers from flash reg base */\n#define STM32_FLASH_SR_OFFSET 0x18\n\n\t.thumb_func\n\t.global _start\n_start:\n\t// r2 = source + half pages * bytes per half page\n\tmuls r2, r2, r3\n\tadd r2, r1, r2\n\t// Go to compare\n\tb test_done\nwrite_half_page:\n\t// initialize pages left in current half page\n\tmov r5, r3\nwrite_word:\n\t// load word from address in r1 and increase r1 by 4\n\tldmia r1!, {r6}\n\t// store word to address in r0 and increase r0 by 4\n\tstmia r0!, {r6}\n\t// check for end of half page\n\tsubs r5, r5, #4\n\tbne write_word\nwait_busy:\n\t// read status register into r6, loop while bottom bit is set\n\tldr r6, [r4, #STM32_FLASH_SR_OFFSET]\n\tlsls r6, r6, #31\n\tbne wait_busy\ntest_done:\n\t// compare r1 and r2, loop if not equal\n\tcmp\tr1, r2\n\tbne\twrite_half_page\n\n\t// Set breakpoint to exit\n\tbkpt #0x00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stm32/stm32lx.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x5a,0x43,0x0a,0x44,0x07,0xe0,0x1d,0x46,0x40,0xc9,0x40,0xc0,0x04,0x3d,0xfb,0xd1,\n0xa6,0x69,0xf6,0x07,0xfc,0xd1,0x91,0x42,0xf5,0xd1,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/gpio_conf_stm32.pl",
    "content": "#!/usr/bin/perl\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Helper for generating GPIO setup for STM32F0, F4, F7, H7, L0, L1, L4, L4+\n# and F1 (for 'stmqspi' and 'cmspi' drivers).\n#\n# Each pin is configured by \"PortAndBit:Conf:Speed\"\n#  'PortAndBit' specifies Port and bit number\n#  'Conf' is one of 'AFx' (alternate), 'P' (output), 'IN' (input),\n#    (each optionally by 'P' (push-pull) or 'O' (open-drain)),\n#    (all optionally followed by 'UP' (pull-up), or 'DO' (pull-down))\n#  'Speed' is one of 'L' (low), 'M' (medium), 'H' (high), 'V' (very high)\n#\n# Port configuration can be given on command line as a single string (pins separated by commas)\n# or via CubeMX generated file. The latter must consist of the quadspi.c / octospi.c and the\n# corresponding header. The precise spelling in these files doesn't seem to be consistent, though ...\n#\n# Pins have to be ordered this way:\n#  - I2C: SDA, SCL\n#  - SPI (1 line): NCS, CLK, IO1/MISO, IO0/MOSI\n#  - DPI (2 lines): NCS, CLK, IO1/MISO, IO0/MOSI\n#  - QPI (4 lines): NCS, CLK, IO3/NHOLD, IO2/NWP, IO1/MISO, IO0/MOSI\n# For dual flash: BK_1 first, then BK_2. If single NCS for both, omit NCS in BK_2\n# For octal flash: NCS, CLK, DQS, IO7 down to IO0\n\nuse strict;\nuse Getopt::Std;\n\nmy $GPIO_BASE;\nmy $Conf;\nmy $STM32F1 = 0;\n\n# \"Blue-Pill stm32f103cbt6 board w/ cmspi\n#$STM32F1 = 1;\n#$GPIO_BASE = 0x40010800;\n#$Conf = \"PB12:PP:M, PB13:PP:V, PB14:INUP:V, PB15:INUP:V\";\n#$Conf = \"PB12:PP:M, PB13:PP:V, PB14:INUP:V, PB01:INUP:V\";\n\n#$STM32F1 = 1;\n#$GPIO_BASE = 0x40010800;\n#$Conf = \"PB07:INUP:V, PB06:INUP:V\";\n\n# mini-stm32f030f4p6 board w/ cmspi\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PB01:PP:V, PA05:PP:V, PA06:INUP:V, PA07:INUP:V\";\n\n# stm32f407vet6 board w/ cmspi\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB00:PP:M, PB03:PP:V, PB04:INUP:V, PB05:INUP:V\";\n\n# stm32f412g-disco quad\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB02:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V, PG06:AF10:V\";\n\n# stm32f413h-disco\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PF09:AF10:V, PF08:AF10:V, PG06:AF10:V\";\n\n# stm32f469i-disco quad\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB06:AF10:V, PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\";\n# w/ cmspi\n#$Conf = \"PB06:PP:M, PF10:PP:V, PF06:INUP:V, PF07:INUP:V, PF09:INUP:V, PF08:INUP:V\";\n\n# stm32f723e-disco quad\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\";\n\n# stm32f746g-disco quad\n#$GPIO_BASE = 0x40020000;\n#Conf = \"PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PD12:AF09:V, PD11:AF09:V\";\n# w/ cmspi\n#$Conf = \"PB06:PP:M, PB02:PP:V, PD13:INUP:V, PE02:INUP:V, PD12:INUP:V, PD11:INUP:V\";\n\n# stm32f769i-disco quad\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\";\n# w/ cmspi\n#$Conf = \"PB06:PP:M, PB02:PP:V, PD13:INUP:V, PE02:INUP:V, PC10:INUP:V, PC09:INUP:V, \";\n\n# b-l475e-iot01a quad\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\";\n\n# stm32l476g-disco quad\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\";\n\n# stm32l496g-disco quad\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PA07:AF10:V, PA06:AF10:V, PA03:AF10:V, PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\";\n\n# stm32l4r9i-disco octal\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PH10:AF05:V, PH09:AF05:V, \"\n#      . \"PH08:AF05:V, PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\";\n\n# stm32l4p5g-disco octal/octal\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PA07:AF10:V, PA06:AF10:V, PC03:AF10:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V, \"\n#      . \"PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V, PG06:AF03:V\";\n#$Conf = \"PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V, \"\n#      . \"PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\";\n\n# nucleo-f767zi dual quad\n#$GPIO_BASE = 0x40020000;\n#$Conf = \"PB06:AF10:V, PB02:AF09:V, PC11:AF09:V, PD13:AF09:V, PE02:AF09:V, PD12:AF09:V, \"\n#      . \"PD11:AF09:V, PE10:AF10:V, PE09:AF10:V, PE08:AF10:V, PE07:AF10:V\";\n# w/ cmspi\n#$Conf = \"PB10:PPUP:M, PB02:PPUP:V, PD13:INPUP:V, PE02:INPUP:V, PD12:INPUP:V, PD11:INPUP:V\";\n#$Conf = \"PC11:PPUP:M, PB02:PPUP:V, PE10:INPUP:V, PE09:INPUP:V, PE08:INPUP:V, PE07:INPUP:V\";\n\n# nucleo-h743zi dual quad\n#$GPIO_BASE = 0x58020000;\n#$Conf = \"PB10:AF09:V, PB02:AF09:V, PC11:AF09:V, PD13:AF09:V, PE02:AF09:V, PD12:AF09:V, \"\n#      . \"PD11:AF09:V, PE10:AF10:V, PE09:AF10:V, PE08:AF10:V, PE07:AF10:V\";\n# w/ cmspi\n#$Conf = \"PB10:PPUP:M, PB02:PPUP:V, PD13:INPUP:V, PE02:INPUP:V, PD12:INPUP:V, PD11:INPUP:V\";\n#$Conf = \"PC11:PPUP:M, PB02:PPUP:V, PE10:INPUP:V, PE09:INPUP:V, PE08:INPUP:V, PE07:INPUP:V\";\n\n# nucleo-h7a3zi dual quad\n#$GPIO_BASE = 0x58020000;\n#$Conf = \"PB10:AF09:V, PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PD12:AF09:V, PD11:AF09:V, \"\n#      . \"PC11:AF09:V, PE10:AF10:V, PD06:AF10:V, PE08:AF10:V, PE07:AF10:V\";\n# w/ cmspi\n#$Conf = \"PB10:PPUP:M, PB02:PPUP:V, PD13:INPUP:V, PE02:INPUP:V, PD12:INPUP:V, PD11:INPUP:V\";\n#$Conf = \"PC11:PPUP:M, PB02:PPUP:V, PE10:INPUP:V, PD06:INPUP:V, PE08:INPUP:V, PE07:INPUP:V\";\n\n# nucleo-l4r5zi one dual quad single NCS\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PA02:AF10:V, PE10:AF10:V, PD07:AF10:V, PD06:AF10:V, PD05:AF10:V, PD04:AF10:V, \"\n#      . \"PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V\";\n# w/ cmspi\n#$Conf = \"PA02:PPUP:M,  PE10:PPUP:V, PD07:INPDO:V, PD06:INPDO:V, PD05:INPDO:V, PD04:INPDO:V\";\n#$Conf = \"PA02:PPUP:M,  PE10:PPUP:V, PE15:INPDO:V, PE14:INPDO:V, PE13:INPDO:V, PE12:INPDO:V\";\n\n# nucleo-l552ze-q dual quad with single NCS\n#$GPIO_BASE = 0x42020000;\n#$Conf = \"PA02:AF10:V, PE10:AF10:V, PD07:AF10:V, PD06:AF10:V, PD05:AF10:V, PD04:AF10:V, \"\n#      . \"PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V\";\n# w/ cmspi\n#$Conf = \"PA02:PPUP:M,  PE10:PPUP:V, PD07:INPDO:V, PD06:INPDO:V, PD05:INPDO:V, PD04:INPDO:V\";\n#$Conf = \"PA02:PPUP:M,  PE10:PPUP:V, PE15:INPDO:V, PE14:INPDO:V, PE13:INPDO:V, PE12:INPDO:V\";\n\n# nucleo-g071rb dual quad\n#$GPIO_BASE = 0x50000000;\n#$Conf = \"PA00:PPUP:H, PA04:PPUP:V, PB03:INPUP:V, PA10:INPUP:V, PB11:INPUP:H, PB01:INPUP:H\";\n#$Conf = \"PA01:PPUP:H, PA04:PPUP:V, PA08:INPUP:V, PB14:INPUP:V, PB04:INPUP:V, PB05:INPUP:V\";\n\n# nucleo-g474re dual quad with single NCS\n#$GPIO_BASE = 0x48000000;\n#$Conf = \"PB11:AF10:H, PB10:AF10:V, PA06:AF10:V, PA07:AF10:V, PB00:AF10:V, PB01:AF10:V, \"\n#      . \"PC04:AF10:V, PC03:AF10:V, PC02:AF10:V, PC01:AF10:V\";\n# w/ cmspi\n#$Conf = \"PB11:PPUP:H, PB10:PPUP:V, PA06:INPUP:V, PA07:INPUP:V, PB00:INPUP:V, PB01:INPUP:V\";\n#$Conf = \"PB11:PPUP:H, PB10:PPUP:V, PC04:INPUP:V, PC03:INPUP:V, PC02:INPUP:V, PC01:INPUP:V\";\n\n# stm32h745i-disco dual quad with single NCS\n#$GPIO_BASE = 0x58020000;\n#$Conf = \"PG06:AF10:H, PF10:AF09:V, PF06:AF09:V, PF07:AF09:V, PF09:AF10:V, PD11:AF09:V, \"\n#      . \"PG14:AF09:H, PG09:AF09:V, PH03:AF09:V, PH02:AF09:V\";\n\n# stm32h747i-disco dual quad with single NCS\n#GPIO_BASE = 0x58020000;\n#$Conf = \"PG06:AF10:H, PB02:AF09:V, PF06:AF09:V, PF07:AF09:V, PF09:AF10:V, PD11:AF09:V, \"\n#      . \"PG14:AF09:H, PG09:AF09:V, PH03:AF09:V, PH02:AF09:V\";\n\n# stm32h7b3i-disco octal\n#$GPIO_BASE = 0x58020000;\n#$Conf = \"PG06:AF10:V, PB02:AF09:V, PC05:AF10:V, PD07:AF10:V, PG09:AF09:V, PH03:AF09:V, PC01:AF10:V, \"\n#      . \"PF06:AF10:V, PF07:AF10:V, PF09:AF10:V, PD11:AF09:V\";\n\n# stm32h735g-disco octal\n#$GPIO_BASE = 0x58020000;\n#$Conf = \"PG06:AF10:V, PF10:AF09:V, PB02:AF10:V, PD07:AF10:V, PG09:AF09:V, PD05:AF10:V, PD04:AF10:V, \"\n#      . \"PD13:AF09:V, PE02:AF09:V, PD12:AF09:V, PD11:AF09:V\";\n\n# stm32l562e-disco octal\n#$GPIO_BASE = 0x42020000;\n#$Conf = \"PA02:AF10:V, PA03:AF10:V, PB02:AF10:V, PC00:AF03:V, PC03:AF10:V, PC02:AF10:V, PC01:AF10:V, \"\n#      . \"PA06:AF10:V, PA07:AF10:V, PB00:AF10:V, PB01:AF10:V\";\n\n&getopts('b:c:f:t');\nif ($Getopt::Std::opt_b eq '')\n{\n\tif ($GPIO_BASE eq '')\n\t{\n\t\tdie(\"usage: $0 [ -1 ] -b io_base [ -c port_configuration ] [ -f conf_file ]\");\n\t}\n}\nelse\n{\n\t$GPIO_BASE = eval $Getopt::Std::opt_b;\n}\n\nif ($Getopt::Std::opt_c eq '')\n{\n\tif (($Conf eq '') && ($Getopt::Std::opt_f eq ''))\n\t{\n\t\tdie(\"usage: $0 [ -b io_base ] ( -c port_configuration | -f conf_file )\");\n\t}\n}#\nelse\n{\n\t$Conf = $Getopt::Std::opt_c . ',';\n}\n\n$STM32F1 = $Getopt::Std::opt_t;\n\nmy $Sep = \"\\t\";\nmy $Form = \"${Sep}mmw 0x%08X 0x%08X 0x%08X\\t;# \";\n\nmy $GPIO_OFFS;\nmy $GPIO_CRL;\nmy $GPIO_CRH;\nmy $GPIO_MODER;\nmy $GPIO_OTYPER;\nmy $GPIO_OSPEEDR;\nmy $GPIO_PUPDR;\nmy $GPIO_IDR;\nmy $GPIO_ODR;\nmy $GPIO_AFRL;\nmy $GPIO_AFRH;\n\nif ($STM32F1)\n{\n\t# offsets for F1 devices\n\t$GPIO_OFFS = 0x400;\n\t$GPIO_CRL = 0x00;\n\t$GPIO_CRH = 0x04;\n\t$GPIO_IDR = 0x08;\n\t$GPIO_ODR = 0x0C;\n}\nelse\n{\n\t# these offsets are identical on all F0, F4, F7, H7, L4, L4+ devices up to now\n\t$GPIO_OFFS = 0x400;\n\t$GPIO_MODER = 0x00;\n\t$GPIO_OTYPER = 0x04;\n\t$GPIO_OSPEEDR = 0x08;\n\t$GPIO_PUPDR = 0x0C;\n\t$GPIO_IDR = 0x10;\n\t$GPIO_ODR = 0x14;\n\t$GPIO_AFRL = 0x20;\n\t$GPIO_AFRH = 0x24;\n}\n\nmy @Out = ( { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { } );\nmy @Port = ( );\nmy $Exor;\nmy %Conf;\nmy $Pins = \"${Sep}#\";\n\nmy $pins;\nmy $altn;\nmy %defs;\n\nif ($Getopt::Std::opt_f ne '')\n{\n\topen(CONF_FILE, '<', $Getopt::Std::opt_f) || die(\"can't open $Getopt::Std::opt_f\");\n\twhile (my $line = <CONF_FILE>)\n\t{\n\t\tif ($line =~ /^\\s*#define\\s+.?(QSPI|QUAD_?SPI|OCTOSPI[^_]*)\\w+_(Port|Pin)\\s/)\n\t\t{\n\t\t\tif ($line =~ /#define\\s+(\\w+)\\s+(\\w+)/)\n\t\t\t{\n\t\t\t\t$defs{$1} = $2;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tdie($line);\n\t\t\t}\n\t\t}\n\t\telsif ($line =~ /^\\s*(P[A-Z])([0-9]+)\\s*-+>\\s+.?(QSPI|QUAD_?SPI|OCTO_?SPI[^_]*)_(\\w+)/)\n\t\t{\n\t\t\t$Conf{$4} = sprintf(\"%s%02d\", $1, $2);\n\t\t}\n\t\telsif ($line =~ /^\\s*GPIO_InitStruct.Pin\\s*=\\s*([^;]+\\w)/)\n\t\t{\n\t\t\t$pins = $1;\n\t\t\twhile ($line !~ /;/)\n\t\t\t{\n\t\t\t\t$line = <CONF_FILE>;\n\t\t\t\t$line =~ /^\\s*([^;]+\\w)/;\n\t\t\t\t$pins .= $1;\n\t\t\t}\n\t\t}\n\t\telsif ($line =~ /^\\s*GPIO_InitStruct.Alternate\\s*=\\s*GPIO_AF([0-9]+)/)\n\t\t{\n\t\t\t$altn = $1;\n\t\t}\n\t\telsif ($line =~ /^\\s*HAL_GPIO_Init\\s*\\(\\s*(\\w+)\\s*,/)\n\t\t{\n\t\t\tmy $port = $1;\n\t\t\tif ($port =~ /GPIO([A-Z])/)\n\t\t\t{\n\t\t\t\t$port = $1;\n\t\t\t}\n\t\t\telsif (exists($defs{$port}))\n\t\t\t{\n\t\t\t\t$defs{$port} =~ /GPIO([A-Z])/;\n\t\t\t\t$port = $1;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tprintf(\"\\n\");\n\t\t\t\tnext;\n\t\t\t}\n\t\t\tmy @pin = split(/\\s*\\|\\s*/, $pins);\n\t\t\tforeach my $pin (@pin)\n\t\t\t{\n\t\t\t\tmy $bit;\n\t\t\t\tif (exists($defs{$pin}))\n\t\t\t\t{\n\t\t\t\t\t$defs{$pin} =~ /GPIO_PIN_([0-9]+)/;\n\t\t\t\t\t$bit = $1;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$pin =~ /GPIO_PIN_([0-9]+)/;\n\t\t\t\t\t$bit = $1;\n\t\t\t\t}\n\t\t\t\t$Conf .= sprintf(\"P%s%02d:AF%02d:V, \", $port, $bit, $altn);\n\t\t\t}\n\t\t\t$pins = '';\n\t\t\t$altn = 0;\n\t\t}\n\t}\n\tclose(CONF_FILE);\n}\nelse\n{\n\tmy @names = ( );\n\tmy @conf = split(/\\s*,\\s*/, $Conf);\n\n\tif (@conf == 2)\n\t{\n\t\tpush(@names, 'SDA', 'SCL');\n\t} else {\n\t\tif (@conf == 3)\n\t\t{\n\t\t\tpush(@names, 'NCS', 'CLK', 'IO0/DIO');\n\t\t}\n\t\telsif (@conf == 4)\n\t\t{\n\t\t\tpush(@names, 'NCS', 'CLK','IO1/MISO', 'IO0/MOSI');\n\t\t}\n\t\telsif (@conf == 6)\n\t\t{\n\t\t\tpush(@names, 'NCS', 'CLK', 'IO3/NHOLD', 'IO2/NWP', 'IO1/MISO', 'IO0/MOSI');\n\t\t}\n\t\telsif (@conf == 10)\n\t\t{\n\t\t\tpush(@names, 'NCS', 'CLK', 'BK_1_IO3/NHOLD', 'BK1_IO2/NWP', 'BK1_IO1/MISO', 'BK1_IO0/MOSI');\n\t\t\tpush(@names, 'BK_2_IO3/NHOLD', 'BK2_IO2/NWP', 'BK2_IO1/MISO', 'BK2_IO0/MOSI');\n\t\t}\n\t\telsif (@conf == 11)\n\t\t{\n\t\t\tpush(@names, 'BK_1_NCS', 'CLK', 'BK_1_IO3/NHOLD', 'BK1_IO2/NWP', 'BK1_IO1/MISO', 'BK1_IO0/MOSI');\n\t\t\tpush(@names, 'BK_2_NCS', 'BK_2_IO3/NHOLD', 'BK2_IO2/NWP', 'BK2_IO1/MISO', 'BK2_IO0/MOSI');\n\t\t}\n\t\telse\n\t\t{\n\t\t\tdie(\"invalid config\");\n\t\t}\n\t}\n\n\tfor (my $index = 0; $index < @conf; $index++)\n\t{\n\t\tuc($conf[$index]) =~ /^P([A-K])([0-9]+):\\s*([A-Z0-9]+):(L|M|H|V)$/;\n\t\t$Pins .= sprintf(\" %s: P%s%02d,\", $names[$index], $1, $2);\n\t}\n\tchop($Pins);\n}\n\nif (exists $Conf{'BK1_IO0'})\n{\n\t# QuadSPI on F4, F7, H7\n\tmy $line;\n\tfor my $i ('NCS', 'BK1_NCS', 'CLK', 'BK1_IO3', 'BK1_IO2', 'BK1_IO1', 'BK1_IO0')\n\t{\n\t\t(exists $Conf{$i}) && ($Pins .= sprintf(\" %s: %s,\", $Conf{$i}, $i));\n\t}\n}\n\nif (exists $Conf{'BK2_IO0'})\n{\n\t# QuadSPI on F4, F7, H7\n\tmy $line;\n\tfor my $i ('NCS', 'BK2_NCS', 'CLK', 'BK2_IO3', 'BK2_IO2', 'BK2_IO1', 'BK2_IO0')\n\t{\n\t\t(exists $Conf{$i}) && ($Pins .= sprintf(\" %s: %s,\", $Conf{$i}, $i));\n\t}\n}\n\nif (exists $Conf{'P1_IO0'})\n{\n\t# OctoSPI on L4+, L5, H7\n\tmy $line;\n\tfor my $i ('P1_NCS', 'P1_CLK', 'P1_DQS', 'P1_IO7', 'P1_IO6', 'P1_IO5', 'P1_IO4',\n\t\t\t   'P1_IO3', 'P1_IO2', 'P1_IO1', 'P1_IO0')\n\t{\n\t\t(exists $Conf{$i}) && ($Pins .= sprintf(\" %s: %s,\", $Conf{$i}, $i));\n\t}\n}\n\nif (exists $Conf{'P2_IO0'})\n{\n\t# OctoSPI on L4+, H7\n\tmy $line;\n\tfor my $i ('P2_NCS', 'P2_CLK', 'P2_DQS', 'P2_IO7', 'P2_IO6', 'P2_IO5', 'P2_IO4',\n\t\t\t   'P2_IO3', 'P2_IO2', 'P2_IO1', 'P2_IO0')\n\t{\n\t\t(exists $Conf{$i}) && ($Pins .= sprintf(\" %s: %s,\", $Conf{$i}, $i));\n\t}\n}\n\nmy @Col = ( );\nmy @conf = split(/\\s*,\\s*/, $Conf);\n\nif (@conf == 3)\n{\n\tsplice(@conf, 2, 0, 'NONE', 'NONE', 'NONE');\n}\nelsif (@conf == 4)\n{\n\tsplice(@conf, 2, 0, 'NONE', 'NONE');\n}\n\nforeach my $line (@conf)\n{\n\t$line = uc($line);\n\t$line =~ /^P([A-K])([0-9]+):\\s*([A-Z0-9]+):(L|M|H|V)$/;\n\tmy $port = $1;\n\tmy $pin = $2;\n\tmy $conf = $3;\n\tmy $speed = $4;\n\n\tmy $MODER = 0x0;\n\tmy $OTYPER = 0x0;\n\tmy $OSPEEDR = 0x0;\n\tmy $PUPDR = 0x0;\n\tmy $AFR = 0x0;\n\tmy $num = ord(${port}) - ord('A');\n\tmy $out = $Out[$num];\n\n\t(exists $$out{'DEF'}) || ($$out{'DEF'} = 0);\n\n\tif ($conf eq '')\n\t{\n\t\tif ($line ne 'NONE')\n\t\t{\n\t\t\tprintf(STDERR \"invalid conf %s\\n\", $line);\n\t\t}\n\t\tnext;\n\t}\n\telsif ($conf =~ /^AF([0-9]+)(|P|O)(|UP|DO)$/)\n\t{\n\t\tif ($STM32F1)\n\t\t{\n\t\t\tprintf(STDERR \"no alternate %s for F1 family\\n\", $line);\n\t\t\tnext;\n\t\t}\n\t\tif (($1 < 0) || ($1 > 15))\n\t\t{\n\t\t\tprintf(STDERR \"invalid alternate %s\\n\", $line);\n\t\t\tnext;\n\t\t}\n\t\t$MODER = 0x2;\n\t\t$AFR = $1;\n\t\tif ($pin <= 7)\n\t\t{\n\t\t\t$$out{'AFRL_H'} |= ($AFR << (${pin} << 2));\n\t\t\t$$out{'AFRL_L'} |= (($AFR ^ 0xF) << (${pin} << 2));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$$out{'AFRH_H'} |= ($AFR << ((${pin} - 8) << 2));\n\t\t\t$$out{'AFRH_L'} |= (($AFR ^ 0xF) << ((${pin} - 8) << 2));\n\t\t}\n\t\tif ($2 ne '') {\n\t\t\t$OTYPER = ($1 eq 'O') ? 0x1 : 0x0;\n\t\t\t$$out{'OTYPER_H'} |= ($OTYPER << $pin);\n\t\t\t$$out{'OTYPER_L'} |= (($OTYPER ^ 0x1) << $pin);\n\t\t}\n\t\t$PUPDR = ($3 eq 'UP') ? 0x1 : (($3 eq 'DO') ? 0x2 : 0x0);\n\t\t$$out{'PUPDR_H'} |= ($PUPDR << (${pin} << 1));\n\t\t$$out{'PUPDR_L'} |= (($PUPDR ^0x3) << (${pin} << 1));\n\t\t$conf = sprintf(\"AF%02d%s%s\", $AFR, $2, $3);\n\t}\n\telsif ($conf =~ /^IN(|P|O)(|UP|DO)$/)\n\t{\n\t\tif ($STM32F1)\n\t\t{\n\t\t\t$MODER = ($1 eq '') ? 0x4 : 0x8;\n\t\t\t($2 eq 'UP') && ($$out{'PUPDR_H'} |= (1 << ${pin}));\n\t\t\t($2 eq 'DO') && ($$out{'PUPDR_L'} |= (1 << ${pin}));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$MODER = 0x0;\n\t\t\tif ($1 ne '')\n\t\t\t{\n\t\t\t\t$OTYPER = ($1 eq 'O') ? 0x1 : 0x0;\n\t\t\t\t$$out{'OTYPER_H'} |= ($OTYPER << $pin);\n\t\t\t\t$$out{'OTYPER_L'} |= (($OTYPER ^ 0x1) << $pin);\n\t\t\t}\n\t\t\t$PUPDR = ($2 eq 'UP') ? 0x1 : (($2 eq 'DO') ? 0x2 : 0x0);\n\t\t\t$$out{'PUPDR_H'} |= ($PUPDR << (${pin} << 1));\n\t\t\t$$out{'PUPDR_L'} |= (($PUPDR ^0x3) << (${pin} << 1));\n\t\t}\n\t\t($2 eq 'UP') && ($$out{'ODR_H'} |= (1 << ${pin}));\n\t\t($2 eq 'DO') && ($$out{'ODR_L'} |= (1 << ${pin}));\n\t}\n\telsif ($conf =~ /^P(P|O)(|UP|DO)$/)\n\t{\n\t\tif ($STM32F1)\n\t\t{\n\t\t\t$MODER = ($1 eq 'O') ? 0x4 : 0x0;\n\t\t\t$MODER |= (($speed eq 'V') ? 0x03 : (($speed eq 'L') ? 0x2 : 0x1));\n\t\t\tif ($2 ne '')\n\t\t\t{\n\t\t\t\tprintf(STDERR \"WARNING: no output w/ pull-up/pull-down for F1 family %s\\n\", $line);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$MODER = 0x1;\n\t\t\t$OTYPER = ($1 eq 'O') ? 0x1 : 0x0;\n\t\t\t$$out{'OTYPER_H'} |= ($OTYPER << $pin);\n\t\t\t$$out{'OTYPER_L'} |= (($OTYPER ^ 0x1) << $pin);\n\t\t\t$PUPDR = ($2 eq 'UP') ? 0x1 : (($2 eq 'DO') ? 0x2 : 0x0);\n\t\t\t$$out{'PUPDR_H'} |= ($PUPDR << ($pin << 1));\n\t\t\t$$out{'PUPDR_L'} |= (($PUPDR ^ 0x3) << ($pin << 1));\n\t\t}\n\t\t($2 eq 'UP') && ($$out{'ODR_H'} |= (1 << ${pin}));\n\t\t($2 eq 'DO') && ($$out{'ODR_L'} |= (1 << ${pin}));\n\t}\n\telse\n\t{\n\t\tprintf(STDERR \"invalid conf %s\\n\", $line);\n\t\tnext;\n\t}\n\n\tif ($$out{'DEF'} & (1<< ${pin}))\n\t{\n\t\tprintf(STDERR \"redefinition: %s\\n\", $line);\n\t}\n\n\tif ($STM32F1)\n\t{\n\t\tif ($pin >= 8)\n\t\t{\n\t\t\t$$out{'CRH_H'} |= ($MODER << (($pin & 0x7) << 2));\n\t\t\t$$out{'CRH_L'} |= (($MODER ^ 0xF) << (($pin & 0x7) << 2));\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$$out{'CRL_H'} |= ($MODER << (($pin & 0x7) << 2));\n\t\t\t$$out{'CRL_L'} |= (($MODER ^ 0xF) << (($pin & 0x7) << 2));\n\t\t}\n\n\t\t$Exor = sprintf(\"0x%08X %2d\", ${GPIO_BASE} + (ord($port)  - ord('A')) * ${GPIO_OFFS} + ${GPIO_ODR}, $pin);\n\t\tmy $exor = 0xB << (($pin & 0x7) << 2);\n\t\t(($MODER & 0x3) == 0x0) && ($Exor .= sprintf(\" 0x%03X 0x%03X 0x%08X\",\n\t\t\t((($pin >= 8) ? ${GPIO_CRH} : ${GPIO_CRL})-${GPIO_ODR}) & 0x3FF,\n\t\t\t((($pin >= 8) ? ${GPIO_CRH} : ${GPIO_CRL})-${GPIO_ODR}) & 0x3FF, $exor));\n\t}\n\telse\n\t{\n\t\t$$out{'DEF'} |= (1 << ${pin});\n\t\t$$out{'MODER_H'} |= ($MODER << (${pin} << 1));\n\t\t$$out{'MODER_L'} |= (($MODER ^ 0x3) << (${pin} << 1));\n\n\t\t$OSPEEDR = (($speed eq 'V') ? 0x3 : (($speed eq 'H') ? 0x2 : (($speed eq 'M') ? 0x1 : 0x0)));\n\t\t$$out{'OSPEEDR_H'} |= ($OSPEEDR << (${pin} << 1));\n\t\t$$out{'OSPEEDR_L'} |= (($OSPEEDR ^ 0x3) << (${pin} << 1));\n\n\t\t$Exor = sprintf(\"0x%08X %2d\", ${GPIO_BASE} + (ord($port)  - ord('A')) * ${GPIO_OFFS} + ${GPIO_ODR}, $pin);\n\t\tmy $exor = (0x1 << ($pin << 1));\n\t\t($MODER == 0x0) && ($Exor .= sprintf(\" 0x%03X 0x%03X 0x%08X\", (${GPIO_MODER}-${GPIO_ODR}) & 0x3FF,\n\t\t\t(${GPIO_MODER}-${GPIO_ODR}) & 0x3FF, $exor));\n\t}\n\n\tpush(@{$Port[$num]}, sprintf(\"P%s%02d:%s:%s\", $port, $pin, $conf, $speed));\n\tpush(@Col, $Exor);\n}\n\nmy $Col = sprintf(\"${Sep}0x%03X \", (${GPIO_IDR}-${GPIO_ODR}) & 0x3FF);\nfor (my $i = 0; $i < @Col; $i++)\n{\n\tif (($i != 0) && (($i % 2) == 0))\n\t{\n\t\t(($i + 1) < @Col) && ($Col .= \"\\\\\\n${Sep}\");\n\t}\n\t$Col .= sprintf(\"%s \", $Col[$i]);\n}\nprintf(\"%s\\n\", $Col);\n\nmy @Col = ( );\nmy $Set;\nfor (my $i = 0; $i < @Out; $i++)\n{\n\tmy $out = $Out[$i];\n\tmy $addr = ${GPIO_BASE} + $i * ${GPIO_OFFS};\n\tmy $count = 0;\n\n\tif ($STM32F1)\n\t{\n\t\tif (($$out{'CRH_H'} | $$out{'CRH_L'} | $$out{'CRL_H'} | $$out{'CRL_L'} |\n\t\t\t\t$$out{'PUPDR_H'} | $$out{'PUPDR_L'}) != 0)\n\t\t{\n\t\t\tpush(@Col, sort({ $b cmp $a } @{$Port[$i]}));\n\n\t\t\t$Set .= sprintf(\"\\n%s# Port %s: %s\\n\", ${Sep}, chr($i + ord('A')),\n\t\t\t\tjoin(\", \", sort({ $b cmp $a } @{$Port[$i]})));\n\n\t\t\t(($$out{'CRL_H'} | $$out{'CRL_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}CRL\\n\", $addr + ${GPIO_CRL}, $$out{'CRL_H'}, $$out{'CRL_L'}));\n\n\t\t\t(($$out{'CRH_H'} | $$out{'CRH_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}CRH\\n\", $addr + ${GPIO_CRH}, $$out{'CRH_H'}, $$out{'CRH_L'}));\n\n\t\t\t(($$out{'ODR_H'} | $$out{'ODR_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}ODR/PUPDR\\n\", $addr + ${GPIO_ODR}, $$out{'ODR_H'}, $$out{'ODR_L'}));\n\t\t}\n\t}\n\telse\n\t{\n\t\tif (($$out{'MODER_H'} | $$out{'MODER_L'} |\n\t\t\t$$out{'OTYPER_H'} | $$out{'OTYPER_L'} |\n\t\t\t$$out{'OSPEEDR_H'} | $$out{'OSPEEDR_L'} |\n\t\t\t$$out{'PUPDR_H'} | $$out{'PUPDR_L'} |\n\t\t\t$$out{'ODR_H'} | $$out{'ODR_L'} |\n\t\t\t$$out{'AFRL_H'} | $$out{'AFRL_L'} |\n\t\t\t$$out{'AFRH_H'} | $$out{'AFRH_L'}) != 0)\n\t\t{\n\t\t\tpush(@Col, sort({ $b cmp $a } @{$Port[$i]}));\n\n\t\t\t$Set .= sprintf(\"%s# Port %s: %s\\n\", ${Sep}, chr($i + ord('A')),\n\t\t\t\tjoin(\", \", sort({ $b cmp $a } @{$Port[$i]})));\n\n\t\t\t(($$out{'MODER_H'} | $$out{'MODER_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}MODER\\n\", $addr + ${GPIO_MODER}, $$out{'MODER_H'}, $$out{'MODER_L'}));\n\n\t\t\t(($$out{'OTYPER_H'} | $$out{'OTYPER_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}OTYPER\\n\", $addr + ${GPIO_OTYPER}, $$out{'OTYPER_H'}, $$out{'OTYPER_L'}));\n\n\t\t\t(($$out{'OSPEEDR_H'} | $$out{'OSPEEDR_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}OSPEEDR\\n\", $addr + ${GPIO_OSPEEDR}, $$out{'OSPEEDR_H'}, $$out{'OSPEEDR_L'}));\n\n\t\t\t(($$out{'PUPDR_H'} | $$out{'PUPDR_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}PUPDR\\n\", $addr + ${GPIO_PUPDR}, $$out{'PUPDR_H'}, $$out{'PUPDR_L'}));\n\n\t\t\t(($$out{'ODR_H'} | $$out{'ODR_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}ODR\\n\", $addr + ${GPIO_ODR}, $$out{'ODR_H'}, $$out{'ODR_L'}));\n\n\t\t\t(($$out{'AFRL_H'} | $$out{'AFRL_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}AFRL\\n\", $addr + ${GPIO_AFRL}, $$out{'AFRL_H'}, $$out{'AFRL_L'}));\n\n\t\t\t(($$out{'AFRH_H'} | $$out{'AFRH_L'}) != 0) &&\n\t\t\t\t($Set .= sprintf(\"${Form}AFRH\\n\", $addr + ${GPIO_AFRH}, $$out{'AFRH_H'}, $$out{'AFRH_L'}));\n\t\t}\n\t}\n}\n\nmy $Col = '';\nfor (my $i = 0; $i < @Col; $i++)\n{\n\tif (($i % 6) == 0)\n\t{\n\t\tchop($Col);\n\t\t(($i + 1) < @Col) && ($Col .= \"\\n${Sep}#\");\n\t}\n\t$Col .= sprintf(\" %s,\", $Col[$i]);\n}\nchop($Col);\n#printf(\"\\n%s\\n\", $Pins);\nprintf(\"%s\\n\", $Col);\nprintf(\"%s\\n\", $Set);\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_crc32.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), crc32 (out)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - OCTOSPI io_base\n\n * Clobbered:\n * r4 - tmp\n * r5 - address of OCTOSPI_DR\n * r6 - address of OCTOSPI_CCR\n * r7 - tmp\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n#define OCTOSPI_CCR_CCR\t\t\t\t\t(OCTOSPI_CCR - OCTOSPI_CCR)\n#define OCTOSPI_TCR_CCR\t\t\t\t\t(OCTOSPI_TCR - OCTOSPI_CCR)\n#define OCTOSPI_IR_CCR\t\t\t\t\t(OCTOSPI_IR - OCTOSPI_CCR)\n\n\t.macro\toctospi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* get OCTOSPI CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #OCTOSPI_SR]\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #OCTOSPI_FCR]\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tmovs\tr4, #0x00\t\t\t\t\t/* initialize crc */\n\tmvns\tr4, r4\t\t\t\t\t\t/* to 0xFFFFFFFF */\nstart_read:\n\toctospi_abort\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #OCTOSPI_DR\t\t\t\t/* load OCTOSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of OCTOSPI_DR */\n\tmovs\tr6, #OCTOSPI_CCR-OCTOSPI_DR\t/* load OCTOSPI_CCR address offset */\n\tadds\tr6, r6, r5\t\t\t\t\t/* address of OCTOSPI_CCR */\n\twait_busy\n\tldr\t\tr7, cr_page_read\t\t\t/* indirect read mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then read to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else read all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #OCTOSPI_DLR]\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate transfer */\n\tldr\t\tr7, tcr_page_read\t\t\t/* TCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_page_read\t\t\t/* IR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tstr\t\tr2, [r3, #OCTOSPI_AR]\t\t/* store SPI start address */\n\tldr\t\tr6, =0x04C11DB7\t\t\t\t/* CRC32 polynomial */\nread_loop:\n\tldrb\tr7, [r5]\t\t\t\t\t/* read next byte from DR */\n\tlsls\tr7, r7, #24\t\t\t\t\t/* shift into msb */\n\teors\tr4, r4, r7\n\t.rept\t8\t\t\t\t\t\t\t/* unrolled bit loop */\n\tasrs\tr7, r4, #31\t\t\t\t\t/* copy bit 31 into bits 0 to 31 */\n\tands\tr7, r7, r6\t\t\t\t\t/* r7 neg. -> CRC32XOR, pos. -> 0x0 */\n\tlsls\tr4, r4, #1\t\t\t\t\t/* shift result */\n\teors\tr4, r4, r7\t\t\t\t\t/* eor by CRC32XOR or 0x0 */\n\t.endr\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\texit\t\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\tread_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tbal\t\tstart_read\t\t\t\t\t/* then next page */\n\t.pool\n\nexit:\n\tmvns\tr0, r4\t\t\t\t\t\t/* invert to get final result */\n\toctospi_abort\t\t\t\t\t\t/* to idle state */\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\ncr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for read command */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for read command */\ntcr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for read command */\nir_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for read command */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_crc32.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x00,0x24,0xe4,0x43,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,\n0x50,0x25,0xed,0x18,0xb0,0x26,0x76,0x19,0x1f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,\n0x5f,0x62,0x22,0x4f,0x1f,0x60,0x17,0x46,0x0f,0x43,0xbf,0x1a,0x87,0x42,0x00,0xd9,\n0x07,0x46,0x1f,0x64,0x1e,0x4f,0x37,0x60,0x1e,0x4f,0xb7,0x60,0x1e,0x4f,0x37,0x61,\n0x9a,0x64,0x15,0x4e,0x2f,0x78,0x3f,0x06,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,\n0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,\n0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,\n0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,\n0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0x01,0x32,0x01,0x38,0x05,0xd4,\n0x0a,0x42,0xd7,0xd1,0xb8,0xe7,0x00,0x00,0xb7,0x1d,0xc1,0x04,0xe0,0x43,0x02,0x25,\n0x1f,0x68,0x2f,0x43,0x1f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_erase_check.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - sector count\n * r1 - QSPI io_base\n\n * Clobbered:\n * r2 - r7 tmp */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n#define OCTOSPI_CCR_CCR\t\t\t\t\t(OCTOSPI_CCR - OCTOSPI_CCR)\n#define OCTOSPI_TCR_CCR\t\t\t\t\t(OCTOSPI_TCR - OCTOSPI_CCR)\n#define OCTOSPI_IR_CCR\t\t\t\t\t(OCTOSPI_IR - OCTOSPI_CCR)\n\n\t.macro\toctospi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r1, #OCTOSPI_CR]\t\t/* get OCTOSPI_CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r1, #OCTOSPI_CR]\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r1, #OCTOSPI_SR]\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r1, #OCTOSPI_FCR]\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tadr\t\tr2, buffer\t\t\t\t\t/* pointer to start of buffer */\n\tmovs\tr3, #OCTOSPI_DR\t\t\t\t/* load OCTOSPI_DR address offset */\n\tadds\tr3, r3, r1\t\t\t\t\t/* address of OCTOSPI_DR */\nsector_start:\n\toctospi_abort\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr6, #OCTOSPI_CCR-OCTOSPI_DR\t/* load OCTOSPI_CCR address offset */\n\tadds\tr6, r6, r3\t\t\t\t\t/* address of OCTOSPI_CCR */\n\twait_busy\n\tldr\t\tr7, cr_page_read\t\t\t/* indirect read mode */\n\tstr\t\tr7, [r1, #OCTOSPI_CR]\t\t/* set mode */\n\tldmia\tr2!, {r4, r5}\t\t\t\t/* load address offset, length */\n\tsubs\tr2, r2, #4\t\t\t\t\t/* point to length */\n\tsubs\tr5, r5, #1\t\t\t\t\t/* decrement sector length for DLR */\n\tstr\t\tr5, [r1, #OCTOSPI_DLR]\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate transfer */\n\tldr\t\tr7, tcr_page_read\t\t\t/* TCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_page_read\t\t\t/* IR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tstr\t\tr4, [r1, #OCTOSPI_AR]\t\t/* store SPI start address */\n\tldr\t\tr6, [r2, #4]\t\t\t\t/* load initial value */\nread_loop:\n\tldrb\tr4, [r3, #0]\t\t\t\t/* read next byte from DR */\n\tmovs\tr7, #0xFF\t\t\t\t\t/* fill bits 8-15 */\n\tlsls\tr7, r7, #8\t\t\t\t\t/* with ones */\n\torrs\tr4, r4, r7\t\t\t\t\t/* copy ones to left of read byte */\n\tands\tr6, r6, r4\t\t\t\t\t/* and read byte to result */\n\tlsls\tr4, r4, #8\t\t\t\t\t/* shift result into higher byte */\n\torrs\tr6, r6, r4\t\t\t\t\t/* or read byte to result */\n\tsubs\tr5, r5, #1\t\t\t\t\t/* decrement byte (count-1) */\n\tbpl\t\tread_loop\t\t\t\t\t/* again if sector not completed */\n\tadds\tr5, r5, #1\t\t\t\t\t/* increment count due to the -1 */\n\tstmia\tr2!, {r5, r6}\t\t\t\t/* save final count and result for sector */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement sector count */\n\tbne\t\tsector_start\t\t\t\t/* next sector? */\n\toctospi_abort\t\t\t\t\t\t/* to idle state */\n\nexit:\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\ncr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for read command */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for read command */\ntcr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for read command */\nir_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for read command */\n\n\t.equ buffer, .\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_erase_check.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x1b,0xa2,0x50,0x23,0x5b,0x18,0x02,0x25,0x0f,0x68,0x2f,0x43,0x0f,0x60,0xb0,0x26,\n0xf6,0x18,0x0f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,0x4f,0x62,0x10,0x4f,0x0f,0x60,\n0x30,0xca,0x04,0x3a,0x01,0x3d,0x0d,0x64,0x0e,0x4f,0x37,0x60,0x0e,0x4f,0xb7,0x60,\n0x0e,0x4f,0x37,0x61,0x8c,0x64,0x56,0x68,0x1c,0x78,0xff,0x27,0x3f,0x02,0x3c,0x43,\n0x26,0x40,0x24,0x02,0x26,0x43,0x01,0x3d,0xf6,0xd5,0x01,0x35,0x60,0xc2,0x01,0x38,\n0xd9,0xd1,0x02,0x25,0x0f,0x68,0x2f,0x43,0x0f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_read.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), remaining bytes (out, 0 means successful)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - OCTOSPI io_base\n * r8 - fifo start\n * r9 - fifo end + 1\n\n * Clobbered:\n * r4 - wp\n * r5 - address of OCTOSPI_DR\n * r6 - address of OCTOSPI_CCR\n * r7 - tmp\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n#define OCTOSPI_CCR_CCR\t\t\t\t\t(OCTOSPI_CCR - OCTOSPI_CCR)\n#define OCTOSPI_TCR_CCR\t\t\t\t\t(OCTOSPI_TCR - OCTOSPI_CCR)\n#define OCTOSPI_IR_CCR\t\t\t\t\t(OCTOSPI_IR - OCTOSPI_CCR)\n\n\t.macro\toctospi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* get OCTOSPI CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #OCTOSPI_SR]\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #OCTOSPI_FCR]\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tldr\t\tr4, wp\t\t\t\t\t\t/* load wp */\nstart_read:\n\toctospi_abort\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #OCTOSPI_DR\t\t\t\t/* load OCTOSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of OCTOSPI_DR */\n\tmovs\tr6, #OCTOSPI_CCR-OCTOSPI_DR\t/* load OCTOSPI_CCR address offset */\n\tadds\tr6, r6, r5\t\t\t\t\t/* address of OCTOSPI_CCR */\n\twait_busy\n\tldr\t\tr7, cr_page_read\t\t\t/* indirect read mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then write to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else write all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #OCTOSPI_DLR]\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate transfer */\n\tldr\t\tr7, tcr_page_read\t\t\t/* TCR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_page_read\t\t\t/* IR for read */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tstr\t\tr2, [r3, #OCTOSPI_AR]\t\t/* store SPI start address */\nread_loop:\n\tldrb\tr7, [r5]\t\t\t\t\t/* read next byte from DR */\n\tstrb\tr7, [r4, #0]\t\t\t\t/* write next byte */\n\tadds\tr4, r4, #1\t\t\t\t\t/* increment internal wp */\n\tcmp\t\tr4, r9\t\t\t\t\t\t/* internal wp beyond end? */\n\tblo\t\twait_fifo\t\t\t\t\t/* if no, then ok */\n\tmov\t\tr4, r8\t\t\t\t\t\t/* else wrap around */\nwait_fifo:\n\tldr\t\tr7, rp\t\t\t\t\t\t/* get rp */\n\tcmp\t\tr7, #0\t\t\t\t\t\t/* if rp equals 0 */\n\tbeq\t\texit\t\t\t\t\t\t/* then abort */\n\tcmp\t\tr4, r7\t\t\t\t\t\t/* check if fifo full */\n\tbeq\t\twait_fifo\t\t\t\t\t/* wait until not full */\n\tadr\t\tr7, wp\t\t\t\t\t\t/* get address of wp */\n\tstr\t\tr4, [r7]\t\t\t\t\t/* store updated wp */\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\texit\t\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\tread_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tbal\t\tstart_read\t\t\t\t\t/* then next page */\n\nexit:\n\tadds\tr0, r0, #1\t\t\t\t\t/* increment count due to the -1 */\n\toctospi_abort\t\t\t\t\t\t/* to idle state */\n\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\ncr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for read command */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for read command */\ntcr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for read command */\nir_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for read command */\n\n\t.equ wp, .\t\t\t\t\t\t\t/* wp, uint32_t */\n\t.equ rp, wp + 4\t\t\t\t\t\t/* rp, uint32_t */\n\t.equ buffer, rp + 4\t\t\t\t\t/* buffer follows right away */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_read.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x27,0x4c,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,0x50,0x25,\n0xed,0x18,0xb0,0x26,0x76,0x19,0x1f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,0x5f,0x62,\n0x1c,0x4f,0x1f,0x60,0x17,0x46,0x0f,0x43,0xbf,0x1a,0x87,0x42,0x00,0xd9,0x07,0x46,\n0x1f,0x64,0x19,0x4f,0x37,0x60,0x19,0x4f,0xb7,0x60,0x19,0x4f,0x37,0x61,0x9a,0x64,\n0x2f,0x78,0x27,0x70,0x01,0x34,0x4c,0x45,0x00,0xd3,0x44,0x46,0x16,0x4f,0x00,0x2f,\n0x09,0xd0,0xbc,0x42,0xfa,0xd0,0x13,0xa7,0x3c,0x60,0x01,0x32,0x01,0x38,0x02,0xd4,\n0x0a,0x42,0xed,0xd1,0xcf,0xe7,0x01,0x30,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,\n0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), remaining bytes (out, 0 means successful)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - OCTOSPI io_base\n * r8 - fifo start\n * r9 - fifo end + 1\n\n * Clobbered:\n * r4 - rp\n * r5 - address of OCTOSPI_DR\n * r6 - address of OCTOSPI_CCR\n * r7 - tmp\n * r10 - single 0x0 / dual 0x1\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n#define OCTOSPI_CCR_CCR\t\t\t\t\t(OCTOSPI_CCR - OCTOSPI_CCR)\n#define OCTOSPI_TCR_CCR\t\t\t\t\t(OCTOSPI_TCR - OCTOSPI_CCR)\n#define OCTOSPI_IR_CCR\t\t\t\t\t(OCTOSPI_IR - OCTOSPI_CCR)\n\n\t.macro\toctospi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* get OCTOSPI CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #OCTOSPI_SR]\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #OCTOSPI_FCR]\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tldr\t\tr4, rp\t\t\t\t\t\t/* load rp */\n\tldr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* get OCTOSPI_CR register */\n\tlsls\tr7, r7, #(31-SPI_DUAL_FLASH)\t/* clear higher order bits */\n\tlsrs\tr7, r7, #31\t\t\t\t\t/* DUAL_FLASH bit into bit 0 */\n\tmov\t\tr10, r7\t\t\t\t\t\t/* save in r10 */\nwip_loop:\n\toctospi_abort\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #OCTOSPI_DR\t\t\t\t/* load OCTOSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of OCTOSPI_DR */\n\tmovs\tr6, #OCTOSPI_CCR-OCTOSPI_DR\t/* load OCTOSPI_CCR address offset */\n\tadds\tr6, r6, r5\t\t\t\t\t/* address of OCTOSPI_CCR */\n\twait_busy\n\tldr\t\tr7, cr_read_status\t\t\t/* indirect read mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\tstr\t\tr7, [r3, #OCTOSPI_DLR]\t\t/* one or two (for dual) bytes */\n\tldr\t\tr7, ccr_read_status\t\t\t/* CCR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate status read */\n\tldr\t\tr7, tcr_read_status\t\t\t/* TCR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_read_status\t\t\t/* IR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tmovs\tr7, #0\t\t\t\t\t\t/* dummy address */\n\tstr\t\tr7, [r3, #OCTOSPI_AR]\t\t/* into AR (for 8-line mode) */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get first status register */\n\tlsrs\tr7, r7, #(SPIFLASH_BSY+1)\t/* if first flash busy, */\n\tbcs\t\twip_loop\t\t\t\t\t/* then poll again */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\ttst\t\tr7, r7\t\t\t\t\t\t/* dual mode ? */\n\tbeq\t\twrite_enable\t\t\t\t/* not dual, then ok */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get second status register */\n\tlsrs\tr7, r7, #(SPIFLASH_BSY+1)\t/* if second flash busy, */\n\tbcs\t\twip_loop\t\t\t\t\t/* then poll again */\nwrite_enable:\n\ttst\t\tr0, r0\t\t\t\t\t\t/* test residual count */\n\tbmi\t\texit\t\t\t\t\t\t/* if negative, then finished */\n\twait_busy\n\tldr\t\tr7, cr_write_enable\t\t\t/* indirect write mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tldr\t\tr7, ccr_write_enable\t\t/* CCR for write enable */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate write enable */\n\tldr\t\tr7, tcr_write_enable\t\t/* TCR for write enable */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* write enable instruction */\n\tldr\t\tr7, ir_write_enable\t\t\t/* IR for write enable */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tmovs\tr7, #0\t\t\t\t\t\t/* silicon bug in L5? dummy write */\n\tstr\t\tr7, [r3, #OCTOSPI_AR]\t\t/* into AR resolves issue */\n\twait_busy\n\tldr\t\tr7, cr_read_status\t\t\t/* indirect read mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual count */\n\tstr\t\tr7, [r3, #OCTOSPI_DLR]\t\t/* one or two (for dual) bytes */\n\tldr\t\tr7, ccr_read_status\t\t\t/* CCR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate status read */\n\tldr\t\tr7, tcr_read_status\t\t\t/* TCR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_read_status\t\t\t/* IR for status read */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tmovs\tr7, #0\t\t\t\t\t\t/* dummy address */\n\tstr\t\tr7, [r3, #OCTOSPI_AR]\t\t/* into AR (for 8-line mode) */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get first status register */\n\tlsrs\tr7, r7, #(SPIFLASH_WE+1)\t/* if first flash not */\n\tbcc\t\terror\t\t\t\t\t\t/* write enabled, then error */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\ttst\t\tr7, r7\t\t\t\t\t\t/* dual mode ? */\n\tbeq\t\tstart_write\t\t\t\t\t/* not dual, then ok */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get second status register */\n\tlsrs\tr7, r7, #(SPIFLASH_WE+1)\t/* if second flash not */\n\tbcc\t\terror\t\t\t\t\t\t/* write enabled, then error */\nstart_write:\n\twait_busy\n\tldr\t\tr7, cr_page_write\t\t\t/* indirect write mode */\n\tstr\t\tr7, [r3, #OCTOSPI_CR]\t\t/* set mode */\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then write to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else write all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #OCTOSPI_DLR]\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_write\t\t\t/* CCR for page write */\n\tstr\t\tr7, [r6, #OCTOSPI_CCR_CCR]\t/* initiate transfer */\n\tldr\t\tr7, tcr_page_write\t\t\t/* TCR for page write */\n\tstr\t\tr7, [r6, #OCTOSPI_TCR_CCR]\t/* instruction */\n\tldr\t\tr7, ir_page_write\t\t\t/* IR for page write */\n\tstr\t\tr7, [r6, #OCTOSPI_IR_CCR]\t/* instruction */\n\tstr\t\tr2, [r3, #OCTOSPI_AR]\t\t/* store SPI start address */\nwrite_loop:\n\tldr\t\tr7, wp\t\t\t\t\t\t/* get wp */\n\tcmp\t\tr7, #0\t\t\t\t\t\t/* if wp equals 0 */\n\tbeq\t\texit\t\t\t\t\t\t/* then abort */\n\tcmp\t\tr4, r7\t\t\t\t\t\t/* check if fifo empty */\n\tbeq\t\twrite_loop\t\t\t\t\t/* wait until not empty */\n\tldrb\tr7, [r4, #0]\t\t\t\t/* read next byte */\n\tstrb\tr7, [r5]\t\t\t\t\t/* write next byte to DR */\n\tadds\tr4, r4, #1\t\t\t\t\t/* increment internal rp */\n\tcmp\t\tr4, r9\t\t\t\t\t\t/* internal rp beyond end? */\n\tblo\t\tupd_write\t\t\t\t\t/* if no, then ok */\n\tmov\t\tr4, r8\t\t\t\t\t\t/* else wrap around */\nupd_write:\n\tadr\t\tr7, rp\t\t\t\t\t\t/* get address of rp */\n\tstr\t\tr4, [r7]\t\t\t\t\t/* store updated rp */\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\tpage_end\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\twrite_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tldr\t\tr7, [r3, #OCTOSPI_SR]\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_TCF+1)\t\t/* shift TCF into C */\n\tbcc\t\tpage_end\t\t\t\t\t/* loop until TCF set */\n\tbal\t\twip_loop\t\t\t\t\t/* then next page */\n\nerror:\n\tmovs\tr0, #0\t\t\t\t\t\t/* return 0xFFFFFFFF */\n\tsubs\tr0, r0, #2\t\t\t\t\t/* for error */\nexit:\n\tadds\tr0, r0, #1\t\t\t\t\t/* increment count due to the -1 */\n\toctospi_abort\t\t\t\t\t\t/* to idle state */\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\ncr_read_status:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for READ_STATUS command */\nccr_read_status:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for READ_STATUS command */\ntcr_read_status:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for READ_STATUS command */\nir_read_status:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for READ_STATUS command */\n\ncr_write_enable:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for WRITE_ENABLE command */\nccr_write_enable:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for WRITE_ENABLE command */\ntcr_write_enable:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for WRITE_ENABLE command */\nir_write_enable:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for WRITE_ENABLE command */\n\ncr_page_write:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CR value for PAGE_PROG command */\nccr_page_write:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_CCR value for PAGE_PROG command */\ntcr_page_write:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_TCR value for PAGE_PROG command */\nir_page_write:\n\t.space\t4\t\t\t\t\t\t\t/* OCTOSPI_IR value for PAGE_PROG command */\n\n\t.equ wp, .\t\t\t\t\t\t\t/* wp, uint32_t */\n\t.equ rp, wp + 4\t\t\t\t\t\t/* rp, uint32_t */\n\t.equ buffer, rp + 4\t\t\t\t\t/* buffer follows right away */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmoctospi_write.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x4f,0x4c,0x1f,0x68,0x7f,0x06,0xff,0x0f,0xba,0x46,0x02,0x25,\n0x1f,0x68,0x2f,0x43,0x1f,0x60,0x50,0x25,0xed,0x18,0xb0,0x26,0x76,0x19,0x1f,0x6a,\n0xbf,0x09,0xfc,0xd2,0x02,0x27,0x5f,0x62,0x39,0x4f,0x1f,0x60,0x57,0x46,0x1f,0x64,\n0x38,0x4f,0x37,0x60,0x38,0x4f,0xb7,0x60,0x38,0x4f,0x37,0x61,0x00,0x27,0x9f,0x64,\n0x2f,0x78,0x7f,0x08,0xe3,0xd2,0x57,0x46,0x3f,0x42,0x02,0xd0,0x2f,0x78,0x7f,0x08,\n0xdd,0xd2,0x00,0x42,0x55,0xd4,0x1f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,0x5f,0x62,\n0x2f,0x4f,0x1f,0x60,0x2f,0x4f,0x37,0x60,0x2f,0x4f,0xb7,0x60,0x2f,0x4f,0x37,0x61,\n0x00,0x27,0x9f,0x64,0x1f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,0x5f,0x62,0x24,0x4f,\n0x1f,0x60,0x57,0x46,0x1f,0x64,0x23,0x4f,0x37,0x60,0x23,0x4f,0xb7,0x60,0x23,0x4f,\n0x37,0x61,0x00,0x27,0x9f,0x64,0x2f,0x78,0xbf,0x08,0x30,0xd3,0x57,0x46,0x3f,0x42,\n0x02,0xd0,0x2f,0x78,0xbf,0x08,0x2a,0xd3,0x1f,0x6a,0xbf,0x09,0xfc,0xd2,0x02,0x27,\n0x5f,0x62,0x1f,0x4f,0x1f,0x60,0x17,0x46,0x0f,0x43,0xbf,0x1a,0x87,0x42,0x00,0xd9,\n0x07,0x46,0x1f,0x64,0x1b,0x4f,0x37,0x60,0x1b,0x4f,0xb7,0x60,0x1b,0x4f,0x37,0x61,\n0x9a,0x64,0x1b,0x4f,0x00,0x2f,0x14,0xd0,0xbc,0x42,0xfa,0xd0,0x27,0x78,0x2f,0x70,\n0x01,0x34,0x4c,0x45,0x00,0xd3,0x44,0x46,0x16,0xa7,0x3c,0x60,0x01,0x32,0x01,0x38,\n0x01,0xd4,0x0a,0x42,0xed,0xd1,0x1f,0x6a,0xbf,0x08,0xfc,0xd3,0x87,0xe7,0x00,0x20,\n0x02,0x38,0x01,0x30,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,0x00,0xbe,0xc0,0x46,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_crc32.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), crc32 (out)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - QSPI io_base\n\n * Clobbered:\n * r4 - rp\n * r5 - address of QSPI_DR\n * r7 - tmp\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n\t.macro\tqspi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #QSPI_CR]\t\t\t/* get QSPI_CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #QSPI_CR]\t\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #QSPI_FCR]\t\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tmovs\tr4, #0x00\t\t\t\t\t/* initialize crc */\n\tmvns\tr4, r4\t\t\t\t\t\t/* to 0xFFFFFFFF */\nstart_read:\n\tqspi_abort\t\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #QSPI_DR\t\t\t\t/* load QSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of QSPI_DR */\n\twait_busy\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then read to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else read all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #QSPI_DLR]\t\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for page read */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate transfer */\n\tstr\t\tr2, [r3, #QSPI_AR]\t\t\t/* store SPI start address */\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* wait for command startup */\n\tldr\t\tr6, =0x04C11DB7\t\t\t\t/* CRC32 polynomial */\nread_loop:\n\tldrb\tr7, [r5]\t\t\t\t\t/* read next byte from DR */\n\tlsls\tr7, r7, #24\t\t\t\t\t/* shift into msb */\n\teors\tr4, r4, r7\n\t.rept\t8\t\t\t\t\t\t\t/* unrolled bit loop */\n\tasrs\tr7, r4, #31\t\t\t\t\t/* copy bit 31 into bits 0 to 31 */\n\tands\tr7, r7, r6\t\t\t\t\t/* r7 neg. -> CRC32XOR, pos. -> 0x0 */\n\tlsls\tr4, r4, #1\t\t\t\t\t/* shift result */\n\teors\tr4, r4, r7\t\t\t\t\t/* eor by CRC32XOR or 0x0 */\n\t.endr\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\texit\t\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\tread_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tbal\t\tstart_read\t\t\t\t\t/* then next page */\n\t.pool\n\nexit:\n\tmvns\tr0, r4\t\t\t\t\t\t/* invert to get final result */\n\tqspi_abort\t\t\t\t\t\t\t/* to idle state */\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for read command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_crc32.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x00,0x24,0xe4,0x43,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,\n0x20,0x25,0xed,0x18,0x9f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,0xdf,0x60,0x17,0x46,\n0x0f,0x43,0xbf,0x1a,0x87,0x42,0x00,0xd9,0x07,0x46,0x1f,0x61,0x1c,0x4f,0x5f,0x61,\n0x9a,0x61,0x9f,0x68,0x14,0x4e,0x2f,0x78,0x3f,0x06,0x7c,0x40,0xe7,0x17,0x37,0x40,\n0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,\n0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,\n0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,\n0x64,0x00,0x7c,0x40,0xe7,0x17,0x37,0x40,0x64,0x00,0x7c,0x40,0x01,0x32,0x01,0x38,\n0x04,0xd4,0x0a,0x42,0xd7,0xd1,0xbf,0xe7,0xb7,0x1d,0xc1,0x04,0xe0,0x43,0x02,0x25,\n0x1f,0x68,0x2f,0x43,0x1f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_erase_check.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - sector count\n * r1 - QSPI io_base\n\n * Clobbered:\n * r2 - r7 tmp */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n\t.macro\tqspi_abort\n\tmovs\tr4, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r1, #QSPI_CR]\t\t\t/* get QSPI_CR register */\n\torrs\tr7, r7, r4\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r1, #QSPI_CR]\t\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r1, #QSPI_SR]\t\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r1, #QSPI_FCR]\t\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tadr\t\tr2, buffer\t\t\t\t\t/* pointer to start of buffer */\n\tmovs\tr3, #QSPI_DR\t\t\t\t/* load QSPI_DR address offset */\n\tadd\t\tr3, r3, r1\t\t\t\t\t/* address of QSPI_DR */\nsector_start:\n\tqspi_abort\t\t\t\t\t\t\t/* start in clean state */\n\tldmia\tr2!, {r4, r5, r6}\t\t\t/* load address offset, length, initial value */\n\tsubs\tr2, r2, #8\t\t\t\t\t/* point to length */\n\tsubs\tr5, r5, #1\t\t\t\t\t/* decrement sector length for DLR */\n\twait_busy\n\tstr\t\tr5, [r1, #QSPI_DLR]\t\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for page read */\n\tstr\t\tr7, [r1, #QSPI_CCR]\t\t\t/* initiate transfer */\n\tstr\t\tr4, [r1, #QSPI_AR]\t\t\t/* store SPI start address */\n\tldr\t\tr7, [r1, #QSPI_SR]\t\t\t/* wait for command startup */\nread_loop:\n\tldrb\tr4, [r3]\t\t\t\t\t/* read next byte from DR */\n\tmovs\tr7, #0xFF\t\t\t\t\t/* fill bits 8-15 */\n\tlsls\tr7, r7, #8\t\t\t\t\t/* with ones */\n\torrs\tr4, r4, r7\t\t\t\t\t/* copy ones to left of read byte */\n\tands\tr6, r6, r4\t\t\t\t\t/* and read byte to result */\n\tlsls\tr4, r4, #8\t\t\t\t\t/* shift result into higher byte */\n\torrs\tr6, r6, r4\t\t\t\t\t/* or read byte to result */\n\tsubs\tr5, r5, #1\t\t\t\t\t/* decrement byte (count-1) */\n\tbpl\t\tread_loop\t\t\t\t\t/* again if sector not completed */\n\tadds\tr5, r5, #1\t\t\t\t\t/* increment count due to the -1 */\n\tstmia\tr2!, {r5, r6}\t\t\t\t/* save final count and result for sector */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement sector count */\n\tbne\t\tsector_start\t\t\t\t/* next sector? */\n\tqspi_abort\t\t\t\t\t\t\t/* to idle state */\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for read command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.equ buffer, .\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_erase_check.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x17,0xa2,0x20,0x23,0x0b,0x44,0x02,0x24,0x0f,0x68,0x27,0x43,0x0f,0x60,0x70,0xca,\n0x08,0x3a,0x01,0x3d,0x8f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,0xcf,0x60,0x0d,0x61,\n0x0c,0x4f,0x4f,0x61,0x8c,0x61,0x8f,0x68,0x1c,0x78,0xff,0x27,0x3f,0x02,0x3c,0x43,\n0x26,0x40,0x24,0x02,0x26,0x43,0x01,0x3d,0xf6,0xd5,0x01,0x35,0x60,0xc2,0x01,0x38,\n0xe1,0xd1,0x02,0x24,0x0f,0x68,0x27,0x43,0x0f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_read.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), remaining bytes (out, 0 means successful)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - QSPI io_base\n * r8 - fifo start\n * r9 - fifo end + 1\n\n * Clobbered:\n * r4 - wp\n * r5 - address of QSPI_DR\n * r7 - tmp\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n\t.macro\tqspi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #QSPI_CR]\t\t\t/* get QSPI_CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #QSPI_CR]\t\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #QSPI_FCR]\t\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tldr\t\tr4, wp\t\t\t\t\t\t/* load wp */\nstart_read:\n\tqspi_abort\t\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #QSPI_DR\t\t\t\t/* load QSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of QSPI_DR */\n\twait_busy\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then read to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else read all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #QSPI_DLR]\t\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_read\t\t\t/* CCR for page read */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate transfer */\n\tstr\t\tr2, [r3, #QSPI_AR]\t\t\t/* store SPI start address */\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* wait for command startup */\nread_loop:\n\tldrb\tr7, [r5]\t\t\t\t\t/* read next byte from DR */\n\tstrb\tr7, [r4, #0]\t\t\t\t/* write next byte */\n\tadds\tr4, r4, #1\t\t\t\t\t/* increment internal wp */\n\tcmp\t\tr4, r9\t\t\t\t\t\t/* internal wp beyond end? */\n\tblo\t\twait_fifo\t\t\t\t\t/* if no, then ok */\n\tmov\t\tr4, r8\t\t\t\t\t\t/* else wrap around */\nwait_fifo:\n\tldr\t\tr7, rp\t\t\t\t\t\t/* get rp */\n\tcmp\t\tr7, #0\t\t\t\t\t\t/* if rp equals 0 */\n\tbeq\t\texit\t\t\t\t\t\t/* then abort */\n\tcmp\t\tr4, r7\t\t\t\t\t\t/* check if fifo full */\n\tbeq\t\twait_fifo\t\t\t\t\t/* wait until not full */\n\tadr\t\tr7, wp\t\t\t\t\t\t/* get address of wp */\n\tstr\t\tr4, [r7]\t\t\t\t\t/* store updated wp */\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\texit\t\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\tread_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tbal\t\tstart_read\t\t\t\t\t/* then next page */\n\nexit:\n\tadds\tr0, r0, #1\t\t\t\t\t/* increment count due to the -1 */\n\tqspi_abort\t\t\t\t\t\t\t/* to idle state */\n\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_page_read:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for read command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.equ wp, .\t\t\t\t\t\t\t/* wp, uint32_t */\n\t.equ rp, wp + 4\t\t\t\t\t\t/* rp, uint32_t */\n\t.equ buffer, rp + 4\t\t\t\t\t/* buffer follows right away */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_read.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x24,0x4c,0x02,0x25,0x1f,0x68,0x2f,0x43,0x1f,0x60,0x20,0x25,\n0xed,0x18,0x9f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,0xdf,0x60,0x17,0x46,0x0f,0x43,\n0xbf,0x1a,0x87,0x42,0x00,0xd9,0x07,0x46,0x1f,0x61,0x18,0x4f,0x5f,0x61,0x9a,0x61,\n0x9f,0x68,0x2f,0x78,0x27,0x70,0x01,0x34,0x4c,0x45,0x00,0xd3,0x44,0x46,0x17,0x4f,\n0x00,0x2f,0x09,0xd0,0xbc,0x42,0xfa,0xd0,0x13,0xa7,0x3c,0x60,0x01,0x32,0x01,0x38,\n0x02,0xd4,0x0a,0x42,0xed,0xd1,0xd6,0xe7,0x01,0x30,0x02,0x25,0x1f,0x68,0x2f,0x43,\n0x1f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 - 2018 by Andreas Bolsch                           *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n/* Params:\n * r0 - total count (bytes), remaining bytes (out, 0 means successful)\n * r1 - flash page size\n * r2 - address offset into flash\n * r3 - QSPI io_base\n * r8 - fifo start\n * r9 - fifo end + 1\n\n * Clobbered:\n * r4 - rp\n * r5 - address of QSPI_DR\n * r7 - tmp\n * r10 - single 0x0 / dual 0x1\n */\n\n#include \"../../../../src/flash/nor/stmqspi.h\"\n\n\t.macro\tqspi_abort\n\tmovs\tr5, #(1<<SPI_ABORT)\t\t\t/* abort bit mask */\n\tldr\t\tr7, [r3, #QSPI_CR]\t\t\t/* get QSPI_CR register */\n\torrs\tr7, r7, r5\t\t\t\t\t/* set abort bit */\n\tstr\t\tr7, [r3, #QSPI_CR]\t\t\t/* store new CR register */\n\t.endm\n\n\t.macro\twait_busy\n0:\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_BUSY+1)\t\t/* shift BUSY into C */\n\tbcs\t\t0b\t\t\t\t\t\t\t/* loop until BUSY cleared */\n\tmovs\tr7, #(1<<SPI_TCF)\t\t\t/* TCF bitmask */\n\tstr\t\tr7, [r3, #QSPI_FCR]\t\t\t/* clear TCF flag */\n\t.endm\n\nstart:\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement count for DLR */\n\tsubs\tr1, r1, #1\t\t\t\t\t/* page size mask and for DLR */\n\tldr\t\tr4, rp\t\t\t\t\t\t/* load rp */\n\tldr\t\tr7, [r3, #QSPI_CR]\t\t\t/* get QSPI_CR register */\n\tlsls\tr7, r7, #(31-SPI_DUAL_FLASH)\t/* clear higher order bits */\n\tlsrs\tr7, r7, #31\t\t\t\t\t/* DUAL_FLASH bit into bit 0 */\n\tmov\t\tr10, r7\t\t\t\t\t\t/* save in r10 */\nwip_loop:\n\tqspi_abort\t\t\t\t\t\t\t/* start in clean state */\n\tmovs\tr5, #QSPI_DR\t\t\t\t/* load QSPI_DR address offset */\n\tadds\tr5, r5, r3\t\t\t\t\t/* address of QSPI_DR */\n\twait_busy\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\tstr\t\tr7, [r3, #QSPI_DLR]\t\t\t/* one or two (for dual) bytes */\n\tldr\t\tr7, ccr_read_status\t\t\t/* CCR for status read */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate status read */\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* wait for command startup */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get first status register */\n\tlsrs\tr7, r7, #(SPIFLASH_BSY+1)\t/* if first flash busy, */\n\tbcs\t\twip_loop\t\t\t\t\t/* then poll again */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\ttst\t\tr7, r7\t\t\t\t\t\t/* dual mode ? */\n\tbeq\t\twrite_enable\t\t\t\t/* not dual, then ok */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get second status register */\n\tlsrs\tr7, r7, #(SPIFLASH_BSY+1)\t/* if second flash busy, */\n\tbcs\t\twip_loop\t\t\t\t\t/* then poll again */\nwrite_enable:\n\ttst\t\tr0, r0\t\t\t\t\t\t/* test residual count */\n\tbmi\t\texit\t\t\t\t\t\t/* if negative, then finished */\n\twait_busy\n\tldr\t\tr7, ccr_write_enable\t\t/* CCR for write enable */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate write enable */\n\twait_busy\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\tstr\t\tr7, [r3, #QSPI_DLR]\t\t\t/* one or two (for dual) bytes */\n\tldr\t\tr7, ccr_read_status\t\t\t/* CCR for status read */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate status read */\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* wait for command startup */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get first status register */\n\tlsrs\tr7, r7, #(SPIFLASH_WE+1)\t/* if first flash not */\n\tbcc\t\terror\t\t\t\t\t\t/* write enabled, then error */\n\tmov\t\tr7, r10\t\t\t\t\t\t/* get dual bit */\n\ttst\t\tr7, r7\t\t\t\t\t\t/* dual mode ? */\n\tbeq\t\tstart_write\t\t\t\t\t/* not dual, then ok */\n\tldrb\tr7, [r5]\t\t\t\t\t/* get second status register */\n\tlsrs\tr7, r7, #(SPIFLASH_WE+1)\t/* if second flash not */\n\tbcc\t\terror\t\t\t\t\t\t/* write enabled, then error */\nstart_write:\n\twait_busy\n\tmov\t\tr7, r2\t\t\t\t\t\t/* get current start address */\n\torrs\tr7, r7, r1\t\t\t\t\t/* end of current page */\n\tsubs\tr7, r7, r2\t\t\t\t\t/* count-1 to end of page */\n\tcmp\t\tr7, r0\t\t\t\t\t\t/* if this count <= remaining */\n\tbls\t\twrite_dlr\t\t\t\t\t/* then write to end of page */\n\tmov\t\tr7, r0\t\t\t\t\t\t/* else write all remaining */\nwrite_dlr:\n\tstr\t\tr7, [r3, #QSPI_DLR]\t\t\t/* size-1 in DLR register */\n\tldr\t\tr7, ccr_page_write\t\t\t/* CCR for page write */\n\tstr\t\tr7, [r3, #QSPI_CCR]\t\t\t/* initiate transfer */\n\tstr\t\tr2, [r3, #QSPI_AR]\t\t\t/* store SPI start address */\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* wait for command startup */\nwrite_loop:\n\tldr\t\tr7, wp\t\t\t\t\t\t/* get wp */\n\tcmp\t\tr7, #0\t\t\t\t\t\t/* if wp equals 0 */\n\tbeq\t\texit\t\t\t\t\t\t/* then abort */\n\tcmp\t\tr4, r7\t\t\t\t\t\t/* check if fifo empty */\n\tbeq\t\twrite_loop\t\t\t\t\t/* wait until not empty */\n\tldrb\tr7, [r4, #0]\t\t\t\t/* read next byte */\n\tstrb\tr7, [r5]\t\t\t\t\t/* write next byte to DR */\n\tadds\tr4, r4, #1\t\t\t\t\t/* increment internal rp */\n\tcmp\t\tr4, r9\t\t\t\t\t\t/* internal rp beyond end? */\n\tblo\t\tupd_write\t\t\t\t\t/* if no, then ok */\n\tmov\t\tr4, r8\t\t\t\t\t\t/* else wrap around */\nupd_write:\n\tadr\t\tr7, rp\t\t\t\t\t\t/* get address of rp */\n\tstr\t\tr4, [r7]\t\t\t\t\t/* store updated rp */\n\tadds\tr2, r2, #1\t\t\t\t\t/* increment address */\n\tsubs\tr0, r0, #1\t\t\t\t\t/* decrement (count-1) */\n\tbmi\t\tpage_end\t\t\t\t\t/* stop if no data left */\n\ttst\t\tr2, r1\t\t\t\t\t\t/* page end ? */\n\tbne\t\twrite_loop\t\t\t\t\t/* if not, then next byte */\npage_end:\n\tldr\t\tr7, [r3, #QSPI_SR]\t\t\t/* load status */\n\tlsrs\tr7, r7, #(SPI_TCF+1)\t\t/* shift TCF into C */\n\tbcc\t\tpage_end\t\t\t\t\t/* loop until TCF set */\n\tbal\t\twip_loop\t\t\t\t\t/* then next page */\n\nerror:\n\tmovs\tr0, #0\t\t\t\t\t\t/* return 0xFFFFFFFF */\n\tsubs\tr0, r0, #2\t\t\t\t\t/* for error */\nexit:\n\tadds\tr0, r0, #1\t\t\t\t\t/* increment count due to the -1 */\n\tqspi_abort\t\t\t\t\t\t\t/* to idle state */\n\n\t.align\t2\t\t\t\t\t\t\t/* align to word, bkpt is 4 words */\n\tbkpt\t#0\t\t\t\t\t\t\t/* before code end for exit_point */\n\t.align\t2\t\t\t\t\t\t\t/* align to word */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_read_status:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for READ_STATUS command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_write_enable:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for WRITE_ENABLE command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.space\t4\t\t\t\t\t\t\t/* not used */\nccr_page_write:\n\t.space\t4\t\t\t\t\t\t\t/* QSPI_CCR value for PAGE_PROG command */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\t.space\t4\t\t\t\t\t\t\t/* not used */\n\n\t.equ wp, .\t\t\t\t\t\t\t/* wp, uint32_t */\n\t.equ rp, wp + 4\t\t\t\t\t\t/* rp, uint32_t */\n\t.equ buffer, rp + 4\t\t\t\t\t/* buffer follows right away */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/stmqspi/stmqspi_write.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x01,0x38,0x01,0x39,0x41,0x4c,0x1f,0x68,0x7f,0x06,0xff,0x0f,0xba,0x46,0x02,0x25,\n0x1f,0x68,0x2f,0x43,0x1f,0x60,0x20,0x25,0xed,0x18,0x9f,0x68,0xbf,0x09,0xfc,0xd2,\n0x02,0x27,0xdf,0x60,0x57,0x46,0x1f,0x61,0x2c,0x4f,0x5f,0x61,0x9f,0x68,0x2f,0x78,\n0x7f,0x08,0xec,0xd2,0x57,0x46,0x3f,0x42,0x02,0xd0,0x2f,0x78,0x7f,0x08,0xe6,0xd2,\n0x00,0x42,0x41,0xd4,0x9f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,0xdf,0x60,0x27,0x4f,\n0x5f,0x61,0x9f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,0xdf,0x60,0x57,0x46,0x1f,0x61,\n0x1e,0x4f,0x5f,0x61,0x9f,0x68,0x2f,0x78,0xbf,0x08,0x2b,0xd3,0x57,0x46,0x3f,0x42,\n0x02,0xd0,0x2f,0x78,0xbf,0x08,0x25,0xd3,0x9f,0x68,0xbf,0x09,0xfc,0xd2,0x02,0x27,\n0xdf,0x60,0x17,0x46,0x0f,0x43,0xbf,0x1a,0x87,0x42,0x00,0xd9,0x07,0x46,0x1f,0x61,\n0x1a,0x4f,0x5f,0x61,0x9a,0x61,0x9f,0x68,0x1b,0x4f,0x00,0x2f,0x14,0xd0,0xbc,0x42,\n0xfa,0xd0,0x27,0x78,0x2f,0x70,0x01,0x34,0x4c,0x45,0x00,0xd3,0x44,0x46,0x17,0xa7,\n0x3c,0x60,0x01,0x32,0x01,0x38,0x01,0xd4,0x0a,0x42,0xed,0xd1,0x9f,0x68,0xbf,0x08,\n0xfc,0xd3,0xa4,0xe7,0x00,0x20,0x02,0x38,0x01,0x30,0x02,0x25,0x1f,0x68,0x2f,0x43,\n0x1f,0x60,0xc0,0x46,0x00,0xbe,0xc0,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/str7x.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv4t\n\n\t.section .init\n/*\n\tr0 source address\n\tr1 address\n\tr2 FLASH_CR0\n\tr3 dword count\n\tr4 result\n\tr5 busy mask\n*/\n\nwrite:\n\tmov\t\tr4, #0x10000000\t\t\t/* set DWPG bit */\n\tstr\t\tr4, [r2, #0x0]\t\t\t/* FLASH_CR0 */\n\tstr\t\tr1, [r2, #0x10]\t\t\t/* FLASH_AR */\n\tldr\t\tr4, [r0], #4\t\t\t/* load data */\n\tstr\t\tr4, [r2, #0x8]\t\t\t/* FLASH_DR0 */\n\tldr\t\tr4, [r0], #4\t\t\t/* load data */\n\tstr\t\tr4, [r2, #0xc]\t\t\t/* FLASH_DR1 */\n\tmov\t\tr4, #0x90000000\t\t\t/* set DWPG and WMS bits */\n\tstr\t\tr4, [r2, #0x0]\t\t\t/* FLASH_CR0 */\nbusy:\n\tldr\t\tr4, [r2, #0x0]\t\t\t/* FLASH_CR0 */\n\ttst\t\tr4, r5\n\tbne\t\tbusy\n\tldr\t\tr4, [r2, #0x14]\t\t\t/* FLASH_ER */\n\ttst\t\tr4, #0xff\t\t\t\t/* do we have errors */\n\ttsteq\tr4, #0x100\t\t\t/* write protection set */\n\tbne\t\texit\n\tadd\t\tr1, r1, #0x8\t\t\t/* next 8 bytes */\n\tsubs\tr3, r3, #1\t\t\t\t/* decrement dword count */\n\tbne\t\twrite\nexit:\n\tb\t\texit\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/str9x.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n\t.text\n\t.arm\n\t.arch armv5t\n\n\t.section .init\n/*\n\tr0 source address (in)\n\tr1 target address (in)\n\tr2 word count (in)\n\tr3 result (out)\n*/\n\nwrite:\n\tbic\t\tr4, r1, #3\t\t\t/* word address */\n\tmov\t\tr3, #0x40\t\t\t/* write command */\n\tstrh\tr3, [r4, #0]\n\tldrh \tr3, [r0], #2\t\t/* read data */\n\tstrh\tr3, [r1], #2\t\t/* write data */\n\tmov\t\tr3, #0x70\t\t\t/* status command */\n\tstrh\tr3, [r4, #0]\nbusy:\n\tldrb\tr3, [r4, #0]\t\t/* status */\n\ttst \tr3, #0x80\n\tbeq \tbusy\n\tmov\t\tr5, #0x50\t\t\t/* clear status command */\n\tstrh\tr5, [r4, #0]\n\tmov\t\tr5, #0xFF\t\t\t/* read array */\n\tstrh\tr5, [r4, #0]\n\ttst\t\tr3, #0x12\n\tbne\t\texit\n\tsubs \tr2, r2, #1\t\t\t/* decrement word count */\n\tbne \twrite\nexit:\n\tbkpt\t#0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/erase.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Infineon XMC1000 flash sectors erase\n *\n * Copyright (c) 2016 Andreas Färber\n *\n * Based on XMC1100 AA-Step Reference Manual\n */\n\n#include \"xmc1xxx.S\"\n\n#define DUMMY_VALUE 0x42\n\n\t.macro erase_page, nvmbase, addr, tmp, tmp2\n\n\tmovs\t\\tmp, #DUMMY_VALUE\n\tstr\t\\tmp, [\\addr]\n\n\tbusy_wait \\nvmbase, \\tmp, \\tmp2\n\n\t.endm\n\n\n\t.macro erase, nvmbase, addr, end, tmp, tmp2\n\n\tmovs\t\\tmp, #NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n2001:\n\terase_page \\nvmbase, \\addr, \\tmp, \\tmp2\n\n\tmovs\t\\tmp, #(NVM_PAGE_SIZE - 1)\n\tadds\t\\tmp, \\tmp, #1\n\tadd\t\\addr, \\addr, \\tmp\n\tcmp\t\\addr, \\end\n\tblt\t2001b\n\n\tmovs\t\\tmp, #NVMPROG_ACTION_IDLE\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n\n\t.endm\n\n\n\t/*\n\t * r0 = 0x40050000\n\t * r1 = e.g. 0x10001000\n\t * r2 = e.g. 0x10011000\n\t * NVMPROG.ACTION = 0x00\n\t */\nerase:\n\terase r0, r1, r2, r3, r4\n\n\tbkpt\t#0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/erase.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xa2,0x23,0x83,0x80,0x42,0x23,0x0b,0x60,0x03,0x88,0x01,0x24,0x23,0x40,0xa3,0x42,\n0xfa,0xd0,0xff,0x23,0x01,0x33,0x19,0x44,0x91,0x42,0xf3,0xdb,0x00,0x23,0x83,0x80,\n0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/erase_check.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Infineon XMC1000 flash sector erase check\n *\n * Copyright (c) 2016 Andreas Färber\n *\n * Based on XMC1100 AA-Step Reference Manual\n */\n\n#include \"xmc1xxx.S\"\n\n\t.macro verify_block, nvmbase, addr, tmp, tmp2\n\n\tmovs\t\\tmp, #0x00\n\tmvns\t\\tmp, \\tmp\n\tstr\t\\tmp, [\\addr, #0x0]\n\tstr\t\\tmp, [\\addr, #0x4]\n\tstr\t\\tmp, [\\addr, #0x8]\n\tstr\t\\tmp, [\\addr, #0xC]\n\n\tbusy_wait \\nvmbase, \\tmp, \\tmp2\n\n\t.endm\n\n\n\t.macro erase_check, nvmbase, addr, end, tmp, tmp2\n\n\tldrh\t\\tmp, [\\nvmbase, #NVMCONF]\n\tmovs\t\\tmp2, #NVMCONF_HRLEV_MASK\n\tmvns\t\\tmp2, \\tmp2\n\tands\t\\tmp, \\tmp, \\tmp2\n\tmovs\t\\tmp2, #NVMCONF_HRLEV_HRE\n\torrs\t\\tmp, \\tmp, \\tmp2\n\tstrh\t\\tmp, [\\nvmbase, #NVMCONF]\n\n\tmovs\t\\tmp, #NVMPROG_ACTION_VERIFY_CONTINUOUS\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n2001:\n\tverify_block \\nvmbase, \\addr, \\tmp, \\tmp2\n\n\tldrh\t\\tmp, [\\nvmbase, #NVMSTATUS]\n\tmovs\t\\tmp2, #NVMSTATUS_VERR_MASK\n\tands\t\\tmp, \\tmp, \\tmp2\n\tcmp\t\\tmp, #NVMSTATUS_VERR_NOFAIL\n\tbne\t2010f\n\n\tadds\t\\addr, \\addr, #NVM_BLOCK_SIZE\n\tcmp\t\\addr, \\end\n\tblt\t2001b\n2010:\n\tmovs\t\\tmp, #NVMPROG_ACTION_IDLE\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n\n\t.endm\n\n\n\t/*\n\t * r0 = 0x40050000\n\t * r1 = e.g. 0x10001000\n\t * r2 = e.g. 0x10002000\n\t * NVMPROG.ACTION = 0x00\n\t */\nerase_check:\n\terase_check r0, r1, r2, r3, r4\n\n\tbkpt\t#0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/erase_check.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0x03,0x89,0x06,0x24,0xe4,0x43,0x23,0x40,0x04,0x24,0x23,0x43,0x03,0x81,0xe0,0x23,\n0x83,0x80,0x00,0x23,0xdb,0x43,0x0b,0x60,0x4b,0x60,0x8b,0x60,0xcb,0x60,0x03,0x88,\n0x01,0x24,0x23,0x40,0xa3,0x42,0xfa,0xd0,0x03,0x88,0x0c,0x24,0x23,0x40,0x00,0x2b,\n0x02,0xd1,0x10,0x31,0x91,0x42,0xec,0xdb,0x00,0x23,0x83,0x80,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/write.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Infineon XMC1000 flash write\n *\n * Copyright (c) 2016 Andreas Färber\n *\n * Based on XMC1100 AA-Step Reference Manual\n */\n\n#include \"xmc1xxx.S\"\n\n\t.macro write_block, nvmbase, dest, src, tmp, tmp2\n\n\tldr\t\\tmp, [\\src,  #0x0]\n\tstr\t\\tmp, [\\dest, #0x0]\n\tldr\t\\tmp, [\\src,  #0x4]\n\tstr\t\\tmp, [\\dest, #0x4]\n\tldr\t\\tmp, [\\src,  #0x8]\n\tstr\t\\tmp, [\\dest, #0x8]\n\tldr\t\\tmp, [\\src,  #0xc]\n\tstr\t\\tmp, [\\dest, #0xc]\n\n\tbusy_wait \\nvmbase, \\tmp, \\tmp2\n\n\t.endm\n\n\n\t.macro write, nvmbase, dest, src, count, tmp, tmp2\n\n\tmovs\t\\tmp, #NVMPROG_ACTION_WRITE_CONTINUOUS\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n1001:\n\twrite_block \\nvmbase, \\dest, \\src, \\tmp, \\tmp2\n\n\tadds\t\\dest, \\dest, #NVM_BLOCK_SIZE\n\tadds\t\\src, \\src, #NVM_BLOCK_SIZE\n\tsubs\t\\count, \\count, #1\n\tcmp\t\\count, #0\n\tbgt\t1001b\n\n\tmovs\t\\tmp, #NVMPROG_ACTION_IDLE\n\tstrh\t\\tmp, [\\nvmbase, #NVMPROG]\n\n\t.endm\n\n\n\t/*\n\t * r0 = 0x40050000\n\t * r1 = e.g. 0x10001000\n\t * r2 = e.g. 0x20000000\n\t * r3 = e.g. 1\n\t * NVMPROG.ACTION = 0x00\n\t */\nwrite:\n\twrite r0, r1, r2, r3, r4, r5\n\n\tbkpt\t#0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/write.inc",
    "content": "/* Autogenerated with ../../../../src/helper/bin2char.sh */\n0xa1,0x24,0x84,0x80,0x14,0x68,0x0c,0x60,0x54,0x68,0x4c,0x60,0x94,0x68,0x8c,0x60,\n0xd4,0x68,0xcc,0x60,0x04,0x88,0x01,0x25,0x2c,0x40,0xac,0x42,0xfa,0xd0,0x10,0x31,\n0x10,0x32,0x01,0x3b,0x00,0x2b,0xed,0xdc,0x00,0x24,0x84,0x80,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/flash/xmc1xxx/xmc1xxx.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Infineon XMC1000 flash\n *\n * Copyright (c) 2016 Andreas Färber\n *\n * Based on XMC1100 AA-Step Reference Manual\n */\n\n\t.text\n\t.syntax unified\n\t.cpu cortex-m0\n\t.thumb\n\t.thumb_func\n\n#define NVMSTATUS\t0x00\n#define NVMPROG\t\t0x04\n#define NVMCONF\t\t0x08\n\n#define NVMSTATUS_BUSY\t\t(1 << 0)\n#define NVMSTATUS_VERR_NOFAIL\t(0x0 << 2)\n#define NVMSTATUS_VERR_MASK\t(0x3 << 2)\n\n#define NVMPROG_ACTION_IDLE\t\t\t0x00\n#define NVMPROG_ACTION_WRITE_CONTINUOUS\t\t0xA1\n#define NVMPROG_ACTION_PAGE_ERASE_CONTINUOUS\t0xA2\n#define NVMPROG_ACTION_VERIFY_CONTINUOUS\t0xE0\n\n#define NVMCONF_HRLEV_NR\t(0x0 << 1)\n#define NVMCONF_HRLEV_HRE\t(0x2 << 1)\n#define NVMCONF_HRLEV_MASK\t(0x3 << 1)\n\n#define NVM_WORD_SIZE\t4\n#define NVM_BLOCK_SIZE\t(4 * NVM_WORD_SIZE)\n#define NVM_PAGE_SIZE\t(16 * NVM_BLOCK_SIZE)\n\n\t.macro busy_wait, nvmbase, tmp, tmp2\n1:\n\tldrh\t\\tmp, [\\nvmbase, #NVMSTATUS]\n\tmovs\t\\tmp2, #NVMSTATUS_BUSY\n\tands\t\\tmp, \\tmp, \\tmp2\n\tcmp\t\\tmp, \\tmp2\n\tbeq\t1b\n\n\t.endm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/reset/espressif/common.mk",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ESP32 Makefile to compile the SoC reset program\n# Copyright (C) 2022 Espressif Systems Ltd.\n\n# Pass V=1 to see the commands being executed by make\nifneq (\"$(V)\",\"1\")\nQ = @\nendif\n\nBIN2C = ../../../../../src/helper/bin2char.sh\n\nAPP = cpu_reset_handler\n\nBUILD_DIR = build\n\nAPP_OBJ = $(BUILD_DIR)/$(APP).o\nAPP_BIN = $(BUILD_DIR)/$(APP)_code.bin\nAPP_CODE = $(APP)_code.inc\n\nCFLAGS += -mtext-section-literals\n\n.PHONY: all cleanxten\n\nall: $(BUILD_DIR) $(APP_OBJ) $(APP_CODE)\n\n$(BUILD_DIR):\n\t$(Q) mkdir $@\n\n$(APP_OBJ): $(SRCS)\n\t@echo \"  CC   $^ -> $@\"\n\t$(Q) $(CROSS)gcc -c $(CFLAGS)  -o $@ $^\n\n$(APP_CODE): $(APP_OBJ)\n\t@echo \"  CC   $^ -> $@\"\n\t$(Q) $(CROSS)objcopy -O binary -j.text $^ $(APP_BIN)\n\t$(Q) $(BIN2C) < $(APP_BIN) > $@\n\nclean:\n\t$(Q) rm -rf $(BUILD_DIR)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc",
    "content": "/* Autogenerated with ../../../../../src/helper/bin2char.sh */\n0x06,0x1e,0x00,0x00,0x06,0x14,0x00,0x00,0x34,0x80,0xf4,0x3f,0xb0,0x80,0xf4,0x3f,\n0xb4,0x80,0xf4,0x3f,0x70,0x80,0xf4,0x3f,0x10,0x22,0x00,0x00,0x00,0x20,0x49,0x9c,\n0x00,0x80,0xf4,0x3f,0xa1,0x3a,0xd8,0x50,0xa4,0x80,0xf4,0x3f,0x64,0xf0,0xf5,0x3f,\n0x64,0x00,0xf6,0x3f,0x8c,0x80,0xf4,0x3f,0x48,0xf0,0xf5,0x3f,0x48,0x00,0xf6,0x3f,\n0xfc,0xa1,0xf5,0x3f,0x38,0x00,0xf0,0x3f,0x30,0x00,0xf0,0x3f,0x2c,0x00,0xf0,0x3f,\n0x34,0x80,0xf4,0x3f,0x00,0x30,0x00,0x00,0x50,0x55,0x30,0x41,0xeb,0xff,0x59,0x04,\n0x41,0xeb,0xff,0x59,0x04,0x41,0xea,0xff,0x59,0x04,0x41,0xea,0xff,0x31,0xea,0xff,\n0x39,0x04,0x31,0xea,0xff,0x41,0xea,0xff,0x39,0x04,0x00,0x00,0x60,0xeb,0x03,0x60,\n0x61,0x04,0x56,0x66,0x04,0x50,0x55,0x30,0x31,0xe7,0xff,0x41,0xe7,0xff,0x39,0x04,\n0x41,0xe7,0xff,0x39,0x04,0x41,0xe6,0xff,0x39,0x04,0x41,0xe6,0xff,0x59,0x04,0x41,\n0xe6,0xff,0x59,0x04,0x41,0xe6,0xff,0x59,0x04,0x41,0xe5,0xff,0x59,0x04,0x41,0xe5,\n0xff,0x59,0x04,0x41,0xe5,0xff,0x0c,0x13,0x39,0x04,0x41,0xe4,0xff,0x0c,0x13,0x39,\n0x04,0x59,0x04,0x41,0xe3,0xff,0x31,0xe3,0xff,0x32,0x64,0x00,0x00,0x70,0x00,0x46,\n0xfe,0xff,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/reset/espressif/esp32/esp32_cpu_reset_handler.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Reset stub used by esp32 target                                       *\n *   Copyright (C) 2017 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#define RTC_CNTL_RESET_STATE_REG    0x3ff48034\n#define RTC_CNTL_RESET_STATE_DEF    0x3000\n#define RTC_CNTL_CLK_CONF_REG       0x3ff48070\n#define RTC_CNTL_CLK_CONF_DEF       0x2210\n#define RTC_CNTL_STORE4_REG         0x3ff480b0\n#define RTC_CNTL_STORE5_REG         0x3ff480b4\n#define WDT_WKEY_VALUE              0x50D83AA1\n#define TIMG0_WDTWPROTECT_REG       0x3ff5f064\n#define TIMG0_WDTCONFIG0_REG        0x3ff5f048\n#define TIMG1_WDTWPROTECT_REG       0x3FF60064\n#define TIMG1_WDTCONFIG0_REG        0x3ff60048\n#define RTC_CNTL_WDTCONFIG0_REG     0x3ff4808c\n#define RTC_CNTL_WDTWPROTECT_REG    0x3ff480a4\n#define JTAG_ENABLE_REG             0x3ff5a1fc\n#define RTC_CNTL_OPTIONS0_REG       0x3ff48000\n#define RTC_CNTL_OPTIONS0_DEF       0x1c492000\n#define RTC_CNTL_SW_SYS_RST         0x80000000\n#define DPORT_APPCPU_CTRL_A_REG     0x3ff0002c\n#define DPORT_APPCPU_RST_EN         0x1\n#define DPORT_APPCPU_CTRL_B_REG     0x3ff00030\n#define DPORT_APPCPU_CLKGATE_EN     0x1\n#define DPORT_APPCPU_CTRL_C_REG     0x3ff00034\n#define DPORT_APPCPU_CTRL_D_REG     0x3ff00038\n\n\n/* This stub is copied to RTC_SLOW_MEM by OpenOCD, and the CPU starts executing\n * it instead of the ROM code (0x40000400). This stub disables watchdogs and\n * goes into a loop.\n * OpenOCD will then halt the target and perform CPU reset using OCD.\n */\n\n\n/* Has to be at offset 0. This is the entry point of the CPU, once\n * RTC_CNTL_PROCPU_STAT_VECTOR_SEL is cleared.\n * CPU will come here after the system reset, triggered by RTC_CNTL_SW_SYS_RST.\n */\n    .global     cpu_at_start_handler\n    .type       cpu_at_start_handler,@function\n    .align      4\ncpu_at_start_handler:\n    j start\n\n\n/* Has to be at offset 4. Once the stub code has been uploaded into RTC Slow\n * memory, OpenOCD will set the PC to this address, and resume execution.\n * The stub will then jump to 'reset' label and perform the reset.\n */\n    .global     cpu_reset_handler\n    .type       cpu_reset_handler,@function\n    .align      4\ncpu_reset_handler:\n    j reset\n\n    .align 4\n    .literal_position\n\n    .align 4\nreset:\n    /* Use a5 as a zero register */\n    xor a5, a5, a5\n    /* Select static reset vector 0 (XCHAL_RESET_VECTOR0_VADDR, 0x50000000) */\n    movi a4, RTC_CNTL_RESET_STATE_REG\n    s32i a5, a4, 0\n    /* Set some clock-related RTC registers to the default values */\n    movi a4, RTC_CNTL_STORE4_REG\n    s32i a5, a4, 0\n    movi a4, RTC_CNTL_STORE5_REG\n    s32i a5, a4, 0\n    movi a4, RTC_CNTL_CLK_CONF_REG\n    movi a3, RTC_CNTL_CLK_CONF_DEF\n    s32i a3, a4, 0\n    /* Reset the digital part of the chip (RTC controller doesn't get reset) */\n    movi a3, (RTC_CNTL_OPTIONS0_DEF | RTC_CNTL_SW_SYS_RST)\n    movi a4, RTC_CNTL_OPTIONS0_REG\n    s32i a3, a4, 0\n    /* Doesn't reach beyond this instruction */\n\n    .align 4\nstart:\n    /* If running on the APP CPU, skip directly to the parking loop */\n    rsr.prid a6\n    extui a6, a6, 1, 1\n    bnez a6, parking_loop\n\n    /* Use a5 as a zero register */\n    xor a5, a5, a5\n    /* Disable the watchdogs */\n    movi a3, WDT_WKEY_VALUE\n    movi a4, RTC_CNTL_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, TIMG0_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, TIMG1_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, RTC_CNTL_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    movi a4, TIMG0_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    movi a4, TIMG1_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    /* Enable JTAG (needed since rev. 3) */\n    movi a4, JTAG_ENABLE_REG\n    s32i.n a5, a4, 0\n    /* Clear APP_CPU boot address */\n    movi a4, DPORT_APPCPU_CTRL_D_REG\n    s32i.n a5, a4, 0\n    /* Clear APP_CPU clock gating */\n    movi a4, DPORT_APPCPU_CTRL_B_REG\n    movi a3, DPORT_APPCPU_CLKGATE_EN\n    s32i.n a3, a4, 0\n    /* Set and clear APP_CPU reset */\n    movi a4, DPORT_APPCPU_CTRL_A_REG\n    movi a3, DPORT_APPCPU_RST_EN\n    s32i.n a3, a4, 0\n    s32i.n a5, a4, 0\n    /* Restore the reset vector to ROM */\n    movi a4, RTC_CNTL_RESET_STATE_REG\n    movi a3, RTC_CNTL_RESET_STATE_DEF\n    s32i.n a3, a4, 0\n\n\nparking_loop:\n    /* PRO and APP CPU will be in this loop, until OpenOCD\n     * finds the JTAG taps and puts the CPUs into debug mode.\n     */\n    waiti 0\n    j parking_loop\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc",
    "content": "/* Autogenerated with ../../../../../src/helper/bin2char.sh */\n0x06,0x23,0x00,0x00,0x06,0x18,0x00,0x00,0x38,0x80,0x00,0x60,0xc0,0x80,0x00,0x60,\n0xc4,0x80,0x00,0x60,0x90,0x80,0x00,0x60,0x74,0x80,0x00,0x60,0x18,0x32,0x58,0x01,\n0x00,0xa0,0x00,0x9c,0x00,0x80,0x00,0x60,0xa1,0x3a,0xd8,0x50,0xac,0x80,0x00,0x60,\n0x64,0xf0,0x01,0x60,0x64,0x00,0x02,0x60,0x94,0x80,0x00,0x60,0x48,0xf0,0x01,0x60,\n0x48,0x00,0x02,0x60,0xb4,0x80,0x00,0x60,0x2a,0x31,0x1d,0x8f,0xb0,0x80,0x00,0x60,\n0x00,0x00,0xb0,0x84,0x04,0x00,0x0c,0x60,0x00,0x00,0x0c,0x60,0x00,0x00,0x0c,0x60,\n0x38,0x80,0x00,0x60,0x00,0x30,0x00,0x00,0x50,0x55,0x30,0x41,0xe7,0xff,0x59,0x04,\n0x41,0xe7,0xff,0x59,0x04,0x41,0xe6,0xff,0x59,0x04,0x41,0xe6,0xff,0x59,0x04,0x41,\n0xe6,0xff,0x31,0xe6,0xff,0x39,0x04,0x31,0xe6,0xff,0x41,0xe6,0xff,0x39,0x04,0x00,\n0x60,0xeb,0x03,0x60,0x61,0x04,0x56,0x26,0x05,0x50,0x55,0x30,0x31,0xe3,0xff,0x41,\n0xe3,0xff,0x39,0x04,0x41,0xe3,0xff,0x39,0x04,0x41,0xe2,0xff,0x39,0x04,0x41,0xe2,\n0xff,0x59,0x04,0x41,0xe2,0xff,0x59,0x04,0x41,0xe2,0xff,0x59,0x04,0x41,0xe1,0xff,\n0x31,0xe2,0xff,0x39,0x04,0x41,0xe1,0xff,0x31,0xe2,0xff,0x39,0x04,0x41,0xe1,0xff,\n0x59,0x04,0x41,0xe1,0xff,0x0c,0x23,0x39,0x04,0x41,0xe0,0xff,0x0c,0x43,0x39,0x04,\n0x52,0x64,0x00,0x41,0xdf,0xff,0x31,0xdf,0xff,0x32,0x64,0x00,0x00,0x70,0x00,0x46,\n0xfe,0xff,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/reset/espressif/esp32s3/esp32s3_cpu_reset_handler.S",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Reset stub used by esp32s3 target                                     *\n *   Copyright (C) 2020 Espressif Systems (Shanghai) Co. Ltd.              *\n ***************************************************************************/\n\n#define RTC_CNTL_RESET_STATE_REG            0x60008038\n#define RTC_CNTL_RESET_STATE_DEF            0x3000\n#define RTC_CNTL_CLK_CONF_REG               0x60008074\n#define RTC_CNTL_CLK_CONF_DEF               0x1583218\n#define RTC_CNTL_STORE4_REG                 0x600080C0\n#define RTC_CNTL_STORE5_REG                 0x600080C4\n#define WDT_WKEY_VALUE                      0x50D83AA1\n#define TIMG0_WDTWPROTECT_REG               0x6001F064\n#define TIMG0_WDTCONFIG0_REG                0x6001F048\n#define TIMG1_WDTWPROTECT_REG               0x60020064\n#define TIMG1_WDTCONFIG0_REG                0x60020048\n#define RTC_CNTL_WDTCONFIG0_REG             0x60008094\n#define RTC_CNTL_WDTWPROTECT_REG            0x600080AC\n#define RTC_CNTL_OPTIONS0_REG               0x60008000\n#define RTC_CNTL_OPTIONS0_DEF               0x1C00A000\n#define RTC_CNTL_SW_SYS_RST                 0x80000000\n#define RTC_CNTL_DIG_PWC_REG                0x60008090\n#define RTC_CNTL_SWD_CONF_REG               0x600080B0\n#define RTC_CNTL_SWD_CONF_VAL               0x84B00000\n#define RTC_CNTL_SWD_WPROTECT_REG           0x600080B4\n#define RTC_CNTL_SWD_WKEY_VALUE             0x8F1D312A\n#define SYSTEM_CORE_1_CONTROL_0_REG         0x600C0000\n#define SYSTEM_CONTROL_CORE_1_RESETING      0x4\n#define SYSTEM_CONTROL_CORE_1_CLKGATE_EN    0x2\n#define SYSTEM_CORE_1_CONTROL_1_REG         0x600C0004\n\n\n/* This stub is copied to RTC_SLOW_MEM by OpenOCD, and the CPU starts executing\n * it instead of the ROM code (0x40000400). This stub disables watchdogs and\n * goes into a loop.\n * OpenOCD will then halt the target and perform CPU reset using OCD.\n */\n\n\n/* Has to be at offset 0. This is the entry point of the CPU, once\n * RTC_CNTL_PROCPU_STAT_VECTOR_SEL is cleared.\n * CPU will come here after the system reset, triggered by RTC_CNTL_SW_SYS_RST.\n */\n    .global     cpu_at_start_handler\n    .type       cpu_at_start_handler,@function\n    .align      4\ncpu_at_start_handler:\n    j start\n\n\n/* Has to be at offset 4. Once the stub code has been uploaded into RTC Slow\n * memory, OpenOCD will set the PC to this address, and resume execution.\n * The stub will then jump to 'reset' label and perform the reset.\n */\n    .global     cpu_reset_handler\n    .type       cpu_reset_handler,@function\n    .align      4\ncpu_reset_handler:\n    j reset\n\n    .align 4\n    .literal_position\n\n    .align 4\nreset:\n    /* Use a5 as a zero register */\n    xor a5, a5, a5\n    /* Select static reset vector 0 (XCHAL_RESET_VECTOR0_VADDR, 0x50000000) */\n    movi a4, RTC_CNTL_RESET_STATE_REG\n    s32i a5, a4, 0\n    /* Set some clock-related RTC registers to the default values */\n    movi a4, RTC_CNTL_STORE4_REG\n    s32i a5, a4, 0\n    movi a4, RTC_CNTL_STORE5_REG\n    s32i a5, a4, 0\n    movi a4, RTC_CNTL_DIG_PWC_REG\n    s32i a5, a4, 0\n    movi a4, RTC_CNTL_CLK_CONF_REG\n    movi a3, RTC_CNTL_CLK_CONF_DEF\n    s32i a3, a4, 0\n    /* Reset the digital part of the chip (RTC controller doesn't get reset) */\n    movi a3, (RTC_CNTL_OPTIONS0_DEF | RTC_CNTL_SW_SYS_RST)\n    movi a4, RTC_CNTL_OPTIONS0_REG\n    s32i a3, a4, 0\n    /* Doesn't reach beyond this instruction */\n\n    .align 4\nstart:\n    /* If running on the APP CPU, skip directly to the parking loop */\n    rsr.prid a6\n    extui a6, a6, 1, 1\n    bnez a6, parking_loop\n\n    /* Use a5 as a zero register */\n    xor a5, a5, a5\n    /* Disable the watchdogs */\n    movi a3, WDT_WKEY_VALUE\n    movi a4, RTC_CNTL_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, TIMG0_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, TIMG1_WDTWPROTECT_REG\n    s32i.n a3, a4, 0\n    movi a4, RTC_CNTL_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    movi a4, TIMG0_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    movi a4, TIMG1_WDTCONFIG0_REG\n    s32i.n a5, a4, 0\n    movi a4, RTC_CNTL_SWD_WPROTECT_REG\n    movi a3, RTC_CNTL_SWD_WKEY_VALUE\n    s32i.n a3, a4, 0\n    movi a4, RTC_CNTL_SWD_CONF_REG\n    movi a3, RTC_CNTL_SWD_CONF_VAL\n    s32i.n a3, a4, 0\n    /* Clear APP_CPU boot address */\n    movi a4, SYSTEM_CORE_1_CONTROL_1_REG\n    s32i.n a5, a4, 0\n    /* Clear APP_CPU clock gating */\n    movi a4, SYSTEM_CORE_1_CONTROL_0_REG\n    movi a3, SYSTEM_CONTROL_CORE_1_CLKGATE_EN\n    s32i.n a3, a4, 0\n    /* Set and clear APP_CPU reset */\n    movi a4, SYSTEM_CORE_1_CONTROL_0_REG\n    movi a3, SYSTEM_CONTROL_CORE_1_RESETING\n    s32i.n a3, a4, 0\n    s32i.n a5, a4, 0\n    /* Restore the reset vector to ROM */\n    movi a4, RTC_CNTL_RESET_STATE_REG\n    movi a3, RTC_CNTL_RESET_STATE_DEF\n    s32i.n a3, a4, 0\n\n\nparking_loop:\n    /* PRO and APP CPU will be in this loop, until OpenOCD\n     * finds the JTAG taps and puts the CPUs into debug mode.\n     */\n    waiti 0\n    j parking_loop\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x04,0x4a,0xc2,0x81,0x04,0x4a,0xc2,0x81,0x01,0x24,0x02,0x88,0xa2,0x43,0x02,0x80,\n0x05,0xe0,0x00,0x00,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,0x00,0x00,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/watchdog/armv7m_kinetis_wdog.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 Tomas Vanek                                        *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n/*\n\tDisable watchdog for Kinetis Kx and KVx\n\tParameters:\n\t\tr0 ... WDOG base (in)\n\n\tUsed instruction set should work on both Cortex-M4 and M0+\n*/\n\n\t.text\n\t.syntax unified\n        .cpu cortex-m0\n\t.thumb\n\n/* WDOG registers offsets */\nWDOG_STCTRLH\t= 0\nWDOG_UNLOCK\t= 0x0e\n\nWDOG_KEY1\t= 0xc520\nWDOG_KEY2\t= 0xd928\n\n\t.thumb_func\nstart:\n/* WDOG_UNLOCK = 0xC520 */\n\tldr     r2, =WDOG_KEY1\n\tstrh    r2, [r0, WDOG_UNLOCK]\n/* WDOG_UNLOCK = 0xD928 */\n\tldr     r2, =WDOG_KEY2\n\tstrh    r2, [r0, WDOG_UNLOCK]\n/* WDOG_STCTRLH clear bit 0 */\n\tmovs\tr4, #1\n\tldrh    r2, [r0, WDOG_STCTRLH]\n\tbics\tr2, r4\n\tstrh    r2, [r0, WDOG_STCTRLH]\n/* OpenOCD checks exit point address. Jump to the very end. */\n\tb\tdone\n\n\t.pool\n\n/* Avoid padding at .text segment end. Otherwise exit point check fails. */\n\t.skip\t( . - start + 2) & 2, 0\ndone:\n\tbkpt    #0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc",
    "content": "/* Autogenerated with ../../../src/helper/bin2char.sh */\n0x02,0x68,0x08,0x4b,0x1a,0x42,0x08,0x4b,0x01,0xd0,0x43,0x60,0x02,0xe0,0x83,0x80,\n0x1b,0x0c,0x83,0x80,0x80,0x24,0xa2,0x43,0x20,0x24,0x22,0x43,0x02,0x60,0x03,0x4b,\n0x83,0x60,0x06,0xe0,0x00,0x20,0x00,0x00,0x20,0xc5,0x28,0xd9,0x00,0x04,0x00,0x00,\n0x00,0x00,0x00,0xbe,\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 Tomas Vanek                                        *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n/*\n\tDisable watchdog, 32-bit version for newer Kinetis\n\tParameters:\n\t\tr0 ... WDOG32 base (in)\n\n\tUsed instruction set should work on both Cortex-M4 and M0+\n*/\n\n\t.text\n\t.syntax unified\n        .cpu cortex-m0\n\t.thumb\n\n/* WDOG registers offsets */\nWDOG_CS\t\t= 0\nWDOG_CNT\t= 4\nWDOG_TOVAL\t= 8\n\nWDOG_KEY \t= 0xd928c520\n\n\t.thumb_func\nstart:\n/* test WDOG_CS bit CMD32EN */\n\tldr     r2, [r0, WDOG_CS]\n\tldr     r3, =0x2000\n\ttst     r2, r3\n\tldr     r3, =WDOG_KEY\n\tbeq     cmd16\n\n/* WDOG_CNT = key */\n\tstr     r3, [r0, WDOG_CNT]\n\tb       unlocked\n\ncmd16:\n/* WDOG_CNT = key, halfword by halfword */\n\tstrh    r3, [r0, WDOG_CNT]\n\tlsrs    r3, r3, #16\n\tstrh    r3, [r0, WDOG_CNT]\n\n/* WDOG_CS: clear EN bit 7, set UPDATE bit 5 */\nunlocked:\n\tmovs    r4, #0x80\n\tbics    r2, r4\n\tmovs    r4, #0x20\n\torrs    r2, r4\n\tstr     r2, [r0, WDOG_CS]\n/* All active WDOG registers have to be updated, set dummy timeout */\n/* WDOG_TOVAL = 0x400 */\n\tldr     r3, =0x400\n\tstr     r3, [r0, WDOG_TOVAL]\n/* OpenOCD checks exit point address. Jump to the very end. */\n\tb       done\n\n\t.pool\n\n/* Avoid padding at .text segment end. Otherwise exit point check fails. */\n\t.skip\t( . - start + 2) & 2, 0\ndone:\n\tbkpt    #0\n\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/remote_bitbang/remote_bitbang_sysfsgpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 Paul Fertser <fercerpav@gmail.com>                 *\n *   Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *\n ***************************************************************************/\n\n/*\n  This is a test application to be used as a remote bitbang server for\n  the OpenOCD remote_bitbang interface driver.\n\n  To compile run:\n  gcc -Wall -ansi -pedantic -std=c99 -o remote_bitbang_sysfsgpio remote_bitbang_sysfsgpio.c\n\n\n  Usage example:\n\n  On Raspberry Pi run:\n  socat TCP6-LISTEN:7777,fork EXEC:\"sudo ./remote_bitbang_sysfsgpio tck 11 tms 25 tdo 9 tdi 10\"\n\n  On host run:\n  openocd -c \"interface remote_bitbang; remote_bitbang host raspberrypi; remote_bitbang port 7777\" \\\n\t  -f target/stm32f1x.cfg\n\n  Or if you want to test UNIX sockets, run both on Raspberry Pi:\n  socat UNIX-LISTEN:/tmp/remotebitbang-socket,fork EXEC:\"sudo ./remote_bitbang_sysfsgpio tck 11 tms 25 tdo 9 tdi 10\"\n  openocd -c \"interface remote_bitbang; remote_bitbang host /tmp/remotebitbang-socket\" -f target/stm32f1x.cfg\n*/\n\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#include <unistd.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n\n#define LOG_ERROR(...)\t\tdo {\t\t\t\t\t\\\n\t\tfprintf(stderr, __VA_ARGS__);\t\t\t\t\\\n\t\tfputc('\\n', stderr);\t\t\t\t\t\\\n\t} while (0)\n#define LOG_WARNING(...)\tLOG_ERROR(__VA_ARGS__)\n\n#define ERROR_OK\t(-1)\n#define ERROR_FAIL\t(-2)\n#define ERROR_JTAG_INIT_FAILED\tERROR_FAIL\n\n/*\n * Helper func to determine if gpio number valid\n *\n * Assume here that there will be less than 1000 gpios on a system\n */\nstatic int is_gpio_valid(int gpio)\n{\n\treturn gpio >= 0 && gpio < 1000;\n}\n\n/*\n * Helper func to open, write to and close a file\n * name and valstr must be null terminated.\n *\n * Returns negative on failure.\n */\nstatic int open_write_close(const char *name, const char *valstr)\n{\n\tint ret;\n\tint fd = open(name, O_WRONLY);\n\tif (fd < 0)\n\t\treturn fd;\n\n\tret = write(fd, valstr, strlen(valstr));\n\tclose(fd);\n\n\treturn ret;\n}\n\n/*\n * Helper func to unexport gpio from sysfs\n */\nstatic void unexport_sysfs_gpio(int gpio)\n{\n\tchar gpiostr[4];\n\n\tif (!is_gpio_valid(gpio))\n\t\treturn;\n\n\tsnprintf(gpiostr, sizeof(gpiostr), \"%d\", gpio);\n\tif (open_write_close(\"/sys/class/gpio/unexport\", gpiostr) < 0)\n\t\tLOG_ERROR(\"Couldn't unexport gpio %d\", gpio);\n\n\treturn;\n}\n\n/*\n * Exports and sets up direction for gpio.\n * If the gpio is an output, it is initialized according to init_high,\n * otherwise it is ignored.\n *\n * If the gpio is already exported we just show a warning and continue; if\n * openocd happened to crash (or was killed by user) then the gpios will not\n * have been cleaned up.\n */\nstatic int setup_sysfs_gpio(int gpio, int is_output, int init_high)\n{\n\tchar buf[40];\n\tchar gpiostr[4];\n\tint ret;\n\n\tif (!is_gpio_valid(gpio))\n\t\treturn ERROR_OK;\n\n\tsnprintf(gpiostr, sizeof(gpiostr), \"%d\", gpio);\n\tret = open_write_close(\"/sys/class/gpio/export\", gpiostr);\n\tif (ret < 0) {\n\t\tif (errno == EBUSY) {\n\t\t\tLOG_WARNING(\"gpio %d is already exported\", gpio);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Couldn't export gpio %d\", gpio);\n\t\t\tperror(\"sysfsgpio: \");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tsnprintf(buf, sizeof(buf), \"/sys/class/gpio/gpio%d/direction\", gpio);\n\tret = open_write_close(buf, is_output ? (init_high ? \"high\" : \"low\") : \"in\");\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"Couldn't set direction for gpio %d\", gpio);\n\t\tperror(\"sysfsgpio: \");\n\t\tunexport_sysfs_gpio(gpio);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsnprintf(buf, sizeof(buf), \"/sys/class/gpio/gpio%d/value\", gpio);\n\tif (is_output)\n\t\tret = open(buf, O_WRONLY | O_NONBLOCK | O_SYNC);\n\telse\n\t\tret = open(buf, O_RDONLY | O_NONBLOCK | O_SYNC);\n\n\tif (ret < 0)\n\t\tunexport_sysfs_gpio(gpio);\n\n\treturn ret;\n}\n\n/*\n * file descriptors for /sys/class/gpio/gpioXX/value\n * Set up during init.\n */\nstatic int tck_fd = -1;\nstatic int tms_fd = -1;\nstatic int tdi_fd = -1;\nstatic int tdo_fd = -1;\nstatic int trst_fd = -1;\nstatic int srst_fd = -1;\n\n/*\n * Bitbang interface read of TDO\n *\n * The sysfs value will read back either '0' or '1'. The trick here is to call\n * lseek to bypass buffering in the sysfs kernel driver.\n */\nstatic int sysfsgpio_read(void)\n{\n\tchar buf[1];\n\n\t/* important to seek to signal sysfs of new read */\n\tlseek(tdo_fd, 0, SEEK_SET);\n\tint ret = read(tdo_fd, &buf, sizeof(buf));\n\n\tif (ret < 0) {\n\t\tLOG_WARNING(\"reading tdo failed\");\n\t\treturn 0;\n\t}\n\n\treturn buf[0];\n}\n\n/*\n * Bitbang interface write of TCK, TMS, TDI\n *\n * Seeing as this is the only function where the outputs are changed,\n * we can cache the old value to avoid needlessly writing it.\n */\nstatic void sysfsgpio_write(int tck, int tms, int tdi)\n{\n\tconst char one[] = \"1\";\n\tconst char zero[] = \"0\";\n\n\tstatic int last_tck;\n\tstatic int last_tms;\n\tstatic int last_tdi;\n\n\tstatic int first_time;\n\tsize_t bytes_written;\n\n\tif (!first_time) {\n\t\tlast_tck = !tck;\n\t\tlast_tms = !tms;\n\t\tlast_tdi = !tdi;\n\t\tfirst_time = 1;\n\t}\n\n\tif (tdi != last_tdi) {\n\t\tbytes_written = write(tdi_fd, tdi ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tdi failed\");\n\t}\n\n\tif (tms != last_tms) {\n\t\tbytes_written = write(tms_fd, tms ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tms failed\");\n\t}\n\n\t/* write clk last */\n\tif (tck != last_tck) {\n\t\tbytes_written = write(tck_fd, tck ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tck failed\");\n\t}\n\n\tlast_tdi = tdi;\n\tlast_tms = tms;\n\tlast_tck = tck;\n}\n\n/*\n * Bitbang interface to manipulate reset lines SRST and TRST\n *\n * (1) assert or (0) deassert reset lines\n */\nstatic void sysfsgpio_reset(int trst, int srst)\n{\n\tconst char one[] = \"1\";\n\tconst char zero[] = \"0\";\n\tsize_t bytes_written;\n\n\t/* assume active low */\n\tif (srst_fd >= 0) {\n\t\tbytes_written = write(srst_fd, srst ? &zero : &one, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing srst failed\");\n\t}\n\n\t/* assume active low */\n\tif (trst_fd >= 0) {\n\t\tbytes_written = write(trst_fd, trst ? &zero : &one, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing trst failed\");\n\t}\n}\n\n/* gpio numbers for each gpio. Negative values are invalid */\nstatic int tck_gpio = -1;\nstatic int tms_gpio = -1;\nstatic int tdi_gpio = -1;\nstatic int tdo_gpio = -1;\nstatic int trst_gpio = -1;\nstatic int srst_gpio = -1;\n\n/* helper func to close and cleanup files only if they were valid/ used */\nstatic void cleanup_fd(int fd, int gpio)\n{\n\tif (gpio >= 0) {\n\t\tif (fd >= 0)\n\t\t\tclose(fd);\n\n\t\tunexport_sysfs_gpio(gpio);\n\t}\n}\n\nstatic void cleanup_all_fds(void)\n{\n\tcleanup_fd(tck_fd, tck_gpio);\n\tcleanup_fd(tms_fd, tms_gpio);\n\tcleanup_fd(tdi_fd, tdi_gpio);\n\tcleanup_fd(tdo_fd, tdo_gpio);\n\tcleanup_fd(trst_fd, trst_gpio);\n\tcleanup_fd(srst_fd, srst_gpio);\n}\n\nstatic void process_remote_protocol(void)\n{\n\tint c;\n\twhile (1) {\n\t\tc = getchar();\n\t\tif (c == EOF || c == 'Q') /* Quit */\n\t\t\tbreak;\n\t\telse if (c == 'b' || c == 'B') /* Blink */\n\t\t\tcontinue;\n\t\telse if (c >= 'r' && c <= 'r' + 3) { /* Reset */\n\t\t\tchar d = c - 'r';\n\t\t\tsysfsgpio_reset(!!(d & 2),\n\t\t\t\t\t(d & 1));\n\t\t} else if (c >= '0' && c <= '0' + 7) {/* Write */\n\t\t\tchar d = c - '0';\n\t\t\tsysfsgpio_write(!!(d & 4),\n\t\t\t\t\t!!(d & 2),\n\t\t\t\t\t(d & 1));\n\t\t} else if (c == 'R')\n\t\t\tputchar(sysfsgpio_read());\n\t\telse\n\t\t\tLOG_ERROR(\"Unknown command '%c' received\", c);\n\t}\n}\n\nint main(int argc, char *argv[])\n{\n\tLOG_WARNING(\"SysfsGPIO remote_bitbang JTAG driver\\n\");\n\n\tfor (int i = 1; i < argc; i++) {\n\t\tif (!strcmp(argv[i], \"tck\"))\n\t\t\ttck_gpio = atoi(argv[++i]);\n\t\telse if (!strcmp(argv[i], \"tms\"))\n\t\t\ttms_gpio = atoi(argv[++i]);\n\t\telse if (!strcmp(argv[i], \"tdo\"))\n\t\t\ttdo_gpio = atoi(argv[++i]);\n\t\telse if (!strcmp(argv[i], \"tdi\"))\n\t\t\ttdi_gpio = atoi(argv[++i]);\n\t\telse if (!strcmp(argv[i], \"trst\"))\n\t\t\ttrst_gpio = atoi(argv[++i]);\n\t\telse if (!strcmp(argv[i], \"srst\"))\n\t\t\tsrst_gpio = atoi(argv[++i]);\n\t\telse {\n\t\t\tLOG_ERROR(\"Usage:\\n%s ((tck|tms|tdo|tdi|trst|srst) num)*\", argv[0]);\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\tif (!(is_gpio_valid(tck_gpio)\n\t\t\t&& is_gpio_valid(tms_gpio)\n\t\t\t&& is_gpio_valid(tdi_gpio)\n\t\t\t&& is_gpio_valid(tdo_gpio))) {\n\t\tif (!is_gpio_valid(tck_gpio))\n\t\t\tLOG_ERROR(\"gpio num for tck is invalid\");\n\t\tif (!is_gpio_valid(tms_gpio))\n\t\t\tLOG_ERROR(\"gpio num for tms is invalid\");\n\t\tif (!is_gpio_valid(tdo_gpio))\n\t\t\tLOG_ERROR(\"gpio num for tdo is invalid\");\n\t\tif (!is_gpio_valid(tdi_gpio))\n\t\t\tLOG_ERROR(\"gpio num for tdi is invalid\");\n\n\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios to all be specified\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/*\n\t * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST\n\t * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.\n\t */\n\ttck_fd = setup_sysfs_gpio(tck_gpio, 1, 0);\n\tif (tck_fd < 0)\n\t\tgoto out_error;\n\n\ttms_fd = setup_sysfs_gpio(tms_gpio, 1, 1);\n\tif (tms_fd < 0)\n\t\tgoto out_error;\n\n\ttdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0);\n\tif (tdi_fd < 0)\n\t\tgoto out_error;\n\n\ttdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0);\n\tif (tdo_fd < 0)\n\t\tgoto out_error;\n\n\t/* assume active low */\n\tif (trst_gpio > 0) {\n\t\ttrst_fd = setup_sysfs_gpio(trst_gpio, 1, 1);\n\t\tif (trst_fd < 0)\n\t\t\tgoto out_error;\n\t}\n\n\t/* assume active low */\n\tif (srst_gpio > 0) {\n\t\tsrst_fd = setup_sysfs_gpio(srst_gpio, 1, 1);\n\t\tif (srst_fd < 0)\n\t\t\tgoto out_error;\n\t}\n\n\tLOG_WARNING(\"SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d\",\n\t\t tck_gpio, tms_gpio, tdi_gpio, tdo_gpio);\n\tLOG_WARNING(\"SysfsGPIO num: srst = %d\", srst_gpio);\n\tLOG_WARNING(\"SysfsGPIO num: trst = %d\", trst_gpio);\n\n\tsetvbuf(stdout, NULL, _IONBF, 0);\n\tprocess_remote_protocol();\n\n\tcleanup_all_fds();\n\treturn 0;\nout_error:\n\tcleanup_all_fds();\n\treturn ERROR_JTAG_INIT_FAILED;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/rpc_examples/ocd_rpc_example.py",
    "content": "#!/usr/bin/env python3\n# SPDX-License-Identifier: GPL-3.0-or-later\n\n\"\"\"\nOpenOCD RPC example, covered by GNU GPLv3 or later\nCopyright (C) 2014 Andreas Ortmann (ortmann@finf.uni-hannover.de)\n\n\nExample output:\n./ocd_rpc_example.py\necho says hi!\n\ntarget state: halted\ntarget halted due to debug-request, current mode: Thread\nxPSR: 0x01000000 pc: 0x00000188 msp: 0x10000fd8\n\nvariable @ 0x10000000: 0x01c9c380\n\nvariable @ 0x10000000: 0xdeadc0de\n\nmemory (before): ['0xdeadc0de', '0x00000011', '0xaaaaaaaa', '0x00000023',\n'0x00000042', '0x0000ffff']\n\nmemory (after): ['0x00000001', '0x00000000', '0xaaaaaaaa', '0x00000023',\n'0x00000042', '0x0000ffff']\n\"\"\"\n\nimport socket\nimport itertools\n\ndef strToHex(data):\n    return map(strToHex, data) if isinstance(data, list) else int(data, 16)\n\ndef hexify(data):\n    return \"<None>\" if data is None else (\"0x%08x\" % data)\n\ndef compareData(a, b):\n    for i, j, num in zip(a, b, itertools.count(0)):\n        if i != j:\n            print(\"difference at %d: %s != %s\" % (num, hexify(i), hexify(j)))\n\n\nclass OpenOcd:\n    COMMAND_TOKEN = '\\x1a'\n    def __init__(self, verbose=False):\n        self.verbose = verbose\n        self.tclRpcIp       = \"127.0.0.1\"\n        self.tclRpcPort     = 6666\n        self.bufferSize     = 4096\n\n        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\n    def __enter__(self):\n        self.connect()\n        return self\n\n    def __exit__(self, type, value, traceback):\n        self.disconnect()\n\n    def connect(self):\n        self.sock.connect((self.tclRpcIp, self.tclRpcPort))\n\n    def disconnect(self):\n        try:\n            self.send(\"exit\")\n        finally:\n            self.sock.close()\n\n    def send(self, cmd):\n        \"\"\"Send a command string to TCL RPC. Return the result that was read.\"\"\"\n        data = (cmd + OpenOcd.COMMAND_TOKEN).encode(\"utf-8\")\n        if self.verbose:\n            print(\"<- \", data)\n\n        self.sock.send(data)\n        return self._recv()\n\n    def _recv(self):\n        \"\"\"Read from the stream until the token (\\x1a) was received.\"\"\"\n        data = bytes()\n        while True:\n            chunk = self.sock.recv(self.bufferSize)\n            data += chunk\n            if bytes(OpenOcd.COMMAND_TOKEN, encoding=\"utf-8\") in chunk:\n                break\n\n        if self.verbose:\n            print(\"-> \", data)\n\n        data = data.decode(\"utf-8\").strip()\n        data = data[:-1] # strip trailing \\x1a\n\n        return data\n\n    def readVariable(self, address):\n        raw = self.send(\"mdw 0x%x\" % address).split(\": \")\n        return None if (len(raw) < 2) else strToHex(raw[1])\n\n    def readMemory(self, wordLen, address, n):\n        output = self.send(\"read_memory 0x%x %d %d\" % (address, wordLen, n))\n        return [*map(lambda x: int(x, 16), output.split(\" \"))]\n\n    def writeVariable(self, address, value):\n        assert value is not None\n        self.send(\"mww 0x%x 0x%x\" % (address, value))\n\n    def writeMemory(self, wordLen, address, data):\n        data = \"{\" + ' '.join(['0x%x' % x for x in data]) + \"}\"\n        self.send(\"write_memory 0x%x %d %s\" % (address, wordLen, data))\n\nif __name__ == \"__main__\":\n\n    def show(*args):\n        print(*args, end=\"\\n\\n\")\n\n    with OpenOcd() as ocd:\n        ocd.send(\"reset\")\n\n        show(ocd.send(\"capture { echo \\\"echo says hi!\\\" }\")[:-1])\n        show(ocd.send(\"capture \\\"halt\\\"\")[:-1])\n\n        # Read the first few words at the RAM region (put starting address of RAM\n        # region into 'addr')\n        addr = 0x10000000\n\n        value = ocd.readVariable(addr)\n        show(\"variable @ %s: %s\" % (hexify(addr), hexify(value)))\n\n        ocd.writeVariable(addr, 0xdeadc0de)\n        show(\"variable @ %s: %s\" % (hexify(addr), hexify(ocd.readVariable(addr))))\n\n        data = [1, 0, 0xaaaaaaaa, 0x23, 0x42, 0xffff]\n        wordlen = 32\n        n = len(data)\n\n        read = ocd.readMemory(wordlen, addr, n)\n        show(\"memory (before):\", list(map(hexify, read)))\n\n        ocd.writeMemory(wordlen, addr, n, data)\n\n        read = ocd.readMemory(wordlen, addr, n)\n        show(\"memory  (after):\", list(map(hexify, read)))\n\n        compareData(read, data)\n\n        ocd.send(\"resume\")\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/rpc_examples/ocdrpc.hs",
    "content": "-- SPDX-License-Identifier: GPL-3.0-or-later\n\n-- OpenOCD RPC example\n-- Copyright (C) 2014 Paul Fertser\n--\n-- Example output:\n-- $ ./ocdrpc\n-- Halting the target, full log output captured:\n-- target state: halted\n-- target halted due to debug-request, current mode: Thread\n-- xPSR: 0x21000000 pc: 0x00003352 msp: 0x20000fe8\n--\n-- Read memory, parse the result and show as a list of strings:\n-- [\"0x20001000\",\"0x0000334d\",\"0x00002abb\",\"0x0000118f\",\"0x00002707\",\"0x00002707\",\"0x00002707\",\"0x00000000\",\"0x00000000\",\"0x00000000\",\"0x00000000\",\"0x00002707\",\"0x00002707\",\"0x00000000\",\"0x00002707\",\"0x00002781\"]\n-- Resuming\n\n{-# LANGUAGE OverloadedStrings #-}\nmodule Main where\n\nimport Prelude\nimport Network.Socket\nimport System.IO.Streams.Core hiding (connect)\nimport System.IO.Streams.Network\nimport System.IO.Streams.Attoparsec\nimport Data.Attoparsec.ByteString.Char8\nimport Data.ByteString.Char8 hiding (putStrLn, concat, map)\nimport Text.Printf\n\nocdReply = manyTill anyChar (char '\\x1a')\n\nocdExec (oistream, oostream) command = do\n  write (Just $ pack $ command ++ \"\\x1a\") oostream\n  parseFromStream ocdReply oistream\n\n-- For each line: dispose of address, then match hex values\nmdwParser = (manyTill anyChar (string \": \") *>\n              hexadecimal `sepBy` char ' ')\n            `sepBy` string \" \\n\"\n\nocdMdw :: (InputStream ByteString, OutputStream ByteString) -> Integer -> Integer -> IO [Integer]\nocdMdw s start qnt = do\n  res <- ocdExec s $ \"mdw \" ++ show start ++ \" \" ++ show qnt\n  case parseOnly mdwParser (pack res) of\n    Right r -> return $ concat r\n\nmain = do\n  osock <- socket AF_INET Stream defaultProtocol\n  connect osock (SockAddrInet 6666 $ tupleToHostAddress (127,0,0,1))\n  ostreams <- socketToStreams osock\n  putStrLn \"Halting the target, full log output captured:\"\n  ocdExec ostreams \"capture \\\"halt\\\"\" >>= putStrLn\n  putStrLn \"Read memory, parse the result and show as a list of strings:\"\n  ocdMdw ostreams 0 16 >>= putStrLn . (show :: [String] -> String) . map (printf \"0x%08x\")\n  putStrLn \"Resuming\"\n  ocdExec ostreams \"resume\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/rtos-helpers/FreeRTOS-openocd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer\n * present in the kernel, so it has to be supplied by other means for\n * OpenOCD's threads awareness.\n *\n * Add this file to your project, and, if you're using --gc-sections,\n * ``--undefined=uxTopUsedPriority'' (or\n * ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final\n * linking) to your LDFLAGS; same with all the other symbols you need.\n */\n\n#include \"FreeRTOS.h\"\n\n#ifdef __GNUC__\n#define USED __attribute__((used))\n#else\n#define USED\n#endif\n\nconst int USED uxTopUsedPriority = configMAX_PRIORITIES - 1;\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/rtos-helpers/uCOS-III-openocd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * uC/OS-III does not provide a fixed layout for OS_TCB, which makes it\n * impossible to determine the appropriate offsets within the structure\n * unaided. A priori knowledge of offsets based on os_dbg.c is tied to a\n * specific release and thusly, brittle. The constants defined below\n * provide the necessary information OpenOCD needs to provide support in\n * the most robust manner possible.\n *\n * This file should be linked along with the project to enable RTOS\n * support for uC/OS-III.\n */\n\n#include <os.h>\n\n#if OS_CFG_DBG_EN == 0\n#error \"OS_CFG_DBG_EN is required to enable RTOS support for OpenOCD\"\n#endif\n\n#define OFFSET_OF(type, member) ((CPU_SIZE_T)&(((type *)0)->member))\n\n#ifdef __GNUC__\n#define USED __attribute__((used))\n#else\n#define USED\n#endif\n\nconst CPU_SIZE_T USED openocd_OS_TCB_StkPtr_offset = OFFSET_OF(OS_TCB, StkPtr);\nconst CPU_SIZE_T USED openocd_OS_TCB_NamePtr_offset = OFFSET_OF(OS_TCB, NamePtr);\nconst CPU_SIZE_T USED openocd_OS_TCB_TaskState_offset = OFFSET_OF(OS_TCB, TaskState);\nconst CPU_SIZE_T USED openocd_OS_TCB_Prio_offset = OFFSET_OF(OS_TCB, Prio);\nconst CPU_SIZE_T USED openocd_OS_TCB_DbgPrevPtr_offset = OFFSET_OF(OS_TCB, DbgPrevPtr);\nconst CPU_SIZE_T USED openocd_OS_TCB_DbgNextPtr_offset = OFFSET_OF(OS_TCB, DbgNextPtr);\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/xsvf_tools/svf2xsvf.py",
    "content": "#!/usr/bin/python3.0\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Copyright 2008, SoftPLC Corporation  http://softplc.com\n# Dick Hollenbeck dick@softplc.com\n\n# A python program to convert an SVF file to an XSVF file.  There is an\n# option to include comments containing the source file line number from the origin\n# SVF file before each outputted XSVF statement.\n#\n# We deviate from the XSVF spec in that we introduce a new command called\n# XWAITSTATE which directly flows from the SVF RUNTEST command.  Unfortunately\n# XRUNSTATE was ill conceived and is not used here.  We also add support for the\n# three Lattice extensions to SVF: LCOUNT, LDELAY, and LSDR.  The xsvf file\n# generated from this program is suitable for use with the xsvf player in\n# OpenOCD with my modifications to xsvf.c.\n#\n# This program is written for python 3.0, and it is not easy to change this\n# back to 2.x.  You may find it easier to use python 3.x even if that means\n# building it.\n\n\nimport re\nimport sys\nimport struct\n\n\n# There are both ---<Lexer>--- and ---<Parser>--- sections to this program\n\n\nif len( sys.argv ) < 3:\n    print(\"usage %s <svf_filename> <xsvf_filename>\" % sys.argv[0])\n    exit(1)\n\n\ninputFilename = sys.argv[1]\noutputFilename = sys.argv[2]\n\ndoCOMMENTs = True       # Save XCOMMENTs in the output xsvf file\n#doCOMMENTs = False       # Save XCOMMENTs in the output xsvf file\n\n# pick your file encoding\nfile_encoding = 'ISO-8859-1'\n#file_encoding = 'utf-8'\n\n\nxrepeat = 0             # argument to XREPEAT, gives retry count for masked compares\n\n\n#-----< Lexer >---------------------------------------------------------------\n\nStateBin = (RESET,IDLE,\n    DRSELECT,DRCAPTURE,DRSHIFT,DREXIT1,DRPAUSE,DREXIT2,DRUPDATE,\n    IRSELECT,IRCAPTURE,IRSHIFT,IREXIT1,IRPAUSE,IREXIT2,IRUPDATE) = range(16)\n\n# Any integer index into this tuple will be equal to its corresponding StateBin value\nStateTxt = (\"RESET\",\"IDLE\",\n    \"DRSELECT\",\"DRCAPTURE\",\"DRSHIFT\",\"DREXIT1\",\"DRPAUSE\",\"DREXIT2\",\"DRUPDATE\",\n    \"IRSELECT\",\"IRCAPTURE\",\"IRSHIFT\",\"IREXIT1\",\"IRPAUSE\",\"IREXIT2\",\"IRUPDATE\")\n\n\n(XCOMPLETE,XTDOMASK,XSIR,XSDR,XRUNTEST,hole0,hole1,XREPEAT,XSDRSIZE,XSDRTDO,\n    XSETSDRMASKS,XSDRINC,XSDRB,XSDRC,XSDRE,XSDRTDOB,XSDRTDOC,\n    XSDRTDOE,XSTATE,XENDIR,XENDDR,XSIR2,XCOMMENT,XWAIT,XWAITSTATE,\n    LCOUNT,LDELAY,LSDR,XTRST) = range(29)\n\n#Note: LCOUNT, LDELAY, and LSDR are Lattice extensions to SVF and provide a way to loop back\n# and check a completion status, essentially waiting on a part until it signals that it is done.\n# For example below: loop 25 times, each time through the loop do a LDELAY (same as a true RUNTEST)\n# and exit loop when LSDR compares match.\n\"\"\"\nLCOUNT\t25;\n! Step to DRPAUSE give 5 clocks and wait for 1.00e+000 SEC.\nLDELAY\tDRPAUSE\t5 TCK\t1.00E-003 SEC;\n! Test for the completed status. Match means pass.\n! Loop back to LDELAY line if not match and loop count less than 25.\nLSDR  1 TDI  (0)\n        TDO  (1);\n\"\"\"\n\n#XTRST is an opcode Xilinx seemed to have missed and it comes from the SVF TRST statement.\n\nLineNumber = 1\n\ndef s_ident(scanner, token): return (\"ident\", token.upper(), LineNumber)\n\ndef s_hex(scanner, token):\n    global LineNumber\n    LineNumber = LineNumber + token.count('\\n')\n    token = ''.join(token.split())\n    return (\"hex\", token[1:-1], LineNumber)\n\ndef s_int(scanner, token): return (\"int\", int(token), LineNumber)\ndef s_float(scanner, token): return (\"float\", float(token), LineNumber)\n#def s_comment(scanner, token): return (\"comment\", token, LineNumber)\ndef s_semicolon(scanner, token): return (\"semi\", token, LineNumber)\n\ndef s_nl(scanner,token):\n    global LineNumber\n    LineNumber = LineNumber + 1\n    #print( 'LineNumber=', LineNumber, file=sys.stderr )\n    return None\n\n#2.00E-002\n\nscanner = re.Scanner([\n    (r\"[a-zA-Z]\\w*\", s_ident),\n#    (r\"[-+]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?\", s_float),\n    (r\"[-+]?[0-9]+(([.][0-9eE+-]*)|([eE]+[-+]?[0-9]+))\", s_float),\n    (r\"\\d+\", s_int),\n    (r\"\\(([0-9a-fA-F]|\\s)*\\)\", s_hex),\n    (r\"(!|//).*$\", None),\n    (r\";\", s_semicolon),\n    (r\"\\n\",s_nl),\n    (r\"\\s*\", None),\n    ],\n    re.MULTILINE\n    )\n\n# open the file using the given encoding\nfile = open( sys.argv[1], encoding=file_encoding )\n\n# read all svf file input into string \"input\"\ninput = file.read()\n\nfile.close()\n\n# Lexer:\n# create a list of tuples containing (tokenType, tokenValue, LineNumber)\ntokens = scanner.scan( input )[0]\n\ninput = None    # allow gc to reclaim memory holding file\n\n#for tokenType, tokenValue, ln in tokens: print( \"line %d: %s\" % (ln, tokenType), tokenValue )\n\n\n#-----<parser>-----------------------------------------------------------------\n\ntokVal = tokType = tokLn = None\n\ntup = iter( tokens )\n\ndef nextTok():\n    \"\"\"\n    Function to read the next token from tup into tokType, tokVal, tokLn (linenumber)\n    which are globals.\n    \"\"\"\n    global tokType, tokVal, tokLn, tup\n    tokType, tokVal, tokLn = tup.__next__()\n\n\nclass ParseError(Exception):\n    \"\"\"A class to hold a parsing error message\"\"\"\n    def __init__(self, linenumber, token, message):\n        self.linenumber = linenumber\n        self.token = token\n        self.message = message\n    def __str__(self):\n        global inputFilename\n        return \"Error in file \\'%s\\' at line %d near token %s\\n %s\" % (\n                   inputFilename, self.linenumber, repr(self.token), self.message)\n\n\nclass MASKSET(object):\n    \"\"\"\n    Class MASKSET holds a set of bit vectors, all of which are related, will all\n    have the same length, and are associated with one of the seven shiftOps:\n    HIR, HDR, TIR, TDR, SIR, SDR, LSDR. One of these holds a mask, smask, tdi, tdo, and a\n    size.\n    \"\"\"\n    def __init__(self, name):\n        self.empty()\n        self.name = name\n\n    def empty(self):\n        self.mask = bytearray()\n        self.smask = bytearray()\n        self.tdi = bytearray()\n        self.tdo = bytearray()\n        self.size = 0\n\n    def syncLengths( self, sawTDI, sawTDO, sawMASK, sawSMASK, newSize ):\n        \"\"\"\n        Set all the lengths equal in the event some of the masks were\n        not seen as part of the last change set.\n        \"\"\"\n        if self.size == newSize:\n            return\n\n        if newSize == 0:\n            self.empty()\n            return\n\n        # If an SIR was given without a MASK(), then use a mask of all zeros.\n        # this is not consistent with the SVF spec, but it makes sense because\n        # it would be odd to be testing an instruction register read out of a\n        # tap without giving a mask for it.  Also, lattice seems to agree and is\n        # generating SVF files that comply with this philosophy.\n        if self.name == 'SIR' and not sawMASK:\n            self.mask = bytearray( newSize )\n\n        if newSize != len(self.mask):\n            self.mask = bytearray( newSize )\n            if self.name == 'SDR':  # leave mask for HIR,HDR,TIR,TDR,SIR zeros\n                for i in range( newSize ):\n                    self.mask[i] = 1\n\n        if newSize != len(self.tdo):\n            self.tdo = bytearray( newSize )\n\n        if newSize != len(self.tdi):\n            self.tdi = bytearray( newSize )\n\n        if newSize != len(self.smask):\n            self.smask = bytearray( newSize )\n\n        self.size = newSize\n#-----</MASKSET>-----\n\n\ndef makeBitArray( hexString, bitCount ):\n    \"\"\"\n    Converts a packed sequence of hex ascii characters into a bytearray where\n    each element in the array holds exactly one bit. Only \"bitCount\" bits are\n    scanned and these must be the least significant bits in the hex number. That\n    is, it is legal to have some unused bits in the must significant hex nibble\n    of the input \"hexString\". The string is scanned starting from the backend,\n    then just before returning we reverse the array. This way the append()\n    method can be used, which I assume is faster than an insert.\n    \"\"\"\n    global tokLn\n    a = bytearray()\n    length = bitCount\n    hexString = list(hexString)\n    hexString.reverse()\n    #print(hexString)\n    for c in hexString:\n        if length <= 0:\n            break;\n        c = int(c, 16)\n        for mask in [1,2,4,8]:\n            if length <= 0:\n                break;\n            length = length - 1\n            a.append( (c & mask) != 0 )\n    if length > 0:\n        raise ParseError( tokLn, hexString, \"Insufficient hex characters for given length of %d\" % bitCount )\n    a.reverse()\n    #print(a)\n    return a\n\n\ndef makeXSVFbytes( bitarray ):\n    \"\"\"\n    Make a bytearray which is contains the XSVF bits which will be written\n    directly to disk.  The number of bytes needed is calculated from the size\n    of the argument bitarray.\n    \"\"\"\n    bitCount = len(bitarray)\n    byteCount = (bitCount+7)//8\n    ba = bytearray( byteCount )\n    firstBit = (bitCount % 8) - 1\n    if firstBit == -1:\n        firstBit = 7\n    bitNdx = 0\n    for byteNdx in range(byteCount):\n        mask = 1<<firstBit\n        byte = 0\n        while mask:\n            if bitarray[bitNdx]:\n                byte |= mask;\n            mask = mask >> 1\n            bitNdx = bitNdx + 1\n        ba[byteNdx] = byte\n        firstBit = 7\n    return ba\n\n\ndef writeComment( outputFile, shiftOp_linenum, shiftOp ):\n    \"\"\"\n    Write an XCOMMENT record to outputFile\n    \"\"\"\n    comment = \"%s @%d\\0\" % (shiftOp, shiftOp_linenum)   # \\0 is terminating nul\n    ba = bytearray(1)\n    ba[0] = XCOMMENT\n    ba += comment.encode()\n    outputFile.write( ba )\n\n\ndef combineBitVectors( trailer, meat, header ):\n    \"\"\"\n    Combine the 3 bit vectors comprizing a transmission.  Since the least\n    significant bits are sent first, the header is put onto the list last so\n    they are sent first from that least significant position.\n    \"\"\"\n    ret = bytearray()\n    ret.extend( trailer )\n    ret.extend( meat )\n    ret.extend( header )\n    return ret\n\n\ndef writeRUNTEST( outputFile, run_state, end_state, run_count, min_time, tokenTxt ):\n    \"\"\"\n    Write the output for the SVF RUNTEST command.\n    run_count - the number of clocks\n    min_time - the number of seconds\n    tokenTxt - either RUNTEST or LDELAY\n    \"\"\"\n    # convert from secs to usecs\n    min_time = int( min_time * 1000000)\n\n    # the SVF RUNTEST command does NOT map to the XSVF XRUNTEST command.  Check the SVF spec, then\n    # read the XSVF command.   They are not the same.  Use an XSVF XWAITSTATE to\n    # implement the required behavior of the SVF RUNTEST command.\n    if doCOMMENTs:\n        writeComment( output, tokLn, tokenTxt )\n\n    if tokenTxt == 'RUNTEST':\n        obuf = bytearray(11)\n        obuf[0] = XWAITSTATE\n        obuf[1] = run_state\n        obuf[2] = end_state\n        struct.pack_into(\">i\", obuf, 3, run_count )  # big endian 4 byte int to obuf\n        struct.pack_into(\">i\", obuf, 7, min_time )   # big endian 4 byte int to obuf\n        outputFile.write( obuf )\n    else:   # == 'LDELAY'\n        obuf = bytearray(10)\n        obuf[0] = LDELAY\n        obuf[1] = run_state\n        # LDELAY has no end_state\n        struct.pack_into(\">i\", obuf, 2, run_count )  # big endian 4 byte int to obuf\n        struct.pack_into(\">i\", obuf, 6, min_time )   # big endian 4 byte int to obuf\n        outputFile.write( obuf )\n\n\noutput = open( outputFilename, mode='wb' )\n\nhir = MASKSET('HIR')\nhdr = MASKSET('HDR')\ntir = MASKSET('TIR')\ntdr = MASKSET('TDR')\nsir = MASKSET('SIR')\nsdr = MASKSET('SDR')\n\n\nexpecting_eof = True\n\n\n# one of the commands that take the shiftParts after the length, the parse\n# template for all of these commands is identical\nshiftOps = ('SDR', 'SIR', 'LSDR', 'HDR', 'HIR', 'TDR', 'TIR')\n\n# the order must correspond to shiftOps, this holds the MASKSETS.  'LSDR' shares sdr with 'SDR'\nshiftSets = (sdr, sir, sdr, hdr, hir, tdr, tir )\n\n# what to expect as parameters to a shiftOp, i.e. after a SDR length or SIR length\nshiftParts = ('TDI', 'TDO', 'MASK', 'SMASK')\n\n# the set of legal states which can trail the RUNTEST command\nrun_state_allowed = ('IRPAUSE', 'DRPAUSE', 'RESET', 'IDLE')\n\nenddr_state_allowed = ('DRPAUSE', 'IDLE')\nendir_state_allowed = ('IRPAUSE', 'IDLE')\n\ntrst_mode_allowed = ('ON', 'OFF', 'Z', 'ABSENT')\n\nenddr_state = IDLE\nendir_state = IDLE\n\nfrequency = \t1.00e+006 # HZ;\n\n# change detection for xsdrsize and xtdomask\nxsdrsize = -1           # the last one sent, send only on change\nxtdomask = bytearray()  # the last one sent, send only on change\n\n\n# we use a number of single byte writes for the XSVF command below\ncmdbuf = bytearray(1)\n\n\n# Save the XREPEAT setting into the file as first thing.\nobuf = bytearray(2)\nobuf[0] = XREPEAT\nobuf[1] = xrepeat\noutput.write( obuf )\n\n\ntry:\n    while 1:\n        expecting_eof = True\n        nextTok()\n        expecting_eof = False\n        # print( tokType, tokVal, tokLn )\n\n        if tokVal in shiftOps:\n            shiftOp_linenum = tokLn\n            shiftOp = tokVal\n\n            set = shiftSets[shiftOps.index(shiftOp)]\n\n            # set flags false, if we see one later, set that one true later\n            sawTDI = sawTDO = sawMASK = sawSMASK = False\n\n            nextTok()\n            if tokType != 'int':\n                raise ParseError( tokLn, tokVal, \"Expecting 'int' giving %s length, got '%s'\" % (shiftOp, tokType) )\n            length = tokVal\n\n            nextTok()\n\n            while tokVal != ';':\n                if tokVal not in shiftParts:\n                    raise ParseError( tokLn, tokVal, \"Expecting TDI, TDO, MASK, SMASK, or ';'\")\n                shiftPart = tokVal\n\n                nextTok()\n\n                if tokType != 'hex':\n                    raise ParseError( tokLn, tokVal, \"Expecting hex bits\" )\n                bits = makeBitArray( tokVal, length )\n\n                if shiftPart == 'TDI':\n                    sawTDI = True\n                    set.tdi = bits\n\n                elif shiftPart == 'TDO':\n                    sawTDO = True\n                    set.tdo = bits\n\n                elif shiftPart == 'MASK':\n                    sawMASK = True\n                    set.mask = bits\n\n                elif shiftPart == 'SMASK':\n                    sawSMASK = True\n                    set.smask = bits\n\n                nextTok()\n\n            set.syncLengths( sawTDI, sawTDO, sawMASK, sawSMASK, length )\n\n            # process all the gathered parameters and generate outputs here\n            if shiftOp == 'SIR':\n                if doCOMMENTs:\n                    writeComment( output, shiftOp_linenum, 'SIR' )\n\n                tdi = combineBitVectors( tir.tdi, sir.tdi, hir.tdi )\n                if len(tdi) > 255:\n                    obuf = bytearray(3)\n                    obuf[0] = XSIR2\n                    struct.pack_into( \">h\", obuf, 1, len(tdi) )\n                else:\n                    obuf = bytearray(2)\n                    obuf[0] = XSIR\n                    obuf[1] = len(tdi)\n                output.write( obuf )\n                obuf = makeXSVFbytes( tdi )\n                output.write( obuf )\n\n            elif shiftOp == 'SDR':\n                if doCOMMENTs:\n                    writeComment( output, shiftOp_linenum, shiftOp )\n\n                if not sawTDO:\n                    # pass a zero filled bit vector for the sdr.mask\n                    mask = combineBitVectors( tdr.mask, bytearray(sdr.size), hdr.mask )\n                    tdi  = combineBitVectors( tdr.tdi,  sdr.tdi,  hdr.tdi )\n\n                    if xsdrsize != len(tdi):\n                        xsdrsize = len(tdi)\n                        cmdbuf[0] = XSDRSIZE\n                        output.write( cmdbuf )\n                        obuf = bytearray(4)\n                        struct.pack_into( \">i\", obuf, 0, xsdrsize )  # big endian 4 byte int to obuf\n                        output.write( obuf )\n\n                    if xtdomask != mask:\n                        xtdomask = mask\n                        cmdbuf[0] = XTDOMASK\n                        output.write( cmdbuf )\n                        obuf = makeXSVFbytes( mask )\n                        output.write( obuf )\n\n                    cmdbuf[0] = XSDR\n                    output.write( cmdbuf )\n                    obuf = makeXSVFbytes( tdi )\n                    output.write( obuf )\n\n                else:\n                    mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask )\n                    tdi  = combineBitVectors( tdr.tdi,  sdr.tdi,  hdr.tdi )\n                    tdo  = combineBitVectors( tdr.tdo,  sdr.tdo,  hdr.tdo )\n\n                    if xsdrsize != len(tdi):\n                        xsdrsize = len(tdi)\n                        cmdbuf[0] = XSDRSIZE\n                        output.write( cmdbuf )\n                        obuf = bytearray(4)\n                        struct.pack_into(\">i\", obuf, 0, xsdrsize )  # big endian 4 byte int to obuf\n                        output.write( obuf )\n\n                    if xtdomask != mask:\n                        xtdomask = mask\n                        cmdbuf[0] = XTDOMASK\n                        output.write( cmdbuf )\n                        obuf = makeXSVFbytes( mask )\n                        output.write( obuf )\n\n                    cmdbuf[0] = XSDRTDO\n                    output.write( cmdbuf )\n                    obuf = makeXSVFbytes( tdi )\n                    output.write( obuf )\n                    obuf = makeXSVFbytes( tdo )\n                    output.write( obuf )\n                    #print( \"len(tdo)=\", len(tdo), \"len(tdr.tdo)=\", len(tdr.tdo), \"len(sdr.tdo)=\", len(sdr.tdo), \"len(hdr.tdo)=\", len(hdr.tdo) )\n\n            elif shiftOp == 'LSDR':\n                if doCOMMENTs:\n                    writeComment( output, shiftOp_linenum, shiftOp )\n\n                mask = combineBitVectors( tdr.mask, sdr.mask, hdr.mask )\n                tdi  = combineBitVectors( tdr.tdi,  sdr.tdi,  hdr.tdi )\n                tdo  = combineBitVectors( tdr.tdo,  sdr.tdo,  hdr.tdo )\n\n                if xsdrsize != len(tdi):\n                    xsdrsize = len(tdi)\n                    cmdbuf[0] = XSDRSIZE\n                    output.write( cmdbuf )\n                    obuf = bytearray(4)\n                    struct.pack_into(\">i\", obuf, 0, xsdrsize )  # big endian 4 byte int to obuf\n                    output.write( obuf )\n\n                if xtdomask != mask:\n                    xtdomask = mask\n                    cmdbuf[0] = XTDOMASK\n                    output.write( cmdbuf )\n                    obuf = makeXSVFbytes( mask )\n                    output.write( obuf )\n\n                cmdbuf[0] = LSDR\n                output.write( cmdbuf )\n                obuf = makeXSVFbytes( tdi )\n                output.write( obuf )\n                obuf = makeXSVFbytes( tdo )\n                output.write( obuf )\n                #print( \"len(tdo)=\", len(tdo), \"len(tdr.tdo)=\", len(tdr.tdo), \"len(sdr.tdo)=\", len(sdr.tdo), \"len(hdr.tdo)=\", len(hdr.tdo) )\n\n        elif tokVal == 'RUNTEST' or tokVal == 'LDELAY':\n            # e.g. from lattice tools:\n            # \"RUNTEST\tIDLE  \t5 TCK\t1.00E-003 SEC;\"\n            saveTok = tokVal\n            nextTok()\n            min_time = 0\n            run_count = 0\n            max_time = 600  # ten minutes\n            if tokVal in run_state_allowed:\n                run_state = StateTxt.index(tokVal)\n                end_state = run_state  # bottom of page 17 of SVF spec\n                nextTok()\n            if tokType != 'int' and tokType != 'float':\n                raise ParseError( tokLn, tokVal, \"Expecting 'int' or 'float' after RUNTEST [run_state]\")\n            timeval = tokVal;\n            nextTok()\n            if tokVal != 'TCK' and tokVal != 'SEC' and tokVal != 'SCK':\n                raise ParseError( tokLn, tokVal, \"Expecting 'TCK' or 'SEC' or 'SCK' after RUNTEST [run_state] (run_count|min_time)\")\n            if tokVal == 'TCK' or tokVal == 'SCK':\n                run_count = int( timeval )\n            else:\n                min_time = timeval\n            nextTok()\n            if tokType == 'int' or tokType == 'float':\n                min_time = tokVal\n                nextTok()\n                if tokVal != 'SEC':\n                    raise ParseError( tokLn, tokVal, \"Expecting 'SEC' after RUNTEST [run_state] run_count min_time\")\n                nextTok()\n            if tokVal == 'MAXIMUM':\n                nextTok()\n                if tokType != 'int' and tokType != 'float':\n                    raise ParseError( tokLn, tokVal, \"Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM\")\n                max_time = tokVal\n                nextTok()\n                if tokVal != 'SEC':\n                    raise ParseError( tokLn, tokVal, \"Expecting 'max_time' after RUNTEST [run_state] min_time SEC MAXIMUM max_time\")\n                nextTok()\n            if tokVal == 'ENDSTATE':\n                nextTok()\n                if tokVal not in run_state_allowed:\n                    raise ParseError( tokLn, tokVal, \"Expecting 'run_state' after RUNTEST .... ENDSTATE\")\n                end_state = StateTxt.index(tokVal)\n                nextTok()\n            if tokVal != ';':\n                raise ParseError( tokLn, tokVal, \"Expecting ';' after RUNTEST ....\")\n            # print( \"run_count=\", run_count, \"min_time=\", min_time,\n                # \"max_time=\", max_time, \"run_state=\", State[run_state], \"end_state=\", State[end_state] )\n            writeRUNTEST( output, run_state, end_state, run_count, min_time, saveTok )\n\n        elif tokVal == 'LCOUNT':\n            nextTok()\n            if tokType != 'int':\n                raise ParseError( tokLn, tokVal, \"Expecting integer 'count' after LCOUNT\")\n            loopCount = tokVal\n            nextTok()\n            if tokVal != ';':\n                raise ParseError( tokLn, tokVal, \"Expecting ';' after LCOUNT count\")\n            if doCOMMENTs:\n                writeComment( output, tokLn, 'LCOUNT' )\n            obuf = bytearray(5)\n            obuf[0] = LCOUNT\n            struct.pack_into(\">i\", obuf, 1, loopCount )  # big endian 4 byte int to obuf\n            output.write( obuf )\n\n        elif tokVal == 'ENDDR':\n            nextTok()\n            if tokVal not in enddr_state_allowed:\n                raise ParseError( tokLn, tokVal, \"Expecting 'stable_state' after ENDDR. (one of: DRPAUSE, IDLE)\")\n            enddr_state = StateTxt.index(tokVal)\n            nextTok()\n            if tokVal != ';':\n                raise ParseError( tokLn, tokVal, \"Expecting ';' after ENDDR stable_state\")\n            if doCOMMENTs:\n                writeComment( output, tokLn, 'ENDDR' )\n            obuf = bytearray(2)\n            obuf[0] = XENDDR\n            # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here.\n            # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e.\n            # boolean argument to XENDDR which only handles two of the 3 intended states.\n            obuf[1] = 1 if enddr_state == DRPAUSE else 0\n            output.write( obuf )\n\n        elif tokVal == 'ENDIR':\n            nextTok()\n            if tokVal not in endir_state_allowed:\n                raise ParseError( tokLn, tokVal, \"Expecting 'stable_state' after ENDIR. (one of: IRPAUSE, IDLE)\")\n            endir_state = StateTxt.index(tokVal)\n            nextTok()\n            if tokVal != ';':\n                raise ParseError( tokLn, tokVal, \"Expecting ';' after ENDIR stable_state\")\n            if doCOMMENTs:\n                writeComment( output, tokLn, 'ENDIR' )\n            obuf = bytearray(2)\n            obuf[0] = XENDIR\n            # Page 10 of the March 1999 SVF spec shows that RESET is also allowed here.\n            # Yet the XSVF spec has no provision for that, and uses a non-standard, i.e.\n            # boolean argument to XENDDR which only handles two of the 3 intended states.\n            obuf[1] = 1 if endir_state == IRPAUSE else 0\n            output.write( obuf )\n\n        elif tokVal == 'STATE':\n            nextTok()\n            ln = tokLn\n            while tokVal != ';':\n                if tokVal not in StateTxt:\n                    raise ParseError( tokLn, tokVal, \"Expecting 'stable_state' after STATE\")\n                stable_state = StateTxt.index( tokVal )\n\n                if doCOMMENTs and ln != -1:\n                    writeComment( output, ln, 'STATE' )\n                    ln = -1     # save comment only once\n\n                obuf = bytearray(2)\n                obuf[0] = XSTATE\n                obuf[1] = stable_state\n                output.write( obuf )\n                nextTok()\n\n        elif tokVal == 'FREQUENCY':\n            nextTok()\n            if tokVal != ';':\n                if tokType != 'int' and tokType != 'float':\n                    raise ParseError( tokLn, tokVal, \"Expecting 'cycles HZ' after FREQUENCY\")\n                frequency = tokVal\n                nextTok()\n                if tokVal != 'HZ':\n                    raise ParseError( tokLn, tokVal, \"Expecting 'HZ' after FREQUENCY cycles\")\n                nextTok()\n                if tokVal != ';':\n                    raise ParseError( tokLn, tokVal, \"Expecting ';' after FREQUENCY cycles HZ\")\n\n        elif tokVal == 'TRST':\n            nextTok()\n            if tokVal not in trst_mode_allowed:\n                raise ParseError( tokLn, tokVal, \"Expecting 'ON|OFF|Z|ABSENT' after TRST\")\n            trst_mode = tokVal\n            nextTok()\n            if tokVal != ';':\n                raise ParseError( tokLn, tokVal, \"Expecting ';' after TRST trst_mode\")\n            if doCOMMENTs:\n                writeComment( output, tokLn, 'TRST %s' % trst_mode )\n            obuf = bytearray( 2 )\n            obuf[0] = XTRST\n            obuf[1] = trst_mode_allowed.index( trst_mode )  # use the index as the binary argument to XTRST opcode\n            output.write( obuf )\n\n        else:\n            raise ParseError( tokLn, tokVal, \"Unknown token '%s'\" % tokVal)\n\nexcept StopIteration:\n    if not expecting_eof:\n        print( \"Unexpected End of File at line \", tokLn )\n\nexcept ParseError as pe:\n    print( \"\\n\", pe )\n\nfinally:\n    # print( \"closing file\" )\n    cmdbuf[0] = XCOMPLETE\n    output.write( cmdbuf )\n    output.close()\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/contrib/xsvf_tools/xsvfdump.py",
    "content": "#!/usr/bin/python3.0\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Copyright 2008, SoftPLC Corporation  http://softplc.com\n# Dick Hollenbeck dick@softplc.com\n\n# Dump an Xilinx XSVF file to stdout\n\n# This program is written for python 3.0, and it is not easy to change this\n# back to 2.x.  You may find it easier to use python 3.x even if that means\n# building it.\n\n\nimport sys\nimport struct\n\n\nLABEL = \"A script to dump an XSVF file to stdout\"\n\n\nXsdrsize = 0\n\n\n(XCOMPLETE,XTDOMASK,XSIR,XSDR,XRUNTEST,hole0,hole1,XREPEAT,XSDRSIZE,XSDRTDO,\n    XSETSDRMASKS,XSDRINC,XSDRB,XSDRC,XSDRE,XSDRTDOB,XSDRTDOC,\n    XSDRTDOE,XSTATE,XENDIR,XENDDR,XSIR2,XCOMMENT,XWAIT,XWAITSTATE,\n    LCOUNT,LDELAY,LSDR,XTRST) = range(29)\n\n\n(RESET,IDLE,\n    DRSELECT,DRCAPTURE,DRSHIFT,DREXIT1,DRPAUSE,DREXIT2,DRUPDATE,\n    IRSELECT,IRCAPTURE,IRSHIFT,IREXIT1,IRPAUSE,IREXIT2,IRUPDATE) = range(16)\n\n\nState = (\"RESET\",\"IDLE\",\n    \"DRSELECT\",\"DRCAPTURE\",\"DRSHIFT\",\"DREXIT1\",\"DRPAUSE\",\"DREXIT2\",\"DRUPDATE\",\n    \"IRSELECT\",\"IRCAPTURE\",\"IRSHIFT\",\"IREXIT1\",\"IRPAUSE\",\"IREXIT2\",\"IRUPDATE\")\n\n\ntrst_mode_allowed = ('ON', 'OFF', 'Z', 'ABSENT')\n\n\nSetsdrmasks = 0\nSetsdrmasksOnesCount = 0\n\ndef ReadSDRMASKS( f, len ):\n    global Setsdrmasks, SetsdrmasksOnesCount\n    byteCount = (len+7)//8\n    Setsdrmasks = f.read( byteCount )\n    ls = []\n    SetsdrmasksOnesCount = 0\n    for b in Setsdrmasks:\n        ls.append( \"%x\" % ((b & 0xf0) >> 4) )\n        ls.append( \"%x\" % ( b & 0x0f ) )\n        for i in range(8):\n            if b & (1<<i):\n                SetsdrmasksOnesCount = SetsdrmasksOnesCount +1\n    return ''.join(ls)\n\n\ndef bytes2hexString( f, len ):\n    byteCount = (len+7)//8\n    bytebuf = f.read( byteCount )\n    ls = []\n    for b in bytebuf:\n        ls.append( \"%x\" % ((b & 0xf0) >> 4) )\n        ls.append( \"%x\" % ( b & 0x0f ) )\n    return ''.join(ls)\n\n\ndef ReadByte( f ):\n    \"\"\"Read a byte from a file and return it as an int in least significant 8 bits\"\"\"\n    b = f.read(1)\n    if b:\n        return 0xff & b[0];\n    else:\n        return -1\n\n\ndef ShowState( state ):\n    \"\"\"return the given state int as a state string\"\"\"\n    #return \"0x%02x\" % state # comment this out to get textual state form\n    global State\n    if 0 <= state <= IRUPDATE:\n        return State[state]\n    else:\n        return \"Unknown state 0x%02x\" % state\n\n\ndef ShowOpcode( op, f ):\n    \"\"\"return the given byte as an opcode string\"\"\"\n    global Xsdrsize\n    if op == XCOMPLETE:\n        print(\"XCOMPLETE\")\n\n    elif op == XTDOMASK:\n        buf = bytes2hexString( f, Xsdrsize )\n        print(\"XTDOMASK 0x%s\" % buf)\n\n    elif op == XSIR:\n        len = ReadByte( f )\n        buf = bytes2hexString( f, len )\n        print(\"XSIR 0x%02X 0x%s\" % (len, buf))\n\n    elif op == XSDR:\n        tdi = bytes2hexString( f, Xsdrsize )\n        print(\"XSDR 0x%s\" % tdi)\n\n    elif op == XRUNTEST:\n        len = struct.unpack( '>i', f.read(4) )[0]\n        print(\"XRUNTEST 0x%08X\" % len)\n\n    elif op == XREPEAT:\n        len = ReadByte( f )\n        print(\"XREPEAT 0x%02X\" % len)\n\n    elif op == XSDRSIZE:\n        Xsdrsize = struct.unpack( '>i', f.read(4) )[0]\n        #print(\"XSDRSIZE 0x%08X\" % Xsdrsize, file=sys.stderr )\n        print(\"XSDRSIZE 0x%08X %d\" % (Xsdrsize, Xsdrsize) )\n\n    elif op == XSDRTDO:\n        tdi = bytes2hexString( f, Xsdrsize )\n        tdo = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRTDO 0x%s 0x%s\" % (tdi, tdo) )\n\n    elif op == XSETSDRMASKS:\n        addrmask = bytes2hexString( f, Xsdrsize )\n        datamask = ReadSDRMASKS( f, Xsdrsize )\n        print(\"XSETSDRMASKS 0x%s 0x%s\" % (addrmask, datamask) )\n\n    elif op == XSDRINC:\n        startaddr = bytes2hexString( f, Xsdrsize )\n        len = ReadByte(f)\n        print(\"XSDRINC 0x%s 0x%02X\" % (startaddr, len), end='' )\n        for numTimes in range(len):\n            data = bytes2hexString( f, SetsdrmasksOnesCount)\n            print(\" 0x%s\" % data )\n        print() # newline\n\n    elif op == XSDRB:\n        tdi = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRB 0x%s\" % tdi )\n\n    elif op == XSDRC:\n        tdi = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRC 0x%s\" % tdi )\n\n    elif op == XSDRE:\n        tdi = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRE 0x%s\" % tdi )\n\n    elif op == XSDRTDOB:\n        tdo = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRTDOB 0x%s\" % tdo )\n\n    elif op == XSDRTDOC:\n        tdi = bytes2hexString( f, Xsdrsize )\n        tdo = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRTDOC 0x%s 0x%s\" % (tdi, tdo) )\n\n    elif op == XSDRTDOE:\n        tdi = bytes2hexString( f, Xsdrsize )\n        tdo = bytes2hexString( f, Xsdrsize )\n        print(\"XSDRTDOE 0x%s 0x%s\" % (tdi, tdo) )\n\n    elif op == XSTATE:\n        b = ReadByte(f)\n        print(\"XSTATE %s\" % ShowState(b))\n\n    elif op == XENDIR:\n        b = ReadByte( f )\n        print(\"XENDIR %s\" % 'IRPAUSE' if b==1 else 'IDLE')\n\n    elif op == XENDDR:\n        b = ReadByte( f )\n        print(\"XENDDR %s\" % 'DRPAUSE' if b==1 else 'IDLE')\n\n    elif op == XSIR2:\n        len = struct.unpack( '>H', f.read(2) )[0]\n        buf = bytes2hexString( f, len )\n        print(\"XSIR2 0x%04X 0x%s\" % (len, buf))\n\n    elif op == XCOMMENT:\n        cmt = []\n        while 1:\n            b = ReadByte(f)\n            if b == 0:          # terminating nul\n                break;\n            cmt.append( chr(b) )\n        print(\"XCOMMENT \\\"%s\\\"\" % ''.join(cmt)  )\n\n    elif op == XWAIT:\n        run_state = ReadByte(f)\n        end_state = ReadByte(f)\n        useconds  = struct.unpack( '>i', f.read(4) )[0]\n        print(\"XWAIT %s %s\" % (ShowState(run_state), ShowState(end_state)), useconds)\n\n    elif op == XWAITSTATE:\n        run_state = ReadByte(f)\n        end_state = ReadByte(f)\n        clocks    = struct.unpack( '>i', f.read(4) )[0]\n        useconds  = struct.unpack( '>i', f.read(4) )[0]\n        print(\"XWAITSTATE %s %s CLOCKS=%d USECS=%d\" % (ShowState(run_state), ShowState(end_state), clocks, useconds) )\n\n    elif op == LCOUNT:\n        loop_count = struct.unpack( '>i', f.read(4) )[0]\n        print(\"LCOUNT\", loop_count )\n\n    elif op == LDELAY:\n        run_state = ReadByte(f)\n        clocks    = struct.unpack( '>i', f.read(4) )[0]\n        useconds  = struct.unpack( '>i', f.read(4) )[0]\n        print(\"LDELAY %s CLOCKS=%d USECS=%d\" % (ShowState(run_state), clocks, useconds) )\n\n    elif op == LSDR:\n        tdi = bytes2hexString( f, Xsdrsize )\n        tdo = bytes2hexString( f, Xsdrsize )\n        print(\"LSDR 0x%s 0x%s\" % (tdi, tdo) )\n\n    elif op == XTRST:\n        # the argument is a single byte and it is the index into \"trst_mode_allowed\"\n        trst_mode = ReadByte(f)\n        if trst_mode <= 3:\n            print(\"TRST %s\" % trst_mode_allowed[trst_mode] )\n        else:\n            print(\"TRST 0x%02X\" % trst_mode );\n\n    else:\n        print(\"UNKNOWN op 0x%02X %d\" % (op, op))\n        exit(1)\n\n\ndef main():\n\n    if len( sys.argv ) < 2:\n        print(\"usage %s <xsvf_filename>\" % sys.argv[0])\n        exit(1)\n\n    f = open( sys.argv[1], 'rb' )\n\n    opcode = ReadByte( f )\n    while opcode != -1:\n        # print the position within the file, then the command\n        print( \"%d: \" % f.tell(), end='' )\n        ShowOpcode( opcode, f )\n        opcode = ReadByte(f)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/.gitattributes",
    "content": "# Avoid DOS conversion of texinfo files during git clone\n*.texi\ttext eol=lf\n*.txt\ttext eol=lf\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/Makefile.am",
    "content": "info_TEXINFOS += %D%/openocd.texi\n%C%_openocd_TEXINFOS = %D%/fdl.texi\n\ndist_man_MANS += %D%/openocd.1\n\nEXTRA_DIST += %D%/manual\n\nMAINTAINERCLEANFILES += \\\n\t%D%/mdate-sh \\\n\t%D%/stamp-vti \\\n\t%D%/version.texi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/checkpatch.rst",
    "content": ".. SPDX-License-Identifier: GPL-2.0-only\n\n==========\nCheckpatch\n==========\n\nCheckpatch (scripts/checkpatch.pl) is a perl script which checks for trivial\nstyle violations in patches and optionally corrects them.  Checkpatch can\nalso be run on file contexts and without the kernel tree.\n\nCheckpatch is not always right. Your judgement takes precedence over checkpatch\nmessages.  If your code looks better with the violations, then its probably\nbest left alone.\n\n\nOptions\n=======\n\nThis section will describe the options checkpatch can be run with.\n\nUsage::\n\n  ./scripts/checkpatch.pl [OPTION]... [FILE]...\n\nAvailable options:\n\n - -q,  --quiet\n\n   Enable quiet mode.\n\n - -v,  --verbose\n   Enable verbose mode.  Additional verbose test descriptions are output\n   so as to provide information on why that particular message is shown.\n\n - --no-tree\n\n   Run checkpatch without the kernel tree.\n\n - --no-signoff\n\n   Disable the 'Signed-off-by' line check.  The sign-off is a simple line at\n   the end of the explanation for the patch, which certifies that you wrote it\n   or otherwise have the right to pass it on as an open-source patch.\n\n   Example::\n\n\t Signed-off-by: Random J Developer <random@developer.example.org>\n\n   Setting this flag effectively stops a message for a missing signed-off-by\n   line in a patch context.\n\n - --patch\n\n   Treat FILE as a patch.  This is the default option and need not be\n   explicitly specified.\n\n - --emacs\n\n   Set output to emacs compile window format.  This allows emacs users to jump\n   from the error in the compile window directly to the offending line in the\n   patch.\n\n - --terse\n\n   Output only one line per report.\n\n - --showfile\n\n   Show the diffed file position instead of the input file position.\n\n - -g,  --git\n\n   Treat FILE as a single commit or a git revision range.\n\n   Single commit with:\n\n   - <rev>\n   - <rev>^\n   - <rev>~n\n\n   Multiple commits with:\n\n   - <rev1>..<rev2>\n   - <rev1>...<rev2>\n   - <rev>-<count>\n\n - -f,  --file\n\n   Treat FILE as a regular source file.  This option must be used when running\n   checkpatch on source files in the kernel.\n\n - --subjective,  --strict\n\n   Enable stricter tests in checkpatch.  By default the tests emitted as CHECK\n   do not activate by default.  Use this flag to activate the CHECK tests.\n\n - --list-types\n\n   Every message emitted by checkpatch has an associated TYPE.  Add this flag\n   to display all the types in checkpatch.\n\n   Note that when this flag is active, checkpatch does not read the input FILE,\n   and no message is emitted.  Only a list of types in checkpatch is output.\n\n - --types TYPE(,TYPE2...)\n\n   Only display messages with the given types.\n\n   Example::\n\n     ./scripts/checkpatch.pl mypatch.patch --types EMAIL_SUBJECT,BRACES\n\n - --ignore TYPE(,TYPE2...)\n\n   Checkpatch will not emit messages for the specified types.\n\n   Example::\n\n     ./scripts/checkpatch.pl mypatch.patch --ignore EMAIL_SUBJECT,BRACES\n\n - --show-types\n\n   By default checkpatch doesn't display the type associated with the messages.\n   Set this flag to show the message type in the output.\n\n - --max-line-length=n\n\n   Set the max line length (default 100).  If a line exceeds the specified\n   length, a LONG_LINE message is emitted.\n\n\n   The message level is different for patch and file contexts.  For patches,\n   a WARNING is emitted.  While a milder CHECK is emitted for files.  So for\n   file contexts, the --strict flag must also be enabled.\n\n - --min-conf-desc-length=n\n\n   Set the Kconfig entry minimum description length, if shorter, warn.\n\n - --tab-size=n\n\n   Set the number of spaces for tab (default 8).\n\n - --root=PATH\n\n   PATH to the kernel tree root.\n\n   This option must be specified when invoking checkpatch from outside\n   the kernel root.\n\n - --no-summary\n\n   Suppress the per file summary.\n\n - --mailback\n\n   Only produce a report in case of Warnings or Errors.  Milder Checks are\n   excluded from this.\n\n - --summary-file\n\n   Include the filename in summary.\n\n - --debug KEY=[0|1]\n\n   Turn on/off debugging of KEY, where KEY is one of 'values', 'possible',\n   'type', and 'attr' (default is all off).\n\n - --fix\n\n   This is an EXPERIMENTAL feature.  If correctable errors exists, a file\n   <inputfile>.EXPERIMENTAL-checkpatch-fixes is created which has the\n   automatically fixable errors corrected.\n\n - --fix-inplace\n\n   EXPERIMENTAL - Similar to --fix but input file is overwritten with fixes.\n\n   DO NOT USE this flag unless you are absolutely sure and you have a backup\n   in place.\n\n - --ignore-perl-version\n\n   Override checking of perl version.  Runtime errors maybe encountered after\n   enabling this flag if the perl version does not meet the minimum specified.\n\n - --codespell\n\n   Use the codespell dictionary for checking spelling errors.\n\n - --codespellfile\n\n   Use the specified codespell file.\n   Default is '/usr/share/codespell/dictionary.txt'.\n\n - --typedefsfile\n\n   Read additional types from this file.\n\n - --color[=WHEN]\n\n   Use colors 'always', 'never', or only when output is a terminal ('auto').\n   Default is 'auto'.\n\n - --kconfig-prefix=WORD\n\n   Use WORD as a prefix for Kconfig symbols (default is `CONFIG_`).\n\n - -h, --help, --version\n\n   Display the help text.\n\nMessage Levels\n==============\n\nMessages in checkpatch are divided into three levels. The levels of messages\nin checkpatch denote the severity of the error. They are:\n\n - ERROR\n\n   This is the most strict level.  Messages of type ERROR must be taken\n   seriously as they denote things that are very likely to be wrong.\n\n - WARNING\n\n   This is the next stricter level.  Messages of type WARNING requires a\n   more careful review.  But it is milder than an ERROR.\n\n - CHECK\n\n   This is the mildest level.  These are things which may require some thought.\n\nType Descriptions\n=================\n\nThis section contains a description of all the message types in checkpatch.\n\n.. Types in this section are also parsed by checkpatch.\n.. The types are grouped into subsections based on use.\n\n\nAllocation style\n----------------\n\n  **ALLOC_ARRAY_ARGS**\n    The first argument for kcalloc or kmalloc_array should be the\n    number of elements.  sizeof() as the first argument is generally\n    wrong.\n\n    See: https://www.kernel.org/doc/html/latest/core-api/memory-allocation.html\n\n  **ALLOC_SIZEOF_STRUCT**\n    The allocation style is bad.  In general for family of\n    allocation functions using sizeof() to get memory size,\n    constructs like::\n\n      p = alloc(sizeof(struct foo), ...)\n\n    should be::\n\n      p = alloc(sizeof(*p), ...)\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#allocating-memory\n\n  **ALLOC_WITH_MULTIPLY**\n    Prefer kmalloc_array/kcalloc over kmalloc/kzalloc with a\n    sizeof multiply.\n\n    See: https://www.kernel.org/doc/html/latest/core-api/memory-allocation.html\n\n\nAPI usage\n---------\n\n  **ARCH_DEFINES**\n    Architecture specific defines should be avoided wherever\n    possible.\n\n  **ARCH_INCLUDE_LINUX**\n    Whenever asm/file.h is included and linux/file.h exists, a\n    conversion can be made when linux/file.h includes asm/file.h.\n    However this is not always the case (See signal.h).\n    This message type is emitted only for includes from arch/.\n\n  **AVOID_BUG**\n    BUG() or BUG_ON() should be avoided totally.\n    Use WARN() and WARN_ON() instead, and handle the \"impossible\"\n    error condition as gracefully as possible.\n\n    See: https://www.kernel.org/doc/html/latest/process/deprecated.html#bug-and-bug-on\n\n  **CONSIDER_KSTRTO**\n    The simple_strtol(), simple_strtoll(), simple_strtoul(), and\n    simple_strtoull() functions explicitly ignore overflows, which\n    may lead to unexpected results in callers.  The respective kstrtol(),\n    kstrtoll(), kstrtoul(), and kstrtoull() functions tend to be the\n    correct replacements.\n\n    See: https://www.kernel.org/doc/html/latest/process/deprecated.html#simple-strtol-simple-strtoll-simple-strtoul-simple-strtoull\n\n  **CONSTANT_CONVERSION**\n    Use of __constant_<foo> form is discouraged for the following functions::\n\n      __constant_cpu_to_be[x]\n      __constant_cpu_to_le[x]\n      __constant_be[x]_to_cpu\n      __constant_le[x]_to_cpu\n      __constant_htons\n      __constant_ntohs\n\n    Using any of these outside of include/uapi/ is not preferred as using the\n    function without __constant_ is identical when the argument is a\n    constant.\n\n    In big endian systems, the macros like __constant_cpu_to_be32(x) and\n    cpu_to_be32(x) expand to the same expression::\n\n      #define __constant_cpu_to_be32(x) ((__force __be32)(__u32)(x))\n      #define __cpu_to_be32(x)          ((__force __be32)(__u32)(x))\n\n    In little endian systems, the macros __constant_cpu_to_be32(x) and\n    cpu_to_be32(x) expand to __constant_swab32 and __swab32.  __swab32\n    has a __builtin_constant_p check::\n\n      #define __swab32(x)\t\t\t\t\\\n        (__builtin_constant_p((__u32)(x)) ?\t\\\n        ___constant_swab32(x) :\t\t\t\\\n        __fswab32(x))\n\n    So ultimately they have a special case for constants.\n    Similar is the case with all of the macros in the list.  Thus\n    using the __constant_... forms are unnecessarily verbose and\n    not preferred outside of include/uapi.\n\n    See: https://lore.kernel.org/lkml/1400106425.12666.6.camel@joe-AO725/\n\n  **DEPRECATED_API**\n    Usage of a deprecated RCU API is detected.  It is recommended to replace\n    old flavourful RCU APIs by their new vanilla-RCU counterparts.\n\n    The full list of available RCU APIs can be viewed from the kernel docs.\n\n    See: https://www.kernel.org/doc/html/latest/RCU/whatisRCU.html#full-list-of-rcu-apis\n\n  **DEPRECATED_VARIABLE**\n    EXTRA_{A,C,CPP,LD}FLAGS are deprecated and should be replaced by the new\n    flags added via commit f77bf01425b1 (\"kbuild: introduce ccflags-y,\n    asflags-y and ldflags-y\").\n\n    The following conversion scheme maybe used::\n\n      EXTRA_AFLAGS    ->  asflags-y\n      EXTRA_CFLAGS    ->  ccflags-y\n      EXTRA_CPPFLAGS  ->  cppflags-y\n      EXTRA_LDFLAGS   ->  ldflags-y\n\n    See:\n\n      1. https://lore.kernel.org/lkml/20070930191054.GA15876@uranus.ravnborg.org/\n      2. https://lore.kernel.org/lkml/1313384834-24433-12-git-send-email-lacombar@gmail.com/\n      3. https://www.kernel.org/doc/html/latest/kbuild/makefiles.html#compilation-flags\n\n  **DEVICE_ATTR_FUNCTIONS**\n    The function names used in DEVICE_ATTR is unusual.\n    Typically, the store and show functions are used with <attr>_store and\n    <attr>_show, where <attr> is a named attribute variable of the device.\n\n    Consider the following examples::\n\n      static DEVICE_ATTR(type, 0444, type_show, NULL);\n      static DEVICE_ATTR(power, 0644, power_show, power_store);\n\n    The function names should preferably follow the above pattern.\n\n    See: https://www.kernel.org/doc/html/latest/driver-api/driver-model/device.html#attributes\n\n  **DEVICE_ATTR_RO**\n    The DEVICE_ATTR_RO(name) helper macro can be used instead of\n    DEVICE_ATTR(name, 0444, name_show, NULL);\n\n    Note that the macro automatically appends _show to the named\n    attribute variable of the device for the show method.\n\n    See: https://www.kernel.org/doc/html/latest/driver-api/driver-model/device.html#attributes\n\n  **DEVICE_ATTR_RW**\n    The DEVICE_ATTR_RW(name) helper macro can be used instead of\n    DEVICE_ATTR(name, 0644, name_show, name_store);\n\n    Note that the macro automatically appends _show and _store to the\n    named attribute variable of the device for the show and store methods.\n\n    See: https://www.kernel.org/doc/html/latest/driver-api/driver-model/device.html#attributes\n\n  **DEVICE_ATTR_WO**\n    The DEVICE_AATR_WO(name) helper macro can be used instead of\n    DEVICE_ATTR(name, 0200, NULL, name_store);\n\n    Note that the macro automatically appends _store to the\n    named attribute variable of the device for the store method.\n\n    See: https://www.kernel.org/doc/html/latest/driver-api/driver-model/device.html#attributes\n\n  **DUPLICATED_SYSCTL_CONST**\n    Commit d91bff3011cf (\"proc/sysctl: add shared variables for range\n    check\") added some shared const variables to be used instead of a local\n    copy in each source file.\n\n    Consider replacing the sysctl range checking value with the shared\n    one in include/linux/sysctl.h.  The following conversion scheme may\n    be used::\n\n      &zero     ->  SYSCTL_ZERO\n      &one      ->  SYSCTL_ONE\n      &int_max  ->  SYSCTL_INT_MAX\n\n    See:\n\n      1. https://lore.kernel.org/lkml/20190430180111.10688-1-mcroce@redhat.com/\n      2. https://lore.kernel.org/lkml/20190531131422.14970-1-mcroce@redhat.com/\n\n  **ENOSYS**\n    ENOSYS means that a nonexistent system call was called.\n    Earlier, it was wrongly used for things like invalid operations on\n    otherwise valid syscalls.  This should be avoided in new code.\n\n    See: https://lore.kernel.org/lkml/5eb299021dec23c1a48fa7d9f2c8b794e967766d.1408730669.git.luto@amacapital.net/\n\n  **ENOTSUPP**\n    ENOTSUPP is not a standard error code and should be avoided in new patches.\n    EOPNOTSUPP should be used instead.\n\n    See: https://lore.kernel.org/netdev/20200510182252.GA411829@lunn.ch/\n\n  **EXPORT_SYMBOL**\n    EXPORT_SYMBOL should immediately follow the symbol to be exported.\n\n  **IN_ATOMIC**\n    in_atomic() is not for driver use so any such use is reported as an ERROR.\n    Also in_atomic() is often used to determine if sleeping is permitted,\n    but it is not reliable in this use model.  Therefore its use is\n    strongly discouraged.\n\n    However, in_atomic() is ok for core kernel use.\n\n    See: https://lore.kernel.org/lkml/20080320201723.b87b3732.akpm@linux-foundation.org/\n\n  **LOCKDEP**\n    The lockdep_no_validate class was added as a temporary measure to\n    prevent warnings on conversion of device->sem to device->mutex.\n    It should not be used for any other purpose.\n\n    See: https://lore.kernel.org/lkml/1268959062.9440.467.camel@laptop/\n\n  **MALFORMED_INCLUDE**\n    The #include statement has a malformed path.  This has happened\n    because the author has included a double slash \"//\" in the pathname\n    accidentally.\n\n  **USE_LOCKDEP**\n    lockdep_assert_held() annotations should be preferred over\n    assertions based on spin_is_locked()\n\n    See: https://www.kernel.org/doc/html/latest/locking/lockdep-design.html#annotations\n\n  **UAPI_INCLUDE**\n    No #include statements in include/uapi should use a uapi/ path.\n\n  **USLEEP_RANGE**\n    usleep_range() should be preferred over udelay(). The proper way of\n    using usleep_range() is mentioned in the kernel docs.\n\n    See: https://www.kernel.org/doc/html/latest/timers/timers-howto.html#delays-information-on-the-various-kernel-delay-sleep-mechanisms\n\n\nComments\n--------\n\n  **BLOCK_COMMENT_STYLE**\n    The comment style is incorrect.  The preferred style for multi-\n    line comments is::\n\n      /*\n      * This is the preferred style\n      * for multi line comments.\n      */\n\n    The networking comment style is a bit different, with the first line\n    not empty like the former::\n\n      /* This is the preferred comment style\n      * for files in net/ and drivers/net/\n      */\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting\n\n  **C99_COMMENTS**\n    C99 style single line comments (//) should not be used.\n    Prefer the block comment style instead.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#commenting\n\n  **DATA_RACE**\n    Applications of data_race() should have a comment so as to document the\n    reasoning behind why it was deemed safe.\n\n    See: https://lore.kernel.org/lkml/20200401101714.44781-1-elver@google.com/\n\n  **FSF_MAILING_ADDRESS**\n    Kernel maintainers reject new instances of the GPL boilerplate paragraph\n    directing people to write to the FSF for a copy of the GPL, since the\n    FSF has moved in the past and may do so again.\n    So do not write paragraphs about writing to the Free Software Foundation's\n    mailing address.\n\n    See: https://lore.kernel.org/lkml/20131006222342.GT19510@leaf/\n\n\nCommit message\n--------------\n\n  **BAD_SIGN_OFF**\n    The signed-off-by line does not fall in line with the standards\n    specified by the community.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#developer-s-certificate-of-origin-1-1\n\n  **BAD_STABLE_ADDRESS_STYLE**\n    The email format for stable is incorrect.\n    Some valid options for stable address are::\n\n      1. stable@vger.kernel.org\n      2. stable@kernel.org\n\n    For adding version info, the following comment style should be used::\n\n      stable@vger.kernel.org # version info\n\n  **COMMIT_COMMENT_SYMBOL**\n    Commit log lines starting with a '#' are ignored by git as\n    comments.  To solve this problem addition of a single space\n    infront of the log line is enough.\n\n  **COMMIT_MESSAGE**\n    The patch is missing a commit description.  A brief\n    description of the changes made by the patch should be added.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes\n\n  **EMAIL_SUBJECT**\n    Naming the tool that found the issue is not very useful in the\n    subject line.  A good subject line summarizes the change that\n    the patch brings.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes\n\n  **FROM_SIGN_OFF_MISMATCH**\n    The author's email does not match with that in the Signed-off-by:\n    line(s). This can be sometimes caused due to an improperly configured\n    email client.\n\n    This message is emitted due to any of the following reasons::\n\n      - The email names do not match.\n      - The email addresses do not match.\n      - The email subaddresses do not match.\n      - The email comments do not match.\n\n  **MISSING_SIGN_OFF**\n    The patch is missing a Signed-off-by line.  A signed-off-by\n    line should be added according to Developer's certificate of\n    Origin.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin\n\n  **NO_AUTHOR_SIGN_OFF**\n    The author of the patch has not signed off the patch.  It is\n    required that a simple sign off line should be present at the\n    end of explanation of the patch to denote that the author has\n    written it or otherwise has the rights to pass it on as an open\n    source patch.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#sign-your-work-the-developer-s-certificate-of-origin\n\n  **DIFF_IN_COMMIT_MSG**\n    Avoid having diff content in commit message.\n    This causes problems when one tries to apply a file containing both\n    the changelog and the diff because patch(1) tries to apply the diff\n    which it found in the changelog.\n\n    See: https://lore.kernel.org/lkml/20150611134006.9df79a893e3636019ad2759e@linux-foundation.org/\n\n  **GERRIT_CHANGE_ID**\n    To be picked up by gerrit, the footer of the commit message might\n    have a Change-Id like::\n\n      Change-Id: Ic8aaa0728a43936cd4c6e1ed590e01ba8f0fbf5b\n      Signed-off-by: A. U. Thor <author@example.com>\n\n    The Change-Id line must be removed before submitting.\n\n  **GIT_COMMIT_ID**\n    The proper way to reference a commit id is:\n    commit <12+ chars of sha1> (\"<title line>\")\n\n    An example may be::\n\n      Commit e21d2170f36602ae2708 (\"video: remove unnecessary\n      platform_set_drvdata()\") removed the unnecessary\n      platform_set_drvdata(), but left the variable \"dev\" unused,\n      delete it.\n\n    See: https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes\n\n\nComparison style\n----------------\n\n  **ASSIGN_IN_IF**\n    Do not use assignments in if condition.\n    Example::\n\n      if ((foo = bar(...)) < BAZ) {\n\n    should be written as::\n\n      foo = bar(...);\n      if (foo < BAZ) {\n\n  **BOOL_COMPARISON**\n    Comparisons of A to true and false are better written\n    as A and !A.\n\n    See: https://lore.kernel.org/lkml/1365563834.27174.12.camel@joe-AO722/\n\n  **COMPARISON_TO_NULL**\n    Comparisons to NULL in the form (foo == NULL) or (foo != NULL)\n    are better written as (!foo) and (foo).\n\n  **CONSTANT_COMPARISON**\n    Comparisons with a constant or upper case identifier on the left\n    side of the test should be avoided.\n\n\nIndentation and Line Breaks\n---------------------------\n\n  **CODE_INDENT**\n    Code indent should use tabs instead of spaces.\n    Outside of comments, documentation and Kconfig,\n    spaces are never used for indentation.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#indentation\n\n  **DEEP_INDENTATION**\n    Indentation with 6 or more tabs usually indicate overly indented\n    code.\n\n    It is suggested to refactor excessive indentation of\n    if/else/for/do/while/switch statements.\n\n    See: https://lore.kernel.org/lkml/1328311239.21255.24.camel@joe2Laptop/\n\n  **SWITCH_CASE_INDENT_LEVEL**\n    switch should be at the same indent as case.\n    Example::\n\n      switch (suffix) {\n      case 'G':\n      case 'g':\n              mem <<= 30;\n              break;\n      case 'M':\n      case 'm':\n              mem <<= 20;\n              break;\n      case 'K':\n      case 'k':\n              mem <<= 10;\n              fallthrough;\n      default:\n              break;\n      }\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#indentation\n\n  **LONG_LINE**\n    The line has exceeded the specified maximum length.\n    To use a different maximum line length, the --max-line-length=n option\n    may be added while invoking checkpatch.\n\n    Earlier, the default line length was 80 columns.  Commit bdc48fa11e46\n    (\"checkpatch/coding-style: deprecate 80-column warning\") increased the\n    limit to 100 columns.  This is not a hard limit either and it's\n    preferable to stay within 80 columns whenever possible.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#breaking-long-lines-and-strings\n\n  **LONG_LINE_STRING**\n    A string starts before but extends beyond the maximum line length.\n    To use a different maximum line length, the --max-line-length=n option\n    may be added while invoking checkpatch.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#breaking-long-lines-and-strings\n\n  **LONG_LINE_COMMENT**\n    A comment starts before but extends beyond the maximum line length.\n    To use a different maximum line length, the --max-line-length=n option\n    may be added while invoking checkpatch.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#breaking-long-lines-and-strings\n\n  **SPLIT_STRING**\n    Quoted strings that appear as messages in userspace and can be\n    grepped, should not be split across multiple lines.\n\n    See: https://lore.kernel.org/lkml/20120203052727.GA15035@leaf/\n\n  **MULTILINE_DEREFERENCE**\n    A single dereferencing identifier spanned on multiple lines like::\n\n      struct_identifier->member[index].\n      member = <foo>;\n\n    is generally hard to follow. It can easily lead to typos and so makes\n    the code vulnerable to bugs.\n\n    If fixing the multiple line dereferencing leads to an 80 column\n    violation, then either rewrite the code in a more simple way or if the\n    starting part of the dereferencing identifier is the same and used at\n    multiple places then store it in a temporary variable, and use that\n    temporary variable only at all the places. For example, if there are\n    two dereferencing identifiers::\n\n      member1->member2->member3.foo1;\n      member1->member2->member3.foo2;\n\n    then store the member1->member2->member3 part in a temporary variable.\n    It not only helps to avoid the 80 column violation but also reduces\n    the program size by removing the unnecessary dereferences.\n\n    But if none of the above methods work then ignore the 80 column\n    violation because it is much easier to read a dereferencing identifier\n    on a single line.\n\n  **TRAILING_STATEMENTS**\n    Trailing statements (for example after any conditional) should be\n    on the next line.\n    Statements, such as::\n\n      if (x == y) break;\n\n    should be::\n\n      if (x == y)\n              break;\n\n\nMacros, Attributes and Symbols\n------------------------------\n\n  **ARRAY_SIZE**\n    The ARRAY_SIZE(foo) macro should be preferred over\n    sizeof(foo)/sizeof(foo[0]) for finding number of elements in an\n    array.\n\n    The macro is defined in include/linux/kernel.h::\n\n      #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n  **AVOID_EXTERNS**\n    Function prototypes don't need to be declared extern in .h\n    files.  It's assumed by the compiler and is unnecessary.\n\n  **AVOID_L_PREFIX**\n    Local symbol names that are prefixed with `.L` should be avoided,\n    as this has special meaning for the assembler; a symbol entry will\n    not be emitted into the symbol table.  This can prevent `objtool`\n    from generating correct unwind info.\n\n    Symbols with STB_LOCAL binding may still be used, and `.L` prefixed\n    local symbol names are still generally usable within a function,\n    but `.L` prefixed local symbol names should not be used to denote\n    the beginning or end of code regions via\n    `SYM_CODE_START_LOCAL`/`SYM_CODE_END`\n\n  **BIT_MACRO**\n    Defines like: 1 << <digit> could be BIT(digit).\n    The BIT() macro is defined via include/linux/bits.h::\n\n      #define BIT(nr)         (1UL << (nr))\n\n  **CONST_READ_MOSTLY**\n    When a variable is tagged with the __read_mostly annotation, it is a\n    signal to the compiler that accesses to the variable will be mostly\n    reads and rarely(but NOT never) a write.\n\n    const __read_mostly does not make any sense as const data is already\n    read-only.  The __read_mostly annotation thus should be removed.\n\n  **DATE_TIME**\n    It is generally desirable that building the same source code with\n    the same set of tools is reproducible, i.e. the output is always\n    exactly the same.\n\n    The kernel does *not* use the ``__DATE__`` and ``__TIME__`` macros,\n    and enables warnings if they are used as they can lead to\n    non-deterministic builds.\n\n    See: https://www.kernel.org/doc/html/latest/kbuild/reproducible-builds.html#timestamps\n\n  **DEFINE_ARCH_HAS**\n    The ARCH_HAS_xyz and ARCH_HAVE_xyz patterns are wrong.\n\n    For big conceptual features use Kconfig symbols instead.  And for\n    smaller things where we have compatibility fallback functions but\n    want architectures able to override them with optimized ones, we\n    should either use weak functions (appropriate for some cases), or\n    the symbol that protects them should be the same symbol we use.\n\n    See: https://lore.kernel.org/lkml/CA+55aFycQ9XJvEOsiM3txHL5bjUc8CeKWJNR_H+MiicaddB42Q@mail.gmail.com/\n\n  **DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON**\n    do {} while(0) macros should not have a trailing semicolon.\n\n  **INIT_ATTRIBUTE**\n    Const init definitions should use __initconst instead of\n    __initdata.\n\n    Similarly init definitions without const require a separate\n    use of const.\n\n  **INLINE_LOCATION**\n    The inline keyword should sit between storage class and type.\n\n    For example, the following segment::\n\n      inline static int example_function(void)\n      {\n              ...\n      }\n\n    should be::\n\n      static inline int example_function(void)\n      {\n              ...\n      }\n\n  **MISPLACED_INIT**\n    It is possible to use section markers on variables in a way\n    which gcc doesn't understand (or at least not the way the\n    developer intended)::\n\n      static struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {\n\n    does not put exynos4_plls in the .initdata section. The __initdata\n    marker can be virtually anywhere on the line, except right after\n    \"struct\". The preferred location is before the \"=\" sign if there is\n    one, or before the trailing \";\" otherwise.\n\n    See: https://lore.kernel.org/lkml/1377655732.3619.19.camel@joe-AO722/\n\n  **MULTISTATEMENT_MACRO_USE_DO_WHILE**\n    Macros with multiple statements should be enclosed in a\n    do - while block.  Same should also be the case for macros\n    starting with `if` to avoid logic defects::\n\n      #define macrofun(a, b, c)                 \\\n        do {                                    \\\n                if (a == 5)                     \\\n                        do_this(b, c);          \\\n        } while (0)\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#macros-enums-and-rtl\n\n  **PREFER_FALLTHROUGH**\n    Use the `fallthrough;` pseudo keyword instead of\n    `/* fallthrough */` like comments.\n\n  **TRAILING_SEMICOLON**\n    Macro definition should not end with a semicolon. The macro\n    invocation style should be consistent with function calls.\n    This can prevent any unexpected code paths::\n\n      #define MAC do_something;\n\n    If this macro is used within a if else statement, like::\n\n      if (some_condition)\n              MAC;\n\n      else\n              do_something;\n\n    Then there would be a compilation error, because when the macro is\n    expanded there are two trailing semicolons, so the else branch gets\n    orphaned.\n\n    See: https://lore.kernel.org/lkml/1399671106.2912.21.camel@joe-AO725/\n\n  **SINGLE_STATEMENT_DO_WHILE_MACRO**\n    For the multi-statement macros, it is necessary to use the do-while\n    loop to avoid unpredictable code paths. The do-while loop helps to\n    group the multiple statements into a single one so that a\n    function-like macro can be used as a function only.\n\n    But for the single statement macros, it is unnecessary to use the\n    do-while loop. Although the code is syntactically correct but using\n    the do-while loop is redundant. So remove the do-while loop for single\n    statement macros.\n\n  **WEAK_DECLARATION**\n    Using weak declarations like __attribute__((weak)) or __weak\n    can have unintended link defects.  Avoid using them.\n\n\nFunctions and Variables\n-----------------------\n\n  **CAMELCASE**\n    Avoid CamelCase Identifiers.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#naming\n\n  **CONST_CONST**\n    Using `const <type> const *` is generally meant to be\n    written `const <type> * const`.\n\n  **CONST_STRUCT**\n    Using const is generally a good idea.  Checkpatch reads\n    a list of frequently used structs that are always or\n    almost always constant.\n\n    The existing structs list can be viewed from\n    `scripts/const_structs.checkpatch`.\n\n    See: https://lore.kernel.org/lkml/alpine.DEB.2.10.1608281509480.3321@hadrien/\n\n  **EMBEDDED_FUNCTION_NAME**\n    Embedded function names are less appropriate to use as\n    refactoring can cause function renaming.  Prefer the use of\n    \"%s\", __func__ to embedded function names.\n\n    Note that this does not work with -f (--file) checkpatch option\n    as it depends on patch context providing the function name.\n\n  **FUNCTION_ARGUMENTS**\n    This warning is emitted due to any of the following reasons:\n\n      1. Arguments for the function declaration do not follow\n         the identifier name.  Example::\n\n           void foo\n           (int bar, int baz)\n\n         This should be corrected to::\n\n           void foo(int bar, int baz)\n\n      2. Some arguments for the function definition do not\n         have an identifier name.  Example::\n\n           void foo(int)\n\n         All arguments should have identifier names.\n\n  **FUNCTION_WITHOUT_ARGS**\n    Function declarations without arguments like::\n\n      int foo()\n\n    should be::\n\n      int foo(void)\n\n  **GLOBAL_INITIALISERS**\n    Global variables should not be initialized explicitly to\n    0 (or NULL, false, etc.).  Your compiler (or rather your\n    loader, which is responsible for zeroing out the relevant\n    sections) automatically does it for you.\n\n  **INITIALISED_STATIC**\n    Static variables should not be initialized explicitly to zero.\n    Your compiler (or rather your loader) automatically does\n    it for you.\n\n  **MULTIPLE_ASSIGNMENTS**\n    Multiple assignments on a single line makes the code unnecessarily\n    complicated. So on a single line assign value to a single variable\n    only, this makes the code more readable and helps avoid typos.\n\n  **RETURN_PARENTHESES**\n    return is not a function and as such doesn't need parentheses::\n\n      return (bar);\n\n    can simply be::\n\n      return bar;\n\n\nPermissions\n-----------\n\n  **DEVICE_ATTR_PERMS**\n    The permissions used in DEVICE_ATTR are unusual.\n    Typically only three permissions are used - 0644 (RW), 0444 (RO)\n    and 0200 (WO).\n\n    See: https://www.kernel.org/doc/html/latest/filesystems/sysfs.html#attributes\n\n  **EXECUTE_PERMISSIONS**\n    There is no reason for source files to be executable.  The executable\n    bit can be removed safely.\n\n  **EXPORTED_WORLD_WRITABLE**\n    Exporting world writable sysfs/debugfs files is usually a bad thing.\n    When done arbitrarily they can introduce serious security bugs.\n    In the past, some of the debugfs vulnerabilities would seemingly allow\n    any local user to write arbitrary values into device registers - a\n    situation from which little good can be expected to emerge.\n\n    See: https://lore.kernel.org/linux-arm-kernel/cover.1296818921.git.segoon@openwall.com/\n\n  **NON_OCTAL_PERMISSIONS**\n    Permission bits should use 4 digit octal permissions (like 0700 or 0444).\n    Avoid using any other base like decimal.\n\n  **SYMBOLIC_PERMS**\n    Permission bits in the octal form are more readable and easier to\n    understand than their symbolic counterparts because many command-line\n    tools use this notation. Experienced kernel developers have been using\n    these traditional Unix permission bits for decades and so they find it\n    easier to understand the octal notation than the symbolic macros.\n    For example, it is harder to read S_IWUSR|S_IRUGO than 0644, which\n    obscures the developer's intent rather than clarifying it.\n\n    See: https://lore.kernel.org/lkml/CA+55aFw5v23T-zvDZp-MmD_EYxF8WbafwwB59934FV7g21uMGQ@mail.gmail.com/\n\n\nSpacing and Brackets\n--------------------\n\n  **ASSIGNMENT_CONTINUATIONS**\n    Assignment operators should not be written at the start of a\n    line but should follow the operand at the previous line.\n\n  **BRACES**\n    The placement of braces is stylistically incorrect.\n    The preferred way is to put the opening brace last on the line,\n    and put the closing brace first::\n\n      if (x is true) {\n              we do y\n      }\n\n    This applies for all non-functional blocks.\n    However, there is one special case, namely functions: they have the\n    opening brace at the beginning of the next line, thus::\n\n      int function(int x)\n      {\n              body of function\n      }\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces\n\n  **BRACKET_SPACE**\n    Whitespace before opening bracket '[' is prohibited.\n    There are some exceptions:\n\n    1. With a type on the left::\n\n        int [] a;\n\n    2. At the beginning of a line for slice initialisers::\n\n        [0...10] = 5,\n\n    3. Inside a curly brace::\n\n        = { [0...10] = 5 }\n\n  **CONCATENATED_STRING**\n    Concatenated elements should have a space in between.\n    Example::\n\n      printk(KERN_INFO\"bar\");\n\n    should be::\n\n      printk(KERN_INFO \"bar\");\n\n  **ELSE_AFTER_BRACE**\n    `else {` should follow the closing block `}` on the same line.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces\n\n  **LINE_SPACING**\n    Vertical space is wasted given the limited number of lines an\n    editor window can display when multiple blank lines are used.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces\n\n  **OPEN_BRACE**\n    The opening brace should be following the function definitions on the\n    next line.  For any non-functional block it should be on the same line\n    as the last construct.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces\n\n  **POINTER_LOCATION**\n    When using pointer data or a function that returns a pointer type,\n    the preferred use of * is adjacent to the data name or function name\n    and not adjacent to the type name.\n    Examples::\n\n      char *linux_banner;\n      unsigned long long memparse(char *ptr, char **retptr);\n      char *match_strdup(substring_t *s);\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces\n\n  **SPACING**\n    Whitespace style used in the kernel sources is described in kernel docs.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces\n\n  **TRAILING_WHITESPACE**\n    Trailing whitespace should always be removed.\n    Some editors highlight the trailing whitespace and cause visual\n    distractions when editing files.\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#spaces\n\n  **UNNECESSARY_PARENTHESES**\n    Parentheses are not required in the following cases:\n\n      1. Function pointer uses::\n\n          (foo->bar)();\n\n        could be::\n\n          foo->bar();\n\n      2. Comparisons in if::\n\n          if ((foo->bar) && (foo->baz))\n          if ((foo == bar))\n\n        could be::\n\n          if (foo->bar && foo->baz)\n          if (foo == bar)\n\n      3. addressof/dereference single Lvalues::\n\n          &(foo->bar)\n          *(foo->bar)\n\n        could be::\n\n          &foo->bar\n          *foo->bar\n\n  **WHILE_AFTER_BRACE**\n    while should follow the closing bracket on the same line::\n\n      do {\n              ...\n      } while(something);\n\n    See: https://www.kernel.org/doc/html/latest/process/coding-style.html#placing-braces-and-spaces\n\n\nOthers\n------\n\n  **CONFIG_DESCRIPTION**\n    Kconfig symbols should have a help text which fully describes\n    it.\n\n  **CORRUPTED_PATCH**\n    The patch seems to be corrupted or lines are wrapped.\n    Please regenerate the patch file before sending it to the maintainer.\n\n  **CVS_KEYWORD**\n    Since linux moved to git, the CVS markers are no longer used.\n    So, CVS style keywords ($Id$, $Revision$, $Log$) should not be\n    added.\n\n  **DEFAULT_NO_BREAK**\n    switch default case is sometimes written as \"default:;\".  This can\n    cause new cases added below default to be defective.\n\n    A \"break;\" should be added after empty default statement to avoid\n    unwanted fallthrough.\n\n  **DOS_LINE_ENDINGS**\n    For DOS-formatted patches, there are extra ^M symbols at the end of\n    the line.  These should be removed.\n\n  **DT_SCHEMA_BINDING_PATCH**\n    DT bindings moved to a json-schema based format instead of\n    freeform text.\n\n    See: https://www.kernel.org/doc/html/latest/devicetree/bindings/writing-schema.html\n\n  **DT_SPLIT_BINDING_PATCH**\n    Devicetree bindings should be their own patch.  This is because\n    bindings are logically independent from a driver implementation,\n    they have a different maintainer (even though they often\n    are applied via the same tree), and it makes for a cleaner history in the\n    DT only tree created with git-filter-branch.\n\n    See: https://www.kernel.org/doc/html/latest/devicetree/bindings/submitting-patches.html#i-for-patch-submitters\n\n  **EMBEDDED_FILENAME**\n    Embedding the complete filename path inside the file isn't particularly\n    useful as often the path is moved around and becomes incorrect.\n\n  **FILE_PATH_CHANGES**\n    Whenever files are added, moved, or deleted, the MAINTAINERS file\n    patterns can be out of sync or outdated.\n\n    So MAINTAINERS might need updating in these cases.\n\n  **MEMSET**\n    The memset use appears to be incorrect.  This may be caused due to\n    badly ordered parameters.  Please recheck the usage.\n\n  **NOT_UNIFIED_DIFF**\n    The patch file does not appear to be in unified-diff format.  Please\n    regenerate the patch file before sending it to the maintainer.\n\n  **PRINTF_0XDECIMAL**\n    Prefixing 0x with decimal output is defective and should be corrected.\n\n  **SPDX_LICENSE_TAG**\n    The source file is missing or has an improper SPDX identifier tag.\n    The Linux kernel requires the precise SPDX identifier in all source files,\n    and it is thoroughly documented in the kernel docs.\n\n    See: https://www.kernel.org/doc/html/latest/process/license-rules.html\n\n  **TYPO_SPELLING**\n    Some words may have been misspelled.  Consider reviewing them.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/fdl.texi",
    "content": "@c -*-texinfo-*-\n@c The GNU Free Documentation License.\n@center Version 1.2, November 2002\n\n@c This file is intended to be included within another document,\n@c hence no sectioning command or @node.\n\n@display\nCopyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.\n51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA\n\nEveryone is permitted to copy and distribute verbatim copies\nof this license document, but changing it is not allowed.\n@end display\n\n@enumerate 0\n@item\nPREAMBLE\n\nThe purpose of this License is to make a manual, textbook, or other\nfunctional and useful document @dfn{free} in the sense of freedom: to\nassure everyone the effective freedom to copy and redistribute it,\nwith or without modifying it, either commercially or noncommercially.\nSecondarily, this License preserves for the author and publisher a way\nto get credit for their work, while not being considered responsible\nfor modifications made by others.\n\nThis License is a kind of ``copyleft'', which means that derivative\nworks of the document must themselves be free in the same sense.  It\ncomplements the GNU General Public License, which is a copyleft\nlicense designed for free software.\n\nWe have designed this License in order to use it for manuals for free\nsoftware, because free software needs free documentation: a free\nprogram should come with manuals providing the same freedoms that the\nsoftware does.  But this License is not limited to software manuals;\nit can be used for any textual work, regardless of subject matter or\nwhether it is published as a printed book.  We recommend this License\nprincipally for works whose purpose is instruction or reference.\n\n@item\nAPPLICABILITY AND DEFINITIONS\n\nThis License applies to any manual or other work, in any medium, that\ncontains a notice placed by the copyright holder saying it can be\ndistributed under the terms of this License.  Such a notice grants a\nworld-wide, royalty-free license, unlimited in duration, to use that\nwork under the conditions stated herein.  The ``Document'', below,\nrefers to any such manual or work.  Any member of the public is a\nlicensee, and is addressed as ``you''.  You accept the license if you\ncopy, modify or distribute the work in a way requiring permission\nunder copyright law.\n\nA ``Modified Version'' of the Document means any work containing the\nDocument or a portion of it, either copied verbatim, or with\nmodifications and/or translated into another language.\n\nA ``Secondary Section'' is a named appendix or a front-matter section\nof the Document that deals exclusively with the relationship of the\npublishers or authors of the Document to the Document's overall\nsubject (or to related matters) and contains nothing that could fall\ndirectly within that overall subject.  (Thus, if the Document is in\npart a textbook of mathematics, a Secondary Section may not explain\nany mathematics.)  The relationship could be a matter of historical\nconnection with the subject or with related matters, or of legal,\ncommercial, philosophical, ethical or political position regarding\nthem.\n\nThe ``Invariant Sections'' are certain Secondary Sections whose titles\nare designated, as being those of Invariant Sections, in the notice\nthat says that the Document is released under this License.  If a\nsection does not fit the above definition of Secondary then it is not\nallowed to be designated as Invariant.  The Document may contain zero\nInvariant Sections.  If the Document does not identify any Invariant\nSections then there are none.\n\nThe ``Cover Texts'' are certain short passages of text that are listed,\nas Front-Cover Texts or Back-Cover Texts, in the notice that says that\nthe Document is released under this License.  A Front-Cover Text may\nbe at most 5 words, and a Back-Cover Text may be at most 25 words.\n\nA ``Transparent'' copy of the Document means a machine-readable copy,\nrepresented in a format whose specification is available to the\ngeneral public, that is suitable for revising the document\nstraightforwardly with generic text editors or (for images composed of\npixels) generic paint programs or (for drawings) some widely available\ndrawing editor, and that is suitable for input to text formatters or\nfor automatic translation to a variety of formats suitable for input\nto text formatters.  A copy made in an otherwise Transparent file\nformat whose markup, or absence of markup, has been arranged to thwart\nor discourage subsequent modification by readers is not Transparent.\nAn image format is not Transparent if used for any substantial amount\nof text.  A copy that is not ``Transparent'' is called ``Opaque''.\n\nExamples of suitable formats for Transparent copies include plain\n@sc{ascii} without markup, Texinfo input format, La@TeX{} input\nformat, @acronym{SGML} or @acronym{XML} using a publicly available\n@acronym{DTD}, and standard-conforming simple @acronym{HTML},\nPostScript or @acronym{PDF} designed for human modification.  Examples\nof transparent image formats include @acronym{PNG}, @acronym{XCF} and\n@acronym{JPG}.  Opaque formats include proprietary formats that can be\nread and edited only by proprietary word processors, @acronym{SGML} or\n@acronym{XML} for which the @acronym{DTD} and/or processing tools are\nnot generally available, and the machine-generated @acronym{HTML},\nPostScript or @acronym{PDF} produced by some word processors for\noutput purposes only.\n\nThe ``Title Page'' means, for a printed book, the title page itself,\nplus such following pages as are needed to hold, legibly, the material\nthis License requires to appear in the title page.  For works in\nformats which do not have any title page as such, ``Title Page'' means\nthe text near the most prominent appearance of the work's title,\npreceding the beginning of the body of the text.\n\nA section ``Entitled XYZ'' means a named subunit of the Document whose\ntitle either is precisely XYZ or contains XYZ in parentheses following\ntext that translates XYZ in another language.  (Here XYZ stands for a\nspecific section name mentioned below, such as ``Acknowledgements'',\n``Dedications'', ``Endorsements'', or ``History''.)  To ``Preserve the Title''\nof such a section when you modify the Document means that it remains a\nsection ``Entitled XYZ'' according to this definition.\n\nThe Document may include Warranty Disclaimers next to the notice which\nstates that this License applies to the Document.  These Warranty\nDisclaimers are considered to be included by reference in this\nLicense, but only as regards disclaiming warranties: any other\nimplication that these Warranty Disclaimers may have is void and has\nno effect on the meaning of this License.\n\n@item\nVERBATIM COPYING\n\nYou may copy and distribute the Document in any medium, either\ncommercially or noncommercially, provided that this License, the\ncopyright notices, and the license notice saying this License applies\nto the Document are reproduced in all copies, and that you add no other\nconditions whatsoever to those of this License.  You may not use\ntechnical measures to obstruct or control the reading or further\ncopying of the copies you make or distribute.  However, you may accept\ncompensation in exchange for copies.  If you distribute a large enough\nnumber of copies you must also follow the conditions in section 3.\n\nYou may also lend copies, under the same conditions stated above, and\nyou may publicly display copies.\n\n@item\nCOPYING IN QUANTITY\n\nIf you publish printed copies (or copies in media that commonly have\nprinted covers) of the Document, numbering more than 100, and the\nDocument's license notice requires Cover Texts, you must enclose the\ncopies in covers that carry, clearly and legibly, all these Cover\nTexts: Front-Cover Texts on the front cover, and Back-Cover Texts on\nthe back cover.  Both covers must also clearly and legibly identify\nyou as the publisher of these copies.  The front cover must present\nthe full title with all words of the title equally prominent and\nvisible.  You may add other material on the covers in addition.\nCopying with changes limited to the covers, as long as they preserve\nthe title of the Document and satisfy these conditions, can be treated\nas verbatim copying in other respects.\n\nIf the required texts for either cover are too voluminous to fit\nlegibly, you should put the first ones listed (as many as fit\nreasonably) on the actual cover, and continue the rest onto adjacent\npages.\n\nIf you publish or distribute Opaque copies of the Document numbering\nmore than 100, you must either include a machine-readable Transparent\ncopy along with each Opaque copy, or state in or with each Opaque copy\na computer-network location from which the general network-using\npublic has access to download using public-standard network protocols\na complete Transparent copy of the Document, free of added material.\nIf you use the latter option, you must take reasonably prudent steps,\nwhen you begin distribution of Opaque copies in quantity, to ensure\nthat this Transparent copy will remain thus accessible at the stated\nlocation until at least one year after the last time you distribute an\nOpaque copy (directly or through your agents or retailers) of that\nedition to the public.\n\nIt is requested, but not required, that you contact the authors of the\nDocument well before redistributing any large number of copies, to give\nthem a chance to provide you with an updated version of the Document.\n\n@item\nMODIFICATIONS\n\nYou may copy and distribute a Modified Version of the Document under\nthe conditions of sections 2 and 3 above, provided that you release\nthe Modified Version under precisely this License, with the Modified\nVersion filling the role of the Document, thus licensing distribution\nand modification of the Modified Version to whoever possesses a copy\nof it.  In addition, you must do these things in the Modified Version:\n\n@enumerate A\n@item\nUse in the Title Page (and on the covers, if any) a title distinct\nfrom that of the Document, and from those of previous versions\n(which should, if there were any, be listed in the History section\nof the Document).  You may use the same title as a previous version\nif the original publisher of that version gives permission.\n\n@item\nList on the Title Page, as authors, one or more persons or entities\nresponsible for authorship of the modifications in the Modified\nVersion, together with at least five of the principal authors of the\nDocument (all of its principal authors, if it has fewer than five),\nunless they release you from this requirement.\n\n@item\nState on the Title page the name of the publisher of the\nModified Version, as the publisher.\n\n@item\nPreserve all the copyright notices of the Document.\n\n@item\nAdd an appropriate copyright notice for your modifications\nadjacent to the other copyright notices.\n\n@item\nInclude, immediately after the copyright notices, a license notice\ngiving the public permission to use the Modified Version under the\nterms of this License, in the form shown in the Addendum below.\n\n@item\nPreserve in that license notice the full lists of Invariant Sections\nand required Cover Texts given in the Document's license notice.\n\n@item\nInclude an unaltered copy of this License.\n\n@item\nPreserve the section Entitled ``History'', Preserve its Title, and add\nto it an item stating at least the title, year, new authors, and\npublisher of the Modified Version as given on the Title Page.  If\nthere is no section Entitled ``History'' in the Document, create one\nstating the title, year, authors, and publisher of the Document as\ngiven on its Title Page, then add an item describing the Modified\nVersion as stated in the previous sentence.\n\n@item\nPreserve the network location, if any, given in the Document for\npublic access to a Transparent copy of the Document, and likewise\nthe network locations given in the Document for previous versions\nit was based on.  These may be placed in the ``History'' section.\nYou may omit a network location for a work that was published at\nleast four years before the Document itself, or if the original\npublisher of the version it refers to gives permission.\n\n@item\nFor any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve\nthe Title of the section, and preserve in the section all the\nsubstance and tone of each of the contributor acknowledgements and/or\ndedications given therein.\n\n@item\nPreserve all the Invariant Sections of the Document,\nunaltered in their text and in their titles.  Section numbers\nor the equivalent are not considered part of the section titles.\n\n@item\nDelete any section Entitled ``Endorsements''.  Such a section\nmay not be included in the Modified Version.\n\n@item\nDo not retitle any existing section to be Entitled ``Endorsements'' or\nto conflict in title with any Invariant Section.\n\n@item\nPreserve any Warranty Disclaimers.\n@end enumerate\n\nIf the Modified Version includes new front-matter sections or\nappendices that qualify as Secondary Sections and contain no material\ncopied from the Document, you may at your option designate some or all\nof these sections as invariant.  To do this, add their titles to the\nlist of Invariant Sections in the Modified Version's license notice.\nThese titles must be distinct from any other section titles.\n\nYou may add a section Entitled ``Endorsements'', provided it contains\nnothing but endorsements of your Modified Version by various\nparties---for example, statements of peer review or that the text has\nbeen approved by an organization as the authoritative definition of a\nstandard.\n\nYou may add a passage of up to five words as a Front-Cover Text, and a\npassage of up to 25 words as a Back-Cover Text, to the end of the list\nof Cover Texts in the Modified Version.  Only one passage of\nFront-Cover Text and one of Back-Cover Text may be added by (or\nthrough arrangements made by) any one entity.  If the Document already\nincludes a cover text for the same cover, previously added by you or\nby arrangement made by the same entity you are acting on behalf of,\nyou may not add another; but you may replace the old one, on explicit\npermission from the previous publisher that added the old one.\n\nThe author(s) and publisher(s) of the Document do not by this License\ngive permission to use their names for publicity for or to assert or\nimply endorsement of any Modified Version.\n\n@item\nCOMBINING DOCUMENTS\n\nYou may combine the Document with other documents released under this\nLicense, under the terms defined in section 4 above for modified\nversions, provided that you include in the combination all of the\nInvariant Sections of all of the original documents, unmodified, and\nlist them all as Invariant Sections of your combined work in its\nlicense notice, and that you preserve all their Warranty Disclaimers.\n\nThe combined work need only contain one copy of this License, and\nmultiple identical Invariant Sections may be replaced with a single\ncopy.  If there are multiple Invariant Sections with the same name but\ndifferent contents, make the title of each such section unique by\nadding at the end of it, in parentheses, the name of the original\nauthor or publisher of that section if known, or else a unique number.\nMake the same adjustment to the section titles in the list of\nInvariant Sections in the license notice of the combined work.\n\nIn the combination, you must combine any sections Entitled ``History''\nin the various original documents, forming one section Entitled\n``History''; likewise combine any sections Entitled ``Acknowledgements'',\nand any sections Entitled ``Dedications''.  You must delete all\nsections Entitled ``Endorsements.''\n\n@item\nCOLLECTIONS OF DOCUMENTS\n\nYou may make a collection consisting of the Document and other documents\nreleased under this License, and replace the individual copies of this\nLicense in the various documents with a single copy that is included in\nthe collection, provided that you follow the rules of this License for\nverbatim copying of each of the documents in all other respects.\n\nYou may extract a single document from such a collection, and distribute\nit individually under this License, provided you insert a copy of this\nLicense into the extracted document, and follow this License in all\nother respects regarding verbatim copying of that document.\n\n@item\nAGGREGATION WITH INDEPENDENT WORKS\n\nA compilation of the Document or its derivatives with other separate\nand independent documents or works, in or on a volume of a storage or\ndistribution medium, is called an ``aggregate'' if the copyright\nresulting from the compilation is not used to limit the legal rights\nof the compilation's users beyond what the individual works permit.\nWhen the Document is included in an aggregate, this License does not\napply to the other works in the aggregate which are not themselves\nderivative works of the Document.\n\nIf the Cover Text requirement of section 3 is applicable to these\ncopies of the Document, then if the Document is less than one half of\nthe entire aggregate, the Document's Cover Texts may be placed on\ncovers that bracket the Document within the aggregate, or the\nelectronic equivalent of covers if the Document is in electronic form.\nOtherwise they must appear on printed covers that bracket the whole\naggregate.\n\n@item\nTRANSLATION\n\nTranslation is considered a kind of modification, so you may\ndistribute translations of the Document under the terms of section 4.\nReplacing Invariant Sections with translations requires special\npermission from their copyright holders, but you may include\ntranslations of some or all Invariant Sections in addition to the\noriginal versions of these Invariant Sections.  You may include a\ntranslation of this License, and all the license notices in the\nDocument, and any Warranty Disclaimers, provided that you also include\nthe original English version of this License and the original versions\nof those notices and disclaimers.  In case of a disagreement between\nthe translation and the original version of this License or a notice\nor disclaimer, the original version will prevail.\n\nIf a section in the Document is Entitled ``Acknowledgements'',\n``Dedications'', or ``History'', the requirement (section 4) to Preserve\nits Title (section 1) will typically require changing the actual\ntitle.\n\n@item\nTERMINATION\n\nYou may not copy, modify, sublicense, or distribute the Document except\nas expressly provided for under this License.  Any other attempt to\ncopy, modify, sublicense or distribute the Document is void, and will\nautomatically terminate your rights under this License.  However,\nparties who have received copies, or rights, from you under this\nLicense will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n@item\nFUTURE REVISIONS OF THIS LICENSE\n\nThe Free Software Foundation may publish new, revised versions\nof the GNU Free Documentation License from time to time.  Such new\nversions will be similar in spirit to the present version, but may\ndiffer in detail to address new problems or concerns.  See\n@uref{https://www.gnu.org/licenses/}.\n\nEach version of the License is given a distinguishing version number.\nIf the Document specifies that a particular numbered version of this\nLicense ``or any later version'' applies to it, you have the option of\nfollowing the terms and conditions either of that specified version or\nof any later version that has been published (not as a draft) by the\nFree Software Foundation.  If the Document does not specify a version\nnumber of this License, you may choose any version ever published (not\nas a draft) by the Free Software Foundation.\n@end enumerate\n\n@page\n@heading ADDENDUM: How to use this License for your documents\n\nTo use this License in a document you have written, include a copy of\nthe License in the document and put the following copyright and\nlicense notices just after the title page:\n\n@smallexample\n@group\n  Copyright (C)  @var{year}  @var{your name}.\n  Permission is granted to copy, distribute and/or modify this document\n  under the terms of the GNU Free Documentation License, Version 1.2\n  or any later version published by the Free Software Foundation;\n  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover\n  Texts.  A copy of the license is included in the section entitled ``GNU\n  Free Documentation License''.\n@end group\n@end smallexample\n\nIf you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,\nreplace the ``with@dots{}Texts.'' line with this:\n\n@smallexample\n@group\n    with the Invariant Sections being @var{list their titles}, with\n    the Front-Cover Texts being @var{list}, and with the Back-Cover Texts\n    being @var{list}.\n@end group\n@end smallexample\n\nIf you have Invariant Sections without Cover Texts, or some other\ncombination of the three, merge those two alternatives to suit the\nsituation.\n\nIf your document contains nontrivial examples of program code, we\nrecommend releasing these examples in parallel under your choice of\nfree software license, such as the GNU General Public License,\nto permit their use in free software.\n\n@c Local Variables:\n@c ispell-local-pdict: \"ispell-dict\"\n@c End:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/app.txt",
    "content": "/** @page appdocs OpenOCD Application APIs\n\nThe top-level APIs in the OpenOCD library allow applications to integrate\nall of the low-level functionality using a set of simple function calls.\n\nThese function calls do not exist in a re-usable form, but\ncontributions to create and document them will be welcome.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/endianness.txt",
    "content": "/** @page endianness About endianness\n\nOpenOCD has to potentially deal with different endianness between:\n- the host PC endianness;\n- the data endianness during communication between host and adapter;\n- the target CPU endianness.\n\nThe whole OpenOCD code should be written to handle any endianness\nmismatch and should run on either little and big endian hosts.\n\nBig-endian host PC are becoming less and less common since Apple&trade; has\nswitched away from big-endian PowerPC&trade; in favor of little-endian intel\nX86&trade;.\n\nThe lack of commercial big-endian hosts makes hard testing OpenOCD correctness\non big-endian hosts. Running OpenOCD on low-cost commercial routers based on\nbig-endian MIPS is possible, but it's tricky to properly setup the system and\nthe cross-compiling environment.\n\nIn next sections there are two example on how to compile and test OpenOCD in an\nemulated big-endian environment.\n\n\n@section endianness_helpers OpenOCD API for handling endianness\n\nUse the following OpenOCD API to handle endianness conversions:\n- host endianness to/from little endian:\n  - le_to_h_u64(), le_to_h_u32(), le_to_h_u16();\n  - h_u64_to_le(), h_u32_to_le(), h_u16_to_le();\n  - buf_get_u32(), buf_get_u64();\n  - buf_set_u32(), buf_set_u64();\n- host endianness to/from big endian:\n  - be_to_h_u64(), be_to_h_u32(), be_to_h_u16();\n  - h_u64_to_be(), h_u32_to_be(), h_u16_to_be();\n- host endianness to/from target endianness:\n  - target_read_u64(), target_read_u32(), target_read_u16();\n  - target_write_u64(), target_write_u32(), target_write_u16();\n  - target_write_phys_u64(), target_write_phys_u32(), target_write_phys_u16();\n  - target_buffer_get_u64(), target_buffer_get_u32(), target_buffer_get_u24(), target_buffer_get_u16();\n  - target_buffer_set_u64(), target_buffer_set_u32(), target_buffer_set_u24(), target_buffer_set_u16();\n- byte swap:\n  - buf_bswap32(), buf_bswap16().\n\n\n@section endianness_docker Use dockers to run different endianness\n\n\nDocker can run a full Linux image that includes the toolchain through QEMU\nemulator.\nBy selecting a big-endian image, it's possible to compile and execute OpenOCD\nin big-endian.\nThere are, so far, not many options for big-endian images; s390x is one of the\nfew available.\n\nTo be expanded.\n\nUser should:\n- install docker;\n- download the big-endian image;\n- run the image in docker;\n- download, in the image, the OpenOCD code to test;\n- recompile OpenOCD code in the image;\n- run OpenOCD binary in the image.\n\nFrom https://github.com/multiarch/qemu-user-static\n\n  @code{.unparsed}\n  docker run --rm -t s390x/ubuntu bash\n  @endcode\n\n\n@section endianness_qemu Use buildroot and QEMU to run different endianness\n\nQEMU User Mode Emulation is an efficient method to launch, on host's CPU,\napplications compiled for another CPU and/or for different endianness.\nIt works either on Linux and BSD. More info available on\nhttps://www.qemu.org/docs/master/user/index.html\n\nWith QEMU User Mode Emulation is thus possible running, on a commonly available\nlittle-endian X86 Linux host, OpenOCD compiled for a big-endian host.\n\nThe following example will show how to use buildroot to:\n- build big-endian toolchain and libraries;\n- compile OpenOCD for big-endian;\n- run the big-endian OpenOCD on little-endian Linux PC.\n\nThe example will use ARM Cortex-A7 big-endian only because I personally feel\ncomfortable reading ARM assembly during debug. User can select other CPU\narchitectures, as this does not impact the result.\n\nA similar method can be used to test OpenOCD compiled for 32 vs 64 bit host.\n\n@note\n- the version of autotools locally installer in your Linux host can be\n  incompatible with the version of autotools used by buildroot. This can cause\n  the build to fail if buildroot has to run its autotools on a partially\n  configured OpenOCD folder. Use either a clean copy of OpenOCD code in 2., or\n  run \"./bootstrap\" in OpenOCD folder to prevent buildroot from using its own\n  autotools;\n- the configuration tool in 4. and 5. matches the version of OpenOCD used by\n  buildroot. Some new driver could be not listed in. OpenOCD will build every\n  driver that is not disabled and with satisfied dependencies. If the driver\n  you plan to use is not listed, try a first build and check OpenOCD with\n  command \"adapter list\", then try to hack the buildroot files Config.in and\n  openocd.mk in folder package/openocd/ and use \"make openocd-reconfigure\" to\n  rerun the build starting with configuration;\n- using pre-built toolchains, you need 2GB of disk space for buildroot build.\n  To also rebuild the toolchains you will need ~5GB and much longer time for\n  the first build (it takes ~2 hour on my crap 10+ years old laptop);\n- you need to install few tools for buildroot dependency, listed in\n  https://buildroot.org/downloads/manual/manual.html#requirement ;\n- you need to install qemu-armeb. On Arch Linux it's in package qemu-arch-extra;\n  on Ubuntu/debian it's packaged in qemu-user.\n  Buildroot can also be configured to build qemu for the host, if you prefer,\n  by enabling BR2_PACKAGE_HOST_QEMU_LINUX_USER_MODE, but this takes longer\n  compile time;\n- don't use qemu-system-arm, as it emulates a complete system and requires a\n  fully bootable ARM image;\n- while QEMU User Mode Emulation is available for both Linux and BSD, buildroot\n  only builds binaries for Linux target. This example can only be used with\n  Linux hosts emulating the Linux target.\n\n\nSteps to run big-endian OpenOCD on little-endian host Linux PC:\n\n1. Get buildroot source. Today's latest version is \"2022.02\":\n     @code{.unparsed}\n     wget https://buildroot.org/downloads/buildroot-2022.02.tar.xz\n     tar xf buildroot-2022.02.tar.xz\n     cd buildroot-2022.02\n     @endcode\n\n2. Override the source repo for OpenOCD in order to build your own code version\n   in place of the default OpenOCD release version:\n     @code{.unparsed}\n     echo OPENOCD_OVERRIDE_SRCDIR=/home/me/openocd.git >> local.mk\n     @endcode\n\n3. Copy default config for OpenOCD big-endian. This used:\n   - ARM Cortex-A7 big-endian target,\n   - external Linaro armeb toolchain (to speed up first build),\n   - OpenOCD all configure options enabled.\n\n     @code{.unparsed}\n     cp $OPENOCD_OVERRIDE_SRCDIR/contrib/buildroot/openocd_be_defconfig configs/\n     @endcode\n\n4. Configure buildroot with default config for OpenOCD big-endian:\n     @code{.unparsed}\n     make openocd_be_defconfig\n     @endcode\n\n5. Optional, change buildroot configuration:\n     @code{.unparsed}\n     make menuconfig\n     @endcode\n   These are the options selected with default config for OpenOCD big-endian:\n     @code{.unparsed}\n     Target options  --->\n       Target Architecture  --->\n         ARM (big endian)\n       Target Architecture Variant  --->\n         cortex-A7\n     Toolchain  --->\n       Toolchain type  --->\n         External toolchain\n       Toolchain  --->\n         Linaro armeb 2018.05\n       Toolchain origin  --->\n         Toolchain to be downloaded and installed\n     Target packages  --->\n       Hardware handling  --->\n         openocd\n           All adapters selected\n     @endcode\n   Save and exit\n\n6. Build (and take a long coffee break ...):\n     @code{.unparsed}\n     make openocd\n     @endcode\n\n7. Execute big-endian OpenOCD:\n     @code{.unparsed}\n     cd output/target\n     qemu-armeb -cpu cortex-a7 -L . usr/bin/openocd -s usr/share/openocd/scripts/ -f board/st_nucleo_f4.cfg\n     @endcode\n\n8. Optional, to rebuild after any source code modification in ${OPENOCD_OVERRIDE_SRCDIR}:\n     @code{.unparsed}\n     make openocd-rebuild\n     @endcode\n\n */\n/** @file\nThis file contains the @ref endianness page.\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/flash.txt",
    "content": "/** @page flashdocs OpenOCD Flash APIs\n\nOpenOCD provides its Flash APIs for developers to support different\ntypes of flash devices, some of which are built-in to target devices\nwhile others may be connected via standard memory interface (e.g. CFI,\nFMI, etc.).\n\nThe Flash module provides the following APIs:\n\n  - @subpage flashcfi\n  - @subpage flashnand\n  - @subpage flashtarget\n\nThis section needs to be expanded.\n\n*/\n\n\n/** @page flashcfi OpenOCD CFI Flash API\n\nThis section needs to be expanded to describe OpenOCD's CFI Flash API.\n\n*/\n\n/** @page flashnand OpenOCD NAND Flash API\n\nThis section needs to be expanded to describe OpenOCD's NAND Flash API.\n\n*/\n\n/** @page flashtarget OpenOCD Target Flash API\n\nThis section needs to be expanded to describe OpenOCD's Target Flash API.\n\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/helper.txt",
    "content": "/** @page helperdocs OpenOCD Helper APIs\n\nOpenOCD uses several low-level APIs as the foundation for high-level APIs:\n\n  - @subpage helperporting\n  - @subpage helperjim\n  - @subpage helpercommand\n  - @subpage helperlogging\n  - @subpage helperbuffers\n\nThis section needs to be expanded.\n\n */\n\n/** @page helperporting OpenOCD Types/Portability APIs\n\nThis section needs to be expanded to describe OpenOCD's type and\nportability API.\n\n */\n\n/** @page helperjim OpenOCD Jim API\n\nThe Jim API provides access to a small-footprint TCL implementation.\n\nVisit http://jim.tcl.tk/ for more information on Jim.\n\nThis section needs to be expanded to describe OpenOCD's Jim API.\n\n */\n\n/** @page helpercommand OpenOCD Command API\n\nOpenOCD's command API allows modules to register callbacks that are then\navailable to the scripting services.  It provides the mechanism for\nthese commands to be dispatched to the module using a standard\ninterface.  It provides macros for defining functions that use and\nextend this interface.\n\n@section helpercmdhandler Command Handlers\n\nCommand handlers are functions with a particular signature, which can\nbe extended by modules for passing additional parameters to helpers or\nanother layer of handlers.\n\n@subsection helpercmdhandlerdef Defining and Calling Command Handlers\n\nThese functions should be defined using the @c COMMAND_HANDLER macro.\nThese methods must be defined as static, as their principal entry point\nshould be the run_command dispatch mechanism.\n\nCommand helper functions that require access to the full set of\nparameters should be defined using the @c COMMAND_HELPER.  These must be\ndeclared static by you, as sometimes you might want to share a helper\namong several files (e.g. @c s3c24xx_nand.h).\n\nBoth types of routines must be called using the @c CALL_COMMAND_HANDLER macro.\nCalls using this macro to normal handlers require the name of the command\nhandler (which can be a name or function pointer).  Calls to helpers and\nderived handlers must pass those extra parameters specified by their\ndefinitions; however, lexical capture is used for the core parameters.\nThis dirty trick is being used as a stop-gap measure while the API is\nmigrated to one that passes a pointer to a structure containing the\nsame ingredients.  At that point, this macro will be removed and callers\nwill be able to use direct invocations.\n\nThus, the following macros can be used to define and call command\nhandlers or helpers:\n\n- @c COMMAND_HANDLER - declare or define a command handler.\n- @c COMMAND_HELPER - declare or define a derived command handler or helper.\n- @c CALL_COMMAND_HANDLER - call a command handler/helper.\n\n@subsection helpercmdhandlermacros Command Handler Macros\n\nIn addition, the following macros may be used in the context of\ncommand handlers and helpers:\n- @c CMD_CTX - the current @c command_context\n- @c CMD_NAME - invoked command name\n- @c CMD_ARGC - the number of command arguments\n- @c CMD_ARGV - array of command argument strings\n\n@section helpercmdregister Command Registration\n\nIn order to use a command handler, it must be registered with the\ncommand subsystem.  All commands are registered with command_registration\nstructures, specifying the name of the command, its handler, its allowed\nmode(s) of execution, and strings that provide usage and help text.\nA single handler may be registered using multiple names, but any name\nmay have only one handler associated with it.\n\nThe @c register_command() and @c register_commands() functions provide\nregistration, while the @c unregister_command() and\n@c unregister_all_commands() functions will remove existing commands.\nThese may be called at any time, allowing the command set to change in\nresponse to system actions.\n\n@subsection helpercmdjim Jim Command Registration\n\nThe command_registration structure provides support for registering\nnative Jim command handlers (@c jim_handler) too.  For these handlers,\nthe module can provide help and usage support; however, this mechanism\nallows Jim handlers to be called as sub-commands of other commands.\nThese commands may be registered with a private data value (@c\njim_handler_data) that will be available when called, as with low-level\nJim command registration.\n\nA command may have a normal @c handler or a @c jim_handler, but not both.\n\n@subsection helpercmdregisterchains Command Chaining\n\nWhen using register_commands(), the array of commands may reference\nother arrays.  When the @c chain field is filled in a\ncommand_registration record, the commands on in the chained list will\nadded in one of two places.  If the record defines a new command, then\nthe chained commands are added under it; otherwise, the commands are\nadded in the same context as the other commands in the array.\n\n@section helpercmdprimer Command Development Primer\n\nThis @ref primercommand provides details about the @c hello module,\nshowing how the pieces described on this page fit together.\n\n */\n\n/** @page helperlogging OpenOCD Logging API\n\nThis section needs to be expanded to describe OpenOCD's Logging API.\n\n */\n\n/** @page helperbuffers OpenOCD Byte Buffer API\n\nThis section needs to be expanded to describe OpenOCD's Byte Buffer API.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/jtag/drivers/remote_bitbang.txt",
    "content": "/** @remote_bitbangpage OpenOCD Developer's Guide\n\nThe remote_bitbang JTAG driver is used to drive JTAG from a remote process. The\nremote_bitbang driver communicates via TCP or UNIX sockets with some remote\nprocess using an ASCII encoding of the bitbang interface. The remote process\npresumably then drives the JTAG however it pleases. The remote process should\nact as a server, listening for connections from the openocd remote_bitbang\ndriver.\n\nThe remote bitbang driver is useful for debugging software running on\nprocessors which are being simulated.\n\nThe bitbang interface consists of the following functions.\n\nblink on\n\tBlink a light somewhere. The argument on is either 1 or 0.\n\nread\n\tSample the value of tdo.\n\nwrite tck tms tdi\n\tSet the value of tck, tms, and tdi.\n\nreset trst srst\n\tSet the value of trst, srst.\n\nAn additional function, quit, is added to the remote_bitbang interface to\nindicate there will be no more requests and the connection with the remote\ndriver should be closed.\n\nThese five functions are encoded in ASCII by assigning a single character to\neach possible request. The assignments are:\n\n\tB - Blink on\n\tb - Blink off\n\tR - Read request\n\tQ - Quit request\n\t0 - Write 0 0 0\n\t1 - Write 0 0 1\n\t2 - Write 0 1 0\n\t3 - Write 0 1 1\n\t4 - Write 1 0 0\n\t5 - Write 1 0 1\n\t6 - Write 1 1 0\n\t7 - Write 1 1 1\n\tr - Reset 0 0\n\ts - Reset 0 1\n\tt - Reset 1 0\n\tu - Reset 1 1\n\nThe read response is encoded in ASCII as either digit 0 or 1.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/jtag.txt",
    "content": "/** @page jtagdocs JTAG APIs\n\nFor new developers unfamiliar with the technology, @ref primerjtag provides\na brief introduction to the IEEE JTAG interface.\n\nThe OpenOCD JTAG library API covers several functional areas.  The jtag\n@b core communicates through the @b minidriver API with either its full\n@a driver implementation (src/jtag/jtag_driver.c) or a @a minidriver .\nInternally, the @b command API is used by the JTAG driver for managing\nasynchronous transactions.\n\n- @subpage jtagcore\n  - @b public API routines\n  - declared in @c src/jtag/jtag.h\n  - used by other modules\n\n- @subpage jtagtcl\n  - @b private TCL handling routines\n  - defined in @c src/jtag/tcl.c\n  - registers and handles Jim commands that configure and use the JTAG core\n\n- @subpage jtagcmd\n  - @b private command queue API\n  - declared in @c src/jtag/commands.h\n  - provides routines used internally by the full JTAG drivers.\n\n- @subpage jtagiface\n  - @b private interface driver API\n  - declared in @c src/jtag/interface.h\n  - used by the core, minidrivers, and the full interface device drivers.\n    - allows implementing new interface device drivers.\n    - includes the Cable/TAP API (commands starting with @c tap_)\n\n- @subpage jtagdriver\n  - @b private minidriver API\n  - declared in @c src/jtag/minidriver.h\n  - used @a only by the core and minidriver implementations:\n    - @c jtag_driver.c (in-tree OpenOCD drivers)\n    - future implementations (on other embedded hosts)\n    - interface device drivers do @b not need this API.\n\n */\n\n/** @page jtagcore JTAG Core API\n\nThis section needs to be expanded.\n\n */\n\n/** @page jtagtcl JTAG TCL API\n\nThis section needs to be expanded.\n\n */\n\n/** @page jtagcmd JTAG Command API\n\nThis section needs to be expanded.\n\n */\n\n/** @page jtagiface JTAG Interface API\n\nThis section needs to be expanded.\n\n */\n\n/** @page jtagdriver JTAG Minidriver API\n\nThis section needs to be expanded.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/main.txt",
    "content": "/** @mainpage OpenOCD Developer's Guide\n\nWelcome to the OpenOCD Developer's Guide -- the developer's resource for\nlearning about the internal architecture of the OpenOCD project. @par\n\nIn addition, this document contains the tactical and strategic plans\nand processes that have been developed by and for the OpenOCD community.\n\nDevelopers that want to contribute to OpenOCD should read the following\nsections before starting work:\n\n- @subpage thelist enumerates opportunities for improving or\nextending the OpenOCD platform.  If your ideas are on The List, you might\ncheck the mailing list archives to find the status of your feature (or bug).\n- The @subpage styleguide provides rules that developers should\n  follow when writing new code for OpenOCD.\n- The @subpage patchguide provides policies that developers should\n  follow when submitting patches to the project.\n- The @subpage bugs page contains the content of the BUGS file, which\n  provides instructions for submitting bug reports to the maintainers.\n- The @subpage releases page describes the project's release process.\n- The @subpage endianness provides hints about writing and testing\n  endianness independent code for OpenOCD.\n\n@ref primer provide introductory materials for new developers on various\nspecific topics.\n\nFinally, the @ref oocd pages explain how the code has been organized\ninto layers of APIs, providing an overview of how they fit together.\nThese pages attempt to give developers a high-level perspective of the\nvarious code modules provided by OpenOCD.\n\n */\n\n/** @page primer OpenOCD Technical Primers\n\nThis pages lists Technical Primers available for OpenOCD Developers.\nThey seek to provide information to pull novices up the learning curves\nassociated with the fundamental technologies used by OpenOCD.\n\n- @subpage primerdocs\n- @subpage primerautotools\n- @subpage primertcl\n- @subpage primerjtag\n\nThe above documents should bridge any \"ancillary\" gaps in contributor\nknowledge, without having to learn the complete languages or technology.\nThey should provide enough information for experienced developers to\nlearn how to make \"correct\" changes when creating patches.\n\nBeyond the fundamentals, the following primers provide introductory\ntutorials for OpenOCD's sub-systems.  These complement the @ref oocd\npages that provide more high-level perspective on related topics.\n\n- @subpage primercommand\n\nIn all cases, these Primers should use idiomatic conventions that the\ncommunity has agreed are the \"right way of doing things\".  In this\nrespect, these documents typically assume some familiarity with the\ninformation contained in one or more @ref styleguide, or they will\ndirectly refer to specific style guides as supplemental reading.\n\nContributions or suggestions for new Technical Primers are welcome.\n\n */\n\n/** @page oocd OpenOCD Architecture\n\nThe OpenOCD library consists of several APIs that build together to\nprovide the support functionality.  The following list shows how these\nmodules are stacked in the current implementation (from bottom to top):\n\n- @subpage helperdocs\n  - @ref helperporting\n  - @ref helperjim\n  - @ref helpercommand\n  - @ref helperlogging\n- @subpage jtagdocs\n  - @ref jtagcore\n  - @ref jtagtcl\n  - @ref jtagcmd\n  - @ref jtagiface\n  - @ref jtagdriver\n- @subpage targetdocs\n  - @ref targetarm\n  - @ref targetnotarm\n  - @ref targetmips\n  - @ref targetregister\n  - @ref targetimage\n  - @ref targettrace\n- @subpage flashdocs\n  - @ref flashcfi\n  - @ref flashnand\n  - @ref flashtarget\n- @subpage serverdocs\n  - @ref servergdb\n  - @ref servertelnet\n  - @ref serverhttp\n- @subpage appdocs\n\nObviously, there are some nuances to the stack that are not shown by\nthis linear list of layers.\n\nThe List of @ref thelist enumerates opportunities for improving or\nextending the OpenOCD platform.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/primer/autotools.txt",
    "content": "/** @page primerautotools OpenOCD Autotools Primer\n\nThis page provides an overview to OpenOCD's use of the GNU autotool suite:\n- @ref primerautoconf\n- @ref primerautomake\n- @ref primerlibtool\n\nMost developers do not need to concern themselves with these tools, as\nthe @ref primerbootstrap script runs these tools in the required sequence.\n\n@section primerbootstrap Autotools Bootstrap\n\nThe @c bootstrap script should be used by developers to run the\nautotools in the correct sequence.\n\nWhen run after a fresh checkout, this script generates the build files\nrequired to compile the project, producing the project configure script.\n\n@subsection primerbootstrapcures Problems Solved By Bootstrap\n\nFor example, the build system can fail in unexpected ways after running\n<code>git pull</code>.  Here, the <code>make maintainer-clean</code>\nshould be used to remove all of the files generated by the @c bootstrap\nscript and subsequent build processes.\n\nIn this particular case, one may also need to remove stray files by hand\nafter running this command to ensure everything is rebuilt properly.\nThis step should be necessary only if the @c maintainer-clean was run\n@b after altering the build system files with git. If it is run\n@b before any updates, the build system should never leave artifacts\nin the tree.\n\nWithout such precautions, changes can be introduced that leave the tree\ntimestamps in an inconsistent state, producing strange compile errors\nthat are resolve after such diligence.\n\n@subsection primermaintainerclean Autotools Cleaning\n\nNormally, all files generated by the bootstrap script, configure\nprocess, and build system should be removed after running <code>make\nmaintainer-clean</code>.  Automatically generated files that remain\nafter this should be listed in @c MAINTAINERCLEANFILES,\n@c DISTCLEANFILES, or @c CLEANFILES, depending on which stage of the\nbuild process they are produced.\n\n@section primerautoconf Autoconf Configuration Script\n\nThe @c autoconf program generates the @c configure script from\n@c configure.in, using serious Perl voodoo.  The resulting script is\nincluded in the project distribution packages and run by users to\nconfigure the build process for their system.\n\n@section primerautomake Automake Makefiles\n\nThe @c automake program generates @c Makefile.in files (from @c\nMakefile.am files).  These files are later processed by the configure\nscript produced by @c autoconf.\n\n@subsection primerautomakenewfiles Creating Makefile.am Files\n\nThis section shows how to add a @c Makefile.am in a new directory (or\none that lacks one).\n-# The new directory must be listed in the @c SUBDIRS variable in the\nparent directory's Makefile.am:\n@code\n$ echo 'SUBDIRS += directory' >>../Makefile.am\n@endcode\n-# Create an bare-bones Makefile.am file in directory that needs it:\n@code\n$ echo \"MAINTAINERCLEANFILES = Makefile.in\" >Makefile.am\n@endcode\n-# The @c configure.in script must be updated, so it generates the required\nMakefile when the @a configure script is run by the user:\n@verbatim\nAC_OUTPUT([\n\t\t...\n\t\tpath/to/new/Makefile\n\t])\n@endverbatim\n\nNote: these instructions are @b not meant to be used literally, rather\nthey are shown for demonstration purposes.\n\nThe default MAINTAINERCLEANFILES rule ensures that the\nautomake-generated @c Makefile.in file will be removed when developers\nrun <code>make maintainer-clean</code>.  Additional rules may be added\nafter this; however, the project should bootstrap and tear down cleanly\nafter taking these minimal steps, with the new directory being visited\nduring the @c make sequence.\n\n@subsection primerautomaketweaks Updating Makefile.am Files\n\nAdding, removing, and renaming files from the project tree usually\nrequires updating the autotools inputs. This section will help describe\nhow to do this as questions arise.\n\n@section primerlibtool Libtool and Libraries\n\nThe @c libtool program provides the means of generating libraries in a\nportable and painless manner (relatively speaking).\n\nThis section will contain an answer to \"what does libtool give OpenOCD?\"\nand \"what do developers need to consider in new code?\"\n\n@section primerautotoolsmation Autotools Automation\n\nThis section outlines three ways the autotools provides automation to\nassist with testing and distribution:\n- @ref primerautocheck -- automatic unit and smoke tests\n- @ref primerautodistcheck -- automatic distribution and packaging tests\n\n@subsection primerautocheck make check\n\nThe <code>make check</code> command will run the OpenOCD test suite,\nonce it has been integrated as such.  This section will contain\ninformation about how to extend the testing build system components to\nimplement new checks.\n\n@subsection primerautodistcheck make distcheck\n\nThe <code>make distcheck</code> command produces an archive of the\nproject deliverables (using <code>make dist</code>) and verifies its\nintegrity for distribution by attempting to use the package in the same\nmanner as a user.\n\nThese checks includes the following steps:\n-# Unpack the project archive into its expected directory.\n-# Configure and build the project in a temporary out-of-tree directory.\n-# Run <code>make check</code> to ensure the distributed code passes all tests.\n-# Run <code>make install</code> into a temporary installation directory.\n-# Check that <code>make uninstall</code> removes all files that were installed.\n-# Check that <code>make distclean</code> removes all files created\nduring all other steps (except the first).\n\nIf all of these steps complete successfully, the @c make process will\noutput a friendly message indicating the archive is ready to be\ndistributed.\n\n */\n/** @file\n\nThis file contains the @ref primerautotools page.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/primer/commands.txt",
    "content": "/** @page primercommand Command Development Primer\n\nThis page provides a primer for writing commands by introducing @c hello\nmodule.  The full source code used in this example can be found in\nhello.c, and the @ref primercmdcode section shows how to use it.\n\nA summary of this information can be found in @ref helpercommand .\n\n@section primercmdhandler Command Handlers\n\nDefining new commands and their helpers is easy.  The following code\ndefines a simple command handler that delegates its argument parsing:\n@code\nCOMMAND_HANDLER(handle_hello_command)\n{\n\tconst char *sep, *name;\n\tint retval = CALL_COMMAND_HANDLER(handle_hello_args);\n\tif (ERROR_OK == retval)\n\t\tcommand_print(CMD, \"Greetings%s%s!\", sep, name);\n\treturn retval;\n}\n@endcode\n\nHere, the @c COMMAND_HANDLER macro establishes the function signature,\nsee in command.h by the @c __COMMAND_HANDLER macro.\n\nThe COMMAND_HELPER macro function allows defining functions with an\nextended version of the base signature.  These helper functions can be\ncalled (with the appropriate parameters), the @c CALL_COMMAND_HANDLER\nmacro to pass any e as parameters to the following helper function:\n\nThe subsequent blocks of code are a normal C function that can do\nanything, so only complex commands deserve should use command helper\nfunctions.  In this respect, this example uses one to demonstrate how --\nnot when -- they should be used.\n\n@code\nstatic COMMAND_HELPER(handle_hello_args, const char **sep, const char **name)\n{\n\tif (argc > 1)\n\t{\n\t\tLOG_ERROR(\"%s: too many arguments\", CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tif (1 == CMD_ARGC)\n\t{\n\t\t*sep = \", \";\n\t\t*name = CMD_ARGV[0];\n\t}\n\telse\n\t\t*sep = *name = \"\";\n\n\treturn ERROR_OK;\n}\n@endcode\n\nOf course, you may also call other macros or functions, but that extends\nbeyond the scope of this tutorial on writing commands.\n\n@section primercmdreg Command Registration\n\nBefore this new function can be used, it must be registered somehow.\nFor a new module, registering should be done in a new function for\nthe purpose, which must be called from @c openocd.c:\n@code\n\nstatic const struct command_registration hello_command_handlers[] = {\n\t{\n\t\t.name = \"hello\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_hello_command,\n\t\t.help = \"print a warm greeting\",\n\t\t.usage = \"[name]\",\n\t},\n\t{\n\t\t.chain = foo_command_handlers,\n\t}\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint hello_register_commands(struct command_context_s *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, handle_command_handlers);\n}\n@endcode\n\nNote that the \"usage\" text should use the same EBNF that's found\nin the User's Guide:  literals in 'single quotes', sequences of\noptional parameters in [square brackets], and alternatives in\n(parentheses|with|vertical bars), and so forth.  No angle brackets.\n\nThat's it!  The command should now be registered and available to scripts.\n\n@section primercmdchain Command Chaining\n\nThis example also shows how to chain command handler registration, so\nyour modules can \"inherit\" commands provided by other (sub)modules.\nHere, the hello module includes the foo commands in the same context\nthat the 'hello' command will be registered.\n\nIf the @c chain field had been put in the 'hello' command, then the\n@c foo module commands would be registered under it.  Indeed, that\ntechnique is used to define the 'foo bar' and 'foo baz' commands,\nas well as for the example drivers that use these modules.\n\nThe code for the 'foo' command handlers can be found in @c hello.c.\n\n@section primercmdcode Trying These Example Commands\n\nThese commands have been inherited by the dummy interface, faux flash,\nand testee target drivers.  The easiest way to test these is by using the\ndummy interface.\n\nOnce OpenOCD has been built with this example code, the following command\ndemonstrates the abilities that the @c hello module provides:\n@code\nopenocd -c 'interface dummy' \\\n\t-c 'dummy hello' \\\n\t-c 'dummy hello World' \\\n\t-c 'dummy hello {John Doe}' \\\n\t-c 'dummy hello John Doe'  # error: too many arguments\n@endcode\n\nIf saved in @c hello.cfg, then running <code>openocd -f hello.cfg</code>\nshould produce the following output before displaying the help text and\nexiting:\n@code\nGreetings!\nGreetings, World!\nGreetings, John Doe!\nError: hello: too many arguments\nRuntime error, file \"openocd.cfg\", line 14:\n    hello: too many arguments\ndummy hello [<name>]\n      prints a warm welcome\n@endcode\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/primer/docs.txt",
    "content": "/** @page primerdocs OpenOCD Documentation Primers\n\nThis page provides an introduction to OpenOCD's documentation processes.\n\nOpenOCD presently produces several kinds of documentation:\n- The User's Guide:\n  - Focuses on using the OpenOCD software.\n  - Details the installation, usage, and customization.\n  - Provides descriptions of public Jim/TCL script commands.\n  - Written using GNU texinfo.\n  - Created with 'make pdf' or 'make html'.\n  - See @subpage primertexinfo and @ref styletexinfo.\n- The References: (as proposed)\n  - Focuses on using specific hardware with OpenOCD.\n  - Details the supported interfaces, chips, boards, and targets.\n  - Provides overview, usage, reference, and FAQ for each device.\n  - Written using LaTeX language with custom macros.\n  - Created with 'make references'.\n  - See @subpage primerlatex and @ref stylelatex.\n- The Manual:\n  - Focuses on developing the OpenOCD software.\n  - Details the architecture, driver interfaces, and processes.\n  - Provides \"full\" coverage of C source code (work-in-progress).\n  - Written using Doxygen C language conventions (i.e. in comments).\n  - Created with 'make doxygen'.\n  - See @subpage primerdoxygen and @ref styledoxygen.\n\nThe following sections provide more information for anyone that wants to\ncontribute new or updated documentation to the OpenOCD project.\n\n */\n/** @page primertexinfo Texinfo Primer\n\nThe OpenOCD User's Guide presently exists entirely within the\ndoc/openocd.texi document.  That file contains documentation with\nmark-up suitable for being parsed by the GNU Texinfo utilities\n(http://www.gnu.org/software/texinfo/).\n\nWhen you add a new command, driver, or driver option, it needs to be\ndocumented in the User's Guide.  Use the existing documentation for\nmodels, but feel free to make better use of Texinfo mechanisms.  See\nthe Texinfo web site for the Texinfo manual and more information.\n\nOpenOCD style guidelines for Texinfo documentation can be found on the\n@ref styletexinfo page.\n\n */\n/** @page primerlatex LaTeX Primer\n\nThe OpenOCD project provides a number of reference guides using the\nLaTeX typesetting language.\n\n- OpenOCD Quick Reference Sheets\n- OpenOCD Hardware Reference Guides\n\nThese documents have not yet been produced, so this Primer serves as\na placeholder to describe how they are created and can be extended.\nThe same holds true for the @ref stylelatex page.\n\n */\n/** @page primerdoxygen Doxygen Primer\n\nDoxygen-style comments are used to provide documentation in-line with\nthe OpenOCD source code.  These comments are used to document functions,\nvariables, structs, enums, fields, and everything else that might need\nto be documented for developers.  Additional files containing comments\nthat supplement the code comments in order to provide complete developer\ndocumentation.\n\nEven if you already know Doxygen, please read this Primer to learn\nhow OpenOCD developers already use Doxygen features in the project tree.\nFor more information about OpenOCD's required style for using Doxygen,\nsee the @ref styledoxygen page and look at existing documentation in the\n@c doc/manual tree.\n\n@section primerdoxytext Doxygen Input Files\n\nDoxygen has been configured parse all of the C source code files (*.c\nand *.h) in @c src/ in order to produce a complete reference of all\nOpenOCD project symbols.  In addition to the source code files, other\nfiles will also be scanned for comment blocks; some are referenced\nexplicitly by the @c INPUT variable in the Doxygen configuration file.\n\nBy default, the Doxygen configuration enables a \"full\" set of features,\nincluding generation of dependency graphs (using the GraphViz package).\nThese features may be disabled by editing the @c Doxyfile.in file at the\ntop of the project tree; the configuration file includes comments that\nprovide detailed documentation for each option.\n\nTo support out-of-tree building of the documentation, the @c Doxyfile.in\n@c INPUT values will have all instances of the string @c \"@srcdir@\"\nreplaced with the current value of the make variable\n<code>$(srcdir)</code>.  The Makefile uses a rule to convert\n@c Doxyfile.in into the @c Doxyfile used by <code>make doxygen</code>.\n\n@section primerdoxyoocd OpenOCD Input Files\n\nOpenOCD uses the @c INPUT mechanism to include additional documentation to\nprovide The Manual for OpenOCD Developers.  These extra files contain\nhigh-level information intended to supplement the relatively low-level\ndocumentation that gets extracted from the source code comments.\n\nOpenOCD's Doxygen configuration file will search for all @c .txt files\nthat can be found under the @c doc/manual directory in the project tree.\nNew files containing valid Doxygen markup that are placed in or under\nthat directory will be detected and included in The Manual automatically.\n\n@section primerdoxyman Doxygen Reference Manual\n\nThe full documentation for Doxygen can be referenced on-line at the project\nhome page: http://www.doxygen.org/index.html.  In HTML versions of this\ndocument, an image with a link to this site appears in the page footer.\n\n*/\n/** @file\n\nThis file contains the Doxygen source code for the @ref primerdocs.\nThe @ref primerdocs page also contains the following sections:\n\n- @ref primertexinfo\n- @ref primerlatex\n- @ref primerdoxygen\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/primer/jtag.txt",
    "content": "/** @page primerjtag OpenOCD JTAG Primer\n\nJTAG is unnecessarily confusing, because JTAG is often confused with\nboundary scan, which is just one of its possible functions.\n\nJTAG is simply a communication interface designed to allow communication\nto functions contained on devices, for the designed purposes of\ninitialisation, programming, testing, debugging, and anything else you\nwant to use it for (as a chip designer).\n\nThink of JTAG as I2C for testing.  It doesn't define what it can do,\njust a logical interface that allows a uniform channel for communication.\n\nSee @par\n\thttp://en.wikipedia.org/wiki/Joint_Test_Action_Group\n\n@image html jtag-state-machine-large.png\n\nThe first page (among other things) shows a logical representation\ndescribing how multiple devices are wired up using JTAG.  JTAG does not\nspecify, data rates or interface levels (3.3V/1.8V, etc) each device can\nsupport different data rates/interface logic levels.  How to wire them\nin a compatible way is an exercise for an engineer.\n\nBasically TMS controls which shift register is placed on the device,\nbetween TDI and TDO.  The second diagram shows the state transitions on\nTMS which will select different shift registers.\n\nThe first thing you need to do is reset the state machine, because when\nyou connect to a chip you do not know what state the controller is in,you need\nto clock TMS as 1, at least 5 times.  This will put you into \"Test Logic\nReset\" State.  Knowing this, you can, once reset, then track what each\ntransition on TMS will do, and hence know what state the JTAG state\nmachine is in.\n\nThere are 2 \"types\" of shift registers.  The Instruction shift register\nand the data shift register.  The sizes of these are undefined, and can\nchange from chip to chip.  The Instruction register is used to select\nwhich Data register/data register function is used, and the data\nregister is used to read data from that function or write data to it.\n\nEach of the states control what happens to either the data register or\ninstruction register.\n\nFor example, one of the data registers will be known as \"bypass\" this is\n(usually) a single bit which has no function and is used to bypass the\nchip.  Assume we have 3 identical chips, wired up like the picture(wikipedia)\nand each has a 3 bits instruction register, and there are 2 known\ninstructions (110 = bypass, 010 = \"some other function\") if we want to use\n\"some other function\", on the second chip in the line, and not change\nthe other chips we would do the following transitions.\n\nFrom Test Logic Reset, TMS goes:\n\n  0 1 1 0 0\n\nwhich puts every chip in the chain into the \"Shift IR state\"\nThen (while holding TMS as 0) TDI goes:\n\n  0 1 1  0 1 0  0 1 1\n\nwhich puts the following values in the instruction shift register for\neach chip [110] [010] [110]\n\nThe order is reversed, because we shift out the least significant bit\nfirst.  Then we transition TMS:\n\n  1 1 1 0 0\n\nwhich puts us in the \"Shift DR state\".\n\nNow when we clock data onto TDI (again while holding TMS to 0) , the\ndata shifts through the data registers, and because of the instruction\nregisters we selected (\"some other function\" has 8 bits in its data\nregister), our total data register in the chain looks like this:\n\n  0 00000000 0\n\nThe first and last bit are in the \"bypassed\" chips, so values read from\nthem are irrelevant and data written to them is ignored.  But we need to\nwrite bits for those registers, because they are in the chain.\n\nIf we wanted to write 0xF5 to the data register we would clock out of\nTDI (holding TMS to 0):\n\n  0 1 0 1 0 1 1 1 1 0\n\nAgain, we are clocking the least-significant bit first.  Then we would\nclock TMS:\n\n  1 1 0\n\nwhich updates the selected data register with the value 0xF5 and returns\nus to run test idle.\n\nIf we needed to read the data register before over-writing it with F5,\nno sweat, that's already done, because the TDI/TDO are set up as a\ncircular shift register, so if you write enough bits to fill the shift\nregister, you will receive the \"captured\" contents of the data registers\nsimultaneously on TDO.\n\nThat's JTAG in a nutshell.  On top of this, you need to get specs for\ntarget chips and work out what the various instruction registers/data\nregisters do, so you can actually do something useful.  That's where it\ngets interesting.  But in and of itself, JTAG is actually very simple.\n\n@section primerjtagmore More Reading\n\nA separate primer contains information about @subpage primerjtagbs for\ndevelopers that want to extend OpenOCD for such purposes.\n\n */\n/** @page primerjtagbs JTAG Boundary Scan Primer\n\nThe following page provides an introduction on JTAG that focuses on its\nboundary scan capabilities: @par\nhttp://www.engr.udayton.edu/faculty/jloomis/ece446/notes/jtag/jtag1.html\n\nOpenOCD does not presently have clear means of using JTAG for boundary\nscan testing purposes; however, some developers have explored the\npossibilities.  The page contains information that may be useful to\nthose wishing to implement boundary scan capabilities in OpenOCD.\n\n@section primerbsdl The BSDL Language\n\nFor more information on the Boundary Scan Description Language (BSDL),\nthe following page provides a good introduction: @par\nhttp://www.radio-electronics.com/info/t_and_m/boundaryscan/bsdl.php\n\n@section primerbsdlvendors Vendor BSDL Files\n\nNXP LPC: @par\nhttp://www.standardics.nxp.com/support/models/lpc2000/\n\nFreescale PowerPC: @par\nhttp://www.freescale.com/webapp/sps/site/overview.jsp?code=DRPPCBSDLFLS\n\nFreescale i.MX1 (too old): @par\nhttp://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX1&nodeId=0162468rH311432973ZrDR&fpsp=1&tab=Design_Tools_Tab\n\nRenesas R32C/117: @par\nhttp://sg.renesas.com/fmwk.jsp?cnt=r32c116_7_8_root.jsp&fp=/products/mpumcu/m16c_family/r32c100_series/r32c116_7_8_group/\n- The device page does not come with BSDL file; you have to register to\n  download them. @par\n  http://www.corelis.com/support/BSDL.htm\n\nTI links theirs right off the generic page for each chip;\nthis may be the case for other vendors as well.  For example:\n\n- DaVinci DM355 -- http://www.ti.com/litv/zip/sprm262b\n- DaVinci DM6446\n  - 2.1 silicon -- http://www.ti.com/litv/zip/sprm325a\n  - older silicon -- http://www.ti.com/litv/zip/sprm203\n- OMAP 3530\n  - CBB package -- http://www.ti.com/litv/zip/sprm315b\n    - 515 ball s-PGBA, POP, 0.4mm pitch\n  - CUS package -- http://www.ti.com/litv/zip/sprm314a\n    - 515 ball s-PGBA, POP, 0.5mm pitch\n  - CBC package -- http://www.ti.com/litv/zip/sprm346\n    - 423 ball s-PGBA, 0.65mm pitch\n\nMany other files are available in the \"Semiconductor Manufacturer's BSDL\nfiles\" section of the following site: @par\nhttp://www.freelabs.com/~whitis/electronics/jtag/\n\n */\n/** @file\nThis file contains the @ref primerjtag and @ref primerjtagbs page.\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/primer/tcl.txt",
    "content": "/** @page primertcl OpenOCD TCL Primer\n\nThe @subpage scripting page provides additional TCL Primer material.\n\n@verbatim\n\n****************************************\n****************************************\n\nThis is a short introduction to 'un-scare' you about the language\nknown as TCL. It is structured as a guided tour through the files\nwritten by me [Duane Ellis] - in early July 2008 for OpenOCD.\n\nWhich uses the \"JIM\" embedded Tcl clone-ish language.\n\nThing described here are *totally* TCL generic... not Jim specific.\n\nThe goal of this document is to encourage you to add your own set of\nchips to the TCL package - and most importantly you should know where\nyou should put them - so they end up in an organized way.\n\n--Duane Ellis.\n\tduane@duaneellis.com\n\n****************************************\n****************************************\n\nAdding \"chip\" support - Duane Ellis July 5 - 2008.\n\nThe concept is this:\n  In your \"openocd.cfg\" file add something like this:\n\n     source [find tcl/chip/VENDOR/FAMILY/NAME.tcl]\n\n  For example...\n     source [find tcl/chip/atmel/at91/at91sam7x256.tcl]\n\n  You'll notice that it makes use of:\n\n       tcl/cpu/arm/<NAME>.tcl.\n\n  Yes, that is where you should put \"core\" specific things.\n  Be careful and learn the difference:\n\n  THE \"CORE\" - is not the entire chip!\n\nDefinition:\n   That \"file\" listed above is called a \"CHIP FILE\".\n\n   It may be standalone, or may need to \"source\" other \"helper\" files.\n\n   The reference [7/5/2008] is the at91sam7x256.tcl file.\n\n****************************************\n****************************************\n=== TCL TOUR ===\nOpen:  at91sam7x256.tcl\n=== TCL TOUR ===\n\nA walk through --- For those who are new to TCL.\n\nExamine the file: at91sam7x256.tcl\n\nIt starts with:\n\tsource [find path/filename.tcl]\n\nIn TCL - this is very important.\n\n\tRule #1 Everything is a string.\n\tRule #2 If you think other wise See #1.\nReminds you of:\n\tRule #1: The wife is correct.\n\tRule #2: If you think otherwise, See #1\n\nAny text contained inside of [square-brackets]\nis just like `back-ticks` in BASH.\n\nHence, the [find FILENAME] executes the command find with a single\nparameter the filename.\n\n========================================\n\nNext you see a series of:\n\nset  NAME    VALUE\n\nIt is mostly \"obvious\" what is going on.\n\nException: The arrays.\n\n  You would *THINK* Tcl supports arrays.\n  In fact, multi-dim arrays. That is false.\n\n  For the index for\"FLASH(0,CHIPSELECT)\" is actually the string\n  \"0,CHIPSELECT\".  This is problematic. In the normal world, you think\n  of array indexes as integers.\n\n  For example these are different:\n\n       set foo(0x0c)  123\n       set foo(12)    444\n\n  Why? Because 0x0c {lowercase} is a string.\n  Don't forget UPPER CASE.\n\n  You must be careful - always... always...  use simple decimal\n  numbers. When in doubt use 'expr' the evaluator. These are all the\n  same.\n\n       set x 0x0c\n       set foo([expr $x])  \"twelve\"\n\n       set x 12\n       set foo([expr $x])  \"twelve\"\n\n       set x \"2 * 6\"\n       set foo([expr $x])  \"twelve\"\n\n**************************************************\n***************************************************\n=== TCL TOUR ===\nOpen the file: \"bitsbytes.tcl\"\n\nThere is some tricky things going on.\n===============\n\nFirst, there is a \"for\" loop - at level 0\n{level 0 means: outside of a procedure/function}\n\nThis means it is evaluated when the file is parsed.\n\n== SIDEBAR: About The FOR command ==\nIn TCL, \"FOR\" is a funny thing, it is not what you think it is.\n\nSyntactically - FOR is a just a command, it is not language\nconstruct like for(;;) in C...\n\nThe \"for\" command takes 4 parameters.\n   (1) The \"initial command\" to execute.\n   (2) the test \"expression\"\n   (3) the \"next command\"\n   (4) the \"body command\" of the FOR loop.\n\nNotice I used the words \"command\" and \"expression\" above.\n\nThe FOR command:\n1)  executes the \"initial command\"\n2)  evaluates the expression if 0 it stops.\n3)  executes the \"body command\"\n4)  executes the \"next command\"\n5)  Goto Step 2.\n\nAs show, each of these items are in {curly-braces}.  This means they\nare passed as they are - KEY-POINT: unevaluated to the FOR\ncommand. Think of it like escaping the backticks in Bash so that the\n\"underlying\" command can evaluate the contents. In this case, the FOR\nCOMMAND.\n\n== END: SIDEBAR: About The FOR command ==\n\nYou'll see two lines:\n\nLINE1:\n       set vn [format \"BIT%d\" $x]\n\nFormat is like \"sprintf\". Because of the [brackets], it becomes what\nyou think.  But here's how:\n\nFirst - the line is parsed - for {braces}.  In this case, there are\nnone.  Then, the parser looks for [brackets] and finds them.  The\nparser then evaluates the contents of the [brackets], and replaces\nthem. It is similar to this bash statement.\n\n       EXPORT vn=`date`\n\nLINE 2 & 3\n       set $vn [expr {1024 * $x}]\n       global $vn\n\nIn line 1, we dynamically created a variable name.  Here, we are\nassigning it a value. Lastly Line 3 we force the variable to be\nglobal, not \"local\" within the \"for command body\"\n\n===============\nThe PROCS\n\nproc create_mask { MSB LSB } {\n     ... body ....\n}\n\nLike \"for\" - PROC is really just a command that takes 3 parameters.\nThe (1) NAME of the function, a (2) LIST of parameters, and a (3) BODY\n\nAgain, this is at \"level 0\" so it is a global function.  (Yes, TCL\nsupports local functions, you put them inside of a function}\n\nYou'll see in some cases, I nest [brackets] a lot and in others I'm\nlazy or wanted it to be more clear... it is a matter of choice.\n===============\n\n\n**************************************************\n***************************************************\n=== TCL TOUR ===\nOpen the file: \"memory.tcl\"\n===============\n\nHere is where I setup some 'memory definitions' that various targets can use.\n\nFor example - there is an \"unknown\" memory region.\n\nAll memory regions must have 2 things:\n\n (1)  N_<name>\n (2)  NAME( array )\n      And the array must have some specific names:\n          ( <idx>, THING )\n\t    Where: THING is one of:\n\t\t   CHIPSELECT\n\t\t   BASE\n\t\t   LEN\n\t\t   HUMAN\n\t\t   TYPE\n\t\t   RWX - the access ability.\n\t\t   WIDTH - the accessible width.\n\n        i.e.: Some regions of memory are not 'word'\n\taccessible.\n\nThe function \"address_info\" - given an address should\ntell you about the address.\n\n     [as of this writing: 7/5/2008 I have done\n     only a little bit with this -Duane]\n\n===\nMAJOR FUNCTION:\n==\n\nproc memread32 { ADDR }\nproc memread16 { ADDR }\nproc memread8 { ADDR }\n\nAll read memory - and return the contents.\n\n[ FIXME: 7/5/2008 - I need to create \"memwrite\" functions]\n\n**************************************************\n***************************************************\n=== TCL TOUR ===\nOpen the file: \"mmr_helpers.tcl\"\n===============\n\nThis file is used to display and work with \"memory mapped registers\"\n\nFor example - 'show_mmr32_reg' is given the NAME of the register to\ndisplay. The assumption is - the NAME is a global variable holding the\naddress of that MMR.\n\nThe code does some tricks. The [set [set NAME]] is the TCL way\nof doing double variable interpolation - like makefiles...\n\nIn a makefile or shell script you may have seen this:\n\n     FOO_linux = \"Penguins rule\"\n     FOO_winXP = \"Broken Glass\"\n     FOO_mac   = \"I like cat names\"\n\n     # Pick one\n     BUILD  = linux\n     #BUILD = winXP\n     #BUILD = mac\n     FOO = ${FOO_${BUILD}}\n\nThe \"double [set] square bracket\" thing is the TCL way, nothing more.\n\n----\n\nThe IF statement - and \"CATCH\" .\n\nNotice this IF COMMAND - (not statement) is like this:\n[7/5/2008 it is this way]\n\n       if ![catch { command } msg ] {\n\t  ...something...\n       } else {\n          error [format string...]\n       }\n\nThe \"IF\" command expects either 2 or 4 parameters.\n\n === Sidebar: About \"commands\" ===\n\n     Take a look at the internals of \"jim.c\"\n     Look for the function: Jim_IfCoreCommand()\n     And all those other \"CoreCommands\"\n\n     You'll notice - they all have \"argc\" and \"argv\"\n\n     Yea, the entire thing is done that way.\n\n     IF is a command. SO is \"FOR\" and \"WHILE\" and \"DO\" and the\n     others. That is why I keep using the phase it is a \"command\"\n\n === END: Sidebar: About \"commands\" ===\n\nParameter 1 to the IF command is expected to be an expression.\n\nAs such, I do not need to wrap it in {braces}.\n\nIn this case, the \"expression\" is the result of the \"CATCH\" command.\n\nCATCH - is an error catcher.\n\nYou give CATCH 1 or 2 parameters.\n    The first 1st parameter is the \"code to execute\"\n    The 2nd (optional) is where to put the error message.\n\n    CATCH returns 0 on success, 1 for failure.\n    The \"![catch command]\" is self explanatory.\n\n\nThe 3rd parameter to IF must be exactly \"else\" or \"elseif\" [I lied\nabove, the IF command can take many parameters they just have to\nbe joined by exactly the words \"else\" or \"elseif\".\n\nThe 4th parameter contains:\n\n    \"error [format STRING....]\"\n\nThis lets me modify the previous lower level error by tacking more\ntext onto the end of it. In this case, i want to add the MMR register\nname to make my error message look better.\n\n---------\nBack to something inside show_mmr32_reg{}.\n\nYou'll see something 'set fn show_${NAME}_helper' Here I am\nconstructing a 'function name' Then - I look it up to see if it\nexists.  {the function: \"proc_exists\" does this}\n\nAnd - if it does - I call the function.\n\nIn \"C\" it is a lot like using: 'sprintf()' to construct a function name\nstring, then using \"dlopen()\" and \"dlsym()\" to look it up - and get a\nfunction pointer - and calling the function pointer.\n\nIn this case - I execute a dynamic command. You can do some cool\ntricks with interpretors.\n\n----------\n\nFunction:   show_mmr32_bits()\n\nIn this case, we use the special TCL command \"upvar\" which tcl's way\nof passing things by reference. In this case, we want to reach up into\nthe callers lexical scope and find the array named \"NAMES\"\n\nThe rest of the function is pretty straight forward.\n\nFirst - we figure out the longest name.\nThen print 4 rows of 8bits - with names.\n\n\n**************************************************\n***************************************************\n=== TCL TOUR ===\nOpen the file: \"chips/atmel/at91/usarts.tcl\"\n===============\n\nFirst - about the AT91SAM series - all of the usarts\nare basically identical...\n\nSecond - there can be many of them.\n\nIn this case - I do some more TCL tricks to dynamically\ncreate functions out of thin air.\n\nSome assumptions:\n\nThe \"CHIP\" file has defined some variables in a proper form.\n\ni.e.: AT91C_BASE_US0 - for usart0,\n      AT91C_BASE_US1 - for usart1\n      ... And so on ...\n\nNear the end of the file - look for a large \"foreach\" loop that\nlooks like this:\n\n      foreach WHO { US0 US1 US2 US3 US4 .... } {\n\n      }\n\nIn this case, I'm trying to figure out what USARTs exist.\n\nStep 1 - is to determine if the NAME has been defined.\ni.e.: Does AT91C_BASE_USx - where X is some number exist?\n\nThe \"info exists VARNAME\" tells you if the variable exists.  Then -\ninside the IF statement... There is another loop. This loop is the\nname of various \"sub-registers\" within the USART.\n\nSome more trick are played with the [set VAR] backtick evaluation stuff.\nAnd we create two variables\n\nWe calculate and create the global variable name for every subregister in the USART.\nAnd - declare that variable as GLOBAL so the world can find it.\n\nThen - we dynamically create a function - based on the register name.\n\nLook carefully at how that is done. You'll notice the FUNCTION BODY is\na string - not something in {braces}. Why? This is because we need TCL\nto evaluate the contents of that string \"*NOW*\" - when $vn exists not\nlater, when the function \"show_FOO\" is invoked.\n\nLastly - we build a \"str\" of commands - and create a single function -\nwith the generated list of commands for the entire USART.\n\nWith that little bit of code - I now have a bunch of functions like:\n\n   show_US0, show_US1, show_US2, .... etc ...\n\n   And show_US0_MR, show_US0_IMR ... etc...\n\nAnd - I have this for every USART... without having to create tons of\nboiler plate yucky code.\n\n****************************************\n****************************************\nEND of the Tcl Intro and Walk Through\n****************************************\n****************************************\n\nFUTURE PLANS\n\n       Some \"GPIO\" functions...\n\n@endverbatim\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/release.txt",
    "content": "/** @page releases Release Processes\n\nThis page provides an introduction to the OpenOCD Release Processes:\n\n- @ref releasewhy - Explain the motivations for producing\n  releases on a regular basis.\n- @ref releasewho - Describes the responsibilities and\n  authority required to produce official OpenOCD releases.\n- @ref releasewhen - Provides guidelines for scheduling\n  activities for each release cycle.\n- @ref releasehow - Outlines all of the steps for the\n  processes used to produce and release the package source archives.\n- @ref releasescriptcmds - Introduces the automated @c release.sh script.\n\n@section releasewhy Why Produce Releases?\n\nThe OpenOCD maintainers produce <i>releases</i> periodically for many\nreasons.  This section provides the key reasons for making releases on a\nregular basis and why a set of <i>release processes</i> should be used\nto produce them.\n\nAt any time, <i>source archives</i> can be produced by running\n<code>make dist</code> in the OpenOCD project tree.  With the 0.2.0\nrelease, this command will package the tree into several popular archive\nformats: <code>openocd-\\<version\\>.{tar.gz,tar.bz2,zip}</code>.  If\nproduced properly, these files are suitable for release to the public.\n\nWhen properly versioned and released for users, these archives present\nseveral important advantages compared to using the source repository\n(including snapshots downloaded from that repository using gitweb):\n\n-# They allow others to package and distribute the code using\n   consistent version labels.  Users won't normally need to care\n   whose package they use, just the version of OpenOCD.\n-# They contain a working configure script and makefiles, which\n   were produced as part of creating the archive.\n-# Because they have been formally released by the project, users\n   don't need to try a random work-in-process revision.  Releasing\n   involves spending some time specifically on quality improvements,\n   including bugfixing source code and documentation.\n-# They provide developers with the flexibility needed to address\n   larger issues, which sometimes involves temporary breakage.\n\nHopefully, this shows several good reasons to produce regular releases,\nbut the release processes were developed with some additional design\ngoals in mind.  Specifically, the releases processes should have the\nfollowing properties:\n\n-# Produce successive sets of archives cleanly and consistently.\n-# Implementable as a script that automates the critical steps.\n-# Prevent human operators from producing broken packages, when possible.\n-# Allow scheduling and automation of building and publishing milestones.\n\nThe current release processes are documented in the following sections.\nThey attempt to meet these design goals, but improvements may still\nneed to be made.\n\n@subsection version_labels Version Labels\n\nUsers can display the OpenOCD version string in at least two\nways.  The command line <code>openocd -v</code> invocation\ndisplays it; as does the Tcl <code>version</code> command.\n\nLabels for released versions look like <em>0.3.0</em>, or\n<em>0.3.0-rc1</em> for a preliminary release.\nNon-released (developer) versions look like <em>0.3.0-dev</em>,\nor <em>0.3.0-rc1-dev</em>.\nIn all cases, additional tags may be appended to those base\nrelease version labels.\n\nThe <code>tools/release/version.sh</code> script is used to\nmanipulate version IDs found in the source tree.\n\n@subsubsection releaseversions Release Versions and Tags\n\nThe OpenOCD version string is composed of three numeric components\nseparated by two decimal points: @c x.y.z, where @c x is the @a major\nversion number, @c y is the @a minor number, and @c z is the @a micro.\nFor any <em>bug-fix</em> release, the micro version number will be non-zero\n(<code>z > 0</code>).  For a <i>minor release</i>, the micro version\nnumber will be zero (<code>z = 0</code>).  For a <i>major releases</i>,\nthe minor version will @a also be zero (<code>y = 0, z = 0</code>).\n\nAfter these required numeric components, release version strings\nmay contain tags such as <em>-rc1</em> or <em>-rc2</em>.\nThese 'rc' tags indicate \"release candidate\" versions of the package.\nLike major/minor/micro numbers, these are updated\nas part of the release process.\n\nThe release process includes version number manipulations to the tree\nbeing released, ensuring that all numbers are incremented (or rolled\nover) at the right time and in the proper locations of the repository.\nOne of those manipulations creates a repository tag matching that\nrelease's version label.\n\n@subsubsection releaseversionsdist Packager Versions\n\nDistributors of patched versions of OpenOCD are encouraged to extend the\nversion string with a unique version tag when producing external\nreleases, as this helps to identify your particular distribution series.\nKnowing that a release has such patches can be essential to tracking\ndown and fixing bugs.\n\nPackager version tags should always be suffixes to the version\ncode from the OpenOCD project, signifying modifications to the\noriginal code base.  Each packager release should have a unique\nversion.\n\nFor example, the following command will add a 'foo' tag to the\nconfigure.ac script of a local copy of the source tree, giving\na version label like <em>0.3.0-foo</em>:\n\n@code\ntools/release/version.sh tag add foo\n@endcode\n\nThis command will modify the configure.ac script in your working copy\nonly.  After running the @c bootstrap sequence, the tree can be patched\nand used to produce your own derived versions.  You might check that\nchange into a private branch of your git tree, along with the other\npatches you are providing.\n\nYou can also \"bump\" those tags (so \"foo1\" becomes \"foo2\" etc)\neach time a derived package is released, incrementing the tag's\nversion to facilitate tracking the changes you have distributed.\n\n@code\ntools/release/version.sh bump tag foo\n@endcode\n\nOf course, any patches in your branches must be provided to\nyour customers, and be in conformance with the GPL.  In most\ncases you should also work to merge your improvements to the\nmainline tree.\n\n@subsubsection version_tags Development Versions and Tags\n\nEverything except formal releases should have the tag <em>-dev</em>\nin their version number.  This helps developers identify reports\ncreated from non-release versions, and it can be detected and\nmanipulated by the release script.  Specifically, this tag will be\nremoved and re-added during the release process; it should never be\nmanipulated by developers in submitted patches.\n\nVersions built from developer trees may have additional tags.\nTrees built from git snapshots have <em>snapshot</em> tags.\nWhen built from a \"live\" git tree, tags specify\nspecific git revisions:\n\n0.3.0-rc1-dev-00015-gf37c9b8-dirty\n\nindicates a development tree based on git revision f37c9b8\n(a truncated version of a SHA1 hash) with some non-git\npatches applied (the <em>dirty</em> tag).  This information\ncan be useful when tracking down bugs.\n(Note that at this writing, the tags do not directly\ncorrespond to <code>git describe</code> output.  The\nhash ID can be used with <code>git show</code>, but\nthe relevant repository tag isn't <em>0.3.0-rc1-dev</em>;\nthis might change in the future.)\n\n@section releasewho Release Manager\n\nOpenOCD archive releases will be produced by an individual filling the\nrole of <i>Release Manager</i>, hereafter abbreviated as <i>RM</i>.  This\nindividual determines the schedule and executes the release processes\nfor the community.\n\n@subsection releasewhohow RM Authority\n\nEach release requires one individual to fulfill the RM role; however,\ngraceful transitions of this authority may take place at any time.  The\ncurrent RM may transfer their authority to another contributor in a post\nto the OpenOCD development mailing list.  Such delegation of authority\nmust be approved by the individual that will receive it and the\ncommunity of maintainers.  Initial arrangements with the new RM should\nbe made off-list, as not every contributor wants these responsibilities.\n\n@subsection releasewhowhat RM Responsibilities\n\nIn addition to the actual process of producing the releases, the RM is\nresponsible for keeping the community informed of all progress through\nthe release cycle(s) being managed.  The RM is responsible for managing\nthe changes to the package version, though the release tools should\nmanage the tasks of adding or removing any required development branch\ntags and incrementing the version.\n\nThese responsibilities matter most towards the end of the release\ncycle, when the RM creates the first RC and all contributors enter\na quality-improvement mode.  The RM works with other contributors\nto make sure everyone knows what kinds of fixes should merge, the\nstatus of major issues, and the release timetable.\n\nIn particular, the RM has the final decision on whether a given\nbug should block the release.\n\n@section releasewhen Release Schedule\n\nThe OpenOCD release process must be carried out on a periodic basis, so\nthe project can realize the benefits presented in answer to the question,\n@ref releasewhy.\n\nStarting with the 0.2.0 release, the OpenOCD project expects to produce\nnew releases every few months.\nBug fix releases could be provided more frequently.  These release\nschedule goals may be adjusted in the future, after the project\nmaintainers and distributors receive feedback and experience.\n\nMore importantly, the statements made in this section do not create an\nobligation by any member of the OpenOCD community to produce new\nreleases on regular schedule, now or in the future.\n\n@subsection releasewhenexample Sample Schedule\n\nThe RM must pro-actively communicate with the community from the\nbeginning of the development cycle through the delivery of the new\nrelease.  This section presents guidelines for scheduling key points\nwhere the community must be informed of changing conditions.\n\nIf Tn is the time of release n, then the following schedule\nmight describe some key T0-to-T1 release cycle milestones.\n\n- T0 ... End of T0 release cycle. T1 cycle starts, with merge\n  window opening.  Developers begin to merge queued work.\n- <em>... several weeks of merge window ...</em>\n- RC1 ... Close mainline to new work.  Produce RC1\n  release, begin testing phase; developers are in \"bugfix mode\",\n  all other work is queued; send out planned endgame schedule.\n- RC2 ... Produce RC2 and send schedule update to\n  mailing list, listing priorities for remaining fixes\n- <em>... more RC milestones, until ready ...</em>\n- T1: End of T1 release cycle. T2 cycle starts, with merge\n  window opening.  Developers begin to merge queued work.\n\nNote that until it happens, any date for T1 is just a goal.\nCritical bugs prevent releases from happening.  We are just\nbeginning to use this window-plus-RCs process, so the lengths\nof the merge windows versus the RC phase is subject to change.\nMost projects have RC phases of a month or more.\n\nSome additional supplemental communication will be desirable.  The above\nlist omits the step-by-step instructions to daily release management.\nIndividuals performing release management need to have the ability to\ninteract proactively with the community as a whole, anticipating when\nsuch interaction will be required and giving ample notification.\n\nThe next section explains why the OpenOCD project allows significant\nflexibility in the part of the development that precedes the release\nprocess.\n\n@subsection releasewhenflex Schedule Flexibility\n\nThe Release Manager should attempt to follow the guidelines in this\ndocument, but the process of scheduling each release milestone should be\ncommunity driven at the start.  Features that don't complete before\nthe merge window closes can be held (perhaps in some branch) until\nthe next merge window opens, rather than delaying the release cycle.\n\nThe Release\nManager cannot schedule the work that will be done on the project,\nwhen it will be submitted, reviewed, and deemed suitable to be committed.\nThat is, the RM cannot act as a priest in a cathedral; OpenOCD uses\nthe bazaar development model.  The release schedule must adapt\ncontinuously in response to changes in the rate of work.\nFewer releases may be\nrequired if developers contribute less patches, and more releases may be\ndesirable if the project continues to grow and experience high rates of\ncommunity contribution.  During each cycle, the RM should be tracking\nthe situation and gathering feedback from the community.\n\n@section releasehow Release Process: Step-by-Step\n\nThe release process is not final; it may need more iterations\nto work out bugs.\nWhile there are release scripts, key steps require community\nsupport; the Release Manager isn't the only participant.\n\nThe following steps should be followed to produce each release:\n\n-# Produce final patches using a local clone of mainline.  Nobody\n   except the RM should be committing anything.  <em>Everyone with commit\n   privileges needs to know and agree to this in advance!</em>  Even the RM\n   only commits a handful of updates as part of the release process\n   itself ... to files which are part of the version identification scheme\n   or release process; and to create the version tag; and then to open the\n   merge window for the next release cycle.\n  -# Finalize @c the NEWS file to describe the changes in the release\n    - This file is used to automatically post \"blurbs\" about the project.\n    - This material should have been produced during the development cycle,\n      by adding items for each @c NEWS-worthy contribution, when committed\n      during the merge window.  (One part of closing the merge window, by\n      opening the RC phase of the release, is the commitment to hold all\n      further such contributions until the next merge window opens.)\n    - The RM should make sure nothing important was omitted, as part of\n      the RC1 cycle.  From then on, no more updates to NEWS content should\n      be needed (except to seed the process for the next release, or maybe\n      if a significant and longstanding bug is fixed late in the RC phase).\n  -# Bump library version if our API changed (not yet required)\n  -# Update and commit the final package version in @c configure.ac:\n     (The <code>tools/release/version.sh</code> script might help ensure\n     the versions are named properly.):\n    -# Remove @c -dev tag.\n    -# Update any @c -rc tag:\n      - If producing the final release from an -rc series, remove it\n      - If producing the first RC in a series, add rc1\n      - If producing the next RC in a series, bump the rc number\n    -# Commit that version change, with a good descriptive comment.\n  -# Create a git tag for the final commit, with a tag name matching\n     the version string in <code>configure.ac</code> (including <em>-rcN</em>\n     where relevant):\n@verbatim\nPACKAGE_VERSION=\"x.y.z\"\nPACKAGE_TAG=\"v${PACKAGE_VERSION}\"\ngit tag -m \"The openocd-${PACKAGE_VERSION} release.\" \"${PACKAGE_TAG}\"\n@endverbatim\n  -# Do not push those changes to mainline yet; only builds using the\n     source archives you will be creating should ever be labeled as\n     official releases (with no \"-dev\" suffix).  Since mainline is a\n     development tree, these will be pushed later, as part of opening\n     the merge window for the next release cycle (restoring the \"-dev\"\n     suffix for that next release.)  Those version and tag updates are\n     the last ones to be included in the release being made.\n-# Produce the release files, using the local clone of the source\n  tree which holds the release's tag and updated version in\n  @c configure.ac ... this is used only to produce the release, and\n  all files should already be properly checked out.\n  -# Run <code>tools/release.sh package</code> to produce the\n\tsource archives.  This automatically bootstraps and\n\tconfigures the process.\n  -# Run <code>tools/release.sh stage</code> to create an @c archives\n\tdirectory with the release data, including MD5 and SHA1\n\tchecksum files.\n  -# Sanity check at least one of those archives, by extracting and\n     configuring its contents, using them to build a copy of OpenOCD,\n     and verifying that the result prints the correct release version\n     in its startup banner.  (For example,\n     \"configure --enable-parport\"\n     then \"make\" and run \"src/openocd -v\" as a sanity check.)\n  -# Run <code>make docs</code> to create the\n     documentation which will be published.\n-# Upload packages and post announcements of their availability:\n  -# Release packages into files section of project sites:\n    - SF.net:\n     -# Under \"Project Admin\", use the \"File Manager\"\n     -# Create a new folder under \"openocd\" named \"${PACKAGE_VERSION}\"\n     -# Upload the @c NEWS file and mark it as the release notes.\n     -# Upload the three source archive files, using the Web interface,\n     \tinto that folder.  Verify the upload worked OK by checking the\n\tMD5 and SHA1 checksums computed by SourceForge against the\n\tversions created as part of staging the release.\n     -# Also upload doc/openocd.pdf (the User's Guide) so the version\n        matching each release will be easily available.\n     -# Select each file in the release, and use the property panel\n        to set its type and select the right release notes.\n       - .tar.bz2: Linux, Mac\n       - .tar.gz: BSD, Solaris, Others\n       - .zip: Windows\n       - For openocd.pdf just associate it with the right release notes.\n     -# Create an SF.net project news update.\n  -# Depending on how paranoid you're feeling today, verify the images by\n     downloading them from the websites and making sure there are no\n     differences between the downloaded copies and your originals.\n  -# Publish User's and Developer's Guides to the project web sites:\n     -# Use SCP to update the SF.net web site with PDF and HTML for the\n          User's Guide, and HTML for the developer's guide ... you can\n\t  instantiate a shell.sourceforge.net instance and set up symlinks\n\t  from your home directory, to simplify this process.\n  -# Post announcement e-mail to the openocd-development list.\n  -# optionally:\n     -# Post an update on the OpenOCD blog.\n     -# Announce updates on freshmeat.net and other trackers.\n     -# Submit updates to news feeds (e.g. Digg, Reddit, etc.).\n-# Resume normal development on mainline, by opening the merge window for\n  the next major or minor release cycle.  (You might want to do this\n  before all the release bits are fully published.)\n  - Update the version label in the @c configure.ac file:\n     - Restore @c -dev version tag.\n     - For a new minor release cycle, increment the release's minor number\n     - For a new major release cycle, increment the release's major number\n       and zero its minor number\n  - Archive @c NEWS file as \"<code>doc/news/NEWS-${PACKAGE_VERSION}</code>\".\n  - Create a new @c NEWS file for the next release\n  - Commit those changes.\n  - Push all the updates to mainline.\n     - Last updates for the release, including the release tag (you\n       will need to \"git push --tags\").\n     - Updates opening the merge window\n  - At this point, it's OK for committers to start pushing changes\n    which have been held off until the next release.  (Any bugfixes to\n    this release will be against a bug-fix release branch starting from\n    the commit you tagged as this release, not mainline.)\n  - Announce to the openocd-development list.  Ideally, you will also\n    be able to say who is managing the next release cycle.\n\nTo start a bug-fix release branch:\n-# Create a new branch, starting from a major or\n   minor release tag\n-# Restore @c -dev version tag.\n-# Bump micro version number in configure.ac\n-# Backport bugfix patches from mainline into that branch.\n   (Always be sure mainline has the fix first, so it's hard\n   to just lose a bugfix.)\n-# Commit and push those patches.\n-# When desired, release as above ... except note that the next\n   release of a bugfix branch is never a new major or minor release\n\n@subsection releasescriptcmds Release Script Commands\n\nThe @c release.sh script automates some of the steps involved\nin making releases, simplifying the Release Manager's work.\n\nThe release script can be used for two tasks:\n- Creating releases and starting a new release cycle:\n@code\ngit checkout master\ntools/release.sh --type=minor --final --start-rc release\n@endcode\n- Creating a development branch from a tagged release:\n@code\ngit checkout 'v0.2.0'\ntools/release.sh --type=micro branch\n@endcode\n\nBoth of these variations make automatic commits and tags in your\nrepository, so you should be sure to run it on a cloned copy before\nproceeding with a live release.\n\n@subsection releasescriptopts Release Script Options\n\nThe @c release.sh script recognizes some command-line options that\naffect its behavior:\n\n- The @c --start-rc indicates that the new development release cycle\n  should start with @c -rc0.  Without this, the @c -rc tag will be omitted,\n  leading to non-monotonic versioning of the in-tree version numbers.\n- The @c --final indicates that the release should drop the @c -rc tag,\n  to going from @c x.y.z-rcN-dev to x.y.z.\n\n@subsection releasescriptenv Release Script Environment\n\nThe @c release.sh script recognizes some environment variables which\naffect its behavior:\n\n- @c CONFIG_OPTS : Passed as options to the configure script.\n- @c MAKE_OPTS : Passed as options to the 'make' processes.\n\n@section releasetutorial Release Tutorials\n\nThis section should contain a brief tutorial for using the Release\nScript to perform release tasks, but the new script needs to be\nused for 0.3.0.\n\n@section releasetodo Release Script Shortcomings\n\nImproved automated packaging and distribution of OpenOCD requires more\npatching of the configure script.  The final release script should be\nable to manage most steps of the processes.  The steps requiring user\ninput could be guided by an \"assistant\" that walks the Release Manager\nthrough the process from beginning to end, performing basic sanity\nchecks on their various inputs (e.g. the @c NEWS blurb).\n\n */\n/** @file\nThis file contains the @ref releases page.\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/scripting.txt",
    "content": "/** @page scripting Scripting Overview\n\n@section scriptingisnt What scripting will not do\n\nThe scripting support is intended for developers of OpenOCD.\nIt is not the intention that normal OpenOCD users will\nuse tcl scripting extensively, write lots of clever scripts,\nor contribute back to OpenOCD.\n\nTarget scripts can contain new procedures that end users may\ntinker to their needs without really understanding tcl.\n\nSince end users are not expected to mess with the scripting\nlanguage, the choice of language is not terribly important\nto those same end users.\n\nJim Tcl was chosen as it was easy to integrate, works\ngreat in an embedded environment and Øyvind Harboe\nhad experience with it.\n\n@section scriptinguses Uses of scripting\n\nDefault implementation of procedures in tcl/procedures.tcl.\n\n- Polymorphic commands for target scripts.\n  - there will be added some commands in Tcl that the target\n    scripts can replace.\n  - produce \\<productionfile\\> \\<serialnumber\\>. Default implementation\n    is to ignore serial number and write a raw binary file\n    to beginning of first flash. Target script can dictate\n    file format and structure of serialnumber. Tcl allows\n    an argument to consist of e.g. a list so the structure of\n    the serial number is not limited to a single string.\n  - reset handling. Precise control of how srst, trst &\n    tms is handled.\n- replace some parts of the current command line handler.\n  This is only to simplify the implementation of OpenOCD\n  and will have no externally visible consequences.\n  Tcl has an advantage in that it's syntax is backwards\n  compatible with the current OpenOCD syntax.\n- external scripting. Low level tcl functions will be defined\n  that return machine readable output. These low level tcl\n  functions constitute the tcl api. flash_banks is such\n  a low level tcl proc. \"flash banks\" is an example of\n  a command that has human readable output. The human\n  readable output is expected to change in between versions\n  of OpenOCD. The output from flash_banks may not be\n  in the preferred form for the client. The client then\n  has two choices a) parse the output from flash_banks\n  or b) write a small piece of tcl to output the\n  flash_banks output to a more suitable form. The latter may\n  be simpler.\n\n\n@section scriptingexternal External scripting\n\nThe embedded Jim Tcl interpreter in OpenOCD is very limited\ncompared to any full scale PC hosted scripting language.\n\nThe goal is to keep the internal Jim Tcl interpreter as\nsmall as possible and allow any advanced scripting,\nespecially scripting that interacts with the host,\nrun on the host and talk to OpenOCD via the TCP/IP\nscripting connection.\n\nAnother problem with Jim Tcl is that there is no debugger\nfor it.\n\nWith a bit of trickery it should be possible to run Jim\nTcl scripts under a Tcl interpreter on a PC. The advantage\nwould be that the Jim Tcl scripts could be debugged using\na standard PC Tcl debugger.\n\nThe rough idea is to write an unknown proc that sends\nunknown commands to OpenOCD.\n\nBasically a PC version of startup.tcl. Patches most\ngratefully accepted! :-)\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/server.txt",
    "content": "/** @page serverdocs OpenOCD Server APIs\n\nOpenOCD provides support for implementing different types of servers.\nPresently, the following servers have APIs that can be used.\n\n  - @subpage servergdb\n  - @subpage servertelnet\n  - @subpage serverhttp\n\n@section serverdocsoverview Overview\n\nWhat follows is a development history, and describes some of the intent\nof why certain features exist within OpenOCD along with the reasoning\nbehind them.\n\nThis roadmap section was written May 2009 - about 9 to 12 months\nafter some of this work had started, it attempts to document some of\nthe reasons why certain features exist within OpenOCD at that time.\n\n@section serverdocsbg Background\n\nIn early 2008, Oyvind Harboe and Duane Ellis had talked about how to\ncreate a reasonable GUI for OpenOCD - something that is non-invasive,\nsimple to use and maintain, and does not tie OpenOCD to many other\npackages.  It would be wrong to \"spider web\" requirements into other\nexternal packages.  That makes it difficult for developers to\nwrite new code and creates a support nightmare.\n\nIn many ways, people had talked about the need for some type of\nhigh-level interface to OpenOCD, because they only had two choices:\n- the ability to script: via an external program the actions of OpenOCD.\n- the ability to write a complex internal commands: native 'commands'\n  inside of OpenOCD was complicated.\n\nFundamentally, the basic problem with both of those would be solved\nwith a script language:\n\n-# <b>Internal</b>: simple, small, and self-contained.\n-# <b>Cross Language</b>: script friendly front-end\n-# <b>Cross Host</b>: GUI Host interface\n-# <b>Cross Debugger</b>: GUI-like interface\n\nWhat follows hopefully shows how the plans to solve these problems\nmaterialized and help to explain the grand roadmap plan.\n\n@subsection serverdocsjim Why JimTCL? The Internal Script Language\n\nAt the time, the existing \"command context schema\" was proving itself\ninsufficient.  However, the problem was also considered from another\ndirection: should OpenOCD be first class and the script second class?\nWhich one rules?\n\nIn the end, OpenOCD won, the conclusion was that simpler will be better.\nLet the script language be \"good enough\"; it would not need numerous\nfeatures.  Imagine debugging an embedded Perl module while debugging\nOpenOCD. Yuck.  OpenOCD already has a complex enough build system, why\nmake it worse?\n\nThe goal was to add a simple language that would be moderately easy to\nwork with and be self-contained.  JimTCL is a single C and single H\nfile, allowing OpenOCD to avoid the spider web of dependent packages.\n\n@section serverdocstcl TCL Server Port\n\nThe TCL Server port was added in mid-2008.  With embedded TCL, we can\nwrite scripts internally to help things, or we can write \"C\" code  that\ninterfaces well with TCL.\n\nFrom there, the developers wanted to create an external front-end that\nwould be @a very usable and that @a any language could utilize,\nallowing simple front-ends to be (a) cross-platform (b) language\nagnostic, and (c) easy to develop and use.\n\nSimple ASCII protocols are easy.  For example, HTTP, FTP (control), and\nSMTP are all text-based.  All of these examples are widely and\nwell-known, and they do not require high-speed or high-volume.  They\nalso support a high degree of interoperability with multiple systems.\nThey are not human-centric protocols; more correctly, they are rigid,\nterse, simple ASCII protocols that are easily parsable by a script.\n\nThus, the TCL server -- a 'machine' type socket interface -- was added\nwith the hope was it would output simple \"name-value\" pair type\ndata.  At the time, simple name/value pairs seemed reasonably easier to\ndo at the time, though Maybe it should output JSON;\n\nSee here:\n\n   http://www.mail-archive.com/openocd-development%40lists.berlios.de/msg00248.html\n\nThe hope was that one could write a script in what ever language you want\nand do things with it!\n\n@section serverdocsgui GUI Like Interfaces\n\nA lot has been said about various \"widigit-foo-gui-library is so\nwonderful\".  Please refer back to the domino and spider web problem of\ndependencies.  Sure, you may well know the WhatEver-GUI library, but\nmost others will not (including the next contributor to OpenOCD).\nHow do we solve that problem?\n\nFor example, Cygwin can be painful, Cygwin GUI packages want X11\nto be present, crossing the barrier between MinGW and Cygwin is\npainful, let alone getting the GUI front end to work on MacOS, and\nLinux, yuck yuck yuck. Painful, very very painful.\n\nWhat works easier and is less work is what is already present in every\nplatform?  The answer: A web browser.  In other words, OpenOCD could\nserve out embedded web pages via \"localhost\" to your browser.\n\nLong before OpenOCD had a TCL command line, Zylin AS built their ZY1000\ndevice with a built-in HTTP server.  Later, they were willing to both\ncontribute and integrate most of that work into the main tree.\n\n@subsection serverdocsother Other Options Considered\n\nWhat if a web browser is not acceptable i.e.: You want to write your own\nfront gadget in Eclipse, or KDevelop, or PerlTK, Ruby, or what ever\nthe latest and greatest Script De Jour is.\n\n- Option 1: Can we transport this extra data through the GDB server\nprotocol? In other words, can we extend the GDB server protocol?\nNo, Eclipse wants to talk to GDB directly and control the GDB port.\n\n- Option 2: SWIG front end (libopenocd): Would that work?\n\nThat's painful - unless you design your api to be very simplistic -\nevery language has it's own set of wack-ness, parameter marshaling is\npainful.\n\nWhat about \"callbacks\" and structures, and other mess. Imagine\ndebugging that system.  When JimTCL was introduced Spencer Oliver had\nquite a few well-put concerns (Summer 2008) about the idea of \"TCL\"\ntaking over OpenOCD.  His concern is and was: how do you debug\nsomething written in 2 different languages?  A \"SWIG\" front-end is\nunlikely to help that situation.\n\n@subsection serverdoccombined Combined: Socket & WebServer Benefits\n\nSeriously think about this question: What script language (or compiled\nlanguage) today cannot talk directly to a socket? Every thing in the\nOpenOCD world can work a socket interface. Any host side tool can talk\nto Localhost or remote host, however one might want to make it work.\n\nA socket interface is very simple. One could write a Java application\nand serve it out via the embedded web server, could it - or something\nlike it talk to the built in TCL server? Yes, absolutely! We are on to\nsomething here.\n\n@subsection serverdocplatforms Platform Permutations\n\nLook at some permutations where OpenOCD can run; these \"just work\" if\nthe Socket Approach is used.\n\n\n- Linux/Cygwin/MinGW/MacOSX/FreeBSD development Host Locally\n- OpenOCD with some dongle on that host\n\n\n- Linux/Cygwin/MinGW/MacOS/FreeBSD development host\n- DONGLE:  TCP/IP based ARM-Linux perhaps at91rm9200 or ep93xx.c, running openocd.\n\n\n- Windows Cygwin/X desktop environment.\n- Linux development host (via remote X11)\n- Dongle:  \"eb93xx.c\" based Linux board\n\n\n@subsection serverdocfuture Development Scale Out\n\nDuring 2008, Duane Ellis created some TCL scripts to display peripheral\nregister contents. For example, look at the sam7 TCL scripts, and the\nstm32 TCL scripts.  The hope was others would create more.\n\n\nA good example of this is display/view the peripheral registers on\nyour embedded target.  Lots of commercial embedded debug tools have\nthis, some can show the TIMER registers, the interrupt controller.\n\nWhat if the chip companies behind STM32, or PIC32, AT91SAM chips -\nwanted to write something that makes working with their chip better,\neasier, faster, etc.\n\n@a Question: How can we (the OpenOCD group) make that really fancy\nstuff across multiple different host platforms?\n\nRemember: OpenOCD runs on:\n-# Linux via USB,\n-# ARM Linux - bit-banging GPIO pins\n-# MacOSX\n-# FreeBSD\n-# Cygwin\n-# MinGW32\n-# Ecos\n\nHow can we get that to work?\n\n@subsection serverdocdebug What about Debugger Plugins?\n\nReally GDB is nice, it works, but it is not a good embedded debug tool.\nOpenOCD cannot work in a GUI when one cannot get to its command line.\nSome GDB front-end developers have pedantic designs that refuse any and\nall access to the GDB command line (e.g.  http://www.kdbg.org/todo.php).\n\nThe TELNET interface to OpenOCD works, but the intent of that interface\nis <b>human interaction</b>. It must remain available, developers depend\nupon it, sometimes that is the only scheme available.\n\nAs a small group of developers, supporting all the platforms and\ntargets in the debugger will be difficult, as there are enough problem\nwith the plethora of Adapters, Chips, and different target boards.\nYes, the TCL interface might be suitable, but it has not received much\nlove or attention.  Perhaps it will after you read and understand this.\n\nOne reason might be, this adds one more host side requirement to make\nuse of the feature.  In other words, one could write a Python/TK\nfront-end, but it is only useable if you have Python/TK installed.\nMaybe this can be done via Eclipse, but not all developers use Eclipse.\nMany developers use Emacs (possibly with GUD mode) or vim and will not\naccept such an interface.  The next developer reading this might be\nusing Insight (GDB-TK) - and somebody else - DDD..\n\nThere is no common host-side GDB front-end method.\n\n@section serverdocschallenge Front-End Scaling\n\nMaybe we are wrong - ie: OpenOCD + some TK tool\n\nRemember: OpenOCD is often (maybe 99.9%) of the time used with\nGDB-REMOTE.  There is always some front-end package - be it command-line\nGDB under DDD, Eclipse, KDevelop, Emacs, or some other package\n(e.g. IAR tools can talk to GDB servers).  How can the OpenOCD\ndevelopers make that fancy target display GUI visible under 5 to 10\ndifferent host-side GDB..\n\nSure - a <em>man on a mission</em> can make that work.  The GUI might be\nlibopenocd + Perl/TK, or maybe an Eclipse Plug-in.\nThat is a development support nightmare for reasons described\nabove. We have enough support problems as it is with targets, adapters,\netc.\n\n@section serverdocshttpbg HTTP Server Background\n\nOpenOCD includes an HTTP server because most development environments\nare likely contain a web browser.  The web browser can talk to OpenOCD's\nHTTP server and provide a high-level interfaces to the program.\nAltogether, it provides a universally accessible GUI for OpenOCD.\n\n@section serverdocshtml Simple HTML Pages\n\nThere is (or could be) a simple \"Jim TCL\" function to read a memory\nlocation. If that can be tied into a TCL script that can modify the\nHTTP text, then we have a simple script-based web server with a JTAG\nengine under the hood.\n\nImagine a web page - served from a small board with two buttons:\n\"LED_ON\" and \"LED_OFF\", each click - turns the LED on or OFF, a very\nsimplistic idea.  Little boards with web servers are great examples of\nthis: Ethernut is a good example and Contiki (not a board, an embedded\nOS) is another example.\n\nOne could create a simple: <b>Click here to display memory</b> or maybe\n<b>click here to display the UART REGISTER BLOCK</b>; click again and see\neach register explained in exquisite detail.\n\nFor an STM32, one could create a simple HTML page, with simple\nsubstitution text that the simple web server use to substitute the\nHTML text JIMTCL_PEEK32( 0x12345678 ) with the value read from\nmemory. We end up with an HTML page that could list the contents of\nevery peripheral register on the target platform.\n\nThat also is transportable, regardless of the OpenOCD host\nplatform: Linux/X86, Linux/ARM, FreeBSD, Cygwin, MinGW, or MacOSX.\nYou could even port OpenOCD to an Android system and use it as a\nbit-banging JTAG Adapter serving web pages.\n\n@subsection serverdocshtmladv Advanced HTML Pages\n\nJava or JavaScript could be used to talk back to the TCL port.  One\ncould write a Java, AJAX, FLASH, or some other developer friendly\ntoolbox and get a real cross-platform GUI interface. Sure, the interface\nis not native - but it is 100% cross-platform!\n\nOpenOCD current uses simple HTML pages; others might be an Adobe FLASH\nexpert, or a Java Expert.  These possibilities could allow the pages\nremain cross-platform but still provide a rich user-interface\nexperience.\n\nDon't forget it can also be very simple, exactly what one developer\ncan contribute, a set of very simple web pages.\n\n@subsection serverdocshtmlstatus HTTP/HTML Status\n\nAs of May 2009, much of the HTML pages were contributed by Zylin AS,\nhence they continue to retain some resemblance to the ZY1000 interface.\n\nPatches would be welcome to move these parts of the system forward.\n\n */\n\n/** @page servergdb OpenOCD GDB Server API\n\nThis section needs to be expanded.\n\n */\n\n/** @page servertelnet OpenOCD Telnet Server API\n\nThis section needs to be expanded.\n\n */\n\n/** @page serverhttp OpenOCD http Server API\n\nThis section needs to be expanded.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/style.txt",
    "content": "/** @page styleguide Style Guides\n\nThe goals for each of these guides are:\n- to produce correct code that appears clean, consistent, and readable,\n- to allow developers to create patches that conform to a standard, and\n- to eliminate these issues as points of future contention.\n\nSome of these rules may be ignored in the spirit of these stated goals;\nhowever, such exceptions should be fairly rare.\n\nThe following style guides describe a formatting, naming, and other\nconventions that should be followed when writing or changing the OpenOCD\ncode:\n\n- @subpage styletcl\n- @subpage stylec\n- @subpage styleperl\n- @subpage styleautotools\n\nIn addition, the following style guides provide information for\nproviding documentation, either as part of the C code or stand-alone.\n\n- @subpage styledoxygen\n- @subpage styletexinfo\n- @subpage stylelatex\n\nFeedback would be welcome to improve the OpenOCD guidelines.\n\n */\n/** @page styletcl TCL Style Guide\n\nOpenOCD needs to expand its Jim/TCL Style Guide.\n\nMany of the guidelines listed on the @ref stylec page should apply to\nOpenOCD's Jim/TCL code as well.\n\n */\n/** @page stylec C Style Guide\n\nThis page contains guidelines for writing new C source code for the\nOpenOCD project.\n\n@section styleformat Formatting Guide\n\n- remove any trailing white space at the end of lines.\n- use TAB characters for indentation; do NOT use spaces.\n- displayed TAB width is 4 characters.\n- use Unix line endings ('\\\\n'); do NOT use DOS endings ('\\\\r\\\\n')\n- limit adjacent empty lines to at most two (2).\n- remove any trailing empty lines at the end of source files\n- do not \"comment out\" code from the tree nor put it within a block\n  @code\n  #if 0\n  ...\n  #endif\n  @endcode\n  otherwise it would never be checked at compile time and when new\n  patches get merged it could be not compilable anymore.\n  Code that is not fully working nor ready for submission should\n  instead be removed entirely (git can retrieve the old version).\n  For exceptional cases that require keeping some unused code, let\n  the compiler check it by putting it in a block\n  @code\n  if (false) {\n      /* explain why this code should be kept here */\n      ...\n  }\n  @endcode\n- in a @c switch statement align the @c switch with the @c case label\n  @code\n  switch (dev_id) {\n  case 0x0123:\n      size = 0x10000;\n      break;\n  case 0x0412:\n      size = 0x20000;\n      break;\n  default:\n      size = 0x40000;\n      break;\n  }\n  @endcode\n- in an <tt> if / then / else </tt> statement, if only one of the conditions\n  require curly brackets due to multi-statement block, put the curly brackets\n  also to the other condition\n  @code\n  if (x > 0)\n      a = 12 + x;\n  else\n      a = 24;\n  @endcode\n  @code\n  if (x > 0) {\n      a = 12 + x;\n  } else {\n      a = 24;\n      x = 0;\n  }\n  @endcode\n\nFinally, try to avoid lines of code that are longer than 72-80 columns:\n\n- long lines frequently indicate other style problems:\n  - insufficient use of static functions, macros, or temporary variables\n  - poor flow-control structure; \"inverted\" logical tests\n- a few lines may be wider than this limit (typically format strings), but:\n  - all C compilers will concatenate series of string constants.\n  - all long string constants should be split across multiple lines.\n  - do never exceed 120 columns.\n\n@section stylenames Naming Rules\n\n- most identifiers must use lower-case letters (and digits) only.\n  - macros must use upper-case letters (and digits) only.\n  - OpenOCD identifiers should NEVER use @c MixedCaps.\n- @c typedef names must end with the '_t' suffix.\n  - This should be reserved for types that should be passed by value.\n  - Do @b not mix the typedef keyword with @c struct.\n- use underline characters between consecutive words in identifiers\n  (e.g. @c more_than_one_word).\n\n@section style_include_guards Include Guards\n\nEvery header file should have a unique include guard to prevent multiple\ninclusion.\nTo guarantee uniqueness, an include guard should be based on the filename and\nthe full path in the project source tree.\n\nFor the header file src/helper/jim-nvp.h, the include guard would look like\nthis:\n\n@code\n#ifndef OPENOCD_HELPER_JIM_NVP_H\n#define OPENOCD_HELPER_JIM_NVP_H\n\n/* Your code here. */\n\n#endif /* OPENOCD_HELPER_JIM_NVP_H */\n@endcode\n\n@section stylec99 C99 Rules\n\n- inline functions\n- @c // comments -- in new code, prefer these for single-line comments\n- trailing comma allowed in enum declarations\n- designated initializers ( .field = value )\n- variables declarations should occur at the point of first use\n- new block scopes for selection and iteration statements\n- use malloc() to create dynamic arrays. Do @b not use @c alloca\nor variable length arrays on the stack. non-MMU hosts(uClinux) and\npthreads require modest and predictable stack usage.\n\n@section styletypes Type Guidelines\n- use native types (@c int or <tt> unsigned int </tt>) if the type is not important\n  - if size matters, use the types from \\<stdint.h\\> or \\<inttypes.h\\>:\n    - @c int8_t, @c int16_t, @c int32_t, or @c int64_t: signed types of specified size\n    - @c uint8_t, @c uint16_t, @c uint32_t, or @c uint64_t: unsigned types of specified size\n    - use the associated @c printf and @c scanf formatting strings for these types\n      (e.g. @c PRId8, PRIx16, SCNu8, ...)\n  - do @b NOT redefine @c uN types from \"types.h\"\n  - use type @c target_addr_t for target's address values\n  - prefer type <tt> unsigned int </tt> to type @c unsigned\n\n@section stylefunc Functions\n\n- static inline functions should be preferred over macros:\n@code\n/* do NOT define macro-like functions like this... */\n#define CUBE(x) ((x) * (x) * (x))\n/* instead, define the same expression using a C99 inline function */\nstatic inline int cube(int x) { return x * x * x; }\n@endcode\n- Functions should be declared static unless required by other modules\n  - define static functions before first usage to avoid forward declarations.\n- Functions should have no space between its name and its parameter list:\n@code\nint f(int x1, int x2)\n{\n\t...\n\tint y = f(x1, x2 - x1);\n\t...\n}\n@endcode\n- Separate assignment and logical test statements.  In other words, you\nshould write statements like the following:\n@code\n// separate statements should be preferred\nresult = foo();\nif (result != ERROR_OK)\n\t...\n@endcode\nMore directly, do @b not combine these kinds of statements:\n@code\n// Combined statements should be avoided\nif ((result = foo()) != ERROR_OK)\n\treturn result;\n@endcode\n- Do not compare @c bool values with @c true or @c false but use the\n  value directly\n@code\nif (!is_enabled)\n    ...\n@endcode\n- Avoid comparing pointers with @c NULL\n@code\nbuf = malloc(buf_size);\nif (!buf) {\n    LOG_ERROR(\"Out of memory\");\n    return ERROR_FAIL;\n}\n@endcode\n\n */\n/** @page styledoxygen Doxygen Style Guide\n\nThe following sections provide guidelines for OpenOCD developers\nwho wish to write Doxygen comments in the code or this manual.\nFor an introduction to Doxygen documentation,\nsee the @ref primerdoxygen.\n\n@section styledoxyblocks Doxygen Block Selection\n\nSeveral different types of Doxygen comments can be used; often,\none style will be the most appropriate for a specific context.\nThe following guidelines provide developers with heuristics for\nselecting an appropriate form and writing consistent documentation\ncomments.\n\n-# use @c /// to for one-line documentation of instances.\n-# for documentation requiring multiple lines, use a \"block\" style:\n@verbatim\n/**\n * @brief First sentence is short description.  Remaining text becomes\n * the full description block, where \"empty\" lines start new paragraphs.\n *\n * One can make text appear in @a italics, @b bold, @c monospace, or\n * in blocks such as the one in which this example appears in the Style\n * Guide.  See the Doxygen Manual for the full list of commands.\n *\n * @param foo For a function, describe the parameters (e.g. @a foo).\n * @returns The value(s) returned, or possible error conditions.\n */\n@endverbatim\n  -# The block should start on the line following the opening @c /\\**.\n  -# The end of the block, @c *&zwj;/, should also be on its own line.\n  -# Every line in the block should have a @c '*' in-line with its start:\n    - A leading space is required to align the @c '*' with the @c /\\** line.\n    - A single \"empty\" line should separate the function documentation\n      from the block of parameter and return value descriptions.\n    - Except to separate paragraphs of documentation, other extra\n      \"empty\" lines should be removed from the block.\n  -# Only single spaces should be used; do @b not add mid-line indentation.\n-# If the total line length will be less than 72-80 columns, then\n  - The @c /\\**< form can be used on the same line.\n  - This style should be used sparingly; the best use is for fields:\n    @verbatim int field; /**< field description */ @endverbatim\n\n@section styledoxyall Doxygen Style Guide\n\nThe following guidelines apply to all Doxygen comment blocks:\n\n-# Use the @c '\\@cmd' form for all doxygen commands (do @b not use @c '\\\\cmd').\n-# Use symbol names such that Doxygen automatically creates links:\n  -# @c function_name() can be used to reference functions\n    (e.g. flash_set_dirty()).\n  -# @c struct_name::member_name should be used to reference structure\n    fields in the documentation (e.g. @c flash_driver::name).\n  -# URLS get converted to markup automatically, without any extra effort.\n  -# new pages can be linked into the hierarchy by using the @c \\@subpage\n    command somewhere the page(s) under which they should be linked:\n  -# use @c \\@ref in other contexts to create links to pages and sections.\n-# Use good Doxygen mark-up:\n  -# '\\@a' (italics) should be used to reference parameters (e.g. <i>foo</i>).\n  -# '\\@b' (bold) should be used to emphasizing <b>single</b> words.\n  -# '\\@c' (monospace) should be used with <code>file names</code> and\n  <code>code symbols</code>, so they appear visually distinct from\n  surrounding text.\n  -# To mark-up multiple words, the HTML alternatives must be used.\n-# Two spaces should be used when nesting lists; do @b not use '\\\\t' in lists.\n-# Code examples provided in documentation must conform to the Style Guide.\n\n@section styledoxytext Doxygen Text Inputs\n\nIn addition to the guidelines in the preceding sections, the following\nadditional style guidelines should be considered when writing\ndocumentation as part of standalone text files:\n\n-# Text files must contain Doxygen at least one comment block:\n  -# Documentation should begin in the first column (except for nested lists).\n  -# Do NOT use the @c '*' convention that must be used in the source code.\n-# Each file should contain at least one @c \\@page block.\n  -# Each new page should be listed as a \\@subpage in the \\@page block\n  of the page that should serve as its parent.\n  -# Large pages should be structure in parts using meaningful \\@section\n  and \\@subsection commands.\n-# Include a @c \\@file block at the end of each Doxygen @c .txt file to\n  document its contents:\n  - Doxygen creates such pages for files automatically, but no content\n    will appear on them for those that only contain manual pages.\n  - The \\@file block should provide useful meta-documentation to assist\n    technical writers; typically, a list of the pages that it contains.\n  - For example, the @ref styleguide exists in @c doc/manual/style.txt,\n    which contains a reference back to itself.\n-# The \\@file and \\@page commands should begin on the same line as\n   the start of the Doxygen comment:\n@verbatim\n/** @page pagename Page Title\n\nDocumentation for the page.\n\n */\n/** @file\n\nThis file contains the @ref pagename page.\n\n */\n@endverbatim\n\nFor an example, the Doxygen source for this Style Guide can be found in\n@c doc/manual/style.txt, alongside other parts of The Manual.\n\n */\n/** @page styletexinfo Texinfo Style Guide\n\nThe User's Guide is there to provide two basic kinds of information.  It\nis a guide for how and why to use each feature or mechanism of OpenOCD.\nIt is also the reference manual for all commands and options involved\nin using them, including interface, flash, target, and other drivers.\nAt this time, it is the only documentation for end users; everything\nelse is addressing OpenOCD developers.\n\nThere are two key audiences for the User's Guide, both developer based.\nThe primary audience is developers using OpenOCD as a tool in their\nwork, or who may be starting to use it that way.  A secondary audience\nincludes developers who are supporting those users by packaging or\ncustomizing it for their hardware, installing it as part of some software\ndistribution, or by evolving OpenOCD itself.  There is some crossover\nbetween those audiences.  We encourage contributions from users as the\nfundamental way to evolve and improve OpenOCD.  In particular, creating\na board or target specific configuration file is something that many\nusers will end up doing at some point, and we like to see such files\nbecome part of the mainline release.\n\nGeneral documentation rules to remember include:\n\n- Be concise and clear.  It's work to remove those extra words and\n  sentences, but such \"noise\" doesn't help readers.\n- Make it easy to skim and browse.  \"Tell what you're going to say,\n  then say it\".  Help readers decide whether to dig in now, or\n  leave it for later.\n- Make sure the chapters flow well.  Presentations should not jump\n  around, and should move easily from overview down to details.\n- Avoid using the passive voice.\n- Address the reader to clarify roles (\"your config file\", \"the board you\n  are debugging\", etc.); \"the user\" (etc) is artificial.\n- Use good English grammar and spelling.  Remember also that English\n  will not be the first language for many readers.  Avoid complex or\n  idiomatic usage that could create needless barriers.\n- Use examples to highlight fundamental ideas and common idioms.\n- Don't overuse list constructs.  This is not a slide presentation;\n  prefer paragraphs.\n\nWhen presenting features and mechanisms of OpenOCD:\n\n- Explain key concepts before presenting commands using them.\n- Tie examples to common developer tasks.\n- When giving instructions, you can \\@enumerate each step both\n  to clearly delineate the steps, and to highlight that this is\n  not explanatory text.\n- When you provide \"how to use it\" advice or tutorials, keep it\n  in separate sections from the reference material.\n- Good indexing is something of a black art.  Use \\@cindex for important\n  concepts, but don't overuse it.  In particular, rely on the \\@deffn\n  indexing, and use \\@cindex primarily with significant blocks of text\n  such as \\@subsection.  The \\@dfn of a key term may merit indexing.\n- Use \\@xref (and \\@anchor) with care.  Hardcopy versions, from the PDF,\n  must make sense without clickable links (which don't work all that well\n  with Texinfo in any case).  If you find you're using many links,\n  read that as a symptom that the presentation may be disjointed and\n  confusing.\n- Avoid font tricks like \\@b, but use \\@option, \\@file, \\@dfn, \\@emph\n  and related mechanisms where appropriate.\n\nFor technical reference material:\n\n- It's OK to start sections with explanations and end them with\n  detailed lists of the relevant commands.\n- Use the \\@deffn style declarations to define all commands and drivers.\n  These will automatically appear in the relevant index, and those\n  declarations help promote consistent presentation and style.\n   - It's a \"Command\" if it can be used interactively.\n   - Else it's a \"Config Command\" if it must be used before the\n     configuration stage completes.\n   - For a \"Driver\", list its name.\n   - Use EBNF style regular expressions to define parameters:\n     brackets around zero-or-one choices, parentheses around\n     exactly-one choices.\n   - Use \\@option, \\@file, \\@var and other mechanisms where appropriate.\n   - Say what output it displays, and what value it returns to callers.\n   - Explain clearly what the command does.  Sometimes you will find\n     that it can't be explained clearly.  That usually means the command\n     is poorly designed; replace it with something better, if you can.\n   - Be complete:  document all commands, except as part of a strategy\n     to phase something in or out.\n   - Be correct:  review the documentation against the code, and\n     vice versa.\n- Alphabetize the \\@defn declarations for all commands in each\n  section.\n- Keep the per-command documentation focused on exactly what that\n  command does, not motivation, advice, suggestions, or big examples.\n  When commands deserve such expanded text, it belongs elsewhere.\n  Solutions might be using a \\@section explaining a cluster of related\n  commands, or acting as a mini-tutorial.\n- Details for any given driver should be grouped together.\n\nThe User's Guide is the first place most users will start reading,\nafter they begin using OpenOCD.  Make that investment of their time\nbe as productive as possible.  Needing to look at OpenOCD source code,\nto figure out how to use it is a bad sign, though it's OK to need to\nlook at the User's guide to figure out what a config script is doing.\n\n */\n/** @page stylelatex LaTeX Style Guide\n\nThis page needs to provide style guidelines for using LaTeX, the\ntypesetting language used by The References for OpenOCD Hardware.\nLikewise, the @ref primerlatex for using this guide needs to be completed.\n\n */\n/** @page styleperl Perl Style Guide\n\nThis page provides some style guidelines for using Perl, a scripting\nlanguage used by several small tools in the tree:\n\n-# Ensure all Perl scripts use the proper suffix (@c .pl for scripts, and\n   @c .pm for modules)\n-# Pass files as script parameters or piped as input:\n  - Do NOT code paths to files in the tree, as this breaks out-of-tree builds.\n  - If you must, then you must also use an automake rule to create the script.\n-# use @c '#!/usr/bin/perl' as the first line of Perl scripts.\n-# always <code>use strict</code> and <code>use warnings</code>\n-# invoke scripts indirectly in Makefiles or other scripts:\n@code\nperl script.pl\n@endcode\n\nMaintainers must also be sure to follow additional guidelines:\n-# Ensure that Perl scripts are committed as executables:\n    Use \"<code>chmod +x script.pl</code>\"\n    @a before using \"<code>git add script.pl</code>\"\n\n */\n/** @page styleautotools Autotools Style Guide\n\nThis page contains style guidelines for the OpenOCD autotools scripts.\n\nThe following guidelines apply to the @c configure.ac file:\n- Better guidelines need to be developed, but until then...\n- Use good judgement.\n\nThe following guidelines apply to @c Makefile.am files:\n-# When assigning variables with long lists of items:\n  -# Separate the values on each line to make the files \"patch friendly\":\n@code\nVAR = \\\n\tvalue1 \\\n\tvalue2 \\\n\t...\n\tvalue9 \\\n\tvalue10\n@endcode\n */\n/** @file\n\nThis file contains the @ref styleguide pages.  The @ref styleguide pages\ninclude the following Style Guides for their respective code and\ndocumentation languages:\n\n- @ref styletcl\n- @ref stylec\n- @ref styledoxygen\n- @ref styletexinfo\n- @ref stylelatex\n- @ref styleperl\n- @ref styleautotools\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/target/mips.txt",
    "content": "/** @page targetmips OpenOCD MIPS Targets\n\n@section ejatgmem EJTAG Memory Addresses\n\nAn optional uncached and unmapped debug segment dseg (EJTAG area) appears in the address range\n0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF3F FFFF. The dseg segment thereby appears in the kseg part of the\ncompatibility segment, and access to kseg is possible with the dseg segment.\n\nThe dseg segment is subdivided into dmseg (EJTAG memory) segment and the drseg (EJTAG registers) segment. The\ndmseg segment is used when the probe services the memory segment. The drseg segment is used when the\nmemory-mapped debug registers are accessed. Table 5-2 shows the subdivision and attributes for the segments.\n\ndseg is divided in :\n\n  - dmseg (0xFFFF FFFF FF20 0000 to 0xFFFF FFFF FF2F FFFF)\n  - drseg (0xFFFF FFFF FF30 0000 to 0xFFFF FFFF FF3F FFFF)\n\nBecause the dseg segment is serviced exclusively by the EJTAG features, there\nare no physical address per se. Instead the lower 21 bits of the virtual address select\nthe appropriate reference in either EJTAG memory or registers. References are not mapped through the\nTLB, nor do the accesses appear on the external system memory interface.\n\nBoth of this memory segments are Uncached.\n\nOn debug exception (break) CPU jumps to the beginning of dmseg. This some kind of memory shared\nbetween CPU and EJTAG dongle.\n\nThere CPU stops (correct terminology is : stalls, because it stops it's pipeline), and is waiting for some action of dongle.\n\nIf the dongle gives it instruction, CPU executes it, augments it's PC to 0xFFFF FFFF FF20 0001 - but it again points to dmseg area,\nso it stops waiting for next instruction.\n\nThis will all become clear later, after reading following prerequisite chapters.\n\n@section impflags Important flags\n\n@subsection\tpnnw PNnW\n\nIndicates read or write of a pending processor access:\n\n  - 0 : Read processor access, for a fetch/load access\n  - 1 : Write processor access, for a store access\n\nThis value is defined only when a processor access is pending.\n\nProcessor will do the action for us : it can for example read internal state (register values),\nand send us back the information via EJTAG memory (dmseg), or it can take some data from dmseg and write it into the registers or RAM.\n\nEvery time when it sees address (i.e. when this address is the part of the opcode it is executing, whether it is instruction or data fetch)\nthat falls into dmseg, processor stalls. That actually means that CPU stops it's pipeline and it is waiting for dongle to take some action.\n\nCPU is now either waiting for dongle to take some data from dmseg (if we requested for CPU do give us internal state, for example),\nor it will wait for some data from dongle (if it needs following instruction because it did previous, or if the operand address of the currently executed opcode\nfalls somewhere (anywhere) in dmseg (0xff..ff20000 - 0xff..ff2fffff)).\n\nBit PNnW describes character of CPU access to EJTAG memory (the memory where dongle puts/takes data) - CPU can either READ for it (PNnW == 0) or\nWRITE to it (PNnW == 1).\n\nBy reading PNnW bit OpenOCD will know if it has to send (PNnW == 0) or to take (PNnW == 1) data (from dmseg, via dongle).\n\n@subsection\tpracc PrAcc\n\nIndicates a pending processor access and controls finishing of a pending processor access.\n\nWhen read:\n\n  - 0 : No pending processor access\n  - 1 : Pending processor access\n\nA write of 0 finishes a processor access if pending;\notherwise operation of the processor is UNDEFINED\nif the bit is written to 0 when no processor access is\npending. A write of 1 is ignored.\n\nA successful FASTDATA access will clear this bit.\n\nAs noted above, on any access to dmseg, processor will stall. It waits for dongle to do some action - either to take or put some data.\nOpenOCD can figure out which action has to be taken by reading PrAcc bit.\n\nOnce action from dongle has been done, i.e. after the data is taken/put, OpenOCD can signal to CPU to proceed with executing the instruction.\nThis can be the next instruction (if previous was finished before pending), or the same instruction - if for example CPU was waiting on dongle\nto give it an operand, because it saw in the instruction opcode that operand address is somewhere in dmseg. That provoked the CPU to stall (it tried operand fetch to dmseg and stopped),\nand PNnW bit is 0 (CPU does read from dmseg), and PrAcc is 1 (CPU is pending on dmseg access).\n\n@subsection spracc\tSPrAcc\n\nShifting in a zero value requests completion of the Fastdata access.\n\nThe PrAcc bit in the EJTAG Control register is overwritten with zero when the access\nsucceeds. (The access succeeds if PrAcc is one and the operation address is in the legal dmseg segment\nFastdata area.)\n\nWhen successful, a one is shifted out. Shifting out a zero indicates a Fastdata access failure.\nShifting in a one does not complete the Fastdata access and the PrAcc bit is unchanged. Shifting out a\none indicates that the access would have been successful if allowed to complete and a zero indicates\nthe access would not have successfully completed.\n\n@section fdreg Fastdata Register (TAP Instruction FASTDATA)\n\nThe width of the Fastdata register is 1 bit.\n\nDuring a Fastdata access, the Fastdata register is written and read, i.e., a bit is\nshifted in and a bit is shifted out.\n\nAlso during a Fastdata access, the Fastdata register value shifted in specifies whether the Fastdata\naccess should be completed or not. The value shifted out is a flag that indicates whether the Fastdata access was\nsuccessful or not (if completion was requested).\n\n@section ejtagacc EJTAG Access Implementation\n\nOpenOCD reads/writes data to JTAG via mips_m4k_read_memory() and mips_m4k_write_memory() functions defined in src/target/mips_m4k.c.\nInternally, these functions call mips32_pracc_read_mem() and mips32_pracc_write_mem() defined in src/target/mips32_pracc.c\n\nLet's take for example function mips32_pracc_read_mem32() which describes CPU reads (fetches) from dmseg (EJTAG memory) :\n\n@code\nstatic const uint32_t code[] = {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t/* start: */\n\tMIPS32_MTC0(15,31,0),\t\t\t\t\t\t\t\t/* move $15 to COP0 DeSave */\n\tMIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)),\t\t\t/* $15 = MIPS32_PRACC_STACK */\n\tMIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)),\n\tMIPS32_SW(8,0,15),\t\t\t\t\t\t\t\t\t/* sw $8,($15) */\n\tMIPS32_SW(9,0,15),\t\t\t\t\t\t\t\t\t/* sw $9,($15) */\n\tMIPS32_SW(10,0,15),\t\t\t\t\t\t\t\t\t/* sw $10,($15) */\n\tMIPS32_SW(11,0,15),\t\t\t\t\t\t\t\t\t/* sw $11,($15) */\n\n\tMIPS32_LUI(8,UPPER16(MIPS32_PRACC_PARAM_IN)),\t\t/* $8 = MIPS32_PRACC_PARAM_IN */\n\tMIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_PARAM_IN)),\n\tMIPS32_LW(9,0,8),\t\t\t\t\t\t\t\t\t/* $9 = mem[$8]; read addr */\n\tMIPS32_LW(10,4,8),\t\t\t\t\t\t\t\t\t/* $10 = mem[$8 + 4]; read count */\n\tMIPS32_LUI(11,UPPER16(MIPS32_PRACC_PARAM_OUT)),\t\t/* $11 = MIPS32_PRACC_PARAM_OUT */\n\tMIPS32_ORI(11,11,LOWER16(MIPS32_PRACC_PARAM_OUT)),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t/* loop: */\n\tMIPS32_BEQ(0,10,8),\t\t\t\t\t\t\t\t\t/* beq 0, $10, end */\n\tMIPS32_NOP,\n\n\tMIPS32_LW(8,0,9),\t\t\t\t\t\t\t\t\t/* lw $8,0($9), Load $8 with the word @mem[$9] */\n\tMIPS32_SW(8,0,11),\t\t\t\t\t\t\t\t\t/* sw $8,0($11) */\n\n\tMIPS32_ADDI(10,10,NEG16(1)),\t\t\t\t\t\t/* $10-- */\n\tMIPS32_ADDI(9,9,4),\t\t\t\t\t\t\t\t\t/* $1 += 4 */\n\tMIPS32_ADDI(11,11,4),\t\t\t\t\t\t\t\t/* $11 += 4 */\n\n\tMIPS32_B(NEG16(8)),\t\t\t\t\t\t\t\t\t/* b loop */\n\tMIPS32_NOP,\n                                          \t\t\t\t/* end: */\n\tMIPS32_LW(11,0,15),\t\t\t\t\t\t\t\t\t/* lw $11,($15) */\n\tMIPS32_LW(10,0,15),\t\t\t\t\t\t\t\t\t/* lw $10,($15) */\n\tMIPS32_LW(9,0,15),\t\t\t\t\t\t\t\t\t/* lw $9,($15) */\n\tMIPS32_LW(8,0,15),\t\t\t\t\t\t\t\t\t/* lw $8,($15) */\n\tMIPS32_B(NEG16(27)),\t\t\t\t\t\t\t\t/* b start */\n\tMIPS32_MFC0(15,31,0),\t\t\t\t\t\t\t\t/* move COP0 DeSave to $15 */\n};\n@endcode\n\nWe have to pass this code to CPU via dongle via dmseg.\n\nAfter debug exception CPU will find itself stalling at the beginning of the dmseg. It waits for the first instruction from dongle.\nThis is MIPS32_MTC0(15,31,0), so CPU saves C0 and continues to addr 0xFF20 0001, which falls also to dmseg, so it stalls.\nDongle proceeds giving to CPU one by one instruction in this manner.\n\nHowever, things are not so simple. If you take a look at the program, you will see that some instructions take operands. If it has to take\noperand from the address in dmseg, CPU will stall waiting for the dongle to do the action of passing the operand and signal this by putting PrAcc to 0.\nIf this operand is somewhere in RAM, CPU will not stall (it stalls only on dmseg), but it will just take it and proceed to next instruction. But since PC for next instruction\npoints to dmseg, it will stall, so that dongle can pass next instruction.\n\nSome instructions are jumps (if these are jumps in dmseg addr, CPU will jump and then stall. If this is jump to some address in RAM, CPU will jump and just proceed -\nwill not stall on addresses in RAM).\n\nTo have information about CPU is currently (does it stalls wanting on operand or it jumped somewhere waiting for next instruction),\nOpenOCD has to call TAP ADDRESS instruction, which will ask CPU to give us his address within EJTAG memory :\n\n@code\naddress = data = 0;\nmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\nmips_ejtag_drscan_32(ejtag_info, &address);\n@endcode\n\nAnd then, upon the results, we can conclude where it is in our code so far, so we can give it what it wants next :\n\n@code\nif ((address >= MIPS32_PRACC_PARAM_IN)\n\t&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))\n{\n\toffset = (address - MIPS32_PRACC_PARAM_IN) / 4;\n\tdata = ctx->local_iparam[offset];\n}\nelse if ((address >= MIPS32_PRACC_PARAM_OUT)\n\t&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))\n{\n\toffset = (address - MIPS32_PRACC_PARAM_OUT) / 4;\n\tdata = ctx->local_oparam[offset];\n}\nelse if ((address >= MIPS32_PRACC_TEXT)\n\t&& (address <= MIPS32_PRACC_TEXT + ctx->code_len * 4))\n{\n\toffset = (address - MIPS32_PRACC_TEXT) / 4;\n\tdata = ctx->code[offset];\n}\nelse if (address == MIPS32_PRACC_STACK)\n{\n\t/* save to our debug stack */\n\tdata = ctx->stack[--ctx->stack_offset];\n}\nelse\n{\n\t/* TODO: send JMP 0xFF200000 instruction.\n\t\tHopefully processor jump back to start of debug vector */\n\tdata = 0;\n\tLOG_ERROR(\"Error reading unexpected address 0x%8.8\" PRIx32 \"\", address);\n\treturn ERROR_JTAG_DEVICE_ERROR;\n}\n@endcode\n\ni.e. if CPU is stalling on addresses in dmseg that are reserved for input parameters, we can conclude that it actually tried to take (read)\nparameter from there, and saw that address of parameter falls in dmseg, so it stopped. Obviously, now dongle have to give to it operand.\n\nSimilarly, mips32_pracc_exec_write() describes CPU writes into EJTAG memory (dmseg).\nObviously, code is RO, and CPU can change only parameters :\n\n@code\nmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);\nmips_ejtag_drscan_32(ctx->ejtag_info, &data);\n\n/* Clear access pending bit */\nejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;\nmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);\nmips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);\n\n//jtag_add_clocks(5);\njtag_execute_queue();\n\nif ((address >= MIPS32_PRACC_PARAM_IN)\n\t&& (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))\n{\n\toffset = (address - MIPS32_PRACC_PARAM_IN) / 4;\n\tctx->local_iparam[offset] = data;\n}\nelse if ((address >= MIPS32_PRACC_PARAM_OUT)\n\t&& (address <= MIPS32_PRACC_PARAM_OUT + ctx->num_oparam * 4))\n{\n\toffset = (address - MIPS32_PRACC_PARAM_OUT) / 4;\n\tctx->local_oparam[offset] = data;\n}\nelse if (address == MIPS32_PRACC_STACK)\n{\n\t/* save data onto our stack */\n\tctx->stack[ctx->stack_offset++] = data;\n}\nelse\n{\n\tLOG_ERROR(\"Error writing unexpected address 0x%8.8\" PRIx32 \"\", address);\n\treturn ERROR_JTAG_DEVICE_ERROR;\n}\n@endcode\n\nCPU loops here :\n\n@code\nwhile (1)\n{\n\tif ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)\n\t\treturn retval;\n\n\taddress = data = 0;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &address);\n\n\t/* Check for read or write */\n\tif (ejtag_ctrl & EJTAG_CTRL_PRNW)\n\t{\n\t\tif ((retval = mips32_pracc_exec_write(&ctx, address)) != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\telse\n\t{\n\t\t/* Check to see if its reading at the debug vector. The first pass through\n\t\t * the module is always read at the vector, so the first one we allow.  When\n\t\t * the second read from the vector occurs we are done and just exit. */\n\t\tif ((address == MIPS32_PRACC_TEXT) && (pass++))\n\t\t{\n\t\t\tbreak;\n\t\t}\n\n\t\tif ((retval = mips32_pracc_exec_read(&ctx, address)) != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cycle == 0)\n\t\tbreak;\n}\n@endcode\n\nand using presented R (mips32_pracc_exec_read()) and W (mips32_pracc_exec_write()) functions it reads in the code (RO) and reads and writes operands (RW).\n\n@section fdimpl OpenOCD FASTDATA Implementation\n\nOpenOCD FASTDATA write function, mips32_pracc_fastdata_xfer() is called from bulk_write_memory callback, which writes a count items of 4 bytes\nto the memory of a target at the an address given.  Because it operates only on whole words, this should be faster than target_write_memory().\n\nIn order to implement FASTDATA write, mips32_pracc_fastdata_xfer() uses the following handler :\n\n@code\nuint32_t handler_code[] = {\n\t/* caution when editing, table is modified below */\n\t/* r15 points to the start of this code */\n\tMIPS32_SW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),\n\tMIPS32_SW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),\n\tMIPS32_SW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),\n\tMIPS32_SW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),\n\t/* start of fastdata area in t0 */\n\tMIPS32_LUI(8,UPPER16(MIPS32_PRACC_FASTDATA_AREA)),\n\tMIPS32_ORI(8,8,LOWER16(MIPS32_PRACC_FASTDATA_AREA)),\n\tMIPS32_LW(9,0,8),\t\t\t\t\t\t\t\t/* start addr in t1 */\n\tMIPS32_LW(10,0,8),\t\t\t\t\t\t\t\t/* end addr to t2 */\n\t\t\t\t\t\t\t\t\t\t\t\t\t/* loop: */\n\t/* 8 */ MIPS32_LW(11,0,0),\t\t\t\t\t\t/* lw t3,[t8 | r9] */\n\t/* 9 */ MIPS32_SW(11,0,0),\t\t\t\t\t\t/* sw t3,[r9 | r8] */\n\tMIPS32_BNE(10,9,NEG16(3)),\t\t\t\t\t\t/* bne $t2,t1,loop */\n\tMIPS32_ADDI(9,9,4),\t\t\t\t\t\t\t\t/* addi t1,t1,4 */\n\n\tMIPS32_LW(8,MIPS32_FASTDATA_HANDLER_SIZE - 4,15),\n\tMIPS32_LW(9,MIPS32_FASTDATA_HANDLER_SIZE - 8,15),\n\tMIPS32_LW(10,MIPS32_FASTDATA_HANDLER_SIZE - 12,15),\n\tMIPS32_LW(11,MIPS32_FASTDATA_HANDLER_SIZE - 16,15),\n\n\tMIPS32_LUI(15,UPPER16(MIPS32_PRACC_TEXT)),\n\tMIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_TEXT)),\n\tMIPS32_JR(15),\t\t\t\t\t\t\t\t\t/* jr start */\n\tMIPS32_MFC0(15,31,0),\t\t\t\t\t\t\t/* move COP0 DeSave to $15 */\n};\n@endcode\n\nIn the beginning and the end of the handler we have function prologue (save the regs that will be clobbered) and epilogue (restore regs),\nand in the very end, after all the xfer have been done, we do jump to the MIPS32_PRACC_TEXT address, i.e. Debug Exception Vector location.\nWe will use this fact (that we came back to MIPS32_PRACC_TEXT)  to verify later if all the handler is executed (because when in RAM,\nprocessor do not stall - it executes all instructions until one of them do not demand access to dmseg (if one of it's operands is there)).\n\nThis handler is put into the RAM and executed from there, and not instruction by  instruction, like in previous simple write\n(mips_m4k_write_memory()) and read (mips_m4k_read_memory()) functions.\n\nN.B. When it is executing this code in RAM, CPU will not stall on instructions, but execute all until it comes to the :\n\n@code\nMIPS32_LW(9,0,8) /* start addr in t1 */\n@endcode\n\nand there it will stall - because it will see that one of the operands have to be fetched from dmseg (EJTAG memory, in this case FASTDATA memory segment).\n\nThis handler is loaded in the RAM, at the reserved location \"work_area\". This work_area is configured in OpenOCD configuration script and should be selected\nin that way that it is not clobbered (overwritten) by data we want to write-in using FASTDATA.\n\nWhat is executed instruction by instruction which is passed by dongle (via EJATG memory) is small jump code, which jumps at the handler in RAM.\nCPU stalls on dmseg when receiving these jmp_code instructions, but once it jumps in RAM, CPU do not stall anymore and executes bunch of handler instructions.\nUntil it comes to the first instruction which has an operand in FASTDATA area. There it stalls and waits on action from probe.\nIt happens actually when CPU comes to this loop :\n\n@code\nMIPS32_LW(9,0,8),\t\t\t\t\t\t\t\t/* start addr in t1 */\nMIPS32_LW(10,0,8),\t\t\t\t\t\t\t\t/* end addr to t2 */\n\t\t\t\t\t\t\t\t\t\t\t\t/* loop: */\n/* 8 */ MIPS32_LW(11,0,0),\t\t\t\t\t\t/* lw t3,[t8 | r9] */\n/* 9 */ MIPS32_SW(11,0,0),\t\t\t\t\t\t/* sw t3,[r9 | r8] */\nMIPS32_BNE(10,9,NEG16(3)),\t\t\t\t\t\t/* bne $t2,t1,loop */\n@endcode\n\nand then it stalls because operand in r8 points to FASTDATA area.\n\nOpenOCD first verifies that CPU came to this place by :\n\n@code\n/* next fetch to dmseg should be in FASTDATA_AREA, check */\naddress = 0;\nmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\nmips_ejtag_drscan_32(ejtag_info, &address);\n\nif (address != MIPS32_PRACC_FASTDATA_AREA)\n\treturn ERROR_FAIL;\n@endcode\n\nand then passes to CPU start and end address of the loop region for handler in RAM.\n\nIn the loop in handler, CPU sees that it has to take and operand from FSTDATA area (to write it to the dst in RAM after), and so it stalls, putting PrAcc to \"1\".\nOpenOCD fills the data via this loop :\n\n@code\nfor (i = 0; i < count; i++)\n{\n\t/* Send the data out using fastdata (clears the access pending bit) */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);\n\tif ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK)\n\t\treturn retval;\n}\n@endcode\n\nEach time when OpenOCD fills data to CPU (via dongle, via dmseg), CPU takes it and proceeds to execute the handler. However, since the handler is in an assembly loop,\nCPU comes to next instruction which also fetches data from FASTDATA area. So it stalls.\nThen OpenOCD fills the data again, from its (OpenOCD's) loop. And this game continues until all the data has been filled.\n\nAfter the last data has been given to CPU it sees that it reached the end address, so it proceeds with next instruction. However, this instruction do not point into dmseg, so\nCPU executes bunch of handler instructions (all prologue) and in the end jumps to MIPS32_PRACC_TEXT address.\n\nOn its side, OpenOCD checks in CPU has jumped back to MIPS32_PRACC_TEXT, which is the confirmation that it correctly executed all the rest of the handler in RAM,\nand that is not stuck somewhere in the RAM, or stalling on some access in dmesg - that would be an error:\n\n@code\naddress = 0;\nmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\nmips_ejtag_drscan_32(ejtag_info, &address);\n\nif (address != MIPS32_PRACC_TEXT)\n\tLOG_ERROR(\"mini program did not return to start\");\n@endcode\n\n@section fdejtagspec EJTAG spec on FASTDATA access\n\nThe width of the Fastdata register is 1 bit. During a Fastdata access, the Fastdata register is written and read, i.e., a bit\nis shifted in and a bit is shifted out. During a Fastdata access, the Fastdata register value shifted in specifies whether\nthe Fastdata access should be completed or not. The value shifted out is a flag that indicates whether the Fastdata\naccess was successful or not (if completion was requested).\n\nThe FASTDATA access is used for efficient block transfers between dmseg (on the probe) and target memory (on the\nprocessor). An \"upload\" is defined as a sequence of processor loads from target memory and stores to dmseg. A\n\"download\" is a sequence of processor loads from dmseg and stores to target memory. The \"Fastdata area\" specifies\nthe legal range of dmseg addresses (0xFF20.0000 - 0xFF20.000F) that can be used for uploads and downloads. The\nData + Fastdata registers (selected with the FASTDATA instruction) allow efficient completion of pending Fastdata\narea accesses.\nDuring Fastdata uploads and downloads, the processor will stall on accesses to the Fastdata area. The PrAcc (processor\naccess pending bit) will be 1 indicating the probe is required to complete the access. Both upload and download\naccesses are attempted by shifting in a zero SPrAcc value (to request access completion) and shifting out SPrAcc to\nsee if the attempt will be successful (i.e., there was an access pending and a legal Fastdata area address was used).\nDownloads will also shift in the data to be used to satisfy the load from dmseg’s Fastdata area, while uploads will\nshift out the data being stored to dmseg’s Fastdata area.\nAs noted above, two conditions must be true for the Fastdata access to succeed. These are:\n\n - PrAcc must be 1, i.e., there must be a pending processor access.\n - The Fastdata operation must use a valid Fastdata area address in dmseg (0xFF20.0000 to 0xFF20.000F).\n\nBasically, because FASTDATA area in dmseg is 16 bytes, we transfer (0xFF20.0000 - 0xFF20.000F)\nFASTDATA scan TAP instruction selects the Data and the Fastdata registers at once.\n\nThey come in order :\nTDI -> | Data register| -> | Fastdata register | -> TDO\n\nFASTDATA register is 1-bit width register. It takes in SPrAcc bit which should be shifted first,\nfollowed by 32 bit of data.\n\nScan width of FASTDTA is 33 bits in total : 33 bits are shifted in and 33 bits are shifted out.\n\nFirst bit that is shifted out is SPrAcc that comes out of Fastdata register and should give us status on FATSDATA write we want to do.\n\n@section fdcheck OpenOCD misses FASTDATA check\n\nDownload flow (probe -> target block transfer) :\n\n1) Probe transfer target execution to a loop in target memory doing a fixed number of \"loads\" to fastdata area of dmseg (and stores to the target download destination.)\n\n2) Probe loops attempting to satisfy the loads \"expected\" from the target.\n   On FASTDATA access \"successful\" move on to next \"load\".\n   On FASTDATA access \"failure\" repeat until \"successful\" or timeout.\n   (A \"failure\" is an attempt to satisfy an access when none are pending.)\n\nNote: A failure may have a recoverable (and even expected) cause like slow target execution of the load loop. Other failures may be due to unexpected more troublesome causes like an exception while in debug mode or a target hang on a bad target memory access.\n\nShifted out SPrAcc bit inform us that there was CPU access pending and that it can be complete.\n\nBasically, we should do following procedure :\n\n - Download (dongle -> CPU) :\nYou shift \"download\" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is \"1\" then an access was pending when you started the scan and it is now complete.\n\nIf SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is \"long overdue\" as something unexpected has happened.)\n\n - Upload (CPU -> dongle) :\nYou shift \"dummy\" DATA and FASTDATA[SPrAcc] = 0 (33 bit scan) into the target. If the value of FASTDATA[SPrAcc] shifted out is \"1\" then an access was pending when you started the scan and it is now complete. The \"upload\" is the DATA shifted out of the target.\n\nIf SPrAcc is 0 then no access was pending to the fastdata area. (Repeat attempt to complete the access you expect for this data word. Timeout if you think the access is \"long overdue\" as something unexpected has happened.)\n\nBasically, if checking first (before scan) if CPU is pending on FASTDATA access (PrAcc is \"1\"), like this\n\n@code\nwait(ready);\ndo_scan();\n@endcode\n\nwhich is inefficient, we should do it like this :\n\n@code\nBEGIN :\n\tdo_scan();\n\tif (!was_ready)\n\tgoto BEGIN;\n@endcode\n\nby checking SPrAcc that we shifted out.\n\nIf some FASTDATA write fails, OpenOCD will continue with it's loop (on the host side), but CPU will rest pending (on the target side)\nwaiting for correct FASTDATA write.\n\nSince OpenOCD goes ahead, it will eventually finish it's loop, and proceed to check if CPU took all the data. But since CPU did not took all the data,\nit is still turns in handler's loop in RAM, stalling on Fastdata area so this check :\n\n@code\naddress = 0;\nmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\nretval = mips_ejtag_drscan_32(ejtag_info, &address);\nif (retval != ERROR_OK)\n\treturn retval;\n\nif (address != MIPS32_PRACC_TEXT)\n\tLOG_ERROR(\"mini program did not return to start\");\n@endcode\n\nfails, and that gives us enough information of the failure.\n\nIn this case, we can lower the JTAG frequency and try again, because most probable reason of this failure is that we tried FASTDATA upload before CPU arrived to rise PrAcc (i.e. before it was pending on access).\nHowever, the reasons for failure might be numerous : reset, exceptions which can occur in debug mode, bus hangs, etc.\n\nIf lowering the JTAG freq does not work either, we can fall back to more robust solution with patch posted below.\n\nTo summarize, FASTDATA communication goes as following :\n\n-# CPU jumps to Debug Exception Vector Location 0xFF200200 in dmseg and it stalls, pending and waiting for EJTAG to give it first debug instruction and signal it by putting PrAcc to \"0\"\n-# When PrAcc goes to \"0\" CPU execute one opcode sent by EJTAG via DATA reg. Then it pends on next access, waiting for PrAcc to be put to \"0\" again\n-# Following this game, OpenOCD first loads handler code in RAM, and then sends the jmp_code - instruction by instruction via DATA reg, which redirects CPU to handler previously set up in RAM\n-# Once in RAM CPU does not pend on any instruction, but it executes all handler instructions until first \"fetch\" to Fastdata area - then it stops and pends.\n-# So - when it comes to any instruction (opcode) in this handler in RAM which reads (or writes) to Fastdata area (0xF..F20.0000 to 0xF..F20.000F), CPU stops (i.e. stalls access).\n   I.e. it stops on this lw opcode and waits to FASTDATA TAP command from the probe.\n-# CPU continues only if OpenOCD shifted in SPrAcc \"0\" (and if the PrAcc was \"1\"). It shifts-out \"1\" to tell us that it was OK (processor was stalled, so it can complete the access),\n   and that it continued execution of the handler in RAM.\n-# If PrAcc was not \"1\" CPU will not continue (go to next instruction), but will shift-out \"0\" and keep stalling on the same instruction of my handler in RAM.\n-# When Fastdata loop is finished, CPU executes all following handler instructions in RAM (prologue).\n-# In the end of my handler in RAM, I jumps back to beginning of Debug Exception Vector Location 0xFF200200 in dmseg.\n-# When it jumps back to 0xFF200200 in dmseg processor stops and pends, waiting for OpenOCD to send it instruction via DATA reg and signal it by putting PrAcc to \"0\".\n\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/target/notarm.txt",
    "content": "/** @page targetnotarm OpenOCD Non-ARM Targets\n\nThis page describes outstanding issues w.r.t. non-ARM targets.\n\n@section targetnotarmflash Flash drivers\n\nThe flash drivers contain ARM32 code that is used\nto execute code on the target.\n\nThis needs to be handled in some CPU independent\nmanner.\n\nThe ocl and ecos flash drivers compile the flash\ndriver code to run on the target on the developer\nmachine.\n\nThe ocl and ecos flash drivers should be unified\nand instructions should be written on how to\ncompile the target flash drivers. Perhaps\nusing automake?\n\n\neCos has CFI driver that could probably be compiled\nfor all targets. The trick is to figure out a\nway to make the compiled flash drivers work\non all target memory maps + sort out all the\nlittle details\n\n@section targetnotarm32v64 32 vs. 64 bit\n\nCurrently OpenOCD only supports 32 bit targets.\n\nAdding 64 bit support would be nice but there\nhasn't been any call for it in the openocd development\nmailing list\n\n@section targetnotarmsupport Target Support\n\ntarget.h is relatively CPU agnostic and\nthe intention is to move in the direction of less\ninstruction set specific.\n\nNon-CPU targets are also supported, but there isn't\na lot of activity on it in the mailing list currently.\nAn example is FPGA programming support via JTAG,\nbut also flash chips can be programmed directly\nusing JTAG.\n\n@section targetnotarmphy non-JTAG physical layer\n\nJTAG is not the only physical protocol used to talk to\nCPUs.\n\nOpenOCD does not today have targets that use non-JTAG.\n\nThe actual physical layer is a relatively modest part\nof the total OpenOCD system.\n\n\n@section targetnotarmppc PowerPC\n\nthere exists open source implementations of PowerPC\ntarget manipulation, but there hasn't been a lot\nof activity in the mailing list.\n\n@section targetnotarmmips MIPS\n\nCurrently OpenOCD has a MIPS target defined. This is the\nfirst non-ARM example of a CPU target\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/manual/target.txt",
    "content": "/** @page targetdocs OpenOCD Target APIs\n\nOpenOCD provides its Target APIs to allow developers to provide trace and\ndebugging support for specific device targets.  These primarily consist of\nARM cores, but other types have been supported.  New targets should be\ndeveloped by following or using these APIs.\n\nThe Target Support module contains APIs that cover several functional areas:\n\n  - @subpage targetarm\n  - @subpage targetnotarm\n  - @subpage targetmips\n  - @subpage targetregister\n  - @subpage targetimage\n  - @subpage targettrace\n\nThis section needs to be expanded.\n\n*/\n\n/** @page targetarm OpenOCD ARM Targets\n\nThis section needs to describe OpenOCD's ARM target support.\n\n */\n\n/** @page targetregister OpenOCD Target Register API\n\nThis section needs to describe OpenOCD's Target Register API, as\nprovided by 'src/target/register.h'.\n\n */\n\n/** @page targetimage OpenOCD Target Image API\n\nThis section needs to describe OpenOCD's Target Image API, as provided\nby 'src/target/image.h'.\n\n */\n\n/** @page targettrace OpenOCD Target Trace API\n\nThis section needs to describe OpenOCD's Target Trace API, as provided\nby 'src/target/trace.h'.\n\n */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/openocd.1",
    "content": ".TH \"OPENOCD\" \"1\" \"November 24, 2009\"\n.SH \"NAME\"\nopenocd \\- A free and open on\\-chip debugging, in\\-system programming and\nboundary\\-scan testing tool for ARM and MIPS systems\n.SH \"SYNOPSIS\"\n.B openocd \\fR[\\fB\\-fsdlcphv\\fR] [\\fB\\-\\-file\\fR <filename>] [\\fB\\-\\-search\\fR <dirname>] [\\fB\\-\\-debug\\fR <debuglevel>] [\\fB\\-\\-log_output\\fR <filename>] [\\fB\\-\\-command\\fR <cmd>] [\\fB\\-\\-pipe\\fR] [\\fB\\-\\-help\\fR] [\\fB\\-\\-version\\fR]\n.SH \"DESCRIPTION\"\n.B OpenOCD\nis an on\\-chip debugging, in\\-system programming and boundary\\-scan\ntesting tool for various ARM and MIPS systems.\n.PP\nThe debugger uses an IEEE 1149\\-1 compliant JTAG TAP bus master to access\non\\-chip debug functionality available on ARM based microcontrollers or\nsystem-on-chip solutions. For MIPS systems the EJTAG interface is supported.\n.PP\nUser interaction is realized through a telnet command line interface,\na gdb (the GNU debugger) remote protocol server, and a simplified RPC\nconnection that can be used to interface with OpenOCD's Jim Tcl engine.\n.PP\nOpenOCD supports various different types of JTAG interfaces/programmers,\nplease check the \\fIopenocd\\fR info page for the complete list.\n.SH \"OPTIONS\"\n.TP\n.B \"\\-f, \\-\\-file <filename>\"\nThis is a shortcut for a \\fB\\-c \"[script \\fI<filename>\\fB]\"\\fR\ncommand, using a search path to load the configuration file\n.IR <filename> .\nIn order to specify multiple config files, you can use multiple\n.B \\-\\-file\narguments. If no such \\fB\\-c\\fR\noptions are included, the first config file\n.B openocd.cfg\nin the search path will be used.\n.TP\n.B \"\\-s, \\-\\-search <dirname>\"\nAdd\n.I <dirname>\nto the search path used for config files and scripts.\nThe search path begins with the current directory,\nthen includes these additional directories before other\ncomponents such as the standard OpenOCD script libraries.\n.TP\n.B \"\\-d, \\-\\-debug <debuglevel>\"\nSet debug level. Possible values are:\n.br\n.RB \"  * \" 0 \" (errors)\"\n.br\n.RB \"  * \" 1 \" (warnings)\"\n.br\n.RB \"  * \" 2 \" (informational messages)\"\n.br\n.RB \"  * \" 3 \" (debug messages)\"\n.br\nThe default level is\n.BR 2 .\n.TP\n.B \"\\-l, \\-\\-log_output <filename>\"\nRedirect log output to the file\n.IR <filename> .\nPer default the log output is printed on\n.BR stderr .\n.TP\n.B \"\\-c, \\-\\-command <cmd>\"\nAdd the command\n.I <cmd>\nto a list of commands executed on server startup.\nNote that you will need to explicitly invoke\n.I init\nif the command requires access to a target or flash.\n.TP\n.B \"\\-p, \\-\\-pipe\"\nUse pipes when talking to gdb.\n.TP\n.B \"\\-h, \\-\\-help\"\nShow a help text and exit.\n.TP\n.B \"\\-v, \\-\\-version\"\nShow version information and exit.\n.SH \"BUGS\"\nPlease report any bugs on the mailing list at\n.BR openocd\\-devel@lists.sourceforge.net .\n.SH \"LICENCE\"\n.B OpenOCD\nis covered by the GNU General Public License (GPL), version 2 or later.\n.SH \"SEE ALSO\"\n.BR jtag (1)\n.PP\nThe full documentation for\n.B openocd\nis maintained as a Texinfo manual. If the\n.BR info\n(or\n.BR pinfo )\nand\n.BR openocd\nprograms are properly installed at your site, the command\n.B info openocd\nshould give you access to the complete manual.\n.SH \"AUTHORS\"\nPlease see the file AUTHORS.\n.PP\nThis manual page was written by Uwe Hermann <uwe@hermann\\-uwe.de>.\nIt is licensed under the terms of the GNU GPL (version 2 or later).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/openocd.texi",
    "content": "\\input texinfo @c -*-texinfo-*-\n@c %**start of header\n@setfilename openocd.info\n@settitle OpenOCD User's Guide\n@dircategory Development\n@direntry\n* OpenOCD: (openocd).      OpenOCD User's Guide\n@end direntry\n@paragraphindent 0\n@c %**end of header\n\n@include version.texi\n\n@copying\n\nThis User's Guide documents\nrelease @value{VERSION},\ndated @value{UPDATED},\nof the Open On-Chip Debugger (OpenOCD).\n\n@itemize @bullet\n@item Copyright @copyright{} 2008-2022 The OpenOCD Project\n@item Copyright @copyright{} 2007-2008 Spencer Oliver @email{spen@@spen-soft.co.uk}\n@item Copyright @copyright{} 2008-2010 Oyvind Harboe @email{oyvind.harboe@@zylin.com}\n@item Copyright @copyright{} 2008 Duane Ellis @email{openocd@@duaneellis.com}\n@item Copyright @copyright{} 2009-2010 David Brownell\n@end itemize\n\n@quotation\nPermission is granted to copy, distribute and/or modify this document\nunder the terms of the GNU Free Documentation License, Version 1.2 or\nany later version published by the Free Software Foundation; with no\nInvariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A\ncopy of the license is included in the section entitled ``GNU Free\nDocumentation License''.\n@end quotation\n@end copying\n\n@titlepage\n@titlefont{@emph{Open On-Chip Debugger:}}\n@sp 1\n@title OpenOCD User's Guide\n@subtitle for release @value{VERSION}\n@subtitle @value{UPDATED}\n\n@page\n@vskip 0pt plus 1filll\n@insertcopying\n@end titlepage\n\n@summarycontents\n@contents\n\n@ifnottex\n@node Top\n@top OpenOCD User's Guide\n\n@insertcopying\n@end ifnottex\n\n@menu\n* About::                            About OpenOCD\n* Developers::                       OpenOCD Developer Resources\n* Debug Adapter Hardware::           Debug Adapter Hardware\n* About Jim-Tcl::                    About Jim-Tcl\n* Running::                          Running OpenOCD\n* OpenOCD Project Setup::            OpenOCD Project Setup\n* Config File Guidelines::           Config File Guidelines\n* Server Configuration::             Server Configuration\n* Debug Adapter Configuration::      Debug Adapter Configuration\n* Reset Configuration::              Reset Configuration\n* TAP Declaration::                  TAP Declaration\n* CPU Configuration::                CPU Configuration\n* Flash Commands::                   Flash Commands\n* Flash Programming::                Flash Programming\n* PLD/FPGA Commands::                PLD/FPGA Commands\n* General Commands::                 General Commands\n* Architecture and Core Commands::   Architecture and Core Commands\n* JTAG Commands::                    JTAG Commands\n* Boundary Scan Commands::           Boundary Scan Commands\n* Utility Commands::                 Utility Commands\n* GDB and OpenOCD::                  Using GDB and OpenOCD\n* Tcl Scripting API::                Tcl Scripting API\n* FAQ::                              Frequently Asked Questions\n* Tcl Crash Course::                 Tcl Crash Course\n* License::                          GNU Free Documentation License\n\n@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename\n@comment case issue with ``Index.html'' and ``index.html''\n@comment Occurs when creating ``--html --no-split'' output\n@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html\n* OpenOCD Concept Index::            Concept Index\n* Command and Driver Index::         Command and Driver Index\n@end menu\n\n@node About\n@unnumbered About\n@cindex about\n\nOpenOCD was created by Dominic Rath as part of a 2005 diploma thesis written\nat the University of Applied Sciences Augsburg (@uref{http://www.hs-augsburg.de}).\nSince that time, the project has grown into an active open-source project,\nsupported by a diverse community of software and hardware developers from\naround the world.\n\n@section What is OpenOCD?\n@cindex TAP\n@cindex JTAG\n\nThe Open On-Chip Debugger (OpenOCD) aims to provide debugging,\nin-system programming and boundary-scan testing for embedded target\ndevices.\n\nIt does so with the assistance of a @dfn{debug adapter}, which is\na small hardware module which helps provide the right kind of\nelectrical signaling to the target being debugged. These are\nrequired since the debug host (on which OpenOCD runs) won't\nusually have native support for such signaling, or the connector\nneeded to hook up to the target.\n\nSuch debug adapters support one or more @dfn{transport} protocols,\neach of which involves different electrical signaling (and uses\ndifferent messaging protocols on top of that signaling). There\nare many types of debug adapter, and little uniformity in what\nthey are called. (There are also product naming differences.)\n\nThese adapters are sometimes packaged as discrete dongles, which\nmay generically be called @dfn{hardware interface dongles}.\nSome development boards also integrate them directly, which may\nlet the development board connect directly to the debug\nhost over USB (and sometimes also to power it over USB).\n\nFor example, a @dfn{JTAG Adapter} supports JTAG\nsignaling, and is used to communicate\nwith JTAG (IEEE 1149.1) compliant TAPs on your target board.\nA @dfn{TAP} is a ``Test Access Port'', a module which processes\nspecial instructions and data. TAPs are daisy-chained within and\nbetween chips and boards. JTAG supports debugging and boundary\nscan operations.\n\nThere are also @dfn{SWD Adapters} that support Serial Wire Debug (SWD)\nsignaling to communicate with some newer ARM cores, as well as debug\nadapters which support both JTAG and SWD transports. SWD supports only\ndebugging, whereas JTAG also supports boundary scan operations.\n\nFor some chips, there are also @dfn{Programming Adapters} supporting\nspecial transports used only to write code to flash memory, without\nsupport for on-chip debugging or boundary scan.\n(At this writing, OpenOCD does not support such non-debug adapters.)\n\n\n@b{Dongles:} OpenOCD currently supports many types of hardware dongles:\nUSB-based, parallel port-based, and other standalone boxes that run\nOpenOCD internally. @xref{Debug Adapter Hardware}.\n\n@b{GDB Debug:} It allows ARM7 (ARM7TDMI and ARM720t), ARM9 (ARM920T,\nARM922T, ARM926EJ--S, ARM966E--S), XScale (PXA25x, IXP42x), Cortex-M3\n(Stellaris LM3, STMicroelectronics STM32 and Energy Micro EFM32) and\nIntel Quark (x10xx) based cores to be debugged via the GDB protocol.\n\n@b{Flash Programming:} Flash writing is supported for external\nCFI-compatible NOR flashes (Intel and AMD/Spansion command set) and several\ninternal flashes (LPC1700, LPC1800, LPC2000, LPC4300, AT91SAM7, AT91SAM3U,\nSTR7x, STR9x, LM3, STM32x and EFM32). Preliminary support for various NAND flash\ncontrollers (LPC3180, Orion, S3C24xx, more) is included.\n\n@section OpenOCD Web Site\n\nThe OpenOCD web site provides the latest public news from the community:\n\n@uref{http://openocd.org/}\n\n@section Latest User's Guide:\n\nThe user's guide you are now reading may not be the latest one\navailable. A version for more recent code may be available.\nIts HTML form is published regularly at:\n\n@uref{http://openocd.org/doc/html/index.html}\n\nPDF form is likewise published at:\n\n@uref{http://openocd.org/doc/pdf/openocd.pdf}\n\n@section OpenOCD User's Forum\n\nThere is an OpenOCD forum (phpBB) hosted by SparkFun,\nwhich might be helpful to you. Note that if you want\nanything to come to the attention of developers, you\nshould post it to the OpenOCD Developer Mailing List\ninstead of this forum.\n\n@uref{http://forum.sparkfun.com/viewforum.php?f=18}\n\n@section OpenOCD User's Mailing List\n\nThe OpenOCD User Mailing List provides the primary means of\ncommunication between users:\n\n@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-user}\n\n@section OpenOCD IRC\n\nSupport can also be found on irc:\n@uref{irc://irc.libera.chat/openocd}\n\n@node Developers\n@chapter OpenOCD Developer Resources\n@cindex developers\n\nIf you are interested in improving the state of OpenOCD's debugging and\ntesting support, new contributions will be welcome. Motivated developers\ncan produce new target, flash or interface drivers, improve the\ndocumentation, as well as more conventional bug fixes and enhancements.\n\nThe resources in this chapter are available for developers wishing to explore\nor expand the OpenOCD source code.\n\n@section OpenOCD Git Repository\n\nDuring the 0.3.x release cycle, OpenOCD switched from Subversion to\na Git repository hosted at SourceForge. The repository URL is:\n\n@uref{git://git.code.sf.net/p/openocd/code}\n\nor via http\n\n@uref{http://git.code.sf.net/p/openocd/code}\n\nYou may prefer to use a mirror and the HTTP protocol:\n\n@uref{http://repo.or.cz/r/openocd.git}\n\nWith standard Git tools, use @command{git clone} to initialize\na local repository, and @command{git pull} to update it.\nThere are also gitweb pages letting you browse the repository\nwith a web browser, or download arbitrary snapshots without\nneeding a Git client:\n\n@uref{http://repo.or.cz/w/openocd.git}\n\nThe @file{README} file contains the instructions for building the project\nfrom the repository or a snapshot.\n\nDevelopers that want to contribute patches to the OpenOCD system are\n@b{strongly} encouraged to work against mainline.\nPatches created against older versions may require additional\nwork from their submitter in order to be updated for newer releases.\n\n@section Doxygen Developer Manual\n\nDuring the 0.2.x release cycle, the OpenOCD project began\nproviding a Doxygen reference manual. This document contains more\ntechnical information about the software internals, development\nprocesses, and similar documentation:\n\n@uref{http://openocd.org/doc/doxygen/html/index.html}\n\nThis document is a work-in-progress, but contributions would be welcome\nto fill in the gaps. All of the source files are provided in-tree,\nlisted in the Doxyfile configuration at the top of the source tree.\n\n@section Gerrit Review System\n\nAll changes in the OpenOCD Git repository go through the web-based Gerrit\nCode Review System:\n\n@uref{https://review.openocd.org/}\n\nAfter a one-time registration and repository setup, anyone can push commits\nfrom their local Git repository directly into Gerrit.\nAll users and developers are encouraged to review, test, discuss and vote\nfor changes in Gerrit. The feedback provides the basis for a maintainer to\neventually submit the change to the main Git repository.\n\nThe @file{HACKING} file, also available as the Patch Guide in the Doxygen\nDeveloper Manual, contains basic information about how to connect a\nrepository to Gerrit, prepare and push patches. Patch authors are expected to\nmaintain their changes while they're in Gerrit, respond to feedback and if\nnecessary rework and push improved versions of the change.\n\n@section OpenOCD Developer Mailing List\n\nThe OpenOCD Developer Mailing List provides the primary means of\ncommunication between developers:\n\n@uref{https://lists.sourceforge.net/mailman/listinfo/openocd-devel}\n\n@section OpenOCD Bug Tracker\n\nThe OpenOCD Bug Tracker is hosted on SourceForge:\n\n@uref{http://bugs.openocd.org/}\n\n\n@node Debug Adapter Hardware\n@chapter Debug Adapter Hardware\n@cindex dongles\n@cindex FTDI\n@cindex wiggler\n@cindex printer port\n@cindex USB Adapter\n@cindex RTCK\n\nDefined: @b{dongle}: A small device that plugs into a computer and serves as\nan adapter .... [snip]\n\nIn the OpenOCD case, this generally refers to @b{a small adapter} that\nattaches to your computer via USB or the parallel port.\n\n\n@section Choosing a Dongle\n\nThere are several things you should keep in mind when choosing a dongle.\n\n@enumerate\n@item @b{Transport} Does it support the kind of communication that you need?\nOpenOCD focuses mostly on JTAG. Your version may also support\nother ways to communicate with target devices.\n@item @b{Voltage} What voltage is your target - 1.8, 2.8, 3.3, or 5V?\nDoes your dongle support it? You might need a level converter.\n@item @b{Pinout} What pinout does your target board use?\nDoes your dongle support it? You may be able to use jumper\nwires, or an \"octopus\" connector, to convert pinouts.\n@item @b{Connection} Does your computer have the USB, parallel, or\nEthernet port needed?\n@item @b{RTCK} Do you expect to use it with ARM chips and boards with\nRTCK support (also known as ``adaptive clocking'')?\n@end enumerate\n\n@section USB FT2232 Based\n\nThere are many USB JTAG dongles on the market, many of them based\non a chip from ``Future Technology Devices International'' (FTDI)\nknown as the FTDI FT2232; this is a USB full speed (12 Mbps) chip.\nSee: @url{http://www.ftdichip.com} for more information.\nIn summer 2009, USB high speed (480 Mbps) versions of these FTDI\nchips started to become available in JTAG adapters. Around 2012, a new\nvariant appeared - FT232H - this is a single-channel version of FT2232H.\n(Adapters using those high speed FT2232H or FT232H chips may support adaptive\nclocking.)\n\nThe FT2232 chips are flexible enough to support some other\ntransport options, such as SWD or the SPI variants used to\nprogram some chips. They have two communications channels,\nand one can be used for a UART adapter at the same time the\nother one is used to provide a debug adapter.\n\nAlso, some development boards integrate an FT2232 chip to serve as\na built-in low-cost debug adapter and USB-to-serial solution.\n\n@itemize @bullet\n@item @b{usbjtag}\n@* Link @url{http://elk.informatik.fh-augsburg.de/hhweb/doc/openocd/usbjtag/usbjtag.html}\n@item @b{jtagkey}\n@* See: @url{http://www.amontec.com/jtagkey.shtml}\n@item @b{jtagkey2}\n@* See: @url{http://www.amontec.com/jtagkey2.shtml}\n@item @b{oocdlink}\n@* See: @url{http://www.oocdlink.com} By Joern Kaipf\n@item @b{signalyzer}\n@* See: @url{http://www.signalyzer.com}\n@item @b{Stellaris Eval Boards}\n@* See: @url{http://www.ti.com} - The Stellaris eval boards\nbundle FT2232-based JTAG and SWD support, which can be used to debug\nthe Stellaris chips. Using separate JTAG adapters is optional.\nThese boards can also be used in a \"pass through\" mode as JTAG adapters\nto other target boards, disabling the Stellaris chip.\n@item @b{TI/Luminary ICDI}\n@* See: @url{http://www.ti.com} - TI/Luminary In-Circuit Debug\nInterface (ICDI) Boards are included in Stellaris LM3S9B9x\nEvaluation Kits. Like the non-detachable FT2232 support on the other\nStellaris eval boards, they can be used to debug other target boards.\n@item @b{olimex-jtag}\n@* See: @url{http://www.olimex.com}\n@item @b{Flyswatter/Flyswatter2}\n@* See: @url{http://www.tincantools.com}\n@item @b{turtelizer2}\n@* See:\n@uref{http://www.ethernut.de/en/hardware/turtelizer/index.html, Turtelizer 2}, or\n@url{http://www.ethernut.de}\n@item @b{comstick}\n@* Link: @url{http://www.hitex.com/index.php?id=383}\n@item @b{stm32stick}\n@* Link @url{http://www.hitex.com/stm32-stick}\n@item @b{axm0432_jtag}\n@* Axiom AXM-0432 Link @url{http://www.axman.com} - NOTE: This JTAG does not appear\nto be available anymore as of April 2012.\n@item @b{cortino}\n@* Link @url{http://www.hitex.com/index.php?id=cortino}\n@item @b{dlp-usb1232h}\n@* Link @url{http://www.dlpdesign.com/usb/usb1232h.shtml}\n@item @b{digilent-hs1}\n@* Link @url{http://www.digilentinc.com/Products/Detail.cfm?Prod=JTAG-HS1}\n@item @b{opendous}\n@* Link @url{http://code.google.com/p/opendous/wiki/JTAG} FT2232H-based\n(OpenHardware).\n@item @b{JTAG-lock-pick Tiny 2}\n@* Link @url{http://www.distortec.com/jtag-lock-pick-tiny-2} FT232H-based\n\n@item @b{GW16042}\n@* Link: @url{http://shop.gateworks.com/index.php?route=product/product&path=70_80&product_id=64}\nFT2232H-based\n\n@end itemize\n@section USB-JTAG / Altera USB-Blaster compatibles\n\nThese devices also show up as FTDI devices, but are not\nprotocol-compatible with the FT2232 devices. They are, however,\nprotocol-compatible among themselves. USB-JTAG devices typically consist\nof a FT245 followed by a CPLD that understands a particular protocol,\nor emulates this protocol using some other hardware.\n\nThey may appear under different USB VID/PID depending on the particular\nproduct. The driver can be configured to search for any VID/PID pair\n(see the section on driver commands).\n\n@itemize\n@item @b{USB-JTAG} Kolja Waschk's USB Blaster-compatible adapter\n@* Link: @url{http://ixo-jtag.sourceforge.net/}\n@item @b{Altera USB-Blaster}\n@* Link: @url{http://www.altera.com/literature/ug/ug_usb_blstr.pdf}\n@end itemize\n\n@section USB J-Link based\nThere are several OEM versions of the SEGGER @b{J-Link} adapter. It is\nan example of a microcontroller based JTAG adapter, it uses an\nAT91SAM764 internally.\n\n@itemize @bullet\n@item @b{SEGGER J-Link}\n@* Link: @url{http://www.segger.com/jlink.html}\n@item @b{Atmel SAM-ICE} (Only works with Atmel chips!)\n@* Link: @url{http://www.atmel.com/tools/atmelsam-ice.aspx}\n@item @b{IAR J-Link}\n@end itemize\n\n@section USB RLINK based\nRaisonance has an adapter called @b{RLink}. It exists in a stripped-down form on the STM32 Primer,\npermanently attached to the JTAG lines. It also exists on the STM32 Primer2, but that is wired for\nSWD and not JTAG, thus not supported.\n\n@itemize @bullet\n@item @b{Raisonance RLink}\n@* Link: @url{http://www.mcu-raisonance.com/~rlink-debugger-programmer__@/microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html}\n@item @b{STM32 Primer}\n@* Link: @url{http://www.stm32circle.com/resources/stm32primer.php}\n@item @b{STM32 Primer2}\n@* Link: @url{http://www.stm32circle.com/resources/stm32primer2.php}\n@end itemize\n\n@section USB ST-LINK based\nSTMicroelectronics has an adapter called @b{ST-LINK}.\nThey only work with STMicroelectronics chips, notably STM32 and STM8.\n\n@itemize @bullet\n@item @b{ST-LINK}\n@* This is available standalone and as part of some kits, eg. STM32VLDISCOVERY.\n@* Link: @url{http://www.st.com/internet/evalboard/product/219866.jsp}\n@item @b{ST-LINK/V2}\n@* This is available standalone and as part of some kits, eg. STM32F4DISCOVERY.\n@* Link: @url{http://www.st.com/internet/evalboard/product/251168.jsp}\n@item @b{STLINK-V3}\n@* This is available standalone and as part of some kits.\n@* Link: @url{http://www.st.com/stlink-v3}\n@item @b{STLINK-V3PWR}\n@* This is available standalone.\nBeside the debugger functionality, the probe includes a SMU (source\nmeasurement unit) aimed at analyzing power consumption during code\nexecution. The SMU is not supported by OpenOCD.\n@* Link: @url{http://www.st.com/stlink-v3pwr}\n@end itemize\n\nFor info the original ST-LINK enumerates using the mass storage usb class; however,\nits implementation is completely broken. The result is this causes issues under Linux.\nThe simplest solution is to get Linux to ignore the ST-LINK using one of the following methods:\n@itemize @bullet\n@item modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n@item add \"options usb-storage quirks=483:3744:i\" to /etc/modprobe.conf\n@end itemize\n\n@section USB TI/Stellaris ICDI based\nTexas Instruments has an adapter called @b{ICDI}.\nIt is not to be confused with the FTDI based adapters that were originally fitted to their\nevaluation boards. This is the adapter fitted to the Stellaris LaunchPad.\n\n@section USB Nuvoton Nu-Link\nNuvoton has an adapter called @b{Nu-Link}.\nIt is available either as stand-alone dongle and embedded on development boards.\nIt supports SWD, serial port bridge and mass storage for firmware update.\nBoth Nu-Link v1 and v2 are supported.\n\n@section USB CMSIS-DAP based\nARM has released a interface standard called CMSIS-DAP that simplifies connecting\ndebuggers to ARM Cortex based targets @url{http://www.keil.com/support/man/docs/dapdebug/dapdebug_introduction.htm}.\n\n@section USB Other\n@itemize @bullet\n@item @b{USBprog}\n@* Link: @url{http://shop.embedded-projects.net/} - which uses an Atmel MEGA32 and a UBN9604\n\n@item @b{USB - Presto}\n@* Link: @url{http://tools.asix.net/prg_presto.htm}\n\n@item @b{Versaloon-Link}\n@* Link: @url{http://www.versaloon.com}\n\n@item @b{ARM-JTAG-EW}\n@* Link: @url{http://www.olimex.com/dev/arm-jtag-ew.html}\n\n@item @b{Buspirate}\n@* Link: @url{http://dangerousprototypes.com/bus-pirate-manual/}\n\n@item @b{opendous}\n@* Link: @url{http://code.google.com/p/opendous-jtag/} - which uses an AT90USB162\n\n@item @b{estick}\n@* Link: @url{http://code.google.com/p/estick-jtag/}\n\n@item @b{Keil ULINK v1}\n@* Link: @url{http://www.keil.com/ulink1/}\n\n@item @b{TI XDS110 Debug Probe}\n@* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds110.html}\n@* Link: @url{https://software-dl.ti.com/ccs/esd/documents/xdsdebugprobes/emu_xds_software_package_download.html#xds110-support-utilities}\n@end itemize\n\n@section IBM PC Parallel Printer Port Based\n\nThe two well-known ``JTAG Parallel Ports'' cables are the Xilinx DLC5\nand the Macraigor Wiggler. There are many clones and variations of\nthese on the market.\n\nNote that parallel ports are becoming much less common, so if you\nhave the choice you should probably avoid these adapters in favor\nof USB-based ones.\n\n@itemize @bullet\n\n@item @b{Wiggler} - There are many clones of this.\n@* Link: @url{http://www.macraigor.com/wiggler.htm}\n\n@item @b{DLC5} - From XILINX - There are many clones of this\n@* Link: Search the web for: ``XILINX DLC5'' - it is no longer\nproduced, PDF schematics are easily found and it is easy to make.\n\n@item @b{Amontec - JTAG Accelerator}\n@* Link: @url{http://www.amontec.com/jtag_accelerator.shtml}\n\n@item @b{Wiggler2}\n@* Link: @url{http://www.ccac.rwth-aachen.de/~michaels/index.php/hardware/armjtag}\n\n@item @b{Wiggler_ntrst_inverted}\n@* Yet another variation - See the source code, src/jtag/parport.c\n\n@item @b{old_amt_wiggler}\n@* Unknown - probably not on the market today\n\n@item @b{arm-jtag}\n@* Link: Most likely @url{http://www.olimex.com/dev/arm-jtag.html} [another wiggler clone]\n\n@item @b{chameleon}\n@* Link: @url{http://www.amontec.com/chameleon.shtml}\n\n@item @b{Triton}\n@* Unknown.\n\n@item @b{Lattice}\n@* ispDownload from Lattice Semiconductor\n@url{http://www.latticesemi.com/lit/docs/@/devtools/dlcable.pdf}\n\n@item @b{flashlink}\n@* From STMicroelectronics;\n@* Link: @url{http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATA_BRIEF/DM00039500.pdf}\n\n@end itemize\n\n@section Other...\n@itemize @bullet\n\n@item @b{ep93xx}\n@* An EP93xx based Linux machine using the GPIO pins directly.\n\n@item @b{at91rm9200}\n@* Like the EP93xx - but an ATMEL AT91RM9200 based solution using the GPIO pins on the chip.\n\n@item @b{bcm2835gpio}\n@* A BCM2835-based board (e.g. Raspberry Pi) using the GPIO pins of the expansion header.\n\n@item @b{imx_gpio}\n@* A NXP i.MX-based board (e.g. Wandboard) using the GPIO pins (should work on any i.MX processor).\n\n@item @b{am335xgpio}\n@* A Texas Instruments AM335x-based board (e.g. BeagleBone Black) using the GPIO pins of the expansion headers.\n\n@item @b{jtag_vpi}\n@* A JTAG driver acting as a client for the JTAG VPI server interface.\n@* Link: @url{http://github.com/fjullien/jtag_vpi}\n\n@item @b{vdebug}\n@* A driver for Cadence virtual Debug Interface to emulated or simulated targets.\nIt implements a client connecting to the vdebug server, which in turn communicates\nwith the emulated or simulated RTL model through a transactor. The driver supports\nJTAG and DAP-level transports.\n\n@item @b{jtag_dpi}\n@* A JTAG driver acting as a client for the SystemVerilog Direct Programming\nInterface (DPI) for JTAG devices. DPI allows OpenOCD to connect to the JTAG\ninterface of a hardware model written in SystemVerilog, for example, on an\nemulation model of target hardware.\n\n@item @b{xlnx_pcie_xvc}\n@* A JTAG driver exposing Xilinx Virtual Cable over PCI Express to OpenOCD as JTAG/SWD interface.\n\n@item @b{linuxgpiod}\n@* A bitbang JTAG driver using Linux GPIO through library libgpiod.\n\n@item @b{sysfsgpio}\n@* A bitbang JTAG driver using Linux legacy sysfs GPIO.\nThis is deprecated from Linux v5.3; prefer using @b{linuxgpiod}.\n\n@item @b{esp_usb_jtag}\n@* A JTAG driver to communicate with builtin debug modules of Espressif ESP32-C3 and ESP32-S3 chips using OpenOCD.\n\n@end itemize\n\n@node About Jim-Tcl\n@chapter About Jim-Tcl\n@cindex Jim-Tcl\n@cindex tcl\n\nOpenOCD uses a small ``Tcl Interpreter'' known as Jim-Tcl.\nThis programming language provides a simple and extensible\ncommand interpreter.\n\nAll commands presented in this Guide are extensions to Jim-Tcl.\nYou can use them as simple commands, without needing to learn\nmuch of anything about Tcl.\nAlternatively, you can write Tcl programs with them.\n\nYou can learn more about Jim at its website, @url{http://jim.tcl.tk}.\nThere is an active and responsive community, get on the mailing list\nif you have any questions. Jim-Tcl maintainers also lurk on the\nOpenOCD mailing list.\n\n@itemize @bullet\n@item @b{Jim vs. Tcl}\n@* Jim-Tcl is a stripped down version of the well known Tcl language,\nwhich can be found here: @url{http://www.tcl.tk}. Jim-Tcl has far\nfewer features. Jim-Tcl is several dozens of .C files and .H files and\nimplements the basic Tcl command set. In contrast: Tcl 8.6 is a\n4.2 MB .zip file containing 1540 files.\n\n@item @b{Missing Features}\n@* Our practice has been: Add/clone the real Tcl feature if/when\nneeded. We welcome Jim-Tcl improvements, not bloat. Also there\nare a large number of optional Jim-Tcl features that are not\nenabled in OpenOCD.\n\n@item @b{Scripts}\n@* OpenOCD configuration scripts are Jim-Tcl Scripts. OpenOCD's\ncommand interpreter today is a mixture of (newer)\nJim-Tcl commands, and the (older) original command interpreter.\n\n@item @b{Commands}\n@* At the OpenOCD telnet command line (or via the GDB monitor command) one\ncan type a Tcl for() loop, set variables, etc.\nSome of the commands documented in this guide are implemented\nas Tcl scripts, from a @file{startup.tcl} file internal to the server.\n\n@item @b{Historical Note}\n@* Jim-Tcl was introduced to OpenOCD in spring 2008. Fall 2010,\nbefore OpenOCD 0.5 release, OpenOCD switched to using Jim-Tcl\nas a Git submodule, which greatly simplified upgrading Jim-Tcl\nto benefit from new features and bugfixes in Jim-Tcl.\n\n@item @b{Need a crash course in Tcl?}\n@*@xref{Tcl Crash Course}.\n@end itemize\n\n@node Running\n@chapter Running\n@cindex command line options\n@cindex logfile\n@cindex directory search\n\nProperly installing OpenOCD sets up your operating system to grant it access\nto the debug adapters. On Linux, this usually involves installing a file\nin @file{/etc/udev/rules.d,} so OpenOCD has permissions. An example rules file\nthat works for many common adapters is shipped with OpenOCD in the\n@file{contrib} directory. MS-Windows needs\ncomplex and confusing driver configuration for every peripheral. Such issues\nare unique to each operating system, and are not detailed in this User's Guide.\n\nThen later you will invoke the OpenOCD server, with various options to\ntell it how each debug session should work.\nThe @option{--help} option shows:\n@verbatim\nbash$ openocd --help\n\n--help       | -h       display this help\n--version    | -v       display OpenOCD version\n--file       | -f       use configuration file <name>\n--search     | -s       dir to search for config files and scripts\n--debug      | -d       set debug level to 3\n             | -d<n>    set debug level to <level>\n--log_output | -l       redirect log output to file <name>\n--command    | -c       run <command>\n@end verbatim\n\nIf you don't give any @option{-f} or @option{-c} options,\nOpenOCD tries to read the configuration file @file{openocd.cfg}.\nTo specify one or more different\nconfiguration files, use @option{-f} options. For example:\n\n@example\nopenocd -f config1.cfg -f config2.cfg -f config3.cfg\n@end example\n\nConfiguration files and scripts are searched for in\n@enumerate\n@item the current directory,\n@item any search dir specified on the command line using the @option{-s} option,\n@item any search dir specified using the @command{add_script_search_dir} command,\n@item a directory in the @env{OPENOCD_SCRIPTS} environment variable (if set),\n@item @file{%APPDATA%/OpenOCD} (only on Windows),\n@item @file{$HOME/Library/Preferences/org.openocd} (only on Darwin),\n@item @file{$XDG_CONFIG_HOME/openocd} (@env{$XDG_CONFIG_HOME} defaults to @file{$HOME/.config}),\n@item @file{$HOME/.openocd},\n@item the site wide script library @file{$pkgdatadir/site} and\n@item the OpenOCD-supplied script library @file{$pkgdatadir/scripts}.\n@end enumerate\nThe first found file with a matching file name will be used.\n\n@quotation Note\nDon't try to use configuration script names or paths which\ninclude the \"#\" character. That character begins Tcl comments.\n@end quotation\n\n@section Simple setup, no customization\n\nIn the best case, you can use two scripts from one of the script\nlibraries, hook up your JTAG adapter, and start the server ... and\nyour JTAG setup will just work \"out of the box\". Always try to\nstart by reusing those scripts, but assume you'll need more\ncustomization even if this works. @xref{OpenOCD Project Setup}.\n\nIf you find a script for your JTAG adapter, and for your board or\ntarget, you may be able to hook up your JTAG adapter then start\nthe server with some variation of one of the following:\n\n@example\nopenocd -f interface/ADAPTER.cfg -f board/MYBOARD.cfg\nopenocd -f interface/ftdi/ADAPTER.cfg -f board/MYBOARD.cfg\n@end example\n\nYou might also need to configure which reset signals are present,\nusing @option{-c 'reset_config trst_and_srst'} or something similar.\nIf all goes well you'll see output something like\n\n@example\nOpen On-Chip Debugger 0.4.0 (2010-01-14-15:06)\nFor bug reports, read\n        http://openocd.org/doc/doxygen/bugs.html\nInfo : JTAG tap: lm3s.cpu tap/device found: 0x3ba00477\n       (mfg: 0x23b, part: 0xba00, ver: 0x3)\n@end example\n\nSeeing that \"tap/device found\" message, and no warnings, means\nthe JTAG communication is working. That's a key milestone, but\nyou'll probably need more project-specific setup.\n\n@section What OpenOCD does as it starts\n\nOpenOCD starts by processing the configuration commands provided\non the command line or, if there were no @option{-c command} or\n@option{-f file.cfg} options given, in @file{openocd.cfg}.\n@xref{configurationstage,,Configuration Stage}.\nAt the end of the configuration stage it verifies the JTAG scan\nchain defined using those commands; your configuration should\nensure that this always succeeds.\nNormally, OpenOCD then starts running as a server.\nAlternatively, commands may be used to terminate the configuration\nstage early, perform work (such as updating some flash memory),\nand then shut down without acting as a server.\n\nOnce OpenOCD starts running as a server, it waits for connections from\nclients (Telnet, GDB, RPC) and processes the commands issued through\nthose channels.\n\nIf you are having problems, you can enable internal debug messages via\nthe @option{-d} option.\n\nAlso it is possible to interleave Jim-Tcl commands w/config scripts using the\n@option{-c} command line switch.\n\nTo enable debug output (when reporting problems or working on OpenOCD\nitself), use the @option{-d} command line switch. This sets the\n@option{debug_level} to \"3\", outputting the most information,\nincluding debug messages. The default setting is \"2\", outputting only\ninformational messages, warnings and errors. You can also change this\nsetting from within a telnet or gdb session using @command{debug_level<n>}\n(@pxref{debuglevel,,debug_level}).\n\nYou can redirect all output from the server to a file using the\n@option{-l <logfile>} switch.\n\nNote! OpenOCD will launch the GDB & telnet server even if it can not\nestablish a connection with the target. In general, it is possible for\nthe JTAG controller to be unresponsive until the target is set up\ncorrectly via e.g. GDB monitor commands in a GDB init script.\n\n@node OpenOCD Project Setup\n@chapter OpenOCD Project Setup\n\nTo use OpenOCD with your development projects, you need to do more than\njust connect the JTAG adapter hardware (dongle) to your development board\nand start the OpenOCD server.\nYou also need to configure your OpenOCD server so that it knows\nabout your adapter and board, and helps your work.\nYou may also want to connect OpenOCD to GDB, possibly\nusing Eclipse or some other GUI.\n\n@section Hooking up the JTAG Adapter\n\nToday's most common case is a dongle with a JTAG cable on one side\n(such as a ribbon cable with a 10-pin or 20-pin IDC connector)\nand a USB cable on the other.\nInstead of USB, some dongles use Ethernet;\nolder ones may use a PC parallel port, or even a serial port.\n\n@enumerate\n@item @emph{Start with power to your target board turned off},\nand nothing connected to your JTAG adapter.\nIf you're particularly paranoid, unplug power to the board.\nIt's important to have the ground signal properly set up,\nunless you are using a JTAG adapter which provides\ngalvanic isolation between the target board and the\ndebugging host.\n\n@item @emph{Be sure it's the right kind of JTAG connector.}\nIf your dongle has a 20-pin ARM connector, you need some kind\nof adapter (or octopus, see below) to hook it up to\nboards using 14-pin or 10-pin connectors ... or to 20-pin\nconnectors which don't use ARM's pinout.\n\nIn the same vein, make sure the voltage levels are compatible.\nNot all JTAG adapters have the level shifters needed to work\nwith 1.2 Volt boards.\n\n@item @emph{Be certain the cable is properly oriented} or you might\ndamage your board. In most cases there are only two possible\nways to connect the cable.\nConnect the JTAG cable from your adapter to the board.\nBe sure it's firmly connected.\n\nIn the best case, the connector is keyed to physically\nprevent you from inserting it wrong.\nThis is most often done using a slot on the board's male connector\nhousing, which must match a key on the JTAG cable's female connector.\nIf there's no housing, then you must look carefully and\nmake sure pin 1 on the cable hooks up to pin 1 on the board.\nRibbon cables are frequently all grey except for a wire on one\nedge, which is red. The red wire is pin 1.\n\nSometimes dongles provide cables where one end is an ``octopus'' of\ncolor coded single-wire connectors, instead of a connector block.\nThese are great when converting from one JTAG pinout to another,\nbut are tedious to set up.\nUse these with connector pinout diagrams to help you match up the\nadapter signals to the right board pins.\n\n@item @emph{Connect the adapter's other end} once the JTAG cable is connected.\nA USB, parallel, or serial port connector will go to the host which\nyou are using to run OpenOCD.\nFor Ethernet, consult the documentation and your network administrator.\n\nFor USB-based JTAG adapters you have an easy sanity check at this point:\ndoes the host operating system see the JTAG adapter? If you're running\nLinux, try the @command{lsusb} command. If that host is an\nMS-Windows host, you'll need to install a driver before OpenOCD works.\n\n@item @emph{Connect the adapter's power supply, if needed.}\nThis step is primarily for non-USB adapters,\nbut sometimes USB adapters need extra power.\n\n@item @emph{Power up the target board.}\nUnless you just let the magic smoke escape,\nyou're now ready to set up the OpenOCD server\nso you can use JTAG to work with that board.\n\n@end enumerate\n\nTalk with the OpenOCD server using\ntelnet (@code{telnet localhost 4444} on many systems) or GDB.\n@xref{GDB and OpenOCD}.\n\n@section Project Directory\n\nThere are many ways you can configure OpenOCD and start it up.\n\nA simple way to organize them all involves keeping a\nsingle directory for your work with a given board.\nWhen you start OpenOCD from that directory,\nit searches there first for configuration files, scripts,\nfiles accessed through semihosting,\nand for code you upload to the target board.\nIt is also the natural place to write files,\nsuch as log files and data you download from the board.\n\n@section Configuration Basics\n\nThere are two basic ways of configuring OpenOCD, and\na variety of ways you can mix them.\nThink of the difference as just being how you start the server:\n\n@itemize\n@item Many @option{-f file} or @option{-c command} options on the command line\n@item No options, but a @dfn{user config file}\nin the current directory named @file{openocd.cfg}\n@end itemize\n\nHere is an example @file{openocd.cfg} file for a setup\nusing a Signalyzer FT2232-based JTAG adapter to talk to\na board with an Atmel AT91SAM7X256 microcontroller:\n\n@example\nsource [find interface/ftdi/signalyzer.cfg]\n\n# GDB can also flash my flash!\ngdb_memory_map enable\ngdb_flash_program enable\n\nsource [find target/sam7x256.cfg]\n@end example\n\nHere is the command line equivalent of that configuration:\n\n@example\nopenocd -f interface/ftdi/signalyzer.cfg \\\n        -c \"gdb_memory_map enable\" \\\n        -c \"gdb_flash_program enable\" \\\n        -f target/sam7x256.cfg\n@end example\n\nYou could wrap such long command lines in shell scripts,\neach supporting a different development task.\nOne might re-flash the board with a specific firmware version.\nAnother might set up a particular debugging or run-time environment.\n\n@quotation Important\nAt this writing (October 2009) the command line method has\nproblems with how it treats variables.\nFor example, after @option{-c \"set VAR value\"}, or doing the\nsame in a script, the variable @var{VAR} will have no value\nthat can be tested in a later script.\n@end quotation\n\nHere we will focus on the simpler solution: one user config\nfile, including basic configuration plus any TCL procedures\nto simplify your work.\n\n@section User Config Files\n@cindex config file, user\n@cindex user config file\n@cindex config file, overview\n\nA user configuration file ties together all the parts of a project\nin one place.\nOne of the following will match your situation best:\n\n@itemize\n@item Ideally almost everything comes from configuration files\nprovided by someone else.\nFor example, OpenOCD distributes a @file{scripts} directory\n(probably in @file{/usr/share/openocd/scripts} on Linux).\nBoard and tool vendors can provide these too, as can individual\nuser sites; the @option{-s} command line option lets you say\nwhere to find these files. (@xref{Running}.)\nThe AT91SAM7X256 example above works this way.\n\nThree main types of non-user configuration file each have their\nown subdirectory in the @file{scripts} directory:\n\n@enumerate\n@item @b{interface} -- one for each different debug adapter;\n@item @b{board} -- one for each different board\n@item @b{target} -- the chips which integrate CPUs and other JTAG TAPs\n@end enumerate\n\nBest case: include just two files, and they handle everything else.\nThe first is an interface config file.\nThe second is board-specific, and it sets up the JTAG TAPs and\ntheir GDB targets (by deferring to some @file{target.cfg} file),\ndeclares all flash memory, and leaves you nothing to do except\nmeet your deadline:\n\n@example\nsource [find interface/olimex-jtag-tiny.cfg]\nsource [find board/csb337.cfg]\n@end example\n\nBoards with a single microcontroller often won't need more\nthan the target config file, as in the AT91SAM7X256 example.\nThat's because there is no external memory (flash, DDR RAM), and\nthe board differences are encapsulated by application code.\n\n@item Maybe you don't know yet what your board looks like to JTAG.\nOnce you know the @file{interface.cfg} file to use, you may\nneed help from OpenOCD to discover what's on the board.\nOnce you find the JTAG TAPs, you can just search for appropriate\ntarget and board\nconfiguration files ... or write your own, from the bottom up.\n@xref{autoprobing,,Autoprobing}.\n\n@item You can often reuse some standard config files but\nneed to write a few new ones, probably a @file{board.cfg} file.\nYou will be using commands described later in this User's Guide,\nand working with the guidelines in the next chapter.\n\nFor example, there may be configuration files for your JTAG adapter\nand target chip, but you need a new board-specific config file\ngiving access to your particular flash chips.\nOr you might need to write another target chip configuration file\nfor a new chip built around the Cortex-M3 core.\n\n@quotation Note\nWhen you write new configuration files, please submit\nthem for inclusion in the next OpenOCD release.\nFor example, a @file{board/newboard.cfg} file will help the\nnext users of that board, and a @file{target/newcpu.cfg}\nwill help support users of any board using that chip.\n@end quotation\n\n@item\nYou may need to write some C code.\nIt may be as simple as supporting a new FT2232 or parport\nbased adapter; a bit more involved, like a NAND or NOR flash\ncontroller driver; or a big piece of work like supporting\na new chip architecture.\n@end itemize\n\nReuse the existing config files when you can.\nLook first in the @file{scripts/boards} area, then @file{scripts/targets}.\nYou may find a board configuration that's a good example to follow.\n\nWhen you write config files, separate the reusable parts\n(things every user of that interface, chip, or board needs)\nfrom ones specific to your environment and debugging approach.\n@itemize\n\n@item\nFor example, a @code{gdb-attach} event handler that invokes\nthe @command{reset init} command will interfere with debugging\nearly boot code, which performs some of the same actions\nthat the @code{reset-init} event handler does.\n\n@item\nLikewise, the @command{arm9 vector_catch} command (or\n@cindex vector_catch\nits siblings @command{xscale vector_catch}\nand @command{cortex_m vector_catch}) can be a time-saver\nduring some debug sessions, but don't make everyone use that either.\nKeep those kinds of debugging aids in your user config file,\nalong with messaging and tracing setup.\n(@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}.)\n\n@item\nYou might need to override some defaults.\nFor example, you might need to move, shrink, or back up the target's\nwork area if your application needs much SRAM.\n\n@item\nTCP/IP port configuration is another example of something which\nis environment-specific, and should only appear in\na user config file. @xref{tcpipports,,TCP/IP Ports}.\n@end itemize\n\n@section Project-Specific Utilities\n\nA few project-specific utility\nroutines may well speed up your work.\nWrite them, and keep them in your project's user config file.\n\nFor example, if you are making a boot loader work on a\nboard, it's nice to be able to debug the ``after it's\nloaded to RAM'' parts separately from the finicky early\ncode which sets up the DDR RAM controller and clocks.\nA script like this one, or a more GDB-aware sibling,\nmay help:\n\n@example\nproc ramboot @{ @} @{\n    # Reset, running the target's \"reset-init\" scripts\n    # to initialize clocks and the DDR RAM controller.\n    # Leave the CPU halted.\n    reset init\n\n    # Load CONFIG_SKIP_LOWLEVEL_INIT version into DDR RAM.\n    load_image u-boot.bin 0x20000000\n\n    # Start running.\n    resume 0x20000000\n@}\n@end example\n\nThen once that code is working you will need to make it\nboot from NOR flash; a different utility would help.\nAlternatively, some developers write to flash using GDB.\n(You might use a similar script if you're working with a flash\nbased microcontroller application instead of a boot loader.)\n\n@example\nproc newboot @{ @} @{\n    # Reset, leaving the CPU halted. The \"reset-init\" event\n    # proc gives faster access to the CPU and to NOR flash;\n    # \"reset halt\" would be slower.\n    reset init\n\n    # Write standard version of U-Boot into the first two\n    # sectors of NOR flash ... the standard version should\n    # do the same lowlevel init as \"reset-init\".\n    flash protect 0 0 1 off\n    flash erase_sector 0 0 1\n    flash write_bank 0 u-boot.bin 0x0\n    flash protect 0 0 1 on\n\n    # Reboot from scratch using that new boot loader.\n    reset run\n@}\n@end example\n\nYou may need more complicated utility procedures when booting\nfrom NAND.\nThat often involves an extra bootloader stage,\nrunning from on-chip SRAM to perform DDR RAM setup so it can load\nthe main bootloader code (which won't fit into that SRAM).\n\nOther helper scripts might be used to write production system images,\ninvolving considerably more than just a three stage bootloader.\n\n@section Target Software Changes\n\nSometimes you may want to make some small changes to the software\nyou're developing, to help make JTAG debugging work better.\nFor example, in C or assembly language code you might\nuse @code{#ifdef JTAG_DEBUG} (or its converse) around code\nhandling issues like:\n\n@itemize @bullet\n\n@item @b{Watchdog Timers}...\nWatchdog timers are typically used to automatically reset systems if\nsome application task doesn't periodically reset the timer. (The\nassumption is that the system has locked up if the task can't run.)\nWhen a JTAG debugger halts the system, that task won't be able to run\nand reset the timer ... potentially causing resets in the middle of\nyour debug sessions.\n\nIt's rarely a good idea to disable such watchdogs, since their usage\nneeds to be debugged just like all other parts of your firmware.\nThat might however be your only option.\n\nLook instead for chip-specific ways to stop the watchdog from counting\nwhile the system is in a debug halt state. It may be simplest to set\nthat non-counting mode in your debugger startup scripts. You may however\nneed a different approach when, for example, a motor could be physically\ndamaged by firmware remaining inactive in a debug halt state. That might\ninvolve a type of firmware mode where that \"non-counting\" mode is disabled\nat the beginning then re-enabled at the end; a watchdog reset might fire\nand complicate the debug session, but hardware (or people) would be\nprotected.@footnote{Note that many systems support a \"monitor mode\" debug\nthat is a somewhat cleaner way to address such issues. You can think of\nit as only halting part of the system, maybe just one task,\ninstead of the whole thing.\nAt this writing, January 2010, OpenOCD based debugging does not support\nmonitor mode debug, only \"halt mode\" debug.}\n\n@item @b{ARM Semihosting}...\n@cindex ARM semihosting\nWhen linked with a special runtime library provided with many\ntoolchains@footnote{See chapter 8 \"Semihosting\" in\n@uref{http://infocenter.arm.com/help/topic/com.arm.doc.dui0203i/DUI0203I_rvct_developer_guide.pdf,\nARM DUI 0203I}, the \"RealView Compilation Tools Developer Guide\".\nThe CodeSourcery EABI toolchain also includes a semihosting library.},\nyour target code can use I/O facilities on the debug host. That library\nprovides a small set of system calls which are handled by OpenOCD.\nIt can let the debugger provide your system console and a file system,\nhelping with early debugging or providing a more capable environment\nfor sometimes-complex tasks like installing system firmware onto\nNAND or SPI flash.\n\n@item @b{ARM Wait-For-Interrupt}...\nMany ARM chips synchronize the JTAG clock using the core clock.\nLow power states which stop that core clock thus prevent JTAG access.\nIdle loops in tasking environments often enter those low power states\nvia the @code{WFI} instruction (or its coprocessor equivalent, before ARMv7).\n\nYou may want to @emph{disable that instruction} in source code,\nor otherwise prevent using that state,\nto ensure you can get JTAG access at any time.@footnote{As a more\npolite alternative, some processors have special debug-oriented\nregisters which can be used to change various features including\nhow the low power states are clocked while debugging.\nThe STM32 DBGMCU_CR register is an example; at the cost of extra\npower consumption, JTAG can be used during low power states.}\nFor example, the OpenOCD @command{halt} command may not\nwork for an idle processor otherwise.\n\n@item @b{Delay after reset}...\nNot all chips have good support for debugger access\nright after reset; many LPC2xxx chips have issues here.\nSimilarly, applications that reconfigure pins used for\nJTAG access as they start will also block debugger access.\n\nTo work with boards like this, @emph{enable a short delay loop}\nthe first thing after reset, before \"real\" startup activities.\nFor example, one second's delay is usually more than enough\ntime for a JTAG debugger to attach, so that\nearly code execution can be debugged\nor firmware can be replaced.\n\n@item @b{Debug Communications Channel (DCC)}...\nSome processors include mechanisms to send messages over JTAG.\nMany ARM cores support these, as do some cores from other vendors.\n(OpenOCD may be able to use this DCC internally, speeding up some\noperations like writing to memory.)\n\nYour application may want to deliver various debugging messages\nover JTAG, by @emph{linking with a small library of code}\nprovided with OpenOCD and using the utilities there to send\nvarious kinds of message.\n@xref{softwaredebugmessagesandtracing,,Software Debug Messages and Tracing}.\n\n@end itemize\n\n@section Target Hardware Setup\n\nChip vendors often provide software development boards which\nare highly configurable, so that they can support all options\nthat product boards may require. @emph{Make sure that any\njumpers or switches match the system configuration you are\nworking with.}\n\nCommon issues include:\n\n@itemize @bullet\n\n@item @b{JTAG setup} ...\nBoards may support more than one JTAG configuration.\nExamples include jumpers controlling pullups versus pulldowns\non the nTRST and/or nSRST signals, and choice of connectors\n(e.g. which of two headers on the base board,\nor one from a daughtercard).\nFor some Texas Instruments boards, you may need to jumper the\nEMU0 and EMU1 signals (which OpenOCD won't currently control).\n\n@item @b{Boot Modes} ...\nComplex chips often support multiple boot modes, controlled\nby external jumpers. Make sure this is set up correctly.\nFor example many i.MX boards from NXP need to be jumpered\nto \"ATX mode\" to start booting using the on-chip ROM, when\nusing second stage bootloader code stored in a NAND flash chip.\n\nSuch explicit configuration is common, and not limited to\nbooting from NAND. You might also need to set jumpers to\nstart booting using code loaded from an MMC/SD card; external\nSPI flash; Ethernet, UART, or USB links; NOR flash; OneNAND\nflash; some external host; or various other sources.\n\n\n@item @b{Memory Addressing} ...\nBoards which support multiple boot modes may also have jumpers\nto configure memory addressing. One board, for example, jumpers\nexternal chipselect 0 (used for booting) to address either\na large SRAM (which must be pre-loaded via JTAG), NOR flash,\nor NAND flash. When it's jumpered to address NAND flash, that\nboard must also be told to start booting from on-chip ROM.\n\nYour @file{board.cfg} file may also need to be told this jumper\nconfiguration, so that it can know whether to declare NOR flash\nusing @command{flash bank} or instead declare NAND flash with\n@command{nand device}; and likewise which probe to perform in\nits @code{reset-init} handler.\n\nA closely related issue is bus width. Jumpers might need to\ndistinguish between 8 bit or 16 bit bus access for the flash\nused to start booting.\n\n@item @b{Peripheral Access} ...\nDevelopment boards generally provide access to every peripheral\non the chip, sometimes in multiple modes (such as by providing\nmultiple audio codec chips).\nThis interacts with software\nconfiguration of pin multiplexing, where for example a\ngiven pin may be routed either to the MMC/SD controller\nor the GPIO controller. It also often interacts with\nconfiguration jumpers. One jumper may be used to route\nsignals to an MMC/SD card slot or an expansion bus (which\nmight in turn affect booting); others might control which\naudio or video codecs are used.\n\n@end itemize\n\nPlus you should of course have @code{reset-init} event handlers\nwhich set up the hardware to match that jumper configuration.\nThat includes in particular any oscillator or PLL used to clock\nthe CPU, and any memory controllers needed to access external\nmemory and peripherals. Without such handlers, you won't be\nable to access those resources without working target firmware\nwhich can do that setup ... this can be awkward when you're\ntrying to debug that target firmware. Even if there's a ROM\nbootloader which handles a few issues, it rarely provides full\naccess to all board-specific capabilities.\n\n\n@node Config File Guidelines\n@chapter Config File Guidelines\n\nThis chapter is aimed at any user who needs to write a config file,\nincluding developers and integrators of OpenOCD and any user who\nneeds to get a new board working smoothly.\nIt provides guidelines for creating those files.\n\nYou should find the following directories under\n@t{$(INSTALLDIR)/scripts}, with config files maintained upstream. Use\nthem as-is where you can; or as models for new files.\n@itemize @bullet\n@item @file{interface} ...\nThese are for debug adapters. Files that specify configuration to use\nspecific JTAG, SWD and other adapters go here.\n@item @file{board} ...\nThink Circuit Board, PWA, PCB, they go by many names. Board files\ncontain initialization items that are specific to a board.\n\nThey reuse target configuration files, since the same\nmicroprocessor chips are used on many boards,\nbut support for external parts varies widely. For\nexample, the SDRAM initialization sequence for the board, or the type\nof external flash and what address it uses. Any initialization\nsequence to enable that external flash or SDRAM should be found in the\nboard file. Boards may also contain multiple targets: two CPUs; or\na CPU and an FPGA.\n@item @file{target} ...\nThink chip. The ``target'' directory represents the JTAG TAPs\non a chip\nwhich OpenOCD should control, not a board. Two common types of targets\nare ARM chips and FPGA or CPLD chips.\nWhen a chip has multiple TAPs (maybe it has both ARM and DSP cores),\nthe target config file defines all of them.\n@item @emph{more} ... browse for other library files which may be useful.\nFor example, there are various generic and CPU-specific utilities.\n@end itemize\n\nThe @file{openocd.cfg} user config\nfile may override features in any of the above files by\nsetting variables before sourcing the target file, or by adding\ncommands specific to their situation.\n\n@section Interface Config Files\n\nThe user config file\nshould be able to source one of these files with a command like this:\n\n@example\nsource [find interface/FOOBAR.cfg]\n@end example\n\nA preconfigured interface file should exist for every debug adapter\nin use today with OpenOCD.\nThat said, perhaps some of these config files\nhave only been used by the developer who created it.\n\nA separate chapter gives information about how to set these up.\n@xref{Debug Adapter Configuration}.\nRead the OpenOCD source code (and Developer's Guide)\nif you have a new kind of hardware interface\nand need to provide a driver for it.\n\n@deffn {Command} {find} 'filename'\nPrints full path to @var{filename} according to OpenOCD search rules.\n@end deffn\n\n@deffn {Command} {ocd_find} 'filename'\nPrints full path to @var{filename} according to OpenOCD search rules. This\nis a low level function used by the @command{find}. Usually you want\nto use @command{find}, instead.\n@end deffn\n\n@section Board Config Files\n@cindex config file, board\n@cindex board config file\n\nThe user config file\nshould be able to source one of these files with a command like this:\n\n@example\nsource [find board/FOOBAR.cfg]\n@end example\n\nThe point of a board config file is to package everything\nabout a given board that user config files need to know.\nIn summary the board files should contain (if present)\n\n@enumerate\n@item One or more @command{source [find target/...cfg]} statements\n@item NOR flash configuration (@pxref{norconfiguration,,NOR Configuration})\n@item NAND flash configuration (@pxref{nandconfiguration,,NAND Configuration})\n@item Target @code{reset} handlers for SDRAM and I/O configuration\n@item JTAG adapter reset configuration (@pxref{Reset Configuration})\n@item All things that are not ``inside a chip''\n@end enumerate\n\nGeneric things inside target chips belong in target config files,\nnot board config files. So for example a @code{reset-init} event\nhandler should know board-specific oscillator and PLL parameters,\nwhich it passes to target-specific utility code.\n\nThe most complex task of a board config file is creating such a\n@code{reset-init} event handler.\nDefine those handlers last, after you verify the rest of the board\nconfiguration works.\n\n@subsection Communication Between Config files\n\nIn addition to target-specific utility code, another way that\nboard and target config files communicate is by following a\nconvention on how to use certain variables.\n\nThe full Tcl/Tk language supports ``namespaces'', but Jim-Tcl does not.\nThus the rule we follow in OpenOCD is this: Variables that begin with\na leading underscore are temporary in nature, and can be modified and\nused at will within a target configuration file.\n\nComplex board config files can do the things like this,\nfor a board with three chips:\n\n@example\n# Chip #1: PXA270 for network side, big endian\nset CHIPNAME network\nset ENDIAN big\nsource [find target/pxa270.cfg]\n# on return: _TARGETNAME = network.cpu\n# other commands can refer to the \"network.cpu\" target.\n$_TARGETNAME configure .... events for this CPU..\n\n# Chip #2: PXA270 for video side, little endian\nset CHIPNAME video\nset ENDIAN little\nsource [find target/pxa270.cfg]\n# on return: _TARGETNAME = video.cpu\n# other commands can refer to the \"video.cpu\" target.\n$_TARGETNAME configure .... events for this CPU..\n\n# Chip #3: Xilinx FPGA for glue logic\nset CHIPNAME xilinx\nunset ENDIAN\nsource [find target/spartan3.cfg]\n@end example\n\nThat example is oversimplified because it doesn't show any flash memory,\nor the @code{reset-init} event handlers to initialize external DRAM\nor (assuming it needs it) load a configuration into the FPGA.\nSuch features are usually needed for low-level work with many boards,\nwhere ``low level'' implies that the board initialization software may\nnot be working. (That's a common reason to need JTAG tools. Another\nis to enable working with microcontroller-based systems, which often\nhave no debugging support except a JTAG connector.)\n\nTarget config files may also export utility functions to board and user\nconfig files. Such functions should use name prefixes, to help avoid\nnaming collisions.\n\nBoard files could also accept input variables from user config files.\nFor example, there might be a @code{J4_JUMPER} setting used to identify\nwhat kind of flash memory a development board is using, or how to set\nup other clocks and peripherals.\n\n@subsection Variable Naming Convention\n@cindex variable names\n\nMost boards have only one instance of a chip.\nHowever, it should be easy to create a board with more than\none such chip (as shown above).\nAccordingly, we encourage these conventions for naming\nvariables associated with different @file{target.cfg} files,\nto promote consistency and\nso that board files can override target defaults.\n\nInputs to target config files include:\n\n@itemize @bullet\n@item @code{CHIPNAME} ...\nThis gives a name to the overall chip, and is used as part of\ntap identifier dotted names.\nWhile the default is normally provided by the chip manufacturer,\nboard files may need to distinguish between instances of a chip.\n@item @code{ENDIAN} ...\nBy default @option{little} - although chips may hard-wire @option{big}.\nChips that can't change endianness don't need to use this variable.\n@item @code{CPUTAPID} ...\nWhen OpenOCD examines the JTAG chain, it can be told verify the\nchips against the JTAG IDCODE register.\nThe target file will hold one or more defaults, but sometimes the\nchip in a board will use a different ID (perhaps a newer revision).\n@end itemize\n\nOutputs from target config files include:\n\n@itemize @bullet\n@item @code{_TARGETNAME} ...\nBy convention, this variable is created by the target configuration\nscript. The board configuration file may make use of this variable to\nconfigure things like a ``reset init'' script, or other things\nspecific to that board and that target.\nIf the chip has 2 targets, the names are @code{_TARGETNAME0},\n@code{_TARGETNAME1}, ... etc.\n@end itemize\n\n@subsection The reset-init Event Handler\n@cindex event, reset-init\n@cindex reset-init handler\n\nBoard config files run in the OpenOCD configuration stage;\nthey can't use TAPs or targets, since they haven't been\nfully set up yet.\nThis means you can't write memory or access chip registers;\nyou can't even verify that a flash chip is present.\nThat's done later in event handlers, of which the target @code{reset-init}\nhandler is one of the most important.\n\nExcept on microcontrollers, the basic job of @code{reset-init} event\nhandlers is setting up flash and DRAM, as normally handled by boot loaders.\nMicrocontrollers rarely use boot loaders; they run right out of their\non-chip flash and SRAM memory. But they may want to use one of these\nhandlers too, if just for developer convenience.\n\n@quotation Note\nBecause this is so very board-specific, and chip-specific, no examples\nare included here.\nInstead, look at the board config files distributed with OpenOCD.\nIf you have a boot loader, its source code will help; so will\nconfiguration files for other JTAG tools\n(@pxref{translatingconfigurationfiles,,Translating Configuration Files}).\n@end quotation\n\nSome of this code could probably be shared between different boards.\nFor example, setting up a DRAM controller often doesn't differ by\nmuch except the bus width (16 bits or 32?) and memory timings, so a\nreusable TCL procedure loaded by the @file{target.cfg} file might take\nthose as parameters.\nSimilarly with oscillator, PLL, and clock setup;\nand disabling the watchdog.\nStructure the code cleanly, and provide comments to help\nthe next developer doing such work.\n(@emph{You might be that next person} trying to reuse init code!)\n\nThe last thing normally done in a @code{reset-init} handler is probing\nwhatever flash memory was configured. For most chips that needs to be\ndone while the associated target is halted, either because JTAG memory\naccess uses the CPU or to prevent conflicting CPU access.\n\n@subsection JTAG Clock Rate\n\nBefore your @code{reset-init} handler has set up\nthe PLLs and clocking, you may need to run with\na low JTAG clock rate.\n@xref{jtagspeed,,JTAG Speed}.\nThen you'd increase that rate after your handler has\nmade it possible to use the faster JTAG clock.\nWhen the initial low speed is board-specific, for example\nbecause it depends on a board-specific oscillator speed, then\nyou should probably set it up in the board config file;\nif it's target-specific, it belongs in the target config file.\n\nFor most ARM-based processors the fastest JTAG clock@footnote{A FAQ\n@uref{http://www.arm.com/support/faqdev/4170.html} gives details.}\nis one sixth of the CPU clock; or one eighth for ARM11 cores.\nConsult chip documentation to determine the peak JTAG clock rate,\nwhich might be less than that.\n\n@quotation Warning\nOn most ARMs, JTAG clock detection is coupled to the core clock, so\nsoftware using a @option{wait for interrupt} operation blocks JTAG access.\nAdaptive clocking provides a partial workaround, but a more complete\nsolution just avoids using that instruction with JTAG debuggers.\n@end quotation\n\nIf both the chip and the board support adaptive clocking,\nuse the @command{jtag_rclk}\ncommand, in case your board is used with JTAG adapter which\nalso supports it. Otherwise use @command{adapter speed}.\nSet the slow rate at the beginning of the reset sequence,\nand the faster rate as soon as the clocks are at full speed.\n\n@anchor{theinitboardprocedure}\n@subsection The init_board procedure\n@cindex init_board procedure\n\nThe concept of @code{init_board} procedure is very similar to @code{init_targets}\n(@xref{theinittargetsprocedure,,The init_targets procedure}.) - it's a replacement of ``linear''\nconfiguration scripts. This procedure is meant to be executed when OpenOCD enters run stage\n(@xref{enteringtherunstage,,Entering the Run Stage},) after @code{init_targets}. The idea to have\nseparate @code{init_targets} and @code{init_board} procedures is to allow the first one to configure\neverything target specific (internal flash, internal RAM, etc.) and the second one to configure\neverything board specific (reset signals, chip frequency, reset-init event handler, external memory, etc.).\nAdditionally ``linear'' board config file will most likely fail when target config file uses\n@code{init_targets} scheme (``linear'' script is executed before @code{init} and @code{init_targets} - after),\nso separating these two configuration stages is very convenient, as the easiest way to overcome this\nproblem is to convert board config file to use @code{init_board} procedure. Board config scripts don't\nneed to override @code{init_targets} defined in target config files when they only need to add some specifics.\n\nJust as @code{init_targets}, the @code{init_board} procedure can be overridden by ``next level'' script (which sources\nthe original), allowing greater code reuse.\n\n@example\n### board_file.cfg ###\n\n# source target file that does most of the config in init_targets\nsource [find target/target.cfg]\n\nproc enable_fast_clock @{@} @{\n    # enables fast on-board clock source\n    # configures the chip to use it\n@}\n\n# initialize only board specifics - reset, clock, adapter frequency\nproc init_board @{@} @{\n    reset_config trst_and_srst trst_pulls_srst\n\n    $_TARGETNAME configure -event reset-start @{\n        adapter speed 100\n    @}\n\n    $_TARGETNAME configure -event reset-init @{\n        enable_fast_clock\n        adapter speed 10000\n    @}\n@}\n@end example\n\n@section Target Config Files\n@cindex config file, target\n@cindex target config file\n\nBoard config files communicate with target config files using\nnaming conventions as described above, and may source one or\nmore target config files like this:\n\n@example\nsource [find target/FOOBAR.cfg]\n@end example\n\nThe point of a target config file is to package everything\nabout a given chip that board config files need to know.\nIn summary the target files should contain\n\n@enumerate\n@item Set defaults\n@item Add TAPs to the scan chain\n@item Add CPU targets (includes GDB support)\n@item CPU/Chip/CPU-Core specific features\n@item On-Chip flash\n@end enumerate\n\nAs a rule of thumb, a target file sets up only one chip.\nFor a microcontroller, that will often include a single TAP,\nwhich is a CPU needing a GDB target, and its on-chip flash.\n\nMore complex chips may include multiple TAPs, and the target\nconfig file may need to define them all before OpenOCD\ncan talk to the chip.\nFor example, some phone chips have JTAG scan chains that include\nan ARM core for operating system use, a DSP,\nanother ARM core embedded in an image processing engine,\nand other processing engines.\n\n@subsection Default Value Boiler Plate Code\n\nAll target configuration files should start with code like this,\nletting board config files express environment-specific\ndifferences in how things should be set up.\n\n@example\n# Boards may override chip names, perhaps based on role,\n# but the default should match what the vendor uses\nif @{ [info exists CHIPNAME] @} @{\n   set  _CHIPNAME $CHIPNAME\n@} else @{\n   set  _CHIPNAME sam7x256\n@}\n\n# ONLY use ENDIAN with targets that can change it.\nif @{ [info exists ENDIAN] @} @{\n   set  _ENDIAN $ENDIAN\n@} else @{\n   set  _ENDIAN little\n@}\n\n# TAP identifiers may change as chips mature, for example with\n# new revision fields (the \"3\" here). Pick a good default; you\n# can pass several such identifiers to the \"jtag newtap\" command.\nif @{ [info exists CPUTAPID ] @} @{\n   set _CPUTAPID $CPUTAPID\n@} else @{\n   set _CPUTAPID 0x3f0f0f0f\n@}\n@end example\n@c but 0x3f0f0f0f is for an str73x part ...\n\n@emph{Remember:} Board config files may include multiple target\nconfig files, or the same target file multiple times\n(changing at least @code{CHIPNAME}).\n\nLikewise, the target configuration file should define\n@code{_TARGETNAME} (or @code{_TARGETNAME0} etc) and\nuse it later on when defining debug targets:\n\n@example\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n@end example\n\n@subsection Adding TAPs to the Scan Chain\nAfter the ``defaults'' are set up,\nadd the TAPs on each chip to the JTAG scan chain.\n@xref{TAP Declaration}, and the naming convention\nfor taps.\n\nIn the simplest case the chip has only one TAP,\nprobably for a CPU or FPGA.\nThe config file for the Atmel AT91SAM7X256\nlooks (in part) like this:\n\n@example\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n@end example\n\nA board with two such at91sam7 chips would be able\nto source such a config file twice, with different\nvalues for @code{CHIPNAME}, so\nit adds a different TAP each time.\n\nIf there are nonzero @option{-expected-id} values,\nOpenOCD attempts to verify the actual tap id against those values.\nIt will issue error messages if there is mismatch, which\ncan help to pinpoint problems in OpenOCD configurations.\n\n@example\nJTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f\n                (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)\nERROR: Tap: sam7x256.cpu - Expected id: 0x12345678, Got: 0x3f0f0f0f\nERROR: expected: mfg: 0x33c, part: 0x2345, ver: 0x1\nERROR:      got: mfg: 0x787, part: 0xf0f0, ver: 0x3\n@end example\n\nThere are more complex examples too, with chips that have\nmultiple TAPs. Ones worth looking at include:\n\n@itemize\n@item @file{target/omap3530.cfg} -- with disabled ARM and DSP,\nplus a JRC to enable them\n@item @file{target/str912.cfg} -- with flash, CPU, and boundary scan\n@item @file{target/ti_dm355.cfg} -- with ETM, ARM, and JRC (this JRC\nis not currently used)\n@end itemize\n\n@subsection Add CPU targets\n\nAfter adding a TAP for a CPU, you should set it up so that\nGDB and other commands can use it.\n@xref{CPU Configuration}.\nFor the at91sam7 example above, the command can look like this;\nnote that @code{$_ENDIAN} is not needed, since OpenOCD defaults\nto little endian, and this chip doesn't support changing that.\n\n@example\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n@end example\n\nWork areas are small RAM areas associated with CPU targets.\nThey are used by OpenOCD to speed up downloads,\nand to download small snippets of code to program flash chips.\nIf the chip includes a form of ``on-chip-ram'' - and many do - define\na work area if you can.\nAgain using the at91sam7 as an example, this can look like:\n\n@example\n$_TARGETNAME configure -work-area-phys 0x00200000 \\\n             -work-area-size 0x4000 -work-area-backup 0\n@end example\n\n@subsection Define CPU targets working in SMP\n@cindex SMP\nAfter setting targets, you can define a list of targets working in SMP.\n\n@example\nset _TARGETNAME_1 $_CHIPNAME.cpu1\nset _TARGETNAME_2 $_CHIPNAME.cpu2\ntarget create $_TARGETNAME_1 cortex_a -chain-position $_CHIPNAME.dap \\\n-coreid 0 -dbgbase $_DAP_DBG1\ntarget create $_TARGETNAME_2 cortex_a -chain-position $_CHIPNAME.dap \\\n-coreid 1 -dbgbase $_DAP_DBG2\n#define 2 targets working in smp.\ntarget smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\n@end example\nIn the above example on cortex_a, 2 cpus are working in SMP.\nIn SMP only one GDB instance is created and :\n@itemize @bullet\n@item a set of hardware breakpoint sets the same breakpoint on all targets in the list.\n@item halt command triggers the halt of all targets in the list.\n@item resume command triggers the write context and the restart of all targets in the list.\n@item following a breakpoint: the target stopped by the breakpoint is displayed to the GDB session.\n@item dedicated GDB serial protocol packets are implemented for switching/retrieving the target\ndisplayed by the GDB session @pxref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}.\n@end itemize\n\nThe SMP behaviour can be disabled/enabled dynamically. On cortex_a following\ncommand have been implemented.\n@itemize @bullet\n@item cortex_a smp on : enable SMP mode, behaviour is as described above.\n@item cortex_a smp off : disable SMP mode, the current target is the one\ndisplayed in the GDB session, only this target is now controlled by GDB\nsession. This behaviour is useful during system boot up.\n@item cortex_a smp : display current SMP mode.\n@item cortex_a smp_gdb : display/fix the core id displayed in GDB session see\nfollowing example.\n@end itemize\n\n@example\n>cortex_a smp_gdb\ngdb coreid  0 -> -1\n#0 : coreid 0 is displayed to GDB ,\n#-> -1 : next resume triggers a real resume\n> cortex_a smp_gdb 1\ngdb coreid  0 -> 1\n#0 :coreid 0 is displayed to GDB ,\n#->1  : next resume displays coreid 1 to GDB\n> resume\n> cortex_a smp_gdb\ngdb coreid  1 -> 1\n#1 :coreid 1 is displayed to GDB ,\n#->1 : next resume displays coreid 1 to GDB\n> cortex_a smp_gdb -1\ngdb coreid  1 -> -1\n#1 :coreid 1 is displayed to GDB,\n#->-1 : next resume triggers a real resume\n@end example\n\n\n@subsection Chip Reset Setup\n\nAs a rule, you should put the @command{reset_config} command\ninto the board file. Most things you think you know about a\nchip can be tweaked by the board.\n\nSome chips have specific ways the TRST and SRST signals are\nmanaged. In the unusual case that these are @emph{chip specific}\nand can never be changed by board wiring, they could go here.\nFor example, some chips can't support JTAG debugging without\nboth signals.\n\nProvide a @code{reset-assert} event handler if you can.\nSuch a handler uses JTAG operations to reset the target,\nletting this target config be used in systems which don't\nprovide the optional SRST signal, or on systems where you\ndon't want to reset all targets at once.\nSuch a handler might write to chip registers to force a reset,\nuse a JRC to do that (preferable -- the target may be wedged!),\nor force a watchdog timer to trigger.\n(For Cortex-M targets, this is not necessary.  The target\ndriver knows how to use trigger an NVIC reset when SRST is\nnot available.)\n\nSome chips need special attention during reset handling if\nthey're going to be used with JTAG.\nAn example might be needing to send some commands right\nafter the target's TAP has been reset, providing a\n@code{reset-deassert-post} event handler that writes a chip\nregister to report that JTAG debugging is being done.\nAnother would be reconfiguring the watchdog so that it stops\ncounting while the core is halted in the debugger.\n\nJTAG clocking constraints often change during reset, and in\nsome cases target config files (rather than board config files)\nare the right places to handle some of those issues.\nFor example, immediately after reset most chips run using a\nslower clock than they will use later.\nThat means that after reset (and potentially, as OpenOCD\nfirst starts up) they must use a slower JTAG clock rate\nthan they will use later.\n@xref{jtagspeed,,JTAG Speed}.\n\n@quotation Important\nWhen you are debugging code that runs right after chip\nreset, getting these issues right is critical.\nIn particular, if you see intermittent failures when\nOpenOCD verifies the scan chain after reset,\nlook at how you are setting up JTAG clocking.\n@end quotation\n\n@anchor{theinittargetsprocedure}\n@subsection The init_targets procedure\n@cindex init_targets procedure\n\nTarget config files can either be ``linear'' (script executed line-by-line when parsed in\nconfiguration stage, @xref{configurationstage,,Configuration Stage},) or they can contain a special\nprocedure called @code{init_targets}, which will be executed when entering run stage\n(after parsing all config files or after @code{init} command, @xref{enteringtherunstage,,Entering the Run Stage}.)\nSuch procedure can be overridden by ``next level'' script (which sources the original).\nThis concept facilitates code reuse when basic target config files provide generic configuration\nprocedures and @code{init_targets} procedure, which can then be sourced and enhanced or changed in\na ``more specific'' target config file. This is not possible with ``linear'' config scripts,\nbecause sourcing them executes every initialization commands they provide.\n\n@example\n### generic_file.cfg ###\n\nproc setup_my_chip @{chip_name flash_size ram_size@} @{\n    # basic initialization procedure ...\n@}\n\nproc init_targets @{@} @{\n    # initializes generic chip with 4kB of flash and 1kB of RAM\n    setup_my_chip MY_GENERIC_CHIP 4096 1024\n@}\n\n### specific_file.cfg ###\n\nsource [find target/generic_file.cfg]\n\nproc init_targets @{@} @{\n    # initializes specific chip with 128kB of flash and 64kB of RAM\n    setup_my_chip MY_CHIP_WITH_128K_FLASH_64KB_RAM 131072 65536\n@}\n@end example\n\nThe easiest way to convert ``linear'' config files to @code{init_targets} version is to\nenclose every line of ``code'' (i.e. not @code{source} commands, procedures, etc.) in this procedure.\n\nFor an example of this scheme see LPC2000 target config files.\n\nThe @code{init_boards} procedure is a similar concept concerning board config files\n(@xref{theinitboardprocedure,,The init_board procedure}.)\n\n@subsection The init_target_events procedure\n@cindex init_target_events procedure\n\nA special procedure called @code{init_target_events} is run just after\n@code{init_targets} (@xref{theinittargetsprocedure,,The init_targets\nprocedure}.) and before @code{init_board}\n(@xref{theinitboardprocedure,,The init_board procedure}.) It is used\nto set up default target events for the targets that do not have those\nevents already assigned.\n\n@subsection ARM Core Specific Hacks\n\nIf the chip has a DCC, enable it. If the chip is an ARM9 with some\nspecial high speed download features - enable it.\n\nIf present, the MMU, the MPU and the CACHE should be disabled.\n\nSome ARM cores are equipped with trace support, which permits\nexamination of the instruction and data bus activity. Trace\nactivity is controlled through an ``Embedded Trace Module'' (ETM)\non one of the core's scan chains. The ETM emits voluminous data\nthrough a ``trace port''. (@xref{armhardwaretracing,,ARM Hardware Tracing}.)\nIf you are using an external trace port,\nconfigure it in your board config file.\nIf you are using an on-chip ``Embedded Trace Buffer'' (ETB),\nconfigure it in your target config file.\n\n@example\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n@end example\n\n@subsection Internal Flash Configuration\n\nThis applies @b{ONLY TO MICROCONTROLLERS} that have flash built in.\n\n@b{Never ever} in the ``target configuration file'' define any type of\nflash that is external to the chip. (For example a BOOT flash on\nChip Select 0.) Such flash information goes in a board file - not\nthe TARGET (chip) file.\n\nExamples:\n@itemize @bullet\n@item at91sam7x256 - has 256K flash YES enable it.\n@item str912 - has flash internal YES enable it.\n@item imx27 - uses boot flash on CS0 - it goes in the board file.\n@item pxa270 - again - CS0 flash - it goes in the board file.\n@end itemize\n\n@anchor{translatingconfigurationfiles}\n@section Translating Configuration Files\n@cindex translation\nIf you have a configuration file for another hardware debugger\nor toolset (Abatron, BDI2000, BDI3000, CCS,\nLauterbach, SEGGER, Macraigor, etc.), translating\nit into OpenOCD syntax is often quite straightforward. The most tricky\npart of creating a configuration script is oftentimes the reset init\nsequence where e.g. PLLs, DRAM and the like is set up.\n\nOne trick that you can use when translating is to write small\nTcl procedures to translate the syntax into OpenOCD syntax. This\ncan avoid manual translation errors and make it easier to\nconvert other scripts later on.\n\nExample of transforming quirky arguments to a simple search and\nreplace job:\n\n@example\n#   Lauterbach syntax(?)\n#\n#       Data.Set c15:0x042f %long 0x40000015\n#\n#   OpenOCD syntax when using procedure below.\n#\n#       setc15 0x01 0x00050078\n\nproc setc15 @{regs value@} @{\n    global TARGETNAME\n\n    echo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n    arm mcr 15 [expr @{($regs >> 12) & 0x7@}] \\\n        [expr @{($regs >> 0) & 0xf@}] [expr @{($regs >> 4) & 0xf@}] \\\n        [expr @{($regs >> 8) & 0x7@}] $value\n@}\n@end example\n\n\n\n@node Server Configuration\n@chapter Server Configuration\n@cindex initialization\nThe commands here are commonly found in the openocd.cfg file and are\nused to specify what TCP/IP ports are used, and how GDB should be\nsupported.\n\n@anchor{configurationstage}\n@section Configuration Stage\n@cindex configuration stage\n@cindex config command\n\nWhen the OpenOCD server process starts up, it enters a\n@emph{configuration stage} which is the only time that\ncertain commands, @emph{configuration commands}, may be issued.\nNormally, configuration commands are only available\ninside startup scripts.\n\nIn this manual, the definition of a configuration command is\npresented as a @emph{Config Command}, not as a @emph{Command}\nwhich may be issued interactively.\nThe runtime @command{help} command also highlights configuration\ncommands, and those which may be issued at any time.\n\nThose configuration commands include declaration of TAPs,\nflash banks,\nthe interface used for JTAG communication,\nand other basic setup.\nThe server must leave the configuration stage before it\nmay access or activate TAPs.\nAfter it leaves this stage, configuration commands may no\nlonger be issued.\n\n@deffn {Command} {command mode} [command_name]\nReturns the command modes allowed by a command: 'any', 'config', or\n'exec'. If no command is specified, returns the current command\nmode. Returns 'unknown' if an unknown command is given. Command can be\nmultiple tokens. (command valid any time)\n\nIn this document, the modes are described as stages, 'config' and\n'exec' mode correspond configuration stage and run stage. 'any' means\nthe command can be executed in either\nstages. @xref{configurationstage,,Configuration Stage}, and\n@xref{enteringtherunstage,,Entering the Run Stage}.\n@end deffn\n\n@anchor{enteringtherunstage}\n@section Entering the Run Stage\n\nThe first thing OpenOCD does after leaving the configuration\nstage is to verify that it can talk to the scan chain\n(list of TAPs) which has been configured.\nIt will warn if it doesn't find TAPs it expects to find,\nor finds TAPs that aren't supposed to be there.\nYou should see no errors at this point.\nIf you see errors, resolve them by correcting the\ncommands you used to configure the server.\nCommon errors include using an initial JTAG speed that's too\nfast, and not providing the right IDCODE values for the TAPs\non the scan chain.\n\nOnce OpenOCD has entered the run stage, a number of commands\nbecome available.\nA number of these relate to the debug targets you may have declared.\nFor example, the @command{mww} command will not be available until\na target has been successfully instantiated.\nIf you want to use those commands, you may need to force\nentry to the run stage.\n\n@deffn {Config Command} {init}\nThis command terminates the configuration stage and\nenters the run stage. This helps when you need to have\nthe startup scripts manage tasks such as resetting the target,\nprogramming flash, etc. To reset the CPU upon startup, add \"init\" and\n\"reset\" at the end of the config script or at the end of the OpenOCD\ncommand line using the @option{-c} command line switch.\n\nIf this command does not appear in any startup/configuration file\nOpenOCD executes the command for you after processing all\nconfiguration files and/or command line options.\n\n@b{NOTE:} This command normally occurs near the end of your\nopenocd.cfg file to force OpenOCD to ``initialize'' and make the\ntargets ready. For example: If your openocd.cfg file needs to\nread/write memory on your target, @command{init} must occur before\nthe memory read/write commands. This includes @command{nand probe}.\n\n@command{init} calls the following internal OpenOCD commands to initialize\ncorresponding subsystems:\n@deffn {Config Command} {target init}\n@deffnx {Command} {transport init}\n@deffnx {Command} {dap init}\n@deffnx {Config Command} {flash init}\n@deffnx {Config Command} {nand init}\n@deffnx {Config Command} {pld init}\n@deffnx {Command} {tpiu init}\n@end deffn\n\nAt last, @command{init} executes all the commands that are specified in\nthe TCL list @var{post_init_commands}. The commands are executed in the\nsame order they occupy in the list. If one of the commands fails, then\nthe error is propagated and OpenOCD fails too.\n@example\nlappend post_init_commands @{echo \"OpenOCD successfully initialized.\"@}\nlappend post_init_commands @{echo \"Have fun with OpenOCD !\"@}\n@end example\n@end deffn\n\n@deffn {Config Command} {noinit}\nPrevent OpenOCD from implicit @command{init} call at the end of startup.\nAllows issuing configuration commands over telnet or Tcl connection.\nWhen you are done with configuration use @command{init} to enter\nthe run stage.\n@end deffn\n\n@deffn {Overridable Procedure} {jtag_init}\nThis is invoked at server startup to verify that it can talk\nto the scan chain (list of TAPs) which has been configured.\n\nThe default implementation first tries @command{jtag arp_init},\nwhich uses only a lightweight JTAG reset before examining the\nscan chain.\nIf that fails, it tries again, using a harder reset\nfrom the overridable procedure @command{init_reset}.\n\nImplementations must have verified the JTAG scan chain before\nthey return.\nThis is done by calling @command{jtag arp_init}\n(or @command{jtag arp_init-reset}).\n@end deffn\n\n@anchor{tcpipports}\n@section TCP/IP Ports\n@cindex TCP port\n@cindex server\n@cindex port\n@cindex security\nThe OpenOCD server accepts remote commands in several syntaxes.\nEach syntax uses a different TCP/IP port, which you may specify\nonly during configuration (before those ports are opened).\n\nFor reasons including security, you may wish to prevent remote\naccess using one or more of these ports.\nIn such cases, just specify the relevant port number as \"disabled\".\nIf you disable all access through TCP/IP, you will need to\nuse the command line @option{-pipe} option.\n\n@anchor{gdb_port}\n@deffn {Config Command} {gdb_port} [number]\n@cindex GDB server\nNormally gdb listens to a TCP/IP port, but GDB can also\ncommunicate via pipes(stdin/out or named pipes). The name\n\"gdb_port\" stuck because it covers probably more than 90% of\nthe normal use cases.\n\nNo arguments reports GDB port. \"pipe\" means listen to stdin\noutput to stdout, an integer is base port number, \"disabled\"\ndisables the gdb server.\n\nWhen using \"pipe\", also use log_output to redirect the log\noutput to a file so as not to flood the stdin/out pipes.\n\nAny other string is interpreted as named pipe to listen to.\nOutput pipe is the same name as input pipe, but with 'o' appended,\ne.g. /var/gdb, /var/gdbo.\n\nThe GDB port for the first target will be the base port, the\nsecond target will listen on gdb_port + 1, and so on.\nWhen not specified during the configuration stage,\nthe port @var{number} defaults to 3333.\nWhen @var{number} is not a numeric value, incrementing it to compute\nthe next port number does not work. In this case, specify the proper\n@var{number} for each target by using the option @code{-gdb-port} of the\ncommands @command{target create} or @command{$target_name configure}.\n@xref{gdbportoverride,,option -gdb-port}.\n\nNote: when using \"gdb_port pipe\", increasing the default remote timeout in\ngdb (with 'set remotetimeout') is recommended. An insufficient timeout may\ncause initialization to fail with \"Unknown remote qXfer reply: OK\".\n@end deffn\n\n@deffn {Config Command} {tcl_port} [number]\nSpecify or query the port used for a simplified RPC\nconnection that can be used by clients to issue TCL commands and get the\noutput from the Tcl engine.\nIntended as a machine interface.\nWhen not specified during the configuration stage,\nthe port @var{number} defaults to 6666.\nWhen specified as \"disabled\", this service is not activated.\n@end deffn\n\n@deffn {Config Command} {telnet_port} [number]\nSpecify or query the\nport on which to listen for incoming telnet connections.\nThis port is intended for interaction with one human through TCL commands.\nWhen not specified during the configuration stage,\nthe port @var{number} defaults to 4444.\nWhen specified as \"disabled\", this service is not activated.\n@end deffn\n\n@anchor{gdbconfiguration}\n@section GDB Configuration\n@cindex GDB\n@cindex GDB configuration\nYou can reconfigure some GDB behaviors if needed.\nThe ones listed here are static and global.\n@xref{targetconfiguration,,Target Configuration}, about configuring individual targets.\n@xref{targetevents,,Target Events}, about configuring target-specific event handling.\n\n@anchor{gdbbreakpointoverride}\n@deffn {Command} {gdb_breakpoint_override} [@option{hard}|@option{soft}|@option{disable}]\nForce breakpoint type for gdb @command{break} commands.\nThis option supports GDB GUIs which don't\ndistinguish hard versus soft breakpoints, if the default OpenOCD and\nGDB behaviour is not sufficient. GDB normally uses hardware\nbreakpoints if the memory map has been set up for flash regions.\n@end deffn\n\n@anchor{gdbflashprogram}\n@deffn {Config Command} {gdb_flash_program} (@option{enable}|@option{disable})\nSet to @option{enable} to cause OpenOCD to program the flash memory when a\nvFlash packet is received.\nThe default behaviour is @option{enable}.\n@end deffn\n\n@deffn {Config Command} {gdb_memory_map} (@option{enable}|@option{disable})\nSet to @option{enable} to cause OpenOCD to send the memory configuration to GDB when\nrequested. GDB will then know when to set hardware breakpoints, and program flash\nusing the GDB load command. @command{gdb_flash_program enable} must also be enabled\nfor flash programming to work.\nDefault behaviour is @option{enable}.\n@xref{gdbflashprogram,,gdb_flash_program}.\n@end deffn\n\n@deffn {Config Command} {gdb_report_data_abort} (@option{enable}|@option{disable})\nSpecifies whether data aborts cause an error to be reported\nby GDB memory read packets.\nThe default behaviour is @option{disable};\nuse @option{enable} see these errors reported.\n@end deffn\n\n@deffn {Config Command} {gdb_report_register_access_error} (@option{enable}|@option{disable})\nSpecifies whether register accesses requested by GDB register read/write\npackets report errors or not.\nThe default behaviour is @option{disable};\nuse @option{enable} see these errors reported.\n@end deffn\n\n@deffn {Config Command} {gdb_target_description} (@option{enable}|@option{disable})\nSet to @option{enable} to cause OpenOCD to send the target descriptions to gdb via qXfer:features:read packet.\nThe default behaviour is @option{enable}.\n@end deffn\n\n@deffn {Command} {gdb_save_tdesc}\nSaves the target description file to the local file system.\n\nThe file name is @i{target_name}.xml.\n@end deffn\n\n@anchor{eventpolling}\n@section Event Polling\n\nHardware debuggers are parts of asynchronous systems,\nwhere significant events can happen at any time.\nThe OpenOCD server needs to detect some of these events,\nso it can report them to through TCL command line\nor to GDB.\n\nExamples of such events include:\n\n@itemize\n@item One of the targets can stop running ... maybe it triggers\na code breakpoint or data watchpoint, or halts itself.\n@item Messages may be sent over ``debug message'' channels ... many\ntargets support such messages sent over JTAG,\nfor receipt by the person debugging or tools.\n@item Loss of power ... some adapters can detect these events.\n@item Resets not issued through JTAG ... such reset sources\ncan include button presses or other system hardware, sometimes\nincluding the target itself (perhaps through a watchdog).\n@item Debug instrumentation sometimes supports event triggering\nsuch as ``trace buffer full'' (so it can quickly be emptied)\nor other signals (to correlate with code behavior).\n@end itemize\n\nNone of those events are signaled through standard JTAG signals.\nHowever, most conventions for JTAG connectors include voltage\nlevel and system reset (SRST) signal detection.\nSome connectors also include instrumentation signals, which\ncan imply events when those signals are inputs.\n\nIn general, OpenOCD needs to periodically check for those events,\neither by looking at the status of signals on the JTAG connector\nor by sending synchronous ``tell me your status'' JTAG requests\nto the various active targets.\nThere is a command to manage and monitor that polling,\nwhich is normally done in the background.\n\n@deffn {Command} {poll} [@option{on}|@option{off}]\nPoll the current target for its current state.\n(Also, @pxref{targetcurstate,,target curstate}.)\nIf that target is in debug mode, architecture\nspecific information about the current state is printed.\nAn optional parameter\nallows background polling to be enabled and disabled.\n\nYou could use this from the TCL command shell, or\nfrom GDB using @command{monitor poll} command.\nLeave background polling enabled while you're using GDB.\n@example\n> poll\nbackground polling: on\ntarget state: halted\ntarget halted in ARM state due to debug-request, \\\n               current mode: Supervisor\ncpsr: 0x800000d3 pc: 0x11081bfc\nMMU: disabled, D-Cache: disabled, I-Cache: enabled\n>\n@end example\n@end deffn\n\n@node Debug Adapter Configuration\n@chapter Debug Adapter Configuration\n@cindex config file, interface\n@cindex interface config file\n\nCorrectly installing OpenOCD includes making your operating system give\nOpenOCD access to debug adapters. Once that has been done, Tcl commands\nare used to select which one is used, and to configure how it is used.\n\n@quotation Note\nBecause OpenOCD started out with a focus purely on JTAG, you may find\nplaces where it wrongly presumes JTAG is the only transport protocol\nin use. Be aware that recent versions of OpenOCD are removing that\nlimitation. JTAG remains more functional than most other transports.\nOther transports do not support boundary scan operations, or may be\nspecific to a given chip vendor. Some might be usable only for\nprogramming flash memory, instead of also for debugging.\n@end quotation\n\nDebug Adapters/Interfaces/Dongles are normally configured\nthrough commands in an interface configuration\nfile which is sourced by your @file{openocd.cfg} file, or\nthrough a command line @option{-f interface/....cfg} option.\n\n@example\nsource [find interface/olimex-jtag-tiny.cfg]\n@end example\n\nThese commands tell\nOpenOCD what type of JTAG adapter you have, and how to talk to it.\nA few cases are so simple that you only need to say what driver to use:\n\n@example\n# jlink interface\nadapter driver jlink\n@end example\n\nMost adapters need a bit more configuration than that.\n\n\n@section Adapter Configuration\n\nThe @command{adapter driver} command tells OpenOCD what type of debug adapter you are\nusing. Depending on the type of adapter, you may need to use one or\nmore additional commands to further identify or configure the adapter.\n\n@deffn {Config Command} {adapter driver} name\nUse the adapter driver @var{name} to connect to the\ntarget.\n@end deffn\n\n@deffn {Command} {adapter list}\nList the debug adapter drivers that have been built into\nthe running copy of OpenOCD.\n@end deffn\n@deffn {Config Command} {adapter transports} transport_name+\nSpecifies the transports supported by this debug adapter.\nThe adapter driver builds-in similar knowledge; use this only\nwhen external configuration (such as jumpering) changes what\nthe hardware can support.\n@end deffn\n\n@anchor{adapter gpio}\n@deffn {Config Command} {adapter gpio [ @\n    @option{tdo} | @option{tdi} | @option{tms} | @option{tck} | @option{trst} | @\n    @option{swdio} | @option{swdio_dir} | @option{swclk} | @option{srst} | @\n    @option{led} @\n    [ @\n        gpio_number | @option{-chip} chip_number | @\n        @option{-active-high} | @option{-active-low} | @\n        @option{-push-pull} | @option{-open-drain} | @option{-open-source} | @\n        @option{-pull-none} | @option{-pull-up} | @option{-pull-down} | @\n        @option{-init-inactive} | @option{-init-active} | @option{-init-input} @\n    ] ]}\n\nDefine the GPIO mapping that the adapter will use. The following signals can be\ndefined:\n\n@itemize @minus\n@item @option{tdo}, @option{tdi}, @option{tms}, @option{tck}, @option{trst}:\nJTAG transport signals\n@item @option{swdio}, @option{swclk}: SWD transport signals\n@item @option{swdio_dir}: optional swdio buffer control signal\n@item @option{srst}: system reset signal\n@item @option{led}: optional activity led\n\n@end itemize\n\nSome adapters require that the GPIO chip number is set in addition to the GPIO\nnumber. The configuration options enable signals to be defined as active-high or\nactive-low. The output drive mode can be set to push-pull, open-drain or\nopen-source. Most adapters will have to emulate open-drain or open-source drive\nmodes by switching between an input and output. Input and output signals can be\ninstructed to use a pull-up or pull-down resistor, assuming it is supported by\nthe adaptor driver and hardware. The initial state of outputs may also be set,\n\"active\" state means 1 for active-high outputs and 0 for active-low outputs.\nBidirectional signals may also be initialized as an input. If the swdio signal\nis buffered the buffer direction can be controlled with the swdio_dir signal;\nthe active state means that the buffer should be set as an output with respect\nto the adapter. The command options are cumulative with later commands able to\noverride settings defined by earlier ones. The two commands @command{gpio led 7\n-active-high} and @command{gpio led -chip 1 -active-low} sent sequentially are\nequivalent to issuing the single command @command{gpio led 7 -chip 1\n-active-low}. It is not permissible to set the drive mode or initial state for\nsignals which are inputs. The drive mode for the srst and trst signals must be\nset with the @command{adapter reset_config} command. It is not permissible to\nset the initial state of swdio_dir as it is derived from the initial state of\nswdio. The command @command{adapter gpio} prints the current configuration for\nall GPIOs while the command @command{adapter gpio gpio_name} prints the current\nconfiguration for gpio_name. Not all adapters support this generic GPIO mapping,\nsome require their own commands to define the GPIOs used. Adapters that support\nthe generic mapping may not support all of the listed options.\n@end deffn\n\n@deffn {Command} {adapter name}\nReturns the name of the debug adapter driver being used.\n@end deffn\n\n@deffn {Config Command} {adapter usb location} [<bus>-<port>[.<port>]...]\nDisplays or specifies the physical USB port of the adapter to use. The path\nroots at @var{bus} and walks down the physical ports, with each\n@var{port} option specifying a deeper level in the bus topology, the last\n@var{port} denoting where the target adapter is actually plugged.\nThe USB bus topology can be queried with the command @emph{lsusb -t} or @emph{dmesg}.\n\nThis command is only available if your libusb1 is at least version 1.0.16.\n@end deffn\n\n@deffn {Config Command} {adapter serial} serial_string\nSpecifies the @var{serial_string} of the adapter to use.\nIf this command is not specified, serial strings are not checked.\nOnly the following adapter drivers use the serial string from this command:\narm-jtag-ew, cmsis_dap, esp_usb_jtag, ft232r, ftdi, hla (stlink, ti-icdi), jlink, kitprog, opendus,\nopenjtag, osbdm, presto, rlink, st-link, usb_blaster (ublast2), usbprog, vsllink, xds110.\n@end deffn\n\n@section Interface Drivers\n\nEach of the interface drivers listed here must be explicitly\nenabled when OpenOCD is configured, in order to be made\navailable at run time.\n\n@deffn {Interface Driver} {amt_jtagaccel}\nAmontec Chameleon in its JTAG Accelerator configuration,\nconnected to a PC's EPP mode parallel port.\nThis defines some driver-specific commands:\n\n@deffn {Config Command} {parport port} number\nSpecifies either the address of the I/O port (default: 0x378 for LPT1) or\nthe number of the @file{/dev/parport} device.\n@end deffn\n\n@deffn {Config Command} {rtck} [@option{enable}|@option{disable}]\nDisplays status of RTCK option.\nOptionally sets that option first.\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {arm-jtag-ew}\nOlimex ARM-JTAG-EW USB adapter\nThis has one driver-specific command:\n\n@deffn {Command} {armjtagew_info}\nLogs some status\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {at91rm9200}\nSupports bitbanged JTAG from the local system,\npresuming that system is an Atmel AT91rm9200\nand a specific set of GPIOs is used.\n@c command:\tat91rm9200_device NAME\n@c chooses among list of bit configs ... only one option\n@end deffn\n\n@deffn {Interface Driver} {cmsis-dap}\nARM CMSIS-DAP compliant based adapter v1 (USB HID based)\nor v2 (USB bulk).\n\n@deffn {Config Command} {cmsis_dap_vid_pid} [vid pid]+\nThe vendor ID and product ID of the CMSIS-DAP device. If not specified\nthe driver will attempt to auto detect the CMSIS-DAP device.\nCurrently, up to eight [@var{vid}, @var{pid}] pairs may be given, e.g.\n@example\ncmsis_dap_vid_pid 0xc251 0xf001 0x0d28 0x0204\n@end example\n@end deffn\n\n@deffn {Config Command} {cmsis_dap_backend} [@option{auto}|@option{usb_bulk}|@option{hid}]\nSpecifies how to communicate with the adapter:\n\n@itemize @minus\n@item @option{hid} Use HID generic reports - CMSIS-DAP v1\n@item @option{usb_bulk} Use USB bulk - CMSIS-DAP v2\n@item @option{auto} First try USB bulk CMSIS-DAP v2, if not found try HID CMSIS-DAP v1.\nThis is the default if @command{cmsis_dap_backend} is not specified.\n@end itemize\n@end deffn\n\n@deffn {Config Command} {cmsis_dap_usb interface} [number]\nSpecifies the @var{number} of the USB interface to use in v2 mode (USB bulk).\nIn most cases need not to be specified and interfaces are searched by\ninterface string or for user class interface.\n@end deffn\n\n@deffn {Command} {cmsis-dap info}\nDisplay various device information, like hardware version, firmware version, current bus status.\n@end deffn\n\n@deffn {Command} {cmsis-dap cmd} number number ...\nExecute an arbitrary CMSIS-DAP command. Use for adapter testing or for handling\nof an adapter vendor specific command from a Tcl script.\n\nTake given numbers as bytes, assemble a CMSIS-DAP protocol command packet\nfrom them and send it to the adapter. The first 4 bytes of the adapter response\nare logged.\nSee @url{https://arm-software.github.io/CMSIS_5/DAP/html/group__DAP__Commands__gr.html}\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {dummy}\nA dummy software-only driver for debugging.\n@end deffn\n\n@deffn {Interface Driver} {ep93xx}\nCirrus Logic EP93xx based single-board computer bit-banging (in development)\n@end deffn\n\n@deffn {Interface Driver} {ftdi}\nThis driver is for adapters using the MPSSE (Multi-Protocol Synchronous Serial\nEngine) mode built into many FTDI chips, such as the FT2232, FT4232 and FT232H.\n\nThe driver is using libusb-1.0 in asynchronous mode to talk to the FTDI device,\nbypassing intermediate libraries like libftdi.\n\nSupport for new FTDI based adapters can be added completely through\nconfiguration files, without the need to patch and rebuild OpenOCD.\n\nThe driver uses a signal abstraction to enable Tcl configuration files to\ndefine outputs for one or several FTDI GPIO. These outputs can then be\ncontrolled using the @command{ftdi set_signal} command. Special signal names\nare reserved for nTRST, nSRST and LED (for blink) so that they, if defined,\nwill be used for their customary purpose. Inputs can be read using the\n@command{ftdi get_signal} command.\n\nTo support SWD, a signal named SWD_EN must be defined. It is set to 1 when the\nSWD protocol is selected. When set, the adapter should route the SWDIO pin to\nthe data input. An SWDIO_OE signal, if defined, will be set to 1 or 0 as\nrequired by the protocol, to tell the adapter to drive the data output onto\nthe SWDIO pin or keep the SWDIO pin Hi-Z, respectively.\n\nDepending on the type of buffer attached to the FTDI GPIO, the outputs have to\nbe controlled differently. In order to support tristateable signals such as\nnSRST, both a data GPIO and an output-enable GPIO can be specified for each\nsignal. The following output buffer configurations are supported:\n\n@itemize @minus\n@item Push-pull with one FTDI output as (non-)inverted data line\n@item Open drain with one FTDI output as (non-)inverted output-enable\n@item Tristate with one FTDI output as (non-)inverted data line and another\n      FTDI output as (non-)inverted output-enable\n@item Unbuffered, using the FTDI GPIO as a tristate output directly by\n      switching data and direction as necessary\n@end itemize\n\nThese interfaces have several commands, used to configure the driver\nbefore initializing the JTAG scan chain:\n\n@deffn {Config Command} {ftdi vid_pid} [vid pid]+\nThe vendor ID and product ID of the adapter. Up to eight\n[@var{vid}, @var{pid}] pairs may be given, e.g.\n@example\nftdi vid_pid 0x0403 0xcff8 0x15ba 0x0003\n@end example\n@end deffn\n\n@deffn {Config Command} {ftdi device_desc} description\nProvides the USB device description (the @emph{iProduct string})\nof the adapter. If not specified, the device description is ignored\nduring device selection.\n@end deffn\n\n@deffn {Config Command} {ftdi channel} channel\nSelects the channel of the FTDI device to use for MPSSE operations. Most\nadapters use the default, channel 0, but there are exceptions.\n@end deffn\n\n@deffn {Config Command} {ftdi layout_init} data direction\nSpecifies the initial values of the FTDI GPIO data and direction registers.\nEach value is a 16-bit number corresponding to the concatenation of the high\nand low FTDI GPIO registers. The values should be selected based on the\nschematics of the adapter, such that all signals are set to safe levels with\nminimal impact on the target system. Avoid floating inputs, conflicting outputs\nand initially asserted reset signals.\n@end deffn\n\n@deffn {Command} {ftdi layout_signal} name [@option{-data}|@option{-ndata} data_mask] [@option{-input}|@option{-ninput} input_mask] [@option{-oe}|@option{-noe} oe_mask] [@option{-alias}|@option{-nalias} name]\nCreates a signal with the specified @var{name}, controlled by one or more FTDI\nGPIO pins via a range of possible buffer connections. The masks are FTDI GPIO\nregister bitmasks to tell the driver the connection and type of the output\nbuffer driving the respective signal. @var{data_mask} is the bitmask for the\npin(s) connected to the data input of the output buffer. @option{-ndata} is\nused with inverting data inputs and @option{-data} with non-inverting inputs.\nThe @option{-oe} (or @option{-noe}) option tells where the output-enable (or\nnot-output-enable) input to the output buffer is connected. The options\n@option{-input} and @option{-ninput} specify the bitmask for pins to be read\nwith the method @command{ftdi get_signal}.\n\nBoth @var{data_mask} and @var{oe_mask} need not be specified. For example, a\nsimple open-collector transistor driver would be specified with @option{-oe}\nonly. In that case the signal can only be set to drive low or to Hi-Z and the\ndriver will complain if the signal is set to drive high. Which means that if\nit's a reset signal, @command{reset_config} must be specified as\n@option{srst_open_drain}, not @option{srst_push_pull}.\n\nA special case is provided when @option{-data} and @option{-oe} is set to the\nsame bitmask. Then the FTDI pin is considered being connected straight to the\ntarget without any buffer. The FTDI pin is then switched between output and\ninput as necessary to provide the full set of low, high and Hi-Z\ncharacteristics. In all other cases, the pins specified in a signal definition\nare always driven by the FTDI.\n\nIf @option{-alias} or @option{-nalias} is used, the signal is created\nidentical (or with data inverted) to an already specified signal\n@var{name}.\n@end deffn\n\n@deffn {Command} {ftdi set_signal} name @option{0}|@option{1}|@option{z}\nSet a previously defined signal to the specified level.\n@itemize @minus\n@item @option{0}, drive low\n@item @option{1}, drive high\n@item @option{z}, set to high-impedance\n@end itemize\n@end deffn\n\n@deffn {Command} {ftdi get_signal} name\nGet the value of a previously defined signal.\n@end deffn\n\n@deffn {Command} {ftdi tdo_sample_edge} @option{rising}|@option{falling}\nConfigure TCK edge at which the adapter samples the value of the TDO signal\n\nDue to signal propagation delays, sampling TDO on rising TCK can become quite\npeculiar at high JTAG clock speeds. However, FTDI chips offer a possibility to sample\nTDO on falling edge of TCK. With some board/adapter configurations, this may increase\nstability at higher JTAG clocks.\n@itemize @minus\n@item @option{rising}, sample TDO on rising edge of TCK - this is the default\n@item @option{falling}, sample TDO on falling edge of TCK\n@end itemize\n@end deffn\n\nFor example adapter definitions, see the configuration files shipped in the\n@file{interface/ftdi} directory.\n\n@end deffn\n\n@deffn {Interface Driver} {ft232r}\nThis driver is implementing synchronous bitbang mode of an FTDI FT232R,\nFT230X, FT231X and similar USB UART bridge ICs by reusing RS232 signals as GPIO.\nIt currently doesn't support using CBUS pins as GPIO.\n\nList of connections (default physical pin numbers for FT232R in 28-pin SSOP package):\n@itemize @minus\n@item RXD(5) - TDI\n@item TXD(1) - TCK\n@item RTS(3) - TDO\n@item CTS(11) - TMS\n@item DTR(2) - TRST\n@item DCD(10) - SRST\n@end itemize\n\nUser can change default pinout by supplying configuration\ncommands with GPIO numbers or RS232 signal names.\nGPIO numbers correspond to bit numbers in FTDI GPIO register.\nThey differ from physical pin numbers.\nFor details see actual FTDI chip datasheets.\nEvery JTAG line must be configured to unique GPIO number\ndifferent than any other JTAG line, even those lines\nthat are sometimes not used like TRST or SRST.\n\nFT232R\n@itemize @minus\n@item bit 7 - RI\n@item bit 6 - DCD\n@item bit 5 - DSR\n@item bit 4 - DTR\n@item bit 3 - CTS\n@item bit 2 - RTS\n@item bit 1 - RXD\n@item bit 0 - TXD\n@end itemize\n\nThese interfaces have several commands, used to configure the driver\nbefore initializing the JTAG scan chain:\n\n@deffn {Config Command} {ft232r vid_pid} @var{vid} @var{pid}\nThe vendor ID and product ID of the adapter. If not specified, default\n0x0403:0x6001 is used.\n@end deffn\n\n@deffn {Config Command} {ft232r jtag_nums} @var{tck} @var{tms} @var{tdi} @var{tdo}\nSet four JTAG GPIO numbers at once.\nIf not specified, default 0 3 1 2 or TXD CTS RXD RTS is used.\n@end deffn\n\n@deffn {Config Command} {ft232r tck_num} @var{tck}\nSet TCK GPIO number. If not specified, default 0 or TXD is used.\n@end deffn\n\n@deffn {Config Command} {ft232r tms_num} @var{tms}\nSet TMS GPIO number. If not specified, default 3 or CTS is used.\n@end deffn\n\n@deffn {Config Command} {ft232r tdi_num} @var{tdi}\nSet TDI GPIO number. If not specified, default 1 or RXD is used.\n@end deffn\n\n@deffn {Config Command} {ft232r tdo_num} @var{tdo}\nSet TDO GPIO number. If not specified, default 2 or RTS is used.\n@end deffn\n\n@deffn {Config Command} {ft232r trst_num} @var{trst}\nSet TRST GPIO number. If not specified, default 4 or DTR is used.\n@end deffn\n\n@deffn {Config Command} {ft232r srst_num} @var{srst}\nSet SRST GPIO number. If not specified, default 6 or DCD is used.\n@end deffn\n\n@deffn {Config Command} {ft232r restore_serial} @var{word}\nRestore serial port after JTAG. This USB bitmode control word\n(16-bit) will be sent before quit. Lower byte should\nset GPIO direction register to a \"sane\" state:\n0x15 for TXD RTS DTR as outputs (1), others as inputs (0). Higher\nbyte is usually 0 to disable bitbang mode.\nWhen kernel driver reattaches, serial port should continue to work.\nValue 0xFFFF disables sending control word and serial port,\nthen kernel driver will not reattach.\nIf not specified, default 0xFFFF is used.\n@end deffn\n\n@end deffn\n\n@deffn {Interface Driver} {remote_bitbang}\nDrive JTAG from a remote process. This sets up a UNIX or TCP socket connection\nwith a remote process and sends ASCII encoded bitbang requests to that process\ninstead of directly driving JTAG.\n\nThe remote_bitbang driver is useful for debugging software running on\nprocessors which are being simulated.\n\n@deffn {Config Command} {remote_bitbang port} number\nSpecifies the TCP port of the remote process to connect to or 0 to use UNIX\nsockets instead of TCP.\n@end deffn\n\n@deffn {Config Command} {remote_bitbang host} hostname\nSpecifies the hostname of the remote process to connect to using TCP, or the\nname of the UNIX socket to use if remote_bitbang port is 0.\n@end deffn\n\nFor example, to connect remotely via TCP to the host foobar you might have\nsomething like:\n\n@example\nadapter driver remote_bitbang\nremote_bitbang port 3335\nremote_bitbang host foobar\n@end example\n\nTo connect to another process running locally via UNIX sockets with socket\nnamed mysocket:\n\n@example\nadapter driver remote_bitbang\nremote_bitbang port 0\nremote_bitbang host mysocket\n@end example\n@end deffn\n\n@deffn {Interface Driver} {usb_blaster}\nUSB JTAG/USB-Blaster compatibles over one of the userspace libraries\nfor FTDI chips. These interfaces have several commands, used to\nconfigure the driver before initializing the JTAG scan chain:\n\n@deffn {Config Command} {usb_blaster vid_pid} vid pid\nThe vendor ID and product ID of the FTDI FT245 device. If not specified,\ndefault values are used.\nCurrently, only one @var{vid}, @var{pid} pair may be given, e.g. for\nAltera USB-Blaster (default):\n@example\nusb_blaster vid_pid 0x09FB 0x6001\n@end example\nThe following VID/PID is for Kolja Waschk's USB JTAG:\n@example\nusb_blaster vid_pid 0x16C0 0x06AD\n@end example\n@end deffn\n\n@deffn {Command} {usb_blaster pin} (@option{pin6}|@option{pin8}) (@option{0}|@option{1}|@option{s}|@option{t})\nSets the state or function of the unused GPIO pins on USB-Blasters\n(pins 6 and 8 on the female JTAG header). These pins can be used as\nSRST and/or TRST provided the appropriate connections are made on the\ntarget board.\n\nFor example, to use pin 6 as SRST:\n@example\nusb_blaster pin pin6 s\nreset_config srst_only\n@end example\n@end deffn\n\n@deffn {Config Command} {usb_blaster lowlevel_driver} (@option{ftdi}|@option{ublast2})\nChooses the low level access method for the adapter. If not specified,\n@option{ftdi} is selected unless it wasn't enabled during the\nconfigure stage. USB-Blaster II needs @option{ublast2}.\n@end deffn\n\n@deffn {Config Command} {usb_blaster firmware} @var{path}\nThis command specifies @var{path} to access USB-Blaster II firmware\nimage. To be used with USB-Blaster II only.\n@end deffn\n\n@end deffn\n\n@deffn {Interface Driver} {gw16012}\nGateworks GW16012 JTAG programmer.\nThis has one driver-specific command:\n\n@deffn {Config Command} {parport port} [port_number]\nDisplay either the address of the I/O port\n(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device.\nIf a parameter is provided, first switch to use that port.\nThis is a write-once setting.\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {jlink}\nSEGGER J-Link family of USB adapters. It currently supports JTAG and SWD\ntransports.\n\n@quotation Compatibility Note\nSEGGER released many firmware versions for the many hardware versions they\nproduced. OpenOCD was extensively tested and intended to run on all of them,\nbut some combinations were reported as incompatible. As a general\nrecommendation, it is advisable to use the latest firmware version\navailable for each hardware version. However the current V8 is a moving\ntarget, and SEGGER firmware versions released after the OpenOCD was\nreleased may not be compatible. In such cases it is recommended to\nrevert to the last known functional version. For 0.5.0, this is from\n\"Feb  8 2012 14:30:39\", packed with 4.42c. For 0.6.0, the last known\nversion is from \"May  3 2012 18:36:22\", packed with 4.46f.\n@end quotation\n\n@deffn {Command} {jlink hwstatus}\nDisplay various hardware related information, for example target voltage and pin\nstates.\n@end deffn\n@deffn {Command} {jlink freemem}\nDisplay free device internal memory.\n@end deffn\n@deffn {Command} {jlink jtag} [@option{2}|@option{3}]\nSet the JTAG command version to be used. Without argument, show the actual JTAG\ncommand version.\n@end deffn\n@deffn {Command} {jlink config}\nDisplay the device configuration.\n@end deffn\n@deffn {Command} {jlink config targetpower} [@option{on}|@option{off}]\nSet the target power state on JTAG-pin 19. Without argument, show the target\npower state.\n@end deffn\n@deffn {Command} {jlink config mac} [@option{ff:ff:ff:ff:ff:ff}]\nSet the MAC address of the device. Without argument, show the MAC address.\n@end deffn\n@deffn {Command} {jlink config ip} [@option{A.B.C.D}(@option{/E}|@option{F.G.H.I})]\nSet the IP configuration of the device, where A.B.C.D is the IP address, E the\nbit of the subnet mask and F.G.H.I the subnet mask. Without arguments, show the\nIP configuration.\n@end deffn\n@deffn {Command} {jlink config usb} [@option{0} to @option{3}]\nSet the USB address of the device. This will also change the USB Product ID\n(PID) of the device. Without argument, show the USB address.\n@end deffn\n@deffn {Command} {jlink config reset}\nReset the current configuration.\n@end deffn\n@deffn {Command} {jlink config write}\nWrite the current configuration to the internal persistent storage.\n@end deffn\n@deffn {Command} {jlink emucom write} <channel> <data>\nWrite data to an EMUCOM channel. The data needs to be encoded as hexadecimal\npairs.\n\nThe following example shows how to write the three bytes 0xaa, 0x0b and 0x23 to\nthe EMUCOM channel 0x10:\n@example\n> jlink emucom write 0x10 aa0b23\n@end example\n@end deffn\n@deffn {Command} {jlink emucom read} <channel> <length>\nRead data from an EMUCOM channel. The read data is encoded as hexadecimal\npairs.\n\nThe following example shows how to read 4 bytes from the EMUCOM channel 0x0:\n@example\n> jlink emucom read 0x0 4\n77a90000\n@end example\n@end deffn\n@deffn {Config Command} {jlink usb} <@option{0} to @option{3}>\nSet the USB address of the interface, in case more than one adapter is connected\nto the host. If not specified, USB addresses are not considered. Device\nselection via USB address is not always unambiguous. It is recommended to use\nthe serial number instead, if possible.\n\nAs a configuration command, it can be used only before 'init'.\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {kitprog}\nThis driver is for Cypress Semiconductor's KitProg adapters. The KitProg is an\nSWD-only adapter that is designed to be used with Cypress's PSoC and PRoC device\nfamilies, but it is possible to use it with some other devices. If you are using\nthis adapter with a PSoC or a PRoC, you may need to add\n@command{kitprog_init_acquire_psoc} or @command{kitprog acquire_psoc} to your\nconfiguration script.\n\nNote that this driver is for the proprietary KitProg protocol, not the CMSIS-DAP\nmode introduced in firmware 2.14. If the KitProg is in CMSIS-DAP mode, it cannot\nbe used with this driver, and must either be used with the cmsis-dap driver or\nswitched back to KitProg mode. See the Cypress KitProg User Guide for\ninstructions on how to switch KitProg modes.\n\nKnown limitations:\n@itemize @bullet\n@item The frequency of SWCLK cannot be configured, and varies between 1.6 MHz\nand 2.7 MHz.\n@item For firmware versions below 2.14, \"JTAG to SWD\" sequences are replaced by\n\"SWD line reset\" in the driver. This is for two reasons. First, the KitProg does\nnot support sending arbitrary SWD sequences, and only firmware 2.14 and later\nimplement both \"JTAG to SWD\" and \"SWD line reset\" in firmware. Earlier firmware\nversions only implement \"SWD line reset\". Second, due to a firmware quirk, an\nSWD sequence must be sent after every target reset in order to re-establish\ncommunications with the target.\n@item Due in part to the limitation above, KitProg devices with firmware below\nversion 2.14 will need to use @command{kitprog_init_acquire_psoc} in order to\ncommunicate with PSoC 5LP devices. This is because, assuming debug is not\ndisabled on the PSoC, the PSoC 5LP needs its JTAG interface switched to SWD\nmode before communication can begin, but prior to firmware 2.14, \"JTAG to SWD\"\ncould only be sent with an acquisition sequence.\n@end itemize\n\n@deffn {Config Command} {kitprog_init_acquire_psoc}\nIndicate that a PSoC acquisition sequence needs to be run during adapter init.\nPlease be aware that the acquisition sequence hard-resets the target.\n@end deffn\n\n@deffn {Command} {kitprog acquire_psoc}\nRun a PSoC acquisition sequence immediately. Typically, this should not be used\noutside of the target-specific configuration scripts since it hard-resets the\ntarget as a side-effect.\nThis is necessary for \"reset halt\" on some PSoC 4 series devices.\n@end deffn\n\n@deffn {Command} {kitprog info}\nDisplay various adapter information, such as the hardware version, firmware\nversion, and target voltage.\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {parport}\nSupports PC parallel port bit-banging cables:\nWigglers, PLD download cable, and more.\nThese interfaces have several commands, used to configure the driver\nbefore initializing the JTAG scan chain:\n\n@deffn {Config Command} {parport cable} name\nSet the layout of the parallel port cable used to connect to the target.\nThis is a write-once setting.\nCurrently valid cable @var{name} values include:\n\n@itemize @minus\n@item @b{altium} Altium Universal JTAG cable.\n@item @b{arm-jtag} Same as original wiggler except SRST and\nTRST connections reversed and TRST is also inverted.\n@item @b{chameleon} The Amontec Chameleon's CPLD when operated\nin configuration mode. This is only used to\nprogram the Chameleon itself, not a connected target.\n@item @b{dlc5} The Xilinx Parallel cable III.\n@item @b{flashlink} The ST Parallel cable.\n@item @b{lattice} Lattice ispDOWNLOAD Cable\n@item @b{old_amt_wiggler} The Wiggler configuration that comes with\nsome versions of\nAmontec's Chameleon Programmer. The new version available from\nthe website uses the original Wiggler layout ('@var{wiggler}')\n@item @b{triton} The parallel port adapter found on the\n``Karo Triton 1 Development Board''.\nThis is also the layout used by the HollyGates design\n(see @uref{http://www.lartmaker.nl/projects/jtag/}).\n@item @b{wiggler} The original Wiggler layout, also supported by\nseveral clones, such as the Olimex ARM-JTAG\n@item @b{wiggler2} Same as original wiggler except an led is fitted on D5.\n@item @b{wiggler_ntrst_inverted} Same as original wiggler except TRST is inverted.\n@end itemize\n@end deffn\n\n@deffn {Config Command} {parport port} [port_number]\nDisplay either the address of the I/O port\n(default: 0x378 for LPT1) or the number of the @file{/dev/parport} device.\nIf a parameter is provided, first switch to use that port.\nThis is a write-once setting.\n\nWhen using PPDEV to access the parallel port, use the number of the parallel port:\n@option{parport port 0} (the default). If @option{parport port 0x378} is specified\nyou may encounter a problem.\n@end deffn\n\n@deffn {Config Command} {parport toggling_time} [nanoseconds]\nDisplays how many nanoseconds the hardware needs to toggle TCK;\nthe parport driver uses this value to obey the\n@command{adapter speed} configuration.\nWhen the optional @var{nanoseconds} parameter is given,\nthat setting is changed before displaying the current value.\n\nThe default setting should work reasonably well on commodity PC hardware.\nHowever, you may want to calibrate for your specific hardware.\n@quotation Tip\nTo measure the toggling time with a logic analyzer or a digital storage\noscilloscope, follow the procedure below:\n@example\n> parport toggling_time 1000\n> adapter speed 500\n@end example\nThis sets the maximum JTAG clock speed of the hardware, but\nthe actual speed probably deviates from the requested 500 kHz.\nNow, measure the time between the two closest spaced TCK transitions.\nYou can use @command{runtest 1000} or something similar to generate a\nlarge set of samples.\nUpdate the setting to match your measurement:\n@example\n> parport toggling_time <measured nanoseconds>\n@end example\nNow the clock speed will be a better match for @command{adapter speed}\ncommand given in OpenOCD scripts and event handlers.\n\nYou can do something similar with many digital multimeters, but note\nthat you'll probably need to run the clock continuously for several\nseconds before it decides what clock rate to show. Adjust the\ntoggling time up or down until the measured clock rate is a good\nmatch with the rate you specified in the @command{adapter speed} command;\nbe conservative.\n@end quotation\n@end deffn\n\n@deffn {Config Command} {parport write_on_exit} (@option{on}|@option{off})\nThis will configure the parallel driver to write a known\ncable-specific value to the parallel interface on exiting OpenOCD.\n@end deffn\n\nFor example, the interface configuration file for a\nclassic ``Wiggler'' cable on LPT2 might look something like this:\n\n@example\nadapter driver parport\nparport port 0x278\nparport cable wiggler\n@end example\n@end deffn\n\n@deffn {Interface Driver} {presto}\nASIX PRESTO USB JTAG programmer.\n@end deffn\n\n@deffn {Interface Driver} {rlink}\nRaisonance RLink USB adapter\n@end deffn\n\n@deffn {Interface Driver} {usbprog}\nusbprog is a freely programmable USB adapter.\n@end deffn\n\n@deffn {Interface Driver} {vsllink}\nvsllink is part of Versaloon which is a versatile USB programmer.\n\n@quotation Note\nThis defines quite a few driver-specific commands,\nwhich are not currently documented here.\n@end quotation\n@end deffn\n\n@anchor{hla_interface}\n@deffn {Interface Driver} {hla}\nThis is a driver that supports multiple High Level Adapters.\nThis type of adapter does not expose some of the lower level api's\nthat OpenOCD would normally use to access the target.\n\nCurrently supported adapters include the STMicroelectronics ST-LINK, TI ICDI\nand Nuvoton Nu-Link.\nST-LINK firmware version >= V2.J21.S4 recommended due to issues with earlier\nversions of firmware where serial number is reset after first use.  Suggest\nusing ST firmware update utility to upgrade ST-LINK firmware even if current\nversion reported is V2.J21.S4.\n\n@deffn {Config Command} {hla_device_desc} description\nCurrently Not Supported.\n@end deffn\n\n@deffn {Config Command} {hla_layout} (@option{stlink}|@option{icdi}|@option{nulink})\nSpecifies the adapter layout to use.\n@end deffn\n\n@deffn {Config Command} {hla_vid_pid} [vid pid]+\nPairs of vendor IDs and product IDs of the device.\n@end deffn\n\n@deffn {Config Command} {hla_stlink_backend} (usb | tcp [port])\n@emph{ST-Link only:} Choose between 'exclusive' USB communication (the default backend) or\n'shared' mode using ST-Link TCP server (the default port is 7184).\n\n@emph{Note:} ST-Link TCP server is a binary application provided by ST\navailable from @url{https://www.st.com/en/development-tools/st-link-server.html,\nST-LINK server software module}.\n@end deffn\n\n@deffn {Command} {hla_command} command\nExecute a custom adapter-specific command. The @var{command} string is\npassed as is to the underlying adapter layout handler.\n@end deffn\n@end deffn\n\n@anchor{st_link_dap_interface}\n@deffn {Interface Driver} {st-link}\nThis is a driver that supports STMicroelectronics adapters ST-LINK/V2\n(from firmware V2J24), STLINK-V3 and STLINK-V3PWR, thanks to a new API that provides\ndirectly access the arm ADIv5 DAP.\n\nThe new API provide access to multiple AP on the same DAP, but the\nmaximum number of the AP port is limited by the specific firmware version\n(e.g. firmware V2J29 has 3 as maximum AP number, while V2J32 has 8).\nAn error is returned for any AP number above the maximum allowed value.\n\n@emph{Note:} Either these same adapters and their older versions are\nalso supported by @ref{hla_interface, the hla interface driver}.\n\n@deffn {Config Command} {st-link backend} (usb | tcp [port])\nChoose between 'exclusive' USB communication (the default backend) or\n'shared' mode using ST-Link TCP server (the default port is 7184).\n\n@emph{Note:} ST-Link TCP server is a binary application provided by ST\navailable from @url{https://www.st.com/en/development-tools/st-link-server.html,\nST-LINK server software module}.\n\n@emph{Note:} ST-Link TCP server does not support the SWIM transport.\n@end deffn\n\n@deffn {Config Command} {st-link vid_pid} [vid pid]+\nPairs of vendor IDs and product IDs of the device.\n@end deffn\n\n@deffn {Command} {st-link cmd} rx_n (tx_byte)+\nSends an arbitrary command composed by the sequence of bytes @var{tx_byte}\nand receives @var{rx_n} bytes.\n\nFor example, the command to read the target's supply voltage is one byte 0xf7 followed\nby 15 bytes zero. It returns 8 bytes, where the first 4 bytes represent the ADC sampling\nof the reference voltage 1.2V and the last 4 bytes represent the ADC sampling of half\nthe target's supply voltage.\n@example\n> st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\n0xf1 0x05 0x00 0x00 0x0b 0x08 0x00 0x00\n@end example\nThe result can be converted to Volts (ignoring the most significant bytes, always zero)\n@example\n> set a [st-link cmd 8 0xf7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]\n> set n [expr @{[lindex $a 4] + 256 * [lindex $a 5]@}]\n> set d [expr @{[lindex $a 0] + 256 * [lindex $a 1]@}]\n> echo [expr @{2 * 1.2 * $n / $d@}]\n3.24891518738\n@end example\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {opendous}\nopendous-jtag is a freely programmable USB adapter.\n@end deffn\n\n@deffn {Interface Driver} {ulink}\nThis is the Keil ULINK v1 JTAG debugger.\n@end deffn\n\n@deffn {Interface Driver} {xds110}\nThe XDS110 is included as the embedded debug probe on many Texas Instruments\nLaunchPad evaluation boards. The XDS110 is also available as a stand-alone USB\ndebug probe with the added capability to supply power to the target board. The\nfollowing commands are supported by the XDS110 driver:\n\n@deffn {Config Command} {xds110 supply} voltage_in_millivolts\nAvailable only on the XDS110 stand-alone probe. Sets the voltage level of the\nXDS110 power supply. A value of 0 leaves the supply off. Otherwise, the supply\ncan be set to any value in the range 1800 to 3600 millivolts.\n@end deffn\n\n@deffn {Command} {xds110 info}\nDisplays information about the connected XDS110 debug probe (e.g. firmware\nversion).\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {xlnx_pcie_xvc}\nThis driver supports the Xilinx Virtual Cable (XVC) over PCI Express.\nIt is commonly found in Xilinx based PCI Express designs. It allows debugging\nfabric based JTAG/SWD devices such as Cortex-M1/M3 microcontrollers. Access to this is\nexposed via extended capability registers in the PCI Express configuration space.\n\nFor more information see Xilinx PG245 (Section on From_PCIE_to_JTAG mode).\n\n@deffn {Config Command} {xlnx_pcie_xvc config} device\nSpecifies the PCI Express device via parameter @var{device} to use.\n\nThe correct value for @var{device} can be obtained by looking at the output\nof lscpi -D (first column) for the corresponding device.\n\nThe string will be of the format \"DDDD:BB:SS.F\" such as \"0000:65:00.1\".\n\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {bcm2835gpio}\nThis SoC is present in Raspberry Pi which is a cheap single-board computer\nexposing some GPIOs on its expansion header.\n\nThe driver accesses memory-mapped GPIO peripheral registers directly\nfor maximum performance, but the only possible race condition is for\nthe pins' modes/muxing (which is highly unlikely), so it should be\nable to coexist nicely with both sysfs bitbanging and various\nperipherals' kernel drivers. The driver restores the previous\nconfiguration on exit.\n\nGPIO numbers >= 32 can't be used for performance reasons. GPIO configuration is\nhandled by the generic command @ref{adapter gpio, @command{adapter gpio}}.\n\nSee @file{interface/raspberrypi-native.cfg} for a sample config and\n@file{interface/raspberrypi-gpio-connector.cfg} for pinout.\n\n@deffn {Config Command} {bcm2835gpio speed_coeffs} @var{speed_coeff} @var{speed_offset}\nSet SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified,\nspeed_coeff defaults to 113714, and speed_offset defaults to 28.\n@end deffn\n\n@deffn {Config Command} {bcm2835gpio peripheral_mem_dev} @var{device}\nSet the device path for access to the memory mapped GPIO control registers.\nUses @file{/dev/gpiomem} by default, this is also the preferred option with\nrespect to system security.\nIf overridden to @file{/dev/mem}:\n@itemize @minus\n@item OpenOCD needs @code{cap_sys_rawio} or run as root to open @file{/dev/mem}.\nPlease be aware of security issues imposed by running OpenOCD with\nelevated user rights and by @file{/dev/mem} itself.\n@item correct @command{peripheral_base} must be configured.\n@item GPIO 0-27 pads are set to the limited slew rate\nand drive strength is reduced to 4 mA (2 mA on RPi 4).\n@end itemize\n\n@end deffn\n\n@deffn {Config Command} {bcm2835gpio peripheral_base} @var{base}\nSet the peripheral base register address to access GPIOs.\nIgnored if @file{/dev/gpiomem} is used. For the RPi1, use\n0x20000000. For RPi2 and RPi3, use 0x3F000000. For RPi4, use 0xFE000000. A full\nlist can be found in the\n@uref{https://www.raspberrypi.org/documentation/hardware/raspberrypi/peripheral_addresses.md, official guide}.\n@end deffn\n\n@end deffn\n\n@deffn {Interface Driver} {imx_gpio}\ni.MX SoC is present in many community boards. Wandboard is an example\nof the one which is most popular.\n\nThis driver is mostly the same as bcm2835gpio.\n\nSee @file{interface/imx-native.cfg} for a sample config and\npinout.\n\n@end deffn\n\n\n@deffn {Interface Driver} {am335xgpio} The AM335x SoC is present in BeagleBone\nBlack and BeagleBone Green single-board computers which expose some of the GPIOs\non the two expansion headers.\n\nFor maximum performance the driver accesses memory-mapped GPIO peripheral\nregisters directly. The memory mapping requires read and write permission to\nkernel memory; if /dev/gpiomem exists it will be used, otherwise /dev/mem will\nbe used. The driver restores the GPIO state on exit.\n\nAll four GPIO ports are available. GPIO configuration is handled by the generic\ncommand @ref{adapter gpio, @command{adapter gpio}}.\n\n@deffn {Config Command} {am335xgpio speed_coeffs} @var{speed_coeff} @var{speed_offset}\nSet SPEED_COEFF and SPEED_OFFSET for delay calculations. If unspecified\nspeed_coeff defaults to 600000 and speed_offset defaults to 575.\n@end deffn\n\nSee @file{interface/beaglebone-swd-native.cfg} for a sample configuration file.\n\n@end deffn\n\n\n@deffn {Interface Driver} {linuxgpiod}\nLinux provides userspace access to GPIO through libgpiod since Linux kernel\nversion v4.6. The driver emulates either JTAG or SWD transport through\nbitbanging. There are no driver-specific commands, all GPIO configuration is\nhandled by the generic command @ref{adapter gpio, @command{adapter gpio}}. This\ndriver supports the resistor pull options provided by the @command{adapter gpio}\ncommand but the underlying hardware may not be able to support them.\n\nSee @file{interface/dln-2-gpiod.cfg} for a sample configuration file.\n@end deffn\n\n\n@deffn {Interface Driver} {sysfsgpio}\nLinux legacy userspace access to GPIO through sysfs is deprecated from Linux kernel version v5.3.\nPrefer using @b{linuxgpiod}, instead.\n\nSee @file{interface/sysfsgpio-raspberrypi.cfg} for a sample config.\n@end deffn\n\n\n@deffn {Interface Driver} {openjtag}\nOpenJTAG compatible USB adapter.\nThis defines some driver-specific commands:\n\n@deffn {Config Command} {openjtag variant} variant\nSpecifies the variant of the OpenJTAG adapter (see @uref{http://www.openjtag.org/}).\nCurrently valid @var{variant} values include:\n\n@itemize @minus\n@item @b{standard} Standard variant (default).\n@item @b{cy7c65215} Cypress CY7C65215 Dual Channel USB-Serial Bridge Controller\n(see @uref{http://www.cypress.com/?rID=82870}).\n@end itemize\n@end deffn\n\n@deffn {Config Command} {openjtag device_desc} string\nThe USB device description string of the adapter.\nThis value is only used with the standard variant.\n@end deffn\n@end deffn\n\n\n@deffn {Interface Driver} {vdebug}\nCadence Virtual Debug Interface driver.\n\n@deffn {Config Command} {vdebug server} host:port\nSpecifies the host and TCP port number where the vdebug server runs.\n@end deffn\n\n@deffn {Config Command} {vdebug batching} value\nSpecifies the batching method for the vdebug request. Possible values are\n0 for no batching\n1 or wr to batch write transactions together (default)\n2 or rw to batch both read and write transactions\n@end deffn\n\n@deffn {Config Command} {vdebug polling} min max\nTakes two values, representing the polling interval in ms. Lower values mean faster\ndebugger responsiveness, but lower emulation performance. The minimum should be\naround 10, maximum should not exceed 1000, which is the default gdb and keepalive\ntimeout value.\n@end deffn\n\n@deffn {Config Command} {vdebug bfm_path} path clk_period\nSpecifies the hierarchical path and input clk period of the vdebug BFM in the design.\nThe hierarchical path uses Verilog notation top.inst.inst\nThe clock period must include the unit, for instance 40ns.\n@end deffn\n\n@deffn {Config Command} {vdebug mem_path} path base size\nSpecifies the hierarchical path to the design memory instance for backdoor access.\nUp to 4 memories can be specified. The hierarchical path uses Verilog notation.\nThe base specifies start address in the design address space, size its size in bytes.\nBoth values can use hexadecimal notation with prefix 0x.\n@end deffn\n@end deffn\n\n@deffn {Interface Driver} {jtag_dpi}\nSystemVerilog Direct Programming Interface (DPI) compatible driver for\nJTAG devices in emulation. The driver acts as a client for the SystemVerilog\nDPI server interface.\n\n@deffn {Config Command} {jtag_dpi set_port} port\nSpecifies the TCP/IP port number of the SystemVerilog DPI server interface.\n@end deffn\n\n@deffn {Config Command} {jtag_dpi set_address} address\nSpecifies the TCP/IP address of the SystemVerilog DPI server interface.\n@end deffn\n@end deffn\n\n\n@deffn {Interface Driver} {buspirate}\n\nThis driver is for the Bus Pirate (see @url{http://dangerousprototypes.com/docs/Bus_Pirate}) and compatible devices.\nIt uses a simple data protocol over a serial port connection.\n\nMost hardware development boards have a UART, a real serial port, or a virtual USB serial device, so this driver\nallows you to start building your own JTAG adapter without the complexity of a custom USB connection.\n\n@deffn {Config Command} {buspirate port} serial_port\nSpecify the serial port's filename. For example:\n@example\nbuspirate port /dev/ttyUSB0\n@end example\n@end deffn\n\n@deffn {Config Command} {buspirate speed} (normal|fast)\nSet the communication speed to 115k (normal) or 1M (fast). For example:\n@example\nbuspirate speed normal\n@end example\n@end deffn\n\n@deffn {Config Command} {buspirate mode} (normal|open-drain)\nSet the Bus Pirate output mode.\n@itemize @minus\n@item In normal mode (push/pull), do not enable the pull-ups, and do not connect I/O header pin VPU to JTAG VREF.\n@item In open drain mode, you will then need to enable the pull-ups.\n@end itemize\nFor example:\n@example\nbuspirate mode normal\n@end example\n@end deffn\n\n@deffn {Config Command} {buspirate pullup} (0|1)\nWhether to connect (1) or not (0) the I/O header pin VPU (JTAG VREF)\nto the pull-up/pull-down resistors on MOSI (JTAG TDI), CLK (JTAG TCK), MISO (JTAG TDO) and CS (JTAG TMS).\nFor example:\n@example\nbuspirate pullup 0\n@end example\n@end deffn\n\n@deffn {Config Command} {buspirate vreg} (0|1)\nWhether to enable (1) or disable (0) the built-in voltage regulator,\nwhich can be used to supply power to a test circuit through\nI/O header pins +3V3 and +5V. For example:\n@example\nbuspirate vreg 0\n@end example\n@end deffn\n\n@deffn {Command} {buspirate led} (0|1)\nTurns the Bus Pirate's LED on (1) or off (0). For example:\n@end deffn\n@example\nbuspirate led 1\n@end example\n\n@end deffn\n\n@deffn {Interface Driver} {esp_usb_jtag}\nEspressif JTAG driver to communicate with ESP32-C3, ESP32-S3 chips and ESP USB Bridge board using OpenOCD.\nThese chips have built-in JTAG circuitry and can be debugged without any additional hardware.\nOnly an USB cable connected to the D+/D- pins is necessary.\n\n@deffn {Command} {espusbjtag tdo}\nReturns the current state of the TDO line\n@end deffn\n\n@deffn {Command} {espusbjtag setio} setio\nManually set the status of the output lines with the order of (tdi tms tck trst srst)\n@example\nespusbjtag setio 0 1 0 1 0\n@end example\n@end deffn\n\n@deffn {Config Command} {espusbjtag vid_pid} vid_pid\nSet vendor ID and product ID for the ESP usb jtag driver\n@example\nespusbjtag vid_pid 0x303a 0x1001\n@end example\n@end deffn\n\n@deffn {Config Command} {espusbjtag caps_descriptor} caps_descriptor\nSet the jtag descriptor to read capabilities of ESP usb jtag driver\n@example\nespusbjtag caps_descriptor 0x2000\n@end example\n@end deffn\n\n@deffn {Config Command} {espusbjtag chip_id} chip_id\nSet chip id to transfer to the ESP USB bridge board\n@example\nespusbjtag chip_id 1\n@end example\n@end deffn\n\n@end deffn\n\n@section Transport Configuration\n@cindex Transport\nAs noted earlier, depending on the version of OpenOCD you use,\nand the debug adapter you are using,\nseveral transports may be available to\ncommunicate with debug targets (or perhaps to program flash memory).\n@deffn {Command} {transport list}\ndisplays the names of the transports supported by this\nversion of OpenOCD.\n@end deffn\n\n@deffn {Command} {transport select} @option{transport_name}\nSelect which of the supported transports to use in this OpenOCD session.\n\nWhen invoked with @option{transport_name}, attempts to select the named\ntransport.  The transport must be supported by the debug adapter\nhardware and by the version of OpenOCD you are using (including the\nadapter's driver).\n\nIf no transport has been selected and no @option{transport_name} is\nprovided, @command{transport select} auto-selects the first transport\nsupported by the debug adapter.\n\n@command{transport select} always returns the name of the session's selected\ntransport, if any.\n@end deffn\n\n@subsection JTAG Transport\n@cindex JTAG\nJTAG is the original transport supported by OpenOCD, and most\nof the OpenOCD commands support it.\nJTAG transports expose a chain of one or more Test Access Points (TAPs),\neach of which must be explicitly declared.\nJTAG supports both debugging and boundary scan testing.\nFlash programming support is built on top of debug support.\n\nJTAG transport is selected with the command @command{transport select\njtag}. Unless your adapter uses either @ref{hla_interface,the hla interface\ndriver} (in which case the command is @command{transport select hla_jtag})\nor @ref{st_link_dap_interface,the st-link interface driver} (in which case\nthe command is @command{transport select dapdirect_jtag}).\n\n@subsection SWD Transport\n@cindex SWD\n@cindex Serial Wire Debug\nSWD (Serial Wire Debug) is an ARM-specific transport which exposes one\nDebug Access Point (DAP, which must be explicitly declared.\n(SWD uses fewer signal wires than JTAG.)\nSWD is debug-oriented, and does not support boundary scan testing.\nFlash programming support is built on top of debug support.\n(Some processors support both JTAG and SWD.)\n\nSWD transport is selected with the command @command{transport select\nswd}. Unless your adapter uses either @ref{hla_interface,the hla interface\ndriver} (in which case the command is @command{transport select hla_swd})\nor @ref{st_link_dap_interface,the st-link interface driver} (in which case\nthe command is @command{transport select dapdirect_swd}).\n\n@deffn {Config Command} {swd newdap} ...\nDeclares a single DAP which uses SWD transport.\nParameters are currently the same as \"jtag newtap\" but this is\nexpected to change.\n@end deffn\n\n@cindex SWD multi-drop\nThe newer SWD devices (SW-DP v2 or SWJ-DP v2) support the multi-drop extension\nof SWD protocol: two or more devices can be connected to one SWD adapter.\nSWD transport works in multi-drop mode if @ref{dap_create,DAP} is configured\nwith both @code{-dp-id} and @code{-instance-id} parameters regardless how many\nDAPs are created.\n\nNot all adapters and adapter drivers support SWD multi-drop. Only the following\nadapter drivers are SWD multi-drop capable:\ncmsis_dap (use an adapter with CMSIS-DAP version 2.0), ftdi, all bitbang based.\n\n@subsection SPI Transport\n@cindex SPI\n@cindex Serial Peripheral Interface\nThe Serial Peripheral Interface (SPI) is a general purpose transport\nwhich uses four wire signaling. Some processors use it as part of a\nsolution for flash programming.\n\n@anchor{swimtransport}\n@subsection SWIM Transport\n@cindex SWIM\n@cindex Single Wire Interface Module\nThe Single Wire Interface Module (SWIM) is a low-pin-count debug protocol used\nby the STMicroelectronics MCU family STM8 and documented in the\n@uref{https://www.st.com/resource/en/user_manual/cd00173911.pdf, User Manual UM470}.\n\nSWIM does not support boundary scan testing nor multiple cores.\n\nThe SWIM transport is selected with the command @command{transport select swim}.\n\nThe concept of TAPs does not fit in the protocol since SWIM does not implement\na scan chain. Nevertheless, the current SW model of OpenOCD requires defining a\nvirtual SWIM TAP through the command @command{swim newtap basename tap_type}.\nThe TAP definition must precede the target definition command\n@command{target create target_name stm8 -chain-position basename.tap_type}.\n\n@anchor{jtagspeed}\n@section JTAG Speed\nJTAG clock setup is part of system setup.\nIt @emph{does not belong with interface setup} since any interface\nonly knows a few of the constraints for the JTAG clock speed.\nSometimes the JTAG speed is\nchanged during the target initialization process: (1) slow at\nreset, (2) program the CPU clocks, (3) run fast.\nBoth the \"slow\" and \"fast\" clock rates are functions of the\noscillators used, the chip, the board design, and sometimes\npower management software that may be active.\n\nThe speed used during reset, and the scan chain verification which\nfollows reset, can be adjusted using a @code{reset-start}\ntarget event handler.\nIt can then be reconfigured to a faster speed by a\n@code{reset-init} target event handler after it reprograms those\nCPU clocks, or manually (if something else, such as a boot loader,\nsets up those clocks).\n@xref{targetevents,,Target Events}.\nWhen the initial low JTAG speed is a chip characteristic, perhaps\nbecause of a required oscillator speed, provide such a handler\nin the target config file.\nWhen that speed is a function of a board-specific characteristic\nsuch as which speed oscillator is used, it belongs in the board\nconfig file instead.\nIn both cases it's safest to also set the initial JTAG clock rate\nto that same slow speed, so that OpenOCD never starts up using a\nclock speed that's faster than the scan chain can support.\n\n@example\njtag_rclk 3000\n$_TARGET.cpu configure -event reset-start @{ jtag_rclk 3000 @}\n@end example\n\nIf your system supports adaptive clocking (RTCK), configuring\nJTAG to use that is probably the most robust approach.\nHowever, it introduces delays to synchronize clocks; so it\nmay not be the fastest solution.\n\n@b{NOTE:} Script writers should consider using @command{jtag_rclk}\ninstead of @command{adapter speed}, but only for (ARM) cores and boards\nwhich support adaptive clocking.\n\n@deffn {Command} {adapter speed} max_speed_kHz\nA non-zero speed is in KHZ. Hence: 3000 is 3mhz.\nJTAG interfaces usually support a limited number of\nspeeds. The speed actually used won't be faster\nthan the speed specified.\n\nChip data sheets generally include a top JTAG clock rate.\nThe actual rate is often a function of a CPU core clock,\nand is normally less than that peak rate.\nFor example, most ARM cores accept at most one sixth of the CPU clock.\n\nSpeed 0 (khz) selects RTCK method.\n@xref{faqrtck,,FAQ RTCK}.\nIf your system uses RTCK, you won't need to change the\nJTAG clocking after setup.\nNot all interfaces, boards, or targets support ``rtck''.\nIf the interface device can not\nsupport it, an error is returned when you try to use RTCK.\n@end deffn\n\n@defun jtag_rclk fallback_speed_kHz\n@cindex adaptive clocking\n@cindex RTCK\nThis Tcl proc (defined in @file{startup.tcl}) attempts to enable RTCK/RCLK.\nIf that fails (maybe the interface, board, or target doesn't\nsupport it), falls back to the specified frequency.\n@example\n# Fall back to 3mhz if RTCK is not supported\njtag_rclk 3000\n@end example\n@end defun\n\n@node Reset Configuration\n@chapter Reset Configuration\n@cindex Reset Configuration\n\nEvery system configuration may require a different reset\nconfiguration. This can also be quite confusing.\nResets also interact with @var{reset-init} event handlers,\nwhich do things like setting up clocks and DRAM, and\nJTAG clock rates. (@xref{jtagspeed,,JTAG Speed}.)\nThey can also interact with JTAG routers.\nPlease see the various board files for examples.\n\n@quotation Note\nTo maintainers and integrators:\nReset configuration touches several things at once.\nNormally the board configuration file\nshould define it and assume that the JTAG adapter supports\neverything that's wired up to the board's JTAG connector.\n\nHowever, the target configuration file could also make note\nof something the silicon vendor has done inside the chip,\nwhich will be true for most (or all) boards using that chip.\nAnd when the JTAG adapter doesn't support everything, the\nuser configuration file will need to override parts of\nthe reset configuration provided by other files.\n@end quotation\n\n@section Types of Reset\n\nThere are many kinds of reset possible through JTAG, but\nthey may not all work with a given board and adapter.\nThat's part of why reset configuration can be error prone.\n\n@itemize @bullet\n@item\n@emph{System Reset} ... the @emph{SRST} hardware signal\nresets all chips connected to the JTAG adapter, such as processors,\npower management chips, and I/O controllers. Normally resets triggered\nwith this signal behave exactly like pressing a RESET button.\n@item\n@emph{JTAG TAP Reset} ... the @emph{TRST} hardware signal resets\njust the TAP controllers connected to the JTAG adapter.\nSuch resets should not be visible to the rest of the system; resetting a\ndevice's TAP controller just puts that controller into a known state.\n@item\n@emph{Emulation Reset} ... many devices can be reset through JTAG\ncommands. These resets are often distinguishable from system\nresets, either explicitly (a \"reset reason\" register says so)\nor implicitly (not all parts of the chip get reset).\n@item\n@emph{Other Resets} ... system-on-chip devices often support\nseveral other types of reset.\nYou may need to arrange that a watchdog timer stops\nwhile debugging, preventing a watchdog reset.\nThere may be individual module resets.\n@end itemize\n\nIn the best case, OpenOCD can hold SRST, then reset\nthe TAPs via TRST and send commands through JTAG to halt the\nCPU at the reset vector before the 1st instruction is executed.\nThen when it finally releases the SRST signal, the system is\nhalted under debugger control before any code has executed.\nThis is the behavior required to support the @command{reset halt}\nand @command{reset init} commands; after @command{reset init} a\nboard-specific script might do things like setting up DRAM.\n(@xref{resetcommand,,Reset Command}.)\n\n@anchor{srstandtrstissues}\n@section SRST and TRST Issues\n\nBecause SRST and TRST are hardware signals, they can have a\nvariety of system-specific constraints. Some of the most\ncommon issues are:\n\n@itemize @bullet\n\n@item @emph{Signal not available} ... Some boards don't wire\nSRST or TRST to the JTAG connector. Some JTAG adapters don't\nsupport such signals even if they are wired up.\nUse the @command{reset_config} @var{signals} options to say\nwhen either of those signals is not connected.\nWhen SRST is not available, your code might not be able to rely\non controllers having been fully reset during code startup.\nMissing TRST is not a problem, since JTAG-level resets can\nbe triggered using with TMS signaling.\n\n@item @emph{Signals shorted} ... Sometimes a chip, board, or\nadapter will connect SRST to TRST, instead of keeping them separate.\nUse the @command{reset_config} @var{combination} options to say\nwhen those signals aren't properly independent.\n\n@item @emph{Timing} ... Reset circuitry like a resistor/capacitor\ndelay circuit, reset supervisor, or on-chip features can extend\nthe effect of a JTAG adapter's reset for some time after the adapter\nstops issuing the reset. For example, there may be chip or board\nrequirements that all reset pulses last for at least a\ncertain amount of time; and reset buttons commonly have\nhardware debouncing.\nUse the @command{adapter srst delay} and @command{jtag_ntrst_delay}\ncommands to say when extra delays are needed.\n\n@item @emph{Drive type} ... Reset lines often have a pullup\nresistor, letting the JTAG interface treat them as open-drain\nsignals. But that's not a requirement, so the adapter may need\nto use push/pull output drivers.\nAlso, with weak pullups it may be advisable to drive\nsignals to both levels (push/pull) to minimize rise times.\nUse the @command{reset_config} @var{trst_type} and\n@var{srst_type} parameters to say how to drive reset signals.\n\n@item @emph{Special initialization} ... Targets sometimes need\nspecial JTAG initialization sequences to handle chip-specific\nissues (not limited to errata).\nFor example, certain JTAG commands might need to be issued while\nthe system as a whole is in a reset state (SRST active)\nbut the JTAG scan chain is usable (TRST inactive).\nMany systems treat combined assertion of SRST and TRST as a\ntrigger for a harder reset than SRST alone.\nSuch custom reset handling is discussed later in this chapter.\n@end itemize\n\nThere can also be other issues.\nSome devices don't fully conform to the JTAG specifications.\nTrivial system-specific differences are common, such as\nSRST and TRST using slightly different names.\nThere are also vendors who distribute key JTAG documentation for\ntheir chips only to developers who have signed a Non-Disclosure\nAgreement (NDA).\n\nSometimes there are chip-specific extensions like a requirement to use\nthe normally-optional TRST signal (precluding use of JTAG adapters which\ndon't pass TRST through), or needing extra steps to complete a TAP reset.\n\nIn short, SRST and especially TRST handling may be very finicky,\nneeding to cope with both architecture and board specific constraints.\n\n@section Commands for Handling Resets\n\n@deffn {Command} {adapter srst pulse_width} milliseconds\nMinimum amount of time (in milliseconds) OpenOCD should wait\nafter asserting nSRST (active-low system reset) before\nallowing it to be deasserted.\n@end deffn\n\n@deffn {Command} {adapter srst delay} milliseconds\nHow long (in milliseconds) OpenOCD should wait after deasserting\nnSRST (active-low system reset) before starting new JTAG operations.\nWhen a board has a reset button connected to SRST line it will\nprobably have hardware debouncing, implying you should use this.\n@end deffn\n\n@deffn {Command} {jtag_ntrst_assert_width} milliseconds\nMinimum amount of time (in milliseconds) OpenOCD should wait\nafter asserting nTRST (active-low JTAG TAP reset) before\nallowing it to be deasserted.\n@end deffn\n\n@deffn {Command} {jtag_ntrst_delay} milliseconds\nHow long (in milliseconds) OpenOCD should wait after deasserting\nnTRST (active-low JTAG TAP reset) before starting new JTAG operations.\n@end deffn\n\n@anchor{reset_config}\n@deffn {Command} {reset_config} mode_flag ...\nThis command displays or modifies the reset configuration\nof your combination of JTAG board and target in target\nconfiguration scripts.\n\nInformation earlier in this section describes the kind of problems\nthe command is intended to address (@pxref{srstandtrstissues,,SRST and TRST Issues}).\nAs a rule this command belongs only in board config files,\ndescribing issues like @emph{board doesn't connect TRST};\nor in user config files, addressing limitations derived\nfrom a particular combination of interface and board.\n(An unlikely example would be using a TRST-only adapter\nwith a board that only wires up SRST.)\n\nThe @var{mode_flag} options can be specified in any order, but only one\nof each type -- @var{signals}, @var{combination}, @var{gates},\n@var{trst_type}, @var{srst_type} and @var{connect_type}\n-- may be specified at a time.\nIf you don't provide a new value for a given type, its previous\nvalue (perhaps the default) is unchanged.\nFor example, this means that you don't need to say anything at all about\nTRST just to declare that if the JTAG adapter should want to drive SRST,\nit must explicitly be driven high (@option{srst_push_pull}).\n\n@itemize\n@item\n@var{signals} can specify which of the reset signals are connected.\nFor example, If the JTAG interface provides SRST, but the board doesn't\nconnect that signal properly, then OpenOCD can't use it.\nPossible values are @option{none} (the default), @option{trst_only},\n@option{srst_only} and @option{trst_and_srst}.\n\n@quotation Tip\nIf your board provides SRST and/or TRST through the JTAG connector,\nyou must declare that so those signals can be used.\n@end quotation\n\n@item\nThe @var{combination} is an optional value specifying broken reset\nsignal implementations.\nThe default behaviour if no option given is @option{separate},\nindicating everything behaves normally.\n@option{srst_pulls_trst} states that the\ntest logic is reset together with the reset of the system (e.g. NXP\nLPC2000, \"broken\" board layout), @option{trst_pulls_srst} says that\nthe system is reset together with the test logic (only hypothetical, I\nhaven't seen hardware with such a bug, and can be worked around).\n@option{combined} implies both @option{srst_pulls_trst} and\n@option{trst_pulls_srst}.\n\n@item\nThe @var{gates} tokens control flags that describe some cases where\nJTAG may be unavailable during reset.\n@option{srst_gates_jtag} (default)\nindicates that asserting SRST gates the\nJTAG clock. This means that no communication can happen on JTAG\nwhile SRST is asserted.\nIts converse is @option{srst_nogate}, indicating that JTAG commands\ncan safely be issued while SRST is active.\n\n@item\nThe @var{connect_type} tokens control flags that describe some cases where\nSRST is asserted while connecting to the target. @option{srst_nogate}\nis required to use this option.\n@option{connect_deassert_srst} (default)\nindicates that SRST will not be asserted while connecting to the target.\nIts converse is @option{connect_assert_srst}, indicating that SRST will\nbe asserted before any target connection.\nOnly some targets support this feature, STM32 and STR9 are examples.\nThis feature is useful if you are unable to connect to your target due\nto incorrect options byte config or illegal program execution.\n@end itemize\n\nThe optional @var{trst_type} and @var{srst_type} parameters allow the\ndriver mode of each reset line to be specified. These values only affect\nJTAG interfaces with support for different driver modes, like the Amontec\nJTAGkey and JTAG Accelerator. Also, they are necessarily ignored if the\nrelevant signal (TRST or SRST) is not connected.\n\n@itemize\n@item\nPossible @var{trst_type} driver modes for the test reset signal (TRST)\nare the default @option{trst_push_pull}, and @option{trst_open_drain}.\nMost boards connect this signal to a pulldown, so the JTAG TAPs\nnever leave reset unless they are hooked up to a JTAG adapter.\n\n@item\nPossible @var{srst_type} driver modes for the system reset signal (SRST)\nare the default @option{srst_open_drain}, and @option{srst_push_pull}.\nMost boards connect this signal to a pullup, and allow the\nsignal to be pulled low by various events including system\npower-up and pressing a reset button.\n@end itemize\n@end deffn\n\n@section Custom Reset Handling\n@cindex events\n\nOpenOCD has several ways to help support the various reset\nmechanisms provided by chip and board vendors.\nThe commands shown in the previous section give standard parameters.\nThere are also @emph{event handlers} associated with TAPs or Targets.\nThose handlers are Tcl procedures you can provide, which are invoked\nat particular points in the reset sequence.\n\n@emph{When SRST is not an option} you must set\nup a @code{reset-assert} event handler for your target.\nFor example, some JTAG adapters don't include the SRST signal;\nand some boards have multiple targets, and you won't always\nwant to reset everything at once.\n\nAfter configuring those mechanisms, you might still\nfind your board doesn't start up or reset correctly.\nFor example, maybe it needs a slightly different sequence\nof SRST and/or TRST manipulations, because of quirks that\nthe @command{reset_config} mechanism doesn't address;\nor asserting both might trigger a stronger reset, which\nneeds special attention.\n\nExperiment with lower level operations, such as\n@command{adapter assert}, @command{adapter deassert}\nand the @command{jtag arp_*} operations shown here,\nto find a sequence of operations that works.\n@xref{JTAG Commands}.\nWhen you find a working sequence, it can be used to override\n@command{jtag_init}, which fires during OpenOCD startup\n(@pxref{configurationstage,,Configuration Stage});\nor @command{init_reset}, which fires during reset processing.\n\nYou might also want to provide some project-specific reset\nschemes. For example, on a multi-target board the standard\n@command{reset} command would reset all targets, but you\nmay need the ability to reset only one target at time and\nthus want to avoid using the board-wide SRST signal.\n\n@deffn {Overridable Procedure} {init_reset} mode\nThis is invoked near the beginning of the @command{reset} command,\nusually to provide as much of a cold (power-up) reset as practical.\nBy default it is also invoked from @command{jtag_init} if\nthe scan chain does not respond to pure JTAG operations.\nThe @var{mode} parameter is the parameter given to the\nlow level reset command (@option{halt},\n@option{init}, or @option{run}), @option{setup},\nor potentially some other value.\n\nThe default implementation just invokes @command{jtag arp_init-reset}.\nReplacements will normally build on low level JTAG\noperations such as @command{adapter assert} and @command{adapter deassert}.\nOperations here must not address individual TAPs\n(or their associated targets)\nuntil the JTAG scan chain has first been verified to work.\n\nImplementations must have verified the JTAG scan chain before\nthey return.\nThis is done by calling @command{jtag arp_init}\n(or @command{jtag arp_init-reset}).\n@end deffn\n\n@deffn {Command} {jtag arp_init}\nThis validates the scan chain using just the four\nstandard JTAG signals (TMS, TCK, TDI, TDO).\nIt starts by issuing a JTAG-only reset.\nThen it performs checks to verify that the scan chain configuration\nmatches the TAPs it can observe.\nThose checks include checking IDCODE values for each active TAP,\nand verifying the length of their instruction registers using\nTAP @code{-ircapture} and @code{-irmask} values.\nIf these tests all pass, TAP @code{setup} events are\nissued to all TAPs with handlers for that event.\n@end deffn\n\n@deffn {Command} {jtag arp_init-reset}\nThis uses TRST and SRST to try resetting\neverything on the JTAG scan chain\n(and anything else connected to SRST).\nIt then invokes the logic of @command{jtag arp_init}.\n@end deffn\n\n\n@node TAP Declaration\n@chapter TAP Declaration\n@cindex TAP declaration\n@cindex TAP configuration\n\n@emph{Test Access Ports} (TAPs) are the core of JTAG.\nTAPs serve many roles, including:\n\n@itemize @bullet\n@item @b{Debug Target} A CPU TAP can be used as a GDB debug target.\n@item @b{Flash Programming} Some chips program the flash directly via JTAG.\nOthers do it indirectly, making a CPU do it.\n@item @b{Program Download} Using the same CPU support GDB uses,\nyou can initialize a DRAM controller, download code to DRAM, and then\nstart running that code.\n@item @b{Boundary Scan} Most chips support boundary scan, which\nhelps test for board assembly problems like solder bridges\nand missing connections.\n@end itemize\n\nOpenOCD must know about the active TAPs on your board(s).\nSetting up the TAPs is the core task of your configuration files.\nOnce those TAPs are set up, you can pass their names to code\nwhich sets up CPUs and exports them as GDB targets,\nprobes flash memory, performs low-level JTAG operations, and more.\n\n@section Scan Chains\n@cindex scan chain\n\nTAPs are part of a hardware @dfn{scan chain},\nwhich is a daisy chain of TAPs.\nThey also need to be added to\nOpenOCD's software mirror of that hardware list,\ngiving each member a name and associating other data with it.\nSimple scan chains, with a single TAP, are common in\nsystems with a single microcontroller or microprocessor.\nMore complex chips may have several TAPs internally.\nVery complex scan chains might have a dozen or more TAPs:\nseveral in one chip, more in the next, and connecting\nto other boards with their own chips and TAPs.\n\nYou can display the list with the @command{scan_chain} command.\n(Don't confuse this with the list displayed by the @command{targets}\ncommand, presented in the next chapter.\nThat only displays TAPs for CPUs which are configured as\ndebugging targets.)\nHere's what the scan chain might look like for a chip more than one TAP:\n\n@verbatim\n   TapName            Enabled IdCode     Expected   IrLen IrCap IrMask\n-- ------------------ ------- ---------- ---------- ----- ----- ------\n 0 omap5912.dsp          Y    0x03df1d81 0x03df1d81    38 0x01  0x03\n 1 omap5912.arm          Y    0x0692602f 0x0692602f     4 0x01  0x0f\n 2 omap5912.unknown      Y    0x00000000 0x00000000     8 0x01  0x03\n@end verbatim\n\nOpenOCD can detect some of that information, but not all\nof it. @xref{autoprobing,,Autoprobing}.\nUnfortunately, those TAPs can't always be autoconfigured,\nbecause not all devices provide good support for that.\nJTAG doesn't require supporting IDCODE instructions, and\nchips with JTAG routers may not link TAPs into the chain\nuntil they are told to do so.\n\nThe configuration mechanism currently supported by OpenOCD\nrequires explicit configuration of all TAP devices using\n@command{jtag newtap} commands, as detailed later in this chapter.\nA command like this would declare one tap and name it @code{chip1.cpu}:\n\n@example\njtag newtap chip1 cpu -irlen 4 -expected-id 0x3ba00477\n@end example\n\nEach target configuration file lists the TAPs provided\nby a given chip.\nBoard configuration files combine all the targets on a board,\nand so forth.\nNote that @emph{the order in which TAPs are declared is very important.}\nThat declaration order must match the order in the JTAG scan chain,\nboth inside a single chip and between them.\n@xref{faqtaporder,,FAQ TAP Order}.\n\nFor example, the STMicroelectronics STR912 chip has\nthree separate TAPs@footnote{See the ST\ndocument titled: @emph{STR91xFAxxx, Section 3.15 Jtag Interface, Page:\n28/102, Figure 3: JTAG chaining inside the STR91xFA}.\n@url{http://eu.st.com/stonline/products/literature/ds/13495.pdf}}.\nTo configure those taps, @file{target/str912.cfg}\nincludes commands something like this:\n\n@example\njtag newtap str912 flash ... params ...\njtag newtap str912 cpu ... params ...\njtag newtap str912 bs ... params ...\n@end example\n\nActual config files typically use a variable such as @code{$_CHIPNAME}\ninstead of literals like @option{str912}, to support more than one chip\nof each type.  @xref{Config File Guidelines}.\n\n@deffn {Command} {jtag names}\nReturns the names of all current TAPs in the scan chain.\nUse @command{jtag cget} or @command{jtag tapisenabled}\nto examine attributes and state of each TAP.\n@example\nforeach t [jtag names] @{\n    puts [format \"TAP: %s\\n\" $t]\n@}\n@end example\n@end deffn\n\n@deffn {Command} {scan_chain}\nDisplays the TAPs in the scan chain configuration,\nand their status.\nThe set of TAPs listed by this command is fixed by\nexiting the OpenOCD configuration stage,\nbut systems with a JTAG router can\nenable or disable TAPs dynamically.\n@end deffn\n\n@c FIXME! \"jtag cget\" should be able to return all TAP\n@c attributes, like \"$target_name cget\" does for targets.\n\n@c Probably want \"jtag eventlist\", and a \"tap-reset\" event\n@c (on entry to RESET state).\n\n@section TAP Names\n@cindex dotted name\n\nWhen TAP objects are declared with @command{jtag newtap},\na @dfn{dotted.name} is created for the TAP, combining the\nname of a module (usually a chip) and a label for the TAP.\nFor example: @code{xilinx.tap}, @code{str912.flash},\n@code{omap3530.jrc}, @code{dm6446.dsp}, or @code{stm32.cpu}.\nMany other commands use that dotted.name to manipulate or\nrefer to the TAP. For example, CPU configuration uses the\nname, as does declaration of NAND or NOR flash banks.\n\nThe components of a dotted name should follow ``C'' symbol\nname rules: start with an alphabetic character, then numbers\nand underscores are OK; while others (including dots!) are not.\n\n@section TAP Declaration Commands\n\n@deffn {Config Command} {jtag newtap} chipname tapname configparams...\nDeclares a new TAP with the dotted name @var{chipname}.@var{tapname},\nand configured according to the various @var{configparams}.\n\nThe @var{chipname} is a symbolic name for the chip.\nConventionally target config files use @code{$_CHIPNAME},\ndefaulting to the model name given by the chip vendor but\noverridable.\n\n@cindex TAP naming convention\nThe @var{tapname} reflects the role of that TAP,\nand should follow this convention:\n\n@itemize @bullet\n@item @code{bs} -- For boundary scan if this is a separate TAP;\n@item @code{cpu} -- The main CPU of the chip, alternatively\n@code{arm} and @code{dsp} on chips with both ARM and DSP CPUs,\n@code{arm1} and @code{arm2} on chips with two ARMs, and so forth;\n@item @code{etb} -- For an embedded trace buffer (example: an ARM ETB11);\n@item @code{flash} -- If the chip has a flash TAP, like the str912;\n@item @code{jrc} -- For JTAG route controller (example: the ICEPick modules\non many Texas Instruments chips, like the OMAP3530 on Beagleboards);\n@item @code{tap} -- Should be used only for FPGA- or CPLD-like devices\nwith a single TAP;\n@item @code{unknownN} -- If you have no idea what the TAP is for (N is a number);\n@item @emph{when in doubt} -- Use the chip maker's name in their data sheet.\nFor example, the Freescale i.MX31 has a SDMA (Smart DMA) with\na JTAG TAP; that TAP should be named @code{sdma}.\n@end itemize\n\nEvery TAP requires at least the following @var{configparams}:\n\n@itemize @bullet\n@item @code{-irlen} @var{NUMBER}\n@*The length in bits of the\ninstruction register, such as 4 or 5 bits.\n@end itemize\n\nA TAP may also provide optional @var{configparams}:\n\n@itemize @bullet\n@item @code{-disable} (or @code{-enable})\n@*Use the @code{-disable} parameter to flag a TAP which is not\nlinked into the scan chain after a reset using either TRST\nor the JTAG state machine's @sc{reset} state.\nYou may use @code{-enable} to highlight the default state\n(the TAP is linked in).\n@xref{enablinganddisablingtaps,,Enabling and Disabling TAPs}.\n@item @code{-expected-id} @var{NUMBER}\n@*A non-zero @var{number} represents a 32-bit IDCODE\nwhich you expect to find when the scan chain is examined.\nThese codes are not required by all JTAG devices.\n@emph{Repeat the option} as many times as required if more than one\nID code could appear (for example, multiple versions).\nSpecify @var{number} as zero to suppress warnings about IDCODE\nvalues that were found but not included in the list.\n\nProvide this value if at all possible, since it lets OpenOCD\ntell when the scan chain it sees isn't right. These values\nare provided in vendors' chip documentation, usually a technical\nreference manual. Sometimes you may need to probe the JTAG\nhardware to find these values.\n@xref{autoprobing,,Autoprobing}.\n@item @code{-ignore-version}\n@*Specify this to ignore the JTAG version field in the @code{-expected-id}\noption. When vendors put out multiple versions of a chip, or use the same\nJTAG-level ID for several largely-compatible chips, it may be more practical\nto ignore the version field than to update config files to handle all of\nthe various chip IDs. The version field is defined as bit 28-31 of the IDCODE.\n@item @code{-ignore-bypass}\n@*Specify this to ignore the 'bypass' bit of the idcode. Some vendor put\nan invalid idcode regarding this bit. Specify this to ignore this bit and\nto not consider this tap in bypass mode.\n@item @code{-ircapture} @var{NUMBER}\n@*The bit pattern loaded by the TAP into the JTAG shift register\non entry to the @sc{ircapture} state, such as 0x01.\nJTAG requires the two LSBs of this value to be 01.\nBy default, @code{-ircapture} and @code{-irmask} are set\nup to verify that two-bit value. You may provide\nadditional bits if you know them, or indicate that\na TAP doesn't conform to the JTAG specification.\n@item @code{-irmask} @var{NUMBER}\n@*A mask used with @code{-ircapture}\nto verify that instruction scans work correctly.\nSuch scans are not used by OpenOCD except to verify that\nthere seems to be no problems with JTAG scan chain operations.\n@item @code{-ignore-syspwrupack}\n@*Specify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP CTRL/STAT\nregister during initial examination and when checking the sticky error bit.\nThis bit is normally checked after setting the CSYSPWRUPREQ bit, but some\ndevices do not set the ack bit until sometime later.\n@end itemize\n@end deffn\n\n@section Other TAP commands\n\n@deffn {Command} {jtag cget} dotted.name @option{-idcode}\nGet the value of the IDCODE found in hardware.\n@end deffn\n\n@deffn {Command} {jtag cget} dotted.name @option{-event} event_name\n@deffnx {Command} {jtag configure} dotted.name @option{-event} event_name handler\nAt this writing this TAP attribute\nmechanism is limited and used mostly for event handling.\n(It is not a direct analogue of the @code{cget}/@code{configure}\nmechanism for debugger targets.)\nSee the next section for information about the available events.\n\nThe @code{configure} subcommand assigns an event handler,\na TCL string which is evaluated when the event is triggered.\nThe @code{cget} subcommand returns that handler.\n@end deffn\n\n@section TAP Events\n@cindex events\n@cindex TAP events\n\nOpenOCD includes two event mechanisms.\nThe one presented here applies to all JTAG TAPs.\nThe other applies to debugger targets,\nwhich are associated with certain TAPs.\n\nThe TAP events currently defined are:\n\n@itemize @bullet\n@item @b{post-reset}\n@* The TAP has just completed a JTAG reset.\nThe tap may still be in the JTAG @sc{reset} state.\nHandlers for these events might perform initialization sequences\nsuch as issuing TCK cycles, TMS sequences to ensure\nexit from the ARM SWD mode, and more.\n\nBecause the scan chain has not yet been verified, handlers for these events\n@emph{should not issue commands which scan the JTAG IR or DR registers}\nof any particular target.\n@b{NOTE:} As this is written (September 2009), nothing prevents such access.\n@item @b{setup}\n@* The scan chain has been reset and verified.\nThis handler may enable TAPs as needed.\n@item @b{tap-disable}\n@* The TAP needs to be disabled. This handler should\nimplement @command{jtag tapdisable}\nby issuing the relevant JTAG commands.\n@item @b{tap-enable}\n@* The TAP needs to be enabled. This handler should\nimplement @command{jtag tapenable}\nby issuing the relevant JTAG commands.\n@end itemize\n\nIf you need some action after each JTAG reset which isn't actually\nspecific to any TAP (since you can't yet trust the scan chain's\ncontents to be accurate), you might:\n\n@example\njtag configure CHIP.jrc -event post-reset @{\n  echo \"JTAG Reset done\"\n  ... non-scan jtag operations to be done after reset\n@}\n@end example\n\n\n@anchor{enablinganddisablingtaps}\n@section Enabling and Disabling TAPs\n@cindex JTAG Route Controller\n@cindex jrc\n\nIn some systems, a @dfn{JTAG Route Controller} (JRC)\nis used to enable and/or disable specific JTAG TAPs.\nMany ARM-based chips from Texas Instruments include\nan ``ICEPick'' module, which is a JRC.\nSuch chips include DaVinci and OMAP3 processors.\n\nA given TAP may not be visible until the JRC has been\ntold to link it into the scan chain; and if the JRC\nhas been told to unlink that TAP, it will no longer\nbe visible.\nSuch routers address problems that JTAG ``bypass mode''\nignores, such as:\n\n@itemize\n@item The scan chain can only go as fast as its slowest TAP.\n@item Having many TAPs slows instruction scans, since all\nTAPs receive new instructions.\n@item TAPs in the scan chain must be powered up, which wastes\npower and prevents debugging some power management mechanisms.\n@end itemize\n\nThe IEEE 1149.1 JTAG standard has no concept of a ``disabled'' tap,\nas implied by the existence of JTAG routers.\nHowever, the upcoming IEEE 1149.7 framework (layered on top of JTAG)\ndoes include a kind of JTAG router functionality.\n\n@c (a) currently the event handlers don't seem to be able to\n@c     fail in a way that could lead to no-change-of-state.\n\nIn OpenOCD, tap enabling/disabling is invoked by the Tcl commands\nshown below, and is implemented using TAP event handlers.\nSo for example, when defining a TAP for a CPU connected to\na JTAG router, your @file{target.cfg} file\nshould define TAP event handlers using\ncode that looks something like this:\n\n@example\njtag configure CHIP.cpu -event tap-enable @{\n  ... jtag operations using CHIP.jrc\n@}\njtag configure CHIP.cpu -event tap-disable @{\n  ... jtag operations using CHIP.jrc\n@}\n@end example\n\nThen you might want that CPU's TAP enabled almost all the time:\n\n@example\njtag configure $CHIP.jrc -event setup \"jtag tapenable $CHIP.cpu\"\n@end example\n\nNote how that particular setup event handler declaration\nuses quotes to evaluate @code{$CHIP} when the event is configured.\nUsing brackets @{ @} would cause it to be evaluated later,\nat runtime, when it might have a different value.\n\n@deffn {Command} {jtag tapdisable} dotted.name\nIf necessary, disables the tap\nby sending it a @option{tap-disable} event.\nReturns the string \"1\" if the tap\nspecified by @var{dotted.name} is enabled,\nand \"0\" if it is disabled.\n@end deffn\n\n@deffn {Command} {jtag tapenable} dotted.name\nIf necessary, enables the tap\nby sending it a @option{tap-enable} event.\nReturns the string \"1\" if the tap\nspecified by @var{dotted.name} is enabled,\nand \"0\" if it is disabled.\n@end deffn\n\n@deffn {Command} {jtag tapisenabled} dotted.name\nReturns the string \"1\" if the tap\nspecified by @var{dotted.name} is enabled,\nand \"0\" if it is disabled.\n\n@quotation Note\nHumans will find the @command{scan_chain} command more helpful\nfor querying the state of the JTAG taps.\n@end quotation\n@end deffn\n\n@anchor{autoprobing}\n@section Autoprobing\n@cindex autoprobe\n@cindex JTAG autoprobe\n\nTAP configuration is the first thing that needs to be done\nafter interface and reset configuration. Sometimes it's\nhard finding out what TAPs exist, or how they are identified.\nVendor documentation is not always easy to find and use.\n\nTo help you get past such problems, OpenOCD has a limited\n@emph{autoprobing} ability to look at the scan chain, doing\na @dfn{blind interrogation} and then reporting the TAPs it finds.\nTo use this mechanism, start the OpenOCD server with only data\nthat configures your JTAG interface, and arranges to come up\nwith a slow clock (many devices don't support fast JTAG clocks\nright when they come out of reset).\n\nFor example, your @file{openocd.cfg} file might have:\n\n@example\nsource [find interface/olimex-arm-usb-tiny-h.cfg]\nreset_config trst_and_srst\njtag_rclk 8\n@end example\n\nWhen you start the server without any TAPs configured, it will\nattempt to autoconfigure the TAPs. There are two parts to this:\n\n@enumerate\n@item @emph{TAP discovery} ...\nAfter a JTAG reset (sometimes a system reset may be needed too),\neach TAP's data registers will hold the contents of either the\nIDCODE or BYPASS register.\nIf JTAG communication is working, OpenOCD will see each TAP,\nand report what @option{-expected-id} to use with it.\n@item @emph{IR Length discovery} ...\nUnfortunately JTAG does not provide a reliable way to find out\nthe value of the @option{-irlen} parameter to use with a TAP\nthat is discovered.\nIf OpenOCD can discover the length of a TAP's instruction\nregister, it will report it.\nOtherwise you may need to consult vendor documentation, such\nas chip data sheets or BSDL files.\n@end enumerate\n\nIn many cases your board will have a simple scan chain with just\na single device. Here's what OpenOCD reported with one board\nthat's a bit more complex:\n\n@example\nclock speed 8 kHz\nThere are no enabled taps. AUTO PROBING MIGHT NOT WORK!!\nAUTO auto0.tap - use \"jtag newtap auto0 tap -expected-id 0x2b900f0f ...\"\nAUTO auto1.tap - use \"jtag newtap auto1 tap -expected-id 0x07926001 ...\"\nAUTO auto2.tap - use \"jtag newtap auto2 tap -expected-id 0x0b73b02f ...\"\nAUTO auto0.tap - use \"... -irlen 4\"\nAUTO auto1.tap - use \"... -irlen 4\"\nAUTO auto2.tap - use \"... -irlen 6\"\nno gdb ports allocated as no target has been specified\n@end example\n\nGiven that information, you should be able to either find some existing\nconfig files to use, or create your own. If you create your own, you\nwould configure from the bottom up: first a @file{target.cfg} file\nwith these TAPs, any targets associated with them, and any on-chip\nresources; then a @file{board.cfg} with off-chip resources, clocking,\nand so forth.\n\n@anchor{dapdeclaration}\n@section DAP declaration (ARMv6-M, ARMv7 and ARMv8 targets)\n@cindex DAP declaration\n\nSince OpenOCD version 0.11.0, the Debug Access Port (DAP) is\nno longer implicitly created together with the target. It must be\nexplicitly declared using the @command{dap create} command. For all ARMv6-M, ARMv7\nand ARMv8 targets, the option \"@option{-dap} @var{dap_name}\" has to be used\ninstead of \"@option{-chain-position} @var{dotted.name}\" when the target is created.\n\nThe @command{dap} command group supports the following sub-commands:\n\n@anchor{dap_create}\n@deffn {Command} {dap create} dap_name @option{-chain-position} dotted.name configparams...\nDeclare a DAP instance named @var{dap_name} linked to the JTAG tap\n@var{dotted.name}. This also creates a new command (@command{dap_name})\nwhich is used for various purposes including additional configuration.\nThere can only be one DAP for each JTAG tap in the system.\n\nA DAP may also provide optional @var{configparams}:\n\n@itemize @bullet\n@item @code{-adiv5}\nSpecify that it's an ADIv5 DAP. This is the default if not specified.\n@item @code{-adiv6}\nSpecify that it's an ADIv6 DAP.\n@item @code{-ignore-syspwrupack}\nSpecify this to ignore the CSYSPWRUPACK bit in the ARM DAP DP CTRL/STAT\nregister during initial examination and when checking the sticky error bit.\nThis bit is normally checked after setting the CSYSPWRUPREQ bit, but some\ndevices do not set the ack bit until sometime later.\n\n@item @code{-dp-id} @var{number}\n@*Debug port identification number for SWD DPv2 multidrop.\nThe @var{number} is written to bits 0..27 of DP TARGETSEL during DP selection.\nTo find the id number of a single connected device read DP TARGETID:\n@code{device.dap dpreg 0x24}\nUse bits 0..27 of TARGETID.\n\n@item @code{-instance-id} @var{number}\n@*Instance identification number for SWD DPv2 multidrop.\nThe @var{number} is written to bits 28..31 of DP TARGETSEL during DP selection.\nTo find the instance number of a single connected device read DP DLPIDR:\n@code{device.dap dpreg 0x34}\nThe instance number is in bits 28..31 of DLPIDR value.\n@end itemize\n@end deffn\n\n@deffn {Command} {dap names}\nThis command returns a list of all registered DAP objects. It it useful mainly\nfor TCL scripting.\n@end deffn\n\n@deffn {Command} {dap info} [@var{num}|@option{root}]\nDisplays the ROM table for MEM-AP @var{num},\ndefaulting to the currently selected AP of the currently selected target.\nOn ADIv5 DAP @var{num} is the numeric index of the AP.\nOn ADIv6 DAP @var{num} is the base address of the AP.\nWith ADIv6 only, @option{root} specifies the root ROM table.\n@end deffn\n\n@deffn {Command} {dap init}\nInitialize all registered DAPs. This command is used internally\nduring initialization. It can be issued at any time after the\ninitialization, too.\n@end deffn\n\nThe following commands exist as subcommands of DAP instances:\n\n@deffn {Command} {$dap_name info} [@var{num}|@option{root}]\nDisplays the ROM table for MEM-AP @var{num},\ndefaulting to the currently selected AP.\nOn ADIv5 DAP @var{num} is the numeric index of the AP.\nOn ADIv6 DAP @var{num} is the base address of the AP.\nWith ADIv6 only, @option{root} specifies the root ROM table.\n@end deffn\n\n@deffn {Command} {$dap_name apid} [num]\nDisplays ID register from AP @var{num}, defaulting to the currently selected AP.\nOn ADIv5 DAP @var{num} is the numeric index of the AP.\nOn ADIv6 DAP @var{num} is the base address of the AP.\n@end deffn\n\n@anchor{DAP subcommand apreg}\n@deffn {Command} {$dap_name apreg} ap_num reg [value]\nDisplays content of a register @var{reg} from AP @var{ap_num}\nor set a new value @var{value}.\nOn ADIv5 DAP @var{ap_num} is the numeric index of the AP.\nOn ADIv6 DAP @var{ap_num} is the base address of the AP.\n@var{reg} is byte address of a word register, 0, 4, 8 ... 0xfc.\n@end deffn\n\n@deffn {Command} {$dap_name apsel} [num]\nSelect AP @var{num}, defaulting to 0.\nOn ADIv5 DAP @var{num} is the numeric index of the AP.\nOn ADIv6 DAP @var{num} is the base address of the AP.\n@end deffn\n\n@deffn {Command} {$dap_name dpreg} reg [value]\nDisplays the content of DP register at address @var{reg}, or set it to a new\nvalue @var{value}.\n\nIn case of SWD, @var{reg} is a value in packed format\n@math{dpbanksel << 4 | addr} and assumes values 0, 4, 8 ... 0xfc.\nIn case of JTAG it only assumes values 0, 4, 8 and 0xc.\n\n@emph{Note:} Consider using @command{poll off} to avoid any disturbing\nbackground activity by OpenOCD while you are operating at such low-level.\n@end deffn\n\n@deffn {Command} {$dap_name baseaddr} [num]\nDisplays debug base address from MEM-AP @var{num},\ndefaulting to the currently selected AP.\nOn ADIv5 DAP @var{num} is the numeric index of the AP.\nOn ADIv6 DAP @var{num} is the base address of the AP.\n@end deffn\n\n@deffn {Command} {$dap_name memaccess} [value]\nDisplays the number of extra tck cycles in the JTAG idle to use for MEM-AP\nmemory bus access [0-255], giving additional time to respond to reads.\nIf @var{value} is defined, first assigns that.\n@end deffn\n\n@deffn {Command} {$dap_name apcsw} [value [mask]]\nDisplays or changes CSW bit pattern for MEM-AP transfers.\n\nAt the begin of each memory access the CSW pattern is extended (bitwise or-ed)\nby @dfn{Size} and @dfn{AddrInc} bit-fields according to transfer requirements\nand the result is written to the real CSW register. All bits except dynamically\nupdated fields @dfn{Size} and @dfn{AddrInc} can be changed by changing\nthe CSW pattern. Refer to ARM ADI v5 manual chapter 7.6.4 and appendix A\nfor details.\n\nUse @var{value} only syntax if you want to set the new CSW pattern as a whole.\nThe example sets HPROT1 bit (required by Cortex-M) and clears the rest of\nthe pattern:\n@example\nkx.dap apcsw 0x2000000\n@end example\n\nIf @var{mask} is also used, the CSW pattern is changed only on bit positions\nwhere the mask bit is 1. The following example sets HPROT3 (cacheable)\nand leaves the rest of the pattern intact. It configures memory access through\nDCache on Cortex-M7.\n@example\nset CSW_HPROT3_CACHEABLE [expr @{1 << 27@}]\nsamv.dap apcsw $CSW_HPROT3_CACHEABLE $CSW_HPROT3_CACHEABLE\n@end example\n\nAnother example clears SPROT bit and leaves the rest of pattern intact:\n@example\nset CSW_SPROT [expr @{1 << 30@}]\nsamv.dap apcsw 0 $CSW_SPROT\n@end example\n\n@emph{Note:} If you want to check the real value of CSW, not CSW pattern, use\n@code{xxx.dap apreg 0}. @xref{DAP subcommand apreg,,}.\n\n@emph{Warning:} Some of the CSW bits are vital for working memory transfer.\nIf you set a wrong CSW pattern and MEM-AP stopped working, use the following\nexample with a proper dap name:\n@example\nxxx.dap apcsw default\n@end example\n@end deffn\n\n@deffn {Config Command} {$dap_name ti_be_32_quirks} [@option{enable}]\nSet/get quirks mode for TI TMS450/TMS570 processors\nDisabled by default\n@end deffn\n\n@deffn {Config Command} {$dap_name nu_npcx_quirks} [@option{enable}]\nSet/get quirks mode for Nuvoton NPCX/NPCD MCU families\nDisabled by default\n@end deffn\n\n@node CPU Configuration\n@chapter CPU Configuration\n@cindex GDB target\n\nThis chapter discusses how to set up GDB debug targets for CPUs.\nYou can also access these targets without GDB\n(@pxref{Architecture and Core Commands},\nand @ref{targetstatehandling,,Target State handling}) and\nthrough various kinds of NAND and NOR flash commands.\nIf you have multiple CPUs you can have multiple such targets.\n\nWe'll start by looking at how to examine the targets you have,\nthen look at how to add one more target and how to configure it.\n\n@section Target List\n@cindex target, current\n@cindex target, list\n\nAll targets that have been set up are part of a list,\nwhere each member has a name.\nThat name should normally be the same as the TAP name.\nYou can display the list with the @command{targets}\n(plural!) command.\nThis display often has only one CPU; here's what it might\nlook like with more than one:\n@verbatim\n    TargetName         Type       Endian TapName            State\n--  ------------------ ---------- ------ ------------------ ------------\n 0* at91rm9200.cpu     arm920t    little at91rm9200.cpu     running\n 1  MyTarget           cortex_m   little mychip.foo         tap-disabled\n@end verbatim\n\nOne member of that list is the @dfn{current target}, which\nis implicitly referenced by many commands.\nIt's the one marked with a @code{*} near the target name.\nIn particular, memory addresses often refer to the address\nspace seen by that current target.\nCommands like @command{mdw} (memory display words)\nand @command{flash erase_address} (erase NOR flash blocks)\nare examples; and there are many more.\n\nSeveral commands let you examine the list of targets:\n\n@deffn {Command} {target current}\nReturns the name of the current target.\n@end deffn\n\n@deffn {Command} {target names}\nLists the names of all current targets in the list.\n@example\nforeach t [target names] @{\n    puts [format \"Target: %s\\n\" $t]\n@}\n@end example\n@end deffn\n\n@c yep, \"target list\" would have been better.\n@c plus maybe \"target setdefault\".\n\n@deffn {Command} {targets} [name]\n@emph{Note: the name of this command is plural. Other target\ncommand names are singular.}\n\nWith no parameter, this command displays a table of all known\ntargets in a user friendly form.\n\nWith a parameter, this command sets the current target to\nthe given target with the given @var{name}; this is\nonly relevant on boards which have more than one target.\n@end deffn\n\n@section Target CPU Types\n@cindex target type\n@cindex CPU type\n\nEach target has a @dfn{CPU type}, as shown in the output of\nthe @command{targets} command. You need to specify that type\nwhen calling @command{target create}.\nThe CPU type indicates more than just the instruction set.\nIt also indicates how that instruction set is implemented,\nwhat kind of debug support it integrates,\nwhether it has an MMU (and if so, what kind),\nwhat core-specific commands may be available\n(@pxref{Architecture and Core Commands}),\nand more.\n\nIt's easy to see what target types are supported,\nsince there's a command to list them.\n\n@anchor{targettypes}\n@deffn {Command} {target types}\nLists all supported target types.\nAt this writing, the supported CPU types are:\n\n@itemize @bullet\n@item @code{aarch64} -- this is an ARMv8-A core with an MMU.\n@item @code{arm11} -- this is a generation of ARMv6 cores.\n@item @code{arm720t} -- this is an ARMv4 core with an MMU.\n@item @code{arm7tdmi} -- this is an ARMv4 core.\n@item @code{arm920t} -- this is an ARMv4 core with an MMU.\n@item @code{arm926ejs} -- this is an ARMv5 core with an MMU.\n@item @code{arm946e} -- this is an ARMv5 core with an MMU.\n@item @code{arm966e} -- this is an ARMv5 core.\n@item @code{arm9tdmi} -- this is an ARMv4 core.\n@item @code{avr} -- implements Atmel's 8-bit AVR instruction set.\n(Support for this is preliminary and incomplete.)\n@item @code{avr32_ap7k} -- this an AVR32 core.\n@item @code{cortex_a} -- this is an ARMv7-A core with an MMU.\n@item @code{cortex_m} -- this is an ARMv7-M core, supporting only the\ncompact Thumb2 instruction set. Supports also ARMv6-M and ARMv8-M cores\n@item @code{cortex_r4} -- this is an ARMv7-R core.\n@item @code{dragonite} -- resembles arm966e.\n@item @code{dsp563xx} -- implements Freescale's 24-bit DSP.\n(Support for this is still incomplete.)\n@item @code{dsp5680xx} -- implements Freescale's 5680x DSP.\n@item @code{esirisc} -- this is an EnSilica eSi-RISC core.\nThe current implementation supports eSi-32xx cores.\n@item @code{esp32} -- this is an Espressif SoC with dual Xtensa cores.\n@item @code{esp32s2} -- this is an Espressif SoC with single Xtensa core.\n@item @code{esp32s3} -- this is an Espressif SoC with dual Xtensa cores.\n@item @code{fa526} -- resembles arm920 (w/o Thumb).\n@item @code{feroceon} -- resembles arm926.\n@item @code{hla_target} -- a Cortex-M alternative to work with HL adapters like ST-Link.\n@item @code{ls1_sap} -- this is the SAP on NXP LS102x CPUs,\nallowing access to physical memory addresses independently of CPU cores.\n@item @code{mem_ap} -- this is an ARM debug infrastructure Access Port without\na CPU, through which bus read and write cycles can be generated; it may be\nuseful for working with non-CPU hardware behind an AP or during development of\nsupport for new CPUs.\nIt's possible to connect a GDB client to this target (the GDB port has to be\nspecified, @xref{gdbportoverride,,option -gdb-port}.), and a fake ARM core will\nbe emulated to comply to GDB remote protocol.\n@item @code{mips_m4k} -- a MIPS core.\n@item @code{mips_mips64} -- a MIPS64 core.\n@item @code{or1k} -- this is an OpenRISC 1000 core.\nThe current implementation supports three JTAG TAP cores:\n@itemize @minus\n@item @code{OpenCores TAP} (See: @url{http://opencores.org/project@comma{}jtag})\n@item @code{Altera Virtual JTAG TAP} (See: @url{http://www.altera.com/literature/ug/ug_virtualjtag.pdf})\n@item @code{Xilinx BSCAN_* virtual JTAG interface} (See: @url{http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_2/spartan6_hdl.pdf})\n@end itemize\nAnd two debug interfaces cores:\n@itemize @minus\n@item @code{Advanced debug interface}\n@*(See: @url{http://opencores.org/project@comma{}adv_debug_sys})\n@item @code{SoC Debug Interface}\n@*(See: @url{http://opencores.org/project@comma{}dbg_interface})\n@end itemize\n@item @code{quark_d20xx} -- an Intel Quark D20xx core.\n@item @code{quark_x10xx} -- an Intel Quark X10xx core.\n@item @code{riscv} -- a RISC-V core.\n@item @code{stm8} -- implements an STM8 core.\n@item @code{testee} -- a dummy target for cases without a real CPU, e.g. CPLD.\n@item @code{xscale} -- this is actually an architecture,\nnot a CPU type. It is based on the ARMv5 architecture.\n@item @code{xtensa} -- this is a generic Cadence/Tensilica Xtensa core.\n@end itemize\n@end deffn\n\nTo avoid being confused by the variety of ARM based cores, remember\nthis key point: @emph{ARM is a technology licencing company}.\n(See: @url{http://www.arm.com}.)\nThe CPU name used by OpenOCD will reflect the CPU design that was\nlicensed, not a vendor brand which incorporates that design.\nName prefixes like arm7, arm9, arm11, and cortex\nreflect design generations;\nwhile names like ARMv4, ARMv5, ARMv6, ARMv7 and ARMv8\nreflect an architecture version implemented by a CPU design.\n\n@anchor{targetconfiguration}\n@section Target Configuration\n\nBefore creating a ``target'', you must have added its TAP to the scan chain.\nWhen you've added that TAP, you will have a @code{dotted.name}\nwhich is used to set up the CPU support.\nThe chip-specific configuration file will normally configure its CPU(s)\nright after it adds all of the chip's TAPs to the scan chain.\n\nAlthough you can set up a target in one step, it's often clearer if you\nuse shorter commands and do it in two steps: create it, then configure\noptional parts.\nAll operations on the target after it's created will use a new\ncommand, created as part of target creation.\n\nThe two main things to configure after target creation are\na work area, which usually has target-specific defaults even\nif the board setup code overrides them later;\nand event handlers (@pxref{targetevents,,Target Events}), which tend\nto be much more board-specific.\nThe key steps you use might look something like this\n\n@example\ndap create mychip.dap -chain-position mychip.cpu\ntarget create MyTarget cortex_m -dap mychip.dap\nMyTarget configure -work-area-phys 0x08000 -work-area-size 8096\nMyTarget configure -event reset-deassert-pre @{ jtag_rclk 5 @}\nMyTarget configure -event reset-init @{ myboard_reinit @}\n@end example\n\nYou should specify a working area if you can; typically it uses some\non-chip SRAM.\nSuch a working area can speed up many things, including bulk\nwrites to target memory;\nflash operations like checking to see if memory needs to be erased;\nGDB memory checksumming;\nand more.\n\n@quotation Warning\nOn more complex chips, the work area can become\ninaccessible when application code\n(such as an operating system)\nenables or disables the MMU.\nFor example, the particular MMU context used to access the virtual\naddress will probably matter ... and that context might not have\neasy access to other addresses needed.\nAt this writing, OpenOCD doesn't have much MMU intelligence.\n@end quotation\n\nIt's often very useful to define a @code{reset-init} event handler.\nFor systems that are normally used with a boot loader,\ncommon tasks include updating clocks and initializing memory\ncontrollers.\nThat may be needed to let you write the boot loader into flash,\nin order to ``de-brick'' your board; or to load programs into\nexternal DDR memory without having run the boot loader.\n\n@deffn {Config Command} {target create} target_name type configparams...\nThis command creates a GDB debug target that refers to a specific JTAG tap.\nIt enters that target into a list, and creates a new\ncommand (@command{@var{target_name}}) which is used for various\npurposes including additional configuration.\n\n@itemize @bullet\n@item @var{target_name} ... is the name of the debug target.\nBy convention this should be the same as the @emph{dotted.name}\nof the TAP associated with this target, which must be specified here\nusing the @code{-chain-position @var{dotted.name}} configparam.\n\nThis name is also used to create the target object command,\nreferred to here as @command{$target_name},\nand in other places the target needs to be identified.\n@item @var{type} ... specifies the target type. @xref{targettypes,,target types}.\n@item @var{configparams} ... all parameters accepted by\n@command{$target_name configure} are permitted.\nIf the target is big-endian, set it here with @code{-endian big}.\n\nYou @emph{must} set the @code{-chain-position @var{dotted.name}} or\n@code{-dap @var{dap_name}} here.\n@end itemize\n@end deffn\n\n@deffn {Command} {$target_name configure} configparams...\nThe options accepted by this command may also be\nspecified as parameters to @command{target create}.\nTheir values can later be queried one at a time by\nusing the @command{$target_name cget} command.\n\n@emph{Warning:} changing some of these after setup is dangerous.\nFor example, moving a target from one TAP to another;\nand changing its endianness.\n\n@itemize @bullet\n\n@item @code{-chain-position} @var{dotted.name} -- names the TAP\nused to access this target.\n\n@item @code{-dap} @var{dap_name} -- names the DAP used to access\nthis target. @xref{dapdeclaration,,DAP declaration}, on how to\ncreate and manage DAP instances.\n\n@item @code{-endian} (@option{big}|@option{little}) -- specifies\nwhether the CPU uses big or little endian conventions\n\n@item @code{-event} @var{event_name} @var{event_body} --\n@xref{targetevents,,Target Events}.\nNote that this updates a list of named event handlers.\nCalling this twice with two different event names assigns\ntwo different handlers, but calling it twice with the\nsame event name assigns only one handler.\n\nCurrent target is temporarily overridden to the event issuing target\nbefore handler code starts and switched back after handler is done.\n\n@item @code{-work-area-backup} (@option{0}|@option{1}) -- says\nwhether the work area gets backed up; by default,\n@emph{it is not backed up.}\nWhen possible, use a working_area that doesn't need to be backed up,\nsince performing a backup slows down operations.\nFor example, the beginning of an SRAM block is likely to\nbe used by most build systems, but the end is often unused.\n\n@item @code{-work-area-size} @var{size} -- specify work are size,\nin bytes. The same size applies regardless of whether its physical\nor virtual address is being used.\n\n@item @code{-work-area-phys} @var{address} -- set the work area\nbase @var{address} to be used when no MMU is active.\n\n@item @code{-work-area-virt} @var{address} -- set the work area\nbase @var{address} to be used when an MMU is active.\n@emph{Do not specify a value for this except on targets with an MMU.}\nThe value should normally correspond to a static mapping for the\n@code{-work-area-phys} address, set up by the current operating system.\n\n@anchor{rtostype}\n@item @code{-rtos} @var{rtos_type} -- enable rtos support for target,\n@var{rtos_type} can be one of @option{auto}, @option{none}, @option{eCos},\n@option{ThreadX}, @option{FreeRTOS}, @option{linux}, @option{ChibiOS},\n@option{embKernel}, @option{mqx}, @option{uCOS-III}, @option{nuttx},\n@option{RIOT}, @option{Zephyr}, @option{rtkernel}\n@xref{gdbrtossupport,,RTOS Support}.\n\n@item @code{-defer-examine} -- skip target examination at initial JTAG chain\nscan and after a reset. A manual call to arp_examine is required to\naccess the target for debugging.\n\n@item @code{-ap-num} @var{ap_number} -- set DAP access port for target.\nOn ADIv5 DAP @var{ap_number} is the numeric index of the DAP AP the target is connected to.\nOn ADIv6 DAP @var{ap_number} is the base address of the DAP AP the target is connected to.\nUse this option with systems where multiple, independent cores are connected\nto separate access ports of the same DAP.\n\n@item @code{-cti} @var{cti_name} -- set Cross-Trigger Interface (CTI) connected\nto the target. Currently, only the @code{aarch64} target makes use of this option,\nwhere it is a mandatory configuration for the target run control.\n@xref{armcrosstrigger,,ARM Cross-Trigger Interface},\nfor instruction on how to declare and control a CTI instance.\n\n@anchor{gdbportoverride}\n@item @code{-gdb-port} @var{number} -- see command @command{gdb_port} for the\npossible values of the parameter @var{number}, which are not only numeric values.\nUse this option to override, for this target only, the global parameter set with\ncommand @command{gdb_port}.\n@xref{gdb_port,,command gdb_port}.\n\n@item @code{-gdb-max-connections} @var{number} -- EXPERIMENTAL: set the maximum\nnumber of GDB connections that are allowed for the target. Default is 1.\nA negative value for @var{number} means unlimited connections.\nSee @xref{gdbmeminspect,,Using GDB as a non-intrusive memory inspector}.\n@end itemize\n@end deffn\n\n@section Other $target_name Commands\n@cindex object command\n\nThe Tcl/Tk language has the concept of object commands,\nand OpenOCD adopts that same model for targets.\n\nA good Tk example is a on screen button.\nOnce a button is created a button\nhas a name (a path in Tk terms) and that name is useable as a first\nclass command. For example in Tk, one can create a button and later\nconfigure it like this:\n\n@example\n# Create\nbutton .foobar -background red -command @{ foo @}\n# Modify\n.foobar configure -foreground blue\n# Query\nset x [.foobar cget -background]\n# Report\nputs [format \"The button is %s\" $x]\n@end example\n\nIn OpenOCD's terms, the ``target'' is an object just like a Tcl/Tk\nbutton, and its object commands are invoked the same way.\n\n@example\nstr912.cpu    mww 0x1234 0x42\nomap3530.cpu  mww 0x5555 123\n@end example\n\nThe commands supported by OpenOCD target objects are:\n\n@deffn {Command} {$target_name arp_examine} @option{allow-defer}\n@deffnx {Command} {$target_name arp_halt}\n@deffnx {Command} {$target_name arp_poll}\n@deffnx {Command} {$target_name arp_reset}\n@deffnx {Command} {$target_name arp_waitstate}\nInternal OpenOCD scripts (most notably @file{startup.tcl})\nuse these to deal with specific reset cases.\nThey are not otherwise documented here.\n@end deffn\n\n@deffn {Command} {$target_name set_reg} dict\nSet register values of the target.\n\n@itemize\n@item @var{dict} ... Tcl dictionary with pairs of register names and values.\n@end itemize\n\nFor example, the following command sets the value 0 to the program counter (pc)\nregister and 0x1000 to the stack pointer (sp) register:\n\n@example\nset_reg @{pc 0 sp 0x1000@}\n@end example\n@end deffn\n\n@deffn {Command} {$target_name get_reg} [-force] list\nGet register values from the target and return them as Tcl dictionary with pairs\nof register names and values.\nIf option \"-force\" is set, the register values are read directly from the\ntarget, bypassing any caching.\n\n@itemize\n@item @var{list} ... List of register names\n@end itemize\n\nFor example, the following command retrieves the values from the program\ncounter (pc) and stack pointer (sp) register:\n\n@example\nget_reg @{pc sp@}\n@end example\n@end deffn\n\n@deffn {Command} {$target_name write_memory} address width data ['phys']\nThis function provides an efficient way to write to the target memory from a Tcl\nscript.\n\n@itemize\n@item @var{address} ... target memory address\n@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64\n@item @var{data} ... Tcl list with the elements to write\n@item ['phys'] ... treat the memory address as physical instead of virtual address\n@end itemize\n\nFor example, the following command writes two 32 bit words into the target\nmemory at address 0x20000000:\n\n@example\nwrite_memory 0x20000000 32 @{0xdeadbeef 0x00230500@}\n@end example\n@end deffn\n\n@deffn {Command} {$target_name read_memory} address width count ['phys']\nThis function provides an efficient way to read the target memory from a Tcl\nscript.\nA Tcl list containing the requested memory elements is returned by this function.\n\n@itemize\n@item @var{address} ... target memory address\n@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64\n@item @var{count} ... number of elements to read\n@item ['phys'] ... treat the memory address as physical instead of virtual address\n@end itemize\n\nFor example, the following command reads two 32 bit words from the target\nmemory at address 0x20000000:\n\n@example\nread_memory 0x20000000 32 2\n@end example\n@end deffn\n\n@deffn {Command} {$target_name cget} queryparm\nEach configuration parameter accepted by\n@command{$target_name configure}\ncan be individually queried, to return its current value.\nThe @var{queryparm} is a parameter name\naccepted by that command, such as @code{-work-area-phys}.\nThere are a few special cases:\n\n@itemize @bullet\n@item @code{-event} @var{event_name} -- returns the handler for the\nevent named @var{event_name}.\nThis is a special case because setting a handler requires\ntwo parameters.\n@item @code{-type} -- returns the target type.\nThis is a special case because this is set using\n@command{target create} and can't be changed\nusing @command{$target_name configure}.\n@end itemize\n\nFor example, if you wanted to summarize information about\nall the targets you might use something like this:\n\n@example\nforeach name [target names] @{\n    set y [$name cget -endian]\n    set z [$name cget -type]\n    puts [format \"Chip %d is %s, Endian: %s, type: %s\" \\\n                 $x $name $y $z]\n@}\n@end example\n@end deffn\n\n@anchor{targetcurstate}\n@deffn {Command} {$target_name curstate}\nDisplays the current target state:\n@code{debug-running},\n@code{halted},\n@code{reset},\n@code{running}, or @code{unknown}.\n(Also, @pxref{eventpolling,,Event Polling}.)\n@end deffn\n\n@deffn {Command} {$target_name eventlist}\nDisplays a table listing all event handlers\ncurrently associated with this target.\n@xref{targetevents,,Target Events}.\n@end deffn\n\n@deffn {Command} {$target_name invoke-event} event_name\nInvokes the handler for the event named @var{event_name}.\n(This is primarily intended for use by OpenOCD framework\ncode, for example by the reset code in @file{startup.tcl}.)\n@end deffn\n\n@deffn {Command} {$target_name mdd} [phys] addr [count]\n@deffnx {Command} {$target_name mdw} [phys] addr [count]\n@deffnx {Command} {$target_name mdh} [phys] addr [count]\n@deffnx {Command} {$target_name mdb} [phys] addr [count]\nDisplay contents of address @var{addr}, as\n64-bit doublewords (@command{mdd}),\n32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),\nor 8-bit bytes (@command{mdb}).\nWhen the current target has an MMU which is present and active,\n@var{addr} is interpreted as a virtual address.\nOtherwise, or if the optional @var{phys} flag is specified,\n@var{addr} is interpreted as a physical address.\nIf @var{count} is specified, displays that many units.\n(If you want to process the data instead of displaying it,\nsee the @code{read_memory} primitives.)\n@end deffn\n\n@deffn {Command} {$target_name mwd} [phys] addr doubleword [count]\n@deffnx {Command} {$target_name mww} [phys] addr word [count]\n@deffnx {Command} {$target_name mwh} [phys] addr halfword [count]\n@deffnx {Command} {$target_name mwb} [phys] addr byte [count]\nWrites the specified @var{doubleword} (64 bits), @var{word} (32 bits),\n@var{halfword} (16 bits), or @var{byte} (8-bit) value,\nat the specified address @var{addr}.\nWhen the current target has an MMU which is present and active,\n@var{addr} is interpreted as a virtual address.\nOtherwise, or if the optional @var{phys} flag is specified,\n@var{addr} is interpreted as a physical address.\nIf @var{count} is specified, fills that many units of consecutive address.\n@end deffn\n\n@anchor{targetevents}\n@section Target Events\n@cindex target events\n@cindex events\nAt various times, certain things can happen, or you want them to happen.\nFor example:\n@itemize @bullet\n@item What should happen when GDB connects? Should your target reset?\n@item When GDB tries to flash the target, do you need to enable the flash via a special command?\n@item Is using SRST appropriate (and possible) on your system?\nOr instead of that, do you need to issue JTAG commands to trigger reset?\nSRST usually resets everything on the scan chain, which can be inappropriate.\n@item During reset, do you need to write to certain memory locations\nto set up system clocks or\nto reconfigure the SDRAM?\nHow about configuring the watchdog timer, or other peripherals,\nto stop running while you hold the core stopped for debugging?\n@end itemize\n\nAll of the above items can be addressed by target event handlers.\nThese are set up by @command{$target_name configure -event} or\n@command{target create ... -event}.\n\nThe programmer's model matches the @code{-command} option used in Tcl/Tk\nbuttons and events. The two examples below act the same, but one creates\nand invokes a small procedure while the other inlines it.\n\n@example\nproc my_init_proc @{ @} @{\n    echo \"Disabling watchdog...\"\n    mww 0xfffffd44 0x00008000\n@}\nmychip.cpu configure -event reset-init my_init_proc\nmychip.cpu configure -event reset-init @{\n    echo \"Disabling watchdog...\"\n    mww 0xfffffd44 0x00008000\n@}\n@end example\n\nThe following target events are defined:\n\n@itemize @bullet\n@item @b{debug-halted}\n@* The target has halted for debug reasons (i.e.: breakpoint)\n@item @b{debug-resumed}\n@* The target has resumed (i.e.: GDB said run)\n@item @b{early-halted}\n@* Occurs early in the halt process\n@item @b{examine-start}\n@* Before target examine is called.\n@item @b{examine-end}\n@* After target examine is called with no errors.\n@item @b{examine-fail}\n@* After target examine fails.\n@item @b{gdb-attach}\n@* When GDB connects. Issued before any GDB communication with the target\nstarts. GDB expects the target is halted during attachment.\n@xref{gdbmeminspect,,GDB as a non-intrusive memory inspector}, how to\nconnect GDB to running target.\nThe event can be also used to set up the target so it is possible to probe flash.\nProbing flash is necessary during GDB connect if you want to use\n@pxref{programmingusinggdb,,programming using GDB}.\nAnother use of the flash memory map is for GDB to automatically choose\nhardware or software breakpoints depending on whether the breakpoint\nis in RAM or read only memory.\nDefault is @code{halt}\n@item @b{gdb-detach}\n@* When GDB disconnects\n@item @b{gdb-end}\n@* When the target has halted and GDB is not doing anything (see early halt)\n@item @b{gdb-flash-erase-start}\n@* Before the GDB flash process tries to erase the flash (default is\n@code{reset init})\n@item @b{gdb-flash-erase-end}\n@* After the GDB flash process has finished erasing the flash\n@item @b{gdb-flash-write-start}\n@* Before GDB writes to the flash\n@item @b{gdb-flash-write-end}\n@* After GDB writes to the flash (default is @code{reset halt})\n@item @b{gdb-start}\n@* Before the target steps, GDB is trying to start/resume the target\n@item @b{halted}\n@* The target has halted\n@item @b{reset-assert-pre}\n@* Issued as part of @command{reset} processing\nafter @command{reset-start} was triggered\nbut before either SRST alone is asserted on the scan chain,\nor @code{reset-assert} is triggered.\n@item @b{reset-assert}\n@* Issued as part of @command{reset} processing\nafter @command{reset-assert-pre} was triggered.\nWhen such a handler is present, cores which support this event will use\nit instead of asserting SRST.\nThis support is essential for debugging with JTAG interfaces which\ndon't include an SRST line (JTAG doesn't require SRST), and for\nselective reset on scan chains that have multiple targets.\n@item @b{reset-assert-post}\n@* Issued as part of @command{reset} processing\nafter @code{reset-assert} has been triggered.\nor the target asserted SRST on the entire scan chain.\n@item @b{reset-deassert-pre}\n@* Issued as part of @command{reset} processing\nafter @code{reset-assert-post} has been triggered.\n@item @b{reset-deassert-post}\n@* Issued as part of @command{reset} processing\nafter @code{reset-deassert-pre} has been triggered\nand (if the target is using it) after SRST has been\nreleased on the scan chain.\n@item @b{reset-end}\n@* Issued as the final step in @command{reset} processing.\n@item @b{reset-init}\n@* Used by @b{reset init} command for board-specific initialization.\nThis event fires after @emph{reset-deassert-post}.\n\nThis is where you would configure PLLs and clocking, set up DRAM so\nyou can download programs that don't fit in on-chip SRAM, set up pin\nmultiplexing, and so on.\n(You may be able to switch to a fast JTAG clock rate here, after\nthe target clocks are fully set up.)\n@item @b{reset-start}\n@* Issued as the first step in @command{reset} processing\nbefore @command{reset-assert-pre} is called.\n\nThis is the most robust place to use @command{jtag_rclk}\nor @command{adapter speed} to switch to a low JTAG clock rate,\nwhen reset disables PLLs needed to use a fast clock.\n@item @b{resume-start}\n@* Before any target is resumed\n@item @b{resume-end}\n@* After all targets have resumed\n@item @b{resumed}\n@* Target has resumed\n@item @b{step-start}\n@* Before a target is single-stepped\n@item @b{step-end}\n@* After single-step has completed\n@item @b{trace-config}\n@* After target hardware trace configuration was changed\n@item @b{semihosting-user-cmd-0x100}\n@* The target made a semihosting call with user-defined operation number 0x100\n@item @b{semihosting-user-cmd-0x101}\n@* The target made a semihosting call with user-defined operation number 0x101\n@item @b{semihosting-user-cmd-0x102}\n@* The target made a semihosting call with user-defined operation number 0x102\n@item @b{semihosting-user-cmd-0x103}\n@* The target made a semihosting call with user-defined operation number 0x103\n@item @b{semihosting-user-cmd-0x104}\n@* The target made a semihosting call with user-defined operation number 0x104\n@item @b{semihosting-user-cmd-0x105}\n@* The target made a semihosting call with user-defined operation number 0x105\n@item @b{semihosting-user-cmd-0x106}\n@* The target made a semihosting call with user-defined operation number 0x106\n@item @b{semihosting-user-cmd-0x107}\n@* The target made a semihosting call with user-defined operation number 0x107\n@end itemize\n\n@quotation Note\nOpenOCD events are not supposed to be preempt by another event, but this\nis not enforced in current code. Only the target event @b{resumed} is\nexecuted with polling disabled; this avoids polling to trigger the event\n@b{halted}, reversing the logical order of execution of their handlers.\nFuture versions of OpenOCD will prevent the event preemption and will\ndisable the schedule of polling during the event execution. Do not rely\non polling in any event handler; this means, don't expect the status of\na core to change during the execution of the handler. The event handler\nwill have to enable polling or use @command{$target_name arp_poll} to\ncheck if the core has changed status.\n@end quotation\n\n@node Flash Commands\n@chapter Flash Commands\n\nOpenOCD has different commands for NOR and NAND flash;\nthe ``flash'' command works with NOR flash, while\nthe ``nand'' command works with NAND flash.\nThis partially reflects different hardware technologies:\nNOR flash usually supports direct CPU instruction and data bus access,\nwhile data from a NAND flash must be copied to memory before it can be\nused. (SPI flash must also be copied to memory before use.)\nHowever, the documentation also uses ``flash'' as a generic term;\nfor example, ``Put flash configuration in board-specific files''.\n\nFlash Steps:\n@enumerate\n@item Configure via the command @command{flash bank}\n@* Do this in a board-specific configuration file,\npassing parameters as needed by the driver.\n@item Operate on the flash via @command{flash subcommand}\n@* Often commands to manipulate the flash are typed by a human, or run\nvia a script in some automated way. Common tasks include writing a\nboot loader, operating system, or other data.\n@item GDB Flashing\n@* Flashing via GDB requires the flash be configured via ``flash\nbank'', and the GDB flash features be enabled.\n@xref{gdbconfiguration,,GDB Configuration}.\n@end enumerate\n\nMany CPUs have the ability to ``boot'' from the first flash bank.\nThis means that misprogramming that bank can ``brick'' a system,\nso that it can't boot.\nJTAG tools, like OpenOCD, are often then used to ``de-brick'' the\nboard by (re)installing working boot firmware.\n\n@anchor{norconfiguration}\n@section Flash Configuration Commands\n@cindex flash configuration\n\n@deffn {Config Command} {flash bank} name driver base size chip_width bus_width target [driver_options]\nConfigures a flash bank which provides persistent storage\nfor addresses from @math{base} to @math{base + size - 1}.\nThese banks will often be visible to GDB through the target's memory map.\nIn some cases, configuring a flash bank will activate extra commands;\nsee the driver-specific documentation.\n\n@itemize @bullet\n@item @var{name} ... may be used to reference the flash bank\nin other flash commands. A number is also available.\n@item @var{driver} ... identifies the controller driver\nassociated with the flash bank being declared.\nThis is usually @code{cfi} for external flash, or else\nthe name of a microcontroller with embedded flash memory.\n@xref{flashdriverlist,,Flash Driver List}.\n@item @var{base} ... Base address of the flash chip.\n@item @var{size} ... Size of the chip, in bytes.\nFor some drivers, this value is detected from the hardware.\n@item @var{chip_width} ... Width of the flash chip, in bytes;\nignored for most microcontroller drivers.\n@item @var{bus_width} ... Width of the data bus used to access the\nchip, in bytes; ignored for most microcontroller drivers.\n@item @var{target} ... Names the target used to issue\ncommands to the flash controller.\n@comment Actually, it's currently a controller-specific parameter...\n@item @var{driver_options} ... drivers may support, or require,\nadditional parameters. See the driver-specific documentation\nfor more information.\n@end itemize\n@quotation Note\nThis command is not available after OpenOCD initialization has completed.\nUse it in board specific configuration files, not interactively.\n@end quotation\n@end deffn\n\n@comment less confusing would be: \"flash list\" (like \"nand list\")\n@deffn {Command} {flash banks}\nPrints a one-line summary of each device that was\ndeclared using @command{flash bank}, numbered from zero.\nNote that this is the @emph{plural} form;\nthe @emph{singular} form is a very different command.\n@end deffn\n\n@deffn {Command} {flash list}\nRetrieves a list of associative arrays for each device that was\ndeclared using @command{flash bank}, numbered from zero.\nThis returned list can be manipulated easily from within scripts.\n@end deffn\n\n@deffn {Command} {flash probe} num\nIdentify the flash, or validate the parameters of the configured flash. Operation\ndepends on the flash type.\nThe @var{num} parameter is a value shown by @command{flash banks}.\nMost flash commands will implicitly @emph{autoprobe} the bank;\nflash drivers can distinguish between probing and autoprobing,\nbut most don't bother.\n@end deffn\n\n@section Preparing a Target before Flash Programming\n\nThe target device should be in well defined state before the flash programming\nbegins.\n\n@emph{Always issue} @command{reset init} before @ref{flashprogrammingcommands,,Flash Programming Commands}.\nDo not issue another @command{reset} or @command{reset halt} or @command{resume}\nuntil the programming session is finished.\n\nIf you use @ref{programmingusinggdb,,Programming using GDB},\nthe target is prepared automatically in the event gdb-flash-erase-start\n\nThe jimtcl script @command{program} calls @command{reset init} explicitly.\n\n@section Erasing, Reading, Writing to Flash\n@cindex flash erasing\n@cindex flash reading\n@cindex flash writing\n@cindex flash programming\n@anchor{flashprogrammingcommands}\n\nOne feature distinguishing NOR flash from NAND or serial flash technologies\nis that for read access, it acts exactly like any other addressable memory.\nThis means you can use normal memory read commands like @command{mdw} or\n@command{dump_image} with it, with no special @command{flash} subcommands.\n@xref{memoryaccess,,Memory access}, and @ref{imageaccess,,Image access}.\n\nWrite access works differently. Flash memory normally needs to be erased\nbefore it's written. Erasing a sector turns all of its bits to ones, and\nwriting can turn ones into zeroes. This is why there are special commands\nfor interactive erasing and writing, and why GDB needs to know which parts\nof the address space hold NOR flash memory.\n\n@quotation Note\nMost of these erase and write commands leverage the fact that NOR flash\nchips consume target address space. They implicitly refer to the current\nJTAG target, and map from an address in that target's address space\nback to a flash bank.\n@comment In May 2009, those mappings may fail if any bank associated\n@comment with that target doesn't successfully autoprobe ... bug worth fixing?\nA few commands use abstract addressing based on bank and sector numbers,\nand don't depend on searching the current target and its address space.\nAvoid confusing the two command models.\n@end quotation\n\nSome flash chips implement software protection against accidental writes,\nsince such buggy writes could in some cases ``brick'' a system.\nFor such systems, erasing and writing may require sector protection to be\ndisabled first.\nExamples include CFI flash such as ``Intel Advanced Bootblock flash'',\nand AT91SAM7 on-chip flash.\n@xref{flashprotect,,flash protect}.\n\n@deffn {Command} {flash erase_sector} num first last\nErase sectors in bank @var{num}, starting at sector @var{first}\nup to and including @var{last}.\nSector numbering starts at 0.\nProviding a @var{last} sector of @option{last}\nspecifies \"to the end of the flash bank\".\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {flash erase_address} [@option{pad}] [@option{unlock}] address length\nErase sectors starting at @var{address} for @var{length} bytes.\nUnless @option{pad} is specified, @math{address} must begin a\nflash sector, and @math{address + length - 1} must end a sector.\nSpecifying @option{pad} erases extra data at the beginning and/or\nend of the specified region, as needed to erase only full sectors.\nThe flash bank to use is inferred from the @var{address}, and\nthe specified length must stay within that bank.\nAs a special case, when @var{length} is zero and @var{address} is\nthe start of the bank, the whole flash is erased.\nIf @option{unlock} is specified, then the flash is unprotected\nbefore erase starts.\n@end deffn\n\n@deffn {Command} {flash filld} address double-word length\n@deffnx {Command} {flash fillw} address word length\n@deffnx {Command} {flash fillh} address halfword length\n@deffnx {Command} {flash fillb} address byte length\nFills flash memory with the specified @var{double-word} (64 bits), @var{word} (32 bits),\n@var{halfword} (16 bits), or @var{byte} (8-bit) pattern,\nstarting at @var{address} and continuing\nfor @var{length} units (word/halfword/byte).\nNo erasure is done before writing; when needed, that must be done\nbefore issuing this command.\nWrites are done in blocks of up to 1024 bytes, and each write is\nverified by reading back the data and comparing it to what was written.\nThe flash bank to use is inferred from the @var{address} of\neach block, and the specified length must stay within that bank.\n@end deffn\n@comment no current checks for errors if fill blocks touch multiple banks!\n\n@deffn {Command} {flash mdw} addr [count]\n@deffnx {Command} {flash mdh} addr [count]\n@deffnx {Command} {flash mdb} addr [count]\nDisplay contents of address @var{addr}, as\n32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),\nor 8-bit bytes (@command{mdb}).\nIf @var{count} is specified, displays that many units.\nReads from flash using the flash driver, therefore it enables reading\nfrom a bank not mapped in target address space.\nThe flash bank to use is inferred from the @var{address} of\neach block, and the specified length must stay within that bank.\n@end deffn\n\n@deffn {Command} {flash write_bank} num filename [offset]\nWrite the binary @file{filename} to flash bank @var{num},\nstarting at @var{offset} bytes from the beginning of the bank. If @var{offset}\nis omitted, start at the beginning of the flash bank.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {flash read_bank} num filename [offset [length]]\nRead @var{length} bytes from the flash bank @var{num} starting at @var{offset}\nand write the contents to the binary @file{filename}. If @var{offset} is\nomitted, start at the beginning of the flash bank. If @var{length} is omitted,\nread the remaining bytes from the flash bank.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {flash verify_bank} num filename [offset]\nCompare the contents of the binary file @var{filename} with the contents of the\nflash bank @var{num} starting at @var{offset}. If @var{offset} is omitted,\nstart at the beginning of the flash bank. Fail if the contents do not match.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {flash write_image} [erase] [unlock] filename [offset] [type]\nWrite the image @file{filename} to the current target's flash bank(s).\nOnly loadable sections from the image are written.\nA relocation @var{offset} may be specified, in which case it is added\nto the base address for each section in the image.\nThe file [@var{type}] can be specified\nexplicitly as @option{bin} (binary), @option{ihex} (Intel hex),\n@option{elf} (ELF file), @option{s19} (Motorola s19).\n@option{mem}, or @option{builder}.\nThe relevant flash sectors will be erased prior to programming\nif the @option{erase} parameter is given. If @option{unlock} is\nprovided, then the flash banks are unlocked before erase and\nprogram. The flash bank to use is inferred from the address of\neach image section.\n\n@quotation Warning\nBe careful using the @option{erase} flag when the flash is holding\ndata you want to preserve.\nPortions of the flash outside those described in the image's\nsections might be erased with no notice.\n@itemize\n@item\nWhen a section of the image being written does not fill out all the\nsectors it uses, the unwritten parts of those sectors are necessarily\nalso erased, because sectors can't be partially erased.\n@item\nData stored in sector \"holes\" between image sections are also affected.\nFor example, \"@command{flash write_image erase ...}\" of an image with\none byte at the beginning of a flash bank and one byte at the end\nerases the entire bank -- not just the two sectors being written.\n@end itemize\nAlso, when flash protection is important, you must re-apply it after\nit has been removed by the @option{unlock} flag.\n@end quotation\n\n@end deffn\n\n@deffn {Command} {flash verify_image} filename [offset] [type]\nVerify the image @file{filename} to the current target's flash bank(s).\nParameters follow the description of 'flash write_image'.\nIn contrast to the 'verify_image' command, for banks with specific\nverify method, that one is used instead of the usual target's read\nmemory methods. This is necessary for flash banks not readable by\nordinary memory reads.\nThis command gives only an overall good/bad result for each bank, not\naddresses of individual failed bytes as it's intended only as quick\ncheck for successful programming.\n@end deffn\n\n@section Other Flash commands\n@cindex flash protection\n\n@deffn {Command} {flash erase_check} num\nCheck erase state of sectors in flash bank @var{num},\nand display that status.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {flash info} num [sectors]\nPrint info about flash bank @var{num}, a list of protection blocks\nand their status. Use @option{sectors} to show a list of sectors instead.\n\nThe @var{num} parameter is a value shown by @command{flash banks}.\nThis command will first query the hardware, it does not print cached\nand possibly stale information.\n@end deffn\n\n@anchor{flashprotect}\n@deffn {Command} {flash protect} num first last (@option{on}|@option{off})\nEnable (@option{on}) or disable (@option{off}) protection of flash blocks\nin flash bank @var{num}, starting at protection block @var{first}\nand continuing up to and including @var{last}.\nProviding a @var{last} block of @option{last}\nspecifies \"to the end of the flash bank\".\nThe @var{num} parameter is a value shown by @command{flash banks}.\nThe protection block is usually identical to a flash sector.\nSome devices may utilize a protection block distinct from flash sector.\nSee @command{flash info} for a list of protection blocks.\n@end deffn\n\n@deffn {Command} {flash padded_value} num value\nSets the default value used for padding any image sections, This should\nnormally match the flash bank erased value. If not specified by this\ncommand or the flash driver then it defaults to 0xff.\n@end deffn\n\n@anchor{program}\n@deffn {Command} {program} filename [preverify] [verify] [reset] [exit] [offset]\nThis is a helper script that simplifies using OpenOCD as a standalone\nprogrammer. The only required parameter is @option{filename}, the others are optional.\n@xref{Flash Programming}.\n@end deffn\n\n@anchor{flashdriverlist}\n@section Flash Driver List\nAs noted above, the @command{flash bank} command requires a driver name,\nand allows driver-specific options and behaviors.\nSome drivers also activate driver-specific commands.\n\n@deffn {Flash Driver} {virtual}\nThis is a special driver that maps a previously defined bank to another\naddress. All bank settings will be copied from the master physical bank.\n\nThe @var{virtual} driver defines one mandatory parameters,\n\n@itemize\n@item @var{master_bank} The bank that this virtual address refers to.\n@end itemize\n\nSo in the following example addresses 0xbfc00000 and 0x9fc00000 refer to\nthe flash bank defined at address 0x1fc00000. Any command executed on\nthe virtual banks is actually performed on the physical banks.\n@example\nflash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\nflash bank vbank0 virtual 0xbfc00000 0 0 0 \\\n           $_TARGETNAME $_FLASHNAME\nflash bank vbank1 virtual 0x9fc00000 0 0 0 \\\n           $_TARGETNAME $_FLASHNAME\n@end example\n@end deffn\n\n@subsection External Flash\n\n@deffn {Flash Driver} {cfi}\n@cindex Common Flash Interface\n@cindex CFI\nThe ``Common Flash Interface'' (CFI) is the main standard for\nexternal NOR flash chips, each of which connects to a\nspecific external chip select on the CPU.\nFrequently the first such chip is used to boot the system.\nYour board's @code{reset-init} handler might need to\nconfigure additional chip selects using other commands (like: @command{mww} to\nconfigure a bus and its timings), or\nperhaps configure a GPIO pin that controls the ``write protect'' pin\non the flash chip.\nThe CFI driver can use a target-specific working area to significantly\nspeed up operation.\n\nThe CFI driver can accept the following optional parameters, in any order:\n\n@itemize\n@item @var{jedec_probe} ... is used to detect certain non-CFI flash ROMs,\nlike AM29LV010 and similar types.\n@item @var{x16_as_x8} ... when a 16-bit flash is hooked up to an 8-bit bus.\n@item @var{bus_swap} ... when data bytes in a 16-bit flash needs to be swapped.\n@item @var{data_swap} ... when data bytes in a 16-bit flash needs to be\nswapped when writing data values (i.e. not CFI commands).\n@end itemize\n\nTo configure two adjacent banks of 16 MBytes each, both sixteen bits (two bytes)\nwide on a sixteen bit bus:\n\n@example\nflash bank $_FLASHNAME cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\nflash bank $_FLASHNAME cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n@end example\n\nTo configure one bank of 32 MBytes\nbuilt from two sixteen bit (two byte) wide parts wired in parallel\nto create a thirty-two bit (four byte) bus with doubled throughput:\n\n@example\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n@end example\n\n@c \"cfi part_id\" disabled\n@end deffn\n\n@deffn {Flash Driver} {jtagspi}\n@cindex Generic JTAG2SPI driver\n@cindex SPI\n@cindex jtagspi\n@cindex bscan_spi\nSeveral FPGAs and CPLDs can retrieve their configuration (bitstream) from a\nSPI flash connected to them. To access this flash from the host, the device\nis first programmed with a special proxy bitstream that\nexposes the SPI flash on the device's JTAG interface. The flash can then be\naccessed through JTAG.\n\nSince signaling between JTAG and SPI is compatible, all that is required for\na proxy bitstream is to connect TDI-MOSI, TDO-MISO, TCK-CLK and activate\nthe flash chip select when the JTAG state machine is in SHIFT-DR. Such\na bitstream for several Xilinx FPGAs can be found in\n@file{contrib/loaders/flash/fpga/xilinx_bscan_spi.py}. It requires\n@uref{https://github.com/m-labs/migen, migen} and a Xilinx toolchain to build.\n\nThis flash bank driver requires a target on a JTAG tap and will access that\ntap directly. Since no support from the target is needed, the target can be a\n\"testee\" dummy. Since the target does not expose the flash memory\nmapping, target commands that would otherwise be expected to access the flash\nwill not work. These include all @command{*_image} and\n@command{$target_name m*} commands as well as @command{program}. Equivalent\nfunctionality is available through the @command{flash write_bank},\n@command{flash read_bank}, and @command{flash verify_bank} commands.\n\nAccording to device size, 1- to 4-byte addresses are sent. However, some\nflash chips additionally have to be switched to 4-byte addresses by an extra\ncommand, see below.\n\n@itemize\n@item @var{ir} ... is loaded into the JTAG IR to map the flash as the JTAG DR.\nFor the bitstreams generated from @file{xilinx_bscan_spi.py} this is the\n@var{USER1} instruction.\n@end itemize\n\n@example\ntarget create $_TARGETNAME testee -chain-position $_CHIPNAME.fpga\nset _XILINX_USER1 0x02\nflash bank $_FLASHNAME spi 0x0 0 0 0 \\\n           $_TARGETNAME $_XILINX_USER1\n@end example\n\n@deffn Command {jtagspi set} bank_id name total_size page_size read_cmd unused pprg_cmd mass_erase_cmd sector_size sector_erase_cmd\nSets flash parameters: @var{name} human readable string, @var{total_size}\nsize in bytes, @var{page_size} is write page size. @var{read_cmd} and @var{pprg_cmd}\nare commands for read and page program, respectively. @var{mass_erase_cmd},\n@var{sector_size} and @var{sector_erase_cmd} are optional.\n@example\njtagspi set 0 w25q128 0x1000000 0x100 0x03 0 0x02 0xC7 0x10000 0xD8\n@end example\n@end deffn\n\n@deffn Command {jtagspi cmd} bank_id resp_num cmd_byte ...\nSends command @var{cmd_byte} and at most 20 following bytes and reads\n@var{resp_num} bytes afterwards. E.g. for 'Enter 4-byte address mode'\n@example\njtagspi cmd 0 0 0xB7\n@end example\n@end deffn\n\n@deffn Command {jtagspi always_4byte} bank_id [ on | off ]\nSome devices use 4-byte addresses for all commands except the legacy 0x03 read\nregardless of device size. This command controls the corresponding hack.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {xcf}\n@cindex Xilinx Platform flash driver\n@cindex xcf\nXilinx FPGAs can be configured from specialized flash ICs named Platform Flash.\nIt is (almost) regular NOR flash with erase sectors, program pages, etc. The\nonly difference is special registers controlling its FPGA specific behavior.\nThey must be properly configured for successful FPGA loading using\nadditional @var{xcf} driver command:\n\n@deffn {Command} {xcf ccb} <bank_id>\ncommand accepts additional parameters:\n@itemize\n@item @var{external|internal} ... selects clock source.\n@item @var{serial|parallel} ... selects serial or parallel data bus mode.\n@item @var{slave|master} ... selects slave of master mode for flash device.\n@item @var{40|20} ... selects clock frequency in MHz for internal clock\nin master mode.\n@end itemize\n@example\nxcf ccb 0 external parallel slave 40\n@end example\nAll of them must be specified even if clock frequency is pointless\nin slave mode. If only bank id specified than command prints current\nCCB register value. Note: there is no need to write this register\nevery time you erase/program data sectors because it stores in\ndedicated sector.\n@end deffn\n\n@deffn {Command} {xcf configure} <bank_id>\nInitiates FPGA loading procedure. Useful if your board has no \"configure\"\nbutton.\n@example\nxcf configure 0\n@end example\n@end deffn\n\nAdditional driver notes:\n@itemize\n@item Only single revision supported.\n@item Driver automatically detects need of bit reverse, but\nonly \"bin\" (raw binary, do not confuse it with \"bit\") and \"mcs\"\n(Intel hex) file types supported.\n@item For additional info check xapp972.pdf and ug380.pdf.\n@end itemize\n@end deffn\n\n@deffn {Flash Driver} {lpcspifi}\n@cindex NXP SPI Flash Interface\n@cindex SPIFI\n@cindex lpcspifi\nNXP's LPC43xx and LPC18xx families include a proprietary SPI\nFlash Interface (SPIFI) peripheral that can drive and provide\nmemory mapped access to external SPI flash devices.\n\nThe lpcspifi driver initializes this interface and provides\nprogram and erase functionality for these serial flash devices.\nUse of this driver @b{requires} a working area of at least 1kB\nto be configured on the target device; more than this will\nsignificantly reduce flash programming times.\n\nThe setup command only requires the @var{base} parameter. All\nother parameters are ignored, and the flash size and layout\nare configured by the driver.\n\n@example\nflash bank $_FLASHNAME lpcspifi 0x14000000 0 0 0 $_TARGETNAME\n@end example\n\n@end deffn\n\n@deffn {Flash Driver} {stmsmi}\n@cindex STMicroelectronics Serial Memory Interface\n@cindex SMI\n@cindex stmsmi\nSome devices from STMicroelectronics (e.g. STR75x MCU family,\nSPEAr MPU family) include a proprietary\n``Serial Memory Interface'' (SMI) controller able to drive external\nSPI flash devices.\nDepending on specific device and board configuration, up to 4 external\nflash devices can be connected.\n\nSMI makes the flash content directly accessible in the CPU address\nspace; each external device is mapped in a memory bank.\nCPU can directly read data, execute code and boot from SMI banks.\nNormal OpenOCD commands like @command{mdw} can be used to display\nthe flash content.\n\nThe setup command only requires the @var{base} parameter in order\nto identify the memory bank.\nAll other parameters are ignored. Additional information, like\nflash size, are detected automatically.\n\n@example\nflash bank $_FLASHNAME stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n@end example\n\n@end deffn\n\n@deffn {Flash Driver} {stmqspi}\n@cindex STMicroelectronics QuadSPI/OctoSPI Interface\n@cindex QuadSPI\n@cindex OctoSPI\n@cindex stmqspi\nSome devices from STMicroelectronics include a proprietary ``QuadSPI Interface''\n(e.g. STM32F4, STM32F7, STM32L4) or ``OctoSPI Interface'' (e.g. STM32L4+)\ncontroller able to drive one or even two (dual mode) external SPI flash devices.\nThe OctoSPI is a superset of QuadSPI, its presence is detected automatically.\nCurrently only the regular command mode is supported, whereas the HyperFlash\nmode is not.\n\nQuadSPI/OctoSPI makes the flash contents directly accessible in the CPU address\nspace; in case of dual mode both devices must be of the same type and are\nmapped in the same memory bank (even and odd addresses interleaved).\nCPU can directly read data, execute code (but not boot) from QuadSPI bank.\n\nThe 'flash bank' command only requires the @var{base} parameter and the extra\nparameter @var{io_base} in order to identify the memory bank. Both are fixed\nby hardware, see datasheet or RM. All other parameters are ignored.\n\nThe controller must be initialized after each reset and properly configured\nfor memory-mapped read operation for the particular flash chip(s), for the full\nlist of available register settings cf. the controller's RM. This setup is quite\nboard specific (that's why booting from this memory is not possible). The\nflash driver infers all parameters from current controller register values when\n'flash probe @var{bank_id}' is executed.\n\nNormal OpenOCD commands like @command{mdw} can be used to display the flash content,\nbut only after proper controller initialization as described above. However,\ndue to a silicon bug in some devices, attempting to access the very last word\nshould be avoided.\n\nIt is possible to use two (even different) flash chips alternatingly, if individual\nbank chip selects are available. For some package variants, this is not the case\ndue to limited pin count. To switch from one to another, adjust FSEL bit accordingly\nand re-issue 'flash probe bank_id'. Note that the bank base address will @emph{not}\nchange, so the address spaces of both devices will overlap. In dual flash mode\nboth chips must be identical regarding size and most other properties.\n\nBlock or sector protection internal to the flash chip is not handled by this\ndriver at all, but can be dealt with manually by the 'cmd' command, see below.\nThe sector protection via 'flash protect' command etc. is completely internal to\nopenocd, intended only to prevent accidental erase or overwrite and it does not\npersist across openocd invocations.\n\nOpenOCD contains a hardcoded list of flash devices with their properties,\nthese are auto-detected. If a device is not included in this list, SFDP discovery\nis attempted. If this fails or gives inappropriate results, manual setting is\nrequired (see 'set' command).\n\n@example\nflash bank $_FLASHNAME stmqspi 0x90000000 0 0 0 \\\n           $_TARGETNAME 0xA0001000\nflash bank $_FLASHNAME stmqspi 0x70000000 0 0 0 \\\n           $_TARGETNAME 0xA0001400\n@end example\n\nThere are three specific commands\n@deffn {Command} {stmqspi mass_erase} bank_id\nClears sector protections and performs a mass erase. Works only if there is no\nchip specific write protection engaged.\n@end deffn\n\n@deffn {Command} {stmqspi set} bank_id name total_size page_size read_cmd fread_cmd pprg_cmd mass_erase_cmd sector_size sector_erase_cmd\nSet flash parameters: @var{name} human readable string, @var{total_size} size\nin bytes, @var{page_size} is write page size. @var{read_cmd}, @var{fread_cmd} and @var{pprg_cmd}\nare commands for reading and page programming. @var{fread_cmd} is used in DPI and QPI modes,\n@var{read_cmd} in normal SPI (single line) mode. @var{mass_erase_cmd}, @var{sector_size}\nand @var{sector_erase_cmd} are optional.\n\nThis command is required if chip id is not hardcoded yet and e.g. for EEPROMs or FRAMs\nwhich don't support an id command.\n\nIn dual mode parameters of both chips are set identically. The parameters refer to\na single chip, so the whole bank gets twice the specified capacity etc.\n@end deffn\n\n@deffn {Command} {stmqspi cmd} bank_id resp_num cmd_byte ...\nIf @var{resp_num} is zero, sends command @var{cmd_byte} and following data\nbytes. In dual mode command byte is sent to @emph{both} chips but data bytes are\nsent @emph{alternatingly} to chip 1 and 2, first to flash 1, second to flash 2, etc.,\ni.e. the total number of bytes (including cmd_byte) must be odd.\n\nIf @var{resp_num} is not zero, cmd and at most four following data bytes are\nsent, in dual mode @emph{simultaneously} to both chips. Then @var{resp_num} bytes\nare read interleaved from both chips starting with chip 1. In this case\n@var{resp_num} must be even.\n\nNote the hardware dictated subtle difference of those two cases in dual-flash mode.\n\nTo check basic communication settings, issue\n@example\nstmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 1 0x05\nstmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 1 0x05\n@end example\nfor single flash mode or\n@example\nstmqspi cmd bank_id 0 0x04; stmqspi cmd bank_id 2 0x05\nstmqspi cmd bank_id 0 0x06; stmqspi cmd bank_id 2 0x05\n@end example\nfor dual flash mode. This should return the status register contents.\n\nIn 8-line mode, @var{cmd_byte} is sent twice - first time as given, second time\ncomplemented. Additionally, in 8-line mode only, some commands (e.g. Read Status)\nneed a dummy address, e.g.\n@example\nstmqspi cmd bank_id 1 0x05 0x00 0x00 0x00 0x00\n@end example\nshould return the status register contents.\n\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {mrvlqspi}\nThis driver supports QSPI flash controller of Marvell's Wireless\nMicrocontroller platform.\n\nThe flash size is autodetected based on the table of known JEDEC IDs\nhardcoded in the OpenOCD sources.\n\n@example\nflash bank $_FLASHNAME mrvlqspi 0x0 0 0 0 $_TARGETNAME 0x46010000\n@end example\n\n@end deffn\n\n@deffn {Flash Driver} {ath79}\n@cindex Atheros ath79 SPI driver\n@cindex ath79\nMembers of ATH79 SoC family from Atheros include a SPI interface with 3\nchip selects.\nOn reset a SPI flash connected to the first chip select (CS0) is made\ndirectly read-accessible in the CPU address space (up to 16MBytes)\nand is usually used to store the bootloader and operating system.\nNormal OpenOCD commands like @command{mdw} can be used to display\nthe flash content while it is in memory-mapped mode (only the first\n4MBytes are accessible without additional configuration on reset).\n\nThe setup command only requires the @var{base} parameter in order\nto identify the memory bank. The actual value for the base address\nis not otherwise used by the driver. However the mapping is passed\nto gdb. Thus for the memory mapped flash (chipselect CS0) the base\naddress should be the actual memory mapped base address. For unmapped\nchipselects (CS1 and CS2) care should be taken to use a base address\nthat does not overlap with real memory regions.\nAdditional information, like flash size, are detected automatically.\nAn optional additional parameter sets the chipselect for the bank,\nwith the default CS0.\nCS1 and CS2 require additional GPIO setup before they can be used\nsince the alternate function must be enabled on the GPIO pin\nCS1/CS2 is routed to on the given SoC.\n\n@example\nflash bank $_FLASHNAME ath79 0xbf000000 0 0 0 $_TARGETNAME\n\n# When using multiple chipselects the base should be different\n# for each, otherwise the write_image command is not able to\n# distinguish the banks.\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\nflash bank flash1 ath79 0x10000000 0 0 0 $_TARGETNAME cs1\nflash bank flash2 ath79 0x20000000 0 0 0 $_TARGETNAME cs2\n@end example\n\n@end deffn\n\n@deffn {Flash Driver} {fespi}\n@cindex Freedom E SPI\n@cindex fespi\n\nSiFive's Freedom E SPI controller, used in HiFive and other boards.\n\n@example\nflash bank $_FLASHNAME fespi 0x20000000 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@subsection Internal Flash (Microcontrollers)\n\n@deffn {Flash Driver} {aduc702x}\nThe ADUC702x analog microcontrollers from Analog Devices\ninclude internal flash and use ARM7TDMI cores.\nThe aduc702x flash driver works with models ADUC7019 through ADUC7028.\nThe setup command only requires the @var{target} argument\nsince all devices in this family have the same memory layout.\n\n@example\nflash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {ambiqmicro}\n@cindex ambiqmicro\n@cindex apollo\nAll members of the Apollo microcontroller family from\nAmbiq Micro include internal flash and use ARM's Cortex-M4 core.\nThe host connects over USB to an FTDI interface that communicates\nwith the target using SWD.\n\nThe @var{ambiqmicro} driver reads the Chip Information Register detect\nthe device class of the MCU.\nThe Flash and SRAM sizes directly follow device class, and are used\nto set up the flash banks.\nIf this fails, the driver will use default values set to the minimum\nsizes of an Apollo chip.\n\nAll Apollo chips have two flash banks of the same size.\nIn all cases the first flash bank starts at location 0,\nand the second bank starts after the first.\n\n@example\n# Flash bank 0\nflash bank $_FLASHNAME ambiqmicro 0 0x00040000 0 0 $_TARGETNAME\n# Flash bank 1 - same size as bank0, starts after bank 0.\nflash bank $_FLASHNAME ambiqmicro 0x00040000 0x00040000 0 0 \\\n           $_TARGETNAME\n@end example\n\nFlash is programmed using custom entry points into the bootloader.\nThis is the only way to program the flash as no flash control registers\nare available to the user.\n\nThe @var{ambiqmicro} driver adds some additional commands:\n\n@deffn {Command} {ambiqmicro mass_erase} <bank>\nErase entire bank.\n@end deffn\n@deffn {Command} {ambiqmicro page_erase} <bank> <first> <last>\nErase device pages.\n@end deffn\n@deffn {Command} {ambiqmicro program_otp} <bank> <offset> <count>\nProgram OTP is a one time operation to create write protected flash.\nThe user writes sectors to SRAM starting at 0x10000010.\nProgram OTP will write these sectors from SRAM to flash, and write protect\nthe flash.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {at91samd}\n@cindex at91samd\nAll members of the ATSAM D2x, D1x, D0x, ATSAMR, ATSAML and ATSAMC microcontroller\nfamilies from Atmel include internal flash and use ARM's Cortex-M0+ core.\n\nDo not use for ATSAM D51 and E5x: use @xref{atsame5}.\n\nThe devices have one flash bank:\n\n@example\nflash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n@end example\n\n@deffn {Command} {at91samd chip-erase}\nIssues a complete Flash erase via the Device Service Unit (DSU). This can be\nused to erase a chip back to its factory state and does not require the\nprocessor to be halted.\n@end deffn\n\n@deffn {Command} {at91samd set-security}\nSecures the Flash via the Set Security Bit (SSB) command. This prevents access\nto the Flash and can only be undone by using the chip-erase command which\nerases the Flash contents and turns off the security bit. Warning: at this\ntime, openocd will not be able to communicate with a secured chip and it is\ntherefore not possible to chip-erase it without using another tool.\n\n@example\nat91samd set-security enable\n@end example\n@end deffn\n\n@deffn {Command} {at91samd eeprom}\nShows or sets the EEPROM emulation size configuration, stored in the User Row\nof the Flash. When setting, the EEPROM size must be specified in bytes and it\nmust be one of the permitted sizes according to the datasheet. Settings are\nwritten immediately but only take effect on MCU reset. EEPROM emulation\nrequires additional firmware support and the minimum EEPROM size may not be\nthe same as the minimum that the hardware supports. Set the EEPROM size to 0\nin order to disable this feature.\n\n@example\nat91samd eeprom\nat91samd eeprom 1024\n@end example\n@end deffn\n\n@deffn {Command} {at91samd bootloader}\nShows or sets the bootloader size configuration, stored in the User Row of the\nFlash. This is called the BOOTPROT region. When setting, the bootloader size\nmust be specified in bytes and it must be one of the permitted sizes according\nto the datasheet. Settings are written immediately but only take effect on\nMCU reset. Setting the bootloader size to 0 disables bootloader protection.\n\n@example\nat91samd bootloader\nat91samd bootloader 16384\n@end example\n@end deffn\n\n@deffn {Command} {at91samd dsu_reset_deassert}\nThis command releases internal reset held by DSU\nand prepares reset vector catch in case of reset halt.\nCommand is used internally in event reset-deassert-post.\n@end deffn\n\n@deffn {Command} {at91samd nvmuserrow}\nWrites or reads the entire 64 bit wide NVM user row register which is located at\n0x804000. This register includes various fuses lock-bits and factory calibration\ndata. Reading the register is done by invoking this command without any\narguments. Writing is possible by giving 1 or 2 hex values. The first argument\nis the register value to be written and the second one is an optional changemask.\nEvery bit which value in changemask is 0 will stay unchanged. The lock- and\nreserved-bits are masked out and cannot be changed.\n\n@example\n# Read user row\n>at91samd nvmuserrow\nNVMUSERROW: 0xFFFFFC5DD8E0C788\n# Write 0xFFFFFC5DD8E0C788 to user row\n>at91samd nvmuserrow 0xFFFFFC5DD8E0C788\n# Write 0x12300 to user row but leave other bits and low\n# byte unchanged\n>at91samd nvmuserrow 0x12345 0xFFF00\n@end example\n@end deffn\n\n@end deffn\n\n@anchor{at91sam3}\n@deffn {Flash Driver} {at91sam3}\n@cindex at91sam3\nAll members of the AT91SAM3 microcontroller family from\nAtmel include internal flash and use ARM's Cortex-M3 core. The driver\ncurrently (6/22/09) recognizes the AT91SAM3U[1/2/4][C/E] chips. Note\nthat the driver was orginaly developed and tested using the\nAT91SAM3U4E, using a SAM3U-EK eval board. Support for other chips in\nthe family was cribbed from the data sheet. @emph{Note to future\nreaders/updaters: Please remove this worrisome comment after other\nchips are confirmed.}\n\nThe AT91SAM3U4[E/C] (256K) chips have two flash banks; most other chips\nhave one flash bank. In all cases the flash banks are at\nthe following fixed locations:\n\n@example\n# Flash bank 0 - all chips\nflash bank $_FLASHNAME at91sam3 0x00080000 0 1 1 $_TARGETNAME\n# Flash bank 1 - only 256K chips\nflash bank $_FLASHNAME at91sam3 0x00100000 0 1 1 $_TARGETNAME\n@end example\n\nInternally, the AT91SAM3 flash memory is organized as follows.\nUnlike the AT91SAM7 chips, these are not used as parameters\nto the @command{flash bank} command:\n\n@itemize\n@item @emph{N-Banks:} 256K chips have 2 banks, others have 1 bank.\n@item @emph{Bank Size:} 128K/64K Per flash bank\n@item @emph{Sectors:} 16 or 8 per bank\n@item @emph{SectorSize:} 8K Per Sector\n@item @emph{PageSize:} 256 bytes per page. Note that OpenOCD operates on 'sector' sizes, not page sizes.\n@end itemize\n\nThe AT91SAM3 driver adds some additional commands:\n\n@deffn {Command} {at91sam3 gpnvm}\n@deffnx {Command} {at91sam3 gpnvm clear} number\n@deffnx {Command} {at91sam3 gpnvm set} number\n@deffnx {Command} {at91sam3 gpnvm show} [@option{all}|number]\nWith no parameters, @command{show} or @command{show all},\nshows the status of all GPNVM bits.\nWith @command{show} @var{number}, displays that bit.\n\nWith @command{set} @var{number} or @command{clear} @var{number},\nmodifies that GPNVM bit.\n@end deffn\n\n@deffn {Command} {at91sam3 info}\nThis command attempts to display information about the AT91SAM3\nchip. @emph{First} it read the @code{CHIPID_CIDR} [address 0x400e0740, see\nSection 28.2.1, page 505 of the AT91SAM3U 29/may/2009 datasheet,\ndocument id: doc6430A] and decodes the values. @emph{Second} it reads the\nvarious clock configuration registers and attempts to display how it\nbelieves the chip is configured. By default, the SLOWCLK is assumed to\nbe 32768 Hz, see the command @command{at91sam3 slowclk}.\n@end deffn\n\n@deffn {Command} {at91sam3 slowclk} [value]\nThis command shows/sets the slow clock frequency used in the\n@command{at91sam3 info} command calculations above.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {at91sam4}\n@cindex at91sam4\nAll members of the AT91SAM4 microcontroller family from\nAtmel include internal flash and use ARM's Cortex-M4 core.\nThis driver uses the same command names/syntax as @xref{at91sam3}.\n@end deffn\n\n@deffn {Flash Driver} {at91sam4l}\n@cindex at91sam4l\nAll members of the AT91SAM4L microcontroller family from\nAtmel include internal flash and use ARM's Cortex-M4 core.\nThis driver uses the same command names/syntax as @xref{at91sam3}.\n\nThe AT91SAM4L driver adds some additional commands:\n@deffn {Command} {at91sam4l smap_reset_deassert}\nThis command releases internal reset held by SMAP\nand prepares reset vector catch in case of reset halt.\nCommand is used internally in event reset-deassert-post.\n@end deffn\n@end deffn\n\n@anchor{atsame5}\n@deffn {Flash Driver} {atsame5}\n@cindex atsame5\nAll members of the SAM E54, E53, E51 and D51 microcontroller\nfamilies from Microchip (former Atmel) include internal flash\nand use ARM's Cortex-M4 core.\n\nThe devices have two ECC flash banks with a swapping feature.\nThis driver handles both banks together as it were one.\nBank swapping is not supported yet.\n\n@example\nflash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n@end example\n\n@deffn {Command} {atsame5 bootloader}\nShows or sets the bootloader size configuration, stored in the User Page of the\nFlash. This is called the BOOTPROT region. When setting, the bootloader size\nmust be specified in bytes. The nearest bigger protection size is used.\nSettings are written immediately but only take effect on MCU reset.\nSetting the bootloader size to 0 disables bootloader protection.\n\n@example\natsame5 bootloader\natsame5 bootloader 16384\n@end example\n@end deffn\n\n@deffn {Command} {atsame5 chip-erase}\nIssues a complete Flash erase via the Device Service Unit (DSU). This can be\nused to erase a chip back to its factory state and does not require the\nprocessor to be halted.\n@end deffn\n\n@deffn {Command} {atsame5 dsu_reset_deassert}\nThis command releases internal reset held by DSU\nand prepares reset vector catch in case of reset halt.\nCommand is used internally in event reset-deassert-post.\n@end deffn\n\n@deffn {Command} {atsame5 userpage}\nWrites or reads the first 64 bits of NVM User Page which is located at\n0x804000. This field includes various fuses.\nReading is done by invoking this command without any arguments.\nWriting is possible by giving 1 or 2 hex values. The first argument\nis the value to be written and the second one is an optional bit mask\n(a zero bit in the mask means the bit stays unchanged).\nThe reserved fields are always masked out and cannot be changed.\n\n@example\n# Read\n>atsame5 userpage\nUSER PAGE: 0xAEECFF80FE9A9239\n# Write\n>atsame5 userpage 0xAEECFF80FE9A9239\n# Write 2 to SEESBLK and 4 to SEEPSZ fields but leave other\n# bits unchanged (setup SmartEEPROM of virtual size 8192\n# bytes)\n>atsame5 userpage 0x4200000000 0x7f00000000\n@end example\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {atsamv}\n@cindex atsamv\nAll members of the ATSAMV7x, ATSAMS70, and ATSAME70 families from\nAtmel include internal flash and use ARM's Cortex-M7 core.\nThis driver uses the same command names/syntax as @xref{at91sam3}.\n\n@example\nflash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {atsamv gpnvm} [@option{show} [@option{all}|number]]\n@deffnx {Command} {atsamv gpnvm} (@option{clr}|@option{set}) number\nWith no parameters, @option{show} or @option{show all},\nshows the status of all GPNVM bits.\nWith @option{show} @var{number}, displays that bit.\n\nWith @option{set} @var{number} or @option{clear} @var{number},\nmodifies that GPNVM bit.\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {at91sam7}\nAll members of the AT91SAM7 microcontroller family from Atmel include\ninternal flash and use ARM7TDMI cores. The driver automatically\nrecognizes a number of these chips using the chip identification\nregister, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME\n@end example\n\nFor chips which are not recognized by the controller driver, you must\nprovide additional parameters in the following order:\n\n@itemize\n@item @var{chip_model} ... label used with @command{flash info}\n@item @var{banks}\n@item @var{sectors_per_bank}\n@item @var{pages_per_sector}\n@item @var{pages_size}\n@item @var{num_nvm_bits}\n@item @var{freq_khz} ... required if an external clock is provided,\noptional (but recommended) when the oscillator frequency is known\n@end itemize\n\nIt is recommended that you provide zeroes for all of those values\nexcept the clock frequency, so that everything except that frequency\nwill be autoconfigured.\nKnowing the frequency helps ensure correct timings for flash access.\n\nThe flash controller handles erases automatically on a page (128/256 byte)\nbasis, so explicit erase commands are not necessary for flash programming.\nHowever, there is an ``EraseAll`` command that can erase an entire flash\nplane (of up to 256KB), and it will be used automatically when you issue\n@command{flash erase_sector} or @command{flash erase_address} commands.\n\n@deffn {Command} {at91sam7 gpnvm} bitnum (@option{set}|@option{clear})\nSet or clear a ``General Purpose Non-Volatile Memory'' (GPNVM)\nbit for the processor. Each processor has a number of such bits,\nused for controlling features such as brownout detection (so they\nare not truly general purpose).\n@quotation Note\nThis assumes that the first flash bank (number 0) is associated with\nthe appropriate at91sam7 target.\n@end quotation\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {avr}\nThe AVR 8-bit microcontrollers from Atmel integrate flash memory.\n@emph{The current implementation is incomplete.}\n@comment - defines mass_erase ... pointless given flash_erase_address\n@end deffn\n\n@deffn {Flash Driver} {bluenrg-x}\nSTMicroelectronics BlueNRG-1, BlueNRG-2 and BlueNRG-LP/LPS Bluetooth low energy wireless system-on-chip. They include ARM Cortex-M0/M0+ core and internal flash memory.\nThe driver automatically recognizes these chips using\nthe chip identification registers, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n@end example\n\nNote that when users ask to erase all the sectors of the flash, a mass erase command is used which is faster than erasing\neach single sector one by one.\n\n@example\nflash erase_sector 0 0 last # It will perform a mass erase\n@end example\n\nTriggering a mass erase is also useful when users want to disable readout protection.\n@end deffn\n\n@deffn {Flash Driver} {cc26xx}\nAll versions of the SimpleLink CC13xx and CC26xx microcontrollers from Texas\nInstruments include internal flash. The cc26xx flash driver supports both the\nCC13xx and CC26xx family of devices. The driver automatically recognizes the\nspecific version's flash parameters and autoconfigures itself. The flash bank\nstarts at address 0.\n\n@example\nflash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {cc3220sf}\nThe CC3220SF version of the SimpleLink CC32xx microcontrollers from Texas\nInstruments includes 1MB of internal flash. The cc3220sf flash driver only\nsupports the internal flash. The serial flash on SimpleLink boards is\nprogrammed via the bootloader over a UART connection. Security features of\nthe CC3220SF may erase the internal flash during power on reset. Refer to\ndocumentation at @url{www.ti.com/cc3220sf} for details on security features\nand programming the serial flash.\n\n@example\nflash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {efm32}\nAll members of the EFM32/EFR32 microcontroller family from Energy Micro (now Silicon Labs)\ninclude internal flash and use Arm Cortex-M3 or Cortex-M4 cores. The driver automatically\nrecognizes a number of these chips using the chip identification register, and\nautoconfigures itself.\n@example\nflash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\n@end example\nIt supports writing to the user data page, as well as the portion of the lockbits page\npast 512 bytes on chips with larger page sizes. The latter is used by the SiLabs\nbootloader/AppLoader system for encryption keys. Setting protection on these pages is\ncurrently not supported.\n@example\nflash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\nflash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n@end example\n\nA special feature of efm32 controllers is that it is possible to completely disable the\ndebug interface by writing the correct values to the 'Debug Lock Word'. OpenOCD supports\nthis via the following command:\n@example\nefm32 debuglock num\n@end example\nThe @var{num} parameter is a value shown by @command{flash banks}.\nNote that in order for this command to take effect, the target needs to be reset.\n@emph{The current implementation is incomplete. Unprotecting flash pages is not\nsupported.}\n@end deffn\n\n@deffn {Flash Driver} {esirisc}\nMembers of the eSi-RISC family may optionally include internal flash programmed\nvia the eSi-TSMC Flash interface. Additional parameters are required to\nconfigure the driver: @option{cfg_address} is the base address of the\nconfiguration register interface, @option{clock_hz} is the expected clock\nfrequency, and @option{wait_states} is the number of configured read wait states.\n\n@example\nflash bank $_FLASHNAME esirisc base_address size_bytes 0 0 \\\n           $_TARGETNAME cfg_address clock_hz wait_states\n@end example\n\n@deffn {Command} {esirisc flash mass_erase} bank_id\nErase all pages in data memory for the bank identified by @option{bank_id}.\n@end deffn\n\n@deffn {Command} {esirisc flash ref_erase} bank_id\nErase the reference cell for the bank identified by @option{bank_id}. @emph{This\nis an uncommon operation.}\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {fm3}\nAll members of the FM3 microcontroller family from Fujitsu\ninclude internal flash and use ARM Cortex-M3 cores.\nThe @var{fm3} driver uses the @var{target} parameter to select the\ncorrect bank config, it can currently be one of the following:\n@code{mb9bfxx1.cpu}, @code{mb9bfxx2.cpu}, @code{mb9bfxx3.cpu},\n@code{mb9bfxx4.cpu}, @code{mb9bfxx5.cpu} or @code{mb9bfxx6.cpu}.\n\n@example\nflash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {fm4}\nAll members of the FM4 microcontroller family from Spansion (formerly Fujitsu)\ninclude internal flash and use ARM Cortex-M4 cores.\nThe @var{fm4} driver uses a @var{family} parameter to select the\ncorrect bank config, it can currently be one of the following:\n@code{MB9BFx64}, @code{MB9BFx65}, @code{MB9BFx66}, @code{MB9BFx67}, @code{MB9BFx68},\n@code{S6E2Cx8}, @code{S6E2Cx9}, @code{S6E2CxA} or @code{S6E2Dx},\nwith @code{x} treated as wildcard and otherwise case (and any trailing\ncharacters) ignored.\n\n@example\nflash bank $@{_FLASHNAME@}0 fm4 0x00000000 0 0 0 \\\n           $_TARGETNAME S6E2CCAJ0A\nflash bank $@{_FLASHNAME@}1 fm4 0x00100000 0 0 0 \\\n           $_TARGETNAME S6E2CCAJ0A\n@end example\n@emph{The current implementation is incomplete. Protection is not supported,\nnor is Chip Erase (only Sector Erase is implemented).}\n@end deffn\n\n@deffn {Flash Driver} {kinetis}\n@cindex kinetis\nKx, KLx, KVx and KE1x members of the Kinetis microcontroller family\nfrom NXP (former Freescale) include\ninternal flash and use ARM Cortex-M0+ or M4 cores. The driver automatically\nrecognizes flash size and a number of flash banks (1-4) using the chip\nidentification register, and autoconfigures itself.\nUse kinetis_ke driver for KE0x and KEAx devices.\n\nThe @var{kinetis} driver defines option:\n@itemize\n@item -sim-base @var{addr} ... base of System Integration Module where chip identification resides. Driver tries two known locations if option is omitted.\n@end itemize\n\n@example\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Config Command} {kinetis create_banks}\nConfiguration command enables automatic creation of additional flash banks\nbased on real flash layout of device. Banks are created during device probe.\nUse 'flash probe 0' to force probe.\n@end deffn\n\n@deffn {Command} {kinetis fcf_source} [protection|write]\nSelect what source is used when writing to a Flash Configuration Field.\n@option{protection} mode builds FCF content from protection bits previously\nset by 'flash protect' command.\nThis mode is default. MCU is protected from unwanted locking by immediate\nwriting FCF after erase of relevant sector.\n@option{write} mode enables direct write to FCF.\nProtection cannot be set by 'flash protect' command. FCF is written along\nwith the rest of a flash image.\n@emph{BEWARE: Incorrect flash configuration may permanently lock the device!}\n@end deffn\n\n@deffn {Command} {kinetis fopt} [num]\nSet value to write to FOPT byte of Flash Configuration Field.\nUsed in kinetis 'fcf_source protection' mode only.\n@end deffn\n\n@deffn {Command} {kinetis mdm check_security}\nChecks status of device security lock. Used internally in examine-end\nand examine-fail event.\n@end deffn\n\n@deffn {Command} {kinetis mdm halt}\nIssues a halt via the MDM-AP. This command can be used to break a watchdog reset\nloop when connecting to an unsecured target.\n@end deffn\n\n@deffn {Command} {kinetis mdm mass_erase}\nIssues a complete flash erase via the MDM-AP. This can be used to erase a chip\nback to its factory state, removing security. It does not require the processor\nto be halted, however the target will remain in a halted state after this\ncommand completes.\n@end deffn\n\n@deffn {Command} {kinetis nvm_partition}\nFor FlexNVM devices only (KxxDX and KxxFX).\nCommand shows or sets data flash or EEPROM backup size in kilobytes,\nsets two EEPROM blocks sizes in bytes and enables/disables loading\nof EEPROM contents to FlexRAM during reset.\n\nFor details see device reference manual, Flash Memory Module,\nProgram Partition command.\n\nSetting is possible only once after mass_erase.\nReset the device after partition setting.\n\nShow partition size:\n@example\nkinetis nvm_partition info\n@end example\n\nSet 32 KB data flash, rest of FlexNVM is EEPROM backup. EEPROM has two blocks\nof 512 and 1536 bytes and its contents is loaded to FlexRAM during reset:\n@example\nkinetis nvm_partition dataflash 32 512 1536 on\n@end example\n\nSet 16 KB EEPROM backup, rest of FlexNVM is a data flash. EEPROM has two blocks\nof 1024 bytes and its contents is not loaded to FlexRAM during reset:\n@example\nkinetis nvm_partition eebkp 16 1024 1024 off\n@end example\n@end deffn\n\n@deffn {Command} {kinetis mdm reset}\nIssues a reset via the MDM-AP. This causes the MCU to output a low pulse on the\nRESET pin, which can be used to reset other hardware on board.\n@end deffn\n\n@deffn {Command} {kinetis disable_wdog}\nFor Kx devices only (KLx has different COP watchdog, it is not supported).\nCommand disables watchdog timer.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {kinetis_ke}\n@cindex kinetis_ke\nKE0x and KEAx members of the Kinetis microcontroller family from NXP include\ninternal flash and use ARM Cortex-M0+. The driver automatically recognizes\nthe KE0x sub-family using the chip identification register, and\nautoconfigures itself.\nUse kinetis (not kinetis_ke) driver for KE1x devices.\n\n@example\nflash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {kinetis_ke mdm check_security}\nChecks status of device security lock. Used internally in examine-end event.\n@end deffn\n\n@deffn {Command} {kinetis_ke mdm mass_erase}\nIssues a complete Flash erase via the MDM-AP.\nThis can be used to erase a chip back to its factory state.\nCommand removes security lock from a device (use of SRST highly recommended).\nIt does not require the processor to be halted.\n@end deffn\n\n@deffn {Command} {kinetis_ke disable_wdog}\nCommand disables watchdog timer.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {lpc2000}\nThis is the driver to support internal flash of all members of the\nLPC11(x)00 and LPC1300 microcontroller families and most members of\nthe LPC800, LPC1500, LPC1700, LPC1800, LPC2000, LPC4000, LPC54100,\nLPC8Nxx and NHS31xx microcontroller families from NXP.\n\n@quotation Note\nThere are LPC2000 devices which are not supported by the @var{lpc2000}\ndriver:\nThe LPC2888 is supported by the @var{lpc288x} driver.\nThe LPC29xx family is supported by the @var{lpc2900} driver.\n@end quotation\n\nThe @var{lpc2000} driver defines two mandatory and two optional parameters,\nwhich must appear in the following order:\n\n@itemize\n@item @var{variant} ... required, may be\n@option{lpc2000_v1} (older LPC21xx and LPC22xx)\n@option{lpc2000_v2} (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)\n@option{lpc1700} (LPC175x and LPC176x and LPC177x/8x)\n@option{lpc4300} - available also as @option{lpc1800} alias (LPC18x[2357] and\nLPC43x[2357])\n@option{lpc800} (LPC8xx)\n@option{lpc1100} (LPC11(x)xx and LPC13xx)\n@option{lpc1500} (LPC15xx)\n@option{lpc54100} (LPC541xx)\n@option{lpc4000} (LPC40xx)\nor @option{auto} - automatically detects flash variant and size for LPC11(x)00,\nLPC8xx, LPC13xx, LPC17xx, LPC40xx, LPC8Nxx and NHS31xx\n@item @var{clock_kHz} ... the frequency, in kiloHertz,\nat which the core is running\n@item @option{calc_checksum} ... optional (but you probably want to provide this!),\ntelling the driver to calculate a valid checksum for the exception vector table.\n@quotation Note\nIf you don't provide @option{calc_checksum} when you're writing the vector\ntable, the boot ROM will almost certainly ignore your flash image.\nHowever, if you do provide it,\nwith most tool chains @command{verify_image} will fail.\n@end quotation\n@item @option{iap_entry} ... optional telling the driver to use a different\nROM IAP entry point.\n@end itemize\n\nLPC flashes don't require the chip and bus width to be specified.\n\n@example\nflash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 $_TARGETNAME \\\n      lpc2000_v2 14765 calc_checksum\n@end example\n\n@deffn {Command} {lpc2000 part_id} bank\nDisplays the four byte part identifier associated with\nthe specified flash @var{bank}.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {lpc288x}\nThe LPC2888 microcontroller from NXP needs slightly different flash\nsupport from its lpc2000 siblings.\nThe @var{lpc288x} driver defines one mandatory parameter,\nthe programming clock rate in Hz.\nLPC flashes don't require the chip and bus width to be specified.\n\n@example\nflash bank $_FLASHNAME lpc288x 0 0 0 0 $_TARGETNAME 12000000\n@end example\n@end deffn\n\n@deffn {Flash Driver} {lpc2900}\nThis driver supports the LPC29xx ARM968E based microcontroller family\nfrom NXP.\n\nThe predefined parameters @var{base}, @var{size}, @var{chip_width} and\n@var{bus_width} of the @code{flash bank} command are ignored. Flash size and\nsector layout are auto-configured by the driver.\nThe driver has one additional mandatory parameter: The CPU clock rate\n(in kHz) at the time the flash operations will take place. Most of the time this\nwill not be the crystal frequency, but a higher PLL frequency. The\n@code{reset-init} event handler in the board script is usually the place where\nyou start the PLL.\n\nThe driver rejects flashless devices (currently the LPC2930).\n\nThe EEPROM in LPC2900 devices is not mapped directly into the address space.\nIt must be handled much more like NAND flash memory, and will therefore be\nhandled by a separate @code{lpc2900_eeprom} driver (not yet available).\n\nSector protection in terms of the LPC2900 is handled transparently. Every time a\nsector needs to be erased or programmed, it is automatically unprotected.\nWhat is shown as protection status in the @code{flash info} command, is\nactually the LPC2900 @emph{sector security}. This is a mechanism to prevent a\nsector from ever being erased or programmed again. As this is an irreversible\nmechanism, it is handled by a special command (@code{lpc2900 secure_sector}),\nand not by the standard @code{flash protect} command.\n\nExample for a 125 MHz clock frequency:\n@example\nflash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME 125000\n@end example\n\nSome @code{lpc2900}-specific commands are defined. In the following command list,\nthe @var{bank} parameter is the bank number as obtained by the\n@code{flash banks} command.\n\n@deffn {Command} {lpc2900 signature} bank\nCalculates a 128-bit hash value, the @emph{signature}, from the whole flash\ncontent. This is a hardware feature of the flash block, hence the calculation is\nvery fast. You may use this to verify the content of a programmed device against\na known signature.\nExample:\n@example\nlpc2900 signature 0\n  signature: 0x5f40cdc8:0xc64e592e:0x10490f89:0x32a0f317\n@end example\n@end deffn\n\n@deffn {Command} {lpc2900 read_custom} bank filename\nReads the 912 bytes of customer information from the flash index sector, and\nsaves it to a file in binary format.\nExample:\n@example\nlpc2900 read_custom 0 /path_to/customer_info.bin\n@end example\n@end deffn\n\nThe index sector of the flash is a @emph{write-only} sector. It cannot be\nerased! In order to guard against unintentional write access, all following\ncommands need to be preceded by a successful call to the @code{password}\ncommand:\n\n@deffn {Command} {lpc2900 password} bank password\nYou need to use this command right before each of the following commands:\n@code{lpc2900 write_custom}, @code{lpc2900 secure_sector},\n@code{lpc2900 secure_jtag}.\n\nThe password string is fixed to \"I_know_what_I_am_doing\".\nExample:\n@example\nlpc2900 password 0 I_know_what_I_am_doing\n  Potentially dangerous operation allowed in next command!\n@end example\n@end deffn\n\n@deffn {Command} {lpc2900 write_custom} bank filename type\nWrites the content of the file into the customer info space of the flash index\nsector. The filetype can be specified with the @var{type} field. Possible values\nfor @var{type} are: @var{bin} (binary), @var{ihex} (Intel hex format),\n@var{elf} (ELF binary) or @var{s19} (Motorola S-records). The file must\ncontain a single section, and the contained data length must be exactly\n912 bytes.\n@quotation Attention\nThis cannot be reverted! Be careful!\n@end quotation\nExample:\n@example\nlpc2900 write_custom 0 /path_to/customer_info.bin bin\n@end example\n@end deffn\n\n@deffn {Command} {lpc2900 secure_sector} bank first last\nSecures the sector range from @var{first} to @var{last} (including) against\nfurther program and erase operations. The sector security will be effective\nafter the next power cycle.\n@quotation Attention\nThis cannot be reverted! Be careful!\n@end quotation\nSecured sectors appear as @emph{protected} in the @code{flash info} command.\nExample:\n@example\nlpc2900 secure_sector 0 1 1\nflash info 0\n  #0 : lpc2900 at 0x20000000, size 0x000c0000, (...)\n          #  0: 0x00000000 (0x2000 8kB) not protected\n          #  1: 0x00002000 (0x2000 8kB) protected\n          #  2: 0x00004000 (0x2000 8kB) not protected\n@end example\n@end deffn\n\n@deffn {Command} {lpc2900 secure_jtag} bank\nIrreversibly disable the JTAG port. The new JTAG security setting will be\neffective after the next power cycle.\n@quotation Attention\nThis cannot be reverted! Be careful!\n@end quotation\nExamples:\n@example\nlpc2900 secure_jtag 0\n@end example\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {mdr}\nThis drivers handles the integrated NOR flash on Milandr Cortex-M\nbased controllers. A known limitation is that the Info memory can't be\nread or verified as it's not memory mapped.\n\n@example\nflash bank <name> mdr <base> <size> \\\n      0 0 <target#> @var{type} @var{page_count} @var{sec_count}\n@end example\n\n@itemize @bullet\n@item @var{type} - 0 for main memory, 1 for info memory\n@item @var{page_count} - total number of pages\n@item @var{sec_count} - number of sector per page count\n@end itemize\n\nExample usage:\n@example\nif @{ [info exists IMEMORY] && [string equal $IMEMORY true] @} @{\n   flash bank $@{_CHIPNAME@}_info.flash mdr 0x00000000 0x01000 \\\n         0 0 $_TARGETNAME 1 1 4\n@} else @{\n   flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 \\\n         0 0 $_TARGETNAME 0 32 4\n@}\n@end example\n@end deffn\n\n@deffn {Flash Driver} {msp432}\nAll versions of the SimpleLink MSP432 microcontrollers from Texas\nInstruments include internal flash. The msp432 flash driver automatically\nrecognizes the specific version's flash parameters and autoconfigures itself.\nMain program flash starts at address 0. The information flash region on\nMSP432P4 versions starts at address 0x200000.\n\n@example\nflash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {msp432 mass_erase} bank_id [main|all]\nPerforms a complete erase of flash. By default, @command{mass_erase} will erase\nonly the main program flash.\n\nOn MSP432P4 versions, using @command{mass_erase all} will erase both the\nmain program and information flash regions. To also erase the BSL in information\nflash, the user must first use the @command{bsl} command.\n@end deffn\n\n@deffn {Command} {msp432 bsl} bank_id [unlock|lock]\nOn MSP432P4 versions, @command{bsl} unlocks and locks the bootstrap loader (BSL)\nregion in information flash so that flash commands can erase or write the BSL.\nLeave the BSL locked to prevent accidentally corrupting the bootstrap loader.\n\nTo erase and program the BSL:\n@example\nmsp432 bsl unlock\nflash erase_address 0x202000 0x2000\nflash write_image bsl.bin 0x202000\nmsp432 bsl lock\n@end example\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {niietcm4}\nThis drivers handles the integrated NOR flash on NIIET Cortex-M4\nbased controllers. Flash size and sector layout are auto-configured by the driver.\nMain flash memory is called \"Bootflash\" and has main region and info region.\nInfo region is NOT memory mapped by default,\nbut it can replace first part of main region if needed.\nFull erase, single and block writes are supported for both main and info regions.\nThere is additional not memory mapped flash called \"Userflash\", which\nalso have division into regions: main and info.\nPurpose of userflash - to store system and user settings.\nDriver has special commands to perform operations with this memory.\n\n@example\nflash bank $_FLASHNAME niietcm4 0 0 0 0 $_TARGETNAME\n@end example\n\nSome niietcm4-specific commands are defined:\n\n@deffn {Command} {niietcm4 uflash_read_byte} bank ('main'|'info') address\nRead byte from main or info userflash region.\n@end deffn\n\n@deffn {Command} {niietcm4 uflash_write_byte} bank ('main'|'info') address value\nWrite byte to main or info userflash region.\n@end deffn\n\n@deffn {Command} {niietcm4 uflash_full_erase} bank\nErase all userflash including info region.\n@end deffn\n\n@deffn {Command} {niietcm4 uflash_erase} bank ('main'|'info') first_sector last_sector\nErase sectors of main or info userflash region, starting at sector first up to and including last.\n@end deffn\n\n@deffn {Command} {niietcm4 uflash_protect_check} bank ('main'|'info')\nCheck sectors protect.\n@end deffn\n\n@deffn {Command} {niietcm4 uflash_protect} bank ('main'|'info') first_sector last_sector ('on'|'off')\nProtect sectors of main or info userflash region, starting at sector first up to and including last.\n@end deffn\n\n@deffn {Command} {niietcm4 bflash_info_remap} bank ('on'|'off')\nEnable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used).\n@end deffn\n\n@deffn {Command} {niietcm4 extmem_cfg} bank ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')\nConfigure external memory interface for boot.\n@end deffn\n\n@deffn {Command} {niietcm4 service_mode_erase} bank\nPerform emergency erase of all flash (bootflash and userflash).\n@end deffn\n\n@deffn {Command} {niietcm4 driver_info} bank\nShow information about flash driver.\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {npcx}\nAll versions of the NPCX microcontroller families from Nuvoton include internal\nflash. The NPCX flash driver supports the NPCX family of devices. The driver\nautomatically recognizes the specific version's flash parameters and\nautoconfigures itself. The flash bank starts at address 0x64000000.\n\n@example\nflash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {nrf5}\nAll members of the nRF51 microcontroller families from Nordic Semiconductor\ninclude internal flash and use ARM Cortex-M0 core. nRF52 family powered\nby ARM Cortex-M4 or M4F core is supported too. nRF52832 is fully supported\nincluding BPROT flash protection scheme. nRF52833 and nRF52840 devices are\nsupported with the exception of security extensions (flash access control list\n- ACL).\n\n@example\nflash bank $_FLASHNAME nrf5 0 0x00000000 0 0 $_TARGETNAME\n@end example\n\nSome nrf5-specific commands are defined:\n\n@deffn {Command} {nrf5 mass_erase}\nErases the contents of the code memory and user information\nconfiguration registers as well. It must be noted that this command\nworks only for chips that do not have factory pre-programmed region 0\ncode.\n@end deffn\n\n@deffn {Command} {nrf5 info}\nDecodes and shows information from FICR and UICR registers.\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {ocl}\nThis driver is an implementation of the ``on chip flash loader''\nprotocol proposed by Pavel Chromy.\n\nIt is a minimalistic command-response protocol intended to be used\nover a DCC when communicating with an internal or external flash\nloader running from RAM. An example implementation for AT91SAM7x is\navailable in @file{contrib/loaders/flash/at91sam7x/}.\n\n@example\nflash bank $_FLASHNAME ocl 0 0 0 0 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {pic32mx}\nThe PIC32MX microcontrollers are based on the MIPS 4K cores,\nand integrate flash memory.\n\n@example\nflash bank $_FLASHNAME pix32mx 0x1fc00000 0 0 0 $_TARGETNAME\nflash bank $_FLASHNAME pix32mx 0x1d000000 0 0 0 $_TARGETNAME\n@end example\n\n@comment numerous *disabled* commands are defined:\n@comment - chip_erase ... pointless given flash_erase_address\n@comment - lock, unlock ... pointless given protect on/off (yes?)\n@comment - pgm_word ... shouldn't bank be deduced from address??\nSome pic32mx-specific commands are defined:\n@deffn {Command} {pic32mx pgm_word} address value bank\nPrograms the specified 32-bit @var{value} at the given @var{address}\nin the specified chip @var{bank}.\n@end deffn\n@deffn {Command} {pic32mx unlock} bank\nUnlock and erase specified chip @var{bank}.\nThis will remove any Code Protection.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {psoc4}\nAll members of the PSoC 41xx/42xx microcontroller family from Cypress\ninclude internal flash and use ARM Cortex-M0 cores.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\nNote: Erased internal flash reads as 00.\nSystem ROM of PSoC 4 does not implement erase of a flash sector.\n\n@example\nflash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n@end example\n\npsoc4-specific commands\n@deffn {Command} {psoc4 flash_autoerase} num (on|off)\nEnables or disables autoerase mode for a flash bank.\n\nIf flash_autoerase is off, use mass_erase before flash programming.\nFlash erase command fails if region to erase is not whole flash memory.\n\nIf flash_autoerase is on, a sector is both erased and programmed in one\nsystem ROM call. Flash erase command is ignored.\nThis mode is suitable for gdb load.\n\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {psoc4 mass_erase} num\nErases the contents of the flash memory, protection and security lock.\n\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {psoc5lp}\nAll members of the PSoC 5LP microcontroller family from Cypress\ninclude internal program flash and use ARM Cortex-M3 cores.\nThe driver probes for a number of these chips and autoconfigures itself,\napart from the base address.\n\n@example\nflash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\n@end example\n\n@b{Note:} PSoC 5LP chips can be configured to have ECC enabled or disabled.\n@quotation Attention\nIf flash operations are performed in ECC-disabled mode, they will also affect\nthe ECC flash region. Erasing a 16k flash sector in the 0x00000000 area will\nthen also erase the corresponding 2k data bytes in the 0x48000000 area.\nWriting to the ECC data bytes in ECC-disabled mode is not implemented.\n@end quotation\n\nCommands defined in the @var{psoc5lp} driver:\n\n@deffn {Command} {psoc5lp mass_erase}\nErases all flash data and ECC/configuration bytes, all flash protection rows,\nand all row latches in all flash arrays on the device.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {psoc5lp_eeprom}\nAll members of the PSoC 5LP microcontroller family from Cypress\ninclude internal EEPROM and use ARM Cortex-M3 cores.\nThe driver probes for a number of these chips and autoconfigures itself,\napart from the base address.\n\n@example\nflash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 \\\n           $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {psoc5lp_nvl}\nAll members of the PSoC 5LP microcontroller family from Cypress\ninclude internal Nonvolatile Latches and use ARM Cortex-M3 cores.\nThe driver probes for a number of these chips and autoconfigures itself.\n\n@example\nflash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n@end example\n\nPSoC 5LP chips have multiple NV Latches:\n\n@itemize\n@item Device Configuration NV Latch - 4 bytes\n@item Write Once (WO) NV Latch - 4 bytes\n@end itemize\n\n@b{Note:} This driver only implements the Device Configuration NVL.\n\nThe @var{psoc5lp} driver reads the ECC mode from Device Configuration NVL.\n@quotation Attention\nSwitching ECC mode via write to Device Configuration NVL will require a reset\nafter successful write.\n@end quotation\n@end deffn\n\n@deffn {Flash Driver} {psoc6}\nSupports PSoC6 (CY8C6xxx) family of Cypress microcontrollers.\nPSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share\nthe same Flash/RAM/MMIO address space.\n\nFlash in PSoC6 is split into three regions:\n@itemize @bullet\n@item Main Flash - this is the main storage for user application.\nTotal size varies among devices, sector size: 256 kBytes, row size:\n512 bytes. Supports erase operation on individual rows.\n@item Work Flash - intended to be used as storage for user data\n(e.g. EEPROM emulation). Total size: 32 KBytes, sector size: 32 KBytes,\nrow size: 512 bytes.\n@item Supervisory Flash - special region which contains device-specific\nservice data. This region does not support erase operation. Only few rows can\nbe programmed by the user, most of the rows are read only. Programming\noperation will erase row automatically.\n@end itemize\n\nAll three flash regions are supported by the driver. Flash geometry is detected\nautomatically by parsing data in SPCIF_GEOMETRY register.\n\nPSoC6 is equipped with NOR Flash so erased Flash reads as 0x00.\n\n@example\nflash bank main_flash_cm0 psoc6 0x10000000 0 0 0 \\\n           $@{TARGET@}.cm0\nflash bank work_flash_cm0 psoc6 0x14000000 0 0 0 \\\n           $@{TARGET@}.cm0\nflash bank super_flash_user_cm0 psoc6 0x16000800 0 0 0 \\\n           $@{TARGET@}.cm0\nflash bank super_flash_nar_cm0 psoc6 0x16001A00 0 0 0 \\\n           $@{TARGET@}.cm0\nflash bank super_flash_key_cm0 psoc6 0x16005A00 0 0 0 \\\n           $@{TARGET@}.cm0\nflash bank super_flash_toc2_cm0 psoc6 0x16007C00 0 0 0 \\\n           $@{TARGET@}.cm0\n\nflash bank main_flash_cm4 psoc6 0x10000000 0 0 0 \\\n           $@{TARGET@}.cm4\nflash bank work_flash_cm4 psoc6 0x14000000 0 0 0 \\\n           $@{TARGET@}.cm4\nflash bank super_flash_user_cm4 psoc6 0x16000800 0 0 0 \\\n           $@{TARGET@}.cm4\nflash bank super_flash_nar_cm4 psoc6 0x16001A00 0 0 0 \\\n           $@{TARGET@}.cm4\nflash bank super_flash_key_cm4 psoc6 0x16005A00 0 0 0 \\\n           $@{TARGET@}.cm4\nflash bank super_flash_toc2_cm4 psoc6 0x16007C00 0 0 0 \\\n           $@{TARGET@}.cm4\n@end example\n\npsoc6-specific commands\n@deffn {Command} {psoc6 reset_halt}\nCommand can be used to simulate broken Vector Catch from gdbinit or tcl scripts.\nWhen invoked for CM0+ target, it will set break point at application entry point\nand issue SYSRESETREQ. This will reset both cores and all peripherals. CM0+ will\nreset CM4 during boot anyway so this is safe. On CM4 target, VECTRESET is used\ninstead of SYSRESETREQ to avoid unwanted reset of CM0+;\n@end deffn\n\n@deffn {Command} {psoc6 mass_erase} num\nErases the contents given flash bank. The @var{num} parameter is a value shown\nby @command{flash banks}.\nNote: only Main and Work flash regions support Erase operation.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {qn908x}\nThe NXP QN908x microcontrollers feature a Cortex-M4F with integrated Bluetooth\nLE 5 support and an internal flash of up to 512 KiB. These chips only support\nthe SWD interface.\n\nThe @var{qn908x} driver uses the internal \"Flash Memory Controller\" block via\nSWD to erase, program and read the internal flash. This driver does not\nsupport the ISP (In-System Programming) mode which is an alternate way to\nprogram the flash via UART, SPI or USB.\n\nThe internal flash is 512 KiB in size in all released chips and it starts at\nthe address 0x01000000, although it can be mapped to address 0 and it is\naliased to other addresses. This driver only recognizes the bank starting at\naddress 0x01000000.\n\nThe internal bootloader stored in ROM is in charge of loading and verifying\nthe image from flash, or enter ISP mode. The programmed image must start at\nthe beginning of the flash and contain a valid header and a matching CRC32\nchecksum. Additionally, the image header contains a \"Code Read Protection\"\n(CRP) word which indicates whether SWD access is enabled, as well as whether\nISP mode is enabled. Therefore, it is possible to program an image that\ndisables SWD and ISP making it impossible to program another image in the\nfuture through these interfaces, or even debug the current image. While this is\na valid use case for production deployments where the chips are locked down, by\ndefault this driver doesn't allow such images that disable the SWD interface.\nTo program such images see the @command{qn908x allow_brick} command.\n\nApart from the CRP field which is located in the image header, the last page\nof the flash memory contains a \"Flash lock and protect\" descriptor which allows\nto individually protect each 2 KiB page, as well as disabling SWD access to the\nflash and RAM. If this access is disabled it is not possible to read, erase or\nprogram individual pages from the SWD interface or even access the read-only\n\"Flash information page\" with information about the bootloader version and\nflash size. However when this protection is in place, it is still possible to\nmass erase the whole chip and then program a new image, for which you can use\nthe @command{qn908x mass_erase}.\n\nExample:\n@example\nflash bank $FLASHNAME qn908x 0x01000000 0 0 0 $TARGETNAME calc_checksum\n@end example\n\nParameters:\n@itemize\n@item @option{calc_checksum} optional parameter to compute the required\nchecksum of the first bytes in the vector table.\n@quotation Note\nIf the checksum in the header of your image is invalid and you don't provide the\n@option{calc_checksum} option the boot ROM will not boot your image and it may\nrender the flash inaccessible. On the other hand, if you use this option to\ncompute the checksum keep in mind that @command{verify_image} will fail on\nthose four bytes of the checksum since those bytes in the flash will have the\nupdated checksum.\n@end quotation\n@end itemize\n\n@deffn {Command} {qn908x allow_brick}\nAllow the qn908x driver to program images with a \"Code Read Protection\" byte\nthat disables the SWD access. Programming such image will cause OpenOCD to\nnot be able to reach the target over SWD anymore after the new image is\nprogrammed and its configuration takes effect, e.g. after a reboot. After\nexecuting @command{qn908x allow_brick} these images will be allowed to be\nprogrammed when writing to the flash.\n@end deffn\n\n@deffn {Command} {qn908x disable_wdog}\nDisable the watchdog timer (WDT) by resetting its CTRL field. The WDT starts\nenabled after a @command{reset halt} and it doesn't run while the target is\nhalted. However, the verification process in this driver uses the generic\nCortex-M verification process which executes a payload in RAM and thus\nrequires the watchdog to be disabled before running @command{verify_image}\nafter a reset halt or any other condition where the watchdog is running.\nNote that this is not done automatically and you must run this command in\nthose scenarios.\n@end deffn\n\n@deffn {Command} {qn908x mass_erase}\nErases the complete flash using the mass_erase method. Mass erase is only\nallowed if enabled in the Lock Status Register 8 (LOCK_STAT_8) which is read\nfrom the last sector of the flash on boot. However, this mass_erase lock\nprotection can be bypassed and this command does so automatically.\n\nIn the same LOCK_STAT_8 the flash and RAM access from SWD can be disabled by\nsetting two bits in this register. After a mass_erase, all the bits of the\nflash would be set, making it the default to restrict SWD access to the flash\nand RAM regions. This new after erase LOCK_STAT_8 value only takes effect after\nbeing read from flash on the next reboot for example. After a mass_erase the\nLOCK_STAT_8 register is changed by the hardware to allow access to flash and\nRAM regardless of the value on flash, but only right after a mass_erase and\nuntil the next boot. Therefore it is possible to perform a mass_erase, program\na new image, verify it and then reboot to a valid image that's locked from the\nSWD access.\n\nThe @command{qn908x mass_erase} command clears the bits that would be loaded\nfrom the flash into LOCK_STAT_8 after erasing the whole chip to allow SWD\naccess for debugging or re-flashing an image without a mass_erase by default.\nIf the image being programmed also programs the last page of the flash with its\nown settings, this mass_erase behavior will interfere with that write since a\nnew erase of at least the last page would need to be performed before writing\nto it again. For this reason the optional @option{keep_lock} argument can be\nused to leave the flash and RAM lock set. For development environments, the\ndefault behavior is desired.\n\nThe mass erase locking mechanism is independent from the individual page\nlocking bits, so it is possible that you can't erase a given page that is\nlocked and you can't unprotect that page because the locking bits are also\nlocked, but can still mass erase the whole flash.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {rp2040}\nSupports RP2040 \"Raspberry Pi Pico\" microcontroller.\nRP2040 is a dual-core device with two CM0+ cores. Both cores share the same\nFlash/RAM/MMIO address space.  Non-volatile storage is achieved with an\nexternal QSPI flash; a Boot ROM provides helper functions.\n\n@example\nflash bank $_FLASHNAME rp2040_flash $_FLASHBASE $_FLASHSIZE 1 32 $_TARGETNAME\n@end example\n@end deffn\n\n@deffn {Flash Driver} {rsl10}\nSupports Onsemi RSL10 microcontroller flash memory.  Uses functions\nstored in ROM to control flash memory interface.\n\n@example\nflash bank $_FLASHNAME rsl10 $_FLASHBASE $_FLASHSIZE 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {rsl10 lock} key1 key2 key3 key4\nWrites @var{key1 key2 key3 key4} words to @var{0x81044 0x81048 0x8104c\n0x8050}. Locks debug port by writing @var{0x4C6F634B} to @var{0x81040}.\n\nTo unlock use the @command{rsl10 unlock key1 key2 key3 key4} command.\n@end deffn\n\n@deffn {Command} {rsl10 unlock} key1 key2 key3 key4\nUnlocks debug port, by writing @var{key1 key2 key3 key4} words to\nregisters through DAP, and clears @var{0x81040} address in flash to 0x1.\n@end deffn\n\n@deffn {Command} {rsl10 mass_erase}\nErases all unprotected flash sectors.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {sim3x}\nAll members of the SiM3 microcontroller family from Silicon Laboratories\ninclude internal flash and use ARM Cortex-M3 cores. It supports both JTAG\nand SWD interface.\nThe @var{sim3x} driver tries to probe the device to auto detect the MCU.\nIf this fails, it will use the @var{size} parameter as the size of flash bank.\n\n@example\nflash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n@end example\n\nThere are 2 commands defined in the @var{sim3x} driver:\n\n@deffn {Command} {sim3x mass_erase}\nErases the complete flash. This is used to unlock the flash.\nAnd this command is only possible when using the SWD interface.\n@end deffn\n\n@deffn {Command} {sim3x lock}\nLock the flash. To unlock use the @command{sim3x mass_erase} command.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stellaris}\nAll members of the Stellaris LM3Sxxx, LM4x and Tiva C microcontroller\nfamilies from Texas Instruments include internal flash. The driver\nautomatically recognizes a number of these chips using the chip\nidentification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stellaris 0 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {stellaris recover}\nPerforms the @emph{Recovering a \"Locked\" Device} procedure to restore\nthe flash and its associated nonvolatile registers to their factory\ndefault values (erased). This is the only way to remove flash\nprotection or re-enable debugging if that capability has been\ndisabled.\n\nNote that the final \"power cycle the chip\" step in this procedure\nmust be performed by hand, since OpenOCD can't do it.\n@quotation Warning\nif more than one Stellaris chip is connected, the procedure is\napplied to all of them.\n@end quotation\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stm32f1x}\nAll members of the STM32F0, STM32F1 and STM32F3 microcontroller families\nfrom STMicroelectronics and all members of the GD32F1x0, GD32F3x0 and GD32E23x microcontroller\nfamilies from GigaDevice include internal flash and use ARM Cortex-M0/M3/M4/M23 cores.\nThe driver also works with GD32VF103 powered by RISC-V core.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stm32f1x 0 0 0 0 $_TARGETNAME\n@end example\n\nNote that some devices have been found that have a flash size register that contains\nan invalid value, to workaround this issue you can override the probed value used by\nthe flash driver.\n\n@example\nflash bank $_FLASHNAME stm32f1x 0 0x20000 0 0 $_TARGETNAME\n@end example\n\nIf you have a target with dual flash banks then define the second bank\nas per the following example.\n@example\nflash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n@end example\n\nSome stm32f1x-specific commands are defined:\n\n@deffn {Command} {stm32f1x lock} num\nLocks the entire stm32 device against reading.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f1x unlock} num\nUnlocks the entire stm32 device for reading. This command will cause\na mass erase of the entire stm32 device if previously locked.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f1x mass_erase} num\nMass erases the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f1x options_read} num\nReads and displays active stm32 option bytes loaded during POR\nor upon executing the @command{stm32f1x options_load} command.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f1x options_write} num (@option{SWWDG}|@option{HWWDG}) (@option{RSTSTNDBY}|@option{NORSTSTNDBY}) (@option{RSTSTOP}|@option{NORSTSTOP}) (@option{USEROPT} user_data)\nWrites the stm32 option byte with the specified values.\nThe @var{num} parameter is a value shown by @command{flash banks}.\nThe @var{user_data} parameter is content of higher 16 bits of the option byte register (Data0 and Data1 as one 16bit number).\n@end deffn\n\n@deffn {Command} {stm32f1x options_load} num\nGenerates a special kind of reset to re-load the stm32 option bytes written\nby the @command{stm32f1x options_write} or @command{flash protect} commands\nwithout having to power cycle the target. Not applicable to stm32f1x devices.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stm32f2x}\nAll members of the STM32F2, STM32F4 and STM32F7 microcontroller families from STMicroelectronics\ninclude internal flash and use ARM Cortex-M3/M4/M7 cores.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n@end example\n\nIf you use OTP (One-Time Programmable) memory define it as a second bank\nas per the following example.\n@example\nflash bank $_FLASHNAME stm32f2x 0x1FFF7800 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {stm32f2x otp} num (@option{enable}|@option{disable}|@option{show})\nEnables or disables OTP write commands for bank @var{num}.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\nNote that some devices have been found that have a flash size register that contains\nan invalid value, to workaround this issue you can override the probed value used by\nthe flash driver.\n\n@example\nflash bank $_FLASHNAME stm32f2x 0 0x20000 0 0 $_TARGETNAME\n@end example\n\nSome stm32f2x-specific commands are defined:\n\n@deffn {Command} {stm32f2x lock} num\nLocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f2x unlock} num\nUnlocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f2x mass_erase} num\nMass erases the entire stm32f2x device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f2x options_read} num\nReads and displays user options and (where implemented) boot_addr0, boot_addr1, optcr2.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32f2x options_write} num user_options boot_addr0 boot_addr1\nWrites user options and (where implemented) boot_addr0 and boot_addr1 in raw format.\nWarning: The meaning of the various bits depends on the device, always check datasheet!\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{user_options} a\n12 bit value, consisting of bits 31-28 and 7-0 of FLASH_OPTCR, @var{boot_addr0} and\n@var{boot_addr1} two halfwords (of FLASH_OPTCR1).\n@end deffn\n\n@deffn {Command} {stm32f2x optcr2_write} num optcr2\nWrites FLASH_OPTCR2 options. Warning: Clearing PCROPi bits requires a full mass erase!\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{optcr2} a 32-bit word.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stm32h7x}\nAll members of the STM32H7 microcontroller families from STMicroelectronics\ninclude internal flash and use ARM Cortex-M7 core.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stm32h7x 0 0 0 0 $_TARGETNAME\n@end example\n\nNote that some devices have been found that have a flash size register that contains\nan invalid value, to workaround this issue you can override the probed value used by\nthe flash driver.\n\n@example\nflash bank $_FLASHNAME stm32h7x 0 0x20000 0 0 $_TARGETNAME\n@end example\n\nSome stm32h7x-specific commands are defined:\n\n@deffn {Command} {stm32h7x lock} num\nLocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32h7x unlock} num\nUnlocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32h7x mass_erase} num\nMass erases the entire stm32h7x device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32h7x option_read} num reg_offset\nReads an option byte register from the stm32h7x device.\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}\nis the register offset of the option byte to read from the used bank registers' base.\nFor example: in STM32H74x/H75x the bank 1 registers' base is 0x52002000 and 0x52002100 for bank 2.\n\nExample usage:\n@example\n# read OPTSR_CUR\nstm32h7x option_read 0 0x1c\n# read WPSN_CUR1R\nstm32h7x option_read 0 0x38\n# read WPSN_CUR2R\nstm32h7x option_read 1 0x38\n@end example\n@end deffn\n\n@deffn {Command} {stm32h7x option_write} num reg_offset value [reg_mask]\nWrites an option byte register of the stm32h7x device.\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}\nis the register offset of the option byte to write from the used bank register base,\nand @var{reg_mask} is the mask to apply when writing the register (only bits with a '1'\nwill be touched).\n\nExample usage:\n@example\n# swap bank 1 and bank 2 in dual bank devices\n# by setting SWAP_BANK_OPT bit in OPTSR_PRG\nstm32h7x option_write 0 0x20 0x8000000 0x8000000\n@end example\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stm32lx}\nAll members of the STM32L0 and STM32L1 microcontroller families from STMicroelectronics\ninclude internal flash and use ARM Cortex-M3 and Cortex-M0+ cores.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n@end example\n\nNote that some devices have been found that have a flash size register that contains\nan invalid value, to workaround this issue you can override the probed value used by\nthe flash driver. If you use 0 as the bank base address, it tells the\ndriver to autodetect the bank location assuming you're configuring the\nsecond bank.\n\n@example\nflash bank $_FLASHNAME stm32lx 0x08000000 0x20000 0 0 $_TARGETNAME\n@end example\n\nSome stm32lx-specific commands are defined:\n\n@deffn {Command} {stm32lx lock} num\nLocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32lx unlock} num\nUnlocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32lx mass_erase} num\nMass erases the entire stm32lx device (all flash banks and EEPROM\ndata). This is the only way to unlock a protected flash (unless RDP\nLevel is 2 which can't be unlocked at all).\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {stm32l4x}\nAll members of the STM32 G0, G4, L4, L4+, L5, U5, WB and WL\nmicrocontroller families from STMicroelectronics include internal flash\nand use ARM Cortex-M0+, M4 and M33 cores.\nThe driver automatically recognizes a number of these chips using\nthe chip identification register, and autoconfigures itself.\n\n@example\nflash bank $_FLASHNAME stm32l4x 0 0 0 0 $_TARGETNAME\n@end example\n\nIf you use OTP (One-Time Programmable) memory define it as a second bank\nas per the following example.\n@example\nflash bank $_FLASHNAME stm32l4x 0x1FFF7000 0 0 0 $_TARGETNAME\n@end example\n\n@deffn {Command} {stm32l4x otp} num (@option{enable}|@option{disable}|@option{show})\nEnables or disables OTP write commands for bank @var{num}.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\nNote that some devices have been found that have a flash size register that contains\nan invalid value, to workaround this issue you can override the probed value used by\nthe flash driver. However, specifying a wrong value might lead to a completely\nwrong flash layout, so this feature must be used carefully.\n\n@example\nflash bank $_FLASHNAME stm32l4x 0x08000000 0x40000 0 0 $_TARGETNAME\n@end example\n\nSome stm32l4x-specific commands are defined:\n\n@deffn {Command} {stm32l4x lock} num\nLocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n\n@emph{Note:} To apply the protection change immediately, use @command{stm32l4x option_load}.\n@end deffn\n\n@deffn {Command} {stm32l4x unlock} num\nUnlocks the entire stm32 device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n\n@emph{Note:} To apply the protection change immediately, use @command{stm32l4x option_load}.\n@end deffn\n\n@deffn {Command} {stm32l4x mass_erase} num\nMass erases the entire stm32l4x device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn {Command} {stm32l4x option_read} num reg_offset\nReads an option byte register from the stm32l4x device.\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}\nis the register offset of the Option byte to read.\n\nFor example to read the FLASH_OPTR register:\n@example\nstm32l4x option_read 0 0x20\n# Option Register (for STM32L4x): <0x40022020> = 0xffeff8aa\n# Option Register (for STM32WBx): <0x58004020> = ...\n# The correct flash base address will be used automatically\n@end example\n\nThe above example will read out the FLASH_OPTR register which contains the RDP\noption byte, Watchdog configuration, BOR level etc.\n@end deffn\n\n@deffn {Command} {stm32l4x option_write} num reg_offset reg_mask\nWrite an option byte register of the stm32l4x device.\nThe @var{num} parameter is a value shown by @command{flash banks}, @var{reg_offset}\nis the register offset of the Option byte to write, and @var{reg_mask} is the mask\nto apply when writing the register (only bits with a '1' will be touched).\n\n@emph{Note:} To apply the option bytes change immediately, use @command{stm32l4x option_load}.\n\nFor example to write the WRP1AR option bytes:\n@example\nstm32l4x option_write 0 0x28 0x00FF0000 0x00FF00FF\n@end example\n\nThe above example will write the WRP1AR option register configuring the Write protection\nArea A for bank 1. The above example set WRP1AR_END=255, WRP1AR_START=0.\nThis will effectively write protect all sectors in flash bank 1.\n@end deffn\n\n@deffn {Command} {stm32l4x wrp_info} num [device_bank]\nList the protected areas using WRP.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@var{device_bank} parameter is optional, possible values 'bank1' or 'bank2',\nif not specified, the command will display the whole flash protected areas.\n\n@b{Note:} @var{device_bank} is different from banks created using @code{flash bank}.\nDevices supported in this flash driver, can have main flash memory organized\nin single or dual-banks mode.\nThus the usage of @var{device_bank} is meaningful only in dual-bank mode, to get\nwrite protected areas in a specific @var{device_bank}\n\n@end deffn\n\n@deffn {Command} {stm32l4x option_load} num\nForces a re-load of the option byte registers. Will cause a system reset of the device.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n@end deffn\n\n@deffn Command {stm32l4x trustzone} num [@option{enable} | @option{disable}]\nEnables or disables Global TrustZone Security, using the TZEN option bit.\nIf neither @option{enabled} nor @option{disable} are specified, the command will display\nthe TrustZone status.\n@emph{Note:} This command works only with devices with TrustZone, eg. STM32L5.\n@emph{Note:} This command will perform an OBL_Launch after modifying the TZEN.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {str7x}\nAll members of the STR7 microcontroller family from STMicroelectronics\ninclude internal flash and use ARM7TDMI cores.\nThe @var{str7x} driver defines one mandatory parameter, @var{variant},\nwhich is either @code{STR71x}, @code{STR73x} or @code{STR75x}.\n\n@example\nflash bank $_FLASHNAME str7x \\\n      0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\n@end example\n\n@deffn {Command} {str7x disable_jtag} bank\nActivate the Debug/Readout protection mechanism\nfor the specified flash bank.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {str9x}\nMost members of the STR9 microcontroller family from STMicroelectronics\ninclude internal flash and use ARM966E cores.\nThe str9 needs the flash controller to be configured using\nthe @command{str9x flash_config} command prior to Flash programming.\n\n@example\nflash bank $_FLASHNAME str9x 0x40000000 0x00040000 0 0 $_TARGETNAME\nstr9x flash_config 0 4 2 0 0x80000\n@end example\n\n@deffn {Command} {str9x flash_config} num bbsr nbbsr bbadr nbbadr\nConfigures the str9 flash controller.\nThe @var{num} parameter is a value shown by @command{flash banks}.\n\n@itemize @bullet\n@item @var{bbsr} - Boot Bank Size register\n@item @var{nbbsr} - Non Boot Bank Size register\n@item @var{bbadr} - Boot Bank Start Address register\n@item @var{nbbadr} - Boot Bank Start Address register\n@end itemize\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {str9xpec}\n@cindex str9xpec\n\nOnly use this driver for locking/unlocking the device or configuring the option bytes.\nUse the standard str9 driver for programming.\nBefore using the flash commands the turbo mode must be enabled using the\n@command{str9xpec enable_turbo} command.\n\nHere is some background info to help\nyou better understand how this driver works. OpenOCD has two flash drivers for\nthe str9:\n@enumerate\n@item\nStandard driver @option{str9x} programmed via the str9 core. Normally used for\nflash programming as it is faster than the @option{str9xpec} driver.\n@item\nDirect programming @option{str9xpec} using the flash controller. This is an\nISC compliant (IEEE 1532) tap connected in series with the str9 core. The str9\ncore does not need to be running to program using this flash driver. Typical use\nfor this driver is locking/unlocking the target and programming the option bytes.\n@end enumerate\n\nBefore we run any commands using the @option{str9xpec} driver we must first disable\nthe str9 core. This example assumes the @option{str9xpec} driver has been\nconfigured for flash bank 0.\n@example\n# assert srst, we do not want core running\n# while accessing str9xpec flash driver\nadapter assert srst\n# turn off target polling\npoll off\n# disable str9 core\nstr9xpec enable_turbo 0\n# read option bytes\nstr9xpec options_read 0\n# re-enable str9 core\nstr9xpec disable_turbo 0\npoll on\nreset halt\n@end example\nThe above example will read the str9 option bytes.\nWhen performing a unlock remember that you will not be able to halt the str9 - it\nhas been locked. Halting the core is not required for the @option{str9xpec} driver\nas mentioned above, just issue the commands above manually or from a telnet prompt.\n\nSeveral str9xpec-specific commands are defined:\n\n@deffn {Command} {str9xpec disable_turbo} num\nRestore the str9 into JTAG chain.\n@end deffn\n\n@deffn {Command} {str9xpec enable_turbo} num\nEnable turbo mode, will simply remove the str9 from the chain and talk\ndirectly to the embedded flash controller.\n@end deffn\n\n@deffn {Command} {str9xpec lock} num\nLock str9 device. The str9 will only respond to an unlock command that will\nerase the device.\n@end deffn\n\n@deffn {Command} {str9xpec part_id} num\nPrints the part identifier for bank @var{num}.\n@end deffn\n\n@deffn {Command} {str9xpec options_cmap} num (@option{bank0}|@option{bank1})\nConfigure str9 boot bank.\n@end deffn\n\n@deffn {Command} {str9xpec options_lvdsel} num (@option{vdd}|@option{vdd_vddq})\nConfigure str9 lvd source.\n@end deffn\n\n@deffn {Command} {str9xpec options_lvdthd} num (@option{2.4v}|@option{2.7v})\nConfigure str9 lvd threshold.\n@end deffn\n\n@deffn {Command} {str9xpec options_lvdwarn} bank (@option{vdd}|@option{vdd_vddq})\nConfigure str9 lvd reset warning source.\n@end deffn\n\n@deffn {Command} {str9xpec options_read} num\nRead str9 option bytes.\n@end deffn\n\n@deffn {Command} {str9xpec options_write} num\nWrite str9 option bytes.\n@end deffn\n\n@deffn {Command} {str9xpec unlock} num\nunlock str9 device.\n@end deffn\n\n@end deffn\n\n@deffn {Flash Driver} {swm050}\n@cindex swm050\nAll members of the swm050 microcontroller family from Foshan Synwit Tech.\n\n@example\nflash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n@end example\n\nOne swm050-specific command is defined:\n\n@deffn {Command} {swm050 mass_erase} bank_id\nErases the entire flash bank.\n@end deffn\n\n@end deffn\n\n\n@deffn {Flash Driver} {tms470}\nMost members of the TMS470 microcontroller family from Texas Instruments\ninclude internal flash and use ARM7TDMI cores.\nThis driver doesn't require the chip and bus width to be specified.\n\nSome tms470-specific commands are defined:\n\n@deffn {Command} {tms470 flash_keyset} key0 key1 key2 key3\nSaves programming keys in a register, to enable flash erase and write commands.\n@end deffn\n\n@deffn {Command} {tms470 osc_megahertz} clock_mhz\nReports the clock speed, which is used to calculate timings.\n@end deffn\n\n@deffn {Command} {tms470 plldis} (0|1)\nDisables (@var{1}) or enables (@var{0}) use of the PLL to speed up\nthe flash clock.\n@end deffn\n@end deffn\n\n@deffn {Flash Driver} {w600}\nW60x series Wi-Fi SoC from WinnerMicro\nare designed with ARM Cortex-M3 and have 1M Byte QFLASH inside.\nThe @var{w600} driver uses the @var{target} parameter to select the\ncorrect bank config.\n\n@example\nflash bank $_FLASHNAME w600 0x08000000 0 0 0 $_TARGETNAMEs\n@end example\n@end deffn\n\n@deffn {Flash Driver} {xmc1xxx}\nAll members of the XMC1xxx microcontroller family from Infineon.\nThis driver does not require the chip and bus width to be specified.\n@end deffn\n\n@deffn {Flash Driver} {xmc4xxx}\nAll members of the XMC4xxx microcontroller family from Infineon.\nThis driver does not require the chip and bus width to be specified.\n\nSome xmc4xxx-specific commands are defined:\n\n@deffn {Command} {xmc4xxx flash_password} bank_id passwd1 passwd2\nSaves flash protection passwords which are used to lock the user flash\n@end deffn\n\n@deffn {Command} {xmc4xxx flash_unprotect} bank_id user_level[0-1]\nRemoves Flash write protection from the selected user bank\n@end deffn\n\n@end deffn\n\n@section NAND Flash Commands\n@cindex NAND\n\nCompared to NOR or SPI flash, NAND devices are inexpensive\nand high density. Today's NAND chips, and multi-chip modules,\ncommonly hold multiple GigaBytes of data.\n\nNAND chips consist of a number of ``erase blocks'' of a given\nsize (such as 128 KBytes), each of which is divided into a\nnumber of pages (of perhaps 512 or 2048 bytes each). Each\npage of a NAND flash has an ``out of band'' (OOB) area to hold\nError Correcting Code (ECC) and other metadata, usually 16 bytes\nof OOB for every 512 bytes of page data.\n\nOne key characteristic of NAND flash is that its error rate\nis higher than that of NOR flash. In normal operation, that\nECC is used to correct and detect errors. However, NAND\nblocks can also wear out and become unusable; those blocks\nare then marked \"bad\". NAND chips are even shipped from the\nmanufacturer with a few bad blocks. The highest density chips\nuse a technology (MLC) that wears out more quickly, so ECC\nsupport is increasingly important as a way to detect blocks\nthat have begun to fail, and help to preserve data integrity\nwith techniques such as wear leveling.\n\nSoftware is used to manage the ECC. Some controllers don't\nsupport ECC directly; in those cases, software ECC is used.\nOther controllers speed up the ECC calculations with hardware.\nSingle-bit error correction hardware is routine. Controllers\ngeared for newer MLC chips may correct 4 or more errors for\nevery 512 bytes of data.\n\nYou will need to make sure that any data you write using\nOpenOCD includes the appropriate kind of ECC. For example,\nthat may mean passing the @code{oob_softecc} flag when\nwriting NAND data, or ensuring that the correct hardware\nECC mode is used.\n\nThe basic steps for using NAND devices include:\n@enumerate\n@item Declare via the command @command{nand device}\n@* Do this in a board-specific configuration file,\npassing parameters as needed by the controller.\n@item Configure each device using @command{nand probe}.\n@* Do this only after the associated target is set up,\nsuch as in its reset-init script or in procures defined\nto access that device.\n@item Operate on the flash via @command{nand subcommand}\n@* Often commands to manipulate the flash are typed by a human, or run\nvia a script in some automated way. Common task include writing a\nboot loader, operating system, or other data needed to initialize or\nde-brick a board.\n@end enumerate\n\n@b{NOTE:} At the time this text was written, the largest NAND\nflash fully supported by OpenOCD is 2 GiBytes (16 GiBits).\nThis is because the variables used to hold offsets and lengths\nare only 32 bits wide.\n(Larger chips may work in some cases, unless an offset or length\nis larger than 0xffffffff, the largest 32-bit unsigned integer.)\nSome larger devices will work, since they are actually multi-chip\nmodules with two smaller chips and individual chipselect lines.\n\n@anchor{nandconfiguration}\n@subsection NAND Configuration Commands\n@cindex NAND configuration\n\nNAND chips must be declared in configuration scripts,\nplus some additional configuration that's done after\nOpenOCD has initialized.\n\n@deffn {Config Command} {nand device} name driver target [configparams...]\nDeclares a NAND device, which can be read and written to\nafter it has been configured through @command{nand probe}.\nIn OpenOCD, devices are single chips; this is unlike some\noperating systems, which may manage multiple chips as if\nthey were a single (larger) device.\nIn some cases, configuring a device will activate extra\ncommands; see the controller-specific documentation.\n\n@b{NOTE:} This command is not available after OpenOCD\ninitialization has completed. Use it in board specific\nconfiguration files, not interactively.\n\n@itemize @bullet\n@item @var{name} ... may be used to reference the NAND bank\nin most other NAND commands. A number is also available.\n@item @var{driver} ... identifies the NAND controller driver\nassociated with the NAND device being declared.\n@xref{nanddriverlist,,NAND Driver List}.\n@item @var{target} ... names the target used when issuing\ncommands to the NAND controller.\n@comment Actually, it's currently a controller-specific parameter...\n@item @var{configparams} ... controllers may support, or require,\nadditional parameters. See the controller-specific documentation\nfor more information.\n@end itemize\n@end deffn\n\n@deffn {Command} {nand list}\nPrints a summary of each device declared\nusing @command{nand device}, numbered from zero.\nNote that un-probed devices show no details.\n@example\n> nand list\n#0: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n        blocksize: 131072, blocks: 8192\n#1: NAND 1GiB 3,3V 8-bit (Micron) pagesize: 2048, buswidth: 8,\n        blocksize: 131072, blocks: 8192\n>\n@end example\n@end deffn\n\n@deffn {Command} {nand probe} num\nProbes the specified device to determine key characteristics\nlike its page and block sizes, and how many blocks it has.\nThe @var{num} parameter is the value shown by @command{nand list}.\nYou must (successfully) probe a device before you can use\nit with most other NAND commands.\n@end deffn\n\n@subsection Erasing, Reading, Writing to NAND Flash\n\n@deffn {Command} {nand dump} num filename offset length [oob_option]\n@cindex NAND reading\nReads binary data from the NAND device and writes it to the file,\nstarting at the specified offset.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\nUse a complete path name for @var{filename}, so you don't depend\non the directory used to start the OpenOCD server.\n\nThe @var{offset} and @var{length} must be exact multiples of the\ndevice's page size. They describe a data region; the OOB data\nassociated with each such page may also be accessed.\n\n@b{NOTE:} At the time this text was written, no error correction\nwas done on the data that's read, unless raw access was disabled\nand the underlying NAND controller driver had a @code{read_page}\nmethod which handled that error correction.\n\nBy default, only page data is saved to the specified file.\nUse an @var{oob_option} parameter to save OOB data:\n@itemize @bullet\n@item no oob_* parameter\n@*Output file holds only page data; OOB is discarded.\n@item @code{oob_raw}\n@*Output file interleaves page data and OOB data;\nthe file will be longer than \"length\" by the size of the\nspare areas associated with each data page.\nNote that this kind of \"raw\" access is different from\nwhat's implied by @command{nand raw_access}, which just\ncontrols whether a hardware-aware access method is used.\n@item @code{oob_only}\n@*Output file has only raw OOB data, and will\nbe smaller than \"length\" since it will contain only the\nspare areas associated with each data page.\n@end itemize\n@end deffn\n\n@deffn {Command} {nand erase} num [offset length]\n@cindex NAND erasing\n@cindex NAND programming\nErases blocks on the specified NAND device, starting at the\nspecified @var{offset} and continuing for @var{length} bytes.\nBoth of those values must be exact multiples of the device's\nblock size, and the region they specify must fit entirely in the chip.\nIf those parameters are not specified,\nthe whole NAND chip will be erased.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\n@b{NOTE:} This command will try to erase bad blocks, when told\nto do so, which will probably invalidate the manufacturer's bad\nblock marker.\nFor the remainder of the current server session, @command{nand info}\nwill still report that the block ``is'' bad.\n@end deffn\n\n@deffn {Command} {nand write} num filename offset [option...]\n@cindex NAND writing\n@cindex NAND programming\nWrites binary data from the file into the specified NAND device,\nstarting at the specified offset. Those pages should already\nhave been erased; you can't change zero bits to one bits.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\nUse a complete path name for @var{filename}, so you don't depend\non the directory used to start the OpenOCD server.\n\nThe @var{offset} must be an exact multiple of the device's page size.\nAll data in the file will be written, assuming it doesn't run\npast the end of the device.\nOnly full pages are written, and any extra space in the last\npage will be filled with 0xff bytes. (That includes OOB data,\nif that's being written.)\n\n@b{NOTE:} At the time this text was written, bad blocks are\nignored. That is, this routine will not skip bad blocks,\nbut will instead try to write them. This can cause problems.\n\nProvide at most one @var{option} parameter. With some\nNAND drivers, the meanings of these parameters may change\nif @command{nand raw_access} was used to disable hardware ECC.\n@itemize @bullet\n@item no oob_* parameter\n@*File has only page data, which is written.\nIf raw access is in use, the OOB area will not be written.\nOtherwise, if the underlying NAND controller driver has\na @code{write_page} routine, that routine may write the OOB\nwith hardware-computed ECC data.\n@item @code{oob_only}\n@*File has only raw OOB data, which is written to the OOB area.\nEach page's data area stays untouched. @i{This can be a dangerous\noption}, since it can invalidate the ECC data.\nYou may need to force raw access to use this mode.\n@item @code{oob_raw}\n@*File interleaves data and OOB data, both of which are written\nIf raw access is enabled, the data is written first, then the\nun-altered OOB.\nOtherwise, if the underlying NAND controller driver has\na @code{write_page} routine, that routine may modify the OOB\nbefore it's written, to include hardware-computed ECC data.\n@item @code{oob_softecc}\n@*File has only page data, which is written.\nThe OOB area is filled with 0xff, except for a standard 1-bit\nsoftware ECC code stored in conventional locations.\nYou might need to force raw access to use this mode, to prevent\nthe underlying driver from applying hardware ECC.\n@item @code{oob_softecc_kw}\n@*File has only page data, which is written.\nThe OOB area is filled with 0xff, except for a 4-bit software ECC\nspecific to the boot ROM in Marvell Kirkwood SoCs.\nYou might need to force raw access to use this mode, to prevent\nthe underlying driver from applying hardware ECC.\n@end itemize\n@end deffn\n\n@deffn {Command} {nand verify} num filename offset [option...]\n@cindex NAND verification\n@cindex NAND programming\nVerify the binary data in the file has been programmed to the\nspecified NAND device, starting at the specified offset.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\nUse a complete path name for @var{filename}, so you don't depend\non the directory used to start the OpenOCD server.\n\nThe @var{offset} must be an exact multiple of the device's page size.\nAll data in the file will be read and compared to the contents of the\nflash, assuming it doesn't run past the end of the device.\nAs with @command{nand write}, only full pages are verified, so any extra\nspace in the last page will be filled with 0xff bytes.\n\nThe same @var{options} accepted by @command{nand write},\nand the file will be processed similarly to produce the buffers that\ncan be compared against the contents produced from @command{nand dump}.\n\n@b{NOTE:} This will not work when the underlying NAND controller\ndriver's @code{write_page} routine must update the OOB with a\nhardware-computed ECC before the data is written. This limitation may\nbe removed in a future release.\n@end deffn\n\n@subsection Other NAND commands\n@cindex NAND other commands\n\n@deffn {Command} {nand check_bad_blocks} num [offset length]\nChecks for manufacturer bad block markers on the specified NAND\ndevice. If no parameters are provided, checks the whole\ndevice; otherwise, starts at the specified @var{offset} and\ncontinues for @var{length} bytes.\nBoth of those values must be exact multiples of the device's\nblock size, and the region they specify must fit entirely in the chip.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\n@b{NOTE:} Before using this command you should force raw access\nwith @command{nand raw_access enable} to ensure that the underlying\ndriver will not try to apply hardware ECC.\n@end deffn\n\n@deffn {Command} {nand info} num\nThe @var{num} parameter is the value shown by @command{nand list}.\nThis prints the one-line summary from \"nand list\", plus for\ndevices which have been probed this also prints any known\nstatus for each block.\n@end deffn\n\n@deffn {Command} {nand raw_access} num (@option{enable}|@option{disable})\nSets or clears an flag affecting how page I/O is done.\nThe @var{num} parameter is the value shown by @command{nand list}.\n\nThis flag is cleared (disabled) by default, but changing that\nvalue won't affect all NAND devices. The key factor is whether\nthe underlying driver provides @code{read_page} or @code{write_page}\nmethods. If it doesn't provide those methods, the setting of\nthis flag is irrelevant; all access is effectively ``raw''.\n\nWhen those methods exist, they are normally used when reading\ndata (@command{nand dump} or reading bad block markers) or\nwriting it (@command{nand write}). However, enabling\nraw access (setting the flag) prevents use of those methods,\nbypassing hardware ECC logic.\n@i{This can be a dangerous option}, since writing blocks\nwith the wrong ECC data can cause them to be marked as bad.\n@end deffn\n\n@anchor{nanddriverlist}\n@subsection NAND Driver List\nAs noted above, the @command{nand device} command allows\ndriver-specific options and behaviors.\nSome controllers also activate controller-specific commands.\n\n@deffn {NAND Driver} {at91sam9}\nThis driver handles the NAND controllers found on AT91SAM9 family chips from\nAtmel. It takes two extra parameters: address of the NAND chip;\naddress of the ECC controller.\n@example\nnand device $NANDFLASH at91sam9 $CHIPNAME 0x40000000 0xfffffe800\n@end example\nAT91SAM9 chips support single-bit ECC hardware. The @code{write_page} and\n@code{read_page} methods are used to utilize the ECC hardware unless they are\ndisabled by using the @command{nand raw_access} command. There are four\nadditional commands that are needed to fully configure the AT91SAM9 NAND\ncontroller. Two are optional; most boards use the same wiring for ALE/CLE:\n@deffn {Config Command} {at91sam9 cle} num addr_line\nConfigure the address line used for latching commands. The @var{num}\nparameter is the value shown by @command{nand list}.\n@end deffn\n@deffn {Config Command} {at91sam9 ale} num addr_line\nConfigure the address line used for latching addresses. The @var{num}\nparameter is the value shown by @command{nand list}.\n@end deffn\n\nFor the next two commands, it is assumed that the pins have already been\nproperly configured for input or output.\n@deffn {Config Command} {at91sam9 rdy_busy} num pio_base_addr pin\nConfigure the RDY/nBUSY input from the NAND device. The @var{num}\nparameter is the value shown by @command{nand list}. @var{pio_base_addr}\nis the base address of the PIO controller and @var{pin} is the pin number.\n@end deffn\n@deffn {Config Command} {at91sam9 ce} num pio_base_addr pin\nConfigure the chip enable input to the NAND device. The @var{num}\nparameter is the value shown by @command{nand list}. @var{pio_base_addr}\nis the base address of the PIO controller and @var{pin} is the pin number.\n@end deffn\n@end deffn\n\n@deffn {NAND Driver} {davinci}\nThis driver handles the NAND controllers found on DaVinci family\nchips from Texas Instruments.\nIt takes three extra parameters:\naddress of the NAND chip;\nhardware ECC mode to use (@option{hwecc1},\n@option{hwecc4}, @option{hwecc4_infix});\naddress of the AEMIF controller on this processor.\n@example\nnand device davinci dm355.arm 0x02000000 hwecc4 0x01e10000\n@end example\nAll DaVinci processors support the single-bit ECC hardware,\nand newer ones also support the four-bit ECC hardware.\nThe @code{write_page} and @code{read_page} methods are used\nto implement those ECC modes, unless they are disabled using\nthe @command{nand raw_access} command.\n@end deffn\n\n@deffn {NAND Driver} {lpc3180}\nThese controllers require an extra @command{nand device}\nparameter: the clock rate used by the controller.\n@deffn {Command} {lpc3180 select} num [mlc|slc]\nConfigures use of the MLC or SLC controller mode.\nMLC implies use of hardware ECC.\nThe @var{num} parameter is the value shown by @command{nand list}.\n@end deffn\n\nAt this writing, this driver includes @code{write_page}\nand @code{read_page} methods. Using @command{nand raw_access}\nto disable those methods will prevent use of hardware ECC\nin the MLC controller mode, but won't change SLC behavior.\n@end deffn\n@comment current lpc3180 code won't issue 5-byte address cycles\n\n@deffn {NAND Driver} {mx3}\nThis driver handles the NAND controller in i.MX31. The mxc driver\nshould work for this chip as well.\n@end deffn\n\n@deffn {NAND Driver} {mxc}\nThis driver handles the NAND controller found in Freescale i.MX\nchips. It has support for v1 (i.MX27 and i.MX31) and v2 (i.MX35).\nThe driver takes 3 extra arguments, chip (@option{mx27},\n@option{mx31}, @option{mx35}), ecc (@option{noecc}, @option{hwecc})\nand optionally if bad block information should be swapped between\nmain area and spare area (@option{biswap}), defaults to off.\n@example\nnand device mx35.nand mxc imx35.cpu mx35 hwecc biswap\n@end example\n@deffn {Command} {mxc biswap} bank_num [enable|disable]\nTurns on/off bad block information swapping from main area,\nwithout parameter query status.\n@end deffn\n@end deffn\n\n@deffn {NAND Driver} {orion}\nThese controllers require an extra @command{nand device}\nparameter: the address of the controller.\n@example\nnand device orion 0xd8000000\n@end example\nThese controllers don't define any specialized commands.\nAt this writing, their drivers don't include @code{write_page}\nor @code{read_page} methods, so @command{nand raw_access} won't\nchange any behavior.\n@end deffn\n\n@deffn {NAND Driver} {s3c2410}\n@deffnx {NAND Driver} {s3c2412}\n@deffnx {NAND Driver} {s3c2440}\n@deffnx {NAND Driver} {s3c2443}\n@deffnx {NAND Driver} {s3c6400}\nThese S3C family controllers don't have any special\n@command{nand device} options, and don't define any\nspecialized commands.\nAt this writing, their drivers don't include @code{write_page}\nor @code{read_page} methods, so @command{nand raw_access} won't\nchange any behavior.\n@end deffn\n\n@node Flash Programming\n@chapter Flash Programming\n\nOpenOCD implements numerous ways to program the target flash, whether internal or external.\nProgramming can be achieved by either using @ref{programmingusinggdb,,Programming using GDB},\nor using the commands given in @ref{flashprogrammingcommands,,Flash Programming Commands}.\n\n@*To simplify using the flash commands directly a jimtcl script is available that handles the programming and verify stage.\nOpenOCD will program/verify/reset the target and optionally shutdown.\n\nThe script is executed as follows and by default the following actions will be performed.\n@enumerate\n@item 'init' is executed.\n@item 'reset init' is called to reset and halt the target, any 'reset init' scripts are executed.\n@item @code{flash write_image} is called to erase and write any flash using the filename given.\n@item If the @option{preverify} parameter is given, the target is \"verified\" first and only flashed if this fails.\n@item @code{verify_image} is called if @option{verify} parameter is given.\n@item @code{reset run} is called if @option{reset} parameter is given.\n@item OpenOCD is shutdown if @option{exit} parameter is given.\n@end enumerate\n\nAn example of usage is given below. @xref{program}.\n\n@example\n# program and verify using elf/hex/s19. verify and reset\n# are optional parameters\nopenocd -f board/stm32f3discovery.cfg \\\n\t-c \"program filename.elf verify reset exit\"\n\n# binary files need the flash address passing\nopenocd -f board/stm32f3discovery.cfg \\\n\t-c \"program filename.bin exit 0x08000000\"\n@end example\n\n@node PLD/FPGA Commands\n@chapter PLD/FPGA Commands\n@cindex PLD\n@cindex FPGA\n\nProgrammable Logic Devices (PLDs) and the more flexible\nField Programmable Gate Arrays (FPGAs) are both types of programmable hardware.\nOpenOCD can support programming them.\nAlthough PLDs are generally restrictive (cells are less functional, and\nthere are no special purpose cells for memory or computational tasks),\nthey share the same OpenOCD infrastructure.\nAccordingly, both are called PLDs here.\n\n@section PLD/FPGA Configuration and Commands\n\nAs it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND),\nOpenOCD maintains a list of PLDs available for use in various commands.\nAlso, each such PLD requires a driver.\n\nThey are referenced by the name which was given when the pld was created or\nthe number shown by the @command{pld devices} command.\nNew PLDs are defined by @command{pld create pld_name driver_name -chain-position tap_name [driver_options]}.\n\n@deffn {Config Command} {pld create} pld_name driver_name -chain-position tap_name [driver_options]\nCreates a new PLD device, supported by driver @var{driver_name},\nassigning @var{pld_name} for further reference.\n@code{-chain-position} @var{tap_name} names the TAP\nused to access this target.\nThe driver may make use of any @var{driver_options} to configure its behavior.\n@end deffn\n\n@deffn {Command} {pld devices}\nList the known PLDs with their name.\n@end deffn\n\n@deffn {Command} {pld load} pld_name filename\nLoads the file @file{filename} into the PLD identified by @var{pld_name}.\nThe file format must be inferred by the driver.\n@end deffn\n\n@section PLD/FPGA Drivers, Options, and Commands\n\nDrivers may support PLD-specific options to the @command{pld device}\ndefinition command, and may also define commands usable only with\nthat particular type of PLD.\n\n@deffn {FPGA Driver} {virtex2} [@option{-no_jstart}]\nVirtex-II is a family of FPGAs sold by Xilinx.\nThis driver can also be used to load Series3, Series6, Series7 and Zynq 7000 devices.\nIt supports the IEEE 1532 standard for In-System Configuration (ISC).\n\nIf @var{-no_jstart} is given, the JSTART instruction is not used after\nloading the bitstream. While required for Series2, Series3, and Series6, it\nbreaks bitstream loading on Series7.\n\n@example\nopenocd -f board/digilent_zedboard.cfg -c \"init\" \\\n\t-c \"pld load 0 zedboard_bitstream.bit\"\n@end example\n\n\n@deffn {Command} {virtex2 read_stat} pld_name\nReads and displays the Virtex-II status register (STAT)\nfor FPGA @var{pld_name}.\n@end deffn\n\n@deffn {Command} {virtex2 set_instr_codes} pld_name cfg_out cfg_in jprogb jstart jshutdown [user1 [user2 [user3 [user4]]]]\nChange values for boundary scan instructions. Default are values for Virtex 2, devices Virtex 4/5/6 and\nSSI devices are using different values.\n@var{pld_name} is the name of the pld device.\n@var{cfg_out} is the value used to select CFG_OUT instruction.\n@var{cfg_in} is the value used to select CFG_IN instruction.\n@var{jprogb} is the value used to select JPROGRAM instruction.\n@var{jstart} is the value used to select JSTART instruction.\n@var{jshutdown} is the value used to select JSHUTDOWN instruction.\n@var{user1} to @var{user4} are the intruction used to select the user registers USER1 to USER4.\n@end deffn\n\n@deffn {Command} {virtex2 set_user_codes} pld_name user1 [user2 [user3 [user4]]]\nChange values for boundary scan instructions selecting the registers USER1 to USER4.\nDescription of the arguments can be found at command @command{virtex2 set_instr_codes}.\n@end deffn\n\n@deffn {Command} {virtex2 program} pld_name\nLoad the bitstream from external memory for FPGA @var{pld_name}. A.k.a. refresh.\n@end deffn\n@end deffn\n\n\n\n@deffn {FPGA Driver} {lattice} [@option{-family} <name>]\nThe FGPA families ECP2, ECP3, ECP5, Certus and CertusPro by Lattice are supported.\nThis driver can be used to load the bitstream into the FPGA or read the status register and read/write the usercode register.\n\nFor the option @option{-family} @var{name} is one of @var{ecp2 ecp3 ecp5 certus}. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).\n\n@deffn {Command} {lattice read_status} pld_name\nReads and displays the status register\nfor FPGA @var{pld_name}.\n@end deffn\n\n@deffn {Command} {lattice read_user} pld_name\nReads and displays the user register\nfor FPGA @var{pld_name}.\n@end deffn\n\n@deffn {Command} {lattice write_user} pld_name val\nWrites the user register.\nfor FPGA @var{pld_name} with value @var{val}.\n@end deffn\n\n@deffn {Command} {lattice set_preload} pld_name length\nSet the length of the register for the preload. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).\nThe load command for the FPGA @var{pld_name} will use a length for the preload of @var{length}.\n@end deffn\n@end deffn\n\n\n@deffn {FPGA Driver} {efinix} [@option{-family} <name>]\nBoth families (Trion and Titanium) sold by Efinix are supported as both use the same protocol for In-System Configuration.\nThis driver can be used to load the bitstream into the FPGA.\nFor the option @option{-family} @var{name} is one of @var{trion|titanium}.\n@end deffn\n\n\n@deffn {FPGA Driver} {intel} [@option{-family} <name>]\nThis driver can be used to load the bitstream into Intel (former Altera) FPGAs.\nThe families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10, Arria II are supported.\n@c Arria V and Arria 10, MAX II, MAX V, MAX10)\n\nFor the option @option{-family} @var{name} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}.\nThis is needed when the JTAG ID of the device is ambiguous (same ID is used for chips in different families).\n\nAs input file format the driver supports a '.rbf' (raw bitstream file) file. The '.rbf' file can be generated\nfrom a '.sof' file with @verb{|quartus_cpf -c blinker.sof blinker.rbf|}\n\nCreates a new PLD device, an FPGA of the Cyclone III family, using the TAP named @verb{|cycloneiii.tap|}:\n@example\npld create cycloneiii.pld intel -chain-position cycloneiii.tap -family cycloneiii\n@end example\n\n@deffn {Command} {intel set_bscan} pld_name len\nSet boundary scan register length of FPGA @var{pld_name} to @var{len}. This is needed because the\nlength can vary between chips with the same JTAG ID.\n@end deffn\n\n@deffn {Command} {intel set_check_pos} pld_name pos\nSelects the position @var{pos} in the boundary-scan register. The bit at this\nposition is checked after loading the bitstream and must be '1', which is the case when no error occurred.\nWith a value of -1 for @var{pos} the check will be omitted.\n@end deffn\n@end deffn\n\n\n@deffn {FPGA Driver} {gowin}\nThis driver can be used to load the bitstream into FPGAs from Gowin.\nIt is possible to program the SRAM. Programming the flash is not supported.\nThe files @verb{|.fs|} and @verb{|.bin|} generated by Gowin FPGA Designer are supported.\n\n@deffn {Command} {gowin read_status} pld_name\nReads and displays the status register\nfor FPGA @var{pld_name}.\n@end deffn\n\n@deffn {Command} {gowin read_user} pld_name\nReads and displays the user register\nfor FPGA @var{pld_name}.\n@end deffn\n\n@deffn {Command} {gowin reload} pld_name\nLoad the bitstream from external memory for\nFPGA @var{pld_name}. A.k.a. refresh.\n@end deffn\n@end deffn\n\n\n@deffn {FPGA Driver} {gatemate}\nThis driver can be used to load the bitstream into GateMate FPGAs form CologneChip.\nThe files @verb{|.bit|} and @verb{|.cfg|} both generated by p_r tool from CologneChip are supported.\n@end deffn\n\n\n@node General Commands\n@chapter General Commands\n@cindex commands\n\nThe commands documented in this chapter here are common commands that\nyou, as a human, may want to type and see the output of. Configuration type\ncommands are documented elsewhere.\n\nIntent:\n@itemize @bullet\n@item @b{Source Of Commands}\n@* OpenOCD commands can occur in a configuration script (discussed\nelsewhere) or typed manually by a human or supplied programmatically,\nor via one of several TCP/IP Ports.\n\n@item @b{From the human}\n@* A human should interact with the telnet interface (default port: 4444)\nor via GDB (default port 3333).\n\nTo issue commands from within a GDB session, use the @option{monitor}\ncommand, e.g. use @option{monitor poll} to issue the @option{poll}\ncommand. All output is relayed through the GDB session.\n\n@item @b{Machine Interface}\nThe Tcl interface's intent is to be a machine interface. The default Tcl\nport is 6666.\n@end itemize\n\n\n@section Server Commands\n\n@deffn {Command} {exit}\nExits the current telnet session.\n@end deffn\n\n@deffn {Command} {help} [string]\nWith no parameters, prints help text for all commands.\nOtherwise, prints each helptext containing @var{string}.\nNot every command provides helptext.\n\nConfiguration commands, and commands valid at any time, are\nexplicitly noted in parenthesis.\nIn most cases, no such restriction is listed; this indicates commands\nwhich are only available after the configuration stage has completed.\n@end deffn\n\n@deffn {Command} {usage} [string]\nWith no parameters, prints usage text for all commands.  Otherwise,\nprints all usage text of which command, help text, and usage text\ncontaining @var{string}.\nNot every command provides helptext.\n@end deffn\n\n@deffn {Command} {sleep} msec [@option{busy}]\nWait for at least @var{msec} milliseconds before resuming.\nIf @option{busy} is passed, busy-wait instead of sleeping.\n(This option is strongly discouraged.)\nUseful in connection with script files\n(@command{script} command and @command{target_name} configuration).\n@end deffn\n\n@deffn {Command} {shutdown} [@option{error}]\nClose the OpenOCD server, disconnecting all clients (GDB, telnet,\nother). If option @option{error} is used, OpenOCD will return a\nnon-zero exit code to the parent process.\n\nIf user types CTRL-C or kills OpenOCD, the command @command{shutdown}\nwill be automatically executed to cause OpenOCD to exit.\n\nIt is possible to specify, in the TCL list @var{pre_shutdown_commands} , a\nset of commands to be automatically executed before @command{shutdown} , e.g.:\n@example\nlappend pre_shutdown_commands @{echo \"Goodbye, my friend ...\"@}\nlappend pre_shutdown_commands @{echo \"see you soon !\"@}\n@end example\nThe commands in the list will be executed (in the same order they occupy\nin the list) before OpenOCD exits. If one of the commands in the list\nfails, then the remaining commands are not executed anymore while OpenOCD\nwill proceed to quit.\n@end deffn\n\n@anchor{debuglevel}\n@deffn {Command} {debug_level} [n]\n@cindex message level\nDisplay debug level.\nIf @var{n} (from 0..4) is provided, then set it to that level.\nThis affects the kind of messages sent to the server log.\nLevel 0 is error messages only;\nlevel 1 adds warnings;\nlevel 2 adds informational messages;\nlevel 3 adds debugging messages;\nand level 4 adds verbose low-level debug messages.\nThe default is level 2, but that can be overridden on\nthe command line along with the location of that log\nfile (which is normally the server's standard output).\n@xref{Running}.\n@end deffn\n\n@deffn {Command} {echo} [-n] message\nLogs a message at \"user\" priority.\nOption \"-n\" suppresses trailing newline.\n@example\necho \"Downloading kernel -- please wait\"\n@end example\n@end deffn\n\n@deffn {Command} {log_output} [filename | \"default\"]\nRedirect logging to @var{filename} or set it back to default output;\nthe default log output channel is stderr.\n@end deffn\n\n@deffn {Command} {add_script_search_dir} [directory]\nAdd @var{directory} to the file/script search path.\n@end deffn\n\n@deffn {Config Command} {bindto} [@var{name}]\nSpecify hostname or IPv4 address on which to listen for incoming\nTCP/IP connections. By default, OpenOCD will listen on the loopback\ninterface only. If your network environment is safe, @code{bindto\n0.0.0.0} can be used to cover all available interfaces.\n@end deffn\n\n@anchor{targetstatehandling}\n@section Target State handling\n@cindex reset\n@cindex halt\n@cindex target initialization\n\nIn this section ``target'' refers to a CPU configured as\nshown earlier (@pxref{CPU Configuration}).\nThese commands, like many, implicitly refer to\na current target which is used to perform the\nvarious operations. The current target may be changed\nby using @command{targets} command with the name of the\ntarget which should become current.\n\n@deffn {Command} {reg} [(number|name) [(value|'force')]]\nAccess a single register by @var{number} or by its @var{name}.\nThe target must generally be halted before access to CPU core\nregisters is allowed. Depending on the hardware, some other\nregisters may be accessible while the target is running.\n\n@emph{With no arguments}:\nlist all available registers for the current target,\nshowing number, name, size, value, and cache status.\nFor valid entries, a value is shown; valid entries\nwhich are also dirty (and will be written back later)\nare flagged as such.\n\n@emph{With number/name}: display that register's value.\nUse @var{force} argument to read directly from the target,\nbypassing any internal cache.\n\n@emph{With both number/name and value}: set register's value.\nWrites may be held in a writeback cache internal to OpenOCD,\nso that setting the value marks the register as dirty instead\nof immediately flushing that value. Resuming CPU execution\n(including by single stepping) or otherwise activating the\nrelevant module will flush such values.\n\nCores may have surprisingly many registers in their\nDebug and trace infrastructure:\n\n@example\n> reg\n===== ARM registers\n(0) r0 (/32): 0x0000D3C2 (dirty)\n(1) r1 (/32): 0xFD61F31C\n(2) r2 (/32)\n...\n(164) ETM_contextid_comparator_mask (/32)\n>\n@end example\n@end deffn\n\n@deffn {Command} {set_reg} dict\nSet register values of the target.\n\n@itemize\n@item @var{dict} ... Tcl dictionary with pairs of register names and values.\n@end itemize\n\nFor example, the following command sets the value 0 to the program counter (pc)\nregister and 0x1000 to the stack pointer (sp) register:\n\n@example\nset_reg @{pc 0 sp 0x1000@}\n@end example\n@end deffn\n\n@deffn {Command} {get_reg} [-force] list\nGet register values from the target and return them as Tcl dictionary with pairs\nof register names and values.\nIf option \"-force\" is set, the register values are read directly from the\ntarget, bypassing any caching.\n\n@itemize\n@item @var{list} ... List of register names\n@end itemize\n\nFor example, the following command retrieves the values from the program\ncounter (pc) and stack pointer (sp) register:\n\n@example\nget_reg @{pc sp@}\n@end example\n@end deffn\n\n@deffn {Command} {write_memory} address width data ['phys']\nThis function provides an efficient way to write to the target memory from a Tcl\nscript.\n\n@itemize\n@item @var{address} ... target memory address\n@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64\n@item @var{data} ... Tcl list with the elements to write\n@item ['phys'] ... treat the memory address as physical instead of virtual address\n@end itemize\n\nFor example, the following command writes two 32 bit words into the target\nmemory at address 0x20000000:\n\n@example\nwrite_memory 0x20000000 32 @{0xdeadbeef 0x00230500@}\n@end example\n@end deffn\n\n@deffn {Command} {read_memory} address width count ['phys']\nThis function provides an efficient way to read the target memory from a Tcl\nscript.\nA Tcl list containing the requested memory elements is returned by this function.\n\n@itemize\n@item @var{address} ... target memory address\n@item @var{width} ... memory access bit size, can be 8, 16, 32 or 64\n@item @var{count} ... number of elements to read\n@item ['phys'] ... treat the memory address as physical instead of virtual address\n@end itemize\n\nFor example, the following command reads two 32 bit words from the target\nmemory at address 0x20000000:\n\n@example\nread_memory 0x20000000 32 2\n@end example\n@end deffn\n\n@deffn {Command} {halt} [ms]\n@deffnx {Command} {wait_halt} [ms]\nThe @command{halt} command first sends a halt request to the target,\nwhich @command{wait_halt} doesn't.\nOtherwise these behave the same: wait up to @var{ms} milliseconds,\nor 5 seconds if there is no parameter, for the target to halt\n(and enter debug mode).\nUsing 0 as the @var{ms} parameter prevents OpenOCD from waiting.\n\n@quotation Warning\nOn ARM cores, software using the @emph{wait for interrupt} operation\noften blocks the JTAG access needed by a @command{halt} command.\nThis is because that operation also puts the core into a low\npower mode by gating the core clock;\nbut the core clock is needed to detect JTAG clock transitions.\n\nOne partial workaround uses adaptive clocking: when the core is\ninterrupted the operation completes, then JTAG clocks are accepted\nat least until the interrupt handler completes.\nHowever, this workaround is often unusable since the processor, board,\nand JTAG adapter must all support adaptive JTAG clocking.\nAlso, it can't work until an interrupt is issued.\n\nA more complete workaround is to not use that operation while you\nwork with a JTAG debugger.\nTasking environments generally have idle loops where the body is the\n@emph{wait for interrupt} operation.\n(On older cores, it is a coprocessor action;\nnewer cores have a @option{wfi} instruction.)\nSuch loops can just remove that operation, at the cost of higher\npower consumption (because the CPU is needlessly clocked).\n@end quotation\n\n@end deffn\n\n@deffn {Command} {resume} [address]\nResume the target at its current code position,\nor the optional @var{address} if it is provided.\n@end deffn\n\n@deffn {Command} {step} [address]\nSingle-step the target at its current code position,\nor the optional @var{address} if it is provided.\n@end deffn\n\n@anchor{resetcommand}\n@deffn {Command} {reset}\n@deffnx {Command} {reset run}\n@deffnx {Command} {reset halt}\n@deffnx {Command} {reset init}\nPerform as hard a reset as possible, using SRST if possible.\n@emph{All defined targets will be reset, and target\nevents will fire during the reset sequence.}\n\nThe optional parameter specifies what should\nhappen after the reset.\nIf there is no parameter, a @command{reset run} is executed.\nThe other options will not work on all systems.\n@xref{Reset Configuration}.\n\n@itemize @minus\n@item @b{run} Let the target run\n@item @b{halt} Immediately halt the target\n@item @b{init} Immediately halt the target, and execute the reset-init script\n@end itemize\n@end deffn\n\n@deffn {Command} {soft_reset_halt}\nRequesting target halt and executing a soft reset. This is often used\nwhen a target cannot be reset and halted. The target, after reset is\nreleased begins to execute code. OpenOCD attempts to stop the CPU and\nthen sets the program counter back to the reset vector. Unfortunately\nthe code that was executed may have left the hardware in an unknown\nstate.\n@end deffn\n\n@deffn {Command} {adapter assert} [signal [assert|deassert signal]]\n@deffnx {Command} {adapter deassert} [signal [assert|deassert signal]]\nSet values of reset signals.\nWithout parameters returns current status of the signals.\nThe @var{signal} parameter values may be\n@option{srst}, indicating that srst signal is to be asserted or deasserted,\n@option{trst}, indicating that trst signal is to be asserted or deasserted.\n\nThe @command{reset_config} command should already have been used\nto configure how the board and the adapter treat these two\nsignals, and to say if either signal is even present.\n@xref{Reset Configuration}.\nTrying to assert a signal that is not present triggers an error.\nIf a signal is present on the adapter and not specified in the command,\nthe signal will not be modified.\n\n@quotation Note\nTRST is specially handled.\nIt actually signifies JTAG's @sc{reset} state.\nSo if the board doesn't support the optional TRST signal,\nor it doesn't support it along with the specified SRST value,\nJTAG reset is triggered with TMS and TCK signals\ninstead of the TRST signal.\nAnd no matter how that JTAG reset is triggered, once\nthe scan chain enters @sc{reset} with TRST inactive,\nTAP @code{post-reset} events are delivered to all TAPs\nwith handlers for that event.\n@end quotation\n@end deffn\n\n@anchor{memoryaccess}\n@section Memory access commands\n@cindex memory access\n\nThese commands allow accesses of a specific size to the memory\nsystem. Often these are used to configure the current target in some\nspecial way. For example - one may need to write certain values to the\nSDRAM controller to enable SDRAM.\n\n@enumerate\n@item Use the @command{targets} (plural) command\nto change the current target.\n@item In system level scripts these commands are deprecated.\nPlease use their TARGET object siblings to avoid making assumptions\nabout what TAP is the current target, or about MMU configuration.\n@end enumerate\n\n@deffn {Command} {mdd} [phys] addr [count]\n@deffnx {Command} {mdw} [phys] addr [count]\n@deffnx {Command} {mdh} [phys] addr [count]\n@deffnx {Command} {mdb} [phys] addr [count]\nDisplay contents of address @var{addr}, as\n64-bit doublewords (@command{mdd}),\n32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),\nor 8-bit bytes (@command{mdb}).\nWhen the current target has an MMU which is present and active,\n@var{addr} is interpreted as a virtual address.\nOtherwise, or if the optional @var{phys} flag is specified,\n@var{addr} is interpreted as a physical address.\nIf @var{count} is specified, displays that many units.\n(If you want to process the data instead of displaying it,\nsee the @code{read_memory} primitives.)\n@end deffn\n\n@deffn {Command} {mwd} [phys] addr doubleword [count]\n@deffnx {Command} {mww} [phys] addr word [count]\n@deffnx {Command} {mwh} [phys] addr halfword [count]\n@deffnx {Command} {mwb} [phys] addr byte [count]\nWrites the specified @var{doubleword} (64 bits), @var{word} (32 bits),\n@var{halfword} (16 bits), or @var{byte} (8-bit) value,\nat the specified address @var{addr}.\nWhen the current target has an MMU which is present and active,\n@var{addr} is interpreted as a virtual address.\nOtherwise, or if the optional @var{phys} flag is specified,\n@var{addr} is interpreted as a physical address.\nIf @var{count} is specified, fills that many units of consecutive address.\n@end deffn\n\n@anchor{imageaccess}\n@section Image loading commands\n@cindex image loading\n@cindex image dumping\n\n@deffn {Command} {dump_image} filename address size\nDump @var{size} bytes of target memory starting at @var{address} to the\nbinary file named @var{filename}.\n@end deffn\n\n@deffn {Command} {fast_load}\nLoads an image stored in memory by @command{fast_load_image} to the\ncurrent target. Must be preceded by fast_load_image.\n@end deffn\n\n@deffn {Command} {fast_load_image} filename address [@option{bin}|@option{ihex}|@option{elf}|@option{s19}]\nNormally you should be using @command{load_image} or GDB load. However, for\ntesting purposes or when I/O overhead is significant(OpenOCD running on an embedded\nhost), storing the image in memory and uploading the image to the target\ncan be a way to upload e.g. multiple debug sessions when the binary does not change.\nArguments are the same as @command{load_image}, but the image is stored in OpenOCD host\nmemory, i.e. does not affect target. This approach is also useful when profiling\ntarget programming performance as I/O and target programming can easily be profiled\nseparately.\n@end deffn\n\n@deffn {Command} {load_image} filename address [[@option{bin}|@option{ihex}|@option{elf}|@option{s19}] @option{min_addr} @option{max_length}]\nLoad image from file @var{filename} to target memory offset by @var{address} from its load address.\nThe file format may optionally be specified\n(@option{bin}, @option{ihex}, @option{elf}, or @option{s19}).\nIn addition the following arguments may be specified:\n@var{min_addr} - ignore data below @var{min_addr} (this is w.r.t. to the target's load address + @var{address})\n@var{max_length} - maximum number of bytes to load.\n@example\nproc load_image_bin @{fname foffset address length @} @{\n    # Load data from fname filename at foffset offset to\n    # target at address. Load at most length bytes.\n    load_image $fname [expr @{$address - $foffset@}] bin \\\n               $address $length\n@}\n@end example\n@end deffn\n\n@deffn {Command} {test_image} filename [address [@option{bin}|@option{ihex}|@option{elf}]]\nDisplays image section sizes and addresses\nas if @var{filename} were loaded into target memory\nstarting at @var{address} (defaults to zero).\nThe file format may optionally be specified\n(@option{bin}, @option{ihex}, or @option{elf})\n@end deffn\n\n@deffn {Command} {verify_image} filename address [@option{bin}|@option{ihex}|@option{elf}]\nVerify @var{filename} against target memory starting at @var{address}.\nThe file format may optionally be specified\n(@option{bin}, @option{ihex}, or @option{elf})\nThis will first attempt a comparison using a CRC checksum, if this fails it will try a binary compare.\n@end deffn\n\n@deffn {Command} {verify_image_checksum} filename address [@option{bin}|@option{ihex}|@option{elf}]\nVerify @var{filename} against target memory starting at @var{address}.\nThe file format may optionally be specified\n(@option{bin}, @option{ihex}, or @option{elf})\nThis perform a comparison using a CRC checksum only\n@end deffn\n\n\n@section Breakpoint and Watchpoint commands\n@cindex breakpoint\n@cindex watchpoint\n\nCPUs often make debug modules accessible through JTAG, with\nhardware support for a handful of code breakpoints and data\nwatchpoints.\nIn addition, CPUs almost always support software breakpoints.\n\n@deffn {Command} {bp} [address len [@option{hw}]]\nWith no parameters, lists all active breakpoints.\nElse sets a breakpoint on code execution starting\nat @var{address} for @var{length} bytes.\nThis is a software breakpoint, unless @option{hw} is specified\nin which case it will be a hardware breakpoint.\n\n(@xref{arm9vectorcatch,,arm9 vector_catch}, or @pxref{xscalevectorcatch,,xscale vector_catch},\nfor similar mechanisms that do not consume hardware breakpoints.)\n@end deffn\n\n@deffn {Command} {rbp} @option{all} | address\nRemove the breakpoint at @var{address} or all breakpoints.\n@end deffn\n\n@deffn {Command} {rwp} address\nRemove data watchpoint on @var{address}\n@end deffn\n\n@deffn {Command} {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]]\nWith no parameters, lists all active watchpoints.\nElse sets a data watchpoint on data from @var{address} for @var{length} bytes.\nThe watch point is an \"access\" watchpoint unless\nthe @option{r} or @option{w} parameter is provided,\ndefining it as respectively a read or write watchpoint.\nIf a @var{value} is provided, that value is used when determining if\nthe watchpoint should trigger. The value may be first be masked\nusing @var{mask} to mark ``don't care'' fields.\n@end deffn\n\n\n@section Real Time Transfer (RTT)\n\nReal Time Transfer (RTT) is an interface specified by SEGGER based on basic\nmemory reads and writes to transfer data bidirectionally between target and host.\nThe specification is independent of the target architecture.\nEvery target that supports so called \"background memory access\", which means\nthat the target memory can be accessed by the debugger while the target is\nrunning, can be used.\nThis interface is especially of interest for targets without\nSerial Wire Output (SWO), such as ARM Cortex-M0, or where semihosting is not\napplicable because of real-time constraints.\n\n@quotation Note\nThe current implementation supports only single target devices.\n@end quotation\n\nThe data transfer between host and target device is organized through\nunidirectional up/down-channels for target-to-host and host-to-target\ncommunication, respectively.\n\n@quotation Note\nThe current implementation does not respect channel buffer flags.\nThey are used to determine what happens when writing to a full buffer, for\nexample.\n@end quotation\n\nChannels are exposed via raw TCP/IP connections. One or more RTT servers can be\nassigned to each channel to make them accessible to an unlimited number\nof TCP/IP connections.\n\n@deffn {Command} {rtt setup} address size ID\nConfigure RTT for the currently selected target.\nOnce RTT is started, OpenOCD searches for a control block with the\nidentifier @var{ID} starting at the memory address @var{address} within the next\n@var{size} bytes.\n@end deffn\n\n@deffn {Command} {rtt start}\nStart RTT.\nIf the control block location is not known, OpenOCD starts searching for it.\n@end deffn\n\n@deffn {Command} {rtt stop}\nStop RTT.\n@end deffn\n\n@deffn {Command} {rtt polling_interval} [interval]\nDisplay the polling interval.\nIf @var{interval} is provided, set the polling interval.\nThe polling interval determines (in milliseconds) how often the up-channels are\nchecked for new data.\n@end deffn\n\n@deffn {Command} {rtt channels}\nDisplay a list of all channels and their properties.\n@end deffn\n\n@deffn {Command} {rtt channellist}\nReturn a list of all channels and their properties as Tcl list.\nThe list can be manipulated easily from within scripts.\n@end deffn\n\n@deffn {Command} {rtt server start} port channel\nStart a TCP server on @var{port} for the channel @var{channel}.\n@end deffn\n\n@deffn {Command} {rtt server stop} port\nStop the TCP sever with port @var{port}.\n@end deffn\n\nThe following example shows how to setup RTT using the SEGGER RTT implementation\non the target device.\n\n@example\nresume\n\nrtt setup 0x20000000 2048 \"SEGGER RTT\"\nrtt start\n\nrtt server start 9090 0\n@end example\n\nIn this example, OpenOCD searches the control block with the ID \"SEGGER RTT\"\nstarting at 0x20000000 for 2048 bytes. The RTT channel 0 is exposed through the\nTCP/IP port 9090.\n\n\n@section Misc Commands\n\n@cindex profiling\n@deffn {Command} {profile} seconds filename [start end]\nProfiling samples the CPU's program counter as quickly as possible,\nwhich is useful for non-intrusive stochastic profiling.\nSaves up to 10000 samples in @file{filename} using ``gmon.out''\nformat. Optional @option{start} and @option{end} parameters allow to\nlimit the address range.\n@end deffn\n\n@deffn {Command} {version} [git]\nReturns a string identifying the version of this OpenOCD server.\nWith option @option{git}, it returns the git version obtained at compile time\nthrough ``git describe''.\n@end deffn\n\n@deffn {Command} {virt2phys} virtual_address\nRequests the current target to map the specified @var{virtual_address}\nto its corresponding physical address, and displays the result.\n@end deffn\n\n@deffn {Command} {add_help_text} 'command_name' 'help-string'\nAdd or replace help text on the given @var{command_name}.\n@end deffn\n\n@deffn {Command} {add_usage_text} 'command_name' 'help-string'\nAdd or replace usage text on the given @var{command_name}.\n@end deffn\n\n@node Architecture and Core Commands\n@chapter Architecture and Core Commands\n@cindex Architecture Specific Commands\n@cindex Core Specific Commands\n\nMost CPUs have specialized JTAG operations to support debugging.\nOpenOCD packages most such operations in its standard command framework.\nSome of those operations don't fit well in that framework, so they are\nexposed here as architecture or implementation (core) specific commands.\n\n@anchor{armhardwaretracing}\n@section ARM Hardware Tracing\n@cindex tracing\n@cindex ETM\n@cindex ETB\n\nCPUs based on ARM cores may include standard tracing interfaces,\nbased on an ``Embedded Trace Module'' (ETM) which sends voluminous\naddress and data bus trace records to a ``Trace Port''.\n\n@itemize\n@item\nDevelopment-oriented boards will sometimes provide a high speed\ntrace connector for collecting that data, when the particular CPU\nsupports such an interface.\n(The standard connector is a 38-pin Mictor, with both JTAG\nand trace port support.)\nThose trace connectors are supported by higher end JTAG adapters\nand some logic analyzer modules; frequently those modules can\nbuffer several megabytes of trace data.\nConfiguring an ETM coupled to such an external trace port belongs\nin the board-specific configuration file.\n@item\nIf the CPU doesn't provide an external interface, it probably\nhas an ``Embedded Trace Buffer'' (ETB) on the chip, which is a\ndedicated SRAM. 4KBytes is one common ETB size.\nConfiguring an ETM coupled only to an ETB belongs in the CPU-specific\n(target) configuration file, since it works the same on all boards.\n@end itemize\n\nETM support in OpenOCD doesn't seem to be widely used yet.\n\n@quotation Issues\nETM support may be buggy, and at least some @command{etm config}\nparameters should be detected by asking the ETM for them.\n\nETM trigger events could also implement a kind of complex\nhardware breakpoint, much more powerful than the simple\nwatchpoint hardware exported by EmbeddedICE modules.\n@emph{Such breakpoints can be triggered even when using the\ndummy trace port driver}.\n\nIt seems like a GDB hookup should be possible,\nas well as tracing only during specific states\n(perhaps @emph{handling IRQ 23} or @emph{calls foo()}).\n\nThere should be GUI tools to manipulate saved trace data and help\nanalyse it in conjunction with the source code.\nIt's unclear how much of a common interface is shared\nwith the current XScale trace support, or should be\nshared with eventual Nexus-style trace module support.\n\nAt this writing (November 2009) only ARM7, ARM9, and ARM11 support\nfor ETM modules is available. The code should be able to\nwork with some newer cores; but not all of them support\nthis original style of JTAG access.\n@end quotation\n\n@subsection ETM Configuration\nETM setup is coupled with the trace port driver configuration.\n\n@deffn {Config Command} {etm config} target width mode clocking driver\nDeclares the ETM associated with @var{target}, and associates it\nwith a given trace port @var{driver}. @xref{traceportdrivers,,Trace Port Drivers}.\n\nSeveral of the parameters must reflect the trace port capabilities,\nwhich are a function of silicon capabilities (exposed later\nusing @command{etm info}) and of what hardware is connected to\nthat port (such as an external pod, or ETB).\nThe @var{width} must be either 4, 8, or 16,\nexcept with ETMv3.0 and newer modules which may also\nsupport 1, 2, 24, 32, 48, and 64 bit widths.\n(With those versions, @command{etm info} also shows whether\nthe selected port width and mode are supported.)\n\nThe @var{mode} must be @option{normal}, @option{multiplexed},\nor @option{demultiplexed}.\nThe @var{clocking} must be @option{half} or @option{full}.\n\n@quotation Warning\nWith ETMv3.0 and newer, the bits set with the @var{mode} and\n@var{clocking} parameters both control the mode.\nThis modified mode does not map to the values supported by\nprevious ETM modules, so this syntax is subject to change.\n@end quotation\n\n@quotation Note\nYou can see the ETM registers using the @command{reg} command.\nNot all possible registers are present in every ETM.\nMost of the registers are write-only, and are used to configure\nwhat CPU activities are traced.\n@end quotation\n@end deffn\n\n@deffn {Command} {etm info}\nDisplays information about the current target's ETM.\nThis includes resource counts from the @code{ETM_CONFIG} register,\nas well as silicon capabilities (except on rather old modules).\nfrom the @code{ETM_SYS_CONFIG} register.\n@end deffn\n\n@deffn {Command} {etm status}\nDisplays status of the current target's ETM and trace port driver:\nis the ETM idle, or is it collecting data?\nDid trace data overflow?\nWas it triggered?\n@end deffn\n\n@deffn {Command} {etm tracemode} [type context_id_bits cycle_accurate branch_output]\nDisplays what data that ETM will collect.\nIf arguments are provided, first configures that data.\nWhen the configuration changes, tracing is stopped\nand any buffered trace data is invalidated.\n\n@itemize\n@item @var{type} ... describing how data accesses are traced,\nwhen they pass any ViewData filtering that was set up.\nThe value is one of\n@option{none} (save nothing),\n@option{data} (save data),\n@option{address} (save addresses),\n@option{all} (save data and addresses)\n@item @var{context_id_bits} ... 0, 8, 16, or 32\n@item @var{cycle_accurate} ... @option{enable} or @option{disable}\ncycle-accurate instruction tracing.\nBefore ETMv3, enabling this causes much extra data to be recorded.\n@item @var{branch_output} ... @option{enable} or @option{disable}.\nDisable this unless you need to try reconstructing the instruction\ntrace stream without an image of the code.\n@end itemize\n@end deffn\n\n@deffn {Command} {etm trigger_debug} (@option{enable}|@option{disable})\nDisplays whether ETM triggering debug entry (like a breakpoint) is\nenabled or disabled, after optionally modifying that configuration.\nThe default behaviour is @option{disable}.\nAny change takes effect after the next @command{etm start}.\n\nBy using script commands to configure ETM registers, you can make the\nprocessor enter debug state automatically when certain conditions,\nmore complex than supported by the breakpoint hardware, happen.\n@end deffn\n\n@subsection ETM Trace Operation\n\nAfter setting up the ETM, you can use it to collect data.\nThat data can be exported to files for later analysis.\nIt can also be parsed with OpenOCD, for basic sanity checking.\n\nTo configure what is being traced, you will need to write\nvarious trace registers using @command{reg ETM_*} commands.\nFor the definitions of these registers, read ARM publication\n@emph{IHI 0014, ``Embedded Trace Macrocell, Architecture Specification''}.\nBe aware that most of the relevant registers are write-only,\nand that ETM resources are limited. There are only a handful\nof address comparators, data comparators, counters, and so on.\n\nExamples of scenarios you might arrange to trace include:\n\n@itemize\n@item Code flow within a function, @emph{excluding} subroutines\nit calls. Use address range comparators to enable tracing\nfor instruction access within that function's body.\n@item Code flow within a function, @emph{including} subroutines\nit calls. Use the sequencer and address comparators to activate\ntracing on an ``entered function'' state, then deactivate it by\nexiting that state when the function's exit code is invoked.\n@item Code flow starting at the fifth invocation of a function,\ncombining one of the above models with a counter.\n@item CPU data accesses to the registers for a particular device,\nusing address range comparators and the ViewData logic.\n@item Such data accesses only during IRQ handling, combining the above\nmodel with sequencer triggers which on entry and exit to the IRQ handler.\n@item @emph{... more}\n@end itemize\n\nAt this writing, September 2009, there are no Tcl utility\nprocedures to help set up any common tracing scenarios.\n\n@deffn {Command} {etm analyze}\nReads trace data into memory, if it wasn't already present.\nDecodes and prints the data that was collected.\n@end deffn\n\n@deffn {Command} {etm dump} filename\nStores the captured trace data in @file{filename}.\n@end deffn\n\n@deffn {Command} {etm image} filename [base_address] [type]\nOpens an image file.\n@end deffn\n\n@deffn {Command} {etm load} filename\nLoads captured trace data from @file{filename}.\n@end deffn\n\n@deffn {Command} {etm start}\nStarts trace data collection.\n@end deffn\n\n@deffn {Command} {etm stop}\nStops trace data collection.\n@end deffn\n\n@anchor{traceportdrivers}\n@subsection Trace Port Drivers\n\nTo use an ETM trace port it must be associated with a driver.\n\n@deffn {Trace Port Driver} {dummy}\nUse the @option{dummy} driver if you are configuring an ETM that's\nnot connected to anything (on-chip ETB or off-chip trace connector).\n@emph{This driver lets OpenOCD talk to the ETM, but it does not expose\nany trace data collection.}\n@deffn {Config Command} {etm_dummy config} target\nAssociates the ETM for @var{target} with a dummy driver.\n@end deffn\n@end deffn\n\n@deffn {Trace Port Driver} {etb}\nUse the @option{etb} driver if you are configuring an ETM\nto use on-chip ETB memory.\n@deffn {Config Command} {etb config} target etb_tap\nAssociates the ETM for @var{target} with the ETB at @var{etb_tap}.\nYou can see the ETB registers using the @command{reg} command.\n@end deffn\n@deffn {Command} {etb trigger_percent} [percent]\nThis displays, or optionally changes, ETB behavior after the\nETM's configured @emph{trigger} event fires.\nIt controls how much more trace data is saved after the (single)\ntrace trigger becomes active.\n\n@itemize\n@item The default corresponds to @emph{trace around} usage,\nrecording 50 percent data before the event and the rest\nafterwards.\n@item The minimum value of @var{percent} is 2 percent,\nrecording almost exclusively data before the trigger.\nSuch extreme @emph{trace before} usage can help figure out\nwhat caused that event to happen.\n@item The maximum value of @var{percent} is 100 percent,\nrecording data almost exclusively after the event.\nThis extreme @emph{trace after} usage might help sort out\nhow the event caused trouble.\n@end itemize\n@c REVISIT allow \"break\" too -- enter debug mode.\n@end deffn\n\n@end deffn\n\n@anchor{armcrosstrigger}\n@section ARM Cross-Trigger Interface\n@cindex CTI\n\nThe ARM Cross-Trigger Interface (CTI) is a generic CoreSight component\nthat connects event sources like tracing components or CPU cores with each\nother through a common trigger matrix (CTM). For ARMv8 architecture, a\nCTI is mandatory for core run control and each core has an individual\nCTI instance attached to it. OpenOCD has limited support for CTI using\nthe @emph{cti} group of commands.\n\n@deffn {Command} {cti create} cti_name @option{-dap} dap_name @option{-ap-num} apn @option{-baseaddr} base_address\nCreates a CTI instance @var{cti_name} on the DAP instance @var{dap_name} on MEM-AP\n@var{apn}.\nOn ADIv5 DAP @var{apn} is the numeric index of the DAP AP the CTI is connected to.\nOn ADIv6 DAP @var{apn} is the base address of the DAP AP the CTI is connected to.\nThe @var{base_address} must match the base address of the CTI\non the respective MEM-AP. All arguments are mandatory. This creates a\nnew command @command{$cti_name} which is used for various purposes\nincluding additional configuration.\n@end deffn\n\n@deffn {Command} {$cti_name enable} @option{on|off}\nEnable (@option{on}) or disable (@option{off}) the CTI.\n@end deffn\n\n@deffn {Command} {$cti_name dump}\nDisplays a register dump of the CTI.\n@end deffn\n\n@deffn {Command} {$cti_name write} @var{reg_name} @var{value}\nWrite @var{value} to the CTI register with the symbolic name @var{reg_name}.\n@end deffn\n\n@deffn {Command} {$cti_name read} @var{reg_name}\nPrint the value read from the CTI register with the symbolic name @var{reg_name}.\n@end deffn\n\n@deffn {Command} {$cti_name ack} @var{event}\nAcknowledge a CTI @var{event}.\n@end deffn\n\n@deffn {Command} {$cti_name channel} @var{channel_number} @var{operation}\nPerform a specific channel operation, the possible operations are:\ngate, ungate, set, clear and pulse\n@end deffn\n\n@deffn {Command} {$cti_name testmode} @option{on|off}\nEnable (@option{on}) or disable (@option{off}) the integration test mode\nof the CTI.\n@end deffn\n\n@deffn {Command} {cti names}\nPrints a list of names of all CTI objects created. This command is mainly\nuseful in TCL scripting.\n@end deffn\n\n@section Generic ARM\n@cindex ARM\n\nThese commands should be available on all ARM processors.\nThey are available in addition to other core-specific\ncommands that may be available.\n\n@deffn {Command} {arm core_state} [@option{arm}|@option{thumb}]\nDisplays the core_state, optionally changing it to process\neither @option{arm} or @option{thumb} instructions.\nThe target may later be resumed in the currently set core_state.\n(Processors may also support the Jazelle state, but\nthat is not currently supported in OpenOCD.)\n@end deffn\n\n@deffn {Command} {arm disassemble} address [count [@option{thumb}]]\n@cindex disassemble\nDisassembles @var{count} instructions starting at @var{address}.\nIf @var{count} is not specified, a single instruction is disassembled.\nIf @option{thumb} is specified, or the low bit of the address is set,\nThumb2 (mixed 16/32-bit) instructions are used;\nelse ARM (32-bit) instructions are used.\n(Processors may also support the Jazelle state, but\nthose instructions are not currently understood by OpenOCD.)\n\nNote that all Thumb instructions are Thumb2 instructions,\nso older processors (without Thumb2 support) will still\nsee correct disassembly of Thumb code.\nAlso, ThumbEE opcodes are the same as Thumb2,\nwith a handful of exceptions.\nThumbEE disassembly currently has no explicit support.\n@end deffn\n\n@deffn {Command} {arm mcr} pX op1 CRn CRm op2 value\nWrite @var{value} to a coprocessor @var{pX} register\npassing parameters @var{CRn},\n@var{CRm}, opcodes @var{opc1} and @var{opc2},\nand using the MCR instruction.\n(Parameter sequence matches the ARM instruction, but omits\nan ARM register.)\n@end deffn\n\n@deffn {Command} {arm mrc} pX coproc op1 CRn CRm op2\nRead a coprocessor @var{pX} register passing parameters @var{CRn},\n@var{CRm}, opcodes @var{opc1} and @var{opc2},\nand the MRC instruction.\nReturns the result so it can be manipulated by Jim scripts.\n(Parameter sequence matches the ARM instruction, but omits\nan ARM register.)\n@end deffn\n\n@deffn {Command} {arm reg}\nDisplay a table of all banked core registers, fetching the current value from every\ncore mode if necessary.\n@end deffn\n\n@deffn {Command} {arm semihosting} [@option{enable}|@option{disable}]\n@cindex ARM semihosting\nDisplay status of semihosting, after optionally changing that status.\n\nSemihosting allows for code executing on an ARM target to use the\nI/O facilities on the host computer i.e. the system where OpenOCD\nis running. The target application must be linked against a library\nimplementing the ARM semihosting convention that forwards operation\nrequests by using a special SVC instruction that is trapped at the\nSupervisor Call vector by OpenOCD.\n@end deffn\n\n@deffn {Command} {arm semihosting_redirect} (@option{disable} | @option{tcp} <port> [@option{debug}|@option{stdio}|@option{all}])\n@cindex ARM semihosting\nRedirect semihosting messages to a specified TCP port.\n\nThis command redirects debug (READC, WRITEC and WRITE0) and stdio (READ, WRITE)\nsemihosting operations to the specified TCP port.\nThe command allows to select which type of operations to redirect (debug, stdio, all (default)).\n\nNote: for stdio operations, only I/O from/to ':tt' file descriptors are redirected.\n@end deffn\n\n@deffn {Command} {arm semihosting_cmdline} [@option{enable}|@option{disable}]\n@cindex ARM semihosting\nSet the command line to be passed to the debugger.\n\n@example\narm semihosting_cmdline argv0 argv1 argv2 ...\n@end example\n\nThis option lets one set the command line arguments to be passed to\nthe program. The first argument (argv0) is the program name in a\nstandard C environment (argv[0]). Depending on the program (not much\nprograms look at argv[0]), argv0 is ignored and can be any string.\n@end deffn\n\n@deffn {Command} {arm semihosting_fileio} [@option{enable}|@option{disable}]\n@cindex ARM semihosting\nDisplay status of semihosting fileio, after optionally changing that\nstatus.\n\nEnabling this option forwards semihosting I/O to GDB process using the\nFile-I/O remote protocol extension. This is especially useful for\ninteracting with remote files or displaying console messages in the\ndebugger.\n@end deffn\n\n@deffn {Command} {arm semihosting_resexit} [@option{enable}|@option{disable}]\n@cindex ARM semihosting\nEnable resumable SEMIHOSTING_SYS_EXIT.\n\nWhen SEMIHOSTING_SYS_EXIT is called outside a debug session,\nthings are simple, the openocd process calls exit() and passes\nthe value returned by the target.\n\nWhen SEMIHOSTING_SYS_EXIT is called during a debug session,\nby default execution returns to the debugger, leaving the\ndebugger in a HALT state, similar to the state entered when\nencountering a break.\n\nIn some use cases, it is useful to have SEMIHOSTING_SYS_EXIT\nreturn normally, as any semihosting call, and do not break\nto the debugger.\nThe standard allows this to happen, but the condition\nto trigger it is a bit obscure (\"by performing an RDI_Execute\nrequest or equivalent\").\n\nTo make the SEMIHOSTING_SYS_EXIT call return normally, enable\nthis option (default: disabled).\n@end deffn\n\n@deffn {Command} {arm semihosting_read_user_param}\n@cindex ARM semihosting\nRead parameter of the semihosting call from the target. Usable in\nsemihosting-user-cmd-0x10* event handlers, returning a string.\n\nWhen the target makes semihosting call with operation number from range 0x100-\n0x107, an optional string parameter can be passed to the server. This parameter\nis valid during the run of the event handlers and is accessible with this\ncommand.\n@end deffn\n\n@deffn {Command} {arm semihosting_basedir} [dir]\n@cindex ARM semihosting\nSet the base directory for semihosting I/O, either an absolute path or a path relative to OpenOCD working directory.\nUse \".\" for the current directory.\n@end deffn\n\n@section ARMv4 and ARMv5 Architecture\n@cindex ARMv4\n@cindex ARMv5\n\nThe ARMv4 and ARMv5 architectures are widely used in embedded systems,\nand introduced core parts of the instruction set in use today.\nThat includes the Thumb instruction set, introduced in the ARMv4T\nvariant.\n\n@subsection ARM7 and ARM9 specific commands\n@cindex ARM7\n@cindex ARM9\n\nThese commands are specific to ARM7 and ARM9 cores, like ARM7TDMI, ARM720T,\nARM9TDMI, ARM920T or ARM926EJ-S.\nThey are available in addition to the ARM commands,\nand any other core-specific commands that may be available.\n\n@deffn {Command} {arm7_9 dbgrq} [@option{enable}|@option{disable}]\nDisplays the value of the flag controlling use of the\nEmbeddedIce DBGRQ signal to force entry into debug mode,\ninstead of breakpoints.\nIf a boolean parameter is provided, first assigns that flag.\n\nThis should be\nsafe for all but ARM7TDMI-S cores (like NXP LPC).\nThis feature is enabled by default on most ARM9 cores,\nincluding ARM9TDMI, ARM920T, and ARM926EJ-S.\n@end deffn\n\n@deffn {Command} {arm7_9 dcc_downloads} [@option{enable}|@option{disable}]\n@cindex DCC\nDisplays the value of the flag controlling use of the debug communications\nchannel (DCC) to write larger (>128 byte) amounts of memory.\nIf a boolean parameter is provided, first assigns that flag.\n\nDCC downloads offer a huge speed increase, but might be\nunsafe, especially with targets running at very low speeds. This command was introduced\nwith OpenOCD rev. 60, and requires a few bytes of working area.\n@end deffn\n\n@deffn {Command} {arm7_9 fast_memory_access} [@option{enable}|@option{disable}]\nDisplays the value of the flag controlling use of memory writes and reads\nthat don't check completion of the operation.\nIf a boolean parameter is provided, first assigns that flag.\n\nThis provides a huge speed increase, especially with USB JTAG\ncables (FT2232), but might be unsafe if used with targets running at very low\nspeeds, like the 32kHz startup clock of an AT91RM9200.\n@end deffn\n\n@subsection ARM9 specific commands\n@cindex ARM9\n\nARM9-family cores are built around ARM9TDMI or ARM9E (including ARM9EJS)\ninteger processors.\nSuch cores include the ARM920T, ARM926EJ-S, and ARM966.\n\n@c 9-june-2009: tried this on arm920t, it didn't work.\n@c no-params always lists nothing caught, and that's how it acts.\n@c 23-oct-2009: doesn't work _consistently_ ... as if the ICE\n@c versions have different rules about when they commit writes.\n\n@anchor{arm9vectorcatch}\n@deffn {Command} {arm9 vector_catch} [@option{all}|@option{none}|list]\n@cindex vector_catch\nVector Catch hardware provides a sort of dedicated breakpoint\nfor hardware events such as reset, interrupt, and abort.\nYou can use this to conserve normal breakpoint resources,\nso long as you're not concerned with code that branches directly\nto those hardware vectors.\n\nThis always finishes by listing the current configuration.\nIf parameters are provided, it first reconfigures the\nvector catch hardware to intercept\n@option{all} of the hardware vectors,\n@option{none} of them,\nor a list with one or more of the following:\n@option{reset} @option{undef} @option{swi} @option{pabt} @option{dabt}\n@option{irq} @option{fiq}.\n@end deffn\n\n@subsection ARM920T specific commands\n@cindex ARM920T\n\nThese commands are available to ARM920T based CPUs,\nwhich are implementations of the ARMv4T architecture\nbuilt using the ARM9TDMI integer core.\nThey are available in addition to the ARM, ARM7/ARM9,\nand ARM9 commands.\n\n@deffn {Command} {arm920t cache_info}\nPrint information about the caches found. This allows to see whether your target\nis an ARM920T (2x16kByte cache) or ARM922T (2x8kByte cache).\n@end deffn\n\n@deffn {Command} {arm920t cp15} regnum [value]\nDisplay cp15 register @var{regnum};\nelse if a @var{value} is provided, that value is written to that register.\nThis uses \"physical access\" and the register number is as\nshown in bits 38..33 of table 9-9 in the ARM920T TRM.\n(Not all registers can be written.)\n@end deffn\n\n@deffn {Command} {arm920t read_cache} filename\nDump the content of ICache and DCache to a file named @file{filename}.\n@end deffn\n\n@deffn {Command} {arm920t read_mmu} filename\nDump the content of the ITLB and DTLB to a file named @file{filename}.\n@end deffn\n\n@subsection ARM926ej-s specific commands\n@cindex ARM926ej-s\n\nThese commands are available to ARM926ej-s based CPUs,\nwhich are implementations of the ARMv5TEJ architecture\nbased on the ARM9EJ-S integer core.\nThey are available in addition to the ARM, ARM7/ARM9,\nand ARM9 commands.\n\nThe Feroceon cores also support these commands, although\nthey are not built from ARM926ej-s designs.\n\n@deffn {Command} {arm926ejs cache_info}\nPrint information about the caches found.\n@end deffn\n\n@subsection ARM966E specific commands\n@cindex ARM966E\n\nThese commands are available to ARM966 based CPUs,\nwhich are implementations of the ARMv5TE architecture.\nThey are available in addition to the ARM, ARM7/ARM9,\nand ARM9 commands.\n\n@deffn {Command} {arm966e cp15} regnum [value]\nDisplay cp15 register @var{regnum};\nelse if a @var{value} is provided, that value is written to that register.\nThe six bit @var{regnum} values are bits 37..32 from table 7-2 of the\nARM966E-S TRM.\nThere is no current control over bits 31..30 from that table,\nas required for BIST support.\n@end deffn\n\n@subsection XScale specific commands\n@cindex XScale\n\nSome notes about the debug implementation on the XScale CPUs:\n\nThe XScale CPU provides a special debug-only mini-instruction cache\n(mini-IC) in which exception vectors and target-resident debug handler\ncode are placed by OpenOCD. In order to get access to the CPU, OpenOCD\nmust point vector 0 (the reset vector) to the entry of the debug\nhandler. However, this means that the complete first cacheline in the\nmini-IC is marked valid, which makes the CPU fetch all exception\nhandlers from the mini-IC, ignoring the code in RAM.\n\nTo address this situation, OpenOCD provides the @code{xscale\nvector_table} command, which allows the user to explicitly write\nindividual entries to either the high or low vector table stored in\nthe mini-IC.\n\nIt is recommended to place a pc-relative indirect branch in the vector\ntable, and put the branch destination somewhere in memory. Doing so\nmakes sure the code in the vector table stays constant regardless of\ncode layout in memory:\n@example\n_vectors:\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        ldr     pc,[pc,#0x100-8]\n        .org 0x100\n        .long real_reset_vector\n        .long real_ui_handler\n        .long real_swi_handler\n        .long real_pf_abort\n        .long real_data_abort\n        .long 0 /* unused */\n        .long real_irq_handler\n        .long real_fiq_handler\n@end example\n\nAlternatively, you may choose to keep some or all of the mini-IC\nvector table entries synced with those written to memory by your\nsystem software. The mini-IC can not be modified while the processor\nis executing, but for each vector table entry not previously defined\nusing the @code{xscale vector_table} command, OpenOCD will copy the\nvalue from memory to the mini-IC every time execution resumes from a\nhalt. This is done for both high and low vector tables (although the\ntable not in use may not be mapped to valid memory, and in this case\nthat copy operation will silently fail). This means that you will\nneed to briefly halt execution at some strategic point during system\nstart-up; e.g., after the software has initialized the vector table,\nbut before exceptions are enabled. A breakpoint can be used to\naccomplish this once the appropriate location in the start-up code has\nbeen identified. A watchpoint over the vector table region is helpful\nin finding the location if you're not sure. Note that the same\nsituation exists any time the vector table is modified by the system\nsoftware.\n\nThe debug handler must be placed somewhere in the address space using\nthe @code{xscale debug_handler} command. The allowed locations for the\ndebug handler are either (0x800 - 0x1fef800) or (0xfe000800 -\n0xfffff800). The default value is 0xfe000800.\n\nXScale has resources to support two hardware breakpoints and two\nwatchpoints. However, the following restrictions on watchpoint\nfunctionality apply: (1) the value and mask arguments to the @code{wp}\ncommand are not supported, (2) the watchpoint length must be a\npower of two and not less than four, and can not be greater than the\nwatchpoint address, and (3) a watchpoint with a length greater than\nfour consumes all the watchpoint hardware resources. This means that\nat any one time, you can have enabled either two watchpoints with a\nlength of four, or one watchpoint with a length greater than four.\n\nThese commands are available to XScale based CPUs,\nwhich are implementations of the ARMv5TE architecture.\n\n@deffn {Command} {xscale analyze_trace}\nDisplays the contents of the trace buffer.\n@end deffn\n\n@deffn {Command} {xscale cache_clean_address} address\nChanges the address used when cleaning the data cache.\n@end deffn\n\n@deffn {Command} {xscale cache_info}\nDisplays information about the CPU caches.\n@end deffn\n\n@deffn {Command} {xscale cp15} regnum [value]\nDisplay cp15 register @var{regnum};\nelse if a @var{value} is provided, that value is written to that register.\n@end deffn\n\n@deffn {Command} {xscale debug_handler} target address\nChanges the address used for the specified target's debug handler.\n@end deffn\n\n@deffn {Command} {xscale dcache} [@option{enable}|@option{disable}]\nEnables or disable the CPU's data cache.\n@end deffn\n\n@deffn {Command} {xscale dump_trace} filename\nDumps the raw contents of the trace buffer to @file{filename}.\n@end deffn\n\n@deffn {Command} {xscale icache} [@option{enable}|@option{disable}]\nEnables or disable the CPU's instruction cache.\n@end deffn\n\n@deffn {Command} {xscale mmu} [@option{enable}|@option{disable}]\nEnables or disable the CPU's memory management unit.\n@end deffn\n\n@deffn {Command} {xscale trace_buffer} [@option{enable}|@option{disable} [@option{fill} [n] | @option{wrap}]]\nDisplays the trace buffer status, after optionally\nenabling or disabling the trace buffer\nand modifying how it is emptied.\n@end deffn\n\n@deffn {Command} {xscale trace_image} filename [offset [type]]\nOpens a trace image from @file{filename}, optionally rebasing\nits segment addresses by @var{offset}.\nThe image @var{type} may be one of\n@option{bin} (binary), @option{ihex} (Intel hex),\n@option{elf} (ELF file), @option{s19} (Motorola s19),\n@option{mem}, or @option{builder}.\n@end deffn\n\n@anchor{xscalevectorcatch}\n@deffn {Command} {xscale vector_catch} [mask]\n@cindex vector_catch\nDisplay a bitmask showing the hardware vectors to catch.\nIf the optional parameter is provided, first set the bitmask to that value.\n\nThe mask bits correspond with bit 16..23 in the DCSR:\n@example\n0x01    Trap Reset\n0x02    Trap Undefined Instructions\n0x04    Trap Software Interrupt\n0x08    Trap Prefetch Abort\n0x10    Trap Data Abort\n0x20    reserved\n0x40    Trap IRQ\n0x80    Trap FIQ\n@end example\n@end deffn\n\n@deffn {Command} {xscale vector_table} [(@option{low}|@option{high}) index value]\n@cindex vector_table\n\nSet an entry in the mini-IC vector table. There are two tables: one for\nlow vectors (at 0x00000000), and one for high vectors (0xFFFF0000), each\nholding the 8 exception vectors. @var{index} can be 1-7, because vector 0\npoints to the debug handler entry and can not be overwritten.\n@var{value} holds the 32-bit opcode that is placed in the mini-IC.\n\nWithout arguments, the current settings are displayed.\n\n@end deffn\n\n@section ARMv6 Architecture\n@cindex ARMv6\n\n@subsection ARM11 specific commands\n@cindex ARM11\n\n@deffn {Command} {arm11 memwrite burst} [@option{enable}|@option{disable}]\nDisplays the value of the memwrite burst-enable flag,\nwhich is enabled by default.\nIf a boolean parameter is provided, first assigns that flag.\nBurst writes are only used for memory writes larger than 1 word.\nThey improve performance by assuming that the CPU has read each data\nword over JTAG and completed its write before the next word arrives,\ninstead of polling for a status flag to verify that completion.\nThis is usually safe, because JTAG runs much slower than the CPU.\n@end deffn\n\n@deffn {Command} {arm11 memwrite error_fatal} [@option{enable}|@option{disable}]\nDisplays the value of the memwrite error_fatal flag,\nwhich is enabled by default.\nIf a boolean parameter is provided, first assigns that flag.\nWhen set, certain memory write errors cause earlier transfer termination.\n@end deffn\n\n@deffn {Command} {arm11 step_irq_enable} [@option{enable}|@option{disable}]\nDisplays the value of the flag controlling whether\nIRQs are enabled during single stepping;\nthey are disabled by default.\nIf a boolean parameter is provided, first assigns that.\n@end deffn\n\n@deffn {Command} {arm11 vcr} [value]\n@cindex vector_catch\nDisplays the value of the @emph{Vector Catch Register (VCR)},\ncoprocessor 14 register 7.\nIf @var{value} is defined, first assigns that.\n\nVector Catch hardware provides dedicated breakpoints\nfor certain hardware events.\nThe specific bit values are core-specific (as in fact is using\ncoprocessor 14 register 7 itself) but all current ARM11\ncores @emph{except the ARM1176} use the same six bits.\n@end deffn\n\n@section ARMv7 and ARMv8 Architecture\n@cindex ARMv7\n@cindex ARMv8\n\n@subsection ARMv7-A specific commands\n@cindex Cortex-A\n\n@deffn {Command} {cortex_a cache_info}\ndisplay information about target caches\n@end deffn\n\n@deffn {Command} {cortex_a dacrfixup} [@option{on}|@option{off}]\nWork around issues with software breakpoints when the program text is\nmapped read-only by the operating system. This option sets the CP15 DACR\nto \"all-manager\" to bypass MMU permission checks on memory access.\nDefaults to 'off'.\n@end deffn\n\n@deffn {Command} {cortex_a dbginit}\nInitialize core debug\nEnables debug by unlocking the Software Lock and clearing sticky powerdown indications\n@end deffn\n\n@deffn {Command} {cortex_a smp} [on|off]\nDisplay/set the current SMP mode\n@end deffn\n\n@deffn {Command} {cortex_a smp_gdb} [core_id]\nDisplay/set the current core displayed in GDB\n@end deffn\n\n@deffn {Command} {cortex_a maskisr} [@option{on}|@option{off}]\nSelects whether interrupts will be processed when single stepping\n@end deffn\n\n@deffn {Command} {cache_config l2x}  [base way]\nconfigure l2x cache\n@end deffn\n\n@deffn {Command} {cortex_a mmu dump} [@option{0}|@option{1}|@option{addr} address [@option{num_entries}]]\nDump the MMU translation table from TTB0 or TTB1 register, or from physical\nmemory location @var{address}. When dumping the table from @var{address}, print at most\n@var{num_entries} page table entries. @var{num_entries} is optional, if omitted, the maximum\npossible (4096) entries are printed.\n@end deffn\n\n@subsection ARMv7-R specific commands\n@cindex Cortex-R\n\n@deffn {Command} {cortex_r4 dbginit}\nInitialize core debug\nEnables debug by unlocking the Software Lock and clearing sticky powerdown indications\n@end deffn\n\n@deffn {Command} {cortex_r4 maskisr} [@option{on}|@option{off}]\nSelects whether interrupts will be processed when single stepping\n@end deffn\n\n\n@subsection ARM CoreSight TPIU and SWO specific commands\n@cindex tracing\n@cindex SWO\n@cindex SWV\n@cindex TPIU\n\nARM CoreSight provides several modules to generate debugging\ninformation internally (ITM, DWT and ETM). Their output is directed\nthrough TPIU or SWO modules to be captured externally either on an SWO pin (this\nconfiguration is called SWV) or on a synchronous parallel trace port.\n\nARM CoreSight provides independent HW blocks named TPIU and SWO each with its\nown functionality. Embedded in Cortex-M3 and M4, ARM provides an optional HW\nblock that includes both TPIU and SWO functionalities and is again named TPIU,\nwhich causes quite some confusion.\nThe registers map of all the TPIU and SWO implementations allows using a single\ndriver that detects at runtime the features available.\n\nThe @command{tpiu} is used for either TPIU or SWO.\nA convenient alias @command{swo} is available to help distinguish, in scripts,\nthe commands for SWO from the commands for TPIU.\n\n@deffn {Command} {swo} ...\nAlias of @command{tpiu ...}. Can be used in scripts to distinguish the commands\nfor SWO from the commands for TPIU.\n@end deffn\n\n@deffn {Command} {tpiu create} tpiu_name configparams...\nCreates a TPIU or a SWO object. The two commands are equivalent.\nAdd the object in a list and add new commands (@command{@var{tpiu_name}})\nwhich are used for various purposes including additional configuration.\n\n@itemize @bullet\n@item @var{tpiu_name} -- the name of the TPIU or SWO object.\nThis name is also used to create the object's command, referred to here\nas @command{$tpiu_name}, and in other places where the TPIU or SWO needs to be identified.\n@item @var{configparams} -- all parameters accepted by @command{$tpiu_name configure} are permitted.\n\nYou @emph{must} set here the AP and MEM_AP base_address through @code{-dap @var{dap_name}},\n@code{-ap-num @var{ap_number}} and @code{-baseaddr @var{base_address}}.\n@end itemize\n@end deffn\n\n@deffn {Command} {tpiu names}\nLists all the TPIU or SWO objects created so far. The two commands are equivalent.\n@end deffn\n\n@deffn {Command} {tpiu init}\nInitialize all registered TPIU and SWO. The two commands are equivalent.\nThese commands are used internally during initialization. They can be issued\nat any time after the initialization, too.\n@end deffn\n\n@deffn {Command} {$tpiu_name cget} queryparm\nEach configuration parameter accepted by @command{$tpiu_name configure} can be\nindividually queried, to return its current value.\nThe @var{queryparm} is a parameter name accepted by that command, such as @code{-dap}.\n@end deffn\n\n@deffn {Command} {$tpiu_name configure} configparams...\nThe options accepted by this command may also be specified as parameters\nto @command{tpiu create}. Their values can later be queried one at a time by\nusing the @command{$tpiu_name cget} command.\n\n@itemize @bullet\n@item @code{-dap} @var{dap_name} -- names the DAP used to access this\nTPIU. @xref{dapdeclaration,,DAP declaration}, on how to create and manage DAP instances.\n\n@item @code{-ap-num} @var{ap_number} -- sets DAP access port for TPIU.\nOn ADIv5 DAP @var{ap_number} is the numeric index of the DAP AP the TPIU is connected to.\nOn ADIv6 DAP @var{ap_number} is the base address of the DAP AP the TPIU is connected to.\n\n@item @code{-baseaddr} @var{base_address} -- sets the TPIU @var{base_address} where\nto access the TPIU in the DAP AP memory space.\n\n@item @code{-protocol} (@option{sync}|@option{uart}|@option{manchester}) -- sets the\nprotocol used for trace data:\n@itemize @minus\n@item @option{sync} -- synchronous parallel trace output mode, using @var{port_width}\n data bits (default);\n@item @option{uart} -- use asynchronous SWO mode with NRZ (same as regular UART 8N1) coding;\n@item @option{manchester} -- use asynchronous SWO mode with Manchester coding.\n@end itemize\n\n@item @code{-event} @var{event_name} @var{event_body} -- assigns an event handler,\na TCL string which is evaluated when the event is triggered. The events\n@code{pre-enable}, @code{post-enable}, @code{pre-disable} and @code{post-disable}\nare defined for TPIU/SWO.\nA typical use case for the event @code{pre-enable} is to enable the trace clock\nof the TPIU.\n\n@item @code{-output} (@option{external}|@option{:}@var{port}|@var{filename}|@option{-}) -- specifies\nthe destination of the trace data:\n@itemize @minus\n@item @option{external} -- configure TPIU/SWO to let user capture trace\noutput externally, either with an additional UART or with a logic analyzer (default);\n@item @option{-} -- configure TPIU/SWO and debug adapter to gather trace data\nand forward it to @command{tcl_trace} command;\n@item @option{:}@var{port} -- configure TPIU/SWO and debug adapter to gather\ntrace data, open a TCP server at port @var{port} and send the trace data to\neach connected client;\n@item @var{filename} -- configure TPIU/SWO and debug adapter to\ngather trace data and append it to @var{filename}, which can be\neither a regular file or a named pipe.\n@end itemize\n\n@item @code{-traceclk} @var{TRACECLKIN_freq} -- mandatory parameter.\nSpecifies the frequency in Hz of the trace clock. For the TPIU embedded in\nCortex-M3 or M4, this is usually the same frequency as HCLK. For protocol\n@option{sync} this is twice the frequency of the pin data rate.\n\n@item @code{-pin-freq} @var{trace_freq} -- specifies the expected data rate\nin Hz of the SWO pin. Parameter used only on protocols @option{uart} and\n@option{manchester}. Can be omitted to let the adapter driver select the\nmaximum supported rate automatically.\n\n@item @code{-port-width} @var{port_width} -- sets to @var{port_width} the width\nof the synchronous parallel port used for trace output. Parameter used only on\nprotocol @option{sync}. If not specified, default value is @var{1}.\n\n@item @code{-formatter} (@option{0}|@option{1}) -- specifies if the formatter\nshould be enabled. Parameter used only on protocol @option{sync}. If not specified,\ndefault value is @var{0}.\n@end itemize\n@end deffn\n\n@deffn {Command} {$tpiu_name enable}\nUses the parameters specified by the previous @command{$tpiu_name configure}\nto configure and enable the TPIU or the SWO.\nIf required, the adapter is also configured and enabled to receive the trace\ndata.\nThis command can be used before @command{init}, but it will take effect only\nafter the @command{init}.\n@end deffn\n\n@deffn {Command} {$tpiu_name disable}\nDisable the TPIU or the SWO, terminating the receiving of the trace data.\n@end deffn\n\n\n\nExample usage:\n@enumerate\n@item STM32L152 board is programmed with an application that configures\nPLL to provide core clock with 24MHz frequency; to use ITM output it's\nenough to:\n@example\n#include <libopencm3/cm3/itm.h>\n    ...\n    \tITM_STIM8(0) = c;\n    ...\n@end example\n(the most obvious way is to use the first stimulus port for printf,\nfor that this ITM_STIM8 assignment can be used inside _write(); to make it\nblocking to avoid data loss, add @code{while (!(ITM_STIM8(0) &\nITM_STIM_FIFOREADY));});\n@item An FT2232H UART is connected to the SWO pin of the board;\n@item Commands to configure UART for 12MHz baud rate:\n@example\n$ setserial /dev/ttyUSB1 spd_cust divisor 5\n$ stty -F /dev/ttyUSB1 38400\n@end example\n(FT2232H's base frequency is 60MHz, spd_cust allows to alias 38400\nbaud with our custom divisor to get 12MHz)\n@item @code{itmdump -f /dev/ttyUSB1 -d1}\n@item OpenOCD invocation line:\n@example\nopenocd -f interface/stlink.cfg \\\n-c \"transport select hla_swd\" \\\n-f target/stm32l1.cfg \\\n-c \"stm32l1.tpiu configure -protocol uart\" \\\n-c \"stm32l1.tpiu configure -traceclk 24000000 -pin-freq 12000000\" \\\n-c \"stm32l1.tpiu enable\"\n@end example\n@end enumerate\n\n@subsection ARMv7-M specific commands\n@cindex tracing\n@cindex SWO\n@cindex SWV\n@cindex ITM\n@cindex ETM\n\n@deffn {Command} {itm port} @var{port} (@option{0}|@option{1}|@option{on}|@option{off})\nEnable or disable trace output for ITM stimulus @var{port} (counting\nfrom 0). Port 0 is enabled on target creation automatically.\n@end deffn\n\n@deffn {Command} {itm ports} (@option{0}|@option{1}|@option{on}|@option{off})\nEnable or disable trace output for all ITM stimulus ports.\n@end deffn\n\n@subsection Cortex-M specific commands\n@cindex Cortex-M\n\n@deffn {Command} {cortex_m maskisr} (@option{auto}|@option{on}|@option{off}|@option{steponly})\nControl masking (disabling) interrupts during target step/resume.\n\nThe @option{auto} option handles interrupts during stepping in a way that they\nget served but don't disturb the program flow. The step command first allows\npending interrupt handlers to execute, then disables interrupts and steps over\nthe next instruction where the core was halted. After the step interrupts\nare enabled again. If the interrupt handlers don't complete within 500ms,\nthe step command leaves with the core running.\n\nThe @option{steponly} option disables interrupts during single-stepping but\nenables them during normal execution. This can be used as a partial workaround\nfor 702596 erratum in Cortex-M7 r0p1. See \"Cortex-M7 (AT610) and Cortex-M7 with\nFPU (AT611) Software Developer Errata Notice\" from ARM for further details.\n\nNote that a free hardware (FPB) breakpoint is required for the @option{auto}\noption. If no breakpoint is available at the time of the step, then the step\nis taken with interrupts enabled, i.e. the same way the @option{off} option\ndoes.\n\nDefault is @option{auto}.\n@end deffn\n\n@deffn {Command} {cortex_m vector_catch} [@option{all}|@option{none}|list]\n@cindex vector_catch\nVector Catch hardware provides dedicated breakpoints\nfor certain hardware events.\n\nParameters request interception of\n@option{all} of these hardware event vectors,\n@option{none} of them,\nor one or more of the following:\n@option{hard_err} for a HardFault exception;\n@option{mm_err} for a MemManage exception;\n@option{bus_err} for a BusFault exception;\n@option{irq_err},\n@option{state_err},\n@option{chk_err}, or\n@option{nocp_err} for various UsageFault exceptions; or\n@option{reset}.\nIf NVIC setup code does not enable them,\nMemManage, BusFault, and UsageFault exceptions\nare mapped to HardFault.\nUsageFault checks for\ndivide-by-zero and unaligned access\nmust also be explicitly enabled.\n\nThis finishes by listing the current vector catch configuration.\n@end deffn\n\n@deffn {Command} {cortex_m reset_config} (@option{sysresetreq}|@option{vectreset})\nControl reset handling if hardware srst is not fitted\n@xref{reset_config,,reset_config}.\n\n@itemize @minus\n@item @option{sysresetreq} use AIRCR SYSRESETREQ to reset system.\n@item @option{vectreset} use AIRCR VECTRESET to reset system (default).\n@end itemize\n\nUsing @option{vectreset} is a safe option for Cortex-M3, M4 and M7 cores.\nThis however has the disadvantage of only resetting the core, all peripherals\nare unaffected. A solution would be to use a @code{reset-init} event handler\nto manually reset the peripherals.\n@xref{targetevents,,Target Events}.\n\nCortex-M0, M0+ and M1 do not support @option{vectreset}, use @option{sysresetreq}\ninstead.\n@end deffn\n\n@subsection ARMv8-A specific commands\n@cindex ARMv8-A\n@cindex aarch64\n\n@deffn {Command} {aarch64 cache_info}\nDisplay information about target caches\n@end deffn\n\n@deffn {Command} {aarch64 dbginit}\nThis command enables debugging by clearing the OS Lock and sticky power-down and reset\nindications. It also establishes the expected, basic cross-trigger configuration the aarch64\ntarget code relies on. In a configuration file, the command would typically be called from a\n@code{reset-end} or @code{reset-deassert-post} handler, to re-enable debugging after a system reset.\nHowever, normally it is not necessary to use the command at all.\n@end deffn\n\n@deffn {Command} {aarch64 disassemble} address [count]\n@cindex disassemble\nDisassembles @var{count} instructions starting at @var{address}.\nIf @var{count} is not specified, a single instruction is disassembled.\n@end deffn\n\n@deffn {Command} {aarch64 smp} [on|off]\nDisplay, enable or disable SMP handling mode. The state of SMP handling influences the way targets in an SMP group\nare handled by the run control. With SMP handling enabled, issuing halt or resume to one core will trigger\nhalting or resuming of all cores in the group. The command @code{target smp} defines which targets are in the SMP\ngroup. With SMP handling disabled, all targets need to be treated individually.\n@end deffn\n\n@deffn {Command} {aarch64 maskisr} [@option{on}|@option{off}]\nSelects whether interrupts will be processed when single stepping. The default configuration is\n@option{on}.\n@end deffn\n\n@deffn {Command} {$target_name catch_exc} [@option{off}|@option{sec_el1}|@option{sec_el3}|@option{nsec_el1}|@option{nsec_el2}]+\nCause @command{$target_name} to halt when an exception is taken. Any combination of\nSecure (sec) EL1/EL3 or Non-Secure (nsec) EL1/EL2 is valid. The target\n@command{$target_name} will halt before taking the exception. In order to resume\nthe target, the exception catch must be disabled again with @command{$target_name catch_exc off}.\nIssuing the command without options prints the current configuration.\n@end deffn\n\n@deffn {Command} {$target_name pauth} [@option{off}|@option{on}]\nEnable or disable pointer authentication features.\nWhen pointer authentication is used on ARM cores, GDB asks GDB servers for an 8-bytes mask to remove signature bits added by pointer authentication.\nIf this feature is enabled, OpenOCD provides GDB with an 8-bytes mask.\nPointer authentication feature is broken until gdb 12.1, going to be fixed.\nConsider using a newer version of gdb if you want to enable pauth feature.\nThe default configuration is @option{off}.\n@end deffn\n\n\n@section EnSilica eSi-RISC Architecture\n\neSi-RISC is a highly configurable microprocessor architecture for embedded systems\nprovided by EnSilica. (See: @url{http://www.ensilica.com/risc-ip/}.)\n\n@subsection eSi-RISC Configuration\n\n@deffn {Command} {esirisc cache_arch} (@option{harvard}|@option{von_neumann})\nConfigure the caching architecture. Targets with the @code{UNIFIED_ADDRESS_SPACE}\noption disabled employ a Harvard architecture. By default, @option{von_neumann} is assumed.\n@end deffn\n\n@deffn {Command} {esirisc hwdc} (@option{all}|@option{none}|mask ...)\nConfigure hardware debug control. The HWDC register controls which exceptions return\ncontrol back to the debugger. Possible masks are @option{all}, @option{none},\n@option{reset}, @option{interrupt}, @option{syscall}, @option{error}, and @option{debug}.\nBy default, @option{reset}, @option{error}, and @option{debug} are enabled.\n@end deffn\n\n@subsection eSi-RISC Operation\n\n@deffn {Command} {esirisc flush_caches}\nFlush instruction and data caches. This command requires that the target is halted\nwhen the command is issued and configured with an instruction or data cache.\n@end deffn\n\n@subsection eSi-Trace Configuration\n\neSi-RISC targets may be configured with support for instruction tracing. Trace\ndata may be written to an in-memory buffer or FIFO. If a FIFO is configured, DMA\nis typically employed to move trace data off-device using a high-speed\nperipheral (eg. SPI). Collected trace data is encoded in one of three different\nformats. At a minimum, @command{esirisc trace buffer} or @command{esirisc trace\nfifo} must be issued along with @command{esirisc trace format} before trace data\ncan be collected.\n\nOpenOCD provides rudimentary analysis of collected trace data. If more detail is\nneeded, collected trace data can be dumped to a file and processed by external\ntooling.\n\n@quotation Issues\nOpenOCD is unable to process trace data sent to a FIFO. A potential workaround\nfor this issue is to configure DMA to copy trace data to an in-memory buffer,\nwhich can then be passed to the @command{esirisc trace analyze} and\n@command{esirisc trace dump} commands.\n\nIt is possible to corrupt trace data when using a FIFO if the peripheral\nresponsible for draining data from the FIFO is not fast enough. This can be\nmanaged by enabling flow control, however this can impact timing-sensitive\nsoftware operation on the CPU.\n@end quotation\n\n@deffn {Command} {esirisc trace buffer} address size [@option{wrap}]\nConfigure trace buffer using the provided address and size. If the @option{wrap}\noption is specified, trace collection will continue once the end of the buffer\nis reached. By default, wrap is disabled.\n@end deffn\n\n@deffn {Command} {esirisc trace fifo} address\nConfigure trace FIFO using the provided address.\n@end deffn\n\n@deffn {Command} {esirisc trace flow_control} (@option{enable}|@option{disable})\nEnable or disable stalling the CPU to collect trace data. By default, flow\ncontrol is disabled.\n@end deffn\n\n@deffn {Command} {esirisc trace format} (@option{full}|@option{branch}|@option{icache}) pc_bits\nConfigure trace format and number of PC bits to be captured. @option{pc_bits}\nmust be within 1 and 31 as the LSB is not collected. If external tooling is used\nto analyze collected trace data, these values must match.\n\nSupported trace formats:\n@itemize\n@item @option{full} capture full trace data, allowing execution history and\ntiming to be determined.\n@item @option{branch} capture taken branch instructions and branch target\naddresses.\n@item @option{icache} capture instruction cache misses.\n@end itemize\n@end deffn\n\n@deffn {Command} {esirisc trace trigger start} (@option{condition}) [start_data start_mask]\nConfigure trigger start condition using the provided start data and mask. A\nbrief description of each condition is provided below; for more detail on how\nthese values are used, see the eSi-RISC Architecture Manual.\n\nSupported conditions:\n@itemize\n@item @option{none} manual tracing (see @command{esirisc trace start}).\n@item @option{pc} start tracing if the PC matches start data and mask.\n@item @option{load} start tracing if the effective address of a load\ninstruction matches start data and mask.\n@item @option{store} start tracing if the effective address of a store\ninstruction matches start data and mask.\n@item @option{exception} start tracing if the EID of an exception matches start\ndata and mask.\n@item @option{eret} start tracing when an @code{ERET} instruction is executed.\n@item @option{wait} start tracing when a @code{WAIT} instruction is executed.\n@item @option{stop} start tracing when a @code{STOP} instruction is executed.\n@item @option{high} start tracing when an external signal is a logical high.\n@item @option{low} start tracing when an external signal is a logical low.\n@end itemize\n@end deffn\n\n@deffn {Command} {esirisc trace trigger stop} (@option{condition}) [stop_data stop_mask]\nConfigure trigger stop condition using the provided stop data and mask. A brief\ndescription of each condition is provided below; for more detail on how these\nvalues are used, see the eSi-RISC Architecture Manual.\n\nSupported conditions:\n@itemize\n@item @option{none} manual tracing (see @command{esirisc trace stop}).\n@item @option{pc} stop tracing if the PC matches stop data and mask.\n@item @option{load} stop tracing if the effective address of a load\ninstruction matches stop data and mask.\n@item @option{store} stop tracing if the effective address of a store\ninstruction matches stop data and mask.\n@item @option{exception} stop tracing if the EID of an exception matches stop\ndata and mask.\n@item @option{eret} stop tracing when an @code{ERET} instruction is executed.\n@item @option{wait} stop tracing when a @code{WAIT} instruction is executed.\n@item @option{stop} stop tracing when a @code{STOP} instruction is executed.\n@end itemize\n@end deffn\n\n@deffn {Command} {esirisc trace trigger delay} (@option{trigger}) [cycles]\nConfigure trigger start/stop delay in clock cycles.\n\nSupported triggers:\n@itemize\n@item @option{none} no delay to start or stop collection.\n@item @option{start} delay @option{cycles} after trigger to start collection.\n@item @option{stop} delay @option{cycles} after trigger to stop collection.\n@item @option{both} delay @option{cycles} after both triggers to start or stop\ncollection.\n@end itemize\n@end deffn\n\n@subsection eSi-Trace Operation\n\n@deffn {Command} {esirisc trace init}\nInitialize trace collection. This command must be called any time the\nconfiguration changes. If a trace buffer has been configured, the contents will\nbe overwritten when trace collection starts.\n@end deffn\n\n@deffn {Command} {esirisc trace info}\nDisplay trace configuration.\n@end deffn\n\n@deffn {Command} {esirisc trace status}\nDisplay trace collection status.\n@end deffn\n\n@deffn {Command} {esirisc trace start}\nStart manual trace collection.\n@end deffn\n\n@deffn {Command} {esirisc trace stop}\nStop manual trace collection.\n@end deffn\n\n@deffn {Command} {esirisc trace analyze} [address size]\nAnalyze collected trace data. This command may only be used if a trace buffer\nhas been configured. If a trace FIFO has been configured, trace data must be\ncopied to an in-memory buffer identified by the @option{address} and\n@option{size} options using DMA.\n@end deffn\n\n@deffn {Command} {esirisc trace dump} [address size] @file{filename}\nDump collected trace data to file. This command may only be used if a trace\nbuffer has been configured. If a trace FIFO has been configured, trace data must\nbe copied to an in-memory buffer identified by the @option{address} and\n@option{size} options using DMA.\n@end deffn\n\n@section Intel Architecture\n\nIntel Quark X10xx is the first product in the Quark family of SoCs. It is an IA-32\n(Pentium x86 ISA) compatible SoC. The core CPU in the X10xx is codenamed Lakemont.\nLakemont version 1 (LMT1) is used in X10xx. The CPU TAP (Lakemont TAP) is used for\nsoftware debug and the CLTAP is used for SoC level operations.\nUseful docs are here: https://communities.intel.com/community/makers/documentation\n@itemize\n@item Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for doc num 330015)\n@item Intel Quark SoC X1000 Debug Operations User Guide (web search for doc num 329866)\n@item Intel Quark SoC X1000 Datasheet (web search for doc num 329676)\n@end itemize\n\n@subsection x86 32-bit specific commands\nThe three main address spaces for x86 are memory, I/O and configuration space.\nThese commands allow a user to read and write to the 64Kbyte I/O address space.\n\n@deffn {Command} {x86_32 idw} address\nDisplay the contents of a 32-bit I/O port from address range 0x0000 - 0xffff.\n@end deffn\n\n@deffn {Command} {x86_32 idh} address\nDisplay the contents of a 16-bit I/O port from address range 0x0000 - 0xffff.\n@end deffn\n\n@deffn {Command} {x86_32 idb} address\nDisplay the contents of a 8-bit I/O port from address range 0x0000 - 0xffff.\n@end deffn\n\n@deffn {Command} {x86_32 iww} address\nWrite the contents of a 32-bit I/O port to address range 0x0000 - 0xffff.\n@end deffn\n\n@deffn {Command} {x86_32 iwh} address\nWrite the contents of a 16-bit I/O port to address range 0x0000 - 0xffff.\n@end deffn\n\n@deffn {Command} {x86_32 iwb} address\nWrite the contents of a 8-bit I/O port to address range 0x0000 - 0xffff.\n@end deffn\n\n@section OpenRISC Architecture\n\nThe OpenRISC CPU is a soft core. It is used in a programmable SoC which can be\nconfigured with any of the TAP / Debug Unit available.\n\n@subsection TAP and Debug Unit selection commands\n@deffn {Command} {tap_select} (@option{vjtag}|@option{mohor}|@option{xilinx_bscan})\nSelect between the Altera Virtual JTAG , Xilinx Virtual JTAG and Mohor TAP.\n@end deffn\n@deffn {Command} {du_select} (@option{adv}|@option{mohor}) [option]\nSelect between the Advanced Debug Interface and the classic one.\n\nAn option can be passed as a second argument to the debug unit.\n\nWhen using the Advanced Debug Interface, option = 1 means the RTL core is\nconfigured with ADBG_USE_HISPEED = 1. This configuration skips status checking\nbetween bytes while doing read or write bursts.\n@end deffn\n\n@subsection Registers commands\n@deffn {Command} {addreg} [name] [address] [feature] [reg_group]\nAdd a new register in the cpu register list. This register will be\nincluded in the generated target descriptor file.\n\n@strong{[feature]} must be \"org.gnu.gdb.or1k.group[0..10]\".\n\n@strong{[reg_group]} can be anything. The default register list defines \"system\",\n \"dmmu\", \"immu\", \"dcache\", \"icache\", \"mac\", \"debug\", \"perf\", \"power\", \"pic\"\n and \"timer\" groups.\n\n@emph{example:}\n@example\naddreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n@end example\n\n@end deffn\n\n@section RISC-V Architecture\n\n@uref{http://riscv.org/, RISC-V} is a free and open ISA. OpenOCD supports JTAG\ndebug of RV32 and RV64 cores in heterogeneous multicore systems of up to 32\nharts. (It's possible to increase this limit to 1024 by changing\nRISCV_MAX_HARTS in riscv.h.) OpenOCD primarily supports 0.13 of the RISC-V\nDebug Specification, but there is also support for legacy targets that\nimplement version 0.11.\n\n@subsection RISC-V Terminology\n\nA @emph{hart} is a hardware thread. A hart may share resources (eg. FPU) with\nanother hart, or may be a separate core.  RISC-V treats those the same, and\nOpenOCD exposes each hart as a separate core.\n\n@subsection Vector Registers\n\nFor harts that implement the vector extension, OpenOCD provides access to the\nrelevant CSRs, as well as the vector registers (v0-v31). The size of each\nvector register is dependent on the value of vlenb. RISC-V allows each vector\nregister to be divided into selected-width elements, and this division can be\nchanged at run-time. Because OpenOCD cannot update register definitions at\nrun-time, it exposes each vector register to gdb as a union of fields of\nvectors so that users can easily access individual bytes, shorts, words,\nlongs, and quads inside each vector register. It is left to gdb or\nhigher-level debuggers to present this data in a more intuitive format.\n\nIn the XML register description, the vector registers (when vlenb=16) look as\nfollows:\n\n@example\n<feature name=\"org.gnu.gdb.riscv.vector\">\n<vector id=\"bytes\" type=\"uint8\" count=\"16\"/>\n<vector id=\"shorts\" type=\"uint16\" count=\"8\"/>\n<vector id=\"words\" type=\"uint32\" count=\"4\"/>\n<vector id=\"longs\" type=\"uint64\" count=\"2\"/>\n<vector id=\"quads\" type=\"uint128\" count=\"1\"/>\n<union id=\"riscv_vector\">\n<field name=\"b\" type=\"bytes\"/>\n<field name=\"s\" type=\"shorts\"/>\n<field name=\"w\" type=\"words\"/>\n<field name=\"l\" type=\"longs\"/>\n<field name=\"q\" type=\"quads\"/>\n</union>\n<reg name=\"v0\" bitsize=\"128\" regnum=\"4162\" save-restore=\"no\"\n        type=\"riscv_vector\" group=\"vector\"/>\n...\n<reg name=\"v31\" bitsize=\"128\" regnum=\"4193\" save-restore=\"no\"\n        type=\"riscv_vector\" group=\"vector\"/>\n</feature>\n@end example\n\n@subsection RISC-V Debug Configuration Commands\n\n@deffn {Config Command} {riscv expose_csrs} n[-m|=name] [...]\nConfigure which CSRs to expose in addition to the standard ones. The CSRs to expose\ncan be specified as individual register numbers or register ranges (inclusive). For the\nindividually listed CSRs, a human-readable name can optionally be set using the @code{n=name}\nsyntax, which will get @code{csr_} prepended to it. If no name is provided, the register will be\nnamed @code{csr<n>}.\n\nBy default OpenOCD attempts to expose only CSRs that are mentioned in a spec,\nand then only if the corresponding extension appears to be implemented. This\ncommand can be used if OpenOCD gets this wrong, or if the target implements custom\nCSRs.\n\n@example\n# Expose a single RISC-V CSR number 128 under the name \"csr128\":\n$_TARGETNAME expose_csrs 128\n\n# Expose multiple RISC-V CSRs 128..132 under names \"csr128\" through \"csr132\":\n$_TARGETNAME expose_csrs 128-132\n\n# Expose a single RISC-V CSR number 1996 under custom name \"csr_myregister\":\n$_TARGETNAME expose_csrs 1996=myregister\n@end example\n@end deffn\n\n@deffn {Config Command} {riscv expose_custom} n[-m|=name] [...]\nThe RISC-V Debug Specification allows targets to expose custom registers\nthrough abstract commands. (See Section 3.5.1.1 in that document.) This command\nconfigures individual registers or register ranges (inclusive) that shall be exposed.\nNumber 0 indicates the first custom register, whose abstract command number is 0xc000.\nFor individually listed registers, a human-readable name can be optionally provided\nusing the @code{n=name} syntax, which will get @code{custom_} prepended to it. If no\nname is provided, the register will be named @code{custom<n>}.\n\n@example\n# Expose one RISC-V custom register with number 0xc010 (0xc000 + 16)\n# under the name \"custom16\":\n$_TARGETNAME expose_custom 16\n\n# Expose a range of RISC-V custom registers with numbers 0xc010 .. 0xc018\n# (0xc000+16 .. 0xc000+24) under the names \"custom16\" through \"custom24\":\n$_TARGETNAME expose_custom 16-24\n\n# Expose one RISC-V custom register with number 0xc020 (0xc000 + 32) under\n# user-defined name \"custom_myregister\":\n$_TARGETNAME expose_custom 32=myregister\n@end example\n@end deffn\n\n@deffn {Command} {riscv info}\nDisplays some information OpenOCD detected about the target.\n@end deffn\n\n@deffn {Command} {riscv reset_delays} [wait]\nOpenOCD learns how many Run-Test/Idle cycles are required between scans to avoid\nencountering the target being busy. This command resets those learned values\nafter `wait` scans. It's only useful for testing OpenOCD itself.\n@end deffn\n\n@deffn {Command} {riscv set_command_timeout_sec} [seconds]\nSet the wall-clock timeout (in seconds) for individual commands. The default\nshould work fine for all but the slowest targets (eg. simulators).\n@end deffn\n\n@deffn {Command} {riscv set_reset_timeout_sec} [seconds]\nSet the maximum time to wait for a hart to come out of reset after reset is\ndeasserted.\n@end deffn\n\n@deffn {Command} {riscv set_mem_access} method1 [method2] [method3]\nSpecify which RISC-V memory access method(s) shall be used, and in which order\nof priority. At least one method must be specified.\n\nAvailable methods are:\n@itemize\n@item @code{progbuf} - Use RISC-V Debug Program Buffer to access memory.\n@item @code{sysbus} - Access memory via RISC-V Debug System Bus interface.\n@item @code{abstract} - Access memory via RISC-V Debug abstract commands.\n@end itemize\n\nBy default, all memory access methods are enabled in the following order:\n@code{progbuf sysbus abstract}.\n\nThis command can be used to change the memory access methods if the default\nbehavior is not suitable for a particular target.\n@end deffn\n\n@deffn {Command} {riscv set_enable_virtual} on|off\nWhen on, memory accesses are performed on physical or virtual memory depending\non the current system configuration. When off (default), all memory accessses are performed\non physical memory.\n@end deffn\n\n@deffn {Command} {riscv set_enable_virt2phys} on|off\nWhen on (default), memory accesses are performed on physical or virtual memory\ndepending on the current satp configuration. When off, all memory accessses are\nperformed on physical memory.\n@end deffn\n\n@deffn {Command} {riscv resume_order} normal|reversed\nSome software assumes all harts are executing nearly continuously. Such\nsoftware may be sensitive to the order that harts are resumed in. On harts\nthat don't support hasel, this option allows the user to choose the order the\nharts are resumed in. If you are using this option, it's probably masking a\nrace condition problem in your code.\n\nNormal order is from lowest hart index to highest. This is the default\nbehavior. Reversed order is from highest hart index to lowest.\n@end deffn\n\n@deffn {Command} {riscv set_ir} (@option{idcode}|@option{dtmcs}|@option{dmi}) [value]\nSet the IR value for the specified JTAG register.  This is useful, for\nexample, when using the existing JTAG interface on a Xilinx FPGA by\nway of BSCANE2 primitives that only permit a limited selection of IR\nvalues.\n\nWhen utilizing version 0.11 of the RISC-V Debug Specification,\n@option{dtmcs} and @option{dmi} set the IR values for the DTMCONTROL\nand DBUS registers, respectively.\n@end deffn\n\n@deffn {Command} {riscv use_bscan_tunnel} value\nEnable or disable use of a BSCAN tunnel to reach DM.  Supply the width of\nthe DM transport TAP's instruction register to enable.  Supply a value of 0 to disable.\n@end deffn\n\n@deffn {Command} {riscv set_ebreakm} on|off\nControl dcsr.ebreakm. When on (default), M-mode ebreak instructions trap to\nOpenOCD. When off, they generate a breakpoint exception handled internally.\n@end deffn\n\n@deffn {Command} {riscv set_ebreaks} on|off\nControl dcsr.ebreaks. When on (default), S-mode ebreak instructions trap to\nOpenOCD. When off, they generate a breakpoint exception handled internally.\n@end deffn\n\n@deffn {Command} {riscv set_ebreaku} on|off\nControl dcsr.ebreaku. When on (default), U-mode ebreak instructions trap to\nOpenOCD. When off, they generate a breakpoint exception handled internally.\n@end deffn\n\n@subsection RISC-V Authentication Commands\n\nThe following commands can be used to authenticate to a RISC-V system. Eg.  a\ntrivial challenge-response protocol could be implemented as follows in a\nconfiguration file, immediately following @command{init}:\n@example\nset challenge [riscv authdata_read]\nriscv authdata_write [expr @{$challenge + 1@}]\n@end example\n\n@deffn {Command} {riscv authdata_read}\nReturn the 32-bit value read from authdata.\n@end deffn\n\n@deffn {Command} {riscv authdata_write} value\nWrite the 32-bit value to authdata.\n@end deffn\n\n@subsection RISC-V DMI Commands\n\nThe following commands allow direct access to the Debug Module Interface, which\ncan be used to interact with custom debug features.\n\n@deffn {Command} {riscv dmi_read} address\nPerform a 32-bit DMI read at address, returning the value.\n@end deffn\n\n@deffn {Command} {riscv dmi_write} address value\nPerform a 32-bit DMI write of value at address.\n@end deffn\n\n@section ARC Architecture\n@cindex ARC\n\nSynopsys DesignWare ARC Processors are a family of 32-bit CPUs that SoC\ndesigners can optimize for a wide range of uses, from deeply embedded to\nhigh-performance host applications in a variety of market segments. See more\nat: @url{http://www.synopsys.com/IP/ProcessorIP/ARCProcessors/Pages/default.aspx}.\nOpenOCD currently supports ARC EM processors.\nThere is a set ARC-specific OpenOCD commands that allow low-level\naccess to the core and provide necessary support for ARC extensibility and\nconfigurability capabilities. ARC processors has much more configuration\ncapabilities than most of the other processors and in addition there is an\nextension interface that allows SoC designers to add custom registers and\ninstructions. For the OpenOCD that mostly means that set of core and AUX\nregisters in target will vary and is not fixed for a particular processor\nmodel. To enable extensibility several TCL commands are provided that allow to\ndescribe those optional registers in OpenOCD configuration files. Moreover\nthose commands allow for a dynamic target features discovery.\n\n\n@subsection General ARC commands\n\n@deffn {Config Command} {arc add-reg} configparams\n\nAdd a new register to processor target. By default newly created register is\nmarked as not existing. @var{configparams} must have following required\narguments:\n\n@itemize @bullet\n\n@item @code{-name} name\n@*Name of a register.\n\n@item @code{-num} number\n@*Architectural register number: core register number or AUX register number.\n\n@item @code{-feature} XML_feature\n@*Name of GDB XML target description feature.\n\n@end itemize\n\n@var{configparams} may have following optional arguments:\n\n@itemize @bullet\n\n@item @code{-gdbnum} number\n@*GDB register number. It is recommended to not assign GDB register number\nmanually, because there would be a risk that two register will have same\nnumber. When register GDB number is not set with this option, then register\nwill get a previous register number + 1. This option is required only for those\nregisters that must be at particular address expected by GDB.\n\n@item @code{-core}\n@*This option specifies that register is a core registers. If not - this is an\nAUX register. AUX registers and core registers reside in different address\nspaces.\n\n@item @code{-bcr}\n@*This options specifies that register is a BCR register. BCR means Build\nConfiguration Registers - this is a special type of AUX registers that are read\nonly and non-volatile, that is - they never change their value. Therefore OpenOCD\nnever invalidates values of those registers in internal caches. Because BCR is a\ntype of AUX registers, this option cannot be used with @code{-core}.\n\n@item @code{-type} type_name\n@*Name of type of this register. This can be either one of the basic GDB types,\nor a custom types described with @command{arc add-reg-type-[flags|struct]}.\n\n@item @code{-g}\n@* If specified then this is a \"general\" register. General registers are always\nread by OpenOCD on context save (when core has just been halted) and is always\ntransferred to GDB client in a response to g-packet. Contrary to this,\nnon-general registers are read and sent to GDB client on-demand. In general it\nis not recommended to apply this option to custom registers.\n\n@end itemize\n\n@end deffn\n\n@deffn {Config Command} {arc add-reg-type-flags} -name name flags...\nAdds new register type of ``flags'' class. ``Flags'' types can contain only\none-bit fields. Each flag definition looks like @code{-flag name bit-position}.\n@end deffn\n\n@anchor{add-reg-type-struct}\n@deffn {Config Command} {arc add-reg-type-struct} -name name structs...\nAdds new register type of ``struct'' class. ``Struct'' types can contain either\nbit-fields or fields of other types, however at the moment only bit fields are\nsupported. Structure bit field definition looks like @code{-bitfield name\nstartbit endbit}.\n@end deffn\n\n@deffn {Command} {arc get-reg-field} reg-name field-name\nReturns value of bit-field in a register. Register must be ``struct'' register\ntype, @xref{add-reg-type-struct}. command definition.\n@end deffn\n\n@deffn {Command} {arc set-reg-exists} reg-names...\nSpecify that some register exists. Any amount of names can be passed\nas an argument for a single command invocation.\n@end deffn\n\n@subsection ARC JTAG commands\n\n@deffn {Command} {arc jtag set-aux-reg} regnum value\nThis command writes value to AUX register via its number. This command access\nregister in target directly via JTAG, bypassing any OpenOCD internal caches,\ntherefore it is unsafe to use if that register can be operated by other means.\n\n@end deffn\n\n@deffn {Command} {arc jtag set-core-reg} regnum value\nThis command is similar to @command{arc jtag set-aux-reg} but is for core\nregisters.\n@end deffn\n\n@deffn {Command} {arc jtag get-aux-reg} regnum\nThis command returns the value storded in AUX register via its number. This commands access\nregister in target directly via JTAG, bypassing any OpenOCD internal caches,\ntherefore it is unsafe to use if that register can be operated by other means.\n\n@end deffn\n\n@deffn {Command} {arc jtag get-core-reg} regnum\nThis command is similar to @command{arc jtag get-aux-reg} but is for core\nregisters.\n@end deffn\n\n@section STM8 Architecture\n@uref{http://st.com/stm8/, STM8} is a 8-bit microcontroller platform from\nSTMicroelectronics, based on a proprietary 8-bit core architecture.\n\nOpenOCD supports debugging STM8 through the STMicroelectronics debug\nprotocol SWIM, @pxref{swimtransport,,SWIM}.\n\n@section Xtensa Architecture\n\nXtensa is a highly-customizable, user-extensible microprocessor and DSP\narchitecture for complex embedded systems provided by Cadence Design\nSystems, Inc. See the\n@uref{https://www.cadence.com/en_US/home/tools/ip/tensilica-ip.html, Tensilica IP}\nwebsite for additional information and documentation.\n\nOpenOCD supports generic Xtensa processor implementations which can be customized by\nproviding a core-specific configuration file which describes every enabled\nXtensa architecture option, e.g. number of address registers, exceptions, reduced\nsize instructions support, memory banks configuration etc. OpenOCD also supports SMP\nconfigurations for Xtensa processors with any number of cores and allows configuring\ntheir debug interconnect (termed \"break/stall networks\"), which control how debug\nsignals are distributed among cores. Xtensa \"break networks\" are compatible with\nARM's Cross Trigger Interface (CTI). OpenOCD implements both generic Xtensa targets\nas well as several Espressif Xtensa-based chips from the\n@uref{https://www.espressif.com/en/products/socs, ESP32 family}.\n\nOCD sessions for Xtensa processor and DSP targets are accessed via the Xtensa\nDebug Module (XDM), which provides external connectivity either through a\ntraditional JTAG interface or an ARM DAP interface. If used, the DAP interface\ncan control Xtensa targets through JTAG or SWD probes.\n\n@subsection Xtensa Core Configuration\n\nDue to the high level of configurability in Xtensa cores, the Xtensa target\nconfiguration comprises two categories:\n\n@enumerate\n@item Base Xtensa support common to all core configurations, and\n@item Core-specific support as configured for individual cores.\n@end enumerate\n\nAll common Xtensa support is built into the OpenOCD Xtensa target layer and\nis enabled through a combination of TCL scripts: the target-specific\n@file{target/xtensa.cfg} and a board-specific @file{board/xtensa-*.cfg},\nsimilar to other target architectures.\n\nImportantly, core-specific configuration information must be provided by\nthe user, and takes the form of an @file{xtensa-core-XXX.cfg} TCL script that\ndefines the core's configurable features through a series of Xtensa\nconfiguration commands (detailed below).\n\nThis core-specific @file{xtensa-core-XXX.cfg} file is typically either:\n\n@itemize @bullet\n@item Located within the Xtensa core configuration build as\n@file{src/config/xtensa-core-openocd.cfg}, or\n@item Generated by running the command @code{xt-gdb --dump-oocd-config}\nfrom the Xtensa processor tool-chain's command-line tools.\n@end itemize\n\nNOTE: @file{xtensa-core-XXX.cfg} must match the target Xtensa hardware\nconnected to OpenOCD.\n\nSome example Xtensa configurations are bundled with OpenOCD for reference:\n@itemize @bullet\n@item Cadence Palladium VDebug emulation target. The user can combine their\n@file{xtensa-core-XXX.cfg} with the provided\n@file{board/xtensa-palladium-vdebug.cfg} to debug an emulated Xtensa RTL design.\n@item NXP MIMXRT685-EVK evaluation kit. The relevant configuration files are\n@file{board/xtensa-rt685-jlink.cfg} and @file{board/xtensa-core-nxp_rt600.cfg}.\nAdditional information is provided by\n@uref{https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt600-evaluation-kit:MIMXRT685-EVK,\nNXP}.\n@end itemize\n\n@subsection Xtensa Configuration Commands\n\n@deffn {Config Command} {xtensa xtdef} (@option{LX}|@option{NX})\nConfigure the Xtensa target architecture. Currently, Xtensa support is limited\nto LX6, LX7, and NX cores.\n@end deffn\n\n@deffn {Config Command} {xtensa xtopt} option value\nConfigure Xtensa target options that are relevant to the debug subsystem.\n@var{option} is one of: @option{arnum}, @option{windowed},\n@option{cpenable}, @option{exceptions}, @option{intnum}, @option{hipriints},\n@option{excmlevel}, @option{intlevels}, @option{debuglevel},\n@option{ibreaknum}, or @option{dbreaknum}. @var{value} is an integer with\nthe exact range determined by each particular option.\n\nNOTE: Some options are specific to Xtensa LX or Xtensa NX architecture, while\nothers may be common to both but have different valid ranges.\n@end deffn\n\n@deffn {Config Command} {xtensa xtmem} (@option{iram}|@option{dram}|@option{sram}|@option{irom}|@option{drom}|@option{srom}) baseaddr bytes\nConfigure Xtensa target memory. Memory type determines access rights,\nwhere RAMs are read/write while ROMs are read-only. @var{baseaddr} and\n@var{bytes} are both integers, typically hexadecimal and decimal, respectively.\n@end deffn\n\n@deffn {Config Command} {xtensa xtmem} (@option{icache}|@option{dcache}) linebytes cachebytes ways [writeback]\nConfigure Xtensa processor cache. All parameters are required except for\nthe optional @option{writeback} parameter; all are integers.\n@end deffn\n\n@deffn {Config Command} {xtensa xtmpu} numfgseg minsegsz lockable execonly\nConfigure an Xtensa Memory Protection Unit (MPU). MPUs can restrict access\nand/or control cacheability of specific address ranges, but are lighter-weight\nthan a full traditional MMU. All parameters are required; all are integers.\n@end deffn\n\n@deffn {Config Command} {xtensa xtmmu} numirefillentries numdrefillentries\n(Xtensa-LX only) Configure an Xtensa Memory Management Unit (MMU). Both\nparameters are required; both are integers.\n@end deffn\n\n@deffn {Config Command} {xtensa xtregs} numregs\nConfigure the total number of registers for the Xtensa core. Configuration\nlogic expects to subsequently process this number of @code{xtensa xtreg}\ndefinitions. @var{numregs} is an integer.\n@end deffn\n\n@deffn {Config Command} {xtensa xtregfmt} (@option{sparse}|@option{contiguous}) [general]\nConfigure the type of register map used by GDB to access the Xtensa core.\nGeneric Xtensa tools (e.g. xt-gdb) require @option{sparse} mapping (default) while\nEspressif tools expect @option{contiguous} mapping. Contiguous mapping takes an\nadditional, optional integer parameter @option{numgregs}, which specifies the number\nof general registers used in handling g/G packets.\n@end deffn\n\n@deffn {Config Command} {xtensa xtreg} name offset\nConfigure an Xtensa core register. All core registers are 32 bits wide,\nwhile TIE and user registers may have variable widths. @var{name} is a\ncharacter string identifier while @var{offset} is a hexadecimal integer.\n@end deffn\n\n@subsection Xtensa Operation Commands\n\n@deffn {Command} {xtensa maskisr} (@option{on}|@option{off})\n(Xtensa-LX only) Mask or unmask Xtensa interrupts during instruction step.\nWhen masked, an interrupt that occurs during a step operation is handled and\nits ISR is executed, with the user's debug session returning after potentially\nexecuting many instructions. When unmasked, a triggered interrupt will result\nin execution progressing the requested number of instructions into the relevant\nvector/ISR code.\n@end deffn\n\n@deffn {Command} {xtensa set_permissive} (0|1)\nBy default accessing memory beyond defined regions is forbidden. This commnd controls memory access address check.\nWhen set to (1), skips access controls and address range check before read/write memory.\n@end deffn\n\n@deffn {Command} {xtensa smpbreak} [none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]\nConfigures debug signals connection (\"break network\") for currently selected core.\n@itemize @bullet\n@item @code{none} - Core's \"break/stall network\" is disconnected. Core is not affected by any debug\nsignal from other cores.\n@item @code{breakinout} - Core's \"break network\" is fully connected (break inputs and outputs are enabled).\nCore will receive debug break signals from other cores and send such signals to them. For example when another core\nis stopped due to breakpoint hit this core will be stopped too and vice versa.\n@item @code{runstall} - Core's \"stall network\" is fully connected (stall inputs and outputs are enabled).\nThis feature is not well implemented and tested yet.\n@item @code{BreakIn} - Core's \"break-in\" signal is enabled.\nCore will receive debug break signals from other cores. For example when another core is\nstopped due to breakpoint hit this core will be stopped too.\n@item @code{BreakOut} - Core's \"break-out\" signal is enabled.\nCore will send debug break signal to other cores. For example when this core is\nstopped due to breakpoint hit other cores with enabled break-in signals will be stopped too.\n@item @code{RunStallIn} - Core's \"runstall-in\" signal is enabled.\nThis feature is not well implemented and tested yet.\n@item @code{DebugModeOut} - Core's \"debugmode-out\" signal is enabled.\nThis feature is not well implemented and tested yet.\n@end itemize\n@end deffn\n\n@deffn {Command} {xtensa exe} <ascii-encoded hexadecimal instruction bytes>\nExecute arbitrary instruction(s) provided as an ascii string.  The string represents an integer\nnumber of instruction bytes, thus its length must be even.\n@end deffn\n\n@subsection Xtensa Performance Monitor Configuration\n\n@deffn {Command} {xtensa perfmon_enable} <counter_id> <select> [mask] [kernelcnt] [tracelevel]\nEnable and start performance counter.\n@itemize @bullet\n@item @code{counter_id} - Counter ID (0-1).\n@item @code{select} - Selects performance metric to be counted by the counter,\ne.g. 0 - CPU cycles, 2 - retired instructions.\n@item @code{mask} - Selects input subsets to be counted (counter will\nincrement only once even if more than one condition corresponding to a mask bit occurs).\n@item @code{kernelcnt} - 0 - count events with \"CINTLEVEL <= tracelevel\",\n1 - count events with \"CINTLEVEL > tracelevel\".\n@item @code{tracelevel} - Compares this value to \"CINTLEVEL\" when deciding\nwhether to count.\n@end itemize\n@end deffn\n\n@deffn {Command} {xtensa perfmon_dump} (counter_id)\nDump performance counter value. If no argument specified, dumps all counters.\n@end deffn\n\n@subsection Xtensa Trace Configuration\n\n@deffn {Command} {xtensa tracestart} [pc <pcval>/[<maskbitcount>]] [after <n> [ins|words]]\nSet up and start a HW trace. Optionally set PC address range to trigger tracing stop when reached during program execution.\nThis command also allows to specify the amount of data to capture after stop trigger activation.\n@itemize @bullet\n@item @code{pcval} - PC value which will trigger trace data collection stop.\n@item @code{maskbitcount} - PC value mask.\n@item @code{n} - Maximum number of instructions/words to capture after trace stop trigger.\n@end itemize\n@end deffn\n\n@deffn {Command} {xtensa tracestop}\nStop current trace as started by the tracestart command.\n@end deffn\n\n@deffn {Command} {xtensa tracedump} <outfile>\nDump trace memory to a file.\n@end deffn\n\n@section Espressif Specific Commands\n\n@deffn {Command} {esp apptrace} (start <destination> [<poll_period> [<trace_size> [<stop_tmo> [<wait4halt> [<skip_size>]]]]])\nStarts\n@uref{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#application-level-tracing-library, application level tracing}.\nData will be stored to specified destination. Available destinations are:\n@itemize @bullet\n@item @code{file://<outfile>} - Save trace logs into file.\n@item @code{tcp://<host>:<port>} - Send trace logs to tcp port on specified host. OpenOCD will act as a tcp client.\n@item @code{con:} - Print trace logs to the stdout.\n@end itemize\nOther parameters will be same for each destination.\n@itemize @bullet\n@item @code{poll_period} - trace data polling period in ms.\n@item @code{trace_size} - maximum trace data size.\nTracing will be stopped automatically when that amount is reached.\nUse \"-1\" to disable the limitation.\n@item @code{stop_tmo} - Data reception timeout in ms.\nTracing will be stopped automatically when no data is received within that period.\n@item @code{wait4halt} - if non-zero then wait for target to be halted before tracing start.\n@item @code{skip_size} - amount of tracing data to be skipped before writing it to destination.\n@end itemize\n@end deffn\n\n@deffn {Command} {esp apptrace} (stop)\nStops tracing started with above command.\n@end deffn\n\n@deffn {Command} {esp apptrace} (status)\nRequests ongoing tracing status.\n@end deffn\n\n@deffn {Command} {esp apptrace} (dump file://<outfile>)\nDumps tracing data from target buffer. It can be useful to dump the latest data\nbuffered on target for post-mortem analysis. For example when target starts tracing automatically\nw/o OpenOCD command and keeps only the latest data window which fit into the buffer.\n@uref{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#application-level-tracing-library, application level tracing}.\nData will be stored to specified destination.\n@end deffn\n\n@deffn {Command} {esp sysview} (start file://<outfile1> [file://<outfile2>] [<poll_period> [<trace_size> [<stop_tmo> [<wait4halt> [<skip_size>]]]]])\nStarts @uref{https://www.segger.com/products/development-tools/systemview/, SEGGER SystemView}\ncompatible tracing. Data will be stored to specified destination.\nFor dual-core chips traces from every core will be saved to separate files.\nResulting files can be open in \"SEGGER SystemView\" application.\n@url{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#openocd-systemview-tracing-command-options}\nThe meaning of the arguments is identical to @command{esp apptrace start}.\n@end deffn\n\n@deffn {Command} {esp sysview} (stop)\nStops SystremView compatible tracing started with above command.\n@url{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#openocd-systemview-tracing-command-options}\n@end deffn\n\n@deffn {Command} {esp sysview} (status)\nRequests ongoing SystremView compatible tracing status.\n@url{https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/app_trace.html#openocd-systemview-tracing-command-options}\n@end deffn\n\n@deffn {Command} {esp sysview_mcore} (start file://<outfile> [<poll_period> [<trace_size> [<stop_tmo> [<wait4halt> [<skip_size>]]]]])\nThis command is identical to @command{esp sysview start}, but uses Espressif multi-core extension to\n@uref{https://www.segger.com/products/development-tools/systemview/, SEGGER SystemView} data format.\nData will be stored to specified destination. Tracing data from all cores are saved in the same file.\nThe meaning of the arguments is identical to @command{esp sysview start}.\n@end deffn\n\n@deffn {Command} {esp sysview_mcore} (stop)\nStops Espressif multi-core SystremView tracing started with above command.\n@end deffn\n\n@deffn {Command} {esp sysview_mcore} (status)\nRequests ongoing Espressif multi-core SystremView tracing status.\n@end deffn\n\n@anchor{softwaredebugmessagesandtracing}\n@section Software Debug Messages and Tracing\n@cindex Linux-ARM DCC support\n@cindex tracing\n@cindex libdcc\n@cindex DCC\nOpenOCD can process certain requests from target software, when\nthe target uses appropriate libraries.\nThe most powerful mechanism is semihosting, but there is also\na lighter weight mechanism using only the DCC channel.\n\nCurrently @command{target_request debugmsgs}\nis supported only for @option{arm7_9} and @option{cortex_m} cores.\nThese messages are received as part of target polling, so\nyou need to have @command{poll on} active to receive them.\nThey are intrusive in that they will affect program execution\ntimes. If that is a problem, @pxref{armhardwaretracing,,ARM Hardware Tracing}.\n\nSee @file{libdcc} in the contrib dir for more details.\nIn addition to sending strings, characters, and\narrays of various size integers from the target,\n@file{libdcc} also exports a software trace point mechanism.\nThe target being debugged may\nissue trace messages which include a 24-bit @dfn{trace point} number.\nTrace point support includes two distinct mechanisms,\neach supported by a command:\n\n@itemize\n@item @emph{History} ... A circular buffer of trace points\ncan be set up, and then displayed at any time.\nThis tracks where code has been, which can be invaluable in\nfinding out how some fault was triggered.\n\nThe buffer may overflow, since it collects records continuously.\nIt may be useful to use some of the 24 bits to represent a\nparticular event, and other bits to hold data.\n\n@item @emph{Counting} ... An array of counters can be set up,\nand then displayed at any time.\nThis can help establish code coverage and identify hot spots.\n\nThe array of counters is directly indexed by the trace point\nnumber, so trace points with higher numbers are not counted.\n@end itemize\n\nLinux-ARM kernels have a ``Kernel low-level debugging\nvia EmbeddedICE DCC channel'' option (CONFIG_DEBUG_ICEDCC,\ndepends on CONFIG_DEBUG_LL) which uses this mechanism to\ndeliver messages before a serial console can be activated.\nThis is not the same format used by @file{libdcc}.\nOther software, such as the U-Boot boot loader, sometimes\ndoes the same thing.\n\n@deffn {Command} {target_request debugmsgs} [@option{enable}|@option{disable}|@option{charmsg}]\nDisplays current handling of target DCC message requests.\nThese messages may be sent to the debugger while the target is running.\nThe optional @option{enable} and @option{charmsg} parameters\nboth enable the messages, while @option{disable} disables them.\n\nWith @option{charmsg} the DCC words each contain one character,\nas used by Linux with CONFIG_DEBUG_ICEDCC;\notherwise the libdcc format is used.\n@end deffn\n\n@deffn {Command} {trace history} [@option{clear}|count]\nWith no parameter, displays all the trace points that have triggered\nin the order they triggered.\nWith the parameter @option{clear}, erases all current trace history records.\nWith a @var{count} parameter, allocates space for that many\nhistory records.\n@end deffn\n\n@deffn {Command} {trace point} [@option{clear}|identifier]\nWith no parameter, displays all trace point identifiers and how many times\nthey have been triggered.\nWith the parameter @option{clear}, erases all current trace point counters.\nWith a numeric @var{identifier} parameter, creates a new a trace point counter\nand associates it with that identifier.\n\n@emph{Important:} The identifier and the trace point number\nare not related except by this command.\nThese trace point numbers always start at zero (from server startup,\nor after @command{trace point clear}) and count up from there.\n@end deffn\n\n\n@node JTAG Commands\n@chapter JTAG Commands\n@cindex JTAG Commands\nMost general purpose JTAG commands have been presented earlier.\n(@xref{jtagspeed,,JTAG Speed}, @ref{Reset Configuration}, and @ref{TAP Declaration}.)\nLower level JTAG commands, as presented here,\nmay be needed to work with targets which require special\nattention during operations such as reset or initialization.\n\nTo use these commands you will need to understand some\nof the basics of JTAG, including:\n\n@itemize @bullet\n@item A JTAG scan chain consists of a sequence of individual TAP\ndevices such as a CPUs.\n@item Control operations involve moving each TAP through the same\nstandard state machine (in parallel)\nusing their shared TMS and clock signals.\n@item Data transfer involves shifting data through the chain of\ninstruction or data registers of each TAP, writing new register values\nwhile the reading previous ones.\n@item Data register sizes are a function of the instruction active in\na given TAP, while instruction register sizes are fixed for each TAP.\nAll TAPs support a BYPASS instruction with a single bit data register.\n@item The way OpenOCD differentiates between TAP devices is by\nshifting different instructions into (and out of) their instruction\nregisters.\n@end itemize\n\n@section Low Level JTAG Commands\n\nThese commands are used by developers who need to access\nJTAG instruction or data registers, possibly controlling\nthe order of TAP state transitions.\nIf you're not debugging OpenOCD internals, or bringing up a\nnew JTAG adapter or a new type of TAP device (like a CPU or\nJTAG router), you probably won't need to use these commands.\nIn a debug session that doesn't use JTAG for its transport protocol,\nthese commands are not available.\n\n@deffn {Command} {drscan} tap [numbits value]+ [@option{-endstate} tap_state]\nLoads the data register of @var{tap} with a series of bit fields\nthat specify the entire register.\nEach field is @var{numbits} bits long with\na numeric @var{value} (hexadecimal encouraged).\nThe return value holds the original value of each\nof those fields.\n\nFor example, a 38 bit number might be specified as one\nfield of 32 bits then one of 6 bits.\n@emph{For portability, never pass fields which are more\nthan 32 bits long. Many OpenOCD implementations do not\nsupport 64-bit (or larger) integer values.}\n\nAll TAPs other than @var{tap} must be in BYPASS mode.\nThe single bit in their data registers does not matter.\n\nWhen @var{tap_state} is specified, the JTAG state machine is left\nin that state.\nFor example @sc{drpause} might be specified, so that more\ninstructions can be issued before re-entering the @sc{run/idle} state.\nIf the end state is not specified, the @sc{run/idle} state is entered.\n\n@quotation Warning\nOpenOCD does not record information about data register lengths,\nso @emph{it is important that you get the bit field lengths right}.\nRemember that different JTAG instructions refer to different\ndata registers, which may have different lengths.\nMoreover, those lengths may not be fixed;\nthe SCAN_N instruction can change the length of\nthe register accessed by the INTEST instruction\n(by connecting a different scan chain).\n@end quotation\n@end deffn\n\n@deffn {Command} {flush_count}\nReturns the number of times the JTAG queue has been flushed.\nThis may be used for performance tuning.\n\nFor example, flushing a queue over USB involves a\nminimum latency, often several milliseconds, which does\nnot change with the amount of data which is written.\nYou may be able to identify performance problems by finding\ntasks which waste bandwidth by flushing small transfers too often,\ninstead of batching them into larger operations.\n@end deffn\n\n@deffn {Command} {irscan} [tap instruction]+ [@option{-endstate} tap_state]\nFor each @var{tap} listed, loads the instruction register\nwith its associated numeric @var{instruction}.\n(The number of bits in that instruction may be displayed\nusing the @command{scan_chain} command.)\nFor other TAPs, a BYPASS instruction is loaded.\n\nWhen @var{tap_state} is specified, the JTAG state machine is left\nin that state.\nFor example @sc{irpause} might be specified, so the data register\ncan be loaded before re-entering the @sc{run/idle} state.\nIf the end state is not specified, the @sc{run/idle} state is entered.\n\n@quotation Note\nOpenOCD currently supports only a single field for instruction\nregister values, unlike data register values.\nFor TAPs where the instruction register length is more than 32 bits,\nportable scripts currently must issue only BYPASS instructions.\n@end quotation\n@end deffn\n\n@deffn {Command} {pathmove} start_state [next_state ...]\nStart by moving to @var{start_state}, which\nmust be one of the @emph{stable} states.\nUnless it is the only state given, this will often be the\ncurrent state, so that no TCK transitions are needed.\nThen, in a series of single state transitions\n(conforming to the JTAG state machine) shift to\neach @var{next_state} in sequence, one per TCK cycle.\nThe final state must also be stable.\n@end deffn\n\n@deffn {Command} {runtest} @var{num_cycles}\nMove to the @sc{run/idle} state, and execute at least\n@var{num_cycles} of the JTAG clock (TCK).\nInstructions often need some time\nto execute before they take effect.\n@end deffn\n\n@c tms_sequence (short|long)\n@c ... temporary, debug-only, other than USBprog bug workaround...\n\n@deffn {Command} {verify_ircapture} (@option{enable}|@option{disable})\nVerify values captured during @sc{ircapture} and returned\nduring IR scans. Default is enabled, but this can be\noverridden by @command{verify_jtag}.\nThis flag is ignored when validating JTAG chain configuration.\n@end deffn\n\n@deffn {Command} {verify_jtag} (@option{enable}|@option{disable})\nEnables verification of DR and IR scans, to help detect\nprogramming errors. For IR scans, @command{verify_ircapture}\nmust also be enabled.\nDefault is enabled.\n@end deffn\n\n@section TAP state names\n@cindex TAP state names\n\nThe @var{tap_state} names used by OpenOCD in the @command{drscan},\n@command{irscan}, and @command{pathmove} commands are the same\nas those used in SVF boundary scan documents, except that\nSVF uses @sc{idle} instead of @sc{run/idle}.\n\n@itemize @bullet\n@item @b{RESET} ... @emph{stable} (with TMS high);\nacts as if TRST were pulsed\n@item @b{RUN/IDLE} ... @emph{stable}; don't assume this always means IDLE\n@item @b{DRSELECT}\n@item @b{DRCAPTURE}\n@item @b{DRSHIFT} ... @emph{stable}; TDI/TDO shifting\nthrough the data register\n@item @b{DREXIT1}\n@item @b{DRPAUSE} ... @emph{stable}; data register ready\nfor update or more shifting\n@item @b{DREXIT2}\n@item @b{DRUPDATE}\n@item @b{IRSELECT}\n@item @b{IRCAPTURE}\n@item @b{IRSHIFT} ... @emph{stable}; TDI/TDO shifting\nthrough the instruction register\n@item @b{IREXIT1}\n@item @b{IRPAUSE} ... @emph{stable}; instruction register ready\nfor update or more shifting\n@item @b{IREXIT2}\n@item @b{IRUPDATE}\n@end itemize\n\nNote that only six of those states are fully ``stable'' in the\nface of TMS fixed (low except for @sc{reset})\nand a free-running JTAG clock. For all the\nothers, the next TCK transition changes to a new state.\n\n@itemize @bullet\n@item From @sc{drshift} and @sc{irshift}, clock transitions will\nproduce side effects by changing register contents. The values\nto be latched in upcoming @sc{drupdate} or @sc{irupdate} states\nmay not be as expected.\n@item @sc{run/idle}, @sc{drpause}, and @sc{irpause} are reasonable\nchoices after @command{drscan} or @command{irscan} commands,\nsince they are free of JTAG side effects.\n@item @sc{run/idle} may have side effects that appear at non-JTAG\nlevels, such as advancing the ARM9E-S instruction pipeline.\nConsult the documentation for the TAP(s) you are working with.\n@end itemize\n\n@node Boundary Scan Commands\n@chapter Boundary Scan Commands\n\nOne of the original purposes of JTAG was to support\nboundary scan based hardware testing.\nAlthough its primary focus is to support On-Chip Debugging,\nOpenOCD also includes some boundary scan commands.\n\n@section SVF: Serial Vector Format\n@cindex Serial Vector Format\n@cindex SVF\n\nThe Serial Vector Format, better known as @dfn{SVF}, is a\nway to represent JTAG test patterns in text files.\nIn a debug session using JTAG for its transport protocol,\nOpenOCD supports running such test files.\n\n@deffn {Command} {svf} @file{filename} [@option{-tap @var{tapname}}] [@option{-quiet}] @\n                     [@option{-nil}] [@option{-progress}] [@option{-ignore_error}] @\n                     [@option{-noreset}] [@option{-addcycles @var{cyclecount}}]\nThis issues a JTAG reset (Test-Logic-Reset) and then\nruns the SVF script from @file{filename}.\n\nArguments can be specified in any order; the optional dash doesn't\naffect their semantics.\n\nCommand options:\n@itemize @minus\n@item @option{-tap @var{tapname}} ignore IR and DR headers and footers\nspecified by the SVF file with HIR, TIR, HDR and TDR commands;\ninstead, calculate them automatically according to the current JTAG\nchain configuration, targeting @var{tapname};\n@item @option{-quiet} do not log every command before execution;\n@item @option{-nil} ``dry run'', i.e., do not perform any operations\non the real interface;\n@item @option{-progress} enable progress indication;\n@item @option{-ignore_error} continue execution despite TDO check\nerrors.\n@item @option{-noreset} omit JTAG reset (Test-Logic-Reset) before executing\ncontent of the SVF file;\n@item @option{-addcycles @var{cyclecount}} inject @var{cyclecount} number of\nadditional TCLK cycles after each SDR scan instruction;\n@end itemize\n@end deffn\n\n@section XSVF: Xilinx Serial Vector Format\n@cindex Xilinx Serial Vector Format\n@cindex XSVF\n\nThe Xilinx Serial Vector Format, better known as @dfn{XSVF}, is a\nbinary representation of SVF which is optimized for use with\nXilinx devices.\nIn a debug session using JTAG for its transport protocol,\nOpenOCD supports running such test files.\n\n@quotation Important\nNot all XSVF commands are supported.\n@end quotation\n\n@deffn {Command} {xsvf} (tapname|@option{plain}) filename [@option{virt2}] [@option{quiet}]\nThis issues a JTAG reset (Test-Logic-Reset) and then\nruns the XSVF script from @file{filename}.\nWhen a @var{tapname} is specified, the commands are directed at\nthat TAP.\nWhen @option{virt2} is specified, the @sc{xruntest} command counts\nare interpreted as TCK cycles instead of microseconds.\nUnless the @option{quiet} option is specified,\nmessages are logged for comments and some retries.\n@end deffn\n\nThe OpenOCD sources also include two utility scripts\nfor working with XSVF; they are not currently installed\nafter building the software.\nYou may find them useful:\n\n@itemize\n@item @emph{svf2xsvf} ... converts SVF files into the extended XSVF\nsyntax understood by the @command{xsvf} command; see notes below.\n@item @emph{xsvfdump} ... converts XSVF files into a text output format;\nunderstands the OpenOCD extensions.\n@end itemize\n\nThe input format accepts a handful of non-standard extensions.\nThese include three opcodes corresponding to SVF extensions\nfrom Lattice Semiconductor (LCOUNT, LDELAY, LDSR), and\ntwo opcodes supporting a more accurate translation of SVF\n(XTRST, XWAITSTATE).\nIf @emph{xsvfdump} shows a file is using those opcodes, it\nprobably will not be usable with other XSVF tools.\n\n\n@section IPDBG: JTAG-Host server\n@cindex IPDBG JTAG-Host server\n@cindex IPDBG\n\nIPDBG is a set of tools to debug IP-Cores. It comprises, among others, a logic analyzer and an arbitrary\nwaveform generator. These are synthesize-able hardware descriptions of\nlogic circuits in addition to software for control, visualization and further analysis.\nIn a session using JTAG for its transport protocol, OpenOCD supports the function\nof a JTAG-Host. The JTAG-Host is needed to connect the circuit over JTAG to the\ncontrol-software. For more details see @url{http://ipdbg.org}.\n\n@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-tap @var{tapname}} @option{-hub @var{ir_value} [@var{dr_length}]} [@option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]}] [@option{-port @var{number}}] [@option{-tool @var{number}}]\nStarts or stops a IPDBG JTAG-Host server. Arguments can be specified in any order.\n\nCommand options:\n@itemize @bullet\n@item @option{-start|-stop} starts or stops a IPDBG JTAG-Host server (default: start).\n@item @option{-tap @var{tapname}} targeting the TAP @var{tapname}.\n@item @option{-hub @var{ir_value}} states that the JTAG hub is\nreachable with dr-scans while the JTAG instruction register has the value @var{ir_value}.\n@item @option{-port @var{number}} tcp port number where the JTAG-Host will listen. The default is 4242 which is used when the option is not given.\n@item @option{-tool @var{number}} number of the tool/feature. These corresponds to the ports \"data_(up/down)_(0..6)\" at the JtagHub. The default is 1 which is used when the option is not given.\n@item @option{-vir [@var{vir_value} [@var{length} [@var{instr_code}]]]} On some devices, the user data-register is reachable if there is a\nspecific value in a second dr. This second dr is called vir (virtual ir). With this parameter given, the IPDBG satisfies this condition prior an\naccess to the IPDBG-Hub. The value shifted into the vir is given by the first parameter @var{vir_value} (default: 0x11). The second\nparameter @var{length} is the length of the vir data register (default: 5). With the @var{instr_code} (default: 0x00e) parameter the ir value to\nshift data through vir can be configured.\n@end itemize\n@end deffn\nor\n@deffn {Command} {ipdbg} [@option{-start|-stop}] @option{-pld @var{name} [@var{user}]} [@option{-port @var{number}}] [@option{-tool @var{number}}]\nAlso starts or stops a IPDBG JTAG-Host server. The pld drivers are able to provide the tap and hub/IR for the IPDBG JTAG-Host server.\nWith the @option{-pld @var{name} [@var{user}]} the information from the pld-driver is used and the options @option{-tap} and @option{-hub} are not required.\nThe defined driver for the pld @var{name} gets selected. (The pld devices names can be shown by the command @command{pld devices}).\n\nThe @verb{|USERx|} instructions are vendor specific and don't change between families of the same vendor.\nSo if there's a pld driver for your vendor it should work with your FPGA even when the driver is not compatible with your device for the remaining features. If your device/vendor is not supported you have to use the previous command.\n\nWith [@var{user}] one can select a different @verb{|USERx|}-Instruction. If the IPDBG JTAG-Hub is used without modification the default value of 1 which selects the first @verb{|USERx|} instruction is adequate.\n\nThe remaining options are described in the previous command.\n@end deffn\n\nExamples:\n@example\nipdbg -start -tap xc6s.tap -hub 0x02 -port 4242 -tool 4\n@end example\nStarts a server listening on tcp-port 4242 which connects to tool 4.\nThe connection is through the TAP of a Xilinx Spartan 6 on USER1 instruction (tested with a papillion pro board).\n\n@example\nipdbg -start -tap 10m50.tap -hub 0x00C -vir -port 60000 -tool 1\n@end example\nStarts a server listening on tcp-port 60000 which connects to tool 1 (data_up_1/data_down_1).\nThe connection is through the TAP of a Intel MAX10 virtual jtag component (sld_instance_index is 0; sld_ir_width is smaller than 5).\n\n@example\nipdbg -start -pld xc7.pld -port 5555 -tool 0\n@end example\nStarts a server listening on tcp-port 5555 which connects to tool 0 (data_up_0/data_down_0).\nThe TAP and ir value used to reach the JTAG Hub is given by the pld driver.\n\n\n@node Utility Commands\n@chapter Utility Commands\n@cindex Utility Commands\n\n@section RAM testing\n@cindex RAM testing\n\nThere is often a need to stress-test random access memory (RAM) for\nerrors. OpenOCD comes with a Tcl implementation of well-known memory\ntesting procedures allowing the detection of all sorts of issues with\nelectrical wiring, defective chips, PCB layout and other common\nhardware problems.\n\nTo use them, you usually need to initialise your RAM controller first;\nconsult your SoC's documentation to get the recommended list of\nregister operations and translate them to the corresponding\n@command{mww}/@command{mwb} commands.\n\nLoad the memory testing functions with\n\n@example\nsource [find tools/memtest.tcl]\n@end example\n\nto get access to the following facilities:\n\n@deffn {Command} {memTestDataBus} address\nTest the data bus wiring in a memory region by performing a walking\n1's test at a fixed address within that region.\n@end deffn\n\n@deffn {Command} {memTestAddressBus} baseaddress size\nPerform a walking 1's test on the relevant bits of the address and\ncheck for aliasing. This test will find single-bit address failures\nsuch as stuck-high, stuck-low, and shorted pins.\n@end deffn\n\n@deffn {Command} {memTestDevice} baseaddress size\nTest the integrity of a physical memory device by performing an\nincrement/decrement test over the entire region. In the process every\nstorage bit in the device is tested as zero and as one.\n@end deffn\n\n@deffn {Command} {runAllMemTests} baseaddress size\nRun all of the above tests over a specified memory region.\n@end deffn\n\n@section Firmware recovery helpers\n@cindex Firmware recovery\n\nOpenOCD includes an easy-to-use script to facilitate mass-market\ndevices recovery with JTAG.\n\nFor quickstart instructions run:\n@example\nopenocd -f tools/firmware-recovery.tcl -c firmware_help\n@end example\n\n@node GDB and OpenOCD\n@chapter GDB and OpenOCD\n@cindex GDB\nOpenOCD complies with the remote gdbserver protocol and, as such, can be used\nto debug remote targets.\nSetting up GDB to work with OpenOCD can involve several components:\n\n@itemize\n@item The OpenOCD server support for GDB may need to be configured.\n@xref{gdbconfiguration,,GDB Configuration}.\n@item GDB's support for OpenOCD may need configuration,\nas shown in this chapter.\n@item If you have a GUI environment like Eclipse,\nthat also will probably need to be configured.\n@end itemize\n\nOf course, the version of GDB you use will need to be one which has\nbeen built to know about the target CPU you're using. It's probably\npart of the tool chain you're using. For example, if you are doing\ncross-development for ARM on an x86 PC, instead of using the native\nx86 @command{gdb} command you might use @command{arm-none-eabi-gdb}\nif that's the tool chain used to compile your code.\n\n@section Connecting to GDB\n@cindex Connecting to GDB\nUse GDB 6.7 or newer with OpenOCD if you run into trouble. For\ninstance GDB 6.3 has a known bug that produces bogus memory access\nerrors, which has since been fixed; see\n@url{http://osdir.com/ml/gdb.bugs.discuss/2004-12/msg00018.html}\n\nOpenOCD can communicate with GDB in two ways:\n\n@enumerate\n@item\nA socket (TCP/IP) connection is typically started as follows:\n@example\ntarget extended-remote localhost:3333\n@end example\nThis would cause GDB to connect to the gdbserver on the local pc using port 3333.\n\nThe extended remote protocol is a super-set of the remote protocol and should\nbe the preferred choice. More details are available in GDB documentation\n@url{https://sourceware.org/gdb/onlinedocs/gdb/Connecting.html}\n\nTo speed-up typing, any GDB command can be abbreviated, including the extended\nremote command above that becomes:\n@example\ntar ext :3333\n@end example\n\n@b{Note:} If any backward compatibility issue requires using the old remote\nprotocol in place of the extended remote one, the former protocol is still\navailable through the command:\n@example\ntarget remote localhost:3333\n@end example\n\n@item\nA pipe connection is typically started as follows:\n@example\ntarget extended-remote | \\\n       openocd -c \"gdb_port pipe; log_output openocd.log\"\n@end example\nThis would cause GDB to run OpenOCD and communicate using pipes (stdin/stdout).\nUsing this method has the advantage of GDB starting/stopping OpenOCD for the debug\nsession. log_output sends the log output to a file to ensure that the pipe is\nnot saturated when using higher debug level outputs.\n@end enumerate\n\nTo list the available OpenOCD commands type @command{monitor help} on the\nGDB command line.\n\n@section Sample GDB session startup\n\nWith the remote protocol, GDB sessions start a little differently\nthan they do when you're debugging locally.\nHere's an example showing how to start a debug session with a\nsmall ARM program.\nIn this case the program was linked to be loaded into SRAM on a Cortex-M3.\nMost programs would be written into flash (address 0) and run from there.\n\n@example\n$ arm-none-eabi-gdb example.elf\n(gdb) target extended-remote localhost:3333\nRemote debugging using localhost:3333\n...\n(gdb) monitor reset halt\n...\n(gdb) load\nLoading section .vectors, size 0x100 lma 0x20000000\nLoading section .text, size 0x5a0 lma 0x20000100\nLoading section .data, size 0x18 lma 0x200006a0\nStart address 0x2000061c, load size 1720\nTransfer rate: 22 KB/sec, 573 bytes/write.\n(gdb) continue\nContinuing.\n...\n@end example\n\nYou could then interrupt the GDB session to make the program break,\ntype @command{where} to show the stack, @command{list} to show the\ncode around the program counter, @command{step} through code,\nset breakpoints or watchpoints, and so on.\n\n@section Configuring GDB for OpenOCD\n\nOpenOCD supports the gdb @option{qSupported} packet, this enables information\nto be sent by the GDB remote server (i.e. OpenOCD) to GDB. Typical information includes\npacket size and the device's memory map.\nYou do not need to configure the packet size by hand,\nand the relevant parts of the memory map should be automatically\nset up when you declare (NOR) flash banks.\n\nHowever, there are other things which GDB can't currently query.\nYou may need to set those up by hand.\nAs OpenOCD starts up, you will often see a line reporting\nsomething like:\n\n@example\nInfo : lm3s.cpu: hardware has 6 breakpoints, 4 watchpoints\n@end example\n\nYou can pass that information to GDB with these commands:\n\n@example\nset remote hardware-breakpoint-limit 6\nset remote hardware-watchpoint-limit 4\n@end example\n\nWith that particular hardware (Cortex-M3) the hardware breakpoints\nonly work for code running from flash memory. Most other ARM systems\ndo not have such restrictions.\n\nRather than typing such commands interactively, you may prefer to\nsave them in a file and have GDB execute them as it starts, perhaps\nusing a @file{.gdbinit} in your project directory or starting GDB\nusing @command{gdb -x filename}.\n\n@section Programming using GDB\n@cindex Programming using GDB\n@anchor{programmingusinggdb}\n\nBy default the target memory map is sent to GDB. This can be disabled by\nthe following OpenOCD configuration option:\n@example\ngdb_memory_map disable\n@end example\nFor this to function correctly a valid flash configuration must also be set\nin OpenOCD. For faster performance you should also configure a valid\nworking area.\n\nInforming GDB of the memory map of the target will enable GDB to protect any\nflash areas of the target and use hardware breakpoints by default. This means\nthat the OpenOCD option @command{gdb_breakpoint_override} is not required when\nusing a memory map. @xref{gdbbreakpointoverride,,gdb_breakpoint_override}.\n\nTo view the configured memory map in GDB, use the GDB command @option{info mem}.\nAll other unassigned addresses within GDB are treated as RAM.\n\nGDB 6.8 and higher set any memory area not in the memory map as inaccessible.\nThis can be changed to the old behaviour by using the following GDB command\n@example\nset mem inaccessible-by-default off\n@end example\n\nIf @command{gdb_flash_program enable} is also used, GDB will be able to\nprogram any flash memory using the vFlash interface.\n\nGDB will look at the target memory map when a load command is given, if any\nareas to be programmed lie within the target flash area the vFlash packets\nwill be used.\n\nIf the target needs configuring before GDB programming, set target\nevent gdb-flash-erase-start:\n@example\n$_TARGETNAME configure -event gdb-flash-erase-start BODY\n@end example\n@xref{targetevents,,Target Events}, for other GDB programming related events.\n\nTo verify any flash programming the GDB command @option{compare-sections}\ncan be used.\n\n@section Using GDB as a non-intrusive memory inspector\n@cindex Using GDB as a non-intrusive memory inspector\n@anchor{gdbmeminspect}\n\nIf your project controls more than a blinking LED, let's say a heavy industrial\nrobot or an experimental nuclear reactor, stopping the controlling process\njust because you want to attach GDB is not a good option.\n\nOpenOCD does not support GDB non-stop mode (might be implemented in the future).\nThough there is a possible setup where the target does not get stopped\nand GDB treats it as it were running.\nIf the target supports background access to memory while it is running,\nyou can use GDB in this mode to inspect memory (mainly global variables)\nwithout any intrusion of the target process.\n\nRemove default setting of gdb-attach event. @xref{targetevents,,Target Events}.\nPlace following command after target configuration:\n@example\n$_TARGETNAME configure -event gdb-attach @{@}\n@end example\n\nIf any of installed flash banks does not support probe on running target,\nswitch off gdb_memory_map:\n@example\ngdb_memory_map disable\n@end example\n\nEnsure GDB is configured without interrupt-on-connect.\nSome GDB versions set it by default, some does not.\n@example\nset remote interrupt-on-connect off\n@end example\n\nIf you switched gdb_memory_map off, you may want to setup GDB memory map\nmanually or issue @command{set mem inaccessible-by-default off}\n\nNow you can issue GDB command @command{target extended-remote ...} and inspect memory\nof a running target. Do not use GDB commands @command{continue},\n@command{step} or @command{next} as they synchronize GDB with your target\nand GDB would require stopping the target to get the prompt back.\n\nDo not use this mode under an IDE like Eclipse as it caches values of\npreviously shown variables.\n\nIt's also possible to connect more than one GDB to the same target by the\ntarget's configuration option @code{-gdb-max-connections}. This allows, for\nexample, one GDB to run a script that continuously polls a set of variables\nwhile other GDB can be used interactively. Be extremely careful in this case,\nbecause the two GDB can easily get out-of-sync.\n\n@section RTOS Support\n@cindex RTOS Support\n@anchor{gdbrtossupport}\n\nOpenOCD includes RTOS support, this will however need enabling as it defaults to disabled.\nIt can be enabled by passing @option{-rtos} arg to the target. @xref{rtostype,,RTOS Type}.\n\n@xref{Threads, Debugging Programs with Multiple Threads,\nDebugging Programs with Multiple Threads, gdb, GDB manual}, for details about relevant\nGDB commands.\n\n@* An example setup is below:\n\n@example\n$_TARGETNAME configure -rtos auto\n@end example\n\nThis will attempt to auto detect the RTOS within your application.\n\nCurrently supported rtos's include:\n@itemize @bullet\n@item @option{eCos}\n@item @option{ThreadX}\n@item @option{FreeRTOS}\n@item @option{linux}\n@item @option{ChibiOS}\n@item @option{embKernel}\n@item @option{mqx}\n@item @option{uCOS-III}\n@item @option{nuttx}\n@item @option{RIOT}\n@item @option{hwthread} (This is not an actual RTOS. @xref{usingopenocdsmpwithgdb,,Using OpenOCD SMP with GDB}.)\n@item @option{Zephyr}\n@item @option{rtkernel}\n@end itemize\n\nAt any time, it's possible to drop the selected RTOS using:\n@example\n$_TARGETNAME configure -rtos none\n@end example\n\nBefore an RTOS can be detected, it must export certain symbols; otherwise, it cannot\nbe used by OpenOCD. Below is a list of the required symbols for each supported RTOS.\n\n@table @code\n@item eCos symbols\nCyg_Thread::thread_list, Cyg_Scheduler_Base::current_thread.\n@item ThreadX symbols\n_tx_thread_current_ptr, _tx_thread_created_ptr, _tx_thread_created_count.\n@item FreeRTOS symbols\n@raggedright\npxCurrentTCB, pxReadyTasksLists, xDelayedTaskList1, xDelayedTaskList2,\npxDelayedTaskList, pxOverflowDelayedTaskList, xPendingReadyList,\nuxCurrentNumberOfTasks, uxTopUsedPriority, xSchedulerRunning.\n@end raggedright\n@item linux symbols\ninit_task.\n@item ChibiOS symbols\nrlist, ch_debug, chSysInit.\n@item embKernel symbols\nRtos::sCurrentTask, Rtos::sListReady, Rtos::sListSleep,\nRtos::sListSuspended, Rtos::sMaxPriorities, Rtos::sCurrentTaskCount.\n@item mqx symbols\n_mqx_kernel_data, MQX_init_struct.\n@item uC/OS-III symbols\nOSRunning, OSTCBCurPtr, OSTaskDbgListPtr, OSTaskQty.\n@item nuttx symbols\ng_readytorun, g_tasklisttable.\n@item RIOT symbols\n@raggedright\nsched_threads, sched_num_threads, sched_active_pid, max_threads,\n_tcb_name_offset.\n@end raggedright\n@item Zephyr symbols\n_kernel, _kernel_openocd_offsets, _kernel_openocd_size_t_size\n@item rtkernel symbols\nMultiple struct offsets.\n@end table\n\nFor most RTOS supported the above symbols will be exported by default. However for\nsome, eg. FreeRTOS, uC/OS-III and Zephyr, extra steps must be taken.\n\nZephyr must be compiled with the DEBUG_THREAD_INFO option. This will generate some symbols\nwith information needed in order to build the list of threads.\n\nFreeRTOS and uC/OS-III RTOSes may require additional OpenOCD-specific file to be linked\nalong with the project:\n\n@table @code\n@item FreeRTOS\ncontrib/rtos-helpers/FreeRTOS-openocd.c\n@item uC/OS-III\ncontrib/rtos-helpers/uCOS-III-openocd.c\n@end table\n\n@anchor{usingopenocdsmpwithgdb}\n@section Using OpenOCD SMP with GDB\n@cindex SMP\n@cindex RTOS\n@cindex hwthread\nOpenOCD includes a pseudo RTOS called @emph{hwthread} that presents CPU cores\n(\"hardware threads\") in an SMP system as threads to GDB. With this extension,\nGDB can be used to inspect the state of an SMP system in a natural way.\nAfter halting the system, using the GDB command @command{info threads} will\nlist the context of each active CPU core in the system. GDB's @command{thread}\ncommand can be used to switch the view to a different CPU core.\nThe @command{step} and @command{stepi} commands can be used to step a specific core\nwhile other cores are free-running or remain halted, depending on the\nscheduler-locking mode configured in GDB.\n\n@node Tcl Scripting API\n@chapter Tcl Scripting API\n@cindex Tcl Scripting API\n@cindex Tcl scripts\n@section API rules\n\nTcl commands are stateless; e.g. the @command{telnet} command has\na concept of currently active target, the Tcl API proc's take this sort\nof state information as an argument to each proc.\n\nThere are three main types of return values: single value, name value\npair list and lists.\n\nName value pair. The proc 'foo' below returns a name/value pair\nlist.\n\n@example\n>  set foo(me)  Duane\n>  set foo(you) Oyvind\n>  set foo(mouse) Micky\n>  set foo(duck) Donald\n@end example\n\nIf one does this:\n\n@example\n>  set foo\n@end example\n\nThe result is:\n\n@example\nme Duane you Oyvind mouse Micky duck Donald\n@end example\n\nThus, to get the names of the associative array is easy:\n\n@verbatim\nforeach { name value } [set foo] {\n        puts \"Name: $name, Value: $value\"\n}\n@end verbatim\n\nLists returned should be relatively small. Otherwise, a range\nshould be passed in to the proc in question.\n\n@section Internal low-level Commands\n\nBy \"low-level\", we mean commands that a human would typically not\ninvoke directly.\n\n@itemize\n@item @b{flash banks} <@var{driver}> <@var{base}> <@var{size}> <@var{chip_width}> <@var{bus_width}> <@var{target}> [@option{driver options} ...]\n\nReturn information about the flash banks\n\n@item @b{capture} <@var{command}>\n\nRun <@var{command}> and return full log output that was produced during\nits execution. Example:\n\n@example\n> capture \"reset init\"\n@end example\n\n@end itemize\n\nOpenOCD commands can consist of two words, e.g. \"flash banks\". The\n@file{startup.tcl} \"unknown\" proc will translate this into a Tcl proc\ncalled \"flash_banks\".\n\n@section Tcl RPC server\n@cindex RPC\n\nOpenOCD provides a simple RPC server that allows to run arbitrary Tcl\ncommands and receive the results.\n\nTo access it, your application needs to connect to a configured TCP port\n(see @command{tcl_port}). Then it can pass any string to the\ninterpreter terminating it with @code{0x1a} and wait for the return\nvalue (it will be terminated with @code{0x1a} as well). This can be\nrepeated as many times as desired without reopening the connection.\n\nIt is not needed anymore to prefix the OpenOCD commands with\n@code{ocd_} to get the results back. But sometimes you might need the\n@command{capture} command.\n\nSee @file{contrib/rpc_examples/} for specific client implementations.\n\n@section Tcl RPC server notifications\n@cindex RPC Notifications\n\nNotifications are sent asynchronously to other commands being executed over\nthe RPC server, so the port must be polled continuously.\n\nTarget event, state and reset notifications are emitted as Tcl associative arrays\nin the following format.\n\n@verbatim\ntype target_event event [event-name]\ntype target_state state [state-name]\ntype target_reset mode [reset-mode]\n@end verbatim\n\n@deffn {Command} {tcl_notifications} [on/off]\nToggle output of target notifications to the current Tcl RPC server.\nOnly available from the Tcl RPC server.\nDefaults to off.\n\n@end deffn\n\n@section Tcl RPC server trace output\n@cindex RPC trace output\n\nTrace data is sent asynchronously to other commands being executed over\nthe RPC server, so the port must be polled continuously.\n\nTarget trace data is emitted as a Tcl associative array in the following format.\n\n@verbatim\ntype target_trace data [trace-data-hex-encoded]\n@end verbatim\n\n@deffn {Command} {tcl_trace} [on/off]\nToggle output of target trace data to the current Tcl RPC server.\nOnly available from the Tcl RPC server.\nDefaults to off.\n\nSee an example application here:\n@url{https://github.com/apmorton/OpenOcdTraceUtil} [OpenOcdTraceUtil]\n\n@end deffn\n\n@node FAQ\n@chapter FAQ\n@cindex faq\n@enumerate\n@anchor{faqrtck}\n@item @b{RTCK, also known as: Adaptive Clocking - What is it?}\n@cindex RTCK\n@cindex adaptive clocking\n@*\n\nIn digital circuit design it is often referred to as ``clock\nsynchronisation'' the JTAG interface uses one clock (TCK or TCLK)\noperating at some speed, your CPU target is operating at another.\nThe two clocks are not synchronised, they are ``asynchronous''\n\nIn order for the two to work together they must be synchronised\nwell enough to work; JTAG can't go ten times faster than the CPU,\nfor example. There are 2 basic options:\n@enumerate\n@item\nUse a special \"adaptive clocking\" circuit to change the JTAG\nclock rate to match what the CPU currently supports.\n@item\nThe JTAG clock must be fixed at some speed that's enough slower than\nthe CPU clock that all TMS and TDI transitions can be detected.\n@end enumerate\n\n@b{Does this really matter?} For some chips and some situations, this\nis a non-issue, like a 500MHz ARM926 with a 5 MHz JTAG link;\nthe CPU has no difficulty keeping up with JTAG.\nStartup sequences are often problematic though, as are other\nsituations where the CPU clock rate changes (perhaps to save\npower).\n\nFor example, Atmel AT91SAM chips start operation from reset with\na 32kHz system clock. Boot firmware may activate the main oscillator\nand PLL before switching to a faster clock (perhaps that 500 MHz\nARM926 scenario).\nIf you're using JTAG to debug that startup sequence, you must slow\nthe JTAG clock to sometimes 1 to 4kHz. After startup completes,\nJTAG can use a faster clock.\n\nConsider also debugging a 500MHz ARM926 hand held battery powered\ndevice that enters a low power ``deep sleep'' mode, at 32kHz CPU\nclock, between keystrokes unless it has work to do. When would\nthat 5 MHz JTAG clock be usable?\n\n@b{Solution #1 - A special circuit}\n\nIn order to make use of this,\nyour CPU, board, and JTAG adapter must all support the RTCK\nfeature. Not all of them support this; keep reading!\n\nThe RTCK (\"Return TCK\") signal in some ARM chips is used to help with\nthis problem. ARM has a good description of the problem described at\nthis link: @url{http://www.arm.com/support/faqdev/4170.html} [checked\n28/nov/2008]. Link title: ``How does the JTAG synchronisation logic\nwork? / how does adaptive clocking work?''.\n\nThe nice thing about adaptive clocking is that ``battery powered hand\nheld device example'' - the adaptiveness works perfectly all the\ntime. One can set a break point or halt the system in the deep power\ndown code, slow step out until the system speeds up.\n\nNote that adaptive clocking may also need to work at the board level,\nwhen a board-level scan chain has multiple chips.\nParallel clock voting schemes are good way to implement this,\nboth within and between chips, and can easily be implemented\nwith a CPLD.\nIt's not difficult to have logic fan a module's input TCK signal out\nto each TAP in the scan chain, and then wait until each TAP's RTCK comes\nback with the right polarity before changing the output RTCK signal.\nTexas Instruments makes some clock voting logic available\nfor free (with no support) in VHDL form; see\n@url{http://tiexpressdsp.com/index.php/Adaptive_Clocking}\n\n@b{Solution #2 - Always works - but may be slower}\n\nOften this is a perfectly acceptable solution.\n\nIn most simple terms: Often the JTAG clock must be 1/10 to 1/12 of\nthe target clock speed. But what that ``magic division'' is varies\ndepending on the chips on your board.\n@b{ARM rule of thumb} Most ARM based systems require an 6:1 division;\nARM11 cores use an 8:1 division.\n@b{Xilinx rule of thumb} is 1/12 the clock speed.\n\nNote: most full speed FT2232 based JTAG adapters are limited to a\nmaximum of 6MHz. The ones using USB high speed chips (FT2232H)\noften support faster clock rates (and adaptive clocking).\n\nYou can still debug the 'low power' situations - you just need to\neither use a fixed and very slow JTAG clock rate ... or else\nmanually adjust the clock speed at every step. (Adjusting is painful\nand tedious, and is not always practical.)\n\nIt is however easy to ``code your way around it'' - i.e.: Cheat a little,\nhave a special debug mode in your application that does a ``high power\nsleep''. If you are careful - 98% of your problems can be debugged\nthis way.\n\nNote that on ARM you may need to avoid using the @emph{wait for interrupt}\noperation in your idle loops even if you don't otherwise change the CPU\nclock rate.\nThat operation gates the CPU clock, and thus the JTAG clock; which\nprevents JTAG access. One consequence is not being able to @command{halt}\ncores which are executing that @emph{wait for interrupt} operation.\n\nTo set the JTAG frequency use the command:\n\n@example\n# Example: 1.234MHz\nadapter speed 1234\n@end example\n\n\n@item @b{Win32 Pathnames} Why don't backslashes work in Windows paths?\n\nOpenOCD uses Tcl and a backslash is an escape char. Use @{ and @}\naround Windows filenames.\n\n@example\n> echo \\a\n\n> echo @{\\a@}\n\\a\n> echo \"\\a\"\n\n>\n@end example\n\n\n@item @b{Missing: cygwin1.dll} OpenOCD complains about a missing cygwin1.dll.\n\nMake sure you have Cygwin installed, or at least a version of OpenOCD that\nclaims to come with all the necessary DLLs. When using Cygwin, try launching\nOpenOCD from the Cygwin shell.\n\n@item @b{Breakpoint Issue} I'm trying to set a breakpoint using GDB (or a front-end like Insight or\nEclipse), but OpenOCD complains that \"Info: arm7_9_common.c:213\narm7_9_add_breakpoint(): sw breakpoint requested, but software breakpoints not enabled\".\n\nGDB issues software breakpoints when a normal breakpoint is requested, or to implement\nsource-line single-stepping. On ARMv4T systems, like ARM7TDMI, ARM720T or ARM920T,\nsoftware breakpoints consume one of the two available hardware breakpoints.\n\n@item @b{LPC2000 Flash} When erasing or writing LPC2000 on-chip flash, the operation fails at random.\n\nMake sure the core frequency specified in the @option{flash lpc2000} line matches the\nclock at the time you're programming the flash. If you've specified the crystal's\nfrequency, make sure the PLL is disabled. If you've specified the full core speed\n(e.g. 60MHz), make sure the PLL is enabled.\n\n@item @b{Amontec Chameleon} When debugging using an Amontec Chameleon in its JTAG Accelerator configuration,\nI keep getting \"Error: amt_jtagaccel.c:184 amt_wait_scan_busy(): amt_jtagaccel timed\nout while waiting for end of scan, rtck was disabled\".\n\nMake sure your PC's parallel port operates in EPP mode. You might have to try several\nsettings in your PC BIOS (ECP, EPP, and different versions of those).\n\n@item @b{Data Aborts} When debugging with OpenOCD and GDB (plain GDB, Insight, or Eclipse),\nI get lots of \"Error: arm7_9_common.c:1771 arm7_9_read_memory():\nmemory read caused data abort\".\n\nThe errors are non-fatal, and are the result of GDB trying to trace stack frames\nbeyond the last valid frame. It might be possible to prevent this by setting up\na proper \"initial\" stack frame, if you happen to know what exactly has to\nbe done, feel free to add this here.\n\n@b{Simple:} In your startup code - push 8 registers of zeros onto the\nstack before calling main(). What GDB is doing is ``climbing'' the run\ntime stack by reading various values on the stack using the standard\ncall frame for the target. GDB keeps going - until one of 2 things\nhappen @b{#1} an invalid frame is found, or @b{#2} some huge number of\nstackframes have been processed. By pushing zeros on the stack, GDB\ngracefully stops.\n\n@b{Debugging Interrupt Service Routines} - In your ISR before you call\nyour C code, do the same - artificially push some zeros onto the stack,\nremember to pop them off when the ISR is done.\n\n@b{Also note:} If you have a multi-threaded operating system, they\noften do not @b{in the interest of saving memory} waste these few\nbytes. Painful...\n\n\n@item @b{JTAG Reset Config} I get the following message in the OpenOCD console (or log file):\n\"Warning: arm7_9_common.c:679 arm7_9_assert_reset(): srst resets test logic, too\".\n\nThis warning doesn't indicate any serious problem, as long as you don't want to\ndebug your core right out of reset. Your .cfg file specified @option{reset_config\ntrst_and_srst srst_pulls_trst} to tell OpenOCD that either your board,\nyour debugger or your target uC (e.g. LPC2000) can't assert the two reset signals\nindependently. With this setup, it's not possible to halt the core right out of\nreset, everything else should work fine.\n\n@item @b{USB Power} When using OpenOCD in conjunction with Amontec JTAGkey and the Yagarto\ntoolchain (Eclipse, arm-elf-gcc, arm-elf-gdb), the debugging seems to be\nunstable. When single-stepping over large blocks of code, GDB and OpenOCD\nquit with an error message. Is there a stability issue with OpenOCD?\n\nNo, this is not a stability issue concerning OpenOCD. Most users have solved\nthis issue by simply using a self-powered USB hub, which they connect their\nAmontec JTAGkey to. Apparently, some computers do not provide a USB power\nsupply stable enough for the Amontec JTAGkey to be operated.\n\n@b{Laptops running on battery have this problem too...}\n\n@item @b{GDB Disconnects} When using the Amontec JTAGkey, sometimes OpenOCD crashes with the following\nerror message: \"Error: gdb_server.c:101 gdb_get_char(): read: 10054\".\nWhat does that mean and what might be the reason for this?\n\nError code 10054 corresponds to WSAECONNRESET, which means that the debugger (GDB)\nhas closed the connection to OpenOCD. This might be a GDB issue.\n\n@item @b{LPC2000 Flash} In the configuration file in the section where flash device configurations\nare described, there is a parameter for specifying the clock frequency\nfor LPC2000 internal flash devices (e.g. @option{flash bank $_FLASHNAME lpc2000\n0x0 0x40000 0 0 $_TARGETNAME lpc2000_v1 14746 calc_checksum}), which must be\nspecified in kilohertz. However, I do have a quartz crystal of a\nfrequency that contains fractions of kilohertz (e.g. 14,745,600 Hz,\ni.e. 14,745.600 kHz). Is it possible to specify real numbers for the\nclock frequency?\n\nNo. The clock frequency specified here must be given as an integral number.\nHowever, this clock frequency is used by the In-Application-Programming (IAP)\nroutines of the LPC2000 family only, which seems to be very tolerant concerning\nthe given clock frequency, so a slight difference between the specified clock\nfrequency and the actual clock frequency will not cause any trouble.\n\n@item @b{Command Order} Do I have to keep a specific order for the commands in the configuration file?\n\nWell, yes and no. Commands can be given in arbitrary order, yet the\ndevices listed for the JTAG scan chain must be given in the right\norder (jtag newdevice), with the device closest to the TDO-Pin being\nlisted first. In general, whenever objects of the same type exist\nwhich require an index number, then these objects must be given in the\nright order (jtag newtap, targets and flash banks - a target\nreferences a jtag newtap and a flash bank references a target).\n\nYou can use the ``scan_chain'' command to verify and display the tap order.\n\nAlso, some commands can't execute until after @command{init} has been\nprocessed. Such commands include @command{nand probe} and everything\nelse that needs to write to controller registers, perhaps for setting\nup DRAM and loading it with code.\n\n@anchor{faqtaporder}\n@item @b{JTAG TAP Order} Do I have to declare the TAPS in some\nparticular order?\n\nYes; whenever you have more than one, you must declare them in\nthe same order used by the hardware.\n\nMany newer devices have multiple JTAG TAPs. For example:\nSTMicroelectronics STM32 chips have two TAPs, a ``boundary scan TAP'' and\n``Cortex-M3'' TAP. Example: The STM32 reference manual, Document ID:\nRM0008, Section 26.5, Figure 259, page 651/681, the ``TDI'' pin is\nconnected to the boundary scan TAP, which then connects to the\nCortex-M3 TAP, which then connects to the TDO pin.\n\nThus, the proper order for the STM32 chip is: (1) The Cortex-M3, then\n(2) The boundary scan TAP. If your board includes an additional JTAG\nchip in the scan chain (for example a Xilinx CPLD or FPGA) you could\nplace it before or after the STM32 chip in the chain. For example:\n\n@itemize @bullet\n@item OpenOCD_TDI(output) -> STM32 TDI Pin (BS Input)\n@item STM32 BS TDO (output) -> STM32 Cortex-M3 TDI (input)\n@item STM32 Cortex-M3 TDO (output) -> SM32 TDO Pin\n@item STM32 TDO Pin (output) -> Xilinx TDI Pin (input)\n@item Xilinx TDO Pin -> OpenOCD TDO (input)\n@end itemize\n\nThe ``jtag device'' commands would thus be in the order shown below. Note:\n\n@itemize @bullet\n@item jtag newtap Xilinx tap -irlen ...\n@item jtag newtap stm32  cpu -irlen ...\n@item jtag newtap stm32  bs  -irlen ...\n@item # Create the debug target and say where it is\n@item target create stm32.cpu -chain-position stm32.cpu ...\n@end itemize\n\n\n@item @b{SYSCOMP} Sometimes my debugging session terminates with an error. When I look into the\nlog file, I can see these error messages: Error: arm7_9_common.c:561\narm7_9_execute_sys_speed(): timeout waiting for SYSCOMP\n\nTODO.\n\n@end enumerate\n\n@node Tcl Crash Course\n@chapter Tcl Crash Course\n@cindex Tcl\n\nNot everyone knows Tcl - this is not intended to be a replacement for\nlearning Tcl, the intent of this chapter is to give you some idea of\nhow the Tcl scripts work.\n\nThis chapter is written with two audiences in mind. (1) OpenOCD users\nwho need to understand a bit more of how Jim-Tcl works so they can do\nsomething useful, and (2) those that want to add a new command to\nOpenOCD.\n\n@section Tcl Rule #1\nThere is a famous joke, it goes like this:\n@enumerate\n@item Rule #1: The wife is always correct\n@item Rule #2: If you think otherwise, See Rule #1\n@end enumerate\n\nThe Tcl equal is this:\n\n@enumerate\n@item Rule #1: Everything is a string\n@item Rule #2: If you think otherwise, See Rule #1\n@end enumerate\n\nAs in the famous joke, the consequences of Rule #1 are profound. Once\nyou understand Rule #1, you will understand Tcl.\n\n@section Tcl Rule #1b\nThere is a second pair of rules.\n@enumerate\n@item Rule #1: Control flow does not exist. Only commands\n@* For example: the classic FOR loop or IF statement is not a control\nflow item, they are commands, there is no such thing as control flow\nin Tcl.\n@item Rule #2: If you think otherwise, See Rule #1\n@* Actually what happens is this: There are commands that by\nconvention, act like control flow key words in other languages. One of\nthose commands is the word ``for'', another command is ``if''.\n@end enumerate\n\n@section Per Rule #1 - All Results are strings\nEvery Tcl command results in a string. The word ``result'' is used\ndeliberately. No result is just an empty string. Remember: @i{Rule #1 -\nEverything is a string}\n\n@section Tcl Quoting Operators\nIn life of a Tcl script, there are two important periods of time, the\ndifference is subtle.\n@enumerate\n@item Parse Time\n@item Evaluation Time\n@end enumerate\n\nThe two key items here are how ``quoted things'' work in Tcl. Tcl has\nthree primary quoting constructs, the [square-brackets] the\n@{curly-braces@} and ``double-quotes''\n\nBy now you should know $VARIABLES always start with a $DOLLAR\nsign. BTW: To set a variable, you actually use the command ``set'', as\nin ``set VARNAME VALUE'' much like the ancient BASIC language ``let x\n= 1'' statement, but without the equal sign.\n\n@itemize @bullet\n@item @b{[square-brackets]}\n@* @b{[square-brackets]} are command substitutions. It operates much\nlike Unix Shell `back-ticks`. The result of a [square-bracket]\noperation is exactly 1 string. @i{Remember Rule #1 - Everything is a\nstring}. These two statements are roughly identical:\n@example\n    # bash example\n    X=`date`\n    echo \"The Date is: $X\"\n    # Tcl example\n    set X [date]\n    puts \"The Date is: $X\"\n@end example\n@item @b{``double-quoted-things''}\n@* @b{``double-quoted-things''} are just simply quoted\ntext. $VARIABLES and [square-brackets] are expanded in place - the\nresult however is exactly 1 string. @i{Remember Rule #1 - Everything\nis a string}\n@example\n    set x \"Dinner\"\n    puts \"It is now \\\"[date]\\\", $x is in 1 hour\"\n@end example\n@item @b{@{Curly-Braces@}}\n@*@b{@{Curly-Braces@}} are magic: $VARIABLES and [square-brackets] are\nparsed, but are NOT expanded or executed. @{Curly-Braces@} are like\n'single-quote' operators in BASH shell scripts, with the added\nfeature: @{curly-braces@} can be nested, single quotes can not. @{@{@{this is\nnested 3 times@}@}@} NOTE: [date] is a bad example;\nat this writing, Jim/OpenOCD does not have a date command.\n@end itemize\n\n@section Consequences of Rule 1/2/3/4\n\nThe consequences of Rule 1 are profound.\n\n@subsection Tokenisation & Execution.\n\nOf course, whitespace, blank lines and #comment lines are handled in\nthe normal way.\n\nAs a script is parsed, each (multi) line in the script file is\ntokenised and according to the quoting rules. After tokenisation, that\nline is immediately executed.\n\nMulti line statements end with one or more ``still-open''\n@{curly-braces@} which - eventually - closes a few lines later.\n\n@subsection Command Execution\n\nRemember earlier: There are no ``control flow''\nstatements in Tcl. Instead there are COMMANDS that simply act like\ncontrol flow operators.\n\nCommands are executed like this:\n\n@enumerate\n@item Parse the next line into (argc) and (argv[]).\n@item Look up (argv[0]) in a table and call its function.\n@item Repeat until End Of File.\n@end enumerate\n\nIt sort of works like this:\n@example\n    for(;;)@{\n        ReadAndParse( &argc, &argv );\n\n        cmdPtr = LookupCommand( argv[0] );\n\n        (*cmdPtr->Execute)( argc, argv );\n    @}\n@end example\n\nWhen the command ``proc'' is parsed (which creates a procedure\nfunction) it gets 3 parameters on the command line. @b{1} the name of\nthe proc (function), @b{2} the list of parameters, and @b{3} the body\nof the function. Note the choice of words: LIST and BODY. The PROC\ncommand stores these items in a table somewhere so it can be found by\n``LookupCommand()''\n\n@subsection The FOR command\n\nThe most interesting command to look at is the FOR command. In Tcl,\nthe FOR command is normally implemented in C. Remember, FOR is a\ncommand just like any other command.\n\nWhen the ascii text containing the FOR command is parsed, the parser\nproduces 5 parameter strings, @i{(If in doubt: Refer to Rule #1)} they\nare:\n\n@enumerate 0\n@item The ascii text 'for'\n@item The start text\n@item The test expression\n@item The next text\n@item The body text\n@end enumerate\n\nSort of reminds you of ``main( int argc, char **argv )'' does it not?\nRemember @i{Rule #1 - Everything is a string.} The key point is this:\nOften many of those parameters are in @{curly-braces@} - thus the\nvariables inside are not expanded or replaced until later.\n\nRemember that every Tcl command looks like the classic ``main( argc,\nargv )'' function in C. In JimTCL - they actually look like this:\n\n@example\nint\nMyCommand( Jim_Interp *interp,\n           int *argc,\n           Jim_Obj * const *argvs );\n@end example\n\nReal Tcl is nearly identical. Although the newer versions have\nintroduced a byte-code parser and interpreter, but at the core, it\nstill operates in the same basic way.\n\n@subsection FOR command implementation\n\nTo understand Tcl it is perhaps most helpful to see the FOR\ncommand. Remember, it is a COMMAND not a control flow structure.\n\nIn Tcl there are two underlying C helper functions.\n\nRemember Rule #1 - You are a string.\n\nThe @b{first} helper parses and executes commands found in an ascii\nstring. Commands can be separated by semicolons, or newlines. While\nparsing, variables are expanded via the quoting rules.\n\nThe @b{second} helper evaluates an ascii string as a numerical\nexpression and returns a value.\n\nHere is an example of how the @b{FOR} command could be\nimplemented. The pseudo code below does not show error handling.\n@example\nvoid Execute_AsciiString( void *interp, const char *string );\n\nint Evaluate_AsciiExpression( void *interp, const char *string );\n\nint\nMyForCommand( void *interp,\n              int argc,\n              char **argv )\n@{\n   if( argc != 5 )@{\n       SetResult( interp, \"WRONG number of parameters\");\n       return ERROR;\n   @}\n\n   // argv[0] = the ascii string just like C\n\n   // Execute the start statement.\n   Execute_AsciiString( interp, argv[1] );\n\n   // Top of loop test\n   for(;;)@{\n        i = Evaluate_AsciiExpression(interp, argv[2]);\n        if( i == 0 )\n            break;\n\n        // Execute the body\n        Execute_AsciiString( interp, argv[3] );\n\n        // Execute the LOOP part\n        Execute_AsciiString( interp, argv[4] );\n    @}\n\n    // Return no error\n    SetResult( interp, \"\" );\n    return SUCCESS;\n@}\n@end example\n\nEvery other command IF, WHILE, FORMAT, PUTS, EXPR, everything works\nin the same basic way.\n\n@section OpenOCD Tcl Usage\n\n@subsection source and find commands\n@b{Where:} In many configuration files\n@* Example: @b{ source [find FILENAME] }\n@*Remember the parsing rules\n@enumerate\n@item The @command{find} command is in square brackets,\nand is executed with the parameter FILENAME. It should find and return\nthe full path to a file with that name; it uses an internal search path.\nThe RESULT is a string, which is substituted into the command line in\nplace of the bracketed @command{find} command.\n(Don't try to use a FILENAME which includes the \"#\" character.\nThat character begins Tcl comments.)\n@item The @command{source} command is executed with the resulting filename;\nit reads a file and executes as a script.\n@end enumerate\n@subsection format command\n@b{Where:} Generally occurs in numerous places.\n@* Tcl has no command like @b{printf()}, instead it has @b{format}, which is really more like\n@b{sprintf()}.\n@b{Example}\n@example\n    set x 6\n    set y 7\n    puts [format \"The answer: %d\" [expr @{$x * $y@}]]\n@end example\n@enumerate\n@item The SET command creates 2 variables, X and Y.\n@item The double [nested] EXPR command performs math\n@* The EXPR command produces numerical result as a string.\n@* Refer to Rule #1\n@item The format command is executed, producing a single string\n@* Refer to Rule #1.\n@item The PUTS command outputs the text.\n@end enumerate\n@subsection Body or Inlined Text\n@b{Where:} Various TARGET scripts.\n@example\n#1 Good\n   proc someproc @{@} @{\n       ... multiple lines of stuff ...\n   @}\n   $_TARGETNAME configure -event FOO someproc\n#2 Good - no variables\n   $_TARGETNAME configure -event foo \"this ; that;\"\n#3 Good Curly Braces\n   $_TARGETNAME configure -event FOO @{\n        puts \"Time: [date]\"\n   @}\n#4 DANGER DANGER DANGER\n   $_TARGETNAME configure -event foo \"puts \\\"Time: [date]\\\"\"\n@end example\n@enumerate\n@item The $_TARGETNAME is an OpenOCD variable convention.\n@*@b{$_TARGETNAME} represents the last target created, the value changes\neach time a new target is created. Remember the parsing rules. When\nthe ascii text is parsed, the @b{$_TARGETNAME} becomes a simple string,\nthe name of the target which happens to be a TARGET (object)\ncommand.\n@item The 2nd parameter to the @option{-event} parameter is a TCBODY\n@*There are 4 examples:\n@enumerate\n@item The TCLBODY is a simple string that happens to be a proc name\n@item The TCLBODY is several simple commands separated by semicolons\n@item The TCLBODY is a multi-line @{curly-brace@} quoted string\n@item The TCLBODY is a string with variables that get expanded.\n@end enumerate\n\nIn the end, when the target event FOO occurs the TCLBODY is\nevaluated. Method @b{#1} and @b{#2} are functionally identical. For\nMethod @b{#3} and @b{#4} it is more interesting. What is the TCLBODY?\n\nRemember the parsing rules. In case #3, @{curly-braces@} mean the\n$VARS and [square-brackets] are expanded later, when the EVENT occurs,\nand the text is evaluated. In case #4, they are replaced before the\n``Target Object Command'' is executed. This occurs at the same time\n$_TARGETNAME is replaced. In case #4 the date will never\nchange. @{BTW: [date] is a bad example; at this writing,\nJim/OpenOCD does not have a date command@}\n@end enumerate\n@subsection Global Variables\n@b{Where:} You might discover this when writing your own procs @* In\nsimple terms: Inside a PROC, if you need to access a global variable\nyou must say so. See also ``upvar''. Example:\n@example\nproc myproc @{ @} @{\n     set y 0 #Local variable Y\n     global x #Global variable X\n     puts [format \"X=%d, Y=%d\" $x $y]\n@}\n@end example\n@section Other Tcl Hacks\n@b{Dynamic variable creation}\n@example\n# Dynamically create a bunch of variables.\nfor @{ set x 0 @} @{ $x < 32 @} @{ set x [expr @{$x + 1@}]@} @{\n    # Create var name\n    set vn [format \"BIT%d\" $x]\n    # Make it a global\n    global $vn\n    # Set it.\n    set $vn [expr @{1 << $x@}]\n@}\n@end example\n@b{Dynamic proc/command creation}\n@example\n# One \"X\" function - 5 uart functions.\nforeach who @{A B C D E@}\n   proc [format \"show_uart%c\" $who] @{ @} \"show_UARTx $who\"\n@}\n@end example\n\n@node License\n@appendix The GNU Free Documentation License.\n@include fdl.texi\n\n@node OpenOCD Concept Index\n@comment DO NOT use the plain word ``Index'', reason: CYGWIN filename\n@comment case issue with ``Index.html'' and ``index.html''\n@comment Occurs when creating ``--html --no-split'' output\n@comment This fix is based on: http://sourceware.org/ml/binutils/2006-05/msg00215.html\n@unnumbered OpenOCD Concept Index\n\n@printindex cp\n\n@node Command and Driver Index\n@unnumbered Command and Driver Index\n@printindex fn\n\n@bye\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/04b4_f155_cypress_kitprog3.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# KitProg3 Firmware 1.01\n# Has inconsistent class code 0 for CMSIS-DAP interface\n\nBus 002 Device 017: ID 04b4:f155 Cypress Semiconductor Corp.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2 ?\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0         8\n  idVendor           0x04b4 Cypress Semiconductor Corp.\n  idProduct          0xf155\n  bcdDevice            1.01\n  iManufacturer           1 Cypress Semiconductor\n  iProduct                6 KitProg3 CMSIS-DAP\n  iSerial               128 102015B003137400\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength          130\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration         11 KitProg3 CMSIS-DAP\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              400mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         0 (Defined at Interface level)\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              6 KitProg3 CMSIS-DAP\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0 No Subclass\n      bInterfaceProtocol      0 None\n      iInterface             12 KitProg3 bridge\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.11\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      43\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x07  EP 7 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         2\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       0 None\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface             15 KitProg3 USBUART\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x02\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        2\n        bSlaveInterface         3\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          3\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0008  1x 8 bytes\n        bInterval               2\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0 Unused\n      bInterfaceProtocol      0\n      iInterface              4 KitProg3 USBUART\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/0d28_0204_nxp_daplink.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: NXP FRDM-K64F\n\nBus 001 Device 006: ID 0d28:0204 NXP ARM mbed\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0d28 NXP\n  idProduct          0x0204 ARM mbed\n  bcdDevice           10.00\n  iManufacturer           1 ARM\n  iProduct                2 DAPLink CMSIS-DAP\n  iSerial                 3 0240000031754e45002f00199485002b6461000097969900\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0082\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              7 USB_MSC\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              6 CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.00\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      33\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               4 mbed Serial Port\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              4 mbed Serial Port\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x03\n          call management\n          use DataInterface\n        bDataInterface          2\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0010  1x 16 bytes\n        bInterval              32\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              5 mbed Serial Port\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/1a6a_2000_spansion_sk_fm4.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://en.opensuse.org/User:A_faerber/SK-FM4-176L-S6E2CC\n\nBus 002 Device 009: ID 1a6a:2000 Spansion Inc.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.01\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x1a6a Spansion Inc.\n  idProduct          0x2000\n  bcdDevice            1.60\n  iManufacturer           1 Spansion\n  iProduct                2 Spansion CMSIS-DAP + COM Port\n  iSerial                 0\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength          107\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x00\n      (Missing must-be-set bit!)\n      (Bus Powered)\n    MaxPower               62mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0 No Subclass\n      bInterfaceProtocol      0 None\n      iInterface              4 Spansion CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.11\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      29\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               5 Spansion USB Serial Port\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              0\n      CDC Header:\n        bcdCDC               10.01\n      CDC ACM:\n        bmCapabilities       0x00\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval             255\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0 Unused\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/2a86_8011_wch_link.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://github.com/pyocd/pyOCD/issues/1395\n\nBus 003 Device 118: ID 2a86:8011 wch.cn WCH-Link\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0         8\n  idVendor           0x2a86\n  idProduct          0x8011\n  bcdDevice            1.00\n  iManufacturer           1 wch.cn\n  iProduct                2 WCH-Link\n  iSerial                 3 0001A0000001\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x006b\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         0\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               4 QYF CMSIS-DAP\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      0\n      iInterface              4 QYF CMSIS-DAP\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          1\n      CDC ACM:\n        bmCapabilities       0x02\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        0\n        bSlaveInterface         1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               2\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              5 (error)\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              6 QYF CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.00\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      33\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/c251_2722_keil_ulink2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Standalone adapter\n\nBus 001 Device 010: ID c251:2722 Keil Software, Inc. Keil ULINK2 CMSIS-DAP\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0xc251 Keil Software, Inc.\n  idProduct          0x2722\n  bcdDevice            1.00\n  iManufacturer           1 Keil Software\n  iProduct                2 Keil ULINK2 CMSIS-DAP\n  iSerial                 3 V0022U9E\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0029\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              4 CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.00\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      33\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/c251_2723_keil_ulink_me.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://stackoverflow.com/questions/27087281/jtag-adapter-ulink-me-and-openocd-on-archlinux\n\nBus 005 Device 026: ID c251:2723 Keil Software, Inc.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0xc251 Keil Software, Inc.\n  idProduct          0x2723\n  bcdDevice            1.00\n  iManufacturer           1 Keil Software\n  iProduct                2 Keil ULINK-ME CMSIS-DAP\n  iSerial                 3 M0489MAE\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength           41\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0 No Subclass\n      bInterfaceProtocol      0 None\n      iInterface              4 CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.00\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      33\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/c251_2750_keil_ulinkplus.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# firmware 2.0.11\n\nBus 001 Device 005: ID c251:2750 Keil Software, Inc.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0xc251 Keil Software, Inc.\n  idProduct          0x2750\n  bcdDevice            1.00\n  iManufacturer           1 KEIL - Tools By ARM\n  iProduct                2 Keil ULINKplus\n  iSerial                 3 L78440715A\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength          101\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              4 ULINKplus CMSIS-DAP\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              5 ULINKplus Digital I/O\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              6 ULINKplus Analog I/O\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              7 ULINKplus Power Probe\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/cmsis_dap/c251_f001_jixin.pro.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://sourceforge.net/p/openocd/tickets/368/\n\nBus 001 Device 008: ID c251:f001 Keil Software, Inc.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2 ?\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0xc251 Keil Software, Inc.\n  idProduct          0xf001\n  bcdDevice            1.00\n  iManufacturer           1 jixin.pro\n  iProduct                2 CMSIS-DAP_LU\n  iSerial                 3 LU_2022_8888\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength          107\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         0\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               4 CMSIS-DAP CDC\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      0 None\n      iInterface              4 CMSIS-DAP CDC\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          1\n      CDC ACM:\n        bmCapabilities       0x02\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        0\n        bSlaveInterface         1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               2\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0 Unused\n      bInterfaceProtocol      0\n      iInterface              5 CMSIS-DAP DCI\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0 No Subclass\n      bInterfaceProtocol      0 None\n      iInterface              6 CMSIS-DAP_LU\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.00\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      33\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/dump.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\ndevs=$(lsusb -d $1:$2 | wc -l)\ncase \"$devs\" in\n\t0 )\n\t\techo \"Error: USB device $1:$2 not found\" > /dev/stderr\n\t\texit 1\n\t\t;;\n\t1 )\n\t\techo \"Dumping $(lsusb -d $1:$2)\" > /dev/stderr\n\t\t;;\n\t* )\n\t\techo \"Error: Multiple matches for 'lsusb -d $1:$2'\" > /dev/stderr\n\t\texit 1\n\t\t;;\nesac\n\n# break SPDX tag to hide it to checkpatch\necho '# SPDX-''License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later'\necho ''\necho '# Optional comment'\n\nlsusb -v -d $1:$2 | sed 's/ *$//'\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/esp_usb_jtag/303a_1001_esp_usb_jtag.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Optional comment\n\nBus 002 Device 035: ID 303a:1001\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x303a\n  idProduct          0x1001\n  bcdDevice            1.01\n  iManufacturer           1 Espressif\n  iProduct                2 USB JTAG/serial debug unit\n  iSerial                 3 7C:DF:A1:A2:8F:38\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0062\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0xc0\n      Self Powered\n    MaxPower              500mA\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         0\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       0\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      0\n      iInterface              0\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x02\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        0\n        bSlaveInterface         1\n      CDC Call Management:\n        bmCapabilities       0x03\n          call management\n          use DataInterface\n        bDataInterface          1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      2\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol      1\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\nDevice Status:     0x0001\n  Self Powered\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ft232r/0403_6001_ft232r.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: FT232RL\n# Chip: FT232RL\n\nBus 001 Device 005: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0         8\n  idVendor           0x0403 Future Technology Devices International, Ltd\n  idProduct          0x6001 FT232 Serial (UART) IC\n  bcdDevice            6.00\n  iManufacturer           1 FTDI\n  iProduct                2 FT232R USB UART\n  iSerial                 3 A50285BI\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0xa0\n      (Bus Powered)\n      Remote Wakeup\n    MaxPower               90mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 FT232R USB UART\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ftdi/0403_6010_ft2232h.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: Steppenprobe\n# Link: https://github.com/diegoherranz/steppenprobe\n# Chip: FT2232HL\n\nBus 001 Device 012: ID 0403:6010 Future Technology Devices International, Ltd FT2232C/D/H Dual UART/FIFO IC\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0403 Future Technology Devices International, Ltd\n  idProduct          0x6010 FT2232C/D/H Dual UART/FIFO IC\n  bcdDevice            7.00\n  iManufacturer           1 FTDI\n  iProduct                2 Dual RS232-HS\n  iSerial                 0\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0037\n    bNumInterfaces          2\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 Dual RS232-HS\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 Dual RS232-HS\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ftdi/0403_6014_digilent_hs2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://sourceforge.net/p/openocd/tickets/357/\n\nBus 001 Device 084: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0403 Future Technology Devices International, Ltd\n  idProduct          0x6014 FT232H Single HS USB-UART/FIFO IC\n  bcdDevice            9.00\n  iManufacturer           1 Digilent\n  iProduct                2 Digilent USB Device\n  iSerial                 3 210249AFCD0B\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 Digilent USB Device\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ftdi/0403_cff8_amontec_jtagkey2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Link: http://www.amontec.com\n# Casing: Hi-Speed JTAGkey-2 (c) 2009, Amontec\n# PCB: Amontec JTAGkey2 v5.3\n# Chip: FT2232HQ\n\nBus 001 Device 017: ID 0403:cff8 Future Technology Devices International, Ltd Amontec JTAGkey\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0403 Future Technology Devices International, Ltd\n  idProduct          0xcff8 Amontec JTAGkey\n  bcdDevice            7.00\n  iManufacturer           1 Amontec\n  iProduct                2 Amontec JTAGkey-2\n  iSerial                 3 53U2ML49\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0037\n    bNumInterfaces          2\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 Amontec JTAGkey-2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 Amontec JTAGkey-2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ftdi/09fb_6001_altera_blaster.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Clone www.terasic.com \"USB Blaster\"\n# PCB reports: \"USB Blaster-B\", \"FOR ALTERA ONLY\"\n# Chip: FT245BL\n\nBus 001 Device 005: ID 09fb:6001 Altera Blaster\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.10\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0         8\n  idVendor           0x09fb Altera\n  idProduct          0x6001 Blaster\n  bcdDevice            4.00\n  iManufacturer           1 Altera\n  iProduct                2 USB-Blaster\n  iSerial                 3 91f28492\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              150mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 USB-Blaster\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/ftdi/9e88_9e8f_sheevaplug_jtagkey.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=837989\n\nBus 003 Device 002: ID 9e88:9e8f\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0         8\n  idVendor           0x9e88\n  idProduct          0x9e8f\n  bcdDevice            5.00\n  iManufacturer           1 FTDI\n  iProduct                2 SheevaPlug JTAGKey FT2232D B\n  iSerial                 3 FTU85Z4Y\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength           55\n    bNumInterfaces          2\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0xc0\n      Self Powered\n    MaxPower                0mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 SheevaPlug JTAGKey FT2232D B\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              2 SheevaPlug JTAGKey FT2232D B\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/icdi/1cbe_00fd_ti_icdi.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: TI Tiva C Series TM4C1294 Connected LaunchPad\n# ICDI firmware update to add OpenOCD support\n\nBus 001 Device 016: ID 1cbe:00fd Luminary Micro Inc. In-Circuit Debug Interface\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.10\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x1cbe Luminary Micro Inc.\n  idProduct          0x00fd In-Circuit Debug Interface\n  bcdDevice            1.00\n  iManufacturer           1 Texas Instruments\n  iProduct                2 In-Circuit Debug Interface\n  iSerial                 3 0F00CAC2\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0074\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              250mA\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         0\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              0\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        0\n        bSlaveInterface         1\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0010  1x 16 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           0\n      bInterfaceClass       254 Application Specific Interface\n      bInterfaceSubClass      1 Device Firmware Update\n      bInterfaceProtocol      1\n      iInterface              0\n      Device Firmware Upgrade Interface Descriptor:\n        bLength                             9\n        bDescriptorType                    33\n        bmAttributes                       15\n          Will Detach\n          Manifestation Tolerant\n          Upload Supported\n          Download Supported\n        wDetachTimeout                  65535 milliseconds\n        wTransferSize                    1024 bytes\n        bcdDFUVersion                   1.10\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/jlink/1366_0101_segger_jlink.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in https://forums.gentoo.org/viewtopic-t-781442-start-0.html\n\nBus 002 Device 002: ID 1366:0101\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.10\n  bDeviceClass            0 (Defined at Interface level)\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0         8\n  idVendor           0x1366\n  idProduct          0x0101\n  bcdDevice            0.01\n  iManufacturer           1 SEGGER\n  iProduct                2 J-Link\n  iSerial                 3 123456\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength           32\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0xc0\n      Self Powered\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0001\n  Self Powered\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/jlink/1366_0101_segger_jlink_plus_10_1.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Standalone adapter, original Segger, HW version 10.1\n\nBus 001 Device 005: ID 1366:0101 SEGGER J-Link PLUS\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x1366 SEGGER\n  idProduct          0x0101 J-Link PLUS\n  bcdDevice            1.00\n  iManufacturer           1 SEGGER\n  iProduct                2 J-Link\n  iSerial                 3 123456\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          4 Configuration\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 BULK interface\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               1\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/kitprog/04b4_f139_cypress_kitprog.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Reported in http://false.ekta.is/tag/unboxing/\n\nBus 003 Device 011: ID 04b4:f139 Cypress Semiconductor Corp.\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2 ?\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0         8\n  idVendor           0x04b4 Cypress Semiconductor Corp.\n  idProduct          0xf139\n  bcdDevice            2.0b\n  iManufacturer           1 Cypress Semiconductor\n  iProduct                2 Cypress KitProg\n  iSerial               128 1C210338012E4400\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength          130\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          2 Cypress KitProg\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              400mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0 No Subclass\n      bInterfaceProtocol      0 None\n      iInterface              3 KitBridge\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.11\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      43\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              5 KitProg Programmer\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         2\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       0\n      bFunctionProtocol       0\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      0 None\n      iInterface              4 KitProg USBUART\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x02\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        2\n        bSlaveInterface         1\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0008  1x 8 bytes\n        bInterval               2\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0 Unused\n      bInterfaceProtocol      0\n      iInterface              4 KitProg USBUART\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x07  EP 7 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/nulink/0416_511d_nuvoton_nulink.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: nuvoTon NuMaker-PFM-M2351\n# Adapter: ICE V3.0\n\nBus 001 Device 013: ID 0416:511d Winbond Electronics Corp. Nuvoton Nu-Link1 ICE/VCOM\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.10\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0416 Winbond Electronics Corp.\n  idProduct          0x511d Nuvoton Nu-Link1 ICE/VCOM\n  bcdDevice            1.00\n  iManufacturer           1 Nuvoton\n  iProduct                2 Nu-Link\n  iSerial                 0\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x006b\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.10\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      28\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               2 Nu-Link\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              0\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          1\n      CDC ACM:\n        bmCapabilities       0x00\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0008  1x 8 bytes\n        bInterval             255\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/nulink/0416_5200_nuvoton_nulink.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: nuvoTon NuMaker-M483KG V1.1\n# Adapter: Nu-Link2-Me V1.0\n\nBus 001 Device 014: ID 0416:5200 Winbond Electronics Corp. Nuvoton Nu-Link2-ME ICE/MSC/VCOM\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0416 Winbond Electronics Corp.\n  idProduct          0x5200 Nuvoton Nu-Link2-ME ICE/MSC/VCOM\n  bcdDevice            0.00\n  iManufacturer           1 Nuvoton\n  iProduct                2 Nu-Link2 Bulk\n  iSerial                 6 13010000AAAAAAAAAAAAAAAAAAAAAAAA\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0099\n    bNumInterfaces          5\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              3 Nu-Link2 VCOM\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          1\n      CDC ACM:\n        bmCapabilities       0x00\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0100  1x 256 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0100  1x 256 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              4 Nu-Link2 HID\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.10\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      35\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0400  1x 1024 bytes\n        bInterval               4\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x07  EP 7 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0400  1x 1024 bytes\n        bInterval               4\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        4\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              5 Nu-Link2 MSC\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x88  EP 8 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x09  EP 9 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/readme.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\nThis folder contains a collection of dumps of USB descriptors, obtained through\nLinux lsusb command, of several USB adapters supported by OpenOCD.\nThis collection should help maintaining adapter drivers even if the developer\ndoesn't have access to all the devices supported by the driver.\n\nTo add a new file, run:\n\n\t./doc/usb_adapters/dump.sh ${vid} ${pid} \\\n\t\t> doc/usb_adapters/${driver}/${vid}_${pid}_${short_description}.txt\n\neventually edit the file to add some extra comment, then submit the file to\nOpenOCD gerrit, as explained in HACKING.\n\nThe dumps are organized in subfolders corresponding to OpenOCD drivers:\n- cmsis_dap;\n- esp_usb_jtag;\n- ft232r;\n- ftdi;\n- icdi;\n- jlink;\n- kitprog;\n- nulink;\n- stlink;\n- xds110.\n\nThe script above assumes the user has granted access permissions to the USB\ndevice file in\n\t/dev/bus/usb/<n>/<m>\nThis is usually the case when the device is listed in\n\tcontrib/60-openocd.rules\nand this udev rules file is properly installed in the host machine.\nIf the user has no proper access permissions, the script has to be run as\nroot or through 'sudo'.\n\nOld versions of 'lsusb -v' dump cryptic errors like:\n\tcan't get device qualifier: Resource temporarily unavailable\n\tcan't get debug descriptor: Resource temporarily unavailable\nwhen some optional descriptor is not present.\nThis is fixed in usbutils v014.\nIf you get such messages simply ignore them. They are printed on stderr, so\nwill not be included in the generated file as the redirection '>' does only\nredirects stdout.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3744_stlinkv1.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Standalone adapter\n\nBus 001 Device 009: ID 0483:3744 STMicroelectronics ST-LINK/V1\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3744 ST-LINK/V1\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STM32 STLink\n  iSerial                 3 0000001\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              4 ST Link\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3748_stlinkv2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# ST-Link/V2 standalone or ST-Link/V2 in firmware update mode\n\nBus 001 Device 006: ID 0483:3748 STMicroelectronics ST-LINK/V2\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3748 ST-LINK/V2\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STM32 STLink\n  iSerial                 3 0668FF323637414257071827\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0027\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              4 ST Link\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_374b_stlinkv2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: ST Nucleo F411\n\nBus 001 Device 007: ID 0483:374b STMicroelectronics ST-LINK/V2.1\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x374b ST-LINK/V2.1\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STM32 STLink\n  iSerial                 3 066EFF373535503457062922\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0080\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              4 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0020  1x 32 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              5 ST-Link mass storage\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         2\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               6 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              6 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          3\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        2\n        bSlaveInterface         3\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0002  1x 2 bytes\n        bInterval             255\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              7 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0008  1x 8 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0010  1x 16 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_374d_stlinkv3.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# ST-Link/V3 in firmware update mode\n\nBus 001 Device 009: ID 0483:374d STMicroelectronics STLINK-V3 Loader\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x374d STLINK-V3 Loader\n  bcdDevice            2.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STM32 ST-LINK/V3\n  iSerial                 3 003500463137510239383538\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          4 DFU Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-LINK/V3\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0001\n  Self Powered\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_374e_stlinkv3.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: ST Nucleo-H745AI-Q\n\nBus 001 Device 008: ID 0483:374e STMicroelectronics STLINK-V3\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x374e STLINK-V3\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STLINK-V3\n  iSerial                 3 005100313137511039383538\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0080\n    bNumInterfaces          4\n    bConfigurationValue     1\n    iConfiguration          4 Default Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              6 ST-Link mass storage\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         2\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               7 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              7 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          3\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        2\n        bSlaveInterface         3\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              8 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_374f_stlinkv3.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Standalone adapter\n\nBus 001 Device 008: ID 0483:374f STMicroelectronics STLINK-V3\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x374f STLINK-V3\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STLINK-V3\n  iSerial                 3 003500463137510239383538\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0097\n    bNumInterfaces          5\n    bConfigurationValue     1\n    iConfiguration          4 Default Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         8 Mass Storage\n      bInterfaceSubClass      6 SCSI\n      bInterfaceProtocol     80 Bulk-Only\n      iInterface              6 ST-Link mass storage\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         2\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               7 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              7 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          3\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        2\n        bSlaveInterface         3\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              8 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        4\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              9 ST-Link Bridge\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x06  EP 6 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3752_stlinkv2.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: ST STM32MP157f-DK2\n\nBus 001 Device 005: ID 0483:3752 STMicroelectronics ST-LINK/V2.1\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3752 ST-LINK/V2.1\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STM32 STLink\n  iSerial                 3 0668FF323637414257071827\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0069\n    bNumInterfaces          3\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              300mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              4 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0020  1x 32 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               6 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              6 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          2\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0008  1x 8 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              7 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3753_stlinkv3.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board STM32MP135F-DK\n\nBus 001 Device 011: ID 0483:3753 STMicroelectronics STLINK-V3\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3753 STLINK-V3\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STLINK-V3\n  iSerial                 3 001000294741500120383733\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x00c2\n    bNumInterfaces          6\n    bConfigurationValue     1\n    iConfiguration          4 Default Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              300mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               7 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              7 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          2\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              8 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              9 ST-Link Bridge\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x06  EP 6 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         4\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction              10 ST-Link VCP2 Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        4\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface             10 ST-Link VCP2 Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          5\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        4\n        bSlaveInterface         5\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        5\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface             11 ST-Link VCP2 Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x07  EP 7 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x87  EP 7 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3755_stlinkv3pwr.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# STLINK-V3PWR standalone in firmware update mode\n\nBus 003 Device 054: ID 0483:3755 STMicroelectronics USB2.0 Hub\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3755\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STLINK-V3PWR\n  iSerial                 3 123456780000\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x0020\n    bNumInterfaces          1\n    bConfigurationValue     1\n    iConfiguration          4 DFU Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              100mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-Link Usbloader\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/stlink/0483_3757_stlinkv3pwr.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# STLINK-V3PWR standalone\n\nBus 003 Device 053: ID 0483:3757 STMicroelectronics USB2.0 Hub\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               2.00\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0483 STMicroelectronics\n  idProduct          0x3757\n  bcdDevice            1.00\n  iManufacturer           1 STMicroelectronics\n  iProduct                2 STLINK-V3PWR\n  iSerial                 3 123456780000\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x00c2\n    bNumInterfaces          6\n    bConfigurationValue     1\n    iConfiguration          4 Default Config\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           3\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              5 ST-Link Debug\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         1\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               6 ST-Link VCP Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              6 ST-Link VCP Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          2\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        1\n        bSlaveInterface         2\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              7 ST-Link VCP Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass    255 Vendor Specific Subclass\n      bInterfaceProtocol    255 Vendor Specific Protocol\n      iInterface              8 ST-Link Bridge\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x06  EP 6 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         4\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               9 ST-Link VCP-PWR Ctrl\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        4\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              9 ST-Link VCP-PWR Ctrl\n      CDC Header:\n        bcdCDC               1.10\n      CDC Call Management:\n        bmCapabilities       0x00\n        bDataInterface          5\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        4\n        bSlaveInterface         5\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x87  EP 7 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x000a  1x 10 bytes\n        bInterval              16\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        5\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface             10 ST-Link VCP-PWR Data\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0200  1x 512 bytes\n        bInterval               0\nDevice Qualifier (for other device speed):\n  bLength                10\n  bDescriptorType         6\n  bcdUSB               2.00\n  bDeviceClass            0\n  bDeviceSubClass         0\n  bDeviceProtocol         0\n  bMaxPacketSize0        64\n  bNumConfigurations      1\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/doc/usb_adapters/xds110/0451_0451_ti_xds110.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later OR GFDL-1.2-no-invariants-or-later\n\n# Board: TI CC2650 LaunchPad\n\nBus 001 Device 005: ID 0451:bef3 Texas Instruments, Inc. CC1352R1 Launchpad\nDevice Descriptor:\n  bLength                18\n  bDescriptorType         1\n  bcdUSB               1.10\n  bDeviceClass          239 Miscellaneous Device\n  bDeviceSubClass         2\n  bDeviceProtocol         1 Interface Association\n  bMaxPacketSize0        64\n  idVendor           0x0451 Texas Instruments, Inc.\n  idProduct          0xbef3 CC1352R1 Launchpad\n  bcdDevice            1.00\n  iManufacturer           1 Texas Instruments\n  iProduct                2 XDS110 (03.00.00.13) Embed with CMSIS-DAP\n  iSerial                 3 L1002566\n  bNumConfigurations      1\n  Configuration Descriptor:\n    bLength                 9\n    bDescriptorType         2\n    wTotalLength       0x00db\n    bNumInterfaces          7\n    bConfigurationValue     1\n    iConfiguration          0\n    bmAttributes         0x80\n      (Bus Powered)\n    MaxPower              500mA\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         0\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        0\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              0\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        0\n        bSlaveInterface         1\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x81  EP 1 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0010  1x 16 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        1\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x82  EP 2 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x01  EP 1 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        2\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x02  EP 2 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x83  EP 3 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Association:\n      bLength                 8\n      bDescriptorType        11\n      bFirstInterface         3\n      bInterfaceCount         2\n      bFunctionClass          2 Communications\n      bFunctionSubClass       2 Abstract (modem)\n      bFunctionProtocol       1 AT-commands (v.25ter)\n      iFunction               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        3\n      bAlternateSetting       0\n      bNumEndpoints           1\n      bInterfaceClass         2 Communications\n      bInterfaceSubClass      2 Abstract (modem)\n      bInterfaceProtocol      1 AT-commands (v.25ter)\n      iInterface              0\n      CDC Header:\n        bcdCDC               1.10\n      CDC ACM:\n        bmCapabilities       0x06\n          sends break\n          line coding and serial state\n      CDC Union:\n        bMasterInterface        3\n        bSlaveInterface         4\n      CDC Call Management:\n        bmCapabilities       0x01\n          call management\n        bDataInterface          4\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x84  EP 4 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0010  1x 16 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        4\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass        10 CDC Data\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x85  EP 5 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x03  EP 3 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        5\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass         3 Human Interface Device\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              6 XDS110 CMSIS-DAP\n        HID Device Descriptor:\n          bLength                 9\n          bDescriptorType        33\n          bcdHID               1.11\n          bCountryCode            0 Not supported\n          bNumDescriptors         1\n          bDescriptorType        34 Report\n          wDescriptorLength      24\n         Report Descriptors:\n           ** UNAVAILABLE **\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x86  EP 6 IN\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x04  EP 4 OUT\n        bmAttributes            3\n          Transfer Type            Interrupt\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               1\n    Interface Descriptor:\n      bLength                 9\n      bDescriptorType         4\n      bInterfaceNumber        6\n      bAlternateSetting       0\n      bNumEndpoints           2\n      bInterfaceClass       255 Vendor Specific Class\n      bInterfaceSubClass      0\n      bInterfaceProtocol      0\n      iInterface              0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x05  EP 5 OUT\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\n      Endpoint Descriptor:\n        bLength                 7\n        bDescriptorType         5\n        bEndpointAddress     0x87  EP 7 IN\n        bmAttributes            2\n          Transfer Type            Bulk\n          Synch Type               None\n          Usage Type               Data\n        wMaxPacketSize     0x0040  1x 64 bytes\n        bInterval               0\nDevice Status:     0x0000\n  (Bus Powered)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/guess-rev.sh",
    "content": "#!/bin/sh\n#\n# This scripts adds local version information from the version\n# control systems git, mercurial (hg) and subversion (svn).\n#\n# Copied from Linux 2.6.32 scripts/setlocalversion and modified\n# slightly to work better for OpenOCD.\n#\n\nusage() {\n\techo \"Usage: $0 [srctree]\" >&2\n\texit 1\n}\n\ncd \"${1:-.}\" || usage\n\n# Check for git and a git repo.\nif head=`git rev-parse --verify --short HEAD 2>/dev/null`; then\n\n\t# If we are at a tagged commit (like \"v2.6.30-rc6\"), we ignore it,\n\t# because this version is defined in the top level Makefile.\n\tif [ -z \"`git describe --exact-match 2>/dev/null`\" ]; then\n\n\t\t# If we are past a tagged commit (like \"v2.6.30-rc5-302-g72357d5\"),\n\t\t# we pretty print it.\n\t\tif atag=\"`git describe 2>/dev/null`\"; then\n\t\t\techo \"$atag\" | awk -F- '{printf(\"-%05d-%s\", $(NF-1),$(NF))}'\n\n\t\t# If we don't have a tag at all we print -g{commitish}.\n\t\telse\n\t\t\tprintf '%s%s' -g $head\n\t\tfi\n\tfi\n\n\t# Is this git on svn?\n\tif git config --get svn-remote.svn.url >/dev/null; then\n\t        printf -- '-svn%s' \"`git svn find-rev $head`\"\n\tfi\n\n\t# Update index only on r/w media\n\t[ -w . ] && git update-index --refresh --unmerged > /dev/null\n\n\t# Check for uncommitted changes\n\tif git diff-index --name-only HEAD | grep -v \"^scripts/package\" \\\n\t    | read dummy; then\n\t\tprintf '%s' -dirty\n\tfi\n\n\t# All done with git\n\texit\nfi\n\n# Check for mercurial and a mercurial repo.\nif hgid=`hg id 2>/dev/null`; then\n\ttag=`printf '%s' \"$hgid\" | cut -d' ' -f2`\n\n\t# Do we have an untagged version?\n\tif [ -z \"$tag\" -o \"$tag\" = tip ]; then\n\t\tid=`printf '%s' \"$hgid\" | sed 's/[+ ].*//'`\n\t\tprintf '%s%s' -hg \"$id\"\n\tfi\n\n\t# Are there uncommitted changes?\n\t# These are represented by + after the changeset id.\n\tcase \"$hgid\" in\n\t\t*+|*+\\ *) printf '%s' -dirty ;;\n\tesac\n\n\t# All done with mercurial\n\texit\nfi\n\n# Check for svn and a svn repo.\nif rev=`svn info 2>/dev/null | grep '^Last Changed Rev'`; then\n\trev=`echo $rev | awk '{print $NF}'`\n\tprintf -- '-svn%s' \"$rev\"\n\n\t# All done with svn\n\texit\nfi\n\n# There's no recognized repository; we must be a snapshot.\nprintf -- '-snapshot'\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libopenocd.la\nbin_PROGRAMS += %D%/openocd\n\n%C%_openocd_SOURCES = \\\n\t%D%/main.c\n\n%C%_libopenocd_la_SOURCES = \\\n\t%D%/hello.c %D%/hello.h \\\n\t%D%/openocd.c %D%/openocd.h\n\n%C%_openocd_LDADD = %D%/libopenocd.la\n\n%C%_openocd_LDADD += $(MINGWLDADD)\n\nif INTERNAL_JIMTCL\n%C%_openocd_LDADD += $(top_builddir)/jimtcl/libjim.a\nelse\n%C%_openocd_LDADD += -ljim\nendif\n\n%C%_libopenocd_la_CPPFLAGS =\n\n# banner output includes RELSTR appended to $VERSION from the configure script\n# guess-rev.sh returns either a repository version ID or \"-snapshot\"\nif RELEASE\n%C%_libopenocd_la_CPPFLAGS += -DRELSTR=\\\"\\\"\n%C%_libopenocd_la_CPPFLAGS += -DGITVERSION=\\\"\\\"\nelse\n%C%_libopenocd_la_CPPFLAGS += -DRELSTR=\\\"`$(top_srcdir)/guess-rev.sh $(top_srcdir)`\\\"\n%C%_libopenocd_la_CPPFLAGS += -DGITVERSION=\\\"`cd $(top_srcdir) && git describe`\\\"\n%C%_libopenocd_la_CPPFLAGS += -DPKGBLDDATE=\\\"`date +%F-%R`\\\"\nendif\n\n# add default CPPFLAGS\n%C%_libopenocd_la_CPPFLAGS += $(AM_CPPFLAGS) $(CPPFLAGS)\n\n# the library search path.\n%C%_libopenocd_la_LDFLAGS = $(all_libraries)\n\nif IS_MINGW\nMINGWLDADD = -lws2_32\nelse\nMINGWLDADD =\nendif\n\n%C%_libopenocd_la_LIBADD = \\\n\t%D%/xsvf/libxsvf.la \\\n\t%D%/svf/libsvf.la \\\n\t%D%/pld/libpld.la \\\n\t%D%/jtag/libjtag.la \\\n\t%D%/transport/libtransport.la \\\n\t%D%/flash/libflash.la \\\n\t%D%/target/libtarget.la \\\n\t%D%/server/libserver.la \\\n\t%D%/rtos/librtos.la \\\n\t%D%/helper/libhelper.la \\\n\t%D%/rtt/librtt.la\n\nBIN2C = $(srcdir)/%D%/helper/bin2char.sh\n\nSTARTUP_TCL_SRCS =\nEXTRA_DIST += $(STARTUP_TCL_SRCS)\n\nBUILT_SOURCES += %D%/startup_tcl.inc\n\n# Convert .tcl to c-array\n%D%/startup_tcl.inc: $(STARTUP_TCL_SRCS)\n\tmkdir -p %D%\n\tcat $^ | $(BIN2C) > $@ || { rm -f $@; false; }\n\n# add generated files to make clean list\nCLEANFILES += %D%/startup_tcl.inc\n\n# we do not want generated file in the dist\n#dist-hook:\n#\trm -f $(distdir)/%D%/startup_tcl.inc\n\ninclude %D%/helper/Makefile.am\ninclude %D%/jtag/Makefile.am\ninclude %D%/transport/Makefile.am\ninclude %D%/xsvf/Makefile.am\ninclude %D%/svf/Makefile.am\ninclude %D%/target/Makefile.am\ninclude %D%/rtos/Makefile.am\ninclude %D%/server/Makefile.am\ninclude %D%/flash/Makefile.am\ninclude %D%/pld/Makefile.am\ninclude %D%/rtt/Makefile.am\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libflash.la\n%C%_libflash_la_SOURCES = \\\n\t%D%/common.c %D%/common.h\n\n%C%_libflash_la_LIBADD = \\\n\t%D%/nor/libocdflashnor.la \\\n\t%D%/nand/libocdflashnand.la\n\nSTARTUP_TCL_SRCS += %D%/startup.tcl\n\ninclude %D%/nor/Makefile.am\ninclude %D%/nand/Makefile.am\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/common.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"common.h\"\n#include <helper/log.h>\n\nunsigned get_flash_name_index(const char *name)\n{\n\tconst char *name_index = strrchr(name, '.');\n\tif (!name_index)\n\t\treturn 0;\n\tif (name_index[1] < '0' || name_index[1] > '9')\n\t\treturn ~0U;\n\tunsigned requested;\n\tint retval = parse_uint(name_index + 1, &requested);\n\t/* detect parsing error by forcing past end of bank list */\n\treturn (retval == ERROR_OK) ? requested : ~0U;\n}\n\nbool flash_driver_name_matches(const char *name, const char *expected)\n{\n\tunsigned blen = strlen(name);\n\t/* only match up to the length of the driver name... */\n\tif (strncmp(name, expected, blen) != 0)\n\t\treturn false;\n\n\t/* ...then check that name terminates at this spot. */\n\treturn expected[blen] == '.' || expected[blen] == '\\0';\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/common.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_COMMON_H\n#define OPENOCD_FLASH_COMMON_H\n\n#include <helper/log.h>\n#include <helper/replacements.h>\n\n/**\n * Parses the optional '.index' portion of a flash bank identifier.\n * @param name The desired driver name, passed by the user.\n * @returns The parsed index request, or 0 if not present.  If the\n * name provides a suffix but it does not parse as an unsigned integer,\n * the routine returns ~0U.  This will prevent further matching.\n */\nunsigned get_flash_name_index(const char *name);\n/**\n * Attempt to match the @c expected name with the @c name of a driver.\n * @param name The name of the driver (from the bank's device structure).\n * @param expected The expected driver name, passed by the user.\n */\nbool flash_driver_name_matches(const char *name, const char *expected);\n\n#define ERROR_FLASH_BANK_INVALID\t\t\t(-900)\n#define ERROR_FLASH_SECTOR_INVALID\t\t\t(-901)\n#define ERROR_FLASH_OPERATION_FAILED\t\t(-902)\n#define ERROR_FLASH_DST_OUT_OF_BANK\t\t\t(-903)\n#define ERROR_FLASH_DST_BREAKS_ALIGNMENT\t(-904)\n#define ERROR_FLASH_BUSY\t\t\t\t\t(-905)\n#define ERROR_FLASH_SECTOR_NOT_ERASED\t\t(-906)\n#define ERROR_FLASH_BANK_NOT_PROBED\t\t\t(-907)\n#define ERROR_FLASH_OPER_UNSUPPORTED\t\t(-908)\n#define ERROR_FLASH_PROTECTED\t\t\t(-909)\n\n#endif /* OPENOCD_FLASH_COMMON_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libocdflashnand.la\n\n%C%_libocdflashnand_la_SOURCES = \\\n\t%D%/ecc.c \\\n\t%D%/ecc_kw.c \\\n\t%D%/core.c \\\n\t%D%/fileio.c \\\n\t%D%/tcl.c \\\n\t%D%/arm_io.c \\\n\t$(NAND_DRIVERS) \\\n\t%D%/driver.c \\\n\t$(NANDHEADERS)\n\nNAND_DRIVERS = \\\n\t%D%/nonce.c \\\n\t%D%/davinci.c \\\n\t%D%/lpc3180.c \\\n\t%D%/lpc32xx.c \\\n\t%D%/mxc.c \\\n\t%D%/mx3.c \\\n\t%D%/orion.c \\\n\t%D%/s3c24xx.c \\\n\t%D%/s3c2410.c \\\n\t%D%/s3c2412.c \\\n\t%D%/s3c2440.c \\\n\t%D%/s3c2443.c \\\n\t%D%/s3c6400.c \\\n\t%D%/at91sam9.c \\\n\t%D%/nuc910.c\n\nNANDHEADERS = \\\n\t%D%/arm_io.h \\\n\t%D%/core.h \\\n\t%D%/driver.h \\\n\t%D%/fileio.h \\\n\t%D%/imp.h \\\n\t%D%/lpc3180.h \\\n\t%D%/lpc32xx.h \\\n\t%D%/mxc.h \\\n\t%D%/mx3.h \\\n\t%D%/s3c24xx.h \\\n\t%D%/s3c24xx_regs.h \\\n\t%D%/nuc910.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/arm_io.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2009 by Marvell Semiconductors, Inc.\n * Written by Nicolas Pitre <nico at marvell.com>\n *\n * Copyright (C) 2009 by David Brownell\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"core.h\"\n#include \"arm_io.h\"\n#include <helper/binarybuffer.h>\n#include <target/arm.h>\n#include <target/armv7m.h>\n#include <target/algorithm.h>\n\n/**\n * Copies code to a working area.  This will allocate room for the code plus the\n * additional amount requested if the working area pointer is null.\n *\n * @param target Pointer to the target to copy code to\n * @param code Pointer to the code area to be copied\n * @param code_size Size of the code being copied\n * @param additional Size of the additional area to be allocated in addition to\n *                   code\n * @param area Pointer to a pointer to a working area to copy code to\n * @return Success or failure of the operation\n */\nstatic int arm_code_to_working_area(struct target *target,\n\tconst uint32_t *code, unsigned code_size,\n\tunsigned additional, struct working_area **area)\n{\n\tuint8_t code_buf[code_size];\n\tint retval;\n\tunsigned size = code_size + additional;\n\n\t/* REVISIT this assumes size doesn't ever change.\n\t * That's usually correct; but there are boards with\n\t * both large and small page chips, where it won't be...\n\t */\n\n\t/* make sure we have a working area */\n\tif (!*area) {\n\t\tretval = target_alloc_working_area(target, size, area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"%s: no %d byte buffer\", __func__, (int) size);\n\t\t\treturn ERROR_NAND_NO_BUFFER;\n\t\t}\n\t}\n\n\t/* buffer code in target endianness */\n\ttarget_buffer_set_u32_array(target, code_buf, code_size / 4, code);\n\n\t/* copy code to work area */\n\tretval = target_write_memory(target, (*area)->address,\n\t\t\t4, code_size / 4, code_buf);\n\n\treturn retval;\n}\n\n/**\n * ARM-specific bulk write from buffer to address of 8-bit wide NAND.\n * For now this supports ARMv4,ARMv5 and ARMv7-M cores.\n *\n * Enhancements to target_run_algorithm() could enable:\n *   - ARMv6 and ARMv7 cores in ARM mode\n *\n * Different code fragments could handle:\n *   - 16-bit wide data (needs different setup)\n *\n * @param nand Pointer to the arm_nand_data struct that defines the I/O\n * @param data Pointer to the data to be copied to flash\n * @param size Size of the data being copied\n * @return Success or failure of the operation\n */\nint arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size)\n{\n\tstruct target *target = nand->target;\n\tstruct arm_algorithm armv4_5_algo;\n\tstruct armv7m_algorithm armv7m_algo;\n\tvoid *arm_algo;\n\tstruct arm *arm = target->arch_info;\n\tstruct reg_param reg_params[3];\n\tuint32_t target_buf;\n\tuint32_t exit_var = 0;\n\tint retval;\n\n\t/* Inputs:\n\t *  r0\tNAND data address (byte wide)\n\t *  r1\tbuffer address\n\t *  r2\tbuffer length\n\t */\n\tstatic const uint32_t code_armv4_5[] = {\n\t\t0xe4d13001,\t/* s: ldrb  r3, [r1], #1 */\n\t\t0xe5c03000,\t/*    strb  r3, [r0]     */\n\t\t0xe2522001,\t/*    subs  r2, r2, #1   */\n\t\t0x1afffffb,\t/*    bne   s            */\n\n\t\t/* exit: ARMv4 needs hardware breakpoint */\n\t\t0xe1200070,\t/* e: bkpt  #0           */\n\t};\n\n\t/* Inputs:\n\t *  r0\tNAND data address (byte wide)\n\t *  r1\tbuffer address\n\t *  r2\tbuffer length\n\t *\n\t * see contrib/loaders/flash/armv7m_io.s for src\n\t */\n\tstatic const uint32_t code_armv7m[] = {\n\t\t0x3b01f811,\n\t\t0x3a017003,\n\t\t0xaffaf47f,\n\t\t0xbf00be00,\n\t};\n\n\tint target_code_size = 0;\n\tconst uint32_t *target_code_src = NULL;\n\n\t/* set up algorithm */\n\tif (is_armv7m(target_to_armv7m(target))) {  /* armv7m target */\n\t\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\t\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\t\tarm_algo = &armv7m_algo;\n\t\ttarget_code_size = sizeof(code_armv7m);\n\t\ttarget_code_src = code_armv7m;\n\t} else {\n\t\tarmv4_5_algo.common_magic = ARM_COMMON_MAGIC;\n\t\tarmv4_5_algo.core_mode = ARM_MODE_SVC;\n\t\tarmv4_5_algo.core_state = ARM_STATE_ARM;\n\t\tarm_algo = &armv4_5_algo;\n\t\ttarget_code_size = sizeof(code_armv4_5);\n\t\ttarget_code_src = code_armv4_5;\n\t}\n\n\tif (nand->op != ARM_NAND_WRITE || !nand->copy_area) {\n\t\tretval = arm_code_to_working_area(target, target_code_src, target_code_size,\n\t\t\t\tnand->chunk_size, &nand->copy_area);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tnand->op = ARM_NAND_WRITE;\n\n\t/* copy data to work area */\n\ttarget_buf = nand->copy_area->address + target_code_size;\n\tretval = target_write_buffer(target, target_buf, size, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* set up parameters */\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_IN);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, nand->data);\n\tbuf_set_u32(reg_params[1].value, 0, 32, target_buf);\n\tbuf_set_u32(reg_params[2].value, 0, 32, size);\n\n\t/* armv4 must exit using a hardware breakpoint */\n\tif (arm->arch == ARM_ARCH_V4)\n\t\texit_var = nand->copy_area->address + target_code_size - 4;\n\n\t/* use alg to write data from work area to NAND chip */\n\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\tnand->copy_area->address, exit_var, 1000, arm_algo);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error executing hosted NAND write\");\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\n\treturn retval;\n}\n\n/**\n * Uses an on-chip algorithm for an ARM device to read from a NAND device and\n * store the data into the host machine's memory.\n *\n * @param nand Pointer to the arm_nand_data struct that defines the I/O\n * @param data Pointer to the data buffer to store the read data\n * @param size Amount of data to be stored to the buffer.\n * @return Success or failure of the operation\n */\nint arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size)\n{\n\tstruct target *target = nand->target;\n\tstruct arm_algorithm armv4_5_algo;\n\tstruct armv7m_algorithm armv7m_algo;\n\tvoid *arm_algo;\n\tstruct arm *arm = target->arch_info;\n\tstruct reg_param reg_params[3];\n\tuint32_t target_buf;\n\tuint32_t exit_var = 0;\n\tint retval;\n\n\t/* Inputs:\n\t *  r0\tbuffer address\n\t *  r1\tNAND data address (byte wide)\n\t *  r2\tbuffer length\n\t */\n\tstatic const uint32_t code_armv4_5[] = {\n\t\t0xe5d13000,\t/* s: ldrb  r3, [r1]     */\n\t\t0xe4c03001,\t/*    strb  r3, [r0], #1 */\n\t\t0xe2522001,\t/*    subs  r2, r2, #1   */\n\t\t0x1afffffb,\t/*    bne   s            */\n\n\t\t/* exit: ARMv4 needs hardware breakpoint */\n\t\t0xe1200070,\t/* e: bkpt  #0           */\n\t};\n\n\t/* Inputs:\n\t *  r0\tbuffer address\n\t *  r1\tNAND data address (byte wide)\n\t *  r2\tbuffer length\n\t *\n\t * see contrib/loaders/flash/armv7m_io.s for src\n\t */\n\tstatic const uint32_t code_armv7m[] = {\n\t\t0xf800780b,\n\t\t0x3a013b01,\n\t\t0xaffaf47f,\n\t\t0xbf00be00,\n\t};\n\n\tint target_code_size = 0;\n\tconst uint32_t *target_code_src = NULL;\n\n\t/* set up algorithm */\n\tif (is_armv7m(target_to_armv7m(target))) {  /* armv7m target */\n\t\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\t\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\t\tarm_algo = &armv7m_algo;\n\t\ttarget_code_size = sizeof(code_armv7m);\n\t\ttarget_code_src = code_armv7m;\n\t} else {\n\t\tarmv4_5_algo.common_magic = ARM_COMMON_MAGIC;\n\t\tarmv4_5_algo.core_mode = ARM_MODE_SVC;\n\t\tarmv4_5_algo.core_state = ARM_STATE_ARM;\n\t\tarm_algo = &armv4_5_algo;\n\t\ttarget_code_size = sizeof(code_armv4_5);\n\t\ttarget_code_src = code_armv4_5;\n\t}\n\n\t/* create the copy area if not yet available */\n\tif (nand->op != ARM_NAND_READ || !nand->copy_area) {\n\t\tretval = arm_code_to_working_area(target, target_code_src, target_code_size,\n\t\t\t\tnand->chunk_size, &nand->copy_area);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tnand->op = ARM_NAND_READ;\n\ttarget_buf = nand->copy_area->address + target_code_size;\n\n\t/* set up parameters */\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_IN);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, target_buf);\n\tbuf_set_u32(reg_params[1].value, 0, 32, nand->data);\n\tbuf_set_u32(reg_params[2].value, 0, 32, size);\n\n\t/* armv4 must exit using a hardware breakpoint */\n\tif (arm->arch == ARM_ARCH_V4)\n\t\texit_var = nand->copy_area->address + target_code_size - 4;\n\n\t/* use alg to write data from NAND chip to work area */\n\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\tnand->copy_area->address, exit_var, 1000, arm_algo);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error executing hosted NAND read\");\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\n\t/* read from work area to the host's memory */\n\tretval = target_read_buffer(target, target_buf, size, data);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/arm_io.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2009 by David Brownell\n */\n#ifndef OPENOCD_FLASH_NAND_ARM_IO_H\n#define OPENOCD_FLASH_NAND_ARM_IO_H\n\n/**\n * Available operational states the arm_nand_data struct can be in.\n */\nenum arm_nand_op {\n\tARM_NAND_NONE,\t/**< No operation performed. */\n\tARM_NAND_READ,\t/**< Read operation performed. */\n\tARM_NAND_WRITE,\t/**< Write operation performed. */\n};\n\n/**\n * The arm_nand_data struct is used for defining NAND I/O operations on an ARM\n * core.\n */\nstruct arm_nand_data {\n\t/** Target is proxy for some ARM core. */\n\tstruct target *target;\n\n\t/** The copy area holds code loop and data for I/O operations. */\n\tstruct working_area *copy_area;\n\n\t/** The chunk size is the page size or ECC chunk. */\n\tunsigned chunk_size;\n\n\t/** Where data is read from or written to. */\n\tuint32_t data;\n\n\t/** Last operation executed using this struct. */\n\tenum arm_nand_op op;\n\n\t/* currently implicit:  data width == 8 bits (not 16) */\n};\n\nint arm_nandwrite(struct arm_nand_data *nand, uint8_t *data, int size);\nint arm_nandread(struct arm_nand_data *nand, uint8_t *data, uint32_t size);\n\n#endif /* OPENOCD_FLASH_NAND_ARM_IO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/at91sam9.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2009 by Dean Glazeski\n * dnglaze@gmail.com\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <target/arm.h>\n#include <helper/log.h>\n#include \"imp.h\"\n#include \"arm_io.h\"\n\n#define AT91C_PIOX_SODR (0x30)\t/**< Offset to PIO SODR. */\n#define AT91C_PIOX_CODR (0x34)\t/**< Offset to PIO CODR. */\n#define AT91C_PIOX_PDSR (0x3C)\t/**< Offset to PIO PDSR. */\n#define AT91C_ECCX_CR (0x00)\t/**< Offset to ECC CR. */\n#define AT91C_ECCX_SR (0x08)\t/**< Offset to ECC SR. */\n#define AT91C_ECCX_PR (0x0C)\t/**< Offset to ECC PR. */\n#define AT91C_ECCX_NPR (0x10)\t/**< Offset to ECC NPR. */\n\n/**\n * Representation of a pin on an AT91SAM9 chip.\n */\nstruct at91sam9_pin {\n\t/** Address of the PIO controller. */\n\tuint32_t pioc;\n\n\t/** Pin number. */\n\tuint32_t num;\n};\n\n/**\n * Private data for the controller that is stored in the NAND device structure.\n */\nstruct at91sam9_nand {\n\t/** Address of the ECC controller for NAND. */\n\tuint32_t ecc;\n\n\t/** Address data is written to. */\n\tuint32_t data;\n\n\t/** Address commands are written to. */\n\tuint32_t cmd;\n\n\t/** Address addresses are written to. */\n\tuint32_t addr;\n\n\t/** I/O structure for hosted reads/writes. */\n\tstruct arm_nand_data io;\n\n\t/** Pin representing the ready/~busy line. */\n\tstruct at91sam9_pin busy;\n\n\t/** Pin representing the chip enable. */\n\tstruct at91sam9_pin ce;\n};\n\n/**\n * Checks if the target is halted and prints an error message if it isn't.\n *\n * @param target Target to be checked.\n * @param label String label for where function is called from.\n * @return True if the target is halted.\n */\nstatic int at91sam9_halted(struct target *target, const char *label)\n{\n\tif (target->state == TARGET_HALTED)\n\t\treturn true;\n\n\tLOG_ERROR(\"Target must be halted to use NAND controller (%s)\", label);\n\treturn false;\n}\n\n/**\n * Initialize the AT91SAM9 NAND controller.\n *\n * @param nand NAND device the controller is attached to.\n * @return Success or failure of initialization.\n */\nstatic int at91sam9_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\tif (!at91sam9_halted(target, \"init\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Enable NAND device attached to a controller.\n *\n * @param nand NAND controller information for controlling NAND device.\n * @return Success or failure of the enabling.\n */\nstatic int at91sam9_enable(struct nand_device *nand)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\treturn target_write_u32(target, info->ce.pioc + AT91C_PIOX_CODR, 1 << info->ce.num);\n}\n\n/**\n * Disable NAND device attached to a controller.\n *\n * @param nand NAND controller information for controlling NAND device.\n * @return Success or failure of the disabling.\n */\nstatic int at91sam9_disable(struct nand_device *nand)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\treturn target_write_u32(target, info->ce.pioc + AT91C_PIOX_SODR, 1 << info->ce.num);\n}\n\n/**\n * Send a command to the NAND device.\n *\n * @param nand NAND device to write the command to.\n * @param command Command to be written.\n * @return Success or failure of writing the command.\n */\nstatic int at91sam9_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!at91sam9_halted(target, \"command\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\tat91sam9_enable(nand);\n\n\treturn target_write_u8(target, info->cmd, command);\n}\n\n/**\n * Reset the AT91SAM9 NAND controller.\n *\n * @param nand NAND device to be reset.\n * @return Success or failure of reset.\n */\nstatic int at91sam9_reset(struct nand_device *nand)\n{\n\tif (!at91sam9_halted(nand->target, \"reset\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn at91sam9_disable(nand);\n}\n\n/**\n * Send an address to the NAND device attached to an AT91SAM9 NAND controller.\n *\n * @param nand NAND device to send the address to.\n * @param address Address to be sent.\n * @return Success or failure of sending the address.\n */\nstatic int at91sam9_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!at91sam9_halted(nand->target, \"address\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn target_write_u8(target, info->addr, address);\n}\n\n/**\n * Read data directly from the NAND device attached to an AT91SAM9 NAND\n * controller.\n *\n * @param nand NAND device to read from.\n * @param data Pointer to where the data should be put.\n * @return Success or failure of reading the data.\n */\nstatic int at91sam9_read_data(struct nand_device *nand, void *data)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!at91sam9_halted(nand->target, \"read data\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn target_read_u8(target, info->data, data);\n}\n\n/**\n * Write data directly to the NAND device attached to an AT91SAM9 NAND\n * controller.\n *\n * @param nand NAND device to be written to.\n * @param data Data to be written.\n * @return Success or failure of the data write.\n */\nstatic int at91sam9_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!at91sam9_halted(target, \"write data\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn target_write_u8(target, info->data, data);\n}\n\n/**\n * Determine if the NAND device is ready by looking at the ready/~busy pin.\n *\n * @param nand NAND device to check.\n * @param timeout Time in milliseconds to wait for NAND to be ready.\n * @return True if the NAND is ready in the timeout period.\n */\nstatic int at91sam9_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t status;\n\n\tif (!at91sam9_halted(target, \"nand ready\"))\n\t\treturn 0;\n\n\tdo {\n\t\ttarget_read_u32(target, info->busy.pioc + AT91C_PIOX_PDSR, &status);\n\n\t\tif (status & (1 << info->busy.num))\n\t\t\treturn 1;\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\n/**\n * Read a block of data from the NAND device attached to an AT91SAM9.  This\n * utilizes the ARM hosted NAND read function.\n *\n * @param nand NAND device to read from.\n * @param data Pointer to where the read data should be placed.\n * @param size Size of the data being read.\n * @return Success or failure of the hosted read.\n */\nstatic int at91sam9_read_block_data(struct nand_device *nand, uint8_t *data, int size)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct arm_nand_data *io = &info->io;\n\tint status;\n\n\tif (!at91sam9_halted(nand->target, \"read block\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\tio->chunk_size = nand->page_size;\n\tstatus = arm_nandread(io, data, size);\n\n\treturn status;\n}\n\n/**\n * Write a block of data to a NAND device attached to an AT91SAM9.  This uses\n * the ARM hosted write function to write the data.\n *\n * @param nand NAND device to write to.\n * @param data Data to be written to device.\n * @param size Size of the data being written.\n * @return Success or failure of the hosted write.\n */\nstatic int at91sam9_write_block_data(struct nand_device *nand, uint8_t *data, int size)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct arm_nand_data *io = &info->io;\n\tint status;\n\n\tif (!at91sam9_halted(nand->target, \"write block\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\tio->chunk_size = nand->page_size;\n\tstatus = arm_nandwrite(io, data, size);\n\n\treturn status;\n}\n\n/**\n * Initialize the ECC controller on the AT91SAM9.\n *\n * @param target Target to configure ECC on.\n * @param info NAND controller information for where the ECC is.\n * @return Success or failure of initialization.\n */\nstatic int at91sam9_ecc_init(struct target *target, struct at91sam9_nand *info)\n{\n\tif (!info->ecc) {\n\t\tLOG_ERROR(\"ECC controller address must be set when not reading raw NAND data\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/* reset ECC parity registers */\n\treturn target_write_u32(target, info->ecc + AT91C_ECCX_CR, 1);\n}\n\n/**\n * Initialize an area for the OOB based on whether a user is requesting the OOB\n * data.  This determines the size of the OOB and allocates the space in case\n * the user has not requested the OOB data.\n *\n * @param nand NAND device we are creating an OOB for.\n * @param oob Pointer to the user supplied OOB area.\n * @param size Size of the OOB.\n * @return Pointer to an area to store OOB data.\n */\nstatic uint8_t *at91sam9_oob_init(struct nand_device *nand, uint8_t *oob, uint32_t *size)\n{\n\tif (!oob) {\n\t\t/* user doesn't want OOB, allocate it */\n\t\tif (nand->page_size == 512)\n\t\t\t*size = 16;\n\t\telse if (nand->page_size == 2048)\n\t\t\t*size = 64;\n\n\t\toob = malloc(*size);\n\t\tif (!oob) {\n\t\t\tLOG_ERROR(\"Unable to allocate space for OOB\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\tmemset(oob, 0xFF, *size);\n\t}\n\n\treturn oob;\n}\n\n/**\n * Reads a page from an AT91SAM9 NAND controller and verifies using 1-bit ECC\n * controller on chip.  This makes an attempt to correct any errors that are\n * encountered while reading the page of data.\n *\n * @param nand NAND device to read from\n * @param page Page to be read.\n * @param data Pointer to where data should be read to.\n * @param data_size Size of the data to be read.\n * @param oob Pointer to where OOB data should be read to.\n * @param oob_size Size of the OOB data to be read.\n * @return Success or failure of reading the NAND page.\n */\nstatic int at91sam9_read_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tint retval;\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint8_t *oob_data;\n\tuint32_t status;\n\n\tretval = at91sam9_ecc_init(target, info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = nand_page_command(nand, page, NAND_CMD_READ0, !data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data) {\n\t\tretval = nand_read_data_page(nand, data, data_size);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\toob_data = at91sam9_oob_init(nand, oob, &oob_size);\n\tretval = nand_read_data_page(nand, oob_data, oob_size);\n\tif (retval == ERROR_OK && data) {\n\t\ttarget_read_u32(target, info->ecc + AT91C_ECCX_SR, &status);\n\t\tif (status & 1) {\n\t\t\tLOG_ERROR(\"Error detected!\");\n\t\t\tif (status & 4)\n\t\t\t\tLOG_ERROR(\"Multiple errors encountered; unrecoverable!\");\n\t\t\telse {\n\t\t\t\t/* attempt recovery */\n\t\t\t\tuint32_t parity;\n\n\t\t\t\ttarget_read_u32(target,\n\t\t\t\t\tinfo->ecc + AT91C_ECCX_PR,\n\t\t\t\t\t&parity);\n\t\t\t\tuint32_t word = (parity & 0x0000FFF0) >> 4;\n\t\t\t\tuint32_t bit = parity & 0x0F;\n\n\t\t\t\tdata[word] ^= (0x1) << bit;\n\t\t\t\tLOG_INFO(\"Data word %d, bit %d corrected.\",\n\t\t\t\t\t(unsigned) word,\n\t\t\t\t\t(unsigned) bit);\n\t\t\t}\n\t\t}\n\n\t\tif (status & 2) {\n\t\t\t/* we could write back correct ECC data */\n\t\t\tLOG_ERROR(\"Error in ECC bytes detected\");\n\t\t}\n\t}\n\n\tif (!oob) {\n\t\t/* if it wasn't asked for, free it */\n\t\tfree(oob_data);\n\t}\n\n\treturn retval;\n}\n\n/**\n * Write a page of data including 1-bit ECC information to a NAND device\n * attached to an AT91SAM9 controller.  If there is OOB data to be written,\n * this will ignore the computed ECC from the ECC controller.\n *\n * @param nand NAND device to write to.\n * @param page Page to write.\n * @param data Pointer to data being written.\n * @param data_size Size of the data being written.\n * @param oob Pointer to OOB data being written.\n * @param oob_size Size of the OOB data.\n * @return Success or failure of the page write.\n */\nstatic int at91sam9_write_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tstruct at91sam9_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint8_t *oob_data = oob;\n\tuint32_t parity, nparity;\n\n\tretval = at91sam9_ecc_init(target, info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data) {\n\t\tretval = nand_write_data_page(nand, data, data_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write data to NAND device\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\toob_data = at91sam9_oob_init(nand, oob, &oob_size);\n\n\tif (!oob) {\n\t\t/* no OOB given, so read in the ECC parity from the ECC controller */\n\t\ttarget_read_u32(target, info->ecc + AT91C_ECCX_PR, &parity);\n\t\ttarget_read_u32(target, info->ecc + AT91C_ECCX_NPR, &nparity);\n\n\t\toob_data[0] = (uint8_t) parity;\n\t\toob_data[1] = (uint8_t) (parity >> 8);\n\t\toob_data[2] = (uint8_t) nparity;\n\t\toob_data[3] = (uint8_t) (nparity >> 8);\n\t}\n\n\tretval = nand_write_data_page(nand, oob_data, oob_size);\n\n\tif (!oob)\n\t\tfree(oob_data);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write OOB data to NAND\");\n\t\treturn retval;\n\t}\n\n\tretval = nand_write_finish(nand);\n\n\treturn retval;\n}\n\n/**\n * Handle the initial NAND device command for AT91SAM9 controllers.  This\n * initializes much of the controller information struct to be ready for future\n * reads and writes.\n */\nNAND_DEVICE_COMMAND_HANDLER(at91sam9_nand_device_command)\n{\n\tunsigned long chip = 0, ecc = 0;\n\tstruct at91sam9_nand *info = NULL;\n\n\tLOG_DEBUG(\"AT91SAM9 NAND Device Command\");\n\n\tif (CMD_ARGC < 3 || CMD_ARGC > 4) {\n\t\tLOG_ERROR(\"parameters: %s target chip_addr\", CMD_ARGV[0]);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);\n\tif (chip == 0) {\n\t\tLOG_ERROR(\"invalid NAND chip address: %s\", CMD_ARGV[2]);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (CMD_ARGC == 4) {\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ecc);\n\t\tif (ecc == 0) {\n\t\t\tLOG_ERROR(\"invalid ECC controller address: %s\", CMD_ARGV[3]);\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tinfo = calloc(1, sizeof(*info));\n\tif (!info) {\n\t\tLOG_ERROR(\"unable to allocate space for controller private data\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tinfo->data = chip;\n\tinfo->cmd = chip | (1 << 22);\n\tinfo->addr = chip | (1 << 21);\n\tinfo->ecc = ecc;\n\n\tnand->controller_priv = info;\n\tinfo->io.target = nand->target;\n\tinfo->io.data = info->data;\n\tinfo->io.op = ARM_NAND_NONE;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Handle the AT91SAM9 CLE command for specifying the address line to use for\n * writing commands to a NAND device.\n */\nCOMMAND_HANDLER(handle_at91sam9_cle_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct at91sam9_nand *info = NULL;\n\tunsigned num, address_line;\n\n\tif (CMD_ARGC != 2) {\n\t\tcommand_print(CMD, \"incorrect number of arguments for 'at91sam9 cle' command\");\n\t\treturn ERROR_OK;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tnand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"invalid nand device number: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tinfo = nand->controller_priv;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);\n\tinfo->cmd = info->data | (1 << address_line);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Handle the AT91SAM9 ALE command for specifying the address line to use for\n * writing addresses to the NAND device.\n */\nCOMMAND_HANDLER(handle_at91sam9_ale_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct at91sam9_nand *info = NULL;\n\tunsigned num, address_line;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tnand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"invalid nand device number: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tinfo = nand->controller_priv;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], address_line);\n\tinfo->addr = info->data | (1 << address_line);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Handle the AT91SAM9 RDY/~BUSY command for specifying the pin that watches the\n * RDY/~BUSY line from the NAND device.\n */\nCOMMAND_HANDLER(handle_at91sam9_rdy_busy_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct at91sam9_nand *info = NULL;\n\tunsigned num, base_pioc, pin_num;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tnand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"invalid nand device number: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tinfo = nand->controller_priv;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);\n\tinfo->busy.pioc = base_pioc;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);\n\tinfo->busy.num = pin_num;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Handle the AT91SAM9 CE command for specifying the pin that is used to enable\n * or disable the NAND device.\n */\nCOMMAND_HANDLER(handle_at91sam9_ce_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct at91sam9_nand *info = NULL;\n\tunsigned num, base_pioc, pin_num;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tnand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"invalid nand device number: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tinfo = nand->controller_priv;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], base_pioc);\n\tinfo->ce.pioc = base_pioc;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], pin_num);\n\tinfo->ce.num = pin_num;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration at91sam9_sub_command_handlers[] = {\n\t{\n\t\t.name = \"cle\",\n\t\t.handler = handle_at91sam9_cle_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set command latch enable address line (default is 22)\",\n\t\t.usage = \"bank_id address_line\",\n\t},\n\t{\n\t\t.name = \"ale\",\n\t\t.handler = handle_at91sam9_ale_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set address latch enable address line (default is 21)\",\n\t\t.usage = \"bank_id address_line\",\n\t},\n\t{\n\t\t.name = \"rdy_busy\",\n\t\t.handler = handle_at91sam9_rdy_busy_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the GPIO input pin connected to \"\n\t\t\t\"the RDY/~BUSY signal (no default)\",\n\t\t.usage = \"bank_id pio_base_addr pin_num\",\n\t},\n\t{\n\t\t.name = \"ce\",\n\t\t.handler = handle_at91sam9_ce_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the GPIO output pin connected to \"\n\t\t\t\"the chip enable signal (no default)\",\n\t\t.usage = \"bank_id pio_base_addr pin_num\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration at91sam9_command_handler[] = {\n\t{\n\t\t.name = \"at91sam9\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"AT91SAM9 NAND flash controller commands\",\n\t\t.usage = \"\",\n\t\t.chain = at91sam9_sub_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/**\n * Structure representing the AT91SAM9 NAND controller.\n */\nstruct nand_flash_controller at91sam9_nand_controller = {\n\t.name = \"at91sam9\",\n\t.nand_device_command = at91sam9_nand_device_command,\n\t.commands = at91sam9_command_handler,\n\t.init = at91sam9_init,\n\t.command = at91sam9_command,\n\t.reset = at91sam9_reset,\n\t.address = at91sam9_address,\n\t.read_data = at91sam9_read_data,\n\t.write_data = at91sam9_write_data,\n\t.nand_ready = at91sam9_nand_ready,\n\t.read_block_data = at91sam9_read_block_data,\n\t.write_block_data = at91sam9_write_block_data,\n\t.read_page = at91sam9_read_page,\n\t.write_page = at91sam9_write_page,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/core.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de>               *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *                                                                         *\n *   Partially based on drivers/mtd/nand_ids.c from Linux.                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n\n/* configured NAND devices and NAND Flash command handler */\nstruct nand_device *nand_devices;\n\nvoid nand_device_add(struct nand_device *c)\n{\n\tif (nand_devices) {\n\t\tstruct nand_device *p = nand_devices;\n\t\twhile (p && p->next)\n\t\t\tp = p->next;\n\t\tp->next = c;\n\t} else\n\t\tnand_devices = c;\n}\n\n\n/*\tChip ID list\n *\n *\tManufacturer, ID code, pagesize, chipsize in MegaByte, eraseblock size,\n *\toptions, name\n *\n *\tPagesize; 0, 256, 512\n *\t0\tget this information from the extended chip ID\n *\t256\t256 Byte page size\n *\t512\t512 Byte page size\n */\nstatic struct nand_info nand_flash_ids[] = {\n\t/* Vendor Specific Entries */\n\t{ NAND_MFR_SAMSUNG,     0xD5, 8192, 2048, 0x100000, LP_OPTIONS,\n\t  \"K9GAG08 2GB NAND 3.3V x8 MLC 2b/cell\"},\n\t{ NAND_MFR_SAMSUNG,     0xD7, 8192, 4096, 0x100000, LP_OPTIONS,\n\t  \"K9LBG08 4GB NAND 3.3V x8 MLC 2b/cell\"},\n\n\t/* start \"museum\" IDs */\n\t{ 0x0,                  0x6e, 256, 1, 0x1000, 0,                \"NAND 1MiB 5V 8-bit\"},\n\t{ 0x0,                  0x64, 256, 2, 0x1000, 0,                \"NAND 2MiB 5V 8-bit\"},\n\t{ 0x0,                  0x6b, 512, 4, 0x2000, 0,                \"NAND 4MiB 5V 8-bit\"},\n\t{ 0x0,                  0xe8, 256, 1, 0x1000, 0,                \"NAND 1MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xec, 256, 1, 0x1000, 0,                \"NAND 1MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xea, 256, 2, 0x1000, 0,                \"NAND 2MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xd5, 512, 4, 0x2000, 0,                \"NAND 4MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xe3, 512, 4, 0x2000, 0,                \"NAND 4MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xe5, 512, 4, 0x2000, 0,                \"NAND 4MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xd6, 512, 8, 0x2000, 0,                \"NAND 8MiB 3.3V 8-bit\"},\n\n\t{ 0x0,                  0x39, 512, 8, 0x2000, 0,                \"NAND 8MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xe6, 512, 8, 0x2000, 0,                \"NAND 8MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16, \"NAND 8MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16, \"NAND 8MiB 3.3V 16-bit\"},\n\t/* end \"museum\" IDs */\n\n\t{ 0x0,                  0x33, 512, 16, 0x4000, 0,               \"NAND 16MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0x73, 512, 16, 0x4000, 0,               \"NAND 16MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16, \"NAND 16MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16, \"NAND 16MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0x35, 512, 32, 0x4000, 0,               \"NAND 32MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0x75, 512, 32, 0x4000, 0,               \"NAND 32MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16, \"NAND 32MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16, \"NAND 32MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0x36, 512, 64, 0x4000, 0,               \"NAND 64MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0x76, 512, 64, 0x4000, 0,               \"NAND 64MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16, \"NAND 64MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16, \"NAND 64MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0x78, 512, 128, 0x4000, 0,              \"NAND 128MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0x39, 512, 128, 0x4000, 0,              \"NAND 128MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0x79, 512, 128, 0x4000, 0,              \"NAND 128MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16, \"NAND 128MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16, \"NAND 128MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16, \"NAND 128MiB 3.3V 16-bit\"},\n\t{ 0x0,                  0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16, \"NAND 128MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0x71, 512, 256, 0x4000, 0,              \"NAND 256MiB 3.3V 8-bit\"},\n\n\t{ 0x0,                  0xA2, 0,  64, 0, LP_OPTIONS,            \"NAND 64MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xF2, 0,  64, 0, LP_OPTIONS,            \"NAND 64MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xB2, 0,  64, 0, LP_OPTIONS16,          \"NAND 64MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xC2, 0,  64, 0, LP_OPTIONS16,          \"NAND 64MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0xA1, 0, 128, 0, LP_OPTIONS,            \"NAND 128MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xF1, 0, 128, 0, LP_OPTIONS,            \"NAND 128MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xB1, 0, 128, 0, LP_OPTIONS16,          \"NAND 128MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xC1, 0, 128, 0, LP_OPTIONS16,          \"NAND 128MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0xAA, 0, 256, 0, LP_OPTIONS,            \"NAND 256MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xDA, 0, 256, 0, LP_OPTIONS,            \"NAND 256MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xBA, 0, 256, 0, LP_OPTIONS16,          \"NAND 256MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xCA, 0, 256, 0, LP_OPTIONS16,          \"NAND 256MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0xAC, 0, 512, 0, LP_OPTIONS,            \"NAND 512MiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xDC, 0, 512, 0, LP_OPTIONS,            \"NAND 512MiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xBC, 0, 512, 0, LP_OPTIONS16,          \"NAND 512MiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xCC, 0, 512, 0, LP_OPTIONS16,          \"NAND 512MiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0xA3, 0, 1024, 0, LP_OPTIONS,           \"NAND 1GiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xD3, 0, 1024, 0, LP_OPTIONS,           \"NAND 1GiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xB3, 0, 1024, 0, LP_OPTIONS16,         \"NAND 1GiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xC3, 0, 1024, 0, LP_OPTIONS16,         \"NAND 1GiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0xA5, 0, 2048, 0, LP_OPTIONS,           \"NAND 2GiB 1.8V 8-bit\"},\n\t{ 0x0,                  0xD5, 0, 8192, 0, LP_OPTIONS,           \"NAND 2GiB 3.3V 8-bit\"},\n\t{ 0x0,                  0xB5, 0, 2048, 0, LP_OPTIONS16,         \"NAND 2GiB 1.8V 16-bit\"},\n\t{ 0x0,                  0xC5, 0, 2048, 0, LP_OPTIONS16,         \"NAND 2GiB 3.3V 16-bit\"},\n\n\t{ 0x0,                  0x48, 0, 2048, 0, LP_OPTIONS,           \"NAND 2GiB 3.3V 8-bit\"},\n\n\t{0, 0, 0, 0, 0, 0, NULL}\n};\n\n/* Manufacturer ID list\n */\nstatic struct nand_manufacturer nand_manuf_ids[] = {\n\t{0x0, \"unknown\"},\n\t{NAND_MFR_TOSHIBA, \"Toshiba\"},\n\t{NAND_MFR_SAMSUNG, \"Samsung\"},\n\t{NAND_MFR_FUJITSU, \"Fujitsu\"},\n\t{NAND_MFR_NATIONAL, \"National\"},\n\t{NAND_MFR_RENESAS, \"Renesas\"},\n\t{NAND_MFR_STMICRO, \"ST Micro\"},\n\t{NAND_MFR_HYNIX, \"Hynix\"},\n\t{NAND_MFR_MICRON, \"Micron\"},\n\t{0x0, NULL},\n};\n\n/*\n * Define default oob placement schemes for large and small page devices\n */\n\n#if 0\nstatic struct nand_ecclayout nand_oob_8 = {\n\t.eccbytes = 3,\n\t.eccpos = {0, 1, 2},\n\t.oobfree = {\n\t\t{.offset = 3,\n\t\t .length = 2},\n\t\t{.offset = 6,\n\t\t .length = 2}\n\t}\n};\n#endif\n\n/**\n * Returns the flash bank specified by @a name, which matches the\n * driver name and a suffix (option) specify the driver-specific\n * bank number. The suffix consists of the '.' and the driver-specific\n * bank number: when two davinci banks are defined, then 'davinci.1' refers\n * to the second (e.g. DM355EVM).\n */\nstatic struct nand_device *get_nand_device_by_name(const char *name)\n{\n\tunsigned requested = get_flash_name_index(name);\n\tunsigned found = 0;\n\n\tstruct nand_device *nand;\n\tfor (nand = nand_devices; nand; nand = nand->next) {\n\t\tif (strcmp(nand->name, name) == 0)\n\t\t\treturn nand;\n\t\tif (!flash_driver_name_matches(nand->controller->name, name))\n\t\t\tcontinue;\n\t\tif (++found < requested)\n\t\t\tcontinue;\n\t\treturn nand;\n\t}\n\treturn NULL;\n}\n\nstruct nand_device *get_nand_device_by_num(int num)\n{\n\tstruct nand_device *p;\n\tint i = 0;\n\n\tfor (p = nand_devices; p; p = p->next) {\n\t\tif (i++ == num)\n\t\t\treturn p;\n\t}\n\n\treturn NULL;\n}\n\nCOMMAND_HELPER(nand_command_get_device, unsigned name_index,\n\tstruct nand_device **nand)\n{\n\tconst char *str = CMD_ARGV[name_index];\n\t*nand = get_nand_device_by_name(str);\n\tif (*nand)\n\t\treturn ERROR_OK;\n\n\tunsigned num;\n\tCOMMAND_PARSE_NUMBER(uint, str, num);\n\t*nand = get_nand_device_by_num(num);\n\tif (!*nand) {\n\t\tcommand_print(CMD, \"NAND flash device '%s' not found\", str);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n\nint nand_build_bbt(struct nand_device *nand, int first, int last)\n{\n\tuint32_t page;\n\tint i;\n\tint pages_per_block = (nand->erase_size / nand->page_size);\n\tuint8_t oob[6];\n\tint ret;\n\n\tif ((first < 0) || (first >= nand->num_blocks))\n\t\tfirst = 0;\n\n\tif ((last >= nand->num_blocks) || (last == -1))\n\t\tlast = nand->num_blocks - 1;\n\n\tpage = first * pages_per_block;\n\tfor (i = first; i <= last; i++) {\n\t\tret = nand_read_page(nand, page, NULL, 0, oob, 6);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (((nand->device->options & NAND_BUSWIDTH_16) && ((oob[0] & oob[1]) != 0xff))\n\t\t\t\t|| (((nand->page_size == 512) && (oob[5] != 0xff)) ||\n\t\t\t\t((nand->page_size == 2048) && (oob[0] != 0xff)))) {\n\t\t\tLOG_WARNING(\"bad block: %i\", i);\n\t\t\tnand->blocks[i].is_bad = 1;\n\t\t} else\n\t\t\tnand->blocks[i].is_bad = 0;\n\n\t\tpage += pages_per_block;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint nand_read_status(struct nand_device *nand, uint8_t *status)\n{\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\t/* Send read status command */\n\t/* FIXME: errors returned from nand->controller are mostly ignored! */\n\tnand->controller->command(nand, NAND_CMD_STATUS);\n\n\talive_sleep(1);\n\n\t/* read status */\n\tif (nand->device->options & NAND_BUSWIDTH_16) {\n\t\tuint16_t data;\n\t\tnand->controller->read_data(nand, &data);\n\t\t*status = data & 0xff;\n\t} else\n\t\tnand->controller->read_data(nand, status);\n\n\treturn ERROR_OK;\n}\n\nstatic int nand_poll_ready(struct nand_device *nand, int timeout)\n{\n\tuint8_t status;\n\n\tnand->controller->command(nand, NAND_CMD_STATUS);\n\tdo {\n\t\tif (nand->device->options & NAND_BUSWIDTH_16) {\n\t\t\tuint16_t data;\n\t\t\tnand->controller->read_data(nand, &data);\n\t\t\tstatus = data & 0xff;\n\t\t} else\n\t\t\tnand->controller->read_data(nand, &status);\n\t\tif (status & NAND_STATUS_READY)\n\t\t\tbreak;\n\t\talive_sleep(1);\n\t} while (timeout--);\n\n\treturn (status & NAND_STATUS_READY) != 0;\n}\n\nint nand_probe(struct nand_device *nand)\n{\n\tuint8_t manufacturer_id, device_id;\n\tuint8_t id_buff[6] = { 0 };\t/* zero buff to silence false warning\n\t\t\t\t\t * from clang static analyzer */\n\tint retval;\n\tint i;\n\n\t/* clear device data */\n\tnand->device = NULL;\n\tnand->manufacturer = NULL;\n\n\t/* clear device parameters */\n\tnand->bus_width = 0;\n\tnand->address_cycles = 0;\n\tnand->page_size = 0;\n\tnand->erase_size = 0;\n\n\t/* initialize controller (device parameters are zero, use controller default) */\n\tretval = nand->controller->init(nand);\n\tif (retval != ERROR_OK) {\n\t\tswitch (retval) {\n\t\t\tcase ERROR_NAND_OPERATION_FAILED:\n\t\t\t\tLOG_DEBUG(\"controller initialization failed\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\tcase ERROR_NAND_OPERATION_NOT_SUPPORTED:\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\"BUG: controller reported that it doesn't support default parameters\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown controller initialization failure\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tnand->controller->command(nand, NAND_CMD_RESET);\n\tnand->controller->reset(nand);\n\n\tnand->controller->command(nand, NAND_CMD_READID);\n\tnand->controller->address(nand, 0x0);\n\n\tif (nand->bus_width == 8) {\n\t\tnand->controller->read_data(nand, &manufacturer_id);\n\t\tnand->controller->read_data(nand, &device_id);\n\t} else {\n\t\tuint16_t data_buf;\n\t\tnand->controller->read_data(nand, &data_buf);\n\t\tmanufacturer_id = data_buf & 0xff;\n\t\tnand->controller->read_data(nand, &data_buf);\n\t\tdevice_id = data_buf & 0xff;\n\t}\n\n\tfor (i = 0; nand_flash_ids[i].name; i++) {\n\t\tif (nand_flash_ids[i].id == device_id &&\n\t\t\t\t(nand_flash_ids[i].mfr_id == manufacturer_id ||\n\t\t\t\tnand_flash_ids[i].mfr_id == 0)) {\n\t\t\tnand->device = &nand_flash_ids[i];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfor (i = 0; nand_manuf_ids[i].name; i++) {\n\t\tif (nand_manuf_ids[i].id == manufacturer_id) {\n\t\t\tnand->manufacturer = &nand_manuf_ids[i];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!nand->manufacturer) {\n\t\tnand->manufacturer = &nand_manuf_ids[0];\n\t\tnand->manufacturer->id = manufacturer_id;\n\t}\n\n\tif (!nand->device) {\n\t\tLOG_ERROR(\n\t\t\t\"unknown NAND flash device found, manufacturer id: 0x%2.2x device id: 0x%2.2x\",\n\t\t\tmanufacturer_id,\n\t\t\tdevice_id);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"found %s (%s)\", nand->device->name, nand->manufacturer->name);\n\n\t/* initialize device parameters */\n\n\t/* bus width */\n\tif (nand->device->options & NAND_BUSWIDTH_16)\n\t\tnand->bus_width = 16;\n\telse\n\t\tnand->bus_width = 8;\n\n\t/* Do we need extended device probe information? */\n\tif (nand->device->page_size == 0 ||\n\t\t\tnand->device->erase_size == 0) {\n\t\tif (nand->bus_width == 8) {\n\t\t\tretval = nand->controller->read_data(nand, id_buff + 3);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = nand->controller->read_data(nand, id_buff + 4);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = nand->controller->read_data(nand, id_buff + 5);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t} else {\n\t\t\tuint16_t data_buf;\n\n\t\t\tretval = nand->controller->read_data(nand, &data_buf);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tid_buff[3] = data_buf;\n\n\t\t\tretval = nand->controller->read_data(nand, &data_buf);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tid_buff[4] = data_buf;\n\n\t\t\tretval = nand->controller->read_data(nand, &data_buf);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tid_buff[5] = data_buf >> 8;\n\t\t}\n\t}\n\n\t/* page size */\n\tif (nand->device->page_size == 0)\n\t\tnand->page_size = 1 << (10 + (id_buff[4] & 3));\n\telse if (nand->device->page_size == 256) {\n\t\tLOG_ERROR(\"NAND flashes with 256 byte pagesize are not supported\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else\n\t\tnand->page_size = nand->device->page_size;\n\n\t/* number of address cycles */\n\tif (nand->page_size <= 512) {\n\t\t/* small page devices */\n\t\tif (nand->device->chip_size <= 32)\n\t\t\tnand->address_cycles = 3;\n\t\telse if (nand->device->chip_size <= 8*1024)\n\t\t\tnand->address_cycles = 4;\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: small page NAND device with more than 8 GiB encountered\");\n\t\t\tnand->address_cycles = 5;\n\t\t}\n\t} else {\n\t\t/* large page devices */\n\t\tif (nand->device->chip_size <= 128)\n\t\t\tnand->address_cycles = 4;\n\t\telse if (nand->device->chip_size <= 32*1024)\n\t\t\tnand->address_cycles = 5;\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: large page NAND device with more than 32 GiB encountered\");\n\t\t\tnand->address_cycles = 6;\n\t\t}\n\t}\n\n\t/* erase size */\n\tif (nand->device->erase_size == 0) {\n\t\tswitch ((id_buff[4] >> 4) & 3) {\n\t\t\tcase 0:\n\t\t\t\tnand->erase_size = 64 << 10;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tnand->erase_size = 128 << 10;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tnand->erase_size = 256 << 10;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tnand->erase_size = 512 << 10;\n\t\t\t\tbreak;\n\t\t}\n\t} else\n\t\tnand->erase_size = nand->device->erase_size;\n\n\t/* initialize controller, but leave parameters at the controllers default */\n\tretval = nand->controller->init(nand);\n\tif (retval != ERROR_OK) {\n\t\tswitch (retval) {\n\t\t\tcase ERROR_NAND_OPERATION_FAILED:\n\t\t\t\tLOG_DEBUG(\"controller initialization failed\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\tcase ERROR_NAND_OPERATION_NOT_SUPPORTED:\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\"controller doesn't support requested parameters (buswidth: %i, address cycles: %i, page size: %i)\",\n\t\t\t\tnand->bus_width,\n\t\t\t\tnand->address_cycles,\n\t\t\t\tnand->page_size);\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown controller initialization failure\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tnand->num_blocks = (nand->device->chip_size * 1024) / (nand->erase_size / 1024);\n\tnand->blocks = malloc(sizeof(struct nand_block) * nand->num_blocks);\n\n\tfor (i = 0; i < nand->num_blocks; i++) {\n\t\tnand->blocks[i].size = nand->erase_size;\n\t\tnand->blocks[i].offset = i * nand->erase_size;\n\t\tnand->blocks[i].is_erased = -1;\n\t\tnand->blocks[i].is_bad = -1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint nand_erase(struct nand_device *nand, int first_block, int last_block)\n{\n\tint i;\n\tuint32_t page;\n\tuint8_t status;\n\tint retval;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tif ((first_block < 0) || (last_block >= nand->num_blocks))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* make sure we know if a block is bad before erasing it */\n\tfor (i = first_block; i <= last_block; i++) {\n\t\tif (nand->blocks[i].is_bad == -1) {\n\t\t\tnand_build_bbt(nand, i, last_block);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfor (i = first_block; i <= last_block; i++) {\n\t\t/* Send erase setup command */\n\t\tnand->controller->command(nand, NAND_CMD_ERASE1);\n\n\t\tpage = i * (nand->erase_size / nand->page_size);\n\n\t\t/* Send page address */\n\t\tif (nand->page_size <= 512) {\n\t\t\t/* row */\n\t\t\tnand->controller->address(nand, page & 0xff);\n\t\t\tnand->controller->address(nand, (page >> 8) & 0xff);\n\n\t\t\t/* 3rd cycle only on devices with more than 32 MiB */\n\t\t\tif (nand->address_cycles >= 4)\n\t\t\t\tnand->controller->address(nand, (page >> 16) & 0xff);\n\n\t\t\t/* 4th cycle only on devices with more than 8 GiB */\n\t\t\tif (nand->address_cycles >= 5)\n\t\t\t\tnand->controller->address(nand, (page >> 24) & 0xff);\n\t\t} else {\n\t\t\t/* row */\n\t\t\tnand->controller->address(nand, page & 0xff);\n\t\t\tnand->controller->address(nand, (page >> 8) & 0xff);\n\n\t\t\t/* 3rd cycle only on devices with more than 128 MiB */\n\t\t\tif (nand->address_cycles >= 5)\n\t\t\t\tnand->controller->address(nand, (page >> 16) & 0xff);\n\t\t}\n\n\t\t/* Send erase confirm command */\n\t\tnand->controller->command(nand, NAND_CMD_ERASE2);\n\n\t\tretval = nand->controller->nand_ready ?\n\t\t\tnand->controller->nand_ready(nand, 1000) :\n\t\t\tnand_poll_ready(nand, 1000);\n\t\tif (!retval) {\n\t\t\tLOG_ERROR(\"timeout waiting for NAND flash block erase to complete\");\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t\t}\n\n\t\tretval = nand_read_status(nand, &status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"couldn't read status\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (status & 0x1) {\n\t\t\tLOG_ERROR(\"didn't erase %sblock %d; status: 0x%2.2x\",\n\t\t\t\t(nand->blocks[i].is_bad == 1)\n\t\t\t\t? \"bad \" : \"\",\n\t\t\t\ti, status);\n\t\t\t/* continue; other blocks might still be erasable */\n\t\t}\n\n\t\tnand->blocks[i].is_erased = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\n#if 0\nstatic int nand_read_plain(struct nand_device *nand,\n\tuint32_t address,\n\tuint8_t *data,\n\tuint32_t data_size)\n{\n\tuint8_t *page;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tif (address % nand->page_size) {\n\t\tLOG_ERROR(\"reads need to be page aligned\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tpage = malloc(nand->page_size);\n\n\twhile (data_size > 0) {\n\t\tuint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;\n\t\tuint32_t page_address;\n\n\n\t\tpage_address = address / nand->page_size;\n\n\t\tnand_read_page(nand, page_address, page, nand->page_size, NULL, 0);\n\n\t\tmemcpy(data, page, thisrun_size);\n\n\t\taddress += thisrun_size;\n\t\tdata += thisrun_size;\n\t\tdata_size -= thisrun_size;\n\t}\n\n\tfree(page);\n\n\treturn ERROR_OK;\n}\n\nstatic int nand_write_plain(struct nand_device *nand,\n\tuint32_t address,\n\tuint8_t *data,\n\tuint32_t data_size)\n{\n\tuint8_t *page;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tif (address % nand->page_size) {\n\t\tLOG_ERROR(\"writes need to be page aligned\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tpage = malloc(nand->page_size);\n\n\twhile (data_size > 0) {\n\t\tuint32_t thisrun_size = (data_size > nand->page_size) ? nand->page_size : data_size;\n\t\tuint32_t page_address;\n\n\t\tmemset(page, 0xff, nand->page_size);\n\t\tmemcpy(page, data, thisrun_size);\n\n\t\tpage_address = address / nand->page_size;\n\n\t\tnand_write_page(nand, page_address, page, nand->page_size, NULL, 0);\n\n\t\taddress += thisrun_size;\n\t\tdata += thisrun_size;\n\t\tdata_size -= thisrun_size;\n\t}\n\n\tfree(page);\n\n\treturn ERROR_OK;\n}\n#endif\n\nint nand_write_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tuint32_t block;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tblock = page / (nand->erase_size / nand->page_size);\n\tif (nand->blocks[block].is_erased == 1)\n\t\tnand->blocks[block].is_erased = 0;\n\n\tif (nand->use_raw || !nand->controller->write_page)\n\t\treturn nand_write_page_raw(nand, page, data, data_size, oob, oob_size);\n\telse\n\t\treturn nand->controller->write_page(nand, page, data, data_size, oob, oob_size);\n}\n\nint nand_read_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tif (nand->use_raw || !nand->controller->read_page)\n\t\treturn nand_read_page_raw(nand, page, data, data_size, oob, oob_size);\n\telse\n\t\treturn nand->controller->read_page(nand, page, data, data_size, oob, oob_size);\n}\n\nint nand_page_command(struct nand_device *nand, uint32_t page,\n\tuint8_t cmd, bool oob_only)\n{\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\n\tif (oob_only && NAND_CMD_READ0 == cmd && nand->page_size <= 512)\n\t\tcmd = NAND_CMD_READOOB;\n\n\tnand->controller->command(nand, cmd);\n\n\tif (nand->page_size <= 512) {\n\t\t/* small page device */\n\n\t\t/* column (always 0, we start at the beginning of a page/OOB area) */\n\t\tnand->controller->address(nand, 0x0);\n\n\t\t/* row */\n\t\tnand->controller->address(nand, page & 0xff);\n\t\tnand->controller->address(nand, (page >> 8) & 0xff);\n\n\t\t/* 4th cycle only on devices with more than 32 MiB */\n\t\tif (nand->address_cycles >= 4)\n\t\t\tnand->controller->address(nand, (page >> 16) & 0xff);\n\n\t\t/* 5th cycle only on devices with more than 8 GiB */\n\t\tif (nand->address_cycles >= 5)\n\t\t\tnand->controller->address(nand, (page >> 24) & 0xff);\n\t} else {\n\t\t/* large page device */\n\n\t\t/* column (0 when we start at the beginning of a page,\n\t\t * or 2048 for the beginning of OOB area)\n\t\t */\n\t\tnand->controller->address(nand, 0x0);\n\t\tif (oob_only)\n\t\t\tnand->controller->address(nand, 0x8);\n\t\telse\n\t\t\tnand->controller->address(nand, 0x0);\n\n\t\t/* row */\n\t\tnand->controller->address(nand, page & 0xff);\n\t\tnand->controller->address(nand, (page >> 8) & 0xff);\n\n\t\t/* 5th cycle only on devices with more than 128 MiB */\n\t\tif (nand->address_cycles >= 5)\n\t\t\tnand->controller->address(nand, (page >> 16) & 0xff);\n\n\t\t/* large page devices need a start command if reading */\n\t\tif (cmd == NAND_CMD_READ0)\n\t\t\tnand->controller->command(nand, NAND_CMD_READSTART);\n\t}\n\n\tif (nand->controller->nand_ready) {\n\t\tif (!nand->controller->nand_ready(nand, 100))\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t} else {\n\t\t/* nand_poll_read() cannot be used during nand read */\n\t\talive_sleep(1);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)\n{\n\tint retval = ERROR_NAND_NO_BUFFER;\n\n\tif (nand->controller->read_block_data)\n\t\tretval = (nand->controller->read_block_data)(nand, data, size);\n\n\tif (retval == ERROR_NAND_NO_BUFFER) {\n\t\tuint32_t i;\n\t\tint incr = (nand->device->options & NAND_BUSWIDTH_16) ? 2 : 1;\n\n\t\tretval = ERROR_OK;\n\t\tfor (i = 0; retval == ERROR_OK && i < size; i += incr) {\n\t\t\tretval = nand->controller->read_data(nand, data);\n\t\t\tdata += incr;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint nand_read_page_raw(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tint retval;\n\n\tretval = nand_page_command(nand, page, NAND_CMD_READ0, !data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data)\n\t\tnand_read_data_page(nand, data, data_size);\n\n\tif (oob)\n\t\tnand_read_data_page(nand, oob, oob_size);\n\n\treturn ERROR_OK;\n}\n\nint nand_write_data_page(struct nand_device *nand, uint8_t *data, uint32_t size)\n{\n\tint retval = ERROR_NAND_NO_BUFFER;\n\n\tif (nand->controller->write_block_data)\n\t\tretval = (nand->controller->write_block_data)(nand, data, size);\n\n\tif (retval == ERROR_NAND_NO_BUFFER) {\n\t\tbool is16bit = nand->device->options & NAND_BUSWIDTH_16;\n\t\tuint32_t incr = is16bit ? 2 : 1;\n\t\tuint16_t write_data;\n\t\tuint32_t i;\n\n\t\tfor (i = 0; i < size; i += incr) {\n\t\t\tif (is16bit)\n\t\t\t\twrite_data = le_to_h_u16(data);\n\t\t\telse\n\t\t\t\twrite_data = *data;\n\n\t\t\tretval = nand->controller->write_data(nand, write_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\tdata += incr;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint nand_write_finish(struct nand_device *nand)\n{\n\tint retval;\n\tuint8_t status;\n\n\tnand->controller->command(nand, NAND_CMD_PAGEPROG);\n\n\tretval = nand->controller->nand_ready ?\n\t\tnand->controller->nand_ready(nand, 100) :\n\t\tnand_poll_ready(nand, 100);\n\tif (!retval)\n\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\n\tretval = nand_read_status(nand, &status);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"couldn't read status\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (status & NAND_STATUS_FAIL) {\n\t\tLOG_ERROR(\"write operation didn't pass, status: 0x%2.2x\",\n\t\t\tstatus);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint nand_write_page_raw(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tint retval;\n\n\tretval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data) {\n\t\tretval = nand_write_data_page(nand, data, data_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write data to NAND device\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tif (oob) {\n\t\tretval = nand_write_data_page(nand, oob, oob_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write OOB data to NAND device\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn nand_write_finish(nand);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/core.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *                                                                         *\n *   Partially based on linux/include/linux/mtd/nand.h                     *\n *   Copyright (C) 2000 David Woodhouse <dwmw2@mvhi.com>                   *\n *   Copyright (C) 2000 Steven J. Hill <sjhill@realitydiluted.com>         *\n *   Copyright (C) 2000 Thomas Gleixner <tglx@linutronix.de>               *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_CORE_H\n#define OPENOCD_FLASH_NAND_CORE_H\n\n#include <flash/common.h>\n\n/**\n * Representation of a single NAND block in a NAND device.\n */\nstruct nand_block {\n\t/** Offset to the block. */\n\tuint32_t offset;\n\n\t/** Size of the block. */\n\tuint32_t size;\n\n\t/** True if the block has been erased. */\n\tint is_erased;\n\n\t/** True if the block is bad. */\n\tint is_bad;\n};\n\nstruct nand_oobfree {\n\tint offset;\n\tint length;\n};\n\nstruct nand_ecclayout {\n\tint eccbytes;\n\tint eccpos[64];\n\tint oobavail;\n\tstruct nand_oobfree oobfree[2];\n};\n\nstruct nand_device {\n\tconst char *name;\n\tstruct target *target;\n\tstruct nand_flash_controller *controller;\n\tvoid *controller_priv;\n\tstruct nand_manufacturer *manufacturer;\n\tstruct nand_info *device;\n\tint bus_width;\n\tint address_cycles;\n\tint page_size;\n\tint erase_size;\n\tbool use_raw;\n\tint num_blocks;\n\tstruct nand_block *blocks;\n\tstruct nand_device *next;\n};\n\n/* NAND Flash Manufacturer ID Codes\n */\nenum {\n\tNAND_MFR_TOSHIBA = 0x98,\n\tNAND_MFR_SAMSUNG = 0xec,\n\tNAND_MFR_FUJITSU = 0x04,\n\tNAND_MFR_NATIONAL = 0x8f,\n\tNAND_MFR_RENESAS = 0x07,\n\tNAND_MFR_STMICRO = 0x20,\n\tNAND_MFR_HYNIX = 0xad,\n\tNAND_MFR_MICRON = 0x2c,\n};\n\nstruct nand_manufacturer {\n\tint id;\n\tconst char *name;\n};\n\nstruct nand_info {\n\tint mfr_id;\n\tint id;\n\tint page_size;\n\tint chip_size;\n\tint erase_size;\n\tint options;\n\tconst char *name;\n};\n\n/* Option constants for bizarre dysfunctionality and real features\n */\nenum {\n\t/* Chip can not auto increment pages */\n\tNAND_NO_AUTOINCR = 0x00000001,\n\n\t/* Buswitdh is 16 bit */\n\tNAND_BUSWIDTH_16 = 0x00000002,\n\n\t/* Device supports partial programming without padding */\n\tNAND_NO_PADDING = 0x00000004,\n\n\t/* Chip has cache program function */\n\tNAND_CACHEPRG = 0x00000008,\n\n\t/* Chip has copy back function */\n\tNAND_COPYBACK = 0x00000010,\n\n\t/* AND Chip which has 4 banks and a confusing page / block\n\t * assignment. See Renesas datasheet for further information */\n\tNAND_IS_AND = 0x00000020,\n\n\t/* Chip has a array of 4 pages which can be read without\n\t * additional ready /busy waits */\n\tNAND_4PAGE_ARRAY = 0x00000040,\n\n\t/* Chip requires that BBT is periodically rewritten to prevent\n\t * bits from adjacent blocks from 'leaking' in altering data.\n\t * This happens with the Renesas AG-AND chips, possibly others.  */\n\tBBT_AUTO_REFRESH = 0x00000080,\n\n\t/* Chip does not require ready check on read. True\n\t * for all large page devices, as they do not support\n\t * autoincrement.*/\n\tNAND_NO_READRDY = 0x00000100,\n\n\t/* Options valid for Samsung large page devices */\n\tNAND_SAMSUNG_LP_OPTIONS = (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK),\n\n\t/* Options for new chips with large page size. The pagesize and the\n\t * erasesize is determined from the extended id bytes\n\t */\n\tLP_OPTIONS = (NAND_SAMSUNG_LP_OPTIONS | NAND_NO_READRDY | NAND_NO_AUTOINCR),\n\tLP_OPTIONS16 = (LP_OPTIONS | NAND_BUSWIDTH_16),\n};\n\nenum {\n\t/* Standard NAND flash commands */\n\tNAND_CMD_READ0 = 0x0,\n\tNAND_CMD_READ1 = 0x1,\n\tNAND_CMD_RNDOUT = 0x5,\n\tNAND_CMD_PAGEPROG = 0x10,\n\tNAND_CMD_READOOB = 0x50,\n\tNAND_CMD_ERASE1 = 0x60,\n\tNAND_CMD_STATUS = 0x70,\n\tNAND_CMD_STATUS_MULTI = 0x71,\n\tNAND_CMD_SEQIN = 0x80,\n\tNAND_CMD_RNDIN = 0x85,\n\tNAND_CMD_READID = 0x90,\n\tNAND_CMD_ERASE2 = 0xd0,\n\tNAND_CMD_RESET = 0xff,\n\n\t/* Extended commands for large page devices */\n\tNAND_CMD_READSTART = 0x30,\n\tNAND_CMD_RNDOUTSTART = 0xE0,\n\tNAND_CMD_CACHEDPROG = 0x15,\n};\n\n/* Status bits */\nenum {\n\tNAND_STATUS_FAIL = 0x01,\n\tNAND_STATUS_FAIL_N1 = 0x02,\n\tNAND_STATUS_TRUE_READY = 0x20,\n\tNAND_STATUS_READY = 0x40,\n\tNAND_STATUS_WP = 0x80,\n};\n\n/* OOB (spare) data formats */\nenum oob_formats {\n\tNAND_OOB_NONE = 0x0,\t/* no OOB data at all */\n\tNAND_OOB_RAW = 0x1,\t\t/* raw OOB data (16 bytes for 512b page sizes, 64 bytes for\n\t\t\t\t\t *2048b page sizes) */\n\tNAND_OOB_ONLY = 0x2,\t/* only OOB data */\n\tNAND_OOB_SW_ECC = 0x10,\t/* when writing, use SW ECC (as opposed to no ECC) */\n\tNAND_OOB_HW_ECC = 0x20,\t/* when writing, use HW ECC (as opposed to no ECC) */\n\tNAND_OOB_SW_ECC_KW = 0x40,\t/* when writing, use Marvell's Kirkwood bootrom format */\n\tNAND_OOB_JFFS2 = 0x100,\t/* when writing, use JFFS2 OOB layout */\n\tNAND_OOB_YAFFS2 = 0x100,/* when writing, use YAFFS2 OOB layout */\n};\n\nextern struct nand_device *nand_devices;\n\nstruct nand_device *get_nand_device_by_num(int num);\n\nint nand_page_command(struct nand_device *nand, uint32_t page,\n\t\t      uint8_t cmd, bool oob_only);\n\nint nand_read_data_page(struct nand_device *nand, uint8_t *data, uint32_t size);\nint nand_write_data_page(struct nand_device *nand,\n\t\t\t uint8_t *data, uint32_t size);\n\nint nand_write_finish(struct nand_device *nand);\n\nint nand_read_page_raw(struct nand_device *nand, uint32_t page,\n\t\t       uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);\nint nand_write_page_raw(struct nand_device *nand, uint32_t page,\n\t\t\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);\n\nint nand_read_status(struct nand_device *nand, uint8_t *status);\n\nint nand_calculate_ecc(struct nand_device *nand,\n\t\t       const uint8_t *dat, uint8_t *ecc_code);\nint nand_calculate_ecc_kw(struct nand_device *nand,\n\t\t\t  const uint8_t *dat, uint8_t *ecc_code);\nint nand_correct_data(struct nand_device *nand, u_char *dat,\n\t\tu_char *read_ecc, u_char *calc_ecc);\n\nint nand_register_commands(struct command_context *cmd_ctx);\n\n/** helper for parsing a nand device command argument string */\nCOMMAND_HELPER(nand_command_get_device, unsigned name_index,\n\tstruct nand_device **nand);\n\n\n#define         ERROR_NAND_DEVICE_INVALID               (-1100)\n#define         ERROR_NAND_OPERATION_FAILED             (-1101)\n#define         ERROR_NAND_OPERATION_TIMEOUT    (-1102)\n#define         ERROR_NAND_OPERATION_NOT_SUPPORTED      (-1103)\n#define         ERROR_NAND_DEVICE_NOT_PROBED    (-1104)\n#define         ERROR_NAND_ERROR_CORRECTION_FAILED      (-1105)\n#define         ERROR_NAND_NO_BUFFER                    (-1106)\n\n#endif /* OPENOCD_FLASH_NAND_CORE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/davinci.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by David Brownell                                  *\n ***************************************************************************/\n\n/*\n * DaVinci family NAND controller support for OpenOCD.\n *\n * This driver uses hardware ECC (1-bit or 4-bit) unless\n * the chip is accessed in \"raw\" mode.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"arm_io.h\"\n#include <target/target.h>\n\nenum ecc {\n\tHWECC1,\t\t/* all controllers support 1-bit ECC */\n\tHWECC4,\t\t/* newer chips also have 4-bit ECC hardware */\n\tHWECC4_INFIX,\t/* avoid this layout, except maybe for boot code */\n};\n\nstruct davinci_nand {\n\tuint8_t chipsel;\t\t/* chipselect 0..3 == CS2..CS5 */\n\tuint8_t eccmode;\n\n\t/* Async EMIF controller base */\n\tuint32_t aemif;\n\n\t/* NAND chip addresses */\n\tuint32_t data;\t\t\t\t/* without CLE or ALE */\n\tuint32_t cmd;\t\t\t\t/* with CLE */\n\tuint32_t addr;\t\t\t\t/* with ALE */\n\n\t/* write acceleration */\n\tstruct arm_nand_data io;\n\n\t/* page i/o for the relevant flavor of hardware ECC */\n\tint (*read_page)(struct nand_device *nand, uint32_t page,\n\t\t\t uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);\n\tint (*write_page)(struct nand_device *nand, uint32_t page,\n\t\t\t  uint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size);\n};\n\n#define NANDFCR         0x60\t\t/* flash control register */\n#define NANDFSR         0x64\t\t/* flash status register */\n#define NANDFECC        0x70\t\t/* 1-bit ECC data, CS0, 1st of 4 */\n#define NAND4BITECCLOAD 0xbc\t\t/* 4-bit ECC, load saved values */\n#define NAND4BITECC     0xc0\t\t/* 4-bit ECC data, 1st of 4 */\n#define NANDERRADDR     0xd0\t\t/* 4-bit ECC err addr, 1st of 2 */\n#define NANDERRVAL      0xd8\t\t/* 4-bit ECC err value, 1st of 2 */\n\nstatic int halted(struct target *target, const char *label)\n{\n\tif (target->state == TARGET_HALTED)\n\t\treturn true;\n\n\tLOG_ERROR(\"Target must be halted to use NAND controller (%s)\", label);\n\treturn false;\n}\n\nstatic int davinci_init(struct nand_device *nand)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nandfcr;\n\n\tif (!halted(target, \"init\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\t/* We require something else to have configured AEMIF to talk\n\t * to NAND chip in this range (including timings and width).\n\t */\n\ttarget_read_u32(target, info->aemif + NANDFCR, &nandfcr);\n\tif (!(nandfcr & (1 << info->chipsel))) {\n\t\tLOG_ERROR(\"chip address %08\" PRIx32 \" not NAND-enabled?\", info->data);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/* REVISIT verify:  AxCR must be in 8-bit mode, since that's all we\n\t * tested.  16 bit support should work too; but not with 4-bit ECC.\n\t */\n\n\treturn ERROR_OK;\n}\n\nstatic int davinci_reset(struct nand_device *nand)\n{\n\treturn ERROR_OK;\n}\n\nstatic int davinci_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nandfsr;\n\n\t/* NOTE: return code is zero/error, else success; not ERROR_* */\n\n\tif (!halted(target, \"ready\"))\n\t\treturn 0;\n\n\tdo {\n\t\ttarget_read_u32(target, info->aemif + NANDFSR, &nandfsr);\n\n\t\tif (nandfsr & 0x01)\n\t\t\treturn 1;\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic int davinci_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!halted(target, \"command\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\ttarget_write_u8(target, info->cmd, command);\n\treturn ERROR_OK;\n}\n\nstatic int davinci_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!halted(target, \"address\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\ttarget_write_u8(target, info->addr, address);\n\treturn ERROR_OK;\n}\n\nstatic int davinci_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!halted(target, \"write_data\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\ttarget_write_u8(target, info->data, data);\n\treturn ERROR_OK;\n}\n\nstatic int davinci_read_data(struct nand_device *nand, void *data)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (!halted(target, \"read_data\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\ttarget_read_u8(target, info->data, data);\n\treturn ERROR_OK;\n}\n\n/* REVISIT a bit of native code should let block reads be MUCH faster */\n\nstatic int davinci_read_block_data(struct nand_device *nand,\n\tuint8_t *data, int data_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nfdata = info->data;\n\tuint32_t tmp;\n\n\tif (!halted(target, \"read_block\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\twhile (data_size >= 4) {\n\t\ttarget_read_u32(target, nfdata, &tmp);\n\n\t\tdata[0] = tmp;\n\t\tdata[1] = tmp >> 8;\n\t\tdata[2] = tmp >> 16;\n\t\tdata[3] = tmp >> 24;\n\n\t\tdata_size -= 4;\n\t\tdata += 4;\n\t}\n\n\twhile (data_size > 0) {\n\t\ttarget_read_u8(target, nfdata, data);\n\n\t\tdata_size -= 1;\n\t\tdata += 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int davinci_write_block_data(struct nand_device *nand,\n\tuint8_t *data, int data_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nfdata = info->data;\n\tuint32_t tmp;\n\tint status;\n\n\tif (!halted(target, \"write_block\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\t/* try the fast way first */\n\tstatus = arm_nandwrite(&info->io, data, data_size);\n\tif (status != ERROR_NAND_NO_BUFFER)\n\t\treturn status;\n\n\t/* else do it slowly */\n\twhile (data_size >= 4) {\n\t\ttmp = le_to_h_u32(data);\n\t\ttarget_write_u32(target, nfdata, tmp);\n\n\t\tdata_size -= 4;\n\t\tdata += 4;\n\t}\n\n\twhile (data_size > 0) {\n\t\ttarget_write_u8(target, nfdata, *data);\n\n\t\tdata_size -= 1;\n\t\tdata += 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int davinci_write_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tuint8_t *ooballoc = NULL;\n\tint status;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\tif (!halted(nand->target, \"write_page\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\t/* Always write both data and OOB ... we are not \"raw\" I/O! */\n\tif (!data) {\n\t\tLOG_ERROR(\"Missing NAND data; try 'nand raw_access enable'\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/* If we're not given OOB, write 0xff where we don't write ECC codes. */\n\tswitch (nand->page_size) {\n\t\tcase 512:\n\t\t\toob_size = 16;\n\t\t\tbreak;\n\t\tcase 2048:\n\t\t\toob_size = 64;\n\t\t\tbreak;\n\t\tcase 4096:\n\t\t\toob_size = 128;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (!oob) {\n\t\tooballoc = malloc(oob_size);\n\t\tif (!ooballoc)\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\toob = ooballoc;\n\t\tmemset(oob, 0x0ff, oob_size);\n\t}\n\n\t/* REVISIT avoid wasting SRAM:  unless nand->use_raw is set,\n\t * use 512 byte chunks.  Read side support will often want\n\t * to include oob_size ...\n\t */\n\tinfo->io.chunk_size = nand->page_size;\n\n\tstatus = info->write_page(nand, page, data, data_size, oob, oob_size);\n\tfree(ooballoc);\n\treturn status;\n}\n\nstatic int davinci_read_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\n\tif (!nand->device)\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\tif (!halted(nand->target, \"read_page\"))\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\treturn info->read_page(nand, page, data, data_size, oob, oob_size);\n}\n\nstatic void davinci_write_pagecmd(struct nand_device *nand, uint8_t cmd, uint32_t page)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint page3 = nand->address_cycles - (nand->page_size == 512);\n\n\t/* write command ({page,otp}x{read,program} */\n\ttarget_write_u8(target, info->cmd, cmd);\n\n\t/* column address (beginning-of-page) */\n\ttarget_write_u8(target, info->addr, 0);\n\tif (nand->page_size > 512)\n\t\ttarget_write_u8(target, info->addr, 0);\n\n\t/* page address */\n\ttarget_write_u8(target, info->addr, page);\n\ttarget_write_u8(target, info->addr, page >> 8);\n\tif (page3)\n\t\ttarget_write_u8(target, info->addr, page >> 16);\n\tif (page3 == 2)\n\t\ttarget_write_u8(target, info->addr, page >> 24);\n}\n\nstatic int davinci_seek_column(struct nand_device *nand, uint16_t column)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\t/* Random read, we must have issued a page read already */\n\ttarget_write_u8(target, info->cmd, NAND_CMD_RNDOUT);\n\n\ttarget_write_u8(target, info->addr, column);\n\n\tif (nand->page_size > 512) {\n\t\ttarget_write_u8(target, info->addr, column >> 8);\n\t\ttarget_write_u8(target, info->cmd, NAND_CMD_RNDOUTSTART);\n\t}\n\n\tif (!davinci_nand_ready(nand, 100))\n\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\n\treturn ERROR_OK;\n}\n\nstatic int davinci_writepage_tail(struct nand_device *nand,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint8_t status;\n\n\tif (oob_size)\n\t\tdavinci_write_block_data(nand, oob, oob_size);\n\n\t/* non-cachemode page program */\n\ttarget_write_u8(target, info->cmd, NAND_CMD_PAGEPROG);\n\n\tif (!davinci_nand_ready(nand, 100))\n\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\n\tif (nand_read_status(nand, &status) != ERROR_OK) {\n\t\tLOG_ERROR(\"couldn't read status\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (status & NAND_STATUS_FAIL) {\n\t\tLOG_ERROR(\"write operation failed, status: 0x%02x\", status);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n * All DaVinci family chips support 1-bit ECC on a per-chipselect basis.\n */\nstatic int davinci_write_page_ecc1(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tunsigned oob_offset;\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tconst uint32_t fcr_addr = info->aemif + NANDFCR;\n\tconst uint32_t ecc1_addr = info->aemif + NANDFECC + (4 * info->chipsel);\n\tuint32_t fcr, ecc1;\n\n\t/* Write contiguous ECC bytes starting at specified offset.\n\t * NOTE: Linux reserves twice as many bytes as we need; and\n\t * for 16-bit OOB, those extra bytes are discontiguous.\n\t */\n\tswitch (nand->page_size) {\n\t\tcase 512:\n\t\t\toob_offset = 0;\n\t\t\tbreak;\n\t\tcase 2048:\n\t\t\toob_offset = 40;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\toob_offset = 80;\n\t\t\tbreak;\n\t}\n\n\tdavinci_write_pagecmd(nand, NAND_CMD_SEQIN, page);\n\n\t/* scrub any old ECC state */\n\ttarget_read_u32(target, ecc1_addr, &ecc1);\n\n\ttarget_read_u32(target, fcr_addr, &fcr);\n\tfcr |= 1 << (8 + info->chipsel);\n\n\tdo {\n\t\t/* set \"start csX 1bit ecc\" bit */\n\t\ttarget_write_u32(target, fcr_addr, fcr);\n\n\t\t/* write 512 bytes */\n\t\tdavinci_write_block_data(nand, data, 512);\n\t\tdata += 512;\n\t\tdata_size -= 512;\n\n\t\t/* read the ecc, pack to 3 bytes, and invert so the ecc\n\t\t * in an erased block is correct\n\t\t */\n\t\ttarget_read_u32(target, ecc1_addr, &ecc1);\n\t\tecc1 = (ecc1 & 0x0fff) | ((ecc1 & 0x0fff0000) >> 4);\n\t\tecc1 = ~ecc1;\n\n\t\t/* save correct ECC code into oob data */\n\t\toob[oob_offset++] = (uint8_t)(ecc1);\n\t\toob[oob_offset++] = (uint8_t)(ecc1 >> 8);\n\t\toob[oob_offset++] = (uint8_t)(ecc1 >> 16);\n\n\t} while (data_size);\n\n\t/* write OOB into spare area */\n\treturn davinci_writepage_tail(nand, oob, oob_size);\n}\n\n/*\n * Preferred \"new style\" ECC layout for use with 4-bit ECC.  This somewhat\n * slows down large page reads done with error correction (since the OOB\n * is read first, so its ECC data can be used incrementally), but the\n * manufacturer bad block markers are safe.  Contrast:  old \"infix\" style.\n */\nstatic int davinci_write_page_ecc4(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tstatic const uint8_t ecc512[] = {\n\t\t0, 1, 2, 3, 4,\t/* 5== mfr badblock */\n\t\t6, 7, /* 8..12 for BBT or JFFS2 */ 13, 14, 15,\n\t};\n\tstatic const uint8_t ecc2048[] = {\n\t\t24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n\t\t34, 35, 36, 37, 38, 39, 40, 41, 42, 43,\n\t\t44, 45, 46, 47, 48, 49, 50, 51, 52, 53,\n\t\t54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\n\t};\n\tstatic const uint8_t ecc4096[] = {\n\t\t48,  49,  50,  51,  52,  53,  54,  55,  56,  57,\n\t\t58,  59,  60,  61,  62,  63,  64,  65,  66,  67,\n\t\t68,  69,  70,  71,  72,  73,  74,  75,  76,  77,\n\t\t78,  79,  80,  81,  82,  83,  84,  85,  86,  87,\n\t\t88,  89,  90,  91,  92,  93,  94,  95,  96,  97,\n\t\t98,  99, 100, 101, 102, 103, 104, 105, 106, 107,\n\t\t108, 109, 110, 111, 112, 113, 114, 115, 116, 117,\n\t\t118, 119, 120, 121, 122, 123, 124, 125, 126, 127,\n\t};\n\n\tstruct davinci_nand *info = nand->controller_priv;\n\tconst uint8_t *l;\n\tstruct target *target = nand->target;\n\tconst uint32_t fcr_addr = info->aemif + NANDFCR;\n\tconst uint32_t ecc4_addr = info->aemif + NAND4BITECC;\n\tuint32_t fcr, ecc4;\n\n\t/* Use the same ECC layout Linux uses.  For small page chips\n\t * it's a bit cramped.\n\t *\n\t * NOTE:  at this writing, 4KB pages have issues in Linux\n\t * because they need more than 64 bytes of ECC data, which\n\t * the standard ECC logic can't handle.\n\t */\n\tswitch (nand->page_size) {\n\t\tcase 512:\n\t\t\tl = ecc512;\n\t\t\tbreak;\n\t\tcase 2048:\n\t\t\tl = ecc2048;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tl = ecc4096;\n\t\t\tbreak;\n\t}\n\n\tdavinci_write_pagecmd(nand, NAND_CMD_SEQIN, page);\n\n\t/* scrub any old ECC state */\n\ttarget_read_u32(target, info->aemif + NANDERRVAL, &ecc4);\n\n\ttarget_read_u32(target, fcr_addr, &fcr);\n\tfcr &= ~(0x03 << 4);\n\tfcr |= (1 << 12) | (info->chipsel << 4);\n\n\tdo {\n\t\tuint32_t raw_ecc[4], *p;\n\t\tint i;\n\n\t\t/* start 4bit ecc on csX */\n\t\ttarget_write_u32(target, fcr_addr, fcr);\n\n\t\t/* write 512 bytes */\n\t\tdavinci_write_block_data(nand, data, 512);\n\t\tdata += 512;\n\t\tdata_size -= 512;\n\n\t\t/* read the ecc, then save it into 10 bytes in the oob */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\ttarget_read_u32(target, ecc4_addr + 4 * i, &raw_ecc[i]);\n\t\t\traw_ecc[i] &= 0x03ff03ff;\n\t\t}\n\t\tfor (i = 0, p = raw_ecc; i < 2; i++, p += 2) {\n\t\t\toob[*l++] = p[0]        & 0xff;\n\t\t\toob[*l++] = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);\n\t\t\toob[*l++] = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);\n\t\t\toob[*l++] = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);\n\t\t\toob[*l++] = (p[1] >> 18) & 0xff;\n\t\t}\n\n\t} while (data_size);\n\n\t/* write OOB into spare area */\n\treturn davinci_writepage_tail(nand, oob, oob_size);\n}\n\n/*\n * \"Infix\" OOB ... like Linux ECC_HW_SYNDROME.  Avoided because it trashes\n * manufacturer bad block markers, except on small page chips.  Once you\n * write to a page using this scheme, you need specialized code to update\n * it (code which ignores now-invalid bad block markers).\n *\n * This is needed *only* to support older firmware.  Older ROM Boot Loaders\n * need it to read their second stage loader (UBL) into SRAM, but from then\n * on the whole system can use the cleaner non-infix layouts.  Systems with\n * older second stage loaders (ABL/U-Boot, etc) or other system software\n * (MVL 4.x/5.x kernels, filesystems, etc) may need it more generally.\n */\nstatic int davinci_write_page_ecc4infix(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tstruct davinci_nand *info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tconst uint32_t fcr_addr = info->aemif + NANDFCR;\n\tconst uint32_t ecc4_addr = info->aemif + NAND4BITECC;\n\tuint32_t fcr, ecc4;\n\n\tdavinci_write_pagecmd(nand, NAND_CMD_SEQIN, page);\n\n\t/* scrub any old ECC state */\n\ttarget_read_u32(target, info->aemif + NANDERRVAL, &ecc4);\n\n\ttarget_read_u32(target, fcr_addr, &fcr);\n\tfcr &= ~(0x03 << 4);\n\tfcr |= (1 << 12) | (info->chipsel << 4);\n\n\tdo {\n\t\tuint32_t raw_ecc[4], *p;\n\t\tuint8_t *l;\n\t\tint i;\n\n\t\t/* start 4bit ecc on csX */\n\t\ttarget_write_u32(target, fcr_addr, fcr);\n\n\t\t/* write 512 bytes */\n\t\tdavinci_write_block_data(nand, data, 512);\n\t\tdata += 512;\n\t\tdata_size -= 512;\n\n\t\t/* read the ecc */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\ttarget_read_u32(target, ecc4_addr + 4 * i, &raw_ecc[i]);\n\t\t\traw_ecc[i] &= 0x03ff03ff;\n\t\t}\n\n\t\t/* skip 6 bytes of prepad, then pack 10 packed ecc bytes */\n\t\tfor (i = 0, l = oob + 6, p = raw_ecc; i < 2; i++, p += 2) {\n\t\t\t*l++ = p[0]        & 0xff;\n\t\t\t*l++ = ((p[0] >>  8) & 0x03) | ((p[0] >> 14) & 0xfc);\n\t\t\t*l++ = ((p[0] >> 22) & 0x0f) | ((p[1] <<  4) & 0xf0);\n\t\t\t*l++ = ((p[1] >>  4) & 0x3f) | ((p[1] >> 10) & 0xc0);\n\t\t\t*l++ = (p[1] >> 18) & 0xff;\n\t\t}\n\n\t\t/* write this \"out-of-band\" data -- infix */\n\t\tdavinci_write_block_data(nand, oob, 16);\n\t\toob += 16;\n\t} while (data_size);\n\n\t/* the last data and OOB writes included the spare area */\n\treturn davinci_writepage_tail(nand, NULL, 0);\n}\n\nstatic int davinci_read_page_ecc4infix(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size, uint8_t *oob, uint32_t oob_size)\n{\n\tint read_size;\n\tint want_col, at_col;\n\tint ret;\n\n\tdavinci_write_pagecmd(nand, NAND_CMD_READ0, page);\n\n\t/* large page devices need a start command */\n\tif (nand->page_size > 512)\n\t\tdavinci_command(nand, NAND_CMD_READSTART);\n\n\tif (!davinci_nand_ready(nand, 100))\n\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\n\t/* NOTE:  not bothering to compute and use ECC data for now */\n\n\twant_col = 0;\n\tat_col = 0;\n\twhile ((data && data_size) || (oob && oob_size)) {\n\n\t\tif (data && data_size) {\n\t\t\tif (want_col != at_col) {\n\t\t\t\t/* Reads are slow, so seek past them when we can */\n\t\t\t\tret  = davinci_seek_column(nand, want_col);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\t\t\t\tat_col = want_col;\n\t\t\t}\n\t\t\t/* read 512 bytes or data_size, whichever is smaller*/\n\t\t\tread_size = data_size > 512 ? 512 : data_size;\n\t\t\tdavinci_read_block_data(nand, data, read_size);\n\t\t\tdata += read_size;\n\t\t\tdata_size -= read_size;\n\t\t\tat_col += read_size;\n\t\t}\n\t\twant_col += 512;\n\n\t\tif (oob && oob_size) {\n\t\t\tif (want_col != at_col) {\n\t\t\t\tret  = davinci_seek_column(nand, want_col);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\t\t\t\tat_col = want_col;\n\t\t\t}\n\t\t\t/* read this \"out-of-band\" data -- infix */\n\t\t\tread_size = oob_size > 16 ? 16 : oob_size;\n\t\t\tdavinci_read_block_data(nand, oob, read_size);\n\t\t\toob += read_size;\n\t\t\toob_size -= read_size;\n\t\t\tat_col += read_size;\n\t\t}\n\t\twant_col += 16;\n\t}\n\treturn ERROR_OK;\n}\n\nNAND_DEVICE_COMMAND_HANDLER(davinci_nand_device_command)\n{\n\tstruct davinci_nand *info;\n\tunsigned long chip, aemif;\n\tenum ecc eccmode;\n\tint chipsel;\n\n\t/* arguments:\n\t *  - \"davinci\"\n\t *  - target\n\t *  - nand chip address\n\t *  - ecc mode\n\t *  - aemif address\n\t * Plus someday, optionally, ALE and CLE masks.\n\t */\n\tif (CMD_ARGC < 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], chip);\n\tif (chip == 0) {\n\t\tLOG_ERROR(\"Invalid NAND chip address %s\", CMD_ARGV[2]);\n\t\tgoto fail;\n\t}\n\n\tif (strcmp(CMD_ARGV[3], \"hwecc1\") == 0)\n\t\teccmode = HWECC1;\n\telse if (strcmp(CMD_ARGV[3], \"hwecc4\") == 0)\n\t\teccmode = HWECC4;\n\telse if (strcmp(CMD_ARGV[3], \"hwecc4_infix\") == 0)\n\t\teccmode = HWECC4_INFIX;\n\telse {\n\t\tLOG_ERROR(\"Invalid ecc mode %s\", CMD_ARGV[3]);\n\t\tgoto fail;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[4], aemif);\n\tif (aemif == 0) {\n\t\tLOG_ERROR(\"Invalid AEMIF controller address %s\", CMD_ARGV[4]);\n\t\tgoto fail;\n\t}\n\n\t/* REVISIT what we'd *like* to do is look up valid ranges using\n\t * target-specific declarations, and not even need to pass the\n\t * AEMIF controller address.\n\t */\n\tif (aemif == 0x01e00000\t\t\t/* dm6446, dm357 */\n\t\t\t|| aemif == 0x01e10000\t\t/* dm335, dm355 */\n\t\t\t|| aemif == 0x01d10000\t\t/* dm365 */\n\t\t) {\n\t\tif (chip < 0x02000000 || chip >= 0x0a000000) {\n\t\t\tLOG_ERROR(\"NAND address %08lx out of range?\", chip);\n\t\t\tgoto fail;\n\t\t}\n\t\tchipsel = (chip - 0x02000000) >> 25;\n\t} else {\n\t\tLOG_ERROR(\"unrecognized AEMIF controller address %08lx\", aemif);\n\t\tgoto fail;\n\t}\n\n\tinfo = calloc(1, sizeof(*info));\n\tif (!info)\n\t\tgoto fail;\n\n\tinfo->eccmode = eccmode;\n\tinfo->chipsel = chipsel;\n\tinfo->aemif = aemif;\n\tinfo->data = chip;\n\tinfo->cmd = chip | 0x10;\n\tinfo->addr = chip | 0x08;\n\n\tnand->controller_priv = info;\n\n\tinfo->io.target = nand->target;\n\tinfo->io.data = info->data;\n\tinfo->io.op = ARM_NAND_NONE;\n\n\t/* NOTE:  for now we don't do any error correction on read.\n\t * Nothing else in OpenOCD currently corrects read errors,\n\t * and in any case it's *writing* that we care most about.\n\t */\n\tinfo->read_page = nand_read_page_raw;\n\n\tswitch (eccmode) {\n\t\tcase HWECC1:\n\t\t\t/* ECC_HW, 1-bit corrections, 3 bytes ECC per 512 data bytes */\n\t\t\tinfo->write_page = davinci_write_page_ecc1;\n\t\t\tbreak;\n\t\tcase HWECC4:\n\t\t\t/* ECC_HW, 4-bit corrections, 10 bytes ECC per 512 data bytes */\n\t\t\tinfo->write_page = davinci_write_page_ecc4;\n\t\t\tbreak;\n\t\tcase HWECC4_INFIX:\n\t\t\t/* Same 4-bit ECC HW, with problematic page/ecc layout */\n\t\t\tinfo->read_page = davinci_read_page_ecc4infix;\n\t\t\tinfo->write_page = davinci_write_page_ecc4infix;\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n\nfail:\n\treturn ERROR_NAND_OPERATION_FAILED;\n}\n\nstruct nand_flash_controller davinci_nand_controller = {\n\t.name                   = \"davinci\",\n\t.usage                  = \"chip_addr hwecc_mode aemif_addr\",\n\t.nand_device_command    = davinci_nand_device_command,\n\t.init                   = davinci_init,\n\t.reset                  = davinci_reset,\n\t.command                = davinci_command,\n\t.address                = davinci_address,\n\t.write_data             = davinci_write_data,\n\t.read_data              = davinci_read_data,\n\t.write_page             = davinci_write_page,\n\t.read_page              = davinci_read_page,\n\t.write_block_data       = davinci_write_block_data,\n\t.read_block_data        = davinci_read_block_data,\n\t.nand_ready             = davinci_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/driver.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include \"core.h\"\n#include \"driver.h\"\n\nstatic struct nand_flash_controller *nand_flash_controllers[] = {\n\t&nonce_nand_controller,\n\t&davinci_nand_controller,\n\t&lpc3180_nand_controller,\n\t&lpc32xx_nand_controller,\n\t&orion_nand_controller,\n\t&s3c2410_nand_controller,\n\t&s3c2412_nand_controller,\n\t&s3c2440_nand_controller,\n\t&s3c2443_nand_controller,\n\t&s3c6400_nand_controller,\n\t&mxc_nand_flash_controller,\n\t&imx31_nand_flash_controller,\n\t&at91sam9_nand_controller,\n\t&nuc910_nand_controller,\n\tNULL\n};\n\nstruct nand_flash_controller *nand_driver_find_by_name(const char *name)\n{\n\tfor (unsigned i = 0; nand_flash_controllers[i]; i++) {\n\t\tstruct nand_flash_controller *controller = nand_flash_controllers[i];\n\t\tif (strcmp(name, controller->name) == 0)\n\t\t\treturn controller;\n\t}\n\treturn NULL;\n}\nint nand_driver_walk(nand_driver_walker_t f, void *x)\n{\n\tfor (unsigned i = 0; nand_flash_controllers[i]; i++) {\n\t\tint retval = (*f)(nand_flash_controllers[i], x);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/driver.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_DRIVER_H\n#define OPENOCD_FLASH_NAND_DRIVER_H\n\nstruct nand_device;\n\n#define __NAND_DEVICE_COMMAND(name) \\\n\tCOMMAND_HELPER(name, struct nand_device *nand)\n\n/**\n * Interface for NAND flash controllers.  Not all of these functions are\n * required for full functionality of the NAND driver, but better performance\n * can be achieved by implementing each function.\n */\nstruct nand_flash_controller {\n\t/** Driver name that is used to select it from configuration files. */\n\tconst char *name;\n\n\t/** Usage of flash command registration. */\n\tconst char *usage;\n\n\tconst struct command_registration *commands;\n\n\t/** NAND device command called when driver is instantiated during configuration. */\n\t__NAND_DEVICE_COMMAND((*nand_device_command));\n\n\t/** Initialize the NAND device. */\n\tint (*init)(struct nand_device *nand);\n\n\t/** Reset the NAND device. */\n\tint (*reset)(struct nand_device *nand);\n\n\t/** Issue a command to the NAND device. */\n\tint (*command)(struct nand_device *nand, uint8_t command);\n\n\t/** Write an address to the NAND device. */\n\tint (*address)(struct nand_device *nand, uint8_t address);\n\n\t/** Write word of data to the NAND device. */\n\tint (*write_data)(struct nand_device *nand, uint16_t data);\n\n\t/** Read word of data from the NAND device. */\n\tint (*read_data)(struct nand_device *nand, void *data);\n\n\t/** Write a block of data to the NAND device. */\n\tint (*write_block_data)(struct nand_device *nand, uint8_t *data, int size);\n\n\t/** Read a block of data from the NAND device. */\n\tint (*read_block_data)(struct nand_device *nand, uint8_t *data, int size);\n\n\t/** Write a page to the NAND device. */\n\tint (*write_page)(struct nand_device *nand, uint32_t page, uint8_t *data,\n\t\t\t  uint32_t data_size, uint8_t *oob, uint32_t oob_size);\n\n\t/** Read a page from the NAND device. */\n\tint (*read_page)(struct nand_device *nand, uint32_t page, uint8_t *data, uint32_t data_size,\n\t\t\t uint8_t *oob, uint32_t oob_size);\n\n\t/** Check if the NAND device is ready for more instructions with timeout. */\n\tint (*nand_ready)(struct nand_device *nand, int timeout);\n};\n\n#define NAND_DEVICE_COMMAND_HANDLER(name) static __NAND_DEVICE_COMMAND(name)\n\n/**\n * Find a NAND flash controller by name.\n * @param name Identifies the NAND controller to find.\n * @returns The nand_flash_controller named @c name, or NULL if not found.\n */\nstruct nand_flash_controller *nand_driver_find_by_name(const char *name);\n\n/** Signature for callback functions passed to nand_driver_walk */\ntypedef int (*nand_driver_walker_t)(struct nand_flash_controller *c, void *);\n/**\n * Walk the list of drivers, encapsulating the data structure type.\n * Application state/context can be passed through the @c x pointer.\n * @param f The callback function to invoke for each function.\n * @param x For use as private data storage, passed directly to @c f.\n * @returns ERROR_OK if successful, or the non-zero return value of @c f.\n * This allows a walker to terminate the loop early.\n */\nint nand_driver_walk(nand_driver_walker_t f, void *x);\n\nextern struct nand_flash_controller at91sam9_nand_controller;\nextern struct nand_flash_controller davinci_nand_controller;\nextern struct nand_flash_controller imx31_nand_flash_controller;\nextern struct nand_flash_controller lpc3180_nand_controller;\nextern struct nand_flash_controller lpc32xx_nand_controller;\nextern struct nand_flash_controller mxc_nand_flash_controller;\nextern struct nand_flash_controller nonce_nand_controller;\nextern struct nand_flash_controller nuc910_nand_controller;\nextern struct nand_flash_controller orion_nand_controller;\nextern struct nand_flash_controller s3c2410_nand_controller;\nextern struct nand_flash_controller s3c2412_nand_controller;\nextern struct nand_flash_controller s3c2440_nand_controller;\nextern struct nand_flash_controller s3c2443_nand_controller;\nextern struct nand_flash_controller s3c6400_nand_controller;\n\n#endif /* OPENOCD_FLASH_NAND_DRIVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/ecc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later WITH eCos-exception-2.0\n\n/*\n * This file contains an ECC algorithm from Toshiba that allows for detection\n * and correction of 1-bit errors in a 256 byte block of data.\n *\n * [ Extracted from the initial code found in some early Linux versions.\n *   The current Linux code is bigger while being faster, but this is of\n *   no real benefit when the bottleneck largely remains the JTAG link.  ]\n *\n * Copyright (C) 2000-2004 Steven J. Hill (sjhill at realitydiluted.com)\n *                         Toshiba America Electronics Components, Inc.\n *\n * Copyright (C) 2006 Thomas Gleixner <tglx at linutronix.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"core.h\"\n\n/*\n * Pre-calculated 256-way 1 byte column parity\n */\nstatic const uint8_t nand_ecc_precalc_table[] = {\n\t0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,\n\t0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,\n\t0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,\n\t0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,\n\t0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,\n\t0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,\n\t0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,\n\t0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,\n\t0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,\n\t0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,\n\t0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,\n\t0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,\n\t0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,\n\t0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,\n\t0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,\n\t0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00\n};\n\n/*\n * nand_calculate_ecc - Calculate 3-byte ECC for 256-byte block\n */\nint nand_calculate_ecc(struct nand_device *nand, const uint8_t *dat, uint8_t *ecc_code)\n{\n\tuint8_t idx, reg1, reg2, reg3, tmp1, tmp2;\n\tint i;\n\n\t/* Initialize variables */\n\treg1 = reg2 = reg3 = 0;\n\n\t/* Build up column parity */\n\tfor (i = 0; i < 256; i++) {\n\t\t/* Get CP0 - CP5 from table */\n\t\tidx = nand_ecc_precalc_table[*dat++];\n\t\treg1 ^= (idx & 0x3f);\n\n\t\t/* All bit XOR = 1 ? */\n\t\tif (idx & 0x40) {\n\t\t\treg3 ^= (uint8_t) i;\n\t\t\treg2 ^= ~((uint8_t) i);\n\t\t}\n\t}\n\n\t/* Create non-inverted ECC code from line parity */\n\ttmp1  = (reg3 & 0x80) >> 0; /* B7 -> B7 */\n\ttmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */\n\ttmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */\n\ttmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */\n\ttmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */\n\ttmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */\n\ttmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */\n\ttmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */\n\n\ttmp2  = (reg3 & 0x08) << 4; /* B3 -> B7 */\n\ttmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */\n\ttmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */\n\ttmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */\n\ttmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */\n\ttmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */\n\ttmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */\n\ttmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */\n\n\t/* Calculate final ECC code */\n#ifdef NAND_ECC_SMC\n\tecc_code[0] = ~tmp2;\n\tecc_code[1] = ~tmp1;\n#else\n\tecc_code[0] = ~tmp1;\n\tecc_code[1] = ~tmp2;\n#endif\n\tecc_code[2] = ((~reg1) << 2) | 0x03;\n\n\treturn 0;\n}\n\nstatic inline int countbits(uint32_t b)\n{\n\tint res = 0;\n\n\tfor (; b; b >>= 1)\n\t\tres += b & 0x01;\n\treturn res;\n}\n\n/**\n * nand_correct_data - Detect and correct a 1 bit error for 256 byte block\n */\nint nand_correct_data(struct nand_device *nand, u_char *dat,\n\t\tu_char *read_ecc, u_char *calc_ecc)\n{\n\tuint8_t s0, s1, s2;\n\n#ifdef NAND_ECC_SMC\n\ts0 = calc_ecc[0] ^ read_ecc[0];\n\ts1 = calc_ecc[1] ^ read_ecc[1];\n\ts2 = calc_ecc[2] ^ read_ecc[2];\n#else\n\ts1 = calc_ecc[0] ^ read_ecc[0];\n\ts0 = calc_ecc[1] ^ read_ecc[1];\n\ts2 = calc_ecc[2] ^ read_ecc[2];\n#endif\n\tif ((s0 | s1 | s2) == 0)\n\t\treturn 0;\n\n\t/* Check for a single bit error */\n\tif (((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&\n\t\t\t((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&\n\t\t\t((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {\n\n\t\tuint32_t byteoffs, bitnum;\n\n\t\tbyteoffs = (s1 << 0) & 0x80;\n\t\tbyteoffs |= (s1 << 1) & 0x40;\n\t\tbyteoffs |= (s1 << 2) & 0x20;\n\t\tbyteoffs |= (s1 << 3) & 0x10;\n\n\t\tbyteoffs |= (s0 >> 4) & 0x08;\n\t\tbyteoffs |= (s0 >> 3) & 0x04;\n\t\tbyteoffs |= (s0 >> 2) & 0x02;\n\t\tbyteoffs |= (s0 >> 1) & 0x01;\n\n\t\tbitnum = (s2 >> 5) & 0x04;\n\t\tbitnum |= (s2 >> 4) & 0x02;\n\t\tbitnum |= (s2 >> 3) & 0x01;\n\n\t\tdat[byteoffs] ^= (1 << bitnum);\n\n\t\treturn 1;\n\t}\n\n\tif (countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 << 16)) == 1)\n\t\treturn 1;\n\n\treturn -1;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/ecc_kw.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Reed-Solomon ECC handling for the Marvell Kirkwood SOC\n * Copyright (C) 2009 Marvell Semiconductor, Inc.\n *\n * Authors: Lennert Buytenhek <buytenh@wantstofly.org>\n *          Nicolas Pitre <nico@fluxnic.net>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"core.h\"\n\n/*****************************************************************************\n * Arithmetic in GF(2^10) (\"F\") modulo x^10 + x^3 + 1.\n *\n * For multiplication, a discrete log/exponent table is used, with\n * primitive element x (F is a primitive field, so x is primitive).\n */\n#define MODPOLY 0x409\t\t/* x^10 + x^3 + 1 in binary */\n\n/*\n * Maps an integer a [0..1022] to a polynomial b = gf_exp[a] in\n * GF(2^10) mod x^10 + x^3 + 1 such that b = x ^ a.  There's two\n * identical copies of this array back-to-back so that we can save\n * the mod 1023 operation when doing a GF multiplication.\n */\nstatic uint16_t gf_exp[1023 + 1023];\n\n/*\n * Maps a polynomial b in GF(2^10) mod x^10 + x^3 + 1 to an index\n * a = gf_log[b] in [0..1022] such that b = x ^ a.\n */\nstatic uint16_t gf_log[1024];\n\nstatic void gf_build_log_exp_table(void)\n{\n\tint i;\n\tint p_i;\n\n\t/*\n\t * p_i = x ^ i\n\t *\n\t * Initialise to 1 for i = 0.\n\t */\n\tp_i = 1;\n\n\tfor (i = 0; i < 1023; i++) {\n\t\tgf_exp[i] = p_i;\n\t\tgf_exp[i + 1023] = p_i;\n\t\tgf_log[p_i] = i;\n\n\t\t/*\n\t\t * p_i = p_i * x\n\t\t */\n\t\tp_i <<= 1;\n\t\tif (p_i & (1 << 10))\n\t\t\tp_i ^= MODPOLY;\n\t}\n}\n\n\n/*****************************************************************************\n * Reed-Solomon code\n *\n * This implements a (1023,1015) Reed-Solomon ECC code over GF(2^10)\n * mod x^10 + x^3 + 1, shortened to (520,512).  The ECC data consists\n * of 8 10-bit symbols, or 10 8-bit bytes.\n *\n * Given 512 bytes of data, computes 10 bytes of ECC.\n *\n * This is done by converting the 512 bytes to 512 10-bit symbols\n * (elements of F), interpreting those symbols as a polynomial in F[X]\n * by taking symbol 0 as the coefficient of X^8 and symbol 511 as the\n * coefficient of X^519, and calculating the residue of that polynomial\n * divided by the generator polynomial, which gives us the 8 ECC symbols\n * as the remainder.  Finally, we convert the 8 10-bit ECC symbols to 10\n * 8-bit bytes.\n *\n * The generator polynomial is hardcoded, as that is faster, but it\n * can be computed by taking the primitive element a = x (in F), and\n * constructing a polynomial in F[X] with roots a, a^2, a^3, ..., a^8\n * by multiplying the minimal polynomials for those roots (which are\n * just 'x - a^i' for each i).\n *\n * Note: due to unfortunate circumstances, the bootrom in the Kirkwood SOC\n * expects the ECC to be computed backward, i.e. from the last byte down\n * to the first one.\n */\nint nand_calculate_ecc_kw(struct nand_device *nand, const uint8_t *data, uint8_t *ecc)\n{\n\tunsigned int r7, r6, r5, r4, r3, r2, r1, r0;\n\tint i;\n\tstatic int tables_initialized;\n\n\tif (!tables_initialized) {\n\t\tgf_build_log_exp_table();\n\t\ttables_initialized = 1;\n\t}\n\n\t/*\n\t * Load bytes 504..511 of the data into r.\n\t */\n\tr0 = data[504];\n\tr1 = data[505];\n\tr2 = data[506];\n\tr3 = data[507];\n\tr4 = data[508];\n\tr5 = data[509];\n\tr6 = data[510];\n\tr7 = data[511];\n\n\t/*\n\t * Shift bytes 503..0 (in that order) into r0, followed\n\t * by eight zero bytes, while reducing the polynomial by the\n\t * generator polynomial in every step.\n\t */\n\tfor (i = 503; i >= -8; i--) {\n\t\tunsigned int d;\n\n\t\td = 0;\n\t\tif (i >= 0)\n\t\t\td = data[i];\n\n\t\tif (r7) {\n\t\t\tuint16_t *t = gf_exp + gf_log[r7];\n\n\t\t\tr7 = r6 ^ t[0x21c];\n\t\t\tr6 = r5 ^ t[0x181];\n\t\t\tr5 = r4 ^ t[0x18e];\n\t\t\tr4 = r3 ^ t[0x25f];\n\t\t\tr3 = r2 ^ t[0x197];\n\t\t\tr2 = r1 ^ t[0x193];\n\t\t\tr1 = r0 ^ t[0x237];\n\t\t\tr0 = d  ^ t[0x024];\n\t\t} else {\n\t\t\tr7 = r6;\n\t\t\tr6 = r5;\n\t\t\tr5 = r4;\n\t\t\tr4 = r3;\n\t\t\tr3 = r2;\n\t\t\tr2 = r1;\n\t\t\tr1 = r0;\n\t\t\tr0 = d;\n\t\t}\n\t}\n\n\tecc[0] = r0;\n\tecc[1] = (r0 >> 8) | (r1 << 2);\n\tecc[2] = (r1 >> 6) | (r2 << 4);\n\tecc[3] = (r2 >> 4) | (r3 << 6);\n\tecc[4] = (r3 >> 2);\n\tecc[5] = r4;\n\tecc[6] = (r4 >> 8) | (r5 << 2);\n\tecc[7] = (r5 >> 6) | (r6 << 4);\n\tecc[8] = (r6 >> 4) | (r7 << 6);\n\tecc[9] = (r7 >> 2);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/fileio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de>               *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *                                                                         *\n *   Partially based on drivers/mtd/nand_ids.c from Linux.                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"core.h\"\n#include \"fileio.h\"\n\nstatic struct nand_ecclayout nand_oob_16 = {\n\t.eccbytes = 6,\n\t.eccpos = {0, 1, 2, 3, 6, 7},\n\t.oobfree = {\n\t\t{.offset = 8,\n\t\t .length = 8}\n\t}\n};\n\nstatic struct nand_ecclayout nand_oob_64 = {\n\t.eccbytes = 24,\n\t.eccpos = {\n\t\t40, 41, 42, 43, 44, 45, 46, 47,\n\t\t48, 49, 50, 51, 52, 53, 54, 55,\n\t\t56, 57, 58, 59, 60, 61, 62, 63\n\t},\n\t.oobfree = {\n\t\t{.offset = 2,\n\t\t .length = 38}\n\t}\n};\n\nvoid nand_fileio_init(struct nand_fileio_state *state)\n{\n\tmemset(state, 0, sizeof(*state));\n\tstate->oob_format = NAND_OOB_NONE;\n}\n\nint nand_fileio_start(struct command_invocation *cmd,\n\tstruct nand_device *nand, const char *filename, int filemode,\n\tstruct nand_fileio_state *state)\n{\n\tif (state->address % nand->page_size) {\n\t\tcommand_print(cmd, \"only page-aligned addresses are supported\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tduration_start(&state->bench);\n\n\tif (filename) {\n\t\tint retval = fileio_open(&state->fileio, filename, filemode, FILEIO_BINARY);\n\t\tif (retval != ERROR_OK) {\n\t\t\tconst char *msg = (filemode == FILEIO_READ) ? \"read\" : \"write\";\n\t\t\tcommand_print(cmd, \"failed to open '%s' for %s access\",\n\t\t\t\tfilename, msg);\n\t\t\treturn retval;\n\t\t}\n\t\tstate->file_opened = true;\n\t}\n\n\tif (!(state->oob_format & NAND_OOB_ONLY)) {\n\t\tstate->page_size = nand->page_size;\n\t\tstate->page = malloc(nand->page_size);\n\t}\n\n\tif (state->oob_format & (NAND_OOB_RAW | NAND_OOB_SW_ECC | NAND_OOB_SW_ECC_KW)) {\n\t\tif (nand->page_size == 512) {\n\t\t\tstate->oob_size = 16;\n\t\t\tstate->eccpos = nand_oob_16.eccpos;\n\t\t} else if (nand->page_size == 2048)   {\n\t\t\tstate->oob_size = 64;\n\t\t\tstate->eccpos = nand_oob_64.eccpos;\n\t\t}\n\t\tstate->oob = malloc(state->oob_size);\n\t}\n\n\treturn ERROR_OK;\n}\nint nand_fileio_cleanup(struct nand_fileio_state *state)\n{\n\tif (state->file_opened)\n\t\tfileio_close(state->fileio);\n\n\tfree(state->oob);\n\tstate->oob = NULL;\n\n\tfree(state->page);\n\tstate->page = NULL;\n\treturn ERROR_OK;\n}\nint nand_fileio_finish(struct nand_fileio_state *state)\n{\n\tnand_fileio_cleanup(state);\n\treturn duration_measure(&state->bench);\n}\n\nCOMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,\n\tstruct nand_device **dev, enum fileio_access filemode,\n\tbool need_size, bool sw_ecc)\n{\n\tnand_fileio_init(state);\n\n\tunsigned minargs = need_size ? 4 : 3;\n\tif (minargs > CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct nand_device *nand;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &nand);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!nand->device) {\n\t\tcommand_print(CMD, \"#%s: not probed\", CMD_ARGV[0]);\n\t\treturn ERROR_NAND_DEVICE_NOT_PROBED;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], state->address);\n\tif (need_size) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], state->size);\n\t\tif (state->size % nand->page_size) {\n\t\t\tcommand_print(CMD, \"only page-aligned sizes are supported\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tif (minargs < CMD_ARGC) {\n\t\tfor (unsigned i = minargs; i < CMD_ARGC; i++) {\n\t\t\tif (!strcmp(CMD_ARGV[i], \"oob_raw\"))\n\t\t\t\tstate->oob_format |= NAND_OOB_RAW;\n\t\t\telse if (!strcmp(CMD_ARGV[i], \"oob_only\"))\n\t\t\t\tstate->oob_format |= NAND_OOB_RAW | NAND_OOB_ONLY;\n\t\t\telse if (sw_ecc && !strcmp(CMD_ARGV[i], \"oob_softecc\"))\n\t\t\t\tstate->oob_format |= NAND_OOB_SW_ECC;\n\t\t\telse if (sw_ecc && !strcmp(CMD_ARGV[i], \"oob_softecc_kw\"))\n\t\t\t\tstate->oob_format |= NAND_OOB_SW_ECC_KW;\n\t\t\telse {\n\t\t\t\tcommand_print(CMD, \"unknown option: %s\", CMD_ARGV[i]);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = nand_fileio_start(CMD, nand, CMD_ARGV[1], filemode, state);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!need_size) {\n\t\tsize_t filesize;\n\t\tretval = fileio_size(state->fileio, &filesize);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tstate->size = filesize;\n\t}\n\n\t*dev = nand;\n\n\treturn ERROR_OK;\n}\n\n/**\n * @returns If no error occurred, returns number of bytes consumed;\n * otherwise, returns a negative error code.)\n */\nint nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s)\n{\n\tsize_t total_read = 0;\n\tsize_t one_read;\n\n\tif (s->page) {\n\t\tfileio_read(s->fileio, s->page_size, s->page, &one_read);\n\t\tif (one_read < s->page_size)\n\t\t\tmemset(s->page + one_read, 0xff, s->page_size - one_read);\n\t\ttotal_read += one_read;\n\t}\n\n\tif (s->oob_format & NAND_OOB_SW_ECC) {\n\t\tuint8_t ecc[3];\n\t\tmemset(s->oob, 0xff, s->oob_size);\n\t\tfor (uint32_t i = 0, j = 0; i < s->page_size; i += 256) {\n\t\t\tnand_calculate_ecc(nand, s->page + i, ecc);\n\t\t\ts->oob[s->eccpos[j++]] = ecc[0];\n\t\t\ts->oob[s->eccpos[j++]] = ecc[1];\n\t\t\ts->oob[s->eccpos[j++]] = ecc[2];\n\t\t}\n\t} else if (s->oob_format & NAND_OOB_SW_ECC_KW)   {\n\t\t/*\n\t\t * In this case eccpos is not used as\n\t\t * the ECC data is always stored contiguously\n\t\t * at the end of the OOB area.  It consists\n\t\t * of 10 bytes per 512-byte data block.\n\t\t */\n\t\tuint8_t *ecc = s->oob + s->oob_size - s->page_size / 512 * 10;\n\t\tmemset(s->oob, 0xff, s->oob_size);\n\t\tfor (uint32_t i = 0; i < s->page_size; i += 512) {\n\t\t\tnand_calculate_ecc_kw(nand, s->page + i, ecc);\n\t\t\tecc += 10;\n\t\t}\n\t} else if (s->oob)   {\n\t\tfileio_read(s->fileio, s->oob_size, s->oob, &one_read);\n\t\tif (one_read < s->oob_size)\n\t\t\tmemset(s->oob + one_read, 0xff, s->oob_size - one_read);\n\t\ttotal_read += one_read;\n\t}\n\treturn total_read;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/fileio.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_FILEIO_H\n#define OPENOCD_FLASH_NAND_FILEIO_H\n\n#include <helper/time_support.h>\n#include <helper/fileio.h>\n\nstruct nand_fileio_state {\n\tuint32_t address;\n\tuint32_t size;\n\n\tuint8_t *page;\n\tuint32_t page_size;\n\n\tenum oob_formats oob_format;\n\tuint8_t *oob;\n\tuint32_t oob_size;\n\n\tconst int *eccpos;\n\n\tbool file_opened;\n\tstruct fileio *fileio;\n\n\tstruct duration bench;\n};\n\nvoid nand_fileio_init(struct nand_fileio_state *state);\nint nand_fileio_start(struct command_invocation *cmd,\n\t\tstruct nand_device *nand, const char *filename, int filemode,\n\t\tstruct nand_fileio_state *state);\nint nand_fileio_cleanup(struct nand_fileio_state *state);\nint nand_fileio_finish(struct nand_fileio_state *state);\n\nCOMMAND_HELPER(nand_fileio_parse_args, struct nand_fileio_state *state,\n\tstruct nand_device **dev, enum fileio_access filemode,\n\tbool need_size, bool sw_ecc);\n\nint nand_fileio_read(struct nand_device *nand, struct nand_fileio_state *s);\n\n#endif /* OPENOCD_FLASH_NAND_FILEIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/imp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_IMP_H\n#define OPENOCD_FLASH_NAND_IMP_H\n\n#include \"core.h\"\n#include \"driver.h\"\n\nvoid nand_device_add(struct nand_device *c);\n\nint nand_write_page(struct nand_device *nand,\n\t\tuint32_t page, uint8_t *data, uint32_t data_size,\n\t\tuint8_t *oob, uint32_t oob_size);\n\nint nand_read_page(struct nand_device *nand, uint32_t page,\n\t\tuint8_t *data, uint32_t data_size,\n\t\tuint8_t *oob, uint32_t oob_size);\n\nint nand_probe(struct nand_device *nand);\nint nand_erase(struct nand_device *nand, int first_block, int last_block);\nint nand_build_bbt(struct nand_device *nand, int first, int last);\n\n#endif /* OPENOCD_FLASH_NAND_IMP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/lpc3180.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *\n *   Copyright (C) 2010 richard vegh <vegh.ricsi@gmail.com>                *\n *   Copyright (C) 2010 Oyvind Harboe <oyvind.harboe@zylin.com>            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"lpc3180.h\"\n#include <target/target.h>\n\nstatic int lpc3180_reset(struct nand_device *nand);\nstatic int lpc3180_controller_ready(struct nand_device *nand, int timeout);\nstatic int lpc3180_tc_ready(struct nand_device *nand, int timeout);\n\n#define ECC_OFFS   0x120\n#define SPARE_OFFS 0x140\n#define DATA_OFFS   0x200\n\n/* nand device lpc3180 <target#> <oscillator_frequency>\n */\nNAND_DEVICE_COMMAND_HANDLER(lpc3180_nand_device_command)\n{\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t osc_freq;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq);\n\n\tstruct lpc3180_nand_controller *lpc3180_info;\n\tlpc3180_info = malloc(sizeof(struct lpc3180_nand_controller));\n\tnand->controller_priv = lpc3180_info;\n\n\tlpc3180_info->osc_freq = osc_freq;\n\n\tif ((lpc3180_info->osc_freq < 1000) || (lpc3180_info->osc_freq > 20000))\n\t\tLOG_WARNING(\n\t\t\t\"LPC3180 oscillator frequency should be between 1000 and 20000 kHz, was %i\",\n\t\t\tlpc3180_info->osc_freq);\n\tlpc3180_info->selected_controller = LPC3180_NO_CONTROLLER;\n\tlpc3180_info->sw_write_protection = 0;\n\tlpc3180_info->sw_wp_lower_bound = 0x0;\n\tlpc3180_info->sw_wp_upper_bound = 0x0;\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_pll(int fclkin, uint32_t pll_ctrl)\n{\n\tint bypass = (pll_ctrl & 0x8000) >> 15;\n\tint direct = (pll_ctrl & 0x4000) >> 14;\n\tint feedback = (pll_ctrl & 0x2000) >> 13;\n\tint p = (1 << ((pll_ctrl & 0x1800) >> 11) * 2);\n\tint n = ((pll_ctrl & 0x0600) >> 9) + 1;\n\tint m = ((pll_ctrl & 0x01fe) >> 1) + 1;\n\tint lock = (pll_ctrl & 0x1);\n\n\tif (!lock)\n\t\tLOG_WARNING(\"PLL is not locked\");\n\n\tif (!bypass && direct)\t/* direct mode */\n\t\treturn (m * fclkin) / n;\n\n\tif (bypass && !direct)\t/* bypass mode */\n\t\treturn fclkin / (2 * p);\n\n\tif (bypass & direct)\t/* direct bypass mode */\n\t\treturn fclkin;\n\n\tif (feedback)\t\t\t/* integer mode */\n\t\treturn m * (fclkin / n);\n\telse\t\t\t\t\t/* non-integer mode */\n\t\treturn (m / (2 * p)) * (fclkin / n);\n}\n\nstatic float lpc3180_cycle_time(struct nand_device *nand)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl;\n\tint sysclk;\n\tint hclk;\n\tint hclk_pll;\n\tfloat cycle;\n\n\t/* calculate timings */\n\n\t/* determine current SYSCLK (13'MHz or main oscillator) */\n\ttarget_read_u32(target, 0x40004050, &sysclk_ctrl);\n\n\tif ((sysclk_ctrl & 1) == 0)\n\t\tsysclk = lpc3180_info->osc_freq;\n\telse\n\t\tsysclk = 13000;\n\n\t/* determine selected HCLK source */\n\ttarget_read_u32(target, 0x40004044, &pwr_ctrl);\n\n\tif ((pwr_ctrl & (1 << 2)) == 0)\t/* DIRECT RUN mode */\n\t\thclk = sysclk;\n\telse {\n\t\ttarget_read_u32(target, 0x40004058, &hclkpll_ctrl);\n\t\thclk_pll = lpc3180_pll(sysclk, hclkpll_ctrl);\n\n\t\ttarget_read_u32(target, 0x40004040, &hclkdiv_ctrl);\n\n\t\tif (pwr_ctrl & (1 << 10)) /* ARM_CLK and HCLK use PERIPH_CLK */\n\t\t\thclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1);\n\t\telse /* HCLK uses HCLK_PLL */\n\t\t\thclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3));\n\t}\n\n\tLOG_DEBUG(\"LPC3180 HCLK currently clocked at %i kHz\", hclk);\n\n\tcycle = (1.0 / hclk) * 1000000.0;\n\n\treturn cycle;\n}\n\nstatic int lpc3180_init(struct nand_device *nand)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint bus_width = nand->bus_width ? nand->bus_width : 8;\n\tint address_cycles = nand->address_cycles ? nand->address_cycles : 3;\n\tint page_size = nand->page_size ? nand->page_size : 512;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/* sanitize arguments */\n\tif ((bus_width != 8) && (bus_width != 16)) {\n\t\tLOG_ERROR(\"LPC3180 only supports 8 or 16 bit bus width, not %i\", bus_width);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\t/* The LPC3180 only brings out 8 bit NAND data bus, but the controller\n\t * would support 16 bit, too, so we just warn about this for now\n\t */\n\tif (bus_width == 16)\n\t\tLOG_WARNING(\"LPC3180 only supports 8 bit bus width\");\n\n\t/* inform calling code about selected bus width */\n\tnand->bus_width = bus_width;\n\n\tif ((address_cycles != 3) && (address_cycles != 4)) {\n\t\tLOG_ERROR(\"LPC3180 only supports 3 or 4 address cycles, not %i\", address_cycles);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\tif ((page_size != 512) && (page_size != 2048)) {\n\t\tLOG_ERROR(\"LPC3180 only supports 512 or 2048 byte pages, not %i\", page_size);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\t/* select MLC controller if none is currently selected */\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_DEBUG(\"no LPC3180 NAND flash controller selected, using default 'mlc'\");\n\t\tlpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\tuint32_t mlc_icr_value = 0x0;\n\t\tfloat cycle;\n\t\tint twp, twh, trp, treh, trhz, trbwb, tcea;\n\n\t\t/* FLASHCLK_CTRL = 0x22 (enable clock for MLC flash controller) */\n\t\ttarget_write_u32(target, 0x400040c8, 0x22);\n\n\t\t/* MLC_CEH = 0x0 (Force nCE assert) */\n\t\ttarget_write_u32(target, 0x200b804c, 0x0);\n\n\t\t/* MLC_LOCK = 0xa25e (unlock protected registers) */\n\t\ttarget_write_u32(target, 0x200b8044, 0xa25e);\n\n\t\t/* MLC_ICR = configuration */\n\t\tif (lpc3180_info->sw_write_protection)\n\t\t\tmlc_icr_value |= 0x8;\n\t\tif (page_size == 2048)\n\t\t\tmlc_icr_value |= 0x4;\n\t\tif (address_cycles == 4)\n\t\t\tmlc_icr_value |= 0x2;\n\t\tif (bus_width == 16)\n\t\t\tmlc_icr_value |= 0x1;\n\t\ttarget_write_u32(target, 0x200b8030, mlc_icr_value);\n\n\t\t/* calculate NAND controller timings */\n\t\tcycle = lpc3180_cycle_time(nand);\n\n\t\ttwp = ((40 / cycle) + 1);\n\t\ttwh = ((20 / cycle) + 1);\n\t\ttrp = ((30 / cycle) + 1);\n\t\ttreh = ((15 / cycle) + 1);\n\t\ttrhz = ((30 / cycle) + 1);\n\t\ttrbwb = ((100 / cycle) + 1);\n\t\ttcea = ((45 / cycle) + 1);\n\n\t\t/* MLC_LOCK = 0xa25e (unlock protected registers) */\n\t\ttarget_write_u32(target, 0x200b8044, 0xa25e);\n\n\t\t/* MLC_TIME_REG */\n\t\ttarget_write_u32(target, 0x200b8034, (twp & 0xf) | ((twh & 0xf) << 4) |\n\t\t\t((trp & 0xf) << 8) | ((treh & 0xf) << 12) | ((trhz & 0x7) << 16) |\n\t\t\t((trbwb & 0x1f) << 19) | ((tcea & 0x3) << 24));\n\n\t\tlpc3180_reset(nand);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\tfloat cycle;\n\t\tint r_setup, r_hold, r_width, r_rdy;\n\t\tint w_setup, w_hold, w_width, w_rdy;\n\n\t\t/* FLASHCLK_CTRL = 0x05 (enable clock for SLC flash controller) */\n\t\ttarget_write_u32(target, 0x400040c8, 0x05);\n\n\t\t/* after reset set other registers of SLC so reset calling is here at the beginning */\n\t\tlpc3180_reset(nand);\n\n\t\t/* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst enabled,\n\t\t *DMA read from SLC, WIDTH = bus_width) */\n\t\ttarget_write_u32(target, 0x20020014, 0x3e | ((bus_width == 16) ? 1 : 0));\n\n\t\t/* SLC_IEN = 3 (INT_RDY_EN = 1) ,(INT_TC_STAT = 1) */\n\t\ttarget_write_u32(target, 0x20020020, 0x03);\n\n\t\t/* DMA configuration\n\t\t * DMACLK_CTRL = 0x01 (enable clock for DMA controller) */\n\t\ttarget_write_u32(target, 0x400040e8, 0x01);\n\t\t/* DMACConfig = DMA enabled*/\n\t\ttarget_write_u32(target, 0x31000030, 0x01);\n\n\n\t\t/* calculate NAND controller timings */\n\t\tcycle = lpc3180_cycle_time(nand);\n\n\t\tr_setup = w_setup = 0;\n\t\tr_hold = w_hold = 10 / cycle;\n\t\tr_width = 30 / cycle;\n\t\tw_width = 40 / cycle;\n\t\tr_rdy = w_rdy = 100 / cycle;\n\n\t\t/* SLC_TAC: SLC timing arcs register */\n\t\ttarget_write_u32(target, 0x2002002c, (r_setup & 0xf) | ((r_hold & 0xf) << 4) |\n\t\t\t((r_width & 0xf) << 8) | ((r_rdy & 0xf) << 12) |  ((w_setup & 0xf) << 16) |\n\t\t\t((w_hold & 0xf) << 20) | ((w_width & 0xf) << 24) | ((w_rdy & 0xf) << 28));\n\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_reset(struct nand_device *nand)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t/* MLC_CMD = 0xff (reset controller and NAND device) */\n\t\ttarget_write_u32(target, 0x200b8000, 0xff);\n\n\t\tif (!lpc3180_controller_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"LPC3180 NAND controller timed out after reset\");\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t\t}\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t/* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */\n\t\ttarget_write_u32(target, 0x20020010, 0x6);\n\n\t\tif (!lpc3180_controller_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"LPC3180 NAND controller timed out after reset\");\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t/* MLC_CMD = command */\n\t\ttarget_write_u32(target, 0x200b8000, command);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t/* SLC_CMD = command */\n\t\ttarget_write_u32(target, 0x20020008, command);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t/* MLC_ADDR = address */\n\t\ttarget_write_u32(target, 0x200b8004, address);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t/* SLC_ADDR = address */\n\t\ttarget_write_u32(target, 0x20020004, address);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t/* MLC_DATA = data */\n\t\ttarget_write_u32(target, 0x200b0000, data);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t/* SLC_DATA = data */\n\t\ttarget_write_u32(target, 0x20020000, data);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_read_data(struct nand_device *nand, void *data)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t/* data = MLC_DATA, use sized access */\n\t\tif (nand->bus_width == 8) {\n\t\t\tuint8_t *data8 = data;\n\t\t\ttarget_read_u8(target, 0x200b0000, data8);\n\t\t} else if (nand->bus_width == 16) {\n\t\t\tuint16_t *data16 = data;\n\t\t\ttarget_read_u16(target, 0x200b0000, data16);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: bus_width neither 8 nor 16 bit\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\tuint32_t data32;\n\n\t\t/* data = SLC_DATA, must use 32-bit access */\n\t\ttarget_read_u32(target, 0x20020000, &data32);\n\n\t\tif (nand->bus_width == 8) {\n\t\t\tuint8_t *data8 = data;\n\t\t\t*data8 = data32 & 0xff;\n\t\t} else if (nand->bus_width == 16) {\n\t\t\tuint16_t *data16 = data;\n\t\t\t*data16 = data32 & 0xffff;\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: bus_width neither 8 nor 16 bit\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_write_page(struct nand_device *nand,\n\tuint32_t page,\n\tuint8_t *data,\n\tuint32_t data_size,\n\tuint8_t *oob,\n\tuint32_t oob_size)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint8_t status;\n\tuint8_t *page_buffer;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\tuint8_t *oob_buffer;\n\t\tint quarter, num_quarters;\n\n\t\tif (!data && oob) {\n\t\t\tLOG_ERROR(\"LPC3180 MLC controller can't write OOB data only\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tif (oob && (oob_size > 24)) {\n\t\t\tLOG_ERROR(\"LPC3180 MLC controller can't write more \"\n\t\t\t\t\"than 6 bytes for each quarter's OOB data\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tif (data_size > (uint32_t)nand->page_size) {\n\t\t\tLOG_ERROR(\"data size exceeds page size\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\t/* MLC_CMD = sequential input */\n\t\ttarget_write_u32(target, 0x200b8000, NAND_CMD_SEQIN);\n\n\t\tpage_buffer = malloc(512);\n\t\toob_buffer = malloc(6);\n\n\t\tif (nand->page_size == 512) {\n\t\t\t/* MLC_ADDR = 0x0 (one column cycle) */\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\n\t\t\t/* MLC_ADDR = row */\n\t\t\ttarget_write_u32(target, 0x200b8004, page & 0xff);\n\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 8) & 0xff);\n\n\t\t\tif (nand->address_cycles == 4)\n\t\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 16) & 0xff);\n\t\t} else {\n\t\t\t/* MLC_ADDR = 0x0 (two column cycles) */\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\n\t\t\t/* MLC_ADDR = row */\n\t\t\ttarget_write_u32(target, 0x200b8004, page & 0xff);\n\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 8) & 0xff);\n\t\t}\n\n\t\t/* when using the MLC controller, we have to treat a large page device\n\t\t * as being made out of four quarters, each the size of a small page device\n\t\t */\n\t\tnum_quarters = (nand->page_size == 2048) ? 4 : 1;\n\n\t\tfor (quarter = 0; quarter < num_quarters; quarter++) {\n\t\t\tint thisrun_data_size = (data_size > 512) ? 512 : data_size;\n\t\t\tint thisrun_oob_size = (oob_size > 6) ? 6 : oob_size;\n\n\t\t\tmemset(page_buffer, 0xff, 512);\n\t\t\tif (data) {\n\t\t\t\tmemcpy(page_buffer, data, thisrun_data_size);\n\t\t\t\tdata_size -= thisrun_data_size;\n\t\t\t\tdata += thisrun_data_size;\n\t\t\t}\n\n\t\t\tmemset(oob_buffer, 0xff, 6);\n\t\t\tif (oob) {\n\t\t\t\tmemcpy(oob_buffer, oob, thisrun_oob_size);\n\t\t\t\toob_size -= thisrun_oob_size;\n\t\t\t\toob += thisrun_oob_size;\n\t\t\t}\n\n\t\t\t/* write MLC_ECC_ENC_REG to start encode cycle */\n\t\t\ttarget_write_u32(target, 0x200b8008, 0x0);\n\n\t\t\ttarget_write_memory(target, 0x200a8000,\n\t\t\t\t4, 128, page_buffer);\n\t\t\ttarget_write_memory(target, 0x200a8000,\n\t\t\t\t1, 6, oob_buffer);\n\n\t\t\t/* write MLC_ECC_AUTO_ENC_REG to start auto encode */\n\t\t\ttarget_write_u32(target, 0x200b8010, 0x0);\n\n\t\t\tif (!lpc3180_controller_ready(nand, 1000)) {\n\t\t\t\tLOG_ERROR(\"timeout while waiting for completion of auto encode cycle\");\n\t\t\t\tfree(page_buffer);\n\t\t\t\tfree(oob_buffer);\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\n\t\t/* MLC_CMD = auto program command */\n\t\ttarget_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG);\n\n\t\tretval = nand_read_status(nand, &status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"couldn't read status\");\n\t\t\tfree(page_buffer);\n\t\t\tfree(oob_buffer);\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (status & NAND_STATUS_FAIL) {\n\t\t\tLOG_ERROR(\"write operation didn't pass, status: 0x%2.2x\", status);\n\t\t\tfree(page_buffer);\n\t\t\tfree(oob_buffer);\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tfree(page_buffer);\n\t\tfree(oob_buffer);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\n\t\t/**********************************************************************\n\t\t*     Write both SLC NAND flash page main area and spare area.\n\t\t*     Small page -\n\t\t*      ------------------------------------------\n\t\t*     |    512 bytes main   |   16 bytes spare   |\n\t\t*      ------------------------------------------\n\t\t*     Large page -\n\t\t*      ------------------------------------------\n\t\t*     |   2048 bytes main   |   64 bytes spare   |\n\t\t*      ------------------------------------------\n\t\t*     If DMA & ECC enabled, then the ECC generated for the 1st 256-byte\n\t\t*     data is written to the 3rd word of the spare area. The ECC\n\t\t*     generated for the 2nd 256-byte data is written to the 4th word\n\t\t*     of the spare area. The ECC generated for the 3rd 256-byte data is\n\t\t*     written to the 7th word of the spare area. The ECC generated\n\t\t*     for the 4th 256-byte data is written to the 8th word of the\n\t\t*     spare area and so on.\n\t\t*\n\t\t**********************************************************************/\n\n\t\tint i = 0, target_mem_base;\n\t\tuint8_t *ecc_flash_buffer;\n\t\tstruct working_area *pworking_area;\n\n\t\tif (lpc3180_info->is_bulk) {\n\n\t\t\tif (!data && oob) {\n\t\t\t\t/*if oob only mode is active original method is used as SLC\n\t\t\t\t *controller hangs during DMA interworking. Anyway the code supports\n\t\t\t\t *the oob only mode below. */\n\t\t\t\treturn nand_write_page_raw(nand,\n\t\t\t\t\tpage,\n\t\t\t\t\tdata,\n\t\t\t\t\tdata_size,\n\t\t\t\t\toob,\n\t\t\t\t\toob_size);\n\t\t\t}\n\t\t\tretval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* allocate a working area */\n\t\t\tif (target->working_area_size < (uint32_t) nand->page_size + 0x200) {\n\t\t\t\tLOG_ERROR(\"Reserve at least 0x%x physical target working area\",\n\t\t\t\t\tnand->page_size + 0x200);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tif (target->working_area_phys%4) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Reserve the physical target working area at word boundary\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tif (target_alloc_working_area(target, target->working_area_size,\n\t\t\t\t    &pworking_area) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"no working area specified, can't read LPC internal flash\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\ttarget_mem_base = target->working_area_phys;\n\n\t\t\tif (nand->page_size == 2048)\n\t\t\t\tpage_buffer = malloc(2048);\n\t\t\telse\n\t\t\t\tpage_buffer = malloc(512);\n\n\t\t\tecc_flash_buffer = malloc(64);\n\n\t\t\t/* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst\n\t\t\t *enabled, DMA write to SLC, WIDTH = bus_width) */\n\t\t\ttarget_write_u32(target, 0x20020014, 0x3c);\n\n\t\t\tif (data && !oob) {\n\t\t\t\t/* set DMA LLI-s in target memory and in DMA*/\n\t\t\t\tfor (i = 0; i < nand->page_size/0x100; i++) {\n\n\t\t\t\t\tint tmp;\n\t\t\t\t\t/* -------LLI for 256 byte block---------\n\t\t\t\t\t * DMACC0SrcAddr = SRAM */\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\ttarget_mem_base+0+i*32,\n\t\t\t\t\t\ttarget_mem_base+DATA_OFFS+i*256);\n\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\t\t0x31000100,\n\t\t\t\t\t\t\ttarget_mem_base+DATA_OFFS);\n\t\t\t\t\t/* DMACCxDestAddr = SLC_DMA_DATA */\n\t\t\t\t\ttarget_write_u32(target, target_mem_base+4+i*32, 0x20020038);\n\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\ttarget_write_u32(target, 0x31000104, 0x20020038);\n\t\t\t\t\t/* DMACCxLLI = next element */\n\t\t\t\t\ttmp = (target_mem_base+(1+i*2)*16)&0xfffffffc;\n\t\t\t\t\ttarget_write_u32(target, target_mem_base+8+i*32, tmp);\n\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\ttarget_write_u32(target, 0x31000108, tmp);\n\t\t\t\t\t/* DMACCxControl =  TransferSize =64, Source burst size =16,\n\t\t\t\t\t * Destination burst size = 16, Source transfer width = 32 bit,\n\t\t\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t\t\t * Destination AHB master select = M0, Source increment = 1,\n\t\t\t\t\t * Destination increment = 0, Terminal count interrupt enable bit = 0*/\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\ttarget_mem_base+12+i*32,\n\t\t\t\t\t\t0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 |\n\t\t\t\t\t\t0<<27 | 0<<31);\n\t\t\t\t\tif (i == 0)\n\t\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\t\t0x3100010c,\n\t\t\t\t\t\t\t0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 |\n\t\t\t\t\t\t\t0<<27 | 0<<31);\n\n\t\t\t\t\t/* -------LLI for 3 byte ECC---------\n\t\t\t\t\t * DMACC0SrcAddr = SLC_ECC*/\n\t\t\t\t\ttarget_write_u32(target, target_mem_base+16+i*32, 0x20020034);\n\t\t\t\t\t/* DMACCxDestAddr = SRAM */\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\ttarget_mem_base+20+i*32,\n\t\t\t\t\t\ttarget_mem_base+SPARE_OFFS+8+16*(i>>1)+(i%2)*4);\n\t\t\t\t\t/* DMACCxLLI = next element */\n\t\t\t\t\ttmp = (target_mem_base+(2+i*2)*16)&0xfffffffc;\n\t\t\t\t\ttarget_write_u32(target, target_mem_base+24+i*32, tmp);\n\t\t\t\t\t/* DMACCxControl =  TransferSize =1, Source burst size =4,\n\t\t\t\t\t * Destination burst size = 4, Source transfer width = 32 bit,\n\t\t\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t\t\t * Destination AHB master select = M0, Source increment = 0,\n\t\t\t\t\t * Destination increment = 1, Terminal count interrupt enable bit = 0*/\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\ttarget_mem_base+28+i*32,\n\t\t\t\t\t\t0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<\n\t\t\t\t\t\t31);\n\t\t\t\t}\n\t\t\t} else if (data && oob) {\n\t\t\t\t/* -------LLI for 512 or 2048 bytes page---------\n\t\t\t\t * DMACC0SrcAddr = SRAM */\n\t\t\t\ttarget_write_u32(target, target_mem_base, target_mem_base+DATA_OFFS);\n\t\t\t\ttarget_write_u32(target, 0x31000100, target_mem_base+DATA_OFFS);\n\t\t\t\t/* DMACCxDestAddr = SLC_DMA_DATA */\n\t\t\t\ttarget_write_u32(target, target_mem_base+4, 0x20020038);\n\t\t\t\ttarget_write_u32(target, 0x31000104, 0x20020038);\n\t\t\t\t/* DMACCxLLI = next element */\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+8,\n\t\t\t\t\t(target_mem_base+32)&0xfffffffc);\n\t\t\t\ttarget_write_u32(target, 0x31000108,\n\t\t\t\t\t(target_mem_base+32)&0xfffffffc);\n\t\t\t\t/* DMACCxControl =  TransferSize =512 or 128, Source burst size =16,\n\t\t\t\t * Destination burst size = 16, Source transfer width = 32 bit,\n\t\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t\t * Destination AHB master select = M0, Source increment = 1,\n\t\t\t\t * Destination increment = 0, Terminal count interrupt enable bit = 0*/\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+12,\n\t\t\t\t\t(nand->page_size ==\n\t\t\t\t 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 |\n\t\t\t\t 1<<26 | 0<<27 | 0<<31);\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t0x3100010c,\n\t\t\t\t\t(nand->page_size ==\n\t\t\t\t 2048 ? 512 : 128) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 |\n\t\t\t\t 1<<26 | 0<<27 | 0<<31);\n\t\t\t\ti = 1;\n\t\t\t} else if (!data && oob)\n\t\t\t\ti = 0;\n\n\t\t\t/* -------LLI for spare area---------\n\t\t\t * DMACC0SrcAddr = SRAM*/\n\t\t\ttarget_write_u32(target, target_mem_base+0+i*32, target_mem_base+SPARE_OFFS);\n\t\t\tif (i == 0)\n\t\t\t\ttarget_write_u32(target, 0x31000100, target_mem_base+SPARE_OFFS);\n\t\t\t/* DMACCxDestAddr = SLC_DMA_DATA */\n\t\t\ttarget_write_u32(target, target_mem_base+4+i*32, 0x20020038);\n\t\t\tif (i == 0)\n\t\t\t\ttarget_write_u32(target, 0x31000104, 0x20020038);\n\t\t\t/* DMACCxLLI = next element = NULL */\n\t\t\ttarget_write_u32(target, target_mem_base+8+i*32, 0);\n\t\t\tif (i == 0)\n\t\t\t\ttarget_write_u32(target, 0x31000108, 0);\n\t\t\t/* DMACCxControl =  TransferSize =16 for large page or 4 for small page,\n\t\t\t * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit,\n\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t * Destination AHB master select = M0, Source increment = 1,\n\t\t\t * Destination increment = 0, Terminal count interrupt enable bit = 0*/\n\t\t\ttarget_write_u32(target,\n\t\t\t\ttarget_mem_base+12+i*32,\n\t\t\t\t(nand->page_size ==\n\t\t\t 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 1<<26 |\n\t\t\t 0<<27 | 0<<31);\n\t\t\tif (i == 0)\n\t\t\t\ttarget_write_u32(target, 0x3100010c,\n\t\t\t\t\t(nand->page_size == 2048 ?\n\t\t\t\t\t0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 |\n\t\t\t\t\t0<<25 | 1<<26 | 0<<27 | 0<<31);\n\n\t\t\tmemset(ecc_flash_buffer, 0xff, 64);\n\t\t\tif (oob)\n\t\t\t\tmemcpy(ecc_flash_buffer, oob, oob_size);\n\t\t\ttarget_write_memory(target,\n\t\t\t\ttarget_mem_base+SPARE_OFFS,\n\t\t\t\t4,\n\t\t\t\t16,\n\t\t\t\tecc_flash_buffer);\n\n\t\t\tif (data) {\n\t\t\t\tmemset(page_buffer, 0xff, nand->page_size == 2048 ? 2048 : 512);\n\t\t\t\tmemcpy(page_buffer, data, data_size);\n\t\t\t\ttarget_write_memory(target,\n\t\t\t\t\ttarget_mem_base+DATA_OFFS,\n\t\t\t\t\t4,\n\t\t\t\t\tnand->page_size == 2048 ? 512 : 128,\n\t\t\t\t\tpage_buffer);\n\t\t\t}\n\n\t\t\tfree(page_buffer);\n\t\t\tfree(ecc_flash_buffer);\n\n\t\t\t/* Enable DMA after channel set up !\n\t\t\t    LLI only works when DMA is the flow controller!\n\t\t\t*/\n\t\t\t/* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC),\n\t\t\t *FlowCntrl = 2 (Pher -> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/\n\t\t\ttarget_write_u32(target,\n\t\t\t\t0x31000110,\n\t\t\t\t1 | 1<<1 | 1<<6 | 2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18);\n\n\t\t\t/* SLC_CTRL = 3 (START DMA), ECC_CLEAR */\n\t\t\ttarget_write_u32(target, 0x20020010, 0x3);\n\n\t\t\t/* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/\n\t\t\ttarget_write_u32(target, 0x20020028, 2);\n\n\t\t\t/* SLC_TC */\n\t\t\tif (!data && oob)\n\t\t\t\ttarget_write_u32(target, 0x20020030,\n\t\t\t\t\t(nand->page_size == 2048 ? 0x10 : 0x04));\n\t\t\telse\n\t\t\t\ttarget_write_u32(target, 0x20020030,\n\t\t\t\t\t(nand->page_size == 2048 ? 0x840 : 0x210));\n\n\t\t\tnand_write_finish(nand);\n\n\t\t\tif (!lpc3180_tc_ready(nand, 1000)) {\n\t\t\t\tLOG_ERROR(\"timeout while waiting for completion of DMA\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\ttarget_free_working_area(target, pworking_area);\n\n\t\t\tLOG_INFO(\"Page =  0x%\" PRIx32 \" was written.\", page);\n\n\t\t} else\n\t\t\treturn nand_write_page_raw(nand, page, data, data_size, oob, oob_size);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_read_page(struct nand_device *nand,\n\tuint32_t page,\n\tuint8_t *data,\n\tuint32_t data_size,\n\tuint8_t *oob,\n\tuint32_t oob_size)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint8_t *page_buffer;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC3180 NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\tuint8_t *oob_buffer;\n\t\tuint32_t page_bytes_done = 0;\n\t\tuint32_t oob_bytes_done = 0;\n\t\tuint32_t mlc_isr;\n\n#if 0\n\t\tif (oob && (oob_size > 6)) {\n\t\t\tLOG_ERROR(\"LPC3180 MLC controller can't read more than 6 bytes of OOB data\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n#endif\n\n\t\tif (data_size > (uint32_t)nand->page_size) {\n\t\t\tLOG_ERROR(\"data size exceeds page size\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tif (nand->page_size == 2048) {\n\t\t\tpage_buffer = malloc(2048);\n\t\t\toob_buffer = malloc(64);\n\t\t} else {\n\t\t\tpage_buffer = malloc(512);\n\t\t\toob_buffer = malloc(16);\n\t\t}\n\n\t\tif (!data && oob) {\n\t\t\t/* MLC_CMD = Read OOB\n\t\t\t * we can use the READOOB command on both small and large page devices,\n\t\t\t * as the controller translates the 0x50 command to a 0x0 with appropriate\n\t\t\t * positioning of the serial buffer read pointer\n\t\t\t */\n\t\t\ttarget_write_u32(target, 0x200b8000, NAND_CMD_READOOB);\n\t\t} else {\n\t\t\t/* MLC_CMD = Read0 */\n\t\t\ttarget_write_u32(target, 0x200b8000, NAND_CMD_READ0);\n\t\t}\n\n\t\tif (nand->page_size == 512) {\n\t\t\t/* small page device\n\t\t\t * MLC_ADDR = 0x0 (one column cycle) */\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\n\t\t\t/* MLC_ADDR = row */\n\t\t\ttarget_write_u32(target, 0x200b8004, page & 0xff);\n\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 8) & 0xff);\n\n\t\t\tif (nand->address_cycles == 4)\n\t\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 16) & 0xff);\n\t\t} else {\n\t\t\t/* large page device\n\t\t\t * MLC_ADDR = 0x0 (two column cycles) */\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\t\t\ttarget_write_u32(target, 0x200b8004, 0x0);\n\n\t\t\t/* MLC_ADDR = row */\n\t\t\ttarget_write_u32(target, 0x200b8004, page & 0xff);\n\t\t\ttarget_write_u32(target, 0x200b8004, (page >> 8) & 0xff);\n\n\t\t\t/* MLC_CMD = Read Start */\n\t\t\ttarget_write_u32(target, 0x200b8000, NAND_CMD_READSTART);\n\t\t}\n\n\t\twhile (page_bytes_done < (uint32_t)nand->page_size) {\n\t\t\t/* MLC_ECC_AUTO_DEC_REG = dummy */\n\t\t\ttarget_write_u32(target, 0x200b8014, 0xaa55aa55);\n\n\t\t\tif (!lpc3180_controller_ready(nand, 1000)) {\n\t\t\t\tLOG_ERROR(\"timeout while waiting for completion of auto decode cycle\");\n\t\t\t\tfree(page_buffer);\n\t\t\t\tfree(oob_buffer);\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\ttarget_read_u32(target, 0x200b8048, &mlc_isr);\n\n\t\t\tif (mlc_isr & 0x8) {\n\t\t\t\tif (mlc_isr & 0x40) {\n\t\t\t\t\tLOG_ERROR(\"uncorrectable error detected: 0x%2.2x\",\n\t\t\t\t\t\t(unsigned)mlc_isr);\n\t\t\t\t\tfree(page_buffer);\n\t\t\t\t\tfree(oob_buffer);\n\t\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t\t}\n\n\t\t\t\tLOG_WARNING(\"%i symbol error detected and corrected\",\n\t\t\t\t\t((int)(((mlc_isr & 0x30) >> 4) + 1)));\n\t\t\t}\n\n\t\t\tif (data)\n\t\t\t\ttarget_read_memory(target,\n\t\t\t\t\t0x200a8000,\n\t\t\t\t\t4,\n\t\t\t\t\t128,\n\t\t\t\t\tpage_buffer + page_bytes_done);\n\n\t\t\tif (oob)\n\t\t\t\ttarget_read_memory(target,\n\t\t\t\t\t0x200a8000,\n\t\t\t\t\t4,\n\t\t\t\t\t4,\n\t\t\t\t\toob_buffer + oob_bytes_done);\n\n\t\t\tpage_bytes_done += 512;\n\t\t\toob_bytes_done += 16;\n\t\t}\n\n\t\tif (data)\n\t\t\tmemcpy(data, page_buffer, data_size);\n\n\t\tif (oob)\n\t\t\tmemcpy(oob, oob_buffer, oob_size);\n\n\t\tfree(page_buffer);\n\t\tfree(oob_buffer);\n\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\n\t\t/**********************************************************************\n\t\t*     Read both SLC NAND flash page main area and spare area.\n\t\t*     Small page -\n\t\t*      ------------------------------------------\n\t\t*     |    512 bytes main   |   16 bytes spare   |\n\t\t*      ------------------------------------------\n\t\t*     Large page -\n\t\t*      ------------------------------------------\n\t\t*     |   2048 bytes main   |   64 bytes spare   |\n\t\t*      ------------------------------------------\n\t\t*     If DMA & ECC enabled, then the ECC generated for the 1st 256-byte\n\t\t*     data is compared with the 3rd word of the spare area. The ECC\n\t\t*     generated for the 2nd 256-byte data is compared with the 4th word\n\t\t*     of the spare area. The ECC generated for the 3rd 256-byte data is\n\t\t*     compared with the 7th word of the spare area. The ECC generated\n\t\t*     for the 4th 256-byte data is compared with the 8th word of the\n\t\t*     spare area and so on.\n\t\t*\n\t\t**********************************************************************/\n\n\t\tint retval, i, target_mem_base;\n\t\tuint8_t *ecc_hw_buffer;\n\t\tuint8_t *ecc_flash_buffer;\n\t\tstruct working_area *pworking_area;\n\n\t\tif (lpc3180_info->is_bulk) {\n\n\t\t\t/* read always the data and also oob areas*/\n\n\t\t\tretval = nand_page_command(nand, page, NAND_CMD_READ0, 0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* allocate a working area */\n\t\t\tif (target->working_area_size < (uint32_t) nand->page_size + 0x200) {\n\t\t\t\tLOG_ERROR(\"Reserve at least 0x%x physical target working area\",\n\t\t\t\t\tnand->page_size + 0x200);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tif (target->working_area_phys%4) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Reserve the physical target working area at word boundary\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tif (target_alloc_working_area(target, target->working_area_size,\n\t\t\t\t    &pworking_area) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"no working area specified, can't read LPC internal flash\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\ttarget_mem_base = target->working_area_phys;\n\n\t\t\tif (nand->page_size == 2048)\n\t\t\t\tpage_buffer = malloc(2048);\n\t\t\telse\n\t\t\t\tpage_buffer = malloc(512);\n\n\t\t\tecc_hw_buffer = malloc(32);\n\t\t\tecc_flash_buffer = malloc(64);\n\n\t\t\t/* SLC_CFG = 0x (Force nCE assert, DMA ECC enabled, ECC enabled, DMA burst\n\t\t\t *enabled, DMA read from SLC, WIDTH = bus_width) */\n\t\t\ttarget_write_u32(target, 0x20020014, 0x3e);\n\n\t\t\t/* set DMA LLI-s in target memory and in DMA*/\n\t\t\tfor (i = 0; i < nand->page_size/0x100; i++) {\n\t\t\t\tint tmp;\n\t\t\t\t/* -------LLI for 256 byte block---------\n\t\t\t\t * DMACC0SrcAddr = SLC_DMA_DATA*/\n\t\t\t\ttarget_write_u32(target, target_mem_base+0+i*32, 0x20020038);\n\t\t\t\tif (i == 0)\n\t\t\t\t\ttarget_write_u32(target, 0x31000100, 0x20020038);\n\t\t\t\t/* DMACCxDestAddr = SRAM */\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+4+i*32,\n\t\t\t\t\ttarget_mem_base+DATA_OFFS+i*256);\n\t\t\t\tif (i == 0)\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\t0x31000104,\n\t\t\t\t\t\ttarget_mem_base+DATA_OFFS);\n\t\t\t\t/* DMACCxLLI = next element */\n\t\t\t\ttmp = (target_mem_base+(1+i*2)*16)&0xfffffffc;\n\t\t\t\ttarget_write_u32(target, target_mem_base+8+i*32, tmp);\n\t\t\t\tif (i == 0)\n\t\t\t\t\ttarget_write_u32(target, 0x31000108, tmp);\n\t\t\t\t/* DMACCxControl =  TransferSize =64, Source burst size =16,\n\t\t\t\t * Destination burst size = 16, Source transfer width = 32 bit,\n\t\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t\t * Destination AHB master select = M0, Source increment = 0,\n\t\t\t\t * Destination increment = 1, Terminal count interrupt enable bit = 0*/\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+12+i*32,\n\t\t\t\t\t0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<\n\t\t\t\t\t31);\n\t\t\t\tif (i == 0)\n\t\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\t\t0x3100010c,\n\t\t\t\t\t\t0x40 | 3<<12 | 3<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<\n\t\t\t\t\t\t31);\n\n\t\t\t\t/* -------LLI for 3 byte ECC---------\n\t\t\t\t * DMACC0SrcAddr = SLC_ECC*/\n\t\t\t\ttarget_write_u32(target, target_mem_base+16+i*32, 0x20020034);\n\t\t\t\t/* DMACCxDestAddr = SRAM */\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+20+i*32,\n\t\t\t\t\ttarget_mem_base+ECC_OFFS+i*4);\n\t\t\t\t/* DMACCxLLI = next element */\n\t\t\t\ttmp = (target_mem_base+(2+i*2)*16)&0xfffffffc;\n\t\t\t\ttarget_write_u32(target, target_mem_base+24+i*32, tmp);\n\t\t\t\t/* DMACCxControl =  TransferSize =1, Source burst size =4,\n\t\t\t\t * Destination burst size = 4, Source transfer width = 32 bit,\n\t\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t\t * Destination AHB master select = M0, Source increment = 0,\n\t\t\t\t * Destination increment = 1, Terminal count interrupt enable bit = 0*/\n\t\t\t\ttarget_write_u32(target,\n\t\t\t\t\ttarget_mem_base+28+i*32,\n\t\t\t\t\t0x01 | 1<<12 | 1<<15 | 2<<18 | 2<<21 | 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<\n\t\t\t\t\t31);\n\t\t\t}\n\n\t\t\t/* -------LLI for spare area---------\n\t\t\t * DMACC0SrcAddr = SLC_DMA_DATA*/\n\t\t\ttarget_write_u32(target, target_mem_base+0+i*32, 0x20020038);\n\t\t\t/* DMACCxDestAddr = SRAM */\n\t\t\ttarget_write_u32(target, target_mem_base+4+i*32, target_mem_base+SPARE_OFFS);\n\t\t\t/* DMACCxLLI = next element = NULL */\n\t\t\ttarget_write_u32(target, target_mem_base+8+i*32, 0);\n\t\t\t/* DMACCxControl =  TransferSize =16 for large page or 4 for small page,\n\t\t\t * Source burst size =16, Destination burst size = 16, Source transfer width = 32 bit,\n\t\t\t * Destination transfer width = 32 bit, Source AHB master select = M0,\n\t\t\t * Destination AHB master select = M0, Source increment = 0,\n\t\t\t * Destination increment = 1, Terminal count interrupt enable bit = 0*/\n\t\t\ttarget_write_u32(target,\n\t\t\t\ttarget_mem_base + 12 + i * 32,\n\t\t\t\t(nand->page_size == 2048 ? 0x10 : 0x04) | 3<<12 | 3<<15 | 2<<18 | 2<<21 |\n\t\t\t 0<<24 | 0<<25 | 0<<26 | 1<<27 | 0<<31);\n\n\t\t\t/* Enable DMA after channel set up !\n\t\t\t    LLI only works when DMA is the flow controller!\n\t\t\t*/\n\t\t\t/* DMACCxConfig= E=1, SrcPeripheral = 1 (SLC), DestPeripheral = 1 (SLC),\n\t\t\t *FlowCntrl = 2 (Pher-> Mem, DMA), IE = 0, ITC = 0, L= 0, H=0*/\n\t\t\ttarget_write_u32(target,\n\t\t\t\t0x31000110,\n\t\t\t\t1 | 1<<1 | 1<<6 |  2<<11 | 0<<14 | 0<<15 | 0<<16 | 0<<18);\n\n\t\t\t/* SLC_CTRL = 3 (START DMA), ECC_CLEAR */\n\t\t\ttarget_write_u32(target, 0x20020010, 0x3);\n\n\t\t\t/* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/\n\t\t\ttarget_write_u32(target, 0x20020028, 2);\n\n\t\t\t/* SLC_TC */\n\t\t\ttarget_write_u32(target, 0x20020030,\n\t\t\t\t(nand->page_size == 2048 ? 0x840 : 0x210));\n\n\t\t\tif (!lpc3180_tc_ready(nand, 1000)) {\n\t\t\t\tLOG_ERROR(\"timeout while waiting for completion of DMA\");\n\t\t\t\tfree(page_buffer);\n\t\t\t\tfree(ecc_hw_buffer);\n\t\t\t\tfree(ecc_flash_buffer);\n\t\t\t\ttarget_free_working_area(target, pworking_area);\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tif (data) {\n\t\t\t\ttarget_read_memory(target,\n\t\t\t\t\ttarget_mem_base+DATA_OFFS,\n\t\t\t\t\t4,\n\t\t\t\t\tnand->page_size == 2048 ? 512 : 128,\n\t\t\t\t\tpage_buffer);\n\t\t\t\tmemcpy(data, page_buffer, data_size);\n\n\t\t\t\tLOG_INFO(\"Page =  0x%\" PRIx32 \" was read.\", page);\n\n\t\t\t\t/* check hw generated ECC for each 256 bytes block with the saved\n\t\t\t\t *ECC in flash spare area*/\n\t\t\t\tint idx = nand->page_size/0x200;\n\t\t\t\ttarget_read_memory(target,\n\t\t\t\t\ttarget_mem_base+SPARE_OFFS,\n\t\t\t\t\t4,\n\t\t\t\t\t16,\n\t\t\t\t\tecc_flash_buffer);\n\t\t\t\ttarget_read_memory(target,\n\t\t\t\t\ttarget_mem_base+ECC_OFFS,\n\t\t\t\t\t4,\n\t\t\t\t\t8,\n\t\t\t\t\tecc_hw_buffer);\n\t\t\t\tfor (i = 0; i < idx; i++) {\n\t\t\t\t\tif ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+i*8)) !=\n\t\t\t\t\t\t\t(0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+8+i*16)))\n\t\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\t\"ECC mismatch at 256 bytes size block= %d at page= 0x%\" PRIx32,\n\t\t\t\t\t\t\ti * 2 + 1, page);\n\t\t\t\t\tif ((0x00ffffff & *(uint32_t *)(void *)(ecc_hw_buffer+4+i*8)) !=\n\t\t\t\t\t\t\t(0x00ffffff & *(uint32_t *)(void *)(ecc_flash_buffer+12+i*16)))\n\t\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\t\"ECC mismatch at 256 bytes size block= %d at page= 0x%\" PRIx32,\n\t\t\t\t\t\t\ti * 2 + 2, page);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (oob)\n\t\t\t\tmemcpy(oob, ecc_flash_buffer, oob_size);\n\n\t\t\tfree(page_buffer);\n\t\t\tfree(ecc_hw_buffer);\n\t\t\tfree(ecc_flash_buffer);\n\n\t\t\ttarget_free_working_area(target, pworking_area);\n\n\t\t} else\n\t\t\treturn nand_read_page_raw(nand, page, data, data_size, oob, oob_size);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc3180_controller_ready(struct nand_device *nand, int timeout)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"lpc3180_controller_ready count start=%d\", timeout);\n\n\tdo {\n\t\tif (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t\tuint8_t status;\n\n\t\t\t/* Read MLC_ISR, wait for controller to become ready */\n\t\t\ttarget_read_u8(target, 0x200b8048, &status);\n\n\t\t\tif (status & 2) {\n\t\t\t\tLOG_DEBUG(\"lpc3180_controller_ready count=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t\tuint32_t status;\n\n\t\t\t/* Read SLC_STAT and check READY bit */\n\t\t\ttarget_read_u32(target, 0x20020018, &status);\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc3180_controller_ready count=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic int lpc3180_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"lpc3180_nand_ready count start=%d\", timeout);\n\n\tdo {\n\t\tif (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER) {\n\t\t\tuint8_t status = 0x0;\n\n\t\t\t/* Read MLC_ISR, wait for NAND flash device to become ready */\n\t\t\ttarget_read_u8(target, 0x200b8048, &status);\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc3180_nand_ready count end=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t\tuint32_t status = 0x0;\n\n\t\t\t/* Read SLC_STAT and check READY bit */\n\t\t\ttarget_read_u32(target, 0x20020018, &status);\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc3180_nand_ready count end=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic int lpc3180_tc_ready(struct nand_device *nand, int timeout)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC3180 NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"lpc3180_tc_ready count start=%d\",\n\t\ttimeout);\n\n\tdo {\n\t\tif (lpc3180_info->selected_controller == LPC3180_SLC_CONTROLLER) {\n\t\t\tuint32_t status = 0x0;\n\t\t\t/* Read SLC_INT_STAT and check INT_TC_STAT bit */\n\t\t\ttarget_read_u32(target, 0x2002001c, &status);\n\n\t\t\tif (status & 2) {\n\t\t\t\tLOG_DEBUG(\"lpc3180_tc_ready count=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nCOMMAND_HANDLER(handle_lpc3180_select_command)\n{\n\tstruct lpc3180_nand_controller *lpc3180_info = NULL;\n\tchar *selected[] = {\n\t\t\"no\", \"mlc\", \"slc\"\n\t};\n\n\tif ((CMD_ARGC < 1) || (CMD_ARGC > 3))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned num;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tstruct nand_device *nand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"nand device '#%s' is out of bounds\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tlpc3180_info = nand->controller_priv;\n\n\tif (CMD_ARGC >= 2) {\n\t\tif (strcmp(CMD_ARGV[1], \"mlc\") == 0)\n\t\t\tlpc3180_info->selected_controller = LPC3180_MLC_CONTROLLER;\n\t\telse if (strcmp(CMD_ARGV[1], \"slc\") == 0) {\n\t\t\tlpc3180_info->selected_controller = LPC3180_SLC_CONTROLLER;\n\t\t\tif (CMD_ARGC == 3 && strcmp(CMD_ARGV[2], \"bulk\") == 0)\n\t\t\t\tlpc3180_info->is_bulk = 1;\n\t\t\telse\n\t\t\t\tlpc3180_info->is_bulk = 0;\n\t\t} else\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (lpc3180_info->selected_controller == LPC3180_MLC_CONTROLLER)\n\t\tcommand_print(CMD, \"%s controller selected\",\n\t\t\tselected[lpc3180_info->selected_controller]);\n\telse\n\t\tcommand_print(CMD,\n\t\t\tlpc3180_info->is_bulk ? \"%s controller selected bulk mode is available\" :\n\t\t\t\"%s controller selected bulk mode is not available\",\n\t\t\tselected[lpc3180_info->selected_controller]);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration lpc3180_exec_command_handlers[] = {\n\t{\n\t\t.name = \"select\",\n\t\t.handler = handle_lpc3180_select_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"select MLC or SLC controller (default is MLC), SLC can be set to bulk mode\",\n\t\t.usage = \"bank_id ['mlc'|'slc' ['bulk'] ]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration lpc3180_command_handler[] = {\n\t{\n\t\t.name = \"lpc3180\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"LPC3180 NAND flash controller commands\",\n\t\t.usage = \"\",\n\t\t.chain = lpc3180_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct nand_flash_controller lpc3180_nand_controller = {\n\t.name = \"lpc3180\",\n\t.commands = lpc3180_command_handler,\n\t.nand_device_command = lpc3180_nand_device_command,\n\t.init = lpc3180_init,\n\t.reset = lpc3180_reset,\n\t.command = lpc3180_command,\n\t.address = lpc3180_address,\n\t.write_data = lpc3180_write_data,\n\t.read_data = lpc3180_read_data,\n\t.write_page = lpc3180_write_page,\n\t.read_page = lpc3180_read_page,\n\t.nand_ready = lpc3180_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/lpc3180.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_LPC3180_H\n#define OPENOCD_FLASH_NAND_LPC3180_H\n\nenum lpc3180_selected_controller {\n\tLPC3180_NO_CONTROLLER,\n\tLPC3180_MLC_CONTROLLER,\n\tLPC3180_SLC_CONTROLLER,\n};\n\nstruct lpc3180_nand_controller {\n\tint osc_freq;\n\tenum lpc3180_selected_controller selected_controller;\n\tint is_bulk;\n\tint sw_write_protection;\n\tuint32_t sw_wp_lower_bound;\n\tuint32_t sw_wp_upper_bound;\n};\n\n#endif /* OPENOCD_FLASH_NAND_LPC3180_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/lpc32xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2011 Bjarne Steinsbo <bsteinsbo@gmail.com>              *\n *   Copyright (C) 2010 richard vegh <vegh.ricsi@gmail.com>                *\n *   Copyright (C) 2010 Oyvind Harboe <oyvind.harboe@zylin.com>            *\n *                                                                         *\n *   Based on a combination of the lpc3180 driver and code from            *\n *   uboot-2009.03-lpc32xx by Kevin Wells.                                 *\n *   Any bugs are mine. --BSt                                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"lpc32xx.h\"\n#include <target/target.h>\n\nstatic int lpc32xx_reset(struct nand_device *nand);\nstatic int lpc32xx_controller_ready(struct nand_device *nand, int timeout);\nstatic int lpc32xx_tc_ready(struct nand_device *nand, int timeout);\n\n/* These are offset with the working area in IRAM when using DMA to\n * read/write data to the SLC controller.\n * - DMA descriptors will be put at start of working area,\n * - Hardware generated ECC will be stored at ECC_OFFS\n * - OOB will be read/written from/to SPARE_OFFS\n * - Actual page data will be read from/to DATA_OFFS\n * There are unused holes between the used areas.\n */\n#define ECC_OFFS   0x120\n#define SPARE_OFFS 0x140\n#define DATA_OFFS  0x200\n\nstatic const int sp_ooblayout[] = {\n\t10, 11, 12, 13, 14, 15\n};\nstatic const int lp_ooblayout[] = {\n\t40, 41, 42, 43, 44, 45,\n\t46, 47, 48, 49, 50, 51,\n\t52, 53, 54, 55, 56, 57,\n\t58, 59, 60, 61, 62, 63\n};\n\nstruct dmac_ll {\n\tvolatile uint32_t dma_src;\n\tvolatile uint32_t dma_dest;\n\tvolatile uint32_t next_lli;\n\tvolatile uint32_t next_ctrl;\n};\n\nstatic struct dmac_ll dmalist[(2048/256) * 2 + 1];\n\n/* nand device lpc32xx <target#> <oscillator_frequency>\n */\nNAND_DEVICE_COMMAND_HANDLER(lpc32xx_nand_device_command)\n{\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t osc_freq;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], osc_freq);\n\n\tstruct lpc32xx_nand_controller *lpc32xx_info;\n\tlpc32xx_info = malloc(sizeof(struct lpc32xx_nand_controller));\n\tnand->controller_priv = lpc32xx_info;\n\n\tlpc32xx_info->osc_freq = osc_freq;\n\n\tif ((lpc32xx_info->osc_freq < 1000) || (lpc32xx_info->osc_freq > 20000))\n\t\tLOG_WARNING(\"LPC32xx oscillator frequency should be between \"\n\t\t\t\"1000 and 20000 kHz, was %i\",\n\t\t\tlpc32xx_info->osc_freq);\n\n\tlpc32xx_info->selected_controller = LPC32XX_NO_CONTROLLER;\n\tlpc32xx_info->sw_write_protection = 0;\n\tlpc32xx_info->sw_wp_lower_bound = 0x0;\n\tlpc32xx_info->sw_wp_upper_bound = 0x0;\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_pll(int fclkin, uint32_t pll_ctrl)\n{\n\tint bypass = (pll_ctrl & 0x8000) >> 15;\n\tint direct = (pll_ctrl & 0x4000) >> 14;\n\tint feedback = (pll_ctrl & 0x2000) >> 13;\n\tint p = (1 << ((pll_ctrl & 0x1800) >> 11) * 2);\n\tint n = ((pll_ctrl & 0x0600) >> 9) + 1;\n\tint m = ((pll_ctrl & 0x01fe) >> 1) + 1;\n\tint lock = (pll_ctrl & 0x1);\n\n\tif (!lock)\n\t\tLOG_WARNING(\"PLL is not locked\");\n\n\tif (!bypass && direct)\t/* direct mode */\n\t\treturn (m * fclkin) / n;\n\n\tif (bypass && !direct)\t/* bypass mode */\n\t\treturn fclkin / (2 * p);\n\n\tif (bypass & direct)\t/* direct bypass mode */\n\t\treturn fclkin;\n\n\tif (feedback)\t/* integer mode */\n\t\treturn m * (fclkin / n);\n\telse\t/* non-integer mode */\n\t\treturn (m / (2 * p)) * (fclkin / n);\n}\n\nstatic float lpc32xx_cycle_time(struct nand_device *nand)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t sysclk_ctrl, pwr_ctrl, hclkdiv_ctrl, hclkpll_ctrl;\n\tint sysclk;\n\tint hclk;\n\tint hclk_pll;\n\tfloat cycle;\n\tint retval;\n\n\t/* calculate timings */\n\n\t/* determine current SYSCLK (13'MHz or main oscillator) */\n\tretval = target_read_u32(target, 0x40004050, &sysclk_ctrl);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not read SYSCLK_CTRL\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif ((sysclk_ctrl & 1) == 0)\n\t\tsysclk = lpc32xx_info->osc_freq;\n\telse\n\t\tsysclk = 13000;\n\n\t/* determine selected HCLK source */\n\tretval = target_read_u32(target, 0x40004044, &pwr_ctrl);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not read HCLK_CTRL\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif ((pwr_ctrl & (1 << 2)) == 0)\t\t/* DIRECT RUN mode */\n\t\thclk = sysclk;\n\telse {\n\t\tretval = target_read_u32(target, 0x40004058, &hclkpll_ctrl);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not read HCLKPLL_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\thclk_pll = lpc32xx_pll(sysclk, hclkpll_ctrl);\n\n\t\tretval = target_read_u32(target, 0x40004040, &hclkdiv_ctrl);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not read CLKDIV_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (pwr_ctrl & (1 << 10))\t/* ARM_CLK and HCLK use PERIPH_CLK */\n\t\t\thclk = hclk_pll / (((hclkdiv_ctrl & 0x7c) >> 2) + 1);\n\t\telse\t/* HCLK uses HCLK_PLL */\n\t\t\thclk = hclk_pll / (1 << (hclkdiv_ctrl & 0x3));\n\t}\n\n\tLOG_DEBUG(\"LPC32xx HCLK currently clocked at %i kHz\", hclk);\n\n\tcycle = (1.0 / hclk) * 1000000.0;\n\n\treturn cycle;\n}\n\nstatic int lpc32xx_init(struct nand_device *nand)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint bus_width = nand->bus_width ? nand->bus_width : 8;\n\tint address_cycles = nand->address_cycles ? nand->address_cycles : 3;\n\tint page_size = nand->page_size ? nand->page_size : 512;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/* sanitize arguments */\n\tif (bus_width != 8) {\n\t\tLOG_ERROR(\"LPC32xx doesn't support %i\", bus_width);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\t/* inform calling code about selected bus width */\n\tnand->bus_width = bus_width;\n\n\tif ((address_cycles < 3) || (address_cycles > 5)) {\n\t\tLOG_ERROR(\"LPC32xx driver doesn't support %i address cycles\", address_cycles);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\tif ((page_size != 512) && (page_size != 2048)) {\n\t\tLOG_ERROR(\"LPC32xx doesn't support page size %i\", page_size);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\t/* select MLC controller if none is currently selected */\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_DEBUG(\"no LPC32xx NAND flash controller selected, \"\n\t\t\t\"using default 'slc'\");\n\t\tlpc32xx_info->selected_controller = LPC32XX_SLC_CONTROLLER;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\tuint32_t mlc_icr_value = 0x0;\n\t\tfloat cycle;\n\t\tint twp, twh, trp, treh, trhz, trbwb, tcea;\n\n\t\t/* FLASHCLK_CTRL = 0x22 (enable clk for MLC) */\n\t\tretval = target_write_u32(target, 0x400040c8, 0x22);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set FLASHCLK_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_CEH = 0x0 (Force nCE assert) */\n\t\tretval = target_write_u32(target, 0x200b804c, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_CEH\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_LOCK = 0xa25e (unlock protected registers) */\n\t\tretval = target_write_u32(target, 0x200b8044, 0xa25e);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_LOCK\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_ICR = configuration */\n\t\tif (lpc32xx_info->sw_write_protection)\n\t\t\tmlc_icr_value |= 0x8;\n\t\tif (page_size == 2048)\n\t\t\tmlc_icr_value |= 0x4;\n\t\tif (address_cycles == 4)\n\t\t\tmlc_icr_value |= 0x2;\n\t\tif (bus_width == 16)\n\t\t\tmlc_icr_value |= 0x1;\n\t\tretval = target_write_u32(target, 0x200b8030, mlc_icr_value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ICR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* calculate NAND controller timings */\n\t\tcycle = lpc32xx_cycle_time(nand);\n\n\t\ttwp = ((40 / cycle) + 1);\n\t\ttwh = ((20 / cycle) + 1);\n\t\ttrp = ((30 / cycle) + 1);\n\t\ttreh = ((15 / cycle) + 1);\n\t\ttrhz = ((30 / cycle) + 1);\n\t\ttrbwb = ((100 / cycle) + 1);\n\t\ttcea = ((45 / cycle) + 1);\n\n\t\t/* MLC_LOCK = 0xa25e (unlock protected registers) */\n\t\tretval = target_write_u32(target, 0x200b8044, 0xa25e);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_LOCK\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_TIME_REG */\n\t\tretval = target_write_u32(target, 0x200b8034,\n\t\t\t\t(twp & 0xf)\n\t\t\t\t| ((twh & 0xf) << 4)\n\t\t\t\t| ((trp & 0xf) << 8)\n\t\t\t\t| ((treh & 0xf) << 12)\n\t\t\t\t| ((trhz & 0x7) << 16)\n\t\t\t\t| ((trbwb & 0x1f) << 19)\n\t\t\t\t| ((tcea & 0x3) << 24));\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_TIME_REG\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tretval = lpc32xx_reset(nand);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\tfloat cycle;\n\t\tint r_setup, r_hold, r_width, r_rdy;\n\t\tint w_setup, w_hold, w_width, w_rdy;\n\n\t\t/* FLASHCLK_CTRL = 0x05 (enable clk for SLC) */\n\t\tretval = target_write_u32(target, 0x400040c8, 0x05);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set FLASHCLK_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* after reset set other registers of SLC,\n\t\t * so reset calling is here at the beginning\n\t\t */\n\t\tretval = lpc32xx_reset(nand);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\n\t\t/* SLC_CFG =\n\t\t\tForce nCE assert,\n\t\t\tDMA ECC enabled,\n\t\t\tECC enabled,\n\t\t\tDMA burst enabled,\n\t\t\tDMA read from SLC,\n\t\t\tWIDTH = bus_width)\n\t\t*/\n\t\tretval = target_write_u32(target, 0x20020014,\n\t\t\t\t0x3e | ((bus_width == 16) ? 1 : 0));\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_CFG\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* SLC_IEN = 3 (INT_RDY_EN = 1) ,(INT_TC_STAT = 1) */\n\t\tretval = target_write_u32(target, 0x20020020, 0x03);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_IEN\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* DMA configuration */\n\n\t\t/* DMACLK_CTRL = 0x01 (enable clock for DMA controller) */\n\t\tretval = target_write_u32(target, 0x400040e8, 0x01);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set DMACLK_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* DMACConfig = DMA enabled*/\n\t\tretval = target_write_u32(target, 0x31000030, 0x01);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set DMACConfig\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* calculate NAND controller timings */\n\t\tcycle = lpc32xx_cycle_time(nand);\n\n\t\tr_setup = w_setup = 0;\n\t\tr_hold = w_hold = 10 / cycle;\n\t\tr_width = 30 / cycle;\n\t\tw_width = 40 / cycle;\n\t\tr_rdy = w_rdy = 100 / cycle;\n\n\t\t/* SLC_TAC: SLC timing arcs register */\n\t\tretval = target_write_u32(target, 0x2002002c,\n\t\t\t\t(r_setup & 0xf)\n\t\t\t\t| ((r_hold & 0xf) << 4)\n\t\t\t\t| ((r_width & 0xf) << 8)\n\t\t\t\t| ((r_rdy & 0xf) << 12)\n\t\t\t\t| ((w_setup & 0xf) << 16)\n\t\t\t\t| ((w_hold & 0xf) << 20)\n\t\t\t\t| ((w_width & 0xf) << 24)\n\t\t\t\t| ((w_rdy & 0xf) << 28));\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_TAC\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_reset(struct nand_device *nand)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use \"\n\t\t\t\"LPC32xx NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t/* MLC_CMD = 0xff (reset controller and NAND device) */\n\t\tretval = target_write_u32(target, 0x200b8000, 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (!lpc32xx_controller_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"LPC32xx MLC NAND controller timed out \"\n\t\t\t\t\"after reset\");\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t\t}\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t/* SLC_CTRL = 0x6 (ECC_CLEAR, SW_RESET) */\n\t\tretval = target_write_u32(target, 0x20020010, 0x6);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_CTRL\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (!lpc32xx_controller_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"LPC32xx SLC NAND controller timed out \"\n\t\t\t\t\"after reset\");\n\t\t\treturn ERROR_NAND_OPERATION_TIMEOUT;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use \"\n\t\t\t\"LPC32xx NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t/* MLC_CMD = command */\n\t\tretval = target_write_u32(target, 0x200b8000, command);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t/* SLC_CMD = command */\n\t\tretval = target_write_u32(target, 0x20020008, command);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_CMD\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use \"\n\t\t\t\"LPC32xx NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t/* MLC_ADDR = address */\n\t\tretval = target_write_u32(target, 0x200b8004, address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t/* SLC_ADDR = address */\n\t\tretval = target_write_u32(target, 0x20020004, address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use \"\n\t\t\t\"LPC32xx NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t/* MLC_DATA = data */\n\t\tretval = target_write_u32(target, 0x200b0000, data);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_DATA\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t/* SLC_DATA = data */\n\t\tretval = target_write_u32(target, 0x20020000, data);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set SLC_DATA\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_read_data(struct nand_device *nand, void *data)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t/* data = MLC_DATA, use sized access */\n\t\tif (nand->bus_width == 8) {\n\t\t\tuint8_t *data8 = data;\n\t\t\tretval = target_read_u8(target, 0x200b0000, data8);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: bus_width neither 8 nor 16 bit\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not read MLC_DATA\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\tuint32_t data32;\n\n\t\t/* data = SLC_DATA, must use 32-bit access */\n\t\tretval = target_read_u32(target, 0x20020000, &data32);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not read SLC_DATA\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (nand->bus_width == 8) {\n\t\t\tuint8_t *data8 = data;\n\t\t\t*data8 = data32 & 0xff;\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: bus_width neither 8 nor 16 bit\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_write_page_mlc(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint8_t status;\n\tstatic uint8_t page_buffer[512];\n\tstatic uint8_t oob_buffer[6];\n\tint quarter, num_quarters;\n\n\t/* MLC_CMD = sequential input */\n\tretval = target_write_u32(target, 0x200b8000, NAND_CMD_SEQIN);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (nand->page_size == 512) {\n\t\t/* MLC_ADDR = 0x0 (one column cycle) */\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_ADDR = row */\n\t\tretval = target_write_u32(target, 0x200b8004, page & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t(page >> 8) & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (nand->address_cycles == 4) {\n\t\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t\t(page >> 16) & 0xff);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* MLC_ADDR = 0x0 (two column cycles) */\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_ADDR = row */\n\t\tretval = target_write_u32(target, 0x200b8004, page & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t(page >> 8) & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\t/* when using the MLC controller, we have to treat a large page device\n\t * as being made out of four quarters, each the size of a small page\n\t * device\n\t */\n\tnum_quarters = (nand->page_size == 2048) ? 4 : 1;\n\n\tfor (quarter = 0; quarter < num_quarters; quarter++) {\n\t\tint thisrun_data_size = (data_size > 512) ? 512 : data_size;\n\t\tint thisrun_oob_size = (oob_size > 6) ? 6 : oob_size;\n\n\t\tmemset(page_buffer, 0xff, 512);\n\t\tif (data) {\n\t\t\tmemcpy(page_buffer, data, thisrun_data_size);\n\t\t\tdata_size -= thisrun_data_size;\n\t\t\tdata += thisrun_data_size;\n\t\t}\n\n\t\tmemset(oob_buffer, 0xff, 6);\n\t\tif (oob) {\n\t\t\tmemcpy(oob_buffer, oob, thisrun_oob_size);\n\t\t\toob_size -= thisrun_oob_size;\n\t\t\toob += thisrun_oob_size;\n\t\t}\n\n\t\t/* write MLC_ECC_ENC_REG to start encode cycle */\n\t\tretval = target_write_u32(target, 0x200b8008, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ECC_ENC_REG\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tretval = target_write_memory(target, 0x200a8000,\n\t\t\t\t4, 128, page_buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_BUF (data)\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_memory(target, 0x200a8000,\n\t\t\t\t1, 6, oob_buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_BUF (oob)\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* write MLC_ECC_AUTO_ENC_REG to start auto encode */\n\t\tretval = target_write_u32(target, 0x200b8010, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ECC_AUTO_ENC_REG\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (!lpc32xx_controller_ready(nand, 1000)) {\n\t\t\tLOG_ERROR(\"timeout while waiting for \"\n\t\t\t\t\"completion of auto encode cycle\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\t/* MLC_CMD = auto program command */\n\tretval = target_write_u32(target, 0x200b8000, NAND_CMD_PAGEPROG);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tretval = nand_read_status(nand, &status);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"couldn't read status\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (status & NAND_STATUS_FAIL) {\n\t\tLOG_ERROR(\"write operation didn't pass, status: 0x%2.2x\",\n\t\t\tstatus);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* SLC controller in !raw mode will use target cpu to read/write nand from/to\n * target internal memory.  The transfer to/from flash is done by DMA.  This\n * function sets up the dma linked list in host memory for later transfer to\n * target.\n */\nstatic int lpc32xx_make_dma_list(uint32_t target_mem_base, uint32_t page_size,\n\tint do_read)\n{\n\tuint32_t i, dmasrc, ctrl, ecc_ctrl, oob_ctrl, dmadst;\n\n\t/* DMACCxControl =\n\t\tTransferSize =64,\n\t\tSource burst size =16,\n\t\tDestination burst size = 16,\n\t\tSource transfer width = 32 bit,\n\t\tDestination transfer width = 32 bit,\n\t\tSource AHB master select = M0,\n\t\tDestination AHB master select = M0,\n\t\tSource increment = 0, // set later\n\t\tDestination increment = 0, // set later\n\t\tTerminal count interrupt enable bit = 0 // set on last\n\t*/\t\t\t/*\n\t * Write Operation Sequence for Small Block NAND\n\t * ----------------------------------------------------------\n\t * 1. X'fer 256 bytes of data from Memory to Flash.\n\t * 2. Copy generated ECC data from Register to Spare Area\n\t * 3. X'fer next 256 bytes of data from Memory to Flash.\n\t * 4. Copy generated ECC data from Register to Spare Area.\n\t * 5. X'fer 16 bytes of Spare area from Memory to Flash.\n\t * Read Operation Sequence for Small Block NAND\n\t * ----------------------------------------------------------\n\t * 1. X'fer 256 bytes of data from Flash to Memory.\n\t * 2. Copy generated ECC data from Register to ECC calc Buffer.\n\t * 3. X'fer next 256 bytes of data from Flash to Memory.\n\t * 4. Copy generated ECC data from Register to ECC calc Buffer.\n\t * 5. X'fer 16 bytes of Spare area from Flash to Memory.\n\t * Write Operation Sequence for Large Block NAND\n\t * ----------------------------------------------------------\n\t * 1. Steps(1-4) of Write Operations repeated for four times\n\t * which generates 16 DMA descriptors to X'fer 2048 bytes of\n\t * data & 32 bytes of ECC data.\n\t * 2. X'fer 64 bytes of Spare area from Memory to Flash.\n\t * Read Operation Sequence for Large Block NAND\n\t * ----------------------------------------------------------\n\t * 1. Steps(1-4) of Read Operations repeated for four times\n\t * which generates 16 DMA descriptors to X'fer 2048 bytes of\n\t * data & 32 bytes of ECC data.\n\t * 2. X'fer 64 bytes of Spare area from Flash to Memory.\n\t */\n\n\tctrl = (0x40 | 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24\n\t\t| 0 << 25 | 0 << 26 | 0 << 27 | 0 << 31);\n\n\t/* DMACCxControl =\n\t\tTransferSize =1,\n\t\tSource burst size =4,\n\t\tDestination burst size = 4,\n\t\tSource transfer width = 32 bit,\n\t\tDestination transfer width = 32 bit,\n\t\tSource AHB master select = M0,\n\t\tDestination AHB master select = M0,\n\t\tSource increment = 0,\n\t\tDestination increment = 1,\n\t\tTerminal count interrupt enable bit = 0\n\t */\n\tecc_ctrl = 0x01 | 1 << 12 | 1 << 15 | 2 << 18 | 2 << 21 | 0 << 24\n\t\t| 0 << 25 | 0 << 26 | 1 << 27 | 0 << 31;\n\n\t/* DMACCxControl =\n\t\tTransferSize =16 for lp or 4 for sp,\n\t\tSource burst size =16,\n\t\tDestination burst size = 16,\n\t\tSource transfer width = 32 bit,\n\t\tDestination transfer width = 32 bit,\n\t\tSource AHB master select = M0,\n\t\tDestination AHB master select = M0,\n\t\tSource increment = 0, // set later\n\t\tDestination increment = 0, // set later\n\t\tTerminal count interrupt enable bit = 1 // set on last\n\t */\n\toob_ctrl = (page_size == 2048 ? 0x10 : 0x04)\n\t\t| 3 << 12 | 3 << 15 | 2 << 18 | 2 << 21 | 0 << 24\n\t\t| 0 << 25 | 0 << 26 | 0 << 27 | 1 << 31;\n\tif (do_read) {\n\t\tctrl |= 1 << 27;/* Destination increment = 1 */\n\t\toob_ctrl |= 1 << 27;\t/* Destination increment = 1 */\n\t\tdmasrc = 0x20020038;\t/* SLC_DMA_DATA */\n\t\tdmadst = target_mem_base + DATA_OFFS;\n\t} else {\n\t\tctrl |= 1 << 26;/* Source increment = 1 */\n\t\toob_ctrl |= 1 << 26;\t/* Source increment = 1 */\n\t\tdmasrc = target_mem_base + DATA_OFFS;\n\t\tdmadst = 0x20020038;\t/* SLC_DMA_DATA */\n\t}\n\t/*\n\t * Write Operation Sequence for Small Block NAND\n\t * ----------------------------------------------------------\n\t * 1. X'fer 256 bytes of data from Memory to Flash.\n\t * 2. Copy generated ECC data from Register to Spare Area\n\t * 3. X'fer next 256 bytes of data from Memory to Flash.\n\t * 4. Copy generated ECC data from Register to Spare Area.\n\t * 5. X'fer 16 bytes of Spare area from Memory to Flash.\n\t * Read Operation Sequence for Small Block NAND\n\t * ----------------------------------------------------------\n\t * 1. X'fer 256 bytes of data from Flash to Memory.\n\t * 2. Copy generated ECC data from Register to ECC calc Buffer.\n\t * 3. X'fer next 256 bytes of data from Flash to Memory.\n\t * 4. Copy generated ECC data from Register to ECC calc Buffer.\n\t * 5. X'fer 16 bytes of Spare area from Flash to Memory.\n\t * Write Operation Sequence for Large Block NAND\n\t * ----------------------------------------------------------\n\t * 1. Steps(1-4) of Write Operations repeated for four times\n\t * which generates 16 DMA descriptors to X'fer 2048 bytes of\n\t * data & 32 bytes of ECC data.\n\t * 2. X'fer 64 bytes of Spare area from Memory to Flash.\n\t * Read Operation Sequence for Large Block NAND\n\t * ----------------------------------------------------------\n\t * 1. Steps(1-4) of Read Operations repeated for four times\n\t * which generates 16 DMA descriptors to X'fer 2048 bytes of\n\t * data & 32 bytes of ECC data.\n\t * 2. X'fer 64 bytes of Spare area from Flash to Memory.\n\t */\n\tfor (i = 0; i < page_size/0x100; i++) {\n\t\tdmalist[i*2].dma_src = (do_read ? dmasrc : (dmasrc + i * 256));\n\t\tdmalist[i*2].dma_dest = (do_read ? (dmadst + i * 256) : dmadst);\n\t\tdmalist[i*2].next_lli =\n\t\t\ttarget_mem_base + (i*2 + 1) * sizeof(struct dmac_ll);\n\t\tdmalist[i*2].next_ctrl = ctrl;\n\n\t\tdmalist[(i*2) + 1].dma_src = 0x20020034;/* SLC_ECC */\n\t\tdmalist[(i*2) + 1].dma_dest =\n\t\t\ttarget_mem_base + ECC_OFFS + i * 4;\n\t\tdmalist[(i*2) + 1].next_lli =\n\t\t\ttarget_mem_base + (i*2 + 2) * sizeof(struct dmac_ll);\n\t\tdmalist[(i*2) + 1].next_ctrl = ecc_ctrl;\n\n\t}\n\tif (do_read)\n\t\tdmadst = target_mem_base + SPARE_OFFS;\n\telse {\n\t\tdmasrc = target_mem_base + SPARE_OFFS;\n\t\tdmalist[(i*2) - 1].next_lli = 0;/* last link = null on write */\n\t\tdmalist[(i*2) - 1].next_ctrl |= (1 << 31);\t/* Set TC enable */\n\t}\n\tdmalist[i*2].dma_src = dmasrc;\n\tdmalist[i*2].dma_dest = dmadst;\n\tdmalist[i*2].next_lli = 0;\n\tdmalist[i*2].next_ctrl = oob_ctrl;\n\n\treturn i * 2 + 1;\t/* Number of descriptors */\n}\n\nstatic int lpc32xx_start_slc_dma(struct nand_device *nand, uint32_t count,\n\tint do_wait)\n{\n\tstruct target *target = nand->target;\n\tint retval;\n\n\t/* DMACIntTCClear = ch0 */\n\tretval = target_write_u32(target, 0x31000008, 1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set DMACIntTCClear\");\n\t\treturn retval;\n\t}\n\n\t/* DMACIntErrClear = ch0 */\n\tretval = target_write_u32(target, 0x31000010, 1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set DMACIntErrClear\");\n\t\treturn retval;\n\t}\n\n\t/* DMACCxConfig=\n\t\tE=1,\n\t\tSrcPeripheral = 1 (SLC),\n\t\tDestPeripheral = 1 (SLC),\n\t\tFlowCntrl = 2 (Pher -> Mem, DMA),\n\t\tIE = 0,\n\t\tITC = 0,\n\t\tL= 0,\n\t\tH=0\n\t*/\n\tretval = target_write_u32(target, 0x31000110,\n\t\t\t1 | 1<<1 | 1<<6 | 2<<11 | 0<<14\n\t\t\t| 0<<15 | 0<<16 | 0<<18);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set DMACC0Config\");\n\t\treturn retval;\n\t}\n\n\t/* SLC_CTRL = 3 (START DMA), ECC_CLEAR */\n\tretval = target_write_u32(target, 0x20020010, 0x3);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set SLC_CTRL\");\n\t\treturn retval;\n\t}\n\n\t/* SLC_ICR = 2, INT_TC_CLR, clear pending TC*/\n\tretval = target_write_u32(target, 0x20020028, 2);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set SLC_ICR\");\n\t\treturn retval;\n\t}\n\n\t/* SLC_TC */\n\tretval = target_write_u32(target, 0x20020030, count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"lpc32xx_start_slc_dma: Could not set SLC_TC\");\n\t\treturn retval;\n\t}\n\n\t/* Wait finish */\n\tif (do_wait && !lpc32xx_tc_ready(nand, 100)) {\n\t\tLOG_ERROR(\"timeout while waiting for completion of DMA\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\treturn retval;\n}\n\nstatic int lpc32xx_dma_ready(struct nand_device *nand, int timeout)\n{\n\tstruct target *target = nand->target;\n\n\tLOG_DEBUG(\"lpc32xx_dma_ready count start=%d\", timeout);\n\n\tdo {\n\t\tuint32_t tc_stat;\n\t\tuint32_t err_stat;\n\t\tint retval;\n\n\t\t/* Read DMACRawIntTCStat */\n\t\tretval = target_read_u32(target, 0x31000014, &tc_stat);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DMACRawIntTCStat\");\n\t\t\treturn 0;\n\t\t}\n\t\t/* Read DMACRawIntErrStat */\n\t\tretval = target_read_u32(target, 0x31000018, &err_stat);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DMACRawIntErrStat\");\n\t\t\treturn 0;\n\t\t}\n\t\tif ((tc_stat | err_stat) & 1) {\n\t\t\tLOG_DEBUG(\"lpc32xx_dma_ready count=%d\",\n\t\t\t\ttimeout);\n\t\t\tif (err_stat & 1) {\n\t\t\t\tLOG_ERROR(\"lpc32xx_dma_ready \"\n\t\t\t\t\t\"DMA error, aborted\");\n\t\t\t\treturn 0;\n\t\t\t} else\n\t\t\t\treturn 1;\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic uint32_t slc_ecc_copy_to_buffer(uint8_t *spare,\n\tconst uint32_t *ecc, int count)\n{\n\tint i;\n\tfor (i = 0; i < (count * 3); i += 3) {\n\t\tuint32_t ce = ecc[i/3];\n\t\tce = ~(ce << 2) & 0xFFFFFF;\n\t\tspare[i+2] = (uint8_t)(ce & 0xFF); ce >>= 8;\n\t\tspare[i+1] = (uint8_t)(ce & 0xFF); ce >>= 8;\n\t\tspare[i]   = (uint8_t)(ce & 0xFF);\n\t}\n\treturn 0;\n}\n\nstatic void lpc32xx_dump_oob(uint8_t *oob, uint32_t oob_size)\n{\n\tint addr = 0;\n\twhile (oob_size > 0) {\n\t\tLOG_DEBUG(\"%02x: %02x %02x %02x %02x %02x %02x %02x %02x\", addr,\n\t\t\toob[0], oob[1], oob[2], oob[3],\n\t\t\toob[4], oob[5], oob[6], oob[7]);\n\t\toob += 8;\n\t\taddr += 8;\n\t\toob_size -= 8;\n\t}\n}\n\nstatic int lpc32xx_write_page_slc(struct nand_device *nand,\n\tstruct working_area *pworking_area,\n\tuint32_t page, uint8_t *data,\n\tuint32_t data_size, uint8_t *oob,\n\tuint32_t oob_size)\n{\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint32_t target_mem_base;\n\n\tLOG_DEBUG(\"SLC write page %\" PRIx32 \" data=%d, oob=%d, \"\n\t\t\"data_size=%\" PRIu32 \", oob_size=%\" PRIu32,\n\t\tpage, !!data, !!oob, data_size, oob_size);\n\n\ttarget_mem_base = pworking_area->address;\n\t/*\n\t * Skip writing page which has all 0xFF data as this will\n\t * generate 0x0 value.\n\t */\n\tif (data && !oob) {\n\t\tuint32_t i, all_ff = 1;\n\t\tfor (i = 0; i < data_size; i++)\n\t\t\tif (data[i] != 0xFF) {\n\t\t\t\tall_ff = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\tif (all_ff)\n\t\t\treturn ERROR_OK;\n\t}\n\t/* Make the dma descriptors in local memory */\n\tint nll = lpc32xx_make_dma_list(target_mem_base, nand->page_size, 0);\n\t/* Write them to target.\n\t   XXX: Assumes host and target have same byte sex.\n\t*/\n\tretval = target_write_memory(target, target_mem_base, 4,\n\t\t\tnll * sizeof(struct dmac_ll) / 4,\n\t\t\t(uint8_t *)dmalist);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not write DMA descriptors to IRAM\");\n\t\treturn retval;\n\t}\n\n\tretval = nand_page_command(nand, page, NAND_CMD_SEQIN, !data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"NAND_CMD_SEQIN failed\");\n\t\treturn retval;\n\t}\n\n\t/* SLC_CFG =\n\t       Force nCE assert,\n\t       DMA ECC enabled,\n\t       ECC enabled,\n\t       DMA burst enabled,\n\t       DMA write to SLC,\n\t       WIDTH = bus_width\n\t*/\n\tretval = target_write_u32(target, 0x20020014, 0x3c);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not set SLC_CFG\");\n\t\treturn retval;\n\t}\n\tif (data) {\n\t\t/* Write data to target */\n\t\tstatic uint8_t fdata[2048];\n\t\tmemset(fdata, 0xFF, nand->page_size);\n\t\tmemcpy(fdata, data, data_size);\n\t\tretval = target_write_memory(target,\n\t\t\t\ttarget_mem_base + DATA_OFFS,\n\t\t\t\t4, nand->page_size/4, fdata);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not write data to IRAM\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Write first descriptor to DMA controller */\n\t\tretval = target_write_memory(target, 0x31000100, 4,\n\t\t\t\tsizeof(struct dmac_ll) / 4,\n\t\t\t\t(uint8_t *)dmalist);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not write DMA descriptor to DMAC\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Start xfer of data from iram to flash using DMA */\n\t\tint tot_size = nand->page_size;\n\t\ttot_size += tot_size == 2048 ? 64 : 16;\n\t\tretval = lpc32xx_start_slc_dma(nand, tot_size, 0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"DMA failed\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Wait for DMA to finish.  SLC is not finished at this stage */\n\t\tif (!lpc32xx_dma_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"Data DMA failed during write\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\t/* data xfer */\n\n\t/* Copy OOB to iram */\n\tstatic uint8_t foob[64];\n\tint foob_size = nand->page_size == 2048 ? 64 : 16;\n\tmemset(foob, 0xFF, foob_size);\n\tif (oob)\t/* Raw mode */\n\t\tmemcpy(foob, oob, oob_size);\n\telse {\n\t\t/* Get HW generated ECC, made while writing data */\n\t\tint ecc_count = nand->page_size == 2048 ? 8 : 2;\n\t\tstatic uint32_t hw_ecc[8];\n\t\tretval = target_read_memory(target, target_mem_base + ECC_OFFS,\n\t\t\t\t4, ecc_count, (uint8_t *)hw_ecc);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Reading hw generated ECC from IRAM failed\");\n\t\t\treturn retval;\n\t\t}\n\t\t/* Copy to oob, at correct offsets */\n\t\tstatic uint8_t ecc[24];\n\t\tslc_ecc_copy_to_buffer(ecc, hw_ecc, ecc_count);\n\t\tconst int *layout = nand->page_size == 2048 ? lp_ooblayout : sp_ooblayout;\n\t\tint i;\n\t\tfor (i = 0; i < ecc_count * 3; i++)\n\t\t\tfoob[layout[i]] = ecc[i];\n\t\tlpc32xx_dump_oob(foob, foob_size);\n\t}\n\tretval = target_write_memory(target, target_mem_base + SPARE_OFFS, 4,\n\t\t\tfoob_size / 4, foob);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Writing OOB to IRAM failed\");\n\t\treturn retval;\n\t}\n\n\t/* Write OOB descriptor to DMA controller */\n\tretval = target_write_memory(target, 0x31000100, 4,\n\t\t\tsizeof(struct dmac_ll) / 4,\n\t\t\t(uint8_t *)(&dmalist[nll-1]));\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not write OOB DMA descriptor to DMAC\");\n\t\treturn retval;\n\t}\n\tif (data) {\n\t\t/* Only restart DMA with last descriptor,\n\t\t * don't setup SLC again */\n\n\t\t/* DMACIntTCClear = ch0 */\n\t\tretval = target_write_u32(target, 0x31000008, 1);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not set DMACIntTCClear\");\n\t\t\treturn retval;\n\t\t}\n\t\t/* DMACCxConfig=\n\t\t * E=1,\n\t\t * SrcPeripheral = 1 (SLC),\n\t\t * DestPeripheral = 1 (SLC),\n\t\t * FlowCntrl = 2 (Pher -> Mem, DMA),\n\t\t * IE = 0,\n\t\t * ITC = 0,\n\t\t * L= 0,\n\t\t * H=0\n\t\t*/\n\t\tretval = target_write_u32(target, 0x31000110,\n\t\t\t\t1 | 1<<1 | 1<<6 | 2<<11 | 0<<14\n\t\t\t\t| 0<<15 | 0<<16 | 0<<18);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not set DMACC0Config\");\n\t\t\treturn retval;\n\t\t}\n\t\t/* Wait finish */\n\t\tif (!lpc32xx_tc_ready(nand, 100)) {\n\t\t\tLOG_ERROR(\"timeout while waiting for \"\n\t\t\t\t\"completion of DMA\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t} else {\n\t\t/* Start xfer of data from iram to flash using DMA */\n\t\tretval = lpc32xx_start_slc_dma(nand, foob_size, 1);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"DMA OOB failed\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Let NAND start actual writing */\n\tretval = nand_write_finish(nand);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"nand_write_finish failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_write_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\tif (!data && oob) {\n\t\t\tLOG_ERROR(\"LPC32xx MLC controller can't write \"\n\t\t\t\t\"OOB data only\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tif (oob && (oob_size > 24)) {\n\t\t\tLOG_ERROR(\"LPC32xx MLC controller can't write more \"\n\t\t\t\t\"than 6 bytes for each quarter's OOB data\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tif (data_size > (uint32_t)nand->page_size) {\n\t\t\tLOG_ERROR(\"data size exceeds page size\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\n\t\tretval = lpc32xx_write_page_mlc(nand, page, data, data_size,\n\t\t\t\toob, oob_size);\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\tstruct working_area *pworking_area;\n\t\tif (!data && oob) {\n\t\t\t/*\n\t\t\t * if oob only mode is active original method is used\n\t\t\t * as SLC controller hangs during DMA interworking. (?)\n\t\t\t * Anyway the code supports the oob only mode below.\n\t\t\t */\n\t\t\treturn nand_write_page_raw(nand, page, data,\n\t\t\t\tdata_size, oob, oob_size);\n\t\t}\n\t\tretval = target_alloc_working_area(target,\n\t\t\t\tnand->page_size + DATA_OFFS,\n\t\t\t\t&pworking_area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't allocate working area in \"\n\t\t\t\t\"LPC internal RAM\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t\tretval = lpc32xx_write_page_slc(nand, pworking_area, page,\n\t\t\t\tdata, data_size, oob, oob_size);\n\t\ttarget_free_working_area(target, pworking_area);\n\t}\n\n\treturn retval;\n}\n\nstatic int lpc32xx_read_page_mlc(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct target *target = nand->target;\n\tstatic uint8_t page_buffer[2048];\n\tstatic uint8_t oob_buffer[64];\n\tuint32_t page_bytes_done = 0;\n\tuint32_t oob_bytes_done = 0;\n\tuint32_t mlc_isr;\n\tint retval;\n\n\tif (!data && oob) {\n\t\t/* MLC_CMD = Read OOB\n\t\t * we can use the READOOB command on both small and large page\n\t\t * devices, as the controller translates the 0x50 command to\n\t\t * a 0x0 with appropriate positioning of the serial buffer\n\t\t * read pointer\n\t\t */\n\t\tretval = target_write_u32(target, 0x200b8000, NAND_CMD_READOOB);\n\t} else {\n\t\t/* MLC_CMD = Read0 */\n\t\tretval = target_write_u32(target, 0x200b8000, NAND_CMD_READ0);\n\t}\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (nand->page_size == 512) {\n\t\t/* small page device\n\t\t * MLC_ADDR = 0x0 (one column cycle) */\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_ADDR = row */\n\t\tretval = target_write_u32(target, 0x200b8004, page & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t(page >> 8) & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (nand->address_cycles == 4) {\n\t\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t\t(page >> 16) & 0xff);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* large page device\n\t\t * MLC_ADDR = 0x0 (two column cycles) */\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004, 0x0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_ADDR = row */\n\t\tretval = target_write_u32(target, 0x200b8004, page & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tretval = target_write_u32(target, 0x200b8004,\n\t\t\t\t(page >> 8) & 0xff);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ADDR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\t/* MLC_CMD = Read Start */\n\t\tretval = target_write_u32(target, 0x200b8000,\n\t\t\t\tNAND_CMD_READSTART);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_CMD\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t}\n\n\twhile (page_bytes_done < (uint32_t)nand->page_size) {\n\t\t/* MLC_ECC_AUTO_DEC_REG = dummy */\n\t\tretval = target_write_u32(target, 0x200b8014, 0xaa55aa55);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not set MLC_ECC_AUTO_DEC_REG\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (!lpc32xx_controller_ready(nand, 1000)) {\n\t\t\tLOG_ERROR(\"timeout while waiting for \"\n\t\t\t\t\"completion of auto decode cycle\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tretval = target_read_u32(target, 0x200b8048, &mlc_isr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not read MLC_ISR\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\n\t\tif (mlc_isr & 0x8) {\n\t\t\tif (mlc_isr & 0x40) {\n\t\t\t\tLOG_ERROR(\"uncorrectable error detected: \"\n\t\t\t\t\t\"0x%2.2x\", (unsigned)mlc_isr);\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tLOG_WARNING(\"%i symbol error detected and corrected\",\n\t\t\t\t((int)(((mlc_isr & 0x30) >> 4) + 1)));\n\t\t}\n\n\t\tif (data) {\n\t\t\tretval = target_read_memory(target, 0x200a8000, 4, 128,\n\t\t\t\t\tpage_buffer + page_bytes_done);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not read MLC_BUF (data)\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\n\t\tif (oob) {\n\t\t\tretval = target_read_memory(target, 0x200a8000, 4, 4,\n\t\t\t\t\toob_buffer + oob_bytes_done);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not read MLC_BUF (oob)\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\n\t\tpage_bytes_done += 512;\n\t\toob_bytes_done += 16;\n\t}\n\n\tif (data)\n\t\tmemcpy(data, page_buffer, data_size);\n\n\tif (oob)\n\t\tmemcpy(oob, oob_buffer, oob_size);\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc32xx_read_page_slc(struct nand_device *nand,\n\tstruct working_area *pworking_area,\n\tuint32_t page, uint8_t *data,\n\tuint32_t data_size, uint8_t *oob,\n\tuint32_t oob_size)\n{\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint32_t target_mem_base;\n\n\tLOG_DEBUG(\"SLC read page %\" PRIx32 \" data=%\" PRIu32 \", oob=%\" PRIu32,\n\t\tpage, data_size, oob_size);\n\n\ttarget_mem_base = pworking_area->address;\n\n\t/* Make the dma descriptors in local memory */\n\tint nll = lpc32xx_make_dma_list(target_mem_base, nand->page_size, 1);\n\t/* Write them to target.\n\t   XXX: Assumes host and target have same byte sex.\n\t*/\n\tretval = target_write_memory(target, target_mem_base, 4,\n\t\t\tnll * sizeof(struct dmac_ll) / 4,\n\t\t\t(uint8_t *)dmalist);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not write DMA descriptors to IRAM\");\n\t\treturn retval;\n\t}\n\n\tretval = nand_page_command(nand, page, NAND_CMD_READ0, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"lpc32xx_read_page_slc: NAND_CMD_READ0 failed\");\n\t\treturn retval;\n\t}\n\n\t/* SLC_CFG =\n\t       Force nCE assert,\n\t       DMA ECC enabled,\n\t       ECC enabled,\n\t       DMA burst enabled,\n\t       DMA read from SLC,\n\t       WIDTH = bus_width\n\t*/\n\tretval = target_write_u32(target, 0x20020014, 0x3e);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"lpc32xx_read_page_slc: Could not set SLC_CFG\");\n\t\treturn retval;\n\t}\n\n\t/* Write first descriptor to DMA controller */\n\tretval = target_write_memory(target, 0x31000100, 4,\n\t\t\tsizeof(struct dmac_ll) / 4, (uint8_t *)dmalist);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not write DMA descriptor to DMAC\");\n\t\treturn retval;\n\t}\n\n\t/* Start xfer of data from flash to iram using DMA */\n\tint tot_size = nand->page_size;\n\ttot_size += nand->page_size == 2048 ? 64 : 16;\n\tretval = lpc32xx_start_slc_dma(nand, tot_size, 1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"lpc32xx_read_page_slc: DMA read failed\");\n\t\treturn retval;\n\t}\n\n\t/* Copy data from iram */\n\tif (data) {\n\t\tretval = target_read_memory(target, target_mem_base + DATA_OFFS,\n\t\t\t\t4, data_size/4, data);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read data from IRAM\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\tif (oob) {\n\t\t/* No error correction, just return data as read from flash */\n\t\tretval = target_read_memory(target,\n\t\t\t\ttarget_mem_base + SPARE_OFFS, 4,\n\t\t\t\toob_size/4, oob);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read OOB from IRAM\");\n\t\t\treturn retval;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Copy OOB from flash, stored in IRAM */\n\tstatic uint8_t foob[64];\n\tretval = target_read_memory(target, target_mem_base + SPARE_OFFS,\n\t\t\t4, nand->page_size == 2048 ? 16 : 4, foob);\n\tlpc32xx_dump_oob(foob, nand->page_size == 2048 ? 64 : 16);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read OOB from IRAM\");\n\t\treturn retval;\n\t}\n\t/* Copy ECC from HW, generated while reading */\n\tint ecc_count = nand->page_size == 2048 ? 8 : 2;\n\tstatic uint32_t hw_ecc[8];\t/* max size */\n\tretval = target_read_memory(target, target_mem_base + ECC_OFFS, 4,\n\t\t\tecc_count, (uint8_t *)hw_ecc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read hw generated ECC from IRAM\");\n\t\treturn retval;\n\t}\n\tstatic uint8_t ecc[24];\n\tslc_ecc_copy_to_buffer(ecc, hw_ecc, ecc_count);\n\t/* Copy ECC from flash using correct layout */\n\tstatic uint8_t fecc[24];/* max size */\n\tconst int *layout = nand->page_size == 2048 ? lp_ooblayout : sp_ooblayout;\n\tint i;\n\tfor (i = 0; i < ecc_count * 3; i++)\n\t\tfecc[i] = foob[layout[i]];\n\t/* Compare ECC and possibly correct data */\n\tfor (i = 0; i < ecc_count; i++) {\n\t\tretval = nand_correct_data(nand, data + 256*i, &fecc[i * 3],\n\t\t\t\t&ecc[i * 3]);\n\t\tif (retval > 0)\n\t\t\tLOG_WARNING(\"error detected and corrected: %\" PRIu32 \"/%d\",\n\t\t\t\tpage, i);\n\t\tif (retval < 0)\n\t\t\tbreak;\n\t}\n\tif (i == ecc_count)\n\t\tretval = ERROR_OK;\n\telse {\n\t\tLOG_ERROR(\"uncorrectable error detected: %\" PRIu32 \"/%d\", page, i);\n\t\tretval = ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn retval;\n}\n\nstatic int lpc32xx_read_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (lpc32xx_info->selected_controller == LPC32XX_NO_CONTROLLER) {\n\t\tLOG_ERROR(\"BUG: no LPC32xx NAND flash controller selected\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\tif (data_size > (uint32_t)nand->page_size) {\n\t\t\tLOG_ERROR(\"data size exceeds page size\");\n\t\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t\t}\n\t\tretval = lpc32xx_read_page_mlc(nand, page, data, data_size,\n\t\t\t\toob, oob_size);\n\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\tstruct working_area *pworking_area;\n\n\t\tretval = target_alloc_working_area(target,\n\t\t\t\tnand->page_size + 0x200,\n\t\t\t\t&pworking_area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't allocate working area in \"\n\t\t\t\t\"LPC internal RAM\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t\tretval = lpc32xx_read_page_slc(nand, pworking_area, page,\n\t\t\t\tdata, data_size, oob, oob_size);\n\t\ttarget_free_working_area(target, pworking_area);\n\t}\n\n\treturn retval;\n}\n\nstatic int lpc32xx_controller_ready(struct nand_device *nand, int timeout)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"lpc32xx_controller_ready count start=%d\", timeout);\n\n\tdo {\n\t\tif (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t\tuint8_t status;\n\n\t\t\t/* Read MLC_ISR, wait for controller to become ready */\n\t\t\tretval = target_read_u8(target, 0x200b8048, &status);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not set MLC_STAT\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tif (status & 2) {\n\t\t\t\tLOG_DEBUG(\"lpc32xx_controller_ready count=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t\tuint32_t status;\n\n\t\t\t/* Read SLC_STAT and check READY bit */\n\t\t\tretval = target_read_u32(target, 0x20020018, &status);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not set SLC_STAT\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc32xx_controller_ready count=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic int lpc32xx_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use LPC32xx \"\n\t\t\t\"NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tLOG_DEBUG(\"lpc32xx_nand_ready count start=%d\", timeout);\n\n\tdo {\n\t\tif (lpc32xx_info->selected_controller == LPC32XX_MLC_CONTROLLER) {\n\t\t\tuint8_t status = 0x0;\n\n\t\t\t/* Read MLC_ISR, wait for NAND flash device to\n\t\t\t * become ready */\n\t\t\tretval = target_read_u8(target, 0x200b8048, &status);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not read MLC_ISR\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc32xx_nand_ready count end=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else if (lpc32xx_info->selected_controller == LPC32XX_SLC_CONTROLLER) {\n\t\t\tuint32_t status = 0x0;\n\n\t\t\t/* Read SLC_STAT and check READY bit */\n\t\t\tretval = target_read_u32(target, 0x20020018, &status);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"could not read SLC_STAT\");\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tif (status & 1) {\n\t\t\t\tLOG_DEBUG(\"lpc32xx_nand_ready count end=%d\",\n\t\t\t\t\ttimeout);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstatic int lpc32xx_tc_ready(struct nand_device *nand, int timeout)\n{\n\tstruct target *target = nand->target;\n\n\tLOG_DEBUG(\"lpc32xx_tc_ready count start=%d\", timeout);\n\n\tdo {\n\t\tuint32_t status = 0x0;\n\t\tint retval;\n\t\t/* Read SLC_INT_STAT and check INT_TC_STAT bit */\n\t\tretval = target_read_u32(target, 0x2002001c, &status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read SLC_INT_STAT\");\n\t\t\treturn 0;\n\t\t}\n\t\tif (status & 2) {\n\t\t\tLOG_DEBUG(\"lpc32xx_tc_ready count=%d\", timeout);\n\t\t\treturn 1;\n\t\t}\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nCOMMAND_HANDLER(handle_lpc32xx_select_command)\n{\n\tstruct lpc32xx_nand_controller *lpc32xx_info = NULL;\n\tchar *selected[] = {\n\t\t\"no\", \"mlc\", \"slc\"\n\t};\n\n\tif ((CMD_ARGC < 1) || (CMD_ARGC > 3))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned num;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\tstruct nand_device *nand = get_nand_device_by_num(num);\n\tif (!nand) {\n\t\tcommand_print(CMD, \"nand device '#%s' is out of bounds\",\n\t\t\tCMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tlpc32xx_info = nand->controller_priv;\n\n\tif (CMD_ARGC >= 2) {\n\t\tif (strcmp(CMD_ARGV[1], \"mlc\") == 0) {\n\t\t\tlpc32xx_info->selected_controller =\n\t\t\t\tLPC32XX_MLC_CONTROLLER;\n\t\t} else if (strcmp(CMD_ARGV[1], \"slc\") == 0) {\n\t\t\tlpc32xx_info->selected_controller =\n\t\t\t\tLPC32XX_SLC_CONTROLLER;\n\t\t} else\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD, \"%s controller selected\",\n\t\tselected[lpc32xx_info->selected_controller]);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration lpc32xx_exec_command_handlers[] = {\n\t{\n\t\t.name = \"select\",\n\t\t.handler = handle_lpc32xx_select_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"select MLC or SLC controller (default is MLC)\",\n\t\t.usage = \"bank_id ['mlc'|'slc' ]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration lpc32xx_command_handler[] = {\n\t{\n\t\t.name = \"lpc32xx\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"LPC32xx NAND flash controller commands\",\n\t\t.usage = \"\",\n\t\t.chain = lpc32xx_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct nand_flash_controller lpc32xx_nand_controller = {\n\t.name = \"lpc32xx\",\n\t.commands = lpc32xx_command_handler,\n\t.nand_device_command = lpc32xx_nand_device_command,\n\t.init = lpc32xx_init,\n\t.reset = lpc32xx_reset,\n\t.command = lpc32xx_command,\n\t.address = lpc32xx_address,\n\t.write_data = lpc32xx_write_data,\n\t.read_data = lpc32xx_read_data,\n\t.write_page = lpc32xx_write_page,\n\t.read_page = lpc32xx_read_page,\n\t.nand_ready = lpc32xx_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/lpc32xx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_LPC32XX_H\n#define OPENOCD_FLASH_NAND_LPC32XX_H\n\nenum lpc32xx_selected_controller {\n\tLPC32XX_NO_CONTROLLER,\n\tLPC32XX_MLC_CONTROLLER,\n\tLPC32XX_SLC_CONTROLLER,\n};\n\nstruct lpc32xx_nand_controller {\n\tint osc_freq;\n\tenum lpc32xx_selected_controller selected_controller;\n\tint sw_write_protection;\n\tuint32_t sw_wp_lower_bound;\n\tuint32_t sw_wp_upper_bound;\n};\n\n#endif /* OPENOCD_FLASH_NAND_LPC32XX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/mx3.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n\n/***************************************************************************\n *   Copyright (C) 2009 by Alexei Babich                                   *\n *   Rezonans plc., Chelyabinsk, Russia                                    *\n *   impatt@mail.ru                                                        *\n ***************************************************************************/\n\n/*\n * Freescale iMX3* OpenOCD NAND Flash controller support.\n *\n * Many thanks to Ben Dooks for writing s3c24xx driver.\n */\n\n/*\ndriver tested with STMicro NAND512W3A @imx31\ntested \"nand probe #\", \"nand erase # 0 #\", \"nand dump # file 0 #\", \"nand write # file 0\"\nget_next_halfword_from_sram_buffer() not tested\n*/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"mx3.h\"\n#include <target/target.h>\n\nstatic const char target_not_halted_err_msg[] =\n\t\t\"target must be halted to use mx3 NAND flash controller\";\nstatic const char data_block_size_err_msg[] =\n\t\t\"minimal granularity is one half-word, %\" PRIu32 \" is incorrect\";\nstatic const char sram_buffer_bounds_err_msg[] =\n\t\t\"trying to access out of SRAM buffer bound (addr=0x%\" PRIx32 \")\";\nstatic const char get_status_register_err_msg[] = \"can't get NAND status\";\nstatic uint32_t in_sram_address;\nstatic unsigned char sign_of_sequental_byte_read;\n\nstatic int test_iomux_settings(struct target *target, uint32_t value,\n\t\tuint32_t mask, const char *text);\nstatic int initialize_nf_controller(struct nand_device *nand);\nstatic int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value);\nstatic int get_next_halfword_from_sram_buffer(struct target *target,\n\t\tuint16_t *value);\nstatic int poll_for_complete_op(struct target *target, const char *text);\nstatic int validate_target_state(struct nand_device *nand);\nstatic int do_data_output(struct nand_device *nand);\n\nstatic int imx31_command(struct nand_device *nand, uint8_t command);\nstatic int imx31_address(struct nand_device *nand, uint8_t address);\n\nNAND_DEVICE_COMMAND_HANDLER(imx31_nand_device_command)\n{\n\tstruct mx3_nf_controller *mx3_nf_info;\n\tmx3_nf_info = malloc(sizeof(struct mx3_nf_controller));\n\tif (!mx3_nf_info) {\n\t\tLOG_ERROR(\"no memory for nand controller\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tnand->controller_priv = mx3_nf_info;\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t/*\n\t* check hwecc requirements\n\t*/\n\t{\n\t\tint hwecc_needed;\n\t\thwecc_needed = strcmp(CMD_ARGV[2], \"hwecc\");\n\t\tif (hwecc_needed == 0)\n\t\t\tmx3_nf_info->flags.hw_ecc_enabled = 1;\n\t\telse\n\t\t\tmx3_nf_info->flags.hw_ecc_enabled = 0;\n\t}\n\n\tmx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;\n\tmx3_nf_info->fin = MX3_NF_FIN_NONE;\n\tmx3_nf_info->flags.target_little_endian =\n\t\t\t(nand->target->endianness == TARGET_LITTLE_ENDIAN);\n\n\treturn ERROR_OK;\n}\n\nstatic int imx31_init(struct nand_device *nand)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint validate_target_result;\n\t\tvalidate_target_result = validate_target_state(nand);\n\t\tif (validate_target_result != ERROR_OK)\n\t\t\treturn validate_target_result;\n\t}\n\n\t{\n\t\tuint16_t buffsize_register_content;\n\t\ttarget_read_u16(target, MX3_NF_BUFSIZ, &buffsize_register_content);\n\t\tmx3_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f);\n\t}\n\n\t{\n\t\tuint32_t pcsr_register_content;\n\t\ttarget_read_u32(target, MX3_PCSR, &pcsr_register_content);\n\t\tif (!nand->bus_width) {\n\t\t\tnand->bus_width = (pcsr_register_content & 0x80000000) ? 16 : 8;\n\t\t} else {\n\t\t\tpcsr_register_content |= ((nand->bus_width == 16) ? 0x80000000 : 0x00000000);\n\t\t\ttarget_write_u32(target, MX3_PCSR, pcsr_register_content);\n\t\t}\n\n\t\tif (!nand->page_size) {\n\t\t\tnand->page_size = (pcsr_register_content & 0x40000000) ? 2048 : 512;\n\t\t} else {\n\t\t\tpcsr_register_content |= ((nand->page_size == 2048) ? 0x40000000 : 0x00000000);\n\t\t\ttarget_write_u32(target, MX3_PCSR, pcsr_register_content);\n\t\t}\n\t\tif (mx3_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) {\n\t\t\tLOG_ERROR(\"NAND controller have only 1 kb SRAM, \"\n\t\t\t\t\t\"so pagesize 2048 is incompatible with it\");\n\t\t}\n\t}\n\n\t{\n\t\tuint32_t cgr_register_content;\n\t\ttarget_read_u32(target, MX3_CCM_CGR2, &cgr_register_content);\n\t\tif (!(cgr_register_content & 0x00000300)) {\n\t\t\tLOG_ERROR(\"clock gating to EMI disabled\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t{\n\t\tuint32_t gpr_register_content;\n\t\ttarget_read_u32(target, MX3_GPR, &gpr_register_content);\n\t\tif (gpr_register_content & 0x00000060) {\n\t\t\tLOG_ERROR(\"pins mode overridden by GPR\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t{\n\t\t/*\n\t\t * testing IOMUX settings; must be in \"functional-mode output and\n\t\t * functional-mode input\" mode\n\t\t */\n\t\tint test_iomux;\n\t\ttest_iomux = ERROR_OK;\n\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0c0, 0x7f7f7f00, \"d0,d1,d2\");\n\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0c4, 0x7f7f7f7f, \"d3,d4,d5,d6\");\n\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x0000007f, \"d7\");\n\t\tif (nand->bus_width == 16) {\n\t\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0c8, 0x7f7f7f00, \"d8,d9,d10\");\n\t\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0cc, 0x7f7f7f7f, \"d11,d12,d13,d14\");\n\t\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x0000007f, \"d15\");\n\t\t}\n\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0d0, 0x7f7f7f00, \"nfwp,nfce,nfrb\");\n\t\ttest_iomux |= test_iomux_settings(target, 0x43fac0d4, 0x7f7f7f7f,\n\t\t\t\t\"nfwe,nfre,nfale,nfcle\");\n\t\tif (test_iomux != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tinitialize_nf_controller(nand);\n\n\t{\n\t\tint retval;\n\t\tuint16_t nand_status_content;\n\t\tretval = ERROR_OK;\n\t\tretval |= imx31_command(nand, NAND_CMD_STATUS);\n\t\tretval |= imx31_address(nand, 0x00);\n\t\tretval |= do_data_output(nand);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(get_status_register_err_msg);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\ttarget_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content);\n\t\tif (!(nand_status_content & 0x0080)) {\n\t\t\t/*\n\t\t\t * is host-big-endian correctly ??\n\t\t\t */\n\t\t\tLOG_INFO(\"NAND read-only\");\n\t\t\tmx3_nf_info->flags.nand_readonly = 1;\n\t\t} else\n\t\t\tmx3_nf_info->flags.nand_readonly = 0;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int imx31_read_data(struct nand_device *nand, void *data)\n{\n\tstruct target *target = nand->target;\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint validate_target_result;\n\t\tvalidate_target_result = validate_target_state(nand);\n\t\tif (validate_target_result != ERROR_OK)\n\t\t\treturn validate_target_result;\n\t}\n\n\t{\n\t\t/*\n\t\t * get data from nand chip\n\t\t */\n\t\tint try_data_output_from_nand_chip;\n\t\ttry_data_output_from_nand_chip = do_data_output(nand);\n\t\tif (try_data_output_from_nand_chip != ERROR_OK)\n\t\t\treturn try_data_output_from_nand_chip;\n\t}\n\n\tif (nand->bus_width == 16)\n\t\tget_next_halfword_from_sram_buffer(target, data);\n\telse\n\t\tget_next_byte_from_sram_buffer(target, data);\n\n\treturn ERROR_OK;\n}\n\nstatic int imx31_write_data(struct nand_device *nand, uint16_t data)\n{\n\tLOG_ERROR(\"write_data() not implemented\");\n\treturn ERROR_NAND_OPERATION_FAILED;\n}\n\nstatic int imx31_reset(struct nand_device *nand)\n{\n\t/*\n\t* validate target state\n\t*/\n\tint validate_target_result;\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\tinitialize_nf_controller(nand);\n\treturn ERROR_OK;\n}\n\nstatic int imx31_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint validate_target_result;\n\t\tvalidate_target_result = validate_target_state(nand);\n\t\tif (validate_target_result != ERROR_OK)\n\t\t\treturn validate_target_result;\n\t}\n\n\tswitch (command) {\n\t\tcase NAND_CMD_READOOB:\n\t\t\tcommand = NAND_CMD_READ0;\n\t\t\tin_sram_address = MX3_NF_SPARE_BUFFER0;\t/* set read point for\n\t\t\t\t\t\t\t\t* data_read() and\n\t\t\t\t\t\t\t\t* read_block_data() to\n\t\t\t\t\t\t\t\t* spare area in SRAM\n\t\t\t\t\t\t\t\t* buffer */\n\t\t\tbreak;\n\t\tcase NAND_CMD_READ1:\n\t\t\tcommand = NAND_CMD_READ0;\n\t\t\t/*\n\t\t\t * offset == one half of page size\n\t\t\t */\n\t\t\tin_sram_address = MX3_NF_MAIN_BUFFER0 + (nand->page_size >> 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tin_sram_address = MX3_NF_MAIN_BUFFER0;\n\t}\n\n\ttarget_write_u16(target, MX3_NF_FCMD, command);\n\t/*\n\t* start command input operation (set MX3_NF_BIT_OP_DONE==0)\n\t*/\n\ttarget_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FCI);\n\t{\n\t\tint poll_result;\n\t\tpoll_result = poll_for_complete_op(target, \"command\");\n\t\tif (poll_result != ERROR_OK)\n\t\t\treturn poll_result;\n\t}\n\t/*\n\t* reset cursor to begin of the buffer\n\t*/\n\tsign_of_sequental_byte_read = 0;\n\tswitch (command) {\n\t\tcase NAND_CMD_READID:\n\t\t\tmx3_nf_info->optype = MX3_NF_DATAOUT_NANDID;\n\t\t\tmx3_nf_info->fin = MX3_NF_FIN_DATAOUT;\n\t\t\tbreak;\n\t\tcase NAND_CMD_STATUS:\n\t\t\tmx3_nf_info->optype = MX3_NF_DATAOUT_NANDSTATUS;\n\t\t\tmx3_nf_info->fin = MX3_NF_FIN_DATAOUT;\n\t\t\tbreak;\n\t\tcase NAND_CMD_READ0:\n\t\t\tmx3_nf_info->fin = MX3_NF_FIN_DATAOUT;\n\t\t\tmx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmx3_nf_info->optype = MX3_NF_DATAOUT_PAGE;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int imx31_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct target *target = nand->target;\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint validate_target_result;\n\t\tvalidate_target_result = validate_target_state(nand);\n\t\tif (validate_target_result != ERROR_OK)\n\t\t\treturn validate_target_result;\n\t}\n\n\ttarget_write_u16(target, MX3_NF_FADDR, address);\n\t/*\n\t* start address input operation (set MX3_NF_BIT_OP_DONE==0)\n\t*/\n\ttarget_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FAI);\n\t{\n\t\tint poll_result;\n\t\tpoll_result = poll_for_complete_op(target, \"address\");\n\t\tif (poll_result != ERROR_OK)\n\t\t\treturn poll_result;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int imx31_nand_ready(struct nand_device *nand, int tout)\n{\n\tuint16_t poll_complete_status;\n\tstruct target *target = nand->target;\n\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint validate_target_result;\n\t\tvalidate_target_result = validate_target_state(nand);\n\t\tif (validate_target_result != ERROR_OK)\n\t\t\treturn validate_target_result;\n\t}\n\n\tdo {\n\t\ttarget_read_u16(target, MX3_NF_CFG2, &poll_complete_status);\n\t\tif (poll_complete_status & MX3_NF_BIT_OP_DONE)\n\t\t\treturn tout;\n\t\talive_sleep(1);\n\t} while (tout-- > 0);\n\treturn tout;\n}\n\nstatic int imx31_write_page(struct nand_device *nand, uint32_t page,\n\t\tuint8_t *data, uint32_t data_size, uint8_t *oob,\n\t\tuint32_t oob_size)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (data_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, data_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (oob_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, oob_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (!data) {\n\t\tLOG_ERROR(\"nothing to program\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint retval;\n\t\tretval = validate_target_state(nand);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\t{\n\t\tint retval = ERROR_OK;\n\t\tretval |= imx31_command(nand, NAND_CMD_SEQIN);\n\t\tretval |= imx31_address(nand, 0x00);\n\t\tretval |= imx31_address(nand, page & 0xff);\n\t\tretval |= imx31_address(nand, (page >> 8) & 0xff);\n\t\tif (nand->address_cycles >= 4) {\n\t\t\tretval |= imx31_address(nand, (page >> 16) & 0xff);\n\t\t\tif (nand->address_cycles >= 5)\n\t\t\t\tretval |= imx31_address(nand, (page >> 24) & 0xff);\n\t\t}\n\t\ttarget_write_buffer(target, MX3_NF_MAIN_BUFFER0, data_size, data);\n\t\tif (oob) {\n\t\t\tif (mx3_nf_info->flags.hw_ecc_enabled) {\n\t\t\t\t/*\n\t\t\t\t * part of spare block will be overridden by hardware\n\t\t\t\t * ECC generator\n\t\t\t\t */\n\t\t\t\tLOG_DEBUG(\"part of spare block will be overridden by hardware ECC generator\");\n\t\t\t}\n\t\t\ttarget_write_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size, oob);\n\t\t}\n\t\t/*\n\t\t * start data input operation (set MX3_NF_BIT_OP_DONE==0)\n\t\t */\n\t\ttarget_write_u16(target, MX3_NF_CFG2, MX3_NF_BIT_OP_FDI);\n\t\t{\n\t\t\tint poll_result;\n\t\t\tpoll_result = poll_for_complete_op(target, \"data input\");\n\t\t\tif (poll_result != ERROR_OK)\n\t\t\t\treturn poll_result;\n\t\t}\n\t\tretval |= imx31_command(nand, NAND_CMD_PAGEPROG);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/*\n\t\t * check status register\n\t\t */\n\t\t{\n\t\t\tuint16_t nand_status_content;\n\t\t\tretval = ERROR_OK;\n\t\t\tretval |= imx31_command(nand, NAND_CMD_STATUS);\n\t\t\tretval |= imx31_address(nand, 0x00);\n\t\t\tretval |= do_data_output(nand);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(get_status_register_err_msg);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\ttarget_read_u16(target, MX3_NF_MAIN_BUFFER0, &nand_status_content);\n\t\t\tif (nand_status_content & 0x0001) {\n\t\t\t\t/*\n\t\t\t\t * is host-big-endian correctly ??\n\t\t\t\t */\n\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int imx31_read_page(struct nand_device *nand, uint32_t page,\n\t\tuint8_t *data, uint32_t data_size, uint8_t *oob,\n\t\tuint32_t oob_size)\n{\n\tstruct target *target = nand->target;\n\n\tif (data_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, data_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (oob_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, oob_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t{\n\t\t/*\n\t\t * validate target state\n\t\t */\n\t\tint retval;\n\t\tretval = validate_target_state(nand);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\t{\n\t\tint retval = ERROR_OK;\n\t\tretval |= imx31_command(nand, NAND_CMD_READ0);\n\t\tretval |= imx31_address(nand, 0x00);\n\t\tretval |= imx31_address(nand, page & 0xff);\n\t\tretval |= imx31_address(nand, (page >> 8) & 0xff);\n\t\tif (nand->address_cycles >= 4) {\n\t\t\tretval |= imx31_address(nand, (page >> 16) & 0xff);\n\t\t\tif (nand->address_cycles >= 5) {\n\t\t\t\tretval |= imx31_address(nand, (page >> 24) & 0xff);\n\t\t\t\tretval |= imx31_command(nand, NAND_CMD_READSTART);\n\t\t\t}\n\t\t}\n\t\tretval |= do_data_output(nand);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (data) {\n\t\t\ttarget_read_buffer(target, MX3_NF_MAIN_BUFFER0, data_size,\n\t\t\t\tdata);\n\t\t}\n\t\tif (oob) {\n\t\t\ttarget_read_buffer(target, MX3_NF_SPARE_BUFFER0, oob_size,\n\t\t\t\toob);\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int test_iomux_settings(struct target *target, uint32_t address,\n\t\tuint32_t mask, const char *text)\n{\n\tuint32_t register_content;\n\ttarget_read_u32(target, address, &register_content);\n\tif ((register_content & mask) != (0x12121212 & mask)) {\n\t\tLOG_ERROR(\"IOMUX for {%s} is bad\", text);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int initialize_nf_controller(struct nand_device *nand)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\t/*\n\t* resets NAND flash controller in zero time ? I don't know.\n\t*/\n\ttarget_write_u16(target, MX3_NF_CFG1, MX3_NF_BIT_RESET_EN);\n\t{\n\t\tuint16_t work_mode;\n\t\twork_mode = MX3_NF_BIT_INT_DIS;\t/* disable interrupt */\n\t\tif (target->endianness == TARGET_BIG_ENDIAN)\n\t\t\twork_mode |= MX3_NF_BIT_BE_EN;\n\t\tif (mx3_nf_info->flags.hw_ecc_enabled)\n\t\t\twork_mode |= MX3_NF_BIT_ECC_EN;\n\t\ttarget_write_u16(target, MX3_NF_CFG1, work_mode);\n\t}\n\t/*\n\t* unlock SRAM buffer for write; 2 mean \"Unlock\", other values means \"Lock\"\n\t*/\n\ttarget_write_u16(target, MX3_NF_BUFCFG, 2);\n\t{\n\t\tuint16_t temp;\n\t\ttarget_read_u16(target, MX3_NF_FWP, &temp);\n\t\tif ((temp & 0x0007) == 1) {\n\t\t\tLOG_ERROR(\"NAND flash is tight-locked, reset needed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t}\n\t/*\n\t* unlock NAND flash for write\n\t*/\n\ttarget_write_u16(target, MX3_NF_FWP, 4);\n\ttarget_write_u16(target, MX3_NF_LOCKSTART, 0x0000);\n\ttarget_write_u16(target, MX3_NF_LOCKEND, 0xFFFF);\n\t/*\n\t* 0x0000 means that first SRAM buffer @0xB800_0000 will be used\n\t*/\n\ttarget_write_u16(target, MX3_NF_BUFADDR, 0x0000);\n\t/*\n\t* address of SRAM buffer\n\t*/\n\tin_sram_address = MX3_NF_MAIN_BUFFER0;\n\tsign_of_sequental_byte_read = 0;\n\treturn ERROR_OK;\n}\n\nstatic int get_next_byte_from_sram_buffer(struct target *target, uint8_t *value)\n{\n\tstatic uint8_t even_byte;\n\t/*\n\t* host-big_endian ??\n\t*/\n\tif (sign_of_sequental_byte_read == 0)\n\t\teven_byte = 0;\n\tif (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) {\n\t\tLOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);\n\t\t*value = 0;\n\t\tsign_of_sequental_byte_read = 0;\n\t\teven_byte = 0;\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else {\n\t\tuint16_t temp;\n\t\ttarget_read_u16(target, in_sram_address, &temp);\n\t\tif (even_byte) {\n\t\t\t*value = temp >> 8;\n\t\t\teven_byte = 0;\n\t\t\tin_sram_address += 2;\n\t\t} else {\n\t\t\t*value = temp & 0xff;\n\t\t\teven_byte = 1;\n\t\t}\n\t}\n\tsign_of_sequental_byte_read = 1;\n\treturn ERROR_OK;\n}\n\nstatic int get_next_halfword_from_sram_buffer(struct target *target,\n\t\tuint16_t *value)\n{\n\tif (in_sram_address > MX3_NF_LAST_BUFFER_ADDR) {\n\t\tLOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);\n\t\t*value = 0;\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else {\n\t\ttarget_read_u16(target, in_sram_address, value);\n\t\tin_sram_address += 2;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int poll_for_complete_op(struct target *target, const char *text)\n{\n\tuint16_t poll_complete_status;\n\tfor (int poll_cycle_count = 0; poll_cycle_count < 100; poll_cycle_count++) {\n\t\tusleep(25);\n\t\ttarget_read_u16(target, MX3_NF_CFG2, &poll_complete_status);\n\t\tif (poll_complete_status & MX3_NF_BIT_OP_DONE)\n\t\t\tbreak;\n\t}\n\tif (!(poll_complete_status & MX3_NF_BIT_OP_DONE)) {\n\t\tLOG_ERROR(\"%s sending timeout\", text);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int validate_target_state(struct nand_device *nand)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(target_not_halted_err_msg);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (mx3_nf_info->flags.target_little_endian !=\n\t\t\t(target->endianness == TARGET_LITTLE_ENDIAN)) {\n\t\t/*\n\t\t * endianness changed after NAND controller probed\n\t\t */\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int do_data_output(struct nand_device *nand)\n{\n\tstruct mx3_nf_controller *mx3_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tswitch (mx3_nf_info->fin) {\n\t\tcase MX3_NF_FIN_DATAOUT:\n\t\t\t/*\n\t\t\t * start data output operation (set MX3_NF_BIT_OP_DONE==0)\n\t\t\t */\n\t\t\ttarget_write_u16 (target, MX3_NF_CFG2,\n\t\t\t\t\tMX3_NF_BIT_DATAOUT_TYPE(mx3_nf_info->optype));\n\t\t\t{\n\t\t\t\tint poll_result;\n\t\t\t\tpoll_result = poll_for_complete_op(target, \"data output\");\n\t\t\t\tif (poll_result != ERROR_OK)\n\t\t\t\t\treturn poll_result;\n\t\t\t}\n\t\t\tmx3_nf_info->fin = MX3_NF_FIN_NONE;\n\t\t\t/*\n\t\t\t * ECC stuff\n\t\t\t */\n\t\t\tif ((mx3_nf_info->optype == MX3_NF_DATAOUT_PAGE)\n\t\t\t\t\t&& mx3_nf_info->flags.hw_ecc_enabled) {\n\t\t\t\tuint16_t ecc_status;\n\t\t\t\ttarget_read_u16 (target, MX3_NF_ECCSTATUS, &ecc_status);\n\t\t\t\tswitch (ecc_status & 0x000c) {\n\t\t\t\tcase 1 << 2:\n\t\t\t\t\tLOG_DEBUG(\"main area read with 1 (correctable) error\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2 << 2:\n\t\t\t\t\tLOG_DEBUG(\"main area read with more than 1 (incorrectable) error\");\n\t\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t\t}\n\t\t\t\tswitch (ecc_status & 0x0003) {\n\t\t\t\tcase 1:\n\t\t\t\t\tLOG_DEBUG(\"spare area read with 1 (correctable) error\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tLOG_DEBUG(\"main area read with more than 1 (incorrectable) error\");\n\t\t\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase MX3_NF_FIN_NONE:\n\t\t\tbreak;\n\t}\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller imx31_nand_flash_controller = {\n\t.name = \"imx31\",\n\t.usage = \"nand device imx31 target noecc|hwecc\",\n\t.nand_device_command = &imx31_nand_device_command,\n\t.init = &imx31_init,\n\t.reset = &imx31_reset,\n\t.command = &imx31_command,\n\t.address = &imx31_address,\n\t.write_data = &imx31_write_data,\n\t.read_data = &imx31_read_data,\n\t.write_page = &imx31_write_page,\n\t.read_page = &imx31_read_page,\n\t.nand_ready = &imx31_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/mx3.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Alexei Babich                                   *\n *   Rezonans plc., Chelyabinsk, Russia                                    *\n *   impatt@mail.ru                                                        *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_MX3_H\n#define OPENOCD_FLASH_NAND_MX3_H\n\n/*\n * Freescale iMX3* OpenOCD NAND Flash controller support.\n *\n * Many thanks to Ben Dooks for writing s3c24xx driver.\n */\n\n#define MX3_NF_BASE_ADDR\t\t\t\t0xb8000000\n#define MX3_NF_BUFSIZ\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe00)\n#define MX3_NF_BUFADDR\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe04)\n#define MX3_NF_FADDR\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe06)\n#define MX3_NF_FCMD\t\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe08)\n#define MX3_NF_BUFCFG\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe0a)\n#define MX3_NF_ECCSTATUS\t\t\t\t(MX3_NF_BASE_ADDR + 0xe0c)\n#define MX3_NF_ECCMAINPOS\t\t\t\t(MX3_NF_BASE_ADDR + 0xe0e)\n#define MX3_NF_ECCSPAREPOS\t\t\t\t(MX3_NF_BASE_ADDR + 0xe10)\n#define MX3_NF_FWP\t\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe12)\n#define MX3_NF_LOCKSTART\t\t\t\t(MX3_NF_BASE_ADDR + 0xe14)\n#define MX3_NF_LOCKEND\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe16)\n#define MX3_NF_FWPSTATUS\t\t\t\t(MX3_NF_BASE_ADDR + 0xe18)\n/*\n * all bits not marked as self-clearing bit\n */\n#define MX3_NF_CFG1\t\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe1a)\n#define MX3_NF_CFG2\t\t\t\t\t\t(MX3_NF_BASE_ADDR + 0xe1c)\n\n#define MX3_NF_MAIN_BUFFER0\t\t\t\t(MX3_NF_BASE_ADDR + 0x0000)\n#define MX3_NF_MAIN_BUFFER1\t\t\t\t(MX3_NF_BASE_ADDR + 0x0200)\n#define MX3_NF_MAIN_BUFFER2\t\t\t\t(MX3_NF_BASE_ADDR + 0x0400)\n#define MX3_NF_MAIN_BUFFER3\t\t\t\t(MX3_NF_BASE_ADDR + 0x0600)\n#define MX3_NF_SPARE_BUFFER0\t\t\t(MX3_NF_BASE_ADDR + 0x0800)\n#define MX3_NF_SPARE_BUFFER1\t\t\t(MX3_NF_BASE_ADDR + 0x0810)\n#define MX3_NF_SPARE_BUFFER2\t\t\t(MX3_NF_BASE_ADDR + 0x0820)\n#define MX3_NF_SPARE_BUFFER3\t\t\t(MX3_NF_BASE_ADDR + 0x0830)\n#define MX3_NF_MAIN_BUFFER_LEN\t\t\t512\n#define MX3_NF_SPARE_BUFFER_LEN\t\t\t16\n#define MX3_NF_LAST_BUFFER_ADDR\t\t\t((MX3_NF_SPARE_BUFFER3) + MX3_NF_SPARE_BUFFER_LEN - 2)\n\n/* bits in MX3_NF_CFG1 register */\n#define MX3_NF_BIT_SPARE_ONLY_EN\t\t(1<<2)\n#define MX3_NF_BIT_ECC_EN\t\t\t\t(1<<3)\n#define MX3_NF_BIT_INT_DIS\t\t\t\t(1<<4)\n#define MX3_NF_BIT_BE_EN\t\t\t\t(1<<5)\n#define MX3_NF_BIT_RESET_EN\t\t\t\t(1<<6)\n#define MX3_NF_BIT_FORCE_CE\t\t\t\t(1<<7)\n\n/* bits in MX3_NF_CFG2 register */\n\n/*Flash Command Input*/\n#define MX3_NF_BIT_OP_FCI\t\t\t\t(1<<0)\n/*\n * Flash Address Input\n */\n#define MX3_NF_BIT_OP_FAI\t\t\t\t(1<<1)\n/*\n * Flash Data Input\n */\n#define MX3_NF_BIT_OP_FDI\t\t\t\t(1<<2)\n\n/* see \"enum mx_dataout_type\" below */\n#define MX3_NF_BIT_DATAOUT_TYPE(x)\t\t((x)<<3)\n#define MX3_NF_BIT_OP_DONE\t\t\t\t(1<<15)\n\n#define MX3_CCM_CGR2\t\t\t\t\t0x53f80028\n#define MX3_GPR\t\t\t\t\t\t\t0x43fac008\n#define MX3_PCSR\t\t\t\t\t\t0x53f8000c\n\nenum mx_dataout_type {\n\tMX3_NF_DATAOUT_PAGE = 1,\n\tMX3_NF_DATAOUT_NANDID = 2,\n\tMX3_NF_DATAOUT_NANDSTATUS = 4,\n};\nenum mx_nf_finalize_action {\n\tMX3_NF_FIN_NONE,\n\tMX3_NF_FIN_DATAOUT,\n};\n\nstruct mx3_nf_flags {\n\tunsigned target_little_endian:1;\n\tunsigned nand_readonly:1;\n\tunsigned one_kb_sram:1;\n\tunsigned hw_ecc_enabled:1;\n};\n\nstruct mx3_nf_controller {\n\tenum mx_dataout_type optype;\n\tenum mx_nf_finalize_action fin;\n\tstruct mx3_nf_flags flags;\n};\n\n#endif /* OPENOCD_FLASH_NAND_MX3_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/mxc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Alexei Babich                                   *\n *   Rezonans plc., Chelyabinsk, Russia                                    *\n *   impatt@mail.ru                                                        *\n *                                                                         *\n *   Copyright (C) 2010 by Gaetan CARLIER                                  *\n *   Trump s.a., Belgium                                                   *\n *                                                                         *\n *   Copyright (C) 2011 by Erik Ahlen                                      *\n *   Avalon Innovation, Sweden                                             *\n ***************************************************************************/\n\n/*\n * Freescale iMX OpenOCD NAND Flash controller support.\n * based on Freescale iMX2* and iMX3* OpenOCD NAND Flash controller support.\n */\n\n/*\n * driver tested with Samsung K9F2G08UXA and Numonyx/ST NAND02G-B2D @mxc\n * tested \"nand probe #\", \"nand erase # 0 #\", \"nand dump # file 0 #\",\n * \"nand write # file 0\", \"nand verify\"\n *\n * get_next_halfword_from_sram_buffer() not tested\n * !! all function only tested with 2k page nand device; mxc_write_page\n *    writes the 4 MAIN_BUFFER's and is not compatible with < 2k page\n * !! oob must be be used due to NFS bug\n * !! oob must be 64 bytes per 2KiB page\n*/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"mxc.h\"\n#include <target/target.h>\n\n#define OOB_SIZE        64\n\n#define nfc_is_v1() (mxc_nf_info->mxc_version == MXC_VERSION_MX27 || \\\n\t\tmxc_nf_info->mxc_version == MXC_VERSION_MX31)\n#define nfc_is_v2() (mxc_nf_info->mxc_version == MXC_VERSION_MX25 || \\\n\t\tmxc_nf_info->mxc_version == MXC_VERSION_MX35)\n\n/* This permits to print (in LOG_INFO) how much bytes\n * has been written after a page read or write.\n * This is useful when OpenOCD is used with a graphical\n * front-end to estimate progression of the global read/write\n */\n#undef _MXC_PRINT_STAT\n/* #define _MXC_PRINT_STAT */\n\nstatic const char target_not_halted_err_msg[] =\n\t\"target must be halted to use mxc NAND flash controller\";\nstatic const char data_block_size_err_msg[] =\n\t\"minimal granularity is one half-word, %\" PRIu32 \" is incorrect\";\nstatic const char sram_buffer_bounds_err_msg[] =\n\t\"trying to access out of SRAM buffer bound (addr=0x%\" PRIx32 \")\";\nstatic const char get_status_register_err_msg[] = \"can't get NAND status\";\nstatic uint32_t in_sram_address;\nstatic unsigned char sign_of_sequental_byte_read;\n\nstatic uint32_t align_address_v2(struct nand_device *nand, uint32_t addr);\nstatic int initialize_nf_controller(struct nand_device *nand);\nstatic int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *value);\nstatic int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t *value);\nstatic int poll_for_complete_op(struct nand_device *nand, const char *text);\nstatic int validate_target_state(struct nand_device *nand);\nstatic int do_data_output(struct nand_device *nand);\n\nstatic int mxc_command(struct nand_device *nand, uint8_t command);\nstatic int mxc_address(struct nand_device *nand, uint8_t address);\n\nNAND_DEVICE_COMMAND_HANDLER(mxc_nand_device_command)\n{\n\tstruct mxc_nf_controller *mxc_nf_info;\n\tint hwecc_needed;\n\n\tmxc_nf_info = malloc(sizeof(struct mxc_nf_controller));\n\tif (!mxc_nf_info) {\n\t\tLOG_ERROR(\"no memory for nand controller\");\n\t\treturn ERROR_FAIL;\n\t}\n\tnand->controller_priv = mxc_nf_info;\n\n\tif (CMD_ARGC < 4) {\n\t\tLOG_ERROR(\"use \\\"nand device mxc target mx25|mx27|mx31|mx35 noecc|hwecc [biswap]\\\"\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * check board type\n\t */\n\tif (strcmp(CMD_ARGV[2], \"mx25\") == 0) {\n\t\tmxc_nf_info->mxc_version = MXC_VERSION_MX25;\n\t\tmxc_nf_info->mxc_base_addr = 0xBB000000;\n\t\tmxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x1E00;\n\t} else if (strcmp(CMD_ARGV[2], \"mx27\") == 0) {\n\t\tmxc_nf_info->mxc_version = MXC_VERSION_MX27;\n\t\tmxc_nf_info->mxc_base_addr = 0xD8000000;\n\t\tmxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x0E00;\n\t} else if (strcmp(CMD_ARGV[2], \"mx31\") == 0) {\n\t\tmxc_nf_info->mxc_version = MXC_VERSION_MX31;\n\t\tmxc_nf_info->mxc_base_addr = 0xB8000000;\n\t\tmxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x0E00;\n\t} else if (strcmp(CMD_ARGV[2], \"mx35\") == 0) {\n\t\tmxc_nf_info->mxc_version = MXC_VERSION_MX35;\n\t\tmxc_nf_info->mxc_base_addr = 0xBB000000;\n\t\tmxc_nf_info->mxc_regs_addr = mxc_nf_info->mxc_base_addr + 0x1E00;\n\t}\n\n\t/*\n\t * check hwecc requirements\n\t */\n\thwecc_needed = strcmp(CMD_ARGV[3], \"hwecc\");\n\tif (hwecc_needed == 0)\n\t\tmxc_nf_info->flags.hw_ecc_enabled = 1;\n\telse\n\t\tmxc_nf_info->flags.hw_ecc_enabled = 0;\n\n\tmxc_nf_info->optype = MXC_NF_DATAOUT_PAGE;\n\tmxc_nf_info->fin = MXC_NF_FIN_NONE;\n\tmxc_nf_info->flags.target_little_endian =\n\t\t(nand->target->endianness == TARGET_LITTLE_ENDIAN);\n\n\t/*\n\t * should factory bad block indicator be swapped\n\t * as a workaround for how the nfc handles pages.\n\t */\n\tif (CMD_ARGC > 4 && strcmp(CMD_ARGV[4], \"biswap\") == 0) {\n\t\tLOG_DEBUG(\"BI-swap enabled\");\n\t\tmxc_nf_info->flags.biswap_enabled = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_mxc_biswap_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct mxc_nf_controller *mxc_nf_info = NULL;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &nand);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"invalid nand device number or name: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tmxc_nf_info = nand->controller_priv;\n\tif (CMD_ARGC == 2) {\n\t\tif (strcmp(CMD_ARGV[1], \"enable\") == 0)\n\t\t\tmxc_nf_info->flags.biswap_enabled = true;\n\t\telse\n\t\t\tmxc_nf_info->flags.biswap_enabled = false;\n\t}\n\tif (mxc_nf_info->flags.biswap_enabled)\n\t\tcommand_print(CMD, \"BI-swapping enabled on %s\", nand->name);\n\telse\n\t\tcommand_print(CMD, \"BI-swapping disabled on %s\", nand->name);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration mxc_sub_command_handlers[] = {\n\t{\n\t\t.name = \"biswap\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_mxc_biswap_command,\n\t\t.help = \"Turns on/off bad block information swapping from main area, \"\n\t\t\t\"without parameter query status.\",\n\t\t.usage = \"bank_id ['enable'|'disable']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration mxc_nand_command_handler[] = {\n\t{\n\t\t.name = \"mxc\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"MXC NAND flash controller commands\",\n\t\t.chain = mxc_sub_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int mxc_init(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tint validate_target_result;\n\tuint16_t buffsize_register_content;\n\tuint32_t sreg_content;\n\tuint32_t sreg = MX2_FMCR;\n\tuint32_t sel_16bit = MX2_FMCR_NF_16BIT_SEL;\n\tuint32_t sel_fms = MX2_FMCR_NF_FMS;\n\tint retval;\n\tuint16_t nand_status_content;\n\t/*\n\t * validate target state\n\t */\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\n\tif (nfc_is_v1()) {\n\t\ttarget_read_u16(target, MXC_NF_BUFSIZ, &buffsize_register_content);\n\t\tmxc_nf_info->flags.one_kb_sram = !(buffsize_register_content & 0x000f);\n\t} else\n\t\tmxc_nf_info->flags.one_kb_sram = 0;\n\n\tif (mxc_nf_info->mxc_version == MXC_VERSION_MX31) {\n\t\tsreg = MX3_PCSR;\n\t\tsel_16bit = MX3_PCSR_NF_16BIT_SEL;\n\t\tsel_fms = MX3_PCSR_NF_FMS;\n\t} else if (mxc_nf_info->mxc_version == MXC_VERSION_MX25) {\n\t\tsreg = MX25_RCSR;\n\t\tsel_16bit = MX25_RCSR_NF_16BIT_SEL;\n\t\tsel_fms = MX25_RCSR_NF_FMS;\n\t} else if (mxc_nf_info->mxc_version == MXC_VERSION_MX35) {\n\t\tsreg = MX35_RCSR;\n\t\tsel_16bit = MX35_RCSR_NF_16BIT_SEL;\n\t\tsel_fms = MX35_RCSR_NF_FMS;\n\t}\n\n\ttarget_read_u32(target, sreg, &sreg_content);\n\tif (!nand->bus_width) {\n\t\t/* bus_width not yet defined. Read it from MXC_FMCR */\n\t\tnand->bus_width = (sreg_content & sel_16bit) ? 16 : 8;\n\t} else {\n\t\t/* bus_width forced in soft. Sync it to MXC_FMCR */\n\t\tsreg_content |= ((nand->bus_width == 16) ? sel_16bit : 0x00000000);\n\t\ttarget_write_u32(target, sreg, sreg_content);\n\t}\n\tif (nand->bus_width == 16)\n\t\tLOG_DEBUG(\"MXC_NF : bus is 16-bit width\");\n\telse\n\t\tLOG_DEBUG(\"MXC_NF : bus is 8-bit width\");\n\n\tif (!nand->page_size)\n\t\tnand->page_size = (sreg_content & sel_fms) ? 2048 : 512;\n\telse {\n\t\tsreg_content |= ((nand->page_size == 2048) ? sel_fms : 0x00000000);\n\t\ttarget_write_u32(target, sreg, sreg_content);\n\t}\n\tif (mxc_nf_info->flags.one_kb_sram && (nand->page_size == 2048)) {\n\t\tLOG_ERROR(\"NAND controller have only 1 kb SRAM, so \"\n\t\t\t\"pagesize 2048 is incompatible with it\");\n\t} else\n\t\tLOG_DEBUG(\"MXC_NF : NAND controller can handle pagesize of 2048\");\n\n\tif (nfc_is_v2() && sreg_content & MX35_RCSR_NF_4K)\n\t\tLOG_ERROR(\"MXC driver does not have support for 4k pagesize.\");\n\n\tinitialize_nf_controller(nand);\n\n\tretval = ERROR_OK;\n\tretval |= mxc_command(nand, NAND_CMD_STATUS);\n\tretval |= mxc_address(nand, 0x00);\n\tretval |= do_data_output(nand);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(get_status_register_err_msg);\n\t\treturn ERROR_FAIL;\n\t}\n\ttarget_read_u16(target, MXC_NF_MAIN_BUFFER0, &nand_status_content);\n\tif (!(nand_status_content & 0x0080)) {\n\t\tLOG_INFO(\"NAND read-only\");\n\t\tmxc_nf_info->flags.nand_readonly = 1;\n\t} else\n\t\tmxc_nf_info->flags.nand_readonly = 0;\n\treturn ERROR_OK;\n}\n\nstatic int mxc_read_data(struct nand_device *nand, void *data)\n{\n\tint validate_target_result;\n\tint try_data_output_from_nand_chip;\n\t/*\n\t * validate target state\n\t */\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\n\t/*\n\t * get data from nand chip\n\t */\n\ttry_data_output_from_nand_chip = do_data_output(nand);\n\tif (try_data_output_from_nand_chip != ERROR_OK) {\n\t\tLOG_ERROR(\"mxc_read_data : read data failed : '%x'\",\n\t\t\ttry_data_output_from_nand_chip);\n\t\treturn try_data_output_from_nand_chip;\n\t}\n\n\tif (nand->bus_width == 16)\n\t\tget_next_halfword_from_sram_buffer(nand, data);\n\telse\n\t\tget_next_byte_from_sram_buffer(nand, data);\n\n\treturn ERROR_OK;\n}\n\nstatic int mxc_write_data(struct nand_device *nand, uint16_t data)\n{\n\tLOG_ERROR(\"write_data() not implemented\");\n\treturn ERROR_NAND_OPERATION_FAILED;\n}\n\nstatic int mxc_reset(struct nand_device *nand)\n{\n\t/*\n\t * validate target state\n\t */\n\tint validate_target_result;\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\tinitialize_nf_controller(nand);\n\treturn ERROR_OK;\n}\n\nstatic int mxc_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint validate_target_result;\n\tint poll_result;\n\t/*\n\t * validate target state\n\t */\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\n\tswitch (command) {\n\t\tcase NAND_CMD_READOOB:\n\t\t\tcommand = NAND_CMD_READ0;\n\t\t\t/* set read point for data_read() and read_block_data() to\n\t\t\t * spare area in SRAM buffer\n\t\t\t */\n\t\t\tif (nfc_is_v1())\n\t\t\t\tin_sram_address = MXC_NF_V1_SPARE_BUFFER0;\n\t\t\telse\n\t\t\t\tin_sram_address = MXC_NF_V2_SPARE_BUFFER0;\n\t\t\tbreak;\n\t\tcase NAND_CMD_READ1:\n\t\t\tcommand = NAND_CMD_READ0;\n\t\t\t/*\n\t\t\t * offset == one half of page size\n\t\t\t */\n\t\t\tin_sram_address = MXC_NF_MAIN_BUFFER0 + (nand->page_size >> 1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tin_sram_address = MXC_NF_MAIN_BUFFER0;\n\t\t\tbreak;\n\t}\n\n\ttarget_write_u16(target, MXC_NF_FCMD, command);\n\t/*\n\t * start command input operation (set MXC_NF_BIT_OP_DONE==0)\n\t */\n\ttarget_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FCI);\n\tpoll_result = poll_for_complete_op(nand, \"command\");\n\tif (poll_result != ERROR_OK)\n\t\treturn poll_result;\n\t/*\n\t * reset cursor to begin of the buffer\n\t */\n\tsign_of_sequental_byte_read = 0;\n\t/* Handle special read command and adjust NF_CFG2(FDO) */\n\tswitch (command) {\n\t\tcase NAND_CMD_READID:\n\t\t\tmxc_nf_info->optype = MXC_NF_DATAOUT_NANDID;\n\t\t\tmxc_nf_info->fin = MXC_NF_FIN_DATAOUT;\n\t\t\tbreak;\n\t\tcase NAND_CMD_STATUS:\n\t\t\tmxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS;\n\t\t\tmxc_nf_info->fin = MXC_NF_FIN_DATAOUT;\n\t\t\ttarget_write_u16 (target, MXC_NF_BUFADDR, 0);\n\t\t\tin_sram_address = 0;\n\t\t\tbreak;\n\t\tcase NAND_CMD_READ0:\n\t\t\tmxc_nf_info->fin = MXC_NF_FIN_DATAOUT;\n\t\t\tmxc_nf_info->optype = MXC_NF_DATAOUT_PAGE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* Other command use the default 'One page data out' FDO */\n\t\t\tmxc_nf_info->optype = MXC_NF_DATAOUT_PAGE;\n\t\t\tbreak;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int mxc_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint validate_target_result;\n\tint poll_result;\n\t/*\n\t * validate target state\n\t */\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\n\ttarget_write_u16(target, MXC_NF_FADDR, address);\n\t/*\n\t * start address input operation (set MXC_NF_BIT_OP_DONE==0)\n\t */\n\ttarget_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FAI);\n\tpoll_result = poll_for_complete_op(nand, \"address\");\n\tif (poll_result != ERROR_OK)\n\t\treturn poll_result;\n\n\treturn ERROR_OK;\n}\n\nstatic int mxc_nand_ready(struct nand_device *nand, int tout)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint16_t poll_complete_status;\n\tint validate_target_result;\n\n\t/*\n\t * validate target state\n\t */\n\tvalidate_target_result = validate_target_state(nand);\n\tif (validate_target_result != ERROR_OK)\n\t\treturn validate_target_result;\n\n\tdo {\n\t\ttarget_read_u16(target, MXC_NF_CFG2, &poll_complete_status);\n\t\tif (poll_complete_status & MXC_NF_BIT_OP_DONE)\n\t\t\treturn tout;\n\n\t\talive_sleep(1);\n\t} while (tout-- > 0);\n\treturn tout;\n}\n\nstatic int mxc_write_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint16_t nand_status_content;\n\tuint16_t swap1, swap2, new_swap1;\n\tuint8_t bufs;\n\tint poll_result;\n\n\tif (data_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, data_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (oob_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, oob_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (!data) {\n\t\tLOG_ERROR(\"nothing to program\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/*\n\t * validate target state\n\t */\n\tretval = validate_target_state(nand);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tin_sram_address = MXC_NF_MAIN_BUFFER0;\n\tsign_of_sequental_byte_read = 0;\n\tretval = ERROR_OK;\n\tretval |= mxc_command(nand, NAND_CMD_SEQIN);\n\tretval |= mxc_address(nand, 0);\t/* col */\n\tretval |= mxc_address(nand, 0);\t/* col */\n\tretval |= mxc_address(nand, page & 0xff);\t/* page address */\n\tretval |= mxc_address(nand, (page >> 8) & 0xff);/* page address */\n\tretval |= mxc_address(nand, (page >> 16) & 0xff);\t/* page address */\n\n\ttarget_write_buffer(target, MXC_NF_MAIN_BUFFER0, data_size, data);\n\tif (oob) {\n\t\tif (mxc_nf_info->flags.hw_ecc_enabled) {\n\t\t\t/*\n\t\t\t * part of spare block will be overridden by hardware\n\t\t\t * ECC generator\n\t\t\t */\n\t\t\tLOG_DEBUG(\"part of spare block will be overridden \"\n\t\t\t\t\"by hardware ECC generator\");\n\t\t}\n\t\tif (nfc_is_v1())\n\t\t\ttarget_write_buffer(target, MXC_NF_V1_SPARE_BUFFER0, oob_size, oob);\n\t\telse {\n\t\t\tuint32_t addr = MXC_NF_V2_SPARE_BUFFER0;\n\t\t\twhile (oob_size > 0) {\n\t\t\t\tuint8_t len = MIN(oob_size, MXC_NF_SPARE_BUFFER_LEN);\n\t\t\t\ttarget_write_buffer(target, addr, len, oob);\n\t\t\t\taddr = align_address_v2(nand, addr + len);\n\t\t\t\toob += len;\n\t\t\t\toob_size -= len;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (nand->page_size > 512 && mxc_nf_info->flags.biswap_enabled) {\n\t\t/* BI-swap - work-around of i.MX NFC for NAND device with page == 2kb*/\n\t\ttarget_read_u16(target, MXC_NF_MAIN_BUFFER3 + 464, &swap1);\n\t\tif (oob) {\n\t\t\tLOG_ERROR(\"Due to NFC Bug, oob is not correctly implemented in mxc driver\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t}\n\t\tswap2 = 0xffff;\t/* Spare buffer unused forced to 0xffff */\n\t\tnew_swap1 = (swap1 & 0xFF00) | (swap2 >> 8);\n\t\tswap2 = (swap1 << 8) | (swap2 & 0xFF);\n\t\ttarget_write_u16(target, MXC_NF_MAIN_BUFFER3 + 464, new_swap1);\n\t\tif (nfc_is_v1())\n\t\t\ttarget_write_u16(target, MXC_NF_V1_SPARE_BUFFER3 + 4, swap2);\n\t\telse\n\t\t\ttarget_write_u16(target, MXC_NF_V2_SPARE_BUFFER3, swap2);\n\t}\n\n\t/*\n\t * start data input operation (set MXC_NF_BIT_OP_DONE==0)\n\t */\n\tif (nfc_is_v1() && nand->page_size > 512)\n\t\tbufs = 4;\n\telse\n\t\tbufs = 1;\n\n\tfor (uint8_t i = 0; i < bufs; ++i) {\n\t\ttarget_write_u16(target, MXC_NF_BUFADDR, i);\n\t\ttarget_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_OP_FDI);\n\t\tpoll_result = poll_for_complete_op(nand, \"data input\");\n\t\tif (poll_result != ERROR_OK)\n\t\t\treturn poll_result;\n\t}\n\n\tretval |= mxc_command(nand, NAND_CMD_PAGEPROG);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * check status register\n\t */\n\tretval = ERROR_OK;\n\tretval |= mxc_command(nand, NAND_CMD_STATUS);\n\ttarget_write_u16 (target, MXC_NF_BUFADDR, 0);\n\tmxc_nf_info->optype = MXC_NF_DATAOUT_NANDSTATUS;\n\tmxc_nf_info->fin = MXC_NF_FIN_DATAOUT;\n\tretval |= do_data_output(nand);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(get_status_register_err_msg);\n\t\treturn retval;\n\t}\n\ttarget_read_u16(target, MXC_NF_MAIN_BUFFER0, &nand_status_content);\n\tif (nand_status_content & 0x0001) {\n\t\t/*\n\t\t * page not correctly written\n\t\t */\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n#ifdef _MXC_PRINT_STAT\n\tLOG_INFO(\"%d bytes newly written\", data_size);\n#endif\n\treturn ERROR_OK;\n}\n\nstatic int mxc_read_page(struct nand_device *nand, uint32_t page,\n\tuint8_t *data, uint32_t data_size,\n\tuint8_t *oob, uint32_t oob_size)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint retval;\n\tuint8_t bufs;\n\tuint16_t swap1, swap2, new_swap1;\n\n\tif (data_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, data_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tif (oob_size % 2) {\n\t\tLOG_ERROR(data_block_size_err_msg, oob_size);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\t/*\n\t * validate target state\n\t */\n\tretval = validate_target_state(nand);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t\t\t\t/* Reset address_cycles before mxc_command ?? */\n\tretval = mxc_command(nand, NAND_CMD_READ0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_address(nand, 0);\t/* col */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_address(nand, 0);\t/* col */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_address(nand, page & 0xff);/* page address */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_address(nand, (page >> 8) & 0xff);\t/* page address */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_address(nand, (page >> 16) & 0xff);/* page address */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mxc_command(nand, NAND_CMD_READSTART);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (nfc_is_v1() && nand->page_size > 512)\n\t\tbufs = 4;\n\telse\n\t\tbufs = 1;\n\n\tfor (uint8_t i = 0; i < bufs; ++i) {\n\t\ttarget_write_u16(target, MXC_NF_BUFADDR, i);\n\t\tmxc_nf_info->fin = MXC_NF_FIN_DATAOUT;\n\t\tretval = do_data_output(nand);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"MXC_NF : Error reading page %d\", i);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tif (nand->page_size > 512 && mxc_nf_info->flags.biswap_enabled) {\n\t\tuint32_t spare_buffer3;\n\t\t/* BI-swap -  work-around of mxc NFC for NAND device with page == 2k */\n\t\ttarget_read_u16(target, MXC_NF_MAIN_BUFFER3 + 464, &swap1);\n\t\tif (nfc_is_v1())\n\t\t\tspare_buffer3 = MXC_NF_V1_SPARE_BUFFER3 + 4;\n\t\telse\n\t\t\tspare_buffer3 = MXC_NF_V2_SPARE_BUFFER3;\n\t\ttarget_read_u16(target, spare_buffer3, &swap2);\n\t\tnew_swap1 = (swap1 & 0xFF00) | (swap2 >> 8);\n\t\tswap2 = (swap1 << 8) | (swap2 & 0xFF);\n\t\ttarget_write_u16(target, MXC_NF_MAIN_BUFFER3 + 464, new_swap1);\n\t\ttarget_write_u16(target, spare_buffer3, swap2);\n\t}\n\n\tif (data)\n\t\ttarget_read_buffer(target, MXC_NF_MAIN_BUFFER0, data_size, data);\n\tif (oob) {\n\t\tif (nfc_is_v1())\n\t\t\ttarget_read_buffer(target, MXC_NF_V1_SPARE_BUFFER0, oob_size, oob);\n\t\telse {\n\t\t\tuint32_t addr = MXC_NF_V2_SPARE_BUFFER0;\n\t\t\twhile (oob_size > 0) {\n\t\t\t\tuint8_t len = MIN(oob_size, MXC_NF_SPARE_BUFFER_LEN);\n\t\t\t\ttarget_read_buffer(target, addr, len, oob);\n\t\t\t\taddr = align_address_v2(nand, addr + len);\n\t\t\t\toob += len;\n\t\t\t\toob_size -= len;\n\t\t\t}\n\t\t}\n\t}\n\n#ifdef _MXC_PRINT_STAT\n\tif (data_size > 0) {\n\t\t/* When Operation Status is read (when page is erased),\n\t\t * this function is used but data_size is null.\n\t\t */\n\t\tLOG_INFO(\"%d bytes newly read\", data_size);\n\t}\n#endif\n\treturn ERROR_OK;\n}\n\nstatic uint32_t align_address_v2(struct nand_device *nand, uint32_t addr)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tuint32_t ret = addr;\n\tif (addr > MXC_NF_V2_SPARE_BUFFER0 &&\n\t\t\t(addr & 0x1F) == MXC_NF_SPARE_BUFFER_LEN)\n\t\tret += MXC_NF_SPARE_BUFFER_MAX - MXC_NF_SPARE_BUFFER_LEN;\n\telse if (addr >= (mxc_nf_info->mxc_base_addr + (uint32_t)nand->page_size))\n\t\tret = MXC_NF_V2_SPARE_BUFFER0;\n\treturn ret;\n}\n\nstatic int initialize_nf_controller(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint16_t work_mode = 0;\n\tuint16_t temp;\n\t/*\n\t * resets NAND flash controller in zero time ? I don't know.\n\t */\n\ttarget_write_u16(target, MXC_NF_CFG1, MXC_NF_BIT_RESET_EN);\n\tif (mxc_nf_info->mxc_version == MXC_VERSION_MX27)\n\t\twork_mode = MXC_NF_BIT_INT_DIS;\t/* disable interrupt */\n\n\tif (target->endianness == TARGET_BIG_ENDIAN) {\n\t\tLOG_DEBUG(\"MXC_NF : work in Big Endian mode\");\n\t\twork_mode |= MXC_NF_BIT_BE_EN;\n\t} else\n\t\tLOG_DEBUG(\"MXC_NF : work in Little Endian mode\");\n\tif (mxc_nf_info->flags.hw_ecc_enabled) {\n\t\tLOG_DEBUG(\"MXC_NF : work with ECC mode\");\n\t\twork_mode |= MXC_NF_BIT_ECC_EN;\n\t} else\n\t\tLOG_DEBUG(\"MXC_NF : work without ECC mode\");\n\tif (nfc_is_v2()) {\n\t\ttarget_write_u16(target, MXC_NF_V2_SPAS, OOB_SIZE / 2);\n\t\tif (nand->page_size) {\n\t\t\tuint16_t pages_per_block = nand->erase_size / nand->page_size;\n\t\t\twork_mode |= MXC_NF_V2_CFG1_PPB(ffs(pages_per_block) - 6);\n\t\t}\n\t\twork_mode |= MXC_NF_BIT_ECC_4BIT;\n\t}\n\ttarget_write_u16(target, MXC_NF_CFG1, work_mode);\n\n\t/*\n\t * unlock SRAM buffer for write; 2 mean \"Unlock\", other values means \"Lock\"\n\t */\n\ttarget_write_u16(target, MXC_NF_BUFCFG, 2);\n\ttarget_read_u16(target, MXC_NF_FWP, &temp);\n\tif ((temp & 0x0007) == 1) {\n\t\tLOG_ERROR(\"NAND flash is tight-locked, reset needed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * unlock NAND flash for write\n\t */\n\tif (nfc_is_v1()) {\n\t\ttarget_write_u16(target, MXC_NF_V1_UNLOCKSTART, 0x0000);\n\t\ttarget_write_u16(target, MXC_NF_V1_UNLOCKEND, 0xFFFF);\n\t} else {\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKSTART0, 0x0000);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKSTART1, 0x0000);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKSTART2, 0x0000);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKSTART3, 0x0000);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKEND0, 0xFFFF);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKEND1, 0xFFFF);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKEND2, 0xFFFF);\n\t\ttarget_write_u16(target, MXC_NF_V2_UNLOCKEND3, 0xFFFF);\n\t}\n\ttarget_write_u16(target, MXC_NF_FWP, 4);\n\n\t/*\n\t * 0x0000 means that first SRAM buffer @base_addr will be used\n\t */\n\ttarget_write_u16(target, MXC_NF_BUFADDR, 0x0000);\n\t/*\n\t * address of SRAM buffer\n\t */\n\tin_sram_address = MXC_NF_MAIN_BUFFER0;\n\tsign_of_sequental_byte_read = 0;\n\treturn ERROR_OK;\n}\n\nstatic int get_next_byte_from_sram_buffer(struct nand_device *nand, uint8_t *value)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tstatic uint8_t even_byte;\n\tuint16_t temp;\n\t/*\n\t * host-big_endian ??\n\t */\n\tif (sign_of_sequental_byte_read == 0)\n\t\teven_byte = 0;\n\n\tif (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) {\n\t\tLOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);\n\t\t*value = 0;\n\t\tsign_of_sequental_byte_read = 0;\n\t\teven_byte = 0;\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else {\n\t\tif (nfc_is_v2())\n\t\t\tin_sram_address = align_address_v2(nand, in_sram_address);\n\n\t\ttarget_read_u16(target, in_sram_address, &temp);\n\t\tif (even_byte) {\n\t\t\t*value = temp >> 8;\n\t\t\teven_byte = 0;\n\t\t\tin_sram_address += 2;\n\t\t} else {\n\t\t\t*value = temp & 0xff;\n\t\t\teven_byte = 1;\n\t\t}\n\t}\n\tsign_of_sequental_byte_read = 1;\n\treturn ERROR_OK;\n}\n\nstatic int get_next_halfword_from_sram_buffer(struct nand_device *nand, uint16_t *value)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (in_sram_address > (nfc_is_v1() ? MXC_NF_V1_LAST_BUFFADDR : MXC_NF_V2_LAST_BUFFADDR)) {\n\t\tLOG_ERROR(sram_buffer_bounds_err_msg, in_sram_address);\n\t\t*value = 0;\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t} else {\n\t\tif (nfc_is_v2())\n\t\t\tin_sram_address = align_address_v2(nand, in_sram_address);\n\n\t\ttarget_read_u16(target, in_sram_address, value);\n\t\tin_sram_address += 2;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int poll_for_complete_op(struct nand_device *nand, const char *text)\n{\n\tif (mxc_nand_ready(nand, 1000) == -1) {\n\t\tLOG_ERROR(\"%s sending timeout\", text);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int validate_target_state(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(target_not_halted_err_msg);\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tif (mxc_nf_info->flags.target_little_endian !=\n\t\t\t(target->endianness == TARGET_LITTLE_ENDIAN)) {\n\t\t/*\n\t\t * endianness changed after NAND controller probed\n\t\t */\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ecc_status_v1(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint16_t ecc_status;\n\n\ttarget_read_u16(target, MXC_NF_ECCSTATUS, &ecc_status);\n\tswitch (ecc_status & 0x000c) {\n\t\tcase 1 << 2:\n\t\t\tLOG_INFO(\"main area read with 1 (correctable) error\");\n\t\t\tbreak;\n\t\tcase 2 << 2:\n\t\t\tLOG_INFO(\"main area read with more than 1 (incorrectable) error\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\tswitch (ecc_status & 0x0003) {\n\t\tcase 1:\n\t\t\tLOG_INFO(\"spare area read with 1 (correctable) error\");\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tLOG_INFO(\"main area read with more than 1 (incorrectable) error\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ecc_status_v2(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint16_t ecc_status;\n\tuint8_t no_subpages;\n\tuint8_t err;\n\n\tno_subpages = nand->page_size >> 9;\n\n\ttarget_read_u16(target, MXC_NF_ECCSTATUS, &ecc_status);\n\tdo {\n\t\terr = ecc_status & 0xF;\n\t\tif (err > 4) {\n\t\t\tLOG_INFO(\"UnCorrectable RS-ECC Error\");\n\t\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t\t} else if (err > 0)\n\t\t\tLOG_INFO(\"%d Symbol Correctable RS-ECC Error\", err);\n\t\tecc_status >>= 4;\n\t} while (--no_subpages);\n\treturn ERROR_OK;\n}\n\nstatic int do_data_output(struct nand_device *nand)\n{\n\tstruct mxc_nf_controller *mxc_nf_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint poll_result;\n\tswitch (mxc_nf_info->fin) {\n\t\tcase MXC_NF_FIN_DATAOUT:\n\t\t\t/*\n\t\t\t * start data output operation (set MXC_NF_BIT_OP_DONE==0)\n\t\t\t */\n\t\t\ttarget_write_u16(target, MXC_NF_CFG2, MXC_NF_BIT_DATAOUT_TYPE(mxc_nf_info->optype));\n\t\t\tpoll_result = poll_for_complete_op(nand, \"data output\");\n\t\t\tif (poll_result != ERROR_OK)\n\t\t\t\treturn poll_result;\n\n\t\t\tmxc_nf_info->fin = MXC_NF_FIN_NONE;\n\t\t\t/*\n\t\t\t * ECC stuff\n\t\t\t */\n\t\t\tif (mxc_nf_info->optype == MXC_NF_DATAOUT_PAGE && mxc_nf_info->flags.hw_ecc_enabled) {\n\t\t\t\tint ecc_status;\n\t\t\t\tif (nfc_is_v1())\n\t\t\t\t\tecc_status = ecc_status_v1(nand);\n\t\t\t\telse\n\t\t\t\t\tecc_status = ecc_status_v2(nand);\n\t\t\t\tif (ecc_status != ERROR_OK)\n\t\t\t\t\treturn ecc_status;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase MXC_NF_FIN_NONE:\n\t\t\tbreak;\n\t}\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller mxc_nand_flash_controller = {\n\t.name = \"mxc\",\n\t.nand_device_command = &mxc_nand_device_command,\n\t.commands = mxc_nand_command_handler,\n\t.init = &mxc_init,\n\t.reset = &mxc_reset,\n\t.command = &mxc_command,\n\t.address = &mxc_address,\n\t.write_data = &mxc_write_data,\n\t.read_data = &mxc_read_data,\n\t.write_page = &mxc_write_page,\n\t.read_page = &mxc_read_page,\n\t.nand_ready = &mxc_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/mxc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Alexei Babich                                   *\n *   Rezonans plc., Chelyabinsk, Russia                                    *\n *   impatt@mail.ru                                                        *\n *                                                                         *\n *   Copyright (C) 2011 by Erik Ahlen                                      *\n *   Avalon Innovation, Sweden                                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_MXC_H\n#define OPENOCD_FLASH_NAND_MXC_H\n\n/*\n * Freescale iMX OpenOCD NAND Flash controller support.\n * based on Freescale iMX2* and iMX3* OpenOCD NAND Flash controller support.\n *\n * Many thanks to Ben Dooks for writing s3c24xx driver.\n */\n\n#define\t\tMXC_NF_BUFSIZ\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x00)\n#define\t\tMXC_NF_BUFADDR\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x04)\n#define\t\tMXC_NF_FADDR\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x06)\n#define\t\tMXC_NF_FCMD\t\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x08)\n#define\t\tMXC_NF_BUFCFG\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x0a)\n#define\t\tMXC_NF_ECCSTATUS\t\t\t(mxc_nf_info->mxc_regs_addr + 0x0c)\n#define\t\tMXC_NF_ECCMAINPOS\t\t\t(mxc_nf_info->mxc_regs_addr + 0x0e)\n#define\t\tMXC_NF_V1_ECCSPAREPOS\t\t(mxc_nf_info->mxc_regs_addr + 0x10)\n#define\t\tMXC_NF_V2_SPAS\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x10)\n#define\t\tMXC_NF_FWP\t\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x12)\n#define\t\tMXC_NF_V1_UNLOCKSTART\t\t(mxc_nf_info->mxc_regs_addr + 0x14)\n#define\t\tMXC_NF_V1_UNLOCKEND\t\t\t(mxc_nf_info->mxc_regs_addr + 0x16)\n#define\t\tMXC_NF_V2_UNLOCKSTART0\t\t(mxc_nf_info->mxc_regs_addr + 0x20)\n#define\t\tMXC_NF_V2_UNLOCKSTART1\t\t(mxc_nf_info->mxc_regs_addr + 0x24)\n#define\t\tMXC_NF_V2_UNLOCKSTART2\t\t(mxc_nf_info->mxc_regs_addr + 0x28)\n#define\t\tMXC_NF_V2_UNLOCKSTART3\t\t(mxc_nf_info->mxc_regs_addr + 0x2c)\n#define\t\tMXC_NF_V2_UNLOCKEND0\t\t(mxc_nf_info->mxc_regs_addr + 0x22)\n#define\t\tMXC_NF_V2_UNLOCKEND1\t\t(mxc_nf_info->mxc_regs_addr + 0x26)\n#define\t\tMXC_NF_V2_UNLOCKEND2\t\t(mxc_nf_info->mxc_regs_addr + 0x2a)\n#define\t\tMXC_NF_V2_UNLOCKEND3\t\t(mxc_nf_info->mxc_regs_addr + 0x2e)\n#define\t\tMXC_NF_FWPSTATUS\t\t\t(mxc_nf_info->mxc_regs_addr + 0x18)\n /*\n  * all bits not marked as self-clearing bit\n  */\n#define\t\tMXC_NF_CFG1\t\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x1a)\n#define\t\tMXC_NF_CFG2\t\t\t\t\t(mxc_nf_info->mxc_regs_addr + 0x1c)\n\n#define\t\tMXC_NF_MAIN_BUFFER0\t\t\t(mxc_nf_info->mxc_base_addr + 0x0000)\n#define\t\tMXC_NF_MAIN_BUFFER1\t\t\t(mxc_nf_info->mxc_base_addr + 0x0200)\n#define\t\tMXC_NF_MAIN_BUFFER2\t\t\t(mxc_nf_info->mxc_base_addr + 0x0400)\n#define\t\tMXC_NF_MAIN_BUFFER3\t\t\t(mxc_nf_info->mxc_base_addr + 0x0600)\n#define\t\tMXC_NF_V1_SPARE_BUFFER0\t\t(mxc_nf_info->mxc_base_addr + 0x0800)\n#define\t\tMXC_NF_V1_SPARE_BUFFER1\t\t(mxc_nf_info->mxc_base_addr + 0x0810)\n#define\t\tMXC_NF_V1_SPARE_BUFFER2\t\t(mxc_nf_info->mxc_base_addr + 0x0820)\n#define\t\tMXC_NF_V1_SPARE_BUFFER3\t\t(mxc_nf_info->mxc_base_addr + 0x0830)\n#define\t\tMXC_NF_V2_MAIN_BUFFER4\t\t(mxc_nf_info->mxc_base_addr + 0x0800)\n#define\t\tMXC_NF_V2_MAIN_BUFFER5\t\t(mxc_nf_info->mxc_base_addr + 0x0a00)\n#define\t\tMXC_NF_V2_MAIN_BUFFER6\t\t(mxc_nf_info->mxc_base_addr + 0x0c00)\n#define\t\tMXC_NF_V2_MAIN_BUFFER7\t\t(mxc_nf_info->mxc_base_addr + 0x0e00)\n#define\t\tMXC_NF_V2_SPARE_BUFFER0\t\t(mxc_nf_info->mxc_base_addr + 0x1000)\n#define\t\tMXC_NF_V2_SPARE_BUFFER1\t\t(mxc_nf_info->mxc_base_addr + 0x1040)\n#define\t\tMXC_NF_V2_SPARE_BUFFER2\t\t(mxc_nf_info->mxc_base_addr + 0x1080)\n#define\t\tMXC_NF_V2_SPARE_BUFFER3\t\t(mxc_nf_info->mxc_base_addr + 0x10c0)\n#define\t\tMXC_NF_V2_SPARE_BUFFER4\t\t(mxc_nf_info->mxc_base_addr + 0x1100)\n#define\t\tMXC_NF_V2_SPARE_BUFFER5\t\t(mxc_nf_info->mxc_base_addr + 0x1140)\n#define\t\tMXC_NF_V2_SPARE_BUFFER6\t\t(mxc_nf_info->mxc_base_addr + 0x1180)\n#define\t\tMXC_NF_V2_SPARE_BUFFER7\t\t(mxc_nf_info->mxc_base_addr + 0x11c0)\n#define\t\tMXC_NF_MAIN_BUFFER_LEN\t\t512\n#define\t\tMXC_NF_SPARE_BUFFER_LEN\t\t16\n#define\t\tMXC_NF_SPARE_BUFFER_MAX\t\t64\n#define\t\tMXC_NF_V1_LAST_BUFFADDR\t\t((MXC_NF_V1_SPARE_BUFFER3) + \\\n\tMXC_NF_SPARE_BUFFER_LEN - 2)\n#define\t\tMXC_NF_V2_LAST_BUFFADDR\t\t((MXC_NF_V2_SPARE_BUFFER7) + \\\n\tMXC_NF_SPARE_BUFFER_LEN - 2)\n\n/* bits in MXC_NF_CFG1 register */\n#define\t\tMXC_NF_BIT_ECC_4BIT\t\t\t(1<<0)\n#define\t\tMXC_NF_BIT_SPARE_ONLY_EN\t(1<<2)\n#define\t\tMXC_NF_BIT_ECC_EN\t\t\t(1<<3)\n#define\t\tMXC_NF_BIT_INT_DIS\t\t\t(1<<4)\n#define\t\tMXC_NF_BIT_BE_EN\t\t\t(1<<5)\n#define\t\tMXC_NF_BIT_RESET_EN\t\t\t(1<<6)\n#define\t\tMXC_NF_BIT_FORCE_CE\t\t\t(1<<7)\n#define\t\tMXC_NF_V2_CFG1_PPB(x)\t\t(((x) & 0x3) << 9)\n\n/* bits in MXC_NF_CFG2 register */\n\n/*Flash Command Input*/\n#define\t\tMXC_NF_BIT_OP_FCI\t\t\t(1<<0)\n /*\n  * Flash Address Input\n  */\n#define\t\tMXC_NF_BIT_OP_FAI\t\t\t(1<<1)\n /*\n  * Flash Data Input\n  */\n#define\t\tMXC_NF_BIT_OP_FDI\t\t\t(1<<2)\n\n/* see \"enum mx_dataout_type\" below */\n#define\t\tMXC_NF_BIT_DATAOUT_TYPE(x)\t((x)<<3)\n#define\t\tMXC_NF_BIT_OP_DONE\t\t\t(1<<15)\n\n#define\t\tMXC_CCM_CGR2\t\t\t\t0x53f80028\n#define\t\tMXC_GPR\t\t\t\t\t\t0x43fac008\n#define\t\tMX2_FMCR\t\t\t\t\t0x10027814\n#define\t\tMX2_FMCR_NF_16BIT_SEL\t\t(1<<4)\n#define\t\tMX2_FMCR_NF_FMS\t\t\t\t(1<<5)\n#define\t\tMX25_RCSR\t\t\t\t\t0x53f80018\n#define\t\tMX25_RCSR_NF_16BIT_SEL\t\t(1<<14)\n#define\t\tMX25_RCSR_NF_FMS\t\t\t(1<<8)\n#define\t\tMX25_RCSR_NF_4K\t\t\t\t(1<<9)\n#define\t\tMX3_PCSR\t\t\t\t\t0x53f8000c\n#define\t\tMX3_PCSR_NF_16BIT_SEL\t\t(1<<31)\n#define\t\tMX3_PCSR_NF_FMS\t\t\t\t(1<<30)\n#define\t\tMX35_RCSR\t\t\t\t\t0x53f80018\n#define\t\tMX35_RCSR_NF_16BIT_SEL\t\t(1<<14)\n#define\t\tMX35_RCSR_NF_FMS\t\t\t(1<<8)\n#define\t\tMX35_RCSR_NF_4K\t\t\t\t(1<<9)\n\nenum mxc_version {\n\tMXC_VERSION_UKWN = 0,\n\tMXC_VERSION_MX25 = 1,\n\tMXC_VERSION_MX27 = 2,\n\tMXC_VERSION_MX31 = 3,\n\tMXC_VERSION_MX35 = 4\n};\n\nenum mxc_dataout_type {\n\tMXC_NF_DATAOUT_PAGE = 1,\n\tMXC_NF_DATAOUT_NANDID = 2,\n\tMXC_NF_DATAOUT_NANDSTATUS = 4,\n};\n\nenum mxc_nf_finalize_action {\n\tMXC_NF_FIN_NONE,\n\tMXC_NF_FIN_DATAOUT,\n};\n\nstruct mxc_nf_flags {\n\tunsigned target_little_endian:1;\n\tunsigned nand_readonly:1;\n\tunsigned one_kb_sram:1;\n\tunsigned hw_ecc_enabled:1;\n\tunsigned biswap_enabled:1;\n};\n\nstruct mxc_nf_controller {\n\tenum mxc_version mxc_version;\n\tuint32_t mxc_base_addr;\n\tuint32_t mxc_regs_addr;\n\tenum mxc_dataout_type optype;\n\tenum mxc_nf_finalize_action fin;\n\tstruct mxc_nf_flags flags;\n};\n\n#endif /* OPENOCD_FLASH_NAND_MXC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/nonce.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"hello.h\"\n\nstatic int nonce_nand_command(struct nand_device *nand, uint8_t command)\n{\n\treturn ERROR_OK;\n}\nstatic int nonce_nand_address(struct nand_device *nand, uint8_t address)\n{\n\treturn ERROR_OK;\n}\nstatic int nonce_nand_read(struct nand_device *nand, void *data)\n{\n\treturn ERROR_OK;\n}\nstatic int nonce_nand_write(struct nand_device *nand, uint16_t data)\n{\n\treturn ERROR_OK;\n}\nstatic int nonce_nand_fast_block_write(struct nand_device *nand,\n\t\tuint8_t *data, int size)\n{\n\treturn ERROR_OK;\n}\n\nstatic int nonce_nand_reset(struct nand_device *nand)\n{\n\treturn nonce_nand_command(nand, NAND_CMD_RESET);\n}\n\nNAND_DEVICE_COMMAND_HANDLER(nonce_nand_device_command)\n{\n\treturn ERROR_OK;\n}\n\nstatic int nonce_nand_init(struct nand_device *nand)\n{\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller nonce_nand_controller = {\n\t.name = \"nonce\",\n\t.commands = hello_command_handlers,\n\t.nand_device_command = &nonce_nand_device_command,\n\t.init = &nonce_nand_init,\n\t.reset = &nonce_nand_reset,\n\t.command = &nonce_nand_command,\n\t.address = &nonce_nand_address,\n\t.read_data = &nonce_nand_read,\n\t.write_data = &nonce_nand_write,\n\t.write_block_data = &nonce_nand_fast_block_write,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/nuc910.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n * NAND controller interface for Nuvoton NUC910\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"nuc910.h\"\n#include \"arm_io.h\"\n#include <target/arm.h>\n\nstruct nuc910_nand_controller {\n\tstruct arm_nand_data io;\n};\n\nstatic int validate_target_state(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct target *target = nand->target;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\ttarget_write_u8(target, NUC910_SMCMD, command);\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct target *target = nand->target;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\ttarget_write_u32(target, NUC910_SMADDR, ((address & 0xff) | NUC910_SMADDR_EOA));\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_read(struct nand_device *nand, void *data)\n{\n\tstruct target *target = nand->target;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\ttarget_read_u8(target, NUC910_SMDATA, data);\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_write(struct nand_device *nand, uint16_t data)\n{\n\tstruct target *target = nand->target;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\ttarget_write_u8(target, NUC910_SMDATA, data);\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_read_block_data(struct nand_device *nand,\n\t\tuint8_t *data, int data_size)\n{\n\tstruct nuc910_nand_controller *nuc910_nand = nand->controller_priv;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tnuc910_nand->io.chunk_size = nand->page_size;\n\n\t/* try the fast way first */\n\tresult = arm_nandread(&nuc910_nand->io, data, data_size);\n\tif (result != ERROR_NAND_NO_BUFFER)\n\t\treturn result;\n\n\t/* else do it slowly */\n\twhile (data_size--)\n\t\tnuc910_nand_read(nand, data++);\n\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_write_block_data(struct nand_device *nand,\n\t\tuint8_t *data, int data_size)\n{\n\tstruct nuc910_nand_controller *nuc910_nand = nand->controller_priv;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tnuc910_nand->io.chunk_size = nand->page_size;\n\n\t/* try the fast way first */\n\tresult = arm_nandwrite(&nuc910_nand->io, data, data_size);\n\tif (result != ERROR_NAND_NO_BUFFER)\n\t\treturn result;\n\n\t/* else do it slowly */\n\twhile (data_size--)\n\t\tnuc910_nand_write(nand, *data++);\n\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_reset(struct nand_device *nand)\n{\n\treturn nuc910_nand_command(nand, NAND_CMD_RESET);\n}\n\nstatic int nuc910_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct target *target = nand->target;\n\tuint32_t status;\n\n\tdo {\n\t\ttarget_read_u32(target, NUC910_SMISR, &status);\n\t\tif (status & NUC910_SMISR_RB_)\n\t\t\treturn 1;\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nNAND_DEVICE_COMMAND_HANDLER(nuc910_nand_device_command)\n{\n\tstruct nuc910_nand_controller *nuc910_nand;\n\n\tnuc910_nand = calloc(1, sizeof(struct nuc910_nand_controller));\n\tif (!nuc910_nand) {\n\t\tLOG_ERROR(\"no memory for nand controller\");\n\t\treturn ERROR_NAND_DEVICE_INVALID;\n\t}\n\n\tnand->controller_priv = nuc910_nand;\n\treturn ERROR_OK;\n}\n\nstatic int nuc910_nand_init(struct nand_device *nand)\n{\n\tstruct nuc910_nand_controller *nuc910_nand = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tint bus_width = nand->bus_width ? nand->bus_width : 8;\n\tint result;\n\n\tresult = validate_target_state(nand);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* nuc910 only supports 8bit */\n\tif (bus_width != 8) {\n\t\tLOG_ERROR(\"nuc910 only supports 8 bit bus width, not %i\", bus_width);\n\t\treturn ERROR_NAND_OPERATION_NOT_SUPPORTED;\n\t}\n\n\t/* inform calling code about selected bus width */\n\tnand->bus_width = bus_width;\n\n\tnuc910_nand->io.target = target;\n\tnuc910_nand->io.data = NUC910_SMDATA;\n\tnuc910_nand->io.op = ARM_NAND_NONE;\n\n\t/* configure nand controller */\n\ttarget_write_u32(target, NUC910_FMICSR, NUC910_FMICSR_SM_EN);\n\ttarget_write_u32(target, NUC910_SMCSR, 0x010000a8);\t/* 2048 page size */\n\ttarget_write_u32(target, NUC910_SMTCR, 0x00010204);\n\ttarget_write_u32(target, NUC910_SMIER, 0x00000000);\n\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller nuc910_nand_controller = {\n\t.name = \"nuc910\",\n\t.command = nuc910_nand_command,\n\t.address = nuc910_nand_address,\n\t.read_data = nuc910_nand_read,\n\t.write_data\t= nuc910_nand_write,\n\t.write_block_data = nuc910_nand_write_block_data,\n\t.read_block_data = nuc910_nand_read_block_data,\n\t.nand_ready = nuc910_nand_ready,\n\t.reset = nuc910_nand_reset,\n\t.nand_device_command = nuc910_nand_device_command,\n\t.init = nuc910_nand_init,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/nuc910.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/*\n * NAND controller interface for Nuvoton NUC910\n */\n\n#ifndef OPENOCD_FLASH_NAND_NUC910_H\n#define OPENOCD_FLASH_NAND_NUC910_H\n\n#define NUC910_FMICSR\t0xB000D000\n#define NUC910_SMCSR\t0xB000D0A0\n#define NUC910_SMTCR\t0xB000D0A4\n#define NUC910_SMIER\t0xB000D0A8\n#define NUC910_SMISR\t0xB000D0AC\n#define NUC910_SMCMD\t0xB000D0B0\n#define NUC910_SMADDR\t0xB000D0B4\n#define NUC910_SMDATA\t0xB000D0B8\n\n#define NUC910_SMECC0\t0xB000D0BC\n#define NUC910_SMECC1\t0xB000D0C0\n#define NUC910_SMECC2\t0xB000D0C4\n#define NUC910_SMECC3\t0xB000D0C8\n#define NUC910_ECC4ST\t0xB000D114\n\n/* Global Control and Status Register (FMICSR) */\n#define NUC910_FMICSR_SM_EN\t(1<<3)\n\n/* NAND Flash Address Port Register (SMADDR) */\n#define NUC910_SMADDR_EOA (1<<31)\n\n/* NAND Flash Control and Status Register (SMCSR) */\n#define NUC910_SMCSR_PSIZE\t(1<<3)\n#define NUC910_SMCSR_DBW\t(1<<4)\n\n/* NAND Flash Interrupt Status Register (SMISR) */\n#define NUC910_SMISR_ECC_IF\t(1<<2)\n#define NUC910_SMISR_RB_\t(1<<18)\n\n/* ECC4 Correction Status (ECC4ST) */\n\n#endif /* OPENOCD_FLASH_NAND_NUC910_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/orion.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Marvell Semiconductors, Inc.                    *\n *   Written by Nicolas Pitre <nico at marvell.com>                        *\n ***************************************************************************/\n\n/*\n * NAND controller interface for Marvell Orion/Kirkwood SoCs.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"arm_io.h\"\n#include <target/arm.h>\n\nstruct orion_nand_controller {\n\tstruct arm_nand_data\tio;\n\n\tuint32_t\t\tcmd;\n\tuint32_t\t\taddr;\n\tuint32_t\t\tdata;\n};\n\n#define CHECK_HALTED \\\n\tdo { \\\n\t\tif (target->state != TARGET_HALTED) { \\\n\t\t\tLOG_ERROR(\"NAND flash access requires halted target\"); \\\n\t\t\treturn ERROR_NAND_OPERATION_FAILED; \\\n\t\t} \\\n\t} while (0)\n\nstatic int orion_nand_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct orion_nand_controller *hw = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tCHECK_HALTED;\n\ttarget_write_u8(target, hw->cmd, command);\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct orion_nand_controller *hw = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tCHECK_HALTED;\n\ttarget_write_u8(target, hw->addr, address);\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_read(struct nand_device *nand, void *data)\n{\n\tstruct orion_nand_controller *hw = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tCHECK_HALTED;\n\ttarget_read_u8(target, hw->data, data);\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_write(struct nand_device *nand, uint16_t data)\n{\n\tstruct orion_nand_controller *hw = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tCHECK_HALTED;\n\ttarget_write_u8(target, hw->data, data);\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_slow_block_write(struct nand_device *nand, uint8_t *data, int size)\n{\n\twhile (size--)\n\t\torion_nand_write(nand, *data++);\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_fast_block_write(struct nand_device *nand, uint8_t *data, int size)\n{\n\tstruct orion_nand_controller *hw = nand->controller_priv;\n\tint retval;\n\n\thw->io.chunk_size = nand->page_size;\n\n\tretval = arm_nandwrite(&hw->io, data, size);\n\tif (retval == ERROR_NAND_NO_BUFFER)\n\t\tretval = orion_nand_slow_block_write(nand, data, size);\n\n\treturn retval;\n}\n\nstatic int orion_nand_reset(struct nand_device *nand)\n{\n\treturn orion_nand_command(nand, NAND_CMD_RESET);\n}\n\nNAND_DEVICE_COMMAND_HANDLER(orion_nand_device_command)\n{\n\tstruct orion_nand_controller *hw;\n\tuint32_t base;\n\tuint8_t ale, cle;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\thw = calloc(1, sizeof(*hw));\n\tif (!hw) {\n\t\tLOG_ERROR(\"no memory for nand controller\");\n\t\treturn ERROR_NAND_DEVICE_INVALID;\n\t}\n\n\tnand->controller_priv = hw;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], base);\n\tcle = 0;\n\tale = 1;\n\n\thw->data = base;\n\thw->cmd = base + (1 << cle);\n\thw->addr = base + (1 << ale);\n\n\thw->io.target = nand->target;\n\thw->io.data = hw->data;\n\thw->io.op = ARM_NAND_NONE;\n\n\treturn ERROR_OK;\n}\n\nstatic int orion_nand_init(struct nand_device *nand)\n{\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller orion_nand_controller = {\n\t.name = \"orion\",\n\t.usage = \"<target_id> <NAND_address>\",\n\t.command = orion_nand_command,\n\t.address = orion_nand_address,\n\t.read_data = orion_nand_read,\n\t.write_data = orion_nand_write,\n\t.write_block_data = orion_nand_fast_block_write,\n\t.reset = orion_nand_reset,\n\t.nand_device_command = orion_nand_device_command,\n\t.init = orion_nand_init,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c2410.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n/*\n * S3C2410 OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n\nNAND_DEVICE_COMMAND_HANDLER(s3c2410_nand_device_command)\n{\n\tstruct s3c24xx_nand_controller *info;\n\tCALL_S3C24XX_DEVICE_COMMAND(nand, &info);\n\n\t/* fill in the address fields for the core device */\n\tinfo->cmd = S3C2410_NFCMD;\n\tinfo->addr = S3C2410_NFADDR;\n\tinfo->data = S3C2410_NFDATA;\n\tinfo->nfstat = S3C2410_NFSTAT;\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c2410_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\ttarget_write_u32(target, S3C2410_NFCONF,\n\t\t\t S3C2410_NFCONF_EN | S3C2410_NFCONF_TACLS(3) |\n\t\t\t S3C2410_NFCONF_TWRPH0(5) | S3C2410_NFCONF_TWRPH1(3));\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c2410_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u32(target, S3C2410_NFDATA, data);\n\treturn ERROR_OK;\n}\n\nstatic int s3c2410_read_data(struct nand_device *nand, void *data)\n{\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_read_u8(target, S3C2410_NFDATA, data);\n\treturn ERROR_OK;\n}\n\nstatic int s3c2410_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct target *target = nand->target;\n\tuint8_t status;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tdo {\n\t\ttarget_read_u8(target, S3C2410_NFSTAT, &status);\n\n\t\tif (status & S3C2410_NFSTAT_BUSY)\n\t\t\treturn 1;\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\treturn 0;\n}\n\nstruct nand_flash_controller s3c2410_nand_controller = {\n\t.name = \"s3c2410\",\n\t.nand_device_command = &s3c2410_nand_device_command,\n\t.init = &s3c2410_init,\n\t.reset = &s3c24xx_reset,\n\t.command = &s3c24xx_command,\n\t.address = &s3c24xx_address,\n\t.write_data = &s3c2410_write_data,\n\t.read_data = &s3c2410_read_data,\n\t.write_page = s3c24xx_write_page,\n\t.read_page = s3c24xx_read_page,\n\t.nand_ready = &s3c2410_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c2412.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n/*\n * S3C2412 OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n\nNAND_DEVICE_COMMAND_HANDLER(s3c2412_nand_device_command)\n{\n\tstruct s3c24xx_nand_controller *info;\n\tCALL_S3C24XX_DEVICE_COMMAND(nand, &info);\n\n\t/* fill in the address fields for the core device */\n\tinfo->cmd = S3C2440_NFCMD;\n\tinfo->addr = S3C2440_NFADDR;\n\tinfo->data = S3C2440_NFDATA;\n\tinfo->nfstat = S3C2412_NFSTAT;\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c2412_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\ttarget_write_u32(target, S3C2410_NFCONF,\n\t\t\t S3C2440_NFCONF_TACLS(3) |\n\t\t\t S3C2440_NFCONF_TWRPH0(7) |\n\t\t\t S3C2440_NFCONF_TWRPH1(7));\n\n\ttarget_write_u32(target, S3C2440_NFCONT,\n\t\t\t S3C2412_NFCONT_INIT_MAIN_ECC |\n\t\t\t S3C2440_NFCONT_ENABLE);\n\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller s3c2412_nand_controller = {\n\t.name = \"s3c2412\",\n\t.nand_device_command = &s3c2412_nand_device_command,\n\t.init = &s3c2412_init,\n\t.reset = &s3c24xx_reset,\n\t.command = &s3c24xx_command,\n\t.address = &s3c24xx_address,\n\t.write_data = &s3c24xx_write_data,\n\t.read_data = &s3c24xx_read_data,\n\t.write_page = s3c24xx_write_page,\n\t.read_page = s3c24xx_read_page,\n\t.write_block_data = &s3c2440_write_block_data,\n\t.read_block_data = &s3c2440_read_block_data,\n\t.nand_ready = &s3c2440_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c2440.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n/*\n * S3C2440 OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n\nNAND_DEVICE_COMMAND_HANDLER(s3c2440_nand_device_command)\n{\n\tstruct s3c24xx_nand_controller *info;\n\tCALL_S3C24XX_DEVICE_COMMAND(nand, &info);\n\n\t/* fill in the address fields for the core device */\n\tinfo->cmd = S3C2440_NFCMD;\n\tinfo->addr = S3C2440_NFADDR;\n\tinfo->data = S3C2440_NFDATA;\n\tinfo->nfstat = S3C2440_NFSTAT;\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c2440_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\ttarget_write_u32(target, S3C2410_NFCONF,\n\t\t\t S3C2440_NFCONF_TACLS(3) |\n\t\t\t S3C2440_NFCONF_TWRPH0(7) |\n\t\t\t S3C2440_NFCONF_TWRPH1(7));\n\n\ttarget_write_u32(target, S3C2440_NFCONT,\n\t\t\t S3C2440_NFCONT_INITECC | S3C2440_NFCONT_ENABLE);\n\n\treturn ERROR_OK;\n}\n\nint s3c2440_nand_ready(struct nand_device *nand, int timeout)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint8_t status;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\tdo {\n\t\ttarget_read_u8(target, s3c24xx_info->nfstat, &status);\n\n\t\tif (status & S3C2440_NFSTAT_READY)\n\t\t\treturn 1;\n\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\n\treturn 0;\n}\n\n/* use the fact we can read/write 4 bytes in one go via a single 32bit op */\n\nint s3c2440_read_block_data(struct nand_device *nand, uint8_t *data, int data_size)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nfdata = s3c24xx_info->data;\n\tuint32_t tmp;\n\n\tLOG_INFO(\"%s: reading data: %p, %p, %d\", __func__, nand, data, data_size);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\twhile (data_size >= 4) {\n\t\ttarget_read_u32(target, nfdata, &tmp);\n\n\t\tdata[0] = tmp;\n\t\tdata[1] = tmp >> 8;\n\t\tdata[2] = tmp >> 16;\n\t\tdata[3] = tmp >> 24;\n\n\t\tdata_size -= 4;\n\t\tdata += 4;\n\t}\n\n\twhile (data_size > 0) {\n\t\ttarget_read_u8(target, nfdata, data);\n\n\t\tdata_size -= 1;\n\t\tdata += 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint s3c2440_write_block_data(struct nand_device *nand, uint8_t *data, int data_size)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\tuint32_t nfdata = s3c24xx_info->data;\n\tuint32_t tmp;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\twhile (data_size >= 4) {\n\t\ttmp = le_to_h_u32(data);\n\t\ttarget_write_u32(target, nfdata, tmp);\n\n\t\tdata_size -= 4;\n\t\tdata += 4;\n\t}\n\n\twhile (data_size > 0) {\n\t\ttarget_write_u8(target, nfdata, *data);\n\n\t\tdata_size -= 1;\n\t\tdata += 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller s3c2440_nand_controller = {\n\t.name = \"s3c2440\",\n\t.nand_device_command = &s3c2440_nand_device_command,\n\t.init = &s3c2440_init,\n\t.reset = &s3c24xx_reset,\n\t.command = &s3c24xx_command,\n\t.address = &s3c24xx_address,\n\t.write_data = &s3c24xx_write_data,\n\t.read_data = &s3c24xx_read_data,\n\t.write_page = s3c24xx_write_page,\n\t.read_page = s3c24xx_read_page,\n\t.write_block_data = &s3c2440_write_block_data,\n\t.read_block_data = &s3c2440_read_block_data,\n\t.nand_ready = &s3c2440_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c2443.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n/*\n * S3C2443 OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n\nNAND_DEVICE_COMMAND_HANDLER(s3c2443_nand_device_command)\n{\n\tstruct s3c24xx_nand_controller *info;\n\tCALL_S3C24XX_DEVICE_COMMAND(nand, &info);\n\n\t/* fill in the address fields for the core device */\n\tinfo->cmd = S3C2440_NFCMD;\n\tinfo->addr = S3C2440_NFADDR;\n\tinfo->data = S3C2440_NFDATA;\n\tinfo->nfstat = S3C2412_NFSTAT;\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c2443_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\ttarget_write_u32(target, S3C2410_NFCONF,\n\t\t\t S3C2440_NFCONF_TACLS(3) |\n\t\t\t S3C2440_NFCONF_TWRPH0(7) |\n\t\t\t S3C2440_NFCONF_TWRPH1(7));\n\n\ttarget_write_u32(target, S3C2440_NFCONT,\n\t\t\t S3C2412_NFCONT_INIT_MAIN_ECC |\n\t\t\t S3C2440_NFCONT_ENABLE);\n\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller s3c2443_nand_controller = {\n\t.name = \"s3c2443\",\n\t.nand_device_command = &s3c2443_nand_device_command,\n\t.init = &s3c2443_init,\n\t.reset = &s3c24xx_reset,\n\t.command = &s3c24xx_command,\n\t.address = &s3c24xx_address,\n\t.write_data = &s3c24xx_write_data,\n\t.read_data = &s3c24xx_read_data,\n\t.write_page = s3c24xx_write_page,\n\t.read_page = s3c24xx_read_page,\n\t.write_block_data = &s3c2440_write_block_data,\n\t.read_block_data = &s3c2440_read_block_data,\n\t.nand_ready = &s3c2440_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c24xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n/*\n * S3C24XX Series OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n\nS3C24XX_DEVICE_COMMAND()\n{\n\t*info = NULL;\n\n\tstruct s3c24xx_nand_controller *s3c24xx_info;\n\ts3c24xx_info = malloc(sizeof(struct s3c24xx_nand_controller));\n\tif (!s3c24xx_info) {\n\t\tLOG_ERROR(\"no memory for nand controller\");\n\t\treturn -ENOMEM;\n\t}\n\n\tnand->controller_priv = s3c24xx_info;\n\t*info = s3c24xx_info;\n\n\treturn ERROR_OK;\n}\n\nint s3c24xx_reset(struct nand_device *nand)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u32(target, s3c24xx_info->cmd, 0xff);\n\n\treturn ERROR_OK;\n}\n\nint s3c24xx_command(struct nand_device *nand, uint8_t command)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u16(target, s3c24xx_info->cmd, command);\n\treturn ERROR_OK;\n}\n\nint s3c24xx_address(struct nand_device *nand, uint8_t address)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u16(target, s3c24xx_info->addr, address);\n\treturn ERROR_OK;\n}\n\nint s3c24xx_write_data(struct nand_device *nand, uint16_t data)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u8(target, s3c24xx_info->data, data);\n\treturn ERROR_OK;\n}\n\nint s3c24xx_read_data(struct nand_device *nand, void *data)\n{\n\tstruct s3c24xx_nand_controller *s3c24xx_info = nand->controller_priv;\n\tstruct target *target = nand->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target must be halted to use S3C24XX NAND flash controller\");\n\t\treturn ERROR_NAND_OPERATION_FAILED;\n\t}\n\n\ttarget_read_u8(target, s3c24xx_info->data, data);\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c24xx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007, 2008 by Ben Dooks                                 *\n *   ben@fluff.org                                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NAND_S3C24XX_H\n#define OPENOCD_FLASH_NAND_S3C24XX_H\n\n/*\n * S3C24XX Series OpenOCD NAND Flash controller support.\n *\n * Many thanks to Simtec Electronics for sponsoring this work.\n */\n\n#include \"imp.h\"\n#include \"s3c24xx_regs.h\"\n#include <target/target.h>\n\nstruct s3c24xx_nand_controller {\n\t/* register addresses */\n\tuint32_t\t\t cmd;\n\tuint32_t\t\t addr;\n\tuint32_t\t\t data;\n\tuint32_t\t\t nfstat;\n};\n\n/* Default to using the un-translated NAND register based address */\n#undef S3C2410_NFREG\n#define S3C2410_NFREG(x) ((x) + 0x4e000000)\n\n#define S3C24XX_DEVICE_COMMAND() \\\n\t\tCOMMAND_HELPER(s3c24xx_nand_device_command, \\\n\t\t\t\tstruct nand_device *nand, \\\n\t\t\t\tstruct s3c24xx_nand_controller **info)\n\nS3C24XX_DEVICE_COMMAND();\n\n#define CALL_S3C24XX_DEVICE_COMMAND(d, i) \\\n\tdo { \\\n\t\tint retval = CALL_COMMAND_HANDLER(s3c24xx_nand_device_command, d, i); \\\n\t\tif (retval != ERROR_OK) \\\n\t\t\treturn retval; \\\n\t} while (0)\n\nint s3c24xx_reset(struct nand_device *nand);\n\nint s3c24xx_command(struct nand_device *nand, uint8_t command);\nint s3c24xx_address(struct nand_device *nand, uint8_t address);\n\nint s3c24xx_write_data(struct nand_device *nand, uint16_t data);\nint s3c24xx_read_data(struct nand_device *nand, void *data);\n\n#define s3c24xx_write_page NULL\n#define s3c24xx_read_page NULL\n\n/* code shared between different controllers */\n\nint s3c2440_nand_ready(struct nand_device *nand, int timeout);\n\nint s3c2440_read_block_data(struct nand_device *nand,\n\t\tuint8_t *data, int data_size);\nint s3c2440_write_block_data(struct nand_device *nand,\n\t\tuint8_t *data, int data_size);\n\n#endif /* OPENOCD_FLASH_NAND_S3C24XX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c24xx_regs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-only */\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Simtec Electronics                        *\n *   linux@simtec.co.uk                                                    *\n *   http://www.simtec.co.uk/products/SWLINUX/                             *\n ***************************************************************************/\n\n/*\n * S3C2410 NAND register definitions\n */\n\n#ifndef OPENOCD_FLASH_NAND_S3C24XX_REGS_H\n#define OPENOCD_FLASH_NAND_S3C24XX_REGS_H\n\n#define S3C2410_NFREG(x) (x)\n\n#define S3C2410_NFCONF  S3C2410_NFREG(0x00)\n#define S3C2410_NFCMD   S3C2410_NFREG(0x04)\n#define S3C2410_NFADDR  S3C2410_NFREG(0x08)\n#define S3C2410_NFDATA  S3C2410_NFREG(0x0C)\n#define S3C2410_NFSTAT  S3C2410_NFREG(0x10)\n#define S3C2410_NFECC   S3C2410_NFREG(0x14)\n\n#define S3C2440_NFCONT   S3C2410_NFREG(0x04)\n#define S3C2440_NFCMD    S3C2410_NFREG(0x08)\n#define S3C2440_NFADDR   S3C2410_NFREG(0x0C)\n#define S3C2440_NFDATA   S3C2410_NFREG(0x10)\n#define S3C2440_NFECCD0  S3C2410_NFREG(0x14)\n#define S3C2440_NFECCD1  S3C2410_NFREG(0x18)\n#define S3C2440_NFECCD   S3C2410_NFREG(0x1C)\n#define S3C2440_NFSTAT   S3C2410_NFREG(0x20)\n#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)\n#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)\n#define S3C2440_NFMECC0  S3C2410_NFREG(0x2C)\n#define S3C2440_NFMECC1  S3C2410_NFREG(0x30)\n#define S3C2440_NFSECC   S3C2410_NFREG(0x34)\n#define S3C2440_NFSBLK   S3C2410_NFREG(0x38)\n#define S3C2440_NFEBLK   S3C2410_NFREG(0x3C)\n\n#define S3C2412_NFSBLK\t\tS3C2410_NFREG(0x20)\n#define S3C2412_NFEBLK\t\tS3C2410_NFREG(0x24)\n#define S3C2412_NFSTAT\t\tS3C2410_NFREG(0x28)\n#define S3C2412_NFMECC_ERR0\tS3C2410_NFREG(0x2C)\n#define S3C2412_NFMECC_ERR1\tS3C2410_NFREG(0x30)\n#define S3C2412_NFMECC0\t\tS3C2410_NFREG(0x34)\n#define S3C2412_NFMECC1\t\tS3C2410_NFREG(0x38)\n#define S3C2412_NFSECC\t\tS3C2410_NFREG(0x3C)\n\n#define S3C2410_NFCONF_EN          (1 << 15)\n#define S3C2410_NFCONF_512BYTE     (1 << 14)\n#define S3C2410_NFCONF_4STEP       (1 << 13)\n#define S3C2410_NFCONF_INITECC     (1 << 12)\n#define S3C2410_NFCONF_NFCE        (1 << 11)\n#define S3C2410_NFCONF_TACLS(x)    ((x) << 8)\n#define S3C2410_NFCONF_TWRPH0(x)   ((x) << 4)\n#define S3C2410_NFCONF_TWRPH1(x)   ((x) << 0)\n\n#define S3C2410_NFSTAT_BUSY        (1 << 0)\n\n#define S3C2440_NFCONF_BUSWIDTH_8\t(0 << 0)\n#define S3C2440_NFCONF_BUSWIDTH_16\t(1 << 0)\n#define S3C2440_NFCONF_ADVFLASH\t\t(1 << 3)\n#define S3C2440_NFCONF_TACLS(x)\t\t((x) << 12)\n#define S3C2440_NFCONF_TWRPH0(x)\t((x) << 8)\n#define S3C2440_NFCONF_TWRPH1(x)\t((x) << 4)\n\n#define S3C2440_NFCONT_LOCKTIGHT\t(1 << 13)\n#define S3C2440_NFCONT_SOFTLOCK\t\t(1 << 12)\n#define S3C2440_NFCONT_ILLEGALACC_EN\t(1 << 10)\n#define S3C2440_NFCONT_RNBINT_EN\t(1 << 9)\n#define S3C2440_NFCONT_RN_FALLING\t(1 << 8)\n#define S3C2440_NFCONT_SPARE_ECCLOCK\t(1 << 6)\n#define S3C2440_NFCONT_MAIN_ECCLOCK\t(1 << 5)\n#define S3C2440_NFCONT_INITECC\t\t(1 << 4)\n#define S3C2440_NFCONT_NFCE\t\t\t(1 << 1)\n#define S3C2440_NFCONT_ENABLE\t\t(1 << 0)\n\n#define S3C2440_NFSTAT_READY\t\t(1 << 0)\n#define S3C2440_NFSTAT_NCE\t\t\t(1 << 1)\n#define S3C2440_NFSTAT_RNB_CHANGE\t(1 << 2)\n#define S3C2440_NFSTAT_ILLEGAL_ACCESS\t(1 << 3)\n\n#define S3C2412_NFCONF_NANDBOOT\t\t(1 << 31)\n#define S3C2412_NFCONF_ECCCLKCON\t(1 << 30)\n#define S3C2412_NFCONF_ECC_MLC\t\t(1 << 24)\n#define S3C2412_NFCONF_TACLS_MASK\t(7 << 12)\t/* 1 extra bit of Tacls */\n\n#define S3C2412_NFCONT_ECC4_DIRWR\t(1 << 18)\n#define S3C2412_NFCONT_LOCKTIGHT\t(1 << 17)\n#define S3C2412_NFCONT_SOFTLOCK\t\t(1 << 16)\n#define S3C2412_NFCONT_ECC4_ENCINT\t(1 << 13)\n#define S3C2412_NFCONT_ECC4_DECINT\t(1 << 12)\n#define S3C2412_NFCONT_MAIN_ECC_LOCK\t(1 << 7)\n#define S3C2412_NFCONT_INIT_MAIN_ECC\t(1 << 5)\n#define S3C2412_NFCONT_NFCE1\t\t(1 << 2)\n#define S3C2412_NFCONT_NFCE0\t\t(1 << 1)\n\n#define S3C2412_NFSTAT_ECC_ENCDONE\t(1 << 7)\n#define S3C2412_NFSTAT_ECC_DECDONE\t(1 << 6)\n#define S3C2412_NFSTAT_ILLEGAL_ACCESS\t(1 << 5)\n#define S3C2412_NFSTAT_RNB_CHANGE\t(1 << 4)\n#define S3C2412_NFSTAT_NFCE1\t\t(1 << 3)\n#define S3C2412_NFSTAT_NFCE0\t\t(1 << 2)\n#define S3C2412_NFSTAT_RES1\t\t\t(1 << 1)\n#define S3C2412_NFSTAT_READY\t\t(1 << 0)\n\n#define S3C2412_NFECCERR_SERRDATA(x)\t(((x) >> 21) & 0xf)\n#define S3C2412_NFECCERR_SERRBIT(x)\t\t(((x) >> 18) & 0x7)\n#define S3C2412_NFECCERR_MERRDATA(x)\t(((x) >> 7) & 0x3ff)\n#define S3C2412_NFECCERR_MERRBIT(x)\t\t(((x) >> 4) & 0x7)\n#define S3C2412_NFECCERR_SPARE_ERR(x)\t(((x) >> 2) & 0x3)\n#define S3C2412_NFECCERR_MAIN_ERR(x)\t(((x) >> 2) & 0x3)\n#define S3C2412_NFECCERR_NONE\t\t(0)\n#define S3C2412_NFECCERR_1BIT\t\t(1)\n#define S3C2412_NFECCERR_MULTIBIT\t(2)\n#define S3C2412_NFECCERR_ECCAREA\t(3)\n\n#endif /* OPENOCD_FLASH_NAND_S3C24XX_REGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/s3c6400.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Peter Korsgaard <jacmet@sunsite.dk>             *\n *   Heavily based on s3c2412.c by Ben Dooks <ben@fluff.org>               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"s3c24xx.h\"\n/* s3c64xx uses another base address for the nand controller than 24xx */\n#undef S3C2410_NFREG\n#define S3C2410_NFREG(x) ((x) + 0x70200000)\n\nNAND_DEVICE_COMMAND_HANDLER(s3c6400_nand_device_command)\n{\n\tstruct s3c24xx_nand_controller *info;\n\tCALL_S3C24XX_DEVICE_COMMAND(nand, &info);\n\n\t/* fill in the address fields for the core device */\n\tinfo->cmd = S3C2440_NFCMD;\n\tinfo->addr = S3C2440_NFADDR;\n\tinfo->data = S3C2440_NFDATA;\n\tinfo->nfstat = S3C2412_NFSTAT;\n\n\treturn ERROR_OK;\n}\n\nstatic int s3c6400_init(struct nand_device *nand)\n{\n\tstruct target *target = nand->target;\n\n\ttarget_write_u32(target, S3C2410_NFCONF,\n\t\t\t S3C2440_NFCONF_TACLS(3) |\n\t\t\t S3C2440_NFCONF_TWRPH0(7) |\n\t\t\t S3C2440_NFCONF_TWRPH1(7) | 4);\n\n\ttarget_write_u32(target, S3C2440_NFCONT,\n\t\t\t S3C2412_NFCONT_INIT_MAIN_ECC |\n\t\t\t S3C2440_NFCONT_ENABLE);\n\n\treturn ERROR_OK;\n}\n\nstruct nand_flash_controller s3c6400_nand_controller = {\n\t.name = \"s3c6400\",\n\t.nand_device_command = &s3c6400_nand_device_command,\n\t.init = &s3c6400_init,\n\t.reset = &s3c24xx_reset,\n\t.command = &s3c24xx_command,\n\t.address = &s3c24xx_address,\n\t.write_data = &s3c24xx_write_data,\n\t.read_data = &s3c24xx_read_data,\n\t.write_page = s3c24xx_write_page,\n\t.read_page = s3c24xx_read_page,\n\t.write_block_data = &s3c2440_write_block_data,\n\t.read_block_data = &s3c2440_read_block_data,\n\t.nand_ready = &s3c2440_nand_ready,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nand/tcl.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2002 Thomas Gleixner <tglx@linutronix.de>               *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *                                                                         *\n *   Partially based on drivers/mtd/nand_ids.c from Linux.                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"core.h\"\n#include \"imp.h\"\n#include \"fileio.h\"\n#include <target/target.h>\n\nCOMMAND_HANDLER(handle_nand_list_command)\n{\n\tstruct nand_device *p;\n\tint i;\n\n\tif (!nand_devices) {\n\t\tcommand_print(CMD, \"no NAND flash devices configured\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (p = nand_devices, i = 0; p; p = p->next, i++) {\n\t\tif (p->device)\n\t\t\tcommand_print(CMD, \"#%i: %s (%s) \"\n\t\t\t\t\"pagesize: %i, buswidth: %i,\\n\\t\"\n\t\t\t\t\"blocksize: %i, blocks: %i\",\n\t\t\t\ti, p->device->name, p->manufacturer->name,\n\t\t\t\tp->page_size, p->bus_width,\n\t\t\t\tp->erase_size, p->num_blocks);\n\t\telse\n\t\t\tcommand_print(CMD, \"#%i: not probed\", i);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_info_command)\n{\n\tint i = 0;\n\tint j = 0;\n\tint first = -1;\n\tint last = -1;\n\n\tswitch (CMD_ARGC) {\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tcase 1:\n\t\t\tfirst = 0;\n\t\t\tlast = INT32_MAX;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], i);\n\t\t\tfirst = last = i;\n\t\t\ti = 0;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], first);\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[2], last);\n\t\t\tbreak;\n\t}\n\n\tstruct nand_device *p;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!p->device) {\n\t\tcommand_print(CMD, \"#%s: not probed\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (first >= p->num_blocks)\n\t\tfirst = p->num_blocks - 1;\n\n\tif (last >= p->num_blocks)\n\t\tlast = p->num_blocks - 1;\n\n\tcommand_print(CMD,\n\t\t\"#%i: %s (%s) pagesize: %i, buswidth: %i, erasesize: %i\",\n\t\ti++,\n\t\tp->device->name,\n\t\tp->manufacturer->name,\n\t\tp->page_size,\n\t\tp->bus_width,\n\t\tp->erase_size);\n\n\tfor (j = first; j <= last; j++) {\n\t\tchar *erase_state, *bad_state;\n\n\t\tif (p->blocks[j].is_erased == 0)\n\t\t\terase_state = \"not erased\";\n\t\telse if (p->blocks[j].is_erased == 1)\n\t\t\terase_state = \"erased\";\n\t\telse\n\t\t\terase_state = \"erase state unknown\";\n\n\t\tif (p->blocks[j].is_bad == 0)\n\t\t\tbad_state = \"\";\n\t\telse if (p->blocks[j].is_bad == 1)\n\t\t\tbad_state = \" (marked bad)\";\n\t\telse\n\t\t\tbad_state = \" (block condition unknown)\";\n\n\t\tcommand_print(CMD,\n\t\t\t\"\\t#%i: 0x%8.8\" PRIx32 \" (%\" PRIu32 \"kB) %s%s\",\n\t\t\tj,\n\t\t\tp->blocks[j].offset,\n\t\t\tp->blocks[j].size / 1024,\n\t\t\terase_state,\n\t\t\tbad_state);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_probe_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct nand_device *p;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = nand_probe(p);\n\tif (retval == ERROR_OK) {\n\t\tcommand_print(CMD, \"NAND flash device '%s (%s)' found\",\n\t\t\tp->device->name, p->manufacturer->name);\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_nand_erase_command)\n{\n\tif (CMD_ARGC != 1 && CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct nand_device *p;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tunsigned long offset;\n\tunsigned long length;\n\n\t/* erase specified part of the chip; or else everything */\n\tif (CMD_ARGC == 3) {\n\t\tunsigned long size = p->erase_size * p->num_blocks;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);\n\t\tif ((offset % p->erase_size) != 0 || offset >= size)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);\n\t\tif ((length == 0) || (length % p->erase_size) != 0\n\t\t    || (length + offset) > size)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\toffset /= p->erase_size;\n\t\tlength /= p->erase_size;\n\t} else {\n\t\toffset = 0;\n\t\tlength = p->num_blocks;\n\t}\n\n\tretval = nand_erase(p, offset, offset + length - 1);\n\tif (retval == ERROR_OK) {\n\t\tcommand_print(CMD, \"erased blocks %lu to %lu \"\n\t\t\t\"on NAND flash device #%s '%s'\",\n\t\t\toffset, offset + length - 1,\n\t\t\tCMD_ARGV[0], p->device->name);\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_nand_check_bad_blocks_command)\n{\n\tint first = -1;\n\tint last = -1;\n\n\tif ((CMD_ARGC < 1) || (CMD_ARGC > 3) || (CMD_ARGC == 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct nand_device *p;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC == 3) {\n\t\tunsigned long offset;\n\t\tunsigned long length;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], offset);\n\t\tif (offset % p->erase_size)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\toffset /= p->erase_size;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], length);\n\t\tif (length % p->erase_size)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tlength -= 1;\n\t\tlength /= p->erase_size;\n\n\t\tfirst = offset;\n\t\tlast = offset + length;\n\t}\n\n\tretval = nand_build_bbt(p, first, last);\n\tif (retval == ERROR_OK) {\n\t\tcommand_print(CMD, \"checked NAND flash device for bad blocks, \"\n\t\t\t\"use \\\"nand info\\\" command to list blocks\");\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_nand_write_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct nand_fileio_state s;\n\tint retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,\n\t\t\t&s, &nand, FILEIO_READ, false, true);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t total_bytes = s.size;\n\twhile (s.size > 0) {\n\t\tint bytes_read = nand_fileio_read(nand, &s);\n\t\tif (bytes_read <= 0) {\n\t\t\tcommand_print(CMD, \"error while reading file\");\n\t\t\tnand_fileio_cleanup(&s);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\ts.size -= bytes_read;\n\n\t\tretval = nand_write_page(nand, s.address / nand->page_size,\n\t\t\t\ts.page, s.page_size, s.oob, s.oob_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"failed writing file %s \"\n\t\t\t\t\"to NAND flash %s at offset 0x%8.8\" PRIx32,\n\t\t\t\tCMD_ARGV[1], CMD_ARGV[0], s.address);\n\t\t\tnand_fileio_cleanup(&s);\n\t\t\treturn retval;\n\t\t}\n\t\ts.address += s.page_size;\n\t}\n\n\tif (nand_fileio_finish(&s) == ERROR_OK) {\n\t\tcommand_print(CMD, \"wrote file %s to NAND flash %s up to \"\n\t\t\t\"offset 0x%8.8\" PRIx32 \" in %fs (%0.3f KiB/s)\",\n\t\t\tCMD_ARGV[1], CMD_ARGV[0], s.address, duration_elapsed(&s.bench),\n\t\t\tduration_kbps(&s.bench, total_bytes));\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_verify_command)\n{\n\tstruct nand_device *nand = NULL;\n\tstruct nand_fileio_state file;\n\tint retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,\n\t\t\t&file, &nand, FILEIO_READ, false, true);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct nand_fileio_state dev;\n\tnand_fileio_init(&dev);\n\tdev.address = file.address;\n\tdev.size = file.size;\n\tdev.oob_format = file.oob_format;\n\tretval = nand_fileio_start(CMD, nand, NULL, FILEIO_NONE, &dev);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (file.size > 0) {\n\t\tretval = nand_read_page(nand, dev.address / dev.page_size,\n\t\t\t\tdev.page, dev.page_size, dev.oob, dev.oob_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"reading NAND flash page failed\");\n\t\t\tnand_fileio_cleanup(&dev);\n\t\t\tnand_fileio_cleanup(&file);\n\t\t\treturn retval;\n\t\t}\n\n\t\tint bytes_read = nand_fileio_read(nand, &file);\n\t\tif (bytes_read <= 0) {\n\t\t\tcommand_print(CMD, \"error while reading file\");\n\t\t\tnand_fileio_cleanup(&dev);\n\t\t\tnand_fileio_cleanup(&file);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif ((dev.page && memcmp(dev.page, file.page, dev.page_size)) ||\n\t\t\t\t(dev.oob && memcmp(dev.oob, file.oob, dev.oob_size))) {\n\t\t\tcommand_print(CMD, \"NAND flash contents differ \"\n\t\t\t\t\"at 0x%8.8\" PRIx32, dev.address);\n\t\t\tnand_fileio_cleanup(&dev);\n\t\t\tnand_fileio_cleanup(&file);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tfile.size -= bytes_read;\n\t\tdev.address += nand->page_size;\n\t}\n\n\tif (nand_fileio_finish(&file) == ERROR_OK) {\n\t\tcommand_print(CMD, \"verified file %s in NAND flash %s \"\n\t\t\t\"up to offset 0x%8.8\" PRIx32 \" in %fs (%0.3f KiB/s)\",\n\t\t\tCMD_ARGV[1], CMD_ARGV[0], dev.address, duration_elapsed(&file.bench),\n\t\t\tduration_kbps(&file.bench, dev.size));\n\t}\n\n\treturn nand_fileio_cleanup(&dev);\n}\n\nCOMMAND_HANDLER(handle_nand_dump_command)\n{\n\tsize_t filesize;\n\tstruct nand_device *nand = NULL;\n\tstruct nand_fileio_state s;\n\tint retval = CALL_COMMAND_HANDLER(nand_fileio_parse_args,\n\t\t\t&s, &nand, FILEIO_WRITE, true, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (s.size > 0) {\n\t\tsize_t size_written;\n\t\tretval = nand_read_page(nand, s.address / nand->page_size,\n\t\t\t\ts.page, s.page_size, s.oob, s.oob_size);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"reading NAND flash page failed\");\n\t\t\tnand_fileio_cleanup(&s);\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (s.page)\n\t\t\tfileio_write(s.fileio, s.page_size, s.page, &size_written);\n\n\t\tif (s.oob)\n\t\t\tfileio_write(s.fileio, s.oob_size, s.oob, &size_written);\n\n\t\ts.size -= nand->page_size;\n\t\ts.address += nand->page_size;\n\t}\n\n\tretval = fileio_size(s.fileio, &filesize);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (nand_fileio_finish(&s) == ERROR_OK) {\n\t\tcommand_print(CMD, \"dumped %zu bytes in %fs (%0.3f KiB/s)\",\n\t\t\tfilesize, duration_elapsed(&s.bench),\n\t\t\tduration_kbps(&s.bench, filesize));\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_raw_access_command)\n{\n\tif ((CMD_ARGC < 1) || (CMD_ARGC > 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct nand_device *p;\n\tint retval = CALL_COMMAND_HANDLER(nand_command_get_device, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!p->device) {\n\t\tcommand_print(CMD, \"#%s: not probed\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[1], p->use_raw);\n\n\tconst char *msg = p->use_raw ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"raw access is %s\", msg);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration nand_exec_command_handlers[] = {\n\t{\n\t\t.name = \"list\",\n\t\t.handler = handle_nand_list_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list configured NAND flash devices\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_nand_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[banknum | first_bank_num last_bank_num]\",\n\t\t.help = \"print info about one or more NAND flash devices\",\n\t},\n\t{\n\t\t.name = \"probe\",\n\t\t.handler = handle_nand_probe_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"identify NAND flash device\",\n\t},\n\t{\n\t\t.name = \"check_bad_blocks\",\n\t\t.handler = handle_nand_check_bad_blocks_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id [offset length]\",\n\t\t.help = \"check all or part of NAND flash device for bad blocks\",\n\t},\n\t{\n\t\t.name = \"erase\",\n\t\t.handler = handle_nand_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id [offset length]\",\n\t\t.help = \"erase all or subset of blocks on NAND flash device\",\n\t},\n\t{\n\t\t.name = \"dump\",\n\t\t.handler = handle_nand_dump_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename offset length \"\n\t\t\t\"['oob_raw'|'oob_only']\",\n\t\t.help = \"dump from NAND flash device\",\n\t},\n\t{\n\t\t.name = \"verify\",\n\t\t.handler = handle_nand_verify_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename offset \"\n\t\t\t\"['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']\",\n\t\t.help = \"verify NAND flash device\",\n\t},\n\t{\n\t\t.name = \"write\",\n\t\t.handler = handle_nand_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename offset \"\n\t\t\t\"['oob_raw'|'oob_only'|'oob_softecc'|'oob_softecc_kw']\",\n\t\t.help = \"write to NAND flash device\",\n\t},\n\t{\n\t\t.name = \"raw_access\",\n\t\t.handler = handle_nand_raw_access_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ['enable'|'disable']\",\n\t\t.help = \"raw access to NAND flash device\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int nand_init(struct command_context *cmd_ctx)\n{\n\tif (!nand_devices)\n\t\treturn ERROR_OK;\n\n\treturn register_commands(cmd_ctx, \"nand\", nand_exec_command_handlers);\n}\n\nCOMMAND_HANDLER(handle_nand_init_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstatic bool nand_initialized;\n\tif (nand_initialized) {\n\t\tLOG_INFO(\"'nand init' has already been called\");\n\t\treturn ERROR_OK;\n\t}\n\tnand_initialized = true;\n\n\tLOG_DEBUG(\"Initializing NAND devices...\");\n\treturn nand_init(CMD_CTX);\n}\n\nstatic int nand_list_walker(struct nand_flash_controller *c, void *x)\n{\n\tstruct command_invocation *cmd = x;\n\tcommand_print(cmd, \"  %s\", c->name);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_list_drivers)\n{\n\tcommand_print(CMD, \"Available NAND flash controller drivers:\");\n\treturn nand_driver_walk(&nand_list_walker, CMD);\n}\n\nstatic COMMAND_HELPER(create_nand_device, const char *bank_name,\n\tstruct nand_flash_controller *controller)\n{\n\tstruct nand_device *c;\n\tstruct target *target;\n\tint retval;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\ttarget = get_target(CMD_ARGV[1]);\n\tif (!target) {\n\t\tLOG_ERROR(\"invalid target %s\", CMD_ARGV[1]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (controller->commands) {\n\t\tretval = register_commands(CMD_CTX, NULL, controller->commands);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tc = malloc(sizeof(struct nand_device));\n\tif (!c) {\n\t\tLOG_ERROR(\"End of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tc->name = strdup(bank_name);\n\tc->target = target;\n\tc->controller = controller;\n\tc->controller_priv = NULL;\n\tc->manufacturer = NULL;\n\tc->device = NULL;\n\tc->bus_width = 0;\n\tc->address_cycles = 0;\n\tc->page_size = 0;\n\tc->use_raw = false;\n\tc->next = NULL;\n\n\tretval = CALL_COMMAND_HANDLER(controller->nand_device_command, c);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"'%s' driver rejected nand flash. Usage: %s\",\n\t\t\tcontroller->name,\n\t\t\tcontroller->usage);\n\t\tfree(c);\n\t\treturn retval;\n\t}\n\n\tif (!controller->usage)\n\t\tLOG_DEBUG(\"'%s' driver usage field missing\", controller->name);\n\n\tnand_device_add(c);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_nand_device_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* save name and increment (for compatibility) with drivers */\n\tconst char *bank_name = *CMD_ARGV++;\n\tCMD_ARGC--;\n\n\tconst char *driver_name = CMD_ARGV[0];\n\tstruct nand_flash_controller *controller;\n\tcontroller = nand_driver_find_by_name(CMD_ARGV[0]);\n\tif (!controller) {\n\t\tLOG_ERROR(\"No valid NAND flash driver found (%s)\", driver_name);\n\t\treturn CALL_COMMAND_HANDLER(handle_nand_list_drivers);\n\t}\n\treturn CALL_COMMAND_HANDLER(create_nand_device, bank_name, controller);\n}\n\nstatic const struct command_registration nand_config_command_handlers[] = {\n\t{\n\t\t.name = \"device\",\n\t\t.handler = &handle_nand_device_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"defines a new NAND bank\",\n\t\t.usage = \"bank_id driver target [driver_options ...]\",\n\t},\n\t{\n\t\t.name = \"drivers\",\n\t\t.handler = &handle_nand_list_drivers,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"lists available NAND drivers\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = &handle_nand_init_command,\n\t\t.help = \"initialize NAND devices\",\n\t\t.usage = \"\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration nand_command_handlers[] = {\n\t{\n\t\t.name = \"nand\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"NAND flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = nand_config_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint nand_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, nand_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libocdflashnor.la\n%C%_libocdflashnor_la_SOURCES = \\\n\t%D%/core.c \\\n\t%D%/tcl.c \\\n\t$(NOR_DRIVERS) \\\n\t%D%/drivers.c \\\n\t$(NORHEADERS)\n\nNOR_DRIVERS = \\\n\t%D%/aduc702x.c \\\n\t%D%/aducm360.c \\\n\t%D%/ambiqmicro.c \\\n\t%D%/at91sam4.c \\\n\t%D%/at91sam4l.c \\\n\t%D%/at91samd.c \\\n\t%D%/at91sam3.c \\\n\t%D%/at91sam7.c \\\n\t%D%/ath79.c \\\n\t%D%/atsamv.c \\\n\t%D%/atsame5.c \\\n\t%D%/avrf.c \\\n\t%D%/bluenrg-x.c \\\n\t%D%/cc3220sf.c \\\n\t%D%/cc26xx.c \\\n\t%D%/cfi.c \\\n\t%D%/dsp5680xx_flash.c \\\n\t%D%/efm32.c \\\n\t%D%/em357.c \\\n\t%D%/esirisc_flash.c \\\n\t%D%/faux.c \\\n\t%D%/fespi.c \\\n\t%D%/fm3.c \\\n\t%D%/fm4.c \\\n\t%D%/jtagspi.c \\\n\t%D%/kinetis.c \\\n\t%D%/kinetis_ke.c \\\n\t%D%/lpc2000.c \\\n\t%D%/lpc288x.c \\\n\t%D%/lpc2900.c \\\n\t%D%/lpcspifi.c \\\n\t%D%/max32xxx.c \\\n\t%D%/mdr.c \\\n\t%D%/msp432.c \\\n\t%D%/mrvlqspi.c \\\n\t%D%/niietcm4.c \\\n\t%D%/non_cfi.c \\\n\t%D%/npcx.c \\\n\t%D%/nrf5.c \\\n\t%D%/numicro.c \\\n\t%D%/ocl.c \\\n\t%D%/pic32mx.c \\\n\t%D%/psoc4.c \\\n\t%D%/psoc5lp.c \\\n\t%D%/psoc6.c \\\n\t%D%/qn908x.c \\\n\t%D%/renesas_rpchf.c \\\n\t%D%/rp2040.c \\\n\t%D%/rsl10.c \\\n\t%D%/sfdp.c \\\n\t%D%/sh_qspi.c \\\n\t%D%/sim3x.c \\\n\t%D%/spi.c \\\n\t%D%/stmsmi.c \\\n\t%D%/stmqspi.c \\\n\t%D%/stellaris.c \\\n\t%D%/stm32f1x.c \\\n\t%D%/stm32f2x.c \\\n\t%D%/stm32lx.c \\\n\t%D%/stm32l4x.c \\\n\t%D%/stm32h7x.c \\\n\t%D%/str7x.c \\\n\t%D%/str9x.c \\\n\t%D%/str9xpec.c \\\n\t%D%/swm050.c \\\n\t%D%/tms470.c \\\n\t%D%/virtual.c \\\n\t%D%/w600.c \\\n\t%D%/xcf.c \\\n\t%D%/xmc1xxx.c \\\n\t%D%/xmc4xxx.c\n\nNORHEADERS = \\\n\t%D%/core.h \\\n\t%D%/cc3220sf.h \\\n\t%D%/bluenrg-x.h \\\n\t%D%/cc26xx.h \\\n\t%D%/cfi.h \\\n\t%D%/driver.h \\\n\t%D%/imp.h \\\n\t%D%/non_cfi.h \\\n\t%D%/ocl.h \\\n\t%D%/sfdp.h \\\n\t%D%/spi.h \\\n\t%D%/stm32l4x.h \\\n\t%D%/stmqspi.h \\\n\t%D%/msp432.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/aduc702x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Kevin McGuire                                   *\n *   Copyright (C) 2008 by Marcel Wijlaars                                 *\n *   Copyright (C) 2009 by Michael Ashton                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/arm.h>\n\nstatic int aduc702x_build_sector_list(struct flash_bank *bank);\nstatic int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms);\nstatic int aduc702x_set_write_enable(struct target *target, int enable);\n\n#define ADUC702X_FLASH                          0xfffff800\n#define ADUC702X_FLASH_FEESTA           (0*4)\n#define ADUC702X_FLASH_FEEMOD           (1*4)\n#define ADUC702X_FLASH_FEECON           (2*4)\n#define ADUC702X_FLASH_FEEDAT           (3*4)\n#define ADUC702X_FLASH_FEEADR           (4*4)\n#define ADUC702X_FLASH_FEESIGN          (5*4)\n#define ADUC702X_FLASH_FEEPRO           (6*4)\n#define ADUC702X_FLASH_FEEHIDE          (7*4)\n\n/* flash bank aduc702x 0 0 0 0 <target#>\n * The ADC7019-28 devices all have the same flash layout */\nFLASH_BANK_COMMAND_HANDLER(aduc702x_flash_bank_command)\n{\n\tbank->base = 0x80000;\n\tbank->size = 0xF800;\t/* top 4k not accessible */\n\n\taduc702x_build_sector_list(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int aduc702x_build_sector_list(struct flash_bank *bank)\n{\n\t/* aduc7026_struct flash_bank *aduc7026_info = bank->driver_priv; */\n\n\tuint32_t offset = 0;\n\n\t/* sector size is 512 */\n\tbank->num_sectors = bank->size / 512;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tfor (unsigned int i = 0; i < bank->num_sectors; ++i) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = 512;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aduc702x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\t/* int res; */\n\tint x;\n\tint count;\n\t/* uint32_t v; */\n\tstruct target *target = bank->target;\n\n\taduc702x_set_write_enable(target, 1);\n\n\t/* mass erase */\n\tif (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) {\n\t\tLOG_DEBUG(\"performing mass erase.\");\n\t\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEDAT, 0x3cff);\n\t\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEADR, 0xffc3);\n\t\ttarget_write_u8(target, ADUC702X_FLASH + ADUC702X_FLASH_FEECON, 0x06);\n\n\t\tif (aduc702x_check_flash_completion(target, 3500) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"mass erase failed\");\n\t\t\taduc702x_set_write_enable(target, 0);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tLOG_DEBUG(\"mass erase successful.\");\n\t\treturn ERROR_OK;\n\t} else {\n\t\tunsigned long adr;\n\n\t\tcount = last - first + 1;\n\t\tfor (x = 0; x < count; ++x) {\n\t\t\tadr = bank->base + ((first + x) * 512);\n\n\t\t\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEADR, adr);\n\t\t\ttarget_write_u8(target, ADUC702X_FLASH + ADUC702X_FLASH_FEECON, 0x05);\n\n\t\t\tif (aduc702x_check_flash_completion(target, 50) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"failed to erase sector at address 0x%08lX\", adr);\n\t\t\t\taduc702x_set_write_enable(target, 0);\n\t\t\t\treturn ERROR_FLASH_SECTOR_NOT_ERASED;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"erased sector at address 0x%08lX\", adr);\n\t\t}\n\t}\n\n\taduc702x_set_write_enable(target, 0);\n\n\treturn ERROR_OK;\n}\n\n/* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall\n * back to another mechanism that does not require onboard RAM\n *\n * Caller should not check for other return values specifically\n */\nstatic int aduc702x_write_block(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 7000;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[6];\n\tstruct arm_algorithm arm_algo;\n\tint retval = ERROR_OK;\n\n\tif (((count%2) != 0) || ((offset%2) != 0)) {\n\t\tLOG_ERROR(\"write block must be multiple of two bytes in offset & length\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* parameters:\n\n\tr0 - address of source data (absolute)\n\tr1 - number of halfwords to be copied\n\tr2 - start address in flash (offset from beginning of flash memory)\n\tr3 - exit code\n\tr4 - base address of flash controller (0xFFFFF800)\n\n\tregisters:\n\n\tr5 - scratch\n\tr6 - set to 2, used to write flash command\n\n\t*/\n\tstatic const uint32_t aduc702x_flash_write_code[] = {\n\t\t/* <_start>: */\n\t\t0xe3a05008,\t/* mov\tr5, #8\t; 0x8 */\n\t\t0xe5845004,\t/* str\tr5, [r4, #4] */\n\t\t0xe3a06002,\t/* mov\tr6, #2\t; 0x2 */\n\t\t/* <next>: */\n\t\t0xe1c421b0,\t/* strh\tr2, [r4, #16] */\n\t\t0xe0d050b2,\t/* ldrh\tr5, [r0], #2 */\n\t\t0xe1c450bc,\t/* strh\tr5, [r4, #12] */\n\t\t0xe5c46008,\t/* strb\tr6, [r4, #8] */\n\t\t/* <wait_complete>: */\n\t\t0xe1d430b0,\t/* ldrh\tr3, [r4] */\n\t\t0xe3130004,\t/* tst\tr3, #4\t; 0x4 */\n\t\t0x1afffffc,\t/* bne\t1001c <wait_complete> */\n\t\t0xe2822002,\t/* add\tr2, r2, #2\t; 0x2 */\n\t\t0xe2511001,\t/* subs\tr1, r1, #1\t; 0x1 */\n\t\t0x0a000001,\t/* beq\t1003c <done> */\n\t\t0xe3130001,\t/* tst\tr3, #1\t; 0x1 */\n\t\t0x1afffff3,\t/* bne\t1000c <next> */\n\t\t/* <done>: */\n\t\t0xeafffffe\t/* b\t1003c <done> */\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(aduc702x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tuint8_t code[sizeof(aduc702x_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(aduc702x_flash_write_code),\n\t\t\taduc702x_flash_write_code);\n\tretval = target_write_buffer(target, write_algorithm->address, sizeof(code), code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a buffer,\n\t\t\t *free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, thisrun_count/2);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, 0xFFFFF800);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 5,\n\t\t\t\treg_params, write_algorithm->address,\n\t\t\t\twrite_algorithm->address +\n\t\t\t\tsizeof(aduc702x_flash_write_code) - 4,\n\t\t\t\t10000, &arm_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing aduc702x flash write algorithm\");\n\t\t\tbreak;\n\t\t}\n\n\t\tif ((buf_get_u32(reg_params[3].value, 0, 32) & 1) != 1) {\n\t\t\t/* FIX!!!! what does this mean??? replace w/sensible error message */\n\t\t\tLOG_ERROR(\"aduc702x detected error writing flash\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\n/* All-JTAG, single-access method.  Very slow.  Used only if there is no\n * working area available. */\nstatic int aduc702x_write_single(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tuint32_t x;\n\tuint8_t b;\n\tstruct target *target = bank->target;\n\n\taduc702x_set_write_enable(target, 1);\n\n\tfor (x = 0; x < count; x += 2) {\n\t\t/* FEEADR = address */\n\t\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEADR, offset + x);\n\n\t\t/* set up data */\n\t\tif ((x + 1) == count) {\n\t\t\t/* last byte */\n\t\t\ttarget_read_u8(target, offset + x + 1, &b);\n\t\t} else\n\t\t\tb = buffer[x + 1];\n\n\t\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEDAT, buffer[x] | (b << 8));\n\n\t\t/* do single-write command */\n\t\ttarget_write_u8(target, ADUC702X_FLASH + ADUC702X_FLASH_FEECON, 0x02);\n\n\t\tif (aduc702x_check_flash_completion(target, 1) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"single write failed for address 0x%08lX\",\n\t\t\t\t(unsigned long)(offset + x));\n\t\t\taduc702x_set_write_enable(target, 0);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t}\n\tLOG_DEBUG(\"wrote %d bytes at address 0x%08lX\", (int)count, (unsigned long)(offset + x));\n\n\taduc702x_set_write_enable(target, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int aduc702x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\t/* try using a block write */\n\tretval = aduc702x_write_block(bank, buffer, offset, count);\n\tif (retval != ERROR_OK) {\n\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t * use normal (slow) JTAG method */\n\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\n\t\t\tretval = aduc702x_write_single(bank, buffer, offset, count);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"slow write failed\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int aduc702x_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\n/* sets FEEMOD bit 3\n * enable = 1 enables writes & erases, 0 disables them */\nstatic int aduc702x_set_write_enable(struct target *target, int enable)\n{\n\t/* don't bother to preserve int enable bit here */\n\ttarget_write_u16(target, ADUC702X_FLASH + ADUC702X_FLASH_FEEMOD, enable ? 8 : 0);\n\n\treturn ERROR_OK;\n}\n\n/* wait up to timeout_ms for controller to not be busy,\n * then check whether the command passed or failed.\n *\n * this function sleeps 1ms between checks (after the first one),\n * so in some cases may slow things down without a usleep after the first read */\nstatic int aduc702x_check_flash_completion(struct target *target, unsigned int timeout_ms)\n{\n\tuint8_t v = 4;\n\n\tint64_t endtime = timeval_ms() + timeout_ms;\n\twhile (1) {\n\t\ttarget_read_u8(target, ADUC702X_FLASH + ADUC702X_FLASH_FEESTA, &v);\n\t\tif ((v & 4) == 0)\n\t\t\tbreak;\n\t\talive_sleep(1);\n\t\tif (timeval_ms() >= endtime)\n\t\t\tbreak;\n\t}\n\n\tif (v & 2)\n\t\treturn ERROR_FAIL;\n\t/* if a command is ignored, both the success and fail bits may be 0 */\n\telse if ((v & 3) == 0)\n\t\treturn ERROR_FAIL;\n\telse\n\t\treturn ERROR_OK;\n}\n\nconst struct flash_driver aduc702x_flash = {\n\t.name = \"aduc702x\",\n\t.flash_bank_command = aduc702x_flash_bank_command,\n\t.erase = aduc702x_erase,\n\t.write = aduc702x_write,\n\t.read = default_flash_read,\n\t.probe = aduc702x_probe,\n\t.auto_probe = aduc702x_probe,\n\t.erase_check = default_flash_blank_check,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/aducm360.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Ivan Buliev                                     *\n *   i.buliev@mikrosistemi.com                                             *\n ***************************************************************************/\n\n/***************************************************************************\n *  This version for ADuCM360 is largely based on the following flash      *\n *  drivers:                                                               *\n *    - aduc702x.c                                                         *\n *          Copyright (C) 2008 by Kevin McGuire                            *\n *          Copyright (C) 2008 by Marcel Wijlaars                          *\n *          Copyright (C) 2009 by Michael Ashton                           *\n *   and                                                                   *\n *    - stm32f1x.c                                                         *\n *          Copyright (C) 2005 by Dominic Rath                             *\n *          Dominic.Rath@gmx.de                                            *\n *                                                                         *\n *          Copyright (C) 2008 by Spencer Oliver                           *\n *          spen@spen-soft.co.uk                                           *\n *                                                                         *\n *          Copyright (C) 2011 by Andreas Fritiofson                       *\n *          andreas.fritiofson@gmail.com                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\nstatic int aducm360_build_sector_list(struct flash_bank *bank);\nstatic int aducm360_check_flash_completion(struct target *target, unsigned int timeout_ms);\nstatic int aducm360_set_write_enable(struct target *target, int enable);\n\n#define ADUCM360_FLASH_BASE             0x40002800\n#define ADUCM360_FLASH_FEESTA           0x0000\n#define ADUCM360_FLASH_FEECON0          0x0004\n#define ADUCM360_FLASH_FEECMD           0x0008\n#define ADUCM360_FLASH_FEEADR0L         0x0010\n#define ADUCM360_FLASH_FEEADR0H         0x0014\n#define ADUCM360_FLASH_FEEADR1L         0x0018\n#define ADUCM360_FLASH_FEEADR1H         0x001C\n#define ADUCM360_FLASH_FEEKEY           0x0020\n#define ADUCM360_FLASH_FEEPROL          0x0028\n#define ADUCM360_FLASH_FEEPROH          0x002C\n#define ADUCM360_FLASH_FEESIGL          0x0030\n#define ADUCM360_FLASH_FEESIGH          0x0034\n#define ADUCM360_FLASH_FEECON1          0x0038\n#define ADUCM360_FLASH_FEEADRAL         0x0048\n#define ADUCM360_FLASH_FEEADRAH         0x004C\n#define ADUCM360_FLASH_FEEAEN0          0x0078\n#define ADUCM360_FLASH_FEEAEN1          0x007C\n#define ADUCM360_FLASH_FEEAEN2          0x0080\n\n/* flash bank aducm360 0 0 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(aducm360_flash_bank_command)\n{\n\tbank->base = 0x00000000;\n\tbank->size = 0x00020000;\n\n\taducm360_build_sector_list(bank);\n\n\treturn ERROR_OK;\n}\n\n#define FLASH_SECTOR_SIZE\t512\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_build_sector_list(struct flash_bank *bank)\n{\n\tuint32_t offset = 0;\n\n\t/* sector size is 512 */\n\tbank->num_sectors = bank->size / FLASH_SECTOR_SIZE;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tfor (unsigned i = 0; i < bank->num_sectors; ++i) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = FLASH_SECTOR_SIZE;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_mass_erase(struct target *target)\n{\n\tuint32_t\t\tvalue;\n\tint\t\t\t\tres = ERROR_OK;\n\n\t/* Clear any old status */\n\ttarget_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value);\n\n\t/* Enable the writing to the flash*/\n\taducm360_set_write_enable(target, 1);\n\n\t/* Unlock for writing */\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F456);\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F123);\n\t/* Issue the 'MASSERASE' command */\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEECMD, 0x00000003);\n\n\t/* Check the result */\n\tres = aducm360_check_flash_completion(target, 3500);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"mass erase failed.\");\n\t\taducm360_set_write_enable(target, 0);\n\t\tres = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn res;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_page_erase(struct target *target, uint32_t padd)\n{\n\tuint32_t\t\tvalue;\n\tint\t\t\t\tres = ERROR_OK;\n\n\t/* Clear any old status */\n\ttarget_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value);\n\n\t/* Enable the writing to the flash*/\n\taducm360_set_write_enable(target, 1);\n\n\t/* Unlock for writing */\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F456);\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEKEY, 0x0000F123);\n\t/* Write the sector address */\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEADR0L, padd & 0xFFFF);\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEEADR0H, (padd>>16) & 0xFFFF);\n\t/* Issue the 'ERASEPAGE' command */\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEECMD, 0x00000001);\n\n\t/* Check the result */\n\tres = aducm360_check_flash_completion(target, 50);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"page erase failed at 0x%08\" PRIx32, padd);\n\t\taducm360_set_write_enable(target, 0);\n\t\tres = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn res;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint             res = ERROR_OK;\n\tint             i;\n\tint             count;\n\tstruct target   *target = bank->target;\n\tuint32_t        padd;\n\n\tif (((first | last) == 0) || ((first == 0) && (last >= bank->num_sectors))) {\n\t\tres = aducm360_mass_erase(target);\n\t} else {\n\t\tcount = last - first + 1;\n\t\tfor (i = 0; i < count; ++i) {\n\t\t\tpadd = bank->base + ((first+i)*FLASH_SECTOR_SIZE);\n\t\t\tres = aducm360_page_erase(target, padd);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn res;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_write_block_sync(\n\t\tstruct flash_bank *bank,\n\t\tconst uint8_t *buffer,\n\t\tuint32_t offset,\n\t\tuint32_t count)\n{\n\tstruct target           *target = bank->target;\n\tuint32_t                target_buffer_size = 8192;\n\tstruct working_area     *helper;\n\tstruct working_area     *target_buffer;\n\tuint32_t                address = bank->base + offset;\n\tstruct reg_param        reg_params[8];\n\tint                     retval = ERROR_OK;\n\tuint32_t                entry_point = 0, exit_point = 0;\n\tuint32_t                res;\n\tstruct armv7m_algorithm armv7m_algo;\n\n\tstatic const uint32_t aducm360_flash_write_code[] = {\n\t\t\t/* helper.code */\n\t\t\t0x88AF4D10, 0x0704F047, 0x682F80AF, 0x600E6806,\n\t\t\t0xF017882F, 0xF43F0F08, 0xF851AFFB, 0x42B77B04,\n\t\t\t0x800DF040, 0x0004F100, 0xF47F3A04, 0x686FAFEF,\n\t\t\t0x0704F027, 0xF04F80AF, 0xF0000400, 0xF04FB802,\n\t\t\t0xBE000480, 0x40002800, 0x00015000, 0x20000000,\n\t\t\t0x00013000\n\t};\n\n\tLOG_DEBUG(\"'aducm360_write_block_sync' requested, dst:0x%08\" PRIx32 \", count:0x%08\" PRIx32 \"bytes.\",\n\t\t\taddress, count);\n\n\t/*  ----- Check the destination area for a Long Word alignment -----  */\n\tif (((count%4) != 0) || ((offset%4) != 0)) {\n\t\tLOG_ERROR(\"write block must be multiple of four bytes in offset & length\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*  ----- Allocate space in the target's RAM for the helper code -----  */\n\tif (target_alloc_working_area(target, sizeof(aducm360_flash_write_code),\n\t\t\t&helper) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/*  ----- Upload the helper code to the space in the target's RAM -----  */\n\tuint8_t code[sizeof(aducm360_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(aducm360_flash_write_code),\n\t\t\taducm360_flash_write_code);\n\tretval = target_write_buffer(target, helper->address, sizeof(code), code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tentry_point = helper->address;\n\n\t/*  ----- Allocate space in the target's RAM for the user application's object code -----  */\n\twhile (target_alloc_working_area_try(target, target_buffer_size, &target_buffer) != ERROR_OK) {\n\t\tLOG_WARNING(\"couldn't allocate a buffer space of 0x%08\" PRIx32 \"bytes in the target's SRAM.\",\n\t\t\t\ttarget_buffer_size);\n\t\ttarget_buffer_size /= 2;\n\t\tif (target_buffer_size <= 256) {\t\t/* No room available */\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\ttarget_free_working_area(target, helper);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\t/* ----- Prepare the target for the helper ----- */\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /*SRC      */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /*DST      */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT); /*COUNT    */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT); /*not used */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN);\t /*RESULT   */\n\n\t/*  ===== Execute the Main Programming Loop! ===== */\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > target_buffer_size) ? target_buffer_size : count;\n\n\t\t/* ----- Upload the chunk ----- */\n\t\tretval = target_write_buffer(target, target_buffer->address, thisrun_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\t/* Set the arguments for the helper */\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, target_buffer->address);\t/*SRC     */\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\t\t\t\t\t/*DST     */\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count);\t\t\t\t/*COUNT   */\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, 0);\t\t\t\t\t\t\t/*NOT USED*/\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 5,\n\t\t\t\treg_params,\tentry_point, exit_point, 10000, &armv7m_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing aducm360 flash write algorithm\");\n\t\t\tbreak;\n\t\t}\n\n\t\tres = buf_get_u32(reg_params[4].value, 0, 32);\n\t\tif (res) {\n\t\t\tLOG_ERROR(\"aducm360 fast sync algorithm reports an error (%02\" PRIX32 \")\", res);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, target_buffer);\n\ttarget_free_working_area(target, helper);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_write_block_async(\n\t\tstruct flash_bank *bank,\n\t\tconst uint8_t *buffer,\n\t\tuint32_t offset,\n\t\tuint32_t count)\n{\n\tstruct target           *target = bank->target;\n\tuint32_t                target_buffer_size = 1024;\n\tstruct working_area     *helper;\n\tstruct working_area     *target_buffer;\n\tuint32_t                address = bank->base + offset;\n\tstruct reg_param        reg_params[9];\n\tint                     retval = ERROR_OK;\n\tuint32_t                entry_point = 0, exit_point = 0;\n\tuint32_t                res;\n\tuint32_t                wcount;\n\tstruct armv7m_algorithm armv7m_algo;\n\n\tstatic const uint32_t aducm360_flash_write_code[] = {\n\t\t\t/* helper.code */\n\t\t\t0x4050F8DF,\t0xF04588A5,\t0x80A50504,\t0x8000F8D0,\n\t\t\t0x0F00F1B8, 0x8016F000,\t0x45476847,\t0xAFF6F43F,\n\t\t\t0x6B04F857, 0x6B04F842,\t0xF0158825,\t0xF43F0F08,\n\t\t\t0x428FAFFB, 0xF100BF28,\t0x60470708,\t0xB10B3B01,\n\t\t\t0xBFE4F7FF, 0xF02588A5,\t0x80A50504,\t0x0900F04F,\n\t\t\t0xBE00BF00, 0x40002800,\t0x20000000,\t0x20000100,\n\t\t\t0x00013000\n\t};\n\n\tLOG_DEBUG(\"'aducm360_write_block_async' requested, dst:0x%08\" PRIx32 \", count:0x%08\" PRIx32 \"bytes.\",\n\t\t\taddress, count);\n\n\t/*  ----- Check the destination area for a Long Word alignment -----  */\n\tif (((count%4) != 0) || ((offset%4) != 0)) {\n\t\tLOG_ERROR(\"write block must be multiple of four bytes in offset & length\");\n\t\treturn ERROR_FAIL;\n\t}\n\twcount = count/4;\n\n\t/*  ----- Allocate space in the target's RAM for the helper code -----  */\n\tif (target_alloc_working_area(target, sizeof(aducm360_flash_write_code),\n\t\t\t&helper) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/*  ----- Upload the helper code to the space in the target's RAM -----  */\n\tuint8_t code[sizeof(aducm360_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(aducm360_flash_write_code),\n\t\t\taducm360_flash_write_code);\n\tretval = target_write_buffer(target, helper->address, sizeof(code), code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tentry_point = helper->address;\n\n\t/*  ----- Allocate space in the target's RAM for the user application's object code ----- */\n\twhile (target_alloc_working_area_try(target, target_buffer_size, &target_buffer) != ERROR_OK) {\n\t\tLOG_WARNING(\"couldn't allocate a buffer space of 0x%08\" PRIx32 \"bytes in the target's SRAM.\",\n\t\t\t\ttarget_buffer_size);\n\t\ttarget_buffer_size /= 2;\n\t\tif (target_buffer_size <= 256) {\t\t/* No room available */\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\ttarget_free_working_area(target, helper);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\t/* ----- Prepare the target for the helper ----- */\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /*SRCBEG     */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /*SRCEND     */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT); /*DST        */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT); /*COUNT (LWs)*/\n\tinit_reg_param(&reg_params[4], \"r9\", 32, PARAM_IN);  /*RESULT     */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, target_buffer->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, target_buffer->address + target_buffer->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, wcount);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, wcount, 4,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\ttarget_buffer->address, target_buffer->size,\n\t\t\tentry_point, exit_point,\n\t\t\t&armv7m_algo);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"error executing aducm360 flash write algorithm\");\n\t} else {\n\t\tres = buf_get_u32(reg_params[4].value, 0, 32);\t/*RESULT*/\n\t\tif (res) {\n\t\t\tLOG_ERROR(\"aducm360 fast async algorithm reports an error (%02\" PRIX32 \")\", res);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, target_buffer);\n\ttarget_free_working_area(target, helper);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\n/* ----------------------------------------------------------------------- */\n/* If this fn returns ERROR_TARGET_RESOURCE_NOT_AVAILABLE, then the caller can fall\n * back to another mechanism that does not require onboard RAM\n *\n * Caller should not check for other return values specifically\n */\nstatic int aducm360_write_block(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tint\tchoice = 0;\n\n\tswitch (choice) {\n\tcase 0:\n\t\treturn aducm360_write_block_sync(bank, buffer, offset, count);\n\tcase 1:\n\t\treturn aducm360_write_block_async(bank, buffer, offset, count);\n\tdefault:\n\t\tLOG_ERROR(\"aducm360_write_block was cancelled (no writing method was chosen)!\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n}\n\n/* ----------------------------------------------------------------------- */\n#define FEESTA_WRDONE\t0x00000008\n\nstatic int aducm360_write_modified(struct flash_bank *bank,\n\t\tconst uint8_t *buffer,\n\t\tuint32_t offset,\n\t\tuint32_t count)\n{\n\tuint32_t\t\tvalue;\n\tint\t\t\t\tres = ERROR_OK;\n\tuint32_t        i, j, a, d;\n\tstruct target   *target = bank->target;\n\n\tLOG_DEBUG(\"performing slow write (offset=0x%08\" PRIx32 \", count=0x%08\" PRIx32 \")...\",\n\t\t\toffset, count);\n\n\t/* Enable the writing to the flash */\n\taducm360_set_write_enable(target, 1);\n\n\t/* Clear any old status */\n\ttarget_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value);\n\n\tfor (i = 0; i < count; i += 4) {\n\t\ta = offset+i;\n\t\tfor (j = 0; i < 4; i += 1)\n\t\t\t*((uint8_t *)(&d) + j) = buffer[i+j];\n\t\ttarget_write_u32(target, a, d);\n\t\tdo {\n\t\t\ttarget_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEESTA, &value);\n\t\t} while (!(value & FEESTA_WRDONE));\n\t}\n\taducm360_set_write_enable(target, 0);\n\n\treturn res;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\t/* try using a block write */\n\tretval = aducm360_write_block(bank, buffer, offset, count);\n\tif (retval != ERROR_OK) {\n\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t * use normal (slow) JTAG method */\n\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\n\t\t\tretval = aducm360_write_modified(bank, buffer, offset, count);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"slow write failed\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t}\n\treturn retval;\n}\n\n/* ----------------------------------------------------------------------- */\nstatic int aducm360_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\n/* ----------------------------------------------------------------------- */\n/* sets FEECON0 bit 2\n * enable = 1 enables writes & erases, 0 disables them */\nstatic int aducm360_set_write_enable(struct target *target, int enable)\n{\n\t/* don't bother to preserve int enable bit here */\n\tuint32_t\tvalue;\n\n\ttarget_read_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEECON0, &value);\n\tif (enable)\n\t\tvalue |= 0x00000004;\n\telse\n\t\tvalue &= ~0x00000004;\n\ttarget_write_u32(target, ADUCM360_FLASH_BASE + ADUCM360_FLASH_FEECON0, value);\n\n\treturn ERROR_OK;\n}\n\n/* ----------------------------------------------------------------------- */\n/* wait up to timeout_ms for controller to not be busy,\n * then check whether the command passed or failed.\n *\n * this function sleeps 1ms between checks (after the first one),\n * so in some cases may slow things down without a usleep after the first read */\nstatic int aducm360_check_flash_completion(struct target *target, unsigned int timeout_ms)\n{\n\tuint32_t v = 1;\n\n\tint64_t endtime = timeval_ms() + timeout_ms;\n\twhile (1) {\n\t\ttarget_read_u32(target, ADUCM360_FLASH_BASE+ADUCM360_FLASH_FEESTA, &v);\n\t\tif ((v & 0x00000001) == 0)\n\t\t\tbreak;\n\t\talive_sleep(1);\n\t\tif (timeval_ms() >= endtime)\n\t\t\tbreak;\n\t}\n\n\tif (!(v & 0x00000004))\t/* b2 */\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n/* ----------------------------------------------------------------------- */\nconst struct flash_driver aducm360_flash = {\n\t.name = \"aducm360\",\n\t.flash_bank_command = aducm360_flash_bank_command,\n\t.erase = aducm360_erase,\n\t.write = aducm360_write,\n\t.read = default_flash_read,\n\t.probe = aducm360_probe,\n\t.auto_probe = aducm360_probe,\n\t.erase_check = default_flash_blank_check,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/ambiqmicro.c",
    "content": "// SPDX-License-Identifier: BSD-3-Clause\n\n/******************************************************************************\n *\n * @file ambiqmicro.c\n *\n * @brief Ambiq Micro flash driver.\n *\n *****************************************************************************/\n\n/******************************************************************************\n * Copyright (c) 2015, David Racine <dracine at ambiqmicro.com>\n *\n * Copyright (c) 2016, Rick Foos <rfoos at solengtech.com>\n *\n * Copyright (c) 2015-2016, Ambiq Micro, Inc.\n *\n * All rights reserved.\n *****************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"imp.h\"\n#include \"target/algorithm.h\"\n#include \"target/armv7m.h\"\n#include \"target/cortex_m.h\"\n\n/** Check error, log error. */\n#define CHECK_STATUS(rc, msg) {\t\\\n\t\tif (rc != ERROR_OK) { \\\n\t\t\tLOG_ERROR(\"status(%d):%s\\n\", rc, msg); } }\n\n/*\n * Address and Key defines.\n */\n#define PROGRAM_KEY      (0x12344321)\n#define OTP_PROGRAM_KEY  (0x87655678)\n\n#define FLASH_PROGRAM_MAIN_FROM_SRAM                0x0800005d\n#define FLASH_PROGRAM_OTP_FROM_SRAM                 0x08000061\n#define FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM       0x08000065\n#define FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM       0x08000069\n\n\nstatic const uint32_t apollo_flash_size[] = {\n\t1 << 15,\n\t1 << 16,\n\t1 << 17,\n\t1 << 18,\n\t1 << 19,\n\t1 << 20,\n\t1 << 21\n};\n\nstatic const uint32_t apollo_sram_size[] = {\n\t1 << 15,\n\t1 << 16,\n\t1 << 17,\n\t1 << 18,\n\t1 << 19,\n\t1 << 20,\n\t1 << 21\n};\n\nstruct ambiqmicro_flash_bank {\n\t/* chip id register */\n\n\tbool probed;\n\n\tconst char *target_name;\n\tuint8_t target_class;\n\n\tuint32_t sramsiz;\n\tuint32_t flshsiz;\n\n\t/* flash geometry */\n\tuint32_t num_pages;\n\tuint32_t pagesize;\n\tuint32_t pages_in_lockregion;\n\n\t/* nv memory bits */\n\tuint16_t num_lockbits;\n\n\t/* main clock status */\n\tuint32_t rcc;\n\tuint32_t rcc2;\n\tuint8_t mck_valid;\n\tuint8_t xtal_mask;\n\tuint32_t iosc_freq;\n\tuint32_t mck_freq;\n\tconst char *iosc_desc;\n\tconst char *mck_desc;\n};\n\nstatic struct {\n\tuint8_t class;\n\tuint8_t partno;\n\tconst char *partname;\n} ambiqmicro_parts[6] = {\n\t{0xFF, 0x00, \"Unknown\"},\n\t{0x01, 0x00, \"Apollo\"},\n\t{0x02, 0x00, \"Apollo2\"},\n\t{0x03, 0x00, \"Unknown\"},\n\t{0x04, 0x00, \"Unknown\"},\n\t{0x05, 0x00, \"Apollo\"},\n};\n\nstatic char *ambiqmicro_classname[6] = {\n\t\"Unknown\", \"Apollo\", \"Apollo2\", \"Unknown\", \"Unknown\", \"Apollo\"\n};\n\n/***************************************************************************\n*\topenocd command interface                                              *\n***************************************************************************/\n\n/* flash_bank ambiqmicro <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(ambiqmicro_flash_bank_command)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tambiqmicro_info = calloc(sizeof(struct ambiqmicro_flash_bank), 1);\n\n\tbank->driver_priv = ambiqmicro_info;\n\n\tambiqmicro_info->target_name = \"Unknown target\";\n\n\t/* part wasn't probed yet */\n\tambiqmicro_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int get_ambiqmicro_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;\n\tchar *classname;\n\n\tif (!ambiqmicro_info->probed) {\n\t\tLOG_ERROR(\"Target not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Check class name in range. */\n\tif (ambiqmicro_info->target_class < sizeof(ambiqmicro_classname))\n\t\tclassname = ambiqmicro_classname[ambiqmicro_info->target_class];\n\telse\n\t\tclassname = ambiqmicro_classname[0];\n\n\tcommand_print_sameline(cmd, \"\\nAmbiq Micro information: Chip is \"\n\t\t\"class %d (%s) %s\\n\",\n\t\tambiqmicro_info->target_class,\n\t\tclassname,\n\t\tambiqmicro_info->target_name);\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************\n*\tchip identification and status                                         *\n***************************************************************************/\n\n/* Fill in driver info structure */\nstatic int ambiqmicro_read_part_info(struct flash_bank *bank)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t part_num = 0;\n\tint retval;\n\n\t/*\n\t * Read Part Number.\n\t */\n\tretval = target_read_u32(target, 0x40020000, &part_num);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"status(0x%x):Could not read part_num.\\n\", retval);\n\t\t/* Set part_num to default device */\n\t\tpart_num = 0;\n\t}\n\tLOG_DEBUG(\"Part number: 0x%\" PRIx32, part_num);\n\n\t/*\n\t * Determine device class.\n\t */\n\tambiqmicro_info->target_class = (part_num & 0xFF000000) >> 24;\n\n\tswitch (ambiqmicro_info->target_class) {\n\t\tcase 1:\t\t/* 1 - Apollo */\n\t\tcase 5:\t\t/* 5 - Apollo Bootloader */\n\t\t\tbank->base = bank->bank_number * 0x40000;\n\t\t\tambiqmicro_info->pagesize = 2048;\n\t\t\tambiqmicro_info->flshsiz =\n\t\t\tapollo_flash_size[(part_num & 0x00F00000) >> 20];\n\t\t\tambiqmicro_info->sramsiz =\n\t\t\tapollo_sram_size[(part_num & 0x000F0000) >> 16];\n\t\t\tambiqmicro_info->num_pages = ambiqmicro_info->flshsiz /\n\t\t\tambiqmicro_info->pagesize;\n\t\t\tif (ambiqmicro_info->num_pages > 128) {\n\t\t\t\tambiqmicro_info->num_pages = 128;\n\t\t\t\tambiqmicro_info->flshsiz = 1024 * 256;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_INFO(\"Unknown Class. Using Apollo-64 as default.\");\n\n\t\t\tbank->base = bank->bank_number * 0x40000;\n\t\t\tambiqmicro_info->pagesize = 2048;\n\t\t\tambiqmicro_info->flshsiz = apollo_flash_size[1];\n\t\t\tambiqmicro_info->sramsiz = apollo_sram_size[0];\n\t\t\tambiqmicro_info->num_pages = ambiqmicro_info->flshsiz /\n\t\t\tambiqmicro_info->pagesize;\n\t\t\tif (ambiqmicro_info->num_pages > 128) {\n\t\t\t\tambiqmicro_info->num_pages = 128;\n\t\t\t\tambiqmicro_info->flshsiz = 1024 * 256;\n\t\t\t}\n\t\t\tbreak;\n\n\t}\n\n\tif (ambiqmicro_info->target_class < ARRAY_SIZE(ambiqmicro_parts))\n\t\tambiqmicro_info->target_name =\n\t\t\tambiqmicro_parts[ambiqmicro_info->target_class].partname;\n\telse\n\t\tambiqmicro_info->target_name =\n\t\t\tambiqmicro_parts[0].partname;\n\n\tLOG_DEBUG(\"num_pages: %\" PRIu32 \", pagesize: %\" PRIu32 \", flash: %\" PRIu32 \", sram: %\" PRIu32,\n\t\tambiqmicro_info->num_pages,\n\t\tambiqmicro_info->pagesize,\n\t\tambiqmicro_info->flshsiz,\n\t\tambiqmicro_info->sramsiz);\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************\n*\tflash operations                                                       *\n***************************************************************************/\n\nstatic int ambiqmicro_protect_check(struct flash_bank *bank)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro = bank->driver_priv;\n\tint status = ERROR_OK;\n\tuint32_t i;\n\n\n\tif (!ambiqmicro->probed) {\n\t\tLOG_ERROR(\"Target not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (i = 0; i < (unsigned) bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = -1;\n\n\treturn status;\n}\n/** Read flash status from bootloader. */\nstatic int check_flash_status(struct target *target, uint32_t address)\n{\n\tuint32_t retflash;\n\tint rc;\n\trc = target_read_u32(target, address, &retflash);\n\t/* target connection failed. */\n\tif (rc != ERROR_OK) {\n\t\tLOG_DEBUG(\"%s:%d:%s(): status(0x%x)\\n\",\n\t\t\t__FILE__, __LINE__, __func__, rc);\n\t\treturn rc;\n\t}\n\t/* target flash failed, unknown cause. */\n\tif (retflash != 0) {\n\t\tLOG_ERROR(\"Flash not happy: status(0x%\" PRIx32 \")\", retflash);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ambiqmicro_exec_command(struct target *target,\n\tuint32_t command,\n\tuint32_t flash_return_address)\n{\n\tint retval, retflash;\n\n\tretval = target_resume(\n\t\ttarget,\n\t\tfalse,\n\t\tcommand,\n\t\ttrue,\n\t\ttrue);\n\n\tCHECK_STATUS(retval, \"error executing ambiqmicro command\");\n\n\t/*\n\t * Wait for halt.\n\t */\n\tfor (;; ) {\n\t\ttarget_poll(target);\n\t\tif (target->state == TARGET_HALTED)\n\t\t\tbreak;\n\t\telse if (target->state == TARGET_RUNNING ||\n\t\t\ttarget->state == TARGET_DEBUG_RUNNING) {\n\t\t\t/*\n\t\t\t * Keep polling until target halts.\n\t\t\t */\n\t\t\ttarget_poll(target);\n\t\t\talive_sleep(100);\n\t\t\tLOG_DEBUG(\"state = %d\", target->state);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Target not halted or running %d\", target->state);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/*\n\t * Read return value, flash error takes precedence.\n\t */\n\tretflash = check_flash_status(target, flash_return_address);\n\tif (retflash != ERROR_OK)\n\t\tretval = retflash;\n\n\t/* Return code from target_resume OR flash. */\n\treturn retval;\n}\n\nstatic int ambiqmicro_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = NULL;\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = NULL;\n\tint retval = ERROR_OK;\n\n\tambiqmicro_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!ambiqmicro_info->probed) {\n\t\tLOG_ERROR(\"Target not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/*\n\t * Clear Bootloader bit.\n\t */\n\tretval = target_write_u32(target, 0x400201a0, 0x0);\n\tCHECK_STATUS(retval, \"error clearing bootloader bit.\");\n\n\t/*\n\t * Set up the SRAM.\n\t */\n\n\t/*\n\t * Bank.\n\t */\n\tretval = target_write_u32(target, 0x10000000, bank->bank_number);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Write Key.\n\t */\n\tretval = target_write_u32(target, 0x10000004, PROGRAM_KEY);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Breakpoint.\n\t */\n\tretval = target_write_u32(target, 0x10000008, 0xfffffffe);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Erase the main array.\n\t */\n\tLOG_INFO(\"Mass erase on bank %d.\", bank->bank_number);\n\n\t/*\n\t * passed pc, addr = ROM function, handle breakpoints, not debugging.\n\t */\n\tretval = ambiqmicro_exec_command(target, FLASH_MASS_ERASE_MAIN_PAGES_FROM_SRAM, 0x10000008);\n\tCHECK_STATUS(retval, \"error executing ambiqmicro flash mass erase.\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * Set Bootloader bit, regardless of command execution.\n\t */\n\tretval = target_write_u32(target, 0x400201a0, 0x1);\n\tCHECK_STATUS(retval, \"error setting bootloader bit.\");\n\n\treturn retval;\n}\n\n\nstatic int ambiqmicro_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!ambiqmicro_info->probed) {\n\t\tLOG_ERROR(\"Target not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/*\n\t * Check pages.\n\t * Fix num_pages for the device.\n\t */\n\tif ((last < first) || (last >= ambiqmicro_info->num_pages))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\t/*\n\t * Just Mass Erase if all pages are given.\n\t * TODO: Fix num_pages for the device\n\t */\n\tif ((first == 0) && (last == (ambiqmicro_info->num_pages - 1)))\n\t\treturn ambiqmicro_mass_erase(bank);\n\n\t/*\n\t * Clear Bootloader bit.\n\t */\n\tretval = target_write_u32(target, 0x400201a0, 0x0);\n\tCHECK_STATUS(retval, \"error clearing bootloader bit.\");\n\n\t/*\n\t * Set up the SRAM.\n\t */\n\n\t/*\n\t * Bank.\n\t */\n\tretval = target_write_u32(target, 0x10000000, bank->bank_number);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Number of pages to erase.\n\t */\n\tretval = target_write_u32(target, 0x10000004, 1 + (last-first));\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Write Key.\n\t */\n\tretval = target_write_u32(target, 0x10000008, PROGRAM_KEY);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Breakpoint.\n\t */\n\tretval = target_write_u32(target, 0x1000000c, 0xfffffffe);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t/*\n\t * Pointer to flash address.\n\t */\n\tretval = target_write_u32(target, 0x10000010, first);\n\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * Erase the pages.\n\t */\n\tLOG_INFO(\"Erasing pages %u to %u on bank %u\", first, last, bank->bank_number);\n\n\t/*\n\t * passed pc, addr = ROM function, handle breakpoints, not debugging.\n\t */\n\tretval = ambiqmicro_exec_command(target, FLASH_ERASE_LIST_MAIN_PAGES_FROM_SRAM, 0x1000000C);\n\tCHECK_STATUS(retval, \"error executing flash page erase\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"%u pages erased!\", 1+(last-first));\n\n\tif (first == 0) {\n\t\t/*\n\t\t * Set Bootloader bit.\n\t\t */\n\t\tretval = target_write_u32(target, 0x400201a0, 0x1);\n\t\tCHECK_STATUS(retval, \"error setting bootloader bit.\");\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int ambiqmicro_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\t/* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;\n\t * struct target *target = bank->target; */\n\n\t/*\n\t * TODO\n\t */\n\tLOG_INFO(\"Not yet implemented\");\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ambiqmicro_write_block(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\t/* struct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv; */\n\tstruct target *target = bank->target;\n\tuint32_t address = bank->base + offset;\n\tuint32_t buffer_pointer = 0x10000010;\n\tuint32_t maxbuffer;\n\tuint32_t thisrun_count;\n\tint retval = ERROR_OK;\n\n\tif (((count%4) != 0) || ((offset%4) != 0)) {\n\t\tLOG_ERROR(\"write block must be multiple of 4 bytes in offset & length\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * Max buffer size for this device.\n\t * Hard code 6kB for the buffer.\n\t */\n\tmaxbuffer = 0x1800;\n\n\tLOG_INFO(\"Flashing main array\");\n\n\twhile (count > 0) {\n\t\tif (count > maxbuffer)\n\t\t\tthisrun_count = maxbuffer;\n\t\telse\n\t\t\tthisrun_count = count;\n\n\t\t/*\n\t\t * Set up the SRAM.\n\t\t */\n\n\t\t/*\n\t\t * Pointer to flash.\n\t\t */\n\t\tretval = target_write_u32(target, 0x10000000, address);\n\t\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t\t/*\n\t\t * Number of 32-bit words to program.\n\t\t */\n\t\tretval = target_write_u32(target, 0x10000004, thisrun_count/4);\n\t\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t\t/*\n\t\t * Write Key.\n\t\t */\n\t\tretval = target_write_u32(target, 0x10000008, PROGRAM_KEY);\n\t\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t\t/*\n\t\t * Breakpoint.\n\t\t */\n\t\tretval = target_write_u32(target, 0x1000000c, 0xfffffffe);\n\t\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\n\t\t/*\n\t\t * Write Buffer.\n\t\t */\n\t\tretval = target_write_buffer(target, buffer_pointer, thisrun_count, buffer);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tCHECK_STATUS(retval, \"error writing target SRAM parameters.\");\n\t\t\tbreak;\n\t\t}\n\n\t\tLOG_DEBUG(\"address = 0x%08\" PRIx32, address);\n\n\t\tretval = ambiqmicro_exec_command(target, FLASH_PROGRAM_MAIN_FROM_SRAM, 0x1000000c);\n\t\tCHECK_STATUS(retval, \"error executing ambiqmicro flash write algorithm\");\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\t}\n\n\n\tLOG_INFO(\"Main array flashed\");\n\n\t/*\n\t * Clear Bootloader bit.\n\t */\n\tretval = target_write_u32(target, 0x400201a0, 0x0);\n\tCHECK_STATUS(retval, \"error clearing bootloader bit\");\n\n\treturn retval;\n}\n\nstatic int ambiqmicro_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\t/* try using a block write */\n\tretval = ambiqmicro_write_block(bank, buffer, offset, count);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"write failed\");\n\n\treturn retval;\n}\n\nstatic int ambiqmicro_probe(struct flash_bank *bank)\n{\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = bank->driver_priv;\n\tint retval;\n\n\t/* If this is a ambiqmicro chip, it has flash; probe() is just\n\t * to figure out how much is present.  Only do it once.\n\t */\n\tif (ambiqmicro_info->probed) {\n\t\tLOG_INFO(\"Target already probed\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* ambiqmicro_read_part_info() already handled error checking and\n\t * reporting.  Note that it doesn't write, so we don't care about\n\t * whether the target is halted or not.\n\t */\n\tretval = ambiqmicro_read_part_info(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfree(bank->sectors);\n\n\t/* provide this for the benefit of the NOR flash framework */\n\tbank->size = ambiqmicro_info->pagesize * ambiqmicro_info->num_pages;\n\tbank->num_sectors = ambiqmicro_info->num_pages;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * ambiqmicro_info->pagesize;\n\t\tbank->sectors[i].size = ambiqmicro_info->pagesize;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\t/*\n\t * Part has been probed.\n\t */\n\tambiqmicro_info->probed = true;\n\n\treturn retval;\n}\n\nstatic int ambiqmicro_otp_program(struct flash_bank *bank,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = NULL;\n\tstruct ambiqmicro_flash_bank *ambiqmicro_info = NULL;\n\tint retval;\n\n\tambiqmicro_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!ambiqmicro_info->probed) {\n\t\tLOG_ERROR(\"Target not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (count > 256) {\n\t\tLOG_ERROR(\"Count must be < 256\");\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/*\n\t * Clear Bootloader bit.\n\t */\n\tretval = target_write_u32(target, 0x400201a0, 0x0);\n\tCHECK_STATUS(retval, \"error clearing bootloader bit.\");\n\n\t/*\n\t * Set up the SRAM.\n\t */\n\n\t/*\n\t * Bank.\n\t */\n\tretval = target_write_u32(target, 0x10000000, offset);\n\tCHECK_STATUS(retval, \"error setting target SRAM parameters.\");\n\n\t/*\n\t * Num of words to program.\n\t */\n\tretval = target_write_u32(target, 0x10000004, count);\n\tCHECK_STATUS(retval, \"error setting target SRAM parameters.\");\n\n\t/*\n\t * Write Key.\n\t */\n\tretval = target_write_u32(target, 0x10000008, OTP_PROGRAM_KEY);\n\tCHECK_STATUS(retval, \"error setting target SRAM parameters.\");\n\n\t/*\n\t * Breakpoint.\n\t */\n\tretval = target_write_u32(target, 0x1000000c, 0xfffffffe);\n\tCHECK_STATUS(retval, \"error setting target SRAM parameters.\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * Program OTP.\n\t */\n\tLOG_INFO(\"Programming OTP offset 0x%08\" PRIx32, offset);\n\n\t/*\n\t * passed pc, addr = ROM function, handle breakpoints, not debugging.\n\t */\n\tretval = ambiqmicro_exec_command(target, FLASH_PROGRAM_OTP_FROM_SRAM, 0x1000000C);\n\tCHECK_STATUS(retval, \"error executing ambiqmicro otp program algorithm\");\n\n\tLOG_INFO(\"Programming OTP finished.\");\n\n\treturn retval;\n}\n\n\n\nCOMMAND_HANDLER(ambiqmicro_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ambiqmicro_mass_erase(bank) == ERROR_OK)\n\t\tcommand_print(CMD, \"ambiqmicro mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"ambiqmicro mass erase failed\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ambiqmicro_handle_page_erase_command)\n{\n\tstruct flash_bank *bank;\n\tuint32_t first, last;\n\tint retval;\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ambiqmicro_erase(bank, first, last) == ERROR_OK)\n\t\tcommand_print(CMD, \"ambiqmicro page erase complete\");\n\telse\n\t\tcommand_print(CMD, \"ambiqmicro page erase failed\");\n\n\treturn ERROR_OK;\n}\n\n\n/**\n * Program the otp block.\n */\nCOMMAND_HANDLER(ambiqmicro_handle_program_otp_command)\n{\n\tstruct flash_bank *bank;\n\tuint32_t offset, count;\n\tint retval;\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], offset);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);\n\n\tcommand_print(CMD, \"offset=0x%08\" PRIx32 \" count=%\" PRIu32, offset, count);\n\n\tCALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\n\tretval = ambiqmicro_otp_program(bank, offset, count);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error check log\");\n\n\treturn ERROR_OK;\n}\n\n\n\nstatic const struct command_registration ambiqmicro_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = ambiqmicro_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase entire device\",\n\t},\n\t{\n\t\t.name = \"page_erase\",\n\t\t.usage = \"<bank> <first> <last>\",\n\t\t.handler = ambiqmicro_handle_page_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase device pages\",\n\t},\n\t{\n\t\t.name = \"program_otp\",\n\t\t.handler = ambiqmicro_handle_program_otp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"<bank> <offset> <count>\",\n\t\t.help =\n\t\t\t\"Program OTP (assumes you have already written array starting at 0x10000010)\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration ambiqmicro_command_handlers[] = {\n\t{\n\t\t.name = \"ambiqmicro\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"ambiqmicro flash command group\",\n\t\t.usage = \"Support for Ambiq Micro parts.\",\n\t\t.chain = ambiqmicro_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver ambiqmicro_flash = {\n\t.name = \"ambiqmicro\",\n\t.commands = ambiqmicro_command_handlers,\n\t.flash_bank_command = ambiqmicro_flash_bank_command,\n\t.erase = ambiqmicro_erase,\n\t.protect = ambiqmicro_protect,\n\t.write = ambiqmicro_write,\n\t.read = default_flash_read,\n\t.probe = ambiqmicro_probe,\n\t.auto_probe = ambiqmicro_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = ambiqmicro_protect_check,\n\t.info = get_ambiqmicro_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/at91sam3.c",
    "content": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)\n\n/*\n * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>\n *\n * at91sam3s* support\n * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>\n * Copyright (C) 2011 by Olivier Schonken and Jim Norris\n *\n * Some of the lower level code was based on code supplied by\n * ATMEL under BSD-Source-Code License and this copyright.\n * ATMEL Microcontroller Software Support\n * Copyright (c) 2009, Atmel Corporation. All rights reserved.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/time_support.h>\n\n#define REG_NAME_WIDTH  (12)\n\n/* at91sam3u series (has one or two flash banks) */\n#define FLASH_BANK0_BASE_U   0x00080000\n#define FLASH_BANK1_BASE_U   0x00100000\n\n/* at91sam3s series (has always one flash bank) */\n#define FLASH_BANK_BASE_S   0x00400000\n\n/* at91sam3sd series (has always two flash banks) */\n#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S\n#define FLASH_BANK1_BASE_512K_SD (FLASH_BANK0_BASE_SD+(512*1024/2))\n\n\n/* at91sam3n series (has always one flash bank) */\n#define FLASH_BANK_BASE_N   0x00400000\n\n/* at91sam3a/x series has two flash banks*/\n#define\tFLASH_BANK0_BASE_AX\t\t\t0x00080000\n/*Bank 1 of the at91sam3a/x series starts at 0x00080000 + half flash size*/\n#define\tFLASH_BANK1_BASE_256K_AX\t0x000A0000\n#define\tFLASH_BANK1_BASE_512K_AX\t0x000C0000\n\n#define         AT91C_EFC_FCMD_GETD                 (0x0)\t/* (EFC) Get Flash Descriptor */\n#define         AT91C_EFC_FCMD_WP                   (0x1)\t/* (EFC) Write Page */\n#define         AT91C_EFC_FCMD_WPL                  (0x2)\t/* (EFC) Write Page and Lock */\n#define         AT91C_EFC_FCMD_EWP                  (0x3)\t/* (EFC) Erase Page and Write Page */\n#define         AT91C_EFC_FCMD_EWPL                 (0x4)\t/* (EFC) Erase Page and Write Page then Lock */\n#define         AT91C_EFC_FCMD_EA                   (0x5)\t/* (EFC) Erase All */\n/* cmd6 is not present in the at91sam3u4/2/1 data sheet table 17-2 */\n/* #define      AT91C_EFC_FCMD_EPL                  (0x6) // (EFC) Erase plane? */\n/* cmd7 is not present in the at91sam3u4/2/1 data sheet table 17-2 */\n/* #define      AT91C_EFC_FCMD_EPA                  (0x7) // (EFC) Erase pages? */\n#define         AT91C_EFC_FCMD_SLB                  (0x8)\t/* (EFC) Set Lock Bit */\n#define         AT91C_EFC_FCMD_CLB                  (0x9)\t/* (EFC) Clear Lock Bit */\n#define         AT91C_EFC_FCMD_GLB                  (0xA)\t/* (EFC) Get Lock Bit */\n#define         AT91C_EFC_FCMD_SFB                  (0xB)\t/* (EFC) Set Fuse Bit */\n#define         AT91C_EFC_FCMD_CFB                  (0xC)\t/* (EFC) Clear Fuse Bit */\n#define         AT91C_EFC_FCMD_GFB                  (0xD)\t/* (EFC) Get Fuse Bit */\n#define         AT91C_EFC_FCMD_STUI                 (0xE)\t/* (EFC) Start Read Unique ID */\n#define         AT91C_EFC_FCMD_SPUI                 (0xF)\t/* (EFC) Stop Read Unique ID */\n\n#define  OFFSET_EFC_FMR   0\n#define  OFFSET_EFC_FCR   4\n#define  OFFSET_EFC_FSR   8\n#define  OFFSET_EFC_FRR   12\n\nstatic float _tomhz(uint32_t freq_hz)\n{\n\tfloat f;\n\n\tf = ((float)(freq_hz)) / 1000000.0;\n\treturn f;\n}\n\n/* How the chip is configured. */\nstruct sam3_cfg {\n\tuint32_t unique_id[4];\n\n\tuint32_t slow_freq;\n\tuint32_t rc_freq;\n\tuint32_t mainosc_freq;\n\tuint32_t plla_freq;\n\tuint32_t mclk_freq;\n\tuint32_t cpu_freq;\n\tuint32_t fclk_freq;\n\tuint32_t pclk0_freq;\n\tuint32_t pclk1_freq;\n\tuint32_t pclk2_freq;\n\n\n#define SAM3_CHIPID_CIDR          (0x400E0740)\n\tuint32_t CHIPID_CIDR;\n#define SAM3_CHIPID_CIDR2         (0x400E0940) /*SAM3X and SAM3A cidr at this address*/\n\tuint32_t CHIPID_CIDR2;\n#define SAM3_CHIPID_EXID          (0x400E0744)\n\tuint32_t CHIPID_EXID;\n#define SAM3_CHIPID_EXID2         (0x400E0944) /*SAM3X and SAM3A cidr at this address*/\n\tuint32_t CHIPID_EXID2;\n\n\n#define SAM3_PMC_BASE             (0x400E0400)\n#define SAM3_PMC_SCSR             (SAM3_PMC_BASE + 0x0008)\n\tuint32_t PMC_SCSR;\n#define SAM3_PMC_PCSR             (SAM3_PMC_BASE + 0x0018)\n\tuint32_t PMC_PCSR;\n#define SAM3_CKGR_UCKR            (SAM3_PMC_BASE + 0x001c)\n\tuint32_t CKGR_UCKR;\n#define SAM3_CKGR_MOR             (SAM3_PMC_BASE + 0x0020)\n\tuint32_t CKGR_MOR;\n#define SAM3_CKGR_MCFR            (SAM3_PMC_BASE + 0x0024)\n\tuint32_t CKGR_MCFR;\n#define SAM3_CKGR_PLLAR           (SAM3_PMC_BASE + 0x0028)\n\tuint32_t CKGR_PLLAR;\n#define SAM3_PMC_MCKR             (SAM3_PMC_BASE + 0x0030)\n\tuint32_t PMC_MCKR;\n#define SAM3_PMC_PCK0             (SAM3_PMC_BASE + 0x0040)\n\tuint32_t PMC_PCK0;\n#define SAM3_PMC_PCK1             (SAM3_PMC_BASE + 0x0044)\n\tuint32_t PMC_PCK1;\n#define SAM3_PMC_PCK2             (SAM3_PMC_BASE + 0x0048)\n\tuint32_t PMC_PCK2;\n#define SAM3_PMC_SR               (SAM3_PMC_BASE + 0x0068)\n\tuint32_t PMC_SR;\n#define SAM3_PMC_IMR              (SAM3_PMC_BASE + 0x006c)\n\tuint32_t PMC_IMR;\n#define SAM3_PMC_FSMR             (SAM3_PMC_BASE + 0x0070)\n\tuint32_t PMC_FSMR;\n#define SAM3_PMC_FSPR             (SAM3_PMC_BASE + 0x0074)\n\tuint32_t PMC_FSPR;\n};\n\n/*\n * The AT91SAM3N data sheet 04-Oct-2010, AT91SAM3U data sheet 22-Aug-2011\n * and AT91SAM3S data sheet 09-Feb-2011 state that for flash writes\n * the flash wait state (FWS) should be set to 6. It seems like that the\n * cause of the problem is not the flash itself, but the flash write\n * buffer. Ie the wait states have to be set before writing into the\n * buffer.\n * Tested and confirmed with SAM3N and SAM3U\n */\n\nstruct sam3_bank_private {\n\tbool probed;\n\t/* DANGER: THERE ARE DRAGONS HERE.. */\n\t/* NOTE: If you add more 'ghost' pointers */\n\t/* be aware that you must *manually* update */\n\t/* these pointers in the function sam3_get_details() */\n\t/* See the comment \"Here there be dragons\" */\n\n\t/* so we can find the chip we belong to */\n\tstruct sam3_chip *chip;\n\t/* so we can find the original bank pointer */\n\tstruct flash_bank *bank;\n\tunsigned bank_number;\n\tuint32_t controller_address;\n\tuint32_t base_address;\n\tuint32_t flash_wait_states;\n\tbool present;\n\tunsigned size_bytes;\n\tunsigned nsectors;\n\tunsigned sector_size;\n\tunsigned page_size;\n};\n\nstruct sam3_chip_details {\n\t/* THERE ARE DRAGONS HERE.. */\n\t/* note: If you add pointers here */\n\t/* be careful about them as they */\n\t/* may need to be updated inside */\n\t/* the function: \"sam3_get_details() */\n\t/* which copy/overwrites the */\n\t/* 'runtime' copy of this structure */\n\tuint32_t chipid_cidr;\n\tconst char *name;\n\n\tunsigned n_gpnvms;\n#define SAM3_N_NVM_BITS 3\n\tunsigned gpnvm[SAM3_N_NVM_BITS];\n\tunsigned total_flash_size;\n\tunsigned total_sram_size;\n\tunsigned n_banks;\n#define SAM3_MAX_FLASH_BANKS 2\n\t/* these are \"initialized\" from the global const data */\n\tstruct sam3_bank_private bank[SAM3_MAX_FLASH_BANKS];\n};\n\nstruct sam3_chip {\n\tstruct sam3_chip *next;\n\tbool probed;\n\n\t/* this is \"initialized\" from the global const structure */\n\tstruct sam3_chip_details details;\n\tstruct target *target;\n\tstruct sam3_cfg cfg;\n};\n\n\nstruct sam3_reg_list {\n\tuint32_t address;  size_t struct_offset; const char *name;\n\tvoid (*explain_func)(struct sam3_chip *chip);\n};\n\nstatic struct sam3_chip *all_sam3_chips;\n\nstatic struct sam3_chip *get_current_sam3(struct command_invocation *cmd)\n{\n\tstruct target *t;\n\tstatic struct sam3_chip *p;\n\n\tt = get_current_target(cmd->ctx);\n\tif (!t) {\n\t\tcommand_print_sameline(cmd, \"No current target?\\n\");\n\t\treturn NULL;\n\t}\n\n\tp = all_sam3_chips;\n\tif (!p) {\n\t\t/* this should not happen */\n\t\t/* the command is not registered until the chip is created? */\n\t\tcommand_print_sameline(cmd, \"No SAM3 chips exist?\\n\");\n\t\treturn NULL;\n\t}\n\n\twhile (p) {\n\t\tif (p->target == t)\n\t\t\treturn p;\n\t\tp = p->next;\n\t}\n\tcommand_print_sameline(cmd, \"Cannot find SAM3 chip?\\n\");\n\treturn NULL;\n}\n\n/* these are used to *initialize* the \"chip->details\" structure. */\nstatic const struct sam3_chip_details all_sam3_details[] = {\n\t/* Start at91sam3u* series */\n\t{\n\t\t.chipid_cidr    = 0x28100960,\n\t\t.name           = \"at91sam3u4e\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 52 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_U,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x281a0760,\n\t\t.name           = \"at91sam3u2e\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 36 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t  .bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28190560,\n\t\t.name           = \"at91sam3u1e\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 20 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x28000960,\n\t\t.name           = \"at91sam3u4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 52 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n\t\t{\n\t\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_U,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x280a0760,\n\t\t.name           = \"at91sam3u2c\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 36 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28090560,\n\t\t.name           = \"at91sam3u1c\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 20 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_U,\n\t\t\t\t.controller_address = 0x400e0800,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\n\t/* Start at91sam3s* series */\n\n\t/* Note: The preliminary at91sam3s datasheet says on page 302 */\n\t/* that the flash controller is at address 0x400E0800. */\n\t/* This is _not_ the case, the controller resides at address 0x400e0a00. */\n\t{\n\t\t.chipid_cidr    = 0x28A00960,\n\t\t.name           = \"at91sam3s4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 48 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x28900960,\n\t\t.name           = \"at91sam3s4b\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 48 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28800960,\n\t\t.name           = \"at91sam3s4a\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 48 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28AA0760,\n\t\t.name           = \"at91sam3s2c\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 32 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x289A0760,\n\t\t.name           = \"at91sam3s2b\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 32 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x298B0A60,\n\t\t.name           = \"at91sam3sd8a\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t  },\n/*\t\t\t.bank[1] = { */\n\t\t\t  {\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_512K_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x299B0A60,\n\t\t.name           = \"at91sam3sd8b\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t  },\n/*\t\t\t.bank[1] = { */\n\t\t\t  {\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_512K_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x29ab0a60,\n\t\t.name           = \"at91sam3sd8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t  },\n/*\t\t\t.bank[1] = { */\n\t\t\t  {\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_512K_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes =  256 * 1024,\n\t\t\t\t.nsectors   =  16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x288A0760,\n\t\t.name           = \"at91sam3s2a\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 32 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28A90560,\n\t\t.name           = \"at91sam3s1c\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28990560,\n\t\t.name           = \"at91sam3s1b\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28890560,\n\t\t.name           = \"at91sam3s1a\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x288B0A60,\n\t\t.name           = \"at91sam3s8a\",\n\t\t.total_flash_size     = 256 * 2048,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 2048,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x289B0A60,\n\t\t.name           = \"at91sam3s8b\",\n\t\t.total_flash_size     = 256 * 2048,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 2048,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x28AB0A60,\n\t\t.name           = \"at91sam3s8c\",\n\t\t.total_flash_size     = 256 * 2048,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 2048,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 32768,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\n\t\t\t},\n\t\t},\n\t},\n\n\t/* Start at91sam3n* series */\n\t{\n\t\t.chipid_cidr    = 0x29540960,\n\t\t.name           = \"at91sam3n4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 24 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29440960,\n\t\t.name           = \"at91sam3n4b\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 24 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29340960,\n\t\t.name           = \"at91sam3n4a\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 24 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 256 * 1024,\n\t\t\t\t.nsectors   = 16,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29590760,\n\t\t.name           = \"at91sam3n2c\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29490760,\n\t\t.name           = \"at91sam3n2b\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29390760,\n\t\t.name           = \"at91sam3n2a\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 16 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 128 * 1024,\n\t\t\t\t.nsectors   = 8,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29580560,\n\t\t.name           = \"at91sam3n1c\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 8 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29480560,\n\t\t.name           = \"at91sam3n1b\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 8 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29380560,\n\t\t.name           = \"at91sam3n1a\",\n\t\t.total_flash_size     = 64 * 1024,\n\t\t.total_sram_size      = 8 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n\t\t/* System boots at address 0x0 */\n\t\t/* gpnvm[1] = selects boot code */\n\t\t/*     if gpnvm[1] == 0 */\n\t\t/*         boot is via \"SAMBA\" (rom) */\n\t\t/*     else */\n\t\t/*         boot is via FLASH */\n\t\t/*         Selection is via gpnvm[2] */\n\t\t/*     endif */\n\t\t/*  */\n\t\t/* NOTE: banks 0 & 1 switch places */\n\t\t/*     if gpnvm[2] == 0 */\n\t\t/*         Bank0 is the boot rom */\n\t\t/*      else */\n\t\t/*         Bank1 is the boot rom */\n\t\t/*      endif */\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 64 * 1024,\n\t\t\t\t.nsectors   = 4,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29480360,\n\t\t.name           = \"at91sam3n0b\",\n\t\t.total_flash_size     = 32 * 1024,\n\t\t.total_sram_size      = 8 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 32 * 1024,\n\t\t\t\t.nsectors   = 2,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29380360,\n\t\t.name           = \"at91sam3n0a\",\n\t\t.total_flash_size     = 32 * 1024,\n\t\t.total_sram_size      = 8 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 32 * 1024,\n\t\t\t\t.nsectors   = 2,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29450260,\n\t\t.name           = \"at91sam3n00b\",\n\t\t.total_flash_size     = 16 * 1024,\n\t\t.total_sram_size      = 4 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 16 * 1024,\n\t\t\t\t.nsectors   = 1,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\t{\n\t\t.chipid_cidr    = 0x29350260,\n\t\t.name           = \"at91sam3n00a\",\n\t\t.total_flash_size     = 16 * 1024,\n\t\t.total_sram_size      = 4 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_N,\n\t\t\t\t.controller_address = 0x400e0A00,\n\t\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t\t.present = 1,\n\t\t\t\t.size_bytes = 16 * 1024,\n\t\t\t\t.nsectors   = 1,\n\t\t\t\t.sector_size = 16384,\n\t\t\t\t.page_size   = 256,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.present = 0,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t},\n\t},\n\n\n\t/* Start at91sam3a series*/\n\t/* System boots at address 0x0 */\n\t/* gpnvm[1] = selects boot code */\n\t/*     if gpnvm[1] == 0 */\n\t/*         boot is via \"SAMBA\" (rom) */\n\t/*     else */\n\t/*         boot is via FLASH */\n\t/*         Selection is via gpnvm[2] */\n\t/*     endif */\n\t/*  */\n\t/* NOTE: banks 0 & 1 switch places */\n\t/*     if gpnvm[2] == 0 */\n\t/*         Bank0 is the boot rom */\n\t/*      else */\n\t/*         Bank1 is the boot rom */\n\t/*      endif */\n\n\t{\n\t\t.chipid_cidr    = 0x283E0A60,\n\t\t.name           = \"at91sam3a8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_512K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x283B0960,\n\t\t.name           = \"at91sam3a4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_256K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/* Start at91sam3x* series */\n\t/* System boots at address 0x0 */\n\t/* gpnvm[1] = selects boot code */\n\t/*     if gpnvm[1] == 0 */\n\t/*         boot is via \"SAMBA\" (rom) */\n\t/*     else */\n\t/*         boot is via FLASH */\n\t/*         Selection is via gpnvm[2] */\n\t/*     endif */\n\t/*  */\n\t/* NOTE: banks 0 & 1 switch places */\n\t/*     if gpnvm[2] == 0 */\n\t/*         Bank0 is the boot rom */\n\t/*      else */\n\t/*         Bank1 is the boot rom */\n\t/*      endif */\n\t/*at91sam3x8h - ES has an incorrect CIDR of 0x286E0A20*/\n\t{\n\t\t.chipid_cidr    = 0x286E0A20,\n\t\t.name           = \"at91sam3x8h - ES\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_512K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t/*at91sam3x8h - ES2 and up uses the correct CIDR of 0x286E0A60*/\n\t{\n\t\t.chipid_cidr    = 0x286E0A60,\n\t\t.name           = \"at91sam3x8h\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_512K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x285E0A60,\n\t\t.name           = \"at91sam3x8e\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_512K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x284E0A60,\n\t\t.name           = \"at91sam3x8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_512K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x285B0960,\n\t\t.name           = \"at91sam3x4e\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_256K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t{\n\t\t.chipid_cidr    = 0x284B0960,\n\t\t.name           = \"at91sam3x4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\t\t{\n/*\t\t.bank[0] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK0_BASE_AX,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\t\t  },\n/*\t\t.bank[1] = { */\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 1,\n\t\t\t.base_address = FLASH_BANK1_BASE_256K_AX,\n\t\t\t.controller_address = 0x400e0c00,\n\t\t\t.flash_wait_states = 6,\t/* workaround silicon bug */\n\t\t\t.present = 1,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  8,\n\t\t\t.sector_size = 16384,\n\t\t\t.page_size   = 256,\n\n\t\t  },\n\t\t},\n\t},\n\t/* terminate */\n\t{\n\t\t.chipid_cidr    = 0,\n\t\t.name                   = NULL,\n\t}\n};\n\n/* Globals above */\n/***********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************/\n/* *ATMEL* style code - from the SAM3 driver code */\n\n/**\n * Get the current status of the EEFC and\n * the value of some status bits (LOCKE, PROGE).\n * @param private  - info about the bank\n * @param v        - result goes here\n */\nstatic int efc_get_status(struct sam3_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tr = target_read_u32(private->chip->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FSR,\n\t\t\tv);\n\tLOG_DEBUG(\"Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)\",\n\t\t(unsigned int)(*v),\n\t\t((unsigned int)((*v >> 2) & 1)),\n\t\t((unsigned int)((*v >> 1) & 1)),\n\t\t((unsigned int)((*v >> 0) & 1)));\n\n\treturn r;\n}\n\n/**\n * Get the result of the last executed command.\n * @param private  - info about the bank\n * @param v        - result goes here\n */\nstatic int efc_get_result(struct sam3_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tuint32_t rv;\n\tr = target_read_u32(private->chip->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FRR,\n\t\t\t&rv);\n\tif (v)\n\t\t*v = rv;\n\tLOG_DEBUG(\"Result: 0x%08x\", ((unsigned int)(rv)));\n\treturn r;\n}\n\nstatic int efc_start_command(struct sam3_bank_private *private,\n\tunsigned command, unsigned argument)\n{\n\tuint32_t n, v;\n\tint r;\n\tint retry;\n\n\tretry = 0;\ndo_retry:\n\n\t/* Check command & argument */\n\tswitch (command) {\n\n\t\tcase AT91C_EFC_FCMD_WP:\n\t\tcase AT91C_EFC_FCMD_WPL:\n\t\tcase AT91C_EFC_FCMD_EWP:\n\t\tcase AT91C_EFC_FCMD_EWPL:\n\t\t/* case AT91C_EFC_FCMD_EPL: */\n\t\t/* case AT91C_EFC_FCMD_EPA: */\n\t\tcase AT91C_EFC_FCMD_SLB:\n\t\tcase AT91C_EFC_FCMD_CLB:\n\t\t\tn = (private->size_bytes / private->page_size);\n\t\t\tif (argument >= n)\n\t\t\t\tLOG_ERROR(\"*BUG*: Embedded flash has only %u pages\", (unsigned)(n));\n\t\t\tbreak;\n\n\t\tcase AT91C_EFC_FCMD_SFB:\n\t\tcase AT91C_EFC_FCMD_CFB:\n\t\t\tif (argument >= private->chip->details.n_gpnvms) {\n\t\t\t\tLOG_ERROR(\"*BUG*: Embedded flash has only %d GPNVMs\",\n\t\t\t\t\t\tprivate->chip->details.n_gpnvms);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase AT91C_EFC_FCMD_GETD:\n\t\tcase AT91C_EFC_FCMD_EA:\n\t\tcase AT91C_EFC_FCMD_GLB:\n\t\tcase AT91C_EFC_FCMD_GFB:\n\t\tcase AT91C_EFC_FCMD_STUI:\n\t\tcase AT91C_EFC_FCMD_SPUI:\n\t\t\tif (argument != 0)\n\t\t\t\tLOG_ERROR(\"Argument is meaningless for cmd: %d\", command);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unknown command %d\", command);\n\t\t\tbreak;\n\t}\n\n\tif (command == AT91C_EFC_FCMD_SPUI) {\n\t\t/* this is a very special situation. */\n\t\t/* Situation (1) - error/retry - see below */\n\t\t/*      And we are being called recursively */\n\t\t/* Situation (2) - normal, finished reading unique id */\n\t} else {\n\t\t/* it should be \"ready\" */\n\t\tefc_get_status(private, &v);\n\t\tif (v & 1) {\n\t\t\t/* then it is ready */\n\t\t\t/* we go on */\n\t\t} else {\n\t\t\tif (retry) {\n\t\t\t\t/* we have done this before */\n\t\t\t\t/* the controller is not responding. */\n\t\t\t\tLOG_ERROR(\"flash controller(%d) is not ready! Error\",\n\t\t\t\t\tprivate->bank_number);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t} else {\n\t\t\t\tretry++;\n\t\t\t\tLOG_ERROR(\"Flash controller(%d) is not ready, attempting reset\",\n\t\t\t\t\tprivate->bank_number);\n\t\t\t\t/* we do that by issuing the *STOP* command */\n\t\t\t\tefc_start_command(private, AT91C_EFC_FCMD_SPUI, 0);\n\t\t\t\t/* above is recursive, and further recursion is blocked by */\n\t\t\t\t/* if (command == AT91C_EFC_FCMD_SPUI) above */\n\t\t\t\tgoto do_retry;\n\t\t\t}\n\t\t}\n\t}\n\n\tv = (0x5A << 24) | (argument << 8) | command;\n\tLOG_DEBUG(\"Command: 0x%08x\", ((unsigned int)(v)));\n\tr = target_write_u32(private->bank->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FCR, v);\n\tif (r != ERROR_OK)\n\t\tLOG_DEBUG(\"Error Write failed\");\n\treturn r;\n}\n\n/**\n * Performs the given command and wait until its completion (or an error).\n * @param private  - info about the bank\n * @param command  - Command to perform.\n * @param argument - Optional command argument.\n * @param status   - put command status bits here\n */\nstatic int efc_perform_command(struct sam3_bank_private *private,\n\tunsigned command,\n\tunsigned argument,\n\tuint32_t *status)\n{\n\n\tint r;\n\tuint32_t v;\n\tint64_t ms_now, ms_end;\n\n\t/* default */\n\tif (status)\n\t\t*status = 0;\n\n\tr = efc_start_command(private, command, argument);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tms_end = 500 + timeval_ms();\n\n\tdo {\n\t\tr = efc_get_status(private, &v);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tms_now = timeval_ms();\n\t\tif (ms_now > ms_end) {\n\t\t\t/* error */\n\t\t\tLOG_ERROR(\"Command timeout\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while ((v & 1) == 0);\n\n\t/* error bits.. */\n\tif (status)\n\t\t*status = (v & 0x6);\n\treturn ERROR_OK;\n\n}\n\n/**\n * Read the unique ID.\n * @param private - info about the bank\n * The unique ID is stored in the 'private' structure.\n */\nstatic int flashd_read_uid(struct sam3_bank_private *private)\n{\n\tint r;\n\tuint32_t v;\n\tint x;\n\t/* assume 0 */\n\tprivate->chip->cfg.unique_id[0] = 0;\n\tprivate->chip->cfg.unique_id[1] = 0;\n\tprivate->chip->cfg.unique_id[2] = 0;\n\tprivate->chip->cfg.unique_id[3] = 0;\n\n\tLOG_DEBUG(\"Begin\");\n\tr = efc_start_command(private, AT91C_EFC_FCMD_STUI, 0);\n\tif (r < 0)\n\t\treturn r;\n\n\tfor (x = 0; x < 4; x++) {\n\t\tr = target_read_u32(private->chip->target,\n\t\t\t\tprivate->bank->base + (x * 4),\n\t\t\t\t&v);\n\t\tif (r < 0)\n\t\t\treturn r;\n\t\tprivate->chip->cfg.unique_id[x] = v;\n\t}\n\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_SPUI, 0, NULL);\n\tLOG_DEBUG(\"End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x\",\n\t\tr,\n\t\t(unsigned int)(private->chip->cfg.unique_id[0]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[1]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[2]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[3]));\n\treturn r;\n\n}\n\n/**\n * Erases the entire flash.\n * @param private - the info about the bank.\n */\nstatic int flashd_erase_entire_bank(struct sam3_bank_private *private)\n{\n\tLOG_DEBUG(\"Here\");\n\treturn efc_perform_command(private, AT91C_EFC_FCMD_EA, 0, NULL);\n}\n\n/**\n * Gets current GPNVM state.\n * @param private  - info about the bank.\n * @param gpnvm    -  GPNVM bit index.\n * @param puthere  - result stored here.\n */\n/* ------------------------------------------------------------------------------ */\nstatic int flashd_get_gpnvm(struct sam3_bank_private *private, unsigned gpnvm, unsigned *puthere)\n{\n\tuint32_t v;\n\tint r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Get GPNVMs status */\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_GFB, 0, NULL);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed\");\n\t\treturn r;\n\t}\n\n\tr = efc_get_result(private, &v);\n\n\tif (puthere) {\n\t\t/* Check if GPNVM is set */\n\t\t/* get the bit and make it a 0/1 */\n\t\t*puthere = (v >> gpnvm) & 1;\n\t}\n\n\treturn r;\n}\n\n/**\n * Clears the selected GPNVM bit.\n * @param private info about the bank\n * @param gpnvm GPNVM index.\n * @returns 0 if successful; otherwise returns an error code.\n */\nstatic int flashd_clr_gpnvm(struct sam3_bank_private *private, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = flashd_get_gpnvm(private, gpnvm, &v);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed: %d\", r);\n\t\treturn r;\n\t}\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_CFB, gpnvm, NULL);\n\tLOG_DEBUG(\"End: %d\", r);\n\treturn r;\n}\n\n/**\n * Sets the selected GPNVM bit.\n * @param private info about the bank\n * @param gpnvm GPNVM index.\n */\nstatic int flashd_set_gpnvm(struct sam3_bank_private *private, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = flashd_get_gpnvm(private, gpnvm, &v);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\tif (v) {\n\t\t/* already set */\n\t\tr = ERROR_OK;\n\t} else {\n\t\t/* set it */\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_SFB, gpnvm, NULL);\n\t}\n\treturn r;\n}\n\n/**\n * Returns a bit field (at most 64) of locked regions within a page.\n * @param private info about the bank\n * @param v where to store locked bits\n */\nstatic int flashd_get_lock_bits(struct sam3_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tLOG_DEBUG(\"Here\");\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_GLB, 0, NULL);\n\tif (r == ERROR_OK)\n\t\tr = efc_get_result(private, v);\n\tLOG_DEBUG(\"End: %d\", r);\n\treturn r;\n}\n\n/**\n * Unlocks all the regions in the given address range.\n * @param private info about the bank\n * @param start_sector first sector to unlock\n * @param end_sector last (inclusive) to unlock\n */\n\nstatic int flashd_unlock(struct sam3_bank_private *private,\n\tunsigned start_sector,\n\tunsigned end_sector)\n{\n\tint r;\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\n\tpages_per_sector = private->sector_size / private->page_size;\n\n\t/* Unlock all pages */\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_CLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Locks regions\n * @param private - info about the bank\n * @param start_sector - first sector to lock\n * @param end_sector   - last sector (inclusive) to lock\n */\nstatic int flashd_lock(struct sam3_bank_private *private,\n\tunsigned start_sector,\n\tunsigned end_sector)\n{\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\tint r;\n\n\tpages_per_sector = private->sector_size / private->page_size;\n\n\t/* Lock all pages */\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_SLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\treturn ERROR_OK;\n}\n\n/****** END SAM3 CODE ********/\n\n/* begin helpful debug code */\n/* print the fieldname, the field value, in dec & hex, and return field value */\nstatic uint32_t sam3_reg_fieldname(struct sam3_chip *chip,\n\tconst char *regname,\n\tuint32_t value,\n\tunsigned shift,\n\tunsigned width)\n{\n\tuint32_t v;\n\tint hwidth, dwidth;\n\n\n\t/* extract the field */\n\tv = value >> shift;\n\tv = v & ((1 << width)-1);\n\tif (width <= 16) {\n\t\thwidth = 4;\n\t\tdwidth = 5;\n\t} else {\n\t\thwidth = 8;\n\t\tdwidth = 12;\n\t}\n\n\t/* show the basics */\n\tLOG_USER_N(\"\\t%*s: %*\" PRIu32 \" [0x%0*\" PRIx32 \"] \",\n\t\tREG_NAME_WIDTH, regname,\n\t\tdwidth, v,\n\t\thwidth, v);\n\treturn v;\n}\n\nstatic const char _unknown[] = \"unknown\";\nstatic const char *const eproc_names[] = {\n\t_unknown,\t\t\t\t\t/* 0 */\n\t\"arm946es\",\t\t\t\t\t/* 1 */\n\t\"arm7tdmi\",\t\t\t\t\t/* 2 */\n\t\"Cortex-M3\",\t\t\t\t/* 3 */\n\t\"arm920t\",\t\t\t\t\t/* 4 */\n\t\"arm926ejs\",\t\t\t\t/* 5 */\n\t_unknown,\t\t\t\t\t/* 6 */\n\t_unknown,\t\t\t\t\t/* 7 */\n\t_unknown,\t\t\t\t\t/* 8 */\n\t_unknown,\t\t\t\t\t/* 9 */\n\t_unknown,\t\t\t\t\t/* 10 */\n\t_unknown,\t\t\t\t\t/* 11 */\n\t_unknown,\t\t\t\t\t/* 12 */\n\t_unknown,\t\t\t\t\t/* 13 */\n\t_unknown,\t\t\t\t\t/* 14 */\n\t_unknown,\t\t\t\t\t/* 15 */\n};\n\n#define nvpsize2 nvpsize\t\t/* these two tables are identical */\nstatic const char *const nvpsize[] = {\n\t\"none\",\t\t\t\t\t\t/*  0 */\n\t\"8K bytes\",\t\t\t\t\t/*  1 */\n\t\"16K bytes\",\t\t\t\t/*  2 */\n\t\"32K bytes\",\t\t\t\t/*  3 */\n\t_unknown,\t\t\t\t\t/*  4 */\n\t\"64K bytes\",\t\t\t\t/*  5 */\n\t_unknown,\t\t\t\t\t/*  6 */\n\t\"128K bytes\",\t\t\t\t/*  7 */\n\t_unknown,\t\t\t\t\t/*  8 */\n\t\"256K bytes\",\t\t\t\t/*  9 */\n\t\"512K bytes\",\t\t\t\t/* 10 */\n\t_unknown,\t\t\t\t\t/* 11 */\n\t\"1024K bytes\",\t\t\t\t/* 12 */\n\t_unknown,\t\t\t\t\t/* 13 */\n\t\"2048K bytes\",\t\t\t\t/* 14 */\n\t_unknown,\t\t\t\t\t/* 15 */\n};\n\nstatic const char *const sramsize[] = {\n\t\"48K Bytes\",\t\t\t\t/*  0 */\n\t\"1K Bytes\",\t\t\t\t\t/*  1 */\n\t\"2K Bytes\",\t\t\t\t\t/*  2 */\n\t\"6K Bytes\",\t\t\t\t\t/*  3 */\n\t\"112K Bytes\",\t\t\t\t/*  4 */\n\t\"4K Bytes\",\t\t\t\t\t/*  5 */\n\t\"80K Bytes\",\t\t\t\t/*  6 */\n\t\"160K Bytes\",\t\t\t\t/*  7 */\n\t\"8K Bytes\",\t\t\t\t\t/*  8 */\n\t\"16K Bytes\",\t\t\t\t/*  9 */\n\t\"32K Bytes\",\t\t\t\t/* 10 */\n\t\"64K Bytes\",\t\t\t\t/* 11 */\n\t\"128K Bytes\",\t\t\t\t/* 12 */\n\t\"256K Bytes\",\t\t\t\t/* 13 */\n\t\"96K Bytes\",\t\t\t\t/* 14 */\n\t\"512K Bytes\",\t\t\t\t/* 15 */\n\n};\n\nstatic const struct archnames { unsigned value; const char *name; } archnames[] = {\n\t{ 0x19,  \"AT91SAM9xx Series\"                                            },\n\t{ 0x29,  \"AT91SAM9XExx Series\"                                          },\n\t{ 0x34,  \"AT91x34 Series\"                                                       },\n\t{ 0x37,  \"CAP7 Series\"                                                          },\n\t{ 0x39,  \"CAP9 Series\"                                                          },\n\t{ 0x3B,  \"CAP11 Series\"                                                         },\n\t{ 0x40,  \"AT91x40 Series\"                                                       },\n\t{ 0x42,  \"AT91x42 Series\"                                                       },\n\t{ 0x55,  \"AT91x55 Series\"                                                       },\n\t{ 0x60,  \"AT91SAM7Axx Series\"                                           },\n\t{ 0x61,  \"AT91SAM7AQxx Series\"                                          },\n\t{ 0x63,  \"AT91x63 Series\"                                                       },\n\t{ 0x70,  \"AT91SAM7Sxx Series\"                                           },\n\t{ 0x71,  \"AT91SAM7XCxx Series\"                                          },\n\t{ 0x72,  \"AT91SAM7SExx Series\"                                          },\n\t{ 0x73,  \"AT91SAM7Lxx Series\"                                           },\n\t{ 0x75,  \"AT91SAM7Xxx Series\"                                           },\n\t{ 0x76,  \"AT91SAM7SLxx Series\"                                          },\n\t{ 0x80,  \"ATSAM3UxC Series (100-pin version)\"           },\n\t{ 0x81,  \"ATSAM3UxE Series (144-pin version)\"           },\n\t{ 0x83,  \"ATSAM3AxC Series (100-pin version)\"           },\n\t{ 0x84,  \"ATSAM3XxC Series (100-pin version)\"           },\n\t{ 0x85,  \"ATSAM3XxE Series (144-pin version)\"           },\n\t{ 0x86,  \"ATSAM3XxG Series (208/217-pin version)\"       },\n\t{ 0x88,  \"ATSAM3SxA Series (48-pin version)\"            },\n\t{ 0x89,  \"ATSAM3SxB Series (64-pin version)\"            },\n\t{ 0x8A,  \"ATSAM3SxC Series (100-pin version)\"           },\n\t{ 0x92,  \"AT91x92 Series\"                                                       },\n\t{ 0x93,  \"ATSAM3NxA Series (48-pin version)\"            },\n\t{ 0x94,  \"ATSAM3NxB Series (64-pin version)\"            },\n\t{ 0x95,  \"ATSAM3NxC Series (100-pin version)\"           },\n\t{ 0x98,  \"ATSAM3SDxA Series (48-pin version)\"           },\n\t{ 0x99,  \"ATSAM3SDxB Series (64-pin version)\"           },\n\t{ 0x9A,  \"ATSAM3SDxC Series (100-pin version)\"          },\n\t{ 0xA5,  \"ATSAM5A\"                                                              },\n\t{ 0xF0,  \"AT75Cxx Series\"                                                       },\n\t{ -1, NULL },\n};\n\nstatic const char *const nvptype[] = {\n\t\"rom\",\t/* 0 */\n\t\"romless or onchip flash\",\t/* 1 */\n\t\"embedded flash memory\",/* 2 */\n\t\"rom(nvpsiz) + embedded flash (nvpsiz2)\",\t/* 3 */\n\t\"sram emulating flash\",\t/* 4 */\n\t_unknown,\t/* 5 */\n\t_unknown,\t/* 6 */\n\t_unknown,\t/* 7 */\n};\n\nstatic const char *_yes_or_no(uint32_t v)\n{\n\tif (v)\n\t\treturn \"YES\";\n\telse\n\t\treturn \"NO\";\n}\n\nstatic const char *const _rc_freq[] = {\n\t\"4 MHz\", \"8 MHz\", \"12 MHz\", \"reserved\"\n};\n\nstatic void sam3_explain_ckgr_mor(struct sam3_chip *chip)\n{\n\tuint32_t v;\n\tuint32_t rcen;\n\n\tv = sam3_reg_fieldname(chip, \"MOSCXTEN\", chip->cfg.CKGR_MOR, 0, 1);\n\tLOG_USER(\"(main xtal enabled: %s)\", _yes_or_no(v));\n\tv = sam3_reg_fieldname(chip, \"MOSCXTBY\", chip->cfg.CKGR_MOR, 1, 1);\n\tLOG_USER(\"(main osc bypass: %s)\", _yes_or_no(v));\n\trcen = sam3_reg_fieldname(chip, \"MOSCRCEN\", chip->cfg.CKGR_MOR, 3, 1);\n\tLOG_USER(\"(onchip RC-OSC enabled: %s)\", _yes_or_no(rcen));\n\tv = sam3_reg_fieldname(chip, \"MOSCRCF\", chip->cfg.CKGR_MOR, 4, 3);\n\tLOG_USER(\"(onchip RC-OSC freq: %s)\", _rc_freq[v]);\n\n\tchip->cfg.rc_freq = 0;\n\tif (rcen) {\n\t\tswitch (v) {\n\t\t\tdefault:\n\t\t\t\tchip->cfg.rc_freq = 0;\n\t\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\t\tchip->cfg.rc_freq = 4 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tchip->cfg.rc_freq = 8 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tchip->cfg.rc_freq = 12 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tv = sam3_reg_fieldname(chip, \"MOSCXTST\", chip->cfg.CKGR_MOR, 8, 8);\n\tLOG_USER(\"(startup clks, time= %f uSecs)\",\n\t\t((float)(v * 1000000)) / ((float)(chip->cfg.slow_freq)));\n\tv = sam3_reg_fieldname(chip, \"MOSCSEL\", chip->cfg.CKGR_MOR, 24, 1);\n\tLOG_USER(\"(mainosc source: %s)\",\n\t\tv ? \"external xtal\" : \"internal RC\");\n\n\tv = sam3_reg_fieldname(chip, \"CFDEN\", chip->cfg.CKGR_MOR, 25, 1);\n\tLOG_USER(\"(clock failure enabled: %s)\",\n\t\t_yes_or_no(v));\n}\n\nstatic void sam3_explain_chipid_cidr(struct sam3_chip *chip)\n{\n\tint x;\n\tuint32_t v;\n\tconst char *cp;\n\n\tsam3_reg_fieldname(chip, \"Version\", chip->cfg.CHIPID_CIDR, 0, 5);\n\tLOG_USER_N(\"\\n\");\n\n\tv = sam3_reg_fieldname(chip, \"EPROC\", chip->cfg.CHIPID_CIDR, 5, 3);\n\tLOG_USER(\"%s\", eproc_names[v]);\n\n\tv = sam3_reg_fieldname(chip, \"NVPSIZE\", chip->cfg.CHIPID_CIDR, 8, 4);\n\tLOG_USER(\"%s\", nvpsize[v]);\n\n\tv = sam3_reg_fieldname(chip, \"NVPSIZE2\", chip->cfg.CHIPID_CIDR, 12, 4);\n\tLOG_USER(\"%s\", nvpsize2[v]);\n\n\tv = sam3_reg_fieldname(chip, \"SRAMSIZE\", chip->cfg.CHIPID_CIDR, 16, 4);\n\tLOG_USER(\"%s\", sramsize[v]);\n\n\tv = sam3_reg_fieldname(chip, \"ARCH\", chip->cfg.CHIPID_CIDR, 20, 8);\n\tcp = _unknown;\n\tfor (x = 0; archnames[x].name; x++) {\n\t\tif (v == archnames[x].value) {\n\t\t\tcp = archnames[x].name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tLOG_USER(\"%s\", cp);\n\n\tv = sam3_reg_fieldname(chip, \"NVPTYP\", chip->cfg.CHIPID_CIDR, 28, 3);\n\tLOG_USER(\"%s\", nvptype[v]);\n\n\tv = sam3_reg_fieldname(chip, \"EXTID\", chip->cfg.CHIPID_CIDR, 31, 1);\n\tLOG_USER(\"(exists: %s)\", _yes_or_no(v));\n}\n\nstatic void sam3_explain_ckgr_mcfr(struct sam3_chip *chip)\n{\n\tuint32_t v;\n\n\tv = sam3_reg_fieldname(chip, \"MAINFRDY\", chip->cfg.CKGR_MCFR, 16, 1);\n\tLOG_USER(\"(main ready: %s)\", _yes_or_no(v));\n\n\tv = sam3_reg_fieldname(chip, \"MAINF\", chip->cfg.CKGR_MCFR, 0, 16);\n\n\tv = (v * chip->cfg.slow_freq) / 16;\n\tchip->cfg.mainosc_freq = v;\n\n\tLOG_USER(\"(%3.03f Mhz (%\" PRIu32 \".%03\" PRIu32 \"khz slowclk)\",\n\t\t_tomhz(v),\n\t\t(uint32_t)(chip->cfg.slow_freq / 1000),\n\t\t(uint32_t)(chip->cfg.slow_freq % 1000));\n}\n\nstatic void sam3_explain_ckgr_plla(struct sam3_chip *chip)\n{\n\tuint32_t mula, diva;\n\n\tdiva = sam3_reg_fieldname(chip, \"DIVA\", chip->cfg.CKGR_PLLAR, 0, 8);\n\tLOG_USER_N(\"\\n\");\n\tmula = sam3_reg_fieldname(chip, \"MULA\", chip->cfg.CKGR_PLLAR, 16, 11);\n\tLOG_USER_N(\"\\n\");\n\tchip->cfg.plla_freq = 0;\n\tif (mula == 0)\n\t\tLOG_USER(\"\\tPLLA Freq: (Disabled,mula = 0)\");\n\telse if (diva == 0)\n\t\tLOG_USER(\"\\tPLLA Freq: (Disabled,diva = 0)\");\n\telse if (diva >= 1) {\n\t\tchip->cfg.plla_freq = (chip->cfg.mainosc_freq * (mula + 1) / diva);\n\t\tLOG_USER(\"\\tPLLA Freq: %3.03f MHz\",\n\t\t\t_tomhz(chip->cfg.plla_freq));\n\t}\n}\n\nstatic void sam3_explain_mckr(struct sam3_chip *chip)\n{\n\tuint32_t css, pres, fin = 0;\n\tint pdiv = 0;\n\tconst char *cp = NULL;\n\n\tcss = sam3_reg_fieldname(chip, \"CSS\", chip->cfg.PMC_MCKR, 0, 2);\n\tswitch (css & 3) {\n\t\tcase 0:\n\t\t\tfin = chip->cfg.slow_freq;\n\t\t\tcp = \"slowclk\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tfin = chip->cfg.mainosc_freq;\n\t\t\tcp  = \"mainosc\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tfin = chip->cfg.plla_freq;\n\t\t\tcp  = \"plla\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tif (chip->cfg.CKGR_UCKR & (1 << 16)) {\n\t\t\t\tfin = 480 * 1000 * 1000;\n\t\t\t\tcp = \"upll\";\n\t\t\t} else {\n\t\t\t\tfin = 0;\n\t\t\t\tcp  = \"upll (*ERROR* UPLL is disabled)\";\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t}\n\n\tLOG_USER(\"%s (%3.03f Mhz)\",\n\t\tcp,\n\t\t_tomhz(fin));\n\tpres = sam3_reg_fieldname(chip, \"PRES\", chip->cfg.PMC_MCKR, 4, 3);\n\tswitch (pres & 0x07) {\n\t\tcase 0:\n\t\t\tpdiv = 1;\n\t\t\tcp = \"selected clock\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tpdiv = 2;\n\t\t\tcp = \"clock/2\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tpdiv = 4;\n\t\t\tcp = \"clock/4\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tpdiv = 8;\n\t\t\tcp = \"clock/8\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tpdiv = 16;\n\t\t\tcp = \"clock/16\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tpdiv = 32;\n\t\t\tcp = \"clock/32\";\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tpdiv = 64;\n\t\t\tcp = \"clock/64\";\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tpdiv = 6;\n\t\t\tcp = \"clock/6\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t}\n\tLOG_USER(\"(%s)\", cp);\n\tfin = fin / pdiv;\n\t/* sam3 has a *SINGLE* clock - */\n\t/* other at91 series parts have divisors for these. */\n\tchip->cfg.cpu_freq = fin;\n\tchip->cfg.mclk_freq = fin;\n\tchip->cfg.fclk_freq = fin;\n\tLOG_USER(\"\\t\\tResult CPU Freq: %3.03f\",\n\t\t_tomhz(fin));\n}\n\n#if 0\nstatic struct sam3_chip *target2sam3(struct target *target)\n{\n\tstruct sam3_chip *chip;\n\n\tif (!target)\n\t\treturn NULL;\n\n\tchip = all_sam3_chips;\n\twhile (chip) {\n\t\tif (chip->target == target)\n\t\t\tbreak;\t/* return below */\n\t\telse\n\t\t\tchip = chip->next;\n\t}\n\treturn chip;\n}\n#endif\n\nstatic uint32_t *sam3_get_reg_ptr(struct sam3_cfg *cfg, const struct sam3_reg_list *list)\n{\n\t/* this function exists to help */\n\t/* keep funky offsetof() errors */\n\t/* and casting from causing bugs */\n\n\t/* By using prototypes - we can detect what would */\n\t/* be casting errors. */\n\n\treturn (uint32_t *)(void *)(((char *)(cfg)) + list->struct_offset);\n}\n\n\n#define SAM3_ENTRY(NAME, FUNC)  { .address = SAM3_ ## NAME, .struct_offset = offsetof( \\\n\t\t\t\t\t\t  struct sam3_cfg, \\\n\t\t\t\t\t\t  NAME), # NAME, FUNC }\nstatic const struct sam3_reg_list sam3_all_regs[] = {\n\tSAM3_ENTRY(CKGR_MOR, sam3_explain_ckgr_mor),\n\tSAM3_ENTRY(CKGR_MCFR, sam3_explain_ckgr_mcfr),\n\tSAM3_ENTRY(CKGR_PLLAR, sam3_explain_ckgr_plla),\n\tSAM3_ENTRY(CKGR_UCKR, NULL),\n\tSAM3_ENTRY(PMC_FSMR, NULL),\n\tSAM3_ENTRY(PMC_FSPR, NULL),\n\tSAM3_ENTRY(PMC_IMR, NULL),\n\tSAM3_ENTRY(PMC_MCKR, sam3_explain_mckr),\n\tSAM3_ENTRY(PMC_PCK0, NULL),\n\tSAM3_ENTRY(PMC_PCK1, NULL),\n\tSAM3_ENTRY(PMC_PCK2, NULL),\n\tSAM3_ENTRY(PMC_PCSR, NULL),\n\tSAM3_ENTRY(PMC_SCSR, NULL),\n\tSAM3_ENTRY(PMC_SR, NULL),\n\tSAM3_ENTRY(CHIPID_CIDR, sam3_explain_chipid_cidr),\n\tSAM3_ENTRY(CHIPID_CIDR2, sam3_explain_chipid_cidr),\n\tSAM3_ENTRY(CHIPID_EXID, NULL),\n\tSAM3_ENTRY(CHIPID_EXID2, NULL),\n\t/* TERMINATE THE LIST */\n\t{ .name = NULL }\n};\n#undef SAM3_ENTRY\n\nstatic struct sam3_bank_private *get_sam3_bank_private(struct flash_bank *bank)\n{\n\treturn bank->driver_priv;\n}\n\n/**\n * Given a pointer to where it goes in the structure,\n * determine the register name, address from the all registers table.\n */\nstatic const struct sam3_reg_list *sam3_get_reg(struct sam3_chip *chip, uint32_t *goes_here)\n{\n\tconst struct sam3_reg_list *reg;\n\n\treg = &(sam3_all_regs[0]);\n\twhile (reg->name) {\n\t\tuint32_t *possible;\n\n\t\t/* calculate where this one go.. */\n\t\t/* it is \"possibly\" this register. */\n\n\t\tpossible = ((uint32_t *)(void *)(((char *)(&(chip->cfg))) + reg->struct_offset));\n\n\t\t/* well? Is it this register */\n\t\tif (possible == goes_here) {\n\t\t\t/* Jump for joy! */\n\t\t\treturn reg;\n\t\t}\n\n\t\t/* next... */\n\t\treg++;\n\t}\n\t/* This is *TOTAL*PANIC* - we are totally screwed. */\n\tLOG_ERROR(\"INVALID SAM3 REGISTER\");\n\treturn NULL;\n}\n\nstatic int sam3_read_this_reg(struct sam3_chip *chip, uint32_t *goes_here)\n{\n\tconst struct sam3_reg_list *reg;\n\tint r;\n\n\treg = sam3_get_reg(chip, goes_here);\n\tif (!reg)\n\t\treturn ERROR_FAIL;\n\n\tr = target_read_u32(chip->target, reg->address, goes_here);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read SAM3 register: %s @ 0x%08x, Err: %d\",\n\t\t\treg->name, (unsigned)(reg->address), r);\n\t}\n\treturn r;\n}\n\nstatic int sam3_read_all_regs(struct sam3_chip *chip)\n{\n\tint r;\n\tconst struct sam3_reg_list *reg;\n\n\treg = &(sam3_all_regs[0]);\n\twhile (reg->name) {\n\t\tr = sam3_read_this_reg(chip,\n\t\t\t\tsam3_get_reg_ptr(&(chip->cfg), reg));\n\t\tif (r != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Cannot read SAM3 register: %s @ 0x%08x, Error: %d\",\n\t\t\t\treg->name, ((unsigned)(reg->address)), r);\n\t\t\treturn r;\n\t\t}\n\t\treg++;\n\t}\n\n\t/* Chip identification register\n\t*\n\t* Unfortunately, the chip identification register is not at\n\t* a constant address across all of the SAM3 series'. As a\n\t* consequence, a simple heuristic is used to find where it's\n\t* at...\n\t*\n\t* If the contents at the first address is zero, then we know\n\t* that the second address is where the chip id register is.\n\t* We can deduce this because for those SAM's that have the\n\t* chip id @ 0x400e0940, the first address, 0x400e0740, is\n\t* located in the memory map of the Power Management Controller\n\t* (PMC). Furthermore, the address is not used by the PMC.\n\t* So when read, the memory controller returns zero.*/\n\tif (chip->cfg.CHIPID_CIDR == 0)\t{\n\t\t/*Put the correct CIDR and EXID values in the chip structure */\n\t\tchip->cfg.CHIPID_CIDR = chip->cfg.CHIPID_CIDR2;\n\t\tchip->cfg.CHIPID_EXID = chip->cfg.CHIPID_EXID2;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int sam3_get_info(struct sam3_chip *chip)\n{\n\tconst struct sam3_reg_list *reg;\n\tuint32_t regval;\n\n\treg = &(sam3_all_regs[0]);\n\twhile (reg->name) {\n\t\t/* display all regs */\n\t\tLOG_DEBUG(\"Start: %s\", reg->name);\n\t\tregval = *sam3_get_reg_ptr(&(chip->cfg), reg);\n\t\tLOG_USER(\"%*s: [0x%08\" PRIx32 \"] -> 0x%08\" PRIx32,\n\t\t\tREG_NAME_WIDTH,\n\t\t\treg->name,\n\t\t\treg->address,\n\t\t\tregval);\n\t\tif (reg->explain_func)\n\t\t\t(*(reg->explain_func))(chip);\n\t\tLOG_DEBUG(\"End: %s\", reg->name);\n\t\treg++;\n\t}\n\tLOG_USER(\"   rc-osc: %3.03f MHz\", _tomhz(chip->cfg.rc_freq));\n\tLOG_USER(\"  mainosc: %3.03f MHz\", _tomhz(chip->cfg.mainosc_freq));\n\tLOG_USER(\"     plla: %3.03f MHz\", _tomhz(chip->cfg.plla_freq));\n\tLOG_USER(\" cpu-freq: %3.03f MHz\", _tomhz(chip->cfg.cpu_freq));\n\tLOG_USER(\"mclk-freq: %3.03f MHz\", _tomhz(chip->cfg.mclk_freq));\n\n\tLOG_USER(\" UniqueId: 0x%08\" PRIx32 \" 0x%08\" PRIx32 \" 0x%08\" PRIx32 \" 0x%08\" PRIx32,\n\t\tchip->cfg.unique_id[0],\n\t\tchip->cfg.unique_id[1],\n\t\tchip->cfg.unique_id[2],\n\t\tchip->cfg.unique_id[3]);\n\n\treturn ERROR_OK;\n}\n\nstatic int sam3_protect_check(struct flash_bank *bank)\n{\n\tint r;\n\tuint32_t v = 0;\n\tunsigned x;\n\tstruct sam3_bank_private *private;\n\n\tLOG_DEBUG(\"Begin\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam3_bank_private(bank);\n\tif (!private) {\n\t\tLOG_ERROR(\"no private for this bank?\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tr = flashd_get_lock_bits(private, &v);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed: %d\", r);\n\t\treturn r;\n\t}\n\n\tfor (x = 0; x < private->nsectors; x++)\n\t\tbank->sectors[x].is_protected = (!!(v & (1 << x)));\n\tLOG_DEBUG(\"Done\");\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)\n{\n\tstruct sam3_chip *chip;\n\n\tchip = all_sam3_chips;\n\n\t/* is this an existing chip? */\n\twhile (chip) {\n\t\tif (chip->target == bank->target)\n\t\t\tbreak;\n\t\tchip = chip->next;\n\t}\n\n\tif (!chip) {\n\t\t/* this is a *NEW* chip */\n\t\tchip = calloc(1, sizeof(struct sam3_chip));\n\t\tif (!chip) {\n\t\t\tLOG_ERROR(\"NO RAM!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tchip->target = bank->target;\n\t\t/* insert at head */\n\t\tchip->next = all_sam3_chips;\n\t\tall_sam3_chips = chip;\n\t\tchip->target = bank->target;\n\t\t/* assumption is this runs at 32khz */\n\t\tchip->cfg.slow_freq = 32768;\n\t\tchip->probed = false;\n\t}\n\n\tswitch (bank->base) {\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Address 0x%08x invalid bank address (try 0x%08x or 0x%08x \"\n\t\t\t\"[at91sam3u series] or 0x%08x [at91sam3s series] or \"\n\t\t\t\"0x%08x [at91sam3n series] or 0x%08x or 0x%08x or 0x%08x[at91sam3ax series] )\",\n\t\t\t((unsigned int)(bank->base)),\n\t\t\t((unsigned int)(FLASH_BANK0_BASE_U)),\n\t\t\t((unsigned int)(FLASH_BANK1_BASE_U)),\n\t\t\t((unsigned int)(FLASH_BANK_BASE_S)),\n\t\t\t((unsigned int)(FLASH_BANK_BASE_N)),\n\t\t\t((unsigned int)(FLASH_BANK0_BASE_AX)),\n\t\t    ((unsigned int)(FLASH_BANK1_BASE_256K_AX)),\n\t\t    ((unsigned int)(FLASH_BANK1_BASE_512K_AX)));\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* at91sam3s and at91sam3n series only has bank 0*/\n\t\t/* at91sam3u and at91sam3ax series has the same address for bank 0*/\n\t\tcase FLASH_BANK_BASE_S:\n\t\tcase FLASH_BANK0_BASE_U:\n\t\t\tbank->driver_priv = &(chip->details.bank[0]);\n\t\t\tbank->bank_number = 0;\n\t\t\tchip->details.bank[0].chip = chip;\n\t\t\tchip->details.bank[0].bank = bank;\n\t\t\tbreak;\n\n\t\t/* Bank 1 of at91sam3u or at91sam3ax series */\n\t\tcase FLASH_BANK1_BASE_U:\n\t\tcase FLASH_BANK1_BASE_256K_AX:\n\t\tcase FLASH_BANK1_BASE_512K_AX:\n\t\t\tbank->driver_priv = &(chip->details.bank[1]);\n\t\t\tbank->bank_number = 1;\n\t\t\tchip->details.bank[1].chip = chip;\n\t\t\tchip->details.bank[1].bank = bank;\n\t\t\tbreak;\n\t}\n\n\t/* we initialize after probing. */\n\treturn ERROR_OK;\n}\n\n/**\n * Remove all chips from the internal list without distinguishing which one\n * is owned by this bank. This simplification works only for one shot\n * deallocation like current flash_free_all_banks()\n */\nstatic void sam3_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct sam3_chip *chip = all_sam3_chips;\n\twhile (chip) {\n\t\tstruct sam3_chip *next = chip->next;\n\t\tfree(chip);\n\t\tchip = next;\n\t}\n\tall_sam3_chips = NULL;\n}\n\nstatic int sam3_get_details(struct sam3_bank_private *private)\n{\n\tconst struct sam3_chip_details *details;\n\tstruct sam3_chip *chip;\n\tstruct flash_bank *saved_banks[SAM3_MAX_FLASH_BANKS];\n\tunsigned x;\n\n\tLOG_DEBUG(\"Begin\");\n\tdetails = all_sam3_details;\n\twhile (details->name) {\n\t\t/* Compare cidr without version bits */\n\t\tif (((details->chipid_cidr ^ private->chip->cfg.CHIPID_CIDR) & 0xFFFFFFE0) == 0)\n\t\t\tbreak;\n\t\telse\n\t\t\tdetails++;\n\t}\n\tif (!details->name) {\n\t\tLOG_ERROR(\"SAM3 ChipID 0x%08x not found in table (perhaps you can ID this chip?)\",\n\t\t\t(unsigned int)(private->chip->cfg.CHIPID_CIDR));\n\t\t/* Help the victim, print details about the chip */\n\t\tLOG_INFO(\"SAM3 CHIPID_CIDR: 0x%08\" PRIx32 \" decodes as follows\",\n\t\t\tprivate->chip->cfg.CHIPID_CIDR);\n\t\tsam3_explain_chipid_cidr(private->chip);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* DANGER: THERE ARE DRAGONS HERE */\n\n\t/* get our chip - it is going */\n\t/* to be over-written shortly */\n\tchip = private->chip;\n\n\t/* Note that, in reality: */\n\t/*  */\n\t/*     private = &(chip->details.bank[0]) */\n\t/* or  private = &(chip->details.bank[1]) */\n\t/*  */\n\n\t/* save the \"bank\" pointers */\n\tfor (x = 0; x < SAM3_MAX_FLASH_BANKS; x++)\n\t\tsaved_banks[x] = chip->details.bank[x].bank;\n\n\t/* Overwrite the \"details\" structure. */\n\tmemcpy(&(private->chip->details),\n\t\tdetails,\n\t\tsizeof(private->chip->details));\n\n\t/* now fix the ghosted pointers */\n\tfor (x = 0; x < SAM3_MAX_FLASH_BANKS; x++) {\n\t\tchip->details.bank[x].chip = chip;\n\t\tchip->details.bank[x].bank = saved_banks[x];\n\t}\n\n\t/* update the *BANK*SIZE* */\n\n\tLOG_DEBUG(\"End\");\n\treturn ERROR_OK;\n}\n\nstatic int _sam3_probe(struct flash_bank *bank, int noise)\n{\n\tint r;\n\tstruct sam3_bank_private *private;\n\n\n\tLOG_DEBUG(\"Begin: Bank: %u, Noise: %d\", bank->bank_number, noise);\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam3_bank_private(bank);\n\tif (!private) {\n\t\tLOG_ERROR(\"Invalid/unknown bank number\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = sam3_read_all_regs(private->chip);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->chip->probed)\n\t\tr = sam3_get_info(private->chip);\n\telse\n\t\tr = sam3_get_details(private);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\t/* update the flash bank size */\n\tfor (unsigned int x = 0; x < SAM3_MAX_FLASH_BANKS; x++) {\n\t\tif (bank->base == private->chip->details.bank[x].base_address) {\n\t\t\tbank->size = private->chip->details.bank[x].size_bytes;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!bank->sectors) {\n\t\tbank->sectors = calloc(private->nsectors, (sizeof((bank->sectors)[0])));\n\t\tif (!bank->sectors) {\n\t\t\tLOG_ERROR(\"No memory!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbank->num_sectors = private->nsectors;\n\n\t\tfor (unsigned int x = 0; x < bank->num_sectors; x++) {\n\t\t\tbank->sectors[x].size = private->sector_size;\n\t\t\tbank->sectors[x].offset = x * (private->sector_size);\n\t\t\t/* mark as unknown */\n\t\t\tbank->sectors[x].is_erased = -1;\n\t\t\tbank->sectors[x].is_protected = -1;\n\t\t}\n\t}\n\n\tprivate->probed = true;\n\n\tr = sam3_protect_check(bank);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tLOG_DEBUG(\"Bank = %d, nbanks = %d\",\n\t\tprivate->bank_number, private->chip->details.n_banks);\n\tif ((private->bank_number + 1) == private->chip->details.n_banks) {\n\t\t/* read unique id, */\n\t\t/* it appears to be associated with the *last* flash bank. */\n\t\tflashd_read_uid(private);\n\t}\n\n\treturn r;\n}\n\nstatic int sam3_probe(struct flash_bank *bank)\n{\n\treturn _sam3_probe(bank, 1);\n}\n\nstatic int sam3_auto_probe(struct flash_bank *bank)\n{\n\treturn _sam3_probe(bank, 0);\n}\n\nstatic int sam3_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct sam3_bank_private *private;\n\tint r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tr = sam3_auto_probe(bank);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Here,r=%d\", r);\n\t\treturn r;\n\t}\n\n\tprivate = get_sam3_bank_private(bank);\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif ((first == 0) && ((last + 1) == private->nsectors)) {\n\t\t/* whole chip */\n\t\tLOG_DEBUG(\"Here\");\n\t\treturn flashd_erase_entire_bank(private);\n\t}\n\tLOG_INFO(\"sam3 auto-erases while programming (request ignored)\");\n\treturn ERROR_OK;\n}\n\nstatic int sam3_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct sam3_bank_private *private;\n\tint r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam3_bank_private(bank);\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (set)\n\t\tr = flashd_lock(private, first, last);\n\telse\n\t\tr = flashd_unlock(private, first, last);\n\tLOG_DEBUG(\"End: r=%d\", r);\n\n\treturn r;\n\n}\n\nstatic int sam3_page_read(struct sam3_bank_private *private, unsigned pagenum, uint8_t *buf)\n{\n\tuint32_t adr;\n\tint r;\n\n\tadr = pagenum * private->page_size;\n\tadr += private->base_address;\n\n\tr = target_read_memory(private->chip->target,\n\t\t\tadr,\n\t\t\t4,\t\t\t\t\t/* THIS*MUST*BE* in 32bit values */\n\t\t\tprivate->page_size / 4,\n\t\t\tbuf);\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"SAM3: Flash program failed to read page phys address: 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\treturn r;\n}\n\nstatic int sam3_page_write(struct sam3_bank_private *private, unsigned pagenum, const uint8_t *buf)\n{\n\tuint32_t adr;\n\tuint32_t status;\n\tuint32_t fmr;\t/* EEFC Flash Mode Register */\n\tint r;\n\n\tadr = pagenum * private->page_size;\n\tadr += private->base_address;\n\n\t/* Get flash mode register value */\n\tr = target_read_u32(private->chip->target, private->controller_address, &fmr);\n\tif (r != ERROR_OK)\n\t\tLOG_DEBUG(\"Error Read failed: read flash mode register\");\n\n\t/* Clear flash wait state field */\n\tfmr &= 0xfffff0ff;\n\n\t/* set FWS (flash wait states) field in the FMR (flash mode register) */\n\tfmr |= (private->flash_wait_states << 8);\n\n\tLOG_DEBUG(\"Flash Mode: 0x%08x\", ((unsigned int)(fmr)));\n\tr = target_write_u32(private->bank->target, private->controller_address, fmr);\n\tif (r != ERROR_OK)\n\t\tLOG_DEBUG(\"Error Write failed: set flash mode register\");\n\n\tLOG_DEBUG(\"Wr Page %u @ phys address: 0x%08x\", pagenum, (unsigned int)(adr));\n\tr = target_write_memory(private->chip->target,\n\t\t\tadr,\n\t\t\t4,\t\t\t\t\t/* THIS*MUST*BE* in 32bit values */\n\t\t\tprivate->page_size / 4,\n\t\t\tbuf);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"SAM3: Failed to write (buffer) page at phys address 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\t\treturn r;\n\t}\n\n\tr = efc_perform_command(private,\n\t\t\t/* send Erase & Write Page */\n\t\t\tAT91C_EFC_FCMD_EWP,\n\t\t\tpagenum,\n\t\t\t&status);\n\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"SAM3: Error performing Erase & Write page @ phys address 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\tif (status & (1 << 2)) {\n\t\tLOG_ERROR(\"SAM3: Page @ Phys address 0x%08x is locked\", (unsigned int)(adr));\n\t\treturn ERROR_FAIL;\n\t}\n\tif (status & (1 << 1)) {\n\t\tLOG_ERROR(\"SAM3: Flash Command error @phys address 0x%08x\", (unsigned int)(adr));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int sam3_write(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tint n;\n\tunsigned page_cur;\n\tunsigned page_end;\n\tint r;\n\tunsigned page_offset;\n\tstruct sam3_bank_private *private;\n\tuint8_t *pagebuffer;\n\n\t/* in case we bail further below, set this to null */\n\tpagebuffer = NULL;\n\n\t/* ignore dumb requests */\n\tif (count == 0) {\n\t\tr = ERROR_OK;\n\t\tgoto done;\n\t}\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\tr = ERROR_TARGET_NOT_HALTED;\n\t\tgoto done;\n\t}\n\n\tprivate = get_sam3_bank_private(bank);\n\tif (!(private->probed)) {\n\t\tr = ERROR_FLASH_BANK_NOT_PROBED;\n\t\tgoto done;\n\t}\n\n\tif ((offset + count) > private->size_bytes) {\n\t\tLOG_ERROR(\"Flash write error - past end of bank\");\n\t\tLOG_ERROR(\" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x\",\n\t\t\t(unsigned int)(offset),\n\t\t\t(unsigned int)(count),\n\t\t\t(unsigned int)(private->size_bytes));\n\t\tr = ERROR_FAIL;\n\t\tgoto done;\n\t}\n\n\tpagebuffer = malloc(private->page_size);\n\tif (!pagebuffer) {\n\t\tLOG_ERROR(\"No memory for %d Byte page buffer\", (int)(private->page_size));\n\t\tr = ERROR_FAIL;\n\t\tgoto done;\n\t}\n\n\t/* what page do we start & end in? */\n\tpage_cur = offset / private->page_size;\n\tpage_end = (offset + count - 1) / private->page_size;\n\n\tLOG_DEBUG(\"Offset: 0x%08x, Count: 0x%08x\", (unsigned int)(offset), (unsigned int)(count));\n\tLOG_DEBUG(\"Page start: %d, Page End: %d\", (int)(page_cur), (int)(page_end));\n\n\t/* Special case: all one page */\n\t/*  */\n\t/* Otherwise: */\n\t/*    (1) non-aligned start */\n\t/*    (2) body pages */\n\t/*    (3) non-aligned end. */\n\n\t/* Handle special case - all one page. */\n\tif (page_cur == page_end) {\n\t\tLOG_DEBUG(\"Special case, all in one page\");\n\t\tr = sam3_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tpage_offset = (offset & (private->page_size-1));\n\t\tmemcpy(pagebuffer + page_offset,\n\t\t\tbuffer,\n\t\t\tcount);\n\n\t\tr = sam3_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\tr = ERROR_OK;\n\t\tgoto done;\n\t}\n\n\t/* non-aligned start */\n\tpage_offset = offset & (private->page_size - 1);\n\tif (page_offset) {\n\t\tLOG_DEBUG(\"Not-Aligned start\");\n\t\t/* read the partial */\n\t\tr = sam3_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\t/* over-write with new data */\n\t\tn = (private->page_size - page_offset);\n\t\tmemcpy(pagebuffer + page_offset,\n\t\t\tbuffer,\n\t\t\tn);\n\n\t\tr = sam3_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tcount  -= n;\n\t\toffset += n;\n\t\tbuffer += n;\n\t\tpage_cur++;\n\t}\n\n\t/* By checking that offset is correct here, we also\n\tfix a clang warning */\n\tassert(offset % private->page_size == 0);\n\n\t/* intermediate large pages */\n\t/* also - the final *terminal* */\n\t/* if that terminal page is a full page */\n\tLOG_DEBUG(\"Full Page Loop: cur=%d, end=%d, count = 0x%08x\",\n\t\t(int)page_cur, (int)page_end, (unsigned int)(count));\n\n\twhile ((page_cur < page_end) &&\n\t\t\t(count >= private->page_size)) {\n\t\tr = sam3_page_write(private, page_cur, buffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\tcount -= private->page_size;\n\t\tbuffer += private->page_size;\n\t\tpage_cur += 1;\n\t}\n\n\t/* terminal partial page? */\n\tif (count) {\n\t\tLOG_DEBUG(\"Terminal partial page, count = 0x%08x\", (unsigned int)(count));\n\t\t/* we have a partial page */\n\t\tr = sam3_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\t\t\t\t/* data goes at start */\n\t\tmemcpy(pagebuffer, buffer, count);\n\t\tr = sam3_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\tLOG_DEBUG(\"Done!\");\n\tr = ERROR_OK;\ndone:\n\tfree(pagebuffer);\n\treturn r;\n}\n\nCOMMAND_HANDLER(sam3_handle_info_command)\n{\n\tstruct sam3_chip *chip;\n\tchip = get_current_sam3(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tunsigned x;\n\tint r;\n\n\t/* bank0 must exist before we can do anything */\n\tif (!chip->details.bank[0].bank) {\n\t\tx = 0;\nneed_define:\n\t\tcommand_print(CMD,\n\t\t\t\"Please define bank %d via command: flash bank %s ... \",\n\t\t\tx,\n\t\t\tat91sam3_flash.name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* if bank 0 is not probed, then probe it */\n\tif (!(chip->details.bank[0].probed)) {\n\t\tr = sam3_auto_probe(chip->details.bank[0].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\t/* above guarantees the \"chip details\" structure is valid */\n\t/* and thus, bank private areas are valid */\n\t/* and we have a SAM3 chip, what a concept! */\n\n\t/* auto-probe other banks, 0 done above */\n\tfor (x = 1; x < SAM3_MAX_FLASH_BANKS; x++) {\n\t\t/* skip banks not present */\n\t\tif (!(chip->details.bank[x].present))\n\t\t\tcontinue;\n\n\t\tif (!chip->details.bank[x].bank)\n\t\t\tgoto need_define;\n\n\t\tif (chip->details.bank[x].probed)\n\t\t\tcontinue;\n\n\t\tr = sam3_auto_probe(chip->details.bank[x].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\n\tr = sam3_get_info(chip);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Sam3Info, Failed %d\", r);\n\t\treturn r;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sam3_handle_gpnvm_command)\n{\n\tunsigned x, v;\n\tint r, who;\n\tstruct sam3_chip *chip;\n\n\tchip = get_current_sam3(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tif (chip->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"sam3 - target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->details.bank[0].bank) {\n\t\tcommand_print(CMD, \"Bank0 must be defined first via: flash bank %s ...\",\n\t\t\tat91sam3_flash.name);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!chip->details.bank[0].probed) {\n\t\tr = sam3_auto_probe(chip->details.bank[0].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\n\tswitch (CMD_ARGC) {\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tcase 0:\n\t\t\tgoto showall;\n\t\tcase 1:\n\t\t\twho = -1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif ((strcmp(CMD_ARGV[0], \"show\") == 0) && (strcmp(CMD_ARGV[1], \"all\") == 0))\n\t\t\t\twho = -1;\n\t\t\telse {\n\t\t\t\tuint32_t v32;\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);\n\t\t\t\twho = v32;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (strcmp(\"show\", CMD_ARGV[0]) == 0) {\n\t\tif (who == -1) {\nshowall:\n\t\t\tr = ERROR_OK;\n\t\t\tfor (x = 0; x < chip->details.n_gpnvms; x++) {\n\t\t\t\tr = flashd_get_gpnvm(&(chip->details.bank[0]), x, &v);\n\t\t\t\tif (r != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t\tcommand_print(CMD, \"sam3-gpnvm%u: %u\", x, v);\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t\tif ((who >= 0) && (((unsigned)(who)) < chip->details.n_gpnvms)) {\n\t\t\tr = flashd_get_gpnvm(&(chip->details.bank[0]), who, &v);\n\t\t\tif (r == ERROR_OK)\n\t\t\t\tcommand_print(CMD, \"sam3-gpnvm%u: %u\", who, v);\n\t\t\treturn r;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"sam3-gpnvm invalid GPNVM: %u\", who);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tif (who == -1) {\n\t\tcommand_print(CMD, \"Missing GPNVM number\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (strcmp(\"set\", CMD_ARGV[0]) == 0)\n\t\tr = flashd_set_gpnvm(&(chip->details.bank[0]), who);\n\telse if ((strcmp(\"clr\", CMD_ARGV[0]) == 0) ||\n\t\t (strcmp(\"clear\", CMD_ARGV[0]) == 0))\t\t\t/* quietly accept both */\n\t\tr = flashd_clr_gpnvm(&(chip->details.bank[0]), who);\n\telse {\n\t\tcommand_print(CMD, \"Unknown command: %s\", CMD_ARGV[0]);\n\t\tr = ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn r;\n}\n\nCOMMAND_HANDLER(sam3_handle_slowclk_command)\n{\n\tstruct sam3_chip *chip;\n\n\tchip = get_current_sam3(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\t/* show */\n\t\t\tbreak;\n\t\tcase 1:\n\t\t{\n\t\t\t/* set */\n\t\t\tuint32_t v;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);\n\t\t\tif (v > 200000) {\n\t\t\t\t/* absurd slow clock of 200Khz? */\n\t\t\t\tcommand_print(CMD, \"Absurd/illegal slow clock freq: %d\\n\", (int)(v));\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tchip->cfg.slow_freq = v;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\t/* error */\n\t\t\tcommand_print(CMD, \"Too many parameters\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tcommand_print(CMD, \"Slowclk freq: %d.%03dkhz\",\n\t\t(int)(chip->cfg.slow_freq / 1000),\n\t\t(int)(chip->cfg.slow_freq % 1000));\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration at91sam3_exec_command_handlers[] = {\n\t{\n\t\t.name = \"gpnvm\",\n\t\t.handler = sam3_handle_gpnvm_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[('clr'|'set'|'show') bitnum]\",\n\t\t.help = \"Without arguments, shows all bits in the gpnvm \"\n\t\t\t\"register.  Otherwise, clears, sets, or shows one \"\n\t\t\t\"General Purpose Non-Volatile Memory (gpnvm) bit.\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = sam3_handle_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Print information about the current at91sam3 chip \"\n\t\t\t\"and its flash configuration.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"slowclk\",\n\t\t.handler = sam3_handle_slowclk_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[clock_hz]\",\n\t\t.help = \"Display or set the slowclock frequency \"\n\t\t\t\"(default 32768 Hz).\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration at91sam3_command_handlers[] = {\n\t{\n\t\t.name = \"at91sam3\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"at91sam3 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = at91sam3_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver at91sam3_flash = {\n\t.name = \"at91sam3\",\n\t.commands = at91sam3_command_handlers,\n\t.flash_bank_command = sam3_flash_bank_command,\n\t.erase = sam3_erase,\n\t.protect = sam3_protect,\n\t.write = sam3_write,\n\t.read = default_flash_read,\n\t.probe = sam3_probe,\n\t.auto_probe = sam3_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = sam3_protect_check,\n\t.free_driver_priv = sam3_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/at91sam4.c",
    "content": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)\n\n/*\n * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>\n *\n * at91sam3s* support\n * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>\n *\n * at91sam3x* & at91sam4 support\n * Copyright (C) 2011 by Olivier Schonken, Jim Norris\n *\n * Some of the lower level code was based on code supplied by\n * ATMEL under BSD-Source-Code License and this copyright.\n * ATMEL Microcontroller Software Support\n * Copyright (c) 2009, Atmel Corporation. All rights reserved.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/time_support.h>\n\n#define REG_NAME_WIDTH  (12)\n\n/* at91sam4s/at91sam4e/at91sam4c series (has always one flash bank)*/\n#define FLASH_BANK_BASE_S   0x00400000\n#define FLASH_BANK_BASE_C   0x01000000\n\n/* at91sam4sd series (two one flash banks), first bank address */\n#define FLASH_BANK0_BASE_SD FLASH_BANK_BASE_S\n/* at91sam4sd16x, second bank address */\n#define FLASH_BANK1_BASE_1024K_SD (FLASH_BANK0_BASE_SD+(1024*1024/2))\n/* at91sam4sd32x, second bank address */\n#define FLASH_BANK1_BASE_2048K_SD (FLASH_BANK0_BASE_SD+(2048*1024/2))\n\n/* at91sam4c32x, first and second bank address */\n#define FLASH_BANK0_BASE_C32 FLASH_BANK_BASE_C\n#define FLASH_BANK1_BASE_C32 (FLASH_BANK_BASE_C+(2048*1024/2))\n\n#define         AT91C_EFC_FCMD_GETD                 (0x0)\t/* (EFC) Get Flash Descriptor */\n#define         AT91C_EFC_FCMD_WP                   (0x1)\t/* (EFC) Write Page */\n#define         AT91C_EFC_FCMD_WPL                  (0x2)\t/* (EFC) Write Page and Lock */\n#define         AT91C_EFC_FCMD_EWP                  (0x3)\t/* (EFC) Erase Page and Write Page */\n#define         AT91C_EFC_FCMD_EWPL                 (0x4)\t/* (EFC) Erase Page and Write Page then Lock */\n#define         AT91C_EFC_FCMD_EA                   (0x5)\t/* (EFC) Erase All */\n/* cmd6 is not present in the at91sam4u4/2/1 data sheet table 19-2 */\n/* #define      AT91C_EFC_FCMD_EPL                  (0x6) // (EFC) Erase plane? */\n#define\t\t\tAT91C_EFC_FCMD_EPA                  (0x7)     /* (EFC) Erase pages */\n#define         AT91C_EFC_FCMD_SLB                  (0x8)\t/* (EFC) Set Lock Bit */\n#define         AT91C_EFC_FCMD_CLB                  (0x9)\t/* (EFC) Clear Lock Bit */\n#define         AT91C_EFC_FCMD_GLB                  (0xA)\t/* (EFC) Get Lock Bit */\n#define         AT91C_EFC_FCMD_SFB                  (0xB)\t/* (EFC) Set Fuse Bit */\n#define         AT91C_EFC_FCMD_CFB                  (0xC)\t/* (EFC) Clear Fuse Bit */\n#define         AT91C_EFC_FCMD_GFB                  (0xD)\t/* (EFC) Get Fuse Bit */\n#define         AT91C_EFC_FCMD_STUI                 (0xE)\t/* (EFC) Start Read Unique ID */\n#define         AT91C_EFC_FCMD_SPUI                 (0xF)\t/* (EFC) Stop Read Unique ID */\n\n#define  OFFSET_EFC_FMR   0\n#define  OFFSET_EFC_FCR   4\n#define  OFFSET_EFC_FSR   8\n#define  OFFSET_EFC_FRR   12\n\nstatic float _tomhz(uint32_t freq_hz)\n{\n\tfloat f;\n\n\tf = ((float)(freq_hz)) / 1000000.0;\n\treturn f;\n}\n\n/* How the chip is configured. */\nstruct sam4_cfg {\n\tuint32_t unique_id[4];\n\n\tuint32_t slow_freq;\n\tuint32_t rc_freq;\n\tuint32_t mainosc_freq;\n\tuint32_t plla_freq;\n\tuint32_t mclk_freq;\n\tuint32_t cpu_freq;\n\tuint32_t fclk_freq;\n\tuint32_t pclk0_freq;\n\tuint32_t pclk1_freq;\n\tuint32_t pclk2_freq;\n\n\n#define SAM4_CHIPID_CIDR          (0x400E0740)\n\tuint32_t CHIPID_CIDR;\n#define SAM4_CHIPID_EXID          (0x400E0744)\n\tuint32_t CHIPID_EXID;\n\n#define SAM4_PMC_BASE             (0x400E0400)\n#define SAM4_PMC_SCSR             (SAM4_PMC_BASE + 0x0008)\n\tuint32_t PMC_SCSR;\n#define SAM4_PMC_PCSR             (SAM4_PMC_BASE + 0x0018)\n\tuint32_t PMC_PCSR;\n#define SAM4_CKGR_UCKR            (SAM4_PMC_BASE + 0x001c)\n\tuint32_t CKGR_UCKR;\n#define SAM4_CKGR_MOR             (SAM4_PMC_BASE + 0x0020)\n\tuint32_t CKGR_MOR;\n#define SAM4_CKGR_MCFR            (SAM4_PMC_BASE + 0x0024)\n\tuint32_t CKGR_MCFR;\n#define SAM4_CKGR_PLLAR           (SAM4_PMC_BASE + 0x0028)\n\tuint32_t CKGR_PLLAR;\n#define SAM4_PMC_MCKR             (SAM4_PMC_BASE + 0x0030)\n\tuint32_t PMC_MCKR;\n#define SAM4_PMC_PCK0             (SAM4_PMC_BASE + 0x0040)\n\tuint32_t PMC_PCK0;\n#define SAM4_PMC_PCK1             (SAM4_PMC_BASE + 0x0044)\n\tuint32_t PMC_PCK1;\n#define SAM4_PMC_PCK2             (SAM4_PMC_BASE + 0x0048)\n\tuint32_t PMC_PCK2;\n#define SAM4_PMC_SR               (SAM4_PMC_BASE + 0x0068)\n\tuint32_t PMC_SR;\n#define SAM4_PMC_IMR              (SAM4_PMC_BASE + 0x006c)\n\tuint32_t PMC_IMR;\n#define SAM4_PMC_FSMR             (SAM4_PMC_BASE + 0x0070)\n\tuint32_t PMC_FSMR;\n#define SAM4_PMC_FSPR             (SAM4_PMC_BASE + 0x0074)\n\tuint32_t PMC_FSPR;\n};\n\nstruct sam4_bank_private {\n\tbool probed;\n\t/* DANGER: THERE ARE DRAGONS HERE.. */\n\t/* NOTE: If you add more 'ghost' pointers */\n\t/* be aware that you must *manually* update */\n\t/* these pointers in the function sam4_get_details() */\n\t/* See the comment \"Here there be dragons\" */\n\n\t/* so we can find the chip we belong to */\n\tstruct sam4_chip *chip;\n\t/* so we can find the original bank pointer */\n\tstruct flash_bank *bank;\n\tunsigned bank_number;\n\tuint32_t controller_address;\n\tuint32_t base_address;\n\tuint32_t flash_wait_states;\n\tbool present;\n\tunsigned size_bytes;\n\tunsigned nsectors;\n\tunsigned sector_size;\n\tunsigned page_size;\n};\n\nstruct sam4_chip_details {\n\t/* THERE ARE DRAGONS HERE.. */\n\t/* note: If you add pointers here */\n\t/* be careful about them as they */\n\t/* may need to be updated inside */\n\t/* the function: \"sam4_get_details() */\n\t/* which copy/overwrites the */\n\t/* 'runtime' copy of this structure */\n\tuint32_t chipid_cidr;\n\tconst char *name;\n\n\tunsigned n_gpnvms;\n#define SAM4_N_NVM_BITS 3\n\tunsigned gpnvm[SAM4_N_NVM_BITS];\n\tunsigned total_flash_size;\n\tunsigned total_sram_size;\n\tunsigned n_banks;\n#define SAM4_MAX_FLASH_BANKS 2\n\t/* these are \"initialized\" from the global const data */\n\tstruct sam4_bank_private bank[SAM4_MAX_FLASH_BANKS];\n};\n\nstruct sam4_chip {\n\tstruct sam4_chip *next;\n\tbool probed;\n\n\t/* this is \"initialized\" from the global const structure */\n\tstruct sam4_chip_details details;\n\tstruct target *target;\n\tstruct sam4_cfg cfg;\n};\n\n\nstruct sam4_reg_list {\n\tuint32_t address;  size_t struct_offset; const char *name;\n\tvoid (*explain_func)(struct sam4_chip *chip);\n};\n\nstatic struct sam4_chip *all_sam4_chips;\n\nstatic struct sam4_chip *get_current_sam4(struct command_invocation *cmd)\n{\n\tstruct target *t;\n\tstatic struct sam4_chip *p;\n\n\tt = get_current_target(cmd->ctx);\n\tif (!t) {\n\t\tcommand_print_sameline(cmd, \"No current target?\\n\");\n\t\treturn NULL;\n\t}\n\n\tp = all_sam4_chips;\n\tif (!p) {\n\t\t/* this should not happen */\n\t\t/* the command is not registered until the chip is created? */\n\t\tcommand_print_sameline(cmd, \"No SAM4 chips exist?\\n\");\n\t\treturn NULL;\n\t}\n\n\twhile (p) {\n\t\tif (p->target == t)\n\t\t\treturn p;\n\t\tp = p->next;\n\t}\n\tcommand_print_sameline(cmd, \"Cannot find SAM4 chip?\\n\");\n\treturn NULL;\n}\n\n/*The actual sector size of the SAM4S flash memory is 65536 bytes. 16 sectors for a 1024KB device*/\n/*The lockregions are 8KB per lock region, with a 1024KB device having 128 lock regions. */\n/*For the best results, nsectors are thus set to the amount of lock regions, and the sector_size*/\n/*set to the lock region size.  Page erases are used to erase 8KB sections when programming*/\n\n/* these are used to *initialize* the \"chip->details\" structure. */\nstatic const struct sam4_chip_details all_sam4_details[] = {\n\t/* Start at91sam4c* series */\n\t/* at91sam4c32e - LQFP144 */\n\t{\n\t\t.chipid_cidr    = 0xA66D0EE0,\n\t\t.name           = \"at91sam4c32e\",\n\t\t.total_flash_size     = 2024 * 1024,\n\t\t.total_sram_size      = 256 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_C32,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_C32,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\t/* at91sam4c32c - LQFP100 */\n\t{\n\t\t.chipid_cidr    = 0xA64D0EE0,\n\t\t.name           = \"at91sam4c32c\",\n\t\t.total_flash_size     = 2024 * 1024,\n\t\t.total_sram_size      = 256 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_C32,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_C32,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\t/* at91sam4c16c - LQFP100 */\n\t{\n\t\t.chipid_cidr    = 0xA64C0CE0,\n\t\t.name           = \"at91sam4c16c\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_C,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/* at91sam4c8c - LQFP100 */\n\t{\n\t\t.chipid_cidr    = 0xA64C0AE0,\n\t\t.name           = \"at91sam4c8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_C,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/* at91sam4c4c (rev B) - LQFP100 */\n\t{\n\t\t.chipid_cidr    = 0xA64C0CE5,\n\t\t.name           = \"at91sam4c4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_C,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  32,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/* Start at91sam4e* series */\n\t/*atsam4e16e - LQFP144/LFBGA144*/\n\t{\n\t\t.chipid_cidr    = 0xA3CC0CE0,\n\t\t.name           = \"at91sam4e16e\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/* Start at91sam4n* series */\n\t/*atsam4n8a - LQFP48/QFN48*/\n\t{\n\t\t.chipid_cidr    = 0x293B0AE0,\n\t\t.name           = \"at91sam4n8a\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4n8b - LQFP64/QFN64*/\n\t{\n\t\t.chipid_cidr    = 0x294B0AE0,\n\t\t.name           = \"at91sam4n8b\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4n8c - LQFP100/TFBGA100/VFBGA100*/\n\t{\n\t\t.chipid_cidr    = 0x295B0AE0,\n\t\t.name           = \"at91sam4n8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4n16b - LQFP64/QFN64*/\n\t{\n\t\t.chipid_cidr    = 0x29460CE0,\n\t\t.name           = \"at91sam4n16b\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 80 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4n16c - LQFP100/TFBGA100/VFBGA100*/\n\t{\n\t\t.chipid_cidr    = 0x29560CE0,\n\t\t.name           = \"at91sam4n16c\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 80 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/* Start at91sam4s* series */\n\t/*atsam4s16c - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x28AC0CE0,\n\t\t.name           = \"at91sam4s16c\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*at91sam4sa16c - TFBGA100/VFBGA100/LQFP100*/\n\t{\n\t\t.chipid_cidr    = 0x28a70ce0,\n\t\t.name           = \"at91sam4sa16c\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4s16b - LQFP64/QFN64/WLCSP64*/\n\t{\n\t\t.chipid_cidr    = 0x289C0CE0,\n\t\t.name           = \"at91sam4s16b\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4sa16b - LQFP64/QFN64*/\n\t{\n\t\t.chipid_cidr    = 0x28970CE0,\n\t\t.name           = \"at91sam4sa16b\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4s16a - LQFP48/QFN48*/\n\t{\n\t\t.chipid_cidr    = 0x288C0CE0,\n\t\t.name           = \"at91sam4s16a\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t.nsectors   =  128,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4s8c - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x28AC0AE0,\n\t\t.name           = \"at91sam4s8c\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4s8b - LQFP64/QFN64/WLCSP64*/\n\t{\n\t\t.chipid_cidr    = 0x289C0AE0,\n\t\t.name           = \"at91sam4s8b\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\t/*atsam4s8a - LQFP48/BGA48*/\n\t{\n\t\t.chipid_cidr    = 0x288C0AE0,\n\t\t.name           = \"at91sam4s8a\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 128 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  512 * 1024,\n\t\t\t.nsectors   =  64,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s4c - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x28ab09e0,\n\t\t.name           = \"at91sam4s4c\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  32,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s4b - LQFP64/QFN64/WLCSP64*/\n\t{\n\t\t.chipid_cidr    = 0x289b09e0,\n\t\t.name           = \"at91sam4s4b\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  32,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s4a - LQFP48/QFN48*/\n\t{\n\t\t.chipid_cidr    = 0x288b09e0,\n\t\t.name           = \"at91sam4s4a\",\n\t\t.total_flash_size     = 256 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  256 * 1024,\n\t\t\t.nsectors   =  32,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s2c - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x28ab07e0,\n\t\t.name           = \"at91sam4s2c\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s2b - LQPF64/QFN64/WLCSP64*/\n\t{\n\t\t.chipid_cidr    = 0x289b07e0,\n\t\t.name           = \"at91sam4s2b\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*atsam4s2a - LQFP48/QFN48*/\n\t{\n\t\t.chipid_cidr    = 0x288b07e0,\n\t\t.name           = \"at91sam4s2a\",\n\t\t.total_flash_size     = 128 * 1024,\n\t\t.total_sram_size      = 64 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\t\t{\n/*\t\t.bank[0] = {*/\n\t\t  {\n\t\t\t.probed = false,\n\t\t\t.chip  = NULL,\n\t\t\t.bank  = NULL,\n\t\t\t.bank_number = 0,\n\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t.controller_address = 0x400e0a00,\n\t\t\t.flash_wait_states = 5,\n\t\t\t.present = true,\n\t\t\t.size_bytes =  128 * 1024,\n\t\t\t.nsectors   =  16,\n\t\t\t.sector_size = 8192,\n\t\t\t.page_size   = 512,\n\t\t  },\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t},\n\t},\n\n\t/*at91sam4sd32c  - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x29a70ee0,\n\t\t.name           = \"at91sam4sd32c\",\n\t\t.total_flash_size     = 2048 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_2048K_SD,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\n\t/*at91sam4sd32b  - LQFP64/BGA64*/\n\t{\n\t\t.chipid_cidr    = 0x29970ee0,\n\t\t.name           = \"at91sam4sd32b\",\n\t\t.total_flash_size     = 2048 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_2048K_SD,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  1024 * 1024,\n\t\t\t\t.nsectors   =  128,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\n\t/*at91sam4sd16c - LQFP100/BGA100*/\n\t{\n\t\t.chipid_cidr    = 0x29a70ce0,\n\t\t.name           = \"at91sam4sd16c\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_1024K_SD,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\n\t/*at91sam4sd16b - LQFP64/BGA64*/\n\t{\n\t\t.chipid_cidr    = 0x29970ce0,\n\t\t.name           = \"at91sam4sd16b\",\n\t\t.total_flash_size     = 1024 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 3,\n\t\t.n_banks        = 2,\n\n/*\t\t.bank[0] = { */\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK0_BASE_SD,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\n/*\t\t.bank[1] = { */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 1,\n\t\t\t\t.base_address = FLASH_BANK1_BASE_1024K_SD,\n\t\t\t\t.controller_address = 0x400e0c00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n\t\t},\n\t},\n\n\t/* atsamg53n19 */\n\t{\n\t\t.chipid_cidr    = 0x247e0ae0,\n\t\t.name           = \"atsamg53n19\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 96 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n/*\t\t.bank[0] = {*/\n\t\t{\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t.bank[1] = {*/\n\t\t  {\n\t\t\t.present = false,\n\t\t\t.probed = false,\n\t\t\t.bank_number = 1,\n\n\t\t  },\n\t\t}\n\t},\n\n\t/* atsamg55g19 Rev.A */\n\t{\n\t\t.chipid_cidr    = 0x24470ae0,\n\t\t.name           = \"atsamg55g19\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t{\n/*\t\t\t.bank[0] = */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t\t.bank[1] = */\n\t\t\t{\n\t\t\t\t.present = false,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t}\n\t},\n\n\t/* atsamg55g19 Rev.B */\n\t{\n\t\t.chipid_cidr    = 0x24470ae1,\n\t\t.name           = \"atsamg55g19b\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t{\n/*\t\t\t.bank[0] = */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t\t.bank[1] = */\n\t\t\t{\n\t\t\t\t.present = false,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t}\n\t},\n\n\t/* atsamg55j19 Rev.A */\n\t{\n\t\t.chipid_cidr    = 0x24570ae0,\n\t\t.name           = \"atsamg55j19\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t{\n/*\t\t\t.bank[0] = */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t\t.bank[1] = */\n\t\t\t{\n\t\t\t\t.present = false,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t}\n\t},\n\n\t/* atsamg55j19 Rev.B */\n\t{\n\t\t.chipid_cidr    = 0x24570ae1,\n\t\t.name           = \"atsamg55j19b\",\n\t\t.total_flash_size     = 512 * 1024,\n\t\t.total_sram_size      = 160 * 1024,\n\t\t.n_gpnvms       = 2,\n\t\t.n_banks        = 1,\n\n\t\t{\n/*\t\t\t.bank[0] = */\n\t\t\t{\n\t\t\t\t.probed = false,\n\t\t\t\t.chip  = NULL,\n\t\t\t\t.bank  = NULL,\n\t\t\t\t.bank_number = 0,\n\t\t\t\t.base_address = FLASH_BANK_BASE_S,\n\t\t\t\t.controller_address = 0x400e0a00,\n\t\t\t\t.flash_wait_states = 5,\n\t\t\t\t.present = true,\n\t\t\t\t.size_bytes =  512 * 1024,\n\t\t\t\t.nsectors   =  64,\n\t\t\t\t.sector_size = 8192,\n\t\t\t\t.page_size   = 512,\n\t\t\t},\n/*\t\t\t.bank[1] = */\n\t\t\t{\n\t\t\t\t.present = false,\n\t\t\t\t.probed = false,\n\t\t\t\t.bank_number = 1,\n\t\t\t},\n\t\t}\n\t},\n\n\t/* terminate */\n\t{\n\t\t.chipid_cidr    = 0,\n\t\t.name                   = NULL,\n\t}\n};\n\n/* Globals above */\n/***********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************\n **********************************************************************/\n/* *ATMEL* style code - from the SAM4 driver code */\n\n/**\n * Get the current status of the EEFC and\n * the value of some status bits (LOCKE, PROGE).\n * @param private  - info about the bank\n * @param v        - result goes here\n */\nstatic int efc_get_status(struct sam4_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tr = target_read_u32(private->chip->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FSR,\n\t\t\tv);\n\tLOG_DEBUG(\"Status: 0x%08x (lockerror: %d, cmderror: %d, ready: %d)\",\n\t\t(unsigned int)(*v),\n\t\t((unsigned int)((*v >> 2) & 1)),\n\t\t((unsigned int)((*v >> 1) & 1)),\n\t\t((unsigned int)((*v >> 0) & 1)));\n\n\treturn r;\n}\n\n/**\n * Get the result of the last executed command.\n * @param private  - info about the bank\n * @param v        - result goes here\n */\nstatic int efc_get_result(struct sam4_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tuint32_t rv;\n\tr = target_read_u32(private->chip->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FRR,\n\t\t\t&rv);\n\tif (v)\n\t\t*v = rv;\n\tLOG_DEBUG(\"Result: 0x%08x\", ((unsigned int)(rv)));\n\treturn r;\n}\n\nstatic int efc_start_command(struct sam4_bank_private *private,\n\tunsigned command, unsigned argument)\n{\n\tuint32_t n, v;\n\tint r;\n\tint retry;\n\n\tretry = 0;\ndo_retry:\n\n\t/* Check command & argument */\n\tswitch (command) {\n\n\t\tcase AT91C_EFC_FCMD_WP:\n\t\tcase AT91C_EFC_FCMD_WPL:\n\t\tcase AT91C_EFC_FCMD_EWP:\n\t\tcase AT91C_EFC_FCMD_EWPL:\n\t\t/* case AT91C_EFC_FCMD_EPL: */\n\t\tcase AT91C_EFC_FCMD_EPA:\n\t\tcase AT91C_EFC_FCMD_SLB:\n\t\tcase AT91C_EFC_FCMD_CLB:\n\t\t\tn = (private->size_bytes / private->page_size);\n\t\t\tif (argument >= n)\n\t\t\t\tLOG_ERROR(\"*BUG*: Embedded flash has only %u pages\", (unsigned)(n));\n\t\t\tbreak;\n\n\t\tcase AT91C_EFC_FCMD_SFB:\n\t\tcase AT91C_EFC_FCMD_CFB:\n\t\t\tif (argument >= private->chip->details.n_gpnvms) {\n\t\t\t\tLOG_ERROR(\"*BUG*: Embedded flash has only %d GPNVMs\",\n\t\t\t\t\t\tprivate->chip->details.n_gpnvms);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase AT91C_EFC_FCMD_GETD:\n\t\tcase AT91C_EFC_FCMD_EA:\n\t\tcase AT91C_EFC_FCMD_GLB:\n\t\tcase AT91C_EFC_FCMD_GFB:\n\t\tcase AT91C_EFC_FCMD_STUI:\n\t\tcase AT91C_EFC_FCMD_SPUI:\n\t\t\tif (argument != 0)\n\t\t\t\tLOG_ERROR(\"Argument is meaningless for cmd: %d\", command);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unknown command %d\", command);\n\t\t\tbreak;\n\t}\n\n\tif (command == AT91C_EFC_FCMD_SPUI) {\n\t\t/* this is a very special situation. */\n\t\t/* Situation (1) - error/retry - see below */\n\t\t/*      And we are being called recursively */\n\t\t/* Situation (2) - normal, finished reading unique id */\n\t} else {\n\t\t/* it should be \"ready\" */\n\t\tefc_get_status(private, &v);\n\t\tif (v & 1) {\n\t\t\t/* then it is ready */\n\t\t\t/* we go on */\n\t\t} else {\n\t\t\tif (retry) {\n\t\t\t\t/* we have done this before */\n\t\t\t\t/* the controller is not responding. */\n\t\t\t\tLOG_ERROR(\"flash controller(%d) is not ready! Error\",\n\t\t\t\t\tprivate->bank_number);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t} else {\n\t\t\t\tretry++;\n\t\t\t\tLOG_ERROR(\"Flash controller(%d) is not ready, attempting reset\",\n\t\t\t\t\tprivate->bank_number);\n\t\t\t\t/* we do that by issuing the *STOP* command */\n\t\t\t\tefc_start_command(private, AT91C_EFC_FCMD_SPUI, 0);\n\t\t\t\t/* above is recursive, and further recursion is blocked by */\n\t\t\t\t/* if (command == AT91C_EFC_FCMD_SPUI) above */\n\t\t\t\tgoto do_retry;\n\t\t\t}\n\t\t}\n\t}\n\n\tv = (0x5A << 24) | (argument << 8) | command;\n\tLOG_DEBUG(\"Command: 0x%08x\", ((unsigned int)(v)));\n\tr = target_write_u32(private->bank->target,\n\t\t\tprivate->controller_address + OFFSET_EFC_FCR, v);\n\tif (r != ERROR_OK)\n\t\tLOG_DEBUG(\"Error Write failed\");\n\treturn r;\n}\n\n/**\n * Performs the given command and wait until its completion (or an error).\n * @param private  - info about the bank\n * @param command  - Command to perform.\n * @param argument - Optional command argument.\n * @param status   - put command status bits here\n */\nstatic int efc_perform_command(struct sam4_bank_private *private,\n\tunsigned command,\n\tunsigned argument,\n\tuint32_t *status)\n{\n\n\tint r;\n\tuint32_t v;\n\tint64_t ms_now, ms_end;\n\n\t/* default */\n\tif (status)\n\t\t*status = 0;\n\n\tr = efc_start_command(private, command, argument);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tms_end = 10000 + timeval_ms();\n\n\tdo {\n\t\tr = efc_get_status(private, &v);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tms_now = timeval_ms();\n\t\tif (ms_now > ms_end) {\n\t\t\t/* error */\n\t\t\tLOG_ERROR(\"Command timeout\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while ((v & 1) == 0);\n\n\t/* error bits.. */\n\tif (status)\n\t\t*status = (v & 0x6);\n\treturn ERROR_OK;\n\n}\n\n/**\n * Read the unique ID.\n * @param private - info about the bank\n * The unique ID is stored in the 'private' structure.\n */\nstatic int flashd_read_uid(struct sam4_bank_private *private)\n{\n\tint r;\n\tuint32_t v;\n\tint x;\n\t/* assume 0 */\n\tprivate->chip->cfg.unique_id[0] = 0;\n\tprivate->chip->cfg.unique_id[1] = 0;\n\tprivate->chip->cfg.unique_id[2] = 0;\n\tprivate->chip->cfg.unique_id[3] = 0;\n\n\tLOG_DEBUG(\"Begin\");\n\tr = efc_start_command(private, AT91C_EFC_FCMD_STUI, 0);\n\tif (r < 0)\n\t\treturn r;\n\n\tfor (x = 0; x < 4; x++) {\n\t\tr = target_read_u32(private->chip->target,\n\t\t\t\tprivate->bank->base + (x * 4),\n\t\t\t\t&v);\n\t\tif (r < 0)\n\t\t\treturn r;\n\t\tprivate->chip->cfg.unique_id[x] = v;\n\t}\n\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_SPUI, 0, NULL);\n\tLOG_DEBUG(\"End: R=%d, id = 0x%08x, 0x%08x, 0x%08x, 0x%08x\",\n\t\tr,\n\t\t(unsigned int)(private->chip->cfg.unique_id[0]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[1]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[2]),\n\t\t(unsigned int)(private->chip->cfg.unique_id[3]));\n\treturn r;\n\n}\n\n/**\n * Erases the entire flash.\n * @param private - the info about the bank.\n */\nstatic int flashd_erase_entire_bank(struct sam4_bank_private *private)\n{\n\tLOG_DEBUG(\"Here\");\n\treturn efc_perform_command(private, AT91C_EFC_FCMD_EA, 0, NULL);\n}\n\n/**\n * Erases the entire flash.\n * @param private - the info about the bank.\n * @param first_page\n * @param num_pages\n * @param status\n */\nstatic int flashd_erase_pages(struct sam4_bank_private *private,\n\t\t\t\t\t\t\t int first_page,\n\t\t\t\t\t\t\t int num_pages,\n\t\t\t\t\t\t\t uint32_t *status)\n{\n\tLOG_DEBUG(\"Here\");\n\tuint8_t erase_pages;\n\tswitch (num_pages)\t{\n\t\tcase 4:\n\t\t\terase_pages = 0x00;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\terase_pages = 0x01;\n\t\t\tbreak;\n\t\tcase 16:\n\t\t\terase_pages = 0x02;\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\terase_pages = 0x03;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terase_pages = 0x00;\n\t\t\tbreak;\n\t}\n\n\t/* AT91C_EFC_FCMD_EPA\n\t * According to the datasheet FARG[15:2] defines the page from which\n\t * the erase will start.This page must be modulo 4, 8, 16 or 32\n\t * according to the number of pages to erase. FARG[1:0] defines the\n\t * number of pages to be erased. Previously (firstpage << 2) was used\n\t * to conform to this, seems it should not be shifted...\n\t */\n\treturn efc_perform_command(private,\n\t\t/* send Erase Page */\n\t\tAT91C_EFC_FCMD_EPA,\n\t\t(first_page) | erase_pages,\n\t\tstatus);\n}\n\n/**\n * Gets current GPNVM state.\n * @param private  - info about the bank.\n * @param gpnvm    -  GPNVM bit index.\n * @param puthere  - result stored here.\n */\n/* ------------------------------------------------------------------------------ */\nstatic int flashd_get_gpnvm(struct sam4_bank_private *private, unsigned gpnvm, unsigned *puthere)\n{\n\tuint32_t v;\n\tint r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Get GPNVMs status */\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_GFB, 0, NULL);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed\");\n\t\treturn r;\n\t}\n\n\tr = efc_get_result(private, &v);\n\n\tif (puthere) {\n\t\t/* Check if GPNVM is set */\n\t\t/* get the bit and make it a 0/1 */\n\t\t*puthere = (v >> gpnvm) & 1;\n\t}\n\n\treturn r;\n}\n\n/**\n * Clears the selected GPNVM bit.\n * @param private info about the bank\n * @param gpnvm GPNVM index.\n * @returns 0 if successful; otherwise returns an error code.\n */\nstatic int flashd_clr_gpnvm(struct sam4_bank_private *private, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = flashd_get_gpnvm(private, gpnvm, &v);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed: %d\", r);\n\t\treturn r;\n\t}\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_CFB, gpnvm, NULL);\n\tLOG_DEBUG(\"End: %d\", r);\n\treturn r;\n}\n\n/**\n * Sets the selected GPNVM bit.\n * @param private info about the bank\n * @param gpnvm GPNVM index.\n */\nstatic int flashd_set_gpnvm(struct sam4_bank_private *private, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\n\tif (private->bank_number != 0) {\n\t\tLOG_ERROR(\"GPNVM only works with Bank0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (gpnvm >= private->chip->details.n_gpnvms) {\n\t\tLOG_ERROR(\"Invalid GPNVM %d, max: %d, ignored\",\n\t\t\tgpnvm, private->chip->details.n_gpnvms);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = flashd_get_gpnvm(private, gpnvm, &v);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\tif (v) {\n\t\t/* already set */\n\t\tr = ERROR_OK;\n\t} else {\n\t\t/* set it */\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_SFB, gpnvm, NULL);\n\t}\n\treturn r;\n}\n\n/**\n * Returns a bit field (at most 64) of locked regions within a page.\n * @param private info about the bank\n * @param v where to store locked bits\n */\nstatic int flashd_get_lock_bits(struct sam4_bank_private *private, uint32_t *v)\n{\n\tint r;\n\tLOG_DEBUG(\"Here\");\n\tr = efc_perform_command(private, AT91C_EFC_FCMD_GLB, 0, NULL);\n\tif (r == ERROR_OK)\t{\n\t\tefc_get_result(private, v);\n\t\tefc_get_result(private, v);\n\t\tefc_get_result(private, v);\n\t\tr = efc_get_result(private, v);\n\t}\n\tLOG_DEBUG(\"End: %d\", r);\n\treturn r;\n}\n\n/**\n * Unlocks all the regions in the given address range.\n * @param private info about the bank\n * @param start_sector first sector to unlock\n * @param end_sector last (inclusive) to unlock\n */\n\nstatic int flashd_unlock(struct sam4_bank_private *private,\n\tunsigned start_sector,\n\tunsigned end_sector)\n{\n\tint r;\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\n\tpages_per_sector = private->sector_size / private->page_size;\n\n\t/* Unlock all pages */\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_CLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Locks regions\n * @param private - info about the bank\n * @param start_sector - first sector to lock\n * @param end_sector   - last sector (inclusive) to lock\n */\nstatic int flashd_lock(struct sam4_bank_private *private,\n\tunsigned start_sector,\n\tunsigned end_sector)\n{\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\tint r;\n\n\tpages_per_sector = private->sector_size / private->page_size;\n\n\t/* Lock all pages */\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\n\t\tr = efc_perform_command(private, AT91C_EFC_FCMD_SLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\treturn ERROR_OK;\n}\n\n/****** END SAM4 CODE ********/\n\n/* begin helpful debug code */\n/* print the fieldname, the field value, in dec & hex, and return field value */\nstatic uint32_t sam4_reg_fieldname(struct sam4_chip *chip,\n\tconst char *regname,\n\tuint32_t value,\n\tunsigned shift,\n\tunsigned width)\n{\n\tuint32_t v;\n\tint hwidth, dwidth;\n\n\n\t/* extract the field */\n\tv = value >> shift;\n\tv = v & ((1 << width)-1);\n\tif (width <= 16) {\n\t\thwidth = 4;\n\t\tdwidth = 5;\n\t} else {\n\t\thwidth = 8;\n\t\tdwidth = 12;\n\t}\n\n\t/* show the basics */\n\tLOG_USER_N(\"\\t%*s: %*\" PRIu32 \" [0x%0*\" PRIx32 \"] \",\n\t\tREG_NAME_WIDTH, regname,\n\t\tdwidth, v,\n\t\thwidth, v);\n\treturn v;\n}\n\nstatic const char _unknown[] = \"unknown\";\nstatic const char *const eproc_names[] = {\n\t\"Cortex-M7\",\t\t\t\t/* 0 */\n\t\"arm946es\",\t\t\t\t\t/* 1 */\n\t\"arm7tdmi\",\t\t\t\t\t/* 2 */\n\t\"Cortex-M3\",\t\t\t\t/* 3 */\n\t\"arm920t\",\t\t\t\t\t/* 4 */\n\t\"arm926ejs\",\t\t\t\t/* 5 */\n\t\"Cortex-A5\",\t\t\t\t/* 6 */\n\t\"Cortex-M4\",\t\t\t\t/* 7 */\n\t_unknown,\t\t\t\t\t/* 8 */\n\t_unknown,\t\t\t\t\t/* 9 */\n\t_unknown,\t\t\t\t\t/* 10 */\n\t_unknown,\t\t\t\t\t/* 11 */\n\t_unknown,\t\t\t\t\t/* 12 */\n\t_unknown,\t\t\t\t\t/* 13 */\n\t_unknown,\t\t\t\t\t/* 14 */\n\t_unknown,\t\t\t\t\t/* 15 */\n};\n\n#define nvpsize2 nvpsize\t\t/* these two tables are identical */\nstatic const char *const nvpsize[] = {\n\t\"none\",\t\t\t\t\t\t/*  0 */\n\t\"8K bytes\",\t\t\t\t\t/*  1 */\n\t\"16K bytes\",\t\t\t\t/*  2 */\n\t\"32K bytes\",\t\t\t\t/*  3 */\n\t_unknown,\t\t\t\t\t/*  4 */\n\t\"64K bytes\",\t\t\t\t/*  5 */\n\t_unknown,\t\t\t\t\t/*  6 */\n\t\"128K bytes\",\t\t\t\t/*  7 */\n\t\"160K bytes\",\t\t\t\t/*  8 */\n\t\"256K bytes\",\t\t\t\t/*  9 */\n\t\"512K bytes\",\t\t\t\t/* 10 */\n\t_unknown,\t\t\t\t\t/* 11 */\n\t\"1024K bytes\",\t\t\t\t/* 12 */\n\t_unknown,\t\t\t\t\t/* 13 */\n\t\"2048K bytes\",\t\t\t\t/* 14 */\n\t_unknown,\t\t\t\t\t/* 15 */\n};\n\nstatic const char *const sramsize[] = {\n\t\"48K Bytes\",\t\t\t\t/*  0 */\n\t\"1K Bytes\",\t\t\t\t\t/*  1 */\n\t\"2K Bytes\",\t\t\t\t\t/*  2 */\n\t\"6K Bytes\",\t\t\t\t\t/*  3 */\n\t\"112K Bytes\",\t\t\t\t/*  4 */\n\t\"4K Bytes\",\t\t\t\t\t/*  5 */\n\t\"80K Bytes\",\t\t\t\t/*  6 */\n\t\"160K Bytes\",\t\t\t\t/*  7 */\n\t\"8K Bytes\",\t\t\t\t\t/*  8 */\n\t\"16K Bytes\",\t\t\t\t/*  9 */\n\t\"32K Bytes\",\t\t\t\t/* 10 */\n\t\"64K Bytes\",\t\t\t\t/* 11 */\n\t\"128K Bytes\",\t\t\t\t/* 12 */\n\t\"256K Bytes\",\t\t\t\t/* 13 */\n\t\"96K Bytes\",\t\t\t\t/* 14 */\n\t\"512K Bytes\",\t\t\t\t/* 15 */\n\n};\n\nstatic const struct archnames { unsigned value; const char *name; } archnames[] = {\n\t{ 0x19,  \"AT91SAM9xx Series\"                                            },\n\t{ 0x29,  \"AT91SAM9XExx Series\"                                          },\n\t{ 0x34,  \"AT91x34 Series\"                                                       },\n\t{ 0x37,  \"CAP7 Series\"                                                          },\n\t{ 0x39,  \"CAP9 Series\"                                                          },\n\t{ 0x3B,  \"CAP11 Series\"                                                         },\n\t{ 0x3C, \"ATSAM4E\"                                                               },\n\t{ 0x40,  \"AT91x40 Series\"                                                       },\n\t{ 0x42,  \"AT91x42 Series\"                                                       },\n\t{ 0x43,  \"SAMG51 Series\"\n\t},\n\t{ 0x44,  \"SAMG55 Series (49-pin WLCSP)\"                                         },\n\t{ 0x45,  \"SAMG55 Series (64-pin)\"                                                        },\n\t{ 0x47,  \"SAMG53 Series\"\n\t},\n\t{ 0x55,  \"AT91x55 Series\"                                                       },\n\t{ 0x60,  \"AT91SAM7Axx Series\"                                           },\n\t{ 0x61,  \"AT91SAM7AQxx Series\"                                          },\n\t{ 0x63,  \"AT91x63 Series\"                                                       },\n\t{ 0x64,  \"SAM4CxxC (100-pin version)\"                                           },\n\t{ 0x66,  \"SAM4CxxE (144-pin version)\"                                           },\n\t{ 0x70,  \"AT91SAM7Sxx Series\"                                           },\n\t{ 0x71,  \"AT91SAM7XCxx Series\"                                          },\n\t{ 0x72,  \"AT91SAM7SExx Series\"                                          },\n\t{ 0x73,  \"AT91SAM7Lxx Series\"                                           },\n\t{ 0x75,  \"AT91SAM7Xxx Series\"                                           },\n\t{ 0x76,  \"AT91SAM7SLxx Series\"                                          },\n\t{ 0x80,  \"ATSAM3UxC Series (100-pin version)\"           },\n\t{ 0x81,  \"ATSAM3UxE Series (144-pin version)\"           },\n\t{ 0x83,  \"ATSAM3A/SAM4A xC Series (100-pin version)\"},\n\t{ 0x84,  \"ATSAM3X/SAM4X xC Series (100-pin version)\"},\n\t{ 0x85,  \"ATSAM3X/SAM4X xE Series (144-pin version)\"},\n\t{ 0x86,  \"ATSAM3X/SAM4X xG Series (208/217-pin version)\"\t},\n\t{ 0x88,  \"ATSAM3S/SAM4S xA Series (48-pin version)\"\t},\n\t{ 0x89,  \"ATSAM3S/SAM4S xB Series (64-pin version)\"\t},\n\t{ 0x8A,  \"ATSAM3S/SAM4S xC Series (100-pin version)\"},\n\t{ 0x92,  \"AT91x92 Series\"                                                       },\n\t{ 0x93,  \"ATSAM3NxA Series (48-pin version)\"            },\n\t{ 0x94,  \"ATSAM3NxB Series (64-pin version)\"            },\n\t{ 0x95,  \"ATSAM3NxC Series (100-pin version)\"           },\n\t{ 0x98,  \"ATSAM3SDxA Series (48-pin version)\"           },\n\t{ 0x99,  \"ATSAM3SDxB Series (64-pin version)\"           },\n\t{ 0x9A,  \"ATSAM3SDxC Series (100-pin version)\"          },\n\t{ 0xA5,  \"ATSAM5A\"                                                              },\n\t{ 0xF0,  \"AT75Cxx Series\"                                                       },\n\t{ -1, NULL },\n};\n\nstatic const char *const nvptype[] = {\n\t\"rom\",\t/* 0 */\n\t\"romless or onchip flash\",\t/* 1 */\n\t\"embedded flash memory\",/* 2 */\n\t\"rom(nvpsiz) + embedded flash (nvpsiz2)\",\t/* 3 */\n\t\"sram emulating flash\",\t/* 4 */\n\t_unknown,\t/* 5 */\n\t_unknown,\t/* 6 */\n\t_unknown,\t/* 7 */\n};\n\nstatic const char *_yes_or_no(uint32_t v)\n{\n\tif (v)\n\t\treturn \"YES\";\n\telse\n\t\treturn \"NO\";\n}\n\nstatic const char *const _rc_freq[] = {\n\t\"4 MHz\", \"8 MHz\", \"12 MHz\", \"reserved\"\n};\n\nstatic void sam4_explain_ckgr_mor(struct sam4_chip *chip)\n{\n\tuint32_t v;\n\tuint32_t rcen;\n\n\tv = sam4_reg_fieldname(chip, \"MOSCXTEN\", chip->cfg.CKGR_MOR, 0, 1);\n\tLOG_USER(\"(main xtal enabled: %s)\", _yes_or_no(v));\n\tv = sam4_reg_fieldname(chip, \"MOSCXTBY\", chip->cfg.CKGR_MOR, 1, 1);\n\tLOG_USER(\"(main osc bypass: %s)\", _yes_or_no(v));\n\trcen = sam4_reg_fieldname(chip, \"MOSCRCEN\", chip->cfg.CKGR_MOR, 3, 1);\n\tLOG_USER(\"(onchip RC-OSC enabled: %s)\", _yes_or_no(rcen));\n\tv = sam4_reg_fieldname(chip, \"MOSCRCF\", chip->cfg.CKGR_MOR, 4, 3);\n\tLOG_USER(\"(onchip RC-OSC freq: %s)\", _rc_freq[v]);\n\n\tchip->cfg.rc_freq = 0;\n\tif (rcen) {\n\t\tswitch (v) {\n\t\t\tdefault:\n\t\t\t\tchip->cfg.rc_freq = 0;\n\t\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\t\tchip->cfg.rc_freq = 4 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tchip->cfg.rc_freq = 8 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tchip->cfg.rc_freq = 12 * 1000 * 1000;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tv = sam4_reg_fieldname(chip, \"MOSCXTST\", chip->cfg.CKGR_MOR, 8, 8);\n\tLOG_USER(\"(startup clks, time= %f uSecs)\",\n\t\t((float)(v * 1000000)) / ((float)(chip->cfg.slow_freq)));\n\tv = sam4_reg_fieldname(chip, \"MOSCSEL\", chip->cfg.CKGR_MOR, 24, 1);\n\tLOG_USER(\"(mainosc source: %s)\",\n\t\tv ? \"external xtal\" : \"internal RC\");\n\n\tv = sam4_reg_fieldname(chip, \"CFDEN\", chip->cfg.CKGR_MOR, 25, 1);\n\tLOG_USER(\"(clock failure enabled: %s)\",\n\t\t_yes_or_no(v));\n}\n\nstatic void sam4_explain_chipid_cidr(struct sam4_chip *chip)\n{\n\tint x;\n\tuint32_t v;\n\tconst char *cp;\n\n\tsam4_reg_fieldname(chip, \"Version\", chip->cfg.CHIPID_CIDR, 0, 5);\n\tLOG_USER_N(\"\\n\");\n\n\tv = sam4_reg_fieldname(chip, \"EPROC\", chip->cfg.CHIPID_CIDR, 5, 3);\n\tLOG_USER(\"%s\", eproc_names[v]);\n\n\tv = sam4_reg_fieldname(chip, \"NVPSIZE\", chip->cfg.CHIPID_CIDR, 8, 4);\n\tLOG_USER(\"%s\", nvpsize[v]);\n\n\tv = sam4_reg_fieldname(chip, \"NVPSIZE2\", chip->cfg.CHIPID_CIDR, 12, 4);\n\tLOG_USER(\"%s\", nvpsize2[v]);\n\n\tv = sam4_reg_fieldname(chip, \"SRAMSIZE\", chip->cfg.CHIPID_CIDR, 16, 4);\n\tLOG_USER(\"%s\", sramsize[v]);\n\n\tv = sam4_reg_fieldname(chip, \"ARCH\", chip->cfg.CHIPID_CIDR, 20, 8);\n\tcp = _unknown;\n\tfor (x = 0; archnames[x].name; x++) {\n\t\tif (v == archnames[x].value) {\n\t\t\tcp = archnames[x].name;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tLOG_USER(\"%s\", cp);\n\n\tv = sam4_reg_fieldname(chip, \"NVPTYP\", chip->cfg.CHIPID_CIDR, 28, 3);\n\tLOG_USER(\"%s\", nvptype[v]);\n\n\tv = sam4_reg_fieldname(chip, \"EXTID\", chip->cfg.CHIPID_CIDR, 31, 1);\n\tLOG_USER(\"(exists: %s)\", _yes_or_no(v));\n}\n\nstatic void sam4_explain_ckgr_mcfr(struct sam4_chip *chip)\n{\n\tuint32_t v;\n\n\tv = sam4_reg_fieldname(chip, \"MAINFRDY\", chip->cfg.CKGR_MCFR, 16, 1);\n\tLOG_USER(\"(main ready: %s)\", _yes_or_no(v));\n\n\tv = sam4_reg_fieldname(chip, \"MAINF\", chip->cfg.CKGR_MCFR, 0, 16);\n\n\tv = (v * chip->cfg.slow_freq) / 16;\n\tchip->cfg.mainosc_freq = v;\n\n\tLOG_USER(\"(%3.03f Mhz (%\" PRIu32 \".%03\" PRIu32 \"khz slowclk)\",\n\t\t_tomhz(v),\n\t\t(uint32_t)(chip->cfg.slow_freq / 1000),\n\t\t(uint32_t)(chip->cfg.slow_freq % 1000));\n}\n\nstatic void sam4_explain_ckgr_plla(struct sam4_chip *chip)\n{\n\tuint32_t mula, diva;\n\n\tdiva = sam4_reg_fieldname(chip, \"DIVA\", chip->cfg.CKGR_PLLAR, 0, 8);\n\tLOG_USER_N(\"\\n\");\n\tmula = sam4_reg_fieldname(chip, \"MULA\", chip->cfg.CKGR_PLLAR, 16, 11);\n\tLOG_USER_N(\"\\n\");\n\tchip->cfg.plla_freq = 0;\n\tif (mula == 0)\n\t\tLOG_USER(\"\\tPLLA Freq: (Disabled,mula = 0)\");\n\telse if (diva == 0)\n\t\tLOG_USER(\"\\tPLLA Freq: (Disabled,diva = 0)\");\n\telse if (diva >= 1) {\n\t\tchip->cfg.plla_freq = (chip->cfg.mainosc_freq * (mula + 1) / diva);\n\t\tLOG_USER(\"\\tPLLA Freq: %3.03f MHz\",\n\t\t\t_tomhz(chip->cfg.plla_freq));\n\t}\n}\n\nstatic void sam4_explain_mckr(struct sam4_chip *chip)\n{\n\tuint32_t css, pres, fin = 0;\n\tint pdiv = 0;\n\tconst char *cp = NULL;\n\n\tcss = sam4_reg_fieldname(chip, \"CSS\", chip->cfg.PMC_MCKR, 0, 2);\n\tswitch (css & 3) {\n\t\tcase 0:\n\t\t\tfin = chip->cfg.slow_freq;\n\t\t\tcp = \"slowclk\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tfin = chip->cfg.mainosc_freq;\n\t\t\tcp  = \"mainosc\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tfin = chip->cfg.plla_freq;\n\t\t\tcp  = \"plla\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tif (chip->cfg.CKGR_UCKR & (1 << 16)) {\n\t\t\t\tfin = 480 * 1000 * 1000;\n\t\t\t\tcp = \"upll\";\n\t\t\t} else {\n\t\t\t\tfin = 0;\n\t\t\t\tcp  = \"upll (*ERROR* UPLL is disabled)\";\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t}\n\n\tLOG_USER(\"%s (%3.03f Mhz)\",\n\t\tcp,\n\t\t_tomhz(fin));\n\tpres = sam4_reg_fieldname(chip, \"PRES\", chip->cfg.PMC_MCKR, 4, 3);\n\tswitch (pres & 0x07) {\n\t\tcase 0:\n\t\t\tpdiv = 1;\n\t\t\tcp = \"selected clock\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tpdiv = 2;\n\t\t\tcp = \"clock/2\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tpdiv = 4;\n\t\t\tcp = \"clock/4\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tpdiv = 8;\n\t\t\tcp = \"clock/8\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tpdiv = 16;\n\t\t\tcp = \"clock/16\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tpdiv = 32;\n\t\t\tcp = \"clock/32\";\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tpdiv = 64;\n\t\t\tcp = \"clock/64\";\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tpdiv = 6;\n\t\t\tcp = \"clock/6\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(0);\n\t\t\tbreak;\n\t}\n\tLOG_USER(\"(%s)\", cp);\n\tfin = fin / pdiv;\n\t/* sam4 has a *SINGLE* clock - */\n\t/* other at91 series parts have divisors for these. */\n\tchip->cfg.cpu_freq = fin;\n\tchip->cfg.mclk_freq = fin;\n\tchip->cfg.fclk_freq = fin;\n\tLOG_USER(\"\\t\\tResult CPU Freq: %3.03f\",\n\t\t_tomhz(fin));\n}\n\n#if 0\nstatic struct sam4_chip *target2sam4(struct target *target)\n{\n\tstruct sam4_chip *chip;\n\n\tif (!target)\n\t\treturn NULL;\n\n\tchip = all_sam4_chips;\n\twhile (chip) {\n\t\tif (chip->target == target)\n\t\t\tbreak;\t/* return below */\n\t\telse\n\t\t\tchip = chip->next;\n\t}\n\treturn chip;\n}\n#endif\n\nstatic uint32_t *sam4_get_reg_ptr(struct sam4_cfg *cfg, const struct sam4_reg_list *list)\n{\n\t/* this function exists to help */\n\t/* keep funky offsetof() errors */\n\t/* and casting from causing bugs */\n\n\t/* By using prototypes - we can detect what would */\n\t/* be casting errors. */\n\n\treturn (uint32_t *)(void *)(((char *)(cfg)) + list->struct_offset);\n}\n\n\n#define SAM4_ENTRY(NAME, FUNC)  { .address = SAM4_ ## NAME, .struct_offset = offsetof( \\\n\t\t\t\t\t\t  struct sam4_cfg, \\\n\t\t\t\t\t\t  NAME), # NAME, FUNC }\nstatic const struct sam4_reg_list sam4_all_regs[] = {\n\tSAM4_ENTRY(CKGR_MOR, sam4_explain_ckgr_mor),\n\tSAM4_ENTRY(CKGR_MCFR, sam4_explain_ckgr_mcfr),\n\tSAM4_ENTRY(CKGR_PLLAR, sam4_explain_ckgr_plla),\n\tSAM4_ENTRY(CKGR_UCKR, NULL),\n\tSAM4_ENTRY(PMC_FSMR, NULL),\n\tSAM4_ENTRY(PMC_FSPR, NULL),\n\tSAM4_ENTRY(PMC_IMR, NULL),\n\tSAM4_ENTRY(PMC_MCKR, sam4_explain_mckr),\n\tSAM4_ENTRY(PMC_PCK0, NULL),\n\tSAM4_ENTRY(PMC_PCK1, NULL),\n\tSAM4_ENTRY(PMC_PCK2, NULL),\n\tSAM4_ENTRY(PMC_PCSR, NULL),\n\tSAM4_ENTRY(PMC_SCSR, NULL),\n\tSAM4_ENTRY(PMC_SR, NULL),\n\tSAM4_ENTRY(CHIPID_CIDR, sam4_explain_chipid_cidr),\n\tSAM4_ENTRY(CHIPID_EXID, NULL),\n\t/* TERMINATE THE LIST */\n\t{ .name = NULL }\n};\n#undef SAM4_ENTRY\n\nstatic struct sam4_bank_private *get_sam4_bank_private(struct flash_bank *bank)\n{\n\treturn bank->driver_priv;\n}\n\n/**\n * Given a pointer to where it goes in the structure,\n * determine the register name, address from the all registers table.\n */\nstatic const struct sam4_reg_list *sam4_get_reg(struct sam4_chip *chip, uint32_t *goes_here)\n{\n\tconst struct sam4_reg_list *reg;\n\n\treg = &(sam4_all_regs[0]);\n\twhile (reg->name) {\n\t\tuint32_t *possible;\n\n\t\t/* calculate where this one go.. */\n\t\t/* it is \"possibly\" this register. */\n\n\t\tpossible = ((uint32_t *)(void *)(((char *)(&(chip->cfg))) + reg->struct_offset));\n\n\t\t/* well? Is it this register */\n\t\tif (possible == goes_here) {\n\t\t\t/* Jump for joy! */\n\t\t\treturn reg;\n\t\t}\n\n\t\t/* next... */\n\t\treg++;\n\t}\n\t/* This is *TOTAL*PANIC* - we are totally screwed. */\n\tLOG_ERROR(\"INVALID SAM4 REGISTER\");\n\treturn NULL;\n}\n\nstatic int sam4_read_this_reg(struct sam4_chip *chip, uint32_t *goes_here)\n{\n\tconst struct sam4_reg_list *reg;\n\tint r;\n\n\treg = sam4_get_reg(chip, goes_here);\n\tif (!reg)\n\t\treturn ERROR_FAIL;\n\n\tr = target_read_u32(chip->target, reg->address, goes_here);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read SAM4 register: %s @ 0x%08x, Err: %d\",\n\t\t\treg->name, (unsigned)(reg->address), r);\n\t}\n\treturn r;\n}\n\nstatic int sam4_read_all_regs(struct sam4_chip *chip)\n{\n\tint r;\n\tconst struct sam4_reg_list *reg;\n\n\treg = &(sam4_all_regs[0]);\n\twhile (reg->name) {\n\t\tr = sam4_read_this_reg(chip,\n\t\t\t\tsam4_get_reg_ptr(&(chip->cfg), reg));\n\t\tif (r != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Cannot read SAM4 register: %s @ 0x%08x, Error: %d\",\n\t\t\t\treg->name, ((unsigned)(reg->address)), r);\n\t\t\treturn r;\n\t\t}\n\t\treg++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4_get_info(struct sam4_chip *chip)\n{\n\tconst struct sam4_reg_list *reg;\n\tuint32_t regval;\n\tint r;\n\n\tr = sam4_read_all_regs(chip);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\treg = &(sam4_all_regs[0]);\n\twhile (reg->name) {\n\t\t/* display all regs */\n\t\tLOG_DEBUG(\"Start: %s\", reg->name);\n\t\tregval = *sam4_get_reg_ptr(&(chip->cfg), reg);\n\t\tLOG_USER(\"%*s: [0x%08\" PRIx32 \"] -> 0x%08\" PRIx32,\n\t\t\tREG_NAME_WIDTH,\n\t\t\treg->name,\n\t\t\treg->address,\n\t\t\tregval);\n\t\tif (reg->explain_func)\n\t\t\t(*(reg->explain_func))(chip);\n\t\tLOG_DEBUG(\"End: %s\", reg->name);\n\t\treg++;\n\t}\n\tLOG_USER(\"   rc-osc: %3.03f MHz\", _tomhz(chip->cfg.rc_freq));\n\tLOG_USER(\"  mainosc: %3.03f MHz\", _tomhz(chip->cfg.mainosc_freq));\n\tLOG_USER(\"     plla: %3.03f MHz\", _tomhz(chip->cfg.plla_freq));\n\tLOG_USER(\" cpu-freq: %3.03f MHz\", _tomhz(chip->cfg.cpu_freq));\n\tLOG_USER(\"mclk-freq: %3.03f MHz\", _tomhz(chip->cfg.mclk_freq));\n\n\tLOG_USER(\" UniqueId: 0x%08\" PRIx32 \" 0x%08\" PRIx32 \" 0x%08\" PRIx32 \" 0x%08\"PRIx32,\n\t\tchip->cfg.unique_id[0],\n\t\tchip->cfg.unique_id[1],\n\t\tchip->cfg.unique_id[2],\n\t\tchip->cfg.unique_id[3]);\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4_protect_check(struct flash_bank *bank)\n{\n\tint r;\n\tuint32_t v[4] = {0};\n\tunsigned x;\n\tstruct sam4_bank_private *private;\n\n\tLOG_DEBUG(\"Begin\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!private) {\n\t\tLOG_ERROR(\"no private for this bank?\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tr = flashd_get_lock_bits(private, v);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed: %d\", r);\n\t\treturn r;\n\t}\n\n\tfor (x = 0; x < private->nsectors; x++)\n\t\tbank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));\n\tLOG_DEBUG(\"Done\");\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)\n{\n\tstruct sam4_chip *chip;\n\n\tchip = all_sam4_chips;\n\n\t/* is this an existing chip? */\n\twhile (chip) {\n\t\tif (chip->target == bank->target)\n\t\t\tbreak;\n\t\tchip = chip->next;\n\t}\n\n\tif (!chip) {\n\t\t/* this is a *NEW* chip */\n\t\tchip = calloc(1, sizeof(struct sam4_chip));\n\t\tif (!chip) {\n\t\t\tLOG_ERROR(\"NO RAM!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tchip->target = bank->target;\n\t\t/* insert at head */\n\t\tchip->next = all_sam4_chips;\n\t\tall_sam4_chips = chip;\n\t\tchip->target = bank->target;\n\t\t/* assumption is this runs at 32khz */\n\t\tchip->cfg.slow_freq = 32768;\n\t\tchip->probed = false;\n\t}\n\n\tswitch (bank->base) {\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Address 0x%08x invalid bank address (try 0x%08x\"\n\t\t\t\t\"[at91sam4s series] )\",\n\t\t\t\t((unsigned int)(bank->base)),\n\t\t\t\t((unsigned int)(FLASH_BANK_BASE_S)));\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* at91sam4s series only has bank 0*/\n\t\t/* at91sam4sd series has the same address for bank 0 (FLASH_BANK0_BASE_SD)*/\n\t\tcase FLASH_BANK_BASE_S:\n\t\tcase FLASH_BANK_BASE_C:\n\t\t\tbank->driver_priv = &(chip->details.bank[0]);\n\t\t\tbank->bank_number = 0;\n\t\t\tchip->details.bank[0].chip = chip;\n\t\t\tchip->details.bank[0].bank = bank;\n\t\t\tbreak;\n\n\t\t/* Bank 1 of at91sam4sd/at91sam4c32 series */\n\t\tcase FLASH_BANK1_BASE_1024K_SD:\n\t\tcase FLASH_BANK1_BASE_2048K_SD:\n\t\tcase FLASH_BANK1_BASE_C32:\n\t\t\tbank->driver_priv = &(chip->details.bank[1]);\n\t\t\tbank->bank_number = 1;\n\t\t\tchip->details.bank[1].chip = chip;\n\t\t\tchip->details.bank[1].bank = bank;\n\t\t\tbreak;\n\t}\n\n\t/* we initialize after probing. */\n\treturn ERROR_OK;\n}\n\n/**\n * Remove all chips from the internal list without distinguishing which one\n * is owned by this bank. This simplification works only for one shot\n * deallocation like current flash_free_all_banks()\n */\nstatic void sam4_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct sam4_chip *chip = all_sam4_chips;\n\twhile (chip) {\n\t\tstruct sam4_chip *next = chip->next;\n\t\tfree(chip);\n\t\tchip = next;\n\t}\n\tall_sam4_chips = NULL;\n}\n\nstatic int sam4_get_details(struct sam4_bank_private *private)\n{\n\tconst struct sam4_chip_details *details;\n\tstruct sam4_chip *chip;\n\tstruct flash_bank *saved_banks[SAM4_MAX_FLASH_BANKS];\n\tunsigned x;\n\n\tLOG_DEBUG(\"Begin\");\n\tdetails = all_sam4_details;\n\twhile (details->name) {\n\t\t/* Compare cidr without version bits */\n\t\tif (details->chipid_cidr == (private->chip->cfg.CHIPID_CIDR & 0xFFFFFFE0))\n\t\t\tbreak;\n\t\telse\n\t\t\tdetails++;\n\t}\n\tif (!details->name) {\n\t\tLOG_ERROR(\"SAM4 ChipID 0x%08x not found in table (perhaps you can ID this chip?)\",\n\t\t\t(unsigned int)(private->chip->cfg.CHIPID_CIDR));\n\t\t/* Help the victim, print details about the chip */\n\t\tLOG_INFO(\"SAM4 CHIPID_CIDR: 0x%08\" PRIx32 \" decodes as follows\",\n\t\t\tprivate->chip->cfg.CHIPID_CIDR);\n\t\tsam4_explain_chipid_cidr(private->chip);\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_DEBUG(\"SAM4 Found chip %s, CIDR 0x%08\" PRIx32, details->name, details->chipid_cidr);\n\t}\n\n\t/* DANGER: THERE ARE DRAGONS HERE */\n\n\t/* get our chip - it is going */\n\t/* to be over-written shortly */\n\tchip = private->chip;\n\n\t/* Note that, in reality: */\n\t/*  */\n\t/*     private = &(chip->details.bank[0]) */\n\t/* or  private = &(chip->details.bank[1]) */\n\t/*  */\n\n\t/* save the \"bank\" pointers */\n\tfor (x = 0; x < SAM4_MAX_FLASH_BANKS; x++)\n\t\tsaved_banks[x] = chip->details.bank[x].bank;\n\n\t/* Overwrite the \"details\" structure. */\n\tmemcpy(&(private->chip->details),\n\t\tdetails,\n\t\tsizeof(private->chip->details));\n\n\t/* now fix the ghosted pointers */\n\tfor (x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {\n\t\tchip->details.bank[x].chip = chip;\n\t\tchip->details.bank[x].bank = saved_banks[x];\n\t}\n\n\t/* update the *BANK*SIZE* */\n\n\tLOG_DEBUG(\"End\");\n\treturn ERROR_OK;\n}\n\nstatic int sam4_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct sam4_bank_private *private;\n\tint k = bank->size / 1024;\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!private)\n\t\treturn ERROR_FAIL;\n\n\tcommand_print_sameline(cmd, \"%s bank %d: %d kB at \" TARGET_ADDR_FMT,\n\t\tprivate->chip->details.name,\n\t\tprivate->bank_number,\n\t\tk,\n\t\tbank->base);\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4_probe(struct flash_bank *bank)\n{\n\tint r;\n\tstruct sam4_bank_private *private;\n\n\n\tLOG_DEBUG(\"Begin: Bank: %u\", bank->bank_number);\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!private) {\n\t\tLOG_ERROR(\"Invalid/unknown bank number\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = sam4_read_all_regs(private->chip);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (private->chip->probed)\n\t\tr = sam4_get_info(private->chip);\n\telse\n\t\tr = sam4_get_details(private);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\t/* update the flash bank size */\n\tfor (unsigned int x = 0; x < SAM4_MAX_FLASH_BANKS; x++) {\n\t\tif (bank->base == private->chip->details.bank[x].base_address) {\n\t\t\tbank->size = private->chip->details.bank[x].size_bytes;\n\t\t\tLOG_DEBUG(\"SAM4 Set flash bank to \" TARGET_ADDR_FMT \" - \"\n\t\t\t\t\tTARGET_ADDR_FMT \", idx %d\", bank->base,\n\t\t\t\t\tbank->base + bank->size, x);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!bank->sectors) {\n\t\tbank->sectors = calloc(private->nsectors, (sizeof((bank->sectors)[0])));\n\t\tif (!bank->sectors) {\n\t\t\tLOG_ERROR(\"No memory!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbank->num_sectors = private->nsectors;\n\n\t\tfor (unsigned int x = 0; x < bank->num_sectors; x++) {\n\t\t\tbank->sectors[x].size = private->sector_size;\n\t\t\tbank->sectors[x].offset = x * (private->sector_size);\n\t\t\t/* mark as unknown */\n\t\t\tbank->sectors[x].is_erased = -1;\n\t\t\tbank->sectors[x].is_protected = -1;\n\t\t}\n\t}\n\n\tprivate->probed = true;\n\n\tr = sam4_protect_check(bank);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tLOG_DEBUG(\"Bank = %d, nbanks = %d\",\n\t\tprivate->bank_number, private->chip->details.n_banks);\n\tif ((private->bank_number + 1) == private->chip->details.n_banks) {\n\t\t/* read unique id, */\n\t\t/* it appears to be associated with the *last* flash bank. */\n\t\tflashd_read_uid(private);\n\t}\n\n\treturn r;\n}\n\nstatic int sam4_auto_probe(struct flash_bank *bank)\n{\n\tstruct sam4_bank_private *private;\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (private && private->probed)\n\t\treturn ERROR_OK;\n\n\treturn sam4_probe(bank);\n}\n\nstatic int sam4_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct sam4_bank_private *private;\n\tint r;\n\tint page_count;\n\t/*16 pages equals 8KB - Same size as a lock region*/\n\tpage_count = 16;\n\tuint32_t status;\n\n\tLOG_DEBUG(\"Here\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tr = sam4_auto_probe(bank);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Here,r=%d\", r);\n\t\treturn r;\n\t}\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif ((first == 0) && ((last + 1) == private->nsectors)) {\n\t\t/* whole chip */\n\t\tLOG_DEBUG(\"Here\");\n\t\treturn flashd_erase_entire_bank(private);\n\t}\n\tLOG_INFO(\"sam4 does not auto-erase while programming (Erasing relevant sectors)\");\n\tLOG_INFO(\"sam4 First: 0x%08x Last: 0x%08x\", first, last);\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\t/*16 pages equals 8KB - Same size as a lock region*/\n\t\tr = flashd_erase_pages(private, (i * page_count), page_count, &status);\n\t\tLOG_INFO(\"Erasing sector: 0x%08x\", i);\n\t\tif (r != ERROR_OK)\n\t\t\tLOG_ERROR(\"SAM4: Error performing Erase page @ lock region number %u\",\n\t\t\t\ti);\n\t\tif (status & (1 << 2)) {\n\t\t\tLOG_ERROR(\"SAM4: Lock Region %u is locked\", i);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (status & (1 << 1)) {\n\t\t\tLOG_ERROR(\"SAM4: Flash Command error @lock region %u\", i);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct sam4_bank_private *private;\n\tint r;\n\n\tLOG_DEBUG(\"Here\");\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!(private->probed))\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (set)\n\t\tr = flashd_lock(private, first, last);\n\telse\n\t\tr = flashd_unlock(private, first, last);\n\tLOG_DEBUG(\"End: r=%d\", r);\n\n\treturn r;\n\n}\n\nstatic int sam4_page_read(struct sam4_bank_private *private, unsigned pagenum, uint8_t *buf)\n{\n\tuint32_t adr;\n\tint r;\n\n\tadr = pagenum * private->page_size;\n\tadr = adr + private->base_address;\n\n\tr = target_read_memory(private->chip->target,\n\t\t\tadr,\n\t\t\t4,\t\t\t\t\t/* THIS*MUST*BE* in 32bit values */\n\t\t\tprivate->page_size / 4,\n\t\t\tbuf);\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"SAM4: Flash program failed to read page phys address: 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\treturn r;\n}\n\nstatic int sam4_set_wait(struct sam4_bank_private *private)\n{\n\tuint32_t fmr;\t/* EEFC Flash Mode Register */\n\tint r;\n\n\t/* Get flash mode register value */\n\tr = target_read_u32(private->chip->target, private->controller_address, &fmr);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"Error Read failed: read flash mode register\");\n\t\treturn r;\n\t}\n\n\t/* Clear flash wait state field */\n\tfmr &= 0xfffff0ff;\n\n\t/* set FWS (flash wait states) field in the FMR (flash mode register) */\n\tfmr |= (private->flash_wait_states << 8);\n\n\tLOG_DEBUG(\"Flash Mode: 0x%08x\", ((unsigned int)(fmr)));\n\tr = target_write_u32(private->bank->target, private->controller_address, fmr);\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"Error Write failed: set flash mode register\");\n\n\treturn r;\n}\n\nstatic int sam4_page_write(struct sam4_bank_private *private, unsigned pagenum, const uint8_t *buf)\n{\n\tuint32_t adr;\n\tuint32_t status;\n\tint r;\n\n\tadr = pagenum * private->page_size;\n\tadr = (adr + private->base_address);\n\n\t/* 1st sector 8kBytes - page 0 - 15*/\n\t/* 2nd sector 8kBytes - page 16 - 30*/\n\t/* 3rd sector 48kBytes - page 31 - 127*/\n\tLOG_DEBUG(\"Wr Page %u @ phys address: 0x%08x\", pagenum, (unsigned int)(adr));\n\tr = target_write_memory(private->chip->target,\n\t\t\tadr,\n\t\t\t4,\t\t\t\t\t/* THIS*MUST*BE* in 32bit values */\n\t\t\tprivate->page_size / 4,\n\t\t\tbuf);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"SAM4: Failed to write (buffer) page at phys address 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\t\treturn r;\n\t}\n\n\tr = efc_perform_command(private,\n\t\t\t/* send Erase & Write Page */\n\t\t\tAT91C_EFC_FCMD_WP,\t/*AT91C_EFC_FCMD_EWP only works on first two 8kb sectors*/\n\t\t\tpagenum,\n\t\t\t&status);\n\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"SAM4: Error performing Write page @ phys address 0x%08x\",\n\t\t\t(unsigned int)(adr));\n\tif (status & (1 << 2)) {\n\t\tLOG_ERROR(\"SAM4: Page @ Phys address 0x%08x is locked\", (unsigned int)(adr));\n\t\treturn ERROR_FAIL;\n\t}\n\tif (status & (1 << 1)) {\n\t\tLOG_ERROR(\"SAM4: Flash Command error @phys address 0x%08x\", (unsigned int)(adr));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int sam4_write(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tint n;\n\tunsigned page_cur;\n\tunsigned page_end;\n\tint r;\n\tunsigned page_offset;\n\tstruct sam4_bank_private *private;\n\tuint8_t *pagebuffer;\n\n\t/* in case we bail further below, set this to null */\n\tpagebuffer = NULL;\n\n\t/* ignore dumb requests */\n\tif (count == 0) {\n\t\tr = ERROR_OK;\n\t\tgoto done;\n\t}\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\tr = ERROR_TARGET_NOT_HALTED;\n\t\tgoto done;\n\t}\n\n\tprivate = get_sam4_bank_private(bank);\n\tif (!(private->probed)) {\n\t\tr = ERROR_FLASH_BANK_NOT_PROBED;\n\t\tgoto done;\n\t}\n\n\tif ((offset + count) > private->size_bytes) {\n\t\tLOG_ERROR(\"Flash write error - past end of bank\");\n\t\tLOG_ERROR(\" offset: 0x%08x, count 0x%08x, BankEnd: 0x%08x\",\n\t\t\t(unsigned int)(offset),\n\t\t\t(unsigned int)(count),\n\t\t\t(unsigned int)(private->size_bytes));\n\t\tr = ERROR_FAIL;\n\t\tgoto done;\n\t}\n\n\tpagebuffer = malloc(private->page_size);\n\tif (!pagebuffer) {\n\t\tLOG_ERROR(\"No memory for %d Byte page buffer\", (int)(private->page_size));\n\t\tr = ERROR_FAIL;\n\t\tgoto done;\n\t}\n\n\tr = sam4_set_wait(private);\n\tif (r != ERROR_OK)\n\t\tgoto done;\n\n\t/* what page do we start & end in? */\n\tpage_cur = offset / private->page_size;\n\tpage_end = (offset + count - 1) / private->page_size;\n\n\tLOG_DEBUG(\"Offset: 0x%08x, Count: 0x%08x\", (unsigned int)(offset), (unsigned int)(count));\n\tLOG_DEBUG(\"Page start: %d, Page End: %d\", (int)(page_cur), (int)(page_end));\n\n\t/* Special case: all one page */\n\t/*  */\n\t/* Otherwise: */\n\t/*    (1) non-aligned start */\n\t/*    (2) body pages */\n\t/*    (3) non-aligned end. */\n\n\t/* Handle special case - all one page. */\n\tif (page_cur == page_end) {\n\t\tLOG_DEBUG(\"Special case, all in one page\");\n\t\tr = sam4_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tpage_offset = (offset & (private->page_size-1));\n\t\tmemcpy(pagebuffer + page_offset,\n\t\t\tbuffer,\n\t\t\tcount);\n\n\t\tr = sam4_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\tr = ERROR_OK;\n\t\tgoto done;\n\t}\n\n\t/* non-aligned start */\n\tpage_offset = offset & (private->page_size - 1);\n\tif (page_offset) {\n\t\tLOG_DEBUG(\"Not-Aligned start\");\n\t\t/* read the partial */\n\t\tr = sam4_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\t/* over-write with new data */\n\t\tn = (private->page_size - page_offset);\n\t\tmemcpy(pagebuffer + page_offset,\n\t\t\tbuffer,\n\t\t\tn);\n\n\t\tr = sam4_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tcount  -= n;\n\t\toffset += n;\n\t\tbuffer += n;\n\t\tpage_cur++;\n\t}\n\n\t/* By checking that offset is correct here, we also\n\tfix a clang warning */\n\tassert(offset % private->page_size == 0);\n\n\t/* intermediate large pages */\n\t/* also - the final *terminal* */\n\t/* if that terminal page is a full page */\n\tLOG_DEBUG(\"Full Page Loop: cur=%d, end=%d, count = 0x%08x\",\n\t\t(int)page_cur, (int)page_end, (unsigned int)(count));\n\n\twhile ((page_cur < page_end) &&\n\t\t\t(count >= private->page_size)) {\n\t\tr = sam4_page_write(private, page_cur, buffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\tcount -= private->page_size;\n\t\tbuffer += private->page_size;\n\t\tpage_cur += 1;\n\t}\n\n\t/* terminal partial page? */\n\tif (count) {\n\t\tLOG_DEBUG(\"Terminal partial page, count = 0x%08x\", (unsigned int)(count));\n\t\t/* we have a partial page */\n\t\tr = sam4_page_read(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t\t\t\t\t/* data goes at start */\n\t\tmemcpy(pagebuffer, buffer, count);\n\t\tr = sam4_page_write(private, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\tLOG_DEBUG(\"Done!\");\n\tr = ERROR_OK;\ndone:\n\tfree(pagebuffer);\n\treturn r;\n}\n\nCOMMAND_HANDLER(sam4_handle_info_command)\n{\n\tstruct sam4_chip *chip;\n\tchip = get_current_sam4(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tunsigned x;\n\tint r;\n\n\t/* bank0 must exist before we can do anything */\n\tif (!chip->details.bank[0].bank) {\n\t\tx = 0;\nneed_define:\n\t\tcommand_print(CMD,\n\t\t\t\"Please define bank %d via command: flash bank %s ... \",\n\t\t\tx,\n\t\t\tat91sam4_flash.name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* if bank 0 is not probed, then probe it */\n\tif (!(chip->details.bank[0].probed)) {\n\t\tr = sam4_auto_probe(chip->details.bank[0].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\t/* above guarantees the \"chip details\" structure is valid */\n\t/* and thus, bank private areas are valid */\n\t/* and we have a SAM4 chip, what a concept! */\n\n\t/* auto-probe other banks, 0 done above */\n\tfor (x = 1; x < SAM4_MAX_FLASH_BANKS; x++) {\n\t\t/* skip banks not present */\n\t\tif (!(chip->details.bank[x].present))\n\t\t\tcontinue;\n\n\t\tif (!chip->details.bank[x].bank)\n\t\t\tgoto need_define;\n\n\t\tif (chip->details.bank[x].probed)\n\t\t\tcontinue;\n\n\t\tr = sam4_auto_probe(chip->details.bank[x].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\n\tr = sam4_get_info(chip);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"Sam4Info, Failed %d\", r);\n\t\treturn r;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sam4_handle_gpnvm_command)\n{\n\tunsigned x, v;\n\tint r, who;\n\tstruct sam4_chip *chip;\n\n\tchip = get_current_sam4(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tif (chip->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"sam4 - target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->details.bank[0].bank) {\n\t\tcommand_print(CMD, \"Bank0 must be defined first via: flash bank %s ...\",\n\t\t\tat91sam4_flash.name);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!chip->details.bank[0].probed) {\n\t\tr = sam4_auto_probe(chip->details.bank[0].bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\n\tswitch (CMD_ARGC) {\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tcase 0:\n\t\t\tgoto showall;\n\t\tcase 1:\n\t\t\twho = -1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif ((strcmp(CMD_ARGV[0], \"show\") == 0) && (strcmp(CMD_ARGV[1], \"all\") == 0))\n\t\t\t\twho = -1;\n\t\t\telse {\n\t\t\t\tuint32_t v32;\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);\n\t\t\t\twho = v32;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (strcmp(\"show\", CMD_ARGV[0]) == 0) {\n\t\tif (who == -1) {\nshowall:\n\t\t\tr = ERROR_OK;\n\t\t\tfor (x = 0; x < chip->details.n_gpnvms; x++) {\n\t\t\t\tr = flashd_get_gpnvm(&(chip->details.bank[0]), x, &v);\n\t\t\t\tif (r != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t\tcommand_print(CMD, \"sam4-gpnvm%u: %u\", x, v);\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t\tif ((who >= 0) && (((unsigned)(who)) < chip->details.n_gpnvms)) {\n\t\t\tr = flashd_get_gpnvm(&(chip->details.bank[0]), who, &v);\n\t\t\tif (r == ERROR_OK)\n\t\t\t\tcommand_print(CMD, \"sam4-gpnvm%u: %u\", who, v);\n\t\t\treturn r;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"sam4-gpnvm invalid GPNVM: %u\", who);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tif (who == -1) {\n\t\tcommand_print(CMD, \"Missing GPNVM number\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (strcmp(\"set\", CMD_ARGV[0]) == 0)\n\t\tr = flashd_set_gpnvm(&(chip->details.bank[0]), who);\n\telse if ((strcmp(\"clr\", CMD_ARGV[0]) == 0) ||\n\t\t (strcmp(\"clear\", CMD_ARGV[0]) == 0))\t\t\t/* quietly accept both */\n\t\tr = flashd_clr_gpnvm(&(chip->details.bank[0]), who);\n\telse {\n\t\tcommand_print(CMD, \"Unknown command: %s\", CMD_ARGV[0]);\n\t\tr = ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn r;\n}\n\nCOMMAND_HANDLER(sam4_handle_slowclk_command)\n{\n\tstruct sam4_chip *chip;\n\n\tchip = get_current_sam4(CMD);\n\tif (!chip)\n\t\treturn ERROR_OK;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\t/* show */\n\t\t\tbreak;\n\t\tcase 1:\n\t\t{\n\t\t\t/* set */\n\t\t\tuint32_t v;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);\n\t\t\tif (v > 200000) {\n\t\t\t\t/* absurd slow clock of 200Khz? */\n\t\t\t\tcommand_print(CMD, \"Absurd/illegal slow clock freq: %d\\n\", (int)(v));\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tchip->cfg.slow_freq = v;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\t/* error */\n\t\t\tcommand_print(CMD, \"Too many parameters\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tcommand_print(CMD, \"Slowclk freq: %d.%03dkhz\",\n\t\t(int)(chip->cfg.slow_freq / 1000),\n\t\t(int)(chip->cfg.slow_freq % 1000));\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration at91sam4_exec_command_handlers[] = {\n\t{\n\t\t.name = \"gpnvm\",\n\t\t.handler = sam4_handle_gpnvm_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[('clr'|'set'|'show') bitnum]\",\n\t\t.help = \"Without arguments, shows all bits in the gpnvm \"\n\t\t\t\"register.  Otherwise, clears, sets, or shows one \"\n\t\t\t\"General Purpose Non-Volatile Memory (gpnvm) bit.\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = sam4_handle_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Print information about the current at91sam4 chip \"\n\t\t\t\"and its flash configuration.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"slowclk\",\n\t\t.handler = sam4_handle_slowclk_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[clock_hz]\",\n\t\t.help = \"Display or set the slowclock frequency \"\n\t\t\t\"(default 32768 Hz).\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration at91sam4_command_handlers[] = {\n\t{\n\t\t.name = \"at91sam4\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"at91sam4 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = at91sam4_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver at91sam4_flash = {\n\t.name = \"at91sam4\",\n\t.commands = at91sam4_command_handlers,\n\t.flash_bank_command = sam4_flash_bank_command,\n\t.erase = sam4_erase,\n\t.protect = sam4_protect,\n\t.write = sam4_write,\n\t.read = default_flash_read,\n\t.probe = sam4_probe,\n\t.auto_probe = sam4_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = sam4_protect_check,\n\t.info = sam4_info,\n\t.free_driver_priv = sam4_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/at91sam4l.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Andrey Yurovsky                                 *\n *   Andrey Yurovsky <yurovsky@gmail.com>                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n\n#include <jtag/jtag.h>\n#include <target/cortex_m.h>\n\n/* At this time, the SAM4L Flash is available in these capacities:\n * ATSAM4Lx4xx: 256KB (512 pages)\n * ATSAM4Lx2xx: 128KB (256 pages)\n * ATSAM4Lx8xx: 512KB (1024 pages)\n */\n\n/* There are 16 lockable regions regardless of overall capacity. The number\n * of pages per sector is therefore dependant on capacity. */\n#define SAM4L_NUM_SECTORS 16\n\n/* Locations in memory map */\n#define SAM4L_FLASH\t\t\t((uint32_t)0x00000000) /* Flash region */\n#define SAM4L_FLASH_USER\t0x00800000 /* Flash user page region */\n#define SAM4L_FLASHCALW\t\t0x400A0000 /* Flash controller */\n#define SAM4L_CHIPID\t\t0x400E0740 /* Chip Identification */\n\n/* Offsets from SAM4L_FLASHCALW */\n#define SAM4L_FCR\t\t\t0x00 /* Flash Control Register (RW) */\n#define SAM4L_FCMD\t\t\t0x04 /* Flash Command Register (RW) */\n#define SAM4L_FSR\t\t\t0x08 /* Flash Status Register (RO) */\n#define SAM4L_FPR\t\t\t0x0C /* Flash Parameter Register (RO) */\n#define SAM4L_FVR\t\t\t0x10 /* Flash Version Register (RO) */\n#define SAM4L_FGPFRHI\t\t0x14 /* Flash General Purpose Register High (RO) */\n#define SAM4L_FGPFRLO\t\t0x18 /* Flash General Purpose Register Low (RO) */\n\n/* Offsets from SAM4L_CHIPID */\n#define SAM4L_CIDR\t\t\t0x00 /* Chip ID Register (RO) */\n#define SAM4L_EXID\t\t\t0x04 /* Chip ID Extension Register (RO) */\n\n/* Flash commands (for SAM4L_FCMD), see Table 14-5 */\n#define SAM4L_FCMD_NOP\t\t0\t /* No Operation */\n#define SAM4L_FCMD_WP\t\t1\t /* Write Page */\n#define SAM4L_FCMD_EP\t\t2\t /* Erase Page */\n#define SAM4L_FCMD_CPB\t\t3\t /* Clear Page Buffer */\n#define SAM4L_FCMD_LP\t\t4\t /* Lock region containing given page */\n#define SAM4L_FCMD_UP\t\t5\t /* Unlock region containing given page */\n#define SAM4L_FCMD_EA\t\t6\t /* Erase All */\n#define SAM4L_FCMD_WGPB\t\t7\t /* Write general-purpose fuse bit */\n#define SAM4L_FCMD_EGPB\t\t8\t /* Erase general-purpose fuse bit */\n#define SAM4L_FCMD_SSB\t\t9\t /* Set security fuses */\n#define SAM4L_FCMD_PGPFB\t10\t/* Program general-purpose fuse byte */\n#define SAM4L_FCMD_EAGPF\t11\t/* Erase all general-purpose fuse bits */\n#define SAM4L_FCMD_QPR\t\t12\t/* Quick page read */\n#define SAM4L_FCMD_WUP\t\t13\t/* Write user page */\n#define SAM4L_FCMD_EUP\t\t14\t/* Erase user page */\n#define SAM4L_FCMD_QPRUP\t15\t/* Quick page read (user page) */\n#define SAM4L_FCMD_HSEN\t\t16\t/* High speed mode enable */\n#define SAM4L_FCMD_HSDIS\t17\t/* High speed mode disable */\n\n#define SAM4L_FMCD_CMDKEY\t0xA5UL\t/* 'key' to issue commands, see 14.10.2 */\n\n\n/* SMAP registers and bits */\n#define SMAP_BASE 0x400A3000\n\n#define SMAP_SCR (SMAP_BASE + 8)\n#define SMAP_SCR_HCR (1 << 1)\n\n\nstruct sam4l_chip_info {\n\tuint32_t id;\n\tuint32_t exid;\n\tconst char *name;\n};\n\n/* These are taken from Table 9-1 in 42023E-SAM-07/2013 */\nstatic const struct sam4l_chip_info sam4l_known_chips[] = {\n\t{ 0xAB0B0AE0, 0x1400000F, \"ATSAM4LC8C\" },\n\t{ 0xAB0A09E0, 0x0400000F, \"ATSAM4LC4C\" },\n\t{ 0xAB0A07E0, 0x0400000F, \"ATSAM4LC2C\" },\n\t{ 0xAB0B0AE0, 0x1300000F, \"ATSAM4LC8B\" },\n\t{ 0xAB0A09E0, 0x0300000F, \"ATSAM4LC4B\" },\n\t{ 0xAB0A07E0, 0x0300000F, \"ATSAM4LC2B\" },\n\t{ 0xAB0B0AE0, 0x1200000F, \"ATSAM4LC8A\" },\n\t{ 0xAB0A09E0, 0x0200000F, \"ATSAM4LC4A\" },\n\t{ 0xAB0A07E0, 0x0200000F, \"ATSAM4LC2A\" },\n\t{ 0xAB0B0AE0, 0x14000002, \"ATSAM4LS8C\" },\n\t{ 0xAB0A09E0, 0x04000002, \"ATSAM4LS4C\" },\n\t{ 0xAB0A07E0, 0x04000002, \"ATSAM4LS2C\" },\n\t{ 0xAB0B0AE0, 0x13000002, \"ATSAM4LS8B\" },\n\t{ 0xAB0A09E0, 0x03000002, \"ATSAM4LS4B\" },\n\t{ 0xAB0A07E0, 0x03000002, \"ATSAM4LS2B\" },\n\t{ 0xAB0B0AE0, 0x12000002, \"ATSAM4LS8A\" },\n\t{ 0xAB0A09E0, 0x02000002, \"ATSAM4LS4A\" },\n\t{ 0xAB0A07E0, 0x02000002, \"ATSAM4LS2A\" },\n};\n\n/* Meaning of SRAMSIZ field in CHIPID, see 9.3.1 in 42023E-SAM-07/2013 */\nstatic const uint16_t sam4l_ram_sizes[16] = { 48, 1, 2, 6, 24, 4, 80, 160, 8, 16, 32, 64, 128, 256, 96, 512 };\n\n/* Meaning of PSZ field in FPR, see 14.10.4 in 42023E-SAM-07/2013 */\nstatic const uint16_t sam4l_page_sizes[8] = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };\n\nstruct sam4l_info {\n\tconst struct sam4l_chip_info *details;\n\n\tuint32_t flash_kb;\n\tuint32_t ram_kb;\n\tuint32_t page_size;\n\tint num_pages;\n\tint sector_size;\n\tunsigned int pages_per_sector;\n\n\tbool probed;\n\tstruct target *target;\n};\n\n\nstatic int sam4l_flash_wait_until_ready(struct target *target)\n{\n\tvolatile unsigned int t = 0;\n\tuint32_t st;\n\tint res;\n\n\t/* Poll the status register until the FRDY bit is set */\n\tdo {\n\t\tres = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);\n\t} while (res == ERROR_OK && !(st & (1<<0)) && ++t < 10);\n\n\treturn res;\n}\n\nstatic int sam4l_flash_check_error(struct target *target, uint32_t *err)\n{\n\tuint32_t st;\n\tint res;\n\n\tres = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FSR, &st);\n\n\tif (res == ERROR_OK)\n\t\t*err = st & ((1<<3) | (1<<2)); /* grab PROGE and LOCKE bits */\n\n\treturn res;\n}\n\nstatic int sam4l_flash_command(struct target *target, uint8_t cmd, int page)\n{\n\tint res;\n\tuint32_t fcmd;\n\tuint32_t err;\n\n\tres = sam4l_flash_wait_until_ready(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (page >= 0) {\n\t\t/* Set the page number. For some commands, the page number is just an\n\t\t * argument (ex: fuse bit number). */\n\t\tfcmd = (SAM4L_FMCD_CMDKEY << 24) | ((page & 0xFFFF) << 8) | (cmd & 0x3F);\n\t} else {\n\t\t/* Reuse the page number that was read from the flash command register. */\n\t\tres = target_read_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, &fcmd);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tfcmd &= ~0x3F; /* clear out the command code */\n\t\tfcmd |= (SAM4L_FMCD_CMDKEY << 24) | (cmd & 0x3F);\n\t}\n\n\t/* Send the command */\n\tres = target_write_u32(target, SAM4L_FLASHCALW + SAM4L_FCMD, fcmd);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = sam4l_flash_check_error(target, &err);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (err != 0)\n\t\tLOG_ERROR(\"%s got error status 0x%08\" PRIx32, __func__, err);\n\n\tres = sam4l_flash_wait_until_ready(target);\n\n\treturn res;\n}\n\nFLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command)\n{\n\tif (bank->base != SAM4L_FLASH) {\n\t\tLOG_ERROR(\"Address \" TARGET_ADDR_FMT\n\t\t\t\t\" invalid bank address (try 0x%08\" PRIx32\n\t\t\t\t\"[at91sam4l series] )\",\n\t\t\t\tbank->base, SAM4L_FLASH);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct sam4l_info *chip;\n\tchip = calloc(1, sizeof(*chip));\n\tif (!chip) {\n\t\tLOG_ERROR(\"No memory for flash bank chip info\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchip->target = bank->target;\n\tchip->probed = false;\n\n\tbank->driver_priv = chip;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct sam4l_chip_info *sam4l_find_chip_name(uint32_t id, uint32_t exid)\n{\n\tunsigned int i;\n\n\tid &= ~0xF;\n\n\tfor (i = 0; i < ARRAY_SIZE(sam4l_known_chips); i++) {\n\t\tif (sam4l_known_chips[i].id == id && sam4l_known_chips[i].exid == exid)\n\t\t\treturn &sam4l_known_chips[i];\n\t}\n\n\treturn NULL;\n}\n\nstatic int sam4l_check_page_erased(struct flash_bank *bank, uint32_t pn,\n\t\tbool *is_erased_p)\n{\n\tint res;\n\tuint32_t st;\n\n\t/* Issue a quick page read to verify that we've erased this page */\n\tres = sam4l_flash_command(bank->target, SAM4L_FCMD_QPR, pn);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Quick page read %\" PRIu32 \" failed\", pn);\n\t\treturn res;\n\t}\n\n\t/* Retrieve the flash status */\n\tres = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read erase status\");\n\t\treturn res;\n\t}\n\n\t/* Is the page in question really erased? */\n\t*is_erased_p = !!(st & (1<<5));\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4l_probe(struct flash_bank *bank)\n{\n\tuint32_t id, exid, param;\n\tint res;\n\tstruct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;\n\n\tif (chip->probed)\n\t\treturn ERROR_OK;\n\n\tres = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_CIDR, &id);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read chip ID\");\n\t\treturn res;\n\t}\n\n\tres = target_read_u32(bank->target, SAM4L_CHIPID + SAM4L_EXID, &exid);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read extended chip ID\");\n\t\treturn res;\n\t}\n\n\tchip->details = sam4l_find_chip_name(id, exid);\n\n\t/* The RAM capacity is in a lookup table. */\n\tchip->ram_kb = sam4l_ram_sizes[0xF & (id >> 16)];\n\n\tswitch (0xF & (id >> 8)) {\n\t\tcase 0x07:\n\t\t\tchip->flash_kb = 128;\n\t\t\tbreak;\n\t\tcase 0x09:\n\t\t\tchip->flash_kb = 256;\n\t\t\tbreak;\n\t\tcase 0x0A:\n\t\t\tchip->flash_kb = 512;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unknown flash size (chip ID is %08\" PRIx32 \"), assuming 128K\", id);\n\t\t\tchip->flash_kb = 128;\n\t\t\tbreak;\n\t}\n\n\t/* Retrieve the Flash parameters */\n\tres = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FPR, &param);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read Flash parameters\");\n\t\treturn res;\n\t}\n\n\t/* Fetch the page size from the parameter register.\tTechnically the flash\n\t * capacity is there too though the manual mentions that not all parts will\n\t * have it set so we use the Chip ID capacity information instead. */\n\tchip->page_size = sam4l_page_sizes[0x7 & (param >> 8)];\n\tassert(chip->page_size);\n\tchip->num_pages = chip->flash_kb * 1024 / chip->page_size;\n\n\tchip->sector_size = (chip->flash_kb * 1024) / SAM4L_NUM_SECTORS;\n\tchip->pages_per_sector = chip->sector_size / chip->page_size;\n\n\t/* Make sure the bank size is correct */\n\tbank->size = chip->flash_kb * 1024;\n\n\t/* Allocate the sector table. */\n\tbank->num_sectors = SAM4L_NUM_SECTORS;\n\tbank->sectors = calloc(bank->num_sectors, (sizeof((bank->sectors)[0])));\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\t/* Fill out the sector information: all SAM4L sectors are the same size and\n\t * there is always a fixed number of them. */\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].size = chip->sector_size;\n\t\tbank->sectors[i].offset = i * chip->sector_size;\n\t\t/* mark as unknown */\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\t/* Done */\n\tchip->probed = true;\n\n\tLOG_INFO(\"SAM4L MCU: %s (Rev %c) (%\" PRIu32 \"KB Flash with %d %\" PRIu32 \"B pages, %\" PRIu32 \"KB RAM)\",\n\t\t\tchip->details ? chip->details->name : \"unknown\", (char)('A' + (id & 0xF)),\n\t\t\tchip->flash_kb, chip->num_pages, chip->page_size, chip->ram_kb);\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4l_protect_check(struct flash_bank *bank)\n{\n\tint res;\n\tuint32_t st;\n\tstruct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (sam4l_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tres = target_read_u32(bank->target, SAM4L_FLASHCALW + SAM4L_FSR, &st);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tst >>= 16; /* There are 16 lock region bits in the upper half word */\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = !!(st & (1<<i));\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4l_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (sam4l_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Make sure the pages make sense. */\n\tif (first >= bank->num_sectors || last >= bank->num_sectors) {\n\t\tLOG_ERROR(\"Protect range %u - %u not valid (%u sectors total)\", first, last,\n\t\t\t\tbank->num_sectors);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Try to lock or unlock each sector in the range.\tThis is done by locking\n\t * a region containing one page in that sector, we arbitrarily choose the 0th\n\t * page in the sector. */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tint res;\n\n\t\tres = sam4l_flash_command(bank->target,\n\t\t\t\tset ? SAM4L_FCMD_LP : SAM4L_FCMD_UP, i * chip->pages_per_sector);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't %slock region containing page %d\", set ? \"\" : \"un\", i);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sam4l_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint ret;\n\tstruct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (sam4l_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Make sure the pages make sense. */\n\tif (first >= bank->num_sectors || last >= bank->num_sectors) {\n\t\tLOG_ERROR(\"Erase range %u - %u not valid (%u sectors total)\", first, last,\n\t\t\t\tbank->num_sectors);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Erase */\n\tif ((first == 0) && ((last + 1) == bank->num_sectors)) {\n\t\tLOG_DEBUG(\"Erasing the whole chip\");\n\n\t\tret = sam4l_flash_command(bank->target, SAM4L_FCMD_EA, -1);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Erase All failed\");\n\t\t\treturn ret;\n\t\t}\n\t} else {\n\t\tLOG_DEBUG(\"Erasing sectors %u through %u...\\n\", first, last);\n\n\t\t/* For each sector... */\n\t\tfor (unsigned int i = first; i <= last; i++) {\n\t\t\t/* For each page in that sector... */\n\t\t\tfor (unsigned int j = 0; j < chip->pages_per_sector; j++) {\n\t\t\t\tunsigned int pn = i * chip->pages_per_sector + j;\n\t\t\t\tbool is_erased = false;\n\n\t\t\t\t/* Issue the page erase */\n\t\t\t\tret = sam4l_flash_command(bank->target, SAM4L_FCMD_EP, pn);\n\t\t\t\tif (ret != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Erasing page %u failed\", pn);\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = sam4l_check_page_erased(bank, pn, &is_erased);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\n\t\t\t\tif (!is_erased) {\n\t\t\t\t\tLOG_DEBUG(\"Page %u was not erased.\", pn);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Write an entire page from host buffer 'buf' to page-aligned 'address' in the\n * Flash. */\nstatic int sam4l_write_page(struct sam4l_info *chip, struct target *target,\n\t\tuint32_t address, const uint8_t *buf)\n{\n\tint res;\n\n\tLOG_DEBUG(\"sam4l_write_page address=%08\" PRIx32, address);\n\n\t/* Clear the page buffer before we write to it */\n\tres = sam4l_flash_command(target, SAM4L_FCMD_CPB, -1);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: can't clear page buffer\", __func__);\n\t\treturn res;\n\t}\n\n\t/* Write the modified page back to the target's page buffer */\n\tres = target_write_memory(target, address, 4, chip->page_size / 4, buf);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: %d\", __func__, __LINE__);\n\t\treturn res;\n\t}\n\n\t/* Commit the page contents to Flash: erase the current page and then\n\t * write it out. */\n\tres = sam4l_flash_command(target, SAM4L_FCMD_EP, -1);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tres = sam4l_flash_command(target, SAM4L_FCMD_WP, -1);\n\n\treturn res;\n}\n\n/* Write partial contents into page-aligned 'address' on the Flash from host\n * buffer 'buf' by writing 'nb' of 'buf' at 'offset' into the Flash page. */\nstatic int sam4l_write_page_partial(struct sam4l_info *chip,\n\t\tstruct flash_bank *bank, uint32_t address, const uint8_t *buf,\n\t\tuint32_t page_offset, uint32_t nb)\n{\n\tint res;\n\tuint8_t *pg = malloc(chip->page_size);\n\tif (!pg)\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"sam4l_write_page_partial address=%08\" PRIx32 \" nb=%08\" PRIx32, address, nb);\n\n\tassert(page_offset + nb < chip->page_size);\n\tassert((address % chip->page_size) == 0);\n\n\t/* Retrieve the full page contents from Flash */\n\tres = target_read_memory(bank->target, address, 4,\n\t\t\tchip->page_size / 4, pg);\n\tif (res != ERROR_OK) {\n\t\tfree(pg);\n\t\treturn res;\n\t}\n\n\t/* Insert our partial page over the data from Flash */\n\tmemcpy(pg + (page_offset % chip->page_size), buf, nb);\n\n\t/* Write the page back out */\n\tres = sam4l_write_page(chip, bank->target, address, pg);\n\tfree(pg);\n\n\treturn res;\n}\n\nstatic int sam4l_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tint res;\n\tuint32_t nb = 0;\n\tstruct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv;\n\n\tLOG_DEBUG(\"sam4l_write offset=%08\" PRIx32 \" count=%08\" PRIx32, offset, count);\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (sam4l_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (offset % chip->page_size) {\n\t\t/* We're starting at an unaligned offset so we'll write a partial page\n\t\t * comprising that offset and up to the end of that page. */\n\t\tnb = chip->page_size - (offset % chip->page_size);\n\t\tif (nb > count)\n\t\t\tnb = count;\n\t} else if (count < chip->page_size) {\n\t\t/* We're writing an aligned but partial page. */\n\t\tnb = count;\n\t}\n\n\tif (nb > 0) {\n\t\tres = sam4l_write_page_partial(chip, bank,\n\t\t\t\t(offset / chip->page_size) * chip->page_size + bank->base,\n\t\t\t\tbuffer,\n\t\t\t\toffset % chip->page_size, nb);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\t/* We're done with the page contents */\n\t\tcount -= nb;\n\t\toffset += nb;\n\t}\n\n\t/* There's at least one aligned page to write out. */\n\tif (count >= chip->page_size) {\n\t\tassert(chip->page_size > 0);\n\t\tint np = count / chip->page_size + ((count % chip->page_size) ? 1 : 0);\n\n\t\tfor (int i = 0; i < np; i++) {\n\t\t\tif (count >= chip->page_size) {\n\t\t\t\tres = sam4l_write_page(chip, bank->target,\n\t\t\t\t\t\tbank->base + offset,\n\t\t\t\t\t\tbuffer + (i * chip->page_size));\n\t\t\t\t/* Advance one page */\n\t\t\t\toffset += chip->page_size;\n\t\t\t\tcount -= chip->page_size;\n\t\t\t} else {\n\t\t\t\tres = sam4l_write_page_partial(chip, bank,\n\t\t\t\t\t\tbank->base + offset,\n\t\t\t\t\t\tbuffer + (i * chip->page_size), 0, count);\n\t\t\t\t/* We're done after this. */\n\t\t\t\toffset += count;\n\t\t\t\tcount = 0;\n\t\t\t}\n\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(sam4l_handle_reset_deassert)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = ERROR_OK;\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t/* If the target has been unresponsive before, try to re-establish\n\t * communication now - CPU is held in reset by DSU, DAP is working */\n\tif (!target_was_examined(target))\n\t\ttarget_examine_one(target);\n\ttarget_poll(target);\n\n\t/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()\n\t * so we just release reset held by SMAP\n\t *\n\t * n_RESET (srst) clears the DP, so reenable debug and set vector catch here\n\t *\n\t * After vectreset SMAP release is not needed however makes no harm\n\t */\n\tif (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {\n\t\tretval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, DCB_DEMCR,\n\t\t\t\tTRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);\n\t\t/* do not return on error here, releasing SMAP reset is more important */\n\t}\n\n\tint retval2 = target_write_u32(target, SMAP_SCR, SMAP_SCR_HCR);\n\tif (retval2 != ERROR_OK)\n\t\treturn retval2;\n\n\treturn retval;\n}\n\nstatic const struct command_registration at91sam4l_exec_command_handlers[] = {\n\t{\n\t\t.name = \"smap_reset_deassert\",\n\t\t.handler = sam4l_handle_reset_deassert,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"deassert internal reset held by SMAP\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration at91sam4l_command_handlers[] = {\n\t{\n\t\t.name = \"at91sam4l\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"at91sam4l flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = at91sam4l_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver at91sam4l_flash = {\n\t.name = \"at91sam4l\",\n\t.commands = at91sam4l_command_handlers,\n\t.flash_bank_command = sam4l_flash_bank_command,\n\t.erase = sam4l_erase,\n\t.protect = sam4l_protect,\n\t.write = sam4l_write,\n\t.read = default_flash_read,\n\t.probe = sam4l_probe,\n\t.auto_probe = sam4l_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = sam4l_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/at91sam7.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Gheorghe Guran (atlas)                          *\n****************************************************************************/\n\n/***************************************************************************\n*\n* New flash setup command:\n*\n* flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_id>\n*\t[<chip_type> <banks>\n*\t <sectors_per_bank> <pages_per_sector>\n*\t <page_size> <num_nvmbits>\n*\t <ext_freq_khz>]\n*\n*   <ext_freq_khz> - MUST be used if clock is from external source,\n*                    CAN be used if main oscillator frequency is known (recommended)\n* Examples:\n* ==== RECOMMENDED (covers clock speed) ============\n*  flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 25000\n*\t\t\t(if auto-detect fails; provides clock spec)\n*  flash bank at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 25000\n*\t\t\t(auto-detect everything except the clock)\n* ==== NOT RECOMMENDED !!! (clock speed is not configured) ====\n*  flash bank at91sam7 0x00100000 0 0 4 $_TARGETNAME AT91SAM7XC256 1 16 64 256 3 0\n*\t\t\t(if auto-detect fails)\n*  flash bank at91sam7 0 0 0 0 $_TARGETNAME\n*\t\t\t(old style, auto-detect everything)\n****************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n\n/* AT91SAM7 control registers */\n#define DBGU_CIDR                       0xFFFFF240\n#define CKGR_MCFR                       0xFFFFFC24\n#define CKGR_MOR                        0xFFFFFC20\n#define CKGR_MCFR_MAINRDY       0x10000\n#define CKGR_PLLR                       0xFFFFFC2c\n#define CKGR_PLLR_DIV           0xff\n#define CKGR_PLLR_MUL           0x07ff0000\n#define PMC_MCKR                        0xFFFFFC30\n#define PMC_MCKR_CSS            0x03\n#define PMC_MCKR_PRES           0x1c\n\n/* Flash Controller Commands */\n#define WP              0x01\n#define SLB             0x02\n#define WPL             0x03\n#define CLB             0x04\n#define EA              0x08\n#define SGPB    0x0B\n#define CGPB    0x0D\n#define SSB             0x0F\n\n/* MC_FSR bit definitions */\n#define MC_FSR_FRDY                     1\n#define MC_FSR_EOL                      2\n\n/* AT91SAM7 constants */\n#define RC_FREQ                         32000\n\n/* Flash timing modes */\n#define FMR_TIMING_NONE         0\n#define FMR_TIMING_NVBITS       1\n#define FMR_TIMING_FLASH        2\n\n/* Flash size constants */\n#define FLASH_SIZE_8KB          1\n#define FLASH_SIZE_16KB         2\n#define FLASH_SIZE_32KB         3\n#define FLASH_SIZE_64KB         5\n#define FLASH_SIZE_128KB        7\n#define FLASH_SIZE_256KB        9\n#define FLASH_SIZE_512KB        10\n#define FLASH_SIZE_1024KB       12\n#define FLASH_SIZE_2048KB       14\n\nstatic int at91sam7_protect_check(struct flash_bank *bank);\nstatic int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,\n\t\tuint32_t count);\n\nstatic uint32_t at91sam7_get_flash_status(struct target *target, int bank_number);\nstatic void at91sam7_set_flash_mode(struct flash_bank *bank, int mode);\nstatic uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout);\nstatic int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen);\n\nstatic const uint32_t mc_fmr[4] = { 0xFFFFFF60, 0xFFFFFF70, 0xFFFFFF80, 0xFFFFFF90 };\nstatic const uint32_t mc_fcr[4] = { 0xFFFFFF64, 0xFFFFFF74, 0xFFFFFF84, 0xFFFFFF94 };\nstatic const uint32_t mc_fsr[4] = { 0xFFFFFF68, 0xFFFFFF78, 0xFFFFFF88, 0xFFFFFF98 };\n\nstatic const char *eproc[8] = {\n\t\"Unknown\", \"ARM946-E\", \"ARM7TDMI\", \"Unknown\", \"ARM920T\", \"ARM926EJ-S\", \"Unknown\", \"Unknown\"\n};\n\nstruct at91sam7_flash_bank {\n\t/* chip id register */\n\tuint32_t cidr;\n\tuint16_t cidr_ext;\n\tuint16_t cidr_nvptyp;\n\tuint16_t cidr_arch;\n\tuint16_t cidr_sramsiz;\n\tuint16_t cidr_nvpsiz;\n\tuint16_t cidr_nvpsiz2;\n\tuint16_t cidr_eproc;\n\tuint16_t cidr_version;\n\tconst char *target_name;\n\n\t/* flash auto-detection */\n\tuint8_t flash_autodetection;\n\n\t/* flash geometry */\n\tuint16_t pages_per_sector;\n\tuint16_t pagesize;\n\tuint16_t pages_in_lockregion;\n\n\t/* nv memory bits */\n\tuint16_t num_lockbits_on;\n\tuint16_t lockbits;\n\tuint16_t num_nvmbits;\n\tuint16_t num_nvmbits_on;\n\tuint16_t nvmbits;\n\tuint8_t securitybit;\n\n\t/* 0: not init\n\t * 1: fmcn for nvbits (1uS)\n\t * 2: fmcn for flash (1.5uS) */\n\tuint8_t flashmode;\n\n\t/* main clock status */\n\tuint8_t mck_valid;\n\tuint32_t mck_freq;\n\n\t/* external clock frequency */\n\tuint32_t ext_freq;\n\n};\n\n#if 0\nstatic long SRAMSIZ[16] = {\n\t-1,\n\t0x0400,\t\t/*  1K */\n\t0x0800,\t\t/*  2K */\n\t-1,\n\t0x1c000,\t/* 112K */\n\t0x1000,\t\t/*   4K */\n\t0x14000,\t/*  80K */\n\t0x28000,\t/* 160K */\n\t0x2000,\t\t/*   8K */\n\t0x4000,\t\t/*  16K */\n\t0x8000,\t\t/*  32K */\n\t0x10000,\t/*  64K */\n\t0x20000,\t/* 128K */\n\t0x40000,\t/* 256K */\n\t0x18000,\t/*  96K */\n\t0x80000,\t/* 512K */\n};\n#endif\n\nstatic uint32_t at91sam7_get_flash_status(struct target *target, int bank_number)\n{\n\tuint32_t fsr;\n\ttarget_read_u32(target, mc_fsr[bank_number], &fsr);\n\n\treturn fsr;\n}\n\n/* Read clock configuration and set at91sam7_info->mck_freq */\nstatic void at91sam7_read_clock_info(struct flash_bank *bank)\n{\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t mckr, mcfr, pllr, mor;\n\tunsigned long tmp = 0, mainfreq;\n\n\t/* Read Clock Generator Main Oscillator Register */\n\ttarget_read_u32(target, CKGR_MOR, &mor);\n\t/* Read Clock Generator Main Clock Frequency Register */\n\ttarget_read_u32(target, CKGR_MCFR, &mcfr);\n\t/* Read Master Clock Register*/\n\ttarget_read_u32(target, PMC_MCKR, &mckr);\n\t/* Read Clock Generator PLL Register  */\n\ttarget_read_u32(target, CKGR_PLLR, &pllr);\n\n\tat91sam7_info->mck_valid = 0;\n\tat91sam7_info->mck_freq = 0;\n\tswitch (mckr & PMC_MCKR_CSS) {\n\t\tcase 0:\t\t\t/* Slow Clock */\n\t\t\tat91sam7_info->mck_valid = 1;\n\t\t\ttmp = RC_FREQ;\n\t\t\tbreak;\n\n\t\tcase 1:\t\t\t/* Main Clock */\n\t\t\tif ((mcfr & CKGR_MCFR_MAINRDY) &&\n\t\t\t(at91sam7_info->ext_freq == 0)) {\n\t\t\t\tat91sam7_info->mck_valid = 1;\n\t\t\t\ttmp = RC_FREQ / 16ul * (mcfr & 0xffff);\n\t\t\t} else if (at91sam7_info->ext_freq != 0) {\n\t\t\t\tat91sam7_info->mck_valid = 1;\n\t\t\t\ttmp = at91sam7_info->ext_freq;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 2:\t\t\t/* Reserved */\n\t\t\tbreak;\n\n\t\tcase 3:\t\t\t/* PLL Clock */\n\t\t\tif ((mcfr & CKGR_MCFR_MAINRDY) &&\n\t\t\t(at91sam7_info->ext_freq == 0)) {\n\t\t\t\ttarget_read_u32(target, CKGR_PLLR, &pllr);\n\t\t\t\tif (!(pllr & CKGR_PLLR_DIV))\n\t\t\t\t\tbreak;\t/* 0 Hz */\n\t\t\t\tat91sam7_info->mck_valid = 1;\n\t\t\t\tmainfreq = RC_FREQ / 16ul * (mcfr & 0xffff);\n\t\t\t\t/* Integer arithmetic should have sufficient precision\n\t\t\t\t * as long as PLL is properly configured. */\n\t\t\t\ttmp = mainfreq / (pllr & CKGR_PLLR_DIV)*\n\t\t\t\t\t\t(((pllr & CKGR_PLLR_MUL) >> 16) + 1);\n\t\t\t} else if ((at91sam7_info->ext_freq != 0) &&\n\t\t\t\t\t((pllr&CKGR_PLLR_DIV) != 0)) {\n\t\t\t\tat91sam7_info->mck_valid = 1;\n\t\t\t\ttmp = at91sam7_info->ext_freq / (pllr&CKGR_PLLR_DIV)*\n\t\t\t\t\t\t(((pllr & CKGR_PLLR_MUL) >> 16) + 1);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t/* Prescaler adjust */\n\tif ((((mckr & PMC_MCKR_PRES) >> 2) == 7) || (tmp == 0)) {\n\t\tat91sam7_info->mck_valid = 0;\n\t\tat91sam7_info->mck_freq = 0;\n\t} else if (((mckr & PMC_MCKR_PRES) >> 2) != 0)\n\t\tat91sam7_info->mck_freq = tmp >> ((mckr & PMC_MCKR_PRES) >> 2);\n\telse\n\t\tat91sam7_info->mck_freq = tmp;\n}\n\n/* Setup the timing registers for nvbits or normal flash */\nstatic void at91sam7_set_flash_mode(struct flash_bank *bank, int mode)\n{\n\tuint32_t fmr, fmcn = 0, fws = 0;\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (mode && (mode != at91sam7_info->flashmode)) {\n\t\t/* Always round up (ceil) */\n\t\tif (mode == FMR_TIMING_NVBITS) {\n\t\t\tif (at91sam7_info->cidr_arch == 0x60) {\n\t\t\t\t/* AT91SAM7A3 uses master clocks in 100 ns */\n\t\t\t\tfmcn = (at91sam7_info->mck_freq/10000000ul) + 1;\n\t\t\t} else {\n\t\t\t\t/* master clocks in 1uS for ARCH 0x7 types */\n\t\t\t\tfmcn = (at91sam7_info->mck_freq/1000000ul) + 1;\n\t\t\t}\n\t\t} else if (mode == FMR_TIMING_FLASH) {\n\t\t\t/* main clocks in 1.5uS */\n\t\t\tfmcn = (at91sam7_info->mck_freq/1000000ul)+\n\t\t\t\t(at91sam7_info->mck_freq/2000000ul) + 1;\n\t\t}\n\n\t\t/* hard overclocking */\n\t\tif (fmcn > 0xFF)\n\t\t\tfmcn = 0xFF;\n\n\t\t/* Only allow fmcn = 0 if clock period is > 30 us = 33kHz. */\n\t\tif (at91sam7_info->mck_freq <= 33333ul)\n\t\t\tfmcn = 0;\n\t\t/* Only allow fws = 0 if clock frequency is < 30 MHz. */\n\t\tif (at91sam7_info->mck_freq > 30000000ul)\n\t\t\tfws = 1;\n\n\t\tLOG_DEBUG(\"fmcn[%i]: %i\", bank->bank_number, (int)(fmcn));\n\t\tfmr = fmcn << 16 | fws << 8;\n\t\ttarget_write_u32(target, mc_fmr[bank->bank_number], fmr);\n\t}\n\n\tat91sam7_info->flashmode = mode;\n}\n\nstatic uint32_t at91sam7_wait_status_busy(struct flash_bank *bank, uint32_t waitbits, int timeout)\n{\n\tuint32_t status;\n\n\twhile ((!((status = at91sam7_get_flash_status(bank->target,\n\t\t\tbank->bank_number)) & waitbits)) && (timeout-- > 0)) {\n\t\tLOG_DEBUG(\"status[%i]: 0x%\" PRIx32 \"\", (int)bank->bank_number, status);\n\t\talive_sleep(1);\n\t}\n\n\tLOG_DEBUG(\"status[%i]: 0x%\" PRIx32 \"\", bank->bank_number, status);\n\n\tif (status & 0x0C) {\n\t\tLOG_ERROR(\"status register: 0x%\" PRIx32 \"\", status);\n\t\tif (status & 0x4)\n\t\t\tLOG_ERROR(\"Lock Error Bit Detected, Operation Abort\");\n\t\tif (status & 0x8)\n\t\t\tLOG_ERROR(\"Invalid command and/or bad keyword, Operation Abort\");\n\t\tif (status & 0x10)\n\t\t\tLOG_ERROR(\"Security Bit Set, Operation Abort\");\n\t}\n\n\treturn status;\n}\n\n/* Send one command to the AT91SAM flash controller */\nstatic int at91sam7_flash_command(struct flash_bank *bank, uint8_t cmd, uint16_t pagen)\n{\n\tuint32_t fcr;\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tfcr = (0x5A << 24) | ((pagen&0x3FF) << 8) | cmd;\n\ttarget_write_u32(target, mc_fcr[bank->bank_number], fcr);\n\tLOG_DEBUG(\"Flash command: 0x%\" PRIx32 \", flash bank: %i, page number: %u\",\n\t\tfcr,\n\t\tbank->bank_number + 1,\n\t\tpagen);\n\n\tif ((at91sam7_info->cidr_arch == 0x60) && ((cmd == SLB) | (cmd == CLB))) {\n\t\t/* Lock bit manipulation on AT91SAM7A3 waits for FC_FSR bit 1, EOL */\n\t\tif (at91sam7_wait_status_busy(bank, MC_FSR_EOL, 10)&0x0C)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\treturn ERROR_OK;\n\t}\n\n\tif (at91sam7_wait_status_busy(bank, MC_FSR_FRDY, 10)&0x0C)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\n/* Read device id register, main clock frequency register and fill in driver info structure */\nstatic int at91sam7_read_part_info(struct flash_bank *bank)\n{\n\tstruct at91sam7_flash_bank *at91sam7_info;\n\tstruct target *target = bank->target;\n\n\tuint16_t bnk, sec;\n\tuint16_t arch;\n\tuint32_t cidr;\n\tuint8_t banks_num = 0;\n\tuint16_t num_nvmbits = 0;\n\tuint16_t sectors_num = 0;\n\tuint16_t pages_per_sector = 0;\n\tuint16_t page_size = 0;\n\tuint32_t ext_freq;\n\tuint32_t bank_size;\n\tuint32_t base_address = 0;\n\tchar *target_name_t = \"Unknown\";\n\n\tat91sam7_info = bank->driver_priv;\n\n\tif (at91sam7_info->cidr != 0) {\n\t\t/* flash already configured, update clock and check for protected sectors */\n\t\tfor (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {\n\t\t\tif (t_bank->target != target)\n\t\t\t\tcontinue;\n\t\t\t/* re-calculate master clock frequency */\n\t\t\tat91sam7_read_clock_info(t_bank);\n\n\t\t\t/* no timing */\n\t\t\tat91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);\n\n\t\t\t/* check protect state */\n\t\t\tat91sam7_protect_check(t_bank);\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Read and parse chip identification register */\n\ttarget_read_u32(target, DBGU_CIDR, &cidr);\n\tif (cidr == 0) {\n\t\tLOG_WARNING(\"Cannot identify target as an AT91SAM\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (at91sam7_info->flash_autodetection == 0) {\n\t\t/* banks and sectors are already created, based on data from input file */\n\t\tfor (struct flash_bank *t_bank = bank; t_bank; t_bank = t_bank->next) {\n\t\t\tif (t_bank->target != target)\n\t\t\t\tcontinue;\n\n\t\t\tat91sam7_info = t_bank->driver_priv;\n\n\t\t\tat91sam7_info->cidr = cidr;\n\t\t\tat91sam7_info->cidr_ext = (cidr >> 31)&0x0001;\n\t\t\tat91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;\n\t\t\tat91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;\n\t\t\tat91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;\n\t\t\tat91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;\n\t\t\tat91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;\n\t\t\tat91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;\n\t\t\tat91sam7_info->cidr_version = cidr&0x001F;\n\n\t\t\t/* calculate master clock frequency */\n\t\t\tat91sam7_read_clock_info(t_bank);\n\n\t\t\t/* no timing */\n\t\t\tat91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);\n\n\t\t\t/* check protect state */\n\t\t\tat91sam7_protect_check(t_bank);\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\tarch = (cidr >> 20)&0x00FF;\n\n\t/* check flash size */\n\tswitch ((cidr >> 8)&0x000F) {\n\t\tcase FLASH_SIZE_8KB:\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_16KB:\n\t\t\tbanks_num = 1;\n\t\t\tsectors_num = 8;\n\t\t\tpages_per_sector = 32;\n\t\t\tpage_size  = 64;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S161/16\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_32KB:\n\t\t\tbanks_num = 1;\n\t\t\tsectors_num = 8;\n\t\t\tpages_per_sector = 32;\n\t\t\tpage_size  = 128;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S321/32\";\n\t\t\t}\n\t\t\tif (arch == 0x72) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7SE32\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_64KB:\n\t\t\tbanks_num = 1;\n\t\t\tsectors_num = 16;\n\t\t\tpages_per_sector = 32;\n\t\t\tpage_size  = 128;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S64\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_128KB:\n\t\t\tbanks_num = 1;\n\t\t\tsectors_num = 8;\n\t\t\tpages_per_sector = 64;\n\t\t\tpage_size  = 256;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S128\";\n\t\t\t}\n\t\t\tif (arch == 0x71) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7XC128\";\n\t\t\t}\n\t\t\tif (arch == 0x72) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7SE128\";\n\t\t\t}\n\t\t\tif (arch == 0x75) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7X128\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_256KB:\n\t\t\tbanks_num = 1;\n\t\t\tsectors_num = 16;\n\t\t\tpages_per_sector = 64;\n\t\t\tpage_size  = 256;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x60) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7A3\";\n\t\t\t}\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S256\";\n\t\t\t}\n\t\t\tif (arch == 0x71) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7XC256\";\n\t\t\t}\n\t\t\tif (arch == 0x72) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7SE256\";\n\t\t\t}\n\t\t\tif (arch == 0x75) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7X256\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_512KB:\n\t\t\tbanks_num = 2;\n\t\t\tsectors_num = 16;\n\t\t\tpages_per_sector = 64;\n\t\t\tpage_size  = 256;\n\t\t\tbase_address = 0x00100000;\n\t\t\tif (arch == 0x70) {\n\t\t\t\tnum_nvmbits = 2;\n\t\t\t\ttarget_name_t = \"AT91SAM7S512\";\n\t\t\t}\n\t\t\tif (arch == 0x71) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7XC512\";\n\t\t\t}\n\t\t\tif (arch == 0x72) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7SE512\";\n\t\t\t}\n\t\t\tif (arch == 0x75) {\n\t\t\t\tnum_nvmbits = 3;\n\t\t\t\ttarget_name_t = \"AT91SAM7X512\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_1024KB:\n\t\t\tbreak;\n\n\t\tcase FLASH_SIZE_2048KB:\n\t\t\tbreak;\n\t}\n\n\tif (strcmp(target_name_t, \"Unknown\") == 0) {\n\t\tLOG_ERROR(\n\t\t\t\"Target autodetection failed! Please specify target parameters in configuration file\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\text_freq = at91sam7_info->ext_freq;\n\n\t/* calculate bank size  */\n\tbank_size = sectors_num * pages_per_sector * page_size;\n\n\tfor (bnk = 0; bnk < banks_num; bnk++) {\n\t\tstruct flash_bank *t_bank = bank;\n\t\tif (bnk > 0) {\n\t\t\tif (!t_bank->next) {\n\t\t\t\t/* create a new flash bank element */\n\t\t\t\tstruct flash_bank *fb = malloc(sizeof(struct flash_bank));\n\t\t\t\tfb->target = target;\n\t\t\t\tfb->driver = bank->driver;\n\t\t\t\tfb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));\n\t\t\t\tfb->name = \"sam7_probed\";\n\t\t\t\tfb->next = NULL;\n\n\t\t\t\t/* link created bank in 'flash_banks' list */\n\t\t\t\tt_bank->next = fb;\n\t\t\t}\n\t\t\tt_bank = t_bank->next;\n\t\t}\n\n\t\tt_bank->bank_number = bnk;\n\t\tt_bank->base = base_address + bnk * bank_size;\n\t\tt_bank->size = bank_size;\n\t\tt_bank->num_sectors = sectors_num;\n\n\t\t/* allocate sectors */\n\t\tt_bank->sectors = malloc(sectors_num * sizeof(struct flash_sector));\n\t\tfor (sec = 0; sec < sectors_num; sec++) {\n\t\t\tt_bank->sectors[sec].offset = sec * pages_per_sector * page_size;\n\t\t\tt_bank->sectors[sec].size = pages_per_sector * page_size;\n\t\t\tt_bank->sectors[sec].is_erased = -1;\n\t\t\tt_bank->sectors[sec].is_protected = -1;\n\t\t}\n\n\t\tat91sam7_info = t_bank->driver_priv;\n\n\t\tat91sam7_info->cidr = cidr;\n\t\tat91sam7_info->cidr_ext = (cidr >> 31)&0x0001;\n\t\tat91sam7_info->cidr_nvptyp = (cidr >> 28)&0x0007;\n\t\tat91sam7_info->cidr_arch = (cidr >> 20)&0x00FF;\n\t\tat91sam7_info->cidr_sramsiz = (cidr >> 16)&0x000F;\n\t\tat91sam7_info->cidr_nvpsiz2 = (cidr >> 12)&0x000F;\n\t\tat91sam7_info->cidr_nvpsiz = (cidr >> 8)&0x000F;\n\t\tat91sam7_info->cidr_eproc = (cidr >> 5)&0x0007;\n\t\tat91sam7_info->cidr_version = cidr&0x001F;\n\n\t\tat91sam7_info->target_name  = target_name_t;\n\t\tat91sam7_info->flashmode = 0;\n\t\tat91sam7_info->ext_freq = ext_freq;\n\t\tat91sam7_info->num_nvmbits = num_nvmbits;\n\t\tat91sam7_info->num_nvmbits_on = 0;\n\t\tat91sam7_info->pagesize = page_size;\n\t\tat91sam7_info->pages_per_sector = pages_per_sector;\n\n\t\t/* calculate master clock frequency */\n\t\tat91sam7_read_clock_info(t_bank);\n\n\t\t/* no timing */\n\t\tat91sam7_set_flash_mode(t_bank, FMR_TIMING_NONE);\n\n\t\t/* check protect state */\n\t\tat91sam7_protect_check(t_bank);\n\t}\n\n\tLOG_DEBUG(\"nvptyp: 0x%3.3x, arch: 0x%4.4x\",\n\t\tat91sam7_info->cidr_nvptyp,\n\t\tat91sam7_info->cidr_arch);\n\n\treturn ERROR_OK;\n}\n\nstatic int at91sam7_erase_check(struct flash_bank *bank)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Configure the flash controller timing */\n\tat91sam7_read_clock_info(bank);\n\tat91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);\n\n\treturn default_flash_blank_check(bank);\n}\n\nstatic int at91sam7_protect_check(struct flash_bank *bank)\n{\n\tuint8_t lock_pos, gpnvm_pos;\n\tuint32_t status;\n\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\n\tif (at91sam7_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstatus = at91sam7_get_flash_status(bank->target, bank->bank_number);\n\tat91sam7_info->lockbits = (status >> 16);\n\n\tat91sam7_info->num_lockbits_on = 0;\n\tfor (lock_pos = 0; lock_pos < bank->num_sectors; lock_pos++) {\n\t\tif (((status >> (16 + lock_pos))&(0x0001)) == 1) {\n\t\t\tat91sam7_info->num_lockbits_on++;\n\t\t\tbank->sectors[lock_pos].is_protected = 1;\n\t\t} else\n\t\t\tbank->sectors[lock_pos].is_protected = 0;\n\t}\n\n\t/* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */\n\tstatus = at91sam7_get_flash_status(bank->target, 0);\n\n\tat91sam7_info->securitybit = (status >> 4)&0x01;\n\tat91sam7_info->nvmbits = (status >> 8)&0xFF;\n\n\tat91sam7_info->num_nvmbits_on = 0;\n\tfor (gpnvm_pos = 0; gpnvm_pos < at91sam7_info->num_nvmbits; gpnvm_pos++) {\n\t\tif (((status >> (8 + gpnvm_pos))&(0x01)) == 1)\n\t\t\tat91sam7_info->num_nvmbits_on++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(at91sam7_flash_bank_command)\n{\n\tstruct flash_bank *t_bank = bank;\n\tstruct at91sam7_flash_bank *at91sam7_info;\n\tstruct target *target = t_bank->target;\n\n\tuint32_t base_address;\n\tuint32_t bank_size;\n\tuint32_t ext_freq = 0;\n\n\tunsigned int banks_num;\n\tunsigned int num_sectors;\n\n\tuint16_t pages_per_sector;\n\tuint16_t page_size;\n\tuint16_t num_nvmbits;\n\n\tat91sam7_info = malloc(sizeof(struct at91sam7_flash_bank));\n\tt_bank->driver_priv = at91sam7_info;\n\n\t/* part wasn't probed for info yet */\n\tat91sam7_info->cidr = 0;\n\tat91sam7_info->flashmode = 0;\n\tat91sam7_info->ext_freq = 0;\n\tat91sam7_info->flash_autodetection = 0;\n\n\tif (CMD_ARGC < 13) {\n\t\tat91sam7_info->flash_autodetection = 1;\n\t\treturn ERROR_OK;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], base_address);\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], banks_num);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], num_sectors);\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[10], pages_per_sector);\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[11], page_size);\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[12], num_nvmbits);\n\n\tif (CMD_ARGC == 14) {\n\t\tunsigned long freq;\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[13], freq);\n\t\text_freq = freq * 1000;\n\t\tat91sam7_info->ext_freq = ext_freq;\n\t}\n\n\tif ((banks_num == 0) || (num_sectors == 0) ||\n\t\t\t(pages_per_sector == 0) || (page_size == 0) || (num_nvmbits == 0)) {\n\t\tat91sam7_info->flash_autodetection = 1;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* calculate bank size  */\n\tbank_size = num_sectors * pages_per_sector * page_size;\n\n\tfor (unsigned int bnk = 0; bnk < banks_num; bnk++) {\n\t\tif (bnk > 0) {\n\t\t\tif (!t_bank->next) {\n\t\t\t\t/* create a new bank element */\n\t\t\t\tstruct flash_bank *fb = malloc(sizeof(struct flash_bank));\n\t\t\t\tfb->target = target;\n\t\t\t\tfb->driver = bank->driver;\n\t\t\t\tfb->driver_priv = malloc(sizeof(struct at91sam7_flash_bank));\n\t\t\t\tfb->name = \"sam7_probed\";\n\t\t\t\tfb->next = NULL;\n\n\t\t\t\t/* link created bank in 'flash_banks' list */\n\t\t\t\tt_bank->next = fb;\n\t\t\t}\n\t\t\tt_bank = t_bank->next;\n\t\t}\n\n\t\tt_bank->bank_number = bnk;\n\t\tt_bank->base = base_address + bnk * bank_size;\n\t\tt_bank->size = bank_size;\n\t\tt_bank->num_sectors = num_sectors;\n\n\t\t/* allocate sectors */\n\t\tt_bank->sectors = malloc(num_sectors * sizeof(struct flash_sector));\n\t\tfor (unsigned int sec = 0; sec < num_sectors; sec++) {\n\t\t\tt_bank->sectors[sec].offset = sec * pages_per_sector * page_size;\n\t\t\tt_bank->sectors[sec].size = pages_per_sector * page_size;\n\t\t\tt_bank->sectors[sec].is_erased = -1;\n\t\t\tt_bank->sectors[sec].is_protected = -1;\n\t\t}\n\n\t\tat91sam7_info = t_bank->driver_priv;\n\n\t\tat91sam7_info->target_name = strdup(CMD_ARGV[7]);\n\t\tat91sam7_info->flashmode = 0;\n\t\tat91sam7_info->ext_freq  = ext_freq;\n\t\tat91sam7_info->num_nvmbits = num_nvmbits;\n\t\tat91sam7_info->num_nvmbits_on = 0;\n\t\tat91sam7_info->pagesize = page_size;\n\t\tat91sam7_info->pages_per_sector = pages_per_sector;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int at91sam7_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\tuint32_t nbytes, pos;\n\tuint8_t *buffer;\n\tuint8_t erase_all;\n\n\tif (at91sam7_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\terase_all = 0;\n\tif ((first == 0) && (last == (bank->num_sectors-1)))\n\t\terase_all = 1;\n\n\t/* Configure the flash controller timing */\n\tat91sam7_read_clock_info(bank);\n\tat91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);\n\n\tif (erase_all) {\n\t\tif (at91sam7_flash_command(bank, EA, 0) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t} else {\n\t\t/* allocate and clean buffer  */\n\t\tnbytes = (last - first + 1) * bank->sectors[first].size;\n\t\tbuffer = malloc(nbytes * sizeof(uint8_t));\n\t\tfor (pos = 0; pos < nbytes; pos++)\n\t\t\tbuffer[pos] = 0xFF;\n\n\t\tif (at91sam7_write(bank, buffer, bank->sectors[first].offset, nbytes) != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tfree(buffer);\n\t}\n\n\t/* mark erased sectors */\n\tfor (unsigned int sec = first; sec <= last; sec++)\n\t\tbank->sectors[sec].is_erased = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int at91sam7_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tuint32_t cmd;\n\tuint32_t pagen;\n\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\n\tif (at91sam7_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\t/* Configure the flash controller timing */\n\tat91sam7_read_clock_info(bank);\n\tat91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (set)\n\t\t\tcmd = SLB;\n\t\telse\n\t\t\tcmd = CLB;\n\n\t\t/* if we lock a page from one sector then entire sector will be locked, also,\n\t\t * if we unlock a page from a locked sector, entire sector will be unlocked   */\n\t\tpagen = sector * at91sam7_info->pages_per_sector;\n\n\t\tif (at91sam7_flash_command(bank, cmd, pagen) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tat91sam7_protect_check(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int at91sam7_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t dst_min_alignment, wcount, bytes_remaining = count;\n\tuint32_t first_page, last_page, pagen, buffer_pos;\n\n\tif (at91sam7_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tdst_min_alignment = at91sam7_info->pagesize;\n\n\tif (offset % dst_min_alignment) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required alignment 0x%\" PRIx32 \"\",\n\t\t\toffset,\n\t\t\tdst_min_alignment);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (at91sam7_info->cidr_arch == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tfirst_page = offset/dst_min_alignment;\n\tlast_page = DIV_ROUND_UP(offset + count, dst_min_alignment);\n\n\tLOG_DEBUG(\"first_page: %i, last_page: %i, count %i\",\n\t\t(int)first_page,\n\t\t(int)last_page,\n\t\t(int)count);\n\n\t/* Configure the flash controller timing */\n\tat91sam7_read_clock_info(bank);\n\tat91sam7_set_flash_mode(bank, FMR_TIMING_FLASH);\n\n\tfor (pagen = first_page; pagen < last_page; pagen++) {\n\t\tif (bytes_remaining < dst_min_alignment)\n\t\t\tcount = bytes_remaining;\n\t\telse\n\t\t\tcount = dst_min_alignment;\n\t\tbytes_remaining -= count;\n\n\t\t/* Write one block to the PageWriteBuffer */\n\t\tbuffer_pos = (pagen-first_page)*dst_min_alignment;\n\t\twcount = DIV_ROUND_UP(count, 4);\n\t\tretval = target_write_memory(target, bank->base + pagen*dst_min_alignment, 4,\n\t\t\t\twcount, buffer + buffer_pos);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Send Write Page command to Flash Controller */\n\t\tif (at91sam7_flash_command(bank, WP, pagen) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\tLOG_DEBUG(\"Write flash bank:%u page number:%\" PRIu32, bank->bank_number, pagen);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int at91sam7_probe(struct flash_bank *bank)\n{\n\t/* we can't probe on an at91sam7\n\t * if this is an at91sam7, it has the configured flash */\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = at91sam7_read_part_info(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int get_at91sam7_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct at91sam7_flash_bank *at91sam7_info = bank->driver_priv;\n\n\tif (at91sam7_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tcommand_print_sameline(cmd, \"\\n at91sam7 driver information: Chip is %s\\n\",\n\t\t\tat91sam7_info->target_name);\n\n\tcommand_print_sameline(cmd,\n\t\t\t\" Cidr: 0x%8.8\" PRIx32 \" | Arch: 0x%4.4x | Eproc: %s | Version: 0x%3.3x | \"\n\t\t\t\"Flashsize: 0x%8.8\" PRIx32 \"\\n\",\n\t\t\tat91sam7_info->cidr,\n\t\t\tat91sam7_info->cidr_arch,\n\t\t\teproc[at91sam7_info->cidr_eproc],\n\t\t\tat91sam7_info->cidr_version,\n\t\t\tbank->size);\n\n\tcommand_print_sameline(cmd,\n\t\t\t\" Master clock (estimated): %u kHz | External clock: %u kHz\\n\",\n\t\t\t(unsigned)(at91sam7_info->mck_freq / 1000),\n\t\t\t(unsigned)(at91sam7_info->ext_freq / 1000));\n\n\tcommand_print_sameline(cmd,\n\t\t\t\" Pagesize: %i bytes | Lockbits(%u): %i 0x%4.4x | Pages in lock region: %i\\n\",\n\t\t\tat91sam7_info->pagesize,\n\t\t\tbank->num_sectors,\n\t\t\tat91sam7_info->num_lockbits_on,\n\t\t\tat91sam7_info->lockbits,\n\t\t\tat91sam7_info->pages_per_sector * at91sam7_info->num_lockbits_on);\n\n\tcommand_print_sameline(cmd, \" Securitybit: %i | Nvmbits(%i): %i 0x%1.1x\\n\",\n\t\tat91sam7_info->securitybit, at91sam7_info->num_nvmbits,\n\t\tat91sam7_info->num_nvmbits_on, at91sam7_info->nvmbits);\n\n\treturn ERROR_OK;\n}\n\n/*\n* On AT91SAM7S: When the gpnvm bits are set with\n* > at91sam7 gpnvm bitnr set\n* the changes are not visible in the flash controller status register MC_FSR\n* until the processor has been reset.\n* On the Olimex board this requires a power cycle.\n* Note that the AT91SAM7S has the following errata (doc6175.pdf sec 14.1.3):\n*   The maximum number of write/erase cycles for Non volatile Memory bits is 100. this includes\n*   Lock Bits (LOCKx), General Purpose NVM bits (GPNVMx) and the Security Bit.\n*/\nCOMMAND_HANDLER(at91sam7_handle_gpnvm_command)\n{\n\tstruct flash_bank *bank;\n\tint bit;\n\tuint8_t flashcmd;\n\tuint32_t status;\n\tstruct at91sam7_flash_bank *at91sam7_info;\n\tint retval;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tbank = get_flash_bank_by_num_noprobe(0);\n\tif (!bank)\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\tif (strcmp(bank->driver->name, \"at91sam7\")) {\n\t\tcommand_print(CMD, \"not an at91sam7 flash bank '%s'\", CMD_ARGV[0]);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target has to be halted to perform flash operation\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (strcmp(CMD_ARGV[1], \"set\") == 0)\n\t\tflashcmd = SGPB;\n\telse if (strcmp(CMD_ARGV[1], \"clear\") == 0)\n\t\tflashcmd = CGPB;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tat91sam7_info = bank->driver_priv;\n\tif (at91sam7_info->cidr == 0) {\n\t\tretval = at91sam7_read_part_info(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], bit);\n\tif ((bit < 0) || (bit >= at91sam7_info->num_nvmbits)) {\n\t\tcommand_print(CMD,\n\t\t\t\"gpnvm bit '#%s' is out of bounds for target %s\",\n\t\t\tCMD_ARGV[0],\n\t\t\tat91sam7_info->target_name);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Configure the flash controller timing */\n\tat91sam7_read_clock_info(bank);\n\tat91sam7_set_flash_mode(bank, FMR_TIMING_NVBITS);\n\n\tif (at91sam7_flash_command(bank, flashcmd, bit) != ERROR_OK)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* GPNVM and SECURITY bits apply only for MC_FSR of EFC0 */\n\tstatus = at91sam7_get_flash_status(bank->target, 0);\n\tLOG_DEBUG(\"at91sam7_handle_gpnvm_command: cmd 0x%x, value %d, status 0x%\" PRIx32,\n\t\tflashcmd,\n\t\tbit,\n\t\tstatus);\n\n\t/* check protect state */\n\tat91sam7_protect_check(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration at91sam7_exec_command_handlers[] = {\n\t{\n\t\t.name = \"gpnvm\",\n\t\t.handler = at91sam7_handle_gpnvm_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set or clear one General Purpose Non-Volatile Memory \"\n\t\t\t\"(gpnvm) bit\",\n\t\t.usage = \"bitnum ('set'|'clear')\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration at91sam7_command_handlers[] = {\n\t{\n\t\t.name = \"at91sam7\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"at91sam7 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = at91sam7_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver at91sam7_flash = {\n\t.name = \"at91sam7\",\n\t.usage = \"gpnvm <bit> <set | clear>\",\n\t.commands = at91sam7_command_handlers,\n\t.flash_bank_command = at91sam7_flash_bank_command,\n\t.erase = at91sam7_erase,\n\t.protect = at91sam7_protect,\n\t.write = at91sam7_write,\n\t.read = default_flash_read,\n\t.probe = at91sam7_probe,\n\t.auto_probe = at91sam7_probe,\n\t.erase_check = at91sam7_erase_check,\n\t.protect_check = at91sam7_protect_check,\n\t.info = get_at91sam7_info,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/at91samd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Andrey Yurovsky                                 *\n *   Andrey Yurovsky <yurovsky@gmail.com>                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"helper/binarybuffer.h\"\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include <target/cortex_m.h>\n\n#define SAMD_NUM_PROT_BLOCKS\t16\n#define SAMD_PAGE_SIZE_MAX\t1024\n\n#define SAMD_FLASH\t\t\t((uint32_t)0x00000000)\t/* physical Flash memory */\n#define SAMD_USER_ROW\t\t((uint32_t)0x00804000)\t/* User Row of Flash */\n#define SAMD_PAC1\t\t\t0x41000000\t/* Peripheral Access Control 1 */\n#define SAMD_DSU\t\t\t0x41002000\t/* Device Service Unit */\n#define SAMD_NVMCTRL\t\t0x41004000\t/* Non-volatile memory controller */\n\n#define SAMD_DSU_STATUSA        1               /* DSU status register */\n#define SAMD_DSU_DID\t\t0x18\t\t/* Device ID register */\n#define SAMD_DSU_CTRL_EXT\t0x100\t\t/* CTRL register, external access */\n\n#define SAMD_NVMCTRL_CTRLA\t\t0x00\t/* NVM control A register */\n#define SAMD_NVMCTRL_CTRLB\t\t0x04\t/* NVM control B register */\n#define SAMD_NVMCTRL_PARAM\t\t0x08\t/* NVM parameters register */\n#define SAMD_NVMCTRL_INTFLAG\t0x14\t/* NVM Interrupt Flag Status & Clear */\n#define SAMD_NVMCTRL_STATUS\t\t0x18\t/* NVM status register */\n#define SAMD_NVMCTRL_ADDR\t\t0x1C\t/* NVM address register */\n#define SAMD_NVMCTRL_LOCK\t\t0x20\t/* NVM Lock section register */\n\n#define SAMD_CMDEX_KEY\t\t0xA5UL\n#define SAMD_NVM_CMD(n)\t\t((SAMD_CMDEX_KEY << 8) | (n & 0x7F))\n\n/* NVMCTRL commands.  See Table 20-4 in 42129F–SAM–10/2013 */\n#define SAMD_NVM_CMD_ER\t\t0x02\t\t/* Erase Row */\n#define SAMD_NVM_CMD_WP\t\t0x04\t\t/* Write Page */\n#define SAMD_NVM_CMD_EAR\t0x05\t\t/* Erase Auxiliary Row */\n#define SAMD_NVM_CMD_WAP\t0x06\t\t/* Write Auxiliary Page */\n#define SAMD_NVM_CMD_LR\t\t0x40\t\t/* Lock Region */\n#define SAMD_NVM_CMD_UR\t\t0x41\t\t/* Unlock Region */\n#define SAMD_NVM_CMD_SPRM\t0x42\t\t/* Set Power Reduction Mode */\n#define SAMD_NVM_CMD_CPRM\t0x43\t\t/* Clear Power Reduction Mode */\n#define SAMD_NVM_CMD_PBC\t0x44\t\t/* Page Buffer Clear */\n#define SAMD_NVM_CMD_SSB\t0x45\t\t/* Set Security Bit */\n#define SAMD_NVM_CMD_INVALL\t0x46\t\t/* Invalidate all caches */\n\n/* NVMCTRL bits */\n#define SAMD_NVM_CTRLB_MANW 0x80\n\n/* NVMCTRL_INTFLAG bits */\n#define SAMD_NVM_INTFLAG_READY 0x01\n\n/* Known identifiers */\n#define SAMD_PROCESSOR_M0\t0x01\n#define SAMD_FAMILY_D\t\t0x00\n#define SAMD_FAMILY_L\t\t0x01\n#define SAMD_FAMILY_C\t\t0x02\n#define SAMD_SERIES_20\t\t0x00\n#define SAMD_SERIES_21\t\t0x01\n#define SAMD_SERIES_22\t\t0x02\n#define SAMD_SERIES_10\t\t0x02\n#define SAMD_SERIES_11\t\t0x03\n#define SAMD_SERIES_09\t\t0x04\n\n/* Device ID macros */\n#define SAMD_GET_PROCESSOR(id) (id >> 28)\n#define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F))\n#define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F))\n#define SAMD_GET_DEVSEL(id) (id & 0xFF)\n\n/* Bits to mask out lockbits in user row */\n#define NVMUSERROW_LOCKBIT_MASK 0x0000FFFFFFFFFFFFULL\n\nstruct samd_part {\n\tuint8_t id;\n\tconst char *name;\n\tuint32_t flash_kb;\n\tuint32_t ram_kb;\n};\n\n/* Known SAMD09 parts. DID reset values missing in RM, see\n * https://github.com/avrxml/asf/blob/master/sam0/utils/cmsis/samd09/include/ */\nstatic const struct samd_part samd09_parts[] = {\n\t{ 0x0, \"SAMD09D14A\", 16, 4 },\n\t{ 0x7, \"SAMD09C13A\", 8, 4 },\n};\n\n/* Known SAMD10 parts */\nstatic const struct samd_part samd10_parts[] = {\n\t{ 0x0, \"SAMD10D14AMU\", 16, 4 },\n\t{ 0x1, \"SAMD10D13AMU\", 8, 4 },\n\t{ 0x2, \"SAMD10D12AMU\", 4, 4 },\n\t{ 0x3, \"SAMD10D14ASU\", 16, 4 },\n\t{ 0x4, \"SAMD10D13ASU\", 8, 4 },\n\t{ 0x5, \"SAMD10D12ASU\", 4, 4 },\n\t{ 0x6, \"SAMD10C14A\", 16, 4 },\n\t{ 0x7, \"SAMD10C13A\", 8, 4 },\n\t{ 0x8, \"SAMD10C12A\", 4, 4 },\n};\n\n/* Known SAMD11 parts */\nstatic const struct samd_part samd11_parts[] = {\n\t{ 0x0, \"SAMD11D14AM\", 16, 4 },\n\t{ 0x1, \"SAMD11D13AMU\", 8, 4 },\n\t{ 0x2, \"SAMD11D12AMU\", 4, 4 },\n\t{ 0x3, \"SAMD11D14ASS\", 16, 4 },\n\t{ 0x4, \"SAMD11D13ASU\", 8, 4 },\n\t{ 0x5, \"SAMD11D12ASU\", 4, 4 },\n\t{ 0x6, \"SAMD11C14A\", 16, 4 },\n\t{ 0x7, \"SAMD11C13A\", 8, 4 },\n\t{ 0x8, \"SAMD11C12A\", 4, 4 },\n\t{ 0x9, \"SAMD11D14AU\", 16, 4 },\n};\n\n/* Known SAMD20 parts. See Table 12-8 in 42129F–SAM–10/2013 */\nstatic const struct samd_part samd20_parts[] = {\n\t{ 0x0, \"SAMD20J18A\", 256, 32 },\n\t{ 0x1, \"SAMD20J17A\", 128, 16 },\n\t{ 0x2, \"SAMD20J16A\", 64, 8 },\n\t{ 0x3, \"SAMD20J15A\", 32, 4 },\n\t{ 0x4, \"SAMD20J14A\", 16, 2 },\n\t{ 0x5, \"SAMD20G18A\", 256, 32 },\n\t{ 0x6, \"SAMD20G17A\", 128, 16 },\n\t{ 0x7, \"SAMD20G16A\", 64, 8 },\n\t{ 0x8, \"SAMD20G15A\", 32, 4 },\n\t{ 0x9, \"SAMD20G14A\", 16, 2 },\n\t{ 0xA, \"SAMD20E18A\", 256, 32 },\n\t{ 0xB, \"SAMD20E17A\", 128, 16 },\n\t{ 0xC, \"SAMD20E16A\", 64, 8 },\n\t{ 0xD, \"SAMD20E15A\", 32, 4 },\n\t{ 0xE, \"SAMD20E14A\", 16, 2 },\n};\n\n/* Known SAMD21 parts. */\nstatic const struct samd_part samd21_parts[] = {\n\t{ 0x0, \"SAMD21J18A\", 256, 32 },\n\t{ 0x1, \"SAMD21J17A\", 128, 16 },\n\t{ 0x2, \"SAMD21J16A\", 64, 8 },\n\t{ 0x3, \"SAMD21J15A\", 32, 4 },\n\t{ 0x4, \"SAMD21J14A\", 16, 2 },\n\t{ 0x5, \"SAMD21G18A\", 256, 32 },\n\t{ 0x6, \"SAMD21G17A\", 128, 16 },\n\t{ 0x7, \"SAMD21G16A\", 64, 8 },\n\t{ 0x8, \"SAMD21G15A\", 32, 4 },\n\t{ 0x9, \"SAMD21G14A\", 16, 2 },\n\t{ 0xA, \"SAMD21E18A\", 256, 32 },\n\t{ 0xB, \"SAMD21E17A\", 128, 16 },\n\t{ 0xC, \"SAMD21E16A\", 64, 8 },\n\t{ 0xD, \"SAMD21E15A\", 32, 4 },\n\t{ 0xE, \"SAMD21E14A\", 16, 2 },\n\n    /* SAMR21 parts have integrated SAMD21 with a radio */\n\t{ 0x18, \"SAMR21G19A\", 256, 32 }, /* with 512k of serial flash */\n\t{ 0x19, \"SAMR21G18A\", 256, 32 },\n\t{ 0x1A, \"SAMR21G17A\", 128, 32 },\n\t{ 0x1B, \"SAMR21G16A\",  64, 16 },\n\t{ 0x1C, \"SAMR21E18A\", 256, 32 },\n\t{ 0x1D, \"SAMR21E17A\", 128, 32 },\n\t{ 0x1E, \"SAMR21E16A\",  64, 16 },\n\n    /* SAMD21 B Variants (Table 3-7 from rev I of datasheet) */\n\t{ 0x20, \"SAMD21J16B\", 64, 8 },\n\t{ 0x21, \"SAMD21J15B\", 32, 4 },\n\t{ 0x23, \"SAMD21G16B\", 64, 8 },\n\t{ 0x24, \"SAMD21G15B\", 32, 4 },\n\t{ 0x26, \"SAMD21E16B\", 64, 8 },\n\t{ 0x27, \"SAMD21E15B\", 32, 4 },\n\n\t/* SAMD21 D and L Variants (from Errata)\n\t   http://ww1.microchip.com/downloads/en/DeviceDoc/\n\t   SAM-D21-Family-Silicon-Errata-and-DataSheet-Clarification-DS80000760D.pdf */\n\t{ 0x55, \"SAMD21E16BU\", 64, 8 },\n\t{ 0x56, \"SAMD21E15BU\", 32, 4 },\n\t{ 0x57, \"SAMD21G16L\", 64, 8 },\n\t{ 0x3E, \"SAMD21E16L\", 64, 8 },\n\t{ 0x3F, \"SAMD21E15L\", 32, 4 },\n\t{ 0x62, \"SAMD21E16CU\", 64, 8 },\n\t{ 0x63, \"SAMD21E15CU\", 32, 4 },\n\t{ 0x92, \"SAMD21J17D\", 128, 16 },\n\t{ 0x93, \"SAMD21G17D\", 128, 16 },\n\t{ 0x94, \"SAMD21E17D\", 128, 16 },\n\t{ 0x95, \"SAMD21E17DU\", 128, 16 },\n\t{ 0x96, \"SAMD21G17L\", 128, 16 },\n\t{ 0x97, \"SAMD21E17L\", 128, 16 },\n\n\t/* Known SAMDA1 parts.\n\t   SAMD-A1 series uses the same series identifier like the SAMD21\n\t   taken from http://ww1.microchip.com/downloads/en/DeviceDoc/40001895A.pdf (pages 14-17) */\n\t{ 0x29, \"SAMDA1J16A\", 64, 8 },\n\t{ 0x2A, \"SAMDA1J15A\", 32, 4 },\n\t{ 0x2B, \"SAMDA1J14A\", 16, 4 },\n\t{ 0x2C, \"SAMDA1G16A\", 64, 8 },\n\t{ 0x2D, \"SAMDA1G15A\", 32, 4 },\n\t{ 0x2E, \"SAMDA1G14A\", 16, 4 },\n\t{ 0x2F, \"SAMDA1E16A\", 64, 8 },\n\t{ 0x30, \"SAMDA1E15A\", 32, 4 },\n\t{ 0x31, \"SAMDA1E14A\", 16, 4 },\n\t{ 0x64, \"SAMDA1J16B\", 64, 8 },\n\t{ 0x65, \"SAMDA1J15B\", 32, 4 },\n\t{ 0x66, \"SAMDA1J14B\", 16, 4 },\n\t{ 0x67, \"SAMDA1G16B\", 64, 8 },\n\t{ 0x68, \"SAMDA1G15B\", 32, 4 },\n\t{ 0x69, \"SAMDA1G14B\", 16, 4 },\n\t{ 0x6A, \"SAMDA1E16B\", 64, 8 },\n\t{ 0x6B, \"SAMDA1E15B\", 32, 4 },\n\t{ 0x6C, \"SAMDA1E14B\", 16, 4 },\n};\n\n/* Known SAML21 parts. */\nstatic const struct samd_part saml21_parts[] = {\n\t{ 0x00, \"SAML21J18A\", 256, 32 },\n\t{ 0x01, \"SAML21J17A\", 128, 16 },\n\t{ 0x02, \"SAML21J16A\", 64, 8 },\n\t{ 0x05, \"SAML21G18A\", 256, 32 },\n\t{ 0x06, \"SAML21G17A\", 128, 16 },\n\t{ 0x07, \"SAML21G16A\", 64, 8 },\n\t{ 0x0A, \"SAML21E18A\", 256, 32 },\n\t{ 0x0B, \"SAML21E17A\", 128, 16 },\n\t{ 0x0C, \"SAML21E16A\", 64, 8 },\n\t{ 0x0D, \"SAML21E15A\", 32, 4 },\n\t{ 0x0F, \"SAML21J18B\", 256, 32 },\n\t{ 0x10, \"SAML21J17B\", 128, 16 },\n\t{ 0x11, \"SAML21J16B\", 64, 8 },\n\t{ 0x14, \"SAML21G18B\", 256, 32 },\n\t{ 0x15, \"SAML21G17B\", 128, 16 },\n\t{ 0x16, \"SAML21G16B\", 64, 8 },\n\t{ 0x19, \"SAML21E18B\", 256, 32 },\n\t{ 0x1A, \"SAML21E17B\", 128, 16 },\n\t{ 0x1B, \"SAML21E16B\", 64, 8 },\n\t{ 0x1C, \"SAML21E15B\", 32, 4 },\n\n    /* SAMR30 parts have integrated SAML21 with a radio */\n\t{ 0x1E, \"SAMR30G18A\", 256, 32 },\n\t{ 0x1F, \"SAMR30E18A\", 256, 32 },\n\n    /* SAMR34/R35 parts have integrated SAML21 with a lora radio */\n\t{ 0x28, \"SAMR34J18\", 256, 40 },\n\t{ 0x29, \"SAMR34J17\", 128, 24 },\n\t{ 0x2A, \"SAMR34J16\", 64, 12 },\n\t{ 0x2B, \"SAMR35J18\", 256, 40 },\n\t{ 0x2C, \"SAMR35J17\", 128, 24 },\n\t{ 0x2D, \"SAMR35J16\", 64, 12 },\n};\n\n/* Known SAML22 parts. */\nstatic const struct samd_part saml22_parts[] = {\n\t{ 0x00, \"SAML22N18A\", 256, 32 },\n\t{ 0x01, \"SAML22N17A\", 128, 16 },\n\t{ 0x02, \"SAML22N16A\", 64, 8 },\n\t{ 0x05, \"SAML22J18A\", 256, 32 },\n\t{ 0x06, \"SAML22J17A\", 128, 16 },\n\t{ 0x07, \"SAML22J16A\", 64, 8 },\n\t{ 0x0A, \"SAML22G18A\", 256, 32 },\n\t{ 0x0B, \"SAML22G17A\", 128, 16 },\n\t{ 0x0C, \"SAML22G16A\", 64, 8 },\n};\n\n/* Known SAMC20 parts. */\nstatic const struct samd_part samc20_parts[] = {\n\t{ 0x00, \"SAMC20J18A\", 256, 32 },\n\t{ 0x01, \"SAMC20J17A\", 128, 16 },\n\t{ 0x02, \"SAMC20J16A\", 64, 8 },\n\t{ 0x03, \"SAMC20J15A\", 32, 4 },\n\t{ 0x05, \"SAMC20G18A\", 256, 32 },\n\t{ 0x06, \"SAMC20G17A\", 128, 16 },\n\t{ 0x07, \"SAMC20G16A\", 64, 8 },\n\t{ 0x08, \"SAMC20G15A\", 32, 4 },\n\t{ 0x0A, \"SAMC20E18A\", 256, 32 },\n\t{ 0x0B, \"SAMC20E17A\", 128, 16 },\n\t{ 0x0C, \"SAMC20E16A\", 64, 8 },\n\t{ 0x0D, \"SAMC20E15A\", 32, 4 },\n\t{ 0x20, \"SAMC20N18A\", 256, 32 },\n\t{ 0x21, \"SAMC20N17A\", 128, 16 },\n};\n\n/* Known SAMC21 parts. */\nstatic const struct samd_part samc21_parts[] = {\n\t{ 0x00, \"SAMC21J18A\", 256, 32 },\n\t{ 0x01, \"SAMC21J17A\", 128, 16 },\n\t{ 0x02, \"SAMC21J16A\", 64, 8 },\n\t{ 0x03, \"SAMC21J15A\", 32, 4 },\n\t{ 0x05, \"SAMC21G18A\", 256, 32 },\n\t{ 0x06, \"SAMC21G17A\", 128, 16 },\n\t{ 0x07, \"SAMC21G16A\", 64, 8 },\n\t{ 0x08, \"SAMC21G15A\", 32, 4 },\n\t{ 0x0A, \"SAMC21E18A\", 256, 32 },\n\t{ 0x0B, \"SAMC21E17A\", 128, 16 },\n\t{ 0x0C, \"SAMC21E16A\", 64, 8 },\n\t{ 0x0D, \"SAMC21E15A\", 32, 4 },\n\t{ 0x20, \"SAMC21N18A\", 256, 32 },\n\t{ 0x21, \"SAMC21N17A\", 128, 16 },\n};\n\n/* Each family of parts contains a parts table in the DEVSEL field of DID.  The\n * processor ID, family ID, and series ID are used to determine which exact\n * family this is and then we can use the corresponding table. */\nstruct samd_family {\n\tuint8_t processor;\n\tuint8_t family;\n\tuint8_t series;\n\tconst struct samd_part *parts;\n\tsize_t num_parts;\n\tuint64_t nvm_userrow_res_mask; /* protect bits which are reserved, 0 -> protect */\n};\n\n/* Known SAMD families */\nstatic const struct samd_family samd_families[] = {\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_20,\n\t\tsamd20_parts, ARRAY_SIZE(samd20_parts),\n\t\t0xFFFF01FFFE01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_21,\n\t\tsamd21_parts, ARRAY_SIZE(samd21_parts),\n\t\t0xFFFF01FFFE01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_09,\n\t\tsamd09_parts, ARRAY_SIZE(samd09_parts),\n\t\t0xFFFF01FFFE01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_10,\n\t\tsamd10_parts, ARRAY_SIZE(samd10_parts),\n\t\t0xFFFF01FFFE01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_D, SAMD_SERIES_11,\n\t\tsamd11_parts, ARRAY_SIZE(samd11_parts),\n\t\t0xFFFF01FFFE01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_21,\n\t\tsaml21_parts, ARRAY_SIZE(saml21_parts),\n\t\t0xFFFF03FFFC01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_L, SAMD_SERIES_22,\n\t\tsaml22_parts, ARRAY_SIZE(saml22_parts),\n\t\t0xFFFF03FFFC01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_20,\n\t\tsamc20_parts, ARRAY_SIZE(samc20_parts),\n\t\t0xFFFF03FFFC01FF77ULL },\n\t{ SAMD_PROCESSOR_M0, SAMD_FAMILY_C, SAMD_SERIES_21,\n\t\tsamc21_parts, ARRAY_SIZE(samc21_parts),\n\t\t0xFFFF03FFFC01FF77ULL },\n};\n\nstruct samd_info {\n\tuint32_t page_size;\n\tint num_pages;\n\tint sector_size;\n\tint prot_block_size;\n\n\tbool probed;\n\tstruct target *target;\n};\n\n\n/**\n * Gives the family structure to specific device id.\n * @param id The id of the device.\n * @return On failure NULL, otherwise a pointer to the structure.\n */\nstatic const struct samd_family *samd_find_family(uint32_t id)\n{\n\tuint8_t processor = SAMD_GET_PROCESSOR(id);\n\tuint8_t family = SAMD_GET_FAMILY(id);\n\tuint8_t series = SAMD_GET_SERIES(id);\n\n\tfor (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {\n\t\tif (samd_families[i].processor == processor &&\n\t\t\tsamd_families[i].series == series &&\n\t\t\tsamd_families[i].family == family)\n\t\t\treturn &samd_families[i];\n\t}\n\n\treturn NULL;\n}\n\n/**\n * Gives the part structure to specific device id.\n * @param id The id of the device.\n * @return On failure NULL, otherwise a pointer to the structure.\n */\nstatic const struct samd_part *samd_find_part(uint32_t id)\n{\n\tuint8_t devsel = SAMD_GET_DEVSEL(id);\n\tconst struct samd_family *family = samd_find_family(id);\n\tif (!family)\n\t\treturn NULL;\n\n\tfor (unsigned i = 0; i < family->num_parts; i++) {\n\t\tif (family->parts[i].id == devsel)\n\t\t\treturn &family->parts[i];\n\t}\n\n\treturn NULL;\n}\n\nstatic int samd_protect_check(struct flash_bank *bank)\n{\n\tint res;\n\tuint16_t lock;\n\n\tres = target_read_u16(bank->target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_LOCK, &lock);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Lock bits are active-low */\n\tfor (unsigned int prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)\n\t\tbank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));\n\n\treturn ERROR_OK;\n}\n\nstatic int samd_get_flash_page_info(struct target *target,\n\t\tuint32_t *sizep, int *nump)\n{\n\tint res;\n\tuint32_t param;\n\n\tres = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_PARAM, &param);\n\tif (res == ERROR_OK) {\n\t\t/* The PSZ field (bits 18:16) indicate the page size bytes as 2^(3+n)\n\t\t * so 0 is 8KB and 7 is 1024KB. */\n\t\tif (sizep)\n\t\t\t*sizep = (8 << ((param >> 16) & 0x7));\n\t\t/* The NVMP field (bits 15:0) indicates the total number of pages */\n\t\tif (nump)\n\t\t\t*nump = param & 0xFFFF;\n\t} else {\n\t\tLOG_ERROR(\"Couldn't read NVM Parameters register\");\n\t}\n\n\treturn res;\n}\n\nstatic int samd_probe(struct flash_bank *bank)\n{\n\tuint32_t id;\n\tint res;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\tconst struct samd_part *part;\n\n\tif (chip->probed)\n\t\treturn ERROR_OK;\n\n\tres = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read Device ID register\");\n\t\treturn res;\n\t}\n\n\tpart = samd_find_part(id);\n\tif (!part) {\n\t\tLOG_ERROR(\"Couldn't find part corresponding to DID %08\" PRIx32, id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->size = part->flash_kb * 1024;\n\n\tres = samd_get_flash_page_info(bank->target, &chip->page_size,\n\t\t\t&chip->num_pages);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't determine Flash page size\");\n\t\treturn res;\n\t}\n\n\t/* Sanity check: the total flash size in the DSU should match the page size\n\t * multiplied by the number of pages. */\n\tif (bank->size != chip->num_pages * chip->page_size) {\n\t\tLOG_WARNING(\"SAMD: bank size doesn't match NVM parameters. \"\n\t\t\t\t\"Identified %\" PRIu32 \"KB Flash but NVMCTRL reports %u %\" PRIu32 \"B pages\",\n\t\t\t\tpart->flash_kb, chip->num_pages, chip->page_size);\n\t}\n\n\t/* Erase granularity = 1 row = 4 pages */\n\tchip->sector_size = chip->page_size * 4;\n\n\t/* Allocate the sector table */\n\tbank->num_sectors = chip->num_pages / 4;\n\tbank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\t/* 16 protection blocks per device */\n\tchip->prot_block_size = bank->size / SAMD_NUM_PROT_BLOCKS;\n\n\t/* Allocate the table of protection blocks */\n\tbank->num_prot_blocks = SAMD_NUM_PROT_BLOCKS;\n\tbank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);\n\tif (!bank->prot_blocks)\n\t\treturn ERROR_FAIL;\n\n\tsamd_protect_check(bank);\n\n\t/* Done */\n\tchip->probed = true;\n\n\tLOG_INFO(\"SAMD MCU: %s (%\" PRIu32 \"KB Flash, %\" PRIu32 \"KB RAM)\", part->name,\n\t\t\tpart->flash_kb, part->ram_kb);\n\n\treturn ERROR_OK;\n}\n\nstatic int samd_check_error(struct target *target)\n{\n\tint ret, ret2;\n\tuint8_t intflag;\n\tuint16_t status;\n\tint timeout_ms = 1000;\n\tint64_t ts_start = timeval_ms();\n\n\tdo {\n\t\tret = target_read_u8(target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_INTFLAG, &intflag);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't read NVM intflag\");\n\t\t\treturn ret;\n\t\t}\n\t\tif (intflag & SAMD_NVM_INTFLAG_READY)\n\t\t\tbreak;\n\t\tkeep_alive();\n\t} while (timeval_ms() - ts_start < timeout_ms);\n\n\tif (!(intflag & SAMD_NVM_INTFLAG_READY)) {\n\t\tLOG_ERROR(\"SAMD: NVM programming timed out\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tret = target_read_u16(target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, &status);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't read NVM status\");\n\t\treturn ret;\n\t}\n\n\tif ((status & 0x001C) == 0)\n\t\treturn ERROR_OK;\n\n\tif (status & (1 << 4)) { /* NVME */\n\t\tLOG_ERROR(\"SAMD: NVM Error\");\n\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (status & (1 << 3)) { /* LOCKE */\n\t\tLOG_ERROR(\"SAMD: NVM lock error\");\n\t\tret = ERROR_FLASH_PROTECTED;\n\t}\n\n\tif (status & (1 << 2)) { /* PROGE */\n\t\tLOG_ERROR(\"SAMD: NVM programming error\");\n\t\tret = ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\t/* Clear the error conditions by writing a one to them */\n\tret2 = target_write_u16(target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_STATUS, status);\n\tif (ret2 != ERROR_OK)\n\t\tLOG_ERROR(\"Can't clear NVM error conditions\");\n\n\treturn ret;\n}\n\nstatic int samd_issue_nvmctrl_command(struct target *target, uint16_t cmd)\n{\n\tint res;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Issue the NVM command */\n\t/* 32-bit write is used to ensure atomic operation on ST-Link */\n\tres = target_write_u32(target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_CTRLA, SAMD_NVM_CMD(cmd));\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Check to see if the NVM command resulted in an error condition. */\n\treturn samd_check_error(target);\n}\n\n/**\n * Erases a flash-row at the given address.\n * @param target Pointer to the target structure.\n * @param address The address of the row.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int samd_erase_row(struct target *target, uint32_t address)\n{\n\tint res;\n\n\t/* Set an address contained in the row to be erased */\n\tres = target_write_u32(target,\n\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_ADDR, address >> 1);\n\n\t/* Issue the Erase Row command to erase that row. */\n\tif (res == ERROR_OK)\n\t\tres = samd_issue_nvmctrl_command(target,\n\t\t\t\taddress == SAMD_USER_ROW ? SAMD_NVM_CMD_EAR : SAMD_NVM_CMD_ER);\n\n\tif (res != ERROR_OK)  {\n\t\tLOG_ERROR(\"Failed to erase row containing %08\" PRIx32, address);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Returns the bitmask of reserved bits in register.\n * @param target Pointer to the target structure.\n * @param mask Bitmask, 0 -> value stays untouched.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int samd_get_reservedmask(struct target *target, uint64_t *mask)\n{\n\tint res;\n\t/* Get the devicetype */\n\tuint32_t id;\n\tres = target_read_u32(target, SAMD_DSU + SAMD_DSU_DID, &id);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read Device ID register\");\n\t\treturn res;\n\t}\n\tconst struct samd_family *family;\n\tfamily = samd_find_family(id);\n\tif (!family) {\n\t\tLOG_ERROR(\"Couldn't determine device family\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*mask = family->nvm_userrow_res_mask;\n\treturn ERROR_OK;\n}\n\nstatic int read_userrow(struct target *target, uint64_t *userrow)\n{\n\tint res;\n\tuint8_t buffer[8];\n\n\tres = target_read_memory(target, SAMD_USER_ROW, 4, 2, buffer);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t*userrow = target_buffer_get_u64(target, buffer);\n\treturn ERROR_OK;\n}\n\n/**\n * Modify the contents of the User Row in Flash. The User Row itself\n * has a size of one page and contains a combination of \"fuses\" and\n * calibration data. Bits which have a value of zero in the mask will\n * not be changed. Up to now devices only use the first 64 bits.\n * @param target Pointer to the target structure.\n * @param value_input The value to write.\n * @param value_mask Bitmask, 0 -> value stays untouched.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int samd_modify_user_row_masked(struct target *target,\n\t\tuint64_t value_input, uint64_t value_mask)\n{\n\tint res;\n\tuint32_t nvm_ctrlb;\n\tbool manual_wp = true;\n\n\t/* Retrieve the MCU's page size, in bytes. This is also the size of the\n\t * entire User Row. */\n\tuint32_t page_size;\n\tres = samd_get_flash_page_info(target, &page_size, NULL);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't determine Flash page size\");\n\t\treturn res;\n\t}\n\n\t/* Make sure the size is sane. */\n\tassert(page_size <= SAMD_PAGE_SIZE_MAX &&\n\t\tpage_size >= sizeof(value_input));\n\n\tuint8_t buf[SAMD_PAGE_SIZE_MAX];\n\t/* Read the user row (comprising one page) by words. */\n\tres = target_read_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tuint64_t value_device;\n\tres = read_userrow(target, &value_device);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tuint64_t value_new = (value_input & value_mask) | (value_device & ~value_mask);\n\n\t/* We will need to erase before writing if the new value needs a '1' in any\n\t * position for which the current value had a '0'.  Otherwise we can avoid\n\t * erasing. */\n\tif ((~value_device) & value_new) {\n\t\tres = samd_erase_row(target, SAMD_USER_ROW);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't erase user row\");\n\t\t\treturn res;\n\t\t}\n\t}\n\n\t/* Modify */\n\ttarget_buffer_set_u64(target, buf, value_new);\n\n\t/* Write the page buffer back out to the target. */\n\tres = target_write_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Check if we need to do manual page write commands */\n\tres = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);\n\tif (res == ERROR_OK)\n\t\tmanual_wp = (nvm_ctrlb & SAMD_NVM_CTRLB_MANW) != 0;\n\telse {\n\t\tLOG_ERROR(\"Read of NVM register CTRKB failed.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (manual_wp) {\n\t\t/* Trigger flash write */\n\t\tres = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_WAP);\n\t} else {\n\t\tres = samd_check_error(target);\n\t}\n\n\treturn res;\n}\n\n/**\n * Modifies the user row register to the given value.\n * @param target Pointer to the target structure.\n * @param value The value to write.\n * @param startb The bit-offset by which the given value is shifted.\n * @param endb The bit-offset of the last bit in value to write.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int samd_modify_user_row(struct target *target, uint64_t value,\n\t\tuint8_t startb, uint8_t endb)\n{\n\tuint64_t mask = 0;\n\tint i;\n\tfor (i = startb ; i <= endb ; i++)\n\t\tmask |= ((uint64_t)1) << i;\n\n\treturn samd_modify_user_row_masked(target, value << startb, mask);\n}\n\nstatic int samd_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tint res = ERROR_OK;\n\n\t/* We can issue lock/unlock region commands with the target running but\n\t * the settings won't persist unless we're able to modify the LOCK regions\n\t * and that requires the target to be halted. */\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (unsigned int prot_block = first; prot_block <= last; prot_block++) {\n\t\tif (set != bank->prot_blocks[prot_block].is_protected) {\n\t\t\t/* Load an address that is within this protection block (we use offset 0) */\n\t\t\tres = target_write_u32(bank->target,\n\t\t\t\t\t\t\tSAMD_NVMCTRL + SAMD_NVMCTRL_ADDR,\n\t\t\t\t\t\t\tbank->prot_blocks[prot_block].offset >> 1);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tgoto exit;\n\n\t\t\t/* Tell the controller to lock that block */\n\t\t\tres = samd_issue_nvmctrl_command(bank->target,\n\t\t\t\t\tset ? SAMD_NVM_CMD_LR : SAMD_NVM_CMD_UR);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tgoto exit;\n\t\t}\n\t}\n\n\t/* We've now applied our changes, however they will be undone by the next\n\t * reset unless we also apply them to the LOCK bits in the User Page.  The\n\t * LOCK bits start at bit 48, corresponding to Sector 0 and end with bit 63,\n\t * corresponding to Sector 15.  A '1' means unlocked and a '0' means\n\t * locked.  See Table 9-3 in the SAMD20 datasheet for more details. */\n\n\tres = samd_modify_user_row(bank->target,\n\t\t\tset ? (uint64_t)0 : (uint64_t)UINT64_MAX,\n\t\t\t48 + first, 48 + last);\n\tif (res != ERROR_OK)\n\t\tLOG_WARNING(\"SAMD: protect settings were not made persistent!\");\n\n\tres = ERROR_OK;\n\nexit:\n\tsamd_protect_check(bank);\n\n\treturn res;\n}\n\nstatic int samd_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (samd_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* For each sector to be erased */\n\tfor (unsigned int s = first; s <= last; s++) {\n\t\tres = samd_erase_row(bank->target, bank->sectors[s].offset);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"SAMD: failed to erase sector %d at 0x%08\" PRIx32, s, bank->sectors[s].offset);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int samd_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tint res;\n\tuint32_t nvm_ctrlb;\n\tuint32_t address;\n\tuint32_t pg_offset;\n\tuint32_t nb;\n\tuint32_t nw;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\tuint8_t *pb = NULL;\n\tbool manual_wp;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed) {\n\t\tif (samd_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Check if we need to do manual page write commands */\n\tres = target_read_u32(bank->target, SAMD_NVMCTRL + SAMD_NVMCTRL_CTRLB, &nvm_ctrlb);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (nvm_ctrlb & SAMD_NVM_CTRLB_MANW)\n\t\tmanual_wp = true;\n\telse\n\t\tmanual_wp = false;\n\n\tres = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_PBC);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: %d\", __func__, __LINE__);\n\t\treturn res;\n\t}\n\n\twhile (count) {\n\t\tnb = chip->page_size - offset % chip->page_size;\n\t\tif (count < nb)\n\t\t\tnb = count;\n\n\t\taddress = bank->base + offset;\n\t\tpg_offset = offset % chip->page_size;\n\n\t\tif (offset % 4 || (offset + nb) % 4) {\n\t\t\t/* Either start or end of write is not word aligned */\n\t\t\tif (!pb) {\n\t\t\t\tpb = malloc(chip->page_size);\n\t\t\t\tif (!pb)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* Set temporary page buffer to 0xff and overwrite the relevant part */\n\t\t\tmemset(pb, 0xff, chip->page_size);\n\t\t\tmemcpy(pb + pg_offset, buffer, nb);\n\n\t\t\t/* Align start address to a word boundary */\n\t\t\taddress -= offset % 4;\n\t\t\tpg_offset -= offset % 4;\n\t\t\tassert(pg_offset % 4 == 0);\n\n\t\t\t/* Extend length to whole words */\n\t\t\tnw = (nb + offset % 4 + 3) / 4;\n\t\t\tassert(pg_offset + 4 * nw <= chip->page_size);\n\n\t\t\t/* Now we have original data extended by 0xff bytes\n\t\t\t * to the nearest word boundary on both start and end */\n\t\t\tres = target_write_memory(bank->target, address, 4, nw, pb + pg_offset);\n\t\t} else {\n\t\t\tassert(nb % 4 == 0);\n\t\t\tnw = nb / 4;\n\t\t\tassert(pg_offset + 4 * nw <= chip->page_size);\n\n\t\t\t/* Word aligned data, use direct write from buffer */\n\t\t\tres = target_write_memory(bank->target, address, 4, nw, buffer);\n\t\t}\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: %d\", __func__, __LINE__);\n\t\t\tgoto free_pb;\n\t\t}\n\n\t\t/* Devices with errata 13134 have automatic page write enabled by default\n\t\t * For other devices issue a write page CMD to the NVM\n\t\t * If the page has not been written up to the last word\n\t\t * then issue CMD_WP always */\n\t\tif (manual_wp || pg_offset + 4 * nw < chip->page_size) {\n\t\t\tres = samd_issue_nvmctrl_command(bank->target, SAMD_NVM_CMD_WP);\n\t\t} else {\n\t\t\t/* Access through AHB is stalled while flash is being programmed */\n\t\t\tusleep(200);\n\n\t\t\tres = samd_check_error(bank->target);\n\t\t}\n\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: write failed at address 0x%08\" PRIx32, __func__, address);\n\t\t\tgoto free_pb;\n\t\t}\n\n\t\t/* We're done with the page contents */\n\t\tcount -= nb;\n\t\toffset += nb;\n\t\tbuffer += nb;\n\t}\n\nfree_pb:\n\tfree(pb);\n\treturn res;\n}\n\nFLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)\n{\n\tif (bank->base != SAMD_FLASH) {\n\t\tLOG_ERROR(\"Address \" TARGET_ADDR_FMT\n\t\t\t\t\" invalid bank address (try 0x%08\" PRIx32\n\t\t\t\t\"[at91samd series] )\",\n\t\t\t\tbank->base, SAMD_FLASH);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct samd_info *chip;\n\tchip = calloc(1, sizeof(*chip));\n\tif (!chip) {\n\t\tLOG_ERROR(\"No memory for flash bank chip info\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchip->target = bank->target;\n\tchip->probed = false;\n\n\tbank->driver_priv = chip;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(samd_handle_chip_erase_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint res = ERROR_FAIL;\n\n\tif (target) {\n\t\t/* Enable access to the DSU by disabling the write protect bit */\n\t\ttarget_write_u32(target, SAMD_PAC1, (1<<1));\n\t\t/* intentionally without error checking - not accessible on secured chip */\n\n\t\t/* Tell the DSU to perform a full chip erase.  It takes about 240ms to\n\t\t * perform the erase. */\n\t\tres = target_write_u8(target, SAMD_DSU + SAMD_DSU_CTRL_EXT, (1<<4));\n\t\tif (res == ERROR_OK)\n\t\t\tcommand_print(CMD, \"chip erase started\");\n\t\telse\n\t\t\tcommand_print(CMD, \"write to DSU CTRL failed\");\n\t}\n\n\treturn res;\n}\n\nCOMMAND_HANDLER(samd_handle_set_security_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC < 1 || (CMD_ARGC >= 1 && (strcmp(CMD_ARGV[0], \"enable\")))) {\n\t\tcommand_print(CMD, \"supply the \\\"enable\\\" argument to proceed.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (target) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_ERROR(\"Target not halted\");\n\t\t\treturn ERROR_TARGET_NOT_HALTED;\n\t\t}\n\n\t\tres = samd_issue_nvmctrl_command(target, SAMD_NVM_CMD_SSB);\n\n\t\t/* Check (and clear) error conditions */\n\t\tif (res == ERROR_OK)\n\t\t\tcommand_print(CMD, \"chip secured on next power-cycle\");\n\t\telse\n\t\t\tcommand_print(CMD, \"failed to secure chip\");\n\t}\n\n\treturn res;\n}\n\nCOMMAND_HANDLER(samd_handle_eeprom_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (target) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_ERROR(\"Target not halted\");\n\t\t\treturn ERROR_TARGET_NOT_HALTED;\n\t\t}\n\n\t\tif (CMD_ARGC >= 1) {\n\t\t\tint val = atoi(CMD_ARGV[0]);\n\t\t\tuint32_t code;\n\n\t\t\tif (val == 0)\n\t\t\t\tcode = 7;\n\t\t\telse {\n\t\t\t\t/* Try to match size in bytes with corresponding size code */\n\t\t\t\tfor (code = 0; code <= 6; code++) {\n\t\t\t\t\tif (val == (2 << (13 - code)))\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (code > 6) {\n\t\t\t\t\tcommand_print(CMD, \"Invalid EEPROM size.  Please see \"\n\t\t\t\t\t\t\t\"datasheet for a list valid sizes.\");\n\t\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tres = samd_modify_user_row(target, code, 4, 6);\n\t\t} else {\n\t\t\tuint16_t val;\n\t\t\tres = target_read_u16(target, SAMD_USER_ROW, &val);\n\t\t\tif (res == ERROR_OK) {\n\t\t\t\tuint32_t size = ((val >> 4) & 0x7); /* grab size code */\n\n\t\t\t\tif (size == 0x7)\n\t\t\t\t\tcommand_print(CMD, \"EEPROM is disabled\");\n\t\t\t\telse {\n\t\t\t\t\t/* Otherwise, 6 is 256B, 0 is 16KB */\n\t\t\t\t\tcommand_print(CMD, \"EEPROM size is %u bytes\",\n\t\t\t\t\t\t\t(2 << (13 - size)));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn res;\n}\n\nCOMMAND_HANDLER(samd_handle_nvmuserrow_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (target) {\n\t\tif (CMD_ARGC > 2) {\n\t\t\tcommand_print(CMD, \"Too much Arguments given.\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (CMD_ARGC > 0) {\n\t\t\tif (target->state != TARGET_HALTED) {\n\t\t\t\tLOG_ERROR(\"Target not halted.\");\n\t\t\t\treturn ERROR_TARGET_NOT_HALTED;\n\t\t\t}\n\n\t\t\tuint64_t mask;\n\t\t\tres = samd_get_reservedmask(target, &mask);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Couldn't determine the mask for reserved bits.\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tmask &= NVMUSERROW_LOCKBIT_MASK;\n\n\t\t\tuint64_t value;\n\t\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], value);\n\n\t\t\tif (CMD_ARGC == 2) {\n\t\t\t\tuint64_t mask_temp;\n\t\t\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], mask_temp);\n\n\t\t\t\tmask &= mask_temp;\n\t\t\t}\n\t\t\tres = samd_modify_user_row_masked(target, value, mask);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\n\t\t/* read register */\n\t\tuint64_t value;\n\t\tres = read_userrow(target, &value);\n\t\tif (res == ERROR_OK)\n\t\t\tcommand_print(CMD, \"NVMUSERROW: 0x%016\"PRIX64, value);\n\t\telse\n\t\t\tLOG_ERROR(\"NVMUSERROW could not be read.\");\n\t}\n\treturn res;\n}\n\nCOMMAND_HANDLER(samd_handle_bootloader_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (target) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_ERROR(\"Target not halted\");\n\t\t\treturn ERROR_TARGET_NOT_HALTED;\n\t\t}\n\n\t\t/* Retrieve the MCU's page size, in bytes. */\n\t\tuint32_t page_size;\n\t\tres = samd_get_flash_page_info(target, &page_size, NULL);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't determine Flash page size\");\n\t\t\treturn res;\n\t\t}\n\n\t\tif (CMD_ARGC >= 1) {\n\t\t\tint val = atoi(CMD_ARGV[0]);\n\t\t\tuint32_t code;\n\n\t\t\tif (val == 0)\n\t\t\t\tcode = 7;\n\t\t\telse {\n\t\t\t\t/* Try to match size in bytes with corresponding size code */\n\t\t\t\tfor (code = 0; code <= 6; code++) {\n\t\t\t\t\tif ((unsigned int)val == (2UL << (8UL - code)) * page_size)\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (code > 6) {\n\t\t\t\t\tcommand_print(CMD, \"Invalid bootloader size.  Please \"\n\t\t\t\t\t\t\t\"see datasheet for a list valid sizes.\");\n\t\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tres = samd_modify_user_row(target, code, 0, 2);\n\t\t} else {\n\t\t\tuint16_t val;\n\t\t\tres = target_read_u16(target, SAMD_USER_ROW, &val);\n\t\t\tif (res == ERROR_OK) {\n\t\t\t\tuint32_t size = (val & 0x7); /* grab size code */\n\t\t\t\tuint32_t nb;\n\n\t\t\t\tif (size == 0x7)\n\t\t\t\t\tnb = 0;\n\t\t\t\telse\n\t\t\t\t\tnb = (2 << (8 - size)) * page_size;\n\n\t\t\t\t/* There are 4 pages per row */\n\t\t\t\tcommand_print(CMD, \"Bootloader size is %\" PRIu32 \" bytes (%\" PRIu32 \" rows)\",\n\t\t\t\t\t   nb, (uint32_t)(nb / (page_size * 4)));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn res;\n}\n\n\n\nCOMMAND_HANDLER(samd_handle_reset_deassert)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = ERROR_OK;\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t/* If the target has been unresponsive before, try to re-establish\n\t * communication now - CPU is held in reset by DSU, DAP is working */\n\tif (!target_was_examined(target))\n\t\ttarget_examine_one(target);\n\ttarget_poll(target);\n\n\t/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()\n\t * so we just release reset held by DSU\n\t *\n\t * n_RESET (srst) clears the DP, so reenable debug and set vector catch here\n\t *\n\t * After vectreset DSU release is not needed however makes no harm\n\t */\n\tif (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {\n\t\tretval = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, DCB_DEMCR,\n\t\t\t\tTRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);\n\t\t/* do not return on error here, releasing DSU reset is more important */\n\t}\n\n\t/* clear CPU Reset Phase Extension bit */\n\tint retval2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1));\n\tif (retval2 != ERROR_OK)\n\t\treturn retval2;\n\n\treturn retval;\n}\n\nstatic const struct command_registration at91samd_exec_command_handlers[] = {\n\t{\n\t\t.name = \"dsu_reset_deassert\",\n\t\t.handler = samd_handle_reset_deassert,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Deassert internal reset held by DSU.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"chip-erase\",\n\t\t.handler = samd_handle_chip_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase the entire Flash by using the Chip-\"\n\t\t\t\"Erase feature in the Device Service Unit (DSU).\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"set-security\",\n\t\t.handler = samd_handle_set_security_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Secure the chip's Flash by setting the Security Bit. \"\n\t\t\t\"This makes it impossible to read the Flash contents. \"\n\t\t\t\"The only way to undo this is to issue the chip-erase \"\n\t\t\t\"command.\",\n\t\t.usage = \"'enable'\",\n\t},\n\t{\n\t\t.name = \"eeprom\",\n\t\t.usage = \"[size_in_bytes]\",\n\t\t.handler = samd_handle_eeprom_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show or set the EEPROM size setting, stored in the User Row. \"\n\t\t\t\"Please see Table 20-3 of the SAMD20 datasheet for allowed values. \"\n\t\t\t\"Changes are stored immediately but take affect after the MCU is \"\n\t\t\t\"reset.\",\n\t},\n\t{\n\t\t.name = \"bootloader\",\n\t\t.usage = \"[size_in_bytes]\",\n\t\t.handler = samd_handle_bootloader_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show or set the bootloader size, stored in the User Row. \"\n\t\t\t\"Please see Table 20-2 of the SAMD20 datasheet for allowed values. \"\n\t\t\t\"Changes are stored immediately but take affect after the MCU is \"\n\t\t\t\"reset.\",\n\t},\n\t{\n\t\t.name = \"nvmuserrow\",\n\t\t.usage = \"[value] [mask]\",\n\t\t.handler = samd_handle_nvmuserrow_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show or set the nvmuserrow register. It is 64 bit wide \"\n\t\t\t\"and located at address 0x804000. Use the optional mask argument \"\n\t\t\t\"to prevent changes at positions where the bitvalue is zero. \"\n\t\t\t\"For security reasons the lock- and reserved-bits are masked out \"\n\t\t\t\"in background and therefore cannot be changed.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration at91samd_command_handlers[] = {\n\t{\n\t\t.name = \"at91samd\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"at91samd flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = at91samd_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver at91samd_flash = {\n\t.name = \"at91samd\",\n\t.commands = at91samd_command_handlers,\n\t.flash_bank_command = samd_flash_bank_command,\n\t.erase = samd_erase,\n\t.protect = samd_protect,\n\t.write = samd_write,\n\t.read = default_flash_read,\n\t.probe = samd_probe,\n\t.auto_probe = samd_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = samd_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/ath79.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Tobias Diedrich                                 *\n *   <ranma+openwrt@tdiedrich.de>                                          *\n *                                                                         *\n *   based on the stmsmi code written by Antonio Borneo                    *\n *   <borneo.antonio@gmail.com>                                            *\n *                                                                         *\n ***************************************************************************/\n/*\n * Driver for the Atheros AR7xxx/AR9xxx SPI flash interface.\n *\n * Since no SPI mode register is present, presumably only\n * SPI \"mode 3\" (CPOL=1 and CPHA=1) is supported.\n *\n * The SPI interface supports up to 3 chip selects, however the SPI flash\n * used for booting the system must be connected to CS0.\n *\n * On boot, the first 4MiB of flash space are memory-mapped into the\n * area bf000000 - bfffffff (4 copies), so the MIPS bootstrap\n * vector bfc00000 is mapped to the beginning of the flash.\n *\n * By writing a 1 to the REMAP_DISABLE bit in the SPI_CONTROL register,\n * the full area of 16MiB is mapped.\n *\n * By writing a 0 to the SPI_FUNCTION_SELECT register (write-only dword\n * register @bf000000), memory mapping is disabled and the SPI registers\n * are exposed to the CPU instead:\n * bf000000 SPI_FUNCTION_SELECT\n * bf000004 SPI_CONTROL\n * bf000008 SPI_IO_CONTROL\n * bf00000c SPI_READ_DATA\n *\n * When not memory-mapped, the SPI interface is essentially bitbanged\n * using SPI_CONTROL and SPI_IO_CONTROL with the only hardware-assistance\n * being the 32bit read-only shift-register SPI_READ_DATA.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <jtag/jtag.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n#include <target/mips32.h>\n#include <target/mips32_pracc.h>\n#include <target/target.h>\n\n#define BITS_PER_BYTE 8\n\n#define ATH79_REG_FS     0\n#define ATH79_REG_CLOCK  4\n#define ATH79_REG_WRITE  8\n#define ATH79_REG_DATA  12\n\n#define ATH79_SPI_CS_ALLHI 0x70000\n#define ATH79_SPI_CS0_HI   0x10000\n#define ATH79_SPI_CS1_HI   0x20000\n#define ATH79_SPI_CS2_HI   0x40000\n#define ATH79_SPI_CE_HI    0x00100\n#define ATH79_SPI_DO_HI    0x00001\n\n#define ATH79_XFER_FINAL   0x00000001\n#define ATH79_XFER_PARTIAL 0x00000000\n\n/* Timeout in ms */\n#define ATH79_MAX_TIMEOUT  (3000)\n\nstruct ath79_spi_ctx {\n\tuint8_t *page_buf;\n\tint pre_deselect;\n\tint post_deselect;\n};\n\nstruct ath79_flash_bank {\n\tbool probed;\n\tint chipselect;\n\tuint32_t io_base;\n\tconst struct flash_device *dev;\n\tstruct ath79_spi_ctx spi;\n};\n\nstruct ath79_target {\n\tchar *name;\n\tuint32_t tap_idcode;\n\tuint32_t io_base;\n};\n\nstatic const struct ath79_target target_devices[] = {\n\t/* name,   tap_idcode, io_base */\n\t{ \"ATH79\", 0x00000001, 0xbf000000 },\n\t{ NULL,    0,          0 }\n};\n\nstatic const uint32_t ath79_chipselects[] = {\n\t(~ATH79_SPI_CS0_HI & ATH79_SPI_CS_ALLHI),\n\t(~ATH79_SPI_CS1_HI & ATH79_SPI_CS_ALLHI),\n\t(~ATH79_SPI_CS2_HI & ATH79_SPI_CS_ALLHI),\n};\n\nstatic void ath79_pracc_addn(struct pracc_queue_info *ctx,\n\t\t\t     const uint32_t *instr,\n\t\t\t     int n)\n{\n\tfor (int i = 0; i < n; i++)\n\t\tpracc_add(ctx, 0, instr[i]);\n}\n\nstatic int ath79_spi_bitbang_codegen(struct ath79_flash_bank *ath79_info,\n\t\t\t\t     struct pracc_queue_info *ctx,\n\t\t\t\t     uint8_t *data, int len,\n\t\t\t\t     int partial_xfer)\n{\n\tuint32_t cs_high = ATH79_SPI_CS_ALLHI;\n\tuint32_t cs_low = ath79_chipselects[ath79_info->chipselect];\n\tuint32_t clock_high = cs_low | ATH79_SPI_CE_HI;\n\tuint32_t clock_low = cs_low;\n\tuint32_t pracc_out = 0;\n\tuint32_t io_base = ath79_info->io_base;\n\n\tconst uint32_t preamble1[] = {\n\t\t/* $15 = MIPS32_PRACC_BASE_ADDR */\n\t\tMIPS32_LUI(0, 15, PRACC_UPPER_BASE_ADDR),\n\t\t/* $1 = io_base */\n\t\tMIPS32_LUI(0, 1, UPPER16(io_base)),\n\t};\n\tath79_pracc_addn(ctx, preamble1, ARRAY_SIZE(preamble1));\n\tif (ath79_info->spi.pre_deselect) {\n\t\t/* Clear deselect flag so we don't deselect again if\n\t\t * this is a partial xfer.\n\t\t */\n\t\tath79_info->spi.pre_deselect = 0;\n\t\tconst uint32_t pre_deselect[] = {\n\t\t\t/* [$1 + FS] = 1  (enable flash io register access) */\n\t\t\tMIPS32_LUI(0, 2, UPPER16(1)),\n\t\t\tMIPS32_ORI(0, 2, 2, LOWER16(1)),\n\t\t\tMIPS32_SW(0, 2, ATH79_REG_FS, 1),\n\t\t\t/* deselect flash just in case */\n\t\t\t/* $2 = SPI_CS_DIS */\n\t\t\tMIPS32_LUI(0, 2, UPPER16(cs_high)),\n\t\t\tMIPS32_ORI(0, 2, 2, LOWER16(cs_high)),\n\t\t\t/* [$1 + WRITE] = $2 */\n\t\t\tMIPS32_SW(0, 2, ATH79_REG_WRITE, 1),\n\t\t};\n\t\tath79_pracc_addn(ctx, pre_deselect, ARRAY_SIZE(pre_deselect));\n\t}\n\tconst uint32_t preamble2[] = {\n\t\t/* t0 = CLOCK_LOW + 0-bit */\n\t\tMIPS32_LUI(0, 8, UPPER16((clock_low + 0))),\n\t\tMIPS32_ORI(0, 8, 8, LOWER16((clock_low + 0))),\n\t\t/* t1 = CLOCK_LOW + 1-bit */\n\t\tMIPS32_LUI(0, 9, UPPER16((clock_low + 1))),\n\t\tMIPS32_ORI(0, 9, 9, LOWER16((clock_low + 1))),\n\t\t/* t2 = CLOCK_HIGH + 0-bit */\n\t\tMIPS32_LUI(0, 10, UPPER16((clock_high + 0))),\n\t\tMIPS32_ORI(0, 10, 10, LOWER16((clock_high + 0))),\n\t\t/* t3 = CLOCK_HIGH + 1-bit */\n\t\tMIPS32_LUI(0, 11, UPPER16((clock_high + 1))),\n\t\tMIPS32_ORI(0, 11, 11, LOWER16((clock_high + 1))),\n\t};\n\tath79_pracc_addn(ctx, preamble2, ARRAY_SIZE(preamble2));\n\n\tfor (int i = 0; i < len; i++) {\n\t\tuint8_t x = data[i];\n\n\t\t/* Generate bitbang code for one byte, highest bit first .*/\n\t\tfor (int j = BITS_PER_BYTE - 1; j >= 0; j--) {\n\t\t\tint bit = ((x >> j) & 1);\n\n\t\t\tif (bit) {\n\t\t\t\t/* [$1 + WRITE] = t1 */\n\t\t\t\tpracc_add(ctx, 0,\n\t\t\t\t\t  MIPS32_SW(0, 9, ATH79_REG_WRITE, 1));\n\t\t\t\t/* [$1 + WRITE] = t3 */\n\t\t\t\tpracc_add(ctx, 0,\n\t\t\t\t\t  MIPS32_SW(0, 11, ATH79_REG_WRITE, 1));\n\t\t\t} else {\n\t\t\t\t/* [$1 + WRITE] = t0 */\n\t\t\t\tpracc_add(ctx, 0,\n\t\t\t\t\t  MIPS32_SW(0, 8, ATH79_REG_WRITE, 1));\n\t\t\t\t/* [$1 + WRITE] = t2 */\n\t\t\t\tpracc_add(ctx, 0,\n\t\t\t\t\t  MIPS32_SW(0, 10, ATH79_REG_WRITE, 1));\n\t\t\t}\n\t\t}\n\t\tif (i % 4 == 3) {\n\t\t\t/* $3 = [$1 + DATA] */\n\t\t\tpracc_add(ctx, 0, MIPS32_LW(0, 3, ATH79_REG_DATA, 1));\n\t\t\t/* [OUTi] = $3 */\n\t\t\tpracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,\n\t\t\t\t  MIPS32_SW(0, 3, PRACC_OUT_OFFSET +\n\t\t\t\t pracc_out, 15));\n\t\t\tpracc_out += 4;\n\t\t}\n\t}\n\tif (len & 3) { /* not a multiple of 4 bytes */\n\t\t/* $3 = [$1 + DATA] */\n\t\tpracc_add(ctx, 0, MIPS32_LW(0, 3, ATH79_REG_DATA, 1));\n\t\t/* [OUTi] = $3 */\n\t\tpracc_add(ctx, MIPS32_PRACC_PARAM_OUT + pracc_out,\n\t\t\t  MIPS32_SW(0, 3, PRACC_OUT_OFFSET + pracc_out, 15));\n\t\tpracc_out += 4;\n\t}\n\n\tif (ath79_info->spi.post_deselect && !partial_xfer) {\n\t\tconst uint32_t post_deselect[] = {\n\t\t\t/* $2 = SPI_CS_DIS */\n\t\t\tMIPS32_LUI(0, 2, UPPER16(cs_high)),\n\t\t\tMIPS32_ORI(0, 2, 2, LOWER16(cs_high)),\n\t\t\t/* [$1 + WRITE] = $2 */\n\t\t\tMIPS32_SW(0, 2, ATH79_REG_WRITE, 1),\n\n\t\t\t/* [$1 + FS] = 0  (disable flash io register access) */\n\t\t\tMIPS32_XORI(0, 2, 2, 0),\n\t\t\tMIPS32_SW(0, 2, ATH79_REG_FS, 1),\n\t\t};\n\t\tath79_pracc_addn(ctx, post_deselect, ARRAY_SIZE(post_deselect));\n\t}\n\n\t/* common pracc epilogue */\n\t/* jump to start */\n\tpracc_add(ctx, 0, MIPS32_B(0, NEG16(ctx->code_count + 1)));\n\t/* restore $15 from DeSave */\n\tpracc_add(ctx, 0, MIPS32_MFC0(0, 15, 31, 0));\n\n\treturn pracc_out / 4;\n}\n\nstatic int ath79_spi_bitbang_chunk(struct flash_bank *bank,\n\t\t\t\t   uint8_t *data, int len, int *transferred)\n{\n\tstruct target *target = bank->target;\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tint pracc_words;\n\n\t/*\n\t * These constants must match the worst case in the above code\n\t * generator function ath79_spi_bitbang_codegen.\n\t */\n\tconst int pracc_pre_post = 26;\n\tconst int pracc_loop_byte = 8 * 2 + 2;\n\n\tstruct pracc_queue_info ctx = {\n\t\t.ejtag_info = ejtag_info\n\t};\n\tint max_len = (PRACC_MAX_INSTRUCTIONS - pracc_pre_post) / pracc_loop_byte;\n\tint to_xfer = len > max_len ? max_len : len;\n\tint partial_xfer = len != to_xfer;\n\tint padded_len = (to_xfer + 3) & ~3;\n\tuint32_t *out = malloc(padded_len);\n\n\tif (!out) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*transferred = 0;\n\tpracc_queue_init(&ctx);\n\n\tLOG_DEBUG(\"ath79_spi_bitbang_bytes(%p, %08\" PRIx32 \", %p, %d)\",\n\t\t  target, ath79_info->io_base, data, len);\n\n\tLOG_DEBUG(\"max code %d => max len %d. to_xfer %d\",\n\t\t  PRACC_MAX_INSTRUCTIONS, max_len, to_xfer);\n\n\tpracc_words = ath79_spi_bitbang_codegen(\n\t\tath79_info, &ctx, data, to_xfer, partial_xfer);\n\n\tLOG_DEBUG(\"Assembled %d instructions, %d stores\",\n\t\t  ctx.code_count, ctx.store_count);\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, out, 1);\n\tif (ctx.retval != ERROR_OK)\n\t\tgoto exit;\n\n\tif (to_xfer & 3) { /* Not a multiple of 4 bytes. */\n\t\t/*\n\t\t * Need to realign last word since we didn't shift the\n\t\t * full 32 bits.\n\t\t */\n\t\tint missed_bytes = 4 - (to_xfer & 3);\n\n\t\tout[pracc_words - 1] <<= BITS_PER_BYTE * missed_bytes;\n\t}\n\n\t/*\n\t * pracc reads return uint32_t in host endianness, convert to\n\t * target endianness.\n\t * Since we know the ATH79 target is big endian and the SPI\n\t * shift register has the bytes in highest to lowest bit order,\n\t * this will ensure correct memory byte order regardless of host\n\t * endianness.\n\t */\n\ttarget_buffer_set_u32_array(target, (uint8_t *)out, pracc_words, out);\n\n\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG)) {\n\t\tfor (int i = 0; i < to_xfer; i++) {\n\t\t\tLOG_DEBUG(\"bitbang %02x => %02x\",\n\t\t\t\t  data[i], ((uint8_t *)out)[i]);\n\t\t}\n\t}\n\tmemcpy(data, out, to_xfer);\n\t*transferred = to_xfer;\n\nexit:\n\tpracc_queue_free(&ctx);\n\tfree(out);\n\treturn ctx.retval;\n}\n\nstatic void ath79_spi_bitbang_prepare(struct flash_bank *bank)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\n\tath79_info->spi.pre_deselect = 1;\n}\n\nstatic int ath79_spi_bitbang_bytes(struct flash_bank *bank,\n\t\t\t\t   uint8_t *data, int len, uint32_t flags)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tint retval;\n\tint transferred;\n\n\tath79_info->spi.post_deselect = !!(flags & ATH79_XFER_FINAL);\n\n\tdo {\n\t\ttransferred = 0;\n\t\tretval = ath79_spi_bitbang_chunk(\n\t\t\tbank, data, len, &transferred);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tdata += transferred;\n\t\tlen -= transferred;\n\t} while (len > 0);\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(ath79_flash_bank_command)\n{\n\tstruct ath79_flash_bank *ath79_info;\n\tint chipselect = 0;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 6 || CMD_ARGC > 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 7) {\n\t\tif (strcmp(CMD_ARGV[6], \"cs0\") == 0)\n\t\t\tchipselect = 0;  /* default */\n\t\telse if (strcmp(CMD_ARGV[6], \"cs1\") == 0)\n\t\t\tchipselect = 1;\n\t\telse if (strcmp(CMD_ARGV[6], \"cs2\") == 0)\n\t\t\tchipselect = 2;\n\t\telse {\n\t\t\tLOG_ERROR(\"Unknown arg: %s\", CMD_ARGV[6]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tath79_info = calloc(1, sizeof(struct ath79_flash_bank));\n\tif (!ath79_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tath79_info->chipselect = chipselect;\n\tbank->driver_priv = ath79_info;\n\n\treturn ERROR_OK;\n}\n\n/* Read the status register of the external SPI flash chip. */\nstatic int read_status_reg(struct flash_bank *bank, uint32_t *status)\n{\n\tuint8_t spi_bytes[] = {SPIFLASH_READ_STATUS, 0};\n\tint retval;\n\n\t/* Send SPI command \"read STATUS\" */\n\tath79_spi_bitbang_prepare(bank);\n\tretval = ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes),\n\t\tATH79_XFER_FINAL);\n\n\t*status = spi_bytes[1];\n\n\treturn retval;\n}\n\n/* check for WIP (write in progress) bit in status register */\n/* timeout in ms */\nstatic int wait_till_ready(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\tint retval;\n\tlong long endtime;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\t/* read flash status register */\n\t\tretval = read_status_reg(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & SPIFLASH_BSY_BIT) == 0)\n\t\t\treturn ERROR_OK;\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_FAIL;\n}\n\n/* Send \"write enable\" command to SPI flash chip. */\nstatic int ath79_write_enable(struct flash_bank *bank)\n{\n\tuint32_t status;\n\tint retval;\n\n\tuint8_t spi_bytes[] = {SPIFLASH_WRITE_ENABLE};\n\n\t/* Send SPI command \"write enable\" */\n\tath79_spi_bitbang_prepare(bank);\n\tretval = ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes),\n\t\tATH79_XFER_FINAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* read flash status register */\n\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check write enabled */\n\tif ((status & SPIFLASH_WE_BIT) == 0) {\n\t\tLOG_ERROR(\"Cannot enable write to flash. Status=0x%08\" PRIx32,\n\t\t\t  status);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int erase_command(struct flash_bank *bank, int sector)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tuint32_t offset = bank->sectors[sector].offset;\n\n\tuint8_t spi_bytes[] = {\n\t\tath79_info->dev->erase_cmd,\n\t\toffset >> 16,\n\t\toffset >> 8,\n\t\toffset\n\t};\n\n\t/* bitbang command */\n\tath79_spi_bitbang_prepare(bank);\n\treturn ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes),\n\t\tATH79_XFER_FINAL);\n}\n\nstatic int ath79_erase_sector(struct flash_bank *bank, int sector)\n{\n\tint retval = ath79_write_enable(bank);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send SPI command \"block erase\" */\n\tretval = erase_command(bank, sector);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* poll WIP for end of self timed Sector Erase cycle */\n\treturn wait_till_ready(bank, ATH79_MAX_TIMEOUT);\n}\n\nstatic int ath79_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: from sector %u to sector %u\", __func__, first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!ath79_info->probed) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (ath79_info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tfor (unsigned sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = ath79_erase_sector(bank, sector);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\tkeep_alive();\n\t}\n\n\treturn retval;\n}\n\nstatic int ath79_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\treturn ERROR_OK;\n}\n\nstatic int ath79_write_page(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t    uint32_t address, uint32_t len)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tuint8_t spi_bytes[] = {\n\t\tSPIFLASH_PAGE_PROGRAM,\n\t\taddress >> 16,\n\t\taddress >> 8,\n\t\taddress,\n\t};\n\tint retval;\n\tuint32_t i, pagesize;\n\n\t/* if no write pagesize, use reasonable default */\n\tpagesize = ath79_info->dev->pagesize ?\n\t\tath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\tif (address & 0xff) {\n\t\tLOG_ERROR(\"ath79_write_page: unaligned write address: %08\" PRIx32,\n\t\t\t  address);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!ath79_info->spi.page_buf) {\n\t\tLOG_ERROR(\"ath79_write_page: page buffer not initialized\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (len > ath79_info->dev->pagesize) {\n\t\tLOG_ERROR(\"ath79_write_page: len bigger than page size %\" PRIu32 \": %\" PRIu32,\n\t\t\tpagesize, len);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = 0; i < len; i++) {\n\t\tif (buffer[i] != 0xff)\n\t\t\tbreak;\n\t}\n\tif (i == len)  /* all 0xff, no need to program. */\n\t\treturn ERROR_OK;\n\n\tLOG_INFO(\"writing %\" PRIu32 \" bytes to flash page @0x%08\" PRIx32, len, address);\n\n\tmemcpy(ath79_info->spi.page_buf, buffer, len);\n\n\t/* unlock writes */\n\tretval = ath79_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* bitbang command */\n\tath79_spi_bitbang_prepare(bank);\n\tretval = ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes),\n\t\tATH79_XFER_PARTIAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write data */\n\treturn ath79_spi_bitbang_bytes(\n\t\tbank, ath79_info->spi.page_buf, len,\n\t\tATH79_XFER_FINAL);\n}\n\nstatic int ath79_write_buffer(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t      uint32_t address, uint32_t len)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tuint32_t page_size;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: address=0x%08\" PRIx32 \" len=0x%08\" PRIx32,\n\t\t  __func__, address, len);\n\n\t/* if no valid page_size, use reasonable default */\n\tpage_size = ath79_info->dev->pagesize ?\n\t\tath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\twhile (len > 0) {\n\t\tint page_len = len > page_size ? page_size : len;\n\n\t\tretval = ath79_write_page(\n\t\t\tbank, buffer, address, page_len);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += page_size;\n\t\taddress += page_size;\n\t\tlen -= page_len;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ath79_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t       uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t  __func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Write pasts end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tstruct flash_sector *bs = &bank->sectors[sector];\n\n\t\tif ((offset < (bs->offset + bs->size)) &&\n\t\t    ((offset + count - 1) >= bs->offset) &&\n\t\t    bs->is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ath79_write_buffer(bank, buffer, offset, count);\n}\n\nstatic int ath79_read_buffer(struct flash_bank *bank, uint8_t *buffer,\n\t\t\t     uint32_t address, uint32_t len)\n{\n\tuint8_t spi_bytes[] = {\n\t\tSPIFLASH_READ,\n\t\taddress >> 16,\n\t\taddress >> 8,\n\t\taddress,\n\t};\n\tint retval;\n\n\tLOG_DEBUG(\"%s: address=0x%08\" PRIx32 \" len=0x%08\" PRIx32,\n\t\t  __func__, address, len);\n\n\tif (address & 0xff) {\n\t\tLOG_ERROR(\"ath79_read_buffer: unaligned read address: %08\" PRIx32,\n\t\t\t  address);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"reading %\" PRIu32 \" bytes from flash @0x%08\" PRIx32, len, address);\n\n\t/* bitbang command */\n\tath79_spi_bitbang_prepare(bank);\n\tretval = ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes), ATH79_XFER_PARTIAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* read data */\n\treturn ath79_spi_bitbang_bytes(\n\t\tbank, buffer, len, ATH79_XFER_FINAL);\n}\n\nstatic int ath79_read(struct flash_bank *bank, uint8_t *buffer,\n\t\t      uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t  __func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Reads past end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\treturn ath79_read_buffer(bank, buffer, offset, count);\n}\n\n/* Return ID of flash device */\nstatic int read_flash_id(struct flash_bank *bank, uint32_t *id)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\tuint8_t spi_bytes[] = {SPIFLASH_READ_ID, 0, 0, 0};\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Send SPI command \"read ID\" */\n\tath79_spi_bitbang_prepare(bank);\n\tretval = ath79_spi_bitbang_bytes(\n\t\tbank, spi_bytes, sizeof(spi_bytes), ATH79_XFER_FINAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*id = (spi_bytes[1] << 0)\n\t\t| (spi_bytes[2] << 8)\n\t\t| (spi_bytes[3] << 16);\n\n\tif (*id == 0xffffff) {\n\t\tLOG_ERROR(\"No SPI flash found\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ath79_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\tstruct flash_sector *sectors;\n\tuint32_t id = 0; /* silence uninitialized warning */\n\tuint32_t pagesize, sectorsize;\n\tconst struct ath79_target *target_device;\n\tint retval;\n\n\tif (ath79_info->probed) {\n\t\tfree(bank->sectors);\n\t\tfree(ath79_info->spi.page_buf);\n\t}\n\tath79_info->probed = false;\n\n\tfor (target_device = target_devices; target_device->name;\n\t\t++target_device)\n\t\tif (target_device->tap_idcode == target->tap->idcode)\n\t\t\tbreak;\n\tif (!target_device->name) {\n\t\tLOG_ERROR(\"Device ID 0x%\" PRIx32 \" is not known\",\n\t\t\t  target->tap->idcode);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tath79_info->io_base = target_device->io_base;\n\n\tLOG_DEBUG(\"Found device %s at address \" TARGET_ADDR_FMT,\n\t\t  target_device->name, bank->base);\n\n\tretval = read_flash_id(bank, &id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tath79_info->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name; p++)\n\t\tif (p->device_id == id) {\n\t\t\tath79_info->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!ath79_info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%08\" PRIx32 \")\",\n\t\t ath79_info->dev->name, ath79_info->dev->device_id);\n\n\t/* Set correct size value */\n\tbank->size = ath79_info->dev->size_in_bytes;\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\tif (bank->size > (1UL << 24))\n\t\tLOG_WARNING(\"device needs paging or 4-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = ath79_info->dev->sectorsize ?\n\t\tath79_info->dev->sectorsize : ath79_info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = ath79_info->dev->size_in_bytes / sectorsize;\n\tsectors = calloc(1, sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* if no write pagesize, use reasonable default */\n\tpagesize = ath79_info->dev->pagesize ? ath79_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\tath79_info->spi.page_buf = malloc(pagesize);\n\tif (!ath79_info->spi.page_buf) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\tfree(sectors);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = 0;\n\t\tsectors[sector].is_protected = 1;\n\t}\n\n\tbank->sectors = sectors;\n\tath79_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int ath79_auto_probe(struct flash_bank *bank)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\n\tif (ath79_info->probed)\n\t\treturn ERROR_OK;\n\treturn ath79_probe(bank);\n}\n\nstatic int ath79_flash_blank_check(struct flash_bank *bank)\n{\n\t/* Not implemented */\n\treturn ERROR_OK;\n}\n\nstatic int ath79_protect_check(struct flash_bank *bank)\n{\n\t/* Not implemented */\n\treturn ERROR_OK;\n}\n\nstatic int get_ath79_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct ath79_flash_bank *ath79_info = bank->driver_priv;\n\n\tif (!ath79_info->probed) {\n\t\tcommand_print_sameline(cmd, \"\\nATH79 flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nATH79 flash information:\\n\"\n\t\t\"  Device \\'%s\\' (ID 0x%08\" PRIx32 \")\\n\",\n\t\tath79_info->dev->name, ath79_info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver ath79_flash = {\n\t.name = \"ath79\",\n\t.flash_bank_command = ath79_flash_bank_command,\n\t.erase = ath79_erase,\n\t.protect = ath79_protect,\n\t.write = ath79_write,\n\t.read = ath79_read,\n\t.probe = ath79_probe,\n\t.auto_probe = ath79_auto_probe,\n\t.erase_check = ath79_flash_blank_check,\n\t.protect_check = ath79_protect_check,\n\t.info = get_ath79_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/atsame5.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Tomas Vanek\t\t\t\t\t   *\n *   vanekt@fbl.cz\t\t\t\t\t\t\t   *\n *                                                                         *\n *   Based on at91samd.c                                                   *\n *   Copyright (C) 2013 by Andrey Yurovsky                                 *\n *   Andrey Yurovsky <yurovsky@gmail.com>                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"helper/binarybuffer.h\"\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include <target/cortex_m.h>\n\n/* A note to prefixing.\n * Definitions and functions inherited from at91samd.c without\n * any change retained the original prefix samd_ so they eventually\n * may go to samd_common.h and .c\n * As currently there are only 3 short functions identical with\n * the original source, no common file was created. */\n\n#define SAME5_PAGES_PER_BLOCK\t16\n#define SAME5_NUM_PROT_BLOCKS\t32\n#define SAMD_PAGE_SIZE_MAX\t1024\n\n#define SAMD_FLASH\t\t0x00000000\t/* physical Flash memory */\n#define SAMD_USER_ROW\t\t0x00804000\t/* User Row of Flash */\n\n#define SAME5_PAC\t\t0x40000000\t/* Peripheral Access Control */\n\n#define SAMD_DSU\t\t0x41002000\t/* Device Service Unit */\n#define SAMD_NVMCTRL\t\t0x41004000\t/* Non-volatile memory controller */\n\n#define SAMD_DSU_STATUSA        1               /* DSU status register */\n#define SAMD_DSU_DID\t\t0x18\t\t/* Device ID register */\n#define SAMD_DSU_CTRL_EXT\t0x100\t\t/* CTRL register, external access */\n\n#define SAME5_NVMCTRL_CTRLA\t0x00\t\t/* NVM control A register */\n#define SAME5_NVMCTRL_CTRLB\t0x04\t\t/* NVM control B register */\n#define SAMD_NVMCTRL_PARAM\t0x08\t\t/* NVM parameters register */\n#define SAME5_NVMCTRL_INTFLAG\t0x10\t\t/* NVM interrupt flag register */\n#define SAME5_NVMCTRL_STATUS\t0x12\t\t/* NVM status register */\n#define SAME5_NVMCTRL_ADDR\t0x14\t\t/* NVM address register */\n#define SAME5_NVMCTRL_LOCK\t0x18\t\t/* NVM Lock section register */\n\n#define SAMD_CMDEX_KEY\t\t0xA5UL\n#define SAMD_NVM_CMD(n)\t\t((SAMD_CMDEX_KEY << 8) | (n & 0x7F))\n\n/* NVMCTRL commands. */\n#define SAME5_NVM_CMD_EP\t0x00\t\t/* Erase Page (User Page only) */\n#define SAME5_NVM_CMD_EB\t0x01\t\t/* Erase Block */\n#define SAME5_NVM_CMD_WP\t0x03\t\t/* Write Page */\n#define SAME5_NVM_CMD_WQW\t0x04\t\t/* Write Quad Word */\n#define SAME5_NVM_CMD_LR\t0x11\t\t/* Lock Region */\n#define SAME5_NVM_CMD_UR\t0x12\t\t/* Unlock Region */\n#define SAME5_NVM_CMD_PBC\t0x15\t\t/* Page Buffer Clear */\n#define SAME5_NVM_CMD_SSB\t0x16\t\t/* Set Security Bit */\n\n/* NVMCTRL bits */\n#define SAME5_NVMCTRL_CTRLA_WMODE_MASK\t0x30\n\n#define SAME5_NVMCTRL_INTFLAG_DONE\t(1 << 0)\n#define SAME5_NVMCTRL_INTFLAG_ADDRE\t(1 << 1)\n#define SAME5_NVMCTRL_INTFLAG_PROGE\t(1 << 2)\n#define SAME5_NVMCTRL_INTFLAG_LOCKE\t(1 << 3)\n#define SAME5_NVMCTRL_INTFLAG_ECCSE\t(1 << 4)\n#define SAME5_NVMCTRL_INTFLAG_ECCDE\t(1 << 5)\n#define SAME5_NVMCTRL_INTFLAG_NVME\t(1 << 6)\n\n\n/* Known identifiers */\n#define SAMD_PROCESSOR_M0\t0x01\n#define SAMD_PROCESSOR_M4\t0x06\n#define SAMD_FAMILY_D\t\t0x00\n#define SAMD_FAMILY_E\t\t0x03\n#define SAMD_SERIES_51\t\t0x06\n#define SAME_SERIES_51\t\t0x01\n#define SAME_SERIES_53\t\t0x03\n#define SAME_SERIES_54\t\t0x04\n\n/* Device ID macros */\n#define SAMD_GET_PROCESSOR(id) (id >> 28)\n#define SAMD_GET_FAMILY(id) (((id >> 23) & 0x1F))\n#define SAMD_GET_SERIES(id) (((id >> 16) & 0x3F))\n#define SAMD_GET_DEVSEL(id) (id & 0xFF)\n\n/* Bits to mask user row */\n#define NVMUSERROW_SAM_E5_D5_MASK\t0x7FFF00FF3C007FFFULL\n\nstruct samd_part {\n\tuint8_t id;\n\tconst char *name;\n\tuint32_t flash_kb;\n\tuint32_t ram_kb;\n};\n\n/* See SAM D5x/E5x Family Silicon Errata and Data Sheet Clarification\n * DS80000748K */\n/* Known SAMD51 parts. */\nstatic const struct samd_part samd51_parts[] = {\n\t{ 0x00, \"SAMD51P20A\", 1024, 256 },\n\t{ 0x01, \"SAMD51P19A\", 512, 192 },\n\t{ 0x02, \"SAMD51N20A\", 1024, 256 },\n\t{ 0x03, \"SAMD51N19A\", 512, 192 },\n\t{ 0x04, \"SAMD51J20A\", 1024, 256 },\n\t{ 0x05, \"SAMD51J19A\", 512, 192 },\n\t{ 0x06, \"SAMD51J18A\", 256, 128 },\n\t{ 0x07, \"SAMD51G19A\", 512, 192 },\n\t{ 0x08, \"SAMD51G18A\", 256, 128 },\n};\n\n/* Known SAME51 parts. */\nstatic const struct samd_part same51_parts[] = {\n\t{ 0x00, \"SAME51N20A\", 1024, 256 },\n\t{ 0x01, \"SAME51N19A\", 512, 192 },\n\t{ 0x02, \"SAME51J19A\", 512, 192 },\n\t{ 0x03, \"SAME51J18A\", 256, 128 },\n\t{ 0x04, \"SAME51J20A\", 1024, 256 },\n\t{ 0x05, \"SAME51G19A\", 512, 192 },\t/* New in rev D */\n\t{ 0x06, \"SAME51G18A\", 256, 128 },\t/* New in rev D */\n};\n\n/* Known SAME53 parts. */\nstatic const struct samd_part same53_parts[] = {\n\t{ 0x02, \"SAME53N20A\", 1024, 256 },\n\t{ 0x03, \"SAME53N19A\", 512, 192 },\n\t{ 0x04, \"SAME53J20A\", 1024, 256 },\n\t{ 0x05, \"SAME53J19A\", 512, 192 },\n\t{ 0x06, \"SAME53J18A\", 256, 128 },\n\t{ 0x55, \"LAN9255/ZMX020\", 1024, 256 },\n\t{ 0x56, \"LAN9255/ZMX019\", 512, 192 },\n\t{ 0x57, \"LAN9255/ZMX018\", 256, 128 },\n};\n\n/* Known SAME54 parts. */\nstatic const struct samd_part same54_parts[] = {\n\t{ 0x00, \"SAME54P20A\", 1024, 256 },\n\t{ 0x01, \"SAME54P19A\", 512, 192 },\n\t{ 0x02, \"SAME54N20A\", 1024, 256 },\n\t{ 0x03, \"SAME54N19A\", 512, 192 },\n};\n\n/* Each family of parts contains a parts table in the DEVSEL field of DID.  The\n * processor ID, family ID, and series ID are used to determine which exact\n * family this is and then we can use the corresponding table. */\nstruct samd_family {\n\tuint8_t processor;\n\tuint8_t family;\n\tuint8_t series;\n\tconst struct samd_part *parts;\n\tsize_t num_parts;\n};\n\n/* Known SAMD families */\nstatic const struct samd_family samd_families[] = {\n\t{ SAMD_PROCESSOR_M4, SAMD_FAMILY_D, SAMD_SERIES_51,\n\t\tsamd51_parts, ARRAY_SIZE(samd51_parts) },\n\t{ SAMD_PROCESSOR_M4, SAMD_FAMILY_E, SAME_SERIES_51,\n\t\tsame51_parts, ARRAY_SIZE(same51_parts) },\n\t{ SAMD_PROCESSOR_M4, SAMD_FAMILY_E, SAME_SERIES_53,\n\t\tsame53_parts, ARRAY_SIZE(same53_parts) },\n\t{ SAMD_PROCESSOR_M4, SAMD_FAMILY_E, SAME_SERIES_54,\n\t\tsame54_parts, ARRAY_SIZE(same54_parts) },\n};\n\nstruct samd_info {\n\tconst struct samd_params *par;\n\tuint32_t page_size;\n\tint num_pages;\n\tint sector_size;\n\tint prot_block_size;\n\n\tbool probed;\n\tstruct target *target;\n};\n\n\n/**\n * Gives the family structure to specific device id.\n * @param id The id of the device.\n * @return On failure NULL, otherwise a pointer to the structure.\n */\nstatic const struct samd_family *samd_find_family(uint32_t id)\n{\n\tuint8_t processor = SAMD_GET_PROCESSOR(id);\n\tuint8_t family = SAMD_GET_FAMILY(id);\n\tuint8_t series = SAMD_GET_SERIES(id);\n\n\tfor (unsigned i = 0; i < ARRAY_SIZE(samd_families); i++) {\n\t\tif (samd_families[i].processor == processor &&\n\t\t\tsamd_families[i].series == series &&\n\t\t\tsamd_families[i].family == family)\n\t\t\treturn &samd_families[i];\n\t}\n\n\treturn NULL;\n}\n\n/**\n * Gives the part structure to specific device id.\n * @param id The id of the device.\n * @return On failure NULL, otherwise a pointer to the structure.\n */\nstatic const struct samd_part *samd_find_part(uint32_t id)\n{\n\tuint8_t devsel = SAMD_GET_DEVSEL(id);\n\tconst struct samd_family *family = samd_find_family(id);\n\tif (!family)\n\t\treturn NULL;\n\n\tfor (unsigned i = 0; i < family->num_parts; i++) {\n\t\tif (family->parts[i].id == devsel)\n\t\t\treturn &family->parts[i];\n\t}\n\n\treturn NULL;\n}\n\nstatic int same5_protect_check(struct flash_bank *bank)\n{\n\tint res;\n\tuint32_t lock;\n\n\tres = target_read_u32(bank->target,\n\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_LOCK, &lock);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Lock bits are active-low */\n\tfor (unsigned int prot_block = 0; prot_block < bank->num_prot_blocks; prot_block++)\n\t\tbank->prot_blocks[prot_block].is_protected = !(lock & (1u<<prot_block));\n\n\treturn ERROR_OK;\n}\n\nstatic int samd_get_flash_page_info(struct target *target,\n\t\tuint32_t *sizep, int *nump)\n{\n\tint res;\n\tuint32_t param;\n\n\tres = target_read_u32(target, SAMD_NVMCTRL + SAMD_NVMCTRL_PARAM, &param);\n\tif (res == ERROR_OK) {\n\t\t/* The PSZ field (bits 18:16) indicate the page size bytes as 2^(3+n)\n\t\t * so 0 is 8KB and 7 is 1024KB. */\n\t\tif (sizep)\n\t\t\t*sizep = (8 << ((param >> 16) & 0x7));\n\t\t/* The NVMP field (bits 15:0) indicates the total number of pages */\n\t\tif (nump)\n\t\t\t*nump = param & 0xFFFF;\n\t} else {\n\t\tLOG_ERROR(\"Couldn't read NVM Parameters register\");\n\t}\n\n\treturn res;\n}\n\nstatic int same5_probe(struct flash_bank *bank)\n{\n\tuint32_t id;\n\tint res;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\tconst struct samd_part *part;\n\n\tif (chip->probed)\n\t\treturn ERROR_OK;\n\n\tres = target_read_u32(bank->target, SAMD_DSU + SAMD_DSU_DID, &id);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read Device ID register\");\n\t\treturn res;\n\t}\n\n\tpart = samd_find_part(id);\n\tif (!part) {\n\t\tLOG_ERROR(\"Couldn't find part corresponding to DID %08\" PRIx32, id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->size = part->flash_kb * 1024;\n\n\tres = samd_get_flash_page_info(bank->target, &chip->page_size,\n\t\t\t&chip->num_pages);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't determine Flash page size\");\n\t\treturn res;\n\t}\n\n\t/* Sanity check: the total flash size in the DSU should match the page size\n\t * multiplied by the number of pages. */\n\tif (bank->size != chip->num_pages * chip->page_size) {\n\t\tLOG_WARNING(\"SAM: bank size doesn't match NVM parameters. \"\n\t\t\t\t\"Identified %\" PRIu32 \"KB Flash but NVMCTRL reports %u %\" PRIu32 \"B pages\",\n\t\t\t\tpart->flash_kb, chip->num_pages, chip->page_size);\n\t}\n\n\t/* Erase granularity = 1 block = 16 pages */\n\tchip->sector_size = chip->page_size * SAME5_PAGES_PER_BLOCK;\n\n\t/* Allocate the sector table */\n\tbank->num_sectors = chip->num_pages / SAME5_PAGES_PER_BLOCK;\n\tbank->sectors = alloc_block_array(0, chip->sector_size, bank->num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\t/* 16 protection blocks per device */\n\tchip->prot_block_size = bank->size / SAME5_NUM_PROT_BLOCKS;\n\n\t/* Allocate the table of protection blocks */\n\tbank->num_prot_blocks = SAME5_NUM_PROT_BLOCKS;\n\tbank->prot_blocks = alloc_block_array(0, chip->prot_block_size, bank->num_prot_blocks);\n\tif (!bank->prot_blocks)\n\t\treturn ERROR_FAIL;\n\n\tsame5_protect_check(bank);\n\n\t/* Done */\n\tchip->probed = true;\n\n\tLOG_INFO(\"SAM MCU: %s (%\" PRIu32 \"KB Flash, %\" PRIu32 \"KB RAM)\", part->name,\n\t\t\tpart->flash_kb, part->ram_kb);\n\n\treturn ERROR_OK;\n}\n\nstatic int same5_wait_and_check_error(struct target *target)\n{\n\tint ret, ret2;\n\t/* Table 54-40 lists the maximum erase block time as 200 ms.\n\t * Include some margin.\n\t */\n\tint timeout_ms = 200 * 5;\n\tint64_t ts_start = timeval_ms();\n\tuint16_t intflag;\n\n\tdo {\n\t\tret = target_read_u16(target,\n\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_INTFLAG, &intflag);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"SAM: error reading the NVMCTRL_INTFLAG register\");\n\t\t\treturn ret;\n\t\t}\n\t\tif (intflag & SAME5_NVMCTRL_INTFLAG_DONE)\n\t\t\tbreak;\n\t\tkeep_alive();\n\t} while (timeval_ms() - ts_start < timeout_ms);\n\n\tif (!(intflag & SAME5_NVMCTRL_INTFLAG_DONE)) {\n\t\tLOG_ERROR(\"SAM: NVM programming timed out\");\n\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t}\n#if 0\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_ECCSE)\n\t\tLOG_ERROR(\"SAM: ECC Single Error\");\n\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_ECCDE) {\n\t\tLOG_ERROR(\"SAM: ECC Double Error\");\n\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t}\n#endif\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_ADDRE) {\n\t\tLOG_ERROR(\"SAM: Addr Error\");\n\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_NVME) {\n\t\tLOG_ERROR(\"SAM: NVM Error\");\n\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_LOCKE) {\n\t\tLOG_ERROR(\"SAM: NVM lock error\");\n\t\tret = ERROR_FLASH_PROTECTED;\n\t}\n\n\tif (intflag & SAME5_NVMCTRL_INTFLAG_PROGE) {\n\t\tLOG_ERROR(\"SAM: NVM programming error\");\n\t\tret = ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\t/* Clear the error conditions by writing a one to them */\n\tret2 = target_write_u16(target,\n\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_INTFLAG, intflag);\n\tif (ret2 != ERROR_OK)\n\t\tLOG_ERROR(\"Can't clear NVM error conditions\");\n\n\treturn ret;\n}\n\nstatic int same5_issue_nvmctrl_command(struct target *target, uint16_t cmd)\n{\n\tint res;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Issue the NVM command */\n\t/* 32-bit write is used to ensure atomic operation on ST-Link */\n\tres = target_write_u32(target,\n\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_CTRLB, SAMD_NVM_CMD(cmd));\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Check to see if the NVM command resulted in an error condition. */\n\treturn same5_wait_and_check_error(target);\n}\n\n/**\n * Erases a flash block or page at the given address.\n * @param target Pointer to the target structure.\n * @param address The address of the row.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int same5_erase_block(struct target *target, uint32_t address)\n{\n\tint res;\n\n\t/* Set an address contained in the block to be erased */\n\tres = target_write_u32(target,\n\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_ADDR, address);\n\n\t/* Issue the Erase Block command. */\n\tif (res == ERROR_OK)\n\t\tres = same5_issue_nvmctrl_command(target,\n\t\t\t\taddress == SAMD_USER_ROW ? SAME5_NVM_CMD_EP : SAME5_NVM_CMD_EB);\n\n\tif (res != ERROR_OK)  {\n\t\tLOG_ERROR(\"Failed to erase block containing %08\" PRIx32, address);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int same5_pre_write_check(struct target *target)\n{\n\tint res;\n\tuint32_t nvm_ctrla;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Check if manual write mode is set */\n\tres = target_read_u32(target, SAMD_NVMCTRL + SAME5_NVMCTRL_CTRLA, &nvm_ctrla);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (nvm_ctrla & SAME5_NVMCTRL_CTRLA_WMODE_MASK) {\n\t\tLOG_ERROR(\"The flash controller must be in manual write mode. Issue 'reset init' and retry.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn res;\n}\n\n\n/**\n * Modify the contents of the User Row in Flash. The User Row itself\n * has a size of one page and contains a combination of \"fuses\" and\n * calibration data. Bits which have a value of zero in the mask will\n * not be changed.\n * @param target Pointer to the target structure.\n * @param data Pointer to the value to write.\n * @param mask Pointer to bitmask, 0 -> value stays untouched.\n * @param offset Offset in user row where new data will be applied.\n * @param count Size of buffer and mask in bytes.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int same5_modify_user_row_masked(struct target *target,\n\t\tconst uint8_t *data, const uint8_t *mask,\n\t\tuint32_t offset, uint32_t count)\n{\n\tint res;\n\n\t/* Retrieve the MCU's flash page size, in bytes. */\n\tuint32_t page_size;\n\tres = samd_get_flash_page_info(target, &page_size, NULL);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't determine Flash page size\");\n\t\treturn res;\n\t}\n\n\t/* Make sure the size is sane. */\n\tassert(page_size <= SAMD_PAGE_SIZE_MAX &&\n\t\tpage_size >= offset + count);\n\n\tuint8_t buf[SAMD_PAGE_SIZE_MAX];\n\t/* Read the user row (comprising one page) by words. */\n\tres = target_read_memory(target, SAMD_USER_ROW, 4, page_size / 4, buf);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Modify buffer and check if really changed */\n\tbool changed = false;\n\tuint32_t i;\n\tfor (i = 0; i < count; i++) {\n\t\tuint8_t old_b = buf[offset+i];\n\t\tuint8_t new_b = (old_b & ~mask[i]) | (data[i] & mask[i]);\n\t\tbuf[offset+i] = new_b;\n\t\tif (old_b != new_b)\n\t\t\tchanged = true;\n\t}\n\n\tif (!changed)\n\t\treturn ERROR_OK;\n\n\tres = same5_pre_write_check(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = same5_erase_block(target, SAMD_USER_ROW);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't erase user row\");\n\t\treturn res;\n\t}\n\n\t/* Write the page buffer back out to the target using Write Quad Word */\n\tfor (i = 0; i < page_size; i += 4 * 4) {\n\t\tres = target_write_memory(target, SAMD_USER_ROW + i, 4, 4, buf + i);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\t/* Trigger flash write */\n\t\tres = same5_issue_nvmctrl_command(target, SAME5_NVM_CMD_WQW);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\treturn res;\n}\n\n/**\n * Modifies the user row register to the given value.\n * @param target Pointer to the target structure.\n * @param value The value to write.\n * @param startb The bit-offset by which the given value is shifted.\n * @param endb The bit-offset of the last bit in value to write.\n * @return On success ERROR_OK, on failure an errorcode.\n */\nstatic int same5_modify_user_row(struct target *target, uint32_t value,\n\t\tuint8_t startb, uint8_t endb)\n{\n\tuint8_t buf_val[8] = { 0 };\n\tuint8_t buf_mask[8] = { 0 };\n\n\tassert(startb <= endb && endb < 64);\n\tbuf_set_u32(buf_val, startb, endb + 1 - startb, value);\n\tbuf_set_u32(buf_mask, startb, endb + 1 - startb, 0xffffffff);\n\n\treturn same5_modify_user_row_masked(target,\n\t\t\tbuf_val, buf_mask, 0, 8);\n}\n\nstatic int same5_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res = ERROR_OK;\n\n\t/* We can issue lock/unlock region commands with the target running but\n\t * the settings won't persist unless we're able to modify the LOCK regions\n\t * and that requires the target to be halted. */\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (unsigned int prot_block = first; prot_block <= last; prot_block++) {\n\t\tif (set != bank->prot_blocks[prot_block].is_protected) {\n\t\t\t/* Load an address that is within this protection block (we use offset 0) */\n\t\t\tres = target_write_u32(bank->target,\n\t\t\t\t\tSAMD_NVMCTRL + SAME5_NVMCTRL_ADDR,\n\t\t\t\t\tbank->prot_blocks[prot_block].offset);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tgoto exit;\n\n\t\t\t/* Tell the controller to lock that block */\n\t\t\tres = same5_issue_nvmctrl_command(bank->target,\n\t\t\t\t\tset ? SAME5_NVM_CMD_LR : SAME5_NVM_CMD_UR);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tgoto exit;\n\t\t}\n\t}\n\n\t/* We've now applied our changes, however they will be undone by the next\n\t * reset unless we also apply them to the LOCK bits in the User Page.\n\t * A '1' means unlocked and a '0' means locked. */\n\tconst uint8_t lock[4] = { 0, 0, 0, 0 };\n\tconst uint8_t unlock[4] = { 0xff, 0xff, 0xff, 0xff };\n\tuint8_t mask[4] = { 0, 0, 0, 0 };\n\n\tbuf_set_u32(mask, first, last + 1 - first, 0xffffffff);\n\n\tres = same5_modify_user_row_masked(bank->target,\n\t\t\tset ? lock : unlock, mask, 8, 4);\n\tif (res != ERROR_OK)\n\t\tLOG_WARNING(\"SAM: protect settings were not made persistent!\");\n\n\tres = ERROR_OK;\n\nexit:\n\tsame5_protect_check(bank);\n\n\treturn res;\n}\n\nstatic int same5_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!chip->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* For each sector to be erased */\n\tfor (unsigned int s = first; s <= last; s++) {\n\t\tres = same5_erase_block(bank->target, bank->sectors[s].offset);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"SAM: failed to erase sector %d at 0x%08\" PRIx32, s, bank->sectors[s].offset);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int same5_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tint res;\n\tuint32_t address;\n\tuint32_t pg_offset;\n\tuint32_t nb;\n\tuint32_t nw;\n\tstruct samd_info *chip = (struct samd_info *)bank->driver_priv;\n\tuint8_t *pb = NULL;\n\n\tres = same5_pre_write_check(bank->target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (!chip->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tres = same5_issue_nvmctrl_command(bank->target, SAME5_NVM_CMD_PBC);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: %d\", __func__, __LINE__);\n\t\treturn res;\n\t}\n\n\twhile (count) {\n\t\tnb = chip->page_size - offset % chip->page_size;\n\t\tif (count < nb)\n\t\t\tnb = count;\n\n\t\taddress = bank->base + offset;\n\t\tpg_offset = offset % chip->page_size;\n\n\t\tif (offset % 4 || (offset + nb) % 4) {\n\t\t\t/* Either start or end of write is not word aligned */\n\t\t\tif (!pb) {\n\t\t\t\tpb = malloc(chip->page_size);\n\t\t\t\tif (!pb)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* Set temporary page buffer to 0xff and overwrite the relevant part */\n\t\t\tmemset(pb, 0xff, chip->page_size);\n\t\t\tmemcpy(pb + pg_offset, buffer, nb);\n\n\t\t\t/* Align start address to a word boundary */\n\t\t\taddress -= offset % 4;\n\t\t\tpg_offset -= offset % 4;\n\t\t\tassert(pg_offset % 4 == 0);\n\n\t\t\t/* Extend length to whole words */\n\t\t\tnw = (nb + offset % 4 + 3) / 4;\n\t\t\tassert(pg_offset + 4 * nw <= chip->page_size);\n\n\t\t\t/* Now we have original data extended by 0xff bytes\n\t\t\t * to the nearest word boundary on both start and end */\n\t\t\tres = target_write_memory(bank->target, address, 4, nw, pb + pg_offset);\n\t\t} else {\n\t\t\tassert(nb % 4 == 0);\n\t\t\tnw = nb / 4;\n\t\t\tassert(pg_offset + 4 * nw <= chip->page_size);\n\n\t\t\t/* Word aligned data, use direct write from buffer */\n\t\t\tres = target_write_memory(bank->target, address, 4, nw, buffer);\n\t\t}\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: %d\", __func__, __LINE__);\n\t\t\tgoto free_pb;\n\t\t}\n\n\t\tres = same5_issue_nvmctrl_command(bank->target, SAME5_NVM_CMD_WP);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: write failed at address 0x%08\" PRIx32, __func__, address);\n\t\t\tgoto free_pb;\n\t\t}\n\n\t\t/* We're done with the page contents */\n\t\tcount -= nb;\n\t\toffset += nb;\n\t\tbuffer += nb;\n\t}\n\nfree_pb:\n\tfree(pb);\n\treturn res;\n}\n\n\nFLASH_BANK_COMMAND_HANDLER(same5_flash_bank_command)\n{\n\tif (bank->base != SAMD_FLASH) {\n\t\tLOG_ERROR(\"Address \" TARGET_ADDR_FMT \" invalid bank address (try \"\n\t\t\t\"0x%08x[same5] )\", bank->base, SAMD_FLASH);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct samd_info *chip;\n\tchip = calloc(1, sizeof(*chip));\n\tif (!chip) {\n\t\tLOG_ERROR(\"No memory for flash bank chip info\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchip->target = bank->target;\n\tchip->probed = false;\n\n\tbank->driver_priv = chip;\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(same5_handle_chip_erase_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target)\n\t\treturn ERROR_FAIL;\n\n\t/* Enable access to the DSU by disabling the write protect bit */\n\ttarget_write_u32(target, SAME5_PAC, (1<<16) | (1<<5) | (1<<1));\n\t/* intentionally without error checking - not accessible on secured chip */\n\n\t/* Tell the DSU to perform a full chip erase.  It takes about 240ms to\n\t * perform the erase. */\n\tint res = target_write_u8(target, SAMD_DSU + SAMD_DSU_CTRL_EXT, (1<<4));\n\tif (res == ERROR_OK)\n\t\tcommand_print(CMD, \"chip erase started\");\n\telse\n\t\tcommand_print(CMD, \"write to DSU CTRL failed\");\n\n\treturn res;\n}\n\n\nCOMMAND_HANDLER(same5_handle_userpage_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target)\n\t\treturn ERROR_FAIL;\n\n\tif (CMD_ARGC > 2) {\n\t\tcommand_print(CMD, \"Too much Arguments given.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC >= 1) {\n\t\tuint64_t value, mask = NVMUSERROW_SAM_E5_D5_MASK;\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], value);\n\n\t\tif (CMD_ARGC == 2) {\n\t\t\tuint64_t mask_temp;\n\t\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], mask_temp);\n\t\t\tmask &= mask_temp;\n\t\t}\n\n\t\tuint8_t val_buf[8], mask_buf[8];\n\t\ttarget_buffer_set_u64(target, val_buf, value);\n\t\ttarget_buffer_set_u64(target, mask_buf, mask);\n\n\t\tres = same5_modify_user_row_masked(target,\n\t\t\t\tval_buf, mask_buf, 0, sizeof(val_buf));\n\t}\n\n\tuint8_t buffer[8];\n\tint res2 = target_read_memory(target, SAMD_USER_ROW, 4, 2, buffer);\n\tif (res2 == ERROR_OK) {\n\t\tuint64_t value = target_buffer_get_u64(target, buffer);\n\t\tcommand_print(CMD, \"USER PAGE: 0x%016\"PRIX64, value);\n\t} else {\n\t\tLOG_ERROR(\"USER PAGE could not be read.\");\n\t}\n\n\tif (CMD_ARGC >= 1)\n\t\treturn res;\n\telse\n\t\treturn res2;\n}\n\n\nCOMMAND_HANDLER(same5_handle_bootloader_command)\n{\n\tint res = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target)\n\t\treturn ERROR_FAIL;\n\n\tif (CMD_ARGC >= 1) {\n\t\tunsigned long size;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[0], size);\n\t\tuint32_t code = (size + 8191) / 8192;\n\t\tif (code > 15) {\n\t\t\tcommand_print(CMD, \"Invalid bootloader size.  Please \"\n\t\t\t\t\t\t\"see datasheet for a list valid sizes.\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tres = same5_modify_user_row(target, 15 - code, 26, 29);\n\t}\n\n\tuint32_t val;\n\tint res2 = target_read_u32(target, SAMD_USER_ROW, &val);\n\tif (res2 == ERROR_OK) {\n\t\tuint32_t code = (val >> 26) & 0xf; /* grab size code */\n\t\tuint32_t size = (15 - code) * 8192;\n\t\tcommand_print(CMD, \"Bootloader protected in the first %\"\n\t\t\t\t      PRIu32 \" bytes\", size);\n\t}\n\n\tif (CMD_ARGC >= 1)\n\t\treturn res;\n\telse\n\t\treturn res2;\n}\n\n\nCOMMAND_HANDLER(samd_handle_reset_deassert)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint res = ERROR_OK;\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tif (!target)\n\t\treturn ERROR_FAIL;\n\n\t/* If the target has been unresponsive before, try to re-establish\n\t * communication now - CPU is held in reset by DSU, DAP is working */\n\tif (!target_was_examined(target))\n\t\ttarget_examine_one(target);\n\ttarget_poll(target);\n\n\t/* In case of sysresetreq, debug retains state set in cortex_m_assert_reset()\n\t * so we just release reset held by DSU\n\t *\n\t * n_RESET (srst) clears the DP, so reenable debug and set vector catch here\n\t *\n\t * After vectreset DSU release is not needed however makes no harm\n\t */\n\tif (target->reset_halt && (jtag_reset_config & RESET_HAS_SRST)) {\n\t\tres = target_write_u32(target, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);\n\t\tif (res == ERROR_OK)\n\t\t\tres = target_write_u32(target, DCB_DEMCR,\n\t\t\t\tTRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);\n\t\t/* do not return on error here, releasing DSU reset is more important */\n\t}\n\n\t/* clear CPU Reset Phase Extension bit */\n\tint res2 = target_write_u8(target, SAMD_DSU + SAMD_DSU_STATUSA, (1<<1));\n\tif (res2 != ERROR_OK)\n\t\treturn res2;\n\n\treturn res;\n}\n\nstatic const struct command_registration same5_exec_command_handlers[] = {\n\t{\n\t\t.name = \"dsu_reset_deassert\",\n\t\t.usage = \"\",\n\t\t.handler = samd_handle_reset_deassert,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Deassert internal reset held by DSU.\"\n\t},\n\t{\n\t\t.name = \"chip-erase\",\n\t\t.usage = \"\",\n\t\t.handler = same5_handle_chip_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase the entire Flash by using the Chip-\"\n\t\t\t\"Erase feature in the Device Service Unit (DSU).\",\n\t},\n\t{\n\t\t.name = \"bootloader\",\n\t\t.usage = \"[size_in_bytes]\",\n\t\t.handler = same5_handle_bootloader_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show or set the bootloader protection size, stored in the User Row. \"\n\t\t\t\"Changes are stored immediately but take affect after the MCU is \"\n\t\t\t\"reset.\",\n\t},\n\t{\n\t\t.name = \"userpage\",\n\t\t.usage = \"[value] [mask]\",\n\t\t.handler = same5_handle_userpage_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show or set the first 64-bit part of user page \"\n\t\t\t\"located at address 0x804000. Use the optional mask argument \"\n\t\t\t\"to prevent changes at positions where the bitvalue is zero. \"\n\t\t\t\"For security reasons the reserved-bits are masked out \"\n\t\t\t\"in background and therefore cannot be changed.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration same5_command_handlers[] = {\n\t{\n\t\t.name = \"atsame5\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"atsame5 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = same5_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver atsame5_flash = {\n\t.name = \"atsame5\",\n\t.commands = same5_command_handlers,\n\t.flash_bank_command = same5_flash_bank_command,\n\t.erase = same5_erase,\n\t.protect = same5_protect,\n\t.write = same5_write,\n\t.read = default_flash_read,\n\t.probe = same5_probe,\n\t.auto_probe = same5_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = same5_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/atsamv.c",
    "content": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-Source-Code)\n\n/*\n * Copyright (C) 2009 by Duane Ellis <openocd@duaneellis.com>\n *\n * at91sam3s* support\n * Copyright (C) 2010 by Olaf Lüke <olaf@uni-paderborn.de>\n *\n * at91sam3x* & at91sam4 support\n * Copyright (C) 2011 by Olivier Schonken and Jim Norris\n *\n * atsamv, atsams, and atsame support\n * Copyright (C) 2015 Morgan Quigley\n *\n * Some of the lower level code was based on code supplied by\n * ATMEL under BSD-Source-Code License and this copyright.\n * ATMEL Microcontroller Software Support\n * Copyright (c) 2009, Atmel Corporation. All rights reserved.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/time_support.h>\n\n#define REG_NAME_WIDTH  (12)\n\n#define SAMV_EFC_FCMD_GETD   (0x0)\t/* (EFC) Get Flash Descriptor */\n#define SAMV_EFC_FCMD_WP     (0x1)\t/* (EFC) Write Page */\n#define SAMV_EFC_FCMD_WPL    (0x2)\t/* (EFC) Write Page and Lock */\n#define SAMV_EFC_FCMD_EWP    (0x3)\t/* (EFC) Erase Page and Write Page */\n#define SAMV_EFC_FCMD_EWPL   (0x4)\t/* (EFC) Erase Page, Write Page then Lock*/\n#define SAMV_EFC_FCMD_EA     (0x5)\t/* (EFC) Erase All */\n#define SAMV_EFC_FCMD_EPA    (0x7)\t/* (EFC) Erase pages */\n#define SAMV_EFC_FCMD_SLB    (0x8)\t/* (EFC) Set Lock Bit */\n#define SAMV_EFC_FCMD_CLB    (0x9)\t/* (EFC) Clear Lock Bit */\n#define SAMV_EFC_FCMD_GLB    (0xA)\t/* (EFC) Get Lock Bit */\n#define SAMV_EFC_FCMD_SFB    (0xB)\t/* (EFC) Set Fuse Bit */\n#define SAMV_EFC_FCMD_CFB    (0xC)\t/* (EFC) Clear Fuse Bit */\n#define SAMV_EFC_FCMD_GFB    (0xD)\t/* (EFC) Get Fuse Bit */\n\n#define OFFSET_EFC_FMR    0\n#define OFFSET_EFC_FCR    4\n#define OFFSET_EFC_FSR    8\n#define OFFSET_EFC_FRR   12\n\n#define SAMV_CHIPID_CIDR       (0x400E0940)\n#define SAMV_NUM_GPNVM_BITS              9\n#define SAMV_CONTROLLER_ADDR   (0x400e0c00)\n#define SAMV_SECTOR_SIZE             16384\n#define SAMV_PAGE_SIZE                 512\n#define SAMV_FLASH_BASE         0x00400000\n\nstruct samv_flash_bank {\n\tbool      probed;\n\tunsigned size_bytes;\n\tunsigned gpnvm[SAMV_NUM_GPNVM_BITS];\n};\n\n/* The actual sector size of the SAMV7 flash memory is 128K bytes.\n * 16 sectors for a 2048KB device. The lock regions are 16KB per lock\n * region, with a 2048KB device having 128 lock regions.\n * For the best results, num_sectors is thus set to the number of lock\n * regions, and the sector_size set to the lock region size. Page\n * erases are used to erase 16KB sections when programming */\n\nstatic int samv_efc_get_status(struct target *target, uint32_t *v)\n{\n\tint r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FSR, v);\n\treturn r;\n}\n\nstatic int samv_efc_get_result(struct target *target, uint32_t *v)\n{\n\tuint32_t rv;\n\tint r = target_read_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FRR, &rv);\n\tif (v)\n\t\t*v = rv;\n\treturn r;\n}\n\nstatic int samv_efc_start_command(struct target *target,\n\t\tunsigned command, unsigned argument)\n{\n\tuint32_t v;\n\tsamv_efc_get_status(target, &v);\n\tif (!(v & 1)) {\n\t\tLOG_ERROR(\"flash controller is not ready\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tv = (0x5A << 24) | (argument << 8) | command;\n\tLOG_DEBUG(\"starting flash command: 0x%08x\", (unsigned int)(v));\n\tint r = target_write_u32(target, SAMV_CONTROLLER_ADDR + OFFSET_EFC_FCR, v);\n\tif (r != ERROR_OK)\n\t\tLOG_DEBUG(\"write failed\");\n\treturn r;\n}\n\nstatic int samv_efc_perform_command(struct target *target,\n\t\tunsigned command, unsigned argument, uint32_t *status)\n{\n\tint r;\n\tuint32_t v;\n\tint64_t ms_now, ms_end;\n\n\tif (status)\n\t\t*status = 0;\n\n\tr = samv_efc_start_command(target, command, argument);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tms_end = 10000 + timeval_ms();\n\n\tdo {\n\t\tr = samv_efc_get_status(target, &v);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tms_now = timeval_ms();\n\t\tif (ms_now > ms_end) {\n\t\t\t/* error */\n\t\t\tLOG_ERROR(\"Command timeout\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while ((v & 1) == 0);\n\n\t/* if requested, copy the flash controller error bits back to the caller */\n\tif (status)\n\t\t*status = (v & 0x6);\n\treturn ERROR_OK;\n}\n\nstatic int samv_erase_pages(struct target *target,\n\t\tint first_page, int num_pages, uint32_t *status)\n{\n\tuint8_t erase_pages;\n\tswitch (num_pages) {\n\t\tcase 4:\n\t\t\terase_pages = 0x00;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\terase_pages = 0x01;\n\t\t\tbreak;\n\t\tcase 16:\n\t\t\terase_pages = 0x02;\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\terase_pages = 0x03;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terase_pages = 0x00;\n\t\t\tbreak;\n\t}\n\n\t/* SAMV_EFC_FCMD_EPA\n\t * According to the datasheet FARG[15:2] defines the page from which\n\t * the erase will start.This page must be modulo 4, 8, 16 or 32\n\t * according to the number of pages to erase. FARG[1:0] defines the\n\t * number of pages to be erased. Previously (firstpage << 2) was used\n\t * to conform to this, seems it should not be shifted...\n\t */\n\treturn samv_efc_perform_command(target, SAMV_EFC_FCMD_EPA,\n\t\t\tfirst_page | erase_pages, status);\n}\n\nstatic int samv_get_gpnvm(struct target *target, unsigned gpnvm, unsigned *out)\n{\n\tuint32_t v;\n\tint r;\n\n\tif (gpnvm >= SAMV_NUM_GPNVM_BITS) {\n\t\tLOG_ERROR(\"invalid gpnvm %d, max: %d\", gpnvm, SAMV_NUM_GPNVM_BITS);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_GFB, 0, NULL);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"samv_get_gpnvm failed\");\n\t\treturn r;\n\t}\n\n\tr = samv_efc_get_result(target, &v);\n\n\tif (out)\n\t\t*out = (v >> gpnvm) & 1;\n\n\treturn r;\n}\n\nstatic int samv_clear_gpnvm(struct target *target, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\n\tif (gpnvm >= SAMV_NUM_GPNVM_BITS) {\n\t\tLOG_ERROR(\"invalid gpnvm %d, max: %d\", gpnvm, SAMV_NUM_GPNVM_BITS);\n\t\treturn ERROR_FAIL;\n\t}\n\tr = samv_get_gpnvm(target, gpnvm, &v);\n\tif (r != ERROR_OK) {\n\t\tLOG_DEBUG(\"get gpnvm failed: %d\", r);\n\t\treturn r;\n\t}\n\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_CFB, gpnvm, NULL);\n\tLOG_DEBUG(\"clear gpnvm result: %d\", r);\n\treturn r;\n}\n\nstatic int samv_set_gpnvm(struct target *target, unsigned gpnvm)\n{\n\tint r;\n\tunsigned v;\n\tif (gpnvm >= SAMV_NUM_GPNVM_BITS) {\n\t\tLOG_ERROR(\"invalid gpnvm %d, max: %d\", gpnvm, SAMV_NUM_GPNVM_BITS);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr = samv_get_gpnvm(target, gpnvm, &v);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\tif (v) {\n\t\tr = ERROR_OK; /* the gpnvm bit is already set */\n\t} else {\n\t\t/* we need to set it */\n\t\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_SFB, gpnvm, NULL);\n\t}\n\treturn r;\n}\n\nstatic int samv_flash_unlock(struct target *target,\n\t\tunsigned start_sector, unsigned end_sector)\n{\n\tint r;\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\n\t/* todo: look into this... i think this should be done on lock regions */\n\tpages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\t\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_CLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int samv_flash_lock(struct target *target,\n\t\tunsigned start_sector, unsigned end_sector)\n{\n\tuint32_t status;\n\tuint32_t pg;\n\tuint32_t pages_per_sector;\n\tint r;\n\n\t/* todo: look into this... i think this should be done on lock regions */\n\tpages_per_sector = SAMV_SECTOR_SIZE / SAMV_PAGE_SIZE;\n\twhile (start_sector <= end_sector) {\n\t\tpg = start_sector * pages_per_sector;\n\t\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_SLB, pg, &status);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tstart_sector++;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int samv_protect_check(struct flash_bank *bank)\n{\n\tint r;\n\tuint32_t v[4] = {0};\n\n\tr = samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_GLB, 0, NULL);\n\tif (r == ERROR_OK)\t{\n\t\tsamv_efc_get_result(bank->target, &v[0]);\n\t\tsamv_efc_get_result(bank->target, &v[1]);\n\t\tsamv_efc_get_result(bank->target, &v[2]);\n\t\tr = samv_efc_get_result(bank->target, &v[3]);\n\t}\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\tfor (unsigned int x = 0; x < bank->num_sectors; x++)\n\t\tbank->sectors[x].is_protected = (!!(v[x >> 5] & (1 << (x % 32))));\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(samv_flash_bank_command)\n{\n\tLOG_INFO(\"flash bank command\");\n\tstruct samv_flash_bank *samv_info;\n\tsamv_info = calloc(1, sizeof(struct samv_flash_bank));\n\tbank->driver_priv = samv_info;\n\treturn ERROR_OK;\n}\n\nstatic int samv_get_device_id(struct flash_bank *bank, uint32_t *device_id)\n{\n\treturn target_read_u32(bank->target, SAMV_CHIPID_CIDR, device_id);\n}\n\nstatic int samv_probe(struct flash_bank *bank)\n{\n\tuint32_t device_id;\n\tint r = samv_get_device_id(bank, &device_id);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\tLOG_INFO(\"device id = 0x%08\" PRIx32 \"\", device_id);\n\n\tuint8_t eproc = (device_id >> 5) & 0x7;\n\tif (eproc != 0) {\n\t\tLOG_ERROR(\"unexpected eproc code: %d was expecting 0 (Cortex-M7)\", eproc);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t nvm_size_code = (device_id >> 8) & 0xf;\n\tswitch (nvm_size_code) {\n\t\tcase 10:\n\t\t\tbank->size = 512 * 1024;\n\t\t\tbreak;\n\t\tcase 12:\n\t\t\tbank->size = 1024 * 1024;\n\t\t\tbreak;\n\t\tcase 14:\n\t\t\tbank->size = 2048 * 1024;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unrecognized flash size code: %d\", nvm_size_code);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct samv_flash_bank *samv_info = bank->driver_priv;\n\tsamv_info->size_bytes = bank->size;\n\tsamv_info->probed = true;\n\n\tbank->base = SAMV_FLASH_BASE;\n\tbank->num_sectors = bank->size / SAMV_SECTOR_SIZE;\n\tbank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));\n\tfor (unsigned int s = 0; s < bank->num_sectors; s++) {\n\t\tbank->sectors[s].size = SAMV_SECTOR_SIZE;\n\t\tbank->sectors[s].offset = s * SAMV_SECTOR_SIZE;\n\t\tbank->sectors[s].is_erased = -1;\n\t\tbank->sectors[s].is_protected = -1;\n\t}\n\n\tr = samv_protect_check(bank);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\treturn ERROR_OK;\n}\n\nstatic int samv_auto_probe(struct flash_bank *bank)\n{\n\tstruct samv_flash_bank *samv_info = bank->driver_priv;\n\tif (samv_info->probed)\n\t\treturn ERROR_OK;\n\treturn samv_probe(bank);\n}\n\nstatic int samv_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tconst int page_count = 32; /* 32 pages equals 16 KB lock region */\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint r = samv_auto_probe(bank);\n\tif (r != ERROR_OK)\n\t\treturn r;\n\n\t/* easy case: we've been requested to erase the entire flash */\n\tif ((first == 0) && ((last + 1) == bank->num_sectors))\n\t\treturn samv_efc_perform_command(bank->target, SAMV_EFC_FCMD_EA, 0, NULL);\n\n\tLOG_INFO(\"erasing lock regions %u-%u...\", first, last);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tuint32_t status;\n\t\tr = samv_erase_pages(bank->target, (i * page_count), page_count, &status);\n\t\tLOG_INFO(\"erasing lock region %u\", i);\n\t\tif (r != ERROR_OK)\n\t\t\tLOG_ERROR(\"error performing erase page @ lock region number %u\", i);\n\t\tif (status & (1 << 2)) {\n\t\t\tLOG_ERROR(\"lock region %u is locked\", i);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (status & (1 << 1)) {\n\t\t\tLOG_ERROR(\"flash command error @lock region %u\", i);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int samv_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint r;\n\tif (set)\n\t\tr = samv_flash_lock(bank->target, first, last);\n\telse\n\t\tr = samv_flash_unlock(bank->target, first, last);\n\n\treturn r;\n}\n\nstatic int samv_page_read(struct target *target,\n\t\tunsigned page_num, uint8_t *buf)\n{\n\tuint32_t addr = SAMV_FLASH_BASE + page_num * SAMV_PAGE_SIZE;\n\tint r = target_read_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"flash program failed to read page @ 0x%08x\",\n\t\t\t\t(unsigned int)(addr));\n\treturn r;\n}\n\nstatic int samv_page_write(struct target *target,\n\t\tunsigned pagenum, const uint8_t *buf)\n{\n\tuint32_t status;\n\tconst uint32_t addr = SAMV_FLASH_BASE + pagenum * SAMV_PAGE_SIZE;\n\tint r;\n\n\tLOG_DEBUG(\"write page %u at address 0x%08x\", pagenum, (unsigned int)addr);\n\tr = target_write_memory(target, addr, 4, SAMV_PAGE_SIZE / 4, buf);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"failed to buffer page at 0x%08x\", (unsigned int)addr);\n\t\treturn r;\n\t}\n\n\tr = samv_efc_perform_command(target, SAMV_EFC_FCMD_WP, pagenum, &status);\n\tif (r != ERROR_OK)\n\t\tLOG_ERROR(\"error performing write page at 0x%08x\", (unsigned int)addr);\n\tif (status & (1 << 2)) {\n\t\tLOG_ERROR(\"page at 0x%08x is locked\", (unsigned int)addr);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (status & (1 << 1)) {\n\t\tLOG_ERROR(\"flash command error at 0x%08x\", (unsigned int)addr);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int samv_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (count == 0)\n\t\treturn ERROR_OK;\n\n\tif ((offset + count) > bank->size) {\n\t\tLOG_ERROR(\"flash write error - past end of bank\");\n\t\tLOG_ERROR(\" offset: 0x%08x, count 0x%08x, bank end: 0x%08x\",\n\t\t\t\t(unsigned int)(offset),\n\t\t\t\t(unsigned int)(count),\n\t\t\t\t(unsigned int)(bank->size));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t pagebuffer[SAMV_PAGE_SIZE] = {0};\n\tuint32_t page_cur = offset / SAMV_PAGE_SIZE;\n\tuint32_t page_end = (offset + count - 1) / SAMV_PAGE_SIZE;\n\n\tLOG_DEBUG(\"offset: 0x%08x, count: 0x%08x\",\n\t\t\t(unsigned int)(offset), (unsigned int)(count));\n\tLOG_DEBUG(\"page start: %d, page end: %d\", (int)(page_cur), (int)(page_end));\n\n\t/* Special case: all one page */\n\t/* Otherwise:                 */\n\t/*    (1) non-aligned start   */\n\t/*    (2) body pages          */\n\t/*    (3) non-aligned end.    */\n\n\tint r;\n\tuint32_t page_offset;\n\n\t/* handle special case - all one page. */\n\tif (page_cur == page_end) {\n\t\tLOG_DEBUG(\"special case, all in one page\");\n\t\tr = samv_page_read(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\n\t\tpage_offset = offset & (SAMV_PAGE_SIZE-1);\n\t\tmemcpy(pagebuffer + page_offset, buffer, count);\n\n\t\tr = samv_page_write(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* step 1) handle the non-aligned starting address */\n\tpage_offset = offset & (SAMV_PAGE_SIZE - 1);\n\tif (page_offset) {\n\t\tLOG_DEBUG(\"non-aligned start\");\n\t\t/* read the partial page */\n\t\tr = samv_page_read(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\n\t\t/* over-write with new data */\n\t\tuint32_t n = SAMV_PAGE_SIZE - page_offset;\n\t\tmemcpy(pagebuffer + page_offset, buffer, n);\n\n\t\tr = samv_page_write(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\n\t\tcount  -= n;\n\t\toffset += n;\n\t\tbuffer += n;\n\t\tpage_cur++;\n\t}\n\n\t/* By checking that offset is correct here, we also fix a clang warning */\n\tassert(offset % SAMV_PAGE_SIZE == 0);\n\n\t/* step 2) handle the full pages */\n\tLOG_DEBUG(\"full page loop: cur=%d, end=%d, count = 0x%08x\",\n\t\t\t(int)page_cur, (int)page_end, (unsigned int)(count));\n\n\twhile ((page_cur < page_end) && (count >= SAMV_PAGE_SIZE)) {\n\t\tr = samv_page_write(bank->target, page_cur, buffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tcount -= SAMV_PAGE_SIZE;\n\t\tbuffer += SAMV_PAGE_SIZE;\n\t\tpage_cur += 1;\n\t}\n\n\t/* step 3) write final page, if it's partial (otherwise it's already done) */\n\tif (count) {\n\t\tLOG_DEBUG(\"final partial page, count = 0x%08x\", (unsigned int)(count));\n\t\t/* we have a partial page */\n\t\tr = samv_page_read(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t\tmemcpy(pagebuffer, buffer, count); /* data goes at start of page */\n\t\tr = samv_page_write(bank->target, page_cur, pagebuffer);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int samv_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct samv_flash_bank *samv_info = bank->driver_priv;\n\tif (!samv_info->probed) {\n\t\tint r = samv_probe(bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\tcommand_print_sameline(cmd, \"Cortex-M7 detected with %\" PRIu32 \" kB flash\\n\",\n\t\t\tbank->size / 1024);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(samv_handle_gpnvm_command)\n{\n\tstruct flash_bank *bank = get_flash_bank_by_num_noprobe(0);\n\tif (!bank)\n\t\treturn ERROR_FAIL;\n\tstruct samv_flash_bank *samv_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint r;\n\tif (!samv_info->probed) {\n\t\tr = samv_auto_probe(bank);\n\t\tif (r != ERROR_OK)\n\t\t\treturn r;\n\t}\n\n\tint who = 0;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tgoto showall;\n\t\tcase 1:\n\t\t\twho = -1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif (!strcmp(CMD_ARGV[0], \"show\") && !strcmp(CMD_ARGV[1], \"all\"))\n\t\t\t\twho = -1;\n\t\t\telse {\n\t\t\t\tuint32_t v32;\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], v32);\n\t\t\t\twho = v32;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tunsigned v = 0;\n\tif (!strcmp(\"show\", CMD_ARGV[0])) {\n\t\tif (who == -1) {\nshowall:\n\t\t\tr = ERROR_OK;\n\t\t\tfor (int x = 0; x < SAMV_NUM_GPNVM_BITS; x++) {\n\t\t\t\tr = samv_get_gpnvm(target, x, &v);\n\t\t\t\tif (r != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t\tcommand_print(CMD, \"samv-gpnvm%u: %u\", x, v);\n\t\t\t}\n\t\t\treturn r;\n\t\t}\n\t\tif ((who >= 0) && (((unsigned)who) < SAMV_NUM_GPNVM_BITS)) {\n\t\t\tr = samv_get_gpnvm(target, who, &v);\n\t\t\tif (r != ERROR_OK)\n\t\t\t\treturn r;\n\n\t\t\tcommand_print(CMD, \"samv-gpnvm%u: %u\", who, v);\n\t\t\treturn r;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"invalid gpnvm: %u\", who);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tif (who == -1) {\n\t\tcommand_print(CMD, \"missing gpnvm number\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (!strcmp(\"set\", CMD_ARGV[0]))\n\t\tr = samv_set_gpnvm(target, who);\n\telse if (!strcmp(\"clr\", CMD_ARGV[0]) || !strcmp(\"clear\", CMD_ARGV[0]))\n\t\tr = samv_clear_gpnvm(target, who);\n\telse {\n\t\tcommand_print(CMD, \"unknown command: %s\", CMD_ARGV[0]);\n\t\tr = ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn r;\n}\n\nstatic const struct command_registration atsamv_exec_command_handlers[] = {\n\t{\n\t\t.name = \"gpnvm\",\n\t\t.handler = samv_handle_gpnvm_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[('clr'|'set'|'show') bitnum]\",\n\t\t.help = \"Without arguments, shows all bits in the gpnvm \"\n\t\t\t\"register.  Otherwise, clears, sets, or shows one \"\n\t\t\t\"General Purpose Non-Volatile Memory (gpnvm) bit.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration atsamv_command_handlers[] = {\n\t{\n\t\t.name = \"atsamv\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"atsamv flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = atsamv_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver atsamv_flash = {\n\t.name = \"atsamv\",\n\t.commands = atsamv_command_handlers,\n\t.flash_bank_command = samv_flash_bank_command,\n\t.erase = samv_erase,\n\t.protect = samv_protect,\n\t.write = samv_write,\n\t.read = default_flash_read,\n\t.probe = samv_probe,\n\t.auto_probe = samv_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = samv_protect_check,\n\t.info = samv_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/avrf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian                                      *\n *   SimonQian@SimonQian.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/avrt.h>\n\n/* AVR_JTAG_Instructions */\n#define AVR_JTAG_INS_LEN                                        4\n/* Public Instructions: */\n#define AVR_JTAG_INS_EXTEST                                     0x00\n#define AVR_JTAG_INS_IDCODE                                     0x01\n#define AVR_JTAG_INS_SAMPLE_PRELOAD                             0x02\n#define AVR_JTAG_INS_BYPASS                                     0x0F\n/* AVR Specified Public Instructions: */\n#define AVR_JTAG_INS_AVR_RESET                                  0x0C\n#define AVR_JTAG_INS_PROG_ENABLE                                0x04\n#define AVR_JTAG_INS_PROG_COMMANDS                              0x05\n#define AVR_JTAG_INS_PROG_PAGELOAD                              0x06\n#define AVR_JTAG_INS_PROG_PAGEREAD                              0x07\n\n/* Data Registers: */\n#define AVR_JTAG_REG_BYPASS_LEN                                 1\n#define AVR_JTAG_REG_DEVICEID_LEN                               32\n\n#define AVR_JTAG_REG_RESET_LEN                                  1\n#define AVR_JTAG_REG_JTAGID_LEN                                 32\n#define AVR_JTAG_REG_PROGRAMMING_ENABLE_LEN                     16\n#define AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN                    15\n#define AVR_JTAG_REG_FLASH_DATA_BYTE_LEN                        16\n\nstruct avrf_type {\n\tchar name[15];\n\tuint16_t chip_id;\n\tint flash_page_size;\n\tint flash_page_num;\n\tint eeprom_page_size;\n\tint eeprom_page_num;\n};\n\nstruct avrf_flash_bank {\n\tint ppage_size;\n\tbool probed;\n};\n\nstatic const struct avrf_type avft_chips_info[] = {\n/*\tname, chip_id,\tflash_page_size, flash_page_num,\n *\t\t\teeprom_page_size, eeprom_page_num\n */\n\t{\"atmega128\", 0x9702, 256, 512, 8, 512},\n\t{\"atmega128rfa1\", 0xa701, 128, 512, 8, 512},\n\t{\"atmega256rfr2\", 0xa802, 256, 1024, 8, 1024},\n\t{\"at90can128\", 0x9781, 256, 512, 8, 512},\n\t{\"at90usb128\", 0x9782, 256, 512, 8, 512},\n\t{\"atmega164p\", 0x940a, 128, 128, 4, 128},\n\t{\"atmega324p\", 0x9508, 128, 256, 4, 256},\n\t{\"atmega324pa\", 0x9511, 128, 256, 4, 256},\n\t{\"atmega644p\", 0x960a, 256, 256, 8, 256},\n\t{\"atmega1284p\", 0x9705, 256, 512, 8, 512},\n\t{\"atmega32u4\", 0x9587, 128, 256, 4, 256},\n};\n\n/* avr program functions */\nstatic int avr_jtag_reset(struct avr_common *avr, uint32_t reset)\n{\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_AVR_RESET);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, reset, AVR_JTAG_REG_RESET_LEN);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_jtag_read_jtagid(struct avr_common *avr, uint32_t *id)\n{\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_IDCODE);\n\tavr_jtag_senddat(avr->jtag_info.tap, id, 0, AVR_JTAG_REG_JTAGID_LEN);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_jtagprg_enterprogmode(struct avr_common *avr)\n{\n\tavr_jtag_reset(avr, 1);\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0xA370, AVR_JTAG_REG_PROGRAMMING_ENABLE_LEN);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_jtagprg_leaveprogmode(struct avr_common *avr)\n{\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2300, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3300, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_ENABLE);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0, AVR_JTAG_REG_PROGRAMMING_ENABLE_LEN);\n\n\tavr_jtag_reset(avr, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_jtagprg_chiperase(struct avr_common *avr)\n{\n\tuint32_t poll_value;\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2380, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3180, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3380, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\tdo {\n\t\tpoll_value = 0;\n\t\tavr_jtag_senddat(avr->jtag_info.tap,\n\t\t\t&poll_value,\n\t\t\t0x3380,\n\t\t\tAVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\t\tif (mcu_execute_queue() != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tLOG_DEBUG(\"poll_value = 0x%04\" PRIx32 \"\", poll_value);\n\t} while (!(poll_value & 0x0200));\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_jtagprg_writeflashpage(struct avr_common *avr,\n\tconst bool ext_addressing,\n\tconst uint8_t *page_buf,\n\tuint32_t buf_size,\n\tuint32_t addr,\n\tuint32_t page_size)\n{\n\tuint32_t poll_value;\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x2310, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\t/* load extended high byte */\n\tif (ext_addressing)\n\t\tavr_jtag_senddat(avr->jtag_info.tap,\n\t\t\tNULL,\n\t\t\t0x0b00 | ((addr >> 17) & 0xFF),\n\t\t\tAVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\t/* load addr high byte */\n\tavr_jtag_senddat(avr->jtag_info.tap,\n\t\tNULL,\n\t\t0x0700 | ((addr >> 9) & 0xFF),\n\t\tAVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\t/* load addr low byte */\n\tavr_jtag_senddat(avr->jtag_info.tap,\n\t\tNULL,\n\t\t0x0300 | ((addr >> 1) & 0xFF),\n\t\tAVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_PAGELOAD);\n\n\tfor (uint32_t i = 0; i < page_size; i++) {\n\t\tif (i < buf_size)\n\t\t\tavr_jtag_senddat(avr->jtag_info.tap, NULL, page_buf[i], 8);\n\t\telse\n\t\t\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0xFF, 8);\n\t}\n\n\tavr_jtag_sendinstr(avr->jtag_info.tap, NULL, AVR_JTAG_INS_PROG_COMMANDS);\n\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3500, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\tavr_jtag_senddat(avr->jtag_info.tap, NULL, 0x3700, AVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\n\tdo {\n\t\tpoll_value = 0;\n\t\tavr_jtag_senddat(avr->jtag_info.tap,\n\t\t\t&poll_value,\n\t\t\t0x3700,\n\t\t\tAVR_JTAG_REG_PROGRAMMING_COMMAND_LEN);\n\t\tif (mcu_execute_queue() != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tLOG_DEBUG(\"poll_value = 0x%04\" PRIx32 \"\", poll_value);\n\t} while (!(poll_value & 0x0200));\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(avrf_flash_bank_command)\n{\n\tstruct avrf_flash_bank *avrf_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tavrf_info = malloc(sizeof(struct avrf_flash_bank));\n\tbank->driver_priv = avrf_info;\n\n\tavrf_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int avrf_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct avr_common *avr = target->arch_info;\n\tint status;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstatus = avr_jtagprg_enterprogmode(avr);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\tstatus = avr_jtagprg_chiperase(avr);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\treturn avr_jtagprg_leaveprogmode(avr);\n}\n\nstatic int avrf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct avr_common *avr = target->arch_info;\n\tuint32_t cur_size, cur_buffer_size, page_size;\n\tbool ext_addressing;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tpage_size = bank->sectors[0].size;\n\tif ((offset % page_size) != 0) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required %\" PRIu32 \"-byte alignment\",\n\t\t\toffset,\n\t\t\tpage_size);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tLOG_DEBUG(\"offset is 0x%08\" PRIx32 \"\", offset);\n\tLOG_DEBUG(\"count is %\" PRIu32 \"\", count);\n\n\tif (avr_jtagprg_enterprogmode(avr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (bank->size > 0x20000)\n\t\text_addressing = true;\n\telse\n\t\text_addressing = false;\n\n\tcur_size = 0;\n\twhile (count > 0) {\n\t\tif (count > page_size)\n\t\t\tcur_buffer_size = page_size;\n\t\telse\n\t\t\tcur_buffer_size = count;\n\t\tavr_jtagprg_writeflashpage(avr,\n\t\t\text_addressing,\n\t\t\tbuffer + cur_size,\n\t\t\tcur_buffer_size,\n\t\t\toffset + cur_size,\n\t\t\tpage_size);\n\t\tcount -= cur_buffer_size;\n\t\tcur_size += cur_buffer_size;\n\n\t\tkeep_alive();\n\t}\n\n\treturn avr_jtagprg_leaveprogmode(avr);\n}\n\n#define EXTRACT_MFG(X)  (((X) & 0xffe) >> 1)\n#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)\n#define EXTRACT_VER(X)  (((X) & 0xf0000000) >> 28)\n\nstatic int avrf_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct avrf_flash_bank *avrf_info = bank->driver_priv;\n\tstruct avr_common *avr = target->arch_info;\n\tconst struct avrf_type *avr_info = NULL;\n\tuint32_t device_id;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tavrf_info->probed = false;\n\n\tavr_jtag_read_jtagid(avr, &device_id);\n\tif (mcu_execute_queue() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tLOG_INFO(\"device id = 0x%08\" PRIx32 \"\", device_id);\n\tif (EXTRACT_MFG(device_id) != 0x1F)\n\t\tLOG_ERROR(\"0x%\" PRIx32 \" is invalid Manufacturer for avr, 0x%X is expected\",\n\t\t\tEXTRACT_MFG(device_id),\n\t\t\t0x1F);\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(avft_chips_info); i++) {\n\t\tif (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) {\n\t\t\tavr_info = &avft_chips_info[i];\n\t\t\tLOG_INFO(\"target device is %s\", avr_info->name);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (avr_info) {\n\t\tfree(bank->sectors);\n\n\t\t/* chip found */\n\t\tbank->base = 0x00000000;\n\t\tbank->size = (avr_info->flash_page_size * avr_info->flash_page_num);\n\t\tbank->num_sectors = avr_info->flash_page_num;\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * avr_info->flash_page_num);\n\n\t\tfor (int i = 0; i < avr_info->flash_page_num; i++) {\n\t\t\tbank->sectors[i].offset = i * avr_info->flash_page_size;\n\t\t\tbank->sectors[i].size = avr_info->flash_page_size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = -1;\n\t\t}\n\n\t\tavrf_info->probed = true;\n\t\treturn ERROR_OK;\n\t} else {\n\t\t/* chip not supported */\n\t\tLOG_ERROR(\"0x%\" PRIx32 \" is not support for avr\", EXTRACT_PART(device_id));\n\n\t\tavrf_info->probed = true;\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nstatic int avrf_auto_probe(struct flash_bank *bank)\n{\n\tstruct avrf_flash_bank *avrf_info = bank->driver_priv;\n\tif (avrf_info->probed)\n\t\treturn ERROR_OK;\n\treturn avrf_probe(bank);\n}\n\nstatic int avrf_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct target *target = bank->target;\n\tstruct avr_common *avr = target->arch_info;\n\tconst struct avrf_type *avr_info = NULL;\n\tuint32_t device_id;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tavr_jtag_read_jtagid(avr, &device_id);\n\tif (mcu_execute_queue() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tLOG_INFO(\"device id = 0x%08\" PRIx32 \"\", device_id);\n\tif (EXTRACT_MFG(device_id) != 0x1F)\n\t\tLOG_ERROR(\"0x%\" PRIx32 \" is invalid Manufacturer for avr, 0x%X is expected\",\n\t\t\tEXTRACT_MFG(device_id),\n\t\t\t0x1F);\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(avft_chips_info); i++) {\n\t\tif (avft_chips_info[i].chip_id == EXTRACT_PART(device_id)) {\n\t\t\tavr_info = &avft_chips_info[i];\n\t\t\tLOG_INFO(\"target device is %s\", avr_info->name);\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (avr_info) {\n\t\t/* chip found */\n\t\tcommand_print_sameline(cmd, \"%s - Rev: 0x%\" PRIx32 \"\", avr_info->name,\n\t\t\tEXTRACT_VER(device_id));\n\t\treturn ERROR_OK;\n\t} else {\n\t\t/* chip not supported */\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as a avr\\n\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n}\n\nstatic int avrf_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct avr_common *avr = target->arch_info;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((avr_jtagprg_enterprogmode(avr) != ERROR_OK)\n\t    || (avr_jtagprg_chiperase(avr) != ERROR_OK)\n\t    || (avr_jtagprg_leaveprogmode(avr) != ERROR_OK))\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(avrf_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (avrf_mass_erase(bank) == ERROR_OK)\n\t\tcommand_print(CMD, \"avr mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"avr mass erase failed\");\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration avrf_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = avrf_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"erase entire device\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration avrf_command_handlers[] = {\n\t{\n\t\t.name = \"avrf\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"AVR flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = avrf_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver avr_flash = {\n\t.name = \"avr\",\n\t.commands = avrf_command_handlers,\n\t.flash_bank_command = avrf_flash_bank_command,\n\t.erase = avrf_erase,\n\t.write = avrf_write,\n\t.read = default_flash_read,\n\t.probe = avrf_probe,\n\t.auto_probe = avrf_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = avrf_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/bluenrg-x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Michele Sardo                                   *\n *   msmttchr@gmail.com                                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/binarybuffer.h>\n#include \"helper/types.h\"\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n#include \"imp.h\"\n#include \"bluenrg-x.h\"\n\n#define BLUENRG2_JTAG_REG\t (flash_priv_data_2.jtag_idcode_reg)\n#define BLUENRGLP_JTAG_REG\t (flash_priv_data_lp.jtag_idcode_reg)\n\n#define DIE_ID_REG(bluenrgx_info)           (bluenrgx_info->flash_ptr->die_id_reg)\n#define JTAG_IDCODE_REG(bluenrgx_info)      (bluenrgx_info->flash_ptr->jtag_idcode_reg)\n#define FLASH_PAGE_SIZE(bluenrgx_info)      (bluenrgx_info->flash_ptr->flash_page_size)\n\n#define FLASH_SIZE_REG_MASK (0xFFFF)\n\nstruct flash_ctrl_priv_data {\n\tuint32_t die_id_reg;\n\tuint32_t jtag_idcode_reg;\n\tuint32_t flash_base;\n\tuint32_t flash_regs_base;\n\tuint32_t flash_page_size;\n\tuint32_t jtag_idcode;\n\tchar *part_name;\n};\n\nstatic const struct flash_ctrl_priv_data flash_priv_data_1 = {\n\t.die_id_reg = 0x4090001C,\n\t.jtag_idcode_reg = 0x40900028,\n\t.flash_base = 0x10040000,\n\t.flash_regs_base = 0x40100000,\n\t.flash_page_size = 2048,\n\t.jtag_idcode = 0x00000000,\n\t.part_name = \"BLUENRG-1\",\n};\n\nstatic const struct flash_ctrl_priv_data flash_priv_data_2 = {\n\t.die_id_reg = 0x4090001C,\n\t.jtag_idcode_reg = 0x40900028,\n\t.flash_base = 0x10040000,\n\t.flash_regs_base = 0x40100000,\n\t.flash_page_size = 2048,\n\t.jtag_idcode = 0x0200A041,\n\t.part_name = \"BLUENRG-2\",\n};\n\nstatic const struct flash_ctrl_priv_data flash_priv_data_lp = {\n\t.die_id_reg = 0x40000000,\n\t.jtag_idcode_reg = 0x40000004,\n\t.flash_base = 0x10040000,\n\t.flash_regs_base = 0x40001000,\n\t.flash_page_size = 2048,\n\t.jtag_idcode = 0x0201E041,\n\t.part_name = \"BLUENRG-LP\",\n};\n\nstatic const struct flash_ctrl_priv_data flash_priv_data_lps = {\n\t.die_id_reg = 0x40000000,\n\t.jtag_idcode_reg = 0x40000004,\n\t.flash_base = 0x10040000,\n\t.flash_regs_base = 0x40001000,\n\t.flash_page_size = 2048,\n\t.jtag_idcode = 0x02028041,\n\t.part_name = \"BLUENRG-LPS\",\n};\n\nstruct bluenrgx_flash_bank {\n\tbool probed;\n\tuint32_t die_id;\n\tconst struct flash_ctrl_priv_data *flash_ptr;\n};\n\nstatic const struct flash_ctrl_priv_data *flash_ctrl[] = {\n\t&flash_priv_data_1,\n\t&flash_priv_data_2,\n\t&flash_priv_data_lp,\n\t&flash_priv_data_lps};\n\n/* flash_bank bluenrg-x 0 0 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info;\n\t/* Create the bank structure */\n\tbluenrgx_info = calloc(1, sizeof(*bluenrgx_info));\n\n\t/* Check allocation */\n\tif (!bluenrgx_info) {\n\t\tLOG_ERROR(\"failed to allocate bank structure\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->write_start_alignment = 16;\n\tbank->write_end_alignment = 16;\n\n\tbank->driver_priv = bluenrgx_info;\n\n\tbluenrgx_info->probed = false;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nstatic inline uint32_t bluenrgx_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\treturn bluenrgx_info->flash_ptr->flash_regs_base + reg_offset;\n}\n\nstatic inline int bluenrgx_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)\n{\n\treturn target_read_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value);\n}\n\nstatic inline int bluenrgx_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)\n{\n\treturn target_write_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value);\n}\n\nstatic int bluenrgx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval = ERROR_OK;\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\tunsigned int num_sectors = (last - first + 1);\n\tconst bool mass_erase = (num_sectors == bank->num_sectors);\n\tstruct target *target = bank->target;\n\tuint32_t address, command;\n\n\t/* check preconditions */\n\tif (!bluenrgx_info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\t/* Disable blue module */\n\tif (target_write_u32(target, 0x200000c0, 0) != ERROR_OK) {\n\t\tLOG_ERROR(\"Blue disable failed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (mass_erase) {\n\t\tcommand = FLASH_CMD_MASSERASE;\n\t\taddress = bank->base;\n\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS,\n\t\t\t\t\t\t\t\t(address - bank->base) >> 2) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tfor (unsigned int i = 0; i < 100; i++) {\n\t\t\tuint32_t value;\n\t\t\tif (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) {\n\t\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (value & FLASH_INT_CMDDONE)\n\t\t\t\tbreak;\n\t\t\tif (i == 99) {\n\t\t\t\tLOG_ERROR(\"Mass erase command failed (timeout)\");\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t} else {\n\t\tcommand = FLASH_CMD_ERASE_PAGE;\n\t\tfor (unsigned int i = first; i <= last; i++) {\n\t\t\taddress = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info);\n\t\t\tLOG_DEBUG(\"address = %08\" PRIx32 \", index = %u\", address, i);\n\n\t\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS,\n\t\t\t\t\t\t\t\t\t(address - bank->base) >> 2) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tif (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tfor (unsigned int j = 0; j < 100; j++) {\n\t\t\t\tuint32_t value;\n\t\t\t\tif (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) {\n\t\t\t\t\tLOG_ERROR(\"Register write failed\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tif (value & FLASH_INT_CMDDONE)\n\t\t\t\t\tbreak;\n\t\t\t\tif (j == 99) {\n\t\t\t\t\tLOG_ERROR(\"Erase command failed (timeout)\");\n\t\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn retval;\n\n}\n\nstatic int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t  uint32_t offset, uint32_t count)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384 + 8;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *write_algorithm_stack;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct mem_param mem_params[1];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and\n\t * hints how to generate the data!\n\t */\n\tstatic const uint8_t bluenrgx_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc\"\n\t};\n\n\t/* check preconditions */\n\tif (!bluenrgx_info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif ((offset + count) > bank->size) {\n\t\tLOG_ERROR(\"Requested write past beyond of flash size: (offset+count) = %\" PRIu32 \", size=%\" PRIu32,\n\t\t\t  (offset + count),\n\t\t\t  bank->size);\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\t}\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (target_alloc_working_area(target, sizeof(bluenrgx_flash_write_code),\n\t\t\t\t\t  &write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\t\t\t sizeof(bluenrgx_flash_write_code),\n\t\t\t\t\t bluenrgx_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\tif (target_alloc_working_area(target, buffer_size, &source)) {\n\t\tLOG_WARNING(\"no large enough working area available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Stack area */\n\tif (target_alloc_working_area(target, 128,\n\t\t\t\t\t  &write_algorithm_stack) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no working area for target algorithm stack\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"sp\", 32, PARAM_OUT);\n\t/* Put the 4th parameter at the location in the stack frame of target write() function.\n\t * See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.lst\n\t * 34 ldr     r6, [sp, #80]\n\t *                     ^^^ offset\n\t */\n\tinit_mem_param(&mem_params[0], write_algorithm_stack->address + 80, 32, PARAM_OUT);\n\t/* Stack for target write algorithm - target write() function has\n\t * __attribute__((naked)) so it does not setup the new stack frame.\n\t * Therefore the stack frame uses the area from SP upwards!\n\t * Interrupts are disabled and no subroutines are called from write()\n\t * so no need to allocate stack below SP.\n\t * TODO: remove __attribute__((naked)) and use similar parameter passing as stm32l4x */\n\tbuf_set_u32(reg_params[4].value, 0, 32, write_algorithm_stack->address);\n\n\t/* FIFO start address (first two words used for write and read pointers) */\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t/* FIFO end address (first two words used for write and read pointers) */\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\t/* Flash memory address */\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\t/* Number of bytes */\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\t/* Flash register base address */\n\tbuf_set_u32(mem_params[0].value, 0, 32, bluenrgx_info->flash_ptr->flash_regs_base);\n\n\tLOG_DEBUG(\"source->address = \" TARGET_ADDR_FMT, source->address);\n\tLOG_DEBUG(\"source->address+ source->size = \" TARGET_ADDR_FMT, source->address+source->size);\n\tLOG_DEBUG(\"write_algorithm_stack->address = \" TARGET_ADDR_FMT, write_algorithm_stack->address);\n\tLOG_DEBUG(\"address = %08\" PRIx32, address);\n\tLOG_DEBUG(\"count = %08\" PRIx32, count);\n\n\tretval = target_run_flash_async_algorithm(target,\n\t\t\t\t\t\t  buffer,\n\t\t\t\t\t\t  count/16,\n\t\t\t\t\t\t  16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */\n\t\t\t\t\t\t  1,\n\t\t\t\t\t\t  mem_params,\n\t\t\t\t\t\t  5,\n\t\t\t\t\t\t  reg_params,\n\t\t\t\t\t\t  source->address,\n\t\t\t\t\t\t  source->size,\n\t\t\t\t\t\t  write_algorithm->address,\n\t\t\t\t\t\t  0,\n\t\t\t\t\t\t  &armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"error executing bluenrg-x flash write algorithm\");\n\n\t\tuint32_t error = buf_get_u32(reg_params[0].value, 0, 32);\n\n\t\tif (error != 0)\n\t\t\tLOG_ERROR(\"flash write failed = %08\" PRIx32, error);\n\t}\n\tif (retval == ERROR_OK) {\n\t\tuint32_t rp;\n\t\t/* Read back rp and check that is valid */\n\t\tretval = target_read_u32(target, source->address+4, &rp);\n\t\tif (retval == ERROR_OK) {\n\t\t\tif ((rp < source->address+8) || (rp > (source->address + source->size))) {\n\t\t\t\tLOG_ERROR(\"flash write failed = %08\" PRIx32, rp);\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\t}\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\ttarget_free_working_area(target, write_algorithm_stack);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_mem_param(&mem_params[0]);\n\n\treturn retval;\n}\n\nstatic int bluenrgx_probe(struct flash_bank *bank)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\tuint32_t idcode, size_info, die_id;\n\tint retval = target_read_u32(bank->target, BLUENRGLP_JTAG_REG, &idcode);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((idcode != flash_priv_data_lp.jtag_idcode) && (idcode != flash_priv_data_lps.jtag_idcode)) {\n\t\tretval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Default device is BlueNRG-1 */\n\tbluenrgx_info->flash_ptr = &flash_priv_data_1;\n\tbank->base = flash_priv_data_1.flash_base;\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(flash_ctrl); i++) {\n\t\tif (idcode == (*flash_ctrl[i]).jtag_idcode) {\n\t\t\tbluenrgx_info->flash_ptr = flash_ctrl[i];\n\t\t\tbank->base = (*flash_ctrl[i]).flash_base;\n\t\t\tbreak;\n\t\t}\n\t}\n\tretval = bluenrgx_read_flash_reg(bank, FLASH_SIZE_REG, &size_info);\n\tsize_info = size_info & FLASH_SIZE_REG_MASK;\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(bank->target, DIE_ID_REG(bluenrgx_info), &die_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tbank->size = (size_info + 1) * FLASH_WORD_LEN;\n\tbank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info);\n\tbank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * FLASH_PAGE_SIZE(bluenrgx_info);\n\t\tbank->sectors[i].size = FLASH_PAGE_SIZE(bluenrgx_info);\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\tbluenrgx_info->probed = true;\n\tbluenrgx_info->die_id = die_id;\n\n\treturn ERROR_OK;\n}\n\nstatic int bluenrgx_auto_probe(struct flash_bank *bank)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\n\tif (bluenrgx_info->probed)\n\t\treturn ERROR_OK;\n\n\treturn bluenrgx_probe(bank);\n}\n\n/* This method must return a string displaying information about the bank */\nstatic int bluenrgx_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;\n\tint mask_number, cut_number;\n\n\tif (!bluenrgx_info->probed) {\n\t\tint retval = bluenrgx_probe(bank);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print_sameline(cmd, \"Unable to find bank information.\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tmask_number = (bluenrgx_info->die_id >> 4) & 0xF;\n\tcut_number = bluenrgx_info->die_id & 0xF;\n\n\tcommand_print_sameline(cmd, \"%s - Rev: %d.%d\",\n\t\t\tbluenrgx_info->flash_ptr->part_name, mask_number, cut_number);\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver bluenrgx_flash = {\n\t.name = \"bluenrg-x\",\n\t.flash_bank_command = bluenrgx_flash_bank_command,\n\t.erase = bluenrgx_erase,\n\t.protect = NULL,\n\t.write = bluenrgx_write,\n\t.read = default_flash_read,\n\t.probe = bluenrgx_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = NULL,\n\t.auto_probe = bluenrgx_auto_probe,\n\t.info = bluenrgx_get_info,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/bluenrg-x.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by STMicroelectronics.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_BLUENRGX_H\n#define OPENOCD_FLASH_NOR_BLUENRGX_H\n\n/* Flash Controller registers offsets */\n#define FLASH_REG_COMMAND 0x00\n#define FLASH_REG_CONFIG  0x04\n#define FLASH_REG_IRQSTAT 0x08\n#define FLASH_REG_IRQMASK 0x0C\n#define FLASH_REG_IRQRAW  0x10\n#define FLASH_REG_ADDRESS 0x18\n#define FLASH_REG_UNLOCKM 0x1C\n#define FLASH_REG_UNLOCKL 0x20\n#define FLASH_REG_DATA0   0x40\n#define FLASH_REG_DATA1   0x44\n#define FLASH_REG_DATA2   0x48\n#define FLASH_REG_DATA3   0x4C\n#define FLASH_SIZE_REG    0x14\n\n/* Flash Controller commands */\n#define FLASH_CMD_ERASE_PAGE 0x11\n#define FLASH_CMD_MASSERASE  0x22\n#define FLASH_CMD_WRITE      0x33\n#define FLASH_CMD_BURSTWRITE 0xCC\n#define FLASH_INT_CMDDONE    0x01\n\n#define FLASH_WORD_LEN       4\n\n#endif /* OPENOCD_FLASH_NOR_BLUENRGX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cc26xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"cc26xx.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/image.h>\n\n#define FLASH_TIMEOUT 8000\n\nstruct cc26xx_bank {\n\tconst char *family_name;\n\tuint32_t icepick_id;\n\tuint32_t user_id;\n\tuint32_t device_type;\n\tuint32_t sector_length;\n\tbool probed;\n\tstruct working_area *working_area;\n\tstruct armv7m_algorithm armv7m_info;\n\tconst uint8_t *algo_code;\n\tuint32_t algo_size;\n\tuint32_t algo_working_size;\n\tuint32_t buffer_addr[2];\n\tuint32_t params_addr[2];\n};\n\n/* Flash helper algorithm for CC26x0 Chameleon targets */\nstatic const uint8_t cc26x0_algo[] = {\n#include \"../../../contrib/loaders/flash/cc26xx/cc26x0_algo.inc\"\n};\n\n/* Flash helper algorithm for CC26x2 Agama targets */\nstatic const uint8_t cc26x2_algo[] = {\n#include \"../../../contrib/loaders/flash/cc26xx/cc26x2_algo.inc\"\n};\n\nstatic int cc26xx_auto_probe(struct flash_bank *bank);\n\nstatic uint32_t cc26xx_device_type(uint32_t icepick_id, uint32_t user_id)\n{\n\tuint32_t device_type = 0;\n\n\tswitch (icepick_id & ICEPICK_ID_MASK) {\n\t\tcase CC26X0_ICEPICK_ID:\n\t\t\tdevice_type = CC26X0_TYPE;\n\t\t\tbreak;\n\t\tcase CC26X1_ICEPICK_ID:\n\t\t\tdevice_type = CC26X1_TYPE;\n\t\t\tbreak;\n\t\tcase CC13X0_ICEPICK_ID:\n\t\t\tdevice_type = CC13X0_TYPE;\n\t\t\tbreak;\n\t\tcase CC13X2_CC26X2_ICEPICK_ID:\n\t\tdefault:\n\t\t\tif ((user_id & USER_ID_CC13_MASK) != 0)\n\t\t\t\tdevice_type = CC13X2_TYPE;\n\t\t\telse\n\t\t\t\tdevice_type = CC26X2_TYPE;\n\t\t\tbreak;\n\t}\n\n\treturn device_type;\n}\n\nstatic uint32_t cc26xx_sector_length(uint32_t icepick_id)\n{\n\tuint32_t sector_length;\n\n\tswitch (icepick_id & ICEPICK_ID_MASK) {\n\t\tcase CC26X0_ICEPICK_ID:\n\t\tcase CC26X1_ICEPICK_ID:\n\t\tcase CC13X0_ICEPICK_ID:\n\t\t\t/* Chameleon family device */\n\t\t\tsector_length = CC26X0_SECTOR_LENGTH;\n\t\t\tbreak;\n\t\tcase CC13X2_CC26X2_ICEPICK_ID:\n\t\tdefault:\n\t\t\t/* Agama family device */\n\t\t\tsector_length = CC26X2_SECTOR_LENGTH;\n\t\t\tbreak;\n\t}\n\n\treturn sector_length;\n}\n\nstatic int cc26xx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\n\tuint32_t status_addr = params_addr + CC26XX_STATUS_OFFSET;\n\tuint32_t status = CC26XX_BUFFER_FULL;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\n\tint retval = ERROR_OK;\n\n\tstart_ms = timeval_ms();\n\twhile (status == CC26XX_BUFFER_FULL) {\n\t\tretval = target_read_u32(target, status_addr, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\telapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > 500)\n\t\t\tkeep_alive();\n\t\tif (elapsed_ms > FLASH_TIMEOUT)\n\t\t\tbreak;\n\t};\n\n\tif (status != CC26XX_BUFFER_EMPTY) {\n\t\tLOG_ERROR(\"%s: Flash operation failed\", cc26xx_bank->family_name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cc26xx_init(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\n\tint retval;\n\n\t/* Make sure we've probed the flash to get the device and size */\n\tretval = cc26xx_auto_probe(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check for working area to use for flash helper algorithm */\n\ttarget_free_working_area(target, cc26xx_bank->working_area);\n\tcc26xx_bank->working_area = NULL;\n\n\tretval = target_alloc_working_area(target, cc26xx_bank->algo_working_size,\n\t\t\t\t&cc26xx_bank->working_area);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Confirm the defined working address is the area we need to use */\n\tif (cc26xx_bank->working_area->address != CC26XX_ALGO_BASE_ADDRESS)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* Write flash helper algorithm into target memory */\n\tretval = target_write_buffer(target, CC26XX_ALGO_BASE_ADDRESS,\n\t\t\t\tcc26xx_bank->algo_size, cc26xx_bank->algo_code);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to load flash helper algorithm\",\n\t\t\tcc26xx_bank->family_name);\n\t\ttarget_free_working_area(target, cc26xx_bank->working_area);\n\t\tcc26xx_bank->working_area = NULL;\n\t\treturn retval;\n\t}\n\n\t/* Initialize the ARMv7 specific info to run the algorithm */\n\tcc26xx_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tcc26xx_bank->armv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* Begin executing the flash helper algorithm */\n\tretval = target_start_algorithm(target, 0, NULL, 0, NULL,\n\t\t\t\tCC26XX_ALGO_BASE_ADDRESS, 0, &cc26xx_bank->armv7m_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to start flash helper algorithm\",\n\t\t\tcc26xx_bank->family_name);\n\t\ttarget_free_working_area(target, cc26xx_bank->working_area);\n\t\tcc26xx_bank->working_area = NULL;\n\t\treturn retval;\n\t}\n\n\t/*\n\t * At this point, the algorithm is running on the target and\n\t * ready to receive commands and data to flash the target\n\t */\n\n\treturn retval;\n}\n\nstatic int cc26xx_quit(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\n\tint retval;\n\n\t/* Regardless of the algo's status, attempt to halt the target */\n\t(void)target_halt(target);\n\n\t/* Now confirm target halted and clean up from flash helper algorithm */\n\tretval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,\n\t\t\t\t&cc26xx_bank->armv7m_info);\n\n\ttarget_free_working_area(target, cc26xx_bank->working_area);\n\tcc26xx_bank->working_area = NULL;\n\n\treturn retval;\n}\n\nstatic int cc26xx_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\tstruct cc26xx_algo_params algo_params;\n\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = cc26xx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters */\n\tbuf_set_u32(algo_params.address, 0, 32, 0);\n\tbuf_set_u32(algo_params.length,  0, 32, 4);\n\tbuf_set_u32(algo_params.command, 0, 32, CC26XX_CMD_ERASE_ALL);\n\tbuf_set_u32(algo_params.status,  0, 32, CC26XX_BUFFER_FULL);\n\n\t/* Issue flash helper algorithm parameters for mass erase */\n\tretval = target_write_buffer(target, cc26xx_bank->params_addr[0],\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\n\t/* Wait for command to complete */\n\tif (retval == ERROR_OK)\n\t\tretval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[0]);\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)cc26xx_quit(bank);\n\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(cc26xx_flash_bank_command)\n{\n\tstruct cc26xx_bank *cc26xx_bank;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcc26xx_bank = malloc(sizeof(struct cc26xx_bank));\n\tif (!cc26xx_bank)\n\t\treturn ERROR_FAIL;\n\n\t/* Initialize private flash information */\n\tmemset((void *)cc26xx_bank, 0x00, sizeof(struct cc26xx_bank));\n\tcc26xx_bank->family_name = \"cc26xx\";\n\tcc26xx_bank->device_type = CC26XX_NO_TYPE;\n\tcc26xx_bank->sector_length = 0x1000;\n\n\t/* Finish initialization of bank */\n\tbank->driver_priv = cc26xx_bank;\n\tbank->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nstatic int cc26xx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\tstruct cc26xx_algo_params algo_params;\n\n\tuint32_t address;\n\tuint32_t length;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Do a mass erase if user requested all sectors of flash */\n\tif ((first == 0) && (last == (bank->num_sectors - 1))) {\n\t\t/* Request mass erase of flash */\n\t\treturn cc26xx_mass_erase(bank);\n\t}\n\n\taddress = first * cc26xx_bank->sector_length;\n\tlength = (last - first + 1) * cc26xx_bank->sector_length;\n\n\tretval = cc26xx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set up algorithm parameters for erase command */\n\tbuf_set_u32(algo_params.address, 0, 32, address);\n\tbuf_set_u32(algo_params.length,  0, 32, length);\n\tbuf_set_u32(algo_params.command, 0, 32, CC26XX_CMD_ERASE_SECTORS);\n\tbuf_set_u32(algo_params.status,  0, 32, CC26XX_BUFFER_FULL);\n\n\t/* Issue flash helper algorithm parameters for erase */\n\tretval = target_write_buffer(target, cc26xx_bank->params_addr[0],\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\n\t/* If no error, wait for erase to finish */\n\tif (retval == ERROR_OK)\n\t\tretval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[0]);\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)cc26xx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int cc26xx_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\tstruct cc26xx_algo_params algo_params[2];\n\tuint32_t size = 0;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\tuint32_t address;\n\n\tuint32_t index;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = cc26xx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters to default values */\n\tbuf_set_u32(algo_params[0].command, 0, 32, CC26XX_CMD_PROGRAM);\n\tbuf_set_u32(algo_params[1].command, 0, 32, CC26XX_CMD_PROGRAM);\n\n\t/* Write requested data, ping-ponging between two buffers */\n\tindex = 0;\n\tstart_ms = timeval_ms();\n\taddress = bank->base + offset;\n\twhile (count > 0) {\n\n\t\tif (count > cc26xx_bank->sector_length)\n\t\t\tsize = cc26xx_bank->sector_length;\n\t\telse\n\t\t\tsize = count;\n\n\t\t/* Put next block of data to flash into buffer */\n\t\tretval = target_write_buffer(target, cc26xx_bank->buffer_addr[index],\n\t\t\t\t\tsize, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write data to target memory\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Update algo parameters for next block */\n\t\tbuf_set_u32(algo_params[index].address, 0, 32, address);\n\t\tbuf_set_u32(algo_params[index].length,  0, 32, size);\n\t\tbuf_set_u32(algo_params[index].status,  0, 32, CC26XX_BUFFER_FULL);\n\n\t\t/* Issue flash helper algorithm parameters for block write */\n\t\tretval = target_write_buffer(target, cc26xx_bank->params_addr[index],\n\t\t\t\t\tsizeof(algo_params[index]), (uint8_t *)&algo_params[index]);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Wait for next ping pong buffer to be ready */\n\t\tindex ^= 1;\n\t\tretval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[index]);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tcount -= size;\n\t\tbuffer += size;\n\t\taddress += size;\n\n\t\telapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > 500)\n\t\t\tkeep_alive();\n\t}\n\n\t/* If no error yet, wait for last buffer to finish */\n\tif (retval == ERROR_OK) {\n\t\tindex ^= 1;\n\t\tretval = cc26xx_wait_algo_done(bank, cc26xx_bank->params_addr[index]);\n\t}\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)cc26xx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int cc26xx_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\n\tuint32_t sector_length;\n\tuint32_t value;\n\tint num_sectors;\n\tint max_sectors;\n\n\tint retval;\n\n\tretval = target_read_u32(target, FCFG1_ICEPICK_ID, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcc26xx_bank->icepick_id = value;\n\n\tretval = target_read_u32(target, FCFG1_USER_ID, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcc26xx_bank->user_id = value;\n\n\tcc26xx_bank->device_type = cc26xx_device_type(cc26xx_bank->icepick_id,\n\t\tcc26xx_bank->user_id);\n\n\tsector_length = cc26xx_sector_length(cc26xx_bank->icepick_id);\n\n\t/* Set up appropriate flash helper algorithm */\n\tswitch (cc26xx_bank->icepick_id & ICEPICK_ID_MASK) {\n\t\tcase CC26X0_ICEPICK_ID:\n\t\tcase CC26X1_ICEPICK_ID:\n\t\tcase CC13X0_ICEPICK_ID:\n\t\t\t/* Chameleon family device */\n\t\t\tcc26xx_bank->algo_code = cc26x0_algo;\n\t\t\tcc26xx_bank->algo_size = sizeof(cc26x0_algo);\n\t\t\tcc26xx_bank->algo_working_size = CC26X0_WORKING_SIZE;\n\t\t\tcc26xx_bank->buffer_addr[0] = CC26X0_ALGO_BUFFER_0;\n\t\t\tcc26xx_bank->buffer_addr[1] = CC26X0_ALGO_BUFFER_1;\n\t\t\tcc26xx_bank->params_addr[0] = CC26X0_ALGO_PARAMS_0;\n\t\t\tcc26xx_bank->params_addr[1] = CC26X0_ALGO_PARAMS_1;\n\t\t\tmax_sectors = CC26X0_MAX_SECTORS;\n\t\t\tbreak;\n\t\tcase CC13X2_CC26X2_ICEPICK_ID:\n\t\tdefault:\n\t\t\t/* Agama family device */\n\t\t\tcc26xx_bank->algo_code = cc26x2_algo;\n\t\t\tcc26xx_bank->algo_size = sizeof(cc26x2_algo);\n\t\t\tcc26xx_bank->algo_working_size = CC26X2_WORKING_SIZE;\n\t\t\tcc26xx_bank->buffer_addr[0] = CC26X2_ALGO_BUFFER_0;\n\t\t\tcc26xx_bank->buffer_addr[1] = CC26X2_ALGO_BUFFER_1;\n\t\t\tcc26xx_bank->params_addr[0] = CC26X2_ALGO_PARAMS_0;\n\t\t\tcc26xx_bank->params_addr[1] = CC26X2_ALGO_PARAMS_1;\n\t\t\tmax_sectors = CC26X2_MAX_SECTORS;\n\t\t\tbreak;\n\t}\n\n\tretval = target_read_u32(target, CC26XX_FLASH_SIZE_INFO, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tnum_sectors = value & 0xff;\n\tif (num_sectors > max_sectors)\n\t\tnum_sectors = max_sectors;\n\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tbank->base = CC26XX_FLASH_BASE_ADDR;\n\tbank->num_sectors = num_sectors;\n\tbank->size = num_sectors * sector_length;\n\tbank->write_start_alignment = 0;\n\tbank->write_end_alignment = 0;\n\tcc26xx_bank->sector_length = sector_length;\n\n\tfor (int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * sector_length;\n\t\tbank->sectors[i].size = sector_length;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\t/* We've successfully determined the stats on the flash bank */\n\tcc26xx_bank->probed = true;\n\n\t/* If we fall through to here, then all went well */\n\n\treturn ERROR_OK;\n}\n\nstatic int cc26xx_auto_probe(struct flash_bank *bank)\n{\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\n\tint retval = ERROR_OK;\n\n\tif (!cc26xx_bank->probed)\n\t\tretval = cc26xx_probe(bank);\n\n\treturn retval;\n}\n\nstatic int cc26xx_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct cc26xx_bank *cc26xx_bank = bank->driver_priv;\n\tconst char *device;\n\n\tswitch (cc26xx_bank->device_type) {\n\t\tcase CC26X0_TYPE:\n\t\t\tdevice = \"CC26x0\";\n\t\t\tbreak;\n\t\tcase CC26X1_TYPE:\n\t\t\tdevice = \"CC26x1\";\n\t\t\tbreak;\n\t\tcase CC13X0_TYPE:\n\t\t\tdevice = \"CC13x0\";\n\t\t\tbreak;\n\t\tcase CC13X2_TYPE:\n\t\t\tdevice = \"CC13x2\";\n\t\t\tbreak;\n\t\tcase CC26X2_TYPE:\n\t\t\tdevice = \"CC26x2\";\n\t\t\tbreak;\n\t\tcase CC26XX_NO_TYPE:\n\t\tdefault:\n\t\t\tdevice = \"Unrecognized\";\n\t\t\tbreak;\n\t}\n\n\tcommand_print_sameline(cmd,\n\t\t\"%s device: ICEPick ID 0x%08\" PRIx32 \", USER ID 0x%08\" PRIx32 \"\\n\",\n\t\tdevice, cc26xx_bank->icepick_id, cc26xx_bank->user_id);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver cc26xx_flash = {\n\t.name = \"cc26xx\",\n\t.flash_bank_command = cc26xx_flash_bank_command,\n\t.erase = cc26xx_erase,\n\t.write = cc26xx_write,\n\t.read = default_flash_read,\n\t.probe = cc26xx_probe,\n\t.auto_probe = cc26xx_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = cc26xx_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cc26xx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_CC26XX_H\n#define OPENOCD_FLASH_NOR_CC26XX_H\n\n/* Addresses of FCFG1 registers to access ICEPick Device ID and User ID */\n#define FCFG1_ICEPICK_ID 0x50001318\n#define FCFG1_USER_ID    0x50001294\n\n/* ICEPick device ID mask and values */\n#define ICEPICK_ID_MASK          0x0fffffff\n#define ICEPICK_REV_MASK         0xf0000000\n#define CC26X0_ICEPICK_ID        0x0b99a02f\n#define CC26X1_ICEPICK_ID        0x0b9bd02f\n#define CC13X0_ICEPICK_ID        0x0b9be02f\n#define CC13X2_CC26X2_ICEPICK_ID 0x0bb4102f\n\n/* User ID mask for Agama CC13x2 vs CC26x2 */\n#define USER_ID_CC13_MASK 0x00800000\n\n/* Common CC26xx/CC13xx flash and memory parameters */\n#define CC26XX_FLASH_BASE_ADDR   0x00000000\n#define CC26XX_FLASH_SIZE_INFO   0x4003002c\n#define CC26XX_SRAM_SIZE_INFO    0x40082250\n#define CC26XX_ALGO_BASE_ADDRESS 0x20000000\n\n/* Chameleon CC26x0/CC13x0 specific parameters */\n#define CC26X0_MAX_SECTORS   32\n#define CC26X0_SECTOR_LENGTH 0x1000\n#define CC26X0_ALGO_BUFFER_0 0x20001c00\n#define CC26X0_ALGO_BUFFER_1 0x20002c00\n#define CC26X0_ALGO_PARAMS_0 0x20001bd8\n#define CC26X0_ALGO_PARAMS_1 0x20001bec\n#define CC26X0_WORKING_SIZE  (CC26X0_ALGO_BUFFER_1 + CC26X0_SECTOR_LENGTH - \\\n\t\t\t\t\t\t\t CC26XX_ALGO_BASE_ADDRESS)\n\n/* Agama CC26x2/CC13x2 specific parameters */\n#define CC26X2_MAX_SECTORS   128\n#define CC26X2_SECTOR_LENGTH 0x2000\n#define CC26X2_ALGO_BUFFER_0 0x20002000\n#define CC26X2_ALGO_BUFFER_1 0x20004000\n#define CC26X2_ALGO_PARAMS_0 0x20001fd8\n#define CC26X2_ALGO_PARAMS_1 0x20001fec\n#define CC26X2_WORKING_SIZE  (CC26X2_ALGO_BUFFER_1 + CC26X2_SECTOR_LENGTH - \\\n\t\t\t\t\t\t\t CC26XX_ALGO_BASE_ADDRESS)\n\n/* CC26xx flash helper algorithm buffer flags */\n#define CC26XX_BUFFER_EMPTY 0x00000000\n#define CC26XX_BUFFER_FULL  0xffffffff\n\n/* CC26XX flash helper algorithm commands */\n#define CC26XX_CMD_NO_ACTION                     0\n#define CC26XX_CMD_ERASE_ALL                     1\n#define CC26XX_CMD_PROGRAM                       2\n#define CC26XX_CMD_ERASE_AND_PROGRAM             3\n#define CC26XX_CMD_ERASE_AND_PROGRAM_WITH_RETAIN 4\n#define CC26XX_CMD_ERASE_SECTORS                 5\n\n/* CC26xx and CC13xx device types */\n#define CC26XX_NO_TYPE 0 /* Device type not determined yet */\n#define CC26X0_TYPE    1 /* CC26x0 Chameleon device */\n#define CC26X1_TYPE    2 /* CC26x1 Chameleon device */\n#define CC26X2_TYPE    3 /* CC26x2 Agama device */\n#define CC13X0_TYPE    4 /* CC13x0 Chameleon device */\n#define CC13X2_TYPE    5 /* CC13x2 Agama device */\n\n/* Flash helper algorithm parameter block struct */\n#define CC26XX_STATUS_OFFSET 0x0c\nstruct cc26xx_algo_params {\n\tuint8_t address[4];\n\tuint8_t length[4];\n\tuint8_t command[4];\n\tuint8_t status[4];\n};\n\n#endif /* OPENOCD_FLASH_NOR_CC26XX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cc3220sf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"cc3220sf.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define FLASH_TIMEOUT 5000\n\nstruct cc3220sf_bank {\n\tbool probed;\n\tstruct armv7m_algorithm armv7m_info;\n};\n\n/* Flash helper algorithm for CC3220SF */\nstatic const uint8_t cc3220sf_algo[] = {\n#include \"../../../contrib/loaders/flash/cc3220sf/cc3220sf.inc\"\n};\n\nstatic int cc3220sf_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tbool done;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\tuint32_t value;\n\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Set starting address to erase to zero */\n\tretval = target_write_u32(target, FMA_REGISTER_ADDR, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write the MERASE bit of the FMC register */\n\tretval = target_write_u32(target, FMC_REGISTER_ADDR, FMC_MERASE_VALUE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Poll the MERASE bit until the mass erase is complete */\n\tdone = false;\n\tstart_ms = timeval_ms();\n\twhile (!done) {\n\t\tretval = target_read_u32(target, FMC_REGISTER_ADDR, &value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((value & FMC_MERASE_BIT) == 0) {\n\t\t\t/* Bit clears when mass erase is finished */\n\t\t\tdone = true;\n\t\t} else {\n\t\t\telapsed_ms = timeval_ms() - start_ms;\n\t\t\tif (elapsed_ms > 500)\n\t\t\t\tkeep_alive();\n\t\t\tif (elapsed_ms > FLASH_TIMEOUT)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!done) {\n\t\t/* Mass erase timed out waiting for confirmation */\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(cc3220sf_flash_bank_command)\n{\n\tstruct cc3220sf_bank *cc3220sf_bank;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcc3220sf_bank = malloc(sizeof(struct cc3220sf_bank));\n\tif (!cc3220sf_bank)\n\t\treturn ERROR_FAIL;\n\n\t/* Initialize private flash information */\n\tcc3220sf_bank->probed = false;\n\n\t/* Finish initialization of flash bank */\n\tbank->driver_priv = cc3220sf_bank;\n\tbank->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nstatic int cc3220sf_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tbool done;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\tuint32_t address;\n\tuint32_t value;\n\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Do a mass erase if user requested all sectors of flash */\n\tif ((first == 0) && (last == (bank->num_sectors - 1))) {\n\t\t/* Request mass erase of flash */\n\t\treturn cc3220sf_mass_erase(bank);\n\t}\n\n\t/* Erase requested sectors one by one */\n\tfor (unsigned int i = first; i <= last; i++) {\n\n\t\t/* Determine address of sector to erase */\n\t\taddress = FLASH_BASE_ADDR + i * FLASH_SECTOR_SIZE;\n\n\t\t/* Set starting address to erase */\n\t\tretval = target_write_u32(target, FMA_REGISTER_ADDR, address);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Write the ERASE bit of the FMC register */\n\t\tretval = target_write_u32(target, FMC_REGISTER_ADDR, FMC_ERASE_VALUE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Poll the ERASE bit until the erase is complete */\n\t\tdone = false;\n\t\tstart_ms = timeval_ms();\n\t\twhile (!done) {\n\t\t\tretval = target_read_u32(target, FMC_REGISTER_ADDR, &value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif ((value & FMC_ERASE_BIT) == 0) {\n\t\t\t\t/* Bit clears when mass erase is finished */\n\t\t\t\tdone = true;\n\t\t\t} else {\n\t\t\t\telapsed_ms = timeval_ms() - start_ms;\n\t\t\t\tif (elapsed_ms > 500)\n\t\t\t\t\tkeep_alive();\n\t\t\t\tif (elapsed_ms > FLASH_TIMEOUT)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!done) {\n\t\t\t/* Sector erase timed out waiting for confirmation */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int cc3220sf_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;\n\tstruct working_area *algo_working_area;\n\tstruct working_area *buffer_working_area;\n\tstruct reg_param reg_params[3];\n\tuint32_t algo_base_address;\n\tuint32_t algo_buffer_address;\n\tuint32_t algo_buffer_size;\n\tuint32_t address;\n\tuint32_t remaining;\n\tuint32_t words;\n\tuint32_t result;\n\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Obtain working area to use for flash helper algorithm */\n\tretval = target_alloc_working_area(target, sizeof(cc3220sf_algo),\n\t\t\t\t&algo_working_area);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Obtain working area to use for flash buffer */\n\tretval = target_alloc_working_area(target,\n\t\t\t\ttarget_get_working_area_avail(target), &buffer_working_area);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, algo_working_area);\n\t\treturn retval;\n\t}\n\n\talgo_base_address = algo_working_area->address;\n\talgo_buffer_address = buffer_working_area->address;\n\talgo_buffer_size = buffer_working_area->size;\n\n\t/* Make sure buffer size is a multiple of 32 word (0x80 byte) chunks */\n\t/* (algo runs more efficiently if it operates on 32 words at a time) */\n\tif (algo_buffer_size > 0x80)\n\t\talgo_buffer_size &= ~0x7f;\n\n\t/* Write flash helper algorithm into target memory */\n\tretval = target_write_buffer(target, algo_base_address,\n\t\t\t\tsizeof(cc3220sf_algo), cc3220sf_algo);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, algo_working_area);\n\t\ttarget_free_working_area(target, buffer_working_area);\n\t\treturn retval;\n\t}\n\n\t/* Initialize the ARMv7m specific info to run the algorithm */\n\tcc3220sf_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tcc3220sf_bank->armv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* Initialize register params for flash helper algorithm */\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_IN_OUT);\n\n\t/* Prepare to write to flash */\n\taddress = FLASH_BASE_ADDR + offset;\n\tremaining = count;\n\n\t/* The flash hardware can only write complete words to flash. If\n\t * an unaligned address is passed in, we must do a read-modify-write\n\t * on a word with enough bytes to align the rest of the buffer. And\n\t * if less than a whole word remains at the end, we must also do a\n\t * read-modify-write on a final word to finish up.\n\t */\n\n\t/* Do one word write to align address on 32-bit boundary if needed */\n\tif (0 != (address & 0x3)) {\n\t\tuint8_t head[4];\n\n\t\t/* Get starting offset for data to write (will be 1 to 3) */\n\t\tuint32_t head_offset = address & 0x03;\n\n\t\t/* Get the aligned address to write this first word to */\n\t\tuint32_t head_address = address & 0xfffffffc;\n\n\t\t/* Retrieve what is already in flash at the head address */\n\t\tretval = target_read_buffer(target, head_address, sizeof(head), head);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Substitute in the new data to write */\n\t\t\twhile ((remaining > 0) && (head_offset < 4)) {\n\t\t\t\thead[head_offset] = *buffer;\n\t\t\t\thead_offset++;\n\t\t\t\taddress++;\n\t\t\t\tbuffer++;\n\t\t\t\tremaining--;\n\t\t\t}\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Helper parameters are passed in registers R0-R2 */\n\t\t\t/* Set start of data buffer, address to write to, and word count */\n\t\t\tbuf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);\n\t\t\tbuf_set_u32(reg_params[1].value, 0, 32, head_address);\n\t\t\tbuf_set_u32(reg_params[2].value, 0, 32, 1);\n\n\t\t\t/* Write head value into buffer to flash */\n\t\t\tretval = target_write_buffer(target, algo_buffer_address,\n\t\t\t\t\t\tsizeof(head), head);\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Execute the flash helper algorithm */\n\t\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\t\t\talgo_base_address, 0, FLASH_TIMEOUT,\n\t\t\t\t\t\t&cc3220sf_bank->armv7m_info);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"cc3220sf: Flash algorithm failed to run\");\n\n\t\t\t/* Check that the head value was written to flash */\n\t\t\tresult = buf_get_u32(reg_params[2].value, 0, 32);\n\t\t\tif (result != 0) {\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tLOG_ERROR(\"cc3220sf: Flash operation failed\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Check if there's data at end of buffer that isn't a full word */\n\tuint32_t tail_count = remaining & 0x03;\n\t/* Adjust remaining so it is a multiple of whole words */\n\tremaining -= tail_count;\n\n\twhile ((retval == ERROR_OK) && (remaining > 0)) {\n\t\t/* Set start of data buffer and address to write to */\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\n\t\t/* Download data to write into memory buffer */\n\t\tif (remaining >= algo_buffer_size) {\n\t\t\t/* Fill up buffer with data to flash */\n\t\t\tretval = target_write_buffer(target, algo_buffer_address,\n\t\t\t\t\t\talgo_buffer_size, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\t/* Count to write is in 32-bit words */\n\t\t\twords = algo_buffer_size / 4;\n\n\t\t\t/* Bump variables to next data */\n\t\t\taddress += algo_buffer_size;\n\t\t\tbuffer += algo_buffer_size;\n\t\t\tremaining -= algo_buffer_size;\n\t\t} else {\n\t\t\t/* Fill buffer with what's left of the data */\n\t\t\tretval = target_write_buffer(target, algo_buffer_address,\n\t\t\t\t\t\tremaining, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\t/* Calculate the final word count to write */\n\t\t\twords = remaining / 4;\n\t\t\tif (0 != (remaining % 4))\n\t\t\t\twords++;\n\n\t\t\t/* Bump variables to any final data */\n\t\t\taddress += remaining;\n\t\t\tbuffer += remaining;\n\t\t\tremaining = 0;\n\t\t}\n\n\t\t/* Set number of words to write */\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, words);\n\n\t\t/* Execute the flash helper algorithm */\n\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\t\talgo_base_address, 0, FLASH_TIMEOUT,\n\t\t\t\t\t&cc3220sf_bank->armv7m_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"cc3220sf: Flash algorithm failed to run\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Check that all words were written to flash */\n\t\tresult = buf_get_u32(reg_params[2].value, 0, 32);\n\t\tif (result != 0) {\n\t\t\tretval = ERROR_FAIL;\n\t\t\tLOG_ERROR(\"cc3220sf: Flash operation failed\");\n\t\t\tbreak;\n\t\t}\n\n\t\tkeep_alive();\n\t}\n\n\t/* Do one word write for any final bytes less than a full word */\n\tif ((retval == ERROR_OK) && (tail_count != 0)) {\n\t\tuint8_t tail[4];\n\n\t\t/* Set starting byte offset for data to write */\n\t\tuint32_t tail_offset = 0;\n\n\t\t/* Retrieve what is already in flash at the tail address */\n\t\tretval = target_read_buffer(target, address, sizeof(tail), tail);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Substitute in the new data to write */\n\t\t\twhile (tail_count > 0) {\n\t\t\t\ttail[tail_offset] = *buffer;\n\t\t\t\ttail_offset++;\n\t\t\t\tbuffer++;\n\t\t\t\ttail_count--;\n\t\t\t}\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Set start of data buffer, address to write to, and word count */\n\t\t\tbuf_set_u32(reg_params[0].value, 0, 32, algo_buffer_address);\n\t\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\t\tbuf_set_u32(reg_params[2].value, 0, 32, 1);\n\n\t\t\t/* Write tail value into buffer to flash */\n\t\t\tretval = target_write_buffer(target, algo_buffer_address,\n\t\t\t\t\t\tsizeof(tail), tail);\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* Execute the flash helper algorithm */\n\t\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\t\t\talgo_base_address, 0, FLASH_TIMEOUT,\n\t\t\t\t\t\t&cc3220sf_bank->armv7m_info);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"cc3220sf: Flash algorithm failed to run\");\n\n\t\t\t/* Check that the tail was written to flash */\n\t\t\tresult = buf_get_u32(reg_params[2].value, 0, 32);\n\t\t\tif (result != 0) {\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tLOG_ERROR(\"cc3220sf: Flash operation failed\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Free resources  */\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\ttarget_free_working_area(target, algo_working_area);\n\ttarget_free_working_area(target, buffer_working_area);\n\n\treturn retval;\n}\n\nstatic int cc3220sf_probe(struct flash_bank *bank)\n{\n\tstruct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;\n\n\tuint32_t base;\n\tuint32_t size;\n\tunsigned int num_sectors;\n\n\tbase = FLASH_BASE_ADDR;\n\tsize = FLASH_NUM_SECTORS * FLASH_SECTOR_SIZE;\n\tnum_sectors = FLASH_NUM_SECTORS;\n\n\tfree(bank->sectors);\n\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tbank->base = base;\n\tbank->size = size;\n\tbank->write_start_alignment = 0;\n\tbank->write_end_alignment = 0;\n\tbank->num_sectors = num_sectors;\n\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * FLASH_SECTOR_SIZE;\n\t\tbank->sectors[i].size = FLASH_SECTOR_SIZE;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\t/* We've successfully recorded the stats on this flash bank */\n\tcc3220sf_bank->probed = true;\n\n\t/* If we fall through to here, then all went well */\n\n\treturn ERROR_OK;\n}\n\nstatic int cc3220sf_auto_probe(struct flash_bank *bank)\n{\n\tstruct cc3220sf_bank *cc3220sf_bank = bank->driver_priv;\n\n\tint retval = ERROR_OK;\n\n\tif (!cc3220sf_bank->probed)\n\t\tretval = cc3220sf_probe(bank);\n\n\treturn retval;\n}\n\nstatic int cc3220sf_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tcommand_print_sameline(cmd, \"CC3220SF with 1MB internal flash\\n\");\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver cc3220sf_flash = {\n\t.name = \"cc3220sf\",\n\t.flash_bank_command = cc3220sf_flash_bank_command,\n\t.erase = cc3220sf_erase,\n\t.write = cc3220sf_write,\n\t.read = default_flash_read,\n\t.probe = cc3220sf_probe,\n\t.auto_probe = cc3220sf_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = cc3220sf_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cc3220sf.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_CC3220SF_H\n#define OPENOCD_FLASH_NOR_CC3220SF_H\n\n/* CC3220SF device types */\n#define CC3220_NO_TYPE 0 /* Device type not determined yet */\n#define CC3220_OTHER   1 /* CC3220 variant without flash */\n#define CC3220SF       2 /* CC3220SF variant with flash */\n\n/* Flash parameters */\n#define FLASH_BASE_ADDR   0x01000000\n#define FLASH_SECTOR_SIZE 2048\n#define FLASH_NUM_SECTORS 512\n\n/* CC2200SF flash registers */\n#define FMA_REGISTER_ADDR 0x400FD000\n#define FMC_REGISTER_ADDR 0x400FD008\n#define FMC_DEFAULT_VALUE 0xA4420000\n#define FMC_ERASE_BIT     0x00000002\n#define FMC_MERASE_BIT    0x00000004\n#define FMC_ERASE_VALUE   (FMC_DEFAULT_VALUE | FMC_ERASE_BIT)\n#define FMC_MERASE_VALUE  (FMC_DEFAULT_VALUE | FMC_MERASE_BIT)\n\n#endif /* OPENOCD_FLASH_NOR_CC3220SF_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cfi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2009 Michael Schwingen                                  *\n *   michael@schwingen.org                                                 *\n *   Copyright (C) 2010 Øyvind Harboe <oyvind.harboe@zylin.com>            *\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"cfi.h\"\n#include \"non_cfi.h\"\n#include <target/arm.h>\n#include <target/arm7_9_common.h>\n#include <target/armv7m.h>\n#include <target/mips32.h>\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n\n/* defines internal maximum size for code fragment in cfi_intel_write_block() */\n#define CFI_MAX_INTEL_CODESIZE 256\n\n/* some id-types with specific handling */\n#define AT49BV6416      0x00d6\n#define AT49BV6416T     0x00d2\n\nstatic const struct cfi_unlock_addresses cfi_unlock_addresses[] = {\n\t[CFI_UNLOCK_555_2AA] = { .unlock1 = 0x555, .unlock2 = 0x2aa },\n\t[CFI_UNLOCK_5555_2AAA] = { .unlock1 = 0x5555, .unlock2 = 0x2aaa },\n};\n\nstatic const int cfi_status_poll_mask_dq6_dq7 = CFI_STATUS_POLL_MASK_DQ6_DQ7;\n\n/* CFI fixups forward declarations */\nstatic void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *param);\nstatic void cfi_fixup_0002_unlock_addresses(struct flash_bank *bank, const void *param);\nstatic void cfi_fixup_reversed_erase_regions(struct flash_bank *bank, const void *param);\nstatic void cfi_fixup_0002_write_buffer(struct flash_bank *bank, const void *param);\nstatic void cfi_fixup_0002_polling_bits(struct flash_bank *bank, const void *param);\n\n/* fixup after reading cmdset 0002 primary query table */\nstatic const struct cfi_fixup cfi_0002_fixups[] = {\n\t{CFI_MFR_SST, 0x00D4, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x00D5, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x00D6, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x00D7, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x2780, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x274b, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_SST, 0x235f, cfi_fixup_0002_polling_bits,\t/* 39VF3201C */\n\t &cfi_status_poll_mask_dq6_dq7},\n\t{CFI_MFR_SST, 0x236d, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_ATMEL, 0x00C8, cfi_fixup_reversed_erase_regions, NULL},\n\t{CFI_MFR_ST, 0x22C4, cfi_fixup_reversed_erase_regions, NULL},\t/* M29W160ET */\n\t{CFI_MFR_FUJITSU, 0x22ea, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_FUJITSU, 0x226b, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_5555_2AAA]},\n\t{CFI_MFR_AMIC, 0xb31a, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_MX, 0x225b, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_EON, 0x225b, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_AMD, 0x225b, cfi_fixup_0002_unlock_addresses,\n\t &cfi_unlock_addresses[CFI_UNLOCK_555_2AA]},\n\t{CFI_MFR_ANY, CFI_ID_ANY, cfi_fixup_0002_erase_regions, NULL},\n\t{CFI_MFR_ST, 0x227E, cfi_fixup_0002_write_buffer, NULL},/* M29W128G */\n\t{0, 0, NULL, NULL}\n};\n\n/* fixup after reading cmdset 0001 primary query table */\nstatic const struct cfi_fixup cfi_0001_fixups[] = {\n\t{0, 0, NULL, NULL}\n};\n\nstatic void cfi_fixup(struct flash_bank *bank, const struct cfi_fixup *fixups)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tfor (const struct cfi_fixup *f = fixups; f->fixup; f++) {\n\t\tif (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi_info->manufacturer)) &&\n\t\t\t\t((f->id  == CFI_ID_ANY)  || (f->id  == cfi_info->device_id)))\n\t\t\tf->fixup(bank, f->param);\n\t}\n}\n\nuint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (cfi_info->x16_as_x8)\n\t\toffset *= 2;\n\n\t/* while the sector list isn't built, only accesses to sector 0 work */\n\tif (sector == 0)\n\t\treturn bank->base + offset * bank->bus_width;\n\telse {\n\t\tif (!bank->sectors) {\n\t\t\tLOG_ERROR(\"BUG: sector list not yet built\");\n\t\t\texit(-1);\n\t\t}\n\t\treturn bank->base + bank->sectors[sector].offset + offset * bank->bus_width;\n\t}\n}\n\nstatic int cfi_target_write_memory(struct flash_bank *bank, target_addr_t addr,\n\t\t\t\t   uint32_t count, const uint8_t *buffer)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tif (cfi_info->write_mem) {\n\t\treturn cfi_info->write_mem(bank, addr, count, buffer);\n\t} else {\n\t\treturn target_write_memory(bank->target, addr, bank->bus_width,\n\t\t\t\t\t   count, buffer);\n\t}\n}\n\nint cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr,\n\t\t\t   uint32_t count, uint8_t *buffer)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tif (cfi_info->read_mem) {\n\t\treturn cfi_info->read_mem(bank, addr, count, buffer);\n\t} else {\n\t\treturn target_read_memory(bank->target, addr, bank->bus_width,\n\t\t\t\t\t  count, buffer);\n\t}\n}\n\nstatic void cfi_command(struct flash_bank *bank, uint8_t cmd, uint8_t *cmd_buf)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\t/* clear whole buffer, to ensure bits that exceed the bus_width\n\t * are set to zero\n\t */\n\tfor (size_t i = 0; i < CFI_MAX_BUS_WIDTH; i++)\n\t\tcmd_buf[i] = 0;\n\n\tif (cfi_info->endianness == TARGET_LITTLE_ENDIAN) {\n\t\tfor (unsigned int i = bank->bus_width; i > 0; i--)\n\t\t\t*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;\n\t} else {\n\t\tfor (unsigned int i = 1; i <= bank->bus_width; i++)\n\t\t\t*cmd_buf++ = (i & (bank->chip_width - 1)) ? 0x0 : cmd;\n\t}\n}\n\nint cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address)\n{\n\tuint8_t command[CFI_MAX_BUS_WIDTH];\n\n\tcfi_command(bank, cmd, command);\n\treturn cfi_target_write_memory(bank, address, 1, command);\n}\n\n/* read unsigned 8-bit value from the bank\n * flash banks are expected to be made of similar chips\n * the query result should be the same for all\n */\nstatic int cfi_query_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint8_t data[CFI_MAX_BUS_WIDTH];\n\n\tint retval;\n\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset),\n\t\t\t\t\t1, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_info->endianness == TARGET_LITTLE_ENDIAN)\n\t\t*val = data[0];\n\telse\n\t\t*val = data[bank->bus_width - 1];\n\n\treturn ERROR_OK;\n}\n\n/* read unsigned 8-bit value from the bank\n * in case of a bank made of multiple chips,\n * the individual values are ORed\n */\nstatic int cfi_get_u8(struct flash_bank *bank, int sector, uint32_t offset, uint8_t *val)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint8_t data[CFI_MAX_BUS_WIDTH];\n\n\tint retval;\n\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset),\n\t\t\t\t\t1, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_info->endianness == TARGET_LITTLE_ENDIAN) {\n\t\tfor (unsigned int i = 0; i < bank->bus_width / bank->chip_width; i++)\n\t\t\tdata[0] |= data[i];\n\n\t\t*val = data[0];\n\t} else {\n\t\tuint8_t value = 0;\n\t\tfor (unsigned int i = 0; i < bank->bus_width / bank->chip_width; i++)\n\t\t\tvalue |= data[bank->bus_width - 1 - i];\n\n\t\t*val = value;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cfi_query_u16(struct flash_bank *bank, int sector, uint32_t offset, uint16_t *val)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint8_t data[CFI_MAX_BUS_WIDTH * 2];\n\tint retval;\n\n\tif (cfi_info->x16_as_x8) {\n\t\tfor (uint8_t i = 0; i < 2; i++) {\n\t\t\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i),\n\t\t\t\t\t\t\t1, &data[i * bank->bus_width]);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset),\n\t\t\t\t\t\t2, data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cfi_info->endianness == TARGET_LITTLE_ENDIAN)\n\t\t*val = data[0] | data[bank->bus_width] << 8;\n\telse\n\t\t*val = data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8;\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_query_u32(struct flash_bank *bank, int sector, uint32_t offset, uint32_t *val)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint8_t data[CFI_MAX_BUS_WIDTH * 4];\n\tint retval;\n\n\tif (cfi_info->x16_as_x8) {\n\t\tfor (uint8_t i = 0; i < 4; i++) {\n\t\t\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset + i),\n\t\t\t\t\t\t\t1, &data[i * bank->bus_width]);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, sector, offset),\n\t\t\t\t\t\t4, data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cfi_info->endianness == TARGET_LITTLE_ENDIAN)\n\t\t*val = data[0] | data[bank->bus_width] << 8 |\n\t\t\tdata[bank->bus_width * 2] << 16 | data[bank->bus_width * 3] << 24;\n\telse\n\t\t*val = data[bank->bus_width - 1] | data[(2 * bank->bus_width) - 1] << 8 |\n\t\t\tdata[(3 * bank->bus_width) - 1] << 16 |\n\t\t\tdata[(4 * bank->bus_width) - 1] << 24;\n\n\treturn ERROR_OK;\n}\n\nint cfi_reset(struct flash_bank *bank)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_info->manufacturer == 0x20 &&\n\t\t\t(cfi_info->device_id == 0x227E || cfi_info->device_id == 0x7E)) {\n\t\t/* Numonix M29W128G is cmd 0xFF intolerant - causes internal undefined state\n\t\t * so we send an extra 0xF0 reset to fix the bug */\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x00));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic void cfi_intel_clear_status_register(struct flash_bank *bank)\n{\n\tcfi_send_command(bank, 0x50, cfi_flash_address(bank, 0, 0x0));\n}\n\nstatic int cfi_intel_wait_status_busy(struct flash_bank *bank, int timeout, uint8_t *val)\n{\n\tuint8_t status;\n\n\tint retval = ERROR_OK;\n\n\tfor (;; ) {\n\t\tif (timeout-- < 0) {\n\t\t\tLOG_ERROR(\"timeout while waiting for WSM to become ready\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tretval = cfi_get_u8(bank, 0, 0x0, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (status & 0x80)\n\t\t\tbreak;\n\n\t\talive_sleep(1);\n\t}\n\n\t/* mask out bit 0 (reserved) */\n\tstatus = status & 0xfe;\n\n\tLOG_DEBUG(\"status: 0x%x\", status);\n\n\tif (status != 0x80) {\n\t\tLOG_ERROR(\"status register: 0x%x\", status);\n\t\tif (status & 0x2)\n\t\t\tLOG_ERROR(\"Block Lock-Bit Detected, Operation Abort\");\n\t\tif (status & 0x4)\n\t\t\tLOG_ERROR(\"Program suspended\");\n\t\tif (status & 0x8)\n\t\t\tLOG_ERROR(\"Low Programming Voltage Detected, Operation Aborted\");\n\t\tif (status & 0x10)\n\t\t\tLOG_ERROR(\"Program Error / Error in Setting Lock-Bit\");\n\t\tif (status & 0x20)\n\t\t\tLOG_ERROR(\"Error in Block Erasure or Clear Lock-Bits\");\n\t\tif (status & 0x40)\n\t\t\tLOG_ERROR(\"Block Erase Suspended\");\n\n\t\tcfi_intel_clear_status_register(bank);\n\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t*val = status;\n\treturn retval;\n}\n\nint cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tuint8_t status, oldstatus;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tint retval;\n\n\tretval = cfi_get_u8(bank, 0, 0x0, &oldstatus);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdo {\n\t\tretval = cfi_get_u8(bank, 0, 0x0, &status);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status ^ oldstatus) & 0x40) {\n\t\t\tif (status & cfi_info->status_poll_mask & 0x20) {\n\t\t\t\tretval = cfi_get_u8(bank, 0, 0x0, &oldstatus);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tretval = cfi_get_u8(bank, 0, 0x0, &status);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tif ((status ^ oldstatus) & 0x40) {\n\t\t\t\t\tLOG_ERROR(\"dq5 timeout, status: 0x%x\", status);\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_DEBUG(\"status: 0x%x\", status);\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {/* no toggle: finished, OK */\n\t\t\tLOG_DEBUG(\"status: 0x%x\", status);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\toldstatus = status;\n\t\talive_sleep(1);\n\t} while (timeout-- > 0);\n\n\tLOG_ERROR(\"timeout, status: 0x%x\", status);\n\n\treturn ERROR_FLASH_BUSY;\n}\n\nstatic int cfi_read_intel_pri_ext(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_intel_pri_ext *pri_ext;\n\n\tfree(cfi_info->pri_ext);\n\n\tpri_ext = malloc(sizeof(struct cfi_intel_pri_ext));\n\tif (!pri_ext) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tcfi_info->pri_ext = pri_ext;\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &pri_ext->pri[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &pri_ext->pri[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &pri_ext->pri[2]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I')) {\n\t\tretval = cfi_reset(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_ERROR(\"Could not read bank flash bank information\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &pri_ext->major_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &pri_ext->minor_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"pri: '%c%c%c', version: %c.%c\", pri_ext->pri[0], pri_ext->pri[1],\n\t\tpri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version);\n\n\tretval = cfi_query_u32(bank, 0, cfi_info->pri_addr + 5, &pri_ext->feature_support);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9, &pri_ext->suspend_cmd_support);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xa, &pri_ext->blk_status_reg_mask);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"feature_support: 0x%\" PRIx32 \", suspend_cmd_support: \"\n\t\t\"0x%x, blk_status_reg_mask: 0x%x\",\n\t\tpri_ext->feature_support,\n\t\tpri_ext->suspend_cmd_support,\n\t\tpri_ext->blk_status_reg_mask);\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xc, &pri_ext->vcc_optimal);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xd, &pri_ext->vpp_optimal);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"Vcc opt: %x.%x, Vpp opt: %u.%x\",\n\t\t(pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,\n\t\t(pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0xe, &pri_ext->num_protection_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (pri_ext->num_protection_fields != 1) {\n\t\tLOG_WARNING(\"expected one protection register field, but found %i\",\n\t\t\tpri_ext->num_protection_fields);\n\t}\n\n\tretval = cfi_query_u16(bank, 0, cfi_info->pri_addr + 0xf, &pri_ext->prot_reg_addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x11, &pri_ext->fact_prot_reg_size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0x12, &pri_ext->user_prot_reg_size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"protection_fields: %i, prot_reg_addr: 0x%x, \"\n\t\t\"factory pre-programmed: %i, user programmable: %i\",\n\t\tpri_ext->num_protection_fields, pri_ext->prot_reg_addr,\n\t\t1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size);\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_read_spansion_pri_ext(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext;\n\n\tfree(cfi_info->pri_ext);\n\n\tpri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));\n\tif (!pri_ext) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tcfi_info->pri_ext = pri_ext;\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &pri_ext->pri[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &pri_ext->pri[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &pri_ext->pri[2]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* default values for implementation specific workarounds */\n\tpri_ext->_unlock1 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock1;\n\tpri_ext->_unlock2 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock2;\n\tpri_ext->_reversed_geometry = 0;\n\n\tif ((pri_ext->pri[0] != 'P') || (pri_ext->pri[1] != 'R') || (pri_ext->pri[2] != 'I')) {\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_ERROR(\"Could not read spansion bank information\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &pri_ext->major_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &pri_ext->minor_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"pri: '%c%c%c', version: %c.%c\", pri_ext->pri[0], pri_ext->pri[1],\n\t\tpri_ext->pri[2], pri_ext->major_version, pri_ext->minor_version);\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 5, &pri_ext->silicon_revision);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 6, &pri_ext->erase_suspend);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 7, &pri_ext->blk_prot);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 8, &pri_ext->tmp_blk_unprotected);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 9, &pri_ext->blk_prot_unprot);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 10, &pri_ext->simultaneous_ops);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 11, &pri_ext->burst_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 12, &pri_ext->page_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 13, &pri_ext->vpp_min);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 14, &pri_ext->vpp_max);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 15, &pri_ext->top_bottom);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"Silicon Revision: 0x%x, Erase Suspend: 0x%x, Block protect: 0x%x\",\n\t\tpri_ext->silicon_revision, pri_ext->erase_suspend, pri_ext->blk_prot);\n\n\tLOG_DEBUG(\"Temporary Unprotect: 0x%x, Block Protect Scheme: 0x%x, \"\n\t\t\"Simultaneous Ops: 0x%x\", pri_ext->tmp_blk_unprotected,\n\t\tpri_ext->blk_prot_unprot, pri_ext->simultaneous_ops);\n\n\tLOG_DEBUG(\"Burst Mode: 0x%x, Page Mode: 0x%x, \", pri_ext->burst_mode, pri_ext->page_mode);\n\n\n\tLOG_DEBUG(\"Vpp min: %u.%x, Vpp max: %u.%x\",\n\t\t(pri_ext->vpp_min & 0xf0) >> 4, pri_ext->vpp_min & 0x0f,\n\t\t(pri_ext->vpp_max & 0xf0) >> 4, pri_ext->vpp_max & 0x0f);\n\n\tLOG_DEBUG(\"WP# protection 0x%x\", pri_ext->top_bottom);\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_read_atmel_pri_ext(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_atmel_pri_ext atmel_pri_ext;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext;\n\n\tfree(cfi_info->pri_ext);\n\n\tpri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));\n\tif (!pri_ext) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* ATMEL devices use the same CFI primary command set (0x2) as AMD/Spansion,\n\t * but a different primary extended query table.\n\t * We read the atmel table, and prepare a valid AMD/Spansion query table.\n\t */\n\n\tmemset(pri_ext, 0, sizeof(struct cfi_spansion_pri_ext));\n\n\tcfi_info->pri_ext = pri_ext;\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 0, &atmel_pri_ext.pri[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 1, &atmel_pri_ext.pri[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 2, &atmel_pri_ext.pri[2]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((atmel_pri_ext.pri[0] != 'P') || (atmel_pri_ext.pri[1] != 'R')\n\t\t\t|| (atmel_pri_ext.pri[2] != 'I')) {\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_ERROR(\"Could not read atmel bank information\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tpri_ext->pri[0] = atmel_pri_ext.pri[0];\n\tpri_ext->pri[1] = atmel_pri_ext.pri[1];\n\tpri_ext->pri[2] = atmel_pri_ext.pri[2];\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 3, &atmel_pri_ext.major_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 4, &atmel_pri_ext.minor_version);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"pri: '%c%c%c', version: %c.%c\", atmel_pri_ext.pri[0],\n\t\tatmel_pri_ext.pri[1], atmel_pri_ext.pri[2],\n\t\tatmel_pri_ext.major_version, atmel_pri_ext.minor_version);\n\n\tpri_ext->major_version = atmel_pri_ext.major_version;\n\tpri_ext->minor_version = atmel_pri_ext.minor_version;\n\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 5, &atmel_pri_ext.features);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 6, &atmel_pri_ext.bottom_boot);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 7, &atmel_pri_ext.burst_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, cfi_info->pri_addr + 8, &atmel_pri_ext.page_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\n\t\t\"features: 0x%2.2x, bottom_boot: 0x%2.2x, burst_mode: 0x%2.2x, page_mode: 0x%2.2x\",\n\t\tatmel_pri_ext.features,\n\t\tatmel_pri_ext.bottom_boot,\n\t\tatmel_pri_ext.burst_mode,\n\t\tatmel_pri_ext.page_mode);\n\n\tif (atmel_pri_ext.features & 0x02)\n\t\tpri_ext->erase_suspend = 2;\n\n\t/* some chips got it backwards... */\n\tif (cfi_info->device_id == AT49BV6416 ||\n\t\t\tcfi_info->device_id == AT49BV6416T) {\n\t\tif (atmel_pri_ext.bottom_boot)\n\t\t\tpri_ext->top_bottom = 3;\n\t\telse\n\t\t\tpri_ext->top_bottom = 2;\n\t} else {\n\t\tif (atmel_pri_ext.bottom_boot)\n\t\t\tpri_ext->top_bottom = 2;\n\t\telse\n\t\t\tpri_ext->top_bottom = 3;\n\t}\n\n\tpri_ext->_unlock1 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock1;\n\tpri_ext->_unlock2 = cfi_unlock_addresses[CFI_UNLOCK_555_2AA].unlock2;\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_read_0002_pri_ext(struct flash_bank *bank)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (cfi_info->manufacturer == CFI_MFR_ATMEL)\n\t\treturn cfi_read_atmel_pri_ext(bank);\n\telse\n\t\treturn cfi_read_spansion_pri_ext(bank);\n}\n\nstatic int cfi_spansion_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tcommand_print_sameline(cmd, \"\\nSpansion primary algorithm extend information:\\n\");\n\n\tcommand_print_sameline(cmd, \"pri: '%c%c%c', version: %c.%c\\n\",\n\t\t\tpri_ext->pri[0], pri_ext->pri[1], pri_ext->pri[2],\n\t\t\tpri_ext->major_version, pri_ext->minor_version);\n\n\tcommand_print_sameline(cmd, \"Silicon Rev.: 0x%x, Address Sensitive unlock: 0x%x\\n\",\n\t\t\t(pri_ext->silicon_revision) >> 2,\n\t\t\t(pri_ext->silicon_revision) & 0x03);\n\n\tcommand_print_sameline(cmd, \"Erase Suspend: 0x%x, Sector Protect: 0x%x\\n\",\n\t\t\tpri_ext->erase_suspend,\n\t\t\tpri_ext->blk_prot);\n\n\tcommand_print_sameline(cmd, \"VppMin: %u.%x, VppMax: %u.%x\\n\",\n\t\t(pri_ext->vpp_min & 0xf0) >> 4, pri_ext->vpp_min & 0x0f,\n\t\t(pri_ext->vpp_max & 0xf0) >> 4, pri_ext->vpp_max & 0x0f);\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_intel_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tcommand_print_sameline(cmd, \"\\nintel primary algorithm extend information:\\n\");\n\n\tcommand_print_sameline(cmd, \"pri: '%c%c%c', version: %c.%c\\n\",\n\t\t\tpri_ext->pri[0],\n\t\t\tpri_ext->pri[1],\n\t\t\tpri_ext->pri[2],\n\t\t\tpri_ext->major_version,\n\t\t\tpri_ext->minor_version);\n\n\tcommand_print_sameline(cmd, \"feature_support: 0x%\" PRIx32 \", \"\n\t\t\t\"suspend_cmd_support: 0x%x, blk_status_reg_mask: 0x%x\\n\",\n\t\t\tpri_ext->feature_support,\n\t\t\tpri_ext->suspend_cmd_support,\n\t\t\tpri_ext->blk_status_reg_mask);\n\n\tcommand_print_sameline(cmd, \"Vcc opt: %x.%x, Vpp opt: %u.%x\\n\",\n\t\t\t(pri_ext->vcc_optimal & 0xf0) >> 4, pri_ext->vcc_optimal & 0x0f,\n\t\t\t(pri_ext->vpp_optimal & 0xf0) >> 4, pri_ext->vpp_optimal & 0x0f);\n\n\tcommand_print_sameline(cmd, \"protection_fields: %i, prot_reg_addr: 0x%x, \"\n\t\t\"factory pre-programmed: %i, user programmable: %i\\n\",\n\t\tpri_ext->num_protection_fields, pri_ext->prot_reg_addr,\n\t\t1 << pri_ext->fact_prot_reg_size, 1 << pri_ext->user_prot_reg_size);\n\n\treturn ERROR_OK;\n}\n\nint cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **argv)\n{\n\tstruct cfi_flash_bank *cfi_info;\n\tbool bus_swap = false;\n\n\tif (argc < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* both widths must:\n\t * - not exceed max value;\n\t * - not be null;\n\t * - be equal to a power of 2.\n\t * bus must be wide enough to hold one chip */\n\tif ((bank->chip_width > CFI_MAX_CHIP_WIDTH)\n\t\t\t|| (bank->bus_width > CFI_MAX_BUS_WIDTH)\n\t\t\t|| (bank->chip_width == 0)\n\t\t\t|| (bank->bus_width == 0)\n\t\t\t|| (bank->chip_width & (bank->chip_width - 1))\n\t\t\t|| (bank->bus_width & (bank->bus_width - 1))\n\t\t\t|| (bank->chip_width > bank->bus_width)) {\n\t\tLOG_ERROR(\"chip and bus width have to specified in bytes\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tcfi_info = calloc(1, sizeof(struct cfi_flash_bank));\n\tif (!cfi_info) {\n\t\tLOG_ERROR(\"No memory for flash bank info\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbank->driver_priv = cfi_info;\n\n\tfor (unsigned i = 6; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"x16_as_x8\") == 0)\n\t\t\tcfi_info->x16_as_x8 = true;\n\t\telse if (strcmp(argv[i], \"data_swap\") == 0)\n\t\t\tcfi_info->data_swap = true;\n\t\telse if (strcmp(argv[i], \"bus_swap\") == 0)\n\t\t\tbus_swap = true;\n\t\telse if (strcmp(argv[i], \"jedec_probe\") == 0)\n\t\t\tcfi_info->jedec_probe = true;\n\t}\n\n\tif (bus_swap)\n\t\tcfi_info->endianness =\n\t\t\tbank->target->endianness == TARGET_LITTLE_ENDIAN ?\n\t\t\tTARGET_BIG_ENDIAN : TARGET_LITTLE_ENDIAN;\n\telse\n\t\tcfi_info->endianness = bank->target->endianness;\n\n\t/* bank wasn't probed yet */\n\tcfi_info->qry[0] = 0xff;\n\n\treturn ERROR_OK;\n}\n\n/* flash_bank cfi <base> <size> <chip_width> <bus_width> <target#> [options]\n */\nFLASH_BANK_COMMAND_HANDLER(cfi_flash_bank_command)\n{\n\treturn cfi_flash_bank_cmd(bank, CMD_ARGC, CMD_ARGV);\n}\n\nstatic int cfi_intel_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tcfi_intel_clear_status_register(bank);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = cfi_send_command(bank, 0x20, cfi_flash_address(bank, i, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_send_command(bank, 0xd0, cfi_flash_address(bank, i, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tuint8_t status;\n\t\tretval = cfi_intel_wait_status_busy(bank, cfi_info->block_erase_timeout, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (status != 0x80) {\n\t\t\tretval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tLOG_ERROR(\"couldn't erase block %u of flash bank at base \"\n\t\t\t\t\tTARGET_ADDR_FMT, i, bank->base);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n}\n\nint cfi_spansion_unlock_seq(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tretval = cfi_send_command(bank, 0xaa, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_send_command(bank, 0x55, cfi_flash_address(bank, 0, pri_ext->_unlock2));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_spansion_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = cfi_spansion_unlock_seq(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_send_command(bank, 0x80, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_spansion_unlock_seq(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_send_command(bank, 0x30, cfi_flash_address(bank, i, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (cfi_spansion_wait_status_busy(bank, cfi_info->block_erase_timeout) != ERROR_OK) {\n\t\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tLOG_ERROR(\"couldn't erase block %i of flash bank at base \"\n\t\t\t\tTARGET_ADDR_FMT, i, bank->base);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n}\n\nint cfi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tswitch (cfi_info->pri_id) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn cfi_intel_erase(bank, first, last);\n\t\tcase 2:\n\t\t\treturn cfi_spansion_erase(bank, first, last);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_intel_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;\n\tint retry = 0;\n\n\t/* if the device supports neither legacy lock/unlock (bit 3) nor\n\t * instant individual block locking (bit 5).\n\t */\n\tif (!(pri_ext->feature_support & 0x28)) {\n\t\tLOG_ERROR(\"lock/unlock not supported on flash\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tcfi_intel_clear_status_register(bank);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = cfi_send_command(bank, 0x60, cfi_flash_address(bank, i, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (set) {\n\t\t\tretval = cfi_send_command(bank, 0x01, cfi_flash_address(bank, i, 0x0));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t} else {\n\t\t\tretval = cfi_send_command(bank, 0xd0, cfi_flash_address(bank, i, 0x0));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbank->sectors[i].is_protected = 0;\n\t\t}\n\n\t\t/* instant individual block locking doesn't require reading of the status register\n\t\t **/\n\t\tif (!(pri_ext->feature_support & 0x20)) {\n\t\t\t/* Clear lock bits operation may take up to 1.4s */\n\t\t\tuint8_t status;\n\t\t\tretval = cfi_intel_wait_status_busy(bank, 1400, &status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tuint8_t block_status;\n\t\t\t/* read block lock bit, to verify status */\n\t\t\tretval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, 0x55));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = cfi_get_u8(bank, i, 0x2, &block_status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif ((block_status & 0x1) != set) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"couldn't change block lock status (set = %i, block_status = 0x%2.2x)\",\n\t\t\t\t\tset, block_status);\n\t\t\t\tretval = cfi_send_command(bank, 0x70, cfi_flash_address(bank, 0, 0x55));\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tuint8_t status;\n\t\t\t\tretval = cfi_intel_wait_status_busy(bank, 10, &status);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tif (retry > 10)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\telse {\n\t\t\t\t\ti--;\n\t\t\t\t\tretry++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* if the device doesn't support individual block lock bits set/clear,\n\t * all blocks have been unlocked in parallel, so we set those that should be protected\n\t */\n\tif ((!set) && (!(pri_ext->feature_support & 0x20))) {\n\t\t/* FIX!!! this code path is broken!!!\n\t\t *\n\t\t * The correct approach is:\n\t\t *\n\t\t * 1. read out current protection status\n\t\t *\n\t\t * 2. override read out protection status w/unprotected.\n\t\t *\n\t\t * 3. re-protect what should be protected.\n\t\t *\n\t\t */\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tif (bank->sectors[i].is_protected == 1) {\n\t\t\t\tcfi_intel_clear_status_register(bank);\n\n\t\t\t\tretval = cfi_send_command(bank, 0x60, cfi_flash_address(bank, i, 0x0));\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tretval = cfi_send_command(bank, 0x01, cfi_flash_address(bank, i, 0x0));\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tuint8_t status;\n\t\t\t\tretval = cfi_intel_wait_status_busy(bank, 100, &status);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n}\n\nint cfi_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tswitch (cfi_info->pri_id) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn cfi_intel_protect(bank, set, first, last);\n\t\tdefault:\n\t\t\tLOG_WARNING(\"protect: cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\treturn ERROR_OK;\n\t}\n}\n\nstatic uint32_t cfi_command_val(struct flash_bank *bank, uint8_t cmd)\n{\n\tstruct target *target = bank->target;\n\n\tuint8_t buf[CFI_MAX_BUS_WIDTH];\n\tcfi_command(bank, cmd, buf);\n\tswitch (bank->bus_width) {\n\t\tcase 1:\n\t\t\treturn buf[0];\n\t\tcase 2:\n\t\t\treturn target_buffer_get_u16(target, buf);\n\t\tcase 4:\n\t\t\treturn target_buffer_get_u32(target, buf);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported bank buswidth %u, can't do block memory writes\",\n\t\t\t\t\tbank->bus_width);\n\t\t\treturn 0;\n\t}\n}\n\nstatic int cfi_intel_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t address, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct reg_param reg_params[7];\n\tstruct arm_algorithm arm_algo;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source = NULL;\n\tuint32_t buffer_size = 32768;\n\tuint32_t write_command_val, busy_pattern_val, error_pattern_val;\n\n\t/* algorithm register usage:\n\t * r0: source address (in RAM)\n\t * r1: target address (in Flash)\n\t * r2: count\n\t * r3: flash write command\n\t * r4: status byte (returned to host)\n\t * r5: busy test pattern\n\t * r6: error test pattern\n\t */\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_intel_32.s for src */\n\tstatic const uint32_t word_32_code[] = {\n\t\t0xe4904004,\t/* loop: ldr r4, [r0], #4 */\n\t\t0xe5813000,\t/*       str r3, [r1] */\n\t\t0xe5814000,\t/*       str r4, [r1] */\n\t\t0xe5914000,\t/* busy: ldr r4, [r1] */\n\t\t0xe0047005,\t/*        and r7, r4, r5 */\n\t\t0xe1570005,\t/*       cmp r7, r5 */\n\t\t0x1afffffb,\t/*       bne busy */\n\t\t0xe1140006,\t/*       tst r4, r6 */\n\t\t0x1a000003,\t/*       bne done */\n\t\t0xe2522001,\t/*       subs r2, r2, #1 */\n\t\t0x0a000001,\t/*       beq done */\n\t\t0xe2811004,\t/*       add r1, r1 #4 */\n\t\t0xeafffff2,\t/*       b loop */\n\t\t0xeafffffe\t/* done: b -2 */\n\t};\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_intel_16.s for src */\n\tstatic const uint32_t word_16_code[] = {\n\t\t0xe0d040b2,\t/* loop: ldrh r4, [r0], #2 */\n\t\t0xe1c130b0,\t/*       strh r3, [r1] */\n\t\t0xe1c140b0,\t/*       strh r4, [r1] */\n\t\t0xe1d140b0,\t/* busy  ldrh r4, [r1] */\n\t\t0xe0047005,\t/*       and r7, r4, r5 */\n\t\t0xe1570005,\t/*       cmp r7, r5 */\n\t\t0x1afffffb,\t/*       bne busy */\n\t\t0xe1140006,\t/*       tst r4, r6 */\n\t\t0x1a000003,\t/*       bne done */\n\t\t0xe2522001,\t/*       subs r2, r2, #1 */\n\t\t0x0a000001,\t/*       beq done */\n\t\t0xe2811002,\t/*       add r1, r1 #2 */\n\t\t0xeafffff2,\t/*       b loop */\n\t\t0xeafffffe\t/* done:\tb -2 */\n\t};\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_intel_8.s for src */\n\tstatic const uint32_t word_8_code[] = {\n\t\t0xe4d04001,\t/* loop: ldrb r4, [r0], #1 */\n\t\t0xe5c13000,\t/*       strb r3, [r1] */\n\t\t0xe5c14000,\t/*       strb r4, [r1] */\n\t\t0xe5d14000,\t/* busy  ldrb r4, [r1] */\n\t\t0xe0047005,\t/*       and r7, r4, r5 */\n\t\t0xe1570005,\t/*       cmp r7, r5 */\n\t\t0x1afffffb,\t/*       bne busy */\n\t\t0xe1140006,\t/*       tst r4, r6 */\n\t\t0x1a000003,\t/*       bne done */\n\t\t0xe2522001,\t/*       subs r2, r2, #1 */\n\t\t0x0a000001,\t/*       beq done */\n\t\t0xe2811001,\t/*       add r1, r1 #1 */\n\t\t0xeafffff2,\t/*       b loop */\n\t\t0xeafffffe\t/* done: b -2 */\n\t};\n\tuint8_t target_code[4*CFI_MAX_INTEL_CODESIZE];\n\tconst uint32_t *target_code_src;\n\tuint32_t target_code_size;\n\tint retval = ERROR_OK;\n\n\t/* check we have a supported arch */\n\tif (is_arm(target_to_arm(target))) {\n\t\t/* All other ARM CPUs have 32 bit instructions */\n\t\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\t\tarm_algo.core_mode = ARM_MODE_SVC;\n\t\tarm_algo.core_state = ARM_STATE_ARM;\n\t} else {\n\t\tLOG_ERROR(\"Unknown architecture\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tcfi_intel_clear_status_register(bank);\n\n\t/* If we are setting up the write_algorithm, we need target_code_src\n\t * if not we only need target_code_size. */\n\n\t/* However, we don't want to create multiple code paths, so we\n\t * do the unnecessary evaluation of target_code_src, which the\n\t * compiler will probably nicely optimize away if not needed */\n\n\t/* prepare algorithm code for target endian */\n\tswitch (bank->bus_width) {\n\t\tcase 1:\n\t\t\ttarget_code_src = word_8_code;\n\t\t\ttarget_code_size = sizeof(word_8_code);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_code_src = word_16_code;\n\t\t\ttarget_code_size = sizeof(word_16_code);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\ttarget_code_src = word_32_code;\n\t\t\ttarget_code_size = sizeof(word_32_code);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported bank buswidth %u, can't do block memory writes\",\n\t\t\t\t\tbank->bus_width);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* flash write code */\n\tif (target_code_size > sizeof(target_code)) {\n\t\tLOG_WARNING(\"Internal error - target code buffer to small. \"\n\t\t\t\t\"Increase CFI_MAX_INTEL_CODESIZE and recompile.\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\ttarget_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src);\n\n\t/* Get memory for block write handler */\n\tretval = target_alloc_working_area(target,\n\t\t\ttarget_code_size,\n\t\t\t&write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"No working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* write algorithm code to working area */\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\ttarget_code_size, target_code);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write block write code to target\");\n\t\tgoto cleanup;\n\t}\n\n\t/* Get a workspace buffer for the data to flash starting with 32k size.\n\t * Half size until buffer would be smaller 256 Bytes then fail back */\n\t/* FIXME Why 256 bytes, why not 32 bytes (smallest flash write page */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\tLOG_WARNING(\n\t\t\t\t\"no large enough working area available, can't do block memory writes\");\n\t\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\t/* setup algo registers */\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[6], \"r6\", 32, PARAM_OUT);\n\n\t/* prepare command and status register patterns */\n\twrite_command_val = cfi_command_val(bank, 0x40);\n\tbusy_pattern_val  = cfi_command_val(bank, 0x80);\n\terror_pattern_val = cfi_command_val(bank, 0x7e);\n\n\tLOG_DEBUG(\"Using target buffer at \" TARGET_ADDR_FMT \" and of size 0x%04\" PRIx32,\n\t\tsource->address, buffer_size);\n\n\t/* Programming main loop */\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;\n\t\tuint32_t wsm_error;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);\n\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, write_command_val);\n\t\tbuf_set_u32(reg_params[5].value, 0, 32, busy_pattern_val);\n\t\tbuf_set_u32(reg_params[6].value, 0, 32, error_pattern_val);\n\n\t\tLOG_DEBUG(\"Write 0x%04\" PRIx32 \" bytes to flash at 0x%08\" PRIx32,\n\t\t\tthisrun_count, address);\n\n\t\t/* Execute algorithm, assume breakpoint for last instruction */\n\t\tretval = target_run_algorithm(target, 0, NULL, 7, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\twrite_algorithm->address + target_code_size -\n\t\t\t\tsizeof(uint32_t),\n\t\t\t\t10000,\t/* 10s should be enough for max. 32k of data */\n\t\t\t\t&arm_algo);\n\n\t\t/* On failure try a fall back to direct word writes */\n\t\tif (retval != ERROR_OK) {\n\t\t\tcfi_intel_clear_status_register(bank);\n\t\t\tLOG_ERROR(\n\t\t\t\t\"Execution of flash algorithm failed. Can't fall back. Please report.\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t/* retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE; */\n\t\t\t/* FIXME To allow fall back or recovery, we must save the actual status\n\t\t\t * somewhere, so that a higher level code can start recovery. */\n\t\t\tgoto cleanup;\n\t\t}\n\n\t\t/* Check return value from algo code */\n\t\twsm_error = buf_get_u32(reg_params[4].value, 0, 32) & error_pattern_val;\n\t\tif (wsm_error) {\n\t\t\t/* read status register (outputs debug information) */\n\t\t\tuint8_t status;\n\t\t\tcfi_intel_wait_status_busy(bank, 100, &status);\n\t\t\tcfi_intel_clear_status_register(bank);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto cleanup;\n\t\t}\n\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\n\t\tkeep_alive();\n\t}\n\n\t/* free up resources */\ncleanup:\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\tdestroy_reg_param(&reg_params[6]);\n\n\treturn retval;\n}\n\nstatic int cfi_spansion_write_block_mips(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t address, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\tstruct target *target = bank->target;\n\tstruct reg_param reg_params[10];\n\tstruct mips32_algorithm mips32_info;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t buffer_size = 32768;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* input parameters -\n\t *\t4  A0 = source address\n\t *\t5  A1 = destination address\n\t *\t6  A2 = number of writes\n\t *\t7  A3 = flash write command\n\t *\t8  T0 = constant to mask DQ7 bits (also used for Dq5 with shift)\n\t * output parameters -\n\t *\t9  T1 = 0x80 ok 0x00 bad\n\t * temp registers -\n\t *\t10 T2 = value read from flash to test status\n\t *\t11 T3 = holding register\n\t * unlock registers -\n\t *  12 T4 = unlock1_addr\n\t *  13 T5 = unlock1_cmd\n\t *  14 T6 = unlock2_addr\n\t *  15 T7 = unlock2_cmd */\n\n\tstatic const uint32_t mips_word_16_code[] = {\n\t\t/* start:\t*/\n\t\tMIPS32_LHU(0, 9, 0, 4),\t\t/* lhu $t1, ($a0)\t\t; out = &saddr */\n\t\tMIPS32_ADDI(0, 4, 4, 2),\t/* addi $a0, $a0, 2\t\t; saddr += 2 */\n\t\tMIPS32_SH(0, 13, 0, 12),\t/* sh $t5, ($t4)\t\t; *fl_unl_addr1 = fl_unl_cmd1 */\n\t\tMIPS32_SH(0, 15, 0, 14),\t/* sh $t7, ($t6)\t\t; *fl_unl_addr2 = fl_unl_cmd2 */\n\t\tMIPS32_SH(0, 7, 0, 12),\t\t/* sh $a3, ($t4)\t\t; *fl_unl_addr1 = fl_write_cmd */\n\t\tMIPS32_SH(0, 9, 0, 5),\t\t/* sh $t1, ($a1)\t\t; *daddr = out */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\t\t/* busy:\t*/\n\t\tMIPS32_LHU(0, 10, 0, 5),\t\t/* lhu $t2, ($a1)\t\t; temp1 = *daddr */\n\t\tMIPS32_XOR(0, 11, 9, 10),\t\t/* xor $t3, $a0, $t2\t; temp2 = out ^ temp1; */\n\t\tMIPS32_AND(0, 11, 8, 11),\t\t/* and $t3, $t0, $t3\t; temp2 = temp2 & DQ7mask */\n\t\tMIPS32_BNE(0, 11, 8, 13),\t\t/* bne $t3, $t0, cont\t; if (temp2 != DQ7mask) goto cont */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop\t\t\t\t\t*/\n\n\t\tMIPS32_SRL(0, 10, 8, 2),\t\t/* srl $t2,$t0,2\t\t; temp1 = DQ7mask >> 2 */\n\t\tMIPS32_AND(0, 11, 10, 11),\t\t\t/* and $t3, $t2, $t3\t; temp2 = temp2 & temp1\t*/\n\t\tMIPS32_BNE(0, 11, 10, NEG16(8)),\t/* bne $t3, $t2, busy\t; if (temp2 != temp1) goto busy\t*/\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop\t\t\t\t\t*/\n\n\t\tMIPS32_LHU(0, 10, 0, 5),\t\t/* lhu $t2, ($a1)\t\t; temp1 = *daddr */\n\t\tMIPS32_XOR(0, 11, 9, 10),\t\t/* xor $t3, $a0, $t2\t; temp2 = out ^ temp1; */\n\t\tMIPS32_AND(0, 11, 8, 11),\t\t/* and $t3, $t0, $t3\t; temp2 = temp2 & DQ7mask */\n\t\tMIPS32_BNE(0, 11, 8, 4),\t\t/* bne $t3, $t0, cont\t; if (temp2 != DQ7mask) goto cont */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\n\t\tMIPS32_XOR(0, 9, 9, 9),\t\t\t/* xor $t1, $t1, $t1\t; out = 0 */\n\t\tMIPS32_BEQ(0, 9, 0, 11),\t\t\t/* beq $t1, $zero, done\t; if (out == 0) goto done */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\t\t/* cont:\t*/\n\t\tMIPS32_ADDI(0, 6, 6, NEG16(1)),\t/* addi, $a2, $a2, -1\t; numwrites-- */\n\t\tMIPS32_BNE(0, 6, 0, 5),\t\t/* bne $a2, $zero, cont2\t; if (numwrite != 0) goto cont2 */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\n\t\tMIPS32_LUI(0, 9, 0),\t\t\t\t/* lui $t1, 0 */\n\t\tMIPS32_ORI(0, 9, 9, 0x80),\t\t\t/* ori $t1, $t1, 0x80\t; out = 0x80 */\n\n\t\tMIPS32_B(0, 4),\t\t\t\t\t/* b done\t\t\t; goto done */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\t\t/* cont2:\t*/\n\t\tMIPS32_ADDI(0, 5, 5, 2),\t\t\t/* addi $a0, $a0, 2\t; daddr += 2 */\n\t\tMIPS32_B(0, NEG16(33)),\t\t\t/* b start\t\t\t; goto start */\n\t\tMIPS32_NOP,\t\t\t\t\t\t/* nop */\n\t\t/* done: */\n\t\tMIPS32_SDBBP(0),\t\t\t\t\t/* sdbbp\t\t\t; break(); */\n\t};\n\n\tmips32_info.common_magic = MIPS32_COMMON_MAGIC;\n\tmips32_info.isa_mode = MIPS32_ISA_MIPS32;\n\n\tint target_code_size = 0;\n\tconst uint32_t *target_code_src = NULL;\n\n\tswitch (bank->bus_width) {\n\t\tcase 2:\n\t\t\t/* Check for DQ5 support */\n\t\t\tif (cfi_info->status_poll_mask & (1 << 5)) {\n\t\t\t\ttarget_code_src = mips_word_16_code;\n\t\t\t\ttarget_code_size = sizeof(mips_word_16_code);\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"Need DQ5 support\");\n\t\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\t\t/* target_code_src = mips_word_16_code_dq7only; */\n\t\t\t\t/* target_code_size = sizeof(mips_word_16_code_dq7only); */\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported bank buswidth %u, can't do block memory writes\",\n\t\t\t\t\tbank->bus_width);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* flash write code */\n\tuint8_t *target_code;\n\n\t/* convert bus-width dependent algorithm code to correct endianness */\n\ttarget_code = malloc(target_code_size);\n\tif (!target_code) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src);\n\n\t/* allocate working area */\n\tretval = target_alloc_working_area(target, target_code_size,\n\t\t\t&write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tfree(target_code);\n\t\treturn retval;\n\t}\n\n\t/* write algorithm code to working area */\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\ttarget_code_size, target_code);\n\tif (retval != ERROR_OK) {\n\t\tfree(target_code);\n\t\treturn retval;\n\t}\n\n\tfree(target_code);\n\n\t/* the following code still assumes target code is fixed 24*4 bytes */\n\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\n\t\t\t\t\"not enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r4\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r5\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r6\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r7\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r8\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[5], \"r9\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[6], \"r12\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[7], \"r13\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[8], \"r14\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[9], \"r15\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0));\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80));\n\t\tbuf_set_u32(reg_params[6].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\t\tbuf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa);\n\t\tbuf_set_u32(reg_params[8].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock2));\n\t\tbuf_set_u32(reg_params[9].value, 0, 32, 0x55555555);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 10, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\twrite_algorithm->address + ((target_code_size) - 4),\n\t\t\t\t10000, &mips32_info);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tstatus = buf_get_u32(reg_params[5].value, 0, 32);\n\t\tif (status != 0x80) {\n\t\t\tLOG_ERROR(\"flash write block failed status: 0x%\" PRIx32, status);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_all_working_areas(target);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\tdestroy_reg_param(&reg_params[6]);\n\tdestroy_reg_param(&reg_params[7]);\n\tdestroy_reg_param(&reg_params[8]);\n\tdestroy_reg_param(&reg_params[9]);\n\n\treturn retval;\n}\n\nstatic int cfi_spansion_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t address, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\tstruct target *target = bank->target;\n\tstruct reg_param reg_params[10];\n\tvoid *arm_algo;\n\tstruct arm_algorithm armv4_5_algo;\n\tstruct armv7m_algorithm armv7m_algo;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t buffer_size = 32768;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* input parameters -\n\t *\tR0 = source address\n\t *\tR1 = destination address\n\t *\tR2 = number of writes\n\t *\tR3 = flash write command\n\t *\tR4 = constant to mask DQ7 bits (also used for Dq5 with shift)\n\t * output parameters -\n\t *\tR5 = 0x80 ok 0x00 bad\n\t * temp registers -\n\t *\tR6 = value read from flash to test status\n\t *\tR7 = holding register\n\t * unlock registers -\n\t *  R8 = unlock1_addr\n\t *  R9 = unlock1_cmd\n\t *  R10 = unlock2_addr\n\t *  R11 = unlock2_cmd */\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_span_32.s for src */\n\tstatic const uint32_t armv4_5_word_32_code[] = {\n\t\t/* 00008100 <sp_32_code>:\t\t*/\n\t\t0xe4905004,\t\t/* ldr\tr5, [r0], #4\t\t\t*/\n\t\t0xe5889000,\t\t/* str\tr9, [r8]\t\t\t\t*/\n\t\t0xe58ab000,\t\t/* str\tr11, [r10]\t\t\t\t*/\n\t\t0xe5883000,\t\t/* str\tr3, [r8]\t\t\t\t*/\n\t\t0xe5815000,\t\t/* str\tr5, [r1]\t\t\t\t*/\n\t\t0xe1a00000,\t\t/* nop\t\t\t\t\t\t\t*/\n\t\t/* 00008110 <sp_32_busy>:\t\t*/\n\t\t0xe5916000,\t\t/* ldr\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000007,\t\t/* beq\t8140 <sp_32_cont> ; b if DQ7 == Data7 */\n\t\t0xe0166124,\t\t/* ands\tr6, r6, r4, lsr #2\t\t*/\n\t\t0x0afffff9,\t\t/* beq\t8110 <sp_32_busy> ;\tb if DQ5 low */\n\t\t0xe5916000,\t\t/* ldr\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000001,\t\t/* beq\t8140 <sp_32_cont> ; b if DQ7 == Data7 */\n\t\t0xe3a05000,\t\t/* mov\tr5, #0\t; 0x0 - return 0x00, error */\n\t\t0x1a000004,\t\t/* bne\t8154 <sp_32_done>\t\t*/\n\t\t/* 00008140 <sp_32_cont>:\t\t*/\n\t\t0xe2522001,\t\t/* subs\tr2, r2, #1\t; 0x1\t\t*/\n\t\t0x03a05080,\t\t/* moveq\tr5, #128\t; 0x80\t*/\n\t\t0x0a000001,\t\t/* beq\t8154 <sp_32_done>\t\t*/\n\t\t0xe2811004,\t\t/* add\tr1, r1, #4\t; 0x4\t\t*/\n\t\t0xeaffffe8,\t\t/* b\t8100 <sp_32_code>\t\t*/\n\t\t/* 00008154 <sp_32_done>:\t\t*/\n\t\t0xeafffffe\t\t/* b\t8154 <sp_32_done>\t\t*/\n\t};\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_span_16.s for src */\n\tstatic const uint32_t armv4_5_word_16_code[] = {\n\t\t/* 00008158 <sp_16_code>:\t\t*/\n\t\t0xe0d050b2,\t\t/* ldrh\tr5, [r0], #2\t\t\t*/\n\t\t0xe1c890b0,\t\t/* strh\tr9, [r8]\t\t\t\t*/\n\t\t0xe1cab0b0,\t\t/* strh\tr11, [r10]\t\t\t\t*/\n\t\t0xe1c830b0,\t\t/* strh\tr3, [r8]\t\t\t\t*/\n\t\t0xe1c150b0,\t\t/* strh\tr5, [r1]\t\t\t\t*/\n\t\t0xe1a00000,\t\t/* nop\t\t\t(mov r0,r0)\t\t*/\n\t\t/* 00008168 <sp_16_busy>:\t\t*/\n\t\t0xe1d160b0,\t\t/* ldrh\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000007,\t\t/* beq\t8198 <sp_16_cont>\t\t*/\n\t\t0xe0166124,\t\t/* ands\tr6, r6, r4, lsr #2\t\t*/\n\t\t0x0afffff9,\t\t/* beq\t8168 <sp_16_busy>\t\t*/\n\t\t0xe1d160b0,\t\t/* ldrh\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000001,\t\t/* beq\t8198 <sp_16_cont>\t\t*/\n\t\t0xe3a05000,\t\t/* mov\tr5, #0\t; 0x0\t\t\t*/\n\t\t0x1a000004,\t\t/* bne\t81ac <sp_16_done>\t\t*/\n\t\t/* 00008198 <sp_16_cont>:\t\t*/\n\t\t0xe2522001,\t/* subs\tr2, r2, #1\t; 0x1\t\t*/\n\t\t0x03a05080,\t/* moveq\tr5, #128\t; 0x80\t*/\n\t\t0x0a000001,\t/* beq\t81ac <sp_16_done>\t\t*/\n\t\t0xe2811002,\t/* add\tr1, r1, #2\t; 0x2\t\t*/\n\t\t0xeaffffe8,\t/* b\t8158 <sp_16_code>\t\t*/\n\t\t/* 000081ac <sp_16_done>:\t\t*/\n\t\t0xeafffffe\t\t/* b\t81ac <sp_16_done>\t\t*/\n\t};\n\n\t/* see contrib/loaders/flash/armv7m_cfi_span_16.s for src */\n\tstatic const uint32_t armv7m_word_16_code[] = {\n\t\t0x5B02F830,\n\t\t0x9000F8A8,\n\t\t0xB000F8AA,\n\t\t0x3000F8A8,\n\t\t0xBF00800D,\n\t\t0xEA85880E,\n\t\t0x40270706,\n\t\t0xEA16D00A,\n\t\t0xD0F70694,\n\t\t0xEA85880E,\n\t\t0x40270706,\n\t\t0xF04FD002,\n\t\t0xD1070500,\n\t\t0xD0023A01,\n\t\t0x0102F101,\n\t\t0xF04FE7E0,\n\t\t0xE7FF0580,\n\t\t0x0000BE00\n\t};\n\n\t/* see contrib/loaders/flash/armv7m_cfi_span_16_dq7.s for src */\n\tstatic const uint32_t armv7m_word_16_code_dq7only[] = {\n\t\t/* 00000000 <code>: */\n\t\t0x5B02F830,\t\t/* ldrh.w\tr5, [r0], #2\t*/\n\t\t0x9000F8A8,\t\t/* strh.w\tr9, [r8]\t\t*/\n\t\t0xB000F8AA,\t\t/* strh.w\tfp, [sl]\t\t*/\n\t\t0x3000F8A8,\t\t/* strh.w\tr3, [r8]\t\t*/\n\t\t0xBF00800D,\t\t/* strh\tr5, [r1, #0]\t\t*/\n\t\t\t\t\t\t/* nop\t\t\t\t\t\t*/\n\n\t\t/* 00000014 <busy>: */\n\t\t0xEA85880E,\t\t/* ldrh\tr6, [r1, #0]\t\t*/\n\t\t\t\t\t\t/* eor.w\tr7, r5, r6\t\t*/\n\t\t0x40270706,\t\t/* ands\t\tr7, r4\t\t\t*/\n\t\t0x3A01D1FA,\t\t/* bne.n\t14 <busy>\t\t*/\n\t\t\t\t\t\t/* subs\tr2, #1\t\t\t\t*/\n\t\t0xF101D002,\t\t/* beq.n\t28 <success>\t*/\n\t\t0xE7EB0102,\t\t/* add.w\tr1, r1, #2\t\t*/\n\t\t\t\t\t\t/* b.n\t0 <code>\t\t\t*/\n\n\t\t/* 00000028 <success>: */\n\t\t0x0580F04F,\t\t/* mov.w\tr5, #128\t\t*/\n\t\t0xBF00E7FF,\t\t/* b.n\t30 <done>\t\t\t*/\n\t\t\t\t\t\t/* nop (for alignment purposes)\t*/\n\n\t\t/* 00000030 <done>: */\n\t\t0x0000BE00\t\t/* bkpt\t0x0000\t\t\t\t*/\n\t};\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_span_16_dq7.s for src */\n\tstatic const uint32_t armv4_5_word_16_code_dq7only[] = {\n\t\t/* <sp_16_code>:\t\t\t\t*/\n\t\t0xe0d050b2,\t\t/* ldrh r5, [r0], #2\t\t\t*/\n\t\t0xe1c890b0,\t\t/* strh r9, [r8]\t\t\t\t*/\n\t\t0xe1cab0b0,\t\t/* strh\tr11, [r10]\t\t\t\t*/\n\t\t0xe1c830b0,\t\t/* strh\tr3, [r8]\t\t\t\t*/\n\t\t0xe1c150b0,\t\t/* strh\tr5, [r1]\t\t\t\t*/\n\t\t0xe1a00000,\t\t/* nop\t\t\t(mov r0,r0)\t\t*/\n\t\t/* <sp_16_busy>:\t\t\t\t*/\n\t\t0xe1d160b0,\t\t/* ldrh\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe2177080,\t\t/* ands\tr7, #0x80\t\t\t\t*/\n\t\t0x1afffffb,\t\t/* bne\t8168 <sp_16_busy>\t\t*/\n\t\t/*\t\t\t\t\t\t\t\t*/\n\t\t0xe2522001,\t\t/* subs\tr2, r2, #1\t; 0x1\t\t*/\n\t\t0x03a05080,\t\t/* moveq\tr5, #128\t; 0x80\t*/\n\t\t0x0a000001,\t\t/* beq\t81ac <sp_16_done>\t\t*/\n\t\t0xe2811002,\t\t/* add\tr1, r1, #2\t; 0x2\t\t*/\n\t\t0xeafffff0,\t\t/* b\t8158 <sp_16_code>\t\t*/\n\t\t/* 000081ac <sp_16_done>:\t\t*/\n\t\t0xeafffffe\t\t/* b\t81ac <sp_16_done>\t\t*/\n\t};\n\n\t/* see contrib/loaders/flash/armv4_5_cfi_span_8.s for src */\n\tstatic const uint32_t armv4_5_word_8_code[] = {\n\t\t/* 000081b0 <sp_16_code_end>:\t*/\n\t\t0xe4d05001,\t\t/* ldrb\tr5, [r0], #1\t\t\t*/\n\t\t0xe5c89000,\t\t/* strb\tr9, [r8]\t\t\t\t*/\n\t\t0xe5cab000,\t\t/* strb\tr11, [r10]\t\t\t\t*/\n\t\t0xe5c83000,\t\t/* strb\tr3, [r8]\t\t\t\t*/\n\t\t0xe5c15000,\t\t/* strb\tr5, [r1]\t\t\t\t*/\n\t\t0xe1a00000,\t\t/* nop\t\t\t(mov r0,r0)\t\t*/\n\t\t/* 000081c0 <sp_8_busy>:\t\t*/\n\t\t0xe5d16000,\t\t/* ldrb\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000007,\t\t/* beq\t81f0 <sp_8_cont>\t\t*/\n\t\t0xe0166124,\t\t/* ands\tr6, r6, r4, lsr #2\t\t*/\n\t\t0x0afffff9,\t\t/* beq\t81c0 <sp_8_busy>\t\t*/\n\t\t0xe5d16000,\t\t/* ldrb\tr6, [r1]\t\t\t\t*/\n\t\t0xe0257006,\t\t/* eor\tr7, r5, r6\t\t\t\t*/\n\t\t0xe0147007,\t\t/* ands\tr7, r4, r7\t\t\t\t*/\n\t\t0x0a000001,\t\t/* beq\t81f0 <sp_8_cont>\t\t*/\n\t\t0xe3a05000,\t\t/* mov\tr5, #0\t; 0x0\t\t\t*/\n\t\t0x1a000004,\t\t/* bne\t8204 <sp_8_done>\t\t*/\n\t\t/* 000081f0 <sp_8_cont>:\t\t*/\n\t\t0xe2522001,\t\t/* subs\tr2, r2, #1\t; 0x1\t\t*/\n\t\t0x03a05080,\t\t/* moveq\tr5, #128\t; 0x80\t*/\n\t\t0x0a000001,\t\t/* beq\t8204 <sp_8_done>\t\t*/\n\t\t0xe2811001,\t\t/* add\tr1, r1, #1\t; 0x1\t\t*/\n\t\t0xeaffffe8,\t\t/* b\t81b0 <sp_16_code_end>\t*/\n\t\t/* 00008204 <sp_8_done>:\t\t*/\n\t\t0xeafffffe\t\t/* b\t8204 <sp_8_done>\t\t*/\n\t};\n\n\tif (strncmp(target_type_name(target), \"mips_m4k\", 8) == 0)\n\t\treturn cfi_spansion_write_block_mips(bank, buffer, address, count);\n\n\tif (is_armv7m(target_to_armv7m(target))) {\t/* armv7m target */\n\t\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\t\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\t\tarm_algo = &armv7m_algo;\n\t} else if (is_arm(target_to_arm(target))) {\n\t\t/* All other ARM CPUs have 32 bit instructions */\n\t\tarmv4_5_algo.common_magic = ARM_COMMON_MAGIC;\n\t\tarmv4_5_algo.core_mode = ARM_MODE_SVC;\n\t\tarmv4_5_algo.core_state = ARM_STATE_ARM;\n\t\tarm_algo = &armv4_5_algo;\n\t} else {\n\t\tLOG_ERROR(\"Unknown architecture\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tint target_code_size = 0;\n\tconst uint32_t *target_code_src = NULL;\n\n\tswitch (bank->bus_width) {\n\t\tcase 1:\n\t\t\tif (is_armv7m(target_to_armv7m(target))) {\n\t\t\t\tLOG_ERROR(\"Unknown ARM architecture\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ttarget_code_src = armv4_5_word_8_code;\n\t\t\ttarget_code_size = sizeof(armv4_5_word_8_code);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t/* Check for DQ5 support */\n\t\t\tif (cfi_info->status_poll_mask & (1 << 5)) {\n\t\t\t\tif (is_armv7m(target_to_armv7m(target))) {\n\t\t\t\t\t/* armv7m target */\n\t\t\t\t\ttarget_code_src = armv7m_word_16_code;\n\t\t\t\t\ttarget_code_size = sizeof(armv7m_word_16_code);\n\t\t\t\t} else { /* armv4_5 target */\n\t\t\t\t\ttarget_code_src = armv4_5_word_16_code;\n\t\t\t\t\ttarget_code_size = sizeof(armv4_5_word_16_code);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* No DQ5 support. Use DQ7 DATA# polling only. */\n\t\t\t\tif (is_armv7m(target_to_armv7m(target))) {\n\t\t\t\t\t/* armv7m target */\n\t\t\t\t\ttarget_code_src = armv7m_word_16_code_dq7only;\n\t\t\t\t\ttarget_code_size = sizeof(armv7m_word_16_code_dq7only);\n\t\t\t\t} else { /* armv4_5 target */\n\t\t\t\t\ttarget_code_src = armv4_5_word_16_code_dq7only;\n\t\t\t\t\ttarget_code_size = sizeof(armv4_5_word_16_code_dq7only);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tif (is_armv7m(target_to_armv7m(target))) {\n\t\t\t\tLOG_ERROR(\"Unknown ARM architecture\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ttarget_code_src = armv4_5_word_32_code;\n\t\t\ttarget_code_size = sizeof(armv4_5_word_32_code);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported bank buswidth %u, can't do block memory writes\",\n\t\t\t\t\tbank->bus_width);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* flash write code */\n\tuint8_t *target_code;\n\n\t/* convert bus-width dependent algorithm code to correct endianness */\n\ttarget_code = malloc(target_code_size);\n\tif (!target_code) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_buffer_set_u32_array(target, target_code, target_code_size / 4, target_code_src);\n\n\t/* allocate working area */\n\tretval = target_alloc_working_area(target, target_code_size,\n\t\t\t&write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tfree(target_code);\n\t\treturn retval;\n\t}\n\n\t/* write algorithm code to working area */\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\ttarget_code_size, target_code);\n\tif (retval != ERROR_OK) {\n\t\tfree(target_code);\n\t\treturn retval;\n\t}\n\n\tfree(target_code);\n\n\t/* the following code still assumes target code is fixed 24*4 bytes */\n\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\n\t\t\t\t\"not enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[6], \"r8\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[7], \"r9\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[8], \"r10\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[9], \"r11\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > buffer_size) ? buffer_size : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count / bank->bus_width);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, cfi_command_val(bank, 0xA0));\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, cfi_command_val(bank, 0x80));\n\t\tbuf_set_u32(reg_params[6].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\t\tbuf_set_u32(reg_params[7].value, 0, 32, 0xaaaaaaaa);\n\t\tbuf_set_u32(reg_params[8].value, 0, 32, cfi_flash_address(bank, 0, pri_ext->_unlock2));\n\t\tbuf_set_u32(reg_params[9].value, 0, 32, 0x55555555);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 10, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\twrite_algorithm->address + ((target_code_size) - 4),\n\t\t\t\t10000, arm_algo);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tstatus = buf_get_u32(reg_params[5].value, 0, 32);\n\t\tif (status != 0x80) {\n\t\t\tLOG_ERROR(\"flash write block failed status: 0x%\" PRIx32, status);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count;\n\t\taddress += thisrun_count;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_all_working_areas(target);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\tdestroy_reg_param(&reg_params[6]);\n\tdestroy_reg_param(&reg_params[7]);\n\tdestroy_reg_param(&reg_params[8]);\n\tdestroy_reg_param(&reg_params[9]);\n\n\treturn retval;\n}\n\nstatic int cfi_intel_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tcfi_intel_clear_status_register(bank);\n\tretval = cfi_send_command(bank, 0x40, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_target_write_memory(bank, address, 1, word);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t status;\n\tretval = cfi_intel_wait_status_busy(bank, cfi_info->word_write_timeout, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (status != 0x80) {\n\t\tretval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"couldn't write word at base \" TARGET_ADDR_FMT\n\t\t\t\t\", address 0x%\" PRIx32,\n\t\t\t\tbank->base, address);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_intel_write_words(struct flash_bank *bank, const uint8_t *word,\n\tuint32_t wordcount, uint32_t address)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\t/* Calculate buffer size and boundary mask\n\t * buffersize is (buffer size per chip) * (number of chips)\n\t * bufferwsize is buffersize in words */\n\tuint32_t buffersize =\n\t\t(1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);\n\tuint32_t buffermask = buffersize-1;\n\tuint32_t bufferwsize = buffersize / bank->bus_width;\n\n\t/* Check for valid range */\n\tif (address & buffermask) {\n\t\tLOG_ERROR(\"Write address at base \" TARGET_ADDR_FMT \", address 0x%\"\n\t\t\t\tPRIx32 \" not aligned to 2^%d boundary\",\n\t\t\t\tbank->base, address, cfi_info->max_buf_write_size);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Check for valid size */\n\tif (wordcount > bufferwsize) {\n\t\tLOG_ERROR(\"Number of data words %\" PRIu32 \" exceeds available buffersize %\" PRIu32,\n\t\t\twordcount, buffersize);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Write to flash buffer */\n\tcfi_intel_clear_status_register(bank);\n\n\t/* Initiate buffer operation _*/\n\tretval = cfi_send_command(bank, 0xe8, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tuint8_t status;\n\tretval = cfi_intel_wait_status_busy(bank, cfi_info->buf_write_timeout, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (status != 0x80) {\n\t\tretval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\n\t\t\t\"couldn't start buffer write operation at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32,\n\t\t\tbank->base,\n\t\t\taddress);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Write buffer wordcount-1 and data words */\n\tretval = cfi_send_command(bank, bufferwsize-1, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_target_write_memory(bank, address, bufferwsize, word);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Commit write operation */\n\tretval = cfi_send_command(bank, 0xd0, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_intel_wait_status_busy(bank, cfi_info->buf_write_timeout, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (status != 0x80) {\n\t\tretval = cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"Buffer write at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32 \" failed.\", bank->base, address);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_spansion_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tretval = cfi_spansion_unlock_seq(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_send_command(bank, 0xa0, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_target_write_memory(bank, address, 1, word);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) {\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"couldn't write word at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32, bank->base, address);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_spansion_write_words(struct flash_bank *bank, const uint8_t *word,\n\tuint32_t wordcount, uint32_t address)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\t/* Calculate buffer size and boundary mask\n\t * buffersize is (buffer size per chip) * (number of chips)\n\t * bufferwsize is buffersize in words */\n\tuint32_t buffersize =\n\t\t(1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);\n\tuint32_t buffermask = buffersize-1;\n\tuint32_t bufferwsize = buffersize / bank->bus_width;\n\n\t/* Check for valid range */\n\tif (address & buffermask) {\n\t\tLOG_ERROR(\"Write address at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32 \" not aligned to 2^%d boundary\",\n\t\t\tbank->base, address, cfi_info->max_buf_write_size);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Check for valid size */\n\tif (wordcount > bufferwsize) {\n\t\tLOG_ERROR(\"Number of data words %\" PRIu32 \" exceeds available buffersize %\"\n\t\t\tPRIu32, wordcount, buffersize);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Unlock */\n\tretval = cfi_spansion_unlock_seq(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Buffer load command */\n\tretval = cfi_send_command(bank, 0x25, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write buffer wordcount-1 and data words */\n\tretval = cfi_send_command(bank, bufferwsize-1, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_target_write_memory(bank, address, bufferwsize, word);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Commit write operation */\n\tretval = cfi_send_command(bank, 0x29, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_spansion_wait_status_busy(bank, cfi_info->buf_write_timeout) != ERROR_OK) {\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"couldn't write block at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32 \", size 0x%\" PRIx32, bank->base, address,\n\t\t\tbufferwsize);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tswitch (cfi_info->pri_id) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn cfi_intel_write_word(bank, word, address);\n\t\tcase 2:\n\t\t\treturn cfi_spansion_write_word(bank, word, address);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int cfi_write_words(struct flash_bank *bank, const uint8_t *word,\n\tuint32_t wordcount, uint32_t address)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (cfi_info->buf_write_timeout_typ == 0) {\n\t\t/* buffer writes are not supported */\n\t\tLOG_DEBUG(\"Buffer Writes Not Supported\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tswitch (cfi_info->pri_id) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn cfi_intel_write_words(bank, word, wordcount, address);\n\t\tcase 2:\n\t\t\treturn cfi_spansion_write_words(bank, word, wordcount, address);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int cfi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint32_t address = bank->base + offset;\n\tuint32_t read_p;\n\tint align;\t/* number of unaligned bytes */\n\tuint8_t current_word[CFI_MAX_BUS_WIDTH];\n\tint retval;\n\n\tLOG_DEBUG(\"reading buffer of %i byte at 0x%8.8x\",\n\t\t(int)count, (unsigned)offset);\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* start at the first byte of the first word (bus_width size) */\n\tread_p = address & ~(bank->bus_width - 1);\n\talign = address - read_p;\n\tif (align != 0) {\n\t\tLOG_INFO(\"Fixup %d unaligned read head bytes\", align);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, read_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* take only bytes we need */\n\t\tfor (unsigned int i = align; (i < bank->bus_width) && (count > 0); i++, count--)\n\t\t\t*buffer++ = current_word[i];\n\n\t\tread_p += bank->bus_width;\n\t}\n\n\talign = count / bank->bus_width;\n\tif (align) {\n\t\tretval = cfi_target_read_memory(bank, read_p, align, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tread_p += align * bank->bus_width;\n\t\tbuffer += align * bank->bus_width;\n\t\tcount -= align * bank->bus_width;\n\t}\n\n\tif (count) {\n\t\tLOG_INFO(\"Fixup %\" PRIu32 \" unaligned read tail bytes\", count);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, read_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* take only bytes we need */\n\t\tfor (unsigned int i = 0; (i < bank->bus_width) && (count > 0); i++, count--)\n\t\t\t*buffer++ = current_word[i];\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cfi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint32_t address = bank->base + offset;\t/* address of first byte to be programmed */\n\tuint32_t write_p;\n\tint align;\t/* number of unaligned bytes */\n\tint blk_count;\t/* number of bus_width bytes for block copy */\n\tuint8_t current_word[CFI_MAX_BUS_WIDTH * 4];\t/* word (bus_width size) currently being\n\t\t\t\t\t\t\t *programmed */\n\tuint8_t *swapped_buffer = NULL;\n\tconst uint8_t *real_buffer = NULL;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* start at the first byte of the first word (bus_width size) */\n\twrite_p = address & ~(bank->bus_width - 1);\n\talign = address - write_p;\n\tif (align != 0) {\n\t\tLOG_INFO(\"Fixup %d unaligned head bytes\", align);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, write_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* replace only bytes that must be written */\n\t\tfor (unsigned int i = align; (i < bank->bus_width) && (count > 0); i++, count--)\n\t\t\tif (cfi_info->data_swap)\n\t\t\t\t/* data bytes are swapped (reverse endianness) */\n\t\t\t\tcurrent_word[bank->bus_width - i] = *buffer++;\n\t\t\telse\n\t\t\t\tcurrent_word[i] = *buffer++;\n\n\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twrite_p += bank->bus_width;\n\t}\n\n\tif (cfi_info->data_swap && count) {\n\t\tswapped_buffer = malloc(count & ~(bank->bus_width - 1));\n\t\tswitch (bank->bus_width) {\n\t\tcase 2:\n\t\t\tbuf_bswap16(swapped_buffer, buffer,\n\t\t\t\t    count & ~(bank->bus_width - 1));\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tbuf_bswap32(swapped_buffer, buffer,\n\t\t\t\t    count & ~(bank->bus_width - 1));\n\t\t\tbreak;\n\t\t}\n\t\treal_buffer = buffer;\n\t\tbuffer = swapped_buffer;\n\t}\n\n\t/* handle blocks of bus_size aligned bytes */\n\tblk_count = count & ~(bank->bus_width - 1);\t/* round down, leave tail bytes */\n\tswitch (cfi_info->pri_id) {\n\t\t/* try block writes (fails without working area) */\n\t\tcase 1:\n\t\tcase 3:\n\t\t\tretval = cfi_intel_write_block(bank, buffer, write_p, blk_count);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tretval = cfi_spansion_write_block(bank, buffer, write_p, blk_count);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t}\n\tif (retval == ERROR_OK) {\n\t\t/* Increment pointers and decrease count on successful block write */\n\t\tbuffer += blk_count;\n\t\twrite_p += blk_count;\n\t\tcount -= blk_count;\n\t} else {\n\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t/* Calculate buffer size and boundary mask\n\t\t\t * buffersize is (buffer size per chip) * (number of chips)\n\t\t\t * bufferwsize is buffersize in words */\n\t\t\tuint32_t buffersize =\n\t\t\t\t(1UL <<\n\t\t\t\t cfi_info->max_buf_write_size) *\n\t\t\t\t(bank->bus_width / bank->chip_width);\n\t\t\tuint32_t buffermask = buffersize-1;\n\t\t\tuint32_t bufferwsize = buffersize / bank->bus_width;\n\n\t\t\t/* fall back to memory writes */\n\t\t\twhile (count >= (uint32_t)bank->bus_width) {\n\t\t\t\tbool fallback;\n\t\t\t\tif ((write_p & 0xff) == 0) {\n\t\t\t\t\tLOG_INFO(\"Programming at 0x%08\" PRIx32 \", count 0x%08\"\n\t\t\t\t\t\tPRIx32 \" bytes remaining\", write_p, count);\n\t\t\t\t}\n\t\t\t\tfallback = true;\n\t\t\t\tif ((bufferwsize > 0) && (count >= buffersize) &&\n\t\t\t\t\t\t!(write_p & buffermask)) {\n\t\t\t\t\tretval = cfi_write_words(bank, buffer, bufferwsize, write_p);\n\t\t\t\t\tif (retval == ERROR_OK) {\n\t\t\t\t\t\tbuffer += buffersize;\n\t\t\t\t\t\twrite_p += buffersize;\n\t\t\t\t\t\tcount -= buffersize;\n\t\t\t\t\t\tfallback = false;\n\t\t\t\t\t} else if (retval != ERROR_FLASH_OPER_UNSUPPORTED)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t\t/* try the slow way? */\n\t\t\t\tif (fallback) {\n\t\t\t\t\tfor (unsigned int i = 0; i < bank->bus_width; i++)\n\t\t\t\t\t\tcurrent_word[i] = *buffer++;\n\n\t\t\t\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\n\t\t\t\t\twrite_p += bank->bus_width;\n\t\t\t\t\tcount -= bank->bus_width;\n\t\t\t\t}\n\t\t\t}\n\t\t} else\n\t\t\treturn retval;\n\t}\n\n\tif (swapped_buffer) {\n\t\tbuffer = real_buffer + (buffer - swapped_buffer);\n\t\tfree(swapped_buffer);\n\t}\n\n\t/* return to read array mode, so we can read from flash again for padding */\n\tretval = cfi_reset(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* handle unaligned tail bytes */\n\tif (count > 0) {\n\t\tLOG_INFO(\"Fixup %\" PRIu32 \" unaligned tail bytes\", count);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, write_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* replace only bytes that must be written */\n\t\tfor (unsigned int i = 0; (i < bank->bus_width) && (count > 0); i++, count--)\n\t\t\tif (cfi_info->data_swap)\n\t\t\t\t/* data bytes are swapped (reverse endianness) */\n\t\t\t\tcurrent_word[bank->bus_width - i] = *buffer++;\n\t\t\telse\n\t\t\t\tcurrent_word[i] = *buffer++;\n\n\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* return to read array mode */\n\treturn cfi_reset(bank);\n}\n\nstatic void cfi_fixup_reversed_erase_regions(struct flash_bank *bank, const void *param)\n{\n\t(void) param;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tpri_ext->_reversed_geometry = 1;\n}\n\nstatic void cfi_fixup_0002_erase_regions(struct flash_bank *bank, const void *param)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\t(void) param;\n\n\tif ((pri_ext->_reversed_geometry) || (pri_ext->top_bottom == 3)) {\n\t\tLOG_DEBUG(\"swapping reversed erase region information on cmdset 0002 device\");\n\n\t\tfor (unsigned int i = 0; i < cfi_info->num_erase_regions / 2; i++) {\n\t\t\tint j = (cfi_info->num_erase_regions - 1) - i;\n\t\t\tuint32_t swap;\n\n\t\t\tswap = cfi_info->erase_region_info[i];\n\t\t\tcfi_info->erase_region_info[i] = cfi_info->erase_region_info[j];\n\t\t\tcfi_info->erase_region_info[j] = swap;\n\t\t}\n\t}\n}\n\nstatic void cfi_fixup_0002_unlock_addresses(struct flash_bank *bank, const void *param)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\tconst struct cfi_unlock_addresses *unlock_addresses = param;\n\n\tpri_ext->_unlock1 = unlock_addresses->unlock1;\n\tpri_ext->_unlock2 = unlock_addresses->unlock2;\n}\n\nstatic void cfi_fixup_0002_polling_bits(struct flash_bank *bank, const void *param)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tconst int *status_poll_mask = param;\n\n\tcfi_info->status_poll_mask = *status_poll_mask;\n}\n\n\nstatic int cfi_query_string(struct flash_bank *bank, int address)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tint retval;\n\n\tretval = cfi_send_command(bank, 0x98, cfi_flash_address(bank, 0, address));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_query_u8(bank, 0, 0x10, &cfi_info->qry[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, 0x11, &cfi_info->qry[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_query_u8(bank, 0, 0x12, &cfi_info->qry[2]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"CFI qry returned: 0x%2.2x 0x%2.2x 0x%2.2x\",\n\t\tcfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2]);\n\n\tif ((cfi_info->qry[0] != 'Q') || (cfi_info->qry[1] != 'R') || (cfi_info->qry[2] != 'Y')) {\n\t\tretval = cfi_reset(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_ERROR(\"Could not probe bank: no QRY\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint cfi_probe(struct flash_bank *bank)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tunsigned int num_sectors = 0;\n\tint sector = 0;\n\tuint32_t unlock1 = 0x555;\n\tuint32_t unlock2 = 0x2aa;\n\tint retval;\n\tuint8_t value_buf0[CFI_MAX_BUS_WIDTH], value_buf1[CFI_MAX_BUS_WIDTH];\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tcfi_info->probed = false;\n\tcfi_info->num_erase_regions = 0;\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tfree(cfi_info->erase_region_info);\n\tcfi_info->erase_region_info = NULL;\n\n\t/* JEDEC standard JESD21C uses 0x5555 and 0x2aaa as unlock addresses,\n\t * while CFI compatible AMD/Spansion flashes use 0x555 and 0x2aa\n\t */\n\tif (cfi_info->jedec_probe) {\n\t\tunlock1 = 0x5555;\n\t\tunlock2 = 0x2aaa;\n\t}\n\n\t/* switch to read identifier codes mode (\"AUTOSELECT\") */\n\tretval = cfi_send_command(bank, 0xaa, cfi_flash_address(bank, 0, unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_send_command(bank, 0x55, cfi_flash_address(bank, 0, unlock2));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, 0, 0x00),\n\t\t\t\t\t1, value_buf0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cfi_target_read_memory(bank, cfi_flash_address(bank, 0, 0x01),\n\t\t\t\t\t1, value_buf1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tswitch (bank->chip_width) {\n\t\tcase 1:\n\t\t\tcfi_info->manufacturer = *value_buf0;\n\t\t\tcfi_info->device_id = *value_buf1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tcfi_info->manufacturer = target_buffer_get_u16(target, value_buf0);\n\t\t\tcfi_info->device_id = target_buffer_get_u16(target, value_buf1);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tcfi_info->manufacturer = target_buffer_get_u32(target, value_buf0);\n\t\t\tcfi_info->device_id = target_buffer_get_u32(target, value_buf1);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported bank chipwidth %u, can't probe memory\",\n\t\t\t\t\tbank->chip_width);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tLOG_INFO(\"Flash Manufacturer/Device: 0x%04x 0x%04x\",\n\t\tcfi_info->manufacturer, cfi_info->device_id);\n\t/* switch back to read array mode */\n\tretval = cfi_reset(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check device/manufacturer ID for known non-CFI flashes. */\n\tcfi_fixup_non_cfi(bank);\n\n\t/* query only if this is a CFI compatible flash,\n\t * otherwise the relevant info has already been filled in\n\t */\n\tif (!cfi_info->not_cfi) {\n\t\t/* enter CFI query mode\n\t\t * according to JEDEC Standard No. 68.01,\n\t\t * a single bus sequence with address = 0x55, data = 0x98 should put\n\t\t * the device into CFI query mode.\n\t\t *\n\t\t * SST flashes clearly violate this, and we will consider them incompatible for now\n\t\t */\n\n\t\tretval = cfi_query_string(bank, 0x55);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/*\n\t\t\t * Spansion S29WS-N CFI query fix is to try 0x555 if 0x55 fails. Should\n\t\t\t * be harmless enough:\n\t\t\t *\n\t\t\t * http://www.infradead.org/pipermail/linux-mtd/2005-September/013618.html\n\t\t\t */\n\t\t\tLOG_USER(\"Try workaround w/0x555 instead of 0x55 to get QRY.\");\n\t\t\tretval = cfi_query_string(bank, 0x555);\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_query_u16(bank, 0, 0x13, &cfi_info->pri_id);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u16(bank, 0, 0x15, &cfi_info->pri_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u16(bank, 0, 0x17, &cfi_info->alt_id);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u16(bank, 0, 0x19, &cfi_info->alt_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: 0x%4.4x, alt_id: \"\n\t\t\t\"0x%4.4x, alt_addr: 0x%4.4x\", cfi_info->qry[0], cfi_info->qry[1],\n\t\t\tcfi_info->qry[2], cfi_info->pri_id, cfi_info->pri_addr,\n\t\t\tcfi_info->alt_id, cfi_info->alt_addr);\n\n\t\tretval = cfi_query_u8(bank, 0, 0x1b, &cfi_info->vcc_min);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x1c, &cfi_info->vcc_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x1d, &cfi_info->vpp_min);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x1e, &cfi_info->vpp_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cfi_query_u8(bank, 0, 0x1f, &cfi_info->word_write_timeout_typ);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x20, &cfi_info->buf_write_timeout_typ);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x21, &cfi_info->block_erase_timeout_typ);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x22, &cfi_info->chip_erase_timeout_typ);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x23, &cfi_info->word_write_timeout_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x24, &cfi_info->buf_write_timeout_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x25, &cfi_info->block_erase_timeout_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x26, &cfi_info->chip_erase_timeout_max);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tuint8_t data;\n\t\tretval = cfi_query_u8(bank, 0, 0x27, &data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcfi_info->dev_size = 1 << data;\n\n\t\tretval = cfi_query_u16(bank, 0, 0x28, &cfi_info->interface_desc);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u16(bank, 0, 0x2a, &cfi_info->max_buf_write_size);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cfi_query_u8(bank, 0, 0x2c, &cfi_info->num_erase_regions);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"size: 0x%\" PRIx32 \", interface desc: %i, max buffer write size: 0x%x\",\n\t\t\tcfi_info->dev_size, cfi_info->interface_desc,\n\t\t\t(1 << cfi_info->max_buf_write_size));\n\n\t\tif (cfi_info->num_erase_regions) {\n\t\t\tcfi_info->erase_region_info = malloc(sizeof(*cfi_info->erase_region_info)\n\t\t\t\t\t* cfi_info->num_erase_regions);\n\t\t\tfor (unsigned int i = 0; i < cfi_info->num_erase_regions; i++) {\n\t\t\t\tretval = cfi_query_u32(bank,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0x2d + (4 * i),\n\t\t\t\t\t\t&cfi_info->erase_region_info[i]);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tLOG_DEBUG(\n\t\t\t\t\t\"erase region[%i]: %\" PRIu32 \" blocks of size 0x%\" PRIx32 \"\",\n\t\t\t\t\ti,\n\t\t\t\t\t(cfi_info->erase_region_info[i] & 0xffff) + 1,\n\t\t\t\t\t(cfi_info->erase_region_info[i] >> 16) * 256);\n\t\t\t}\n\t\t} else\n\t\t\tcfi_info->erase_region_info = NULL;\n\n\t\t/* We need to read the primary algorithm extended query table before calculating\n\t\t * the sector layout to be able to apply fixups\n\t\t */\n\t\tswitch (cfi_info->pri_id) {\n\t\t\t/* Intel command set (standard and extended) */\n\t\t\tcase 0x0001:\n\t\t\tcase 0x0003:\n\t\t\t\tcfi_read_intel_pri_ext(bank);\n\t\t\t\tbreak;\n\t\t\t/* AMD/Spansion, Atmel, ... command set */\n\t\t\tcase 0x0002:\n\t\t\t\tcfi_info->status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7;\t/*\n\t\t\t\t\t\t\t\t\t\t\t\t *default\n\t\t\t\t\t\t\t\t\t\t\t\t *for\n\t\t\t\t\t\t\t\t\t\t\t\t *all\n\t\t\t\t\t\t\t\t\t\t\t\t *CFI\n\t\t\t\t\t\t\t\t\t\t\t\t *flashes\n\t\t\t\t\t\t\t\t\t\t\t\t **/\n\t\t\t\tcfi_read_0002_pri_ext(bank);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* return to read array mode\n\t\t * we use both reset commands, as some Intel flashes fail to recognize the 0xF0 command\n\t\t */\n\t\tretval = cfi_reset(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\t/* end CFI case */\n\n\tLOG_DEBUG(\"Vcc min: %x.%x, Vcc max: %x.%x, Vpp min: %u.%x, Vpp max: %u.%x\",\n\t\t(cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,\n\t\t(cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,\n\t\t(cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,\n\t\t(cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);\n\n\tLOG_DEBUG(\"typ. word write timeout: %u us, typ. buf write timeout: %u us, \"\n\t\t\"typ. block erase timeout: %u ms, typ. chip erase timeout: %u ms\",\n\t\t1 << cfi_info->word_write_timeout_typ, 1 << cfi_info->buf_write_timeout_typ,\n\t\t1 << cfi_info->block_erase_timeout_typ, 1 << cfi_info->chip_erase_timeout_typ);\n\n\tLOG_DEBUG(\"max. word write timeout: %u us, max. buf write timeout: %u us, \"\n\t\t\"max. block erase timeout: %u ms, max. chip erase timeout: %u ms\",\n\t\t(1 << cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ),\n\t\t(1 << cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),\n\t\t(1 << cfi_info->block_erase_timeout_max) * (1 << cfi_info->block_erase_timeout_typ),\n\t\t(1 << cfi_info->chip_erase_timeout_max) * (1 << cfi_info->chip_erase_timeout_typ));\n\n\t/* convert timeouts to real values in ms */\n\tcfi_info->word_write_timeout = DIV_ROUND_UP((1L << cfi_info->word_write_timeout_typ) *\n\t\t\t(1L << cfi_info->word_write_timeout_max), 1000);\n\tcfi_info->buf_write_timeout = DIV_ROUND_UP((1L << cfi_info->buf_write_timeout_typ) *\n\t\t\t(1L << cfi_info->buf_write_timeout_max), 1000);\n\tcfi_info->block_erase_timeout = (1L << cfi_info->block_erase_timeout_typ) *\n\t\t(1L << cfi_info->block_erase_timeout_max);\n\tcfi_info->chip_erase_timeout = (1L << cfi_info->chip_erase_timeout_typ) *\n\t\t(1L << cfi_info->chip_erase_timeout_max);\n\n\tLOG_DEBUG(\"calculated word write timeout: %u ms, buf write timeout: %u ms, \"\n\t\t\"block erase timeout: %u ms, chip erase timeout: %u ms\",\n\t\tcfi_info->word_write_timeout, cfi_info->buf_write_timeout,\n\t\tcfi_info->block_erase_timeout, cfi_info->chip_erase_timeout);\n\n\t/* apply fixups depending on the primary command set */\n\tswitch (cfi_info->pri_id) {\n\t\t/* Intel command set (standard and extended) */\n\t\tcase 0x0001:\n\t\tcase 0x0003:\n\t\t\tcfi_fixup(bank, cfi_0001_fixups);\n\t\t\tbreak;\n\t\t/* AMD/Spansion, Atmel, ... command set */\n\t\tcase 0x0002:\n\t\t\tcfi_fixup(bank, cfi_0002_fixups);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tbreak;\n\t}\n\n\tif ((cfi_info->dev_size * bank->bus_width / bank->chip_width) != bank->size) {\n\t\tLOG_WARNING(\"configuration specifies 0x%\" PRIx32 \" size, but a 0x%\" PRIx32\n\t\t\t\" size flash was found\", bank->size, cfi_info->dev_size);\n\t}\n\n\tif (cfi_info->num_erase_regions == 0) {\n\t\t/* a device might have only one erase block, spanning the whole device */\n\t\tbank->num_sectors = 1;\n\t\tbank->sectors = malloc(sizeof(struct flash_sector));\n\n\t\tbank->sectors[sector].offset = 0x0;\n\t\tbank->sectors[sector].size = bank->size;\n\t\tbank->sectors[sector].is_erased = -1;\n\t\tbank->sectors[sector].is_protected = -1;\n\t} else {\n\t\tuint32_t offset = 0;\n\n\t\tfor (unsigned int i = 0; i < cfi_info->num_erase_regions; i++)\n\t\t\tnum_sectors += (cfi_info->erase_region_info[i] & 0xffff) + 1;\n\n\t\tbank->num_sectors = num_sectors;\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\n\t\tfor (unsigned int i = 0; i < cfi_info->num_erase_regions; i++) {\n\t\t\tfor (uint32_t j = 0; j < (cfi_info->erase_region_info[i] & 0xffff) + 1; j++) {\n\t\t\t\tbank->sectors[sector].offset = offset;\n\t\t\t\tbank->sectors[sector].size =\n\t\t\t\t\t((cfi_info->erase_region_info[i] >> 16) * 256)\n\t\t\t\t\t* bank->bus_width / bank->chip_width;\n\t\t\t\toffset += bank->sectors[sector].size;\n\t\t\t\tbank->sectors[sector].is_erased = -1;\n\t\t\t\tbank->sectors[sector].is_protected = -1;\n\t\t\t\tsector++;\n\t\t\t}\n\t\t}\n\t\tif (offset != (cfi_info->dev_size * bank->bus_width / bank->chip_width)) {\n\t\t\tLOG_WARNING(\n\t\t\t\t\"CFI size is 0x%\" PRIx32 \", but total sector size is 0x%\" PRIx32 \"\",\n\t\t\t\t(cfi_info->dev_size * bank->bus_width / bank->chip_width),\n\t\t\t\toffset);\n\t\t}\n\t}\n\n\tcfi_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nint cfi_auto_probe(struct flash_bank *bank)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tif (cfi_info->probed)\n\t\treturn ERROR_OK;\n\treturn cfi_probe(bank);\n}\n\nstatic int cfi_intel_protect_check(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_intel_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\t/* check if block lock bits are supported on this device */\n\tif (!(pri_ext->blk_status_reg_mask & 0x1))\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tretval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, 0x55));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint8_t block_status;\n\t\tretval = cfi_get_u8(bank, i, 0x2, &block_status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (block_status & 1)\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\treturn cfi_send_command(bank, 0xff, cfi_flash_address(bank, 0, 0x0));\n}\n\nstatic int cfi_spansion_protect_check(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\tretval = cfi_spansion_unlock_seq(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_send_command(bank, 0x90, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint8_t block_status;\n\t\tretval = cfi_get_u8(bank, i, 0x2, &block_status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (block_status & 1)\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\treturn cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n}\n\nint cfi_protect_check(struct flash_bank *bank)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tswitch (cfi_info->pri_id) {\n\t\tcase 1:\n\t\tcase 3:\n\t\t\treturn cfi_intel_protect_check(bank);\n\t\tcase 2:\n\t\t\treturn cfi_spansion_protect_check(bank);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint cfi_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\tif (cfi_info->qry[0] == 0xff) {\n\t\tcommand_print_sameline(cmd, \"\\ncfi flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!cfi_info->not_cfi)\n\t\tcommand_print_sameline(cmd, \"\\nCFI flash: \");\n\telse\n\t\tcommand_print_sameline(cmd, \"\\nnon-CFI flash: \");\n\n\tcommand_print_sameline(cmd, \"mfr: 0x%4.4x, id:0x%4.4x\\n\",\n\t\t\tcfi_info->manufacturer, cfi_info->device_id);\n\n\tcommand_print_sameline(cmd, \"qry: '%c%c%c', pri_id: 0x%4.4x, pri_addr: \"\n\t\t\t\"0x%4.4x, alt_id: 0x%4.4x, alt_addr: 0x%4.4x\\n\",\n\t\t\tcfi_info->qry[0], cfi_info->qry[1], cfi_info->qry[2],\n\t\t\tcfi_info->pri_id, cfi_info->pri_addr, cfi_info->alt_id, cfi_info->alt_addr);\n\n\tcommand_print_sameline(cmd, \"Vcc min: %x.%x, Vcc max: %x.%x, \"\n\t\t\t\"Vpp min: %u.%x, Vpp max: %u.%x\\n\",\n\t\t\t(cfi_info->vcc_min & 0xf0) >> 4, cfi_info->vcc_min & 0x0f,\n\t\t\t(cfi_info->vcc_max & 0xf0) >> 4, cfi_info->vcc_max & 0x0f,\n\t\t\t(cfi_info->vpp_min & 0xf0) >> 4, cfi_info->vpp_min & 0x0f,\n\t\t\t(cfi_info->vpp_max & 0xf0) >> 4, cfi_info->vpp_max & 0x0f);\n\n\tcommand_print_sameline(cmd, \"typ. word write timeout: %u us, \"\n\t\t\t\"typ. buf write timeout: %u us, \"\n\t\t\t\"typ. block erase timeout: %u ms, \"\n\t\t\t\"typ. chip erase timeout: %u ms\\n\",\n\t\t\t1 << cfi_info->word_write_timeout_typ,\n\t\t\t1 << cfi_info->buf_write_timeout_typ,\n\t\t\t1 << cfi_info->block_erase_timeout_typ,\n\t\t\t1 << cfi_info->chip_erase_timeout_typ);\n\n\tcommand_print_sameline(cmd, \"max. word write timeout: %u us, \"\n\t\t\t\"max. buf write timeout: %u us, max. \"\n\t\t\t\"block erase timeout: %u ms, max. chip erase timeout: %u ms\\n\",\n\t\t\t(1 <<\n\t\t\t cfi_info->word_write_timeout_max) * (1 << cfi_info->word_write_timeout_typ),\n\t\t\t(1 <<\n\t\t\t cfi_info->buf_write_timeout_max) * (1 << cfi_info->buf_write_timeout_typ),\n\t\t\t(1 <<\n\t\t\t cfi_info->block_erase_timeout_max) *\n\t\t\t(1 << cfi_info->block_erase_timeout_typ),\n\t\t\t(1 <<\n\t\t\t cfi_info->chip_erase_timeout_max) *\n\t\t\t(1 << cfi_info->chip_erase_timeout_typ));\n\n\tcommand_print_sameline(cmd, \"size: 0x%\" PRIx32 \", interface desc: %i, \"\n\t\t\t\"max buffer write size: 0x%x\\n\",\n\t\t\tcfi_info->dev_size,\n\t\t\tcfi_info->interface_desc,\n\t\t\t1 << cfi_info->max_buf_write_size);\n\n\tswitch (cfi_info->pri_id) {\n\t    case 1:\n\t    case 3:\n\t\t    cfi_intel_info(bank, cmd);\n\t\t    break;\n\t    case 2:\n\t\t    cfi_spansion_info(bank, cmd);\n\t\t    break;\n\t    default:\n\t\t    LOG_ERROR(\"cfi primary command set %i unsupported\", cfi_info->pri_id);\n\t\t    break;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void cfi_fixup_0002_write_buffer(struct flash_bank *bank, const void *param)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\n\t/* disable write buffer for M29W128G */\n\tcfi_info->buf_write_timeout_typ = 0;\n}\n\nconst struct flash_driver cfi_flash = {\n\t.name = \"cfi\",\n\t.flash_bank_command = cfi_flash_bank_command,\n\t.erase = cfi_erase,\n\t.protect = cfi_protect,\n\t.write = cfi_write,\n\t.read = cfi_read,\n\t.probe = cfi_probe,\n\t.auto_probe = cfi_auto_probe,\n\t/* FIXME: access flash at bus_width size */\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = cfi_protect_check,\n\t.info = cfi_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/cfi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_CFI_H\n#define OPENOCD_FLASH_NOR_CFI_H\n\n#define CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7 0xE0 /* DQ5..DQ7 */\n#define CFI_STATUS_POLL_MASK_DQ6_DQ7     0xC0 /* DQ6..DQ7 */\n\nstruct cfi_flash_bank {\n\tbool x16_as_x8;\n\tbool jedec_probe;\n\tbool not_cfi;\n\tbool probed;\n\n\tenum target_endianness endianness;\n\tbool data_swap;\n\n\tuint16_t manufacturer;\n\tuint16_t device_id;\n\n\tuint8_t qry[3];\n\n\t/* identification string */\n\tuint16_t pri_id;\n\tuint16_t pri_addr;\n\tuint16_t alt_id;\n\tuint16_t alt_addr;\n\n\t/* device-system interface */\n\tuint8_t vcc_min;\n\tuint8_t vcc_max;\n\tuint8_t vpp_min;\n\tuint8_t vpp_max;\n\tuint8_t word_write_timeout_typ;\n\tuint8_t buf_write_timeout_typ;\n\tuint8_t block_erase_timeout_typ;\n\tuint8_t chip_erase_timeout_typ;\n\tuint8_t word_write_timeout_max;\n\tuint8_t buf_write_timeout_max;\n\tuint8_t block_erase_timeout_max;\n\tuint8_t chip_erase_timeout_max;\n\n\tuint8_t status_poll_mask;\n\n\t/* flash geometry */\n\tuint32_t dev_size;\n\tuint16_t interface_desc;\n\tuint16_t max_buf_write_size;\n\tuint8_t num_erase_regions;\n\tuint32_t *erase_region_info;\n\n\tvoid *pri_ext;\n\tvoid *alt_ext;\n\n\t/* calculated timeouts */\n\tunsigned word_write_timeout;\n\tunsigned buf_write_timeout;\n\tunsigned block_erase_timeout;\n\tunsigned chip_erase_timeout;\n\n\t/* memory accessors */\n\tint (*write_mem)(struct flash_bank *bank, target_addr_t addr,\n\t\t\t uint32_t count, const uint8_t *buffer);\n\tint (*read_mem)(struct flash_bank *bank, target_addr_t addr,\n\t\t\tuint32_t count, uint8_t *buffer);\n};\n\n/* Intel primary extended query table\n * as defined for the Advanced+ Boot Block Flash Memory (C3)\n * and used by the linux kernel cfi driver (as of 2.6.14)\n */\nstruct cfi_intel_pri_ext {\n\tuint8_t pri[3];\n\tuint8_t major_version;\n\tuint8_t minor_version;\n\tuint32_t feature_support;\n\tuint8_t suspend_cmd_support;\n\tuint16_t blk_status_reg_mask;\n\tuint8_t vcc_optimal;\n\tuint8_t vpp_optimal;\n\tuint8_t num_protection_fields;\n\tuint16_t prot_reg_addr;\n\tuint8_t fact_prot_reg_size;\n\tuint8_t user_prot_reg_size;\n\tuint8_t extra[0];\n};\n\n/* Spansion primary extended query table as defined for and used by\n * the linux kernel cfi driver (as of 2.6.15)\n */\nstruct cfi_spansion_pri_ext {\n\tuint8_t  pri[3];\n\tuint8_t  major_version;\n\tuint8_t  minor_version;\n\tuint8_t  silicon_revision; /* bits 1-0: Address Sensitive Unlock */\n\tuint8_t  erase_suspend;\n\tuint8_t  blk_prot;\n\tuint8_t  tmp_blk_unprotected;\n\tuint8_t  blk_prot_unprot;\n\tuint8_t  simultaneous_ops;\n\tuint8_t  burst_mode;\n\tuint8_t  page_mode;\n\tuint8_t  vpp_min;\n\tuint8_t  vpp_max;\n\tuint8_t  top_bottom;\n\tint _reversed_geometry;\n\tuint32_t _unlock1;\n\tuint32_t _unlock2;\n};\n\n/* Atmel primary extended query table as defined for and used by\n * the linux kernel cfi driver (as of 2.6.20+)\n */\nstruct cfi_atmel_pri_ext {\n\tuint8_t pri[3];\n\tuint8_t major_version;\n\tuint8_t minor_version;\n\tuint8_t features;\n\tuint8_t bottom_boot;\n\tuint8_t burst_mode;\n\tuint8_t page_mode;\n};\n\nenum {\n\tCFI_UNLOCK_555_2AA,\n\tCFI_UNLOCK_5555_2AAA,\n};\n\nstruct cfi_unlock_addresses {\n\tuint32_t unlock1;\n\tuint32_t unlock2;\n};\n\nstruct cfi_fixup {\n\tuint16_t mfr;\n\tuint16_t id;\n\tvoid (*fixup)(struct flash_bank *bank, const void *param);\n\tconst void *param;\n};\n\nint cfi_erase(struct flash_bank *bank, unsigned int first, unsigned int last);\nint cfi_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last);\nint cfi_probe(struct flash_bank *bank);\nint cfi_auto_probe(struct flash_bank *bank);\nint cfi_protect_check(struct flash_bank *bank);\nint cfi_get_info(struct flash_bank *bank, struct command_invocation *cmd);\nint cfi_flash_bank_cmd(struct flash_bank *bank, unsigned int argc, const char **argv);\n\nuint32_t cfi_flash_address(struct flash_bank *bank, int sector, uint32_t offset);\nint cfi_spansion_unlock_seq(struct flash_bank *bank);\nint cfi_send_command(struct flash_bank *bank, uint8_t cmd, uint32_t address);\nint cfi_write_word(struct flash_bank *bank, uint8_t *word, uint32_t address);\nint cfi_spansion_wait_status_busy(struct flash_bank *bank, int timeout);\nint cfi_reset(struct flash_bank *bank);\n\nint cfi_target_read_memory(struct flash_bank *bank, target_addr_t addr,\n\t\t\t   uint32_t count, uint8_t *buffer);\n\n#define CFI_MFR_AMD\t\t0x0001\n#define CFI_MFR_FUJITSU\t0x0004\n#define CFI_MFR_ATMEL\t0x001F\n#define CFI_MFR_ST\t\t0x0020\t/* STMicroelectronics */\n#define CFI_MFR_AMIC\t0x0037\n#define CFI_MFR_SST\t\t0x00BF\n#define CFI_MFR_MX\t\t0x00C2\n#define CFI_MFR_EON\t\t0x007F\n\n#define CFI_MFR_ANY\t\t0xffff\n#define CFI_ID_ANY\t\t0xffff\n\n#define CFI_MAX_BUS_WIDTH       4\n#define CFI_MAX_CHIP_WIDTH      4\n\n#endif /* OPENOCD_FLASH_NOR_CFI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/core.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n *   Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz>                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include <flash/common.h>\n#include <flash/nor/core.h>\n#include <flash/nor/imp.h>\n#include <target/image.h>\n\n/**\n * @file\n * Upper level of NOR flash framework.\n * The lower level interfaces are to drivers.  These upper level ones\n * primarily support access from Tcl scripts or from GDB.\n */\n\nstatic struct flash_bank *flash_banks;\n\nint flash_driver_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\n\tretval = bank->driver->erase(bank, first, last);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"failed erasing sectors %u to %u\", first, last);\n\n\treturn retval;\n}\n\nint flash_driver_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\tunsigned int num_blocks;\n\n\tif (bank->num_prot_blocks)\n\t\tnum_blocks = bank->num_prot_blocks;\n\telse\n\t\tnum_blocks = bank->num_sectors;\n\n\n\t/* callers may not supply illegal parameters ... */\n\tif (first > last || last >= num_blocks) {\n\t\tLOG_ERROR(\"illegal protection block range\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* force \"set\" to 0/1 */\n\tset = !!set;\n\n\tif (!bank->driver->protect) {\n\t\tLOG_ERROR(\"Flash protection is not supported.\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\t/* DANGER!\n\t *\n\t * We must not use any cached information about protection state!!!!\n\t *\n\t * There are a million things that could change the protect state:\n\t *\n\t * the target could have reset, power cycled, been hot plugged,\n\t * the application could have run, etc.\n\t *\n\t * Drivers only receive valid protection block range.\n\t */\n\tretval = bank->driver->protect(bank, set, first, last);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"failed setting protection for blocks %u to %u\", first, last);\n\n\treturn retval;\n}\n\nint flash_driver_write(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\tretval = bank->driver->write(bank, buffer, offset, count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\n\t\t\t\"error writing to flash at address \" TARGET_ADDR_FMT\n\t\t\t\" at offset 0x%8.8\" PRIx32,\n\t\t\tbank->base,\n\t\t\toffset);\n\t}\n\n\treturn retval;\n}\n\nint flash_driver_read(struct flash_bank *bank,\n\tuint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"call flash_driver_read()\");\n\n\tretval = bank->driver->read(bank, buffer, offset, count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\n\t\t\t\"error reading to flash at address \" TARGET_ADDR_FMT\n\t\t\t\" at offset 0x%8.8\" PRIx32,\n\t\t\tbank->base,\n\t\t\toffset);\n\t}\n\n\treturn retval;\n}\n\nint default_flash_read(struct flash_bank *bank,\n\tuint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\treturn target_read_buffer(bank->target, offset + bank->base, count, buffer);\n}\n\nint flash_driver_verify(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\tretval = bank->driver->verify ? bank->driver->verify(bank, buffer, offset, count) :\n\t\tdefault_flash_verify(bank, buffer, offset, count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"verify failed in bank at \" TARGET_ADDR_FMT \" starting at 0x%8.8\" PRIx32,\n\t\t\tbank->base, offset);\n\t}\n\n\treturn retval;\n}\n\nint default_flash_verify(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tuint32_t target_crc, image_crc;\n\tint retval;\n\n\tretval = image_calculate_checksum(buffer, count, &image_crc);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_checksum_memory(bank->target, offset + bank->base, count, &target_crc);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"addr \" TARGET_ADDR_FMT \", len 0x%08\" PRIx32 \", crc 0x%08\" PRIx32 \" 0x%08\" PRIx32,\n\t\toffset + bank->base, count, ~image_crc, ~target_crc);\n\tif (target_crc == image_crc)\n\t\treturn ERROR_OK;\n\telse\n\t\treturn ERROR_FAIL;\n}\n\nvoid flash_bank_add(struct flash_bank *bank)\n{\n\t/* put flash bank in linked list */\n\tunsigned bank_num = 0;\n\tif (flash_banks) {\n\t\t/* find last flash bank */\n\t\tstruct flash_bank *p = flash_banks;\n\t\twhile (p->next) {\n\t\t\tbank_num += 1;\n\t\t\tp = p->next;\n\t\t}\n\t\tp->next = bank;\n\t\tbank_num += 1;\n\t} else\n\t\tflash_banks = bank;\n\n\tbank->bank_number = bank_num;\n}\n\nstruct flash_bank *flash_bank_list(void)\n{\n\treturn flash_banks;\n}\n\nstruct flash_bank *get_flash_bank_by_num_noprobe(unsigned int num)\n{\n\tstruct flash_bank *p;\n\tunsigned int i = 0;\n\n\tfor (p = flash_banks; p; p = p->next) {\n\t\tif (i++ == num)\n\t\t\treturn p;\n\t}\n\tLOG_ERROR(\"flash bank %d does not exist\", num);\n\treturn NULL;\n}\n\nunsigned int flash_get_bank_count(void)\n{\n\tstruct flash_bank *p;\n\tunsigned int i = 0;\n\tfor (p = flash_banks; p; p = p->next)\n\t\ti++;\n\treturn i;\n}\n\nvoid default_flash_free_driver_priv(struct flash_bank *bank)\n{\n\tfree(bank->driver_priv);\n\tbank->driver_priv = NULL;\n}\n\nvoid flash_free_all_banks(void)\n{\n\tstruct flash_bank *bank = flash_banks;\n\twhile (bank) {\n\t\tstruct flash_bank *next = bank->next;\n\t\tif (bank->driver->free_driver_priv)\n\t\t\tbank->driver->free_driver_priv(bank);\n\t\telse\n\t\t\tLOG_WARNING(\"Flash driver of %s does not support free_driver_priv()\", bank->name);\n\n\t\t/* For 'virtual' flash driver bank->sectors and bank->prot_blocks pointers are copied from\n\t\t * master flash_bank structure. They point to memory locations allocated by master flash driver\n\t\t * so master driver is responsible for releasing them.\n\t\t * Avoid UB caused by double-free memory corruption if flash bank is 'virtual'. */\n\n\t\tif (strcmp(bank->driver->name, \"virtual\") != 0) {\n\t\t\tfree(bank->sectors);\n\t\t\tfree(bank->prot_blocks);\n\t\t}\n\n\t\tfree(bank->name);\n\t\tfree(bank);\n\t\tbank = next;\n\t}\n\tflash_banks = NULL;\n}\n\nstruct flash_bank *get_flash_bank_by_name_noprobe(const char *name)\n{\n\tunsigned requested = get_flash_name_index(name);\n\tunsigned found = 0;\n\n\tstruct flash_bank *bank;\n\tfor (bank = flash_banks; bank; bank = bank->next) {\n\t\tif (strcmp(bank->name, name) == 0)\n\t\t\treturn bank;\n\t\tif (!flash_driver_name_matches(bank->driver->name, name))\n\t\t\tcontinue;\n\t\tif (++found < requested)\n\t\t\tcontinue;\n\t\treturn bank;\n\t}\n\treturn NULL;\n}\n\nint get_flash_bank_by_name(const char *name, struct flash_bank **bank_result)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\n\tbank = get_flash_bank_by_name_noprobe(name);\n\tif (bank) {\n\t\tretval = bank->driver->auto_probe(bank);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"auto_probe failed\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t*bank_result = bank;\n\treturn ERROR_OK;\n}\n\nint get_flash_bank_by_num(unsigned int num, struct flash_bank **bank)\n{\n\tstruct flash_bank *p = get_flash_bank_by_num_noprobe(num);\n\tint retval;\n\n\tif (!p)\n\t\treturn ERROR_FAIL;\n\n\tretval = p->driver->auto_probe(p);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"auto_probe failed\");\n\t\treturn retval;\n\t}\n\t*bank = p;\n\treturn ERROR_OK;\n}\n\n/* lookup flash bank by address, bank not found is success, but\n * result_bank is set to NULL. */\nint get_flash_bank_by_addr(struct target *target,\n\ttarget_addr_t addr,\n\tbool check,\n\tstruct flash_bank **result_bank)\n{\n\tstruct flash_bank *c;\n\n\t/* cycle through bank list */\n\tfor (c = flash_banks; c; c = c->next) {\n\t\tif (c->target != target)\n\t\t\tcontinue;\n\n\t\tint retval;\n\t\tretval = c->driver->auto_probe(c);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"auto_probe failed\");\n\t\t\treturn retval;\n\t\t}\n\t\t/* check whether address belongs to this flash bank */\n\t\tif ((addr >= c->base) && (addr <= c->base + (c->size - 1))) {\n\t\t\t*result_bank = c;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\t*result_bank = NULL;\n\tif (check) {\n\t\tLOG_ERROR(\"No flash at address \" TARGET_ADDR_FMT, addr);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int default_flash_mem_blank_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tconst int buffer_size = 1024;\n\tuint32_t n_bytes;\n\tint retval = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint8_t *buffer = malloc(buffer_size);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint32_t j;\n\t\tbank->sectors[i].is_erased = 1;\n\n\t\tfor (j = 0; j < bank->sectors[i].size; j += buffer_size) {\n\t\t\tuint32_t chunk;\n\t\t\tchunk = buffer_size;\n\t\t\tif (chunk > (bank->sectors[i].size - j))\n\t\t\t\tchunk = (bank->sectors[i].size - j);\n\n\t\t\tretval = target_read_memory(target,\n\t\t\t\t\tbank->base + bank->sectors[i].offset + j,\n\t\t\t\t\t4,\n\t\t\t\t\tchunk/4,\n\t\t\t\t\tbuffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\n\t\t\tfor (n_bytes = 0; n_bytes < chunk; n_bytes++) {\n\t\t\t\tif (buffer[n_bytes] != bank->erased_value) {\n\t\t\t\t\tbank->sectors[i].is_erased = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nint default_flash_blank_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct target_memory_check_block *block_array;\n\tblock_array = malloc(bank->num_sectors * sizeof(struct target_memory_check_block));\n\tif (!block_array)\n\t\treturn default_flash_mem_blank_check(bank);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tblock_array[i].address = bank->base + bank->sectors[i].offset;\n\t\tblock_array[i].size = bank->sectors[i].size;\n\t\tblock_array[i].result = UINT32_MAX; /* erase state unknown */\n\t}\n\n\tbool fast_check = true;\n\tfor (unsigned int i = 0; i < bank->num_sectors; ) {\n\t\tretval = target_blank_check_memory(target,\n\t\t\t\tblock_array + i, bank->num_sectors - i,\n\t\t\t\tbank->erased_value);\n\t\tif (retval < 1) {\n\t\t\t/* Run slow fallback if the first run gives no result\n\t\t\t * otherwise use possibly incomplete results */\n\t\t\tif (i == 0)\n\t\t\t\tfast_check = false;\n\t\t\tbreak;\n\t\t}\n\t\ti += retval; /* add number of blocks done this round */\n\t}\n\n\tif (fast_check) {\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\t\tbank->sectors[i].is_erased = block_array[i].result;\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tif (retval == ERROR_NOT_IMPLEMENTED)\n\t\t\tLOG_USER(\"Running slow fallback erase check\");\n\t\telse\n\t\t\tLOG_USER(\"Running slow fallback erase check - add working memory\");\n\n\t\tretval = default_flash_mem_blank_check(bank);\n\t}\n\tfree(block_array);\n\n\treturn retval;\n}\n\n/* Manipulate given flash region, selecting the bank according to target\n * and address.  Maps an address range to a set of sectors, and issues\n * the callback() on that set ... e.g. to erase or unprotect its members.\n *\n * Parameter iterate_protect_blocks switches iteration of protect block\n * instead of erase sectors. If there is no protect blocks array, sectors\n * are used in iteration, so compatibility for old flash drivers is retained.\n *\n * The \"pad_reason\" parameter is a kind of boolean:  when it's NULL, the\n * range must fit those sectors exactly.  This is clearly safe; it can't\n * erase data which the caller said to leave alone, for example.  If it's\n * non-NULL, rather than failing, extra data in the first and/or last\n * sectors will be added to the range, and that reason string is used when\n * warning about those additions.\n */\nstatic int flash_iterate_address_range_inner(struct target *target,\n\tchar *pad_reason, target_addr_t addr, uint32_t length,\n\tbool iterate_protect_blocks,\n\tint (*callback)(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last))\n{\n\tstruct flash_bank *c;\n\tstruct flash_sector *block_array;\n\ttarget_addr_t last_addr = addr + length - 1;\t/* the last address of range */\n\tint first = -1;\n\tint last = -1;\n\tint i;\n\tint num_blocks;\n\n\tint retval = get_flash_bank_by_addr(target, addr, true, &c);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (c->size == 0 || c->num_sectors == 0) {\n\t\tLOG_ERROR(\"Bank is invalid\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tif (length == 0) {\n\t\t/* special case, erase whole bank when length is zero */\n\t\tif (addr != c->base) {\n\t\t\tLOG_ERROR(\"Whole bank access must start at beginning of bank.\");\n\t\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t\t}\n\n\t\treturn callback(c, 0, c->num_sectors - 1);\n\t}\n\n\t/* check whether it all fits in this bank */\n\tif (last_addr > c->base + c->size - 1) {\n\t\tLOG_ERROR(\"Flash access does not fit into bank.\");\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (!c->prot_blocks || c->num_prot_blocks == 0) {\n\t\t/* flash driver does not define protect blocks, use sectors instead */\n\t\titerate_protect_blocks = false;\n\t}\n\n\tif (iterate_protect_blocks) {\n\t\tblock_array = c->prot_blocks;\n\t\tnum_blocks = c->num_prot_blocks;\n\t} else {\n\t\tblock_array = c->sectors;\n\t\tnum_blocks = c->num_sectors;\n\t}\n\n\tfor (i = 0; i < num_blocks; i++) {\n\t\tstruct flash_sector *f = &block_array[i];\n\t\ttarget_addr_t sector_addr = c->base + f->offset;\n\t\ttarget_addr_t sector_last_addr = sector_addr + f->size - 1;\n\n\t\t/* start only on a sector boundary */\n\t\tif (first < 0) {\n\t\t\t/* scanned past the first sector? */\n\t\t\tif (addr < sector_addr)\n\t\t\t\tbreak;\n\n\t\t\t/* is this the first sector? */\n\t\t\tif (addr == sector_addr)\n\t\t\t\tfirst = i;\n\n\t\t\t/* Does this need head-padding?  If so, pad and warn;\n\t\t\t * or else force an error.\n\t\t\t *\n\t\t\t * Such padding can make trouble, since *WE* can't\n\t\t\t * ever know if that data was in use.  The warning\n\t\t\t * should help users sort out messes later.\n\t\t\t */\n\t\t\telse if (addr <= sector_last_addr && pad_reason) {\n\t\t\t\t/* FIXME say how many bytes (e.g. 80 KB) */\n\t\t\t\tLOG_WARNING(\"Adding extra %s range, \"\n\t\t\t\t\tTARGET_ADDR_FMT \" .. \" TARGET_ADDR_FMT,\n\t\t\t\t\tpad_reason,\n\t\t\t\t\tsector_addr,\n\t\t\t\t\taddr - 1);\n\t\t\t\tfirst = i;\n\t\t\t} else\n\t\t\t\tcontinue;\n\t\t}\n\n\t\t/* is this (also?) the last sector? */\n\t\tif (last_addr == sector_last_addr) {\n\t\t\tlast = i;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Does this need tail-padding?  If so, pad and warn;\n\t\t * or else force an error.\n\t\t */\n\t\tif (last_addr < sector_last_addr && pad_reason) {\n\t\t\t/* FIXME say how many bytes (e.g. 80 KB) */\n\t\t\tLOG_WARNING(\"Adding extra %s range, \"\n\t\t\t\tTARGET_ADDR_FMT \" .. \" TARGET_ADDR_FMT,\n\t\t\t\tpad_reason,\n\t\t\t\tlast_addr + 1,\n\t\t\t\tsector_last_addr);\n\t\t\tlast = i;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* MUST finish on a sector boundary */\n\t\tif (last_addr < sector_addr)\n\t\t\tbreak;\n\t}\n\n\t/* invalid start or end address? */\n\tif (first == -1 || last == -1) {\n\t\tLOG_ERROR(\"address range \" TARGET_ADDR_FMT \" .. \" TARGET_ADDR_FMT\n\t\t\t\" is not sector-aligned\",\n\t\t\taddr,\n\t\t\tlast_addr);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* The NOR driver may trim this range down, based on what\n\t * sectors are already erased/unprotected.  GDB currently\n\t * blocks such optimizations.\n\t */\n\treturn callback(c, first, last);\n}\n\n/* The inner fn only handles a single bank, we could be spanning\n * multiple chips.\n */\nstatic int flash_iterate_address_range(struct target *target,\n\tchar *pad_reason, target_addr_t addr, uint32_t length,\n\tbool iterate_protect_blocks,\n\tint (*callback)(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last))\n{\n\tstruct flash_bank *c;\n\tint retval = ERROR_OK;\n\n\t/* Danger! zero-length iterations means entire bank! */\n\tdo {\n\t\tretval = get_flash_bank_by_addr(target, addr, true, &c);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tuint32_t cur_length = length;\n\t\t/* check whether it all fits in this bank */\n\t\tif (addr + length - 1 > c->base + c->size - 1) {\n\t\t\tLOG_DEBUG(\"iterating over more than one flash bank.\");\n\t\t\tcur_length = c->base + c->size - addr;\n\t\t}\n\t\tretval = flash_iterate_address_range_inner(target,\n\t\t\t\tpad_reason, addr, cur_length,\n\t\t\t\titerate_protect_blocks,\n\t\t\t\tcallback);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tlength -= cur_length;\n\t\taddr += cur_length;\n\t} while (length > 0);\n\n\treturn retval;\n}\n\nint flash_erase_address_range(struct target *target,\n\tbool pad, target_addr_t addr, uint32_t length)\n{\n\treturn flash_iterate_address_range(target, pad ? \"erase\" : NULL,\n\t\taddr, length, false, &flash_driver_erase);\n}\n\nstatic int flash_driver_unprotect(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\treturn flash_driver_protect(bank, 0, first, last);\n}\n\nint flash_unlock_address_range(struct target *target, target_addr_t addr,\n\t\tuint32_t length)\n{\n\t/* By default, pad to sector boundaries ... the real issue here\n\t * is that our (only) caller *permanently* removes protection,\n\t * and doesn't restore it.\n\t */\n\treturn flash_iterate_address_range(target, \"unprotect\",\n\t\taddr, length, true, &flash_driver_unprotect);\n}\n\nstatic int compare_section(const void *a, const void *b)\n{\n\tstruct imagesection *b1, *b2;\n\tb1 = *((struct imagesection **)a);\n\tb2 = *((struct imagesection **)b);\n\n\tif (b1->base_address == b2->base_address)\n\t\treturn 0;\n\telse if (b1->base_address > b2->base_address)\n\t\treturn 1;\n\telse\n\t\treturn -1;\n}\n\n/**\n * Get aligned start address of a flash write region\n */\ntarget_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t addr)\n{\n\tif (addr < bank->base || addr >= bank->base + bank->size\n\t\t\t|| bank->write_start_alignment <= 1)\n\t\treturn addr;\n\n\tif (bank->write_start_alignment == FLASH_WRITE_ALIGN_SECTOR) {\n\t\tuint32_t offset = addr - bank->base;\n\t\tuint32_t aligned = 0;\n\t\tfor (unsigned int sect = 0; sect < bank->num_sectors; sect++) {\n\t\t\tif (bank->sectors[sect].offset > offset)\n\t\t\t\tbreak;\n\n\t\t\taligned = bank->sectors[sect].offset;\n\t\t}\n\t\treturn bank->base + aligned;\n\t}\n\n\treturn addr & ~(bank->write_start_alignment - 1);\n}\n\n/**\n * Get aligned end address of a flash write region\n */\ntarget_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr)\n{\n\tif (addr < bank->base || addr >= bank->base + bank->size\n\t\t\t|| bank->write_end_alignment <= 1)\n\t\treturn addr;\n\n\tif (bank->write_end_alignment == FLASH_WRITE_ALIGN_SECTOR) {\n\t\tuint32_t offset = addr - bank->base;\n\t\tuint32_t aligned = 0;\n\t\tfor (unsigned int sect = 0; sect < bank->num_sectors; sect++) {\n\t\t\taligned = bank->sectors[sect].offset + bank->sectors[sect].size - 1;\n\t\t\tif (aligned >= offset)\n\t\t\t\tbreak;\n\t\t}\n\t\treturn bank->base + aligned;\n\t}\n\n\treturn addr | (bank->write_end_alignment - 1);\n}\n\n/**\n * Check if gap between sections is bigger than minimum required to discontinue flash write\n */\nstatic bool flash_write_check_gap(struct flash_bank *bank,\n\t\t\t\ttarget_addr_t addr1, target_addr_t addr2)\n{\n\tif (bank->minimal_write_gap == FLASH_WRITE_CONTINUOUS\n\t\t\t|| addr1 < bank->base || addr1 >= bank->base + bank->size\n\t\t\t|| addr2 < bank->base || addr2 >= bank->base + bank->size)\n\t\treturn false;\n\n\tif (bank->minimal_write_gap == FLASH_WRITE_GAP_SECTOR) {\n\t\tunsigned int sect;\n\t\tuint32_t offset1 = addr1 - bank->base;\n\t\t/* find the sector following the one containing addr1 */\n\t\tfor (sect = 0; sect < bank->num_sectors; sect++) {\n\t\t\tif (bank->sectors[sect].offset > offset1)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (sect >= bank->num_sectors)\n\t\t\treturn false;\n\n\t\tuint32_t offset2 = addr2 - bank->base;\n\t\treturn bank->sectors[sect].offset + bank->sectors[sect].size <= offset2;\n\t}\n\n\ttarget_addr_t aligned1 = flash_write_align_end(bank, addr1);\n\ttarget_addr_t aligned2 = flash_write_align_start(bank, addr2);\n\treturn aligned1 + bank->minimal_write_gap < aligned2;\n}\n\n\nint flash_write_unlock_verify(struct target *target, struct image *image,\n\tuint32_t *written, bool erase, bool unlock, bool write, bool verify)\n{\n\tint retval = ERROR_OK;\n\n\tunsigned int section;\n\tuint32_t section_offset;\n\tstruct flash_bank *c;\n\tint *padding;\n\n\tsection = 0;\n\tsection_offset = 0;\n\n\tif (written)\n\t\t*written = 0;\n\n\tif (erase) {\n\t\t/* assume all sectors need erasing - stops any problems\n\t\t * when flash_write is called multiple times */\n\n\t\tflash_set_dirty();\n\t}\n\n\t/* allocate padding array */\n\tpadding = calloc(image->num_sections, sizeof(*padding));\n\n\t/* This fn requires all sections to be in ascending order of addresses,\n\t * whereas an image can have sections out of order. */\n\tstruct imagesection **sections = malloc(sizeof(struct imagesection *) *\n\t\t\timage->num_sections);\n\n\tfor (unsigned int i = 0; i < image->num_sections; i++)\n\t\tsections[i] = &image->sections[i];\n\n\tqsort(sections, image->num_sections, sizeof(struct imagesection *),\n\t\tcompare_section);\n\n\t/* loop until we reach end of the image */\n\twhile (section < image->num_sections) {\n\t\tuint32_t buffer_idx;\n\t\tuint8_t *buffer;\n\t\tunsigned int section_last;\n\t\ttarget_addr_t run_address = sections[section]->base_address + section_offset;\n\t\tuint32_t run_size = sections[section]->size - section_offset;\n\t\tint pad_bytes = 0;\n\n\t\tif (sections[section]->size ==  0) {\n\t\t\tLOG_WARNING(\"empty section %d\", section);\n\t\t\tsection++;\n\t\t\tsection_offset = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* find the corresponding flash bank */\n\t\tretval = get_flash_bank_by_addr(target, run_address, false, &c);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tif (!c) {\n\t\t\tLOG_WARNING(\"no flash bank found for address \" TARGET_ADDR_FMT, run_address);\n\t\t\tsection++;\t/* and skip it */\n\t\t\tsection_offset = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* collect consecutive sections which fall into the same bank */\n\t\tsection_last = section;\n\t\tpadding[section] = 0;\n\t\twhile ((run_address + run_size - 1 < c->base + c->size - 1) &&\n\t\t\t\t(section_last + 1 < image->num_sections)) {\n\t\t\t/* sections are sorted */\n\t\t\tassert(sections[section_last + 1]->base_address >= c->base);\n\t\t\tif (sections[section_last + 1]->base_address >= (c->base + c->size)) {\n\t\t\t\t/* Done with this bank */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* if we have multiple sections within our image,\n\t\t\t * flash programming could fail due to alignment issues\n\t\t\t * attempt to rebuild a consecutive buffer for the flash loader */\n\t\t\ttarget_addr_t run_next_addr = run_address + run_size;\n\t\t\ttarget_addr_t next_section_base = sections[section_last + 1]->base_address;\n\t\t\tif (next_section_base < run_next_addr) {\n\t\t\t\tLOG_ERROR(\"Section at \" TARGET_ADDR_FMT\n\t\t\t\t\t\" overlaps section ending at \" TARGET_ADDR_FMT,\n\t\t\t\t\tnext_section_base, run_next_addr);\n\t\t\t\tLOG_ERROR(\"Flash write aborted.\");\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto done;\n\t\t\t}\n\n\t\t\tpad_bytes = next_section_base - run_next_addr;\n\t\t\tif (pad_bytes) {\n\t\t\t\tif (flash_write_check_gap(c, run_next_addr - 1, next_section_base)) {\n\t\t\t\t\tLOG_INFO(\"Flash write discontinued at \" TARGET_ADDR_FMT\n\t\t\t\t\t\t\", next section at \" TARGET_ADDR_FMT,\n\t\t\t\t\t\trun_next_addr, next_section_base);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (pad_bytes > 0)\n\t\t\t\tLOG_INFO(\"Padding image section %d at \" TARGET_ADDR_FMT\n\t\t\t\t\t\" with %d bytes\",\n\t\t\t\t\tsection_last, run_next_addr, pad_bytes);\n\n\t\t\tpadding[section_last] = pad_bytes;\n\t\t\trun_size += pad_bytes;\n\t\t\trun_size += sections[++section_last]->size;\n\t\t}\n\n\t\tif (run_address + run_size - 1 > c->base + c->size - 1) {\n\t\t\t/* If we have more than one flash chip back to back, then we limit\n\t\t\t * the current write operation to the current chip.\n\t\t\t */\n\t\t\tLOG_DEBUG(\"Truncate flash run size to the current flash chip.\");\n\n\t\t\trun_size = c->base + c->size - run_address;\n\t\t\tassert(run_size > 0);\n\t\t}\n\n\t\tuint32_t padding_at_start = 0;\n\t\tif (c->write_start_alignment || c->write_end_alignment) {\n\t\t\t/* align write region according to bank requirements */\n\t\t\ttarget_addr_t aligned_start = flash_write_align_start(c, run_address);\n\t\t\tpadding_at_start = run_address - aligned_start;\n\t\t\tif (padding_at_start > 0) {\n\t\t\t\tLOG_WARNING(\"Section start address \" TARGET_ADDR_FMT\n\t\t\t\t\t\" breaks the required alignment of flash bank %s\",\n\t\t\t\t\trun_address, c->name);\n\t\t\t\tLOG_WARNING(\"Padding %\" PRIu32 \" bytes from \" TARGET_ADDR_FMT,\n\t\t\t\t\tpadding_at_start, aligned_start);\n\n\t\t\t\trun_address -= padding_at_start;\n\t\t\t\trun_size += padding_at_start;\n\t\t\t}\n\n\t\t\ttarget_addr_t run_end = run_address + run_size - 1;\n\t\t\ttarget_addr_t aligned_end = flash_write_align_end(c, run_end);\n\t\t\tpad_bytes = aligned_end - run_end;\n\t\t\tif (pad_bytes > 0) {\n\t\t\t\tLOG_INFO(\"Padding image section %d at \" TARGET_ADDR_FMT\n\t\t\t\t\t\" with %d bytes (bank write end alignment)\",\n\t\t\t\t\tsection_last, run_end + 1, pad_bytes);\n\n\t\t\t\tpadding[section_last] += pad_bytes;\n\t\t\t\trun_size += pad_bytes;\n\t\t\t}\n\n\t\t} else if (unlock || erase) {\n\t\t\t/* If we're applying any sector automagic, then pad this\n\t\t\t * (maybe-combined) segment to the end of its last sector.\n\t\t\t */\n\t\t\tuint32_t offset_start = run_address - c->base;\n\t\t\tuint32_t offset_end = offset_start + run_size;\n\t\t\tuint32_t end = offset_end, delta;\n\n\t\t\tfor (unsigned int sector = 0; sector < c->num_sectors; sector++) {\n\t\t\t\tend = c->sectors[sector].offset\n\t\t\t\t\t+ c->sectors[sector].size;\n\t\t\t\tif (offset_end <= end)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdelta = end - offset_end;\n\t\t\tpadding[section_last] += delta;\n\t\t\trun_size += delta;\n\t\t}\n\n\t\t/* allocate buffer */\n\t\tbuffer = malloc(run_size);\n\t\tif (!buffer) {\n\t\t\tLOG_ERROR(\"Out of memory for flash bank buffer\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto done;\n\t\t}\n\n\t\tif (padding_at_start)\n\t\t\tmemset(buffer, c->default_padded_value, padding_at_start);\n\n\t\tbuffer_idx = padding_at_start;\n\n\t\t/* read sections to the buffer */\n\t\twhile (buffer_idx < run_size) {\n\t\t\tsize_t size_read;\n\n\t\t\tsize_read = run_size - buffer_idx;\n\t\t\tif (size_read > sections[section]->size - section_offset)\n\t\t\t\tsize_read = sections[section]->size - section_offset;\n\n\t\t\t/* KLUDGE!\n\t\t\t *\n\t\t\t * #¤%#\"%¤% we have to figure out the section # from the sorted\n\t\t\t * list of pointers to sections to invoke image_read_section()...\n\t\t\t */\n\t\t\tintptr_t diff = (intptr_t)sections[section] - (intptr_t)image->sections;\n\t\t\tint t_section_num = diff / sizeof(struct imagesection);\n\n\t\t\tLOG_DEBUG(\"image_read_section: section = %d, t_section_num = %d, \"\n\t\t\t\t\t\"section_offset = %\"PRIu32\", buffer_idx = %\"PRIu32\", size_read = %zu\",\n\t\t\t\tsection, t_section_num, section_offset,\n\t\t\t\tbuffer_idx, size_read);\n\t\t\tretval = image_read_section(image, t_section_num, section_offset,\n\t\t\t\t\tsize_read, buffer + buffer_idx, &size_read);\n\t\t\tif (retval != ERROR_OK || size_read == 0) {\n\t\t\t\tfree(buffer);\n\t\t\t\tgoto done;\n\t\t\t}\n\n\t\t\tbuffer_idx += size_read;\n\t\t\tsection_offset += size_read;\n\n\t\t\t/* see if we need to pad the section */\n\t\t\tif (padding[section]) {\n\t\t\t\tmemset(buffer + buffer_idx, c->default_padded_value, padding[section]);\n\t\t\t\tbuffer_idx += padding[section];\n\t\t\t}\n\n\t\t\tif (section_offset >= sections[section]->size) {\n\t\t\t\tsection++;\n\t\t\t\tsection_offset = 0;\n\t\t\t}\n\t\t}\n\n\t\tretval = ERROR_OK;\n\n\t\tif (unlock)\n\t\t\tretval = flash_unlock_address_range(target, run_address, run_size);\n\t\tif (retval == ERROR_OK) {\n\t\t\tif (erase) {\n\t\t\t\t/* calculate and erase sectors */\n\t\t\t\tretval = flash_erase_address_range(target,\n\t\t\t\t\t\ttrue, run_address, run_size);\n\t\t\t}\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tif (write) {\n\t\t\t\t/* write flash sectors */\n\t\t\t\tretval = flash_driver_write(c, buffer, run_address - c->base, run_size);\n\t\t\t}\n\t\t}\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tif (verify) {\n\t\t\t\t/* verify flash sectors */\n\t\t\t\tretval = flash_driver_verify(c, buffer, run_address - c->base, run_size);\n\t\t\t}\n\t\t}\n\n\t\tfree(buffer);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* abort operation */\n\t\t\tgoto done;\n\t\t}\n\n\t\tif (written)\n\t\t\t*written += run_size;\t/* add run size to total written counter */\n\t}\n\ndone:\n\tfree(sections);\n\tfree(padding);\n\n\treturn retval;\n}\n\nint flash_write(struct target *target, struct image *image,\n\tuint32_t *written, bool erase)\n{\n\treturn flash_write_unlock_verify(target, image, written, erase, false, true, false);\n}\n\nstruct flash_sector *alloc_block_array(uint32_t offset, uint32_t size,\n\t\tunsigned int num_blocks)\n{\n\tstruct flash_sector *array = calloc(num_blocks, sizeof(struct flash_sector));\n\tif (!array)\n\t\treturn NULL;\n\n\tfor (unsigned int i = 0; i < num_blocks; i++) {\n\t\tarray[i].offset = offset;\n\t\tarray[i].size = size;\n\t\tarray[i].is_erased = -1;\n\t\tarray[i].is_protected = -1;\n\t\toffset += size;\n\t}\n\n\treturn array;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/core.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_CORE_H\n#define OPENOCD_FLASH_NOR_CORE_H\n\n#include <flash/common.h>\n\n/**\n * @file\n * Upper level NOR flash interfaces.\n */\n\nstruct image;\n\n/**\n * Describes the geometry and status of a single flash sector\n * within a flash bank.  A single bank typically consists of multiple\n * sectors, each of which can be erased and protected independently.\n */\nstruct flash_sector {\n\t/** Bus offset from start of the flash chip (in bytes). */\n\tuint32_t offset;\n\t/** Number of bytes in this flash sector. */\n\tuint32_t size;\n\t/**\n\t * Indication of erasure status: 0 = not erased, 1 = erased,\n\t * other = unknown.  Set by @c flash_driver_s::erase_check only.\n\t *\n\t * This information must be considered stale immediately.\n\t * Don't set it in flash_driver_s::erase or a device mass_erase\n\t * Don't clear it in flash_driver_s::write\n\t * The flag is not used in a protection block\n\t */\n\tint is_erased;\n\t/**\n\t * Indication of protection status: 0 = unprotected/unlocked,\n\t * 1 = protected/locked, other = unknown.  Set by\n\t * @c flash_driver_s::protect_check.\n\t *\n\t * This information must be considered stale immediately.\n\t * A million things could make it stale: power cycle,\n\t * reset of target, code running on target, etc.\n\t *\n\t * If a flash_bank uses an extra array of protection blocks,\n\t * protection flag is not valid in sector array\n\t */\n\tint is_protected;\n};\n\n/** Special value for write_start_alignment and write_end_alignment field */\n#define FLASH_WRITE_ALIGN_SECTOR\tUINT32_MAX\n\n/** Special values for minimal_write_gap field */\n#define FLASH_WRITE_CONTINUOUS\t\t0\n#define FLASH_WRITE_GAP_SECTOR\t\tUINT32_MAX\n\n/**\n * Provides details of a flash bank, available either on-chip or through\n * a major interface.\n *\n * This structure will be passed as a parameter to the callbacks in the\n * flash_driver_s structure, some of which may modify the contents of\n * this structure of the area of flash that it defines.  Driver writers\n * may use the @c driver_priv member to store additional data on a\n * per-bank basis, if required.\n */\nstruct flash_bank {\n\tchar *name;\n\n\tstruct target *target; /**< Target to which this bank belongs. */\n\n\tconst struct flash_driver *driver; /**< Driver for this bank. */\n\tvoid *driver_priv; /**< Private driver storage pointer */\n\n\tunsigned int bank_number; /**< The 'bank' (or chip number) of this instance. */\n\ttarget_addr_t base; /**< The base address of this bank */\n\tuint32_t size; /**< The size of this chip bank, in bytes */\n\n\tunsigned int chip_width; /**< Width of the chip in bytes (1,2,4 bytes) */\n\tunsigned int bus_width; /**< Maximum bus width, in bytes (1,2,4 bytes) */\n\n\t/** Erased value. Defaults to 0xFF. */\n\tuint8_t erased_value;\n\n\t/** Default padded value used, normally this matches the  flash\n\t * erased value. Defaults to 0xFF. */\n\tuint8_t default_padded_value;\n\n\t/** Required alignment of flash write start address.\n\t * Default 0, no alignment. Can be any power of two or FLASH_WRITE_ALIGN_SECTOR */\n\tuint32_t write_start_alignment;\n\t/** Required alignment of flash write end address.\n\t * Default 0, no alignment. Can be any power of two or FLASH_WRITE_ALIGN_SECTOR */\n\tuint32_t write_end_alignment;\n\t/** Minimal gap between sections to discontinue flash write\n\t * Default FLASH_WRITE_GAP_SECTOR splits the write if one or more untouched\n\t * sectors in between.\n     * Can be size in bytes or FLASH_WRITE_CONTINUOUS */\n\tuint32_t minimal_write_gap;\n\n\t/**\n\t * The number of sectors on this chip.  This value will\n\t * be set initially to 0, and the flash driver must set this to\n\t * some non-zero value during \"probe()\" or \"auto_probe()\".\n\t */\n\tunsigned int num_sectors;\n\t/** Array of sectors, allocated and initialized by the flash driver */\n\tstruct flash_sector *sectors;\n\n\t/**\n\t * The number of protection blocks in this bank. This value\n\t * is set initially to 0 and sectors are used as protection blocks.\n\t * Driver probe can set protection blocks array to work with\n\t * protection granularity different than sector size.\n\t */\n\tunsigned int num_prot_blocks;\n\t/** Array of protection blocks, allocated and initialized by the flash driver */\n\tstruct flash_sector *prot_blocks;\n\n\tstruct flash_bank *next; /**< The next flash bank on this chip */\n};\n\n/** Registers the 'flash' subsystem commands */\nint flash_register_commands(struct command_context *cmd_ctx);\n\n/**\n * Erases @a length bytes in the @a target flash, starting at @a addr.\n * The range @a addr to @a addr + @a length - 1 must be strictly\n * sector aligned, unless @a pad is true.  Setting @a pad true extends\n * the range, at beginning and/or end, if needed for sector alignment.\n * @returns ERROR_OK if successful; otherwise, an error code.\n */\nint flash_erase_address_range(struct target *target,\n\t\tbool pad, target_addr_t addr, uint32_t length);\n\nint flash_unlock_address_range(struct target *target, target_addr_t addr,\n\t\tuint32_t length);\n\n/**\n * Align start address of a flash write region according to bank requirements.\n * @param bank Pointer to bank descriptor structure\n * @param addr Address to align\n * @returns Aligned address\n*/\ntarget_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t addr);\n/**\n * Align end address of a flash write region according to bank requirements.\n * Note: Use address of the last byte to write, not the next after the region.\n * @param bank Pointer to bank descriptor structure\n * @param addr Address to align (address of the last byte to write)\n * @returns Aligned address (address of the last byte of padded region)\n*/\ntarget_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr);\n\n/**\n * Writes @a image into the @a target flash.  The @a written parameter\n * will contain the\n * @param target The target with the flash to be programmed.\n * @param image The image that will be programmed to flash.\n * @param written On return, contains the number of bytes written.\n * @param erase Indicates whether the flash driver should first\n * erase the corresponding banks or sectors before programming.\n * @returns ERROR_OK if successful; otherwise, an error code.\n */\nint flash_write(struct target *target,\n\t\tstruct image *image, uint32_t *written, bool erase);\n\n/**\n * Forces targets to re-examine their erase/protection state.\n * This routine must be called when the system may modify the status.\n */\nvoid flash_set_dirty(void);\n\n/** @returns The number of flash banks currently defined. */\nunsigned int flash_get_bank_count(void);\n\n/** Deallocates bank->driver_priv */\nvoid default_flash_free_driver_priv(struct flash_bank *bank);\n\n/** Deallocates all flash banks */\nvoid flash_free_all_banks(void);\n\n/**\n * Provides default read implementation for flash memory.\n * @param bank The bank to read.\n * @param buffer The data bytes read.\n * @param offset The offset into the chip to read.\n * @param count The number of bytes to read.\n * @returns ERROR_OK if successful; otherwise, an error code.\n */\nint default_flash_read(struct flash_bank *bank,\n\t\tuint8_t *buffer, uint32_t offset, uint32_t count);\n\n/**\n * Provides default verify implementation for flash memory.\n * @param bank The bank to verify.\n * @param buffer The data bytes to verify.\n * @param offset The offset into the chip to verify.\n * @param count The number of bytes to verify.\n * @returns ERROR_OK if successful; otherwise, an error code.\n */\nint default_flash_verify(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count);\n\n/**\n * Provides default erased-bank check handling. Checks to see if\n * the flash driver knows they are erased; if things look uncertain,\n * this routine will call default_flash_mem_blank_check() to confirm.\n * @returns ERROR_OK if successful; otherwise, an error code.\n */\nint default_flash_blank_check(struct flash_bank *bank);\n/**\n * Returns the flash bank specified by @a name, which matches the\n * driver name and a suffix (option) specify the driver-specific\n * bank number. The suffix consists of the '.' and the driver-specific\n * bank number: when two str9x banks are defined, then 'str9x.1' refers\n * to the second.\n */\nint get_flash_bank_by_name(const char *name, struct flash_bank **bank_result);\n/**\n * Returns the flash bank specified by @a name, which matches the\n * driver name and a suffix (option) specify the driver-specific\n * bank number. The suffix consists of the '.' and the driver-specific\n * bank number: when two str9x banks are defined, then 'str9x.1' refers\n * to the second.\n */\nstruct flash_bank *get_flash_bank_by_name_noprobe(const char *name);\n/**\n * Returns the flash bank like get_flash_bank_by_name(), without probing.\n * @param num The flash bank number.\n * @param bank returned bank if fn returns ERROR_OK\n * @returns ERROR_OK if successful\n */\nint get_flash_bank_by_num(unsigned int num, struct flash_bank **bank);\n/**\n * Retrieves @a bank from a command argument, reporting errors parsing\n * the bank identifier or retrieving the specified bank.  The bank\n * may be identified by its bank number or by @c name.instance, where\n * @a instance is driver-specific.\n * @param name_index The index to the string in args containing the\n * bank identifier.\n * @param bank On output, contains a pointer to the bank or NULL.\n * @returns ERROR_OK on success, or an error indicating the problem.\n */\nCOMMAND_HELPER(flash_command_get_bank, unsigned name_index,\n\t\tstruct flash_bank **bank);\n/**\n * Retrieves @a bank from a command argument, reporting errors parsing\n * the bank identifier or retrieving the specified bank.  The bank\n * may be identified by its bank number or by @c name.instance, where\n * @a instance is driver-specific.\n * @param name_index The index to the string in args containing the\n * bank identifier.\n * @param bank On output, contains a pointer to the bank or NULL.\n * @param do_probe Does auto-probing when set, otherwise without probing.\n * @returns ERROR_OK on success, or an error indicating the problem.\n */\nCOMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index,\n\t\tstruct flash_bank **bank, bool do_probe);\n/**\n * Returns the flash bank like get_flash_bank_by_num(), without probing.\n * @param num The flash bank number.\n * @returns A struct flash_bank for flash bank @a num, or NULL.\n */\nstruct flash_bank *get_flash_bank_by_num_noprobe(unsigned int num);\n/**\n * Returns the flash bank located at a specified address.\n * @param target The target, presumed to contain one or more banks.\n * @param addr An address that is within the range of the bank.\n * @param check return ERROR_OK and result_bank NULL if the bank does not exist\n * @param result_bank The struct flash_bank located at @a addr, or NULL.\n * @returns ERROR_OK on success, or an error indicating the problem.\n */\nint get_flash_bank_by_addr(struct target *target, target_addr_t addr, bool check,\n\t\tstruct flash_bank **result_bank);\n/**\n * Allocate and fill an array of sectors or protection blocks.\n * @param offset Offset of first block.\n * @param size Size of each block.\n * @param num_blocks Number of blocks in array.\n * @returns A struct flash_sector pointer or NULL when allocation failed.\n */\nstruct flash_sector *alloc_block_array(uint32_t offset, uint32_t size,\n\t\tunsigned int num_blocks);\n\n#endif /* OPENOCD_FLASH_NOR_CORE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/driver.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_DRIVER_H\n#define OPENOCD_FLASH_NOR_DRIVER_H\n\nstruct flash_bank;\n\n#define __FLASH_BANK_COMMAND(name) \\\n\t\tCOMMAND_HELPER(name, struct flash_bank *bank)\n\n/**\n * @brief Provides the implementation-independent structure that defines\n * all of the callbacks required by OpenOCD flash drivers.\n *\n * Driver authors must implement the routines defined here, providing an\n * instance with the fields filled out.  After that, the instance must\n * be registered in flash.c, so it can be used by the driver lookup system.\n *\n * Specifically, the user can issue the command: @par\n * @code\n * flash bank DRIVERNAME ...parameters...\n * @endcode\n *\n * OpenOCD will search for the driver with a @c flash_driver_s::name\n * that matches @c DRIVERNAME.\n *\n * The flash subsystem calls some of the other drivers routines a using\n * corresponding static <code>flash_driver_<i>callback</i>()</code>\n * routine in flash.c.\n */\nstruct flash_driver {\n\t/**\n\t * Gives a human-readable name of this flash driver,\n\t * This field is used to select and initialize the driver.\n\t */\n\tconst char *name;\n\n\t/**\n\t * Gives a human-readable description of arguments.\n\t */\n\tconst char *usage;\n\n\t/**\n\t * An array of driver-specific commands to register.  When called\n\t * during the \"flash bank\" command, the driver can register addition\n\t * commands to support new flash chip functions.\n\t */\n\tconst struct command_registration *commands;\n\n\t/**\n\t * Finish the \"flash bank\" command for @a bank.  The\n\t * @a bank parameter will have been filled in by the core flash\n\t * layer when this routine is called, and the driver can store\n\t * additional information in its struct flash_bank::driver_priv field.\n\t *\n\t * The CMD_ARGV are: @par\n\t * @code\n\t * CMD_ARGV[0] = bank\n\t * CMD_ARGV[1] = drivername {name above}\n\t * CMD_ARGV[2] = baseaddress\n\t * CMD_ARGV[3] = lengthbytes\n\t * CMD_ARGV[4] = chip_width_in bytes\n\t * CMD_ARGV[5] = bus_width_in_bytes\n\t * CMD_ARGV[6] = driver-specific parameters\n\t * @endcode\n\t *\n\t * For example, CMD_ARGV[4] = 2 (for 16 bit flash),\n\t *\tCMD_ARGV[5] = 4 (for 32 bit bus).\n\t *\n\t * If extra arguments are provided (@a CMD_ARGC > 6), they will\n\t * start in @a CMD_ARGV[6].  These can be used to implement\n\t * driver-specific extensions.\n\t *\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\t__FLASH_BANK_COMMAND((*flash_bank_command));\n\n\t/**\n\t * Bank/sector erase routine (target-specific).  When\n\t * called, the flash driver should erase the specified sectors\n\t * using whatever means are at its disposal.\n\t *\n\t * @param bank The bank of flash to be erased.\n\t * @param first The number of the first sector to erase, typically 0.\n\t * @param last The number of the last sector to erase, typically N-1.\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*erase)(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last);\n\n\t/**\n\t * Bank/sector protection routine (target-specific).\n\t *\n\t * If protection is not implemented, set method to NULL\n\t *\n\t * When called, the driver should enable/disable protection\n\t * for MINIMUM the range covered by first..last sectors\n\t * inclusive. Some chips have alignment requirements will\n\t * cause the actual range to be protected / unprotected to\n\t * be larger than the first..last range.\n\t *\n\t * @param bank The bank to protect or unprotect.\n\t * @param set If non-zero, enable protection; if 0, disable it.\n\t * @param first The first sector to (un)protect, typically 0.\n\t * @param last The last sector to (un)project, typically N-1.\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*protect)(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last);\n\n\t/**\n\t * Program data into the flash.  Note CPU address will be\n\t * \"bank->base + offset\", while the physical address is\n\t * dependent upon current target MMU mappings.\n\t *\n\t * @param bank The bank to program\n\t * @param buffer The data bytes to write.\n\t * @param offset The offset into the chip to program.\n\t * @param count The number of bytes to write.\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*write)(struct flash_bank *bank,\n\t\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count);\n\n\t/**\n\t * Read data from the flash. Note CPU address will be\n\t * \"bank->base + offset\", while the physical address is\n\t * dependent upon current target MMU mappings.\n\t *\n\t * @param bank The bank to read.\n\t * @param buffer The data bytes read.\n\t * @param offset The offset into the chip to read.\n\t * @param count The number of bytes to read.\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\t int (*read)(struct flash_bank *bank,\n\t\t\tuint8_t *buffer, uint32_t offset, uint32_t count);\n\n\t/**\n\t * Verify data in flash.  Note CPU address will be\n\t * \"bank->base + offset\", while the physical address is\n\t * dependent upon current target MMU mappings.\n\t *\n\t * @param bank The bank to verify\n\t * @param buffer The data bytes to verify against.\n\t * @param offset The offset into the chip to verify.\n\t * @param count The number of bytes to verify.\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*verify)(struct flash_bank *bank,\n\t\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count);\n\n\t/**\n\t * Probe to determine what kind of flash is present.\n\t * This is invoked by the \"probe\" script command.\n\t *\n\t * @param bank The bank to probe\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*probe)(struct flash_bank *bank);\n\n\t/**\n\t * Check the erasure status of a flash bank.\n\t * When called, the driver routine must perform the required\n\t * checks and then set the @c flash_sector_s::is_erased field\n\t * for each of the flash banks's sectors.\n\t *\n\t * @param bank The bank to check\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*erase_check)(struct flash_bank *bank);\n\n\t/**\n\t * Determine if the specific bank is \"protected\" or not.\n\t * When called, the driver routine must must perform the\n\t * required protection check(s) and then set the @c\n\t * flash_sector_s::is_protected field for each of the flash\n\t * bank's sectors.\n\t *\n\t * If protection is not implemented, set method to NULL\n\t *\n\t * @param bank - the bank to check\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*protect_check)(struct flash_bank *bank);\n\n\t/**\n\t * Display human-readable information about the flash\n\t * bank.\n\t *\n\t * @param bank - the bank to get info about\n\t * @param cmd - command invocation instance for which to generate\n\t *              the textual output\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*info)(struct flash_bank *bank, struct command_invocation *cmd);\n\n\t/**\n\t * A more gentle flavor of flash_driver_s::probe, performing\n\t * setup with less noise.  Generally, driver routines should test\n\t * to see if the bank has already been probed; if it has, the\n\t * driver probably should not perform its probe a second time.\n\t *\n\t * This callback is often called from the inside of other\n\t * routines (e.g. GDB flash downloads) to autoprobe the flash as\n\t * it is programming the flash.\n\t *\n\t * @param bank - the bank to probe\n\t * @returns ERROR_OK if successful; otherwise, an error code.\n\t */\n\tint (*auto_probe)(struct flash_bank *bank);\n\n\t/**\n\t * Deallocates private driver structures.\n\t * Use default_flash_free_driver_priv() to simply free(bank->driver_priv)\n\t *\n\t * @param bank - the bank being destroyed\n\t */\n\tvoid (*free_driver_priv)(struct flash_bank *bank);\n};\n\n#define FLASH_BANK_COMMAND_HANDLER(name) \\\n\tstatic __FLASH_BANK_COMMAND(name)\n\n/**\n * Find a NOR flash driver by its name.\n * @param name The name of the requested driver.\n * @returns The flash_driver called @c name, or NULL if not found.\n */\nconst struct flash_driver *flash_driver_find_by_name(const char *name);\n\nextern const struct flash_driver aduc702x_flash;\nextern const struct flash_driver aducm360_flash;\nextern const struct flash_driver ambiqmicro_flash;\nextern const struct flash_driver at91sam3_flash;\nextern const struct flash_driver at91sam4_flash;\nextern const struct flash_driver at91sam4l_flash;\nextern const struct flash_driver at91sam7_flash;\nextern const struct flash_driver at91samd_flash;\nextern const struct flash_driver ath79_flash;\nextern const struct flash_driver atsame5_flash;\nextern const struct flash_driver atsamv_flash;\nextern const struct flash_driver avr_flash;\nextern const struct flash_driver bluenrgx_flash;\nextern const struct flash_driver cc26xx_flash;\nextern const struct flash_driver cc3220sf_flash;\nextern const struct flash_driver cfi_flash;\nextern const struct flash_driver dsp5680xx_flash;\nextern const struct flash_driver efm32_flash;\nextern const struct flash_driver em357_flash;\nextern const struct flash_driver esirisc_flash;\nextern const struct flash_driver faux_flash;\nextern const struct flash_driver fespi_flash;\nextern const struct flash_driver fm3_flash;\nextern const struct flash_driver fm4_flash;\nextern const struct flash_driver jtagspi_flash;\nextern const struct flash_driver kinetis_flash;\nextern const struct flash_driver kinetis_ke_flash;\nextern const struct flash_driver lpc2000_flash;\nextern const struct flash_driver lpc288x_flash;\nextern const struct flash_driver lpc2900_flash;\nextern const struct flash_driver lpcspifi_flash;\nextern const struct flash_driver max32xxx_flash;\nextern const struct flash_driver mdr_flash;\nextern const struct flash_driver mrvlqspi_flash;\nextern const struct flash_driver msp432_flash;\nextern const struct flash_driver niietcm4_flash;\nextern const struct flash_driver npcx_flash;\nextern const struct flash_driver nrf51_flash;\nextern const struct flash_driver nrf5_flash;\nextern const struct flash_driver numicro_flash;\nextern const struct flash_driver ocl_flash;\nextern const struct flash_driver pic32mx_flash;\nextern const struct flash_driver psoc4_flash;\nextern const struct flash_driver psoc5lp_eeprom_flash;\nextern const struct flash_driver psoc5lp_flash;\nextern const struct flash_driver psoc5lp_nvl_flash;\nextern const struct flash_driver psoc6_flash;\nextern const struct flash_driver qn908x_flash;\nextern const struct flash_driver renesas_rpchf_flash;\nextern const struct flash_driver rp2040_flash;\nextern const struct flash_driver rsl10_flash;\nextern const struct flash_driver sh_qspi_flash;\nextern const struct flash_driver sim3x_flash;\nextern const struct flash_driver stellaris_flash;\nextern const struct flash_driver stm32f1x_flash;\nextern const struct flash_driver stm32f2x_flash;\nextern const struct flash_driver stm32h7x_flash;\nextern const struct flash_driver stm32l4x_flash;\nextern const struct flash_driver stm32lx_flash;\nextern const struct flash_driver stmqspi_flash;\nextern const struct flash_driver stmsmi_flash;\nextern const struct flash_driver str7x_flash;\nextern const struct flash_driver str9x_flash;\nextern const struct flash_driver str9xpec_flash;\nextern const struct flash_driver swm050_flash;\nextern const struct flash_driver tms470_flash;\nextern const struct flash_driver virtual_flash;\nextern const struct flash_driver w600_flash;\nextern const struct flash_driver xcf_flash;\nextern const struct flash_driver xmc1xxx_flash;\nextern const struct flash_driver xmc4xxx_flash;\n\n#endif /* OPENOCD_FLASH_NOR_DRIVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/drivers.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"imp.h\"\n\n/**\n * The list of built-in flash drivers.\n * @todo Make this dynamically extendable with loadable modules.\n */\nstatic const struct flash_driver * const flash_drivers[] = {\n\t&aduc702x_flash,\n\t&aducm360_flash,\n\t&ambiqmicro_flash,\n\t&at91sam3_flash,\n\t&at91sam4_flash,\n\t&at91sam4l_flash,\n\t&at91sam7_flash,\n\t&at91samd_flash,\n\t&ath79_flash,\n\t&atsame5_flash,\n\t&atsamv_flash,\n\t&avr_flash,\n\t&bluenrgx_flash,\n\t&cc3220sf_flash,\n\t&cc26xx_flash,\n\t&cfi_flash,\n\t&dsp5680xx_flash,\n\t&efm32_flash,\n\t&em357_flash,\n\t&esirisc_flash,\n\t&faux_flash,\n\t&fm3_flash,\n\t&fm4_flash,\n\t&fespi_flash,\n\t&jtagspi_flash,\n\t&kinetis_flash,\n\t&kinetis_ke_flash,\n\t&lpc2000_flash,\n\t&lpc288x_flash,\n\t&lpc2900_flash,\n\t&lpcspifi_flash,\n\t&max32xxx_flash,\n\t&mdr_flash,\n\t&mrvlqspi_flash,\n\t&msp432_flash,\n\t&niietcm4_flash,\n\t&npcx_flash,\n\t&nrf5_flash,\n\t&nrf51_flash,\n\t&numicro_flash,\n\t&ocl_flash,\n\t&pic32mx_flash,\n\t&psoc4_flash,\n\t&psoc5lp_flash,\n\t&psoc5lp_eeprom_flash,\n\t&psoc5lp_nvl_flash,\n\t&psoc6_flash,\n\t&qn908x_flash,\n\t&renesas_rpchf_flash,\n\t&rp2040_flash,\n\t&sh_qspi_flash,\n\t&sim3x_flash,\n\t&stellaris_flash,\n\t&stm32f1x_flash,\n\t&stm32f2x_flash,\n\t&stm32lx_flash,\n\t&stm32l4x_flash,\n\t&stm32h7x_flash,\n\t&stmsmi_flash,\n\t&stmqspi_flash,\n\t&str7x_flash,\n\t&str9x_flash,\n\t&str9xpec_flash,\n\t&swm050_flash,\n\t&tms470_flash,\n\t&virtual_flash,\n\t&xcf_flash,\n\t&xmc1xxx_flash,\n\t&xmc4xxx_flash,\n\t&w600_flash,\n\t&rsl10_flash,\n\tNULL,\n};\n\nconst struct flash_driver *flash_driver_find_by_name(const char *name)\n{\n\tfor (unsigned i = 0; flash_drivers[i]; i++) {\n\t\tif (strcmp(name, flash_drivers[i]->name) == 0)\n\t\t\treturn flash_drivers[i];\n\t}\n\treturn NULL;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/dsp5680xx_flash.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Rodrigo L. Rosa                                 *\n *   rodrigorosa.LG@gmail.com                                              *\n *                                                                         *\n *   Based on a file written by:                                           *\n *   Kevin McGuire                                                         *\n *   Marcel Wijlaars                                                       *\n *   Michael Ashton                                                        *\n ***************************************************************************/\n\n/**\n * @file   dsp5680xx_flash.c\n * @author Rodrigo L. Rosa <rodrigorosa.LG@gmail.com>\n * @date   Thu Jun  9 18:21:58 2011\n *\n * @brief  This file implements the basic functions to run flashing commands\n * from the TCL interface.\n * It allows the user to flash the Freescale 5680xx DSP.\n *\n *\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/dsp5680xx.h>\n\nstatic int dsp5680xx_build_sector_list(struct flash_bank *bank)\n{\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; ++i) {\n\t\tbank->sectors[i].offset = i * HFM_SECTOR_SIZE;\n\t\tbank->sectors[i].size = HFM_SECTOR_SIZE;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\tLOG_USER(\"%s not tested yet.\", __func__);\n\treturn ERROR_OK;\n\n}\n\n/* flash bank dsp5680xx 0 0 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(dsp5680xx_flash_bank_command)\n{\n\tbank->base = HFM_FLASH_BASE_ADDR;\n\tbank->size = HFM_SIZE_BYTES; /* top 4k not accessible */\n\tbank->num_sectors = HFM_SECTOR_COUNT;\n\tdsp5680xx_build_sector_list(bank);\n\n\treturn ERROR_OK;\n}\n\n/**\n * A memory mapped register (PROT) holds information regarding sector protection.\n * Protection refers to undesired core access.\n * The value in this register is loaded from flash upon reset.\n *\n * @param bank\n *\n * @return\n */\nstatic int dsp5680xx_flash_protect_check(struct flash_bank *bank)\n{\n\tint retval = ERROR_OK;\n\n\tuint16_t protected = 0;\n\n\tretval = dsp5680xx_f_protect_check(bank->target, &protected);\n\tif (retval != ERROR_OK) {\n\t\tfor (int i = 0; i < HFM_SECTOR_COUNT; i++)\n\t\t\tbank->sectors[i].is_protected = -1;\n\t\treturn ERROR_OK;\n\t}\n\tfor (int i = 0; i < HFM_SECTOR_COUNT / 2; i++) {\n\t\tif (protected & 1) {\n\t\t\tbank->sectors[2 * i].is_protected = 1;\n\t\t\tbank->sectors[2 * i + 1].is_protected = 1;\n\t\t} else {\n\t\t\tbank->sectors[2 * i].is_protected = 0;\n\t\t\tbank->sectors[2 * i + 1].is_protected = 0;\n\t\t}\n\t\tprotected = (protected >> 1);\n\t}\n\treturn retval;\n}\n\n/**\n * Protection functionality is not implemented.\n * The current implementation applies/removes security on the chip.\n * The chip is effectively secured/unsecured after the first reset\n * following the execution of this function.\n *\n * @param bank\n * @param set Apply or remove security on the chip.\n * @param first This parameter is ignored.\n * @param last This parameter is ignored.\n *\n * @return\n */\nstatic int dsp5680xx_flash_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n/**\n * This applies security to flash module after next reset, it does\n * not actually apply protection (protection refers to undesired access from the core)\n */\n\tint retval;\n\n\tif (set)\n\t\tretval = dsp5680xx_f_lock(bank->target);\n\telse\n\t\tretval = dsp5680xx_f_unlock(bank->target);\n\n\treturn retval;\n}\n\n/**\n * The dsp5680xx use word addressing. The \"/2\" that appear in the following code\n * are a workaround for the fact that OpenOCD uses byte addressing.\n *\n * @param bank\n * @param buffer Data to write to flash.\n * @param offset\n * @param count In bytes (2 bytes per address).\n *\n * @return\n */\nstatic int dsp5680xx_flash_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t\t uint32_t offset, uint32_t count)\n{\n\tif ((offset + count / 2) > bank->size) {\n\t\tLOG_ERROR(\"%s: Flash bank cannot fit data.\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (offset % 2) {\n\t\t/**\n\t\t * Writing to odd addresses not supported.\n\t\t * This chip uses word addressing, Openocd only supports byte addressing.\n\t\t * The workaround results in disabling writing to odd byte addresses\n\t\t */\n\t\tLOG_ERROR(\"%s: Writing to odd addresses not supported for this target\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn dsp5680xx_f_wr(bank->target, buffer, bank->base + offset / 2, count, 0);\n}\n\nstatic int dsp5680xx_probe(struct flash_bank *bank)\n{\n\tLOG_DEBUG(\"%s not implemented\", __func__);\n\treturn ERROR_OK;\n}\n\n/**\n * The flash module (FM) on the dsp5680xx supports both individual sector\n * and mass erase of the flash memory.\n * If this function is called with @a first == @a last == 0 or if @a first is the\n * first sector (#0) and @a last is the last sector then the mass erase command\n * is executed (much faster than erasing each sector individually).\n *\n * @param bank\n * @param first\n * @param last\n *\n * @return\n */\nstatic int dsp5680xx_flash_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\treturn dsp5680xx_f_erase(bank->target, (uint32_t) first, (uint32_t) last);\n}\n\n/**\n * The flash module (FM) on the dsp5680xx support a blank check function.\n * This function executes the FM's blank check functionality on each and every sector.\n *\n * @param bank\n *\n * @return\n */\nstatic int dsp5680xx_flash_erase_check(struct flash_bank *bank)\n{\n\tint retval = ERROR_OK;\n\n\tuint8_t erased = 0;\n\n\tuint32_t i;\n\n\tfor (i = 0; i < HFM_SECTOR_COUNT; i++) {\n\t\tretval = dsp5680xx_f_erase_check(bank->target, &erased, i);\n\t\tif (retval != ERROR_OK) {\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t} else {\n\t\t\tif (erased)\n\t\t\t\tbank->sectors[i].is_erased = 1;\n\t\t\telse\n\t\t\t\tbank->sectors[i].is_erased = 0;\n\t\t}\n\t}\n\treturn retval;\n}\n\nconst struct flash_driver dsp5680xx_flash = {\n\t.name = \"dsp5680xx_flash\",\n\t.flash_bank_command = dsp5680xx_flash_bank_command,\n\t.erase = dsp5680xx_flash_erase,\n\t.protect = dsp5680xx_flash_protect,\n\t.write = dsp5680xx_flash_write,\n\t/* .read = default_flash_read, */\n\t.probe = dsp5680xx_probe,\n\t.auto_probe = dsp5680xx_probe,\n\t.erase_check = dsp5680xx_flash_erase_check,\n\t.protect_check = dsp5680xx_flash_protect_check,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/efm32.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *                                                                         *\n *   Copyright (C) 2013 by Roman Dmitrienko                                *\n *   me@iamroman.org                                                       *\n *                                                                         *\n *   Copyright (C) 2014 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   Copyright (C) 2021 Doug Brunner                                       *\n *   doug.a.brunner@gmail.com                                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n#define EFM_FAMILY_ID_GIANT_GECKO       72\n#define EFM_FAMILY_ID_LEOPARD_GECKO     74\n\n#define EFM32_FLASH_ERASE_TMO           100\n#define EFM32_FLASH_WDATAREADY_TMO      100\n#define EFM32_FLASH_WRITE_TMO           100\n\n#define EFM32_FLASH_BASE                0\n\n/* size in bytes, not words; must fit all Gecko devices */\n#define LOCKWORDS_SZ                512\n\n#define EFM32_MSC_INFO_BASE             0x0fe00000\n\n#define EFM32_MSC_USER_DATA             EFM32_MSC_INFO_BASE\n#define EFM32_MSC_LOCK_BITS             (EFM32_MSC_INFO_BASE+0x4000)\n#define EFM32_MSC_LOCK_BITS_EXTRA       (EFM32_MSC_LOCK_BITS+LOCKWORDS_SZ)\n#define EFM32_MSC_DEV_INFO              (EFM32_MSC_INFO_BASE+0x8000)\n\n/* PAGE_SIZE is not present in Zero, Happy and the original Gecko MCU */\n#define EFM32_MSC_DI_PAGE_SIZE          (EFM32_MSC_DEV_INFO+0x1e7)\n#define EFM32_MSC_DI_FLASH_SZ           (EFM32_MSC_DEV_INFO+0x1f8)\n#define EFM32_MSC_DI_RAM_SZ             (EFM32_MSC_DEV_INFO+0x1fa)\n#define EFM32_MSC_DI_PART_NUM           (EFM32_MSC_DEV_INFO+0x1fc)\n#define EFM32_MSC_DI_PART_FAMILY        (EFM32_MSC_DEV_INFO+0x1fe)\n#define EFM32_MSC_DI_PROD_REV           (EFM32_MSC_DEV_INFO+0x1ff)\n\n#define EFM32_MSC_REGBASE               0x400c0000\n#define EFM32_MSC_REGBASE_SERIES1       0x400e0000\n#define EFM32_MSC_REG_WRITECTRL         0x008\n#define EFM32_MSC_WRITECTRL_WREN_MASK   0x1\n#define EFM32_MSC_REG_WRITECMD          0x00c\n#define EFM32_MSC_WRITECMD_LADDRIM_MASK 0x1\n#define EFM32_MSC_WRITECMD_ERASEPAGE_MASK 0x2\n#define EFM32_MSC_WRITECMD_WRITEONCE_MASK 0x8\n#define EFM32_MSC_REG_ADDRB             0x010\n#define EFM32_MSC_REG_WDATA             0x018\n#define EFM32_MSC_REG_STATUS            0x01c\n#define EFM32_MSC_STATUS_BUSY_MASK      0x1\n#define EFM32_MSC_STATUS_LOCKED_MASK    0x2\n#define EFM32_MSC_STATUS_INVADDR_MASK   0x4\n#define EFM32_MSC_STATUS_WDATAREADY_MASK 0x8\n#define EFM32_MSC_STATUS_WORDTIMEOUT_MASK 0x10\n#define EFM32_MSC_STATUS_ERASEABORTED_MASK 0x20\n#define EFM32_MSC_REG_LOCK              0x03c\n#define EFM32_MSC_REG_LOCK_SERIES1      0x040\n#define EFM32_MSC_LOCK_LOCKKEY          0x1b71\n\nenum efm32_bank_index {\n\tEFM32_BANK_INDEX_MAIN,\n\tEFM32_BANK_INDEX_USER_DATA,\n\tEFM32_BANK_INDEX_LOCK_BITS,\n\tEFM32_N_BANKS\n};\n\nstatic int efm32x_get_bank_index(target_addr_t base)\n{\n\tswitch (base) {\n\t\tcase EFM32_FLASH_BASE:\n\t\t\treturn EFM32_BANK_INDEX_MAIN;\n\t\tcase EFM32_MSC_USER_DATA:\n\t\t\treturn EFM32_BANK_INDEX_USER_DATA;\n\t\tcase EFM32_MSC_LOCK_BITS:\n\t\t\treturn EFM32_BANK_INDEX_LOCK_BITS;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n}\n\nstruct efm32_family_data {\n\tint family_id;\n\tconst char *name;\n\n\t/* EFM32 series (EFM32LG995F is the \"old\" series 0, while EFR32MG12P132\n\t   is the \"new\" series 1). Determines location of MSC registers. */\n\tint series;\n\n\t/* Page size in bytes, or 0 to read from EFM32_MSC_DI_PAGE_SIZE */\n\tint page_size;\n\n\t/* MSC register base address, or 0 to use default */\n\tuint32_t msc_regbase;\n};\n\nstruct efm32_info {\n\tconst struct efm32_family_data *family_data;\n\tuint16_t flash_sz_kib;\n\tuint16_t ram_sz_kib;\n\tuint16_t part_num;\n\tuint8_t part_family;\n\tuint8_t prod_rev;\n\tuint16_t page_size;\n};\n\nstruct efm32x_flash_chip {\n\tstruct efm32_info info;\n\tbool probed[EFM32_N_BANKS];\n\tuint32_t lb_page[LOCKWORDS_SZ/4];\n\tuint32_t reg_base;\n\tuint32_t reg_lock;\n\tuint32_t refcount;\n};\n\nstatic const struct efm32_family_data efm32_families[] = {\n\t\t{ 16, \"EFR32MG1P Mighty\", .series = 1 },\n\t\t{ 17, \"EFR32MG1B Mighty\", .series = 1 },\n\t\t{ 18, \"EFR32MG1V Mighty\", .series = 1 },\n\t\t{ 19, \"EFR32BG1P Blue\", .series = 1 },\n\t\t{ 20, \"EFR32BG1B Blue\", .series = 1 },\n\t\t{ 21, \"EFR32BG1V Blue\", .series = 1 },\n\t\t{ 25, \"EFR32FG1P Flex\", .series = 1 },\n\t\t{ 26, \"EFR32FG1B Flex\", .series = 1 },\n\t\t{ 27, \"EFR32FG1V Flex\", .series = 1 },\n\t\t{ 28, \"EFR32MG2P Mighty\", .series = 1 },\n\t\t{ 29, \"EFR32MG2B Mighty\", .series = 1 },\n\t\t{ 30, \"EFR32MG2V Mighty\", .series = 1 },\n\t\t{ 31, \"EFR32BG12P Blue\", .series = 1 },\n\t\t{ 32, \"EFR32BG12B Blue\", .series = 1 },\n\t\t{ 33, \"EFR32BG12V Blue\", .series = 1 },\n\t\t{ 37, \"EFR32FG12P Flex\", .series = 1 },\n\t\t{ 38, \"EFR32FG12B Flex\", .series = 1 },\n\t\t{ 39, \"EFR32FG12V Flex\", .series = 1 },\n\t\t{ 40, \"EFR32MG13P Mighty\", .series = 1 },\n\t\t{ 41, \"EFR32MG13B Mighty\", .series = 1 },\n\t\t{ 42, \"EFR32MG13V Mighty\", .series = 1 },\n\t\t{ 43, \"EFR32BG13P Blue\", .series = 1 },\n\t\t{ 44, \"EFR32BG13B Blue\", .series = 1 },\n\t\t{ 45, \"EFR32BG13V Blue\", .series = 1 },\n\t\t{ 46, \"EFR32ZG13P Zen\", .series = 1 },\n\t\t{ 49, \"EFR32FG13P Flex\", .series = 1 },\n\t\t{ 50, \"EFR32FG13B Flex\", .series = 1 },\n\t\t{ 51, \"EFR32FG13V Flex\", .series = 1 },\n\t\t{ 52, \"EFR32MG14P Mighty\", .series = 1 },\n\t\t{ 53, \"EFR32MG14B Mighty\", .series = 1 },\n\t\t{ 54, \"EFR32MG14V Mighty\", .series = 1 },\n\t\t{ 55, \"EFR32BG14P Blue\", .series = 1 },\n\t\t{ 56, \"EFR32BG14B Blue\", .series = 1 },\n\t\t{ 57, \"EFR32BG14V Blue\", .series = 1 },\n\t\t{ 58, \"EFR32ZG14P Zen\", .series = 1 },\n\t\t{ 61, \"EFR32FG14P Flex\", .series = 1 },\n\t\t{ 62, \"EFR32FG14B Flex\", .series = 1 },\n\t\t{ 63, \"EFR32FG14V Flex\", .series = 1 },\n\t\t{ 71, \"EFM32G\", .series = 0, .page_size = 512 },\n\t\t{ 72, \"EFM32GG Giant\", .series = 0 },\n\t\t{ 73, \"EFM32TG Tiny\", .series = 0, .page_size = 512 },\n\t\t{ 74, \"EFM32LG Leopard\", .series = 0 },\n\t\t{ 75, \"EFM32WG Wonder\", .series = 0 },\n\t\t{ 76, \"EFM32ZG Zero\", .series = 0, .page_size = 1024 },\n\t\t{ 77, \"EFM32HG Happy\", .series = 0, .page_size = 1024 },\n\t\t{ 81, \"EFM32PG1B Pearl\", .series = 1 },\n\t\t{ 83, \"EFM32JG1B Jade\", .series = 1 },\n\t\t{ 85, \"EFM32PG12B Pearl\", .series = 1 },\n\t\t{ 87, \"EFM32JG12B Jade\", .series = 1 },\n\t\t{ 89, \"EFM32PG13B Pearl\", .series = 1 },\n\t\t{ 91, \"EFM32JG13B Jade\", .series = 1 },\n\t\t{ 100, \"EFM32GG11B Giant\", .series = 1, .msc_regbase = 0x40000000 },\n\t\t{ 103, \"EFM32TG11B Tiny\", .series = 1, .msc_regbase = 0x40000000 },\n\t\t{ 106, \"EFM32GG12B Giant\", .series = 1, .msc_regbase = 0x40000000 },\n\t\t{ 120, \"EZR32WG Wonder\", .series = 0 },\n\t\t{ 121, \"EZR32LG Leopard\", .series = 0 },\n\t\t{ 122, \"EZR32HG Happy\", .series = 0, .page_size = 1024 },\n};\n\nconst struct flash_driver efm32_flash;\n\nstatic int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t addr, uint32_t count);\n\nstatic int efm32x_write_only_lockbits(struct flash_bank *bank);\n\nstatic int efm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_sz)\n{\n\treturn target_read_u16(bank->target, EFM32_MSC_DI_FLASH_SZ, flash_sz);\n}\n\nstatic int efm32x_get_ram_size(struct flash_bank *bank, uint16_t *ram_sz)\n{\n\treturn target_read_u16(bank->target, EFM32_MSC_DI_RAM_SZ, ram_sz);\n}\n\nstatic int efm32x_get_part_num(struct flash_bank *bank, uint16_t *pnum)\n{\n\treturn target_read_u16(bank->target, EFM32_MSC_DI_PART_NUM, pnum);\n}\n\nstatic int efm32x_get_part_family(struct flash_bank *bank, uint8_t *pfamily)\n{\n\treturn target_read_u8(bank->target, EFM32_MSC_DI_PART_FAMILY, pfamily);\n}\n\nstatic int efm32x_get_prod_rev(struct flash_bank *bank, uint8_t *prev)\n{\n\treturn target_read_u8(bank->target, EFM32_MSC_DI_PROD_REV, prev);\n}\n\nstatic int efm32x_read_reg_u32(struct flash_bank *bank, target_addr_t offset,\n\t\t\t       uint32_t *value)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tuint32_t base = efm32x_info->reg_base;\n\n\treturn target_read_u32(bank->target, base + offset, value);\n}\n\nstatic int efm32x_write_reg_u32(struct flash_bank *bank, target_addr_t offset,\n\t\t\t       uint32_t value)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tuint32_t base = efm32x_info->reg_base;\n\n\treturn target_write_u32(bank->target, base + offset, value);\n}\n\nstatic int efm32x_read_info(struct flash_bank *bank)\n{\n\tint ret;\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tstruct efm32_info *efm32_info = &(efm32x_info->info);\n\n\tmemset(efm32_info, 0, sizeof(struct efm32_info));\n\n\tconst struct cortex_m_common *cortex_m = target_to_cm(bank->target);\n\n\tswitch (cortex_m->core_info->partno) {\n\tcase CORTEX_M3_PARTNO:\n\tcase CORTEX_M4_PARTNO:\n\tcase CORTEX_M0P_PARTNO:\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Target is not Cortex-Mx Device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = efm32x_get_flash_size(bank, &(efm32_info->flash_sz_kib));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_get_ram_size(bank, &(efm32_info->ram_sz_kib));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_get_part_num(bank, &(efm32_info->part_num));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_get_part_family(bank, &(efm32_info->part_family));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_get_prod_rev(bank, &(efm32_info->prod_rev));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(efm32_families); i++) {\n\t\tif (efm32_families[i].family_id == efm32_info->part_family)\n\t\t\tefm32_info->family_data = &efm32_families[i];\n\t}\n\n\tif (!efm32_info->family_data) {\n\t\tLOG_ERROR(\"Unknown MCU family %d\", efm32_info->part_family);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (efm32_info->family_data->series) {\n\t\tcase 0:\n\t\t\tefm32x_info->reg_base = EFM32_MSC_REGBASE;\n\t\t\tefm32x_info->reg_lock = EFM32_MSC_REG_LOCK;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tefm32x_info->reg_base = EFM32_MSC_REGBASE_SERIES1;\n\t\t\tefm32x_info->reg_lock = EFM32_MSC_REG_LOCK_SERIES1;\n\t\t\tbreak;\n\t}\n\n\tif (efm32_info->family_data->msc_regbase != 0)\n\t\tefm32x_info->reg_base = efm32_info->family_data->msc_regbase;\n\n\tif (efm32_info->family_data->page_size != 0) {\n\t\tefm32_info->page_size = efm32_info->family_data->page_size;\n\t} else {\n\t\tuint8_t pg_size = 0;\n\t\tret = target_read_u8(bank->target, EFM32_MSC_DI_PAGE_SIZE,\n\t\t\t&pg_size);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tefm32_info->page_size = (1 << ((pg_size+10) & 0xff));\n\n\t\tif (efm32_info->part_family == EFM_FAMILY_ID_GIANT_GECKO ||\n\t\t\t\tefm32_info->part_family == EFM_FAMILY_ID_LEOPARD_GECKO) {\n\t\t\t/* Giant or Leopard Gecko */\n\t\t\tif (efm32_info->prod_rev < 18) {\n\t\t\t\t/* EFM32 GG/LG errata: MEM_INFO_PAGE_SIZE is invalid\n\t\t\t\t   for MCUs with PROD_REV < 18 */\n\t\t\t\tif (efm32_info->flash_sz_kib < 512)\n\t\t\t\t\tefm32_info->page_size = 2048;\n\t\t\t\telse\n\t\t\t\t\tefm32_info->page_size = 4096;\n\t\t\t}\n\t\t}\n\n\t\tif ((efm32_info->page_size != 2048) &&\n\t\t\t\t(efm32_info->page_size != 4096)) {\n\t\t\tLOG_ERROR(\"Invalid page size %u\", efm32_info->page_size);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* flash bank efm32 <base> <size> 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(efm32x_flash_bank_command)\n{\n\tstruct efm32x_flash_chip *efm32x_info = NULL;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint bank_index = efm32x_get_bank_index(bank->base);\n\tif (bank_index < 0) {\n\t\tLOG_ERROR(\"Flash bank with base address %\" PRIx32 \" is not supported\",\n\t\t\t(uint32_t) bank->base);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* look for an existing flash structure matching target */\n\tfor (struct flash_bank *bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {\n\t\tif (bank_iter->driver == &efm32_flash\n\t\t\t&& bank_iter->target == bank->target\n\t\t\t&& bank->driver_priv) {\n\t\t\tefm32x_info = bank->driver_priv;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!efm32x_info) {\n\t\t/* target not matched, make a new one */\n\t\tefm32x_info = calloc(1, sizeof(struct efm32x_flash_chip));\n\n\t\tmemset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);\n\t}\n\n\t++efm32x_info->refcount;\n\tbank->driver_priv = efm32x_info;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Remove flash structure corresponding to this bank,\n * if and only if it's not used by any others\n */\nstatic void efm32x_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\n\tif (efm32x_info) {\n\t\t/* Use ref count to determine if it can be freed; scanning bank list doesn't work,\n\t\t * because this function can be called after some banks in the list have been\n\t\t * already destroyed */\n\t\t--efm32x_info->refcount;\n\t\tif (efm32x_info->refcount == 0) {\n\t\t\tfree(efm32x_info);\n\t\t\tbank->driver_priv = NULL;\n\t\t}\n\t}\n}\n\n/* set or reset given bits in a register */\nstatic int efm32x_set_reg_bits(struct flash_bank *bank, uint32_t reg,\n\tuint32_t bitmask, int set)\n{\n\tint ret = 0;\n\tuint32_t reg_val = 0;\n\n\tret = efm32x_read_reg_u32(bank, reg, &reg_val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (set)\n\t\treg_val |= bitmask;\n\telse\n\t\treg_val &= ~bitmask;\n\n\treturn efm32x_write_reg_u32(bank, reg, reg_val);\n}\n\nstatic int efm32x_set_wren(struct flash_bank *bank, int write_enable)\n{\n\treturn efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECTRL,\n\t\tEFM32_MSC_WRITECTRL_WREN_MASK, write_enable);\n}\n\nstatic int efm32x_msc_lock(struct flash_bank *bank, int lock)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\treturn efm32x_write_reg_u32(bank, efm32x_info->reg_lock,\n\t\t(lock ? 0 : EFM32_MSC_LOCK_LOCKKEY));\n}\n\nstatic int efm32x_wait_status(struct flash_bank *bank, int timeout,\n\tuint32_t wait_mask, int wait_for_set)\n{\n\tint ret = 0;\n\tuint32_t status = 0;\n\n\twhile (1) {\n\t\tret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);\n\t\tif (ret != ERROR_OK)\n\t\t\tbreak;\n\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32 \"\", status);\n\n\t\tif (((status & wait_mask) == 0) && (wait_for_set == 0))\n\t\t\tbreak;\n\t\telse if (((status & wait_mask) != 0) && wait_for_set)\n\t\t\tbreak;\n\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for MSC status\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\talive_sleep(1);\n\t}\n\n\tif (status & EFM32_MSC_STATUS_ERASEABORTED_MASK)\n\t\tLOG_WARNING(\"page erase was aborted\");\n\n\treturn ret;\n}\n\nstatic int efm32x_erase_page(struct flash_bank *bank, uint32_t addr)\n{\n\t/* this function DOES NOT set WREN; must be set already */\n\t/* 1. write address to ADDRB\n\t   2. write LADDRIM\n\t   3. check status (INVADDR, LOCKED)\n\t   4. write ERASEPAGE\n\t   5. wait until !STATUS_BUSY\n\t */\n\tint ret = 0;\n\tuint32_t status = 0;\n\tLOG_DEBUG(\"erasing flash page at 0x%08\" PRIx32, addr);\n\n\tret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,\n\t\tEFM32_MSC_WRITECMD_LADDRIM_MASK, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_DEBUG(\"status 0x%\" PRIx32, status);\n\n\tif (status & EFM32_MSC_STATUS_LOCKED_MASK) {\n\t\tLOG_ERROR(\"Page is locked\");\n\t\treturn ERROR_FAIL;\n\t} else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {\n\t\tLOG_ERROR(\"Invalid address 0x%\" PRIx32, addr);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,\n\t\tEFM32_MSC_WRITECMD_ERASEPAGE_MASK, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn efm32x_wait_status(bank, EFM32_FLASH_ERASE_TMO,\n\t\tEFM32_MSC_STATUS_BUSY_MASK, 0);\n}\n\nstatic int efm32x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tint ret = 0;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tefm32x_msc_lock(bank, 0);\n\tret = efm32x_set_wren(bank, 1);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to enable MSC write\");\n\t\treturn ret;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tret = efm32x_erase_page(bank, bank->base + bank->sectors[i].offset);\n\t\tif (ret != ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to erase page %d\", i);\n\t}\n\n\tret = efm32x_set_wren(bank, 0);\n\tefm32x_msc_lock(bank, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (bank->base == EFM32_MSC_LOCK_BITS) {\n\t\tret = efm32x_write_only_lockbits(bank);\n\t\tif (ret != ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to restore lockbits after erase\");\n\t}\n\n\treturn ret;\n}\n\nstatic int efm32x_read_lock_data(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint data_size = 0;\n\tuint32_t *ptr = NULL;\n\tint ret = 0;\n\n\tassert(bank->num_sectors > 0);\n\n\t/* calculate the number of 32-bit words to read (one lock bit per sector) */\n\tdata_size = (bank->num_sectors + 31) / 32;\n\n\tptr = efm32x_info->lb_page;\n\n\tfor (int i = 0; i < data_size; i++, ptr++) {\n\t\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+i*4, ptr);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read PLW %d\", i);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t/* also, read ULW, DLW, MLW, ALW and CLW words */\n\n\t/* ULW, word 126 */\n\tptr = efm32x_info->lb_page + 126;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+126*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read ULW\");\n\t\treturn ret;\n\t}\n\n\t/* DLW, word 127 */\n\tptr = efm32x_info->lb_page + 127;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+127*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read DLW\");\n\t\treturn ret;\n\t}\n\n\t/* MLW, word 125, present in GG, LG, PG, JG, EFR32 */\n\tptr = efm32x_info->lb_page + 125;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+125*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read MLW\");\n\t\treturn ret;\n\t}\n\n\t/* ALW, word 124, present in GG, LG, PG, JG, EFR32 */\n\tptr = efm32x_info->lb_page + 124;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+124*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read ALW\");\n\t\treturn ret;\n\t}\n\n\t/* CLW1, word 123, present in EFR32 */\n\tptr = efm32x_info->lb_page + 123;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+123*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read CLW1\");\n\t\treturn ret;\n\t}\n\n\t/* CLW0, word 122, present in GG, LG, PG, JG, EFR32 */\n\tptr = efm32x_info->lb_page + 122;\n\tret = target_read_u32(target, EFM32_MSC_LOCK_BITS+122*4, ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read CLW0\");\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int efm32x_write_only_lockbits(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\treturn efm32x_priv_write(bank, (uint8_t *)efm32x_info->lb_page, EFM32_MSC_LOCK_BITS, LOCKWORDS_SZ);\n}\n\nstatic int efm32x_write_lock_data(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tint ret = 0;\n\n\t/* Preserve any data written to the high portion of the lockbits page */\n\tassert(efm32x_info->info.page_size >= LOCKWORDS_SZ);\n\tuint32_t extra_bytes = efm32x_info->info.page_size - LOCKWORDS_SZ;\n\tuint8_t *extra_data = NULL;\n\tif (extra_bytes) {\n\t\textra_data = malloc(extra_bytes);\n\t\tret = target_read_buffer(bank->target, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes, extra_data);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read extra contents of LB page\");\n\t\t\tfree(extra_data);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\tret = efm32x_erase_page(bank, EFM32_MSC_LOCK_BITS);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to erase LB page\");\n\t\tif (extra_data)\n\t\t\tfree(extra_data);\n\t\treturn ret;\n\t}\n\n\tif (extra_data) {\n\t\tret = efm32x_priv_write(bank, extra_data, EFM32_MSC_LOCK_BITS_EXTRA, extra_bytes);\n\t\tfree(extra_data);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to restore extra contents of LB page\");\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\treturn efm32x_write_only_lockbits(bank);\n}\n\nstatic int efm32x_get_page_lock(struct flash_bank *bank, size_t page)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tuint32_t dw = 0;\n\tuint32_t mask = 0;\n\n\tswitch (bank->base) {\n\t\tcase EFM32_FLASH_BASE:\n\t\t\tdw = efm32x_info->lb_page[page >> 5];\n\t\t\tmask = 1 << (page & 0x1f);\n\t\t\tbreak;\n\t\tcase EFM32_MSC_USER_DATA:\n\t\t\tdw = efm32x_info->lb_page[126];\n\t\t\tmask = 0x1;\n\t\t\tbreak;\n\t\tcase EFM32_MSC_LOCK_BITS:\n\t\t\tdw = efm32x_info->lb_page[126];\n\t\t\tmask = 0x2;\n\t\t\tbreak;\n\t}\n\n\treturn (dw & mask) ? 0 : 1;\n}\n\nstatic int efm32x_set_page_lock(struct flash_bank *bank, size_t page, int set)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\n\tif (bank->base != EFM32_FLASH_BASE) {\n\t\tLOG_ERROR(\"Locking user and lockbits pages is not supported yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t *dw = &efm32x_info->lb_page[page >> 5];\n\tuint32_t mask = 0;\n\n\tmask = 1 << (page & 0x1f);\n\n\tif (!set)\n\t\t*dw |= mask;\n\telse\n\t\t*dw &= ~mask;\n\n\treturn ERROR_OK;\n}\n\nstatic int efm32x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tint ret = 0;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tret = efm32x_set_page_lock(bank, i, set);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to set lock on page %d\", i);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\tret = efm32x_write_lock_data(bank);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write LB page\");\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int efm32x_write_block(struct flash_bank *bank, const uint8_t *buf,\n\tuint32_t address, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tint ret = ERROR_OK;\n\n\t/* see contrib/loaders/flash/efm32.S for src */\n\tstatic const uint8_t efm32x_flash_write_code[] = {\n\t\t/* #define EFM32_MSC_WRITECTRL_OFFSET      0x008 */\n\t\t/* #define EFM32_MSC_WRITECMD_OFFSET       0x00c */\n\t\t/* #define EFM32_MSC_ADDRB_OFFSET          0x010 */\n\t\t/* #define EFM32_MSC_WDATA_OFFSET          0x018 */\n\t\t/* #define EFM32_MSC_STATUS_OFFSET         0x01c */\n\n\t\t\t0x01, 0x26,    /* movs    r6, #1 */\n\t\t\t0x86, 0x60,    /* str     r6, [r0, #EFM32_MSC_WRITECTRL_OFFSET] */\n\n\t\t/* wait_fifo: */\n\t\t\t0x16, 0x68,    /* ldr     r6, [r2, #0] */\n\t\t\t0x00, 0x2e,    /* cmp     r6, #0 */\n\t\t\t0x22, 0xd0,    /* beq     exit */\n\t\t\t0x55, 0x68,    /* ldr     r5, [r2, #4] */\n\t\t\t0xb5, 0x42,    /* cmp     r5, r6 */\n\t\t\t0xf9, 0xd0,    /* beq     wait_fifo */\n\n\t\t\t0x04, 0x61,    /* str     r4, [r0, #EFM32_MSC_ADDRB_OFFSET] */\n\t\t\t0x01, 0x26,    /* movs    r6, #1 */\n\t\t\t0xc6, 0x60,    /* str     r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */\n\t\t\t0xc6, 0x69,    /* ldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET] */\n\t\t\t0x06, 0x27,    /* movs    r7, #6 */\n\t\t\t0x3e, 0x42,    /* tst     r6, r7 */\n\t\t\t0x16, 0xd1,    /* bne     error */\n\n\t\t/* wait_wdataready: */\n\t\t\t0xc6, 0x69,    /* ldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET] */\n\t\t\t0x08, 0x27,    /* movs    r7, #8 */\n\t\t\t0x3e, 0x42,    /* tst     r6, r7 */\n\t\t\t0xfb, 0xd0,    /* beq     wait_wdataready */\n\n\t\t\t0x2e, 0x68,    /* ldr     r6, [r5] */\n\t\t\t0x86, 0x61,    /* str     r6, [r0, #EFM32_MSC_WDATA_OFFSET] */\n\t\t\t0x08, 0x26,    /* movs    r6, #8 */\n\t\t\t0xc6, 0x60,    /* str     r6, [r0, #EFM32_MSC_WRITECMD_OFFSET] */\n\n\t\t\t0x04, 0x35,    /* adds    r5, #4 */\n\t\t\t0x04, 0x34,    /* adds    r4, #4 */\n\n\t\t/* busy: */\n\t\t\t0xc6, 0x69,    /* ldr     r6, [r0, #EFM32_MSC_STATUS_OFFSET] */\n\t\t\t0x01, 0x27,    /* movs    r7, #1 */\n\t\t\t0x3e, 0x42,    /* tst     r6, r7 */\n\t\t\t0xfb, 0xd1,    /* bne     busy */\n\n\t\t\t0x9d, 0x42,    /* cmp     r5, r3 */\n\t\t\t0x01, 0xd3,    /* bcc     no_wrap */\n\t\t\t0x15, 0x46,    /* mov     r5, r2 */\n\t\t\t0x08, 0x35,    /* adds    r5, #8 */\n\n\t\t/* no_wrap: */\n\t\t\t0x55, 0x60,    /* str     r5, [r2, #4] */\n\t\t\t0x01, 0x39,    /* subs    r1, r1, #1 */\n\t\t\t0x00, 0x29,    /* cmp     r1, #0 */\n\t\t\t0x02, 0xd0,    /* beq     exit */\n\t\t\t0xdb, 0xe7,    /* b       wait_fifo */\n\n\t\t/* error: */\n\t\t\t0x00, 0x20,    /* movs    r0, #0 */\n\t\t\t0x50, 0x60,    /* str     r0, [r2, #4] */\n\n\t\t/* exit: */\n\t\t\t0x30, 0x46,    /* mov     r0, r6 */\n\t\t\t0x00, 0xbe,    /* bkpt    #0 */\n\t};\n\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(efm32x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tret = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(efm32x_flash_write_code), efm32x_flash_write_code);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tbuffer_size &= ~3UL; /* Make sure it's 4 byte aligned */\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* flash base (in), status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* count (word-32bit) */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN_OUT);\t/* target address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, efm32x_info->reg_base);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tret = target_run_flash_async_algorithm(target, buf, count, 4,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (ret == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"flash write failed at address 0x%\"PRIx32,\n\t\t\t\tbuf_get_u32(reg_params[4].value, 0, 32));\n\n\t\tif (buf_get_u32(reg_params[0].value, 0, 32) &\n\t\t\t\tEFM32_MSC_STATUS_LOCKED_MASK) {\n\t\t\tLOG_ERROR(\"flash memory write protected\");\n\t\t}\n\n\t\tif (buf_get_u32(reg_params[0].value, 0, 32) &\n\t\t\t\tEFM32_MSC_STATUS_INVADDR_MASK) {\n\t\t\tLOG_ERROR(\"invalid flash memory write address\");\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn ret;\n}\n\nstatic int efm32x_write_word(struct flash_bank *bank, uint32_t addr,\n\tuint32_t val)\n{\n\t/* this function DOES NOT set WREN; must be set already */\n\t/* 1. write address to ADDRB\n\t   2. write LADDRIM\n\t   3. check status (INVADDR, LOCKED)\n\t   4. wait for WDATAREADY\n\t   5. write data to WDATA\n\t   6. write WRITECMD_WRITEONCE to WRITECMD\n\t   7. wait until !STATUS_BUSY\n\t */\n\n\t/* FIXME: EFM32G ref states (7.3.2) that writes should be\n\t * performed twice per dword */\n\n\tint ret = 0;\n\tuint32_t status = 0;\n\n\t/* if not called, GDB errors will be reported during large writes */\n\tkeep_alive();\n\n\tret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_ADDRB, addr);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_set_reg_bits(bank, EFM32_MSC_REG_WRITECMD,\n\t\tEFM32_MSC_WRITECMD_LADDRIM_MASK, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = efm32x_read_reg_u32(bank, EFM32_MSC_REG_STATUS, &status);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_DEBUG(\"status 0x%\" PRIx32, status);\n\n\tif (status & EFM32_MSC_STATUS_LOCKED_MASK) {\n\t\tLOG_ERROR(\"Page is locked\");\n\t\treturn ERROR_FAIL;\n\t} else if (status & EFM32_MSC_STATUS_INVADDR_MASK) {\n\t\tLOG_ERROR(\"Invalid address 0x%\" PRIx32, addr);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = efm32x_wait_status(bank, EFM32_FLASH_WDATAREADY_TMO,\n\t\tEFM32_MSC_STATUS_WDATAREADY_MASK, 1);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Wait for WDATAREADY failed\");\n\t\treturn ret;\n\t}\n\n\tret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WDATA, val);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"WDATA write failed\");\n\t\treturn ret;\n\t}\n\n\tret = efm32x_write_reg_u32(bank, EFM32_MSC_REG_WRITECMD,\n\t\tEFM32_MSC_WRITECMD_WRITEONCE_MASK);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"WRITECMD write failed\");\n\t\treturn ret;\n\t}\n\n\tret = efm32x_wait_status(bank, EFM32_FLASH_WRITE_TMO,\n\t\tEFM32_MSC_STATUS_BUSY_MASK, 0);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Wait for BUSY failed\");\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int efm32x_priv_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t addr, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint8_t *new_buffer = NULL;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (addr & 0x3) {\n\t\tLOG_ERROR(\"addr 0x%\" PRIx32 \" breaks required 4-byte \"\n\t\t\t\"alignment\", addr);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (count & 0x3) {\n\t\tuint32_t old_count = count;\n\t\tcount = (old_count | 3) + 1;\n\t\tnew_buffer = malloc(count);\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"odd number of bytes to write and no memory \"\n\t\t\t\t\"for padding buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"odd number of bytes to write (%\" PRIu32 \"), extending to %\" PRIu32 \" \"\n\t\t\t\"and padding with 0xff\", old_count, count);\n\t\tmemset(new_buffer, 0xff, count);\n\t\tbuffer = memcpy(new_buffer, buffer, old_count);\n\t}\n\n\tuint32_t words_remaining = count / 4;\n\tint retval, retval2;\n\n\t/* unlock flash registers */\n\tefm32x_msc_lock(bank, 0);\n\tretval = efm32x_set_wren(bank, 1);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup;\n\n\t/* try using a block write */\n\tretval = efm32x_write_block(bank, buffer, addr, words_remaining);\n\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t/* if block write failed (no sufficient working area),\n\t\t * we use normal (slow) single word accesses */\n\t\tLOG_WARNING(\"couldn't use block writes, falling back to single \"\n\t\t\t\"memory accesses\");\n\n\t\twhile (words_remaining > 0) {\n\t\t\tuint32_t value;\n\t\t\tmemcpy(&value, buffer, sizeof(uint32_t));\n\n\t\t\tretval = efm32x_write_word(bank, addr, value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\twords_remaining--;\n\t\t\tbuffer += 4;\n\t\t\taddr += 4;\n\t\t}\n\t}\n\nreset_pg_and_lock:\n\tretval2 = efm32x_set_wren(bank, 0);\n\tefm32x_msc_lock(bank, 1);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\ncleanup:\n\tfree(new_buffer);\n\treturn retval;\n}\n\nstatic int efm32x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tif (bank->base == EFM32_MSC_LOCK_BITS && offset < LOCKWORDS_SZ) {\n\t\tLOG_ERROR(\"Cannot write to lock words\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn efm32x_priv_write(bank, buffer, bank->base + offset, count);\n}\n\nstatic int efm32x_probe(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tstruct efm32_info *efm32_mcu_info = &(efm32x_info->info);\n\tint ret;\n\n\tint bank_index = efm32x_get_bank_index(bank->base);\n\tassert(bank_index >= 0);\n\n\tefm32x_info->probed[bank_index] = false;\n\tmemset(efm32x_info->lb_page, 0xff, LOCKWORDS_SZ);\n\n\tret = efm32x_read_info(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_INFO(\"detected part: %s Gecko, rev %d\",\n\t\t\tefm32_mcu_info->family_data->name, efm32_mcu_info->prod_rev);\n\tLOG_INFO(\"flash size = %d KiB\", efm32_mcu_info->flash_sz_kib);\n\tLOG_INFO(\"flash page size = %d B\", efm32_mcu_info->page_size);\n\n\tassert(efm32_mcu_info->page_size != 0);\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tif (bank->base == EFM32_FLASH_BASE) {\n\t\tbank->num_sectors = efm32_mcu_info->flash_sz_kib * 1024 /\n\t\t\tefm32_mcu_info->page_size;\n\t\tassert(bank->num_sectors > 0);\n\n\t\tret = efm32x_read_lock_data(bank);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read LB data\");\n\t\t\treturn ret;\n\t\t}\n\t} else\n\t\tbank->num_sectors = 1;\n\tbank->size = bank->num_sectors * efm32_mcu_info->page_size;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\tfor (uint32_t i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * efm32_mcu_info->page_size;\n\t\tbank->sectors[i].size = efm32_mcu_info->page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\tefm32x_info->probed[bank_index] = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int efm32x_auto_probe(struct flash_bank *bank)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\n\tint bank_index = efm32x_get_bank_index(bank->base);\n\tassert(bank_index >= 0);\n\n\tif (efm32x_info->probed[bank_index])\n\t\treturn ERROR_OK;\n\treturn efm32x_probe(bank);\n}\n\nstatic int efm32x_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint ret = 0;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tret = efm32x_read_lock_data(bank);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read LB data\");\n\t\treturn ret;\n\t}\n\n\tassert(bank->sectors);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = efm32x_get_page_lock(bank, i);\n\n\treturn ERROR_OK;\n}\n\nstatic int get_efm32x_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\tint ret;\n\n\tret = efm32x_read_info(bank);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read EFM32 info\");\n\t\treturn ret;\n\t}\n\n\tcommand_print_sameline(cmd, \"%s Gecko, rev %d\", efm32x_info->info.family_data->name,\n\t\tefm32x_info->info.prod_rev);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(efm32x_handle_debuglock_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct efm32x_flash_chip *efm32x_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t *ptr;\n\tptr = efm32x_info->lb_page + 127;\n\t*ptr = 0;\n\n\tretval = efm32x_write_lock_data(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write LB page\");\n\t\treturn retval;\n\t}\n\n\tcommand_print(CMD, \"efm32x debug interface locked, reset the device to apply\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration efm32x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"debuglock\",\n\t\t.handler = efm32x_handle_debuglock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lock the debug interface of the device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration efm32x_command_handlers[] = {\n\t{\n\t\t.name = \"efm32\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"efm32 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = efm32x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver efm32_flash = {\n\t.name = \"efm32\",\n\t.commands = efm32x_command_handlers,\n\t.flash_bank_command = efm32x_flash_bank_command,\n\t.erase = efm32x_erase,\n\t.protect = efm32x_protect,\n\t.write = efm32x_write,\n\t.read = default_flash_read,\n\t.probe = efm32x_probe,\n\t.auto_probe = efm32x_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = efm32x_protect_check,\n\t.info = get_efm32x_info,\n\t.free_driver_priv = efm32x_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/em357.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *\n *   Copyright (C) 2011 by Erik Botö\n *   erik.boto@pelagicore.com\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n/* em357 register locations */\n\n#define EM357_FLASH_ACR         0x40008000\n#define EM357_FLASH_KEYR        0x40008004\n#define EM357_FLASH_OPTKEYR     0x40008008\n#define EM357_FLASH_SR          0x4000800C\n#define EM357_FLASH_CR          0x40008010\n#define EM357_FLASH_AR          0x40008014\n#define EM357_FLASH_OBR         0x4000801C\n#define EM357_FLASH_WRPR        0x40008020\n\n#define EM357_FPEC_CLK          0x4000402c\n/* option byte location */\n\n#define EM357_OB_RDP            0x08040800\n#define EM357_OB_WRP0           0x08040808\n#define EM357_OB_WRP1           0x0804080A\n#define EM357_OB_WRP2           0x0804080C\n\n/* FLASH_CR register bits */\n\n#define FLASH_PG                (1 << 0)\n#define FLASH_PER               (1 << 1)\n#define FLASH_MER               (1 << 2)\n#define FLASH_OPTPG             (1 << 4)\n#define FLASH_OPTER             (1 << 5)\n#define FLASH_STRT              (1 << 6)\n#define FLASH_LOCK              (1 << 7)\n#define FLASH_OPTWRE    (1 << 9)\n\n/* FLASH_SR register bits */\n\n#define FLASH_BSY               (1 << 0)\n#define FLASH_PGERR             (1 << 2)\n#define FLASH_WRPRTERR  (1 << 4)\n#define FLASH_EOP               (1 << 5)\n\n/* EM357_FLASH_OBR bit definitions (reading) */\n\n#define OPT_ERROR               0\n#define OPT_READOUT             1\n\n/* register unlock keys */\n\n#define KEY1                    0x45670123\n#define KEY2                    0xCDEF89AB\n\nstruct em357_options {\n\tuint16_t RDP;\n\tuint16_t user_options;\n\tuint16_t protection[3];\n};\n\nstruct em357_flash_bank {\n\tstruct em357_options option_bytes;\n\tint ppage_size;\n\tbool probed;\n};\n\nstatic int em357_mass_erase(struct flash_bank *bank);\n\n/* flash bank em357 <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(em357_flash_bank_command)\n{\n\tstruct em357_flash_bank *em357_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tem357_info = malloc(sizeof(struct em357_flash_bank));\n\tbank->driver_priv = em357_info;\n\n\tem357_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\nstatic inline int em357_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\treturn target_read_u32(target, EM357_FLASH_SR, status);\n}\n\nstatic int em357_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* wait for busy to clear */\n\tfor (;; ) {\n\t\tretval = em357_get_flash_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32 \"\", status);\n\t\tif ((status & FLASH_BSY) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tif (status & FLASH_WRPRTERR) {\n\t\tLOG_ERROR(\"em357 device protected\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\tif (status & FLASH_PGERR) {\n\t\tLOG_ERROR(\"em357 device programming failed\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t/* Clear but report errors */\n\tif (status & (FLASH_WRPRTERR | FLASH_PGERR)) {\n\t\t/* If this operation fails, we ignore it and report the original\n\t\t * retval\n\t\t */\n\t\ttarget_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR | FLASH_PGERR);\n\t}\n\treturn retval;\n}\n\nstatic int em357_read_options(struct flash_bank *bank)\n{\n\tuint32_t optiondata;\n\tstruct em357_flash_bank *em357_info = NULL;\n\tstruct target *target = bank->target;\n\n\tem357_info = bank->driver_priv;\n\n\t/* read current option bytes */\n\tint retval = target_read_u32(target, EM357_FLASH_OBR, &optiondata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tem357_info->option_bytes.user_options = (uint16_t)0xFFFC | ((optiondata >> 2) & 0x03);\n\tem357_info->option_bytes.RDP = (optiondata & (1 << OPT_READOUT)) ? 0xFFFF : 0x5AA5;\n\n\tif (optiondata & (1 << OPT_READOUT))\n\t\tLOG_INFO(\"Device Security Bit Set\");\n\n\t/* each bit refers to a 4bank protection */\n\tretval = target_read_u32(target, EM357_FLASH_WRPR, &optiondata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tem357_info->option_bytes.protection[0] = (uint16_t)optiondata;\n\tem357_info->option_bytes.protection[1] = (uint16_t)(optiondata >> 8);\n\tem357_info->option_bytes.protection[2] = (uint16_t)(optiondata >> 16);\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_erase_options(struct flash_bank *bank)\n{\n\tstruct em357_flash_bank *em357_info = NULL;\n\tstruct target *target = bank->target;\n\n\tem357_info = bank->driver_priv;\n\n\t/* read current options */\n\tem357_read_options(bank);\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* unlock option flash registers */\n\tretval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* erase option bytes */\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTER | FLASH_STRT | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* clear readout protection and complementary option bytes\n\t * this will also force a device unlock if set */\n\tem357_info->option_bytes.RDP = 0x5AA5;\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_write_options(struct flash_bank *bank)\n{\n\tstruct em357_flash_bank *em357_info = NULL;\n\tstruct target *target = bank->target;\n\n\tem357_info = bank->driver_priv;\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* unlock option flash registers */\n\tretval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_OPTKEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* program option bytes */\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_OPTPG | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write protection byte 1 */\n\tretval = target_write_u16(target, EM357_OB_WRP0, em357_info->option_bytes.protection[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write protection byte 2 */\n\tretval = target_write_u16(target, EM357_OB_WRP1, em357_info->option_bytes.protection[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write protection byte 3 */\n\tretval = target_write_u16(target, EM357_OB_WRP2, em357_info->option_bytes.protection[2]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write readout protection bit */\n\tretval = target_write_u16(target, EM357_OB_RDP, em357_info->option_bytes.RDP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct em357_flash_bank *em357_info = bank->driver_priv;\n\n\tuint32_t protection;\n\tint i, s;\n\tint num_bits;\n\tint set;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* each bit refers to a 4bank protection (bit 0-23) */\n\tint retval = target_read_u32(target, EM357_FLASH_WRPR, &protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* each protection bit is for 4 * 2K pages */\n\tnum_bits = (bank->num_sectors / em357_info->ppage_size);\n\n\tfor (i = 0; i < num_bits; i++) {\n\t\tset = 1;\n\t\tif (protection & (1 << i))\n\t\t\tset = 0;\n\n\t\tfor (s = 0; s < em357_info->ppage_size; s++)\n\t\t\tbank->sectors[(i * em357_info->ppage_size) + s].is_protected = set;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1)))\n\t\treturn em357_mass_erase(bank);\n\n\t/* Enable FPEC clock */\n\ttarget_write_u32(target, EM357_FPEC_CLK, 0x00000001);\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, EM357_FLASH_AR,\n\t\t\t\tbank->base + bank->sectors[i].offset);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_PER | FLASH_STRT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = em357_wait_status_busy(bank, 100);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct em357_flash_bank *em357_info = NULL;\n\tstruct target *target = bank->target;\n\tuint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};\n\tint reg, bit;\n\tint status;\n\tuint32_t protection;\n\n\tem357_info = bank->driver_priv;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first % em357_info->ppage_size) != 0) {\n\t\tLOG_WARNING(\"aligned start protect sector to a %d sector boundary\",\n\t\t\tem357_info->ppage_size);\n\t\tfirst = first - (first % em357_info->ppage_size);\n\t}\n\tif (((last + 1) % em357_info->ppage_size) != 0) {\n\t\tLOG_WARNING(\"aligned end protect sector to a %d sector boundary\",\n\t\t\tem357_info->ppage_size);\n\t\tlast++;\n\t\tlast = last - (last % em357_info->ppage_size);\n\t\tlast--;\n\t}\n\n\t/* each bit refers to a 4bank protection */\n\tint retval = target_read_u32(target, EM357_FLASH_WRPR, &protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tprot_reg[0] = (uint16_t)protection;\n\tprot_reg[1] = (uint16_t)(protection >> 8);\n\tprot_reg[2] = (uint16_t)(protection >> 16);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\treg = (i / em357_info->ppage_size) / 8;\n\t\tbit = (i / em357_info->ppage_size) - (reg * 8);\n\n\t\tLOG_WARNING(\"reg, bit: %d, %d\", reg, bit);\n\t\tif (set)\n\t\t\tprot_reg[reg] &= ~(1 << bit);\n\t\telse\n\t\t\tprot_reg[reg] |= (1 << bit);\n\t}\n\n\tstatus = em357_erase_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn status;\n\n\tem357_info->option_bytes.protection[0] = prot_reg[0];\n\tem357_info->option_bytes.protection[1] = prot_reg[1];\n\tem357_info->option_bytes.protection[2] = prot_reg[2];\n\n\treturn em357_write_options(bank);\n}\n\nstatic int em357_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* see contrib/loaders/flash/stm32x.s for src, the same is used here except for\n\t * a modified *_FLASH_BASE */\n\n\tstatic const uint8_t em357_flash_write_code[] = {\n\t\t/* #define EM357_FLASH_CR_OFFSET\t0x10\n\t\t * #define EM357_FLASH_SR_OFFSET\t0x0C\n\t\t * write: */\n\t\t0x08, 0x4c,\t\t\t\t\t/* ldr\tr4, EM357_FLASH_BASE */\n\t\t0x1c, 0x44,\t\t\t\t\t/* add\tr4, r3 */\n\t\t/* write_half_word: */\n\t\t0x01, 0x23,\t\t\t\t\t/* movs\tr3, #0x01 */\n\t\t0x23, 0x61,\t\t\t\t\t/* str\tr3, [r4,\n\t\t\t\t\t\t\t\t *#EM357_FLASH_CR_OFFSET] */\n\t\t0x30, 0xf8, 0x02, 0x3b,\t\t/* ldrh\tr3, [r0], #0x02 */\n\t\t0x21, 0xf8, 0x02, 0x3b,\t\t/* strh\tr3, [r1], #0x02 */\n\t\t/* busy: */\n\t\t0xe3, 0x68,\t\t\t\t\t/* ldr\tr3, [r4,\n\t\t\t\t\t\t\t\t *#EM357_FLASH_SR_OFFSET] */\n\t\t0x13, 0xf0, 0x01, 0x0f,\t\t/* tst\tr3, #0x01 */\n\t\t0xfb, 0xd0,\t\t\t\t\t/* beq\tbusy */\n\t\t0x13, 0xf0, 0x14, 0x0f,\t\t/* tst\tr3, #0x14 */\n\t\t0x01, 0xd1,\t\t\t\t\t/* bne\texit */\n\t\t0x01, 0x3a,\t\t\t\t\t/* subs\tr2, r2, #0x01 */\n\t\t0xf0, 0xd1,\t\t\t\t\t/* bne\twrite_half_word */\n\t\t/* exit: */\n\t\t0x00, 0xbe,\t\t\t\t\t/* bkpt\t#0x00 */\n\t\t0x00, 0x80, 0x00, 0x40,\t\t/* EM357_FLASH_BASE: .word 0x40008000 */\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(em357_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(em357_flash_write_code), em357_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\n\t\t\t\t\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_IN_OUT);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > (buffer_size / 2)) ?\n\t\t\t(buffer_size / 2) : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count * 2, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, 0);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 4, reg_params,\n\t\t\t\twrite_algorithm->address, 0, 10000, &armv7m_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing em357 flash write algorithm\");\n\t\t\tbreak;\n\t\t}\n\n\t\tif (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_PGERR) {\n\t\t\tLOG_ERROR(\"flash memory not erased before writing\");\n\t\t\t/* Clear but report errors */\n\t\t\ttarget_write_u32(target, EM357_FLASH_SR, FLASH_PGERR);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (buf_get_u32(reg_params[3].value, 0, 32) & FLASH_WRPRTERR) {\n\t\t\tLOG_ERROR(\"flash memory write protected\");\n\t\t\t/* Clear but report errors */\n\t\t\ttarget_write_u32(target, EM357_FLASH_SR, FLASH_WRPRTERR);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count * 2;\n\t\taddress += thisrun_count * 2;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn retval;\n}\n\nstatic int em357_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t words_remaining = (count / 2);\n\tuint32_t bytes_remaining = (count & 0x00000001);\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x1) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* unlock flash registers */\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget_write_u32(target, EM357_FPEC_CLK, 0x00000001);\n\n\t/* multiple half words (2-byte) to be programmed? */\n\tif (words_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = em357_write_block(bank, buffer, offset, words_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) single dword accesses */\n\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += words_remaining * 2;\n\t\t\taddress += words_remaining * 2;\n\t\t\twords_remaining = 0;\n\t\t}\n\t}\n\n\tif ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))\n\t\treturn retval;\n\n\twhile (words_remaining > 0) {\n\t\tuint16_t value;\n\t\tmemcpy(&value, buffer + bytes_written, sizeof(uint16_t));\n\n\t\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u16(target, address, value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = em357_wait_status_busy(bank, 5);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbytes_written += 2;\n\t\twords_remaining--;\n\t\taddress += 2;\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint16_t value = 0xffff;\n\t\tmemcpy(&value, buffer + bytes_written, bytes_remaining);\n\n\t\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_PG);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u16(target, address, value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = em357_wait_status_busy(bank, 5);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);\n}\n\nstatic int em357_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct em357_flash_bank *em357_info = bank->driver_priv;\n\tint i;\n\tuint16_t num_pages;\n\tint page_size;\n\tuint32_t base_address = 0x08000000;\n\n\tem357_info->probed = false;\n\n\tswitch (bank->size) {\n\t\tcase 0x10000:\n\t\t\t/* 64k -- 64 1k pages */\n\t\t\tnum_pages = 64;\n\t\t\tpage_size = 1024;\n\t\t\tbreak;\n\t\tcase 0x20000:\n\t\t\t/* 128k -- 128 1k pages */\n\t\t\tnum_pages = 128;\n\t\t\tpage_size = 1024;\n\t\t\tbreak;\n\t\tcase 0x30000:\n\t\t\t/* 192k -- 96 2k pages */\n\t\t\tnum_pages = 96;\n\t\t\tpage_size = 2048;\n\t\t\tbreak;\n\t\tcase 0x40000:\n\t\t\t/* 256k -- 128 2k pages */\n\t\t\tnum_pages = 128;\n\t\t\tpage_size = 2048;\n\t\t\tbreak;\n\t\tcase 0x80000:\n\t\t\t/* 512k -- 256 2k pages */\n\t\t\tnum_pages = 256;\n\t\t\tpage_size = 2048;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_WARNING(\"No size specified for em357 flash driver, assuming 192k!\");\n\t\t\tnum_pages = 96;\n\t\t\tpage_size = 2048;\n\t\t\tbreak;\n\t}\n\n\t/* Enable FPEC CLK */\n\tint retval = target_write_u32(target, EM357_FPEC_CLK, 0x00000001);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tem357_info->ppage_size = 4;\n\n\tLOG_INFO(\"flash size = %d KiB\", num_pages*page_size/1024);\n\n\tfree(bank->sectors);\n\n\tbank->base = base_address;\n\tbank->size = (num_pages * page_size);\n\tbank->num_sectors = num_pages;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_pages);\n\n\tfor (i = 0; i < num_pages; i++) {\n\t\tbank->sectors[i].offset = i * page_size;\n\t\tbank->sectors[i].size = page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\tem357_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_auto_probe(struct flash_bank *bank)\n{\n\tstruct em357_flash_bank *em357_info = bank->driver_priv;\n\tif (em357_info->probed)\n\t\treturn ERROR_OK;\n\treturn em357_probe(bank);\n}\n\nCOMMAND_HANDLER(em357_handle_lock_command)\n{\n\tstruct target *target = NULL;\n\tstruct em357_flash_bank *em357_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tem357_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (em357_erase_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"em357 failed to erase options\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* set readout protection */\n\tem357_info->option_bytes.RDP = 0;\n\n\tif (em357_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"em357 failed to lock device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"em357 locked\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(em357_handle_unlock_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (em357_erase_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"em357 failed to unlock device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (em357_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"em357 failed to lock device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"em357 unlocked.\\n\"\n\t\t\"INFO: a reset or power cycle is required \"\n\t\t\"for the new settings to take effect.\");\n\n\treturn ERROR_OK;\n}\n\nstatic int em357_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Make sure the flash clock is on */\n\ttarget_write_u32(target, EM357_FPEC_CLK, 0x00000001);\n\n\t/* unlock option flash registers */\n\tint retval = target_write_u32(target, EM357_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* mass erase flash memory */\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_MER | FLASH_STRT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_wait_status_busy(bank, 100);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, EM357_FLASH_CR, FLASH_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(em357_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = em357_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"em357 mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"em357 mass erase failed\");\n\n\treturn retval;\n}\n\nstatic const struct command_registration em357_exec_command_handlers[] = {\n\t{\n\t\t.name = \"lock\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = em357_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Lock entire flash device.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = em357_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Unlock entire protected flash device.\",\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = em357_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration em357_command_handlers[] = {\n\t{\n\t\t.name = \"em357\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"em357 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = em357_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver em357_flash = {\n\t.name = \"em357\",\n\t.commands = em357_command_handlers,\n\t.flash_bank_command = em357_flash_bank_command,\n\t.erase = em357_erase,\n\t.protect = em357_protect,\n\t.write = em357_write,\n\t.read = default_flash_read,\n\t.probe = em357_probe,\n\t.auto_probe = em357_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = em357_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/esirisc_flash.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <flash/common.h>\n#include <flash/nor/imp.h>\n#include <helper/command.h>\n#include <helper/log.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n#include <target/esirisc.h>\n#include <target/target.h>\n\n/* eSi-TSMC Flash Registers */\n#define CONTROL\t\t\t\t0x00\t/* Control Register */\n#define TIMING0\t\t\t\t0x04\t/* Timing Register 0 */\n#define TIMING1\t\t\t\t0x08\t/* Timing Register 1 */\n#define TIMING2\t\t\t\t0x0c\t/* Timing Register 2 */\n#define UNLOCK1\t\t\t\t0x18\t/* Unlock 1 */\n#define UNLOCK2\t\t\t\t0x1c\t/* Unlock 2 */\n#define ADDRESS\t\t\t\t0x20\t/* Erase/Program Address */\n#define PB_DATA\t\t\t\t0x24\t/* Program Buffer Data */\n#define PB_INDEX\t\t\t0x28\t/* Program Buffer Index */\n#define STATUS\t\t\t\t0x2c\t/* Status Register */\n#define REDUN_0\t\t\t\t0x30\t/* Redundant Address 0 */\n#define REDUN_1\t\t\t\t0x34\t/* Redundant Address 1 */\n\n/* Control Fields */\n#define CONTROL_SLM\t\t\t(1<<0)\t/* Sleep Mode */\n#define CONTROL_WP\t\t\t(1<<1)\t/* Register Write Protect */\n#define CONTROL_E\t\t\t(1<<3)\t/* Erase */\n#define CONTROL_EP\t\t\t(1<<4)\t/* Erase Page */\n#define CONTROL_P\t\t\t(1<<5)\t/* Program Flash */\n#define CONTROL_ERC\t\t\t(1<<6)\t/* Erase Reference Cell */\n#define CONTROL_R\t\t\t(1<<7)\t/* Recall Trim Code */\n#define CONTROL_AP\t\t\t(1<<8)\t/* Auto-Program */\n\n/* Timing Fields */\n#define TIMING0_R(x)\t\t(((x) <<  0) & 0x3f)\t\t/* Read Wait States */\n#define TIMING0_F(x)\t\t(((x) << 16) & 0xffff0000)\t/* Tnvh Clock Cycles */\n#define TIMING1_E(x)\t\t(((x) <<  0) & 0xffffff)\t/* Tme/Terase/Tre Clock Cycles */\n#define TIMING2_P(x)\t\t(((x) <<  0) & 0xffff)\t\t/* Tprog Clock Cycles */\n#define TIMING2_H(x)\t\t(((x) << 16) & 0xff0000)\t/* Clock Cycles in 100ns */\n#define TIMING2_T(x)\t\t(((x) << 24) & 0xf000000)\t/* Clock Cycles in 10ns */\n\n/* Status Fields */\n#define STATUS_BUSY\t\t\t(1<<0)\t/* Busy (Erase/Program) */\n#define STATUS_WER\t\t\t(1<<1)\t/* Write Protect Error */\n#define STATUS_DR\t\t\t(1<<2)\t/* Disable Redundancy */\n#define STATUS_DIS\t\t\t(1<<3)\t/* Discharged */\n#define STATUS_BO\t\t\t(1<<4)\t/* Brown Out */\n\n/* Redundant Address Fields */\n#define REDUN_R\t\t\t\t(1<<0)\t\t\t\t\t\t/* Used */\n#define REDUN_P(x)\t\t\t(((x) << 12) & 0x7f000)\t\t/* Redundant Page Address */\n\n/*\n * The eSi-TSMC Flash manual provides two sets of timings based on the\n * underlying flash process. By default, 90nm is assumed.\n */\n#if 0 /* 55nm */\n#define TNVH\t\t\t\t5000\t\t/* 5us   */\n#define TME\t\t\t\t\t80000000\t/* 80ms  */\n#define TERASE\t\t\t\t160000000\t/* 160ms */\n#define TRE\t\t\t\t\t100000000\t/* 100ms */\n#define TPROG\t\t\t\t8000\t\t/* 8us   */\n#else /* 90nm */\n#define TNVH\t\t\t\t5000\t\t/* 5us   */\n#define TME\t\t\t\t\t20000000\t/* 20ms  */\n#define TERASE\t\t\t\t40000000\t/* 40ms  */\n#define TRE\t\t\t\t\t40000000\t/* 40ms  */\n#define TPROG\t\t\t\t40000\t\t/* 40us  */\n#endif\n\n#define CONTROL_TIMEOUT\t\t5000\t\t/* 5s    */\n#define FLASH_PAGE_SIZE\t\t4096\n#define PB_MAX\t\t\t\t32\n\n#define NUM_NS_PER_S\t\t1000000000ULL\n\nstruct esirisc_flash_bank {\n\tbool probed;\n\tuint32_t cfg;\n\tuint32_t clock;\n\tuint32_t wait_states;\n};\n\nstatic const struct command_registration esirisc_flash_command_handlers[];\n\nFLASH_BANK_COMMAND_HANDLER(esirisc_flash_bank_command)\n{\n\tstruct esirisc_flash_bank *esirisc_info;\n\n\tif (CMD_ARGC < 9)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tesirisc_info = calloc(1, sizeof(struct esirisc_flash_bank));\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], esirisc_info->cfg);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], esirisc_info->clock);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[8], esirisc_info->wait_states);\n\n\tbank->driver_priv = esirisc_info;\n\n\t/* register commands using existing esirisc context */\n\tregister_commands(CMD_CTX, \"esirisc\", esirisc_flash_command_handlers);\n\n\treturn ERROR_OK;\n}\n\n/*\n * Register writes are ignored if the control.WP flag is set; the\n * following sequence is required to modify this flag even when\n * protection is disabled.\n */\nstatic int esirisc_flash_unlock(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\ttarget_write_u32(target, esirisc_info->cfg + UNLOCK1, 0x7123);\n\ttarget_write_u32(target, esirisc_info->cfg + UNLOCK2, 0x812a);\n\ttarget_write_u32(target, esirisc_info->cfg + UNLOCK1, 0xbee1);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_disable_protect(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t control;\n\n\ttarget_read_u32(target, esirisc_info->cfg + CONTROL, &control);\n\tif (!(control & CONTROL_WP))\n\t\treturn ERROR_OK;\n\n\t(void)esirisc_flash_unlock(bank);\n\n\tcontrol &= ~CONTROL_WP;\n\n\ttarget_write_u32(target, esirisc_info->cfg + CONTROL, control);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_enable_protect(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t control;\n\n\ttarget_read_u32(target, esirisc_info->cfg + CONTROL, &control);\n\tif (control & CONTROL_WP)\n\t\treturn ERROR_OK;\n\n\t(void)esirisc_flash_unlock(bank);\n\n\tcontrol |= CONTROL_WP;\n\n\ttarget_write_u32(target, esirisc_info->cfg + CONTROL, control);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_check_status(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\n\ttarget_read_u32(target, esirisc_info->cfg + STATUS, &status);\n\tif (status & STATUS_WER) {\n\t\tLOG_ERROR(\"%s: bad status: 0x%\" PRIx32, bank->name, status);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_clear_status(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\ttarget_write_u32(target, esirisc_info->cfg + STATUS, STATUS_WER);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_wait(struct flash_bank *bank, int ms)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\tint64_t t;\n\n\tt = timeval_ms();\n\tfor (;;) {\n\t\ttarget_read_u32(target, esirisc_info->cfg + STATUS, &status);\n\t\tif (!(status & STATUS_BUSY))\n\t\t\treturn ERROR_OK;\n\n\t\tif ((timeval_ms() - t) > ms)\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\n\t\tkeep_alive();\n\t}\n}\n\nstatic int esirisc_flash_control(struct flash_bank *bank, uint32_t control)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tesirisc_flash_clear_status(bank);\n\n\ttarget_write_u32(target, esirisc_info->cfg + CONTROL, control);\n\n\tint retval = esirisc_flash_wait(bank, CONTROL_TIMEOUT);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: control timed out: 0x%\" PRIx32, bank->name, control);\n\t\treturn retval;\n\t}\n\n\treturn esirisc_flash_check_status(bank);\n}\n\nstatic int esirisc_flash_recall(struct flash_bank *bank)\n{\n\treturn esirisc_flash_control(bank, CONTROL_R);\n}\n\nstatic int esirisc_flash_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t(void)esirisc_flash_disable_protect(bank);\n\n\tfor (unsigned int page = first; page < last; ++page) {\n\t\tuint32_t address = page * FLASH_PAGE_SIZE;\n\n\t\ttarget_write_u32(target, esirisc_info->cfg + ADDRESS, address);\n\n\t\tretval = esirisc_flash_control(bank, CONTROL_EP);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to erase address: 0x%\" PRIx32, bank->name, address);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t(void)esirisc_flash_enable_protect(bank);\n\n\treturn retval;\n}\n\nstatic int esirisc_flash_mass_erase(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t(void)esirisc_flash_disable_protect(bank);\n\n\ttarget_write_u32(target, esirisc_info->cfg + ADDRESS, 0);\n\n\tretval = esirisc_flash_control(bank, CONTROL_E);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"%s: failed to mass erase\", bank->name);\n\n\t(void)esirisc_flash_enable_protect(bank);\n\n\treturn retval;\n}\n\n/*\n * Per TSMC, the reference cell should be erased once per sample. This\n * is typically done during wafer sort, however we include support for\n * those that may need to calibrate flash at a later time.\n */\nstatic int esirisc_flash_ref_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t(void)esirisc_flash_disable_protect(bank);\n\n\tretval = esirisc_flash_control(bank, CONTROL_ERC);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"%s: failed to erase reference cell\", bank->name);\n\n\t(void)esirisc_flash_enable_protect(bank);\n\n\treturn retval;\n}\n\nstatic int esirisc_flash_fill_pb(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t count)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\t/*\n\t * The pb_index register is auto-incremented when pb_data is written\n\t * and should be cleared before each operation.\n\t */\n\ttarget_write_u32(target, esirisc_info->cfg + PB_INDEX, 0);\n\n\t/*\n\t * The width of the pb_data register depends on the underlying\n\t * target; writing one byte at a time incurs a significant\n\t * performance penalty and should be avoided.\n\t */\n\twhile (count > 0) {\n\t\tuint32_t max_bytes = DIV_ROUND_UP(esirisc->num_bits, 8);\n\t\tuint32_t num_bytes = MIN(count, max_bytes);\n\n\t\ttarget_write_buffer(target, esirisc_info->cfg + PB_DATA, num_bytes, buffer);\n\n\t\tbuffer += num_bytes;\n\t\tcount -= num_bytes;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_write(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t(void)esirisc_flash_disable_protect(bank);\n\n\t/*\n\t * The address register is auto-incremented based on the contents of\n\t * the pb_index register after each operation completes. It can be\n\t * set once provided pb_index is cleared before each operation.\n\t */\n\ttarget_write_u32(target, esirisc_info->cfg + ADDRESS, offset);\n\n\t/*\n\t * Care must be taken when filling the program buffer; a maximum of\n\t * 32 bytes may be written at a time and may not cross a 32-byte\n\t * boundary based on the current offset.\n\t */\n\twhile (count > 0) {\n\t\tuint32_t max_bytes = PB_MAX - (offset & 0x1f);\n\t\tuint32_t num_bytes = MIN(count, max_bytes);\n\n\t\tesirisc_flash_fill_pb(bank, buffer, num_bytes);\n\n\t\tretval = esirisc_flash_control(bank, CONTROL_P);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to program address: 0x%\" PRIx32, bank->name, offset);\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += num_bytes;\n\t\toffset += num_bytes;\n\t\tcount -= num_bytes;\n\t}\n\n\t(void)esirisc_flash_enable_protect(bank);\n\n\treturn retval;\n}\n\nstatic uint32_t esirisc_flash_num_cycles(struct flash_bank *bank, uint64_t ns)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\n\t/* apply scaling factor to avoid truncation */\n\tuint64_t hz = (uint64_t)esirisc_info->clock * 1000;\n\tuint64_t num_cycles = ((hz / NUM_NS_PER_S) * ns) / 1000;\n\n\tif (hz % NUM_NS_PER_S > 0)\n\t\tnum_cycles++;\n\n\treturn num_cycles;\n}\n\nstatic int esirisc_flash_init(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t value;\n\tint retval;\n\n\t(void)esirisc_flash_disable_protect(bank);\n\n\t/* initialize timing registers */\n\tvalue = TIMING0_F(esirisc_flash_num_cycles(bank, TNVH))\n\t\t\t| TIMING0_R(esirisc_info->wait_states);\n\n\tLOG_DEBUG(\"TIMING0: 0x%\" PRIx32, value);\n\ttarget_write_u32(target, esirisc_info->cfg + TIMING0, value);\n\n\tvalue = TIMING1_E(esirisc_flash_num_cycles(bank, TERASE));\n\n\tLOG_DEBUG(\"TIMING1: 0x%\" PRIx32, value);\n\ttarget_write_u32(target, esirisc_info->cfg + TIMING1, value);\n\n\tvalue = TIMING2_T(esirisc_flash_num_cycles(bank, 10))\n\t\t\t| TIMING2_H(esirisc_flash_num_cycles(bank, 100))\n\t\t\t| TIMING2_P(esirisc_flash_num_cycles(bank, TPROG));\n\n\tLOG_DEBUG(\"TIMING2: 0x%\" PRIx32, value);\n\ttarget_write_u32(target, esirisc_info->cfg + TIMING2, value);\n\n\t/* recall trim code */\n\tretval = esirisc_flash_recall(bank);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"%s: failed to recall trim code\", bank->name);\n\n\t(void)esirisc_flash_enable_protect(bank);\n\n\treturn retval;\n}\n\nstatic int esirisc_flash_probe(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbank->num_sectors = bank->size / FLASH_PAGE_SIZE;\n\tbank->sectors = alloc_block_array(0, FLASH_PAGE_SIZE, bank->num_sectors);\n\n\tretval = esirisc_flash_init(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to initialize bank\", bank->name);\n\t\treturn retval;\n\t}\n\n\tesirisc_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flash_auto_probe(struct flash_bank *bank)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\n\tif (esirisc_info->probed)\n\t\treturn ERROR_OK;\n\n\treturn esirisc_flash_probe(bank);\n}\n\nstatic int esirisc_flash_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct esirisc_flash_bank *esirisc_info = bank->driver_priv;\n\n\tcommand_print_sameline(cmd,\n\t\t\t\"%4s cfg at 0x%\" PRIx32 \", clock %\" PRIu32 \", wait_states %\" PRIu32,\n\t\t\t\"\",\t/* align with first line */\n\t\t\tesirisc_info->cfg,\n\t\t\tesirisc_info->clock,\n\t\t\tesirisc_info->wait_states);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_flash_mass_erase_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = esirisc_flash_mass_erase(bank);\n\n\tcommand_print(CMD, \"mass erase %s\",\n\t\t\t(retval == ERROR_OK) ? \"successful\" : \"failed\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_esirisc_flash_ref_erase_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = esirisc_flash_ref_erase(bank);\n\n\tcommand_print(CMD, \"erase reference cell %s\",\n\t\t\t(retval == ERROR_OK) ? \"successful\" : \"failed\");\n\n\treturn retval;\n}\n\nstatic const struct command_registration esirisc_flash_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = handle_esirisc_flash_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"erase all pages in data memory\",\n\t\t.usage = \"bank_id\",\n\t},\n\t{\n\t\t.name = \"ref_erase\",\n\t\t.handler = handle_esirisc_flash_ref_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"erase reference cell (uncommon)\",\n\t\t.usage = \"bank_id\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esirisc_flash_command_handlers[] = {\n\t{\n\t\t.name = \"flash\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"eSi-TSMC Flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = esirisc_flash_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver esirisc_flash = {\n\t.name = \"esirisc\",\n\t.usage = \"flash bank bank_id 'esirisc' base_address size_bytes 0 0 target \"\n\t\t\t\"cfg_address clock_hz wait_states\",\n\t.flash_bank_command = esirisc_flash_bank_command,\n\t.erase = esirisc_flash_erase,\n\t.write = esirisc_flash_write,\n\t.read = default_flash_read,\n\t.probe = esirisc_flash_probe,\n\t.auto_probe = esirisc_flash_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = esirisc_flash_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/faux.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/image.h>\n#include \"hello.h\"\n\nstruct faux_flash_bank {\n\tstruct target *target;\n\tuint8_t *memory;\n\tuint32_t start_address;\n};\n\nstatic const int sector_size = 0x10000;\n\n\n/* flash bank faux <base> <size> <chip_width> <bus_width> <target#> <driverPath>\n */\nFLASH_BANK_COMMAND_HANDLER(faux_flash_bank_command)\n{\n\tstruct faux_flash_bank *info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tinfo = malloc(sizeof(struct faux_flash_bank));\n\tif (!info) {\n\t\tLOG_ERROR(\"no memory for flash bank info\");\n\t\treturn ERROR_FAIL;\n\t}\n\tinfo->memory = malloc(bank->size);\n\tif (!info->memory) {\n\t\tfree(info);\n\t\tLOG_ERROR(\"no memory for flash bank info\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbank->driver_priv = info;\n\n\t/* Use 0x10000 as a fixed sector size. */\n\tuint32_t offset = 0;\n\tbank->num_sectors = bank->size/sector_size;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = sector_size;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\tinfo->target = get_target(CMD_ARGV[5]);\n\tif (!info->target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[5]);\n\t\tfree(info->memory);\n\t\tfree(info);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int faux_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct faux_flash_bank *info = bank->driver_priv;\n\tmemset(info->memory + first*sector_size, 0xff, sector_size*(last-first + 1));\n\treturn ERROR_OK;\n}\n\nstatic int faux_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct faux_flash_bank *info = bank->driver_priv;\n\tmemcpy(info->memory + offset, buffer, count);\n\treturn ERROR_OK;\n}\n\nstatic int faux_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tcommand_print_sameline(cmd, \"faux flash driver\");\n\treturn ERROR_OK;\n}\n\nstatic int faux_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration faux_command_handlers[] = {\n\t{\n\t\t.name = \"faux\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"faux flash command group\",\n\t\t.chain = hello_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver faux_flash = {\n\t.name = \"faux\",\n\t.commands = faux_command_handlers,\n\t.flash_bank_command = faux_flash_bank_command,\n\t.erase = faux_erase,\n\t.write = faux_write,\n\t.read = default_flash_read,\n\t.probe = faux_probe,\n\t.auto_probe = faux_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = faux_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/fespi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n *   Modified by Megan Wachs <megan@sifive.com> from the original stmsmi.c *\n ***************************************************************************/\n\n/* The Freedom E SPI controller is a SPI bus controller\n * specifically designed for SPI Flash Memories on Freedom E platforms.\n *\n * Two working modes are available:\n * - SW mode: the SPI is controlled by SW. Any custom commands can be sent\n *   on the bus. Writes are only possible in this mode.\n * - HW mode: Memory content is directly\n *   accessible in CPU memory space. CPU can read and execute memory content.\n */\n\n/* ATTENTION:\n * To have flash memory mapped in CPU memory space, the controller\n * must have \"HW mode\" enabled.\n * 1) The command \"reset init\" has to initialize the controller and put\n *    it in HW mode (this is actually the default out of reset for Freedom E systems).\n * 2) every command in this file have to return to prompt in HW mode. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <jtag/jtag.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include \"target/riscv/riscv.h\"\n\n/* Register offsets */\n\n#define FESPI_REG_SCKDIV          0x00\n#define FESPI_REG_SCKMODE         0x04\n#define FESPI_REG_CSID            0x10\n#define FESPI_REG_CSDEF           0x14\n#define FESPI_REG_CSMODE          0x18\n\n#define FESPI_REG_DCSSCK          0x28\n#define FESPI_REG_DSCKCS          0x2a\n#define FESPI_REG_DINTERCS        0x2c\n#define FESPI_REG_DINTERXFR       0x2e\n\n#define FESPI_REG_FMT             0x40\n#define FESPI_REG_TXFIFO          0x48\n#define FESPI_REG_RXFIFO          0x4c\n#define FESPI_REG_TXCTRL          0x50\n#define FESPI_REG_RXCTRL          0x54\n\n#define FESPI_REG_FCTRL           0x60\n#define FESPI_REG_FFMT            0x64\n\n#define FESPI_REG_IE              0x70\n#define FESPI_REG_IP              0x74\n\n/* Fields */\n\n#define FESPI_SCK_POL             0x1\n#define FESPI_SCK_PHA             0x2\n\n#define FESPI_FMT_PROTO(x)        ((x) & 0x3)\n#define FESPI_FMT_ENDIAN(x)       (((x) & 0x1) << 2)\n#define FESPI_FMT_DIR(x)          (((x) & 0x1) << 3)\n#define FESPI_FMT_LEN(x)          (((x) & 0xf) << 16)\n\n/* TXCTRL register */\n#define FESPI_TXWM(x)             ((x) & 0xffff)\n/* RXCTRL register */\n#define FESPI_RXWM(x)             ((x) & 0xffff)\n\n#define FESPI_IP_TXWM             0x1\n#define FESPI_IP_RXWM             0x2\n\n#define FESPI_FCTRL_EN            0x1\n\n#define FESPI_INSN_CMD_EN         0x1\n#define FESPI_INSN_ADDR_LEN(x)    (((x) & 0x7) << 1)\n#define FESPI_INSN_PAD_CNT(x)     (((x) & 0xf) << 4)\n#define FESPI_INSN_CMD_PROTO(x)   (((x) & 0x3) << 8)\n#define FESPI_INSN_ADDR_PROTO(x)  (((x) & 0x3) << 10)\n#define FESPI_INSN_DATA_PROTO(x)  (((x) & 0x3) << 12)\n#define FESPI_INSN_CMD_CODE(x)    (((x) & 0xff) << 16)\n#define FESPI_INSN_PAD_CODE(x)    (((x) & 0xff) << 24)\n\n/* Values */\n\n#define FESPI_CSMODE_AUTO         0\n#define FESPI_CSMODE_HOLD         2\n#define FESPI_CSMODE_OFF          3\n\n#define FESPI_DIR_RX              0\n#define FESPI_DIR_TX              1\n\n#define FESPI_PROTO_S             0\n#define FESPI_PROTO_D             1\n#define FESPI_PROTO_Q             2\n\n#define FESPI_ENDIAN_MSB          0\n#define FESPI_ENDIAN_LSB          1\n\n\n/* Timeout in ms */\n#define FESPI_CMD_TIMEOUT   (100)\n#define FESPI_PROBE_TIMEOUT (100)\n#define FESPI_MAX_TIMEOUT  (3000)\n\n\nstruct fespi_flash_bank {\n\tbool probed;\n\ttarget_addr_t ctrl_base;\n\tconst struct flash_device *dev;\n};\n\nstruct fespi_target {\n\tchar *name;\n\tuint32_t tap_idcode;\n\tuint32_t ctrl_base;\n};\n\n/* TODO !!! What is the right naming convention here? */\nstatic const struct fespi_target target_devices[] = {\n\t/* name,   tap_idcode, ctrl_base */\n\t{ \"Freedom E310-G000 SPI Flash\", 0x10e31913, 0x10014000 },\n\t{ \"Freedom E310-G002 SPI Flash\", 0x20000913, 0x10014000 },\n\t{ NULL, 0, 0 }\n};\n\nFLASH_BANK_COMMAND_HANDLER(fespi_flash_bank_command)\n{\n\tstruct fespi_flash_bank *fespi_info;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfespi_info = malloc(sizeof(struct fespi_flash_bank));\n\tif (!fespi_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = fespi_info;\n\tfespi_info->probed = false;\n\tfespi_info->ctrl_base = 0;\n\tif (CMD_ARGC >= 7) {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[6], fespi_info->ctrl_base);\n\t\tLOG_DEBUG(\"ASSUMING FESPI device at ctrl_base = \" TARGET_ADDR_FMT,\n\t\t\t\tfespi_info->ctrl_base);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int fespi_read_reg(struct flash_bank *bank, uint32_t *value, target_addr_t address)\n{\n\tstruct target *target = bank->target;\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\n\tint result = target_read_u32(target, fespi_info->ctrl_base + address, value);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"fespi_read_reg() error at \" TARGET_ADDR_FMT,\n\t\t\t\tfespi_info->ctrl_base + address);\n\t\treturn result;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int fespi_write_reg(struct flash_bank *bank, target_addr_t address, uint32_t value)\n{\n\tstruct target *target = bank->target;\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\n\tint result = target_write_u32(target, fespi_info->ctrl_base + address, value);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"fespi_write_reg() error writing 0x%\" PRIx32 \" to \" TARGET_ADDR_FMT,\n\t\t\t\tvalue, fespi_info->ctrl_base + address);\n\t\treturn result;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int fespi_disable_hw_mode(struct flash_bank *bank)\n{\n\tuint32_t fctrl;\n\tif (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl & ~FESPI_FCTRL_EN);\n}\n\nstatic int fespi_enable_hw_mode(struct flash_bank *bank)\n{\n\tuint32_t fctrl;\n\tif (fespi_read_reg(bank, &fctrl, FESPI_REG_FCTRL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn fespi_write_reg(bank, FESPI_REG_FCTRL, fctrl | FESPI_FCTRL_EN);\n}\n\nstatic int fespi_set_dir(struct flash_bank *bank, bool dir)\n{\n\tuint32_t fmt;\n\tif (fespi_read_reg(bank, &fmt, FESPI_REG_FMT) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn fespi_write_reg(bank, FESPI_REG_FMT,\n\t\t\t(fmt & ~(FESPI_FMT_DIR(0xFFFFFFFF))) | FESPI_FMT_DIR(dir));\n}\n\nstatic int fespi_txwm_wait(struct flash_bank *bank)\n{\n\tint64_t start = timeval_ms();\n\n\twhile (1) {\n\t\tuint32_t ip;\n\t\tif (fespi_read_reg(bank, &ip, FESPI_REG_IP) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (ip & FESPI_IP_TXWM)\n\t\t\tbreak;\n\t\tint64_t now = timeval_ms();\n\t\tif (now - start > 1000) {\n\t\t\tLOG_ERROR(\"ip.txwm didn't get set.\");\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int fespi_tx(struct flash_bank *bank, uint8_t in)\n{\n\tint64_t start = timeval_ms();\n\n\twhile (1) {\n\t\tuint32_t txfifo;\n\t\tif (fespi_read_reg(bank, &txfifo, FESPI_REG_TXFIFO) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (!(txfifo >> 31))\n\t\t\tbreak;\n\t\tint64_t now = timeval_ms();\n\t\tif (now - start > 1000) {\n\t\t\tLOG_ERROR(\"txfifo stayed negative.\");\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t}\n\n\treturn fespi_write_reg(bank, FESPI_REG_TXFIFO, in);\n}\n\nstatic int fespi_rx(struct flash_bank *bank, uint8_t *out)\n{\n\tint64_t start = timeval_ms();\n\tuint32_t value;\n\n\twhile (1) {\n\t\tif (fespi_read_reg(bank, &value, FESPI_REG_RXFIFO) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (!(value >> 31))\n\t\t\tbreak;\n\t\tint64_t now = timeval_ms();\n\t\tif (now - start > 1000) {\n\t\t\tLOG_ERROR(\"rxfifo didn't go positive (value=0x%\" PRIx32 \").\", value);\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t}\n\n\tif (out)\n\t\t*out = value & 0xff;\n\n\treturn ERROR_OK;\n}\n\n/* TODO!!! Why don't we need to call this after writing? */\nstatic int fespi_wip(struct flash_bank *bank, int timeout)\n{\n\tint64_t endtime;\n\n\tfespi_set_dir(bank, FESPI_DIR_RX);\n\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tendtime = timeval_ms() + timeout;\n\n\tfespi_tx(bank, SPIFLASH_READ_STATUS);\n\tif (fespi_rx(bank, NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tdo {\n\t\talive_sleep(1);\n\n\t\tfespi_tx(bank, 0);\n\t\tuint8_t rx;\n\t\tif (fespi_rx(bank, &rx) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif ((rx & SPIFLASH_BSY_BIT) == 0) {\n\t\t\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tfespi_set_dir(bank, FESPI_DIR_TX);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_FAIL;\n}\n\nstatic int fespi_erase_sector(struct flash_bank *bank, int sector)\n{\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tint retval;\n\n\tretval = fespi_tx(bank, SPIFLASH_WRITE_ENABLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = fespi_txwm_wait(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tretval = fespi_tx(bank, fespi_info->dev->erase_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tsector = bank->sectors[sector].offset;\n\tif (bank->size > 0x1000000) {\n\t\tretval = fespi_tx(bank, sector >> 24);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = fespi_tx(bank, sector >> 16);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = fespi_tx(bank, sector >> 8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = fespi_tx(bank, sector);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = fespi_txwm_wait(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tretval = fespi_wip(bank, FESPI_MAX_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int fespi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: from sector %u to sector %u\", __func__, first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!(fespi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (fespi_info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tif (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tretval = fespi_txwm_wait(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"WM Didn't go high before attempting.\");\n\t\treturn retval;\n\t}\n\n\t/* Disable Hardware accesses*/\n\tif (fespi_disable_hw_mode(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* poll WIP */\n\tretval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = fespi_erase_sector(bank, sector);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tkeep_alive();\n\t}\n\n\t/* Switch to HW mode before return to prompt */\ndone:\n\tif (fespi_enable_hw_mode(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn retval;\n}\n\nstatic int fespi_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\treturn ERROR_OK;\n}\n\nstatic int slow_fespi_write_buffer(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t len)\n{\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tuint32_t ii;\n\n\t/* TODO!!! assert that len < page size */\n\n\tif (fespi_tx(bank, SPIFLASH_WRITE_ENABLE) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (fespi_txwm_wait(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (fespi_tx(bank, fespi_info->dev->pprog_cmd) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (bank->size > 0x1000000 && fespi_tx(bank, offset >> 24) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (fespi_tx(bank, offset >> 16) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (fespi_tx(bank, offset >> 8) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (fespi_tx(bank, offset) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tfor (ii = 0; ii < len; ii++) {\n\t\tif (fespi_tx(bank, buffer[ii]) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (fespi_txwm_wait(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tkeep_alive();\n\n\treturn ERROR_OK;\n}\n\nstatic const uint8_t riscv32_bin[] = {\n#include \"../../../contrib/loaders/flash/fespi/riscv32_fespi.inc\"\n};\n\nstatic const uint8_t riscv64_bin[] = {\n#include \"../../../contrib/loaders/flash/fespi/riscv64_fespi.inc\"\n};\n\nstatic int fespi_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tuint32_t cur_count, page_size;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"bank->size=0x%x offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t\tbank->size, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > fespi_info->dev->size_in_bytes) {\n\t\tLOG_WARNING(\"Write past end of flash. Extra data discarded.\");\n\t\tcount = fespi_info->dev->size_in_bytes - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tif ((offset <\n\t\t\t\t\t(bank->sectors[sector].offset + bank->sectors[sector].size))\n\t\t\t\t&& ((offset + count - 1) >= bank->sectors[sector].offset)\n\t\t\t\t&& bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct riscv_info *riscv = riscv_info(target);\n\tif (!is_riscv(riscv)) {\n\t\tLOG_ERROR(\"Unexpected target type\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tunsigned int xlen = riscv_xlen(target);\n\tstruct working_area *algorithm_wa = NULL;\n\tstruct working_area *data_wa = NULL;\n\tconst uint8_t *bin;\n\tsize_t bin_size;\n\tif (xlen == 32) {\n\t\tbin = riscv32_bin;\n\t\tbin_size = sizeof(riscv32_bin);\n\t} else {\n\t\tbin = riscv64_bin;\n\t\tbin_size = sizeof(riscv64_bin);\n\t}\n\n\tunsigned data_wa_size = 0;\n\tif (target_alloc_working_area(target, bin_size, &algorithm_wa) == ERROR_OK) {\n\t\tretval = target_write_buffer(target, algorithm_wa->address,\n\t\t\t\tbin_size, bin);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to write code to \" TARGET_ADDR_FMT \": %d\",\n\t\t\t\t\talgorithm_wa->address, retval);\n\t\t\ttarget_free_working_area(target, algorithm_wa);\n\t\t\talgorithm_wa = NULL;\n\n\t\t} else {\n\t\t\tdata_wa_size = MIN(target_get_working_area_avail(target), count);\n\t\t\tif (data_wa_size < 128) {\n\t\t\t\tLOG_WARNING(\"Couldn't allocate data working area.\");\n\t\t\t\ttarget_free_working_area(target, algorithm_wa);\n\t\t\t\talgorithm_wa = NULL;\n\t\t\t} else if (target_alloc_working_area(target, data_wa_size, &data_wa) != ERROR_OK) {\n\t\t\t\ttarget_free_working_area(target, algorithm_wa);\n\t\t\t\talgorithm_wa = NULL;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tLOG_WARNING(\"Couldn't allocate %zd-byte working area.\", bin_size);\n\t\talgorithm_wa = NULL;\n\t}\n\n\t/* If no valid page_size, use reasonable default. */\n\tpage_size = fespi_info->dev->pagesize ?\n\t\tfespi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\tif (algorithm_wa) {\n\t\tstruct reg_param reg_params[6];\n\t\tinit_reg_param(&reg_params[0], \"a0\", xlen, PARAM_IN_OUT);\n\t\tinit_reg_param(&reg_params[1], \"a1\", xlen, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[2], \"a2\", xlen, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[3], \"a3\", xlen, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[4], \"a4\", xlen, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[5], \"a5\", xlen, PARAM_OUT);\n\n\t\twhile (count > 0) {\n\t\t\tcur_count = MIN(count, data_wa_size);\n\t\t\tbuf_set_u64(reg_params[0].value, 0, xlen, fespi_info->ctrl_base);\n\t\t\tbuf_set_u64(reg_params[1].value, 0, xlen, page_size);\n\t\t\tbuf_set_u64(reg_params[2].value, 0, xlen, data_wa->address);\n\t\t\tbuf_set_u64(reg_params[3].value, 0, xlen, offset);\n\t\t\tbuf_set_u64(reg_params[4].value, 0, xlen, cur_count);\n\t\t\tbuf_set_u64(reg_params[5].value, 0, xlen,\n\t\t\t\t\tfespi_info->dev->pprog_cmd | (bank->size > 0x1000000 ? 0x100 : 0));\n\n\t\t\tretval = target_write_buffer(target, data_wa->address, cur_count,\n\t\t\t\t\tbuffer);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"Failed to write %d bytes to \" TARGET_ADDR_FMT \": %d\",\n\t\t\t\t\t\tcur_count, data_wa->address, retval);\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"write(ctrl_base=0x%\" TARGET_PRIxADDR \", page_size=0x%x, \"\n\t\t\t\t\t\"address=0x%\" TARGET_PRIxADDR \", offset=0x%\" PRIx32\n\t\t\t\t\t\", count=0x%\" PRIx32 \"), buffer=%02x %02x %02x %02x %02x %02x ...\" PRIx32,\n\t\t\t\t\tfespi_info->ctrl_base, page_size, data_wa->address, offset, cur_count,\n\t\t\t\t\tbuffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]);\n\t\t\tretval = target_run_algorithm(target, 0, NULL,\n\t\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\t\talgorithm_wa->address, 0, cur_count * 2, NULL);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to execute algorithm at \" TARGET_ADDR_FMT \": %d\",\n\t\t\t\t\t\talgorithm_wa->address, retval);\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\tuint64_t algorithm_result = buf_get_u64(reg_params[0].value, 0, xlen);\n\t\t\tif (algorithm_result != 0) {\n\t\t\t\tLOG_ERROR(\"Algorithm returned error %\" PRId64, algorithm_result);\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\tbuffer += cur_count;\n\t\t\toffset += cur_count;\n\t\t\tcount -= cur_count;\n\t\t}\n\n\t\ttarget_free_working_area(target, data_wa);\n\t\ttarget_free_working_area(target, algorithm_wa);\n\n\t} else {\n\t\tfespi_txwm_wait(bank);\n\n\t\t/* Disable Hardware accesses*/\n\t\tif (fespi_disable_hw_mode(bank) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* poll WIP */\n\t\tretval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tuint32_t page_offset = offset % page_size;\n\t\t/* central part, aligned words */\n\t\twhile (count > 0) {\n\t\t\t/* clip block at page boundary */\n\t\t\tif (page_offset + count > page_size)\n\t\t\t\tcur_count = page_size - page_offset;\n\t\t\telse\n\t\t\t\tcur_count = count;\n\n\t\t\tretval = slow_fespi_write_buffer(bank, buffer, offset, cur_count);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\n\t\t\tpage_offset = 0;\n\t\t\tbuffer += cur_count;\n\t\t\toffset += cur_count;\n\t\t\tcount -= cur_count;\n\t\t}\n\n\t\t/* Switch to HW mode before return to prompt */\n\t\tif (fespi_enable_hw_mode(bank) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n\nerr:\n\ttarget_free_working_area(target, data_wa);\n\ttarget_free_working_area(target, algorithm_wa);\n\n\t/* Switch to HW mode before return to prompt */\n\tif (fespi_enable_hw_mode(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn retval;\n}\n\n/* Return ID of flash device */\n/* On exit, SW mode is kept */\nstatic int fespi_read_flash_id(struct flash_bank *bank, uint32_t *id)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfespi_txwm_wait(bank);\n\n\t/* poll WIP */\n\tretval = fespi_wip(bank, FESPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfespi_set_dir(bank, FESPI_DIR_RX);\n\n\t/* Send SPI command \"read ID\" */\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_HOLD) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tfespi_tx(bank, SPIFLASH_READ_ID);\n\t/* Send dummy bytes to actually read the ID.*/\n\tfespi_tx(bank, 0);\n\tfespi_tx(bank, 0);\n\tfespi_tx(bank, 0);\n\n\t/* read ID from Receive Register */\n\t*id = 0;\n\tif (fespi_rx(bank, NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tuint8_t rx;\n\tif (fespi_rx(bank, &rx) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*id = rx;\n\tif (fespi_rx(bank, &rx) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*id |= (rx << 8);\n\tif (fespi_rx(bank, &rx) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*id |= (rx << 16);\n\n\tif (fespi_write_reg(bank, FESPI_REG_CSMODE, FESPI_CSMODE_AUTO) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tfespi_set_dir(bank, FESPI_DIR_TX);\n\n\treturn ERROR_OK;\n}\n\nstatic int fespi_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tstruct flash_sector *sectors;\n\tuint32_t id = 0; /* silence uninitialized warning */\n\tconst struct fespi_target *target_device;\n\tint retval;\n\tuint32_t sectorsize;\n\n\tif (fespi_info->probed)\n\t\tfree(bank->sectors);\n\tfespi_info->probed = false;\n\n\tif (fespi_info->ctrl_base == 0) {\n\t\tfor (target_device = target_devices ; target_device->name ; ++target_device)\n\t\t\tif (target_device->tap_idcode == target->tap->idcode)\n\t\t\t\tbreak;\n\n\t\tif (!target_device->name) {\n\t\t\tLOG_ERROR(\"Device ID 0x%\" PRIx32 \" is not known as FESPI capable\",\n\t\t\t\t\ttarget->tap->idcode);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tfespi_info->ctrl_base = target_device->ctrl_base;\n\n\t\tLOG_DEBUG(\"Valid FESPI on device %s at address \" TARGET_ADDR_FMT,\n\t\t\t\ttarget_device->name, bank->base);\n\n\t} else {\n\t  LOG_DEBUG(\"Assuming FESPI as specified at address \" TARGET_ADDR_FMT\n\t\t\t  \" with ctrl at \" TARGET_ADDR_FMT, fespi_info->ctrl_base,\n\t\t\t  bank->base);\n\t}\n\n\t/* read and decode flash ID; returns in SW mode */\n\tif (fespi_write_reg(bank, FESPI_REG_TXCTRL, FESPI_TXWM(1)) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tfespi_set_dir(bank, FESPI_DIR_TX);\n\n\t/* Disable Hardware accesses*/\n\tif (fespi_disable_hw_mode(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tretval = fespi_read_flash_id(bank, &id);\n\n\tif (fespi_enable_hw_mode(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfespi_info->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name ; p++)\n\t\tif (p->device_id == id) {\n\t\t\tfespi_info->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!fespi_info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%08\" PRIx32 \")\",\n\t\t\tfespi_info->dev->name, fespi_info->dev->device_id);\n\n\t/* Set correct size value */\n\tbank->size = fespi_info->dev->size_in_bytes;\n\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = fespi_info->dev->sectorsize ?\n\t\tfespi_info->dev->sectorsize : fespi_info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = fespi_info->dev->size_in_bytes / sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tfespi_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int fespi_auto_probe(struct flash_bank *bank)\n{\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\tif (fespi_info->probed)\n\t\treturn ERROR_OK;\n\treturn fespi_probe(bank);\n}\n\nstatic int fespi_protect_check(struct flash_bank *bank)\n{\n\t/* Nothing to do. Protection is only handled in SW. */\n\treturn ERROR_OK;\n}\n\nstatic int get_fespi_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct fespi_flash_bank *fespi_info = bank->driver_priv;\n\n\tif (!(fespi_info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nFESPI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nFESPI flash information:\\n\"\n\t\t\t\"  Device \\'%s\\' (ID 0x%08\" PRIx32 \")\\n\",\n\t\t\tfespi_info->dev->name, fespi_info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver fespi_flash = {\n\t.name = \"fespi\",\n\t.flash_bank_command = fespi_flash_bank_command,\n\t.erase = fespi_erase,\n\t.protect = fespi_protect,\n\t.write = fespi_write,\n\t.read = default_flash_read,\n\t.probe = fespi_probe,\n\t.auto_probe = fespi_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = fespi_protect_check,\n\t.info = get_fespi_info,\n\t.free_driver_priv = default_flash_free_driver_priv\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/fm3.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Marc Willam, Holger Wech                        *\n *       openOCD.fseu(AT)de.fujitsu.com                                    *\n *   Copyright (C) 2011 Ronny Strutz                                       *\n *                                                                         *\n *   Copyright (C) 2013 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define FLASH_DQ6 0x40\t\t/* Data toggle flag bit (TOGG) position */\n#define FLASH_DQ5 0x20\t\t/* Time limit exceeding flag bit (TLOV) position */\n\nenum fm3_variant {\n\tMB9BFXX1,\t/* Flash Type '1' */\n\tMB9BFXX2,\n\tMB9BFXX3,\n\tMB9BFXX4,\n\tMB9BFXX5,\n\tMB9BFXX6,\n\tMB9BFXX7,\n\tMB9BFXX8,\n\n\tMB9AFXX1,\t/* Flash Type '2' */\n\tMB9AFXX2,\n\tMB9AFXX3,\n\tMB9AFXX4,\n\tMB9AFXX5,\n\tMB9AFXX6,\n\tMB9AFXX7,\n\tMB9AFXX8,\n};\n\nenum fm3_flash_type {\n\tFM3_NO_FLASH_TYPE = 0,\n\tFM3_FLASH_TYPE1   = 1,\n\tFM3_FLASH_TYPE2   = 2\n};\n\nstruct fm3_flash_bank {\n\tenum fm3_variant variant;\n\tenum fm3_flash_type flashtype;\n\tbool probed;\n};\n\nFLASH_BANK_COMMAND_HANDLER(fm3_flash_bank_command)\n{\n\tstruct fm3_flash_bank *fm3_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfm3_info = malloc(sizeof(struct fm3_flash_bank));\n\tbank->driver_priv = fm3_info;\n\n\t/* Flash type '1' */\n\tif (strcmp(CMD_ARGV[5], \"mb9bfxx1.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX1;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx2.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX2;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx3.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX3;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx4.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX4;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx5.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX5;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx6.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX6;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx7.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX7;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9bfxx8.cpu\") == 0) {\n\t\tfm3_info->variant = MB9BFXX8;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE1;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx1.cpu\") == 0) {\t/* Flash type '2' */\n\t\tfm3_info->variant = MB9AFXX1;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx2.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX2;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx3.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX3;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx4.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX4;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx5.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX5;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx6.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX6;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx7.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX7;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t} else if (strcmp(CMD_ARGV[5], \"mb9afxx8.cpu\") == 0) {\n\t\tfm3_info->variant = MB9AFXX8;\n\t\tfm3_info->flashtype = FM3_FLASH_TYPE2;\n\t}\n\n\t/* unknown Flash type */\n\telse {\n\t\tLOG_ERROR(\"unknown fm3 variant: %s\", CMD_ARGV[5]);\n\t\tfree(fm3_info);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tfm3_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\n/* Data polling algorithm */\nstatic int fm3_busy_wait(struct target *target, uint32_t offset, int timeout_ms)\n{\n\tint retval = ERROR_OK;\n\tuint8_t state1, state2;\n\tint ms = 0;\n\n\t/* While(1) loop exit via \"break\" and \"return\" on error */\n\twhile (1) {\n\t\t/* dummy-read - see flash manual */\n\t\tretval = target_read_u8(target, offset, &state1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Data polling 1 */\n\t\tretval = target_read_u8(target, offset, &state1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Data polling 2 */\n\t\tretval = target_read_u8(target, offset, &state2);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Flash command finished via polled data equal? */\n\t\tif ((state1 & FLASH_DQ6) == (state2 & FLASH_DQ6))\n\t\t\tbreak;\n\t\t/* Timeout Flag? */\n\t\telse if (state1 & FLASH_DQ5) {\n\t\t\t/* Retry data polling */\n\n\t\t\t/* Data polling 1 */\n\t\t\tretval = target_read_u8(target, offset, &state1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* Data polling 2 */\n\t\t\tretval = target_read_u8(target, offset, &state2);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* Flash command finished via polled data equal? */\n\t\t\tif ((state1 & FLASH_DQ6) != (state2 & FLASH_DQ6))\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\t\t/* finish anyway */\n\t\t\tbreak;\n\t\t}\n\t\tusleep(1000);\n\t\t++ms;\n\n\t\t/* Polling time exceeded? */\n\t\tif (ms > timeout_ms) {\n\t\t\tLOG_ERROR(\"Polling data reading timed out!\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tif (retval == ERROR_OK)\n\t\tLOG_DEBUG(\"fm3_busy_wait(%\" PRIx32 \") needs about %d ms\", offset, ms);\n\n\treturn retval;\n}\n\nstatic int fm3_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct fm3_flash_bank *fm3_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval = ERROR_OK;\n\tuint32_t u32_dummy_read;\n\tint odd;\n\tuint32_t u32_flash_type;\n\tuint32_t u32_flash_seq_address1;\n\tuint32_t u32_flash_seq_address2;\n\n\tstruct working_area *write_algorithm;\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_info;\n\n\tu32_flash_type = (uint32_t) fm3_info->flashtype;\n\n\tif (u32_flash_type == FM3_FLASH_TYPE1) {\n\t\tu32_flash_seq_address1 = 0x00001550;\n\t\tu32_flash_seq_address2 = 0x00000AA8;\n\t} else if (u32_flash_type == FM3_FLASH_TYPE2) {\n\t\tu32_flash_seq_address1 = 0x00000AA8;\n\t\tu32_flash_seq_address2 = 0x00000554;\n\t} else {\n\t\tLOG_ERROR(\"Flash/Device type unknown!\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* RAMCODE used for fm3 Flash sector erase:\t\t\t\t   */\n\t/* R0 keeps Flash Sequence address 1     (u32FlashSeq1)    */\n\t/* R1 keeps Flash Sequence address 2     (u32FlashSeq2)    */\n\t/* R2 keeps Flash Offset address         (ofs)\t\t\t   */\n\tstatic const uint8_t fm3_flash_erase_sector_code[] = {\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0xAA; */\n\t\t0xAA, 0x24,\t\t/*        MOVS  R4, #0xAA              */\n\t\t0x04, 0x80,\t\t/*        STRH  R4, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq2 = 0x55; */\n\t\t0x55, 0x23,\t\t/*        MOVS  R3, #0x55              */\n\t\t0x0B, 0x80,\t\t/*        STRH  R3, [R1, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0x80; */\n\t\t0x80, 0x25,\t\t/*        MOVS  R5, #0x80              */\n\t\t0x05, 0x80,\t\t/*        STRH  R5, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0xAA; */\n\t\t0x04, 0x80,\t\t/*        STRH  R4, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq2 = 0x55; */\n\t\t0x0B, 0x80,\t\t/*        STRH  R3, [R1, #0]           */\n\t\t\t\t\t\t/* Sector_Erase Command (0x30)         */\n\t\t\t\t\t\t/*    *(uint16_t*)ofs = 0x30;          */\n\t\t0x30, 0x20,\t\t/*        MOVS  R0, #0x30              */\n\t\t0x10, 0x80,\t\t/*        STRH  R0, [R2, #0]           */\n\t\t\t\t\t\t/* End Code                            */\n\t\t0x00, 0xBE,\t\t/*        BKPT  #0                     */\n\t};\n\n\tLOG_INFO(\"Fujitsu MB9[A/B]FXXX: Sector Erase ... (%u to %u)\", first, last);\n\n\t/* disable HW watchdog */\n\tretval = target_write_u32(target, 0x40011C00, 0x1ACCE551);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011C00, 0xE5331AAE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011008, 0x00000000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */\n\tretval = target_write_u32(target, 0x40000000, 0x0001);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* dummy read of FASZR */\n\tretval = target_read_u32(target, 0x40000000, &u32_dummy_read);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* allocate working area with flash sector erase code */\n\tif (target_alloc_working_area(target, sizeof(fm3_flash_erase_sector_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\tsizeof(fm3_flash_erase_sector_code), fm3_flash_erase_sector_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /* u32_flash_seq_address1 */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /* u32_flash_seq_address2 */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT); /* offset\t\t\t\t*/\n\n\t/* write code buffer and use Flash sector erase code within fm3\t\t\t\t*/\n\tfor (unsigned int sector = first ; sector <= last ; sector++) {\n\t\tuint32_t offset = bank->sectors[sector].offset;\n\n\t\tfor (odd = 0; odd < 2 ; odd++) {\n\t\t\tif (odd)\n\t\t\t\toffset += 4;\n\n\t\t\tbuf_set_u32(reg_params[0].value, 0, 32, u32_flash_seq_address1);\n\t\t\tbuf_set_u32(reg_params[1].value, 0, 32, u32_flash_seq_address2);\n\t\t\tbuf_set_u32(reg_params[2].value, 0, 32, offset);\n\n\t\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\t\twrite_algorithm->address, 0, 100000, &armv7m_info);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error executing flash erase programming algorithm\");\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tretval = fm3_busy_wait(target, offset, 500);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, write_algorithm);\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\n\t/* FASZR = 0x02, Enables CPU Run Mode (32-bit Flash access) */\n\tretval = target_write_u32(target, 0x40000000, 0x0002);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, 0x40000000, &u32_dummy_read); /* dummy read of FASZR */\n\n\treturn retval;\n}\n\nstatic int fm3_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct fm3_flash_bank *fm3_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 2048;\t\t/* Default minimum value */\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\tuint32_t u32_flash_type;\n\tuint32_t u32_flash_seq_address1;\n\tuint32_t u32_flash_seq_address2;\n\n\t/* Increase buffer_size if needed */\n\tif (buffer_size < (target->working_area_size / 2))\n\t\tbuffer_size = (target->working_area_size / 2);\n\n\tu32_flash_type = (uint32_t) fm3_info->flashtype;\n\n\tif (u32_flash_type == FM3_FLASH_TYPE1) {\n\t\tu32_flash_seq_address1 = 0x00001550;\n\t\tu32_flash_seq_address2 = 0x00000AA8;\n\t} else if (u32_flash_type == FM3_FLASH_TYPE2) {\n\t\tu32_flash_seq_address1 = 0x00000AA8;\n\t\tu32_flash_seq_address2 = 0x00000554;\n\t} else {\n\t\tLOG_ERROR(\"Flash/Device type unknown!\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* RAMCODE used for fm3 Flash programming:                 */\n\t/* R0 keeps source start address         (u32Source)       */\n\t/* R1 keeps target start address         (u32Target)       */\n\t/* R2 keeps number of halfwords to write (u32Count)        */\n\t/* R3 keeps Flash Sequence address 1     (u32FlashSeq1)    */\n\t/* R4 keeps Flash Sequence address 2     (u32FlashSeq2)    */\n\t/* R5 returns result value               (u32FlashResult)  */\n\n\tstatic const uint8_t fm3_flash_write_code[] = {\n\t\t\t\t\t\t\t\t/*    fm3_FLASH_IF->FASZ &= 0xFFFD;           */\n\t0x5F, 0xF0, 0x80, 0x45,\t\t/*        MOVS.W   R5, #(fm3_FLASH_IF->FASZ)  */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x4F, 0xF6, 0xFD, 0x76,\t\t/*        MOVW     R6, #0xFFFD                */\n\t0x35, 0x40,\t\t\t\t\t/*        ANDS     R5, R5, R6                 */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x35, 0x60,\t\t\t\t\t/*        STR      R5, [R6]                   */\n\t\t\t\t\t\t\t\t/*    fm3_FLASH_IF->FASZ |= 1;                */\n\t0x5F, 0xF0, 0x80, 0x45,\t\t/*        MOVS.W   R5, #(fm3_FLASH_IF->FASZ)  */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R3]                   */\n\t0x55, 0xF0, 0x01, 0x05,\t\t/*        ORRS.W   R5, R5, #1                 */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x35, 0x60,\t\t\t\t\t/*        STR      R5, [R6]                   */\n\t\t\t\t\t\t\t\t/*    u32_dummy_read = fm3_FLASH_IF->FASZ;      */\n\t0x28, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32_dummy_read         */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x36, 0x68,\t\t\t\t\t/*        LDR      R6, [R6]                   */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t\t\t\t\t\t\t\t/*    u32FlashResult = FLASH_WRITE_NO_RESULT  */\n\t0x26, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x00, 0x26,\t\t\t\t\t/*        MOVS     R6, #0                     */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t\t\t\t\t\t\t\t/*    while ((u32Count > 0 )                  */\n\t\t\t\t\t\t\t\t/*      && (u32FlashResult                    */\n\t\t\t\t\t\t\t\t/*          == FLASH_WRITE_NO_RESULT))        */\n\t0x01, 0x2A,\t\t\t\t\t/* L0:    CMP      R2, #1                     */\n\t0x2C, 0xDB,\t\t\t\t\t/*        BLT.N    L1                         */\n\t0x24, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x00, 0x2D,\t\t\t\t\t/*        CMP      R5, #0                     */\n\t0x28, 0xD1,\t\t\t\t\t/*        BNE.N    L1                         */\n\t\t\t\t\t\t\t\t/*    *u32FlashSeq1 = FLASH_WRITE_1;          */\n\t0xAA, 0x25,\t\t\t\t\t/*        MOVS     R5, #0xAA                  */\n\t0x1D, 0x60,\t\t\t\t\t/*        STR      R5, [R3]                   */\n\t\t\t\t\t\t\t\t/*    *u32FlashSeq2 = FLASH_WRITE_2;          */\n\t0x55, 0x25,\t\t\t\t\t/*        MOVS     R5, #0x55                  */\n\t0x25, 0x60,\t\t\t\t\t/*        STR      R5, [R4]                   */\n\t\t\t\t\t\t\t\t/*    *u32FlashSeq1 = FLASH_WRITE_3;          */\n\t0xA0, 0x25,\t\t\t\t\t/*        MOVS     R5, #0xA0                  */\n\t0x1D, 0x60,\t\t\t\t\t/*        STRH     R5, [R3]                   */\n\t\t\t\t\t\t\t\t/*    *(volatile uint16_t*)u32Target          */\n\t\t\t\t\t\t\t\t/*      = *(volatile uint16_t*)u32Source;     */\n\t0x05, 0x88,\t\t\t\t\t/*        LDRH     R5, [R0]                   */\n\t0x0D, 0x80,\t\t\t\t\t/*        STRH     R5, [R1]                   */\n\t\t\t\t\t\t\t\t/*    while (u32FlashResult                   */\n\t\t\t\t\t\t\t\t/*           == FLASH_WRITE_NO_RESTULT)       */\n\t0x1E, 0x4D,\t\t\t\t\t/* L2:    LDR.N    R5, ??u32FlashResult       */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x00, 0x2D,\t\t\t\t\t/*        CMP      R5, #0                     */\n\t0x11, 0xD1,\t\t\t\t\t/*        BNE.N    L3                         */\n\t\t\t\t\t\t\t\t/*    if ((*(volatile uint16_t*)u32Target     */\n\t\t\t\t\t\t\t\t/*        & FLASH_DQ5) == FLASH_DQ5)          */\n\t0x0D, 0x88,\t\t\t\t\t/*        LDRH     R5, [R1]                   */\n\t0xAD, 0x06,\t\t\t\t\t/*        LSLS     R5, R5, #0x1A              */\n\t0x02, 0xD5,\t\t\t\t\t/*        BPL.N    L4                         */\n\t\t\t\t\t\t\t\t/*    u32FlashResult = FLASH_WRITE_TIMEOUT    */\n\t0x1A, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x02, 0x26,\t\t\t\t\t/*        MOVS     R6, #2                     */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t\t\t\t\t\t\t\t/*    if ((*(volatile uint16_t *)u32Target    */\n\t\t\t\t\t\t\t\t/*         & FLASH_DQ7)                       */\n\t\t\t\t\t\t\t\t/*        == (*(volatile uint16_t*)u32Source  */\n\t\t\t\t\t\t\t\t/*            & FLASH_DQ7))                   */\n\t0x0D, 0x88,\t\t\t\t\t/* L4:    LDRH     R5, [R1]                   */\n\t0x15, 0xF0, 0x80, 0x05,\t\t/*        ANDS.W   R5, R5, #0x80              */\n\t0x06, 0x88,\t\t\t\t\t/*        LDRH     R6, [R0]                   */\n\t0x16, 0xF0, 0x80, 0x06,\t\t/*        ANDS.W   R6, R6, #0x80              */\n\t0xB5, 0x42,\t\t\t\t\t/*        CMP      R5, R6                     */\n\t0xED, 0xD1,\t\t\t\t\t/*        BNE.N    L2                         */\n\t\t\t\t\t\t\t\t/*    u32FlashResult = FLASH_WRITE_OKAY       */\n\t0x15, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x01, 0x26,\t\t\t\t\t/*        MOVS     R6, #1                     */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t0xE9, 0xE7,\t\t\t\t\t/*        B.N      L2                         */\n\t\t\t\t\t\t\t\t/*    if (u32FlashResult                      */\n\t\t\t\t\t\t\t\t/*        != FLASH_WRITE_TIMEOUT)             */\n\t0x13, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x02, 0x2D,\t\t\t\t\t/*        CMP      R5, #2                     */\n\t0x02, 0xD0,\t\t\t\t\t/*        BEQ.N    L5                         */\n\t\t\t\t\t\t\t\t/*    u32FlashResult = FLASH_WRITE_NO_RESULT  */\n\t0x11, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32FlashResult       */\n\t0x00, 0x26,\t\t\t\t\t/*        MOVS     R6, #0                     */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t\t\t\t\t\t\t\t/*    u32Count--;                             */\n\t0x52, 0x1E,\t\t\t\t\t/* L5:    SUBS     R2, R2, #1                 */\n\t\t\t\t\t\t\t\t/*    u32Source += 2;                         */\n\t0x80, 0x1C,\t\t\t\t\t/*        ADDS     R0, R0, #2                 */\n\t\t\t\t\t\t\t\t/*    u32Target += 2;                         */\n\t0x89, 0x1C,\t\t\t\t\t/*        ADDS     R1, R1, #2                 */\n\t0xD0, 0xE7,\t\t\t\t\t/*        B.N      L0                         */\n\t\t\t\t\t\t\t\t/*    fm3_FLASH_IF->FASZ &= 0xFFFE;           */\n\t0x5F, 0xF0, 0x80, 0x45,\t\t/* L1:    MOVS.W   R5, #(fm3_FLASH_IF->FASZ)  */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x4F, 0xF6, 0xFE, 0x76,\t\t/*        MOVW     R6, #0xFFFE                */\n\t0x35, 0x40,\t\t\t\t\t/*        ANDS     R5, R5, R6                 */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x35, 0x60,\t\t\t\t\t/*        STR      R5, [R6]                   */\n\t\t\t\t\t\t\t\t/*    fm3_FLASH_IF->FASZ |= 2;                */\n\t0x5F, 0xF0, 0x80, 0x45,\t\t/*        MOVS.W   R5, #(fm3_FLASH_IF->FASZ)  */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t0x55, 0xF0, 0x02, 0x05,\t\t/*        ORRS.W   R5, R5, #2                 */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x35, 0x60,\t\t\t\t\t/*        STR      R5, [R6]                   */\n\t\t\t\t\t\t\t\t/*    u32_dummy_read = fm3_FLASH_IF->FASZ;      */\n\t0x04, 0x4D,\t\t\t\t\t/*        LDR.N    R5, ??u32_dummy_read         */\n\t0x5F, 0xF0, 0x80, 0x46,\t\t/*        MOVS.W   R6, #(fm3_FLASH_IF->FASZ)  */\n\t0x36, 0x68,\t\t\t\t\t/*        LDR      R6, [R6]                   */\n\t0x2E, 0x60,\t\t\t\t\t/*        STR      R6, [R5]                   */\n\t\t\t\t\t\t\t\t/*    copy u32FlashResult to R3 for return    */\n\t\t\t\t\t\t\t\t/*      value                                 */\n\t0xDF, 0xF8, 0x08, 0x50,\t\t/*        LDR.W    R5, ??u32FlashResult       */\n\t0x2D, 0x68,\t\t\t\t\t/*        LDR      R5, [R5]                   */\n\t\t\t\t\t\t\t\t/*    Breakpoint here                         */\n\t0x00, 0xBE,\t\t\t\t\t/*        BKPT     #0                         */\n\n\t/* The following address pointers assume, that the code is running from   */\n\t/* SRAM basic-address + 8.These address pointers will be patched, if a    */\n\t/* different start address in RAM is used (e.g. for Flash type 2)!        */\n\t/* Default SRAM basic-address is 0x20000000.                              */\n\t0x00, 0x00, 0x00, 0x20,     /* u32_dummy_read address in RAM (0x20000000)   */\n\t0x04, 0x00, 0x00, 0x20      /* u32FlashResult address in RAM (0x20000004) */\n\t};\n\n\tLOG_INFO(\"Fujitsu MB9[A/B]FXXX: FLASH Write ...\");\n\n\t/* disable HW watchdog */\n\tretval = target_write_u32(target, 0x40011C00, 0x1ACCE551);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011C00, 0xE5331AAE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011008, 0x00000000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcount = count / 2;\t\t/* number bytes -> number halfwords */\n\n\t/* check code alignment */\n\tif (offset & 0x1) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* allocate working area and variables with flash programming code */\n\tif (target_alloc_working_area(target, sizeof(fm3_flash_write_code) + 8,\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address + 8,\n\t\tsizeof(fm3_flash_write_code), fm3_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Patching 'local variable address' */\n\t/* Algorithm: u32_dummy_read: */\n\tretval = target_write_u32(target, (write_algorithm->address + 8)\n\t\t\t+ sizeof(fm3_flash_write_code) - 8, (write_algorithm->address));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* Algorithm: u32FlashResult: */\n\tretval = target_write_u32(target, (write_algorithm->address + 8)\n\t\t\t+ sizeof(fm3_flash_write_code) - 4, (write_algorithm->address) + 4);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* free working area, write algorithm already allocated */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"No large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /* source start address */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /* target start address */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT); /* number of halfwords to program */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT); /* Flash Sequence address 1 */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT); /* Flash Sequence address 1 */\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_IN);  /* result */\n\n\t/* write code buffer and use Flash programming code within fm3           */\n\t/* Set breakpoint to 0 with time-out of 1000 ms                          */\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count * 2, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, u32_flash_seq_address1);\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, u32_flash_seq_address2);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 6, reg_params,\n\t\t\t\t(write_algorithm->address + 8), 0, 1000, &armv7m_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing fm3 Flash programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (buf_get_u32(reg_params[5].value, 0, 32) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Fujitsu MB9[A/B]FXXX: Flash programming ERROR (Timeout) -> Reg R3: %\" PRIx32,\n\t\t\t\tbuf_get_u32(reg_params[5].value, 0, 32));\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer  += thisrun_count * 2;\n\t\taddress += thisrun_count * 2;\n\t\tcount   -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\n\treturn retval;\n}\n\nstatic int fm3_probe(struct flash_bank *bank)\n{\n\tstruct fm3_flash_bank *fm3_info = bank->driver_priv;\n\tuint16_t num_pages;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n/*\n -- page-- start -- blocksize - mpu - totalFlash --\n\tpage0 0x00000\t16k\n\tpage1 0x04000\t16k\n\tpage2 0x08000\t96k\t\t___ fxx3  128k Flash\n\tpage3 0x20000  128k\t\t___ fxx4  256k Flash\n\tpage4 0x40000  128k\t\t___ fxx5  384k Flash\n\tpage5 0x60000  128k\t\t___ fxx6  512k Flash\n-----------------------\n\tpage6 0x80000  128k\n\tpage7 0xa0000  128k\t\t___ fxx7  256k Flash\n\tpage8 0xc0000  128k\n\tpage9 0xe0000  128k\t\t___ fxx8  256k Flash\n */\n\n\tnum_pages = 10;\t\t\t\t/* max number of Flash pages for malloc */\n\tfm3_info->probed = false;\n\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_pages);\n\tbank->base = 0x00000000;\n\tbank->size = 32 * 1024;\t\t/* bytes */\n\n\tbank->sectors[0].offset = 0;\n\tbank->sectors[0].size = 16 * 1024;\n\tbank->sectors[0].is_erased = -1;\n\tbank->sectors[0].is_protected = -1;\n\n\tbank->sectors[1].offset = 0x4000;\n\tbank->sectors[1].size = 16 * 1024;\n\tbank->sectors[1].is_erased = -1;\n\tbank->sectors[1].is_protected = -1;\n\n\tif ((fm3_info->variant == MB9BFXX1)\n\t    || (fm3_info->variant == MB9AFXX1)) {\n\t\tnum_pages = 3;\n\t\tbank->size = 64 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[2].offset = 0x8000;\n\t\tbank->sectors[2].size = 32 * 1024;\n\t\tbank->sectors[2].is_erased = -1;\n\t\tbank->sectors[2].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX2)\n\t\t|| (fm3_info->variant == MB9BFXX4)\n\t\t|| (fm3_info->variant == MB9BFXX5)\n\t\t|| (fm3_info->variant == MB9BFXX6)\n\t\t|| (fm3_info->variant == MB9BFXX7)\n\t\t|| (fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX2)\n\t\t|| (fm3_info->variant == MB9AFXX4)\n\t\t|| (fm3_info->variant == MB9AFXX5)\n\t\t|| (fm3_info->variant == MB9AFXX6)\n\t\t|| (fm3_info->variant == MB9AFXX7)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 3;\n\t\tbank->size = 128 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[2].offset = 0x8000;\n\t\tbank->sectors[2].size = 96 * 1024;\n\t\tbank->sectors[2].is_erased = -1;\n\t\tbank->sectors[2].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX4)\n\t\t|| (fm3_info->variant == MB9BFXX5)\n\t\t|| (fm3_info->variant == MB9BFXX6)\n\t\t|| (fm3_info->variant == MB9BFXX7)\n\t\t|| (fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX4)\n\t\t|| (fm3_info->variant == MB9AFXX5)\n\t\t|| (fm3_info->variant == MB9AFXX6)\n\t\t|| (fm3_info->variant == MB9AFXX7)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 4;\n\t\tbank->size = 256 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[3].offset = 0x20000;\n\t\tbank->sectors[3].size = 128 * 1024;\n\t\tbank->sectors[3].is_erased = -1;\n\t\tbank->sectors[3].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX5)\n\t\t|| (fm3_info->variant == MB9BFXX6)\n\t\t|| (fm3_info->variant == MB9BFXX7)\n\t\t|| (fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX5)\n\t\t|| (fm3_info->variant == MB9AFXX6)\n\t\t|| (fm3_info->variant == MB9AFXX7)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 5;\n\t\tbank->size = 384 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[4].offset = 0x40000;\n\t\tbank->sectors[4].size = 128 * 1024;\n\t\tbank->sectors[4].is_erased = -1;\n\t\tbank->sectors[4].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX6)\n\t\t|| (fm3_info->variant == MB9BFXX7)\n\t\t|| (fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX6)\n\t\t|| (fm3_info->variant == MB9AFXX7)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 6;\n\t\tbank->size = 512 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[5].offset = 0x60000;\n\t\tbank->sectors[5].size = 128 * 1024;\n\t\tbank->sectors[5].is_erased = -1;\n\t\tbank->sectors[5].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX7)\n\t\t|| (fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX7)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 8;\n\t\tbank->size = 768 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[6].offset = 0x80000;\n\t\tbank->sectors[6].size = 128 * 1024;\n\t\tbank->sectors[6].is_erased = -1;\n\t\tbank->sectors[6].is_protected = -1;\n\n\t\tbank->sectors[7].offset = 0xa0000;\n\t\tbank->sectors[7].size = 128 * 1024;\n\t\tbank->sectors[7].is_erased = -1;\n\t\tbank->sectors[7].is_protected = -1;\n\t}\n\n\tif ((fm3_info->variant == MB9BFXX8)\n\t\t|| (fm3_info->variant == MB9AFXX8)) {\n\t\tnum_pages = 10;\n\t\tbank->size = 1024 * 1024; /* bytes */\n\t\tbank->num_sectors = num_pages;\n\n\t\tbank->sectors[8].offset = 0xc0000;\n\t\tbank->sectors[8].size = 128 * 1024;\n\t\tbank->sectors[8].is_erased = -1;\n\t\tbank->sectors[8].is_protected = -1;\n\n\t\tbank->sectors[9].offset = 0xe0000;\n\t\tbank->sectors[9].size = 128 * 1024;\n\t\tbank->sectors[9].is_erased = -1;\n\t\tbank->sectors[9].is_protected = -1;\n\t}\n\n\tfm3_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int fm3_auto_probe(struct flash_bank *bank)\n{\n\tstruct fm3_flash_bank *fm3_info = bank->driver_priv;\n\tif (fm3_info->probed)\n\t\treturn ERROR_OK;\n\treturn fm3_probe(bank);\n}\n\n/* Chip erase */\nstatic int fm3_chip_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct fm3_flash_bank *fm3_info2 = bank->driver_priv;\n\tint retval = ERROR_OK;\n\tuint32_t u32_dummy_read;\n\tuint32_t u32_flash_type;\n\tuint32_t u32_flash_seq_address1;\n\tuint32_t u32_flash_seq_address2;\n\n\tstruct working_area *write_algorithm;\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_info;\n\n\tu32_flash_type = (uint32_t) fm3_info2->flashtype;\n\n\tif (u32_flash_type == FM3_FLASH_TYPE1) {\n\t\tLOG_INFO(\"*** Erasing mb9bfxxx type\");\n\t\tu32_flash_seq_address1 = 0x00001550;\n\t\tu32_flash_seq_address2 = 0x00000AA8;\n\t} else if (u32_flash_type == FM3_FLASH_TYPE2) {\n\t\tLOG_INFO(\"*** Erasing mb9afxxx type\");\n\t\tu32_flash_seq_address1 = 0x00000AA8;\n\t\tu32_flash_seq_address2 = 0x00000554;\n\t} else {\n\t\tLOG_ERROR(\"Flash/Device type unknown!\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* RAMCODE used for fm3 Flash chip erase:\t\t\t\t   */\n\t/* R0 keeps Flash Sequence address 1     (u32FlashSeq1)    */\n\t/* R1 keeps Flash Sequence address 2     (u32FlashSeq2)    */\n\tstatic const uint8_t fm3_flash_erase_chip_code[] = {\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0xAA; */\n\t\t0xAA, 0x22,\t\t/*        MOVS  R2, #0xAA              */\n\t\t0x02, 0x80,\t\t/*        STRH  R2, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq2 = 0x55; */\n\t\t0x55, 0x23,\t\t/*        MOVS  R3, #0x55              */\n\t\t0x0B, 0x80,\t\t/*        STRH  R3, [R1, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0x80; */\n\t\t0x80, 0x24,\t\t/*        MOVS  R4, #0x80              */\n\t\t0x04, 0x80,\t\t/*        STRH  R4, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0xAA; */\n\t\t0x02, 0x80,\t\t/*        STRH  R2, [R0, #0]           */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq2 = 0x55; */\n\t\t0x0B, 0x80,\t\t/*        STRH  R3, [R1, #0]           */\n\t\t\t\t\t\t/* Chip_Erase Command 0x10             */\n\t\t\t\t\t\t/*    *(uint16_t*)u32FlashSeq1 = 0x10; */\n\t\t0x10, 0x21,\t\t/*        MOVS  R1, #0x10              */\n\t\t0x01, 0x80,\t\t/*        STRH  R1, [R0, #0]           */\n\t\t\t\t\t\t/* End Code                            */\n\t\t0x00, 0xBE,\t\t/*        BKPT  #0                      */\n\t};\n\n\tLOG_INFO(\"Fujitsu MB9[A/B]xxx: Chip Erase ... (may take several seconds)\");\n\n\t/* disable HW watchdog */\n\tretval = target_write_u32(target, 0x40011C00, 0x1ACCE551);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011C00, 0xE5331AAE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, 0x40011008, 0x00000000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* FASZR = 0x01, Enables CPU Programming Mode (16-bit Flash access) */\n\tretval = target_write_u32(target, 0x40000000, 0x0001);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* dummy read of FASZR */\n\tretval = target_read_u32(target, 0x40000000, &u32_dummy_read);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* allocate working area with flash chip erase code */\n\tif (target_alloc_working_area(target, sizeof(fm3_flash_erase_chip_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\tsizeof(fm3_flash_erase_chip_code), fm3_flash_erase_chip_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /* u32_flash_seq_address1 */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /* u32_flash_seq_address2 */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, u32_flash_seq_address1);\n\tbuf_set_u32(reg_params[1].value, 0, 32, u32_flash_seq_address2);\n\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params,\n\t\t\twrite_algorithm->address, 0, 100000, &armv7m_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error executing flash erase programming algorithm\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\treturn retval;\n\t}\n\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\tretval = fm3_busy_wait(target, u32_flash_seq_address2, 20000);\t/* 20s timeout */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* FASZR = 0x02, Re-enables CPU Run Mode (32-bit Flash access) */\n\tretval = target_write_u32(target, 0x40000000, 0x0002);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, 0x40000000, &u32_dummy_read); /* dummy read of FASZR */\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(fm3_handle_chip_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (fm3_chip_erase(bank) == ERROR_OK) {\n\t\tcommand_print(CMD, \"fm3 chip erase complete\");\n\t} else {\n\t\tcommand_print(CMD, \"fm3 chip erase failed\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration fm3_exec_command_handlers[] = {\n\t{\n\t\t.name = \"chip_erase\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = fm3_handle_chip_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase entire Flash device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration fm3_command_handlers[] = {\n\t{\n\t\t.name = \"fm3\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"fm3 Flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = fm3_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver fm3_flash = {\n\t.name = \"fm3\",\n\t.commands = fm3_command_handlers,\n\t.flash_bank_command = fm3_flash_bank_command,\n\t.erase = fm3_erase,\n\t.write = fm3_write_block,\n\t.probe = fm3_probe,\n\t.auto_probe = fm3_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/fm4.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Spansion FM4 flash\n *\n * Copyright (c) 2015 Andreas Färber\n *\n * Based on S6E2DH_MN709-00013 for S6E2DH/DF/D5/D3 series\n * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series\n * Based on MB9B560R_MN709-00005 for MB9BFx66/x67/x68 series\n * Based on MB9B560L_MN709-00006 for MB9BFx64/x65/x66 series\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define FLASH_BASE 0x40000000\n#define FASZR   (FLASH_BASE + 0x000)\n#define DFCTRLR (FLASH_BASE + 0x030)\n#define DFCTRLR_DFE (1UL << 0)\n\n#define WDG_BASE 0x40011000\n#define WDG_CTL (WDG_BASE + 0x008)\n#define WDG_LCK (WDG_BASE + 0xC00)\n\nenum fm4_variant {\n\tMB9BFX64,\n\tMB9BFX65,\n\tMB9BFX66,\n\tMB9BFX67,\n\tMB9BFX68,\n\n\tS6E2CX8,\n\tS6E2CX9,\n\tS6E2CXA,\n\n\tS6E2DX,\n};\n\nstruct fm4_flash_bank {\n\tenum fm4_variant variant;\n\tint macro_nr;\n\tbool probed;\n};\n\nstatic int fm4_disable_hw_watchdog(struct target *target)\n{\n\tint retval;\n\n\tretval = target_write_u32(target, WDG_LCK, 0x1ACCE551);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, WDG_LCK, 0xE5331AAE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, WDG_CTL, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int fm4_enter_flash_cpu_programming_mode(struct target *target)\n{\n\tuint32_t u32_value;\n\tint retval;\n\n\t/* FASZR ASZ = CPU programming mode */\n\tretval = target_write_u32(target, FASZR, 0x00000001);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_read_u32(target, FASZR, &u32_value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int fm4_enter_flash_cpu_rom_mode(struct target *target)\n{\n\tuint32_t u32_value;\n\tint retval;\n\n\t/* FASZR ASZ = CPU ROM mode */\n\tretval = target_write_u32(target, FASZR, 0x00000002);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_read_u32(target, FASZR, &u32_value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int fm4_flash_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct working_area *workarea;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_algo;\n\tunsigned i;\n\tint retval;\n\tconst uint8_t erase_sector_code[] = {\n#include \"../../../contrib/loaders/flash/fm4/erase.inc\"\n\t};\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"Spansion FM4 erase sectors %u to %u\", first, last);\n\n\tretval = fm4_disable_hw_watchdog(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = fm4_enter_flash_cpu_programming_mode(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_alloc_working_area(target, sizeof(erase_sector_code),\n\t\t\t&workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_code;\n\t}\n\tretval = target_write_buffer(target, workarea->address,\n\t\t\tsizeof(erase_sector_code), erase_sector_code);\n\tif (retval != ERROR_OK)\n\t\tgoto err_write_code;\n\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_IN);\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tuint32_t addr = bank->base + bank->sectors[sector].offset;\n\t\tuint32_t result;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, (addr & ~0xffff) | 0xAA8);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, (addr & ~0xffff) | 0x554);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, addr);\n\n\t\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\tworkarea->address, 0,\n\t\t\t\t1000, &armv7m_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing flash sector erase \"\n\t\t\t\t\"programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run;\n\t\t}\n\n\t\tresult = buf_get_u32(reg_params[3].value, 0, 32);\n\t\tif (result == 2) {\n\t\t\tLOG_ERROR(\"Timeout error from flash sector erase programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run_ret;\n\t\t} else if (result != 0) {\n\t\t\tLOG_ERROR(\"Unexpected error %\" PRIu32 \" from flash sector erase programming algorithm\", result);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run_ret;\n\t\t} else\n\t\t\tretval = ERROR_OK;\n\t}\n\nerr_run_ret:\nerr_run:\n\tfor (i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nerr_write_code:\n\ttarget_free_working_area(target, workarea);\n\nerr_alloc_code:\n\tif (retval != ERROR_OK)\n\t\tfm4_enter_flash_cpu_rom_mode(target);\n\telse\n\t\tretval = fm4_enter_flash_cpu_rom_mode(target);\n\n\treturn retval;\n}\n\nstatic int fm4_flash_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t byte_count)\n{\n\tstruct target *target = bank->target;\n\tstruct working_area *code_workarea, *data_workarea;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_algo;\n\tuint32_t halfword_count = DIV_ROUND_UP(byte_count, 2);\n\tuint32_t result;\n\tunsigned i;\n\tint retval, retval2 = ERROR_OK;\n\tconst uint8_t write_block_code[] = {\n#include \"../../../contrib/loaders/flash/fm4/write.inc\"\n\t};\n\n\tLOG_DEBUG(\"Spansion FM4 write at 0x%08\" PRIx32 \" (%\" PRIu32 \" bytes)\",\n\t\toffset, byte_count);\n\n\tif (offset & 0x1) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\",\n\t\t\toffset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\tif (byte_count & 0x1) {\n\t\tLOG_WARNING(\"length %\" PRIu32 \" is not 2-byte aligned, rounding up\",\n\t\t\tbyte_count);\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = fm4_disable_hw_watchdog(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_alloc_working_area(target, sizeof(write_block_code),\n\t\t\t&code_workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available for write code.\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tretval = target_write_buffer(target, code_workarea->address,\n\t\t\tsizeof(write_block_code), write_block_code);\n\tif (retval != ERROR_OK)\n\t\tgoto err_write_code;\n\n\tretval = target_alloc_working_area(target,\n\t\tMIN(halfword_count * 2, target_get_working_area_avail(target)),\n\t\t&data_workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available for write data.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_data;\n\t}\n\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_IN);\n\n\tretval = fm4_enter_flash_cpu_programming_mode(target);\n\tif (retval != ERROR_OK)\n\t\tgoto err_flash_mode;\n\n\twhile (byte_count > 0) {\n\t\tuint32_t halfwords = MIN(halfword_count, data_workarea->size / 2);\n\t\tuint32_t addr = bank->base + offset;\n\n\t\tLOG_DEBUG(\"copying %\" PRIu32 \" bytes to SRAM \" TARGET_ADDR_FMT,\n\t\t\tMIN(halfwords * 2, byte_count), data_workarea->address);\n\n\t\tretval = target_write_buffer(target, data_workarea->address,\n\t\t\tMIN(halfwords * 2, byte_count), buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error writing data buffer\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_write_data;\n\t\t}\n\n\t\tLOG_DEBUG(\"writing 0x%08\" PRIx32 \"-0x%08\" PRIx32 \" (%\" PRIu32 \"x)\",\n\t\t\taddr, addr + halfwords * 2 - 1, halfwords);\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, (addr & ~0xffff) | 0xAA8);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, (addr & ~0xffff) | 0x554);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, addr);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, data_workarea->address);\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, halfwords);\n\n\t\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\tcode_workarea->address, 0,\n\t\t\t\t5 * 60 * 1000, &armv7m_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing flash sector erase \"\n\t\t\t\t\"programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run;\n\t\t}\n\n\t\tresult = buf_get_u32(reg_params[5].value, 0, 32);\n\t\tif (result == 2) {\n\t\t\tLOG_ERROR(\"Timeout error from flash write \"\n\t\t\t\t\"programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run_ret;\n\t\t} else if (result != 0) {\n\t\t\tLOG_ERROR(\"Unexpected error %\" PRIu32 \" from flash write \"\n\t\t\t\t\"programming algorithm\", result);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run_ret;\n\t\t} else\n\t\t\tretval = ERROR_OK;\n\n\t\thalfword_count -= halfwords;\n\t\toffset += halfwords * 2;\n\t\tbuffer += halfwords * 2;\n\t\tbyte_count -= MIN(halfwords * 2, byte_count);\n\t}\n\nerr_run_ret:\nerr_run:\nerr_write_data:\n\tretval2 = fm4_enter_flash_cpu_rom_mode(target);\n\nerr_flash_mode:\n\tfor (i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\n\ttarget_free_working_area(target, data_workarea);\nerr_alloc_data:\nerr_write_code:\n\ttarget_free_working_area(target, code_workarea);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn retval2;\n}\n\nstatic int mb9bf_probe(struct flash_bank *bank)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\tuint32_t flash_addr = bank->base;\n\n\tswitch (fm4_bank->variant) {\n\tcase MB9BFX64:\n\t\tbank->num_sectors = 8;\n\t\tbreak;\n\tcase MB9BFX65:\n\t\tbank->num_sectors = 10;\n\t\tbreak;\n\tcase MB9BFX66:\n\t\tbank->num_sectors = 12;\n\t\tbreak;\n\tcase MB9BFX67:\n\t\tbank->num_sectors = 16;\n\t\tbreak;\n\tcase MB9BFX68:\n\t\tbank->num_sectors = 20;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tLOG_DEBUG(\"%u sectors\", bank->num_sectors);\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t\tsizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (i < 4)\n\t\t\tbank->sectors[i].size = 8 * 1024;\n\t\telse if (i == 4)\n\t\t\tbank->sectors[i].size = 32 * 1024;\n\t\telse\n\t\t\tbank->sectors[i].size = 64 * 1024;\n\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\n\t\tbank->size += bank->sectors[i].size;\n\t\tflash_addr += bank->sectors[i].size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void s6e2cc_init_sector(struct flash_sector *sector, int sa)\n{\n\tif (sa < 8)\n\t\tsector->size = 8 * 1024;\n\telse if (sa == 8)\n\t\tsector->size = 32 * 1024;\n\telse\n\t\tsector->size = 64 * 1024;\n\n\tsector->is_erased = -1;\n\tsector->is_protected = -1;\n}\n\nstatic int s6e2cc_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\tuint32_t u32_value;\n\tuint32_t flash_addr = bank->base;\n\tint retval;\n\tunsigned int i, num_extra_sectors, num_sectors;\n\n\tretval = target_read_u32(target, DFCTRLR, &u32_value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (u32_value & DFCTRLR_DFE) {\n\t\tLOG_WARNING(\"Dual Flash mode is not implemented.\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tswitch (fm4_bank->variant) {\n\tcase S6E2CX8:\n\t\tnum_sectors = (fm4_bank->macro_nr == 0) ? 20 : 0;\n\t\tbreak;\n\tcase S6E2CX9:\n\t\tnum_sectors = (fm4_bank->macro_nr == 0) ? 20 : 12;\n\t\tbreak;\n\tcase S6E2CXA:\n\t\tnum_sectors = 20;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\tnum_extra_sectors = (fm4_bank->macro_nr == 0) ? 1 : 4;\n\tbank->num_sectors = num_sectors + num_extra_sectors;\n\n\tLOG_DEBUG(\"%u sectors\", bank->num_sectors);\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t\tsizeof(struct flash_sector));\n\tfor (i = 0; i < num_sectors; i++) {\n\t\tint sa = 4 + i;\n\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\ts6e2cc_init_sector(&bank->sectors[i], sa);\n\n\t\tbank->size += bank->sectors[i].size;\n\t\tflash_addr += bank->sectors[i].size;\n\t}\n\n\tflash_addr = (fm4_bank->macro_nr == 0) ? 0x00406000 : 0x00408000;\n\tfor (; i < bank->num_sectors; i++) {\n\t\tint sa = 4 - num_extra_sectors + (i - num_sectors);\n\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\ts6e2cc_init_sector(&bank->sectors[i], sa);\n\n\t\t/*\n\t\t * Don't increase bank->size for these sectors\n\t\t * to avoid an overlap between Flash Macros #0 and #1.\n\t\t */\n\t\tflash_addr += bank->sectors[i].size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int s6e2dh_probe(struct flash_bank *bank)\n{\n\tuint32_t flash_addr = bank->base;\n\n\tbank->num_sectors = 10;\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t\tsizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (i < 4)\n\t\t\tbank->sectors[i].size = 8 * 1024;\n\t\telse if (i == 4)\n\t\t\tbank->sectors[i].size = 32 * 1024;\n\t\telse\n\t\t\tbank->sectors[i].size = 64 * 1024;\n\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\n\t\tbank->size += bank->sectors[i].size;\n\t\tflash_addr += bank->sectors[i].size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int fm4_probe(struct flash_bank *bank)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\tint retval;\n\n\tif (fm4_bank->probed)\n\t\treturn ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (fm4_bank->variant) {\n\tcase MB9BFX64:\n\tcase MB9BFX65:\n\tcase MB9BFX66:\n\tcase MB9BFX67:\n\tcase MB9BFX68:\n\t\tretval = mb9bf_probe(bank);\n\t\tbreak;\n\tcase S6E2CX8:\n\tcase S6E2CX9:\n\tcase S6E2CXA:\n\t\tretval = s6e2cc_probe(bank);\n\t\tbreak;\n\tcase S6E2DX:\n\t\tretval = s6e2dh_probe(bank);\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfm4_bank->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int fm4_auto_probe(struct flash_bank *bank)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\n\tif (fm4_bank->probed)\n\t\treturn ERROR_OK;\n\n\treturn fm4_probe(bank);\n}\n\nstatic int fm4_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\tconst char *name;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (fm4_bank->variant) {\n\tcase MB9BFX64:\n\t\tname = \"MB9BFx64\";\n\t\tbreak;\n\tcase MB9BFX65:\n\t\tname = \"MB9BFx65\";\n\t\tbreak;\n\tcase MB9BFX66:\n\t\tname = \"MB9BFx66\";\n\t\tbreak;\n\tcase MB9BFX67:\n\t\tname = \"MB9BFx67\";\n\t\tbreak;\n\tcase MB9BFX68:\n\t\tname = \"MB9BFx68\";\n\t\tbreak;\n\tcase S6E2CX8:\n\t\tname = \"S6E2Cx8\";\n\t\tbreak;\n\tcase S6E2CX9:\n\t\tname = \"S6E2Cx9\";\n\t\tbreak;\n\tcase S6E2CXA:\n\t\tname = \"S6E2CxA\";\n\t\tbreak;\n\tcase S6E2DX:\n\t\tname = \"S6E2Dx\";\n\t\tbreak;\n\tdefault:\n\t\tname = \"unknown\";\n\t\tbreak;\n\t}\n\n\tswitch (fm4_bank->variant) {\n\tcase S6E2CX8:\n\tcase S6E2CX9:\n\tcase S6E2CXA:\n\t\tcommand_print_sameline(cmd, \"%s MainFlash Macro #%i\", name, fm4_bank->macro_nr);\n\t\tbreak;\n\tdefault:\n\t\tcommand_print_sameline(cmd, \"%s MainFlash\", name);\n\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool fm4_name_match(const char *s, const char *pattern)\n{\n\tint i = 0;\n\n\twhile (s[i]) {\n\t\t/* If the match string is shorter, ignore excess */\n\t\tif (!pattern[i])\n\t\t\treturn true;\n\t\t/* Use x as wildcard */\n\t\tif (pattern[i] != 'x' && tolower(s[i]) != tolower(pattern[i]))\n\t\t\treturn false;\n\t\ti++;\n\t}\n\treturn true;\n}\n\nstatic int mb9bf_bank_setup(struct flash_bank *bank, const char *variant)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\n\tif (fm4_name_match(variant, \"MB9BFx64\")) {\n\t\tfm4_bank->variant = MB9BFX64;\n\t} else if (fm4_name_match(variant, \"MB9BFx65\")) {\n\t\tfm4_bank->variant = MB9BFX65;\n\t} else if (fm4_name_match(variant, \"MB9BFx66\")) {\n\t\tfm4_bank->variant = MB9BFX66;\n\t} else if (fm4_name_match(variant, \"MB9BFx67\")) {\n\t\tfm4_bank->variant = MB9BFX67;\n\t} else if (fm4_name_match(variant, \"MB9BFx68\")) {\n\t\tfm4_bank->variant = MB9BFX68;\n\t} else {\n\t\tLOG_WARNING(\"MB9BF variant %s not recognized.\", variant);\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int s6e2cc_bank_setup(struct flash_bank *bank, const char *variant)\n{\n\tstruct fm4_flash_bank *fm4_bank = bank->driver_priv;\n\n\tif (fm4_name_match(variant, \"S6E2Cx8\")) {\n\t\tfm4_bank->variant = S6E2CX8;\n\t} else if (fm4_name_match(variant, \"S6E2Cx9\")) {\n\t\tfm4_bank->variant = S6E2CX9;\n\t} else if (fm4_name_match(variant, \"S6E2CxA\")) {\n\t\tfm4_bank->variant = S6E2CXA;\n\t} else {\n\t\tLOG_WARNING(\"S6E2CC variant %s not recognized.\", variant);\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(fm4_flash_bank_command)\n{\n\tstruct fm4_flash_bank *fm4_bank;\n\tconst char *variant;\n\tint ret;\n\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tvariant = CMD_ARGV[6];\n\n\tfm4_bank = malloc(sizeof(struct fm4_flash_bank));\n\tif (!fm4_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tfm4_bank->probed = false;\n\tfm4_bank->macro_nr = (bank->base == 0x00000000) ? 0 : 1;\n\n\tbank->driver_priv = fm4_bank;\n\n\tif (fm4_name_match(variant, \"MB9BF\"))\n\t\tret = mb9bf_bank_setup(bank, variant);\n\telse if (fm4_name_match(variant, \"S6E2Cx\"))\n\t\tret = s6e2cc_bank_setup(bank, variant);\n\telse if (fm4_name_match(variant, \"S6E2Dx\")) {\n\t\tfm4_bank->variant = S6E2DX;\n\t\tret = ERROR_OK;\n\t} else {\n\t\tLOG_WARNING(\"Family %s not recognized.\", variant);\n\t\tret = ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\tif (ret != ERROR_OK)\n\t\tfree(fm4_bank);\n\treturn ret;\n}\n\nconst struct flash_driver fm4_flash = {\n\t.name = \"fm4\",\n\t.flash_bank_command = fm4_flash_bank_command,\n\t.info = fm4_get_info_command,\n\t.probe = fm4_probe,\n\t.auto_probe = fm4_auto_probe,\n\t.read = default_flash_read,\n\t.erase = fm4_flash_erase,\n\t.erase_check = default_flash_blank_check,\n\t.write = fm4_flash_write,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/imp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_IMP_H\n#define OPENOCD_FLASH_NOR_IMP_H\n\n#include <stdbool.h>\n\n/* this is an internal header */\n#include \"core.h\"\n#include \"driver.h\"\n/* almost all drivers will need this file */\n#include <target/target.h>\n\n/**\n * Adds a new NOR bank to the global list of banks.\n * @param bank The bank that should be added.\n */\nvoid flash_bank_add(struct flash_bank *bank);\n\n/**\n * @return The first bank in the global list.\n */\nstruct flash_bank *flash_bank_list(void);\n\nint flash_driver_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last);\nint flash_driver_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last);\nint flash_driver_write(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count);\nint flash_driver_read(struct flash_bank *bank,\n\t\tuint8_t *buffer, uint32_t offset, uint32_t count);\nint flash_driver_verify(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count);\n\n/* write (optional verify) an image to flash memory of the given target */\nint flash_write_unlock_verify(struct target *target, struct image *image,\n\t\tuint32_t *written, bool erase, bool unlock, bool write, bool verify);\n\n#endif /* OPENOCD_FLASH_NOR_IMP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/jtagspi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 Robert Jordens <jordens@gmail.com>                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <jtag/jtag.h>\n#include <flash/nor/spi.h>\n#include <helper/time_support.h>\n\n#define JTAGSPI_MAX_TIMEOUT 3000\n\n\nstruct jtagspi_flash_bank {\n\tstruct jtag_tap *tap;\n\tstruct flash_device dev;\n\tchar devname[32];\n\tbool probed;\n\tbool always_4byte;\t\t\t/* use always 4-byte address except for basic read 0x03 */\n\tuint32_t ir;\n\tunsigned int addr_len;\t\t/* address length in bytes */\n};\n\nFLASH_BANK_COMMAND_HANDLER(jtagspi_flash_bank_command)\n{\n\tstruct jtagspi_flash_bank *info;\n\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tinfo = malloc(sizeof(struct jtagspi_flash_bank));\n\tif (!info) {\n\t\tLOG_ERROR(\"no memory for flash bank info\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbank->sectors = NULL;\n\tbank->driver_priv = info;\n\n\tif (!bank->target->tap) {\n\t\tLOG_ERROR(\"Target has no JTAG tap\");\n\t\treturn ERROR_FAIL;\n\t}\n\tinfo->tap = bank->target->tap;\n\tinfo->probed = false;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], info->ir);\n\n\treturn ERROR_OK;\n}\n\nstatic void jtagspi_set_ir(struct flash_bank *bank)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tstruct scan_field field;\n\tuint8_t buf[4] = { 0 };\n\n\tLOG_DEBUG(\"loading jtagspi ir\");\n\tbuf_set_u32(buf, 0, info->tap->ir_length, info->ir);\n\tfield.num_bits = info->tap->ir_length;\n\tfield.out_value = buf;\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(info->tap, &field, TAP_IDLE);\n}\n\nstatic void flip_u8(const uint8_t *in, uint8_t *out, unsigned int len)\n{\n\tfor (unsigned int i = 0; i < len; i++)\n\t\tout[i] = flip_u32(in[i], 8);\n}\n\nstatic int jtagspi_cmd(struct flash_bank *bank, uint8_t cmd,\n\t\tuint8_t *write_buffer, unsigned int write_len, uint8_t *data_buffer, int data_len)\n{\n\tassert(write_buffer || write_len == 0);\n\tassert(data_buffer || data_len == 0);\n\n\tstruct scan_field fields[6];\n\n\tLOG_DEBUG(\"cmd=0x%02x write_len=%d data_len=%d\", cmd, write_len, data_len);\n\n\t/* negative data_len == read operation */\n\tconst bool is_read = (data_len < 0);\n\tif (is_read)\n\t\tdata_len = -data_len;\n\n\tint n = 0;\n\tconst uint8_t marker = 1;\n\tfields[n].num_bits = 1;\n\tfields[n].out_value = &marker;\n\tfields[n].in_value = NULL;\n\tn++;\n\n\t/* transfer length = cmd + address + read/write,\n\t * -1 due to the counter implementation */\n\tuint8_t xfer_bits[4];\n\th_u32_to_be(xfer_bits, ((sizeof(cmd) + write_len + data_len) * CHAR_BIT) - 1);\n\tflip_u8(xfer_bits, xfer_bits, sizeof(xfer_bits));\n\tfields[n].num_bits = sizeof(xfer_bits) * CHAR_BIT;\n\tfields[n].out_value = xfer_bits;\n\tfields[n].in_value = NULL;\n\tn++;\n\n\tflip_u8(&cmd, &cmd, sizeof(cmd));\n\tfields[n].num_bits = sizeof(cmd) * CHAR_BIT;\n\tfields[n].out_value = &cmd;\n\tfields[n].in_value = NULL;\n\tn++;\n\n\tif (write_len) {\n\t\tflip_u8(write_buffer, write_buffer, write_len);\n\t\tfields[n].num_bits = write_len * CHAR_BIT;\n\t\tfields[n].out_value = write_buffer;\n\t\tfields[n].in_value = NULL;\n\t\tn++;\n\t}\n\n\tif (data_len > 0) {\n\t\tif (is_read) {\n\t\t\tfields[n].num_bits = jtag_tap_count_enabled();\n\t\t\tfields[n].out_value = NULL;\n\t\t\tfields[n].in_value = NULL;\n\t\t\tn++;\n\n\t\t\tfields[n].out_value = NULL;\n\t\t\tfields[n].in_value = data_buffer;\n\t\t} else {\n\t\t\tflip_u8(data_buffer, data_buffer, data_len);\n\t\t\tfields[n].out_value = data_buffer;\n\t\t\tfields[n].in_value = NULL;\n\t\t}\n\t\tfields[n].num_bits = data_len * CHAR_BIT;\n\t\tn++;\n\t}\n\n\tjtagspi_set_ir(bank);\n\t/* passing from an IR scan to SHIFT-DR clears BYPASS registers */\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tjtag_add_dr_scan(info->tap, n, fields, TAP_IDLE);\n\tint retval = jtag_execute_queue();\n\n\tif (is_read)\n\t\tflip_u8(data_buffer, data_buffer, data_len);\n\treturn retval;\n}\n\nCOMMAND_HANDLER(jtagspi_handle_set)\n{\n\tstruct flash_bank *bank = NULL;\n\tstruct jtagspi_flash_bank *info = NULL;\n\tstruct flash_sector *sectors = NULL;\n\tuint32_t temp;\n\tunsigned int index = 1;\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\t/* there are 6 mandatory arguments:\n\t * devname, size_in_bytes, pagesize, read_cmd, unused, pprog_cmd */\n\tif (index + 6 > CMD_ARGC) {\n\t\tcommand_print(CMD, \"jtagspi: not enough arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* calling flash_command_get_bank without probing because handle_set is used\n\t   to set device parameters if not autodetected. So probing would fail\n\t   anyhow.\n\t*/\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0,\n\t\t&bank, false);\n\tif (ERROR_OK != retval)\n\t\treturn retval;\n\tinfo = bank->driver_priv;\n\n\t/* invalidate all old info */\n\tif (info->probed) {\n\t\tbank->size = 0;\n\t\tbank->num_sectors = 0;\n\t\tif (bank->sectors)\n\t\t\tfree(bank->sectors);\n\t\tbank->sectors = NULL;\n\t\tinfo->always_4byte = false;\n\t\tinfo->probed = false;\n\t}\n\tmemset(&info->dev, 0, sizeof(info->dev));\n\n\tstrncpy(info->devname, CMD_ARGV[index++], sizeof(info->devname) - 1);\n\tinfo->devname[sizeof(info->devname) - 1] = '\\0';\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp);\n\tinfo->dev.size_in_bytes = temp;\n\tif ((temp & (temp - 1)) || (temp < (1UL << 8))) {\n\t\tcommand_print(CMD, \"jtagspi: device size must be 2^n with n >= 8\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp);\n\tinfo->dev.pagesize = temp;\n\tif (info->dev.pagesize == 0)\n\t\tinfo->dev.pagesize = SPIFLASH_DEF_PAGESIZE;\n\tif ((temp & (temp - 1)) || (temp > info->dev.size_in_bytes)) {\n\t\tcommand_print(CMD, \"jtagspi: page size must be 2^n and <= device size\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.read_cmd);\n\tif ((info->dev.read_cmd != 0x03) &&\n\t\t(info->dev.read_cmd != 0x13)) {\n\t\tcommand_print(CMD, \"jtagspi: only 0x03/0x13 READ allowed\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.qread_cmd);\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.pprog_cmd);\n\tif ((info->dev.pprog_cmd != 0x02) &&\n\t\t(info->dev.pprog_cmd != 0x12)) {\n\t\tcommand_print(CMD, \"jtagspi: only 0x02/0x12 PPRG allowed\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* remaining params are optional */\n\tif (index < CMD_ARGC)\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.chip_erase_cmd);\n\telse\n\t\tinfo->dev.chip_erase_cmd = 0x00;\n\n\tif (index < CMD_ARGC) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], temp);\n\t\tinfo->dev.sectorsize = temp;\n\t\tif ((info->dev.sectorsize > info->dev.size_in_bytes) ||\n\t\t\t(info->dev.sectorsize < info->dev.pagesize) || (temp & (temp - 1))) {\n\t\t\tcommand_print(CMD, \"jtagspi: sector size must be 2^n and <= device size\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (index < CMD_ARGC)\n\t\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], info->dev.erase_cmd);\n\t\telse {\n\t\t\tcommand_print(CMD, \"jtagspi: erase command missing\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t} else {\n\t\t/* no sector size / sector erase cmd given, treat whole bank as a single sector */\n\t\tinfo->dev.erase_cmd = 0x00;\n\t\tinfo->dev.sectorsize = info->dev.size_in_bytes;\n\t}\n\n\tif (index < CMD_ARGC) {\n\t\tcommand_print(CMD, \"jtagspi: extra arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* set correct size value */\n\tbank->size = info->dev.size_in_bytes;\n\n\t/* calculate address length in bytes */\n\tif (bank->size <= (1UL << 8))\n\t\tinfo->addr_len = 1;\n\telse if (bank->size <= (1UL << 16))\n\t\tinfo->addr_len = 2;\n\telse if (bank->size <= (1UL << 24))\n\t\tinfo->addr_len = 3;\n\telse {\n\t\tinfo->addr_len = 4;\n\t\tLOG_WARNING(\"4-byte addresses needed, might need extra command to enable\");\n\t}\n\n\t/* create and fill sectors array */\n\tbank->num_sectors =\n\t\tinfo->dev.size_in_bytes / info->dev.sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"Not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * (info->dev.sectorsize);\n\t\tsectors[sector].size = info->dev.sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tinfo->dev.name = info->devname;\n\tif (info->dev.size_in_bytes / 4096)\n\t\tLOG_INFO(\"flash \\'%s\\' id = unknown\\nflash size = %\" PRIu32 \" kbytes\",\n\t\t\tinfo->dev.name, info->dev.size_in_bytes / 1024);\n\telse\n\t\tLOG_INFO(\"flash \\'%s\\' id = unknown\\nflash size = %\" PRIu32 \" bytes\",\n\t\t\tinfo->dev.name, info->dev.size_in_bytes);\n\tinfo->probed = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtagspi_handle_cmd)\n{\n\tstruct flash_bank *bank;\n\tconst unsigned int max = 20;\n\tuint8_t cmd_byte, num_read, write_buffer[max], read_buffer[1 << CHAR_BIT];\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint8_t num_write = CMD_ARGC - 3;\n\tif (num_write > max) {\n\t\tcommand_print(CMD, \"at most %d bytes may be send\", max);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* calling flash_command_get_bank without probing because we like to be\n\t   able to send commands before auto-probing occurred. For example sending\n\t   \"release from power down\" is needed before probing when flash is in\n\t   power down mode.\n\t */\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0,\n\t\t\t\t\t\t\t\t&bank, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], num_read);\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[2], cmd_byte);\n\n\tfor (unsigned int i = 0; i < num_write; i++)\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[i + 3], write_buffer[i]);\n\n\t/* process command */\n\tretval = jtagspi_cmd(bank, cmd_byte, write_buffer, num_write, read_buffer, -num_read);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print_sameline(CMD, \"spi: %02\" PRIx8, cmd_byte);\n\n\tfor (unsigned int i = 0; i < num_write; i++)\n\t\tcommand_print_sameline(CMD, \" %02\" PRIx8, write_buffer[i]);\n\n\tcommand_print_sameline(CMD, \" ->\");\n\n\tfor (unsigned int i = 0; i < num_read; i++)\n\t\tcommand_print_sameline(CMD, \" %02\" PRIx8, read_buffer[i]);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtagspi_handle_always_4byte)\n{\n\tstruct flash_bank *bank;\n\tstruct jtagspi_flash_bank *jtagspi_info;\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif ((CMD_ARGC != 1) && (CMD_ARGC != 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (ERROR_OK != retval)\n\t\treturn retval;\n\n\tjtagspi_info = bank->driver_priv;\n\n\tif (CMD_ARGC == 1)\n\t\tcommand_print(CMD, jtagspi_info->always_4byte ? \"on\" : \"off\");\n\telse\n\t\tCOMMAND_PARSE_BOOL(CMD_ARGV[1], jtagspi_info->always_4byte, \"on\", \"off\");\n\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_probe(struct flash_bank *bank)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tstruct flash_sector *sectors;\n\tconst struct flash_device *p;\n\tuint8_t in_buf[3];\n\tuint32_t id, sectorsize;\n\n\tif (bank->sectors) {\n\t\tfree(bank->sectors);\n\t\tbank->sectors = NULL;\n\t}\n\tinfo->probed = false;\n\n\tjtagspi_cmd(bank, SPIFLASH_READ_ID, NULL, 0, in_buf, -3);\n\t/* the table in spi.c has the manufacturer byte (first) as the lsb */\n\tid = le_to_h_u24(in_buf);\n\n\tmemset(&info->dev, 0, sizeof(info->dev));\n\tfor (p = flash_devices; p->name ; p++)\n\t\tif (p->device_id == id) {\n\t\t\tmemcpy(&info->dev, p, sizeof(info->dev));\n\t\t\tbreak;\n\t\t}\n\n\tif (!(p->name)) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%06\" PRIx32 \")\", id & 0xFFFFFF);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%06\" PRIx32 \")\",\n\t\tinfo->dev.name, info->dev.device_id & 0xFFFFFF);\n\n\t/* Set correct size value */\n\tbank->size = info->dev.size_in_bytes;\n\n\t/* calculate address length in bytes */\n\tif (bank->size <= (1UL << 8))\n\t\tinfo->addr_len = 1;\n\telse if (bank->size <= (1UL << 16))\n\t\tinfo->addr_len = 2;\n\telse if (bank->size <= (1UL << 24))\n\t\tinfo->addr_len = 3;\n\telse {\n\t\tinfo->addr_len = 4;\n\t\tLOG_WARNING(\"4-byte addresses needed, might need extra command to enable\");\n\t}\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = info->dev.sectorsize ?\n\t\tinfo->dev.sectorsize : info->dev.size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = info->dev.size_in_bytes / sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tinfo->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_auto_probe(struct flash_bank *bank)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\n\tif (info->probed)\n\t\treturn ERROR_OK;\n\treturn jtagspi_probe(bank);\n}\n\nstatic int jtagspi_read_status(struct flash_bank *bank, uint32_t *status)\n{\n\tuint8_t buf;\n\tint err = jtagspi_cmd(bank, SPIFLASH_READ_STATUS, NULL, 0, &buf, -1);\n\tif (err == ERROR_OK) {\n\t\t*status = buf;\n\t\tLOG_DEBUG(\"status=0x%02\" PRIx32, *status);\n\t}\n\treturn err;\n}\n\nstatic int jtagspi_wait(struct flash_bank *bank, int timeout_ms)\n{\n\tint64_t t0 = timeval_ms();\n\tint64_t dt;\n\n\tdo {\n\t\tdt = timeval_ms() - t0;\n\n\t\tuint32_t status = (uint32_t)-1;\n\t\tint retval = jtagspi_read_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & SPIFLASH_BSY_BIT) == 0) {\n\t\t\tLOG_DEBUG(\"waited %\" PRId64 \" ms\", dt);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\talive_sleep(1);\n\t} while (dt <= timeout_ms);\n\n\tLOG_ERROR(\"timeout, device still busy\");\n\treturn ERROR_FAIL;\n}\n\nstatic int jtagspi_write_enable(struct flash_bank *bank)\n{\n\tjtagspi_cmd(bank, SPIFLASH_WRITE_ENABLE, NULL, 0, NULL, 0);\n\n\tuint32_t status = (uint32_t)-1;\n\tint retval = jtagspi_read_status(bank, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((status & SPIFLASH_WE_BIT) == 0) {\n\t\tLOG_ERROR(\"Cannot enable write to flash. Status=0x%02\" PRIx32, status);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_bulk_erase(struct flash_bank *bank)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tint retval;\n\tint64_t t0 = timeval_ms();\n\n\tif (info->dev.chip_erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tretval = jtagspi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtagspi_cmd(bank, info->dev.chip_erase_cmd, NULL, 0, NULL, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtagspi_wait(bank, bank->num_sectors * JTAGSPI_MAX_TIMEOUT);\n\tLOG_INFO(\"took %\" PRId64 \" ms\", timeval_ms() - t0);\n\treturn retval;\n}\n\nstatic uint8_t *fill_addr(uint32_t addr, unsigned int addr_len, uint8_t *buffer)\n{\n\tfor (buffer += addr_len; addr_len > 0; --addr_len) {\n\t\t*--buffer = addr;\n\t\taddr >>= 8;\n\t}\n\n\treturn buffer;\n}\n\nstatic int jtagspi_sector_erase(struct flash_bank *bank, unsigned int sector)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tint retval;\n\tuint8_t addr[sizeof(uint32_t)];\n\tint64_t t0 = timeval_ms();\n\n\tretval = jtagspi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */\n\tunsigned int addr_len = info->always_4byte ? 4 : info->addr_len;\n\n\tretval = jtagspi_cmd(bank, info->dev.erase_cmd, fill_addr(bank->sectors[sector].offset, addr_len, addr),\n\t\t\taddr_len, NULL, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT);\n\tLOG_INFO(\"sector %u took %\" PRId64 \" ms\", sector, timeval_ms() - t0);\n\treturn retval;\n}\n\nstatic int jtagspi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"erase from sector %u to sector %u\", first, last);\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!(info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (first == 0 && last == (bank->num_sectors - 1) &&\n\t\tinfo->dev.chip_erase_cmd != 0x00 &&\n\t\tinfo->dev.chip_erase_cmd != info->dev.erase_cmd) {\n\t\tLOG_DEBUG(\"Trying bulk erase.\");\n\t\tretval = jtagspi_bulk_erase(bank);\n\t\tif (retval == ERROR_OK)\n\t\t\treturn retval;\n\t\telse\n\t\t\tLOG_WARNING(\"Bulk flash erase failed. Falling back to sector erase.\");\n\t}\n\n\tif (info->dev.erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = jtagspi_sector_erase(bank, sector);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Sector erase failed.\");\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int jtagspi_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tuint32_t pagesize, currsize;\n\tuint8_t addr[sizeof(uint32_t)];\n\tint retval;\n\n\tif (!(info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed.\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* if no sectorsize, use reasonable default */\n\tpagesize = info->dev.sectorsize ? info->dev.sectorsize : info->dev.pagesize;\n\tif (pagesize == 0)\n\t\tpagesize = (info->dev.size_in_bytes <= SPIFLASH_DEF_PAGESIZE) ?\n\t\t\tinfo->dev.size_in_bytes : SPIFLASH_DEF_PAGESIZE;\n\n\t/* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */\n\tunsigned int addr_len = ((info->dev.read_cmd != 0x03) && info->always_4byte) ? 4 : info->addr_len;\n\n\twhile (count > 0) {\n\t\t/* length up to end of current page */\n\t\tcurrsize = ((offset + pagesize) & ~(pagesize - 1)) - offset;\n\t\t/* but no more than remaining size */\n\t\tcurrsize = (count < currsize) ? count : currsize;\n\n\t\tretval = jtagspi_cmd(bank, info->dev.read_cmd, fill_addr(offset, addr_len, addr),\n\t\t\taddr_len, buffer, -currsize);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"page read error\");\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"read page at 0x%08\" PRIx32, offset);\n\t\toffset += currsize;\n\t\tbuffer += currsize;\n\t\tcount -= currsize;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_page_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tuint8_t addr[sizeof(uint32_t)];\n\tint retval;\n\n\tretval = jtagspi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* ATXP032/064/128 use always 4-byte addresses except for 0x03 read */\n\tunsigned int addr_len = ((info->dev.read_cmd != 0x03) && info->always_4byte) ? 4 : info->addr_len;\n\n\tretval = jtagspi_cmd(bank, info->dev.pprog_cmd, fill_addr(offset, addr_len, addr),\n\t\taddr_len, (uint8_t *) buffer, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn jtagspi_wait(bank, JTAGSPI_MAX_TIMEOUT);\n}\n\nstatic int jtagspi_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\tuint32_t pagesize, currsize;\n\tint retval;\n\n\tif (!(info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed.\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* if no write pagesize, use reasonable default */\n\tpagesize = info->dev.pagesize ? info->dev.pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\twhile (count > 0) {\n\t\t/* length up to end of current page */\n\t\tcurrsize = ((offset + pagesize) & ~(pagesize - 1)) - offset;\n\t\t/* but no more than remaining size */\n\t\tcurrsize = (count < currsize) ? count : currsize;\n\n\t\tretval = jtagspi_page_write(bank, buffer, offset, currsize);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"page write error\");\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"wrote page at 0x%08\" PRIx32, offset);\n\t\toffset += currsize;\n\t\tbuffer += currsize;\n\t\tcount -= currsize;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int jtagspi_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct jtagspi_flash_bank *info = bank->driver_priv;\n\n\tif (!(info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nJTAGSPI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"flash \\'%s\\', device id = 0x%06\" PRIx32\n\t\t\", flash size = %\" PRIu32 \" %sbytes\\n(page size = %\" PRIu32\n\t\t\", read = 0x%02\" PRIx8 \", qread = 0x%02\" PRIx8\n\t\t\", pprog = 0x%02\" PRIx8 \", mass_erase = 0x%02\" PRIx8\n\t\t\", sector size = %\" PRIu32 \" %sbytes, sector_erase = 0x%02\" PRIx8 \")\",\n\t\tinfo->dev.name, info->dev.device_id & 0xFFFFFF,\n\t\tbank->size / 4096 ? bank->size / 1024 : bank->size,\n\t\tbank->size / 4096 ? \"k\" : \"\", info->dev.pagesize,\n\t\tinfo->dev.read_cmd, info->dev.qread_cmd,\n\t\tinfo->dev.pprog_cmd, info->dev.chip_erase_cmd,\n\t\tinfo->dev.sectorsize / 4096 ?\n\t\tinfo->dev.sectorsize / 1024 : info->dev.sectorsize,\n\t\tinfo->dev.sectorsize / 4096 ? \"k\" : \"\",\n\t\tinfo->dev.erase_cmd);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration jtagspi_exec_command_handlers[] = {\n\t{\n\t\t.name = \"set\",\n\t\t.handler = jtagspi_handle_set,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id name chip_size page_size read_cmd unused pprg_cmd \"\n\t\t\t\"[ mass_erase_cmd ] [ sector_size sector_erase_cmd ]\",\n\t\t.help = \"Set device parameters if not autodetected.\",\n\t},\n\t{\n\t\t.name = \"cmd\",\n\t\t.handler = jtagspi_handle_cmd,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id num_resp cmd_byte ...\",\n\t\t.help = \"Send low-level command cmd_byte and following bytes, read num_bytes.\",\n\t},\n\t{\n\t\t.name = \"always_4byte\",\n\t\t.handler = jtagspi_handle_always_4byte,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id [ on | off ]\",\n\t\t.help = \"Use always 4-byte address except for basic 0x03.\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jtagspi_command_handlers[] = {\n\t{\n\t\t.name = \"jtagspi\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"jtagspi command group\",\n\t\t.usage = \"\",\n\t\t.chain = jtagspi_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver jtagspi_flash = {\n\t.name = \"jtagspi\",\n\t.commands = jtagspi_command_handlers,\n\t.flash_bank_command = jtagspi_flash_bank_command,\n\t.erase = jtagspi_erase,\n\t.protect = jtagspi_protect,\n\t.write = jtagspi_write,\n\t.read = jtagspi_read,\n\t.probe = jtagspi_probe,\n\t.auto_probe = jtagspi_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = jtagspi_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/kinetis.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   kesmtp@freenet.de                                                     *\n *                                                                         *\n *   Copyright (C) 2011 sleep(5) ltd                                       *\n *   tomas@sleepfive.com                                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Christopher D. Kilgour                          *\n *   techie at whiterocker.com                                             *\n *                                                                         *\n *   Copyright (C) 2013 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   Copyright (C) 2015 Tomas Vanek                                        *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/target_type.h>\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n/*\n * Implementation Notes\n *\n * The persistent memories in the Kinetis chip families K10 through\n * K70 are all manipulated with the Flash Memory Module.  Some\n * variants call this module the FTFE, others call it the FTFL.  To\n * indicate that both are considered here, we use FTFX.\n *\n * Within the module, according to the chip variant, the persistent\n * memory is divided into what Freescale terms Program Flash, FlexNVM,\n * and FlexRAM.  All chip variants have Program Flash.  Some chip\n * variants also have FlexNVM and FlexRAM, which always appear\n * together.\n *\n * A given Kinetis chip may have 1, 2 or 4 blocks of flash.  Here we map\n * each block to a separate bank.  Each block size varies by chip and\n * may be determined by the read-only SIM_FCFG1 register.  The sector\n * size within each bank/block varies by chip, and may be 1, 2 or 4k.\n * The sector size may be different for flash and FlexNVM.\n *\n * The first half of the flash (1 or 2 blocks) is always Program Flash\n * and always starts at address 0x00000000.  The \"PFLSH\" flag, bit 23\n * of the read-only SIM_FCFG2 register, determines whether the second\n * half of the flash is also Program Flash or FlexNVM+FlexRAM.  When\n * PFLSH is set, the second from the first half.  When PFLSH is clear,\n * the second half of flash is FlexNVM and always starts at address\n * 0x10000000.  FlexRAM, which is also present when PFLSH is clear,\n * always starts at address 0x14000000.\n *\n * The Flash Memory Module provides a register set where flash\n * commands are loaded to perform flash operations like erase and\n * program.  Different commands are available depending on whether\n * Program Flash or FlexNVM/FlexRAM is being manipulated.  Although\n * the commands used are quite consistent between flash blocks, the\n * parameters they accept differ according to the flash sector size.\n *\n */\n\n/* Addresses */\n#define FCF_ADDRESS\t0x00000400\n#define FCF_FPROT\t0x8\n#define FCF_FSEC\t0xc\n#define FCF_FOPT\t0xd\n#define FCF_FDPROT\t0xf\n#define FCF_SIZE\t0x10\n\n#define FLEXRAM\t\t0x14000000\n\n#define MSCM_OCMDR0\t0x40001400\n#define FMC_PFB01CR\t0x4001f004\n#define FTFX_FSTAT\t0x40020000\n#define FTFX_FCNFG\t0x40020001\n#define FTFX_FCCOB3\t0x40020004\n#define FTFX_FPROT3\t0x40020010\n#define FTFX_FDPROT\t0x40020017\n#define SIM_BASE\t0x40047000\n#define SIM_BASE_KL28\t0x40074000\n#define SIM_COPC\t0x40048100\n\t/* SIM_COPC does not exist on devices with changed SIM_BASE */\n#define WDOG_BASE\t0x40052000\n#define WDOG32_KE1X\t0x40052000\n#define WDOG32_KL28\t0x40076000\n#define SMC_PMCTRL\t0x4007E001\n#define SMC_PMSTAT\t0x4007E003\n#define SMC32_PMCTRL\t0x4007E00C\n#define SMC32_PMSTAT\t0x4007E014\n#define PMC_REGSC\t0x4007D002\n#define MC_PMCTRL\t0x4007E003\n#define MCM_PLACR\t0xF000300C\n\n/* Offsets */\n#define SIM_SOPT1_OFFSET    0x0000\n#define SIM_SDID_OFFSET\t    0x1024\n#define SIM_FCFG1_OFFSET    0x104c\n#define SIM_FCFG2_OFFSET    0x1050\n\n#define WDOG_STCTRLH_OFFSET      0\n#define WDOG32_CS_OFFSET         0\n\n/* Values */\n#define PM_STAT_RUN\t\t0x01\n#define PM_STAT_VLPR\t\t0x04\n#define PM_CTRL_RUNM_RUN\t0x00\n\n/* Commands */\n#define FTFX_CMD_BLOCKSTAT  0x00\n#define FTFX_CMD_SECTSTAT   0x01\n#define FTFX_CMD_LWORDPROG  0x06\n#define FTFX_CMD_SECTERASE  0x09\n#define FTFX_CMD_SECTWRITE  0x0b\n#define FTFX_CMD_MASSERASE  0x44\n#define FTFX_CMD_PGMPART    0x80\n#define FTFX_CMD_SETFLEXRAM 0x81\n\n/* The older Kinetis K series uses the following SDID layout :\n * Bit 31-16 : 0\n * Bit 15-12 : REVID\n * Bit 11-7  : DIEID\n * Bit 6-4   : FAMID\n * Bit 3-0   : PINID\n *\n * The newer Kinetis series uses the following SDID layout :\n * Bit 31-28 : FAMID\n * Bit 27-24 : SUBFAMID\n * Bit 23-20 : SERIESID\n * Bit 19-16 : SRAMSIZE\n * Bit 15-12 : REVID\n * Bit 6-4   : Reserved (0)\n * Bit 3-0   : PINID\n *\n * We assume that if bits 31-16 are 0 then it's an older\n * K-series MCU.\n */\n\n#define KINETIS_SOPT1_RAMSIZE_MASK  0x0000F000\n#define KINETIS_SOPT1_RAMSIZE_K24FN1M 0x0000B000\n\n#define KINETIS_SDID_K_SERIES_MASK  0x0000FFFF\n\n#define KINETIS_SDID_DIEID_MASK 0x00000F80\n\n#define KINETIS_SDID_DIEID_K22FN128\t0x00000680 /* smaller pflash with FTFA */\n#define KINETIS_SDID_DIEID_K22FN256\t0x00000A80\n#define KINETIS_SDID_DIEID_K22FN512\t0x00000E80\n#define KINETIS_SDID_DIEID_K24FN256\t0x00000700\n\n#define KINETIS_SDID_DIEID_K24FN1M\t0x00000300 /* Detect Errata 7534 */\n\n/* We can't rely solely on the FAMID field to determine the MCU\n * type since some FAMID values identify multiple MCUs with\n * different flash sector sizes (K20 and K22 for instance).\n * Therefore we combine it with the DIEID bits which may possibly\n * break if Freescale bumps the DIEID for a particular MCU. */\n#define KINETIS_K_SDID_TYPE_MASK 0x00000FF0\n#define KINETIS_K_SDID_K10_M50\t 0x00000000\n#define KINETIS_K_SDID_K10_M72\t 0x00000080\n#define KINETIS_K_SDID_K10_M100\t 0x00000100\n#define KINETIS_K_SDID_K10_M120\t 0x00000180\n#define KINETIS_K_SDID_K11\t\t 0x00000220\n#define KINETIS_K_SDID_K12\t\t 0x00000200\n#define KINETIS_K_SDID_K20_M50\t 0x00000010\n#define KINETIS_K_SDID_K20_M72\t 0x00000090\n#define KINETIS_K_SDID_K20_M100\t 0x00000110\n#define KINETIS_K_SDID_K20_M120\t 0x00000190\n#define KINETIS_K_SDID_K21_M50   0x00000230\n#define KINETIS_K_SDID_K21_M120\t 0x00000330\n#define KINETIS_K_SDID_K22_M50   0x00000210\n#define KINETIS_K_SDID_K22_M120\t 0x00000310\n#define KINETIS_K_SDID_K30_M72   0x000000A0\n#define KINETIS_K_SDID_K30_M100  0x00000120\n#define KINETIS_K_SDID_K40_M72   0x000000B0\n#define KINETIS_K_SDID_K40_M100  0x00000130\n#define KINETIS_K_SDID_K50_M72   0x000000E0\n#define KINETIS_K_SDID_K51_M72\t 0x000000F0\n#define KINETIS_K_SDID_K53\t\t 0x00000170\n#define KINETIS_K_SDID_K60_M100  0x00000140\n#define KINETIS_K_SDID_K60_M150  0x000001C0\n#define KINETIS_K_SDID_K70_M150  0x000001D0\n\n#define KINETIS_K_REVID_MASK\t0x0000F000\n#define KINETIS_K_REVID_SHIFT\t12\n\n#define KINETIS_SDID_SERIESID_MASK 0x00F00000\n#define KINETIS_SDID_SERIESID_K   0x00000000\n#define KINETIS_SDID_SERIESID_KL   0x00100000\n#define KINETIS_SDID_SERIESID_KE   0x00200000\n#define KINETIS_SDID_SERIESID_KW   0x00500000\n#define KINETIS_SDID_SERIESID_KV   0x00600000\n\n#define KINETIS_SDID_SUBFAMID_SHIFT 24\n#define KINETIS_SDID_SUBFAMID_MASK  0x0F000000\n#define KINETIS_SDID_SUBFAMID_KX0   0x00000000\n#define KINETIS_SDID_SUBFAMID_KX1   0x01000000\n#define KINETIS_SDID_SUBFAMID_KX2   0x02000000\n#define KINETIS_SDID_SUBFAMID_KX3   0x03000000\n#define KINETIS_SDID_SUBFAMID_KX4   0x04000000\n#define KINETIS_SDID_SUBFAMID_KX5   0x05000000\n#define KINETIS_SDID_SUBFAMID_KX6   0x06000000\n#define KINETIS_SDID_SUBFAMID_KX7   0x07000000\n#define KINETIS_SDID_SUBFAMID_KX8   0x08000000\n\n#define KINETIS_SDID_FAMILYID_SHIFT 28\n#define KINETIS_SDID_FAMILYID_MASK  0xF0000000\n#define KINETIS_SDID_FAMILYID_K0X   0x00000000\n#define KINETIS_SDID_FAMILYID_K1X   0x10000000\n#define KINETIS_SDID_FAMILYID_K2X   0x20000000\n#define KINETIS_SDID_FAMILYID_K3X   0x30000000\n#define KINETIS_SDID_FAMILYID_K4X   0x40000000\n#define KINETIS_SDID_FAMILYID_K5X   0x50000000\n#define KINETIS_SDID_FAMILYID_K6X   0x60000000\n#define KINETIS_SDID_FAMILYID_K7X   0x70000000\n#define KINETIS_SDID_FAMILYID_K8X   0x80000000\n#define KINETIS_SDID_FAMILYID_KL8X  0x90000000\n\n/* The field originally named DIEID has new name/meaning on KE1x */\n#define KINETIS_SDID_PROJECTID_MASK  KINETIS_SDID_DIEID_MASK\n#define KINETIS_SDID_PROJECTID_KE1XF 0x00000080\n#define KINETIS_SDID_PROJECTID_KE1XZ 0x00000100\n\nstruct kinetis_flash_bank {\n\tstruct kinetis_chip *k_chip;\n\tbool probed;\n\tunsigned bank_number;\t\t/* bank number in particular chip */\n\tstruct flash_bank *bank;\n\n\tuint32_t sector_size;\n\tuint32_t protection_size;\n\tuint32_t prog_base;\t\t/* base address for FTFx operations */\n\t\t\t\t\t/* usually same as bank->base for pflash, differs for FlexNVM */\n\tuint32_t protection_block;\t/* number of first protection block in this bank */\n\n\tenum {\n\t\tFC_AUTO = 0,\n\t\tFC_PFLASH,\n\t\tFC_FLEX_NVM,\n\t\tFC_FLEX_RAM,\n\t} flash_class;\n};\n\n#define KINETIS_MAX_BANKS 4u\n\nstruct kinetis_chip {\n\tstruct target *target;\n\tbool probed;\n\n\tuint32_t sim_sdid;\n\tuint32_t sim_fcfg1;\n\tuint32_t sim_fcfg2;\n\tuint32_t fcfg2_maxaddr0_shifted;\n\tuint32_t fcfg2_maxaddr1_shifted;\n\n\tunsigned num_pflash_blocks, num_nvm_blocks;\n\tunsigned pflash_sector_size, nvm_sector_size;\n\tunsigned max_flash_prog_size;\n\n\tuint32_t pflash_base;\n\tuint32_t pflash_size;\n\tuint32_t nvm_base;\n\tuint32_t nvm_size;\t\t/* whole FlexNVM */\n\tuint32_t dflash_size;\t\t/* accessible rest of FlexNVM if EEPROM backup uses part of FlexNVM */\n\n\tuint32_t progr_accel_ram;\n\tuint32_t sim_base;\n\n\tenum {\n\t\tFS_PROGRAM_SECTOR = 1,\n\t\tFS_PROGRAM_LONGWORD = 2,\n\t\tFS_PROGRAM_PHRASE = 4,\t\t/* Unsupported */\n\n\t\tFS_NO_CMD_BLOCKSTAT = 0x40,\n\t\tFS_WIDTH_256BIT = 0x80,\n\t\tFS_ECC = 0x100,\n\t} flash_support;\n\n\tenum {\n\t\tKINETIS_CACHE_NONE,\n\t\tKINETIS_CACHE_K,\t/* invalidate using FMC->PFB0CR/PFB01CR */\n\t\tKINETIS_CACHE_L,\t/* invalidate using MCM->PLACR */\n\t\tKINETIS_CACHE_MSCM,\t/* devices like KE1xF, invalidate MSCM->OCMDR0 */\n\t} cache_type;\n\n\tenum {\n\t\tKINETIS_WDOG_NONE,\n\t\tKINETIS_WDOG_K,\n\t\tKINETIS_WDOG_COP,\n\t\tKINETIS_WDOG32_KE1X,\n\t\tKINETIS_WDOG32_KL28,\n\t} watchdog_type;\n\n\tenum {\n\t\tKINETIS_SMC,\n\t\tKINETIS_SMC32,\n\t\tKINETIS_MC,\n\t} sysmodectrlr_type;\n\n\tchar name[40];\n\n\tunsigned num_banks;\n\tstruct kinetis_flash_bank banks[KINETIS_MAX_BANKS];\n};\n\nstruct kinetis_type {\n\tuint32_t sdid;\n\tchar *name;\n};\n\nstatic const struct kinetis_type kinetis_types_old[] = {\n\t{ KINETIS_K_SDID_K10_M50,  \"MK10D%s5\" },\n\t{ KINETIS_K_SDID_K10_M72,  \"MK10D%s7\" },\n\t{ KINETIS_K_SDID_K10_M100, \"MK10D%s10\" },\n\t{ KINETIS_K_SDID_K10_M120, \"MK10F%s12\" },\n\t{ KINETIS_K_SDID_K11,      \"MK11D%s5\" },\n\t{ KINETIS_K_SDID_K12,      \"MK12D%s5\" },\n\n\t{ KINETIS_K_SDID_K20_M50,  \"MK20D%s5\" },\n\t{ KINETIS_K_SDID_K20_M72,  \"MK20D%s7\" },\n\t{ KINETIS_K_SDID_K20_M100, \"MK20D%s10\" },\n\t{ KINETIS_K_SDID_K20_M120, \"MK20F%s12\" },\n\t{ KINETIS_K_SDID_K21_M50,  \"MK21D%s5\" },\n\t{ KINETIS_K_SDID_K21_M120, \"MK21F%s12\" },\n\t{ KINETIS_K_SDID_K22_M50,  \"MK22D%s5\" },\n\t{ KINETIS_K_SDID_K22_M120, \"MK22F%s12\" },\n\n\t{ KINETIS_K_SDID_K30_M72,  \"MK30D%s7\" },\n\t{ KINETIS_K_SDID_K30_M100, \"MK30D%s10\" },\n\n\t{ KINETIS_K_SDID_K40_M72,  \"MK40D%s7\" },\n\t{ KINETIS_K_SDID_K40_M100, \"MK40D%s10\" },\n\n\t{ KINETIS_K_SDID_K50_M72,  \"MK50D%s7\" },\n\t{ KINETIS_K_SDID_K51_M72,  \"MK51D%s7\" },\n\t{ KINETIS_K_SDID_K53,      \"MK53D%s10\" },\n\n\t{ KINETIS_K_SDID_K60_M100, \"MK60D%s10\" },\n\t{ KINETIS_K_SDID_K60_M150, \"MK60F%s15\" },\n\n\t{ KINETIS_K_SDID_K70_M150, \"MK70F%s15\" },\n};\n\n\n#define MDM_AP\t\t\t1\n\n#define MDM_REG_STAT\t\t0x00\n#define MDM_REG_CTRL\t\t0x04\n#define MDM_REG_ID\t\t0xfc\n\n#define MDM_STAT_FMEACK\t\t(1<<0)\n#define MDM_STAT_FREADY\t\t(1<<1)\n#define MDM_STAT_SYSSEC\t\t(1<<2)\n#define MDM_STAT_SYSRES\t\t(1<<3)\n#define MDM_STAT_FMEEN\t\t(1<<5)\n#define MDM_STAT_BACKDOOREN\t(1<<6)\n#define MDM_STAT_LPEN\t\t(1<<7)\n#define MDM_STAT_VLPEN\t\t(1<<8)\n#define MDM_STAT_LLSMODEXIT\t(1<<9)\n#define MDM_STAT_VLLSXMODEXIT\t(1<<10)\n#define MDM_STAT_CORE_HALTED\t(1<<16)\n#define MDM_STAT_CORE_SLEEPDEEP\t(1<<17)\n#define MDM_STAT_CORESLEEPING\t(1<<18)\n\n#define MDM_CTRL_FMEIP\t\t(1<<0)\n#define MDM_CTRL_DBG_DIS\t(1<<1)\n#define MDM_CTRL_DBG_REQ\t(1<<2)\n#define MDM_CTRL_SYS_RES_REQ\t(1<<3)\n#define MDM_CTRL_CORE_HOLD_RES\t(1<<4)\n#define MDM_CTRL_VLLSX_DBG_REQ\t(1<<5)\n#define MDM_CTRL_VLLSX_DBG_ACK\t(1<<6)\n#define MDM_CTRL_VLLSX_STAT_ACK\t(1<<7)\n\n#define MDM_ACCESS_TIMEOUT\t500 /* msec */\n\n\nstatic bool allow_fcf_writes;\nstatic uint8_t fcf_fopt = 0xff;\nstatic bool create_banks;\n\n\nconst struct flash_driver kinetis_flash;\nstatic int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\tuint32_t offset, uint32_t count);\nstatic int kinetis_probe_chip(struct kinetis_chip *k_chip);\nstatic int kinetis_auto_probe(struct flash_bank *bank);\n\n\nstatic int kinetis_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)\n{\n\tLOG_DEBUG(\"MDM_REG[0x%02x] <- %08\" PRIX32, reg, value);\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"MDM: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_write(ap, reg, value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: failed to queue a write request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)\n{\n\tstruct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"MDM: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_read(ap, reg, result);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: failed to queue a read request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"MDM_REG[0x%02x]: %08\" PRIX32, reg, *result);\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_mdm_poll_register(struct adiv5_dap *dap, unsigned reg,\n\t\t\tuint32_t mask, uint32_t value, uint32_t timeout_ms)\n{\n\tuint32_t val;\n\tint retval;\n\tint64_t ms_timeout = timeval_ms() + timeout_ms;\n\n\tdo {\n\t\tretval = kinetis_mdm_read_register(dap, reg, &val);\n\t\tif (retval != ERROR_OK || (val & mask) == value)\n\t\t\treturn retval;\n\n\t\talive_sleep(1);\n\t} while (timeval_ms() < ms_timeout);\n\n\tLOG_DEBUG(\"MDM: polling timed out\");\n\treturn ERROR_FAIL;\n}\n\n/*\n * This command can be used to break a watchdog reset loop when\n * connecting to an unsecured target. Unlike other commands, halt will\n * automatically retry as it does not know how far into the boot process\n * it is when the command is called.\n */\nCOMMAND_HANDLER(kinetis_mdm_halt)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\tint retval;\n\tint tries = 0;\n\tuint32_t stat;\n\tint64_t ms_timeout = timeval_ms() + MDM_ACCESS_TIMEOUT;\n\n\tif (!dap) {\n\t\tLOG_ERROR(\"Cannot perform halt with a high-level adapter\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\twhile (true) {\n\t\ttries++;\n\n\t\tkinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_CORE_HOLD_RES);\n\n\t\talive_sleep(1);\n\n\t\tretval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &stat);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"MDM: failed to read MDM_REG_STAT\");\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Repeat setting MDM_CTRL_CORE_HOLD_RES until system is out of\n\t\t * reset with flash ready and without security\n\t\t */\n\t\tif ((stat & (MDM_STAT_FREADY | MDM_STAT_SYSSEC | MDM_STAT_SYSRES))\n\t\t\t\t== (MDM_STAT_FREADY | MDM_STAT_SYSRES))\n\t\t\tbreak;\n\n\t\tif (timeval_ms() >= ms_timeout) {\n\t\t\tLOG_ERROR(\"MDM: halt timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"MDM: halt succeeded after %d attempts.\", tries);\n\n\ttarget_poll(target);\n\t/* enable polling in case kinetis_check_flash_security_status disabled it */\n\tjtag_poll_set_enabled(true);\n\n\talive_sleep(100);\n\n\ttarget->reset_halt = true;\n\ttarget->type->assert_reset(target);\n\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to clear MDM_REG_CTRL\");\n\t\treturn retval;\n\t}\n\n\ttarget->type->deassert_reset(target);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(kinetis_mdm_reset)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\tint retval;\n\n\tif (!dap) {\n\t\tLOG_ERROR(\"Cannot perform reset with a high-level adapter\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to write MDM_REG_CTRL\");\n\t\treturn retval;\n\t}\n\n\tretval = kinetis_mdm_poll_register(dap, MDM_REG_STAT, MDM_STAT_SYSRES, 0, 500);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to assert reset\");\n\t\treturn retval;\n\t}\n\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to clear MDM_REG_CTRL\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n * This function implements the procedure to mass erase the flash via\n * SWD/JTAG on Kinetis K and L series of devices as it is described in\n * AN4835 \"Production Flash Programming Best Practices for Kinetis K-\n * and L-series MCUs\" Section 4.2.1. To prevent a watchdog reset loop,\n * the core remains halted after this function completes as suggested\n * by the application note.\n */\nCOMMAND_HANDLER(kinetis_mdm_mass_erase)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\tLOG_ERROR(\"Cannot perform mass erase with a high-level adapter\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval;\n\n\t/*\n\t * ... Power on the processor, or if power has already been\n\t * applied, assert the RESET pin to reset the processor. For\n\t * devices that do not have a RESET pin, write the System\n\t * Reset Request bit in the MDM-AP control register after\n\t * establishing communication...\n\t */\n\n\t/* assert SRST if configured */\n\tbool has_srst = jtag_get_reset_config() & RESET_HAS_SRST;\n\tif (has_srst)\n\t\tadapter_assert_reset();\n\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ);\n\tif (retval != ERROR_OK && !has_srst) {\n\t\tLOG_ERROR(\"MDM: failed to assert reset\");\n\t\tgoto deassert_reset_and_exit;\n\t}\n\n\t/*\n\t * ... Read the MDM-AP status register repeatedly and wait for\n\t * stable conditions suitable for mass erase:\n\t * - mass erase is enabled\n\t * - flash is ready\n\t * - reset is finished\n\t *\n\t * Mass erase is started as soon as all conditions are met in 32\n\t * subsequent status reads.\n\t *\n\t * In case of not stable conditions (RESET/WDOG loop in secured device)\n\t * the user is asked for manual pressing of RESET button\n\t * as a last resort.\n\t */\n\tint cnt_mass_erase_disabled = 0;\n\tint cnt_ready = 0;\n\tint64_t ms_start = timeval_ms();\n\tbool man_reset_requested = false;\n\n\tdo {\n\t\tuint32_t stat = 0;\n\t\tint64_t ms_elapsed = timeval_ms() - ms_start;\n\n\t\tif (!man_reset_requested && ms_elapsed > 100) {\n\t\t\tLOG_INFO(\"MDM: Press RESET button now if possible.\");\n\t\t\tman_reset_requested = true;\n\t\t}\n\n\t\tif (ms_elapsed > 3000) {\n\t\t\tLOG_ERROR(\"MDM: waiting for mass erase conditions timed out.\");\n\t\t\tLOG_INFO(\"Mass erase of a secured MCU is not possible without hardware reset.\");\n\t\t\tLOG_INFO(\"Connect SRST, use 'reset_config srst_only' and retry.\");\n\t\t\tgoto deassert_reset_and_exit;\n\t\t}\n\t\tretval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &stat);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcnt_ready = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!(stat & MDM_STAT_FMEEN)) {\n\t\t\tcnt_ready = 0;\n\t\t\tcnt_mass_erase_disabled++;\n\t\t\tif (cnt_mass_erase_disabled > 10) {\n\t\t\t\tLOG_ERROR(\"MDM: mass erase is disabled\");\n\t\t\t\tgoto deassert_reset_and_exit;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif ((stat & (MDM_STAT_FREADY | MDM_STAT_SYSRES)) == MDM_STAT_FREADY)\n\t\t\tcnt_ready++;\n\t\telse\n\t\t\tcnt_ready = 0;\n\n\t} while (cnt_ready < 32);\n\n\t/*\n\t * ... Write the MDM-AP control register to set the Flash Mass\n\t * Erase in Progress bit. This will start the mass erase\n\t * process...\n\t */\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, MDM_CTRL_SYS_RES_REQ | MDM_CTRL_FMEIP);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to start mass erase\");\n\t\tgoto deassert_reset_and_exit;\n\t}\n\n\t/*\n\t * ... Read the MDM-AP control register until the Flash Mass\n\t * Erase in Progress bit clears...\n\t * Data sheed defines erase time <3.6 sec/512kB flash block.\n\t * The biggest device has 4 pflash blocks => timeout 16 sec.\n\t */\n\tretval = kinetis_mdm_poll_register(dap, MDM_REG_CTRL, MDM_CTRL_FMEIP, 0, 16000);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: mass erase timeout\");\n\t\tgoto deassert_reset_and_exit;\n\t}\n\n\ttarget_poll(target);\n\t/* enable polling in case kinetis_check_flash_security_status disabled it */\n\tjtag_poll_set_enabled(true);\n\n\talive_sleep(100);\n\n\ttarget->reset_halt = true;\n\ttarget->type->assert_reset(target);\n\n\t/*\n\t * ... Negate the RESET signal or clear the System Reset Request\n\t * bit in the MDM-AP control register.\n\t */\n\tretval = kinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"MDM: failed to clear MDM_REG_CTRL\");\n\n\ttarget->type->deassert_reset(target);\n\n\treturn retval;\n\ndeassert_reset_and_exit:\n\tkinetis_mdm_write_register(dap, MDM_REG_CTRL, 0);\n\tif (has_srst)\n\t\tadapter_deassert_reset();\n\treturn retval;\n}\n\nstatic const uint32_t kinetis_known_mdm_ids[] = {\n\t0x001C0000,\t/* Kinetis-K Series */\n\t0x001C0020,\t/* Kinetis-L/M/V/E Series */\n\t0x001C0030,\t/* Kinetis with a Cortex-M7, in time of writing KV58 */\n};\n\n/*\n * This function implements the procedure to connect to\n * SWD/JTAG on Kinetis K and L series of devices as it is described in\n * AN4835 \"Production Flash Programming Best Practices for Kinetis K-\n * and L-series MCUs\" Section 4.1.1\n */\nCOMMAND_HANDLER(kinetis_check_flash_security_status)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\tLOG_WARNING(\"Cannot check flash security status with a high-level adapter\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!dap->ops)\n\t\treturn ERROR_OK;\t/* too early to check, in JTAG mode ops may not be initialised */\n\n\tuint32_t val;\n\tint retval;\n\n\t/*\n\t * ... The MDM-AP ID register can be read to verify that the\n\t * connection is working correctly...\n\t */\n\tretval = kinetis_mdm_read_register(dap, MDM_REG_ID, &val);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to read ID register\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (val == 0)\n\t\treturn ERROR_OK;\t/* dap not yet initialised */\n\n\tbool found = false;\n\tfor (size_t i = 0; i < ARRAY_SIZE(kinetis_known_mdm_ids); i++) {\n\t\tif (val == kinetis_known_mdm_ids[i]) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!found)\n\t\tLOG_WARNING(\"MDM: unknown ID %08\" PRIX32, val);\n\n\t/*\n\t * ... Read the System Security bit to determine if security is enabled.\n\t * If System Security = 0, then proceed. If System Security = 1, then\n\t * communication with the internals of the processor, including the\n\t * flash, will not be possible without issuing a mass erase command or\n\t * unsecuring the part through other means (backdoor key unlock)...\n\t */\n\tretval = kinetis_mdm_read_register(dap, MDM_REG_STAT, &val);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to read MDM_REG_STAT\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/*\n\t * System Security bit is also active for short time during reset.\n\t * If a MCU has blank flash and runs in RESET/WDOG loop,\n\t * System Security bit is active most of time!\n\t * We should observe Flash Ready bit and read status several times\n\t * to avoid false detection of secured MCU\n\t */\n\tint secured_score = 0, flash_not_ready_score = 0;\n\n\tif ((val & (MDM_STAT_SYSSEC | MDM_STAT_FREADY)) != MDM_STAT_FREADY) {\n\t\tuint32_t stats[32];\n\t\tstruct adiv5_ap *ap = dap_get_ap(dap, MDM_AP);\n\t\tif (!ap) {\n\t\t\tLOG_ERROR(\"MDM: failed to get AP\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tfor (unsigned int i = 0; i < 32; i++) {\n\t\t\tstats[i] = MDM_STAT_FREADY;\n\t\t\tdap_queue_ap_read(ap, MDM_REG_STAT, &stats[i]);\n\t\t}\n\t\tretval = dap_run(dap);\n\t\tdap_put_ap(ap);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"MDM: dap_run failed when validating secured state\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tfor (unsigned int i = 0; i < 32; i++) {\n\t\t\tif (stats[i] & MDM_STAT_SYSSEC)\n\t\t\t\tsecured_score++;\n\t\t\tif (!(stats[i] & MDM_STAT_FREADY))\n\t\t\t\tflash_not_ready_score++;\n\t\t}\n\t}\n\n\tif (flash_not_ready_score <= 8 && secured_score > 24) {\n\t\tjtag_poll_set_enabled(false);\n\n\t\tLOG_WARNING(\"*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********\");\n\t\tLOG_WARNING(\"****                                                          ****\");\n\t\tLOG_WARNING(\"**** Your Kinetis MCU is in secured state, which means that,  ****\");\n\t\tLOG_WARNING(\"**** with exception for very basic communication, JTAG/SWD    ****\");\n\t\tLOG_WARNING(\"**** interface will NOT work. In order to restore its         ****\");\n\t\tLOG_WARNING(\"**** functionality please issue 'kinetis mdm mass_erase'      ****\");\n\t\tLOG_WARNING(\"**** command, power cycle the MCU and restart OpenOCD.        ****\");\n\t\tLOG_WARNING(\"****                                                          ****\");\n\t\tLOG_WARNING(\"*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********\");\n\n\t} else if (flash_not_ready_score > 24) {\n\t\tjtag_poll_set_enabled(false);\n\t\tLOG_WARNING(\"**** Your Kinetis MCU is probably locked-up in RESET/WDOG loop. ****\");\n\t\tLOG_WARNING(\"**** Common reason is a blank flash (at least a reset vector).  ****\");\n\t\tLOG_WARNING(\"**** Issue 'kinetis mdm halt' command or if SRST is connected   ****\");\n\t\tLOG_WARNING(\"**** and configured, use 'reset halt'                           ****\");\n\t\tLOG_WARNING(\"**** If MCU cannot be halted, it is likely secured and running  ****\");\n\t\tLOG_WARNING(\"**** in RESET/WDOG loop. Issue 'kinetis mdm mass_erase'         ****\");\n\n\t} else {\n\t\tLOG_INFO(\"MDM: Chip is unsecured. Continuing.\");\n\t\tjtag_poll_set_enabled(true);\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic struct kinetis_chip *kinetis_get_chip(struct target *target)\n{\n\tstruct flash_bank *bank_iter;\n\tstruct kinetis_flash_bank *k_bank;\n\n\t/* iterate over all kinetis banks */\n\tfor (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {\n\t\tif (bank_iter->driver != &kinetis_flash\n\t\t    || bank_iter->target != target)\n\t\t\tcontinue;\n\n\t\tk_bank = bank_iter->driver_priv;\n\t\tif (!k_bank)\n\t\t\tcontinue;\n\n\t\tif (k_bank->k_chip)\n\t\t\treturn k_bank->k_chip;\n\t}\n\treturn NULL;\n}\n\nstatic int kinetis_chip_options(struct kinetis_chip *k_chip, int argc, const char *argv[])\n{\n\tfor (int i = 0; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"-sim-base\") == 0) {\n\t\t\tif (i + 1 < argc)\n\t\t\t\tk_chip->sim_base = strtoul(argv[++i], NULL, 0);\n\t\t} else\n\t\t\tLOG_ERROR(\"Unsupported flash bank option %s\", argv[i]);\n\t}\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(kinetis_flash_bank_command)\n{\n\tstruct target *target = bank->target;\n\tstruct kinetis_chip *k_chip;\n\tstruct kinetis_flash_bank *k_bank;\n\tint retval;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_INFO(\"add flash_bank kinetis %s\", bank->name);\n\n\tk_chip = kinetis_get_chip(target);\n\n\tif (!k_chip) {\n\t\tk_chip = calloc(sizeof(struct kinetis_chip), 1);\n\t\tif (!k_chip) {\n\t\t\tLOG_ERROR(\"No memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tk_chip->target = target;\n\n\t\t/* only the first defined bank can define chip options */\n\t\tretval = kinetis_chip_options(k_chip, CMD_ARGC - 6, CMD_ARGV + 6);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (k_chip->num_banks >= KINETIS_MAX_BANKS) {\n\t\tLOG_ERROR(\"Only %u Kinetis flash banks are supported\", KINETIS_MAX_BANKS);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = k_bank = &(k_chip->banks[k_chip->num_banks]);\n\tk_bank->k_chip = k_chip;\n\tk_bank->bank_number = k_chip->num_banks;\n\tk_bank->bank = bank;\n\tk_chip->num_banks++;\n\n\treturn ERROR_OK;\n}\n\n\nstatic void kinetis_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tif (!k_bank)\n\t\treturn;\n\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\tif (!k_chip)\n\t\treturn;\n\n\tk_chip->num_banks--;\n\tif (k_chip->num_banks == 0)\n\t\tfree(k_chip);\n}\n\n\nstatic int kinetis_create_missing_banks(struct kinetis_chip *k_chip)\n{\n\tunsigned num_blocks;\n\tstruct kinetis_flash_bank *k_bank;\n\tstruct flash_bank *bank;\n\tchar base_name[69], name[87], num[11];\n\tchar *class, *p;\n\n\tnum_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;\n\tif (num_blocks > KINETIS_MAX_BANKS) {\n\t\tLOG_ERROR(\"Only %u Kinetis flash banks are supported\", KINETIS_MAX_BANKS);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank = k_chip->banks[0].bank;\n\tif (bank && bank->name) {\n\t\tstrncpy(base_name, bank->name, sizeof(base_name) - 1);\n\t\tbase_name[sizeof(base_name) - 1] = '\\0';\n\t\tp = strstr(base_name, \".pflash\");\n\t\tif (p) {\n\t\t\t*p = '\\0';\n\t\t\tif (k_chip->num_pflash_blocks > 1) {\n\t\t\t\t/* rename first bank if numbering is needed */\n\t\t\t\tsnprintf(name, sizeof(name), \"%s.pflash0\", base_name);\n\t\t\t\tfree(bank->name);\n\t\t\t\tbank->name = strdup(name);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tstrncpy(base_name, target_name(k_chip->target), sizeof(base_name) - 1);\n\t\tbase_name[sizeof(base_name) - 1] = '\\0';\n\t\tp = strstr(base_name, \".cpu\");\n\t\tif (p)\n\t\t\t*p = '\\0';\n\t}\n\n\tfor (unsigned int bank_idx = 1; bank_idx < num_blocks; bank_idx++) {\n\t\tk_bank = &(k_chip->banks[bank_idx]);\n\t\tbank = k_bank->bank;\n\n\t\tif (bank)\n\t\t\tcontinue;\n\n\t\tnum[0] = '\\0';\n\n\t\tif (bank_idx < k_chip->num_pflash_blocks) {\n\t\t\tclass = \"pflash\";\n\t\t\tif (k_chip->num_pflash_blocks > 1)\n\t\t\t\tsnprintf(num, sizeof(num), \"%u\", bank_idx);\n\t\t} else {\n\t\t\tclass = \"flexnvm\";\n\t\t\tif (k_chip->num_nvm_blocks > 1)\n\t\t\t\tsnprintf(num, sizeof(num), \"%u\",\n\t\t\t\t\t bank_idx - k_chip->num_pflash_blocks);\n\t\t}\n\n\t\tbank = calloc(sizeof(struct flash_bank), 1);\n\t\tif (!bank)\n\t\t\treturn ERROR_FAIL;\n\n\t\tbank->target = k_chip->target;\n\t\tbank->driver = &kinetis_flash;\n\t\tbank->default_padded_value = bank->erased_value = 0xff;\n\n\t\tsnprintf(name, sizeof(name), \"%s.%s%s\",\n\t\t\t base_name, class, num);\n\t\tbank->name = strdup(name);\n\n\t\tbank->driver_priv = k_bank = &(k_chip->banks[k_chip->num_banks]);\n\t\tk_bank->k_chip = k_chip;\n\t\tk_bank->bank_number = bank_idx;\n\t\tk_bank->bank = bank;\n\t\tif (k_chip->num_banks <= bank_idx)\n\t\t\tk_chip->num_banks = bank_idx + 1;\n\n\t\tflash_bank_add(bank);\n\t}\n\treturn ERROR_OK;\n}\n\n\nstatic int kinetis_disable_wdog_algo(struct target *target, size_t code_size, const uint8_t *code, uint32_t wdog_base)\n{\n\tstruct working_area *wdog_algorithm;\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct reg_param reg_params[1];\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_alloc_working_area(target, code_size, &wdog_algorithm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_buffer(target, wdog_algorithm->address,\n\t\t\tcode_size, code);\n\tif (retval == ERROR_OK) {\n\t\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\t\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, wdog_base);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 1, reg_params,\n\t\t\twdog_algorithm->address,\n\t\t\twdog_algorithm->address + code_size - 2,\n\t\t\t500, &armv7m_info);\n\n\t\tdestroy_reg_param(&reg_params[0]);\n\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"Error executing Kinetis WDOG unlock algorithm\");\n\t}\n\n\ttarget_free_working_area(target, wdog_algorithm);\n\n\treturn retval;\n}\n\n/* Disable the watchdog on Kinetis devices\n * Standard Kx WDOG peripheral checks timing and therefore requires to run algo.\n */\nstatic int kinetis_disable_wdog_kx(struct target *target)\n{\n\tconst uint32_t wdog_base = WDOG_BASE;\n\tuint16_t wdog;\n\tint retval;\n\n\tstatic const uint8_t kinetis_unlock_wdog_code[] = {\n#include \"../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc\"\n\t};\n\n\tretval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((wdog & 0x1) == 0) {\n\t\t/* watchdog already disabled */\n\t\treturn ERROR_OK;\n\t}\n\tLOG_INFO(\"Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%04\" PRIx16 \")\", wdog);\n\n\tretval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"WDOG_STCTRLH = 0x%04\" PRIx16, wdog);\n\treturn (wdog & 0x1) ? ERROR_FAIL : ERROR_OK;\n}\n\nstatic int kinetis_disable_wdog32(struct target *target, uint32_t wdog_base)\n{\n\tuint32_t wdog_cs;\n\tint retval;\n\n\tstatic const uint8_t kinetis_unlock_wdog_code[] = {\n#include \"../../../contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc\"\n\t};\n\n\tretval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((wdog_cs & 0x80) == 0)\n\t\treturn ERROR_OK; /* watchdog already disabled */\n\n\tLOG_INFO(\"Disabling Kinetis watchdog (initial WDOG_CS 0x%08\" PRIx32 \")\", wdog_cs);\n\n\tretval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((wdog_cs & 0x80) == 0)\n\t\treturn ERROR_OK; /* watchdog disabled successfully */\n\n\tLOG_ERROR(\"Cannot disable Kinetis watchdog (WDOG_CS 0x%08\" PRIx32 \"), issue 'reset init'\", wdog_cs);\n\treturn ERROR_FAIL;\n}\n\nstatic int kinetis_disable_wdog(struct kinetis_chip *k_chip)\n{\n\tstruct target *target = k_chip->target;\n\tuint8_t sim_copc;\n\tint retval;\n\n\tif (!k_chip->probed) {\n\t\tretval = kinetis_probe_chip(k_chip);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tswitch (k_chip->watchdog_type) {\n\tcase KINETIS_WDOG_K:\n\t\treturn kinetis_disable_wdog_kx(target);\n\n\tcase KINETIS_WDOG_COP:\n\t\tretval = target_read_u8(target, SIM_COPC, &sim_copc);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((sim_copc & 0xc) == 0)\n\t\t\treturn ERROR_OK; /* watchdog already disabled */\n\n\t\tLOG_INFO(\"Disabling Kinetis watchdog (initial SIM_COPC 0x%02\" PRIx8 \")\", sim_copc);\n\t\tretval = target_write_u8(target, SIM_COPC, sim_copc & ~0xc);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = target_read_u8(target, SIM_COPC, &sim_copc);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((sim_copc & 0xc) == 0)\n\t\t\treturn ERROR_OK; /* watchdog disabled successfully */\n\n\t\tLOG_ERROR(\"Cannot disable Kinetis watchdog (SIM_COPC 0x%02\" PRIx8 \"), issue 'reset init'\", sim_copc);\n\t\treturn ERROR_FAIL;\n\n\tcase KINETIS_WDOG32_KE1X:\n\t\treturn kinetis_disable_wdog32(target, WDOG32_KE1X);\n\n\tcase KINETIS_WDOG32_KL28:\n\t\treturn kinetis_disable_wdog32(target, WDOG32_KL28);\n\n\tdefault:\n\t\treturn ERROR_OK;\n\t}\n}\n\nCOMMAND_HANDLER(kinetis_disable_wdog_handler)\n{\n\tint result;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct kinetis_chip *k_chip = kinetis_get_chip(target);\n\n\tif (!k_chip)\n\t\treturn ERROR_FAIL;\n\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tresult = kinetis_disable_wdog(k_chip);\n\treturn result;\n}\n\n\nstatic int kinetis_ftfx_decode_error(uint8_t fstat)\n{\n\tif (fstat & 0x20) {\n\t\tLOG_ERROR(\"Flash operation failed, illegal command\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\t} else if (fstat & 0x10)\n\t\tLOG_ERROR(\"Flash operation failed, protection violated\");\n\n\telse if (fstat & 0x40)\n\t\tLOG_ERROR(\"Flash operation failed, read collision\");\n\n\telse if (fstat & 0x80)\n\t\treturn ERROR_OK;\n\n\telse\n\t\tLOG_ERROR(\"Flash operation timed out\");\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int kinetis_ftfx_clear_error(struct target *target)\n{\n\t/* reset error flags */\n\treturn target_write_u8(target, FTFX_FSTAT, 0x70);\n}\n\n\nstatic int kinetis_ftfx_prepare(struct target *target)\n{\n\tint result;\n\tuint8_t fstat;\n\n\t/* wait until busy */\n\tfor (unsigned int i = 0; i < 50; i++) {\n\t\tresult = target_read_u8(target, FTFX_FSTAT, &fstat);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tif (fstat & 0x80)\n\t\t\tbreak;\n\t}\n\n\tif ((fstat & 0x80) == 0) {\n\t\tLOG_ERROR(\"Flash controller is busy\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\tif (fstat != 0x80) {\n\t\t/* reset error flags */\n\t\tresult = kinetis_ftfx_clear_error(target);\n\t}\n\treturn result;\n}\n\n/* Kinetis Program-LongWord Microcodes */\nstatic const uint8_t kinetis_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/kinetis/kinetis_flash.inc\"\n};\n\n/* Program LongWord Block Write */\nstatic int kinetis_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t wcount)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tuint32_t address = k_bank->prog_base + offset;\n\tuint32_t end_address;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval;\n\tuint8_t fstat;\n\n\t/* allocate working area with flash programming code */\n\tif (target_alloc_working_area(target, sizeof(kinetis_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\tsizeof(kinetis_flash_write_code), kinetis_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer, size *must* be multiple of word */\n\tbuffer_size = target_get_working_area_avail(target) & ~(sizeof(uint32_t) - 1);\n\tif (buffer_size < 256) {\n\t\tLOG_WARNING(\"large enough working area not available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t} else if (buffer_size > 16384) {\n\t\t/* probably won't benefit from more than 16k ... */\n\t\tbuffer_size = 16384;\n\t}\n\n\tif (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {\n\t\tLOG_ERROR(\"allocating working area failed\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* address */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /* word count */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, wcount);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, FTFX_FSTAT);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, wcount, 4,\n\t\t\t\t\t\t0, NULL,\n\t\t\t\t\t\t5, reg_params,\n\t\t\t\t\t\tsource->address, source->size,\n\t\t\t\t\t\twrite_algorithm->address, 0,\n\t\t\t\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tend_address = buf_get_u32(reg_params[0].value, 0, 32);\n\n\t\tLOG_ERROR(\"Error writing flash at %08\" PRIx32, end_address);\n\n\t\tretval = target_read_u8(target, FTFX_FSTAT, &fstat);\n\t\tif (retval == ERROR_OK) {\n\t\t\tretval = kinetis_ftfx_decode_error(fstat);\n\n\t\t\t/* reset error flags */\n\t\t\ttarget_write_u8(target, FTFX_FSTAT, 0x70);\n\t\t}\n\t} else if (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error executing kinetis Flash programming algorithm\");\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\nstatic int kinetis_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tif (allow_fcf_writes) {\n\t\tLOG_ERROR(\"Protection setting is possible with 'kinetis fcf_source protection' only!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!bank->prot_blocks || bank->num_prot_blocks == 0) {\n\t\tLOG_ERROR(\"No protection possible for current bank!\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tfor (unsigned int i = first; i < bank->num_prot_blocks && i <= last; i++)\n\t\tbank->prot_blocks[i].is_protected = set;\n\n\tLOG_INFO(\"Protection bits will be written at the next FCF sector erase or write.\");\n\tLOG_INFO(\"Do not issue 'flash info' command until protection is written,\");\n\tLOG_INFO(\"doing so would re-read protection status from MCU.\");\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_protect_check(struct flash_bank *bank)\n{\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tint result;\n\tint b;\n\tuint32_t fprot;\n\n\tif (k_bank->flash_class == FC_PFLASH) {\n\n\t\t/* read protection register */\n\t\tresult = target_read_u32(bank->target, FTFX_FPROT3, &fprot);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\t/* Every bit protects 1/32 of the full flash (not necessarily just this bank) */\n\n\t} else if (k_bank->flash_class == FC_FLEX_NVM) {\n\t\tuint8_t fdprot;\n\n\t\t/* read protection register */\n\t\tresult = target_read_u8(bank->target, FTFX_FDPROT, &fdprot);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tfprot = fdprot;\n\n\t} else {\n\t\tLOG_ERROR(\"Protection checks for FlexRAM not supported\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tb = k_bank->protection_block;\n\tfor (unsigned int i = 0; i < bank->num_prot_blocks; i++) {\n\t\tif ((fprot >> b) & 1)\n\t\t\tbank->prot_blocks[i].is_protected = 0;\n\t\telse\n\t\t\tbank->prot_blocks[i].is_protected = 1;\n\n\t\tb++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int kinetis_fill_fcf(struct flash_bank *bank, uint8_t *fcf)\n{\n\tuint32_t fprot = 0xffffffff;\n\tuint8_t fsec = 0xfe;\t\t /* set MCU unsecure */\n\tuint8_t fdprot = 0xff;\n\tunsigned num_blocks;\n\tuint32_t pflash_bit;\n\tuint8_t dflash_bit;\n\tstruct flash_bank *bank_iter;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\n\tmemset(fcf, 0xff, FCF_SIZE);\n\n\tpflash_bit = 1;\n\tdflash_bit = 1;\n\n\t/* iterate over all kinetis banks */\n\t/* current bank is bank 0, it contains FCF */\n\tnum_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;\n\tfor (unsigned int bank_idx = 0; bank_idx < num_blocks; bank_idx++) {\n\t\tk_bank = &(k_chip->banks[bank_idx]);\n\t\tbank_iter = k_bank->bank;\n\n\t\tif (!bank_iter) {\n\t\t\tLOG_WARNING(\"Missing bank %u configuration, FCF protection flags may be incomplete\", bank_idx);\n\t\t\tcontinue;\n\t\t}\n\n\t\tkinetis_auto_probe(bank_iter);\n\n\t\tassert(bank_iter->prot_blocks);\n\n\t\tif (k_bank->flash_class == FC_PFLASH) {\n\t\t\tfor (unsigned int i = 0; i < bank_iter->num_prot_blocks; i++) {\n\t\t\t\tif (bank_iter->prot_blocks[i].is_protected == 1)\n\t\t\t\t\tfprot &= ~pflash_bit;\n\n\t\t\t\tpflash_bit <<= 1;\n\t\t\t}\n\n\t\t} else if (k_bank->flash_class == FC_FLEX_NVM) {\n\t\t\tfor (unsigned int i = 0; i < bank_iter->num_prot_blocks; i++) {\n\t\t\t\tif (bank_iter->prot_blocks[i].is_protected == 1)\n\t\t\t\t\tfdprot &= ~dflash_bit;\n\n\t\t\t\tdflash_bit <<= 1;\n\t\t\t}\n\n\t\t}\n\t}\n\n\ttarget_buffer_set_u32(bank->target, fcf + FCF_FPROT, fprot);\n\tfcf[FCF_FSEC] = fsec;\n\tfcf[FCF_FOPT] = fcf_fopt;\n\tfcf[FCF_FDPROT] = fdprot;\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ftfx_command(struct target *target, uint8_t fcmd, uint32_t faddr,\n\t\t\t\tuint8_t fccob4, uint8_t fccob5, uint8_t fccob6, uint8_t fccob7,\n\t\t\t\tuint8_t fccob8, uint8_t fccob9, uint8_t fccoba, uint8_t fccobb,\n\t\t\t\tuint8_t *ftfx_fstat)\n{\n\tuint8_t command[12] = {faddr & 0xff, (faddr >> 8) & 0xff, (faddr >> 16) & 0xff, fcmd,\n\t\t\tfccob7, fccob6, fccob5, fccob4,\n\t\t\tfccobb, fccoba, fccob9, fccob8};\n\tint result;\n\tuint8_t fstat;\n\tint64_t ms_timeout = timeval_ms() + 250;\n\n\tresult = target_write_memory(target, FTFX_FCCOB3, 4, 3, command);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* start command */\n\tresult = target_write_u8(target, FTFX_FSTAT, 0x80);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* wait for done */\n\tdo {\n\t\tresult = target_read_u8(target, FTFX_FSTAT, &fstat);\n\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tif (fstat & 0x80)\n\t\t\tbreak;\n\n\t} while (timeval_ms() < ms_timeout);\n\n\tif (ftfx_fstat)\n\t\t*ftfx_fstat = fstat;\n\n\tif ((fstat & 0xf0) != 0x80) {\n\t\tLOG_DEBUG(\"ftfx command failed FSTAT: %02X FCCOB: %02X%02X%02X%02X %02X%02X%02X%02X %02X%02X%02X%02X\",\n\t\t\t fstat, command[3], command[2], command[1], command[0],\n\t\t\t command[7], command[6], command[5], command[4],\n\t\t\t command[11], command[10], command[9], command[8]);\n\n\t\treturn kinetis_ftfx_decode_error(fstat);\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int kinetis_read_pmstat(struct kinetis_chip *k_chip, uint8_t *pmstat)\n{\n\tint result;\n\tuint32_t stat32;\n\tstruct target *target = k_chip->target;\n\n\tswitch (k_chip->sysmodectrlr_type) {\n\tcase KINETIS_SMC:\n\t\tresult = target_read_u8(target, SMC_PMSTAT, pmstat);\n\t\treturn result;\n\n\tcase KINETIS_SMC32:\n\t\tresult = target_read_u32(target, SMC32_PMSTAT, &stat32);\n\t\tif (result == ERROR_OK)\n\t\t\t*pmstat = stat32 & 0xff;\n\t\treturn result;\n\n\tcase KINETIS_MC:\n\t\t/* emulate SMC by reading PMC_REGSC bit 3 (VLPRS) */\n\t\tresult = target_read_u8(target, PMC_REGSC, pmstat);\n\t\tif (result == ERROR_OK) {\n\t\t\tif (*pmstat & 0x08)\n\t\t\t\t*pmstat = PM_STAT_VLPR;\n\t\t\telse\n\t\t\t\t*pmstat = PM_STAT_RUN;\n\t\t}\n\t\treturn result;\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic int kinetis_check_run_mode(struct kinetis_chip *k_chip)\n{\n\tint result;\n\tuint8_t pmstat;\n\tstruct target *target;\n\n\tif (!k_chip) {\n\t\tLOG_ERROR(\"Chip not probed.\");\n\t\treturn ERROR_FAIL;\n\t}\n\ttarget = k_chip->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tresult = kinetis_read_pmstat(k_chip, &pmstat);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (pmstat == PM_STAT_RUN)\n\t\treturn ERROR_OK;\n\n\tif (pmstat == PM_STAT_VLPR) {\n\t\t/* It is safe to switch from VLPR to RUN mode without changing clock */\n\t\tLOG_INFO(\"Switching from VLPR to RUN mode.\");\n\n\t\tswitch (k_chip->sysmodectrlr_type) {\n\t\tcase KINETIS_SMC:\n\t\t\tresult = target_write_u8(target, SMC_PMCTRL, PM_CTRL_RUNM_RUN);\n\t\t\tbreak;\n\n\t\tcase KINETIS_SMC32:\n\t\t\tresult = target_write_u32(target, SMC32_PMCTRL, PM_CTRL_RUNM_RUN);\n\t\t\tbreak;\n\n\t\tcase KINETIS_MC:\n\t\t\tresult = target_write_u32(target, MC_PMCTRL, PM_CTRL_RUNM_RUN);\n\t\t\tbreak;\n\t\t}\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tfor (unsigned int i = 100; i > 0; i--) {\n\t\t\tresult = kinetis_read_pmstat(k_chip, &pmstat);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\n\t\t\tif (pmstat == PM_STAT_RUN)\n\t\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"Flash operation not possible in current run mode: SMC_PMSTAT: 0x%x\", pmstat);\n\tLOG_ERROR(\"Issue a 'reset init' command.\");\n\treturn ERROR_TARGET_NOT_HALTED;\n}\n\n\nstatic void kinetis_invalidate_flash_cache(struct kinetis_chip *k_chip)\n{\n\tstruct target *target = k_chip->target;\n\n\tswitch (k_chip->cache_type) {\n\tcase KINETIS_CACHE_K:\n\t\ttarget_write_u8(target, FMC_PFB01CR + 2, 0xf0);\n\t\t/* Set CINV_WAY bits - request invalidate of all cache ways */\n\t\t/* FMC_PFB0CR has same address and CINV_WAY bits as FMC_PFB01CR */\n\t\tbreak;\n\n\tcase KINETIS_CACHE_L:\n\t\ttarget_write_u8(target, MCM_PLACR + 1, 0x04);\n\t\t/* set bit CFCC - Clear Flash Controller Cache */\n\t\tbreak;\n\n\tcase KINETIS_CACHE_MSCM:\n\t\ttarget_write_u32(target, MSCM_OCMDR0, 0x30);\n\t\t/* disable data prefetch and flash speculate */\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\n\nstatic int kinetis_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint result;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\n\tresult = kinetis_check_run_mode(k_chip);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* reset error flags */\n\tresult = kinetis_ftfx_prepare(bank->target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif ((first > bank->num_sectors) || (last > bank->num_sectors))\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/*\n\t * FIXME: TODO: use the 'Erase Flash Block' command if the\n\t * requested erase is PFlash or NVM and encompasses the entire\n\t * block.  Should be quicker.\n\t */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\t/* set command and sector address */\n\t\tresult = kinetis_ftfx_command(bank->target, FTFX_CMD_SECTERASE, k_bank->prog_base + bank->sectors[i].offset,\n\t\t\t\t0, 0, 0, 0,  0, 0, 0, 0,  NULL);\n\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_WARNING(\"erase sector %u failed\", i);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tif (k_bank->prog_base == 0\n\t\t\t&& bank->sectors[i].offset <= FCF_ADDRESS\n\t\t\t&& bank->sectors[i].offset + bank->sectors[i].size > FCF_ADDRESS + FCF_SIZE) {\n\t\t\tif (allow_fcf_writes) {\n\t\t\t\tLOG_WARNING(\"Flash Configuration Field erased, DO NOT reset or power off the device\");\n\t\t\t\tLOG_WARNING(\"until correct FCF is programmed or MCU gets security lock.\");\n\t\t\t} else {\n\t\t\t\tuint8_t fcf_buffer[FCF_SIZE];\n\n\t\t\t\tkinetis_fill_fcf(bank, fcf_buffer);\n\t\t\t\tresult = kinetis_write_inner(bank, fcf_buffer, FCF_ADDRESS, FCF_SIZE);\n\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\tLOG_WARNING(\"Flash Configuration Field write failed\");\n\t\t\t\telse\n\t\t\t\t\tLOG_DEBUG(\"Generated FCF written\");\n\t\t\t}\n\t\t}\n\t}\n\n\tkinetis_invalidate_flash_cache(k_bank->k_chip);\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_make_ram_ready(struct target *target)\n{\n\tint result;\n\tuint8_t ftfx_fcnfg;\n\n\t/* check if ram ready */\n\tresult = target_read_u8(target, FTFX_FCNFG, &ftfx_fcnfg);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (ftfx_fcnfg & (1 << 1))\n\t\treturn ERROR_OK;\t/* ram ready */\n\n\t/* make flex ram available */\n\tresult = kinetis_ftfx_command(target, FTFX_CMD_SETFLEXRAM, 0x00ff0000,\n\t\t\t\t 0, 0, 0, 0,  0, 0, 0, 0,  NULL);\n\tif (result != ERROR_OK)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* check again */\n\tresult = target_read_u8(target, FTFX_FCNFG, &ftfx_fcnfg);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (ftfx_fcnfg & (1 << 1))\n\t\treturn ERROR_OK;\t/* ram ready */\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n\nstatic int kinetis_write_sections(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t uint32_t offset, uint32_t count)\n{\n\tint result = ERROR_OK;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\tuint8_t *buffer_aligned = NULL;\n\t/*\n\t * Kinetis uses different terms for the granularity of\n\t * sector writes, e.g. \"phrase\" or \"128 bits\".  We use\n\t * the generic term \"chunk\". The largest possible\n\t * Kinetis \"chunk\" is 16 bytes (128 bits).\n\t */\n\tuint32_t prog_section_chunk_bytes = k_bank->sector_size >> 8;\n\tuint32_t prog_size_bytes = k_chip->max_flash_prog_size;\n\n\twhile (count > 0) {\n\t\tuint32_t size = prog_size_bytes - offset % prog_size_bytes;\n\t\tuint32_t align_begin = offset % prog_section_chunk_bytes;\n\t\tuint32_t align_end;\n\t\tuint32_t size_aligned;\n\t\tuint16_t chunk_count;\n\t\tuint8_t ftfx_fstat;\n\n\t\tif (size > count)\n\t\t\tsize = count;\n\n\t\talign_end = (align_begin + size) % prog_section_chunk_bytes;\n\t\tif (align_end)\n\t\t\talign_end = prog_section_chunk_bytes - align_end;\n\n\t\tsize_aligned = align_begin + size + align_end;\n\t\tchunk_count = size_aligned / prog_section_chunk_bytes;\n\n\t\tif (size != size_aligned) {\n\t\t\t/* aligned section: the first, the last or the only */\n\t\t\tif (!buffer_aligned)\n\t\t\t\tbuffer_aligned = malloc(prog_size_bytes);\n\n\t\t\tmemset(buffer_aligned, 0xff, size_aligned);\n\t\t\tmemcpy(buffer_aligned + align_begin, buffer, size);\n\n\t\t\tresult = target_write_memory(bank->target, k_chip->progr_accel_ram,\n\t\t\t\t\t\t4, size_aligned / 4, buffer_aligned);\n\n\t\t\tLOG_DEBUG(\"section @ \" TARGET_ADDR_FMT \" aligned begin %\" PRIu32\n\t\t\t\t\t\", end %\" PRIu32,\n\t\t\t\t\tbank->base + offset, align_begin, align_end);\n\t\t} else\n\t\t\tresult = target_write_memory(bank->target, k_chip->progr_accel_ram,\n\t\t\t\t\t\t4, size_aligned / 4, buffer);\n\n\t\tLOG_DEBUG(\"write section @ \" TARGET_ADDR_FMT \" with length %\" PRIu32\n\t\t\t\t\" bytes\",\n\t\t\t  bank->base + offset, size);\n\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"target_write_memory failed\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* execute section-write command */\n\t\tresult = kinetis_ftfx_command(bank->target, FTFX_CMD_SECTWRITE,\n\t\t\t\tk_bank->prog_base + offset - align_begin,\n\t\t\t\tchunk_count>>8, chunk_count, 0, 0,\n\t\t\t\t0, 0, 0, 0,  &ftfx_fstat);\n\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error writing section at \" TARGET_ADDR_FMT,\n\t\t\t\t\tbank->base + offset);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ftfx_fstat & 0x01) {\n\t\t\tLOG_ERROR(\"Flash write error at \" TARGET_ADDR_FMT,\n\t\t\t\t\tbank->base + offset);\n\t\t\tif (k_bank->prog_base == 0 && offset == FCF_ADDRESS + FCF_SIZE\n\t\t\t\t\t&& (k_chip->flash_support & FS_WIDTH_256BIT)) {\n\t\t\t\tLOG_ERROR(\"Flash write immediately after the end of Flash Config Field shows error\");\n\t\t\t\tLOG_ERROR(\"because the flash memory is 256 bits wide (data were written correctly).\");\n\t\t\t\tLOG_ERROR(\"Either change the linker script to add a gap of 16 bytes after FCF\");\n\t\t\t\tLOG_ERROR(\"or set 'kinetis fcf_source write'\");\n\t\t\t}\n\t\t}\n\n\t\tbuffer += size;\n\t\toffset += size;\n\t\tcount -= size;\n\n\t\tkeep_alive();\n\t}\n\n\tfree(buffer_aligned);\n\treturn result;\n}\n\n\nstatic int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t uint32_t offset, uint32_t count)\n{\n\tint result;\n\tbool fallback = false;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\n\tif (!(k_chip->flash_support & FS_PROGRAM_SECTOR)) {\n\t\t/* fallback to longword write */\n\t\tfallback = true;\n\t\tLOG_INFO(\"This device supports Program Longword execution only.\");\n\t} else {\n\t\tresult = kinetis_make_ram_ready(bank->target);\n\t\tif (result != ERROR_OK) {\n\t\t\tfallback = true;\n\t\t\tLOG_WARNING(\"FlexRAM not ready, fallback to slow longword write.\");\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"flash write @ \" TARGET_ADDR_FMT, bank->base + offset);\n\n\tif (!fallback) {\n\t\t/* program section command */\n\t\tkinetis_write_sections(bank, buffer, offset, count);\n\t} else if (k_chip->flash_support & FS_PROGRAM_LONGWORD) {\n\t\t/* program longword command, not supported in FTFE */\n\t\tuint8_t *new_buffer = NULL;\n\n\t\t/* check word alignment */\n\t\tif (offset & 0x3) {\n\t\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks the required alignment\", offset);\n\t\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t\t}\n\n\t\tif (count & 0x3) {\n\t\t\tuint32_t old_count = count;\n\t\t\tcount = (old_count | 3) + 1;\n\t\t\tnew_buffer = malloc(count);\n\t\t\tif (!new_buffer) {\n\t\t\t\tLOG_ERROR(\"odd number of bytes to write and no memory \"\n\t\t\t\t\t\"for padding buffer\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tLOG_INFO(\"odd number of bytes to write (%\" PRIu32 \"), extending to %\" PRIu32 \" \"\n\t\t\t\t\"and padding with 0xff\", old_count, count);\n\t\t\tmemset(new_buffer + old_count, 0xff, count - old_count);\n\t\t\tbuffer = memcpy(new_buffer, buffer, old_count);\n\t\t}\n\n\t\tuint32_t words_remaining = count / 4;\n\n\t\tkinetis_disable_wdog(k_chip);\n\n\t\t/* try using a block write */\n\t\tresult = kinetis_write_block(bank, buffer, offset, words_remaining);\n\n\t\tif (result == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t * we use normal (slow) single word accesses */\n\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single \"\n\t\t\t\t\"memory accesses\");\n\n\t\t\twhile (words_remaining) {\n\t\t\t\tuint8_t ftfx_fstat;\n\n\t\t\t\tLOG_DEBUG(\"write longword @ %08\" PRIx32, (uint32_t)(bank->base + offset));\n\n\t\t\t\tresult = kinetis_ftfx_command(bank->target, FTFX_CMD_LWORDPROG, k_bank->prog_base + offset,\n\t\t\t\t\t\tbuffer[3], buffer[2], buffer[1], buffer[0],\n\t\t\t\t\t\t0, 0, 0, 0,  &ftfx_fstat);\n\n\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Error writing longword at \" TARGET_ADDR_FMT,\n\t\t\t\t\t\t\tbank->base + offset);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (ftfx_fstat & 0x01)\n\t\t\t\t\tLOG_ERROR(\"Flash write error at \" TARGET_ADDR_FMT,\n\t\t\t\t\t\t\tbank->base + offset);\n\n\t\t\t\tbuffer += 4;\n\t\t\t\toffset += 4;\n\t\t\t\twords_remaining--;\n\n\t\t\t\tkeep_alive();\n\t\t\t}\n\t\t}\n\t\tfree(new_buffer);\n\t} else {\n\t\tLOG_ERROR(\"Flash write strategy not implemented\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tkinetis_invalidate_flash_cache(k_chip);\n\treturn result;\n}\n\n\nstatic int kinetis_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t uint32_t offset, uint32_t count)\n{\n\tint result;\n\tbool set_fcf = false;\n\tbool fcf_in_data_valid = false;\n\tbool fcf_differs = false;\n\tint sect = 0;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\tuint8_t fcf_buffer[FCF_SIZE];\n\tuint8_t fcf_current[FCF_SIZE];\n\tuint8_t fcf_in_data[FCF_SIZE];\n\n\tresult = kinetis_check_run_mode(k_chip);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* reset error flags */\n\tresult = kinetis_ftfx_prepare(bank->target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (k_bank->prog_base == 0 && !allow_fcf_writes) {\n\t\tif (bank->sectors[1].offset <= FCF_ADDRESS)\n\t\t\tsect = 1;\t/* 1kb sector, FCF in 2nd sector */\n\n\t\tif (offset < bank->sectors[sect].offset + bank->sectors[sect].size\n\t\t\t&& offset + count > bank->sectors[sect].offset)\n\t\t\tset_fcf = true; /* write to any part of sector with FCF */\n\t}\n\n\tif (set_fcf) {\n\t\tkinetis_fill_fcf(bank, fcf_buffer);\n\n\t\tfcf_in_data_valid = offset <= FCF_ADDRESS\n\t\t\t\t\t && offset + count >= FCF_ADDRESS + FCF_SIZE;\n\t\tif (fcf_in_data_valid) {\n\t\t\tmemcpy(fcf_in_data, buffer + FCF_ADDRESS - offset, FCF_SIZE);\n\t\t\tif (memcmp(fcf_in_data, fcf_buffer, 8)) {\n\t\t\t\tfcf_differs = true;\n\t\t\t\tLOG_INFO(\"Setting of backdoor key is not supported in mode 'kinetis fcf_source protection'.\");\n\t\t\t}\n\t\t\tif (memcmp(fcf_in_data + FCF_FPROT, fcf_buffer + FCF_FPROT, 4)) {\n\t\t\t\tfcf_differs = true;\n\t\t\t\tLOG_INFO(\"Flash protection requested in the programmed file differs from current setting.\");\n\t\t\t}\n\t\t\tif (fcf_in_data[FCF_FDPROT] != fcf_buffer[FCF_FDPROT]) {\n\t\t\t\tfcf_differs = true;\n\t\t\t\tLOG_INFO(\"Data flash protection requested in the programmed file differs from current setting.\");\n\t\t\t}\n\t\t\tif ((fcf_in_data[FCF_FSEC] & 3) != 2) {\n\t\t\t\tfcf_in_data_valid = false;\n\t\t\t\tLOG_INFO(\"Device security requested in the programmed file! Write denied.\");\n\t\t\t} else if (fcf_in_data[FCF_FSEC] != fcf_buffer[FCF_FSEC]) {\n\t\t\t\tfcf_differs = true;\n\t\t\t\tLOG_INFO(\"Strange unsecure mode 0x%02\" PRIx8\n\t\t\t\t\t\" requested in the programmed file, set FSEC = 0x%02\" PRIx8\n\t\t\t\t\t\" in the startup code!\",\n\t\t\t\t\tfcf_in_data[FCF_FSEC], fcf_buffer[FCF_FSEC]);\n\t\t\t}\n\t\t\tif (fcf_in_data[FCF_FOPT] != fcf_buffer[FCF_FOPT]) {\n\t\t\t\tfcf_differs = true;\n\t\t\t\tLOG_INFO(\"FOPT requested in the programmed file differs from current setting, set 'kinetis fopt 0x%02\"\n\t\t\t\t\tPRIx8 \"'.\", fcf_in_data[FCF_FOPT]);\n\t\t\t}\n\n\t\t\t/* If the device has ECC flash, then we cannot re-program FCF */\n\t\t\tif (fcf_differs) {\n\t\t\t\tif (k_chip->flash_support & FS_ECC) {\n\t\t\t\t\tfcf_in_data_valid = false;\n\t\t\t\t\tLOG_INFO(\"Cannot re-program FCF. Expect verify errors at FCF (0x400-0x40f).\");\n\t\t\t\t} else {\n\t\t\t\t\tLOG_INFO(\"Trying to re-program FCF.\");\n\t\t\t\t\tif (!(k_chip->flash_support & FS_PROGRAM_LONGWORD))\n\t\t\t\t\t\tLOG_INFO(\"Flash re-programming may fail on this device!\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (set_fcf && !fcf_in_data_valid) {\n\t\tif (offset < FCF_ADDRESS) {\n\t\t\t/* write part preceding FCF */\n\t\t\tresult = kinetis_write_inner(bank, buffer, offset, FCF_ADDRESS - offset);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t}\n\n\t\tresult = target_read_memory(bank->target, bank->base + FCF_ADDRESS, 4, FCF_SIZE / 4, fcf_current);\n\t\tif (result == ERROR_OK && memcmp(fcf_current, fcf_buffer, FCF_SIZE) == 0)\n\t\t\tset_fcf = false;\n\n\t\tif (set_fcf) {\n\t\t\t/* write FCF if differs from flash - eliminate multiple writes */\n\t\t\tresult = kinetis_write_inner(bank, fcf_buffer, FCF_ADDRESS, FCF_SIZE);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t}\n\n\t\tLOG_WARNING(\"Flash Configuration Field written.\");\n\t\tLOG_WARNING(\"Reset or power off the device to make settings effective.\");\n\n\t\tif (offset + count > FCF_ADDRESS + FCF_SIZE) {\n\t\t\tuint32_t delta = FCF_ADDRESS + FCF_SIZE - offset;\n\t\t\t/* write part after FCF */\n\t\t\tresult = kinetis_write_inner(bank, buffer + delta, FCF_ADDRESS + FCF_SIZE, count - delta);\n\t\t}\n\t\treturn result;\n\n\t} else {\n\t\t/* no FCF fiddling, normal write */\n\t\treturn kinetis_write_inner(bank, buffer, offset, count);\n\t}\n}\n\n\nstatic int kinetis_probe_chip(struct kinetis_chip *k_chip)\n{\n\tint result;\n\tuint8_t fcfg1_nvmsize, fcfg1_pfsize, fcfg1_eesize, fcfg1_depart;\n\tuint8_t fcfg2_pflsh;\n\tuint32_t ee_size = 0;\n\tuint32_t pflash_size_k, nvm_size_k, dflash_size_k;\n\tuint32_t pflash_size_m;\n\tunsigned num_blocks = 0;\n\tunsigned maxaddr_shift = 13;\n\tstruct target *target = k_chip->target;\n\n\tunsigned familyid = 0, subfamid = 0;\n\tunsigned cpu_mhz = 120;\n\tbool use_nvm_marking = false;\n\tchar flash_marking[12], nvm_marking[2];\n\tchar name[40];\n\n\tk_chip->probed = false;\n\tk_chip->pflash_sector_size = 0;\n\tk_chip->pflash_base = 0;\n\tk_chip->nvm_base = 0x10000000;\n\tk_chip->progr_accel_ram = FLEXRAM;\n\n\tname[0] = '\\0';\n\n\tif (k_chip->sim_base)\n\t\tresult = target_read_u32(target, k_chip->sim_base + SIM_SDID_OFFSET, &k_chip->sim_sdid);\n\telse {\n\t\tresult = target_read_u32(target, SIM_BASE + SIM_SDID_OFFSET, &k_chip->sim_sdid);\n\t\tif (result == ERROR_OK)\n\t\t\tk_chip->sim_base = SIM_BASE;\n\t\telse {\n\t\t\tresult = target_read_u32(target, SIM_BASE_KL28 + SIM_SDID_OFFSET, &k_chip->sim_sdid);\n\t\t\tif (result == ERROR_OK)\n\t\t\t\tk_chip->sim_base = SIM_BASE_KL28;\n\t\t}\n\t}\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif ((k_chip->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {\n\t\t/* older K-series MCU */\n\t\tuint32_t mcu_type = k_chip->sim_sdid & KINETIS_K_SDID_TYPE_MASK;\n\t\tk_chip->cache_type = KINETIS_CACHE_K;\n\t\tk_chip->watchdog_type = KINETIS_WDOG_K;\n\n\t\tswitch (mcu_type) {\n\t\tcase KINETIS_K_SDID_K10_M50:\n\t\tcase KINETIS_K_SDID_K20_M50:\n\t\t\t/* 1kB sectors */\n\t\t\tk_chip->pflash_sector_size = 1<<10;\n\t\t\tk_chip->nvm_sector_size = 1<<10;\n\t\t\tnum_blocks = 2;\n\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;\n\t\t\tbreak;\n\t\tcase KINETIS_K_SDID_K10_M72:\n\t\tcase KINETIS_K_SDID_K20_M72:\n\t\tcase KINETIS_K_SDID_K30_M72:\n\t\tcase KINETIS_K_SDID_K30_M100:\n\t\tcase KINETIS_K_SDID_K40_M72:\n\t\tcase KINETIS_K_SDID_K40_M100:\n\t\tcase KINETIS_K_SDID_K50_M72:\n\t\t\t/* 2kB sectors, 1kB FlexNVM sectors */\n\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\tk_chip->nvm_sector_size = 1<<10;\n\t\t\tnum_blocks = 2;\n\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;\n\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\tbreak;\n\t\tcase KINETIS_K_SDID_K10_M100:\n\t\tcase KINETIS_K_SDID_K20_M100:\n\t\tcase KINETIS_K_SDID_K11:\n\t\tcase KINETIS_K_SDID_K12:\n\t\tcase KINETIS_K_SDID_K21_M50:\n\t\tcase KINETIS_K_SDID_K22_M50:\n\t\tcase KINETIS_K_SDID_K51_M72:\n\t\tcase KINETIS_K_SDID_K53:\n\t\tcase KINETIS_K_SDID_K60_M100:\n\t\t\t/* 2kB sectors */\n\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\tk_chip->nvm_sector_size = 2<<10;\n\t\t\tnum_blocks = 2;\n\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;\n\t\t\tbreak;\n\t\tcase KINETIS_K_SDID_K21_M120:\n\t\tcase KINETIS_K_SDID_K22_M120:\n\t\t\t/* 4kB sectors (MK21FN1M0, MK21FX512, MK22FN1M0, MK22FX512) */\n\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\tk_chip->nvm_sector_size = 4<<10;\n\t\t\tnum_blocks = 2;\n\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\tbreak;\n\t\tcase KINETIS_K_SDID_K10_M120:\n\t\tcase KINETIS_K_SDID_K20_M120:\n\t\tcase KINETIS_K_SDID_K60_M150:\n\t\tcase KINETIS_K_SDID_K70_M150:\n\t\t\t/* 4kB sectors */\n\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\tk_chip->nvm_sector_size = 4<<10;\n\t\t\tnum_blocks = 4;\n\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported K-family FAMID\");\n\t\t}\n\n\t\tfor (size_t idx = 0; idx < ARRAY_SIZE(kinetis_types_old); idx++) {\n\t\t\tif (kinetis_types_old[idx].sdid == mcu_type) {\n\t\t\t\tstrcpy(name, kinetis_types_old[idx].name);\n\t\t\t\tuse_nvm_marking = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* first revision of some devices has no SMC */\n\t\tswitch (mcu_type) {\n\t\tcase KINETIS_K_SDID_K10_M100:\n\t\tcase KINETIS_K_SDID_K20_M100:\n\t\tcase KINETIS_K_SDID_K30_M100:\n\t\tcase KINETIS_K_SDID_K40_M100:\n\t\tcase KINETIS_K_SDID_K60_M100:\n\t\t\t{\n\t\t\t\tuint32_t revid = (k_chip->sim_sdid & KINETIS_K_REVID_MASK) >> KINETIS_K_REVID_SHIFT;\n\t\t\t\t /* highest bit set corresponds to rev 2.x */\n\t\t\t\tif (revid <= 7) {\n\t\t\t\t\tk_chip->sysmodectrlr_type = KINETIS_MC;\n\t\t\t\t\tstrcat(name, \" Rev 1.x\");\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t} else {\n\t\t/* Newer K-series or KL series MCU */\n\t\tfamilyid = (k_chip->sim_sdid & KINETIS_SDID_FAMILYID_MASK) >> KINETIS_SDID_FAMILYID_SHIFT;\n\t\tsubfamid = (k_chip->sim_sdid & KINETIS_SDID_SUBFAMID_MASK) >> KINETIS_SDID_SUBFAMID_SHIFT;\n\n\t\tswitch (k_chip->sim_sdid & KINETIS_SDID_SERIESID_MASK) {\n\t\tcase KINETIS_SDID_SERIESID_K:\n\t\t\tuse_nvm_marking = true;\n\t\t\tk_chip->cache_type = KINETIS_CACHE_K;\n\t\t\tk_chip->watchdog_type = KINETIS_WDOG_K;\n\n\t\t\tswitch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {\n\t\t\tcase KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2:\n\t\t\t\t/* K02FN64, K02FN128: FTFA, 2kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tcpu_mhz = 100;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX2: {\n\t\t\t\t/* MK24FN1M reports as K22, this should detect it (according to errata note 1N83J) */\n\t\t\t\tuint32_t sopt1;\n\t\t\t\tresult = target_read_u32(target, k_chip->sim_base + SIM_SOPT1_OFFSET, &sopt1);\n\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\treturn result;\n\n\t\t\t\tif (((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN1M) &&\n\t\t\t\t\t\t((sopt1 & KINETIS_SOPT1_RAMSIZE_MASK) == KINETIS_SOPT1_RAMSIZE_K24FN1M)) {\n\t\t\t\t\t/* MK24FN1M */\n\t\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\t\tnum_blocks = 2;\n\t\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\t\tsubfamid = 4; /* errata 1N83J fix */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN128\n\t\t\t\t\t|| (k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN256\n\t\t\t\t\t|| (k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K22FN512) {\n\t\t\t\t\t/* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */\n\t\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\t\t/* autodetect 1 or 2 blocks */\n\t\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tLOG_ERROR(\"Unsupported Kinetis K22 DIEID\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX4:\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tif ((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {\n\t\t\t\t\t/* K24FN256 - smaller pflash with FTFA */\n\t\t\t\t\tnum_blocks = 1;\n\t\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* K24FN1M without errata 7534 */\n\t\t\t\tnum_blocks = 2;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX1:\t/* errata 7534 - should be K63 */\n\t\t\tcase KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX2:\t/* errata 7534 - should be K64 */\n\t\t\t\tsubfamid += 2; /* errata 7534 fix */\n\t\t\t\t/* fallthrough */\n\t\t\tcase KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX3:\n\t\t\t\t/* K63FN1M0 */\n\t\t\tcase KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX4:\n\t\t\t\t/* K64FN1M0, K64FX512 */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tk_chip->nvm_sector_size = 4<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tnum_blocks = 2;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:\n\t\t\t\t/* K26FN2M0 */\n\t\t\tcase KINETIS_SDID_FAMILYID_K6X | KINETIS_SDID_SUBFAMID_KX6:\n\t\t\t\t/* K66FN2M0, K66FX1M0 */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tk_chip->nvm_sector_size = 4<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tnum_blocks = 4;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_ECC;\n\t\t\t\tcpu_mhz = 180;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX7:\n\t\t\t\t/* K27FN2M0 */\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX8:\n\t\t\t\t/* K28FN2M0 */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tnum_blocks = 4;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_ECC;\n\t\t\t\tcpu_mhz = 150;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\tcase KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\tcase KINETIS_SDID_FAMILYID_K8X | KINETIS_SDID_SUBFAMID_KX2:\n\t\t\t\t/* K80FN256, K81FN256, K82FN256 */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;\n\t\t\t\tcpu_mhz = 150;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_KL8X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\tcase KINETIS_SDID_FAMILYID_KL8X | KINETIS_SDID_SUBFAMID_KX2:\n\t\t\t\t/* KL81Z128, KL82Z128 */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\n\t\t\t\tuse_nvm_marking = false;\n\t\t\t\tsnprintf(name, sizeof(name), \"MKL8%uZ%%s7\",\n\t\t\t\t\t subfamid);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported Kinetis FAMILYID SUBFAMID\");\n\t\t\t}\n\n\t\t\tif (name[0] == '\\0')\n\t\t\t\tsnprintf(name, sizeof(name), \"MK%u%uF%%s%u\",\n\t\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\tbreak;\n\n\t\tcase KINETIS_SDID_SERIESID_KL:\n\t\t\t/* KL-series */\n\t\t\tk_chip->pflash_sector_size = 1<<10;\n\t\t\tk_chip->nvm_sector_size = 1<<10;\n\t\t\t/* autodetect 1 or 2 blocks */\n\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\t\t\tk_chip->watchdog_type = KINETIS_WDOG_COP;\n\n\t\t\tcpu_mhz = 48;\n\t\t\tswitch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX3:\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX3:\n\t\t\t\tsubfamid = 7;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX8:\n\t\t\t\tcpu_mhz = 72;\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tnum_blocks = 2;\n\t\t\t\tk_chip->watchdog_type = KINETIS_WDOG32_KL28;\n\t\t\t\tk_chip->sysmodectrlr_type = KINETIS_SMC32;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tsnprintf(name, sizeof(name), \"MKL%u%uZ%%s%u\",\n\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\tbreak;\n\n\t\tcase KINETIS_SDID_SERIESID_KW:\n\t\t\t/* Newer KW-series (all KW series except KW2xD, KW01Z) */\n\t\t\tcpu_mhz = 48;\n\t\t\tswitch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {\n\t\t\tcase KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\t\t/* KW40Z */\n\t\t\tcase KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\t\t/* KW30Z */\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\t\t/* KW20Z */\n\t\t\t\t/* FTFA, 1kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 1<<10;\n\t\t\t\tk_chip->nvm_sector_size = 1<<10;\n\t\t\t\t/* autodetect 1 or 2 blocks */\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\t\t\t\tk_chip->watchdog_type = KINETIS_WDOG_COP;\n\t\t\t\tbreak;\n\t\t\tcase KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\t\t/* KW41Z */\n\t\t\tcase KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\t\t/* KW31Z */\n\t\t\tcase KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\t\t/* KW21Z */\n\t\t\t\t/* FTFA, 2kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tk_chip->nvm_sector_size = 2<<10;\n\t\t\t\t/* autodetect 1 or 2 blocks */\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\t\t\t\tk_chip->watchdog_type = KINETIS_WDOG_COP;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported KW FAMILYID SUBFAMID\");\n\t\t\t}\n\t\t\tsnprintf(name, sizeof(name), \"MKW%u%uZ%%s%u\",\n\t\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\tbreak;\n\n\t\tcase KINETIS_SDID_SERIESID_KV:\n\t\t\t/* KV-series */\n\t\t\tk_chip->watchdog_type = KINETIS_WDOG_K;\n\t\t\tswitch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\t\t/* KV10: FTFA, 1kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 1<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\t\t\t\tstrcpy(name, \"MKV10Z%s7\");\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\t\t/* KV11: FTFA, 2kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\t\t\t\tstrcpy(name, \"MKV11Z%s7\");\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX0:\n\t\t\t\t/* KV30: FTFA, 2kB sectors, 1 block */\n\t\t\tcase KINETIS_SDID_FAMILYID_K3X | KINETIS_SDID_SUBFAMID_KX1:\n\t\t\t\t/* KV31: FTFA, 2kB sectors, 2 blocks */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\t/* autodetect 1 or 2 blocks */\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_K;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:\n\t\t\tcase KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX4:\n\t\t\tcase KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX6:\n\t\t\t\t/* KV4x: FTFA, 4kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_LONGWORD;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_K;\n\t\t\t\tcpu_mhz = 168;\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX6:\n\t\t\tcase KINETIS_SDID_FAMILYID_K5X | KINETIS_SDID_SUBFAMID_KX8:\n\t\t\t\t/* KV5x: FTFE, 8kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 8<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tnum_blocks = 1;\n\t\t\t\tmaxaddr_shift = 14;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_WIDTH_256BIT | FS_ECC;\n\t\t\t\tk_chip->pflash_base = 0x10000000;\n\t\t\t\tk_chip->progr_accel_ram = 0x18000000;\n\t\t\t\tcpu_mhz = 240;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported KV FAMILYID SUBFAMID\");\n\t\t\t}\n\n\t\t\tif (name[0] == '\\0')\n\t\t\t\tsnprintf(name, sizeof(name), \"MKV%u%uF%%s%u\",\n\t\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\tbreak;\n\n\t\tcase KINETIS_SDID_SERIESID_KE:\n\t\t\t/* KE1x-series */\n\t\t\tk_chip->watchdog_type = KINETIS_WDOG32_KE1X;\n\t\t\tswitch (k_chip->sim_sdid &\n\t\t\t\t(KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK | KINETIS_SDID_PROJECTID_MASK)) {\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1XZ:\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX5 | KINETIS_SDID_PROJECTID_KE1XZ:\n\t\t\t\t/* KE1xZ: FTFE, 2kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 2<<10;\n\t\t\t\tk_chip->nvm_sector_size = 2<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<9;\n\t\t\t\tnum_blocks = 2;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_L;\n\n\t\t\t\tcpu_mhz = 72;\n\t\t\t\tsnprintf(name, sizeof(name), \"MKE%u%uZ%%s%u\",\n\t\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\t\tbreak;\n\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1XF:\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX6 | KINETIS_SDID_PROJECTID_KE1XF:\n\t\t\tcase KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX8 | KINETIS_SDID_PROJECTID_KE1XF:\n\t\t\t\t/* KE1xF: FTFE, 4kB sectors */\n\t\t\t\tk_chip->pflash_sector_size = 4<<10;\n\t\t\t\tk_chip->nvm_sector_size = 2<<10;\n\t\t\t\tk_chip->max_flash_prog_size = 1<<10;\n\t\t\t\tnum_blocks = 2;\n\t\t\t\tk_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;\n\t\t\t\tk_chip->cache_type = KINETIS_CACHE_MSCM;\n\n\t\t\t\tcpu_mhz = 168;\n\t\t\t\tsnprintf(name, sizeof(name), \"MKE%u%uF%%s%u\",\n\t\t\t\t\t familyid, subfamid, cpu_mhz / 10);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported KE FAMILYID SUBFAMID\");\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported K-series\");\n\t\t}\n\t}\n\n\tif (k_chip->pflash_sector_size == 0) {\n\t\tLOG_ERROR(\"MCU is unsupported, SDID 0x%08\" PRIx32, k_chip->sim_sdid);\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tresult = target_read_u32(target, k_chip->sim_base + SIM_FCFG1_OFFSET, &k_chip->sim_fcfg1);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tresult = target_read_u32(target, k_chip->sim_base + SIM_FCFG2_OFFSET, &k_chip->sim_fcfg2);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tLOG_DEBUG(\"SDID: 0x%08\" PRIX32 \" FCFG1: 0x%08\" PRIX32 \" FCFG2: 0x%08\" PRIX32, k_chip->sim_sdid,\n\t\t\tk_chip->sim_fcfg1, k_chip->sim_fcfg2);\n\n\tfcfg1_nvmsize = (uint8_t)((k_chip->sim_fcfg1 >> 28) & 0x0f);\n\tfcfg1_pfsize = (uint8_t)((k_chip->sim_fcfg1 >> 24) & 0x0f);\n\tfcfg1_eesize = (uint8_t)((k_chip->sim_fcfg1 >> 16) & 0x0f);\n\tfcfg1_depart = (uint8_t)((k_chip->sim_fcfg1 >> 8) & 0x0f);\n\n\tfcfg2_pflsh = (uint8_t)((k_chip->sim_fcfg2 >> 23) & 0x01);\n\tk_chip->fcfg2_maxaddr0_shifted = ((k_chip->sim_fcfg2 >> 24) & 0x7f) << maxaddr_shift;\n\tk_chip->fcfg2_maxaddr1_shifted = ((k_chip->sim_fcfg2 >> 16) & 0x7f) << maxaddr_shift;\n\n\tif (num_blocks == 0)\n\t\tnum_blocks = k_chip->fcfg2_maxaddr1_shifted ? 2 : 1;\n\telse if (k_chip->fcfg2_maxaddr1_shifted == 0 && num_blocks >= 2 && fcfg2_pflsh) {\n\t\t/* fcfg2_maxaddr1 may be zero due to partitioning whole NVM as EEPROM backup\n\t\t * Do not adjust block count in this case! */\n\t\tnum_blocks = 1;\n\t\tLOG_WARNING(\"MAXADDR1 is zero, number of flash banks adjusted to 1\");\n\t} else if (k_chip->fcfg2_maxaddr1_shifted != 0 && num_blocks == 1) {\n\t\tnum_blocks = 2;\n\t\tLOG_WARNING(\"MAXADDR1 is non zero, number of flash banks adjusted to 2\");\n\t}\n\n\t/* when the PFLSH bit is set, there is no FlexNVM/FlexRAM */\n\tif (!fcfg2_pflsh) {\n\t\tswitch (fcfg1_nvmsize) {\n\t\tcase 0x03:\n\t\tcase 0x05:\n\t\tcase 0x07:\n\t\tcase 0x09:\n\t\tcase 0x0b:\n\t\t\tk_chip->nvm_size = 1 << (14 + (fcfg1_nvmsize >> 1));\n\t\t\tbreak;\n\t\tcase 0x0f:\n\t\t\tif (k_chip->pflash_sector_size >= 4<<10)\n\t\t\t\tk_chip->nvm_size = 512<<10;\n\t\t\telse\n\t\t\t\t/* K20_100 */\n\t\t\t\tk_chip->nvm_size = 256<<10;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tk_chip->nvm_size = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (fcfg1_eesize) {\n\t\tcase 0x00:\n\t\tcase 0x01:\n\t\tcase 0x02:\n\t\tcase 0x03:\n\t\tcase 0x04:\n\t\tcase 0x05:\n\t\tcase 0x06:\n\t\tcase 0x07:\n\t\tcase 0x08:\n\t\tcase 0x09:\n\t\t\tee_size = (16 << (10 - fcfg1_eesize));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tee_size = 0;\n\t\t\tbreak;\n\t\t}\n\n\t\tswitch (fcfg1_depart) {\n\t\tcase 0x01:\n\t\tcase 0x02:\n\t\tcase 0x03:\n\t\tcase 0x04:\n\t\tcase 0x05:\n\t\tcase 0x06:\n\t\t\tk_chip->dflash_size = k_chip->nvm_size - (4096 << fcfg1_depart);\n\t\t\tbreak;\n\t\tcase 0x07:\n\t\tcase 0x08:\n\t\t\tk_chip->dflash_size = 0;\n\t\t\tbreak;\n\t\tcase 0x09:\n\t\tcase 0x0a:\n\t\tcase 0x0b:\n\t\tcase 0x0c:\n\t\tcase 0x0d:\n\t\t\tk_chip->dflash_size = 4096 << (fcfg1_depart & 0x7);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tk_chip->dflash_size = k_chip->nvm_size;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tswitch (fcfg1_pfsize) {\n\tcase 0x00:\n\t\tk_chip->pflash_size = 8192;\n\t\tbreak;\n\tcase 0x01:\n\tcase 0x03:\n\tcase 0x05:\n\tcase 0x07:\n\tcase 0x09:\n\tcase 0x0b:\n\tcase 0x0d:\n\t\tk_chip->pflash_size = 1 << (14 + (fcfg1_pfsize >> 1));\n\t\tbreak;\n\tcase 0x0f:\n\t\t/* a peculiar case: Freescale states different sizes for 0xf\n\t\t * KL03P24M48SF0RM\t32 KB .... duplicate of code 0x3\n\t\t * K02P64M100SFARM\t128 KB ... duplicate of code 0x7\n\t\t * K22P121M120SF8RM\t256 KB ... duplicate of code 0x9\n\t\t * K22P121M120SF7RM\t512 KB ... duplicate of code 0xb\n\t\t * K22P100M120SF5RM\t1024 KB ... duplicate of code 0xd\n\t\t * K26P169M180SF5RM\t2048 KB ... the only unique value\n\t\t * fcfg2_maxaddr0 seems to be the only clue to pflash_size\n\t\t * Checking fcfg2_maxaddr0 in bank probe is pointless then\n\t\t */\n\t\tif (fcfg2_pflsh)\n\t\t\tk_chip->pflash_size = k_chip->fcfg2_maxaddr0_shifted * num_blocks;\n\t\telse\n\t\t\tk_chip->pflash_size = k_chip->fcfg2_maxaddr0_shifted * num_blocks / 2;\n\t\tif (k_chip->pflash_size != 2048<<10)\n\t\t\tLOG_WARNING(\"SIM_FCFG1 PFSIZE = 0xf: please check if pflash is %\" PRIu32 \" KB\", k_chip->pflash_size>>10);\n\n\t\tbreak;\n\tdefault:\n\t\tk_chip->pflash_size = 0;\n\t\tbreak;\n\t}\n\n\tif (k_chip->flash_support & FS_PROGRAM_SECTOR && k_chip->max_flash_prog_size == 0) {\n\t\tk_chip->max_flash_prog_size = k_chip->pflash_sector_size;\n\t\t/* Program section size is equal to sector size by default */\n\t}\n\n\tif (fcfg2_pflsh) {\n\t\tk_chip->num_pflash_blocks = num_blocks;\n\t\tk_chip->num_nvm_blocks = 0;\n\t} else {\n\t\tk_chip->num_pflash_blocks = (num_blocks + 1) / 2;\n\t\tk_chip->num_nvm_blocks = num_blocks - k_chip->num_pflash_blocks;\n\t}\n\n\tif (use_nvm_marking) {\n\t\tnvm_marking[0] = k_chip->num_nvm_blocks ? 'X' : 'N';\n\t\tnvm_marking[1] = '\\0';\n\t} else\n\t\tnvm_marking[0] = '\\0';\n\n\tpflash_size_k = k_chip->pflash_size / 1024;\n\tpflash_size_m = pflash_size_k / 1024;\n\tif (pflash_size_m)\n\t\tsnprintf(flash_marking, sizeof(flash_marking), \"%s%\" PRIu32 \"M0xxx\", nvm_marking, pflash_size_m);\n\telse\n\t\tsnprintf(flash_marking, sizeof(flash_marking), \"%s%\" PRIu32 \"xxx\", nvm_marking, pflash_size_k);\n\n\tsnprintf(k_chip->name, sizeof(k_chip->name), name, flash_marking);\n\tLOG_INFO(\"Kinetis %s detected: %u flash blocks\", k_chip->name, num_blocks);\n\tLOG_INFO(\"%u PFlash banks: %\" PRIu32 \" KiB total\", k_chip->num_pflash_blocks, pflash_size_k);\n\tif (k_chip->num_nvm_blocks) {\n\t\tnvm_size_k = k_chip->nvm_size / 1024;\n\t\tdflash_size_k = k_chip->dflash_size / 1024;\n\t\tLOG_INFO(\"%u FlexNVM banks: %\" PRIu32 \" KiB total, %\" PRIu32 \" KiB available as data flash, %\"\n\t\t\t PRIu32 \" bytes FlexRAM\", k_chip->num_nvm_blocks, nvm_size_k, dflash_size_k, ee_size);\n\t}\n\n\tk_chip->probed = true;\n\n\tif (create_banks)\n\t\tkinetis_create_missing_banks(k_chip);\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_probe(struct flash_bank *bank)\n{\n\tint result;\n\tuint8_t fcfg2_maxaddr0, fcfg2_pflsh, fcfg2_maxaddr1;\n\tunsigned num_blocks, first_nvm_bank;\n\tuint32_t size_k;\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip;\n\n\tassert(k_bank);\n\tk_chip = k_bank->k_chip;\n\n\tk_bank->probed = false;\n\n\tif (!k_chip->probed) {\n\t\tresult = kinetis_probe_chip(k_chip);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\tnum_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;\n\tfirst_nvm_bank = k_chip->num_pflash_blocks;\n\n\tif (k_bank->bank_number < k_chip->num_pflash_blocks) {\n\t\t/* pflash, banks start at address zero */\n\t\tk_bank->flash_class = FC_PFLASH;\n\t\tbank->size = (k_chip->pflash_size / k_chip->num_pflash_blocks);\n\t\tbank->base = k_chip->pflash_base + bank->size * k_bank->bank_number;\n\t\tk_bank->prog_base = 0x00000000 + bank->size * k_bank->bank_number;\n\t\tk_bank->sector_size = k_chip->pflash_sector_size;\n\t\t/* pflash is divided into 32 protection areas for\n\t\t * parts with more than 32K of PFlash. For parts with\n\t\t * less the protection unit is set to 1024 bytes */\n\t\tk_bank->protection_size = MAX(k_chip->pflash_size / 32, 1024);\n\t\tbank->num_prot_blocks = bank->size / k_bank->protection_size;\n\t\tk_bank->protection_block = bank->num_prot_blocks * k_bank->bank_number;\n\n\t\tsize_k = bank->size / 1024;\n\t\tLOG_DEBUG(\"Kinetis bank %u: %\" PRIu32 \"k PFlash, FTFx base 0x%08\" PRIx32 \", sect %\" PRIu32,\n\t\t\t k_bank->bank_number, size_k, k_bank->prog_base, k_bank->sector_size);\n\n\t} else if (k_bank->bank_number < num_blocks) {\n\t\t/* nvm, banks start at address 0x10000000 */\n\t\tunsigned nvm_ord = k_bank->bank_number - first_nvm_bank;\n\t\tuint32_t limit;\n\n\t\tk_bank->flash_class = FC_FLEX_NVM;\n\t\tbank->size = k_chip->nvm_size / k_chip->num_nvm_blocks;\n\t\tbank->base = k_chip->nvm_base + bank->size * nvm_ord;\n\t\tk_bank->prog_base = 0x00800000 + bank->size * nvm_ord;\n\t\tk_bank->sector_size = k_chip->nvm_sector_size;\n\t\tif (k_chip->dflash_size == 0) {\n\t\t\tk_bank->protection_size = 0;\n\t\t} else {\n\t\t\tint i;\n\t\t\tfor (i = k_chip->dflash_size; ~i & 1; i >>= 1)\n\t\t\t\t;\n\t\t\tif (i == 1)\n\t\t\t\tk_bank->protection_size = k_chip->dflash_size / 8;\t/* data flash size = 2^^n */\n\t\t\telse\n\t\t\t\tk_bank->protection_size = k_chip->nvm_size / 8;\t/* TODO: verify on SF1, not documented in RM */\n\t\t}\n\t\tbank->num_prot_blocks = 8 / k_chip->num_nvm_blocks;\n\t\tk_bank->protection_block = bank->num_prot_blocks * nvm_ord;\n\n\t\t/* EEPROM backup part of FlexNVM is not accessible, use dflash_size as a limit */\n\t\tif (k_chip->dflash_size > bank->size * nvm_ord)\n\t\t\tlimit = k_chip->dflash_size - bank->size * nvm_ord;\n\t\telse\n\t\t\tlimit = 0;\n\n\t\tif (bank->size > limit) {\n\t\t\tbank->size = limit;\n\t\t\tLOG_DEBUG(\"FlexNVM bank %u limited to 0x%08\" PRIx32 \" due to active EEPROM backup\",\n\t\t\t\tk_bank->bank_number, limit);\n\t\t}\n\n\t\tsize_k = bank->size / 1024;\n\t\tLOG_DEBUG(\"Kinetis bank %u: %\" PRIu32 \"k FlexNVM, FTFx base 0x%08\" PRIx32 \", sect %\" PRIu32,\n\t\t\t k_bank->bank_number, size_k, k_bank->prog_base, k_bank->sector_size);\n\n\t} else {\n\t\tLOG_ERROR(\"Cannot determine parameters for bank %u, only %u banks on device\",\n\t\t\t\tk_bank->bank_number, num_blocks);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tfcfg2_pflsh = (uint8_t)((k_chip->sim_fcfg2 >> 23) & 0x01);\n\tfcfg2_maxaddr0 = (uint8_t)((k_chip->sim_fcfg2 >> 24) & 0x7f);\n\tfcfg2_maxaddr1 = (uint8_t)((k_chip->sim_fcfg2 >> 16) & 0x7f);\n\n\tif (k_bank->bank_number == 0 && k_chip->fcfg2_maxaddr0_shifted != bank->size)\n\t\tLOG_WARNING(\"MAXADDR0 0x%02\" PRIx8 \" check failed,\"\n\t\t\t\t\" please report to OpenOCD mailing list\", fcfg2_maxaddr0);\n\n\tif (fcfg2_pflsh) {\n\t\tif (k_bank->bank_number == 1 && k_chip->fcfg2_maxaddr1_shifted != bank->size)\n\t\t\tLOG_WARNING(\"MAXADDR1 0x%02\" PRIx8 \" check failed,\"\n\t\t\t\t\" please report to OpenOCD mailing list\", fcfg2_maxaddr1);\n\t} else {\n\t\tif (k_bank->bank_number == first_nvm_bank\n\t\t\t\t&& k_chip->fcfg2_maxaddr1_shifted != k_chip->dflash_size)\n\t\t\tLOG_WARNING(\"FlexNVM MAXADDR1 0x%02\" PRIx8 \" check failed,\"\n\t\t\t\t\" please report to OpenOCD mailing list\", fcfg2_maxaddr1);\n\t}\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tfree(bank->prot_blocks);\n\tbank->prot_blocks = NULL;\n\n\tif (k_bank->sector_size == 0) {\n\t\tLOG_ERROR(\"Unknown sector size for bank %u\", bank->bank_number);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tbank->num_sectors = bank->size / k_bank->sector_size;\n\n\tif (bank->num_sectors > 0) {\n\t\t/* FlexNVM bank can be used for EEPROM backup therefore zero sized */\n\t\tbank->sectors = alloc_block_array(0, k_bank->sector_size, bank->num_sectors);\n\t\tif (!bank->sectors)\n\t\t\treturn ERROR_FAIL;\n\n\t\tbank->prot_blocks = alloc_block_array(0, k_bank->protection_size, bank->num_prot_blocks);\n\t\tif (!bank->prot_blocks)\n\t\t\treturn ERROR_FAIL;\n\n\t} else {\n\t\tbank->num_prot_blocks = 0;\n\t}\n\n\tk_bank->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_auto_probe(struct flash_bank *bank)\n{\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\n\tif (k_bank && k_bank->probed)\n\t\treturn ERROR_OK;\n\n\treturn kinetis_probe(bank);\n}\n\nstatic int kinetis_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tconst char *bank_class_names[] = {\n\t\t\"(ANY)\", \"PFlash\", \"FlexNVM\", \"FlexRAM\"\n\t};\n\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\tuint32_t size_k = bank->size / 1024;\n\n\tcommand_print_sameline(cmd,\n\t\t\"%s %s: %\" PRIu32 \"k %s bank %s at \" TARGET_ADDR_FMT,\n\t\tbank->driver->name, k_chip->name,\n\t\tsize_k, bank_class_names[k_bank->flash_class],\n\t\tbank->name, bank->base);\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_blank_check(struct flash_bank *bank)\n{\n\tstruct kinetis_flash_bank *k_bank = bank->driver_priv;\n\tstruct kinetis_chip *k_chip = k_bank->k_chip;\n\tint result;\n\n\t/* surprisingly blank check does not work in VLPR and HSRUN modes */\n\tresult = kinetis_check_run_mode(k_chip);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* reset error flags */\n\tresult = kinetis_ftfx_prepare(bank->target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (k_bank->flash_class == FC_PFLASH || k_bank->flash_class == FC_FLEX_NVM) {\n\t\tbool block_dirty = true;\n\t\tbool use_block_cmd = !(k_chip->flash_support & FS_NO_CMD_BLOCKSTAT);\n\t\tuint8_t ftfx_fstat;\n\n\t\tif (use_block_cmd && k_bank->flash_class == FC_FLEX_NVM) {\n\t\t\tuint8_t fcfg1_depart = (uint8_t)((k_chip->sim_fcfg1 >> 8) & 0x0f);\n\t\t\t/* block operation cannot be used on FlexNVM when EEPROM backup partition is set */\n\t\t\tif (fcfg1_depart != 0xf && fcfg1_depart != 0)\n\t\t\t\tuse_block_cmd = false;\n\t\t}\n\n\t\tif (use_block_cmd) {\n\t\t\t/* check if whole bank is blank */\n\t\t\tresult = kinetis_ftfx_command(bank->target, FTFX_CMD_BLOCKSTAT, k_bank->prog_base,\n\t\t\t\t\t\t\t 0, 0, 0, 0,  0, 0, 0, 0, &ftfx_fstat);\n\n\t\t\tif (result != ERROR_OK)\n\t\t\t\tkinetis_ftfx_clear_error(bank->target);\n\t\t\telse if ((ftfx_fstat & 0x01) == 0)\n\t\t\t\tblock_dirty = false;\n\t\t}\n\n\t\tif (block_dirty) {\n\t\t\t/* the whole bank is not erased, check sector-by-sector */\n\t\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\t\t/* normal margin */\n\t\t\t\tresult = kinetis_ftfx_command(bank->target, FTFX_CMD_SECTSTAT,\n\t\t\t\t\t\tk_bank->prog_base + bank->sectors[i].offset,\n\t\t\t\t\t\t1, 0, 0, 0,  0, 0, 0, 0, &ftfx_fstat);\n\n\t\t\t\tif (result == ERROR_OK) {\n\t\t\t\t\tbank->sectors[i].is_erased = !(ftfx_fstat & 0x01);\n\t\t\t\t} else {\n\t\t\t\t\tLOG_DEBUG(\"Ignoring error on PFlash sector blank-check\");\n\t\t\t\t\tkinetis_ftfx_clear_error(bank->target);\n\t\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* the whole bank is erased, update all sectors */\n\t\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\t\t\tbank->sectors[i].is_erased = 1;\n\t\t}\n\t} else {\n\t\tLOG_WARNING(\"kinetis_blank_check not supported yet for FlexRAM\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(kinetis_nvm_partition)\n{\n\tint result;\n\tunsigned bank_idx;\n\tunsigned num_blocks, first_nvm_bank;\n\tunsigned long par, log2 = 0, ee1 = 0, ee2 = 0;\n\tenum { SHOW_INFO, DF_SIZE, EEBKP_SIZE } sz_type = SHOW_INFO;\n\tbool enable;\n\tuint8_t load_flex_ram = 1;\n\tuint8_t ee_size_code = 0x3f;\n\tuint8_t flex_nvm_partition_code = 0;\n\tuint8_t ee_split = 3;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct kinetis_chip *k_chip;\n\tuint32_t sim_fcfg1;\n\n\tk_chip = kinetis_get_chip(target);\n\n\tif (CMD_ARGC >= 2) {\n\t\tif (strcmp(CMD_ARGV[0], \"dataflash\") == 0)\n\t\t\tsz_type = DF_SIZE;\n\t\telse if (strcmp(CMD_ARGV[0], \"eebkp\") == 0)\n\t\t\tsz_type = EEBKP_SIZE;\n\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[1], par);\n\t\twhile (par >> (log2 + 3))\n\t\t\tlog2++;\n\t}\n\tswitch (sz_type) {\n\tcase SHOW_INFO:\n\t\tif (!k_chip) {\n\t\t\tLOG_ERROR(\"Chip not probed.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tresult = target_read_u32(target, k_chip->sim_base + SIM_FCFG1_OFFSET, &sim_fcfg1);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tflex_nvm_partition_code = (uint8_t)((sim_fcfg1 >> 8) & 0x0f);\n\t\tswitch (flex_nvm_partition_code) {\n\t\tcase 0:\n\t\t\tcommand_print(CMD, \"No EEPROM backup, data flash only\");\n\t\t\tbreak;\n\t\tcase 1:\n\t\tcase 2:\n\t\tcase 3:\n\t\tcase 4:\n\t\tcase 5:\n\t\tcase 6:\n\t\t\tcommand_print(CMD, \"EEPROM backup %d KB\", 4 << flex_nvm_partition_code);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tcommand_print(CMD, \"No data flash, EEPROM backup only\");\n\t\t\tbreak;\n\t\tcase 0x9:\n\t\tcase 0xA:\n\t\tcase 0xB:\n\t\tcase 0xC:\n\t\tcase 0xD:\n\t\tcase 0xE:\n\t\t\tcommand_print(CMD, \"data flash %d KB\", 4 << (flex_nvm_partition_code & 7));\n\t\t\tbreak;\n\t\tcase 0xf:\n\t\t\tcommand_print(CMD, \"No EEPROM backup, data flash only (DEPART not set)\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcommand_print(CMD, \"Unsupported EEPROM backup size code 0x%02\" PRIx8, flex_nvm_partition_code);\n\t\t}\n\t\treturn ERROR_OK;\n\n\tcase DF_SIZE:\n\t\tflex_nvm_partition_code = 0x8 | log2;\n\t\tbreak;\n\n\tcase EEBKP_SIZE:\n\t\tflex_nvm_partition_code = log2;\n\t\tbreak;\n\t}\n\n\tif (CMD_ARGC == 3) {\n\t\tunsigned long eex;\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], eex);\n\t\tee1 = ee2 = eex / 2;\n\t} else if (CMD_ARGC >= 4) {\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], ee1);\n\t\tCOMMAND_PARSE_NUMBER(ulong, CMD_ARGV[3], ee2);\n\t}\n\n\tenable = ee1 + ee2 > 0;\n\tif (enable) {\n\t\tfor (log2 = 2; ; log2++) {\n\t\t\tif (ee1 + ee2 == (16u << 10) >> log2)\n\t\t\t\tbreak;\n\t\t\tif (ee1 + ee2 > (16u << 10) >> log2 || log2 >= 9) {\n\t\t\t\tLOG_ERROR(\"Unsupported EEPROM size\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t}\n\n\t\tif (ee1 * 3 == ee2)\n\t\t\tee_split = 1;\n\t\telse if (ee1 * 7 == ee2)\n\t\t\tee_split = 0;\n\t\telse if (ee1 != ee2) {\n\t\t\tLOG_ERROR(\"Unsupported EEPROM sizes ratio\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tee_size_code = log2 | ee_split << 4;\n\t}\n\n\tif (CMD_ARGC >= 5)\n\t\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[4], enable);\n\tif (enable)\n\t\tload_flex_ram = 0;\n\n\tLOG_INFO(\"DEPART 0x%\" PRIx8 \", EEPROM size code 0x%\" PRIx8,\n\t\t flex_nvm_partition_code, ee_size_code);\n\n\tresult = kinetis_check_run_mode(k_chip);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* reset error flags */\n\tresult = kinetis_ftfx_prepare(target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tresult = kinetis_ftfx_command(target, FTFX_CMD_PGMPART, load_flex_ram,\n\t\t\t\t      ee_size_code, flex_nvm_partition_code, 0, 0,\n\t\t\t\t      0, 0, 0, 0,  NULL);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tcommand_print(CMD, \"FlexNVM partition set. Please reset MCU.\");\n\n\tif (k_chip) {\n\t\tfirst_nvm_bank = k_chip->num_pflash_blocks;\n\t\tnum_blocks = k_chip->num_pflash_blocks + k_chip->num_nvm_blocks;\n\t\tfor (bank_idx = first_nvm_bank; bank_idx < num_blocks; bank_idx++)\n\t\t\tk_chip->banks[bank_idx].probed = false;\t/* re-probe before next use */\n\t\tk_chip->probed = false;\n\t}\n\n\tcommand_print(CMD, \"FlexNVM banks will be re-probed to set new data flash size.\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(kinetis_fcf_source_handler)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tif (strcmp(CMD_ARGV[0], \"write\") == 0)\n\t\t\tallow_fcf_writes = true;\n\t\telse if (strcmp(CMD_ARGV[0], \"protection\") == 0)\n\t\t\tallow_fcf_writes = false;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (allow_fcf_writes) {\n\t\tcommand_print(CMD, \"Arbitrary Flash Configuration Field writes enabled.\");\n\t\tcommand_print(CMD, \"Protection info writes to FCF disabled.\");\n\t\tLOG_WARNING(\"BEWARE: incorrect flash configuration may permanently lock the device.\");\n\t} else {\n\t\tcommand_print(CMD, \"Protection info writes to Flash Configuration Field enabled.\");\n\t\tcommand_print(CMD, \"Arbitrary FCF writes disabled. Mode safe from unwanted locking of the device.\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(kinetis_fopt_handler)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], fcf_fopt);\n\t} else {\n\t\tcommand_print(CMD, \"FCF_FOPT 0x%02\" PRIx8, fcf_fopt);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(kinetis_create_banks_handler)\n{\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcreate_banks = true;\n\n\treturn ERROR_OK;\n}\n\n\nstatic const struct command_registration kinetis_security_command_handlers[] = {\n\t{\n\t\t.name = \"check_security\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Check status of device security lock\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_check_flash_security_status,\n\t},\n\t{\n\t\t.name = \"halt\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Issue a halt via the MDM-AP\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_mdm_halt,\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Issue a complete flash erase via the MDM-AP\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_mdm_mass_erase,\n\t},\n\t{\n\t\t.name = \"reset\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Issue a reset via the MDM-AP\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_mdm_reset,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration kinetis_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mdm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"MDM-AP command group\",\n\t\t.usage = \"\",\n\t\t.chain = kinetis_security_command_handlers,\n\t},\n\t{\n\t\t.name = \"disable_wdog\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Disable the watchdog timer\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_disable_wdog_handler,\n\t},\n\t{\n\t\t.name = \"nvm_partition\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Show/set data flash or EEPROM backup size in kilobytes,\"\n\t\t\t\" set two EEPROM sizes in bytes and FlexRAM loading during reset\",\n\t\t.usage = \"('info'|'dataflash' size|'eebkp' size) [eesize1 eesize2] ['on'|'off']\",\n\t\t.handler = kinetis_nvm_partition,\n\t},\n\t{\n\t\t.name = \"fcf_source\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Use protection as a source for Flash Configuration Field or allow writing arbitrary values to the FCF\"\n\t\t\t\" Mode 'protection' is safe from unwanted locking of the device.\",\n\t\t.usage = \"['protection'|'write']\",\n\t\t.handler = kinetis_fcf_source_handler,\n\t},\n\t{\n\t\t.name = \"fopt\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"FCF_FOPT value source in 'kinetis fcf_source protection' mode\",\n\t\t.usage = \"[num]\",\n\t\t.handler = kinetis_fopt_handler,\n\t},\n\t{\n\t\t.name = \"create_banks\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Driver creates additional banks if device with two/four flash blocks is probed\",\n\t\t.handler = kinetis_create_banks_handler,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration kinetis_command_handler[] = {\n\t{\n\t\t.name = \"kinetis\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Kinetis flash controller commands\",\n\t\t.usage = \"\",\n\t\t.chain = kinetis_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\n\nconst struct flash_driver kinetis_flash = {\n\t.name = \"kinetis\",\n\t.commands = kinetis_command_handler,\n\t.flash_bank_command = kinetis_flash_bank_command,\n\t.erase = kinetis_erase,\n\t.protect = kinetis_protect,\n\t.write = kinetis_write,\n\t.read = default_flash_read,\n\t.probe = kinetis_probe,\n\t.auto_probe = kinetis_auto_probe,\n\t.erase_check = kinetis_blank_check,\n\t.protect_check = kinetis_protect_check,\n\t.info = kinetis_info,\n\t.free_driver_priv = kinetis_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/kinetis_ke.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Ivan Meleca                                     *\n *   ivan@artekit.eu                                                       *\n *                                                                         *\n *   Modified from kinetis.c                                               *\n *                                                                         *\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   kesmtp@freenet.de                                                     *\n *                                                                         *\n *   Copyright (C) 2011 sleep(5) ltd                                       *\n *   tomas@sleepfive.com                                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Christopher D. Kilgour                          *\n *   techie at whiterocker.com                                             *\n *                                                                         *\n *   Copyright (C) 2013 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   Copyright (C) 2015 Tomas Vanek                                        *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n/* Addresses */\n#define SIM_SRSID\t\t\t\t\t0x40048000\n#define ICS_C1\t\t\t\t\t\t0x40064000\n#define ICS_C2\t\t\t\t\t\t0x40064001\n#define ICS_C3\t\t\t\t\t\t0x40064002\n#define ICS_C4\t\t\t\t\t\t0x40064003\n#define ICS_S\t\t\t\t\t\t0x40064004\n#define SIM_BUSDIV\t\t\t\t\t0x40048018\n#define SIM_CLKDIV_KE06\t\t\t\t0x40048024\n#define SIM_CLKDIV_KE04_44_64_80\t0x40048024\n#define SIM_CLKDIV_KE04_16_20_24\t0x4004801C\n#define WDOG_CS1\t\t\t\t\t0x40052000\n\n#define ICS_C2_BDIV_MASK\t\t\t0xE0\n#define ICS_C2_BDIV_SHIFT\t\t\t5\n#define ICS_C2_BDIV(x)\t\t\t\t(((uint8_t)(((uint8_t)(x))<<ICS_C2_BDIV_SHIFT))&ICS_C2_BDIV_MASK)\n#define ICS_S_LOCK_MASK\t\t\t\t0x40\n#define ICS_C4_SCFTRIM_MASK\t\t\t0x1\n#define SIM_CLKDIV_OUTDIV2_MASK\t\t0x1000000\n#define FTMRX_FCLKDIV_FDIV_MASK\t\t0x3F\n#define FTMRX_FCLKDIV_FDIV_SHIFT\t0\n#define FTMRX_FCLKDIV_FDIV(x)\t\t(((uint8_t)(((uint8_t)(x))<<FTMRX_FCLKDIV_FDIV_SHIFT))&FTMRX_FCLKDIV_FDIV_MASK)\n#define FTMRX_FCLKDIV_FDIVLCK_MASK\t0x40\n#define FTMRX_FCLKDIV_FDIVLCK_SHIFT\t6\n#define FTMRX_FCLKDIV_FDIVLD_MASK\t0x80\n#define FTMRX_FCLKDIV_FDIVLD_SHIFT\t7\n#define FTMRX_FSTAT_CCIF_MASK\t\t0x80\n#define FTMRX_FSTAT_MGSTAT0_MASK\t0x01\n#define FTMRX_FSTAT_MGSTAT1_MASK\t0x02\n\n/* Commands */\n#define FTMRX_CMD_ALLERASED\t\t\t0x01\n#define FTMRX_CMD_BLOCKERASED\t\t0x02\n#define FTMRX_CMD_SECTIONERASED\t\t0x03\n#define FTMRX_CMD_READONCE\t\t\t0x04\n#define FTMRX_CMD_PROGFLASH\t\t\t0x06\n#define FTMRX_CMD_PROGONCE\t\t\t0x07\n#define FTMRX_CMD_ERASEALL\t\t\t0x08\n#define FTMRX_CMD_ERASEBLOCK\t\t0x09\n#define FTMRX_CMD_ERASESECTOR\t\t0x0A\n#define FTMRX_CMD_UNSECURE\t\t\t0x0B\n#define FTMRX_CMD_VERIFYACCESS\t\t0x0C\n#define FTMRX_CMD_SETMARGINLVL\t\t0x0D\n#define FTMRX_CMD_SETFACTORYLVL\t\t0x0E\n#define FTMRX_CMD_CONFIGNVM\t\t\t0x0F\n\n/* Error codes */\n#define FTMRX_ERROR_ACCERR\t\t\t0x20\n#define FTMRX_ERROR_FPVIOL\t\t\t0x10\n\n#define KINETIS_KE_SRSID_FAMID(x)\t\t((x >> 28) & 0x0F)\n#define KINETIS_KE_SRSID_SUBFAMID(x)\t((x >> 24) & 0x0F)\n#define KINETIS_KE_SRSID_PINCOUNT(x)\t((x >> 16) & 0x0F)\n\n#define KINETIS_KE_SRSID_KEX2\t0x02\n#define KINETIS_KE_SRSID_KEX4\t0x04\n#define KINETIS_KE_SRSID_KEX6\t0x06\n\nstruct kinetis_ke_flash_bank {\n\tuint32_t sector_size;\n\tuint32_t protection_size;\n\n\tuint32_t sim_srsid;\n\tuint32_t ftmrx_fclkdiv_addr;\n\tuint32_t ftmrx_fccobix_addr;\n\tuint32_t ftmrx_fstat_addr;\n\tuint32_t ftmrx_fprot_addr;\n\tuint32_t ftmrx_fccobhi_addr;\n\tuint32_t ftmrx_fccoblo_addr;\n};\n\n#define MDM_REG_STAT\t\t0x00\n#define MDM_REG_CTRL\t\t0x04\n#define MDM_REG_ID\t\t\t0xfc\n\n#define MDM_STAT_FMEACK\t\t(1<<0)\n#define MDM_STAT_FREADY\t\t(1<<1)\n#define MDM_STAT_SYSSEC\t\t(1<<2)\n#define MDM_STAT_SYSRES\t\t(1<<3)\n#define MDM_STAT_FMEEN\t\t(1<<5)\n#define MDM_STAT_BACKDOOREN\t(1<<6)\n#define MDM_STAT_LPEN\t\t(1<<7)\n#define MDM_STAT_VLPEN\t\t(1<<8)\n#define MDM_STAT_LLSMODEXIT\t(1<<9)\n#define MDM_STAT_VLLSXMODEXIT\t(1<<10)\n#define MDM_STAT_CORE_HALTED\t(1<<16)\n#define MDM_STAT_CORE_SLEEPDEEP\t(1<<17)\n#define MDM_STAT_CORESLEEPING\t(1<<18)\n\n#define MEM_CTRL_FMEIP\t\t(1<<0)\n#define MEM_CTRL_DBG_DIS\t(1<<1)\n#define MEM_CTRL_DBG_REQ\t(1<<2)\n#define MEM_CTRL_SYS_RES_REQ\t(1<<3)\n#define MEM_CTRL_CORE_HOLD_RES\t(1<<4)\n#define MEM_CTRL_VLLSX_DBG_REQ\t(1<<5)\n#define MEM_CTRL_VLLSX_DBG_ACK\t(1<<6)\n#define MEM_CTRL_VLLSX_STAT_ACK\t(1<<7)\n\n#define MDM_ACCESS_TIMEOUT\t3000 /* iterations */\n\nstatic int kinetis_ke_mdm_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)\n{\n\tLOG_DEBUG(\"MDM_REG[0x%02x] <- %08\" PRIX32, reg, value);\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, 1);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"MDM: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_write(ap, reg, value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: failed to queue a write request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_mdm_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)\n{\n\tstruct adiv5_ap *ap = dap_get_ap(dap, 1);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"MDM: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_read(ap, reg, result);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: failed to queue a read request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"MDM: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"MDM_REG[0x%02x]: %08\" PRIX32, reg, *result);\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_mdm_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value)\n{\n\tuint32_t val;\n\tint retval;\n\tint timeout = MDM_ACCESS_TIMEOUT;\n\n\tdo {\n\t\tretval = kinetis_ke_mdm_read_register(dap, reg, &val);\n\t\tif (retval != ERROR_OK || (val & mask) == value)\n\t\t\treturn retval;\n\n\t\talive_sleep(1);\n\t} while (timeout--);\n\n\tLOG_DEBUG(\"MDM: polling timed out\");\n\treturn ERROR_FAIL;\n}\n\nstatic int kinetis_ke_prepare_flash(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\tuint8_t c2, c3, c4, s = 0;\n\tuint16_t trim_value = 0;\n\tuint16_t timeout = 0;\n\tuint32_t bus_clock = 0;\n\tuint32_t bus_reg_val = 0;\n\tuint32_t bus_reg_addr = 0;\n\tuint32_t flash_clk_div;\n\tuint8_t fclkdiv;\n\tint result;\n\n\t/*\n\t * The RM states that the flash clock has to be set to 1MHz for writing and\n\t * erasing operations (otherwise it can damage the flash).\n\t * This function configures the entire clock tree to make sure we\n\t * run at the specified clock. We'll set FEI mode running from the ~32KHz\n\t * internal clock. So we need to:\n\t * - Trim internal clock.\n\t * - Configure the divider for ICSOUTCLK (ICS module).\n\t * - Configure the divider to get a bus clock (SIM module).\n\t * - Configure the flash clock that depends on the bus clock.\n\t *\n\t * For MKE02_40 and MKE02_20 we set ICSOUTCLK = 20MHz and bus clock = 20MHz.\n\t * For MKE04 and MKE06 we run at ICSOUTCLK = 48MHz and bus clock = 24MHz.\n\t */\n\n\t/*\n\t * Trim internal clock\n\t */\n\tswitch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {\n\n\t\tcase KINETIS_KE_SRSID_KEX2:\n\t\t\t/* Both KE02_20 and KE02_40 should get the same trim value */\n\t\t\ttrim_value = 0x4C;\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX4:\n\t\t\ttrim_value = 0x54;\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX6:\n\t\t\ttrim_value = 0x58;\n\t\t\tbreak;\n\t}\n\n\tresult = target_read_u8(target, ICS_C4, &c4);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tc3 = trim_value;\n\tc4 = (c4 & ~(ICS_C4_SCFTRIM_MASK)) | ((trim_value >> 8) & 0x01);\n\n\tresult = target_write_u8(target, ICS_C3, c3);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tresult = target_write_u8(target, ICS_C4, c4);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tresult = target_read_u8(target, ICS_S, &s);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* Wait */\n\twhile (!(s & ICS_S_LOCK_MASK)) {\n\n\t\tif (timeout <= 1000) {\n\t\t\ttimeout++;\n\t\t\talive_sleep(1);\n\t\t} else {\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tresult = target_read_u8(target, ICS_S, &s);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\t/* ... trim done ... */\n\n\t/*\n\t * Configure SIM (bus clock)\n\t */\n\tswitch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {\n\n\t\t/* KE02 sub-family operates on SIM_BUSDIV */\n\t\tcase KINETIS_KE_SRSID_KEX2:\n\t\t\tbus_reg_val = 0;\n\t\t\tbus_reg_addr = SIM_BUSDIV;\n\t\t\tbus_clock = 20000000;\n\t\t\tbreak;\n\n\t\t/* KE04 and KE06 sub-family operates on SIM_CLKDIV\n\t\t * Clocks are divided by:\n\t\t * DIV1 = core clock = 48MHz\n\t\t * DIV2 = bus clock = 24Mhz\n\t\t * DIV3 = timer clocks\n\t\t * So we need to configure SIM_CLKDIV, DIV1 and DIV2 value\n\t\t */\n\t\tcase KINETIS_KE_SRSID_KEX4:\n\t\t\t/* KE04 devices have the SIM_CLKDIV register at a different offset\n\t\t\t * depending on the pin count. */\n\t\t\tswitch (KINETIS_KE_SRSID_PINCOUNT(kinfo->sim_srsid)) {\n\n\t\t\t\t/* 16, 20 and 24 pins */\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\t\tbus_reg_addr = SIM_CLKDIV_KE04_16_20_24;\n\t\t\t\t\tbreak;\n\n\t\t\t\t/* 44, 64 and 80 pins */\n\t\t\t\tcase 5:\n\t\t\t\tcase 7:\n\t\t\t\tcase 8:\n\t\t\t\t\tbus_reg_addr = SIM_CLKDIV_KE04_44_64_80;\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"KE04 - Unknown pin count\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tbus_reg_val = SIM_CLKDIV_OUTDIV2_MASK;\n\t\t\tbus_clock = 24000000;\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX6:\n\t\t\tbus_reg_val = SIM_CLKDIV_OUTDIV2_MASK;\n\t\t\tbus_reg_addr = SIM_CLKDIV_KE06;\n\t\t\tbus_clock = 24000000;\n\t\t\tbreak;\n\t}\n\n\tresult = target_write_u32(target, bus_reg_addr, bus_reg_val);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/*\n\t * Configure ICS to FEI (internal source)\n\t */\n\tresult = target_read_u8(target, ICS_C2, &c2);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tc2 &= ~ICS_C2_BDIV_MASK;\n\n\tswitch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {\n\n\t\tcase KINETIS_KE_SRSID_KEX2:\n\t\t\t/* Note: since there are two KE02 types, the KE02_40 @ 40MHz and the\n\t\t\t * KE02_20 @ 20MHz, we divide here the ~40MHz ICSFLLCLK down to 20MHz,\n\t\t\t * for compatibility.\n\t\t\t */\n\t\t\tc2 |= ICS_C2_BDIV(1);\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX4:\n\t\tcase KINETIS_KE_SRSID_KEX6:\n\t\t\t/* For KE04 and KE06, the ICSFLLCLK can be 48MHz. */\n\t\t\tc2 |= ICS_C2_BDIV(0);\n\t\t\tbreak;\n\t}\n\n\tresult = target_write_u8(target, ICS_C2, c2);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* Internal clock as reference (IREFS = 1) */\n\tresult = target_write_u8(target, ICS_C1, 4);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* Wait for FLL to lock */\n\tresult = target_read_u8(target, ICS_S, &s);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\twhile (!(s & ICS_S_LOCK_MASK)) {\n\n\t\tif (timeout <= 1000) {\n\t\t\ttimeout++;\n\t\t\talive_sleep(1);\n\t\t} else {\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tresult = target_read_u8(target, ICS_S, &s);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\t/*\n\t * Configure flash clock to 1MHz.\n\t */\n\tflash_clk_div = bus_clock / 1000000L - 1;\n\n\t/* Check if the FCLKDIV register is locked */\n\tresult = target_read_u8(target, kinfo->ftmrx_fclkdiv_addr, &fclkdiv);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (!(fclkdiv & FTMRX_FCLKDIV_FDIVLCK_MASK)) {\n\t\t/* Unlocked. Check if the register was configured, and if so, if it has the right value */\n\t\tif ((fclkdiv & FTMRX_FCLKDIV_FDIVLD_MASK) &&\n\t\t\t((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div))) {\n\t\t\tLOG_WARNING(\"Flash clock was already set and contains an invalid value.\");\n\t\t\tLOG_WARNING(\"Please reset the target.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Finally, configure the flash clock */\n\t\tfclkdiv = (fclkdiv & ~(FTMRX_FCLKDIV_FDIV_MASK)) | FTMRX_FCLKDIV_FDIV(flash_clk_div);\n\t\tresult = target_write_u8(target, kinfo->ftmrx_fclkdiv_addr, fclkdiv);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t} else {\n\t\t/* Locked. Check if the current value is correct. */\n\t\tif ((fclkdiv & FTMRX_FCLKDIV_FDIV_MASK) != FTMRX_FCLKDIV_FDIV(flash_clk_div)) {\n\t\t\tLOG_WARNING(\"Flash clock register is locked and contains an invalid value.\");\n\t\t\tLOG_WARNING(\"Please reset the target.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tLOG_INFO(\"Flash clock ready\");\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_stop_watchdog(struct target *target)\n{\n\tstruct working_area *watchdog_algorithm;\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval;\n\tuint8_t cs1;\n\n\tstatic const uint8_t watchdog_code[] = {\n#include \"../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_watchdog.inc\"\n\t};\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Check if the watchdog is enabled */\n\tretval = target_read_u8(target, WDOG_CS1, &cs1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!(cs1 & 0x80)) {\n\t\t/* Already stopped */\n\t\treturn ERROR_OK;\n\t}\n\n\t/* allocate working area with watchdog code */\n\tif (target_alloc_working_area(target, sizeof(watchdog_code), &watchdog_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"No working area available for watchdog algorithm\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, watchdog_algorithm->address,\n\t\t\tsizeof(watchdog_code), watchdog_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tretval = target_run_algorithm(target, 0, NULL, 0, NULL,\n\t\t\twatchdog_algorithm->address, 0, 100000, &armv7m_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error executing Kinetis KE watchdog algorithm\");\n\t} else {\n\t\tLOG_INFO(\"Watchdog stopped\");\n\t}\n\n\ttarget_free_working_area(target, watchdog_algorithm);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(kinetis_ke_disable_wdog_handler)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn kinetis_ke_stop_watchdog(target);\n}\n\nCOMMAND_HANDLER(kinetis_ke_mdm_mass_erase)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\tLOG_ERROR(\"Cannot perform mass erase with a high-level adapter\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval;\n\n\t/* According to chapter 18.3.7.2 of the KE02 reference manual */\n\n\t/* assert SRST */\n\tif (jtag_get_reset_config() & RESET_HAS_SRST)\n\t\tadapter_assert_reset();\n\n\t/*\n\t * 1. Reset the device by asserting RESET pin or DAP_CTRL[3]\n\t */\n\tretval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_SYS_RES_REQ);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * ... Read the MDM-AP status register until the Flash Ready bit sets...\n\t */\n\tretval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,\n\t\t\t\t\t   MDM_STAT_FREADY | MDM_STAT_SYSRES,\n\t\t\t\t\t   MDM_STAT_FREADY);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM : flash ready timeout\");\n\t\treturn retval;\n\t}\n\n\t/*\n\t * 2. Set DAP_CTRL[0] bit to invoke debug mass erase via SWD\n\t * 3. Release reset by deasserting RESET pin or DAP_CTRL[3] bit via SWD.\n\t */\n\tretval = kinetis_ke_mdm_write_register(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* As a sanity check make sure that device started mass erase procedure */\n\tretval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,\n\t\t\t\t\t   MDM_STAT_FMEACK, MDM_STAT_FMEACK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * 4. Wait till DAP_CTRL[0] bit is cleared (after mass erase completes,\n\t * DAP_CTRL[0] bit is cleared automatically).\n\t */\n\tretval = kinetis_ke_mdm_poll_register(dap, MDM_REG_CTRL,\n\t\t\t\t\t   MEM_CTRL_FMEIP,\n\t\t\t\t\t   0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (jtag_get_reset_config() & RESET_HAS_SRST)\n\t\tadapter_deassert_reset();\n\n\treturn ERROR_OK;\n}\n\nstatic const uint32_t kinetis_ke_known_mdm_ids[] = {\n\t0x001C0020,\t/* Kinetis-L/M/V/E/KE Series */\n};\n\n/*\n * This function implements the procedure to connect to\n * SWD/JTAG on Kinetis K and L series of devices as it is described in\n * AN4835 \"Production Flash Programming Best Practices for Kinetis K-\n * and L-series MCUs\" Section 4.1.1\n */\nCOMMAND_HANDLER(kinetis_ke_check_flash_security_status)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\tLOG_WARNING(\"Cannot check flash security status with a high-level adapter\");\n\t\treturn ERROR_OK;\n\t}\n\n\tuint32_t val;\n\tint retval;\n\n\t/*\n\t * ... The MDM-AP ID register can be read to verify that the\n\t * connection is working correctly...\n\t */\n\tretval = kinetis_ke_mdm_read_register(dap, MDM_REG_ID, &val);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to read ID register\");\n\t\tgoto fail;\n\t}\n\n\tbool found = false;\n\tfor (size_t i = 0; i < ARRAY_SIZE(kinetis_ke_known_mdm_ids); i++) {\n\t\tif (val == kinetis_ke_known_mdm_ids[i]) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!found)\n\t\tLOG_WARNING(\"MDM: unknown ID %08\" PRIX32, val);\n\n\t/*\n\t * ... Read the MDM-AP status register until the Flash Ready bit sets...\n\t */\n\tretval = kinetis_ke_mdm_poll_register(dap, MDM_REG_STAT,\n\t\t\t\t\t   MDM_STAT_FREADY,\n\t\t\t\t\t   MDM_STAT_FREADY);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: flash ready timeout\");\n\t\tgoto fail;\n\t}\n\n\t/*\n\t * ... Read the System Security bit to determine if security is enabled.\n\t * If System Security = 0, then proceed. If System Security = 1, then\n\t * communication with the internals of the processor, including the\n\t * flash, will not be possible without issuing a mass erase command or\n\t * unsecuring the part through other means (backdoor key unlock)...\n\t */\n\tretval = kinetis_ke_mdm_read_register(dap, MDM_REG_STAT, &val);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MDM: failed to read MDM_REG_STAT\");\n\t\tgoto fail;\n\t}\n\n\tif (val & MDM_STAT_SYSSEC) {\n\t\tjtag_poll_set_enabled(false);\n\n\t\tLOG_WARNING(\"*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********\");\n\t\tLOG_WARNING(\"****                                                          ****\");\n\t\tLOG_WARNING(\"**** Your Kinetis MCU is in secured state, which means that,  ****\");\n\t\tLOG_WARNING(\"**** with exception for very basic communication, JTAG/SWD    ****\");\n\t\tLOG_WARNING(\"**** interface will NOT work. In order to restore its         ****\");\n\t\tLOG_WARNING(\"**** functionality please issue 'kinetis_ke mdm mass_erase'   ****\");\n\t\tLOG_WARNING(\"**** command, power cycle the MCU and restart OpenOCD.        ****\");\n\t\tLOG_WARNING(\"****                                                          ****\");\n\t\tLOG_WARNING(\"*********** ATTENTION! ATTENTION! ATTENTION! ATTENTION! **********\");\n\t} else {\n\t\tLOG_INFO(\"MDM: Chip is unsecured. Continuing.\");\n\t\tjtag_poll_set_enabled(true);\n\t}\n\n\treturn ERROR_OK;\n\nfail:\n\tLOG_ERROR(\"MDM: Failed to check security status of the MCU. Cannot proceed further\");\n\tjtag_poll_set_enabled(false);\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(kinetis_ke_flash_bank_command)\n{\n\tstruct kinetis_ke_flash_bank *bank_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_INFO(\"add flash_bank kinetis_ke %s\", bank->name);\n\n\tbank_info = malloc(sizeof(struct kinetis_ke_flash_bank));\n\n\tmemset(bank_info, 0, sizeof(struct kinetis_ke_flash_bank));\n\n\tbank->driver_priv = bank_info;\n\n\treturn ERROR_OK;\n}\n\n/* Kinetis Program-LongWord Microcodes */\nstatic uint8_t kinetis_ke_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/kinetis_ke/kinetis_ke_flash.inc\"\n};\n\nstatic int kinetis_ke_write_words(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t\t\t\t\t\tuint32_t offset, uint32_t words)\n{\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t ram_buffer_size = 512 + 16;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\tuint32_t flash_code_size;\n\n\tLOG_INFO(\"Kinetis KE: FLASH Write ...\");\n\n\t/* allocate working area with flash programming code */\n\tif (target_alloc_working_area(target, sizeof(kinetis_ke_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Patch the FTMRx registers addresses */\n\tflash_code_size = sizeof(kinetis_ke_flash_write_code);\n\tbuf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-16], 0, 32, kinfo->ftmrx_fstat_addr);\n\tbuf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-12], 0, 32, kinfo->ftmrx_fccobix_addr);\n\tbuf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-8], 0, 32, kinfo->ftmrx_fccobhi_addr);\n\tbuf_set_u32(&kinetis_ke_flash_write_code[flash_code_size-4], 0, 32, kinfo->ftmrx_fccoblo_addr);\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\tsizeof(kinetis_ke_flash_write_code), kinetis_ke_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\tif (target_alloc_working_area(target, ram_buffer_size, &source) != ERROR_OK) {\n\t\t/* free working area, write algorithm already allocated */\n\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\tLOG_WARNING(\"No large enough working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, words);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, words, 4,\n\t\t\t0, NULL,\n\t\t\t4, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tif (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_ACCERR)\n\t\t\tLOG_ERROR(\"flash access error\");\n\n\t\tif (buf_get_u32(reg_params[0].value, 0, 32) & FTMRX_ERROR_FPVIOL)\n\t\t\tLOG_ERROR(\"flash protection violation\");\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn retval;\n}\n\nstatic int kinetis_ke_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tLOG_WARNING(\"kinetis_ke_protect not supported yet\");\n\t/* FIXME: TODO */\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn ERROR_FLASH_BANK_INVALID;\n}\n\nstatic int kinetis_ke_protect_check(struct flash_bank *bank)\n{\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint result;\n\tuint8_t fprot;\n\tuint8_t fpopen, fpldis, fphdis;\n\tuint8_t fphs, fpls;\n\tuint32_t lprot_size = 0, hprot_size = 0;\n\tuint32_t lprot_to = 0, hprot_from = 0;\n\n\t/* read protection register */\n\tresult = target_read_u8(bank->target, kinfo->ftmrx_fprot_addr, &fprot);\n\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tfpopen = fprot & 0x80;\n\tfpldis = fprot & 0x04;\n\tfphdis = fprot & 0x20;\n\tfphs = (fprot >> 3) & 0x03;\n\tfpls = fprot & 0x03;\n\n\t/* Fully unprotected? */\n\tif (fpopen && fpldis && fphdis) {\n\t\tLOG_WARNING(\"No flash protection found.\");\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\t\tbank->sectors[i].is_protected = 0;\n\n\t\tkinfo->protection_size = 0;\n\t} else {\n\t\tLOG_WARNING(\"Flash protected. FPOPEN=%i FPLDIS=%i FPHDIS=%i FPLS=%i FPHS=%i\",\n\t\t\t\t\tfpopen ? 1 : 0, fpldis ? 1 : 0, fphdis ? 1 : 0, fpls, fphs);\n\n\t\t/* Retrieve which region is protected and how much */\n\t\tif (fpopen) {\n\t\t\tif (fpldis == 0)\n\t\t\t\tlprot_size = (kinfo->sector_size * 4) << fpls;\n\n\t\t\tif (fphdis == 0)\n\t\t\t\thprot_size = (kinfo->sector_size * 2) << fphs;\n\t\t} else {\n\t\t\tif (fpldis == 1)\n\t\t\t\tlprot_size = (kinfo->sector_size * 4) << fpls;\n\n\t\t\tif (fphdis == 1)\n\t\t\t\thprot_size = (kinfo->sector_size * 2) << fphs;\n\t\t}\n\n\t\tkinfo->protection_size = lprot_size + hprot_size;\n\n\t\t/* lprot_to indicates up to where the lower region is protected */\n\t\tlprot_to = lprot_size / kinfo->sector_size;\n\n\t\t/* hprot_from indicates from where the upper region is protected */\n\t\thprot_from = (0x8000 - hprot_size) / kinfo->sector_size;\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\n\t\t\t/* Check if the sector is in the lower region */\n\t\t\tif (bank->sectors[i].offset < 0x4000) {\n\t\t\t\t/* Compare the sector start address against lprot_to */\n\t\t\t\tif (lprot_to && (i < lprot_to))\n\t\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t\telse\n\t\t\t\t\tbank->sectors[i].is_protected = 0;\n\n\t\t\t/* Check if the sector is between the lower and upper region\n\t\t\t * OR after the upper region */\n\t\t\t} else if (bank->sectors[i].offset < 0x6000 || bank->sectors[i].offset >= 0x8000) {\n\t\t\t\t/* If fpopen is 1 then these regions are protected */\n\t\t\t\tif (fpopen)\n\t\t\t\t\tbank->sectors[i].is_protected = 0;\n\t\t\t\telse\n\t\t\t\t\tbank->sectors[i].is_protected = 1;\n\n\t\t\t/* Check if the sector is in the upper region */\n\t\t\t} else if (bank->sectors[i].offset < 0x8000) {\n\t\t\t\tif (hprot_from && (i > hprot_from))\n\t\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t\telse\n\t\t\t\t\tbank->sectors[i].is_protected = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_ftmrx_command(struct flash_bank *bank, uint8_t count,\n\t\t\t\t\t\t\t\t\tuint8_t *FCCOBIX, uint8_t *FCCOBHI, uint8_t *FCCOBLO, uint8_t *fstat)\n{\n\tuint8_t i;\n\tint result;\n\tstruct target *target = bank->target;\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\tuint32_t timeout = 0;\n\n\t/* Clear error flags */\n\tresult = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x30);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tfor (i = 0; i < count; i++)\t{\n\t\t/* Write index */\n\t\tresult = target_write_u8(target, kinfo->ftmrx_fccobix_addr, FCCOBIX[i]);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\t/* Write high part */\n\t\tresult = target_write_u8(target, kinfo->ftmrx_fccobhi_addr, FCCOBHI[i]);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\t/* Write low part (that is not always required) */\n\t\tif (FCCOBLO) {\n\t\t\tresult = target_write_u8(target, kinfo->ftmrx_fccoblo_addr, FCCOBLO[i]);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t}\n\t}\n\n\t/* Launch the command */\n\tresult = target_write_u8(target, kinfo->ftmrx_fstat_addr, 0x80);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* Wait for it to finish */\n\tresult = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\twhile (!(*fstat & FTMRX_FSTAT_CCIF_MASK)) {\n\t\tif (timeout <= 1000) {\n\t\t\ttimeout++;\n\t\t\talive_sleep(1);\n\t\t} else {\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tresult = target_read_u8(target, kinfo->ftmrx_fstat_addr, fstat);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint result;\n\tuint8_t FCCOBIX[2], FCCOBHI[2], FCCOBLO[2], fstat;\n\tbool fcf_erased = false;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first > bank->num_sectors) || (last > bank->num_sectors))\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tresult = kinetis_ke_prepare_flash(bank);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tFCCOBIX[0] = 0;\n\t\tFCCOBHI[0] = FTMRX_CMD_ERASESECTOR;\n\t\tFCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16;\n\n\t\tFCCOBIX[1] = 1;\n\t\tFCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8;\n\t\tFCCOBLO[1] = (bank->base + bank->sectors[i].offset);\n\n\t\tresult = kinetis_ke_ftmrx_command(bank, 2, FCCOBIX, FCCOBHI, FCCOBLO, &fstat);\n\n\t\tif (result != ERROR_OK)\t{\n\t\t\tLOG_WARNING(\"erase sector %u failed\", i);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tif (i == 2)\n\t\t\tfcf_erased = true;\n\t}\n\n\tif (fcf_erased) {\n\t\tLOG_WARNING\n\t\t\t(\"flash configuration field erased, please reset the device\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t uint32_t offset, uint32_t count)\n{\n\tint result;\n\tuint8_t *new_buffer = NULL;\n\tuint32_t words = count / 4;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset > bank->size)\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\n\tif (offset & 0x3) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks the required alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tresult = kinetis_ke_stop_watchdog(bank->target);\n\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\tresult = kinetis_ke_prepare_flash(bank);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (count & 0x3) {\n\t\tuint32_t old_count = count;\n\t\tcount = (old_count | 3) + 1;\n\t\tnew_buffer = malloc(count);\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"odd number of bytes to write and no memory \"\n\t\t\t\t\"for padding buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_INFO(\"odd number of bytes to write (%\" PRIu32 \"), extending to %\" PRIu32 \" \"\n\t\t\t\"and padding with 0xff\", old_count, count);\n\n\t\tmemset(new_buffer, 0xff, count);\n\t\tbuffer = memcpy(new_buffer, buffer, old_count);\n\t\twords++;\n\t}\n\n\tresult = kinetis_ke_write_words(bank, buffer, offset, words);\n\tfree(new_buffer);\n\n\treturn result;\n}\n\nstatic int kinetis_ke_probe(struct flash_bank *bank)\n{\n\tint result;\n\tuint32_t offset = 0;\n\tstruct target *target = bank->target;\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\n\tresult = target_read_u32(target, SIM_SRSID, &kinfo->sim_srsid);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (KINETIS_KE_SRSID_FAMID(kinfo->sim_srsid) != 0x00) {\n\t\tLOG_ERROR(\"Unsupported KE family\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tswitch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {\n\t\tcase KINETIS_KE_SRSID_KEX2:\n\t\t\tLOG_INFO(\"KE02 sub-family\");\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX4:\n\t\t\tLOG_INFO(\"KE04 sub-family\");\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX6:\n\t\t\tLOG_INFO(\"KE06 sub-family\");\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported KE sub-family\");\n\t\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\t/* We can only retrieve the ke0x part, but there is no way to know\n\t * the flash size, so assume the maximum flash size for the entire\n\t * sub family.\n\t */\n\tbank->base = 0x00000000;\n\tkinfo->sector_size = 512;\n\n\tswitch (KINETIS_KE_SRSID_SUBFAMID(kinfo->sim_srsid)) {\n\n\t\tcase KINETIS_KE_SRSID_KEX2:\n\t\t\t/* Max. 64KB */\n\t\t\tbank->size = 0x00010000;\n\t\t\tbank->num_sectors = 128;\n\n\t\t\t/* KE02 uses the FTMRH flash controller,\n\t\t\t * and registers have a different offset from the\n\t\t\t * FTMRE flash controller. Sort this out here.\n\t\t\t */\n\t\t\tkinfo->ftmrx_fclkdiv_addr = 0x40020000;\n\t\t\tkinfo->ftmrx_fccobix_addr = 0x40020002;\n\t\t\tkinfo->ftmrx_fstat_addr = 0x40020006;\n\t\t\tkinfo->ftmrx_fprot_addr = 0x40020008;\n\t\t\tkinfo->ftmrx_fccobhi_addr = 0x4002000A;\n\t\t\tkinfo->ftmrx_fccoblo_addr = 0x4002000B;\n\t\t\tbreak;\n\n\t\tcase KINETIS_KE_SRSID_KEX6:\n\t\tcase KINETIS_KE_SRSID_KEX4:\n\t\t\t/* Max. 128KB */\n\t\t\tbank->size = 0x00020000;\n\t\t\tbank->num_sectors = 256;\n\n\t\t\t/* KE04 and KE06 use the FTMRE flash controller,\n\t\t\t * and registers have a different offset from the\n\t\t\t * FTMRH flash controller. Sort this out here.\n\t\t\t */\n\t\t\tkinfo->ftmrx_fclkdiv_addr = 0x40020003;\n\t\t\tkinfo->ftmrx_fccobix_addr = 0x40020001;\n\t\t\tkinfo->ftmrx_fstat_addr = 0x40020005;\n\t\t\tkinfo->ftmrx_fprot_addr = 0x4002000B;\n\t\t\tkinfo->ftmrx_fccobhi_addr = 0x40020009;\n\t\t\tkinfo->ftmrx_fccoblo_addr = 0x40020008;\n\t\t\tbreak;\n\t}\n\n\tfree(bank->sectors);\n\n\tassert(bank->num_sectors > 0);\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = kinfo->sector_size;\n\t\toffset += kinfo->sector_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_auto_probe(struct flash_bank *bank)\n{\n\tstruct kinetis_ke_flash_bank *kinfo = bank->driver_priv;\n\n\tif (kinfo->sim_srsid)\n\t\treturn ERROR_OK;\n\n\treturn kinetis_ke_probe(bank);\n}\n\nstatic int kinetis_ke_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tcommand_print_sameline(cmd, \"%s driver for flash bank %s at \" TARGET_ADDR_FMT,\n\t\t\tbank->driver->name,\tbank->name, bank->base);\n\n\treturn ERROR_OK;\n}\n\nstatic int kinetis_ke_blank_check(struct flash_bank *bank)\n{\n\tuint8_t FCCOBIX[3], FCCOBHI[3], FCCOBLO[3], fstat;\n\tuint16_t longwords = 0;\n\tint result;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tresult = kinetis_ke_prepare_flash(bank);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check if whole bank is blank */\n\tFCCOBIX[0] = 0;\n\tFCCOBHI[0] = FTMRX_CMD_ALLERASED;\n\n\tresult = kinetis_ke_ftmrx_command(bank, 1, FCCOBIX, FCCOBHI, NULL, &fstat);\n\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK)) {\n\t\t/* the whole bank is not erased, check sector-by-sector */\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tFCCOBIX[0] = 0;\n\t\t\tFCCOBHI[0] = FTMRX_CMD_SECTIONERASED;\n\t\t\tFCCOBLO[0] = (bank->base + bank->sectors[i].offset) >> 16;\n\n\t\t\tFCCOBIX[1] = 1;\n\t\t\tFCCOBHI[1] = (bank->base + bank->sectors[i].offset) >> 8;\n\t\t\tFCCOBLO[1] = (bank->base + bank->sectors[i].offset);\n\n\t\t\tlongwords = 128;\n\n\t\t\tFCCOBIX[2] = 2;\n\t\t\tFCCOBHI[2] = longwords >> 8;\n\t\t\tFCCOBLO[2] = longwords;\n\n\t\t\tresult = kinetis_ke_ftmrx_command(bank, 3, FCCOBIX, FCCOBHI, FCCOBLO, &fstat);\n\n\t\t\tif (result == ERROR_OK)\t{\n\t\t\t\tbank->sectors[i].is_erased = !(fstat & (FTMRX_FSTAT_MGSTAT0_MASK | FTMRX_FSTAT_MGSTAT1_MASK));\n\t\t\t} else {\n\t\t\t\tLOG_DEBUG(\"Ignoring error on PFlash sector blank-check\");\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* the whole bank is erased, update all sectors */\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\t\tbank->sectors[i].is_erased = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration kinetis_ke_security_command_handlers[] = {\n\t{\n\t\t.name = \"check_security\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Check status of device security lock\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_ke_check_flash_security_status,\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Issue a complete flash erase via the MDM-AP\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_ke_mdm_mass_erase,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration kinetis_ke_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mdm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"MDM-AP command group\",\n\t\t.usage = \"\",\n\t\t.chain = kinetis_ke_security_command_handlers,\n\t},\n\t{\n\t\t.name = \"disable_wdog\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Disable the watchdog timer\",\n\t\t.usage = \"\",\n\t\t.handler = kinetis_ke_disable_wdog_handler,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration kinetis_ke_command_handler[] = {\n\t{\n\t\t.name = \"kinetis_ke\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Kinetis KE flash controller commands\",\n\t\t.usage = \"\",\n\t\t.chain = kinetis_ke_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver kinetis_ke_flash = {\n\t.name = \"kinetis_ke\",\n\t.commands = kinetis_ke_command_handler,\n\t.flash_bank_command = kinetis_ke_flash_bank_command,\n\t.erase = kinetis_ke_erase,\n\t.protect = kinetis_ke_protect,\n\t.write = kinetis_ke_write,\n\t.read = default_flash_read,\n\t.probe = kinetis_ke_probe,\n\t.auto_probe = kinetis_ke_auto_probe,\n\t.erase_check = kinetis_ke_blank_check,\n\t.protect_check = kinetis_ke_protect_check,\n\t.info = kinetis_ke_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/lpc2000.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   LPC1700 support Copyright (C) 2009 by Audrius Urmanavicius            *\n *   didele.deze@gmail.com                                                 *\n *                                                                         *\n *   LPC1100 variant and auto-probing support Copyright (C) 2014           *\n *   by Cosmin Gorgovan cosmin [at] linux-geek [dot] org                   *\n *                                                                         *\n *   LPC800/LPC1500/LPC54100 support Copyright (C) 2013/2014               *\n *   by Nemui Trinomius                                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   LPC8N04/HNS31xx support Copyright (C) 2018                            *\n *   by Jean-Christian de Rivaz jcdr [at] innodelec [dot] ch               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/arm_opcodes.h>\n#include <target/armv7m.h>\n\n/**\n * @file\n * flash programming support for NXP LPC8xx,LPC1xxx,LPC4xxx,LP5410x,LPC2xxx and NHS31xx devices.\n *\n * @todo Provide a way to update CCLK after declaring the flash bank. The value which is correct after chip reset will\n * rarely still work right after the clocks switch to use the PLL (e.g. 4MHz --> 100 MHz).\n */\n/*\n * currently supported devices:\n * variant 1 (lpc2000_v1):\n * - 2104 | 5 | 6\n * - 2114 | 9\n * - 2124 | 9\n * - 2194\n * - 2212 | 4\n * - 2292 | 4\n *\n * variant 2 (lpc2000_v2):\n * - 213x\n * - 214x\n * - 2101 | 2 | 3\n * - 2364 | 6 | 8\n * - 2378\n *\n * lpc1700:\n * - 175x\n * - 176x (tested with LPC1768)\n * - 177x\n * - 178x (tested with LPC1788)\n *\n * lpc4000: (lpc1700's alias)\n * - 407x\n * - 408x (tested with LPC4088)\n *\n * lpc4300: (also available as lpc1800 - alias)\n * - 43x2 | 3 | 5 | 7 (tested with LPC4337/LPC4357)\n * - 18x2 | 3 | 5 | 7\n *\n * lpc800:\n * - 810 | 1 | 2 (tested with LPC810/LPC811/LPC812)\n * - 822 | 4 (tested with LPC824)\n * - 8N04\n * - NHS31xx (tested with NHS3100)\n * - 844 | 5 (tested with LPC845)\n *\n * lpc1100:\n * - 11xx\n * - 11Axx\n * - 11Cxx\n * - 11Dxx\n * - 11Exx\n * - 11Uxx (tested with LPC11U34)\n * - 131x\n * - 134x\n *\n * lpc1500:\n * - 15x7 | 8 | 9 (tested with LPC1549)\n *\n * lpc54100:\n * - 54101 | 2 (tested with LPC54102)\n *\n * The auto variant auto-detects parts from the following series:\n * - 11xx\n * - 11Axx\n * - 11Cxx\n * - 11Dxx\n * - 11Exx\n * - 11Uxx\n * - 131x\n * - 134x\n * - 175x\n * - 176x\n * - 177x\n * - 178x\n * - 407x\n * - 408x\n * - 81x\n * - 82x\n * - 8N04\n * - NHS31xx\n */\n\n/* Part IDs for autodetection */\n/* A script which can automatically extract part ids from user manuals is available here:\n * https://github.com/lgeek/lpc_part_ids\n */\n#define LPC1110_1      0x0A07102B\n#define LPC1110_2      0x1A07102B\n#define LPC1111_002_1  0x0A16D02B\n#define LPC1111_002_2  0x1A16D02B\n#define LPC1111_101_1  0x041E502B\n#define LPC1111_101_2  0x2516D02B\n#define LPC1111_103_1  0x00010013\n#define LPC1111_201_1  0x0416502B\n#define LPC1111_201_2  0x2516902B\n#define LPC1111_203_1  0x00010012\n#define LPC1112_101_1  0x042D502B\n#define LPC1112_101_2  0x2524D02B\n#define LPC1112_102_1  0x0A24902B\n#define LPC1112_102_2  0x1A24902B\n#define LPC1112_103_1  0x00020023\n#define LPC1112_201_1  0x0425502B\n#define LPC1112_201_2  0x2524902B\n#define LPC1112_203_1  0x00020022\n#define LPC1113_201_1  0x0434502B\n#define LPC1113_201_2  0x2532902B\n#define LPC1113_203_1  0x00030032\n#define LPC1113_301_1  0x0434102B\n#define LPC1113_301_2  0x2532102B\n#define LPC1113_303_1  0x00030030\n#define LPC1114_102_1  0x0A40902B\n#define LPC1114_102_2  0x1A40902B\n#define LPC1114_201_1  0x0444502B\n#define LPC1114_201_2  0x2540902B\n#define LPC1114_203_1  0x00040042\n#define LPC1114_301_1  0x0444102B\n#define LPC1114_301_2  0x2540102B\n#define LPC1114_303_1  0x00040040\n#define LPC1114_323_1  0x00040060\n#define LPC1114_333_1  0x00040070\n#define LPC1115_303_1  0x00050080\n\n#define LPC11A02_1     0x4D4C802B\n#define LPC11A04_1     0x4D80002B\n#define LPC11A11_001_1 0x455EC02B\n#define LPC11A12_101_1 0x4574802B\n#define LPC11A13_201_1 0x458A402B\n#define LPC11A14_301_1 0x35A0002B\n#define LPC11A14_301_2 0x45A0002B\n\n#define LPC11C12_301_1 0x1421102B\n#define LPC11C14_301_1 0x1440102B\n#define LPC11C22_301_1 0x1431102B\n#define LPC11C24_301_1 0x1430102B\n\n#define LPC11E11_101   0x293E902B\n#define LPC11E12_201   0x2954502B\n#define LPC11E13_301   0x296A102B\n#define LPC11E14_401   0x2980102B\n#define LPC11E36_501   0x00009C41\n#define LPC11E37_401   0x00007C45\n#define LPC11E37_501   0x00007C41\n\n#define LPC11U12_201_1 0x095C802B\n#define LPC11U12_201_2 0x295C802B\n#define LPC11U13_201_1 0x097A802B\n#define LPC11U13_201_2 0x297A802B\n#define LPC11U14_201_1 0x0998802B\n#define LPC11U14_201_2 0x2998802B\n#define LPC11U23_301   0x2972402B\n#define LPC11U24_301   0x2988402B\n#define LPC11U24_401   0x2980002B\n#define LPC11U34_311   0x0003D440\n#define LPC11U34_421   0x0001CC40\n#define LPC11U35_401   0x0001BC40\n#define LPC11U35_501   0x0000BC40\n#define LPC11U36_401   0x00019C40\n#define LPC11U37_401   0x00017C40\n#define LPC11U37H_401  0x00007C44\n#define LPC11U37_501   0x00007C40\n\n#define LPC11E66       0x0000DCC1\n#define LPC11E67       0x0000BC81\n#define LPC11E68       0x00007C01\n\n#define LPC11U66       0x0000DCC8\n#define LPC11U67_1     0x0000BC88\n#define LPC11U67_2     0x0000BC80\n#define LPC11U68_1     0x00007C08\n#define LPC11U68_2     0x00007C00\n\n#define LPC1311        0x2C42502B\n#define LPC1311_1      0x1816902B\n#define LPC1313        0x2C40102B\n#define LPC1313_1      0x1830102B\n#define LPC1315        0x3A010523\n#define LPC1316        0x1A018524\n#define LPC1317        0x1A020525\n#define LPC1342        0x3D01402B\n#define LPC1343        0x3D00002B\n#define LPC1343_1      0x3000002B\n#define LPC1345        0x28010541\n#define LPC1346        0x08018542\n#define LPC1347        0x08020543\n\n#define LPC1751_1      0x25001110\n#define LPC1751_2      0x25001118\n#define LPC1752        0x25001121\n#define LPC1754        0x25011722\n#define LPC1756        0x25011723\n#define LPC1758        0x25013F37\n#define LPC1759        0x25113737\n#define LPC1763        0x26012033\n#define LPC1764        0x26011922\n#define LPC1765        0x26013733\n#define LPC1766        0x26013F33\n#define LPC1767        0x26012837\n#define LPC1768        0x26013F37\n#define LPC1769        0x26113F37\n#define LPC1774        0x27011132\n#define LPC1776        0x27191F43\n#define LPC1777        0x27193747\n#define LPC1778        0x27193F47\n#define LPC1785        0x281D1743\n#define LPC1786        0x281D1F43\n#define LPC1787        0x281D3747\n#define LPC1788        0x281D3F47\n\n#define LPC4072        0x47011121\n#define LPC4074        0x47011132\n#define LPC4076        0x47191F43\n#define LPC4078        0x47193F47\n#define LPC4088        0x481D3F47\n\n#define LPC810_021     0x00008100\n#define LPC811_001     0x00008110\n#define LPC812_101     0x00008120\n#define LPC812_101_1   0x00008121\n#define LPC812_101_2   0x00008122\n#define LPC812_101_3   0x00008123\n\n#define LPC822_101     0x00008221\n#define LPC822_101_1   0x00008222\n#define LPC824_201     0x00008241\n#define LPC824_201_1   0x00008242\n\n#define LPC8N04        0x00008A04\n#define NHS3100        0x4e310020\n#define NHS3152        0x4e315220\n#define NHS3153        0x4e315320 /* Only specified in Rev.1 of the datasheet */\n\n#define LPC844_201     0x00008441\n#define LPC844_201_1   0x00008442\n#define LPC844_201_2   0x00008444\n\n#define LPC845_301     0x00008451\n#define LPC845_301_1   0x00008452\n#define LPC845_301_2   0x00008453\n#define LPC845_301_3   0x00008454\n\n#define IAP_CODE_LEN 0x34\n\n#define LPC11XX_REG_SECTORS\t24\n\ntypedef enum {\n\tLPC2000_V1,\n\tLPC2000_V2,\n\tLPC1700,\n\tLPC4300,\n\tLPC800,\n\tLPC1100,\n\tLPC1500,\n\tLPC54100,\n\tLPC_AUTO,\n} lpc2000_variant;\n\nstruct lpc2000_flash_bank {\n\tlpc2000_variant variant;\n\tuint32_t cclk;\n\tint cmd51_dst_boundary;\n\tint calc_checksum;\n\tuint32_t cmd51_max_buffer;\n\tint checksum_vector;\n\tuint32_t iap_max_stack;\n\tuint32_t lpc4300_bank;\n\tuint32_t iap_entry_alternative;\n\tbool probed;\n};\n\nenum lpc2000_status_codes {\n\tLPC2000_CMD_SUCCESS = 0,\n\tLPC2000_INVALID_COMMAND = 1,\n\tLPC2000_SRC_ADDR_ERROR = 2,\n\tLPC2000_DST_ADDR_ERROR = 3,\n\tLPC2000_SRC_ADDR_NOT_MAPPED = 4,\n\tLPC2000_DST_ADDR_NOT_MAPPED = 5,\n\tLPC2000_COUNT_ERROR = 6,\n\tLPC2000_INVALID_SECTOR = 7,\n\tLPC2000_SECTOR_NOT_BLANK = 8,\n\tLPC2000_SECTOR_NOT_PREPARED = 9,\n\tLPC2000_COMPARE_ERROR = 10,\n\tLPC2000_BUSY = 11,\n\tLPC2000_PARAM_ERROR = 12,\n\tLPC2000_ADDR_ERROR = 13,\n\tLPC2000_ADDR_NOT_MAPPED = 14,\n\tLPC2000_CMD_NOT_LOCKED = 15,\n\tLPC2000_INVALID_CODE = 16,\n\tLPC2000_INVALID_BAUD_RATE = 17,\n\tLPC2000_INVALID_STOP_BIT = 18,\n\tLPC2000_CRP_ENABLED = 19,\n\tLPC2000_INVALID_FLASH_UNIT = 20,\n\tLPC2000_USER_CODE_CHECKSUM = 21,\n\tLCP2000_ERROR_SETTING_ACTIVE_PARTITION = 22,\n};\n\nstatic int lpc2000_build_sector_list(struct flash_bank *bank)\n{\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\tuint32_t offset = 0;\n\n\t/* default to a 4096 write buffer */\n\tlpc2000_info->cmd51_max_buffer = 4096;\n\n\tif (lpc2000_info->variant == LPC2000_V1) {\n\t\tlpc2000_info->cmd51_dst_boundary = 512;\n\t\tlpc2000_info->checksum_vector = 5;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\t/* variant 1 has different layout for 128kb and 256kb flashes */\n\t\tif (bank->size == 128 * 1024) {\n\t\t\tbank->num_sectors = 16;\n\t\t\tbank->sectors = malloc(sizeof(struct flash_sector) * 16);\n\t\t\tfor (int i = 0; i < 16; i++) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 8 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t}\n\t\t} else if (bank->size == 256 * 1024) {\n\t\t\tbank->num_sectors = 18;\n\t\t\tbank->sectors = malloc(sizeof(struct flash_sector) * 18);\n\n\t\t\tfor (int i = 0; i < 8; i++) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 8 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t}\n\t\t\tfor (int i = 8; i < 10; i++) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 64 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t}\n\t\t\tfor (int i = 10; i < 18; i++) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 8 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\texit(-1);\n\t\t}\n\t} else if (lpc2000_info->variant == LPC2000_V2) {\n\t\tlpc2000_info->cmd51_dst_boundary = 256;\n\t\tlpc2000_info->checksum_vector = 5;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\t/* variant 2 has a uniform layout, only number of sectors differs */\n\t\tswitch (bank->size) {\n\t\t\tcase 4 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024;\n\t\t\t\tbank->num_sectors = 1;\n\t\t\t\tbreak;\n\t\t\tcase 8 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024;\n\t\t\t\tbank->num_sectors = 2;\n\t\t\t\tbreak;\n\t\t\tcase 16 * 1024:\n\t\t\t\tbank->num_sectors = 4;\n\t\t\t\tbreak;\n\t\t\tcase 32 * 1024:\n\t\t\t\tbank->num_sectors = 8;\n\t\t\t\tbreak;\n\t\t\tcase 64 * 1024:\n\t\t\t\tbank->num_sectors = 9;\n\t\t\t\tbreak;\n\t\t\tcase 128 * 1024:\n\t\t\t\tbank->num_sectors = 11;\n\t\t\t\tbreak;\n\t\t\tcase 256 * 1024:\n\t\t\t\tbank->num_sectors = 15;\n\t\t\t\tbreak;\n\t\t\tcase 500 * 1024:\n\t\t\t\tbank->num_sectors = 27;\n\t\t\t\tbreak;\n\t\t\tcase 512 * 1024:\n\t\t\tcase 504 * 1024:\n\t\t\t\tbank->num_sectors = 28;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tif (i < 8) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 4 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t} else if (i < 22) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 32 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t} else if (i < 28) {\n\t\t\t\tbank->sectors[i].offset = offset;\n\t\t\t\tbank->sectors[i].size = 4 * 1024;\n\t\t\t\toffset += bank->sectors[i].size;\n\t\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\t\tbank->sectors[i].is_protected = 1;\n\t\t\t}\n\t\t}\n\t} else if (lpc2000_info->variant == LPC1700) {\n\t\tlpc2000_info->cmd51_dst_boundary = 256;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\tswitch (bank->size) {\n\t\t\tcase 4 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 256;\n\t\t\t\tbank->num_sectors = 1;\n\t\t\t\tbreak;\n\t\t\tcase 8 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 512;\n\t\t\t\tbank->num_sectors = 2;\n\t\t\t\tbreak;\n\t\t\tcase 16 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 512;\n\t\t\t\tbank->num_sectors = 4;\n\t\t\t\tbreak;\n\t\t\tcase 32 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024;\n\t\t\t\tbank->num_sectors = 8;\n\t\t\t\tbreak;\n\t\t\tcase 64 * 1024:\n\t\t\t\tbank->num_sectors = 16;\n\t\t\t\tbreak;\n\t\t\tcase 128 * 1024:\n\t\t\t\tbank->num_sectors = 18;\n\t\t\tbreak;\n\t\t\tcase 256 * 1024:\n\t\t\t\tbank->num_sectors = 22;\n\t\t\t\tbreak;\n\t\t\tcase 512 * 1024:\n\t\t\t\tbank->num_sectors = 30;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\t/* sectors 0-15 are 4kB-sized, 16 and above are 32kB-sized for LPC17xx/LPC40xx devices */\n\t\t\tbank->sectors[i].size = (i < 16) ? 4 * 1024 : 32 * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\t} else if (lpc2000_info->variant == LPC4300) {\n\t\tlpc2000_info->cmd51_dst_boundary = 512;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 208;\n\n\t\tswitch (bank->size) {\n\t\t\tcase 256 * 1024:\n\t\t\t\tbank->num_sectors = 11;\n\t\t\t\tbreak;\n\t\t\tcase 384 * 1024:\n\t\t\t\tbank->num_sectors = 13;\n\t\t\t\tbreak;\n\t\t\tcase 512 * 1024:\n\t\t\t\tbank->num_sectors = 15;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\t/* sectors 0-7 are 8kB-sized, 8 and above are 64kB-sized for LPC43xx devices */\n\t\t\tbank->sectors[i].size = (i < 8) ? 8 * 1024 : 64 * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\n\t} else if (lpc2000_info->variant == LPC800) {\n\t\tlpc2000_info->cmd51_dst_boundary = 64;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 208;\t\t/* 148byte for LPC81x,208byte for LPC82x. */\n\t\tlpc2000_info->cmd51_max_buffer = 256;\t/* smallest MCU in the series, LPC810, has 1 kB of SRAM */\n\n\t\tswitch (bank->size) {\n\t\t\tcase 4 * 1024:\n\t\t\t\tbank->num_sectors = 4;\n\t\t\t\tbreak;\n\t\t\tcase 8 * 1024:\n\t\t\t\tbank->num_sectors = 8;\n\t\t\t\tbreak;\n\t\t\tcase 16 * 1024:\n\t\t\t\tbank->num_sectors = 16;\n\t\t\t\tbreak;\n\t\t\tcase 30 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024;\t/* For LPC8N04 and NHS31xx, have 8kB of SRAM */\n\t\t\t\tbank->num_sectors = 30;\t\t\t/* There have only 30kB of writable Flash out of 32kB */\n\t\t\t\tbreak;\n\t\t\tcase 32 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024; /* For LPC824, has 8kB of SRAM */\n\t\t\t\tbank->num_sectors = 32;\n\t\t\t\tbreak;\n\t\t\tcase 64 * 1024:\n\t\t\t\tlpc2000_info->cmd51_max_buffer = 1024; /* For LPC844, has 8kB of SRAM */\n\t\t\t\tbank->num_sectors = 64;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\t/* all sectors are 1kB-sized for LPC8xx devices */\n\t\t\tbank->sectors[i].size = 1 * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\n\t} else if (lpc2000_info->variant == LPC1100) {\n\t\tlpc2000_info->cmd51_dst_boundary = 256;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\tif ((bank->size % (4 * 1024)) != 0) {\n\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered,\\nLPC1100 flash size must be a multiple of 4096\");\n\t\t\texit(-1);\n\t\t}\n\t\tlpc2000_info->cmd51_max_buffer = 512; /* smallest MCU in the series, LPC1110, has 1 kB of SRAM */\n\t\tunsigned int large_sectors = 0;\n\t\tunsigned int normal_sectors = bank->size / 4096;\n\n\t\tif (normal_sectors > LPC11XX_REG_SECTORS) {\n\t\t\tlarge_sectors = (normal_sectors - LPC11XX_REG_SECTORS) / 8;\n\t\t\tnormal_sectors = LPC11XX_REG_SECTORS;\n\t\t}\n\n\t\tbank->num_sectors = normal_sectors + large_sectors;\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\tbank->sectors[i].size = (i < LPC11XX_REG_SECTORS ? 4 : 32) * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\n\t} else if (lpc2000_info->variant == LPC1500) {\n\t\tlpc2000_info->cmd51_dst_boundary = 256;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\tswitch (bank->size) {\n\t\t\tcase 64 * 1024:\n\t\t\t\tbank->num_sectors = 16;\n\t\t\t\tbreak;\n\t\t\tcase 128 * 1024:\n\t\t\t\tbank->num_sectors = 32;\n\t\t\t\tbreak;\n\t\t\tcase 256 * 1024:\n\t\t\t\tbank->num_sectors = 64;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\t/* all sectors are 4kB-sized */\n\t\t\tbank->sectors[i].size = 4 * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\n\t} else if (lpc2000_info->variant == LPC54100) {\n\t\tlpc2000_info->cmd51_dst_boundary = 256;\n\t\tlpc2000_info->checksum_vector = 7;\n\t\tlpc2000_info->iap_max_stack = 128;\n\n\t\tswitch (bank->size) {\n\t\t\tcase 256 * 1024:\n\t\t\t\tbank->num_sectors = 8;\n\t\t\t\tbreak;\n\t\t\tcase 512 * 1024:\n\t\t\t\tbank->num_sectors = 16;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = offset;\n\t\t\t/* all sectors are 32kB-sized */\n\t\t\tbank->sectors[i].size = 32 * 1024;\n\t\t\toffset += bank->sectors[i].size;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\t}\n\n\t} else {\n\t\tLOG_ERROR(\"BUG: unknown lpc2000_info->variant encountered\");\n\t\texit(-1);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* this function allocates and initializes working area used for IAP algorithm\n * uses 52 + max IAP stack bytes working area\n * 0x0 to 0x7: jump gate (BX to thumb state, b -2 to wait)\n * 0x8 to 0x1f: command parameter table (1+5 words)\n * 0x20 to 0x33: command result table (1+4 words)\n * 0x34 to 0xb3|0x104: stack\n *        (128b needed for lpc1xxx/2000/5410x, 208b for lpc43xx/lpc82x and 148b for lpc81x)\n */\n\nstatic int lpc2000_iap_working_area_init(struct flash_bank *bank, struct working_area **iap_working_area)\n{\n\tstruct target *target = bank->target;\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\n\tif (target_alloc_working_area(target, IAP_CODE_LEN + lpc2000_info->iap_max_stack, iap_working_area) != ERROR_OK) {\n\t\tLOG_ERROR(\"no working area specified, can't write LPC2000 internal flash\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tuint8_t jump_gate[8];\n\n\t/* write IAP code to working area */\n\tswitch (lpc2000_info->variant) {\n\t\tcase LPC800:\n\t\tcase LPC1100:\n\t\tcase LPC1500:\n\t\tcase LPC1700:\n\t\tcase LPC4300:\n\t\tcase LPC54100:\n\t\tcase LPC_AUTO:\n\t\t\ttarget_buffer_set_u32(target, jump_gate, ARMV4_5_T_BX(12));\n\t\t\ttarget_buffer_set_u32(target, jump_gate + 4, ARMV5_T_BKPT(0));\n\t\t\tbreak;\n\t\tcase LPC2000_V1:\n\t\tcase LPC2000_V2:\n\t\t\ttarget_buffer_set_u32(target, jump_gate, ARMV4_5_BX(12));\n\t\t\ttarget_buffer_set_u32(target, jump_gate + 4, ARMV4_5_B(0xfffffe, 0));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown lpc2000_info->variant encountered\");\n\t\t\texit(-1);\n\t}\n\n\tint retval = target_write_memory(target, (*iap_working_area)->address, 4, 2, jump_gate);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Write memory at address \" TARGET_ADDR_FMT \" failed (check work_area definition)\",\n\t\t\t\t(*iap_working_area)->address);\n\t\ttarget_free_working_area(target, *iap_working_area);\n\t}\n\n\treturn retval;\n}\n\n/* call LPC8xx/LPC1xxx/LPC4xxx/LPC5410x/LPC2000 IAP function */\n\nstatic int lpc2000_iap_call(struct flash_bank *bank, struct working_area *iap_working_area, int code,\n\t\tuint32_t param_table[5], uint32_t result_table[4])\n{\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tstruct arm_algorithm arm_algo;\t/* for LPC2000 */\n\tstruct armv7m_algorithm armv7m_info;\t/* for LPC8xx/LPC1xxx/LPC4xxx/LPC5410x */\n\tuint32_t iap_entry_point = 0;\t/* to make compiler happier */\n\n\tswitch (lpc2000_info->variant) {\n\t\tcase LPC800:\n\t\tcase LPC1100:\n\t\tcase LPC1700:\n\t\tcase LPC_AUTO:\n\t\t\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\t\t\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\t\t\tiap_entry_point = 0x1fff1ff1;\n\t\t\tbreak;\n\t\tcase LPC1500:\n\t\tcase LPC54100:\n\t\t\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\t\t\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\t\t\tiap_entry_point = 0x03000205;\n\t\t\tbreak;\n\t\tcase LPC2000_V1:\n\t\tcase LPC2000_V2:\n\t\t\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\t\t\tarm_algo.core_mode = ARM_MODE_SVC;\n\t\t\tarm_algo.core_state = ARM_STATE_ARM;\n\t\t\tiap_entry_point = 0x7ffffff1;\n\t\t\tbreak;\n\t\tcase LPC4300:\n\t\t\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\t\t\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\t\t\t/* read out IAP entry point from ROM driver table at 0x10400100 */\n\t\t\ttarget_read_u32(target, 0x10400100, &iap_entry_point);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown lpc2000->variant encountered\");\n\t\t\texit(-1);\n\t}\n\n\tif (lpc2000_info->iap_entry_alternative != 0x0)\n\t\tiap_entry_point = lpc2000_info->iap_entry_alternative;\n\n\tstruct mem_param mem_params[2];\n\n\t/* command parameter table */\n\tinit_mem_param(&mem_params[0], iap_working_area->address + 8, 6 * 4, PARAM_OUT);\n\ttarget_buffer_set_u32(target, mem_params[0].value, code);\n\ttarget_buffer_set_u32(target, mem_params[0].value + 0x04, param_table[0]);\n\ttarget_buffer_set_u32(target, mem_params[0].value + 0x08, param_table[1]);\n\ttarget_buffer_set_u32(target, mem_params[0].value + 0x0c, param_table[2]);\n\ttarget_buffer_set_u32(target, mem_params[0].value + 0x10, param_table[3]);\n\ttarget_buffer_set_u32(target, mem_params[0].value + 0x14, param_table[4]);\n\n\tstruct reg_param reg_params[5];\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, iap_working_area->address + 0x08);\n\n\t/* command result table */\n\tinit_mem_param(&mem_params[1], iap_working_area->address + 0x20, 5 * 4, PARAM_IN);\n\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, iap_working_area->address + 0x20);\n\n\t/* IAP entry point */\n\tinit_reg_param(&reg_params[2], \"r12\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[2].value, 0, 32, iap_entry_point);\n\n\tswitch (lpc2000_info->variant) {\n\t\tcase LPC800:\n\t\tcase LPC1100:\n\t\tcase LPC1500:\n\t\tcase LPC1700:\n\t\tcase LPC4300:\n\t\tcase LPC54100:\n\t\tcase LPC_AUTO:\n\t\t\t/* IAP stack */\n\t\t\tinit_reg_param(&reg_params[3], \"sp\", 32, PARAM_OUT);\n\t\t\tbuf_set_u32(reg_params[3].value, 0, 32,\n\t\t\t\tiap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);\n\n\t\t\t/* return address */\n\t\t\tinit_reg_param(&reg_params[4], \"lr\", 32, PARAM_OUT);\n\t\t\tbuf_set_u32(reg_params[4].value, 0, 32, (iap_working_area->address + 0x04) | 1);\n\t\t\t/* bit0 of LR = 1 to return in Thumb mode */\n\n\t\t\ttarget_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address, 0, 10000,\n\t\t\t\t\t&armv7m_info);\n\t\t\tbreak;\n\t\tcase LPC2000_V1:\n\t\tcase LPC2000_V2:\n\t\t\t/* IAP stack */\n\t\t\tinit_reg_param(&reg_params[3], \"sp_svc\", 32, PARAM_OUT);\n\t\t\tbuf_set_u32(reg_params[3].value, 0, 32,\n\t\t\t\tiap_working_area->address + IAP_CODE_LEN + lpc2000_info->iap_max_stack);\n\n\t\t\t/* return address */\n\t\t\tinit_reg_param(&reg_params[4], \"lr_svc\", 32, PARAM_OUT);\n\t\t\tbuf_set_u32(reg_params[4].value, 0, 32, iap_working_area->address + 0x04);\n\n\t\t\ttarget_run_algorithm(target, 2, mem_params, 5, reg_params, iap_working_area->address,\n\t\t\t\t\tiap_working_area->address + 0x4, 10000, &arm_algo);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown lpc2000->variant encountered\");\n\t\t\texit(-1);\n\t}\n\n\tint status_code = target_buffer_get_u32(target, mem_params[1].value);\n\tresult_table[0] = target_buffer_get_u32(target, mem_params[1].value + 0x04);\n\tresult_table[1] = target_buffer_get_u32(target, mem_params[1].value + 0x08);\n\tresult_table[2] = target_buffer_get_u32(target, mem_params[1].value + 0x0c);\n\tresult_table[3] = target_buffer_get_u32(target, mem_params[1].value + 0x10);\n\n\tLOG_DEBUG(\"IAP command = %i (0x%8.8\" PRIx32 \", 0x%8.8\" PRIx32 \", 0x%8.8\" PRIx32 \", 0x%8.8\" PRIx32 \", 0x%8.8\" PRIx32\n\t\t\t\") completed with result = %8.8x\",\n\t\t\tcode, param_table[0], param_table[1], param_table[2], param_table[3], param_table[4], status_code);\n\n\tdestroy_mem_param(&mem_params[0]);\n\tdestroy_mem_param(&mem_params[1]);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn status_code;\n}\n\nstatic int lpc2000_iap_blank_check(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tif (last >= bank->num_sectors)\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tuint32_t param_table[5] = {0};\n\tuint32_t result_table[4];\n\tstruct working_area *iap_working_area;\n\n\tint retval = lpc2000_iap_working_area_init(bank, &iap_working_area);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\tif (lpc2000_info->variant == LPC4300)\n\t\tparam_table[2] = lpc2000_info->lpc4300_bank;\n\n\tfor (unsigned int i = first; i <= last && retval == ERROR_OK; i++) {\n\t\t/* check single sector */\n\t\tparam_table[0] = param_table[1] = i;\n\t\tint status_code = lpc2000_iap_call(bank, iap_working_area, 53, param_table, result_table);\n\n\t\tswitch (status_code) {\n\t\t\tcase ERROR_FLASH_OPERATION_FAILED:\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_CMD_SUCCESS:\n\t\t\t\tbank->sectors[i].is_erased = 1;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_SECTOR_NOT_BLANK:\n\t\t\t\tbank->sectors[i].is_erased = 0;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_INVALID_SECTOR:\n\t\t\t\tbank->sectors[i].is_erased = 0;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_BUSY:\n\t\t\t\tretval = ERROR_FLASH_BUSY;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown LPC2000 status code %i\", status_code);\n\t\t\t\texit(-1);\n\t\t}\n\t}\n\n\tstruct target *target = bank->target;\n\ttarget_free_working_area(target, iap_working_area);\n\n\treturn retval;\n}\n\n/*\n * flash bank lpc2000 <base> <size> 0 0 <target#> <lpc_variant> <cclk> [calc_checksum]\n */\nFLASH_BANK_COMMAND_HANDLER(lpc2000_flash_bank_command)\n{\n\tif (CMD_ARGC < 8)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct lpc2000_flash_bank *lpc2000_info = calloc(1, sizeof(*lpc2000_info));\n\tlpc2000_info->probed = false;\n\n\tbank->driver_priv = lpc2000_info;\n\n\tif (strcmp(CMD_ARGV[6], \"lpc2000_v1\") == 0) {\n\t\tlpc2000_info->variant = LPC2000_V1;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc2000_v2\") == 0) {\n\t\tlpc2000_info->variant = LPC2000_V2;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc1700\") == 0 || strcmp(CMD_ARGV[6], \"lpc4000\") == 0) {\n\t\tlpc2000_info->variant = LPC1700;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc1800\") == 0 || strcmp(CMD_ARGV[6], \"lpc4300\") == 0) {\n\t\tlpc2000_info->variant = LPC4300;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc800\") == 0) {\n\t\tlpc2000_info->variant = LPC800;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc1100\") == 0) {\n\t\tlpc2000_info->variant = LPC1100;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc1500\") == 0) {\n\t\tlpc2000_info->variant = LPC1500;\n\t} else if (strcmp(CMD_ARGV[6], \"lpc54100\") == 0) {\n\t\tlpc2000_info->variant = LPC54100;\n\t} else if (strcmp(CMD_ARGV[6], \"auto\") == 0) {\n\t\tlpc2000_info->variant = LPC_AUTO;\n\t} else {\n\t\tLOG_ERROR(\"unknown LPC2000 variant: %s\", CMD_ARGV[6]);\n\t\tfree(lpc2000_info);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\t/* Maximum size required for the IAP stack.\n\t   This value only gets used when probing, only for auto, lpc1100 and lpc1700.\n\t   We use the maximum size for any part supported by the driver(!) to be safe\n\t   in case the auto variant is mistakenly used on a MCU from one of the series\n\t   for which we don't support auto-probing. */\n\tlpc2000_info->iap_max_stack = 208;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[7], lpc2000_info->cclk);\n\tlpc2000_info->calc_checksum = 0;\n\n\tuint32_t temp_base = 0;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], temp_base);\n\tif (temp_base >= 0x1B000000)\n\t\tlpc2000_info->lpc4300_bank = 1; /* bank B */\n\telse\n\t\tlpc2000_info->lpc4300_bank = 0; /* bank A */\n\n\tif (CMD_ARGC >= 9) {\n\t\tif (strcmp(CMD_ARGV[8], \"calc_checksum\") == 0)\n\t\t\tlpc2000_info->calc_checksum = 1;\n\t}\n\tif (CMD_ARGC >= 10 && !lpc2000_info->iap_entry_alternative)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[9], lpc2000_info->iap_entry_alternative);\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc2000_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\tuint32_t param_table[5] = {0};\n\n\tparam_table[0] = first;\n\tparam_table[1] = last;\n\n\tif (lpc2000_info->variant == LPC4300)\n\t\tparam_table[2] = lpc2000_info->lpc4300_bank;\n\telse\n\t\tparam_table[2] = lpc2000_info->cclk;\n\n\tuint32_t result_table[4];\n\tstruct working_area *iap_working_area;\n\n\tint retval = lpc2000_iap_working_area_init(bank, &iap_working_area);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (lpc2000_info->variant == LPC4300)\n\t\t/* Init IAP Anyway */\n\t\tlpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);\n\n\t/* Prepare sectors */\n\tint status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);\n\tswitch (status_code) {\n\t\tcase ERROR_FLASH_OPERATION_FAILED:\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\tcase LPC2000_CMD_SUCCESS:\n\t\t\tbreak;\n\t\tcase LPC2000_INVALID_SECTOR:\n\t\t\tretval = ERROR_FLASH_SECTOR_INVALID;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_WARNING(\"lpc2000 prepare sectors returned %i\", status_code);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\t/* Erase sectors */\n\t\tparam_table[2] = lpc2000_info->cclk;\n\t\tif (lpc2000_info->variant == LPC4300)\n\t\t\tparam_table[3] = lpc2000_info->lpc4300_bank;\n\n\t\tstatus_code = lpc2000_iap_call(bank, iap_working_area, 52, param_table, result_table);\n\t\tswitch (status_code) {\n\t\t\tcase ERROR_FLASH_OPERATION_FAILED:\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_CMD_SUCCESS:\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_INVALID_SECTOR:\n\t\t\t\tretval = ERROR_FLASH_SECTOR_INVALID;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_WARNING(\"lpc2000 erase sectors returned %i\", status_code);\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tstruct target *target = bank->target;\n\ttarget_free_working_area(target, iap_working_area);\n\n\treturn retval;\n}\n\nstatic int lpc2000_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\n\tuint32_t dst_min_alignment = lpc2000_info->cmd51_dst_boundary;\n\n\tif (offset % dst_min_alignment) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required alignment 0x%\" PRIx32, offset, dst_min_alignment);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tint first_sector = 0;\n\tint last_sector = 0;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (offset >= bank->sectors[i].offset)\n\t\t\tfirst_sector = i;\n\t\tif (offset + DIV_ROUND_UP(count, dst_min_alignment) * dst_min_alignment > bank->sectors[i].offset)\n\t\t\tlast_sector = i;\n\t}\n\n\tLOG_DEBUG(\"first_sector: %i, last_sector: %i\", first_sector, last_sector);\n\n\t/* check if exception vectors should be flashed */\n\tif ((offset == 0) && (count >= 0x20) && lpc2000_info->calc_checksum) {\n\t\tassert(lpc2000_info->checksum_vector < 8);\n\t\tuint32_t checksum = 0;\n\t\tfor (int i = 0; i < 8; i++) {\n\t\t\tLOG_DEBUG(\"Vector 0x%2.2x: 0x%8.8\" PRIx32, i * 4, buf_get_u32(buffer + (i * 4), 0, 32));\n\t\t\tif (i != lpc2000_info->checksum_vector)\n\t\t\t\tchecksum += buf_get_u32(buffer + (i * 4), 0, 32);\n\t\t}\n\t\tchecksum = 0 - checksum;\n\t\tLOG_DEBUG(\"checksum: 0x%8.8\" PRIx32, checksum);\n\n\t\tuint32_t original_value = buf_get_u32(buffer + (lpc2000_info->checksum_vector * 4), 0, 32);\n\t\tif (original_value != checksum) {\n\t\t\tLOG_WARNING(\"Boot verification checksum in image (0x%8.8\" PRIx32 \") to be written to flash is \"\n\t\t\t\t\t\"different from calculated vector checksum (0x%8.8\" PRIx32 \").\", original_value, checksum);\n\t\t\tLOG_WARNING(\"OpenOCD will write the correct checksum. To remove this warning modify build tools on developer PC to inject correct LPC vector \"\n\t\t\t\t\t\"checksum.\");\n\t\t}\n\n\t\t/* FIXME: WARNING! This code is broken because it modifies the callers buffer in place. */\n\t\tbuf_set_u32((uint8_t *)buffer + (lpc2000_info->checksum_vector * 4), 0, 32, checksum);\n\t}\n\n\tstruct working_area *iap_working_area;\n\n\tint retval = lpc2000_iap_working_area_init(bank, &iap_working_area);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct working_area *download_area;\n\n\t/* allocate a working area */\n\tif (target_alloc_working_area(target, lpc2000_info->cmd51_max_buffer, &download_area) != ERROR_OK) {\n\t\tLOG_ERROR(\"no working area specified, can't write LPC2000 internal flash\");\n\t\ttarget_free_working_area(target, iap_working_area);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tuint32_t bytes_remaining = count;\n\tuint32_t bytes_written = 0;\n\tuint32_t param_table[5] = {0};\n\tuint32_t result_table[4];\n\n\tif (lpc2000_info->variant == LPC4300)\n\t\t/* Init IAP Anyway */\n\t\tlpc2000_iap_call(bank, iap_working_area, 49, param_table, result_table);\n\n\twhile (bytes_remaining > 0) {\n\t\tuint32_t thisrun_bytes;\n\t\tif (bytes_remaining >= lpc2000_info->cmd51_max_buffer)\n\t\t\tthisrun_bytes = lpc2000_info->cmd51_max_buffer;\n\t\telse\n\t\t\tthisrun_bytes = lpc2000_info->cmd51_dst_boundary;\n\n\t\t/* Prepare sectors */\n\t\tparam_table[0] = first_sector;\n\t\tparam_table[1] = last_sector;\n\n\t\tif (lpc2000_info->variant == LPC4300)\n\t\t\tparam_table[2] = lpc2000_info->lpc4300_bank;\n\t\telse\n\t\t\tparam_table[2] = lpc2000_info->cclk;\n\n\t\tint status_code = lpc2000_iap_call(bank, iap_working_area, 50, param_table, result_table);\n\t\tswitch (status_code) {\n\t\t\tcase ERROR_FLASH_OPERATION_FAILED:\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_CMD_SUCCESS:\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_INVALID_SECTOR:\n\t\t\t\tretval = ERROR_FLASH_SECTOR_INVALID;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_WARNING(\"lpc2000 prepare sectors returned %i\", status_code);\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* Exit if error occurred */\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (bytes_remaining >= thisrun_bytes) {\n\t\t\tretval = target_write_buffer(bank->target, download_area->address, thisrun_bytes, buffer + bytes_written);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tuint8_t *last_buffer = malloc(thisrun_bytes);\n\t\t\tmemcpy(last_buffer, buffer + bytes_written, bytes_remaining);\n\t\t\tmemset(last_buffer + bytes_remaining, 0xff, thisrun_bytes - bytes_remaining);\n\t\t\ttarget_write_buffer(bank->target, download_area->address, thisrun_bytes, last_buffer);\n\t\t\tfree(last_buffer);\n\t\t}\n\n\t\tLOG_DEBUG(\"writing 0x%\" PRIx32 \" bytes to address \" TARGET_ADDR_FMT,\n\t\t\t\tthisrun_bytes, bank->base + offset + bytes_written);\n\n\t\t/* Write data */\n\t\tparam_table[0] = bank->base + offset + bytes_written;\n\t\tparam_table[1] = download_area->address;\n\t\tparam_table[2] = thisrun_bytes;\n\t\tparam_table[3] = lpc2000_info->cclk;\n\t\tstatus_code = lpc2000_iap_call(bank, iap_working_area, 51, param_table, result_table);\n\t\tswitch (status_code) {\n\t\t\tcase ERROR_FLASH_OPERATION_FAILED:\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_CMD_SUCCESS:\n\t\t\t\tbreak;\n\t\t\tcase LPC2000_INVALID_SECTOR:\n\t\t\t\tretval = ERROR_FLASH_SECTOR_INVALID;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_WARNING(\"lpc2000 returned %i\", status_code);\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* Exit if error occurred */\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (bytes_remaining > thisrun_bytes)\n\t\t\tbytes_remaining -= thisrun_bytes;\n\t\telse\n\t\t\tbytes_remaining = 0;\n\t\tbytes_written += thisrun_bytes;\n\t}\n\n\ttarget_free_working_area(target, iap_working_area);\n\ttarget_free_working_area(target, download_area);\n\n\treturn retval;\n}\n\nstatic int get_lpc2000_part_id(struct flash_bank *bank, uint32_t *part_id)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t param_table[5] = {0};\n\tuint32_t result_table[4];\n\tstruct working_area *iap_working_area;\n\n\tint retval = lpc2000_iap_working_area_init(bank, &iap_working_area);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* The status seems to be bogus with the part ID command on some IAP\n\t   firmwares, so ignore it. */\n\tlpc2000_iap_call(bank, iap_working_area, 54, param_table, result_table);\n\n\tstruct target *target = bank->target;\n\ttarget_free_working_area(target, iap_working_area);\n\n\t/* If the result is zero, the command probably didn't work out. */\n\tif (result_table[0] == 0)\n\t\treturn LPC2000_INVALID_COMMAND;\n\n\t*part_id = result_table[0];\n\treturn LPC2000_CMD_SUCCESS;\n}\n\nstatic int lpc2000_auto_probe_flash(struct flash_bank *bank)\n{\n\tuint32_t part_id;\n\tint retval;\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = get_lpc2000_part_id(bank, &part_id);\n\tif (retval != LPC2000_CMD_SUCCESS) {\n\t\tLOG_ERROR(\"Could not get part ID\");\n\t\treturn retval;\n\t}\n\n\tswitch (part_id) {\n\t\tcase LPC1110_1:\n\t\tcase LPC1110_2:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 4 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1111_002_1:\n\t\tcase LPC1111_002_2:\n\t\tcase LPC1111_101_1:\n\t\tcase LPC1111_101_2:\n\t\tcase LPC1111_103_1:\n\t\tcase LPC1111_201_1:\n\t\tcase LPC1111_201_2:\n\t\tcase LPC1111_203_1:\n\t\tcase LPC11A11_001_1:\n\t\tcase LPC11E11_101:\n\t\tcase LPC1311:\n\t\tcase LPC1311_1:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 8 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1112_101_1:\n\t\tcase LPC1112_101_2:\n\t\tcase LPC1112_102_1:\n\t\tcase LPC1112_102_2:\n\t\tcase LPC1112_103_1:\n\t\tcase LPC1112_201_1:\n\t\tcase LPC1112_201_2:\n\t\tcase LPC1112_203_1:\n\t\tcase LPC11A02_1:\n\t\tcase LPC11C12_301_1:\n\t\tcase LPC11C22_301_1:\n\t\tcase LPC11A12_101_1:\n\t\tcase LPC11E12_201:\n\t\tcase LPC11U12_201_1:\n\t\tcase LPC11U12_201_2:\n\t\tcase LPC1342:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 16 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1113_201_1:\n\t\tcase LPC1113_201_2:\n\t\tcase LPC1113_203_1:\n\t\tcase LPC1113_301_1:\n\t\tcase LPC1113_301_2:\n\t\tcase LPC1113_303_1:\n\t\tcase LPC11A13_201_1:\n\t\tcase LPC11E13_301:\n\t\tcase LPC11U13_201_1:\n\t\tcase LPC11U13_201_2:\n\t\tcase LPC11U23_301:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 24 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1114_102_1:\n\t\tcase LPC1114_102_2:\n\t\tcase LPC1114_201_1:\n\t\tcase LPC1114_201_2:\n\t\tcase LPC1114_203_1:\n\t\tcase LPC1114_301_1:\n\t\tcase LPC1114_301_2:\n\t\tcase LPC1114_303_1:\n\t\tcase LPC11A04_1:\n\t\tcase LPC11A14_301_1:\n\t\tcase LPC11A14_301_2:\n\t\tcase LPC11C14_301_1:\n\t\tcase LPC11C24_301_1:\n\t\tcase LPC11E14_401:\n\t\tcase LPC11U14_201_1:\n\t\tcase LPC11U14_201_2:\n\t\tcase LPC11U24_301:\n\t\tcase LPC11U24_401:\n\t\tcase LPC1313:\n\t\tcase LPC1313_1:\n\t\tcase LPC1315:\n\t\tcase LPC1343:\n\t\tcase LPC1343_1:\n\t\tcase LPC1345:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 32 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1751_1:\n\t\tcase LPC1751_2:\n\t\t\tlpc2000_info->variant = LPC1700;\n\t\t\tbank->size = 32 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC11U34_311:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 40 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1114_323_1:\n\t\tcase LPC11U34_421:\n\t\tcase LPC1316:\n\t\tcase LPC1346:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 48 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1114_333_1:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 56 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1115_303_1:\n\t\tcase LPC11U35_401:\n\t\tcase LPC11U35_501:\n\t\tcase LPC11E66:\n\t\tcase LPC11U66:\n\t\tcase LPC1317:\n\t\tcase LPC1347:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 64 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1752:\n\t\tcase LPC4072:\n\t\t\tlpc2000_info->variant = LPC1700;\n\t\t\tbank->size = 64 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC11E36_501:\n\t\tcase LPC11U36_401:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 96 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC11E37_401:\n\t\tcase LPC11E37_501:\n\t\tcase LPC11U37_401:\n\t\tcase LPC11U37H_401:\n\t\tcase LPC11U37_501:\n\t\tcase LPC11E67:\n\t\tcase LPC11E68:\n\t\tcase LPC11U67_1:\n\t\tcase LPC11U67_2:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 128 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1754:\n\t\tcase LPC1764:\n\t\tcase LPC1774:\n\t\tcase LPC4074:\n\t\t\tlpc2000_info->variant = LPC1700;\n\t\t\tbank->size = 128 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC11U68_1:\n\t\tcase LPC11U68_2:\n\t\t\tlpc2000_info->variant = LPC1100;\n\t\t\tbank->size = 256 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1756:\n\t\tcase LPC1763:\n\t\tcase LPC1765:\n\t\tcase LPC1766:\n\t\tcase LPC1776:\n\t\tcase LPC1785:\n\t\tcase LPC1786:\n\t\tcase LPC4076:\n\t\t\tlpc2000_info->variant = LPC1700;\n\t\t\tbank->size = 256 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC1758:\n\t\tcase LPC1759:\n\t\tcase LPC1767:\n\t\tcase LPC1768:\n\t\tcase LPC1769:\n\t\tcase LPC1777:\n\t\tcase LPC1778:\n\t\tcase LPC1787:\n\t\tcase LPC1788:\n\t\tcase LPC4078:\n\t\tcase LPC4088:\n\t\t\tlpc2000_info->variant = LPC1700;\n\t\t\tbank->size = 512 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC810_021:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 4 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC811_001:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 8 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC812_101:\n\t\tcase LPC812_101_1:\n\t\tcase LPC812_101_2:\n\t\tcase LPC812_101_3:\n\t\tcase LPC822_101:\n\t\tcase LPC822_101_1:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 16 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC824_201:\n\t\tcase LPC824_201_1:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 32 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC8N04:\n\t\tcase NHS3100:\n\t\tcase NHS3152:\n\t\tcase NHS3153:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 30 * 1024;\n\t\t\tbreak;\n\n\t\tcase LPC844_201:\n\t\tcase LPC844_201_1:\n\t\tcase LPC844_201_2:\n\t\tcase LPC845_301:\n\t\tcase LPC845_301_1:\n\t\tcase LPC845_301_2:\n\t\tcase LPC845_301_3:\n\t\t\tlpc2000_info->variant = LPC800;\n\t\t\tbank->size = 64 * 1024;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown Part ID encountered: 0x%\" PRIx32, part_id);\n\t\t\texit(-1);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc2000_probe(struct flash_bank *bank)\n{\n\tint status;\n\tuint32_t part_id;\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\n\tif (!lpc2000_info->probed) {\n\t\tif (lpc2000_info->variant == LPC_AUTO) {\n\t\t\tstatus = lpc2000_auto_probe_flash(bank);\n\t\t\tif (status != ERROR_OK)\n\t\t\t\treturn status;\n\t\t} else if (lpc2000_info->variant == LPC1100 || lpc2000_info->variant == LPC1700) {\n\t\t\tstatus = get_lpc2000_part_id(bank, &part_id);\n\t\t\tif (status == LPC2000_CMD_SUCCESS)\n\t\t\t\tLOG_INFO(\"If auto-detection fails for this part, please email \"\n\t\t\t\t\t\"openocd-devel@lists.sourceforge.net, citing part id 0x%\" PRIx32 \".\\n\", part_id);\n\t\t}\n\n\t\tlpc2000_build_sector_list(bank);\n\t\tlpc2000_info->probed = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc2000_erase_check(struct flash_bank *bank)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn lpc2000_iap_blank_check(bank, 0, bank->num_sectors - 1);\n}\n\nstatic int get_lpc2000_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct lpc2000_flash_bank *lpc2000_info = bank->driver_priv;\n\n\tcommand_print_sameline(cmd, \"lpc2000 flash driver variant: %i, clk: %\" PRIu32 \"kHz\",\n\t\t\tlpc2000_info->variant, lpc2000_info->cclk);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(lpc2000_handle_part_id_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t part_id;\n\tint status_code = get_lpc2000_part_id(bank, &part_id);\n\tif (status_code != 0x0) {\n\t\tif (status_code == ERROR_FLASH_OPERATION_FAILED) {\n\t\t\tcommand_print(CMD, \"no sufficient working area specified, can't access LPC2000 IAP interface\");\n\t\t} else\n\t\t\tcommand_print(CMD, \"lpc2000 IAP returned status code %i\", status_code);\n\t} else\n\t\tcommand_print(CMD, \"lpc2000 part id: 0x%8.8\" PRIx32, part_id);\n\n\treturn retval;\n}\n\nstatic const struct command_registration lpc2000_exec_command_handlers[] = {\n\t{\n\t\t.name = \"part_id\",\n\t\t.handler = lpc2000_handle_part_id_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"print part id of lpc2000 flash bank <num>\",\n\t\t.usage = \"<bank>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration lpc2000_command_handlers[] = {\n\t{\n\t\t.name = \"lpc2000\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"lpc2000 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = lpc2000_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver lpc2000_flash = {\n\t.name = \"lpc2000\",\n\t.commands = lpc2000_command_handlers,\n\t.flash_bank_command = lpc2000_flash_bank_command,\n\t.erase = lpc2000_erase,\n\t.write = lpc2000_write,\n\t.read = default_flash_read,\n\t.probe = lpc2000_probe,\n\t.auto_probe = lpc2000_probe,\n\t.erase_check = lpc2000_erase_check,\n\t.info = get_lpc2000_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/lpc288x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by\t\t\t                                       *\n *   Karl RobinSod <karl.robinsod@gmail.com>                               *\n ***************************************************************************/\n\n/***************************************************************************\n* There are some things to notice\n*\n* You need to unprotect flash sectors each time you connect the OpenOCD\n* Dumping 1MB takes about 60 Seconds\n* Full erase (sectors 0-22 inclusive) takes 2-4 seconds\n* Writing 1MB takes 88 seconds\n*\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n\n#define LOAD_TIMER_ERASE        0\n#define LOAD_TIMER_WRITE        1\n\n#define FLASH_PAGE_SIZE         512\n\n/* LPC288X control registers */\n#define DBGU_CIDR               0x8000507C\n/* LPC288X flash registers */\n#define F_CTRL                  0x80102000\t/* Flash control register R/W 0x5 */\n#define F_STAT                  0x80102004\t/* Flash status register RO 0x45 */\n#define F_PROG_TIME             0x80102008\t/* Flash program time register R/W 0 */\n#define F_WAIT                  0x80102010\t/* Flash read wait state register R/W 0xC004 */\n#define F_CLK_TIME              0x8010201C\t/* Flash clock divider for 66 kHz generation R/W 0\n\t\t\t\t\t\t **/\n#define F_INTEN_CLR             0x80102FD8\t/* Clear interrupt enable bits WO - */\n#define F_INTEN_SET             0x80102FDC\t/* Set interrupt enable bits WO - */\n#define F_INT_STAT              0x80102FE0\t/* Interrupt status bits RO 0 */\n#define F_INTEN                 0x80102FE4\t/* Interrupt enable bits RO 0 */\n#define F_INT_CLR               0x80102FE8\t/* Clear interrupt status bits WO */\n#define F_INT_SET               0x80102FEC\t/* Set interrupt status bits WO - */\n#define FLASH_PD                0x80005030\t/* Allows turning off the Flash memory for power\n\t\t\t\t\t\t *savings. R/W 1*/\n#define FLASH_INIT              0x80005034\t/* Monitors Flash readiness, such as recovery from\n\t\t\t\t\t\t *Power Down mode. R/W -*/\n\n/* F_CTRL bits */\n#define FC_CS                   0x0001\n#define FC_FUNC                 0x0002\n#define FC_WEN                  0x0004\n#define FC_RD_LATCH             0x0020\n#define FC_PROTECT              0x0080\n#define FC_SET_DATA             0x0400\n#define FC_RSSL                 0x0800\n#define FC_PROG_REQ             0x1000\n#define FC_CLR_BUF              0x4000\n#define FC_LOAD_REQ             0x8000\n/* F_STAT bits */\n#define FS_DONE                 0x0001\n#define FS_PROGGNT              0x0002\n#define FS_RDY                  0x0004\n#define FS_ERR                  0x0020\n/* F_PROG_TIME */\n#define FPT_TIME_MASK   0x7FFF\n\n#define FPT_ENABLE              0x8000\n/* F_WAIT */\n#define FW_WAIT_STATES_MASK             0x00FF\n#define FW_SET_MASK                             0xC000\n\n/* F_CLK_TIME */\n#define FCT_CLK_DIV_MASK    0x0FFF\n\nstruct lpc288x_flash_bank {\n\tuint32_t working_area;\n\tuint32_t working_area_size;\n\n\t/* chip id register */\n\tuint32_t cidr;\n\tconst char *target_name;\n\tuint32_t cclk;\n\n\tuint32_t sector_size_break;\n};\n\nstatic uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout);\nstatic void lpc288x_load_timer(int erase, struct target *target);\nstatic void lpc288x_set_flash_clk(struct flash_bank *bank);\nstatic uint32_t lpc288x_system_ready(struct flash_bank *bank);\n\nstatic uint32_t lpc288x_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\tstruct target *target = bank->target;\n\tdo {\n\t\talive_sleep(1);\n\t\ttimeout--;\n\t\ttarget_read_u32(target, F_STAT, &status);\n\t} while (((status & FS_DONE) == 0) && timeout);\n\n\tif (timeout == 0) {\n\t\tLOG_DEBUG(\"Timedout!\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\n/* Read device id register and fill in driver info structure */\nstatic int lpc288x_read_part_info(struct flash_bank *bank)\n{\n\tstruct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t cidr;\n\n\tint i = 0;\n\tuint32_t offset;\n\n\tif (lpc288x_info->cidr == 0x0102100A)\n\t\treturn ERROR_OK;/* already probed, multiple probes may cause memory leak, not\n\t\t\t\t *allowed */\n\n\t/* Read and parse chip identification register */\n\ttarget_read_u32(target, DBGU_CIDR, &cidr);\n\n\tif (cidr != 0x0102100A) {\n\t\tLOG_WARNING(\"Cannot identify target as an LPC288X (%08\" PRIx32 \")\", cidr);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tlpc288x_info->cidr = cidr;\n\tlpc288x_info->sector_size_break = 0x000F0000;\n\tlpc288x_info->target_name = \"LPC288x\";\n\n\t/* setup the sector info... */\n\toffset = bank->base;\n\tbank->num_sectors = 23;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * 23);\n\n\tfor (i = 0; i < 15; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = 64 * 1024;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\tfor (i = 15; i < 23; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = 8 * 1024;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* TODO: Revisit! Is it impossible to read protection status? */\nstatic int lpc288x_protect_check(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\n/* flash_bank LPC288x 0 0 0 0 <target#> <cclk> */\nFLASH_BANK_COMMAND_HANDLER(lpc288x_flash_bank_command)\n{\n\tstruct lpc288x_flash_bank *lpc288x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlpc288x_info = malloc(sizeof(struct lpc288x_flash_bank));\n\tbank->driver_priv = lpc288x_info;\n\n\t/* part wasn't probed for info yet */\n\tlpc288x_info->cidr = 0;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], lpc288x_info->cclk);\n\n\treturn ERROR_OK;\n}\n\n/* The frequency is the AHB clock frequency divided by (CLK_DIV ×3) + 1.\n * This must be programmed such that the Flash Programming clock frequency is 66 kHz ± 20%.\n * AHB = 12 MHz ?\n * 12000000/66000 = 182\n * CLK_DIV = 60 ? */\nstatic void lpc288x_set_flash_clk(struct flash_bank *bank)\n{\n\tuint32_t clk_time;\n\tstruct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;\n\tclk_time = (lpc288x_info->cclk / 66000) / 3;\n\ttarget_write_u32(bank->target, F_CTRL, FC_CS | FC_WEN);\n\ttarget_write_u32(bank->target, F_CLK_TIME, clk_time);\n}\n\n/* AHB tcyc (in ns) 83 ns\n * LOAD_TIMER_ERASE\t\tFPT_TIME\t= ((400,000,000 / AHB tcyc (in ns)) - 2) / 512\n *\t\t\t\t\t\t\t\t\t= 9412 (9500) (AN10548 9375)\n * LOAD_TIMER_WRITE\t\tFPT_TIME\t= ((1,000,000 / AHB tcyc (in ns)) - 2) / 512\n *\t\t\t\t\t\t\t\t\t= 23 (75) (AN10548 72 - is this wrong?)\n * TODO: Sort out timing calcs ;) */\nstatic void lpc288x_load_timer(int erase, struct target *target)\n{\n\tif (erase == LOAD_TIMER_ERASE)\n\t\ttarget_write_u32(target, F_PROG_TIME, FPT_ENABLE | 9500);\n\telse\n\t\ttarget_write_u32(target, F_PROG_TIME, FPT_ENABLE | 75);\n}\n\nstatic uint32_t lpc288x_system_ready(struct flash_bank *bank)\n{\n\tstruct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;\n\tif (lpc288x_info->cidr == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int lpc288x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint32_t status;\n\tstruct target *target = bank->target;\n\n\tstatus = lpc288x_system_ready(bank);\t/* probed? halted? */\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_INFO(\"Bad sector range\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\t/* Configure the flash controller timing */\n\tlpc288x_set_flash_clk(bank);\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\tlpc288x_load_timer(LOAD_TIMER_ERASE, target);\n\n\t\ttarget_write_u32(target, bank->sectors[sector].offset, 0x00);\n\n\t\ttarget_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_CS);\n\t}\n\tif (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\treturn ERROR_OK;\n}\n\nstatic int lpc288x_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tuint8_t page_buffer[FLASH_PAGE_SIZE];\n\tuint32_t status, source_offset, dest_offset;\n\tstruct target *target = bank->target;\n\tuint32_t bytes_remaining = count;\n\tuint32_t first_sector, last_sector, sector, page;\n\n\t/* probed? halted? */\n\tstatus = lpc288x_system_ready(bank);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\t/* Initialise search indices */\n\tfirst_sector = last_sector = 0xffffffff;\n\n\t/* validate the write range... */\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif ((offset >= bank->sectors[i].offset) &&\n\t\t\t\t(offset < (bank->sectors[i].offset + bank->sectors[i].size)) &&\n\t\t\t\t(first_sector == 0xffffffff)) {\n\t\t\tfirst_sector = i;\n\t\t\t/* all writes must start on a sector boundary... */\n\t\t\tif (offset % bank->sectors[i].size) {\n\t\t\t\tLOG_INFO(\n\t\t\t\t\t\"offset 0x%\" PRIx32 \" breaks required alignment 0x%\" PRIx32 \"\",\n\t\t\t\t\toffset,\n\t\t\t\t\tbank->sectors[i].size);\n\t\t\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t\t\t}\n\t\t}\n\t\tif (((offset + count) > bank->sectors[i].offset) &&\n\t\t\t\t((offset + count) <= (bank->sectors[i].offset + bank->sectors[i].size)) &&\n\t\t\t\t(last_sector == 0xffffffff))\n\t\t\tlast_sector = i;\n\t}\n\n\t/* Range check... */\n\tif (first_sector == 0xffffffff || last_sector == 0xffffffff) {\n\t\tLOG_INFO(\"Range check failed %\" PRIx32 \" %\" PRIx32 \"\", offset, count);\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\t}\n\n\t/* Configure the flash controller timing */\n\tlpc288x_set_flash_clk(bank);\n\n\t/* initialise the offsets */\n\tsource_offset = 0;\n\tdest_offset = 0;\n\n\tfor (sector = first_sector; sector <= last_sector; sector++) {\n\t\tfor (page = 0; page < bank->sectors[sector].size / FLASH_PAGE_SIZE; page++) {\n\t\t\tif (bytes_remaining == 0) {\n\t\t\t\tcount = 0;\n\t\t\t\tmemset(page_buffer, 0xFF, FLASH_PAGE_SIZE);\n\t\t\t} else if (bytes_remaining < FLASH_PAGE_SIZE) {\n\t\t\t\tcount = bytes_remaining;\n\t\t\t\tmemset(page_buffer, 0xFF, FLASH_PAGE_SIZE);\n\t\t\t\tmemcpy(page_buffer, &buffer[source_offset], count);\n\t\t\t} else {\n\t\t\t\tcount = FLASH_PAGE_SIZE;\n\t\t\t\tmemcpy(page_buffer, &buffer[source_offset], count);\n\t\t\t}\n\n\t\t\t/* Wait for flash to become ready */\n\t\t\tif (lpc288x_wait_status_busy(bank, 1000) != ERROR_OK)\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\t\t/* fill flash data latches with 1's */\n\t\t\ttarget_write_u32(target, F_CTRL, FC_CS | FC_SET_DATA | FC_WEN | FC_FUNC);\n\n\t\t\ttarget_write_u32(target, F_CTRL, FC_CS | FC_WEN | FC_FUNC);\n\n\t\t\tif (target_write_buffer(target, offset + dest_offset, FLASH_PAGE_SIZE,\n\t\t\t\t\tpage_buffer) != ERROR_OK) {\n\t\t\t\tLOG_INFO(\"Write to flash buffer failed\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tdest_offset += FLASH_PAGE_SIZE;\n\t\t\tsource_offset += count;\n\t\t\tbytes_remaining -= count;\n\n\t\t\tlpc288x_load_timer(LOAD_TIMER_WRITE, target);\n\n\t\t\ttarget_write_u32(target, F_CTRL, FC_PROG_REQ | FC_PROTECT | FC_FUNC |\n\t\t\t\tFC_CS);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int lpc288x_probe(struct flash_bank *bank)\n{\n\t/* we only deal with LPC2888 so flash config is fixed */\n\tstruct lpc288x_flash_bank *lpc288x_info = bank->driver_priv;\n\tint retval;\n\n\tif (lpc288x_info->cidr != 0)\n\t\treturn ERROR_OK;/* already probed */\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = lpc288x_read_part_info(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn ERROR_OK;\n}\n\nstatic int lpc288x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint status;\n\tuint32_t value;\n\tstruct target *target = bank->target;\n\n\t/* probed? halted? */\n\tstatus = lpc288x_system_ready(bank);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\t/* Configure the flash controller timing */\n\tlpc288x_set_flash_clk(bank);\n\n\tfor (unsigned int lockregion = first; lockregion <= last; lockregion++) {\n\t\tif (set) {\n\t\t\t/* write an odd value to base address to protect... */\n\t\t\tvalue = 0x01;\n\t\t} else {\n\t\t\t/* write an even value to base address to unprotect... */\n\t\t\tvalue = 0x00;\n\t\t}\n\t\ttarget_write_u32(target, bank->sectors[lockregion].offset, value);\n\t\ttarget_write_u32(target, F_CTRL, FC_LOAD_REQ | FC_PROTECT | FC_WEN | FC_FUNC |\n\t\t\tFC_CS);\n\t}\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver lpc288x_flash = {\n\t.name = \"lpc288x\",\n\t.flash_bank_command = lpc288x_flash_bank_command,\n\t.erase = lpc288x_erase,\n\t.protect = lpc288x_protect,\n\t.write = lpc288x_write,\n\t.read = default_flash_read,\n\t.probe = lpc288x_probe,\n\t.auto_probe = lpc288x_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = lpc288x_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/lpc2900.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by                                                 *\n *   Rolf Meeser <rolfm_9dq@yahoo.de>                                      *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/arm.h>\n#include <target/image.h>\n\n/* 1024 bytes */\n#define KiB                 1024\n\n/* Some flash constants */\n#define FLASH_PAGE_SIZE     512\t\t/* bytes */\n#define FLASH_ERASE_TIME    100000\t/* microseconds */\n#define FLASH_PROGRAM_TIME  1000\t/* microseconds */\n\n/* Chip ID / Feature Registers */\n#define CHIPID          0xE0000000\t/* Chip ID */\n#define FEAT0           0xE0000100\t/* Chip feature 0 */\n#define FEAT1           0xE0000104\t/* Chip feature 1 */\n#define FEAT2           0xE0000108\t/* Chip feature 2 (contains flash size indicator) */\n#define FEAT3           0xE000010C\t/* Chip feature 3 */\n\n#define EXPECTED_CHIPID 0x209CE02B\t/* Chip ID of all LPC2900 devices */\n\n/* Flash/EEPROM Control Registers */\n#define FCTR            0x20200000\t/* Flash control */\n#define FPTR            0x20200008\t/* Flash program-time */\n#define FTCTR           0x2020000C\t/* Flash test control */\n#define FBWST           0x20200010\t/* Flash bridge wait-state */\n#define FCRA            0x2020001C\t/* Flash clock divider */\n#define FMSSTART        0x20200020\t/* Flash Built-In Self Test start address */\n#define FMSSTOP         0x20200024\t/* Flash Built-In Self Test stop address */\n#define FMS16           0x20200028\t/* Flash 16-bit signature */\n#define FMSW0           0x2020002C\t/* Flash 128-bit signature Word 0 */\n#define FMSW1           0x20200030\t/* Flash 128-bit signature Word 1 */\n#define FMSW2           0x20200034\t/* Flash 128-bit signature Word 2 */\n#define FMSW3           0x20200038\t/* Flash 128-bit signature Word 3 */\n\n#define EECMD           0x20200080\t/* EEPROM command */\n#define EEADDR          0x20200084\t/* EEPROM address */\n#define EEWDATA         0x20200088\t/* EEPROM write data */\n#define EERDATA         0x2020008C\t/* EEPROM read data */\n#define EEWSTATE        0x20200090\t/* EEPROM wait state */\n#define EECLKDIV        0x20200094\t/* EEPROM clock divider */\n#define EEPWRDWN        0x20200098\t/* EEPROM power-down/start */\n#define EEMSSTART       0x2020009C\t/* EEPROM BIST start address */\n#define EEMSSTOP        0x202000A0\t/* EEPROM BIST stop address */\n#define EEMSSIG         0x202000A4\t/* EEPROM 24-bit BIST signature */\n\n#define INT_CLR_ENABLE  0x20200FD8\t/* Flash/EEPROM interrupt clear enable */\n#define INT_SET_ENABLE  0x20200FDC\t/* Flash/EEPROM interrupt set enable */\n#define INT_STATUS      0x20200FE0\t/* Flash/EEPROM interrupt status */\n#define INT_ENABLE      0x20200FE4\t/* Flash/EEPROM interrupt enable */\n#define INT_CLR_STATUS  0x20200FE8\t/* Flash/EEPROM interrupt clear status */\n#define INT_SET_STATUS  0x20200FEC\t/* Flash/EEPROM interrupt set status */\n\n/* Interrupt sources */\n#define INTSRC_END_OF_PROG    (1 << 28)\n#define INTSRC_END_OF_BIST    (1 << 27)\n#define INTSRC_END_OF_RDWR    (1 << 26)\n#define INTSRC_END_OF_MISR    (1 << 2)\n#define INTSRC_END_OF_BURN    (1 << 1)\n#define INTSRC_END_OF_ERASE   (1 << 0)\n\n/* FCTR bits */\n#define FCTR_FS_LOADREQ       (1 << 15)\n#define FCTR_FS_CACHECLR      (1 << 14)\n#define FCTR_FS_CACHEBYP      (1 << 13)\n#define FCTR_FS_PROGREQ       (1 << 12)\n#define FCTR_FS_RLS           (1 << 11)\n#define FCTR_FS_PDL           (1 << 10)\n#define FCTR_FS_PD            (1 << 9)\n#define FCTR_FS_WPB           (1 << 7)\n#define FCTR_FS_ISS           (1 << 6)\n#define FCTR_FS_RLD           (1 << 5)\n#define FCTR_FS_DCR           (1 << 4)\n#define FCTR_FS_WEB           (1 << 2)\n#define FCTR_FS_WRE           (1 << 1)\n#define FCTR_FS_CS            (1 << 0)\n/* FPTR bits */\n#define FPTR_EN_T             (1 << 15)\n/* FTCTR bits */\n#define FTCTR_FS_BYPASS_R     (1 << 29)\n#define FTCTR_FS_BYPASS_W     (1 << 28)\n/* FMSSTOP bits */\n#define FMSSTOP_MISR_START    (1 << 17)\n/* EEMSSTOP bits */\n#define EEMSSTOP_STRTBIST     (1 << 31)\n\n/* Index sector */\n#define ISS_CUSTOMER_START1   (0x830)\n#define ISS_CUSTOMER_END1     (0xA00)\n#define ISS_CUSTOMER_SIZE1    (ISS_CUSTOMER_END1 - ISS_CUSTOMER_START1)\n#define ISS_CUSTOMER_NWORDS1  (ISS_CUSTOMER_SIZE1 / 4)\n#define ISS_CUSTOMER_START2   (0xA40)\n#define ISS_CUSTOMER_END2     (0xC00)\n#define ISS_CUSTOMER_SIZE2    (ISS_CUSTOMER_END2 - ISS_CUSTOMER_START2)\n#define ISS_CUSTOMER_NWORDS2  (ISS_CUSTOMER_SIZE2 / 4)\n#define ISS_CUSTOMER_SIZE     (ISS_CUSTOMER_SIZE1 + ISS_CUSTOMER_SIZE2)\n\n/**\n * Private data for \\c lpc2900 flash driver.\n */\nstruct lpc2900_flash_bank {\n\t/**\n\t * This flag is set when the device has been successfully probed.\n\t */\n\tbool is_probed;\n\n\t/**\n\t * Holds the value read from CHIPID register.\n\t * The driver will not load if the chipid doesn't match the expected\n\t * value of 0x209CE02B of the LPC2900 family. A probe will only be done\n\t * if the chipid does not yet contain the expected value.\n\t */\n\tuint32_t chipid;\n\n\t/**\n\t * String holding device name.\n\t * This string is set by the probe function to the type number of the\n\t * device. It takes the form \"LPC29xx\".\n\t */\n\tchar *target_name;\n\n\t/**\n\t * System clock frequency.\n\t * Holds the clock frequency in Hz, as passed by the configuration file\n\t * to the <tt>flash bank</tt> command.\n\t */\n\tuint32_t clk_sys_fmc;\n\n\t/**\n\t * Flag to indicate that dangerous operations are possible.\n\t * This flag can be set by passing the correct password to the\n\t * <tt>lpc2900 password</tt> command. If set, other dangerous commands,\n\t * which operate on the index sector, can be executed.\n\t */\n\tuint32_t risky;\n\n\t/**\n\t * Maximum contiguous block of internal SRAM (bytes).\n\t * Autodetected by the driver. Not the total amount of SRAM, only\n\t * the largest \\em contiguous block!\n\t */\n\tuint32_t max_ram_block;\n\n};\n\nstatic uint32_t lpc2900_wait_status(struct flash_bank *bank, uint32_t mask, int timeout);\nstatic void lpc2900_setup(struct flash_bank *bank);\nstatic uint32_t lpc2900_is_ready(struct flash_bank *bank);\nstatic uint32_t lpc2900_read_security_status(struct flash_bank *bank);\nstatic uint32_t lpc2900_run_bist128(struct flash_bank *bank,\n\t\tuint32_t addr_from, uint32_t addr_to,\n\t\tuint32_t signature[4]);\nstatic unsigned int lpc2900_address2sector(struct flash_bank *bank, uint32_t offset);\nstatic uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var);\n\n/***********************  Helper functions  **************************/\n\n/**\n * Wait for an event in mask to occur in INT_STATUS.\n *\n * Return when an event occurs, or after a timeout.\n *\n * @param[in] bank Pointer to the flash bank descriptor\n * @param[in] mask Mask to be used for INT_STATUS\n * @param[in] timeout Timeout in ms\n */\nstatic uint32_t lpc2900_wait_status(struct flash_bank *bank,\n\tuint32_t mask,\n\tint timeout)\n{\n\tuint32_t int_status;\n\tstruct target *target = bank->target;\n\n\tdo {\n\t\talive_sleep(1);\n\t\ttimeout--;\n\t\ttarget_read_u32(target, INT_STATUS, &int_status);\n\t} while (((int_status & mask) == 0) && (timeout != 0));\n\n\tif (timeout == 0) {\n\t\tLOG_DEBUG(\"Timeout!\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Set up the flash for erase/program operations.\n *\n * Enable the flash, and set the correct CRA clock of 66 kHz.\n *\n * @param bank Pointer to the flash bank descriptor\n */\nstatic void lpc2900_setup(struct flash_bank *bank)\n{\n\tuint32_t fcra;\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\t/* Power up the flash block */\n\ttarget_write_u32(bank->target, FCTR, FCTR_FS_WEB | FCTR_FS_CS);\n\n\tfcra = (lpc2900_info->clk_sys_fmc / (3 * 66000)) - 1;\n\ttarget_write_u32(bank->target, FCRA, fcra);\n}\n\n/**\n * Check if device is ready.\n *\n * Check if device is ready for flash operation:\n * Must have been successfully probed.\n * Must be halted.\n */\nstatic uint32_t lpc2900_is_ready(struct flash_bank *bank)\n{\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\tif (!lpc2900_info->is_probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Read the status of sector security from the index sector.\n *\n * @param bank Pointer to the flash bank descriptor\n */\nstatic uint32_t lpc2900_read_security_status(struct flash_bank *bank)\n{\n\tuint32_t status = lpc2900_is_ready(bank);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\tstruct target *target = bank->target;\n\n\t/* Enable ISS access */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS);\n\n\t/* Read the relevant block of memory from the ISS sector */\n\tuint32_t iss_secured_field[0x230/16][4];\n\ttarget_read_memory(target, bank->base + 0xC00, 4, 0x230/4,\n\t\t(uint8_t *)iss_secured_field);\n\n\t/* Disable ISS access */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t/* Check status of each sector. Note that the sector numbering in the LPC2900\n\t * is different from the logical sector numbers used in OpenOCD!\n\t * Refer to the user manual for details.\n\t *\n\t * All zeros (16x 0x00) are treated as a secured sector (is_protected = 1)\n\t * All ones (16x 0xFF) are treated as a non-secured sector (is_protected = 0)\n\t * Anything else is undefined (is_protected = -1). This is treated as\n\t * a protected sector!\n\t */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tunsigned int index_t;\n\n\t\t/* Convert logical sector number to physical sector number */\n\t\tif (sector <= 4)\n\t\t\tindex_t = sector + 11;\n\t\telse if (sector <= 7)\n\t\t\tindex_t = sector + 27;\n\t\telse\n\t\t\tindex_t = sector - 8;\n\n\t\tbank->sectors[sector].is_protected = -1;\n\n\t\tif ((iss_secured_field[index_t][0] == 0x00000000) &&\n\t\t\t(iss_secured_field[index_t][1] == 0x00000000) &&\n\t\t\t(iss_secured_field[index_t][2] == 0x00000000) &&\n\t\t\t(iss_secured_field[index_t][3] == 0x00000000))\n\t\t\tbank->sectors[sector].is_protected = 1;\n\n\t\tif ((iss_secured_field[index_t][0] == 0xFFFFFFFF) &&\n\t\t\t(iss_secured_field[index_t][1] == 0xFFFFFFFF) &&\n\t\t\t(iss_secured_field[index_t][2] == 0xFFFFFFFF) &&\n\t\t\t(iss_secured_field[index_t][3] == 0xFFFFFFFF))\n\t\t\tbank->sectors[sector].is_protected = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Use BIST to calculate a 128-bit hash value over a range of flash.\n *\n * @param bank Pointer to the flash bank descriptor\n * @param addr_from\n * @param addr_to\n * @param signature\n */\nstatic uint32_t lpc2900_run_bist128(struct flash_bank *bank,\n\tuint32_t addr_from,\n\tuint32_t addr_to,\n\tuint32_t signature[4])\n{\n\tstruct target *target = bank->target;\n\n\t/* Clear END_OF_MISR interrupt status */\n\ttarget_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_MISR);\n\n\t/* Start address */\n\ttarget_write_u32(target, FMSSTART, addr_from >> 4);\n\t/* End address, and issue start command */\n\ttarget_write_u32(target, FMSSTOP, (addr_to >> 4) | FMSSTOP_MISR_START);\n\n\t/* Poll for end of operation. Calculate a reasonable timeout. */\n\tif (lpc2900_wait_status(bank, INTSRC_END_OF_MISR, 1000) != ERROR_OK)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* Return the signature */\n\tuint8_t sig_buf[4 * 4];\n\ttarget_read_memory(target, FMSW0, 4, 4, sig_buf);\n\ttarget_buffer_get_u32_array(target, sig_buf, 4, signature);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Return sector number for given address.\n *\n * Return the (logical) sector number for a given relative address.\n * No sanity check is done. It assumed that the address is valid.\n *\n * @param bank Pointer to the flash bank descriptor\n * @param offset Offset address relative to bank start\n */\nstatic unsigned int lpc2900_address2sector(struct flash_bank *bank,\n\tuint32_t offset)\n{\n\tuint32_t address = bank->base + offset;\n\n\t/* Run through all sectors of this bank */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Return immediately if address is within the current sector */\n\t\tif (address < (bank->sectors[sector].offset + bank->sectors[sector].size))\n\t\t\treturn sector;\n\t}\n\n\t/* We should never come here. If we do, return an arbitrary sector number. */\n\treturn 0;\n}\n\n/**\n * Write one page to the index sector.\n *\n * @param bank Pointer to the flash bank descriptor\n * @param pagenum Page number (0...7)\n * @param page Page array (FLASH_PAGE_SIZE bytes)\n */\nstatic int lpc2900_write_index_page(struct flash_bank *bank,\n\tint pagenum,\n\tuint8_t page[FLASH_PAGE_SIZE])\n{\n\t/* Only pages 4...7 are user writable */\n\tif ((pagenum < 4) || (pagenum > 7)) {\n\t\tLOG_ERROR(\"Refuse to burn index sector page %d\", pagenum);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* Get target, and check if it's halted */\n\tstruct target *target = bank->target;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Private info */\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\t/* Enable flash block and set the correct CRA clock of 66 kHz */\n\tlpc2900_setup(bank);\n\n\t/* Un-protect the index sector */\n\ttarget_write_u32(target, bank->base, 0);\n\ttarget_write_u32(target, FCTR,\n\t\tFCTR_FS_LOADREQ | FCTR_FS_WPB | FCTR_FS_ISS |\n\t\tFCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS);\n\n\t/* Set latch load mode */\n\ttarget_write_u32(target, FCTR,\n\t\tFCTR_FS_ISS | FCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS);\n\n\t/* Write whole page to flash data latches */\n\tif (target_write_memory(target,\n\t\t\tbank->base + pagenum * FLASH_PAGE_SIZE,\n\t\t\t4, FLASH_PAGE_SIZE / 4, page) != ERROR_OK) {\n\t\tLOG_ERROR(\"Index sector write failed @ page %d\", pagenum);\n\t\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Clear END_OF_BURN interrupt status */\n\ttarget_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_BURN);\n\n\t/* Set the program/erase time to FLASH_PROGRAM_TIME */\n\ttarget_write_u32(target, FPTR,\n\t\tFPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc,\n\t\t\tFLASH_PROGRAM_TIME));\n\n\t/* Trigger flash write */\n\ttarget_write_u32(target, FCTR,\n\t\tFCTR_FS_PROGREQ | FCTR_FS_ISS |\n\t\tFCTR_FS_WPB | FCTR_FS_WRE | FCTR_FS_CS);\n\n\t/* Wait for the end of the write operation. If it's not over after one\n\t * second, something went dreadfully wrong... :-(\n\t */\n\tif (lpc2900_wait_status(bank, INTSRC_END_OF_BURN, 1000) != ERROR_OK) {\n\t\tLOG_ERROR(\"Index sector write failed @ page %d\", pagenum);\n\t\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Calculate FPTR.TR register value for desired program/erase time.\n *\n * @param clock_var System clock in Hz\n * @param time_var Program/erase time in µs\n */\nstatic uint32_t lpc2900_calc_tr(uint32_t clock_var, uint32_t time_var)\n{\n\t/*           ((time[µs]/1e6) * f[Hz]) + 511\n\t * FPTR.TR = -------------------------------\n\t *                         512\n\t */\n\n\tuint32_t tr_val = (uint32_t)((((time_var / 1e6) * clock_var) + 511.0) / 512.0);\n\n\treturn tr_val;\n}\n\n/***********************  Private flash commands  **************************/\n\n\n/**\n * Command to determine the signature of the whole flash.\n *\n * Uses the Built-In-Self-Test (BIST) to generate a 128-bit hash value\n * of the flash content.\n */\nCOMMAND_HANDLER(lpc2900_handle_signature_command)\n{\n\tuint32_t status;\n\tuint32_t signature[4];\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Run BIST over whole flash range */\n\tstatus = lpc2900_run_bist128(bank, bank->base, bank->base + (bank->size - 1), signature);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\tcommand_print(CMD, \"signature: 0x%8.8\" PRIx32\n\t\t\":0x%8.8\" PRIx32\n\t\t\":0x%8.8\" PRIx32\n\t\t\":0x%8.8\" PRIx32,\n\t\tsignature[3], signature[2], signature[1], signature[0]);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Store customer info in file.\n *\n * Read customer info from index sector, and store that block of data into\n * a disk file. The format is binary.\n */\nCOMMAND_HANDLER(lpc2900_handle_read_custom_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\tlpc2900_info->risky = 0;\n\n\t/* Get target, and check if it's halted */\n\tstruct target *target = bank->target;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Storage for customer info. Read in two parts */\n\tuint8_t customer[4 * (ISS_CUSTOMER_NWORDS1 + ISS_CUSTOMER_NWORDS2)];\n\n\t/* Enable access to index sector */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB | FCTR_FS_ISS);\n\n\t/* Read two parts */\n\ttarget_read_memory(target, bank->base+ISS_CUSTOMER_START1, 4,\n\t\tISS_CUSTOMER_NWORDS1,\n\t\t&customer[0]);\n\ttarget_read_memory(target, bank->base+ISS_CUSTOMER_START2, 4,\n\t\tISS_CUSTOMER_NWORDS2,\n\t\t&customer[4 * ISS_CUSTOMER_NWORDS1]);\n\n\t/* Deactivate access to index sector */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t/* Try and open the file */\n\tstruct fileio *fileio;\n\tconst char *filename = CMD_ARGV[1];\n\tint ret = fileio_open(&fileio, filename, FILEIO_WRITE, FILEIO_BINARY);\n\tif (ret != ERROR_OK) {\n\t\tLOG_WARNING(\"Could not open file %s\", filename);\n\t\treturn ret;\n\t}\n\n\tsize_t nwritten;\n\tret = fileio_write(fileio, sizeof(customer), customer, &nwritten);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Write operation to file %s failed\", filename);\n\t\tfileio_close(fileio);\n\t\treturn ret;\n\t}\n\n\tfileio_close(fileio);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Enter password to enable potentially dangerous options.\n */\nCOMMAND_HANDLER(lpc2900_handle_password_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n#define ISS_PASSWORD \"I_know_what_I_am_doing\"\n\n\tlpc2900_info->risky = !strcmp(CMD_ARGV[1], ISS_PASSWORD);\n\n\tif (!lpc2900_info->risky) {\n\t\tcommand_print(CMD, \"Wrong password (use '%s')\", ISS_PASSWORD);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tcommand_print(CMD,\n\t\t\"Potentially dangerous operation allowed in next command!\");\n\n\treturn ERROR_OK;\n}\n\n/**\n * Write customer info from file to the index sector.\n */\nCOMMAND_HANDLER(lpc2900_handle_write_custom_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\t/* Check if command execution is allowed. */\n\tif (!lpc2900_info->risky) {\n\t\tcommand_print(CMD, \"Command execution not allowed!\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tlpc2900_info->risky = 0;\n\n\t/* Get target, and check if it's halted */\n\tstruct target *target = bank->target;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The image will always start at offset 0 */\n\tstruct image image;\n\timage.base_address_set = true;\n\timage.base_address = 0;\n\timage.start_address_set = false;\n\n\tconst char *filename = CMD_ARGV[1];\n\tconst char *type = (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL;\n\tretval = image_open(&image, filename, type);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Do a sanity check: The image must be exactly the size of the customer\n\t   programmable area. Any other size is rejected. */\n\tif (image.num_sections != 1) {\n\t\tLOG_ERROR(\"Only one section allowed in image file.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tif ((image.sections[0].base_address != 0) ||\n\t\t\t(image.sections[0].size != ISS_CUSTOMER_SIZE)) {\n\t\tLOG_ERROR(\"Incorrect image file size. Expected %d, \"\n\t\t\t\"got %\" PRIu32,\n\t\t\tISS_CUSTOMER_SIZE, image.sections[0].size);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* Well boys, I reckon this is it... */\n\n\t/* Customer info is split into two blocks in pages 4 and 5. */\n\tuint8_t page[FLASH_PAGE_SIZE];\n\n\t/* Page 4 */\n\tuint32_t offset = ISS_CUSTOMER_START1 % FLASH_PAGE_SIZE;\n\tmemset(page, 0xff, FLASH_PAGE_SIZE);\n\tsize_t size_read;\n\tretval = image_read_section(&image, 0, 0,\n\t\t\tISS_CUSTOMER_SIZE1, &page[offset], &size_read);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"couldn't read from file '%s'\", filename);\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\tretval = lpc2900_write_index_page(bank, 4, page);\n\tif (retval != ERROR_OK) {\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\n\t/* Page 5 */\n\toffset = ISS_CUSTOMER_START2 % FLASH_PAGE_SIZE;\n\tmemset(page, 0xff, FLASH_PAGE_SIZE);\n\tretval = image_read_section(&image, 0, ISS_CUSTOMER_SIZE1,\n\t\t\tISS_CUSTOMER_SIZE2, &page[offset], &size_read);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"couldn't read from file '%s'\", filename);\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\tretval = lpc2900_write_index_page(bank, 5, page);\n\tif (retval != ERROR_OK) {\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\n\timage_close(&image);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Activate 'sector security' for a range of sectors.\n */\nCOMMAND_HANDLER(lpc2900_handle_secure_sector_command)\n{\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Get the bank descriptor */\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\t/* Check if command execution is allowed. */\n\tif (!lpc2900_info->risky) {\n\t\tcommand_print(CMD, \"Command execution not allowed! \"\n\t\t\t\"(use 'password' command first)\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tlpc2900_info->risky = 0;\n\n\t/* Read sector range, and do a sanity check. */\n\tunsigned int first, last;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);\n\tif ((first >= bank->num_sectors) ||\n\t\t\t(last >= bank->num_sectors) ||\n\t\t\t(first > last)) {\n\t\tcommand_print(CMD, \"Illegal sector range\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tuint8_t page[FLASH_PAGE_SIZE];\n\n\t/* Sectors in page 6 */\n\tif ((first <= 4) || (last >= 8)) {\n\t\tmemset(&page, 0xff, FLASH_PAGE_SIZE);\n\t\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\t\tif (sector <= 4)\n\t\t\t\tmemset(&page[0xB0 + 16*sector], 0, 16);\n\t\t\telse if (sector >= 8)\n\t\t\t\tmemset(&page[0x00 + 16*(sector - 8)], 0, 16);\n\t\t}\n\n\t\tretval = lpc2900_write_index_page(bank, 6, page);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to update index sector page 6\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Sectors in page 7 */\n\tif ((first <= 7) && (last >= 5)) {\n\t\tmemset(&page, 0xff, FLASH_PAGE_SIZE);\n\t\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\t\tif ((sector >= 5) && (sector <= 7))\n\t\t\t\tmemset(&page[0x00 + 16*(sector - 5)], 0, 16);\n\t\t}\n\n\t\tretval = lpc2900_write_index_page(bank, 7, page);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to update index sector page 7\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tcommand_print(CMD,\n\t\t\"Sectors security will become effective after next power cycle\");\n\n\t/* Update the sector security status */\n\tif (lpc2900_read_security_status(bank) != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot determine sector security status\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Activate JTAG protection.\n */\nCOMMAND_HANDLER(lpc2900_handle_secure_jtag_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Get the bank descriptor */\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\t/* Check if command execution is allowed. */\n\tif (!lpc2900_info->risky) {\n\t\tcommand_print(CMD, \"Command execution not allowed! \"\n\t\t\t\"(use 'password' command first)\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tlpc2900_info->risky = 0;\n\n\t/* Prepare page */\n\tuint8_t page[FLASH_PAGE_SIZE];\n\tmemset(&page, 0xff, FLASH_PAGE_SIZE);\n\n\n\t/* Insert \"soft\" protection word */\n\tpage[0x30 + 15] = 0x7F;\n\tpage[0x30 + 11] = 0x7F;\n\tpage[0x30 +  7] = 0x7F;\n\tpage[0x30 +  3] = 0x7F;\n\n\t/* Write to page 5 */\n\tretval = lpc2900_write_index_page(bank, 5, page);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed to update index sector page 5\");\n\t\treturn retval;\n\t}\n\n\tLOG_INFO(\"JTAG security set. Good bye!\");\n\n\treturn ERROR_OK;\n}\n\n/***********************  Flash interface functions  **************************/\n\nstatic const struct command_registration lpc2900_exec_command_handlers[] = {\n\t{\n\t\t.name = \"signature\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = lpc2900_handle_signature_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Calculate and display signature of flash bank.\",\n\t},\n\t{\n\t\t.name = \"read_custom\",\n\t\t.handler = lpc2900_handle_read_custom_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename\",\n\t\t.help = \"Copies 912 bytes of customer information \"\n\t\t\t\"from index sector into file.\",\n\t},\n\t{\n\t\t.name = \"password\",\n\t\t.handler = lpc2900_handle_password_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id password\",\n\t\t.help = \"Enter fixed password to enable 'dangerous' options.\",\n\t},\n\t{\n\t\t.name = \"write_custom\",\n\t\t.handler = lpc2900_handle_write_custom_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename ('bin'|'ihex'|'elf'|'s19')\",\n\t\t.help = \"Copies 912 bytes of customer info from file \"\n\t\t\t\"to index sector.\",\n\t},\n\t{\n\t\t.name = \"secure_sector\",\n\t\t.handler = lpc2900_handle_secure_sector_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id first_sector last_sector\",\n\t\t.help = \"Activate sector security for a range of sectors.  \"\n\t\t\t\"It will be effective after a power cycle.\",\n\t},\n\t{\n\t\t.name = \"secure_jtag\",\n\t\t.handler = lpc2900_handle_secure_jtag_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Disable the JTAG port.  \"\n\t\t\t\"It will be effective after a power cycle.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration lpc2900_command_handlers[] = {\n\t{\n\t\t.name = \"lpc2900\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"LPC2900 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = lpc2900_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Evaluate flash bank command. */\nFLASH_BANK_COMMAND_HANDLER(lpc2900_flash_bank_command)\n{\n\tstruct lpc2900_flash_bank *lpc2900_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlpc2900_info = malloc(sizeof(struct lpc2900_flash_bank));\n\tbank->driver_priv = lpc2900_info;\n\n\t/* Get flash clock.\n\t * Reject it if we can't meet the requirements for program time\n\t * (if clock too slow), or for erase time (clock too fast).\n\t */\n\tuint32_t clk_sys_fmc;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], clk_sys_fmc);\n\tlpc2900_info->clk_sys_fmc = clk_sys_fmc * 1000;\n\n\tuint32_t clock_limit;\n\t/* Check program time limit */\n\tclock_limit = 512000000l / FLASH_PROGRAM_TIME;\n\tif (lpc2900_info->clk_sys_fmc < clock_limit) {\n\t\tLOG_WARNING(\"flash clock must be at least %\" PRIu32 \" kHz\",\n\t\t\t(clock_limit / 1000));\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\t/* Check erase time limit */\n\tclock_limit = (uint32_t)((32767.0 * 512.0 * 1e6) / FLASH_ERASE_TIME);\n\tif (lpc2900_info->clk_sys_fmc > clock_limit) {\n\t\tLOG_WARNING(\"flash clock must be a maximum of %\" PRIu32 \" kHz\",\n\t\t\t(clock_limit / 1000));\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\t/* Chip ID will be obtained by probing the device later */\n\tlpc2900_info->chipid = 0;\n\tlpc2900_info->is_probed = false;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Erase sector(s).\n *\n * @param bank Pointer to the flash bank descriptor\n * @param first First sector to be erased\n * @param last Last sector (including) to be erased\n */\nstatic int lpc2900_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint32_t status;\n\tunsigned int last_unsecured_sector;\n\tbool has_unsecured_sector;\n\tstruct target *target = bank->target;\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\n\n\tstatus = lpc2900_is_ready(bank);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\t/* Sanity check on sector range */\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_INFO(\"Bad sector range\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\t/* Update the info about secured sectors */\n\tlpc2900_read_security_status(bank);\n\n\t/* The selected sector range might include secured sectors. An attempt\n\t * to erase such a sector will cause the erase to fail also for unsecured\n\t * sectors. It is necessary to determine the last unsecured sector now,\n\t * because we have to treat the last relevant sector in the list in\n\t * a special way.\n\t */\n\tlast_unsecured_sector = -1;\n\thas_unsecured_sector = false;\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (!bank->sectors[sector].is_protected) {\n\t\t\tlast_unsecured_sector = sector;\n\t\t\thas_unsecured_sector = true;\n\t\t}\n\t}\n\n\t/* Exit now, in case of the rare constellation where all sectors in range\n\t * are secured. This is regarded a success, since erasing/programming of\n\t * secured sectors shall be handled transparently.\n\t */\n\tif (!has_unsecured_sector)\n\t\treturn ERROR_OK;\n\n\t/* Enable flash block and set the correct CRA clock of 66 kHz */\n\tlpc2900_setup(bank);\n\n\t/* Clear END_OF_ERASE interrupt status */\n\ttarget_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_ERASE);\n\n\t/* Set the program/erase timer to FLASH_ERASE_TIME */\n\ttarget_write_u32(target, FPTR,\n\t\tFPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc,\n\t\t\tFLASH_ERASE_TIME));\n\n\t/* Sectors are marked for erasure, then erased all together */\n\tfor (unsigned int sector = first; sector <= last_unsecured_sector; sector++) {\n\t\t/* Only mark sectors that aren't secured. Any attempt to erase a group\n\t\t * of sectors will fail if any single one of them is secured!\n\t\t */\n\t\tif (!bank->sectors[sector].is_protected) {\n\t\t\t/* Unprotect the sector */\n\t\t\ttarget_write_u32(target, bank->sectors[sector].offset, 0);\n\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\tFCTR_FS_LOADREQ | FCTR_FS_WPB |\n\t\t\t\tFCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS);\n\n\t\t\t/* Mark the sector for erasure. The last sector in the list\n\t\t\t   triggers the erasure. */\n\t\t\ttarget_write_u32(target, bank->sectors[sector].offset, 0);\n\t\t\tif (sector == last_unsecured_sector) {\n\t\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\t\tFCTR_FS_PROGREQ | FCTR_FS_WPB | FCTR_FS_CS);\n\t\t\t} else {\n\t\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\t\tFCTR_FS_LOADREQ | FCTR_FS_WPB |\n\t\t\t\t\tFCTR_FS_WEB | FCTR_FS_CS);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Wait for the end of the erase operation. If it's not over after two seconds,\n\t * something went dreadfully wrong... :-(\n\t */\n\tif (lpc2900_wait_status(bank, INTSRC_END_OF_ERASE, 2000) != ERROR_OK)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* Normal flash operating mode */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\treturn ERROR_OK;\n}\n\n/* lpc2900_protect command is not supported.\n* \"Protection\" in LPC2900 terms is handled transparently. Sectors will\n* automatically be unprotected as needed.\n* Instead we use the concept of sector security. A secured sector is shown\n* as \"protected\" in OpenOCD. Sector security is a permanent feature, and\n* cannot be disabled once activated.\n*/\n\n/**\n * Write data to flash.\n *\n * @param bank Pointer to the flash bank descriptor\n * @param buffer Buffer with data\n * @param offset Start address (relative to bank start)\n * @param count Number of bytes to be programmed\n */\nstatic int lpc2900_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tuint8_t page[FLASH_PAGE_SIZE];\n\tuint32_t status;\n\tuint32_t num_bytes;\n\tstruct target *target = bank->target;\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\tint retval;\n\n\tstatic const uint32_t write_target_code[] = {\n\t\t/* Set auto latch mode: FCTR=CS|WRE|WEB */\n\t\t0xe3a0a007,\t/* loop       mov r10, #0x007 */\n\t\t0xe583a000,\t/*            str r10,[r3,#0] */\n\n\t\t/* Load complete page into latches */\n\t\t0xe3a06020,\t/*            mov r6,#(512/16) */\n\t\t0xe8b00f00,\t/* next       ldmia r0!,{r8-r11} */\n\t\t0xe8a10f00,\t/*            stmia r1!,{r8-r11} */\n\t\t0xe2566001,\t/*            subs r6,#1 */\n\t\t0x1afffffb,\t/*            bne next */\n\n\t\t/* Clear END_OF_BURN interrupt status */\n\t\t0xe3a0a002,\t/*            mov r10,#(1 << 1) */\n\t\t0xe583afe8,\t/*            str r10,[r3,#0xfe8] */\n\n\t\t/* Set the erase time to FLASH_PROGRAM_TIME */\n\t\t0xe5834008,\t/*            str r4,[r3,#8] */\n\n\t\t/* Trigger flash write\n\t\t * FCTR = CS | WRE | WPB | PROGREQ */\n\t\t0xe3a0a083,\t/*            mov r10,#0x83 */\n\t\t0xe38aaa01,\t/*            orr r10,#0x1000 */\n\t\t0xe583a000,\t/*            str r10,[r3,#0] */\n\n\t\t/* Wait for end of burn */\n\t\t0xe593afe0,\t/* wait       ldr r10,[r3,#0xfe0] */\n\t\t0xe21aa002,\t/*            ands r10,#(1 << 1) */\n\t\t0x0afffffc,\t/*            beq wait */\n\n\t\t/* End? */\n\t\t0xe2522001,\t/*            subs r2,#1 */\n\t\t0x1affffed,\t/*            bne loop */\n\n\t\t0xeafffffe\t/* done       b done */\n\t};\n\n\n\tstatus = lpc2900_is_ready(bank);\n\tif (status != ERROR_OK)\n\t\treturn status;\n\n\t/* Enable flash block and set the correct CRA clock of 66 kHz */\n\tlpc2900_setup(bank);\n\n\t/* Update the info about secured sectors */\n\tlpc2900_read_security_status(bank);\n\n\t/* Unprotect all involved sectors */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start address in or before this sector?\n\t\t * End address in or behind this sector? */\n\t\tif (((bank->base + offset) <\n\t\t\t\t(bank->sectors[sector].offset + bank->sectors[sector].size)) &&\n\t\t\t\t((bank->base + (offset + count - 1)) >= bank->sectors[sector].offset)) {\n\t\t\t/* This sector is involved and needs to be unprotected.\n\t\t\t * Don't do it for secured sectors.\n\t\t\t */\n\t\t\tif (!bank->sectors[sector].is_protected) {\n\t\t\t\ttarget_write_u32(target, bank->sectors[sector].offset, 0);\n\t\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\t\tFCTR_FS_LOADREQ | FCTR_FS_WPB |\n\t\t\t\t\tFCTR_FS_WEB | FCTR_FS_WRE | FCTR_FS_CS);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Set the program/erase time to FLASH_PROGRAM_TIME */\n\tuint32_t prog_time = FPTR_EN_T | lpc2900_calc_tr(lpc2900_info->clk_sys_fmc, FLASH_PROGRAM_TIME);\n\n\t/* If there is a working area of reasonable size, use it to program via\n\t * a target algorithm. If not, fall back to host programming. */\n\n\t/* We need some room for target code. */\n\tconst uint32_t target_code_size = sizeof(write_target_code);\n\n\t/* Try working area allocation. Start with a large buffer, and try with\n\t * reduced size if that fails. */\n\tstruct working_area *warea;\n\tuint32_t buffer_size = lpc2900_info->max_ram_block - 1 * KiB;\n\twhile (target_alloc_working_area_try(target,\n\t\t\t\t buffer_size + target_code_size,\n\t\t\t\t &warea) != ERROR_OK) {\n\t\t/* Try a smaller buffer now, and stop if it's too small. */\n\t\tbuffer_size -= 1 * KiB;\n\t\tif (buffer_size < 2 * KiB) {\n\t\t\tLOG_INFO(\"no (large enough) working area, falling back to host mode\");\n\t\t\twarea = NULL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (warea) {\n\t\tstruct reg_param reg_params[5];\n\t\tstruct arm_algorithm arm_algo;\n\n\t\t/* We can use target mode. Download the algorithm. */\n\t\tuint8_t code[sizeof(write_target_code)];\n\t\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(write_target_code),\n\t\t\t\twrite_target_code);\n\t\tretval = target_write_buffer(target, (warea->address) + buffer_size, sizeof(code), code);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write block write code to target\");\n\t\t\ttarget_free_all_working_areas(target);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\t\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\n\t\t/* Write to flash in large blocks */\n\t\twhile (count != 0) {\n\t\t\tuint32_t this_npages;\n\t\t\tconst uint8_t *this_buffer;\n\t\t\tunsigned int start_sector = lpc2900_address2sector(bank, offset);\n\n\t\t\t/* First page / last page / rest */\n\t\t\tif (offset % FLASH_PAGE_SIZE) {\n\t\t\t\t/* Block doesn't start on page boundary.\n\t\t\t\t * Burn first partial page separately. */\n\t\t\t\tmemset(&page, 0xff, sizeof(page));\n\t\t\t\tmemcpy(&page[offset % FLASH_PAGE_SIZE],\n\t\t\t\t\tbuffer,\n\t\t\t\t\tFLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE));\n\t\t\t\tthis_npages = 1;\n\t\t\t\tthis_buffer = &page[0];\n\t\t\t\tcount = count + (offset % FLASH_PAGE_SIZE);\n\t\t\t\toffset = offset - (offset % FLASH_PAGE_SIZE);\n\t\t\t} else if (count < FLASH_PAGE_SIZE) {\n\t\t\t\t/* Download last incomplete page separately. */\n\t\t\t\tmemset(&page, 0xff, sizeof(page));\n\t\t\t\tmemcpy(&page, buffer, count);\n\t\t\t\tthis_npages = 1;\n\t\t\t\tthis_buffer = &page[0];\n\t\t\t\tcount = FLASH_PAGE_SIZE;\n\t\t\t} else {\n\t\t\t\t/* Download as many full pages as possible */\n\t\t\t\tthis_npages = (count < buffer_size) ?\n\t\t\t\t\tcount / FLASH_PAGE_SIZE :\n\t\t\t\t\tbuffer_size / FLASH_PAGE_SIZE;\n\t\t\t\tthis_buffer = buffer;\n\n\t\t\t\t/* Make sure we stop at the next secured sector */\n\t\t\t\tunsigned int sector = start_sector + 1;\n\t\t\t\twhile (sector < bank->num_sectors) {\n\t\t\t\t\t/* Secured? */\n\t\t\t\t\tif (bank->sectors[sector].is_protected) {\n\t\t\t\t\t\t/* Is that next sector within the current block? */\n\t\t\t\t\t\tif ((bank->sectors[sector].offset - bank->base) <\n\t\t\t\t\t\t\t\t(offset + (this_npages * FLASH_PAGE_SIZE))) {\n\t\t\t\t\t\t\t/* Yes! Split the block */\n\t\t\t\t\t\t\tthis_npages =\n\t\t\t\t\t\t\t\t(bank->sectors[sector].offset -\n\t\t\t\t\t\t\t\t bank->base - offset)\n\t\t\t\t\t\t\t\t/ FLASH_PAGE_SIZE;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tsector++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Skip the current sector if it is secured */\n\t\t\tif (bank->sectors[start_sector].is_protected) {\n\t\t\t\tLOG_DEBUG(\"Skip secured sector %u\",\n\t\t\t\t\tstart_sector);\n\n\t\t\t\t/* Stop if this is the last sector */\n\t\t\t\tif (start_sector == bank->num_sectors - 1)\n\t\t\t\t\tbreak;\n\n\t\t\t\t/* Skip */\n\t\t\t\tuint32_t nskip = bank->sectors[start_sector].size -\n\t\t\t\t\t(offset % bank->sectors[start_sector].size);\n\t\t\t\toffset += nskip;\n\t\t\t\tbuffer += nskip;\n\t\t\t\tcount = (count >= nskip) ? (count - nskip) : 0;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Execute buffer download */\n\t\t\tretval = target_write_buffer(target, warea->address,\n\t\t\t\t\tthis_npages * FLASH_PAGE_SIZE, this_buffer);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Unable to write data to target\");\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\t/* Prepare registers */\n\t\t\tbuf_set_u32(reg_params[0].value, 0, 32, warea->address);\n\t\t\tbuf_set_u32(reg_params[1].value, 0, 32, offset);\n\t\t\tbuf_set_u32(reg_params[2].value, 0, 32, this_npages);\n\t\t\tbuf_set_u32(reg_params[3].value, 0, 32, FCTR);\n\t\t\tbuf_set_u32(reg_params[4].value, 0, 32, FPTR_EN_T | prog_time);\n\n\t\t\t/* Execute algorithm, assume breakpoint for last instruction */\n\t\t\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\t\t\tarm_algo.core_mode = ARM_MODE_SVC;\n\t\t\tarm_algo.core_state = ARM_STATE_ARM;\n\n\t\t\tretval = target_run_algorithm(target, 0, NULL, 5, reg_params,\n\t\t\t\t\t(warea->address) + buffer_size,\n\t\t\t\t\t(warea->address) + buffer_size + target_code_size - 4,\n\t\t\t\t\t10000,\t/* 10s should be enough for max. 16 KiB of data */\n\t\t\t\t\t&arm_algo);\n\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Execution of flash algorithm failed.\");\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcount -= this_npages * FLASH_PAGE_SIZE;\n\t\t\tbuffer += this_npages * FLASH_PAGE_SIZE;\n\t\t\toffset += this_npages * FLASH_PAGE_SIZE;\n\t\t}\n\n\t\t/* Free all resources */\n\t\tdestroy_reg_param(&reg_params[0]);\n\t\tdestroy_reg_param(&reg_params[1]);\n\t\tdestroy_reg_param(&reg_params[2]);\n\t\tdestroy_reg_param(&reg_params[3]);\n\t\tdestroy_reg_param(&reg_params[4]);\n\t\ttarget_free_all_working_areas(target);\n\t} else {\n\t\t/* Write to flash memory page-wise */\n\t\twhile (count != 0) {\n\t\t\t/* How many bytes do we copy this time? */\n\t\t\tnum_bytes = (count >= FLASH_PAGE_SIZE) ?\n\t\t\t\tFLASH_PAGE_SIZE - (offset % FLASH_PAGE_SIZE) :\n\t\t\t\tcount;\n\n\t\t\t/* Don't do anything with it if the page is in a secured sector. */\n\t\t\tif (!bank->sectors[lpc2900_address2sector(bank, offset)].is_protected) {\n\t\t\t\t/* Set latch load mode */\n\t\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\t\tFCTR_FS_CS | FCTR_FS_WRE | FCTR_FS_WEB);\n\n\t\t\t\t/* Always clear the buffer (a little overhead, but who cares) */\n\t\t\t\tmemset(page, 0xFF, FLASH_PAGE_SIZE);\n\n\t\t\t\t/* Copy them to the buffer */\n\t\t\t\tmemcpy(&page[offset % FLASH_PAGE_SIZE],\n\t\t\t\t\t&buffer[offset % FLASH_PAGE_SIZE],\n\t\t\t\t\tnum_bytes);\n\n\t\t\t\t/* Write whole page to flash data latches */\n\t\t\t\tif (target_write_memory(target,\n\t\t\t\t\t\tbank->base + (offset - (offset % FLASH_PAGE_SIZE)),\n\t\t\t\t\t\t4, FLASH_PAGE_SIZE / 4, page) != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Write failed @ 0x%8.8\" PRIx32, offset);\n\t\t\t\t\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t}\n\n\t\t\t\t/* Clear END_OF_BURN interrupt status */\n\t\t\t\ttarget_write_u32(target, INT_CLR_STATUS, INTSRC_END_OF_BURN);\n\n\t\t\t\t/* Set the programming time */\n\t\t\t\ttarget_write_u32(target, FPTR, FPTR_EN_T | prog_time);\n\n\t\t\t\t/* Trigger flash write */\n\t\t\t\ttarget_write_u32(target, FCTR,\n\t\t\t\t\tFCTR_FS_CS | FCTR_FS_WRE | FCTR_FS_WPB | FCTR_FS_PROGREQ);\n\n\t\t\t\t/* Wait for the end of the write operation. If it's not over\n\t\t\t\t * after one second, something went dreadfully wrong... :-(\n\t\t\t\t */\n\t\t\t\tif (lpc2900_wait_status(bank, INTSRC_END_OF_BURN, 1000) != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Write failed @ 0x%8.8\" PRIx32, offset);\n\t\t\t\t\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Update pointers and counters */\n\t\t\toffset += num_bytes;\n\t\t\tbuffer += num_bytes;\n\t\t\tcount -= num_bytes;\n\t\t}\n\n\t\tretval = ERROR_OK;\n\t}\n\n\t/* Normal flash operating mode */\n\ttarget_write_u32(target, FCTR, FCTR_FS_CS | FCTR_FS_WEB);\n\n\treturn retval;\n}\n\n/**\n * Try and identify the device.\n *\n * Determine type number and its memory layout.\n *\n * @param bank Pointer to the flash bank descriptor\n */\nstatic int lpc2900_probe(struct flash_bank *bank)\n{\n\tstruct lpc2900_flash_bank *lpc2900_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t offset;\n\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* We want to do this only once. */\n\tif (lpc2900_info->is_probed)\n\t\treturn ERROR_OK;\n\n\t/* Probing starts with reading the CHIPID register. We will continue only\n\t * if this identifies as an LPC2900 device.\n\t */\n\ttarget_read_u32(target, CHIPID, &lpc2900_info->chipid);\n\n\tif (lpc2900_info->chipid != EXPECTED_CHIPID) {\n\t\tLOG_WARNING(\"Device is not an LPC29xx\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* It's an LPC29xx device. Now read the feature register FEAT0...FEAT3. */\n\tuint32_t feat0, feat1, feat2, feat3;\n\ttarget_read_u32(target, FEAT0, &feat0);\n\ttarget_read_u32(target, FEAT1, &feat1);\n\ttarget_read_u32(target, FEAT2, &feat2);\n\ttarget_read_u32(target, FEAT3, &feat3);\n\n\t/* Base address */\n\tbank->base = 0x20000000;\n\n\t/* Determine flash layout from FEAT2 register */\n\tuint32_t num_64k_sectors = (feat2 >> 16) & 0xFF;\n\tuint32_t num_8k_sectors = (feat2 >> 0) & 0xFF;\n\tbank->num_sectors = num_64k_sectors + num_8k_sectors;\n\tbank->size = KiB * (64 * num_64k_sectors + 8 * num_8k_sectors);\n\n\t/* Determine maximum contiguous RAM block */\n\tlpc2900_info->max_ram_block = 16 * KiB;\n\tif ((feat1 & 0x30) == 0x30) {\n\t\tlpc2900_info->max_ram_block = 32 * KiB;\n\t\tif ((feat1 & 0x0C) == 0x0C)\n\t\t\tlpc2900_info->max_ram_block = 48 * KiB;\n\t}\n\n\t/* Determine package code and ITCM size */\n\tuint32_t package_code = feat0 & 0x0F;\n\tuint32_t itcm_code = (feat1 >> 16) & 0x1F;\n\n\t/* Determine the exact type number. */\n\tuint32_t found = 1;\n\tif ((package_code == 4) && (itcm_code == 5)) {\n\t\t/* Old LPC2917 or LPC2919 (non-/01 devices) */\n\t\tlpc2900_info->target_name = (bank->size == 768*KiB) ? \"LPC2919\" : \"LPC2917\";\n\t} else {\n\t\tif (package_code == 2) {\n\t\t\t/* 100-pin package */\n\t\t\tif (bank->size == 128*KiB)\n\t\t\t\tlpc2900_info->target_name = \"LPC2921\";\n\t\t\telse if (bank->size == 256*KiB)\n\t\t\t\tlpc2900_info->target_name = \"LPC2923\";\n\t\t\telse if (bank->size == 512*KiB)\n\t\t\t\tlpc2900_info->target_name = \"LPC2925\";\n\t\t\telse\n\t\t\t\tfound = 0;\n\t\t} else if (package_code == 4) {\n\t\t\t/* 144-pin package */\n\t\t\tif ((bank->size == 256*KiB) && (feat3 == 0xFFFFFFE9))\n\t\t\t\tlpc2900_info->target_name = \"LPC2926\";\n\t\t\telse if ((bank->size == 512*KiB) && (feat3 == 0xFFFFFCF0))\n\t\t\t\tlpc2900_info->target_name = \"LPC2917/01\";\n\t\t\telse if ((bank->size == 512*KiB) && (feat3 == 0xFFFFFFF1))\n\t\t\t\tlpc2900_info->target_name = \"LPC2927\";\n\t\t\telse if ((bank->size == 768*KiB) && (feat3 == 0xFFFFFCF8))\n\t\t\t\tlpc2900_info->target_name = \"LPC2919/01\";\n\t\t\telse if ((bank->size == 768*KiB) && (feat3 == 0xFFFFFFF9))\n\t\t\t\tlpc2900_info->target_name = \"LPC2929\";\n\t\t\telse\n\t\t\t\tfound = 0;\n\t\t} else if (package_code == 5) {\n\t\t\t/* 208-pin package */\n\t\t\tlpc2900_info->target_name = (bank->size == 0) ? \"LPC2930\" : \"LPC2939\";\n\t\t} else\n\t\t\tfound = 0;\n\t}\n\n\tif (!found) {\n\t\tLOG_WARNING(\"Unknown LPC29xx derivative (FEATx=\"\n\t\t\t\"%08\" PRIx32 \":%08\" PRIx32 \":%08\" PRIx32 \":%08\" PRIx32 \")\",\n\t\t\tfeat0, feat1, feat2, feat3);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Show detected device */\n\tLOG_INFO(\"Flash bank %u: Device %s, %\" PRIu32\n\t\t\" KiB in %u sectors\",\n\t\tbank->bank_number,\n\t\tlpc2900_info->target_name, bank->size / KiB,\n\t\tbank->num_sectors);\n\n\t/* Flashless devices cannot be handled */\n\tif (bank->num_sectors == 0) {\n\t\tLOG_WARNING(\"Flashless device cannot be handled\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Sector layout.\n\t * These are logical sector numbers. When doing real flash operations,\n\t * the logical flash number are translated into the physical flash numbers\n\t * of the device.\n\t */\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\n\toffset = 0;\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\n\t\tif (i <= 7)\n\t\t\tbank->sectors[i].size = 8 * KiB;\n\t\telse if (i <= 18)\n\t\t\tbank->sectors[i].size = 64 * KiB;\n\t\telse {\n\t\t\t/* We shouldn't come here. But there might be a new part out there\n\t\t\t * that has more than 19 sectors. Politely ask for a fix then.\n\t\t\t */\n\t\t\tbank->sectors[i].size = 0;\n\t\t\tLOG_ERROR(\"Never heard about sector %u\", i);\n\t\t}\n\n\t\toffset += bank->sectors[i].size;\n\t}\n\n\tlpc2900_info->is_probed = true;\n\n\t/* Read sector security status */\n\tif (lpc2900_read_security_status(bank) != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot determine sector security status\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Run a blank check for each sector.\n *\n * For speed reasons, the device isn't read word by word.\n * A hash value is calculated by the hardware (\"BIST\") for each sector.\n * This value is then compared against the known hash of an empty sector.\n *\n * @param bank Pointer to the flash bank descriptor\n */\nstatic int lpc2900_erase_check(struct flash_bank *bank)\n{\n\tuint32_t status = lpc2900_is_ready(bank);\n\tif (status != ERROR_OK) {\n\t\tLOG_INFO(\"Processor not halted/not probed\");\n\t\treturn status;\n\t}\n\n\t/* Use the BIST (Built-In Self Test) to generate a signature of each flash\n\t * sector. Compare against the expected signature of an empty sector.\n\t */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tuint32_t signature[4];\n\t\tstatus = lpc2900_run_bist128(bank, bank->sectors[sector].offset,\n\t\t\t\tbank->sectors[sector].offset + (bank->sectors[sector].size - 1), signature);\n\t\tif (status != ERROR_OK)\n\t\t\treturn status;\n\n\t\t/* The expected signatures for an empty sector are different\n\t\t * for 8 KiB and 64 KiB sectors.\n\t\t */\n\t\tif (bank->sectors[sector].size == 8*KiB) {\n\t\t\tbank->sectors[sector].is_erased =\n\t\t\t\t(signature[3] == 0x01ABAAAA) &&\n\t\t\t\t(signature[2] == 0xAAAAAAAA) &&\n\t\t\t\t(signature[1] == 0xAAAAAAAA) &&\n\t\t\t\t(signature[0] == 0xAAA00AAA);\n\t\t}\n\t\tif (bank->sectors[sector].size == 64*KiB) {\n\t\t\tbank->sectors[sector].is_erased =\n\t\t\t\t(signature[3] == 0x11801222) &&\n\t\t\t\t(signature[2] == 0xB88844FF) &&\n\t\t\t\t(signature[1] == 0x11A22008) &&\n\t\t\t\t(signature[0] == 0x2B1BFE44);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Get protection (sector security) status.\n *\n * Determine the status of \"sector security\" for each sector.\n * A secured sector is one that can never be erased/programmed again.\n *\n * @param bank Pointer to the flash bank descriptor\n */\nstatic int lpc2900_protect_check(struct flash_bank *bank)\n{\n\treturn lpc2900_read_security_status(bank);\n}\n\nconst struct flash_driver lpc2900_flash = {\n\t.name = \"lpc2900\",\n\t.commands = lpc2900_command_handlers,\n\t.flash_bank_command = lpc2900_flash_bank_command,\n\t.erase = lpc2900_erase,\n\t.write = lpc2900_write,\n\t.read = default_flash_read,\n\t.probe = lpc2900_probe,\n\t.auto_probe = lpc2900_probe,\n\t.erase_check = lpc2900_erase_check,\n\t.protect_check = lpc2900_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/lpcspifi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <jtag/jtag.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n/* Offsets from ssp_base into config & data registers */\n#define SSP_CR0\t\t(0x00)  /* Control register 0 */\n#define SSP_CR1\t\t(0x04)  /* Control register 1 */\n#define SSP_DATA\t(0x08)  /* Data register (TX and RX) */\n#define SSP_SR\t\t(0x0C)  /* Status register */\n#define SSP_CPSR\t(0x10)  /* Clock prescale register */\n\n/* Status register fields */\n#define SSP_BSY\t\t(0x00000010)\n\n/* Timeout in ms */\n#define SSP_CMD_TIMEOUT   (100)\n#define SSP_PROBE_TIMEOUT (100)\n#define SSP_MAX_TIMEOUT  (3000)\n\n/* Size of the stack to alloc in the working area for the execution of\n * the ROM spifi_init() function */\n#define SPIFI_INIT_STACK_SIZE  512\n\nstruct lpcspifi_flash_bank {\n\tbool probed;\n\tuint32_t ssp_base;\n\tuint32_t io_base;\n\tuint32_t ioconfig_base;\n\tuint32_t bank_num;\n\tuint32_t max_spi_clock_mhz;\n\tconst struct flash_device *dev;\n};\n\n/* flash_bank lpcspifi <base> <size> <chip_width> <bus_width> <target>\n */\nFLASH_BANK_COMMAND_HANDLER(lpcspifi_flash_bank_command)\n{\n\tstruct lpcspifi_flash_bank *lpcspifi_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlpcspifi_info = malloc(sizeof(struct lpcspifi_flash_bank));\n\tif (!lpcspifi_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = lpcspifi_info;\n\tlpcspifi_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\nstatic inline int ioconfig_write_reg(struct target *target, uint32_t ioconfig_base, uint32_t offset, uint32_t value)\n{\n\treturn target_write_u32(target, ioconfig_base + offset, value);\n}\n\nstatic inline int ssp_write_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t value)\n{\n\treturn target_write_u32(target, ssp_base + offset, value);\n}\n\nstatic inline int io_write_reg(struct target *target, uint32_t io_base, uint32_t offset, uint32_t value)\n{\n\treturn target_write_u32(target, io_base + offset, value);\n}\n\nstatic inline int ssp_read_reg(struct target *target, uint32_t ssp_base, uint32_t offset, uint32_t *value)\n{\n\treturn target_read_u32(target, ssp_base + offset, value);\n}\n\nstatic int ssp_setcs(struct target *target, uint32_t io_base, unsigned int value)\n{\n\treturn io_write_reg(target, io_base, 0x12ac, value ? 0xffffffff : 0x00000000);\n}\n\n/* Poll the SSP busy flag. When this comes back as 0, the transfer is complete\n * and the controller is idle. */\nstatic int poll_ssp_busy(struct target *target, uint32_t ssp_base, int timeout)\n{\n\tint64_t endtime;\n\tuint32_t value;\n\tint retval;\n\n\tretval = ssp_read_reg(target, ssp_base, SSP_SR, &value);\n\tif ((retval == ERROR_OK) && (value & SSP_BSY) == 0)\n\t\treturn ERROR_OK;\n\telse if (retval != ERROR_OK)\n\t\treturn retval;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\talive_sleep(1);\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_SR, &value);\n\t\tif ((retval == ERROR_OK) && (value & SSP_BSY) == 0)\n\t\t\treturn ERROR_OK;\n\t\telse if (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"Timeout while polling BSY\");\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n/* Un-initialize the ssp module and initialize the SPIFI module */\nstatic int lpcspifi_set_hw_mode(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *spifi_init_algorithm;\n\tstruct reg_param reg_params[2];\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"Uninitializing LPC43xx SSP\");\n\t/* Turn off the SSP module */\n\tretval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* see contrib/loaders/flash/lpcspifi_init.S for src */\n\tstatic const uint8_t spifi_init_code[] = {\n\t\t0x4f, 0xea, 0x00, 0x08, 0xa1, 0xb0, 0x00, 0xaf,\n\t\t0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,\n\t\t0x4f, 0xf0, 0xf3, 0x02, 0xc3, 0xf8, 0x8c, 0x21,\n\t\t0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,\n\t\t0x4f, 0xf4, 0xc0, 0x42, 0xc4, 0xf2, 0x08, 0x02,\n\t\t0x4f, 0xf4, 0xc0, 0x41, 0xc4, 0xf2, 0x08, 0x01,\n\t\t0x4f, 0xf4, 0xc0, 0x40, 0xc4, 0xf2, 0x08, 0x00,\n\t\t0x4f, 0xf0, 0xd3, 0x04, 0xc0, 0xf8, 0x9c, 0x41,\n\t\t0x20, 0x46, 0xc1, 0xf8, 0x98, 0x01, 0x01, 0x46,\n\t\t0xc2, 0xf8, 0x94, 0x11, 0xc3, 0xf8, 0x90, 0x11,\n\t\t0x4f, 0xf4, 0xc0, 0x43, 0xc4, 0xf2, 0x08, 0x03,\n\t\t0x4f, 0xf0, 0x13, 0x02, 0xc3, 0xf8, 0xa0, 0x21,\n\t\t0x40, 0xf2, 0x18, 0x13, 0xc1, 0xf2, 0x40, 0x03,\n\t\t0x1b, 0x68, 0x1c, 0x68, 0x40, 0xf2, 0xb4, 0x30,\n\t\t0xc1, 0xf2, 0x00, 0x00, 0x4f, 0xf0, 0x03, 0x01,\n\t\t0x4f, 0xf0, 0xc0, 0x02, 0x4f, 0xea, 0x08, 0x03,\n\t\t0xa0, 0x47, 0x00, 0xf0, 0x00, 0xb8, 0x00, 0xbe\n\t};\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\n\tLOG_DEBUG(\"Allocating working area for SPIFI init algorithm\");\n\t/* Get memory for spifi initialization algorithm */\n\tretval = target_alloc_working_area(target, sizeof(spifi_init_code)\n\t\t+ SPIFI_INIT_STACK_SIZE, &spifi_init_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Insufficient working area to initialize SPIFI \"\n\t\t\t\"module. You must allocate at least %zdB of working \"\n\t\t\t\"area in order to use this driver.\",\n\t\t\tsizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE\n\t\t);\n\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"Writing algorithm to working area at \" TARGET_ADDR_FMT,\n\t\tspifi_init_algorithm->address);\n\t/* Write algorithm to working area */\n\tretval = target_write_buffer(target,\n\t\tspifi_init_algorithm->address,\n\t\tsizeof(spifi_init_code),\n\t\tspifi_init_code\n\t);\n\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, spifi_init_algorithm);\n\t\treturn retval;\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\t\t/* spifi clk speed */\n\t/* the spifi_init() rom API makes use of the stack */\n\tinit_reg_param(&reg_params[1], \"sp\", 32, PARAM_OUT);\n\n\t/* For now, the algorithm will set up the SPIFI module\n\t * @ the IRC clock speed. In the future, it could be made\n\t * a bit smarter to use other clock sources if the user has\n\t * already configured them in order to speed up memory-\n\t * mapped reads. */\n\tbuf_set_u32(reg_params[0].value, 0, 32, 12);\n\t/* valid stack pointer */\n\tbuf_set_u32(reg_params[1].value, 0, 32, (spifi_init_algorithm->address +\n\t\tsizeof(spifi_init_code) + SPIFI_INIT_STACK_SIZE) & ~7UL);\n\n\t/* Run the algorithm */\n\tLOG_DEBUG(\"Running SPIFI init algorithm\");\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params,\n\t\tspifi_init_algorithm->address,\n\t\tspifi_init_algorithm->address + sizeof(spifi_init_code) - 2,\n\t\t1000, &armv7m_info);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error executing SPIFI init algorithm\");\n\n\ttarget_free_working_area(target, spifi_init_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\treturn retval;\n}\n\n/* Initialize the ssp module */\nstatic int lpcspifi_set_sw_mode(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tuint32_t io_base = lpcspifi_info->io_base;\n\tuint32_t ioconfig_base = lpcspifi_info->ioconfig_base;\n\tint retval = ERROR_OK;\n\n\t/* Re-initialize SPIFI. There are a couple of errata on this, so this makes\n\tsure that nothing's in an unhappy state. */\n\tretval = lpcspifi_set_hw_mode(bank);\n\n\t/* If we couldn't initialize hardware mode, don't even bother continuing */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize the pins */\n\tretval = ioconfig_write_reg(target, ioconfig_base, 0x194, 0x00000040);\n\tif (retval == ERROR_OK)\n\t\tretval = ioconfig_write_reg(target, ioconfig_base, 0x1a0, 0x00000044);\n\tif (retval == ERROR_OK)\n\t\tretval = ioconfig_write_reg(target, ioconfig_base, 0x190, 0x00000040);\n\tif (retval == ERROR_OK)\n\t\tretval = ioconfig_write_reg(target, ioconfig_base, 0x19c, 0x000000ed);\n\tif (retval == ERROR_OK)\n\t\tretval = ioconfig_write_reg(target, ioconfig_base, 0x198, 0x000000ed);\n\tif (retval == ERROR_OK)\n\t\tretval = ioconfig_write_reg(target, ioconfig_base, 0x18c, 0x000000ea);\n\n\t/* Set CS high & as an output */\n\tif (retval == ERROR_OK)\n\t\tretval = io_write_reg(target, io_base, 0x12ac, 0xffffffff);\n\tif (retval == ERROR_OK)\n\t\tretval = io_write_reg(target, io_base, 0x2014, 0x00000800);\n\n\t/* Initialize the module */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_CR0, 0x00000007);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000000);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_CPSR, 0x00000008);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_CR1, 0x00000002);\n\n\t/* If something didn't work out, attempt to return SPIFI to HW mode */\n\tif (retval != ERROR_OK)\n\t\tlpcspifi_set_hw_mode(bank);\n\n\treturn retval;\n}\n\n/* Read the status register of the external SPI flash chip. */\nstatic int read_status_reg(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tuint32_t io_base = lpcspifi_info->io_base;\n\tuint32_t value;\n\tint retval = ERROR_OK;\n\n\tretval = ssp_setcs(target, io_base, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_STATUS);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\t/* Dummy write to clock in the register */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_setcs(target, io_base, 1);\n\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\t*status = value;\n\n\treturn retval;\n}\n\n/* check for BSY bit in flash status register */\n/* timeout in ms */\nstatic int wait_till_ready(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\tint retval;\n\tint64_t endtime;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\t/* read flash status register */\n\t\tretval = read_status_reg(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & SPIFLASH_BSY_BIT) == 0)\n\t\t\treturn ERROR_OK;\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout waiting for flash to finish write/erase operation\");\n\treturn ERROR_FAIL;\n}\n\n/* Send \"write enable\" command to SPI flash chip. */\nstatic int lpcspifi_write_enable(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tuint32_t io_base = lpcspifi_info->io_base;\n\tuint32_t status, value;\n\tint retval = ERROR_OK;\n\n\tretval = ssp_setcs(target, io_base, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_WRITE_ENABLE);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_setcs(target, io_base, 1);\n\n\t/* read flash status register */\n\tif (retval == ERROR_OK)\n\t\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check write enabled */\n\tif ((status & SPIFLASH_WE_BIT) == 0) {\n\t\tLOG_ERROR(\"Cannot enable write to flash. Status=0x%08\" PRIx32, status);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic int lpcspifi_bulk_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tuint32_t io_base = lpcspifi_info->io_base;\n\tuint32_t value;\n\tint retval = ERROR_OK;\n\n\tif (lpcspifi_info->dev->chip_erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tretval = lpcspifi_set_sw_mode(bank);\n\n\tif (retval == ERROR_OK)\n\t\tretval = lpcspifi_write_enable(bank);\n\n\t/* send SPI command \"bulk erase\" */\n\tif (retval == ERROR_OK)\n\t\tssp_setcs(target, io_base, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, lpcspifi_info->dev->chip_erase_cmd);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_setcs(target, io_base, 1);\n\n\t/* poll flash BSY for self-timed bulk erase */\n\tif (retval == ERROR_OK)\n\t\tretval = wait_till_ready(bank, bank->num_sectors*SSP_MAX_TIMEOUT);\n\n\treturn retval;\n}\n\nstatic int lpcspifi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *erase_algorithm;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"erase from sector %u to sector %u\", first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!(lpcspifi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* If we're erasing the entire chip and the flash supports\n\t * it, use a bulk erase instead of going sector-by-sector. */\n\tif (first == 0 && last == (bank->num_sectors - 1)\n\t\t&& lpcspifi_info->dev->chip_erase_cmd != lpcspifi_info->dev->erase_cmd) {\n\t\tLOG_DEBUG(\"Chip supports the bulk erase command.\"\n\t\t\" Will use bulk erase instead of sector-by-sector erase.\");\n\t\tretval = lpcspifi_bulk_erase(bank);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tretval = lpcspifi_set_hw_mode(bank);\n\t\t\treturn retval;\n\t\t} else\n\t\t\tLOG_WARNING(\"Bulk flash erase failed. Falling back to sector-by-sector erase.\");\n\t}\n\n\tif (lpcspifi_info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tretval = lpcspifi_set_hw_mode(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* see contrib/loaders/flash/lpcspifi_erase.S for src */\n\tstatic const uint8_t lpcspifi_flash_erase_code[] = {\n\t\t0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,\n\t\t0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,\n\t\t0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,\n\t\t0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,\n\t\t0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,\n\t\t0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,\n\t\t0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,\n\t\t0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,\n\t\t0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,\n\t\t0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,\n\t\t0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,\n\t\t0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,\n\t\t0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,\n\t\t0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,\n\t\t0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,\n\t\t0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,\n\t\t0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,\n\t\t0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,\n\t\t0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,\n\t\t0x00, 0xf0, 0x52, 0xf8, 0x4f, 0xf0, 0x06, 0x09,\n\t\t0x00, 0xf0, 0x3b, 0xf8, 0x00, 0xf0, 0x48, 0xf8,\n\t\t0x00, 0xf0, 0x4a, 0xf8, 0x4f, 0xf0, 0x05, 0x09,\n\t\t0x00, 0xf0, 0x33, 0xf8, 0x4f, 0xf0, 0x00, 0x09,\n\t\t0x00, 0xf0, 0x2f, 0xf8, 0x00, 0xf0, 0x3c, 0xf8,\n\t\t0x19, 0xf0, 0x02, 0x0f, 0x00, 0xf0, 0x45, 0x80,\n\t\t0x00, 0xf0, 0x3a, 0xf8, 0x4f, 0xea, 0x02, 0x09,\n\t\t0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xea, 0x10, 0x49,\n\t\t0x00, 0xf0, 0x1f, 0xf8, 0x4f, 0xea, 0x10, 0x29,\n\t\t0x00, 0xf0, 0x1b, 0xf8, 0x4f, 0xea, 0x00, 0x09,\n\t\t0x00, 0xf0, 0x17, 0xf8, 0x00, 0xf0, 0x24, 0xf8,\n\t\t0x00, 0xf0, 0x26, 0xf8, 0x4f, 0xf0, 0x05, 0x09,\n\t\t0x00, 0xf0, 0x0f, 0xf8, 0x4f, 0xf0, 0x00, 0x09,\n\t\t0x00, 0xf0, 0x0b, 0xf8, 0x00, 0xf0, 0x18, 0xf8,\n\t\t0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4, 0xf0, 0xaf,\n\t\t0x01, 0x39, 0xf9, 0xb1, 0x18, 0x44, 0xff, 0xf7,\n\t\t0xbf, 0xbf, 0x4f, 0xf4, 0x40, 0x5a, 0xc4, 0xf2,\n\t\t0x08, 0x0a, 0xca, 0xf8, 0x08, 0x90, 0xda, 0xf8,\n\t\t0x0c, 0x90, 0x19, 0xf0, 0x10, 0x0f, 0x7f, 0xf4,\n\t\t0xfa, 0xaf, 0xda, 0xf8, 0x08, 0x90, 0x70, 0x47,\n\t\t0x4f, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0x02, 0xb8,\n\t\t0x4f, 0xf0, 0x00, 0x08, 0x4f, 0xf4, 0x80, 0x4a,\n\t\t0xc4, 0xf2, 0x0f, 0x0a, 0xca, 0xf8, 0xab, 0x80,\n\t\t0x70, 0x47, 0x00, 0x20, 0x00, 0xbe, 0xff, 0xff\n\t};\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\n\t/* Get memory for spifi initialization algorithm */\n\tretval = target_alloc_working_area(target, sizeof(lpcspifi_flash_erase_code),\n\t\t&erase_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Insufficient working area. You must configure a working\"\n\t\t\t\" area of at least %zdB in order to erase SPIFI flash.\",\n\t\t\tsizeof(lpcspifi_flash_erase_code));\n\t\treturn retval;\n\t}\n\n\t/* Write algorithm to working area */\n\tretval = target_write_buffer(target, erase_algorithm->address,\n\t\tsizeof(lpcspifi_flash_erase_code), lpcspifi_flash_erase_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, erase_algorithm);\n\t\treturn retval;\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* Start address */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* Sector count */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* Erase command */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* Sector size */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, bank->sectors[first].offset);\n\tbuf_set_u32(reg_params[1].value, 0, 32, last - first + 1);\n\tbuf_set_u32(reg_params[2].value, 0, 32, lpcspifi_info->dev->erase_cmd);\n\tbuf_set_u32(reg_params[3].value, 0, 32, bank->sectors[first].size);\n\n\t/* Run the algorithm */\n\tretval = target_run_algorithm(target, 0, NULL, 4, reg_params,\n\t\terase_algorithm->address,\n\t\terase_algorithm->address + sizeof(lpcspifi_flash_erase_code) - 4,\n\t\t3000*(last - first + 1), &armv7m_info);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error executing flash erase algorithm\");\n\n\ttarget_free_working_area(target, erase_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\tretval = lpcspifi_set_hw_mode(bank);\n\n\treturn retval;\n}\n\nstatic int lpcspifi_protect(struct flash_bank *bank, int set,\n\tunsigned int first, unsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\treturn ERROR_OK;\n}\n\nstatic int lpcspifi_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t page_size, fifo_size;\n\tstruct working_area *fifo;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *write_algorithm;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\toffset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > lpcspifi_info->dev->size_in_bytes) {\n\t\tLOG_WARNING(\"Writes past end of flash. Extra data discarded.\");\n\t\tcount = lpcspifi_info->dev->size_in_bytes - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tif ((offset <\n\t\t\t\t(bank->sectors[sector].offset + bank->sectors[sector].size))\n\t\t\t&& ((offset + count - 1) >= bank->sectors[sector].offset)\n\t\t\t&& bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* if no valid page_size, use reasonable default */\n\tpage_size = lpcspifi_info->dev->pagesize ?\n\t\tlpcspifi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\tretval = lpcspifi_set_hw_mode(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* see contrib/loaders/flash/lpcspifi_write.S for src */\n\tstatic const uint8_t lpcspifi_flash_write_code[] = {\n\t\t0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x08, 0x0a,\n\t\t0x4f, 0xf0, 0xea, 0x08, 0xca, 0xf8, 0x8c, 0x81,\n\t\t0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x90, 0x81,\n\t\t0x4f, 0xf0, 0x40, 0x08, 0xca, 0xf8, 0x94, 0x81,\n\t\t0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x98, 0x81,\n\t\t0x4f, 0xf0, 0xed, 0x08, 0xca, 0xf8, 0x9c, 0x81,\n\t\t0x4f, 0xf0, 0x44, 0x08, 0xca, 0xf8, 0xa0, 0x81,\n\t\t0x4f, 0xf4, 0xc0, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,\n\t\t0x4f, 0xf4, 0x00, 0x68, 0xca, 0xf8, 0x14, 0x80,\n\t\t0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,\n\t\t0x4f, 0xf0, 0xff, 0x08, 0xca, 0xf8, 0xab, 0x80,\n\t\t0x4f, 0xf0, 0x00, 0x0a, 0xc4, 0xf2, 0x05, 0x0a,\n\t\t0x4f, 0xf0, 0x00, 0x08, 0xc0, 0xf2, 0x00, 0x18,\n\t\t0xca, 0xf8, 0x94, 0x80, 0x4f, 0xf4, 0x00, 0x5a,\n\t\t0xc4, 0xf2, 0x05, 0x0a, 0x4f, 0xf0, 0x01, 0x08,\n\t\t0xca, 0xf8, 0x00, 0x87, 0x4f, 0xf4, 0x40, 0x5a,\n\t\t0xc4, 0xf2, 0x08, 0x0a, 0x4f, 0xf0, 0x07, 0x08,\n\t\t0xca, 0xf8, 0x00, 0x80, 0x4f, 0xf0, 0x02, 0x08,\n\t\t0xca, 0xf8, 0x10, 0x80, 0xca, 0xf8, 0x04, 0x80,\n\t\t0x4f, 0xf0, 0x00, 0x0b, 0xa3, 0x44, 0x93, 0x45,\n\t\t0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6a, 0xf8,\n\t\t0x4f, 0xf0, 0x06, 0x09, 0x00, 0xf0, 0x53, 0xf8,\n\t\t0x00, 0xf0, 0x60, 0xf8, 0x00, 0xf0, 0x62, 0xf8,\n\t\t0x4f, 0xf0, 0x05, 0x09, 0x00, 0xf0, 0x4b, 0xf8,\n\t\t0x4f, 0xf0, 0x00, 0x09, 0x00, 0xf0, 0x47, 0xf8,\n\t\t0x00, 0xf0, 0x54, 0xf8, 0x19, 0xf0, 0x02, 0x0f,\n\t\t0x00, 0xf0, 0x5d, 0x80, 0x00, 0xf0, 0x52, 0xf8,\n\t\t0x4f, 0xf0, 0x02, 0x09, 0x00, 0xf0, 0x3b, 0xf8,\n\t\t0x4f, 0xea, 0x12, 0x49, 0x00, 0xf0, 0x37, 0xf8,\n\t\t0x4f, 0xea, 0x12, 0x29, 0x00, 0xf0, 0x33, 0xf8,\n\t\t0x4f, 0xea, 0x02, 0x09, 0x00, 0xf0, 0x2f, 0xf8,\n\t\t0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f,\n\t\t0x00, 0xf0, 0x47, 0x80, 0x47, 0x68, 0x47, 0x45,\n\t\t0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8, 0x01, 0x9b,\n\t\t0x00, 0xf0, 0x21, 0xf8, 0x8f, 0x42, 0x28, 0xbf,\n\t\t0x00, 0xf1, 0x08, 0x07, 0x47, 0x60, 0x01, 0x3b,\n\t\t0xbb, 0xb3, 0x02, 0xf1, 0x01, 0x02, 0x93, 0x45,\n\t\t0x7f, 0xf4, 0xe6, 0xaf, 0x00, 0xf0, 0x22, 0xf8,\n\t\t0xa3, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x4f, 0xf0,\n\t\t0x05, 0x09, 0x00, 0xf0, 0x0c, 0xf8, 0x4f, 0xf0,\n\t\t0x00, 0x09, 0x00, 0xf0, 0x08, 0xf8, 0x00, 0xf0,\n\t\t0x15, 0xf8, 0x19, 0xf0, 0x01, 0x0f, 0x7f, 0xf4,\n\t\t0xf0, 0xaf, 0xff, 0xf7, 0xa7, 0xbf, 0x4f, 0xf4,\n\t\t0x40, 0x5a, 0xc4, 0xf2, 0x08, 0x0a, 0xca, 0xf8,\n\t\t0x08, 0x90, 0xda, 0xf8, 0x0c, 0x90, 0x19, 0xf0,\n\t\t0x10, 0x0f, 0x7f, 0xf4, 0xfa, 0xaf, 0xda, 0xf8,\n\t\t0x08, 0x90, 0x70, 0x47, 0x4f, 0xf0, 0xff, 0x08,\n\t\t0x00, 0xf0, 0x02, 0xb8, 0x4f, 0xf0, 0x00, 0x08,\n\t\t0x4f, 0xf4, 0x80, 0x4a, 0xc4, 0xf2, 0x0f, 0x0a,\n\t\t0xca, 0xf8, 0xab, 0x80, 0x70, 0x47, 0x00, 0x20,\n\t\t0x50, 0x60, 0xff, 0xf7, 0xef, 0xff, 0x30, 0x46,\n\t\t0x00, 0xbe, 0xff, 0xff\n\t};\n\n\tif (target_alloc_working_area(target, sizeof(lpcspifi_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_ERROR(\"Insufficient working area. You must configure\"\n\t\t\t\" a working area > %zdB in order to write to SPIFI flash.\",\n\t\t\tsizeof(lpcspifi_flash_write_code));\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(lpcspifi_flash_write_code),\n\t\t\tlpcspifi_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* FIFO allocation */\n\tfifo_size = target_get_working_area_avail(target);\n\n\tif (fifo_size == 0) {\n\t\t/* if we already allocated the writing code but failed to get fifo\n\t\t * space, free the algorithm */\n\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\tLOG_ERROR(\"Insufficient working area. Please allocate at least\"\n\t\t\t\" %zdB of working area to enable flash writes.\",\n\t\t\tsizeof(lpcspifi_flash_write_code) + 1\n\t\t);\n\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t} else if (fifo_size < page_size)\n\t\tLOG_WARNING(\"Working area size is limited; flash writes may be\"\n\t\t\t\" slow. Increase working area size to at least %zdB\"\n\t\t\t\" to reduce write times.\",\n\t\t\t(size_t)(sizeof(lpcspifi_flash_write_code) + page_size)\n\t\t);\n\telse if (fifo_size > 0x2000) /* Beyond this point, we start to get diminishing returns */\n\t\tfifo_size = 0x2000;\n\n\tif (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t\t/* buffer start, status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t\t/* buffer end */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t\t/* target address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t\t/* count (halfword-16bit) */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\t\t/* page size */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, fifo->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, offset);\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\tbuf_set_u32(reg_params[4].value, 0, 32, page_size);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, 1,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\tfifo->address, fifo->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info\n\t);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error executing flash write algorithm\");\n\n\ttarget_free_working_area(target, fifo);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\t/* Switch to HW mode before return to prompt */\n\tretval = lpcspifi_set_hw_mode(bank);\n\treturn retval;\n}\n\n/* Return ID of flash device */\n/* On exit, SW mode is kept */\nstatic int lpcspifi_read_flash_id(struct flash_bank *bank, uint32_t *id)\n{\n\tstruct target *target = bank->target;\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tuint32_t ssp_base = lpcspifi_info->ssp_base;\n\tuint32_t io_base = lpcspifi_info->io_base;\n\tuint32_t value;\n\tuint8_t id_buf[3] = {0, 0, 0};\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"Getting ID\");\n\tretval = lpcspifi_set_sw_mode(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* poll WIP */\n\tif (retval == ERROR_OK)\n\t\tretval = wait_till_ready(bank, SSP_PROBE_TIMEOUT);\n\n\t/* Send SPI command \"read ID\" */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_setcs(target, io_base, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, SPIFLASH_READ_ID);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\n\t/* Dummy write to clock in data */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\tid_buf[0] = value;\n\n\t/* Dummy write to clock in data */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\tid_buf[1] = value;\n\n\t/* Dummy write to clock in data */\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_write_reg(target, ssp_base, SSP_DATA, 0x00);\n\tif (retval == ERROR_OK)\n\t\tretval = poll_ssp_busy(target, ssp_base, SSP_CMD_TIMEOUT);\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_read_reg(target, ssp_base, SSP_DATA, &value);\n\tif (retval == ERROR_OK)\n\t\tid_buf[2] = value;\n\n\tif (retval == ERROR_OK)\n\t\tretval = ssp_setcs(target, io_base, 1);\n\tif (retval == ERROR_OK)\n\t\t*id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];\n\n\treturn retval;\n}\n\nstatic int lpcspifi_probe(struct flash_bank *bank)\n{\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tstruct flash_sector *sectors;\n\tuint32_t id = 0; /* silence uninitialized warning */\n\tint retval;\n\tuint32_t sectorsize;\n\n\t/* If we've already probed, we should be fine to skip this time. */\n\tif (lpcspifi_info->probed)\n\t\treturn ERROR_OK;\n\tlpcspifi_info->probed = false;\n\n\tlpcspifi_info->ssp_base = 0x40083000;\n\tlpcspifi_info->io_base = 0x400F4000;\n\tlpcspifi_info->ioconfig_base = 0x40086000;\n\tlpcspifi_info->bank_num = bank->bank_number;\n\n\t/* read and decode flash ID; returns in SW mode */\n\tretval = lpcspifi_read_flash_id(bank, &id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lpcspifi_set_hw_mode(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tlpcspifi_info->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name ; p++)\n\t\tif (p->device_id == id) {\n\t\t\tlpcspifi_info->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!lpcspifi_info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%08\" PRIx32 \")\",\n\t\tlpcspifi_info->dev->name, lpcspifi_info->dev->device_id);\n\n\t/* Set correct size value */\n\tbank->size = lpcspifi_info->dev->size_in_bytes;\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\tif (bank->size > (1UL << 24))\n\t\tLOG_WARNING(\"device needs paging or 4-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = lpcspifi_info->dev->sectorsize ?\n\t\tlpcspifi_info->dev->sectorsize : lpcspifi_info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = lpcspifi_info->dev->size_in_bytes / sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\n\tlpcspifi_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int lpcspifi_auto_probe(struct flash_bank *bank)\n{\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\tif (lpcspifi_info->probed)\n\t\treturn ERROR_OK;\n\treturn lpcspifi_probe(bank);\n}\n\nstatic int lpcspifi_protect_check(struct flash_bank *bank)\n{\n\t/* Nothing to do. Protection is only handled in SW. */\n\treturn ERROR_OK;\n}\n\nstatic int get_lpcspifi_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct lpcspifi_flash_bank *lpcspifi_info = bank->driver_priv;\n\n\tif (!(lpcspifi_info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nSPIFI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nSPIFI flash information:\\n\"\n\t\t\"  Device \\'%s\\' (ID 0x%08\" PRIx32 \")\\n\",\n\t\tlpcspifi_info->dev->name, lpcspifi_info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver lpcspifi_flash = {\n\t.name = \"lpcspifi\",\n\t.flash_bank_command = lpcspifi_flash_bank_command,\n\t.erase = lpcspifi_erase,\n\t.protect = lpcspifi_protect,\n\t.write = lpcspifi_write,\n\t.read = default_flash_read,\n\t.probe = lpcspifi_probe,\n\t.auto_probe = lpcspifi_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = lpcspifi_protect_check,\n\t.info = get_lpcspifi_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/max32xxx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Maxim Integrated                                *\n *   Kevin Gillespie <kevin.gillespie@maximintegrated.com>                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n/* Register Addresses */\n#define FLSH_ADDR                  0x000\n#define FLSH_CLKDIV                0x004\n#define FLSH_CN                    0x008\n#define PR1E_ADDR                  0x00C\n#define PR2S_ADDR                  0x010\n#define PR2E_ADDR                  0x014\n#define PR3S_ADDR                  0x018\n#define PR3E_ADDR                  0x01C\n#define FLSH_MD                    0x020\n#define FLSH_INT                   0x024\n#define FLSH_DATA0                 0x030\n#define FLSH_DATA1                 0x034\n#define FLSH_DATA2                 0x038\n#define FLSH_DATA3                 0x03C\n#define FLSH_BL_CTRL               0x170\n#define FLSH_PROT                  0x300\n\n#define ARM_PID_REG                0xE00FFFE0\n#define MAX326XX_ID_REG            0x40000838\n\n/* Register settings */\n#define FLSH_INT_AF                0x00000002\n\n#define FLSH_CN_UNLOCK_MASK        0xF0000000\n#define FLSH_CN_UNLOCK_VALUE       0x20000000\n\n#define FLSH_CN_PEND               0x01000000\n\n#define FLSH_CN_ERASE_CODE_MASK    0x0000FF00\n#define FLSH_CN_ERASE_CODE_PGE     0x00005500\n#define FLSH_CN_ERASE_CODE_ME      0x0000AA00\n\n#define FLSH_CN_PGE                0x00000004\n#define FLSH_CN_ME                 0x00000002\n#define FLSH_CN_WR                 0x00000001\n#define FLASH_BL_CTRL_23           0x00020000\n#define FLASH_BL_CTRL_IFREN        0x00000001\n\n#define ARM_PID_DEFAULT_CM3        0xB4C3\n#define ARM_PID_DEFAULT_CM4        0xB4C4\n#define MAX326XX_ID                0x4D\n\nstatic int max32xxx_mass_erase(struct flash_bank *bank);\n\nstruct max32xxx_flash_bank {\n\tbool probed;\n\tint max326xx;\n\tunsigned int flash_size;\n\tunsigned int flc_base;\n\tunsigned int sector_size;\n\tunsigned int clkdiv_value;\n\tuint32_t int_state;\n\tunsigned int burst_size_bits;\n};\n\n/* see contrib/loaders/flash/max32xxx/max32xxx.s for src */\nstatic const uint8_t write_code[] = {\n#include \"../../../contrib/loaders/flash/max32xxx/max32xxx.inc\"\n};\n\n/*\t\tConfig Command: flash bank name driver base size chip_width bus_width target [driver_option]\n\tflash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]\n */\nFLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)\n{\n\tstruct max32xxx_flash_bank *info;\n\n\tif (CMD_ARGC < 9) {\n\t\tLOG_WARNING(\"incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tinfo = calloc(sizeof(struct max32xxx_flash_bank), 1);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], info->flash_size);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], info->flc_base);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], info->sector_size);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], info->clkdiv_value);\n\n\tif (CMD_ARGC > 9)\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], info->burst_size_bits);\n\telse\n\t\tinfo->burst_size_bits = 32;\n\n\tinfo->int_state = 0;\n\tbank->driver_priv = info;\n\treturn ERROR_OK;\n}\n\nstatic int get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tcommand_print_sameline(cmd, \"\\nMaxim Integrated max32xxx flash driver\\n\");\n\treturn ERROR_OK;\n}\n\n/***************************************************************************\n*\tflash operations\n***************************************************************************/\n\nstatic int max32xxx_flash_op_pre(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tuint32_t flsh_cn;\n\tuint32_t bootloader;\n\n\t/* Check if the flash controller is busy */\n\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\tif (flsh_cn & (FLSH_CN_PEND | FLSH_CN_ERASE_CODE_MASK | FLSH_CN_PGE |\n\t\tFLSH_CN_ME | FLSH_CN_WR))\n\t\treturn ERROR_FLASH_BUSY;\n\n\t/* Refresh flash controller timing */\n\ttarget_write_u32(target, info->flc_base + FLSH_CLKDIV, info->clkdiv_value);\n\n\t/* Clear and disable flash programming interrupts */\n\ttarget_read_u32(target, info->flc_base + FLSH_INT, &info->int_state);\n\ttarget_write_u32(target, info->flc_base + FLSH_INT, 0x00000000);\n\n\t/* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */\n\tif (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {\n\t\tLOG_ERROR(\"Read failure on FLSH_BL_CTRL\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (bootloader & FLASH_BL_CTRL_23) {\n\t\tLOG_WARNING(\"FLSH_BL_CTRL indicates BL mode 2 or mode 3.\");\n\t\tif (bootloader & FLASH_BL_CTRL_IFREN) {\n\t\t\tLOG_WARNING(\"Flash page 0 swapped out, attempting to swap back in for programming\");\n\t\t\tbootloader &= ~(FLASH_BL_CTRL_IFREN);\n\t\t\tif (target_write_u32(target, info->flc_base + FLSH_BL_CTRL, bootloader) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Write failure on FLSH_BL_CTRL\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Read failure on FLSH_BL_CTRL\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (bootloader & FLASH_BL_CTRL_IFREN) {\n\t\t\t\t/* Bummer */\n\t\t\t\tLOG_ERROR(\"Unable to swap flash page 0 back in. Writes to page 0 will fail.\");\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Unlock flash */\n\tflsh_cn &= ~FLSH_CN_UNLOCK_MASK;\n\tflsh_cn |= FLSH_CN_UNLOCK_VALUE;\n\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t/* Confirm flash is unlocked */\n\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\tif ((flsh_cn & FLSH_CN_UNLOCK_VALUE) != FLSH_CN_UNLOCK_VALUE)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_flash_op_post(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tuint32_t flsh_cn;\n\n\t/* Restore flash programming interrupts */\n\ttarget_write_u32(target, info->flc_base + FLSH_INT, info->int_state);\n\n\t/* Lock flash */\n\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\tflsh_cn &= ~FLSH_CN_UNLOCK_MASK;\n\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_protect_check(struct flash_bank *bank)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t temp_reg;\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (!info->max326xx) {\n\t\tfor (unsigned i = 0; i < bank->num_sectors; i++)\n\t\t\tbank->sectors[i].is_protected = -1;\n\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\t/* Check the protection */\n\tfor (unsigned i = 0; i < bank->num_sectors; i++) {\n\t\tif (i%32 == 0)\n\t\t\ttarget_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);\n\n\t\tif (temp_reg & (0x1 << i%32))\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint32_t flsh_cn, flsh_int;\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\tint retry;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1)))\n\t\treturn max32xxx_mass_erase(bank);\n\n\t/* Prepare to issue flash operation */\n\tretval = max32xxx_flash_op_pre(bank);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint erased = 0;\n\tfor (unsigned int banknr = first; banknr <= last; banknr++) {\n\n\t\t/* Check the protection */\n\t\tif (bank->sectors[banknr].is_protected == 1) {\n\t\t\tLOG_WARNING(\"Flash sector %u is protected\", banknr);\n\t\t\tcontinue;\n\t\t} else\n\t\t\terased = 1;\n\n\t\t/* Address is first word in page */\n\t\ttarget_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);\n\n\t\t/* Write page erase code */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\tflsh_cn |= FLSH_CN_ERASE_CODE_PGE;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\t/* Issue page erase command */\n\t\tflsh_cn |= 0x4;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\t/* Wait until erase complete */\n\t\tretry = 1000;\n\t\tdo {\n\t\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\t\tif (retry <= 0) {\n\t\t\tLOG_ERROR(\"Timed out waiting for flash page erase @ 0x%08x\",\n\t\t\t\tbanknr * info->sector_size);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\t/* Check access violations */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);\n\t\tif (flsh_int & FLSH_INT_AF) {\n\t\t\tLOG_ERROR(\"Error erasing flash page %i\", banknr);\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_INT, 0);\n\t\t\tmax32xxx_flash_op_post(bank);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tif (!erased) {\n\t\tLOG_ERROR(\"All pages protected %u to %u\", first, last);\n\t\tmax32xxx_flash_op_post(bank);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (max32xxx_flash_op_post(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t temp_reg;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (!info->max326xx)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tif ((last < first) || (last >= bank->num_sectors))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\t/* Setup the protection on the pages given */\n\tfor (unsigned int page = first; page <= last; page++) {\n\t\tif (set) {\n\t\t\t/* Set the write/erase bit for this page */\n\t\t\ttarget_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);\n\t\t\ttemp_reg |= (0x1 << page%32);\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);\n\t\t\tbank->sectors[page].is_protected = 1;\n\t\t} else {\n\t\t\t/* Clear the write/erase bit for this page */\n\t\t\ttarget_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);\n\t\t\ttemp_reg &= ~(0x1 << page%32);\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);\n\t\t\tbank->sectors[page].is_protected = 0;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t wcount)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *source;\n\tstruct working_area *write_algorithm;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\t/* power of two, and multiple of word size */\n\tstatic const unsigned buf_min = 128;\n\n\t/* for small buffers it's faster not to download an algorithm */\n\tif (wcount * 4 < buf_min)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tLOG_DEBUG(\"(bank=%p buffer=%p offset=%08\" PRIx32 \" wcount=%08\" PRIx32 \"\",\n\t\tbank, buffer, offset, wcount);\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(write_code), &write_algorithm) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no working area for block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* plus a buffer big enough for this data */\n\tif (wcount * 4 < buffer_size)\n\t\tbuffer_size = wcount * 4;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\n\t\tif (buffer_size <= buf_min) {\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tLOG_DEBUG(\"retry target_alloc_working_area(%s, size=%u)\",\n\t\t\ttarget_name(target), (unsigned) buffer_size);\n\t}\n\n\ttarget_write_buffer(target, write_algorithm->address, sizeof(write_code),\n\t\twrite_code);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, wcount);\n\tbuf_set_u32(reg_params[4].value, 0, 32, info->flc_base);\n\tretval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,\n\t\t5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED)\n\t\tLOG_ERROR(\"error %d executing max32xxx flash write algorithm\", retval);\n\n\ttarget_free_working_area(target, write_algorithm);\n\ttarget_free_working_area(target, source);\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\treturn retval;\n}\n\nstatic int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t flsh_cn, flsh_int;\n\tuint32_t address = offset;\n\tuint32_t remaining = count;\n\tuint32_t words_remaining;\n\tint retval;\n\tint retry;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"bank=%p buffer=%p offset=%08\" PRIx32 \" count=%08\" PRIx32 \"\",\n\t\tbank, buffer, offset, count);\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (offset & 0x3) {\n\t\tLOG_WARNING(\"offset size must be word aligned\");\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\t/* Prepare to issue flash operation */\n\tretval = max32xxx_flash_op_pre(bank);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (remaining >= 4) {\n\t\t/* write in 32-bit units */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\tflsh_cn &= 0xF7FFFFFF;\n\t\tflsh_cn |= 0x00000010;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\t/* try using a block write */\n\t\twords_remaining = remaining / 4;\n\t\tretval = max32xxx_write_block(bank, buffer, offset, words_remaining);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)\n\t\t\t\tLOG_DEBUG(\"writing flash word-at-a-time\");\n\t\t\telse {\n\t\t\t\tmax32xxx_flash_op_post(bank);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t} else {\n\t\t\t/* all 32-bit words have been written */\n\t\t\tbuffer += words_remaining * 4;\n\t\t\taddress += words_remaining * 4;\n\t\t\tremaining -= words_remaining * 4;\n\t\t}\n\t}\n\n\tif ((remaining >= 4) && ((address & 0x1F) != 0)) {\n\t\t/* write in 32-bit units until we are 128-bit aligned */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\tflsh_cn &= 0xF7FFFFFF;\n\t\tflsh_cn |= 0x00000010;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\twhile ((remaining >= 4) && ((address & 0x1F) != 0)) {\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_ADDR, address);\n\t\t\ttarget_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);\n\t\t\tflsh_cn |= 0x00000001;\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\t\t\t/* Wait until flash operation is complete */\n\t\t\tretry = 10;\n\n\t\t\tdo {\n\t\t\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\t\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\t\t\tif (retry <= 0) {\n\t\t\t\tLOG_ERROR(\"Timed out waiting for flash write @ 0x%08\" PRIx32, address);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tbuffer += 4;\n\t\t\taddress += 4;\n\t\t\tremaining -= 4;\n\t\t}\n\t}\n\n\tif ((info->burst_size_bits == 128) && (remaining >= 16)) {\n\t\t/* write in 128-bit bursts while we can */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\n\t\tflsh_cn &= 0xFFFFFFEF;\n\t\tflsh_cn |= 0x08000000;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\t\ttarget_write_u32(target, info->flc_base + FLSH_ADDR, address);\n\n\t\twhile (remaining >= 16) {\n\t\t\tif ((address & 0xFFF) == 0)\n\t\t\t\tLOG_DEBUG(\"Writing @ 0x%08\" PRIx32, address);\n\n\t\t\ttarget_write_buffer(target, info->flc_base + FLSH_DATA0, 16, buffer);\n\t\t\tflsh_cn |= 0x00000001;\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\t\t\t/* Wait until flash operation is complete */\n\t\t\tretry = 10;\n\n\t\t\tdo {\n\t\t\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\t\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\t\t\tif (retry <= 0) {\n\t\t\t\tLOG_ERROR(\"Timed out waiting for flash write @ 0x%08\" PRIx32, address);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tbuffer += 16;\n\t\t\taddress += 16;\n\t\t\tremaining -= 16;\n\t\t}\n\t}\n\n\tif (remaining >= 4) {\n\n\t\t/* write in 32-bit units while we can */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\tflsh_cn &= 0xF7FFFFFF;\n\t\tflsh_cn |= 0x00000010;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\twhile (remaining >= 4) {\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_ADDR, address);\n\t\t\ttarget_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);\n\t\t\tflsh_cn |= 0x00000001;\n\t\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\t\t\t/* Wait until flash operation is complete */\n\t\t\tretry = 10;\n\n\t\t\tdo {\n\t\t\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\t\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\t\t\tif (retry <= 0) {\n\t\t\t\tLOG_ERROR(\"Timed out waiting for flash write @ 0x%08\" PRIx32, address);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\n\t\t\tbuffer += 4;\n\t\t\taddress += 4;\n\t\t\tremaining -= 4;\n\t\t}\n\t}\n\n\tif (remaining > 0) {\n\t\t/* write remaining bytes in a 32-bit unit */\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\tflsh_cn &= 0xF7FFFFFF;\n\t\tflsh_cn |= 0x00000010;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t\tuint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};\n\t\tint i = 0;\n\n\t\twhile (remaining > 0) {\n\t\t\tlast_word[i++] = *buffer;\n\t\t\tbuffer++;\n\t\t\tremaining--;\n\t\t}\n\n\t\ttarget_write_u32(target, info->flc_base + FLSH_ADDR, address);\n\t\ttarget_write_buffer(target, info->flc_base + FLSH_DATA0, 4, last_word);\n\t\tflsh_cn |= 0x00000001;\n\t\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\t\t/* Wait until flash operation is complete */\n\t\tretry = 10;\n\n\t\tdo {\n\t\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\t\tif (retry <= 0) {\n\t\t\tLOG_ERROR(\"Timed out waiting for flash write @ 0x%08\" PRIx32, address);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\t/* Check access violations */\n\ttarget_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);\n\tif (flsh_int & FLSH_INT_AF) {\n\t\tLOG_ERROR(\"Flash Error writing 0x%\" PRIx32 \" bytes at 0x%08\" PRIx32, count, offset);\n\t\tmax32xxx_flash_op_post(bank);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (max32xxx_flash_op_post(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_probe(struct flash_bank *bank)\n{\n\tstruct max32xxx_flash_bank *info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t arm_id[2];\n\tuint16_t arm_pid;\n\n\tfree(bank->sectors);\n\n\t/* provide this for the benefit of the NOR flash framework */\n\tbank->size = info->flash_size;\n\tbank->num_sectors = info->flash_size / info->sector_size;\n\tbank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * info->sector_size;\n\t\tbank->sectors[i].size = info->sector_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\t/* Probe to determine if this part is in the max326xx family */\n\tinfo->max326xx = 0;\n\ttarget_read_u32(target, ARM_PID_REG, &arm_id[0]);\n\ttarget_read_u32(target, ARM_PID_REG+4, &arm_id[1]);\n\tarm_pid = (arm_id[1] << 8) + arm_id[0];\n\tLOG_DEBUG(\"arm_pid = 0x%x\", arm_pid);\n\n\tif ((arm_pid == ARM_PID_DEFAULT_CM3) || arm_pid == ARM_PID_DEFAULT_CM4) {\n\t\tuint32_t max326xx_id;\n\t\ttarget_read_u32(target, MAX326XX_ID_REG, &max326xx_id);\n\t\tLOG_DEBUG(\"max326xx_id = 0x%\" PRIx32, max326xx_id);\n\t\tmax326xx_id = ((max326xx_id & 0xFF000000) >> 24);\n\t\tif (max326xx_id == MAX326XX_ID)\n\t\t\tinfo->max326xx = 1;\n\t}\n\tLOG_DEBUG(\"info->max326xx = %d\", info->max326xx);\n\n\t/* Initialize the protection bits for each flash page */\n\tif (max32xxx_protect_check(bank) == ERROR_FLASH_OPER_UNSUPPORTED)\n\t\tLOG_WARNING(\"Flash protection not supported on this device\");\n\n\tinfo->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int max32xxx_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = NULL;\n\tstruct max32xxx_flash_bank *info = NULL;\n\tuint32_t flsh_cn, flsh_int;\n\tint retval;\n\tint retry;\n\tinfo = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!info->probed)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tint not_protected = 0;\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (bank->sectors[i].is_protected == 1)\n\t\t\tLOG_WARNING(\"Flash sector %u is protected\", i);\n\t\telse\n\t\t\tnot_protected = 1;\n\t}\n\n\tif (!not_protected) {\n\t\tLOG_ERROR(\"All pages protected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Prepare to issue flash operation */\n\tretval = max32xxx_flash_op_pre(bank);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write mass erase code */\n\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\tflsh_cn |= FLSH_CN_ERASE_CODE_ME;\n\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t/* Issue mass erase command */\n\tflsh_cn |= 0x2;\n\ttarget_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);\n\n\t/* Wait until erase complete */\n\tretry = 1000;\n\tdo {\n\t\ttarget_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);\n\t} while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));\n\n\tif (retry <= 0) {\n\t\tLOG_ERROR(\"Timed out waiting for flash mass erase\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Check access violations */\n\ttarget_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);\n\tif (flsh_int & FLSH_INT_AF) {\n\t\tLOG_ERROR(\"Error mass erasing\");\n\t\ttarget_write_u32(target, info->flc_base + FLSH_INT, 0);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (max32xxx_flash_op_post(bank) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(max32xxx_handle_mass_erase_command)\n{\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"max32xxx mass_erase <bank>\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (max32xxx_mass_erase(bank) == ERROR_OK)\n\t\tcommand_print(CMD, \"max32xxx mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"max32xxx mass erase failed\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(max32xxx_handle_protection_set_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\tstruct max32xxx_flash_bank *info;\n\tuint32_t addr, len;\n\n\tif (CMD_ARGC != 3) {\n\t\tcommand_print(CMD, \"max32xxx protection_set <bank> <addr> <size>\");\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tinfo = bank->driver_priv;\n\n\t/* Convert the range to the page numbers */\n\tif (sscanf(CMD_ARGV[1], \"0x%\"SCNx32, &addr) != 1) {\n\t\tLOG_WARNING(\"Error parsing address\");\n\t\tcommand_print(CMD, \"max32xxx protection_set <bank> <addr> <size>\");\n\t\treturn ERROR_FAIL;\n\t}\n\t/* Mask off the top portion on the address */\n\taddr = (addr & 0x0FFFFFFF);\n\n\tif (sscanf(CMD_ARGV[2], \"0x%\"SCNx32, &len) != 1) {\n\t\tLOG_WARNING(\"Error parsing length\");\n\t\tcommand_print(CMD, \"max32xxx protection_set <bank> <addr> <size>\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check the address is in the range of the flash */\n\tif ((addr+len) >= info->flash_size)\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tif (len == 0)\n\t\treturn ERROR_OK;\n\n\t/* Convert the address and length to the page boundaries */\n\taddr = addr - (addr % info->sector_size);\n\tif (len % info->sector_size)\n\t\tlen = len + info->sector_size - (len % info->sector_size);\n\n\t/* Convert the address and length to page numbers */\n\taddr = (addr / info->sector_size);\n\tlen = addr + (len / info->sector_size) - 1;\n\n\tif (max32xxx_protect(bank, 1, addr, len) == ERROR_OK)\n\t\tcommand_print(CMD, \"max32xxx protection set complete\");\n\telse\n\t\tcommand_print(CMD, \"max32xxx protection set failed\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(max32xxx_handle_protection_clr_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\tstruct max32xxx_flash_bank *info;\n\tuint32_t addr, len;\n\n\tif (CMD_ARGC != 3) {\n\t\tcommand_print(CMD, \"max32xxx protection_clr <bank> <addr> <size>\");\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tinfo = bank->driver_priv;\n\n\t/* Convert the range to the page numbers */\n\tif (sscanf(CMD_ARGV[1], \"0x%\"SCNx32, &addr) != 1) {\n\t\tLOG_WARNING(\"Error parsing address\");\n\t\tcommand_print(CMD, \"max32xxx protection_clr <bank> <addr> <size>\");\n\t\treturn ERROR_FAIL;\n\t}\n\t/* Mask off the top portion on the address */\n\taddr = (addr & 0x0FFFFFFF);\n\n\tif (sscanf(CMD_ARGV[2], \"0x%\"SCNx32, &len) != 1) {\n\t\tLOG_WARNING(\"Error parsing length\");\n\t\tcommand_print(CMD, \"max32xxx protection_clr <bank> <addr> <size>\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check the address is in the range of the flash */\n\tif ((addr+len) >= info->flash_size)\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tif (len == 0)\n\t\treturn ERROR_OK;\n\n\t/* Convert the address and length to the page boundaries */\n\taddr = addr - (addr % info->sector_size);\n\tif (len % info->sector_size)\n\t\tlen = len + info->sector_size - (len % info->sector_size);\n\n\t/* Convert the address and length to page numbers */\n\taddr = (addr / info->sector_size);\n\tlen = addr + (len / info->sector_size) - 1;\n\n\tif (max32xxx_protect(bank, 0, addr, len) == ERROR_OK)\n\t\tcommand_print(CMD, \"max32xxx protection clear complete\");\n\telse\n\t\tcommand_print(CMD, \"max32xxx protection clear failed\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(max32xxx_handle_protection_check_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\tstruct max32xxx_flash_bank *info;\n\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"max32xxx protection_check <bank>\");\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tinfo = bank->driver_priv;\n\n\t/* Update the protection array */\n\tretval = max32xxx_protect_check(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"Error updating the protection array\");\n\t\treturn retval;\n\t}\n\n\tLOG_WARNING(\"s:<sector number> a:<address> p:<protection bit>\");\n\tfor (unsigned i = 0; i < bank->num_sectors; i += 4) {\n\t\tLOG_WARNING(\"s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d\",\n\t\t(i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,\n\t\t(i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,\n\t\t(i+2), (i+2)*info->sector_size, bank->sectors[(i+2)].is_protected,\n\t\t(i+3), (i+3)*info->sector_size, bank->sectors[(i+3)].is_protected);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration max32xxx_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = max32xxx_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"mass erase flash\",\n\t},\n\t{\n\t\t.name = \"protection_set\",\n\t\t.handler = max32xxx_handle_protection_set_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id addr size\",\n\t\t.help = \"set flash protection for address range\",\n\t},\n\t{\n\t\t.name = \"protection_clr\",\n\t\t.handler = max32xxx_handle_protection_clr_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id addr size\",\n\t\t.help = \"clear flash protection for address range\",\n\t},\n\t{\n\t\t.name = \"protection_check\",\n\t\t.handler = max32xxx_handle_protection_check_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"check flash protection\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration max32xxx_command_handlers[] = {\n\t{\n\t\t.name = \"max32xxx\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"max32xxx flash command group\",\n\t\t.chain = max32xxx_exec_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver max32xxx_flash = {\n\t.name = \"max32xxx\",\n\t.commands = max32xxx_command_handlers,\n\t.flash_bank_command = max32xxx_flash_bank_command,\n\t.erase = max32xxx_erase,\n\t.protect = max32xxx_protect,\n\t.write = max32xxx_write,\n\t.read = default_flash_read,\n\t.probe = max32xxx_probe,\n\t.auto_probe = max32xxx_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = max32xxx_protect_check,\n\t.info = get_info,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/mdr.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *                                                                         *\n *   Copyright (C) 2013 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define MD_RST_CLK\t\t0x40020000\n#define MD_PER_CLOCK\t\t(MD_RST_CLK + 0x1C)\n#define MD_PER_CLOCK_EEPROM\t(1 << 3)\n#define MD_PER_CLOCK_RST_CLK\t(1 << 4)\n\n#define FLASH_REG_BASE\t0x40018000\n#define FLASH_CMD\t(FLASH_REG_BASE + 0x00)\n#define FLASH_ADR\t(FLASH_REG_BASE + 0x04)\n#define FLASH_DI\t(FLASH_REG_BASE + 0x08)\n#define FLASH_DO\t(FLASH_REG_BASE + 0x0C)\n#define FLASH_KEY\t(FLASH_REG_BASE + 0x10)\n\n#define FLASH_NVSTR\t(1 << 13)\n#define FLASH_PROG\t(1 << 12)\n#define FLASH_MAS1\t(1 << 11)\n#define FLASH_ERASE\t(1 << 10)\n#define FLASH_IFREN\t(1 << 9)\n#define FLASH_SE\t(1 << 8)\n#define FLASH_YE\t(1 << 7)\n#define FLASH_XE\t(1 << 6)\n#define FLASH_RD\t(1 << 2)\n#define FLASH_WR\t(1 << 1)\n#define FLASH_CON\t(1 << 0)\n#define FLASH_DELAY_MASK\t(7 << 3)\n\n#define KEY\t\t0x8AAA5551\n\nstruct mdr_flash_bank {\n\tbool probed;\n\tunsigned int mem_type;\n\tunsigned int page_count;\n\tunsigned int sec_count;\n};\n\n/* flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count> */\nFLASH_BANK_COMMAND_HANDLER(mdr_flash_bank_command)\n{\n\tstruct mdr_flash_bank *mdr_info;\n\n\tif (CMD_ARGC < 9)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tmdr_info = malloc(sizeof(struct mdr_flash_bank));\n\n\tbank->driver_priv = mdr_info;\n\tmdr_info->probed = false;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], mdr_info->mem_type);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], mdr_info->page_count);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], mdr_info->sec_count);\n\treturn ERROR_OK;\n}\n\nstatic int mdr_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tuint32_t flash_cmd;\n\tint retval;\n\tunsigned int i;\n\n\tretval = target_read_u32(target, FLASH_CMD, &flash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < mdr_info->sec_count; i++) {\n\t\tretval = target_write_u32(target, FLASH_ADR, i << 2);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tflash_cmd |= FLASH_XE | FLASH_MAS1 | FLASH_ERASE;\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tflash_cmd |= FLASH_NVSTR;\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tflash_cmd &= ~FLASH_ERASE;\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tflash_cmd &= ~(FLASH_XE | FLASH_MAS1 | FLASH_NVSTR);\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int mdr_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tint retval, retval2;\n\tunsigned int j;\n\tuint32_t flash_cmd, cur_per_clock;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!(cur_per_clock & 0x10)) {\n\t\tLOG_ERROR(\"Target needs reset before flash operations\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tretval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, FLASH_KEY, KEY);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, FLASH_CMD, &flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\t/* Switch on register access */\n\tflash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON;\n\tif (mdr_info->mem_type)\n\t\tflash_cmd |= FLASH_IFREN;\n\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1)) &&\n\t\t!mdr_info->mem_type) {\n\t\tretval = mdr_mass_erase(bank);\n\t\tgoto reset_pg_and_lock;\n\t}\n\n\tunsigned int page_size = bank->size / mdr_info->page_count;\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tfor (j = 0; j < mdr_info->sec_count; j++) {\n\t\t\tretval = target_write_u32(target, FLASH_ADR, (i * page_size) | (j << 2));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\tflash_cmd |= FLASH_XE | FLASH_ERASE;\n\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\t\t\tflash_cmd |= FLASH_NVSTR;\n\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\t\t\tflash_cmd &= ~FLASH_ERASE;\n\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\t\t\tflash_cmd &= ~(FLASH_XE | FLASH_NVSTR);\n\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto reset_pg_and_lock;\n\t\t}\n\t}\n\nreset_pg_and_lock:\n\tflash_cmd &= FLASH_DELAY_MASK;\n\tretval2 = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\n\tretval2 = target_write_u32(target, FLASH_KEY, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\n\treturn retval;\n}\n\nstatic int mdr_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* see contrib/loaders/flash/mdr32fx.S for src */\n\tstatic const uint8_t mdr32fx_flash_write_code[] = {\n\t\t0x07, 0x68, 0x16, 0x68, 0x00, 0x2e, 0x2e, 0xd0, 0x55, 0x68, 0xb5, 0x42,\n\t\t0xf9, 0xd0, 0x2e, 0x68, 0x44, 0x60, 0x86, 0x60, 0x17, 0x4e, 0x37, 0x43,\n\t\t0x07, 0x60, 0x05, 0x26, 0x00, 0xf0, 0x25, 0xf8, 0x15, 0x4e, 0x37, 0x43,\n\t\t0x07, 0x60, 0x0d, 0x26, 0x00, 0xf0, 0x1f, 0xf8, 0x80, 0x26, 0x37, 0x43,\n\t\t0x07, 0x60, 0x3d, 0x26, 0x00, 0xf0, 0x19, 0xf8, 0x80, 0x26, 0xb7, 0x43,\n\t\t0x07, 0x60, 0x0f, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x05, 0x26, 0x00, 0xf0,\n\t\t0x10, 0xf8, 0x0d, 0x4e, 0xb7, 0x43, 0x07, 0x60, 0x04, 0x35, 0x04, 0x34,\n\t\t0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46, 0x08, 0x35, 0x55, 0x60, 0x01, 0x39,\n\t\t0x00, 0x29, 0x00, 0xd0, 0xcd, 0xe7, 0x30, 0x46, 0x00, 0xbe, 0x01, 0x3e,\n\t\t0x00, 0x2e, 0xfc, 0xd1, 0x70, 0x47, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00,\n\t\t0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(mdr32fx_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(mdr32fx_flash_write_code), mdr32fx_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tbuffer_size &= ~3UL; /* Make sure it's 4 byte aligned */\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* flash base (in), status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* count (32bit) */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN_OUT);\t/* target address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, FLASH_REG_BASE);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, 4,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED)\n\t\tLOG_ERROR(\"flash write failed at address 0x%\"PRIx32,\n\t\t\t\tbuf_get_u32(reg_params[4].value, 0, 32));\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\nstatic int mdr_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tuint8_t *new_buffer = NULL;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x3) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 4-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* If there's an odd number of bytes, the data has to be padded. Duplicate\n\t * the buffer and use the normal code path with a single block write since\n\t * it's probably cheaper than to special case the last odd write using\n\t * discrete accesses. */\n\tint rem = count % 4;\n\tif (rem) {\n\t\tnew_buffer = malloc(count + rem);\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"odd number of bytes to write and no memory for padding buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"odd number of bytes to write, padding with 0xff\");\n\t\tbuffer = memcpy(new_buffer, buffer, count);\n\t\twhile (rem--)\n\t\t\tnew_buffer[count++] = 0xff;\n\t}\n\n\tuint32_t flash_cmd, cur_per_clock;\n\tint retval, retval2;\n\n\tretval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);\n\tif (retval != ERROR_OK)\n\t\tgoto free_buffer;\n\n\tif (!(cur_per_clock & MD_PER_CLOCK_RST_CLK)) {\n\t\t/* Something's very wrong if the RST_CLK module is not clocked */\n\t\tLOG_ERROR(\"Target needs reset before flash operations\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto free_buffer;\n\t}\n\n\tretval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);\n\tif (retval != ERROR_OK)\n\t\tgoto free_buffer;\n\n\tretval = target_write_u32(target, FLASH_KEY, KEY);\n\tif (retval != ERROR_OK)\n\t\tgoto free_buffer;\n\n\tretval = target_read_u32(target, FLASH_CMD, &flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\t/* Switch on register access */\n\tflash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON;\n\tif (mdr_info->mem_type)\n\t\tflash_cmd |= FLASH_IFREN;\n\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\t/* try using block write */\n\tretval = mdr_write_block(bank, buffer, offset, count/4);\n\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t/* if block write failed (no sufficient working area),\n\t\t * we use normal (slow) single halfword accesses */\n\t\tLOG_WARNING(\"Can't use block writes, falling back to single memory accesses\");\n\n\t\tunsigned int page_size = bank->size / mdr_info->page_count;\n\t\tunsigned int page_mask = page_size - 1;\n\t\twhile (count > 0) {\n\t\t\tunsigned int i, j;\n\t\t\tunsigned int cur_page = offset & ~page_mask;\n\t\t\tunsigned int bytes_to_write = cur_page + page_size - offset;\n\t\t\tif (count < bytes_to_write)\n\t\t\t\tbytes_to_write = count;\n\n\t\t\t/*LOG_INFO(\"Selecting next page: %08x\", cur_page);*/\n\n\t\t\tfor (i = 0; i < mdr_info->sec_count; i++) {\n\t\t\t\tretval = target_write_u32(target, FLASH_ADR, offset + i*4);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto reset_pg_and_lock;\n\t\t\t\t/*LOG_INFO(\"Selecting page/sector: %08x\", offset + i*4);*/\n\n\t\t\t\tflash_cmd |= FLASH_XE | FLASH_PROG;\n\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\t\tflash_cmd |= FLASH_NVSTR;\n\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\t\tfor (j = 0;\n\t\t\t\t     (((offset + j + i*4) & ~page_mask) == cur_page) &&\n\t\t\t\t\t     (j + i*4 < count);\n\t\t\t\t     j += mdr_info->sec_count*4) {\n\t\t\t\t\tuint32_t value;\n\t\t\t\t\tmemcpy(&value, buffer + j + i*4, sizeof(uint32_t));\n\t\t\t\t\tretval = target_write_u32(target, FLASH_DI, value);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tgoto reset_pg_and_lock;\n\t\t\t\t\t/*LOG_INFO(\"Writing to addr %08x\", offset + j + i*4);*/\n\t\t\t\t\tretval = target_write_u32(target, FLASH_ADR, offset + j + i*4);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\t\t\tflash_cmd |= FLASH_YE;\n\t\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tgoto reset_pg_and_lock;\n\t\t\t\t\tflash_cmd &= ~FLASH_YE;\n\t\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tgoto reset_pg_and_lock;\n\t\t\t\t}\n\t\t\t\tflash_cmd &= ~FLASH_NVSTR;\n\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto reset_pg_and_lock;\n\n\t\t\t\tflash_cmd &= ~(FLASH_XE | FLASH_PROG);\n\t\t\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto reset_pg_and_lock;\n\t\t\t}\n\n\t\t\tbuffer += bytes_to_write;\n\t\t\toffset += bytes_to_write;\n\t\t\tcount -= bytes_to_write;\n\t\t}\n\t}\n\nreset_pg_and_lock:\n\tflash_cmd &= FLASH_DELAY_MASK;\n\tretval2 = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\n\tretval2 = target_write_u32(target, FLASH_KEY, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\nfree_buffer:\n\tfree(new_buffer);\n\n\t/* read some bytes bytes to flush buffer in flash accelerator.\n\t * See errata for 1986VE1T and 1986VE3. Error 0007 */\n\tif ((retval == ERROR_OK) && (!mdr_info->mem_type)) {\n\t\tuint32_t tmp;\n\t\ttarget_checksum_memory(bank->target, bank->base, 64, &tmp);\n\t}\n\n\treturn retval;\n}\n\nstatic int mdr_read(struct flash_bank *bank, uint8_t *buffer,\n\t\t    uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tint retval, retval2;\n\n\tif (!mdr_info->mem_type)\n\t\treturn default_flash_read(bank, buffer, offset, count);\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x3) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 4-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (count & 0x3) {\n\t\tLOG_ERROR(\"count 0x%\" PRIx32 \" breaks required 4-byte alignment\", count);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tuint32_t flash_cmd, cur_per_clock;\n\n\tretval = target_read_u32(target, MD_PER_CLOCK, &cur_per_clock);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tif (!(cur_per_clock & MD_PER_CLOCK_RST_CLK)) {\n\t\t/* Something's very wrong if the RST_CLK module is not clocked */\n\t\tLOG_ERROR(\"Target needs reset before flash operations\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err;\n\t}\n\n\tretval = target_write_u32(target, MD_PER_CLOCK, cur_per_clock | MD_PER_CLOCK_EEPROM);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tretval = target_write_u32(target, FLASH_KEY, KEY);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tretval = target_read_u32(target, FLASH_CMD, &flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\t/* Switch on register access */\n\tflash_cmd = (flash_cmd & FLASH_DELAY_MASK) | FLASH_CON | FLASH_IFREN;\n\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\tfor (uint32_t i = 0; i < count; i += 4) {\n\t\tretval = target_write_u32(target, FLASH_ADR, offset + i);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd |\n\t\t\t\t\t  FLASH_XE | FLASH_YE | FLASH_SE);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t\tuint32_t buf;\n\t\tretval = target_read_u32(target, FLASH_DO, &buf);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t\tbuf_set_u32(buffer, i * 8, 32, buf);\n\n\t\tretval = target_write_u32(target, FLASH_CMD, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t}\n\nreset_pg_and_lock:\n\tflash_cmd &= FLASH_DELAY_MASK;\n\tretval2 = target_write_u32(target, FLASH_CMD, flash_cmd);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\nerr_lock:\n\tretval2 = target_write_u32(target, FLASH_KEY, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\nerr:\n\treturn retval;\n}\n\nstatic int mdr_probe(struct flash_bank *bank)\n{\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tunsigned int page_count, page_size, i;\n\n\tpage_count = mdr_info->page_count;\n\tpage_size = bank->size / page_count;\n\n\tfree(bank->sectors);\n\n\tbank->num_sectors = page_count;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * page_count);\n\n\tfor (i = 0; i < page_count; i++) {\n\t\tbank->sectors[i].offset = i * page_size;\n\t\tbank->sectors[i].size = page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\tmdr_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int mdr_auto_probe(struct flash_bank *bank)\n{\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tif (mdr_info->probed)\n\t\treturn ERROR_OK;\n\treturn mdr_probe(bank);\n}\n\nstatic int get_mdr_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct mdr_flash_bank *mdr_info = bank->driver_priv;\n\tcommand_print_sameline(cmd, \"MDR32Fx - %s\",\n\t\t\tmdr_info->mem_type ? \"info memory\" : \"main memory\");\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver mdr_flash = {\n\t.name = \"mdr\",\n\t.usage = \"flash bank <name> mdr <base> <size> 0 0 <target#> <type> <page_count> <sec_count>\\n\"\n\t\"<type>: 0 for main memory, 1 for info memory\",\n\t.flash_bank_command = mdr_flash_bank_command,\n\t.erase = mdr_erase,\n\t.write = mdr_write,\n\t.read = mdr_read,\n\t.probe = mdr_probe,\n\t.auto_probe = mdr_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = get_mdr_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/mrvlqspi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2014 by Mahavir Jain <mjain@marvell.com>                *\n ***************************************************************************/\n\n /*\n  * This is QSPI flash controller driver for Marvell's Wireless\n  * Microcontroller platform.\n  *\n  * For more information please refer,\n  * https://origin-www.marvell.com/microcontrollers/wi-fi-microcontroller-platform/\n  */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define QSPI_R_EN (0x0)\n#define QSPI_W_EN (0x1)\n#define QSPI_SS_DISABLE (0x0)\n#define QSPI_SS_ENABLE (0x1)\n#define WRITE_DISABLE (0x0)\n#define WRITE_ENABLE (0x1)\n\n#define QSPI_TIMEOUT (1000)\n#define FIFO_FLUSH_TIMEOUT (1000)\n#define BLOCK_ERASE_TIMEOUT (1000)\n#define CHIP_ERASE_TIMEOUT (10000)\n\n#define SS_EN (1 << 0)\n#define XFER_RDY (1 << 1)\n#define RFIFO_EMPTY (1 << 4)\n#define WFIFO_EMPTY (1 << 6)\n#define WFIFO_FULL (1 << 7)\n#define FIFO_FLUSH (1 << 9)\n#define RW_EN (1 << 13)\n#define XFER_STOP (1 << 14)\n#define XFER_START (1 << 15)\n#define CONF_MASK (0x7)\n#define CONF_OFFSET (10)\n\n#define INS_WRITE_ENABLE 0x06\n#define INS_WRITE_DISABLE 0x04\n#define INS_READ_STATUS 0x05\n#define INS_PAGE_PROGRAM 0x02\n\n#define CNTL 0x0 /* QSPI_BASE + 0x0 */\n#define CONF 0x4\n#define DOUT 0x8\n#define DIN 0xc\n#define INSTR 0x10\n#define ADDR 0x14\n#define RDMODE 0x18\n#define HDRCNT 0x1c\n#define DINCNT 0x20\n\nstruct mrvlqspi_flash_bank {\n\tbool probed;\n\tuint32_t reg_base;\n\tuint32_t bank_num;\n\tconst struct flash_device *dev;\n};\n\nstatic inline uint32_t mrvlqspi_get_reg(struct flash_bank *bank, uint32_t reg)\n{\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\treturn reg + mrvlqspi_info->reg_base;\n}\n\nstatic inline int mrvlqspi_set_din_cnt(struct flash_bank *bank, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\n\treturn target_write_u32(target, mrvlqspi_get_reg(bank, DINCNT), count);\n}\n\nstatic inline int mrvlqspi_set_addr(struct flash_bank *bank, uint32_t addr)\n{\n\tstruct target *target = bank->target;\n\n\treturn target_write_u32(target, mrvlqspi_get_reg(bank, ADDR), addr);\n}\n\nstatic inline int mrvlqspi_set_instr(struct flash_bank *bank, uint32_t instr)\n{\n\tstruct target *target = bank->target;\n\n\treturn target_write_u32(target, mrvlqspi_get_reg(bank, INSTR), instr);\n}\n\nstatic inline int mrvlqspi_set_hdr_cnt(struct flash_bank *bank, uint32_t hdr_cnt)\n{\n\tstruct target *target = bank->target;\n\n\treturn target_write_u32(target, mrvlqspi_get_reg(bank, HDRCNT), hdr_cnt);\n}\n\nstatic int mrvlqspi_set_conf(struct flash_bank *bank, uint32_t conf_val)\n{\n\tint retval;\n\tuint32_t regval;\n\tstruct target *target = bank->target;\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), &regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tregval &= ~(CONF_MASK << CONF_OFFSET);\n\tregval |= (conf_val << CONF_OFFSET);\n\n\treturn target_write_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), regval);\n}\n\nstatic int mrvlqspi_set_ss_state(struct flash_bank *bank, bool state, int timeout)\n{\n\tint retval;\n\tuint32_t regval;\n\tstruct target *target = bank->target;\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CNTL), &regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (state)\n\t\tregval |= SS_EN;\n\telse\n\t\tregval &= ~(SS_EN);\n\n\tretval = target_write_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CNTL), regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for xfer_ready to set */\n\tfor (;;) {\n\t\tretval = target_read_u32(target,\n\t\t\t\tmrvlqspi_get_reg(bank, CNTL), &regval);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%08\" PRIx32, regval);\n\t\tif ((regval & XFER_RDY) == XFER_RDY)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_start_transfer(struct flash_bank *bank, bool rw_mode)\n{\n\tint retval;\n\tuint32_t regval;\n\tstruct target *target = bank->target;\n\n\tretval = mrvlqspi_set_ss_state(bank, QSPI_SS_ENABLE, QSPI_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), &regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (rw_mode)\n\t\tregval |= RW_EN;\n\telse\n\t\tregval &= ~(RW_EN);\n\n\tregval |= XFER_START;\n\n\tretval = target_write_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_stop_transfer(struct flash_bank *bank)\n{\n\tint retval;\n\tuint32_t regval;\n\tstruct target *target = bank->target;\n\tint timeout = QSPI_TIMEOUT;\n\n\t/* wait for xfer_ready and wfifo_empty to set */\n\tfor (;;) {\n\t\tretval = target_read_u32(target,\n\t\t\t\tmrvlqspi_get_reg(bank, CNTL), &regval);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%08\" PRIx32, regval);\n\t\tif ((regval & (XFER_RDY | WFIFO_EMPTY)) ==\n\t\t\t\t\t(XFER_RDY | WFIFO_EMPTY))\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), &regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tregval |= XFER_STOP;\n\n\tretval = target_write_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), regval);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for xfer_start to reset */\n\tfor (;;) {\n\t\tretval = target_read_u32(target,\n\t\t\t\tmrvlqspi_get_reg(bank, CONF), &regval);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%08\" PRIx32, regval);\n\t\tif ((regval & XFER_START) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tretval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_fifo_flush(struct flash_bank *bank, int timeout)\n{\n\tint retval;\n\tuint32_t val;\n\tstruct target *target = bank->target;\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), &val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tval |= FIFO_FLUSH;\n\n\tretval = target_write_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, CONF), val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for fifo_flush to clear */\n\tfor (;;) {\n\t\tretval = target_read_u32(target,\n\t\t\t\tmrvlqspi_get_reg(bank, CONF), &val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%08\" PRIX32, val);\n\t\tif ((val & FIFO_FLUSH) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_read_byte(struct flash_bank *bank, uint8_t *data)\n{\n\tint retval;\n\tuint32_t val;\n\tstruct target *target = bank->target;\n\n\t/* wait for rfifo_empty to reset */\n\tfor (;;) {\n\t\tretval = target_read_u32(target,\n\t\t\t\tmrvlqspi_get_reg(bank, CNTL), &val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%08\" PRIx32, val);\n\t\tif ((val & RFIFO_EMPTY) == 0)\n\t\t\tbreak;\n\t\tusleep(10);\n\t}\n\n\tretval = target_read_u32(target,\n\t\t\tmrvlqspi_get_reg(bank, DIN), &val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = val & 0xFF;\n\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_flash_busy_status(struct flash_bank *bank, int timeout)\n{\n\tuint8_t val;\n\tint retval;\n\n\t/* Flush read/write fifos */\n\tretval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction/addr count value */\n\tretval = mrvlqspi_set_hdr_cnt(bank, 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read flash status register in continuous manner */\n\tretval = mrvlqspi_set_din_cnt(bank, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, INS_READ_STATUS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set data and addr pin length */\n\tretval = mrvlqspi_set_conf(bank, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enable read mode transfer */\n\tretval = mrvlqspi_start_transfer(bank, QSPI_R_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (;;) {\n\t\tretval = mrvlqspi_read_byte(bank, &val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (!(val & 0x1))\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\treturn mrvlqspi_stop_transfer(bank);\n}\n\nstatic int mrvlqspi_set_write_status(struct flash_bank *bank, bool mode)\n{\n\tint retval;\n\tuint32_t instr;\n\n\t/* Flush read/write fifos */\n\tretval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction/addr count value */\n\tretval = mrvlqspi_set_hdr_cnt(bank, 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mode)\n\t\tinstr = INS_WRITE_ENABLE;\n\telse\n\t\tinstr = INS_WRITE_DISABLE;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, instr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_start_transfer(bank, QSPI_W_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_stop_transfer(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int mrvlqspi_read_id(struct flash_bank *bank, uint32_t *id)\n{\n\tuint8_t id_buf[3] = {0, 0, 0};\n\tint retval, i;\n\n\tLOG_DEBUG(\"Getting ID\");\n\n\t/* Flush read/write fifos */\n\tretval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction/addr count value */\n\tretval = mrvlqspi_set_hdr_cnt(bank, 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set count for number of bytes to read */\n\tretval = mrvlqspi_set_din_cnt(bank, 0x3);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, SPIFLASH_READ_ID);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set data and addr pin length */\n\tretval = mrvlqspi_set_conf(bank, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_start_transfer(bank, QSPI_R_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < 3; i++) {\n\t\tretval = mrvlqspi_read_byte(bank, &id_buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"ID is 0x%02\" PRIx8 \" 0x%02\" PRIx8 \" 0x%02\" PRIx8,\n\t\t\t\t\tid_buf[0], id_buf[1], id_buf[2]);\n\tretval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*id = id_buf[2] << 16 | id_buf[1] << 8 | id_buf[0];\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_block_erase(struct flash_bank *bank, uint32_t offset)\n{\n\tint retval;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\n\t/* Set flash write enable */\n\tretval = mrvlqspi_set_write_status(bank, WRITE_ENABLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction/addr count value */\n\tretval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4)));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set read offset address */\n\tretval = mrvlqspi_set_addr(bank, offset);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->erase_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_start_transfer(bank, QSPI_W_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_stop_transfer(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn mrvlqspi_flash_busy_status(bank, BLOCK_ERASE_TIMEOUT);\n}\n\nstatic int mrvlqspi_bulk_erase(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\n\tif (mrvlqspi_info->dev->chip_erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\t/* Set flash write enable */\n\tretval = mrvlqspi_set_write_status(bank, WRITE_ENABLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, mrvlqspi_info->dev->chip_erase_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_start_transfer(bank, QSPI_W_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_stop_transfer(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn mrvlqspi_flash_busy_status(bank, CHIP_ERASE_TIMEOUT);\n}\n\nstatic int mrvlqspi_flash_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"erase from sector %u to sector %u\", first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!(mrvlqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* If we're erasing the entire chip and the flash supports\n\t * it, use a bulk erase instead of going sector-by-sector. */\n\tif (first == 0 && last == (bank->num_sectors - 1)\n\t\t&& mrvlqspi_info->dev->chip_erase_cmd !=\n\t\t\t\t\tmrvlqspi_info->dev->erase_cmd) {\n\t\tLOG_DEBUG(\"Chip supports the bulk erase command.\"\n\t\t\" Will use bulk erase instead of sector-by-sector erase.\");\n\t\tretval = mrvlqspi_bulk_erase(bank);\n\t\tif (retval == ERROR_OK) {\n\t\t\treturn retval;\n\t\t} else\n\t\t\tLOG_WARNING(\"Bulk flash erase failed.\"\n\t\t\t\t\" Falling back to sector-by-sector erase.\");\n\t}\n\n\tif (mrvlqspi_info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = mrvlqspi_block_erase(bank,\n\t\t\t\tsector * mrvlqspi_info->dev->sectorsize);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int mrvlqspi_flash_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\tuint32_t page_size, fifo_size;\n\tstruct working_area *fifo;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *write_algorithm;\n\n\tLOG_DEBUG(\"offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\toffset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > mrvlqspi_info->dev->size_in_bytes) {\n\t\tLOG_WARNING(\"Writes past end of flash. Extra data discarded.\");\n\t\tcount = mrvlqspi_info->dev->size_in_bytes - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tif ((offset <\n\t\t\t(bank->sectors[sector].offset + bank->sectors[sector].size))\n\t\t\t&& ((offset + count - 1) >= bank->sectors[sector].offset)\n\t\t\t&& bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* if no valid page_size, use reasonable default */\n\tpage_size = mrvlqspi_info->dev->pagesize ?\n\t\tmrvlqspi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\t/* See contrib/loaders/flash/mrvlqspi.S for src */\n\tstatic const uint8_t mrvlqspi_flash_write_code[] = {\n\t\t0x4f, 0xf0, 0x00, 0x0a, 0xa2, 0x44, 0x92, 0x45,\n\t\t0x7f, 0xf6, 0xfc, 0xaf, 0x00, 0xf0, 0x6b, 0xf8,\n\t\t0x5f, 0xf0, 0x01, 0x08, 0xc5, 0xf8, 0x1c, 0x80,\n\t\t0x5f, 0xf0, 0x06, 0x08, 0xc5, 0xf8, 0x10, 0x80,\n\t\t0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0, 0x6b, 0xf8,\n\t\t0x00, 0xf0, 0x7d, 0xf8, 0x5f, 0xf0, 0x31, 0x08,\n\t\t0xc5, 0xf8, 0x1c, 0x80, 0x90, 0x46, 0xc5, 0xf8,\n\t\t0x14, 0x80, 0x5f, 0xf0, 0x02, 0x08, 0xc5, 0xf8,\n\t\t0x10, 0x80, 0x5f, 0xf0, 0x01, 0x09, 0x00, 0xf0,\n\t\t0x5a, 0xf8, 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1,\n\t\t0x00, 0x0f, 0x00, 0xf0, 0x8b, 0x80, 0x47, 0x68,\n\t\t0x47, 0x45, 0x3f, 0xf4, 0xf6, 0xaf, 0x17, 0xf8,\n\t\t0x01, 0x9b, 0x00, 0xf0, 0x30, 0xf8, 0x8f, 0x42,\n\t\t0x28, 0xbf, 0x00, 0xf1, 0x08, 0x07, 0x47, 0x60,\n\t\t0x01, 0x3b, 0x00, 0x2b, 0x00, 0xf0, 0x05, 0x80,\n\t\t0x02, 0xf1, 0x01, 0x02, 0x92, 0x45, 0x7f, 0xf4,\n\t\t0xe4, 0xaf, 0x00, 0xf0, 0x50, 0xf8, 0xa2, 0x44,\n\t\t0x00, 0xf0, 0x2d, 0xf8, 0x5f, 0xf0, 0x01, 0x08,\n\t\t0xc5, 0xf8, 0x1c, 0x80, 0x5f, 0xf0, 0x00, 0x08,\n\t\t0xc5, 0xf8, 0x20, 0x80, 0x5f, 0xf0, 0x05, 0x08,\n\t\t0xc5, 0xf8, 0x10, 0x80, 0x5f, 0xf0, 0x00, 0x09,\n\t\t0x00, 0xf0, 0x29, 0xf8, 0x00, 0xf0, 0x13, 0xf8,\n\t\t0x09, 0xf0, 0x01, 0x09, 0xb9, 0xf1, 0x00, 0x0f,\n\t\t0xf8, 0xd1, 0x00, 0xf0, 0x34, 0xf8, 0x00, 0x2b,\n\t\t0xa4, 0xd1, 0x00, 0xf0, 0x53, 0xb8, 0xd5, 0xf8,\n\t\t0x00, 0x80, 0x5f, 0xea, 0x08, 0x68, 0xfa, 0xd4,\n\t\t0xc5, 0xf8, 0x08, 0x90, 0x70, 0x47, 0xd5, 0xf8,\n\t\t0x00, 0x80, 0x5f, 0xea, 0xc8, 0x68, 0xfa, 0xd4,\n\t\t0xd5, 0xf8, 0x0c, 0x90, 0x70, 0x47, 0xd5, 0xf8,\n\t\t0x04, 0x80, 0x48, 0xf4, 0x00, 0x78, 0xc5, 0xf8,\n\t\t0x04, 0x80, 0xd5, 0xf8, 0x04, 0x80, 0x5f, 0xea,\n\t\t0x88, 0x58, 0xfa, 0xd4, 0x70, 0x47, 0xd5, 0xf8,\n\t\t0x00, 0x80, 0x48, 0xf0, 0x01, 0x08, 0xc5, 0xf8,\n\t\t0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea,\n\t\t0x88, 0x78, 0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80,\n\t\t0x69, 0xf3, 0x4d, 0x38, 0x48, 0xf4, 0x00, 0x48,\n\t\t0xc5, 0xf8, 0x04, 0x80, 0x70, 0x47, 0xd5, 0xf8,\n\t\t0x00, 0x80, 0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5,\n\t\t0xd5, 0xf8, 0x00, 0x80, 0x5f, 0xea, 0x48, 0x68,\n\t\t0xfa, 0xd5, 0xd5, 0xf8, 0x04, 0x80, 0x48, 0xf4,\n\t\t0x80, 0x48, 0xc5, 0xf8, 0x04, 0x80, 0xd5, 0xf8,\n\t\t0x04, 0x80, 0x5f, 0xea, 0x08, 0x48, 0xfa, 0xd4,\n\t\t0xd5, 0xf8, 0x00, 0x80, 0x28, 0xf0, 0x01, 0x08,\n\t\t0xc5, 0xf8, 0x00, 0x80, 0xd5, 0xf8, 0x00, 0x80,\n\t\t0x5f, 0xea, 0x88, 0x78, 0xfa, 0xd5, 0x70, 0x47,\n\t\t0x00, 0x20, 0x50, 0x60, 0x30, 0x46, 0x00, 0xbe\n\t};\n\n\tif (target_alloc_working_area(target, sizeof(mrvlqspi_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_ERROR(\"Insufficient working area. You must configure\"\n\t\t\t\" a working area > %zdB in order to write to SPIFI flash.\",\n\t\t\tsizeof(mrvlqspi_flash_write_code));\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(mrvlqspi_flash_write_code),\n\t\t\tmrvlqspi_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* FIFO allocation */\n\tfifo_size = target_get_working_area_avail(target);\n\n\tif (fifo_size == 0) {\n\t\t/* if we already allocated the writing code but failed to get fifo\n\t\t * space, free the algorithm */\n\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\tLOG_ERROR(\"Insufficient working area. Please allocate at least\"\n\t\t\t\" %zdB of working area to enable flash writes.\",\n\t\t\tsizeof(mrvlqspi_flash_write_code) + 1\n\t\t);\n\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t} else if (fifo_size < page_size)\n\t\tLOG_WARNING(\"Working area size is limited; flash writes may be\"\n\t\t\t\" slow. Increase working area size to at least %zdB\"\n\t\t\t\" to reduce write times.\",\n\t\t\t(size_t)(sizeof(mrvlqspi_flash_write_code) + page_size)\n\t\t);\n\n\tif (target_alloc_working_area(target, fifo_size, &fifo) != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* buffer start, status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* target address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* count (halfword-16bit) */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\t/* page size */\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_OUT);\t/* qspi base address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, fifo->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, fifo->address + fifo->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, offset);\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\tbuf_set_u32(reg_params[4].value, 0, 32, page_size);\n\tbuf_set_u32(reg_params[5].value, 0, 32, (uint32_t) mrvlqspi_info->reg_base);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, 1,\n\t\t\t0, NULL,\n\t\t\t6, reg_params,\n\t\t\tfifo->address, fifo->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info\n\t);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error executing flash write algorithm\");\n\n\ttarget_free_working_area(target, fifo);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\n\treturn retval;\n}\n\nstatic int mrvlqspi_flash_read(struct flash_bank *bank, uint8_t *buffer,\n\t\t\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\tint retval;\n\tuint32_t i;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(mrvlqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Flush read/write fifos */\n\tretval = mrvlqspi_fifo_flush(bank, FIFO_FLUSH_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction/addr count value */\n\tretval = mrvlqspi_set_hdr_cnt(bank, (0x1 | (0x3 << 4)));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set count for number of bytes to read */\n\tretval = mrvlqspi_set_din_cnt(bank, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set read address */\n\tretval = mrvlqspi_set_addr(bank, offset);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set instruction */\n\tretval = mrvlqspi_set_instr(bank, SPIFLASH_READ);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set data and addr pin length */\n\tretval = mrvlqspi_set_conf(bank, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mrvlqspi_start_transfer(bank, QSPI_R_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = mrvlqspi_read_byte(bank, &buffer[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = mrvlqspi_set_ss_state(bank, QSPI_SS_DISABLE, QSPI_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\tuint32_t id = 0;\n\tint retval;\n\tstruct flash_sector *sectors;\n\tuint32_t sectorsize;\n\n\t/* If we've already probed, we should be fine to skip this time. */\n\tif (mrvlqspi_info->probed)\n\t\treturn ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tmrvlqspi_info->probed = false;\n\tmrvlqspi_info->bank_num = bank->bank_number;\n\n\t/* Read flash JEDEC ID */\n\tretval = mrvlqspi_read_id(bank, &id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmrvlqspi_info->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name ; p++)\n\t\tif (p->device_id == id) {\n\t\t\tmrvlqspi_info->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!mrvlqspi_info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device ID 0x%08\" PRIx32, id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' ID 0x%08\" PRIx32,\n\t\tmrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id);\n\n\n\t/* Set correct size value */\n\tbank->size = mrvlqspi_info->dev->size_in_bytes;\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\tif (bank->size > (1UL << 24))\n\t\tLOG_WARNING(\"device needs paging or 4-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = mrvlqspi_info->dev->sectorsize ?\n\t\tmrvlqspi_info->dev->sectorsize : mrvlqspi_info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = mrvlqspi_info->dev->size_in_bytes / sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tmrvlqspi_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_auto_probe(struct flash_bank *bank)\n{\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\tif (mrvlqspi_info->probed)\n\t\treturn ERROR_OK;\n\treturn mrvlqspi_probe(bank);\n}\n\nstatic int mrvlqspi_flash_erase_check(struct flash_bank *bank)\n{\n\t/* Not implemented yet */\n\treturn ERROR_OK;\n}\n\nstatic int mrvlqspi_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info = bank->driver_priv;\n\n\tif (!(mrvlqspi_info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nQSPI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nQSPI flash information:\\n\"\n\t\t\"  Device \\'%s\\' ID 0x%08\" PRIx32 \"\\n\",\n\t\tmrvlqspi_info->dev->name, mrvlqspi_info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(mrvlqspi_flash_bank_command)\n{\n\tstruct mrvlqspi_flash_bank *mrvlqspi_info;\n\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tmrvlqspi_info = malloc(sizeof(struct mrvlqspi_flash_bank));\n\tif (!mrvlqspi_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Get QSPI controller register map base address */\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], mrvlqspi_info->reg_base);\n\tbank->driver_priv = mrvlqspi_info;\n\tmrvlqspi_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver mrvlqspi_flash = {\n\t.name = \"mrvlqspi\",\n\t.flash_bank_command = mrvlqspi_flash_bank_command,\n\t.erase = mrvlqspi_flash_erase,\n\t.write = mrvlqspi_flash_write,\n\t.read = mrvlqspi_flash_read,\n\t.probe = mrvlqspi_probe,\n\t.auto_probe = mrvlqspi_auto_probe,\n\t.erase_check = mrvlqspi_flash_erase_check,\n\t.info = mrvlqspi_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/msp432.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"msp432.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/image.h>\n\n/* MSP432P4 hardware registers */\n#define P4_FLASH_MAIN_SIZE_REG 0xE0043020\n#define P4_FLASH_INFO_SIZE_REG 0xE0043024\n#define P4_DEVICE_ID_REG       0x0020100C\n#define P4_HARDWARE_REV_REG    0x00201010\n\n/* MSP432E4 hardware registers */\n#define E4_DID0_REG 0x400FE000\n#define E4_DID1_REG 0x400FE004\n\n#define FLASH_TIMEOUT 8000\n\n#define SUPPORT_MESSAGE \\\n\t\"Your pre-production MSP432P401x silicon is not fully supported\\n\" \\\n\t\"You can find more information at www.ti.com/product/MSP432P401R\"\n\nstruct msp432_bank {\n\tuint32_t device_id;\n\tuint32_t hardware_rev;\n\tint family_type;\n\tint device_type;\n\tuint32_t sector_length;\n\tbool probed_main;\n\tbool probed_info;\n\tbool unlock_bsl;\n\tstruct working_area *working_area;\n\tstruct armv7m_algorithm armv7m_info;\n};\n\n/* Flash helper algorithm for MSP432P401x targets */\nstatic const uint8_t msp432p401x_algo[] = {\n#include \"../../../contrib/loaders/flash/msp432/msp432p401x_algo.inc\"\n};\n\n/* Flash helper algorithm for MSP432P411x targets */\nstatic const uint8_t msp432p411x_algo[] = {\n#include \"../../../contrib/loaders/flash/msp432/msp432p411x_algo.inc\"\n};\n\n/* Flash helper algorithm for MSP432E4x targets */\nstatic const uint8_t msp432e4x_algo[] = {\n#include \"../../../contrib/loaders/flash/msp432/msp432e4x_algo.inc\"\n};\n\nstatic int msp432_auto_probe(struct flash_bank *bank);\n\nstatic int msp432_device_type(uint32_t family_type, uint32_t device_id,\n\tuint32_t hardware_rev)\n{\n\tint device_type = MSP432_NO_TYPE;\n\n\tif (family_type == MSP432E4) {\n\t\t/* MSP432E4 device family */\n\n\t\tif (device_id == 0x180C0002) {\n\t\t\tif (hardware_rev == 0x102DC06E) {\n\t\t\t\t/* The 01Y variant */\n\t\t\t\tdevice_type = MSP432E401Y;\n\t\t\t} else if (hardware_rev == 0x1032E076) {\n\t\t\t\t/* The 11Y variant */\n\t\t\t\tdevice_type = MSP432E411Y;\n\t\t\t} else {\n\t\t\t\t/* Reasonable guess that this is a new variant */\n\t\t\t\tdevice_type = MSP432E4X_GUESS;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Wild guess that this is an MSP432E4 */\n\t\t\tdevice_type = MSP432E4X_GUESS;\n\t\t}\n\t} else {\n\t\t/* MSP432P4 device family */\n\n\t\t/* Examine the device ID and hardware revision to get the device type */\n\t\tswitch (device_id) {\n\t\t\tcase 0xA000:\n\t\t\tcase 0xA001:\n\t\t\tcase 0xA002:\n\t\t\tcase 0xA003:\n\t\t\tcase 0xA004:\n\t\t\tcase 0xA005:\n\t\t\t\t/* Device is definitely MSP432P401x, check hardware revision */\n\t\t\t\tif (hardware_rev == 0x41 || hardware_rev == 0x42) {\n\t\t\t\t\t/* Rev A or B of the silicon has been deprecated */\n\t\t\t\t\tdevice_type = MSP432P401X_DEPR;\n\t\t\t\t} else if (hardware_rev >= 0x43 && hardware_rev <= 0x49) {\n\t\t\t\t\t/* Current and future revisions of the MSP432P401x device */\n\t\t\t\t\tdevice_type = MSP432P401X;\n\t\t\t\t} else {\n\t\t\t\t\t/* Unknown or unanticipated hardware revision */\n\t\t\t\t\tdevice_type = MSP432P401X_GUESS;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0xA010:\n\t\t\tcase 0xA012:\n\t\t\tcase 0xA016:\n\t\t\tcase 0xA019:\n\t\t\tcase 0xA01F:\n\t\t\tcase 0xA020:\n\t\t\tcase 0xA022:\n\t\t\tcase 0xA026:\n\t\t\tcase 0xA029:\n\t\t\tcase 0xA02F:\n\t\t\t\t/* Device is definitely MSP432P411x, check hardware revision */\n\t\t\t\tif (hardware_rev >= 0x41 && hardware_rev <= 0x49) {\n\t\t\t\t\t/* Current and future revisions of the MSP432P411x device */\n\t\t\t\t\tdevice_type = MSP432P411X;\n\t\t\t\t} else {\n\t\t\t\t\t/* Unknown or unanticipated hardware revision */\n\t\t\t\t\tdevice_type = MSP432P411X_GUESS;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0xFFFF:\n\t\t\t\t/* Device is very early silicon that has been deprecated */\n\t\t\t\tdevice_type = MSP432P401X_DEPR;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif (device_id < 0xA010) {\n\t\t\t\t\t/* Wild guess that this is an MSP432P401x */\n\t\t\t\t\tdevice_type = MSP432P401X_GUESS;\n\t\t\t\t} else {\n\t\t\t\t\t/* Reasonable guess that this is a new variant */\n\t\t\t\t\tdevice_type = MSP432P411X_GUESS;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn device_type;\n}\n\nstatic const char *msp432_return_text(uint32_t return_code)\n{\n\tswitch (return_code) {\n\t\tcase FLASH_BUSY:\n\t\t\treturn \"FLASH_BUSY\";\n\t\tcase FLASH_SUCCESS:\n\t\t\treturn \"FLASH_SUCCESS\";\n\t\tcase FLASH_ERROR:\n\t\t\treturn \"FLASH_ERROR\";\n\t\tcase FLASH_TIMEOUT_ERROR:\n\t\t\treturn \"FLASH_TIMEOUT_ERROR\";\n\t\tcase FLASH_VERIFY_ERROR:\n\t\t\treturn \"FLASH_VERIFY_WRONG\";\n\t\tcase FLASH_WRONG_COMMAND:\n\t\t\treturn \"FLASH_WRONG_COMMAND\";\n\t\tcase FLASH_POWER_ERROR:\n\t\t\treturn \"FLASH_POWER_ERROR\";\n\t\tdefault:\n\t\t\treturn \"UNDEFINED_RETURN_CODE\";\n\t}\n}\n\nstatic void msp432_init_params(struct msp432_algo_params *algo_params)\n{\n\tbuf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);\n\tbuf_set_u32(algo_params->return_code, 0, 32, 0);\n\tbuf_set_u32(algo_params->_reserved0, 0, 32, 0);\n\tbuf_set_u32(algo_params->address, 0, 32, 0);\n\tbuf_set_u32(algo_params->length, 0, 32, 0);\n\tbuf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);\n\tbuf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);\n\tbuf_set_u32(algo_params->erase_param, 0, 32, FLASH_ERASE_MAIN);\n\tbuf_set_u32(algo_params->unlock_bsl, 0, 32, FLASH_LOCK_BSL);\n}\n\nstatic int msp432_exec_cmd(struct target *target, struct msp432_algo_params\n\t\t\t*algo_params, uint32_t command)\n{\n\tint retval;\n\n\t/* Make sure the given params do not include the command */\n\tbuf_set_u32(algo_params->flash_command, 0, 32, FLASH_NO_COMMAND);\n\tbuf_set_u32(algo_params->return_code, 0, 32, 0);\n\tbuf_set_u32(algo_params->buffer1_status, 0, 32, BUFFER_INACTIVE);\n\tbuf_set_u32(algo_params->buffer2_status, 0, 32, BUFFER_INACTIVE);\n\n\t/* Write out parameters to target memory */\n\tretval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,\n\t\t\t\tsizeof(struct msp432_algo_params), (uint8_t *)algo_params);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write out command to target memory */\n\tretval = target_write_u32(target, ALGO_FLASH_COMMAND_ADDR, command);\n\n\treturn retval;\n}\n\nstatic int msp432_wait_return_code(struct target *target)\n{\n\tuint32_t return_code = 0;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\n\tint retval = ERROR_OK;\n\n\tstart_ms = timeval_ms();\n\twhile ((return_code == 0) || (return_code == FLASH_BUSY)) {\n\t\tretval = target_read_u32(target, ALGO_RETURN_CODE_ADDR, &return_code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\telapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > 500)\n\t\t\tkeep_alive();\n\t\tif (elapsed_ms > FLASH_TIMEOUT)\n\t\t\tbreak;\n\t};\n\n\tif (return_code != FLASH_SUCCESS) {\n\t\tLOG_ERROR(\"msp432: Flash operation failed: %s\",\n\t\t\tmsp432_return_text(return_code));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int msp432_wait_inactive(struct target *target, uint32_t buffer)\n{\n\tuint32_t status_code = BUFFER_ACTIVE;\n\tuint32_t status_addr;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\n\tint retval;\n\n\tswitch (buffer) {\n\t\tcase 1: /* Buffer 1 */\n\t\t\tstatus_addr = ALGO_BUFFER1_STATUS_ADDR;\n\t\t\tbreak;\n\t\tcase 2: /* Buffer 2 */\n\t\t\tstatus_addr = ALGO_BUFFER2_STATUS_ADDR;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tstart_ms = timeval_ms();\n\twhile (status_code != BUFFER_INACTIVE) {\n\t\tretval = target_read_u32(target, status_addr, &status_code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\telapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > 500)\n\t\t\tkeep_alive();\n\t\tif (elapsed_ms > FLASH_TIMEOUT)\n\t\t\tbreak;\n\t};\n\n\tif (status_code != BUFFER_INACTIVE) {\n\t\tLOG_ERROR(\n\t\t\t\"msp432: Flash operation failed: buffer not written to flash\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int msp432_init(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\tstruct msp432_algo_params algo_params;\n\tstruct reg_param reg_params[1];\n\n\tconst uint8_t *loader_code;\n\tuint32_t loader_size;\n\tuint32_t algo_entry_addr;\n\tint retval;\n\n\t/* Make sure we've probed the flash to get the device and size */\n\tretval = msp432_auto_probe(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Choose appropriate flash helper algorithm */\n\tswitch (msp432_bank->device_type) {\n\t\tcase MSP432P401X:\n\t\tcase MSP432P401X_DEPR:\n\t\tcase MSP432P401X_GUESS:\n\t\tdefault:\n\t\t\tloader_code = msp432p401x_algo;\n\t\t\tloader_size = sizeof(msp432p401x_algo);\n\t\t\talgo_entry_addr = P4_ALGO_ENTRY_ADDR;\n\t\t\tbreak;\n\t\tcase MSP432P411X:\n\t\tcase MSP432P411X_GUESS:\n\t\t\tloader_code = msp432p411x_algo;\n\t\t\tloader_size = sizeof(msp432p411x_algo);\n\t\t\talgo_entry_addr = P4_ALGO_ENTRY_ADDR;\n\t\t\tbreak;\n\t\tcase MSP432E401Y:\n\t\tcase MSP432E411Y:\n\t\tcase MSP432E4X_GUESS:\n\t\t\tloader_code = msp432e4x_algo;\n\t\t\tloader_size = sizeof(msp432e4x_algo);\n\t\t\talgo_entry_addr = E4_ALGO_ENTRY_ADDR;\n\t\t\tbreak;\n\t}\n\n\t/* Issue warnings if this is a device we may not be able to flash */\n\tif (msp432_bank->device_type == MSP432P401X_GUESS ||\n\t\tmsp432_bank->device_type == MSP432P411X_GUESS) {\n\t\t/* Explicit device type check failed. Report this. */\n\t\tLOG_WARNING(\n\t\t\t\"msp432: Unrecognized MSP432P4 Device ID and Hardware \"\n\t\t\t\"Rev (%04\" PRIX32 \", %02\" PRIX32 \")\", msp432_bank->device_id,\n\t\t\tmsp432_bank->hardware_rev);\n\t} else if (msp432_bank->device_type == MSP432P401X_DEPR) {\n\t\tLOG_WARNING(\n\t\t\t\"msp432: MSP432P401x pre-production device (deprecated \"\n\t\t\t\"silicon)\\n\" SUPPORT_MESSAGE);\n\t} else if (msp432_bank->device_type == MSP432E4X_GUESS) {\n\t\t/* Explicit device type check failed. Report this. */\n\t\tLOG_WARNING(\n\t\t\t\"msp432: Unrecognized MSP432E4 DID0 and DID1 values \"\n\t\t\t\"(%08\" PRIX32 \", %08\" PRIX32 \")\", msp432_bank->device_id,\n\t\t\tmsp432_bank->hardware_rev);\n\t}\n\n\t/* Check for working area to use for flash helper algorithm */\n\ttarget_free_working_area(target, msp432_bank->working_area);\n\tmsp432_bank->working_area = NULL;\n\n\tretval = target_alloc_working_area(target, ALGO_WORKING_SIZE,\n\t\t\t\t&msp432_bank->working_area);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Confirm the defined working address is the area we need to use */\n\tif (msp432_bank->working_area->address != ALGO_BASE_ADDR)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* Write flash helper algorithm into target memory */\n\tretval = target_write_buffer(target, ALGO_BASE_ADDR, loader_size,\n\t\t\t\tloader_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize the ARMv7 specific info to run the algorithm */\n\tmsp432_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tmsp432_bank->armv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* Initialize algorithm parameters to default values */\n\tmsp432_init_params(&algo_params);\n\n\t/* Write out parameters to target memory */\n\tretval = target_write_buffer(target, ALGO_PARAMS_BASE_ADDR,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize stack pointer for flash helper algorithm */\n\tinit_reg_param(&reg_params[0], \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, ALGO_STACK_POINTER_ADDR);\n\n\t/* Begin executing the flash helper algorithm */\n\tretval = target_start_algorithm(target, 0, NULL, 1, reg_params,\n\t\t\t\talgo_entry_addr, 0, &msp432_bank->armv7m_info);\n\tdestroy_reg_param(&reg_params[0]);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"msp432: Failed to start flash helper algorithm\");\n\t\treturn retval;\n\t}\n\n\t/*\n\t * At this point, the algorithm is running on the target and\n\t * ready to receive commands and data to flash the target\n\t */\n\n\t/* Issue the init command to the flash helper algorithm */\n\tretval = msp432_exec_cmd(target, &algo_params, FLASH_INIT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = msp432_wait_return_code(target);\n\n\treturn retval;\n}\n\nstatic int msp432_quit(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\tstruct msp432_algo_params algo_params;\n\n\tint retval;\n\n\t/* Initialize algorithm parameters to default values */\n\tmsp432_init_params(&algo_params);\n\n\t/* Issue the exit command to the flash helper algorithm */\n\tretval = msp432_exec_cmd(target, &algo_params, FLASH_EXIT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t(void)msp432_wait_return_code(target);\n\n\t/* Regardless of the return code, attempt to halt the target */\n\t(void)target_halt(target);\n\n\t/* Now confirm target halted and clean up from flash helper algorithm */\n\tretval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0, FLASH_TIMEOUT,\n\t\t\t\t&msp432_bank->armv7m_info);\n\n\ttarget_free_working_area(target, msp432_bank->working_area);\n\tmsp432_bank->working_area = NULL;\n\n\treturn retval;\n}\n\nstatic int msp432_mass_erase(struct flash_bank *bank, bool all)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\tstruct msp432_algo_params algo_params;\n\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = msp432_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters to default values */\n\tmsp432_init_params(&algo_params);\n\tif (all) {\n\t\tbuf_set_u32(algo_params.erase_param, 0, 32,\n\t\t\tFLASH_ERASE_MAIN | FLASH_ERASE_INFO);\n\t\tif (msp432_bank->unlock_bsl)\n\t\t\tbuf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);\n\t}\n\n\t/* Issue the mass erase command to the flash helper algorithm */\n\tretval = msp432_exec_cmd(target, &algo_params, FLASH_MASS_ERASE);\n\tif (retval != ERROR_OK) {\n\t\t(void)msp432_quit(bank);\n\t\treturn retval;\n\t}\n\n\tretval = msp432_wait_return_code(target);\n\tif (retval != ERROR_OK) {\n\t\t(void)msp432_quit(bank);\n\t\treturn retval;\n\t}\n\n\tretval = msp432_quit(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(msp432_mass_erase_command)\n{\n\tstruct flash_bank *bank;\n\tstruct msp432_bank *msp432_bank;\n\tbool all;\n\n\tint retval;\n\n\tif (1 > CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (1 == CMD_ARGC) {\n\t\tall = false;\n\t} else if (2 == CMD_ARGC) {\n\t\t/* Check argument for how much to erase */\n\t\tif (strcmp(CMD_ARGV[1], \"main\") == 0)\n\t\t\tall = false;\n\t\telse if (strcmp(CMD_ARGV[1], \"all\") == 0)\n\t\t\tall = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tmsp432_bank = bank->driver_priv;\n\n\tif (msp432_bank->family_type == MSP432E4) {\n\t\t/* MSP432E4 does not have main vs info regions, ignore \"all\" */\n\t\tall = false;\n\t}\n\n\tretval = msp432_mass_erase(bank, all);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (msp432_bank->family_type == MSP432E4) {\n\t\t/* MSP432E4 does not have main vs info regions */\n\t\tLOG_INFO(\"msp432: Mass erase of flash is complete\");\n\t} else {\n\t\tLOG_INFO(\"msp432: Mass erase of %s is complete\",\n\t\t\tall ? \"main + information flash\" : \"main flash\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(msp432_bsl_command)\n{\n\tstruct flash_bank *bank;\n\tstruct msp432_bank *msp432_bank;\n\n\tint retval;\n\n\tif (1 > CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmsp432_bank = bank->driver_priv;\n\n\tif (msp432_bank->family_type == MSP432E4) {\n\t\tLOG_WARNING(\"msp432: MSP432E4 does not have a BSL region\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (2 == CMD_ARGC) {\n\t\tif (strcmp(CMD_ARGV[1], \"lock\") == 0)\n\t\t\tmsp432_bank->unlock_bsl = false;\n\t\telse if (strcmp(CMD_ARGV[1], \"unlock\") == 0)\n\t\t\tmsp432_bank->unlock_bsl = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else if (1 != CMD_ARGC) {\n\t\t/* Extra, unknown argument passed in */\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tLOG_INFO(\"msp432: BSL flash region is currently %slocked\",\n\t\tmsp432_bank->unlock_bsl ? \"un\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(msp432_flash_bank_command)\n{\n\tstruct msp432_bank *msp432_bank;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Create shared private struct for flash banks */\n\tmsp432_bank = malloc(sizeof(struct msp432_bank));\n\tif (!msp432_bank)\n\t\treturn ERROR_FAIL;\n\n\t/* Initialize private flash information */\n\tmsp432_bank->device_id = 0;\n\tmsp432_bank->hardware_rev = 0;\n\tmsp432_bank->family_type = MSP432_NO_FAMILY;\n\tmsp432_bank->device_type = MSP432_NO_TYPE;\n\tmsp432_bank->sector_length = 0x1000;\n\tmsp432_bank->probed_main = false;\n\tmsp432_bank->probed_info = false;\n\tmsp432_bank->unlock_bsl = false;\n\tmsp432_bank->working_area = NULL;\n\n\t/* Finish up initial settings here */\n\tbank->driver_priv = msp432_bank;\n\tbank->base = FLASH_BASE;\n\n\treturn ERROR_OK;\n}\n\nstatic int msp432_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\tstruct msp432_algo_params algo_params;\n\n\tbool is_main = bank->base == FLASH_BASE;\n\tbool is_info = bank->base == P4_FLASH_INFO_BASE;\n\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Do a mass erase if user requested all sectors of main flash */\n\tif (is_main && (first == 0) && (last == (bank->num_sectors - 1))) {\n\t\t/* Request mass erase of main flash */\n\t\treturn msp432_mass_erase(bank, false);\n\t}\n\n\tretval = msp432_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters to default values */\n\tmsp432_init_params(&algo_params);\n\n\t/* Adjust params if this is the info bank */\n\tif (is_info) {\n\t\tbuf_set_u32(algo_params.erase_param, 0, 32, FLASH_ERASE_INFO);\n\t\t/* And flag if BSL is unlocked */\n\t\tif (msp432_bank->unlock_bsl)\n\t\t\tbuf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);\n\t}\n\n\t/* Erase requested sectors one by one */\n\tfor (unsigned int i = first; i <= last; i++) {\n\n\t\t/* Skip TVL (read-only) sector of the info bank */\n\t\tif (is_info && 1 == i)\n\t\t\tcontinue;\n\n\t\t/* Skip BSL sectors of info bank if locked */\n\t\tif (is_info && (2 == i || 3 == i) &&\n\t\t\t!msp432_bank->unlock_bsl)\n\t\t\tcontinue;\n\n\t\t/* Convert sector number to starting address of sector */\n\t\tbuf_set_u32(algo_params.address, 0, 32, bank->base +\n\t\t\t(i * msp432_bank->sector_length));\n\n\t\t/* Issue the sector erase command to the flash helper algorithm */\n\t\tretval = msp432_exec_cmd(target, &algo_params, FLASH_SECTOR_ERASE);\n\t\tif (retval != ERROR_OK) {\n\t\t\t(void)msp432_quit(bank);\n\t\t\treturn retval;\n\t\t}\n\n\t\tretval = msp432_wait_return_code(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\t(void)msp432_quit(bank);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = msp432_quit(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int msp432_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\tstruct msp432_algo_params algo_params;\n\tuint32_t size;\n\tuint32_t data_ready = BUFFER_DATA_READY;\n\tlong long start_ms;\n\tlong long elapsed_ms;\n\n\tbool is_info = bank->base == P4_FLASH_INFO_BASE;\n\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/*\n\t * Block attempts to write to read-only sectors of flash\n\t * The TVL region in sector 1 of the info flash is always read-only\n\t * The BSL region in sectors 2 and 3 of the info flash may be unlocked\n\t * The helper algorithm will hang on attempts to write to TVL\n\t */\n\tif (is_info) {\n\t\t/* Set read-only start to TVL sector */\n\t\tuint32_t start = 0x1000;\n\t\t/* Set read-only end after BSL region if locked */\n\t\tuint32_t end = (msp432_bank->unlock_bsl) ? 0x2000 : 0x4000;\n\t\t/* Check if request includes anything in read-only sectors */\n\t\tif ((offset + count - 1) < start || offset >= end) {\n\t\t\t/* The request includes no bytes in read-only sectors */\n\t\t\t/* Fall out and process the request normally */\n\t\t} else {\n\t\t\t/* Send a request for anything before read-only sectors */\n\t\t\tif (offset < start) {\n\t\t\t\tuint32_t start_count = MIN(start - offset, count);\n\t\t\t\tretval = msp432_write(bank, buffer, offset, start_count);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t\t/* Send a request for anything after read-only sectors */\n\t\t\tif ((offset + count - 1) >= end) {\n\t\t\t\tuint32_t skip = end - offset;\n\t\t\t\tcount -= skip;\n\t\t\t\toffset += skip;\n\t\t\t\tbuffer += skip;\n\t\t\t\treturn msp432_write(bank, buffer, offset, count);\n\t\t\t} else {\n\t\t\t\t/* Request is entirely in read-only sectors */\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = msp432_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters to default values */\n\tmsp432_init_params(&algo_params);\n\n\t/* Set up parameters for requested flash write operation */\n\tbuf_set_u32(algo_params.address, 0, 32, bank->base + offset);\n\tbuf_set_u32(algo_params.length, 0, 32, count);\n\n\t/* Check if this is the info bank */\n\tif (is_info) {\n\t\t/* And flag if BSL is unlocked */\n\t\tif (msp432_bank->unlock_bsl)\n\t\t\tbuf_set_u32(algo_params.unlock_bsl, 0, 32, FLASH_UNLOCK_BSL);\n\t}\n\n\t/* Set up flash helper algorithm to continuous flash mode */\n\tretval = msp432_exec_cmd(target, &algo_params, FLASH_CONTINUOUS);\n\tif (retval != ERROR_OK) {\n\t\t(void)msp432_quit(bank);\n\t\treturn retval;\n\t}\n\n\t/* Write requested data, one buffer at a time */\n\tstart_ms = timeval_ms();\n\twhile (count > 0) {\n\n\t\tif (count > ALGO_BUFFER_SIZE)\n\t\t\tsize = ALGO_BUFFER_SIZE;\n\t\telse\n\t\t\tsize = count;\n\n\t\t/* Put next block of data to flash into buffer */\n\t\tretval = target_write_buffer(target, ALGO_BUFFER1_ADDR, size, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write data to target memory\");\n\t\t\t(void)msp432_quit(bank);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\t/* Signal the flash helper algorithm that data is ready to flash */\n\t\tretval = target_write_u32(target, ALGO_BUFFER1_STATUS_ADDR,\n\t\t\t\t\tdata_ready);\n\t\tif (retval != ERROR_OK) {\n\t\t\t(void)msp432_quit(bank);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tretval = msp432_wait_inactive(target, 1);\n\t\tif (retval != ERROR_OK) {\n\t\t\t(void)msp432_quit(bank);\n\t\t\treturn retval;\n\t\t}\n\n\t\tcount -= size;\n\t\tbuffer += size;\n\n\t\telapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > 500)\n\t\t\tkeep_alive();\n\t}\n\n\t/* Confirm that the flash helper algorithm is finished */\n\tretval = msp432_wait_return_code(target);\n\tif (retval != ERROR_OK) {\n\t\t(void)msp432_quit(bank);\n\t\treturn retval;\n\t}\n\n\tretval = msp432_quit(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int msp432_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\n\tuint32_t device_id;\n\tuint32_t hardware_rev;\n\n\tuint32_t sector_length;\n\tuint32_t size;\n\tunsigned int num_sectors;\n\n\tbool is_main = bank->base == FLASH_BASE;\n\tbool is_info = bank->base == P4_FLASH_INFO_BASE;\n\n\tint retval;\n\n\t/* Check if this bank has already been successfully probed */\n\tif (is_main && msp432_bank->probed_main)\n\t\treturn ERROR_OK;\n\tif (is_info && msp432_bank->probed_info)\n\t\treturn ERROR_OK;\n\n\t/* Read the flash size register to determine this is a P4 or not */\n\t/* MSP432P4s will return the size of flash.  MSP432E4s will return zero */\n\tretval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 0) {\n\t\t/* This is likely an MSP432E4 */\n\t\tmsp432_bank->family_type = MSP432E4;\n\n\t\tretval = target_read_u32(target, E4_DID0_REG, &device_id);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tmsp432_bank->device_id = device_id;\n\n\t\tretval = target_read_u32(target, E4_DID1_REG, &hardware_rev);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tmsp432_bank->hardware_rev = hardware_rev;\n\t} else {\n\t\t/* This is likely an MSP432P4 */\n\t\tmsp432_bank->family_type = MSP432P4;\n\n\t\tretval = target_read_u32(target, P4_DEVICE_ID_REG, &device_id);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tmsp432_bank->device_id = device_id & 0xFFFF;\n\n\t\tretval = target_read_u32(target, P4_HARDWARE_REV_REG, &hardware_rev);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tmsp432_bank->hardware_rev = hardware_rev & 0xFF;\n\t}\n\n\tmsp432_bank->device_type = msp432_device_type(msp432_bank->family_type,\n\t\tmsp432_bank->device_id, msp432_bank->hardware_rev);\n\n\tif (msp432_bank->family_type == MSP432P4) {\n\t\t/* Set up MSP432P4 specific flash parameters */\n\t\tif (is_main) {\n\t\t\tretval = target_read_u32(target, P4_FLASH_MAIN_SIZE_REG, &size);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tsector_length = P4_SECTOR_LENGTH;\n\t\t\tnum_sectors = size / sector_length;\n\t\t} else if (is_info) {\n\t\t\tif (msp432_bank->device_type == MSP432P411X ||\n\t\t\t\tmsp432_bank->device_type == MSP432P411X_GUESS) {\n\t\t\t\t/* MSP432P411x has an info size register, use that for size */\n\t\t\t\tretval = target_read_u32(target, P4_FLASH_INFO_SIZE_REG, &size);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else {\n\t\t\t\t/* All other MSP432P401x devices have fixed info region size */\n\t\t\t\tsize = 0x4000; /* 16 KB info region */\n\t\t\t}\n\t\t\tsector_length = P4_SECTOR_LENGTH;\n\t\t\tnum_sectors = size / sector_length;\n\t\t} else {\n\t\t\t/* Invalid bank somehow */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\t/* Set up MSP432E4 specific flash parameters */\n\t\tif (is_main) {\n\t\t\tsize = E4_FLASH_SIZE;\n\t\t\tsector_length = E4_SECTOR_LENGTH;\n\t\t\tnum_sectors = size / sector_length;\n\t\t} else {\n\t\t\t/* Invalid bank somehow */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tif (num_sectors > 0) {\n\t\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\t\tif (!bank->sectors)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->size = size;\n\tbank->write_start_alignment = 0;\n\tbank->write_end_alignment = 0;\n\tbank->num_sectors = num_sectors;\n\tmsp432_bank->sector_length = sector_length;\n\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * sector_length;\n\t\tbank->sectors[i].size = sector_length;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\t/* We've successfully determined the stats on this flash bank */\n\tif (is_main)\n\t\tmsp432_bank->probed_main = true;\n\tif (is_info)\n\t\tmsp432_bank->probed_info = true;\n\n\tif (is_main && MSP432P4 == msp432_bank->family_type) {\n\t\t/* Create the info flash bank needed by MSP432P4 variants */\n\t\tstruct flash_bank *info = calloc(sizeof(struct flash_bank), 1);\n\t\tif (!info)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Create a name for the info bank, append \"_1\" to main name */\n\t\tchar *name = malloc(strlen(bank->name) + 3);\n\t\tstrcpy(name, bank->name);\n\t\tstrcat(name, \"_1\");\n\n\t\t/* Initialize info bank */\n\t\tinfo->name = name;\n\t\tinfo->target = bank->target;\n\t\tinfo->driver = bank->driver;\n\t\tinfo->driver_priv = msp432_bank;\n\t\tinfo->base = P4_FLASH_INFO_BASE;\n\n\t\tflash_bank_add(info);\n\t}\n\n\t/* If we fall through to here, then all went well */\n\n\treturn ERROR_OK;\n}\n\nstatic int msp432_auto_probe(struct flash_bank *bank)\n{\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\n\tbool is_main = bank->base == FLASH_BASE;\n\tbool is_info = bank->base == P4_FLASH_INFO_BASE;\n\n\tint retval = ERROR_OK;\n\n\tif (is_main)\n\t\tif (!msp432_bank->probed_main)\n\t\t\tretval = msp432_probe(bank);\n\tif (is_info)\n\t\tif (!msp432_bank->probed_info)\n\t\t\tretval = msp432_probe(bank);\n\n\treturn retval;\n}\n\nstatic int msp432_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct msp432_bank *msp432_bank = bank->driver_priv;\n\n\tswitch (msp432_bank->device_type) {\n\t\tcase MSP432P401X_DEPR:\n\t\t\tif (msp432_bank->device_id == 0xFFFF) {\n\t\t\t\t/* Very early pre-production silicon currently deprecated */\n\t\t\t\tcommand_print_sameline(cmd, \"MSP432P401x pre-production device (deprecated silicon)\\n\"\n\t\t\t\t\tSUPPORT_MESSAGE);\n\t\t\t} else {\n\t\t\t\t/* Revision A or B silicon, also deprecated */\n\t\t\t\tcommand_print_sameline(cmd, \"MSP432P401x Device Rev %c (deprecated silicon)\\n\"\n\t\t\t\t\tSUPPORT_MESSAGE, (char)msp432_bank->hardware_rev);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase MSP432P401X:\n\t\t\tcommand_print_sameline(cmd, \"MSP432P401x Device Rev %c\\n\",\n\t\t\t\t(char)msp432_bank->hardware_rev);\n\t\t\tbreak;\n\t\tcase MSP432P411X:\n\t\t\tcommand_print_sameline(cmd, \"MSP432P411x Device Rev %c\\n\",\n\t\t\t\t(char)msp432_bank->hardware_rev);\n\t\t\tbreak;\n\t\tcase MSP432E401Y:\n\t\t\tcommand_print_sameline(cmd, \"MSP432E401Y Device\\n\");\n\t\t\tbreak;\n\t\tcase MSP432E411Y:\n\t\t\tcommand_print_sameline(cmd, \"MSP432E411Y Device\\n\");\n\t\t\tbreak;\n\t\tcase MSP432E4X_GUESS:\n\t\t\tcommand_print_sameline(cmd,\n\t\t\t\t\"Unrecognized MSP432E4 DID0 and DID1 IDs (%08\" PRIX32 \", %08\" PRIX32 \")\",\n\t\t\t\tmsp432_bank->device_id, msp432_bank->hardware_rev);\n\t\t\tbreak;\n\t\tcase MSP432P401X_GUESS:\n\t\tcase MSP432P411X_GUESS:\n\t\tdefault:\n\t\t\tcommand_print_sameline(cmd,\n\t\t\t\t\"Unrecognized MSP432P4 Device ID and Hardware Rev (%04\" PRIX32 \", %02\" PRIX32 \")\",\n\t\t\t\tmsp432_bank->device_id, msp432_bank->hardware_rev);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int msp432_protect_check(struct flash_bank *bank)\n{\n\t/* Added to suppress warning, not needed for MSP432 flash */\n\treturn ERROR_OK;\n}\n\nstatic void msp432_flash_free_driver_priv(struct flash_bank *bank)\n{\n\tbool is_main = bank->base == FLASH_BASE;\n\n\t/* A single private struct is shared between main and info banks */\n\t/* Only free it on the call for main bank */\n\tif (is_main)\n\t\tfree(bank->driver_priv);\n\n\t/* Forget about the private struct on both main and info banks */\n\tbank->driver_priv = NULL;\n}\n\nstatic const struct command_registration msp432_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = msp432_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase entire flash memory on device.\",\n\t\t.usage = \"bank_id ['main' | 'all']\",\n\t},\n\t{\n\t\t.name = \"bsl\",\n\t\t.handler = msp432_bsl_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Allow BSL to be erased or written by flash commands.\",\n\t\t.usage = \"bank_id ['unlock' | 'lock']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration msp432_command_handlers[] = {\n\t{\n\t\t.name = \"msp432\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"MSP432 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = msp432_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver msp432_flash = {\n\t.name = \"msp432\",\n\t.commands = msp432_command_handlers,\n\t.flash_bank_command = msp432_flash_bank_command,\n\t.erase = msp432_erase,\n\t.write = msp432_write,\n\t.read = default_flash_read,\n\t.probe = msp432_probe,\n\t.auto_probe = msp432_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = msp432_protect_check,\n\t.info = msp432_info,\n\t.free_driver_priv = msp432_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/msp432.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_MSP432_H\n#define OPENOCD_FLASH_NOR_MSP432_H\n\n/* MSP432 family types */\n#define MSP432_NO_FAMILY 0 /* Family type not determined yet */\n#define MSP432E4         1 /* MSP432E4 family of devices */\n#define MSP432P4         2 /* MSP432P4 family of devices */\n\n/* MSP432 device types */\n#define MSP432_NO_TYPE    0 /* Device type not determined yet */\n#define MSP432P401X_DEPR  1 /* Early MSP432P401x offerings, now deprecated */\n#define MSP432P401X       2 /* MSP432P401x device, revision C or higher */\n#define MSP432P411X       3 /* MSP432P411x device, revision A or higher */\n#define MSP432P401X_GUESS 4 /* Assuming it's an MSP432P401x device */\n#define MSP432P411X_GUESS 5 /* Assuming it's an MSP432P411x device */\n#define MSP432E401Y       6 /* MSP432E401Y device */\n#define MSP432E411Y       7 /* MSP432E401Y device */\n#define MSP432E4X_GUESS   8 /* Assuming it's an MSP432E4x device */\n\n/* Common MSP432 flash parameters */\n#define FLASH_BASE 0x00000000\n\n/* MSP432P4 flash parameters */\n#define P4_FLASH_MAIN_BASE FLASH_BASE\n#define P4_FLASH_INFO_BASE 0x00200000\n#define P4_SECTOR_LENGTH   0x1000\n#define P4_ALGO_ENTRY_ADDR 0x01000110\n\n/* MSP432E4 flash parameters */\n#define E4_FLASH_BASE      FLASH_BASE\n#define E4_FLASH_SIZE      0x100000\n#define E4_SECTOR_LENGTH   0x4000\n#define E4_ALGO_ENTRY_ADDR 0x20000110\n\n/* Flash helper algorithm key addresses */\n#define ALGO_BASE_ADDR           0x20000000\n#define ALGO_BUFFER1_ADDR        0x20002000\n#define ALGO_BUFFER2_ADDR        0x20003000\n#define ALGO_PARAMS_BASE_ADDR    0x20000150\n#define ALGO_FLASH_COMMAND_ADDR  0x20000150\n#define ALGO_RETURN_CODE_ADDR    0x20000154\n#define ALGO_FLASH_DEST_ADDR     0x2000015c\n#define ALGO_FLASH_LENGTH_ADDR   0x20000160\n#define ALGO_BUFFER1_STATUS_ADDR 0x20000164\n#define ALGO_BUFFER2_STATUS_ADDR 0x20000168\n#define ALGO_ERASE_PARAM_ADDR    0x2000016c\n#define ALGO_UNLOCK_BSL_ADDR     0x20000170\n#define ALGO_STACK_POINTER_ADDR  0x20002000\n\n/* Flash helper algorithm key sizes */\n#define ALGO_BUFFER_SIZE  0x1000\n#define ALGO_WORKING_SIZE (ALGO_BUFFER2_ADDR + 0x1000 - ALGO_BASE_ADDR)\n\n/* Flash helper algorithm flash commands */\n#define FLASH_NO_COMMAND    0\n#define FLASH_MASS_ERASE    1\n#define FLASH_SECTOR_ERASE  2\n#define FLASH_PROGRAM       4\n#define FLASH_INIT          8\n#define FLASH_EXIT          16\n#define FLASH_CONTINUOUS    32\n\n/* Flash helper algorithm return codes */\n#define FLASH_BUSY          0x00000001\n#define FLASH_SUCCESS       0x00000ACE\n#define FLASH_ERROR         0x0000DEAD\n#define FLASH_TIMEOUT_ERROR 0xDEAD0000\n#define FLASH_VERIFY_ERROR  0xDEADDEAD\n#define FLASH_WRONG_COMMAND 0x00000BAD\n#define FLASH_POWER_ERROR   0x00DEAD00\n\n/* Flash helper algorithm buffer status values */\n#define BUFFER_INACTIVE   0x00\n#define BUFFER_ACTIVE     0x01\n#define BUFFER_DATA_READY 0x10\n\n/* Flash helper algorithm erase parameters */\n#define FLASH_ERASE_MAIN 0x01\n#define FLASH_ERASE_INFO 0x02\n\n/* Flash helper algorithm lock/unlock BSL options */\n#define FLASH_LOCK_BSL   0x00\n#define FLASH_UNLOCK_BSL 0x0b\n\n/* Flash helper algorithm parameter block struct */\nstruct msp432_algo_params {\n\tuint8_t flash_command[4];\n\tuint8_t return_code[4];\n\tuint8_t _reserved0[4];\n\tuint8_t address[4];\n\tuint8_t length[4];\n\tuint8_t buffer1_status[4];\n\tuint8_t buffer2_status[4];\n\tuint8_t erase_param[4];\n\tuint8_t unlock_bsl[4];\n};\n\n#endif /* OPENOCD_FLASH_NOR_MSP432_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/niietcm4.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Bogdan Kolbov                                   *\n *   kolbov@niiet.ru                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define FLASH_DRIVER_VER\t\t\t0x00010000\n#define CHIPID_ADDR\t\t\t\t\t0xF0000000\n#define K1921VK01T_ID\t\t\t\t0x00000000\n\n/*==============================================================================\n *\t\t\t\t\t\t\tFLASH CONTROL REGS\n *==============================================================================\n */\n\n#define MAIN_MEM_TYPE\t\t\t\t0\n#define INFO_MEM_TYPE\t\t\t\t1\n#define SERVICE_MODE_ERASE_ADDR\t\t0x80030164\n#define MAGIC_KEY\t\t\t\t\t0xA442\n\n/*-- BOOTFLASH ---------------------------------------------------------------*/\n#define BOOTFLASH_BASE\t\t\t\t0xA001C000\n#define FMA\t\t\t\t\t\t\t(BOOTFLASH_BASE + 0x00)\n#define FMD1\t\t\t\t\t\t(BOOTFLASH_BASE + 0x04)\n#define FMC\t\t\t\t\t\t\t(BOOTFLASH_BASE + 0x08)\n#define FCIS\t\t\t\t\t\t(BOOTFLASH_BASE + 0x0C)\n#define FCIM\t\t\t\t\t\t(BOOTFLASH_BASE + 0x10)\n#define FCIC\t\t\t\t\t\t(BOOTFLASH_BASE + 0x14)\n#define FMD2\t\t\t\t\t\t(BOOTFLASH_BASE + 0x50)\n#define FMD3\t\t\t\t\t\t(BOOTFLASH_BASE + 0x54)\n#define FMD4\t\t\t\t\t\t(BOOTFLASH_BASE + 0x58)\n\n\n/*---- FMC: Command register */\n#define FMC_WRITE\t\t\t\t\t(1<<0)\t\t\t\t/* Writing in main region */\n#define FMC_PAGE_ERASE\t\t\t\t(1<<1)\t\t\t\t/* Page erase the main region */\n#define FMC_FULL_ERASE\t\t\t\t(1<<2)\t\t\t\t/* Erase full flash */\n#define FMC_WRITE_IFB\t\t\t\t(1<<4)\t\t\t\t/* Writing in info region */\n#define FMC_PAGEERASE_IFB\t\t\t(1<<5)\t\t\t\t/* Erase page of info region */\n#define FMC_MAGIC_KEY\t\t\t\t(MAGIC_KEY<<16)\t\t/* Operation run command */\n\n/*---- FCIS: Status register */\n#define FCIS_OP_CMLT\t\t\t\t(1<<0)\t\t\t\t/* Completion flag operation */\n#define FCIS_OP_ERROR\t\t\t\t(1<<1)\t\t\t\t/* Flag operation error */\n\n/*---- FCIC: CLear status register */\n#define FCIC_CLR_OPCMLT\t\t\t\t(1<<0)\t\t\t\t/* Clear completion flag in register FCIS */\n#define FCIC_CLR_OPERROR\t\t\t(1<<1)\t\t\t\t/* Clear error flag in register FCIS */\n\n/*-- USERFLASH ---------------------------------------------------------------*/\n#define USERFLASH_PAGE_SIZE\t\t\t256\n#define USERFLASH_PAGE_TOTALNUM\t\t256\n\n#define USERFLASH_BASE\t\t\t\t0xA0022000\n#define UFMA\t\t\t\t\t\t(USERFLASH_BASE + 0x00)\n#define UFMD\t\t\t\t\t\t(USERFLASH_BASE + 0x04)\n#define UFMC\t\t\t\t\t\t(USERFLASH_BASE + 0x08)\n#define UFCIS\t\t\t\t\t\t(USERFLASH_BASE + 0x0C)\n#define UFCIM\t\t\t\t\t\t(USERFLASH_BASE + 0x10)\n#define UFCIC\t\t\t\t\t\t(USERFLASH_BASE + 0x14)\n\n/*---- UFMC: Command register */\n#define UFMC_WRITE\t\t\t\t\t(1<<0)\t\t\t\t/* Writing in main region */\n#define UFMC_PAGE_ERASE\t\t\t\t(1<<1)\t\t\t\t/* Paged erase the main region */\n#define UFMC_FULL_ERASE\t\t\t\t(1<<2)\t\t\t\t/* Erase full flash */\n#define UFMC_READ\t\t\t\t\t(1<<3)\t\t\t\t/* Reading from main region */\n#define UFMC_WRITE_IFB\t\t\t\t(1<<4)\t\t\t\t/* Writing in info region */\n#define UFMC_PAGEERASE_IFB\t\t\t(1<<5)\t\t\t\t/* Erase page of info region */\n#define UFMC_READ_IFB\t\t\t\t(1<<6)\t\t\t\t/* Reading from info region */\n#define UFMC_MAGIC_KEY\t\t\t\t(MAGIC_KEY<<16)\t\t/* Operation run command */\n\n/*---- UFCIS: Status register */\n#define UFCIS_OP_CMLT\t\t\t\t(1<<0)\t\t\t\t/* Completion flag operation */\n#define UFCIS_OP_ERROR\t\t\t\t(1<<1)\t\t\t\t/* Flag operation error */\n\n/*---- UFCIC: CLear status register */\n#define UFCIC_CLR_OPCMLT\t\t\t(1<<0)\t\t\t\t/* Clear completion flag in register FCIS */\n#define UFCIC_CLR_OPERROR\t\t\t(1<<1)\t\t\t\t/* Clear error flag in register FCIS */\n\n/*---- In info userflash address space */\n#define INFOWORD0_ADDR\t\t\t\t0x00\n#define INFOWORD0_BOOTFROM_IFB\t\t(1<<0)\t\t\t\t/* Boot from bootflash or bootflash_ifb */\n#define INFOWORD0_EN_GPIO\t\t\t(1<<1)\t\t\t\t/* Remap to 0x00000000 extmem or bootflash */\n#define INFOWORD0_BOOTFROM_IFB_POS\t0\n#define INFOWORD0_EN_GPIO_POS\t\t1\n#define INFOWORD0_EXTMEM_SEL_POS\t3\t\t\t\t\t/* Choose altfunc of gpio to work with extmem */\n\n#define INFOWORD1_ADDR\t\t\t\t0x01\n#define INFOWORD1_PINNUM_POS\t\t0\t\t\t\t\t/* Choose gpio pin number to control extmem boot */\n#define INFOWORD1_PORTNUM_POS\t\t4\t\t\t\t\t/* Choose gpio port to control extmem boot */\n\n#define INFOWORD2_ADDR\t\t\t\t0x02\n#define INFOWORD2_LOCK_IFB_BF\t\t(1<<0)\t\t\t\t/* Protect info part of bootflash */\n\n#define INFOWORD3_ADDR\t\t\t\t0x03\n#define INFOWORD3_LOCK_IFB_UF\t\t(1<<0)\t\t\t\t/* Protect info part of userflash */\n\n#define BF_LOCK_ADDR\t\t\t\t0x40\n#define UF_LOCK_ADDR\t\t\t\t0x80\n\n/**\n * Private data for flash driver.\n */\nstruct niietcm4_flash_bank {\n\t/* target params */\n\tbool probed;\n\tuint32_t chipid;\n\tchar *chip_name;\n\tchar chip_brief[4096];\n\t/* not mapped userflash params */\n\tuint32_t uflash_width;\n\tuint32_t uflash_size;\n\tuint32_t uflash_pagetotal;\n\tuint32_t uflash_info_size;\n\tuint32_t uflash_info_pagetotal;\n\t/* boot params */\n\tbool bflash_info_remap;\n\tchar *extmem_boot_port;\n\tuint32_t extmem_boot_pin;\n\tuint32_t extmem_boot_altfunc;\n\tbool extmem_boot;\n};\n\n/*==============================================================================\n *\t\t\t\t\t\t\tHELPER FUNCTIONS\n *==============================================================================\n */\n\n/**\n * Wait while operation with bootflash being performed and check result status\n */\nstatic int niietcm4_opstatus_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\tint timeout = 5000;\n\n\tuint32_t flash_status;\n\tretval = target_read_u32(target, FCIS, &flash_status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (flash_status == 0x00) {\n\t\tretval = target_read_u32(target, FCIS, &flash_status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"Bootflash operation timeout\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t}\n\tif (flash_status == FCIS_OP_ERROR) {\n\t\tLOG_ERROR(\"Bootflash operation error\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\t/* clear status */\n\tuint32_t flash_cmd = FCIC_CLR_OPCMLT | FCIC_CLR_OPERROR;\n\tretval = target_write_u32(target, FCIC, flash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\n/**\n * Wait while operation with userflash being performed and check result status\n */\nstatic int niietcm4_uopstatus_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\tint timeout = 5000;\n\n\tuint32_t uflash_status;\n\tretval = target_read_u32(target, UFCIS, &uflash_status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (uflash_status == 0x00) {\n\t\tretval = target_read_u32(target, UFCIS, &uflash_status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"Userflash operation timeout\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t}\n\tif (uflash_status == UFCIS_OP_ERROR) {\n\t\tLOG_ERROR(\"Userflash operation error\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\t/* clear status */\n\tuint32_t uflash_cmd = UFCIC_CLR_OPCMLT | UFCIC_CLR_OPERROR;\n\tretval = target_write_u32(target, UFCIC, uflash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\n/**\n * Dump page of userflash region.\n * If we want to change some settings, we have to dump it full, because userflash is flash(not EEPROM).\n * And correct write to flash can be performed only after erase.\n * So without dump, changing one registers will clear others.\n */\nstatic int niietcm4_dump_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)\n{\n\tstruct target *target = bank->target;\n\tint i;\n\tint retval = ERROR_OK;\n\n\tuint32_t uflash_cmd;\n\tif (mem_type == INFO_MEM_TYPE)\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\telse\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ;\n\n\tint first = page_num*USERFLASH_PAGE_SIZE;\n\tint last = first + USERFLASH_PAGE_SIZE;\n\n\tfor (i = first; i < last; i++) {\n\t\tretval = target_write_u32(target, UFMA, i);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = niietcm4_uopstatus_check(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_read_u32(target, UFMD, &dump[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\n/**\n * Load modified page dump to userflash region page.\n */\nstatic int niietcm4_load_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)\n{\n\tstruct target *target = bank->target;\n\tint i;\n\tint retval = ERROR_OK;\n\n\tuint32_t uflash_cmd;\n\tif (mem_type == INFO_MEM_TYPE)\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE_IFB;\n\telse\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE;\n\n\tint first = page_num*USERFLASH_PAGE_SIZE;\n\tint last = first + USERFLASH_PAGE_SIZE;\n\n\tfor (i = first; i < last; i++) {\n\t\tretval = target_write_u32(target, UFMA, i);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, UFMD, dump[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = niietcm4_uopstatus_check(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\n/**\n * Erase one page of userflash info or main region\n */\nstatic int niietcm4_uflash_page_erase(struct flash_bank *bank, int page_num, int mem_type)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tuint32_t uflash_cmd;\n\tif (mem_type == INFO_MEM_TYPE)\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGEERASE_IFB;\n\telse\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGE_ERASE;\n\n\tretval = target_write_u32(target, UFMA, page_num*USERFLASH_PAGE_SIZE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, UFMD, 0xFF);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* status check */\n\tretval = niietcm4_uopstatus_check(bank);\n\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\treturn retval;\n}\n\n/**\n * Enable or disable protection of userflash pages\n */\nstatic int niietcm4_uflash_protect(struct flash_bank *bank, int mem_type,\n\t\tint set, unsigned int first, unsigned int last)\n{\n\tint retval;\n\tif (mem_type == INFO_MEM_TYPE) {\n\t\t/* read dump */\n\t\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\t\tretval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* modify dump */\n\t\tif (set)\n\t\t\tuflash_dump[INFOWORD2_ADDR] &= ~INFOWORD3_LOCK_IFB_UF;\n\t\telse\n\t\t\tuflash_dump[INFOWORD2_ADDR] |= INFOWORD3_LOCK_IFB_UF;\n\t\t/* erase page 0 userflash */\n\t\tretval = niietcm4_uflash_page_erase(bank, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* write dump to userflash */\n\t\tretval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\t/* read dump */\n\t\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\t\tretval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* modify dump */\n\t\tfor (unsigned int i = first; i <= last; i++) {\n\t\t\tuint32_t reg_num = i/8;\n\t\t\tuint32_t bit_num = i%8;\n\t\t\tif (set)\n\t\t\t\tuflash_dump[UF_LOCK_ADDR+reg_num] &= ~(1<<bit_num);\n\t\t\telse\n\t\t\t\tuflash_dump[UF_LOCK_ADDR+reg_num] |= (1<<bit_num);\n\t\t}\n\t\t/* erase page 0 info userflash */\n\t\tretval = niietcm4_uflash_page_erase(bank, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* write dump to userflash */\n\t\tretval = niietcm4_load_uflash_page(bank, uflash_dump,  0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\n/*==============================================================================\n *\t\t\t\t\t\t\tFLASH COMMANDS\n *==============================================================================\n */\nCOMMAND_HANDLER(niietcm4_handle_uflash_read_byte_command)\n{\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tuint32_t uflash_addr;\n\tuint32_t uflash_cmd;\n\tuint32_t uflash_data;\n\n\tif (strcmp(\"info\", CMD_ARGV[0]) == 0)\n\t\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\telse if (strcmp(\"main\", CMD_ARGV[0]) == 0)\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);\n\n\tretval = target_write_u32(target, UFMA, uflash_addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* status check */\n\tretval = niietcm4_uopstatus_check(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_read_u32(target, UFMD, &uflash_data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcommand_print(CMD,  \"Read userflash %s region:\\n\"\n\t\t\t\t\t\t\"address = 0x%04\" PRIx32 \",\\n\"\n\t\t\t\t\t\t\"value   = 0x%02\" PRIx32 \".\", CMD_ARGV[0], uflash_addr, uflash_data);\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_uflash_write_byte_command)\n{\n\tif (CMD_ARGC < 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tuint32_t uflash_addr;\n\tuint32_t uflash_data;\n\tint mem_type;\n\n\tif (strcmp(\"info\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 1;\n\telse if (strcmp(\"main\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 0;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], uflash_data);\n\n\tint page_num = uflash_addr/USERFLASH_PAGE_SIZE;\n\n\tcommand_print(CMD, \"Write userflash %s region:\\n\"\n\t\t\t\t\t   \"address = 0x%04\" PRIx32 \",\\n\"\n\t\t\t\t\t   \"value   = 0x%02\" PRIx32 \".\\n\"\n\t\t\t\t\t   \"Please wait ... \", CMD_ARGV[0], uflash_addr, uflash_data);\n\t/* dump */\n\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\tniietcm4_dump_uflash_page(bank, uflash_dump, page_num, mem_type);\n\n\t/* modify dump */\n\tuflash_dump[uflash_addr%USERFLASH_PAGE_SIZE] = uflash_data;\n\n\t/* erase page userflash */\n\tniietcm4_uflash_page_erase(bank, page_num, mem_type);\n\n\t/* write dump to userflash */\n\tniietcm4_load_uflash_page(bank, uflash_dump, page_num, mem_type);\n\tcommand_print(CMD, \"done!\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_uflash_full_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t uflash_addr = 0;\n\tuint32_t uflash_data = 0xFF;\n\tuint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_FULL_ERASE;\n\n\tretval = target_write_u32(target, UFMA, uflash_addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, UFMD, uflash_data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* status check */\n\tretval = niietcm4_uopstatus_check(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcommand_print(CMD, \"Userflash full erase done!\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_uflash_erase_command)\n{\n\tif (CMD_ARGC < 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tunsigned int first, last;\n\tint mem_type;\n\n\tif (strcmp(\"info\", CMD_ARGV[0]) == 0)\n\t\t\tmem_type = 1;\n\telse if (strcmp(\"main\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 0;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = niietcm4_uflash_page_erase(bank, i, mem_type);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tcommand_print(CMD, \"Erase %s userflash pages %u through %u done!\", CMD_ARGV[0], first, last);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_uflash_protect_check_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct target *target = bank->target;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tint mem_type;\n\tif (strcmp(\"info\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 1;\n\telse if (strcmp(\"main\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 0;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint i, j;\n\tuint32_t uflash_addr;\n\tuint32_t uflash_cmd;\n\tuint32_t uflash_data;\n\n\t/* chose between main userflash and info userflash */\n\tif (mem_type == INFO_MEM_TYPE) {\n\t\tuflash_addr = INFOWORD3_ADDR;\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\t\tretval = target_write_u32(target, UFMA, uflash_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* status check */\n\t\tretval = niietcm4_uopstatus_check(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_read_u32(target, UFMD, &uflash_data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (uflash_data & INFOWORD3_LOCK_IFB_UF)\n\t\t\tcommand_print(CMD, \"All sectors of info userflash are not protected!\");\n\t\telse\n\t\t\tcommand_print(CMD, \"All sectors of info userflash are protected!\");\n\t} else {\n\t\tuflash_addr = UF_LOCK_ADDR;\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\t\tfor (i = 0; i < USERFLASH_PAGE_TOTALNUM/8; i++) {\n\t\t\tretval = target_write_u32(target, UFMA, uflash_addr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* status check */\n\t\t\tretval = niietcm4_uopstatus_check(bank);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_read_u32(target, UFMD, &uflash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tfor (j = 0; j < 8; j++) {\n\t\t\t\tif (uflash_data & 0x1)\n\t\t\t\t\tcommand_print(CMD, \"Userflash sector #%03d: 0x%04x (0x100) is not protected!\",\n\t\t\t\t\t\t\t\t\t\t\ti*8+j, (i*8+j)*USERFLASH_PAGE_SIZE);\n\t\t\t\telse\n\t\t\t\t\tcommand_print(CMD, \"Userflash sector #%03d: 0x%04x (0x100) is protected!\",\n\t\t\t\t\t\t\t\t\t\t\ti*8+j, (i*8+j)*USERFLASH_PAGE_SIZE);\n\t\t\t\tuflash_data = uflash_data >> 1;\n\t\t\t}\n\t\t\tuflash_addr++;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_uflash_protect_command)\n{\n\tif (CMD_ARGC < 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tint mem_type;\n\tif (strcmp(\"info\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 1;\n\telse if (strcmp(\"main\", CMD_ARGV[0]) == 0)\n\t\tmem_type = 0;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned int first, last;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);\n\n\tint set;\n\tif (strcmp(\"on\", CMD_ARGV[3]) == 0) {\n\t\tcommand_print(CMD, \"Try to enable %s userflash sectors %u through %u protection. Please wait ... \",\n\t\t\t\t\t\t\t\tCMD_ARGV[0], first, last);\n\t\tset = 1;\n\t} else if (strcmp(\"off\", CMD_ARGV[3]) == 0) {\n\t\tcommand_print(CMD, \"Try to disable %s userflash sectors %u through %u protection. Please wait ... \",\n\t\t\t\t\t\t\t\tCMD_ARGV[0], first, last);\n\t\tset = 0;\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = niietcm4_uflash_protect(bank, mem_type, set, first, last);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\tcommand_print(CMD, \"done!\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_bflash_info_remap_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tint set;\n\tif (strcmp(\"on\", CMD_ARGV[0]) == 0) {\n\t\tcommand_print(CMD, \"Try to enable bootflash info region remap. Please wait ...\");\n\t\tset = 1;\n\t} else if (strcmp(\"off\", CMD_ARGV[0]) == 0) {\n\t\tcommand_print(CMD, \"Try to disable bootflash info region remap. Please wait ...\");\n\t\tset = 0;\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* dump */\n\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\tniietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\n\t/* modify dump */\n\tif (set)\n\t\tuflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_BOOTFROM_IFB;\n\telse\n\t\tuflash_dump[INFOWORD0_ADDR] |= INFOWORD0_BOOTFROM_IFB;\n\n\t/* erase page userflash */\n\tniietcm4_uflash_page_erase(bank, 0, 1);\n\n\t/* write dump to userflash */\n\tniietcm4_load_uflash_page(bank, uflash_dump, 0, 1);\n\tcommand_print(CMD, \"done!\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_extmem_cfg_command)\n{\n\tif (CMD_ARGC < 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tuint32_t port;\n\tif (strcmp(\"gpioa\", CMD_ARGV[0]) == 0)\n\t\tport = 8;\n\telse if (strcmp(\"gpiob\", CMD_ARGV[0]) == 0)\n\t\tport = 9;\n\telse if (strcmp(\"gpioc\", CMD_ARGV[0]) == 0)\n\t\tport = 10;\n\telse if (strcmp(\"gpiod\", CMD_ARGV[0]) == 0)\n\t\tport = 11;\n\telse if (strcmp(\"gpioe\", CMD_ARGV[0]) == 0)\n\t\tport = 12;\n\telse if (strcmp(\"gpiof\", CMD_ARGV[0]) == 0)\n\t\tport = 13;\n\telse if (strcmp(\"gpiog\", CMD_ARGV[0]) == 0)\n\t\tport = 14;\n\telse if (strcmp(\"gpioh\", CMD_ARGV[0]) == 0)\n\t\tport = 15;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t pin;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pin);\n\tif (pin > 15)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t func;\n\tif (strcmp(\"func1\", CMD_ARGV[2]) == 0)\n\t\tfunc = 0;\n\telse if (strcmp(\"func3\", CMD_ARGV[2]) == 0)\n\t\tfunc = 3;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,  \"Try to configure external memory boot interface:\\n\"\n\t\t\t\t\t\t\"port = %s\\n\"\n\t\t\t\t\t\t\"pin  = %s\\n\"\n\t\t\t\t\t\t\"func = %s\\n\"\n\t\t\t\t\t\t\"Please wait ...\", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2]);\n\t/* dump */\n\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\tniietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\n\t/* modify dump */\n\tuflash_dump[INFOWORD0_ADDR] &= ~(3<<INFOWORD0_EXTMEM_SEL_POS);\n\tuflash_dump[INFOWORD0_ADDR] |= func<<INFOWORD0_EXTMEM_SEL_POS;\n\tuflash_dump[INFOWORD1_ADDR] = (port<<INFOWORD1_PORTNUM_POS) | (pin<<INFOWORD1_PINNUM_POS);\n\n\t/* erase page userflash */\n\tniietcm4_uflash_page_erase(bank, 0, 1);\n\n\t/* write dump to userflash */\n\tniietcm4_load_uflash_page(bank, uflash_dump, 0, 1);\n\tcommand_print(CMD, \"done!\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_extmem_boot_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\tint set;\n\n\tif (strcmp(\"on\", CMD_ARGV[0]) == 0) {\n\t\tcommand_print(CMD, \"Try to enable boot from external memory. Please wait ...\");\n\t\tset = 1;\n\t} else if (strcmp(\"off\", CMD_ARGV[0]) == 0) {\n\t\tcommand_print(CMD, \"Try to disable boot from external memory. Please wait ...\");\n\t\tset = 0;\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* dump */\n\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\tniietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\n\t/* modify dump */\n\tif (set)\n\t\tuflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_EN_GPIO;\n\telse\n\t\tuflash_dump[INFOWORD0_ADDR] |= INFOWORD0_EN_GPIO;\n\n\t/* erase page userflash */\n\tniietcm4_uflash_page_erase(bank, 0, 1);\n\n\t/* write dump to userflash */\n\tniietcm4_load_uflash_page(bank, uflash_dump, 0, 1);\n\tcommand_print(CMD, \"done!\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_service_mode_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct target *target = bank->target;\n\n\tcommand_print(CMD, \"Try to perform service mode erase. Please wait ...\");\n\n\tretval = target_write_u32(target, SERVICE_MODE_ERASE_ADDR, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint timeout = 500;\n\tuint32_t status;\n\n\tretval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (status != 0x03) {\n\t\tretval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"Service mode erase timeout\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t}\n\tcommand_print(CMD, \"done! All data erased.\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(niietcm4_handle_driver_info_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"niietcm4 flash driver\\n\"\n\t\t\t\t\t\t   \"version: %d.%d\\n\"\n\t\t\t\t\t\t   \"author: Bogdan Kolbov\\n\"\n\t\t\t\t\t\t   \"mail: kolbov@niiet.ru\",\n\t\t\t\t\t\t   FLASH_DRIVER_VER>>16,\n\t\t\t\t\t\t   FLASH_DRIVER_VER&0xFFFF);\n\n\treturn retval;\n}\n\nstatic const struct command_registration niietcm4_exec_command_handlers[] = {\n\t{\n\t\t.name = \"uflash_read_byte\",\n\t\t.handler = niietcm4_handle_uflash_read_byte_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('main'|'info') address\",\n\t\t.help = \"Read byte from main or info userflash region\",\n\t},\n\t{\n\t\t.name = \"uflash_write_byte\",\n\t\t.handler = niietcm4_handle_uflash_write_byte_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('main'|'info') address value\",\n\t\t.help = \"Write byte to main or info userflash region\",\n\t},\n\t{\n\t\t.name = \"uflash_full_erase\",\n\t\t.handler = niietcm4_handle_uflash_full_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase all userflash including info region\",\n\t},\n\t{\n\t\t.name = \"uflash_erase\",\n\t\t.handler = niietcm4_handle_uflash_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('main'|'info') first_sector_num last_sector_num\",\n\t\t.help = \"Erase sectors of main or info userflash region, starting at sector first up to and including last.\",\n\t},\n\t{\n\t\t.name = \"uflash_protect_check\",\n\t\t.handler = niietcm4_handle_uflash_protect_check_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('main'|'info')\",\n\t\t.help = \"Check sectors protect.\",\n\t},\n\t{\n\t\t.name = \"uflash_protect\",\n\t\t.handler = niietcm4_handle_uflash_protect_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('main'|'info') first_sector_num last_sector_num ('on'|'off')\",\n\t\t.help = \"Protect sectors of main or info userflash region, starting at sector first up to and including last.\",\n\t},\n\t{\n\t\t.name = \"bflash_info_remap\",\n\t\t.handler = niietcm4_handle_bflash_info_remap_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('on'|'off')\",\n\t\t.help = \"Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used).\",\n\t},\n\t{\n\t\t.name = \"extmem_cfg\",\n\t\t.handler = niietcm4_handle_extmem_cfg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')\",\n\t\t.help = \"Configure external memory interface for boot.\",\n\t},\n\t{\n\t\t.name = \"extmem_boot\",\n\t\t.handler = niietcm4_handle_extmem_boot_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('on'|'off')\",\n\t\t.help = \"Enable boot from external memory.\",\n\t},\n\t{\n\t\t.name = \"service_mode_erase\",\n\t\t.handler = niietcm4_handle_service_mode_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Perform emergency erase of all flash (bootflash and userflash).\",\n\t},\n\t{\n\t\t.name = \"driver_info\",\n\t\t.handler = niietcm4_handle_driver_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Show information about flash driver.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration niietcm4_command_handlers[] = {\n\t{\n\t\t.name = \"niietcm4\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"niietcm4 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = niietcm4_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/*==============================================================================\n *\t\t\t\t\t\t\tFLASH INTERFACE\n *==============================================================================\n */\n\nFLASH_BANK_COMMAND_HANDLER(niietcm4_flash_bank_command)\n{\n\tstruct niietcm4_flash_bank *niietcm4_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tniietcm4_info = malloc(sizeof(struct niietcm4_flash_bank));\n\n\tbank->driver_priv = niietcm4_info;\n\n\t/* information will be updated by probing */\n\tniietcm4_info->probed = false;\n\tniietcm4_info->chipid = 0;\n\tniietcm4_info->chip_name = NULL;\n\tniietcm4_info->uflash_width = 0;\n\tniietcm4_info->uflash_size = 0;\n\tniietcm4_info->uflash_pagetotal = 0;\n\tniietcm4_info->uflash_info_size = 0;\n\tniietcm4_info->uflash_info_pagetotal = 0;\n\tniietcm4_info->bflash_info_remap = false;\n\tniietcm4_info->extmem_boot_port = NULL;\n\tniietcm4_info->extmem_boot_pin = 0;\n\tniietcm4_info->extmem_boot_altfunc = 0;\n\tniietcm4_info->extmem_boot = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int niietcm4_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\n\tint retval = ERROR_FLASH_OPERATION_FAILED;\n\tint set;\n\tuint32_t uflash_addr;\n\tuint32_t uflash_cmd;\n\tuint32_t uflash_data;\n\t/* chose between main bootflash and info bootflash  */\n\tif (niietcm4_info->bflash_info_remap) {\n\t\tuflash_addr = INFOWORD2_ADDR;\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\t\tretval = target_write_u32(target, UFMA, uflash_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* status check */\n\t\tretval = niietcm4_uopstatus_check(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_read_u32(target, UFMD, &uflash_data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (uflash_data & INFOWORD2_LOCK_IFB_BF)\n\t\t\tset = 0;\n\t\telse\n\t\t\tset = 1;\n\t\tbank->sectors[0].is_protected = set;\n\t} else {\n\t\tuflash_addr = BF_LOCK_ADDR;\n\t\tuflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\t\tfor (unsigned int i = 0; i < bank->num_sectors/8; i++) {\n\t\t\tretval = target_write_u32(target, UFMA, uflash_addr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* status check */\n\t\t\tretval = niietcm4_uopstatus_check(bank);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_read_u32(target, UFMD, &uflash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tfor (int j = 0; j < 8; j++) {\n\t\t\t\tif (uflash_data & 0x1)\n\t\t\t\t\tset = 0;\n\t\t\t\telse\n\t\t\t\t\tset = 1;\n\t\t\t\tbank->sectors[i*8+j].is_protected = set;\n\t\t\t\tuflash_data = uflash_data >> 1;\n\t\t\t}\n\t\t\tuflash_addr++;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int niietcm4_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\n\tint retval;\n\tuint32_t flash_cmd;\n\n\t/* start mass erase */\n\tflash_cmd = FMC_MAGIC_KEY | FMC_FULL_ERASE;\n\tretval = target_write_u32(target, FMC, flash_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* status check */\n\tretval = niietcm4_opstatus_check(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int niietcm4_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tint retval = ERROR_FLASH_OPERATION_FAILED;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1))) {\n\t\tretval = niietcm4_mass_erase(bank);\n\t\treturn retval;\n\t}\n\n\t/* chose between main bootflash and info bootflash */\n\tuint32_t flash_cmd, flash_addr;\n\tif (niietcm4_info->bflash_info_remap)\n\t\tflash_cmd = FMC_MAGIC_KEY | FMC_PAGEERASE_IFB;\n\telse\n\t\tflash_cmd = FMC_MAGIC_KEY | FMC_PAGE_ERASE;\n\n\t/* erasing pages */\n\tunsigned int page_size = bank->size / bank->num_sectors;\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\t/* current page addr */\n\t\tflash_addr = i*page_size;\n\t\tretval = target_write_u32(target, FMA, flash_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* start erase */\n\t\tretval = target_write_u32(target, FMC, flash_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* status check */\n\t\tretval = niietcm4_opstatus_check(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int niietcm4_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_INFO(\"Please wait ...\"); /* it`s quite a long process */\n\t/* chose between main bootflash and info bootflash */\n\tif (niietcm4_info->bflash_info_remap) {\n\t\t/* dump */\n\t\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\t\tretval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* modify dump */\n\t\tif (set)\n\t\t\tuflash_dump[INFOWORD2_ADDR] &= ~INFOWORD2_LOCK_IFB_BF;\n\t\telse\n\t\t\tuflash_dump[INFOWORD2_ADDR] |= INFOWORD2_LOCK_IFB_BF;\n\t\t/* erase page 0 userflash */\n\t\tretval = niietcm4_uflash_page_erase(bank, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* write dump to userflash */\n\t\tretval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\t/* read dump*/\n\t\tuint32_t uflash_dump[USERFLASH_PAGE_SIZE];\n\t\tretval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* modify dump */\n\t\tfor (unsigned int i = first; i <= last; i++)\t{\n\t\t\tuint32_t reg_num = i/8;\n\t\t\tuint32_t bit_num = i%8;\n\t\t\tif (set)\n\t\t\t\tuflash_dump[BF_LOCK_ADDR+reg_num] &= ~(1<<bit_num);\n\t\t\telse\n\t\t\t\tuflash_dump[BF_LOCK_ADDR+reg_num] |= (1<<bit_num);\n\t\t}\n\t\t/* erase page 0 info userflash */\n\t\tretval = niietcm4_uflash_page_erase(bank, 0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* write dump to userflash */\n\t\tretval = niietcm4_load_uflash_page(bank, uflash_dump,  0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int niietcm4_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tuint32_t buffer_size = 32768 + 8; /* 8 bytes for rp and wp */\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* see contrib/loaders/flash/k1921vk01t.S for src */\n\tstatic const uint8_t niietcm4_flash_write_code[] = {\n\t\t0x14, 0x4f, 0x16, 0x68, 0x00, 0x2e, 0x23, 0xd0, 0x55, 0x68, 0xb5, 0x42, 0xf9, 0xd0, 0x2e, 0x68,\n\t\t0x7e, 0x60, 0x04, 0x35, 0x2e, 0x68, 0x3e, 0x65, 0x04, 0x35, 0x2e, 0x68, 0x7e, 0x65, 0x04, 0x35,\n\t\t0x2e, 0x68, 0xbe, 0x65, 0x04, 0x35, 0x3c, 0x60, 0x10, 0x34, 0xb8, 0x60, 0xfe, 0x68, 0x00, 0x2e,\n\t\t0xfc, 0xd0, 0x02, 0x2e, 0x0a, 0xd0, 0x01, 0x26, 0x7e, 0x61, 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46,\n\t\t0x08, 0x35, 0x55, 0x60, 0x01, 0x39, 0x00, 0x29, 0x02, 0xd0, 0xda, 0xe7, 0x00, 0x20, 0x50, 0x60,\n\t\t0x30, 0x46, 0x00, 0xbe, 0x00, 0xc0, 0x01, 0xa0\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(niietcm4_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(niietcm4_flash_write_code), niietcm4_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tbuffer_size &= ~15UL; /* Make sure it's 16 byte aligned */\n\t\tbuffer_size += 8; /* And 8 bytes for WP and RP */\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* write_cmd base (in), status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* count (128bit) */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN_OUT);\t/* target address */\n\n\tuint32_t flash_cmd;\n\tif (niietcm4_info->bflash_info_remap)\n\t\tflash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB;\n\telse\n\t\tflash_cmd = FMC_MAGIC_KEY | FMC_WRITE;\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, flash_cmd);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, 16,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED)\n\t\tLOG_ERROR(\"flash write failed at address 0x%\"PRIx32,\n\t\t\t\tbuf_get_u32(reg_params[4].value, 0, 32));\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\nstatic int niietcm4_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tuint8_t *new_buffer = NULL;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0xF) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 4-word alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* If there's an odd number of words, the data has to be padded. Duplicate\n\t * the buffer and use the normal code path with a single block write since\n\t * it's probably cheaper than to special case the last odd write using\n\t * discrete accesses. */\n\n\tint rem = count % 16;\n\tif (rem) {\n\t\tnew_buffer = malloc(count + 16 - rem);\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"Odd number of words to write and no memory for padding buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"Odd number of words to write, padding with 0xFFFFFFFF\");\n\t\tbuffer = memcpy(new_buffer, buffer, count);\n\t\twhile (rem < 16) {\n\t\t\tnew_buffer[count++] = 0xff;\n\t\t\trem++;\n\t\t}\n\t}\n\n\tint retval;\n\n\t/* try using block write */\n\tretval = niietcm4_write_block(bank, buffer, offset, count/16);\n\tuint32_t flash_addr, flash_cmd, flash_data;\n\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t/* if block write failed (no sufficient working area),\n\t\t * we use normal (slow) single halfword accesses */\n\t\tLOG_WARNING(\"Can't use block writes, falling back to single memory accesses\");\n\t\tLOG_INFO(\"Please wait ...\"); /* it`s quite a long process */\n\n\t\t/* chose between main bootflash and info bootflash */\n\t\tif (niietcm4_info->bflash_info_remap)\n\t\t\tflash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB;\n\t\telse\n\t\t\tflash_cmd = FMC_MAGIC_KEY | FMC_WRITE;\n\n\t\t/* write 16 bytes per try */\n\t\tfor (unsigned int i = 0; i < count; i += 16) {\n\t\t\t/* current addr */\n\t\t\tLOG_INFO(\"%u byte of %\" PRIu32, i, count);\n\t\t\tflash_addr = offset + i;\n\t\t\tretval = target_write_u32(target, FMA, flash_addr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\n\t\t\t/* Prepare data (4 words) */\n\t\t\tuint32_t value[4];\n\t\t\tmemcpy(&value, buffer + i*16, 4*sizeof(uint32_t));\n\n\t\t\t/* place in reg 16 bytes of data */\n\t\t\tflash_data = value[0];\n\t\t\tretval = target_write_u32(target, FMD1, flash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\t\t\tflash_data = value[1];\n\t\t\tretval = target_write_u32(target, FMD2, flash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\t\t\tflash_data = value[2];\n\t\t\tretval = target_write_u32(target, FMD3, flash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\t\t\tflash_data = value[3];\n\t\t\tretval = target_write_u32(target, FMD4, flash_data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\n\t\t\t/* write start */\n\t\t\tretval = target_write_u32(target, FMC, flash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\n\t\t\t/* status check */\n\t\t\tretval = niietcm4_opstatus_check(bank);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto free_buffer;\n\t\t}\n\n\t}\n\nfree_buffer:\n\tfree(new_buffer);\n\treturn retval;\n}\n\nstatic int niietcm4_probe_k1921vk01t(struct flash_bank *bank)\n{\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tniietcm4_info->chip_name = \"K1921VK01T\";\n\n\t/* check if we in service mode */\n\tuint32_t service_mode;\n\tretval = target_read_u32(target, 0x80017000, &service_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tservice_mode = (service_mode>>2) & 0x1;\n\n\tif (!service_mode) {\n\t\tniietcm4_info->uflash_width = 8;\n\t\tniietcm4_info->uflash_size = 0x10000;\n\t\tniietcm4_info->uflash_pagetotal = 256;\n\t\tniietcm4_info->uflash_info_size = 0x200;\n\t\tniietcm4_info->uflash_info_pagetotal = 2;\n\n\t\tuint32_t uflash_data[2];\n\t\tuint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;\n\t\tfor (int i = 0; i < 2; i++) {\n\t\t\tretval = target_write_u32(target, UFMA, i);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_u32(target, UFMC, uflash_cmd);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* status check */\n\t\t\tretval = niietcm4_uopstatus_check(bank);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_read_u32(target, UFMD, &uflash_data[i]);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tint boot_from_ifb = (uflash_data[0]>>INFOWORD0_BOOTFROM_IFB_POS) & 0x1;\n\t\tint en_gpio = (uflash_data[0]>>INFOWORD0_EN_GPIO_POS) & 0x1;\n\t\tint extmem_sel = (uflash_data[0]>>INFOWORD0_EXTMEM_SEL_POS) & 0x3;\n\t\tint pinnum = (uflash_data[1]>>INFOWORD1_PINNUM_POS) & 0xF;\n\t\tint portnum = (uflash_data[1]>>INFOWORD1_PORTNUM_POS) & 0x7;\n\n\t\tif (boot_from_ifb)\n\t\t\tniietcm4_info->bflash_info_remap = false;\n\t\telse\n\t\t\tniietcm4_info->bflash_info_remap = true;\n\t\tif (extmem_sel == 0x2)\n\t\t\tniietcm4_info->extmem_boot_altfunc = 3;\n\t\telse\n\t\t\tniietcm4_info->extmem_boot_altfunc = 1;\n\t\tif (portnum == 0x0)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOA\";\n\t\telse if (portnum == 0x1)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOB\";\n\t\telse if (portnum == 0x2)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOC\";\n\t\telse if (portnum == 0x3)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOD\";\n\t\telse if (portnum == 0x4)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOE\";\n\t\telse if (portnum == 0x5)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOF\";\n\t\telse if (portnum == 0x6)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOG\";\n\t\telse if (portnum == 0x7)\n\t\t\tniietcm4_info->extmem_boot_port = \"GPIOH\";\n\t\telse\n\t\t\tniietcm4_info->extmem_boot_port = \"not defined\";\n\t\tif (en_gpio)\n\t\t\tniietcm4_info->extmem_boot = false;\n\t\telse\n\t\t\tniietcm4_info->extmem_boot = true;\n\t\tniietcm4_info->extmem_boot_pin = pinnum;\n\n\t\t/* check state of extmem boot en pin, if \"high\", extmem remapped to 0x00000000 */\n\t\tuint32_t extmem_boot_port_data;\n\t\tretval = target_read_u32(target, 0x80010000 + 0x1000*portnum, &extmem_boot_port_data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tint extmem_boot_pin_data = (extmem_boot_port_data>>pinnum) & 0x1;\n\n\t\tuint32_t extmem_base;\n\t\tuint32_t bflash_base;\n\t\tif (extmem_boot_pin_data && niietcm4_info->extmem_boot) {\n\t\t\textmem_base = 0x00000000;\n\t\t\tbflash_base = 0x40000000;\n\t\t} else {\n\t\t\textmem_base = 0x40000000;\n\t\t\tbflash_base = 0x00000000;\n\t\t}\n\n\t\tuint32_t bflash_size = 0x100000;\n\t\tuint32_t bflash_pages = 128;\n\t\tuint32_t bflash_info_size = 0x2000;\n\t\tuint32_t bflash_info_pages = 1;\n\t\tif (niietcm4_info->bflash_info_remap) {\n\t\t\tbflash_base += 0x2000;\n\t\t\tbflash_size -= 0x2000;\n\t\t\tbflash_pages--;\n\t\t\tbank->size = bflash_info_size;\n\t\t\tbank->num_sectors = bflash_info_pages;\n\t\t} else {\n\t\t\tbank->size = bflash_size;\n\t\t\tbank->num_sectors = bflash_pages;\n\t\t}\n\n\t\tchar info_bootflash_addr_str[64];\n\t\tif (niietcm4_info->bflash_info_remap)\n\t\t\tsnprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str),\n\t\t\t\t\tTARGET_ADDR_FMT \" base address\", bank->base);\n\t\telse\n\t\t\tsnprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str),\n\t\t\t\t\t\"not mapped to global address space\");\n\n\t\tsnprintf(niietcm4_info->chip_brief,\n\t\t\t\tsizeof(niietcm4_info->chip_brief),\n\t\t\t\t\"\\n\"\n\t\t\t\t\"MEMORY CONFIGURATION\\n\"\n\t\t\t\t\"Bootflash :\\n\"\n\t\t\t\t\"    %\" PRIu32 \" kB total\\n\"\n\t\t\t\t\"    %\" PRIu32 \" pages %\" PRIu32 \" kB each\\n\"\n\t\t\t\t\"    0x%08\" PRIx32 \" base address\\n\"\n\t\t\t\t\"%s\"\n\t\t\t\t\"Info bootflash :\\n\"\n\t\t\t\t\"    %\" PRIu32 \" kB total\\n\"\n\t\t\t\t\"    %\" PRIu32 \" pages %\" PRIu32 \" kB each\\n\"\n\t\t\t\t\"    %s\\n\"\n\t\t\t\t\"%s\"\n\t\t\t\t\"Userflash :\\n\"\n\t\t\t\t\"    %\" PRIu32 \" kB total\\n\"\n\t\t\t\t\"    %\" PRIu32 \" pages %\" PRIu32 \" B each\\n\"\n\t\t\t\t\"    %\" PRIu32 \" bit cells\\n\"\n\t\t\t\t\"    not mapped to global address space\\n\"\n\t\t\t\t\"Info userflash :\\n\"\n\t\t\t\t\"    %\" PRIu32 \" B total\\n\"\n\t\t\t\t\"    %\" PRIu32 \" pages of %\" PRIu32 \" B each\\n\"\n\t\t\t\t\"    %\" PRIu32 \" bit cells\\n\"\n\t\t\t\t\"    not mapped to global address space\\n\"\n\t\t\t\t\"RAM :\\n\"\n\t\t\t\t\"    192 kB total\\n\"\n\t\t\t\t\"    0x20000000 base address\\n\"\n\t\t\t\t\"External memory :\\n\"\n\t\t\t\t\"    8/16 bit address space\\n\"\n\t\t\t\t\"    0x%08\" PRIx32 \" base address\\n\"\n\t\t\t\t\"\\n\"\n\t\t\t\t\"INFOWORD STATUS\\n\"\n\t\t\t\t\"Bootflash info region remap :\\n\"\n\t\t\t\t\"    %s\\n\"\n\t\t\t\t\"External memory boot port :\\n\"\n\t\t\t\t\"    %s\\n\"\n\t\t\t\t\"External memory boot pin :\\n\"\n\t\t\t\t\"    %\" PRIu32 \"\\n\"\n\t\t\t\t\"External memory interface alternative function :\\n\"\n\t\t\t\t\"    %\" PRIu32 \"\\n\"\n\t\t\t\t\"Option boot from external memory :\\n\"\n\t\t\t\t\"    %s\\n\",\n\t\t\t\tbflash_size/1024,\n\t\t\t\tbflash_pages,\n\t\t\t\t(bflash_size/bflash_pages)/1024,\n\t\t\t\tbflash_base,\n\t\t\t\tniietcm4_info->bflash_info_remap ? \"\" : \"    this flash will be used for debugging, writing and etc\\n\",\n\t\t\t\tbflash_info_size/1024,\n\t\t\t\tbflash_info_pages,\n\t\t\t\t(bflash_info_size/bflash_info_pages)/1024,\n\t\t\t\tinfo_bootflash_addr_str,\n\t\t\t\tniietcm4_info->bflash_info_remap ? \"    this flash will be used for debugging, writing and etc\\n\" : \"\",\n\t\t\t\tniietcm4_info->uflash_size/1024,\n\t\t\t\tniietcm4_info->uflash_pagetotal,\n\t\t\t\tniietcm4_info->uflash_size/niietcm4_info->uflash_pagetotal,\n\t\t\t\tniietcm4_info->uflash_width,\n\t\t\t\tniietcm4_info->uflash_info_size,\n\t\t\t\tniietcm4_info->uflash_info_pagetotal,\n\t\t\t\tniietcm4_info->uflash_info_size/niietcm4_info->uflash_info_pagetotal,\n\t\t\t\tniietcm4_info->uflash_width,\n\t\t\t\textmem_base,\n\t\t\t\tniietcm4_info->bflash_info_remap ? \"enable\" : \"disable\",\n\t\t\t\tniietcm4_info->extmem_boot_port,\n\t\t\t\tniietcm4_info->extmem_boot_pin,\n\t\t\t\tniietcm4_info->extmem_boot_altfunc,\n\t\t\t\tniietcm4_info->extmem_boot ? \"enable\" : \"disable\");\n\t} else {\n\t\tbank->size = 0x100000;\n\t\tbank->num_sectors = 128;\n\n\t\tsprintf(niietcm4_info->chip_brief,\n\t\t\t\t\"\\n\"\n\t\t\t\t\"H[2] was HIGH while startup. Device entered service mode.\\n\"\n\t\t\t\t\"All flashes were locked.\\n\"\n\t\t\t\t\"If you want to perform emergency erase (erase all flashes),\\n\"\n\t\t\t\t\"please use \\\"service_mode_erase\\\" command and reset device.\\n\"\n\t\t\t\t\"Do not forget to pull H[2] down while reset for returning to normal operation mode.\\n\"\n\t\t\t\t);\n\t}\n\n\treturn retval;\n}\n\nstatic int niietcm4_probe(struct flash_bank *bank)\n{\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tuint32_t retval;\n\tuint32_t chipid;\n\n\tretval = target_read_u32(target, CHIPID_ADDR, &chipid);\n\tif (retval != ERROR_OK) {\n\t\tchipid = K1921VK01T_ID;\n\t\tLOG_INFO(\"unknown chipid, assuming K1921VK01T\");\n\t}\n\n\tif (chipid == K1921VK01T_ID)\n\t\tniietcm4_probe_k1921vk01t(bank);\n\n\tint page_total = bank->num_sectors;\n\tint page_size = bank->size / page_total;\n\n\tbank->sectors = malloc(sizeof(struct flash_sector) * page_total);\n\n\tfor (int i = 0; i < page_total; i++) {\n\t\tbank->sectors[i].offset = i * page_size;\n\t\tbank->sectors[i].size = page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\tniietcm4_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int niietcm4_auto_probe(struct flash_bank *bank)\n{\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tif (niietcm4_info->probed)\n\t\treturn ERROR_OK;\n\treturn niietcm4_probe(bank);\n}\n\nstatic int get_niietcm4_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;\n\tcommand_print_sameline(cmd, \"\\nNIIET Cortex-M4F %s\\n%s\",\n\t\t\tniietcm4_info->chip_name, niietcm4_info->chip_brief);\n\treturn ERROR_OK;\n}\n\n\nconst struct flash_driver niietcm4_flash = {\n\t.name = \"niietcm4\",\n\t.usage = \"flash bank <name> niietcm4 <base> <size> 0 0 <target#>\",\n\t.commands = niietcm4_command_handlers,\n\t.flash_bank_command = niietcm4_flash_bank_command,\n\t.erase = niietcm4_erase,\n\t.protect = niietcm4_protect,\n\t.write = niietcm4_write,\n\t.read = default_flash_read,\n\t.probe = niietcm4_probe,\n\t.auto_probe = niietcm4_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = niietcm4_protect_check,\n\t.info = get_niietcm4_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/non_cfi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *   Copyright (C) 2009 Michael Schwingen                                  *\n *   michael@schwingen.org                                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"cfi.h\"\n#include \"non_cfi.h\"\n\n#define KB 1024\n#define MB (1024*1024)\n#define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))\n\n/* non-CFI compatible flashes */\nstatic const struct non_cfi non_cfi_flashes[] = {\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0xd4,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 64*KB,\n\t\t.interface_desc = 0x0,\t\t/* x8 only device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(16, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0xd5,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 128*KB,\n\t\t.interface_desc = 0x0,\t\t/* x8 only device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(32, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0xd6,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 256*KB,\n\t\t.interface_desc = 0x0,\t\t/* x8 only device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(64, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0xd7,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x0,\t\t/* x8 only device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(128, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_AMD,\t\t/* Spansion AM29LV040B */\n\t\t.id = 0x4f,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x0,\t\t/* x8 only device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(8, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x2780,\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(128, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_ST,\n\t\t.id = 0xd6,\t\t\t\t\t/* ST29F400BB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(7, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_ST,\n\t\t.id = 0xd5,\t\t\t\t\t/* ST29F400BT */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(7, 64*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 16*KB)\n\t\t}\n\t},\n\n\t/* SST 39VF* do not support DQ5 status polling - this currently is\n\t   only supported by the host algorithm, not by the target code using\n\t   the work area.\n\t   Only true for 8-bit and 32-bit wide memories. 16-bit wide memories\n\t   without DQ5 status polling are supported by the target code.\n\t*/\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x2782,\t\t\t\t/* SST39xF160 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(512, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x2783,\t\t\t\t/* SST39VF320 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 4*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1024, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x234b,\t\t\t\t/* SST39VF1601 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(512, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x274b,\t\t\t\t/* SST39WF1601 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(512, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x234a,\t\t\t\t/* SST39VF1602 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(512, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x235b,\t\t\t\t/* SST39VF3201 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 4*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1024, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x235a,\t\t\t\t/* SST39VF3202 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 4*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1024, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_SST,\n\t\t.id = 0x236d,\t\t/* SST39VF6401B */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 8*MB,\n\t\t.interface_desc = 0x2,\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,\n\t\t.num_erase_regions = 1,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(2048, 4*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_AMD,\n\t\t.id = 0x22ab,\t\t\t\t/* AM29F400BB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(7, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_AMD,\n\t\t.id = 0x2223,\t\t\t\t/* AM29F400BT */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(7, 64*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 16*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_FUJITSU,\n\t\t.id = 0x226b,\t\t\t\t/* AM29SL800DB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(15, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_FUJITSU,\n\t\t.id = 0x22ea,\t\t\t\t/* MBM29SL800TE */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(15, 64*KB),\n\t\t\tERASE_REGION(1,  32*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1,  16*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_FUJITSU,\n\t\t.id = 0xba,\t\t\t\t/* 29LV400BC */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 512*KB,\n\t\t.interface_desc = 0x1,\t\t/* x8 or x16 device w/ nBYTE */\n\t\t.max_buf_write_size = 0x00,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(7, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_AMIC,\n\t\t.id = 0xb31a,\t\t\t\t/* A29L800A */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(15, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_MX,\n\t\t.id = 0x225b,\t\t\t\t/* MX29LV800B */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2, 8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(15, 64*KB)\n\t\t}\n\t},\n\n\t{\n\t\t.mfr = CFI_MFR_MX,\n\t\t.id = 0x2249,\t\t\t\t/* MX29LV160AB: 2MB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2, 8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(31, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_MX,\n\t\t.id = 0x22C4,\t\t\t\t/* MX29LV160AT: 2MB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(31, 64*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(2, 8*KB),\n\t\t\tERASE_REGION(1, 16*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_EON,\n\t\t.id = 0x225b,\t\t\t\t/* EN29LV800BB */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2,  8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(15, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_ATMEL,\n\t\t.id = 0x00c0,\t\t\t\t/* Atmel 49BV1614 */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 3,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(8,  8*KB),\n\t\t\tERASE_REGION(2, 32*KB),\n\t\t\tERASE_REGION(30, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_ATMEL,\n\t\t.id = 0xC2,\t\t\t\t\t/* Atmel 49BV1614T */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 2*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 3,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(30, 64*KB),\n\t\t\tERASE_REGION(2, 32*KB),\n\t\t\tERASE_REGION(8,  8*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = CFI_MFR_AMD,\n\t\t.id = 0x225b,\t\t\t\t/* S29AL008D */\n\t\t.pri_id = 0x02,\n\t\t.dev_size = 1*MB,\n\t\t.interface_desc = 0x2,\t\t/* x8 or x16 device with nBYTE */\n\t\t.max_buf_write_size = 0x0,\n\t\t.status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,\n\t\t.num_erase_regions = 4,\n\t\t.erase_region_info = {\n\t\t\tERASE_REGION(1, 16*KB),\n\t\t\tERASE_REGION(2, 8*KB),\n\t\t\tERASE_REGION(1, 32*KB),\n\t\t\tERASE_REGION(15, 64*KB)\n\t\t}\n\t},\n\t{\n\t\t.mfr = 0,\n\t\t.id = 0,\n\t}\n};\n\nvoid cfi_fixup_non_cfi(struct flash_bank *bank)\n{\n\tunsigned int mask;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tconst struct non_cfi *non_cfi = non_cfi_flashes;\n\n\tif (cfi_info->x16_as_x8)\n\t\tmask = 0xFF;\n\telse\n\t\tmask = 0xFFFF;\n\n\tfor (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++) {\n\t\tif ((cfi_info->manufacturer == non_cfi->mfr)\n\t\t    && (cfi_info->device_id == (non_cfi->id & mask)))\n\t\t\tbreak;\n\t}\n\n\t/* only fixup jedec flashes found in table */\n\tif (!non_cfi->mfr)\n\t\treturn;\n\n\tcfi_info->not_cfi = true;\n\n\t/* fill in defaults for non-critical data */\n\tcfi_info->vcc_min = 0x0;\n\tcfi_info->vcc_max = 0x0;\n\tcfi_info->vpp_min = 0x0;\n\tcfi_info->vpp_max = 0x0;\n\t/* these are used for timeouts - use vales that should be long enough\n\t   for normal operation. */\n\tcfi_info->word_write_timeout_typ = 0x0a;\n\tcfi_info->buf_write_timeout_typ = 0x0d;\n\tcfi_info->block_erase_timeout_typ = 0x0d;\n\tcfi_info->chip_erase_timeout_typ = 0x10;\n\tcfi_info->word_write_timeout_max = 0x0;\n\tcfi_info->buf_write_timeout_max = 0x0;\n\tcfi_info->block_erase_timeout_max = 0x0;\n\tcfi_info->chip_erase_timeout_max = 0x0;\n\n\tcfi_info->qry[0] = 'Q';\n\tcfi_info->qry[1] = 'R';\n\tcfi_info->qry[2] = 'Y';\n\n\tcfi_info->pri_id = non_cfi->pri_id;\n\tcfi_info->pri_addr = 0x0;\n\tcfi_info->alt_id = 0x0;\n\tcfi_info->alt_addr = 0x0;\n\tcfi_info->alt_ext = NULL;\n\n\tcfi_info->interface_desc = non_cfi->interface_desc;\n\tcfi_info->max_buf_write_size = non_cfi->max_buf_write_size;\n\tcfi_info->status_poll_mask = non_cfi->status_poll_mask;\n\tcfi_info->num_erase_regions = non_cfi->num_erase_regions;\n\tsize_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) *\n\t\tcfi_info->num_erase_regions;\n\tcfi_info->erase_region_info = malloc(erase_region_info_size);\n\tmemcpy(cfi_info->erase_region_info,\n\t\tnon_cfi->erase_region_info, erase_region_info_size);\n\tcfi_info->dev_size = non_cfi->dev_size;\n\n\tif (cfi_info->pri_id == 0x2) {\n\t\tstruct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));\n\n\t\tpri_ext->pri[0] = 'P';\n\t\tpri_ext->pri[1] = 'R';\n\t\tpri_ext->pri[2] = 'I';\n\n\t\tpri_ext->major_version = '1';\n\t\tpri_ext->minor_version = '0';\n\n\t\tpri_ext->silicon_revision = 0x0;\n\t\tpri_ext->erase_suspend = 0x0;\n\t\tpri_ext->blk_prot = 0x0;\n\t\tpri_ext->tmp_blk_unprotected = 0x0;\n\t\tpri_ext->blk_prot_unprot = 0x0;\n\t\tpri_ext->simultaneous_ops = 0x0;\n\t\tpri_ext->burst_mode = 0x0;\n\t\tpri_ext->page_mode = 0x0;\n\t\tpri_ext->vpp_min = 0x0;\n\t\tpri_ext->vpp_max = 0x0;\n\t\tpri_ext->top_bottom = 0x0;\n\n\t\tpri_ext->_unlock1 = 0x5555;\n\t\tpri_ext->_unlock2 = 0x2AAA;\n\t\tpri_ext->_reversed_geometry = 0;\n\n\t\tcfi_info->pri_ext = pri_ext;\n\t} else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3)) {\n\t\tLOG_ERROR(\"BUG: non-CFI flashes using the Intel commandset are not yet supported\");\n\t\texit(-1);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/non_cfi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_NON_CFI_H\n#define OPENOCD_FLASH_NOR_NON_CFI_H\n\nstruct non_cfi {\n\tuint16_t mfr;\n\tuint16_t id;\n\tuint16_t pri_id;\n\tuint32_t dev_size;\n\tuint16_t interface_desc;\n\tuint16_t max_buf_write_size;\n\tuint8_t num_erase_regions;\n\tuint32_t erase_region_info[6];\n\tuint8_t  status_poll_mask;\n};\n\nvoid cfi_fixup_non_cfi(struct flash_bank *bank);\n\n#endif /* OPENOCD_FLASH_NOR_NON_CFI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/npcx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2020 by Nuvoton Technology Corporation\n * Mulin Chao <mlchao@nuvoton.com>\n * Wealian Liao <WHLIAO@nuvoton.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/armv7m.h>\n#include \"../../../contrib/loaders/flash/npcx/npcx_flash.h\"\n\n/* NPCX flash loader */\nstatic const uint8_t npcx_algo[] = {\n#include \"../../../contrib/loaders/flash/npcx/npcx_algo.inc\"\n};\n\n#define NPCX_FLASH_TIMEOUT_MS 8000\n#define NPCX_FLASH_BASE_ADDR 0x64000000\n\n/* flash list */\nenum npcx_flash_device_index {\n\tNPCX_FLASH_256KB = 0,\n\tNPCX_FLASH_512KB = 1,\n\tNPCX_FLASH_1MB = 2,\n\tNPCX_FLASH_UNKNOWN,\n};\n\nstruct npcx_flash_bank {\n\tconst char *family_name;\n\tuint32_t sector_length;\n\tbool probed;\n\tenum npcx_flash_device_index flash;\n\tstruct working_area *working_area;\n\tstruct armv7m_algorithm armv7m_info;\n\tconst uint8_t *algo_code;\n\tuint32_t algo_size;\n\tuint32_t algo_working_size;\n\tuint32_t buffer_addr;\n\tuint32_t params_addr;\n};\n\nstruct npcx_flash_info {\n\tchar *name;\n\tuint32_t id;\n\tuint32_t size;\n};\n\nstatic const struct npcx_flash_info flash_info[] = {\n\t[NPCX_FLASH_256KB] = {\n\t\t.name = \"256KB Flash\",\n\t\t.id = 0xEF4012,\n\t\t.size = 256 * 1024,\n\t},\n\t[NPCX_FLASH_512KB] = {\n\t\t.name = \"512KB Flash\",\n\t\t.id = 0xEF4013,\n\t\t.size = 512 * 1024,\n\t},\n\t[NPCX_FLASH_1MB] = {\n\t\t.name = \"1MB Flash\",\n\t\t.id = 0xEF4014,\n\t\t.size = 1024 * 1024,\n\t},\n\t[NPCX_FLASH_UNKNOWN] = {\n\t\t.name = \"Unknown Flash\",\n\t\t.size = 0xFFFFFFFF,\n\t},\n};\n\nstatic int npcx_init(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\n\t/* Check for working area to use for flash helper algorithm */\n\ttarget_free_working_area(target, npcx_bank->working_area);\n\tnpcx_bank->working_area = NULL;\n\n\tint retval = target_alloc_working_area(target, npcx_bank->algo_working_size,\n\t\t\t\t&npcx_bank->working_area);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Confirm the defined working address is the area we need to use */\n\tif (npcx_bank->working_area->address != NPCX_FLASH_LOADER_WORKING_ADDR) {\n\t\tLOG_ERROR(\"%s: Invalid working address\", npcx_bank->family_name);\n\t\tLOG_INFO(\"Hint: Use '-work-area-phys 0x%\" PRIx32 \"' in your target configuration\",\n\t\t\tNPCX_FLASH_LOADER_WORKING_ADDR);\n\t\ttarget_free_working_area(target, npcx_bank->working_area);\n\t\tnpcx_bank->working_area = NULL;\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Write flash helper algorithm into target memory */\n\tretval = target_write_buffer(target, NPCX_FLASH_LOADER_PROGRAM_ADDR,\n\t\t\t\tnpcx_bank->algo_size, npcx_bank->algo_code);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to load flash helper algorithm\",\n\t\t\tnpcx_bank->family_name);\n\t\ttarget_free_working_area(target, npcx_bank->working_area);\n\t\tnpcx_bank->working_area = NULL;\n\t\treturn retval;\n\t}\n\n\t/* Initialize the ARMv7 specific info to run the algorithm */\n\tnpcx_bank->armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tnpcx_bank->armv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* Begin executing the flash helper algorithm */\n\tretval = target_start_algorithm(target, 0, NULL, 0, NULL,\n\t\t\t\tNPCX_FLASH_LOADER_PROGRAM_ADDR, 0,\n\t\t\t\t&npcx_bank->armv7m_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to start flash helper algorithm\",\n\t\t\tnpcx_bank->family_name);\n\t\ttarget_free_working_area(target, npcx_bank->working_area);\n\t\tnpcx_bank->working_area = NULL;\n\t\treturn retval;\n\t}\n\n\t/*\n\t * At this point, the algorithm is running on the target and\n\t * ready to receive commands and data to flash the target\n\t */\n\n\treturn retval;\n}\n\nstatic int npcx_quit(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\n\t/* Regardless of the algo's status, attempt to halt the target */\n\t(void)target_halt(target);\n\n\t/* Now confirm target halted and clean up from flash helper algorithm */\n\tint retval = target_wait_algorithm(target, 0, NULL, 0, NULL, 0,\n\t\t\t\t\tNPCX_FLASH_TIMEOUT_MS, &npcx_bank->armv7m_info);\n\n\ttarget_free_working_area(target, npcx_bank->working_area);\n\tnpcx_bank->working_area = NULL;\n\n\treturn retval;\n}\n\nstatic int npcx_wait_algo_done(struct flash_bank *bank, uint32_t params_addr)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tuint32_t status_addr = params_addr + offsetof(struct npcx_flash_params, sync);\n\tuint32_t status;\n\tint64_t start_ms = timeval_ms();\n\n\tdo {\n\t\tint retval = target_read_u32(target, status_addr, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tkeep_alive();\n\n\t\tint64_t elapsed_ms = timeval_ms() - start_ms;\n\t\tif (elapsed_ms > NPCX_FLASH_TIMEOUT_MS)\n\t\t\tbreak;\n\t} while (status == NPCX_FLASH_LOADER_EXECUTE);\n\n\tif (status != NPCX_FLASH_LOADER_WAIT) {\n\t\tLOG_ERROR(\"%s: Flash operation failed, status=0x%\" PRIx32,\n\t\t\t\tnpcx_bank->family_name,\n\t\t\t\tstatus);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic enum npcx_flash_device_index npcx_get_flash_id(struct flash_bank *bank, uint32_t *flash_id)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tstruct npcx_flash_params algo_params;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint retval = npcx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set up algorithm parameters for get flash ID command */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_GET_FLASH_ID);\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);\n\n\t/* Issue flash helper algorithm parameters for get flash ID */\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\tif (retval != ERROR_OK) {\n\t\t(void)npcx_quit(bank);\n\t\treturn retval;\n\t}\n\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\n\t/* If no error, wait for finishing */\n\tif (retval == ERROR_OK) {\n\t\tretval = npcx_wait_algo_done(bank, npcx_bank->params_addr);\n\t\tif (retval == ERROR_OK)\n\t\t\ttarget_read_u32(target, NPCX_FLASH_LOADER_BUFFER_ADDR, flash_id);\n\t}\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)npcx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int npcx_get_flash(uint32_t flash_id)\n{\n\tfor (uint32_t i = 0; i < ARRAY_SIZE(flash_info) - 1; i++) {\n\t\tif (flash_info[i].id == flash_id)\n\t\t\treturn i;\n\t}\n\n\treturn NPCX_FLASH_UNKNOWN;\n}\n\nstatic int npcx_probe(struct flash_bank *bank)\n{\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tuint32_t sector_length = NPCX_FLASH_ERASE_SIZE;\n\tuint32_t flash_id;\n\n\t/* Set up appropriate flash helper algorithm */\n\tnpcx_bank->algo_code = npcx_algo;\n\tnpcx_bank->algo_size = sizeof(npcx_algo);\n\tnpcx_bank->algo_working_size = NPCX_FLASH_LOADER_PARAMS_SIZE +\n\t\t\t\t\tNPCX_FLASH_LOADER_BUFFER_SIZE +\n\t\t\t\t\tNPCX_FLASH_LOADER_PROGRAM_SIZE;\n\tnpcx_bank->buffer_addr = NPCX_FLASH_LOADER_BUFFER_ADDR;\n\tnpcx_bank->params_addr = NPCX_FLASH_LOADER_PARAMS_ADDR;\n\n\tint retval = npcx_get_flash_id(bank, &flash_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tnpcx_bank->flash = npcx_get_flash(flash_id);\n\n\tunsigned int num_sectors = flash_info[npcx_bank->flash].size / sector_length;\n\n\tbank->sectors = calloc(num_sectors, sizeof(struct flash_sector));\n\tif (!bank->sectors) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->base = NPCX_FLASH_BASE_ADDR;\n\tbank->num_sectors = num_sectors;\n\tbank->size = num_sectors * sector_length;\n\tbank->write_start_alignment = 0;\n\tbank->write_end_alignment = 0;\n\tnpcx_bank->sector_length = sector_length;\n\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * sector_length;\n\t\tbank->sectors[i].size = sector_length;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\t/* We've successfully determined the stats on the flash bank */\n\tnpcx_bank->probed = true;\n\n\t/* If we fall through to here, then all went well */\n\treturn ERROR_OK;\n}\n\nstatic int npcx_auto_probe(struct flash_bank *bank)\n{\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tif (!npcx_bank->probed)\n\t\tretval = npcx_probe(bank);\n\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(npcx_flash_bank_command)\n{\n\tstruct npcx_flash_bank *npcx_bank;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tnpcx_bank = calloc(1, sizeof(struct npcx_flash_bank));\n\tif (!npcx_bank) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Initialize private flash information */\n\tnpcx_bank->family_name = \"npcx\";\n\tnpcx_bank->sector_length = NPCX_FLASH_ERASE_SIZE;\n\n\t/* Finish initialization of bank */\n\tbank->driver_priv = npcx_bank;\n\tbank->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nstatic int npcx_chip_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tstruct npcx_flash_params algo_params;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Make sure we've probed the flash to get the device and size */\n\tint retval = npcx_auto_probe(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = npcx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set up algorithm parameters for chip erase command */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_ALL);\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);\n\n\t/* Set algorithm parameters */\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\tif (retval != ERROR_OK) {\n\t\t(void)npcx_quit(bank);\n\t\treturn retval;\n\t}\n\n\t/* Issue flash helper algorithm parameters for chip erase */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\n\t/* If no error, wait for chip erase finish */\n\tif (retval == ERROR_OK)\n\t\tretval = npcx_wait_algo_done(bank, npcx_bank->params_addr);\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)npcx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int npcx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tstruct npcx_flash_params algo_params;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1))) {\n\t\t/* Request chip erase */\n\t\treturn npcx_chip_erase(bank);\n\t}\n\n\tuint32_t address = first * npcx_bank->sector_length;\n\tuint32_t length = (last - first + 1) * npcx_bank->sector_length;\n\n\t/* Make sure we've probed the flash to get the device and size */\n\tint retval = npcx_auto_probe(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = npcx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set up algorithm parameters for erase command */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.len, length);\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_ERASE_SECTORS);\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);\n\n\t/* Set algorithm parameters */\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\tif (retval != ERROR_OK) {\n\t\t(void)npcx_quit(bank);\n\t\treturn retval;\n\t}\n\n\t/* Issue flash helper algorithm parameters for erase */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);\n\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\n\t/* If no error, wait for erase to finish */\n\tif (retval == ERROR_OK)\n\t\tretval = npcx_wait_algo_done(bank, npcx_bank->params_addr);\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)npcx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int npcx_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\tstruct npcx_flash_params algo_params;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Make sure we've probed the flash to get the device and size */\n\tint retval = npcx_auto_probe(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = npcx_init(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Initialize algorithm parameters to default values */\n\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.cmd, NPCX_FLASH_CMD_PROGRAM);\n\n\tuint32_t address = offset;\n\n\twhile (count > 0) {\n\t\tuint32_t size = (count > NPCX_FLASH_LOADER_BUFFER_SIZE) ?\n\t\t\t\t\t\t\tNPCX_FLASH_LOADER_BUFFER_SIZE : count;\n\n\t\t/* Put the data into buffer */\n\t\tretval = target_write_buffer(target, npcx_bank->buffer_addr,\n\t\t\t\t\tsize, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write data to target memory\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Update algo parameters for flash write */\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.addr, address);\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.len, size);\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_WAIT);\n\n\t\t/* Set algorithm parameters */\n\t\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Issue flash helper algorithm parameters for flash write */\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&algo_params.sync, NPCX_FLASH_LOADER_EXECUTE);\n\t\tretval = target_write_buffer(target, npcx_bank->params_addr,\n\t\t\t\tsizeof(algo_params), (uint8_t *)&algo_params);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Wait for flash write finish */\n\t\tretval = npcx_wait_algo_done(bank, npcx_bank->params_addr);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tcount -= size;\n\t\tbuffer += size;\n\t\taddress += size;\n\t}\n\n\t/* Regardless of errors, try to close down algo */\n\t(void)npcx_quit(bank);\n\n\treturn retval;\n}\n\nstatic int npcx_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct npcx_flash_bank *npcx_bank = bank->driver_priv;\n\n\tcommand_print_sameline(cmd, \"%s flash: %s\\n\",\n\t\t\t\t\tnpcx_bank->family_name,\n\t\t\t\t\tflash_info[npcx_bank->flash].name);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver npcx_flash = {\n\t.name = \"npcx\",\n\t.flash_bank_command = npcx_flash_bank_command,\n\t.erase = npcx_erase,\n\t.write = npcx_write,\n\t.read = default_flash_read,\n\t.probe = npcx_probe,\n\t.auto_probe = npcx_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = npcx_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/nrf5.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 Synapse Product Development                        *\n *   Andrey Smirnov <andrew.smironv@gmail.com>                             *\n *   Angus Gratton <gus@projectgus.com>                                    *\n *   Erdem U. Altunyurt <spamjunkeater@gmail.com>                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <helper/types.h>\n#include <helper/time_support.h>\n\n/* Both those values are constant across the current spectrum ofr nRF5 devices */\n#define WATCHDOG_REFRESH_REGISTER       0x40010600\n#define WATCHDOG_REFRESH_VALUE          0x6e524635\n\nenum {\n\tNRF5_FLASH_BASE = 0x00000000,\n};\n\nenum nrf5_ficr_registers {\n\tNRF5_FICR_BASE = 0x10000000, /* Factory Information Configuration Registers */\n\n#define NRF5_FICR_REG(offset) (NRF5_FICR_BASE + offset)\n\n\tNRF5_FICR_CODEPAGESIZE\t\t= NRF5_FICR_REG(0x010),\n\tNRF5_FICR_CODESIZE\t\t= NRF5_FICR_REG(0x014),\n\n\tNRF51_FICR_CLENR0\t\t= NRF5_FICR_REG(0x028),\n\tNRF51_FICR_PPFC\t\t\t= NRF5_FICR_REG(0x02C),\n\tNRF51_FICR_NUMRAMBLOCK\t\t= NRF5_FICR_REG(0x034),\n\tNRF51_FICR_SIZERAMBLOCK0\t= NRF5_FICR_REG(0x038),\n\tNRF51_FICR_SIZERAMBLOCK1\t= NRF5_FICR_REG(0x03C),\n\tNRF51_FICR_SIZERAMBLOCK2\t= NRF5_FICR_REG(0x040),\n\tNRF51_FICR_SIZERAMBLOCK3\t= NRF5_FICR_REG(0x044),\n\n\tNRF5_FICR_CONFIGID\t\t= NRF5_FICR_REG(0x05C),\n\tNRF5_FICR_DEVICEID0\t\t= NRF5_FICR_REG(0x060),\n\tNRF5_FICR_DEVICEID1\t\t= NRF5_FICR_REG(0x064),\n\tNRF5_FICR_ER0\t\t\t= NRF5_FICR_REG(0x080),\n\tNRF5_FICR_ER1\t\t\t= NRF5_FICR_REG(0x084),\n\tNRF5_FICR_ER2\t\t\t= NRF5_FICR_REG(0x088),\n\tNRF5_FICR_ER3\t\t\t= NRF5_FICR_REG(0x08C),\n\tNRF5_FICR_IR0\t\t\t= NRF5_FICR_REG(0x090),\n\tNRF5_FICR_IR1\t\t\t= NRF5_FICR_REG(0x094),\n\tNRF5_FICR_IR2\t\t\t= NRF5_FICR_REG(0x098),\n\tNRF5_FICR_IR3\t\t\t= NRF5_FICR_REG(0x09C),\n\tNRF5_FICR_DEVICEADDRTYPE\t= NRF5_FICR_REG(0x0A0),\n\tNRF5_FICR_DEVICEADDR0\t\t= NRF5_FICR_REG(0x0A4),\n\tNRF5_FICR_DEVICEADDR1\t\t= NRF5_FICR_REG(0x0A8),\n\n\tNRF51_FICR_OVERRIDEN\t\t= NRF5_FICR_REG(0x0AC),\n\tNRF51_FICR_NRF_1MBIT0\t\t= NRF5_FICR_REG(0x0B0),\n\tNRF51_FICR_NRF_1MBIT1\t\t= NRF5_FICR_REG(0x0B4),\n\tNRF51_FICR_NRF_1MBIT2\t\t= NRF5_FICR_REG(0x0B8),\n\tNRF51_FICR_NRF_1MBIT3\t\t= NRF5_FICR_REG(0x0BC),\n\tNRF51_FICR_NRF_1MBIT4\t\t= NRF5_FICR_REG(0x0C0),\n\tNRF51_FICR_BLE_1MBIT0\t\t= NRF5_FICR_REG(0x0EC),\n\tNRF51_FICR_BLE_1MBIT1\t\t= NRF5_FICR_REG(0x0F0),\n\tNRF51_FICR_BLE_1MBIT2\t\t= NRF5_FICR_REG(0x0F4),\n\tNRF51_FICR_BLE_1MBIT3\t\t= NRF5_FICR_REG(0x0F8),\n\tNRF51_FICR_BLE_1MBIT4\t\t= NRF5_FICR_REG(0x0FC),\n\n\t/* Following registers are available on nRF52 and on nRF51 since rev 3 */\n\tNRF5_FICR_INFO_PART\t\t\t= NRF5_FICR_REG(0x100),\n\tNRF5_FICR_INFO_VARIANT\t\t= NRF5_FICR_REG(0x104),\n\tNRF5_FICR_INFO_PACKAGE\t\t= NRF5_FICR_REG(0x108),\n\tNRF5_FICR_INFO_RAM\t\t\t= NRF5_FICR_REG(0x10C),\n\tNRF5_FICR_INFO_FLASH\t\t= NRF5_FICR_REG(0x110),\n};\n\nenum nrf5_uicr_registers {\n\tNRF5_UICR_BASE = 0x10001000, /* User Information\n\t\t\t\t       * Configuration Registers */\n\n#define NRF5_UICR_REG(offset) (NRF5_UICR_BASE + offset)\n\n\tNRF51_UICR_CLENR0\t= NRF5_UICR_REG(0x000),\n\tNRF51_UICR_RBPCONF\t= NRF5_UICR_REG(0x004),\n\tNRF51_UICR_XTALFREQ\t= NRF5_UICR_REG(0x008),\n\tNRF51_UICR_FWID\t\t= NRF5_UICR_REG(0x010),\n};\n\nenum nrf5_nvmc_registers {\n\tNRF5_NVMC_BASE = 0x4001E000, /* Non-Volatile Memory\n\t\t\t\t       * Controller Registers */\n\n#define NRF5_NVMC_REG(offset) (NRF5_NVMC_BASE + offset)\n\n\tNRF5_NVMC_READY\t= NRF5_NVMC_REG(0x400),\n\tNRF5_NVMC_CONFIG\t= NRF5_NVMC_REG(0x504),\n\tNRF5_NVMC_ERASEPAGE\t= NRF5_NVMC_REG(0x508),\n\tNRF5_NVMC_ERASEALL\t= NRF5_NVMC_REG(0x50C),\n\tNRF5_NVMC_ERASEUICR\t= NRF5_NVMC_REG(0x514),\n\n\tNRF5_BPROT_BASE = 0x40000000,\n};\n\nenum nrf5_nvmc_config_bits {\n\tNRF5_NVMC_CONFIG_REN = 0x00,\n\tNRF5_NVMC_CONFIG_WEN = 0x01,\n\tNRF5_NVMC_CONFIG_EEN = 0x02,\n\n};\n\nstruct nrf52_ficr_info {\n\tuint32_t part;\n\tuint32_t variant;\n\tuint32_t package;\n\tuint32_t ram;\n\tuint32_t flash;\n};\n\nenum nrf5_features {\n\tNRF5_FEATURE_SERIES_51\t= 1 << 0,\n\tNRF5_FEATURE_SERIES_52\t= 1 << 1,\n\tNRF5_FEATURE_BPROT\t\t= 1 << 2,\n\tNRF5_FEATURE_ACL_PROT\t= 1 << 3,\n};\n\nstruct nrf5_device_spec {\n\tuint16_t hwid;\n\tconst char *part;\n\tconst char *variant;\n\tconst char *build_code;\n\tunsigned int flash_size_kb;\n\tenum nrf5_features features;\n};\n\nstruct nrf5_info {\n\tunsigned int refcount;\n\n\tstruct nrf5_bank {\n\t\tstruct nrf5_info *chip;\n\t\tbool probed;\n\t} bank[2];\n\tstruct target *target;\n\n\t/* chip identification stored in nrf5_probe() for use in nrf5_info() */\n\tbool ficr_info_valid;\n\tstruct nrf52_ficr_info ficr_info;\n\tconst struct nrf5_device_spec *spec;\n\tuint16_t hwid;\n\tenum nrf5_features features;\n\tunsigned int flash_size_kb;\n\tunsigned int ram_size_kb;\n};\n\n#define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \\\n{                                                   \\\n.hwid          = (id),                              \\\n.part          = pt,                                \\\n.variant       = var,                               \\\n.build_code    = bcode,                             \\\n.flash_size_kb = (fsize),                           \\\n.features      = NRF5_FEATURE_SERIES_51,            \\\n}\n\n#define NRF5_DEVICE_DEF(id, pt, var, bcode, fsize, features) \\\n{                                                   \\\n.hwid          = (id),                              \\\n.part          = pt,                                \\\n.variant       = var,                               \\\n.build_code    = bcode,                             \\\n.flash_size_kb = (fsize),                           \\\n.features      = features,                          \\\n}\n\n/* The known devices table below is derived from the \"nRF5x series\n * compatibility matrix\" documents, which can be found in the \"DocLib\" of\n * nordic:\n *\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51422_ic_revision_overview\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51822_ic_revision_overview\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF51/latest/COMP/nrf51/nRF51824_ic_revision_overview\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52810/latest/COMP/nrf52810/nRF52810_ic_revision_overview\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52832/latest/COMP/nrf52832/ic_revision_overview\n * https://www.nordicsemi.com/DocLib/Content/Comp_Matrix/nRF52840/latest/COMP/nrf52840/nRF52840_ic_revision_overview\n *\n * Up to date with Matrix v2.0, plus some additional HWIDs.\n *\n * The additional HWIDs apply where the build code in the matrix is\n * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is\n * for x==0, x!=0 means different (unspecified) HWIDs.\n */\nstatic const struct nrf5_device_spec nrf5_known_devices_table[] = {\n\t/* nRF51822 Devices (IC rev 1). */\n\tNRF51_DEVICE_DEF(0x001D, \"51822\", \"QFAA\", \"CA/C0\", 256),\n\tNRF51_DEVICE_DEF(0x0026, \"51822\", \"QFAB\", \"AA\",    128),\n\tNRF51_DEVICE_DEF(0x0027, \"51822\", \"QFAB\", \"A0\",    128),\n\tNRF51_DEVICE_DEF(0x0020, \"51822\", \"CEAA\", \"BA\",    256),\n\tNRF51_DEVICE_DEF(0x002F, \"51822\", \"CEAA\", \"B0\",    256),\n\n\t/* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards\n\t   with built-in jlink seem to use engineering samples not listed\n\t   in the nRF51 Series Compatibility Matrix V1.0. */\n\tNRF51_DEVICE_DEF(0x0071, \"51822\", \"QFAC\", \"AB\",    256),\n\n\t/* nRF51822 Devices (IC rev 2). */\n\tNRF51_DEVICE_DEF(0x002A, \"51822\", \"QFAA\", \"FA0\",   256),\n\tNRF51_DEVICE_DEF(0x0044, \"51822\", \"QFAA\", \"GC0\",   256),\n\tNRF51_DEVICE_DEF(0x003C, \"51822\", \"QFAA\", \"G0\",    256),\n\tNRF51_DEVICE_DEF(0x0057, \"51822\", \"QFAA\", \"G2\",    256),\n\tNRF51_DEVICE_DEF(0x0058, \"51822\", \"QFAA\", \"G3\",    256),\n\tNRF51_DEVICE_DEF(0x004C, \"51822\", \"QFAB\", \"B0\",    128),\n\tNRF51_DEVICE_DEF(0x0040, \"51822\", \"CEAA\", \"CA0\",   256),\n\tNRF51_DEVICE_DEF(0x0047, \"51822\", \"CEAA\", \"DA0\",   256),\n\tNRF51_DEVICE_DEF(0x004D, \"51822\", \"CEAA\", \"D00\",   256),\n\n\t/* nRF51822 Devices (IC rev 3). */\n\tNRF51_DEVICE_DEF(0x0072, \"51822\", \"QFAA\", \"H0\",    256),\n\tNRF51_DEVICE_DEF(0x00D1, \"51822\", \"QFAA\", \"H2\",    256),\n\tNRF51_DEVICE_DEF(0x007B, \"51822\", \"QFAB\", \"C0\",    128),\n\tNRF51_DEVICE_DEF(0x0083, \"51822\", \"QFAC\", \"A0\",    256),\n\tNRF51_DEVICE_DEF(0x0084, \"51822\", \"QFAC\", \"A1\",    256),\n\tNRF51_DEVICE_DEF(0x007D, \"51822\", \"CDAB\", \"A0\",    128),\n\tNRF51_DEVICE_DEF(0x0079, \"51822\", \"CEAA\", \"E0\",    256),\n\tNRF51_DEVICE_DEF(0x0087, \"51822\", \"CFAC\", \"A0\",    256),\n\tNRF51_DEVICE_DEF(0x008F, \"51822\", \"QFAA\", \"H1\",    256),\n\n\t/* nRF51422 Devices (IC rev 1). */\n\tNRF51_DEVICE_DEF(0x001E, \"51422\", \"QFAA\", \"CA\",    256),\n\tNRF51_DEVICE_DEF(0x0024, \"51422\", \"QFAA\", \"C0\",    256),\n\tNRF51_DEVICE_DEF(0x0031, \"51422\", \"CEAA\", \"A0A\",   256),\n\n\t/* nRF51422 Devices (IC rev 2). */\n\tNRF51_DEVICE_DEF(0x002D, \"51422\", \"QFAA\", \"DAA\",   256),\n\tNRF51_DEVICE_DEF(0x002E, \"51422\", \"QFAA\", \"E0\",    256),\n\tNRF51_DEVICE_DEF(0x0061, \"51422\", \"QFAB\", \"A00\",   128),\n\tNRF51_DEVICE_DEF(0x0050, \"51422\", \"CEAA\", \"B0\",    256),\n\n\t/* nRF51422 Devices (IC rev 3). */\n\tNRF51_DEVICE_DEF(0x0073, \"51422\", \"QFAA\", \"F0\",    256),\n\tNRF51_DEVICE_DEF(0x007C, \"51422\", \"QFAB\", \"B0\",    128),\n\tNRF51_DEVICE_DEF(0x0085, \"51422\", \"QFAC\", \"A0\",    256),\n\tNRF51_DEVICE_DEF(0x0086, \"51422\", \"QFAC\", \"A1\",    256),\n\tNRF51_DEVICE_DEF(0x007E, \"51422\", \"CDAB\", \"A0\",    128),\n\tNRF51_DEVICE_DEF(0x007A, \"51422\", \"CEAA\", \"C0\",    256),\n\tNRF51_DEVICE_DEF(0x0088, \"51422\", \"CFAC\", \"A0\",    256),\n\n\t/* The driver fully autodetects nRF52 series devices by FICR INFO,\n\t * no need for nRF52xxx HWIDs in this table */\n#if 0\n\t/* nRF52810 Devices */\n\tNRF5_DEVICE_DEF(0x0142, \"52810\", \"QFAA\", \"B0\",    192,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT),\n\tNRF5_DEVICE_DEF(0x0143, \"52810\", \"QCAA\", \"C0\",    192,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT),\n\n\t/* nRF52832 Devices */\n\tNRF5_DEVICE_DEF(0x00C7, \"52832\", \"QFAA\", \"B0\",    512,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT),\n\tNRF5_DEVICE_DEF(0x0139, \"52832\", \"QFAA\", \"E0\",    512,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT),\n\tNRF5_DEVICE_DEF(0x00E3, \"52832\", \"CIAA\", \"B0\",    512,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_BPROT),\n\n\t/* nRF52840 Devices */\n\tNRF5_DEVICE_DEF(0x0150, \"52840\", \"QIAA\", \"C0\",    1024,\tNRF5_FEATURE_SERIES_52 | NRF5_FEATURE_ACL_PROT),\n#endif\n};\n\nstruct nrf5_device_package {\n\tuint32_t package;\n\tconst char *code;\n};\n\n/* Newer devices have FICR INFO.PACKAGE.\n * This table converts its value to two character code */\nstatic const struct nrf5_device_package nrf5_packages_table[] = {\n\t{ 0x2000, \"QF\" },\n\t{ 0x2001, \"CH\" },\n\t{ 0x2002, \"CI\" },\n\t{ 0x2005, \"CK\" },\n};\n\nconst struct flash_driver nrf5_flash, nrf51_flash;\n\nstatic bool nrf5_bank_is_probed(const struct flash_bank *bank)\n{\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\n\tassert(nbank);\n\n\treturn nbank->probed;\n}\nstatic int nrf5_probe(struct flash_bank *bank);\n\nstatic int nrf5_get_probed_chip_if_halted(struct flash_bank *bank, struct nrf5_info **chip)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\t*chip = nbank->chip;\n\n\tif (nrf5_bank_is_probed(bank))\n\t\treturn ERROR_OK;\n\n\treturn nrf5_probe(bank);\n}\n\nstatic int nrf5_wait_for_nvmc(struct nrf5_info *chip)\n{\n\tuint32_t ready;\n\tint res;\n\tint timeout_ms = 340;\n\tint64_t ts_start = timeval_ms();\n\n\tdo {\n\t\tres = target_read_u32(chip->target, NRF5_NVMC_READY, &ready);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error waiting NVMC_READY: generic flash write/erase error (check protection etc...)\");\n\t\t\treturn res;\n\t\t}\n\n\t\tif (ready == 0x00000001)\n\t\t\treturn ERROR_OK;\n\n\t\tkeep_alive();\n\n\t} while ((timeval_ms()-ts_start) < timeout_ms);\n\n\tLOG_DEBUG(\"Timed out waiting for NVMC_READY\");\n\treturn ERROR_FLASH_BUSY;\n}\n\nstatic int nrf5_nvmc_erase_enable(struct nrf5_info *chip)\n{\n\tint res;\n\tres = target_write_u32(chip->target,\n\t\t\t       NRF5_NVMC_CONFIG,\n\t\t\t       NRF5_NVMC_CONFIG_EEN);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to enable erase operation\");\n\t\treturn res;\n\t}\n\n\t/*\n\t  According to NVMC examples in Nordic SDK busy status must be\n\t  checked after writing to NVMC_CONFIG\n\t */\n\tres = nrf5_wait_for_nvmc(chip);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Erase enable did not complete\");\n\n\treturn res;\n}\n\nstatic int nrf5_nvmc_write_enable(struct nrf5_info *chip)\n{\n\tint res;\n\tres = target_write_u32(chip->target,\n\t\t\t       NRF5_NVMC_CONFIG,\n\t\t\t       NRF5_NVMC_CONFIG_WEN);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to enable write operation\");\n\t\treturn res;\n\t}\n\n\t/*\n\t  According to NVMC examples in Nordic SDK busy status must be\n\t  checked after writing to NVMC_CONFIG\n\t */\n\tres = nrf5_wait_for_nvmc(chip);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Write enable did not complete\");\n\n\treturn res;\n}\n\nstatic int nrf5_nvmc_read_only(struct nrf5_info *chip)\n{\n\tint res;\n\tres = target_write_u32(chip->target,\n\t\t\t       NRF5_NVMC_CONFIG,\n\t\t\t       NRF5_NVMC_CONFIG_REN);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to enable read-only operation\");\n\t\treturn res;\n\t}\n\t/*\n\t  According to NVMC examples in Nordic SDK busy status must be\n\t  checked after writing to NVMC_CONFIG\n\t */\n\tres = nrf5_wait_for_nvmc(chip);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Read only enable did not complete\");\n\n\treturn res;\n}\n\nstatic int nrf5_nvmc_generic_erase(struct nrf5_info *chip,\n\t\t\t       uint32_t erase_register, uint32_t erase_value)\n{\n\tint res;\n\n\tres = nrf5_nvmc_erase_enable(chip);\n\tif (res != ERROR_OK)\n\t\tgoto error;\n\n\tres = target_write_u32(chip->target,\n\t\t\t       erase_register,\n\t\t\t       erase_value);\n\tif (res != ERROR_OK)\n\t\tgoto set_read_only;\n\n\tres = nrf5_wait_for_nvmc(chip);\n\tif (res != ERROR_OK)\n\t\tgoto set_read_only;\n\n\treturn nrf5_nvmc_read_only(chip);\n\nset_read_only:\n\tnrf5_nvmc_read_only(chip);\nerror:\n\tLOG_ERROR(\"Failed to erase reg: 0x%08\"PRIx32\" val: 0x%08\"PRIx32,\n\t\t  erase_register, erase_value);\n\treturn ERROR_FAIL;\n}\n\nstatic int nrf5_protect_check_clenr0(struct flash_bank *bank)\n{\n\tint res;\n\tuint32_t clenr0;\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\n\tassert(chip);\n\n\tres = target_read_u32(chip->target, NRF51_FICR_CLENR0,\n\t\t\t      &clenr0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read code region 0 size[FICR]\");\n\t\treturn res;\n\t}\n\n\tif (clenr0 == 0xFFFFFFFF) {\n\t\tres = target_read_u32(chip->target, NRF51_UICR_CLENR0,\n\t\t\t\t      &clenr0);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read code region 0 size[UICR]\");\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected =\n\t\t\tclenr0 != 0xFFFFFFFF && bank->sectors[i].offset < clenr0;\n\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_protect_check_bprot(struct flash_bank *bank)\n{\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\n\tassert(chip);\n\n\tstatic uint32_t nrf5_bprot_offsets[4] = { 0x600, 0x604, 0x610, 0x614 };\n\tuint32_t bprot_reg = 0;\n\tint res;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tunsigned int bit = i % 32;\n\t\tif (bit == 0) {\n\t\t\tunsigned int n_reg = i / 32;\n\t\t\tif (n_reg >= ARRAY_SIZE(nrf5_bprot_offsets))\n\t\t\t\tbreak;\n\n\t\t\tres = target_read_u32(chip->target, NRF5_BPROT_BASE + nrf5_bprot_offsets[n_reg], &bprot_reg);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\t\tbank->sectors[i].is_protected = (bprot_reg & (1 << bit)) ? 1 : 0;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_protect_check(struct flash_bank *bank)\n{\n\t/* UICR cannot be write protected so just return early */\n\tif (bank->base == NRF5_UICR_BASE)\n\t\treturn ERROR_OK;\n\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\n\tassert(chip);\n\n\tif (chip->features & NRF5_FEATURE_BPROT)\n\t\treturn nrf5_protect_check_bprot(bank);\n\n\tif (chip->features & NRF5_FEATURE_SERIES_51)\n\t\treturn nrf5_protect_check_clenr0(bank);\n\n\tLOG_WARNING(\"Flash protection of this nRF device is not supported\");\n\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n}\n\nstatic int nrf5_protect_clenr0(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res;\n\tuint32_t clenr0, ppfc;\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\n\tif (first != 0) {\n\t\tLOG_ERROR(\"Code region 0 must start at the beginning of the bank\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = target_read_u32(chip->target, NRF51_FICR_PPFC,\n\t\t\t      &ppfc);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read PPFC register\");\n\t\treturn res;\n\t}\n\n\tif ((ppfc & 0xFF) == 0x00) {\n\t\tLOG_ERROR(\"Code region 0 size was pre-programmed at the factory, can't change flash protection settings\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = target_read_u32(chip->target, NRF51_UICR_CLENR0,\n\t\t\t      &clenr0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read code region 0 size from UICR\");\n\t\treturn res;\n\t}\n\n\tif (!set || clenr0 != 0xFFFFFFFF) {\n\t\tLOG_ERROR(\"You need to perform chip erase before changing the protection settings\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = nrf5_nvmc_write_enable(chip);\n\tif (res != ERROR_OK)\n\t\tgoto error;\n\n\tclenr0 = bank->sectors[last].offset + bank->sectors[last].size;\n\tres = target_write_u32(chip->target, NRF51_UICR_CLENR0, clenr0);\n\n\tint res2 = nrf5_wait_for_nvmc(chip);\n\n\tif (res == ERROR_OK)\n\t\tres = res2;\n\n\tif (res == ERROR_OK)\n\t\tLOG_INFO(\"A reset or power cycle is required for the new protection settings to take effect.\");\n\telse\n\t\tLOG_ERROR(\"Couldn't write code region 0 size to UICR\");\n\nerror:\n\tnrf5_nvmc_read_only(chip);\n\n\treturn res;\n}\n\nstatic int nrf5_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res;\n\tstruct nrf5_info *chip;\n\n\t/* UICR cannot be write protected so just bail out early */\n\tif (bank->base == NRF5_UICR_BASE) {\n\t\tLOG_ERROR(\"UICR page does not support protection\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tres = nrf5_get_probed_chip_if_halted(bank, &chip);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (chip->features & NRF5_FEATURE_SERIES_51)\n\t\treturn nrf5_protect_clenr0(bank, set, first, last);\n\n\tLOG_ERROR(\"Flash protection setting is not supported on this nRF5 device\");\n\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n}\n\nstatic bool nrf5_info_variant_to_str(uint32_t variant, char *bf)\n{\n\tuint8_t b[4];\n\n\th_u32_to_be(b, variant);\n\tif (isalnum(b[0]) && isalnum(b[1]) && isalnum(b[2]) && isalnum(b[3])) {\n\t\tmemcpy(bf, b, 4);\n\t\tbf[4] = 0;\n\t\treturn true;\n\t}\n\n\tstrcpy(bf, \"xxxx\");\n\treturn false;\n}\n\nstatic const char *nrf5_decode_info_package(uint32_t package)\n{\n\tfor (size_t i = 0; i < ARRAY_SIZE(nrf5_packages_table); i++) {\n\t\tif (nrf5_packages_table[i].package == package)\n\t\t\treturn nrf5_packages_table[i].code;\n\t}\n\treturn \"xx\";\n}\n\nstatic int get_nrf5_chip_type_str(const struct nrf5_info *chip, char *buf, unsigned int buf_size)\n{\n\tint res;\n\tif (chip->spec) {\n\t\tres = snprintf(buf, buf_size, \"nRF%s-%s(build code: %s)\",\n\t\t\t\tchip->spec->part, chip->spec->variant, chip->spec->build_code);\n\t} else if (chip->ficr_info_valid) {\n\t\tchar variant[5];\n\t\tnrf5_info_variant_to_str(chip->ficr_info.variant, variant);\n\t\tres = snprintf(buf, buf_size, \"nRF%\" PRIx32 \"-%s%.2s(build code: %s)\",\n\t\t\t\tchip->ficr_info.part,\n\t\t\t\tnrf5_decode_info_package(chip->ficr_info.package),\n\t\t\t\tvariant, &variant[2]);\n\t} else {\n\t\tres = snprintf(buf, buf_size, \"nRF51xxx (HWID 0x%04\" PRIx16 \")\", chip->hwid);\n\t}\n\n\t/* safety: */\n\tif (res <= 0 || (unsigned int)res >= buf_size) {\n\t\tLOG_ERROR(\"BUG: buffer problem in %s\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\n\tchar chip_type_str[256];\n\tif (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tcommand_print_sameline(cmd, \"%s %ukB Flash, %ukB RAM\",\n\t\t\tchip_type_str, chip->flash_size_kb, chip->ram_size_kb);\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_read_ficr_info(struct nrf5_info *chip)\n{\n\tint res;\n\tstruct target *target = chip->target;\n\n\tchip->ficr_info_valid = false;\n\n\tres = target_read_u32(target, NRF5_FICR_INFO_PART, &chip->ficr_info.part);\n\tif (res != ERROR_OK) {\n\t\tLOG_DEBUG(\"Couldn't read FICR INFO.PART register\");\n\t\treturn res;\n\t}\n\n\tuint32_t series = chip->ficr_info.part & 0xfffff000;\n\tswitch (series) {\n\tcase 0x51000:\n\t\tchip->features = NRF5_FEATURE_SERIES_51;\n\t\tbreak;\n\n\tcase 0x52000:\n\t\tchip->features = NRF5_FEATURE_SERIES_52;\n\n\t\tswitch (chip->ficr_info.part) {\n\t\tcase 0x52810:\n\t\tcase 0x52832:\n\t\t\tchip->features |= NRF5_FEATURE_BPROT;\n\t\t\tbreak;\n\n\t\tcase 0x52840:\n\t\t\tchip->features |= NRF5_FEATURE_ACL_PROT;\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_DEBUG(\"FICR INFO likely not implemented. Invalid PART value 0x%08\"\n\t\t\t\tPRIx32, chip->ficr_info.part);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Now we know the device has FICR INFO filled by something relevant:\n\t * Although it is not documented, the tested nRF51 rev 3 devices\n\t * have FICR INFO.PART, RAM and FLASH of the same format as nRF52.\n\t * VARIANT and PACKAGE coding is unknown for a nRF51 device.\n\t * nRF52 devices have FICR INFO documented and always filled. */\n\n\tres = target_read_u32(target, NRF5_FICR_INFO_VARIANT, &chip->ficr_info.variant);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = target_read_u32(target, NRF5_FICR_INFO_PACKAGE, &chip->ficr_info.package);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = target_read_u32(target, NRF5_FICR_INFO_RAM, &chip->ficr_info.ram);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = target_read_u32(target, NRF5_FICR_INFO_FLASH, &chip->ficr_info.flash);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tchip->ficr_info_valid = true;\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_get_ram_size(struct target *target, uint32_t *ram_size)\n{\n\tint res;\n\n\t*ram_size = 0;\n\n\tuint32_t numramblock;\n\tres = target_read_u32(target, NRF51_FICR_NUMRAMBLOCK, &numramblock);\n\tif (res != ERROR_OK) {\n\t\tLOG_DEBUG(\"Couldn't read FICR NUMRAMBLOCK register\");\n\t\treturn res;\n\t}\n\n\tif (numramblock < 1 || numramblock > 4) {\n\t\tLOG_DEBUG(\"FICR NUMRAMBLOCK strange value %\" PRIx32, numramblock);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tfor (unsigned int i = 0; i < numramblock; i++) {\n\t\tuint32_t sizeramblock;\n\t\tres = target_read_u32(target, NRF51_FICR_SIZERAMBLOCK0 + sizeof(uint32_t)*i, &sizeramblock);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Couldn't read FICR NUMRAMBLOCK register\");\n\t\t\treturn res;\n\t\t}\n\t\tif (sizeramblock < 1024 || sizeramblock > 65536)\n\t\t\tLOG_DEBUG(\"FICR SIZERAMBLOCK strange value %\" PRIx32, sizeramblock);\n\t\telse\n\t\t\t*ram_size += sizeramblock;\n\t}\n\treturn res;\n}\n\nstatic int nrf5_probe(struct flash_bank *bank)\n{\n\tint res;\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\tstruct target *target = chip->target;\n\n\tuint32_t configid;\n\tres = target_read_u32(target, NRF5_FICR_CONFIGID, &configid);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read CONFIGID register\");\n\t\treturn res;\n\t}\n\n\t/* HWID is stored in the lower two bytes of the CONFIGID register */\n\tchip->hwid = configid & 0xFFFF;\n\n\t/* guess a nRF51 series if the device has no FICR INFO and we don't know HWID */\n\tchip->features = NRF5_FEATURE_SERIES_51;\n\n\t/* Don't bail out on error for the case that some old engineering\n\t * sample has FICR INFO registers unreadable. We can proceed anyway. */\n\t(void)nrf5_read_ficr_info(chip);\n\n\tchip->spec = NULL;\n\tfor (size_t i = 0; i < ARRAY_SIZE(nrf5_known_devices_table); i++) {\n\t\tif (chip->hwid == nrf5_known_devices_table[i].hwid) {\n\t\t\tchip->spec = &nrf5_known_devices_table[i];\n\t\t\tchip->features = chip->spec->features;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (chip->spec && chip->ficr_info_valid) {\n\t\t/* check if HWID table gives the same part as FICR INFO */\n\t\tif (chip->ficr_info.part != strtoul(chip->spec->part, NULL, 16))\n\t\t\tLOG_WARNING(\"HWID 0x%04\" PRIx32 \" mismatch: FICR INFO.PART %\"\n\t\t\t\t\t\tPRIx32, chip->hwid, chip->ficr_info.part);\n\t}\n\n\tif (chip->ficr_info_valid) {\n\t\tchip->ram_size_kb = chip->ficr_info.ram;\n\t} else {\n\t\tuint32_t ram_size;\n\t\tnrf5_get_ram_size(target, &ram_size);\n\t\tchip->ram_size_kb = ram_size / 1024;\n\t}\n\n\t/* The value stored in NRF5_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */\n\tuint32_t flash_page_size;\n\tres = target_read_u32(chip->target, NRF5_FICR_CODEPAGESIZE,\n\t\t\t\t&flash_page_size);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read code page size\");\n\t\treturn res;\n\t}\n\n\t/* Note the register name is misleading,\n\t * NRF5_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */\n\tuint32_t num_sectors;\n\tres = target_read_u32(chip->target, NRF5_FICR_CODESIZE, &num_sectors);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't read code memory size\");\n\t\treturn res;\n\t}\n\n\tchip->flash_size_kb = num_sectors * flash_page_size / 1024;\n\n\tif (!chip->bank[0].probed && !chip->bank[1].probed) {\n\t\tchar chip_type_str[256];\n\t\tif (get_nrf5_chip_type_str(chip, chip_type_str, sizeof(chip_type_str)) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tconst bool device_is_unknown = (!chip->spec && !chip->ficr_info_valid);\n\t\tLOG_INFO(\"%s%s %ukB Flash, %ukB RAM\",\n\t\t\t\tdevice_is_unknown ? \"Unknown device: \" : \"\",\n\t\t\t\tchip_type_str,\n\t\t\t\tchip->flash_size_kb,\n\t\t\t\tchip->ram_size_kb);\n\t}\n\n\tfree(bank->sectors);\n\n\tif (bank->base == NRF5_FLASH_BASE) {\n\t\t/* Sanity check */\n\t\tif (chip->spec && chip->flash_size_kb != chip->spec->flash_size_kb)\n\t\t\tLOG_WARNING(\"Chip's reported Flash capacity does not match expected one\");\n\t\tif (chip->ficr_info_valid && chip->flash_size_kb != chip->ficr_info.flash)\n\t\t\tLOG_WARNING(\"Chip's reported Flash capacity does not match FICR INFO.FLASH\");\n\n\t\tbank->num_sectors = num_sectors;\n\t\tbank->size = num_sectors * flash_page_size;\n\n\t\tbank->sectors = alloc_block_array(0, flash_page_size, num_sectors);\n\t\tif (!bank->sectors)\n\t\t\treturn ERROR_FAIL;\n\n\t\tchip->bank[0].probed = true;\n\n\t} else {\n\t\tbank->num_sectors = 1;\n\t\tbank->size = flash_page_size;\n\n\t\tbank->sectors = alloc_block_array(0, flash_page_size, num_sectors);\n\t\tif (!bank->sectors)\n\t\t\treturn ERROR_FAIL;\n\n\t\tbank->sectors[0].is_protected = 0;\n\n\t\tchip->bank[1].probed = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int nrf5_auto_probe(struct flash_bank *bank)\n{\n\tif (nrf5_bank_is_probed(bank))\n\t\treturn ERROR_OK;\n\n\treturn nrf5_probe(bank);\n}\n\nstatic int nrf5_erase_all(struct nrf5_info *chip)\n{\n\tLOG_DEBUG(\"Erasing all non-volatile memory\");\n\treturn nrf5_nvmc_generic_erase(chip,\n\t\t\t\t\tNRF5_NVMC_ERASEALL,\n\t\t\t\t\t0x00000001);\n}\n\nstatic int nrf5_erase_page(struct flash_bank *bank,\n\t\t\t\t\t\t\tstruct nrf5_info *chip,\n\t\t\t\t\t\t\tstruct flash_sector *sector)\n{\n\tint res;\n\n\tLOG_DEBUG(\"Erasing page at 0x%\"PRIx32, sector->offset);\n\n\tif (bank->base == NRF5_UICR_BASE) {\n\t\tif (chip->features & NRF5_FEATURE_SERIES_51) {\n\t\t\tuint32_t ppfc;\n\t\t\tres = target_read_u32(chip->target, NRF51_FICR_PPFC,\n\t\t\t\t      &ppfc);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Couldn't read PPFC register\");\n\t\t\t\treturn res;\n\t\t\t}\n\n\t\t\tif ((ppfc & 0xFF) == 0xFF) {\n\t\t\t\t/* We can't erase the UICR.  Double-check to\n\t\t\t\t   see if it's already erased before complaining. */\n\t\t\t\tdefault_flash_blank_check(bank);\n\t\t\t\tif (sector->is_erased == 1)\n\t\t\t\t\treturn ERROR_OK;\n\n\t\t\t\tLOG_ERROR(\"The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tres = nrf5_nvmc_generic_erase(chip,\n\t\t\t\t\t       NRF5_NVMC_ERASEUICR,\n\t\t\t\t\t       0x00000001);\n\n\n\t} else {\n\t\tres = nrf5_nvmc_generic_erase(chip,\n\t\t\t\t\t       NRF5_NVMC_ERASEPAGE,\n\t\t\t\t\t       sector->offset);\n\t}\n\n\treturn res;\n}\n\n/* Start a low level flash write for the specified region */\nstatic int nrf5_ll_flash_write(struct nrf5_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes)\n{\n\tstruct target *target = chip->target;\n\tuint32_t buffer_size = 8192;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\tstatic const uint8_t nrf5_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/nrf5/nrf5.inc\"\n\t};\n\n\tLOG_DEBUG(\"Writing buffer to flash address=0x%\"PRIx32\" bytes=0x%\"PRIx32, address, bytes);\n\tassert(bytes % 4 == 0);\n\n\t/* allocate working area with flash programming code */\n\tif (target_alloc_working_area(target, sizeof(nrf5_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, falling back to slow memory writes\");\n\n\t\tfor (; bytes > 0; bytes -= 4) {\n\t\t\tretval = target_write_memory(target, address, 4, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = nrf5_wait_for_nvmc(chip);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\taddress += 4;\n\t\t\tbuffer += 4;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\t\tsizeof(nrf5_flash_write_code),\n\t\t\t\tnrf5_flash_write_code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tbuffer_size &= ~3UL; /* Make sure it's 4 byte aligned */\n\t\tif (buffer_size <= 256) {\n\t\t\t/* free working area, write algorithm already allocated */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"No large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* byte count */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_IN_OUT);\t/* target address */\n\tinit_reg_param(&reg_params[4], \"r6\", 32, PARAM_OUT);\t/* watchdog refresh value */\n\tinit_reg_param(&reg_params[5], \"r7\", 32, PARAM_OUT);\t/* watchdog refresh register address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, bytes);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[3].value, 0, 32, address);\n\tbuf_set_u32(reg_params[4].value, 0, 32, WATCHDOG_REFRESH_VALUE);\n\tbuf_set_u32(reg_params[5].value, 0, 32, WATCHDOG_REFRESH_REGISTER);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, bytes/4, 4,\n\t\t\t0, NULL,\n\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, write_algorithm->address + sizeof(nrf5_flash_write_code) - 2,\n\t\t\t&armv7m_info);\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\n\treturn retval;\n}\n\nstatic int nrf5_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t\t\tuint32_t offset, uint32_t count)\n{\n\tstruct nrf5_info *chip;\n\n\tint res = nrf5_get_probed_chip_if_halted(bank, &chip);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tassert(offset % 4 == 0);\n\tassert(count % 4 == 0);\n\n\t/* UICR CLENR0 based protection used on nRF51 is somewhat clumsy:\n\t * RM reads: Code running from code region 1 will not be able to write\n\t * to code region 0.\n\t * Unfortunately the flash loader running from RAM can write to both\n\t * code regions without any hint the protection is violated.\n\t *\n\t * Update protection state and check if any flash sector to be written\n\t * is protected. */\n\tif (chip->features & NRF5_FEATURE_SERIES_51) {\n\n\t\tres = nrf5_protect_check_clenr0(bank);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t\tstruct flash_sector *bs = &bank->sectors[sector];\n\n\t\t\t/* Start offset in or before this sector? */\n\t\t\t/* End offset in or behind this sector? */\n\t\t\tif ((offset < (bs->offset + bs->size))\n\t\t\t\t\t&& ((offset + count - 1) >= bs->offset)\n\t\t\t\t\t&& bs->is_protected == 1) {\n\t\t\t\tLOG_ERROR(\"Write refused, sector %d is protected\", sector);\n\t\t\t\treturn ERROR_FLASH_PROTECTED;\n\t\t\t}\n\t\t}\n\t}\n\n\tres = nrf5_nvmc_write_enable(chip);\n\tif (res != ERROR_OK)\n\t\tgoto error;\n\n\tres = nrf5_ll_flash_write(chip, bank->base + offset, buffer, count);\n\tif (res != ERROR_OK)\n\t\tgoto error;\n\n\treturn nrf5_nvmc_read_only(chip);\n\nerror:\n\tnrf5_nvmc_read_only(chip);\n\tLOG_ERROR(\"Failed to write to nrf5 flash\");\n\treturn res;\n}\n\nstatic int nrf5_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint res;\n\tstruct nrf5_info *chip;\n\n\tres = nrf5_get_probed_chip_if_halted(bank, &chip);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* UICR CLENR0 based protection used on nRF51 prevents erase\n\t * absolutely silently. NVMC has no flag to indicate the protection\n\t * was violated.\n\t *\n\t * Update protection state and check if any flash sector to be erased\n\t * is protected. */\n\tif (chip->features & NRF5_FEATURE_SERIES_51) {\n\n\t\tres = nrf5_protect_check_clenr0(bank);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\t/* For each sector to be erased */\n\tfor (unsigned int s = first; s <= last && res == ERROR_OK; s++) {\n\n\t\tif (chip->features & NRF5_FEATURE_SERIES_51\n\t\t\t\t&& bank->sectors[s].is_protected == 1) {\n\t\t\tLOG_ERROR(\"Flash sector %d is protected\", s);\n\t\t\treturn ERROR_FLASH_PROTECTED;\n\t\t}\n\n\t\tres = nrf5_erase_page(bank, chip, &bank->sectors[s]);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error erasing sector %d\", s);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void nrf5_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct nrf5_bank *nbank = bank->driver_priv;\n\tstruct nrf5_info *chip = nbank->chip;\n\tif (!chip)\n\t\treturn;\n\n\tchip->refcount--;\n\tif (chip->refcount == 0) {\n\t\tfree(chip);\n\t\tbank->driver_priv = NULL;\n\t}\n}\n\nstatic struct nrf5_info *nrf5_get_chip(struct target *target)\n{\n\tstruct flash_bank *bank_iter;\n\n\t/* iterate over nrf5 banks of same target */\n\tfor (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {\n\t\tif (bank_iter->driver != &nrf5_flash && bank_iter->driver != &nrf51_flash)\n\t\t\tcontinue;\n\n\t\tif (bank_iter->target != target)\n\t\t\tcontinue;\n\n\t\tstruct nrf5_bank *nbank = bank_iter->driver_priv;\n\t\tif (!nbank)\n\t\t\tcontinue;\n\n\t\tif (nbank->chip)\n\t\t\treturn nbank->chip;\n\t}\n\treturn NULL;\n}\n\nFLASH_BANK_COMMAND_HANDLER(nrf5_flash_bank_command)\n{\n\tstruct nrf5_info *chip;\n\tstruct nrf5_bank *nbank = NULL;\n\n\tswitch (bank->base) {\n\tcase NRF5_FLASH_BASE:\n\tcase NRF5_UICR_BASE:\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Invalid bank address \" TARGET_ADDR_FMT, bank->base);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchip = nrf5_get_chip(bank->target);\n\tif (!chip) {\n\t\t/* Create a new chip */\n\t\tchip = calloc(1, sizeof(*chip));\n\t\tif (!chip)\n\t\t\treturn ERROR_FAIL;\n\n\t\tchip->target = bank->target;\n\t}\n\n\tswitch (bank->base) {\n\tcase NRF5_FLASH_BASE:\n\t\tnbank = &chip->bank[0];\n\t\tbreak;\n\tcase NRF5_UICR_BASE:\n\t\tnbank = &chip->bank[1];\n\t\tbreak;\n\t}\n\tassert(nbank);\n\n\tchip->refcount++;\n\tnbank->chip = chip;\n\tnbank->probed = false;\n\tbank->driver_priv = nbank;\n\tbank->write_start_alignment = bank->write_end_alignment = 4;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(nrf5_handle_mass_erase_command)\n{\n\tint res;\n\tstruct flash_bank *bank = NULL;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tres = get_flash_bank_by_addr(target, NRF5_FLASH_BASE, true, &bank);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tassert(bank);\n\n\tstruct nrf5_info *chip;\n\n\tres = nrf5_get_probed_chip_if_halted(bank, &chip);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (chip->features & NRF5_FEATURE_SERIES_51) {\n\t\tuint32_t ppfc;\n\t\tres = target_read_u32(target, NRF51_FICR_PPFC,\n\t\t\t      &ppfc);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read PPFC register\");\n\t\t\treturn res;\n\t\t}\n\n\t\tif ((ppfc & 0xFF) == 0x00) {\n\t\t\tLOG_ERROR(\"Code region 0 size was pre-programmed at the factory, \"\n\t\t\t\t  \"mass erase command won't work.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tres = nrf5_erase_all(chip);\n\tif (res == ERROR_OK) {\n\t\tLOG_INFO(\"Mass erase completed.\");\n\t\tif (chip->features & NRF5_FEATURE_SERIES_51)\n\t\t\tLOG_INFO(\"A reset or power cycle is required if the flash was protected before.\");\n\n\t} else {\n\t\tLOG_ERROR(\"Failed to erase the chip\");\n\t}\n\n\treturn res;\n}\n\nCOMMAND_HANDLER(nrf5_handle_info_command)\n{\n\tint res;\n\tstruct flash_bank *bank = NULL;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tres = get_flash_bank_by_addr(target, NRF5_FLASH_BASE, true, &bank);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tassert(bank);\n\n\tstruct nrf5_info *chip;\n\n\tres = nrf5_get_probed_chip_if_halted(bank, &chip);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tstatic struct {\n\t\tconst uint32_t address;\n\t\tuint32_t value;\n\t} ficr[] = {\n\t\t{ .address = NRF5_FICR_CODEPAGESIZE\t},\n\t\t{ .address = NRF5_FICR_CODESIZE\t},\n\t\t{ .address = NRF51_FICR_CLENR0\t\t},\n\t\t{ .address = NRF51_FICR_PPFC\t\t},\n\t\t{ .address = NRF51_FICR_NUMRAMBLOCK\t},\n\t\t{ .address = NRF51_FICR_SIZERAMBLOCK0\t},\n\t\t{ .address = NRF51_FICR_SIZERAMBLOCK1\t},\n\t\t{ .address = NRF51_FICR_SIZERAMBLOCK2\t},\n\t\t{ .address = NRF51_FICR_SIZERAMBLOCK3\t},\n\t\t{ .address = NRF5_FICR_CONFIGID\t},\n\t\t{ .address = NRF5_FICR_DEVICEID0\t},\n\t\t{ .address = NRF5_FICR_DEVICEID1\t},\n\t\t{ .address = NRF5_FICR_ER0\t\t},\n\t\t{ .address = NRF5_FICR_ER1\t\t},\n\t\t{ .address = NRF5_FICR_ER2\t\t},\n\t\t{ .address = NRF5_FICR_ER3\t\t},\n\t\t{ .address = NRF5_FICR_IR0\t\t},\n\t\t{ .address = NRF5_FICR_IR1\t\t},\n\t\t{ .address = NRF5_FICR_IR2\t\t},\n\t\t{ .address = NRF5_FICR_IR3\t\t},\n\t\t{ .address = NRF5_FICR_DEVICEADDRTYPE\t},\n\t\t{ .address = NRF5_FICR_DEVICEADDR0\t},\n\t\t{ .address = NRF5_FICR_DEVICEADDR1\t},\n\t\t{ .address = NRF51_FICR_OVERRIDEN\t},\n\t\t{ .address = NRF51_FICR_NRF_1MBIT0\t},\n\t\t{ .address = NRF51_FICR_NRF_1MBIT1\t},\n\t\t{ .address = NRF51_FICR_NRF_1MBIT2\t},\n\t\t{ .address = NRF51_FICR_NRF_1MBIT3\t},\n\t\t{ .address = NRF51_FICR_NRF_1MBIT4\t},\n\t\t{ .address = NRF51_FICR_BLE_1MBIT0\t},\n\t\t{ .address = NRF51_FICR_BLE_1MBIT1\t},\n\t\t{ .address = NRF51_FICR_BLE_1MBIT2\t},\n\t\t{ .address = NRF51_FICR_BLE_1MBIT3\t},\n\t\t{ .address = NRF51_FICR_BLE_1MBIT4\t},\n\t}, uicr[] = {\n\t\t{ .address = NRF51_UICR_CLENR0,\t\t},\n\t\t{ .address = NRF51_UICR_RBPCONF\t\t},\n\t\t{ .address = NRF51_UICR_XTALFREQ\t},\n\t\t{ .address = NRF51_UICR_FWID\t\t},\n\t};\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(ficr); i++) {\n\t\tres = target_read_u32(chip->target, ficr[i].address,\n\t\t\t\t      &ficr[i].value);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read %\" PRIx32, ficr[i].address);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(uicr); i++) {\n\t\tres = target_read_u32(chip->target, uicr[i].address,\n\t\t\t\t      &uicr[i].value);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read %\" PRIx32, uicr[i].address);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tcommand_print(CMD,\n\t\t \"\\n[factory information control block]\\n\\n\"\n\t\t \"code page size: %\"PRIu32\"B\\n\"\n\t\t \"code memory size: %\"PRIu32\"kB\\n\"\n\t\t \"code region 0 size: %\"PRIu32\"kB\\n\"\n\t\t \"pre-programmed code: %s\\n\"\n\t\t \"number of ram blocks: %\"PRIu32\"\\n\"\n\t\t \"ram block 0 size: %\"PRIu32\"B\\n\"\n\t\t \"ram block 1 size: %\"PRIu32\"B\\n\"\n\t\t \"ram block 2 size: %\"PRIu32\"B\\n\"\n\t\t \"ram block 3 size: %\"PRIu32 \"B\\n\"\n\t\t \"config id: %\" PRIx32 \"\\n\"\n\t\t \"device id: 0x%\"PRIx32\"%08\"PRIx32\"\\n\"\n\t\t \"encryption root: 0x%08\"PRIx32\"%08\"PRIx32\"%08\"PRIx32\"%08\"PRIx32\"\\n\"\n\t\t \"identity root: 0x%08\"PRIx32\"%08\"PRIx32\"%08\"PRIx32\"%08\"PRIx32\"\\n\"\n\t\t \"device address type: 0x%\"PRIx32\"\\n\"\n\t\t \"device address: 0x%\"PRIx32\"%08\"PRIx32\"\\n\"\n\t\t \"override enable: %\"PRIx32\"\\n\"\n\t\t \"NRF_1MBIT values: %\"PRIx32\" %\"PRIx32\" %\"PRIx32\" %\"PRIx32\" %\"PRIx32\"\\n\"\n\t\t \"BLE_1MBIT values: %\"PRIx32\" %\"PRIx32\" %\"PRIx32\" %\"PRIx32\" %\"PRIx32\"\\n\"\n\t\t \"\\n[user information control block]\\n\\n\"\n\t\t \"code region 0 size: %\"PRIu32\"kB\\n\"\n\t\t \"read back protection configuration: %\"PRIx32\"\\n\"\n\t\t \"reset value for XTALFREQ: %\"PRIx32\"\\n\"\n\t\t \"firmware id: 0x%04\"PRIx32,\n\t\t ficr[0].value,\n\t\t (ficr[1].value * ficr[0].value) / 1024,\n\t\t (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024,\n\t\t ((ficr[3].value & 0xFF) == 0x00) ? \"present\" : \"not present\",\n\t\t ficr[4].value,\n\t\t ficr[5].value,\n\t\t (ficr[6].value == 0xFFFFFFFF) ? 0 : ficr[6].value,\n\t\t (ficr[7].value == 0xFFFFFFFF) ? 0 : ficr[7].value,\n\t\t (ficr[8].value == 0xFFFFFFFF) ? 0 : ficr[8].value,\n\t\t ficr[9].value,\n\t\t ficr[10].value, ficr[11].value,\n\t\t ficr[12].value, ficr[13].value, ficr[14].value, ficr[15].value,\n\t\t ficr[16].value, ficr[17].value, ficr[18].value, ficr[19].value,\n\t\t ficr[20].value,\n\t\t ficr[21].value, ficr[22].value,\n\t\t ficr[23].value,\n\t\t ficr[24].value, ficr[25].value, ficr[26].value, ficr[27].value, ficr[28].value,\n\t\t ficr[29].value, ficr[30].value, ficr[31].value, ficr[32].value, ficr[33].value,\n\t\t (uicr[0].value == 0xFFFFFFFF) ? 0 : uicr[0].value / 1024,\n\t\t uicr[1].value & 0xFFFF,\n\t\t uicr[2].value & 0xFF,\n\t\t uicr[3].value & 0xFFFF);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration nrf5_exec_command_handlers[] = {\n\t{\n\t\t.name\t\t= \"mass_erase\",\n\t\t.handler\t= nrf5_handle_mass_erase_command,\n\t\t.mode\t\t= COMMAND_EXEC,\n\t\t.help\t\t= \"Erase all flash contents of the chip.\",\n\t\t.usage\t\t= \"\",\n\t},\n\t{\n\t\t.name\t\t= \"info\",\n\t\t.handler\t= nrf5_handle_info_command,\n\t\t.mode\t\t= COMMAND_EXEC,\n\t\t.help\t\t= \"Show FICR and UICR info.\",\n\t\t.usage\t\t= \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration nrf5_command_handlers[] = {\n\t{\n\t\t.name\t= \"nrf5\",\n\t\t.mode\t= COMMAND_ANY,\n\t\t.help\t= \"nrf5 flash command group\",\n\t\t.usage\t= \"\",\n\t\t.chain\t= nrf5_exec_command_handlers,\n\t},\n\t{\n\t\t.name\t= \"nrf51\",\n\t\t.mode\t= COMMAND_ANY,\n\t\t.help\t= \"nrf51 flash command group\",\n\t\t.usage\t= \"\",\n\t\t.chain\t= nrf5_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver nrf5_flash = {\n\t.name\t\t\t= \"nrf5\",\n\t.commands\t\t= nrf5_command_handlers,\n\t.flash_bank_command\t= nrf5_flash_bank_command,\n\t.info\t\t\t= nrf5_info,\n\t.erase\t\t\t= nrf5_erase,\n\t.protect\t\t= nrf5_protect,\n\t.write\t\t\t= nrf5_write,\n\t.read\t\t\t= default_flash_read,\n\t.probe\t\t\t= nrf5_probe,\n\t.auto_probe\t\t= nrf5_auto_probe,\n\t.erase_check\t\t= default_flash_blank_check,\n\t.protect_check\t\t= nrf5_protect_check,\n\t.free_driver_priv\t= nrf5_free_driver_priv,\n};\n\n/* We need to retain the flash-driver name as well as the commands\n * for backwards compatibility */\nconst struct flash_driver nrf51_flash = {\n\t.name\t\t\t= \"nrf51\",\n\t.commands\t\t= nrf5_command_handlers,\n\t.flash_bank_command\t= nrf5_flash_bank_command,\n\t.info\t\t\t= nrf5_info,\n\t.erase\t\t\t= nrf5_erase,\n\t.protect\t\t= nrf5_protect,\n\t.write\t\t\t= nrf5_write,\n\t.read\t\t\t= default_flash_read,\n\t.probe\t\t\t= nrf5_probe,\n\t.auto_probe\t\t= nrf5_auto_probe,\n\t.erase_check\t\t= default_flash_blank_check,\n\t.protect_check\t\t= nrf5_protect_check,\n\t.free_driver_priv\t= nrf5_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/numicro.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by James K. Larson                                 *\n *   jlarson@pacifier.com                                                  *\n *                                                                         *\n *   Copyright (C) 2013 Cosmin Gorgovan                                    *\n *   cosmin [at] linux-geek [dot] org                                      *\n *                                                                         *\n *   Copyright (C) 2014 Pawel Si                                           *\n *   stawel+openocd@gmail.com                                              *\n *                                                                         *\n *   Copyright (C) 2015 Nemui Trinomius                                    *\n *   nemuisan_kawausogasuki@live.jp                                        *\n *                                                                         *\n *   Copyright (C) 2017 Zale Yu                                            *\n *   CYYU@nuvoton.com                                                      *\n *                                                                         *\n *   Copyright (C) 2022 Jian-Hong Pan                                      *\n *   chienhung.pan@gmail.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n/* Nuvoton NuMicro register locations */\n#define NUMICRO_SYS_BASE        0x50000000\n#define NUMICRO_SYS_WRPROT      0x50000100\n#define NUMICRO_SYS_IPRSTC1     0x50000008\n\n#define NUMICRO_SYSCLK_BASE     0x50000200\n#define NUMICRO_SYSCLK_PWRCON   0x50000200\n#define NUMICRO_SYSCLK_CLKSEL0  0x50000210\n#define NUMICRO_SYSCLK_CLKDIV   0x50000218\n#define NUMICRO_SYSCLK_AHBCLK   0x50000204\n\n#define NUMICRO_FLASH_BASE      0x5000C000\n#define NUMICRO_FLASH_ISPCON    0x5000C000\n#define NUMICRO_FLASH_ISPADR    0x5000C004\n#define NUMICRO_FLASH_ISPDAT    0x5000C008\n#define NUMICRO_FLASH_ISPCMD    0x5000C00C\n#define NUMICRO_FLASH_ISPTRG    0x5000C010\n#define NUMICRO_FLASH_CHEAT\t  0x5000C01C\t/* Undocumented isp register(may be cheat register) */\n\n#define NUMICRO_SCS_BASE        0xE000E000\n#define NUMICRO_SCS_AIRCR       0xE000ED0C\n#define NUMICRO_SCS_DHCSR       0xE000EDF0\n#define NUMICRO_SCS_DEMCR       0xE000EDFC\n\n#define NUMICRO_APROM_BASE      0x00000000\n#define NUMICRO_DATA_BASE       0x0001F000\n#define NUMICRO_LDROM_BASE      0x00100000\n#define NUMICRO_CONFIG_BASE     0x00300000\n\n#define NUMICRO_CONFIG0         0x5000C000\n#define NUMICRO_CONFIG1         0x5000C004\n\n/* Command register bits */\n#define PWRCON_OSC22M         (1 << 2)\n#define PWRCON_XTL12M         (1 << 0)\n\n#define IPRSTC1_CPU_RST       (1 << 1)\n#define IPRSTC1_CHIP_RST      (1 << 0)\n\n#define AHBCLK_ISP_EN         (1 << 2)\n#define AHBCLK_SRAM_EN        (1 << 4)\n#define AHBCLK_TICK_EN        (1 << 5)\n\n#define ISPCON_ISPEN          (1 << 0)\n#define ISPCON_BS_AP          (0 << 1)\n#define ISPCON_BS_LP          (1 << 1)\n#define ISPCON_BS_MASK        (1 << 1)\n#define ISPCON_APUEN          (1 << 3)\n#define ISPCON_CFGUEN         (1 << 4)\n#define ISPCON_LDUEN          (1 << 5)\n#define ISPCON_ISPFF          (1 << 6)\n\n#define CONFIG0_LOCK_MASK\t  (1 << 1)\n\n/* isp commands */\n#define ISPCMD_READ           0x00\n#define ISPCMD_WRITE          0x21\n#define ISPCMD_ERASE          0x22\n#define ISPCMD_CHIPERASE      0x26   /* Undocumented isp \"Chip-Erase\" command */\n#define ISPCMD_READ_CID       0x0B\n#define ISPCMD_READ_DID       0x0C\n#define ISPCMD_READ_UID       0x04\n#define ISPCMD_VECMAP         0x2E\n#define ISPTRG_ISPGO          (1 << 0)\n\n/* access unlock keys */\n#define REG_KEY1              0x59\n#define REG_KEY2              0x16\n#define REG_KEY3              0x88\n#define REG_LOCK              0x00\n\n/* flash pagesizes */\n#define NUMICRO_PAGESIZE        512\n/* flash MAX banks */\n#define NUMICRO_MAX_FLASH_BANKS 4\n\n/* flash bank structs */\nstruct numicro_flash_bank_type {\n\tuint32_t base;\n\tuint32_t size;\n};\n\n/* part structs */\nstruct numicro_cpu_type {\n\tchar *partname;\n\tuint32_t partid;\n\tunsigned int n_banks;\n\tstruct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS];\n};\n\n/* If DataFlash size equals zero, it means the actual size depends on config settings. */\n#define NUMICRO_BANKS_GENERAL(aprom_size, data_size, ldrom_size, config_size) \\\n\t.n_banks = 4, \\\n\t{{NUMICRO_APROM_BASE,  (aprom_size)}, \\\n\t {NUMICRO_DATA_BASE,   (data_size)}, \\\n\t {NUMICRO_LDROM_BASE,  (ldrom_size)}, \\\n\t {NUMICRO_CONFIG_BASE, (config_size)}}\n\nstatic const struct numicro_cpu_type numicro_parts[] = {\n\t/*PART NO*/     /*PART ID*/ /*Banks*/\n\t/* M051AN */\n\t{\"M052LAN\",  0x00005200, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054LAN\",  0x00005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058LAN\",  0x00005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516LAN\", 0x00005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M052ZAN\",  0x00005203, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054ZAN\",  0x00005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058ZAN\",  0x00005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516ZAN\", 0x00005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\n\t/* M051BN */\n\t{\"M052LBN\",  0x10005200, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054LBN\",  0x10005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058LBN\",  0x10005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516LBN\", 0x10005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M052ZBN\",  0x10005203, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054ZBN\",  0x10005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058ZBN\",  0x10005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516ZBN\", 0x10005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\n\t/* M051DN */\n\t{\"M0516LDN\", 0x20005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516ZDN\", 0x20005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M052LDN\",  0x20005200, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M052ZDN\",  0x20005203, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054LDN\",  0x20005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M054ZDN\",  0x20005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058LDN\",  0x20005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058ZDN\",  0x20005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\n\t/* M051DE */\n\t{\"M0516LDE\", 0x30005A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M0516ZDE\", 0x30005A03, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M052LDE\",  0x30005200, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M052ZDE\",  0x30005203, NUMICRO_BANKS_GENERAL(8 * 1024,  4 * 1024, 4 * 1024, 4)},\n\t{\"M054LDE\",  0x30005400, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M054ZDE\",  0x30005403, NUMICRO_BANKS_GENERAL(16 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058LDE\",  0x30005800, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"M058ZDE\",  0x30005803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\n\t/* M0518 */\n\t{\"M0518LC2AE\", 0x10051803, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M0518LD2AE\", 0x10051800, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M0518SC2AE\", 0x10051813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M0518SD2AE\", 0x10051810, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* M0519 */\n\t{\"M0519LD3AE\", 0x00051902, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"M0519LE3AE\", 0x00051900, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"M0519SD3AE\", 0x00051922, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"M0519SE3AE\", 0x00051920, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"M0519VE3AE\", 0x00051930, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\n\t/* M058S */\n\t{\"M058SFAN\", 0x00005818, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M058SLAN\", 0x00005810, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M058SSAN\", 0x00005816, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"M058SZAN\", 0x00005813, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* MINI51AN */\n\t{\"MINI51LAN\", 0x00205100, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI51TAN\", 0x00205104, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI51ZAN\", 0x00205103, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52LAN\", 0x00205200, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52TAN\", 0x00205204, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52ZAN\", 0x00205203, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54LAN\", 0x00205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54TAN\", 0x00205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54ZAN\", 0x00205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\n\t/* MINI51DE */\n\t{\"MINI51FDE\", 0x20205105, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI51LDE\", 0x20205100, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI51TDE\", 0x20205104, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI51ZDE\", 0x20205103, NUMICRO_BANKS_GENERAL(4 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52FDE\", 0x20205205, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52LDE\", 0x20205200, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52TDE\", 0x20205204, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI52ZDE\", 0x20205203, NUMICRO_BANKS_GENERAL(8 * 1024,  0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54FDE\", 0x20205405, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54LDE\", 0x20205400, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54TDE\", 0x20205404, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI54ZDE\", 0x20205403, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\n\t/* MINI55 */\n\t{\"MINI55LDE\", 0x00505500, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)},\n\t{\"MINI55ZDE\", 0x00505503, NUMICRO_BANKS_GENERAL(35 * 512, 0 * 1024, 2 * 1024, 8)},\n\n\t/* MINI58 */\n\t{\"MINI58FDE\", 0x00A05805, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},\n\t{\"MINI58LDE\", 0x00A05800, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},\n\t{\"MINI58TDE\", 0x00A05804, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},\n\t{\"MINI58ZDE\", 0x00A05803, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 5 * 512, 8)},\n\n\t/* NANO100AN */\n\t{\"NANO100LC2AN\", 0x00110025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LD2AN\", 0x00110019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LD3AN\", 0x00110018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SC2AN\", 0x00110023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SD2AN\", 0x00110016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SD3AN\", 0x00110015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100VD2AN\", 0x00110013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100VD3AN\", 0x00110012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100ZC2AN\", 0x00110029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100ZD2AN\", 0x00110028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100ZD3AN\", 0x00110027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LC2AN\", 0x00112025, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LD2AN\", 0x00112019, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LD3AN\", 0x00112018, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SC2AN\", 0x00112023, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SD2AN\", 0x00112016, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SD3AN\", 0x00112015, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120VD2AN\", 0x00112013, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120VD3AN\", 0x00112012, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120ZC2AN\", 0x00112029, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120ZD2AN\", 0x00112028, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120ZD3AN\", 0x00112027, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NANO100BN */\n\t{\"NANO100KC2BN\", 0x00110040, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100KD2BN\", 0x00110039, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100KD3BN\", 0x00110038, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100KE3BN\", 0x00110030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LC2BN\", 0x00110043, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LD2BN\", 0x0011003F, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LD3BN\", 0x0011003E, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100LE3BN\", 0x00110036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100ND2BN\", 0x00110046, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100ND3BN\", 0x00110045, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100NE3BN\", 0x00110044, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SC2BN\", 0x00110042, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SD2BN\", 0x0011003D, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SD3BN\", 0x0011003C, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO100SE3BN\", 0x00110034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110KC2BN\", 0x00111040, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110KD2BN\", 0x00111039, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110KD3BN\", 0x00111038, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110KE3BN\", 0x00111030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110RC2BN\", 0x00111043, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110RD2BN\", 0x00111044, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110RD3BN\", 0x00111045, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110SC2BN\", 0x00111042, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110SD2BN\", 0x0011103D, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110SD3BN\", 0x0011103C, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO110SE3BN\", 0x00111034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120KC2BN\", 0x00112040, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120KD2BN\", 0x00112039, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120KD3BN\", 0x00112038, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120KE3BN\", 0x00112030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LC2BN\", 0x00112043, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LD2BN\", 0x0011203F, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LD3BN\", 0x0011203E, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120LE3BN\", 0x00112036, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SC2BN\", 0x00112042, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SD2BN\", 0x0011203D, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SD3BN\", 0x0011203C, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO120SE3BN\", 0x00112034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130KC2BN\", 0x00113040, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130KD2BN\", 0x00113039, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130KD3BN\", 0x00113038, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130KE3BN\", 0x00113030, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130SC2BN\", 0x00113042, NUMICRO_BANKS_GENERAL(32 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130SD2BN\", 0x0011303D, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130SD3BN\", 0x0011303C, NUMICRO_BANKS_GENERAL(64 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"NANO130SE3BN\", 0x00113034, NUMICRO_BANKS_GENERAL(123 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NANO103 */\n\t{\"NANO103SD3AE\", 0x00110301, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO103LD3AE\", 0x00110304, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO103ZD3AE\", 0x00110307, NUMICRO_BANKS_GENERAL(64 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NANO112AN */\n\t{\"NANO102LB1AN\", 0x00110206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO102LC2AN\", 0x00110208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO102SC2AN\", 0x00110212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO102ZB1AN\", 0x00110202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO102ZC2AN\", 0x00110204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112LB1AN\", 0x00111202, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112LC2AN\", 0x00111204, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112RB1AN\", 0x00111210, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112RC2AN\", 0x00111212, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112SB1AN\", 0x00111206, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112SC2AN\", 0x00111208, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NANO112VC2AN\", 0x00111216, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC029AN */\n\t{\"NUC029LAN\", 0x00295A00, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 4)},\n\t{\"NUC029TAN\", 0x00295804, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 4)},\n\n\t/* NUC029AE */\n\t{\"NUC029FAE\", 0x00295415, NUMICRO_BANKS_GENERAL(16 * 1024, 0 * 1024, 2 * 1024, 8)},\n\n\t/* NUC100AN */\n\t{\"NUC100LD3AN\", 0x00010003, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LE3AN\", 0x00010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD3AN\", 0x00010012, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RE3AN\", 0x00010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VD2AN\", 0x00010022, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VD3AN\", 0x00010021, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VE3AN\", 0x00100018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD3AN\", 0x00012003, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LE3AN\", 0x00120000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD3AN\", 0x00012012, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RE3AN\", 0x00012009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VD2AN\", 0x00012022, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VD3AN\", 0x00012021, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VE3AN\", 0x00012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC100BN */\n\t{\"NUC100LC1BN\", 0x10010008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LD1BN\", 0x10010005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LD2BN\", 0x10010004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RC1BN\", 0x10010017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD1BN\", 0x10010014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD2BN\", 0x10010013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LC1BN\", 0x10012008, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD1BN\", 0x10012005, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD2BN\", 0x10012004, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RC1BN\", 0x10012017, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD1BN\", 0x10012014, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD2BN\", 0x10012013, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* NUC100CN */\n\t{\"NUC130LC1CN\", 0x20013008, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC130LD2CN\", 0x20013004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC130LE3CN\", 0x20013000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC130RC1CN\", 0x20013017, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC130RD2CN\", 0x20013013, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC130RE3CN\", 0x20013009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC130VE3CN\", 0x20013018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC140LC1CN\", 0x20014008, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC140LD2CN\", 0x20014004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC140LE3CN\", 0x20014000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC140RC1CN\", 0x20014017, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC140RD2CN\", 0x20014013, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC140RE3CN\", 0x20014009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC140VE3CN\", 0x20014018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC100DN */\n\t{\"NUC100LC1DN\", 0x30010008, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LD1DN\", 0x30010005, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LD2DN\", 0x30010004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LD3DN\", 0x30010003, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100LE3DN\", 0x30010000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RC1DN\", 0x30010017, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD1DN\", 0x30010014, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD2DN\", 0x30010013, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RD3DN\", 0x30010012, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100RE3DN\", 0x30010009, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VD2DN\", 0x30010022, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VD3DN\", 0x30010021, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC100VE3DN\", 0x30010018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LC1DN\", 0x30012008, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD1DN\", 0x30012005, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD2DN\", 0x30012004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LD3DN\", 0x30012003, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120LE3DN\", 0x30012000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RC1DN\", 0x30012035, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD1DN\", 0x30012032, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD2DN\", 0x30012031, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RD3DN\", 0x30012030, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120RE3DN\", 0x30012027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VD2DN\", 0x30012022, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VD3DN\", 0x30012021, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC120VE3DN\", 0x30012018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC121 */\n\t{\"NUC121SC2AE\", 0x00012105, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\t{\"NUC121LC2AE\", 0x00012125, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\t{\"NUC121ZC2AE\", 0x00012145, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\t{\"NUC125SC2AE\", 0x00012505, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\t{\"NUC125LC2AE\", 0x00012525, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\t{\"NUC125ZC2AE\", 0x00012545, NUMICRO_BANKS_GENERAL(32 * 1024, 0 * 1024, 9 * 512, 8)},\n\n\t/* NUC122 */\n\t{\"NUC122LC1AN\", 0x00012208, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC122LD2AN\", 0x00012204, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC122SC1AN\", 0x00012226, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC122SD2AN\", 0x00012222, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC122ZC1AN\", 0x00012235, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC122ZD2AN\", 0x00012231, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* NUC123AN */\n\t{\"NUC123LC2AN1\", 0x00012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123LD4AN0\", 0x00012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123SC2AN1\", 0x00012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123SD4AN0\", 0x00012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123ZC2AN1\", 0x00012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123ZD4AN0\", 0x00012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* NUC123AE */\n\t{\"NUC123LC2AE1\", 0x10012325, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123LD4AE0\", 0x10012335, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123SC2AE1\", 0x10012305, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123SD4AE0\", 0x10012315, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123ZC2AE1\", 0x10012345, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC123ZD4AE0\", 0x10012355, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* NUC131AE */\n\t{\"NUC131LC2AE\", 0x10013103, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC131LD2AE\", 0x10013100, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC131SC2AE\", 0x10013113, NUMICRO_BANKS_GENERAL(32 * 1024, 4 * 1024, 4 * 1024, 8)},\n\t{\"NUC131SD2AE\", 0x10013110, NUMICRO_BANKS_GENERAL(64 * 1024, 4 * 1024, 4 * 1024, 8)},\n\n\t/* NUC200/220AN */\n\t{\"NUC200LC2AN\", 0x00020007, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC200LD2AN\", 0x00020004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC200LE3AN\", 0x00020000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC200SC2AN\", 0x00020034, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC200SD2AN\", 0x00020031, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC200SE3AN\", 0x00020027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC200VE3AN\", 0x00020018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC220LC2AN\", 0x00022007, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC220LD2AN\", 0x00022004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC220LE3AN\", 0x00022000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC220SC2AN\", 0x00022034, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC220SD2AN\", 0x00022031, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 4 * 1024, 8)},\n\t{\"NUC220SE3AN\", 0x00022027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"NUC220VE3AN\", 0x00022018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC230/240AE */\n\t{\"NUC230LC2AE\", 0x10023007, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC230LD2AE\", 0x10023004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC230LE3AE\", 0x10023000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"NUC230SC2AE\", 0x10023034, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC230SD2AE\", 0x10023031, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC230SE3AE\", 0x10023027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"NUC230VE3AE\", 0x10023018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"NUC240LC2AE\", 0x10024007, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC240LD2AE\", 0x10024004, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC240LE3AE\", 0x10024000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"NUC240SC2AE\", 0x10024034, NUMICRO_BANKS_GENERAL(32 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC240SD2AE\", 0x10024031, NUMICRO_BANKS_GENERAL(64 * 1024,  4 * 1024, 8 * 1024, 8)},\n\t{\"NUC240SE3AE\", 0x10024027, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\t{\"NUC240VE3AE\", 0x10024018, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 8 * 1024, 8)},\n\n\t/* M451 */\n\t{\"M451LC3AE\",  0x00945101, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451LD3AE\",  0x00945100, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451LE6AE\",  0x00845101, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451LG6AE\",  0x00845100, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451MLC3AE\", 0x00945001, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451MLD3AE\", 0x00945000, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451MLE6AE\", 0x00845001, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451MLG6AE\", 0x00845000, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451MSC3AE\", 0x00945011, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451MSD3AE\", 0x00945010, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451RC3AE\",  0x00945121, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451RD3AE\",  0x00945120, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M451RE6AE\",  0x00845121, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451RG6AE\",  0x00845120, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451VE6AE\",  0x00845131, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M451VG6AE\",  0x00845130, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M452LC3AE\",  0x00945201, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M452LD3AE\",  0x00945200, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M452LE6AE\",  0x00845201, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M452LG6AE\",  0x00845200, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M452RD3AE\",  0x00945220, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M452RE6AE\",  0x00845221, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M452RG6AE\",  0x00845220, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453LC3AE\",  0x00945301, NUMICRO_BANKS_GENERAL(40 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M453LD3AE\",  0x00945300, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M453LE6AE\",  0x00845301, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453LG6AE\",  0x00845300, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453RD3AE\",  0x00945320, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M453RE6AE\",  0x00845321, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453RG6AE\",  0x00845320, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453VD3AE\",  0x00945330, NUMICRO_BANKS_GENERAL(72 * 1024,  0 * 1024, 4 * 1024, 8)},\n\t{\"M453VE6AE\",  0x00845331, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M453VG6AE\",  0x00845330, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKVG6AE\",  0x00845430, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKVE6AE\",  0x00845431, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKRG6AE\",  0x00845420, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKRE6AE\",  0x00845421, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKLG6AE\",  0x00845400, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 4 * 1024, 8)},\n\t{\"M4TKLE6AE\",  0x00845401, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 4 * 1024, 8)},\n\n\t/* NUC442_472 */\n\t{\"NUC442JG8AE\", 0x00044203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442JI8AE\", 0x00044201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442KG8AE\", 0x00044206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442KI8AE\", 0x00044204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442RG8AE\", 0x00044212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442RI8AE\", 0x00044210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442VG8AE\", 0x00044209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC442VI8AE\", 0x00044207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472HG8AE\", 0x00047203, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472HI8AE\", 0x00047201, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472JG8AE\", 0x00047206, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472JI8AE\", 0x00047204, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472KG8AE\", 0x00047209, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472KI8AE\", 0x00047207, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472VG8AE\", 0x00047212, NUMICRO_BANKS_GENERAL(256 * 1024, 0 * 1024, 16 * 1024, 16)},\n\t{\"NUC472VI8AE\", 0x00047210, NUMICRO_BANKS_GENERAL(512 * 1024, 0 * 1024, 16 * 1024, 16)},\n\n\t{\"UNKNOWN\", 0x00000000, NUMICRO_BANKS_GENERAL(128 * 1024, 0 * 1024, 16 * 1024, 8)},\n};\n\n/* Private bank information for NuMicro. */\nstruct  numicro_flash_bank {\n\tstruct working_area *write_algorithm;\n\tbool probed;\n\tconst struct numicro_cpu_type *cpu;\n};\n\n/* Private variables */\nstatic uint32_t m_page_size = NUMICRO_PAGESIZE;\nstatic uint32_t m_address_bias_offset;\n\n/* Private methods */\nstatic int numicro_get_arm_arch(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tif (armv7m->arm.arch != ARM_ARCH_V6M) {\n\t\tLOG_DEBUG(\"NuMicro arm architecture: armv7m\\n\");\n\t\tm_page_size = NUMICRO_PAGESIZE * 4;\n\t\tm_address_bias_offset = 0x10000000;\n\t} else {\n\t\tLOG_DEBUG(\"NuMicro arm architecture: armv6m\\n\");\n\t\tm_page_size = NUMICRO_PAGESIZE;\n\t\tm_address_bias_offset = 0x0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int numicro_reg_unlock(struct target *target)\n{\n\tuint32_t is_protected;\n\tint retval = ERROR_OK;\n\n\t/* Check to see if NUC is register unlocked or not */\n\tretval = target_read_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, &is_protected);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"protected = 0x%08\" PRIx32 \"\", is_protected);\n\tif (is_protected == 0) {\t/* means protected - so unlock it */\n\t\t/* unlock flash registers */\n\t\tretval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY2);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, REG_KEY3);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\t/* Check that unlock worked */\n\tretval = target_read_u32(target, NUMICRO_SYS_WRPROT - m_address_bias_offset, &is_protected);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (is_protected == 1) {\t/* means unprotected */\n\t\tLOG_DEBUG(\"protection removed\");\n\t} else {\n\t\tLOG_DEBUG(\"still protected!!\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int numicro_init_isp(struct target *target)\n{\n\tuint32_t reg_stat;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = numicro_reg_unlock(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enable ISP/SRAM/TICK Clock */\n\tretval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK - m_address_bias_offset, &reg_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg_stat |= AHBCLK_ISP_EN | AHBCLK_SRAM_EN | AHBCLK_TICK_EN;\n\tretval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK - m_address_bias_offset, reg_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enable ISP */\n\tretval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, &reg_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg_stat |= ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN | ISPCON_ISPEN;\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, reg_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write one to undocumented flash control register */\n\tretval = target_write_u32(target, NUMICRO_FLASH_CHEAT - m_address_bias_offset, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t *rdata)\n{\n\tuint32_t timeout, status;\n\tint retval = ERROR_OK;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPDAT - m_address_bias_offset, wdata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPADR - m_address_bias_offset, addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, ISPTRG_ISPGO);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to clear - check the GO flag */\n\ttimeout = 100;\n\tfor (;;) {\n\t\tretval = target_read_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif ((status & (ISPTRG_ISPGO)) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_DEBUG(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t}\n\n\tretval = target_read_u32(target, NUMICRO_FLASH_ISPDAT - m_address_bias_offset, rdata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n/* NuMicro Program-LongWord Microcodes */\nstatic const uint8_t numicro_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/numicro/numicro_m0.inc\"\n};\n\nstatic const uint8_t numicro_m4_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/numicro/numicro_m4.inc\"\n};\n\n/* Program LongWord Block Write */\nstatic int numicro_writeblock(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 1024; /* Default minimum value */\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* Params:\n\t * r0 - workarea buffer / result\n\t * r1 - target address\n\t * r2 - wordcount\n\t * Clobbered:\n\t * r4 - tmp\n\t * r5 - tmp\n\t * r6 - tmp\n\t * r7 - tmp\n\t */\n\n\t/* Increase buffer_size if needed */\n\tif (buffer_size < (target->working_area_size/2))\n\t\tbuffer_size = (target->working_area_size/2);\n\n\t/* check code alignment */\n\tif (offset & 0x1) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\t/* Difference between M0 and M4 */\n\tif (m_page_size == NUMICRO_PAGESIZE) {\n\t\t/* allocate working area with flash programming code */\n\t\tif (target_alloc_working_area(target, sizeof(numicro_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(numicro_flash_write_code), numicro_flash_write_code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else { /* for M4 */\n\t\t/* allocate working area with flash programming code */\n\t\tif (target_alloc_working_area(target, sizeof(numicro_m4_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(numicro_m4_flash_write_code), numicro_m4_flash_write_code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer_size = m_page_size;\n\t}\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 4;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* free working area, write algorithm already allocated */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"No large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* *pLW (*buffer) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);    /* faddr */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);    /* number of words to program */\n\n\t/* write code buffer and use Flash programming code within NuMicro     */\n\t/* Set breakpoint to 0 with time-out of 1000 ms                        */\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > (buffer_size / 4)) ? (buffer_size / 4) : count;\n\n\t\tretval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\twrite_algorithm->address, 0, 100000, &armv7m_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing NuMicro Flash programming algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer  += thisrun_count * 4;\n\t\taddress += thisrun_count * 4;\n\t\tcount   -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\n\treturn retval;\n}\n\n/* Flash Lock checking - examines the lock bit. */\nstatic int numicro_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tuint32_t set, config[2];\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_INFO(\"Nuvoton NuMicro: Flash Lock Check...\");\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read CONFIG0,CONFIG1 */\n\tnumicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0 - m_address_bias_offset, 0, &config[0]);\n\tnumicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1 - m_address_bias_offset, 0, &config[1]);\n\n\tLOG_DEBUG(\"CONFIG0: 0x%\" PRIx32 \",CONFIG1: 0x%\" PRIx32 \"\", config[0], config[1]);\n\n\tif ((config[0] & (1<<7)) == 0)\n\t\tLOG_INFO(\"CBS=0: Boot From LPROM\");\n\telse\n\t\tLOG_INFO(\"CBS=1: Boot From APROM\");\n\n\tif ((config[0] & CONFIG0_LOCK_MASK) == 0) {\n\n\t\tLOG_INFO(\"Flash is secure locked!\");\n\t\tLOG_INFO(\"TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!\");\n\t\tset = 1;\n\t} else {\n\t\tLOG_INFO(\"Flash is not locked!\");\n\t    set = 0;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = set;\n\n\treturn ERROR_OK;\n}\n\n\nstatic int numicro_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tuint32_t timeout, status;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_INFO(\"Nuvoton NuMicro: Sector Erase ... (%u to %u)\", first, last);\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, ISPCMD_ERASE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tLOG_DEBUG(\"erasing sector %u at address \" TARGET_ADDR_FMT, i, bank->base + bank->sectors[i].offset);\n\t\tretval = target_write_u32(target,\n\t\t\t\t\t  NUMICRO_FLASH_ISPADR - m_address_bias_offset,\n\t\t\t\t\t  bank->base + bank->sectors[i].offset);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target,\n\t\t\t\t\t  NUMICRO_FLASH_ISPTRG - m_address_bias_offset,\n\t\t\t\t\t  ISPTRG_ISPGO); /* This is the only bit available */\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* wait for busy to clear - check the GO flag */\n\t\ttimeout = 100;\n\t\tfor (;;) {\n\t\t\tretval = target_read_u32(target, NUMICRO_FLASH_ISPTRG - m_address_bias_offset, &status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (status == 0)\n\t\t\t\tbreak;\n\t\t\tif (timeout-- <= 0) {\n\t\t\t\tLOG_DEBUG(\"timed out waiting for flash\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t\t}\n\n\t\t/* check for failure */\n\t\tretval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif ((status & ISPCON_ISPFF) != 0) {\n\t\t\tLOG_DEBUG(\"failure: 0x%\" PRIx32 \"\", status);\n\t\t\t/* if bit is set, then must write to it to clear it. */\n\t\t\tretval = target_write_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, (status | ISPCON_ISPFF));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* done, */\n\tLOG_DEBUG(\"Erase done.\");\n\n\treturn ERROR_OK;\n}\n\n/* The write routine stub. */\nstatic int numicro_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t timeout, status;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_INFO(\"Nuvoton NuMicro: Flash Write ...\");\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, NUMICRO_FLASH_ISPCMD - m_address_bias_offset, ISPCMD_WRITE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tassert(offset % 4 == 0);\n\tassert(count % 4 == 0);\n\n\tuint32_t words_remaining = count / 4;\n\n\t/* try using a block write */\n\tretval = numicro_writeblock(bank, buffer, offset, words_remaining);\n\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t/* if block write failed (no sufficient working area),\n\t\t * we use normal (slow) single word accesses */\n\t\tLOG_WARNING(\"couldn't use block writes, falling back to single \"\n\t\t\t\"memory accesses\");\n\n\t\t/* program command */\n\t\tfor (uint32_t i = 0; i < count; i += 4) {\n\t\t\t/* write 4 bytes each time with 0xff padding to avoid unaligned case */\n\t\t\tuint8_t padding[4] = {0xff, 0xff, 0xff, 0xff};\n\t\t\tmemcpy(padding, buffer + i, MIN(4, count - i));\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\t\t\t  NUMICRO_FLASH_ISPADR - m_address_bias_offset,\n\t\t\t\t\t\t  bank->base + offset + i);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_memory(target,\n\t\t\t\t\t\t     NUMICRO_FLASH_ISPDAT - m_address_bias_offset,\n\t\t\t\t\t\t     4, 1, padding);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_u32(target,\n\t\t\t\t\t\t  NUMICRO_FLASH_ISPTRG - m_address_bias_offset,\n\t\t\t\t\t\t  ISPTRG_ISPGO);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* wait for busy to clear - check the GO flag */\n\t\t\ttimeout = 100;\n\t\t\tfor (;;) {\n\t\t\t\tretval = target_read_u32(target,\n\t\t\t\t\t\t\t NUMICRO_FLASH_ISPTRG - m_address_bias_offset,\n\t\t\t\t\t\t\t &status);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tif (status == 0)\n\t\t\t\t\tbreak;\n\t\t\t\tif (timeout-- <= 0) {\n\t\t\t\t\tLOG_DEBUG(\"timed out waiting for flash\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tbusy_sleep(1);\t/* can use busy sleep for short times. */\n\t\t\t}\n\n\t\t}\n\t}\n\n\t/* check for failure */\n\tretval = target_read_u32(target, NUMICRO_FLASH_ISPCON - m_address_bias_offset, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif ((status & ISPCON_ISPFF) != 0) {\n\t\tLOG_DEBUG(\"failure: 0x%\" PRIx32 \"\", status);\n\t\t/* if bit is set, then must write to it to clear it. */\n\t\tretval = target_write_u32(target,\n\t\t\t\t\t  NUMICRO_FLASH_ISPCON - m_address_bias_offset,\n\t\t\t\t\t  (status | ISPCON_ISPFF));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tLOG_DEBUG(\"Write OK\");\n\t}\n\n\t/* done. */\n\tLOG_DEBUG(\"Write done.\");\n\n\treturn ERROR_OK;\n}\n\nstatic int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type **cpu)\n{\n\tuint32_t part_id;\n\tint retval = ERROR_OK;\n\n\tnumicro_get_arm_arch(target);\n\t/* Read NuMicro PartID */\n\tretval = target_read_u32(target, NUMICRO_SYS_BASE - m_address_bias_offset, &part_id);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"NuMicro flash driver: Failed to Get PartID\\n\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tLOG_INFO(\"Device ID: 0x%08\" PRIx32 \"\", part_id);\n\t/* search part numbers */\n\tfor (size_t i = 0; i < ARRAY_SIZE(numicro_parts); i++) {\n\t\tif (part_id == numicro_parts[i].partid) {\n\t\t\t*cpu = &numicro_parts[i];\n\t\t\tLOG_INFO(\"Device Name: %s\", (*cpu)->partname);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nstatic int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_cpu_type *cpu, uint32_t *flash_size)\n{\n\tfor (size_t i = 0; i < cpu->n_banks; i++) {\n\t\tif (bank->base == cpu->bank[i].base) {\n\t\t\t*flash_size = cpu->bank[i].size;\n\t\t\tLOG_INFO(\"bank base = \" TARGET_ADDR_FMT \", size = 0x%08\"\n\t\t\t\t\tPRIx32, bank->base, *flash_size);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int numicro_probe(struct flash_bank *bank)\n{\n\tuint32_t flash_size, offset = 0;\n\tint num_pages;\n\tconst struct numicro_cpu_type *cpu;\n\tstruct target *target = bank->target;\n\tint retval = ERROR_OK;\n\n\tretval = numicro_get_cpu_type(target, &cpu);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"NuMicro flash driver: Failed to detect a known part\\n\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tretval = numicro_get_flash_size(bank, cpu, &flash_size);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"NuMicro flash driver: Failed to detect flash size\\n\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tnum_pages = flash_size / m_page_size;\n\n\tbank->num_sectors = num_pages;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_pages);\n\tbank->size = flash_size;\n\n\tfor (int i = 0; i < num_pages; i++) {\n\t\tbank->sectors[i].offset = offset;\n\t\tbank->sectors[i].size = m_page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t\toffset += m_page_size;\n\t}\n\n\tstruct numicro_flash_bank *numicro_info = bank->driver_priv;\n\tnumicro_info->probed = true;\n\tnumicro_info->cpu = cpu;\n\tLOG_DEBUG(\"Nuvoton NuMicro: Probed ...\");\n\n\treturn ERROR_OK;\n}\n\n/* Standard approach to autoprobing. */\nstatic int numicro_auto_probe(struct flash_bank *bank)\n{\n\tstruct numicro_flash_bank *numicro_info = bank->driver_priv;\n\tif (numicro_info->probed)\n\t\treturn ERROR_OK;\n\treturn numicro_probe(bank);\n}\n\n\n/* This is the function called in the config file. */\nFLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command)\n{\n\tstruct numicro_flash_bank *bank_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"add flash_bank numicro %s\", bank->name);\n\n\tbank_info = malloc(sizeof(struct numicro_flash_bank));\n\n\tmemset(bank_info, 0, sizeof(struct numicro_flash_bank));\n\n\tbank->driver_priv = bank_info;\n\tbank->write_start_alignment = bank->write_end_alignment = 4;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(numicro_handle_read_isp_command)\n{\n\tuint32_t address;\n\tuint32_t ispdat;\n\tint retval = ERROR_OK;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = numicro_fmc_cmd(target, ISPCMD_READ, address, 0, &ispdat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"0x%08\" PRIx32 \": 0x%08\" PRIx32, address, ispdat);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(numicro_handle_write_isp_command)\n{\n\tuint32_t address;\n\tuint32_t ispdat, rdat;\n\tint retval = ERROR_OK;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = numicro_fmc_cmd(target, ISPCMD_WRITE, address, ispdat, &rdat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"0x%08\" PRIx32 \": 0x%08\" PRIx32, address, ispdat);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(numicro_handle_chip_erase_command)\n{\n\tint retval = ERROR_OK;\n\tuint32_t rdat;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tnumicro_get_arm_arch(target);\n\tretval = numicro_init_isp(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"numicro chip_erase failed\");\n\t\treturn retval;\n\t}\n\n\tcommand_print(CMD, \"numicro chip_erase complete\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration numicro_exec_command_handlers[] = {\n\t{\n\t\t.name = \"read_isp\",\n\t\t.handler = numicro_handle_read_isp_command,\n\t\t.usage = \"address\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read flash through ISP.\",\n\t},\n\t{\n\t\t.name = \"write_isp\",\n\t\t.handler = numicro_handle_write_isp_command,\n\t\t.usage = \"address value\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write flash through ISP.\",\n\t},\n\t{\n\t\t.name = \"chip_erase\",\n\t\t.handler = numicro_handle_chip_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"chip erase through ISP.\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration numicro_command_handlers[] = {\n\t{\n\t\t.name = \"numicro\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"numicro flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = numicro_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver numicro_flash = {\n\t.name = \"numicro\",\n\t.commands = numicro_command_handlers,\n\t.flash_bank_command = numicro_flash_bank_command,\n\t.erase = numicro_erase,\n\t.write = numicro_write,\n\t.read = default_flash_read,\n\t.probe = numicro_probe,\n\t.auto_probe = numicro_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = numicro_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/ocl.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"ocl.h\"\n#include <target/embeddedice.h>\n\nstruct ocl_priv {\n\tstruct arm_jtag *jtag_info;\n\tunsigned int buflen;\n\tunsigned int bufalign;\n};\n\n/* flash_bank ocl 0 0 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(ocl_flash_bank_command)\n{\n\tstruct arm7_9_common *arm7_9;\n\tstruct ocl_priv *ocl;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tarm7_9 = target_to_arm7_9(bank->target);\n\tif (!is_arm7_9(arm7_9))\n\t\treturn ERROR_TARGET_INVALID;\n\n\tocl = bank->driver_priv = malloc(sizeof(struct ocl_priv));\n\tocl->jtag_info = &arm7_9->jtag_info;\n\tocl->buflen = 0;\n\tocl->bufalign = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int ocl_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct ocl_priv *ocl = bank->driver_priv;\n\tint retval;\n\tuint32_t dcc_buffer[3];\n\n\t/* check preconditions */\n\tif (bank->num_sectors == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_RUNNING) {\n\t\tLOG_ERROR(\"target has to be running to communicate with the loader\");\n\t\treturn ERROR_TARGET_NOT_RUNNING;\n\t}\n\n\tif ((first == 0) && (last == bank->num_sectors - 1)) {\n\t\tdcc_buffer[0] = OCL_ERASE_ALL;\n\t\tretval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tdcc_buffer[0] = OCL_ERASE_BLOCK;\n\t\tdcc_buffer[1] = first;\n\t\tdcc_buffer[2] = last;\n\t\tretval = embeddedice_send(ocl->jtag_info, dcc_buffer, 3);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* wait for response, fixed timeout of 1 s */\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* receive response */\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer + 1, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dcc_buffer[1] != OCL_CMD_DONE) {\n\t\tif (dcc_buffer[0] == OCL_ERASE_ALL)\n\t\t\tLOG_ERROR(\"loader response to OCL_ERASE_ALL 0x%08\" PRIx32 \"\", dcc_buffer[1]);\n\t\telse\n\t\t\tLOG_ERROR(\"loader response to OCL_ERASE_BLOCK 0x%08\" PRIx32 \"\", dcc_buffer[1]);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ocl_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct ocl_priv *ocl = bank->driver_priv;\n\tint retval;\n\tuint32_t *dcc_buffer;\n\tuint32_t *dcc_bufptr;\n\tint byteofs;\n\tint runlen;\n\tuint32_t chksum;\n\n\tint i;\n\n\t/* check preconditions */\n\tif (ocl->buflen == 0 || ocl->bufalign == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (bank->target->state != TARGET_RUNNING) {\n\t\tLOG_ERROR(\"target has to be running to communicate with the loader\");\n\t\treturn ERROR_TARGET_NOT_RUNNING;\n\t}\n\n\t/* allocate buffer for max. ocl buffer + overhead */\n\tdcc_buffer = malloc(sizeof(uint32_t)*(ocl->buflen/4 + 3));\n\n\twhile (count) {\n\t\tif (count + (offset % ocl->bufalign) > ocl->buflen)\n\t\t\trunlen = ocl->buflen - (offset % ocl->bufalign);\n\t\telse\n\t\t\trunlen = count;\n\n\t\tdcc_buffer[0] = OCL_FLASH_BLOCK | runlen;\n\t\tdcc_buffer[1] = offset;\n\t\tdcc_bufptr = &dcc_buffer[2];\n\n\t\t*dcc_bufptr = 0xffffffff;\n\t\tbyteofs = (offset % ocl->bufalign) % 4;\n\t\tchksum = OCL_CHKS_INIT;\n\n\t\t/* copy data to DCC buffer in proper byte order and properly aligned */\n\t\tfor (i = 0; i < runlen; i++) {\n\t\t\tswitch (byteofs++) {\n\t\t\t\tcase 0:\n\t\t\t\t\t*dcc_bufptr &= *(buffer++) | 0xffffff00;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\t*dcc_bufptr &= ((*(buffer++)) << 8) | 0xffff00ff;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\t*dcc_bufptr &= ((*(buffer++)) << 16) | 0xff00ffff;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\t*dcc_bufptr &= ((*(buffer++)) << 24) | 0x00ffffff;\n\t\t\t\t\tchksum ^= *(dcc_bufptr++);\n\t\t\t\t\t*dcc_bufptr = 0xffffffff;\n\t\t\t\t\tbyteofs = 0;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* add the remaining word to checksum */\n\t\tif (byteofs)\n\t\t\tchksum ^= *(dcc_bufptr++);\n\n\t\t*(dcc_bufptr++) = chksum;\n\n\t\t/* send the data */\n\t\tretval = embeddedice_send(ocl->jtag_info, dcc_buffer, dcc_bufptr-dcc_buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(dcc_buffer);\n\t\t  return retval;\n\t\t}\n\n\t\t/* wait for response, fixed timeout of 1 s */\n\t\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(dcc_buffer);\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* receive response */\n\t\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(dcc_buffer);\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (dcc_buffer[0] != OCL_CMD_DONE) {\n\t\t\tLOG_ERROR(\"loader response to OCL_FLASH_BLOCK 0x%08\" PRIx32 \"\", dcc_buffer[0]);\n\t\t\tfree(dcc_buffer);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tcount -= runlen;\n\t\toffset += runlen;\n\t}\n\n\tfree(dcc_buffer);\n\treturn ERROR_OK;\n}\n\nstatic int ocl_probe(struct flash_bank *bank)\n{\n\tstruct ocl_priv *ocl = bank->driver_priv;\n\tint retval;\n\tuint32_t dcc_buffer[1];\n\tint sectsize;\n\n\t/* purge pending data in DCC */\n\tembeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\n\tdcc_buffer[0] = OCL_PROBE;\n\tretval = embeddedice_send(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for response, fixed timeout of 1 s */\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 1000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* receive response */\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dcc_buffer[0] != OCL_CMD_DONE) {\n\t\tLOG_ERROR(\"loader response to OCL_PROBE 0x%08\" PRIx32 \"\", dcc_buffer[0]);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* receive and fill in parameters, detection of loader is important, receive it one by one */\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tbank->base = dcc_buffer[0];\n\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tbank->size = dcc_buffer[0];\n\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tbank->num_sectors = dcc_buffer[0];\n\n\tretval = embeddedice_handshake(ocl->jtag_info, EICE_COMM_CTRL_WBIT, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = embeddedice_receive(ocl->jtag_info, dcc_buffer, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tocl->buflen = dcc_buffer[0] & 0xffff;\n\tocl->bufalign = dcc_buffer[0] >> 16;\n\n\tbank->sectors = realloc(bank->sectors, sizeof(struct flash_sector)*bank->num_sectors);\n\tif (bank->num_sectors == 0) {\n\t\tLOG_ERROR(\"number of sectors shall be non zero value\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\tif (bank->size % bank->num_sectors) {\n\t\tLOG_ERROR(\"bank size not divisible by number of sectors\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\tsectsize = bank->size / bank->num_sectors;\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * sectsize;\n\t\tbank->sectors[i].size = sectsize;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\tif (ocl->bufalign == 0)\n\t\tocl->bufalign = 1;\n\n\tif (ocl->buflen == 0) {\n\t\tLOG_ERROR(\"buflen shall be non zero value\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tif ((ocl->bufalign > ocl->buflen) || (ocl->buflen % ocl->bufalign)) {\n\t\tLOG_ERROR(\"buflen is not multiple of bufalign\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tif (ocl->buflen % 4) {\n\t\tLOG_ERROR(\"buflen shall be divisible by 4\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ocl_auto_probe(struct flash_bank *bank)\n{\n\tstruct ocl_priv *ocl = bank->driver_priv;\n\n\tif (ocl->buflen == 0 || ocl->bufalign == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver ocl_flash = {\n\t.name = \"ocl\",\n\t.flash_bank_command = ocl_flash_bank_command,\n\t.erase = ocl_erase,\n\t.write = ocl_write,\n\t.read = default_flash_read,\n\t.probe = ocl_probe,\n\t.erase_check = default_flash_blank_check,\n\t.auto_probe = ocl_auto_probe,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/ocl.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_OCL_H\n#define OPENOCD_FLASH_NOR_OCL_H\n\n/* command/response mask */\n#define OCL_CMD_MASK 0xFFFF0000L\n\n/* commands */\n#define OCL_FLASH_BLOCK 0x0CFB0000L\n#define OCL_ERASE_BLOCK 0x0CEB0000L\n#define OCL_ERASE_ALL 0x0CEA0000L\n#define OCL_PROBE 0x0CBE0000L\n\n/* responses */\n#define OCL_CMD_DONE 0x0ACD0000L\n#define OCL_CMD_ERR 0x0ACE0000L\n#define OCL_CHKS_FAIL 0x0ACF0000L\n#define OCL_BUFF_OVER 0x0AB00000L\n\n#define OCL_CHKS_INIT 0xC100CD0CL\n\n#endif /* OPENOCD_FLASH_NOR_OCL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/pic32mx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by John McCarthy                                   *\n *   jgmcc@magma.ca                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include \"imp.h\"\n#include <target/algorithm.h>\n#include <target/mips32.h>\n#include <target/mips_m4k.h>\n\n#define PIC32MX_MANUF_ID\t0x029\n\n/* pic32mx memory locations */\n\n#define PIC32MX_PHYS_RAM\t\t\t0x00000000\n#define PIC32MX_PHYS_PGM_FLASH\t\t0x1D000000\n#define PIC32MX_PHYS_PERIPHERALS\t0x1F800000\n#define PIC32MX_PHYS_BOOT_FLASH\t\t0x1FC00000\n\n/*\n * Translate Virtual and Physical addresses.\n * Note: These macros only work for KSEG0/KSEG1 addresses.\n */\n\n#define virt2phys(v)\t((v) & 0x1FFFFFFF)\n\n/* pic32mx configuration register locations */\n\n#define PIC32MX_DEVCFG0_1XX_2XX\t0xBFC00BFC\n#define PIC32MX_DEVCFG0\t\t0xBFC02FFC\n#define PIC32MX_DEVCFG1\t\t0xBFC02FF8\n#define PIC32MX_DEVCFG2\t\t0xBFC02FF4\n#define PIC32MX_DEVCFG3\t\t0xBFC02FF0\n#define PIC32MX_DEVID\t\t0xBF80F220\n\n#define PIC32MX_BMXPFMSZ\t0xBF882060\n#define PIC32MX_BMXBOOTSZ\t0xBF882070\n#define PIC32MX_BMXDRMSZ\t0xBF882040\n\n/* pic32mx flash controller register locations */\n\n#define PIC32MX_NVMCON\t\t0xBF80F400\n#define PIC32MX_NVMCONCLR\t0xBF80F404\n#define PIC32MX_NVMCONSET\t0xBF80F408\n#define PIC32MX_NVMCONINV\t0xBF80F40C\n#define NVMCON_NVMWR\t\t(1 << 15)\n#define NVMCON_NVMWREN\t\t(1 << 14)\n#define NVMCON_NVMERR\t\t(1 << 13)\n#define NVMCON_LVDERR\t\t(1 << 12)\n#define NVMCON_LVDSTAT\t\t(1 << 11)\n#define NVMCON_OP_PFM_ERASE\t\t0x5\n#define NVMCON_OP_PAGE_ERASE\t0x4\n#define NVMCON_OP_ROW_PROG\t\t0x3\n#define NVMCON_OP_WORD_PROG\t\t0x1\n#define NVMCON_OP_NOP\t\t\t0x0\n\n#define PIC32MX_NVMKEY\t\t0xBF80F410\n#define PIC32MX_NVMADDR\t\t0xBF80F420\n#define PIC32MX_NVMADDRCLR\t0xBF80F424\n#define PIC32MX_NVMADDRSET\t0xBF80F428\n#define PIC32MX_NVMADDRINV\t0xBF80F42C\n#define PIC32MX_NVMDATA\t\t0xBF80F430\n#define PIC32MX_NVMSRCADDR\t0xBF80F440\n\n/* flash unlock keys */\n\n#define NVMKEY1\t\t\t0xAA996655\n#define NVMKEY2\t\t\t0x556699AA\n\n#define MX_1XX_2XX\t\t\t1\t/* PIC32mx1xx/2xx */\n#define MX_17X_27X\t\t\t2\t/* PIC32mx17x/27x */\n\nstruct pic32mx_flash_bank {\n\tbool probed;\n\tint dev_type;\t\t/* Default 0. 1 for Pic32MX1XX/2XX variant */\n};\n\n/*\n * DEVID values as per PIC32MX Flash Programming Specification Rev N\n */\n\nstatic const struct pic32mx_devs_s {\n\tuint32_t devid;\n\tconst char *name;\n} pic32mx_devs[] = {\n\t{0x04A07053, \"110F016B\"},\n\t{0x04A09053, \"110F016C\"},\n\t{0x04A0B053, \"110F016D\"},\n\t{0x04A06053, \"120F032B\"},\n\t{0x04A08053, \"120F032C\"},\n\t{0x04A0A053, \"120F032D\"},\n\t{0x04D07053, \"130F064B\"},\n\t{0x04D09053, \"130F064C\"},\n\t{0x04D0B053, \"130F064D\"},\n\t{0x04D06053, \"150F128B\"},\n\t{0x04D08053, \"150F128C\"},\n\t{0x04D0A053, \"150F128D\"},\n\t{0x06610053, \"170F256B\"},\n\t{0x0661A053, \"170F256D\"},\n\t{0x04A01053, \"210F016B\"},\n\t{0x04A03053, \"210F016C\"},\n\t{0x04A05053, \"210F016D\"},\n\t{0x04A00053, \"220F032B\"},\n\t{0x04A02053, \"220F032C\"},\n\t{0x04A04053, \"220F032D\"},\n\t{0x04D01053, \"230F064B\"},\n\t{0x04D03053, \"230F064C\"},\n\t{0x04D05053, \"230F064D\"},\n\t{0x04D00053, \"250F128B\"},\n\t{0x04D02053, \"250F128C\"},\n\t{0x04D04053, \"250F128D\"},\n\t{0x06600053, \"270F256B\"},\n\t{0x0660A053, \"270F256D\"},\n\t{0x05600053, \"330F064H\"},\n\t{0x05601053, \"330F064L\"},\n\t{0x05602053, \"430F064H\"},\n\t{0x05603053, \"430F064L\"},\n\t{0x0570C053, \"350F128H\"},\n\t{0x0570D053, \"350F128L\"},\n\t{0x0570E053, \"450F128H\"},\n\t{0x0570F053, \"450F128L\"},\n\t{0x05704053, \"350F256H\"},\n\t{0x05705053, \"350F256L\"},\n\t{0x05706053, \"450F256H\"},\n\t{0x05707053, \"450F256L\"},\n\t{0x05808053, \"370F512H\"},\n\t{0x05809053, \"370F512L\"},\n\t{0x0580A053, \"470F512H\"},\n\t{0x0580B053, \"470F512L\"},\n\t{0x00938053, \"360F512L\"},\n\t{0x00934053, \"360F256L\"},\n\t{0x0092D053, \"340F128L\"},\n\t{0x0092A053, \"320F128L\"},\n\t{0x00916053, \"340F512H\"},\n\t{0x00912053, \"340F256H\"},\n\t{0x0090D053, \"340F128H\"},\n\t{0x0090A053, \"320F128H\"},\n\t{0x00906053, \"320F064H\"},\n\t{0x00902053, \"320F032H\"},\n\t{0x00978053, \"460F512L\"},\n\t{0x00974053, \"460F256L\"},\n\t{0x0096D053, \"440F128L\"},\n\t{0x00952053, \"440F256H\"},\n\t{0x00956053, \"440F512H\"},\n\t{0x0094D053, \"440F128H\"},\n\t{0x00942053, \"420F032H\"},\n\t{0x04307053, \"795F512L\"},\n\t{0x0430E053, \"795F512H\"},\n\t{0x04306053, \"775F512L\"},\n\t{0x0430D053, \"775F512H\"},\n\t{0x04312053, \"775F256L\"},\n\t{0x04303053, \"775F256H\"},\n\t{0x04417053, \"764F128L\"},\n\t{0x0440B053, \"764F128H\"},\n\t{0x04341053, \"695F512L\"},\n\t{0x04325053, \"695F512H\"},\n\t{0x04311053, \"675F512L\"},\n\t{0x0430C053, \"675F512H\"},\n\t{0x04305053, \"675F256L\"},\n\t{0x0430B053, \"675F256H\"},\n\t{0x04413053, \"664F128L\"},\n\t{0x04407053, \"664F128H\"},\n\t{0x04411053, \"664F064L\"},\n\t{0x04405053, \"664F064H\"},\n\t{0x0430F053, \"575F512L\"},\n\t{0x04309053, \"575F512H\"},\n\t{0x04333053, \"575F256L\"},\n\t{0x04317053, \"575F256H\"},\n\t{0x0440F053, \"564F128L\"},\n\t{0x04403053, \"564F128H\"},\n\t{0x0440D053, \"564F064L\"},\n\t{0x04401053, \"564F064H\"},\n\t{0x04400053, \"534F064H\"},\n\t{0x0440C053, \"534F064L\"},\n\t{0x00000000, NULL}\n};\n\n/* flash bank pic32mx <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)\n{\n\tstruct pic32mx_flash_bank *pic32mx_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tpic32mx_info = malloc(sizeof(struct pic32mx_flash_bank));\n\tbank->driver_priv = pic32mx_info;\n\n\tpic32mx_info->probed = false;\n\tpic32mx_info->dev_type = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t pic32mx_get_flash_status(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\n\ttarget_read_u32(target, PIC32MX_NVMCON, &status);\n\n\treturn status;\n}\n\nstatic uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\n\t/* wait for busy to clear */\n\twhile (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0)) {\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32, status);\n\t\talive_sleep(1);\n\t}\n\tif (timeout <= 0)\n\t\tLOG_DEBUG(\"timeout: status: 0x%\" PRIx32, status);\n\n\treturn status;\n}\n\nstatic int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\n\ttarget_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op);\n\n\t/* unlock flash registers */\n\ttarget_write_u32(target, PIC32MX_NVMKEY, NVMKEY1);\n\ttarget_write_u32(target, PIC32MX_NVMKEY, NVMKEY2);\n\n\t/* start operation */\n\ttarget_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR);\n\n\tstatus = pic32mx_wait_status_busy(bank, timeout);\n\n\t/* lock flash registers */\n\ttarget_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN);\n\n\treturn status;\n}\n\nstatic int pic32mx_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;\n\n\tuint32_t config0_address;\n\tuint32_t devcfg0;\n\tunsigned int s, num_pages;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (pic32mx_info->dev_type) {\n\tcase\tMX_1XX_2XX:\n\tcase\tMX_17X_27X:\n\t\tconfig0_address = PIC32MX_DEVCFG0_1XX_2XX;\n\t\tbreak;\n\tdefault:\n\t\tconfig0_address = PIC32MX_DEVCFG0;\n\t\tbreak;\n\t}\n\n\ttarget_read_u32(target, config0_address, &devcfg0);\n\n\tif ((devcfg0 & (1 << 28)) == 0) /* code protect bit */\n\t\tnum_pages = 0xffff;\t\t\t/* All pages protected */\n\telse if (virt2phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) {\n\t\tif (devcfg0 & (1 << 24))\n\t\t\tnum_pages = 0;\t\t\t/* All pages unprotected */\n\t\telse\n\t\t\tnum_pages = 0xffff;\t\t/* All pages protected */\n\t} else {\n\t\t/* pgm flash */\n\t\tswitch (pic32mx_info->dev_type) {\n\t\tcase\tMX_1XX_2XX:\n\t\t\tnum_pages = (~devcfg0 >> 10) & 0x7f;\n\t\t\tbreak;\n\t\tcase\tMX_17X_27X:\n\t\t\tnum_pages = (~devcfg0 >> 10) & 0x1ff;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tnum_pages = (~devcfg0 >> 12) & 0xff;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfor (s = 0; s < bank->num_sectors && s < num_pages; s++)\n\t\tbank->sectors[s].is_protected = 1;\n\tfor (; s < bank->num_sectors; s++)\n\t\tbank->sectors[s].is_protected = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int pic32mx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1))\n\t\t&& (virt2phys(bank->base) == PIC32MX_PHYS_PGM_FLASH)) {\n\t\t/* this will only erase the Program Flash (PFM), not the Boot Flash (BFM)\n\t\t * we need to use the MTAP to perform a full erase */\n\t\tLOG_DEBUG(\"Erasing entire program flash\");\n\t\tstatus = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);\n\t\tif (status & NVMCON_NVMERR)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\tif (status & NVMCON_LVDERR)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\ttarget_write_u32(target, PIC32MX_NVMADDR, virt2phys(bank->base + bank->sectors[i].offset));\n\n\t\tstatus = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);\n\n\t\tif (status & NVMCON_NVMERR)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\tif (status & NVMCON_LVDERR)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int pic32mx_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* see contrib/loaders/flash/pic32mx.s for src */\n\nstatic uint32_t pic32mx_flash_write_code[] = {\n\t\t\t\t\t/* write: */\n\t0x3C08AA99,\t\t/* lui $t0, 0xaa99 */\n\t0x35086655,\t\t/* ori $t0, 0x6655 */\n\t0x3C095566,\t\t/* lui $t1, 0x5566 */\n\t0x352999AA,\t\t/* ori $t1, 0x99aa */\n\t0x3C0ABF80,\t\t/* lui $t2, 0xbf80 */\n\t0x354AF400,\t\t/* ori $t2, 0xf400 */\n\t0x340B4003,\t\t/* ori $t3, $zero, 0x4003 */\n\t0x340C8000,\t\t/* ori $t4, $zero, 0x8000 */\n\t\t\t\t\t/* write_row: */\n\t0x2CD30080,\t\t/* sltiu $s3, $a2, 128 */\n\t0x16600008,\t\t/* bne $s3, $zero, write_word */\n\t0x340D4000,\t\t/* ori $t5, $zero, 0x4000 */\n\t0xAD450020,\t\t/* sw $a1, 32($t2) */\n\t0xAD440040,\t\t/* sw $a0, 64($t2) */\n\t0x04110016,\t\t/* bal progflash */\n\t0x24840200,\t\t/* addiu $a0, $a0, 512 */\n\t0x24A50200,\t\t/* addiu $a1, $a1, 512 */\n\t0x1000FFF7,\t\t/* beq $zero, $zero, write_row */\n\t0x24C6FF80,\t\t/* addiu $a2, $a2, -128 */\n\t\t\t\t\t/* write_word: */\n\t0x3C15A000,\t\t/* lui $s5, 0xa000 */\n\t0x36B50000,\t\t/* ori $s5, $s5, 0x0 */\n\t0x00952025,\t\t/* or $a0, $a0, $s5 */\n\t0x10000008,\t\t/* beq $zero, $zero, next_word */\n\t0x340B4001,\t\t/* ori $t3, $zero, 0x4001 */\n\t\t\t\t\t/* prog_word: */\n\t0x8C940000,\t\t/* lw $s4, 0($a0) */\n\t0xAD540030,\t\t/* sw $s4, 48($t2) */\n\t0xAD450020,\t\t/* sw $a1, 32($t2) */\n\t0x04110009,\t\t/* bal progflash */\n\t0x24840004,\t\t/* addiu $a0, $a0, 4 */\n\t0x24A50004,\t\t/* addiu $a1, $a1, 4 */\n\t0x24C6FFFF,\t\t/* addiu $a2, $a2, -1 */\n\t\t\t\t\t/* next_word: */\n\t0x14C0FFF8,\t\t/* bne $a2, $zero, prog_word */\n\t0x00000000,\t\t/* nop */\n\t\t\t\t\t/* done: */\n\t0x10000002,\t\t/* beq $zero, $zero, exit */\n\t0x24040000,\t\t/* addiu $a0, $zero, 0 */\n\t\t\t\t\t/* error: */\n\t0x26240000,\t\t/* addiu $a0, $s1, 0 */\n\t\t\t\t\t/* exit: */\n\t0x7000003F,\t\t/* sdbbp */\n\t\t\t\t\t/* progflash: */\n\t0xAD4B0000,\t\t/* sw $t3, 0($t2) */\n\t0xAD480010,\t\t/* sw $t0, 16($t2) */\n\t0xAD490010,\t\t/* sw $t1, 16($t2) */\n\t0xAD4C0008,\t\t/* sw $t4, 8($t2) */\n\t\t\t\t\t/* waitflash: */\n\t0x8D500000,\t\t/* lw $s0, 0($t2) */\n\t0x020C8024,\t\t/* and $s0, $s0, $t4 */\n\t0x1600FFFD,\t\t/* bne $s0, $zero, waitflash */\n\t0x00000000,\t\t/* nop */\n\t0x00000000,\t\t/* nop */\n\t0x00000000,\t\t/* nop */\n\t0x00000000,\t\t/* nop */\n\t0x00000000,\t\t/* nop */\n\t0x8D510000,\t\t/* lw $s1, 0($t2) */\n\t0x30113000,\t\t/* andi $s1, $zero, 0x3000 */\n\t0x1620FFEF,\t\t/* bne $s1, $zero, error */\n\t0xAD4D0004,\t\t/* sw $t5, 4($t2) */\n\t0x03E00008,\t\t/* jr $ra */\n\t0x00000000\t\t/* nop */\n};\n\nstatic int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[3];\n\tuint32_t row_size;\n\tint retval = ERROR_OK;\n\n\tstruct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;\n\tstruct mips32_algorithm mips32_info;\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Change values for counters and row size, depending on variant */\n\tswitch (pic32mx_info->dev_type) {\n\tcase\tMX_1XX_2XX:\n\tcase\tMX_17X_27X:\n\t\t/* 128 byte row */\n\t\tpic32mx_flash_write_code[8] = 0x2CD30020;\n\t\tpic32mx_flash_write_code[14] = 0x24840080;\n\t\tpic32mx_flash_write_code[15] = 0x24A50080;\n\t\tpic32mx_flash_write_code[17] = 0x24C6FFE0;\n\t\trow_size = 128;\n\t\tbreak;\n\tdefault:\n\t\t/* 512 byte row */\n\t\tpic32mx_flash_write_code[8] = 0x2CD30080;\n\t\tpic32mx_flash_write_code[14] = 0x24840200;\n\t\tpic32mx_flash_write_code[15] = 0x24A50200;\n\t\tpic32mx_flash_write_code[17] = 0x24C6FF80;\n\t\trow_size = 512;\n\t\tbreak;\n\t}\n\n\tuint8_t code[sizeof(pic32mx_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(pic32mx_flash_write_code),\n\t\t\tpic32mx_flash_write_code);\n\tretval = target_write_buffer(target, write_algorithm->address, sizeof(code), code);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tmips32_info.common_magic = MIPS32_COMMON_MAGIC;\n\tmips32_info.isa_mode = MIPS32_ISA_MIPS32;\n\n\tinit_reg_param(&reg_params[0], \"r4\", 32, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"r5\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r6\", 32, PARAM_OUT);\n\n\tint row_offset = offset % row_size;\n\tuint8_t *new_buffer = NULL;\n\tif (row_offset && (count >= (row_size / 4))) {\n\t\tnew_buffer = malloc(buffer_size);\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tmemset(new_buffer,  0xff, row_offset);\n\t\taddress -= row_offset;\n\t} else\n\t\trow_offset = 0;\n\n\twhile (count > 0) {\n\t\tuint32_t status;\n\t\tuint32_t thisrun_count;\n\n\t\tif (row_offset) {\n\t\t\tthisrun_count = (count > ((buffer_size - row_offset) / 4)) ?\n\t\t\t\t((buffer_size - row_offset) / 4) : count;\n\n\t\t\tmemcpy(new_buffer + row_offset, buffer, thisrun_count * 4);\n\n\t\t\tretval = target_write_buffer(target, source->address,\n\t\t\t\trow_offset + thisrun_count * 4, new_buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t} else {\n\t\t\tthisrun_count = (count > (buffer_size / 4)) ?\n\t\t\t\t\t(buffer_size / 4) : count;\n\n\t\t\tretval = target_write_buffer(target, source->address,\n\t\t\t\t\tthisrun_count * 4, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, virt2phys(source->address));\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, virt2phys(address));\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count + row_offset / 4);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\t0, 10000, &mips32_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing pic32mx flash write algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tstatus = buf_get_u32(reg_params[0].value, 0, 32);\n\n\t\tif (status & NVMCON_NVMERR) {\n\t\t\tLOG_ERROR(\"Flash write error NVMERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (status & NVMCON_LVDERR) {\n\t\t\tLOG_ERROR(\"Flash write error LVDERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count * 4;\n\t\taddress += thisrun_count * 4;\n\t\tcount -= thisrun_count;\n\t\tif (row_offset) {\n\t\t\taddress += row_offset;\n\t\t\trow_offset = 0;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\n\tfree(new_buffer);\n\treturn retval;\n}\n\nstatic int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)\n{\n\tstruct target *target = bank->target;\n\n\ttarget_write_u32(target, PIC32MX_NVMADDR, virt2phys(address));\n\ttarget_write_u32(target, PIC32MX_NVMDATA, word);\n\n\treturn pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);\n}\n\nstatic int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tuint32_t words_remaining = (count / 4);\n\tuint32_t bytes_remaining = (count & 0x00000003);\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tuint32_t status;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"writing to flash at address \" TARGET_ADDR_FMT \" at offset 0x%8.8\" PRIx32\n\t\t\t\" count: 0x%8.8\" PRIx32 \"\", bank->base, offset, count);\n\n\tif (offset & 0x3) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \"breaks required 4-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* multiple words (4-byte) to be programmed? */\n\tif (words_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = pic32mx_write_block(bank, buffer, offset, words_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) single dword accesses */\n\t\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t} else if (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\t\t\tLOG_ERROR(\"flash writing failed\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += words_remaining * 4;\n\t\t\taddress += words_remaining * 4;\n\t\t\twords_remaining = 0;\n\t\t}\n\t}\n\n\twhile (words_remaining > 0) {\n\t\tuint32_t value;\n\t\tmemcpy(&value, buffer + bytes_written, sizeof(uint32_t));\n\n\t\tstatus = pic32mx_write_word(bank, address, value);\n\n\t\tif (status & NVMCON_NVMERR) {\n\t\t\tLOG_ERROR(\"Flash write error NVMERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tif (status & NVMCON_LVDERR) {\n\t\t\tLOG_ERROR(\"Flash write error LVDERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tbytes_written += 4;\n\t\twords_remaining--;\n\t\taddress += 4;\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint32_t value = 0xffffffff;\n\t\tmemcpy(&value, buffer + bytes_written, bytes_remaining);\n\n\t\tstatus = pic32mx_write_word(bank, address, value);\n\n\t\tif (status & NVMCON_NVMERR) {\n\t\t\tLOG_ERROR(\"Flash write error NVMERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tif (status & NVMCON_LVDERR) {\n\t\t\tLOG_ERROR(\"Flash write error LVDERR (status = 0x%08\" PRIx32 \")\", status);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int pic32mx_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;\n\tstruct mips32_common *mips32 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tint i;\n\tuint32_t num_pages = 0;\n\tuint32_t device_id;\n\tint page_size;\n\n\tpic32mx_info->probed = false;\n\n\tdevice_id = ejtag_info->idcode;\n\tLOG_INFO(\"device id = 0x%08\" PRIx32 \" (manuf 0x%03x dev 0x%04x, ver 0x%02x)\",\n\t\t\t  device_id,\n\t\t\t  (unsigned)((device_id >> 1) & 0x7ff),\n\t\t\t  (unsigned)((device_id >> 12) & 0xffff),\n\t\t\t  (unsigned)((device_id >> 28) & 0xf));\n\n\tif (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {\n\t\tLOG_WARNING(\"Cannot identify target as a PIC32MX family.\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Check for PIC32mx1xx/2xx */\n\tfor (i = 0; pic32mx_devs[i].name; i++) {\n\t\tif (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {\n\t\t\tif ((pic32mx_devs[i].name[0] == '1') || (pic32mx_devs[i].name[0] == '2'))\n\t\t\t\tpic32mx_info->dev_type = (pic32mx_devs[i].name[1] == '7') ? MX_17X_27X : MX_1XX_2XX;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tswitch (pic32mx_info->dev_type) {\n\tcase\tMX_1XX_2XX:\n\tcase\tMX_17X_27X:\n\t\tpage_size = 1024;\n\t\tbreak;\n\tdefault:\n\t\tpage_size = 4096;\n\t\tbreak;\n\t}\n\n\tif (virt2phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH) {\n\t\t/* 0x1FC00000: Boot flash size */\n#if 0\n\t\t/* for some reason this register returns 8k for the boot bank size\n\t\t * this does not match the docs, so for now set the boot bank at a\n\t\t * fixed 12k */\n\t\tif (target_read_u32(target, PIC32MX_BMXBOOTSZ, &num_pages) != ERROR_OK) {\n\t\t\tLOG_WARNING(\"PIC32MX flash size failed, probe inaccurate - assuming 12k flash\");\n\t\t\tnum_pages = (12 * 1024);\n\t\t}\n#else\n\t\t/* fixed 12k boot bank - see comments above */\n\t\tswitch (pic32mx_info->dev_type) {\n\t\tcase\tMX_1XX_2XX:\n\t\tcase\tMX_17X_27X:\n\t\t\tnum_pages = (3 * 1024);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tnum_pages = (12 * 1024);\n\t\t\tbreak;\n\t\t}\n#endif\n\t} else {\n\t\t/* read the flash size from the device */\n\t\tif (target_read_u32(target, PIC32MX_BMXPFMSZ, &num_pages) != ERROR_OK) {\n\t\t\tswitch (pic32mx_info->dev_type) {\n\t\t\tcase\tMX_1XX_2XX:\n\t\t\tcase\tMX_17X_27X:\n\t\t\t\tLOG_WARNING(\"PIC32MX flash size failed, probe inaccurate - assuming 32k flash\");\n\t\t\t\tnum_pages = (32 * 1024);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_WARNING(\"PIC32MX flash size failed, probe inaccurate - assuming 512k flash\");\n\t\t\t\tnum_pages = (512 * 1024);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_INFO(\"flash size = %\" PRIu32 \" KiB\", num_pages / 1024);\n\n\tfree(bank->sectors);\n\n\t/* calculate numbers of pages */\n\tnum_pages /= page_size;\n\tbank->size = (num_pages * page_size);\n\tbank->num_sectors = num_pages;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_pages);\n\n\tfor (i = 0; i < (int)num_pages; i++) {\n\t\tbank->sectors[i].offset = i * page_size;\n\t\tbank->sectors[i].size = page_size;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\tpic32mx_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int pic32mx_auto_probe(struct flash_bank *bank)\n{\n\tstruct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;\n\tif (pic32mx_info->probed)\n\t\treturn ERROR_OK;\n\treturn pic32mx_probe(bank);\n}\n\nstatic int pic32mx_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct target *target = bank->target;\n\tstruct mips32_common *mips32 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tuint32_t device_id;\n\n\tdevice_id = ejtag_info->idcode;\n\n\tif (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {\n\t\tcommand_print_sameline(cmd,\n\t\t\t\t\"Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\\n\",\n\t\t\t\t(unsigned)((device_id >> 1) & 0x7ff),\n\t\t\t\tPIC32MX_MANUF_ID);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tint i;\n\tfor (i = 0; pic32mx_devs[i].name; i++) {\n\t\tif (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {\n\t\t\tcommand_print_sameline(cmd, \"PIC32MX%s\", pic32mx_devs[i].name);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!pic32mx_devs[i].name)\n\t\tcommand_print_sameline(cmd, \"Unknown\");\n\n\tcommand_print_sameline(cmd, \" Ver: 0x%02x\",\n\t\t\t(unsigned)((device_id >> 28) & 0xf));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(pic32mx_handle_pgm_word_command)\n{\n\tuint32_t address, value;\n\tint status, res;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (address < bank->base || address >= (bank->base + bank->size)) {\n\t\tcommand_print(CMD, \"flash address '%s' is out of bounds\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tres = ERROR_OK;\n\tstatus = pic32mx_write_word(bank, address, value);\n\tif (status & NVMCON_NVMERR)\n\t\tres = ERROR_FLASH_OPERATION_FAILED;\n\tif (status & NVMCON_LVDERR)\n\t\tres = ERROR_FLASH_OPERATION_FAILED;\n\n\tif (res == ERROR_OK)\n\t\tcommand_print(CMD, \"pic32mx pgm word complete\");\n\telse\n\t\tcommand_print(CMD, \"pic32mx pgm word failed (status = 0x%x)\", status);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(pic32mx_handle_unlock_command)\n{\n\tstruct target *target = NULL;\n\tstruct mips_m4k_common *mips_m4k;\n\tstruct mips_ejtag *ejtag_info;\n\tint timeout = 10;\n\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"pic32mx unlock <bank>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget = bank->target;\n\tmips_m4k = target_to_m4k(target);\n\tejtag_info = &mips_m4k->mips32.ejtag_info;\n\n\t/* we have to use the MTAP to perform a full erase */\n\tmips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);\n\tmips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);\n\n\t/* first check status of device */\n\tuint8_t mchip_cmd = MCHP_STATUS;\n\tmips_ejtag_drscan_8(ejtag_info, &mchip_cmd);\n\tif (mchip_cmd & (1 << 7)) {\n\t\t/* device is not locked */\n\t\tcommand_print(CMD, \"pic32mx is already unlocked, erasing anyway\");\n\t}\n\n\t/* unlock/erase device */\n\tmips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);\n\tjtag_add_sleep(200);\n\n\tmips_ejtag_drscan_8_out(ejtag_info, MCHP_ERASE);\n\n\tdo {\n\t\tmchip_cmd = MCHP_STATUS;\n\t\tmips_ejtag_drscan_8(ejtag_info, &mchip_cmd);\n\t\tif (timeout-- == 0) {\n\t\t\tLOG_DEBUG(\"timeout waiting for unlock: 0x%\" PRIx8 \"\", mchip_cmd);\n\t\t\tbreak;\n\t\t}\n\t\talive_sleep(1);\n\t} while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));\n\n\tmips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);\n\n\t/* select ejtag tap */\n\tmips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);\n\n\tcommand_print(CMD, \"pic32mx unlocked.\\n\"\n\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\"for the new settings to take effect.\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration pic32mx_exec_command_handlers[] = {\n\t{\n\t\t.name = \"pgm_word\",\n\t\t.usage = \"<addr> <value> <bank>\",\n\t\t.handler = pic32mx_handle_pgm_word_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"program a word\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = pic32mx_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[bank_id]\",\n\t\t.help = \"Unlock/Erase entire device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration pic32mx_command_handlers[] = {\n\t{\n\t\t.name = \"pic32mx\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"pic32mx flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = pic32mx_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver pic32mx_flash = {\n\t.name = \"pic32mx\",\n\t.commands = pic32mx_command_handlers,\n\t.flash_bank_command = pic32mx_flash_bank_command,\n\t.erase = pic32mx_erase,\n\t.protect = pic32mx_protect,\n\t.write = pic32mx_write,\n\t.read = default_flash_read,\n\t.probe = pic32mx_probe,\n\t.auto_probe = pic32mx_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = pic32mx_protect_check,\n\t.info = pic32mx_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/psoc4.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *                                                                         *\n *   Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) *\n *   vanekt@fbl.cz                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <jtag/jtag.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n/* device documents:\n\n PSoC(R) 4: PSoC 4200 Family Datasheet\n\tDocument Number: 001-87197 Rev. *B  Revised August 29, 2013\n\n PSoC 4100/4200 Family PSoC(R) 4 Architecture TRM\n\tDocument No. 001-85634 Rev. *E June 28, 2016\n\n PSoC(R) 4 Registers TRM Spec.\n\tDocument No. 001-85847 Rev. *A June 25, 2013\n\n PSoC 4000 Family PSoC(R) 4 Technical Reference Manual\n\tDocument No. 001-89309 Rev. *B May 9, 2016\n\n PSoC 41XX_BLE/42XX_BLE Family PSoC 4 BLE Architecture TRM\n\tDocument No. 001-92738 Rev. *C February 12, 2016\n\n PSoC 4200L Family PSoC 4 Architecture TRM\n\tDocument No. 001-97952 Rev. *A December 15, 2015\n\n PSoC 4200L Family PSoC 4 Registers TRM\n\tDocument No. 001-98126 Rev. *A December 16, 2015\n\n PSoC 4100M/4200M Family PSoC 4 Architecture TRM\n\tDocument No. 001-95223 Rev. *B July 29, 2015\n\n PSoC 4100S Family PSoC 4 Architecture TRM\n\tDocument No. 002-10621 Rev. *A July 29, 2016\n\n PSoC 4100S Family PSoC 4 Registers TRM\n\tDocument No. 002-10523 Rev. *A July 20, 2016\n\n PSoC Analog Coprocessor Architecture TRM\n\tDocument No. 002-10404 Rev. ** December 18, 2015\n\n CY8C4Axx PSoC Analog Coprocessor Registers TRM\n\tDocument No. 002-10405 Rev. ** December 18, 2015\n\n CY8C41xx, CY8C42xx Programming Specifications\n\tDocument No. 001-81799 Rev. *C March 4, 2014\n\n CYBL10x6x, CY8C4127_BL, CY8C4247_BL Programming Specifications\n\tDocument No. 001-91508 Rev. *B September 22, 2014\n\n http://dmitry.gr/index.php?r=05.Projects&proj=24.%20PSoC4%20confidential\n*/\n\n/* register locations */\n#define PSOC4_SFLASH_MACRO0\t\t0x0FFFF000\n\n#define PSOC4_CPUSS_SYSREQ_LEGACY\t0x40000004\n#define PSOC4_CPUSS_SYSARG_LEGACY\t0x40000008\n#define PSOC4_SPCIF_GEOMETRY_LEGACY\t0x400E0000\n\n#define PSOC4_CPUSS_SYSREQ_NEW\t\t0x40100004\n#define PSOC4_CPUSS_SYSARG_NEW\t\t0x40100008\n#define PSOC4_SPCIF_GEOMETRY_NEW\t0x40110000\n\n#define PSOC4_TEST_MODE\t\t\t0x40030014\n\n#define PSOC4_ROMTABLE_PID0\t\t0xF0000FE0\n\n\n/* constants */\n#define PSOC4_SFLASH_MACRO_SIZE\t\t0x800\n#define PSOC4_ROWS_PER_MACRO\t\t512\n\n#define PSOC4_SROM_KEY1\t\t\t0xb6\n#define PSOC4_SROM_KEY2\t\t\t0xd3\n#define PSOC4_SROM_SYSREQ_BIT\t\t(1<<31)\n#define PSOC4_SROM_HMASTER_BIT\t\t(1<<30)\n#define PSOC4_SROM_PRIVILEGED_BIT\t(1<<28)\n#define PSOC4_SROM_STATUS_SUCCEEDED\t0xa0000000\n#define PSOC4_SROM_STATUS_FAILED\t0xf0000000\n#define PSOC4_SROM_STATUS_MASK\t\t0xf0000000\n\n/* not documented in any TRM */\n#define PSOC4_SROM_ERR_IMO_NOT_IMPLEM\t0xf0000013\n\n#define PSOC4_CMD_GET_SILICON_ID\t0\n#define PSOC4_CMD_LOAD_LATCH\t\t4\n#define PSOC4_CMD_WRITE_ROW\t\t5\n#define PSOC4_CMD_PROGRAM_ROW\t\t6\n#define PSOC4_CMD_ERASE_ALL\t\t0xa\n#define PSOC4_CMD_CHECKSUM\t\t0xb\n#define PSOC4_CMD_WRITE_PROTECTION\t0xd\n#define PSOC4_CMD_SET_IMO48\t\t0x15\n#define PSOC4_CMD_WRITE_SFLASH_ROW\t0x18\n\n#define PSOC4_CHIP_PROT_VIRGIN\t\t0x0\n#define PSOC4_CHIP_PROT_OPEN\t\t0x1\n#define PSOC4_CHIP_PROT_PROTECTED\t0x2\n#define PSOC4_CHIP_PROT_KILL\t\t0x4\n\n#define PSOC4_ROMTABLE_DESIGNER_CHECK\t0xb4\n\n#define PSOC4_FAMILY_FLAG_LEGACY\t1\n\nstruct psoc4_chip_family {\n\tuint16_t id;\n\tconst char *name;\n\tuint32_t flags;\n};\n\nstatic const struct psoc4_chip_family psoc4_families[] = {\n\t{ 0x93, \"PSoC4100/4200\",           .flags = PSOC4_FAMILY_FLAG_LEGACY },\n\t{ 0x9A, \"PSoC4000\",                .flags = 0 },\n\t{ 0x9E, \"PSoC/PRoC BLE (119E)\",    .flags = 0 },\n\t{ 0xA0, \"PSoC4200L\",               .flags = 0 },\n\t{ 0xA1, \"PSoC4100M/4200M\",         .flags = 0 },\n\t{ 0xA3, \"PSoC/PRoC BLE (11A3)\",    .flags = 0 },\n\t{ 0xA9, \"PSoC4000S\",               .flags = 0 },\n\t{ 0xAA, \"PSoC/PRoC BLE (11AA)\",    .flags = 0 },\n\t{ 0xAB, \"PSoC4100S\",               .flags = 0 },\n\t{ 0xAC, \"PSoC Analog Coprocessor\", .flags = 0 },\n\t{ 0,    \"Unknown\",                 .flags = 0 }\n};\n\n\nstruct psoc4_flash_bank {\n\tuint32_t row_size;\n\tuint32_t user_bank_size;\n\tunsigned int num_macros;\n\tbool probed;\n\tuint8_t cmd_program_row;\n\tuint16_t family_id;\n\tbool legacy_family;\n\tuint32_t cpuss_sysreq_addr;\n\tuint32_t cpuss_sysarg_addr;\n\tuint32_t spcif_geometry_addr;\n};\n\n\nstatic const struct psoc4_chip_family *psoc4_family_by_id(uint16_t family_id)\n{\n\tconst struct psoc4_chip_family *p = psoc4_families;\n\twhile (p->id && p->id != family_id)\n\t\tp++;\n\n\treturn p;\n}\n\nstatic const char *psoc4_decode_chip_protection(uint8_t protection)\n{\n\tswitch (protection) {\n\tcase PSOC4_CHIP_PROT_VIRGIN:\n\t\treturn \"protection VIRGIN\";\n\tcase PSOC4_CHIP_PROT_OPEN:\n\t\treturn \"protection open\";\n\tcase PSOC4_CHIP_PROT_PROTECTED:\n\t\treturn \"PROTECTED\";\n\tcase PSOC4_CHIP_PROT_KILL:\n\t\treturn \"protection KILL\";\n\tdefault:\n\t\tLOG_WARNING(\"Unknown protection state 0x%02\" PRIx8 \"\", protection);\n\t\treturn \"\";\n\t}\n}\n\n\n/* flash bank <name> psoc <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command)\n{\n\tstruct psoc4_flash_bank *psoc4_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tpsoc4_info = calloc(1, sizeof(struct psoc4_flash_bank));\n\n\tbank->driver_priv = psoc4_info;\n\tbank->default_padded_value = bank->erased_value = 0x00;\n\tpsoc4_info->user_bank_size = bank->size;\n\tpsoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW;\n\n\treturn ERROR_OK;\n}\n\n\n/* PSoC 4 system ROM request\n *  Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service\n *  in sysrem ROM. Algorithm just waits for NMI to finish.\n *  When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.\n *  Otherwise address of memory parameter block is set in CPUSS_SYSARG\n *  and the first parameter is written to the first word of parameter block\n */\nstatic int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd,\n\t\tuint16_t cmd_param,\n\t\tuint32_t *sysreq_params, uint32_t sysreq_params_size,\n\t\tuint32_t *sysarg_out)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tstruct working_area *sysreq_wait_algorithm;\n\tstruct working_area *sysreq_mem;\n\n\tstruct reg_param reg_params[1];\n\tstruct armv7m_algorithm armv7m_info;\n\n\tint retval = ERROR_OK;\n\n\tuint32_t param1 = PSOC4_SROM_KEY1\n\t\t\t | ((PSOC4_SROM_KEY2 + cmd) << 8)\n\t\t\t | (cmd_param << 16);\n\n\tstatic uint8_t psoc4_sysreq_wait_code[] = {\n\t\t/* system request NMI is served immediately after algo run\n       now we are done: break */\n\t\t0x00, 0xbe,\t\t/* bkpt 0 */\n\t};\n\n\tconst int code_words = (sizeof(psoc4_sysreq_wait_code) + 3) / 4;\n\t\t\t\t\t/* stack must be aligned */\n\tconst int stack_size = 256;\n\t/* tested stack sizes on PSoC4200:\n\t\tERASE_ALL\t144\n\t\tPROGRAM_ROW\t112\n\t\tother sysreq\t 68\n\t*/\n\n\t/* allocate area for sysreq wait code and stack */\n\tif (target_alloc_working_area(target, code_words * 4 + stack_size,\n\t\t\t&sysreq_wait_algorithm) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no working area for sysreq code\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Write the code */\n\tretval = target_write_buffer(target,\n\t\t\tsysreq_wait_algorithm->address,\n\t\t\tsizeof(psoc4_sysreq_wait_code),\n\t\t\tpsoc4_sysreq_wait_code);\n\tif (retval != ERROR_OK) {\n\t\t/* we already allocated the writing code, but failed to get a\n\t\t * buffer, free the algorithm */\n\t\tgoto cleanup_algo;\n\t}\n\n\tif (sysreq_params_size) {\n\t\tLOG_DEBUG(\"SYSREQ %02\" PRIx8 \" %04\" PRIx16 \" %08\" PRIx32 \" size %\" PRIu32,\n\t\t\tcmd, cmd_param, param1, sysreq_params_size);\n\t\t/* Allocate memory for sysreq_params */\n\t\tretval = target_alloc_working_area(target, sysreq_params_size, &sysreq_mem);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_WARNING(\"no working area for sysreq parameters\");\n\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\tgoto cleanup_algo;\n\t\t}\n\n\t\t/* Write sysreq_params */\n\t\ttarget_buffer_set_u32(target, (uint8_t *)sysreq_params, param1);\n\t\tretval = target_write_buffer(target, sysreq_mem->address,\n\t\t\t\tsysreq_params_size, (uint8_t *)sysreq_params);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup_mem;\n\n\t\t/* Set address of sysreq parameters block */\n\t\tretval = target_write_u32(target, psoc4_info->cpuss_sysarg_addr, sysreq_mem->address);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup_mem;\n\n\t} else {\n\t\t/* Sysreq without memory block of parameters */\n\t\tLOG_DEBUG(\"SYSREQ %02\" PRIx8 \" %04\" PRIx16 \" %08\" PRIx32,\n\t\t\tcmd, cmd_param, param1);\n\t\t/* Set register parameter */\n\t\tretval = target_write_u32(target, psoc4_info->cpuss_sysarg_addr, param1);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup_mem;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* sysreq stack */\n\tinit_reg_param(&reg_params[0], \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32,\n\t\t    sysreq_wait_algorithm->address + sysreq_wait_algorithm->size);\n\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tif (!armv7m) {\n\t\t/* something is very wrong if armv7m is NULL */\n\t\tLOG_ERROR(\"unable to get armv7m target\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto cleanup;\n\t}\n\n\t/* Set SROM request */\n\tretval = target_write_u32(target, psoc4_info->cpuss_sysreq_addr,\n\t\t\t\t  PSOC4_SROM_SYSREQ_BIT | PSOC4_SROM_HMASTER_BIT | cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup;\n\n\t/* Execute wait code */\n\tretval = target_run_algorithm(target, 0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\tsysreq_wait_algorithm->address, 0, 1000, &armv7m_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"sysreq wait code execution failed\");\n\t\tgoto cleanup;\n\t}\n\n\tuint32_t sysarg_out_tmp;\n\tretval = target_read_u32(target, psoc4_info->cpuss_sysarg_addr, &sysarg_out_tmp);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup;\n\n\tif (sysarg_out) {\n\t\t*sysarg_out = sysarg_out_tmp;\n\t\t/* If result is an error, do not show now, let caller to decide */\n\t} else if ((sysarg_out_tmp & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {\n\t\tLOG_ERROR(\"sysreq error 0x%\" PRIx32, sysarg_out_tmp);\n\t\tretval = ERROR_FAIL;\n\t}\ncleanup:\n\tdestroy_reg_param(&reg_params[0]);\n\ncleanup_mem:\n\tif (sysreq_params_size)\n\t\ttarget_free_working_area(target, sysreq_mem);\n\ncleanup_algo:\n\ttarget_free_working_area(target, sysreq_wait_algorithm);\n\n\treturn retval;\n}\n\n\n/* helper routine to get silicon ID from a PSoC 4 chip */\nstatic int psoc4_get_silicon_id(struct flash_bank *bank, uint32_t *silicon_id, uint16_t *family_id, uint8_t *protection)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tuint32_t part0, part1;\n\n\tint retval = psoc4_sysreq(bank, PSOC4_CMD_GET_SILICON_ID, 0, NULL, 0, &part0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((part0 & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {\n\t\tLOG_ERROR(\"sysreq error 0x%\" PRIx32, part0);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target_read_u32(target, psoc4_info->cpuss_sysreq_addr, &part1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* build ID as Cypress sw does:\n\t * bit 31..16 silicon ID\n\t * bit 15..8  revision ID (so far 0x11 for all devices)\n\t * bit 7..0   family ID (lowest 8 bits)\n\t */\n\tif (silicon_id)\n\t\t\t*silicon_id = ((part0 & 0x0000ffff) << 16)\n\t\t\t\t    | ((part0 & 0x00ff0000) >> 8)\n\t\t\t\t    | (part1 & 0x000000ff);\n\n\tif (family_id)\n\t\t\t*family_id = part1 & 0x0fff;\n\n\tif (protection)\n\t\t\t*protection = (part1 >> 12) & 0x0f;\n\n\treturn ERROR_OK;\n}\n\n\nstatic int psoc4_get_family(struct target *target, uint16_t *family_id)\n{\n\tint retval, i;\n\tuint32_t pidbf[3];\n\tuint8_t pid[3];\n\n\tretval = target_read_memory(target, PSOC4_ROMTABLE_PID0, 4, 3, (uint8_t *)pidbf);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < 3; i++) {\n\t\tuint32_t tmp = target_buffer_get_u32(target, (uint8_t *)(pidbf + i));\n\t\tif (tmp & 0xffffff00) {\n\t\t\tLOG_ERROR(\"Unexpected data in ROMTABLE\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tpid[i] = tmp & 0xff;\n\t}\n\n\tuint16_t family = pid[0] | ((pid[1] & 0xf) << 8);\n\tuint32_t designer = ((pid[1] & 0xf0) >> 4) | ((pid[2] & 0xf) << 4);\n\n\tif (designer != PSOC4_ROMTABLE_DESIGNER_CHECK) {\n\t\tLOG_ERROR(\"ROMTABLE designer is not Cypress\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*family_id = family;\n\treturn ERROR_OK;\n}\n\n\nstatic int psoc4_flash_prepare(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint16_t family_id;\n\tint retval;\n\n\t/* get family ID from SROM call */\n\tretval = psoc4_get_silicon_id(bank, NULL, &family_id, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* and check with family ID from ROMTABLE */\n\tif (family_id != psoc4_info->family_id) {\n\t\tLOG_ERROR(\"Family mismatch\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!psoc4_info->legacy_family) {\n\t\tuint32_t sysreq_status;\n\t\tretval = psoc4_sysreq(bank, PSOC4_CMD_SET_IMO48, 0, NULL, 0, &sysreq_status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((sysreq_status & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {\n\t\t\t/* This undocumented error code is returned probably when\n\t\t\t * PSOC4_CMD_SET_IMO48 command is not implemented.\n\t\t\t * Can be safely ignored, programming works.\n\t\t\t */\n\t\t\tif (sysreq_status == PSOC4_SROM_ERR_IMO_NOT_IMPLEM)\n\t\t\t\tLOG_INFO(\"PSOC4_CMD_SET_IMO48 is not implemented on this device.\");\n\t\t\telse {\n\t\t\t\tLOG_ERROR(\"sysreq error 0x%\" PRIx32, sysreq_status);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int psoc4_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tuint32_t prot_addr = PSOC4_SFLASH_MACRO0;\n\tint retval;\n\tuint8_t bf[PSOC4_ROWS_PER_MACRO/8];\n\tunsigned int s = 0;\n\n\tfor (unsigned int m = 0; m < psoc4_info->num_macros; m++, prot_addr += PSOC4_SFLASH_MACRO_SIZE) {\n\t\tretval = target_read_memory(target, prot_addr, 4, PSOC4_ROWS_PER_MACRO/32, bf);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (unsigned int i = 0; i < PSOC4_ROWS_PER_MACRO && s < bank->num_sectors; i++, s++)\n\t\t\tbank->sectors[s].is_protected = bf[i/8] & (1 << (i%8)) ? 1 : 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int psoc4_mass_erase(struct flash_bank *bank)\n{\n\tint retval = psoc4_flash_prepare(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Call \"Erase All\" system ROM API */\n\tuint32_t param = 0;\n\treturn psoc4_sysreq(bank, PSOC4_CMD_ERASE_ALL,\n\t\t\t0,\n\t\t\t&param, sizeof(param), NULL);\n}\n\n\nstatic int psoc4_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\tif (psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW) {\n\t\tLOG_INFO(\"Autoerase enabled, erase command ignored\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1)))\n\t\treturn psoc4_mass_erase(bank);\n\n\tLOG_ERROR(\"Only mass erase available! Consider using 'psoc4 flash_autoerase 0 on'\");\n\n\treturn ERROR_FAIL;\n}\n\n\nstatic int psoc4_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tif (!psoc4_info->probed)\n\t\treturn ERROR_FAIL;\n\n\tint retval = psoc4_flash_prepare(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t *sysrq_buffer = NULL;\n\tconst int param_sz = 8;\n\tint chip_prot = PSOC4_CHIP_PROT_OPEN;\n\tunsigned int i;\n\tunsigned int num_bits = bank->num_sectors;\n\n\tif (num_bits > PSOC4_ROWS_PER_MACRO)\n\t\tnum_bits = PSOC4_ROWS_PER_MACRO;\n\n\tint prot_sz = num_bits / 8;\n\n\tsysrq_buffer = malloc(param_sz + prot_sz);\n\tif (!sysrq_buffer) {\n\t\tLOG_ERROR(\"no memory for row buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = first; i <= last && i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = set;\n\n\tfor (unsigned int m = 0, sect = 0; m < psoc4_info->num_macros; m++) {\n\t\tuint8_t *p = (uint8_t *)(sysrq_buffer + 2);\n\t\tmemset(p, 0, prot_sz);\n\t\tfor (i = 0; i < num_bits && sect < bank->num_sectors; i++, sect++) {\n\t\t\tif (bank->sectors[sect].is_protected)\n\t\t\t\tp[i/8] |= 1 << (i%8);\n\t\t}\n\n\t\t/* Call \"Load Latch\" system ROM API */\n\t\ttarget_buffer_set_u32(target, (uint8_t *)(sysrq_buffer + 1),\n\t\t\t\t\tprot_sz - 1);\n\t\tretval = psoc4_sysreq(bank, PSOC4_CMD_LOAD_LATCH,\n\t\t\t0\t/* Byte number in latch from what to write */\n\t\t\t  | (m << 8), /* flash macro index */\n\t\t\tsysrq_buffer, param_sz + prot_sz,\n\t\t\tNULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Call \"Write Protection\" system ROM API */\n\t\tretval = psoc4_sysreq(bank, PSOC4_CMD_WRITE_PROTECTION,\n\t\t\tchip_prot | (m << 8), NULL, 0, NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\tfree(sysrq_buffer);\n\n\tpsoc4_protect_check(bank);\n\treturn retval;\n}\n\n\nCOMMAND_HANDLER(psoc4_handle_flash_autoerase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\tbool enable = psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW;\n\n\tif (CMD_ARGC >= 2)\n\t\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);\n\n\tif (enable) {\n\t\tpsoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW;\n\t\tLOG_INFO(\"Flash auto-erase enabled, non mass erase commands will be ignored.\");\n\t} else {\n\t\tpsoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW;\n\t\tLOG_INFO(\"Flash auto-erase disabled. Use psoc mass_erase before flash programming.\");\n\t}\n\n\treturn retval;\n}\n\n\nstatic int psoc4_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\tuint32_t *sysrq_buffer = NULL;\n\tconst int param_sz = 8;\n\n\tint retval = psoc4_flash_prepare(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tsysrq_buffer = malloc(param_sz + psoc4_info->row_size);\n\tif (!sysrq_buffer) {\n\t\tLOG_ERROR(\"no memory for row buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t *row_buffer = (uint8_t *)sysrq_buffer + param_sz;\n\tuint32_t row_num = offset / psoc4_info->row_size;\n\tuint32_t row_offset = offset - row_num * psoc4_info->row_size;\n\tif (row_offset)\n\t\tmemset(row_buffer, bank->default_padded_value, row_offset);\n\n\twhile (count) {\n\t\tuint32_t chunk_size = psoc4_info->row_size - row_offset;\n\t\tif (chunk_size > count) {\n\t\t\tchunk_size = count;\n\t\t\tmemset(row_buffer + chunk_size, bank->default_padded_value, psoc4_info->row_size - chunk_size);\n\t\t}\n\t\tmemcpy(row_buffer + row_offset, buffer, chunk_size);\n\t\tLOG_DEBUG(\"offset / row: 0x%08\" PRIx32 \" / %\" PRIu32 \", size %\" PRIu32 \"\",\n\t\t\t\toffset, row_offset, chunk_size);\n\n\t\tuint32_t macro_idx = row_num / PSOC4_ROWS_PER_MACRO;\n\n\t\t/* Call \"Load Latch\" system ROM API */\n\t\ttarget_buffer_set_u32(target, (uint8_t *)(sysrq_buffer + 1),\n\t\t\t\t\tpsoc4_info->row_size - 1);\n\t\tretval = psoc4_sysreq(bank, PSOC4_CMD_LOAD_LATCH,\n\t\t\t\t0\t/* Byte number in latch from what to write */\n\t\t\t\t  | (macro_idx << 8),\n\t\t\t\tsysrq_buffer, param_sz + psoc4_info->row_size,\n\t\t\t\tNULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup;\n\n\t\t/* Call \"Program Row\" or \"Write Row\" system ROM API */\n\t\tuint32_t sysrq_param;\n\t\tretval = psoc4_sysreq(bank, psoc4_info->cmd_program_row,\n\t\t\t\trow_num & 0xffff,\n\t\t\t\t&sysrq_param, sizeof(sysrq_param),\n\t\t\t\tNULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup;\n\n\t\tbuffer += chunk_size;\n\t\trow_num++;\n\t\trow_offset = 0;\n\t\tcount -= chunk_size;\n\t}\n\ncleanup:\n\tfree(sysrq_buffer);\n\treturn retval;\n}\n\n\n/* Due to Cypress's method of market segmentation some devices\n * have accessible only 1/2, 1/4 or 1/8 of SPCIF described flash */\nstatic int psoc4_test_flash_wounding(struct target *target, uint32_t flash_size)\n{\n\tint retval, i;\n\tfor (i = 3; i >= 1; i--) {\n\t\tuint32_t addr = flash_size >> i;\n\t\tuint32_t dummy;\n\t\tretval = target_read_u32(target, addr, &dummy);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn i;\n\t}\n\treturn 0;\n}\n\n\nstatic int psoc4_probe(struct flash_bank *bank)\n{\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tint retval;\n\tuint16_t family_id;\n\n\tpsoc4_info->probed = false;\n\n\tretval = psoc4_get_family(target, &family_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst struct psoc4_chip_family *family = psoc4_family_by_id(family_id);\n\n\tif (family->id == 0) {\n\t\tLOG_ERROR(\"Cannot identify PSoC 4 family.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (family->flags & PSOC4_FAMILY_FLAG_LEGACY) {\n\t\tLOG_INFO(\"%s legacy family detected.\", family->name);\n\t\tpsoc4_info->legacy_family = true;\n\t\tpsoc4_info->cpuss_sysreq_addr = PSOC4_CPUSS_SYSREQ_LEGACY;\n\t\tpsoc4_info->cpuss_sysarg_addr = PSOC4_CPUSS_SYSARG_LEGACY;\n\t\tpsoc4_info->spcif_geometry_addr = PSOC4_SPCIF_GEOMETRY_LEGACY;\n\t} else {\n\t\tLOG_INFO(\"%s family detected.\", family->name);\n\t\tpsoc4_info->legacy_family = false;\n\t\tpsoc4_info->cpuss_sysreq_addr = PSOC4_CPUSS_SYSREQ_NEW;\n\t\tpsoc4_info->cpuss_sysarg_addr = PSOC4_CPUSS_SYSARG_NEW;\n\t\tpsoc4_info->spcif_geometry_addr = PSOC4_SPCIF_GEOMETRY_NEW;\n\t}\n\n\tuint32_t spcif_geometry;\n\tretval = target_read_u32(target, psoc4_info->spcif_geometry_addr, &spcif_geometry);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t flash_size_in_kb = spcif_geometry & 0x3fff;\n\t/* TRM of legacy, M and L version describes FLASH field as 16-bit.\n\t * S-series and PSoC Analog Coprocessor changes spec to 14-bit only.\n\t * Impose PSoC Analog Coprocessor limit to all devices as it\n\t * does not make any harm: flash size is safely below 4 MByte limit\n\t */\n\tuint32_t row_size = (spcif_geometry >> 22) & 3;\n\tuint32_t num_macros = (spcif_geometry >> 20) & 3;\n\n\tif (psoc4_info->legacy_family) {\n\t\tflash_size_in_kb = flash_size_in_kb * 256 / 1024;\n\t\trow_size *= 128;\n\t} else {\n\t\tflash_size_in_kb = (flash_size_in_kb + 1) * 256 / 1024;\n\t\trow_size = 64 * (row_size + 1);\n\t\tnum_macros++;\n\t}\n\n\tLOG_DEBUG(\"SPCIF geometry: %\" PRIu32 \" KiB flash, row %\" PRIu32 \" bytes.\",\n\t\t flash_size_in_kb, row_size);\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (psoc4_info->user_bank_size) {\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size\");\n\t\tflash_size_in_kb = psoc4_info->user_bank_size / 1024;\n\t}\n\n\tchar macros_txt[22] = \"\";\n\tif (num_macros > 1)\n\t\tsnprintf(macros_txt, sizeof(macros_txt), \" in %\" PRIu32 \" macros\", num_macros);\n\n\tLOG_INFO(\"flash size = %\" PRIu32 \" KiB%s\", flash_size_in_kb, macros_txt);\n\n\t/* calculate number of pages */\n\tuint32_t num_rows = flash_size_in_kb * 1024 / row_size;\n\n\t/* check number of flash macros */\n\tif (num_macros != (num_rows + PSOC4_ROWS_PER_MACRO - 1) / PSOC4_ROWS_PER_MACRO)\n\t\tLOG_WARNING(\"Number of macros does not correspond with flash size!\");\n\n\tif (!psoc4_info->legacy_family) {\n\t\tint wounding = psoc4_test_flash_wounding(target, num_rows * row_size);\n\t\tif (wounding > 0) {\n\t\t\tflash_size_in_kb = flash_size_in_kb >> wounding;\n\t\t\tnum_rows = num_rows >> wounding;\n\t\t\tLOG_INFO(\"WOUNDING detected: accessible flash size %\" PRIu32 \" kbytes\", flash_size_in_kb);\n\t\t}\n\t}\n\n\tfree(bank->sectors);\n\n\tpsoc4_info->family_id = family_id;\n\tpsoc4_info->num_macros = num_macros;\n\tpsoc4_info->row_size = row_size;\n\tbank->base = 0x00000000;\n\tbank->size = num_rows * row_size;\n\tbank->num_sectors = num_rows;\n\tbank->sectors = alloc_block_array(0, row_size, num_rows);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"flash bank set %\" PRIu32 \" rows\", num_rows);\n\tpsoc4_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc4_auto_probe(struct flash_bank *bank)\n{\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\tif (psoc4_info->probed)\n\t\treturn ERROR_OK;\n\treturn psoc4_probe(bank);\n}\n\n\nstatic int get_psoc4_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc4_flash_bank *psoc4_info = bank->driver_priv;\n\n\tif (!psoc4_info->probed)\n\t\treturn ERROR_FAIL;\n\n\tconst struct psoc4_chip_family *family = psoc4_family_by_id(psoc4_info->family_id);\n\tuint32_t size_in_kb = bank->size / 1024;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print_sameline(cmd, \"%s, flash %\" PRIu32 \" kb\"\n\t\t\t\" (halt target to see details)\", family->name, size_in_kb);\n\t\treturn ERROR_OK;\n\t}\n\n\tuint32_t silicon_id;\n\tuint16_t family_id;\n\tuint8_t protection;\n\n\tint retval = psoc4_get_silicon_id(bank, &silicon_id, &family_id, &protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (family_id != psoc4_info->family_id)\n\t\tcommand_print_sameline(cmd, \"Family id mismatch 0x%02\" PRIx16\n\t\t\t\"/0x%02\" PRIx16 \", silicon id 0x%08\" PRIx32,\n\t\t\tpsoc4_info->family_id, family_id, silicon_id);\n\telse {\n\t\tcommand_print_sameline(cmd, \"%s silicon id 0x%08\" PRIx32 \"\",\n\t\t\tfamily->name, silicon_id);\n\t}\n\n\tconst char *prot_txt = psoc4_decode_chip_protection(protection);\n\tcommand_print_sameline(cmd, \", flash %\" PRIu32 \" kb %s\", size_in_kb, prot_txt);\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(psoc4_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc4_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"psoc mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"psoc mass erase failed\");\n\n\treturn retval;\n}\n\n\nstatic const struct command_registration psoc4_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = psoc4_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"flash_autoerase\",\n\t\t.handler = psoc4_handle_flash_autoerase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id on|off\",\n\t\t.help = \"Set autoerase mode for flash bank.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration psoc4_command_handlers[] = {\n\t{\n\t\t.name = \"psoc4\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"PSoC 4 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = psoc4_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver psoc4_flash = {\n\t.name = \"psoc4\",\n\t.commands = psoc4_command_handlers,\n\t.flash_bank_command = psoc4_flash_bank_command,\n\t.erase = psoc4_erase,\n\t.protect = psoc4_protect,\n\t.write = psoc4_write,\n\t.read = default_flash_read,\n\t.probe = psoc4_probe,\n\t.auto_probe = psoc4_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = psoc4_protect_check,\n\t.info = get_psoc4_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/psoc5lp.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * PSoC 5LP flash driver\n *\n * Copyright (c) 2016 Andreas Färber\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/time_support.h>\n#include <target/armv7m.h>\n\n#define PM_ACT_CFG0             0x400043A0\n#define PM_ACT_CFG12            0x400043AC\n#define SPC_CPU_DATA            0x40004720\n#define SPC_SR                  0x40004722\n#define PRT1_PC2                0x4000500A\n#define PHUB_CH0_BASIC_CFG      0x40007010\n#define PHUB_CH0_ACTION         0x40007014\n#define PHUB_CH0_BASIC_STATUS   0x40007018\n#define PHUB_CH1_BASIC_CFG      0x40007020\n#define PHUB_CH1_ACTION         0x40007024\n#define PHUB_CH1_BASIC_STATUS   0x40007028\n#define PHUB_CFGMEM0_CFG0       0x40007600\n#define PHUB_CFGMEM0_CFG1       0x40007604\n#define PHUB_CFGMEM1_CFG0       0x40007608\n#define PHUB_CFGMEM1_CFG1       0x4000760C\n#define PHUB_TDMEM0_ORIG_TD0    0x40007800\n#define PHUB_TDMEM0_ORIG_TD1    0x40007804\n#define PHUB_TDMEM1_ORIG_TD0    0x40007808\n#define PHUB_TDMEM1_ORIG_TD1    0x4000780C\n#define PANTHER_DEVICE_ID       0x4008001C\n\n/* NVL is not actually mapped to the Cortex-M address space\n * As we need a base address different from other banks in the device\n * we use the address of NVL programming data in Cypress images */\n#define NVL_META_BASE\t\t\t0x90000000\n\n#define PM_ACT_CFG12_EN_EE (1 << 4)\n\n#define SPC_KEY1 0xB6\n#define SPC_KEY2 0xD3\n\n#define SPC_LOAD_BYTE           0x00\n#define SPC_LOAD_MULTI_BYTE     0x01\n#define SPC_LOAD_ROW            0x02\n#define SPC_READ_BYTE           0x03\n#define SPC_READ_MULTI_BYTE     0x04\n#define SPC_WRITE_ROW           0x05\n#define SPC_WRITE_USER_NVL      0x06\n#define SPC_PRG_ROW             0x07\n#define SPC_ERASE_SECTOR        0x08\n#define SPC_ERASE_ALL           0x09\n#define SPC_READ_HIDDEN_ROW     0x0A\n#define SPC_PROGRAM_PROTECT_ROW 0x0B\n#define SPC_GET_CHECKSUM        0x0C\n#define SPC_GET_TEMP            0x0E\n#define SPC_READ_VOLATILE_BYTE  0x10\n\n#define SPC_ARRAY_ALL      0x3F\n#define SPC_ARRAY_EEPROM   0x40\n#define SPC_ARRAY_NVL_USER 0x80\n#define SPC_ARRAY_NVL_WO   0xF8\n\n#define SPC_ROW_PROTECTION 0\n\n#define SPC_OPCODE_LEN 3\n\n#define SPC_SR_DATA_READY (1 << 0)\n#define SPC_SR_IDLE       (1 << 1)\n\n#define PM_ACT_CFG0_EN_CLK_SPC      (1 << 3)\n\n#define PHUB_CHX_BASIC_CFG_EN       (1 << 0)\n#define PHUB_CHX_BASIC_CFG_WORK_SEP (1 << 5)\n\n#define PHUB_CHX_ACTION_CPU_REQ (1 << 0)\n\n#define PHUB_CFGMEMX_CFG0 (1 << 7)\n\n#define PHUB_TDMEMX_ORIG_TD0_NEXT_TD_PTR_LAST (0xff << 16)\n#define PHUB_TDMEMX_ORIG_TD0_INC_SRC_ADDR     (1 << 24)\n\n#define NVL_3_ECCEN  (1 << 3)\n\n#define ROW_SIZE           256\n#define ROW_ECC_SIZE       32\n#define ROWS_PER_SECTOR    64\n#define SECTOR_SIZE        (ROWS_PER_SECTOR * ROW_SIZE)\n#define ROWS_PER_BLOCK     256\n#define BLOCK_SIZE         (ROWS_PER_BLOCK * ROW_SIZE)\n#define SECTORS_PER_BLOCK  (BLOCK_SIZE / SECTOR_SIZE)\n#define EEPROM_ROW_SIZE    16\n#define EEPROM_SECTOR_SIZE (ROWS_PER_SECTOR * EEPROM_ROW_SIZE)\n#define EEPROM_BLOCK_SIZE  (ROWS_PER_BLOCK * EEPROM_ROW_SIZE)\n\n#define PART_NUMBER_LEN (17 + 1)\n\nstruct psoc5lp_device {\n\tuint32_t id;\n\tunsigned fam;\n\tunsigned speed_mhz;\n\tunsigned flash_kb;\n\tunsigned eeprom_kb;\n};\n\n/*\n * Device information collected from datasheets.\n * Different temperature ranges (C/I/Q/A) may share IDs, not differing otherwise.\n */\nstatic const struct psoc5lp_device psoc5lp_devices[] = {\n\t/* CY8C58LP Family Datasheet */\n\t{ .id = 0x2E11F069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E120069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E123069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E124069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E126069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E127069, .fam = 8, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E117069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E118069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E119069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E11C069, .fam = 8, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E114069, .fam = 8, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E115069, .fam = 8, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E116069, .fam = 8, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E160069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t/*           ''                                                               */\n\t{ .id = 0x2E161069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t/*           ''                                                               */\n\t{ .id = 0x2E1D2069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E1D6069, .fam = 8, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\n\t/* CY8C56LP Family Datasheet */\n\t{ .id = 0x2E10A069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E10D069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E10E069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E106069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E108069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E109069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E101069, .fam = 6, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E104069, .fam = 6, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t/*           ''                                                               */\n\t{ .id = 0x2E105069, .fam = 6, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E128069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t/*           ''                                                               */\n\t{ .id = 0x2E122069, .fam = 6, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E129069, .fam = 6, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E163069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E156069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E1D3069, .fam = 6, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\n\t/* CY8C54LP Family Datasheet */\n\t{ .id = 0x2E11A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E16A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E12A069, .fam = 4, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E103069, .fam = 4, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E16C069, .fam = 4, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E102069, .fam = 4, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E148069, .fam = 4, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E155069, .fam = 4, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E16B069, .fam = 4, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E12B069, .fam = 4, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E168069, .fam = 4, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E178069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E15D069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E1D4069, .fam = 4, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\n\t/* CY8C52LP Family Datasheet */\n\t{ .id = 0x2E11E069, .fam = 2, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E12F069, .fam = 2, .speed_mhz = 67, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E133069, .fam = 2, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E159069, .fam = 2, .speed_mhz = 67, .flash_kb = 128, .eeprom_kb = 2 },\n\t{ .id = 0x2E11D069, .fam = 2, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E121069, .fam = 2, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E184069, .fam = 2, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E196069, .fam = 2, .speed_mhz = 67, .flash_kb =  64, .eeprom_kb = 2 },\n\t{ .id = 0x2E132069, .fam = 2, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E138069, .fam = 2, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E13A069, .fam = 2, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E152069, .fam = 2, .speed_mhz = 67, .flash_kb =  32, .eeprom_kb = 2 },\n\t{ .id = 0x2E15F069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E15A069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n\t{ .id = 0x2E1D5069, .fam = 2, .speed_mhz = 80, .flash_kb = 256, .eeprom_kb = 2 },\n};\n\nstatic void psoc5lp_get_part_number(const struct psoc5lp_device *dev, char *str)\n{\n\tstrcpy(str, \"CY8Cabcdefg-LPxxx\");\n\n\tstr[4] = '5';\n\tstr[5] = '0' + dev->fam;\n\n\tswitch (dev->speed_mhz) {\n\tcase 67:\n\t\tstr[6] = '6';\n\t\tbreak;\n\tcase 80:\n\t\tstr[6] = '8';\n\t\tbreak;\n\tdefault:\n\t\tstr[6] = '?';\n\t}\n\n\tswitch (dev->flash_kb) {\n\tcase 32:\n\t\tstr[7] = '5';\n\t\tbreak;\n\tcase 64:\n\t\tstr[7] = '6';\n\t\tbreak;\n\tcase 128:\n\t\tstr[7] = '7';\n\t\tbreak;\n\tcase 256:\n\t\tstr[7] = '8';\n\t\tbreak;\n\tdefault:\n\t\tstr[7] = '?';\n\t}\n\n\t/* Package does not matter. */\n\tstr[8] = 'x';\n\tstr[9] = 'x';\n\n\t/* Temperate range cannot uniquely be identified. */\n\tstr[10] = 'x';\n}\n\nstatic int psoc5lp_get_device_id(struct target *target, uint32_t *id)\n{\n\tint retval;\n\n\tretval = target_read_u32(target, PANTHER_DEVICE_ID, id); /* dummy read */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_read_u32(target, PANTHER_DEVICE_ID, id);\n\treturn retval;\n}\n\nstatic int psoc5lp_find_device(struct target *target,\n\tconst struct psoc5lp_device **device)\n{\n\tuint32_t device_id;\n\tunsigned i;\n\tint retval;\n\n\t*device = NULL;\n\n\tretval = psoc5lp_get_device_id(target, &device_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"PANTHER_DEVICE_ID = 0x%08\" PRIX32, device_id);\n\n\tfor (i = 0; i < ARRAY_SIZE(psoc5lp_devices); i++) {\n\t\tif (psoc5lp_devices[i].id == device_id) {\n\t\t\t*device = &psoc5lp_devices[i];\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"Device 0x%08\" PRIX32 \" not supported\", device_id);\n\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n}\n\nstatic int psoc5lp_spc_enable_clock(struct target *target)\n{\n\tint retval;\n\tuint8_t pm_act_cfg0;\n\n\tretval = target_read_u8(target, PM_ACT_CFG0, &pm_act_cfg0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read PM_ACT_CFG0\");\n\t\treturn retval;\n\t}\n\n\tif (pm_act_cfg0 & PM_ACT_CFG0_EN_CLK_SPC)\n\t\treturn ERROR_OK;\t/* clock already enabled */\n\n\tretval = target_write_u8(target, PM_ACT_CFG0, pm_act_cfg0 | PM_ACT_CFG0_EN_CLK_SPC);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Cannot enable SPC clock\");\n\n\treturn retval;\n}\n\nstatic int psoc5lp_spc_write_opcode(struct target *target, uint8_t opcode)\n{\n\tint retval;\n\n\tretval = target_write_u8(target, SPC_CPU_DATA, SPC_KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, SPC_KEY2 + opcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, opcode);\n\treturn retval;\n}\n\nstatic void psoc5lp_spc_write_opcode_buffer(struct target *target,\n\tuint8_t *buf, uint8_t opcode)\n{\n\tbuf[0] = SPC_KEY1;\n\tbuf[1] = SPC_KEY2 + opcode;\n\tbuf[2] = opcode;\n}\n\nstatic int psoc5lp_spc_busy_wait_data(struct target *target)\n{\n\tint64_t endtime;\n\tuint8_t sr;\n\tint retval;\n\n\tretval = target_read_u8(target, SPC_SR, &sr); /* dummy read */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tendtime = timeval_ms() + 1000; /* 1 second timeout */\n\tdo {\n\t\talive_sleep(1);\n\t\tretval = target_read_u8(target, SPC_SR, &sr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (sr == SPC_SR_DATA_READY)\n\t\t\treturn ERROR_OK;\n\t} while (timeval_ms() < endtime);\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int psoc5lp_spc_busy_wait_idle(struct target *target)\n{\n\tint64_t endtime;\n\tuint8_t sr;\n\tint retval;\n\n\tretval = target_read_u8(target, SPC_SR, &sr); /* dummy read */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tendtime = timeval_ms() + 1000; /* 1 second timeout */\n\tdo {\n\t\talive_sleep(1);\n\t\tretval = target_read_u8(target, SPC_SR, &sr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (sr == SPC_SR_IDLE)\n\t\t\treturn ERROR_OK;\n\t} while (timeval_ms() < endtime);\n\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int psoc5lp_spc_load_byte(struct target *target,\n\tuint8_t array_id, uint8_t offset, uint8_t value)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_LOAD_BYTE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, offset);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_load_row(struct target *target,\n\tuint8_t array_id, const uint8_t *data, unsigned row_size)\n{\n\tunsigned i;\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_LOAD_ROW);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < row_size; i++) {\n\t\tretval = target_write_u8(target, SPC_CPU_DATA, data[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_read_byte(struct target *target,\n\tuint8_t array_id, uint8_t offset, uint8_t *data)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_READ_BYTE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, offset);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_data(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u8(target, SPC_CPU_DATA, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_write_row(struct target *target,\n\tuint8_t array_id, uint16_t row_id, const uint8_t *temp)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_WRITE_ROW);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, row_id >> 8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, row_id & 0xff);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, temp[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, temp[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_write_user_nvl(struct target *target,\n\tuint8_t array_id)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_WRITE_USER_NVL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_erase_sector(struct target *target,\n\tuint8_t array_id, uint8_t row_id)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_ERASE_SECTOR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, row_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_erase_all(struct target *target)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_ERASE_ALL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_read_hidden_row(struct target *target,\n\tuint8_t array_id, uint8_t row_id, uint8_t *data)\n{\n\tint i, retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_READ_HIDDEN_ROW);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, row_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_data(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < ROW_SIZE; i++) {\n\t\tretval = target_read_u8(target, SPC_CPU_DATA, &data[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_get_temp(struct target *target, uint8_t samples,\n\tuint8_t *data)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_GET_TEMP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, samples);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_data(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u8(target, SPC_CPU_DATA, &data[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_read_u8(target, SPC_CPU_DATA, &data[1]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_spc_read_volatile_byte(struct target *target,\n\tuint8_t array_id, uint8_t offset, uint8_t *data)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_write_opcode(target, SPC_READ_VOLATILE_BYTE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, array_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u8(target, SPC_CPU_DATA, offset);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_data(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u8(target, SPC_CPU_DATA, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n/*\n * NV Latch\n */\n\nstruct psoc5lp_nvl_flash_bank {\n\tbool probed;\n\tconst struct psoc5lp_device *device;\n};\n\nstatic int psoc5lp_nvl_read(struct flash_bank *bank,\n\tuint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint retval;\n\n\tretval = psoc5lp_spc_enable_clock(bank->target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (count > 0) {\n\t\tretval = psoc5lp_spc_read_byte(bank->target,\n\t\t\t\tSPC_ARRAY_NVL_USER, offset, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbuffer++;\n\t\toffset++;\n\t\tcount--;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_nvl_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tLOG_WARNING(\"There is no erase operation for NV Latches\");\n\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n}\n\nstatic int psoc5lp_nvl_erase_check(struct flash_bank *bank)\n{\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_erased = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_nvl_write(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t byte_count)\n{\n\tstruct target *target = bank->target;\n\tuint8_t *current_data, val;\n\tbool write_required = false, pullup_needed = false, ecc_changed = false;\n\tuint32_t i;\n\tint retval;\n\n\tif (offset != 0 || byte_count != bank->size) {\n\t\tLOG_ERROR(\"NVL can only be written in whole\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tcurrent_data = calloc(1, bank->size);\n\tif (!current_data)\n\t\treturn ERROR_FAIL;\n\tretval = psoc5lp_nvl_read(bank, current_data, offset, byte_count);\n\tif (retval != ERROR_OK) {\n\t\tfree(current_data);\n\t\treturn retval;\n\t}\n\tfor (i = offset; i < byte_count; i++) {\n\t\tif (current_data[i] != buffer[i]) {\n\t\t\twrite_required = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (((buffer[2] & 0x80) == 0x80) && ((current_data[0] & 0x0C) != 0x08))\n\t\tpullup_needed = true;\n\tif (((buffer[3] ^ current_data[3]) & 0x08) == 0x08)\n\t\tecc_changed = true;\n\tfree(current_data);\n\n\tif (!write_required) {\n\t\tLOG_INFO(\"Unchanged, skipping NVL write\");\n\t\treturn ERROR_OK;\n\t}\n\tif (pullup_needed) {\n\t\tretval = target_read_u8(target, PRT1_PC2, &val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tval &= 0xF0;\n\t\tval |= 0x05;\n\t\tretval = target_write_u8(target, PRT1_PC2, val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (i = offset; i < byte_count; i++) {\n\t\tretval = psoc5lp_spc_load_byte(target,\n\t\t\t\tSPC_ARRAY_NVL_USER, i, buffer[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = psoc5lp_spc_read_volatile_byte(target,\n\t\t\t\tSPC_ARRAY_NVL_USER, i, &val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (val != buffer[i]) {\n\t\t\tLOG_ERROR(\"Failed to load NVL byte %\" PRIu32 \": \"\n\t\t\t\t\"expected 0x%02\" PRIx8 \", read 0x%02\" PRIx8,\n\t\t\t\ti, buffer[i], val);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tretval = psoc5lp_spc_write_user_nvl(target, SPC_ARRAY_NVL_USER);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ecc_changed) {\n\t\tretval = target_call_reset_callbacks(target, RESET_INIT);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_WARNING(\"Reset failed after enabling or disabling ECC\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_nvl_get_info_command(struct flash_bank *bank,\n\tstruct command_invocation *cmd)\n{\n\tstruct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;\n\tchar part_number[PART_NUMBER_LEN];\n\n\tpsoc5lp_get_part_number(psoc_nvl_bank->device, part_number);\n\n\tcommand_print_sameline(cmd, \"%s\", part_number);\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_nvl_probe(struct flash_bank *bank)\n{\n\tstruct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;\n\tint retval;\n\n\tif (psoc_nvl_bank->probed)\n\t\treturn ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = psoc5lp_find_device(bank->target, &psoc_nvl_bank->device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tbank->base = NVL_META_BASE;\n\tbank->size = 4;\n\tbank->num_sectors = 1;\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t       sizeof(struct flash_sector));\n\tbank->sectors[0].offset = 0;\n\tbank->sectors[0].size = 4;\n\tbank->sectors[0].is_erased = -1;\n\tbank->sectors[0].is_protected = -1;\n\n\tpsoc_nvl_bank->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_nvl_auto_probe(struct flash_bank *bank)\n{\n\tstruct psoc5lp_nvl_flash_bank *psoc_nvl_bank = bank->driver_priv;\n\n\tif (psoc_nvl_bank->probed)\n\t\treturn ERROR_OK;\n\n\treturn psoc5lp_nvl_probe(bank);\n}\n\nFLASH_BANK_COMMAND_HANDLER(psoc5lp_nvl_flash_bank_command)\n{\n\tstruct psoc5lp_nvl_flash_bank *psoc_nvl_bank;\n\n\tpsoc_nvl_bank = malloc(sizeof(struct psoc5lp_nvl_flash_bank));\n\tif (!psoc_nvl_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tpsoc_nvl_bank->probed = false;\n\n\tbank->driver_priv = psoc_nvl_bank;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver psoc5lp_nvl_flash = {\n\t.name = \"psoc5lp_nvl\",\n\t.flash_bank_command = psoc5lp_nvl_flash_bank_command,\n\t.info = psoc5lp_nvl_get_info_command,\n\t.probe = psoc5lp_nvl_probe,\n\t.auto_probe = psoc5lp_nvl_auto_probe,\n\t.read = psoc5lp_nvl_read,\n\t.erase = psoc5lp_nvl_erase,\n\t.erase_check = psoc5lp_nvl_erase_check,\n\t.write = psoc5lp_nvl_write,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n\n/*\n * EEPROM\n */\n\nstruct psoc5lp_eeprom_flash_bank {\n\tbool probed;\n\tconst struct psoc5lp_device *device;\n};\n\nstatic int psoc5lp_eeprom_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = psoc5lp_spc_erase_sector(bank->target,\n\t\t\t\tSPC_ARRAY_EEPROM, i);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_eeprom_write(struct flash_bank *bank,\n\tconst uint8_t *buffer, uint32_t offset, uint32_t byte_count)\n{\n\tstruct target *target = bank->target;\n\tuint8_t temp[2];\n\tunsigned row;\n\tint retval;\n\n\tif (offset % EEPROM_ROW_SIZE != 0) {\n\t\tLOG_ERROR(\"Writes must be row-aligned, got offset 0x%08\" PRIx32,\n\t\t\toffset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tretval = psoc5lp_spc_get_temp(target, 3, temp);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to read Die temperature\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"Get_Temp: sign 0x%02\" PRIx8 \", magnitude 0x%02\" PRIx8,\n\t\ttemp[0], temp[1]);\n\n\tfor (row = offset / EEPROM_ROW_SIZE; byte_count >= EEPROM_ROW_SIZE; row++) {\n\t\tretval = psoc5lp_spc_load_row(target, SPC_ARRAY_EEPROM,\n\t\t\t\tbuffer, EEPROM_ROW_SIZE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = psoc5lp_spc_write_row(target, SPC_ARRAY_EEPROM,\n\t\t\t\trow, temp);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += EEPROM_ROW_SIZE;\n\t\tbyte_count -= EEPROM_ROW_SIZE;\n\t\toffset += EEPROM_ROW_SIZE;\n\t}\n\tif (byte_count > 0) {\n\t\tuint8_t buf[EEPROM_ROW_SIZE];\n\n\t\tmemcpy(buf, buffer, byte_count);\n\t\tmemset(buf + byte_count, bank->default_padded_value,\n\t\t\t\tEEPROM_ROW_SIZE - byte_count);\n\n\t\tLOG_DEBUG(\"Padding %\" PRIu32 \" bytes\", EEPROM_ROW_SIZE - byte_count);\n\t\tretval = psoc5lp_spc_load_row(target, SPC_ARRAY_EEPROM,\n\t\t\t\tbuf, EEPROM_ROW_SIZE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = psoc5lp_spc_write_row(target, SPC_ARRAY_EEPROM,\n\t\t\t\trow, temp);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_eeprom_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;\n\tchar part_number[PART_NUMBER_LEN];\n\n\tpsoc5lp_get_part_number(psoc_eeprom_bank->device, part_number);\n\n\tcommand_print_sameline(cmd, \"%s\", part_number);\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_eeprom_probe(struct flash_bank *bank)\n{\n\tstruct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;\n\tuint32_t flash_addr = bank->base;\n\tuint32_t val;\n\tint retval;\n\n\tif (psoc_eeprom_bank->probed)\n\t\treturn ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = psoc5lp_find_device(bank->target, &psoc_eeprom_bank->device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(bank->target, PM_ACT_CFG12, &val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (!(val & PM_ACT_CFG12_EN_EE)) {\n\t\tval |= PM_ACT_CFG12_EN_EE;\n\t\tretval = target_write_u32(bank->target, PM_ACT_CFG12, val);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tbank->size = psoc_eeprom_bank->device->eeprom_kb * 1024;\n\tbank->num_sectors = DIV_ROUND_UP(bank->size, EEPROM_SECTOR_SIZE);\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t       sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].size = EEPROM_SECTOR_SIZE;\n\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\n\t\tflash_addr += bank->sectors[i].size;\n\t}\n\n\tbank->default_padded_value = bank->erased_value = 0x00;\n\n\tpsoc_eeprom_bank->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_eeprom_auto_probe(struct flash_bank *bank)\n{\n\tstruct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank = bank->driver_priv;\n\n\tif (psoc_eeprom_bank->probed)\n\t\treturn ERROR_OK;\n\n\treturn psoc5lp_eeprom_probe(bank);\n}\n\nFLASH_BANK_COMMAND_HANDLER(psoc5lp_eeprom_flash_bank_command)\n{\n\tstruct psoc5lp_eeprom_flash_bank *psoc_eeprom_bank;\n\n\tpsoc_eeprom_bank = malloc(sizeof(struct psoc5lp_eeprom_flash_bank));\n\tif (!psoc_eeprom_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tpsoc_eeprom_bank->probed = false;\n\tpsoc_eeprom_bank->device = NULL;\n\n\tbank->driver_priv = psoc_eeprom_bank;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver psoc5lp_eeprom_flash = {\n\t.name = \"psoc5lp_eeprom\",\n\t.flash_bank_command = psoc5lp_eeprom_flash_bank_command,\n\t.info = psoc5lp_eeprom_get_info_command,\n\t.probe = psoc5lp_eeprom_probe,\n\t.auto_probe = psoc5lp_eeprom_auto_probe,\n\t.read = default_flash_read,\n\t.erase = psoc5lp_eeprom_erase,\n\t.erase_check = default_flash_blank_check,\n\t.write = psoc5lp_eeprom_write,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n\n/*\n * Program Flash\n */\n\nstruct psoc5lp_flash_bank {\n\tbool probed;\n\tconst struct psoc5lp_device *device;\n\tbool ecc_enabled;\n\t/* If ecc is disabled, num_sectors counts both std and ecc sectors.\n\t * If ecc is enabled, num_sectors indicates just the number of std sectors.\n\t * However ecc sector descriptors bank->sector[num_sectors..2*num_sectors-1]\n\t * are used for driver private flash operations */\n};\n\nstatic int psoc5lp_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tint retval;\n\n\tif (!psoc_bank->ecc_enabled) {\n\t\t/* Silently avoid erasing sectors twice */\n\t\tif (last >= first + bank->num_sectors / 2) {\n\t\t\tLOG_DEBUG(\"Skipping duplicate erase of sectors %u to %u\",\n\t\t\t\tfirst + bank->num_sectors / 2, last);\n\t\t\tlast = first + (bank->num_sectors / 2) - 1;\n\t\t}\n\t\t/* Check for any remaining ECC sectors */\n\t\tif (last >= bank->num_sectors / 2) {\n\t\t\tLOG_WARNING(\"Skipping erase of ECC region sectors %u to %u\",\n\t\t\t\tbank->num_sectors / 2, last);\n\t\t\tlast = (bank->num_sectors / 2) - 1;\n\t\t}\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = psoc5lp_spc_erase_sector(bank->target,\n\t\t\t\ti / SECTORS_PER_BLOCK, i % SECTORS_PER_BLOCK);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Derived from core.c:default_flash_blank_check() */\nstatic int psoc5lp_erase_check(struct flash_bank *bank)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tunsigned int num_sectors = bank->num_sectors;\n\tif (psoc_bank->ecc_enabled)\n\t\tnum_sectors *= 2;\t/* count both std and ecc sector always */\n\n\tstruct target_memory_check_block *block_array;\n\tblock_array = malloc(num_sectors * sizeof(struct target_memory_check_block));\n\tif (!block_array)\n\t\treturn ERROR_FAIL;\n\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tblock_array[i].address = bank->base + bank->sectors[i].offset;\n\t\tblock_array[i].size = bank->sectors[i].size;\n\t\tblock_array[i].result = UINT32_MAX; /* erase state unknown */\n\t}\n\n\tbool fast_check = true;\n\tfor (unsigned int i = 0; i < num_sectors; ) {\n\t\tretval = armv7m_blank_check_memory(target,\n\t\t\t\t\tblock_array + i, num_sectors - i,\n\t\t\t\t\tbank->erased_value);\n\t\tif (retval < 1) {\n\t\t\t/* Run slow fallback if the first run gives no result\n\t\t\t * otherwise use possibly incomplete results */\n\t\t\tif (i == 0)\n\t\t\t\tfast_check = false;\n\t\t\tbreak;\n\t\t}\n\t\ti += retval; /* add number of blocks done this round */\n\t}\n\n\tif (fast_check) {\n\t\tif (psoc_bank->ecc_enabled) {\n\t\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\t\t\tbank->sectors[i].is_erased =\n\t\t\t\t\t(block_array[i].result != 1)\n\t\t\t\t\t? block_array[i].result\n\t\t\t\t\t: block_array[i + bank->num_sectors].result;\n\t\t\t\t/* if std sector is erased, use status of ecc sector */\n\t\t} else {\n\t\t\tfor (unsigned int i = 0; i < num_sectors; i++)\n\t\t\t\tbank->sectors[i].is_erased = block_array[i].result;\n\t\t}\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"Can't run erase check - add working memory\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tfree(block_array);\n\n\treturn retval;\n}\n\nstatic int psoc5lp_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t byte_count)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tstruct working_area *code_area, *even_row_area, *odd_row_area;\n\tuint32_t row_size;\n\tuint8_t temp[2], buf[12], ecc_bytes[ROW_ECC_SIZE];\n\tunsigned array_id, row;\n\tint i, retval;\n\n\tif (offset + byte_count > bank->size) {\n\t\tLOG_ERROR(\"Writing to ECC not supported\");\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\t}\n\n\tif (offset % ROW_SIZE != 0) {\n\t\tLOG_ERROR(\"Writes must be row-aligned, got offset 0x%08\" PRIx32,\n\t\t\toffset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\trow_size = ROW_SIZE;\n\tif (!psoc_bank->ecc_enabled) {\n\t\trow_size += ROW_ECC_SIZE;\n\t\tmemset(ecc_bytes, bank->default_padded_value, ROW_ECC_SIZE);\n\t}\n\n\tretval = psoc5lp_spc_get_temp(target, 3, temp);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to read Die temperature\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"Get_Temp: sign 0x%02\" PRIx8 \", magnitude 0x%02\" PRIx8,\n\t\ttemp[0], temp[1]);\n\n\tassert(target_get_working_area_avail(target) == target->working_area_size);\n\tretval = target_alloc_working_area(target,\n\t\t\ttarget_get_working_area_avail(target) / 2, &code_area);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not allocate working area for program SRAM\");\n\t\treturn retval;\n\t}\n\tassert(code_area->address < 0x20000000);\n\n\tretval = target_alloc_working_area(target,\n\t\t\tSPC_OPCODE_LEN + 1 + row_size + 3 + SPC_OPCODE_LEN + 6,\n\t\t\t&even_row_area);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not allocate working area for even row\");\n\t\tgoto err_alloc_even;\n\t}\n\tassert(even_row_area->address >= 0x20000000);\n\n\tretval = target_alloc_working_area(target, even_row_area->size,\n\t\t\t&odd_row_area);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not allocate working area for odd row\");\n\t\tgoto err_alloc_odd;\n\t}\n\tassert(odd_row_area->address >= 0x20000000);\n\n\tfor (array_id = offset / BLOCK_SIZE; byte_count > 0; array_id++) {\n\t\tfor (row = (offset / ROW_SIZE) % ROWS_PER_BLOCK;\n\t\t     row < ROWS_PER_BLOCK && byte_count > 0; row++) {\n\t\t\tbool even_row = (row % 2 == 0);\n\t\t\tstruct working_area *data_area = even_row ? even_row_area : odd_row_area;\n\t\t\tunsigned len = MIN(ROW_SIZE, byte_count);\n\n\t\t\tLOG_DEBUG(\"Writing load command for array %u row %u at \" TARGET_ADDR_FMT,\n\t\t\t\tarray_id, row, data_area->address);\n\n\t\t\tpsoc5lp_spc_write_opcode_buffer(target, buf, SPC_LOAD_ROW);\n\t\t\tbuf[SPC_OPCODE_LEN] = array_id;\n\t\t\tretval = target_write_buffer(target, data_area->address, 4, buf);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_write;\n\n\t\t\tretval = target_write_buffer(target,\n\t\t\t\tdata_area->address + SPC_OPCODE_LEN + 1,\n\t\t\t\tlen, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_write;\n\t\t\tbuffer += len;\n\t\t\tbyte_count -= len;\n\t\t\toffset += len;\n\n\t\t\tif (len < ROW_SIZE) {\n\t\t\t\tuint8_t padding[ROW_SIZE];\n\n\t\t\t\tmemset(padding, bank->default_padded_value, ROW_SIZE);\n\n\t\t\t\tLOG_DEBUG(\"Padding %d bytes\", ROW_SIZE - len);\n\t\t\t\tretval = target_write_buffer(target,\n\t\t\t\t\tdata_area->address + SPC_OPCODE_LEN + 1 + len,\n\t\t\t\t\tROW_SIZE - len, padding);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto err_write;\n\t\t\t}\n\n\t\t\tif (!psoc_bank->ecc_enabled) {\n\t\t\t\tretval = target_write_buffer(target,\n\t\t\t\t\tdata_area->address + SPC_OPCODE_LEN + 1 + ROW_SIZE,\n\t\t\t\t\tsizeof(ecc_bytes), ecc_bytes);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto err_write;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < 3; i++)\n\t\t\t\tbuf[i] = 0x00; /* 3 NOPs for short delay */\n\t\t\tpsoc5lp_spc_write_opcode_buffer(target, buf + 3, SPC_PRG_ROW);\n\t\t\tbuf[3 + SPC_OPCODE_LEN] = array_id;\n\t\t\tbuf[3 + SPC_OPCODE_LEN + 1] = row >> 8;\n\t\t\tbuf[3 + SPC_OPCODE_LEN + 2] = row & 0xff;\n\t\t\tmemcpy(buf + 3 + SPC_OPCODE_LEN + 3, temp, 2);\n\t\t\tbuf[3 + SPC_OPCODE_LEN + 5] = 0x00; /* padding */\n\t\t\tretval = target_write_buffer(target,\n\t\t\t\tdata_area->address + SPC_OPCODE_LEN + 1 + row_size,\n\t\t\t\t12, buf);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_write;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_CH0_BASIC_STATUS : PHUB_CH1_BASIC_STATUS,\n\t\t\t\t(even_row ? 0 : 1) << 8);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_CH0_BASIC_CFG : PHUB_CH1_BASIC_CFG,\n\t\t\t\tPHUB_CHX_BASIC_CFG_WORK_SEP | PHUB_CHX_BASIC_CFG_EN);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_CFGMEM0_CFG0 : PHUB_CFGMEM1_CFG0,\n\t\t\t\tPHUB_CFGMEMX_CFG0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_CFGMEM0_CFG1 : PHUB_CFGMEM1_CFG1,\n\t\t\t\t((SPC_CPU_DATA >> 16) << 16) | (data_area->address >> 16));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_TDMEM0_ORIG_TD0 : PHUB_TDMEM1_ORIG_TD0,\n\t\t\t\tPHUB_TDMEMX_ORIG_TD0_INC_SRC_ADDR |\n\t\t\t\tPHUB_TDMEMX_ORIG_TD0_NEXT_TD_PTR_LAST |\n\t\t\t\t((SPC_OPCODE_LEN + 1 + row_size + 3 + SPC_OPCODE_LEN + 5) & 0xfff));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_TDMEM0_ORIG_TD1 : PHUB_TDMEM1_ORIG_TD1,\n\t\t\t\t((SPC_CPU_DATA & 0xffff) << 16) | (data_area->address & 0xffff));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma;\n\n\t\t\tretval = psoc5lp_spc_busy_wait_idle(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_idle;\n\n\t\t\tretval = target_write_u32(target,\n\t\t\t\teven_row ? PHUB_CH0_ACTION : PHUB_CH1_ACTION,\n\t\t\t\tPHUB_CHX_ACTION_CPU_REQ);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err_dma_action;\n\t\t}\n\t}\n\n\tretval = psoc5lp_spc_busy_wait_idle(target);\n\nerr_dma_action:\nerr_idle:\nerr_dma:\nerr_write:\n\ttarget_free_working_area(target, odd_row_area);\nerr_alloc_odd:\n\ttarget_free_working_area(target, even_row_area);\nerr_alloc_even:\n\ttarget_free_working_area(target, code_area);\n\n\treturn retval;\n}\n\nstatic int psoc5lp_protect_check(struct flash_bank *bank)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tuint8_t row_data[ROW_SIZE];\n\tconst unsigned protection_bytes_per_sector = ROWS_PER_SECTOR * 2 / 8;\n\tunsigned i, k, num_sectors;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (i = 0; i < DIV_ROUND_UP(bank->size, BLOCK_SIZE); i++) {\n\t\tretval = psoc5lp_spc_read_hidden_row(bank->target, i,\n\t\t\t\tSPC_ROW_PROTECTION, row_data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Last flash array may have less rows, but in practice full sectors. */\n\t\tif (i == bank->size / BLOCK_SIZE)\n\t\t\tnum_sectors = (bank->size % BLOCK_SIZE) / SECTOR_SIZE;\n\t\telse\n\t\t\tnum_sectors = SECTORS_PER_BLOCK;\n\n\t\tfor (unsigned int j = 0; j < num_sectors; j++) {\n\t\t\tint sector_nr = i * SECTORS_PER_BLOCK + j;\n\t\t\tstruct flash_sector *sector = &bank->sectors[sector_nr];\n\t\t\tstruct flash_sector *ecc_sector;\n\n\t\t\tif (psoc_bank->ecc_enabled)\n\t\t\t\tecc_sector = &bank->sectors[bank->num_sectors + sector_nr];\n\t\t\telse\n\t\t\t\tecc_sector = &bank->sectors[bank->num_sectors / 2 + sector_nr];\n\n\t\t\tsector->is_protected = ecc_sector->is_protected = 0;\n\t\t\tfor (k = protection_bytes_per_sector * j;\n\t\t\t     k < protection_bytes_per_sector * (j + 1); k++) {\n\t\t\t\tassert(k < protection_bytes_per_sector * SECTORS_PER_BLOCK);\n\t\t\t\tLOG_DEBUG(\"row[%u][%02u] = 0x%02\" PRIx8, i, k, row_data[k]);\n\t\t\t\tif (row_data[k] != 0x00) {\n\t\t\t\t\tsector->is_protected = ecc_sector->is_protected = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tchar part_number[PART_NUMBER_LEN];\n\tconst char *ecc;\n\n\tpsoc5lp_get_part_number(psoc_bank->device, part_number);\n\tecc = psoc_bank->ecc_enabled ? \"ECC enabled\" : \"ECC disabled\";\n\n\tcommand_print_sameline(cmd, \"%s %s\", part_number, ecc);\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc5lp_flash_bank *psoc_bank = bank->driver_priv;\n\tuint32_t flash_addr = bank->base;\n\tuint8_t nvl[4], temp[2];\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!psoc_bank->device) {\n\t\tretval = psoc5lp_find_device(target, &psoc_bank->device);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbank->size = psoc_bank->device->flash_kb * 1024;\n\t}\n\n\tbank->num_sectors = DIV_ROUND_UP(bank->size, SECTOR_SIZE);\n\n\tif (!psoc_bank->probed) {\n\t\tretval = psoc5lp_spc_enable_clock(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* First values read are inaccurate, so do it once now. */\n\t\tretval = psoc5lp_spc_get_temp(target, 3, temp);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to read Die temperature\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tbank->sectors = calloc(bank->num_sectors * 2,\n\t\t\t\t       sizeof(struct flash_sector));\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tbank->sectors[i].size = SECTOR_SIZE;\n\t\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = -1;\n\n\t\t\tflash_addr += bank->sectors[i].size;\n\t\t}\n\t\tflash_addr = 0x48000000;\n\t\tfor (unsigned int i = bank->num_sectors; i < bank->num_sectors * 2; i++) {\n\t\t\tbank->sectors[i].size = ROWS_PER_SECTOR * ROW_ECC_SIZE;\n\t\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\t\tbank->sectors[i].is_erased = -1;\n\t\t\tbank->sectors[i].is_protected = -1;\n\n\t\t\tflash_addr += bank->sectors[i].size;\n\t\t}\n\n\t\tbank->default_padded_value = bank->erased_value = 0x00;\n\n\t\tpsoc_bank->probed = true;\n\t}\n\n\tretval = psoc5lp_spc_read_byte(target, SPC_ARRAY_NVL_USER, 3, &nvl[3]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"NVL[%d] = 0x%02\" PRIx8, 3, nvl[3]);\n\tpsoc_bank->ecc_enabled = nvl[3] & NVL_3_ECCEN;\n\n\tif (!psoc_bank->ecc_enabled)\n\t\tbank->num_sectors *= 2;\n\n\treturn ERROR_OK;\n}\n\nstatic int psoc5lp_auto_probe(struct flash_bank *bank)\n{\n\treturn psoc5lp_probe(bank);\n}\n\nCOMMAND_HANDLER(psoc5lp_handle_mass_erase_command)\n{\n\tstruct flash_bank *bank;\n\tint retval;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = psoc5lp_spc_erase_all(bank->target);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"PSoC 5LP erase succeeded\");\n\telse\n\t\tcommand_print(CMD, \"PSoC 5LP erase failed\");\n\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(psoc5lp_flash_bank_command)\n{\n\tstruct psoc5lp_flash_bank *psoc_bank;\n\n\tpsoc_bank = malloc(sizeof(struct psoc5lp_flash_bank));\n\tif (!psoc_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tpsoc_bank->probed = false;\n\tpsoc_bank->device = NULL;\n\n\tbank->driver_priv = psoc_bank;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration psoc5lp_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = psoc5lp_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase all flash data and ECC/configuration bytes, \"\n\t\t\t\"all flash protection rows, \"\n\t\t\t\"and all row latches in all flash arrays on the device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration psoc5lp_command_handlers[] = {\n\t{\n\t\t.name = \"psoc5lp\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"PSoC 5LP flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = psoc5lp_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver psoc5lp_flash = {\n\t.name = \"psoc5lp\",\n\t.commands = psoc5lp_command_handlers,\n\t.flash_bank_command = psoc5lp_flash_bank_command,\n\t.info = psoc5lp_get_info_command,\n\t.probe = psoc5lp_probe,\n\t.auto_probe = psoc5lp_auto_probe,\n\t.protect_check = psoc5lp_protect_check,\n\t.read = default_flash_read,\n\t.erase = psoc5lp_erase,\n\t.erase_check = psoc5lp_erase_check,\n\t.write = psoc5lp_write,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/psoc6.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *                                                                         *\n *   Copyright (C) 2018 by Bohdan Tymkiv                                   *\n *   bohdan.tymkiv@cypress.com bohdan200@gmail.com                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <time.h>\n\n#include \"imp.h\"\n#include \"helper/time_support.h\"\n#include \"target/arm_adi_v5.h\"\n#include \"target/target.h\"\n#include \"target/cortex_m.h\"\n#include \"target/breakpoints.h\"\n#include \"target/target_type.h\"\n#include \"target/algorithm.h\"\n\n/**************************************************************************************************\n * PSoC6 device definitions\n *************************************************************************************************/\n#define MFLASH_SECTOR_SIZE              (256u * 1024u)\n#define WFLASH_SECTOR_SIZE              (32u * 1024u)\n\n#define MEM_BASE_MFLASH                 0x10000000u\n#define MEM_BASE_WFLASH                 0x14000000u\n#define MEM_WFLASH_SIZE                 32768u\n#define MEM_BASE_SFLASH                 0x16000000u\n#define RAM_STACK_WA_SIZE               2048u\n#define PSOC6_SPCIF_GEOMETRY            0x4025F00Cu\n\n#define PROTECTION_UNKNOWN              0x00u\n#define PROTECTION_VIRGIN               0x01u\n#define PROTECTION_NORMAL               0x02u\n#define PROTECTION_SECURE               0x03u\n#define PROTECTION_DEAD                 0x04u\n\n#define MEM_BASE_IPC                    0x40230000u\n#define IPC_STRUCT_SIZE                 0x20u\n#define MEM_IPC(n)                      (MEM_BASE_IPC + (n) * IPC_STRUCT_SIZE)\n#define MEM_IPC_ACQUIRE(n)              (MEM_IPC(n) + 0x00u)\n#define MEM_IPC_NOTIFY(n)               (MEM_IPC(n) + 0x08u)\n#define MEM_IPC_DATA(n)                 (MEM_IPC(n) + 0x0Cu)\n#define MEM_IPC_LOCK_STATUS(n)          (MEM_IPC(n) + 0x10u)\n\n#define MEM_BASE_IPC_INTR               0x40231000u\n#define IPC_INTR_STRUCT_SIZE            0x20u\n#define MEM_IPC_INTR(n)                 (MEM_BASE_IPC_INTR + (n) * IPC_INTR_STRUCT_SIZE)\n#define MEM_IPC_INTR_MASK(n)            (MEM_IPC_INTR(n) + 0x08u)\n#define IPC_ACQUIRE_SUCCESS_MSK         0x80000000u\n#define IPC_LOCK_ACQUIRED_MSK           0x80000000u\n\n#define IPC_ID                          2u\n#define IPC_INTR_ID                     0u\n#define IPC_TIMEOUT_MS                  1000\n\n#define SROMAPI_SIID_REQ                    0x00000001u\n#define SROMAPI_SIID_REQ_FAMILY_REVISION    (SROMAPI_SIID_REQ | 0x000u)\n#define SROMAPI_SIID_REQ_SIID_PROTECTION    (SROMAPI_SIID_REQ | 0x100u)\n#define SROMAPI_WRITEROW_REQ                0x05000100u\n#define SROMAPI_PROGRAMROW_REQ              0x06000100u\n#define SROMAPI_ERASESECTOR_REQ             0x14000100u\n#define SROMAPI_ERASEALL_REQ                0x0A000100u\n#define SROMAPI_ERASEROW_REQ                0x1C000100u\n\n#define SROMAPI_STATUS_MSK                  0xF0000000u\n#define SROMAPI_STAT_SUCCESS                0xA0000000u\n#define SROMAPI_DATA_LOCATION_MSK           0x00000001u\n#define SROMAPI_CALL_TIMEOUT_MS             1500\n\nstruct psoc6_target_info {\n\tuint32_t silicon_id;\n\tuint8_t protection;\n\tuint32_t main_flash_sz;\n\tuint32_t row_sz;\n\tbool is_probed;\n};\n\nstruct timeout {\n\tint64_t start_time;\n\tlong timeout_ms;\n};\n\nstruct row_region {\n\tuint32_t addr;\n\tsize_t size;\n};\n\nstatic const struct row_region safe_sflash_regions[] = {\n\t{0x16000800, 0x800},\t/* SFLASH: User Data */\n\t{0x16001A00, 0x200},\t/* SFLASH: NAR */\n\t{0x16005A00, 0xC00},\t/* SFLASH: Public Key */\n\t{0x16007C00, 0x400},\t/* SFLASH: TOC2 */\n};\n\n#define SFLASH_NUM_REGIONS ARRAY_SIZE(safe_sflash_regions)\n\nstatic struct working_area *g_stack_area;\nstatic struct armv7m_algorithm g_armv7m_info;\n\n/** ***********************************************************************************************\n * @brief Initializes `struct timeout` structure with given timeout value\n * @param to pointer to `struct timeout` structure\n * @param timeout_ms timeout, in milliseconds\n *************************************************************************************************/\nstatic void timeout_init(struct timeout *to, long timeout_ms)\n{\n\tto->start_time = timeval_ms();\n\tto->timeout_ms = timeout_ms;\n}\n\n/** ***********************************************************************************************\n * @brief Returns true if given `struct timeout` structure has expired\n * @param to pointer to `struct timeout` structure\n * @return true if timeout expired\n *************************************************************************************************/\nstatic bool timeout_expired(struct timeout *to)\n{\n\treturn (timeval_ms() - to->start_time) > to->timeout_ms;\n}\n\n/** ***********************************************************************************************\n * @brief Starts pseudo flash algorithm and leaves it running. Function allocates working area for\n * algorithm code and CPU stack, adjusts stack pointer, uploads and starts the algorithm.\n * Algorithm (a basic infinite loop) runs asynchronously while driver performs Flash operations.\n *\n * @param target target for the algorithm\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int sromalgo_prepare(struct target *target)\n{\n\tint hr;\n\n\t/* Initialize Vector Table Offset register (in case FW modified it) */\n\thr = target_write_u32(target, 0xE000ED08, 0x00000000);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\t/* Allocate Working Area for Stack and Flash algorithm */\n\thr = target_alloc_working_area(target, RAM_STACK_WA_SIZE, &g_stack_area);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tg_armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tg_armv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tstruct reg_param reg_params;\n\tinit_reg_param(&reg_params, \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params.value, 0, 32, g_stack_area->address + g_stack_area->size);\n\n\t/* Write basic infinite loop algorithm to target RAM */\n\thr = target_write_u32(target, g_stack_area->address, 0xFEE7FEE7);\n\tif (hr != ERROR_OK)\n\t\tgoto destroy_rp_free_wa;\n\n\thr = target_start_algorithm(target, 0, NULL, 1, &reg_params, g_stack_area->address,\n\t\t\t0, &g_armv7m_info);\n\tif (hr != ERROR_OK)\n\t\tgoto destroy_rp_free_wa;\n\n\tdestroy_reg_param(&reg_params);\n\n\treturn hr;\n\ndestroy_rp_free_wa:\n\t/* Something went wrong, do some cleanup */\n\tdestroy_reg_param(&reg_params);\n\n\ttarget_free_working_area(target, g_stack_area);\n\tg_stack_area = NULL;\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Stops running flash algorithm and releases associated resources.\n * This function is also used for cleanup in case of errors so g_stack_area may be NULL.\n * These cases have to be handled gracefully.\n *\n * @param target current target\n *************************************************************************************************/\nstatic void sromalgo_release(struct target *target)\n{\n\tint hr = ERROR_OK;\n\n\tif (g_stack_area) {\n\t\t/* Stop flash algorithm if it is running */\n\t\tif (target->running_alg) {\n\t\t\thr = target_halt(target);\n\t\t\tif (hr != ERROR_OK)\n\t\t\t\tgoto exit_free_wa;\n\n\t\t\thr = target_wait_algorithm(target, 0, NULL, 0, NULL, 0,\n\t\t\t\t\tIPC_TIMEOUT_MS, &g_armv7m_info);\n\t\t\tif (hr != ERROR_OK)\n\t\t\t\tgoto exit_free_wa;\n\t\t}\n\nexit_free_wa:\n\t\t/* Free Stack/Flash algorithm working area */\n\t\ttarget_free_working_area(target, g_stack_area);\n\t\tg_stack_area = NULL;\n\t}\n}\n\n/** ***********************************************************************************************\n * @brief Waits for expected IPC lock status. PSoC6 uses IPC structures for inter-core\n * communication. Same IPCs are used to invoke SROM API. IPC structure must be locked prior to\n * invoking any SROM API. This ensures nothing else in the system will use same IPC thus corrupting\n * our data. Locking is performed by ipc_acquire(), this function ensures that IPC is actually\n * in expected state\n *\n * @param target current target\n * @param ipc_id IPC index to poll. IPC #2 is dedicated for DAP access\n * @param lock_expected expected lock status\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int ipc_poll_lock_stat(struct target *target, uint32_t ipc_id, bool lock_expected)\n{\n\tint hr;\n\tuint32_t reg_val;\n\n\tstruct timeout to;\n\ttimeout_init(&to, IPC_TIMEOUT_MS);\n\n\twhile (!timeout_expired(&to)) {\n\t\t/* Process any server requests */\n\t\tkeep_alive();\n\n\t\t/* Read IPC Lock status */\n\t\thr = target_read_u32(target, MEM_IPC_LOCK_STATUS(ipc_id), &reg_val);\n\t\tif (hr != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to read IPC Lock Status register\");\n\t\t\treturn hr;\n\t\t}\n\n\t\tbool is_locked = (reg_val & IPC_LOCK_ACQUIRED_MSK) != 0;\n\n\t\tif (lock_expected == is_locked)\n\t\t\treturn ERROR_OK;\n\t}\n\n\tif (target->coreid) {\n\t\tLOG_WARNING(\"SROM API calls via CM4 target are supported on single-core PSoC6 devices only. \"\n\t\t\t\"Please perform all Flash-related operations via CM0+ target on dual-core devices.\");\n\t}\n\n\tLOG_ERROR(\"Timeout polling IPC Lock Status\");\n\treturn ERROR_TARGET_TIMEOUT;\n}\n\n/** ***********************************************************************************************\n * @brief Acquires IPC structure. PSoC6 uses IPC structures for inter-core communication.\n * Same IPCs are used to invoke SROM API. IPC structure must be locked prior to invoking any SROM API.\n * This ensures nothing else in the system will use same IPC thus corrupting our data.\n * This function locks the IPC.\n *\n * @param target current target\n * @param ipc_id ipc_id IPC index to acquire. IPC #2 is dedicated for DAP access\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int ipc_acquire(struct target *target, char ipc_id)\n{\n\tint hr = ERROR_OK;\n\tbool is_acquired = false;\n\tuint32_t reg_val;\n\n\tstruct timeout to;\n\ttimeout_init(&to, IPC_TIMEOUT_MS);\n\n\twhile (!timeout_expired(&to)) {\n\t\tkeep_alive();\n\n\t\thr = target_write_u32(target, MEM_IPC_ACQUIRE(ipc_id), IPC_ACQUIRE_SUCCESS_MSK);\n\t\tif (hr != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write to IPC Acquire register\");\n\t\t\treturn hr;\n\t\t}\n\n\t\t/* Check if data is written on first step */\n\t\thr = target_read_u32(target, MEM_IPC_ACQUIRE(ipc_id), &reg_val);\n\t\tif (hr != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to read IPC Acquire register\");\n\t\t\treturn hr;\n\t\t}\n\n\t\tis_acquired = (reg_val & IPC_ACQUIRE_SUCCESS_MSK) != 0;\n\t\tif (is_acquired) {\n\t\t\t/* If IPC structure is acquired, the lock status should be set */\n\t\t\thr = ipc_poll_lock_stat(target, ipc_id, true);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!is_acquired)\n\t\tLOG_ERROR(\"Timeout acquiring IPC structure\");\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Invokes SROM API functions which are responsible for Flash operations\n *\n * @param target current target\n * @param req_and_params request id of the function to invoke\n * @param working_area address of memory buffer in target's memory space for SROM API parameters\n * @param data_out pointer to variable which will be populated with execution status\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int call_sromapi(struct target *target,\n\tuint32_t req_and_params,\n\tuint32_t working_area,\n\tuint32_t *data_out)\n{\n\tint hr;\n\n\tbool is_data_in_ram = (req_and_params & SROMAPI_DATA_LOCATION_MSK) == 0;\n\n\thr = ipc_acquire(target, IPC_ID);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tif (is_data_in_ram)\n\t\thr = target_write_u32(target, MEM_IPC_DATA(IPC_ID), working_area);\n\telse\n\t\thr = target_write_u32(target, MEM_IPC_DATA(IPC_ID), req_and_params);\n\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\t/* Enable notification interrupt of IPC_INTR_STRUCT0(CM0+) for IPC_STRUCT2 */\n\thr = target_write_u32(target, MEM_IPC_INTR_MASK(IPC_INTR_ID), 1u << (16 + IPC_ID));\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\thr = target_write_u32(target, MEM_IPC_NOTIFY(IPC_ID), 1);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\t/* Poll lock status */\n\thr = ipc_poll_lock_stat(target, IPC_ID, false);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\t/* Poll Data byte */\n\tif (is_data_in_ram)\n\t\thr = target_read_u32(target, working_area, data_out);\n\telse\n\t\thr = target_read_u32(target, MEM_IPC_DATA(IPC_ID), data_out);\n\n\tif (hr != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading SROM API Status location\");\n\t\treturn hr;\n\t}\n\n\tbool is_success = (*data_out & SROMAPI_STATUS_MSK) == SROMAPI_STAT_SUCCESS;\n\tif (!is_success) {\n\t\tLOG_ERROR(\"SROM API execution failed. Status: 0x%08\" PRIX32, *data_out);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Retrieves SiliconID and Protection status of the target device\n * @param target current target\n * @param si_id pointer to variable, will be populated with SiliconID\n * @param protection pointer to variable, will be populated with protection status\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int get_silicon_id(struct target *target, uint32_t *si_id, uint8_t *protection)\n{\n\tint hr;\n\tuint32_t family_rev, siid_prot;\n\n\thr = sromalgo_prepare(target);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\t/* Read FamilyID and Revision */\n\thr = call_sromapi(target, SROMAPI_SIID_REQ_FAMILY_REVISION, 0, &family_rev);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\t/* Read SiliconID and Protection */\n\thr = call_sromapi(target, SROMAPI_SIID_REQ_SIID_PROTECTION, 0, &siid_prot);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\t*si_id  = (siid_prot & 0x0000FFFF) << 16;\n\t*si_id |= (family_rev & 0x00FF0000) >> 8;\n\t*si_id |= (family_rev & 0x000000FF) >> 0;\n\n\t*protection = (siid_prot & 0x000F0000) >> 0x10;\n\nexit:\n\tsromalgo_release(target);\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Translates Protection status to openocd-friendly boolean value\n * @param bank current flash bank\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_protect_check(struct flash_bank *bank)\n{\n\tint is_protected;\n\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\tint hr = get_silicon_id(bank->target, &psoc6_info->silicon_id, &psoc6_info->protection);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tswitch (psoc6_info->protection) {\n\t\tcase PROTECTION_VIRGIN:\n\t\tcase PROTECTION_NORMAL:\n\t\t\tis_protected = 0;\n\t\t\tbreak;\n\n\t\tcase PROTECTION_UNKNOWN:\n\t\tcase PROTECTION_SECURE:\n\t\tcase PROTECTION_DEAD:\n\t\tdefault:\n\t\t\tis_protected = 1;\n\t\t\tbreak;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = is_protected;\n\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Dummy function, Life Cycle transition is not currently supported\n * @return ERROR_OK always\n *************************************************************************************************/\nstatic int psoc6_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\t(void)bank;\n\t(void)set;\n\t(void)first;\n\t(void)last;\n\n\tLOG_WARNING(\"Life Cycle transition for PSoC6 is not supported\");\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Translates Protection status to string\n * @param protection protection value\n * @return pointer to const string describing protection status\n *************************************************************************************************/\nstatic const char *protection_to_str(uint8_t protection)\n{\n\tswitch (protection) {\n\t\tcase PROTECTION_VIRGIN:\n\t\t\treturn \"VIRGIN\";\n\t\tcase PROTECTION_NORMAL:\n\t\t\treturn \"NORMAL\";\n\t\tcase PROTECTION_SECURE:\n\t\t\treturn \"SECURE\";\n\t\tcase PROTECTION_DEAD:\n\t\t\treturn \"DEAD\";\n\t\tcase PROTECTION_UNKNOWN:\n\t\tdefault:\n\t\t\treturn \"UNKNOWN\";\n\t}\n}\n\n/** ***********************************************************************************************\n * @brief psoc6_get_info Displays human-readable information about acquired device\n * @param bank current flash bank\n * @param cmd pointer to command invocation instance\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\n\tif (psoc6_info->is_probed == false)\n\t\treturn ERROR_FAIL;\n\n\tint hr = get_silicon_id(bank->target, &psoc6_info->silicon_id, &psoc6_info->protection);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tcommand_print_sameline(cmd,\n\t\t\"PSoC6 Silicon ID: 0x%08\" PRIX32 \"\\n\"\n\t\t\"Protection: %s\\n\"\n\t\t\"Main Flash size: %\" PRIu32 \" kB\\n\"\n\t\t\"Work Flash size: 32 kB\\n\",\n\t\tpsoc6_info->silicon_id,\n\t\tprotection_to_str(psoc6_info->protection),\n\t\tpsoc6_info->main_flash_sz / 1024);\n\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Checks if given flash bank belongs to Supervisory Flash\n * @param bank current flash bank\n * @return true if flash bank belongs to Supervisory Flash\n *************************************************************************************************/\nstatic bool is_sflash_bank(struct flash_bank *bank)\n{\n\tfor (size_t i = 0; i < SFLASH_NUM_REGIONS; i++) {\n\t\tif (bank->base == safe_sflash_regions[i].addr)\n\t\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/** ***********************************************************************************************\n * @brief Checks if given flash bank belongs to Work Flash\n * @param bank current flash bank\n * @return true if flash bank belongs to Work Flash\n *************************************************************************************************/\nstatic inline bool is_wflash_bank(struct flash_bank *bank)\n{\n\treturn (bank->base == MEM_BASE_WFLASH);\n}\n\n/** ***********************************************************************************************\n * @brief Checks if given flash bank belongs to Main Flash\n * @param bank current flash bank\n * @return true if flash bank belongs to Main Flash\n *************************************************************************************************/\nstatic inline bool is_mflash_bank(struct flash_bank *bank)\n{\n\treturn (bank->base == MEM_BASE_MFLASH);\n}\n\n/** ***********************************************************************************************\n * @brief Probes the device and populates related data structures with target flash geometry data.\n * This is done in non-intrusive way, no SROM API calls are involved so GDB can safely attach to a\n * running target. Function assumes that size of Work Flash is 32kB (true for all current part numbers)\n *\n * @param bank current flash bank\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\n\tint hr = ERROR_OK;\n\n\t/* Retrieve data from SPCIF_GEOMETRY */\n\tuint32_t geom;\n\ttarget_read_u32(target, PSOC6_SPCIF_GEOMETRY, &geom);\n\tuint32_t row_sz_lg2 = (geom & 0xF0) >> 4;\n\tuint32_t row_sz = (0x01 << row_sz_lg2);\n\tuint32_t row_cnt = 1 + ((geom & 0x00FFFF00) >> 8);\n\tuint32_t bank_cnt = 1 + ((geom & 0xFF000000) >> 24);\n\n\t/* Calculate size of Main Flash*/\n\tuint32_t flash_sz_bytes = bank_cnt * row_cnt * row_sz;\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tsize_t bank_size = 0;\n\n\tif (is_mflash_bank(bank))\n\t\tbank_size = flash_sz_bytes;\n\telse if (is_wflash_bank(bank))\n\t\tbank_size = MEM_WFLASH_SIZE;\n\telse if (is_sflash_bank(bank)) {\n\t\tfor (size_t i = 0; i < SFLASH_NUM_REGIONS; i++) {\n\t\t\tif (safe_sflash_regions[i].addr == bank->base) {\n\t\t\t\tbank_size = safe_sflash_regions[i].size;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (bank_size == 0) {\n\t\tLOG_ERROR(\"Invalid Flash Bank base address in config file\");\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tunsigned int num_sectors = bank_size / row_sz;\n\tbank->size = bank_size;\n\n\tbank->erased_value = 0;\n\tbank->default_padded_value = 0;\n\n\tbank->num_sectors = num_sectors;\n\tbank->sectors = calloc(num_sectors, sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].size = row_sz;\n\t\tbank->sectors[i].offset = i * row_sz;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\tpsoc6_info->is_probed = true;\n\tpsoc6_info->main_flash_sz = flash_sz_bytes;\n\tpsoc6_info->row_sz = row_sz;\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Probes target device only if it hasn't been probed yet\n * @param bank current flash bank\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_auto_probe(struct flash_bank *bank)\n{\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\tint hr;\n\n\tif (psoc6_info->is_probed)\n\t\thr = ERROR_OK;\n\telse\n\t\thr = psoc6_probe(bank);\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Erases single sector (256k) on target device\n * @param bank current flash bank\n * @param wa working area for SROM API parameters\n * @param addr starting address of the sector\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_erase_sector(struct flash_bank *bank, struct working_area *wa, uint32_t addr)\n{\n\tstruct target *target = bank->target;\n\n\tLOG_DEBUG(\"Erasing SECTOR @%08\" PRIX32, addr);\n\n\tint hr = target_write_u32(target, wa->address, SROMAPI_ERASESECTOR_REQ);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\thr = target_write_u32(target, wa->address + 0x04, addr);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tuint32_t data_out;\n\thr = call_sromapi(target, SROMAPI_ERASESECTOR_REQ, wa->address, &data_out);\n\tif (hr != ERROR_OK)\n\t\tLOG_ERROR(\"SECTOR @%08\" PRIX32 \" not erased!\", addr);\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Erases single row (512b) on target device\n * @param bank current flash bank\n * @param wa working area for SROM API parameters\n * @param addr starting address of the flash row\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_erase_row(struct flash_bank *bank, struct working_area *wa, uint32_t addr)\n{\n\tstruct target *target = bank->target;\n\n\tLOG_DEBUG(\"Erasing ROW @%08\" PRIX32, addr);\n\n\tint hr = target_write_u32(target, wa->address, SROMAPI_ERASEROW_REQ);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\thr = target_write_u32(target, wa->address + 0x04, addr);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tuint32_t data_out;\n\thr = call_sromapi(target, SROMAPI_ERASEROW_REQ, wa->address, &data_out);\n\tif (hr != ERROR_OK)\n\t\tLOG_ERROR(\"ROW @%08\" PRIX32 \" not erased!\", addr);\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Performs Erase operation. Function will try to use biggest erase block possible to\n * speedup the operation.\n *\n * @param bank current flash bank\n * @param first first sector to erase\n * @param last last sector to erase\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\tconst uint32_t sector_size = is_wflash_bank(bank) ? WFLASH_SECTOR_SIZE : MFLASH_SECTOR_SIZE;\n\n\tint hr;\n\tstruct working_area *wa;\n\n\tif (is_sflash_bank(bank)) {\n\t\tLOG_INFO(\"Erase operation on Supervisory Flash is not required, skipping\");\n\t\treturn ERROR_OK;\n\t}\n\n\thr = sromalgo_prepare(target);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\thr = target_alloc_working_area(target, psoc6_info->row_sz + 32, &wa);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\t/* Number of rows in single sector */\n\tconst unsigned int rows_in_sector = sector_size / psoc6_info->row_sz;\n\n\twhile (last >= first) {\n\t\t/* Erase Sector if we are on sector boundary and erase size covers whole sector */\n\t\tif ((first % rows_in_sector) == 0 &&\n\t\t\t(last - first + 1) >= rows_in_sector) {\n\t\t\thr = psoc6_erase_sector(bank, wa, bank->base + first * psoc6_info->row_sz);\n\t\t\tif (hr != ERROR_OK)\n\t\t\t\tgoto exit_free_wa;\n\n\t\t\tfirst += rows_in_sector;\n\t\t} else {\n\t\t\t/* Perform Row Erase otherwise */\n\t\t\thr = psoc6_erase_row(bank, wa, bank->base + first * psoc6_info->row_sz);\n\t\t\tif (hr != ERROR_OK)\n\t\t\t\tgoto exit_free_wa;\n\n\t\t\tfirst += 1;\n\t\t}\n\t}\n\nexit_free_wa:\n\ttarget_free_working_area(target, wa);\nexit:\n\tsromalgo_release(target);\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Programs single Flash Row\n * @param bank current flash bank\n * @param addr address of the flash row\n * @param buffer pointer to the buffer with data\n * @param is_sflash true if current flash bank belongs to Supervisory Flash\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_program_row(struct flash_bank *bank,\n\tuint32_t addr,\n\tconst uint8_t *buffer,\n\tbool is_sflash)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\tstruct working_area *wa;\n\tconst uint32_t sromapi_req = is_sflash ? SROMAPI_WRITEROW_REQ : SROMAPI_PROGRAMROW_REQ;\n\tuint32_t data_out;\n\tint hr = ERROR_OK;\n\n\tLOG_DEBUG(\"Programming ROW @%08\" PRIX32, addr);\n\n\thr = target_alloc_working_area(target, psoc6_info->row_sz + 32, &wa);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\thr = target_write_u32(target, wa->address, sromapi_req);\n\tif (hr != ERROR_OK)\n\t\tgoto exit_free_wa;\n\n\thr = target_write_u32(target,\n\t\t\twa->address + 0x04,\n\t\t\t0x106);\n\tif (hr != ERROR_OK)\n\t\tgoto exit_free_wa;\n\n\thr = target_write_u32(target, wa->address + 0x08, addr);\n\tif (hr != ERROR_OK)\n\t\tgoto exit_free_wa;\n\n\thr = target_write_u32(target, wa->address + 0x0C, wa->address + 0x10);\n\tif (hr != ERROR_OK)\n\t\tgoto exit_free_wa;\n\n\thr = target_write_buffer(target, wa->address + 0x10, psoc6_info->row_sz, buffer);\n\tif (hr != ERROR_OK)\n\t\tgoto exit_free_wa;\n\n\thr = call_sromapi(target, sromapi_req, wa->address, &data_out);\n\nexit_free_wa:\n\ttarget_free_working_area(target, wa);\n\nexit:\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Performs Program operation\n * @param bank current flash bank\n * @param buffer pointer to the buffer with data\n * @param offset starting offset in flash bank\n * @param count number of bytes in buffer\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int psoc6_program(struct flash_bank *bank,\n\tconst uint8_t *buffer,\n\tuint32_t offset,\n\tuint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct psoc6_target_info *psoc6_info = bank->driver_priv;\n\tconst bool is_sflash = is_sflash_bank(bank);\n\tint hr;\n\n\tuint8_t page_buf[psoc6_info->row_sz];\n\n\thr = sromalgo_prepare(target);\n\tif (hr != ERROR_OK)\n\t\tgoto exit;\n\n\twhile (count) {\n\t\tuint32_t row_offset = offset % psoc6_info->row_sz;\n\t\tuint32_t aligned_addr = bank->base + offset - row_offset;\n\t\tuint32_t row_bytes = MIN(psoc6_info->row_sz - row_offset, count);\n\n\t\tmemset(page_buf, 0, sizeof(page_buf));\n\t\tmemcpy(&page_buf[row_offset], buffer, row_bytes);\n\n\t\thr = psoc6_program_row(bank, aligned_addr, page_buf, is_sflash);\n\t\tif (hr != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to program Flash at address 0x%08\" PRIX32, aligned_addr);\n\t\t\tgoto exit;\n\t\t}\n\n\t\tbuffer += row_bytes;\n\t\toffset += row_bytes;\n\t\tcount -= row_bytes;\n\t}\n\nexit:\n\tsromalgo_release(target);\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Performs Mass Erase operation\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nCOMMAND_HANDLER(psoc6_handle_mass_erase_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint hr = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\thr = psoc6_erase(bank, 0, bank->num_sectors - 1);\n\n\treturn hr;\n}\n\n/** ***********************************************************************************************\n * @brief Simulates broken Vector Catch\n * Function will try to determine entry point of user application. If it succeeds it will set HW\n * breakpoint at that address, issue SW Reset and remove the breakpoint afterwards.\n * In case of CM0, SYSRESETREQ is used. This allows to reset all peripherals. Boot code will\n * reset CM4 anyway, so using SYSRESETREQ is safe here.\n * In case of CM4, VECTRESET is used instead of SYSRESETREQ to not disturb CM0 core.\n *\n * @param target current target\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nstatic int handle_reset_halt(struct target *target)\n{\n\tint hr;\n\tuint32_t reset_addr;\n\tbool is_cm0 = (target->coreid == 0);\n\n\t/* Halt target device */\n\tif (target->state != TARGET_HALTED) {\n\t\thr = target_halt(target);\n\t\tif (hr != ERROR_OK)\n\t\t\treturn hr;\n\n\t\ttarget_wait_state(target, TARGET_HALTED, IPC_TIMEOUT_MS);\n\t\tif (hr != ERROR_OK)\n\t\t\treturn hr;\n\t}\n\n\t/* Read Vector Offset register */\n\tuint32_t vt_base;\n\tconst uint32_t vt_offset_reg = is_cm0 ? 0x402102B0 : 0x402102C0;\n\thr = target_read_u32(target, vt_offset_reg, &vt_base);\n\tif (hr != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\t/* Invalid value means flash is empty */\n\tvt_base &= 0xFFFFFF00;\n\tif ((vt_base == 0) || (vt_base == 0xFFFFFF00))\n\t\treturn ERROR_OK;\n\n\t/* Read Reset Vector value*/\n\thr = target_read_u32(target, vt_base + 4, &reset_addr);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\t/* Invalid value means flash is empty */\n\tif ((reset_addr == 0) || (reset_addr == 0xFFFFFF00))\n\t\treturn ERROR_OK;\n\n\n\t/* Set breakpoint at User Application entry point */\n\thr = breakpoint_add(target, reset_addr, 2, BKPT_HARD);\n\tif (hr != ERROR_OK)\n\t\treturn hr;\n\n\tconst struct armv7m_common *cm = target_to_armv7m(target);\n\n\t/* PSoC6 reboots immediately after issuing SYSRESETREQ / VECTRESET\n\t * this disables SWD/JTAG pins momentarily and may break communication\n\t * Ignoring return value of mem_ap_write_atomic_u32 seems to be ok here */\n\tif (is_cm0) {\n\t\t/* Reset the CM0 by asserting SYSRESETREQ. This will also reset CM4 */\n\t\tLOG_INFO(\"psoc6.cm0: bkpt @0x%08\" PRIX32 \", issuing SYSRESETREQ\", reset_addr);\n\t\tmem_ap_write_atomic_u32(cm->debug_ap, NVIC_AIRCR,\n\t\t\tAIRCR_VECTKEY | AIRCR_SYSRESETREQ);\n\t} else {\n\t\tLOG_INFO(\"psoc6.cm4: bkpt @0x%08\" PRIX32 \", issuing VECTRESET\", reset_addr);\n\t\tmem_ap_write_atomic_u32(cm->debug_ap, NVIC_AIRCR,\n\t\t\tAIRCR_VECTKEY | AIRCR_VECTRESET);\n\t}\n\n\t/* Wait 100ms for bootcode and reinitialize DAP */\n\tusleep(100000);\n\tdap_dp_init(cm->debug_ap->dap);\n\n\ttarget_wait_state(target, TARGET_HALTED, IPC_TIMEOUT_MS);\n\n\t/* Remove the break point */\n\tbreakpoint_remove(target, reset_addr);\n\n\treturn ERROR_OK;\n}\n\n/** ***********************************************************************************************\n * @brief Simulates broken Vector Catch\n * Function will try to determine entry point of user application. If it succeeds it will set HW\n * breakpoint at that address, issue SW Reset and remove the breakpoint afterwards.\n * In case of CM0, SYSRESETREQ is used. This allows to reset all peripherals. Boot code will\n * reset CM4 anyway, so using SYSRESETREQ is safe here.\n * In case of CM4, VECTRESET is used instead of SYSRESETREQ to not disturb CM0 core.\n *\n * @return ERROR_OK in case of success, ERROR_XXX code otherwise\n *************************************************************************************************/\nCOMMAND_HANDLER(psoc6_handle_reset_halt)\n{\n\tif (CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\treturn handle_reset_halt(target);\n}\n\nFLASH_BANK_COMMAND_HANDLER(psoc6_flash_bank_command)\n{\n\tstruct psoc6_target_info *psoc6_info;\n\tint hr = ERROR_OK;\n\n\tif (CMD_ARGC < 6)\n\t\thr = ERROR_COMMAND_SYNTAX_ERROR;\n\telse {\n\t\tpsoc6_info = calloc(1, sizeof(struct psoc6_target_info));\n\t\tpsoc6_info->is_probed = false;\n\t\tbank->driver_priv = psoc6_info;\n\t}\n\treturn hr;\n}\n\nstatic const struct command_registration psoc6_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = psoc6_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank\",\n\t\t.help = \"Erases entire Main Flash\",\n\t},\n\t{\n\t\t.name = \"reset_halt\",\n\t\t.handler = psoc6_handle_reset_halt,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"Tries to simulate broken Vector Catch\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration psoc6_command_handlers[] = {\n\t{\n\t\t.name = \"psoc6\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"PSoC 6 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = psoc6_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver psoc6_flash = {\n\t.name = \"psoc6\",\n\t.commands = psoc6_command_handlers,\n\t.flash_bank_command = psoc6_flash_bank_command,\n\t.erase = psoc6_erase,\n\t.protect = psoc6_protect,\n\t.write = psoc6_program,\n\t.read = default_flash_read,\n\t.probe = psoc6_probe,\n\t.auto_probe = psoc6_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = psoc6_protect_check,\n\t.info = psoc6_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/qn908x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n/***************************************************************************\n *   Copyright (C) 2020 iosabi                                             *\n *   iosabi <iosabi@protonmail.com>                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <helper/crc32.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n\n/* The QN908x has two flash regions, one is the main flash region holding the\n * user code and the second one is a small (0x800 bytes) \"Flash information\n * page\" that can't be written to by the user. This page contains information\n * programmed at the factory.\n *\n * The main flash region is normally 512 KiB, there's a field in the \"Flash\n * information page\" that allows to specify for 256 KiB size chips. However, at\n * the time of writing, none of the variants in the market have 256 KiB.\n *\n * The flash is divided into blocks of 256 KiB each, therefore containing two\n * blocks. A block is subdivided into pages, of 2048 bytes. A page is the\n * smallest region that can be erased or protected independently, although it\n * is also possible to erase a whole block or both blocks. A page is subdivided\n * into 8 rows of 64 words (32-bit words). The word subdivision is only\n * relevant because DMA can write multiple words in the same row in the same\n * flash program operation.\n *\n * For the Flash information page we are only interested in the last\n * 0x100 bytes which contain a CRC-32 checksum of that 0x100 bytes long region\n * and a field stating the size of the flash. This is also a good check that\n * we are dealing with the right chip/flash configuration and is used in the\n * probe() function.\n */\n#define QN908X_FLASH_BASE\t\t\t\t\t\t0x01000000\n\n#define QN908X_FLASH_PAGE_SIZE\t\t\t\t\t2048\n#define QN908X_FLASH_PAGES_PER_BLOCK\t\t\t128\n#define QN908X_FLASH_MAX_BLOCKS\t\t\t\t\t2\n#define QN908X_FLASH_BLOCK_SIZE \\\n\t\t(QN908X_FLASH_PAGES_PER_BLOCK * QN908X_FLASH_PAGE_SIZE)\n#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS\t0x1c\n#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_SIZE\t4\n#define QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END\t\\\n\t(QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_SIZE)\n\n\n/* Flash information page memory fields. */\n#define QN908X_INFO_PAGE_BASE\t\t\t\t\t0x210b0000u\n#define QN908X_INFO_PAGE_CRC32\t\t\t\t\t(QN908X_INFO_PAGE_BASE + 0x700)\n#define QN908X_INFO_PAGE_CRC_START\t\t\t\t(QN908X_INFO_PAGE_BASE + 0x704)\n#define QN908X_INFO_PAGE_BOOTLOADER_VER\t\t\t(QN908X_INFO_PAGE_BASE + 0x704)\n#define QN908X_INFO_PAGE_FLASH_SIZE\t\t\t\t(QN908X_INFO_PAGE_BASE + 0x708)\n#define QN908X_INFO_PAGE_BLUETOOTH_ADDR\t\t\t(QN908X_INFO_PAGE_BASE + 0x7fa)\n#define QN908X_INFO_PAGE_CRC_END\t\t\t\t(QN908X_INFO_PAGE_BASE + 0x800)\n\n\n/* Possible values of the QN908X_INFO_PAGE_FLASH_SIZE field. */\nenum qn908x_info_page_flash_size {\n\tQN908X_FLASH_SIZE_512K\t\t\t\t\t= 0xfffff0ff,\n\tQN908X_FLASH_SIZE_256K\t\t\t\t\t= 0xffffe0ff,\n};\n\n/* QN908x \"Flash memory controller\", described in section 28 of the user\n * manual. In the NXP SDK this peripheral is called \"FLASH\", however we use the\n * name \"FMC\" (Flash Memory Controller) here when referring to the controller\n * to avoid confusion with other \"flash\" terms in OpenOCD. */\n#define QN908X_FMC_BASE 0x40081000u\n#define QN908X_FMC_INI_RD_EN\t\t\t\t\t\t(QN908X_FMC_BASE + 0x00)\n#define QN908X_FMC_ERASE_CTRL\t\t\t\t\t\t(QN908X_FMC_BASE + 0x04)\n#define QN908X_FMC_ERASE_TIME\t\t\t\t\t\t(QN908X_FMC_BASE + 0x08)\n#define QN908X_FMC_TIME_CTRL\t\t\t\t\t\t(QN908X_FMC_BASE + 0x0c)\n#define QN908X_FMC_SMART_CTRL\t\t\t\t\t\t(QN908X_FMC_BASE + 0x10)\n#define QN908X_FMC_INT_STAT\t\t\t\t\t\t\t(QN908X_FMC_BASE + 0x18)\n#define QN908X_FMC_LOCK_STAT_0\t\t\t\t\t\t(QN908X_FMC_BASE + 0x20)\n#define QN908X_FMC_LOCK_STAT_1\t\t\t\t\t\t(QN908X_FMC_BASE + 0x24)\n#define QN908X_FMC_LOCK_STAT_2\t\t\t\t\t\t(QN908X_FMC_BASE + 0x28)\n#define QN908X_FMC_LOCK_STAT_3\t\t\t\t\t\t(QN908X_FMC_BASE + 0x2c)\n#define QN908X_FMC_LOCK_STAT_4\t\t\t\t\t\t(QN908X_FMC_BASE + 0x30)\n#define QN908X_FMC_LOCK_STAT_5\t\t\t\t\t\t(QN908X_FMC_BASE + 0x34)\n#define QN908X_FMC_LOCK_STAT_6\t\t\t\t\t\t(QN908X_FMC_BASE + 0x38)\n#define QN908X_FMC_LOCK_STAT_7\t\t\t\t\t\t(QN908X_FMC_BASE + 0x3c)\n#define QN908X_FMC_LOCK_STAT_8\t\t\t\t\t\t(QN908X_FMC_BASE + 0x40)\n#define QN908X_FMC_STATUS1\t\t\t\t\t\t\t(QN908X_FMC_BASE + 0x48)\n#define QN908X_FMC_DEBUG_PASSWORD\t\t\t\t\t(QN908X_FMC_BASE + 0xa8)\n#define QN908X_FMC_ERASE_PASSWORD\t\t\t\t\t(QN908X_FMC_BASE + 0xac)\n\n#define QN908X_FMC_INI_RD_EN_INI_RD_EN_MASK\t\t\tBIT(0)\n\n#define QN908X_FMC_STATUS1_FSH_ERA_BUSY_L_MASK\t\tBIT(9)\n#define QN908X_FMC_STATUS1_FSH_WR_BUSY_L_MASK\t\tBIT(10)\n#define QN908X_FMC_STATUS1_FSH_ERA_BUSY_H_MASK\t\tBIT(12)\n#define QN908X_FMC_STATUS1_FSH_WR_BUSY_H_MASK\t\tBIT(13)\n#define QN908X_FMC_STATUS1_INI_RD_DONE_MASK\t\t\tBIT(15)\n#define QN908X_FMC_STATUS1_FSH_STA_MASK\t\t\t\tBIT(26)\n\n#define QN908X_FMC_ERASE_CTRL_PAGE_IDXL_SHIFT\t\t0\n#define QN908X_FMC_ERASE_CTRL_PAGE_IDXH_SHIFT\t\t8\n#define QN908X_FMC_ERASE_CTRL_HALF_ERASEL_EN_SHIFT\t28\n#define QN908X_FMC_ERASE_CTRL_HALF_ERASEH_EN_SHIFT\t29\n#define QN908X_FMC_ERASE_CTRL_PAGE_ERASEL_EN_SHIFT\t30\n#define QN908X_FMC_ERASE_CTRL_PAGE_ERASEH_EN_SHIFT\t31\n\n#define QN908X_FMC_INT_STAT_AHBL_INT_MASK\t\t\tBIT(0)\n#define QN908X_FMC_INT_STAT_LOCKL_INT_MASK\t\t\tBIT(1)\n#define QN908X_FMC_INT_STAT_ERASEL_INT_MASK\t\t\tBIT(2)\n#define QN908X_FMC_INT_STAT_WRITEL_INT_MASK\t\t\tBIT(3)\n#define QN908X_FMC_INT_STAT_WR_BUFL_INT_MASK\t\tBIT(4)\n#define QN908X_FMC_INT_STAT_WRITE_FAIL_L_INT_MASK\tBIT(5)\n#define QN908X_FMC_INT_STAT_ERASE_FAIL_L_INT_MASK\tBIT(6)\n#define QN908X_FMC_INT_STAT_AHBH_INT_MASK\t\t\tBIT(8)\n#define QN908X_FMC_INT_STAT_LOCKH_INT_MASK\t\t\tBIT(9)\n#define QN908X_FMC_INT_STAT_ERASEH_INT_MASK\t\t\tBIT(10)\n#define QN908X_FMC_INT_STAT_WRITEH_INT_MASK\t\t\tBIT(11)\n#define QN908X_FMC_INT_STAT_WR_BUFH_INT_MASK\t\tBIT(12)\n#define QN908X_FMC_INT_STAT_WRITE_FAIL_H_INT_MASK\tBIT(13)\n#define QN908X_FMC_INT_STAT_ERASE_FAIL_H_INT_MASK\tBIT(14)\n\n#define QN908X_FMC_SMART_CTRL_PRGML_EN_MASK\t\t\tBIT(0)\n#define QN908X_FMC_SMART_CTRL_PRGMH_EN_MASK\t\t\tBIT(1)\n#define QN908X_FMC_SMART_CTRL_SMART_WRITEL_EN_MASK\tBIT(2)\n#define QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK\tBIT(3)\n#define QN908X_FMC_SMART_CTRL_SMART_ERASEL_EN_MASK\tBIT(4)\n#define QN908X_FMC_SMART_CTRL_SMART_ERASEH_EN_MASK\tBIT(5)\n#define QN908X_FMC_SMART_CTRL_MAX_WRITE_MASK\t\t0xf00u\n#define QN908X_FMC_SMART_CTRL_MAX_WRITE_SHIFT\t\t8u\n#define QN908X_FMC_SMART_CTRL_MAX_WRITE(x) \\\n\t(((uint32_t)(((uint32_t)(x)) << QN908X_FMC_SMART_CTRL_MAX_WRITE_SHIFT)) \\\n\t& QN908X_FMC_SMART_CTRL_MAX_WRITE_MASK)\n#define QN908X_FMC_SMART_CTRL_MAX_ERASE_MASK\t\t0x3f000u\n#define QN908X_FMC_SMART_CTRL_MAX_ERASE_SHIFT\t\t12u\n#define QN908X_FMC_SMART_CTRL_MAX_ERASE(x) \\\n\t(((uint32_t)(((uint32_t)(x)) << QN908X_FMC_SMART_CTRL_MAX_ERASE_SHIFT)) \\\n\t& QN908X_FMC_SMART_CTRL_MAX_ERASE_MASK)\n\n#define QN908X_FMC_SMART_CTRL_MAX_ERASE_RETRIES\t\t9\n#define QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES\t\t9\n\n#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE_MASK\t\t0xfffu\n#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE_SHIFT\t\t0u\n#define QN908X_FMC_TIME_CTRL_PRGM_CYCLE(x) \\\n\t(((uint32_t)(((uint32_t)(x)) << QN908X_FMC_TIME_CTRL_PRGM_CYCLE_SHIFT)) \\\n\t& QN908X_FMC_TIME_CTRL_PRGM_CYCLE_MASK)\n#define QN908X_FMC_TIME_CTRL_TIME_BASE_MASK\t\t\t0xff000u\n#define QN908X_FMC_TIME_CTRL_TIME_BASE_SHIFT\t\t12u\n#define QN908X_FMC_TIME_CTRL_TIME_BASE(x) \\\n\t(((uint32_t)(((uint32_t)(x)) << QN908X_FMC_TIME_CTRL_TIME_BASE_SHIFT)) \\\n\t& QN908X_FMC_TIME_CTRL_TIME_BASE_MASK)\n\n#define QN908X_FMC_LOCK_STAT_8_MASS_ERASE_LOCK_EN\tBIT(0)\n#define QN908X_FMC_LOCK_STAT_8_FSH_PROTECT_EN\t\tBIT(1)\n#define QN908X_FMC_LOCK_STAT_8_MEM_PROTECT_EN\t\tBIT(2)\n#define QN908X_FMC_LOCK_STAT_8_PROTECT_ANY\t\t\t(BIT(1) | BIT(2))\n\n/* See Table 418 \"Flash lock and protect description\" in the user manual */\n#define QN908X_FLASH_LOCK_ADDR\t\t\t\t\t\t(QN908X_FLASH_BASE + 0x7f820)\n/* Allow mass erase */\n#define QN908X_FLASH_LOCK_ENABLE_MASS_ERASE\t\t\tBIT(0)\n/* disallow flash access from SWD */\n#define QN908X_FLASH_LOCK_ENABLE_FLASH_PROTECTION\tBIT(1)\n/* disallow SRAM access from SWD */\n#define QN908X_FLASH_LOCK_ENABLE_MEMORY_PROTECTION\tBIT(2)\n\n/* Page lock information located at the beginning of the last page. */\nstruct qn908x_flash_page_lock {\n\tuint8_t bits[QN908X_FLASH_MAX_BLOCKS * QN908X_FLASH_PAGES_PER_BLOCK / 8];\n\tuint8_t protection;\n\tuint8_t _reserved[3];\n\t/* nvds_size is unused here, but we need to preserve it across erases\n\t * when locking and unlocking pages. */\n\tuint8_t nvds_size[4];\n} __attribute__ ((packed));\n\n/* Clock configuration is stored in the SYSCON. */\n#define QN908X_SYSCON_BASE\t\t\t\t\t\t0x40000000u\n#define QN908X_SYSCON_CLK_EN\t\t\t\t\t(QN908X_SYSCON_BASE + 0x00cu)\n#define QN908X_SYSCON_CLK_CTRL\t\t\t\t\t(QN908X_SYSCON_BASE + 0x010u)\n#define QN908X_SYSCON_CHIP_ID\t\t\t\t\t(QN908X_SYSCON_BASE + 0x108u)\n#define QN908X_SYSCON_XTAL_CTRL\t\t\t\t\t(QN908X_SYSCON_BASE + 0x180u)\n\n/* Internal 16MHz / 8MHz clock used by the erase operation. */\n#define QN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK\t\tBIT(21)\n\n#define SYSCON_XTAL_CTRL_XTAL_DIV_MASK\t\t\tBIT(31)\n\n#define SYSCON_CLK_CTRL_AHB_DIV_MASK\t\t\t0x1FFF0u\n#define SYSCON_CLK_CTRL_AHB_DIV_SHIFT\t\t\t4u\n#define SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK\t\tBIT(19)\n#define SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK\t\tBIT(20)\n#define SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK\t\t0xC0000000u\n#define SYSCON_CLK_CTRL_SYS_CLK_SEL_SHIFT\t\t30u\n\n#define CLOCK_16MHZ\t\t\t\t\t\t\t\t16000000u\n#define CLOCK_32MHZ\t\t\t\t\t\t\t\t32000000u\n#define CLOCK_32KHZ\t\t\t\t\t\t\t\t32000u\n\n/* Watchdog block registers */\n#define QN908X_WDT_BASE\t\t\t\t\t\t\t0x40001000u\n#define QN908X_WDT_CTRL\t\t\t\t\t\t\t(QN908X_WDT_BASE + 0x08u)\n#define QN908X_WDT_LOCK\t\t\t\t\t\t\t(QN908X_WDT_BASE + 0x20u)\n\nstruct qn908x_flash_bank {\n\t/* The number of flash blocks. Initially set to zero until the flash\n\t * is probed. This determines the size of the flash. */\n\tunsigned int num_blocks;\n\n\tunsigned int user_bank_size;\n\tbool calc_checksum;\n\n\t/* Whether we allow to flash an image that disables SWD access, potentially\n\t * bricking the device since the image can't be reflashed from SWD. */\n\tbool allow_swd_disabled;\n\n\tbool page_lock_loaded;\n\tstruct qn908x_flash_page_lock page_lock;\n};\n\n/* 500 ms timeout. */\n#define QN908X_DEFAULT_TIMEOUT_MS 500\n\n/* Forward declaration of commands. */\nstatic int qn908x_probe(struct flash_bank *bank);\nstatic int qn908x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count);\n\n/* Update the value of a register with a mask. This helper allows to read a\n * register, modify a subset of the bits and write back the value, which is a\n * common operation when modifying only a bit filed in a register. */\nstatic int qn908x_update_reg(struct target *target, target_addr_t reg,\n\t\tuint32_t mask, uint32_t value)\n{\n\tuint32_t orig_value = 0;\n\tuint32_t new_value;\n\tint retval;\n\tif (mask != 0xffffffff) {\n\t\t/* No need to read the old value if we request a mask of 32 bits. */\n\t\tretval = target_read_u32(target, reg, &orig_value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Error reading reg at \" TARGET_ADDR_FMT\n\t\t\t\t\t\": %d\", reg, retval);\n\t\t\treturn retval;\n\t\t}\n\t}\n\tnew_value = (orig_value & ~mask) | (value & mask);\n\tretval = target_write_u32(target, reg, new_value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Error writing reg at \" TARGET_ADDR_FMT \" with 0x%08\"\n\t\t\t\tPRIx32 \": %d\", reg, new_value, retval);\n\t\treturn retval;\n\t}\n\tif (mask == 0xffffffff) {\n\t\tLOG_DEBUG(\"Updated reg at \" TARGET_ADDR_FMT \": ?? -> 0x%.08\"\n\t\t\t\tPRIx32 \"\", reg, new_value);\n\t} else {\n\t\tLOG_DEBUG(\"Updated reg at \" TARGET_ADDR_FMT \": 0x%.08\" PRIx32\n\t\t\t\t\" -> 0x%.08\" PRIx32, reg, orig_value, new_value);\n\t}\n\treturn ERROR_OK;\n}\n\n/* Load lock bit and protection bit and load redundancy page info.\n * This populates the LOCK_STAT_n registers with the values from the lock page,\n * making protection bit changes to the last page effective. */\nstatic int qn908x_load_lock_stat(struct target *target)\n{\n\tint retval = target_write_u32(target, QN908X_FMC_INI_RD_EN,\n\t\t\tQN908X_FMC_INI_RD_EN_INI_RD_EN_MASK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t status1;\n\tconst uint32_t status_mask = QN908X_FMC_STATUS1_FSH_STA_MASK\n\t\t\t| QN908X_FMC_STATUS1_INI_RD_DONE_MASK;\n\tdo {\n\t\tretval = target_read_u32(target, QN908X_FMC_STATUS1, &status1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} while ((status1 & status_mask) != QN908X_FMC_STATUS1_INI_RD_DONE_MASK);\n\n\tfor (int i = 0; i <= 8; i++) {\n\t\tuint32_t addr = QN908X_FMC_LOCK_STAT_0 + i * 4;\n\t\tuint32_t lock_stat;\n\t\tif (target_read_u32(target, addr, &lock_stat) == ERROR_OK)\n\t\t\tLOG_DEBUG(\"LOCK_STAT_%d = 0x%08\" PRIx32, i, lock_stat);\n\t}\n\treturn ERROR_OK;\n}\n\n/* Initializes the FMC controller registers for allowing writing. */\nstatic int qn908x_init_flash(struct target *target)\n{\n\t/* Determine the current clock configuration. */\n\tuint32_t clk_ctrl;\n\tint retval = target_read_u32(target, QN908X_SYSCON_CLK_CTRL, &clk_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t clk_sel = (clk_ctrl & SYSCON_CLK_CTRL_SYS_CLK_SEL_MASK)\n\t\t\t>> SYSCON_CLK_CTRL_SYS_CLK_SEL_SHIFT;\n\tLOG_DEBUG(\"Clock clk_sel=0x%08\" PRIu32, clk_sel);\n\n\t/* Core clock frequency. */\n\tuint32_t core_freq = 0;\n\tswitch (clk_sel) {\n\tcase 0:\t/* RCO 32 MHz */\n\t\tcore_freq = (clk_ctrl & SYSCON_CLK_CTRL_CLK_OSC32M_DIV_MASK) ?\n\t\t\tCLOCK_16MHZ : CLOCK_32MHZ;\n\t\tbreak;\n\tcase 1:\t/* Xin frequency */\n\t{\n\t\tuint32_t clk_xtal;\n\t\tretval = target_read_u32(target, QN908X_SYSCON_XTAL_CTRL, &clk_xtal);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcore_freq\t= (clk_ctrl & SYSCON_CLK_CTRL_CLK_XTAL_SEL_MASK)\n\t\t\t\t\t&& (clk_xtal & SYSCON_XTAL_CTRL_XTAL_DIV_MASK)\n\t\t\t\t\t? CLOCK_32MHZ : CLOCK_16MHZ;\n\t}\n\tbreak;\n\tcase 2:\t/* 32 Kz */\n\t\tcore_freq = CLOCK_32KHZ;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t ahb_div = (clk_ctrl & SYSCON_CLK_CTRL_AHB_DIV_MASK)\n\t\t\t>> SYSCON_CLK_CTRL_AHB_DIV_SHIFT;\n\tuint32_t ahb_freq = core_freq / (ahb_div + 1);\n\n\tLOG_DEBUG(\"Core freq: %\" PRIu32 \" Hz | AHB freq: %\" PRIu32 \" Hz\",\n\t\t\tcore_freq, ahb_freq);\n\n\t/* TIME_BASE is 2uS at the current AHB clock speed. */\n\tretval = target_write_u32(target, QN908X_FMC_TIME_CTRL,\n\t\t\tQN908X_FMC_TIME_CTRL_TIME_BASE(2 * ahb_freq / 1000000) |\n\t\t\tQN908X_FMC_TIME_CTRL_PRGM_CYCLE(30));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn qn908x_load_lock_stat(target);\n}\n\n/* flash bank qn908x <base> <size> 0 0 <target#> [calc_checksum] */\nFLASH_BANK_COMMAND_HANDLER(qn908x_flash_bank_command)\n{\n\tstruct qn908x_flash_bank *qn908x_info;\n\n\tif (CMD_ARGC < 6 || CMD_ARGC > 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (bank->base != QN908X_FLASH_BASE) {\n\t\tLOG_ERROR(\"Address \" TARGET_ADDR_FMT\n\t\t\t\" is an invalid bank address (try 0x%08\" PRIx32 \")\",\n\t\t\tbank->base, QN908X_FLASH_BASE);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tqn908x_info = malloc(sizeof(struct qn908x_flash_bank));\n\n\tif (!qn908x_info)\n\t\treturn ERROR_FAIL;\n\n\tbank->driver_priv = qn908x_info;\n\tqn908x_info->num_blocks = 0;\n\tqn908x_info->user_bank_size = bank->size;\n\tqn908x_info->page_lock_loaded = false;\n\tqn908x_info->allow_swd_disabled = false;\n\n\tqn908x_info->calc_checksum = false;\n\tif (CMD_ARGC == 7) {\n\t\tif (strcmp(CMD_ARGV[6], \"calc_checksum\")) {\n\t\t\tfree(qn908x_info);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tqn908x_info->calc_checksum = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_read_page_lock(struct flash_bank *bank)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The last page of the flash contains the \"Flash lock and protect\"\n\t * information. It is not clear where this is located on chips with only\n\t * one block. */\n\tuint32_t prot_offset = qn908x_info->num_blocks * QN908X_FLASH_BLOCK_SIZE\n\t\t\t- QN908X_FLASH_PAGE_SIZE;\n\n\tint retval = target_read_memory(bank->target, bank->base + prot_offset, 4,\n\t\t\tsizeof(qn908x_info->page_lock) / 4,\n\t\t\t(void *)(&qn908x_info->page_lock));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"Flash protection = 0x%02\" PRIx8,\n\t\t\tqn908x_info->page_lock.protection);\n\n\tqn908x_info->page_lock_loaded = true;\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_busy_check(struct target *target)\n{\n\tuint32_t status1;\n\tint retval = target_read_u32(target, QN908X_FMC_STATUS1, &status1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((status1 & (QN908X_FMC_STATUS1_FSH_ERA_BUSY_L_MASK\n\t\t\t\t\t| QN908X_FMC_STATUS1_FSH_WR_BUSY_L_MASK\n\t\t\t\t\t| QN908X_FMC_STATUS1_FSH_ERA_BUSY_H_MASK\n\t\t\t\t\t| QN908X_FMC_STATUS1_FSH_WR_BUSY_H_MASK)))\n\t\treturn ERROR_FLASH_BUSY;\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_status_check(struct target *target)\n{\n\tuint32_t int_stat;\n\tint retval = target_read_u32(target, QN908X_FMC_INT_STAT, &int_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* The error bits for block 0 and block 1 have the exact same layout, only\n\t * that block 1 error bits are shifted by 8 bits. We use this fact to\n\t * loop over the blocks */\n\tfor (unsigned int block = 0; block <= 1; block++) {\n\t\tunsigned int shift = (block) ? 8 : 0;\n\t\tif (int_stat & (QN908X_FMC_INT_STAT_AHBL_INT_MASK << shift)) {\n\t\t\tLOG_ERROR(\"AHB error on block %u\", block);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (int_stat & (QN908X_FMC_INT_STAT_LOCKL_INT_MASK << shift)) {\n\t\t\tLOG_ERROR(\"Locked page being accessed error on block %u\", block);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (int_stat & (QN908X_FMC_INT_STAT_WRITE_FAIL_L_INT_MASK << shift)) {\n\t\t\tLOG_ERROR(\"Smart write on block %u failed\", block);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif ((int_stat & (QN908X_FMC_INT_STAT_ERASE_FAIL_L_INT_MASK << shift))\n\t\t\t\t|| (int_stat & (QN908X_FMC_INT_STAT_ERASE_FAIL_H_INT_MASK << shift))) {\n\t\t\tLOG_ERROR(\"Smart erase on block %u failed\", block);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_wait_for_idle(struct target *target, int64_t timeout_ms)\n{\n\tint64_t ms_start = timeval_ms();\n\n\tint busy = ERROR_FLASH_BUSY;\n\twhile (busy != ERROR_OK) {\n\t\tbusy = qn908x_busy_check(target);\n\t\tif (busy != ERROR_OK && busy != ERROR_FLASH_BUSY)\n\t\t\treturn busy;\n\t\tif (timeval_ms() - ms_start > timeout_ms) {\n\t\t\tLOG_ERROR(\"Timeout waiting to be idle.\");\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/* Set up the chip to perform an erase (page or block) operation. */\nstatic int qn908x_setup_erase(struct target *target)\n{\n\tint retval;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Enable 8MHz clock. */\n\tretval = qn908x_update_reg(target, QN908X_SYSCON_CLK_EN,\n\t\t\tQN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK,\n\t\t\tQN908X_SYSCON_CLK_EN_CLK_DP_EN_MASK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set ERASE_TIME to 2ms for smart erase. */\n\tretval = qn908x_update_reg(target, QN908X_FMC_ERASE_TIME,\n\t\t\t(1u << 20) - 1,\n\t\t\t2000 * 8);\t/* 2000 uS * 8 MHz = x cycles */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set up smart erase. SWD can only perform smart erase. */\n\tuint32_t ctrl_val\t= QN908X_FMC_SMART_CTRL_SMART_ERASEH_EN_MASK\n\t\t\t\t\t\t| QN908X_FMC_SMART_CTRL_SMART_ERASEL_EN_MASK\n\t\t\t\t\t\t| QN908X_FMC_SMART_CTRL_MAX_ERASE(QN908X_FMC_SMART_CTRL_MAX_ERASE_RETRIES)\n\t\t\t\t\t\t| QN908X_FMC_SMART_CTRL_MAX_WRITE(QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES);\n\tretval = target_write_u32(target, QN908X_FMC_SMART_CTRL, ctrl_val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tif (!qn908x_info->num_blocks) {\n\t\tif (qn908x_probe(bank) != ERROR_OK)\n\t\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tretval = qn908x_setup_erase(bank->target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tif (i >= bank->num_sectors)\n\t\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t\tuint32_t block_idx = i / QN908X_FLASH_PAGES_PER_BLOCK;\n\t\tuint32_t page_idx = i % QN908X_FLASH_PAGES_PER_BLOCK;\n\t\tif (block_idx >= qn908x_info->num_blocks)\n\t\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\t\tLOG_DEBUG(\"Erasing page %\" PRIu32 \" of block %\" PRIu32,\n\t\t\tpage_idx, block_idx);\n\n\t\t/* Depending on the block the page we are erasing is located we\n\t\t * need to use a different set of bits in the registers. */\n\t\tuint32_t ctrl_page_idx_shift = block_idx ?\n\t\t\tQN908X_FMC_ERASE_CTRL_PAGE_IDXH_SHIFT :\n\t\t\tQN908X_FMC_ERASE_CTRL_PAGE_IDXL_SHIFT;\n\t\tuint32_t ctrl_erase_en_shift = block_idx ?\n\t\t\tQN908X_FMC_ERASE_CTRL_PAGE_ERASEH_EN_SHIFT :\n\t\t\tQN908X_FMC_ERASE_CTRL_PAGE_ERASEL_EN_SHIFT;\n\n\t\tretval = target_write_u32(bank->target, QN908X_FMC_ERASE_CTRL,\n\t\t\t\tBIT(ctrl_erase_en_shift) | (page_idx << ctrl_page_idx_shift));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = qn908x_status_check(bank->target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int qn908x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!qn908x_info->page_lock_loaded) {\n\t\tint retval = qn908x_read_page_lock(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Use [first, last) interval open on the right side from now on. */\n\tlast++;\n\t/* We use sectors as prot_blocks. */\n\tbool needs_update = false;\n\tfor (unsigned int i = first; i < last; i++) {\n\t\tif (set != (((qn908x_info->page_lock.bits[i / 8] >> (i % 8)) & 1) ^ 1))\n\t\t\tneeds_update = true;\n\t}\n\n\t/* Check that flash protection still allows SWD access to flash and RAM,\n\t * otherwise we won't be able to re-flash this chip from SWD unless we do a\n\t * mass erase. */\n\tif (qn908x_info->page_lock.protection & QN908X_FMC_LOCK_STAT_8_PROTECT_ANY) {\n\t\tLOG_WARNING(\"SWD flash/RAM access disabled in the Flash lock and \"\n\t\t\t\"protect descriptor. You might need to issue a mass_erase to \"\n\t\t\t\"regain SWD access to this chip after reboot.\");\n\t}\n\n\tif (!needs_update)\n\t\treturn ERROR_OK;\n\n\tint last_page = qn908x_info->num_blocks * QN908X_FLASH_PAGES_PER_BLOCK - 1;\n\tint retval;\n\n\tif (qn908x_info->page_lock.bits[sizeof(qn908x_info->page_lock.bits) - 1] & 0x80) {\n\t\t/* A bit 1 in the MSB in the page_lock.bits array means that the last\n\t\t * page is unlocked, so we can just erase it. */\n\t\tretval = qn908x_erase(bank, last_page, last_page);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\t/* TODO: The last page is locked and we can't erase unless we use the\n\t\t * ERASE_PASSWORD from code running on the device. For this we need to\n\t\t * copy a little program to RAM and execute the erase command from\n\t\t * there since there's no way to override the page protection from\n\t\t * SWD. */\n\t\tLOG_ERROR(\"Unprotecting the last page is not supported. Issue a \"\n\t\t\t\"\\\"qn908x mass_erase\\\" command to erase the whole flash, \"\n\t\t\t\"including the last page and its protection.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = first / 8; i < (last + 7) / 8; i++) {\n\t\t/* first_mask contains a bit set if the bit corresponds to a block id\n\t\t * that is larger or equal than first. This is basically 0xff in all\n\t\t * cases except potentially the first iteration. */\n\t\tuint8_t first_mask\t= (first <= i * 8)\n\t\t\t\t\t\t\t? 0xff : 0xff ^ ((1u << (first - i * 8)) - 1);\n\t\t/* Similar to first_mask, this contains a bit set if the corresponding\n\t\t * is smaller than last. */\n\t\tuint8_t last_mask\t= (i * 8 + 8 <= last)\n\t\t\t\t\t\t\t? 0xff : ((1u << (last - i * 8)) - 1);\n\n\t\tuint8_t mask = first_mask & last_mask;\n\t\tLOG_DEBUG(\"protect set=%d bits[%d] with mask=0x%02x\", set, i, mask);\n\t\t/* To \"set\" the protection bit means to clear the bit in the page_lock\n\t\t * bit array. */\n\t\tif (set)\n\t\t\tqn908x_info->page_lock.bits[i] &= ~mask;\n\t\telse\n\t\t\tqn908x_info->page_lock.bits[i] |= mask;\n\t}\n\n\tretval = qn908x_write(bank, (void *)(&qn908x_info->page_lock),\n\t\t\tlast_page * QN908X_FLASH_PAGE_SIZE, sizeof(qn908x_info->page_lock));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Reload the lock_stat to make the changes effective. */\n\tretval = qn908x_load_lock_stat(bank->target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = first; i < last; i++)\n\t\tbank->sectors[i].is_protected = set;\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The flash infrastructure was requested to align writes to 32 bit */\n\tassert(((offset % 4) == 0) && ((count % 4) == 0));\n\n\t/* Compute the calc_checksum even if it wasn't requested. */\n\tuint32_t checksum = 0;\n\tif (offset == 0 && count >= 0x20) {\n\t\tfor (int i = 0; i < 7; i++)\n\t\t\tchecksum += buf_get_u32(buffer + (i * 4), 0, 32);\n\t\tchecksum = 0 - checksum;\n\t\tLOG_DEBUG(\"computed image checksum: 0x%8.8\" PRIx32, checksum);\n\t\tuint32_t stored_checksum = buf_get_u32(buffer + 7 * 4, 0, 32);\n\t\tif (checksum != stored_checksum) {\n\t\t\tLOG_WARNING(\"Image vector table checksum mismatch: expected 0x%08\"\n\t\t\t\t\tPRIx32 \" but found 0x%08\" PRIx32,\n\t\t\t\t\tchecksum, stored_checksum);\n\t\t\tif (!qn908x_info->calc_checksum)\n\t\t\t\tLOG_WARNING(\"This device will not boot, use calc_checksum in \"\n\t\t\t\t\t\t\"the flash bank.\");\n\t\t\telse\n\t\t\t\tLOG_WARNING(\"Updating checksum, verification will fail.\");\n\t\t}\n\t}\n\n\t/* Check the Code Read Protection (CRP) word for invalid values or not\n\t * allowed ones. */\n\tif (offset <= 0x20 && offset + count >= 0x24) {\n\t\tuint32_t crp = buf_get_u32(buffer + 0x20 - offset, 0, 32);\n\t\t/* 2-bit fields at bits 10, 12, 14, 16 and 18 must not be 00 or 11. */\n\t\tfor (int i = 10; i <= 18; i += 2) {\n\t\t\tuint32_t field = (crp >> i) & 3;\n\t\t\tif (field == 0 || field == 3) {\n\t\t\t\tLOG_DEBUG(\"Code Read Protection = 0x%08\" PRIx32, crp);\n\t\t\t\tLOG_ERROR(\"The Code Read Protection (CRP) field at bit %d is \"\n\t\t\t\t\t\t\"invalid (%\" PRIu32 \"). An invalid value could make \"\n\t\t\t\t\t\t\"the flash inaccessible.\", i, field);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tuint32_t swd_allowed = (crp >> 18) & 3;\n\t\tif (swd_allowed != 2) {\n\t\t\tLOG_WARNING(\"The Code Read Protection (CRP) in this image \"\n\t\t\t\t\t\"(0x%08\" PRIx32 \") is disabling the SWD access, which is \"\n\t\t\t\t\t\"currently used by OpenOCD to flash this device. After \"\n\t\t\t\t\t\"reboot, this device will not be accessible to OpenOCD \"\n\t\t\t\t\t\"anymore.\", crp);\n\t\t\tif (!qn908x_info->allow_swd_disabled) {\n\t\t\t\tLOG_ERROR(\"Disabling SWD is not allowed, run \"\n\t\t\t\t\t\t\"\\\"qn908x allow_brick\\\" before if you really want to \"\n\t\t\t\t\t\t\"disable SWD. You won't be able to access this chip \"\n\t\t\t\t\t\t\"anymore from OpenOCD.\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t smart_ctrl\t= QN908X_FMC_SMART_CTRL_SMART_WRITEL_EN_MASK\n\t\t\t\t\t\t| QN908X_FMC_SMART_CTRL_PRGML_EN_MASK\n\t\t\t\t\t\t| QN908X_FMC_SMART_CTRL_MAX_WRITE(QN908X_FMC_SMART_CTRL_MAX_WRITE_RETRIES);\n\tif (qn908x_info->num_blocks > 1) {\n\t\tsmart_ctrl\t|= QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK\n\t\t\t\t\t| QN908X_FMC_SMART_CTRL_PRGMH_EN_MASK;\n\t}\n\tretval = target_write_u32(bank->target, QN908X_FMC_SMART_CTRL, smart_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Write data page-wise, as suggested in the examples in section\n\t * 28.5.2 \"Flash write\" of user manual UM11023 in revision 1.1\n\t * (February 2018). */\n\twhile (count > 0) {\n\t\tuint32_t next_offset = (offset & ~(QN908X_FLASH_PAGE_SIZE - 1)) + QN908X_FLASH_PAGE_SIZE;\n\t\tuint32_t chunk_len = next_offset - offset;\n\t\tif (chunk_len > count)\n\t\t\tchunk_len = count;\n\n\t\tif (offset == 0\n\t\t\t\t&& chunk_len >= QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END\n\t\t\t\t&& qn908x_info->calc_checksum) {\n\t\t\t/* write data prior to checksum */\n\t\t\tretval = target_write_buffer(bank->target, bank->base,\n\t\t\t\t\tQN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* write computed crc checksum instead of provided data */\n\t\t\tretval = target_write_u32(bank->target, bank->base + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_POS, checksum);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_write_buffer(bank->target,\n\t\t\t\t\tbank->base + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END,\n\t\t\t\t\tchunk_len - QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END,\n\t\t\t\t\tbuffer + QN908X_FLASH_IRQ_VECTOR_CHECKSUM_END);\n\t\t} else {\n\t\t\tretval = target_write_buffer(bank->target, bank->base + offset,\n\t\t\t\t\tchunk_len, buffer);\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tkeep_alive();\n\t\tbuffer += chunk_len;\n\t\tcount -= chunk_len;\n\t\toffset = next_offset;\n\n\t\t/* Wait for FMC to complete write */\n\t\tretval = qn908x_wait_for_idle(bank->target, QN908X_DEFAULT_TIMEOUT_MS);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Check if FMC reported any errors */\n\t\tretval = qn908x_status_check(bank->target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int is_flash_protected(struct flash_bank *bank, bool *is_protected)\n{\n\tint retval;\n\tuint32_t lock_stat;\n\tretval = target_read_u32(bank->target, QN908X_FMC_LOCK_STAT_8, &lock_stat);\n\tif (retval)\n\t\treturn retval;\n\n\t*is_protected = false;\n\tif (lock_stat & QN908X_FMC_LOCK_STAT_8_PROTECT_ANY)\n\t\t*is_protected = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_probe(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\tuint8_t info_page[QN908X_INFO_PAGE_CRC_END - QN908X_INFO_PAGE_CRC_START];\n\tqn908x_info->num_blocks = 0;\n\n\t/* When the SWD access to the RAM is locked by the LOCK_STAT_8 register we\n\t * can't access the info page to verify the chip/bank version and it will\n\t * read all zeros. This situation prevents the bank from being initialized\n\t * at all so no other operation can be performed. The only option to\n\t * re-flash the chip is to perform a mass_erase from SWD, which can be\n\t * performed even if the mass_erase operation is locked as well.\n\t * We attempt to read the info page and redirect the user to perform a\n\t * mass_erase if we detect this situation. */\n\tretval = target_read_memory(bank->target, QN908X_INFO_PAGE_CRC_START,\n\t\t\tsizeof(uint32_t), sizeof(info_page) / sizeof(uint32_t),\n\t\t\tinfo_page);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t crc_seed = 0xffffffff;\n\t/* The QN908x uses the standard little endian CRC32 polynomial and all ones\n\t * as seed. The CRC32 is however finalized by one last xor operation that\n\t * is not part of the common CRC32 implementation, so we do that by hand */\n\tuint32_t computed_crc = crc32_le(CRC32_POLY_LE, crc_seed,\n\t\t\tinfo_page, sizeof(info_page));\n\tcomputed_crc ^= crc_seed;\n\tuint32_t read_crc;\n\tretval = target_read_u32(bank->target, QN908X_INFO_PAGE_CRC32, &read_crc);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (computed_crc != read_crc) {\n\t\tuint32_t info_page_or = 0;\n\t\tfor (unsigned int i = 0; i < sizeof(info_page); i++)\n\t\t\tinfo_page_or |= info_page[i];\n\t\tbool is_protected;\n\t\tretval = is_flash_protected(bank, &is_protected);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (info_page_or == 0 && is_protected) {\n\t\t\tLOG_ERROR(\"The flash or memory in this chip is protected and \"\n\t\t\t\t\"cannot be accessed from the SWD interface. However, a \"\n\t\t\t\t\"\\\"qn908x mass_erase\\\" can erase the device and lift this \"\n\t\t\t\t\"protection.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_ERROR(\"Flash information page CRC32 mismatch, found 0x%08\"\n\t\t\tPRIx32 \" but computed 0x%08\" PRIx32 \". Flash size unknown\",\n\t\t\tread_crc, computed_crc);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t flash_size_fld = target_buffer_get_u32(bank->target,\n\t\t\tinfo_page + (QN908X_INFO_PAGE_FLASH_SIZE - QN908X_INFO_PAGE_CRC_START));\n\n\tswitch (flash_size_fld) {\n\tcase QN908X_FLASH_SIZE_512K:\n\t\tqn908x_info->num_blocks = 2;\n\t\tbreak;\n\tcase QN908X_FLASH_SIZE_256K:\n\t\tqn908x_info->num_blocks = 1;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Unknown Flash size field: 0x%08\" PRIx32,\n\t\t\tflash_size_fld);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->size = qn908x_info->num_blocks * QN908X_FLASH_BLOCK_SIZE;\n\tbank->write_start_alignment = 4;\n\tbank->write_end_alignment = 4;\n\n\t/* The flash supports erasing and protecting individual pages. */\n\tbank->num_sectors = qn908x_info->num_blocks *\n\t\tQN908X_FLASH_PAGES_PER_BLOCK;\n\tbank->sectors = alloc_block_array(0, QN908X_FLASH_PAGE_SIZE,\n\t\t\tbank->num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tretval = qn908x_init_flash(bank->target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"Detected flash size: %d KiB\", bank->size / 1024);\n\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_auto_probe(struct flash_bank *bank)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\tif (qn908x_info->num_blocks != 0)\n\t\treturn ERROR_OK;\n\tLOG_DEBUG(\"auto_probe\");\n\treturn qn908x_probe(bank);\n}\n\nstatic int qn908x_protect_check(struct flash_bank *bank)\n{\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\n\tint retval = qn908x_read_page_lock(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (uint32_t i = 0;\n\t\t\ti < qn908x_info->num_blocks * QN908X_FLASH_PAGES_PER_BLOCK;\n\t\t\ti++) {\n\t\t/* A bit 0 in page_lock means page is locked. */\n\t\tbank->sectors[i].is_protected =\n\t\t\t((qn908x_info->page_lock.bits[i / 8] >> (i % 8)) & 1) ^ 1;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int qn908x_get_info(struct flash_bank *bank,\n\t\tstruct command_invocation *cmd)\n{\n\tuint32_t bootloader_version;\n\tuint32_t chip_id;\n\tuint8_t bluetooth[6];\n\tint retval;\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\n\tretval = target_read_u32(bank->target, QN908X_SYSCON_CHIP_ID, &chip_id);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print_sameline(cmd, \"Cannot read QN908x chip ID.\");\n\t\treturn retval;\n\t}\n\tretval = target_read_u32(bank->target, QN908X_INFO_PAGE_BOOTLOADER_VER,\n\t\t\t&bootloader_version);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print_sameline(cmd, \"Cannot read from QN908x info page.\");\n\t\treturn retval;\n\t}\n\n\tretval = target_read_memory(bank->target, QN908X_INFO_PAGE_BLUETOOTH_ADDR,\n\t\t\t1, sizeof(bluetooth), bluetooth);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print_sameline(cmd, \"Cannot read QN908x bluetooth L2 address.\");\n\t\treturn retval;\n\t}\n\n\tcommand_print_sameline(cmd, \"qn908x: chip id: 0x%\" PRIx32, chip_id);\n\n\tcommand_print_sameline(cmd, \" bdaddr: \"\n\t\t\t\"%02\" PRIx8 \":%02\" PRIx8 \":%02\" PRIx8\n\t\t\t\":%02\" PRIx8 \":%02\" PRIx8 \":%02\" PRIx8,\n\t\t\tbluetooth[0], bluetooth[1], bluetooth[2],\n\t\t\tbluetooth[3], bluetooth[4], bluetooth[5]);\n\n\tcommand_print_sameline(cmd, \" bootloader: %08\" PRIx32, bootloader_version);\n\n\tcommand_print_sameline(cmd, \" blocks: %\" PRIu32, qn908x_info->num_blocks);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(qn908x_handle_allow_brick_command)\n{\n\tint retval;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct flash_bank *bank = NULL;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = get_flash_bank_by_addr(target, QN908X_FLASH_BASE, true, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* If get_flash_bank_by_addr() did not find the flash bank, it should have\n\t * returned and error code instead of ERROR_OK */\n\tassert(bank);\n\tstruct qn908x_flash_bank *qn908x_info = bank->driver_priv;\n\n\tLOG_WARNING(\"Flashing images that disable SWD in qn908x is now allowed.\");\n\tqn908x_info->allow_swd_disabled = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(qn908x_handle_disable_wdog_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* To change any value in the watchdog block (WDT) we need to first write\n\t * 0x1ACCE551 to the LOCK register, and we can then set it back to any other\n\t * value to prevent accidental changes to the watchdog. */\n\tretval = target_write_u32(target, QN908X_WDT_LOCK, 0x1ACCE551);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, QN908X_WDT_CTRL, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_write_u32(target, QN908X_WDT_LOCK, 0);\n}\n\nCOMMAND_HANDLER(qn908x_handle_mass_erase_command)\n{\n\tint retval;\n\tbool keep_lock = false;\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (CMD_ARGC == 1) {\n\t\tif (strcmp(\"keep_lock\", CMD_ARGV[0]))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tkeep_lock = true;\n\t}\n\n\t/* This operation can be performed without probing the bank since it is the\n\t * only way to unlock a chip when the flash and ram have been locked. */\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tretval = qn908x_setup_erase(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check the mass-erase locking status for information purposes only. This\n\t * lock applies to both the SWD and the code running in the core but can be\n\t * bypassed in either case. */\n\tuint32_t lock_stat_8;\n\tretval = target_read_u32(target, QN908X_FMC_LOCK_STAT_8, &lock_stat_8);\n\tLOG_DEBUG(\"LOCK_STAT_8 before erasing: 0x%\" PRIx32, lock_stat_8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif ((lock_stat_8 & QN908X_FMC_LOCK_STAT_8_MASS_ERASE_LOCK_EN) == 0) {\n\t\tLOG_INFO(\"mass_erase disabled by Flash lock and protection, forcing \"\n\t\t\t\t\"mass_erase.\");\n\t}\n\t/* Set the DEBUG_PASSWORD so we can force the mass erase from the SWD. We do\n\t * this regardless of the lock status. */\n\tretval = target_write_u32(target, QN908X_FMC_DEBUG_PASSWORD, 0xCA1E093F);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Erase both halves of the flash at the same time. These are actually done\n\t * sequentially but we need to send the command to erase both blocks since\n\t * doing so in a locked flash will change the LOCK_STAT_8 register to 0x01,\n\t * allowing us to access the (now erase) flash an memory. Erasing only one\n\t * block at a time does not reset the LOCK_STAT_8 register and therefore\n\t * will not grant access to program the chip. */\n\tuint32_t erase_cmd = (1u << QN908X_FMC_ERASE_CTRL_HALF_ERASEH_EN_SHIFT) |\n\t\t(1u << QN908X_FMC_ERASE_CTRL_HALF_ERASEL_EN_SHIFT);\n\tLOG_DEBUG(\"Erasing both blocks with command 0x%\" PRIx32, erase_cmd);\n\n\tretval = target_write_u32(target, QN908X_FMC_ERASE_CTRL, erase_cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = qn908x_status_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set the debug password back to 0 to avoid accidental mass_erase. */\n\tretval = target_write_u32(target, QN908X_FMC_DEBUG_PASSWORD, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* At this point the flash is erased and we are able to write to the flash\n\t * since the LOCK_STAT_8 gets updated to 0x01 after the mass_erase. However,\n\t * after a hard reboot this value will be realoaded from flash which after\n\t * an erase is 0xff. This means that after flashing an image that doesn't\n\t * set the protection bits we end up with a chip that we can't debug. We\n\t * update this value to 0x01 unless \"keep_lock\" is passed to allow the SWD\n\t * interface to debug the flash and RAM after a hard reset. */\n\tif (keep_lock)\n\t\treturn retval;\n\n\tretval = qn908x_init_flash(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Unlock access to RAM and FLASH in the last page of the flash and\n\t * reloading */\n\tretval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t smart_ctrl = QN908X_FMC_SMART_CTRL_SMART_WRITEH_EN_MASK |\n\t\tQN908X_FMC_SMART_CTRL_PRGMH_EN_MASK;\n\tretval = target_write_u32(target, QN908X_FMC_SMART_CTRL, smart_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, QN908X_FLASH_LOCK_ADDR,\n\t\t\tQN908X_FLASH_LOCK_ENABLE_MASS_ERASE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = qn908x_wait_for_idle(target, QN908X_DEFAULT_TIMEOUT_MS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Force a page_lock reload after the mass_erase . */\n\tretval = qn908x_load_lock_stat(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic const struct command_registration qn908x_exec_command_handlers[] = {\n\t{\n\t\t.name\t\t= \"allow_brick\",\n\t\t.handler\t= qn908x_handle_allow_brick_command,\n\t\t.mode\t\t= COMMAND_EXEC,\n\t\t.help\t\t= \"Allow writing images that disable SWD access in their \"\n\t\t\t\t\"Code Read Protection (CRP) word. Warning: This can make your \"\n\t\t\t\t\"chip inaccessible from OpenOCD or any other SWD debugger.\",\n\t\t.usage\t\t= \"\",\n\t},\n\t{\n\t\t.name\t\t= \"disable_wdog\",\n\t\t.handler\t= qn908x_handle_disable_wdog_command,\n\t\t.mode\t\t= COMMAND_EXEC,\n\t\t.help\t\t= \"Disabled the watchdog (WDT).\",\n\t\t.usage\t\t= \"\",\n\t},\n\t{\n\t\t.name\t\t= \"mass_erase\",\n\t\t.handler\t= qn908x_handle_mass_erase_command,\n\t\t.mode\t\t= COMMAND_EXEC,\n\t\t.help\t\t= \"Erase the whole flash chip.\",\n\t\t.usage\t\t= \"[keep_lock]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration qn908x_command_handlers[] = {\n\t{\n\t\t.name\t\t= \"qn908x\",\n\t\t.mode\t\t= COMMAND_ANY,\n\t\t.help\t\t= \"qn908x flash controller commands\",\n\t\t.usage\t\t= \"\",\n\t\t.chain\t\t= qn908x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver qn908x_flash = {\n\t.name\t\t\t\t= \"qn908x\",\n\t.commands\t\t\t= qn908x_command_handlers,\n\t.flash_bank_command\t= qn908x_flash_bank_command,\n\t.info\t\t\t\t= qn908x_get_info,\n\t.erase\t\t\t\t= qn908x_erase,\n\t.protect\t\t\t= qn908x_protect,\n\t.write\t\t\t\t= qn908x_write,\n\t.read\t\t\t\t= default_flash_read,\n\t.probe\t\t\t\t= qn908x_probe,\n\t.auto_probe\t\t\t= qn908x_auto_probe,\n\t.erase_check\t\t= default_flash_blank_check,\n\t.protect_check\t\t= qn908x_protect_check,\n\t.free_driver_priv\t= default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/renesas_rpchf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Renesas RCar Gen3 RPC Hyperflash driver\n * Based on U-Boot RPC Hyperflash driver\n *\n * Copyright (C) 2016 Renesas Electronics Corporation\n * Copyright (C) 2016 Cogent Embedded, Inc.\n * Copyright (C) 2017-2019 Marek Vasut <marek.vasut@gmail.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"cfi.h\"\n#include \"non_cfi.h\"\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <helper/time_support.h>\n\n#define RPC_CMNCR\t\t0x0000\t/* R/W */\n#define RPC_CMNCR_MD\t\tBIT(31)\n#define RPC_CMNCR_MOIIO0(val)\t(((val) & 0x3) << 16)\n#define RPC_CMNCR_MOIIO1(val)\t(((val) & 0x3) << 18)\n#define RPC_CMNCR_MOIIO2(val)\t(((val) & 0x3) << 20)\n#define RPC_CMNCR_MOIIO3(val)\t(((val) & 0x3) << 22)\n#define RPC_CMNCR_MOIIO_HIZ\t(RPC_CMNCR_MOIIO0(3) | RPC_CMNCR_MOIIO1(3) | \\\n\t\t\t\t RPC_CMNCR_MOIIO2(3) | RPC_CMNCR_MOIIO3(3))\n#define RPC_CMNCR_IO0FV(val)\t(((val) & 0x3) << 8)\n#define RPC_CMNCR_IO2FV(val)\t(((val) & 0x3) << 12)\n#define RPC_CMNCR_IO3FV(val)\t(((val) & 0x3) << 14)\n#define RPC_CMNCR_IOFV_HIZ\t(RPC_CMNCR_IO0FV(3) | RPC_CMNCR_IO2FV(3) | \\\n\t\t\t\t RPC_CMNCR_IO3FV(3))\n#define RPC_CMNCR_BSZ(val)\t(((val) & 0x3) << 0)\n\n#define RPC_SSLDR\t\t0x0004\t/* R/W */\n#define RPC_SSLDR_SPNDL(d)\t(((d) & 0x7) << 16)\n#define RPC_SSLDR_SLNDL(d)\t(((d) & 0x7) << 8)\n#define RPC_SSLDR_SCKDL(d)\t(((d) & 0x7) << 0)\n\n#define RPC_DRCR\t\t0x000C\t/* R/W */\n#define RPC_DRCR_SSLN\t\tBIT(24)\n#define RPC_DRCR_RBURST(v)\t(((v) & 0x1F) << 16)\n#define RPC_DRCR_RCF\t\tBIT(9)\n#define RPC_DRCR_RBE\t\tBIT(8)\n#define RPC_DRCR_SSLE\t\tBIT(0)\n\n#define RPC_DRCMR\t\t0x0010\t/* R/W */\n#define RPC_DRCMR_CMD(c)\t(((c) & 0xFF) << 16)\n#define RPC_DRCMR_OCMD(c)\t(((c) & 0xFF) << 0)\n\n#define RPC_DREAR\t\t0x0014\t/* R/W */\n#define RPC_DREAR_EAV(v)\t(((v) & 0xFF) << 16)\n#define RPC_DREAR_EAC(v)\t(((v) & 0x7) << 0)\n\n#define RPC_DROPR\t\t0x0018\t/* R/W */\n#define RPC_DROPR_OPD3(o)\t(((o) & 0xFF) << 24)\n#define RPC_DROPR_OPD2(o)\t(((o) & 0xFF) << 16)\n#define RPC_DROPR_OPD1(o)\t(((o) & 0xFF) << 8)\n#define RPC_DROPR_OPD0(o)\t(((o) & 0xFF) << 0)\n\n#define RPC_DRENR\t\t0x001C\t/* R/W */\n#define RPC_DRENR_CDB(o)\t(uint32_t)((((o) & 0x3) << 30))\n#define RPC_DRENR_OCDB(o)\t(((o) & 0x3) << 28)\n#define RPC_DRENR_ADB(o)\t(((o) & 0x3) << 24)\n#define RPC_DRENR_OPDB(o)\t(((o) & 0x3) << 20)\n#define RPC_DRENR_SPIDB(o)\t(((o) & 0x3) << 16)\n#define RPC_DRENR_DME\t\tBIT(15)\n#define RPC_DRENR_CDE\t\tBIT(14)\n#define RPC_DRENR_OCDE\t\tBIT(12)\n#define RPC_DRENR_ADE(v)\t(((v) & 0xF) << 8)\n#define RPC_DRENR_OPDE(v)\t(((v) & 0xF) << 4)\n\n#define RPC_SMCR\t\t0x0020\t/* R/W */\n#define RPC_SMCR_SSLKP\t\tBIT(8)\n#define RPC_SMCR_SPIRE\t\tBIT(2)\n#define RPC_SMCR_SPIWE\t\tBIT(1)\n#define RPC_SMCR_SPIE\t\tBIT(0)\n\n#define RPC_SMCMR\t\t0x0024\t/* R/W */\n#define RPC_SMCMR_CMD(c)\t(((c) & 0xFF) << 16)\n#define RPC_SMCMR_OCMD(c)\t(((c) & 0xFF) << 0)\n\n#define RPC_SMADR\t\t0x0028\t/* R/W */\n#define RPC_SMOPR\t\t0x002C\t/* R/W */\n#define RPC_SMOPR_OPD0(o)\t(((o) & 0xFF) << 0)\n#define RPC_SMOPR_OPD1(o)\t(((o) & 0xFF) << 8)\n#define RPC_SMOPR_OPD2(o)\t(((o) & 0xFF) << 16)\n#define RPC_SMOPR_OPD3(o)\t(((o) & 0xFF) << 24)\n\n#define RPC_SMENR\t\t0x0030\t/* R/W */\n#define RPC_SMENR_CDB(o)\t(((o) & 0x3) << 30)\n#define RPC_SMENR_OCDB(o)\t(((o) & 0x3) << 28)\n#define RPC_SMENR_ADB(o)\t(((o) & 0x3) << 24)\n#define RPC_SMENR_OPDB(o)\t(((o) & 0x3) << 20)\n#define RPC_SMENR_SPIDB(o)\t(((o) & 0x3) << 16)\n#define RPC_SMENR_DME\t\tBIT(15)\n#define RPC_SMENR_CDE\t\tBIT(14)\n#define RPC_SMENR_OCDE\t\tBIT(12)\n#define RPC_SMENR_ADE(v)\t(((v) & 0xF) << 8)\n#define RPC_SMENR_OPDE(v)\t(((v) & 0xF) << 4)\n#define RPC_SMENR_SPIDE(v)\t(((v) & 0xF) << 0)\n\n#define RPC_SMRDR0\t\t0x0038\t/* R */\n#define RPC_SMRDR1\t\t0x003C\t/* R */\n#define RPC_SMWDR0\t\t0x0040\t/* R/W */\n#define RPC_SMWDR1\t\t0x0044\t/* R/W */\n#define RPC_CMNSR\t\t0x0048\t/* R */\n#define RPC_CMNSR_SSLF\t\tBIT(1)\n#define\tRPC_CMNSR_TEND\t\tBIT(0)\n\n#define RPC_DRDMCR\t\t0x0058\t/* R/W */\n#define RPC_DRDMCR_DMCYC(v)\t(((v) & 0xF) << 0)\n\n#define RPC_DRDRENR\t\t0x005C\t/* R/W */\n#define RPC_DRDRENR_HYPE\t(0x5 << 12)\n#define RPC_DRDRENR_ADDRE\tBIT(8)\n#define RPC_DRDRENR_OPDRE\tBIT(4)\n#define RPC_DRDRENR_DRDRE\tBIT(0)\n\n#define RPC_SMDMCR\t\t0x0060\t/* R/W */\n#define RPC_SMDMCR_DMCYC(v)\t(((v) & 0xF) << 0)\n\n#define RPC_SMDRENR\t\t0x0064\t/* R/W */\n#define RPC_SMDRENR_HYPE\t(0x5 << 12)\n#define RPC_SMDRENR_ADDRE\tBIT(8)\n#define RPC_SMDRENR_OPDRE\tBIT(4)\n#define RPC_SMDRENR_SPIDRE\tBIT(0)\n\n#define RPC_PHYCNT\t\t0x007C\t/* R/W */\n#define RPC_PHYCNT_CAL\t\tBIT(31)\n#define PRC_PHYCNT_OCTA_AA\tBIT(22)\n#define PRC_PHYCNT_OCTA_SA\tBIT(23)\n#define PRC_PHYCNT_EXDS\t\tBIT(21)\n#define RPC_PHYCNT_OCT\t\tBIT(20)\n#define RPC_PHYCNT_WBUF2\tBIT(4)\n#define RPC_PHYCNT_WBUF\t\tBIT(2)\n#define RPC_PHYCNT_MEM(v)\t(((v) & 0x3) << 0)\n\n#define RPC_PHYINT\t\t0x0088\t/* R/W */\n#define RPC_PHYINT_RSTEN\tBIT(18)\n#define RPC_PHYINT_WPEN\t\tBIT(17)\n#define RPC_PHYINT_INTEN\tBIT(16)\n#define RPC_PHYINT_RST\t\tBIT(2)\n#define RPC_PHYINT_WP\t\tBIT(1)\n#define RPC_PHYINT_INT\t\tBIT(0)\n\n#define RPC_WBUF\t\t0x8000\t/* R/W size=4/8/16/32/64Bytes */\n#define RPC_WBUF_SIZE\t\t0x100\n\nstatic uint32_t rpc_base = 0xee200000;\nstatic uint32_t mem_base = 0x08000000;\n\nenum rpc_hf_size {\n\tRPC_HF_SIZE_16BIT = RPC_SMENR_SPIDE(0x8),\n\tRPC_HF_SIZE_32BIT = RPC_SMENR_SPIDE(0xC),\n\tRPC_HF_SIZE_64BIT = RPC_SMENR_SPIDE(0xF),\n};\n\nstatic int rpc_hf_wait_tend(struct target *target)\n{\n\tuint32_t reg = rpc_base + RPC_CMNSR;\n\tuint32_t val;\n\tunsigned long timeout = 1000;\n\tlong long endtime;\n\tint ret;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\tret = target_read_u32(target, reg, &val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (val & RPC_CMNSR_TEND)\n\t\t\treturn ERROR_OK;\n\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_TIMEOUT_REACHED;\n}\n\nstatic int clrsetbits_u32(struct target *target, uint32_t reg,\n\t\t\t   uint32_t clr, uint32_t set)\n{\n\tuint32_t val;\n\tint ret;\n\n\tret = target_read_u32(target, reg, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval &= ~clr;\n\tval |= set;\n\n\treturn target_write_u32(target, reg, val);\n}\n\nstatic int rpc_hf_mode(struct target *target, bool manual)\n{\n\tuint32_t val;\n\tint ret;\n\n\tret = rpc_hf_wait_tend(target);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Mode TEND timeout\");\n\t\treturn ret;\n\t}\n\n\tret = clrsetbits_u32(target, rpc_base + RPC_PHYCNT,\n\t\t\t\tRPC_PHYCNT_WBUF | RPC_PHYCNT_WBUF2 |\n\t\t\t\tRPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3),\n\t\t\t\tRPC_PHYCNT_CAL | RPC_PHYCNT_MEM(3));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = clrsetbits_u32(target, rpc_base + RPC_CMNCR,\n\t\t\t\tRPC_CMNCR_MD | RPC_CMNCR_BSZ(3),\n\t\t\t\tRPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |\n\t\t\t\t(manual ? RPC_CMNCR_MD : 0) | RPC_CMNCR_BSZ(1));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (manual)\n\t\treturn ERROR_OK;\n\n\tret = target_write_u32(target, rpc_base + RPC_DRCR,\n\t\t\t       RPC_DRCR_RBURST(0x1F) | RPC_DRCR_RCF |\n\t\t\t       RPC_DRCR_RBE);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_DRCMR,\n\t\t\t       RPC_DRCMR_CMD(0xA0));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tret = target_write_u32(target, rpc_base + RPC_DRENR,\n\t\t\t       RPC_DRENR_CDB(2) | RPC_DRENR_OCDB(2) |\n\t\t\t       RPC_DRENR_ADB(2) | RPC_DRENR_SPIDB(2) |\n\t\t\t       RPC_DRENR_CDE | RPC_DRENR_OCDE |\n\t\t\t       RPC_DRENR_ADE(4));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_DRDMCR,\n\t\t\t       RPC_DRDMCR_DMCYC(0xE));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_DRDRENR,\n\t\t\t       RPC_DRDRENR_HYPE | RPC_DRDRENR_ADDRE |\n\t\t\t       RPC_DRDRENR_DRDRE);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Dummy read */\n\treturn target_read_u32(target, rpc_base + RPC_DRCR, &val);\n}\n\nstatic int rpc_hf_xfer(struct target *target, target_addr_t addr,\n\t\t       uint32_t wdata, uint32_t *rdata, enum rpc_hf_size size,\n\t\t       bool write, const uint8_t *wbuf, unsigned int wbuf_size)\n{\n\tint ret;\n\tuint32_t val;\n\n\tif (wbuf_size != 0) {\n\t\tret = rpc_hf_wait_tend(target);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Xfer TEND timeout\");\n\t\t\treturn ret;\n\t\t}\n\n\t\t/* Write calibration magic */\n\t\tret = target_write_u32(target, rpc_base + RPC_DRCR, 0x01FF0301);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_u32(target, rpc_base + RPC_PHYCNT, 0x80030277);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_memory(target, rpc_base | RPC_WBUF, 4,\n\t\t\t\t\t  wbuf_size / 4, wbuf);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = clrsetbits_u32(target, rpc_base + RPC_CMNCR,\n\t\t\t\t\tRPC_CMNCR_MD | RPC_CMNCR_BSZ(3),\n\t\t\t\t\tRPC_CMNCR_MOIIO_HIZ | RPC_CMNCR_IOFV_HIZ |\n\t\t\t\t\tRPC_CMNCR_MD | RPC_CMNCR_BSZ(1));\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t} else {\n\t\tret = rpc_hf_mode(target, 1);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\t/* Submit HF address, SMCMR CMD[7] ~= CA Bit# 47 (R/nW) */\n\tret = target_write_u32(target, rpc_base + RPC_SMCMR,\n\t\t\t       write ? 0 : RPC_SMCMR_CMD(0x80));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_SMADR,\n\t\t\t       addr >> 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_SMOPR, 0x0);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, rpc_base + RPC_SMDRENR,\n\t\t\t       RPC_SMDRENR_HYPE | RPC_SMDRENR_ADDRE |\n\t\t\t       RPC_SMDRENR_SPIDRE);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval = RPC_SMENR_CDB(2) | RPC_SMENR_OCDB(2) |\n\t      RPC_SMENR_ADB(2) | RPC_SMENR_SPIDB(2) |\n\t      (wbuf_size ? RPC_SMENR_OPDB(2) : 0) |\n\t      RPC_SMENR_CDE | RPC_SMENR_OCDE | RPC_SMENR_ADE(4) | size;\n\n\tif (write) {\n\t\tret = target_write_u32(target, rpc_base + RPC_SMENR, val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (wbuf_size == 0) {\n\t\t\tbuf_bswap32((uint8_t *)&wdata, (uint8_t *)&wdata, 4);\n\t\t\tret = target_write_u32(target, rpc_base + RPC_SMWDR0,\n\t\t\t\t\t       wdata);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\n\t\tret = target_write_u32(target, rpc_base + RPC_SMCR,\n\t\t\t\t       RPC_SMCR_SPIWE | RPC_SMCR_SPIE);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t} else {\n\t\tval |= RPC_SMENR_DME;\n\n\t\tret = target_write_u32(target, rpc_base + RPC_SMDMCR,\n\t\t\t\t       RPC_SMDMCR_DMCYC(0xE));\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_u32(target, rpc_base + RPC_SMENR, val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_u32(target, rpc_base + RPC_SMCR,\n\t\t\t\t       RPC_SMCR_SPIRE | RPC_SMCR_SPIE);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = rpc_hf_wait_tend(target);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tuint32_t val32;\n\t\tret = target_read_u32(target, rpc_base + RPC_SMRDR0, &val32);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\tbuf_bswap32((uint8_t *)&val32, (uint8_t *)&val32, 4);\n\t\t*rdata = val32;\n\t}\n\n\tret = rpc_hf_mode(target, 0);\n\tif (ret != ERROR_OK)\n\t\tLOG_ERROR(\"Xfer done TEND timeout\");\n\treturn ret;\n}\n\nstatic int rpchf_target_write_memory(struct flash_bank *bank, target_addr_t addr,\n\t\t\t\t     uint32_t count, const uint8_t *buffer)\n{\n\tstruct target *target = bank->target;\n\tuint32_t wdata;\n\n\tif (count != 2)\n\t\treturn ERROR_FAIL;\n\n\twdata = buffer[0] | (buffer[1] << 8);\n\n\treturn rpc_hf_xfer(target, addr, wdata, NULL, RPC_HF_SIZE_16BIT,\n\t\t\t   true, NULL, 0);\n}\n\nstatic int rpchf_target_read_memory(struct flash_bank *bank, target_addr_t addr,\n\t\t\t\t    uint32_t count, uint8_t *buffer)\n{\n\tstruct target *target = bank->target;\n\tuint32_t i, rdata;\n\tint ret;\n\n\tfor (i = 0; i < count; i++) {\n\t\tret = rpc_hf_xfer(target, addr + (2 * i), 0, &rdata,\n\t\t\t\t\tRPC_HF_SIZE_16BIT, false, NULL, 0);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\tbuffer[(2 * i) + 0] = rdata & 0xff;\n\t\tbuffer[(2 * i) + 1] = (rdata >> 8) & 0xff;\n\t}\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(rpchf_flash_bank_command)\n{\n\tstruct cfi_flash_bank *cfi_info;\n\tint ret;\n\n\tret = cfi_flash_bank_cmd(bank, CMD_ARGC, CMD_ARGV);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tcfi_info = bank->driver_priv;\n\tcfi_info->read_mem = rpchf_target_read_memory;\n\tcfi_info->write_mem = rpchf_target_write_memory;\n\n\treturn ERROR_OK;\n}\n\nstatic int rpchf_spansion_write_words(struct flash_bank *bank, const uint8_t *word,\n\tuint32_t wordcount, uint32_t address)\n{\n\tint retval;\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct cfi_spansion_pri_ext *pri_ext = cfi_info->pri_ext;\n\n\t/* Calculate buffer size and boundary mask\n\t * buffersize is (buffer size per chip) * (number of chips)\n\t * bufferwsize is buffersize in words */\n\tuint32_t buffersize = RPC_WBUF_SIZE;\n\tuint32_t buffermask = buffersize - 1;\n\tuint32_t bufferwsize = buffersize / 2;\n\n\t/* Check for valid range */\n\tif (address & buffermask) {\n\t\tLOG_ERROR(\"Write address at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32 \" not aligned to 2^%d boundary\",\n\t\t\tbank->base, address, cfi_info->max_buf_write_size);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Check for valid size */\n\tif (wordcount > bufferwsize) {\n\t\tLOG_ERROR(\"Number of data words %\" PRIu32 \" exceeds available buffersize %\"\n\t\t\tPRIu32, wordcount, buffersize);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Unlock */\n\tretval = cfi_spansion_unlock_seq(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cfi_send_command(bank, 0xa0, cfi_flash_address(bank, 0, pri_ext->_unlock1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = rpc_hf_xfer(bank->target, address, 0, NULL, RPC_HF_SIZE_64BIT, true, word, wordcount * 2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cfi_spansion_wait_status_busy(bank, cfi_info->word_write_timeout) != ERROR_OK) {\n\t\tretval = cfi_send_command(bank, 0xf0, cfi_flash_address(bank, 0, 0x0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"couldn't write block at base \" TARGET_ADDR_FMT\n\t\t\t\", address 0x%\" PRIx32 \", size 0x%\" PRIx32, bank->base, address,\n\t\t\tbufferwsize);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rpchf_write_words(struct flash_bank *bank, const uint8_t *word,\n\tuint32_t wordcount, uint32_t address)\n{\n\treturn rpchf_spansion_write_words(bank, word, wordcount, address);\n}\n\nstatic int rpchf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tuint32_t address = bank->base + offset;\t/* address of first byte to be programmed */\n\tuint32_t write_p;\n\tint align;\t/* number of unaligned bytes */\n\tuint8_t current_word[CFI_MAX_BUS_WIDTH * 4];\t/* word (bus_width size) currently being\n\t\t\t\t\t\t\t *programmed */\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* start at the first byte of the first word (bus_width size) */\n\twrite_p = address & ~(bank->bus_width - 1);\n\talign = address - write_p;\n\tif (align != 0) {\n\t\tLOG_INFO(\"Fixup %d unaligned head bytes\", align);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, write_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* replace only bytes that must be written */\n\t\tfor (unsigned int i = align; (i < bank->bus_width) && (count > 0); i++, count--) {\n\t\t\tif (cfi_info->data_swap)\n\t\t\t\t/* data bytes are swapped (reverse endianness) */\n\t\t\t\tcurrent_word[bank->bus_width - i] = *buffer++;\n\t\t\telse\n\t\t\t\tcurrent_word[i] = *buffer++;\n\t\t}\n\n\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twrite_p += bank->bus_width;\n\t}\n\n\t/* Calculate buffer size and boundary mask\n\t * buffersize is (buffer size per chip) * (number of chips)\n\t * bufferwsize is buffersize in words */\n\tuint32_t buffersize = RPC_WBUF_SIZE;\n\tuint32_t buffermask = buffersize-1;\n\tuint32_t bufferwsize = buffersize / bank->bus_width;\n\n\t/* fall back to memory writes */\n\twhile (count >= (uint32_t)bank->bus_width) {\n\t\tbool fallback;\n\t\tif ((write_p & 0xff) == 0) {\n\t\t\tLOG_INFO(\"Programming at 0x%08\" PRIx32 \", count 0x%08\"\n\t\t\t\tPRIx32 \" bytes remaining\", write_p, count);\n\t\t}\n\t\tfallback = true;\n\t\tif ((bufferwsize > 0) && (count >= buffersize) &&\n\t\t\t\t!(write_p & buffermask)) {\n\t\t\tretval = rpchf_write_words(bank, buffer, bufferwsize, write_p);\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tbuffer += buffersize;\n\t\t\t\twrite_p += buffersize;\n\t\t\t\tcount -= buffersize;\n\t\t\t\tfallback = false;\n\t\t\t} else if (retval != ERROR_FLASH_OPER_UNSUPPORTED)\n\t\t\t\treturn retval;\n\t\t}\n\t\t/* try the slow way? */\n\t\tif (fallback) {\n\t\t\tfor (unsigned int i = 0; i < bank->bus_width; i++)\n\t\t\t\tcurrent_word[i] = *buffer++;\n\n\t\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\twrite_p += bank->bus_width;\n\t\t\tcount -= bank->bus_width;\n\t\t}\n\t}\n\n\t/* return to read array mode, so we can read from flash again for padding */\n\tretval = cfi_reset(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* handle unaligned tail bytes */\n\tif (count > 0) {\n\t\tLOG_INFO(\"Fixup %\" PRIu32 \" unaligned tail bytes\", count);\n\n\t\t/* read a complete word from flash */\n\t\tretval = cfi_target_read_memory(bank, write_p, 1, current_word);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* replace only bytes that must be written */\n\t\tfor (unsigned int i = 0; (i < bank->bus_width) && (count > 0); i++, count--)\n\t\t\tif (cfi_info->data_swap)\n\t\t\t\t/* data bytes are swapped (reverse endianness) */\n\t\t\t\tcurrent_word[bank->bus_width - i] = *buffer++;\n\t\t\telse\n\t\t\t\tcurrent_word[i] = *buffer++;\n\n\t\tretval = cfi_write_word(bank, current_word, write_p);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* return to read array mode */\n\treturn cfi_reset(bank);\n}\n\nstatic int rpchf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct cfi_flash_bank *cfi_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tLOG_DEBUG(\"reading buffer of %\" PRIu32 \" byte at 0x%8.8\" PRIx32,\n\t\t  count, offset);\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tif (cfi_info->qry[0] != 'Q')\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\treturn target_read_memory(target, offset | mem_base,\n\t\t\t\t  4, count / 4, buffer);\n}\n\nconst struct flash_driver renesas_rpchf_flash = {\n\t.name = \"rpchf\",\n\t.flash_bank_command = rpchf_flash_bank_command,\n\t.erase = cfi_erase,\n\t.protect = cfi_protect,\n\t.write = rpchf_write,\n\t.read = rpchf_read,\n\t.probe = cfi_probe,\n\t.auto_probe = cfi_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = cfi_protect_check,\n\t.info = cfi_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/rp2040.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include \"spi.h\"\n\n/* NOTE THAT THIS CODE REQUIRES FLASH ROUTINES in BOOTROM WITH FUNCTION TABLE PTR AT 0x00000010\n   Your gdbinit should load the bootrom.elf if appropriate */\n\n/* this is 'M' 'u', 1 (version) */\n#define BOOTROM_MAGIC 0x01754d\n#define BOOTROM_MAGIC_ADDR 0x00000010\n\n/* Call a ROM function via the debug trampoline\n   Up to four arguments passed in r0...r3 as per ABI\n   Function address is passed in r7\n   the trampoline is needed because OpenOCD \"algorithm\" code insists on sw breakpoints. */\n\n#define MAKE_TAG(a, b) (((b)<<8) | a)\n#define FUNC_DEBUG_TRAMPOLINE       MAKE_TAG('D', 'T')\n#define FUNC_DEBUG_TRAMPOLINE_END   MAKE_TAG('D', 'E')\n#define FUNC_FLASH_EXIT_XIP         MAKE_TAG('E', 'X')\n#define FUNC_CONNECT_INTERNAL_FLASH MAKE_TAG('I', 'F')\n#define FUNC_FLASH_RANGE_ERASE      MAKE_TAG('R', 'E')\n#define FUNC_FLASH_RANGE_PROGRAM    MAKE_TAG('R', 'P')\n#define FUNC_FLASH_FLUSH_CACHE      MAKE_TAG('F', 'C')\n#define FUNC_FLASH_ENTER_CMD_XIP    MAKE_TAG('C', 'X')\n\nstruct rp2040_flash_bank {\n\t/* flag indicating successful flash probe */\n\tbool probed;\n\t/* stack used by Boot ROM calls */\n\tstruct working_area *stack;\n\t/* function jump table populated by rp2040_flash_probe() */\n\tuint16_t jump_debug_trampoline;\n\tuint16_t jump_debug_trampoline_end;\n\tuint16_t jump_flash_exit_xip;\n\tuint16_t jump_connect_internal_flash;\n\tuint16_t jump_flash_range_erase;\n\tuint16_t jump_flash_range_program;\n\tuint16_t jump_flush_cache;\n\tuint16_t jump_enter_cmd_xip;\n\t/* detected model of SPI flash */\n\tconst struct flash_device *dev;\n};\n\n/* guessed SPI flash description if autodetection disabled (same as win w25q16jv) */\nstatic const struct flash_device rp2040_default_spi_device =\n\tFLASH_ID(\"autodetect disabled\", 0x03, 0x00, 0x02, 0xd8, 0xc7, 0, 0x100, 0x10000, 0);\n\nstatic uint32_t rp2040_lookup_symbol(struct target *target, uint32_t tag, uint16_t *symbol)\n{\n\tuint32_t magic;\n\tint err = target_read_u32(target, BOOTROM_MAGIC_ADDR, &magic);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tmagic &= 0xffffff; /* ignore bootrom version */\n\tif (magic != BOOTROM_MAGIC) {\n\t\tif (!((magic ^ BOOTROM_MAGIC)&0xffff))\n\t\t\tLOG_ERROR(\"Incorrect RP2040 BOOT ROM version\");\n\t\telse\n\t\t\tLOG_ERROR(\"RP2040 BOOT ROM not found\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* dereference the table pointer */\n\tuint16_t table_entry;\n\terr = target_read_u16(target, BOOTROM_MAGIC_ADDR + 4, &table_entry);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tuint16_t entry_tag;\n\tdo {\n\t\terr = target_read_u16(target, table_entry, &entry_tag);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tif (entry_tag == tag) {\n\t\t\t/* 16 bit symbol is next */\n\t\t\treturn target_read_u16(target, table_entry + 2, symbol);\n\t\t}\n\t\ttable_entry += 4;\n\t} while (entry_tag);\n\treturn ERROR_FAIL;\n}\n\nstatic int rp2040_call_rom_func(struct target *target, struct rp2040_flash_bank *priv,\n\t\tuint16_t func_offset, uint32_t argdata[], unsigned int n_args, unsigned int timeout_ms)\n{\n\tchar *regnames[4] = { \"r0\", \"r1\", \"r2\", \"r3\" };\n\n\tassert(n_args <= ARRAY_SIZE(regnames)); /* only allow register arguments */\n\n\tif (!priv->stack) {\n\t\tLOG_ERROR(\"no stack for flash programming code\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\ttarget_addr_t stacktop = priv->stack->address + priv->stack->size;\n\n\tLOG_TARGET_DEBUG(target, \"Calling ROM func @0x%\" PRIx16 \" with %u arguments\", func_offset, n_args);\n\n\tstruct reg_param args[ARRAY_SIZE(regnames) + 2];\n\tstruct armv7m_algorithm alg_info;\n\n\tfor (unsigned int i = 0; i < n_args; ++i) {\n\t\tinit_reg_param(&args[i], regnames[i], 32, PARAM_OUT);\n\t\tbuf_set_u32(args[i].value, 0, 32, argdata[i]);\n\t}\n\t/* Pass function pointer in r7 */\n\tinit_reg_param(&args[n_args], \"r7\", 32, PARAM_OUT);\n\tbuf_set_u32(args[n_args].value, 0, 32, func_offset);\n\t/* Setup stack */\n\tinit_reg_param(&args[n_args + 1], \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(args[n_args + 1].value, 0, 32, stacktop);\n\tunsigned int n_reg_params = n_args + 2;\t/* User arguments + r7 + sp */\n\n\tfor (unsigned int i = 0; i < n_reg_params; ++i)\n\t\tLOG_DEBUG(\"Set %s = 0x%\" PRIx32, args[i].reg_name, buf_get_u32(args[i].value, 0, 32));\n\n\t/* Actually call the function */\n\talg_info.common_magic = ARMV7M_COMMON_MAGIC;\n\talg_info.core_mode = ARM_MODE_THREAD;\n\tint err = target_run_algorithm(\n\t\ttarget,\n\t\t0, NULL,          /* No memory arguments */\n\t\tn_reg_params, args, /* User arguments + r7 + sp */\n\t\tpriv->jump_debug_trampoline, priv->jump_debug_trampoline_end,\n\t\ttimeout_ms,\n\t\t&alg_info\n\t);\n\n\tfor (unsigned int i = 0; i < n_reg_params; ++i)\n\t\tdestroy_reg_param(&args[i]);\n\n\tif (err != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to invoke ROM function @0x%\" PRIx16, func_offset);\n\n\treturn err;\n}\n\n/* Finalize flash write/erase/read ID\n * - flush cache\n * - enters memory-mapped (XIP) mode to make flash data visible\n * - deallocates target ROM func stack if previously allocated\n */\nstatic int rp2040_finalize_stack_free(struct flash_bank *bank)\n{\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\t/* Always flush before returning to execute-in-place, to invalidate stale\n\t * cache contents. The flush call also restores regular hardware-controlled\n\t * chip select following a rp2040_flash_exit_xip().\n\t */\n\tLOG_DEBUG(\"Flushing flash cache after write behind\");\n\tint err = rp2040_call_rom_func(target, priv, priv->jump_flush_cache, NULL, 0, 1000);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to flush flash cache\");\n\t\t/* Intentionally continue after error and try to setup xip anyway */\n\t}\n\n\tLOG_DEBUG(\"Configuring SSI for execute-in-place\");\n\terr = rp2040_call_rom_func(target, priv, priv->jump_enter_cmd_xip, NULL, 0, 1000);\n\tif (err != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to set SSI to XIP mode\");\n\n\ttarget_free_working_area(target, priv->stack);\n\tpriv->stack = NULL;\n\treturn err;\n}\n\n/* Prepare flash write/erase/read ID\n * - allocates a stack for target ROM func\n * - switches the SPI interface from memory-mapped mode to direct command mode\n * Always pair with a call of rp2040_finalize_stack_free()\n * after flash operation finishes or fails.\n */\nstatic int rp2040_stack_grab_and_prep(struct flash_bank *bank)\n{\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\t/* target_alloc_working_area always allocates multiples of 4 bytes, so no worry about alignment */\n\tconst int STACK_SIZE = 256;\n\tint err = target_alloc_working_area(target, STACK_SIZE, &priv->stack);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not allocate stack for flash programming code\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tLOG_DEBUG(\"Connecting internal flash\");\n\terr = rp2040_call_rom_func(target, priv, priv->jump_connect_internal_flash, NULL, 0, 1000);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to connect internal flash\");\n\t\treturn err;\n\t}\n\n\tLOG_DEBUG(\"Kicking flash out of XIP mode\");\n\terr = rp2040_call_rom_func(target, priv, priv->jump_flash_exit_xip, NULL, 0, 1000);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exit flash XIP mode\");\n\t\treturn err;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rp2040_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tLOG_DEBUG(\"Writing %d bytes starting at 0x%\" PRIx32, count, offset);\n\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct working_area *bounce = NULL;\n\n\tint err = rp2040_stack_grab_and_prep(bank);\n\tif (err != ERROR_OK)\n\t\tgoto cleanup;\n\n\tunsigned int avail_pages = target_get_working_area_avail(target) / priv->dev->pagesize;\n\t/* We try to allocate working area rounded down to device page size,\n\t * al least 1 page, at most the write data size\n\t */\n\tunsigned int chunk_size = MIN(MAX(avail_pages, 1) * priv->dev->pagesize, count);\n\terr = target_alloc_working_area(target, chunk_size, &bounce);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not allocate bounce buffer for flash programming. Can't continue\");\n\t\tgoto cleanup;\n\t}\n\n\tLOG_DEBUG(\"Allocated flash bounce buffer @\" TARGET_ADDR_FMT, bounce->address);\n\n\twhile (count > 0) {\n\t\tuint32_t write_size = count > chunk_size ? chunk_size : count;\n\t\tLOG_DEBUG(\"Writing %d bytes to offset 0x%\" PRIx32, write_size, offset);\n\t\terr = target_write_buffer(target, bounce->address, write_size, buffer);\n\t\tif (err != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not load data into target bounce buffer\");\n\t\t\tbreak;\n\t\t}\n\t\tuint32_t args[3] = {\n\t\t\toffset, /* addr */\n\t\t\tbounce->address, /* data */\n\t\t\twrite_size /* count */\n\t\t};\n\t\terr = rp2040_call_rom_func(target, priv, priv->jump_flash_range_program,\n\t\t\t\t\t\t\t\t args, ARRAY_SIZE(args), 3000);\n\t\tif (err != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to invoke flash programming code on target\");\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += write_size;\n\t\toffset += write_size;\n\t\tcount -= write_size;\n\t}\n\ncleanup:\n\ttarget_free_working_area(target, bounce);\n\n\trp2040_finalize_stack_free(bank);\n\n\treturn err;\n}\n\nstatic int rp2040_flash_erase(struct flash_bank *bank, unsigned int first, unsigned int last)\n{\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t start_addr = bank->sectors[first].offset;\n\tuint32_t length = bank->sectors[last].offset + bank->sectors[last].size - start_addr;\n\tLOG_DEBUG(\"RP2040 erase %d bytes starting at 0x%\" PRIx32, length, start_addr);\n\n\tint err = rp2040_stack_grab_and_prep(bank);\n\tif (err != ERROR_OK)\n\t\tgoto cleanup;\n\n\tLOG_DEBUG(\"Remote call flash_range_erase\");\n\n\tuint32_t args[4] = {\n\t\tbank->sectors[first].offset, /* addr */\n\t\tbank->sectors[last].offset + bank->sectors[last].size - bank->sectors[first].offset, /* count */\n\t\tpriv->dev->sectorsize, /* block_size */\n\t\tpriv->dev->erase_cmd /* block_cmd */\n\t};\n\n\t/*\n\tThe RP2040 Boot ROM provides a _flash_range_erase() API call documented in Section 2.8.3.1.3:\n\thttps://datasheets.raspberrypi.org/rp2040/rp2040-datasheet.pdf\n\tand the particular source code for said Boot ROM function can be found here:\n\thttps://github.com/raspberrypi/pico-bootrom/blob/master/bootrom/program_flash_generic.c\n\n\tIn theory, the function algorithm provides for erasing both a smaller \"sector\" (4096 bytes) and\n\tan optional larger \"block\" (size and command provided in args).\n\t*/\n\n\tunsigned int timeout_ms = 2000 * (last - first) + 1000;\n\terr = rp2040_call_rom_func(target, priv, priv->jump_flash_range_erase,\n\t\t\t\t\t\t\targs, ARRAY_SIZE(args), timeout_ms);\n\ncleanup:\n\trp2040_finalize_stack_free(bank);\n\n\treturn err;\n}\n\n/* -----------------------------------------------------------------------------\n   Driver probing etc */\n\nstatic int rp2040_ssel_active(struct target *target, bool active)\n{\n\tconst target_addr_t qspi_ctrl_addr = 0x4001800c;\n\tconst uint32_t qspi_ctrl_outover_low  = 2UL << 8;\n\tconst uint32_t qspi_ctrl_outover_high = 3UL << 8;\n\tuint32_t state = (active) ? qspi_ctrl_outover_low : qspi_ctrl_outover_high;\n\tuint32_t val;\n\n\tint err = target_read_u32(target, qspi_ctrl_addr, &val);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tval = (val & ~qspi_ctrl_outover_high) | state;\n\n\terr = target_write_u32(target, qspi_ctrl_addr, val);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nstatic int rp2040_spi_read_flash_id(struct target *target, uint32_t *devid)\n{\n\tuint32_t device_id = 0;\n\tconst target_addr_t ssi_dr0 = 0x18000060;\n\n\tint err = rp2040_ssel_active(target, true);\n\n\t/* write RDID request into SPI peripheral's FIFO */\n\tfor (int count = 0; (count < 4) && (err == ERROR_OK); count++)\n\t\terr = target_write_u32(target, ssi_dr0, SPIFLASH_READ_ID);\n\n\t/* by this time, there is a receive FIFO entry for every write */\n\tfor (int count = 0; (count < 4) && (err == ERROR_OK); count++) {\n\t\tuint32_t status;\n\t\terr = target_read_u32(target, ssi_dr0, &status);\n\n\t\tdevice_id >>= 8;\n\t\tdevice_id |= (status & 0xFF) << 24;\n\t}\n\n\tif (err == ERROR_OK)\n\t\t*devid = device_id >> 8;\n\n\tint err2 = rp2040_ssel_active(target, false);\n\tif (err2 != ERROR_OK)\n\t\tLOG_ERROR(\"SSEL inactive failed\");\n\n\treturn err;\n}\n\nstatic int rp2040_flash_probe(struct flash_bank *bank)\n{\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint err = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE, &priv->jump_debug_trampoline);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Debug trampoline not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\tpriv->jump_debug_trampoline &= ~1u; /* mask off thumb bit */\n\n\terr = rp2040_lookup_symbol(target, FUNC_DEBUG_TRAMPOLINE_END, &priv->jump_debug_trampoline_end);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Debug trampoline end not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\tpriv->jump_debug_trampoline_end &= ~1u; /* mask off thumb bit */\n\n\terr = rp2040_lookup_symbol(target, FUNC_FLASH_EXIT_XIP, &priv->jump_flash_exit_xip);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_FLASH_EXIT_XIP not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\terr = rp2040_lookup_symbol(target, FUNC_CONNECT_INTERNAL_FLASH, &priv->jump_connect_internal_flash);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_CONNECT_INTERNAL_FLASH not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\terr = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_ERASE, &priv->jump_flash_range_erase);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_FLASH_RANGE_ERASE not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\terr = rp2040_lookup_symbol(target, FUNC_FLASH_RANGE_PROGRAM, &priv->jump_flash_range_program);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_FLASH_RANGE_PROGRAM not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\terr = rp2040_lookup_symbol(target, FUNC_FLASH_FLUSH_CACHE, &priv->jump_flush_cache);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_FLASH_FLUSH_CACHE not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\terr = rp2040_lookup_symbol(target, FUNC_FLASH_ENTER_CMD_XIP, &priv->jump_enter_cmd_xip);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"Function FUNC_FLASH_ENTER_CMD_XIP not found in RP2040 ROM.\");\n\t\treturn err;\n\t}\n\n\tif (bank->size) {\n\t\t/* size overridden, suppress reading SPI flash ID */\n\t\tpriv->dev = &rp2040_default_spi_device;\n\t\tLOG_DEBUG(\"SPI flash autodetection disabled, using configured size\");\n\n\t} else {\n\t\t/* zero bank size in cfg, read SPI flash ID and autodetect */\n\t\terr = rp2040_stack_grab_and_prep(bank);\n\n\t\tuint32_t device_id = 0;\n\t\tif (err == ERROR_OK)\n\t\t\terr = rp2040_spi_read_flash_id(target, &device_id);\n\n\t\trp2040_finalize_stack_free(bank);\n\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\t/* search for a SPI flash Device ID match */\n\t\tpriv->dev = NULL;\n\t\tfor (const struct flash_device *p = flash_devices; p->name ; p++)\n\t\t\tif (p->device_id == device_id) {\n\t\t\t\tpriv->dev = p;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tif (!priv->dev) {\n\t\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", device_id);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"Found flash device '%s' (ID 0x%08\" PRIx32 \")\",\n\t\t\tpriv->dev->name, priv->dev->device_id);\n\n\t\tbank->size = priv->dev->size_in_bytes;\n\t}\n\n\t/* the Boot ROM flash_range_program() routine requires page alignment */\n\tbank->write_start_alignment = priv->dev->pagesize;\n\tbank->write_end_alignment = priv->dev->pagesize;\n\n\tbank->num_sectors = bank->size / priv->dev->sectorsize;\n\tLOG_INFO(\"RP2040 B0 Flash Probe: %\" PRIu32 \" bytes @\" TARGET_ADDR_FMT \", in %u sectors\\n\",\n\t\tbank->size, bank->base, bank->num_sectors);\n\tbank->sectors = alloc_block_array(0, priv->dev->sectorsize, bank->num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tif (err == ERROR_OK)\n\t\tpriv->probed = true;\n\n\treturn err;\n}\n\nstatic int rp2040_flash_auto_probe(struct flash_bank *bank)\n{\n\tstruct rp2040_flash_bank *priv = bank->driver_priv;\n\n\tif (priv->probed)\n\t\treturn ERROR_OK;\n\n\treturn rp2040_flash_probe(bank);\n}\n\nstatic void rp2040_flash_free_driver_priv(struct flash_bank *bank)\n{\n\tfree(bank->driver_priv);\n\tbank->driver_priv = NULL;\n}\n\n/* -----------------------------------------------------------------------------\n   Driver boilerplate */\n\nFLASH_BANK_COMMAND_HANDLER(rp2040_flash_bank_command)\n{\n\tstruct rp2040_flash_bank *priv;\n\tpriv = malloc(sizeof(struct rp2040_flash_bank));\n\tpriv->probed = false;\n\n\t/* Set up driver_priv */\n\tbank->driver_priv = priv;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver rp2040_flash = {\n\t.name = \"rp2040_flash\",\n\t.flash_bank_command = rp2040_flash_bank_command,\n\t.erase =  rp2040_flash_erase,\n\t.write = rp2040_flash_write,\n\t.read = default_flash_read,\n\t.probe = rp2040_flash_probe,\n\t.auto_probe = rp2040_flash_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.free_driver_priv = rp2040_flash_free_driver_priv\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/rsl10.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Toms Stūrmanis                                  *\n *   toms.sturmanis@gmail.com                                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n#include \"imp.h\"\n\n#define RSL10_FLASH_ADDRESS_MAIN              0x00100000\n#define RSL10_FLASH_ADDRESS_NVR1              0x00080000\n#define RSL10_FLASH_ADDRESS_NVR2              0x00080800\n#define RSL10_FLASH_ADDRESS_NVR3              0x00081000\n#define RSL10_FLASH_ADDRESS_NVR4              0x00081800\n#define RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING 0x00081040\n\n#define RSL10_REG_ID 0x1FFFFFFC\n\n#define RSL10_FLASH_REG_MAIN_WRITE_UNLOCK 0x40000504\n#define RSL10_FLASH_REG_MAIN_CTRL         0x40000508\n#define RSL10_FLASH_REG_IF_STATUS         0x40000538\n#define RSL10_FLASH_REG_NVR_WRITE_UNLOCK  0x40000548\n#define RSL10_FLASH_REG_NVR_CTRL          0x4000054C\n\n#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1 0x400000F0\n#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY2 0x400000F4\n#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY3 0x400000F8\n#define RSL10_FLASH_REG_DEBUG_UNLOCK_KEY4 0x400000FC\n\n#define RSL10_NVR3_USER_KEY_OFFSET 0x40\n\n#define RSL10_ID             0x09010106\n#define RSL10_FLASH_KEY_MAIN 0xDBC8264E\n#define RSL10_FLASH_KEY_NVR  0x71B371F5\n#define RSL10_KEY_DEBUG_LOCK 0x4C6F634B\n\n#define RSL10_FLASH_REG_MAIN_CTRL_LOW_W_ENABLE    BIT(0)\n#define RSL10_FLASH_REG_MAIN_CTRL_MIDDLE_W_ENABLE BIT(1)\n#define RSL10_FLASH_REG_MAIN_CTRL_HIGH_W_ENABLE   BIT(2)\n\n#define RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE BIT(1)\n#define RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE BIT(2)\n#define RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE BIT(3)\n\n#define RSL10_FLASH_REG_STATUS_LOW_W_UNLOCKED    BIT(0)\n#define RSL10_FLASH_REG_STATUS_MIDDLE_W_UNLOCKED BIT(1)\n#define RSL10_FLASH_REG_STATUS_HIGH_W_UNLOCKED   BIT(2)\n#define RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED   BIT(4)\n#define RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED   BIT(5)\n#define RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED   BIT(6)\n\n#define RSL10_ROM_CMD_WRITE_WORD_PAIR 0x3C\n#define RSL10_ROM_CMD_WRITE_BUFFER    0x40\n#define RSL10_ROM_CMD_ERASE_SECTOR    0x44\n#define RSL10_ROM_CMD_ERASE_ALL       0x48\n\n#define FLASH_SECTOR_SIZE 0x2000\n\n#define RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE FLASH_SECTOR_SIZE\n\n#define ALGO_STACK_POINTER_ADDR  0x20002000\n\n/* Used to launch flash related functions from ROM\n * Params :\n * r0-r2 = arguments\n * r3 = target address in rom\n */\nstatic const uint8_t rsl10_rom_launcher_code[] = {\n#include \"../../../contrib/loaders/flash/rsl10/rom_launcher.inc\"\n};\n\nenum rsl10_flash_status {\n\tRSL10_FLASH_ERR_NONE              = 0x0,\n\tRSL10_FLASH_ERR_GENERAL_FAILURE   = 0x1,\n\tRSL10_FLASH_ERR_WRITE_NOT_ENABLED = 0x2,\n\tRSL10_FLASH_ERR_BAD_ADDRESS       = 0x3,\n\tRSL10_FLASH_ERR_ERASE_FAILED      = 0x4,\n\tRSL10_FLASH_ERR_BAD_LENGTH        = 0x5,\n\tRSL10_FLASH_ERR_INACCESSIBLE      = 0x6,\n\tRSL10_FLASH_ERR_COPIER_BUSY       = 0x7,\n\tRSL10_FLASH_ERR_PROG_FAILED       = 0x8,\n\tRSL10_FLASH_MAX_ERR_CODES /* must be the last one */\n};\n\nstatic const char *const rsl10_error_list[] = {\n\t[RSL10_FLASH_ERR_GENERAL_FAILURE]   = \"general failure\",\n\t[RSL10_FLASH_ERR_WRITE_NOT_ENABLED] = \"write not enabled, protected\",\n\t[RSL10_FLASH_ERR_BAD_ADDRESS]       = \"bad address\",\n\t[RSL10_FLASH_ERR_ERASE_FAILED]      = \"erase failed\",\n\t[RSL10_FLASH_ERR_BAD_LENGTH]        = \"bad length\",\n\t[RSL10_FLASH_ERR_INACCESSIBLE]      = \"inaccessible: not powered up, or isolated\",\n\t[RSL10_FLASH_ERR_COPIER_BUSY]       = \"copier busy\",\n\t[RSL10_FLASH_ERR_PROG_FAILED]       = \"prog failed\",\n};\n\nstatic const char *rsl10_error(enum rsl10_flash_status x)\n{\n\tif (x >= RSL10_FLASH_MAX_ERR_CODES || !rsl10_error_list[x])\n\t\treturn \"unknown\";\n\treturn rsl10_error_list[x];\n}\n\nconst struct flash_driver rsl10_flash;\n\nstruct rsl10_info {\n\tunsigned int refcount;\n\n\tstruct rsl10_bank {\n\t\tstruct rsl10_info *chip;\n\t\tbool probed;\n\t} bank[5];\n\tstruct target *target;\n\n\tunsigned int flash_size_kb;\n};\n\nstatic bool rsl10_bank_is_probed(const struct flash_bank *bank)\n{\n\tstruct rsl10_bank *nbank = bank->driver_priv;\n\tassert(nbank);\n\treturn nbank->probed;\n}\n\nstatic int rsl10_probe(struct flash_bank *bank);\n\nstatic int rsl10_get_probed_chip_if_halted(struct flash_bank *bank, struct rsl10_info **chip)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct rsl10_bank *nbank = bank->driver_priv;\n\t*chip                    = nbank->chip;\n\n\tif (rsl10_bank_is_probed(bank))\n\t\treturn ERROR_OK;\n\n\treturn rsl10_probe(bank);\n}\n\nstatic int rsl10_protect_check(struct flash_bank *bank)\n{\n\tstruct rsl10_bank *nbank = bank->driver_priv;\n\tstruct rsl10_info *chip  = nbank->chip;\n\n\tassert(chip);\n\n\tuint32_t status;\n\n\tint retval = target_read_u32(bank->target, RSL10_FLASH_REG_IF_STATUS, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (bank->base == RSL10_FLASH_ADDRESS_MAIN) {\n\t\tfor (unsigned int i = 0; i < bank->num_prot_blocks; i++)\n\t\t\tbank->prot_blocks[i].is_protected = (status & (1 << i)) ? 0 : 1;\n\n\t} else {\n\t\tuint32_t test_bit = 0;\n\t\tswitch (bank->base) {\n\t\tcase RSL10_FLASH_ADDRESS_NVR1:\n\t\t\ttest_bit = RSL10_FLASH_REG_STATUS_NVR1_W_UNLOCKED;\n\t\t\tbreak;\n\t\tcase RSL10_FLASH_ADDRESS_NVR2:\n\t\t\ttest_bit = RSL10_FLASH_REG_STATUS_NVR2_W_UNLOCKED;\n\t\t\tbreak;\n\t\tcase RSL10_FLASH_ADDRESS_NVR3:\n\t\t\ttest_bit = RSL10_FLASH_REG_STATUS_NVR3_W_UNLOCKED;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tbank->sectors[0].is_protected = (status & test_bit) ? 0 : 1;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int rsl10_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)\n{\n\n\tstruct rsl10_info *chip;\n\tint retval = rsl10_get_probed_chip_if_halted(bank, &chip);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (bank->base == RSL10_FLASH_ADDRESS_MAIN) {\n\t\tuint32_t status;\n\t\tretval = target_read_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (unsigned int i = first; i <= last; i++) {\n\t\t\tif (set)\n\t\t\t\tstatus &= ~(1 << i);\n\t\t\telse\n\t\t\t\tstatus |= (1 << i);\n\t\t}\n\n\t\tretval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_CTRL, status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = target_write_u32(bank->target, RSL10_FLASH_REG_MAIN_WRITE_UNLOCK, RSL10_FLASH_KEY_MAIN);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tuint32_t bit = 0;\n\t\tswitch (bank->base) {\n\t\tcase RSL10_FLASH_ADDRESS_NVR1:\n\t\t\tbit = RSL10_FLASH_REG_NVR_CTRL_NVR1_W_ENABLE;\n\t\t\tbreak;\n\t\tcase RSL10_FLASH_ADDRESS_NVR2:\n\t\t\tbit = RSL10_FLASH_REG_NVR_CTRL_NVR2_W_ENABLE;\n\t\t\tbreak;\n\t\tcase RSL10_FLASH_ADDRESS_NVR3:\n\t\t\tbit = RSL10_FLASH_REG_NVR_CTRL_NVR3_W_ENABLE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tuint32_t status;\n\t\tretval = target_read_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (set)\n\t\t\tstatus &= ~bit;\n\t\telse\n\t\t\tstatus |= bit;\n\n\t\tretval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_CTRL, status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = target_write_u32(bank->target, RSL10_FLASH_REG_NVR_WRITE_UNLOCK, RSL10_FLASH_KEY_NVR);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rsl10_check_device(struct flash_bank *bank)\n{\n\tuint32_t configid;\n\tint retval = target_read_u32(bank->target, RSL10_REG_ID, &configid);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (configid != RSL10_ID) {\n\t\tLOG_ERROR(\"This is not supported (RSL10) device, use other flash driver!!!\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int rsl10_probe(struct flash_bank *bank)\n{\n\tstruct rsl10_bank *nbank = bank->driver_priv;\n\tstruct rsl10_info *chip  = nbank->chip;\n\n\tint retval = rsl10_check_device(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tunsigned int bank_id;\n\tunsigned int num_prot_blocks = 0;\n\tswitch (bank->base) {\n\tcase RSL10_FLASH_ADDRESS_MAIN:\n\t\tbank_id         = 0;\n\t\tnum_prot_blocks = 3;\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR1:\n\t\tbank_id = 1;\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR2:\n\t\tbank_id = 2;\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR3:\n\t\tbank_id = 3;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t flash_page_size = 2048;\n\n\tbank->write_start_alignment = 8;\n\tbank->write_end_alignment   = 8;\n\n\tbank->num_sectors   = bank->size / flash_page_size;\n\tchip->flash_size_kb = bank->size / 1024;\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tbank->sectors = alloc_block_array(0, flash_page_size, bank->num_sectors);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tfree(bank->prot_blocks);\n\tbank->prot_blocks = NULL;\n\n\tif (num_prot_blocks > 0) {\n\t\tbank->num_prot_blocks = num_prot_blocks;\n\t\tbank->prot_blocks     = alloc_block_array(0, bank->num_sectors / 3 * flash_page_size, bank->num_prot_blocks);\n\t\tif (!bank->prot_blocks)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tchip->bank[bank_id].probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int rsl10_auto_probe(struct flash_bank *bank)\n{\n\tif (rsl10_bank_is_probed(bank))\n\t\treturn ERROR_OK;\n\n\treturn rsl10_probe(bank);\n}\n\nstatic int rsl10_ll_flash_erase(struct rsl10_info *chip, uint32_t address)\n{\n\tstruct target *target = chip->target;\n\tstruct working_area *write_algorithm;\n\n\tLOG_DEBUG(\"erasing buffer flash address=0x%\" PRIx32, address);\n\n\tint retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Current working area 0x%x is too small! Increase working area size!\", target->working_area_size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval =\n\t\ttarget_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);\n\tif (retval != ERROR_OK)\n\t\tgoto free_algorithm;\n\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_info;\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode    = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* address */\n\tinit_reg_param(&reg_params[1], \"r3\", 32, PARAM_OUT);    /* cmd */\n\tinit_reg_param(&reg_params[2], \"sp\", 32, PARAM_OUT);    /* stack pointer */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\tuint32_t cmd;\n\tretval = target_read_u32(target, RSL10_ROM_CMD_ERASE_SECTOR, &cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto free_reg_params;\n\tbuf_set_u32(reg_params[1].value, 0, 32, cmd);\n\tbuf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);\n\n\tretval = target_run_algorithm(\n\t\ttarget, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,\n\t\twrite_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info\n\t);\n\tif (retval != ERROR_OK)\n\t\tgoto free_reg_params;\n\n\tint algo_ret = buf_get_u32(reg_params[0].value, 0, 32);\n\tif (algo_ret != RSL10_FLASH_ERR_NONE) {\n\t\tLOG_ERROR(\"RSL10 ERASE ERROR: '%s' (%d)\", rsl10_error(algo_ret), algo_ret);\n\t\tretval = ERROR_FLASH_SECTOR_NOT_ERASED;\n\t}\n\nfree_reg_params:\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nfree_algorithm:\n\ttarget_free_working_area(target, write_algorithm);\n\treturn retval;\n}\n\nstatic int rsl10_ll_flash_write(struct rsl10_info *chip, uint32_t address, const uint8_t *buffer, uint32_t bytes)\n{\n\tstruct target *target = chip->target;\n\tstruct working_area *write_algorithm;\n\n\tif (bytes == 8) {\n\t\tuint32_t data;\n\t\tdata = buf_get_u32(buffer, 0, 32);\n\t\tLOG_DEBUG(\"Writing 0x%\" PRIx32 \" to flash address=0x%\" PRIx32 \" bytes=0x%\" PRIx32, data, address, bytes);\n\t} else\n\t\tLOG_DEBUG(\"Writing buffer to flash address=0x%\" PRIx32 \" bytes=0x%\" PRIx32, address, bytes);\n\n\t/* allocate working area with flash programming code */\n\tint retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Current working area 0x%x is too small! Increase working area size!\", target->working_area_size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval =\n\t\ttarget_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);\n\tif (retval != ERROR_OK)\n\t\tgoto free_algorithm;\n\n\t/* memory buffer, rounded down, to be multiple of 8 */\n\tuint32_t buffer_avail = target_get_working_area_avail(target) & ~7;\n\tuint32_t buffer_size  = MIN(RSL10_ROM_CMD_WRITE_BUFFER_MAX_SIZE, buffer_avail);\n\tstruct working_area *source;\n\tretval = target_alloc_working_area(target, buffer_size, &source);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Current working area 0x%x is too small! Increase working area size!\", target->working_area_size);\n\t\tgoto free_algorithm;\n\t}\n\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode    = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* start addr, return value */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);    /* length */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);    /* data */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);    /* cmd */\n\tinit_reg_param(&reg_params[4], \"sp\", 32, PARAM_OUT);    /* stack pointer */\n\tbuf_set_u32(reg_params[4].value, 0, 32, ALGO_STACK_POINTER_ADDR);\n\n\tuint32_t cmd             = 0;\n\tuint32_t sent_bytes      = 0;\n\tuint32_t write_address   = 0;\n\tuint32_t bytes_to_send   = 0;\n\tuint32_t remaining_bytes = 0;\n\n\tretval = target_read_u32(target, RSL10_ROM_CMD_WRITE_BUFFER, &cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto free_everything;\n\n\twhile (sent_bytes < bytes) {\n\t\tremaining_bytes = bytes - sent_bytes;\n\t\tbytes_to_send   = remaining_bytes >= buffer_size ? buffer_size : remaining_bytes;\n\n\t\tretval = target_write_buffer(target, source->address, bytes_to_send, buffer + sent_bytes);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto free_everything;\n\n\t\twrite_address = address + sent_bytes;\n\n\t\tLOG_DEBUG(\n\t\t\t\"write_address: 0x%\" PRIx32 \", words: 0x%\" PRIx32 \", source: 0x%\" PRIx64 \", cmd: 0x%\" PRIx32, write_address,\n\t\t\tbytes_to_send / 4, source->address, cmd\n\t\t);\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, write_address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, bytes_to_send / 4);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, cmd);\n\n\t\tretval = target_run_algorithm(\n\t\t\ttarget, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,\n\t\t\twrite_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info\n\t\t);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto free_everything;\n\n\t\tint algo_ret = buf_get_u32(reg_params[0].value, 0, 32);\n\t\tif (algo_ret != RSL10_FLASH_ERR_NONE) {\n\t\t\tLOG_ERROR(\"RSL10 WRITE ERROR: '%s' (%d)\", rsl10_error(algo_ret), algo_ret);\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto free_everything;\n\t\t}\n\n\t\tsent_bytes += bytes_to_send;\n\t}\n\nfree_everything:\n\ttarget_free_working_area(target, source);\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nfree_algorithm:\n\ttarget_free_working_area(target, write_algorithm);\n\n\treturn retval;\n}\n\nstatic int rsl10_mass_erase(struct target *target)\n{\n\tstruct working_area *write_algorithm;\n\n\tint retval = target_alloc_working_area(target, sizeof(rsl10_rom_launcher_code), &write_algorithm);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Current working area 0x%x is too small! Increase working area size!\", target->working_area_size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval =\n\t\ttarget_write_buffer(target, write_algorithm->address, sizeof(rsl10_rom_launcher_code), rsl10_rom_launcher_code);\n\tif (retval != ERROR_OK)\n\t\tgoto free_algorithm;\n\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_info;\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode    = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* return value */\n\tinit_reg_param(&reg_params[1], \"r3\", 32, PARAM_OUT);    /* cmd */\n\tinit_reg_param(&reg_params[2], \"sp\", 32, PARAM_OUT);    /* stack pointer */\n\n\tuint32_t cmd;\n\tretval = target_read_u32(target, RSL10_ROM_CMD_ERASE_ALL, &cmd);\n\tif (retval != ERROR_OK)\n\t\tgoto free_reg_params;\n\tbuf_set_u32(reg_params[1].value, 0, 32, cmd);\n\tbuf_set_u32(reg_params[2].value, 0, 32, ALGO_STACK_POINTER_ADDR);\n\n\tretval = target_run_algorithm(\n\t\ttarget, 0, NULL, ARRAY_SIZE(reg_params), reg_params, write_algorithm->address,\n\t\twrite_algorithm->address + sizeof(rsl10_rom_launcher_code) - 2, 1000, &armv7m_info\n\t);\n\tif (retval != ERROR_OK)\n\t\tgoto free_reg_params;\n\n\tint algo_ret = buf_get_u32(reg_params[0].value, 0, 32);\n\tif (algo_ret != RSL10_FLASH_ERR_NONE) {\n\t\tLOG_ERROR(\"RSL10 MASS ERASE ERROR: '%s' (%d)\", rsl10_error(algo_ret), algo_ret);\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\nfree_reg_params:\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nfree_algorithm:\n\ttarget_free_working_area(target, write_algorithm);\n\treturn retval;\n}\n\nstatic int rsl10_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct rsl10_info *chip;\n\n\tint retval = rsl10_get_probed_chip_if_halted(bank, &chip);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn rsl10_ll_flash_write(chip, bank->base + offset, buffer, count);\n}\n\nstatic int rsl10_erase(struct flash_bank *bank, unsigned int first, unsigned int last)\n{\n\tLOG_INFO(\"erase bank: %x, %x\", first, last);\n\tint retval;\n\tstruct rsl10_info *chip;\n\n\tretval = rsl10_get_probed_chip_if_halted(bank, &chip);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = rsl10_ll_flash_erase(chip, bank->base + i * 0x800);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void rsl10_free_driver_priv(struct flash_bank *bank)\n{\n\tstruct rsl10_bank *nbank = bank->driver_priv;\n\tstruct rsl10_info *chip  = nbank->chip;\n\tif (!chip)\n\t\treturn;\n\n\tchip->refcount--;\n\tif (chip->refcount == 0) {\n\t\tfree(chip);\n\t\tbank->driver_priv = NULL;\n\t}\n}\n\nstatic struct rsl10_info *rsl10_get_chip(struct target *target)\n{\n\tstruct flash_bank *bank_iter;\n\n\t/* iterate over rsl10 banks of same target */\n\tfor (bank_iter = flash_bank_list(); bank_iter; bank_iter = bank_iter->next) {\n\t\tif (bank_iter->driver != &rsl10_flash)\n\t\t\tcontinue;\n\n\t\tif (bank_iter->target != target)\n\t\t\tcontinue;\n\n\t\tstruct rsl10_bank *nbank = bank_iter->driver_priv;\n\t\tif (!nbank)\n\t\t\tcontinue;\n\n\t\tif (nbank->chip)\n\t\t\treturn nbank->chip;\n\t}\n\treturn NULL;\n}\n\nFLASH_BANK_COMMAND_HANDLER(rsl10_flash_bank_command)\n{\n\tstruct rsl10_info *chip  = NULL;\n\tstruct rsl10_bank *nbank = NULL;\n\tLOG_INFO(\"Creating flash @ \" TARGET_ADDR_FMT, bank->base);\n\n\tswitch (bank->base) {\n\tcase RSL10_FLASH_ADDRESS_MAIN:\n\tcase RSL10_FLASH_ADDRESS_NVR1:\n\tcase RSL10_FLASH_ADDRESS_NVR2:\n\tcase RSL10_FLASH_ADDRESS_NVR3:\n\tcase RSL10_FLASH_ADDRESS_NVR4:\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Invalid bank address \" TARGET_ADDR_FMT, bank->base);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchip = rsl10_get_chip(bank->target);\n\tif (!chip) {\n\t\tchip = calloc(1, sizeof(*chip));\n\t\tif (!chip)\n\t\t\treturn ERROR_FAIL;\n\n\t\tchip->target = bank->target;\n\t}\n\n\tswitch (bank->base) {\n\tcase RSL10_FLASH_ADDRESS_MAIN:\n\t\tnbank = &chip->bank[0];\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR1:\n\t\tnbank = &chip->bank[1];\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR2:\n\t\tnbank = &chip->bank[2];\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR3:\n\t\tnbank = &chip->bank[3];\n\t\tbreak;\n\tcase RSL10_FLASH_ADDRESS_NVR4:\n\t\tnbank = &chip->bank[4];\n\t\tbreak;\n\t}\n\tassert(nbank);\n\n\tchip->refcount++;\n\tnbank->chip       = chip;\n\tnbank->probed     = false;\n\tbank->driver_priv = nbank;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(rsl10_lock_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"Keys used: %s %s %s %s\", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2], CMD_ARGV[3]);\n\n\tuint32_t user_key[4];\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);\n\n\tuint8_t write_buffer[6 * 4];\n\ttarget_buffer_set_u32(target, write_buffer, RSL10_KEY_DEBUG_LOCK);\n\ttarget_buffer_set_u32_array(target, &write_buffer[4], 4, user_key);\n\t/* pad the end to 64-bit word boundary */\n\tmemset(&write_buffer[5 * 4], bank->default_padded_value, 4);\n\n\tretval = rsl10_erase(bank, 0, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = rsl10_write(bank, write_buffer, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer));\n\tif (retval != ERROR_OK) {\n\t\t/* erase sector, if write fails, otherwise it can lock debug with wrong keys */\n\t\treturn rsl10_erase(bank, 0, 0);\n\t}\n\n\tcommand_print(\n\t\tCMD, \"****** WARNING ******\\n\"\n\t\t\t \"rsl10 device has been successfully prepared to lock.\\n\"\n\t\t\t \"Debug port is locked after restart.\\n\"\n\t\t\t \"Unlock with 'rsl10_unlock key0 key1 key2 key3'\\n\"\n\t\t\t \"****** ....... ******\\n\"\n\t);\n\n\treturn rsl10_protect(bank, true, 0, 0);\n}\n\nCOMMAND_HANDLER(rsl10_unlock_command)\n{\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target            = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\tstruct adiv5_ap *ap   = dap_get_ap(dap, 0);\n\n\tuint32_t user_key[4];\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], user_key[0]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], user_key[1]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], user_key[2]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], user_key[3]);\n\n\tuint8_t write_buffer1[4 * 4];\n\ttarget_buffer_set_u32_array(target, write_buffer1, 4, user_key);\n\tint retval = mem_ap_write_buf(ap, write_buffer1, 4, 4, RSL10_FLASH_REG_DEBUG_UNLOCK_KEY1);\n\tif (retval != ERROR_OK) {\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tdap_put_ap(ap);\n\n\tuint32_t key;\n\tretval = mem_ap_read_atomic_u32(ap, RSL10_FLASH_ADDRESS_LOCK_INFO_SETTING, &key);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_INFO(\"mem read: 0x%08\" PRIx32, key);\n\n\tif (key == RSL10_KEY_DEBUG_LOCK) {\n\t\tretval = command_run_line(CMD_CTX, \"reset init\");\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tstruct flash_bank *bank;\n\t\tretval = get_flash_bank_by_addr(target, RSL10_FLASH_ADDRESS_NVR3, true, &bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = rsl10_protect(bank, false, 0, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tuint8_t write_buffer2[4 * 2];\n\t\ttarget_buffer_set_u32(target, write_buffer2, 0x1);\n\t\t/* pad the end to 64-bit word boundary */\n\t\tmemset(&write_buffer2[4], bank->default_padded_value, 4);\n\n\t\t/* let it fail, because sector is not erased, maybe just erase all? */\n\t\t(void)rsl10_write(bank, write_buffer2, RSL10_NVR3_USER_KEY_OFFSET, sizeof(write_buffer2));\n\t\tcommand_print(CMD, \"Debug port is unlocked!\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(rsl10_mass_erase_command)\n{\n\tif (CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tint retval = rsl10_mass_erase(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"Mass erase was succesfull!\");\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration rsl10_exec_command_handlers[] = {\n\t{\n\t\t.name    = \"lock\",\n\t\t.handler = rsl10_lock_command,\n\t\t.mode    = COMMAND_EXEC,\n\t\t.help    = \"Lock rsl10 debug, with passed keys\",\n\t\t.usage   = \"key1 key2 key3 key4\",\n\t},\n\t{\n\t\t.name    = \"unlock\",\n\t\t.handler = rsl10_unlock_command,\n\t\t.mode    = COMMAND_EXEC,\n\t\t.help    = \"Unlock rsl10 debug, with passed keys\",\n\t\t.usage   = \"key1 key2 key3 key4\",\n\t},\n\t{\n\t\t.name    = \"mass_erase\",\n\t\t.handler = rsl10_mass_erase_command,\n\t\t.mode    = COMMAND_EXEC,\n\t\t.help    = \"Mass erase all unprotected flash areas\",\n\t\t.usage   = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE};\n\nstatic const struct command_registration rsl10_command_handlers[] = {\n\t{\n\t\t.name  = \"rsl10\",\n\t\t.mode  = COMMAND_ANY,\n\t\t.help  = \"rsl10 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = rsl10_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE};\n\nconst struct flash_driver rsl10_flash = {\n\t.name               = \"rsl10\",\n\t.commands           = rsl10_command_handlers,\n\t.flash_bank_command = rsl10_flash_bank_command,\n\t.erase              = rsl10_erase,\n\t.protect            = rsl10_protect,\n\t.write              = rsl10_write,\n\t.read               = default_flash_read,\n\t.probe              = rsl10_probe,\n\t.auto_probe         = rsl10_auto_probe,\n\t.erase_check        = default_flash_blank_check,\n\t.protect_check      = rsl10_protect_check,\n\t.free_driver_priv   = rsl10_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/sfdp.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de\t   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include \"sfdp.h\"\n\n#define SFDP_MAGIC\t\t\t0x50444653\n#define SFDP_ACCESS_PROT\t0xFF\n#define SFDP_BASIC_FLASH\t0xFF00\n#define SFDP_4BYTE_ADDR\t\t0xFF84\n\nstatic const char *sfdp_name = \"sfdp\";\n\nstruct sfdp_hdr {\n\tuint32_t\t\t\tsignature;\n\tuint32_t\t\t\trevision;\n};\n\nstruct sfdp_phdr {\n\tuint32_t\t\t\trevision;\n\tuint32_t\t\t\tptr;\n};\n\nstruct sfdp_basic_flash_param {\n\tuint32_t\t\t\tfast_addr;\t\t/* 01: fast read and 3/4 address bytes */\n\tuint32_t\t\t\tdensity;\t\t/* 02: memory density */\n\tuint32_t\t\t\tfast_1x4;\t\t/* 03: 1-1-4 and 1-4-4 fast read */\n\tuint32_t\t\t\tfast_1x2;\t\t/* 04: 1-2-2 and 1-1-2 fast read */\n\tuint32_t\t\t\tfast_444;\t\t/* 05: 4-4-4 and 2-2-2 fast read */\n\tuint32_t\t\t\tread_222;\t\t/* 06: 2-2-2 fast read instr and dummy */\n\tuint32_t\t\t\tread_444;\t\t/* 07: 4-4-4 fast read instr and dummy */\n\tuint32_t\t\t\terase_t12;\t\t/* 08: erase types 1, 2 */\n\tuint32_t\t\t\terase_t34;\t\t/* 09: erase types 3, 4 */\n\tuint32_t\t\t\terase_time;\t\t/* 10: erase times for types 1 - 4 */\n\tuint32_t\t\t\tchip_byte;\t\t/* 11: chip erase time, byte prog time, page prog */\n\tuint32_t\t\t\tsusp_time;\t\t/* 12: suspend and resume times */\n\tuint32_t\t\t\tsusp_instr;\t\t/* 13: suspend and resume instr */\n\tuint32_t\t\t\tpwrd_instr;\t\t/* 14: powerdown instr */\n\tuint32_t\t\t\tquad_req;\t\t/* 15: quad enable requirements */\n\tuint32_t\t\t\taddr_reset;\t\t/* 16: 3-/4-byte addressing and reset */\n\tuint32_t\t\t\tread_1x8;\t\t/* 17: 1-1-8 and 1-8-8 fast read instr and dummy */\n\tuint32_t\t\t\tdtr_drive;\t\t/* 18: dtr modes and drive strength */\n\tuint32_t\t\t\toctal_req;\t\t/* 19: octal enable requirements */\n\tuint32_t\t\t\tspeed_888;\t\t/* 20: speed in 8-8-8 modes */\n};\n\nstruct sfdp_4byte_addr_param {\n\tuint32_t\t\t\tflags;\t\t\t/* 01: various flags */\n\tuint32_t\t\t\terase_t1234;\t/* 02: erase commands */\n};\n\n/* Try to get parameters from flash via SFDP */\nint spi_sfdp(struct flash_bank *bank, struct flash_device *dev,\n\tread_sfdp_block_t read_sfdp_block)\n{\n\tstruct sfdp_hdr header;\n\tstruct sfdp_phdr *pheaders = NULL;\n\tuint32_t *ptable = NULL;\n\tunsigned int j, k, nph;\n\tint retval, erase_type = 0;\n\n\tmemset(dev, 0, sizeof(struct flash_device));\n\n\t/* retrieve SFDP header */\n\tmemset(&header, 0, sizeof(header));\n\tretval = read_sfdp_block(bank, 0x0, sizeof(header) >> 2, (uint32_t *)&header);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"header 0x%08\" PRIx32 \" 0x%08\" PRIx32, header.signature, header.revision);\n\tif (header.signature != SFDP_MAGIC) {\n\t\tLOG_INFO(\"no SDFP found\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\tif (((header.revision >> 24) & 0xFF) != SFDP_ACCESS_PROT) {\n\t\tLOG_ERROR(\"access protocol 0x%02x not implemented\",\n\t\t\t(header.revision >> 24) & 0xFFU);\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* retrieve table of parameter headers */\n\tnph = ((header.revision >> 16) & 0xFF) + 1;\n\tLOG_DEBUG(\"parameter headers: %d\", nph);\n\tpheaders = malloc(sizeof(struct sfdp_phdr) * nph);\n\tif (!pheaders) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tmemset(pheaders, 0, sizeof(struct sfdp_phdr) * nph);\n\tretval = read_sfdp_block(bank, sizeof(header),\n\t\t(sizeof(struct sfdp_phdr) >> 2) * nph, (uint32_t *)pheaders);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tfor (k = 0; k < nph; k++) {\n\t\tuint8_t words = (pheaders[k].revision >> 24) & 0xFF;\n\t\tuint16_t id = (((pheaders[k].ptr) >> 16) & 0xFF00) | (pheaders[k].revision & 0xFF);\n\t\tuint32_t ptr = pheaders[k].ptr & 0xFFFFFF;\n\n\t\tLOG_DEBUG(\"pheader %d len=0x%02\" PRIx8 \" id=0x%04\" PRIx16\n\t\t\t\" ptr=0x%06\" PRIx32, k, words, id, ptr);\n\n\t\t/* retrieve parameter table */\n\t\tptable = malloc(words << 2);\n\t\tif (!ptable) {\n\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto err;\n\t\t}\n\t\tretval = read_sfdp_block(bank, ptr, words, ptable);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tfor (j = 0; j < words; j++)\n\t\t\tLOG_DEBUG(\"word %02d 0x%08X\", j + 1, ptable[j]);\n\n\t\tif (id == SFDP_BASIC_FLASH) {\n\t\t\tstruct sfdp_basic_flash_param *table = (struct sfdp_basic_flash_param *)ptable;\n\t\t\tuint16_t erase;\n\n\t\t\tif (words < 9) {\n\t\t\t\tLOG_ERROR(\"id=0x%04\" PRIx16 \" invalid length %d\", id, words);\n\t\t\t\tretval = ERROR_FLASH_BANK_NOT_PROBED;\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"basic flash parameter table\");\n\t\t\t/* dummy device name */\n\t\t\tdev->name = sfdp_name;\n\n\t\t\t/* default instructions */\n\t\t\tdev->read_cmd = SPIFLASH_READ;\n\t\t\tdev->pprog_cmd = SPIFLASH_PAGE_PROGRAM;\n\t\t\tdev->chip_erase_cmd = SPIFLASH_MASS_ERASE;\n\n\t\t\t/* get device size */\n\t\t\tif (table->density & (1UL << 31))\n\t\t\t\tdev->size_in_bytes = 1UL << ((table->density & ~(1UL << 31)) - 3);\n\t\t\telse\n\t\t\t\tdev->size_in_bytes = (table->density + 1) >> 3;\n\n\t\t\t/* 2-2-2 read instruction, not used */\n\t\t\tif (table->fast_444 & (1UL << 0))\n\t\t\t\tdev->qread_cmd = (table->read_222 >> 24) & 0xFF;\n\n\t\t\t/* 4-4-4 read instruction */\n\t\t\tif (table->fast_444 & (1UL << 4))\n\t\t\t\tdev->qread_cmd = (table->read_444 >> 24) & 0xFF;\n\n\t\t\t/* find the largest erase block size and instruction */\n\t\t\terase = (table->erase_t12 >> 0) & 0xFFFF;\n\t\t\terase_type = 1;\n\t\t\tif (((table->erase_t12 >> 16) & 0xFF) > (erase & 0xFF)) {\n\t\t\t\terase = (table->erase_t12 >> 16) & 0xFFFF;\n\t\t\t\terase_type = 2;\n\t\t\t}\n\t\t\tif (((table->erase_t34 >> 0) & 0xFF) > (erase & 0xFF)) {\n\t\t\t\terase = (table->erase_t34 >> 0) & 0xFFFF;\n\t\t\t\terase_type = 3;\n\t\t\t}\n\t\t\tif (((table->erase_t34 >> 16) & 0xFF) > (erase & 0xFF)) {\n\t\t\t\terase = (table->erase_t34 >> 16) & 0xFFFF;\n\t\t\t\terase_type = 4;\n\t\t\t}\n\t\t\tdev->erase_cmd = (erase >> 8) & 0xFF;\n\t\t\tdev->sectorsize = 1UL << (erase & 0xFF);\n\n\t\t\tif ((offsetof(struct sfdp_basic_flash_param, chip_byte) >> 2) < words) {\n\t\t\t\t/* get Program Page Size, if chip_byte present, that's optional */\n\t\t\t\tdev->pagesize = 1UL << ((table->chip_byte >> 4) & 0x0F);\n\t\t\t} else {\n\t\t\t\t/* no explicit page size specified ... */\n\t\t\t\tif (table->fast_addr & (1UL << 2)) {\n\t\t\t\t\t/* Write Granularity = 1, use 64 bytes */\n\t\t\t\t\tdev->pagesize = 1UL << 6;\n\t\t\t\t} else {\n\t\t\t\t\t/* Write Granularity = 0, use 16 bytes */\n\t\t\t\t\tdev->pagesize = 1UL << 4;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (dev->size_in_bytes > (1UL << 24)) {\n\t\t\t\tif (((table->fast_addr >> 17) & 0x3) == 0x0)\n\t\t\t\t\tLOG_ERROR(\"device needs paging - not implemented\");\n\n\t\t\t\t/* 4-byte addresses needed if more than 16 MBytes */\n\t\t\t\tif (((offsetof(struct sfdp_basic_flash_param, addr_reset) >> 2) < words) &&\n\t\t\t\t\t(table->addr_reset & (1UL << 29))) {\n\t\t\t\t\t/* dedicated 4-byte-address instructions, hopefully these ...\n\t\t\t\t\t * this entry is unfortunately optional as well\n\t\t\t\t\t * a subsequent 4-byte address table may overwrite this */\n\t\t\t\t\tdev->read_cmd = 0x13;\n\t\t\t\t\tdev->pprog_cmd = 0x12;\n\t\t\t\t\tdev->erase_cmd = 0xDC;\n\t\t\t\t\tif (dev->qread_cmd != 0)\n\t\t\t\t\t\tdev->qread_cmd = 0xEC;\n\t\t\t\t} else if (((table->fast_addr >> 17) & 0x3) == 0x1)\n\t\t\t\t\tLOG_INFO(\"device has to be switched to 4-byte addresses\");\n\t\t\t}\n\t\t} else if (id == SFDP_4BYTE_ADDR) {\n\t\t\tstruct sfdp_4byte_addr_param *table = (struct sfdp_4byte_addr_param *)ptable;\n\n\t\t\tif (words >= (offsetof(struct sfdp_4byte_addr_param, erase_t1234)\n\t\t\t\t+ sizeof(table->erase_t1234)) >> 2) {\n\t\t\t\tLOG_INFO(\"4-byte address parameter table\");\n\n\t\t\t\t/* read and page program instructions */\n\t\t\t\tif (table->flags & (1UL << 0))\n\t\t\t\t\tdev->read_cmd = 0x13;\n\t\t\t\tif (table->flags & (1UL << 5))\n\t\t\t\t\tdev->qread_cmd = 0xEC;\n\t\t\t\tif (table->flags & (1UL << 6))\n\t\t\t\t\tdev->pprog_cmd = 0x12;\n\n\t\t\t\t/* erase instructions */\n\t\t\t\tif ((erase_type == 1) && (table->flags & (1UL << 9)))\n\t\t\t\t\tdev->erase_cmd = (table->erase_t1234 >> 0) & 0xFF;\n\t\t\t\telse if ((erase_type == 2) && (table->flags & (1UL << 10)))\n\t\t\t\t\tdev->erase_cmd = (table->erase_t1234 >> 8) & 0xFF;\n\t\t\t\telse if ((erase_type == 3) && (table->flags & (1UL << 11)))\n\t\t\t\t\tdev->erase_cmd = (table->erase_t1234 >> 16) & 0xFF;\n\t\t\t\telse if ((erase_type == 4) && (table->flags & (1UL << 12)))\n\t\t\t\t\tdev->erase_cmd = (table->erase_t1234 >> 24) & 0xFF;\n\t\t\t} else\n\t\t\t\tLOG_ERROR(\"parameter table id=0x%04\" PRIx16 \" invalid length %d\", id, words);\n\t\t} else\n\t\t\tLOG_DEBUG(\"unimplemented parameter table id=0x%04\" PRIx16, id);\n\n\t\tfree(ptable);\n\t\tptable = NULL;\n\t}\n\n\tif (erase_type != 0) {\n\t\tLOG_INFO(\"valid SFDP detected\");\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"incomplete/invalid SFDP\");\n\t\tretval = ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\nerr:\n\tfree(pheaders);\n\tfree(ptable);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/sfdp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Andreas Bolsch <andreas.bolsch@mni.thm.de\t   *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_SFDP_H\n#define OPENOCD_FLASH_NOR_SFDP_H\n\n/* per JESD216D 'addr' is *byte* based but must be word aligned,\n * 'buffer' is word based, word aligned and always little-endian encoded,\n * in the flash, 'addr_len' is 3 or 4, 'dummy' ***usually*** 8\n *\n * the actual number of dummy clocks should be worked out by this function\n * dynamically, i.e. by scanning the first few bytes for the SFDP signature\n *\n * buffer contents is supposed to be returned in ***host*** endianness */\ntypedef int (*read_sfdp_block_t)(struct flash_bank *bank, uint32_t addr,\n\tuint32_t words, uint32_t *buffer);\n\nextern int spi_sfdp(struct flash_bank *bank, struct flash_device *dev,\n\tread_sfdp_block_t read_sfdp_block);\n\n#endif /* OPENOCD_FLASH_NOR_SFDP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/sh_qspi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-only\n\n/*\n * SH QSPI (Quad SPI) driver\n * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com>\n *\n * Based on U-Boot SH QSPI driver\n * Copyright (C) 2013 Renesas Electronics Corporation\n * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n#include <jtag/jtag.h>\n#include <target/algorithm.h>\n#include <target/arm.h>\n#include <target/arm_opcodes.h>\n#include <target/target.h>\n\n/* SH QSPI register bit masks <REG>_<BIT> */\n#define SPCR_MSTR\t0x08\n#define SPCR_SPE\t0x40\n#define SPSR_SPRFF\t0x80\n#define SPSR_SPTEF\t0x20\n#define SPPCR_IO3FV\t0x04\n#define SPPCR_IO2FV\t0x02\n#define SPPCR_IO1FV\t0x01\n#define SPBDCR_RXBC0\tBIT(0)\n#define SPCMD_SCKDEN\tBIT(15)\n#define SPCMD_SLNDEN\tBIT(14)\n#define SPCMD_SPNDEN\tBIT(13)\n#define SPCMD_SSLKP\tBIT(7)\n#define SPCMD_BRDV0\tBIT(2)\n#define SPCMD_INIT1\t(SPCMD_SCKDEN | SPCMD_SLNDEN | \\\n\t\t\tSPCMD_SPNDEN | SPCMD_SSLKP | \\\n\t\t\tSPCMD_BRDV0)\n#define SPCMD_INIT2\t(SPCMD_SPNDEN | SPCMD_SSLKP | \\\n\t\t\tSPCMD_BRDV0)\n#define SPBFCR_TXRST\tBIT(7)\n#define SPBFCR_RXRST\tBIT(6)\n#define SPBFCR_TXTRG\t0x30\n#define SPBFCR_RXTRG\t0x07\n\n/* SH QSPI register set */\n#define SH_QSPI_SPCR\t\t0x00\n#define SH_QSPI_SSLP\t\t0x01\n#define SH_QSPI_SPPCR\t\t0x02\n#define SH_QSPI_SPSR\t\t0x03\n#define SH_QSPI_SPDR\t\t0x04\n#define SH_QSPI_SPSCR\t\t0x08\n#define SH_QSPI_SPSSR\t\t0x09\n#define SH_QSPI_SPBR\t\t0x0a\n#define SH_QSPI_SPDCR\t\t0x0b\n#define SH_QSPI_SPCKD\t\t0x0c\n#define SH_QSPI_SSLND\t\t0x0d\n#define SH_QSPI_SPND\t\t0x0e\n#define SH_QSPI_DUMMY0\t\t0x0f\n#define SH_QSPI_SPCMD0\t\t0x10\n#define SH_QSPI_SPCMD1\t\t0x12\n#define SH_QSPI_SPCMD2\t\t0x14\n#define SH_QSPI_SPCMD3\t\t0x16\n#define SH_QSPI_SPBFCR\t\t0x18\n#define SH_QSPI_DUMMY1\t\t0x19\n#define SH_QSPI_SPBDCR\t\t0x1a\n#define SH_QSPI_SPBMUL0\t\t0x1c\n#define SH_QSPI_SPBMUL1\t\t0x20\n#define SH_QSPI_SPBMUL2\t\t0x24\n#define SH_QSPI_SPBMUL3\t\t0x28\n\nstruct sh_qspi_flash_bank {\n\tconst struct flash_device *dev;\n\tuint32_t\t\tio_base;\n\tbool\t\t\tprobed;\n\tstruct working_area\t*io_algorithm;\n\tstruct working_area\t*source;\n\tunsigned int\t\tbuffer_size;\n};\n\nstruct sh_qspi_target {\n\tchar\t\t*name;\n\tuint32_t\ttap_idcode;\n\tuint32_t\tio_base;\n};\n\nstatic const struct sh_qspi_target target_devices[] = {\n\t/* name,\ttap_idcode,\tio_base */\n\t{ \"SH QSPI\",\t0x4ba00477,\t0xe6b10000 },\n\t{ NULL,\t\t0,\t\t0 }\n};\n\nstatic int sh_qspi_init(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tuint8_t val;\n\tint ret;\n\n\t/* QSPI initialize */\n\t/* Set master mode only */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPCR, SPCR_MSTR);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set SSL signal level */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SSLP, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set MOSI signal value when transfer is in idle state */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPPCR,\n\t\t\t      SPPCR_IO3FV | SPPCR_IO2FV);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set bit rate. See 58.3.8 Quad Serial Peripheral Interface */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBR, 0x01);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Disable Dummy Data Transmission */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPDCR, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set clock delay value */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPCKD, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set SSL negation delay value */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SSLND, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set next-access delay value */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPND, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set equence command */\n\tret = target_write_u16(target, info->io_base + SH_QSPI_SPCMD0,\n\t\t\t       SPCMD_INIT2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Reset transfer and receive Buffer */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval |= SPBFCR_TXRST | SPBFCR_RXRST;\n\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Clear transfer and receive Buffer control bit */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval &= ~(SPBFCR_TXRST | SPBFCR_RXRST);\n\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set equence control method. Use equence0 only */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPSCR, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Enable SPI function */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval |= SPCR_SPE;\n\n\treturn target_write_u8(target, info->io_base + SH_QSPI_SPCR, val);\n}\n\nstatic int sh_qspi_cs_activate(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tuint8_t val;\n\tint ret;\n\n\t/* Set master mode only */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPCR, SPCR_MSTR);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set command */\n\tret = target_write_u16(target, info->io_base + SH_QSPI_SPCMD0,\n\t\t\t       SPCMD_INIT1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Reset transfer and receive Buffer */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval |= SPBFCR_TXRST | SPBFCR_RXRST;\n\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Clear transfer and receive Buffer control bit */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval &= ~(SPBFCR_TXRST | SPBFCR_RXRST);\n\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR, val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set equence control method. Use equence0 only */\n\tret = target_write_u8(target, info->io_base + SH_QSPI_SPSCR, 0x00);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Enable SPI function */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval |= SPCR_SPE;\n\n\treturn target_write_u8(target, info->io_base + SH_QSPI_SPCR, val);\n}\n\nstatic int sh_qspi_cs_deactivate(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tuint8_t val;\n\tint ret;\n\n\t/* Disable SPI Function */\n\tret = target_read_u8(target, info->io_base + SH_QSPI_SPCR, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tval &= ~SPCR_SPE;\n\n\treturn target_write_u8(target, info->io_base + SH_QSPI_SPCR, val);\n}\n\nstatic int sh_qspi_wait_for_bit(struct flash_bank *bank, uint8_t reg,\n\t\t\t\tuint32_t mask, bool set,\n\t\t\t\tunsigned long timeout)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tlong long endtime;\n\tuint8_t val;\n\tint ret;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\tret = target_read_u8(target, info->io_base + reg, &val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (!set)\n\t\t\tval = ~val;\n\n\t\tif ((val & mask) == mask)\n\t\t\treturn ERROR_OK;\n\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_TIMEOUT_REACHED;\n}\n\nstatic int sh_qspi_xfer_common(struct flash_bank *bank,\n\t\t\t       const uint8_t *dout, unsigned int outlen,\n\t\t\t       uint8_t *din, unsigned int inlen,\n\t\t\t       bool xfer_start, bool xfer_end)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tuint8_t tdata, rdata;\n\tuint8_t val;\n\tunsigned int nbyte = outlen + inlen;\n\tint ret = 0;\n\n\tif (xfer_start) {\n\t\tret = sh_qspi_cs_activate(bank);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_u32(target, info->io_base + SH_QSPI_SPBMUL0,\n\t\t\t\t       nbyte);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_read_u8(target, info->io_base + SH_QSPI_SPBFCR,\n\t\t\t\t     &val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tval &= ~(SPBFCR_TXTRG | SPBFCR_RXTRG);\n\n\t\tret = target_write_u8(target, info->io_base + SH_QSPI_SPBFCR,\n\t\t\t\t      val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\twhile (nbyte > 0) {\n\t\tret = sh_qspi_wait_for_bit(bank, SH_QSPI_SPSR, SPSR_SPTEF,\n\t\t\t\t\t\ttrue, 1000);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\ttdata = outlen ? *dout++ : 0;\n\t\tret = target_write_u8(target, info->io_base + SH_QSPI_SPDR,\n\t\t\t\t      tdata);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = sh_qspi_wait_for_bit(bank, SH_QSPI_SPSR, SPSR_SPRFF,\n\t\t\t\t\t\ttrue, 1000);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_read_u8(target, info->io_base + SH_QSPI_SPDR,\n\t\t\t\t     &rdata);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\tif (!outlen && inlen) {\n\t\t\t*din++ = rdata;\n\t\t\tinlen--;\n\t\t}\n\n\t\tif (outlen)\n\t\t\toutlen--;\n\n\t\tnbyte--;\n\t}\n\n\tif (xfer_end)\n\t\treturn sh_qspi_cs_deactivate(bank);\n\telse\n\t\treturn ERROR_OK;\n}\n\n/* Send \"write enable\" command to SPI flash chip. */\nstatic int sh_qspi_write_enable(struct flash_bank *bank)\n{\n\tuint8_t dout = SPIFLASH_WRITE_ENABLE;\n\n\treturn sh_qspi_xfer_common(bank, &dout, 1, NULL, 0, 1, 1);\n}\n\n/* Read the status register of the external SPI flash chip. */\nstatic int read_status_reg(struct flash_bank *bank, uint32_t *status)\n{\n\tuint8_t dout = SPIFLASH_READ_STATUS;\n\tuint8_t din;\n\tint ret;\n\n\tret = sh_qspi_xfer_common(bank, &dout, 1, &din, 1, 1, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t*status = din & 0xff;\n\n\treturn ERROR_OK;\n}\n\n/* check for WIP (write in progress) bit in status register */\n/* timeout in ms */\nstatic int wait_till_ready(struct flash_bank *bank, int timeout)\n{\n\tlong long endtime;\n\tuint32_t status;\n\tint ret;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\t/* read flash status register */\n\t\tret = read_status_reg(bank, &status);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif ((status & SPIFLASH_BSY_BIT) == 0)\n\t\t\treturn ERROR_OK;\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_TIMEOUT_REACHED;\n}\n\nstatic int sh_qspi_erase_sector(struct flash_bank *bank, int sector)\n{\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tbool addr4b = info->dev->size_in_bytes > (1UL << 24);\n\tuint32_t address = (sector * info->dev->sectorsize) <<\n\t\t\t   (addr4b ? 0 : 8);\n\tuint8_t dout[5] = {\n\t\tinfo->dev->erase_cmd,\n\t\t(address >> 24) & 0xff, (address >> 16) & 0xff,\n\t\t(address >> 8) & 0xff, (address >> 0) & 0xff\n\t};\n\tunsigned int doutlen = addr4b ? 5 : 4;\n\tint ret;\n\n\t/* Write Enable */\n\tret = sh_qspi_write_enable(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Erase */\n\tret = sh_qspi_xfer_common(bank, dout, doutlen, NULL, 0, 1, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Poll status register */\n\treturn wait_till_ready(bank, 3000);\n}\n\nstatic int sh_qspi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: from sector %u to sector %u\", __func__, first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!info->probed) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = sh_qspi_erase_sector(bank, sector);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\tkeep_alive();\n\t}\n\n\treturn retval;\n}\n\nstatic int sh_qspi_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t       uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tstruct reg_param reg_params[4];\n\tstruct arm_algorithm arm_algo;\n\tuint32_t io_base = (uint32_t)(info->io_base);\n\tuint32_t src_base = (uint32_t)(info->source->address);\n\tuint32_t chunk;\n\tbool addr4b = !!(info->dev->size_in_bytes > (1UL << 24));\n\tint ret = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t  __func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Write pasts end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\tif (offset & 0xff) {\n\t\tLOG_ERROR(\"sh_qspi_write_page: unaligned write address: %08\" PRIx32,\n\t\t\t  offset);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tstruct flash_sector *bs = &bank->sectors[sector];\n\n\t\tif ((offset < (bs->offset + bs->size)) &&\n\t\t    ((offset + count - 1) >= bs->offset) &&\n\t\t    bs->is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t  __func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Reads past end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tchunk = (count > info->buffer_size) ?\n\t\t\tinfo->buffer_size : count;\n\n\t\ttarget_write_buffer(target, info->source->address,\n\t\t\t\t    chunk, buffer);\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, io_base);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, src_base);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32,\n\t\t\t\t(1 << 31) | (addr4b << 30) |\n\t\t\t\t(info->dev->pprog_cmd << 20) | chunk);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, offset);\n\n\t\tret = target_run_algorithm(target, 0, NULL, 4, reg_params,\n\t\t\t\tinfo->io_algorithm->address,\n\t\t\t\t0, 10000, &arm_algo);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing SH QSPI flash IO algorithm\");\n\t\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += chunk;\n\t\toffset += chunk;\n\t\tcount -= chunk;\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn ret;\n}\n\nstatic int sh_qspi_read(struct flash_bank *bank, uint8_t *buffer,\n\t\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tstruct reg_param reg_params[4];\n\tstruct arm_algorithm arm_algo;\n\tuint32_t io_base = (uint32_t)(info->io_base);\n\tuint32_t src_base = (uint32_t)(info->source->address);\n\tuint32_t chunk;\n\tbool addr4b = !!(info->dev->size_in_bytes > (1UL << 24));\n\tint ret = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t  __func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Reads past end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tchunk = (count > info->buffer_size) ?\n\t\t\tinfo->buffer_size : count;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, io_base);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, src_base);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32,\n\t\t\t\t(addr4b << 30) | (info->dev->read_cmd << 20) |\n\t\t\t\tchunk);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, offset);\n\n\t\tret = target_run_algorithm(target, 0, NULL, 4, reg_params,\n\t\t\t\tinfo->io_algorithm->address,\n\t\t\t\t0, 10000, &arm_algo);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing SH QSPI flash IO algorithm\");\n\t\t\tret = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\ttarget_read_buffer(target, info->source->address,\n\t\t\t\t   chunk, buffer);\n\n\t\tbuffer += chunk;\n\t\toffset += chunk;\n\t\tcount -= chunk;\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn ret;\n}\n\n/* Return ID of flash device */\nstatic int read_flash_id(struct flash_bank *bank, uint32_t *id)\n{\n\tstruct target *target = bank->target;\n\tuint8_t dout = SPIFLASH_READ_ID;\n\tuint8_t din[3] = { 0, 0, 0 };\n\tint ret;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tret = sh_qspi_xfer_common(bank, &dout, 1, din, 3, 1, 1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t*id = (din[0] << 0) | (din[1] << 8) | (din[2] << 16);\n\n\tif (*id == 0xffffff) {\n\t\tLOG_ERROR(\"No SPI flash found\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_protect(struct flash_bank *bank, int set,\n\t\t\t unsigned int first, unsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_upload_helper(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\n\t/* see contrib/loaders/flash/sh_qspi.s for src */\n\tstatic const uint8_t sh_qspi_io_code[] = {\n#include \"../../../contrib/loaders/flash/sh_qspi/sh_qspi.inc\"\n\t};\n\tint ret;\n\n\ttarget_free_working_area(target, info->source);\n\ttarget_free_working_area(target, info->io_algorithm);\n\n\t/* FIXME: Working areas are allocated during flash probe\n\t * and eventual target_free_all_working_areas() called in case\n\t * of target reset or run is not handled at all.\n\t * Not a big problem if area backp is off.\n\t */\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(sh_qspi_io_code),\n\t\t\t&info->io_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\ttarget_write_buffer(target, info->io_algorithm->address,\n\t\t\t    sizeof(sh_qspi_io_code), sh_qspi_io_code);\n\n\t/*\n\t * Try to allocate as big work area buffer as possible, start\n\t * with 32 kiB and count down. If there is less than 256 Bytes\n\t * of work area available, abort.\n\t */\n\tinfo->buffer_size = 32768;\n\twhile (true) {\n\t\tret = target_alloc_working_area_try(target, info->buffer_size,\n\t\t\t\t\t\t    &info->source);\n\t\tif (ret == ERROR_OK)\n\t\t\treturn ret;\n\n\t\tinfo->buffer_size /= 2;\n\t\tif (info->buffer_size <= 256) {\n\t\t\ttarget_free_working_area(target, info->io_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\tstruct flash_sector *sectors;\n\tuint32_t id = 0; /* silence uninitialized warning */\n\tuint32_t sectorsize;\n\tconst struct sh_qspi_target *target_device;\n\tint ret;\n\n\tif (info->probed)\n\t\tfree(bank->sectors);\n\n\tinfo->probed = false;\n\n\tfor (target_device = target_devices; target_device->name;\n\t\t++target_device)\n\t\tif (target_device->tap_idcode == target->tap->idcode)\n\t\t\tbreak;\n\tif (!target_device->name) {\n\t\tLOG_ERROR(\"Device ID 0x%\" PRIx32 \" is not known\",\n\t\t\t  target->tap->idcode);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tinfo->io_base = target_device->io_base;\n\n\tLOG_DEBUG(\"Found device %s at address \" TARGET_ADDR_FMT,\n\t\t  target_device->name, bank->base);\n\n\tret = sh_qspi_upload_helper(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = sh_qspi_init(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = read_flash_id(bank, &id);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tinfo->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name; p++)\n\t\tif (p->device_id == id) {\n\t\t\tinfo->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%08\" PRIx32 \")\",\n\t\t info->dev->name, info->dev->device_id);\n\n\t/* Set correct size value */\n\tbank->size = info->dev->size_in_bytes;\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = info->dev->sectorsize ?\n\t\t     info->dev->sectorsize :\n\t\t     info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = info->dev->size_in_bytes / sectorsize;\n\tsectors = calloc(1, sizeof(*sectors) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = 0;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tinfo->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_auto_probe(struct flash_bank *bank)\n{\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\n\tif (info->probed)\n\t\treturn ERROR_OK;\n\n\treturn sh_qspi_probe(bank);\n}\n\nstatic int sh_qspi_flash_blank_check(struct flash_bank *bank)\n{\n\t/* Not implemented */\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_protect_check(struct flash_bank *bank)\n{\n\t/* Not implemented */\n\treturn ERROR_OK;\n}\n\nstatic int sh_qspi_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct sh_qspi_flash_bank *info = bank->driver_priv;\n\n\tif (!info->probed) {\n\t\tcommand_print_sameline(cmd, \"\\nSH QSPI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nSH QSPI flash information:\\n\"\n\t\t\"  Device \\'%s\\' (ID 0x%08\" PRIx32 \")\\n\",\n\t\tinfo->dev->name, info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(sh_qspi_flash_bank_command)\n{\n\tstruct sh_qspi_flash_bank *info;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 6 || CMD_ARGC > 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif ((CMD_ARGC == 7) && strcmp(CMD_ARGV[6], \"cs0\")) {\n\t\tLOG_ERROR(\"Unknown arg: %s\", CMD_ARGV[6]);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tinfo = calloc(1, sizeof(struct sh_qspi_flash_bank));\n\tif (!info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = info;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver sh_qspi_flash = {\n\t.name\t\t\t= \"sh_qspi\",\n\t.flash_bank_command\t= sh_qspi_flash_bank_command,\n\t.erase\t\t\t= sh_qspi_erase,\n\t.protect\t\t= sh_qspi_protect,\n\t.write\t\t\t= sh_qspi_write,\n\t.read\t\t\t= sh_qspi_read,\n\t.probe\t\t\t= sh_qspi_probe,\n\t.auto_probe\t\t= sh_qspi_auto_probe,\n\t.erase_check\t\t= sh_qspi_flash_blank_check,\n\t.protect_check\t\t= sh_qspi_protect_check,\n\t.info\t\t\t= sh_qspi_get_info,\n\t.free_driver_priv\t= default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/sim3x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2014 by Ladislav Bábel                                  *\n *   ladababel@seznam.cz                                                   *\n *                                                                         *\n *   Copyright (C) 2015 by Andreas Bomholtz                                *\n *   andreas@seluxit.com                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/cortex_m.h>\n\n/* SI32_DEVICEID0 */\n#define DEVICEID0_DEVICEID0              (0x400490C0)\n#define DEVICEID0_DEVICEID1              (0x400490D0)\n#define DEVICEID0_DEVICEID2              (0x400490E0)\n#define DEVICEID0_DEVICEID3              (0x400490F0)\n\n/* cortex_m CPUID */\n#define CPUID_CHECK_VALUE                (0x410FC230)\n#define CPUID_CHECK_VALUE_MASK           (0xFF0FFFF0)\n\n/* Flash */\n#define FLASH_BASE_ADDRESS               (0x00000000)\n#define LOCK_WORD_ADDRESS                (0x0003FFFC)\n\n#define LOCK_WORD_MCU_UNLOCKED           (0xFFFFFFFF)\n/* Can't by locked again without erase, because LOCK_WORD is in FLASH */\n#define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE (0x00000000)\n\n/* SI32_FLASHCTRL_0 */\n#define FLASHCTRL0_CONFIG_ALL            (0x4002E000)\n#define FLASHCTRL0_CONFIG_SET            (0x4002E004)\n#define FLASHCTRL0_CONFIG_CLR            (0x4002E008)\n#define FLASHCTRL0_CONFIG_ERASEEN_MASK   (0x00040000)\n#define FLASHCTRL0_CONFIG_BUSYF_MASK     (0x00100000)\n\n#define FLASHCTRL0_WRADDR                (0x4002E0A0)\n#define FLASHCTRL0_WRDATA                (0x4002E0B0)\n\n#define FLASHCTRL0_KEY                   (0x4002E0C0)\n#define FLASHCTRL0_KEY_INITIAL_UNLOCK    (0x000000A5)\n#define FLASHCTRL0_KEY_SINGLE_UNLOCK     (0x000000F1)\n#define FLASHCTRL0_KEY_MULTIPLE_UNLOCK   (0x000000F2)\n#define FLASHCTRL0_KEY_MULTIPLE_LOCK     (0x0000005A)\n\n#define FLASH_BUSY_TIMEOUT               (100)\n\n/* SI32_RSTSRC_0 */\n#define RSTSRC0_RESETEN_ALL              (0x4002D060)\n#define RSTSRC0_RESETEN_SET              (0x4002D064)\n#define RSTSRC0_RESETEN_CLR              (0x4002D068)\n#define RSTSRC0_RESETEN_VMONREN_MASK     (0x00000004)\n#define RSTSRC0_RESETEN_SWREN_MASK       (0x00000040)\n\n/* SI32_VMON_0 */\n#define VMON0_CONTROL_ALL                (0x4002F000)\n#define VMON0_CONTROL_SET                (0x4002F004)\n#define VMON0_CONTROL_CLR                (0x4002F008)\n#define VMON0_CONTROL_VMONEN_MASK        (0x80000000)\n\n/* SI32_CLKCTRL_0 */\n#define CLKCTRL0_APBCLKG0_ALL            (0x4002D020)\n#define CLKCTRL0_APBCLKG0_SET            (0x4002D024)\n#define CLKCTRL0_APBCLKG0_CLR            (0x4002D028)\n#define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK (0x40000000)\n\n/* SI32_WDTIMER_0 */\n#define WDTIMER0_CONTROL_ALL             (0x40030000)\n#define WDTIMER0_CONTROL_SET             (0x40030004)\n#define WDTIMER0_CONTROL_CLR             (0x40030008)\n#define WDTIMER0_CONTROL_DBGMD_MASK      (0x00000002)\n\n#define WDTIMER0_STATUS_ALL              (0x40030010)\n#define WDTIMER0_STATUS_SET              (0x40030014)\n#define WDTIMER0_STATUS_CLR              (0x40030018)\n#define WDTIMER0_STATUS_KEYSTS_MASK      (0x00000001)\n#define WDTIMER0_STATUS_PRIVSTS_MASK     (0x00000002)\n\n#define WDTIMER0_THRESHOLD               (0x40030020)\n\n#define WDTIMER0_WDTKEY                  (0x40030030)\n#define WDTIMER0_KEY_ATTN                (0x000000A5)\n#define WDTIMER0_KEY_WRITE               (0x000000F1)\n#define WDTIMER0_KEY_RESET               (0x000000CC)\n#define WDTIMER0_KEY_DISABLE             (0x000000DD)\n#define WDTIMER0_KEY_START               (0x000000EE)\n#define WDTIMER0_KEY_LOCK                (0x000000FF)\n\n/* DAP */\n#define SIM3X_AP                         (0x0A)\n\n#define SIM3X_AP_CTRL1                   (0x00)\n#define SIM3X_AP_CTRL2                   (0x04)\n#define SIM3X_AP_LOCK                    (0x08)\n#define SIM3X_AP_CRC                     (0x0C)\n\n#define SIM3X_AP_INIT_STAT               (0x10)\n#define SIM3X_AP_DAP_IN                  (0x14)\n#define SIM3X_AP_DAP_OUT                 (0x18)\n\n#define SIM3X_AP_ID                      (0xFC)\n\n/* DAP register values */\n#define SIM3X_AP_CTRL1_MASS_ERASE_REQ    (0x00000001)\n#define SIM3X_AP_CTRL1_RESET_REQ         (0x00000008)\n/* this bit is set if MCU is locked */\n#define SIM3X_AP_INIT_STAT_LOCK          (0x00000004)\n/* expected value inside SIM3X_AP_ID */\n#define SIM3X_AP_ID_VALUE                (0x2430002)\n\n#define SIM3X_FLASH_PAGE_SIZE            1024\n\nstruct sim3x_info {\n\tuint16_t flash_size_kb;\n\tuint16_t part_number;\n\tchar part_family;\n\tuint8_t device_revision;\n\tchar device_package[4];\n\tbool probed;\n\tbool need_init;\n\tbool flash_locked;\n};\n\n/* flash bank sim3x 0 0 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command)\n{\n\tstruct sim3x_info *sim3x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Init sim3x_info struct */\n\tsim3x_info = malloc(sizeof(struct sim3x_info));\n\tsim3x_info->probed = false;\n\tsim3x_info->need_init = true;\n\tsim3x_info->device_revision = 0;\n\tmemset(sim3x_info->device_package, 0, 4);\n\tbank->driver_priv = sim3x_info;\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_init(struct flash_bank *bank)\n{\n\tint ret;\n\tstruct target *target;\n\tstruct sim3x_info *sim3x_info;\n\n\ttarget = bank->target;\n\n\t/* Disable watchdog timer */\n\tret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_DISABLE);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Enable one write command */\n\tret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_WRITE);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Watchdog Timer Debug Mode */\n\tret = target_write_u32(target, WDTIMER0_CONTROL_SET,\n\t\t\tWDTIMER0_CONTROL_DBGMD_MASK);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Enable VDD Supply Monitor */\n\tret = target_write_u32(target, VMON0_CONTROL_SET,\n\t\t\tVMON0_CONTROL_VMONEN_MASK);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Set VDD Supply Monitor as a reset source */\n\tret = target_write_u32(target, RSTSRC0_RESETEN_SET,\n\t\t\tRSTSRC0_RESETEN_VMONREN_MASK);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Flash Controller Clock Enable */\n\tret = target_write_u32(target, CLKCTRL0_APBCLKG0_SET,\n\t\t\tCLKCTRL0_APBCLKG0_FLCTRLCEN_MASK);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Disable Flash Erase Mode */\n\tret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR,\n\t\t\tFLASHCTRL0_CONFIG_ERASEEN_MASK);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tsim3x_info = bank->driver_priv;\n\tsim3x_info->need_init = 0;\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_erase_page(struct flash_bank *bank, uint32_t addr)\n{\n\tint ret, i;\n\tuint32_t temp;\n\tstruct target *target;\n\n\ttarget = bank->target;\n\n\tfor (i = 0; i < FLASH_BUSY_TIMEOUT; i++) {\n\t\tret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\t/* If is not busy */\n\t\tif ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) {\n\t\t\t/* If erase is not enabled */\n\t\t\tif ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) == 0) {\n\t\t\t\t/* Enter Flash Erase Mode */\n\t\t\t\tret = target_write_u32(target, FLASHCTRL0_CONFIG_SET,\n\t\t\t\t\t\tFLASHCTRL0_CONFIG_ERASEEN_MASK);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t/* Write the address of the Flash page to WRADDR */\n\t\t\tret = target_write_u32(target, FLASHCTRL0_WRADDR, addr);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\n\t\t\t/* Write the initial unlock value to KEY */\n\t\t\tret = target_write_u32(target, FLASHCTRL0_KEY,\n\t\t\tFLASHCTRL0_KEY_INITIAL_UNLOCK);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\n\t\t\t/* Write the single unlock value to KEY */\n\t\t\tret = target_write_u32(target, FLASHCTRL0_KEY,\n\t\t\tFLASHCTRL0_KEY_SINGLE_UNLOCK);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\n\t\t\t/* Write any value to WRDATA to initiate the page erase */\n\t\t\tret = target_write_u32(target, FLASHCTRL0_WRDATA, 0);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\talive_sleep(1);\n\t}\n\n\tLOG_ERROR(\"timed out waiting for FLASHCTRL0_CONFIG_BUSYF\");\n\treturn ERROR_FAIL;\n}\n\nstatic int sim3x_flash_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint ret;\n\tuint32_t temp;\n\tstruct sim3x_info *sim3x_info;\n\tstruct target *target;\n\n\t/* Check if target is halted */\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tsim3x_info = bank->driver_priv;\n\n\t/* Init MCU after reset */\n\tif (sim3x_info->need_init) {\n\t\tret = sim3x_init(bank);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to init MCU\");\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t/* erase pages */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tret = sim3x_erase_page(bank, bank->sectors[i].offset);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\ttarget = bank->target;\n\n\t/* Wait until busy */\n\tfor (unsigned int i = 0; i < FLASH_BUSY_TIMEOUT; i++) {\n\t\tret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) { /* If is not busy */\n\t\t\tif ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) != 0) { /* If erase is enabled */\n\t\t\t\t/* Disable Flash Erase Mode */\n\t\t\t\tret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR,\n\t\t\t\t\t\tFLASHCTRL0_CONFIG_ERASEEN_MASK);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\talive_sleep(1);\n\t}\n\n\tLOG_ERROR(\"timed out waiting for FLASHCTRL0_CONFIG_BUSYF\");\n\treturn ERROR_FAIL;\n}\n\nstatic int sim3x_write_block(struct flash_bank *bank, const uint8_t *buf,\n\t\tuint32_t offset, uint32_t count) /* count is count of half words (2 bytes)! */\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint ret = ERROR_OK;\n\n\t/* see contrib/loaders/flash/sim3x.s for src */\n\n\tstatic const uint8_t sim3x_flash_write_code[] = {\n\t\t/* Write the initial unlock value to KEY (0xA5) */\n\t\t0xA5, 0x26, /* movs    r6, #INITIAL_UNLOCK */\n\t\t0xC0, 0xF8, 0xC0, 0x60, /* str     r6, [r0, #FLASHCTRL_KEY] */\n\n\t\t/* Write the multiple unlock value to KEY (0xF2) */\n\t\t0xF2, 0x26, /* movs    r6, #MULTIPLE_UNLOCK */\n\t\t0xC0, 0xF8, 0xC0, 0x60, /* str     r6, [r0, #FLASHCTRL_KEY] */\n\n\t\t/* wait_fifo: */\n\t\t0x16, 0x68, /* ldr     r6, [r2, #0] */\n\t\t0x00, 0x2E, /* cmp     r6, #0 */\n\t\t0x16, 0xD0, /* beq     exit */\n\t\t0x55, 0x68, /* ldr     r5, [r2, #4] */\n\t\t0xB5, 0x42, /* cmp     r5, r6 */\n\t\t0xF9, 0xD0, /* beq     wait_fifo */\n\n\t\t/* wait for BUSYF flag */\n\t\t/* wait_busy1: */\n\t\t0x06, 0x68, /* ldr     r6, [r0, #FLASHCTRL_CONFIG] */\n\t\t0x16, 0xF4, 0x80, 0x1F, /* tst     r6, #BUSYF */\n\t\t0xFB, 0xD1, /* bne     wait_busy1 */\n\n\t\t/* Write the destination address to WRADDR */\n\t\t0xC0, 0xF8, 0xA0, 0x40, /* str     r4, [r0, #FLASHCTRL_WRADDR] */\n\n\t\t/* Write the data half-word to WRDATA in right-justified format */\n\t\t0x2E, 0x88, /* ldrh    r6, [r5] */\n\t\t0xC0, 0xF8, 0xB0, 0x60, /* str     r6, [r0, #FLASHCTRL_WRDATA] */\n\n\t\t0x02, 0x35, /* adds    r5, #2 */\n\t\t0x02, 0x34, /* adds    r4, #2 */\n\n\t\t/* wrap rp at end of buffer */\n\t\t0x9D, 0x42, /* cmp     r5, r3 */\n\t\t0x01, 0xD3, /* bcc     no_wrap */\n\t\t0x15, 0x46, /* mov     r5, r2 */\n\t\t0x08, 0x35, /* adds    r5, #8 */\n\n\t\t/* no_wrap: */\n\t\t0x55, 0x60, /* str     r5, [r2, #4] */\n\t\t0x49, 0x1E, /* subs    r1, r1, #1 */\n\t\t0x00, 0x29, /* cmp     r1, #0 */\n\t\t0x00, 0xD0, /* beq     exit */\n\t\t0xE5, 0xE7, /* b       wait_fifo */\n\n\t\t/* exit: */\n\t\t0x5A, 0x26, /* movs    r6, #MULTIPLE_LOCK */\n\t\t0xC0, 0xF8, 0xC0, 0x60, /* str     r6, [r0, #FLASHCTRL_KEY] */\n\n\t\t/* wait for BUSYF flag */\n\t\t/* wait_busy2: */\n\t\t0x06, 0x68, /* ldr     r6, [r0, #FLASHCTRL_CONFIG] */\n\t\t0x16, 0xF4, 0x80, 0x1F, /* tst     r6, #BUSYF */\n\t\t0xFB, 0xD1, /* bne     wait_busy2 */\n\n\t\t0x00, 0xBE /* bkpt    #0 */\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(sim3x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tret = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(sim3x_flash_write_code), sim3x_flash_write_code);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tbuffer_size &= ~1UL; /* Make sure it's 2 byte aligned */\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm\n\t\t\t */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT); /* flash base */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT); /* count */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT); /* buffer start */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT); /* buffer end */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN_OUT); /* target address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, FLASHCTRL0_CONFIG_ALL);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tret = target_run_flash_async_algorithm(target, buf, count, 2, 0, NULL, 5,\n\t\t\treg_params, source->address, source->size, write_algorithm->address,\n\t\t\t0, &armv7m_info);\n\n\tif (ret == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"flash write failed at address 0x%\"PRIx32,\n\t\t\tbuf_get_u32(reg_params[4].value, 0, 32));\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn ret;\n}\n\nstatic int sim3x_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tint ret;\n\tstruct target *target;\n\tstruct sim3x_info *sim3x_info;\n\tuint8_t *new_buffer = NULL;\n\n\ttarget = bank->target;\n\n\t/* Check if target is halted */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tsim3x_info = bank->driver_priv;\n\n\tif (sim3x_info->flash_locked) {\n\t\tLOG_ERROR(\"Flash is locked\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Init MCU after reset */\n\tif (sim3x_info->need_init) {\n\t\tret = sim3x_init(bank);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tif (offset & 0x1) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (count & 0x1) {\n\t\tuint32_t old_count = count;\n\t\tcount++;\n\t\tnew_buffer = malloc(count);\n\n\t\tif (!new_buffer) {\n\t\t\tLOG_ERROR(\"odd number of bytes to write and no memory \"\n\t\t\t\t\t\"for padding buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"odd number of bytes to write (%\" PRIu32 \"), extending to %\" PRIu32\n\t\t\t\t\" and padding with 0xff\", old_count, count);\n\n\t\tnew_buffer[count - 1] = 0xff;\n\t\tbuffer = memcpy(new_buffer, buffer, old_count);\n\t}\n\n\tret = sim3x_write_block(bank, buffer, offset, count / 2);\n\tfree(new_buffer);\n\treturn ret;\n}\n\nstatic int sim3x_flash_lock_check(struct flash_bank *bank)\n{\n\tint ret;\n\tuint32_t lock_word;\n\tstruct sim3x_info *sim3x_info;\n\n\tret = target_read_u32(bank->target, LOCK_WORD_ADDRESS, &lock_word);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Can not read Lock Word\");\n\t\treturn ret;\n\t}\n\n\tsim3x_info = bank->driver_priv;\n\tsim3x_info->flash_locked = (lock_word != 0xFFFFFFFF);\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_flash_protect_check(struct flash_bank *bank)\n{\n\tint ret;\n\tstruct sim3x_info *sim3x_info;\n\n\t/* Check if target is halted */\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tret = sim3x_flash_lock_check(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tsim3x_info = bank->driver_priv;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = sim3x_info->flash_locked;\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_flash_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tint ret;\n\tuint8_t lock_word[4];\n\tstruct sim3x_info *sim3x_info;\n\tstruct target *target;\n\n\ttarget = bank->target;\n\n\t/* Check if target is halted */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (first != 0 || last != bank->num_sectors - 1) {\n\t\tLOG_ERROR(\"Flash does not support finer granularity\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsim3x_info = bank->driver_priv;\n\n\tif (set) {\n\t\tif (sim3x_info->flash_locked) {\n\t\t\tLOG_INFO(\"Flash is already locked\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Lock Flash */\n\t\ttarget_buffer_set_u32(target, lock_word, 0xFFFFFFFE);\n\t\tret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t} else {\n\t\t/* Flash is unlocked by an erase operation */\n\t\tret = sim3x_flash_erase(bank, 0, 0);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tret = sim3x_flash_protect_check(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (set) {\n\t\tif (sim3x_info->flash_locked) {\n\t\t\tLOG_INFO(\"Flash locked\");\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tLOG_ERROR(\"Flash lock error\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tif (sim3x_info->flash_locked) {\n\t\t\tLOG_ERROR(\"Flash unlock error\");\n\t\t\treturn ERROR_FAIL;\n\t\t} else {\n\t\t\tLOG_INFO(\"Flash unlocked\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n}\n\nstatic int sim3x_read_deviceid(struct flash_bank *bank)\n{\n\tint ret;\n\tstruct sim3x_info *sim3x_info;\n\n\tuint32_t device_id;\n\tint part_number;\n\tchar part_num_string[4];\n\n\tsim3x_info = bank->driver_priv;\n\n\t/* MCU check */\n\tret = target_read_u32(bank->target, DEVICEID0_DEVICEID2, &device_id);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Device ID should be 'M3' */\n\tif (device_id != 0x00004D33)\n\t\treturn ERROR_FAIL;\n\n\t/* Family and Part number */\n\tret = target_read_u32(bank->target, DEVICEID0_DEVICEID1, &device_id);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tpart_num_string[0] = device_id >> 16;\n\tpart_num_string[1] = device_id >> 8;\n\tpart_num_string[2] = device_id;\n\tpart_num_string[3] = 0;\n\n\tpart_number = atoi(part_num_string);\n\n\t/* Part Number should be between 100 and 999 */\n\tif (!isalpha(device_id >> 24) || part_number < 100 || part_number > 999)\n\t\treturn ERROR_FAIL;\n\n\tsim3x_info->part_family = device_id >> 24;\n\tsim3x_info->part_number = part_number;\n\n\t/* Package and Revision */\n\tret = target_read_u32(bank->target, DEVICEID0_DEVICEID0, &device_id);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tsim3x_info->device_package[0] = device_id >> 24;\n\tsim3x_info->device_package[1] = device_id >> 16;\n\tsim3x_info->device_package[2] = device_id >> 8;\n\tsim3x_info->device_package[3] = 0;\n\n\tsim3x_info->device_revision = device_id;\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_parse_part_info(struct sim3x_info *sim3x_info)\n{\n\tswitch (sim3x_info->part_number) {\n\tcase 134:\n\tcase 136:\n\t\tsim3x_info->flash_size_kb = 32;\n\t\tbreak;\n\tcase 144:\n\tcase 146:\n\t\tsim3x_info->flash_size_kb = 64;\n\t\tbreak;\n\tcase 154:\n\tcase 156:\n\tcase 157:\n\t\tsim3x_info->flash_size_kb = 128;\n\t\tbreak;\n\tcase 164:\n\tcase 166:\n\tcase 167:\n\t\tsim3x_info->flash_size_kb = 256;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Unknown Part number %d\", sim3x_info->part_number);\n\t\tsim3x_info->part_number = 0;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (sim3x_info->part_family) {\n\tcase 'c':\n\tcase 'C':\n\t\tLOG_INFO(\"SiM3C%d detected\", sim3x_info->part_number);\n\t\tbreak;\n\tcase 'u':\n\tcase 'U':\n\t\tLOG_INFO(\"SiM3U%d detected\", sim3x_info->part_number);\n\t\tbreak;\n\tcase 'l':\n\tcase 'L':\n\t\tLOG_INFO(\"SiM3L%d detected\", sim3x_info->part_number);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Unsupported MCU family %c\", sim3x_info->part_family);\n\t\tsim3x_info->part_family = 0;\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_read_info(struct flash_bank *bank)\n{\n\tint ret;\n\tstruct sim3x_info *sim3x_info;\n\tuint32_t cpuid;\n\n\tsim3x_info = bank->driver_priv;\n\n\t/* Core check */\n\tret = target_read_u32(bank->target, CPUID, &cpuid);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read CPU ID\");\n\t\treturn ret;\n\t}\n\n\tif (((cpuid >> 4) & 0xfff) != 0xc23) {\n\t\tLOG_ERROR(\"Target is not Cortex-M3\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Read info from chip */\n\tret = sim3x_read_deviceid(bank);\n\tif (ret == ERROR_OK) {\n\t\tret = sim3x_parse_part_info(sim3x_info);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to parse info from MCU\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tLOG_WARNING(\"Failed to read info from MCU, using info from flash bank parameters\");\n\n\t\t/* Check if flash size is given in flash bank command */\n\t\tif (!bank->size) {\n\t\t\tLOG_ERROR(\"Flash size not set in the flash bank command\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Convert bank size to kb */\n\t\tsim3x_info->flash_size_kb = bank->size / 1024;\n\t}\n\n\tLOG_INFO(\"Flash size = %dKB\", sim3x_info->flash_size_kb);\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_probe(struct flash_bank *bank)\n{\n\tint ret, i;\n\tstruct sim3x_info *sim3x_info;\n\n\tsim3x_info = bank->driver_priv;\n\tsim3x_info->probed = false;\n\tsim3x_info->need_init = true;\n\n\t/* Read info from chip */\n\tret = sim3x_read_info(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = sim3x_flash_lock_check(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tfree(bank->sectors);\n\n\tbank->base = FLASH_BASE_ADDRESS;\n\tbank->size = sim3x_info->flash_size_kb * SIM3X_FLASH_PAGE_SIZE;\n\tbank->num_sectors = SIM3X_FLASH_PAGE_SIZE;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * sim3x_info->flash_size_kb);\n\n\tfor (i = 0; i < sim3x_info->flash_size_kb; i++) {\n\t\tbank->sectors[i].offset = i * SIM3X_FLASH_PAGE_SIZE;\n\t\tbank->sectors[i].size = SIM3X_FLASH_PAGE_SIZE;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = sim3x_info->flash_locked;\n\t}\n\n\tsim3x_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int sim3x_auto_probe(struct flash_bank *bank)\n{\n\tstruct sim3x_info *sim3x_info;\n\n\tsim3x_info = bank->driver_priv;\n\n\tif (sim3x_info->probed) {\n\t\tsim3x_info->need_init = true;\n\t\treturn ERROR_OK;\n\t} else {\n\t\treturn sim3x_probe(bank);\n\t}\n}\n\nstatic int sim3x_flash_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct sim3x_info *sim3x_info;\n\n\tsim3x_info = bank->driver_priv;\n\n\t/* Read info about chip */\n\tint ret = sim3x_read_info(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Part */\n\tif (sim3x_info->part_family && sim3x_info->part_number) {\n\t\tcommand_print_sameline(cmd, \"SiM3%c%d\", sim3x_info->part_family, sim3x_info->part_number);\n\n\t\t/* Revision */\n\t\tif (sim3x_info->device_revision && sim3x_info->device_revision <= 'Z' - 'A') {\n\t\t\tcommand_print_sameline(cmd, \"-%c\", sim3x_info->device_revision + 'A');\n\n\t\t\t/* Package */\n\t\t\tcommand_print_sameline(cmd, \"-G%s\", sim3x_info->device_package);\n\t\t}\n\t}\n\n\t/* Print flash size */\n\tcommand_print_sameline(cmd, \" flash_size = %dKB\", sim3x_info->flash_size_kb);\n\n\treturn ERROR_OK;\n}\n/**\n *  reg 31:8 - no effect\n *  reg 7:4  - bank\n *  reg 3:2  - register\n *  reg 1:0  - no effect\n */\nstatic int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)\n{\n\tLOG_DEBUG(\"DAP_REG[0x%02x] <- %08\" PRIX32, reg, value);\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"DAP: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_write(ap, reg, value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"DAP: failed to queue a write request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"DAP: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)\n{\n\tstruct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);\n\tif (!ap) {\n\t\tLOG_DEBUG(\"DAP: failed to get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_queue_ap_read(ap, reg, result);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"DAP: failed to queue a read request\");\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"DAP: dap_run failed\");\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"DAP_REG[0x%02x]: %08\" PRIX32, reg, *result);\n\treturn ERROR_OK;\n}\n\nstatic int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout)\n{\n\tuint32_t val;\n\tint retval;\n\n\tdo {\n\t\tretval = ap_read_register(dap, reg, &val);\n\t\tif (retval != ERROR_OK || (val & mask) == value)\n\t\t\treturn retval;\n\n\t\talive_sleep(1);\n\t} while (timeout--);\n\n\tLOG_DEBUG(\"DAP: polling timed out\");\n\treturn ERROR_FAIL;\n}\n\nCOMMAND_HANDLER(sim3x_mass_erase)\n{\n\tuint32_t val;\n\tint ret;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\t/* Used debug interface doesn't support direct DAP access */\n\t\tLOG_ERROR(\"mass_erase can't be used by this debug interface\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = ap_read_register(dap, SIM3X_AP_ID, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (val != SIM3X_AP_ID_VALUE) {\n\t\tLOG_ERROR(\"Wrong SIM3X_AP_ID\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Mass erase sequence */\n\tret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ | SIM3X_AP_CTRL1_MASS_ERASE_REQ);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ap_poll_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_MASS_ERASE_REQ, 0x00000000, FLASH_BUSY_TIMEOUT);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ap_write_register(dap, SIM3X_AP_CTRL1, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_INFO(\"Mass erase success\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sim3x_lock)\n{\n\tuint32_t val;\n\tint ret;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *dap = cortex_m->armv7m.arm.dap;\n\n\tif (!dap) {\n\t\t/* Used debug interface doesn't support direct DAP access */\n\t\tLOG_INFO(\"Target can't be unlocked by this debug interface\");\n\n\t\t/* Core check */\n\t\tret = target_read_u32(target, CPUID, &val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif ((val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {\n\t\t\tLOG_ERROR(\"Target is not ARM Cortex-M3 or is already locked\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\t/* check SIM3X_AP_ID */\n\t\tret = ap_read_register(dap, SIM3X_AP_ID, &val);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (val != SIM3X_AP_ID_VALUE) {\n\t\t\tLOG_ERROR(\"Wrong SIM3X_AP_ID\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* check if locked */\n\t\tret = target_read_u32(target, CPUID, &val);\n\t\t/* if correct value is read, then it will continue */\n\t\tif (ret != ERROR_OK || (val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {\n\t\t\t/* if correct value isn't read, then it will check SIM3X_AP_INIT_STAT register */\n\t\t\tret = ap_read_register(dap, SIM3X_AP_INIT_STAT, &val);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\n\t\t\tif (val & SIM3X_AP_INIT_STAT_LOCK) {\n\t\t\t\tLOG_INFO(\"Target is already locked\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"Target doesn't seem to be locked but memory was not read correct\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\tret = target_read_u32(target, LOCK_WORD_ADDRESS, &val);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (val == LOCK_WORD_MCU_UNLOCKED) {\n\t\t/* Lock Flash */\n\t\tuint8_t lock_word[4];\n\t\ttarget_buffer_set_u32(target, lock_word, 0xFFFFFFFE);\n\n\t\t/* Get Flash Bank */\n\t\tstruct flash_bank *bank;\n\t\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tLOG_INFO(\"Target is successfully locked\");\n\t\treturn ERROR_OK;\n\t} else if (val == LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE) {\n\t\t/* Can't by locked again without erase, because LOCK_WORD is in FLASH */\n\t\tLOG_ERROR(\"Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_ERROR(\"Unexpected lock word value\");\n\n\t\t/* SIM3X_AP_ID_VALUE is not checked */\n\t\tif (!dap)\n\t\t\tLOG_INFO(\"Maybe this isn't a SiM3x MCU\");\n\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nstatic const struct command_registration sim3x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Erase the complete flash\",\n\t\t.usage = \"\",\n\t\t.handler = sim3x_mass_erase,\n\t},\n\t{\n\t\t.name = \"lock\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Locks the flash. Unlock by mass erase\",\n\t\t.usage = \"\",\n\t\t.handler = sim3x_lock,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration sim3x_command_handlers[] = {\n\t{\n\t\t.name = \"sim3x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"sim3x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = sim3x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver sim3x_flash = {\n\t.name = \"sim3x\",\n\t.commands = sim3x_command_handlers,\n\t.flash_bank_command = sim3x_flash_bank_command,\n\t.erase = sim3x_flash_erase,\n\t.protect = sim3x_flash_protect,\n\t.write = sim3x_flash_write,\n\t.read = default_flash_read,\n\t.probe = sim3x_probe,\n\t.auto_probe = sim3x_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = sim3x_flash_protect_check,\n\t.info = sim3x_flash_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/spi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Andreas Bolsch                                  *\n *   andreas.bolsch@mni.thm.de                                             *\n *                                                                         *\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n *                                                                         *\n *   Copyright (C) 2010 by Antonio Borneo                                  *\n *   borneo.antonio@gmail.com                                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <jtag/jtag.h>\n\n /* Shared table of known SPI flash devices for SPI-based flash drivers. Taken\n  * from device datasheets and Linux SPI flash drivers. */\nconst struct flash_device flash_devices[] = {\n\t/* name, read_cmd, qread_cmd, pprog_cmd, erase_cmd, chip_erase_cmd, device_id,\n\t * pagesize, sectorsize, size_in_bytes\n\t * note: device id is usually 3 bytes long, however the unused highest byte counts\n\t * continuation codes for manufacturer id as per JEP106xx */\n\tFLASH_ID(\"st m25pe10\",          0x03, 0x00, 0x02, 0xd8, 0x00, 0x00118020, 0x100, 0x10000, 0x20000),\n\tFLASH_ID(\"st m25pe20\",          0x03, 0x00, 0x02, 0xd8, 0x00, 0x00128020, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"st m25pe40\",          0x03, 0x00, 0x02, 0xd8, 0x00, 0x00138020, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"st m25pe80\",          0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00148020, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"st m25pe16\",          0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00158020, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"st m25p05\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00102020, 0x80,  0x8000,  0x10000),\n\tFLASH_ID(\"st m25p10\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00112020, 0x80,  0x8000,  0x20000),\n\tFLASH_ID(\"st m25p20\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00122020, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"st m25p40\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00132020, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"st m25p80\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00142020, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"st m25p16\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00152020, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"st m25p32\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00162020, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"st m25p64\",           0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00172020, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"st m25p128\",          0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00182020, 0x100, 0x40000, 0x1000000),\n\tFLASH_ID(\"st m45pe10\",          0x03, 0x00, 0x02, 0xd8, 0xd8, 0x00114020, 0x100, 0x10000, 0x20000),\n\tFLASH_ID(\"st m45pe20\",          0x03, 0x00, 0x02, 0xd8, 0xd8, 0x00124020, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"st m45pe40\",          0x03, 0x00, 0x02, 0xd8, 0xd8, 0x00134020, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"st m45pe80\",          0x03, 0x00, 0x02, 0xd8, 0xd8, 0x00144020, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"sp s25fl004\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00120201, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"sp s25fl008\",         0x03, 0x08, 0x02, 0xd8, 0xc7, 0x00130201, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"sp s25fl016\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00140201, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"sp s25fl116k\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00154001, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"sp s25fl032\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00150201, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"sp s25fl132k\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00164001, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"sp s25fl064\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00160201, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"sp s25fl164k\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00174001, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"sp s25fl128s\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00182001, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"sp s25fl256s\",        0x13, 0x00, 0x12, 0xdc, 0xc7, 0x00190201, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"sp s25fl512s\",        0x13, 0x00, 0x12, 0xdc, 0xc7, 0x00200201, 0x200, 0x40000, 0x4000000),\n\tFLASH_ID(\"cyp s25fl064l\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00176001, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"cyp s25fl128l\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x00186001, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"cyp s25fl256l\",       0x13, 0x00, 0x12, 0xdc, 0xc7, 0x00196001, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"cyp s28hl256t\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x00195a34, 0x100, 0x40000, 0x2000000), /* page! */\n\tFLASH_ID(\"cyp s28hs256t\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x00195b34, 0x100, 0x40000, 0x2000000), /* page! */\n\tFLASH_ID(\"cyp s28hl512t\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a5a34, 0x100, 0x40000, 0x4000000), /* page! */\n\tFLASH_ID(\"cyp s28hs512t\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a5b34, 0x100, 0x40000, 0x4000000), /* page! */\n\tFLASH_ID(\"cyp s28hl01gt\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b5a34, 0x100, 0x40000, 0x8000000), /* page! */\n\tFLASH_ID(\"cyp s28hs01gt\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b5b34, 0x100, 0x40000, 0x8000000), /* page! */\n\tFLASH_ID(\"atmel 25f512\",        0x03, 0x00, 0x02, 0x52, 0xc7, 0x0065001f, 0x80,  0x8000,  0x10000),\n\tFLASH_ID(\"atmel 25f1024\",       0x03, 0x00, 0x02, 0x52, 0x62, 0x0060001f, 0x100, 0x8000,  0x20000),\n\tFLASH_ID(\"atmel 25f2048\",       0x03, 0x00, 0x02, 0x52, 0x62, 0x0063001f, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"atmel 25f4096\",       0x03, 0x00, 0x02, 0x52, 0x62, 0x0064001f, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"atmel 25fs040\",       0x03, 0x00, 0x02, 0xd7, 0xc7, 0x0004661f, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"adesto 25sf041b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001841f, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"adesto 25df081a\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001451f, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"adesto 25sf081b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001851f, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"adesto 25sf161b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001861f, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"adesto 25df321b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001471f, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"adesto 25sf321b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001871f, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"adesto 25xf641b\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001881f, 0x100, 0x10000, 0x800000), /* sf/qf */\n\tFLASH_ID(\"adesto 25xf128a\",     0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0001891f, 0x100, 0x10000, 0x1000000), /* sf/qf */\n\tFLASH_ID(\"adesto xp032\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0700a743, 0x100, 0x10000, 0x400000), /* 4-byte */\n\tFLASH_ID(\"adesto xp064b\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0001a81f, 0x100, 0x10000, 0x800000), /* 4-byte */\n\tFLASH_ID(\"adesto xp128\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0000a91f, 0x100, 0x10000, 0x1000000), /* 4-byte */\n\tFLASH_ID(\"mac 25l512\",          0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001020c2, 0x010, 0x10000, 0x10000),\n\tFLASH_ID(\"mac 25l1005\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001120c2, 0x010, 0x10000, 0x20000),\n\tFLASH_ID(\"mac 25l2005\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001220c2, 0x010, 0x10000, 0x40000),\n\tFLASH_ID(\"mac 25l4005\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001320c2, 0x010, 0x10000, 0x80000),\n\tFLASH_ID(\"mac 25l8005\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001420c2, 0x010, 0x10000, 0x100000),\n\tFLASH_ID(\"mac 25l1605\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001520c2, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"mac 25l3205\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001620c2, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"mac 25l6405\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001720c2, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"mac 25l12845\",        0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001820c2, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"mac 25l25645\",        0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001920c2, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"mac 25l51245\",        0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a20c2, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"mac 25lm51245\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x003a85c2, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"mac 25r512f\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001028c2, 0x100, 0x10000, 0x10000),\n\tFLASH_ID(\"mac 25r1035f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001128c2, 0x100, 0x10000, 0x20000),\n\tFLASH_ID(\"mac 25r2035f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001228c2, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"mac 25r4035f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001328c2, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"mac 25r8035f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001428c2, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"mac 25r1635f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001528c2, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"mac 25r3235f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001628c2, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"mac 25r6435f\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001728c2, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"mac 25u1635e\",        0x03, 0xeb, 0x02, 0x20, 0xc7, 0x003525c2, 0x100, 0x1000,  0x100000),\n\tFLASH_ID(\"mac 66l1g45g\",        0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001b20c2, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"mac 66um1g45g\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x003b80c2, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"mac 66lm1g45g\",       0x13, 0xec, 0x12, 0xdc, 0xc7, 0x003b85c2, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"micron n25q032\",      0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0016ba20, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"micron n25q064\",      0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0017ba20, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"micron n25q128\",      0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018ba20, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"micron n25q256 3v\",   0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019ba20, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"micron n25q256 1.8v\", 0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019bb20, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"micron mt25ql512\",    0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0020ba20, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"micron mt25ql01\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021ba20, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"micron mt25qu01\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0021bb20, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"micron mt25ql02\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0022ba20, 0x100, 0x10000, 0x10000000),\n\tFLASH_ID(\"win w25q80bv\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001440ef, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"win w25q16jv\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001540ef, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"win w25q16jv\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001570ef, 0x100, 0x10000, 0x200000), /* QPI / DTR */\n\tFLASH_ID(\"win w25q32fv/jv\",     0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001640ef, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"win w25q32fv\",        0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001660ef, 0x100, 0x10000, 0x400000), /* QPI mode */\n\tFLASH_ID(\"win w25q32jv\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001670ef, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"win w25q64fv/jv\",     0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001740ef, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"win w25q64fv\",        0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001760ef, 0x100, 0x10000, 0x800000), /* QPI mode */\n\tFLASH_ID(\"win w25q64jv\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001770ef, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"win w25q128fv/jv\",    0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001840ef, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"win w25q128fv\",       0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001860ef, 0x100, 0x10000, 0x1000000), /* QPI mode */\n\tFLASH_ID(\"win w25q128jv\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001870ef, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"win w25q256fv/jv\",    0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001940ef, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"win w25q256fv\",       0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x001960ef, 0x100, 0x10000, 0x2000000), /* QPI mode */\n\tFLASH_ID(\"win w25q256jv\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001970ef, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"win w25q512jv\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x002040ef, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"win w25q01jv\",        0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002140ef, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"win w25q01jv-dtr\",    0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x002170ef, 0x100, 0x10000, 0x8000000),\n\tFLASH_ID(\"win w25q02jv-dtr\",    0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x002270ef, 0x100, 0x10000, 0x10000000),\n\tFLASH_ID(\"gd gd25q512\",         0x03, 0x00, 0x02, 0x20, 0xc7, 0x001040c8, 0x100, 0x1000,  0x10000),\n\tFLASH_ID(\"gd gd25q10\",          0x03, 0x00, 0x02, 0x20, 0xc7, 0x001140c8, 0x100, 0x1000,  0x20000),\n\tFLASH_ID(\"gd gd25q20\",          0x03, 0x00, 0x02, 0x20, 0xc7, 0x001240c8, 0x100, 0x1000,  0x40000),\n\tFLASH_ID(\"gd gd25q40\",          0x03, 0x00, 0x02, 0x20, 0xc7, 0x001340c8, 0x100, 0x1000,  0x80000),\n\tFLASH_ID(\"gd gd25q16c\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001540c8, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"gd gd25q32c\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001640c8, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"gd gd25q64c\",         0x03, 0x00, 0x02, 0xd8, 0xc7, 0x001740c8, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"gd gd25q128c\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x001840c8, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"gd gd25q256c\",        0x13, 0x00, 0x12, 0xdc, 0xc7, 0x001940c8, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"gd gd25q512mc\",       0x13, 0x00, 0x12, 0xdc, 0xc7, 0x002040c8, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"gd gd25lx256e\",       0x13, 0x0c, 0x12, 0xdc, 0xc7, 0x001968c8, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"zbit zb25vq16\",       0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0015605e, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"zbit zb25vq32\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016405e, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"zbit zb25vq32\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016605e, 0x100, 0x10000, 0x400000), /* QPI mode */\n\tFLASH_ID(\"zbit zb25vq64\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017405e, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"zbit zb25vq64\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017605e, 0x100, 0x10000, 0x800000), /* QPI mode */\n\tFLASH_ID(\"zbit zb25vq128\",      0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018405e, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"zbit zb25vq128\",      0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018605e, 0x100, 0x10000, 0x1000000), /* QPI mode */\n\tFLASH_ID(\"issi is25lq040b\",     0x03, 0xeb, 0x02, 0x20, 0xc7, 0x0013409d, 0x100, 0x1000,  0x80000),\n\tFLASH_ID(\"issi is25lp032\",      0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0016609d, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"issi is25lp064\",      0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0017609d, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"issi is25lp128d\",     0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018609d, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"issi is25wp128d\",     0x03, 0xeb, 0x02, 0xd8, 0xc7, 0x0018709d, 0x100, 0x10000, 0x1000000),\n\tFLASH_ID(\"issi is25lp256d\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019609d, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"issi is25wp256d\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x0019709d, 0x100, 0x10000, 0x2000000),\n\tFLASH_ID(\"issi is25lp512m\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a609d, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"issi is25wp512m\",     0x13, 0xec, 0x12, 0xdc, 0xc7, 0x001a709d, 0x100, 0x10000, 0x4000000),\n\tFLASH_ID(\"xtx xt25f02e\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0012400b, 0x100, 0x10000, 0x40000),\n\tFLASH_ID(\"xtx xt25f04d\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0013400b, 0x100, 0x10000, 0x80000),\n\tFLASH_ID(\"xtx xt25f08b\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0014400b, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"xtx xt25f16b\",        0x03, 0x00, 0x02, 0xd8, 0xc7, 0x0015400b, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"xtx xt25f32b\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016400b, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"xtx xt25f64b\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017400b, 0x100, 0x10000, 0x400000),\n\tFLASH_ID(\"xtx xt25f128b\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018400b, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"xtx xt25q08d\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0014600b, 0x100, 0x10000, 0x100000),\n\tFLASH_ID(\"xtx xt25q16b\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0015600b, 0x100, 0x10000, 0x200000),\n\tFLASH_ID(\"xtx xt25q32b\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0016600b, 0x100, 0x10000, 0x400000), /* exists ? */\n\tFLASH_ID(\"xtx xt25q64b\",        0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0017600b, 0x100, 0x10000, 0x800000),\n\tFLASH_ID(\"xtx xt25q128b\",       0x03, 0x0b, 0x02, 0xd8, 0xc7, 0x0018600b, 0x100, 0x10000, 0x1000000),\n\n\t/* FRAM, no erase commands, no write page or sectors */\n\tFRAM_ID(\"fu mb85rs16n\",         0x03, 0,    0x02, 0x00010104, 0x800),\n\tFRAM_ID(\"fu mb85rs32v\",         0x03, 0,    0x02, 0x00010204, 0x1000), /* exists ? */\n\tFRAM_ID(\"fu mb85rs64v\",         0x03, 0,    0x02, 0x00020304, 0x2000),\n\tFRAM_ID(\"fu mb85rs128b\",        0x03, 0,    0x02, 0x00090404, 0x4000),\n\tFRAM_ID(\"fu mb85rs256b\",        0x03, 0,    0x02, 0x00090504, 0x8000),\n\tFRAM_ID(\"fu mb85rs512t\",        0x03, 0,    0x02, 0x00032604, 0x10000),\n\tFRAM_ID(\"fu mb85rs1mt\",         0x03, 0,    0x02, 0x00032704, 0x20000),\n\tFRAM_ID(\"fu mb85rs2mta\",        0x03, 0,    0x02, 0x00034804, 0x40000),\n\tFRAM_ID(\"cyp fm25v01a\",         0x03, 0,    0x02, 0x060821c2, 0x4000),\n\tFRAM_ID(\"cyp fm25v02\",          0x03, 0,    0x02, 0x060022c2, 0x8000),\n\tFRAM_ID(\"cyp fm25v02a\",         0x03, 0,    0x02, 0x060822c2, 0x8000),\n\tFRAM_ID(\"cyp fm25v05\",          0x03, 0,    0x02, 0x060023c2, 0x10000),\n\tFRAM_ID(\"cyp fm25v10\",          0x03, 0,    0x02, 0x060024c2, 0x20000),\n\tFRAM_ID(\"cyp fm25v20a\",         0x03, 0,    0x02, 0x060825c2, 0x40000),\n\tFRAM_ID(\"cyp fm25v40\",          0x03, 0,    0x02, 0x064026c2, 0x80000),\n\tFRAM_ID(\"cyp cy15b102qn\",       0x03, 0,    0x02, 0x06002ac2, 0x40000),\n\tFRAM_ID(\"cyp cy15v102qn\",       0x03, 0,    0x02, 0x06042ac2, 0x40000),\n\tFRAM_ID(\"cyp cy15b104qi\",       0x03, 0,    0x02, 0x06012dc2, 0x80000),\n\tFRAM_ID(\"cyp cy15b104qi\",       0x03, 0,    0x02, 0x06a12dc2, 0x80000),\n\tFRAM_ID(\"cyp cy15v104qi\",       0x03, 0,    0x02, 0x06052dc2, 0x80000),\n\tFRAM_ID(\"cyp cy15v104qi\",       0x03, 0,    0x02, 0x06a52dc2, 0x80000),\n\tFRAM_ID(\"cyp cy15b104qn\",       0x03, 0,    0x02, 0x06402cc2, 0x80000),\n\tFRAM_ID(\"cyp cy15b108qi\",       0x03, 0,    0x02, 0x06012fc2, 0x100000),\n\tFRAM_ID(\"cyp cy15b108qi\",       0x03, 0,    0x02, 0x06a12fc2, 0x100000),\n\tFRAM_ID(\"cyp cy15v108qi\",       0x03, 0,    0x02, 0x06052fc2, 0x100000),\n\tFRAM_ID(\"cyp cy15v108qi\",       0x03, 0,    0x02, 0x06a52fc2, 0x100000),\n\tFRAM_ID(\"cyp cy15b108qn\",       0x03, 0,    0x02, 0x06012ec2, 0x100000),\n\tFRAM_ID(\"cyp cy15b108qn\",       0x03, 0,    0x02, 0x06032ec2, 0x100000),\n\tFRAM_ID(\"cyp cy15b108qn\",       0x03, 0,    0x02, 0x06a12ec2, 0x100000),\n\tFRAM_ID(\"cyp cy15v108qn\",       0x03, 0,    0x02, 0x06052ec2, 0x100000),\n\tFRAM_ID(\"cyp cy15v108qn\",       0x03, 0,    0x02, 0x06072ec2, 0x100000),\n\tFRAM_ID(\"cyp cy15v108qn\",       0x03, 0,    0x02, 0x06a52ec2, 0x100000),\n\n\tFLASH_ID(NULL,                  0,    0,    0,    0,    0,    0,          0,     0,       0)\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/spi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018-2019 by Andreas Bolsch                             *\n *   andreas.bolsch@mni.thm.de                                             *\n *                                                                         *\n *   Copyright (C) 2012 by George Harris                                   *\n *   george@luminairecoffee.com                                            *\n *                                                                         *\n *   Copyright (C) 2010 by Antonio Borneo                                  *\n *   borneo.antonio@gmail.com                                              *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_SPI_H\n#define OPENOCD_FLASH_NOR_SPI_H\n\n#ifndef __ASSEMBLER__\n\n/* data structure to maintain flash ids from different vendors */\nstruct flash_device {\n\tconst char *name;\n\tuint8_t read_cmd;\n\tuint8_t qread_cmd;\n\tuint8_t pprog_cmd;\n\tuint8_t erase_cmd;\n\tuint8_t chip_erase_cmd;\n\tuint32_t device_id;\n\tuint32_t pagesize;\n\tuint32_t sectorsize;\n\tuint32_t size_in_bytes;\n};\n\n#define FLASH_ID(n, re, qr, pp, es, ces, id, psize, ssize, size) \\\n{\t                                \\\n\t.name = n,                      \\\n\t.read_cmd = re,                 \\\n\t.qread_cmd = qr,                \\\n\t.pprog_cmd = pp,                \\\n\t.erase_cmd = es,                \\\n\t.chip_erase_cmd = ces,          \\\n\t.device_id = id,                \\\n\t.pagesize = psize,              \\\n\t.sectorsize = ssize,            \\\n\t.size_in_bytes = size,          \\\n}\n\n#define FRAM_ID(n, re, qr, pp, id, size) \\\n{\t                                \\\n\t.name = n,                      \\\n\t.read_cmd = re,                 \\\n\t.qread_cmd = qr,                \\\n\t.pprog_cmd = pp,                \\\n\t.erase_cmd = 0x00,              \\\n\t.chip_erase_cmd = 0x00,         \\\n\t.device_id = id,                \\\n\t.pagesize = 0,                  \\\n\t.sectorsize = 0,                \\\n\t.size_in_bytes = size,          \\\n}\n\nextern const struct flash_device flash_devices[];\n\n#endif\n\n/* fields in SPI flash status register */\n#define\tSPIFLASH_BSY\t\t0\n#define SPIFLASH_BSY_BIT\t(1 << SPIFLASH_BSY)\t/* WIP Bit of SPI SR */\n#define\tSPIFLASH_WE\t\t\t1\n#define SPIFLASH_WE_BIT\t\t(1 << SPIFLASH_WE)\t/* WEL Bit of SPI SR */\n\n/* SPI Flash Commands */\n#define SPIFLASH_READ_ID\t\t0x9F /* Read Flash Identification */\n#define SPIFLASH_READ_MID\t\t0xAF /* Read Flash Identification, multi-io */\n#define SPIFLASH_READ_STATUS\t0x05 /* Read Status Register */\n#define SPIFLASH_WRITE_ENABLE\t0x06 /* Write Enable */\n#define SPIFLASH_PAGE_PROGRAM\t0x02 /* Page Program */\n#define SPIFLASH_FAST_READ\t\t0x0B /* Fast Read */\n#define SPIFLASH_READ\t\t\t0x03 /* Normal Read */\n#define SPIFLASH_MASS_ERASE\t\t0xC7 /* Mass Erase */\n#define SPIFLASH_READ_SFDP\t\t0x5A /* Read Serial Flash Discoverable Parameters */\n\n#define SPIFLASH_DEF_PAGESIZE\t256  /* default for non-page-oriented devices (FRAMs) */\n\n#endif /* OPENOCD_FLASH_NOR_SPI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stellaris.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n/***************************************************************************\n* STELLARIS flash is tested on LM3S811, LM3S6965, LM3s3748, more.\n***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"imp.h\"\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/armv7m.h>\n\n#define DID0_VER(did0) ((did0 >> 28)&0x07)\n\n/* STELLARIS control registers */\n#define SCB_BASE\t0x400FE000\n#define DID0\t\t0x000\n#define DID1\t\t0x004\n#define DC0\t\t\t0x008\n#define DC1\t\t\t0x010\n#define DC2\t\t\t0x014\n#define DC3\t\t\t0x018\n#define DC4\t\t\t0x01C\n\n#define RIS\t\t\t0x050\n#define RCC\t\t\t0x060\n#define PLLCFG\t\t0x064\n#define RCC2\t\t0x070\n#define NVMSTAT\t\t0x1a0\n\n/* \"legacy\" flash memory protection registers (64KB max) */\n#define FMPRE\t\t0x130\n#define FMPPE\t\t0x134\n\n/* new flash memory protection registers (for more than 64KB) */\n#define FMPRE0\t\t0x200\t\t/* PRE1 = PRE0 + 4, etc */\n#define FMPPE0\t\t0x400\t\t/* PPE1 = PPE0 + 4, etc */\n\n#define USECRL\t\t0x140\n\n#define FLASH_CONTROL_BASE\t0x400FD000\n#define FLASH_FMA\t(FLASH_CONTROL_BASE | 0x000)\n#define FLASH_FMD\t(FLASH_CONTROL_BASE | 0x004)\n#define FLASH_FMC\t(FLASH_CONTROL_BASE | 0x008)\n#define FLASH_CRIS\t(FLASH_CONTROL_BASE | 0x00C)\n#define FLASH_CIM\t(FLASH_CONTROL_BASE | 0x010)\n#define FLASH_MISC\t(FLASH_CONTROL_BASE | 0x014)\n#define FLASH_FSIZE\t(FLASH_CONTROL_BASE | 0xFC0)\n#define FLASH_SSIZE\t(FLASH_CONTROL_BASE | 0xFC4)\n\n#define AMISC\t1\n#define PMISC\t2\n\n#define AMASK\t1\n#define PMASK\t2\n\n/* Flash Controller Command bits */\n#define FMC_WRKEY\t(0xA442 << 16)\n#define FMC_COMT\t(1 << 3)\n#define FMC_MERASE\t(1 << 2)\n#define FMC_ERASE\t(1 << 1)\n#define FMC_WRITE\t(1 << 0)\n\n/* STELLARIS constants */\n\n/* values to write in FMA to commit write-\"once\" values */\n#define FLASH_FMA_PRE(x)\t(2 * (x))\t/* for FMPPREx */\n#define FLASH_FMA_PPE(x)\t(2 * (x) + 1)\t/* for FMPPPEx */\n\nstatic void stellaris_read_clock_info(struct flash_bank *bank);\nstatic int stellaris_mass_erase(struct flash_bank *bank);\n\nstruct stellaris_flash_bank {\n\t/* chip id register */\n\tuint32_t did0;\n\tuint32_t did1;\n\tuint32_t dc0;\n\tuint32_t dc1;\n\tuint32_t fsize;\n\tuint32_t ssize;\n\n\tconst char *target_name;\n\tuint8_t target_class;\n\n\tuint32_t sramsiz;\n\t/* flash geometry */\n\tuint32_t num_pages;\n\tuint32_t pagesize;\n\n\t/* main clock status */\n\tuint32_t rcc;\n\tuint32_t rcc2;\n\tuint8_t  mck_valid;\n\tuint8_t  xtal_mask;\n\tuint32_t iosc_freq;\n\tuint32_t mck_freq;\n\tconst char *iosc_desc;\n\tconst char *mck_desc;\n};\n\n/* Autogenerated by contrib/gen-stellaris-part-header.pl */\n/* From Stellaris Firmware Development Package revision 9453 */\nstatic const struct {\n\tuint8_t class;\n\tuint8_t partno;\n\tconst char *partname;\n} stellaris_parts[] = {\n\t{0x00, 0x01, \"LM3S101\"},\n\t{0x00, 0x02, \"LM3S102\"},\n\t{0x01, 0xBF, \"LM3S1110\"},\n\t{0x01, 0xC3, \"LM3S1133\"},\n\t{0x01, 0xC5, \"LM3S1138\"},\n\t{0x01, 0xC1, \"LM3S1150\"},\n\t{0x01, 0xC4, \"LM3S1162\"},\n\t{0x01, 0xC2, \"LM3S1165\"},\n\t{0x01, 0xEC, \"LM3S1166\"},\n\t{0x01, 0xC6, \"LM3S1332\"},\n\t{0x01, 0xBC, \"LM3S1435\"},\n\t{0x01, 0xBA, \"LM3S1439\"},\n\t{0x01, 0xBB, \"LM3S1512\"},\n\t{0x01, 0xC7, \"LM3S1538\"},\n\t{0x01, 0xDB, \"LM3S1601\"},\n\t{0x03, 0x06, \"LM3S1607\"},\n\t{0x01, 0xDA, \"LM3S1608\"},\n\t{0x01, 0xC0, \"LM3S1620\"},\n\t{0x04, 0xCD, \"LM3S1621\"},\n\t{0x03, 0x03, \"LM3S1625\"},\n\t{0x03, 0x04, \"LM3S1626\"},\n\t{0x03, 0x05, \"LM3S1627\"},\n\t{0x01, 0xB3, \"LM3S1635\"},\n\t{0x01, 0xEB, \"LM3S1636\"},\n\t{0x01, 0xBD, \"LM3S1637\"},\n\t{0x04, 0xB1, \"LM3S1651\"},\n\t{0x01, 0xB9, \"LM3S1751\"},\n\t{0x03, 0x10, \"LM3S1776\"},\n\t{0x04, 0x16, \"LM3S1811\"},\n\t{0x04, 0x3D, \"LM3S1816\"},\n\t{0x01, 0xB4, \"LM3S1850\"},\n\t{0x01, 0xDD, \"LM3S1911\"},\n\t{0x01, 0xDC, \"LM3S1918\"},\n\t{0x01, 0xB7, \"LM3S1937\"},\n\t{0x01, 0xBE, \"LM3S1958\"},\n\t{0x01, 0xB5, \"LM3S1960\"},\n\t{0x01, 0xB8, \"LM3S1968\"},\n\t{0x01, 0xEA, \"LM3S1969\"},\n\t{0x04, 0xCE, \"LM3S1B21\"},\n\t{0x06, 0xCA, \"LM3S1C21\"},\n\t{0x06, 0xCB, \"LM3S1C26\"},\n\t{0x06, 0x98, \"LM3S1C58\"},\n\t{0x06, 0xB0, \"LM3S1D21\"},\n\t{0x06, 0xCC, \"LM3S1D26\"},\n\t{0x06, 0x1D, \"LM3S1F11\"},\n\t{0x06, 0x1B, \"LM3S1F16\"},\n\t{0x06, 0xAF, \"LM3S1G21\"},\n\t{0x06, 0x95, \"LM3S1G58\"},\n\t{0x06, 0x1E, \"LM3S1H11\"},\n\t{0x06, 0x1C, \"LM3S1H16\"},\n\t{0x04, 0x0F, \"LM3S1J11\"},\n\t{0x04, 0x3C, \"LM3S1J16\"},\n\t{0x04, 0x0E, \"LM3S1N11\"},\n\t{0x04, 0x3B, \"LM3S1N16\"},\n\t{0x04, 0xB2, \"LM3S1P51\"},\n\t{0x04, 0x9E, \"LM3S1R21\"},\n\t{0x04, 0xC9, \"LM3S1R26\"},\n\t{0x04, 0x30, \"LM3S1W16\"},\n\t{0x04, 0x2F, \"LM3S1Z16\"},\n\t{0x01, 0x51, \"LM3S2110\"},\n\t{0x01, 0x84, \"LM3S2139\"},\n\t{0x03, 0x39, \"LM3S2276\"},\n\t{0x01, 0xA2, \"LM3S2410\"},\n\t{0x01, 0x59, \"LM3S2412\"},\n\t{0x01, 0x56, \"LM3S2432\"},\n\t{0x01, 0x5A, \"LM3S2533\"},\n\t{0x01, 0xE1, \"LM3S2601\"},\n\t{0x01, 0xE0, \"LM3S2608\"},\n\t{0x03, 0x33, \"LM3S2616\"},\n\t{0x01, 0x57, \"LM3S2620\"},\n\t{0x01, 0x85, \"LM3S2637\"},\n\t{0x01, 0x53, \"LM3S2651\"},\n\t{0x03, 0x80, \"LM3S2671\"},\n\t{0x03, 0x50, \"LM3S2678\"},\n\t{0x01, 0xA4, \"LM3S2730\"},\n\t{0x01, 0x52, \"LM3S2739\"},\n\t{0x03, 0x3A, \"LM3S2776\"},\n\t{0x04, 0x6D, \"LM3S2793\"},\n\t{0x01, 0xE3, \"LM3S2911\"},\n\t{0x01, 0xE2, \"LM3S2918\"},\n\t{0x01, 0xED, \"LM3S2919\"},\n\t{0x01, 0x54, \"LM3S2939\"},\n\t{0x01, 0x8F, \"LM3S2948\"},\n\t{0x01, 0x58, \"LM3S2950\"},\n\t{0x01, 0x55, \"LM3S2965\"},\n\t{0x04, 0x6C, \"LM3S2B93\"},\n\t{0x06, 0x94, \"LM3S2D93\"},\n\t{0x06, 0x93, \"LM3S2U93\"},\n\t{0x00, 0x19, \"LM3S300\"},\n\t{0x00, 0x11, \"LM3S301\"},\n\t{0x00, 0x1A, \"LM3S308\"},\n\t{0x00, 0x12, \"LM3S310\"},\n\t{0x00, 0x13, \"LM3S315\"},\n\t{0x00, 0x14, \"LM3S316\"},\n\t{0x00, 0x17, \"LM3S317\"},\n\t{0x00, 0x15, \"LM3S328\"},\n\t{0x03, 0x08, \"LM3S3634\"},\n\t{0x03, 0x43, \"LM3S3651\"},\n\t{0x04, 0xC8, \"LM3S3654\"},\n\t{0x03, 0x44, \"LM3S3739\"},\n\t{0x03, 0x49, \"LM3S3748\"},\n\t{0x03, 0x45, \"LM3S3749\"},\n\t{0x04, 0x42, \"LM3S3826\"},\n\t{0x04, 0x41, \"LM3S3J26\"},\n\t{0x04, 0x40, \"LM3S3N26\"},\n\t{0x04, 0x3F, \"LM3S3W26\"},\n\t{0x04, 0x3E, \"LM3S3Z26\"},\n\t{0x03, 0x81, \"LM3S5632\"},\n\t{0x04, 0x0C, \"LM3S5651\"},\n\t{0x03, 0x8A, \"LM3S5652\"},\n\t{0x04, 0x4D, \"LM3S5656\"},\n\t{0x03, 0x91, \"LM3S5662\"},\n\t{0x03, 0x96, \"LM3S5732\"},\n\t{0x03, 0x97, \"LM3S5737\"},\n\t{0x03, 0xA0, \"LM3S5739\"},\n\t{0x03, 0x99, \"LM3S5747\"},\n\t{0x03, 0xA7, \"LM3S5749\"},\n\t{0x03, 0x9A, \"LM3S5752\"},\n\t{0x03, 0x9C, \"LM3S5762\"},\n\t{0x04, 0x69, \"LM3S5791\"},\n\t{0x04, 0x0B, \"LM3S5951\"},\n\t{0x04, 0x4E, \"LM3S5956\"},\n\t{0x04, 0x68, \"LM3S5B91\"},\n\t{0x06, 0x2E, \"LM3S5C31\"},\n\t{0x06, 0x2C, \"LM3S5C36\"},\n\t{0x06, 0x5E, \"LM3S5C51\"},\n\t{0x06, 0x5B, \"LM3S5C56\"},\n\t{0x06, 0x5F, \"LM3S5D51\"},\n\t{0x06, 0x5C, \"LM3S5D56\"},\n\t{0x06, 0x87, \"LM3S5D91\"},\n\t{0x06, 0x2D, \"LM3S5G31\"},\n\t{0x06, 0x1F, \"LM3S5G36\"},\n\t{0x06, 0x5D, \"LM3S5G51\"},\n\t{0x06, 0x4F, \"LM3S5G56\"},\n\t{0x04, 0x09, \"LM3S5K31\"},\n\t{0x04, 0x4A, \"LM3S5K36\"},\n\t{0x04, 0x0A, \"LM3S5P31\"},\n\t{0x04, 0x48, \"LM3S5P36\"},\n\t{0x04, 0xB6, \"LM3S5P3B\"},\n\t{0x04, 0x0D, \"LM3S5P51\"},\n\t{0x04, 0x4C, \"LM3S5P56\"},\n\t{0x04, 0x07, \"LM3S5R31\"},\n\t{0x04, 0x4B, \"LM3S5R36\"},\n\t{0x04, 0x47, \"LM3S5T36\"},\n\t{0x06, 0x7F, \"LM3S5U91\"},\n\t{0x04, 0x46, \"LM3S5Y36\"},\n\t{0x00, 0x2A, \"LM3S600\"},\n\t{0x00, 0x21, \"LM3S601\"},\n\t{0x00, 0x2B, \"LM3S608\"},\n\t{0x00, 0x22, \"LM3S610\"},\n\t{0x01, 0xA1, \"LM3S6100\"},\n\t{0x00, 0x23, \"LM3S611\"},\n\t{0x01, 0x74, \"LM3S6110\"},\n\t{0x00, 0x24, \"LM3S612\"},\n\t{0x00, 0x25, \"LM3S613\"},\n\t{0x00, 0x26, \"LM3S615\"},\n\t{0x00, 0x28, \"LM3S617\"},\n\t{0x00, 0x29, \"LM3S618\"},\n\t{0x00, 0x27, \"LM3S628\"},\n\t{0x01, 0xA5, \"LM3S6420\"},\n\t{0x01, 0x82, \"LM3S6422\"},\n\t{0x01, 0x75, \"LM3S6432\"},\n\t{0x01, 0x76, \"LM3S6537\"},\n\t{0x01, 0x71, \"LM3S6610\"},\n\t{0x01, 0xE7, \"LM3S6611\"},\n\t{0x01, 0xE6, \"LM3S6618\"},\n\t{0x01, 0x83, \"LM3S6633\"},\n\t{0x01, 0x8B, \"LM3S6637\"},\n\t{0x01, 0xA3, \"LM3S6730\"},\n\t{0x01, 0x77, \"LM3S6753\"},\n\t{0x01, 0xE9, \"LM3S6911\"},\n\t{0x01, 0xE8, \"LM3S6918\"},\n\t{0x01, 0x89, \"LM3S6938\"},\n\t{0x01, 0x72, \"LM3S6950\"},\n\t{0x01, 0x78, \"LM3S6952\"},\n\t{0x01, 0x73, \"LM3S6965\"},\n\t{0x06, 0xAA, \"LM3S6C11\"},\n\t{0x06, 0xAC, \"LM3S6C65\"},\n\t{0x06, 0x9F, \"LM3S6G11\"},\n\t{0x06, 0xAB, \"LM3S6G65\"},\n\t{0x00, 0x38, \"LM3S800\"},\n\t{0x00, 0x31, \"LM3S801\"},\n\t{0x00, 0x39, \"LM3S808\"},\n\t{0x00, 0x32, \"LM3S811\"},\n\t{0x00, 0x33, \"LM3S812\"},\n\t{0x00, 0x34, \"LM3S815\"},\n\t{0x00, 0x36, \"LM3S817\"},\n\t{0x00, 0x37, \"LM3S818\"},\n\t{0x00, 0x35, \"LM3S828\"},\n\t{0x01, 0x64, \"LM3S8530\"},\n\t{0x01, 0x8E, \"LM3S8538\"},\n\t{0x01, 0x61, \"LM3S8630\"},\n\t{0x01, 0x63, \"LM3S8730\"},\n\t{0x01, 0x8D, \"LM3S8733\"},\n\t{0x01, 0x86, \"LM3S8738\"},\n\t{0x01, 0x65, \"LM3S8930\"},\n\t{0x01, 0x8C, \"LM3S8933\"},\n\t{0x01, 0x88, \"LM3S8938\"},\n\t{0x01, 0xA6, \"LM3S8962\"},\n\t{0x01, 0x62, \"LM3S8970\"},\n\t{0x01, 0xD7, \"LM3S8971\"},\n\t{0x06, 0xAE, \"LM3S8C62\"},\n\t{0x06, 0xAD, \"LM3S8G62\"},\n\t{0x04, 0xCF, \"LM3S9781\"},\n\t{0x04, 0x67, \"LM3S9790\"},\n\t{0x04, 0x6B, \"LM3S9792\"},\n\t{0x04, 0x2D, \"LM3S9971\"},\n\t{0x04, 0x20, \"LM3S9997\"},\n\t{0x04, 0xD0, \"LM3S9B81\"},\n\t{0x04, 0x66, \"LM3S9B90\"},\n\t{0x04, 0x6A, \"LM3S9B92\"},\n\t{0x04, 0x6E, \"LM3S9B95\"},\n\t{0x04, 0x6F, \"LM3S9B96\"},\n\t{0x04, 0x1D, \"LM3S9BN2\"},\n\t{0x04, 0x1E, \"LM3S9BN5\"},\n\t{0x04, 0x1F, \"LM3S9BN6\"},\n\t{0x06, 0x70, \"LM3S9C97\"},\n\t{0x06, 0xA9, \"LM3S9D81\"},\n\t{0x06, 0x7E, \"LM3S9D90\"},\n\t{0x06, 0x92, \"LM3S9D92\"},\n\t{0x06, 0x9D, \"LM3S9D96\"},\n\t{0x06, 0x7B, \"LM3S9DN5\"},\n\t{0x06, 0x7C, \"LM3S9DN6\"},\n\t{0x06, 0x60, \"LM3S9G97\"},\n\t{0x06, 0x79, \"LM3S9GN5\"},\n\t{0x04, 0x1B, \"LM3S9L71\"},\n\t{0x04, 0x18, \"LM3S9L97\"},\n\t{0x06, 0xA8, \"LM3S9U81\"},\n\t{0x06, 0x7D, \"LM3S9U90\"},\n\t{0x06, 0x90, \"LM3S9U92\"},\n\t{0x06, 0x9B, \"LM3S9U96\"},\n\t{0x05, 0x01, \"LM4F120B2QR/TM4C1233C3PM\"},\n\t{0x05, 0x02, \"LM4F120C4QR/TM4C1233D5PM\"},\n\t{0x05, 0x03, \"LM4F120E5QR/TM4C1233E6PM\"},\n\t{0x05, 0x04, \"LM4F120H5QR/TM4C1233H6PM\"},\n\t{0x05, 0x08, \"LM4F121B2QR/TM4C1232C3PM\"},\n\t{0x05, 0x09, \"LM4F121C4QR/TM4C1232D5PM\"},\n\t{0x05, 0x0A, \"LM4F121E5QR/TM4C1232E6PM\"},\n\t{0x05, 0x0B, \"LM4F121H5QR/TM4C1232H6PM\"},\n\t{0x05, 0x10, \"LM4F110E5QR/TM4C1231E6PM\"},\n\t{0x05, 0x11, \"LM4F110H5QR/TM4C1231H6PM\"},\n\t{0x05, 0x18, \"LM4F110B2QR/TM4C1231C3PM\"},\n\t{0x05, 0x19, \"LM4F110C4QR/TM4C1231D5PM\"},\n\t{0x05, 0x20, \"LM4F111E5QR/TM4C1230E6PM\"},\n\t{0x05, 0x21, \"LM4F111H5QR/TM4C1230H6PM\"},\n\t{0x05, 0x22, \"LM4F111B2QR/TM4C1230C3PM\"},\n\t{0x05, 0x23, \"LM4F111C4QR/TM4C1230D5PM\"},\n\t{0x05, 0x30, \"LM4F112E5QC/TM4C1231E6PZ\"},\n\t{0x05, 0x31, \"LM4F112H5QC/TM4C1231H6PZ\"},\n\t{0x05, 0x35, \"LM4F112H5QD/TM4C1231H6PGE\"},\n\t{0x05, 0x36, \"LM4F112C4QC/TM4C1231D5PZ\"},\n\t{0x05, 0x40, \"LM4F130E5QR/TM4C1237E6PM\"},\n\t{0x05, 0x41, \"LM4F130H5QR/TM4C1237H6PM\"},\n\t{0x05, 0x48, \"LM4F130C4QR/TM4C1237D5PM\"},\n\t{0x05, 0x50, \"LM4F131E5QR/TM4C1236E6PM\"},\n\t{0x05, 0x51, \"LM4F131H5QR/TM4C1236H6PM\"},\n\t{0x05, 0x52, \"LM4F131C4QR/TM4C1236D5PM\"},\n\t{0x05, 0x60, \"LM4F132E5QC/TM4C1237E6PZ\"},\n\t{0x05, 0x61, \"LM4F132H5QC/TM4C1237H6PZ\"},\n\t{0x05, 0x65, \"LM4F132H5QD/TM4C1237H6PGE\"},\n\t{0x05, 0x66, \"LM4F132C4QC/TM4C1237D5PZ\"},\n\t{0x05, 0x70, \"LM4F210E5QR/TM4C123BE6PM\"},\n\t{0x05, 0x73, \"LM4F210H5QR/TM4C123BH6PM\"},\n\t{0x05, 0x80, \"LM4F211E5QR/TM4C123AE6PM\"},\n\t{0x05, 0x83, \"LM4F211H5QR/TM4C123AH6PM\"},\n\t{0x05, 0xA0, \"LM4F230E5QR/TM4C123GE6PM\"},\n\t{0x05, 0xA1, \"LM4F230H5QR/TM4C123GH6PM\"},\n\t{0x05, 0xB0, \"LM4F231E5QR/TM4C123FE6PM\"},\n\t{0x05, 0xB1, \"LM4F231H5QR/TM4C123FH6PM\"},\n\t{0x05, 0xC0, \"LM4F232E5QC/TM4C123GE6PZ\"},\n\t{0x05, 0xC1, \"LM4F232H5QC/TM4C123GH6PZ\"},\n\t{0x05, 0xC3, \"LM4F212E5QC/TM4C123BE6PZ\"},\n\t{0x05, 0xC4, \"LM4F212H5QC/TM4C123BH6PZ\"},\n\t{0x05, 0xC5, \"LM4F232H5QD/TM4C123GH6PGE\"},\n\t{0x05, 0xC6, \"LM4F212H5QD/TM4C123BH6PGE\"},\n\t{0x05, 0xD0, \"LM4F122C4QC/TM4C1233D5PZ\"},\n\t{0x05, 0xD1, \"LM4F122E5QC/TM4C1233E6PZ\"},\n\t{0x05, 0xD2, \"LM4F122H5QC/TM4C1233H6PZ\"},\n\t{0x05, 0xD6, \"LM4F122H5QD/TM4C1233H6PGE\"},\n\t{0x05, 0xE1, \"LM4FSXLH5BB\"},\n\t{0x05, 0xE3, \"LM4F232H5BB/TM4C123GH6ZRB\"},\n\t{0x05, 0xE4, \"LM4FS99H5BB\"},\n\t{0x05, 0xE5, \"LM4FS1AH5BB\"},\n\t{0x05, 0xE9, \"LM4F212H5BB/TM4C123BH6ZRB\"},\n\t{0x05, 0xEA, \"LM4FS1GH5BB\"},\n\t{0x05, 0xF0, \"TM4C123GH6ZXR\"},\n\t{0x0A, 0x19, \"TM4C1290NCPDT\"},\n\t{0x0A, 0x1B, \"TM4C1290NCZAD\"},\n\t{0x0A, 0x1C, \"TM4C1292NCPDT\"},\n\t{0x0A, 0x1E, \"TM4C1292NCZAD\"},\n\t{0x0A, 0x1F, \"TM4C1294NCPDT\"},\n\t{0x0A, 0x21, \"TM4C1294NCZAD\"},\n\t{0x0A, 0x22, \"TM4C1297NCZAD\"},\n\t{0x0A, 0x23, \"TM4C1299NCZAD\"},\n\t{0x0A, 0x24, \"TM4C129CNCPDT\"},\n\t{0x0A, 0x26, \"TM4C129CNCZAD\"},\n\t{0x0A, 0x27, \"TM4C129DNCPDT\"},\n\t{0x0A, 0x29, \"TM4C129DNCZAD\"},\n\t{0x0A, 0x2D, \"TM4C129ENCPDT\"},\n\t{0x0A, 0x2F, \"TM4C129ENCZAD\"},\n\t{0x0A, 0x30, \"TM4C129LNCZAD\"},\n\t{0x0A, 0x32, \"TM4C129XNCZAD\"},\n\t{0x0A, 0x34, \"TM4C1294KCPDT\"},\n\t{0x0A, 0x35, \"TM4C129EKCPDT\"},\n\t{0x0A, 0x36, \"TM4C1299KCZAD\"},\n\t{0x0A, 0x37, \"TM4C129XKCZAD\"},\n\t{0xFF, 0x00, \"Unknown Part\"}\n};\n\nstatic const char * const stellaris_classname[] = {\n\t\"Sandstorm\",\n\t\"Fury\",\n\t\"Unknown\",\n\t\"DustDevil\",\n\t\"Tempest\",\n\t\"Blizzard/TM4C123x\",\n\t\"Firestorm\",\n\t\"\",\n\t\"\",\n\t\"\",\n\t\"Snowflake\",\n};\n\n/***************************************************************************\n*\topenocd command interface                                              *\n***************************************************************************/\n\n/* flash_bank stellaris <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(stellaris_flash_bank_command)\n{\n\tstruct stellaris_flash_bank *stellaris_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstellaris_info = calloc(sizeof(struct stellaris_flash_bank), 1);\n\tbank->base = 0x0;\n\tbank->driver_priv = stellaris_info;\n\n\tstellaris_info->target_name = \"Unknown target\";\n\n\t/* part wasn't probed for info yet */\n\tstellaris_info->did1 = 0;\n\n\t/* TODO Specify the main crystal speed in kHz using an optional\n\t * argument; ditto, the speed of an external oscillator used\n\t * instead of a crystal.  Avoid programming flash using IOSC.\n\t */\n\treturn ERROR_OK;\n}\n\nstatic int get_stellaris_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\n\tif (stellaris_info->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* Read main and master clock frequency register */\n\tstellaris_read_clock_info(bank);\n\n\tcommand_print_sameline(cmd,\n\t\t\t\"\\nTI/LMI Stellaris information: Chip is \"\n\t\t\t\"class %i (%s) %s rev %c%i\\n\",\n\t\t\tstellaris_info->target_class,\n\t\t\tstellaris_classname[stellaris_info->target_class],\n\t\t\tstellaris_info->target_name,\n\t\t\t(int)('A' + ((stellaris_info->did0 >> 8) & 0xFF)),\n\t\t\t(int)((stellaris_info->did0) & 0xFF));\n\n\tcommand_print_sameline(cmd,\n\t\t\t\"did1: 0x%8.8\" PRIx32 \", arch: 0x%4.4\" PRIx32\n\t\t\t\", eproc: %s, ramsize: %\" PRIu32 \"k, flashsize: %\" PRIu32 \"k\\n\",\n\t\t\tstellaris_info->did1,\n\t\t\tstellaris_info->did1,\n\t\t\t\"ARMv7M\",\n\t\t\tstellaris_info->sramsiz,\n\t\t\t(uint32_t)(stellaris_info->num_pages * stellaris_info->pagesize / 1024));\n\n\tcommand_print_sameline(cmd,\n\t\t\t\"master clock: %ikHz%s, \"\n\t\t\t\"rcc is 0x%\" PRIx32 \", rcc2 is 0x%\" PRIx32 \", \"\n\t\t\t\"pagesize: %\" PRIu32 \", pages: %\" PRIu32,\n\t\t\t(int)(stellaris_info->mck_freq / 1000),\n\t\t\tstellaris_info->mck_desc,\n\t\t\tstellaris_info->rcc,\n\t\t\tstellaris_info->rcc2,\n\t\t\tstellaris_info->pagesize,\n\t\t\tstellaris_info->num_pages);\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************\n*\tchip identification and status                                         *\n***************************************************************************/\n\n/* Set the flash timing register to match current clocking */\nstatic void stellaris_set_flash_timing(struct flash_bank *bank)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t usecrl = (stellaris_info->mck_freq/1000000ul-1);\n\n\t/* only valid for Sandstorm and Fury class devices */\n\tif (stellaris_info->target_class > 1)\n\t\treturn;\n\n\tLOG_DEBUG(\"usecrl = %i\", (int)(usecrl));\n\ttarget_write_u32(target, SCB_BASE | USECRL, usecrl);\n}\n\nstatic const unsigned rcc_xtal[32] = {\n\t[0x00] = 1000000,\t\t/* no pll */\n\t[0x01] = 1843200,\t\t/* no pll */\n\t[0x02] = 2000000,\t\t/* no pll */\n\t[0x03] = 2457600,\t\t/* no pll */\n\n\t[0x04] = 3579545,\n\t[0x05] = 3686400,\n\t[0x06] = 4000000,\t\t/* usb */\n\t[0x07] = 4096000,\n\n\t[0x08] = 4915200,\n\t[0x09] = 5000000,\t\t/* usb */\n\t[0x0a] = 5120000,\n\t[0x0b] = 6000000,\t\t/* (reset) usb */\n\n\t[0x0c] = 6144000,\n\t[0x0d] = 7372800,\n\t[0x0e] = 8000000,\t\t/* usb */\n\t[0x0f] = 8192000,\n\n\t/* parts before DustDevil use just 4 bits for xtal spec */\n\n\t[0x10] = 10000000,\t\t/* usb */\n\t[0x11] = 12000000,\t\t/* usb */\n\t[0x12] = 12288000,\n\t[0x13] = 13560000,\n\n\t[0x14] = 14318180,\n\t[0x15] = 16000000,\t\t/* usb */\n\t[0x16] = 16384000,\n};\n\n/** Read clock configuration and set stellaris_info->usec_clocks. */\nstatic void stellaris_read_clock_info(struct flash_bank *bank)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t rcc, rcc2, pllcfg, sysdiv, usesysdiv, bypass, oscsrc;\n\tunsigned xtal;\n\tunsigned long mainfreq;\n\n\ttarget_read_u32(target, SCB_BASE | RCC, &rcc);\n\tLOG_DEBUG(\"Stellaris RCC %\" PRIx32 \"\", rcc);\n\n\ttarget_read_u32(target, SCB_BASE | RCC2, &rcc2);\n\tLOG_DEBUG(\"Stellaris RCC2 %\" PRIx32 \"\", rcc);\n\n\ttarget_read_u32(target, SCB_BASE | PLLCFG, &pllcfg);\n\tLOG_DEBUG(\"Stellaris PLLCFG %\" PRIx32 \"\", pllcfg);\n\n\tstellaris_info->rcc = rcc;\n\tstellaris_info->rcc2 = rcc2;\n\n\tsysdiv = (rcc >> 23) & 0xF;\n\tusesysdiv = (rcc >> 22) & 0x1;\n\tbypass = (rcc >> 11) & 0x1;\n\toscsrc = (rcc >> 4) & 0x3;\n\txtal = (rcc >> 6) & stellaris_info->xtal_mask;\n\n\t/* NOTE: post-Sandstorm parts have RCC2 which may override\n\t * parts of RCC ... with more sysdiv options, option for\n\t * 32768 Hz mainfreq, PLL controls.  On Sandstorm it reads\n\t * as zero, so the \"use RCC2\" flag is always clear.\n\t */\n\tif (rcc2 & (1 << 31)) {\n\t\tsysdiv = (rcc2 >> 23) & 0x3F;\n\t\tbypass = (rcc2 >> 11) & 0x1;\n\t\toscsrc = (rcc2 >> 4) & 0x7;\n\n\t\t/* FIXME Tempest parts have an additional lsb for\n\t\t * fractional sysdiv (200 MHz / 2.5 == 80 MHz)\n\t\t */\n\t}\n\n\tstellaris_info->mck_desc = \"\";\n\n\tswitch (oscsrc) {\n\t\tcase 0:\t\t\t\t/* MOSC */\n\t\t\tmainfreq = rcc_xtal[xtal];\n\t\t\tbreak;\n\t\tcase 1:\t\t\t\t/* IOSC */\n\t\t\tmainfreq = stellaris_info->iosc_freq;\n\t\t\tstellaris_info->mck_desc = stellaris_info->iosc_desc;\n\t\t\tbreak;\n\t\tcase 2:\t\t\t\t/* IOSC/4 */\n\t\t\tmainfreq = stellaris_info->iosc_freq / 4;\n\t\t\tstellaris_info->mck_desc = stellaris_info->iosc_desc;\n\t\t\tbreak;\n\t\tcase 3:\t\t\t\t/* lowspeed */\n\t\t\t/* Sandstorm doesn't have this 30K +/- 30% osc */\n\t\t\tmainfreq = 30000;\n\t\t\tstellaris_info->mck_desc = \" (±30%)\";\n\t\t\tbreak;\n\t\tcase 8:\t\t\t\t/* hibernation osc */\n\t\t\t/* not all parts support hibernation */\n\t\t\tmainfreq = 32768;\n\t\t\tbreak;\n\n\t\tdefault: /* NOTREACHED */\n\t\t\tmainfreq = 0;\n\t\t\tbreak;\n\t}\n\n\t/* PLL is used if it's not bypassed; its output is 200 MHz\n\t * even when it runs at 400 MHz (adds divide-by-two stage).\n\t */\n\tif (!bypass)\n\t\tmainfreq = 200000000;\n\n\tif (usesysdiv)\n\t\tstellaris_info->mck_freq = mainfreq/(1 + sysdiv);\n\telse\n\t\tstellaris_info->mck_freq = mainfreq;\n}\n\n/* Read device id register, main clock frequency register and fill in driver info structure */\nstatic int stellaris_read_part_info(struct flash_bank *bank)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t did0, did1, ver, fam;\n\tint i;\n\n\t/* Read and parse chip identification register */\n\ttarget_read_u32(target, SCB_BASE | DID0, &did0);\n\ttarget_read_u32(target, SCB_BASE | DID1, &did1);\n\ttarget_read_u32(target, SCB_BASE | DC0, &stellaris_info->dc0);\n\ttarget_read_u32(target, SCB_BASE | DC1, &stellaris_info->dc1);\n\tLOG_DEBUG(\"did0 0x%\" PRIx32 \", did1 0x%\" PRIx32 \", dc0 0x%\" PRIx32 \", dc1 0x%\" PRIx32 \"\",\n\t\t  did0, did1, stellaris_info->dc0, stellaris_info->dc1);\n\n\tver = DID0_VER(did0);\n\tif ((ver != 0) && (ver != 1)) {\n\t\tLOG_WARNING(\"Unknown did0 version, cannot identify target\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (did1 == 0) {\n\t\tLOG_WARNING(\"Cannot identify target as a Stellaris\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tver = did1 >> 28;\n\tfam = (did1 >> 24) & 0xF;\n\tif (((ver != 0) && (ver != 1)) || (fam != 0)) {\n\t\tLOG_WARNING(\"Unknown did1 version/family.\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* For Sandstorm, Fury, DustDevil:  current data sheets say IOSC\n\t * is 12 MHz, but some older parts have 15 MHz.  A few data sheets\n\t * even give _both_ numbers!  We'll use current numbers; IOSC is\n\t * always approximate.\n\t *\n\t * For Tempest:  IOSC is calibrated, 16 MHz\n\t * For Blizzard:  IOSC is calibrated, 16 MHz\n\t * For Firestorm:  IOSC is calibrated, 16 MHz\n\t */\n\tstellaris_info->iosc_freq = 12000000;\n\tstellaris_info->iosc_desc = \" (±30%)\";\n\tstellaris_info->xtal_mask = 0x0f;\n\n\t/* get device class */\n\tif (DID0_VER(did0) > 0) {\n\t\tstellaris_info->target_class = (did0 >> 16) & 0xFF;\n\t} else {\n\t\t/* Sandstorm class */\n\t\tstellaris_info->target_class = 0;\n\t}\n\n\tswitch (stellaris_info->target_class) {\n\t\tcase 0:\t\t\t\t/* Sandstorm */\n\t\t\t/*\n\t\t\t * Current (2009-August) parts seem to be rev C2 and use 12 MHz.\n\t\t\t * Parts before rev C0 used 15 MHz; some C0 parts use 15 MHz\n\t\t\t * (LM3S618), but some other C0 parts are 12 MHz (LM3S811).\n\t\t\t */\n\t\t\tif (((did0 >> 8) & 0xff) < 2) {\n\t\t\t\tstellaris_info->iosc_freq = 15000000;\n\t\t\t\tstellaris_info->iosc_desc = \" (±50%)\";\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 1:\t\t\t/* Fury */\n\t\t\tbreak;\n\n\t\tcase 4:\t\t\t/* Tempest */\n\t\tcase 5:\t\t\t/* Blizzard */\n\t\tcase 6:\t\t\t/* Firestorm */\n\t\tcase 0xa:\t\t/* Snowflake */\n\t\t\tstellaris_info->iosc_freq = 16000000;\t/* +/- 1% */\n\t\t\tstellaris_info->iosc_desc = \" (±1%)\";\n\t\t\t/* FALL THROUGH */\n\n\t\tcase 3:\t\t\t/* DustDevil */\n\t\t\tstellaris_info->xtal_mask = 0x1f;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_WARNING(\"Unknown did0 class\");\n\t}\n\n\tfor (i = 0; stellaris_parts[i].partno; i++) {\n\t\tif ((stellaris_parts[i].partno == ((did1 >> 16) & 0xFF)) &&\n\t\t\t\t(stellaris_parts[i].class == stellaris_info->target_class))\n\t\t\tbreak;\n\t}\n\n\tstellaris_info->target_name = stellaris_parts[i].partname;\n\n\tstellaris_info->did0 = did0;\n\tstellaris_info->did1 = did1;\n\n\tif (stellaris_info->target_class == 5) { /* Blizzard */\n\t\ttarget_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize);\n\t\ttarget_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize);\n\n\t\tstellaris_info->num_pages = 2 * (1 + (stellaris_info->fsize & 0xFFFF));\n\t\tstellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4;\n\t\tstellaris_info->pagesize = 1024;\n\t} else if (stellaris_info->target_class == 0xa) { /* Snowflake */\n\t\ttarget_read_u32(target, FLASH_FSIZE, &stellaris_info->fsize);\n\t\ttarget_read_u32(target, FLASH_SSIZE, &stellaris_info->ssize);\n\n\t\tstellaris_info->pagesize = (1 << ((stellaris_info->fsize >> 16) & 7)) * 1024;\n\t\tstellaris_info->num_pages = 2048 * (1 + (stellaris_info->fsize & 0xFFFF)) /\n\t\t\tstellaris_info->pagesize;\n\t\tstellaris_info->sramsiz = (1 + (stellaris_info->ssize & 0xFFFF)) / 4;\n\t} else {\n\t\tstellaris_info->num_pages = 2 * (1 + (stellaris_info->dc0 & 0xFFFF));\n\t\tstellaris_info->sramsiz = (1 + ((stellaris_info->dc0 >> 16) & 0xFFFF)) / 4;\n\t\tstellaris_info->pagesize = 1024;\n\t}\n\n\t/* REVISIT for at least Tempest parts, read NVMSTAT.FWB too.\n\t * That exposes a 32-word Flash Write Buffer ... enabling\n\t * writes of more than one word at a time.\n\t */\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************\n*\tflash operations                                                       *\n***************************************************************************/\n\nstatic int stellaris_protect_check(struct flash_bank *bank)\n{\n\tstruct stellaris_flash_bank *stellaris = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t flash_sizek = stellaris->pagesize / 1024 *\n\t\tstellaris->num_pages;\n\tuint32_t fmppe_addr;\n\tint status = ERROR_OK;\n\n\tif (stellaris->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = -1;\n\n\t/* Read each Flash Memory Protection Program Enable (FMPPE) register\n\t * to report any pages that we can't write.  Ignore the Read Enable\n\t * register (FMPRE).\n\t */\n\n\tif (stellaris->target_class >= 0x0a || flash_sizek > 64)\n\t\tfmppe_addr = SCB_BASE | FMPPE0;\n\telse\n\t\tfmppe_addr = SCB_BASE | FMPPE;\n\n\tunsigned int page = 0, lockbitnum, lockbitcnt = flash_sizek / 2;\n\tunsigned int bits_per_page = stellaris->pagesize / 2048;\n\t/* Every lock bit always corresponds to a 2k region */\n\tfor (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) {\n\t\tuint32_t fmppe;\n\n\t\ttarget_read_u32(target, fmppe_addr, &fmppe);\n\t\tfor (unsigned int i = 0; i < 32 && lockbitnum + i < lockbitcnt; i++) {\n\t\t\tbool protect = !(fmppe & (1 << i));\n\t\t\tif (bits_per_page) {\n\t\t\t\tbank->sectors[page++].is_protected = protect;\n\t\t\t\ti += bits_per_page - 1;\n\t\t\t} else { /* 1024k pages, every lockbit covers 2 pages */\n\t\t\t\tbank->sectors[page++].is_protected = protect;\n\t\t\t\tbank->sectors[page++].is_protected = protect;\n\t\t\t}\n\t\t}\n\t\tfmppe_addr += 4;\n\t}\n\n\treturn status;\n}\n\nstatic int stellaris_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint32_t flash_fmc, flash_cris;\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (stellaris_info->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif ((last < first) || (last >= stellaris_info->num_pages))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\n\tif ((first == 0) && (last == (stellaris_info->num_pages - 1)))\n\t\treturn stellaris_mass_erase(bank);\n\n\t/* Refresh flash controller timing */\n\tstellaris_read_clock_info(bank);\n\tstellaris_set_flash_timing(bank);\n\n\t/* Clear and disable flash programming interrupts */\n\ttarget_write_u32(target, FLASH_CIM, 0);\n\ttarget_write_u32(target, FLASH_MISC, PMISC | AMISC);\n\n\t/* REVISIT this clobbers state set by any halted firmware ...\n\t * it might want to process those IRQs.\n\t */\n\n\tfor (unsigned int banknr = first; banknr <= last; banknr++) {\n\t\t/* Address is first word in page */\n\t\ttarget_write_u32(target, FLASH_FMA, banknr * stellaris_info->pagesize);\n\t\t/* Write erase command */\n\t\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_ERASE);\n\t\t/* Wait until erase complete */\n\t\tdo {\n\t\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t\t} while (flash_fmc & FMC_ERASE);\n\n\t\t/* Check access violations */\n\t\ttarget_read_u32(target, FLASH_CRIS, &flash_cris);\n\t\tif (flash_cris & (AMASK)) {\n\t\t\tLOG_WARNING(\"Error erasing flash page %i,  flash_cris 0x%\" PRIx32 \"\",\n\t\t\t\t\tbanknr, flash_cris);\n\t\t\ttarget_write_u32(target, FLASH_CRIS, 0);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stellaris_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tstruct stellaris_flash_bank *stellaris = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t flash_fmc, flash_cris;\n\tunsigned int bits_per_page = stellaris->pagesize / 2048;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!set) {\n\t\tLOG_ERROR(\"Hardware doesn't support page-level unprotect. \"\n\t\t\t\"Try the 'recover' command.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (stellaris->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (stellaris->target_class == 0x03 &&\n\t    !((stellaris->did0 >> 8) & 0xFF) &&\n\t    !((stellaris->did0) & 0xFF)) {\n\t\tLOG_ERROR(\"DustDevil A0 parts can't be unprotected, see errata; refusing to proceed\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (!bits_per_page && (first % 2 || !(last % 2))) {\n\t\tLOG_ERROR(\"Can't protect unaligned pages\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\t/* Refresh flash controller timing */\n\tstellaris_read_clock_info(bank);\n\tstellaris_set_flash_timing(bank);\n\n\t/* Clear and disable flash programming interrupts */\n\ttarget_write_u32(target, FLASH_CIM, 0);\n\ttarget_write_u32(target, FLASH_MISC, PMISC | AMISC);\n\n\tuint32_t flash_sizek = stellaris->pagesize / 1024 *\n\t\tstellaris->num_pages;\n\tuint32_t fmppe_addr;\n\n\tif (stellaris->target_class >= 0x0a || flash_sizek > 64)\n\t\tfmppe_addr = SCB_BASE | FMPPE0;\n\telse\n\t\tfmppe_addr = SCB_BASE | FMPPE;\n\n\tunsigned int page = 0;\n\tunsigned int lockbitnum, lockbitcnt = flash_sizek / 2;\n\t/* Every lock bit always corresponds to a 2k region */\n\tfor (lockbitnum = 0; lockbitnum < lockbitcnt; lockbitnum += 32) {\n\t\tuint32_t fmppe;\n\n\t\ttarget_read_u32(target, fmppe_addr, &fmppe);\n\t\tfor (unsigned int i = 0;\n\t\t     i < 32 && lockbitnum + i < lockbitcnt;\n\t\t     i++) {\n\t\t\tif (page >= first && page <= last)\n\t\t\t\tfmppe &= ~(1 << i);\n\n\t\t\tif (bits_per_page) {\n\t\t\t\tif (!((i + 1) % bits_per_page))\n\t\t\t\t\tpage++;\n\t\t\t} else { /* 1024k pages, every lockbit covers 2 pages */\n\t\t\t\tpage += 2;\n\t\t\t}\n\t\t}\n\t\ttarget_write_u32(target, fmppe_addr, fmppe);\n\n\t\t/* Commit FMPPE* */\n\t\ttarget_write_u32(target, FLASH_FMA, 1 + lockbitnum / 16);\n\t\t/* Write commit command */\n\t\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_COMT);\n\n\t\t/* Wait until commit complete */\n\t\tdo {\n\t\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t\t} while (flash_fmc & FMC_COMT);\n\n\t\t/* Check access violations */\n\t\ttarget_read_u32(target, FLASH_CRIS, &flash_cris);\n\t\tif (flash_cris & (AMASK)) {\n\t\t\tLOG_WARNING(\"Error setting flash page protection,  flash_cris 0x%\" PRIx32 \"\", flash_cris);\n\t\t\ttarget_write_u32(target, FLASH_CRIS, 0);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\tfmppe_addr += 4;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* see contrib/loaders/flash/stellaris.s for src */\n\nstatic const uint8_t stellaris_write_code[] = {\n\t\t\t\t\t\t\t\t/* write: */\n\t0xDF, 0xF8, 0x40, 0x40,\t\t/* ldr\t\tr4, pFLASH_CTRL_BASE */\n\t0xDF, 0xF8, 0x40, 0x50,\t\t/* ldr\t\tr5, FLASHWRITECMD */\n\t\t\t\t\t\t\t\t/* wait_fifo: */\n\t0xD0, 0xF8, 0x00, 0x80,\t\t/* ldr\t\tr8, [r0, #0] */\n\t0xB8, 0xF1, 0x00, 0x0F,\t\t/* cmp\t\tr8, #0 */\n\t0x17, 0xD0,\t\t\t\t\t/* beq\t\texit */\n\t0x47, 0x68,\t\t\t\t\t/* ldr\t\tr7, [r0, #4] */\n\t0x47, 0x45,\t\t\t\t\t/* cmp\t\tr7, r8 */\n\t0xF7, 0xD0,\t\t\t\t\t/* beq\t\twait_fifo */\n\t\t\t\t\t\t\t\t/* mainloop: */\n\t0x22, 0x60,\t\t\t\t\t/* str\t\tr2, [r4, #0] */\n\t0x02, 0xF1, 0x04, 0x02,\t\t/* add\t\tr2, r2, #4 */\n\t0x57, 0xF8, 0x04, 0x8B,\t\t/* ldr\t\tr8, [r7], #4 */\n\t0xC4, 0xF8, 0x04, 0x80,\t\t/* str\t\tr8, [r4, #4] */\n\t0xA5, 0x60,\t\t\t\t\t/* str\t\tr5, [r4, #8] */\n\t\t\t\t\t\t\t\t/* busy: */\n\t0xD4, 0xF8, 0x08, 0x80,\t\t/* ldr\t\tr8, [r4, #8] */\n\t0x18, 0xF0, 0x01, 0x0F,\t\t/* tst\t\tr8, #1 */\n\t0xFA, 0xD1,\t\t\t\t\t/* bne\t\tbusy */\n\t0x8F, 0x42,\t\t\t\t\t/* cmp\t\tr7, r1 */\n\t0x28, 0xBF,\t\t\t\t\t/* it\t\tcs */\n\t0x00, 0xF1, 0x08, 0x07,\t\t/* addcs\tr7, r0, #8 */\n\t0x47, 0x60,\t\t\t\t\t/* str\t\tr7, [r0, #4] */\n\t0x01, 0x3B,\t\t\t\t\t/* subs\t\tr3, r3, #1 */\n\t0x03, 0xB1,\t\t\t\t\t/* cbz\t\tr3, exit */\n\t0xE2, 0xE7,\t\t\t\t\t/* b\t\twait_fifo */\n\t\t\t\t\t\t\t\t/* exit: */\n\t0x00, 0xBE,\t\t\t\t\t/* bkpt\t\t#0 */\n\n\t/* pFLASH_CTRL_BASE: */\n\t0x00, 0xD0, 0x0F, 0x40,\t/* .word\t0x400FD000 */\n\t/* FLASHWRITECMD: */\n\t0x01, 0x00, 0x42, 0xA4\t/* .word\t0xA4420001 */\n};\nstatic int stellaris_write_block(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t wcount)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *source;\n\tstruct working_area *write_algorithm;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\t/* power of two, and multiple of word size */\n\tstatic const unsigned buf_min = 128;\n\n\t/* for small buffers it's faster not to download an algorithm */\n\tif (wcount * 4 < buf_min)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tLOG_DEBUG(\"(bank=%p buffer=%p offset=%08\" PRIx32 \" wcount=%08\" PRIx32 \"\",\n\t\t\tbank, buffer, offset, wcount);\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(stellaris_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no working area for block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* plus a buffer big enough for this data */\n\tif (wcount * 4 < buffer_size)\n\t\tbuffer_size = wcount * 4;\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= buf_min) {\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tLOG_DEBUG(\"retry target_alloc_working_area(%s, size=%u)\",\n\t\t\t\ttarget_name(target), (unsigned) buffer_size);\n\t}\n\n\ttarget_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(stellaris_write_code),\n\t\t\tstellaris_write_code);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, wcount);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, wcount, 4,\n\t\t\t0, NULL,\n\t\t\t4, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED)\n\t\tLOG_ERROR(\"error %d executing stellaris flash write algorithm\", retval);\n\n\ttarget_free_working_area(target, write_algorithm);\n\ttarget_free_working_area(target, source);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn retval;\n}\n\nstatic int stellaris_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t address = offset;\n\tuint32_t flash_cris, flash_fmc;\n\tuint32_t words_remaining = (count / 4);\n\tuint32_t bytes_remaining = (count & 0x00000003);\n\tuint32_t bytes_written = 0;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"(bank=%p buffer=%p offset=%08\" PRIx32 \" count=%08\" PRIx32 \"\",\n\t\t\tbank, buffer, offset, count);\n\n\tif (stellaris_info->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\tif (offset & 0x3) {\n\t\tLOG_WARNING(\"offset size must be word aligned\");\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif (offset + count > bank->size)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\t/* Refresh flash controller timing */\n\tstellaris_read_clock_info(bank);\n\tstellaris_set_flash_timing(bank);\n\n\t/* Clear and disable flash programming interrupts */\n\ttarget_write_u32(target, FLASH_CIM, 0);\n\ttarget_write_u32(target, FLASH_MISC, PMISC | AMISC);\n\n\t/* REVISIT this clobbers state set by any halted firmware ...\n\t * it might want to process those IRQs.\n\t */\n\n\t/* multiple words to be programmed? */\n\tif (words_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = stellaris_write_block(bank, buffer, offset,\n\t\t\t\twords_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\tLOG_DEBUG(\"writing flash word-at-a-time\");\n\t\t\t} else if (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\t\t\t/* if an error occurred, we examine the reason, and quit */\n\t\t\t\ttarget_read_u32(target, FLASH_CRIS, &flash_cris);\n\n\t\t\t\tLOG_ERROR(\"flash writing failed with CRIS: 0x%\" PRIx32 \"\", flash_cris);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += words_remaining * 4;\n\t\t\taddress += words_remaining * 4;\n\t\t\twords_remaining = 0;\n\t\t}\n\t}\n\n\twhile (words_remaining > 0) {\n\t\tif (!(address & 0xff))\n\t\t\tLOG_DEBUG(\"0x%\" PRIx32 \"\", address);\n\n\t\t/* Program one word */\n\t\ttarget_write_u32(target, FLASH_FMA, address);\n\t\ttarget_write_buffer(target, FLASH_FMD, 4, buffer);\n\t\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);\n\t\t/* LOG_DEBUG(\"0x%x 0x%x 0x%x\",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */\n\t\t/* Wait until write complete */\n\t\tdo {\n\t\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t\t} while (flash_fmc & FMC_WRITE);\n\n\t\tbuffer += 4;\n\t\taddress += 4;\n\t\twords_remaining--;\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};\n\n\t\t/* copy the last remaining bytes into the write buffer */\n\t\tmemcpy(last_word, buffer+bytes_written, bytes_remaining);\n\n\t\tif (!(address & 0xff))\n\t\t\tLOG_DEBUG(\"0x%\" PRIx32 \"\", address);\n\n\t\t/* Program one word */\n\t\ttarget_write_u32(target, FLASH_FMA, address);\n\t\ttarget_write_buffer(target, FLASH_FMD, 4, last_word);\n\t\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_WRITE);\n\t\t/* LOG_DEBUG(\"0x%x 0x%x 0x%x\",address,buf_get_u32(buffer, 0, 32),FMC_WRKEY | FMC_WRITE); */\n\t\t/* Wait until write complete */\n\t\tdo {\n\t\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t\t} while (flash_fmc & FMC_WRITE);\n\t}\n\n\t/* Check access violations */\n\ttarget_read_u32(target, FLASH_CRIS, &flash_cris);\n\tif (flash_cris & (AMASK)) {\n\t\tLOG_DEBUG(\"flash_cris 0x%\" PRIx32 \"\", flash_cris);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stellaris_probe(struct flash_bank *bank)\n{\n\tstruct stellaris_flash_bank *stellaris_info = bank->driver_priv;\n\tint retval;\n\n\t/* If this is a stellaris chip, it has flash; probe() is just\n\t * to figure out how much is present.  Only do it once.\n\t */\n\tif (stellaris_info->did1 != 0)\n\t\treturn ERROR_OK;\n\n\t/* stellaris_read_part_info() already handled error checking and\n\t * reporting.  Note that it doesn't write, so we don't care about\n\t * whether the target is halted or not.\n\t */\n\tretval = stellaris_read_part_info(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfree(bank->sectors);\n\n\t/* provide this for the benefit of the NOR flash framework */\n\tbank->size = stellaris_info->num_pages * stellaris_info->pagesize;\n\tbank->num_sectors = stellaris_info->num_pages;\n\tbank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * stellaris_info->pagesize;\n\t\tbank->sectors[i].size = stellaris_info->pagesize;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\treturn retval;\n}\n\nstatic int stellaris_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = NULL;\n\tstruct stellaris_flash_bank *stellaris_info = NULL;\n\tuint32_t flash_fmc;\n\n\tstellaris_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (stellaris_info->did1 == 0)\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\n\t/* Refresh flash controller timing */\n\tstellaris_read_clock_info(bank);\n\tstellaris_set_flash_timing(bank);\n\n\t/* Clear and disable flash programming interrupts */\n\ttarget_write_u32(target, FLASH_CIM, 0);\n\ttarget_write_u32(target, FLASH_MISC, PMISC | AMISC);\n\n\t/* REVISIT this clobbers state set by any halted firmware ...\n\t * it might want to process those IRQs.\n\t */\n\n\ttarget_write_u32(target, FLASH_FMA, 0);\n\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);\n\t/* Wait until erase complete */\n\tdo {\n\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t} while (flash_fmc & FMC_MERASE);\n\n\t/* if device has > 128k, then second erase cycle is needed\n\t * this is only valid for older devices, but will not hurt */\n\tif (stellaris_info->num_pages * stellaris_info->pagesize > 0x20000) {\n\t\ttarget_write_u32(target, FLASH_FMA, 0x20000);\n\t\ttarget_write_u32(target, FLASH_FMC, FMC_WRKEY | FMC_MERASE);\n\t\t/* Wait until erase complete */\n\t\tdo {\n\t\t\ttarget_read_u32(target, FLASH_FMC, &flash_fmc);\n\t\t} while (flash_fmc & FMC_MERASE);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stellaris_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stellaris_mass_erase(bank) == ERROR_OK)\n\t\tcommand_print(CMD, \"stellaris mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"stellaris mass erase failed\");\n\n\treturn ERROR_OK;\n}\n\n/**\n * Perform the Stellaris \"Recovering a 'Locked' Device procedure.\n * This performs a mass erase and then restores all nonvolatile registers\n * (including USER_* registers and flash lock bits) to their defaults.\n * Accordingly, flash can be reprogrammed, and JTAG can be used.\n *\n * NOTE that DustDevil parts (at least rev A0 silicon) have errata which\n * can affect this operation if flash protection has been enabled.\n */\nCOMMAND_HANDLER(stellaris_handle_recover_command)\n{\n\tstruct flash_bank *bank;\n\tstruct arm *arm;\n\tint retval;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tbank = get_flash_bank_by_num_noprobe(0);\n\tif (!bank)\n\t\treturn ERROR_FAIL;\n\n\t/* REVISIT ... it may be worth sanity checking that the AP is\n\t * inactive before we start.  ARM documents that switching a DP's\n\t * mode while it's active can cause fault modes that need a power\n\t * cycle to recover.\n\t */\n\n\tJim_Eval_Named(CMD_CTX->interp, \"catch { hla_command \\\"debug unlock\\\" }\", NULL, 0);\n\tif (!strcmp(Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL), \"0\")) {\n\t\tretval = ERROR_OK;\n\t\tgoto user_action;\n\t}\n\n\t/* assert SRST */\n\tif (!(jtag_get_reset_config() & RESET_HAS_SRST)) {\n\t\tLOG_ERROR(\"Can't recover Stellaris flash without SRST\");\n\t\treturn ERROR_FAIL;\n\t}\n\tadapter_assert_reset();\n\n\tarm = target_to_arm(bank->target);\n\tfor (int i = 0; i < 5; i++) {\n\t\tretval = dap_to_swd(arm->dap);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tretval = dap_to_jtag(arm->dap);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\n\t/* de-assert SRST */\n\tadapter_deassert_reset();\n\tretval = jtag_execute_queue();\n\n\t/* wait 400+ msec ... OK, \"1+ second\" is simpler */\n\tusleep(1000);\n\nuser_action:\n\t/* USER INTERVENTION required for the power cycle\n\t * Restarting OpenOCD is likely needed because of mode switching.\n\t */\n\tLOG_INFO(\"USER ACTION:  \"\n\t\t\"power cycle Stellaris chip, then restart OpenOCD.\");\n\ndone:\n\treturn retval;\n}\n\nstatic const struct command_registration stellaris_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = stellaris_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"erase entire device\",\n\t},\n\t{\n\t\t.name = \"recover\",\n\t\t.handler = stellaris_handle_recover_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"recover (and erase) locked device\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration stellaris_command_handlers[] = {\n\t{\n\t\t.name = \"stellaris\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Stellaris flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stellaris_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stellaris_flash = {\n\t.name = \"stellaris\",\n\t.commands = stellaris_command_handlers,\n\t.flash_bank_command = stellaris_flash_bank_command,\n\t.erase = stellaris_erase,\n\t.protect = stellaris_protect,\n\t.write = stellaris_write,\n\t.read = default_flash_read,\n\t.probe = stellaris_probe,\n\t.auto_probe = stellaris_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stellaris_protect_check,\n\t.info = get_stellaris_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32f1x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/cortex_m.h>\n\n/* stm32x register locations */\n\n#define FLASH_REG_BASE_B0 0x40022000\n#define FLASH_REG_BASE_B1 0x40022040\n\n#define STM32_FLASH_ACR     0x00\n#define STM32_FLASH_KEYR    0x04\n#define STM32_FLASH_OPTKEYR 0x08\n#define STM32_FLASH_SR      0x0C\n#define STM32_FLASH_CR      0x10\n#define STM32_FLASH_AR      0x14\n#define STM32_FLASH_OBR     0x1C\n#define STM32_FLASH_WRPR    0x20\n\n/* TODO: Check if code using these really should be hard coded to bank 0.\n * There are valid cases, on dual flash devices the protection of the\n * second bank is done on the bank0 reg's. */\n#define STM32_FLASH_ACR_B0     0x40022000\n#define STM32_FLASH_KEYR_B0    0x40022004\n#define STM32_FLASH_OPTKEYR_B0 0x40022008\n#define STM32_FLASH_SR_B0      0x4002200C\n#define STM32_FLASH_CR_B0      0x40022010\n#define STM32_FLASH_AR_B0      0x40022014\n#define STM32_FLASH_OBR_B0     0x4002201C\n#define STM32_FLASH_WRPR_B0    0x40022020\n\n/* option byte location */\n\n#define STM32_OB_RDP\t\t0x1FFFF800\n#define STM32_OB_USER\t\t0x1FFFF802\n#define STM32_OB_DATA0\t\t0x1FFFF804\n#define STM32_OB_DATA1\t\t0x1FFFF806\n#define STM32_OB_WRP0\t\t0x1FFFF808\n#define STM32_OB_WRP1\t\t0x1FFFF80A\n#define STM32_OB_WRP2\t\t0x1FFFF80C\n#define STM32_OB_WRP3\t\t0x1FFFF80E\n\n/* FLASH_CR register bits */\n\n#define FLASH_PG\t\t\t(1 << 0)\n#define FLASH_PER\t\t\t(1 << 1)\n#define FLASH_MER\t\t\t(1 << 2)\n#define FLASH_OPTPG\t\t\t(1 << 4)\n#define FLASH_OPTER\t\t\t(1 << 5)\n#define FLASH_STRT\t\t\t(1 << 6)\n#define FLASH_LOCK\t\t\t(1 << 7)\n#define FLASH_OPTWRE\t\t(1 << 9)\n#define FLASH_OBL_LAUNCH\t(1 << 13)\t/* except stm32f1x series */\n\n/* FLASH_SR register bits */\n\n#define FLASH_BSY\t\t(1 << 0)\n#define FLASH_PGERR\t\t(1 << 2)\n#define FLASH_WRPRTERR\t(1 << 4)\n#define FLASH_EOP\t\t(1 << 5)\n\n/* STM32_FLASH_OBR bit definitions (reading) */\n\n#define OPT_ERROR\t\t0\n#define OPT_READOUT\t\t1\n#define OPT_RDWDGSW\t\t2\n#define OPT_RDRSTSTOP\t3\n#define OPT_RDRSTSTDBY\t4\n#define OPT_BFB2\t\t5\t/* dual flash bank only */\n\n/* register unlock keys */\n\n#define KEY1\t\t\t0x45670123\n#define KEY2\t\t\t0xCDEF89AB\n\n/* timeout values */\n\n#define FLASH_WRITE_TIMEOUT 10\n#define FLASH_ERASE_TIMEOUT 100\n\nstruct stm32x_options {\n\tuint8_t rdp;\n\tuint8_t user;\n\tuint16_t data;\n\tuint32_t protection;\n};\n\nstruct stm32x_flash_bank {\n\tstruct stm32x_options option_bytes;\n\tint ppage_size;\n\tbool probed;\n\n\tbool has_dual_banks;\n\t/* used to access dual flash bank stm32xl */\n\tbool can_load_options;\n\tuint32_t register_base;\n\tuint8_t default_rdp;\n\tint user_data_offset;\n\tint option_offset;\n\tuint32_t user_bank_size;\n};\n\nstatic int stm32x_mass_erase(struct flash_bank *bank);\nstatic int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t address, uint32_t hwords_count);\n\n/* flash bank stm32x <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)\n{\n\tstruct stm32x_flash_bank *stm32x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstm32x_info = malloc(sizeof(struct stm32x_flash_bank));\n\n\tbank->driver_priv = stm32x_info;\n\tstm32x_info->probed = false;\n\tstm32x_info->has_dual_banks = false;\n\tstm32x_info->can_load_options = false;\n\tstm32x_info->register_base = FLASH_REG_BASE_B0;\n\tstm32x_info->user_bank_size = bank->size;\n\n\t/* The flash write must be aligned to a halfword boundary */\n\tbank->write_start_alignment = bank->write_end_alignment = 2;\n\n\treturn ERROR_OK;\n}\n\nstatic inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\treturn reg + stm32x_info->register_base;\n}\n\nstatic inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\treturn target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status);\n}\n\nstatic int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* wait for busy to clear */\n\tfor (;;) {\n\t\tretval = stm32x_get_flash_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32 \"\", status);\n\t\tif ((status & FLASH_BSY) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FLASH_BUSY;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tif (status & FLASH_WRPRTERR) {\n\t\tLOG_ERROR(\"stm32x device protected\");\n\t\tretval = ERROR_FLASH_PROTECTED;\n\t}\n\n\tif (status & FLASH_PGERR) {\n\t\tLOG_ERROR(\"stm32x device programming failed / flash not erased\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* Clear but report errors */\n\tif (status & (FLASH_WRPRTERR | FLASH_PGERR)) {\n\t\t/* If this operation fails, we ignore it and report the original\n\t\t * retval\n\t\t */\n\t\ttarget_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR),\n\t\t\t\tFLASH_WRPRTERR | FLASH_PGERR);\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_check_operation_supported(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\t/* if we have a dual flash bank device then\n\t * we need to perform option byte stuff on bank0 only */\n\tif (stm32x_info->register_base != FLASH_REG_BASE_B0) {\n\t\tLOG_ERROR(\"Option byte operations must use bank 0\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_read_options(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t option_bytes;\n\tint retval;\n\n\t/* read user and read protection option bytes, user data option bytes */\n\tretval = target_read_u32(target, STM32_FLASH_OBR_B0, &option_bytes);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info->option_bytes.rdp = (option_bytes & (1 << OPT_READOUT)) ? 0 : stm32x_info->default_rdp;\n\tstm32x_info->option_bytes.user = (option_bytes >> stm32x_info->option_offset >> 2) & 0xff;\n\tstm32x_info->option_bytes.data = (option_bytes >> stm32x_info->user_data_offset) & 0xffff;\n\n\t/* read write protection option bytes */\n\tretval = target_read_u32(target, STM32_FLASH_WRPR_B0, &stm32x_info->option_bytes.protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_erase_options(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\t/* read current options */\n\tstm32x_read_options(bank);\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* unlock option flash registers */\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY1);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* erase option bytes */\n\tretval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTER | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\tretval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTER | FLASH_STRT | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tretval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* clear read protection option byte\n\t * this will also force a device unlock if set */\n\tstm32x_info->option_bytes.rdp = stm32x_info->default_rdp;\n\n\treturn ERROR_OK;\n\nflash_lock:\n\ttarget_write_u32(target, STM32_FLASH_CR_B0, FLASH_LOCK);\n\treturn retval;\n}\n\nstatic int stm32x_write_options(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tstruct target *target = bank->target;\n\n\tstm32x_info = bank->driver_priv;\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, STM32_FLASH_KEYR_B0, KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* unlock option flash registers */\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY1);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR_B0, KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* program option bytes */\n\tretval = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_OPTPG | FLASH_OPTWRE);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tuint8_t opt_bytes[16];\n\n\ttarget_buffer_set_u16(target, opt_bytes, stm32x_info->option_bytes.rdp);\n\ttarget_buffer_set_u16(target, opt_bytes + 2, stm32x_info->option_bytes.user);\n\ttarget_buffer_set_u16(target, opt_bytes + 4, stm32x_info->option_bytes.data & 0xff);\n\ttarget_buffer_set_u16(target, opt_bytes + 6, (stm32x_info->option_bytes.data >> 8) & 0xff);\n\ttarget_buffer_set_u16(target, opt_bytes + 8, stm32x_info->option_bytes.protection & 0xff);\n\ttarget_buffer_set_u16(target, opt_bytes + 10, (stm32x_info->option_bytes.protection >> 8) & 0xff);\n\ttarget_buffer_set_u16(target, opt_bytes + 12, (stm32x_info->option_bytes.protection >> 16) & 0xff);\n\ttarget_buffer_set_u16(target, opt_bytes + 14, (stm32x_info->option_bytes.protection >> 24) & 0xff);\n\n\t/* Block write is preferred in favour of operation with ancient ST-Link\n\t * firmwares without 16-bit memory access. See\n\t * 480: flash: stm32f1x: write option bytes using the loader\n\t * https://review.openocd.org/c/openocd/+/480\n\t */\n\tretval = stm32x_write_block(bank, opt_bytes, STM32_OB_RDP, sizeof(opt_bytes) / 2);\n\nflash_lock:\n\t{\n\t\tint retval2 = target_write_u32(target, STM32_FLASH_CR_B0, FLASH_LOCK);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = retval2;\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tuint32_t protection;\n\n\tint retval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* medium density - each bit refers to a 4 sector protection block\n\t * high density - each bit refers to a 2 sector protection block\n\t * bit 31 refers to all remaining sectors in a bank */\n\tretval = target_read_u32(target, STM32_FLASH_WRPR_B0, &protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_prot_blocks; i++)\n\t\tbank->prot_blocks[i].is_protected = (protection & (1 << i)) ? 0 : 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((first == 0) && (last == (bank->num_sectors - 1)))\n\t\treturn stm32x_mass_erase(bank);\n\n\t/* unlock flash registers */\n\tint retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PER);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\t\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_AR),\n\t\t\t\tbank->base + bank->sectors[i].offset);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\t\tretval = target_write_u32(target,\n\t\t\t\tstm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PER | FLASH_STRT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\n\t\tretval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\t}\n\nflash_lock:\n\t{\n\t\tint retval2 = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = retval2;\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint retval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_erase_options(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"stm32x failed to erase options\");\n\t\treturn retval;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tif (set)\n\t\t\tstm32x_info->option_bytes.protection &= ~(1 << i);\n\t\telse\n\t\t\tstm32x_info->option_bytes.protection |= (1 << i);\n\t}\n\n\treturn stm32x_write_options(bank);\n}\n\nstatic int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t address, uint32_t hwords_count)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval;\n\n\tstatic const uint8_t stm32x_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/stm32/stm32f1x.inc\"\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(stm32x_flash_write_code), stm32x_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* memory buffer */\n\tbuffer_size = target_get_working_area_avail(target);\n\tbuffer_size = MIN(hwords_count * 2 + 8, MAX(buffer_size, 256));\n\t/* Normally we allocate all available working area.\n\t * MIN shrinks buffer_size if the size of the written block is smaller.\n\t * MAX prevents using async algo if the available working area is smaller\n\t * than 256, the following allocation fails with\n\t * ERROR_TARGET_RESOURCE_NOT_AVAILABLE and slow flashing takes place.\n\t */\n\n\tretval = target_alloc_working_area(target, buffer_size, &source);\n\t/* Allocated size is always 32-bit word aligned */\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t/* target_alloc_working_area() may return ERROR_FAIL if area backup fails:\n\t\t * convert any error to ERROR_TARGET_RESOURCE_NOT_AVAILABLE\n\t\t */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tstruct reg_param reg_params[5];\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* flash base (in), status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* count (halfword-16bit) */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN_OUT);\t/* target address */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, stm32x_info->register_base);\n\tbuf_set_u32(reg_params[1].value, 0, 32, hwords_count);\n\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[4].value, 0, 32, address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tretval = target_run_flash_async_algorithm(target, buffer, hwords_count, 2,\n\t\t\t0, NULL,\n\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\t/* Actually we just need to check for programming errors\n\t\t * stm32x_wait_status_busy also reports error and clears status bits.\n\t\t *\n\t\t * Target algo returns flash status in r0 only if properly finished.\n\t\t * It is safer to re-read status register.\n\t\t */\n\t\tint retval2 = stm32x_wait_status_busy(bank, 5);\n\t\tif (retval2 != ERROR_OK)\n\t\t\tretval = retval2;\n\n\t\tLOG_ERROR(\"flash write failed just before address 0x%\"PRIx32,\n\t\t\t\tbuf_get_u32(reg_params[4].value, 0, 32));\n\t}\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\treturn retval;\n}\n\nstatic int stm32x_write_block_riscv(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t address, uint32_t hwords_count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tstatic const uint8_t gd32vf103_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/gd32vf103/gd32vf103.inc\"\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(gd32vf103_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tint retval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(gd32vf103_flash_write_code), gd32vf103_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* memory buffer */\n\tbuffer_size = target_get_working_area_avail(target);\n\tbuffer_size = MIN(hwords_count * 2, MAX(buffer_size, 256));\n\n\tretval = target_alloc_working_area(target, buffer_size, &source);\n\t/* Allocated size is always word aligned */\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t/* target_alloc_working_area() may return ERROR_FAIL if area backup fails:\n\t\t * convert any error to ERROR_TARGET_RESOURCE_NOT_AVAILABLE\n\t\t */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tstruct reg_param reg_params[4];\n\n\tinit_reg_param(&reg_params[0], \"a0\", 32, PARAM_OUT);\t/* poiner to FLASH_SR */\n\tinit_reg_param(&reg_params[1], \"a1\", 32, PARAM_OUT);\t/* count (halfword-16bit) */\n\tinit_reg_param(&reg_params[2], \"a2\", 32, PARAM_OUT);\t/* buffer start */\n\tinit_reg_param(&reg_params[3], \"a3\", 32, PARAM_IN_OUT);\t/* target address */\n\n\twhile (hwords_count > 0) {\n\t\tuint32_t thisrun_hwords = source->size / 2;\n\n\t\t/* Limit to the amount of data we actually want to write */\n\t\tif (thisrun_hwords > hwords_count)\n\t\t\tthisrun_hwords = hwords_count;\n\n\t\t/* Write data to buffer */\n\t\tretval = target_write_buffer(target, source->address,\n\t\t\t\t\tthisrun_hwords * 2, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, stm32x_get_flash_reg(bank, STM32_FLASH_SR));\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, thisrun_hwords);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, address);\n\n\t\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\twrite_algorithm->address + sizeof(gd32vf103_flash_write_code) - 4,\n\t\t\t\t10000, NULL);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to execute algorithm at 0x%\" TARGET_PRIxADDR \": %d\",\n\t\t\t\t\twrite_algorithm->address, retval);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Actually we just need to check for programming errors\n\t\t * stm32x_wait_status_busy also reports error and clears status bits\n\t\t */\n\t\tretval = stm32x_wait_status_busy(bank, 5);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"flash write failed at address 0x%\"PRIx32,\n\t\t\t\t\tbuf_get_u32(reg_params[3].value, 0, 32));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Update counters */\n\t\tbuffer += thisrun_hwords * 2;\n\t\taddress += thisrun_hwords * 2;\n\t\thwords_count -= thisrun_hwords;\n\t}\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\treturn retval;\n}\n\n/** Writes a block to flash either using target algorithm\n *  or use fallback, host controlled halfword-by-halfword access.\n *  Flash controller must be unlocked before this call.\n */\nstatic int stm32x_write_block(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t address, uint32_t hwords_count)\n{\n\tstruct target *target = bank->target;\n\n\t/* The flash write must be aligned to a halfword boundary.\n\t * The flash infrastructure ensures it, do just a security check\n\t */\n\tassert(address % 2 == 0);\n\n\tint retval;\n\tstruct arm *arm = target_to_arm(target);\n\tif (is_arm(arm)) {\n\t\t/* try using a block write - on ARM architecture or... */\n\t\tretval = stm32x_write_block_async(bank, buffer, address, hwords_count);\n\t} else {\n\t\t/* ... RISC-V architecture */\n\t\tretval = stm32x_write_block_riscv(bank, buffer, address, hwords_count);\n\t}\n\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t/* if block write failed (no sufficient working area),\n\t\t * we use normal (slow) single halfword accesses */\n\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\n\t\twhile (hwords_count > 0) {\n\t\t\tretval = target_write_memory(target, address, 2, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = stm32x_wait_status_busy(bank, 5);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\thwords_count--;\n\t\t\tbuffer += 2;\n\t\t\taddress += 2;\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The flash write must be aligned to a halfword boundary.\n\t * The flash infrastructure ensures it, do just a security check\n\t */\n\tassert(offset % 2 == 0);\n\tassert(count % 2 == 0);\n\n\tint retval, retval2;\n\n\t/* unlock flash registers */\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\t/* enable flash programming */\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_PG);\n\tif (retval != ERROR_OK)\n\t\tgoto reset_pg_and_lock;\n\n\t/* write to flash */\n\tretval = stm32x_write_block(bank, buffer, bank->base + offset, count / 2);\n\nreset_pg_and_lock:\n\tretval2 = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\n\treturn retval;\n}\n\nstruct stm32x_property_addr {\n\tuint32_t device_id;\n\tuint32_t flash_size;\n};\n\nstatic int stm32x_get_property_addr(struct target *target, struct stm32x_property_addr *addr)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tswitch (cortex_m_get_partno_safe(target)) {\n\tcase CORTEX_M0_PARTNO: /* STM32F0x devices */\n\t\taddr->device_id = 0x40015800;\n\t\taddr->flash_size = 0x1FFFF7CC;\n\t\treturn ERROR_OK;\n\tcase CORTEX_M3_PARTNO: /* STM32F1x devices */\n\t\taddr->device_id = 0xE0042000;\n\t\taddr->flash_size = 0x1FFFF7E0;\n\t\treturn ERROR_OK;\n\tcase CORTEX_M4_PARTNO: /* STM32F3x devices */\n\t\taddr->device_id = 0xE0042000;\n\t\taddr->flash_size = 0x1FFFF7CC;\n\t\treturn ERROR_OK;\n\tcase CORTEX_M23_PARTNO: /* GD32E23x devices */\n\t\taddr->device_id = 0x40015800;\n\t\taddr->flash_size = 0x1FFFF7E0;\n\t\treturn ERROR_OK;\n\tcase CORTEX_M_PARTNO_INVALID:\n\t\t/* Check for GD32VF103 with RISC-V CPU */\n\t\tif (strcmp(target_type_name(target), \"riscv\") == 0\n\t\t\t\t&& target_address_bits(target) == 32) {\n\t\t\t/* There is nothing like arm common_magic in riscv_info_t\n\t\t\t * check text name of target and if target is 32-bit\n\t\t\t */\n\t\t\taddr->device_id = 0xE0042000;\n\t\t\taddr->flash_size = 0x1FFFF7E0;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\t/* fallthrough */\n\tdefault:\n\t\tLOG_ERROR(\"Cannot identify target as a stm32x\");\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nstatic int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32x_property_addr addr;\n\n\tint retval = stm32x_get_property_addr(target, &addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_read_u32(target, addr.device_id, device_id);\n}\n\nstatic int stm32x_get_flash_size(struct flash_bank *bank, uint16_t *flash_size_in_kb)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32x_property_addr addr;\n\n\tint retval = stm32x_get_property_addr(target, &addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_read_u16(target, addr.flash_size, flash_size_in_kb);\n}\n\nstatic int stm32x_probe(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tuint16_t flash_size_in_kb;\n\tuint16_t max_flash_size_in_kb;\n\tuint32_t dbgmcu_idcode;\n\tint page_size;\n\tuint32_t base_address = 0x08000000;\n\n\tstm32x_info->probed = false;\n\tstm32x_info->register_base = FLASH_REG_BASE_B0;\n\tstm32x_info->user_data_offset = 10;\n\tstm32x_info->option_offset = 0;\n\n\t/* default factory read protection level 0 */\n\tstm32x_info->default_rdp = 0xA5;\n\n\t/* read stm32 device id register */\n\tint retval = stm32x_get_device_id(bank, &dbgmcu_idcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"device id = 0x%08\" PRIx32 \"\", dbgmcu_idcode);\n\n\tuint16_t device_id = dbgmcu_idcode & 0xfff;\n\tuint16_t rev_id = dbgmcu_idcode >> 16;\n\n\t/* set page size, protection granularity and max flash size depending on family */\n\tswitch (device_id) {\n\tcase 0x440: /* stm32f05x */\n\t\tpage_size = 1024;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 64;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x444: /* stm32f03x */\n\tcase 0x445: /* stm32f04x */\n\t\tpage_size = 1024;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 32;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x448: /* stm32f07x */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 128;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x442: /* stm32f09x */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 256;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x410: /* stm32f1x medium-density */\n\t\tpage_size = 1024;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 128;\n\t\t/* GigaDevice GD32F1x0 & GD32F3x0 & GD32E23x series devices\n\t\t   share DEV_ID with STM32F101/2/3 medium-density line,\n\t\t   however they use a REV_ID different from any STM32 device.\n\t\t   The main difference is another offset of user option bits\n\t\t   (like WDG_SW, nRST_STOP, nRST_STDBY) in option byte register\n\t\t   (FLASH_OBR/FMC_OBSTAT 0x4002201C).\n\t\t   This caused problems e.g. during flash block programming\n\t\t   because of unexpected active hardware watchog. */\n\t\tswitch (rev_id) {\n\t\tcase 0x1303: /* gd32f1x0 */\n\t\t\tstm32x_info->user_data_offset = 16;\n\t\t\tstm32x_info->option_offset = 6;\n\t\t\tmax_flash_size_in_kb = 64;\n\t\t\tstm32x_info->can_load_options = true;\n\t\t\tbreak;\n\t\tcase 0x1704: /* gd32f3x0 */\n\t\t\tstm32x_info->user_data_offset = 16;\n\t\t\tstm32x_info->option_offset = 6;\n\t\t\tstm32x_info->can_load_options = true;\n\t\t\tbreak;\n\t\tcase 0x1906: /* gd32vf103 */\n\t\t\tbreak;\n\t\tcase 0x1909: /* gd32e23x */\n\t\t\tstm32x_info->user_data_offset = 16;\n\t\t\tstm32x_info->option_offset = 6;\n\t\t\tmax_flash_size_in_kb = 64;\n\t\t\tstm32x_info->can_load_options = true;\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0x412: /* stm32f1x low-density */\n\t\tpage_size = 1024;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 32;\n\t\tbreak;\n\tcase 0x414: /* stm32f1x high-density */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 512;\n\t\tbreak;\n\tcase 0x418: /* stm32f1x connectivity */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 256;\n\t\tbreak;\n\tcase 0x430: /* stm32f1 XL-density (dual flash banks) */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 1024;\n\t\tstm32x_info->has_dual_banks = true;\n\t\tbreak;\n\tcase 0x420: /* stm32f100xx low- and medium-density value line */\n\t\tpage_size = 1024;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 128;\n\t\tbreak;\n\tcase 0x428: /* stm32f100xx high-density value line */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 4;\n\t\tmax_flash_size_in_kb = 512;\n\t\tbreak;\n\tcase 0x422: /* stm32f302/3xb/c */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 256;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x446: /* stm32f303xD/E */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 512;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x432: /* stm32f37x */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 256;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tcase 0x438: /* stm32f33x */\n\tcase 0x439: /* stm32f302x6/8 */\n\t\tpage_size = 2048;\n\t\tstm32x_info->ppage_size = 2;\n\t\tmax_flash_size_in_kb = 64;\n\t\tstm32x_info->user_data_offset = 16;\n\t\tstm32x_info->option_offset = 6;\n\t\tstm32x_info->default_rdp = 0xAA;\n\t\tstm32x_info->can_load_options = true;\n\t\tbreak;\n\tdefault:\n\t\tLOG_WARNING(\"Cannot identify target as a STM32 family.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* get flash size from target. */\n\tretval = stm32x_get_flash_size(bank, &flash_size_in_kb);\n\n\t/* failed reading flash size or flash size invalid (early silicon),\n\t * default to max target family */\n\tif (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {\n\t\tLOG_WARNING(\"STM32 flash size failed, probe inaccurate - assuming %dk flash\",\n\t\t\tmax_flash_size_in_kb);\n\t\tflash_size_in_kb = max_flash_size_in_kb;\n\t}\n\n\tif (stm32x_info->has_dual_banks) {\n\t\t/* split reported size into matching bank */\n\t\tif (bank->base != 0x08080000) {\n\t\t\t/* bank 0 will be fixed 512k */\n\t\t\tflash_size_in_kb = 512;\n\t\t} else {\n\t\t\tflash_size_in_kb -= 512;\n\t\t\t/* bank1 also uses a register offset */\n\t\t\tstm32x_info->register_base = FLASH_REG_BASE_B1;\n\t\t\tbase_address = 0x08080000;\n\t\t}\n\t}\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (stm32x_info->user_bank_size) {\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size\");\n\t\tflash_size_in_kb = stm32x_info->user_bank_size / 1024;\n\t}\n\n\tLOG_INFO(\"flash size = %d KiB\", flash_size_in_kb);\n\n\t/* did we assign flash size? */\n\tassert(flash_size_in_kb != 0xffff);\n\n\t/* calculate numbers of pages */\n\tint num_pages = flash_size_in_kb * 1024 / page_size;\n\n\t/* check that calculation result makes sense */\n\tassert(num_pages > 0);\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tfree(bank->prot_blocks);\n\tbank->prot_blocks = NULL;\n\n\tbank->base = base_address;\n\tbank->size = (num_pages * page_size);\n\n\tbank->num_sectors = num_pages;\n\tbank->sectors = alloc_block_array(0, page_size, num_pages);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\t/* calculate number of write protection blocks */\n\tint num_prot_blocks = num_pages / stm32x_info->ppage_size;\n\tif (num_prot_blocks > 32)\n\t\tnum_prot_blocks = 32;\n\n\tbank->num_prot_blocks = num_prot_blocks;\n\tbank->prot_blocks = alloc_block_array(0, stm32x_info->ppage_size * page_size, num_prot_blocks);\n\tif (!bank->prot_blocks)\n\t\treturn ERROR_FAIL;\n\n\tif (num_prot_blocks == 32)\n\t\tbank->prot_blocks[31].size = (num_pages - (31 * stm32x_info->ppage_size)) * page_size;\n\n\tstm32x_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_auto_probe(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tif (stm32x_info->probed)\n\t\treturn ERROR_OK;\n\treturn stm32x_probe(bank);\n}\n\n#if 0\nCOMMAND_HANDLER(stm32x_handle_part_id_command)\n{\n\treturn ERROR_OK;\n}\n#endif\n\nstatic const char *get_stm32f0_revision(uint16_t rev_id)\n{\n\tconst char *rev_str = NULL;\n\n\tswitch (rev_id) {\n\tcase 0x1000:\n\t\trev_str = \"1.0\";\n\t\tbreak;\n\tcase 0x2000:\n\t\trev_str = \"2.0\";\n\t\tbreak;\n\t}\n\treturn rev_str;\n}\n\nstatic int get_stm32x_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tuint32_t dbgmcu_idcode;\n\n\t/* read stm32 device id register */\n\tint retval = stm32x_get_device_id(bank, &dbgmcu_idcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint16_t device_id = dbgmcu_idcode & 0xfff;\n\tuint16_t rev_id = dbgmcu_idcode >> 16;\n\tconst char *device_str;\n\tconst char *rev_str = NULL;\n\n\tswitch (device_id) {\n\tcase 0x410:\n\t\tdevice_str = \"STM32F10x (Medium Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x0000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1303: /* gd32f1x0 */\n\t\t\tdevice_str = \"GD32F1x0\";\n\t\t\tbreak;\n\n\t\tcase 0x1704: /* gd32f3x0 */\n\t\t\tdevice_str = \"GD32F3x0\";\n\t\t\tbreak;\n\n\t\tcase 0x1906:\n\t\t\tdevice_str = \"GD32VF103\";\n\t\t\tbreak;\n\n\t\tcase 0x1909: /* gd32e23x */\n\t\t\tdevice_str = \"GD32E23x\";\n\t\t\tbreak;\n\n\t\tcase 0x2000:\n\t\t\trev_str = \"B\";\n\t\t\tbreak;\n\n\t\tcase 0x2001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x2003:\n\t\t\trev_str = \"Y\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x412:\n\t\tdevice_str = \"STM32F10x (Low Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x414:\n\t\tdevice_str = \"STM32F10x (High Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x1003:\n\t\t\trev_str = \"Y\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x418:\n\t\tdevice_str = \"STM32F10x (Connectivity)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x420:\n\t\tdevice_str = \"STM32F100 (Low/Medium Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x422:\n\t\tdevice_str = \"STM32F302xB/C\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x1003:\n\t\t\trev_str = \"Y\";\n\t\t\tbreak;\n\n\t\tcase 0x2000:\n\t\t\trev_str = \"B\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x428:\n\t\tdevice_str = \"STM32F100 (High Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x430:\n\t\tdevice_str = \"STM32F10x (XL Density)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x432:\n\t\tdevice_str = \"STM32F37x\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x2000:\n\t\t\trev_str = \"B\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x438:\n\t\tdevice_str = \"STM32F33x\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x439:\n\t\tdevice_str = \"STM32F302x6/8\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x444:\n\t\tdevice_str = \"STM32F03x\";\n\t\trev_str = get_stm32f0_revision(rev_id);\n\t\tbreak;\n\n\tcase 0x440:\n\t\tdevice_str = \"STM32F05x\";\n\t\trev_str = get_stm32f0_revision(rev_id);\n\t\tbreak;\n\n\tcase 0x445:\n\t\tdevice_str = \"STM32F04x\";\n\t\trev_str = get_stm32f0_revision(rev_id);\n\t\tbreak;\n\n\tcase 0x446:\n\t\tdevice_str = \"STM32F303xD/E\";\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x448:\n\t\tdevice_str = \"STM32F07x\";\n\t\trev_str = get_stm32f0_revision(rev_id);\n\t\tbreak;\n\n\tcase 0x442:\n\t\tdevice_str = \"STM32F09x\";\n\t\trev_str = get_stm32f0_revision(rev_id);\n\t\tbreak;\n\n\tdefault:\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as a STM32F0/1/3\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rev_str)\n\t\tcommand_print_sameline(cmd, \"%s - Rev: %s\", device_str, rev_str);\n\telse\n\t\tcommand_print_sameline(cmd, \"%s - Rev: unknown (0x%04x)\", device_str, rev_id);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_lock_command)\n{\n\tstruct target *target = NULL;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32x_erase_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to erase options\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* set readout protection */\n\tstm32x_info->option_bytes.rdp = 0;\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to lock device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"stm32x locked\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_unlock_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32x_erase_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to erase options\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to unlock device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"stm32x unlocked.\\n\"\n\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\"for the new settings to take effect.\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_options_read_command)\n{\n\tuint32_t optionbyte, protection;\n\tstruct target *target = NULL;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, STM32_FLASH_OBR_B0, &optionbyte);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint16_t user_data = optionbyte >> stm32x_info->user_data_offset;\n\n\tretval = target_read_u32(target, STM32_FLASH_WRPR_B0, &protection);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (optionbyte & (1 << OPT_ERROR))\n\t\tcommand_print(CMD, \"option byte complement error\");\n\n\tcommand_print(CMD, \"option byte register = 0x%\" PRIx32 \"\", optionbyte);\n\tcommand_print(CMD, \"write protection register = 0x%\" PRIx32 \"\", protection);\n\n\tcommand_print(CMD, \"read protection: %s\",\n\t\t\t\t(optionbyte & (1 << OPT_READOUT)) ? \"on\" : \"off\");\n\n\t/* user option bytes are offset depending on variant */\n\toptionbyte >>= stm32x_info->option_offset;\n\n\tcommand_print(CMD, \"watchdog: %sware\",\n\t\t\t\t(optionbyte & (1 << OPT_RDWDGSW)) ? \"soft\" : \"hard\");\n\n\tcommand_print(CMD, \"stop mode: %sreset generated upon entry\",\n\t\t\t\t(optionbyte & (1 << OPT_RDRSTSTOP)) ? \"no \" : \"\");\n\n\tcommand_print(CMD, \"standby mode: %sreset generated upon entry\",\n\t\t\t\t(optionbyte & (1 << OPT_RDRSTSTDBY)) ? \"no \" : \"\");\n\n\tif (stm32x_info->has_dual_banks)\n\t\tcommand_print(CMD, \"boot: bank %d\", (optionbyte & (1 << OPT_BFB2)) ? 0 : 1);\n\n\tcommand_print(CMD, \"user data = 0x%02\" PRIx16 \"\", user_data);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_options_write_command)\n{\n\tstruct target *target = NULL;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tuint8_t optionbyte;\n\tuint16_t useropt;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* start with current options */\n\toptionbyte = stm32x_info->option_bytes.user;\n\tuseropt = stm32x_info->option_bytes.data;\n\n\t/* skip over flash bank */\n\tCMD_ARGC--;\n\tCMD_ARGV++;\n\n\twhile (CMD_ARGC) {\n\t\tif (strcmp(\"SWWDG\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte |= (1 << 0);\n\t\telse if (strcmp(\"HWWDG\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte &= ~(1 << 0);\n\t\telse if (strcmp(\"NORSTSTOP\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte |= (1 << 1);\n\t\telse if (strcmp(\"RSTSTOP\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte &= ~(1 << 1);\n\t\telse if (strcmp(\"NORSTSTNDBY\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte |= (1 << 2);\n\t\telse if (strcmp(\"RSTSTNDBY\", CMD_ARGV[0]) == 0)\n\t\t\toptionbyte &= ~(1 << 2);\n\t\telse if (strcmp(\"USEROPT\", CMD_ARGV[0]) == 0) {\n\t\t\tif (CMD_ARGC < 2)\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], useropt);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t} else if (stm32x_info->has_dual_banks) {\n\t\t\tif (strcmp(\"BOOT0\", CMD_ARGV[0]) == 0)\n\t\t\t\toptionbyte |= (1 << 3);\n\t\t\telse if (strcmp(\"BOOT1\", CMD_ARGV[0]) == 0)\n\t\t\t\toptionbyte &= ~(1 << 3);\n\t\t\telse\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t} else\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t}\n\n\tif (stm32x_erase_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to erase options\");\n\t\treturn ERROR_OK;\n\t}\n\n\tstm32x_info->option_bytes.user = optionbyte;\n\tstm32x_info->option_bytes.data = useropt;\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x failed to write options\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"stm32x write options complete.\\n\"\n\t\t\t\t\"INFO: %spower cycle is required \"\n\t\t\t\t\"for the new settings to take effect.\",\n\t\t\t\tstm32x_info->can_load_options\n\t\t\t\t\t? \"'stm32f1x options_load' command or \" : \"\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_options_load_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (!stm32x_info->can_load_options) {\n\t\tLOG_ERROR(\"Command not applicable to stm32f1x devices - power cycle is \"\n\t\t\t\"required instead.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_check_operation_supported(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* unlock option flash registers */\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2);\n\tif (retval != ERROR_OK) {\n\t\t(void)target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\t\treturn retval;\n\t}\n\n\t/* force re-load of option bytes - generates software reset */\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_OBL_LAUNCH);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* unlock option flash registers */\n\tint retval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_KEYR), KEY2);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* mass erase flash memory */\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_MER);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),\n\t\t\tFLASH_MER | FLASH_STRT);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tretval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\nflash_lock:\n\t{\n\t\tint retval2 = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = retval2;\n\t}\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"stm32x mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"stm32x mass erase failed\");\n\n\treturn retval;\n}\n\nstatic const struct command_registration stm32f1x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"lock\",\n\t\t.handler = stm32x_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lock entire flash device.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = stm32x_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Unlock entire protected flash device.\",\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stm32x_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"options_read\",\n\t\t.handler = stm32x_handle_options_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Read and display device option bytes.\",\n\t},\n\t{\n\t\t.name = \"options_write\",\n\t\t.handler = stm32x_handle_options_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ('SWWDG'|'HWWDG') \"\n\t\t\t\"('RSTSTNDBY'|'NORSTSTNDBY') \"\n\t\t\t\"('RSTSTOP'|'NORSTSTOP') ('USEROPT' user_data)\",\n\t\t.help = \"Replace bits in device option bytes.\",\n\t},\n\t{\n\t\t.name = \"options_load\",\n\t\t.handler = stm32x_handle_options_load_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Force re-load of device option bytes.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm32f1x_command_handlers[] = {\n\t{\n\t\t.name = \"stm32f1x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm32f1x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm32f1x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stm32f1x_flash = {\n\t.name = \"stm32f1x\",\n\t.commands = stm32f1x_command_handlers,\n\t.flash_bank_command = stm32x_flash_bank_command,\n\t.erase = stm32x_erase,\n\t.protect = stm32x_protect,\n\t.write = stm32x_write,\n\t.read = default_flash_read,\n\t.probe = stm32x_probe,\n\t.auto_probe = stm32x_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stm32x_protect_check,\n\t.info = get_stm32x_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32f2x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/cortex_m.h>\n\n/* Regarding performance:\n *\n * Short story - it might be best to leave the performance at\n * current levels.\n *\n * You may see a jump in speed if you change to using\n * 32bit words for the block programming.\n *\n * Its a shame you cannot use the double word as its\n * even faster - but you require external VPP for that mode.\n *\n * Having said all that 16bit writes give us the widest vdd\n * operating range, so may be worth adding a note to that effect.\n *\n */\n\n/* Danger!!!! The STM32F1x and STM32F2x series actually have\n * quite different flash controllers.\n *\n * What's more scary is that the names of the registers and their\n * addresses are the same, but the actual bits and what they do are\n * can be very different.\n *\n * To reduce testing complexity and dangers of regressions,\n * a separate file is used for stm32fx2x.\n *\n * Sector sizes in kiBytes:\n * 1 MiByte part with 4 x 16, 1 x 64, 7 x 128.\n * 1.5 MiByte part with 4 x 16, 1 x 64, 11 x 128.\n * 2 MiByte part with 4 x 16, 1 x 64, 7 x 128, 4 x 16, 1 x 64, 7 x 128.\n * 1 MiByte STM32F42x/43x part with DB1M Option set:\n *                    4 x 16, 1 x 64, 3 x 128, 4 x 16, 1 x 64, 3 x 128.\n *\n * STM32F7[2|3]\n * 512 kiByte part with 4 x 16, 1 x 64, 3 x 128.\n *\n * STM32F7[4|5]\n * 1 MiByte part with 4 x 32, 1 x 128, 3 x 256.\n *\n * STM32F7[6|7]\n * 1 MiByte part in single bank mode with 4 x 32, 1 x 128, 3 x 256.\n * 1 MiByte part in dual-bank mode two banks with 4 x 16, 1 x 64, 3 x 128 each.\n * 2 MiByte part in single-bank mode with 4 x 32, 1 x 128, 7 x 256.\n * 2 MiByte part in dual-bank mode two banks with 4 x 16, 1 x 64, 7 x 128 each.\n *\n * Protection size is sector size.\n *\n * Tested with STM3220F-EVAL board.\n *\n * STM32F4xx series for reference.\n *\n * RM0090\n * http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf\n *\n * PM0059\n * www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/\n * PROGRAMMING_MANUAL/CD00233952.pdf\n *\n * STM32F7xx series for reference.\n *\n * RM0385\n * http://www.st.com/web/en/resource/technical/document/reference_manual/DM00124865.pdf\n *\n * RM0410\n * http://www.st.com/resource/en/reference_manual/dm00224583.pdf\n *\n * RM0430\n * http://www.st.com/resource/en/reference_manual/dm00305666.pdf\n *\n * RM0431\n * http://www.st.com/resource/en/reference_manual/dm00305990.pdf\n *\n * STM32F1x series - notice that this code was copy, pasted and knocked\n * into a stm32f2x driver, so in case something has been converted or\n * bugs haven't been fixed, here are the original manuals:\n *\n * RM0008 - Reference manual\n *\n * RM0042, the Flash programming manual for low-, medium- high-density and\n * connectivity line STM32F10x devices\n *\n * PM0068, the Flash programming manual for XL-density STM32F10x devices.\n *\n */\n\n/* Erase time can be as high as 1000ms, 10x this and it's toast... */\n#define FLASH_ERASE_TIMEOUT 10000\n#define FLASH_WRITE_TIMEOUT 5\n\n/* Mass erase time can be as high as 32 s in x8 mode. */\n#define FLASH_MASS_ERASE_TIMEOUT 33000\n\n#define FLASH_BANK_BASE     0x80000000\n\n#define STM32F2_OTP_SIZE 512\n#define STM32F2_OTP_SECTOR_SIZE 32\n#define STM32F2_OTP_BANK_BASE       0x1fff7800\n#define STM32F2_OTP_LOCK_BASE       ((STM32F2_OTP_BANK_BASE) + (STM32F2_OTP_SIZE))\n\n/* see RM0410 section 3.6 \"One-time programmable bytes\" */\n#define STM32F7_OTP_SECTOR_SIZE 64\n#define STM32F7_OTP_SIZE 1024\n#define STM32F7_OTP_BANK_BASE       0x1ff0f000\n#define STM32F7_OTP_LOCK_BASE       ((STM32F7_OTP_BANK_BASE) + (STM32F7_OTP_SIZE))\n\n#define STM32_FLASH_BASE    0x40023c00\n#define STM32_FLASH_ACR     0x40023c00\n#define STM32_FLASH_KEYR    0x40023c04\n#define STM32_FLASH_OPTKEYR 0x40023c08\n#define STM32_FLASH_SR      0x40023c0C\n#define STM32_FLASH_CR      0x40023c10\n#define STM32_FLASH_OPTCR   0x40023c14\n#define STM32_FLASH_OPTCR1  0x40023c18\n#define STM32_FLASH_OPTCR2  0x40023c1c\n\n/* FLASH_CR register bits */\n#define FLASH_PG       (1 << 0)\n#define FLASH_SER      (1 << 1)\n#define FLASH_MER      (1 << 2)\t\t/* MER/MER1 for f76x/77x */\n#define FLASH_MER1     (1 << 15)\t/* MER2 for f76x/77x, confusing ... */\n#define FLASH_STRT     (1 << 16)\n#define FLASH_PSIZE_8  (0 << 8)\n#define FLASH_PSIZE_16 (1 << 8)\n#define FLASH_PSIZE_32 (2 << 8)\n#define FLASH_PSIZE_64 (3 << 8)\n/* The sector number encoding is not straight binary for dual bank flash. */\n#define FLASH_SNB(a)   ((a) << 3)\n#define FLASH_LOCK     (1 << 31)\n\n/* FLASH_SR register bits */\n#define FLASH_BSY      (1 << 16)\n#define FLASH_PGSERR   (1 << 7) /* Programming sequence error */\n#define FLASH_PGPERR   (1 << 6) /* Programming parallelism error */\n#define FLASH_PGAERR   (1 << 5) /* Programming alignment error */\n#define FLASH_WRPERR   (1 << 4) /* Write protection error */\n#define FLASH_OPERR    (1 << 1) /* Operation error */\n\n#define FLASH_ERROR (FLASH_PGSERR | FLASH_PGPERR | FLASH_PGAERR | FLASH_WRPERR | FLASH_OPERR)\n\n/* STM32_FLASH_OPTCR register bits */\n#define OPTCR_LOCK     (1 << 0)\n#define OPTCR_START    (1 << 1)\n#define OPTCR_NDBANK   (1 << 29)\t/* not dual bank mode */\n#define OPTCR_DB1M     (1 << 30)\t/* 1 MiB devices dual flash bank option */\n#define OPTCR_SPRMOD   (1 << 31)\t/* switches PCROPi/nWPRi interpretation */\n\n/* STM32_FLASH_OPTCR2 register bits */\n#define OPTCR2_PCROP_RDP\t(1 << 31)\t/* erase PCROP zone when decreasing RDP */\n\n/* register unlock keys */\n#define KEY1           0x45670123\n#define KEY2           0xCDEF89AB\n\n/* option register unlock key */\n#define OPTKEY1        0x08192A3B\n#define OPTKEY2        0x4C5D6E7F\n\nstruct stm32x_options {\n\tuint8_t RDP;\n\tuint16_t user_options;\t/* bit 0-7 usual options, bit 8-11 extra options */\n\tuint32_t protection;\n\tuint32_t boot_addr;\n\tuint32_t optcr2_pcrop;\n};\n\nstruct stm32x_flash_bank {\n\tstruct stm32x_options option_bytes;\n\tbool probed;\n\tbool otp_unlocked;\n\tbool has_large_mem;\t\t/* F42x/43x/469/479/7xx in dual bank mode */\n\tbool has_extra_options; /* F42x/43x/469/479/7xx */\n\tbool has_boot_addr;     /* F7xx */\n\tbool has_optcr2_pcrop;\t/* F72x/73x */\n\tunsigned int protection_bits; /* F413/423 */\n\tuint32_t user_bank_size;\n};\n\nstatic bool stm32x_is_otp(struct flash_bank *bank)\n{\n\treturn bank->base == STM32F2_OTP_BANK_BASE ||\n\t\tbank->base == STM32F7_OTP_BANK_BASE;\n}\n\nstatic bool stm32x_otp_is_f7(struct flash_bank *bank)\n{\n\treturn bank->base == STM32F7_OTP_BANK_BASE;\n}\n\nstatic int stm32x_is_otp_unlocked(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\treturn stm32x_info->otp_unlocked;\n}\n\nstatic int stm32x_otp_disable(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tLOG_INFO(\"OTP memory bank #%u is disabled for write commands.\",\n\t\t bank->bank_number);\n\tstm32x_info->otp_unlocked = false;\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_otp_enable(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (!stm32x_info->otp_unlocked) {\n\t\tLOG_INFO(\"OTP memory bank #%u is enabled for write commands.\",\n\t\t\t bank->bank_number);\n\t\tstm32x_info->otp_unlocked = true;\n\t} else {\n\t\tLOG_WARNING(\"OTP memory bank #%u is already enabled for write commands.\",\n\t\t\t    bank->bank_number);\n\t}\n\treturn ERROR_OK;\n}\n\n/* flash bank stm32x <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)\n{\n\tstruct stm32x_flash_bank *stm32x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstm32x_info = malloc(sizeof(struct stm32x_flash_bank));\n\tbank->driver_priv = stm32x_info;\n\n\tstm32x_info->probed = false;\n\tstm32x_info->otp_unlocked = false;\n\tstm32x_info->user_bank_size = bank->size;\n\n\treturn ERROR_OK;\n}\n\nstatic inline int stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg)\n{\n\treturn reg;\n}\n\nstatic inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\treturn target_read_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR), status);\n}\n\nstatic int stm32x_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tstruct target *target = bank->target;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* wait for busy to clear */\n\tfor (;;) {\n\t\tretval = stm32x_get_flash_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32, status);\n\t\tif ((status & FLASH_BSY) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\n\tif (status & FLASH_WRPERR) {\n\t\tLOG_ERROR(\"stm32x device protected\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t/* Clear but report errors */\n\tif (status & FLASH_ERROR) {\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ERROR_FAIL;\n\t\t/* If this operation fails, we ignore it and report the original\n\t\t * retval\n\t\t */\n\t\ttarget_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_SR),\n\t\t\t\tstatus & FLASH_ERROR);\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_unlock_reg(struct target *target)\n{\n\tuint32_t ctrl;\n\n\t/* first check if not already unlocked\n\t * otherwise writing on STM32_FLASH_KEYR will fail\n\t */\n\tint retval = target_read_u32(target, STM32_FLASH_CR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & FLASH_LOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock flash registers */\n\tretval = target_write_u32(target, STM32_FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, STM32_FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, STM32_FLASH_CR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & FLASH_LOCK) {\n\t\tLOG_ERROR(\"flash not unlocked STM32_FLASH_CR: 0x%\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_unlock_option_reg(struct target *target)\n{\n\tuint32_t ctrl;\n\n\tint retval = target_read_u32(target, STM32_FLASH_OPTCR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & OPTCR_LOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock option registers */\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, STM32_FLASH_OPTKEYR, OPTKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, STM32_FLASH_OPTCR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & OPTCR_LOCK) {\n\t\tLOG_ERROR(\"options not unlocked STM32_FLASH_OPTCR: 0x%\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_read_options(struct flash_bank *bank)\n{\n\tuint32_t optiondata;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tstruct target *target = bank->target;\n\n\tstm32x_info = bank->driver_priv;\n\n\t/* read current option bytes */\n\tint retval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n    /* caution: F2 implements 5 bits (WDG_SW only)\n     * whereas F7 6 bits (IWDG_SW and WWDG_SW) in user_options */\n\tstm32x_info->option_bytes.user_options = optiondata & 0xfc;\n\tstm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff;\n\tstm32x_info->option_bytes.protection =\n\t\t(optiondata >> 16) & (~(0xffff << stm32x_info->protection_bits) & 0xffff);\n\n\tif (stm32x_info->has_extra_options) {\n\t\t/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */\n\t\tstm32x_info->option_bytes.user_options |= (optiondata >> 20) &\n\t\t\t((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00);\n\t}\n\n\tif (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {\n\t\tretval = target_read_u32(target, STM32_FLASH_OPTCR1, &optiondata);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* FLASH_OPTCR1 has quite different meanings ... */\n\t\tif (stm32x_info->has_boot_addr) {\n\t\t\t/* for F7xx it contains boot0 and boot1 */\n\t\t\tstm32x_info->option_bytes.boot_addr = optiondata;\n\t\t} else {\n\t\t\t/* for F42x/43x/469/479 it contains 12 additional protection bits */\n\t\t\tstm32x_info->option_bytes.protection |= (optiondata >> 4) & 0x00fff000;\n\t\t}\n\t}\n\n\tif (stm32x_info->has_optcr2_pcrop) {\n\t\tretval = target_read_u32(target, STM32_FLASH_OPTCR2, &optiondata);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tstm32x_info->option_bytes.optcr2_pcrop = optiondata;\n\t\tif (stm32x_info->has_optcr2_pcrop &&\n\t\t\t(stm32x_info->option_bytes.optcr2_pcrop & ~OPTCR2_PCROP_RDP)) {\n\t\t\tLOG_INFO(\"PCROP Engaged\");\n\t\t}\n\t} else {\n\t\tstm32x_info->option_bytes.optcr2_pcrop = 0x0;\n\t}\n\n\tif (stm32x_info->option_bytes.RDP != 0xAA)\n\t\tLOG_INFO(\"Device Security Bit Set\");\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_write_options(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tstruct target *target = bank->target;\n\tuint32_t optiondata, optiondata2;\n\n\tstm32x_info = bank->driver_priv;\n\n\tint retval = stm32x_unlock_option_reg(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* rebuild option data */\n\toptiondata = stm32x_info->option_bytes.user_options & 0xfc;\n\toptiondata |= stm32x_info->option_bytes.RDP << 8;\n\toptiondata |= (stm32x_info->option_bytes.protection &\n\t\t(~(0xffff << stm32x_info->protection_bits))) << 16;\n\n\tif (stm32x_info->has_extra_options) {\n\t\t/* F42x/43x/469/479 and 7xx have up to 4 bits of extra options */\n\t\toptiondata |= (stm32x_info->option_bytes.user_options &\n\t\t\t((0xf00 << (stm32x_info->protection_bits - 12)) & 0xf00)) << 20;\n\t}\n\n\tif (stm32x_info->has_large_mem || stm32x_info->has_boot_addr) {\n\t\tif (stm32x_info->has_boot_addr) {\n\t\t\t/* F7xx uses FLASH_OPTCR1 for boot0 and boot1 ... */\n\t\t\toptiondata2 = stm32x_info->option_bytes.boot_addr;\n\t\t} else {\n\t\t\t/* F42x/43x/469/479 uses FLASH_OPTCR1 for additional protection bits */\n\t\t\toptiondata2 = (stm32x_info->option_bytes.protection & 0x00fff000) << 4;\n\t\t}\n\n\t\tretval = target_write_u32(target, STM32_FLASH_OPTCR1, optiondata2);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* program extra pcrop register */\n\tif (stm32x_info->has_optcr2_pcrop) {\n\t\tretval = target_write_u32(target, STM32_FLASH_OPTCR2,\n\t\t\tstm32x_info->option_bytes.optcr2_pcrop);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* program options */\n\tretval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* start programming cycle */\n\tretval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPTCR_START);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for completion, this might trigger a security erase and take a while */\n\tretval = stm32x_wait_status_busy(bank, FLASH_MASS_ERASE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* relock registers */\n\tretval = target_write_u32(target, STM32_FLASH_OPTCR, optiondata | OPTCR_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_otp_read_protect(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tuint32_t lock_base;\n\tint retval;\n\tuint8_t lock;\n\n\tlock_base = stm32x_otp_is_f7(bank) ? STM32F7_OTP_LOCK_BASE\n\t\t  : STM32F2_OTP_LOCK_BASE;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tretval = target_read_u8(target, lock_base + i, &lock);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbank->sectors[i].is_protected = !lock;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_otp_protect(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tuint32_t lock_base;\n\tint i, retval;\n\tuint8_t lock;\n\n\tassert((first <= last) && (last < bank->num_sectors));\n\n\tlock_base = stm32x_otp_is_f7(bank) ? STM32F7_OTP_LOCK_BASE\n\t\t  : STM32F2_OTP_LOCK_BASE;\n\n\tfor (i = first; first <= last; i++) {\n\t\tretval = target_read_u8(target, lock_base + i, &lock);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (lock)\n\t\t\tcontinue;\n\n\t\tlock = 0xff;\n\t\tretval = target_write_u8(target, lock_base + i, lock);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_protect_check(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tstruct flash_sector *prot_blocks;\n\tunsigned int num_prot_blocks;\n\tint retval;\n\n\t/* if it's the OTP bank, look at the lock bits there */\n\tif (stm32x_is_otp(bank))\n\t\treturn stm32x_otp_read_protect(bank);\n\n\t/* read write protection settings */\n\tretval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"unable to read option bytes\");\n\t\treturn retval;\n\t}\n\n\tif (bank->prot_blocks) {\n\t\tnum_prot_blocks = bank->num_prot_blocks;\n\t\tprot_blocks = bank->prot_blocks;\n\t} else {\n\t\tnum_prot_blocks = bank->num_sectors;\n\t\tprot_blocks = bank->sectors;\n\t}\n\n\tfor (unsigned int i = 0; i < num_prot_blocks; i++)\n\t\tprot_blocks[i].is_protected =\n\t\t\t~(stm32x_info->option_bytes.protection >> i) & 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tif (stm32x_is_otp(bank)) {\n\t\tLOG_ERROR(\"Cannot erase OTP memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tassert((first <= last) && (last < bank->num_sectors));\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint retval;\n\tretval = stm32x_unlock_reg(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\tSector Erase\n\tTo erase a sector, follow the procedure below:\n\t1. Check that no Flash memory operation is ongoing by checking the BSY bit in the\n\t  FLASH_SR register\n\t2. Set the SER bit and select the sector\n\t  you wish to erase (SNB) in the FLASH_CR register\n\t3. Set the STRT bit in the FLASH_CR register\n\t4. Wait for the BSY bit to be cleared\n\t */\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tunsigned int snb;\n\t\tif (stm32x_info->has_large_mem && i >= (bank->num_sectors / 2))\n\t\t\tsnb = (i - (bank->num_sectors / 2)) | 0x10;\n\t\telse\n\t\t\tsnb = i;\n\n\t\tretval = target_write_u32(target,\n\t\t\t\tstm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_SER | FLASH_SNB(snb) | FLASH_STRT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (stm32x_is_otp(bank)) {\n\t\tif (!set) {\n\t\t\tLOG_ERROR(\"OTP protection can only be enabled\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\n\t\treturn stm32x_otp_protect(bank, first, last);\n\t}\n\n\t/* read protection settings */\n\tint retval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"unable to read option bytes\");\n\t\treturn retval;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tif (set)\n\t\t\tstm32x_info->option_bytes.protection &= ~(1 << i);\n\t\telse\n\t\t\tstm32x_info->option_bytes.protection |= (1 << i);\n\t}\n\n\tretval = stm32x_write_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 16384;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\tstatic const uint8_t stm32x_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/stm32/stm32f2x.inc\"\n\t};\n\n\tif (stm32x_is_otp(bank) && !stm32x_is_otp_unlocked(bank)) {\n\t\tLOG_ERROR(\"OTP memory bank is disabled for write commands.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(stm32x_flash_write_code),\n\t\t\tstm32x_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t\t/* buffer start, status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t\t/* buffer end */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t\t/* target address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t\t/* count (halfword-16bit) */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\t\t/* flash base */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\tbuf_set_u32(reg_params[4].value, 0, 32, STM32_FLASH_BASE);\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, 2,\n\t\t\t0, NULL,\n\t\t\t5, reg_params,\n\t\t\tsource->address, source->size,\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"error executing stm32x flash write algorithm\");\n\n\t\tuint32_t error = buf_get_u32(reg_params[0].value, 0, 32) & FLASH_ERROR;\n\n\t\tif (error & FLASH_WRPERR)\n\t\t\tLOG_ERROR(\"flash memory write protected\");\n\n\t\tif (error != 0) {\n\t\t\tLOG_ERROR(\"flash write failed = 0x%08\" PRIx32, error);\n\t\t\t/* Clear but report errors */\n\t\t\ttarget_write_u32(target, STM32_FLASH_SR, error);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\nstatic int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t words_remaining = (count / 2);\n\tuint32_t bytes_remaining = (count & 0x00000001);\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x1) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tretval = stm32x_unlock_reg(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* multiple half words (2-byte) to be programmed? */\n\tif (words_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = stm32x_write_block(bank, buffer, offset, words_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) single dword accesses */\n\t\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += words_remaining * 2;\n\t\t\taddress += words_remaining * 2;\n\t\t\twords_remaining = 0;\n\t\t}\n\t}\n\n\tif ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))\n\t\treturn retval;\n\n\t/*\n\tStandard programming\n\tThe Flash memory programming sequence is as follows:\n\t1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the\n\t  FLASH_SR register.\n\t2. Set the PG bit in the FLASH_CR register\n\t3. Perform the data write operation(s) to the desired memory address (inside main\n\t  memory block or OTP area):\n\t– – Half-word access in case of x16 parallelism\n\t– Word access in case of x32 parallelism\n\t–\n\t4.\n\tByte access in case of x8 parallelism\n\tDouble word access in case of x64 parallelism\n\tWait for the BSY bit to be cleared\n\t*/\n\twhile (words_remaining > 0) {\n\t\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),\n\t\t\t\tFLASH_PG | FLASH_PSIZE_16);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = target_write_memory(target, address, 2, 1, buffer + bytes_written);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbytes_written += 2;\n\t\twords_remaining--;\n\t\taddress += 2;\n\t}\n\n\tif (bytes_remaining) {\n\t\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),\n\t\t\t\tFLASH_PG | FLASH_PSIZE_8);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u8(target, address, buffer[bytes_written]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn target_write_u32(target, STM32_FLASH_CR, FLASH_LOCK);\n}\n\nstatic void setup_sector(struct flash_bank *bank, unsigned int i,\n\t\tunsigned int size)\n{\n\tassert(i < bank->num_sectors);\n\tbank->sectors[i].offset = bank->size;\n\tbank->sectors[i].size = size;\n\tbank->size += bank->sectors[i].size;\n\tLOG_DEBUG(\"sector %u: %ukBytes\", i, size >> 10);\n}\n\nstatic uint16_t sector_size_in_kb(unsigned int i, uint16_t max_sector_size_in_kb)\n{\n\tif (i < 4)\n\t\treturn max_sector_size_in_kb / 8;\n\tif (i == 4)\n\t\treturn max_sector_size_in_kb / 2;\n\treturn max_sector_size_in_kb;\n}\n\nstatic unsigned int calculate_number_of_sectors(struct flash_bank *bank,\n\t\tuint16_t flash_size_in_kb,\n\t\tuint16_t max_sector_size_in_kb)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tuint16_t remaining_flash_size_in_kb = flash_size_in_kb;\n\tunsigned int nr_sectors;\n\n\t/* Dual Bank Flash has two identically-arranged banks of sectors. */\n\tif (stm32x_info->has_large_mem)\n\t\tremaining_flash_size_in_kb /= 2;\n\n\tfor (nr_sectors = 0; remaining_flash_size_in_kb > 0; nr_sectors++) {\n\t\tuint16_t size_in_kb = sector_size_in_kb(nr_sectors, max_sector_size_in_kb);\n\t\tif (size_in_kb > remaining_flash_size_in_kb) {\n\t\t\tLOG_INFO(\"%s Bank %\" PRIu16 \" kiB final sector clipped to %\" PRIu16 \" kiB\",\n\t\t\t\t stm32x_info->has_large_mem ? \"Dual\" : \"Single\",\n\t\t\t\t flash_size_in_kb, remaining_flash_size_in_kb);\n\t\t\tremaining_flash_size_in_kb = 0;\n\t\t} else {\n\t\t\tremaining_flash_size_in_kb -= size_in_kb;\n\t\t}\n\t}\n\n\treturn stm32x_info->has_large_mem ? nr_sectors*2 : nr_sectors;\n}\n\nstatic void setup_bank(struct flash_bank *bank, unsigned int start,\n\tuint16_t flash_size_in_kb, uint16_t max_sector_size_in_kb)\n{\n\tuint16_t remaining_flash_size_in_kb = flash_size_in_kb;\n\tunsigned int sector_index = 0;\n\twhile (remaining_flash_size_in_kb > 0) {\n\t\tuint16_t size_in_kb = sector_size_in_kb(sector_index, max_sector_size_in_kb);\n\t\tif (size_in_kb > remaining_flash_size_in_kb) {\n\t\t\t/* Clip last sector. Already warned in\n\t\t\t * calculate_number_of_sectors. */\n\t\t\tsize_in_kb = remaining_flash_size_in_kb;\n\t\t}\n\t\tsetup_sector(bank, start + sector_index, size_in_kb * 1024);\n\t\tremaining_flash_size_in_kb -= size_in_kb;\n\t\tsector_index++;\n\t}\n}\n\nstatic int stm32x_get_device_id(struct flash_bank *bank, uint32_t *device_id)\n{\n\t/* this checks for a stm32f4x errata issue where a\n\t * stm32f2x DBGMCU_IDCODE is incorrectly returned.\n\t * If the issue is detected target is forced to stm32f4x Rev A.\n\t * Only effects Rev A silicon */\n\n\tstruct target *target = bank->target;\n\n\t/* read stm32 device id register */\n\tint retval = target_read_u32(target, 0xE0042000, device_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((*device_id & 0xfff) == 0x411\n\t\t\t&& cortex_m_get_partno_safe(target) == CORTEX_M4_PARTNO) {\n\t\t*device_id &= ~((0xFFFF << 16) | 0xfff);\n\t\t*device_id |= (0x1000 << 16) | 0x413;\n\t\tLOG_INFO(\"stm32f4x errata detected - fixing incorrect MCU_IDCODE\");\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tunsigned int num_prot_blocks, num_sectors;\n\tuint16_t flash_size_in_kb;\n\tuint16_t otp_size_in_b;\n\tuint16_t otp_sector_size;\n\tuint32_t flash_size_reg = 0x1FFF7A22;\n\tuint16_t max_sector_size_in_kb = 128;\n\tuint16_t max_flash_size_in_kb;\n\tuint32_t device_id;\n\tuint32_t base_address = 0x08000000;\n\n\tstm32x_info->probed = false;\n\tstm32x_info->has_large_mem = false;\n\tstm32x_info->has_boot_addr = false;\n\tstm32x_info->has_extra_options = false;\n\tstm32x_info->has_optcr2_pcrop = false;\n\tstm32x_info->protection_bits = 12;\t\t/* max. number of nWRPi bits (in FLASH_OPTCR !!!) */\n\tnum_prot_blocks = 0;\n\n\tfree(bank->sectors);\n\tbank->num_sectors = 0;\n\tbank->sectors = NULL;\n\n\tfree(bank->prot_blocks);\n\tbank->num_prot_blocks = 0;\n\tbank->prot_blocks = NULL;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\t/* if explicitly called out as OTP bank, short circuit probe */\n\tif (stm32x_is_otp(bank)) {\n\t\tif (stm32x_otp_is_f7(bank)) {\n\t\t\totp_size_in_b = STM32F7_OTP_SIZE;\n\t\t\totp_sector_size = STM32F7_OTP_SECTOR_SIZE;\n\t\t} else {\n\t\t\totp_size_in_b = STM32F2_OTP_SIZE;\n\t\t\totp_sector_size = STM32F2_OTP_SECTOR_SIZE;\n\t\t}\n\n\t\tnum_sectors = otp_size_in_b / otp_sector_size;\n\t\tLOG_INFO(\"flash size = %\" PRIu16 \" bytes\", otp_size_in_b);\n\n\t\tassert(num_sectors > 0);\n\n\t\tbank->num_sectors = num_sectors;\n\t\tbank->sectors = calloc(sizeof(struct flash_sector), num_sectors);\n\n\t\tif (stm32x_otp_is_f7(bank))\n\t\t\tbank->size = STM32F7_OTP_SIZE;\n\t\telse\n\t\t\tbank->size = STM32F2_OTP_SIZE;\n\n\t\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\t\tbank->sectors[i].offset = i * otp_sector_size;\n\t\t\tbank->sectors[i].size = otp_sector_size;\n\t\t\tbank->sectors[i].is_erased = 1;\n\t\t\tbank->sectors[i].is_protected = 0;\n\t\t}\n\n\t\tstm32x_info->probed = true;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* read stm32 device id register */\n\tint retval = stm32x_get_device_id(bank, &device_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_INFO(\"device id = 0x%08\" PRIx32, device_id);\n\tdevice_id &= 0xfff;\t\t/* only bits 0-11 are used further on */\n\n\t/* set max flash size depending on family, id taken from AN2606 */\n\tswitch (device_id) {\n\tcase 0x411: /* F20x/21x */\n\tcase 0x413: /* F40x/41x */\n\t\tmax_flash_size_in_kb = 1024;\n\t\tbreak;\n\n\tcase 0x419: /* F42x/43x */\n\tcase 0x434: /* F469/479 */\n\t\tstm32x_info->has_extra_options = true;\n\t\tmax_flash_size_in_kb = 2048;\n\t\tbreak;\n\n\tcase 0x423:\t/* F401xB/C */\n\t\tmax_flash_size_in_kb = 256;\n\t\tbreak;\n\n\tcase 0x421:\t/* F446 */\n\tcase 0x431: /* F411 */\n\tcase 0x433: /* F401xD/E */\n\tcase 0x441: /* F412 */\n\t\tmax_flash_size_in_kb = 512;\n\t\tbreak;\n\n\tcase 0x458: /* F410 */\n\t\tmax_flash_size_in_kb = 128;\n\t\tbreak;\n\n\tcase 0x449:\t/* F74x/75x */\n\t\tmax_flash_size_in_kb = 1024;\n\t\tmax_sector_size_in_kb = 256;\n\t\tflash_size_reg = 0x1FF0F442;\n\t\tstm32x_info->has_extra_options = true;\n\t\tstm32x_info->has_boot_addr = true;\n\t\tbreak;\n\n\tcase 0x451:\t/* F76x/77x */\n\t\tmax_flash_size_in_kb = 2048;\n\t\tmax_sector_size_in_kb = 256;\n\t\tflash_size_reg = 0x1FF0F442;\n\t\tstm32x_info->has_extra_options = true;\n\t\tstm32x_info->has_boot_addr = true;\n\t\tbreak;\n\n\tcase 0x452:\t/* F72x/73x */\n\t\tmax_flash_size_in_kb = 512;\n\t\tflash_size_reg = 0x1FF07A22;\t/* yes, 0x1FF*0*7A22, not 0x1FF*F*7A22 */\n\t\tstm32x_info->has_extra_options = true;\n\t\tstm32x_info->has_boot_addr = true;\n\t\tstm32x_info->has_optcr2_pcrop = true;\n\t\tbreak;\n\n\tcase 0x463:\t/* F413x/423x */\n\t\tmax_flash_size_in_kb = 1536;\n\t\tstm32x_info->has_extra_options = true;\n\t\tstm32x_info->protection_bits = 15;\n\t\tnum_prot_blocks = 15;\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_WARNING(\"Cannot identify target as a STM32 family.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* get flash size from target. */\n\tretval = target_read_u16(target, flash_size_reg, &flash_size_in_kb);\n\n\t/* failed reading flash size or flash size invalid (early silicon),\n\t * default to max target family */\n\tif (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {\n\t\tLOG_WARNING(\"STM32 flash size failed, probe inaccurate - assuming %\" PRIu16 \"k flash\",\n\t\t\tmax_flash_size_in_kb);\n\t\tflash_size_in_kb = max_flash_size_in_kb;\n\t}\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (stm32x_info->user_bank_size) {\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size\");\n\t\tflash_size_in_kb = stm32x_info->user_bank_size / 1024;\n\t}\n\n\tLOG_INFO(\"flash size = %\" PRIu16 \" KiB\", flash_size_in_kb);\n\n\t/* did we assign flash size? */\n\tassert(flash_size_in_kb != 0xffff);\n\n\t/* F42x/43x/469/479 1024 kiByte devices have a dual bank option */\n\tif ((device_id == 0x419) || (device_id == 0x434)) {\n\t\tuint32_t optiondata;\n\t\tretval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"unable to read option bytes\");\n\t\t\treturn retval;\n\t\t}\n\t\tif ((flash_size_in_kb > 1024) || (optiondata & OPTCR_DB1M)) {\n\t\t\tstm32x_info->has_large_mem = true;\n\t\t\tLOG_INFO(\"Dual Bank %\" PRIu16 \" kiB STM32F42x/43x/469/479 found\", flash_size_in_kb);\n\t\t} else {\n\t\t\tstm32x_info->has_large_mem = false;\n\t\t\tLOG_INFO(\"Single Bank %\" PRIu16 \" kiB STM32F42x/43x/469/479 found\", flash_size_in_kb);\n\t\t}\n\t}\n\n\t/* F76x/77x devices have a dual bank option */\n\tif (device_id == 0x451) {\n\t\tuint32_t optiondata;\n\t\tretval = target_read_u32(target, STM32_FLASH_OPTCR, &optiondata);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"unable to read option bytes\");\n\t\t\treturn retval;\n\t\t}\n\t\tif (optiondata & OPTCR_NDBANK) {\n\t\t\tstm32x_info->has_large_mem = false;\n\t\t\tLOG_INFO(\"Single Bank %\" PRIu16 \" kiB STM32F76x/77x found\", flash_size_in_kb);\n\t\t} else {\n\t\t\tstm32x_info->has_large_mem = true;\n\t\t\tmax_sector_size_in_kb >>= 1; /* sector size divided by 2 in dual-bank mode */\n\t\t\tLOG_INFO(\"Dual Bank %\" PRIu16 \" kiB STM32F76x/77x found\", flash_size_in_kb);\n\t\t}\n\t}\n\n\t/* calculate numbers of pages */\n\tunsigned int num_pages = calculate_number_of_sectors(\n\t\t\tbank, flash_size_in_kb, max_sector_size_in_kb);\n\n\tbank->base = base_address;\n\tbank->num_sectors = num_pages;\n\tbank->sectors = calloc(num_pages, sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < num_pages; i++) {\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 0;\n\t}\n\tbank->size = 0;\n\tLOG_DEBUG(\"allocated %u sectors\", num_pages);\n\n\t/* F76x/77x in dual bank mode */\n\tif ((device_id == 0x451) && stm32x_info->has_large_mem)\n\t\tnum_prot_blocks = num_pages >> 1;\n\n\tif (num_prot_blocks) {\n\t\tbank->prot_blocks = malloc(sizeof(struct flash_sector) * num_prot_blocks);\n\t\tfor (unsigned int i = 0; i < num_prot_blocks; i++)\n\t\t\tbank->prot_blocks[i].is_protected = 0;\n\t\tLOG_DEBUG(\"allocated %u prot blocks\", num_prot_blocks);\n\t}\n\n\tif (stm32x_info->has_large_mem) {\n\t\t/* dual-bank */\n\t\tsetup_bank(bank, 0, flash_size_in_kb >> 1, max_sector_size_in_kb);\n\t\tsetup_bank(bank, num_pages >> 1, flash_size_in_kb >> 1,\n\t\t\tmax_sector_size_in_kb);\n\n\t\t/* F767x/F77x in dual mode, one protection bit refers to two adjacent sectors */\n\t\tif (device_id == 0x451) {\n\t\t\tfor (unsigned int i = 0; i < num_prot_blocks; i++) {\n\t\t\t\tbank->prot_blocks[i].offset = bank->sectors[i << 1].offset;\n\t\t\t\tbank->prot_blocks[i].size = bank->sectors[i << 1].size\n\t\t\t\t\t\t+ bank->sectors[(i << 1) + 1].size;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* single-bank */\n\t\tsetup_bank(bank, 0, flash_size_in_kb, max_sector_size_in_kb);\n\n\t\t/* F413/F423, sectors 14 and 15 share one common protection bit */\n\t\tif (device_id == 0x463) {\n\t\t\tfor (unsigned int i = 0; i < num_prot_blocks; i++) {\n\t\t\t\tbank->prot_blocks[i].offset = bank->sectors[i].offset;\n\t\t\t\tbank->prot_blocks[i].size = bank->sectors[i].size;\n\t\t\t}\n\t\t\tbank->prot_blocks[num_prot_blocks - 1].size <<= 1;\n\t\t}\n\t}\n\tbank->num_prot_blocks = num_prot_blocks;\n\tassert((bank->size >> 10) == flash_size_in_kb);\n\n\tstm32x_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_auto_probe(struct flash_bank *bank)\n{\n\tstruct stm32x_flash_bank *stm32x_info = bank->driver_priv;\n\tif (stm32x_info->probed)\n\t\treturn ERROR_OK;\n\treturn stm32x_probe(bank);\n}\n\nstatic int get_stm32x_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tuint32_t dbgmcu_idcode;\n\n\t/* read stm32 device id register */\n\tint retval = stm32x_get_device_id(bank, &dbgmcu_idcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint16_t device_id = dbgmcu_idcode & 0xfff;\n\tuint16_t rev_id = dbgmcu_idcode >> 16;\n\tconst char *device_str;\n\tconst char *rev_str = NULL;\n\n\tswitch (device_id) {\n\tcase 0x411:\n\t\tdevice_str = \"STM32F2xx\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x2000:\n\t\t\trev_str = \"B\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x2001:\n\t\t\trev_str = \"Y\";\n\t\t\tbreak;\n\n\t\tcase 0x2003:\n\t\t\trev_str = \"X\";\n\t\t\tbreak;\n\n\t\tcase 0x2007:\n\t\t\trev_str = \"1\";\n\t\t\tbreak;\n\n\t\tcase 0x200F:\n\t\t\trev_str = \"V\";\n\t\t\tbreak;\n\n\t\tcase 0x201F:\n\t\t\trev_str = \"2\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x413:\n\tcase 0x419:\n\tcase 0x434:\n\t\tdevice_str = \"STM32F4xx\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x1003:\n\t\t\trev_str = \"Y\";\n\t\t\tbreak;\n\n\t\tcase 0x1007:\n\t\t\trev_str = \"1\";\n\t\t\tbreak;\n\n\t\tcase 0x2001:\n\t\t\trev_str = \"3\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x421:\n\t\tdevice_str = \"STM32F446\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x423:\n\tcase 0x431:\n\tcase 0x433:\n\tcase 0x458:\n\tcase 0x441:\n\t\tdevice_str = \"STM32F4xx (Low Power)\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\n\t\tcase 0x2000:\n\t\t\trev_str = \"B\";\n\t\t\tbreak;\n\n\t\tcase 0x3000:\n\t\t\trev_str = \"C\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x449:\n\t\tdevice_str = \"STM32F7[4|5]x\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x451:\n\t\tdevice_str = \"STM32F7[6|7]x\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\tcase 0x1001:\n\t\t\trev_str = \"Z\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x452:\n\t\tdevice_str = \"STM32F7[2|3]x\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tcase 0x463:\n\t\tdevice_str = \"STM32F4[1|2]3\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1000:\n\t\t\trev_str = \"A\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as a STM32F2/4/7\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rev_str)\n\t\tcommand_print_sameline(cmd, \"%s - Rev: %s\", device_str, rev_str);\n\telse\n\t\tcommand_print_sameline(cmd, \"%s - Rev: unknown (0x%04\" PRIx16 \")\", device_str, rev_id);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_lock_command)\n{\n\tstruct target *target = NULL;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_INFO(\"Target not halted\");\n\t\t/* return ERROR_TARGET_NOT_HALTED; */\n\t}\n\n\tif (stm32x_read_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to read options\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* set readout protection */\n\tstm32x_info->option_bytes.RDP = 0;\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to lock device\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"%s locked\", bank->driver->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_unlock_command)\n{\n\tstruct target *target = NULL;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_INFO(\"Target not halted\");\n\t\t/* return ERROR_TARGET_NOT_HALTED; */\n\t}\n\n\tif (stm32x_read_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to read options\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* clear readout protection and complementary option bytes\n\t * this will also force a device unlock if set */\n\tstm32x_info->option_bytes.RDP = 0xAA;\n\tif (stm32x_info->has_optcr2_pcrop) {\n\t\tstm32x_info->option_bytes.optcr2_pcrop = OPTCR2_PCROP_RDP | (~1U << bank->num_sectors);\n\t}\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to unlock device\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"%s unlocked.\\n\"\n\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\"for the new settings to take effect.\", bank->driver->name);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_mass_erase(struct flash_bank *bank)\n{\n\tint retval;\n\tuint32_t flash_mer;\n\tstruct target *target = bank->target;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstm32x_info = bank->driver_priv;\n\n\tretval = stm32x_unlock_reg(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* mass erase flash memory */\n\tif (stm32x_info->has_large_mem)\n\t\tflash_mer = FLASH_MER | FLASH_MER1;\n\telse\n\t\tflash_mer = FLASH_MER;\n\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), flash_mer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR),\n\t\tflash_mer | FLASH_STRT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_wait_status_busy(bank, FLASH_MASS_ERASE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, stm32x_get_flash_reg(bank, STM32_FLASH_CR), FLASH_LOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32x_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"stm32x mass_erase <bank>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_mass_erase(bank);\n\tif (retval == ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32x mass erase complete\");\n\t} else {\n\t\tcommand_print(CMD, \"stm32x mass erase failed\");\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32f2x_handle_options_read_command)\n{\n\tint retval;\n\tstruct flash_bank *bank;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\n\tif (CMD_ARGC != 1) {\n\t\tcommand_print(CMD, \"stm32f2x options_read <bank>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\tif (stm32x_info->has_extra_options) {\n\t\tif (stm32x_info->has_boot_addr) {\n\t\t\tuint32_t boot_addr = stm32x_info->option_bytes.boot_addr;\n\n\t\t\tcommand_print(CMD, \"stm32f2x user_options 0x%03\" PRIX16 \",\"\n\t\t\t\t\" boot_add0 0x%04\" PRIX32 \", boot_add1 0x%04\" PRIX32,\n\t\t\t\tstm32x_info->option_bytes.user_options,\n\t\t\t\tboot_addr & 0xffff, (boot_addr & 0xffff0000) >> 16);\n\t\t\tif (stm32x_info->has_optcr2_pcrop) {\n\t\t\t\tcommand_print(CMD, \"stm32f2x optcr2_pcrop 0x%08\" PRIX32,\n\t\t\t\t\t\tstm32x_info->option_bytes.optcr2_pcrop);\n\t\t\t}\n\t\t} else {\n\t\t\tcommand_print(CMD, \"stm32f2x user_options 0x%03\" PRIX16,\n\t\t\t\tstm32x_info->option_bytes.user_options);\n\t\t}\n\t} else {\n\t\tcommand_print(CMD, \"stm32f2x user_options 0x%02\" PRIX16,\n\t\t\tstm32x_info->option_bytes.user_options);\n\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32f2x_handle_options_write_command)\n{\n\tint retval;\n\tstruct flash_bank *bank;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tuint16_t user_options, boot_addr0, boot_addr1, options_mask;\n\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"stm32f2x options_write <bank> ...\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\tif (stm32x_info->has_boot_addr) {\n\t\tif (CMD_ARGC != 4) {\n\t\t\tcommand_print(CMD, \"stm32f2x options_write <bank> <user_options>\"\n\t\t\t\t\" <boot_addr0> <boot_addr1>\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], boot_addr0);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], boot_addr1);\n\t\tstm32x_info->option_bytes.boot_addr = boot_addr0 | (((uint32_t) boot_addr1) << 16);\n\t} else {\n\t\tif (CMD_ARGC != 2) {\n\t\t\tcommand_print(CMD, \"stm32f2x options_write <bank> <user_options>\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], user_options);\n\toptions_mask = !stm32x_info->has_extra_options ? ~0xfc :\n\t\t~(((0xf00 << (stm32x_info->protection_bits - 12)) | 0xff) & 0xffc);\n\tif (user_options & options_mask) {\n\t\tcommand_print(CMD, \"stm32f2x invalid user_options\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tstm32x_info->option_bytes.user_options = user_options;\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32f2x failed to write options\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* switching between single- and dual-bank modes requires re-probe */\n\t/* ... and reprogramming of whole flash */\n\tstm32x_info->probed = false;\n\n\tcommand_print(CMD, \"stm32f2x write options complete.\\n\"\n\t\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\t\"for the new settings to take effect.\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32f2x_handle_optcr2_write_command)\n{\n\tint retval;\n\tstruct flash_bank *bank;\n\tstruct stm32x_flash_bank *stm32x_info = NULL;\n\tuint32_t optcr2_pcrop;\n\n\tif (CMD_ARGC != 2) {\n\t\tcommand_print(CMD, \"stm32f2x optcr2_write <bank> <optcr2_value>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32x_info = bank->driver_priv;\n\tif (!stm32x_info->has_optcr2_pcrop) {\n\t\tcommand_print(CMD, \"no optcr2 register\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tcommand_print(CMD, \"INFO: To disable PCROP, set PCROP_RDP\"\n\t\t\t\t\" with PCROPi bits STILL SET, then\\nlock device and\"\n\t\t\t\t\" finally unlock it. Clears PCROP and mass erases flash.\");\n\n\tretval = stm32x_read_options(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], optcr2_pcrop);\n\tstm32x_info->option_bytes.optcr2_pcrop = optcr2_pcrop;\n\n\tif (stm32x_write_options(bank) != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32f2x failed to write options\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(CMD, \"stm32f2x optcr2_write complete.\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_otp_command)\n{\n\tif (CMD_ARGC < 2) {\n\t\tcommand_print(CMD, \"stm32x otp <bank> (enable|disable|show)\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (stm32x_is_otp(bank)) {\n\t\tif (strcmp(CMD_ARGV[1], \"enable\") == 0) {\n\t\t\tstm32x_otp_enable(bank);\n\t\t} else if (strcmp(CMD_ARGV[1], \"disable\") == 0) {\n\t\t\tstm32x_otp_disable(bank);\n\t\t} else if (strcmp(CMD_ARGV[1], \"show\") == 0) {\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"OTP memory bank #%u is %s for write commands.\",\n\t\t\t\tbank->bank_number,\n\t\t\t\tstm32x_is_otp_unlocked(bank) ? \"enabled\" : \"disabled\");\n\t\t} else {\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t} else {\n\t\tcommand_print(CMD, \"Failed: not an OTP bank.\");\n\t}\n\n\treturn retval;\n}\n\nstatic const struct command_registration stm32f2x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"lock\",\n\t\t.handler = stm32x_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lock entire flash device.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = stm32x_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Unlock entire protected flash device.\",\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stm32x_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"options_read\",\n\t\t.handler = stm32f2x_handle_options_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Read and display device option bytes.\",\n\t},\n\t{\n\t\t.name = \"options_write\",\n\t\t.handler = stm32f2x_handle_options_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id user_options [ boot_add0 boot_add1 ]\",\n\t\t.help = \"Write option bytes\",\n\t},\n\t{\n\t\t.name = \"optcr2_write\",\n\t\t.handler = stm32f2x_handle_optcr2_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id optcr2\",\n\t\t.help = \"Write optcr2 word\",\n\t},\n\t{\n\t\t.name = \"otp\",\n\t\t.handler = stm32x_handle_otp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"OTP (One Time Programmable) memory write enable/disable.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm32f2x_command_handlers[] = {\n\t{\n\t\t.name = \"stm32f2x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm32f2x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm32f2x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stm32f2x_flash = {\n\t.name = \"stm32f2x\",\n\t.commands = stm32f2x_command_handlers,\n\t.flash_bank_command = stm32x_flash_bank_command,\n\t.erase = stm32x_erase,\n\t.protect = stm32x_protect,\n\t.write = stm32x_write,\n\t.read = default_flash_read,\n\t.probe = stm32x_probe,\n\t.auto_probe = stm32x_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stm32x_protect_check,\n\t.info = get_stm32x_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32h7x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by STMicroelectronics                              *\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/cortex_m.h>\n\n\n/* Erase time can be as high as 1000ms, 10x this and it's toast... */\n#define FLASH_ERASE_TIMEOUT 10000\n#define FLASH_WRITE_TIMEOUT 5\n\n/* RM 433 */\n/* Same Flash registers for both banks, */\n/* access depends on Flash Base address */\n#define FLASH_ACR       0x00\n#define FLASH_KEYR      0x04\n#define FLASH_OPTKEYR   0x08\n#define FLASH_CR        0x0C\n#define FLASH_SR        0x10\n#define FLASH_CCR       0x14\n#define FLASH_OPTCR     0x18\n#define FLASH_OPTSR_CUR 0x1C\n#define FLASH_OPTSR_PRG 0x20\n#define FLASH_OPTCCR    0x24\n#define FLASH_WPSN_CUR  0x38\n#define FLASH_WPSN_PRG  0x3C\n\n\n/* FLASH_CR register bits */\n#define FLASH_LOCK     (1 << 0)\n#define FLASH_PG       (1 << 1)\n#define FLASH_SER      (1 << 2)\n#define FLASH_BER      (1 << 3)\n#define FLASH_PSIZE_8  (0 << 4)\n#define FLASH_PSIZE_16 (1 << 4)\n#define FLASH_PSIZE_32 (2 << 4)\n#define FLASH_PSIZE_64 (3 << 4)\n#define FLASH_FW       (1 << 6)\n#define FLASH_START    (1 << 7)\n\n/* FLASH_SR register bits */\n#define FLASH_BSY      (1 << 0)  /* Operation in progress */\n#define FLASH_QW       (1 << 2)  /* Operation queue in progress */\n#define FLASH_WRPERR   (1 << 17) /* Write protection error */\n#define FLASH_PGSERR   (1 << 18) /* Programming sequence error */\n#define FLASH_STRBERR  (1 << 19) /* Strobe error */\n#define FLASH_INCERR   (1 << 21) /* Inconsistency error */\n#define FLASH_OPERR    (1 << 22) /* Operation error */\n#define FLASH_RDPERR   (1 << 23) /* Read Protection error */\n#define FLASH_RDSERR   (1 << 24) /* Secure Protection error */\n#define FLASH_SNECCERR (1 << 25) /* Single ECC error */\n#define FLASH_DBECCERR (1 << 26) /* Double ECC error */\n\n#define FLASH_ERROR (FLASH_WRPERR | FLASH_PGSERR | FLASH_STRBERR | FLASH_INCERR | FLASH_OPERR | \\\n\t\t\t\t\t FLASH_RDPERR | FLASH_RDSERR | FLASH_SNECCERR | FLASH_DBECCERR)\n\n/* FLASH_OPTCR register bits */\n#define OPT_LOCK       (1 << 0)\n#define OPT_START      (1 << 1)\n\n/* FLASH_OPTSR register bits */\n#define OPT_BSY        (1 << 0)\n#define OPT_RDP_POS    8\n#define OPT_RDP_MASK   (0xff << OPT_RDP_POS)\n#define OPT_OPTCHANGEERR (1 << 30)\n\n/* FLASH_OPTCCR register bits */\n#define OPT_CLR_OPTCHANGEERR (1 << 30)\n\n/* register unlock keys */\n#define KEY1           0x45670123\n#define KEY2           0xCDEF89AB\n\n/* option register unlock key */\n#define OPTKEY1        0x08192A3B\n#define OPTKEY2        0x4C5D6E7F\n\n#define DBGMCU_IDCODE_REGISTER  0x5C001000\n#define FLASH_BANK0_ADDRESS     0x08000000\n#define FLASH_BANK1_ADDRESS     0x08100000\n#define FLASH_REG_BASE_B0       0x52002000\n#define FLASH_REG_BASE_B1       0x52002100\n\n/* Supported device IDs */\n#define DEVID_STM32H74_H75XX    0x450\n#define DEVID_STM32H7A_H7BXX    0x480\n#define DEVID_STM32H72_H73XX    0x483\n\nstruct stm32h7x_rev {\n\tuint16_t rev;\n\tconst char *str;\n};\n\n/* stm32h7x_part_info permits the store each device information and specificities.\n * the default unit is byte unless the suffix '_kb' is used. */\n\nstruct stm32h7x_part_info {\n\tuint16_t id;\n\tconst char *device_str;\n\tconst struct stm32h7x_rev *revs;\n\tsize_t num_revs;\n\tunsigned int page_size_kb;\n\tunsigned int block_size;    /* flash write word size in bytes */\n\tuint16_t max_flash_size_kb;\n\tbool has_dual_bank;\n\tuint16_t max_bank_size_kb;  /* Used when has_dual_bank is true */\n\tuint32_t fsize_addr;        /* Location of FSIZE register */\n\tuint32_t wps_group_size;    /* write protection group sectors' count */\n\tuint32_t wps_mask;\n\t/* function to compute flash_cr register values */\n\tuint32_t (*compute_flash_cr)(uint32_t cmd, int snb);\n};\n\nstruct stm32h7x_flash_bank {\n\tbool probed;\n\tuint32_t idcode;\n\tuint32_t user_bank_size;\n\tuint32_t flash_regs_base;    /* Address of flash reg controller */\n\tconst struct stm32h7x_part_info *part_info;\n};\n\nenum stm32h7x_opt_rdp {\n\tOPT_RDP_L0 = 0xaa,\n\tOPT_RDP_L1 = 0x00,\n\tOPT_RDP_L2 = 0xcc\n};\n\nstatic const struct stm32h7x_rev stm32h74_h75xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x1003, \"Y\" }, { 0x2001, \"X\"  }, { 0x2003, \"V\"  },\n};\n\nstatic const struct stm32h7x_rev stm32h7a_h7bxx_revs[] = {\n\t{ 0x1000, \"A\"},\n};\n\nstatic const struct stm32h7x_rev stm32h72_h73xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" },\n};\n\nstatic uint32_t stm32h74_h75xx_compute_flash_cr(uint32_t cmd, int snb)\n{\n\treturn cmd | (snb << 8);\n}\n\nstatic uint32_t stm32h7a_h7bxx_compute_flash_cr(uint32_t cmd, int snb)\n{\n\t/* save FW and START bits, to be right shifted by 2 bits later */\n\tconst uint32_t tmp = cmd & (FLASH_FW | FLASH_START);\n\n\t/* mask parallelism (ignored), FW and START bits */\n\tcmd &= ~(FLASH_PSIZE_64 | FLASH_FW | FLASH_START);\n\n\treturn cmd | (tmp >> 2) | (snb << 6);\n}\n\nstatic const struct stm32h7x_part_info stm32h7x_parts[] = {\n\t{\n\t.id\t\t\t\t\t= DEVID_STM32H74_H75XX,\n\t.revs\t\t\t\t= stm32h74_h75xx_revs,\n\t.num_revs\t\t\t= ARRAY_SIZE(stm32h74_h75xx_revs),\n\t.device_str\t\t\t= \"STM32H74x/75x\",\n\t.page_size_kb\t\t= 128,\n\t.block_size\t\t\t= 32,\n\t.max_flash_size_kb\t= 2048,\n\t.max_bank_size_kb\t= 1024,\n\t.has_dual_bank\t\t= true,\n\t.fsize_addr\t\t\t= 0x1FF1E880,\n\t.wps_group_size\t\t= 1,\n\t.wps_mask\t\t\t= 0xFF,\n\t.compute_flash_cr\t= stm32h74_h75xx_compute_flash_cr,\n\t},\n\t{\n\t.id\t\t\t\t\t= DEVID_STM32H7A_H7BXX,\n\t.revs\t\t\t\t= stm32h7a_h7bxx_revs,\n\t.num_revs\t\t\t= ARRAY_SIZE(stm32h7a_h7bxx_revs),\n\t.device_str\t\t\t= \"STM32H7Ax/7Bx\",\n\t.page_size_kb\t\t= 8,\n\t.block_size\t\t\t= 16,\n\t.max_flash_size_kb\t= 2048,\n\t.max_bank_size_kb\t= 1024,\n\t.has_dual_bank\t\t= true,\n\t.fsize_addr\t\t\t= 0x08FFF80C,\n\t.wps_group_size\t\t= 4,\n\t.wps_mask\t\t\t= 0xFFFFFFFF,\n\t.compute_flash_cr\t= stm32h7a_h7bxx_compute_flash_cr,\n\t},\n\t{\n\t.id\t\t\t\t\t= DEVID_STM32H72_H73XX,\n\t.revs\t\t\t\t= stm32h72_h73xx_revs,\n\t.num_revs\t\t\t= ARRAY_SIZE(stm32h72_h73xx_revs),\n\t.device_str\t\t\t= \"STM32H72x/73x\",\n\t.page_size_kb\t\t= 128,\n\t.block_size\t\t\t= 32,\n\t.max_flash_size_kb\t= 1024,\n\t.max_bank_size_kb\t= 1024,\n\t.has_dual_bank\t\t= false,\n\t.fsize_addr\t\t\t= 0x1FF1E880,\n\t.wps_group_size\t\t= 1,\n\t.wps_mask\t\t\t= 0xFF,\n\t.compute_flash_cr   = stm32h74_h75xx_compute_flash_cr,\n\t},\n};\n\n/* flash bank stm32x <base> <size> 0 0 <target#> */\n\nFLASH_BANK_COMMAND_HANDLER(stm32x_flash_bank_command)\n{\n\tstruct stm32h7x_flash_bank *stm32x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstm32x_info = malloc(sizeof(struct stm32h7x_flash_bank));\n\tbank->driver_priv = stm32x_info;\n\n\tstm32x_info->probed = false;\n\tstm32x_info->user_bank_size = bank->size;\n\n\treturn ERROR_OK;\n}\n\nstatic inline uint32_t stm32x_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)\n{\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\treturn reg_offset + stm32x_info->flash_regs_base;\n}\n\nstatic inline int stm32x_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)\n{\n\tuint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);\n\tint retval = target_read_u32(bank->target, reg_addr, value);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error while reading from address 0x%\" PRIx32, reg_addr);\n\n\treturn retval;\n}\n\nstatic inline int stm32x_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)\n{\n\tuint32_t reg_addr = stm32x_get_flash_reg(bank, reg_offset);\n\tint retval = target_write_u32(bank->target, reg_addr, value);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error while writing to address 0x%\" PRIx32, reg_addr);\n\n\treturn retval;\n}\n\nstatic inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\treturn stm32x_read_flash_reg(bank, FLASH_SR, status);\n}\n\nstatic int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\tint retval;\n\n\t/* wait for flash operations completion */\n\tfor (;;) {\n\t\tretval = stm32x_get_flash_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & FLASH_QW) == 0)\n\t\t\tbreak;\n\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"wait_flash_op_queue, time out expired, status: 0x%\" PRIx32, status);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tif (status & FLASH_WRPERR) {\n\t\tLOG_ERROR(\"wait_flash_op_queue, WRPERR detected\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t/* Clear error + EOP flags but report errors */\n\tif (status & FLASH_ERROR) {\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ERROR_FAIL;\n\t\t/* If this operation fails, we ignore it and report the original retval */\n\t\tstm32x_write_flash_reg(bank, FLASH_CCR, status);\n\t}\n\treturn retval;\n}\n\nstatic int stm32x_unlock_reg(struct flash_bank *bank)\n{\n\tuint32_t ctrl;\n\n\t/* first check if not already unlocked\n\t * otherwise writing on FLASH_KEYR will fail\n\t */\n\tint retval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & FLASH_LOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock flash registers for bank */\n\tretval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_write_flash_reg(bank, FLASH_KEYR, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_read_flash_reg(bank, FLASH_CR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & FLASH_LOCK) {\n\t\tLOG_ERROR(\"flash not unlocked STM32_FLASH_CRx: 0x%\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_unlock_option_reg(struct flash_bank *bank)\n{\n\tuint32_t ctrl;\n\n\tint retval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & OPT_LOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock option registers */\n\tretval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_write_flash_reg(bank, FLASH_OPTKEYR, OPTKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_read_flash_reg(bank, FLASH_OPTCR, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & OPT_LOCK) {\n\t\tLOG_ERROR(\"options not unlocked STM32_FLASH_OPTCR: 0x%\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic inline int stm32x_lock_reg(struct flash_bank *bank)\n{\n\treturn stm32x_write_flash_reg(bank, FLASH_CR, FLASH_LOCK);\n}\n\nstatic inline int stm32x_lock_option_reg(struct flash_bank *bank)\n{\n\treturn stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_LOCK);\n}\n\nstatic int stm32x_write_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)\n{\n\tint retval, retval2;\n\n\t/* unlock option bytes for modification */\n\tretval = stm32x_unlock_option_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_options_lock;\n\n\t/* write option bytes */\n\tretval = stm32x_write_flash_reg(bank, reg_offset, value);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_options_lock;\n\n\t/* Remove OPT error flag before programming */\n\tretval = stm32x_write_flash_reg(bank, FLASH_OPTCCR, OPT_CLR_OPTCHANGEERR);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_options_lock;\n\n\t/* start programming cycle */\n\tretval = stm32x_write_flash_reg(bank, FLASH_OPTCR, OPT_START);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_options_lock;\n\n\t/* wait for completion */\n\tint timeout = FLASH_ERASE_TIMEOUT;\n\tuint32_t status;\n\tfor (;;) {\n\t\tretval = stm32x_read_flash_reg(bank, FLASH_OPTSR_CUR, &status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"stm32x_options_program: failed to read FLASH_OPTSR_CUR\");\n\t\t\tgoto flash_options_lock;\n\t\t}\n\t\tif ((status & OPT_BSY) == 0)\n\t\t\tbreak;\n\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"waiting for OBL launch, time out expired, OPTSR: 0x%\" PRIx32, status);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto flash_options_lock;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\t/* check for failure */\n\tif (status & OPT_OPTCHANGEERR) {\n\t\tLOG_ERROR(\"error changing option bytes (OPTCHANGEERR=1)\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\nflash_options_lock:\n\tretval2 = stm32x_lock_option_reg(bank);\n\tif (retval2 != ERROR_OK)\n\t\tLOG_ERROR(\"error during the lock of flash options\");\n\n\treturn (retval == ERROR_OK) ? retval2 : retval;\n}\n\nstatic int stm32x_modify_option(struct flash_bank *bank, uint32_t reg_offset, uint32_t value, uint32_t mask)\n{\n\tuint32_t data;\n\n\tint retval = stm32x_read_flash_reg(bank, reg_offset, &data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdata = (data & ~mask) | (value & mask);\n\n\treturn stm32x_write_option(bank, reg_offset, data);\n}\n\nstatic int stm32x_protect_check(struct flash_bank *bank)\n{\n\tuint32_t protection;\n\n\t/* read 'write protection' settings */\n\tint retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"unable to read WPSN_CUR register\");\n\t\treturn retval;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_prot_blocks; i++)\n\t\tbank->prot_blocks[i].is_protected = protection & (1 << i) ? 0 : 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\tint retval, retval2;\n\n\tassert(first < bank->num_sectors);\n\tassert(last < bank->num_sectors);\n\n\tif (bank->target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = stm32x_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/*\n\tSector Erase\n\tTo erase a sector, follow the procedure below:\n\t1. Check that no Flash memory operation is ongoing by checking the QW bit in the\n\t  FLASH_SR register\n\t2. Set the SER bit and select the sector\n\t  you wish to erase (SNB) in the FLASH_CR register\n\t3. Set the STRT bit in the FLASH_CR register\n\t4. Wait for flash operations completion\n\t */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tLOG_DEBUG(\"erase sector %u\", i);\n\t\tretval = stm32x_write_flash_reg(bank, FLASH_CR,\n\t\t\t\tstm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64, i));\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error erase sector %u\", i);\n\t\t\tgoto flash_lock;\n\t\t}\n\t\tretval = stm32x_write_flash_reg(bank, FLASH_CR,\n\t\t\t\tstm32x_info->part_info->compute_flash_cr(FLASH_SER | FLASH_PSIZE_64 | FLASH_START, i));\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error erase sector %u\", i);\n\t\t\tgoto flash_lock;\n\t\t}\n\t\tretval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"erase time-out or operation error sector %u\", i);\n\t\t\tgoto flash_lock;\n\t\t}\n\t}\n\nflash_lock:\n\tretval2 = stm32x_lock_reg(bank);\n\tif (retval2 != ERROR_OK)\n\t\tLOG_ERROR(\"error during the lock of flash\");\n\n\treturn (retval == ERROR_OK) ? retval2 : retval;\n}\n\nstatic int stm32x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\tuint32_t protection;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* read 'write protection' settings */\n\tint retval = stm32x_read_flash_reg(bank, FLASH_WPSN_CUR, &protection);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"unable to read WPSN_CUR register\");\n\t\treturn retval;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tif (set)\n\t\t\tprotection &= ~(1 << i);\n\t\telse\n\t\t\tprotection |= (1 << i);\n\t}\n\n\t/* apply WRPSN mask */\n\tprotection &= stm32x_info->part_info->wps_mask;\n\n\tLOG_DEBUG(\"stm32x_protect, option_bytes written WPSN 0x%\" PRIx32, protection);\n\n\t/* apply new option value */\n\treturn stm32x_write_option(bank, FLASH_WPSN_PRG, protection);\n}\n\nstatic int stm32x_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\t/*\n\t * If the size of the data part of the buffer is not a multiple of .block_size, we get\n\t * \"corrupted fifo read\" pointer in target_run_flash_async_algorithm()\n\t */\n\tuint32_t data_size = 512 * stm32x_info->part_info->block_size;\n\tuint32_t buffer_size = 8 + data_size;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\tstatic const uint8_t stm32x_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/stm32/stm32h7x.inc\"\n\t};\n\n\tif (target_alloc_working_area(target, sizeof(stm32x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(stm32x_flash_write_code),\n\t\t\tstm32x_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tdata_size /= 2;\n\t\tbuffer_size = 8 + data_size;\n\t\tif (data_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"target_alloc_working_area_try : buffer_size -> 0x%\" PRIx32, buffer_size);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t\t/* buffer start, status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t\t/* buffer end */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t\t/* target address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t\t/* count of words (word size = .block_size (bytes) */\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\t\t/* word size in bytes */\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_OUT);\t\t/* flash reg base */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\tbuf_set_u32(reg_params[4].value, 0, 32, stm32x_info->part_info->block_size);\n\tbuf_set_u32(reg_params[5].value, 0, 32, stm32x_info->flash_regs_base);\n\n\tretval = target_run_flash_async_algorithm(target,\n\t\t\t\t\t\t  buffer,\n\t\t\t\t\t\t  count,\n\t\t\t\t\t\t  stm32x_info->part_info->block_size,\n\t\t\t\t\t\t  0, NULL,\n\t\t\t\t\t\t  ARRAY_SIZE(reg_params), reg_params,\n\t\t\t\t\t\t  source->address, source->size,\n\t\t\t\t\t\t  write_algorithm->address, 0,\n\t\t\t\t\t\t  &armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"error executing stm32h7x flash write algorithm\");\n\n\t\tuint32_t flash_sr = buf_get_u32(reg_params[0].value, 0, 32);\n\n\t\tif (flash_sr & FLASH_WRPERR)\n\t\t\tLOG_ERROR(\"flash memory write protected\");\n\n\t\tif ((flash_sr & FLASH_ERROR) != 0) {\n\t\t\tLOG_ERROR(\"flash write failed, FLASH_SR = 0x%08\" PRIx32, flash_sr);\n\t\t\t/* Clear error + EOP flags but report errors */\n\t\t\tstm32x_write_flash_reg(bank, FLASH_CCR, flash_sr);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\treturn retval;\n}\n\nstatic int stm32x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\tuint32_t address = bank->base + offset;\n\tint retval, retval2;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* should be enforced via bank->write_start_alignment */\n\tassert(!(offset % stm32x_info->part_info->block_size));\n\n\t/* should be enforced via bank->write_end_alignment */\n\tassert(!(count % stm32x_info->part_info->block_size));\n\n\tretval = stm32x_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tuint32_t blocks_remaining = count / stm32x_info->part_info->block_size;\n\n\t/* multiple words (n * .block_size) to be programmed in block */\n\tif (blocks_remaining) {\n\t\tretval = stm32x_write_block(bank, buffer, offset, blocks_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) dword accesses */\n\t\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += blocks_remaining * stm32x_info->part_info->block_size;\n\t\t\taddress += blocks_remaining * stm32x_info->part_info->block_size;\n\t\t\tblocks_remaining = 0;\n\t\t}\n\t\tif ((retval != ERROR_OK) && (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE))\n\t\t\tgoto flash_lock;\n\t}\n\n\t/*\n\tStandard programming\n\tThe Flash memory programming sequence is as follows:\n\t1. Check that no main Flash memory operation is ongoing by checking the QW bit in the\n\t   FLASH_SR register.\n\t2. Set the PG bit in the FLASH_CR register\n\t3. 8 x Word access (or Force Write FW)\n\t4. Wait for flash operations completion\n\t*/\n\twhile (blocks_remaining > 0) {\n\t\tretval = stm32x_write_flash_reg(bank, FLASH_CR,\n\t\t\t\tstm32x_info->part_info->compute_flash_cr(FLASH_PG | FLASH_PSIZE_64, 0));\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\n\t\tretval = target_write_buffer(target, address, stm32x_info->part_info->block_size, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\n\t\tretval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto flash_lock;\n\n\t\tbuffer += stm32x_info->part_info->block_size;\n\t\taddress += stm32x_info->part_info->block_size;\n\t\tblocks_remaining--;\n\t}\n\nflash_lock:\n\tretval2 = stm32x_lock_reg(bank);\n\tif (retval2 != ERROR_OK)\n\t\tLOG_ERROR(\"error during the lock of flash\");\n\n\treturn (retval == ERROR_OK) ? retval2 : retval;\n}\n\nstatic int stm32x_read_id_code(struct flash_bank *bank, uint32_t *id)\n{\n\t/* read stm32 device id register */\n\tint retval = target_read_u32(bank->target, DBGMCU_IDCODE_REGISTER, id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\tuint16_t flash_size_in_kb;\n\tuint32_t device_id;\n\n\tstm32x_info->probed = false;\n\tstm32x_info->part_info = NULL;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tint retval = stm32x_read_id_code(bank, &stm32x_info->idcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"device id = 0x%08\" PRIx32, stm32x_info->idcode);\n\n\tdevice_id = stm32x_info->idcode & 0xfff;\n\n\tfor (unsigned int n = 0; n < ARRAY_SIZE(stm32h7x_parts); n++) {\n\t\tif (device_id == stm32h7x_parts[n].id)\n\t\t\tstm32x_info->part_info = &stm32h7x_parts[n];\n\t}\n\tif (!stm32x_info->part_info) {\n\t\tLOG_WARNING(\"Cannot identify target as a STM32H7xx family.\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_INFO(\"Device: %s\", stm32x_info->part_info->device_str);\n\t}\n\n\t/* update the address of controller */\n\tif (bank->base == FLASH_BANK0_ADDRESS)\n\t\tstm32x_info->flash_regs_base = FLASH_REG_BASE_B0;\n\telse if (bank->base == FLASH_BANK1_ADDRESS)\n\t\tstm32x_info->flash_regs_base = FLASH_REG_BASE_B1;\n\telse {\n\t\tLOG_WARNING(\"Flash register base not defined for bank %u\", bank->bank_number);\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"flash_regs_base: 0x%\" PRIx32, stm32x_info->flash_regs_base);\n\n\t/* get flash size from target */\n\t/* STM32H74x/H75x, the second core (Cortex-M4) cannot read the flash size */\n\tretval = ERROR_FAIL;\n\tif (device_id == DEVID_STM32H74_H75XX\n\t\t\t&& cortex_m_get_partno_safe(target) == CORTEX_M4_PARTNO)\n\t\tLOG_WARNING(\"%s cannot read the flash size register\", target_name(target));\n\telse\n\t\tretval = target_read_u16(target, stm32x_info->part_info->fsize_addr, &flash_size_in_kb);\n\n\tif (retval != ERROR_OK) {\n\t\t/* read error when device has invalid value, set max flash size */\n\t\tflash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;\n\t\tLOG_INFO(\"assuming %\" PRIu16 \"k flash\", flash_size_in_kb);\n\t} else\n\t\tLOG_INFO(\"flash size probed value %\" PRIu16 \"k\", flash_size_in_kb);\n\n\t/* setup bank size */\n\tconst uint32_t bank1_base = FLASH_BANK0_ADDRESS;\n\tconst uint32_t bank2_base = bank1_base + stm32x_info->part_info->max_bank_size_kb * 1024;\n\tbool has_dual_bank = stm32x_info->part_info->has_dual_bank;\n\n\tswitch (device_id) {\n\tcase DEVID_STM32H74_H75XX:\n\tcase DEVID_STM32H7A_H7BXX:\n\t\t/* For STM32H74x/75x and STM32H7Ax/Bx\n\t\t *  - STM32H7xxxI devices contains dual bank, 1 Mbyte each\n\t\t *  - STM32H7xxxG devices contains dual bank, 512 Kbyte each\n\t\t *  - STM32H7xxxB devices contains single bank, 128 Kbyte\n\t\t *  - the second bank starts always from 0x08100000\n\t\t */\n\t\tif (flash_size_in_kb == 128)\n\t\t\thas_dual_bank = false;\n\t\telse\n\t\t\t/* flash size is 2M or 1M */\n\t\t\tflash_size_in_kb /= 2;\n\t\tbreak;\n\tcase DEVID_STM32H72_H73XX:\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"unsupported device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (has_dual_bank) {\n\t\tLOG_INFO(\"STM32H7 flash has dual banks\");\n\t\tif (bank->base != bank1_base && bank->base != bank2_base) {\n\t\t\tLOG_ERROR(\"STM32H7 flash bank base address config is incorrect. \"\n\t\t\t\t\tTARGET_ADDR_FMT \" but should rather be 0x%\" PRIx32 \" or 0x%\" PRIx32,\n\t\t\t\t\tbank->base, bank1_base, bank2_base);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tLOG_INFO(\"STM32H7 flash has a single bank\");\n\t\tif (bank->base == bank2_base) {\n\t\t\tLOG_ERROR(\"this device has a single bank only\");\n\t\t\treturn ERROR_FAIL;\n\t\t} else if (bank->base != bank1_base) {\n\t\t\tLOG_ERROR(\"STM32H7 flash bank base address config is incorrect. \"\n\t\t\t\t\tTARGET_ADDR_FMT \" but should be 0x%\" PRIx32,\n\t\t\t\t\tbank->base, bank1_base);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tLOG_INFO(\"Bank (%u) size is %\" PRIu16 \" kb, base address is \" TARGET_ADDR_FMT,\n\t\tbank->bank_number, flash_size_in_kb, bank->base);\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have an invalid flash size register value */\n\tif (stm32x_info->user_bank_size) {\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size\");\n\t\tflash_size_in_kb = stm32x_info->user_bank_size / 1024;\n\t} else if (flash_size_in_kb == 0xffff) {\n\t\t/* die flash size */\n\t\tflash_size_in_kb = stm32x_info->part_info->max_flash_size_kb;\n\t}\n\n\t/* did we assign flash size? */\n\tassert(flash_size_in_kb != 0xffff);\n\tbank->size = flash_size_in_kb * 1024;\n\tbank->write_start_alignment = stm32x_info->part_info->block_size;\n\tbank->write_end_alignment = stm32x_info->part_info->block_size;\n\n\t/* setup sectors */\n\tbank->num_sectors = flash_size_in_kb / stm32x_info->part_info->page_size_kb;\n\tassert(bank->num_sectors > 0);\n\n\tfree(bank->sectors);\n\n\tbank->sectors = alloc_block_array(0, stm32x_info->part_info->page_size_kb * 1024,\n\t\t\tbank->num_sectors);\n\n\tif (!bank->sectors) {\n\t\tLOG_ERROR(\"failed to allocate bank sectors\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* setup protection blocks */\n\tconst uint32_t wpsn = stm32x_info->part_info->wps_group_size;\n\tassert(bank->num_sectors % wpsn == 0);\n\n\tbank->num_prot_blocks = bank->num_sectors / wpsn;\n\tassert(bank->num_prot_blocks > 0);\n\n\tfree(bank->prot_blocks);\n\n\tbank->prot_blocks = alloc_block_array(0, stm32x_info->part_info->page_size_kb * wpsn * 1024,\n\t\t\tbank->num_prot_blocks);\n\n\tif (!bank->prot_blocks) {\n\t\tLOG_ERROR(\"failed to allocate bank prot_block\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstm32x_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_auto_probe(struct flash_bank *bank)\n{\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (stm32x_info->probed)\n\t\treturn ERROR_OK;\n\n\treturn stm32x_probe(bank);\n}\n\n/* This method must return a string displaying information about the bank */\nstatic int stm32x_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\tconst struct stm32h7x_part_info *info = stm32x_info->part_info;\n\n\tif (!stm32x_info->probed) {\n\t\tint retval = stm32x_probe(bank);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print_sameline(cmd, \"Unable to find bank information.\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tif (info) {\n\t\tconst char *rev_str = NULL;\n\t\tuint16_t rev_id = stm32x_info->idcode >> 16;\n\n\t\tfor (unsigned int i = 0; i < info->num_revs; i++)\n\t\t\tif (rev_id == info->revs[i].rev)\n\t\t\t\trev_str = info->revs[i].str;\n\n\t\tif (rev_str) {\n\t\t\tcommand_print_sameline(cmd, \"%s - Rev: %s\",\n\t\t\t\tstm32x_info->part_info->device_str, rev_str);\n\t\t} else {\n\t\t\tcommand_print_sameline(cmd,\n\t\t\t\t \"%s - Rev: unknown (0x%04\" PRIx16 \")\",\n\t\t\t\tstm32x_info->part_info->device_str, rev_id);\n\t\t}\n\t} else {\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as a STM32H7x\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stm32x_set_rdp(struct flash_bank *bank, enum stm32h7x_opt_rdp new_rdp)\n{\n\tstruct target *target = bank->target;\n\tuint32_t optsr, cur_rdp;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_read_flash_reg(bank, FLASH_OPTSR_PRG, &optsr);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"unable to read FLASH_OPTSR_PRG register\");\n\t\treturn retval;\n\t}\n\n\t/* get current RDP, and check if there is a change */\n\tcur_rdp = (optsr & OPT_RDP_MASK) >> OPT_RDP_POS;\n\tif (new_rdp == cur_rdp) {\n\t\tLOG_INFO(\"the requested RDP value is already programmed\");\n\t\treturn ERROR_OK;\n\t}\n\n\tswitch (new_rdp) {\n\tcase OPT_RDP_L0:\n\t\tLOG_WARNING(\"unlocking the entire flash device\");\n\t\tbreak;\n\tcase OPT_RDP_L1:\n\t\tLOG_WARNING(\"locking the entire flash device\");\n\t\tbreak;\n\tcase OPT_RDP_L2:\n\t\tLOG_WARNING(\"locking the entire flash device, irreversible\");\n\t\tbreak;\n\t}\n\n\t/* apply new RDP */\n\toptsr = (optsr & ~OPT_RDP_MASK) | (new_rdp << OPT_RDP_POS);\n\n\t/* apply new option value */\n\treturn stm32x_write_option(bank, FLASH_OPTSR_PRG, optsr);\n}\n\nCOMMAND_HANDLER(stm32x_handle_lock_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_set_rdp(bank, OPT_RDP_L1);\n\n\tif (retval != ERROR_OK)\n\t\tcommand_print(CMD, \"%s failed to lock device\", bank->driver->name);\n\telse\n\t\tcommand_print(CMD, \"%s locked\", bank->driver->name);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_unlock_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_set_rdp(bank, OPT_RDP_L0);\n\n\tif (retval != ERROR_OK)\n\t\tcommand_print(CMD, \"%s failed to unlock device\", bank->driver->name);\n\telse\n\t\tcommand_print(CMD, \"%s unlocked\", bank->driver->name);\n\n\treturn retval;\n}\n\nstatic int stm32x_mass_erase(struct flash_bank *bank)\n{\n\tint retval, retval2;\n\tstruct target *target = bank->target;\n\tstruct stm32h7x_flash_bank *stm32x_info = bank->driver_priv;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32x_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\t/* mass erase flash memory bank */\n\tretval = stm32x_write_flash_reg(bank, FLASH_CR,\n\t\t\tstm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64, 0));\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tretval = stm32x_write_flash_reg(bank, FLASH_CR,\n\t\t\tstm32x_info->part_info->compute_flash_cr(FLASH_BER | FLASH_PSIZE_64 | FLASH_START, 0));\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\n\tretval = stm32x_wait_flash_op_queue(bank, 30000);\n\tif (retval != ERROR_OK)\n\t\tgoto flash_lock;\n\nflash_lock:\n\tretval2 = stm32x_lock_reg(bank);\n\tif (retval2 != ERROR_OK)\n\t\tLOG_ERROR(\"error during the lock of flash\");\n\n\treturn (retval == ERROR_OK) ? retval2 : retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"stm32h7x mass_erase <bank>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32x_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"stm32h7x mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"stm32h7x mass erase failed\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_option_read_command)\n{\n\tif (CMD_ARGC < 2) {\n\t\tcommand_print(CMD, \"stm32h7x option_read <bank> <option_reg offset>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t reg_offset, value;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);\n\tretval = stm32x_read_flash_reg(bank, reg_offset, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"Option Register: <0x%\" PRIx32 \"> = 0x%\" PRIx32,\n\t\t\tstm32x_get_flash_reg(bank, reg_offset), value);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32x_handle_option_write_command)\n{\n\tif (CMD_ARGC < 3) {\n\t\tcommand_print(CMD, \"stm32h7x option_write <bank> <option_reg offset> <value> [mask]\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t reg_offset, value, mask = 0xffffffff;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);\n\tif (CMD_ARGC > 3)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], mask);\n\n\treturn stm32x_modify_option(bank, reg_offset, value, mask);\n}\n\nstatic const struct command_registration stm32h7x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"lock\",\n\t\t.handler = stm32x_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lock entire flash device.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = stm32x_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Unlock entire protected flash device.\",\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stm32x_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"option_read\",\n\t\t.handler = stm32x_handle_option_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id reg_offset\",\n\t\t.help = \"Read and display device option bytes.\",\n\t},\n\t{\n\t\t.name = \"option_write\",\n\t\t.handler = stm32x_handle_option_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id reg_offset value [mask]\",\n\t\t.help = \"Write device option bit fields with provided value.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm32h7x_command_handlers[] = {\n\t{\n\t\t.name = \"stm32h7x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm32h7x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm32h7x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stm32h7x_flash = {\n\t.name = \"stm32h7x\",\n\t.commands = stm32h7x_command_handlers,\n\t.flash_bank_command = stm32x_flash_bank_command,\n\t.erase = stm32x_erase,\n\t.protect = stm32x_protect,\n\t.write = stm32x_write,\n\t.read = default_flash_read,\n\t.probe = stm32x_probe,\n\t.auto_probe = stm32x_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stm32x_protect_check,\n\t.info = stm32x_get_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32l4x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Uwe Bonnes                                      *\n *   bon@elektron.ikp.physik.tu-darmstadt.de                               *\n *                                                                         *\n *   Copyright (C) 2019 by Tarek Bochkati for STMicroelectronics           *\n *   tarek.bouchkati@gmail.com                                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/align.h>\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <target/algorithm.h>\n#include <target/arm_adi_v5.h>\n#include <target/cortex_m.h>\n#include \"stm32l4x.h\"\n\n/* STM32L4xxx series for reference.\n *\n * RM0351 (STM32L4x5/STM32L4x6)\n * http://www.st.com/resource/en/reference_manual/dm00083560.pdf\n *\n * RM0394 (STM32L43x/44x/45x/46x)\n * http://www.st.com/resource/en/reference_manual/dm00151940.pdf\n *\n * RM0432 (STM32L4R/4Sxx)\n * http://www.st.com/resource/en/reference_manual/dm00310109.pdf\n *\n * STM32L476RG Datasheet (for erase timing)\n * http://www.st.com/resource/en/datasheet/stm32l476rg.pdf\n *\n * The RM0351 devices have normally two banks, but on 512 and 256 kiB devices\n * an option byte is available to map all sectors to the first bank.\n * Both STM32 banks are treated as one OpenOCD bank, as other STM32 devices\n * handlers do!\n *\n * RM0394 devices have a single bank only.\n *\n * RM0432 devices have single and dual bank operating modes.\n *  - for STM32L4R/Sxx the FLASH size is 2Mbyte or 1Mbyte.\n *  - for STM32L4P/Q5x the FLASH size is 1Mbyte or 512Kbyte.\n * Bank page (sector) size is 4Kbyte (dual mode) or 8Kbyte (single mode).\n *\n * Bank mode is controlled by two different bits in option bytes register.\n *  - for STM32L4R/Sxx\n *    In 2M FLASH devices bit 22 (DBANK) controls Dual Bank mode.\n *    In 1M FLASH devices bit 21 (DB1M) controls Dual Bank mode.\n *  - for STM32L4P5/Q5x\n *    In 1M FLASH devices bit 22 (DBANK) controls Dual Bank mode.\n *    In 512K FLASH devices bit 21 (DB512K) controls Dual Bank mode.\n */\n\n/* STM32WBxxx series for reference.\n *\n * RM0434 (STM32WB55/WB35x)\n * http://www.st.com/resource/en/reference_manual/dm00318631.pdf\n *\n * RM0471 (STM32WB50/WB30x)\n * http://www.st.com/resource/en/reference_manual/dm00622834.pdf\n *\n * RM0473 (STM32WB15x)\n * http://www.st.com/resource/en/reference_manual/dm00649196.pdf\n *\n * RM0478 (STM32WB10x)\n * http://www.st.com/resource/en/reference_manual/dm00689203.pdf\n */\n\n/* STM32WLxxx series for reference.\n *\n * RM0461 (STM32WLEx)\n * http://www.st.com/resource/en/reference_manual/dm00530369.pdf\n *\n * RM0453 (STM32WL5x)\n * http://www.st.com/resource/en/reference_manual/dm00451556.pdf\n */\n\n/* STM32C0xxx series for reference.\n *\n * RM0490 (STM32C0x1)\n * http://www.st.com/resource/en/reference_manual/dm00781702.pdf\n */\n\n/* STM32G0xxx series for reference.\n *\n * RM0444 (STM32G0x1)\n * http://www.st.com/resource/en/reference_manual/dm00371828.pdf\n *\n * RM0454 (STM32G0x0)\n * http://www.st.com/resource/en/reference_manual/dm00463896.pdf\n */\n\n/* STM32G4xxx series for reference.\n *\n * RM0440 (STM32G43x/44x/47x/48x/49x/4Ax)\n * http://www.st.com/resource/en/reference_manual/dm00355726.pdf\n *\n * Cat. 2 devices have single bank only, page size is 2kByte.\n *\n * Cat. 3 devices have single and dual bank operating modes,\n * Page size is 2kByte (dual mode) or 4kByte (single mode).\n *\n * Bank mode is controlled by bit 22 (DBANK) in option bytes register.\n * Both banks are treated as a single OpenOCD bank.\n *\n * Cat. 4 devices have single bank only, page size is 2kByte.\n */\n\n/* STM32L5xxx series for reference.\n *\n * RM0428 (STM32L552xx/STM32L562xx)\n * http://www.st.com/resource/en/reference_manual/dm00346336.pdf\n */\n\n/* Erase time can be as high as 25ms, 10x this and assume it's toast... */\n\n#define FLASH_ERASE_TIMEOUT 250\n#define FLASH_WRITE_TIMEOUT 50\n\n\n/* relevant STM32L4 flags ****************************************************/\n#define F_NONE              0\n/* this flag indicates if the device flash is with dual bank architecture */\n#define F_HAS_DUAL_BANK     BIT(0)\n/* this flags is used for dual bank devices only, it indicates if the\n * 4 WRPxx are usable if the device is configured in single-bank mode */\n#define F_USE_ALL_WRPXX     BIT(1)\n/* this flag indicates if the device embeds a TrustZone security feature */\n#define F_HAS_TZ            BIT(2)\n/* this flag indicates if the device has the same flash registers as STM32L5 */\n#define F_HAS_L5_FLASH_REGS BIT(3)\n/* this flag indicates that programming should be done in quad-word\n * the default programming word size is double-word */\n#define F_QUAD_WORD_PROG    BIT(4)\n/* end of STM32L4 flags ******************************************************/\n\n\nenum stm32l4_flash_reg_index {\n\tSTM32_FLASH_ACR_INDEX,\n\tSTM32_FLASH_KEYR_INDEX,\n\tSTM32_FLASH_OPTKEYR_INDEX,\n\tSTM32_FLASH_SR_INDEX,\n\tSTM32_FLASH_CR_INDEX,\n\t/* for some devices like STM32WL5x, the CPU2 have a dedicated C2CR register w/o LOCKs,\n\t * so it uses the C2CR for flash operations and CR for checking locks and locking */\n\tSTM32_FLASH_CR_WLK_INDEX, /* FLASH_CR_WITH_LOCK */\n\tSTM32_FLASH_OPTR_INDEX,\n\tSTM32_FLASH_WRP1AR_INDEX,\n\tSTM32_FLASH_WRP1BR_INDEX,\n\tSTM32_FLASH_WRP2AR_INDEX,\n\tSTM32_FLASH_WRP2BR_INDEX,\n\tSTM32_FLASH_REG_INDEX_NUM,\n};\n\nenum stm32l4_rdp {\n\tRDP_LEVEL_0   = 0xAA,\n\tRDP_LEVEL_0_5 = 0x55, /* for devices with TrustZone enabled */\n\tRDP_LEVEL_1   = 0x00,\n\tRDP_LEVEL_2   = 0xCC\n};\n\nstatic const uint32_t stm32l4_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {\n\t[STM32_FLASH_ACR_INDEX]      = 0x000,\n\t[STM32_FLASH_KEYR_INDEX]     = 0x008,\n\t[STM32_FLASH_OPTKEYR_INDEX]  = 0x00C,\n\t[STM32_FLASH_SR_INDEX]       = 0x010,\n\t[STM32_FLASH_CR_INDEX]       = 0x014,\n\t[STM32_FLASH_OPTR_INDEX]     = 0x020,\n\t[STM32_FLASH_WRP1AR_INDEX]   = 0x02C,\n\t[STM32_FLASH_WRP1BR_INDEX]   = 0x030,\n\t[STM32_FLASH_WRP2AR_INDEX]   = 0x04C,\n\t[STM32_FLASH_WRP2BR_INDEX]   = 0x050,\n};\n\nstatic const uint32_t stm32wl_cpu2_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {\n\t[STM32_FLASH_ACR_INDEX]      = 0x000,\n\t[STM32_FLASH_KEYR_INDEX]     = 0x008,\n\t[STM32_FLASH_OPTKEYR_INDEX]  = 0x010,\n\t[STM32_FLASH_SR_INDEX]       = 0x060,\n\t[STM32_FLASH_CR_INDEX]       = 0x064,\n\t[STM32_FLASH_CR_WLK_INDEX]   = 0x014,\n\t[STM32_FLASH_OPTR_INDEX]     = 0x020,\n\t[STM32_FLASH_WRP1AR_INDEX]   = 0x02C,\n\t[STM32_FLASH_WRP1BR_INDEX]   = 0x030,\n};\n\nstatic const uint32_t stm32l5_ns_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {\n\t[STM32_FLASH_ACR_INDEX]      = 0x000,\n\t[STM32_FLASH_KEYR_INDEX]     = 0x008, /* NSKEYR */\n\t[STM32_FLASH_OPTKEYR_INDEX]  = 0x010,\n\t[STM32_FLASH_SR_INDEX]       = 0x020, /* NSSR */\n\t[STM32_FLASH_CR_INDEX]       = 0x028, /* NSCR */\n\t[STM32_FLASH_OPTR_INDEX]     = 0x040,\n\t[STM32_FLASH_WRP1AR_INDEX]   = 0x058,\n\t[STM32_FLASH_WRP1BR_INDEX]   = 0x05C,\n\t[STM32_FLASH_WRP2AR_INDEX]   = 0x068,\n\t[STM32_FLASH_WRP2BR_INDEX]   = 0x06C,\n};\n\nstatic const uint32_t stm32l5_s_flash_regs[STM32_FLASH_REG_INDEX_NUM] = {\n\t[STM32_FLASH_ACR_INDEX]      = 0x000,\n\t[STM32_FLASH_KEYR_INDEX]     = 0x00C, /* SECKEYR */\n\t[STM32_FLASH_OPTKEYR_INDEX]  = 0x010,\n\t[STM32_FLASH_SR_INDEX]       = 0x024, /* SECSR */\n\t[STM32_FLASH_CR_INDEX]       = 0x02C, /* SECCR */\n\t[STM32_FLASH_OPTR_INDEX]     = 0x040,\n\t[STM32_FLASH_WRP1AR_INDEX]   = 0x058,\n\t[STM32_FLASH_WRP1BR_INDEX]   = 0x05C,\n\t[STM32_FLASH_WRP2AR_INDEX]   = 0x068,\n\t[STM32_FLASH_WRP2BR_INDEX]   = 0x06C,\n};\n\nstruct stm32l4_rev {\n\tconst uint16_t rev;\n\tconst char *str;\n};\n\nstruct stm32l4_part_info {\n\tuint16_t id;\n\tconst char *device_str;\n\tconst struct stm32l4_rev *revs;\n\tconst size_t num_revs;\n\tconst uint16_t max_flash_size_kb;\n\tconst uint32_t flags; /* one bit per feature, see STM32L4 flags: macros F_XXX */\n\tconst uint32_t flash_regs_base;\n\tconst uint32_t fsize_addr;\n\tconst uint32_t otp_base;\n\tconst uint32_t otp_size;\n};\n\nstruct stm32l4_flash_bank {\n\tbool probed;\n\tuint32_t idcode;\n\tunsigned int bank1_sectors;\n\tbool dual_bank_mode;\n\tint hole_sectors;\n\tuint32_t user_bank_size;\n\tuint32_t data_width;\n\tuint32_t cr_bker_mask;\n\tuint32_t sr_bsy_mask;\n\tuint32_t wrpxxr_mask;\n\tconst struct stm32l4_part_info *part_info;\n\tuint32_t flash_regs_base;\n\tconst uint32_t *flash_regs;\n\tbool otp_enabled;\n\tenum stm32l4_rdp rdp;\n\tbool tzen;\n\tuint32_t optr;\n};\n\nenum stm32_bank_id {\n\tSTM32_BANK1,\n\tSTM32_BANK2,\n\tSTM32_ALL_BANKS\n};\n\nstruct stm32l4_wrp {\n\tenum stm32l4_flash_reg_index reg_idx;\n\tuint32_t value;\n\tbool used;\n\tint first;\n\tint last;\n\tint offset;\n};\n\n/* human readable list of families this drivers supports (sorted alphabetically) */\nstatic const char *device_families = \"STM32C0/G0/G4/L4/L4+/L5/U5/WB/WL\";\n\nstatic const struct stm32l4_rev stm32l47_l48xx_revs[] = {\n\t{ 0x1000, \"1\" }, { 0x1001, \"2\" }, { 0x1003, \"3\" }, { 0x1007, \"4\" }\n};\n\nstatic const struct stm32l4_rev stm32l43_l44xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x2001, \"Y\" },\n};\n\n\nstatic const struct stm32l4_rev stm32c01xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32c03xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32g05_g06xx_revs[] = {\n\t{ 0x1000, \"A\" },\n};\n\nstatic const struct stm32l4_rev stm32_g07_g08xx_revs[] = {\n\t{ 0x1000, \"A/Z\" } /* A and Z, no typo in RM! */, { 0x2000, \"B\" },\n};\n\nstatic const struct stm32l4_rev stm32l49_l4axx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" },\n};\n\nstatic const struct stm32l4_rev stm32l45_l46xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x2001, \"Y\" },\n};\n\nstatic const struct stm32l4_rev stm32l41_l42xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x2001, \"Y\" },\n};\n\nstatic const struct stm32l4_rev stm32g03_g04xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x2000, \"B\" },\n};\n\nstatic const struct stm32l4_rev stm32g0b_g0cxx_revs[] = {\n\t{ 0x1000, \"A\" },\n};\n\nstatic const struct stm32l4_rev stm32g43_g44xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" }, { 0x2001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32g47_g48xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" }, { 0x2001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32l4r_l4sxx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x1003, \"Y\" }, { 0x100F, \"W\" },\n\t{ 0x101F, \"V\" },\n};\n\nstatic const struct stm32l4_rev stm32l4p_l4qxx_revs[] = {\n\t{ 0x1001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32l55_l56xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" }, { 0x2001, \"Z\" },\n};\n\nstatic const struct stm32l4_rev stm32g49_g4axx_revs[] = {\n\t{ 0x1000, \"A\" },\n};\n\nstatic const struct stm32l4_rev stm32u57_u58xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1001, \"Z\" }, { 0x1003, \"Y\" }, { 0x2000, \"B\" },\n\t{ 0x2001, \"X\" }, { 0x3000, \"C\" },\n};\n\nstatic const struct stm32l4_rev stm32wb1xx_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" },\n};\n\nstatic const struct stm32l4_rev stm32wb5xx_revs[] = {\n\t{ 0x2001, \"2.1\" },\n};\n\nstatic const struct stm32l4_rev stm32wb3xx_revs[] = {\n\t{ 0x1000, \"A\" },\n};\n\nstatic const struct stm32l4_rev stm32wle_wl5xx_revs[] = {\n\t{ 0x1000, \"1.0\" },\n};\n\nstatic const struct stm32l4_part_info stm32l4_parts[] = {\n\t{\n\t  .id                    = DEVID_STM32L47_L48XX,\n\t  .revs                  = stm32l47_l48xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l47_l48xx_revs),\n\t  .device_str            = \"STM32L47/L48xx\",\n\t  .max_flash_size_kb     = 1024,\n\t  .flags                 = F_HAS_DUAL_BANK,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L43_L44XX,\n\t  .revs                  = stm32l43_l44xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l43_l44xx_revs),\n\t  .device_str            = \"STM32L43/L44xx\",\n\t  .max_flash_size_kb     = 256,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32C01XX,\n\t  .revs                  = stm32c01xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32c01xx_revs),\n\t  .device_str            = \"STM32C01xx\",\n\t  .max_flash_size_kb     = 32,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75A0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32C03XX,\n\t  .revs                  = stm32c03xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32c03xx_revs),\n\t  .device_str            = \"STM32C03xx\",\n\t  .max_flash_size_kb     = 32,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75A0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G05_G06XX,\n\t  .revs                  = stm32g05_g06xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g05_g06xx_revs),\n\t  .device_str            = \"STM32G05/G06xx\",\n\t  .max_flash_size_kb     = 64,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G07_G08XX,\n\t  .revs                  = stm32_g07_g08xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32_g07_g08xx_revs),\n\t  .device_str            = \"STM32G07/G08xx\",\n\t  .max_flash_size_kb     = 128,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L49_L4AXX,\n\t  .revs                  = stm32l49_l4axx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l49_l4axx_revs),\n\t  .device_str            = \"STM32L49/L4Axx\",\n\t  .max_flash_size_kb     = 1024,\n\t  .flags                 = F_HAS_DUAL_BANK,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L45_L46XX,\n\t  .revs                  = stm32l45_l46xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l45_l46xx_revs),\n\t  .device_str            = \"STM32L45/L46xx\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L41_L42XX,\n\t  .revs                  = stm32l41_l42xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l41_l42xx_revs),\n\t  .device_str            = \"STM32L41/L42xx\",\n\t  .max_flash_size_kb     = 128,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G03_G04XX,\n\t  .revs                  = stm32g03_g04xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g03_g04xx_revs),\n\t  .device_str            = \"STM32G03x/G04xx\",\n\t  .max_flash_size_kb     = 64,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G0B_G0CXX,\n\t  .revs                  = stm32g0b_g0cxx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g0b_g0cxx_revs),\n\t  .device_str            = \"STM32G0B/G0Cx\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_HAS_DUAL_BANK,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G43_G44XX,\n\t  .revs                  = stm32g43_g44xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g43_g44xx_revs),\n\t  .device_str            = \"STM32G43/G44xx\",\n\t  .max_flash_size_kb     = 128,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G47_G48XX,\n\t  .revs                  = stm32g47_g48xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g47_g48xx_revs),\n\t  .device_str            = \"STM32G47/G48xx\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_HAS_DUAL_BANK | F_USE_ALL_WRPXX,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L4R_L4SXX,\n\t  .revs                  = stm32l4r_l4sxx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l4r_l4sxx_revs),\n\t  .device_str            = \"STM32L4R/L4Sxx\",\n\t  .max_flash_size_kb     = 2048,\n\t  .flags                 = F_HAS_DUAL_BANK | F_USE_ALL_WRPXX,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L4P_L4QXX,\n\t  .revs                  = stm32l4p_l4qxx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l4p_l4qxx_revs),\n\t  .device_str            = \"STM32L4P/L4Qxx\",\n\t  .max_flash_size_kb     = 1024,\n\t  .flags                 = F_HAS_DUAL_BANK | F_USE_ALL_WRPXX,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32L55_L56XX,\n\t  .revs                  = stm32l55_l56xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32l55_l56xx_revs),\n\t  .device_str            = \"STM32L55/L56xx\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_HAS_DUAL_BANK | F_USE_ALL_WRPXX | F_HAS_TZ | F_HAS_L5_FLASH_REGS,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x0BFA05E0,\n\t  .otp_base              = 0x0BFA0000,\n\t  .otp_size              = 512,\n\t},\n\t{\n\t  .id                    = DEVID_STM32G49_G4AXX,\n\t  .revs                  = stm32g49_g4axx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32g49_g4axx_revs),\n\t  .device_str            = \"STM32G49/G4Axx\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32U57_U58XX,\n\t  .revs                  = stm32u57_u58xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32u57_u58xx_revs),\n\t  .device_str            = \"STM32U57/U58xx\",\n\t  .max_flash_size_kb     = 2048,\n\t  .flags                 = F_HAS_DUAL_BANK | F_QUAD_WORD_PROG | F_HAS_TZ | F_HAS_L5_FLASH_REGS,\n\t  .flash_regs_base       = 0x40022000,\n\t  .fsize_addr            = 0x0BFA07A0,\n\t  .otp_base              = 0x0BFA0000,\n\t  .otp_size              = 512,\n\t},\n\t{\n\t  .id                    = DEVID_STM32WB1XX,\n\t  .revs                  = stm32wb1xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32wb1xx_revs),\n\t  .device_str            = \"STM32WB1x\",\n\t  .max_flash_size_kb     = 320,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x58004000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32WB5XX,\n\t  .revs                  = stm32wb5xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32wb5xx_revs),\n\t  .device_str            = \"STM32WB5x\",\n\t  .max_flash_size_kb     = 1024,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x58004000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32WB3XX,\n\t  .revs                  = stm32wb3xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32wb3xx_revs),\n\t  .device_str            = \"STM32WB3x\",\n\t  .max_flash_size_kb     = 512,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x58004000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n\t{\n\t  .id                    = DEVID_STM32WLE_WL5XX,\n\t  .revs                  = stm32wle_wl5xx_revs,\n\t  .num_revs              = ARRAY_SIZE(stm32wle_wl5xx_revs),\n\t  .device_str            = \"STM32WLE/WL5x\",\n\t  .max_flash_size_kb     = 256,\n\t  .flags                 = F_NONE,\n\t  .flash_regs_base       = 0x58004000,\n\t  .fsize_addr            = 0x1FFF75E0,\n\t  .otp_base              = 0x1FFF7000,\n\t  .otp_size              = 1024,\n\t},\n};\n\n/* flash bank stm32l4x <base> <size> 0 0 <target#> */\nFLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* fix-up bank base address: 0 is used for normal flash memory */\n\tif (bank->base == 0)\n\t\tbank->base = STM32_FLASH_BANK_BASE;\n\n\tstm32l4_info = calloc(1, sizeof(struct stm32l4_flash_bank));\n\tif (!stm32l4_info)\n\t\treturn ERROR_FAIL; /* Checkme: What better error to use?*/\n\tbank->driver_priv = stm32l4_info;\n\n\tstm32l4_info->probed = false;\n\tstm32l4_info->otp_enabled = false;\n\tstm32l4_info->user_bank_size = bank->size;\n\n\treturn ERROR_OK;\n}\n\n/* bitmap helper extension */\nstruct range {\n\tunsigned int start;\n\tunsigned int end;\n};\n\nstatic void bitmap_to_ranges(unsigned long *bitmap, unsigned int nbits,\n\t\tstruct range *ranges, unsigned int *ranges_count) {\n\t*ranges_count = 0;\n\tbool last_bit = 0, cur_bit;\n\tfor (unsigned int i = 0; i < nbits; i++) {\n\t\tcur_bit = test_bit(i, bitmap);\n\n\t\tif (cur_bit && !last_bit) {\n\t\t\t(*ranges_count)++;\n\t\t\tranges[*ranges_count - 1].start = i;\n\t\t\tranges[*ranges_count - 1].end = i;\n\t\t} else if (cur_bit && last_bit) {\n\t\t\t/* update (increment) the end this range */\n\t\t\tranges[*ranges_count - 1].end = i;\n\t\t}\n\n\t\tlast_bit = cur_bit;\n\t}\n}\n\nstatic inline int range_print_one(struct range *range, char *str)\n{\n\tif (range->start == range->end)\n\t\treturn sprintf(str, \"[%d]\", range->start);\n\n\treturn sprintf(str, \"[%d,%d]\", range->start, range->end);\n}\n\nstatic char *range_print_alloc(struct range *ranges, unsigned int ranges_count)\n{\n\t/* each range will be printed like the following: [start,end]\n\t * start and end, both are unsigned int, an unsigned int takes 10 characters max\n\t * plus 3 characters for '[', ',' and ']'\n\t * thus means each range can take maximum 23 character\n\t * after each range we add a ' ' as separator and finally we need the '\\0'\n\t * if the ranges_count is zero we reserve one char for '\\0' to return an empty string */\n\tchar *str = calloc(1, ranges_count * (24 * sizeof(char)) + 1);\n\tchar *ptr = str;\n\n\tfor (unsigned int i = 0; i < ranges_count; i++) {\n\t\tptr += range_print_one(&(ranges[i]), ptr);\n\n\t\tif (i < ranges_count - 1)\n\t\t\t*(ptr++) = ' ';\n\t}\n\n\treturn str;\n}\n\n/* end of bitmap helper extension */\n\nstatic inline bool stm32l4_is_otp(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn bank->base == stm32l4_info->part_info->otp_base;\n}\n\nstatic int stm32l4_otp_enable(struct flash_bank *bank, bool enable)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\n\tif (!stm32l4_is_otp(bank))\n\t\treturn ERROR_FAIL;\n\n\tchar *op_str = enable ? \"enabled\" : \"disabled\";\n\n\tLOG_INFO(\"OTP memory (bank #%d) is %s%s for write commands\",\n\t\t\tbank->bank_number,\n\t\t\tstm32l4_info->otp_enabled == enable ? \"already \" : \"\",\n\t\t\top_str);\n\n\tstm32l4_info->otp_enabled = enable;\n\n\treturn ERROR_OK;\n}\n\nstatic inline bool stm32l4_otp_is_enabled(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn stm32l4_info->otp_enabled;\n}\n\nstatic void stm32l4_sync_rdp_tzen(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\n\tbool tzen = false;\n\n\tif (stm32l4_info->part_info->flags & F_HAS_TZ)\n\t\ttzen = (stm32l4_info->optr & FLASH_TZEN) != 0;\n\n\tuint32_t rdp = stm32l4_info->optr & FLASH_RDP_MASK;\n\n\t/* for devices without TrustZone:\n\t *   RDP level 0 and 2 values are to 0xAA and 0xCC\n\t *   Any other value corresponds to RDP level 1\n\t * for devices with TrusZone:\n\t *   RDP level 0 and 2 values are 0xAA and 0xCC\n\t *   RDP level 0.5 value is 0x55 only if TZEN = 1\n\t *   Any other value corresponds to RDP level 1, including 0x55 if TZEN = 0\n\t */\n\n\tif (rdp != RDP_LEVEL_0 && rdp != RDP_LEVEL_2) {\n\t\tif (!tzen || (tzen && rdp != RDP_LEVEL_0_5))\n\t\t\trdp = RDP_LEVEL_1;\n\t}\n\n\tstm32l4_info->tzen = tzen;\n\tstm32l4_info->rdp = rdp;\n}\n\nstatic inline uint32_t stm32l4_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn stm32l4_info->flash_regs_base + reg_offset;\n}\n\nstatic inline uint32_t stm32l4_get_flash_reg_by_index(struct flash_bank *bank,\n\tenum stm32l4_flash_reg_index reg_index)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn stm32l4_get_flash_reg(bank, stm32l4_info->flash_regs[reg_index]);\n}\n\nstatic inline int stm32l4_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)\n{\n\treturn target_read_u32(bank->target, stm32l4_get_flash_reg(bank, reg_offset), value);\n}\n\nstatic inline int stm32l4_read_flash_reg_by_index(struct flash_bank *bank,\n\tenum stm32l4_flash_reg_index reg_index, uint32_t *value)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn stm32l4_read_flash_reg(bank, stm32l4_info->flash_regs[reg_index], value);\n}\n\nstatic inline int stm32l4_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)\n{\n\treturn target_write_u32(bank->target, stm32l4_get_flash_reg(bank, reg_offset), value);\n}\n\nstatic inline int stm32l4_write_flash_reg_by_index(struct flash_bank *bank,\n\tenum stm32l4_flash_reg_index reg_index, uint32_t value)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn stm32l4_write_flash_reg(bank, stm32l4_info->flash_regs[reg_index], value);\n}\n\nstatic int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* wait for busy to clear */\n\tfor (;;) {\n\t\tretval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32 \"\", status);\n\t\tif ((status & stm32l4_info->sr_bsy_mask) == 0)\n\t\t\tbreak;\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tif (status & FLASH_WRPERR) {\n\t\tLOG_ERROR(\"stm32x device protected\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t/* Clear but report errors */\n\tif (status & FLASH_ERROR) {\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ERROR_FAIL;\n\t\t/* If this operation fails, we ignore it and report the original\n\t\t * retval\n\t\t */\n\t\tstm32l4_write_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, status & FLASH_ERROR);\n\t}\n\n\treturn retval;\n}\n\n/** set all FLASH_SECBB registers to the same value */\nstatic int stm32l4_set_secbb(struct flash_bank *bank, uint32_t value)\n{\n\t/* This function should be used only with device with TrustZone, do just a security check */\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tassert(stm32l4_info->part_info->flags & F_HAS_TZ);\n\n\t/* based on RM0438 Rev6 for STM32L5x devices:\n\t * to modify a page block-based security attribution, it is recommended to\n\t *  1- check that no flash operation is ongoing on the related page\n\t *  2- add ISB instruction after modifying the page security attribute in SECBBxRy\n\t *     this step is not need in case of JTAG direct access\n\t */\n\tint retval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write SECBBxRy registers */\n\tLOG_DEBUG(\"setting secure block-based areas registers (SECBBxRy) to 0x%08x\", value);\n\n\tconst uint8_t secbb_regs[] = {\n\t\t\tFLASH_SECBB1(1), FLASH_SECBB1(2), FLASH_SECBB1(3), FLASH_SECBB1(4), /* bank 1 SECBB register offsets */\n\t\t\tFLASH_SECBB2(1), FLASH_SECBB2(2), FLASH_SECBB2(3), FLASH_SECBB2(4)  /* bank 2 SECBB register offsets */\n\t};\n\n\n\tunsigned int num_secbb_regs = ARRAY_SIZE(secbb_regs);\n\n\t/* in single bank mode, it's useless to modify FLASH_SECBB2Rx registers\n\t * then consider only the first half of secbb_regs\n\t */\n\tif (!stm32l4_info->dual_bank_mode)\n\t\tnum_secbb_regs /= 2;\n\n\tfor (unsigned int i = 0; i < num_secbb_regs; i++) {\n\t\tretval = stm32l4_write_flash_reg(bank, secbb_regs[i], value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic inline int stm32l4_get_flash_cr_with_lock_index(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\treturn (stm32l4_info->flash_regs[STM32_FLASH_CR_WLK_INDEX]) ?\n\t\tSTM32_FLASH_CR_WLK_INDEX : STM32_FLASH_CR_INDEX;\n}\n\nstatic int stm32l4_unlock_reg(struct flash_bank *bank)\n{\n\tconst uint32_t flash_cr_index = stm32l4_get_flash_cr_with_lock_index(bank);\n\tuint32_t ctrl;\n\n\t/* first check if not already unlocked\n\t * otherwise writing on STM32_FLASH_KEYR will fail\n\t */\n\tint retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & FLASH_LOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock flash registers */\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_KEYR_INDEX, KEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & FLASH_LOCK) {\n\t\tLOG_ERROR(\"flash not unlocked STM32_FLASH_CR: %\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_unlock_option_reg(struct flash_bank *bank)\n{\n\tconst uint32_t flash_cr_index = stm32l4_get_flash_cr_with_lock_index(bank);\n\tuint32_t ctrl;\n\n\tint retval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((ctrl & FLASH_OPTLOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* unlock option registers */\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_OPTKEYR_INDEX, OPTKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_read_flash_reg_by_index(bank, flash_cr_index, &ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ctrl & FLASH_OPTLOCK) {\n\t\tLOG_ERROR(\"options not unlocked STM32_FLASH_CR: %\" PRIx32, ctrl);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_perform_obl_launch(struct flash_bank *bank)\n{\n\tint retval, retval2;\n\n\tretval = stm32l4_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_unlock_option_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\t/* Set OBL_LAUNCH bit in CR -> system reset and option bytes reload,\n\t * but the RMs explicitly do *NOT* list this as power-on reset cause, and:\n\t * \"Note: If the read protection is set while the debugger is still\n\t * connected through JTAG/SWD, apply a POR (power-on reset) instead of a system reset.\"\n\t */\n\n\t/* \"Setting OBL_LAUNCH generates a reset so the option byte loading is performed under system reset\" */\n\t/* Due to this reset ST-Link reports an SWD_DP_ERROR, despite the write was successful,\n\t * then just ignore the returned value */\n\tstm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_OBL_LAUNCH);\n\n\t/* Need to re-probe after change */\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tstm32l4_info->probed = false;\n\nerr_lock:\n\tretval2 = stm32l4_write_flash_reg_by_index(bank, stm32l4_get_flash_cr_with_lock_index(bank),\n\t\t\tFLASH_LOCK | FLASH_OPTLOCK);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval2;\n}\n\nstatic int stm32l4_write_option(struct flash_bank *bank, uint32_t reg_offset,\n\tuint32_t value, uint32_t mask)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tuint32_t optiondata;\n\tint retval, retval2;\n\n\tretval = stm32l4_read_flash_reg(bank, reg_offset, &optiondata);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* for STM32L5 and similar devices, use always non-secure\n\t * registers for option bytes programming */\n\tconst uint32_t *saved_flash_regs = stm32l4_info->flash_regs;\n\tif (stm32l4_info->part_info->flags & F_HAS_L5_FLASH_REGS)\n\t\tstm32l4_info->flash_regs = stm32l5_ns_flash_regs;\n\n\tretval = stm32l4_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_unlock_option_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\toptiondata = (optiondata & ~mask) | (value & mask);\n\n\tretval = stm32l4_write_flash_reg(bank, reg_offset, optiondata);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_OPTSTRT);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\nerr_lock:\n\tretval2 = stm32l4_write_flash_reg_by_index(bank, stm32l4_get_flash_cr_with_lock_index(bank),\n\t\t\tFLASH_LOCK | FLASH_OPTLOCK);\n\tstm32l4_info->flash_regs = saved_flash_regs;\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval2;\n}\n\nstatic int stm32l4_get_one_wrpxy(struct flash_bank *bank, struct stm32l4_wrp *wrpxy,\n\t\tenum stm32l4_flash_reg_index reg_idx, int offset)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tint ret;\n\n\twrpxy->reg_idx = reg_idx;\n\twrpxy->offset = offset;\n\n\tret = stm32l4_read_flash_reg_by_index(bank, wrpxy->reg_idx , &wrpxy->value);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\twrpxy->first = (wrpxy->value & stm32l4_info->wrpxxr_mask) + wrpxy->offset;\n\twrpxy->last = ((wrpxy->value >> 16) & stm32l4_info->wrpxxr_mask) + wrpxy->offset;\n\twrpxy->used = wrpxy->first <= wrpxy->last;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_get_all_wrpxy(struct flash_bank *bank, enum stm32_bank_id dev_bank_id,\n\t\tstruct stm32l4_wrp *wrpxy, unsigned int *n_wrp)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tint ret;\n\n\t*n_wrp = 0;\n\n\t/* for single bank devices there is 2 WRP regions.\n\t * for dual bank devices there is 2 WRP regions per bank,\n\t *   if configured as single bank only 2 WRP are usable\n\t *   except for STM32L4R/S/P/Q, G4 cat3, L5 ... all 4 WRP are usable\n\t * note: this should be revised, if a device will have the SWAP banks option\n\t */\n\n\tint wrp2y_sectors_offset = -1; /* -1 : unused */\n\n\t/* if bank_id is BANK1 or ALL_BANKS */\n\tif (dev_bank_id != STM32_BANK2) {\n\t\t/* get FLASH_WRP1AR */\n\t\tret = stm32l4_get_one_wrpxy(bank, &wrpxy[(*n_wrp)++], STM32_FLASH_WRP1AR_INDEX, 0);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\t/* get WRP1BR */\n\t\tret = stm32l4_get_one_wrpxy(bank, &wrpxy[(*n_wrp)++], STM32_FLASH_WRP1BR_INDEX, 0);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\t/* for some devices (like STM32L4R/S) in single-bank mode, the 4 WRPxx are usable */\n\t\tif ((stm32l4_info->part_info->flags & F_USE_ALL_WRPXX) && !stm32l4_info->dual_bank_mode)\n\t\t\twrp2y_sectors_offset = 0;\n\t}\n\n\t/* if bank_id is BANK2 or ALL_BANKS */\n\tif (dev_bank_id != STM32_BANK1 && stm32l4_info->dual_bank_mode)\n\t\twrp2y_sectors_offset = stm32l4_info->bank1_sectors;\n\n\tif (wrp2y_sectors_offset >= 0) {\n\t\t/* get WRP2AR */\n\t\tret = stm32l4_get_one_wrpxy(bank, &wrpxy[(*n_wrp)++], STM32_FLASH_WRP2AR_INDEX, wrp2y_sectors_offset);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\t/* get WRP2BR */\n\t\tret = stm32l4_get_one_wrpxy(bank, &wrpxy[(*n_wrp)++], STM32_FLASH_WRP2BR_INDEX, wrp2y_sectors_offset);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_write_one_wrpxy(struct flash_bank *bank, struct stm32l4_wrp *wrpxy)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\n\tint wrp_start = wrpxy->first - wrpxy->offset;\n\tint wrp_end = wrpxy->last - wrpxy->offset;\n\n\tuint32_t wrp_value = (wrp_start & stm32l4_info->wrpxxr_mask) | ((wrp_end & stm32l4_info->wrpxxr_mask) << 16);\n\n\treturn stm32l4_write_option(bank, stm32l4_info->flash_regs[wrpxy->reg_idx], wrp_value, 0xffffffff);\n}\n\nstatic int stm32l4_write_all_wrpxy(struct flash_bank *bank, struct stm32l4_wrp *wrpxy, unsigned int n_wrp)\n{\n\tint ret;\n\n\tfor (unsigned int i = 0; i < n_wrp; i++) {\n\t\tret = stm32l4_write_one_wrpxy(bank, &wrpxy[i]);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_protect_check(struct flash_bank *bank)\n{\n\tunsigned int n_wrp;\n\tstruct stm32l4_wrp wrpxy[4];\n\n\tint ret = stm32l4_get_all_wrpxy(bank, STM32_ALL_BANKS, wrpxy, &n_wrp);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* initialize all sectors as unprotected */\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = 0;\n\n\t/* now check WRPxy and mark the protected sectors */\n\tfor (unsigned int i = 0; i < n_wrp; i++) {\n\t\tif (wrpxy[i].used) {\n\t\t\tfor (int s = wrpxy[i].first; s <= wrpxy[i].last; s++)\n\t\t\t\tbank->sectors[s].is_protected = 1;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tint retval, retval2;\n\n\tassert((first <= last) && (last < bank->num_sectors));\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"cannot erase OTP memory\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* set all FLASH pages as secure */\n\t\tretval = stm32l4_set_secbb(bank, FLASH_SECBB_SECURE);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* restore all FLASH pages as non-secure */\n\t\t\tstm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE); /* ignore the return value */\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = stm32l4_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\t/*\n\tSector Erase\n\tTo erase a sector, follow the procedure below:\n\t1. Check that no Flash memory operation is ongoing by\n\t   checking the BSY bit in the FLASH_SR register\n\t2. Set the PER bit and select the page and bank\n\t   you wish to erase in the FLASH_CR register\n\t3. Set the STRT bit in the FLASH_CR register\n\t4. Wait for the BSY bit to be cleared\n\t */\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tuint32_t erase_flags;\n\t\terase_flags = FLASH_PER | FLASH_STRT;\n\n\t\tif (i >= stm32l4_info->bank1_sectors) {\n\t\t\tuint8_t snb;\n\t\t\tsnb = i - stm32l4_info->bank1_sectors;\n\t\t\terase_flags |= snb << FLASH_PAGE_SHIFT | stm32l4_info->cr_bker_mask;\n\t\t} else\n\t\t\terase_flags |= i << FLASH_PAGE_SHIFT;\n\t\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, erase_flags);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\nerr_lock:\n\tretval2 = stm32l4_write_flash_reg_by_index(bank, stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* restore all FLASH pages as non-secure */\n\t\tint retval3 = stm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE);\n\t\tif (retval3 != ERROR_OK)\n\t\t\treturn retval3;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval2;\n}\n\nstatic int stm32l4_protect_same_bank(struct flash_bank *bank, enum stm32_bank_id bank_id, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tunsigned int i;\n\n\t/* check if the desired protection is already configured */\n\tfor (i = first; i <= last; i++) {\n\t\tif (bank->sectors[i].is_protected != set)\n\t\t\tbreak;\n\t\telse if (i == last) {\n\t\t\tLOG_INFO(\"The specified sectors are already %s\", set ? \"protected\" : \"unprotected\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* all sectors from first to last (or part of them) could have different\n\t * protection other than the requested */\n\tunsigned int n_wrp;\n\tstruct stm32l4_wrp wrpxy[4];\n\n\tint ret = stm32l4_get_all_wrpxy(bank, bank_id, wrpxy, &n_wrp);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* use bitmap and range helpers to optimize the WRP usage */\n\tDECLARE_BITMAP(pages, bank->num_sectors);\n\tbitmap_zero(pages, bank->num_sectors);\n\n\tfor (i = 0; i < n_wrp; i++) {\n\t\tif (wrpxy[i].used) {\n\t\t\tfor (int p = wrpxy[i].first; p <= wrpxy[i].last; p++)\n\t\t\t\tset_bit(p, pages);\n\t\t}\n\t}\n\n\t/* we have at most 'n_wrp' WRP areas\n\t * add one range if the user is trying to protect a fifth range */\n\tstruct range ranges[n_wrp + 1];\n\tunsigned int ranges_count = 0;\n\n\tbitmap_to_ranges(pages, bank->num_sectors, ranges, &ranges_count);\n\n\t/* pretty-print the currently protected ranges */\n\tif (ranges_count > 0) {\n\t\tchar *ranges_str = range_print_alloc(ranges, ranges_count);\n\t\tLOG_DEBUG(\"current protected areas: %s\", ranges_str);\n\t\tfree(ranges_str);\n\t} else\n\t\tLOG_DEBUG(\"current protected areas: none\");\n\n\tif (set) { /* flash protect */\n\t\tfor (i = first; i <= last; i++)\n\t\t\tset_bit(i, pages);\n\t} else { /* flash unprotect */\n\t\tfor (i = first; i <= last; i++)\n\t\t\tclear_bit(i, pages);\n\t}\n\n\t/* check the ranges_count after the user request */\n\tbitmap_to_ranges(pages, bank->num_sectors, ranges, &ranges_count);\n\n\t/* pretty-print the requested areas for protection */\n\tif (ranges_count > 0) {\n\t\tchar *ranges_str = range_print_alloc(ranges, ranges_count);\n\t\tLOG_DEBUG(\"requested areas for protection: %s\", ranges_str);\n\t\tfree(ranges_str);\n\t} else\n\t\tLOG_DEBUG(\"requested areas for protection: none\");\n\n\tif (ranges_count > n_wrp) {\n\t\tLOG_ERROR(\"cannot set the requested protection \"\n\t\t\t\t\"(only %u write protection areas are available)\" , n_wrp);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* re-init all WRPxy as disabled (first > last)*/\n\tfor (i = 0; i < n_wrp; i++) {\n\t\twrpxy[i].first = wrpxy[i].offset + 1;\n\t\twrpxy[i].last = wrpxy[i].offset;\n\t}\n\n\t/* then configure WRPxy areas */\n\tfor (i = 0; i < ranges_count; i++) {\n\t\twrpxy[i].first = ranges[i].start;\n\t\twrpxy[i].last = ranges[i].end;\n\t}\n\n\t/* finally write WRPxy registers */\n\treturn stm32l4_write_all_wrpxy(bank, wrpxy, n_wrp);\n}\n\nstatic int stm32l4_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"cannot protect/unprotect OTP memory\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* refresh the sectors' protection */\n\tint ret = stm32l4_protect_check(bank);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* the requested sectors could be located into bank1 and/or bank2 */\n\tif (last < stm32l4_info->bank1_sectors) {\n\t\treturn stm32l4_protect_same_bank(bank, STM32_BANK1, set, first, last);\n\t} else if (first >= stm32l4_info->bank1_sectors) {\n\t\treturn stm32l4_protect_same_bank(bank, STM32_BANK2, set, first, last);\n\t} else {\n\t\tret = stm32l4_protect_same_bank(bank, STM32_BANK1, set, first, stm32l4_info->bank1_sectors - 1);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\treturn stm32l4_protect_same_bank(bank, STM32_BANK2, set, stm32l4_info->bank1_sectors, last);\n\t}\n}\n\n/* count is the size divided by stm32l4_info->data_width */\nstatic int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval = ERROR_OK;\n\n\tstatic const uint8_t stm32l4_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/stm32/stm32l4x.inc\"\n\t};\n\n\tif (target_alloc_working_area(target, sizeof(stm32l4_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = target_write_buffer(target, write_algorithm->address,\n\t\t\tsizeof(stm32l4_flash_write_code),\n\t\t\tstm32l4_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* data_width should be multiple of double-word */\n\tassert(stm32l4_info->data_width % 8 == 0);\n\tconst size_t extra_size = sizeof(struct stm32l4_work_area);\n\tuint32_t buffer_size = target_get_working_area_avail(target) - extra_size;\n\t/* buffer_size should be multiple of stm32l4_info->data_width */\n\tbuffer_size &= ~(stm32l4_info->data_width - 1);\n\n\tif (buffer_size < 256) {\n\t\tLOG_WARNING(\"large enough working area not available, can't do block memory writes\");\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t} else if (buffer_size > 16384) {\n\t\t/* probably won't benefit from more than 16k ... */\n\t\tbuffer_size = 16384;\n\t}\n\n\tif (target_alloc_working_area_try(target, buffer_size + extra_size, &source) != ERROR_OK) {\n\t\tLOG_ERROR(\"allocating working area failed\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* contrib/loaders/flash/stm32/stm32l4x.c:write() arguments */\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\t/* stm32l4_work_area ptr , status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* buffer end */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* target address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* count (of stm32l4_info->data_width) */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);\n\tbuf_set_u32(reg_params[2].value, 0, 32, address);\n\tbuf_set_u32(reg_params[3].value, 0, 32, count);\n\n\t/* write algo stack pointer */\n\tinit_reg_param(&reg_params[4], \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[4].value, 0, 32, source->address +\n\t\t\toffsetof(struct stm32l4_work_area, stack) + LDR_STACK_SIZE);\n\n\tstruct stm32l4_loader_params loader_extra_params;\n\n\ttarget_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_sr_addr,\n\t\t\tstm32l4_get_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX));\n\ttarget_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_cr_addr,\n\t\t\tstm32l4_get_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX));\n\ttarget_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_word_size,\n\t\t\tstm32l4_info->data_width);\n\ttarget_buffer_set_u32(target, (uint8_t *) &loader_extra_params.flash_sr_bsy_mask,\n\t\t\tstm32l4_info->sr_bsy_mask);\n\n\tretval = target_write_buffer(target, source->address, sizeof(loader_extra_params),\n\t\t\t(uint8_t *) &loader_extra_params);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_run_flash_async_algorithm(target, buffer, count, stm32l4_info->data_width,\n\t\t\t0, NULL,\n\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\tsource->address + offsetof(struct stm32l4_work_area, fifo),\n\t\t\tsource->size - offsetof(struct stm32l4_work_area, fifo),\n\t\t\twrite_algorithm->address, 0,\n\t\t\t&armv7m_info);\n\n\tif (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\tLOG_ERROR(\"error executing stm32l4 flash write algorithm\");\n\n\t\tuint32_t error;\n\t\tstm32l4_read_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, &error);\n\t\terror &= FLASH_ERROR;\n\n\t\tif (error & FLASH_WRPERR)\n\t\t\tLOG_ERROR(\"flash memory write protected\");\n\n\t\tif (error != 0) {\n\t\t\tLOG_ERROR(\"flash write failed = %08\" PRIx32, error);\n\t\t\t/* Clear but report errors */\n\t\t\tstm32l4_write_flash_reg_by_index(bank, STM32_FLASH_SR_INDEX, error);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\n/* count is the size divided by stm32l4_info->data_width */\nstatic int stm32l4_write_block_without_loader(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t\tuint32_t offset, uint32_t count)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t address = bank->base + offset;\n\tint retval = ERROR_OK;\n\n\t/* wait for BSY bit */\n\tretval = stm32l4_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* set PG in FLASH_CR */\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_PG);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\n\t/* write directly to flash memory */\n\tconst uint8_t *src = buffer;\n\tconst uint32_t data_width_in_words = stm32l4_info->data_width / 4;\n\twhile (count--) {\n\t\tretval = target_write_memory(target, address, 4, data_width_in_words, src);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* wait for BSY bit */\n\t\tretval = stm32l4_wait_status_busy(bank, FLASH_WRITE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tsrc += stm32l4_info->data_width;\n\t\taddress += stm32l4_info->data_width;\n\t}\n\n\t/* reset PG in FLASH_CR */\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tint retval = ERROR_OK, retval2;\n\n\tif (stm32l4_is_otp(bank) && !stm32l4_otp_is_enabled(bank)) {\n\t\tLOG_ERROR(\"OTP memory is disabled for write commands\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* ensure that stm32l4_info->data_width is 'at least' a multiple of dword */\n\tassert(stm32l4_info->data_width % 8 == 0);\n\n\t/* The flash write must be aligned to the 'stm32l4_info->data_width' boundary.\n\t * The flash infrastructure ensures it, do just a security check */\n\tassert(offset % stm32l4_info->data_width == 0);\n\tassert(count % stm32l4_info->data_width == 0);\n\n\t/* STM32G4xxx Cat. 3 devices may have gaps between banks, check whether\n\t * data to be written does not go into a gap:\n\t * suppose buffer is fully contained in bank from sector 0 to sector\n\t * num->sectors - 1 and sectors are ordered according to offset\n\t */\n\tstruct flash_sector *head = &bank->sectors[0];\n\tstruct flash_sector *tail = &bank->sectors[bank->num_sectors - 1];\n\n\twhile ((head < tail) && (offset >= (head + 1)->offset)) {\n\t\t/* buffer does not intersect head nor gap behind head */\n\t\thead++;\n\t}\n\n\twhile ((head < tail) && (offset + count <= (tail - 1)->offset + (tail - 1)->size)) {\n\t\t/* buffer does not intersect tail nor gap before tail */\n\t\t--tail;\n\t}\n\n\tLOG_DEBUG(\"data: 0x%08\" PRIx32 \" - 0x%08\" PRIx32 \", sectors: 0x%08\" PRIx32 \" - 0x%08\" PRIx32,\n\t\toffset, offset + count - 1, head->offset, tail->offset + tail->size - 1);\n\n\t/* Now check that there is no gap from head to tail, this should work\n\t * even for multiple or non-symmetric gaps\n\t */\n\twhile (head < tail) {\n\t\tif (head->offset + head->size != (head + 1)->offset) {\n\t\t\tLOG_ERROR(\"write into gap from \" TARGET_ADDR_FMT \" to \" TARGET_ADDR_FMT,\n\t\t\t\tbank->base + head->offset + head->size,\n\t\t\t\tbank->base + (head + 1)->offset - 1);\n\t\t\tretval = ERROR_FLASH_DST_OUT_OF_BANK;\n\t\t}\n\t\thead++;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* set all FLASH pages as secure */\n\t\tretval = stm32l4_set_secbb(bank, FLASH_SECBB_SECURE);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* restore all FLASH pages as non-secure */\n\t\t\tstm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE); /* ignore the return value */\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = stm32l4_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\n\t/* For TrustZone enabled devices, when TZEN is set and RDP level is 0.5,\n\t * the debug is possible only in non-secure state.\n\t * Thus means the flashloader will run in non-secure mode,\n\t * and the workarea need to be in non-secure RAM */\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0_5))\n\t\tLOG_WARNING(\"RDP = 0x55, the work-area should be in non-secure RAM (check SAU partitioning)\");\n\n\t/* first try to write using the loader, for better performance */\n\tretval = stm32l4_write_block(bank, buffer, offset,\n\t\t\tcount / stm32l4_info->data_width);\n\n\t/* if resources are not available write without a loader */\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\tLOG_WARNING(\"falling back to programming without a flash loader (slower)\");\n\t\tretval = stm32l4_write_block_without_loader(bank, buffer, offset,\n\t\t\t\tcount / stm32l4_info->data_width);\n\t}\n\nerr_lock:\n\tretval2 = stm32l4_write_flash_reg_by_index(bank, stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* restore all FLASH pages as non-secure */\n\t\tint retval3 = stm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE);\n\t\tif (retval3 != ERROR_OK)\n\t\t\treturn retval3;\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"block write failed\");\n\t\treturn retval;\n\t}\n\treturn retval2;\n}\n\nstatic int stm32l4_read_idcode(struct flash_bank *bank, uint32_t *id)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target = bank->target;\n\n\t/* try reading possible IDCODE registers, in the following order */\n\tuint32_t dbgmcu_idcode[] = {DBGMCU_IDCODE_L4_G4, DBGMCU_IDCODE_G0, DBGMCU_IDCODE_L5};\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(dbgmcu_idcode); i++) {\n\t\tretval = target_read_u32(target, dbgmcu_idcode[i], id);\n\t\tif ((retval == ERROR_OK) && ((*id & 0xfff) != 0) && ((*id & 0xfff) != 0xfff))\n\t\t\treturn ERROR_OK;\n\t}\n\n\t/* Workaround for STM32WL5x devices:\n\t * DBGMCU_IDCODE cannot be read using CPU1 (Cortex-M0+) at AP1,\n\t * to solve this read the UID64 (IEEE 64-bit unique device ID register) */\n\n\tstruct armv7m_common *armv7m = target_to_armv7m_safe(target);\n\tif (!armv7m) {\n\t\tLOG_ERROR(\"Flash requires Cortex-M target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\t/* CPU2 (Cortex-M0+) is supported only with non-hla adapters because it is on AP1.\n\t * Using HLA adapters armv7m.debug_ap is null, and checking ap_num triggers a segfault */\n\tif (cortex_m_get_partno_safe(target) == CORTEX_M0P_PARTNO &&\n\t\t\tarmv7m->debug_ap && armv7m->debug_ap->ap_num == 1) {\n\t\tuint32_t uid64_ids;\n\n\t\t/* UID64 is contains\n\t\t *  - Bits 63:32 : DEVNUM (unique device number, different for each individual device)\n\t\t *  - Bits 31:08 : STID (company ID) = 0x0080E1\n\t\t *  - Bits 07:00 : DEVID (device ID) = 0x15\n\t\t *\n\t\t *  read only the fixed values {STID,DEVID} from UID64_IDS to identify the device as STM32WLx\n\t\t */\n\t\tretval = target_read_u32(target, UID64_IDS, &uid64_ids);\n\t\tif (retval == ERROR_OK && uid64_ids == UID64_IDS_STM32WL) {\n\t\t\t/* force the DEV_ID to DEVID_STM32WLE_WL5XX and the REV_ID to unknown */\n\t\t\t*id = DEVID_STM32WLE_WL5XX;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"can't get the device id\");\n\treturn (retval == ERROR_OK) ? ERROR_FAIL : retval;\n}\n\nstatic const char *get_stm32l4_rev_str(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tconst struct stm32l4_part_info *part_info = stm32l4_info->part_info;\n\tassert(part_info);\n\n\tconst uint16_t rev_id = stm32l4_info->idcode >> 16;\n\tfor (unsigned int i = 0; i < part_info->num_revs; i++) {\n\t\tif (rev_id == part_info->revs[i].rev)\n\t\t\treturn part_info->revs[i].str;\n\t}\n\treturn \"'unknown'\";\n}\n\nstatic const char *get_stm32l4_bank_type_str(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tassert(stm32l4_info->part_info);\n\treturn stm32l4_is_otp(bank) ? \"OTP\" :\n\t\t\tstm32l4_info->dual_bank_mode ? \"Flash dual\" :\n\t\t\t\"Flash single\";\n}\n\nstatic int stm32l4_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tconst struct stm32l4_part_info *part_info;\n\tuint16_t flash_size_kb = 0xffff;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tstruct armv7m_common *armv7m = target_to_armv7m_safe(target);\n\tif (!armv7m) {\n\t\tLOG_ERROR(\"Flash requires Cortex-M target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tstm32l4_info->probed = false;\n\n\t/* read stm32 device id registers */\n\tint retval = stm32l4_read_idcode(bank, &stm32l4_info->idcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t device_id = stm32l4_info->idcode & 0xFFF;\n\n\tfor (unsigned int n = 0; n < ARRAY_SIZE(stm32l4_parts); n++) {\n\t\tif (device_id == stm32l4_parts[n].id) {\n\t\t\tstm32l4_info->part_info = &stm32l4_parts[n];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!stm32l4_info->part_info) {\n\t\tLOG_WARNING(\"Cannot identify target as an %s family device.\", device_families);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tpart_info = stm32l4_info->part_info;\n\tconst char *rev_str = get_stm32l4_rev_str(bank);\n\tconst uint16_t rev_id = stm32l4_info->idcode >> 16;\n\n\tLOG_INFO(\"device idcode = 0x%08\" PRIx32 \" (%s - Rev %s : 0x%04x)\",\n\t\t\tstm32l4_info->idcode, part_info->device_str, rev_str, rev_id);\n\n\tstm32l4_info->flash_regs_base = stm32l4_info->part_info->flash_regs_base;\n\tstm32l4_info->data_width = (part_info->flags & F_QUAD_WORD_PROG) ? 16 : 8;\n\tstm32l4_info->cr_bker_mask = FLASH_BKER;\n\tstm32l4_info->sr_bsy_mask = FLASH_BSY;\n\n\t/* Set flash write alignment boundaries.\n\t * Ask the flash infrastructure to ensure required alignment */\n\tbank->write_start_alignment = stm32l4_info->data_width;\n\tbank->write_end_alignment = stm32l4_info->data_width;\n\n\t/* Initialize the flash registers layout */\n\tif (part_info->flags & F_HAS_L5_FLASH_REGS)\n\t\tstm32l4_info->flash_regs = stm32l5_ns_flash_regs;\n\telse\n\t\tstm32l4_info->flash_regs = stm32l4_flash_regs;\n\n\t/* read flash option register */\n\tretval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &stm32l4_info->optr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32l4_sync_rdp_tzen(bank);\n\n\t/* for devices with TrustZone, use flash secure registers when TZEN=1 and RDP is LEVEL_0 */\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\tif (part_info->flags & F_HAS_L5_FLASH_REGS) {\n\t\t\tstm32l4_info->flash_regs_base |= STM32L5_REGS_SEC_OFFSET;\n\t\t\tstm32l4_info->flash_regs = stm32l5_s_flash_regs;\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: device supported incomplete\");\n\t\t\treturn ERROR_NOT_IMPLEMENTED;\n\t\t}\n\t}\n\n\tif (part_info->flags & F_HAS_TZ)\n\t\tLOG_INFO(\"TZEN = %d : TrustZone %s by option bytes\",\n\t\t\t\tstm32l4_info->tzen,\n\t\t\t\tstm32l4_info->tzen ? \"enabled\" : \"disabled\");\n\n\tLOG_INFO(\"RDP level %s (0x%02X)\",\n\t\t\tstm32l4_info->rdp == RDP_LEVEL_0 ? \"0\" : stm32l4_info->rdp == RDP_LEVEL_0_5 ? \"0.5\" : \"1\",\n\t\t\tstm32l4_info->rdp);\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tbank->size = part_info->otp_size;\n\n\t\tLOG_INFO(\"OTP size is %d bytes, base address is \" TARGET_ADDR_FMT, bank->size, bank->base);\n\n\t\t/* OTP memory is considered as one sector */\n\t\tfree(bank->sectors);\n\t\tbank->num_sectors = 1;\n\t\tbank->sectors = alloc_block_array(0, part_info->otp_size, 1);\n\n\t\tif (!bank->sectors) {\n\t\t\tLOG_ERROR(\"failed to allocate bank sectors\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tstm32l4_info->probed = true;\n\t\treturn ERROR_OK;\n\t} else if (bank->base != STM32_FLASH_BANK_BASE && bank->base != STM32_FLASH_S_BANK_BASE) {\n\t\tLOG_ERROR(\"invalid bank base address\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* get flash size from target. */\n\tretval = target_read_u16(target, part_info->fsize_addr, &flash_size_kb);\n\n\t/* failed reading flash size or flash size invalid (early silicon),\n\t * default to max target family */\n\tif (retval != ERROR_OK || flash_size_kb == 0xffff || flash_size_kb == 0\n\t\t\t|| flash_size_kb > part_info->max_flash_size_kb) {\n\t\tLOG_WARNING(\"STM32 flash size failed, probe inaccurate - assuming %dk flash\",\n\t\t\tpart_info->max_flash_size_kb);\n\t\tflash_size_kb = part_info->max_flash_size_kb;\n\t}\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (stm32l4_info->user_bank_size) {\n\t\tLOG_WARNING(\"overriding size register by configured bank size - MAY CAUSE TROUBLE\");\n\t\tflash_size_kb = stm32l4_info->user_bank_size / 1024;\n\t}\n\n\tLOG_INFO(\"flash size = %d KiB\", flash_size_kb);\n\n\t/* did we assign a flash size? */\n\tassert((flash_size_kb != 0xffff) && flash_size_kb);\n\n\tconst bool is_max_flash_size = flash_size_kb == stm32l4_info->part_info->max_flash_size_kb;\n\n\tstm32l4_info->bank1_sectors = 0;\n\tstm32l4_info->hole_sectors = 0;\n\n\tint num_pages = 0;\n\tint page_size_kb = 0;\n\n\tstm32l4_info->dual_bank_mode = false;\n\n\tswitch (device_id) {\n\tcase DEVID_STM32L47_L48XX:\n\tcase DEVID_STM32L49_L4AXX:\n\t\t/* if flash size is max (1M) the device is always dual bank\n\t\t * STM32L47/L48xx: has variants with 512K\n\t\t * STM32L49/L4Axx: has variants with 512 and 256\n\t\t * for these variants:\n\t\t *   if DUAL_BANK = 0 -> single bank\n\t\t *   else -> dual bank without gap\n\t\t * note: the page size is invariant\n\t\t */\n\t\tpage_size_kb = 2;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\n\t\t/* check DUAL_BANK option bit if the flash is less than 1M */\n\t\tif (is_max_flash_size || (stm32l4_info->optr & FLASH_L4_DUAL_BANK)) {\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32L43_L44XX:\n\tcase DEVID_STM32C01XX:\n\tcase DEVID_STM32C03XX:\n\tcase DEVID_STM32G05_G06XX:\n\tcase DEVID_STM32G07_G08XX:\n\tcase DEVID_STM32L45_L46XX:\n\tcase DEVID_STM32L41_L42XX:\n\tcase DEVID_STM32G03_G04XX:\n\tcase DEVID_STM32G43_G44XX:\n\tcase DEVID_STM32G49_G4AXX:\n\tcase DEVID_STM32WB1XX:\n\t\t/* single bank flash */\n\t\tpage_size_kb = 2;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tbreak;\n\tcase DEVID_STM32G0B_G0CXX:\n\t\t/* single/dual bank depending on DUAL_BANK option bit */\n\t\tpage_size_kb = 2;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tstm32l4_info->cr_bker_mask = FLASH_BKER_G0;\n\n\t\t/* check DUAL_BANK bit */\n\t\tif (stm32l4_info->optr & FLASH_G0_DUAL_BANK) {\n\t\t\tstm32l4_info->sr_bsy_mask = FLASH_BSY | FLASH_BSY2;\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32G47_G48XX:\n\t\t/* STM32G47/8 can be single/dual bank:\n\t\t *   if DUAL_BANK = 0 -> single bank\n\t\t *   else -> dual bank WITH gap\n\t\t */\n\t\tpage_size_kb = 4;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tif (stm32l4_info->optr & FLASH_G4_DUAL_BANK) {\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tpage_size_kb = 2;\n\t\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\n\t\t\t/* for devices with trimmed flash, there is a gap between both banks */\n\t\t\tstm32l4_info->hole_sectors =\n\t\t\t\t(part_info->max_flash_size_kb - flash_size_kb) / (2 * page_size_kb);\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32L4R_L4SXX:\n\tcase DEVID_STM32L4P_L4QXX:\n\t\t/* STM32L4R/S can be single/dual bank:\n\t\t *   if size = 2M check DBANK bit\n\t\t *   if size = 1M check DB1M bit\n\t\t * STM32L4P/Q can be single/dual bank\n\t\t *   if size = 1M check DBANK bit\n\t\t *   if size = 512K check DB512K bit (same as DB1M bit)\n\t\t */\n\t\tpage_size_kb = 8;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tif ((is_max_flash_size && (stm32l4_info->optr & FLASH_L4R_DBANK)) ||\n\t\t\t(!is_max_flash_size && (stm32l4_info->optr & FLASH_LRR_DB1M))) {\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tpage_size_kb = 4;\n\t\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32L55_L56XX:\n\t\t/* STM32L55/L56xx can be single/dual bank:\n\t\t *   if size = 512K check DBANK bit\n\t\t *   if size = 256K check DB256K bit\n\t\t *\n\t\t * default page size is 4kb, if DBANK = 1, the page size is 2kb.\n\t\t */\n\n\t\tpage_size_kb = (stm32l4_info->optr & FLASH_L5_DBANK) ? 2 : 4;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\n\t\tif ((is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DBANK)) ||\n\t\t\t(!is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DB256))) {\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32U57_U58XX:\n\t\t/* if flash size is max (2M) the device is always dual bank\n\t\t * otherwise check DUALBANK\n\t\t */\n\t\tpage_size_kb = 8;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tif (is_max_flash_size || (stm32l4_info->optr & FLASH_U5_DUALBANK)) {\n\t\t\tstm32l4_info->dual_bank_mode = true;\n\t\t\tstm32l4_info->bank1_sectors = num_pages / 2;\n\t\t}\n\t\tbreak;\n\tcase DEVID_STM32WB5XX:\n\tcase DEVID_STM32WB3XX:\n\t\t/* single bank flash */\n\t\tpage_size_kb = 4;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\t\tbreak;\n\tcase DEVID_STM32WLE_WL5XX:\n\t\t/* single bank flash */\n\t\tpage_size_kb = 2;\n\t\tnum_pages = flash_size_kb / page_size_kb;\n\t\tstm32l4_info->bank1_sectors = num_pages;\n\n\t\t/* CPU2 (Cortex-M0+) is supported only with non-hla adapters because it is on AP1.\n\t\t * Using HLA adapters armv7m->debug_ap is null, and checking ap_num triggers a segfault */\n\t\tif (armv7m->debug_ap && armv7m->debug_ap->ap_num == 1)\n\t\t\tstm32l4_info->flash_regs = stm32wl_cpu2_flash_regs;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"unsupported device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* ensure that at least there is 1 flash sector / page */\n\tif (num_pages == 0) {\n\t\tif (stm32l4_info->user_bank_size)\n\t\t\tLOG_ERROR(\"The specified flash size is less than page size\");\n\n\t\tLOG_ERROR(\"Flash pages count cannot be zero\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"flash mode : %s-bank\", stm32l4_info->dual_bank_mode ? \"dual\" : \"single\");\n\n\tconst int gap_size_kb = stm32l4_info->hole_sectors * page_size_kb;\n\n\tif (gap_size_kb != 0) {\n\t\tLOG_INFO(\"gap detected from 0x%08x to 0x%08x\",\n\t\t\tSTM32_FLASH_BANK_BASE + stm32l4_info->bank1_sectors\n\t\t\t\t* page_size_kb * 1024,\n\t\t\tSTM32_FLASH_BANK_BASE + (stm32l4_info->bank1_sectors\n\t\t\t\t* page_size_kb + gap_size_kb) * 1024 - 1);\n\t}\n\n\t/* number of significant bits in WRPxxR differs per device,\n\t * always right adjusted, on some devices non-implemented\n\t * bits read as '0', on others as '1' ...\n\t * notably G4 Cat. 2 implement only 6 bits, contradicting the RM\n\t */\n\n\t/* use *max_flash_size* instead of actual size as the trimmed versions\n\t * certainly use the same number of bits\n\t */\n\tuint32_t max_pages = stm32l4_info->part_info->max_flash_size_kb / page_size_kb;\n\n\t/* in dual bank mode number of pages is doubled, but extra bit is bank selection */\n\tstm32l4_info->wrpxxr_mask = ((max_pages >> (stm32l4_info->dual_bank_mode ? 1 : 0)) - 1);\n\tassert((stm32l4_info->wrpxxr_mask & 0xFFFF0000) == 0);\n\tLOG_DEBUG(\"WRPxxR mask 0x%04\" PRIx16, (uint16_t)stm32l4_info->wrpxxr_mask);\n\n\tfree(bank->sectors);\n\n\tbank->size = (flash_size_kb + gap_size_kb) * 1024;\n\tbank->num_sectors = num_pages;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!bank->sectors) {\n\t\tLOG_ERROR(\"failed to allocate bank sectors\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * page_size_kb * 1024;\n\t\t/* in dual bank configuration, if there is a gap between banks\n\t\t * we fix up the sector offset to consider this gap */\n\t\tif (i >= stm32l4_info->bank1_sectors && stm32l4_info->hole_sectors)\n\t\t\tbank->sectors[i].offset += gap_size_kb * 1024;\n\t\tbank->sectors[i].size = page_size_kb * 1024;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\tstm32l4_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_auto_probe(struct flash_bank *bank)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tif (stm32l4_info->probed) {\n\t\tuint32_t optr_cur;\n\n\t\t/* save flash_regs_base */\n\t\tuint32_t saved_flash_regs_base = stm32l4_info->flash_regs_base;\n\n\t\t/* for devices with TrustZone, use NS flash registers to read OPTR */\n\t\tif (stm32l4_info->part_info->flags & F_HAS_L5_FLASH_REGS)\n\t\t\tstm32l4_info->flash_regs_base &= ~STM32L5_REGS_SEC_OFFSET;\n\n\t\t/* read flash option register and re-probe if optr value is changed */\n\t\tint retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &optr_cur);\n\n\t\t/* restore saved flash_regs_base */\n\t\tstm32l4_info->flash_regs_base = saved_flash_regs_base;\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (stm32l4_info->optr == optr_cur)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn stm32l4_probe(bank);\n}\n\nstatic int get_stm32l4_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tconst struct stm32l4_part_info *part_info = stm32l4_info->part_info;\n\n\tif (part_info) {\n\t\tconst uint16_t rev_id = stm32l4_info->idcode >> 16;\n\t\tcommand_print_sameline(cmd, \"%s - Rev %s : 0x%04x\", part_info->device_str,\n\t\t\t\tget_stm32l4_rev_str(bank), rev_id);\n\t\tif (stm32l4_info->probed)\n\t\t\tcommand_print_sameline(cmd, \" - %s-bank\", get_stm32l4_bank_type_str(bank));\n\t} else {\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as an %s device\", device_families);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32l4_mass_erase(struct flash_bank *bank)\n{\n\tint retval, retval2;\n\tstruct target *target = bank->target;\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"cannot erase OTP memory\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tuint32_t action = FLASH_MER1;\n\n\tif (stm32l4_info->part_info->flags & F_HAS_DUAL_BANK)\n\t\taction |= FLASH_MER2;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* set all FLASH pages as secure */\n\t\tretval = stm32l4_set_secbb(bank, FLASH_SECBB_SECURE);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* restore all FLASH pages as non-secure */\n\t\t\tstm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE); /* ignore the return value */\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = stm32l4_unlock_reg(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\t/* mass erase flash memory */\n\tretval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT / 10);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, action);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, action | FLASH_STRT);\n\tif (retval != ERROR_OK)\n\t\tgoto err_lock;\n\n\tretval = stm32l4_wait_status_busy(bank, FLASH_ERASE_TIMEOUT);\n\nerr_lock:\n\tretval2 = stm32l4_write_flash_reg_by_index(bank, stm32l4_get_flash_cr_with_lock_index(bank), FLASH_LOCK);\n\n\tif (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0)) {\n\t\t/* restore all FLASH pages as non-secure */\n\t\tint retval3 = stm32l4_set_secbb(bank, FLASH_SECBB_NON_SECURE);\n\t\tif (retval3 != ERROR_OK)\n\t\t\treturn retval3;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval2;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1) {\n\t\tcommand_print(CMD, \"stm32l4x mass_erase <STM32L4 bank>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"stm32l4x mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"stm32l4x mass erase failed\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_option_read_command)\n{\n\tif (CMD_ARGC < 2) {\n\t\tcommand_print(CMD, \"stm32l4x option_read <STM32L4 bank> <option_reg offset>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t reg_offset, reg_addr;\n\tuint32_t value = 0;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);\n\treg_addr = stm32l4_get_flash_reg(bank, reg_offset);\n\n\tretval = stm32l4_read_flash_reg(bank, reg_offset, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"Option Register: <0x%\" PRIx32 \"> = 0x%\" PRIx32 \"\", reg_addr, value);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_option_write_command)\n{\n\tif (CMD_ARGC < 3) {\n\t\tcommand_print(CMD, \"stm32l4x option_write <STM32L4 bank> <option_reg offset> <value> [mask]\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t reg_offset;\n\tuint32_t value = 0;\n\tuint32_t mask = 0xFFFFFFFF;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg_offset);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);\n\n\tif (CMD_ARGC > 3)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], mask);\n\n\tcommand_print(CMD, \"%s Option written.\\n\"\n\t\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\t\"for the new settings to take effect.\", bank->driver->name);\n\n\tretval = stm32l4_write_option(bank, reg_offset, value, mask);\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_trustzone_command)\n{\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tif (!(stm32l4_info->part_info->flags & F_HAS_TZ)) {\n\t\tLOG_ERROR(\"This device does not have a TrustZone\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &stm32l4_info->optr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32l4_sync_rdp_tzen(bank);\n\n\tif (CMD_ARGC == 1) {\n\t\t/* only display the TZEN value */\n\t\tLOG_INFO(\"Global TrustZone Security is %s\", stm32l4_info->tzen ? \"enabled\" : \"disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\tbool new_tzen;\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[1], new_tzen);\n\n\tif (new_tzen == stm32l4_info->tzen) {\n\t\tLOG_INFO(\"The requested TZEN is already programmed\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (new_tzen) {\n\t\tif (stm32l4_info->rdp != RDP_LEVEL_0) {\n\t\t\tLOG_ERROR(\"TZEN can be set only when RDP level is 0\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tretval = stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX],\n\t\t\t\tFLASH_TZEN, FLASH_TZEN);\n\t} else {\n\t\t/* Deactivation of TZEN (from 1 to 0) is only possible when the RDP is\n\t\t * changing to level 0 (from level 1 to level 0 or from level 0.5 to level 0). */\n\t\tif (stm32l4_info->rdp != RDP_LEVEL_1 && stm32l4_info->rdp != RDP_LEVEL_0_5) {\n\t\t\tLOG_ERROR(\"Deactivation of TZEN is only possible when the RDP is changing to level 0\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tretval = stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX],\n\t\t\t\tRDP_LEVEL_0, FLASH_RDP_MASK | FLASH_TZEN);\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn stm32l4_perform_obl_launch(bank);\n}\n\nCOMMAND_HANDLER(stm32l4_handle_option_load_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32l4_perform_obl_launch(bank);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"stm32l4x option load failed\");\n\t\treturn retval;\n\t}\n\n\n\tcommand_print(CMD, \"stm32l4x option load completed. Power-on reset might be required\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_lock_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"cannot lock/unlock OTP memory\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* set readout protection level 1 by erasing the RDP option byte */\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tif (stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX],\n\t\t\tRDP_LEVEL_1, FLASH_RDP_MASK) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to lock device\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_unlock_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"cannot lock/unlock OTP memory\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tif (stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX],\n\t\t\tRDP_LEVEL_0, FLASH_RDP_MASK) != ERROR_OK) {\n\t\tcommand_print(CMD, \"%s failed to unlock device\", bank->driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_wrp_info_command)\n{\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (stm32l4_is_otp(bank)) {\n\t\tLOG_ERROR(\"OTP memory does not have write protection areas\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tstruct stm32l4_flash_bank *stm32l4_info = bank->driver_priv;\n\tenum stm32_bank_id dev_bank_id = STM32_ALL_BANKS;\n\tif (CMD_ARGC == 2) {\n\t\tif (strcmp(CMD_ARGV[1], \"bank1\") == 0)\n\t\t\tdev_bank_id = STM32_BANK1;\n\t\telse if (strcmp(CMD_ARGV[1], \"bank2\") == 0)\n\t\t\tdev_bank_id = STM32_BANK2;\n\t\telse\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (dev_bank_id == STM32_BANK2) {\n\t\tif (!(stm32l4_info->part_info->flags & F_HAS_DUAL_BANK)) {\n\t\t\tLOG_ERROR(\"this device has no second bank\");\n\t\t\treturn ERROR_FAIL;\n\t\t} else if (!stm32l4_info->dual_bank_mode) {\n\t\t\tLOG_ERROR(\"this device is configured in single bank mode\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tint ret;\n\tunsigned int n_wrp, i;\n\tstruct stm32l4_wrp wrpxy[4];\n\n\tret = stm32l4_get_all_wrpxy(bank, dev_bank_id, wrpxy, &n_wrp);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* use bitmap and range helpers to better describe protected areas */\n\tDECLARE_BITMAP(pages, bank->num_sectors);\n\tbitmap_zero(pages, bank->num_sectors);\n\n\tfor (i = 0; i < n_wrp; i++) {\n\t\tif (wrpxy[i].used) {\n\t\t\tfor (int p = wrpxy[i].first; p <= wrpxy[i].last; p++)\n\t\t\t\tset_bit(p, pages);\n\t\t}\n\t}\n\n\t/* we have at most 'n_wrp' WRP areas */\n\tstruct range ranges[n_wrp];\n\tunsigned int ranges_count = 0;\n\n\tbitmap_to_ranges(pages, bank->num_sectors, ranges, &ranges_count);\n\n\tif (ranges_count > 0) {\n\t\t/* pretty-print the protected ranges */\n\t\tchar *ranges_str = range_print_alloc(ranges, ranges_count);\n\t\tcommand_print(CMD, \"protected areas: %s\", ranges_str);\n\t\tfree(ranges_str);\n\t} else\n\t\tcommand_print(CMD, \"no protected areas\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32l4_handle_otp_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!stm32l4_is_otp(bank)) {\n\t\tcommand_print(CMD, \"the specified bank is not an OTP memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (strcmp(CMD_ARGV[1], \"enable\") == 0)\n\t\tstm32l4_otp_enable(bank, true);\n\telse if (strcmp(CMD_ARGV[1], \"disable\") == 0)\n\t\tstm32l4_otp_enable(bank, false);\n\telse if (strcmp(CMD_ARGV[1], \"show\") == 0)\n\t\tcommand_print(CMD, \"OTP memory bank #%d is %s for write commands.\",\n\t\t\t\tbank->bank_number, stm32l4_otp_is_enabled(bank) ? \"enabled\" : \"disabled\");\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration stm32l4_exec_command_handlers[] = {\n\t{\n\t\t.name = \"lock\",\n\t\t.handler = stm32l4_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lock entire flash device.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = stm32l4_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Unlock entire protected flash device.\",\n\t},\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stm32l4_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"option_read\",\n\t\t.handler = stm32l4_handle_option_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id reg_offset\",\n\t\t.help = \"Read & Display device option bytes.\",\n\t},\n\t{\n\t\t.name = \"option_write\",\n\t\t.handler = stm32l4_handle_option_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id reg_offset value mask\",\n\t\t.help = \"Write device option bit fields with provided value.\",\n\t},\n\t{\n\t\t.name = \"trustzone\",\n\t\t.handler = stm32l4_handle_trustzone_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"<bank_id> [enable|disable]\",\n\t\t.help = \"Configure TrustZone security\",\n\t},\n\t{\n\t\t.name = \"wrp_info\",\n\t\t.handler = stm32l4_handle_wrp_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id [bank1|bank2]\",\n\t\t.help = \"list the protected areas using WRP\",\n\t},\n\t{\n\t\t.name = \"option_load\",\n\t\t.handler = stm32l4_handle_option_load_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Force re-load of device options (will cause device reset).\",\n\t},\n\t{\n\t\t.name = \"otp\",\n\t\t.handler = stm32l4_handle_otp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"<bank_id> <enable|disable|show>\",\n\t\t.help = \"OTP (One Time Programmable) memory write enable/disable\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm32l4_command_handlers[] = {\n\t{\n\t\t.name = \"stm32l4x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm32l4x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm32l4_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stm32l4x_flash = {\n\t.name = \"stm32l4x\",\n\t.commands = stm32l4_command_handlers,\n\t.flash_bank_command = stm32l4_flash_bank_command,\n\t.erase = stm32l4_erase,\n\t.protect = stm32l4_protect,\n\t.write = stm32l4_write,\n\t.read = default_flash_read,\n\t.probe = stm32l4_probe,\n\t.auto_probe = stm32l4_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stm32l4_protect_check,\n\t.info = get_stm32l4_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32l4x.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Uwe Bonnes                                      *\n *   bon@elektron.ikp.physik.tu-darmstadt.de                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_STM32L4X\n#define OPENOCD_FLASH_NOR_STM32L4X\n\n/* IMPORTANT: this file is included by stm32l4x driver and flashloader,\n * so please when changing this file, do not forget to check the flashloader */\n\n/* FIXME: #include \"helper/bits.h\" cause build errors when compiling\n * the flashloader, for now just redefine the needed 'BIT 'macro */\n\n#ifndef BIT\n#define BIT(nr)                 (1UL << (nr))\n#endif\n\n/* FLASH_CR register bits */\n#define FLASH_PG\t\t\t\tBIT(0)\n#define FLASH_PER\t\t\t\tBIT(1)\n#define FLASH_MER1\t\t\t\tBIT(2)\n#define FLASH_PAGE_SHIFT\t\t3\n#define FLASH_BKER\t\t\t\tBIT(11)\n#define FLASH_BKER_G0\t\t\tBIT(13)\n#define FLASH_MER2\t\t\t\tBIT(15)\n#define FLASH_STRT\t\t\t\tBIT(16)\n#define FLASH_OPTSTRT\t\t\tBIT(17)\n#define FLASH_EOPIE\t\t\t\tBIT(24)\n#define FLASH_ERRIE\t\t\t\tBIT(25)\n#define FLASH_OBL_LAUNCH\t\tBIT(27)\n#define FLASH_OPTLOCK\t\t\tBIT(30)\n#define FLASH_LOCK\t\t\t\tBIT(31)\n\n/* FLASH_SR register bits */\n#define FLASH_BSY\t\t\t\tBIT(16)\n#define FLASH_BSY2\t\t\t\tBIT(17)\n\n/* Fast programming not used => related errors not used*/\n#define FLASH_PGSERR\t\t\tBIT(7) /* Programming sequence error */\n#define FLASH_SIZERR\t\t\tBIT(6) /* Size error */\n#define FLASH_PGAERR\t\t\tBIT(5) /* Programming alignment error */\n#define FLASH_WRPERR\t\t\tBIT(4) /* Write protection error */\n#define FLASH_PROGERR\t\t\tBIT(3) /* Programming error */\n#define FLASH_OPERR\t\t\t\tBIT(1) /* Operation error */\n#define FLASH_EOP\t\t\t\tBIT(0) /* End of operation */\n#define FLASH_ERROR\t\t\t\t(FLASH_PGSERR | FLASH_SIZERR | FLASH_PGAERR | \\\n\t\t\t\t\t\t\t\tFLASH_WRPERR | FLASH_PROGERR | FLASH_OPERR)\n\n/* register unlock keys */\n#define KEY1\t\t\t\t\t0x45670123\n#define KEY2\t\t\t\t\t0xCDEF89AB\n\n/* option register unlock key */\n#define OPTKEY1\t\t\t\t\t0x08192A3B\n#define OPTKEY2\t\t\t\t\t0x4C5D6E7F\n\n/* FLASH_OPTR register bits */\n#define FLASH_RDP_MASK\t\t\t0xFF\n#define FLASH_G0_DUAL_BANK\t\tBIT(21)\n#define FLASH_G4_DUAL_BANK\t\tBIT(22)\n#define FLASH_L4_DUAL_BANK\t\tBIT(21)\n#define FLASH_L4R_DBANK\t\t\tBIT(22)\n#define FLASH_LRR_DB1M\t\t\tBIT(21)\n#define FLASH_L5_DBANK\t\t\tBIT(22)\n#define FLASH_L5_DB256\t\t\tBIT(21)\n#define FLASH_U5_DUALBANK\t\tBIT(21)\n#define FLASH_TZEN\t\t\t\tBIT(31)\n\n/* FLASH secure block based bank 1/2 register offsets */\n#define FLASH_SECBB1(X) (0x80 + 4 * (X - 1))\n#define FLASH_SECBB2(X) (0xA0 + 4 * (X - 1))\n\n#define FLASH_SECBB_SECURE      0xFFFFFFFF\n#define FLASH_SECBB_NON_SECURE  0\n\n/* IDCODE register possible addresses */\n#define DBGMCU_IDCODE_G0\t\t0x40015800\n#define DBGMCU_IDCODE_L4_G4\t\t0xE0042000\n#define DBGMCU_IDCODE_L5\t\t0xE0044000\n#define UID64_DEVNUM\t\t\t0x1FFF7580\n#define UID64_IDS\t\t\t\t0x1FFF7584\n#define UID64_IDS_STM32WL\t\t0x0080E115\n\n/* Supported device IDs */\n#define DEVID_STM32L47_L48XX\t0x415\n#define DEVID_STM32L43_L44XX\t0x435\n#define DEVID_STM32C01XX\t\t0x443\n#define DEVID_STM32C03XX\t\t0x453\n#define DEVID_STM32G05_G06XX\t0x456\n#define DEVID_STM32G07_G08XX\t0x460\n#define DEVID_STM32L49_L4AXX\t0x461\n#define DEVID_STM32L45_L46XX\t0x462\n#define DEVID_STM32L41_L42XX\t0x464\n#define DEVID_STM32G03_G04XX\t0x466\n#define DEVID_STM32G0B_G0CXX\t0x467\n#define DEVID_STM32G43_G44XX\t0x468\n#define DEVID_STM32G47_G48XX\t0x469\n#define DEVID_STM32L4R_L4SXX\t0x470\n#define DEVID_STM32L4P_L4QXX\t0x471\n#define DEVID_STM32L55_L56XX\t0x472\n#define DEVID_STM32G49_G4AXX\t0x479\n#define DEVID_STM32U57_U58XX\t0x482\n#define DEVID_STM32WB1XX\t\t0x494\n#define DEVID_STM32WB5XX\t\t0x495\n#define DEVID_STM32WB3XX\t\t0x496\n#define DEVID_STM32WLE_WL5XX\t0x497\n\n/* known Flash base addresses */\n#define STM32_FLASH_BANK_BASE\t0x08000000\n#define STM32_FLASH_S_BANK_BASE\t0x0C000000\n\n/* offset between non-secure and secure flash registers */\n#define STM32L5_REGS_SEC_OFFSET 0x10000000\n\n/* 100 bytes as loader stack should be large enough for the loader to operate */\n#define LDR_STACK_SIZE\t\t\t100\n\nstruct stm32l4_work_area {\n\tstruct stm32l4_loader_params {\n\t\tuint32_t flash_sr_addr;\n\t\tuint32_t flash_cr_addr;\n\t\tuint32_t flash_word_size;\n\t\tuint32_t flash_sr_bsy_mask;\n\t} params;\n\tuint8_t stack[LDR_STACK_SIZE];\n\tstruct flash_async_algorithm_circbuf {\n\t\t/* note: stm32l4_work_area struct is shared between the loader\n\t\t * and stm32l4x flash driver.\n\t\t *\n\t\t * '*wp' and '*rp' pointers' size is 4 bytes each since stm32l4x\n\t\t * devices have 32-bit processors.\n\t\t * however when used in openocd code, their size depends on the host\n\t\t *   if the host is 32-bit, then the size is 4 bytes each.\n\t\t *   if the host is 64-bit, then the size is 8 bytes each.\n\t\t * to avoid this size difference, change their types depending on the\n\t\t * usage (pointers for the loader, and 32-bit integers in openocd code).\n\t\t */\n#ifdef OPENOCD_CONTRIB_LOADERS_FLASH_STM32_STM32L4X\n\t\tuint8_t *wp;\n\t\tuint8_t *rp;\n#else\n\t\tuint32_t wp;\n\t\tuint32_t rp;\n#endif /* OPENOCD_CONTRIB_LOADERS_FLASH_STM32_STM32L4X */\n\t} fifo;\n};\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stm32lx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Clement Burin des Roziers                       *\n *   clement.burin-des-roziers@hikob.com                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n\n/* stm32lx flash register locations */\n\n#define FLASH_ACR\t\t0x00\n#define FLASH_PECR\t\t0x04\n#define FLASH_PDKEYR\t0x08\n#define FLASH_PEKEYR\t0x0C\n#define FLASH_PRGKEYR\t0x10\n#define FLASH_OPTKEYR\t0x14\n#define FLASH_SR\t\t0x18\n#define FLASH_OBR\t\t0x1C\n#define FLASH_WRPR\t\t0x20\n\n/* FLASH_ACR bites */\n#define FLASH_ACR__LATENCY\t\t(1<<0)\n#define FLASH_ACR__PRFTEN\t\t(1<<1)\n#define FLASH_ACR__ACC64\t\t(1<<2)\n#define FLASH_ACR__SLEEP_PD\t\t(1<<3)\n#define FLASH_ACR__RUN_PD\t\t(1<<4)\n\n/* FLASH_PECR bits */\n#define FLASH_PECR__PELOCK\t\t(1<<0)\n#define FLASH_PECR__PRGLOCK\t\t(1<<1)\n#define FLASH_PECR__OPTLOCK\t\t(1<<2)\n#define FLASH_PECR__PROG\t\t(1<<3)\n#define FLASH_PECR__DATA\t\t(1<<4)\n#define FLASH_PECR__FTDW\t\t(1<<8)\n#define FLASH_PECR__ERASE\t\t(1<<9)\n#define FLASH_PECR__FPRG\t\t(1<<10)\n#define FLASH_PECR__EOPIE\t\t(1<<16)\n#define FLASH_PECR__ERRIE\t\t(1<<17)\n#define FLASH_PECR__OBL_LAUNCH\t(1<<18)\n\n/* FLASH_SR bits */\n#define FLASH_SR__BSY\t\t(1<<0)\n#define FLASH_SR__EOP\t\t(1<<1)\n#define FLASH_SR__ENDHV\t\t(1<<2)\n#define FLASH_SR__READY\t\t(1<<3)\n#define FLASH_SR__WRPERR\t(1<<8)\n#define FLASH_SR__PGAERR\t(1<<9)\n#define FLASH_SR__SIZERR\t(1<<10)\n#define FLASH_SR__OPTVERR\t(1<<11)\n\n/* Unlock keys */\n#define PEKEY1\t\t\t0x89ABCDEF\n#define PEKEY2\t\t\t0x02030405\n#define PRGKEY1\t\t\t0x8C9DAEBF\n#define PRGKEY2\t\t\t0x13141516\n#define OPTKEY1\t\t\t0xFBEAD9C8\n#define OPTKEY2\t\t\t0x24252627\n\n/* other registers */\n#define DBGMCU_IDCODE\t\t0xE0042000\n#define DBGMCU_IDCODE_L0\t0x40015800\n\n/* Constants */\n#define FLASH_SECTOR_SIZE 4096\n#define FLASH_BANK0_ADDRESS 0x08000000\n\n/* option bytes */\n#define OPTION_BYTES_ADDRESS 0x1FF80000\n\n#define OPTION_BYTE_0_PR1 0xFFFF0000\n#define OPTION_BYTE_0_PR0 0xFF5500AA\n\nstatic int stm32lx_unlock_program_memory(struct flash_bank *bank);\nstatic int stm32lx_lock_program_memory(struct flash_bank *bank);\nstatic int stm32lx_enable_write_half_page(struct flash_bank *bank);\nstatic int stm32lx_erase_sector(struct flash_bank *bank, int sector);\nstatic int stm32lx_wait_until_bsy_clear(struct flash_bank *bank);\nstatic int stm32lx_lock(struct flash_bank *bank);\nstatic int stm32lx_unlock(struct flash_bank *bank);\nstatic int stm32lx_mass_erase(struct flash_bank *bank);\nstatic int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int timeout);\nstatic int stm32lx_update_part_info(struct flash_bank *bank, uint16_t flash_size_in_kb);\n\nstruct stm32lx_rev {\n\tuint16_t rev;\n\tconst char *str;\n};\n\nstruct stm32lx_part_info {\n\tuint16_t id;\n\tconst char *device_str;\n\tconst struct stm32lx_rev *revs;\n\tsize_t num_revs;\n\tunsigned int page_size;\n\tunsigned int pages_per_sector;\n\tuint16_t max_flash_size_kb;\n\tuint16_t first_bank_size_kb; /* used when has_dual_banks is true */\n\tbool has_dual_banks;\n\n\tuint32_t flash_base;\t/* Flash controller registers location */\n\tuint32_t fsize_base;\t/* Location of FSIZE register */\n};\n\nstruct stm32lx_flash_bank {\n\tbool probed;\n\tuint32_t idcode;\n\tuint32_t user_bank_size;\n\tuint32_t flash_base;\n\n\tstruct stm32lx_part_info part_info;\n};\n\nstatic const struct stm32lx_rev stm32_416_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1008, \"Y\" }, { 0x1038, \"W\" }, { 0x1078, \"V\" },\n};\nstatic const struct stm32lx_rev stm32_417_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1008, \"Z\" }, { 0x1018, \"Y\" }, { 0x1038, \"X\" }\n};\nstatic const struct stm32lx_rev stm32_425_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" }, { 0x2008, \"Y\" }, { 0x2018, \"1, X\" },\n};\nstatic const struct stm32lx_rev stm32_427_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1018, \"Y\" }, { 0x1038, \"X\" }, { 0x10f8, \"V\" },\n};\nstatic const struct stm32lx_rev stm32_429_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1018, \"Z\" },\n};\nstatic const struct stm32lx_rev stm32_436_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1008, \"Z\" }, { 0x1018, \"Y\" }, { 0x1038, \"X\" },\n};\nstatic const struct stm32lx_rev stm32_437_revs[] = {\n\t{ 0x1000, \"A\" },\n};\nstatic const struct stm32lx_rev stm32_447_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x2000, \"B\" }, { 0x2008, \"Z\" },\n};\nstatic const struct stm32lx_rev stm32_457_revs[] = {\n\t{ 0x1000, \"A\" }, { 0x1008, \"Z\" },\n};\n\nstatic const struct stm32lx_part_info stm32lx_parts[] = {\n\t{\n\t\t.id\t\t\t\t\t= 0x416,\n\t\t.revs\t\t\t\t= stm32_416_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_416_revs),\n\t\t.device_str\t\t\t= \"STM32L1xx (Cat.1 - Low/Medium Density)\",\n\t\t.page_size\t\t\t= 256,\n\t\t.pages_per_sector\t= 16,\n\t\t.max_flash_size_kb\t= 128,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40023C00,\n\t\t.fsize_base\t\t\t= 0x1FF8004C,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x417,\n\t\t.revs\t\t\t\t= stm32_417_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_417_revs),\n\t\t.device_str\t\t\t= \"STM32L0xx (Cat. 3)\",\n\t\t.page_size\t\t\t= 128,\n\t\t.pages_per_sector\t= 32,\n\t\t.max_flash_size_kb\t= 64,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40022000,\n\t\t.fsize_base\t\t\t= 0x1FF8007C,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x425,\n\t\t.revs\t\t\t\t= stm32_425_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_425_revs),\n\t\t.device_str\t\t\t= \"STM32L0xx (Cat. 2)\",\n\t\t.page_size\t\t\t= 128,\n\t\t.pages_per_sector\t= 32,\n\t\t.max_flash_size_kb\t= 32,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40022000,\n\t\t.fsize_base\t\t\t= 0x1FF8007C,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x427,\n\t\t.revs\t\t\t\t= stm32_427_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_427_revs),\n\t\t.device_str\t\t\t= \"STM32L1xx (Cat.3 - Medium+ Density)\",\n\t\t.page_size\t\t\t= 256,\n\t\t.pages_per_sector\t= 16,\n\t\t.max_flash_size_kb\t= 256,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40023C00,\n\t\t.fsize_base\t\t\t= 0x1FF800CC,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x429,\n\t\t.revs\t\t\t\t= stm32_429_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_429_revs),\n\t\t.device_str\t\t\t= \"STM32L1xx (Cat.2)\",\n\t\t.page_size\t\t\t= 256,\n\t\t.pages_per_sector\t= 16,\n\t\t.max_flash_size_kb\t= 128,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40023C00,\n\t\t.fsize_base\t\t\t= 0x1FF8004C,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x436,\n\t\t.revs\t\t\t\t= stm32_436_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_436_revs),\n\t\t.device_str\t\t\t= \"STM32L1xx (Cat.4/Cat.3 - Medium+/High Density)\",\n\t\t.page_size\t\t\t= 256,\n\t\t.pages_per_sector\t= 16,\n\t\t.max_flash_size_kb\t= 384,\n\t\t.first_bank_size_kb\t= 192,\n\t\t.has_dual_banks\t\t= true,\n\t\t.flash_base\t\t\t= 0x40023C00,\n\t\t.fsize_base\t\t\t= 0x1FF800CC,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x437,\n\t\t.revs\t\t\t\t= stm32_437_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_437_revs),\n\t\t.device_str\t\t\t= \"STM32L1xx (Cat.5/Cat.6)\",\n\t\t.page_size\t\t\t= 256,\n\t\t.pages_per_sector\t= 16,\n\t\t.max_flash_size_kb\t= 512,\n\t\t.first_bank_size_kb\t= 0,\t\t/* determined in runtime */\n\t\t.has_dual_banks\t\t= true,\n\t\t.flash_base\t\t\t= 0x40023C00,\n\t\t.fsize_base\t\t\t= 0x1FF800CC,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x447,\n\t\t.revs\t\t\t\t= stm32_447_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_447_revs),\n\t\t.device_str\t\t\t= \"STM32L0xx (Cat.5)\",\n\t\t.page_size\t\t\t= 128,\n\t\t.pages_per_sector\t= 32,\n\t\t.max_flash_size_kb\t= 192,\n\t\t.first_bank_size_kb\t= 0,\t\t/* determined in runtime */\n\t\t.has_dual_banks\t\t= false,\t/* determined in runtime */\n\t\t.flash_base\t\t\t= 0x40022000,\n\t\t.fsize_base\t\t\t= 0x1FF8007C,\n\t},\n\t{\n\t\t.id\t\t\t\t\t= 0x457,\n\t\t.revs\t\t\t\t= stm32_457_revs,\n\t\t.num_revs\t\t\t= ARRAY_SIZE(stm32_457_revs),\n\t\t.device_str\t\t\t= \"STM32L0xx (Cat.1)\",\n\t\t.page_size\t\t\t= 128,\n\t\t.pages_per_sector\t= 32,\n\t\t.max_flash_size_kb\t= 16,\n\t\t.has_dual_banks\t\t= false,\n\t\t.flash_base\t\t\t= 0x40022000,\n\t\t.fsize_base\t\t\t= 0x1FF8007C,\n\t},\n};\n\n/* flash bank stm32lx <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(stm32lx_flash_bank_command)\n{\n\tstruct stm32lx_flash_bank *stm32lx_info;\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Create the bank structure */\n\tstm32lx_info = calloc(1, sizeof(*stm32lx_info));\n\n\t/* Check allocation */\n\tif (!stm32lx_info) {\n\t\tLOG_ERROR(\"failed to allocate bank structure\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = stm32lx_info;\n\n\tstm32lx_info->probed = false;\n\tstm32lx_info->user_bank_size = bank->size;\n\n\t/* the stm32l erased value is 0x00 */\n\tbank->default_padded_value = bank->erased_value = 0x00;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm32lx_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"stm32lx mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"stm32lx mass erase failed\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32lx_handle_lock_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_lock(bank);\n\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"STM32Lx locked, takes effect after power cycle.\");\n\telse\n\t\tcommand_print(CMD, \"STM32Lx lock failed\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stm32lx_handle_unlock_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_unlock(bank);\n\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"STM32Lx unlocked, takes effect after power cycle.\");\n\telse\n\t\tcommand_print(CMD, \"STM32Lx unlock failed\");\n\n\treturn retval;\n}\n\nstatic int stm32lx_protect_check(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\tuint32_t wrpr;\n\n\t/*\n\t * Read the WRPR word, and check each bit (corresponding to each\n\t * flash sector\n\t */\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_WRPR,\n\t\t\t&wrpr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (wrpr & (1 << i))\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval;\n\n\t/*\n\t * It could be possible to do a mass erase if all sectors must be\n\t * erased, but it is not implemented yet.\n\t */\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/*\n\t * Loop over the selected sectors and erase them\n\t */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = stm32lx_erase_sector(bank, i);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbank->sectors[i].is_erased = 1;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_write_half_pages(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\tuint32_t hp_nb = stm32lx_info->part_info.page_size / 2;\n\tuint32_t buffer_size = (16384 / hp_nb) * hp_nb; /* must be multiple of hp_nb */\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\n\tstruct reg_param reg_params[5];\n\tstruct armv7m_algorithm armv7m_info;\n\n\tint retval = ERROR_OK;\n\n\tstatic const uint8_t stm32lx_flash_write_code[] = {\n#include \"../../../contrib/loaders/flash/stm32/stm32lx.inc\"\n\t};\n\n\t/* Make sure we're performing a half-page aligned write. */\n\tif (offset % hp_nb) {\n\t\tLOG_ERROR(\"The offset must be %\" PRIu32 \"B-aligned but it is %\" PRIi32 \"B)\", hp_nb, offset);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (count % hp_nb) {\n\t\tLOG_ERROR(\"The byte count must be %\" PRIu32 \"B-aligned but count is %\" PRIu32 \"B)\", hp_nb, count);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(stm32lx_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no working area for block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Write the flashing code */\n\tretval = target_write_buffer(target,\n\t\t\twrite_algorithm->address,\n\t\t\tsizeof(stm32lx_flash_write_code),\n\t\t\tstm32lx_flash_write_code);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, write_algorithm);\n\t\treturn retval;\n\t}\n\n\t/* Allocate half pages memory */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tif (buffer_size > 1024)\n\t\t\tbuffer_size -= 1024;\n\t\telse\n\t\t\tbuffer_size /= 2;\n\n\t\tif (buffer_size <= stm32lx_info->part_info.page_size) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t} else {\n\t\t\t/* Make sure we're still asking for an integral number of half-pages */\n\t\t\tbuffer_size -= buffer_size % hp_nb;\n\t\t}\n\t}\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_OUT);\n\n\t/* Enable half-page write */\n\tretval = stm32lx_enable_write_half_page(bank);\n\tif (retval != ERROR_OK) {\n\t\ttarget_free_working_area(target, source);\n\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\tdestroy_reg_param(&reg_params[0]);\n\t\tdestroy_reg_param(&reg_params[1]);\n\t\tdestroy_reg_param(&reg_params[2]);\n\t\tdestroy_reg_param(&reg_params[3]);\n\t\tdestroy_reg_param(&reg_params[4]);\n\t\treturn retval;\n\t}\n\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tif (!armv7m) {\n\n\t\t/* something is very wrong if armv7m is NULL */\n\t\tLOG_ERROR(\"unable to get armv7m target\");\n\t\treturn retval;\n\t}\n\n\t/* save any DEMCR flags and configure target to catch any Hard Faults */\n\tuint32_t demcr_save = armv7m->demcr;\n\tarmv7m->demcr = VC_HARDERR;\n\n\t/* Loop while there are bytes to write */\n\twhile (count > 0) {\n\t\tuint32_t this_count;\n\t\tthis_count = (count > buffer_size) ? buffer_size : count;\n\n\t\t/* Write the next half pages */\n\t\tretval = target_write_buffer(target, source->address, this_count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* 4: Store useful information in the registers */\n\t\t/* the destination address of the copy (R0) */\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\t\t/* The source address of the copy (R1) */\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, source->address);\n\t\t/* The number of half pages to copy (R2) */\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, this_count / hp_nb);\n\t\t/* The size in byes of a half page (R3) */\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, hp_nb);\n\t\t/* The flash base address (R4) */\n\t\tbuf_set_u32(reg_params[4].value, 0, 32, stm32lx_info->flash_base);\n\n\t\t/* 5: Execute the bunch of code */\n\t\tretval = target_run_algorithm(target, 0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\twrite_algorithm->address, 0, 10000, &armv7m_info);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* check for Hard Fault */\n\t\tif (armv7m->exception_number == 3)\n\t\t\tbreak;\n\n\t\t/* 6: Wait while busy */\n\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tbuffer += this_count;\n\t\taddress += this_count;\n\t\tcount -= this_count;\n\t}\n\n\t/* restore previous flags */\n\tarmv7m->demcr = demcr_save;\n\n\tif (armv7m->exception_number == 3) {\n\n\t\t/* the stm32l15x devices seem to have an issue when blank.\n\t\t * if a ram loader is executed on a blank device it will\n\t\t * Hard Fault, this issue does not happen for a already programmed device.\n\t\t * A related issue is described in the stm32l151xx errata (Doc ID 17721 Rev 6 - 2.1.3).\n\t\t * The workaround of handling the Hard Fault exception does work, but makes the\n\t\t * loader more complicated, as a compromise we manually write the pages, programming time\n\t\t * is reduced by 50% using this slower method.\n\t\t */\n\n\t\tLOG_WARNING(\"Couldn't use loader, falling back to page memory writes\");\n\n\t\twhile (count > 0) {\n\t\t\tuint32_t this_count;\n\t\t\tthis_count = (count > hp_nb) ? hp_nb : count;\n\n\t\t\t/* Write the next half pages */\n\t\t\tretval = target_write_buffer(target, address, this_count, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\t/* Wait while busy */\n\t\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\tbuffer += this_count;\n\t\t\taddress += this_count;\n\t\t\tcount -= this_count;\n\t\t}\n\t}\n\n\tif (retval == ERROR_OK)\n\t\tretval = stm32lx_lock_program_memory(bank);\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\n\treturn retval;\n}\n\nstatic int stm32lx_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\tuint32_t hp_nb = stm32lx_info->part_info.page_size / 2;\n\tuint32_t halfpages_number;\n\tuint32_t bytes_remaining = 0;\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tint retval, retval2;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x3) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required 4-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tretval = stm32lx_unlock_program_memory(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* first we need to write any unaligned head bytes up to\n\t * the next 128 byte page */\n\n\tif (offset % hp_nb)\n\t\tbytes_remaining = MIN(count, hp_nb - (offset % hp_nb));\n\n\twhile (bytes_remaining > 0) {\n\t\tuint8_t value[4] = {0xff, 0xff, 0xff, 0xff};\n\n\t\t/* copy remaining bytes into the write buffer */\n\t\tuint32_t bytes_to_write = MIN(4, bytes_remaining);\n\t\tmemcpy(value, buffer + bytes_written, bytes_to_write);\n\n\t\tretval = target_write_buffer(target, address, 4, value);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t\tbytes_written += bytes_to_write;\n\t\tbytes_remaining -= bytes_to_write;\n\t\taddress += 4;\n\n\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\t}\n\n\toffset += bytes_written;\n\tcount -= bytes_written;\n\n\t/* this should always pass this check here */\n\tassert((offset % hp_nb) == 0);\n\n\t/* calculate half pages */\n\thalfpages_number = count / hp_nb;\n\n\tif (halfpages_number) {\n\t\tretval = stm32lx_write_half_pages(bank, buffer + bytes_written, offset, hp_nb * halfpages_number);\n\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t/* attempt slow memory writes */\n\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\thalfpages_number = 0;\n\t\t} else {\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* write any remaining bytes */\n\tuint32_t page_bytes_written = hp_nb * halfpages_number;\n\tbytes_written += page_bytes_written;\n\taddress += page_bytes_written;\n\tbytes_remaining = count - page_bytes_written;\n\n\tretval = stm32lx_unlock_program_memory(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (bytes_remaining > 0) {\n\t\tuint8_t value[4] = {0xff, 0xff, 0xff, 0xff};\n\n\t\t/* copy remaining bytes into the write buffer */\n\t\tuint32_t bytes_to_write = MIN(4, bytes_remaining);\n\t\tmemcpy(value, buffer + bytes_written, bytes_to_write);\n\n\t\tretval = target_write_buffer(target, address, 4, value);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\n\t\tbytes_written += bytes_to_write;\n\t\tbytes_remaining -= bytes_to_write;\n\t\taddress += 4;\n\n\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto reset_pg_and_lock;\n\t}\n\nreset_pg_and_lock:\n\tretval2 = stm32lx_lock_program_memory(bank);\n\tif (retval == ERROR_OK)\n\t\tretval = retval2;\n\n\treturn retval;\n}\n\nstatic int stm32lx_read_id_code(struct target *target, uint32_t *id)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint retval;\n\tif (armv7m->arm.arch == ARM_ARCH_V6M)\n\t\tretval = target_read_u32(target, DBGMCU_IDCODE_L0, id);\n\telse\n\t/* read stm32 device id register */\n\t\tretval = target_read_u32(target, DBGMCU_IDCODE, id);\n\treturn retval;\n}\n\nstatic int stm32lx_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tuint16_t flash_size_in_kb;\n\tuint32_t device_id;\n\tuint32_t base_address = FLASH_BANK0_ADDRESS;\n\tuint32_t second_bank_base;\n\tunsigned int n;\n\n\tstm32lx_info->probed = false;\n\n\tint retval = stm32lx_read_id_code(bank->target, &device_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstm32lx_info->idcode = device_id;\n\n\tLOG_DEBUG(\"device id = 0x%08\" PRIx32 \"\", device_id);\n\n\tfor (n = 0; n < ARRAY_SIZE(stm32lx_parts); n++) {\n\t\tif ((device_id & 0xfff) == stm32lx_parts[n].id) {\n\t\t\tstm32lx_info->part_info = stm32lx_parts[n];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (n == ARRAY_SIZE(stm32lx_parts)) {\n\t\tLOG_ERROR(\"Cannot identify target as an STM32 L0 or L1 family device.\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_INFO(\"Device: %s\", stm32lx_info->part_info.device_str);\n\t}\n\n\tstm32lx_info->flash_base = stm32lx_info->part_info.flash_base;\n\n\t/* Get the flash size from target. */\n\tretval = target_read_u16(target, stm32lx_info->part_info.fsize_base,\n\t\t\t&flash_size_in_kb);\n\n\t/* 0x436 devices report their flash size as a 0 or 1 code indicating 384K\n\t * or 256K, respectively.  Please see RM0038 r8 or newer and refer to\n\t * section 30.1.1. */\n\tif (retval == ERROR_OK && (device_id & 0xfff) == 0x436) {\n\t\tif (flash_size_in_kb == 0)\n\t\t\tflash_size_in_kb = 384;\n\t\telse if (flash_size_in_kb == 1)\n\t\t\tflash_size_in_kb = 256;\n\t}\n\n\t/* 0x429 devices only use the lowest 8 bits of the flash size register */\n\tif (retval == ERROR_OK && (device_id & 0xfff) == 0x429) {\n\t\tflash_size_in_kb &= 0xff;\n\t}\n\n\t/* Failed reading flash size or flash size invalid (early silicon),\n\t * default to max target family */\n\tif (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) {\n\t\tLOG_WARNING(\"STM32L flash size failed, probe inaccurate - assuming %dk flash\",\n\t\t\tstm32lx_info->part_info.max_flash_size_kb);\n\t\tflash_size_in_kb = stm32lx_info->part_info.max_flash_size_kb;\n\t} else if (flash_size_in_kb > stm32lx_info->part_info.max_flash_size_kb) {\n\t\tLOG_WARNING(\"STM32L probed flash size assumed incorrect since FLASH_SIZE=%dk > %dk, - assuming %dk flash\",\n\t\t\tflash_size_in_kb, stm32lx_info->part_info.max_flash_size_kb,\n\t\t\tstm32lx_info->part_info.max_flash_size_kb);\n\t\tflash_size_in_kb = stm32lx_info->part_info.max_flash_size_kb;\n\t}\n\n\t/* Overwrite default dual-bank configuration */\n\tretval = stm32lx_update_part_info(bank, flash_size_in_kb);\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (stm32lx_info->part_info.has_dual_banks) {\n\t\t/* Use the configured base address to determine if this is the first or second flash bank.\n\t\t * Verify that the base address is reasonably correct and determine the flash bank size\n\t\t */\n\t\tsecond_bank_base = base_address +\n\t\t\tstm32lx_info->part_info.first_bank_size_kb * 1024;\n\t\tif (bank->base == second_bank_base || !bank->base) {\n\t\t\t/* This is the second bank  */\n\t\t\tbase_address = second_bank_base;\n\t\t\tflash_size_in_kb = flash_size_in_kb -\n\t\t\t\tstm32lx_info->part_info.first_bank_size_kb;\n\t\t} else if (bank->base == base_address) {\n\t\t\t/* This is the first bank */\n\t\t\tflash_size_in_kb = stm32lx_info->part_info.first_bank_size_kb;\n\t\t} else {\n\t\t\tLOG_WARNING(\"STM32L flash bank base address config is incorrect. \"\n\t\t\t\t\tTARGET_ADDR_FMT \" but should rather be 0x%\" PRIx32\n\t\t\t\t\t\" or 0x%\" PRIx32,\n\t\t\t\t\t\tbank->base, base_address, second_bank_base);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"STM32L flash has dual banks. Bank (%u) size is %dkb, base address is 0x%\" PRIx32,\n\t\t\t\tbank->bank_number, flash_size_in_kb, base_address);\n\t} else {\n\t\tLOG_INFO(\"STM32L flash size is %dkb, base address is 0x%\" PRIx32, flash_size_in_kb, base_address);\n\t}\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (stm32lx_info->user_bank_size) {\n\t\tflash_size_in_kb = stm32lx_info->user_bank_size / 1024;\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size: %dkbytes\", flash_size_in_kb);\n\t}\n\n\t/* calculate numbers of sectors (4kB per sector) */\n\tunsigned int num_sectors = (flash_size_in_kb * 1024) / FLASH_SECTOR_SIZE;\n\n\tfree(bank->sectors);\n\n\tbank->size = flash_size_in_kb * 1024;\n\tbank->base = base_address;\n\tbank->num_sectors = num_sectors;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tif (!bank->sectors) {\n\t\tLOG_ERROR(\"failed to allocate bank sectors\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; i < num_sectors; i++) {\n\t\tbank->sectors[i].offset = i * FLASH_SECTOR_SIZE;\n\t\tbank->sectors[i].size = FLASH_SECTOR_SIZE;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\tstm32lx_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_auto_probe(struct flash_bank *bank)\n{\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\tif (stm32lx_info->probed)\n\t\treturn ERROR_OK;\n\n\treturn stm32lx_probe(bank);\n}\n\n/* This method must return a string displaying information about the bank */\nstatic int stm32lx_get_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tconst struct stm32lx_part_info *info = &stm32lx_info->part_info;\n\tuint16_t rev_id = stm32lx_info->idcode >> 16;\n\tconst char *rev_str = NULL;\n\n\tif (!stm32lx_info->probed) {\n\t\tint retval = stm32lx_probe(bank);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print_sameline(cmd, \"Unable to find bank information.\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tfor (unsigned int i = 0; i < info->num_revs; i++)\n\t\tif (rev_id == info->revs[i].rev)\n\t\t\trev_str = info->revs[i].str;\n\n\tif (rev_str) {\n\t\tcommand_print_sameline(cmd, \"%s - Rev: %s\", info->device_str, rev_str);\n\t} else {\n\t\tcommand_print_sameline(cmd, \"%s - Rev: unknown (0x%04x)\", info->device_str, rev_id);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration stm32lx_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stm32lx_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device. including available EEPROM\",\n\t},\n\t{\n\t\t.name = \"lock\",\n\t\t.handler = stm32lx_handle_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Increase the readout protection to Level 1.\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.handler = stm32lx_handle_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Lower the readout protection from Level 1 to 0.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm32lx_command_handlers[] = {\n\t{\n\t\t.name = \"stm32lx\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm32lx flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm32lx_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stm32lx_flash = {\n\t\t.name = \"stm32lx\",\n\t\t.commands = stm32lx_command_handlers,\n\t\t.flash_bank_command = stm32lx_flash_bank_command,\n\t\t.erase = stm32lx_erase,\n\t\t.write = stm32lx_write,\n\t\t.read = default_flash_read,\n\t\t.probe = stm32lx_probe,\n\t\t.auto_probe = stm32lx_auto_probe,\n\t\t.erase_check = default_flash_blank_check,\n\t\t.protect_check = stm32lx_protect_check,\n\t\t.info = stm32lx_get_info,\n\t\t.free_driver_priv = default_flash_free_driver_priv,\n};\n\n/* Static methods implementation */\nstatic int stm32lx_unlock_program_memory(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\tuint32_t reg32;\n\n\t/*\n\t * Unlocking the program memory is done by unlocking the PECR,\n\t * then by writing the 2 PRGKEY to the PRGKEYR register\n\t */\n\n\t/* check flash is not already unlocked */\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((reg32 & FLASH_PECR__PRGLOCK) == 0)\n\t\treturn ERROR_OK;\n\n\t/* To unlock the PECR write the 2 PEKEY to the PEKEYR register */\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR,\n\t\t\tPEKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR,\n\t\t\tPEKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Make sure it worked */\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (reg32 & FLASH_PECR__PELOCK) {\n\t\tLOG_ERROR(\"PELOCK is not cleared :(\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PRGKEYR,\n\t\t\tPRGKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PRGKEYR,\n\t\t\tPRGKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Make sure it worked */\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (reg32 & FLASH_PECR__PRGLOCK) {\n\t\tLOG_ERROR(\"PRGLOCK is not cleared :(\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_enable_write_half_page(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\tuint32_t reg32;\n\n\t/**\n\t * Unlock the program memory, then set the FPRG bit in the PECR register.\n\t */\n\tretval = stm32lx_unlock_program_memory(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg32 |= FLASH_PECR__FPRG;\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\treg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg32 |= FLASH_PECR__PROG;\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\treg32);\n\n\treturn retval;\n}\n\nstatic int stm32lx_lock_program_memory(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\tuint32_t reg32;\n\n\t/* To lock the program memory, simply set the lock bit and lock PECR */\n\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg32 |= FLASH_PECR__PRGLOCK;\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\treg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t&reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treg32 |= FLASH_PECR__PELOCK;\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\treg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_erase_sector(struct flash_bank *bank, int sector)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\tuint32_t reg32;\n\n\t/*\n\t * To erase a sector (i.e. stm32lx_info->part_info.pages_per_sector pages),\n\t * first unlock the memory, loop over the pages of this sector\n\t * and write 0x0 to its first word.\n\t */\n\n\tretval = stm32lx_unlock_program_memory(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (int page = 0; page < (int)stm32lx_info->part_info.pages_per_sector;\n\t\t\tpage++) {\n\t\treg32 = FLASH_PECR__PROG | FLASH_PECR__ERASE;\n\t\tretval = target_write_u32(target,\n\t\t\t\tstm32lx_info->flash_base + FLASH_PECR, reg32);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tuint32_t addr = bank->base + bank->sectors[sector].offset + (page\n\t\t\t\t* stm32lx_info->part_info.page_size);\n\t\tretval = target_write_u32(target, addr, 0x0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = stm32lx_wait_until_bsy_clear(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = stm32lx_lock_program_memory(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic inline int stm32lx_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\treturn target_read_u32(target, stm32lx_info->flash_base + FLASH_SR, status);\n}\n\nstatic int stm32lx_wait_until_bsy_clear(struct flash_bank *bank)\n{\n\treturn stm32lx_wait_until_bsy_clear_timeout(bank, 100);\n}\n\nstatic int stm32lx_unlock_options_bytes(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\tuint32_t reg32;\n\n\t/*\n\t* Unlocking the options bytes is done by unlocking the PECR,\n\t* then by writing the 2 FLASH_PEKEYR to the FLASH_OPTKEYR register\n\t*/\n\n\t/* check flash is not already unlocked */\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, &reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((reg32 & FLASH_PECR__OPTLOCK) == 0)\n\t\treturn ERROR_OK;\n\n\tif ((reg32 & FLASH_PECR__PELOCK) != 0) {\n\n\t\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, PEKEY1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PEKEYR, PEKEY2);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* To unlock the PECR write the 2 OPTKEY to the FLASH_OPTKEYR register */\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_OPTKEYR, OPTKEY1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_OPTKEYR, OPTKEY2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_wait_until_bsy_clear_timeout(struct flash_bank *bank, int timeout)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tuint32_t status;\n\tint retval = ERROR_OK;\n\n\t/* wait for busy to clear */\n\tfor (;;) {\n\t\tretval = stm32lx_get_flash_status(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"status: 0x%\" PRIx32 \"\", status);\n\t\tif ((status & FLASH_SR__BSY) == 0)\n\t\t\tbreak;\n\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t}\n\n\tif (status & FLASH_SR__WRPERR) {\n\t\tLOG_ERROR(\"access denied / write protected\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\tif (status & FLASH_SR__PGAERR) {\n\t\tLOG_ERROR(\"invalid program address\");\n\t\tretval = ERROR_FAIL;\n\t}\n\n\t/* Clear but report errors */\n\tif (status & FLASH_SR__OPTVERR) {\n\t\t/* If this operation fails, we ignore it and report the original retval */\n\t\ttarget_write_u32(target, stm32lx_info->flash_base + FLASH_SR, status & FLASH_SR__OPTVERR);\n\t}\n\n\treturn retval;\n}\n\nstatic int stm32lx_obl_launch(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\tint retval;\n\n\t/* This will fail as the target gets immediately rebooted */\n\ttarget_write_u32(target, stm32lx_info->flash_base + FLASH_PECR,\n\t\t\t FLASH_PECR__OBL_LAUNCH);\n\n\tsize_t tries = 10;\n\tdo {\n\t\ttarget_halt(target);\n\t\tretval = target_poll(target);\n\t} while (--tries > 0 &&\n\t\t (retval != ERROR_OK || target->state != TARGET_HALTED));\n\n\treturn tries ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic int stm32lx_lock(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32lx_unlock_options_bytes(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* set the RDP protection level to 1 */\n\tretval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_unlock(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct target *target = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = stm32lx_unlock_options_bytes(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* set the RDP protection level to 0 */\n\tretval = target_write_u32(target, OPTION_BYTES_ADDRESS, OPTION_BYTE_0_PR0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_wait_until_bsy_clear_timeout(bank, 30000);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_mass_erase(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct target *target = bank->target;\n\tstruct stm32lx_flash_bank *stm32lx_info = NULL;\n\tuint32_t reg32;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstm32lx_info = bank->driver_priv;\n\n\tretval = stm32lx_lock(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_obl_launch(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_unlock(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stm32lx_obl_launch(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, stm32lx_info->flash_base + FLASH_PECR, &reg32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, stm32lx_info->flash_base + FLASH_PECR, reg32 | FLASH_PECR__OPTLOCK);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm32lx_update_part_info(struct flash_bank *bank, uint16_t flash_size_in_kb)\n{\n\tstruct stm32lx_flash_bank *stm32lx_info = bank->driver_priv;\n\n\tswitch (stm32lx_info->part_info.id) {\n\tcase 0x447: /* STM32L0xx (Cat.5) devices */\n\t\tif (flash_size_in_kb == 192 || flash_size_in_kb == 128) {\n\t\t\tstm32lx_info->part_info.first_bank_size_kb = flash_size_in_kb / 2;\n\t\t\tstm32lx_info->part_info.has_dual_banks = true;\n\t\t}\n\t\tbreak;\n\tcase 0x437: /* STM32L1xx (Cat.5/Cat.6) */\n\t\tstm32lx_info->part_info.first_bank_size_kb = flash_size_in_kb / 2;\n\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stmqspi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 - 2019 by Andreas Bolsch                           *\n *   andreas.bolsch@mni.thm.de                                             *\n *                                                                         *\n *   Copyright (C) 2010 by Antonio Borneo                                  *\n *   borneo.antonio@gmail.com                                              *\n ***************************************************************************/\n\n/* STM QuadSPI (QSPI) and OctoSPI (OCTOSPI) controller are SPI bus controllers\n * specifically designed for SPI memories.\n * Two working modes are available:\n * - indirect mode: the SPI is controlled by SW. Any custom commands can be sent\n *   on the bus.\n * - memory mapped mode: the SPI is under QSPI/OCTOSPI control. Memory content\n *   is directly accessible in CPU memory space. CPU can read and execute from\n *   memory (but not write to) */\n\n/* ATTENTION:\n * To have flash mapped in CPU memory space, the QSPI/OCTOSPI controller\n * has to be in \"memory mapped mode\". This requires following constraints:\n * 1) The command \"reset init\" has to initialize QSPI/OCTOSPI controller and put\n *    it in memory mapped mode;\n * 2) every command in this file has to return to prompt in memory mapped mode. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <helper/time_support.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n#include <target/image.h>\n#include \"stmqspi.h\"\n#include \"sfdp.h\"\n\n/* deprecated */\n#undef SPIFLASH_READ\n#undef SPIFLASH_PAGE_PROGRAM\n\n/* saved mode settings */\n#define QSPI_MODE (stmqspi_info->saved_ccr & \\\n\t(0xF0000000U | QSPI_DCYC_MASK | QSPI_4LINE_MODE | QSPI_ALTB_MODE | QSPI_ADDR4))\n\n/* saved read mode settings but indirect read instead of memory mapped\n * in particular, use the dummy cycle setting from this saved setting */\n#define\tQSPI_CCR_READ (QSPI_READ_MODE | (stmqspi_info->saved_ccr & \\\n\t(0xF0000000U | QSPI_DCYC_MASK | QSPI_4LINE_MODE | QSPI_ALTB_MODE | QSPI_ADDR4 | 0xFF)))\n\n/* QSPI_CCR for various other commands, these never use dummy cycles nor alternate bytes */\n#define\tQSPI_CCR_READ_STATUS \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ADDR & QSPI_NO_ALTB) | \\\n\t(QSPI_READ_MODE | SPIFLASH_READ_STATUS))\n\n#define\tQSPI_CCR_READ_ID \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ADDR & QSPI_NO_ALTB) | \\\n\t(QSPI_READ_MODE | SPIFLASH_READ_ID))\n\n#define\tQSPI_CCR_READ_MID \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ADDR & QSPI_NO_ALTB) | \\\n\t(QSPI_READ_MODE | SPIFLASH_READ_MID))\n\n/* always use 3-byte addresses for read SFDP */\n#define\tQSPI_CCR_READ_SFDP \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & ~QSPI_ADDR4 & QSPI_NO_ALTB) | \\\n\t(QSPI_READ_MODE | QSPI_ADDR3 | SPIFLASH_READ_SFDP))\n\n#define QSPI_CCR_WRITE_ENABLE \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ADDR & QSPI_NO_ALTB & QSPI_NO_DATA) | \\\n\t(QSPI_WRITE_MODE | SPIFLASH_WRITE_ENABLE))\n\n#define QSPI_CCR_SECTOR_ERASE \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ALTB & QSPI_NO_DATA) | \\\n\t(QSPI_WRITE_MODE | stmqspi_info->dev.erase_cmd))\n\n#define QSPI_CCR_MASS_ERASE \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ADDR & QSPI_NO_ALTB & QSPI_NO_DATA) | \\\n\t(QSPI_WRITE_MODE | stmqspi_info->dev.chip_erase_cmd))\n\n#define QSPI_CCR_PAGE_PROG \\\n\t((QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ALTB) | \\\n\t(QSPI_WRITE_MODE | stmqspi_info->dev.pprog_cmd))\n\n/* saved mode settings */\n#define OCTOSPI_MODE (stmqspi_info->saved_cr & 0xCFFFFFFF)\n\n#define OPI_MODE ((stmqspi_info->saved_ccr & OCTOSPI_ISIZE_MASK) != 0)\n\n#define OCTOSPI_MODE_CCR (stmqspi_info->saved_ccr & \\\n\t(0xF0000000U | OCTOSPI_8LINE_MODE | OCTOSPI_ALTB_MODE | OCTOSPI_ADDR4))\n\n/* use saved ccr for read */\n#define OCTOSPI_CCR_READ OCTOSPI_MODE_CCR\n\n/* OCTOSPI_CCR for various other commands, these never use alternate bytes\t*\n * for READ_STATUS and READ_ID, 4-byte address 0\t\t\t\t\t\t\t*\n * 4 dummy cycles must sent in OPI mode when DQS is disabled. However, when\t*\n * DQS is enabled, some STM32 devices need at least 6 dummy cycles for\t\t*\n * proper operation, but otherwise the actual number has no effect!\t\t\t*\n * E.g. RM0432 Rev. 7 is incorrect regarding this: L4R9 works well with 4\t*\n * dummy clocks whereas L4P5 not at all.\t\t\t\t\t\t\t\t\t*\n */\n#define OPI_DUMMY \\\n\t((stmqspi_info->saved_ccr & OCTOSPI_DQSEN) ? 6U : 4U)\n\n#define\tOCTOSPI_CCR_READ_STATUS \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_DDTR & \\\n\t(OPI_MODE ? ~0U : OCTOSPI_NO_ADDR) & OCTOSPI_NO_ALTB))\n\n#define\tOCTOSPI_CCR_READ_ID \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_DDTR & \\\n\t(OPI_MODE ? ~0U : OCTOSPI_NO_ADDR) & OCTOSPI_NO_ALTB))\n\n#define\tOCTOSPI_CCR_READ_MID OCTOSPI_CCR_READ_ID\n\n/* 4-byte address in octo mode, else 3-byte address for read SFDP */\n#define\tOCTOSPI_CCR_READ_SFDP(len) \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_DDTR & ~OCTOSPI_ADDR4 & OCTOSPI_NO_ALTB) | \\\n\t(((len) < 4) ? OCTOSPI_ADDR3 : OCTOSPI_ADDR4))\n\n#define OCTOSPI_CCR_WRITE_ENABLE \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_ADDR & OCTOSPI_NO_ALTB & OCTOSPI_NO_DATA))\n\n#define OCTOSPI_CCR_SECTOR_ERASE \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_ALTB & OCTOSPI_NO_DATA))\n\n#define OCTOSPI_CCR_MASS_ERASE \\\n\t((OCTOSPI_MODE_CCR & OCTOSPI_NO_ADDR & OCTOSPI_NO_ALTB & OCTOSPI_NO_DATA))\n\n#define OCTOSPI_CCR_PAGE_PROG \\\n\t((OCTOSPI_MODE_CCR & QSPI_NO_ALTB))\n\n#define SPI_ADSIZE (((stmqspi_info->saved_ccr >> SPI_ADSIZE_POS) & 0x3) + 1)\n\n#define OPI_CMD(cmd) ((OPI_MODE ? ((((uint16_t)(cmd)) << 8) | (~(cmd) & 0xFFU)) : (cmd)))\n\n/* convert uint32_t into 4 uint8_t in little endian byte order */\nstatic inline uint32_t h_to_le_32(uint32_t val)\n{\n\tuint32_t result;\n\n\th_u32_to_le((uint8_t *)&result, val);\n\treturn result;\n}\n\n/* Timeout in ms */\n#define SPI_CMD_TIMEOUT\t\t\t(100)\n#define SPI_PROBE_TIMEOUT\t\t(100)\n#define SPI_MAX_TIMEOUT\t\t\t(2000)\n#define SPI_MASS_ERASE_TIMEOUT\t(400000)\n\nstruct sector_info {\n\tuint32_t offset;\n\tuint32_t size;\n\tuint32_t result;\n};\n\nstruct stmqspi_flash_bank {\n\tbool probed;\n\tchar devname[32];\n\tbool octo;\n\tstruct flash_device dev;\n\tuint32_t io_base;\n\tuint32_t saved_cr;\t/* in particular FSEL, DFM bit mask in QUADSPI_CR *AND* OCTOSPI_CR */\n\tuint32_t saved_ccr; /* different meaning for QUADSPI and OCTOSPI */\n\tuint32_t saved_tcr;\t/* only for OCTOSPI */\n\tuint32_t saved_ir;\t/* only for OCTOSPI */\n\tunsigned int sfdp_dummy1;\t/* number of dummy bytes for SFDP read for flash1 and octo */\n\tunsigned int sfdp_dummy2;\t/* number of dummy bytes for SFDP read for flash2 */\n};\n\nstatic inline int octospi_cmd(struct flash_bank *bank, uint32_t mode,\n\t\tuint32_t ccr, uint32_t ir)\n{\n\tstruct target *target = bank->target;\n\tconst struct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tconst uint32_t io_base = stmqspi_info->io_base;\n\n\tint retval = target_write_u32(target, io_base + OCTOSPI_CR,\n\t\tOCTOSPI_MODE | mode);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, io_base + OCTOSPI_TCR,\n\t\t(stmqspi_info->saved_tcr & ~OCTOSPI_DCYC_MASK) |\n\t\t((OPI_MODE && (mode == OCTOSPI_READ_MODE)) ?\n\t\t(OPI_DUMMY << OCTOSPI_DCYC_POS) : 0));\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, io_base + OCTOSPI_CCR, ccr);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_write_u32(target, io_base + OCTOSPI_IR, OPI_CMD(ir));\n}\n\nFLASH_BANK_COMMAND_HANDLER(stmqspi_flash_bank_command)\n{\n\tstruct stmqspi_flash_bank *stmqspi_info;\n\tuint32_t io_base;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[6], io_base);\n\n\tstmqspi_info = malloc(sizeof(struct stmqspi_flash_bank));\n\tif (!stmqspi_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = stmqspi_info;\n\tstmqspi_info->sfdp_dummy1 = 0;\n\tstmqspi_info->sfdp_dummy2 = 0;\n\tstmqspi_info->probed = false;\n\tstmqspi_info->io_base = io_base;\n\n\treturn ERROR_OK;\n}\n\n/* Poll busy flag */\n/* timeout in ms */\nstatic int poll_busy(struct flash_bank *bank, int timeout)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tlong long endtime;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\tuint32_t spi_sr;\n\t\tint retval = target_read_u32(target, io_base + SPI_SR, &spi_sr);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((spi_sr & BIT(SPI_BUSY)) == 0) {\n\t\t\t/* Clear transmit finished flag */\n\t\t\treturn target_write_u32(target, io_base + SPI_FCR, BIT(SPI_TCF));\n\t\t} else\n\t\t\tLOG_DEBUG(\"busy: 0x%08X\", spi_sr);\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"Timeout while polling BUSY\");\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\nstatic int stmqspi_abort(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tconst struct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tconst uint32_t io_base = stmqspi_info->io_base;\n\tuint32_t cr;\n\n\tint retval = target_read_u32(target, io_base + SPI_CR, &cr);\n\n\tif (retval != ERROR_OK)\n\t\tcr = 0;\n\n\treturn target_write_u32(target, io_base + SPI_CR, cr | BIT(SPI_ABORT));\n}\n\n/* Set to memory-mapped mode, e.g. after an error */\nstatic int set_mm_mode(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tint retval;\n\n\t/* Reset Address register bits 0 and 1, see various errata sheets */\n\tretval = target_write_u32(target, io_base + SPI_AR, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Finally switch to memory mapped mode */\n\tif (IS_OCTOSPI) {\n\t\tretval = target_write_u32(target, io_base + OCTOSPI_CR,\n\t\t\tOCTOSPI_MODE | OCTOSPI_MM_MODE);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, io_base + OCTOSPI_CCR,\n\t\t\t\tstmqspi_info->saved_ccr);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, io_base + OCTOSPI_TCR,\n\t\t\t\tstmqspi_info->saved_tcr);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, io_base + OCTOSPI_IR,\n\t\t\t\tstmqspi_info->saved_ir);\n\t} else {\n\t\tretval = target_write_u32(target, io_base + QSPI_CR,\n\t\t\tstmqspi_info->saved_cr);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_write_u32(target, io_base + QSPI_CCR,\n\t\t\t\tstmqspi_info->saved_ccr);\n\t}\n\treturn retval;\n}\n\n/* Read the status register of the external SPI flash chip(s). */\nstatic int read_status_reg(struct flash_bank *bank, uint16_t *status)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint8_t data;\n\tint count, retval;\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read always two (for DTR mode) bytes per chip */\n\tcount = 2;\n\tretval = target_write_u32(target, io_base + SPI_DLR,\n\t\t((stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 2 * count : count) - 1);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read status */\n\tif (IS_OCTOSPI) {\n\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE, OCTOSPI_CCR_READ_STATUS,\n\t\t\tSPIFLASH_READ_STATUS);\n\t\tif (OPI_MODE) {\n\t\t\t/* Dummy address 0, only required for 8-line mode */\n\t\t\tretval = target_write_u32(target, io_base + SPI_AR, 0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\t} else\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_READ_STATUS);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t*status = 0;\n\n\t/* for debugging only */\n\tuint32_t dummy;\n\t(void)target_read_u32(target, io_base + SPI_SR, &dummy);\n\n\tfor ( ; count > 0; --count) {\n\t\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH)))\n\t\t\t!= BIT(SPI_FSEL_FLASH)) {\n\t\t\t/* get status of flash 1 in dual mode or flash 1 only mode */\n\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t\t*status |= data;\n\t\t}\n\n\t\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0) {\n\t\t\t/* get status of flash 2 in dual mode or flash 2 only mode */\n\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t\t*status |= ((uint16_t)data) << 8;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"flash status regs: 0x%04\" PRIx16, *status);\n\nerr:\n\treturn retval;\n}\n\n/* check for WIP (write in progress) bit(s) in status register(s) */\n/* timeout in ms */\nstatic int wait_till_ready(struct flash_bank *bank, int timeout)\n{\n\tuint16_t status;\n\tint retval;\n\tlong long endtime;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\t/* Read flash status register(s) */\n\t\tretval = read_status_reg(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & ((SPIFLASH_BSY_BIT << 8) | SPIFLASH_BSY_BIT)) == 0)\n\t\t\treturn retval;\n\t\talive_sleep(25);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n/* Send \"write enable\" command to SPI flash chip(s). */\nstatic int qspi_write_enable(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint16_t status;\n\tint retval;\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Send write enable command */\n\tif (IS_OCTOSPI) {\n\t\tretval = octospi_cmd(bank, OCTOSPI_WRITE_MODE, OCTOSPI_CCR_WRITE_ENABLE,\n\t\t\tSPIFLASH_WRITE_ENABLE);\n\t\tif (OPI_MODE) {\n\t\t\t/* Dummy address 0, only required for 8-line mode */\n\t\t\tretval = target_write_u32(target, io_base + SPI_AR, 0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\t} else\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_WRITE_ENABLE);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\n\t/* Wait for transmit of command completed */\n\tpoll_busy(bank, SPI_CMD_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read flash status register */\n\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Check write enabled for flash 1 */\n\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH)))\n\t\t!= BIT(SPI_FSEL_FLASH))\n\t\tif ((status & (SPIFLASH_WE_BIT | SPIFLASH_BSY_BIT)) != SPIFLASH_WE_BIT) {\n\t\t\tLOG_ERROR(\"Cannot write enable flash1. Status=0x%02x\",\n\t\t\t\tstatus & 0xFFU);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t/* Check write enabled for flash 2 */\n\tstatus >>= 8;\n\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0)\n\t\tif ((status & (SPIFLASH_WE_BIT | SPIFLASH_BSY_BIT)) != SPIFLASH_WE_BIT) {\n\t\t\tLOG_ERROR(\"Cannot write enable flash2. Status=0x%02x\",\n\t\t\t\tstatus & 0xFFU);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\nerr:\n\treturn retval;\n}\n\nCOMMAND_HANDLER(stmqspi_handle_mass_erase_command)\n{\n\tstruct target *target = NULL;\n\tstruct flash_bank *bank;\n\tstruct stmqspi_flash_bank *stmqspi_info;\n\tstruct duration bench;\n\tuint32_t io_base;\n\tuint16_t status;\n\tunsigned int sector;\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstmqspi_info = bank->driver_priv;\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (stmqspi_info->dev.chip_erase_cmd == 0x00) {\n\t\tLOG_ERROR(\"Mass erase not available for this device\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tfor (sector = 0; sector < bank->num_sectors; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FLASH_PROTECTED;\n\t\t}\n\t}\n\n\tio_base = stmqspi_info->io_base;\n\tduration_start(&bench);\n\n\tretval = qspi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Send Mass Erase command */\n\tif (IS_OCTOSPI)\n\t\tretval = octospi_cmd(bank, OCTOSPI_WRITE_MODE, OCTOSPI_CCR_MASS_ERASE,\n\t\t\tstmqspi_info->dev.chip_erase_cmd);\n\telse\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_MASS_ERASE);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Wait for transmit of command completed */\n\tpoll_busy(bank, SPI_CMD_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read flash status register(s) */\n\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Check for command in progress for flash 1 */\n\tif (((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH)))\n\t\t!= BIT(SPI_FSEL_FLASH)) && ((status & SPIFLASH_BSY_BIT) == 0) &&\n\t\t((status & SPIFLASH_WE_BIT) != 0)) {\n\t\tLOG_ERROR(\"Mass erase command not accepted by flash1. Status=0x%02x\",\n\t\t\tstatus & 0xFFU);\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err;\n\t}\n\n\t/* Check for command in progress for flash 2 */\n\tstatus >>= 8;\n\tif (((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0) &&\n\t\t((status & SPIFLASH_BSY_BIT) == 0) &&\n\t\t((status & SPIFLASH_WE_BIT) != 0)) {\n\t\tLOG_ERROR(\"Mass erase command not accepted by flash2. Status=0x%02x\",\n\t\t\tstatus & 0xFFU);\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err;\n\t}\n\n\t/* Poll WIP for end of self timed Sector Erase cycle */\n\tretval = wait_till_ready(bank, SPI_MASS_ERASE_TIMEOUT);\n\n\tduration_measure(&bench);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"stmqspi mass erase completed in %fs (%0.3f KiB/s)\",\n\t\t\tduration_elapsed(&bench),\n\t\t\tduration_kbps(&bench, bank->size));\n\telse\n\t\tcommand_print(CMD, \"stmqspi mass erase not completed even after %fs\",\n\t\t\tduration_elapsed(&bench));\n\nerr:\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int log2u(uint32_t word)\n{\n\tint result;\n\n\tfor (result = 0; (unsigned int) result < sizeof(uint32_t) * CHAR_BIT; result++)\n\t\tif (word == BIT(result))\n\t\t\treturn result;\n\n\treturn -1;\n}\n\nCOMMAND_HANDLER(stmqspi_handle_set)\n{\n\tstruct flash_bank *bank = NULL;\n\tstruct target *target = NULL;\n\tstruct stmqspi_flash_bank *stmqspi_info = NULL;\n\tstruct flash_sector *sectors = NULL;\n\tuint32_t io_base;\n\tunsigned int index = 0, dual, fsize;\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\t/* chip_erase_cmd, sectorsize and erase_cmd are optional */\n\tif ((CMD_ARGC < 7) || (CMD_ARGC > 10))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, index++, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget = bank->target;\n\tstmqspi_info = bank->driver_priv;\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\n\t/* invalidate all flash device info */\n\tif (stmqspi_info->probed)\n\t\tfree(bank->sectors);\n\tbank->size = 0;\n\tbank->num_sectors = 0;\n\tbank->sectors = NULL;\n\tstmqspi_info->sfdp_dummy1 = 0;\n\tstmqspi_info->sfdp_dummy2 = 0;\n\tstmqspi_info->probed = false;\n\tmemset(&stmqspi_info->dev, 0, sizeof(stmqspi_info->dev));\n\tstmqspi_info->dev.name = \"unknown\";\n\n\tstrncpy(stmqspi_info->devname, CMD_ARGV[index++], sizeof(stmqspi_info->devname) - 1);\n\tstmqspi_info->devname[sizeof(stmqspi_info->devname) - 1] = '\\0';\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], stmqspi_info->dev.size_in_bytes);\n\tif (log2u(stmqspi_info->dev.size_in_bytes) < 8) {\n\t\tcommand_print(CMD, \"stmqspi: device size must be 2^n with n >= 8\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], stmqspi_info->dev.pagesize);\n\tif (stmqspi_info->dev.pagesize > stmqspi_info->dev.size_in_bytes ||\n\t\t(log2u(stmqspi_info->dev.pagesize) < 0)) {\n\t\tcommand_print(CMD, \"stmqspi: page size must be 2^n and <= device size\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], stmqspi_info->dev.read_cmd);\n\tif ((stmqspi_info->dev.read_cmd != 0x03) &&\n\t\t(stmqspi_info->dev.read_cmd != 0x13)) {\n\t\tcommand_print(CMD, \"stmqspi: only 0x03/0x13 READ cmd allowed\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], stmqspi_info->dev.qread_cmd);\n\tif ((stmqspi_info->dev.qread_cmd != 0x00) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x0B) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x0C) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x3B) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x3C) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x6B) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0x6C) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0xBB) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0xBC) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0xEB) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0xEC) &&\n\t\t(stmqspi_info->dev.qread_cmd != 0xEE)) {\n\t\tcommand_print(CMD, \"stmqspi: only 0x0B/0x0C/0x3B/0x3C/\"\n\t\t\t\"0x6B/0x6C/0xBB/0xBC/0xEB/0xEC/0xEE QREAD allowed\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], stmqspi_info->dev.pprog_cmd);\n\tif ((stmqspi_info->dev.pprog_cmd != 0x02) &&\n\t\t(stmqspi_info->dev.pprog_cmd != 0x12) &&\n\t\t(stmqspi_info->dev.pprog_cmd != 0x32)) {\n\t\tcommand_print(CMD, \"stmqspi: only 0x02/0x12/0x32 PPRG cmd allowed\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (index < CMD_ARGC)\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], stmqspi_info->dev.chip_erase_cmd);\n\telse\n\t\tstmqspi_info->dev.chip_erase_cmd = 0x00;\n\n\tif (index < CMD_ARGC) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], stmqspi_info->dev.sectorsize);\n\t\tif ((stmqspi_info->dev.sectorsize > stmqspi_info->dev.size_in_bytes) ||\n\t\t\t(stmqspi_info->dev.sectorsize < stmqspi_info->dev.pagesize) ||\n\t\t\t(log2u(stmqspi_info->dev.sectorsize) < 0)) {\n\t\t\tcommand_print(CMD, \"stmqspi: sector size must be 2^n and <= device size\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (index < CMD_ARGC)\n\t\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[index++], stmqspi_info->dev.erase_cmd);\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else {\n\t\t/* no sector size / sector erase cmd given, treat whole bank as a single sector */\n\t\tstmqspi_info->dev.erase_cmd = 0x00;\n\t\tstmqspi_info->dev.sectorsize = stmqspi_info->dev.size_in_bytes;\n\t}\n\n\t/* set correct size value */\n\tbank->size = stmqspi_info->dev.size_in_bytes << dual;\n\n\tio_base = stmqspi_info->io_base;\n\n\tuint32_t dcr;\n\tretval = target_read_u32(target, io_base + SPI_DCR, &dcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tfsize = (dcr >> SPI_FSIZE_POS) & (BIT(SPI_FSIZE_LEN) - 1);\n\n\tLOG_DEBUG(\"FSIZE = 0x%04x\", fsize);\n\tif (bank->size == BIT(fsize + 1))\n\t\tLOG_DEBUG(\"FSIZE in DCR(1) matches actual capacity. Beware of silicon bug in H7, L4+, MP1.\");\n\telse if (bank->size == BIT(fsize + 0))\n\t\tLOG_DEBUG(\"FSIZE in DCR(1) is off by one regarding actual capacity. Fix for silicon bug?\");\n\telse\n\t\tLOG_ERROR(\"FSIZE in DCR(1) doesn't match actual capacity.\");\n\n\t/* create and fill sectors array */\n\tbank->num_sectors =\n\t\tstmqspi_info->dev.size_in_bytes / stmqspi_info->dev.sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * (stmqspi_info->dev.sectorsize << dual);\n\t\tsectors[sector].size = (stmqspi_info->dev.sectorsize << dual);\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tstmqspi_info->dev.name = stmqspi_info->devname;\n\tif (stmqspi_info->dev.size_in_bytes / 4096)\n\t\tLOG_INFO(\"flash \\'%s\\' id = unknown\\nchip size = %\" PRIu32 \" KiB,\"\n\t\t\t\" bank size = %\" PRIu32 \" KiB\", stmqspi_info->dev.name,\n\t\t\tstmqspi_info->dev.size_in_bytes / 1024,\n\t\t\t(stmqspi_info->dev.size_in_bytes / 1024) << dual);\n\telse\n\t\tLOG_INFO(\"flash \\'%s\\' id = unknown\\nchip size = %\" PRIu32 \" B,\"\n\t\t\t\" bank size = %\" PRIu32 \" B\", stmqspi_info->dev.name,\n\t\t\tstmqspi_info->dev.size_in_bytes,\n\t\t\tstmqspi_info->dev.size_in_bytes << dual);\n\n\tstmqspi_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stmqspi_handle_cmd)\n{\n\tstruct target *target = NULL;\n\tstruct flash_bank *bank;\n\tstruct stmqspi_flash_bank *stmqspi_info = NULL;\n\tuint32_t io_base, addr;\n\tuint8_t num_write, num_read, cmd_byte, data;\n\tunsigned int count;\n\tconst int max = 21;\n\tchar temp[4], output[(2 + max + 256) * 3 + 8];\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tnum_write = CMD_ARGC - 2;\n\tif (num_write > max) {\n\t\tLOG_ERROR(\"at most %d bytes may be sent\", max);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget = bank->target;\n\tstmqspi_info = bank->driver_priv;\n\tio_base = stmqspi_info->io_base;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], num_read);\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[2], cmd_byte);\n\n\tif (num_read == 0) {\n\t\t/* nothing to read, then one command byte and for dual flash\n\t\t * an *even* number of data bytes to follow */\n\t\tif (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) {\n\t\t\tif ((num_write & 1) == 0) {\n\t\t\t\tLOG_ERROR(\"number of data bytes to write must be even in dual mode\");\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* read mode, one command byte and up to four following address bytes */\n\t\tif (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) {\n\t\t\tif ((num_read & 1) != 0) {\n\t\t\t\tLOG_ERROR(\"number of bytes to read must be even in dual mode\");\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\t\tif ((num_write < 1) || (num_write > 5)) {\n\t\t\tLOG_ERROR(\"one cmd and up to four addr bytes must be send when reading\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send command byte */\n\tsnprintf(output, sizeof(output), \"spi: %02x \", cmd_byte);\n\tif (num_read == 0) {\n\t\t/* write, send cmd byte */\n\t\tretval = target_write_u32(target, io_base + SPI_DLR, ((uint32_t)num_write) - 2);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tif (IS_OCTOSPI)\n\t\t\tretval = octospi_cmd(bank, OCTOSPI_WRITE_MODE,\n\t\t\t\t(OCTOSPI_MODE_CCR & OCTOSPI_NO_ALTB & OCTOSPI_NO_ADDR &\n\t\t\t\t((num_write == 1) ? OCTOSPI_NO_DATA : ~0U)), cmd_byte);\n\t\telse\n\t\t\tretval = target_write_u32(target, io_base + QSPI_CCR,\n\t\t\t\t(QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ALTB & QSPI_NO_ADDR &\n\t\t\t\t((num_write == 1) ? QSPI_NO_DATA : ~0U)) |\n\t\t\t\t(QSPI_WRITE_MODE | cmd_byte));\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* send additional data bytes */\n\t\tfor (count = 3; count < CMD_ARGC; count++) {\n\t\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[count], data);\n\t\t\tsnprintf(temp, sizeof(temp), \"%02\" PRIx8 \" \", data);\n\t\t\tretval = target_write_u8(target, io_base + SPI_DR, data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t\tstrncat(output, temp, sizeof(output) - strlen(output) - 1);\n\t\t}\n\t\tstrncat(output, \"-> \", sizeof(output) - strlen(output) - 1);\n\t} else {\n\t\t/* read, pack additional bytes into address */\n\t\taddr = 0;\n\t\tfor (count = 3; count < CMD_ARGC; count++) {\n\t\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[count], data);\n\t\t\tsnprintf(temp, sizeof(temp), \"%02\" PRIx8 \" \", data);\n\t\t\taddr = (addr << 8) | data;\n\t\t\tstrncat(output, temp, sizeof(output) - strlen(output) - 1);\n\t\t}\n\t\tstrncat(output, \"-> \", sizeof(output) - strlen(output) - 1);\n\n\t\t/* send cmd byte, if ADMODE indicates no address, this already triggers command */\n\t\tretval = target_write_u32(target, io_base + SPI_DLR, ((uint32_t)num_read) - 1);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\t\tif (IS_OCTOSPI)\n\t\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE,\n\t\t\t\t(OCTOSPI_MODE_CCR & OCTOSPI_NO_DDTR & OCTOSPI_NO_ALTB & ~OCTOSPI_ADDR4 &\n\t\t\t\t\t((num_write == 1) ? OCTOSPI_NO_ADDR : ~0U)) |\n\t\t\t\t(((num_write - 2) & 0x3U) << SPI_ADSIZE_POS), cmd_byte);\n\t\telse\n\t\t\tretval = target_write_u32(target, io_base + QSPI_CCR,\n\t\t\t\t(QSPI_MODE & ~QSPI_DCYC_MASK & QSPI_NO_ALTB & ~QSPI_ADDR4 &\n\t\t\t\t\t((num_write == 1) ? QSPI_NO_ADDR : ~0U)) |\n\t\t\t\t((QSPI_READ_MODE | (((num_write - 2) & 0x3U) << SPI_ADSIZE_POS) | cmd_byte)));\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tif (num_write > 1) {\n\t\t\t/* if ADMODE indicates address required, only the write to AR triggers command */\n\t\t\tretval = target_write_u32(target, io_base + SPI_AR, addr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\n\t\t/* read response bytes */\n\t\tfor ( ; num_read > 0; num_read--) {\n\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t\tsnprintf(temp, sizeof(temp), \"%02\" PRIx8 \" \", data);\n\t\t\tstrncat(output, temp, sizeof(output) - strlen(output) - 1);\n\t\t}\n\t}\n\tcommand_print(CMD, \"%s\", output);\n\nerr:\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int qspi_erase_sector(struct flash_bank *bank, unsigned int sector)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint16_t status;\n\tint retval;\n\n\tretval = qspi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Send Sector Erase command */\n\tif (IS_OCTOSPI)\n\t\tretval = octospi_cmd(bank, OCTOSPI_WRITE_MODE, OCTOSPI_CCR_SECTOR_ERASE,\n\t\t\tstmqspi_info->dev.erase_cmd);\n\telse\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_SECTOR_ERASE);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Address is sector offset, this write initiates command transmission */\n\tretval = target_write_u32(target, io_base + SPI_AR, bank->sectors[sector].offset);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Wait for transmit of command completed */\n\tpoll_busy(bank, SPI_CMD_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read flash status register(s) */\n\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tLOG_DEBUG(\"erase status regs: 0x%04\" PRIx16, status);\n\n\t/* Check for command in progress for flash 1 */\n\t/* If BSY and WE are already cleared the erase did probably complete already */\n\tif (((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH)))\n\t\t!= BIT(SPI_FSEL_FLASH)) && ((status & SPIFLASH_BSY_BIT) == 0) &&\n\t\t((status & SPIFLASH_WE_BIT) != 0)) {\n\t\tLOG_ERROR(\"Sector erase command not accepted by flash1. Status=0x%02x\",\n\t\t\tstatus & 0xFFU);\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err;\n\t}\n\n\t/* Check for command in progress for flash 2 */\n\t/* If BSY and WE are already cleared the erase did probably complete already */\n\tstatus >>= 8;\n\tif (((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0) &&\n\t\t((status & SPIFLASH_BSY_BIT) == 0) &&\n\t\t((status & SPIFLASH_WE_BIT) != 0)) {\n\t\tLOG_ERROR(\"Sector erase command not accepted by flash2. Status=0x%02x\",\n\t\t\tstatus & 0xFFU);\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err;\n\t}\n\n\t/* Erase takes a long time, so some sort of progress message is a good idea */\n\tLOG_DEBUG(\"erasing sector %4u\", sector);\n\n\t/* Poll WIP for end of self timed Sector Erase cycle */\n\tretval = wait_till_ready(bank, SPI_MAX_TIMEOUT);\n\nerr:\n\treturn retval;\n}\n\nstatic int stmqspi_erase(struct flash_bank *bank, unsigned int first, unsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tunsigned int sector;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: from sector %u to sector %u\", __func__, first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (stmqspi_info->dev.erase_cmd == 0x00) {\n\t\tLOG_ERROR(\"Sector erase not available for this device\");\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tfor (sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FLASH_PROTECTED;\n\t\t}\n\t}\n\n\tfor (sector = first; sector <= last; sector++) {\n\t\tretval = qspi_erase_sector(bank, sector);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\talive_sleep(10);\n\t\tkeep_alive();\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Flash sector_erase failed on sector %u\", sector);\n\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int stmqspi_protect(struct flash_bank *bank, int set,\n\tunsigned int first, unsigned int last)\n{\n\tunsigned int sector;\n\n\tfor (sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\n\tif (set)\n\t\tLOG_WARNING(\"setting soft protection only, not related to flash's hardware write protection\");\n\n\treturn ERROR_OK;\n}\n\n/* Check whether flash is blank */\nstatic int stmqspi_blank_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tstruct duration bench;\n\tstruct reg_param reg_params[2];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *algorithm;\n\tconst uint8_t *code;\n\tstruct sector_info erase_check_info;\n\tuint32_t codesize, maxsize, result, exit_point;\n\tunsigned int count, index, num_sectors, sector;\n\tint retval;\n\tconst uint32_t erased = 0x00FF;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* see contrib/loaders/flash/stmqspi/stmqspi_erase_check.S for src */\n\tstatic const uint8_t stmqspi_erase_check_code[] = {\n\t\t#include \"../../../contrib/loaders/flash/stmqspi/stmqspi_erase_check.inc\"\n\t};\n\n\t/* see contrib/loaders/flash/stmqspi/stmoctospi_erase_check.S for src */\n\tstatic const uint8_t stmoctospi_erase_check_code[] = {\n\t\t#include \"../../../contrib/loaders/flash/stmqspi/stmoctospi_erase_check.inc\"\n\t};\n\n\tif (IS_OCTOSPI) {\n\t\tcode = stmoctospi_erase_check_code;\n\t\tcodesize = sizeof(stmoctospi_erase_check_code);\n\t} else {\n\t\tcode = stmqspi_erase_check_code;\n\t\tcodesize = sizeof(stmqspi_erase_check_code);\n\t}\n\n\t/* This will overlay the last 4 words of stmqspi/stmoctospi_erase_check_code in target */\n\t/* for read use the saved settings (memory mapped mode) but indirect read mode */\n\tuint32_t ccr_buffer[][4] = {\n\t\t/* cr  (not used for QSPI)\t\t\t*\n\t\t * ccr (for both QSPI and OCTOSPI)\t*\n\t\t * tcr (not used for QSPI)\t\t\t*\n\t\t * ir  (not used for QSPI)\t\t\t*/\n\t\t{\n\t\t\th_to_le_32(OCTOSPI_MODE | OCTOSPI_READ_MODE),\n\t\t\th_to_le_32(IS_OCTOSPI ? OCTOSPI_CCR_READ : QSPI_CCR_READ),\n\t\t\th_to_le_32(stmqspi_info->saved_tcr),\n\t\t\th_to_le_32(stmqspi_info->saved_ir),\n\t\t},\n\t};\n\n\tmaxsize = target_get_working_area_avail(target);\n\tif (maxsize < codesize + sizeof(erase_check_info)) {\n\t\tLOG_ERROR(\"Not enough working area, can't do QSPI blank check\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tnum_sectors = (maxsize - codesize) / sizeof(erase_check_info);\n\tnum_sectors = (bank->num_sectors < num_sectors) ? bank->num_sectors : num_sectors;\n\n\tif (target_alloc_working_area_try(target,\n\t\t\tcodesize + num_sectors * sizeof(erase_check_info), &algorithm) != ERROR_OK) {\n\t\tLOG_ERROR(\"allocating working area failed\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t};\n\n\t/* prepare blank check code, excluding ccr_buffer */\n\tretval = target_write_buffer(target, algorithm->address,\n\t\tcodesize - sizeof(ccr_buffer), code);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* prepare QSPI/OCTOSPI_CCR register values */\n\tretval = target_write_buffer(target, algorithm->address\n\t\t+ codesize - sizeof(ccr_buffer),\n\t\tsizeof(ccr_buffer), (uint8_t *)ccr_buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tduration_start(&bench);\n\n\t/* after breakpoint instruction (halfword), one nop (halfword) and\n\t * port_buffer till end of code */\n\texit_point = algorithm->address + codesize - sizeof(uint32_t) - sizeof(ccr_buffer);\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\t/* sector count */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* QSPI/OCTOSPI io_base */\n\n\tsector = 0;\n\twhile (sector < bank->num_sectors) {\n\t\t/* at most num_sectors sectors to handle in one run */\n\t\tcount = bank->num_sectors - sector;\n\t\tif (count > num_sectors)\n\t\t\tcount = num_sectors;\n\n\t\tfor (index = 0; index < count; index++) {\n\t\t\terase_check_info.offset = h_to_le_32(bank->sectors[sector + index].offset);\n\t\t\terase_check_info.size = h_to_le_32(bank->sectors[sector + index].size);\n\t\t\terase_check_info.result = h_to_le_32(erased);\n\n\t\t\tretval = target_write_buffer(target, algorithm->address\n\t\t\t\t+ codesize + index * sizeof(erase_check_info),\n\t\t\t\t\tsizeof(erase_check_info), (uint8_t *)&erase_check_info);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, count);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, stmqspi_info->io_base);\n\n\t\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\t\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t\tLOG_DEBUG(\"checking sectors %u to %u\", sector, sector + count - 1);\n\t\t/* check a block of sectors */\n\t\tretval = target_run_algorithm(target,\n\t\t\t0, NULL,\n\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\talgorithm->address, exit_point,\n\t\t\tcount * ((bank->sectors[sector].size >> 6) + 1) + 1000,\n\t\t\t&armv7m_info);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tfor (index = 0; index < count; index++) {\n\t\t\tretval = target_read_buffer(target, algorithm->address\n\t\t\t\t+ codesize + index * sizeof(erase_check_info),\n\t\t\t\t\tsizeof(erase_check_info), (uint8_t *)&erase_check_info);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\n\t\t\tif ((erase_check_info.offset != h_to_le_32(bank->sectors[sector + index].offset)) ||\n\t\t\t\t(erase_check_info.size != 0)) {\n\t\t\t\tLOG_ERROR(\"corrupted blank check info\");\n\t\t\t\tgoto err;\n\t\t\t}\n\n\t\t\t/* we need le_32_to_h, but that's the same as h_to_le_32 */\n\t\t\tresult = h_to_le_32(erase_check_info.result);\n\t\t\tbank->sectors[sector + index].is_erased = ((result & 0xFF) == 0xFF);\n\t\t\tLOG_DEBUG(\"Flash sector %u checked: 0x%04x\", sector + index, result & 0xFFFFU);\n\t\t}\n\t\tkeep_alive();\n\t\tsector += count;\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\tduration_measure(&bench);\n\tLOG_INFO(\"stmqspi blank checked in %fs (%0.3f KiB/s)\", duration_elapsed(&bench),\n\t\tduration_kbps(&bench, bank->size));\n\nerr:\n\ttarget_free_working_area(target, algorithm);\n\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\n/* Verify checksum */\nstatic int qspi_verify(struct flash_bank *bank, uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *algorithm;\n\tconst uint8_t *code;\n\tuint32_t pagesize, codesize, crc32, result, exit_point;\n\tint retval;\n\n\t/* see contrib/loaders/flash/stmqspi/stmqspi_crc32.S for src */\n\tstatic const uint8_t stmqspi_crc32_code[] = {\n\t\t#include \"../../../contrib/loaders/flash/stmqspi/stmqspi_crc32.inc\"\n\t};\n\n\t/* see contrib/loaders/flash/stmqspi/stmoctospi_crc32.S for src */\n\tstatic const uint8_t stmoctospi_crc32_code[] = {\n\t\t#include \"../../../contrib/loaders/flash/stmqspi/stmoctospi_crc32.inc\"\n\t};\n\n\tif (IS_OCTOSPI) {\n\t\tcode = stmoctospi_crc32_code;\n\t\tcodesize = sizeof(stmoctospi_crc32_code);\n\t} else {\n\t\tcode = stmqspi_crc32_code;\n\t\tcodesize = sizeof(stmqspi_crc32_code);\n\t}\n\n\t/* block size doesn't matter that much here */\n\tpagesize = stmqspi_info->dev.sectorsize;\n\tif (pagesize == 0)\n\t\tpagesize = stmqspi_info->dev.pagesize;\n\tif (pagesize == 0)\n\t\tpagesize = SPIFLASH_DEF_PAGESIZE;\n\n\t/* adjust size according to dual flash mode */\n\tpagesize = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? pagesize << 1 : pagesize;\n\n\t/* This will overlay the last 4 words of stmqspi/stmoctospi_crc32_code in target */\n\t/* for read use the saved settings (memory mapped mode) but indirect read mode */\n\tuint32_t ccr_buffer[][4] = {\n\t\t/* cr  (not used for QSPI)\t\t\t*\n\t\t * ccr (for both QSPI and OCTOSPI)\t*\n\t\t * tcr (not used for QSPI)\t\t\t*\n\t\t * ir  (not used for QSPI)\t\t\t*/\n\t\t{\n\t\t\th_to_le_32(OCTOSPI_MODE | OCTOSPI_READ_MODE),\n\t\t\th_to_le_32(IS_OCTOSPI ? OCTOSPI_CCR_READ : QSPI_CCR_READ),\n\t\t\th_to_le_32(stmqspi_info->saved_tcr),\n\t\t\th_to_le_32(stmqspi_info->saved_ir),\n\t\t},\n\t};\n\n\tif (target_alloc_working_area_try(target, codesize, &algorithm) != ERROR_OK) {\n\t\tLOG_ERROR(\"Not enough working area, can't do QSPI verify\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t};\n\n\t/* prepare verify code, excluding ccr_buffer */\n\tretval = target_write_buffer(target, algorithm->address,\n\t\tcodesize - sizeof(ccr_buffer), code);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* prepare QSPI/OCTOSPI_CCR register values */\n\tretval = target_write_buffer(target, algorithm->address\n\t\t+ codesize - sizeof(ccr_buffer),\n\t\tsizeof(ccr_buffer), (uint8_t *)ccr_buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* after breakpoint instruction (halfword), one nop (halfword) and\n\t * port_buffer till end of code */\n\texit_point = algorithm->address + codesize - sizeof(uint32_t) - sizeof(ccr_buffer);\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* count (in), crc32 (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* pagesize */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\t/* offset into flash address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* QSPI/OCTOSPI io_base */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, count);\n\tbuf_set_u32(reg_params[1].value, 0, 32, pagesize);\n\tbuf_set_u32(reg_params[2].value, 0, 32, offset);\n\tbuf_set_u32(reg_params[3].value, 0, 32, stmqspi_info->io_base);\n\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tretval = target_run_algorithm(target,\n\t\t0, NULL,\n\t\tARRAY_SIZE(reg_params), reg_params,\n\t\talgorithm->address, exit_point,\n\t\t(count >> 5) + 1000,\n\t\t&armv7m_info);\n\tkeep_alive();\n\n\timage_calculate_checksum(buffer, count, &crc32);\n\n\tif (retval == ERROR_OK) {\n\t\tresult = buf_get_u32(reg_params[0].value, 0, 32);\n\t\tLOG_DEBUG(\"addr \" TARGET_ADDR_FMT \", len 0x%08\" PRIx32 \", crc 0x%08\" PRIx32 \" 0x%08\" PRIx32,\n\t\t\toffset + bank->base, count, ~crc32, result);\n\t\tif (~crc32 != result)\n\t\t\tretval = ERROR_FAIL;\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\nerr:\n\ttarget_free_working_area(target, algorithm);\n\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int qspi_read_write_block(struct flash_bank *bank, uint8_t *buffer,\n\tuint32_t offset, uint32_t count, bool write)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tstruct reg_param reg_params[6];\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct working_area *algorithm;\n\tuint32_t pagesize, fifo_start, fifosize, remaining;\n\tuint32_t maxsize, codesize, exit_point;\n\tconst uint8_t *code = NULL;\n\tunsigned int dual;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" len=0x%08\" PRIx32,\n\t\t__func__, offset, count);\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\n\t/* see contrib/loaders/flash/stmqspi/stmqspi_read.S for src */\n\tstatic const uint8_t stmqspi_read_code[] = {\n#include \"../../../contrib/loaders/flash/stmqspi/stmqspi_read.inc\"\n\t};\n\n\t/* see contrib/loaders/flash/stmqspi/stmoctospi_read.S for src */\n\tstatic const uint8_t stmoctospi_read_code[] = {\n#include \"../../../contrib/loaders/flash/stmqspi/stmoctospi_read.inc\"\n\t};\n\n\t/* see contrib/loaders/flash/stmqspi/stmqspi_write.S for src */\n\tstatic const uint8_t stmqspi_write_code[] = {\n#include \"../../../contrib/loaders/flash/stmqspi/stmqspi_write.inc\"\n\t};\n\n\t/* see contrib/loaders/flash/stmqspi/stmoctospi_write.S for src */\n\tstatic const uint8_t stmoctospi_write_code[] = {\n#include \"../../../contrib/loaders/flash/stmqspi/stmoctospi_write.inc\"\n\t};\n\n\t/* This will overlay the last 12 words of stmqspi/stmoctospi_read/write_code in target */\n\t/* for read use the saved settings (memory mapped mode) but indirect read mode */\n\tuint32_t ccr_buffer[][4] = {\n\t\t/* cr  (not used for QSPI)\t\t\t*\n\t\t * ccr (for both QSPI and OCTOSPI)\t*\n\t\t * tcr (not used for QSPI)\t\t\t*\n\t\t * ir  (not used for QSPI)\t\t\t*/\n\t\t{\n\t\t\th_to_le_32(OCTOSPI_MODE | OCTOSPI_READ_MODE),\n\t\t\th_to_le_32(IS_OCTOSPI ? OCTOSPI_CCR_READ_STATUS : QSPI_CCR_READ_STATUS),\n\t\t\th_to_le_32((stmqspi_info->saved_tcr & ~OCTOSPI_DCYC_MASK) |\n\t\t\t\t\t\t(OPI_MODE ? (OPI_DUMMY << OCTOSPI_DCYC_POS) : 0)),\n\t\t\th_to_le_32(OPI_CMD(SPIFLASH_READ_STATUS)),\n\t\t},\n\t\t{\n\t\t\th_to_le_32(OCTOSPI_MODE | OCTOSPI_WRITE_MODE),\n\t\t\th_to_le_32(IS_OCTOSPI ? OCTOSPI_CCR_WRITE_ENABLE : QSPI_CCR_WRITE_ENABLE),\n\t\t\th_to_le_32(stmqspi_info->saved_tcr & ~OCTOSPI_DCYC_MASK),\n\t\t\th_to_le_32(OPI_CMD(SPIFLASH_WRITE_ENABLE)),\n\t\t},\n\t\t{\n\t\t\th_to_le_32(OCTOSPI_MODE | (write ? OCTOSPI_WRITE_MODE : OCTOSPI_READ_MODE)),\n\t\t\th_to_le_32(write ? (IS_OCTOSPI ? OCTOSPI_CCR_PAGE_PROG : QSPI_CCR_PAGE_PROG) :\n\t\t\t\t(IS_OCTOSPI ? OCTOSPI_CCR_READ : QSPI_CCR_READ)),\n\t\t\th_to_le_32(write ? (stmqspi_info->saved_tcr & ~OCTOSPI_DCYC_MASK) :\n\t\t\t\tstmqspi_info->saved_tcr),\n\t\t\th_to_le_32(write ? OPI_CMD(stmqspi_info->dev.pprog_cmd) : stmqspi_info->saved_ir),\n\t\t},\n\t};\n\n\t/* force reasonable defaults */\n\tfifosize = stmqspi_info->dev.sectorsize ?\n\t\tstmqspi_info->dev.sectorsize : stmqspi_info->dev.size_in_bytes;\n\n\tif (write) {\n\t\tif (IS_OCTOSPI) {\n\t\t\tcode = stmoctospi_write_code;\n\t\t\tcodesize = sizeof(stmoctospi_write_code);\n\t\t} else {\n\t\t\tcode = stmqspi_write_code;\n\t\t\tcodesize = sizeof(stmqspi_write_code);\n\t\t}\n\t} else {\n\t\tif (IS_OCTOSPI) {\n\t\t\tcode = stmoctospi_read_code;\n\t\t\tcodesize = sizeof(stmoctospi_read_code);\n\t\t} else {\n\t\t\tcode = stmqspi_read_code;\n\t\t\tcodesize = sizeof(stmqspi_read_code);\n\t\t}\n\t}\n\n\t/* for write, pagesize must be taken into account */\n\t/* for read, the page size doesn't matter that much */\n\tpagesize = stmqspi_info->dev.pagesize;\n\tif (pagesize == 0)\n\t\tpagesize = (fifosize <= SPIFLASH_DEF_PAGESIZE) ?\n\t\t\tfifosize : SPIFLASH_DEF_PAGESIZE;\n\n\t/* adjust sizes according to dual flash mode */\n\tpagesize <<= dual;\n\tfifosize <<= dual;\n\n\t/* memory buffer, we assume sectorsize to be a power of 2 times pagesize */\n\tmaxsize = target_get_working_area_avail(target);\n\tif (maxsize < codesize + 2 * sizeof(uint32_t) + pagesize) {\n\t\tLOG_ERROR(\"not enough working area, can't do QSPI page reads/writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* fifo size at most sector size, and multiple of page size */\n\tmaxsize -= (codesize + 2 * sizeof(uint32_t));\n\tfifosize = ((maxsize < fifosize) ? maxsize : fifosize) & ~(pagesize - 1);\n\n\tif (target_alloc_working_area_try(target,\n\t\tcodesize + 2 * sizeof(uint32_t) + fifosize, &algorithm) != ERROR_OK) {\n\t\tLOG_ERROR(\"allocating working area failed\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t};\n\n\t/* prepare flash write code, excluding ccr_buffer */\n\tretval = target_write_buffer(target, algorithm->address,\n\t\tcodesize - sizeof(ccr_buffer), code);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* prepare QSPI/OCTOSPI_CCR register values */\n\tretval = target_write_buffer(target, algorithm->address\n\t\t+ codesize - sizeof(ccr_buffer),\n\t\tsizeof(ccr_buffer), (uint8_t *)ccr_buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* target buffer starts right after flash_write_code, i.e.\n\t * wp and rp are implicitly included in buffer!!! */\n\tfifo_start = algorithm->address + codesize + 2 * sizeof(uint32_t);\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT); /* count (in), status (out) */\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\t/* pagesize */\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_IN_OUT);\t/* offset into flash address */\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\t/* QSPI/OCTOSPI io_base */\n\tinit_reg_param(&reg_params[4], \"r8\", 32, PARAM_OUT);\t/* fifo start */\n\tinit_reg_param(&reg_params[5], \"r9\", 32, PARAM_OUT);\t/* fifo end + 1 */\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, count);\n\tbuf_set_u32(reg_params[1].value, 0, 32, pagesize);\n\tbuf_set_u32(reg_params[2].value, 0, 32, offset);\n\tbuf_set_u32(reg_params[3].value, 0, 32, io_base);\n\tbuf_set_u32(reg_params[4].value, 0, 32, fifo_start);\n\tbuf_set_u32(reg_params[5].value, 0, 32, fifo_start + fifosize);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\t/* after breakpoint instruction (halfword), one nop (halfword) and\n\t * ccr_buffer follow till end of code */\n\texit_point = algorithm->address + codesize\n\t\t- (sizeof(ccr_buffer) + sizeof(uint32_t));\n\n\tif (write) {\n\t\tretval = target_run_flash_async_algorithm(target, buffer, count, 1,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\talgorithm->address + codesize,\n\t\t\t\tfifosize + 2 * sizeof(uint32_t),\n\t\t\t\talgorithm->address, exit_point,\n\t\t\t\t&armv7m_info);\n\t} else {\n\t\tretval = target_run_read_async_algorithm(target, buffer, count, 1,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\talgorithm->address + codesize,\n\t\t\t\tfifosize + 2 * sizeof(uint32_t),\n\t\t\t\talgorithm->address, exit_point,\n\t\t\t\t&armv7m_info);\n\t}\n\n\tremaining = buf_get_u32(reg_params[0].value, 0, 32);\n\tif ((retval == ERROR_OK) && remaining)\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\n\tif (retval != ERROR_OK) {\n\t\toffset = buf_get_u32(reg_params[2].value, 0, 32);\n\t\tLOG_ERROR(\"flash %s failed at address 0x%\" PRIx32 \", remaining 0x%\" PRIx32,\n\t\t\twrite ? \"write\" : \"read\", offset, remaining);\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\nerr:\n\ttarget_free_working_area(target, algorithm);\n\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int stmqspi_read(struct flash_bank *bank, uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t__func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Read beyond end of flash. Extra data to be ignored.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn qspi_read_write_block(bank, buffer, offset, count, false);\n}\n\nstatic int stmqspi_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tunsigned int dual, sector;\n\tbool octal_dtr;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t__func__, offset, count);\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\toctal_dtr = IS_OCTOSPI && (stmqspi_info->saved_ccr & BIT(OCTOSPI_DDTR));\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Write beyond end of flash. Extra data discarded.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tif ((offset < (bank->sectors[sector].offset + bank->sectors[sector].size)) &&\n\t\t\t((offset + count - 1) >= bank->sectors[sector].offset) &&\n\t\t\tbank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FLASH_PROTECTED;\n\t\t}\n\t}\n\n\tif ((dual || octal_dtr) && ((offset & 1) != 0 || (count & 1) != 0)) {\n\t\tLOG_ERROR(\"In dual-QSPI and octal-DTR modes writes must be two byte aligned: \"\n\t\t\t\"%s: address=0x%08\" PRIx32 \" len=0x%08\" PRIx32, __func__, offset, count);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn qspi_read_write_block(bank, (uint8_t *)buffer, offset, count, true);\n}\n\nstatic int stmqspi_verify(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tunsigned int dual;\n\tbool octal_dtr;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t__func__, offset, count);\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\toctal_dtr = IS_OCTOSPI && (stmqspi_info->saved_ccr & BIT(OCTOSPI_DDTR));\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!(stmqspi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tif (offset + count > bank->size) {\n\t\tLOG_WARNING(\"Verify beyond end of flash. Extra data ignored.\");\n\t\tcount = bank->size - offset;\n\t}\n\n\tif ((dual || octal_dtr) && ((offset & 1) != 0 || (count & 1) != 0)) {\n\t\tLOG_ERROR(\"In dual-QSPI and octal-DTR modes reads must be two byte aligned: \"\n\t\t\t\"%s: address=0x%08\" PRIx32 \" len=0x%08\" PRIx32, __func__, offset, count);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn qspi_verify(bank, (uint8_t *)buffer, offset, count);\n}\n\n/* Find appropriate dummy setting, in particular octo mode */\nstatic int find_sfdp_dummy(struct flash_bank *bank, int len)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint8_t data;\n\tunsigned int dual, count;\n\tbool flash1 = !(stmqspi_info->saved_cr & BIT(SPI_FSEL_FLASH));\n\tint retval;\n\tconst unsigned int max_bytes = 64;\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\n\tLOG_DEBUG(\"%s: len=%d, dual=%u, flash1=%d\",\n\t\t__func__, len, dual, flash1);\n\n\t/* Abort any previous operation */\n\tretval = target_write_u32(target, io_base + SPI_CR,\n\t\tstmqspi_info->saved_cr | BIT(SPI_ABORT));\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Switch to saved_cr (had to be set accordingly before this call) */\n\tretval = target_write_u32(target, io_base + SPI_CR, stmqspi_info->saved_cr);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read at most that many bytes */\n\tretval = target_write_u32(target, io_base + SPI_DLR, (max_bytes << dual) - 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read SFDP block */\n\tif (IS_OCTOSPI)\n\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE,\n\t\t\tOCTOSPI_CCR_READ_SFDP(len), SPIFLASH_READ_SFDP);\n\telse\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_READ_SFDP);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read from start of sfdp block */\n\tretval = target_write_u32(target, io_base + SPI_AR, 0);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tfor (count = 0 ; count < max_bytes; count++) {\n\t\tif ((dual != 0) && !flash1) {\n\t\t\t/* discard even byte in dual flash-mode if flash2 */\n\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\n\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tif (data == 0x53) {\n\t\t\tLOG_DEBUG(\"start of SFDP header for flash%c after %u dummy bytes\",\n\t\t\t\tflash1 ? '1' : '2', count);\n\t\t\tif (flash1)\n\t\t\t\tstmqspi_info->sfdp_dummy1 = count;\n\t\t\telse\n\t\t\t\tstmqspi_info->sfdp_dummy2 = count;\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tif ((dual != 0) && flash1) {\n\t\t\t/* discard odd byte in dual flash-mode if flash1 */\n\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"no start of SFDP header even after %u dummy bytes\", count);\n\nerr:\n\t/* Abort operation */\n\tretval = stmqspi_abort(bank);\n\n\treturn retval;\n}\n\n/* Read SFDP parameter block */\nstatic int read_sfdp_block(struct flash_bank *bank, uint32_t addr,\n\tuint32_t words, uint32_t *buffer)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tbool flash1 = !(stmqspi_info->saved_cr & BIT(SPI_FSEL_FLASH));\n\tunsigned int dual, count, len, *dummy;\n\tint retval;\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\n\tif (IS_OCTOSPI && (((stmqspi_info->saved_ccr >> SPI_DMODE_POS) & 0x7) > 3)) {\n\t\t/* in OCTO mode 4-byte address and (yet) unknown number of dummy clocks */\n\t\tlen = 4;\n\n\t\t/* in octo mode, use sfdp_dummy1 only */\n\t\tdummy = &stmqspi_info->sfdp_dummy1;\n\t\tif (*dummy == 0) {\n\t\t\tretval = find_sfdp_dummy(bank, len);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\t/* in all other modes 3-byte-address and 8(?) dummy clocks */\n\t\tlen = 3;\n\n\t\t/* use sfdp_dummy1/2 according to currently selected flash */\n\t\tdummy = (stmqspi_info->saved_cr & BIT(SPI_FSEL_FLASH)) ?\n\t\t\t&stmqspi_info->sfdp_dummy2 : &stmqspi_info->sfdp_dummy1;\n\n\t\t/* according to SFDP standard, there should always be 8 dummy *CLOCKS*\n\t\t * giving 1, 2 or 4 dummy *BYTES*, however, this is apparently not\n\t\t * always implemented correctly, so determine the number of dummy bytes\n\t\t * dynamically */\n\t\tif (*dummy == 0) {\n\t\t\tretval = find_sfdp_dummy(bank, len);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"%s: addr=0x%08\" PRIx32 \" words=0x%08\" PRIx32 \" dummy=%u\",\n\t\t__func__, addr, words, *dummy);\n\n\t/* Abort any previous operation */\n\tretval = target_write_u32(target, io_base + SPI_CR,\n\t\tstmqspi_info->saved_cr | BIT(SPI_ABORT));\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Switch to one flash only */\n\tretval = target_write_u32(target, io_base + SPI_CR, stmqspi_info->saved_cr);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read that many words plus dummy bytes */\n\tretval = target_write_u32(target, io_base + SPI_DLR,\n\t\t((*dummy + words * sizeof(uint32_t)) << dual) - 1);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* Read SFDP block */\n\tif (IS_OCTOSPI)\n\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE,\n\t\t\tOCTOSPI_CCR_READ_SFDP(len), SPIFLASH_READ_SFDP);\n\telse\n\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_READ_SFDP);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tretval = target_write_u32(target, io_base + SPI_AR, addr << dual);\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* dummy clocks */\n\tfor (count = *dummy << dual; count > 0; --count) {\n\t\tretval = target_read_u8(target, io_base + SPI_DR, (uint8_t *)buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\t}\n\n\tfor ( ; words > 0; words--) {\n\t\tif (dual != 0) {\n\t\t\tuint32_t word1, word2;\n\n\t\t\tretval = target_read_u32(target, io_base + SPI_DR, &word1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t\tretval = target_read_u32(target, io_base + SPI_DR, &word2);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\n\t\t\tif (!flash1) {\n\t\t\t\t/* shift odd numbered bytes into even numbered ones */\n\t\t\t\tword1 >>= 8;\n\t\t\t\tword2 >>= 8;\n\t\t\t}\n\n\t\t\t/* pack even numbered bytes into one word */\n\t\t\t*buffer = (word1 & 0xFFU) | ((word1 & 0xFF0000U) >> 8) |\n\t\t\t\t((word2 & 0xFFU) << 16) | ((word2 & 0xFF0000U) << 8);\n\n\n\t\t} else {\n\t\t\tretval = target_read_u32(target, io_base + SPI_DR, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\t\tLOG_DEBUG(\"raw SFDP data 0x%08\" PRIx32, *buffer);\n\n\t\t/* endian correction, sfdp data is always le uint32_t based */\n\t\t*buffer = le_to_h_u32((uint8_t *)buffer);\n\t\tbuffer++;\n\t}\n\nerr:\n\treturn retval;\n}\n\n/* Return ID of flash device(s) */\n/* On exit, indirect mode is kept */\nstatic int read_flash_id(struct flash_bank *bank, uint32_t *id1, uint32_t *id2)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint8_t byte;\n\tunsigned int type, count, len1, len2;\n\tint retval = ERROR_OK;\n\n\t/* invalidate both ids */\n\t*id1 = 0;\n\t*id2 = 0;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* SPIFLASH_READ_MID causes device in octal mode to go berserk, so don't use in this case */\n\tfor (type = (IS_OCTOSPI && OPI_MODE) ? 1 : 0; type < 2 ; type++) {\n\t\t/* Abort any previous operation */\n\t\tretval = stmqspi_abort(bank);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* Poll WIP */\n\t\tretval = wait_till_ready(bank, SPI_PROBE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* Wait for busy to be cleared */\n\t\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* Read at most 16 bytes per chip */\n\t\tcount = 16;\n\t\tretval = target_write_u32(target, io_base + SPI_DLR,\n\t\t\t(stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH) ? count * 2 : count) - 1);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* Read id: one particular flash chip (N25Q128) switches back to SPI mode when receiving\n\t\t * SPI_FLASH_READ_ID in QPI mode, hence try SPIFLASH_READ_MID first */\n\t\tswitch (type) {\n\t\t\tcase 0:\n\t\t\t\tif (IS_OCTOSPI)\n\t\t\t\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE,\n\t\t\t\t\t\tOCTOSPI_CCR_READ_MID, SPIFLASH_READ_MID);\n\t\t\t\telse\n\t\t\t\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_READ_MID);\n\t\t\t\tbreak;\n\n\t\t\tcase 1:\n\t\t\t\tif (IS_OCTOSPI)\n\t\t\t\t\tretval = octospi_cmd(bank, OCTOSPI_READ_MODE,\n\t\t\t\t\t\tOCTOSPI_CCR_READ_ID, SPIFLASH_READ_ID);\n\t\t\t\telse\n\t\t\t\t\tretval = target_write_u32(target, io_base + QSPI_CCR, QSPI_CCR_READ_ID);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\t/* Dummy address 0, only required for 8-line mode */\n\t\tif (IS_OCTOSPI && OPI_MODE) {\n\t\t\tretval = target_write_u32(target, io_base + SPI_AR, 0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto err;\n\t\t}\n\n\t\t/* for debugging only */\n\t\tuint32_t dummy;\n\t\t(void)target_read_u32(target, io_base + SPI_SR, &dummy);\n\n\t\t/* Read ID from Data Register */\n\t\tfor (len1 = 0, len2 = 0; count > 0; --count) {\n\t\t\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |\n\t\t\t\tBIT(SPI_FSEL_FLASH))) != BIT(SPI_FSEL_FLASH)) {\n\t\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &byte);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto err;\n\t\t\t\t/* collect 3 bytes without continuation codes */\n\t\t\t\tif ((byte != 0x7F) && (len1 < 3)) {\n\t\t\t\t\t*id1 = (*id1 >> 8) | ((uint32_t)byte) << 16;\n\t\t\t\t\tlen1++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |\n\t\t\t\tBIT(SPI_FSEL_FLASH))) != 0) {\n\t\t\t\tretval = target_read_u8(target, io_base + SPI_DR, &byte);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto err;\n\t\t\t\t/* collect 3 bytes without continuation codes */\n\t\t\t\tif ((byte != 0x7F) && (len2 < 3)) {\n\t\t\t\t\t*id2 = (*id2 >> 8) | ((uint32_t)byte) << 16;\n\t\t\t\t\tlen2++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (((*id1 != 0x000000) && (*id1 != 0xFFFFFF)) ||\n\t\t\t((*id2 != 0x000000) && (*id2 != 0xFFFFFF)))\n\t\t\tbreak;\n\t}\n\n\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |\n\t\tBIT(SPI_FSEL_FLASH))) != BIT(SPI_FSEL_FLASH)) {\n\t\tif ((*id1 == 0x000000) || (*id1 == 0xFFFFFF)) {\n\t\t\t/* no id retrieved, so id must be set manually */\n\t\t\tLOG_INFO(\"No id from flash1\");\n\t\t\tretval = ERROR_FLASH_BANK_NOT_PROBED;\n\t\t}\n\t}\n\n\tif ((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) | BIT(SPI_FSEL_FLASH))) != 0) {\n\t\tif ((*id2 == 0x000000) || (*id2 == 0xFFFFFF)) {\n\t\t\t/* no id retrieved, so id must be set manually */\n\t\t\tLOG_INFO(\"No id from flash2\");\n\t\t\tretval = ERROR_FLASH_BANK_NOT_PROBED;\n\t\t}\n\t}\n\nerr:\n\treturn retval;\n}\n\nstatic int stmqspi_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\tstruct flash_sector *sectors = NULL;\n\tuint32_t io_base = stmqspi_info->io_base;\n\tuint32_t id1 = 0, id2 = 0, data = 0;\n\tconst struct flash_device *p;\n\tconst uint32_t magic = 0xAEF1510E;\n\tunsigned int dual, fsize;\n\tbool octal_dtr;\n\tint retval;\n\n\t/* invalidate all flash device info */\n\tif (stmqspi_info->probed)\n\t\tfree(bank->sectors);\n\tbank->size = 0;\n\tbank->num_sectors = 0;\n\tbank->sectors = NULL;\n\tstmqspi_info->sfdp_dummy1 = 0;\n\tstmqspi_info->sfdp_dummy2 = 0;\n\tstmqspi_info->probed = false;\n\tmemset(&stmqspi_info->dev, 0, sizeof(stmqspi_info->dev));\n\tstmqspi_info->dev.name = \"unknown\";\n\n\t/* Abort any previous operation */\n\tretval = stmqspi_abort(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for busy to be cleared */\n\tretval = poll_busy(bank, SPI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check whether QSPI_ABR is writeable and readback returns the value written */\n\tretval = target_write_u32(target, io_base + QSPI_ABR, magic);\n\tif (retval == ERROR_OK) {\n\t\t(void)target_read_u32(target, io_base + QSPI_ABR, &data);\n\t\t(void)target_write_u32(target, io_base + QSPI_ABR, 0);\n\t}\n\n\tif (data == magic) {\n\t\tLOG_DEBUG(\"QSPI_ABR register present\");\n\t\tstmqspi_info->octo = false;\n\t} else {\n\t\tuint32_t magic_id;\n\n\t\tretval = target_read_u32(target, io_base + OCTOSPI_MAGIC, &magic_id);\n\n\t\tif (retval == ERROR_OK && magic_id == OCTO_MAGIC_ID) {\n\t\t\tLOG_DEBUG(\"OCTOSPI_MAGIC present\");\n\t\t\tstmqspi_info->octo = true;\n\t\t} else {\n\t\t\tLOG_ERROR(\"No QSPI, no OCTOSPI at 0x%08\" PRIx32, io_base);\n\t\t\tstmqspi_info->probed = false;\n\t\t\tstmqspi_info->dev.name = \"none\";\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* save current FSEL and DFM bits in QSPI/OCTOSPI_CR, current QSPI/OCTOSPI_CCR value */\n\tretval = target_read_u32(target, io_base + SPI_CR, &stmqspi_info->saved_cr);\n\tif (retval == ERROR_OK)\n\t\tretval = target_read_u32(target, io_base + SPI_CCR, &stmqspi_info->saved_ccr);\n\n\tif (IS_OCTOSPI) {\n\t\tuint32_t dcr1;\n\n\t\tretval = target_read_u32(target, io_base + OCTOSPI_DCR1, &dcr1);\n\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_read_u32(target, io_base + OCTOSPI_TCR,\n\t\t\t\t&stmqspi_info->saved_tcr);\n\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = target_read_u32(target, io_base + OCTOSPI_IR,\n\t\t\t\t&stmqspi_info->saved_ir);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"No OCTOSPI at io_base 0x%08\" PRIx32, io_base);\n\t\t\tstmqspi_info->probed = false;\n\t\t\tstmqspi_info->dev.name = \"none\";\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tconst uint32_t mtyp = (dcr1 & OCTOSPI_MTYP_MASK) >> OCTOSPI_MTYP_POS;\n\n\t\tif ((mtyp != 0x0) && (mtyp != 0x1)) {\n\t\t\tLOG_ERROR(\"Only regular SPI protocol supported in OCTOSPI\");\n\t\t\tstmqspi_info->probed = false;\n\t\t\tstmqspi_info->dev.name = \"none\";\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_DEBUG(\"OCTOSPI at 0x%08\" PRIx64 \", io_base at 0x%08\" PRIx32 \", OCTOSPI_CR 0x%08\"\n\t\t\tPRIx32 \", OCTOSPI_CCR 0x%08\" PRIx32 \", %d-byte addr\", bank->base, io_base,\n\t\t\tstmqspi_info->saved_cr, stmqspi_info->saved_ccr, SPI_ADSIZE);\n\t} else {\n\t\tif (retval == ERROR_OK) {\n\t\t\tLOG_DEBUG(\"QSPI at 0x%08\" PRIx64 \", io_base at 0x%08\" PRIx32 \", QSPI_CR 0x%08\"\n\t\t\t\tPRIx32 \", QSPI_CCR 0x%08\" PRIx32 \", %d-byte addr\", bank->base, io_base,\n\t\t\t\tstmqspi_info->saved_cr, stmqspi_info->saved_ccr, SPI_ADSIZE);\n\t\t\t\tif (stmqspi_info->saved_ccr & (1U << QSPI_DDRM))\n\t\t\t\t\tLOG_WARNING(\"DDR mode is untested and suffers from some silicon bugs\");\n\t\t} else {\n\t\t\tLOG_ERROR(\"No QSPI at io_base 0x%08\" PRIx32, io_base);\n\t\t\tstmqspi_info->probed = false;\n\t\t\tstmqspi_info->dev.name = \"none\";\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tdual = (stmqspi_info->saved_cr & BIT(SPI_DUAL_FLASH)) ? 1 : 0;\n\toctal_dtr = IS_OCTOSPI && (stmqspi_info->saved_ccr & BIT(OCTOSPI_DDTR));\n\tif (dual || octal_dtr)\n\t\tbank->write_start_alignment = bank->write_end_alignment = 2;\n\telse\n\t\tbank->write_start_alignment = bank->write_end_alignment = 1;\n\n\t/* read and decode flash ID; returns in indirect mode */\n\tretval = read_flash_id(bank, &id1, &id2);\n\tLOG_DEBUG(\"id1 0x%06\" PRIx32 \", id2 0x%06\" PRIx32, id1, id2);\n\tif (retval == ERROR_FLASH_BANK_NOT_PROBED) {\n\t\t/* no id retrieved, so id must be set manually */\n\t\tLOG_INFO(\"No id - set flash parameters manually\");\n\t\tretval = ERROR_OK;\n\t\tgoto err;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\t/* identify flash1 */\n\tfor (p = flash_devices; id1 && p->name ; p++) {\n\t\tif (p->device_id == id1) {\n\t\t\tmemcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev));\n\t\t\tif (p->size_in_bytes / 4096)\n\t\t\t\tLOG_INFO(\"flash1 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\t\" KiB\", p->name, id1, p->size_in_bytes / 1024);\n\t\t\telse\n\t\t\t\tLOG_INFO(\"flash1 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\t\" B\", p->name, id1, p->size_in_bytes);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (id1 && !p->name) {\n\t\t/* chip not been identified by id, then try SFDP */\n\t\tstruct flash_device temp;\n\t\tuint32_t saved_cr = stmqspi_info->saved_cr;\n\n\t\t/* select flash1 */\n\t\tstmqspi_info->saved_cr = stmqspi_info->saved_cr & ~BIT(SPI_FSEL_FLASH);\n\t\tretval = spi_sfdp(bank, &temp, &read_sfdp_block);\n\n\t\t/* restore saved_cr */\n\t\tstmqspi_info->saved_cr = saved_cr;\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tLOG_INFO(\"flash1 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\" KiB\", temp.name, id1, temp.size_in_bytes / 1024);\n\t\t\t/* save info and retrieved *good* id as spi_sfdp clears all info */\n\t\t\tmemcpy(&stmqspi_info->dev, &temp, sizeof(stmqspi_info->dev));\n\t\t\tstmqspi_info->dev.device_id = id1;\n\t\t} else {\n\t\t\t/* even not identified by SFDP, then give up */\n\t\t\tLOG_WARNING(\"Unknown flash1 device id = 0x%06\" PRIx32\n\t\t\t\t\" - set flash parameters manually\", id1);\n\t\t\tretval = ERROR_OK;\n\t\t\tgoto err;\n\t\t}\n\t}\n\n\t/* identify flash2 */\n\tfor (p = flash_devices; id2 && p->name ; p++) {\n\t\tif (p->device_id == id2) {\n\t\t\tif (p->size_in_bytes / 4096)\n\t\t\t\tLOG_INFO(\"flash2 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\t\" KiB\", p->name, id2, p->size_in_bytes / 1024);\n\t\t\telse\n\t\t\t\tLOG_INFO(\"flash2 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\t\" B\", p->name, id2, p->size_in_bytes);\n\n\t\t\tif (!id1)\n\t\t\t\tmemcpy(&stmqspi_info->dev, p, sizeof(stmqspi_info->dev));\n\t\t\telse {\n\t\t\t\tif ((stmqspi_info->dev.read_cmd != p->read_cmd) ||\n\t\t\t\t\t(stmqspi_info->dev.qread_cmd != p->qread_cmd) ||\n\t\t\t\t\t(stmqspi_info->dev.pprog_cmd != p->pprog_cmd) ||\n\t\t\t\t\t(stmqspi_info->dev.erase_cmd != p->erase_cmd) ||\n\t\t\t\t\t(stmqspi_info->dev.chip_erase_cmd != p->chip_erase_cmd) ||\n\t\t\t\t\t(stmqspi_info->dev.sectorsize != p->sectorsize) ||\n\t\t\t\t\t(stmqspi_info->dev.size_in_bytes != p->size_in_bytes)) {\n\t\t\t\t\tLOG_ERROR(\"Incompatible flash1/flash2 devices\");\n\t\t\t\t\tgoto err;\n\t\t\t\t}\n\t\t\t\t/* page size is optional in SFDP, so accept smallest value */\n\t\t\t\tif (p->pagesize < stmqspi_info->dev.pagesize)\n\t\t\t\t\tstmqspi_info->dev.pagesize = p->pagesize;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (id2 && !p->name) {\n\t\t/* chip not been identified by id, then try SFDP */\n\t\tstruct flash_device temp;\n\t\tuint32_t saved_cr = stmqspi_info->saved_cr;\n\n\t\t/* select flash2 */\n\t\tstmqspi_info->saved_cr = stmqspi_info->saved_cr | BIT(SPI_FSEL_FLASH);\n\t\tretval = spi_sfdp(bank, &temp, &read_sfdp_block);\n\n\t\t/* restore saved_cr */\n\t\tstmqspi_info->saved_cr = saved_cr;\n\n\t\tif (retval == ERROR_OK)\n\t\t\tLOG_INFO(\"flash2 \\'%s\\' id = 0x%06\" PRIx32 \" size = %\" PRIu32\n\t\t\t\t\" KiB\", temp.name, id2, temp.size_in_bytes / 1024);\n\t\telse {\n\t\t\t/* even not identified by SFDP, then give up */\n\t\t\tLOG_WARNING(\"Unknown flash2 device id = 0x%06\" PRIx32\n\t\t\t\t\" - set flash parameters manually\", id2);\n\t\t\tretval = ERROR_OK;\n\t\t\tgoto err;\n\t\t}\n\n\t\tif (!id1)\n\t\t\tmemcpy(&stmqspi_info->dev, &temp, sizeof(stmqspi_info->dev));\n\t\telse {\n\t\t\tif ((stmqspi_info->dev.read_cmd != temp.read_cmd) ||\n\t\t\t\t(stmqspi_info->dev.qread_cmd != temp.qread_cmd) ||\n\t\t\t\t(stmqspi_info->dev.pprog_cmd != temp.pprog_cmd) ||\n\t\t\t\t(stmqspi_info->dev.erase_cmd != temp.erase_cmd) ||\n\t\t\t\t(stmqspi_info->dev.chip_erase_cmd != temp.chip_erase_cmd) ||\n\t\t\t\t(stmqspi_info->dev.sectorsize != temp.sectorsize) ||\n\t\t\t\t(stmqspi_info->dev.size_in_bytes != temp.size_in_bytes)) {\n\t\t\t\tLOG_ERROR(\"Incompatible flash1/flash2 devices\");\n\t\t\t\tgoto err;\n\t\t\t}\n\t\t\t/* page size is optional in SFDP, so accept smallest value */\n\t\t\tif (temp.pagesize < stmqspi_info->dev.pagesize)\n\t\t\t\tstmqspi_info->dev.pagesize = temp.pagesize;\n\t\t}\n\t}\n\n\t/* Set correct size value */\n\tbank->size = stmqspi_info->dev.size_in_bytes << dual;\n\n\tuint32_t dcr;\n\tretval = target_read_u32(target, io_base + SPI_DCR, &dcr);\n\n\tif (retval != ERROR_OK)\n\t\tgoto err;\n\n\tfsize = (dcr >> SPI_FSIZE_POS) & (BIT(SPI_FSIZE_LEN) - 1);\n\n\tLOG_DEBUG(\"FSIZE = 0x%04x\", fsize);\n\tif (bank->size == BIT((fsize + 1)))\n\t\tLOG_DEBUG(\"FSIZE in DCR(1) matches actual capacity. Beware of silicon bug in H7, L4+, MP1.\");\n\telse if (bank->size == BIT((fsize + 0)))\n\t\tLOG_DEBUG(\"FSIZE in DCR(1) is off by one regarding actual capacity. Fix for silicon bug?\");\n\telse\n\t\tLOG_ERROR(\"FSIZE in DCR(1) doesn't match actual capacity.\");\n\n\t/* if no sectors, then treat whole flash as single sector */\n\tif (stmqspi_info->dev.sectorsize == 0)\n\t\tstmqspi_info->dev.sectorsize = stmqspi_info->dev.size_in_bytes;\n\t/* if no page_size, then use sectorsize as page_size */\n\tif (stmqspi_info->dev.pagesize == 0)\n\t\tstmqspi_info->dev.pagesize = stmqspi_info->dev.sectorsize;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors = stmqspi_info->dev.size_in_bytes / stmqspi_info->dev.sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto err;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * (stmqspi_info->dev.sectorsize << dual);\n\t\tsectors[sector].size = (stmqspi_info->dev.sectorsize << dual);\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 0;\n\t}\n\n\tbank->sectors = sectors;\n\tstmqspi_info->probed = true;\n\nerr:\n\t/* Switch to memory mapped mode before return to prompt */\n\tset_mm_mode(bank);\n\n\treturn retval;\n}\n\nstatic int stmqspi_auto_probe(struct flash_bank *bank)\n{\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\n\tif (stmqspi_info->probed)\n\t\treturn ERROR_OK;\n\tstmqspi_probe(bank);\n\treturn ERROR_OK;\n}\n\nstatic int stmqspi_protect_check(struct flash_bank *bank)\n{\n\t/* Nothing to do. Protection is only handled in SW. */\n\treturn ERROR_OK;\n}\n\nstatic int get_stmqspi_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stmqspi_flash_bank *stmqspi_info = bank->driver_priv;\n\n\tif (!(stmqspi_info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nQSPI flash bank not probed yet\\n\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tcommand_print_sameline(cmd, \"flash%s%s \\'%s\\', device id = 0x%06\" PRIx32\n\t\t\t\", flash size = %\" PRIu32 \"%s B\\n(page size = %\" PRIu32\n\t\t\t\", read = 0x%02\" PRIx8 \", qread = 0x%02\" PRIx8\n\t\t\t\", pprog = 0x%02\" PRIx8 \", mass_erase = 0x%02\" PRIx8\n\t\t\t\", sector size = %\" PRIu32 \" %sB, sector_erase = 0x%02\" PRIx8 \")\",\n\t\t\t((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |\n\t\t\tBIT(SPI_FSEL_FLASH))) != BIT(SPI_FSEL_FLASH)) ? \"1\" : \"\",\n\t\t\t((stmqspi_info->saved_cr & (BIT(SPI_DUAL_FLASH) |\n\t\t\tBIT(SPI_FSEL_FLASH))) != 0) ? \"2\" : \"\",\n\t\t\tstmqspi_info->dev.name, stmqspi_info->dev.device_id,\n\t\t\tbank->size / 4096 ? bank->size / 1024 : bank->size,\n\t\t\tbank->size / 4096 ? \"Ki\" : \"\", stmqspi_info->dev.pagesize,\n\t\t\tstmqspi_info->dev.read_cmd, stmqspi_info->dev.qread_cmd,\n\t\t\tstmqspi_info->dev.pprog_cmd, stmqspi_info->dev.chip_erase_cmd,\n\t\t\tstmqspi_info->dev.sectorsize / 4096 ?\n\t\t\t\tstmqspi_info->dev.sectorsize / 1024 : stmqspi_info->dev.sectorsize,\n\t\t\tstmqspi_info->dev.sectorsize / 4096 ? \"Ki\" : \"\",\n\t\t\tstmqspi_info->dev.erase_cmd);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration stmqspi_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = stmqspi_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Mass erase entire flash device.\",\n\t},\n\t{\n\t\t.name = \"set\",\n\t\t.handler = stmqspi_handle_set,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id name chip_size page_size read_cmd qread_cmd pprg_cmd \"\n\t\t\t\"[ mass_erase_cmd ] [ sector_size sector_erase_cmd ]\",\n\t\t.help = \"Set params of single flash chip\",\n\t},\n\t{\n\t\t.name = \"cmd\",\n\t\t.handler = stmqspi_handle_cmd,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id num_resp cmd_byte ...\",\n\t\t.help = \"Send low-level command cmd_byte and following bytes or read num_resp.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stmqspi_command_handlers[] = {\n\t{\n\t\t.name = \"stmqspi\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stmqspi flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = stmqspi_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver stmqspi_flash = {\n\t.name = \"stmqspi\",\n\t.commands = stmqspi_command_handlers,\n\t.flash_bank_command = stmqspi_flash_bank_command,\n\t.erase = stmqspi_erase,\n\t.protect = stmqspi_protect,\n\t.write = stmqspi_write,\n\t.read = stmqspi_read,\n\t.verify = stmqspi_verify,\n\t.probe = stmqspi_probe,\n\t.auto_probe = stmqspi_auto_probe,\n\t.erase_check = stmqspi_blank_check,\n\t.protect_check = stmqspi_protect_check,\n\t.info = get_stmqspi_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stmqspi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 - 2018 by Andreas Bolsch                           *\n *   andreas.bolsch@mni.thm.de                                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_FLASH_NOR_STMQSPI_H\n#define OPENOCD_FLASH_NOR_STMQSPI_H\n\n#include \"spi.h\"\n\n/* QSPI register offsets */\n#define QSPI_CR\t\t\t(0x00)\t/* Control register */\n#define QSPI_DCR\t\t(0x04)\t/* Device configuration register */\n#define QSPI_SR\t\t\t(0x08)\t/* Status register */\n#define QSPI_FCR\t\t(0x0C)\t/* Flag clear register */\n#define QSPI_DLR\t\t(0x10)\t/* Data length register */\n#define QSPI_CCR\t\t(0x14)\t/* Communication configuration register */\n#define QSPI_AR\t\t\t(0x18)\t/* Address register */\n#define QSPI_ABR\t\t(0x1C)\t/* Alternate bytes register */\n#define QSPI_DR\t\t\t(0x20)\t/* Data register */\n\n/* common bits in QSPI_CR and OCTOSPI_CR */\n#define SPI_FSEL_FLASH\t7\t\t/* Select flash 2 */\n#define SPI_DUAL_FLASH\t6\t\t/* Dual flash mode */\n#define SPI_ABORT\t\t1\t\t/* Abort bit */\n\n/* common bits in QSPI_DCR and OCTOSPI_DCR1 */\n#define SPI_FSIZE_POS\t16\t\t/* bit position of FSIZE */\n#define SPI_FSIZE_LEN\t5\t\t/* width of FSIZE field */\n\n/* common bits in QSPI_SR/FCR and OCTOSPI_SR/FCR */\n#define SPI_BUSY\t\t5\t\t/* Busy flag */\n#define SPI_FTF\t\t\t2\t\t/* FIFO threshold flag */\n#define SPI_TCF\t\t\t1\t\t/* Transfer complete flag */\n\n/* fields in QSPI_CCR */\n#define QSPI_DDRM\t\t\t31\t\t\t\t\t/* position of DDRM bit */\n#define SPI_DMODE_POS\t\t24\t\t\t\t\t/* bit position of DMODE */\n#define QSPI_DCYC_POS\t\t18\t\t\t\t\t/* bit position of DCYC */\n#define QSPI_DCYC_LEN\t\t5\t\t\t\t\t/* width of DCYC field */\n#define QSPI_DCYC_MASK\t\t((BIT(QSPI_DCYC_LEN) - 1) << QSPI_DCYC_POS)\n#define SPI_ADSIZE_POS\t\t12\t\t\t\t\t/* bit position of ADSIZE */\n\n#define QSPI_WRITE_MODE\t\t0x00000000U\t\t\t/* indirect write mode */\n#define QSPI_READ_MODE\t\t0x04000000U\t\t\t/* indirect read mode */\n#define QSPI_MM_MODE\t\t0x0C000000U\t\t\t/* memory mapped mode */\n#define QSPI_ALTB_MODE\t\t0x0003C000U\t\t\t/* alternate byte mode */\n#define QSPI_4LINE_MODE\t\t0x03000F00U\t\t\t/* 4 lines for data, addr, instr */\n#define QSPI_NO_DATA\t\t(~0x03000000U)\t\t/* no data */\n#define QSPI_NO_ALTB\t\t(~QSPI_ALTB_MODE)\t/* no alternate */\n#define QSPI_NO_ADDR\t\t(~0x00000C00U)\t\t/* no address */\n#define QSPI_ADDR3\t\t\t(0x2U << SPI_ADSIZE_POS)\t/* 3 byte address */\n#define QSPI_ADDR4\t\t\t(0x3U << SPI_ADSIZE_POS)\t/* 4 byte address */\n\n/* OCTOSPI register offsets */\n#define OCTOSPI_CR\t\t(0x000)\t/* Control register */\n#define OCTOSPI_DCR1\t(0x008)\t/* Device configuration register 1 */\n#define OCTOSPI_DCR2\t(0x00C)\t/* Device configuration register 2 */\n#define OCTOSPI_DCR3\t(0x010)\t/* Device configuration register 3 */\n#define\tOCTOSPI_SR\t\t(0x020)\t/* Status register */\n#define OCTOSPI_FCR\t\t(0x024)\t/* Flag clear register */\n#define OCTOSPI_DLR\t\t(0x040)\t/* Data length register */\n#define OCTOSPI_AR\t\t(0x048)\t/* Address register */\n#define OCTOSPI_DR\t\t(0x050)\t/* Data register */\n#define OCTOSPI_CCR\t\t(0x100)\t/* Communication configuration register */\n#define OCTOSPI_TCR\t\t(0x108)\t/* Timing configuration register */\n#define OCTOSPI_IR\t\t(0x110)\t/* Instruction register */\n#define OCTOSPI_WCCR\t(0x180)\t/* Write communication configuration register */\n#define OCTOSPI_WIR\t\t(0x190)\t/* Write instruction register */\n#define OCTOSPI_MAGIC\t(0x3FC)\t/* Magic ID register, deleted from RM, why? */\n\n#define OCTO_MAGIC_ID\t0xA3C5DD01\t/* Magic ID, deleted from RM, why? */\n\n/* additional bits in OCTOSPI_CR */\n#define OCTOSPI_WRITE_MODE\t0x00000000U\t\t\t/* indirect write mode */\n#define OCTOSPI_READ_MODE\t0x10000000U\t\t\t/* indirect read mode */\n#define OCTOSPI_MM_MODE\t\t0x30000000U\t\t\t/* memory mapped mode */\n\n/* additional fields in OCTOSPI_DCR1 */\n#define OCTOSPI_MTYP_POS\t(24)\t\t\t\t/* bit position of MTYP */\n#define OCTOSPI_MTYP_LEN\t(3)\t\t\t\t\t/* width of MTYP field */\n#define OCTOSPI_MTYP_MASK\t((BIT(OCTOSPI_MTYP_LEN) - 1) << OCTOSPI_MTYP_POS)\n\n/* fields in OCTOSPI_CCR */\n#define OCTOSPI_ALTB_MODE\t0x001F0000U\t\t\t\t/* alternate byte mode */\n#define OCTOSPI_8LINE_MODE\t0x0F003F3FU\t\t\t\t/* 8 lines DTR for data, addr, instr */\n#define OCTOSPI_NO_DATA\t\t(~0x0F000000U)\t\t\t/* no data */\n#define OCTOSPI_NO_ALTB\t\t(~OCTOSPI_ALTB_MODE)\t/* no alternate */\n#define OCTOSPI_NO_ADDR\t\t(~0x00000F00U)\t\t\t/* no address */\n#define OCTOSPI_ADDR3\t\t(0x2U << SPI_ADSIZE_POS)\t/* 3 byte address */\n#define OCTOSPI_ADDR4\t\t(0x3U << SPI_ADSIZE_POS)\t/* 4 byte address */\n#define OCTOSPI_DQSEN\t\t29\t\t\t\t\t\t/* DQS enable */\n#define OCTOSPI_DDTR\t\t27\t\t\t\t\t\t/* DTR for data */\n#define OCTOSPI_NO_DDTR\t\t(~BIT(OCTOSPI_DDTR))\t/* no DTR for data, but maybe still DQS */\n#define OCTOSPI_ISIZE_MASK\t(0x30)\t\t\t\t\t/* ISIZE field */\n\n/* fields in OCTOSPI_TCR */\n#define OCTOSPI_DCYC_POS\t0\t\t\t\t\t/* bit position of DCYC */\n#define OCTOSPI_DCYC_LEN\t5\t\t\t\t\t/* width of DCYC field */\n#define OCTOSPI_DCYC_MASK\t((BIT(OCTOSPI_DCYC_LEN) - 1) << OCTOSPI_DCYC_POS)\n\n#define IS_OCTOSPI\t\t\t(stmqspi_info->octo)\n#define SPI_CR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_CR : QSPI_CR)\n#define SPI_DCR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_DCR1 : QSPI_DCR)\n#define\tSPI_SR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_SR : QSPI_SR)\n#define SPI_FCR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_FCR : QSPI_FCR)\n#define SPI_DLR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_DLR : QSPI_DLR)\n#define SPI_AR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_AR : QSPI_AR)\n#define SPI_DR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_DR : QSPI_DR)\n#define SPI_CCR\t\t\t\t(IS_OCTOSPI ? OCTOSPI_CCR : QSPI_CCR)\n\n#endif /* OPENOCD_FLASH_NOR_STMQSPI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/stmsmi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Antonio Borneo <borneo.antonio@gmail.com>       *\n ***************************************************************************/\n\n/* STM Serial Memory Interface (SMI) controller is a SPI bus controller\n * specifically designed for SPI memories.\n * Only SPI \"mode 3\" (CPOL=1 and CPHA=1) is supported.\n * Two working modes are available:\n * - SW mode: the SPI is controlled by SW. Any custom commands can be sent\n *   on the bus.\n * - HW mode: the SPI but is under SMI control. Memory content is directly\n *   accessible in CPU memory space. CPU can read, write and execute memory\n *   content. */\n\n/* ATTENTION:\n * To have flash memory mapped in CPU memory space, the SMI controller\n * have to be in \"HW mode\". This requires following constraints:\n * 1) The command \"reset init\" have to initialize SMI controller and put\n *    it in HW mode;\n * 2) every command in this file have to return to prompt in HW mode. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include \"spi.h\"\n#include <jtag/jtag.h>\n#include <helper/time_support.h>\n\n#define SMI_READ_REG(a)\t\t\t\t\\\n({\t\t\t\t\t\t\t\t\t\\\n\tint _ret;\t\t\t\t\t\t\\\n\tuint32_t _value;\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t_ret = target_read_u32(target, io_base + (a), &_value); \\\n\tif (_ret != ERROR_OK)\t\t\t\\\n\t\treturn _ret;\t\t\t\t\\\n\t_value;\t\t\t\t\t\t\t\\\n})\n\n#define SMI_WRITE_REG(a, v)\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint _retval;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t_retval = target_write_u32(target, io_base + (a), (v)); \\\n\tif (_retval != ERROR_OK)\t\t\\\n\t\treturn _retval;\t\t\t\t\\\n}\n\n#define SMI_POLL_TFF(timeout)\t\t\\\n{\t\t\t\t\t\t\t\t\t\\\n\tint _retval;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t_retval = poll_tff(target, io_base, timeout); \\\n\tif (_retval != ERROR_OK)\t\t\\\n\t\treturn _retval;\t\t\t\t\\\n}\n\n#define SMI_SET_SW_MODE()\tSMI_WRITE_REG(SMI_CR1, \\\n\tSMI_READ_REG(SMI_CR1) | SMI_SW_MODE)\n#define SMI_SET_HWWB_MODE() SMI_WRITE_REG(SMI_CR1, \\\n\t(SMI_READ_REG(SMI_CR1) | SMI_WB_MODE) & ~SMI_SW_MODE)\n#define SMI_SET_HW_MODE()\tSMI_WRITE_REG(SMI_CR1, \\\n\tSMI_READ_REG(SMI_CR1) & ~(SMI_SW_MODE | SMI_WB_MODE))\n#define SMI_CLEAR_TFF()\t\tSMI_WRITE_REG(SMI_SR, ~SMI_TFF)\n\n#define SMI_BANK_SIZE      (0x01000000)\n\n#define SMI_CR1 (0x00) /* Control register 1 */\n#define SMI_CR2 (0x04) /* Control register 2 */\n#define SMI_SR  (0x08) /* Status register */\n#define SMI_TR  (0x0c) /* TX */\n#define SMI_RR  (0x10) /* RX */\n\n/* fields in SMI_CR1 */\n#define SMI_SW_MODE       0x10000000 /* set to enable SW Mode */\n#define SMI_WB_MODE       0x20000000 /* Write Burst Mode */\n\n/* fields in SMI_CR2 */\n#define SMI_TX_LEN_1      0x00000001 /* data length = 1 byte */\n#define SMI_TX_LEN_4      0x00000004 /* data length = 4 byte */\n#define SMI_RX_LEN_3      0x00000030 /* data length = 3 byte */\n#define SMI_SEND          0x00000080 /* Send data */\n#define SMI_RSR           0x00000400 /* reads status reg */\n#define SMI_WE            0x00000800 /* Write Enable */\n#define SMI_SEL_BANK0     0x00000000 /* Select Bank0 */\n#define SMI_SEL_BANK1     0x00001000 /* Select Bank1 */\n#define SMI_SEL_BANK2     0x00002000 /* Select Bank2 */\n#define SMI_SEL_BANK3     0x00003000 /* Select Bank3 */\n\n/* fields in SMI_SR */\n#define SMI_TFF           0x00000100 /* Transfer Finished Flag */\n\n/* Commands */\n#define SMI_READ_ID       0x0000009F /* Read Flash Identification */\n\n/* Timeout in ms */\n#define SMI_CMD_TIMEOUT   (100)\n#define SMI_PROBE_TIMEOUT (100)\n#define SMI_MAX_TIMEOUT  (3000)\n\nstruct stmsmi_flash_bank {\n\tbool probed;\n\tuint32_t io_base;\n\tuint32_t bank_num;\n\tconst struct flash_device *dev;\n};\n\nstruct stmsmi_target {\n\tchar *name;\n\tuint32_t tap_idcode;\n\tuint32_t smi_base;\n\tuint32_t io_base;\n};\n\nstatic const struct stmsmi_target target_devices[] = {\n\t/* name,          tap_idcode, smi_base,   io_base */\n\t{ \"SPEAr3xx/6xx\", 0x07926041, 0xf8000000, 0xfc000000 },\n\t{ \"STR75x\",       0x4f1f0041, 0x80000000, 0x90000000 },\n\t{ NULL,           0,          0,          0 }\n};\n\nFLASH_BANK_COMMAND_HANDLER(stmsmi_flash_bank_command)\n{\n\tstruct stmsmi_flash_bank *stmsmi_info;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstmsmi_info = malloc(sizeof(struct stmsmi_flash_bank));\n\tif (!stmsmi_info) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->driver_priv = stmsmi_info;\n\tstmsmi_info->probed = false;\n\n\treturn ERROR_OK;\n}\n\n/* Poll transmit finished flag */\n/* timeout in ms */\nstatic int poll_tff(struct target *target, uint32_t io_base, int timeout)\n{\n\tint64_t endtime;\n\n\tif (SMI_READ_REG(SMI_SR) & SMI_TFF)\n\t\treturn ERROR_OK;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\talive_sleep(1);\n\t\tif (SMI_READ_REG(SMI_SR) & SMI_TFF)\n\t\t\treturn ERROR_OK;\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"Timeout while polling TFF\");\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n/* Read the status register of the external SPI flash chip.\n * The operation is triggered by setting SMI_RSR bit.\n * SMI sends the proper SPI command (0x05) and returns value in SMI_SR */\nstatic int read_status_reg(struct flash_bank *bank, uint32_t *status)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t/* Read status */\n\tSMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_RSR);\n\n\t/* Poll transmit finished flag */\n\tSMI_POLL_TFF(SMI_CMD_TIMEOUT);\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t*status = SMI_READ_REG(SMI_SR) & 0x0000ffff;\n\n\t/* clean-up SMI_CR2 */\n\tSMI_WRITE_REG(SMI_CR2, 0); /* AB: Required ? */\n\n\treturn ERROR_OK;\n}\n\n/* check for WIP (write in progress) bit in status register */\n/* timeout in ms */\nstatic int wait_till_ready(struct flash_bank *bank, int timeout)\n{\n\tuint32_t status;\n\tint retval;\n\tint64_t endtime;\n\n\tendtime = timeval_ms() + timeout;\n\tdo {\n\t\t/* read flash status register */\n\t\tretval = read_status_reg(bank, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif ((status & SPIFLASH_BSY_BIT) == 0)\n\t\t\treturn ERROR_OK;\n\t\talive_sleep(1);\n\t} while (timeval_ms() < endtime);\n\n\tLOG_ERROR(\"timeout\");\n\treturn ERROR_FAIL;\n}\n\n/* Send \"write enable\" command to SPI flash chip.\n * The operation is triggered by setting SMI_WE bit, and SMI sends\n * the proper SPI command (0x06) */\nstatic int smi_write_enable(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tuint32_t status;\n\tint retval;\n\n\t/* Enter in HW mode */\n\tSMI_SET_HW_MODE(); /* AB: is this correct ?*/\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t/* Send write enable command */\n\tSMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_WE);\n\n\t/* Poll transmit finished flag */\n\tSMI_POLL_TFF(SMI_CMD_TIMEOUT);\n\n\t/* read flash status register */\n\tretval = read_status_reg(bank, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check write enabled */\n\tif ((status & SPIFLASH_WE_BIT) == 0) {\n\t\tLOG_ERROR(\"Cannot enable write to flash. Status=0x%08\" PRIx32, status);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t erase_command(struct stmsmi_flash_bank *stmsmi_info,\n\tuint32_t offset)\n{\n\tuint8_t cmd_bytes[] = {\n\t\tstmsmi_info->dev->erase_cmd,\n\t\toffset >> 16,\n\t\toffset >> 8,\n\t\toffset\n\t};\n\n\treturn le_to_h_u32(cmd_bytes);\n}\n\nstatic int smi_erase_sector(struct flash_bank *bank, int sector)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tuint32_t cmd;\n\tint retval;\n\n\tretval = smi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Switch to SW mode to send sector erase command */\n\tSMI_SET_SW_MODE();\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t/* send SPI command \"block erase\" */\n\tcmd = erase_command(stmsmi_info, bank->sectors[sector].offset);\n\tSMI_WRITE_REG(SMI_TR, cmd);\n\tSMI_WRITE_REG(SMI_CR2, stmsmi_info->bank_num | SMI_SEND | SMI_TX_LEN_4);\n\n\t/* Poll transmit finished flag */\n\tSMI_POLL_TFF(SMI_CMD_TIMEOUT);\n\n\t/* poll WIP for end of self timed Sector Erase cycle */\n\tretval = wait_till_ready(bank, SMI_MAX_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stmsmi_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: from sector %u to sector %u\", __func__, first, last);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((last < first) || (last >= bank->num_sectors)) {\n\t\tLOG_ERROR(\"Flash sector invalid\");\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tif (!(stmsmi_info->probed)) {\n\t\tLOG_ERROR(\"Flash bank not probed\");\n\t\treturn ERROR_FLASH_BANK_NOT_PROBED;\n\t}\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tif (bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (stmsmi_info->dev->erase_cmd == 0x00)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tretval = smi_erase_sector(bank, sector);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\tkeep_alive();\n\t}\n\n\t/* Switch to HW mode before return to prompt */\n\tSMI_SET_HW_MODE();\n\treturn retval;\n}\n\nstatic int stmsmi_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tfor (unsigned int sector = first; sector <= last; sector++)\n\t\tbank->sectors[sector].is_protected = set;\n\treturn ERROR_OK;\n}\n\nstatic int smi_write_buffer(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t address, uint32_t len)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tint retval;\n\n\tLOG_DEBUG(\"%s: address=0x%08\" PRIx32 \" len=0x%08\" PRIx32,\n\t\t\t__func__, address, len);\n\n\tretval = smi_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* HW mode, write burst mode */\n\tSMI_SET_HWWB_MODE();\n\n\tretval = target_write_buffer(target, address, len, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int stmsmi_write(struct flash_bank *bank, const uint8_t *buffer,\n\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tuint32_t cur_count, page_size, page_offset;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"%s: offset=0x%08\" PRIx32 \" count=0x%08\" PRIx32,\n\t\t__func__, offset, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset + count > stmsmi_info->dev->size_in_bytes) {\n\t\tLOG_WARNING(\"Write pasts end of flash. Extra data discarded.\");\n\t\tcount = stmsmi_info->dev->size_in_bytes - offset;\n\t}\n\n\t/* Check sector protection */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\t/* Start offset in or before this sector? */\n\t\t/* End offset in or behind this sector? */\n\t\tif ((offset <\n\t\t\t\t(bank->sectors[sector].offset + bank->sectors[sector].size))\n\t\t\t&& ((offset + count - 1) >= bank->sectors[sector].offset)\n\t\t\t&& bank->sectors[sector].is_protected) {\n\t\t\tLOG_ERROR(\"Flash sector %u protected\", sector);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* if no valid page_size, use reasonable default */\n\tpage_size = stmsmi_info->dev->pagesize ?\n\t\tstmsmi_info->dev->pagesize : SPIFLASH_DEF_PAGESIZE;\n\n\t/* unaligned buffer head */\n\tif (count > 0 && (offset & 3) != 0) {\n\t\tcur_count = 4 - (offset & 3);\n\t\tif (cur_count > count)\n\t\t\tcur_count = count;\n\t\tretval = smi_write_buffer(bank, buffer, bank->base + offset,\n\t\t\tcur_count);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\t\toffset += cur_count;\n\t\tbuffer += cur_count;\n\t\tcount -= cur_count;\n\t}\n\n\tpage_offset = offset % page_size;\n\t/* central part, aligned words */\n\twhile (count >= 4) {\n\t\t/* clip block at page boundary */\n\t\tif (page_offset + count > page_size)\n\t\t\tcur_count = page_size - page_offset;\n\t\telse\n\t\t\tcur_count = count & ~3;\n\n\t\tretval = smi_write_buffer(bank, buffer, bank->base + offset,\n\t\t\tcur_count);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err;\n\n\t\tpage_offset = 0;\n\t\tbuffer += cur_count;\n\t\toffset += cur_count;\n\t\tcount -= cur_count;\n\n\t\tkeep_alive();\n\t}\n\n\t/* buffer tail */\n\tif (count > 0)\n\t\tretval = smi_write_buffer(bank, buffer, bank->base + offset, count);\n\nerr:\n\t/* Switch to HW mode before return to prompt */\n\tSMI_SET_HW_MODE();\n\treturn retval;\n}\n\n/* Return ID of flash device */\n/* On exit, SW mode is kept */\nstatic int read_flash_id(struct flash_bank *bank, uint32_t *id)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base = stmsmi_info->io_base;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* poll WIP */\n\tretval = wait_till_ready(bank, SMI_PROBE_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* enter in SW mode */\n\tSMI_SET_SW_MODE();\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t/* Send SPI command \"read ID\" */\n\tSMI_WRITE_REG(SMI_TR, SMI_READ_ID);\n\tSMI_WRITE_REG(SMI_CR2,\n\t\tstmsmi_info->bank_num | SMI_SEND | SMI_RX_LEN_3 | SMI_TX_LEN_1);\n\n\t/* Poll transmit finished flag */\n\tSMI_POLL_TFF(SMI_CMD_TIMEOUT);\n\n\t/* clear transmit finished flag */\n\tSMI_CLEAR_TFF();\n\n\t/* read ID from Receive Register */\n\t*id = SMI_READ_REG(SMI_RR) & 0x00ffffff;\n\treturn ERROR_OK;\n}\n\nstatic int stmsmi_probe(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tuint32_t io_base, sectorsize;\n\tstruct flash_sector *sectors;\n\tuint32_t id = 0; /* silence uninitialized warning */\n\tconst struct stmsmi_target *target_device;\n\tint retval;\n\n\tif (stmsmi_info->probed)\n\t\tfree(bank->sectors);\n\tstmsmi_info->probed = false;\n\n\tfor (target_device = target_devices ; target_device->name ; ++target_device)\n\t\tif (target_device->tap_idcode == target->tap->idcode)\n\t\t\tbreak;\n\tif (!target_device->name) {\n\t\tLOG_ERROR(\"Device ID 0x%\" PRIx32 \" is not known as SMI capable\",\n\t\t\t\ttarget->tap->idcode);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (bank->base - target_device->smi_base) {\n\t\tcase 0:\n\t\t\tstmsmi_info->bank_num = SMI_SEL_BANK0;\n\t\t\tbreak;\n\t\tcase SMI_BANK_SIZE:\n\t\t\tstmsmi_info->bank_num = SMI_SEL_BANK1;\n\t\t\tbreak;\n\t\tcase 2*SMI_BANK_SIZE:\n\t\t\tstmsmi_info->bank_num = SMI_SEL_BANK2;\n\t\t\tbreak;\n\t\tcase 3*SMI_BANK_SIZE:\n\t\t\tstmsmi_info->bank_num = SMI_SEL_BANK3;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Invalid SMI base address \" TARGET_ADDR_FMT, bank->base);\n\t\t\treturn ERROR_FAIL;\n\t}\n\tio_base = target_device->io_base;\n\tstmsmi_info->io_base = io_base;\n\n\tLOG_DEBUG(\"Valid SMI on device %s at address \" TARGET_ADDR_FMT,\n\t\ttarget_device->name, bank->base);\n\n\t/* read and decode flash ID; returns in SW mode */\n\tretval = read_flash_id(bank, &id);\n\tSMI_SET_HW_MODE();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstmsmi_info->dev = NULL;\n\tfor (const struct flash_device *p = flash_devices; p->name ; p++)\n\t\tif (p->device_id == id) {\n\t\t\tstmsmi_info->dev = p;\n\t\t\tbreak;\n\t\t}\n\n\tif (!stmsmi_info->dev) {\n\t\tLOG_ERROR(\"Unknown flash device (ID 0x%08\" PRIx32 \")\", id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Found flash device \\'%s\\' (ID 0x%08\" PRIx32 \")\",\n\t\tstmsmi_info->dev->name, stmsmi_info->dev->device_id);\n\n\t/* Set correct size value */\n\tbank->size = stmsmi_info->dev->size_in_bytes;\n\tif (bank->size <= (1UL << 16))\n\t\tLOG_WARNING(\"device needs 2-byte addresses - not implemented\");\n\tif (bank->size > (1UL << 24))\n\t\tLOG_WARNING(\"device needs paging or 4-byte addresses - not implemented\");\n\n\t/* if no sectors, treat whole bank as single sector */\n\tsectorsize = stmsmi_info->dev->sectorsize ?\n\t\tstmsmi_info->dev->sectorsize : stmsmi_info->dev->size_in_bytes;\n\n\t/* create and fill sectors array */\n\tbank->num_sectors =\n\t\tstmsmi_info->dev->size_in_bytes / sectorsize;\n\tsectors = malloc(sizeof(struct flash_sector) * bank->num_sectors);\n\tif (!sectors) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tsectors[sector].offset = sector * sectorsize;\n\t\tsectors[sector].size = sectorsize;\n\t\tsectors[sector].is_erased = -1;\n\t\tsectors[sector].is_protected = 1;\n\t}\n\n\tbank->sectors = sectors;\n\tstmsmi_info->probed = true;\n\treturn ERROR_OK;\n}\n\nstatic int stmsmi_auto_probe(struct flash_bank *bank)\n{\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\tif (stmsmi_info->probed)\n\t\treturn ERROR_OK;\n\treturn stmsmi_probe(bank);\n}\n\nstatic int stmsmi_protect_check(struct flash_bank *bank)\n{\n\t/* Nothing to do. Protection is only handled in SW. */\n\treturn ERROR_OK;\n}\n\nstatic int get_stmsmi_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct stmsmi_flash_bank *stmsmi_info = bank->driver_priv;\n\n\tif (!(stmsmi_info->probed)) {\n\t\tcommand_print_sameline(cmd, \"\\nSMI flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\nSMI flash information:\\n\"\n\t\t\"  Device \\'%s\\' (ID 0x%08\" PRIx32 \")\\n\",\n\t\tstmsmi_info->dev->name, stmsmi_info->dev->device_id);\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver stmsmi_flash = {\n\t.name = \"stmsmi\",\n\t.flash_bank_command = stmsmi_flash_bank_command,\n\t.erase = stmsmi_erase,\n\t.protect = stmsmi_protect,\n\t.write = stmsmi_write,\n\t.read = default_flash_read,\n\t.probe = stmsmi_probe,\n\t.auto_probe = stmsmi_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = stmsmi_protect_check,\n\t.info = get_stmsmi_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/str7x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2010 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/arm.h>\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n\n/*  Flash registers */\n\n#define FLASH_CR0\t\t0x00000000\n#define FLASH_CR1\t\t0x00000004\n#define FLASH_DR0\t\t0x00000008\n#define FLASH_DR1\t\t0x0000000C\n#define FLASH_AR\t\t0x00000010\n#define FLASH_ER\t\t0x00000014\n#define FLASH_NVWPAR\t0x0000DFB0\n#define FLASH_NVAPR0\t0x0000DFB8\n#define FLASH_NVAPR1\t0x0000DFBC\n\n/* FLASH_CR0 register bits */\n\n#define FLASH_WMS\t\t0x80000000\n#define FLASH_SUSP\t\t0x40000000\n#define FLASH_WPG\t\t0x20000000\n#define FLASH_DWPG\t\t0x10000000\n#define FLASH_SER\t\t0x08000000\n#define FLASH_SPR\t\t0x01000000\n#define FLASH_BER\t\t0x04000000\n#define FLASH_MER\t\t0x02000000\n#define FLASH_LOCK\t\t0x00000010\n#define FLASH_BSYA1\t\t0x00000004\n#define FLASH_BSYA0\t\t0x00000002\n\n/* FLASH_CR1 register bits */\n\n#define FLASH_B1S\t\t0x02000000\n#define FLASH_B0S\t\t0x01000000\n#define FLASH_B1F1\t\t0x00020000\n#define FLASH_B1F0\t\t0x00010000\n#define FLASH_B0F7\t\t0x00000080\n#define FLASH_B0F6\t\t0x00000040\n#define FLASH_B0F5\t\t0x00000020\n#define FLASH_B0F4\t\t0x00000010\n#define FLASH_B0F3\t\t0x00000008\n#define FLASH_B0F2\t\t0x00000004\n#define FLASH_B0F1\t\t0x00000002\n#define FLASH_B0F0\t\t0x00000001\n\n/* FLASH_ER register bits */\n\n#define FLASH_WPF\t\t0x00000100\n#define FLASH_RESER\t\t0x00000080\n#define FLASH_SEQER\t\t0x00000040\n#define FLASH_10ER\t\t0x00000008\n#define FLASH_PGER\t\t0x00000004\n#define FLASH_ERER\t\t0x00000002\n#define FLASH_ERR\t\t0x00000001\n\n\nstruct str7x_flash_bank {\n\tuint32_t *sector_bits;\n\tuint32_t disable_bit;\n\tuint32_t busy_bits;\n\tuint32_t register_base;\n};\n\nstruct str7x_mem_layout {\n\tuint32_t sector_start;\n\tuint32_t sector_size;\n\tuint32_t sector_bit;\n};\n\nenum str7x_status_codes {\n\tSTR7X_CMD_SUCCESS = 0,\n\tSTR7X_INVALID_COMMAND = 1,\n\tSTR7X_SRC_ADDR_ERROR = 2,\n\tSTR7X_DST_ADDR_ERROR = 3,\n\tSTR7X_SRC_ADDR_NOT_MAPPED = 4,\n\tSTR7X_DST_ADDR_NOT_MAPPED = 5,\n\tSTR7X_COUNT_ERROR = 6,\n\tSTR7X_INVALID_SECTOR = 7,\n\tSTR7X_SECTOR_NOT_BLANK = 8,\n\tSTR7X_SECTOR_NOT_PREPARED = 9,\n\tSTR7X_COMPARE_ERROR = 10,\n\tSTR7X_BUSY = 11\n};\n\nstatic const struct str7x_mem_layout mem_layout_str7bank0[] = {\n\t{0x00000000, 0x02000, 0x01},\n\t{0x00002000, 0x02000, 0x02},\n\t{0x00004000, 0x02000, 0x04},\n\t{0x00006000, 0x02000, 0x08},\n\t{0x00008000, 0x08000, 0x10},\n\t{0x00010000, 0x10000, 0x20},\n\t{0x00020000, 0x10000, 0x40},\n\t{0x00030000, 0x10000, 0x80}\n};\n\nstatic const struct str7x_mem_layout mem_layout_str7bank1[] = {\n\t{0x00000000, 0x02000, 0x10000},\n\t{0x00002000, 0x02000, 0x20000}\n};\n\nstatic int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\treturn str7x_info->register_base | reg;\n}\n\nstatic int str7x_build_block_list(struct flash_bank *bank)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\n\tint i;\n\tunsigned int num_sectors;\n\tint b0_sectors = 0, b1_sectors = 0;\n\n\tswitch (bank->size) {\n\t\tcase 16 * 1024:\n\t\t\tb1_sectors = 2;\n\t\t\tbreak;\n\t\tcase 64 * 1024:\n\t\t\tb0_sectors = 5;\n\t\t\tbreak;\n\t\tcase 128 * 1024:\n\t\t\tb0_sectors = 6;\n\t\t\tbreak;\n\t\tcase 256 * 1024:\n\t\t\tb0_sectors = 8;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\texit(-1);\n\t}\n\n\tnum_sectors = b0_sectors + b1_sectors;\n\n\tbank->num_sectors = num_sectors;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tstr7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);\n\n\tnum_sectors = 0;\n\n\tfor (i = 0; i < b0_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;\n\t\tbank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\t/* the reset_init handler marks all the sectors unprotected,\n\t\t * matching hardware after reset; keep the driver in sync\n\t\t */\n\t\tbank->sectors[num_sectors].is_protected = 0;\n\t\tstr7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;\n\t}\n\n\tfor (i = 0; i < b1_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;\n\t\tbank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\t/* the reset_init handler marks all the sectors unprotected,\n\t\t * matching hardware after reset; keep the driver in sync\n\t\t */\n\t\tbank->sectors[num_sectors].is_protected = 0;\n\t\tstr7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>\n */\nFLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)\n{\n\tstruct str7x_flash_bank *str7x_info;\n\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstr7x_info = malloc(sizeof(struct str7x_flash_bank));\n\tbank->driver_priv = str7x_info;\n\n\t/* set default bits for str71x flash */\n\tstr7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);\n\tstr7x_info->disable_bit = (1 << 1);\n\n\tif (strcmp(CMD_ARGV[6], \"STR71x\") == 0)\n\t\tstr7x_info->register_base = 0x40100000;\n\telse if (strcmp(CMD_ARGV[6], \"STR73x\") == 0) {\n\t\tstr7x_info->register_base = 0x80100000;\n\t\tstr7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);\n\t} else if (strcmp(CMD_ARGV[6], \"STR75x\") == 0) {\n\t\tstr7x_info->register_base = 0x20100000;\n\t\tstr7x_info->disable_bit = (1 << 0);\n\t} else {\n\t\tLOG_ERROR(\"unknown STR7x variant: '%s'\", CMD_ARGV[6]);\n\t\tfree(str7x_info);\n\t\treturn ERROR_FLASH_BANK_INVALID;\n\t}\n\n\tstr7x_build_block_list(bank);\n\n\treturn ERROR_OK;\n}\n\n/* wait for flash to become idle or report errors.\n\n   FIX!!! what's the maximum timeout??? The documentation doesn't\n   state any maximum time.... by inspection it seems > 1000ms is to be\n   expected.\n\n   10000ms is long enough that it should cover anything, yet not\n   quite be equivalent to an infinite loop.\n\n */\nstatic int str7x_waitbusy(struct flash_bank *bank)\n{\n\tint err;\n\tint i;\n\tstruct target *target = bank->target;\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\n\tfor (i = 0 ; i < 10000; i++) {\n\t\tuint32_t retval;\n\t\terr = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tif ((retval & str7x_info->busy_bits) == 0)\n\t\t\treturn ERROR_OK;\n\n\t\talive_sleep(1);\n\t}\n\tLOG_ERROR(\"Timed out waiting for str7x flash\");\n\treturn ERROR_FAIL;\n}\n\n\nstatic int str7x_result(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tuint32_t flash_flags;\n\n\tint retval;\n\tretval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &flash_flags);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (flash_flags & FLASH_WPF) {\n\t\tLOG_ERROR(\"str7x hw write protection set\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tif (flash_flags & FLASH_RESER) {\n\t\tLOG_ERROR(\"str7x suspended program erase not resumed\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tif (flash_flags & FLASH_10ER) {\n\t\tLOG_ERROR(\"str7x trying to set bit to 1 when it is already 0\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tif (flash_flags & FLASH_PGER) {\n\t\tLOG_ERROR(\"str7x program error\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tif (flash_flags & FLASH_ERER) {\n\t\tLOG_ERROR(\"str7x erase error\");\n\t\tretval = ERROR_FAIL;\n\t}\n\tif (retval == ERROR_OK) {\n\t\tif (flash_flags & FLASH_ERR) {\n\t\t\t/* this should always be set if one of the others are set... */\n\t\t\tLOG_ERROR(\"str7x write operation failed / bad setup\");\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int str7x_protect_check(struct flash_bank *bank)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tuint32_t flash_flags;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tint retval;\n\tretval = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &flash_flags);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (flash_flags & str7x_info->sector_bits[i])\n\t\t\tbank->sectors[i].is_protected = 0;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str7x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tuint32_t cmd;\n\tuint32_t sectors = 0;\n\tint err;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++)\n\t\tsectors |= str7x_info->sector_bits[i];\n\n\tLOG_DEBUG(\"sectors: 0x%\" PRIx32 \"\", sectors);\n\n\t/* clear FLASH_ER register */\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = FLASH_SER;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = sectors;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = FLASH_SER | FLASH_WMS;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = str7x_waitbusy(bank);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = str7x_result(bank);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nstatic int str7x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t cmd;\n\tuint32_t protect_blocks;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tprotect_blocks = 0xFFFFFFFF;\n\n\tif (set) {\n\t\tfor (unsigned int i = first; i <= last; i++)\n\t\t\tprotect_blocks &= ~(str7x_info->sector_bits[i]);\n\t}\n\n\t/* clear FLASH_ER register */\n\tint err;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = FLASH_SPR;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = protect_blocks;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcmd = FLASH_SPR | FLASH_WMS;\n\terr = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = str7x_waitbusy(bank);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = str7x_result(bank);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nstatic int str7x_write_block(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct str7x_flash_bank *str7x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 32768;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[6];\n\tstruct arm_algorithm arm_algo;\n\tint retval = ERROR_OK;\n\n\t/* see contrib/loaders/flash/str7x.s for src */\n\n\tstatic const uint32_t str7x_flash_write_code[] = {\n\t\t\t\t\t/* write:\t\t\t\t*/\n\t\t0xe3a04201, /*\tmov r4, #0x10000000\t*/\n\t\t0xe5824000, /*\tstr r4, [r2, #0x0]\t*/\n\t\t0xe5821010, /*\tstr r1, [r2, #0x10]\t*/\n\t\t0xe4904004, /*\tldr r4, [r0], #4\t*/\n\t\t0xe5824008, /*\tstr r4, [r2, #0x8]\t*/\n\t\t0xe4904004, /*\tldr r4, [r0], #4\t*/\n\t\t0xe582400c, /*\tstr r4, [r2, #0xc]\t*/\n\t\t0xe3a04209, /*\tmov r4, #0x90000000\t*/\n\t\t0xe5824000, /*\tstr r4, [r2, #0x0]\t*/\n\t\t\t\t\t/* busy:\t\t\t\t*/\n\t\t0xe5924000, /*\tldr r4, [r2, #0x0]\t*/\n\t\t0xe1140005,\t/*\ttst r4, r5\t\t\t*/\n\t\t0x1afffffc, /*\tbne busy\t\t\t*/\n\t\t0xe5924014, /*\tldr r4, [r2, #0x14]\t*/\n\t\t0xe31400ff, /*\ttst r4, #0xff\t\t*/\n\t\t0x03140c01, /*\ttsteq r4, #0x100\t*/\n\t\t0x1a000002, /*\tbne exit\t\t\t*/\n\t\t0xe2811008, /*\tadd r1, r1, #0x8\t*/\n\t\t0xe2533001, /*\tsubs r3, r3, #1\t\t*/\n\t\t0x1affffec, /*\tbne write\t\t\t*/\n\t\t\t\t\t/* exit:\t\t\t\t*/\n\t\t0xeafffffe, /*\tb exit\t\t\t\t*/\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tuint8_t code[sizeof(str7x_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(str7x_flash_write_code),\n\t\t\tstr7x_flash_write_code);\n\ttarget_write_buffer(target, write_algorithm->address, sizeof(code), code);\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[4], \"r4\", 32, PARAM_IN);\n\tinit_reg_param(&reg_params[5], \"r5\", 32, PARAM_OUT);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;\n\n\t\ttarget_write_buffer(target, source->address, thisrun_count * 8, buffer);\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, thisrun_count);\n\t\tbuf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 6, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\twrite_algorithm->address + (sizeof(str7x_flash_write_code) - 4),\n\t\t\t\t10000, &arm_algo);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (buf_get_u32(reg_params[4].value, 0, 32) != 0x00) {\n\t\t\tretval = str7x_result(bank);\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count * 8;\n\t\taddress += thisrun_count * 8;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\tdestroy_reg_param(&reg_params[4]);\n\tdestroy_reg_param(&reg_params[5]);\n\n\treturn retval;\n}\n\nstatic int str7x_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t dwords_remaining = (count / 8);\n\tuint32_t bytes_remaining = (count & 0x00000007);\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tuint32_t cmd;\n\tint retval;\n\tuint32_t check_address = offset;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x7) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 8-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint32_t sec_start = bank->sectors[i].offset;\n\t\tuint32_t sec_end = sec_start + bank->sectors[i].size;\n\n\t\t/* check if destination falls within the current sector */\n\t\tif ((check_address >= sec_start) && (check_address < sec_end)) {\n\t\t\t/* check if destination ends in the current sector */\n\t\t\tif (offset + count < sec_end)\n\t\t\t\tcheck_address = offset + count;\n\t\t\telse\n\t\t\t\tcheck_address = sec_end;\n\t\t}\n\t}\n\n\tif (check_address != offset + count)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\t/* clear FLASH_ER register */\n\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);\n\n\t/* multiple dwords (8-byte) to be programmed? */\n\tif (dwords_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = str7x_write_block(bank, buffer, offset, dwords_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) single dword accesses */\n\t\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += dwords_remaining * 8;\n\t\t\taddress += dwords_remaining * 8;\n\t\t\tdwords_remaining = 0;\n\t\t}\n\t}\n\n\twhile (dwords_remaining > 0) {\n\t\t/* command */\n\t\tcmd = FLASH_DWPG;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\n\t\t/* address */\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);\n\n\t\t/* data word 1 */\n\t\ttarget_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),\n\t\t\t\t4, 1, buffer + bytes_written);\n\t\tbytes_written += 4;\n\n\t\t/* data word 2 */\n\t\ttarget_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),\n\t\t\t\t4, 1, buffer + bytes_written);\n\t\tbytes_written += 4;\n\n\t\t/* start programming cycle */\n\t\tcmd = FLASH_DWPG | FLASH_WMS;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\n\t\tint err;\n\t\terr = str7x_waitbusy(bank);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = str7x_result(bank);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tdwords_remaining--;\n\t\taddress += 8;\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\n\n\t\t/* copy the last remaining bytes into the write buffer */\n\t\tmemcpy(last_dword, buffer+bytes_written, bytes_remaining);\n\n\t\t/* command */\n\t\tcmd = FLASH_DWPG;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\n\t\t/* address */\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);\n\n\t\t/* data word 1 */\n\t\ttarget_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),\n\t\t\t\t4, 1, last_dword);\n\n\t\t/* data word 2 */\n\t\ttarget_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),\n\t\t\t\t4, 1, last_dword + 4);\n\n\t\t/* start programming cycle */\n\t\tcmd = FLASH_DWPG | FLASH_WMS;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);\n\n\t\tint err;\n\t\terr = str7x_waitbusy(bank);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = str7x_result(bank);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str7x_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\n#if 0\nCOMMAND_HANDLER(str7x_handle_part_id_command)\n{\n\treturn ERROR_OK;\n}\n#endif\n\nstatic int get_str7x_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\t/* Setting the write protection on a sector is a permanent change but it\n\t * can be disabled temporarily. FLASH_NVWPAR reflects the permanent\n\t * protection state of the sectors, not the temporary.\n\t */\n\tcommand_print_sameline(cmd, \"STR7x flash protection info is only valid after a power cycle, \"\n\t\t\t\"clearing the protection is only temporary and may not be reflected in the current \"\n\t\t\t\"info returned.\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str7x_handle_disable_jtag_command)\n{\n\tstruct target *target = NULL;\n\tstruct str7x_flash_bank *str7x_info = NULL;\n\n\tuint32_t flash_cmd;\n\tuint16_t protection_level = 0;\n\tuint16_t protection_regs;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr7x_info = bank->driver_priv;\n\n\ttarget = bank->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* first we get protection status */\n\tuint32_t reg;\n\ttarget_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);\n\n\tif (!(reg & str7x_info->disable_bit))\n\t\tprotection_level = 1;\n\n\ttarget_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);\n\tprotection_regs = ~(reg >> 16);\n\n\twhile (((protection_regs) != 0) && (protection_level < 16)) {\n\t\tprotection_regs >>= 1;\n\t\tprotection_level++;\n\t}\n\n\tif (protection_level == 0) {\n\t\tflash_cmd = FLASH_SPR;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);\n\t\tflash_cmd = FLASH_SPR | FLASH_WMS;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);\n\t} else {\n\t\tflash_cmd = FLASH_SPR;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),\n\t\t\t\t~(1 << (15 + protection_level)));\n\t\tflash_cmd = FLASH_SPR | FLASH_WMS;\n\t\ttarget_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration str7x_exec_command_handlers[] = {\n\t{\n\t\t.name = \"disable_jtag\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str7x_handle_disable_jtag_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"disable jtag access\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration str7x_command_handlers[] = {\n\t{\n\t\t.name = \"str7x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"str7x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = str7x_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver str7x_flash = {\n\t.name = \"str7x\",\n\t.commands = str7x_command_handlers,\n\t.flash_bank_command = str7x_flash_bank_command,\n\t.erase = str7x_erase,\n\t.protect = str7x_protect,\n\t.write = str7x_write,\n\t.read = default_flash_read,\n\t.probe = str7x_probe,\n\t.auto_probe = str7x_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = str7x_protect_check,\n\t.info = get_str7x_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/str9x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *\n *   Copyright (C) 2008 by Oyvind Harboe                                   *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/arm966e.h>\n#include <target/algorithm.h>\n\n/* Flash registers */\n\n#define FLASH_BBSR\t\t0x54000000\t\t/* Boot Bank Size Register                */\n#define FLASH_NBBSR\t\t0x54000004\t\t/* Non-Boot Bank Size Register            */\n#define FLASH_BBADR\t\t0x5400000C\t\t/* Boot Bank Base Address Register        */\n#define FLASH_NBBADR\t0x54000010\t\t/* Non-Boot Bank Base Address Register    */\n#define FLASH_CR\t\t0x54000018\t\t/* Control Register                       */\n#define FLASH_SR\t\t0x5400001C\t\t/* Status Register                        */\n#define FLASH_BCE5ADDR\t0x54000020\t\t/* BC Fifth Entry Target Address Register */\n\nstruct str9x_flash_bank {\n\tuint32_t *sector_bits;\n\tint variant;\n\tint bank1;\n};\n\nenum str9x_status_codes {\n\tSTR9X_CMD_SUCCESS = 0,\n\tSTR9X_INVALID_COMMAND = 1,\n\tSTR9X_SRC_ADDR_ERROR = 2,\n\tSTR9X_DST_ADDR_ERROR = 3,\n\tSTR9X_SRC_ADDR_NOT_MAPPED = 4,\n\tSTR9X_DST_ADDR_NOT_MAPPED = 5,\n\tSTR9X_COUNT_ERROR = 6,\n\tSTR9X_INVALID_SECTOR = 7,\n\tSTR9X_SECTOR_NOT_BLANK = 8,\n\tSTR9X_SECTOR_NOT_PREPARED = 9,\n\tSTR9X_COMPARE_ERROR = 10,\n\tSTR9X_BUSY = 11\n};\n\nstatic uint32_t bank1start = 0x00080000;\n\nstatic int str9x_build_block_list(struct flash_bank *bank)\n{\n\tstruct str9x_flash_bank *str9x_info = bank->driver_priv;\n\n\tint i;\n\tunsigned int num_sectors;\n\tint b0_sectors = 0, b1_sectors = 0;\n\tuint32_t offset = 0;\n\n\t/* set if we have large flash str9 */\n\tstr9x_info->variant = 0;\n\tstr9x_info->bank1 = 0;\n\n\tswitch (bank->size) {\n\t\tcase (256 * 1024):\n\t\t\tb0_sectors = 4;\n\t\t\tbreak;\n\t\tcase (512 * 1024):\n\t\t\tb0_sectors = 8;\n\t\t\tbreak;\n\t\tcase (1024 * 1024):\n\t\t\tbank1start = 0x00100000;\n\t\t\tstr9x_info->variant = 1;\n\t\t\tb0_sectors = 16;\n\t\t\tbreak;\n\t\tcase (2048 * 1024):\n\t\t\tbank1start = 0x00200000;\n\t\t\tstr9x_info->variant = 1;\n\t\t\tb0_sectors = 32;\n\t\t\tbreak;\n\t\tcase (128 * 1024):\n\t\t\tstr9x_info->variant = 1;\n\t\t\tstr9x_info->bank1 = 1;\n\t\t\tb1_sectors = 8;\n\t\t\tbank1start = bank->base;\n\t\t\tbreak;\n\t\tcase (32 * 1024):\n\t\t\tstr9x_info->bank1 = 1;\n\t\t\tb1_sectors = 4;\n\t\t\tbank1start = bank->base;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\texit(-1);\n\t}\n\n\tnum_sectors = b0_sectors + b1_sectors;\n\n\tbank->num_sectors = num_sectors;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tstr9x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);\n\n\tnum_sectors = 0;\n\n\tfor (i = 0; i < b0_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = offset;\n\t\tbank->sectors[num_sectors].size = 0x10000;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\tbank->sectors[num_sectors].is_protected = 1;\n\t\tstr9x_info->sector_bits[num_sectors++] = (1 << i);\n\t}\n\n\tfor (i = 0; i < b1_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = offset;\n\t\tbank->sectors[num_sectors].size = str9x_info->variant == 0 ? 0x2000 : 0x4000;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\tbank->sectors[num_sectors].is_protected = 1;\n\t\tif (str9x_info->variant)\n\t\t\tstr9x_info->sector_bits[num_sectors++] = (1 << i);\n\t\telse\n\t\t\tstr9x_info->sector_bits[num_sectors++] = (1 << (i + 8));\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* flash bank str9x <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command)\n{\n\tstruct str9x_flash_bank *str9x_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstr9x_info = malloc(sizeof(struct str9x_flash_bank));\n\tbank->driver_priv = str9x_info;\n\n\tstr9x_build_block_list(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int str9x_protect_check(struct flash_bank *bank)\n{\n\tint retval;\n\tstruct str9x_flash_bank *str9x_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\n\tuint32_t adr;\n\tuint32_t status = 0;\n\tuint16_t hstatus = 0;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* read level one protection */\n\n\tif (str9x_info->variant) {\n\t\tif (str9x_info->bank1) {\n\t\t\tadr = bank1start + 0x18;\n\t\t\tretval = target_write_u16(target, adr, 0x90);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_read_u16(target, adr, &hstatus);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tstatus = hstatus;\n\t\t} else {\n\t\t\tadr = bank1start + 0x14;\n\t\t\tretval = target_write_u16(target, adr, 0x90);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_read_u32(target, adr, &status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\tadr = bank1start + 0x10;\n\t\tretval = target_write_u16(target, adr, 0x90);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_read_u16(target, adr, &hstatus);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tstatus = hstatus;\n\t}\n\n\t/* read array command */\n\tretval = target_write_u16(target, adr, 0xFF);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (status & str9x_info->sector_bits[i])\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9x_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tuint32_t adr;\n\tuint8_t status;\n\tuint8_t erase_cmd;\n\tint total_timeout;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Check if we can erase whole bank */\n\tif ((first == 0) && (last == (bank->num_sectors - 1))) {\n\t\t/* Optimize to run erase bank command instead of sector */\n\t\terase_cmd = 0x80;\n\t\t/* Add timeout duration since erase bank takes more time */\n\t\ttotal_timeout = 1000 * bank->num_sectors;\n\t} else {\n\t\t/* Erase sector command */\n\t\terase_cmd = 0x20;\n\t\ttotal_timeout = 1000;\n\t}\n\n\t/* this is so the compiler can *know* */\n\tassert(total_timeout > 0);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tint retval;\n\t\tadr = bank->base + bank->sectors[i].offset;\n\n\t\t/* erase sectors or block */\n\t\tretval = target_write_u16(target, adr, erase_cmd);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u16(target, adr, 0xD0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* get status */\n\t\tretval = target_write_u16(target, adr, 0x70);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tint timeout;\n\t\tfor (timeout = 0; timeout < total_timeout; timeout++) {\n\t\t\tretval = target_read_u8(target, adr, &status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (status & 0x80)\n\t\t\t\tbreak;\n\t\t\talive_sleep(1);\n\t\t}\n\t\tif (timeout == total_timeout) {\n\t\t\tLOG_ERROR(\"erase timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* clear status, also clear read array */\n\t\tretval = target_write_u16(target, adr, 0x50);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* read array command */\n\t\tretval = target_write_u16(target, adr, 0xFF);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (status & 0x22) {\n\t\t\tLOG_ERROR(\"error erasing flash bank, status: 0x%x\", status);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\t/* If we ran erase bank command, we are finished */\n\t\tif (erase_cmd == 0x80)\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9x_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tuint32_t adr;\n\tuint8_t status;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\t/* Level One Protection */\n\n\t\tadr = bank->base + bank->sectors[i].offset;\n\n\t\ttarget_write_u16(target, adr, 0x60);\n\t\tif (set)\n\t\t\ttarget_write_u16(target, adr, 0x01);\n\t\telse\n\t\t\ttarget_write_u16(target, adr, 0xD0);\n\n\t\t/* query status */\n\t\ttarget_read_u8(target, adr, &status);\n\n\t\t/* clear status, also clear read array */\n\t\ttarget_write_u16(target, adr, 0x50);\n\n\t\t/* read array command */\n\t\ttarget_write_u16(target, adr, 0xFF);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9x_write_block(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t buffer_size = 32768;\n\tstruct working_area *write_algorithm;\n\tstruct working_area *source;\n\tuint32_t address = bank->base + offset;\n\tstruct reg_param reg_params[4];\n\tstruct arm_algorithm arm_algo;\n\tint retval = ERROR_OK;\n\n\t/* see contrib/loaders/flash/str9x.s for src */\n\n\tstatic const uint32_t str9x_flash_write_code[] = {\n\t\t\t\t\t/* write:\t\t\t\t*/\n\t\t0xe3c14003,\t/*\tbic\tr4, r1, #3\t\t*/\n\t\t0xe3a03040,\t/*\tmov\tr3, #0x40\t\t*/\n\t\t0xe1c430b0,\t/*\tstrh r3, [r4, #0]\t*/\n\t\t0xe0d030b2,\t/*\tldrh r3, [r0], #2\t*/\n\t\t0xe0c130b2,\t/*\tstrh r3, [r1], #2\t*/\n\t\t0xe3a03070,\t/*\tmov r3, #0x70\t\t*/\n\t\t0xe1c430b0,\t/*\tstrh r3, [r4, #0]\t*/\n\t\t\t\t\t/* busy:\t\t\t\t*/\n\t\t0xe5d43000,\t/*\tldrb r3, [r4, #0]\t*/\n\t\t0xe3130080,\t/*\ttst r3, #0x80\t\t*/\n\t\t0x0afffffc,\t/*\tbeq busy\t\t\t*/\n\t\t0xe3a05050,\t/*\tmov\tr5, #0x50\t\t*/\n\t\t0xe1c450b0,\t/*\tstrh r5, [r4, #0]\t*/\n\t\t0xe3a050ff,\t/*\tmov\tr5, #0xFF\t\t*/\n\t\t0xe1c450b0,\t/*\tstrh r5, [r4, #0]\t*/\n\t\t0xe3130012,\t/*\ttst\tr3, #0x12\t\t*/\n\t\t0x1a000001,\t/*\tbne exit\t\t\t*/\n\t\t0xe2522001,\t/*\tsubs r2, r2, #1\t\t*/\n\t\t0x1affffed,\t/*\tbne write\t\t\t*/\n\t\t\t\t\t/* exit:\t\t\t\t*/\n\t\t0xe1200070,\t/*\tbkpt #0\t\t\t\t*/\n\t};\n\n\t/* flash write code */\n\tif (target_alloc_working_area(target, sizeof(str9x_flash_write_code),\n\t\t\t&write_algorithm) != ERROR_OK) {\n\t\tLOG_WARNING(\"no working area available, can't do block memory writes\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tuint8_t code[sizeof(str9x_flash_write_code)];\n\ttarget_buffer_set_u32_array(target, code, ARRAY_SIZE(str9x_flash_write_code),\n\t\t\tstr9x_flash_write_code);\n\ttarget_write_buffer(target, write_algorithm->address, sizeof(code), code);\n\n\t/* memory buffer */\n\twhile (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {\n\t\tbuffer_size /= 2;\n\t\tif (buffer_size <= 256) {\n\t\t\t/* we already allocated the writing code, but failed to get a\n\t\t\t * buffer, free the algorithm */\n\t\t\ttarget_free_working_area(target, write_algorithm);\n\n\t\t\tLOG_WARNING(\"no large enough working area available, can't do block memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_IN);\n\n\twhile (count > 0) {\n\t\tuint32_t thisrun_count = (count > (buffer_size / 2)) ? (buffer_size / 2) : count;\n\n\t\ttarget_write_buffer(target, source->address, thisrun_count * 2, buffer);\n\n\t\tbuf_set_u32(reg_params[0].value, 0, 32, source->address);\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, address);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, thisrun_count);\n\n\t\tretval = target_run_algorithm(target, 0, NULL, 4, reg_params,\n\t\t\t\twrite_algorithm->address,\n\t\t\t\t0, 10000, &arm_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error executing str9x flash write algorithm\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (buf_get_u32(reg_params[3].value, 0, 32) != 0x80) {\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += thisrun_count * 2;\n\t\taddress += thisrun_count * 2;\n\t\tcount -= thisrun_count;\n\t}\n\n\ttarget_free_working_area(target, source);\n\ttarget_free_working_area(target, write_algorithm);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\tdestroy_reg_param(&reg_params[3]);\n\n\treturn retval;\n}\n\nstatic int str9x_write(struct flash_bank *bank,\n\t\tconst uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t words_remaining = (count / 2);\n\tuint32_t bytes_remaining = (count & 0x00000001);\n\tuint32_t address = bank->base + offset;\n\tuint32_t bytes_written = 0;\n\tuint8_t status;\n\tint retval;\n\tuint32_t check_address = offset;\n\tuint32_t bank_adr;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (offset & 0x1) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 2-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint32_t sec_start = bank->sectors[i].offset;\n\t\tuint32_t sec_end = sec_start + bank->sectors[i].size;\n\n\t\t/* check if destination falls within the current sector */\n\t\tif ((check_address >= sec_start) && (check_address < sec_end)) {\n\t\t\t/* check if destination ends in the current sector */\n\t\t\tif (offset + count < sec_end)\n\t\t\t\tcheck_address = offset + count;\n\t\t\telse\n\t\t\t\tcheck_address = sec_end;\n\t\t}\n\t}\n\n\tif (check_address != offset + count)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\t/* multiple half words (2-byte) to be programmed? */\n\tif (words_remaining > 0) {\n\t\t/* try using a block write */\n\t\tretval = str9x_write_block(bank, buffer, offset, words_remaining);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\t\t/* if block write failed (no sufficient working area),\n\t\t\t\t * we use normal (slow) single dword accesses */\n\t\t\t\tLOG_WARNING(\"couldn't use block writes, falling back to single memory accesses\");\n\t\t\t} else if (retval == ERROR_FLASH_OPERATION_FAILED) {\n\t\t\t\tLOG_ERROR(\"flash writing failed\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t} else {\n\t\t\tbuffer += words_remaining * 2;\n\t\t\taddress += words_remaining * 2;\n\t\t\twords_remaining = 0;\n\t\t}\n\t}\n\n\twhile (words_remaining > 0) {\n\t\tbank_adr = address & ~0x03;\n\n\t\t/* write data command */\n\t\ttarget_write_u16(target, bank_adr, 0x40);\n\t\ttarget_write_memory(target, address, 2, 1, buffer + bytes_written);\n\n\t\t/* get status command */\n\t\ttarget_write_u16(target, bank_adr, 0x70);\n\n\t\tint timeout;\n\t\tfor (timeout = 0; timeout < 1000; timeout++) {\n\t\t\ttarget_read_u8(target, bank_adr, &status);\n\t\t\tif (status & 0x80)\n\t\t\t\tbreak;\n\t\t\talive_sleep(1);\n\t\t}\n\t\tif (timeout == 1000) {\n\t\t\tLOG_ERROR(\"write timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* clear status reg and read array */\n\t\ttarget_write_u16(target, bank_adr, 0x50);\n\t\ttarget_write_u16(target, bank_adr, 0xFF);\n\n\t\tif (status & 0x10)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\telse if (status & 0x02)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\tbytes_written += 2;\n\t\twords_remaining--;\n\t\taddress += 2;\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint8_t last_halfword[2] = {0xff, 0xff};\n\n\t\t/* copy the last remaining bytes into the write buffer */\n\t\tmemcpy(last_halfword, buffer+bytes_written, bytes_remaining);\n\n\t\tbank_adr = address & ~0x03;\n\n\t\t/* write data command */\n\t\ttarget_write_u16(target, bank_adr, 0x40);\n\t\ttarget_write_memory(target, address, 2, 1, last_halfword);\n\n\t\t/* query status command */\n\t\ttarget_write_u16(target, bank_adr, 0x70);\n\n\t\tint timeout;\n\t\tfor (timeout = 0; timeout < 1000; timeout++) {\n\t\t\ttarget_read_u8(target, bank_adr, &status);\n\t\t\tif (status & 0x80)\n\t\t\t\tbreak;\n\t\t\talive_sleep(1);\n\t\t}\n\t\tif (timeout == 1000) {\n\t\t\tLOG_ERROR(\"write timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* clear status reg and read array */\n\t\ttarget_write_u16(target, bank_adr, 0x50);\n\t\ttarget_write_u16(target, bank_adr, 0xFF);\n\n\t\tif (status & 0x10)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\telse if (status & 0x02)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9x_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\n#if 0\nCOMMAND_HANDLER(str9x_handle_part_id_command)\n{\n\treturn ERROR_OK;\n}\n#endif\n\nCOMMAND_HANDLER(str9x_handle_flash_config_command)\n{\n\tstruct target *target = NULL;\n\n\tif (CMD_ARGC < 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t bbsr, nbbsr, bbadr, nbbadr;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], bbsr);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], nbbsr);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], bbadr);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], nbbadr);\n\n\ttarget = bank->target;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* config flash controller */\n\ttarget_write_u32(target, FLASH_BBSR, bbsr);\n\ttarget_write_u32(target, FLASH_NBBSR, nbbsr);\n\ttarget_write_u32(target, FLASH_BBADR, bbadr >> 2);\n\ttarget_write_u32(target, FLASH_NBBADR, nbbadr >> 2);\n\n\t/* set bit 18 instruction TCM order as per flash programming manual */\n\tarm966e_write_cp15(target, 62, 0x40000);\n\n\t/* enable flash bank 1 */\n\ttarget_write_u32(target, FLASH_CR, 0x18);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration str9x_config_command_handlers[] = {\n\t{\n\t\t.name = \"flash_config\",\n\t\t.handler = str9x_handle_flash_config_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Configure str9x flash controller, prior to \"\n\t\t\t\"programming the flash.\",\n\t\t.usage = \"bank_id BBSR NBBSR BBADR NBBADR\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration str9x_command_handlers[] = {\n\t{\n\t\t.name = \"str9x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"str9x flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = str9x_config_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver str9x_flash = {\n\t.name = \"str9x\",\n\t.commands = str9x_command_handlers,\n\t.flash_bank_command = str9x_flash_bank_command,\n\t.erase = str9x_erase,\n\t.protect = str9x_protect,\n\t.write = str9x_write,\n\t.read = default_flash_read,\n\t.probe = str9x_probe,\n\t.auto_probe = str9x_probe,\n\t.erase_check = default_flash_blank_check,\n\t.protect_check = str9x_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/str9xpec.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/arm7_9_common.h>\n\n/* ISC commands */\n\n#define ISC_IDCODE\t\t\t\t0xFE\n#define ISC_MFG_READ\t\t\t0x4C\n#define ISC_CONFIGURATION\t\t0x07\n#define ISC_ENABLE\t\t\t\t0x0C\n#define ISC_DISABLE\t\t\t\t0x0F\n#define ISC_NOOP\t\t\t\t0x10\n#define ISC_ADDRESS_SHIFT\t\t0x11\n#define ISC_CLR_STATUS\t\t\t0x13\n#define ISC_PROGRAM\t\t\t\t0x20\n#define ISC_PROGRAM_SECURITY\t0x22\n#define ISC_PROGRAM_UC\t\t\t0x23\n#define ISC_ERASE\t\t\t\t0x30\n#define ISC_READ\t\t\t\t0x50\n#define ISC_BLANK_CHECK\t\t\t0x60\n\n/* ISC_DEFAULT bit definitions */\n\n#define ISC_STATUS_SECURITY\t\t0x40\n#define ISC_STATUS_INT_ERROR\t0x30\n#define ISC_STATUS_MODE\t\t\t0x08\n#define ISC_STATUS_BUSY\t\t\t0x04\n#define ISC_STATUS_ERROR\t\t0x03\n\n/* Option bytes definitions */\n\n#define STR9XPEC_OPT_CSMAPBIT\t\t48\n#define STR9XPEC_OPT_LVDTHRESBIT\t49\n#define STR9XPEC_OPT_LVDSELBIT\t\t50\n#define STR9XPEC_OPT_LVDWARNBIT\t\t51\n#define STR9XPEC_OPT_OTPBIT\t\t\t63\n\nenum str9xpec_status_codes {\n\tSTR9XPEC_INVALID_COMMAND = 1,\n\tSTR9XPEC_ISC_SUCCESS = 2,\n\tSTR9XPEC_ISC_DISABLED = 3,\n\tSTR9XPEC_ISC_INTFAIL = 32,\n};\n\nstruct str9xpec_flash_controller {\n\tstruct jtag_tap *tap;\n\tuint32_t *sector_bits;\n\tint chain_pos;\n\tint isc_enable;\n\tuint8_t options[8];\n};\n\nstatic int str9xpec_erase_area(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last);\nstatic int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);\nstatic int str9xpec_write_options(struct flash_bank *bank);\n\nstatic int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)\n{\n\tif (!tap)\n\t\treturn ERROR_TARGET_INVALID;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\t\tstruct scan_field field;\n\n\t\tfield.num_bits = tap->ir_length;\n\t\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\t\tfield.out_value = t;\n\t\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_ir_scan(tap, &field, end_state);\n\n\t\tfree(t);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic uint8_t str9xpec_isc_status(struct jtag_tap *tap)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\n\tif (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)\n\t\treturn ISC_STATUS_ERROR;\n\n\tfield.num_bits = 8;\n\tfield.out_value = NULL;\n\tfield.in_value = &status;\n\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tLOG_DEBUG(\"status: 0x%2.2x\", status);\n\n\tif (status & ISC_STATUS_SECURITY)\n\t\tLOG_INFO(\"Device Security Bit Set\");\n\n\treturn status;\n}\n\nstatic int str9xpec_isc_enable(struct flash_bank *bank)\n{\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\tif (str9xpec_info->isc_enable)\n\t\treturn ERROR_OK;\n\n\t/* enter isc mode */\n\tif (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)\n\t\treturn ERROR_TARGET_INVALID;\n\n\t/* check ISC status */\n\tstatus = str9xpec_isc_status(tap);\n\tif (status & ISC_STATUS_MODE) {\n\t\t/* we have entered isc mode */\n\t\tstr9xpec_info->isc_enable = 1;\n\t\tLOG_DEBUG(\"ISC_MODE Enabled\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_isc_disable(struct flash_bank *bank)\n{\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ERROR_OK;\n\n\tif (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)\n\t\treturn ERROR_TARGET_INVALID;\n\n\t/* delay to handle aborts */\n\tjtag_add_sleep(50);\n\n\t/* check ISC status */\n\tstatus = str9xpec_isc_status(tap);\n\tif (!(status & ISC_STATUS_MODE)) {\n\t\t/* we have left isc mode */\n\t\tstr9xpec_info->isc_enable = 0;\n\t\tLOG_DEBUG(\"ISC_MODE Disabled\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_read_config(struct flash_bank *bank)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\tLOG_DEBUG(\"ISC_CONFIGURATION\");\n\n\t/* execute ISC_CONFIGURATION command */\n\tstr9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);\n\n\tfield.num_bits = 64;\n\tfield.out_value = NULL;\n\tfield.in_value = str9xpec_info->options;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tstatus = str9xpec_isc_status(tap);\n\n\treturn status;\n}\n\nstatic int str9xpec_build_block_list(struct flash_bank *bank)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\tint i;\n\tunsigned int num_sectors;\n\tint b0_sectors = 0, b1_sectors = 0;\n\tuint32_t offset = 0;\n\tint b1_size = 0x2000;\n\n\tswitch (bank->size) {\n\t\tcase (256 * 1024):\n\t\t\tb0_sectors = 4;\n\t\t\tbreak;\n\t\tcase (512 * 1024):\n\t\t\tb0_sectors = 8;\n\t\t\tbreak;\n\t\tcase (1024 * 1024):\n\t\t\tb0_sectors = 16;\n\t\t\tbreak;\n\t\tcase (2048 * 1024):\n\t\t\tb0_sectors = 32;\n\t\t\tbreak;\n\t\tcase (128 * 1024):\n\t\t\tb1_size = 0x4000;\n\t\t\tb1_sectors = 8;\n\t\t\tbreak;\n\t\tcase (32 * 1024):\n\t\t\tb1_sectors = 4;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown bank->size encountered\");\n\t\t\texit(-1);\n\t}\n\n\tnum_sectors = b0_sectors + b1_sectors;\n\n\tbank->num_sectors = num_sectors;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);\n\tstr9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);\n\n\tnum_sectors = 0;\n\n\tfor (i = 0; i < b0_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = offset;\n\t\tbank->sectors[num_sectors].size = 0x10000;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\tbank->sectors[num_sectors].is_protected = 1;\n\t\tstr9xpec_info->sector_bits[num_sectors++] = i;\n\t}\n\n\tfor (i = 0; i < b1_sectors; i++) {\n\t\tbank->sectors[num_sectors].offset = offset;\n\t\tbank->sectors[num_sectors].size = b1_size;\n\t\toffset += bank->sectors[i].size;\n\t\tbank->sectors[num_sectors].is_erased = -1;\n\t\tbank->sectors[num_sectors].is_protected = 1;\n\t\tstr9xpec_info->sector_bits[num_sectors++] = i + 32;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* flash bank str9x <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info;\n\tstruct arm *arm = NULL;\n\tstruct arm7_9_common *arm7_9 = NULL;\n\tstruct arm_jtag *jtag_info = NULL;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstr9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));\n\tbank->driver_priv = str9xpec_info;\n\n\t/* REVISIT verify that the jtag position of flash controller is\n\t * right after *THIS* core, which must be a STR9xx core ...\n\t */\n\tarm = bank->target->arch_info;\n\tarm7_9 = arm->arch_info;\n\tjtag_info = &arm7_9->jtag_info;\n\n\t/* The core is the next tap after the flash controller in the chain */\n\tstr9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);\n\tstr9xpec_info->isc_enable = 0;\n\n\tstr9xpec_build_block_list(bank);\n\n\t/* clear option byte register */\n\tbuf_set_u32(str9xpec_info->options, 0, 64, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_blank_check(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tuint8_t *buffer = NULL;\n\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\tif (!str9xpec_info->isc_enable)\n\t\tstr9xpec_isc_enable(bank);\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tbuffer = calloc(DIV_ROUND_UP(64, 8), 1);\n\n\tLOG_DEBUG(\"blank check: first_bank: %u, last_bank: %u\", first, last);\n\n\tfor (unsigned int i = first; i <= last; i++)\n\t\tbuf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);\n\n\t/* execute ISC_BLANK_CHECK command */\n\tstr9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);\n\n\tfield.num_bits = 64;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_sleep(40000);\n\n\t/* read blank check result */\n\tfield.num_bits = 64;\n\tfield.out_value = NULL;\n\tfield.in_value = buffer;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);\n\tjtag_execute_queue();\n\n\tstatus = str9xpec_isc_status(tap);\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tif (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))\n\t\t\tbank->sectors[i].is_erased = 0;\n\t\telse\n\t\t\tbank->sectors[i].is_erased = 1;\n\t}\n\n\tfree(buffer);\n\n\tstr9xpec_isc_disable(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_protect_check(struct flash_bank *bank)\n{\n\tuint8_t status;\n\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\tstatus = str9xpec_read_config(bank);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))\n\t\t\tbank->sectors[i].is_protected = 1;\n\t\telse\n\t\t\tbank->sectors[i].is_protected = 0;\n\t}\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_erase_area(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tuint8_t *buffer = NULL;\n\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\tif (!str9xpec_info->isc_enable)\n\t\tstr9xpec_isc_enable(bank);\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ISC_STATUS_ERROR;\n\n\tbuffer = calloc(DIV_ROUND_UP(64, 8), 1);\n\n\tLOG_DEBUG(\"erase: first_bank: %u, last_bank: %u\", first, last);\n\n\t/* last bank: 0xFF signals a full erase (unlock complete device) */\n\t/* last bank: 0xFE signals a option byte erase */\n\tif (last == 0xFF) {\n\t\tfor (unsigned int i = 0; i < 64; i++)\n\t\t\tbuf_set_u32(buffer, i, 1, 1);\n\t} else if (last == 0xFE)\n\t\tbuf_set_u32(buffer, 49, 1, 1);\n\telse {\n\t\tfor (unsigned int i = first; i <= last; i++)\n\t\t\tbuf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);\n\t}\n\n\tLOG_DEBUG(\"ISC_ERASE\");\n\n\t/* execute ISC_ERASE command */\n\tstr9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);\n\n\tfield.num_bits = 64;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tjtag_add_sleep(10);\n\n\t/* wait for erase completion */\n\twhile (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))\n\t\talive_sleep(1);\n\n\tfree(buffer);\n\n\tstr9xpec_isc_disable(bank);\n\n\treturn status;\n}\n\nstatic int str9xpec_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint status;\n\n\tstatus = str9xpec_erase_area(bank, first, last);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_lock_device(struct flash_bank *bank)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tstr9xpec_info = bank->driver_priv;\n\ttap = str9xpec_info->tap;\n\n\tif (!str9xpec_info->isc_enable)\n\t\tstr9xpec_isc_enable(bank);\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ISC_STATUS_ERROR;\n\n\t/* set security address */\n\tstr9xpec_set_address(bank, 0x80);\n\n\t/* execute ISC_PROGRAM command */\n\tstr9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);\n\n\tstr9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);\n\n\tdo {\n\t\tfield.num_bits = 8;\n\t\tfield.out_value = NULL;\n\t\tfield.in_value = &status;\n\n\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\t\tjtag_execute_queue();\n\n\t} while (!(status & ISC_STATUS_BUSY));\n\n\tstr9xpec_isc_disable(bank);\n\n\treturn status;\n}\n\nstatic int str9xpec_unlock_device(struct flash_bank *bank)\n{\n\tuint8_t status;\n\n\tstatus = str9xpec_erase_area(bank, 0, 255);\n\n\treturn status;\n}\n\nstatic int str9xpec_protect(struct flash_bank *bank, int set,\n\t\tunsigned int first, unsigned int last)\n{\n\tuint8_t status;\n\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\tstatus = str9xpec_read_config(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tLOG_DEBUG(\"protect: first_bank: %u, last_bank: %u\", first, last);\n\n\t/* last bank: 0xFF signals a full device protect */\n\tif (last == 0xFF) {\n\t\tif (set)\n\t\t\tstatus = str9xpec_lock_device(bank);\n\t\telse {\n\t\t\t/* perform full erase to unlock device */\n\t\t\tstatus = str9xpec_unlock_device(bank);\n\t\t}\n\t} else {\n\t\tfor (unsigned int i = first; i <= last; i++) {\n\t\t\tif (set)\n\t\t\t\tbuf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);\n\t\t\telse\n\t\t\t\tbuf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);\n\t\t}\n\n\t\tstatus = str9xpec_write_options(bank);\n\t}\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)\n{\n\tstruct jtag_tap *tap;\n\tstruct scan_field field;\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\n\ttap = str9xpec_info->tap;\n\n\t/* set flash controller address */\n\tstr9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);\n\n\tfield.num_bits = 8;\n\tfield.out_value = &sector;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;\n\tuint32_t dwords_remaining = (count / 8);\n\tuint32_t bytes_remaining = (count & 0x00000007);\n\tuint32_t bytes_written = 0;\n\tuint8_t status;\n\tuint32_t check_address = offset;\n\tstruct jtag_tap *tap;\n\tstruct scan_field field;\n\tuint8_t *scanbuf;\n\tunsigned int first_sector = 0;\n\tunsigned int last_sector = 0;\n\n\ttap = str9xpec_info->tap;\n\n\tif (!str9xpec_info->isc_enable)\n\t\tstr9xpec_isc_enable(bank);\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tif (offset & 0x7) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required 8-byte alignment\", offset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tuint32_t sec_start = bank->sectors[i].offset;\n\t\tuint32_t sec_end = sec_start + bank->sectors[i].size;\n\n\t\t/* check if destination falls within the current sector */\n\t\tif ((check_address >= sec_start) && (check_address < sec_end)) {\n\t\t\t/* check if destination ends in the current sector */\n\t\t\tif (offset + count < sec_end)\n\t\t\t\tcheck_address = offset + count;\n\t\t\telse\n\t\t\t\tcheck_address = sec_end;\n\t\t}\n\n\t\tif ((offset >= sec_start) && (offset < sec_end))\n\t\t\tfirst_sector = i;\n\n\t\tif ((offset + count >= sec_start) && (offset + count < sec_end))\n\t\t\tlast_sector = i;\n\t}\n\n\tif (check_address != offset + count)\n\t\treturn ERROR_FLASH_DST_OUT_OF_BANK;\n\n\tLOG_DEBUG(\"first_sector: %i, last_sector: %i\", first_sector, last_sector);\n\n\tscanbuf = calloc(DIV_ROUND_UP(64, 8), 1);\n\n\tLOG_DEBUG(\"ISC_PROGRAM\");\n\n\tfor (unsigned int i = first_sector; i <= last_sector; i++) {\n\t\tstr9xpec_set_address(bank, str9xpec_info->sector_bits[i]);\n\n\t\tdwords_remaining = dwords_remaining < (bank->sectors[i].size/8)\n\t\t\t\t? dwords_remaining : (bank->sectors[i].size/8);\n\n\t\twhile (dwords_remaining > 0) {\n\t\t\tstr9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);\n\n\t\t\tfield.num_bits = 64;\n\t\t\tfield.out_value = (buffer + bytes_written);\n\t\t\tfield.in_value = NULL;\n\n\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\t\t\t/* small delay before polling */\n\t\t\tjtag_add_sleep(50);\n\n\t\t\tstr9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);\n\n\t\t\tdo {\n\t\t\t\tfield.num_bits = 8;\n\t\t\t\tfield.out_value = NULL;\n\t\t\t\tfield.in_value = scanbuf;\n\n\t\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);\n\t\t\t\tjtag_execute_queue();\n\n\t\t\t\tstatus = buf_get_u32(scanbuf, 0, 8);\n\n\t\t\t} while (!(status & ISC_STATUS_BUSY));\n\n\t\t\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\t\t/* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED; */\n\n\t\t\tdwords_remaining--;\n\t\t\tbytes_written += 8;\n\t\t}\n\t}\n\n\tif (bytes_remaining) {\n\t\tuint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\n\n\t\t/* copy the last remaining bytes into the write buffer */\n\t\tmemcpy(last_dword, buffer+bytes_written, bytes_remaining);\n\n\t\tstr9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);\n\n\t\tfield.num_bits = 64;\n\t\tfield.out_value = last_dword;\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\t\t/* small delay before polling */\n\t\tjtag_add_sleep(50);\n\n\t\tstr9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);\n\n\t\tdo {\n\t\t\tfield.num_bits = 8;\n\t\t\tfield.out_value = NULL;\n\t\t\tfield.in_value = scanbuf;\n\n\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);\n\t\t\tjtag_execute_queue();\n\n\t\t\tstatus = buf_get_u32(scanbuf, 0, 8);\n\n\t\t} while (!(status & ISC_STATUS_BUSY));\n\n\t\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t\t/* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED; */\n\t}\n\n\tfree(scanbuf);\n\n\tstr9xpec_isc_disable(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_part_id_command)\n{\n\tstruct scan_field field;\n\tuint8_t *buffer = NULL;\n\tstruct jtag_tap *tap;\n\tuint32_t idcode;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\ttap = str9xpec_info->tap;\n\n\tbuffer = calloc(DIV_ROUND_UP(32, 8), 1);\n\n\tstr9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);\n\n\tfield.num_bits = 32;\n\tfield.out_value = NULL;\n\tfield.in_value = buffer;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tidcode = buf_get_u32(buffer, 0, 32);\n\n\tcommand_print(CMD, \"str9xpec part id: 0x%8.8\" PRIx32 \"\", idcode);\n\n\tfree(buffer);\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_erase_check(struct flash_bank *bank)\n{\n\treturn str9xpec_blank_check(bank, 0, bank->num_sectors - 1);\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_read_command)\n{\n\tuint8_t status;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\tstatus = str9xpec_read_config(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* boot bank */\n\tif (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))\n\t\tcommand_print(CMD, \"CS Map: bank1\");\n\telse\n\t\tcommand_print(CMD, \"CS Map: bank0\");\n\n\t/* OTP lock */\n\tif (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))\n\t\tcommand_print(CMD, \"OTP Lock: OTP Locked\");\n\telse\n\t\tcommand_print(CMD, \"OTP Lock: OTP Unlocked\");\n\n\t/* LVD Threshold */\n\tif (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))\n\t\tcommand_print(CMD, \"LVD Threshold: 2.7v\");\n\telse\n\t\tcommand_print(CMD, \"LVD Threshold: 2.4v\");\n\n\t/* LVD reset warning */\n\tif (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))\n\t\tcommand_print(CMD, \"LVD Reset Warning: VDD or VDDQ Inputs\");\n\telse\n\t\tcommand_print(CMD, \"LVD Reset Warning: VDD Input Only\");\n\n\t/* LVD reset select */\n\tif (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))\n\t\tcommand_print(CMD, \"LVD Reset Selection: VDD or VDDQ Inputs\");\n\telse\n\t\tcommand_print(CMD, \"LVD Reset Selection: VDD Input Only\");\n\n\treturn ERROR_OK;\n}\n\nstatic int str9xpec_write_options(struct flash_bank *bank)\n{\n\tstruct scan_field field;\n\tuint8_t status;\n\tstruct jtag_tap *tap;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tstr9xpec_info = bank->driver_priv;\n\ttap = str9xpec_info->tap;\n\n\t/* erase config options first */\n\tstatus = str9xpec_erase_area(bank, 0xFE, 0xFE);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn status;\n\n\tif (!str9xpec_info->isc_enable)\n\t\tstr9xpec_isc_enable(bank);\n\n\tif (!str9xpec_info->isc_enable)\n\t\treturn ISC_STATUS_ERROR;\n\n\t/* according to data 64th bit has to be set */\n\tbuf_set_u32(str9xpec_info->options, 63, 1, 1);\n\n\t/* set option byte address */\n\tstr9xpec_set_address(bank, 0x50);\n\n\t/* execute ISC_PROGRAM command */\n\tstr9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);\n\n\tfield.num_bits = 64;\n\tfield.out_value = str9xpec_info->options;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\t/* small delay before polling */\n\tjtag_add_sleep(50);\n\n\tstr9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);\n\n\tdo {\n\t\tfield.num_bits = 8;\n\t\tfield.out_value = NULL;\n\t\tfield.in_value = &status;\n\n\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);\n\t\tjtag_execute_queue();\n\n\t} while (!(status & ISC_STATUS_BUSY));\n\n\tstr9xpec_isc_disable(bank);\n\n\treturn status;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_write_command)\n{\n\tuint8_t status;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstatus = str9xpec_write_options(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tcommand_print(CMD, \"str9xpec write options complete.\\n\"\n\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\"for the new settings to take effect.\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\tif (strcmp(CMD_ARGV[1], \"bank1\") == 0)\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);\n\telse\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\tif (strcmp(CMD_ARGV[1], \"2.7v\") == 0)\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);\n\telse\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\tif (strcmp(CMD_ARGV[1], \"vdd_vddq\") == 0)\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);\n\telse\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)\n{\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\tif (strcmp(CMD_ARGV[1], \"vdd_vddq\") == 0)\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);\n\telse\n\t\tbuf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_lock_command)\n{\n\tuint8_t status;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstatus = str9xpec_lock_device(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_unlock_command)\n{\n\tuint8_t status;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstatus = str9xpec_unlock_device(bank);\n\n\tif ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tcommand_print(CMD, \"str9xpec unlocked.\\n\"\n\t\t\t\"INFO: a reset or power cycle is required \"\n\t\t\t\"for the new settings to take effect.\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)\n{\n\tstruct jtag_tap *tap0;\n\tstruct jtag_tap *tap1;\n\tstruct jtag_tap *tap2;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\n\t/* remove arm core from chain - enter turbo mode */\n\ttap0 = str9xpec_info->tap;\n\tif (!tap0) {\n\t\t/* things are *WRONG* */\n\t\tcommand_print(CMD, \"**STR9FLASH** (tap0) invalid chain?\");\n\t\treturn ERROR_FAIL;\n\t}\n\ttap1 = tap0->next_tap;\n\tif (!tap1) {\n\t\t/* things are *WRONG* */\n\t\tcommand_print(CMD, \"**STR9FLASH** (tap1) invalid chain?\");\n\t\treturn ERROR_FAIL;\n\t}\n\ttap2 = tap1->next_tap;\n\tif (!tap2) {\n\t\t/* things are *WRONG* */\n\t\tcommand_print(CMD, \"**STR9FLASH** (tap2) invalid chain?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* enable turbo mode - TURBO-PROG-ENABLE */\n\tstr9xpec_set_instr(tap2, 0xD, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* modify scan chain - str9 core has been removed */\n\ttap1->enabled = 0;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)\n{\n\tstruct jtag_tap *tap;\n\tstruct str9xpec_flash_controller *str9xpec_info = NULL;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstr9xpec_info = bank->driver_priv;\n\ttap = str9xpec_info->tap;\n\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\t/* exit turbo mode via RESET */\n\tstr9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);\n\tjtag_add_tlr();\n\tjtag_execute_queue();\n\n\t/* restore previous scan chain */\n\tif (tap->next_tap)\n\t\ttap->next_tap->enabled = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration str9xpec_config_command_handlers[] = {\n\t{\n\t\t.name = \"enable_turbo\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_enable_turbo_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"enable str9xpec turbo mode\",\n\t},\n\t{\n\t\t.name = \"disable_turbo\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_disable_turbo_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"disable str9xpec turbo mode\",\n\t},\n\t{\n\t\t.name = \"options_cmap\",\n\t\t.usage = \"<bank> <bank0 | bank1>\",\n\t\t.handler = str9xpec_handle_flash_options_cmap_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure str9xpec boot sector\",\n\t},\n\t{\n\t\t.name = \"options_lvdthd\",\n\t\t.usage = \"<bank> <2.4v | 2.7v>\",\n\t\t.handler = str9xpec_handle_flash_options_lvdthd_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure str9xpec lvd threshold\",\n\t},\n\t{\n\t\t.name = \"options_lvdsel\",\n\t\t.usage = \"<bank> <vdd | vdd_vddq>\",\n\t\t.handler = str9xpec_handle_flash_options_lvdsel_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure str9xpec lvd selection\",\n\t},\n\t{\n\t\t.name = \"options_lvdwarn\",\n\t\t.usage = \"<bank> <vdd | vdd_vddq>\",\n\t\t.handler = str9xpec_handle_flash_options_lvdwarn_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure str9xpec lvd warning\",\n\t},\n\t{\n\t\t.name = \"options_read\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_options_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read str9xpec options\",\n\t},\n\t{\n\t\t.name = \"options_write\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_options_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write str9xpec options\",\n\t},\n\t{\n\t\t.name = \"lock\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_lock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"lock str9xpec device\",\n\t},\n\t{\n\t\t.name = \"unlock\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_flash_unlock_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"unlock str9xpec device\",\n\t},\n\t{\n\t\t.name = \"part_id\",\n\t\t.usage = \"<bank>\",\n\t\t.handler = str9xpec_handle_part_id_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"print part id of str9xpec flash bank\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration str9xpec_command_handlers[] = {\n\t{\n\t\t.name = \"str9xpec\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"str9xpec flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = str9xpec_config_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver str9xpec_flash = {\n\t.name = \"str9xpec\",\n\t.commands = str9xpec_command_handlers,\n\t.flash_bank_command = str9xpec_flash_bank_command,\n\t.erase = str9xpec_erase,\n\t.protect = str9xpec_protect,\n\t.write = str9xpec_write,\n\t.read = default_flash_read,\n\t.probe = str9xpec_probe,\n\t.auto_probe = str9xpec_probe,\n\t.erase_check = str9xpec_erase_check,\n\t.protect_check = str9xpec_protect_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/swm050.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io>                    *\n *   Copyright (C) 2019 Caleb Szalacinski <contact@skiboy.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <target/image.h>\n\n#define SWM050_DELAY\t\t100\n\n#define SWM050_FLASH_PAGE_SIZE\t0x200\n#define SWM050_FLASH_PAGES\t16\n\n#define SWM050_CPU_ID\t\t0xE000ED00\n#define SWM050_CPU_ID_VAL\t0x410CC200\n\n#define SWM050_FLASH_REG1\t0x1F000000\n#define SWM050_FLASH_REG2\t0x1F000038\n#define SWM050_FLASH_KEY\t0xAAAAAAAA\n\n#define SWM050_SYSCTL_CFG_0\t0x400F0000\n#define SWM050_SYSCTL_DBLF\t0x400F0008\n\nstatic int swm050_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Perform erase */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x4);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int curr_page = first; curr_page <= last; curr_page++) {\n\t\tuint32_t curr_addr = bank->base + (SWM050_FLASH_PAGE_SIZE * curr_page);\n\t\t/* Perform write */\n\t\tretval = target_write_u32(target, curr_addr, SWM050_FLASH_KEY);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\talive_sleep(SWM050_DELAY);\n\t}\n\n\t/* Close flash interface */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int swm050_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\tretval = ERROR_TARGET_NOT_HALTED;\n\t\treturn retval;\n\t}\n\n\t/* Perform write */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_memory(target, bank->base + offset, 4, count/4, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Close flash interface */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int swm050_probe(struct flash_bank *bank)\n{\n\treturn ERROR_OK;\n}\n\nstatic int swm050_mass_erase(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Perform mass erase */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x6);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, SWM050_FLASH_REG2, 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, 0x0, SWM050_FLASH_KEY);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\talive_sleep(SWM050_DELAY);\n\n\t/* Close flash interface */\n\tretval = target_write_u32(target, SWM050_FLASH_REG1, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(swm050_handle_mass_erase_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swm050_mass_erase(bank);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"swm050 mass erase complete\");\n\telse\n\t\tcommand_print(CMD, \"swm050 mass erase failed\");\n\n\treturn retval;\n}\n\nFLASH_BANK_COMMAND_HANDLER(swm050_flash_bank_command)\n{\n\tfree(bank->sectors);\n\tbank->write_start_alignment = 4;\n\tbank->write_end_alignment = 4;\n\tbank->size = SWM050_FLASH_PAGE_SIZE * SWM050_FLASH_PAGES;\n\n\tbank->num_sectors = SWM050_FLASH_PAGES;\n\tbank->sectors = alloc_block_array(0, SWM050_FLASH_PAGE_SIZE, SWM050_FLASH_PAGES);\n\tif (!bank->sectors)\n\t\treturn ERROR_FAIL;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration swm050_exec_command_handlers[] = {\n\t{\n\t\t.name = \"mass_erase\",\n\t\t.handler = swm050_handle_mass_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Erase entire flash device.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration swm050_command_handlers[] = {\n\t{\n\t\t.name = \"swm050\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"swm050 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = swm050_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver swm050_flash = {\n\t.name = \"swm050\",\n\t.commands = swm050_command_handlers,\n\t.flash_bank_command = swm050_flash_bank_command,\n\t.erase = swm050_erase,\n\t.write = swm050_write,\n\t.read = default_flash_read,\n\t.probe = swm050_probe,\n\t.auto_probe = swm050_probe,\n\t.erase_check = default_flash_blank_check,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/tcl.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007,2008 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n *   Copyright (C) 2017-2018 Tomas Vanek <vanekt@fbl.cz>                   *\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"imp.h\"\n#include <helper/time_support.h>\n#include <target/image.h>\n\n/**\n * @file\n * Implements Tcl commands used to access NOR flash facilities.\n */\n\nCOMMAND_HELPER(flash_command_get_bank_probe_optional, unsigned int name_index,\n\t       struct flash_bank **bank, bool do_probe)\n{\n\tconst char *name = CMD_ARGV[name_index];\n\tint retval;\n\tif (do_probe) {\n\t\tretval = get_flash_bank_by_name(name, bank);\n\t} else {\n\t\t*bank  = get_flash_bank_by_name_noprobe(name);\n\t\tretval = ERROR_OK;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (*bank)\n\t\treturn ERROR_OK;\n\n\tunsigned bank_num;\n\tCOMMAND_PARSE_NUMBER(uint, name, bank_num);\n\n\tif (do_probe) {\n\t\treturn get_flash_bank_by_num(bank_num, bank);\n\t} else {\n\t\t*bank  = get_flash_bank_by_num_noprobe(bank_num);\n\t\tretval = (bank) ? ERROR_OK : ERROR_FAIL;\n\t\treturn retval;\n\t}\n}\n\nCOMMAND_HELPER(flash_command_get_bank, unsigned name_index,\n\tstruct flash_bank **bank)\n{\n\treturn CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional,\n\t\t\t\t    name_index, bank, true);\n}\n\nCOMMAND_HANDLER(handle_flash_info_command)\n{\n\tstruct flash_bank *p;\n\tint j = 0;\n\tint retval;\n\tbool show_sectors = false;\n\tbool prot_block_available;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2) {\n\t\tif (strcmp(\"sectors\", CMD_ARGV[1]) == 0)\n\t\t\tshow_sectors = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (p) {\n\t\tint num_blocks;\n\t\tstruct flash_sector *block_array;\n\n\t\t/* attempt auto probe */\n\t\tretval = p->driver->auto_probe(p);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* If the driver does not implement protection, we show the default\n\t\t * state of is_protected array - usually protection state unknown */\n\t\tif (!p->driver->protect_check) {\n\t\t\tretval = ERROR_FLASH_OPER_UNSUPPORTED;\n\t\t} else {\n\t\t\t/* We must query the hardware to avoid printing stale information! */\n\t\t\tretval = p->driver->protect_check(p);\n\t\t\tif (retval != ERROR_OK && retval != ERROR_FLASH_OPER_UNSUPPORTED)\n\t\t\t\treturn retval;\n\t\t}\n\t\tif (retval == ERROR_FLASH_OPER_UNSUPPORTED)\n\t\t\tLOG_INFO(\"Flash protection check is not implemented.\");\n\n\t\tcommand_print(CMD,\n\t\t\t\"#%u : %s at \" TARGET_ADDR_FMT \", size 0x%8.8\" PRIx32\n\t\t\t\", buswidth %u, chipwidth %u\",\n\t\t\tp->bank_number,\n\t\t\tp->driver->name,\n\t\t\tp->base,\n\t\t\tp->size,\n\t\t\tp->bus_width,\n\t\t\tp->chip_width);\n\n\t\tprot_block_available = p->num_prot_blocks && p->prot_blocks;\n\t\tif (!show_sectors && prot_block_available) {\n\t\t\tblock_array = p->prot_blocks;\n\t\t\tnum_blocks = p->num_prot_blocks;\n\t\t} else {\n\t\t\tblock_array = p->sectors;\n\t\t\tnum_blocks = p->num_sectors;\n\t\t}\n\n\t\tfor (j = 0; j < num_blocks; j++) {\n\t\t\tchar *protect_state = \"\";\n\n\t\t\tif (block_array[j].is_protected == 0)\n\t\t\t\tprotect_state = \"not protected\";\n\t\t\telse if (block_array[j].is_protected == 1)\n\t\t\t\tprotect_state = \"protected\";\n\t\t\telse if (!show_sectors || !prot_block_available)\n\t\t\t\tprotect_state = \"protection state unknown\";\n\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"\\t#%3i: 0x%8.8\" PRIx32 \" (0x%\" PRIx32 \" %\" PRIu32 \"kB) %s\",\n\t\t\t\tj,\n\t\t\t\tblock_array[j].offset,\n\t\t\t\tblock_array[j].size,\n\t\t\t\tblock_array[j].size >> 10,\n\t\t\t\tprotect_state);\n\t\t}\n\n\t\tif (p->driver->info) {\n\t\t\t/* Let the flash driver print extra custom info */\n\t\t\tretval = p->driver->info(p, CMD);\n\t\t\tcommand_print_sameline(CMD, \"\\n\");\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"error retrieving flash info\");\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_probe_command)\n{\n\tstruct flash_bank *p;\n\tint retval;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank_probe_optional, 0, &p, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (p) {\n\t\tretval = p->driver->probe(p);\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"flash '%s' found at \" TARGET_ADDR_FMT,\n\t\t\t\tp->driver->name,\n\t\t\t\tp->base);\n\t} else {\n\t\tcommand_print(CMD, \"flash bank '#%s' is out of bounds\", CMD_ARGV[0]);\n\t\tretval = ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_erase_check_command)\n{\n\tbool blank = true;\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *p;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = p->driver->erase_check(p);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"successfully checked erase state\");\n\telse {\n\t\tcommand_print(CMD,\n\t\t\t\"unknown error when checking erase state of flash bank #%s at \"\n\t\t\tTARGET_ADDR_FMT,\n\t\t\tCMD_ARGV[0],\n\t\t\tp->base);\n\t}\n\n\tfor (unsigned int j = 0; j < p->num_sectors; j++) {\n\t\tchar *erase_state;\n\n\t\tif (p->sectors[j].is_erased == 0)\n\t\t\terase_state = \"not erased\";\n\t\telse if (p->sectors[j].is_erased == 1)\n\t\t\tcontinue;\n\t\telse\n\t\t\terase_state = \"erase state unknown\";\n\n\t\tblank = false;\n\t\tcommand_print(CMD,\n\t\t\t\"\\t#%3i: 0x%8.8\" PRIx32 \" (0x%\" PRIx32 \" %\" PRIu32 \"kB) %s\",\n\t\t\tj,\n\t\t\tp->sectors[j].offset,\n\t\t\tp->sectors[j].size,\n\t\t\tp->sectors[j].size >> 10,\n\t\t\terase_state);\n\t}\n\n\tif (blank)\n\t\tcommand_print(CMD, \"\\tBank is erased\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_erase_address_command)\n{\n\tstruct flash_bank *p;\n\tint retval = ERROR_OK;\n\ttarget_addr_t address;\n\tuint32_t length;\n\tbool do_pad = false;\n\tbool do_unlock = false;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\twhile (CMD_ARGC >= 3) {\n\t\t/* Optionally pad out the address range to block/sector\n\t\t * boundaries.  We can't know if there's data in that part\n\t\t * of the flash; only do padding if we're told to.\n\t\t */\n\t\tif (strcmp(\"pad\", CMD_ARGV[0]) == 0)\n\t\t\tdo_pad = true;\n\t\telse if (strcmp(\"unlock\", CMD_ARGV[0]) == 0)\n\t\t\tdo_unlock = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t}\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\n\tif (length <= 0) {\n\t\tcommand_print(CMD, \"Length must be >0\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = get_flash_bank_by_addr(target, address, true, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* We can't know if we did a resume + halt, in which case we no longer know the erased state\n\t **/\n\tflash_set_dirty();\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tif (do_unlock)\n\t\tretval = flash_unlock_address_range(target, address, length);\n\n\tif (retval == ERROR_OK)\n\t\tretval = flash_erase_address_range(target, do_pad, address, length);\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"erased address \" TARGET_ADDR_FMT \" (length %\" PRIu32 \")\"\n\t\t\t\" in %fs (%0.3f KiB/s)\", address, length,\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, length));\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_erase_command)\n{\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t first;\n\tuint32_t last;\n\n\tstruct flash_bank *p;\n\tint retval;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);\n\tif (strcmp(CMD_ARGV[2], \"last\") == 0)\n\t\tlast = p->num_sectors - 1;\n\telse\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);\n\n\tif (!(first <= last)) {\n\t\tcommand_print(CMD, \"ERROR: \"\n\t\t\t\"first sector must be <= last\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!(last <= (p->num_sectors - 1))) {\n\t\tcommand_print(CMD, \"ERROR: \"\n\t\t\t\"last sector must be <= %u\",\n\t\t\tp->num_sectors - 1);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tretval = flash_driver_erase(p, first, last);\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"erased sectors %\" PRIu32 \" \"\n\t\t\t\"through %\" PRIu32 \" on flash bank %u \"\n\t\t\t\"in %fs\", first, last, p->bank_number, duration_elapsed(&bench));\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_protect_command)\n{\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t first;\n\tuint32_t last;\n\n\tstruct flash_bank *p;\n\tint retval;\n\tint num_blocks;\n\n\tretval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (p->num_prot_blocks)\n\t\tnum_blocks = p->num_prot_blocks;\n\telse\n\t\tnum_blocks = p->num_sectors;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], first);\n\tif (strcmp(CMD_ARGV[2], \"last\") == 0)\n\t\tlast = num_blocks - 1;\n\telse\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], last);\n\n\tbool set;\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[3], set);\n\n\tif (!(first <= last)) {\n\t\tcommand_print(CMD, \"ERROR: \"\n\t\t\t\"first %s must be <= last\",\n\t\t\t(p->num_prot_blocks) ? \"block\" : \"sector\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!(last <= (uint32_t)(num_blocks - 1))) {\n\t\tcommand_print(CMD, \"ERROR: \"\n\t\t\t\"last %s must be <= %d\",\n\t\t\t(p->num_prot_blocks) ? \"block\" : \"sector\",\n\t\t\tnum_blocks - 1);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = flash_driver_protect(p, set, first, last);\n\tif (retval == ERROR_OK) {\n\t\tcommand_print(CMD, \"%s protection for %s %\" PRIu32\n\t\t\t\" through %\" PRIu32 \" on flash bank %d\",\n\t\t\t(set) ? \"set\" : \"cleared\",\n\t\t\t(p->num_prot_blocks) ? \"blocks\" : \"sectors\",\n\t\t\tfirst, last, p->bank_number);\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_write_image_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tstruct image image;\n\tuint32_t written;\n\n\tint retval;\n\n\t/* flash auto-erase is disabled by default*/\n\tint auto_erase = 0;\n\tbool auto_unlock = false;\n\n\twhile (CMD_ARGC) {\n\t\tif (strcmp(CMD_ARGV[0], \"erase\") == 0) {\n\t\t\tauto_erase = 1;\n\t\t\tCMD_ARGV++;\n\t\t\tCMD_ARGC--;\n\t\t\tcommand_print(CMD, \"auto erase enabled\");\n\t\t} else if (strcmp(CMD_ARGV[0], \"unlock\") == 0) {\n\t\t\tauto_unlock = true;\n\t\t\tCMD_ARGV++;\n\t\t\tCMD_ARGC--;\n\t\t\tcommand_print(CMD, \"auto unlock enabled\");\n\t\t} else\n\t\t\tbreak;\n\t}\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!target) {\n\t\tLOG_ERROR(\"no target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tif (CMD_ARGC >= 2) {\n\t\timage.base_address_set = true;\n\t\tCOMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);\n\t} else {\n\t\timage.base_address_set = false;\n\t\timage.base_address = 0x0;\n\t}\n\n\timage.start_address_set = false;\n\n\tretval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = flash_write_unlock_verify(target, &image, &written, auto_erase,\n\t\tauto_unlock, true, false);\n\tif (retval != ERROR_OK) {\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"wrote %\" PRIu32 \" bytes from file %s \"\n\t\t\t\"in %fs (%0.3f KiB/s)\", written, CMD_ARGV[0],\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, written));\n\t}\n\n\timage_close(&image);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_verify_image_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tstruct image image;\n\tuint32_t verified;\n\n\tint retval;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!target) {\n\t\tLOG_ERROR(\"no target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tif (CMD_ARGC >= 2) {\n\t\timage.base_address_set = 1;\n\t\tCOMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], image.base_address);\n\t} else {\n\t\timage.base_address_set = 0;\n\t\timage.base_address = 0x0;\n\t}\n\n\timage.start_address_set = 0;\n\n\tretval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = flash_write_unlock_verify(target, &image, &verified, false,\n\t\tfalse, false, true);\n\tif (retval != ERROR_OK) {\n\t\timage_close(&image);\n\t\treturn retval;\n\t}\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"verified %\" PRIu32 \" bytes from file %s \"\n\t\t\t\"in %fs (%0.3f KiB/s)\", verified, CMD_ARGV[0],\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, verified));\n\t}\n\n\timage_close(&image);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_fill_command)\n{\n\ttarget_addr_t address;\n\tuint64_t pattern;\n\tuint32_t count;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tunsigned i;\n\tuint32_t wordsize;\n\tint retval;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], pattern);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);\n\n\tstruct flash_bank *bank;\n\tretval = get_flash_bank_by_addr(target, address, true, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswitch (CMD_NAME[4]) {\n\t\tcase 'd':\n\t\t\twordsize = 8;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\twordsize = 4;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\twordsize = 2;\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\twordsize = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif ((wordsize < sizeof(pattern)) && (pattern >> (8 * wordsize) != 0)) {\n\t\tcommand_print(CMD, \"Fill pattern 0x%\" PRIx64 \" does not fit within %\" PRIu32 \"-byte word\", pattern, wordsize);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (count == 0)\n\t\treturn ERROR_OK;\n\n\tif (address + count * wordsize > bank->base + bank->size) {\n\t\tLOG_ERROR(\"Cannot cross flash bank borders\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t size_bytes = count * wordsize;\n\ttarget_addr_t aligned_start = flash_write_align_start(bank, address);\n\ttarget_addr_t end_addr = address + size_bytes - 1;\n\ttarget_addr_t aligned_end = flash_write_align_end(bank, end_addr);\n\tuint32_t aligned_size = aligned_end + 1 - aligned_start;\n\tuint32_t padding_at_start = address - aligned_start;\n\tuint32_t padding_at_end = aligned_end - end_addr;\n\n\tuint8_t *buffer = malloc(aligned_size);\n\tif (!buffer)\n\t\treturn ERROR_FAIL;\n\n\tif (padding_at_start) {\n\t\tmemset(buffer, bank->default_padded_value, padding_at_start);\n\t\tLOG_WARNING(\"Start address \" TARGET_ADDR_FMT\n\t\t\t\" breaks the required alignment of flash bank %s\",\n\t\t\taddress, bank->name);\n\t\tLOG_WARNING(\"Padding %\" PRIu32 \" bytes from \" TARGET_ADDR_FMT,\n\t\t    padding_at_start, aligned_start);\n\t}\n\n\tuint8_t *ptr = buffer + padding_at_start;\n\n\tswitch (wordsize) {\n\t\tcase 8:\n\t\t\tfor (i = 0; i < count; i++, ptr += wordsize)\n\t\t\t\ttarget_buffer_set_u64(target, ptr, pattern);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tfor (i = 0; i < count; i++, ptr += wordsize)\n\t\t\t\ttarget_buffer_set_u32(target, ptr, pattern);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tfor (i = 0; i < count; i++, ptr += wordsize)\n\t\t\t\ttarget_buffer_set_u16(target, ptr, pattern);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tmemset(ptr, pattern, count);\n\t\t\tptr += count;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: can't happen\");\n\t\t\texit(-1);\n\t}\n\n\tif (padding_at_end) {\n\t\tmemset(ptr, bank->default_padded_value, padding_at_end);\n\t\tLOG_INFO(\"Padding at \" TARGET_ADDR_FMT \" with %\" PRIu32\n\t\t\t\" bytes (bank write end alignment)\",\n\t\t\tend_addr + 1, padding_at_end);\n\t}\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tretval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = flash_driver_read(bank, buffer, address - bank->base, size_bytes);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tfor (i = 0, ptr = buffer; i < count; i++) {\n\t\tuint64_t readback = 0;\n\n\t\tswitch (wordsize) {\n\t\t\tcase 8:\n\t\t\t\treadback = target_buffer_get_u64(target, ptr);\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\treadback = target_buffer_get_u32(target, ptr);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\treadback = target_buffer_get_u16(target, ptr);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\treadback = *ptr;\n\t\t\t\tbreak;\n\t\t}\n\t\tif (readback != pattern) {\n\t\t\tLOG_ERROR(\n\t\t\t\t\"Verification error address \" TARGET_ADDR_FMT\n\t\t\t\t\", read back 0x%02\" PRIx64 \", expected 0x%02\" PRIx64,\n\t\t\t\taddress + i * wordsize, readback, pattern);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto done;\n\t\t}\n\t\tptr += wordsize;\n\t}\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"wrote %\" PRIu32 \" bytes to \" TARGET_ADDR_FMT\n\t\t\t\" in %fs (%0.3f KiB/s)\", size_bytes, address,\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, size_bytes));\n\t}\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_md_command)\n{\n\tint retval;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget_addr_t address;\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\n\tuint32_t count = 1;\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);\n\n\tunsigned int wordsize;\n\tswitch (CMD_NAME[2]) {\n\t\tcase 'w':\n\t\t\twordsize = 4;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\twordsize = 2;\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\twordsize = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (count == 0)\n\t\treturn ERROR_OK;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct flash_bank *bank;\n\tretval = get_flash_bank_by_addr(target, address, true, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t offset = address - bank->base;\n\tuint32_t sizebytes = count * wordsize;\n\tif (offset + sizebytes > bank->size) {\n\t\tcommand_print(CMD, \"Cannot cross flash bank borders\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t *buffer = calloc(count, wordsize);\n\tif (!buffer) {\n\t\tcommand_print(CMD, \"No memory for flash read buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = flash_driver_read(bank, buffer, offset, sizebytes);\n\tif (retval == ERROR_OK)\n\t\ttarget_handle_md_output(CMD, target, address, wordsize, count, buffer);\n\n\tfree(buffer);\n\n\treturn retval;\n}\n\n\nCOMMAND_HANDLER(handle_flash_write_bank_command)\n{\n\tuint32_t offset;\n\tuint8_t *buffer;\n\tsize_t length;\n\tstruct fileio *fileio;\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\toffset = 0;\n\n\tif (CMD_ARGC > 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);\n\n\tif (offset > bank->size) {\n\t\tLOG_ERROR(\"Offset 0x%8.8\" PRIx32 \" is out of range of the flash bank\",\n\t\t\toffset);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tsize_t filesize;\n\tretval = fileio_size(fileio, &filesize);\n\tif (retval != ERROR_OK) {\n\t\tfileio_close(fileio);\n\t\treturn retval;\n\t}\n\n\tlength = MIN(filesize, bank->size - offset);\n\n\tif (!length) {\n\t\tLOG_INFO(\"Nothing to write to flash bank\");\n\t\tfileio_close(fileio);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (length != filesize)\n\t\tLOG_INFO(\"File content exceeds flash bank size. Only writing the \"\n\t\t\t\"first %zu bytes of the file\", length);\n\n\ttarget_addr_t start_addr = bank->base + offset;\n\ttarget_addr_t aligned_start = flash_write_align_start(bank, start_addr);\n\ttarget_addr_t end_addr = start_addr + length - 1;\n\ttarget_addr_t aligned_end = flash_write_align_end(bank, end_addr);\n\tuint32_t aligned_size = aligned_end + 1 - aligned_start;\n\tuint32_t padding_at_start = start_addr - aligned_start;\n\tuint32_t padding_at_end = aligned_end - end_addr;\n\n\tbuffer = malloc(aligned_size);\n\tif (!buffer) {\n\t\tfileio_close(fileio);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (padding_at_start) {\n\t\tmemset(buffer, bank->default_padded_value, padding_at_start);\n\t\tLOG_WARNING(\"Start offset 0x%08\" PRIx32\n\t\t\t\" breaks the required alignment of flash bank %s\",\n\t\t\toffset, bank->name);\n\t\tLOG_WARNING(\"Padding %\" PRIu32 \" bytes from \" TARGET_ADDR_FMT,\n\t\t    padding_at_start, aligned_start);\n\t}\n\n\tuint8_t *ptr = buffer + padding_at_start;\n\tsize_t buf_cnt;\n\tif (fileio_read(fileio, length, ptr, &buf_cnt) != ERROR_OK) {\n\t\tfree(buffer);\n\t\tfileio_close(fileio);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (buf_cnt != length) {\n\t\tLOG_ERROR(\"Short read\");\n\t\tfree(buffer);\n\t\tfileio_close(fileio);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tptr += length;\n\n\tif (padding_at_end) {\n\t\tmemset(ptr, bank->default_padded_value, padding_at_end);\n\t\tLOG_INFO(\"Padding at \" TARGET_ADDR_FMT \" with %\" PRIu32\n\t\t\t\" bytes (bank write end alignment)\",\n\t\t\tend_addr + 1, padding_at_end);\n\t}\n\n\tretval = flash_driver_write(bank, buffer, aligned_start - bank->base, aligned_size);\n\n\tfree(buffer);\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"wrote %zu bytes from file %s to flash bank %u\"\n\t\t\t\" at offset 0x%8.8\" PRIx32 \" in %fs (%0.3f KiB/s)\",\n\t\t\tlength, CMD_ARGV[1], bank->bank_number, offset,\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, length));\n\t}\n\n\tfileio_close(fileio);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_flash_read_bank_command)\n{\n\tuint32_t offset;\n\tuint8_t *buffer;\n\tstruct fileio *fileio;\n\tuint32_t length;\n\tsize_t written;\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tstruct flash_bank *p;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\toffset = 0;\n\n\tif (CMD_ARGC > 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);\n\n\tif (offset > p->size) {\n\t\tLOG_ERROR(\"Offset 0x%8.8\" PRIx32 \" is out of range of the flash bank\",\n\t\t\toffset);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tlength = p->size - offset;\n\n\tif (CMD_ARGC > 3)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], length);\n\n\tif (offset + length > p->size) {\n\t\tLOG_ERROR(\"Length of %\" PRIu32 \" bytes with offset 0x%8.8\" PRIx32\n\t\t\t\" is out of range of the flash bank\", length, offset);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tbuffer = malloc(length);\n\tif (!buffer) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = flash_driver_read(p, buffer, offset, length);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Read error\");\n\t\tfree(buffer);\n\t\treturn retval;\n\t}\n\n\tretval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not open file\");\n\t\tfree(buffer);\n\t\treturn retval;\n\t}\n\n\tretval = fileio_write(fileio, length, buffer, &written);\n\tfileio_close(fileio);\n\tfree(buffer);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not write file\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (duration_measure(&bench) == ERROR_OK)\n\t\tcommand_print(CMD, \"wrote %zd bytes to file %s from flash bank %u\"\n\t\t\t\" at offset 0x%8.8\" PRIx32 \" in %fs (%0.3f KiB/s)\",\n\t\t\twritten, CMD_ARGV[1], p->bank_number, offset,\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, written));\n\n\treturn retval;\n}\n\n\nCOMMAND_HANDLER(handle_flash_verify_bank_command)\n{\n\tuint32_t offset;\n\tuint8_t *buffer_file, *buffer_flash;\n\tstruct fileio *fileio;\n\tsize_t read_cnt;\n\tsize_t filesize;\n\tsize_t length;\n\tint differ;\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tstruct flash_bank *p;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\toffset = 0;\n\n\tif (CMD_ARGC > 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], offset);\n\n\tif (offset > p->size) {\n\t\tLOG_ERROR(\"Offset 0x%8.8\" PRIx32 \" is out of range of the flash bank\",\n\t\t\toffset);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tretval = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not open file\");\n\t\treturn retval;\n\t}\n\n\tretval = fileio_size(fileio, &filesize);\n\tif (retval != ERROR_OK) {\n\t\tfileio_close(fileio);\n\t\treturn retval;\n\t}\n\n\tlength = MIN(filesize, p->size - offset);\n\n\tif (!length) {\n\t\tLOG_INFO(\"Nothing to compare with flash bank\");\n\t\tfileio_close(fileio);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (length != filesize)\n\t\tLOG_INFO(\"File content exceeds flash bank size. Only comparing the \"\n\t\t\t\"first %zu bytes of the file\", length);\n\n\tbuffer_file = malloc(length);\n\tif (!buffer_file) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfileio_close(fileio);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = fileio_read(fileio, length, buffer_file, &read_cnt);\n\tfileio_close(fileio);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"File read failure\");\n\t\tfree(buffer_file);\n\t\treturn retval;\n\t}\n\n\tif (read_cnt != length) {\n\t\tLOG_ERROR(\"Short read\");\n\t\tfree(buffer_file);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbuffer_flash = malloc(length);\n\tif (!buffer_flash) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(buffer_file);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = flash_driver_read(p, buffer_flash, offset, length);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Flash read error\");\n\t\tfree(buffer_flash);\n\t\tfree(buffer_file);\n\t\treturn retval;\n\t}\n\n\tif (duration_measure(&bench) == ERROR_OK)\n\t\tcommand_print(CMD, \"read %zd bytes from file %s and flash bank %u\"\n\t\t\t\" at offset 0x%8.8\" PRIx32 \" in %fs (%0.3f KiB/s)\",\n\t\t\tlength, CMD_ARGV[1], p->bank_number, offset,\n\t\t\tduration_elapsed(&bench), duration_kbps(&bench, length));\n\n\tdiffer = memcmp(buffer_file, buffer_flash, length);\n\tcommand_print(CMD, \"contents %s\", differ ? \"differ\" : \"match\");\n\tif (differ) {\n\t\tuint32_t t;\n\t\tint diffs = 0;\n\t\tfor (t = 0; t < length; t++) {\n\t\t\tif (buffer_flash[t] == buffer_file[t])\n\t\t\t\tcontinue;\n\t\t\tcommand_print(CMD, \"diff %d address 0x%08\" PRIx32 \". Was 0x%02x instead of 0x%02x\",\n\t\t\t\t\tdiffs, t + offset, buffer_flash[t], buffer_file[t]);\n\t\t\tif (diffs++ >= 127) {\n\t\t\t\tcommand_print(CMD, \"More than 128 errors, the rest are not printed.\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tkeep_alive();\n\t\t}\n\t}\n\tfree(buffer_flash);\n\tfree(buffer_file);\n\n\treturn differ ? ERROR_FAIL : ERROR_OK;\n}\n\nvoid flash_set_dirty(void)\n{\n\tstruct flash_bank *c;\n\n\t/* set all flash to require erasing */\n\tfor (c = flash_bank_list(); c; c = c->next) {\n\t\tfor (unsigned int i = 0; i < c->num_sectors; i++)\n\t\t\tc->sectors[i].is_erased = 0;\n\t}\n}\n\nCOMMAND_HANDLER(handle_flash_padded_value_command)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *p;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &p);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], p->default_padded_value);\n\n\tcommand_print(CMD, \"Default padded value set to 0x%\" PRIx8 \" for flash bank %u\",\n\t\t\tp->default_padded_value, p->bank_number);\n\n\treturn retval;\n}\n\nstatic const struct command_registration flash_exec_command_handlers[] = {\n\t{\n\t\t.name = \"probe\",\n\t\t.handler = handle_flash_probe_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Identify a flash bank.\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_flash_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id ['sectors']\",\n\t\t.help = \"Print information about a flash bank.\",\n\t},\n\t{\n\t\t.name = \"erase_check\",\n\t\t.handler = handle_flash_erase_check_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Check erase state of all blocks in a \"\n\t\t\t\"flash bank.\",\n\t},\n\t{\n\t\t.name = \"erase_sector\",\n\t\t.handler = handle_flash_erase_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id first_sector_num (last_sector_num|'last')\",\n\t\t.help = \"Erase a range of sectors in a flash bank.\",\n\t},\n\t{\n\t\t.name = \"erase_address\",\n\t\t.handler = handle_flash_erase_address_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['pad'] ['unlock'] address length\",\n\t\t.help = \"Erase flash sectors starting at address and \"\n\t\t\t\"continuing for length bytes.  If 'pad' is specified, \"\n\t\t\t\"data outside that range may also be erased: the start \"\n\t\t\t\"address may be decreased, and length increased, so \"\n\t\t\t\"that all of the first and last sectors are erased. \"\n\t\t\t\"If 'unlock' is specified, then the flash is unprotected \"\n\t\t\t\"before erasing.\",\n\n\t},\n\t{\n\t\t.name = \"filld\",\n\t\t.handler = handle_flash_fill_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address value n\",\n\t\t.help = \"Fill n double-words with 64-bit value, starting at \"\n\t\t\t\"word address.  (No autoerase.)\",\n\t},\n\t{\n\t\t.name = \"fillw\",\n\t\t.handler = handle_flash_fill_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address value n\",\n\t\t.help = \"Fill n words with 32-bit value, starting at \"\n\t\t\t\"word address.  (No autoerase.)\",\n\t},\n\t{\n\t\t.name = \"fillh\",\n\t\t.handler = handle_flash_fill_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address value n\",\n\t\t.help = \"Fill n halfwords with 16-bit value, starting at \"\n\t\t\t\"word address.  (No autoerase.)\",\n\t},\n\t{\n\t\t.name = \"fillb\",\n\t\t.handler = handle_flash_fill_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address value n\",\n\t\t.help = \"Fill n bytes with 8-bit value, starting at \"\n\t\t\t\"word address.  (No autoerase.)\",\n\t},\n\t{\n\t\t.name = \"mdb\",\n\t\t.handler = handle_flash_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address [count]\",\n\t\t.help = \"Display bytes from flash.\",\n\t},\n\t{\n\t\t.name = \"mdh\",\n\t\t.handler = handle_flash_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address [count]\",\n\t\t.help = \"Display half-words from flash.\",\n\t},\n\t{\n\t\t.name = \"mdw\",\n\t\t.handler = handle_flash_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address [count]\",\n\t\t.help = \"Display words from flash.\",\n\t},\n\t{\n\t\t.name = \"write_bank\",\n\t\t.handler = handle_flash_write_bank_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename [offset]\",\n\t\t.help = \"Write binary data from file to flash bank. Allow optional \"\n\t\t\t\"offset from beginning of the bank (defaults to zero).\",\n\t},\n\t{\n\t\t.name = \"write_image\",\n\t\t.handler = handle_flash_write_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[erase] [unlock] filename [offset [file_type]]\",\n\t\t.help = \"Write an image to flash.  Optionally first unprotect \"\n\t\t\t\"and/or erase the region to be used. Allow optional \"\n\t\t\t\"offset from beginning of bank (defaults to zero)\",\n\t},\n\t{\n\t\t.name = \"verify_image\",\n\t\t.handler = handle_flash_verify_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename [offset [file_type]]\",\n\t\t.help = \"Verify an image against flash. Allow optional \"\n\t\t\t\"offset from beginning of bank (defaults to zero)\",\n\t},\n\t{\n\t\t.name = \"read_bank\",\n\t\t.handler = handle_flash_read_bank_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename [offset [length]]\",\n\t\t.help = \"Read binary data from flash bank to file. Allow optional \"\n\t\t\t\"offset from beginning of the bank (defaults to zero).\",\n\t},\n\t{\n\t\t.name = \"verify_bank\",\n\t\t.handler = handle_flash_verify_bank_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id filename [offset]\",\n\t\t.help = \"Compare the contents of a file with the contents of the \"\n\t\t\t\"flash bank. Allow optional offset from beginning of the bank \"\n\t\t\t\"(defaults to zero).\",\n\t},\n\t{\n\t\t.name = \"protect\",\n\t\t.handler = handle_flash_protect_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id first_block [last_block|'last'] \"\n\t\t\t\"('on'|'off')\",\n\t\t.help = \"Turn protection on or off for a range of protection \"\n\t\t\t\"blocks or sectors in a given flash bank. \"\n\t\t\t\"See 'flash info' output for a list of blocks.\",\n\t},\n\t{\n\t\t.name = \"padded_value\",\n\t\t.handler = handle_flash_padded_value_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id value\",\n\t\t.help = \"Set default flash padded value\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int flash_init_drivers(struct command_context *cmd_ctx)\n{\n\tif (!flash_bank_list())\n\t\treturn ERROR_OK;\n\n\treturn register_commands(cmd_ctx, \"flash\", flash_exec_command_handlers);\n}\n\nCOMMAND_HANDLER(handle_flash_bank_command)\n{\n\tif (CMD_ARGC < 7) {\n\t\tLOG_ERROR(\"usage: flash bank <name> <driver> \"\n\t\t\t\"<base> <size> <chip_width> <bus_width> <target>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\t/* save bank name and advance arguments for compatibility */\n\tconst char *bank_name = *CMD_ARGV++;\n\tCMD_ARGC--;\n\n\tstruct target *target = get_target(CMD_ARGV[5]);\n\tif (!target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[5]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tconst char *driver_name = CMD_ARGV[0];\n\tconst struct flash_driver *driver = flash_driver_find_by_name(driver_name);\n\tif (!driver) {\n\t\t/* no matching flash driver found */\n\t\tLOG_ERROR(\"flash driver '%s' not found\", driver_name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* check the flash bank name is unique */\n\tif (get_flash_bank_by_name_noprobe(bank_name)) {\n\t\t/* flash bank name already exists  */\n\t\tLOG_ERROR(\"flash bank name '%s' already exists\", bank_name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* register flash specific commands */\n\tif (driver->commands) {\n\t\tint retval = register_commands(CMD_CTX, NULL, driver->commands);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"couldn't register '%s' commands\",\n\t\t\t\tdriver_name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct flash_bank *c = calloc(1, sizeof(*c));\n\tc->name = strdup(bank_name);\n\tc->target = target;\n\tc->driver = driver;\n\tCOMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[1], c->base);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], c->size);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[3], c->chip_width);\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[4], c->bus_width);\n\tc->default_padded_value = c->erased_value = 0xff;\n\tc->minimal_write_gap = FLASH_WRITE_GAP_SECTOR;\n\n\tint retval;\n\tretval = CALL_COMMAND_HANDLER(driver->flash_bank_command, c);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"'%s' driver rejected flash bank at \" TARGET_ADDR_FMT\n\t\t\t\t\"; usage: %s\", driver_name, c->base, driver->usage);\n\t\tfree(c);\n\t\treturn retval;\n\t}\n\n\tif (!driver->usage)\n\t\tLOG_DEBUG(\"'%s' driver usage field missing\", driver_name);\n\n\tflash_bank_add(c);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_flash_banks_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned n = 0;\n\tfor (struct flash_bank *p = flash_bank_list(); p; p = p->next, n++) {\n\t\tcommand_print(CMD, \"#%d : %s (%s) at \" TARGET_ADDR_FMT \", size 0x%8.8\" PRIx32 \", \"\n\t\t\t\"buswidth %u, chipwidth %u\", p->bank_number,\n\t\t\tp->name, p->driver->name, p->base, p->size,\n\t\t\tp->bus_width, p->chip_width);\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_flash_list)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (struct flash_bank *p = flash_bank_list(); p; p = p->next) {\n\t\tcommand_print(CMD,\n\t\t\t\"{\\n\"\n\t\t\t\"    name       %s\\n\"\n\t\t\t\"    driver     %s\\n\"\n\t\t\t\"    base       \" TARGET_ADDR_FMT \"\\n\"\n\t\t\t\"    size       0x%\" PRIx32 \"\\n\"\n\t\t\t\"    bus_width  %u\\n\"\n\t\t\t\"    chip_width %u\\n\"\n\t\t\t\"    target     %s\\n\"\n\t\t\t\"}\",\n\t\t\tp->name, p->driver->name, p->base, p->size, p->bus_width, p->chip_width,\n\t\t\ttarget_name(p->target));\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_flash_init_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstatic bool flash_initialized;\n\tif (flash_initialized) {\n\t\tLOG_INFO(\"'flash init' has already been called\");\n\t\treturn ERROR_OK;\n\t}\n\tflash_initialized = true;\n\n\tLOG_DEBUG(\"Initializing flash devices...\");\n\treturn flash_init_drivers(CMD_CTX);\n}\n\nstatic const struct command_registration flash_config_command_handlers[] = {\n\t{\n\t\t.name = \"bank\",\n\t\t.handler = handle_flash_bank_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"bank_id driver_name base_address size_bytes \"\n\t\t\t\"chip_width_bytes bus_width_bytes target \"\n\t\t\t\"[driver_options ...]\",\n\t\t.help = \"Define a new bank with the given name, \"\n\t\t\t\"using the specified NOR flash driver.\",\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_flash_init_command,\n\t\t.help = \"Initialize flash devices.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"banks\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_flash_banks_command,\n\t\t.help = \"Display table with information about flash banks.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"list\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_flash_list,\n\t\t.help = \"Returns a list of details about the flash banks.\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration flash_command_handlers[] = {\n\t{\n\t\t.name = \"flash\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"NOR flash command group\",\n\t\t.chain = flash_config_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint flash_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, flash_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/tms470.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007,2008 by Christopher Kilgour                        *\n *   techie |_at_| whiterocker |_dot_| com                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n\n/* ----------------------------------------------------------------------\n *                      Internal Support, Helpers\n * ---------------------------------------------------------------------- */\n\nstruct tms470_flash_bank {\n\tunsigned ordinal;\n\n\t/* device identification register */\n\tuint32_t device_ident_reg;\n\tuint32_t silicon_version;\n\tuint32_t technology_family;\n\tuint32_t rom_flash;\n\tuint32_t part_number;\n\tconst char *part_name;\n\n};\n\nstatic const struct flash_sector tms470r1a256_sectors[] = {\n\t{0x00000000, 0x00002000, -1, -1},\n\t{0x00002000, 0x00002000, -1, -1},\n\t{0x00004000, 0x00002000, -1, -1},\n\t{0x00006000, 0x00002000, -1, -1},\n\t{0x00008000, 0x00008000, -1, -1},\n\t{0x00010000, 0x00008000, -1, -1},\n\t{0x00018000, 0x00008000, -1, -1},\n\t{0x00020000, 0x00008000, -1, -1},\n\t{0x00028000, 0x00008000, -1, -1},\n\t{0x00030000, 0x00008000, -1, -1},\n\t{0x00038000, 0x00002000, -1, -1},\n\t{0x0003A000, 0x00002000, -1, -1},\n\t{0x0003C000, 0x00002000, -1, -1},\n\t{0x0003E000, 0x00002000, -1, -1},\n};\n\n#define TMS470R1A256_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a256_sectors)\n\nstatic const struct flash_sector tms470r1a288_bank0_sectors[] = {\n\t{0x00000000, 0x00002000, -1, -1},\n\t{0x00002000, 0x00002000, -1, -1},\n\t{0x00004000, 0x00002000, -1, -1},\n\t{0x00006000, 0x00002000, -1, -1},\n};\n\n#define TMS470R1A288_BANK0_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a288_bank0_sectors)\n\nstatic const struct flash_sector tms470r1a288_bank1_sectors[] = {\n\t{0x00040000, 0x00010000, -1, -1},\n\t{0x00050000, 0x00010000, -1, -1},\n\t{0x00060000, 0x00010000, -1, -1},\n\t{0x00070000, 0x00010000, -1, -1},\n};\n\n#define TMS470R1A288_BANK1_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a288_bank1_sectors)\n\nstatic const struct flash_sector tms470r1a384_bank0_sectors[] = {\n\t{0x00000000, 0x00002000, -1, -1},\n\t{0x00002000, 0x00002000, -1, -1},\n\t{0x00004000, 0x00004000, -1, -1},\n\t{0x00008000, 0x00004000, -1, -1},\n\t{0x0000C000, 0x00004000, -1, -1},\n\t{0x00010000, 0x00004000, -1, -1},\n\t{0x00014000, 0x00004000, -1, -1},\n\t{0x00018000, 0x00002000, -1, -1},\n\t{0x0001C000, 0x00002000, -1, -1},\n\t{0x0001E000, 0x00002000, -1, -1},\n};\n\n#define TMS470R1A384_BANK0_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a384_bank0_sectors)\n\nstatic const struct flash_sector tms470r1a384_bank1_sectors[] = {\n\t{0x00020000, 0x00008000, -1, -1},\n\t{0x00028000, 0x00008000, -1, -1},\n\t{0x00030000, 0x00008000, -1, -1},\n\t{0x00038000, 0x00008000, -1, -1},\n};\n\n#define TMS470R1A384_BANK1_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a384_bank1_sectors)\n\nstatic const struct flash_sector tms470r1a384_bank2_sectors[] = {\n\t{0x00040000, 0x00008000, -1, -1},\n\t{0x00048000, 0x00008000, -1, -1},\n\t{0x00050000, 0x00008000, -1, -1},\n\t{0x00058000, 0x00008000, -1, -1},\n};\n\n#define TMS470R1A384_BANK2_NUM_SECTORS \\\n\tARRAY_SIZE(tms470r1a384_bank2_sectors)\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_read_part_info(struct flash_bank *bank)\n{\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t device_ident_reg;\n\tuint32_t silicon_version;\n\tuint32_t technology_family;\n\tuint32_t rom_flash;\n\tuint32_t part_number;\n\tconst char *part_name;\n\n\t/* we shall not rely on the caller in this test, this function allocates memory,\n\t   thus and executing the code more than once may cause memory leak */\n\tif (tms470_info->device_ident_reg)\n\t\treturn ERROR_OK;\n\n\t/* read and parse the device identification register */\n\ttarget_read_u32(target, 0xFFFFFFF0, &device_ident_reg);\n\n\tLOG_INFO(\"device_ident_reg = 0x%08\" PRIx32 \"\", device_ident_reg);\n\n\tif ((device_ident_reg & 7) == 0) {\n\t\tLOG_WARNING(\"Cannot identify target as a TMS470 family.\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tsilicon_version = (device_ident_reg >> 12) & 0xF;\n\ttechnology_family = (device_ident_reg >> 11) & 1;\n\trom_flash = (device_ident_reg >> 10) & 1;\n\tpart_number = (device_ident_reg >> 3) & 0x7f;\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\tbank->num_sectors = 0;\n\n\t/*\n\t * If the part number is known, determine if the flash bank is valid\n\t * based on the base address being within the known flash bank\n\t * ranges.  Then fixup/complete the remaining fields of the flash\n\t * bank structure.\n\t */\n\tswitch (part_number) {\n\t\tcase 0x0a:\n\t\t\tpart_name = \"TMS470R1A256\";\n\n\t\t\tif (bank->base >= 0x00040000) {\n\t\t\t\tLOG_ERROR(\"No %s flash bank contains base address \"\n\t\t\t\t\t\tTARGET_ADDR_FMT \".\",\n\t\t\t\t\t\tpart_name,\n\t\t\t\t\t\tbank->base);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\ttms470_info->ordinal = 0;\n\t\t\tbank->base = 0x00000000;\n\t\t\tbank->size = 256 * 1024;\n\t\t\tbank->num_sectors = TMS470R1A256_NUM_SECTORS;\n\t\t\tbank->sectors = malloc(sizeof(tms470r1a256_sectors));\n\t\t\tif (!bank->sectors)\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t(void)memcpy(bank->sectors, tms470r1a256_sectors, sizeof(tms470r1a256_sectors));\n\t\t\tbreak;\n\n\t\tcase 0x2b:\n\t\t\tpart_name = \"TMS470R1A288\";\n\n\t\t\tif (bank->base < 0x00008000) {\n\t\t\t\ttms470_info->ordinal = 0;\n\t\t\t\tbank->base = 0x00000000;\n\t\t\t\tbank->size = 32 * 1024;\n\t\t\t\tbank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS;\n\t\t\t\tbank->sectors = malloc(sizeof(tms470r1a288_bank0_sectors));\n\t\t\t\tif (!bank->sectors)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t(void)memcpy(bank->sectors, tms470r1a288_bank0_sectors,\n\t\t\t\t\t\tsizeof(tms470r1a288_bank0_sectors));\n\t\t\t} else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000)) {\n\t\t\t\ttms470_info->ordinal = 1;\n\t\t\t\tbank->base = 0x00040000;\n\t\t\t\tbank->size = 256 * 1024;\n\t\t\t\tbank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS;\n\t\t\t\tbank->sectors = malloc(sizeof(tms470r1a288_bank1_sectors));\n\t\t\t\tif (!bank->sectors)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t(void)memcpy(bank->sectors, tms470r1a288_bank1_sectors,\n\t\t\t\t\t\tsizeof(tms470r1a288_bank1_sectors));\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"No %s flash bank contains base address \" TARGET_ADDR_FMT \".\",\n\t\t\t\t\t\tpart_name, bank->base);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 0x2d:\n\t\t\tpart_name = \"TMS470R1A384\";\n\n\t\t\tif (bank->base < 0x00020000) {\n\t\t\t\ttms470_info->ordinal = 0;\n\t\t\t\tbank->base = 0x00000000;\n\t\t\t\tbank->size = 128 * 1024;\n\t\t\t\tbank->num_sectors = TMS470R1A384_BANK0_NUM_SECTORS;\n\t\t\t\tbank->sectors = malloc(sizeof(tms470r1a384_bank0_sectors));\n\t\t\t\tif (!bank->sectors)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t(void)memcpy(bank->sectors, tms470r1a384_bank0_sectors,\n\t\t\t\t\t\tsizeof(tms470r1a384_bank0_sectors));\n\t\t\t} else if ((bank->base >= 0x00020000) && (bank->base < 0x00040000)) {\n\t\t\t\ttms470_info->ordinal = 1;\n\t\t\t\tbank->base = 0x00020000;\n\t\t\t\tbank->size = 128 * 1024;\n\t\t\t\tbank->num_sectors = TMS470R1A384_BANK1_NUM_SECTORS;\n\t\t\t\tbank->sectors = malloc(sizeof(tms470r1a384_bank1_sectors));\n\t\t\t\tif (!bank->sectors)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t(void)memcpy(bank->sectors, tms470r1a384_bank1_sectors,\n\t\t\t\t\t\tsizeof(tms470r1a384_bank1_sectors));\n\t\t\t} else if ((bank->base >= 0x00040000) && (bank->base < 0x00060000)) {\n\t\t\t\ttms470_info->ordinal = 2;\n\t\t\t\tbank->base = 0x00040000;\n\t\t\t\tbank->size = 128 * 1024;\n\t\t\t\tbank->num_sectors = TMS470R1A384_BANK2_NUM_SECTORS;\n\t\t\t\tbank->sectors = malloc(sizeof(tms470r1a384_bank2_sectors));\n\t\t\t\tif (!bank->sectors)\n\t\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\t(void)memcpy(bank->sectors, tms470r1a384_bank2_sectors,\n\t\t\t\t\t\tsizeof(tms470r1a384_bank2_sectors));\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"No %s flash bank contains base address \" TARGET_ADDR_FMT \".\",\n\t\t\t\t\t\tpart_name, bank->base);\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_WARNING(\"Could not identify part 0x%02x as a member of the TMS470 family.\",\n\t\t\t\t\t(unsigned)part_number);\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* turn off memory selects */\n\ttarget_write_u32(target, 0xFFFFFFE4, 0x00000000);\n\ttarget_write_u32(target, 0xFFFFFFE0, 0x00000000);\n\n\tLOG_INFO(\"Identified %s, ver=%d, core=%s, nvmem=%s.\",\n\t\tpart_name,\n\t\t(int)(silicon_version),\n\t\t(technology_family ? \"1.8v\" : \"3.3v\"),\n\t\t(rom_flash ? \"rom\" : \"flash\"));\n\n\ttms470_info->device_ident_reg = device_ident_reg;\n\ttms470_info->silicon_version = silicon_version;\n\ttms470_info->technology_family = technology_family;\n\ttms470_info->rom_flash = rom_flash;\n\ttms470_info->part_number = part_number;\n\ttms470_info->part_name = part_name;\n\n\t/*\n\t * Disable reset on address access violation.\n\t */\n\ttarget_write_u32(target, 0xFFFFFFE0, 0x00004007);\n\n\treturn ERROR_OK;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic uint32_t keys_set;\nstatic uint32_t flash_keys[4];\n\nCOMMAND_HANDLER(tms470_handle_flash_keyset_command)\n{\n\tif (CMD_ARGC > 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (CMD_ARGC == 4) {\n\t\tint i;\n\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tint start = (strncmp(CMD_ARGV[i], \"0x\", 2) == 0) ? 2 : 0;\n\n\t\t\tif (sscanf(&CMD_ARGV[i][start], \"%\" SCNx32 \"\", &flash_keys[i]) != 1) {\n\t\t\t\tcommand_print(CMD, \"could not process flash key %s\",\n\t\t\t\t\tCMD_ARGV[i]);\n\t\t\t\tLOG_ERROR(\"could not process flash key %s\", CMD_ARGV[i]);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\n\t\tkeys_set = 1;\n\t} else if (CMD_ARGC != 0) {\n\t\tcommand_print(CMD, \"tms470 flash_keyset <key0> <key1> <key2> <key3>\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (keys_set) {\n\t\tcommand_print(CMD,\n\t\t\t\"using flash keys 0x%08\" PRIx32 \", 0x%08\" PRIx32 \", 0x%08\" PRIx32 \", 0x%08\" PRIx32 \"\",\n\t\t\tflash_keys[0],\n\t\t\tflash_keys[1],\n\t\t\tflash_keys[2],\n\t\t\tflash_keys[3]);\n\t} else\n\t\tcommand_print(CMD, \"flash keys not set\");\n\n\treturn ERROR_OK;\n}\n\nstatic const uint32_t flash_keys_all_ones[] = { 0xFFFFFFFF, 0xFFFFFFFF,\n\t\t0xFFFFFFFF, 0xFFFFFFFF,};\n\nstatic const uint32_t flash_keys_all_zeros[] = { 0x00000000, 0x00000000,\n\t\t0x00000000, 0x00000000,};\n\nstatic const uint32_t flash_keys_mix1[] = { 0xf0fff0ff, 0xf0fff0ff,\n\t\t0xf0fff0ff, 0xf0fff0ff};\n\nstatic const uint32_t flash_keys_mix2[] = { 0x0000ffff, 0x0000ffff,\n\t\t0x0000ffff, 0x0000ffff};\n\n/* ---------------------------------------------------------------------- */\n\nstatic int osc_mhz = 12;\n\nCOMMAND_HANDLER(tms470_handle_osc_megahertz_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (CMD_ARGC == 1)\n\t\tsscanf(CMD_ARGV[0], \"%d\", &osc_mhz);\n\n\tif (osc_mhz <= 0) {\n\t\tLOG_ERROR(\"osc_megahertz must be positive and non-zero!\");\n\t\tcommand_print(CMD, \"osc_megahertz must be positive and non-zero!\");\n\t\tosc_mhz = 12;\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD, \"osc_megahertz=%d\", osc_mhz);\n\n\treturn ERROR_OK;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int plldis;\n\nCOMMAND_HANDLER(tms470_handle_plldis_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (CMD_ARGC == 1) {\n\t\tsscanf(CMD_ARGV[0], \"%d\", &plldis);\n\t\tplldis = plldis ? 1 : 0;\n\t}\n\n\tcommand_print(CMD, \"plldis=%d\", plldis);\n\n\treturn ERROR_OK;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_check_flash_unlocked(struct target *target)\n{\n\tuint32_t fmbbusy;\n\n\ttarget_read_u32(target, 0xFFE89C08, &fmbbusy);\n\tLOG_INFO(\"tms470 fmbbusy = 0x%08\" PRIx32 \" -> %s\",\n\t\tfmbbusy,\n\t\tfmbbusy & 0x8000 ? \"unlocked\" : \"LOCKED\");\n\treturn fmbbusy & 0x8000 ? ERROR_OK : ERROR_FLASH_OPERATION_FAILED;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_try_flash_keys(struct target *target, const uint32_t *key_set)\n{\n\tuint32_t glbctrl, fmmstat;\n\tint retval = ERROR_FLASH_OPERATION_FAILED;\n\n\t/* set GLBCTRL.4  */\n\ttarget_read_u32(target, 0xFFFFFFDC, &glbctrl);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);\n\n\t/* only perform the key match when 3VSTAT is clear */\n\ttarget_read_u32(target, 0xFFE8BC0C, &fmmstat);\n\tif (!(fmmstat & 0x08)) {\n\t\tunsigned i;\n\t\tuint32_t fmbptr, fmbac2, orig_fmregopt;\n\n\t\ttarget_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07);\n\n\t\t/* wait for pump ready */\n\t\tdo {\n\t\t\ttarget_read_u32(target, 0xFFE8A814, &fmbptr);\n\t\t\talive_sleep(1);\n\t\t} while (!(fmbptr & 0x0200));\n\n\t\t/* force max wait states */\n\t\ttarget_read_u32(target, 0xFFE88004, &fmbac2);\n\t\ttarget_write_u32(target, 0xFFE88004, fmbac2 | 0xff);\n\n\t\t/* save current access mode, force normal read mode */\n\t\ttarget_read_u32(target, 0xFFE89C00, &orig_fmregopt);\n\t\ttarget_write_u32(target, 0xFFE89C00, 0x00);\n\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tuint32_t tmp;\n\n\t\t\t/* There is no point displaying the value of tmp, it is\n\t\t\t * filtered by the chip.  The purpose of this read is to\n\t\t\t * prime the unlocking logic rather than read out the value.\n\t\t\t */\n\t\t\ttarget_read_u32(target, 0x00001FF0 + 4 * i, &tmp);\n\n\t\t\tLOG_INFO(\"tms470 writing fmpkey = 0x%08\" PRIx32 \"\", key_set[i]);\n\t\t\ttarget_write_u32(target, 0xFFE89C0C, key_set[i]);\n\t\t}\n\n\t\tif (tms470_check_flash_unlocked(target) == ERROR_OK) {\n\t\t\t/*\n\t\t\t * There seems to be a side-effect of reading the FMPKEY\n\t\t\t * register in that it re-enables the protection.  So we\n\t\t\t * re-enable it.\n\t\t\t */\n\t\t\tfor (i = 0; i < 4; i++) {\n\t\t\t\tuint32_t tmp;\n\n\t\t\t\ttarget_read_u32(target, 0x00001FF0 + 4 * i, &tmp);\n\t\t\t\ttarget_write_u32(target, 0xFFE89C0C, key_set[i]);\n\t\t\t}\n\t\t\tretval = ERROR_OK;\n\t\t}\n\n\t\t/* restore settings */\n\t\ttarget_write_u32(target, 0xFFE89C00, orig_fmregopt);\n\t\ttarget_write_u32(target, 0xFFE88004, fmbac2);\n\t}\n\n\t/* clear config bit */\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl);\n\n\treturn retval;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_unlock_flash(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tconst uint32_t *p_key_sets[5];\n\tunsigned i, key_set_count;\n\n\tif (keys_set) {\n\t\tkey_set_count = 5;\n\t\tp_key_sets[0] = flash_keys;\n\t\tp_key_sets[1] = flash_keys_all_ones;\n\t\tp_key_sets[2] = flash_keys_all_zeros;\n\t\tp_key_sets[3] = flash_keys_mix1;\n\t\tp_key_sets[4] = flash_keys_mix2;\n\t} else {\n\t\tkey_set_count = 4;\n\t\tp_key_sets[0] = flash_keys_all_ones;\n\t\tp_key_sets[1] = flash_keys_all_zeros;\n\t\tp_key_sets[2] = flash_keys_mix1;\n\t\tp_key_sets[3] = flash_keys_mix2;\n\t}\n\n\tfor (i = 0; i < key_set_count; i++) {\n\t\tif (tms470_try_flash_keys(target, p_key_sets[i]) == ERROR_OK) {\n\t\t\tLOG_INFO(\"tms470 flash is unlocked\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_WARNING(\"tms470 could not unlock flash memory protection level 2\");\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_flash_initialize_internal_state_machine(struct flash_bank *bank)\n{\n\tuint32_t fmmac2, fmmac1, fmmaxep, k, delay, glbctrl, sysclk;\n\tstruct target *target = bank->target;\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tint result = ERROR_OK;\n\n\t/*\n\t * Select the desired bank to be programmed by writing BANK[2:0] of\n\t * FMMAC2.\n\t */\n\ttarget_read_u32(target, 0xFFE8BC04, &fmmac2);\n\tfmmac2 &= ~0x0007;\n\tfmmac2 |= (tms470_info->ordinal & 7);\n\ttarget_write_u32(target, 0xFFE8BC04, fmmac2);\n\tLOG_DEBUG(\"set fmmac2 = 0x%04\" PRIx32 \"\", fmmac2);\n\n\t/*\n\t * Disable level 1 sector protection by setting bit 15 of FMMAC1.\n\t */\n\ttarget_read_u32(target, 0xFFE8BC00, &fmmac1);\n\tfmmac1 |= 0x8000;\n\ttarget_write_u32(target, 0xFFE8BC00, fmmac1);\n\tLOG_DEBUG(\"set fmmac1 = 0x%04\" PRIx32 \"\", fmmac1);\n\n\t/*\n\t * FMTCREG = 0x2fc0;\n\t */\n\ttarget_write_u32(target, 0xFFE8BC10, 0x2fc0);\n\tLOG_DEBUG(\"set fmtcreg = 0x2fc0\");\n\n\t/*\n\t * MAXPP = 50\n\t */\n\ttarget_write_u32(target, 0xFFE8A07C, 50);\n\tLOG_DEBUG(\"set fmmaxpp = 50\");\n\n\t/*\n\t * MAXCP = 0xf000 + 2000\n\t */\n\ttarget_write_u32(target, 0xFFE8A084, 0xf000 + 2000);\n\tLOG_DEBUG(\"set fmmaxcp = 0x%04x\", 0xf000 + 2000);\n\n\t/*\n\t * configure VHV\n\t */\n\ttarget_read_u32(target, 0xFFE8A080, &fmmaxep);\n\tif (fmmaxep == 0xf000) {\n\t\tfmmaxep = 0xf000 + 4095;\n\t\ttarget_write_u32(target, 0xFFE8A80C, 0x9964);\n\t\tLOG_DEBUG(\"set fmptr3 = 0x9964\");\n\t} else {\n\t\tfmmaxep = 0xa000 + 4095;\n\t\ttarget_write_u32(target, 0xFFE8A80C, 0x9b64);\n\t\tLOG_DEBUG(\"set fmptr3 = 0x9b64\");\n\t}\n\ttarget_write_u32(target, 0xFFE8A080, fmmaxep);\n\tLOG_DEBUG(\"set fmmaxep = 0x%04\" PRIx32 \"\", fmmaxep);\n\n\t/*\n\t * FMPTR4 = 0xa000\n\t */\n\ttarget_write_u32(target, 0xFFE8A810, 0xa000);\n\tLOG_DEBUG(\"set fmptr4 = 0xa000\");\n\n\t/*\n\t * FMPESETUP, delay parameter selected based on clock frequency.\n\t *\n\t * According to the TI App Note SPNU257 and flashing code, delay is\n\t * int((sysclk(MHz) + 1) / 2), with a minimum of 5.  The system\n\t * clock is usually derived from the ZPLL module, and selected by\n\t * the plldis global.\n\t */\n\ttarget_read_u32(target, 0xFFFFFFDC, &glbctrl);\n\tsysclk = (plldis ? 1 : (glbctrl & 0x08) ? 4 : 8) * osc_mhz / (1 + (glbctrl & 7));\n\tdelay = (sysclk > 10) ? (sysclk + 1) / 2 : 5;\n\ttarget_write_u32(target, 0xFFE8A018, (delay << 4) | (delay << 8));\n\tLOG_DEBUG(\"set fmpsetup = 0x%04\" PRIx32 \"\", (delay << 4) | (delay << 8));\n\n\t/*\n\t * FMPVEVACCESS, based on delay.\n\t */\n\tk = delay | (delay << 8);\n\ttarget_write_u32(target, 0xFFE8A05C, k);\n\tLOG_DEBUG(\"set fmpvevaccess = 0x%04\" PRIx32 \"\", k);\n\n\t/*\n\t * FMPCHOLD, FMPVEVHOLD, FMPVEVSETUP, based on delay.\n\t */\n\tk <<= 1;\n\ttarget_write_u32(target, 0xFFE8A034, k);\n\tLOG_DEBUG(\"set fmpchold = 0x%04\" PRIx32 \"\", k);\n\ttarget_write_u32(target, 0xFFE8A040, k);\n\tLOG_DEBUG(\"set fmpvevhold = 0x%04\" PRIx32 \"\", k);\n\ttarget_write_u32(target, 0xFFE8A024, k);\n\tLOG_DEBUG(\"set fmpvevsetup = 0x%04\" PRIx32 \"\", k);\n\n\t/*\n\t * FMCVACCESS, based on delay.\n\t */\n\tk = delay * 16;\n\ttarget_write_u32(target, 0xFFE8A060, k);\n\tLOG_DEBUG(\"set fmcvaccess = 0x%04\" PRIx32 \"\", k);\n\n\t/*\n\t * FMCSETUP, based on delay.\n\t */\n\tk = 0x3000 | delay * 20;\n\ttarget_write_u32(target, 0xFFE8A020, k);\n\tLOG_DEBUG(\"set fmcsetup = 0x%04\" PRIx32 \"\", k);\n\n\t/*\n\t * FMEHOLD, based on delay.\n\t */\n\tk = (delay * 20) << 2;\n\ttarget_write_u32(target, 0xFFE8A038, k);\n\tLOG_DEBUG(\"set fmehold = 0x%04\" PRIx32 \"\", k);\n\n\t/*\n\t * PWIDTH, CWIDTH, EWIDTH, based on delay.\n\t */\n\ttarget_write_u32(target, 0xFFE8A050, delay * 8);\n\tLOG_DEBUG(\"set fmpwidth = 0x%04\" PRIx32 \"\", delay * 8);\n\ttarget_write_u32(target, 0xFFE8A058, delay * 1000);\n\tLOG_DEBUG(\"set fmcwidth = 0x%04\" PRIx32 \"\", delay * 1000);\n\ttarget_write_u32(target, 0xFFE8A054, delay * 5400);\n\tLOG_DEBUG(\"set fmewidth = 0x%04\" PRIx32 \"\", delay * 5400);\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_flash_status(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tint result = ERROR_OK;\n\tuint32_t fmmstat;\n\n\ttarget_read_u32(target, 0xFFE8BC0C, &fmmstat);\n\tLOG_DEBUG(\"set fmmstat = 0x%04\" PRIx32 \"\", fmmstat);\n\n\tif (fmmstat & 0x0080) {\n\t\tLOG_WARNING(\"tms470 flash command: erase still active after busy clear.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0040) {\n\t\tLOG_WARNING(\"tms470 flash command: program still active after busy clear.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0020) {\n\t\tLOG_WARNING(\"tms470 flash command: invalid data command.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0010) {\n\t\tLOG_WARNING(\"tms470 flash command: program, erase or validate sector failed.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0008) {\n\t\tLOG_WARNING(\"tms470 flash command: voltage instability detected.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0006) {\n\t\tLOG_WARNING(\"tms470 flash command: command suspend detected.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tif (fmmstat & 0x0001) {\n\t\tLOG_WARNING(\"tms470 flash command: sector was locked.\");\n\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_erase_sector(struct flash_bank *bank, int sector)\n{\n\tuint32_t glbctrl, orig_fmregopt, fmbsea, fmbseb, fmmstat;\n\tstruct target *target = bank->target;\n\tuint32_t flash_addr = bank->base + bank->sectors[sector].offset;\n\tint result = ERROR_OK;\n\n\t/*\n\t * Set the bit GLBCTRL4 of the GLBCTRL register (in the System\n\t * module) to enable writing to the flash registers }.\n\t */\n\ttarget_read_u32(target, 0xFFFFFFDC, &glbctrl);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);\n\tLOG_DEBUG(\"set glbctrl = 0x%08\" PRIx32 \"\", glbctrl | 0x10);\n\n\t/* Force normal read mode. */\n\ttarget_read_u32(target, 0xFFE89C00, &orig_fmregopt);\n\ttarget_write_u32(target, 0xFFE89C00, 0);\n\tLOG_DEBUG(\"set fmregopt = 0x%08x\", 0);\n\n\t(void)tms470_flash_initialize_internal_state_machine(bank);\n\n\t/*\n\t * Select one or more bits in FMBSEA or FMBSEB to disable Level 1\n\t * protection for the particular sector to be erased/written.\n\t */\n\tassert(sector >= 0);\n\tif (sector < 16) {\n\t\ttarget_read_u32(target, 0xFFE88008, &fmbsea);\n\t\ttarget_write_u32(target, 0xFFE88008, fmbsea | (1 << sector));\n\t\tLOG_DEBUG(\"set fmbsea = 0x%04\" PRIx32 \"\", fmbsea | (1 << sector));\n\t} else {\n\t\ttarget_read_u32(target, 0xFFE8800C, &fmbseb);\n\t\ttarget_write_u32(target, 0xFFE8800C, fmbseb | (1 << (sector - 16)));\n\t\tLOG_DEBUG(\"set fmbseb = 0x%04\" PRIx32 \"\", fmbseb | (1 << (sector - 16)));\n\t}\n\tbank->sectors[sector].is_protected = 0;\n\n\t/*\n\t * clear status register, sent erase command, kickoff erase\n\t */\n\ttarget_write_u16(target, flash_addr, 0x0040);\n\tLOG_DEBUG(\"write *(uint16_t *)0x%08\" PRIx32 \"=0x0040\", flash_addr);\n\ttarget_write_u16(target, flash_addr, 0x0020);\n\tLOG_DEBUG(\"write *(uint16_t *)0x%08\" PRIx32 \"=0x0020\", flash_addr);\n\ttarget_write_u16(target, flash_addr, 0xffff);\n\tLOG_DEBUG(\"write *(uint16_t *)0x%08\" PRIx32 \"=0xffff\", flash_addr);\n\n\t/*\n\t * Monitor FMMSTAT, busy until clear, then check and other flags for\n\t * ultimate result of the operation.\n\t */\n\tdo {\n\t\ttarget_read_u32(target, 0xFFE8BC0C, &fmmstat);\n\t\tif (fmmstat & 0x0100)\n\t\t\talive_sleep(1);\n\t} while (fmmstat & 0x0100);\n\n\tresult = tms470_flash_status(bank);\n\n\tif (sector < 16) {\n\t\ttarget_write_u32(target, 0xFFE88008, fmbsea);\n\t\tLOG_DEBUG(\"set fmbsea = 0x%04\" PRIx32 \"\", fmbsea);\n\t\tbank->sectors[sector].is_protected = fmbsea & (1 << sector) ? 0 : 1;\n\t} else {\n\t\ttarget_write_u32(target, 0xFFE8800C, fmbseb);\n\t\tLOG_DEBUG(\"set fmbseb = 0x%04\" PRIx32 \"\", fmbseb);\n\t\tbank->sectors[sector].is_protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;\n\t}\n\ttarget_write_u32(target, 0xFFE89C00, orig_fmregopt);\n\tLOG_DEBUG(\"set fmregopt = 0x%08\" PRIx32 \"\", orig_fmregopt);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl);\n\tLOG_DEBUG(\"set glbctrl = 0x%08\" PRIx32 \"\", glbctrl);\n\n\treturn result;\n}\n\n/*----------------------------------------------------------------------\n *              Implementation of Flash Driver Interfaces\n *---------------------------------------------------------------------- */\n\nstatic const struct command_registration tms470_any_command_handlers[] = {\n\t{\n\t\t.name = \"flash_keyset\",\n\t\t.usage = \"<key0> <key1> <key2> <key3>\",\n\t\t.handler = tms470_handle_flash_keyset_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"tms470 flash_keyset <key0> <key1> <key2> <key3>\",\n\t},\n\t{\n\t\t.name = \"osc_megahertz\",\n\t\t.usage = \"<MHz>\",\n\t\t.handler = tms470_handle_osc_megahertz_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"tms470 osc_megahertz <MHz>\",\n\t},\n\t{\n\t\t.name = \"plldis\",\n\t\t.usage = \"<0 | 1>\",\n\t\t.handler = tms470_handle_plldis_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"tms470 plldis <0/1>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration tms470_command_handlers[] = {\n\t{\n\t\t.name = \"tms470\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"TI tms470 flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = tms470_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tint result = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\ttms470_read_part_info(bank);\n\n\tif ((first >= bank->num_sectors) || (last >= bank->num_sectors) ||\n\t\t\t(first > last)) {\n\t\tLOG_ERROR(\"Sector range %u to %u invalid.\", first, last);\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\tresult = tms470_unlock_flash(bank);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tfor (unsigned int sector = first; sector <= last; sector++) {\n\t\tLOG_INFO(\"Erasing tms470 bank %u sector %u...\", tms470_info->ordinal, sector);\n\n\t\tresult = tms470_erase_sector(bank, sector);\n\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"tms470 could not erase flash sector.\");\n\t\t\tbreak;\n\t\t} else\n\t\t\tLOG_INFO(\"sector erased successfully.\");\n\t}\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tstruct target *target = bank->target;\n\tuint32_t fmmac2, fmbsea, fmbseb;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\ttms470_read_part_info(bank);\n\n\tif ((first >= bank->num_sectors) || (last >= bank->num_sectors) ||\n\t\t\t(first > last)) {\n\t\tLOG_ERROR(\"Sector range %u to %u invalid.\", first, last);\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\t}\n\n\t/* enable the appropriate bank */\n\ttarget_read_u32(target, 0xFFE8BC04, &fmmac2);\n\ttarget_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);\n\n\t/* get the original sector protection flags for this bank */\n\ttarget_read_u32(target, 0xFFE88008, &fmbsea);\n\ttarget_read_u32(target, 0xFFE8800C, &fmbseb);\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tif (sector < 16) {\n\t\t\tfmbsea = set ? fmbsea & ~(1 << sector) : fmbsea | (1 << sector);\n\t\t\tbank->sectors[sector].is_protected = set ? 1 : 0;\n\t\t} else {\n\t\t\tfmbseb = set ? fmbseb &\n\t\t\t\t~(1 << (sector - 16)) : fmbseb | (1 << (sector - 16));\n\t\t\tbank->sectors[sector].is_protected = set ? 1 : 0;\n\t\t}\n\t}\n\n\t/* update the protection bits */\n\ttarget_write_u32(target, 0xFFE88008, fmbsea);\n\ttarget_write_u32(target, 0xFFE8800C, fmbseb);\n\n\treturn ERROR_OK;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tuint32_t glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat;\n\tint result = ERROR_OK;\n\tuint32_t i;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\ttms470_read_part_info(bank);\n\n\tLOG_INFO(\"Writing %\" PRIu32 \" bytes starting at \" TARGET_ADDR_FMT,\n\t\t\tcount, bank->base + offset);\n\n\t/* set GLBCTRL.4  */\n\ttarget_read_u32(target, 0xFFFFFFDC, &glbctrl);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);\n\n\t(void)tms470_flash_initialize_internal_state_machine(bank);\n\n\t/* force max wait states */\n\ttarget_read_u32(target, 0xFFE88004, &fmbac2);\n\ttarget_write_u32(target, 0xFFE88004, fmbac2 | 0xff);\n\n\t/* save current access mode, force normal read mode */\n\ttarget_read_u32(target, 0xFFE89C00, &orig_fmregopt);\n\ttarget_write_u32(target, 0xFFE89C00, 0x00);\n\n\t/*\n\t * Disable Level 1 protection for all sectors to be erased/written.\n\t */\n\ttarget_read_u32(target, 0xFFE88008, &fmbsea);\n\ttarget_write_u32(target, 0xFFE88008, 0xffff);\n\ttarget_read_u32(target, 0xFFE8800C, &fmbseb);\n\ttarget_write_u32(target, 0xFFE8800C, 0xffff);\n\n\t/* read MAXPP */\n\ttarget_read_u32(target, 0xFFE8A07C, &fmmaxpp);\n\n\tfor (i = 0; i < count; i += 2) {\n\t\tuint32_t addr = bank->base + offset + i;\n\t\tuint16_t word = (((uint16_t) buffer[i]) << 8) | (uint16_t) buffer[i + 1];\n\n\t\tif (word != 0xffff) {\n\t\t\tLOG_INFO(\"writing 0x%04x at 0x%08\" PRIx32 \"\", word, addr);\n\n\t\t\t/* clear status register */\n\t\t\ttarget_write_u16(target, addr, 0x0040);\n\t\t\t/* program flash command */\n\t\t\ttarget_write_u16(target, addr, 0x0010);\n\t\t\t/* burn the 16-bit word (big-endian) */\n\t\t\ttarget_write_u16(target, addr, word);\n\n\t\t\t/*\n\t\t\t * Monitor FMMSTAT, busy until clear, then check and other flags\n\t\t\t * for ultimate result of the operation.\n\t\t\t */\n\t\t\tdo {\n\t\t\t\ttarget_read_u32(target, 0xFFE8BC0C, &fmmstat);\n\t\t\t\tif (fmmstat & 0x0100)\n\t\t\t\t\talive_sleep(1);\n\t\t\t} while (fmmstat & 0x0100);\n\n\t\t\tif (fmmstat & 0x3ff) {\n\t\t\t\tLOG_ERROR(\"fmstat = 0x%04\" PRIx32 \"\", fmmstat);\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Could not program word 0x%04x at address 0x%08\" PRIx32 \".\",\n\t\t\t\t\tword,\n\t\t\t\t\taddr);\n\t\t\t\tresult = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else\n\t\t\tLOG_INFO(\"skipping 0xffff at 0x%08\" PRIx32 \"\", addr);\n\t}\n\n\t/* restore */\n\ttarget_write_u32(target, 0xFFE88008, fmbsea);\n\ttarget_write_u32(target, 0xFFE8800C, fmbseb);\n\ttarget_write_u32(target, 0xFFE88004, fmbac2);\n\ttarget_write_u32(target, 0xFFE89C00, orig_fmregopt);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl);\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_probe(struct flash_bank *bank)\n{\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn tms470_read_part_info(bank);\n}\n\nstatic int tms470_auto_probe(struct flash_bank *bank)\n{\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\n\tif (tms470_info->device_ident_reg)\n\t\treturn ERROR_OK;\n\treturn tms470_probe(bank);\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_erase_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tint result = ERROR_OK;\n\tuint32_t fmmac2, fmbac2, glbctrl, orig_fmregopt;\n\tstatic uint8_t buffer[64 * 1024];\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!tms470_info->device_ident_reg)\n\t\ttms470_read_part_info(bank);\n\n\t/* set GLBCTRL.4  */\n\ttarget_read_u32(target, 0xFFFFFFDC, &glbctrl);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);\n\n\t/* save current access mode, force normal read mode */\n\ttarget_read_u32(target, 0xFFE89C00, &orig_fmregopt);\n\ttarget_write_u32(target, 0xFFE89C00, 0x00);\n\n\t/* enable the appropriate bank */\n\ttarget_read_u32(target, 0xFFE8BC04, &fmmac2);\n\ttarget_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);\n\n\t/* TCR = 0 */\n\ttarget_write_u32(target, 0xFFE8BC10, 0x2fc0);\n\n\t/* clear TEZ in fmbrdy */\n\ttarget_write_u32(target, 0xFFE88010, 0x0b);\n\n\t/* save current wait states, force max */\n\ttarget_read_u32(target, 0xFFE88004, &fmbac2);\n\ttarget_write_u32(target, 0xFFE88004, fmbac2 | 0xff);\n\n\t/*\n\t * The TI primitives inspect the flash memory by reading one 32-bit\n\t * word at a time.  Here we read an entire sector and inspect it in\n\t * an attempt to reduce the JTAG overhead.\n\t */\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tuint32_t i, addr = bank->base + bank->sectors[sector].offset;\n\n\t\tLOG_INFO(\"checking flash bank %u sector %u\", tms470_info->ordinal, sector);\n\n\t\ttarget_read_buffer(target, addr, bank->sectors[sector].size, buffer);\n\n\t\tbank->sectors[sector].is_erased = 1;\n\t\tfor (i = 0; i < bank->sectors[sector].size; i++) {\n\t\t\tif (buffer[i] != 0xff) {\n\t\t\t\tbank->sectors[sector].is_erased = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (bank->sectors[sector].is_erased != 1) {\n\t\t\tresult = ERROR_FLASH_SECTOR_NOT_ERASED;\n\t\t\tbreak;\n\t\t} else\n\t\t\tLOG_INFO(\"sector erased\");\n\t}\n\n\t/* reset TEZ, wait states, read mode, GLBCTRL.4 */\n\ttarget_write_u32(target, 0xFFE88010, 0x0f);\n\ttarget_write_u32(target, 0xFFE88004, fmbac2);\n\ttarget_write_u32(target, 0xFFE89C00, orig_fmregopt);\n\ttarget_write_u32(target, 0xFFFFFFDC, glbctrl);\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int tms470_protect_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\tint result = ERROR_OK;\n\tuint32_t fmmac2, fmbsea, fmbseb;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!tms470_info->device_ident_reg)\n\t\ttms470_read_part_info(bank);\n\n\t/* enable the appropriate bank */\n\ttarget_read_u32(target, 0xFFE8BC04, &fmmac2);\n\ttarget_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);\n\n\ttarget_read_u32(target, 0xFFE88008, &fmbsea);\n\ttarget_read_u32(target, 0xFFE8800C, &fmbseb);\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tint protected;\n\n\t\tif (sector < 16) {\n\t\t\tprotected = fmbsea & (1 << sector) ? 0 : 1;\n\t\t\tbank->sectors[sector].is_protected = protected;\n\t\t} else {\n\t\t\tprotected = fmbseb & (1 << (sector - 16)) ? 0 : 1;\n\t\t\tbank->sectors[sector].is_protected = protected;\n\t\t}\n\n\t\tLOG_DEBUG(\"bank %u sector %u is %s\",\n\t\t\ttms470_info->ordinal,\n\t\t\tsector,\n\t\t\tprotected ? \"protected\" : \"not protected\");\n\t}\n\n\treturn result;\n}\n\n/* ---------------------------------------------------------------------- */\n\nstatic int get_tms470_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct tms470_flash_bank *tms470_info = bank->driver_priv;\n\n\tif (!tms470_info->device_ident_reg)\n\t\ttms470_read_part_info(bank);\n\n\tif (!tms470_info->device_ident_reg) {\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as a TMS470\\n\");\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\tcommand_print_sameline(cmd, \"\\ntms470 information: Chip is %s\\n\", tms470_info->part_name);\n\tcommand_print_sameline(cmd, \"Flash protection level 2 is %s\\n\",\n\t\ttms470_check_flash_unlocked(bank->target) == ERROR_OK ? \"disabled\" : \"enabled\");\n\n\treturn ERROR_OK;\n}\n\n/* ---------------------------------------------------------------------- */\n\n/*\n * flash bank tms470 <base> <size> <chip_width> <bus_width> <target>\n * [options...]\n */\n\nFLASH_BANK_COMMAND_HANDLER(tms470_flash_bank_command)\n{\n\tbank->driver_priv = malloc(sizeof(struct tms470_flash_bank));\n\n\tif (!bank->driver_priv)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t(void)memset(bank->driver_priv, 0, sizeof(struct tms470_flash_bank));\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver tms470_flash = {\n\t.name = \"tms470\",\n\t.commands = tms470_command_handlers,\n\t.flash_bank_command = tms470_flash_bank_command,\n\t.erase = tms470_erase,\n\t.protect = tms470_protect,\n\t.write = tms470_write,\n\t.read = default_flash_read,\n\t.probe = tms470_probe,\n\t.auto_probe = tms470_auto_probe,\n\t.erase_check = tms470_erase_check,\n\t.protect_check = tms470_protect_check,\n\t.info = get_tms470_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/virtual.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n\nstatic struct flash_bank *virtual_get_master_bank(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank;\n\n\tmaster_bank = get_flash_bank_by_name_noprobe(bank->driver_priv);\n\tif (!master_bank)\n\t\tLOG_ERROR(\"master flash bank '%s' does not exist\", (char *)bank->driver_priv);\n\n\treturn master_bank;\n}\n\nstatic void virtual_update_bank_info(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\n\tif (!master_bank)\n\t\treturn;\n\n\t/* update the info we do not have */\n\tbank->size = master_bank->size;\n\tbank->chip_width = master_bank->chip_width;\n\tbank->bus_width = master_bank->bus_width;\n\tbank->erased_value = master_bank->erased_value;\n\tbank->default_padded_value = master_bank->default_padded_value;\n\tbank->write_start_alignment = master_bank->write_start_alignment;\n\tbank->write_end_alignment = master_bank->write_end_alignment;\n\tbank->minimal_write_gap = master_bank->minimal_write_gap;\n\tbank->num_sectors = master_bank->num_sectors;\n\tbank->sectors = master_bank->sectors;\n\tbank->num_prot_blocks = master_bank->num_prot_blocks;\n\tbank->prot_blocks = master_bank->prot_blocks;\n}\n\nFLASH_BANK_COMMAND_HANDLER(virtual_flash_bank_command)\n{\n\tif (CMD_ARGC < 7)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* get the master flash bank */\n\tconst char *bank_name = CMD_ARGV[6];\n\tstruct flash_bank *master_bank = get_flash_bank_by_name_noprobe(bank_name);\n\n\tif (!master_bank) {\n\t\tLOG_ERROR(\"master flash bank '%s' does not exist\", bank_name);\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t}\n\n\t/* save master bank name - use this to get settings later */\n\tbank->driver_priv = strdup(bank_name);\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\treturn flash_driver_protect(master_bank, set, first, last);\n}\n\nstatic int virtual_protect_check(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tif (!master_bank->driver->protect_check)\n\t\treturn ERROR_FLASH_OPER_UNSUPPORTED;\n\n\t/* call master handler */\n\treturn master_bank->driver->protect_check(master_bank);\n}\n\nstatic int virtual_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->erase(master_bank, first, last);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->write(master_bank, buffer, offset, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_probe(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->probe(master_bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* update the info we do not have */\n\tvirtual_update_bank_info(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_auto_probe(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->auto_probe(master_bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* update the info we do not have */\n\tvirtual_update_bank_info(bank);\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\tcommand_print_sameline(cmd, \"%s driver for flash bank %s at \" TARGET_ADDR_FMT,\n\t\t\tbank->driver->name, master_bank->name, master_bank->base);\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_blank_check(struct flash_bank *bank)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->erase_check(master_bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int virtual_flash_read(struct flash_bank *bank,\n\t\tuint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\tstruct flash_bank *master_bank = virtual_get_master_bank(bank);\n\tint retval;\n\n\tif (!master_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* call master handler */\n\tretval = master_bank->driver->read(master_bank, buffer, offset, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver virtual_flash = {\n\t.name = \"virtual\",\n\t.flash_bank_command = virtual_flash_bank_command,\n\t.erase = virtual_erase,\n\t.protect = virtual_protect,\n\t.write = virtual_write,\n\t.read = virtual_flash_read,\n\t.probe = virtual_probe,\n\t.auto_probe = virtual_auto_probe,\n\t.erase_check = virtual_blank_check,\n\t.protect_check = virtual_protect_check,\n\t.info = virtual_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/w600.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Simon Qian                                      *\n *   SimonQian@SimonQian.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define W600_FLASH_SECSIZE\t\t0x1000\n#define W600_FLASH_PAGESIZE\t\t0x100\n#define W600_FLASH_BASE\t\t\t0x08000000\n#define W600_FLASH_PROTECT_SIZE\t0x2000\n\n/* w600 register locations */\n\n#define QFLASH_REGBASE\t\t\t0X40002000\n#define QFLASH_CMD_INFO\t\t\t(QFLASH_REGBASE + 0)\n#define QFLASH_CMD_START\t\t(QFLASH_REGBASE + 4)\n#define QFLASH_BUFFER\t\t\t(QFLASH_REGBASE + 0X200)\n\n#define QFLASH_CMD_READ\t\t\t(1ul << 14)\n#define QFLASH_CMD_WRITE\t\t0\n#define QFLASH_CMD_ADDR\t\t\t(1ul << 31)\n#define QFLASH_CMD_DATA\t\t\t(1ul << 15)\n#define QFLASH_CMD_DATALEN(len)\t(((len) & 0x3FF) << 16)\n\n#define QFLASH_CMD_RDID\t\t\t(QFLASH_CMD_READ | 0x9F)\n#define QFLASH_CMD_WREN\t\t\t(QFLASH_CMD_WRITE | 0x06)\n#define QFLASH_CMD_WRDI\t\t\t(QFLASH_CMD_WRITE | 0x04)\n#define QFLASH_CMD_SE\t\t\t(QFLASH_CMD_WRITE | QFLASH_CMD_ADDR | (1ul << 11) | 0x20)\n#define QFLASH_CMD_PP\t\t\t(QFLASH_CMD_WRITE | QFLASH_CMD_ADDR | (1ul << 12) | 0x02)\n\n#define QFLASH_START\t\t\t(1ul << 28)\n#define QFLASH_ADDR(addr)\t\t(((addr) & 0xFFFFF) << 8)\n#define QFLASH_CRM(crm)\t\t\t(((crm) & 0xFF) << 0)\n\nstruct w600_flash_param {\n\tuint8_t id;\n\tuint8_t se_delay;\n\tuint8_t pp_delay;\n};\nstatic const struct w600_flash_param w600_param[] = {\n\t{\n\t\t.id = 0x85,\n\t\t.se_delay = 8,\n\t\t.pp_delay = 2,\n\t},\n\t{\n\t\t.id = 0x1C,\n\t\t.se_delay = 50,\n\t\t.pp_delay = 1,\n\t},\n\t{\n\t\t.id = 0xC8,\n\t\t.se_delay = 45,\n\t\t.pp_delay = 1,\n\t},\n\t{\n\t\t.id = 0x0B,\n\t\t.se_delay = 60,\n\t\t.pp_delay = 1,\n\t},\n\t{\n\t\t.id = 0x68,\n\t\t.se_delay = 50,\n\t\t.pp_delay = 1,\n\t},\n};\n\nstruct w600_flash_bank {\n\tbool probed;\n\n\tuint32_t id;\n\tconst struct w600_flash_param *param;\n\tuint32_t register_base;\n\tuint32_t user_bank_size;\n};\n\n/* flash bank w600 <base> <size> 0 0 <target#>\n */\nFLASH_BANK_COMMAND_HANDLER(w600_flash_bank_command)\n{\n\tstruct w600_flash_bank *w600_info;\n\n\tif (CMD_ARGC < 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tw600_info = malloc(sizeof(struct w600_flash_bank));\n\n\tbank->driver_priv = w600_info;\n\tw600_info->probed = false;\n\tw600_info->register_base = QFLASH_REGBASE;\n\tw600_info->user_bank_size = bank->size;\n\n\treturn ERROR_OK;\n}\n\nstatic int w600_get_delay(struct flash_bank *bank, uint32_t cmd)\n{\n\tstruct w600_flash_bank *w600_info = bank->driver_priv;\n\n\tif (!w600_info->param)\n\t\treturn 0;\n\n\tswitch (cmd) {\n\tcase QFLASH_CMD_SE:\n\t\treturn w600_info->param->se_delay;\n\tcase QFLASH_CMD_PP:\n\t\treturn w600_info->param->pp_delay;\n\tdefault:\n\t\treturn 0;\n\t}\n}\n\nstatic int w600_start_do(struct flash_bank *bank, uint32_t cmd, uint32_t addr,\n\t\tuint32_t len, int timeout)\n{\n\tstruct target *target = bank->target;\n\n\tif (len > 0)\n\t\tcmd |= QFLASH_CMD_DATALEN(len - 1) | QFLASH_CMD_DATA;\n\n\tLOG_DEBUG(\"WRITE CMD: 0x%08\" PRIx32 \"\", cmd);\n\tint retval = target_write_u32(target, QFLASH_CMD_INFO, cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\taddr |= QFLASH_START;\n\tLOG_DEBUG(\"WRITE START: 0x%08\" PRIx32 \"\", addr);\n\tretval = target_write_u32(target, QFLASH_CMD_START, addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"DELAY %dms\", timeout);\n\talive_sleep(timeout);\n\n\tint retry = 100;\n\tuint32_t status;\n\tfor (;;) {\n\t\tLOG_DEBUG(\"READ START...\");\n\t\tretval = target_read_u32(target, QFLASH_CMD_START, &status);\n\t\tif (retval == ERROR_OK)\n\t\t\tLOG_DEBUG(\"READ START: 0x%08\" PRIx32 \"\", status);\n\t\telse\n\t\t\tLOG_DEBUG(\"READ START FAILED\");\n\n\t\tif ((retval != ERROR_OK) || (status & QFLASH_START)) {\n\t\t\tif (retry-- <= 0) {\n\t\t\t\tLOG_ERROR(\"timed out waiting for flash\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int w600_write_enable(struct flash_bank *bank)\n{\n\treturn w600_start_do(bank, QFLASH_CMD_WREN, 0, 0, 0);\n}\n\nstatic int w600_write_disable(struct flash_bank *bank)\n{\n\treturn w600_start_do(bank, QFLASH_CMD_WRDI, 0, 0, 0);\n}\n\nstatic int w600_start(struct flash_bank *bank, uint32_t cmd, uint32_t addr,\n\t\tuint32_t len)\n{\n\tint retval = w600_write_enable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = w600_start_do(bank, cmd, addr, len, w600_get_delay(bank, cmd));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = w600_write_disable(bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int w600_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tint retval = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\tif (first < W600_FLASH_PROTECT_SIZE / W600_FLASH_SECSIZE) {\n\t\tLOG_ERROR(\"can not erase protected area\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tretval = w600_start(bank, QFLASH_CMD_SE,\n\t\t\tQFLASH_ADDR(bank->sectors[i].offset), 0);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int w600_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t count)\n{\n\tstruct target *target = bank->target;\n\tint retval = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif ((offset % W600_FLASH_PAGESIZE) != 0) {\n\t\tLOG_WARNING(\"offset 0x%\" PRIx32 \" breaks required %d-byte alignment\",\n\t\t\toffset, W600_FLASH_PAGESIZE);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\tif ((count % W600_FLASH_PAGESIZE) != 0) {\n\t\tLOG_WARNING(\"count 0x%\" PRIx32 \" breaks required %d-byte alignment\",\n\t\t\toffset, W600_FLASH_PAGESIZE);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\n\twhile (count > 0) {\n\t\tretval = target_write_buffer(target, QFLASH_BUFFER, W600_FLASH_PAGESIZE, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = w600_start(bank, QFLASH_CMD_PP, QFLASH_ADDR(offset),\n\t\t\t\tW600_FLASH_PAGESIZE);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tcount -= W600_FLASH_PAGESIZE;\n\t\toffset += W600_FLASH_PAGESIZE;\n\t\tbuffer += W600_FLASH_PAGESIZE;\n\t}\n\n\treturn retval;\n}\n\nstatic int w600_get_flash_id(struct flash_bank *bank, uint32_t *flash_id)\n{\n\tstruct target *target = bank->target;\n\n\tint retval = w600_start(bank, QFLASH_CMD_RDID, 0, 4);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_read_u32(target, QFLASH_BUFFER, flash_id);\n}\n\nstatic int w600_probe(struct flash_bank *bank)\n{\n\tstruct w600_flash_bank *w600_info = bank->driver_priv;\n\tuint32_t flash_size;\n\tuint32_t flash_id;\n\tsize_t i;\n\n\tw600_info->probed = false;\n\n\t/* read stm32 device id register */\n\tint retval = w600_get_flash_id(bank, &flash_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(\"flash_id id = 0x%08\" PRIx32 \"\", flash_id);\n\tw600_info->id = flash_id;\n\tw600_info->param = NULL;\n\tfor (i = 0; i < ARRAY_SIZE(w600_param); i++) {\n\t\tif (w600_param[i].id == (flash_id & 0xFF)) {\n\t\t\tw600_info->param = &w600_param[i];\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!w600_info->param) {\n\t\tLOG_ERROR(\"flash_id not supported for w600\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* if the user sets the size manually then ignore the probed value\n\t * this allows us to work around devices that have a invalid flash size register value */\n\tif (w600_info->user_bank_size) {\n\t\tLOG_INFO(\"ignoring flash probed value, using configured bank size\");\n\t\tflash_size = w600_info->user_bank_size;\n\t} else {\n\t\tflash_size = ((flash_id & 0xFFFFFF) >> 16) & 0xFF;\n\t\tif ((flash_size != 0x14) && (flash_size != 0x13)) {\n\t\t\tLOG_ERROR(\"w600 flash size failed, probe inaccurate\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tflash_size = 1 << flash_size;\n\t}\n\n\tLOG_INFO(\"flash size = %\" PRIu32 \" KiB\", flash_size / 1024);\n\n\t/* calculate numbers of pages */\n\tsize_t num_pages = flash_size / W600_FLASH_SECSIZE;\n\n\t/* check that calculation result makes sense */\n\tassert(num_pages > 0);\n\n\tfree(bank->sectors);\n\tbank->sectors = NULL;\n\n\tbank->base = W600_FLASH_BASE;\n\tbank->size = num_pages * W600_FLASH_SECSIZE;\n\tbank->num_sectors = num_pages;\n\tbank->write_start_alignment = W600_FLASH_PAGESIZE;\n\tbank->write_end_alignment = W600_FLASH_PAGESIZE;\n\tbank->sectors = malloc(sizeof(struct flash_sector) * num_pages);\n\n\tfor (i = 0; i < num_pages; i++) {\n\t\tbank->sectors[i].offset = i * W600_FLASH_SECSIZE;\n\t\tbank->sectors[i].size = W600_FLASH_SECSIZE;\n\t\tbank->sectors[i].is_erased = -1;\n\t\t/* offset 0 to W600_FLASH_PROTECT_SIZE should be protected */\n\t\tbank->sectors[i].is_protected = (i < W600_FLASH_PROTECT_SIZE / W600_FLASH_SECSIZE);\n\t}\n\n\tw600_info->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int w600_auto_probe(struct flash_bank *bank)\n{\n\tstruct w600_flash_bank *w600_info = bank->driver_priv;\n\tif (w600_info->probed)\n\t\treturn ERROR_OK;\n\treturn w600_probe(bank);\n}\n\nstatic int get_w600_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tuint32_t flash_id;\n\n\t/* read w600 device id register */\n\tint retval = w600_get_flash_id(bank, &flash_id);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print_sameline(cmd, \"w600 : 0x%08\" PRIx32 \"\", flash_id);\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver w600_flash = {\n\t.name = \"w600\",\n\t.flash_bank_command = w600_flash_bank_command,\n\t.erase = w600_erase,\n\t.write = w600_write,\n\t.read = default_flash_read,\n\t.probe = w600_probe,\n\t.auto_probe = w600_auto_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = get_w600_info,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/xcf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Uladzimir Pylinski aka barthess                 *\n *   barthess@yandex.ru                                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"imp.h\"\n#include <jtag/jtag.h>\n#include <helper/time_support.h>\n\n/*\n ******************************************************************************\n * DEFINES\n ******************************************************************************\n */\n\n#define SECTOR_ERASE_TIMEOUT_MS         (35 * 1000)\n\n#define XCF_PAGE_SIZE                   32\n#define XCF_DATA_SECTOR_SIZE            (1024 * 1024)\n\n#define ID_XCF01S                       0x05044093\n#define ID_XCF02S                       0x05045093\n#define ID_XCF04S                       0x05046093\n#define ID_XCF08P                       0x05057093\n#define ID_XCF16P                       0x05058093\n#define ID_XCF32P                       0x05059093\n#define ID_MEANINGFUL_MASK              0x0FFFFFFF\n\nstatic const char * const xcf_name_list[] = {\n\t\"XCF08P\",\n\t\"XCF16P\",\n\t\"XCF32P\",\n\t\"unknown\"\n};\n\nstruct xcf_priv {\n\tbool probed;\n};\n\nstruct xcf_status {\n\tbool isc_error;\t\t/* false == OK, true == error */\n\tbool prog_error;\t/* false == OK, true == error */\n\tbool prog_busy;\t\t/* false == idle, true == busy */\n\tbool isc_mode;\t\t/* false == normal mode, true == ISC mode */\n};\n\n/*\n ******************************************************************************\n * GLOBAL VARIABLES\n ******************************************************************************\n */\nstatic const uint8_t cmd_bypass[2]              = {0xFF, 0xFF};\n\nstatic const uint8_t cmd_isc_address_shift[2]   = {0xEB, 0x00};\nstatic const uint8_t cmd_isc_data_shift[2]      = {0xED, 0x00};\nstatic const uint8_t cmd_isc_disable[2]         = {0xF0, 0x00};\nstatic const uint8_t cmd_isc_enable[2]          = {0xE8, 0x00};\nstatic const uint8_t cmd_isc_erase[2]           = {0xEC, 0x00};\nstatic const uint8_t cmd_isc_program[2]         = {0xEA, 0x00};\n\nstatic const uint8_t cmd_xsc_blank_check[2]     = {0x0D, 0x00};\nstatic const uint8_t cmd_xsc_config[2]          = {0xEE, 0x00};\nstatic const uint8_t cmd_xsc_data_btc[2]        = {0xF2, 0x00};\nstatic const uint8_t cmd_xsc_data_ccb[2]        = {0x0C, 0x00};\nstatic const uint8_t cmd_xsc_data_done[2]       = {0x09, 0x00};\nstatic const uint8_t cmd_xsc_data_sucr[2]       = {0x0E, 0x00};\nstatic const uint8_t cmd_xsc_data_wrpt[2]       = {0xF7, 0x00};\nstatic const uint8_t cmd_xsc_op_status[2]       = {0xE3, 0x00};\nstatic const uint8_t cmd_xsc_read[2]            = {0xEF, 0x00};\nstatic const uint8_t cmd_xsc_unlock[2]          = {0x55, 0xAA};\n\n/*\n ******************************************************************************\n * LOCAL FUNCTIONS\n ******************************************************************************\n */\n\nstatic const char *product_name(const struct flash_bank *bank)\n{\n\n\tswitch (bank->target->tap->idcode & ID_MEANINGFUL_MASK) {\n\t\tcase ID_XCF08P:\n\t\t\treturn xcf_name_list[0];\n\t\tcase ID_XCF16P:\n\t\t\treturn xcf_name_list[1];\n\t\tcase ID_XCF32P:\n\t\t\treturn xcf_name_list[2];\n\t\tdefault:\n\t\t\treturn xcf_name_list[3];\n\t}\n}\n\nstatic void fill_sector_table(struct flash_bank *bank)\n{\n\t/* Note: is_erased and is_protected fields must be set here to an unknown\n\t * state, they will be correctly filled from other API calls. */\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].is_erased              = -1;\n\t\tbank->sectors[i].is_protected   = -1;\n\t}\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].size   = XCF_DATA_SECTOR_SIZE;\n\t\tbank->sectors[i].offset = i * XCF_DATA_SECTOR_SIZE;\n\t}\n\n\tbank->size = bank->num_sectors * XCF_DATA_SECTOR_SIZE;\n}\n\nstatic struct xcf_status read_status(struct flash_bank *bank)\n{\n\tstruct xcf_status ret;\n\tuint8_t irdata[2];\n\tstruct scan_field scan;\n\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd_bypass;\n\tscan.in_value = irdata;\n\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tret.isc_error   = ((irdata[0] >> 7) & 3) == 0b01;\n\tret.prog_error  = ((irdata[0] >> 5) & 3) == 0b01;\n\tret.prog_busy   = ((irdata[0] >> 4) & 1) == 0;\n\tret.isc_mode    = ((irdata[0] >> 3) & 1) == 1;\n\n\treturn ret;\n}\n\nstatic int isc_enter(struct flash_bank *bank)\n{\n\n\tstruct xcf_status status = read_status(bank);\n\n\tif (true == status.isc_mode)\n\t\treturn ERROR_OK;\n\telse {\n\t\tstruct scan_field scan;\n\n\t\tscan.check_mask = NULL;\n\t\tscan.check_value = NULL;\n\t\tscan.num_bits = 16;\n\t\tscan.out_value = cmd_isc_enable;\n\t\tscan.in_value = NULL;\n\n\t\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\t\tjtag_execute_queue();\n\n\t\tstatus = read_status(bank);\n\t\tif (!status.isc_mode) {\n\t\t\tLOG_ERROR(\"*** XCF: FAILED to enter ISC mode\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n}\n\nstatic int isc_leave(struct flash_bank *bank)\n{\n\n\tstruct xcf_status status = read_status(bank);\n\n\tif (!status.isc_mode)\n\t\treturn ERROR_OK;\n\telse {\n\t\tstruct scan_field scan;\n\n\t\tscan.check_mask = NULL;\n\t\tscan.check_value = NULL;\n\t\tscan.num_bits = 16;\n\t\tscan.out_value = cmd_isc_disable;\n\t\tscan.in_value = NULL;\n\n\t\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\t\tjtag_execute_queue();\n\t\talive_sleep(1);\t/* device needs 50 uS to leave ISC mode */\n\n\t\tstatus = read_status(bank);\n\t\tif (status.isc_mode) {\n\t\t\tLOG_ERROR(\"*** XCF: FAILED to leave ISC mode\");\n\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n}\n\nstatic int sector_state(uint8_t wrpt, int sector)\n{\n\tif (((wrpt >> sector) & 1) == 1)\n\t\treturn 0;\n\telse\n\t\treturn 1;\n}\n\nstatic uint8_t fill_select_block(unsigned int first, unsigned int last)\n{\n\tuint8_t ret = 0;\n\tfor (unsigned int i = first; i <= last; i++)\n\t\tret |= 1 << i;\n\treturn ret;\n}\n\nstatic int isc_read_register(struct flash_bank *bank, const uint8_t *cmd,\n\tuint8_t *data_buf, int num_bits)\n{\n\tstruct scan_field scan;\n\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.out_value = cmd;\n\tscan.in_value = NULL;\n\tscan.num_bits = 16;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);\n\n\tscan.out_value = NULL;\n\tscan.in_value = data_buf;\n\tscan.num_bits = num_bits;\n\tjtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int isc_wait_erase_program(struct flash_bank *bank, int64_t timeout_ms)\n{\n\n\tuint8_t isc_default;\n\tint64_t t0 = timeval_ms();\n\tint64_t dt;\n\n\tdo {\n\t\tisc_read_register(bank, cmd_xsc_op_status, &isc_default, 8);\n\t\tif (((isc_default >> 2) & 1) == 1)\n\t\t\treturn ERROR_OK;\n\t\tdt = timeval_ms() - t0;\n\t} while (dt <= timeout_ms);\n\treturn ERROR_FLASH_OPERATION_FAILED;\n}\n\n/*\n * helper function for procedures without program jtag command at the end\n */\nstatic int isc_set_register(struct flash_bank *bank, const uint8_t *cmd,\n\tconst uint8_t *data_buf, int num_bits, int64_t timeout_ms)\n{\n\tstruct scan_field scan;\n\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);\n\n\tscan.num_bits = num_bits;\n\tscan.out_value = data_buf;\n\tscan.in_value = NULL;\n\tjtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);\n\n\tif (timeout_ms == 0)\n\t\treturn jtag_execute_queue();\n\telse\n\t\treturn isc_wait_erase_program(bank, timeout_ms);\n}\n\n/*\n * helper function for procedures required program jtag command at the end\n */\nstatic int isc_program_register(struct flash_bank *bank, const uint8_t *cmd,\n\tconst uint8_t *data_buf, int num_bits, int64_t timeout_ms)\n{\n\tstruct scan_field scan;\n\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_DRSHIFT);\n\n\tscan.num_bits = num_bits;\n\tscan.out_value = data_buf;\n\tscan.in_value = NULL;\n\tjtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IRSHIFT);\n\n\tscan.num_bits = 16;\n\tscan.out_value = cmd_isc_program;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\n\tif (timeout_ms == 0)\n\t\treturn jtag_execute_queue();\n\telse\n\t\treturn isc_wait_erase_program(bank, timeout_ms);\n}\n\nstatic int isc_clear_protect(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint8_t select_block[3] = {0x0, 0x0, 0x0};\n\tselect_block[0] = fill_select_block(first, last);\n\treturn isc_set_register(bank, cmd_xsc_unlock, select_block, 24, 0);\n}\n\nstatic int isc_set_protect(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint8_t wrpt[2] = {0xFF, 0xFF};\n\tfor (unsigned int i = first; i <= last; i++)\n\t\twrpt[0] &= ~(1 << i);\n\n\treturn isc_program_register(bank, cmd_xsc_data_wrpt, wrpt, 16, 0);\n}\n\nstatic int isc_erase_sectors(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tuint8_t select_block[3] = {0, 0, 0};\n\tselect_block[0] = fill_select_block(first, last);\n\tint64_t timeout = SECTOR_ERASE_TIMEOUT_MS * (last - first + 1);\n\treturn isc_set_register(bank, cmd_isc_erase, select_block, 24, timeout);\n}\n\nstatic int isc_adr_shift(struct flash_bank *bank, int adr)\n{\n\tuint8_t adr_buf[3];\n\th_u24_to_le(adr_buf, adr);\n\treturn isc_set_register(bank, cmd_isc_address_shift, adr_buf, 24, 0);\n}\n\nstatic int isc_program_data_page(struct flash_bank *bank, const uint8_t *page_buf)\n{\n\treturn isc_program_register(bank, cmd_isc_data_shift, page_buf, 8 * XCF_PAGE_SIZE, 100);\n}\n\nstatic void isc_data_read_out(struct flash_bank *bank, uint8_t *buffer, uint32_t count)\n{\n\n\tstruct scan_field scan;\n\n\t/* Do not change this code with isc_read_register() call because it needs\n\t * transition to IDLE state before data retrieving. */\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd_xsc_read;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\n\tscan.num_bits = 8 * count;\n\tscan.out_value = NULL;\n\tscan.in_value = buffer;\n\tjtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);\n\n\tjtag_execute_queue();\n}\n\nstatic int isc_set_data_done(struct flash_bank *bank, int sector)\n{\n\tuint8_t done = 0xFF;\n\tdone &= ~(1 << sector);\n\treturn isc_program_register(bank, cmd_xsc_data_done, &done, 8, 100);\n}\n\nstatic void flip_u8(uint8_t *out, const uint8_t *in, int len)\n{\n\tfor (int i = 0; i < len; i++)\n\t\tout[i] = flip_u32(in[i], 8);\n}\n\n/*\n * Xilinx bin file contains simple fixed header for automatic bus width detection:\n * 16 bytes of 0xFF\n * 4 byte sync word 0xAA995566 or (bit reversed) 0x5599AA66 in MSC file\n *\n * Function presumes need of bit reversing if it can not exactly detects\n * the opposite.\n */\nstatic bool need_bit_reverse(const uint8_t *buffer)\n{\n\tconst size_t L = 20;\n\tuint8_t reference[L];\n\tmemset(reference, 0xFF, 16);\n\treference[16] = 0x55;\n\treference[17] = 0x99;\n\treference[18] = 0xAA;\n\treference[19] = 0x66;\n\n\tif (memcmp(reference, buffer, L) == 0)\n\t\treturn false;\n\telse\n\t\treturn true;\n}\n\n/*\n * The page address to be programmed is determined by loading the\n * internal ADDRESS Register using an ISC_ADDRESS_SHIFT instruction sequence.\n * The page address automatically increments to the next 256-bit\n * page address after each programming sequence until the last address\n * in the 8 Mb block is reached. To continue programming the next block,\n * the next 8 Mb block's starting address must be loaded into the\n * internal ADDRESS register.\n */\nstatic int read_write_data(struct flash_bank *bank, const uint8_t *w_buffer,\n\tuint8_t *r_buffer, bool write_flag, uint32_t offset, uint32_t count)\n{\n\tint dbg_count = count;\n\tint dbg_written = 0;\n\tint ret = ERROR_OK;\n\tuint8_t *page_buf = malloc(XCF_PAGE_SIZE);\n\tbool revbit = true;\n\tisc_enter(bank);\n\n\tif (offset % XCF_PAGE_SIZE != 0) {\n\t\tret = ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t\tgoto EXIT;\n\t}\n\n\tif ((offset + count) > (bank->num_sectors * XCF_DATA_SECTOR_SIZE)) {\n\t\tret = ERROR_FLASH_DST_OUT_OF_BANK;\n\t\tgoto EXIT;\n\t}\n\n\tif ((write_flag) && (offset == 0) && (count >= XCF_PAGE_SIZE))\n\t\trevbit = need_bit_reverse(w_buffer);\n\n\twhile (count > 0) {\n\t\tuint32_t sector_num = offset / XCF_DATA_SECTOR_SIZE;\n\t\tuint32_t sector_offset = offset - sector_num * XCF_DATA_SECTOR_SIZE;\n\t\tuint32_t sector_bytes = XCF_DATA_SECTOR_SIZE - sector_offset;\n\t\tif (count < sector_bytes)\n\t\t\tsector_bytes = count;\n\t\tisc_adr_shift(bank, offset);\n\t\toffset += sector_bytes;\n\t\tcount -= sector_bytes;\n\n\t\tif (write_flag) {\n\t\t\twhile (sector_bytes > 0) {\n\t\t\t\tint len;\n\n\t\t\t\tif (sector_bytes < XCF_PAGE_SIZE) {\n\t\t\t\t\tlen = sector_bytes;\n\t\t\t\t\tmemset(page_buf, 0xFF, XCF_PAGE_SIZE);\n\t\t\t\t} else\n\t\t\t\t\tlen = XCF_PAGE_SIZE;\n\n\t\t\t\tif (revbit)\n\t\t\t\t\tflip_u8(page_buf, w_buffer, len);\n\t\t\t\telse\n\t\t\t\t\tmemcpy(page_buf, w_buffer, len);\n\n\t\t\t\tw_buffer += len;\n\t\t\t\tsector_bytes -= len;\n\t\t\t\tret = isc_program_data_page(bank, page_buf);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\tgoto EXIT;\n\t\t\t\telse {\n\t\t\t\t\tLOG_DEBUG(\"written %d bytes from %d\", dbg_written, dbg_count);\n\t\t\t\t\tdbg_written += len;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tisc_data_read_out(bank, r_buffer, sector_bytes);\n\t\t\tflip_u8(r_buffer, r_buffer, sector_bytes);\n\t\t\tr_buffer += sector_bytes;\n\t\t}\n\t}\n\n\t/* Set 'done' flags for all data sectors because driver supports\n\t * only single revision. */\n\tif (write_flag) {\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tret = isc_set_data_done(bank, i);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tgoto EXIT;\n\t\t}\n\t}\n\nEXIT:\n\tfree(page_buf);\n\tisc_leave(bank);\n\treturn ret;\n}\n\nstatic uint16_t isc_read_ccb(struct flash_bank *bank)\n{\n\tuint8_t ccb[2];\n\tisc_read_register(bank, cmd_xsc_data_ccb, ccb, 16);\n\treturn le_to_h_u16(ccb);\n}\n\nstatic unsigned int gucr_num(const struct flash_bank *bank)\n{\n\treturn bank->num_sectors;\n}\n\nstatic unsigned int sucr_num(const struct flash_bank *bank)\n{\n\treturn bank->num_sectors + 1;\n}\n\nstatic int isc_program_ccb(struct flash_bank *bank, uint16_t ccb)\n{\n\tuint8_t buf[2];\n\th_u16_to_le(buf, ccb);\n\treturn isc_program_register(bank, cmd_xsc_data_ccb, buf, 16, 100);\n}\n\nstatic int isc_program_singe_revision_sucr(struct flash_bank *bank)\n{\n\tuint8_t sucr[2] = {0xFC, 0xFF};\n\treturn isc_program_register(bank, cmd_xsc_data_sucr, sucr, 16, 100);\n}\n\nstatic int isc_program_single_revision_btc(struct flash_bank *bank)\n{\n\tuint8_t buf[4];\n\tuint32_t btc = 0xFFFFFFFF;\n\tbtc &= ~0b1111;\n\tbtc |= ((bank->num_sectors - 1) << 2);\n\tbtc &= ~(1 << 4);\n\th_u32_to_le(buf, btc);\n\treturn isc_program_register(bank, cmd_xsc_data_btc, buf, 32, 100);\n}\n\nstatic int fpga_configure(struct flash_bank *bank)\n{\n\tstruct scan_field scan;\n\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd_xsc_config;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\tjtag_execute_queue();\n\n\treturn ERROR_OK;\n}\n\n/*\n ******************************************************************************\n * EXPORTED FUNCTIONS\n ******************************************************************************\n */\n\nFLASH_BANK_COMMAND_HANDLER(xcf_flash_bank_command)\n{\n\tstruct xcf_priv *priv;\n\n\tpriv = malloc(sizeof(struct xcf_priv));\n\tif (!priv) {\n\t\tLOG_ERROR(\"no memory for flash bank info\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbank->driver_priv = priv;\n\tpriv->probed = false;\n\treturn ERROR_OK;\n}\n\nstatic int xcf_info(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tconst struct xcf_priv *priv = bank->driver_priv;\n\n\tif (!priv->probed) {\n\t\tcommand_print_sameline(cmd, \"\\nXCF flash bank not probed yet\\n\");\n\t\treturn ERROR_OK;\n\t}\n\tcommand_print_sameline(cmd, \"%s\", product_name(bank));\n\treturn ERROR_OK;\n}\n\nstatic int xcf_probe(struct flash_bank *bank)\n{\n\tstruct xcf_priv *priv = bank->driver_priv;\n\tuint32_t id;\n\n\tif (priv->probed)\n\t\tfree(bank->sectors);\n\tpriv->probed = false;\n\n\tif (!bank->target->tap) {\n\t\tLOG_ERROR(\"Target has no JTAG tap\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* check idcode and alloc memory for sector table */\n\tif (!bank->target->tap->hasidcode)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t/* guess number of blocks using chip ID */\n\tid = bank->target->tap->idcode;\n\tswitch (id & ID_MEANINGFUL_MASK) {\n\t\tcase ID_XCF08P:\n\t\t\tbank->num_sectors = 1;\n\t\t\tbreak;\n\t\tcase ID_XCF16P:\n\t\t\tbank->num_sectors = 2;\n\t\t\tbreak;\n\t\tcase ID_XCF32P:\n\t\t\tbank->num_sectors = 4;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unknown flash device ID 0x%\" PRIX32, id);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tbank->sectors = malloc(bank->num_sectors * sizeof(struct flash_sector));\n\tif (!bank->sectors) {\n\t\tLOG_ERROR(\"No memory for sector table\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfill_sector_table(bank);\n\n\tpriv->probed = true;\n\t/* REVISIT: Why is unchanged bank->driver_priv rewritten by same value? */\n\tbank->driver_priv = priv;\n\n\tLOG_INFO(\"product name: %s\", product_name(bank));\n\tLOG_INFO(\"device id = 0x%\" PRIX32, bank->target->tap->idcode);\n\tLOG_INFO(\"flash size = %d configuration bits\",\n\t\tbank->num_sectors * XCF_DATA_SECTOR_SIZE * 8);\n\tLOG_INFO(\"number of sectors = %u\", bank->num_sectors);\n\n\treturn ERROR_OK;\n}\n\nstatic int xcf_auto_probe(struct flash_bank *bank)\n{\n\tstruct xcf_priv *priv = bank->driver_priv;\n\n\tif (priv->probed)\n\t\treturn ERROR_OK;\n\telse\n\t\treturn xcf_probe(bank);\n}\n\nstatic int xcf_protect_check(struct flash_bank *bank)\n{\n\tuint8_t wrpt[2];\n\n\tisc_enter(bank);\n\tisc_read_register(bank, cmd_xsc_data_wrpt, wrpt, 16);\n\tisc_leave(bank);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = sector_state(wrpt[0], i);\n\n\treturn ERROR_OK;\n}\n\nstatic int xcf_erase_check(struct flash_bank *bank)\n{\n\tuint8_t blankreg;\n\tstruct scan_field scan;\n\n\tisc_enter(bank);\n\n\t/* Do not change this code with isc_read_register() call because it needs\n\t * transition to IDLE state and pause before data retrieving. */\n\tscan.check_mask = NULL;\n\tscan.check_value = NULL;\n\tscan.num_bits = 16;\n\tscan.out_value = cmd_xsc_blank_check;\n\tscan.in_value = NULL;\n\tjtag_add_ir_scan(bank->target->tap, &scan, TAP_IDLE);\n\tjtag_execute_queue();\n\talive_sleep(500);\t/* device needs at least 0.5s to self check */\n\n\tscan.num_bits = 8;\n\tscan.in_value = &blankreg;\n\tjtag_add_dr_scan(bank->target->tap, 1, &scan, TAP_IDLE);\n\tjtag_execute_queue();\n\n\tisc_leave(bank);\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_erased = sector_state(blankreg, i);\n\n\treturn ERROR_OK;\n}\n\nstatic int xcf_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tif ((first >= bank->num_sectors)\n\t\t|| (last >= bank->num_sectors)\n\t\t|| (last < first))\n\t\treturn ERROR_FLASH_SECTOR_INVALID;\n\telse {\n\t\tisc_enter(bank);\n\t\tisc_clear_protect(bank, first, last);\n\t\tint ret = isc_erase_sectors(bank, first, last);\n\t\tisc_leave(bank);\n\t\treturn ret;\n\t}\n}\n\nstatic int xcf_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)\n{\n\treturn read_write_data(bank, NULL, buffer, false, offset, count);\n}\n\nstatic int xcf_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset,\n\tuint32_t count)\n{\n\treturn read_write_data(bank, buffer, NULL, true, offset, count);\n}\n\nstatic int xcf_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint ret;\n\n\tisc_enter(bank);\n\tif (set)\n\t\tret = isc_set_protect(bank, first, last);\n\telse {\n\t\t/* write protection may be removed only with following erase */\n\t\tisc_clear_protect(bank, first, last);\n\t\tret = isc_erase_sectors(bank, first, last);\n\t}\n\tisc_leave(bank);\n\n\treturn ret;\n}\n\nCOMMAND_HANDLER(xcf_handle_ccb_command) {\n\n\tif (!((CMD_ARGC == 1) || (CMD_ARGC == 5)))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint16_t ccb = 0xFFFF;\n\tisc_enter(bank);\n\tuint16_t old_ccb = isc_read_ccb(bank);\n\tisc_leave(bank);\n\n\tif (CMD_ARGC == 1) {\n\t\tLOG_INFO(\"current CCB = 0x%X\", old_ccb);\n\t\treturn ERROR_OK;\n\t} else {\n\t\t/* skip over flash bank */\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\twhile (CMD_ARGC) {\n\t\t\tif (strcmp(\"external\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb |= (1 << 0);\n\t\t\telse if (strcmp(\"internal\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb &= ~(1 << 0);\n\t\t\telse if (strcmp(\"serial\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb |= (3 << 1);\n\t\t\telse if (strcmp(\"parallel\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb &= ~(3 << 1);\n\t\t\telse if (strcmp(\"slave\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb |= (1 << 3);\n\t\t\telse if (strcmp(\"master\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb &= ~(1 << 3);\n\t\t\telse if (strcmp(\"40\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb |= (3 << 4);\n\t\t\telse if (strcmp(\"20\", CMD_ARGV[0]) == 0)\n\t\t\t\tccb &= ~(1 << 5);\n\t\t\telse\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t}\n\n\t\tisc_enter(bank);\n\t\tint sector;\n\n\t\t/* GUCR sector */\n\t\tsector = gucr_num(bank);\n\t\tisc_clear_protect(bank, sector, sector);\n\t\tint ret = isc_erase_sectors(bank, sector, sector);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\t\tret = isc_program_ccb(bank, ccb);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\t\tret = isc_program_single_revision_btc(bank);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\t\tret = isc_set_data_done(bank, sector);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\n\t\t/* SUCR sector */\n\t\tsector = sucr_num(bank);\n\t\tisc_clear_protect(bank, sector, sector);\n\t\tret = isc_erase_sectors(bank, sector, sector);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\t\tret = isc_program_singe_revision_sucr(bank);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\t\tret = isc_set_data_done(bank, sector);\n\t\tif (ret != ERROR_OK)\n\t\t\tgoto EXIT;\n\nEXIT:\n\t\tisc_leave(bank);\n\t\treturn ret;\n\t}\n}\n\nCOMMAND_HANDLER(xcf_handle_configure_command) {\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct flash_bank *bank;\n\tint retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn fpga_configure(bank);\n}\n\nstatic const struct command_registration xcf_exec_command_handlers[] = {\n\t{\n\t\t.name = \"configure\",\n\t\t.handler = xcf_handle_configure_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id\",\n\t\t.help = \"Initiate FPGA loading procedure.\"\n\t},\n\t{\n\t\t.name = \"ccb\",\n\t\t.handler = xcf_handle_ccb_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id [('external'|'internal') \"\n\t\t\t\"('serial'|'parallel') \"\n\t\t\t\"('slave'|'master') \"\n\t\t\t\"('40'|'20')]\",\n\t\t.help = \"Write CCB register with supplied options and (silently) BTC \"\n\t\t\t\"register with single revision options. Display current \"\n\t\t\t\"CCB value when only bank_id supplied. \"\n\t\t\t\"Following options available: \"\n\t\t\t\"1) external or internal clock source; \"\n\t\t\t\"2) serial or parallel bus mode; \"\n\t\t\t\"3) slave or master mode; \"\n\t\t\t\"4) clock frequency in MHz for internal clock in master mode;\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration xcf_command_handlers[] = {\n\t{\n\t\t.name = \"xcf\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Xilinx platform flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = xcf_exec_command_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver xcf_flash = {\n\t.name               = \"xcf\",\n\t.usage              = NULL,\n\t.commands           = xcf_command_handlers,\n\t.flash_bank_command = xcf_flash_bank_command,\n\t.erase              = xcf_erase,\n\t.protect            = xcf_protect,\n\t.write              = xcf_write,\n\t.read               = xcf_read,\n\t.probe              = xcf_probe,\n\t.auto_probe         = xcf_auto_probe,\n\t.erase_check        = xcf_erase_check,\n\t.protect_check      = xcf_protect_check,\n\t.info               = xcf_info,\n\t.free_driver_priv   = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/xmc1xxx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * XMC1000 flash driver\n *\n * Copyright (c) 2016 Andreas Färber\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/align.h>\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n#define FLASH_BASE\t0x10000000\n#define PAU_BASE\t0x40000000\n#define SCU_BASE\t0x40010000\n#define NVM_BASE\t0x40050000\n\n#define FLASH_CS0\t(FLASH_BASE + 0xf00)\n\n#define PAU_FLSIZE\t(PAU_BASE + 0x404)\n\n#define SCU_IDCHIP\t(SCU_BASE + 0x004)\n\n#define NVMSTATUS\t(NVM_BASE + 0x00)\n#define NVMPROG\t\t(NVM_BASE + 0x04)\n#define NVMCONF\t\t(NVM_BASE + 0x08)\n\n#define NVMSTATUS_BUSY\t\t(1 << 0)\n#define NVMSTATUS_VERR_MASK\t(0x3 << 2)\n\n#define NVMPROG_ACTION_OPTYPE_IDLE_VERIFY\t(0 << 0)\n#define NVMPROG_ACTION_OPTYPE_WRITE\t\t(1 << 0)\n#define NVMPROG_ACTION_OPTYPE_PAGE_ERASE\t(2 << 0)\n\n#define NVMPROG_ACTION_ONE_SHOT_ONCE\t\t(1 << 4)\n#define NVMPROG_ACTION_ONE_SHOT_CONTINUOUS\t(2 << 4)\n\n#define NVMPROG_ACTION_VERIFY_EACH\t\t(1 << 6)\n#define NVMPROG_ACTION_VERIFY_NO\t\t(2 << 6)\n#define NVMPROG_ACTION_VERIFY_ARRAY\t\t(3 << 6)\n\n#define NVMPROG_ACTION_IDLE\t0x00\n#define NVMPROG_ACTION_MASK\t0xff\n\n#define NVM_WORD_SIZE 4\n#define NVM_BLOCK_SIZE (4 * NVM_WORD_SIZE)\n#define NVM_PAGE_SIZE (16 * NVM_BLOCK_SIZE)\n\nstruct xmc1xxx_flash_bank {\n\tbool probed;\n};\n\nstatic int xmc1xxx_nvm_set_idle(struct target *target)\n{\n\treturn target_write_u16(target, NVMPROG, NVMPROG_ACTION_IDLE);\n}\n\nstatic int xmc1xxx_nvm_check_idle(struct target *target)\n{\n\tuint16_t val;\n\tint retval;\n\n\tretval = target_read_u16(target, NVMPROG, &val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif ((val & NVMPROG_ACTION_MASK) != NVMPROG_ACTION_IDLE) {\n\t\tLOG_WARNING(\"NVMPROG.ACTION\");\n\t\tretval = xmc1xxx_nvm_set_idle(target);\n\t}\n\n\treturn retval;\n}\n\nstatic int xmc1xxx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct target *target = bank->target;\n\tstruct working_area *workarea;\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_algo;\n\tunsigned i;\n\tint retval;\n\tconst uint8_t erase_code[] = {\n#include \"../../../contrib/loaders/flash/xmc1xxx/erase.inc\"\n\t};\n\n\tLOG_DEBUG(\"Infineon XMC1000 erase sectors %u to %u\", first, last);\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = xmc1xxx_nvm_check_idle(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_alloc_working_area(target, sizeof(erase_code),\n\t\t\t&workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_code;\n\t}\n\tretval = target_write_buffer(target, workarea->address,\n\t\t\tsizeof(erase_code), erase_code);\n\tif (retval != ERROR_OK)\n\t\tgoto err_write_code;\n\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, NVM_BASE);\n\tbuf_set_u32(reg_params[1].value, 0, 32, bank->base +\n\t\tbank->sectors[first].offset);\n\tbuf_set_u32(reg_params[2].value, 0, 32, bank->base +\n\t\tbank->sectors[last].offset + bank->sectors[last].size);\n\n\tretval = target_run_algorithm(target,\n\t\t\t0, NULL,\n\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\tworkarea->address, 0,\n\t\t\t1000, &armv7m_algo);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error executing flash sector erase \"\n\t\t\t\"programming algorithm\");\n\t\tretval = xmc1xxx_nvm_set_idle(target);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_WARNING(\"Couldn't restore NVMPROG.ACTION\");\n\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\tgoto err_run;\n\t}\n\nerr_run:\n\tfor (i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nerr_write_code:\n\ttarget_free_working_area(target, workarea);\n\nerr_alloc_code:\n\treturn retval;\n}\n\nstatic int xmc1xxx_erase_check(struct flash_bank *bank)\n{\n\tstruct target *target = bank->target;\n\tstruct working_area *workarea;\n\tstruct reg_param reg_params[3];\n\tstruct armv7m_algorithm armv7m_algo;\n\tuint16_t val;\n\tunsigned i;\n\tint retval;\n\tconst uint8_t erase_check_code[] = {\n#include \"../../../contrib/loaders/flash/xmc1xxx/erase_check.inc\"\n\t};\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_alloc_working_area(target, sizeof(erase_check_code),\n\t\t\t&workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_code;\n\t}\n\tretval = target_write_buffer(target, workarea->address,\n\t\t\tsizeof(erase_check_code), erase_check_code);\n\tif (retval != ERROR_OK)\n\t\tgoto err_write_code;\n\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, NVM_BASE);\n\n\tfor (unsigned int sector = 0; sector < bank->num_sectors; sector++) {\n\t\tuint32_t start = bank->base + bank->sectors[sector].offset;\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, start);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, start + bank->sectors[sector].size);\n\n\t\tretval = xmc1xxx_nvm_check_idle(target);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err_nvmprog;\n\n\t\tLOG_DEBUG(\"Erase-checking 0x%08\" PRIx32, start);\n\t\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\tworkarea->address, 0,\n\t\t\t\t1000, &armv7m_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing flash sector erase check \"\n\t\t\t\t\"programming algorithm\");\n\t\t\tretval = xmc1xxx_nvm_set_idle(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_WARNING(\"Couldn't restore NVMPROG.ACTION\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run;\n\t\t}\n\n\t\tretval = target_read_u16(target, NVMSTATUS, &val);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read NVMSTATUS\");\n\t\t\tgoto err_nvmstatus;\n\t\t}\n\t\tbank->sectors[sector].is_erased = (val & NVMSTATUS_VERR_MASK) ? 0 : 1;\n\t}\n\nerr_nvmstatus:\nerr_run:\nerr_nvmprog:\n\tfor (i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\nerr_write_code:\n\ttarget_free_working_area(target, workarea);\n\nerr_alloc_code:\n\treturn retval;\n}\n\nstatic int xmc1xxx_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\tuint32_t offset, uint32_t byte_count)\n{\n\tstruct target *target = bank->target;\n\tstruct working_area *code_workarea, *data_workarea;\n\tstruct reg_param reg_params[4];\n\tstruct armv7m_algorithm armv7m_algo;\n\tuint32_t block_count = DIV_ROUND_UP(byte_count, NVM_BLOCK_SIZE);\n\tunsigned i;\n\tint retval;\n\tconst uint8_t write_code[] = {\n#include \"../../../contrib/loaders/flash/xmc1xxx/write.inc\"\n\t};\n\n\tLOG_DEBUG(\"Infineon XMC1000 write at 0x%08\" PRIx32 \" (%\" PRIu32 \" bytes)\",\n\t\toffset, byte_count);\n\n\tif (!IS_ALIGNED(offset, NVM_BLOCK_SIZE)) {\n\t\tLOG_ERROR(\"offset 0x%\" PRIx32 \" breaks required block alignment\",\n\t\t\toffset);\n\t\treturn ERROR_FLASH_DST_BREAKS_ALIGNMENT;\n\t}\n\tif (!IS_ALIGNED(byte_count, NVM_BLOCK_SIZE)) {\n\t\tLOG_WARNING(\"length %\" PRIu32 \" is not block aligned, rounding up\",\n\t\t\tbyte_count);\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_alloc_working_area(target, sizeof(write_code),\n\t\t\t&code_workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available for write code.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_code;\n\t}\n\tretval = target_write_buffer(target, code_workarea->address,\n\t\t\tsizeof(write_code), write_code);\n\tif (retval != ERROR_OK)\n\t\tgoto err_write_code;\n\n\tretval = target_alloc_working_area(target, MAX(NVM_BLOCK_SIZE,\n\t\tMIN(block_count * NVM_BLOCK_SIZE, target_get_working_area_avail(target))),\n\t\t&data_workarea);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"No working area available for write data.\");\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto err_alloc_data;\n\t}\n\n\tarmv7m_algo.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_algo.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_OUT);\n\tinit_reg_param(&reg_params[3], \"r3\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, NVM_BASE);\n\n\twhile (byte_count > 0) {\n\t\tuint32_t blocks = MIN(block_count, data_workarea->size / NVM_BLOCK_SIZE);\n\t\tuint32_t addr = bank->base + offset;\n\n\t\tLOG_DEBUG(\"copying %\" PRIu32 \" bytes to SRAM \" TARGET_ADDR_FMT,\n\t\t\tMIN(blocks * NVM_BLOCK_SIZE, byte_count),\n\t\t\tdata_workarea->address);\n\n\t\tretval = target_write_buffer(target, data_workarea->address,\n\t\t\tMIN(blocks * NVM_BLOCK_SIZE, byte_count), buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error writing data buffer\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_write_data;\n\t\t}\n\t\tif (byte_count < blocks * NVM_BLOCK_SIZE) {\n\t\t\tretval = target_write_memory(target,\n\t\t\t\tdata_workarea->address + byte_count, 1,\n\t\t\t\tblocks * NVM_BLOCK_SIZE - byte_count,\n\t\t\t\t&bank->default_padded_value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error writing data padding\");\n\t\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\t\tgoto err_write_pad;\n\t\t\t}\n\t\t}\n\n\t\tLOG_DEBUG(\"writing 0x%08\" PRIx32 \"-0x%08\" PRIx32 \" (%\" PRIu32 \"x)\",\n\t\t\taddr, addr + blocks * NVM_BLOCK_SIZE - 1, blocks);\n\n\t\tretval = xmc1xxx_nvm_check_idle(target);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto err_nvmprog;\n\n\t\tbuf_set_u32(reg_params[1].value, 0, 32, addr);\n\t\tbuf_set_u32(reg_params[2].value, 0, 32, data_workarea->address);\n\t\tbuf_set_u32(reg_params[3].value, 0, 32, blocks);\n\n\t\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\tcode_workarea->address, 0,\n\t\t\t\t5 * 60 * 1000, &armv7m_algo);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error executing flash write \"\n\t\t\t\t\"programming algorithm\");\n\t\t\tretval = xmc1xxx_nvm_set_idle(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_WARNING(\"Couldn't restore NVMPROG.ACTION\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tgoto err_run;\n\t\t}\n\n\t\tblock_count -= blocks;\n\t\toffset += blocks * NVM_BLOCK_SIZE;\n\t\tbuffer += blocks * NVM_BLOCK_SIZE;\n\t\tbyte_count -= MIN(blocks * NVM_BLOCK_SIZE, byte_count);\n\t}\n\nerr_run:\nerr_nvmprog:\nerr_write_pad:\nerr_write_data:\n\tfor (i = 0; i < ARRAY_SIZE(reg_params); i++)\n\t\tdestroy_reg_param(&reg_params[i]);\n\n\ttarget_free_working_area(target, data_workarea);\nerr_alloc_data:\nerr_write_code:\n\ttarget_free_working_area(target, code_workarea);\n\nerr_alloc_code:\n\treturn retval;\n}\n\nstatic int xmc1xxx_protect_check(struct flash_bank *bank)\n{\n\tuint32_t nvmconf;\n\tunsigned int num_protected;\n\tint retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_read_u32(bank->target, NVMCONF, &nvmconf);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read NVMCONF register.\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"NVMCONF = %08\" PRIx32, nvmconf);\n\n\tnum_protected = (nvmconf >> 4) & 0xff;\n\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tbank->sectors[i].is_protected = (i < num_protected) ? 1 : 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc1xxx_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tuint32_t chipid[8];\n\tint i, retval;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Obtain the 8-word Chip Identification Number */\n\tfor (i = 0; i < 7; i++) {\n\t\tretval = target_read_u32(bank->target, FLASH_CS0 + i * 4, &chipid[i]);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Cannot read CS0 register %i.\", i);\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"ID[%d] = %08\" PRIX32, i, chipid[i]);\n\t}\n\tretval = target_read_u32(bank->target, SCU_BASE + 0x000, &chipid[7]);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read DBGROMID register.\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"ID[7] = %08\" PRIX32, chipid[7]);\n\n\tcommand_print_sameline(cmd,\n\t\t\t\"XMC%\" PRIx32 \"00 %\" PRIX32 \" flash %\" PRIu32 \"KB ROM %\" PRIu32 \"KB SRAM %\" PRIu32 \"KB\",\n\t\t\t(chipid[0] >> 12) & 0xff,\n\t\t\t0xAA + (chipid[7] >> 28) - 1,\n\t\t\t(((chipid[6] >> 12) & 0x3f) - 1) * 4,\n\t\t\t(((chipid[4] >> 8) & 0x3f) * 256) / 1024,\n\t\t\t(((chipid[5] >> 8) & 0x1f) * 256 * 4) / 1024);\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc1xxx_probe(struct flash_bank *bank)\n{\n\tstruct xmc1xxx_flash_bank *xmc_bank = bank->driver_priv;\n\tuint32_t flash_addr = bank->base;\n\tuint32_t idchip, flsize;\n\tint retval;\n\n\tif (xmc_bank->probed)\n\t\treturn ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = target_read_u32(bank->target, SCU_IDCHIP, &idchip);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read IDCHIP register.\");\n\t\treturn retval;\n\t}\n\n\tif ((idchip & 0xffff0000) != 0x10000) {\n\t\tLOG_ERROR(\"IDCHIP register does not match XMC1xxx.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"IDCHIP = %08\" PRIx32, idchip);\n\n\tretval = target_read_u32(bank->target, PAU_FLSIZE, &flsize);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read FLSIZE register.\");\n\t\treturn retval;\n\t}\n\n\tbank->num_sectors = 1 + ((flsize >> 12) & 0x3f) - 1;\n\tbank->size = bank->num_sectors * 4 * 1024;\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t       sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tif (i == 0) {\n\t\t\tbank->sectors[i].size = 0x200;\n\t\t\tbank->sectors[i].offset = 0xE00;\n\t\t\tflash_addr += 0x1000;\n\t\t} else {\n\t\t\tbank->sectors[i].size = 4 * 1024;\n\t\t\tbank->sectors[i].offset = flash_addr - bank->base;\n\t\t\tflash_addr += bank->sectors[i].size;\n\t\t}\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\t}\n\n\txmc_bank->probed = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc1xxx_auto_probe(struct flash_bank *bank)\n{\n\tstruct xmc1xxx_flash_bank *xmc_bank = bank->driver_priv;\n\n\tif (xmc_bank->probed)\n\t\treturn ERROR_OK;\n\n\treturn xmc1xxx_probe(bank);\n}\n\nFLASH_BANK_COMMAND_HANDLER(xmc1xxx_flash_bank_command)\n{\n\tstruct xmc1xxx_flash_bank *xmc_bank;\n\n\txmc_bank = malloc(sizeof(struct xmc1xxx_flash_bank));\n\tif (!xmc_bank)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\txmc_bank->probed = false;\n\n\tbank->driver_priv = xmc_bank;\n\n\treturn ERROR_OK;\n}\n\nconst struct flash_driver xmc1xxx_flash = {\n\t.name = \"xmc1xxx\",\n\t.flash_bank_command = xmc1xxx_flash_bank_command,\n\t.info = xmc1xxx_get_info_command,\n\t.probe = xmc1xxx_probe,\n\t.auto_probe = xmc1xxx_auto_probe,\n\t.protect_check = xmc1xxx_protect_check,\n\t.read = default_flash_read,\n\t.erase = xmc1xxx_erase,\n\t.erase_check = xmc1xxx_erase_check,\n\t.write = xmc1xxx_write,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/nor/xmc4xxx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/**************************************************************************\n*   Copyright (C) 2015 Jeff Ciesielski <jeffciesielski@gmail.com>         *\n***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"imp.h\"\n#include <helper/binarybuffer.h>\n#include <target/algorithm.h>\n#include <target/armv7m.h>\n\n/* Maximum number of sectors */\n#define MAX_XMC_SECTORS 12\n\n/* System control unit registers */\n#define SCU_REG_BASE 0x50004000\n\n#define SCU_ID_CHIP 0x04\n\n/* Base of the non-cached flash memory */\n#define PFLASH_BASE\t0x0C000000\n\n/* User configuration block offsets */\n#define UCB0_BASE       0x00000000\n#define UCB1_BASE       0x00000400\n#define UCB2_BASE       0x00000800\n\n/* Flash register base */\n#define FLASH_REG_BASE 0x58000000\n\n/* PMU ID Registers */\n#define FLASH_REG_PMU_ID\t(FLASH_REG_BASE | 0x0508)\n\n/* PMU Fields */\n#define PMU_MOD_REV_MASK\t0xFF\n#define PMU_MOD_TYPE_MASK\t0xFF00\n#define PMU_MOD_NO_MASK\t\t0xFFFF0000\n\n/* Prefetch Config */\n#define FLASH_REG_PREF_PCON\t(FLASH_REG_BASE | 0x4000)\n\n/* Prefetch Fields */\n#define PCON_IBYP\t(1 << 0)\n#define PCON_IINV\t(1 << 1)\n\n/* Flash ID Register */\n#define FLASH_REG_FLASH0_ID\t(FLASH_REG_BASE | 0x2008)\n\n/* Flash Status Register */\n#define FLASH_REG_FLASH0_FSR\t(FLASH_REG_BASE | 0x2010)\n\n#define FSR_PBUSY\t(0)\n#define FSR_FABUSY\t(1)\n#define FSR_PROG\t(4)\n#define FSR_ERASE\t(5)\n#define FSR_PFPAGE\t(6)\n#define FSR_PFOPER\t(8)\n#define FSR_SQER\t(10)\n#define FSR_PROER\t(11)\n#define FSR_PFSBER\t(12)\n#define FSR_PFDBER\t(14)\n#define FSR_PROIN\t(16)\n#define FSR_RPROIN\t(18)\n#define FSR_RPRODIS\t(19)\n#define FSR_WPROIN0\t(21)\n#define FSR_WPROIN1\t(22)\n#define FSR_WPROIN2\t(23)\n#define FSR_WPRODIS0\t(25)\n#define FSR_WPRODIS1\t(26)\n#define FSR_SLM\t\t(28)\n#define FSR_VER\t\t(31)\n\n#define FSR_PBUSY_MASK\t\t(0x01 << FSR_PBUSY)\n#define FSR_FABUSY_MASK\t\t(0x01 << FSR_FABUSY)\n#define FSR_PROG_MASK\t\t(0x01 << FSR_PROG)\n#define FSR_ERASE_MASK\t\t(0x01 << FSR_ERASE)\n#define FSR_PFPAGE_MASK\t\t(0x01 << FSR_PFPAGE)\n#define FSR_PFOPER_MASK\t\t(0x01 << FSR_PFOPER)\n#define FSR_SQER_MASK\t\t(0x01 << FSR_SQER)\n#define FSR_PROER_MASK\t\t(0x01 << FSR_PROER)\n#define FSR_PFSBER_MASK\t\t(0x01 << FSR_PFSBER)\n#define FSR_PFDBER_MASK\t\t(0x01 << FSR_PFDBER)\n#define FSR_PROIN_MASK\t\t(0x01 << FSR_PROIN)\n#define FSR_RPROIN_MASK\t\t(0x01 << FSR_RPROIN)\n#define FSR_RPRODIS_MASK\t(0x01 << FSR_RPRODIS)\n#define FSR_WPROIN0_MASK\t(0x01 << FSR_WPROIN0)\n#define FSR_WPROIN1_MASK\t(0x01 << FSR_WPROIN1)\n#define FSR_WPROIN2_MASK\t(0x01 << FSR_WPROIN2)\n#define FSR_WPRODIS0_MASK\t(0x01 << FSR_WPRODIS0)\n#define FSR_WPRODIS1_MASK\t(0x01 << FSR_WPRODIS1)\n#define FSR_SLM_MASK\t\t(0x01 << FSR_SLM)\n#define FSR_VER_MASK\t\t(0x01 << FSR_VER)\n\n/* Flash Config Register */\n#define FLASH_REG_FLASH0_FCON\t(FLASH_REG_BASE | 0x2014)\n\n#define FCON_WSPFLASH           (0)\n#define FCON_WSECPF             (4)\n#define FCON_IDLE               (13)\n#define FCON_ESLDIS             (14)\n#define FCON_SLEEP              (15)\n#define FCON_RPA                (16)\n#define FCON_DCF                (17)\n#define FCON_DDF                (18)\n#define FCON_VOPERM             (24)\n#define FCON_SQERM              (25)\n#define FCON_PROERM             (26)\n#define FCON_PFSBERM            (27)\n#define FCON_PFDBERM            (29)\n#define FCON_EOBM               (31)\n\n#define FCON_WSPFLASH_MASK      (0x0f << FCON_WSPFLASH)\n#define FCON_WSECPF_MASK        (0x01 << FCON_WSECPF)\n#define FCON_IDLE_MASK          (0x01 << FCON_IDLE)\n#define FCON_ESLDIS_MASK        (0x01 << FCON_ESLDIS)\n#define FCON_SLEEP_MASK         (0x01 << FCON_SLEEP)\n#define FCON_RPA_MASK           (0x01 << FCON_RPA)\n#define FCON_DCF_MASK           (0x01 << FCON_DCF)\n#define FCON_DDF_MASK           (0x01 << FCON_DDF)\n#define FCON_VOPERM_MASK        (0x01 << FCON_VOPERM)\n#define FCON_SQERM_MASK         (0x01 << FCON_SQERM)\n#define FCON_PROERM_MASK        (0x01 << FCON_PROERM)\n#define FCON_PFSBERM_MASK       (0x01 << FCON_PFSBERM)\n#define FCON_PFDBERM_MASK       (0x01 << FCON_PFDBERM)\n#define FCON_EOBM_MASK          (0x01 << FCON_EOBM)\n\n/* Flash Margin Control Register */\n#define FLASH_REG_FLASH0_MARP\t(FLASH_REG_BASE | 0x2018)\n\n#define MARP_MARGIN\t\t(0)\n#define MARP_TRAPDIS\t\t(15)\n\n#define MARP_MARGIN_MASK        (0x0f << MARP_MARGIN)\n#define MARP_TRAPDIS_MASK       (0x01 << MARP_TRAPDIS)\n\n/* Flash Protection Registers */\n#define FLASH_REG_FLASH0_PROCON0\t(FLASH_REG_BASE | 0x2020)\n#define FLASH_REG_FLASH0_PROCON1\t(FLASH_REG_BASE | 0x2024)\n#define FLASH_REG_FLASH0_PROCON2\t(FLASH_REG_BASE | 0x2028)\n\n#define PROCON_S0L             (0)\n#define PROCON_S1L             (1)\n#define PROCON_S2L             (2)\n#define PROCON_S3L             (3)\n#define PROCON_S4L             (4)\n#define PROCON_S5L             (5)\n#define PROCON_S6L             (6)\n#define PROCON_S7L             (7)\n#define PROCON_S8L             (8)\n#define PROCON_S9L             (9)\n#define PROCON_S10_S11L        (10)\n#define PROCON_RPRO            (15)\n\n#define PROCON_S0L_MASK        (0x01 << PROCON_S0L)\n#define PROCON_S1L_MASK        (0x01 << PROCON_S1L)\n#define PROCON_S2L_MASK        (0x01 << PROCON_S2L)\n#define PROCON_S3L_MASK        (0x01 << PROCON_S3L)\n#define PROCON_S4L_MASK        (0x01 << PROCON_S4L)\n#define PROCON_S5L_MASK        (0x01 << PROCON_S5L)\n#define PROCON_S6L_MASK        (0x01 << PROCON_S6L)\n#define PROCON_S7L_MASK        (0x01 << PROCON_S7L)\n#define PROCON_S8L_MASK        (0x01 << PROCON_S8L)\n#define PROCON_S9L_MASK        (0x01 << PROCON_S9L)\n#define PROCON_S10_S11L_MASK   (0x01 << PROCON_S10_S11L)\n#define PROCON_RPRO_MASK       (0x01 << PROCON_RPRO)\n\n#define FLASH_PROTECT_CONFIRMATION_CODE 0x8AFE15C3\n\n/* Flash controller configuration values */\n#define FLASH_ID_XMC4500        0xA2\n#define FLASH_ID_XMC4300_XMC4700_4800   0x92\n#define FLASH_ID_XMC4100_4200   0x9C\n#define FLASH_ID_XMC4400        0x9F\n\n/* Timeouts */\n#define FLASH_OP_TIMEOUT 5000\n\n/* Flash commands (write/erase/protect) are performed using special\n * command sequences that are written to magic addresses in the flash controller */\n/* Command sequence addresses.  See reference manual, section 8: Flash Command Sequences */\n#define FLASH_CMD_ERASE_1 0x0C005554\n#define FLASH_CMD_ERASE_2 0x0C00AAA8\n#define FLASH_CMD_ERASE_3 FLASH_CMD_ERASE_1\n#define FLASH_CMD_ERASE_4 FLASH_CMD_ERASE_1\n#define FLASH_CMD_ERASE_5 FLASH_CMD_ERASE_2\n/* ERASE_6 is the sector base address */\n\n#define FLASH_CMD_CLEAR_STATUS FLASH_CMD_ERASE_1\n\n#define FLASH_CMD_ENTER_PAGEMODE FLASH_CMD_ERASE_1\n\n#define FLASH_CMD_LOAD_PAGE_1 0x0C0055F0\n#define FLASH_CMD_LOAD_PAGE_2 0x0C0055F4\n\n#define FLASH_CMD_WRITE_PAGE_1 FLASH_CMD_ERASE_1\n#define FLASH_CMD_WRITE_PAGE_2 FLASH_CMD_ERASE_2\n#define FLASH_CMD_WRITE_PAGE_3 FLASH_CMD_ERASE_1\n/* WRITE_PAGE_4 is the page base address */\n\n#define FLASH_CMD_TEMP_UNPROT_1 FLASH_CMD_ERASE_1\n#define FLASH_CMD_TEMP_UNPROT_2 FLASH_CMD_ERASE_2\n#define FLASH_CMD_TEMP_UNPROT_3 0x0C00553C\n#define FLASH_CMD_TEMP_UNPROT_4 FLASH_CMD_ERASE_2\n#define FLASH_CMD_TEMP_UNPROT_5 FLASH_CMD_ERASE_2\n#define FLASH_CMD_TEMP_UNPROT_6 0x0C005558\n\nstruct xmc4xxx_flash_bank {\n\tbool probed;\n\n\t/* We need the flash controller ID to choose the sector layout */\n\tuint32_t fcon_id;\n\n\t/* Passwords used for protection operations */\n\tuint32_t pw1;\n\tuint32_t pw2;\n\tbool pw_set;\n\n\t/* Protection flags */\n\tbool read_protected;\n\n\tbool write_prot_otp[MAX_XMC_SECTORS];\n};\n\nstruct xmc4xxx_command_seq {\n\tuint32_t address;\n\tuint32_t magic;\n};\n\n/* Sector capacities.  See section 8 of xmc4x00_rm */\nstatic const unsigned int sector_capacity_8[8] = {\n\t16, 16, 16, 16, 16, 16, 16, 128\n};\n\nstatic const unsigned int sector_capacity_9[9] = {\n\t16, 16, 16, 16, 16, 16, 16, 128, 256\n};\n\nstatic const unsigned int sector_capacity_12[12] = {\n\t16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256\n};\n\nstatic const unsigned int sector_capacity_16[16] = {\n\t16, 16, 16, 16, 16, 16, 16, 16, 128, 256, 256, 256, 256, 256, 256, 256\n};\n\nstatic int xmc4xxx_write_command_sequence(struct flash_bank *bank,\n\t\t\t\t\t struct xmc4xxx_command_seq *seq,\n\t\t\t\t\t int seq_len)\n{\n\tint res = ERROR_OK;\n\n\tfor (int i = 0; i < seq_len; i++) {\n\t\tres = target_write_u32(bank->target, seq[i].address,\n\t\t\t\t       seq[i].magic);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_load_bank_layout(struct flash_bank *bank)\n{\n\tconst unsigned int *capacity = NULL;\n\n\t/* At this point, we know which flash controller ID we're\n\t * talking to and simply need to fill out the bank structure accordingly */\n\tLOG_DEBUG(\"%u sectors\", bank->num_sectors);\n\n\tswitch (bank->num_sectors) {\n\tcase 8:\n\t\tcapacity = sector_capacity_8;\n\t\tbreak;\n\tcase 9:\n\t\tcapacity = sector_capacity_9;\n\t\tbreak;\n\tcase 12:\n\t\tcapacity = sector_capacity_12;\n\t\tbreak;\n\tcase 16:\n\t\tcapacity = sector_capacity_16;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Unexpected number of sectors, %u\\n\",\n\t\t\t  bank->num_sectors);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* This looks like a bank that we understand, now we know the\n\t * corresponding sector capacities and we can add those up into the\n\t * bank size. */\n\tuint32_t total_offset = 0;\n\tbank->sectors = calloc(bank->num_sectors,\n\t\t\t       sizeof(struct flash_sector));\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].size = capacity[i] * 1024;\n\t\tbank->sectors[i].offset = total_offset;\n\t\tbank->sectors[i].is_erased = -1;\n\t\tbank->sectors[i].is_protected = -1;\n\n\t\tbank->size += bank->sectors[i].size;\n\t\tLOG_DEBUG(\"\\t%d: %uk\", i, capacity[i]);\n\t\ttotal_offset += bank->sectors[i].size;\n\t}\n\n\t/* This part doesn't follow the typical standard of 0xff\n\t * being the erased value.*/\n\tbank->default_padded_value = bank->erased_value = 0x00;\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_probe(struct flash_bank *bank)\n{\n\tint res;\n\tuint32_t devid, config;\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\tuint8_t flash_id;\n\n\tif (fb->probed)\n\t\treturn ERROR_OK;\n\n\t/* It's not possible for the DAP to access the OTP locations needed for\n\t * probing the part info and Flash geometry so we require that the target\n\t * be halted before proceeding. */\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The SCU registers contain the ID of the chip */\n\tres = target_read_u32(bank->target, SCU_REG_BASE + SCU_ID_CHIP, &devid);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read device identification register.\");\n\t\treturn res;\n\t}\n\n\t/* Make sure this is a XMC4000 family device */\n\tif ((devid & 0xF0000) != 0x40000 && devid != 0) {\n\t\tLOG_ERROR(\"Platform ID doesn't match XMC4xxx: 0x%08\" PRIx32, devid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Found XMC4xxx with devid: 0x%08\" PRIx32, devid);\n\n\t/* Now sanity-check the Flash controller itself. */\n\tres = target_read_u32(bank->target, FLASH_REG_FLASH0_ID,\n\t\t\t&config);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read Flash bank configuration.\");\n\t\treturn res;\n\t}\n\tflash_id = (config & 0xff0000) >> 16;\n\n\t/* The Flash configuration register is our only means of\n\t * determining the sector layout. We need to make sure that\n\t * we understand the type of controller we're dealing with */\n\tswitch (flash_id) {\n\tcase FLASH_ID_XMC4100_4200:\n\t\tbank->num_sectors = 8;\n\t\tLOG_DEBUG(\"XMC4xxx: XMC4100/4200 detected.\");\n\t\tbreak;\n\tcase FLASH_ID_XMC4400:\n\t\tbank->num_sectors = 9;\n\t\tLOG_DEBUG(\"XMC4xxx: XMC4400 detected.\");\n\t\tbreak;\n\tcase FLASH_ID_XMC4500:\n\t\tbank->num_sectors = 12;\n\t\tLOG_DEBUG(\"XMC4xxx: XMC4500 detected.\");\n\t\tbreak;\n\tcase FLASH_ID_XMC4300_XMC4700_4800:\n\t\tbank->num_sectors = 16;\n\t\tLOG_DEBUG(\"XMC4xxx: XMC4700/4800 detected.\");\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"XMC4xxx: Unexpected flash ID. got %02\" PRIx8,\n\t\t\t  flash_id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Retrieve information about the particular bank we're probing and fill in\n\t * the bank structure accordingly. */\n\tres = xmc4xxx_load_bank_layout(bank);\n\tif (res == ERROR_OK) {\n\t\t/* We're done */\n\t\tfb->probed = true;\n\t} else {\n\t\tLOG_ERROR(\"Unable to load bank information.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_get_sector_start_addr(struct flash_bank *bank,\n\t\tunsigned int sector, uint32_t *ret_addr)\n{\n\t/* Make sure we understand this sector */\n\tif (sector > bank->num_sectors)\n\t\treturn ERROR_FAIL;\n\n\t*ret_addr = bank->base + bank->sectors[sector].offset;\n\n\treturn ERROR_OK;\n\n}\n\nstatic int xmc4xxx_clear_flash_status(struct flash_bank *bank)\n{\n\tint res;\n\t/* TODO: Do we need to check for sequence error? */\n\tLOG_INFO(\"Clearing flash status\");\n\tres = target_write_u32(bank->target, FLASH_CMD_CLEAR_STATUS,\n\t\t\t       0xF5);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write erase command sequence\");\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_get_flash_status(struct flash_bank *bank, uint32_t *status)\n{\n\tint res;\n\n\tres = target_read_u32(bank->target, FLASH_REG_FLASH0_FSR, status);\n\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Cannot read flash status register.\");\n\n\treturn res;\n}\n\nstatic int xmc4xxx_wait_status_busy(struct flash_bank *bank, int timeout)\n{\n\tint res;\n\tuint32_t status;\n\n\tres = xmc4xxx_get_flash_status(bank, &status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* While the flash controller is busy, wait */\n\twhile (status & FSR_PBUSY_MASK) {\n\t\tres = xmc4xxx_get_flash_status(bank, &status);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tif (timeout-- <= 0) {\n\t\t\tLOG_ERROR(\"Timed out waiting for flash\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\talive_sleep(1);\n\t\tkeep_alive();\n\t}\n\n\tif (status & FSR_PROER_MASK) {\n\t\tLOG_ERROR(\"XMC4xxx flash protected\");\n\t\tres = ERROR_FAIL;\n\t}\n\n\treturn res;\n}\n\nstatic int xmc4xxx_erase_sector(struct flash_bank *bank, uint32_t address,\n\t\t\t\tbool user_config)\n{\n\tint res;\n\tuint32_t status;\n\n\t/* See reference manual table 8.4: Command Sequences for Flash Control */\n\tstruct xmc4xxx_command_seq erase_cmd_seq[6] = {\n\t\t{FLASH_CMD_ERASE_1, 0xAA},\n\t\t{FLASH_CMD_ERASE_2, 0x55},\n\t\t{FLASH_CMD_ERASE_3, 0x80},\n\t\t{FLASH_CMD_ERASE_4, 0xAA},\n\t\t{FLASH_CMD_ERASE_5, 0x55},\n\t\t{0xFF,              0xFF} /* Needs filled in */\n\t};\n\n\t/* We need to fill in the base address of the sector we'll be\n\t * erasing, as well as the magic code that determines whether\n\t * this is a standard flash sector or a user configuration block */\n\n\terase_cmd_seq[5].address = address;\n\tif (user_config) {\n\t\t/* Removing flash protection requires the addition of\n\t\t * the base address */\n\t\terase_cmd_seq[5].address += bank->base;\n\t\terase_cmd_seq[5].magic = 0xC0;\n\t} else {\n\t\terase_cmd_seq[5].magic = 0x30;\n\t}\n\n\tres = xmc4xxx_write_command_sequence(bank, erase_cmd_seq,\n\t\t\t\t\t     ARRAY_SIZE(erase_cmd_seq));\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Read the flash status register */\n\tres = target_read_u32(bank->target, FLASH_REG_FLASH0_FSR, &status);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read flash status register.\");\n\t\treturn res;\n\t}\n\n\t/* Check for a sequence error */\n\tif (status & FSR_SQER_MASK) {\n\t\tLOG_ERROR(\"Error with flash erase sequence\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Make sure a flash erase was triggered */\n\tif (!(status & FSR_ERASE_MASK)) {\n\t\tLOG_ERROR(\"Flash failed to erase\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Now we must wait for the erase operation to end */\n\tres = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT);\n\n\treturn res;\n}\n\nstatic int xmc4xxx_erase(struct flash_bank *bank, unsigned int first,\n\t\tunsigned int last)\n{\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\tint res;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Unable to erase, target is not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!fb->probed) {\n\t\tres = xmc4xxx_probe(bank);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\tuint32_t tmp_addr;\n\t/* Loop through the sectors and erase each one */\n\tfor (unsigned int i = first; i <= last; i++) {\n\t\tres = xmc4xxx_get_sector_start_addr(bank, i, &tmp_addr);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Invalid sector %u\", i);\n\t\t\treturn res;\n\t\t}\n\n\t\tLOG_DEBUG(\"Erasing sector %u @ 0x%08\"PRIx32, i, tmp_addr);\n\n\t\tres = xmc4xxx_erase_sector(bank, tmp_addr, false);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write erase command sequence\");\n\t\t\tgoto clear_status_and_exit;\n\t\t}\n\n\t\t/* Now we must wait for the erase operation to end */\n\t\tres = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT);\n\n\t\tif (res != ERROR_OK)\n\t\t\tgoto clear_status_and_exit;\n\t}\n\nclear_status_and_exit:\n\tres = xmc4xxx_clear_flash_status(bank);\n\treturn res;\n\n}\n\nstatic int xmc4xxx_enter_page_mode(struct flash_bank *bank)\n{\n\tint res;\n\tuint32_t status;\n\n\tres = target_write_u32(bank->target, FLASH_CMD_ENTER_PAGEMODE, 0x50);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write enter page mode command\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = xmc4xxx_get_flash_status(bank, &status);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Make sure we're in page mode */\n\tif (!(status & FSR_PFPAGE_MASK)) {\n\t\tLOG_ERROR(\"Unable to enter page mode\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Make sure we didn't encounter a sequence error */\n\tif (status & FSR_SQER_MASK) {\n\t\tLOG_ERROR(\"Sequence error while entering page mode\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn res;\n}\n\nstatic int xmc4xxx_write_page(struct flash_bank *bank, const uint8_t *pg_buf,\n\t\t\t      uint32_t offset, bool user_config)\n{\n\tint res;\n\tuint32_t status;\n\n\t/* Base of the flash write command */\n\tstruct xmc4xxx_command_seq write_cmd_seq[4] = {\n\t\t{FLASH_CMD_WRITE_PAGE_1, 0xAA},\n\t\t{FLASH_CMD_WRITE_PAGE_2, 0x55},\n\t\t{FLASH_CMD_WRITE_PAGE_3, 0xFF}, /* Needs filled in */\n\t\t{0xFF,                   0xFF}\t/* Needs filled in */\n\t};\n\n\t/* The command sequence differs depending on whether this is\n\t * being written to standard flash or the user configuration\n\t * area */\n\tif (user_config)\n\t\twrite_cmd_seq[2].magic = 0xC0;\n\telse\n\t\twrite_cmd_seq[2].magic = 0xA0;\n\n\t/* Finally, we need to add the address that this page will be\n\t * written to */\n\twrite_cmd_seq[3].address = bank->base + offset;\n\twrite_cmd_seq[3].magic = 0xAA;\n\n\n\t/* Flash pages are written 256 bytes at a time.  For each 256\n\t * byte chunk, we need to:\n\t * 1. Enter page mode. This activates the flash write buffer\n\t * 2. Load the page buffer with data (2x 32 bit words at a time)\n\t * 3. Burn the page buffer into its intended location\n\t * If the starting offset is not on a 256 byte boundary, we\n\t * will need to pad the beginning of the write buffer\n\t * accordingly. Likewise, if the last page does not fill the\n\t * buffer, we should pad it to avoid leftover data from being\n\t * written to flash\n\t */\n\tres = xmc4xxx_enter_page_mode(bank);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Copy the data into the page buffer*/\n\tfor (int i = 0; i < 256; i += 8) {\n\t\tuint32_t w_lo = target_buffer_get_u32(bank->target, &pg_buf[i]);\n\t\tuint32_t w_hi = target_buffer_get_u32(bank->target, &pg_buf[i + 4]);\n\t\tLOG_DEBUG(\"WLO: %08\"PRIx32, w_lo);\n\t\tLOG_DEBUG(\"WHI: %08\"PRIx32, w_hi);\n\n\t\t/* Data is loaded 2x 32 bit words at a time */\n\t\tres = target_write_u32(bank->target, FLASH_CMD_LOAD_PAGE_1, w_lo);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tres = target_write_u32(bank->target, FLASH_CMD_LOAD_PAGE_2, w_hi);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\t/* Check for an error */\n\t\tres = xmc4xxx_get_flash_status(bank, &status);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tif (status & FSR_SQER_MASK) {\n\t\t\tLOG_ERROR(\"Error loading page buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* The page buffer is now full, time to commit it to flash */\n\n\tres = xmc4xxx_write_command_sequence(bank, write_cmd_seq, ARRAY_SIZE(write_cmd_seq));\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to enter write command sequence\");\n\t\treturn res;\n\t}\n\n\t/* Read the flash status register */\n\tres = xmc4xxx_get_flash_status(bank, &status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* Check for a sequence error */\n\tif (status & FSR_SQER_MASK) {\n\t\tLOG_ERROR(\"Error with flash write sequence\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Make sure a flash write was triggered */\n\tif (!(status & FSR_PROG_MASK)) {\n\t\tLOG_ERROR(\"Failed to write flash page\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Wait for the write operation to end */\n\tres = xmc4xxx_wait_status_busy(bank, FLASH_OP_TIMEOUT);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* TODO: Verify that page was written without error */\n\treturn res;\n}\n\nstatic int xmc4xxx_write(struct flash_bank *bank, const uint8_t *buffer,\n\t\t\t uint32_t offset, uint32_t count)\n{\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\tint res = ERROR_OK;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Unable to erase, target is not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!fb->probed) {\n\t\tres = xmc4xxx_probe(bank);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\t/* Make sure we won't run off the end of the flash bank */\n\tif ((offset + count) > (bank->size)) {\n\t\tLOG_ERROR(\"Attempting to write past the end of flash\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\n\t/* Attempt to write the passed in buffer to flash */\n\t/* Pages are written 256 bytes at a time, we need to handle\n\t * scenarios where padding is required at the beginning and\n\t * end of a page */\n\twhile (count) {\n\t\t/* page working area */\n\t\tuint8_t tmp_buf[256] = {0};\n\n\t\t/* Amount of data we'll be writing to this page */\n\t\tint remaining;\n\t\tint end_pad;\n\n\t\tremaining = MIN(count, sizeof(tmp_buf));\n\t\tend_pad   = sizeof(tmp_buf) - remaining;\n\n\t\t/* Make sure we're starting on a page boundary */\n\t\tint start_pad = offset % 256;\n\t\tif (start_pad) {\n\t\t\tLOG_INFO(\"Write does not start on a 256 byte boundary. \"\n\t\t\t\t \"Padding by %d bytes\", start_pad);\n\t\t\tmemset(tmp_buf, 0xff, start_pad);\n\t\t\t/* Subtract the amount of start offset from\n\t\t\t * the amount of data we'll need to write */\n\t\t\tremaining -= start_pad;\n\t\t}\n\n\t\t/* Remove the amount we'll be writing from the total count */\n\t\tcount -= remaining;\n\n\t\t/* Now copy in the remaining data */\n\t\tmemcpy(&tmp_buf[start_pad], buffer, remaining);\n\n\t\tif (end_pad) {\n\t\t\tLOG_INFO(\"Padding end of page @\" TARGET_ADDR_FMT \" by %d bytes\",\n\t\t\t\t bank->base + offset, end_pad);\n\t\t\tmemset(&tmp_buf[256 - end_pad], 0xff, end_pad);\n\t\t}\n\n\t\t/* Now commit this page to flash, if there was start\n\t\t * padding, we should subtract that from the target offset */\n\t\tres = xmc4xxx_write_page(bank, tmp_buf, (offset - start_pad), false);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to write flash page\");\n\t\t\tgoto abort_write_and_exit;\n\t\t}\n\n\t\t/* Advance the buffer pointer */\n\t\tbuffer += remaining;\n\n\t\t/* Advance the offset */\n\t\toffset += remaining;\n\t}\n\nabort_write_and_exit:\n\txmc4xxx_clear_flash_status(bank);\n\treturn res;\n\n}\n\nstatic int xmc4xxx_get_info_command(struct flash_bank *bank, struct command_invocation *cmd)\n{\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\tuint32_t scu_idcode;\n\n\tif (bank->target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Cannot communicate... target not halted.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* The SCU registers contain the ID of the chip */\n\tint res = target_read_u32(bank->target, SCU_REG_BASE + SCU_ID_CHIP, &scu_idcode);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot read device identification register.\");\n\t\treturn res;\n\t}\n\n\tuint16_t dev_id = (scu_idcode & 0xfff0) >> 4;\n\tuint16_t rev_id = scu_idcode & 0xf;\n\tconst char *dev_str;\n\tconst char *rev_str = NULL;\n\n\tswitch (dev_id) {\n\tcase 0x100:\n\t\tdev_str = \"XMC4100\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"AA\";\n\t\t\tbreak;\n\t\tcase 0x2:\n\t\t\trev_str = \"AB\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0x200:\n\t\tdev_str = \"XMC4200\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"AA\";\n\t\t\tbreak;\n\t\tcase 0x2:\n\t\t\trev_str = \"AB\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0x300:\n\t\tdev_str = \"XMC4300\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"AA\";\n\t\t}\n\t\tbreak;\n\tcase 0x400:\n\t\tdev_str = \"XMC4400\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"AA\";\n\t\t\tbreak;\n\t\tcase 0x2:\n\t\t\trev_str = \"AB\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0:\n\t\t/* XMC4500 EES AA13 with date codes before GE212\n\t\t * had zero SCU_IDCHIP\n\t\t */\n\t\tdev_str = \"XMC4500 EES\";\n\t\trev_str = \"AA13\";\n\t\tbreak;\n\tcase 0x500:\n\t\tdev_str = \"XMC4500\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x2:\n\t\t\trev_str = \"AA\";\n\t\t\tbreak;\n\t\tcase 0x3:\n\t\t\trev_str = \"AB\";\n\t\t\tbreak;\n\t\tcase 0x4:\n\t\t\trev_str = \"AC\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0x700:\n\t\tdev_str = \"XMC4700\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"EES-AA\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 0x800:\n\t\tdev_str = \"XMC4800\";\n\n\t\tswitch (rev_id) {\n\t\tcase 0x1:\n\t\t\trev_str = \"EES-AA\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tcommand_print_sameline(cmd, \"Cannot identify target as an XMC4xxx. SCU_ID: %\"PRIx32 \"\\n\", scu_idcode);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* String to declare protection data held in the private driver */\n\tchar prot_str[512] = {0};\n\tif (fb->read_protected)\n\t\tsnprintf(prot_str, sizeof(prot_str), \"\\nFlash is read protected\");\n\n\tbool otp_enabled = false;\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++)\n\t\tif (fb->write_prot_otp[i])\n\t\t\totp_enabled = true;\n\n\t/* If OTP Write protection is enabled (User 2), list each\n\t * sector that has it enabled */\n\tchar otp_str[14];\n\tif (otp_enabled) {\n\t\tstrcat(prot_str, \"\\nOTP Protection is enabled for sectors:\\n\");\n\t\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\t\tif (fb->write_prot_otp[i]) {\n\t\t\t\tsnprintf(otp_str, sizeof(otp_str), \"- %d\\n\", i);\n\t\t\t\tstrncat(prot_str, otp_str, sizeof(prot_str) - strlen(prot_str) - 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (rev_str)\n\t\tcommand_print_sameline(cmd, \"%s - Rev: %s%s\", dev_str, rev_str, prot_str);\n\telse\n\t\tcommand_print_sameline(cmd, \"%s - Rev: unknown (0x%01x)%s\", dev_str, rev_id, prot_str);\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_temp_unprotect(struct flash_bank *bank, int user_level)\n{\n\tstruct xmc4xxx_flash_bank *fb;\n\tint res = ERROR_OK;\n\tuint32_t status = 0;\n\n\tstruct xmc4xxx_command_seq temp_unprot_seq[6] = {\n\t\t{FLASH_CMD_TEMP_UNPROT_1, 0xAA},\n\t\t{FLASH_CMD_TEMP_UNPROT_2, 0x55},\n\t\t{FLASH_CMD_TEMP_UNPROT_3, 0xFF}, /* Needs filled in */\n\t\t{FLASH_CMD_TEMP_UNPROT_4, 0xFF}, /* Needs filled in */\n\t\t{FLASH_CMD_TEMP_UNPROT_5, 0xFF}, /* Needs filled in */\n\t\t{FLASH_CMD_TEMP_UNPROT_6, 0x05}\n\t};\n\n\tif (user_level < 0 || user_level > 2) {\n\t\tLOG_ERROR(\"Invalid user level, must be 0-2\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfb = bank->driver_priv;\n\n\t/* Fill in the user level and passwords */\n\ttemp_unprot_seq[2].magic = user_level;\n\ttemp_unprot_seq[3].magic = fb->pw1;\n\ttemp_unprot_seq[4].magic = fb->pw2;\n\n\tres = xmc4xxx_write_command_sequence(bank, temp_unprot_seq,\n\t\t\t\t\t     ARRAY_SIZE(temp_unprot_seq));\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write temp unprotect sequence\");\n\t\treturn res;\n\t}\n\n\tres = xmc4xxx_get_flash_status(bank, &status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (status & FSR_WPRODIS0) {\n\t\tLOG_INFO(\"Flash is temporarily unprotected\");\n\t} else {\n\t\tLOG_INFO(\"Unable to disable flash protection\");\n\t\tres = ERROR_FAIL;\n\t}\n\n\n\treturn res;\n}\n\nstatic int xmc4xxx_flash_unprotect(struct flash_bank *bank, int32_t level)\n{\n\tuint32_t addr;\n\tint res;\n\n\tswitch (level) {\n\tcase 0:\n\t\taddr = UCB0_BASE;\n\t\tbreak;\n\tcase 1:\n\t\taddr = UCB1_BASE;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Invalid user level. Must be 0-1\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = xmc4xxx_erase_sector(bank, addr, true);\n\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Error erasing user configuration block\");\n\n\treturn res;\n}\n\n/* Reference: \"XMC4500 Flash Protection.pptx\" app note */\nstatic int xmc4xxx_flash_protect(struct flash_bank *bank, int level, bool read_protect,\n\t\tunsigned int first, unsigned int last)\n{\n\t/* User configuration block buffers */\n\tuint8_t ucp0_buf[8 * sizeof(uint32_t)] = {0};\n\tuint32_t ucb_base = 0;\n\tuint32_t procon = 0;\n\tint res = ERROR_OK;\n\tuint32_t status = 0;\n\tbool proin = false;\n\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\n\t/* Read protect only works for user 0, make sure we don't try\n\t * to do something silly */\n\tif (level != 0 && read_protect) {\n\t\tLOG_ERROR(\"Read protection is for user level 0 only!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check to see if protection is already installed for the\n\t * specified user level.  If it is, the user configuration\n\t * block will need to be erased before we can continue */\n\n\t/* Grab the flash status register*/\n\tres = xmc4xxx_get_flash_status(bank, &status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tswitch (level) {\n\tcase 0:\n\t\tif ((status & FSR_RPROIN_MASK) || (status & FSR_WPROIN0_MASK))\n\t\t\tproin = true;\n\t\tbreak;\n\tcase 1:\n\t\tif (status & FSR_WPROIN1_MASK)\n\t\t\tproin = true;\n\t\tbreak;\n\tcase 2:\n\t\tif (status & FSR_WPROIN2_MASK)\n\t\t\tproin = true;\n\t\tbreak;\n\t}\n\n\tif (proin) {\n\t\tLOG_ERROR(\"Flash protection is installed for user %d\"\n\t\t\t  \" and must be removed before continuing\", level);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* If this device has 12 flash sectors, protection for\n\t * sectors 10 & 11 are handled jointly. If we are trying to\n\t * write all sectors, we should decrement\n\t * last to ensure we don't write to a register bit that\n\t * doesn't exist*/\n\tif ((bank->num_sectors == 12) && (last == 12))\n\t\tlast--;\n\n\t/*  We need to fill out the procon register representation\n\t *   that we will be writing to the device */\n\tfor (unsigned int i = first; i <= last; i++)\n\t\tprocon |= 1 << i;\n\n\t/* If read protection is requested, set the appropriate bit\n\t * (we checked that this is allowed above) */\n\tif (read_protect)\n\t\tprocon |= PROCON_RPRO_MASK;\n\n\tLOG_DEBUG(\"Setting flash protection with procon:\");\n\tLOG_DEBUG(\"PROCON: %\"PRIx32, procon);\n\n\t/* First we need to copy in the procon register to the buffer\n\t * we're going to attempt to write.  This is written twice */\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[0 * 4], procon);\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[2 * 4], procon);\n\n\t/* Now we must copy in both flash passwords.  As with the\n\t * procon data, this must be written twice (4 total words\n\t * worth of data) */\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[4 * 4], fb->pw1);\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[5 * 4], fb->pw2);\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[6 * 4], fb->pw1);\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[7 * 4], fb->pw2);\n\n\t/* Finally, (if requested) we copy in the confirmation\n\t * code so that the protection is permanent and will\n\t * require a password to undo. */\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[0 * 4], FLASH_PROTECT_CONFIRMATION_CODE);\n\ttarget_buffer_set_u32(bank->target, &ucp0_buf[2 * 4], FLASH_PROTECT_CONFIRMATION_CODE);\n\n\t/* Now that the data is copied into place, we must write\n\t * these pages into flash */\n\n\t/* The user configuration block base depends on what level of\n\t * protection we're trying to install, select the proper one */\n\tswitch (level) {\n\tcase 0:\n\t\tucb_base = UCB0_BASE;\n\t\tbreak;\n\tcase 1:\n\t\tucb_base = UCB1_BASE;\n\t\tbreak;\n\tcase 2:\n\t\tucb_base = UCB2_BASE;\n\t\tbreak;\n\t}\n\n\t/* Write the user config pages */\n\tres = xmc4xxx_write_page(bank, ucp0_buf, ucb_base, true);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Error writing user configuration block 0\");\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xmc4xxx_protect(struct flash_bank *bank, int set, unsigned int first,\n\t\tunsigned int last)\n{\n\tint ret;\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\n\t/* Check for flash passwords */\n\tif (!fb->pw_set) {\n\t\tLOG_ERROR(\"Flash passwords not set, use xmc4xxx flash_password to set them\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* We want to clear flash protection temporarily*/\n\tif (set == 0) {\n\t\tLOG_WARNING(\"Flash protection will be temporarily disabled\"\n\t\t\t    \" for all pages (User 0 only)!\");\n\t\tret = xmc4xxx_temp_unprotect(bank, 0);\n\t\treturn ret;\n\t}\n\n\t/* Install write protection for user 0 on the specified pages */\n\tret = xmc4xxx_flash_protect(bank, 0, false, first, last);\n\n\treturn ret;\n}\n\nstatic int xmc4xxx_protect_check(struct flash_bank *bank)\n{\n\tint ret;\n\tuint32_t protection[3] = {0};\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\n\tret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON0, &protection[0]);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to read flash User0 protection register\");\n\t\treturn ret;\n\t}\n\n\tret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON1, &protection[1]);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to read flash User1 protection register\");\n\t\treturn ret;\n\t}\n\n\tret = target_read_u32(bank->target, FLASH_REG_FLASH0_PROCON2, &protection[2]);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to read flash User2 protection register\");\n\t\treturn ret;\n\t}\n\n\tunsigned int sectors = bank->num_sectors;\n\n\t/* On devices with 12 sectors, sectors 10 & 11 are protected\n\t * together instead of individually */\n\tif (sectors == 12)\n\t\tsectors--;\n\n\t/* Clear the protection status */\n\tfor (unsigned int i = 0; i < bank->num_sectors; i++) {\n\t\tbank->sectors[i].is_protected = 0;\n\t\tfb->write_prot_otp[i] = false;\n\t}\n\tfb->read_protected = false;\n\n\t/* The xmc4xxx series supports 3 levels of user protection\n\t * (User0, User1 (low priority), and User 2(OTP), we need to\n\t * check all 3 */\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(protection); i++) {\n\n\t\t/* Check for write protection on every available\n\t\t*  sector */\n\t\tfor (unsigned int j = 0; j < sectors; j++) {\n\t\t\tint set = (protection[i] & (1 << j)) ? 1 : 0;\n\t\t\tbank->sectors[j].is_protected |= set;\n\n\t\t\t/* Handle sector 11 */\n\t\t\tif (j == 10)\n\t\t\t\tbank->sectors[j + 1].is_protected |= set;\n\n\t\t\t/* User 2 indicates this protection is\n\t\t\t * permanent, make note in the private driver structure */\n\t\t\tif (i == 2 && set) {\n\t\t\t\tfb->write_prot_otp[j] = true;\n\n\t\t\t\t/* Handle sector 11 */\n\t\t\t\tif (j == 10)\n\t\t\t\t\tfb->write_prot_otp[j + 1] = true;\n\t\t\t}\n\n\t\t}\n\t}\n\n\t/* XMC4xxx also supports read protection, make a note\n\t * in the private driver structure */\n\tif (protection[0] & PROCON_RPRO_MASK)\n\t\tfb->read_protected = true;\n\n\treturn ERROR_OK;\n}\n\nFLASH_BANK_COMMAND_HANDLER(xmc4xxx_flash_bank_command)\n{\n\tbank->driver_priv = malloc(sizeof(struct xmc4xxx_flash_bank));\n\n\tif (!bank->driver_priv)\n\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\n\t(void)memset(bank->driver_priv, 0, sizeof(struct xmc4xxx_flash_bank));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xmc4xxx_handle_flash_password_command)\n{\n\tint res;\n\tstruct flash_bank *bank;\n\n\tif (CMD_ARGC < 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tres = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tstruct xmc4xxx_flash_bank *fb = bank->driver_priv;\n\n\terrno = 0;\n\n\t/* We skip over the flash bank */\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], fb->pw1);\n\n\tif (errno)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], fb->pw2);\n\n\tif (errno)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfb->pw_set = true;\n\n\tcommand_print(CMD, \"XMC4xxx flash passwords set to:\\n\");\n\tcommand_print(CMD, \"-0x%08\"PRIx32\"\\n\", fb->pw1);\n\tcommand_print(CMD, \"-0x%08\"PRIx32\"\\n\", fb->pw2);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xmc4xxx_handle_flash_unprotect_command)\n{\n\tstruct flash_bank *bank;\n\tint res;\n\tint32_t level;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tres = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tCOMMAND_PARSE_NUMBER(s32, CMD_ARGV[1], level);\n\n\tres = xmc4xxx_flash_unprotect(bank, level);\n\n\treturn res;\n}\n\nstatic const struct command_registration xmc4xxx_exec_command_handlers[] = {\n\t{\n\t\t.name = \"flash_password\",\n\t\t.handler = xmc4xxx_handle_flash_password_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id password1 password2\",\n\t\t.help = \"Set the flash passwords used for protect operations. \"\n\t\t\"Passwords should be in standard hex form (0x00000000). \"\n\t\t\"(You must call this before any other protect commands) \"\n\t\t\"NOTE: The xmc4xxx's UCB area only allows for FOUR cycles. \"\n\t\t\"Please use protection carefully!\",\n\t},\n\t{\n\t\t.name = \"flash_unprotect\",\n\t\t.handler = xmc4xxx_handle_flash_unprotect_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"bank_id user_level[0-1]\",\n\t\t.help = \"Permanently Removes flash protection (read and write) \"\n\t\t\"for the specified user level\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration xmc4xxx_command_handlers[] = {\n\t{\n\t\t.name = \"xmc4xxx\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"xmc4xxx flash command group\",\n\t\t.usage = \"\",\n\t\t.chain = xmc4xxx_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct flash_driver xmc4xxx_flash = {\n\t.name = \"xmc4xxx\",\n\t.commands = xmc4xxx_command_handlers,\n\t.flash_bank_command = xmc4xxx_flash_bank_command,\n\t.erase = xmc4xxx_erase,\n\t.write = xmc4xxx_write,\n\t.read = default_flash_read,\n\t.probe = xmc4xxx_probe,\n\t.auto_probe = xmc4xxx_probe,\n\t.erase_check = default_flash_blank_check,\n\t.info = xmc4xxx_get_info_command,\n\t.protect_check = xmc4xxx_protect_check,\n\t.protect = xmc4xxx_protect,\n\t.free_driver_priv = default_flash_free_driver_priv,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/flash/startup.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Defines basic Tcl procs for OpenOCD flash module\n\n#\n# program utility proc\n# usage: program filename\n# optional args: verify, reset, exit and address\n#\n\nlappend _telnet_autocomplete_skip program_error\nproc program_error {description exit} {\n\tif {$exit == 1} {\n\t\techo $description\n\t\tshutdown error\n\t}\n\n\terror $description\n}\n\nproc program {filename args} {\n\tset exit 0\n\tset needsflash 1\n\n\tforeach arg $args {\n\t\tif {[string equal $arg \"preverify\"]} {\n\t\t\tset preverify 1\n\t\t} elseif {[string equal $arg \"verify\"]} {\n\t\t\tset verify 1\n\t\t} elseif {[string equal $arg \"reset\"]} {\n\t\t\tset reset 1\n\t\t} elseif {[string equal $arg \"exit\"]} {\n\t\t\tset exit 1\n\t\t} else {\n\t\t\tset address $arg\n\t\t}\n\t}\n\n\t# Set variables\n\tset filename \\{$filename\\}\n\tif {[info exists address]} {\n\t\tset flash_args \"$filename $address\"\n\t} else {\n\t\tset flash_args \"$filename\"\n\t}\n\n\n\t# make sure init is called\n\tif {[catch {init}] != 0} {\n\t\tprogram_error \"** OpenOCD init failed **\" 1\n\t}\n\n\t# reset target and call any init scripts\n\tif {[catch {reset init}] != 0} {\n\t\tprogram_error \"** Unable to reset target **\" $exit\n\t}\n\n\t# Check whether programming is needed\n\tif {[info exists preverify]} {\n\t\techo \"**pre-verifying**\"\n\t\tif {[catch {eval verify_image $flash_args}] == 0} {\n\t\t\techo \"**Verified OK - No flashing**\"\n\t\t\tset needsflash 0\n\t\t}\n\t}\n\n\t# start programming phase\n\tif {$needsflash == 1} {\n\t\techo \"** Programming Started **\"\n\n\t\tif {[catch {eval flash write_image erase $flash_args}] == 0} {\n\t\t\techo \"** Programming Finished **\"\n\t\t\tif {[info exists verify]} {\n\t\t\t\t# verify phase\n\t\t\t\techo \"** Verify Started **\"\n\t\t\t\tif {[catch {eval verify_image $flash_args}] == 0} {\n\t\t\t\t\techo \"** Verified OK **\"\n\t\t\t\t} else {\n\t\t\t\t\tprogram_error \"** Verify Failed **\" $exit\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tprogram_error \"** Programming Failed **\" $exit\n\t\t}\n\t}\n\n\tif {[info exists reset]} {\n\t\t# reset target if requested\n\t\tif {$exit == 1} {\n\t\t\t# also disable target polling, we are shutting down anyway\n\t\t\tpoll off\n\t\t}\n\t\techo \"** Resetting Target **\"\n\t\treset run\n\t}\n\n\n\tif {$exit == 1} {\n\t\tshutdown\n\t}\n\treturn\n}\n\nadd_help_text program \"write an image to flash, address is only required for binary images. verify, reset, exit are optional\"\nadd_usage_text program \"<filename> \\[address\\] \\[pre-verify\\] \\[verify\\] \\[reset\\] \\[exit\\]\"\n\n# stm32[f0x|f3x] uses the same flash driver as the stm32f1x\nproc stm32f0x args { eval stm32f1x $args }\nproc stm32f3x args { eval stm32f1x $args }\n\n# stm32[f4x|f7x] uses the same flash driver as the stm32f2x\nproc stm32f4x args { eval stm32f2x $args }\nproc stm32f7x args { eval stm32f2x $args }\n\n# stm32lx driver supports both STM32 L0 and L1 devices\nproc stm32l0x args { eval stm32lx $args }\nproc stm32l1x args { eval stm32lx $args }\n\n# stm32[g0|g4|l5|u5|wb|wl] uses the same flash driver as the stm32l4x\nproc stm32g0x args { eval stm32l4x $args }\nproc stm32g4x args { eval stm32l4x $args }\nproc stm32l5x args { eval stm32l4x $args }\nproc stm32u5x args { eval stm32l4x $args }\nproc stm32wbx args { eval stm32l4x $args }\nproc stm32wlx args { eval stm32l4x $args }\n\n# gd32e23x uses the same flash driver as the stm32f1x\nproc gd32e23x args { eval stm32f1x $args }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/hello.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include <helper/log.h>\n#include \"hello.h\"\n\nCOMMAND_HANDLER(handle_foo_command)\n{\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t address;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\n\tconst char *msg = \"<unchanged>\";\n\tif (CMD_ARGC == 2) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[1], enable);\n\t\tmsg = enable ? \"enable\" : \"disable\";\n\t}\n\n\tLOG_INFO(\"%s: address=0x%8.8\" PRIx32 \" enabled=%s\", CMD_NAME, address, msg);\n\treturn ERROR_OK;\n}\n\nstatic bool foo_flag;\n\nCOMMAND_HANDLER(handle_flag_command)\n{\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t&foo_flag, \"foo flag\");\n}\n\nstatic const struct command_registration foo_command_handlers[] = {\n\t{\n\t\t.name = \"bar\",\n\t\t.handler = &handle_foo_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"address ['enable'|'disable']\",\n\t\t.help = \"an example command\",\n\t},\n\t{\n\t\t.name = \"baz\",\n\t\t.handler = &handle_foo_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"address ['enable'|'disable']\",\n\t\t.help = \"a sample command\",\n\t},\n\t{\n\t\t.name = \"flag\",\n\t\t.handler = &handle_flag_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[on|off]\",\n\t\t.help = \"set a flag\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic COMMAND_HELPER(handle_hello_args, const char **sep, const char **name)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (1 == CMD_ARGC) {\n\t\t*sep = \" \";\n\t\t*name = CMD_ARGV[0];\n\t} else\n\t\t*sep = *name = \"\";\n\n\treturn ERROR_OK;\n}\nCOMMAND_HANDLER(handle_hello_command)\n{\n\tconst char *sep, *name;\n\tint retval = CALL_COMMAND_HANDLER(handle_hello_args, &sep, &name);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"Greetings%s%s!\", sep, name);\n\treturn retval;\n}\n\nconst struct command_registration hello_command_handlers[] = {\n\t{\n\t\t.name = \"hello\",\n\t\t.handler = handle_hello_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"prints a warm welcome\",\n\t\t.usage = \"[name]\",\n\t},\n\t{\n\t\t.name = \"foo\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"example command handler skeleton\",\n\t\t.chain = foo_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/hello.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELLO_H\n#define OPENOCD_HELLO_H\n\nstruct command_registration;\n\n/**\n * Export the registration for the hello command group, so it can be\n * embedded in example drivers.\n */\nextern const struct command_registration hello_command_handlers[];\n\n#endif /* OPENOCD_HELLO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libhelper.la\n\n%C%_libhelper_la_SOURCES = \\\n\t%D%/binarybuffer.c \\\n\t%D%/options.c \\\n\t%D%/time_support_common.c \\\n\t%D%/configuration.c \\\n\t%D%/log.c \\\n\t%D%/command.c \\\n\t%D%/crc32.c \\\n\t%D%/time_support.c \\\n\t%D%/replacements.c \\\n\t%D%/fileio.c \\\n\t%D%/util.c \\\n\t%D%/jep106.c \\\n\t%D%/jim-nvp.c \\\n\t%D%/nvp.c \\\n\t%D%/align.h \\\n\t%D%/binarybuffer.h \\\n\t%D%/bits.h \\\n\t%D%/configuration.h \\\n\t%D%/list.h \\\n\t%D%/util.h \\\n\t%D%/types.h \\\n\t%D%/log.h \\\n\t%D%/command.h \\\n\t%D%/crc32.h \\\n\t%D%/time_support.h \\\n\t%D%/replacements.h \\\n\t%D%/fileio.h \\\n\t%D%/system.h \\\n\t%D%/jep106.h \\\n\t%D%/jep106.inc \\\n\t%D%/jim-nvp.h \\\n\t%D%/nvp.h \\\n\t%D%/compiler.h\n\nSTARTUP_TCL_SRCS += %D%/startup.tcl\nEXTRA_DIST += \\\n\t%D%/bin2char.sh \\\n\t%D%/update_jep106.pl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/align.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * The content of this file is mainly copied/inspired from Linux kernel\n * code in include/linux/align.h and include/uapi/linux/const.h\n *\n * Macro name 'ALIGN' conflicts with macOS/BSD file param.h\n */\n\n#ifndef OPENOCD_HELPER_ALIGN_H\n#define OPENOCD_HELPER_ALIGN_H\n\n#define ALIGN_MASK(x, mask)             \\\n({                                      \\\n\ttypeof(mask) _mask = (mask);        \\\n\t((x) + _mask) & ~_mask;             \\\n})\n\n/* @a is a power of 2 value */\n#define ALIGN_UP(x, a)          ALIGN_MASK(x, (typeof(x))(a) - 1)\n#define ALIGN_DOWN(x, a)        ((x) & ~((typeof(x))(a) - 1))\n#define IS_ALIGNED(x, a)        (((x) & ((typeof(x))(a) - 1)) == 0)\n\n#define IS_PWR_OF_2(x)                  \\\n({                                      \\\n\ttypeof(x) _x = (x);                 \\\n\t_x == 0 || (_x & (_x - 1)) == 0;    \\\n})\n\n#endif /* OPENOCD_HELPER_ALIGN_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/bin2char.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n[ $# != 0 ] && {\n    echo \"Usage: $0\"\n    echo\n    echo \"Read binary data from standard input and write it as a comma separated\"\n    echo \"list of hexadecimal byte values to standard output. The output is usable\"\n    echo \"as a C array initializer. It is terminated with a comma so it can be\"\n    echo \"continued e.g. for zero termination.\"\n    exit 1\n}\n\necho \"/* Autogenerated with $0 */\"\nod -v -A n -t x1 | sed 's/ *\\(..\\) */0x\\1,/g'\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/binarybuffer.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"helper/replacements.h\"\n#include \"log.h\"\n#include \"binarybuffer.h\"\n\nstatic const unsigned char bit_reverse_table256[] = {\n\t0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,\n\t0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,\n\t0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,\n\t0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,\n\t0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,\n\t0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,\n\t0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,\n\t0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,\n\t0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,\n\t0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,\n\t0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,\n\t0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,\n\t0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,\n\t0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,\n\t0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,\n\t0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF\n};\n\nstatic const char hex_digits[] = {\n\t'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n\t'a', 'b', 'c', 'd', 'e', 'f'\n};\n\nvoid *buf_cpy(const void *from, void *_to, unsigned size)\n{\n\tif (!from || !_to)\n\t\treturn NULL;\n\n\t/* copy entire buffer */\n\tmemcpy(_to, from, DIV_ROUND_UP(size, 8));\n\n\t/* mask out bits that don't belong to the buffer */\n\tunsigned trailing_bits = size % 8;\n\tif (trailing_bits) {\n\t\tuint8_t *to = _to;\n\t\tto[size / 8] &= (1 << trailing_bits) - 1;\n\t}\n\treturn _to;\n}\n\nstatic bool buf_cmp_masked(uint8_t a, uint8_t b, uint8_t m)\n{\n\treturn (a & m) != (b & m);\n}\nstatic bool buf_cmp_trailing(uint8_t a, uint8_t b, uint8_t m, unsigned trailing)\n{\n\tuint8_t mask = (1 << trailing) - 1;\n\treturn buf_cmp_masked(a, b, mask & m);\n}\n\nbool buf_cmp(const void *_buf1, const void *_buf2, unsigned size)\n{\n\tif (!_buf1 || !_buf2)\n\t\treturn _buf1 != _buf2;\n\n\tunsigned last = size / 8;\n\tif (memcmp(_buf1, _buf2, last) != 0)\n\t\treturn false;\n\n\tunsigned trailing = size % 8;\n\tif (!trailing)\n\t\treturn false;\n\n\tconst uint8_t *buf1 = _buf1, *buf2 = _buf2;\n\treturn buf_cmp_trailing(buf1[last], buf2[last], 0xff, trailing);\n}\n\nbool buf_cmp_mask(const void *_buf1, const void *_buf2,\n\tconst void *_mask, unsigned size)\n{\n\tif (!_buf1 || !_buf2)\n\t\treturn _buf1 != _buf2 || _buf1 != _mask;\n\n\tconst uint8_t *buf1 = _buf1, *buf2 = _buf2, *mask = _mask;\n\tunsigned last = size / 8;\n\tfor (unsigned i = 0; i < last; i++) {\n\t\tif (buf_cmp_masked(buf1[i], buf2[i], mask[i]))\n\t\t\treturn true;\n\t}\n\tunsigned trailing = size % 8;\n\tif (!trailing)\n\t\treturn false;\n\treturn buf_cmp_trailing(buf1[last], buf2[last], mask[last], trailing);\n}\n\n\nvoid *buf_set_ones(void *_buf, unsigned size)\n{\n\tuint8_t *buf = _buf;\n\tif (!buf)\n\t\treturn NULL;\n\n\tmemset(buf, 0xff, size / 8);\n\n\tunsigned trailing_bits = size % 8;\n\tif (trailing_bits)\n\t\tbuf[size / 8] = (1 << trailing_bits) - 1;\n\n\treturn buf;\n}\n\nvoid *buf_set_buf(const void *_src, unsigned src_start,\n\tvoid *_dst, unsigned dst_start, unsigned len)\n{\n\tconst uint8_t *src = _src;\n\tuint8_t *dst = _dst;\n\tunsigned i, sb, db, sq, dq, lb, lq;\n\n\tsb = src_start / 8;\n\tdb = dst_start / 8;\n\tsq = src_start % 8;\n\tdq = dst_start % 8;\n\tlb = len / 8;\n\tlq = len % 8;\n\n\tsrc += sb;\n\tdst += db;\n\n\t/* check if both buffers are on byte boundary and\n\t * len is a multiple of 8bit so we can simple copy\n\t * the buffer */\n\tif ((sq == 0) && (dq == 0) &&  (lq == 0)) {\n\t\tfor (i = 0; i < lb; i++)\n\t\t\t*dst++ = *src++;\n\t\treturn _dst;\n\t}\n\n\t/* fallback to slow bit copy */\n\tfor (i = 0; i < len; i++) {\n\t\tif (((*src >> (sq&7)) & 1) == 1)\n\t\t\t*dst |= 1 << (dq&7);\n\t\telse\n\t\t\t*dst &= ~(1 << (dq&7));\n\t\tif (sq++ == 7) {\n\t\t\tsq = 0;\n\t\t\tsrc++;\n\t\t}\n\t\tif (dq++ == 7) {\n\t\t\tdq = 0;\n\t\t\tdst++;\n\t\t}\n\t}\n\n\treturn _dst;\n}\n\nuint32_t flip_u32(uint32_t value, unsigned int num)\n{\n\tuint32_t c = (bit_reverse_table256[value & 0xff] << 24) |\n\t\t(bit_reverse_table256[(value >> 8) & 0xff] << 16) |\n\t\t(bit_reverse_table256[(value >> 16) & 0xff] << 8) |\n\t\t(bit_reverse_table256[(value >> 24) & 0xff]);\n\n\tif (num < 32)\n\t\tc = c >> (32 - num);\n\n\treturn c;\n}\n\nstatic int ceil_f_to_u32(float x)\n{\n\tif (x < 0)\t/* return zero for negative numbers */\n\t\treturn 0;\n\n\tuint32_t y = x;\t/* cut off fraction */\n\n\tif ((x - y) > 0.0)\t/* if there was a fractional part, increase by one */\n\t\ty++;\n\n\treturn y;\n}\n\nchar *buf_to_hex_str(const void *_buf, unsigned buf_len)\n{\n\tunsigned len_bytes = DIV_ROUND_UP(buf_len, 8);\n\tchar *str = calloc(len_bytes * 2 + 1, 1);\n\n\tconst uint8_t *buf = _buf;\n\tfor (unsigned i = 0; i < len_bytes; i++) {\n\t\tuint8_t tmp = buf[len_bytes - i - 1];\n\t\tif ((i == 0) && (buf_len % 8))\n\t\t\ttmp &= (0xff >> (8 - (buf_len % 8)));\n\t\tstr[2 * i] = hex_digits[tmp >> 4];\n\t\tstr[2 * i + 1] = hex_digits[tmp & 0xf];\n\t}\n\n\treturn str;\n}\n\n/** identify radix, and skip radix-prefix (0, 0x or 0X) */\nstatic void str_radix_guess(const char **_str, unsigned *_str_len,\n\tunsigned *_radix)\n{\n\tunsigned radix = *_radix;\n\tif (radix != 0)\n\t\treturn;\n\tconst char *str = *_str;\n\tunsigned str_len = *_str_len;\n\tif (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) {\n\t\tradix = 16;\n\t\tstr += 2;\n\t\tstr_len -= 2;\n\t} else if ((str[0] == '0') && (str_len != 1)) {\n\t\tradix = 8;\n\t\tstr += 1;\n\t\tstr_len -= 1;\n\t} else\n\t\tradix = 10;\n\t*_str = str;\n\t*_str_len = str_len;\n\t*_radix = radix;\n}\n\nint str_to_buf(const char *str, unsigned str_len,\n\tvoid *_buf, unsigned buf_len, unsigned radix)\n{\n\tstr_radix_guess(&str, &str_len, &radix);\n\n\tfloat factor;\n\tif (radix == 16)\n\t\tfactor = 0.5;\t/* log(16) / log(256) = 0.5 */\n\telse if (radix == 10)\n\t\tfactor = 0.41524;\t/* log(10) / log(256) = 0.41524 */\n\telse if (radix == 8)\n\t\tfactor = 0.375;\t/* log(8) / log(256) = 0.375 */\n\telse\n\t\treturn 0;\n\n\t/* copy to zero-terminated buffer */\n\tchar *charbuf = strndup(str, str_len);\n\n\t/* number of digits in base-256 notation */\n\tunsigned b256_len = ceil_f_to_u32(str_len * factor);\n\tuint8_t *b256_buf = calloc(b256_len, 1);\n\n\t/* go through zero terminated buffer\n\t * input digits (ASCII) */\n\tunsigned i;\n\tfor (i = 0; charbuf[i]; i++) {\n\t\tuint32_t tmp = charbuf[i];\n\t\tif ((tmp >= '0') && (tmp <= '9'))\n\t\t\ttmp = (tmp - '0');\n\t\telse if ((tmp >= 'a') && (tmp <= 'f'))\n\t\t\ttmp = (tmp - 'a' + 10);\n\t\telse if ((tmp >= 'A') && (tmp <= 'F'))\n\t\t\ttmp = (tmp - 'A' + 10);\n\t\telse\n\t\t\tcontinue;\t/* skip characters other than [0-9,a-f,A-F] */\n\n\t\tif (tmp >= radix)\n\t\t\tcontinue;\t/* skip digits invalid for the current radix */\n\n\t\t/* base-256 digits */\n\t\tfor (unsigned j = 0; j < b256_len; j++) {\n\t\t\ttmp += (uint32_t)b256_buf[j] * radix;\n\t\t\tb256_buf[j] = (uint8_t)(tmp & 0xFF);\n\t\t\ttmp >>= 8;\n\t\t}\n\n\t}\n\n\tuint8_t *buf = _buf;\n\tfor (unsigned j = 0; j < DIV_ROUND_UP(buf_len, 8); j++) {\n\t\tif (j < b256_len)\n\t\t\tbuf[j] = b256_buf[j];\n\t\telse\n\t\t\tbuf[j] = 0;\n\t}\n\n\t/* mask out bits that don't belong to the buffer */\n\tif (buf_len % 8)\n\t\tbuf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));\n\n\tfree(b256_buf);\n\tfree(charbuf);\n\n\treturn i;\n}\n\nvoid bit_copy_queue_init(struct bit_copy_queue *q)\n{\n\tINIT_LIST_HEAD(&q->list);\n}\n\nint bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,\n\tunsigned src_offset, unsigned bit_count)\n{\n\tstruct bit_copy_queue_entry *qe = malloc(sizeof(*qe));\n\tif (!qe)\n\t\treturn ERROR_FAIL;\n\n\tqe->dst = dst;\n\tqe->dst_offset = dst_offset;\n\tqe->src = src;\n\tqe->src_offset = src_offset;\n\tqe->bit_count = bit_count;\n\tlist_add_tail(&qe->list, &q->list);\n\n\treturn ERROR_OK;\n}\n\nvoid bit_copy_execute(struct bit_copy_queue *q)\n{\n\tstruct bit_copy_queue_entry *qe;\n\tstruct bit_copy_queue_entry *tmp;\n\tlist_for_each_entry_safe(qe, tmp, &q->list, list) {\n\t\tbit_copy(qe->dst, qe->dst_offset, qe->src, qe->src_offset, qe->bit_count);\n\t\tlist_del(&qe->list);\n\t\tfree(qe);\n\t}\n}\n\nvoid bit_copy_discard(struct bit_copy_queue *q)\n{\n\tstruct bit_copy_queue_entry *qe;\n\tstruct bit_copy_queue_entry *tmp;\n\tlist_for_each_entry_safe(qe, tmp, &q->list, list) {\n\t\tlist_del(&qe->list);\n\t\tfree(qe);\n\t}\n}\n\n/**\n * Convert a string of hexadecimal pairs into its binary\n * representation.\n *\n * @param[out] bin Buffer to store binary representation. The buffer size must\n *                 be at least @p count.\n * @param[in] hex String with hexadecimal pairs to convert into its binary\n *                representation.\n * @param[in] count Number of hexadecimal pairs to convert.\n *\n * @return The number of converted hexadecimal pairs.\n */\nsize_t unhexify(uint8_t *bin, const char *hex, size_t count)\n{\n\tsize_t i;\n\tchar tmp;\n\n\tif (!bin || !hex)\n\t\treturn 0;\n\n\tmemset(bin, 0, count);\n\n\tfor (i = 0; i < 2 * count; i++) {\n\t\tif (hex[i] >= 'a' && hex[i] <= 'f')\n\t\t\ttmp = hex[i] - 'a' + 10;\n\t\telse if (hex[i] >= 'A' && hex[i] <= 'F')\n\t\t\ttmp = hex[i] - 'A' + 10;\n\t\telse if (hex[i] >= '0' && hex[i] <= '9')\n\t\t\ttmp = hex[i] - '0';\n\t\telse\n\t\t\treturn i / 2;\n\n\t\tbin[i / 2] |= tmp << (4 * ((i + 1) % 2));\n\t}\n\n\treturn i / 2;\n}\n\n/**\n * Convert binary data into a string of hexadecimal pairs.\n *\n * @param[out] hex Buffer to store string of hexadecimal pairs. The buffer size\n *                 must be at least @p length.\n * @param[in] bin Buffer with binary data to convert into hexadecimal pairs.\n * @param[in] count Number of bytes to convert.\n * @param[in] length Maximum number of characters, including null-terminator,\n *                   to store into @p hex.\n *\n * @returns The length of the converted string excluding null-terminator.\n */\nsize_t hexify(char *hex, const uint8_t *bin, size_t count, size_t length)\n{\n\tsize_t i;\n\tuint8_t tmp;\n\n\tif (!length)\n\t\treturn 0;\n\n\tfor (i = 0; i < length - 1 && i < 2 * count; i++) {\n\t\ttmp = (bin[i / 2] >> (4 * ((i + 1) % 2))) & 0x0f;\n\t\thex[i] = hex_digits[tmp];\n\t}\n\n\thex[i] = 0;\n\n\treturn i;\n}\n\nvoid buffer_shr(void *_buf, unsigned buf_len, unsigned count)\n{\n\tunsigned i;\n\tunsigned char *buf = _buf;\n\tunsigned bytes_to_remove;\n\tunsigned shift;\n\n\tbytes_to_remove = count / 8;\n\tshift = count - (bytes_to_remove * 8);\n\n\tfor (i = 0; i < (buf_len - 1); i++)\n\t\tbuf[i] = (buf[i] >> shift) | ((buf[i+1] << (8 - shift)) & 0xff);\n\n\tbuf[(buf_len - 1)] = buf[(buf_len - 1)] >> shift;\n\n\tif (bytes_to_remove) {\n\t\tmemmove(buf, &buf[bytes_to_remove], buf_len - bytes_to_remove);\n\t\tmemset(&buf[buf_len - bytes_to_remove], 0, bytes_to_remove);\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/binarybuffer.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_BINARYBUFFER_H\n#define OPENOCD_HELPER_BINARYBUFFER_H\n\n#include \"list.h\"\n\n/** @file\n * Support functions to access arbitrary bits in a byte array\n */\n\n/**\n * Sets @c num bits in @c _buffer, starting at the @c first bit,\n * using the bits in @c value.  This routine fast-paths writes\n * of little-endian, byte-aligned, 32-bit words.\n * @param _buffer The buffer whose bits will be set.\n *\tDo not use uninitialized buffer or clang static analyzer emits a warning.\n * @param first The bit offset in @c _buffer to start writing (0-31).\n * @param num The number of bits from @c value to copy (1-32).\n * @param value Up to 32 bits that will be copied to _buffer.\n */\nstatic inline void buf_set_u32(uint8_t *_buffer,\n\tunsigned first, unsigned num, uint32_t value)\n{\n\tuint8_t *buffer = _buffer;\n\n\tif ((num == 32) && (first == 0)) {\n\t\tbuffer[3] = (value >> 24) & 0xff;\n\t\tbuffer[2] = (value >> 16) & 0xff;\n\t\tbuffer[1] = (value >> 8) & 0xff;\n\t\tbuffer[0] = (value >> 0) & 0xff;\n\t} else {\n\t\tfor (unsigned i = first; i < first + num; i++) {\n\t\t\tif (((value >> (i - first)) & 1) == 1)\n\t\t\t\tbuffer[i / 8] |= 1 << (i % 8);\n\t\t\telse\n\t\t\t\tbuffer[i / 8] &= ~(1 << (i % 8));\n\t\t}\n\t}\n}\n\n/**\n * Sets @c num bits in @c _buffer, starting at the @c first bit,\n * using the bits in @c value.  This routine fast-paths writes\n * of little-endian, byte-aligned, 64-bit words.\n * @param _buffer The buffer whose bits will be set.\n *\tDo not use uninitialized buffer or clang static analyzer emits a warning.\n * @param first The bit offset in @c _buffer to start writing (0-63).\n * @param num The number of bits from @c value to copy (1-64).\n * @param value Up to 64 bits that will be copied to _buffer.\n */\nstatic inline void buf_set_u64(uint8_t *_buffer,\n\tunsigned first, unsigned num, uint64_t value)\n{\n\tuint8_t *buffer = _buffer;\n\n\tif ((num == 32) && (first == 0)) {\n\t\tbuffer[3] = (value >> 24) & 0xff;\n\t\tbuffer[2] = (value >> 16) & 0xff;\n\t\tbuffer[1] = (value >> 8) & 0xff;\n\t\tbuffer[0] = (value >> 0) & 0xff;\n\t} else if ((num == 64) && (first == 0)) {\n\t\tbuffer[7] = (value >> 56) & 0xff;\n\t\tbuffer[6] = (value >> 48) & 0xff;\n\t\tbuffer[5] = (value >> 40) & 0xff;\n\t\tbuffer[4] = (value >> 32) & 0xff;\n\t\tbuffer[3] = (value >> 24) & 0xff;\n\t\tbuffer[2] = (value >> 16) & 0xff;\n\t\tbuffer[1] = (value >> 8) & 0xff;\n\t\tbuffer[0] = (value >> 0) & 0xff;\n\t} else {\n\t\tfor (unsigned i = first; i < first + num; i++) {\n\t\t\tif (((value >> (i - first)) & 1) == 1)\n\t\t\t\tbuffer[i / 8] |= 1 << (i % 8);\n\t\t\telse\n\t\t\t\tbuffer[i / 8] &= ~(1 << (i % 8));\n\t\t}\n\t}\n}\n\n/**\n * Retrieves @c num bits from @c _buffer, starting at the @c first bit,\n * returning the bits in a 32-bit word.  This routine fast-paths reads\n * of little-endian, byte-aligned, 32-bit words.\n * @param _buffer The buffer whose bits will be read.\n * @param first The bit offset in @c _buffer to start reading (0-31).\n * @param num The number of bits from @c _buffer to read (1-32).\n * @returns Up to 32-bits that were read from @c _buffer.\n */\nstatic inline uint32_t buf_get_u32(const uint8_t *_buffer,\n\tunsigned first, unsigned num)\n{\n\tconst uint8_t *buffer = _buffer;\n\n\tif ((num == 32) && (first == 0)) {\n\t\treturn (((uint32_t)buffer[3]) << 24) |\n\t\t\t\t(((uint32_t)buffer[2]) << 16) |\n\t\t\t\t(((uint32_t)buffer[1]) << 8) |\n\t\t\t\t(((uint32_t)buffer[0]) << 0);\n\t} else {\n\t\tuint32_t result = 0;\n\t\tfor (unsigned i = first; i < first + num; i++) {\n\t\t\tif (((buffer[i / 8] >> (i % 8)) & 1) == 1)\n\t\t\t\tresult |= 1U << (i - first);\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Retrieves @c num bits from @c _buffer, starting at the @c first bit,\n * returning the bits in a 64-bit word.  This routine fast-paths reads\n * of little-endian, byte-aligned, 64-bit words.\n * @param _buffer The buffer whose bits will be read.\n * @param first The bit offset in @c _buffer to start reading (0-63).\n * @param num The number of bits from @c _buffer to read (1-64).\n * @returns Up to 64-bits that were read from @c _buffer.\n */\nstatic inline uint64_t buf_get_u64(const uint8_t *_buffer,\n\tunsigned first, unsigned num)\n{\n\tconst uint8_t *buffer = _buffer;\n\n\tif ((num == 32) && (first == 0)) {\n\t\treturn 0 + ((((uint32_t)buffer[3]) << 24) |   /* Note - zero plus is to avoid a checkpatch bug */\n\t\t\t\t(((uint32_t)buffer[2]) << 16) |\n\t\t\t\t(((uint32_t)buffer[1]) << 8)  |\n\t\t\t\t(((uint32_t)buffer[0]) << 0));\n\t} else if ((num == 64) && (first == 0)) {\n\t\treturn 0 + ((((uint64_t)buffer[7]) << 56) |   /* Note - zero plus is to avoid a checkpatch bug */\n\t\t\t\t(((uint64_t)buffer[6]) << 48) |\n\t\t\t\t(((uint64_t)buffer[5]) << 40) |\n\t\t\t\t(((uint64_t)buffer[4]) << 32) |\n\t\t\t\t(((uint64_t)buffer[3]) << 24) |\n\t\t\t\t(((uint64_t)buffer[2]) << 16) |\n\t\t\t\t(((uint64_t)buffer[1]) << 8)  |\n\t\t\t\t(((uint64_t)buffer[0]) << 0));\n\t} else {\n\t\tuint64_t result = 0;\n\t\tfor (unsigned i = first; i < first + num; i++) {\n\t\t\tif (((buffer[i / 8] >> (i % 8)) & 1) == 1)\n\t\t\t\tresult = result | ((uint64_t)1 << (uint64_t)(i - first));\n\t\t}\n\t\treturn result;\n\t}\n}\n\n\n/**\n * Inverts the ordering of bits inside a 32-bit word (e.g. 31..0 -> 0..31).\n * This routine can be used to flip smaller data types by using smaller\n * values for @c width.\n * @param value The word to flip.\n * @param width The number of bits in value (2-32).\n * @returns A 32-bit word with @c value in reversed bit-order.\n */\nuint32_t flip_u32(uint32_t value, unsigned width);\n\nbool buf_cmp(const void *buf1, const void *buf2, unsigned size);\nbool buf_cmp_mask(const void *buf1, const void *buf2,\n\t\tconst void *mask, unsigned size);\n\n/**\n * Copies @c size bits out of @c from and into @c to.  Any extra\n * bits in the final byte will be set to zero.\n * @param from The buffer to copy into @c to.\n * @param to The buffer that will receive the copy of @c from.\n * @param size The number of bits to copy.\n */\nvoid *buf_cpy(const void *from, void *to, unsigned size);\n\n/**\n * Set the contents of @c buf with @c count bits, all set to 1.\n * @param buf The buffer to fill with ones.\n * @param size The number of bits.\n * @returns The original buffer (@c buf).\n */\nvoid *buf_set_ones(void *buf, unsigned size);\n\nvoid *buf_set_buf(const void *src, unsigned src_start,\n\t\t  void *dst, unsigned dst_start, unsigned len);\n\nint str_to_buf(const char *str, unsigned len,\n\t\tvoid *bin_buf, unsigned buf_size, unsigned radix);\nchar *buf_to_hex_str(const void *buf, unsigned size);\n\n/* read a uint32_t from a buffer in target memory endianness */\nstatic inline uint32_t fast_target_buffer_get_u32(const void *p, bool le)\n{\n\treturn le ? le_to_h_u32(p) : be_to_h_u32(p);\n}\n\nstatic inline void bit_copy(uint8_t *dst, unsigned dst_offset, const uint8_t *src,\n\tunsigned src_offset, unsigned bit_count)\n{\n\tbuf_set_buf(src, src_offset, dst, dst_offset, bit_count);\n}\n\nstruct bit_copy_queue {\n\tstruct list_head list;\n};\n\nstruct bit_copy_queue_entry {\n\tuint8_t *dst;\n\tunsigned dst_offset;\n\tconst uint8_t *src;\n\tunsigned src_offset;\n\tunsigned bit_count;\n\tstruct list_head list;\n};\n\nvoid bit_copy_queue_init(struct bit_copy_queue *q);\nint bit_copy_queued(struct bit_copy_queue *q, uint8_t *dst, unsigned dst_offset, const uint8_t *src,\n\t\t    unsigned src_offset, unsigned bit_count);\nvoid bit_copy_execute(struct bit_copy_queue *q);\nvoid bit_copy_discard(struct bit_copy_queue *q);\n\n/* functions to convert to/from hex encoded buffer\n * used in ti-icdi driver and gdb server */\nsize_t unhexify(uint8_t *bin, const char *hex, size_t count);\nsize_t hexify(char *hex, const uint8_t *bin, size_t count, size_t out_maxlen);\nvoid buffer_shr(void *_buf, unsigned buf_len, unsigned count);\n\n#endif /* OPENOCD_HELPER_BINARYBUFFER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/bits.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2018, STMicroelectronics - All Rights Reserved\n * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics\n */\n\n/*\n * The content of this file is mainly copied/inspired from Linux kernel\n * code in include/linux/types.h include/linux/bitmap.h include/linux/bitops.h\n */\n\n#ifndef OPENOCD_HELPER_BITS_H\n#define OPENOCD_HELPER_BITS_H\n\n#include <helper/replacements.h>\n#include <helper/types.h>\n\n#define BIT(nr)                     (1UL << (nr))\n#define BIT_ULL(nr)                 (1ULL << (nr))\n#define BITS_PER_BYTE               8\n#define BITS_PER_LONG               (BITS_PER_BYTE * sizeof(long))\n#define BITS_PER_LONG_LONG          (BITS_PER_BYTE * sizeof(long long))\n#define GENMASK(h, l)               (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))\n#define GENMASK_ULL(h, l)           (((~0ULL) - (1ULL << (l)) + 1) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))\n#define BITS_TO_LONGS(nr)           DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))\n#define BIT_MASK(nr)                (1UL << ((nr) % BITS_PER_LONG))\n#define BIT_WORD(nr)                ((nr) / BITS_PER_LONG)\n#define DECLARE_BITMAP(name, bits)  unsigned long name[BITS_TO_LONGS(bits)]\n\n/**\n * bitmap_zero - Clears all the bits in memory\n * @param dst the address of the bitmap\n * @param nbits the number of bits to clear\n */\nstatic inline void bitmap_zero(unsigned long *dst, unsigned int nbits)\n{\n\tunsigned int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);\n\tmemset(dst, 0, len);\n}\n\n/**\n * clear_bit - Clear a bit in memory\n * @param nr the bit to set\n * @param addr the address to start counting from\n */\nstatic inline void clear_bit(unsigned int nr, volatile unsigned long *addr)\n{\n\tunsigned long mask = BIT_MASK(nr);\n\tunsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);\n\n\t*p &= ~mask;\n}\n\n/**\n * set_bit - Set a bit in memory\n * @param nr the bit to set\n * @param addr the address to start counting from\n */\nstatic inline void set_bit(unsigned int nr, volatile unsigned long *addr)\n{\n\tunsigned long mask = BIT_MASK(nr);\n\tunsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);\n\n\t*p |= mask;\n}\n\n/**\n * test_bit - Determine whether a bit is set\n * @param nr bit number to test\n * @param addr Address to start counting from\n */\nstatic inline int test_bit(unsigned int nr, const volatile unsigned long *addr)\n{\n\treturn 1UL & (addr[BIT_WORD(nr)] >> (nr % BITS_PER_LONG));\n}\n\n#endif /* OPENOCD_HELPER_BITS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/command.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008, Duane Ellis                                       *\n *   openocd@duaneeellis.com                                               *\n *                                                                         *\n *   part of this file is taken from libcli (libcli.sourceforge.net)       *\n *   Copyright (C) David Parrish (david@dparrish.com)                      *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* @todo the inclusion of target.h here is a layering violation */\n#include <jtag/jtag.h>\n#include <target/target.h>\n#include \"command.h\"\n#include \"configuration.h\"\n#include \"log.h\"\n#include \"time_support.h\"\n#include \"jim-eventloop.h\"\n\n/* nice short description of source file */\n#define __THIS__FILE__ \"command.c\"\n\nstruct log_capture_state {\n\tJim_Interp *interp;\n\tJim_Obj *output;\n};\n\nstatic int unregister_command(struct command_context *context,\n\tconst char *cmd_prefix, const char *name);\nstatic int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv);\nstatic int help_add_command(struct command_context *cmd_ctx,\n\tconst char *cmd_name, const char *help_text, const char *usage_text);\nstatic int help_del_command(struct command_context *cmd_ctx, const char *cmd_name);\n\n/* set of functions to wrap jimtcl internal data */\nstatic inline bool jimcmd_is_proc(Jim_Cmd *cmd)\n{\n\treturn cmd->isproc;\n}\n\nbool jimcmd_is_oocd_command(Jim_Cmd *cmd)\n{\n\treturn !cmd->isproc && cmd->u.native.cmdProc == jim_command_dispatch;\n}\n\nvoid *jimcmd_privdata(Jim_Cmd *cmd)\n{\n\treturn cmd->isproc ? NULL : cmd->u.native.privData;\n}\n\nstatic void tcl_output(void *privData, const char *file, unsigned line,\n\tconst char *function, const char *string)\n{\n\tstruct log_capture_state *state = privData;\n\tJim_AppendString(state->interp, state->output, string, strlen(string));\n}\n\nstatic struct log_capture_state *command_log_capture_start(Jim_Interp *interp)\n{\n\t/* capture log output and return it. A garbage collect can\n\t * happen, so we need a reference count to this object */\n\tJim_Obj *jim_output = Jim_NewStringObj(interp, \"\", 0);\n\tif (!jim_output)\n\t\treturn NULL;\n\n\tJim_IncrRefCount(jim_output);\n\n\tstruct log_capture_state *state = malloc(sizeof(*state));\n\tif (!state) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tJim_DecrRefCount(interp, jim_output);\n\t\treturn NULL;\n\t}\n\n\tstate->interp = interp;\n\tstate->output = jim_output;\n\n\tlog_add_callback(tcl_output, state);\n\n\treturn state;\n}\n\n/* Classic openocd commands provide progress output which we\n * will capture and return as a Tcl return value.\n *\n * However, if a non-openocd command has been invoked, then it\n * makes sense to return the tcl return value from that command.\n *\n * The tcl return value is empty for openocd commands that provide\n * progress output.\n *\n * Therefore we set the tcl return value only if we actually\n * captured output.\n */\nstatic void command_log_capture_finish(struct log_capture_state *state)\n{\n\tif (!state)\n\t\treturn;\n\n\tlog_remove_callback(tcl_output, state);\n\n\tint length;\n\tJim_GetString(state->output, &length);\n\n\tif (length > 0)\n\t\tJim_SetResult(state->interp, state->output);\n\telse {\n\t\t/* No output captured, use tcl return value (which could\n\t\t * be empty too). */\n\t}\n\tJim_DecrRefCount(state->interp, state->output);\n\n\tfree(state);\n}\n\nstatic int command_retval_set(Jim_Interp *interp, int retval)\n{\n\tint *return_retval = Jim_GetAssocData(interp, \"retval\");\n\tif (return_retval)\n\t\t*return_retval = retval;\n\n\treturn (retval == ERROR_OK) ? JIM_OK : retval;\n}\n\nextern struct command_context *global_cmd_ctx;\n\n/* dump a single line to the log for the command.\n * Do nothing in case we are not at debug level 3 */\nstatic void script_debug(Jim_Interp *interp, unsigned int argc, Jim_Obj * const *argv)\n{\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn;\n\n\tchar *dbg = alloc_printf(\"command -\");\n\tfor (unsigned i = 0; i < argc; i++) {\n\t\tint len;\n\t\tconst char *w = Jim_GetString(argv[i], &len);\n\t\tchar *t = alloc_printf(\"%s %s\", dbg, w);\n\t\tfree(dbg);\n\t\tdbg = t;\n\t}\n\tLOG_DEBUG(\"%s\", dbg);\n\tfree(dbg);\n}\n\nstatic void script_command_args_free(char **words, unsigned nwords)\n{\n\tfor (unsigned i = 0; i < nwords; i++)\n\t\tfree(words[i]);\n\tfree(words);\n}\n\nstatic char **script_command_args_alloc(\n\tunsigned argc, Jim_Obj * const *argv, unsigned *nwords)\n{\n\tchar **words = malloc(argc * sizeof(char *));\n\tif (!words)\n\t\treturn NULL;\n\n\tunsigned i;\n\tfor (i = 0; i < argc; i++) {\n\t\tint len;\n\t\tconst char *w = Jim_GetString(argv[i], &len);\n\t\twords[i] = strdup(w);\n\t\tif (!words[i]) {\n\t\t\tscript_command_args_free(words, i);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\t*nwords = i;\n\treturn words;\n}\n\nstruct command_context *current_command_context(Jim_Interp *interp)\n{\n\t/* grab the command context from the associated data */\n\tstruct command_context *cmd_ctx = Jim_GetAssocData(interp, \"context\");\n\tif (!cmd_ctx) {\n\t\t/* Tcl can invoke commands directly instead of via command_run_line(). This would\n\t\t * happen when the Jim Tcl interpreter is provided by eCos or if we are running\n\t\t * commands in a startup script.\n\t\t *\n\t\t * A telnet or gdb server would provide a non-default command context to\n\t\t * handle piping of error output, have a separate current target, etc.\n\t\t */\n\t\tcmd_ctx = global_cmd_ctx;\n\t}\n\treturn cmd_ctx;\n}\n\n/**\n * Find a openocd command from fullname.\n * @returns Returns the named command if it is registred in interp.\n * Returns NULL otherwise.\n */\nstatic struct command *command_find_from_name(Jim_Interp *interp, const char *name)\n{\n\tif (!name)\n\t\treturn NULL;\n\n\tJim_Obj *jim_name = Jim_NewStringObj(interp, name, -1);\n\tJim_IncrRefCount(jim_name);\n\tJim_Cmd *cmd = Jim_GetCommand(interp, jim_name, JIM_NONE);\n\tJim_DecrRefCount(interp, jim_name);\n\tif (!cmd || jimcmd_is_proc(cmd) || !jimcmd_is_oocd_command(cmd))\n\t\treturn NULL;\n\n\treturn jimcmd_privdata(cmd);\n}\n\nstatic struct command *command_new(struct command_context *cmd_ctx,\n\tconst char *full_name, const struct command_registration *cr)\n{\n\tassert(cr->name);\n\n\t/*\n\t * If it is a non-jim command with no .usage specified,\n\t * log an error.\n\t *\n\t * strlen(.usage) == 0 means that the command takes no\n\t * arguments.\n\t*/\n\tif (!cr->jim_handler && !cr->usage)\n\t\tLOG_ERROR(\"BUG: command '%s' does not have the \"\n\t\t\t\"'.usage' field filled out\",\n\t\t\tfull_name);\n\n\tstruct command *c = calloc(1, sizeof(struct command));\n\tif (!c)\n\t\treturn NULL;\n\n\tc->name = strdup(cr->name);\n\tif (!c->name) {\n\t\tfree(c);\n\t\treturn NULL;\n\t}\n\n\tc->handler = cr->handler;\n\tc->jim_handler = cr->jim_handler;\n\tc->mode = cr->mode;\n\n\tif (cr->help || cr->usage)\n\t\thelp_add_command(cmd_ctx, full_name, cr->help, cr->usage);\n\n\treturn c;\n}\n\nstatic void command_free(struct Jim_Interp *interp, void *priv)\n{\n\tstruct command *c = priv;\n\n\tfree(c->name);\n\tfree(c);\n}\n\nstatic struct command *register_command(struct command_context *context,\n\tconst char *cmd_prefix, const struct command_registration *cr)\n{\n\tchar *full_name;\n\n\tif (!context || !cr->name)\n\t\treturn NULL;\n\n\tif (cmd_prefix)\n\t\tfull_name = alloc_printf(\"%s %s\", cmd_prefix, cr->name);\n\telse\n\t\tfull_name = strdup(cr->name);\n\tif (!full_name)\n\t\treturn NULL;\n\n\tstruct command *c = command_find_from_name(context->interp, full_name);\n\tif (c) {\n\t\t/* TODO: originally we treated attempting to register a cmd twice as an error\n\t\t * Sometimes we need this behaviour, such as with flash banks.\n\t\t * http://www.mail-archive.com/openocd-development@lists.berlios.de/msg11152.html */\n\t\tLOG_DEBUG(\"command '%s' is already registered\", full_name);\n\t\tfree(full_name);\n\t\treturn c;\n\t}\n\n\tc = command_new(context, full_name, cr);\n\tif (!c) {\n\t\tfree(full_name);\n\t\treturn NULL;\n\t}\n\n\tif (false) /* too noisy with debug_level 3 */\n\t\tLOG_DEBUG(\"registering '%s'...\", full_name);\n\tint retval = Jim_CreateCommand(context->interp, full_name,\n\t\t\t\tjim_command_dispatch, c, command_free);\n\tif (retval != JIM_OK) {\n\t\tcommand_run_linef(context, \"del_help_text {%s}\", full_name);\n\t\tcommand_run_linef(context, \"del_usage_text {%s}\", full_name);\n\t\tfree(c);\n\t\tfree(full_name);\n\t\treturn NULL;\n\t}\n\n\tfree(full_name);\n\treturn c;\n}\n\nint __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,\n\tconst struct command_registration *cmds, void *data,\n\tstruct target *override_target)\n{\n\tint retval = ERROR_OK;\n\tunsigned i;\n\tfor (i = 0; cmds[i].name || cmds[i].chain; i++) {\n\t\tconst struct command_registration *cr = cmds + i;\n\n\t\tstruct command *c = NULL;\n\t\tif (cr->name) {\n\t\t\tc = register_command(cmd_ctx, cmd_prefix, cr);\n\t\t\tif (!c) {\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tc->jim_handler_data = data;\n\t\t\tc->jim_override_target = override_target;\n\t\t}\n\t\tif (cr->chain) {\n\t\t\tif (cr->name) {\n\t\t\t\tif (cmd_prefix) {\n\t\t\t\t\tchar *new_prefix = alloc_printf(\"%s %s\", cmd_prefix, cr->name);\n\t\t\t\t\tif (!new_prefix) {\n\t\t\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tretval = __register_commands(cmd_ctx, new_prefix, cr->chain, data, override_target);\n\t\t\t\t\tfree(new_prefix);\n\t\t\t\t} else {\n\t\t\t\t\tretval = __register_commands(cmd_ctx, cr->name, cr->chain, data, override_target);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tretval = __register_commands(cmd_ctx, cmd_prefix, cr->chain, data, override_target);\n\t\t\t}\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tif (retval != ERROR_OK) {\n\t\tfor (unsigned j = 0; j < i; j++)\n\t\t\tunregister_command(cmd_ctx, cmd_prefix, cmds[j].name);\n\t}\n\treturn retval;\n}\n\nstatic __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)))\nint unregister_commands_match(struct command_context *cmd_ctx, const char *format, ...)\n{\n\tJim_Interp *interp = cmd_ctx->interp;\n\tva_list ap;\n\n\tva_start(ap, format);\n\tchar *query = alloc_vprintf(format, ap);\n\tva_end(ap);\n\tif (!query)\n\t\treturn ERROR_FAIL;\n\n\tchar *query_cmd = alloc_printf(\"info commands {%s}\", query);\n\tfree(query);\n\tif (!query_cmd)\n\t\treturn ERROR_FAIL;\n\n\tint retval = Jim_EvalSource(interp, __THIS__FILE__, __LINE__, query_cmd);\n\tfree(query_cmd);\n\tif (retval != JIM_OK)\n\t\treturn ERROR_FAIL;\n\n\tJim_Obj *list = Jim_GetResult(interp);\n\tJim_IncrRefCount(list);\n\n\tint len = Jim_ListLength(interp, list);\n\tfor (int i = 0; i < len; i++) {\n\t\tJim_Obj *elem = Jim_ListGetIndex(interp, list, i);\n\t\tJim_IncrRefCount(elem);\n\n\t\tconst char *name = Jim_GetString(elem, NULL);\n\t\tstruct command *c = command_find_from_name(interp, name);\n\t\tif (!c) {\n\t\t\t/* not openocd command */\n\t\t\tJim_DecrRefCount(interp, elem);\n\t\t\tcontinue;\n\t\t}\n\t\tif (false) /* too noisy with debug_level 3 */\n\t\t\tLOG_DEBUG(\"delete command \\\"%s\\\"\", name);\n#if JIM_VERSION >= 80\n\t\tJim_DeleteCommand(interp, elem);\n#else\n\t\tJim_DeleteCommand(interp, name);\n#endif\n\n\t\thelp_del_command(cmd_ctx, name);\n\n\t\tJim_DecrRefCount(interp, elem);\n\t}\n\n\tJim_DecrRefCount(interp, list);\n\treturn ERROR_OK;\n}\n\nint unregister_all_commands(struct command_context *context,\n\tconst char *cmd_prefix)\n{\n\tif (!context)\n\t\treturn ERROR_OK;\n\n\tif (!cmd_prefix || !*cmd_prefix)\n\t\treturn unregister_commands_match(context, \"*\");\n\n\tint retval = unregister_commands_match(context, \"%s *\", cmd_prefix);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn unregister_commands_match(context, \"%s\", cmd_prefix);\n}\n\nstatic int unregister_command(struct command_context *context,\n\tconst char *cmd_prefix, const char *name)\n{\n\tif (!context || !name)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!cmd_prefix || !*cmd_prefix)\n\t\treturn unregister_commands_match(context, \"%s\", name);\n\n\treturn unregister_commands_match(context, \"%s %s\", cmd_prefix, name);\n}\n\nvoid command_output_text(struct command_context *context, const char *data)\n{\n\tif (context && context->output_handler && data)\n\t\tcontext->output_handler(context, data);\n}\n\nvoid command_print_sameline(struct command_invocation *cmd, const char *format, ...)\n{\n\tchar *string;\n\n\tva_list ap;\n\tva_start(ap, format);\n\n\tstring = alloc_vprintf(format, ap);\n\tif (string && cmd) {\n\t\t/* we want this collected in the log + we also want to pick it up as a tcl return\n\t\t * value.\n\t\t *\n\t\t * The latter bit isn't precisely neat, but will do for now.\n\t\t */\n\t\tJim_AppendString(cmd->ctx->interp, cmd->output, string, -1);\n\t\t/* We already printed it above\n\t\t * command_output_text(context, string); */\n\t\tfree(string);\n\t}\n\n\tva_end(ap);\n}\n\nvoid command_print(struct command_invocation *cmd, const char *format, ...)\n{\n\tchar *string;\n\n\tva_list ap;\n\tva_start(ap, format);\n\n\tstring = alloc_vprintf(format, ap);\n\tif (string && cmd) {\n\t\tstrcat(string, \"\\n\");\t/* alloc_vprintf guaranteed the buffer to be at least one\n\t\t\t\t\t *char longer */\n\t\t/* we want this collected in the log + we also want to pick it up as a tcl return\n\t\t * value.\n\t\t *\n\t\t * The latter bit isn't precisely neat, but will do for now.\n\t\t */\n\t\tJim_AppendString(cmd->ctx->interp, cmd->output, string, -1);\n\t\t/* We already printed it above\n\t\t * command_output_text(context, string); */\n\t\tfree(string);\n\t}\n\n\tva_end(ap);\n}\n\nstatic bool command_can_run(struct command_context *cmd_ctx, struct command *c, const char *full_name)\n{\n\tif (c->mode == COMMAND_ANY || c->mode == cmd_ctx->mode)\n\t\treturn true;\n\n\t/* Many commands may be run only before/after 'init' */\n\tconst char *when;\n\tswitch (c->mode) {\n\t\tcase COMMAND_CONFIG:\n\t\t\twhen = \"before\";\n\t\t\tbreak;\n\t\tcase COMMAND_EXEC:\n\t\t\twhen = \"after\";\n\t\t\tbreak;\n\t\t/* handle the impossible with humor; it guarantees a bug report! */\n\t\tdefault:\n\t\t\twhen = \"if Cthulhu is summoned by\";\n\t\t\tbreak;\n\t}\n\tLOG_ERROR(\"The '%s' command must be used %s 'init'.\",\n\t\t\tfull_name ? full_name : c->name, when);\n\treturn false;\n}\n\nstatic int run_command(struct command_context *context,\n\tstruct command *c, const char **words, unsigned num_words)\n{\n\tstruct command_invocation cmd = {\n\t\t.ctx = context,\n\t\t.current = c,\n\t\t.name = c->name,\n\t\t.argc = num_words - 1,\n\t\t.argv = words + 1,\n\t};\n\n\tcmd.output = Jim_NewEmptyStringObj(context->interp);\n\tJim_IncrRefCount(cmd.output);\n\n\tint retval = c->handler(&cmd);\n\tif (retval == ERROR_COMMAND_SYNTAX_ERROR) {\n\t\t/* Print help for command */\n\t\tcommand_run_linef(context, \"usage %s\", words[0]);\n\t} else if (retval == ERROR_COMMAND_CLOSE_CONNECTION) {\n\t\t/* just fall through for a shutdown request */\n\t} else {\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_DEBUG(\"Command '%s' failed with error code %d\",\n\t\t\t\t\t\twords[0], retval);\n\t\t/*\n\t\t * Use the command output as the Tcl result.\n\t\t * Drop last '\\n' to allow command output concatenation\n\t\t * while keep using command_print() everywhere.\n\t\t */\n\t\tconst char *output_txt = Jim_String(cmd.output);\n\t\tint len = strlen(output_txt);\n\t\tif (len && output_txt[len - 1] == '\\n')\n\t\t\t--len;\n\t\tJim_SetResultString(context->interp, output_txt, len);\n\t}\n\tJim_DecrRefCount(context->interp, cmd.output);\n\n\treturn retval;\n}\n\nint command_run_line(struct command_context *context, char *line)\n{\n\t/* all the parent commands have been registered with the interpreter\n\t * so, can just evaluate the line as a script and check for\n\t * results\n\t */\n\t/* run the line thru a script engine */\n\tint retval = ERROR_FAIL;\n\tint retcode;\n\t/* Beware! This code needs to be reentrant. It is also possible\n\t * for OpenOCD commands to be invoked directly from Tcl. This would\n\t * happen when the Jim Tcl interpreter is provided by eCos for\n\t * instance.\n\t */\n\tstruct target *saved_target_override = context->current_target_override;\n\tcontext->current_target_override = NULL;\n\n\tJim_Interp *interp = context->interp;\n\tstruct command_context *old_context = Jim_GetAssocData(interp, \"context\");\n\tJim_DeleteAssocData(interp, \"context\");\n\tretcode = Jim_SetAssocData(interp, \"context\", NULL, context);\n\tif (retcode == JIM_OK) {\n\t\t/* associated the return value */\n\t\tJim_DeleteAssocData(interp, \"retval\");\n\t\tretcode = Jim_SetAssocData(interp, \"retval\", NULL, &retval);\n\t\tif (retcode == JIM_OK) {\n\t\t\tretcode = Jim_Eval_Named(interp, line, NULL, 0);\n\n\t\t\tJim_DeleteAssocData(interp, \"retval\");\n\t\t}\n\t\tJim_DeleteAssocData(interp, \"context\");\n\t\tint inner_retcode = Jim_SetAssocData(interp, \"context\", NULL, old_context);\n\t\tif (retcode == JIM_OK)\n\t\t\tretcode = inner_retcode;\n\t}\n\tcontext->current_target_override = saved_target_override;\n\tif (retcode == JIM_OK) {\n\t\tconst char *result;\n\t\tint reslen;\n\n\t\tresult = Jim_GetString(Jim_GetResult(interp), &reslen);\n\t\tif (reslen > 0) {\n\t\t\tcommand_output_text(context, result);\n\t\t\tcommand_output_text(context, \"\\n\");\n\t\t}\n\t\tretval = ERROR_OK;\n\t} else if (retcode == JIM_EXIT) {\n\t\t/* ignore.\n\t\t * exit(Jim_GetExitCode(interp)); */\n\t} else if (retcode == ERROR_COMMAND_CLOSE_CONNECTION) {\n\t\treturn retcode;\n\t} else {\n\t\tJim_MakeErrorMessage(interp);\n\t\t/* error is broadcast */\n\t\tLOG_USER(\"%s\", Jim_GetString(Jim_GetResult(interp), NULL));\n\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* It wasn't a low level OpenOCD command that failed */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nint command_run_linef(struct command_context *context, const char *format, ...)\n{\n\tint retval = ERROR_FAIL;\n\tchar *string;\n\tva_list ap;\n\tva_start(ap, format);\n\tstring = alloc_vprintf(format, ap);\n\tif (string) {\n\t\tretval = command_run_line(context, string);\n\t\tfree(string);\n\t}\n\tva_end(ap);\n\treturn retval;\n}\n\nvoid command_set_output_handler(struct command_context *context,\n\tcommand_output_handler_t output_handler, void *priv)\n{\n\tcontext->output_handler = output_handler;\n\tcontext->output_handler_priv = priv;\n}\n\nstruct command_context *copy_command_context(struct command_context *context)\n{\n\tstruct command_context *copy_context = malloc(sizeof(struct command_context));\n\n\t*copy_context = *context;\n\n\treturn copy_context;\n}\n\nvoid command_done(struct command_context *cmd_ctx)\n{\n\tif (!cmd_ctx)\n\t\treturn;\n\n\tfree(cmd_ctx);\n}\n\n/* find full path to file */\nCOMMAND_HANDLER(handle_find)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tchar *full_path = find_file(CMD_ARGV[0]);\n\tif (!full_path)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\tcommand_print(CMD, \"%s\", full_path);\n\tfree(full_path);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_echo)\n{\n\tif (CMD_ARGC == 2 && !strcmp(CMD_ARGV[0], \"-n\")) {\n\t\tLOG_USER_N(\"%s\", CMD_ARGV[1]);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_FAIL;\n\n\tLOG_USER(\"%s\", CMD_ARGV[0]);\n\treturn ERROR_OK;\n}\n\n/* Capture progress output and return as tcl return value. If the\n * progress output was empty, return tcl return value.\n */\nstatic int jim_capture(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tif (argc != 2)\n\t\treturn JIM_ERR;\n\n\tstruct log_capture_state *state = command_log_capture_start(interp);\n\n\t/* disable polling during capture. This avoids capturing output\n\t * from polling.\n\t *\n\t * This is necessary in order to avoid accidentally getting a non-empty\n\t * string for tcl fn's.\n\t */\n\tbool save_poll_mask = jtag_poll_mask();\n\n\tconst char *str = Jim_GetString(argv[1], NULL);\n\tint retcode = Jim_Eval_Named(interp, str, __THIS__FILE__, __LINE__);\n\n\tjtag_poll_unmask(save_poll_mask);\n\n\tcommand_log_capture_finish(state);\n\n\treturn retcode;\n}\n\nstruct help_entry {\n\tstruct list_head lh;\n\tchar *cmd_name;\n\tchar *help;\n\tchar *usage;\n};\n\nstatic COMMAND_HELPER(command_help_show, struct help_entry *c,\n\tbool show_help, const char *cmd_match);\n\nstatic COMMAND_HELPER(command_help_show_list, bool show_help, const char *cmd_match)\n{\n\tstruct help_entry *entry;\n\n\tlist_for_each_entry(entry, CMD_CTX->help_list, lh)\n\t\tCALL_COMMAND_HANDLER(command_help_show, entry, show_help, cmd_match);\n\treturn ERROR_OK;\n}\n\n#define HELP_LINE_WIDTH(_n) (int)(76 - (2 * _n))\n\nstatic void command_help_show_indent(unsigned n)\n{\n\tfor (unsigned i = 0; i < n; i++)\n\t\tLOG_USER_N(\"  \");\n}\nstatic void command_help_show_wrap(const char *str, unsigned n, unsigned n2)\n{\n\tconst char *cp = str, *last = str;\n\twhile (*cp) {\n\t\tconst char *next = last;\n\t\tdo {\n\t\t\tcp = next;\n\t\t\tdo {\n\t\t\t\tnext++;\n\t\t\t} while (*next != ' ' && *next != '\\t' && *next != '\\0');\n\t\t} while ((next - last < HELP_LINE_WIDTH(n)) && *next != '\\0');\n\t\tif (next - last < HELP_LINE_WIDTH(n))\n\t\t\tcp = next;\n\t\tcommand_help_show_indent(n);\n\t\tLOG_USER(\"%.*s\", (int)(cp - last), last);\n\t\tlast = cp + 1;\n\t\tn = n2;\n\t}\n}\n\nstatic COMMAND_HELPER(command_help_show, struct help_entry *c,\n\tbool show_help, const char *cmd_match)\n{\n\tunsigned int n = 0;\n\tfor (const char *s = strchr(c->cmd_name, ' '); s; s = strchr(s + 1, ' '))\n\t\tn++;\n\n\t/* If the match string occurs anywhere, we print out\n\t * stuff for this command. */\n\tbool is_match = strstr(c->cmd_name, cmd_match) ||\n\t\t(c->usage && strstr(c->usage, cmd_match)) ||\n\t\t(c->help && strstr(c->help, cmd_match));\n\n\tif (is_match) {\n\t\tif (c->usage && strlen(c->usage) > 0) {\n\t\t\tchar *msg = alloc_printf(\"%s %s\", c->cmd_name, c->usage);\n\t\t\tcommand_help_show_wrap(msg, n, n + 5);\n\t\t\tfree(msg);\n\t\t} else {\n\t\t\tcommand_help_show_wrap(c->cmd_name, n, n + 5);\n\t\t}\n\t}\n\n\tif (is_match && show_help) {\n\t\tchar *msg;\n\n\t\t/* TODO: factorize jim_command_mode() to avoid running jim command here */\n\t\tchar *request = alloc_printf(\"command mode %s\", c->cmd_name);\n\t\tif (!request) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tint retval = Jim_Eval(CMD_CTX->interp, request);\n\t\tfree(request);\n\t\tenum command_mode mode = COMMAND_UNKNOWN;\n\t\tif (retval != JIM_ERR) {\n\t\t\tconst char *result = Jim_GetString(Jim_GetResult(CMD_CTX->interp), NULL);\n\t\t\tif (!strcmp(result, \"any\"))\n\t\t\t\tmode = COMMAND_ANY;\n\t\t\telse if (!strcmp(result, \"config\"))\n\t\t\t\tmode = COMMAND_CONFIG;\n\t\t\telse if (!strcmp(result, \"exec\"))\n\t\t\t\tmode = COMMAND_EXEC;\n\t\t}\n\n\t\t/* Normal commands are runtime-only; highlight exceptions */\n\t\tif (mode != COMMAND_EXEC) {\n\t\t\tconst char *stage_msg = \"\";\n\n\t\t\tswitch (mode) {\n\t\t\t\tcase COMMAND_CONFIG:\n\t\t\t\t\tstage_msg = \" (configuration command)\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase COMMAND_ANY:\n\t\t\t\t\tstage_msg = \" (command valid any time)\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tstage_msg = \" (?mode error?)\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmsg = alloc_printf(\"%s%s\", c->help ? c->help : \"\", stage_msg);\n\t\t} else\n\t\t\tmsg = alloc_printf(\"%s\", c->help ? c->help : \"\");\n\n\t\tif (msg) {\n\t\t\tcommand_help_show_wrap(msg, n + 3, n + 3);\n\t\t\tfree(msg);\n\t\t} else\n\t\t\treturn -ENOMEM;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_help_command)\n{\n\tbool full = strcmp(CMD_NAME, \"help\") == 0;\n\tint retval;\n\tchar *cmd_match;\n\n\tif (CMD_ARGC <= 0)\n\t\tcmd_match = strdup(\"\");\n\n\telse {\n\t\tcmd_match = strdup(CMD_ARGV[0]);\n\n\t\tfor (unsigned int i = 1; i < CMD_ARGC && cmd_match; ++i) {\n\t\t\tchar *prev = cmd_match;\n\t\t\tcmd_match = alloc_printf(\"%s %s\", prev, CMD_ARGV[i]);\n\t\t\tfree(prev);\n\t\t}\n\t}\n\n\tif (!cmd_match) {\n\t\tLOG_ERROR(\"unable to build search string\");\n\t\treturn -ENOMEM;\n\t}\n\tretval = CALL_COMMAND_HANDLER(command_help_show_list, full, cmd_match);\n\n\tfree(cmd_match);\n\treturn retval;\n}\n\nstatic char *alloc_concatenate_strings(int argc, Jim_Obj * const *argv)\n{\n\tchar *prev, *all;\n\tint i;\n\n\tassert(argc >= 1);\n\n\tall = strdup(Jim_GetString(argv[0], NULL));\n\tif (!all) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn NULL;\n\t}\n\n\tfor (i = 1; i < argc; ++i) {\n\t\tprev = all;\n\t\tall = alloc_printf(\"%s %s\", all, Jim_GetString(argv[i], NULL));\n\t\tfree(prev);\n\t\tif (!all) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\treturn all;\n}\n\nstatic int exec_command(Jim_Interp *interp, struct command_context *cmd_ctx,\n\t\tstruct command *c, int argc, Jim_Obj * const *argv)\n{\n\tif (c->jim_handler)\n\t\treturn c->jim_handler(interp, argc, argv);\n\n\t/* use c->handler */\n\tunsigned int nwords;\n\tchar **words = script_command_args_alloc(argc, argv, &nwords);\n\tif (!words)\n\t\treturn JIM_ERR;\n\n\tint retval = run_command(cmd_ctx, c, (const char **)words, nwords);\n\tscript_command_args_free(words, nwords);\n\treturn command_retval_set(interp, retval);\n}\n\nstatic int jim_command_dispatch(Jim_Interp *interp, int argc, Jim_Obj * const *argv)\n{\n\t/* check subcommands */\n\tif (argc > 1) {\n\t\tchar *s = alloc_printf(\"%s %s\", Jim_GetString(argv[0], NULL), Jim_GetString(argv[1], NULL));\n\t\tJim_Obj *js = Jim_NewStringObj(interp, s, -1);\n\t\tJim_IncrRefCount(js);\n\t\tfree(s);\n\t\tJim_Cmd *cmd = Jim_GetCommand(interp, js, JIM_NONE);\n\t\tif (cmd) {\n\t\t\tint retval = Jim_EvalObjPrefix(interp, js, argc - 2, argv + 2);\n\t\t\tJim_DecrRefCount(interp, js);\n\t\t\treturn retval;\n\t\t}\n\t\tJim_DecrRefCount(interp, js);\n\t}\n\n\tscript_debug(interp, argc, argv);\n\n\tstruct command *c = jim_to_command(interp);\n\tif (!c->jim_handler && !c->handler) {\n\t\tJim_EvalObjPrefix(interp, Jim_NewStringObj(interp, \"usage\", -1), 1, argv);\n\t\treturn JIM_ERR;\n\t}\n\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\n\tif (!command_can_run(cmd_ctx, c, Jim_GetString(argv[0], NULL)))\n\t\treturn JIM_ERR;\n\n\ttarget_call_timer_callbacks();\n\n\t/*\n\t * Black magic of overridden current target:\n\t * If the command we are going to handle has a target prefix,\n\t * override the current target temporarily for the time\n\t * of processing the command.\n\t * current_target_override is used also for event handlers\n\t * therefore we prevent touching it if command has no prefix.\n\t * Previous override is saved and restored back to ensure\n\t * correct work when jim_command_dispatch() is re-entered.\n\t */\n\tstruct target *saved_target_override = cmd_ctx->current_target_override;\n\tif (c->jim_override_target)\n\t\tcmd_ctx->current_target_override = c->jim_override_target;\n\n\tint retval = exec_command(interp, cmd_ctx, c, argc, argv);\n\n\tif (c->jim_override_target)\n\t\tcmd_ctx->current_target_override = saved_target_override;\n\n\treturn retval;\n}\n\nstatic int jim_command_mode(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tenum command_mode mode;\n\n\tif (argc > 1) {\n\t\tchar *full_name = alloc_concatenate_strings(argc - 1, argv + 1);\n\t\tif (!full_name)\n\t\t\treturn JIM_ERR;\n\t\tJim_Obj *s = Jim_NewStringObj(interp, full_name, -1);\n\t\tJim_IncrRefCount(s);\n\t\tJim_Cmd *cmd = Jim_GetCommand(interp, s, JIM_NONE);\n\t\tJim_DecrRefCount(interp, s);\n\t\tfree(full_name);\n\t\tif (!cmd || !(jimcmd_is_proc(cmd) || jimcmd_is_oocd_command(cmd))) {\n\t\t\tJim_SetResultString(interp, \"unknown\", -1);\n\t\t\treturn JIM_OK;\n\t\t}\n\n\t\tif (jimcmd_is_proc(cmd)) {\n\t\t\t/* tcl proc */\n\t\t\tmode = COMMAND_ANY;\n\t\t} else {\n\t\t\tstruct command *c = jimcmd_privdata(cmd);\n\n\t\t\tmode = c->mode;\n\t\t}\n\t} else\n\t\tmode = cmd_ctx->mode;\n\n\tconst char *mode_str;\n\tswitch (mode) {\n\t\tcase COMMAND_ANY:\n\t\t\tmode_str = \"any\";\n\t\t\tbreak;\n\t\tcase COMMAND_CONFIG:\n\t\t\tmode_str = \"config\";\n\t\t\tbreak;\n\t\tcase COMMAND_EXEC:\n\t\t\tmode_str = \"exec\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmode_str = \"unknown\";\n\t\t\tbreak;\n\t}\n\tJim_SetResultString(interp, mode_str, -1);\n\treturn JIM_OK;\n}\n\nint help_del_all_commands(struct command_context *cmd_ctx)\n{\n\tstruct help_entry *curr, *n;\n\n\tlist_for_each_entry_safe(curr, n, cmd_ctx->help_list, lh) {\n\t\tlist_del(&curr->lh);\n\t\tfree(curr->cmd_name);\n\t\tfree(curr->help);\n\t\tfree(curr->usage);\n\t\tfree(curr);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int help_del_command(struct command_context *cmd_ctx, const char *cmd_name)\n{\n\tstruct help_entry *curr;\n\n\tlist_for_each_entry(curr, cmd_ctx->help_list, lh) {\n\t\tif (!strcmp(cmd_name, curr->cmd_name)) {\n\t\t\tlist_del(&curr->lh);\n\t\t\tfree(curr->cmd_name);\n\t\t\tfree(curr->help);\n\t\t\tfree(curr->usage);\n\t\t\tfree(curr);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int help_add_command(struct command_context *cmd_ctx,\n\tconst char *cmd_name, const char *help_text, const char *usage_text)\n{\n\tint cmp = -1; /* add after curr */\n\tstruct help_entry *curr;\n\n\tlist_for_each_entry_reverse(curr, cmd_ctx->help_list, lh) {\n\t\tcmp = strcmp(cmd_name, curr->cmd_name);\n\t\tif (cmp >= 0)\n\t\t\tbreak;\n\t}\n\n\tstruct help_entry *entry;\n\tif (cmp) {\n\t\tentry = calloc(1, sizeof(*entry));\n\t\tif (!entry) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tentry->cmd_name = strdup(cmd_name);\n\t\tif (!entry->cmd_name) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tfree(entry);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tlist_add(&entry->lh, &curr->lh);\n\t} else {\n\t\tentry = curr;\n\t}\n\n\tif (help_text) {\n\t\tchar *text = strdup(help_text);\n\t\tif (!text) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tfree(entry->help);\n\t\tentry->help = text;\n\t}\n\n\tif (usage_text) {\n\t\tchar *text = strdup(usage_text);\n\t\tif (!text) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tfree(entry->usage);\n\t\tentry->usage = text;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_help_add_command)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst char *help = !strcmp(CMD_NAME, \"add_help_text\") ? CMD_ARGV[1] : NULL;\n\tconst char *usage = !strcmp(CMD_NAME, \"add_usage_text\") ? CMD_ARGV[1] : NULL;\n\tif (!help && !usage) {\n\t\tLOG_ERROR(\"command name '%s' is unknown\", CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tconst char *cmd_name = CMD_ARGV[0];\n\treturn help_add_command(CMD_CTX, cmd_name, help, usage);\n}\n\n/* sleep command sleeps for <n> milliseconds\n * this is useful in target startup scripts\n */\nCOMMAND_HANDLER(handle_sleep_command)\n{\n\tbool busy = false;\n\tif (CMD_ARGC == 2) {\n\t\tif (strcmp(CMD_ARGV[1], \"busy\") == 0)\n\t\t\tbusy = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else if (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned long duration = 0;\n\tint retval = parse_ulong(CMD_ARGV[0], &duration);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!busy) {\n\t\tint64_t then = timeval_ms();\n\t\twhile (timeval_ms() - then < (int64_t)duration) {\n\t\t\ttarget_call_timer_callbacks_now();\n\t\t\tkeep_alive();\n\t\t\tusleep(1000);\n\t\t}\n\t} else\n\t\tbusy_sleep(duration);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration command_subcommand_handlers[] = {\n\t{\n\t\t.name = \"mode\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_command_mode,\n\t\t.usage = \"[command_name ...]\",\n\t\t.help = \"Returns the command modes allowed by a command: \"\n\t\t\t\"'any', 'config', or 'exec'. If no command is \"\n\t\t\t\"specified, returns the current command mode. \"\n\t\t\t\"Returns 'unknown' if an unknown command is given. \"\n\t\t\t\"Command can be multiple tokens.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration command_builtin_handlers[] = {\n\t{\n\t\t.name = \"ocd_find\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_find,\n\t\t.help = \"find full path to file\",\n\t\t.usage = \"file\",\n\t},\n\t{\n\t\t.name = \"capture\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_capture,\n\t\t.help = \"Capture progress output and return as tcl return value. If the \"\n\t\t\t\t\"progress output was empty, return tcl return value.\",\n\t\t.usage = \"command\",\n\t},\n\t{\n\t\t.name = \"echo\",\n\t\t.handler = handle_echo,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Logs a message at \\\"user\\\" priority. \"\n\t\t\t\"Option \\\"-n\\\" suppresses trailing newline\",\n\t\t.usage = \"[-n] string\",\n\t},\n\t{\n\t\t.name = \"add_help_text\",\n\t\t.handler = handle_help_add_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Add new command help text; \"\n\t\t\t\"Command can be multiple tokens.\",\n\t\t.usage = \"command_name helptext_string\",\n\t},\n\t{\n\t\t.name = \"add_usage_text\",\n\t\t.handler = handle_help_add_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Add new command usage text; \"\n\t\t\t\"command can be multiple tokens.\",\n\t\t.usage = \"command_name usage_string\",\n\t},\n\t{\n\t\t.name = \"sleep\",\n\t\t.handler = handle_sleep_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Sleep for specified number of milliseconds.  \"\n\t\t\t\"\\\"busy\\\" will busy wait instead (avoid this).\",\n\t\t.usage = \"milliseconds ['busy']\",\n\t},\n\t{\n\t\t.name = \"help\",\n\t\t.handler = handle_help_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Show full command help; \"\n\t\t\t\"command can be multiple tokens.\",\n\t\t.usage = \"[command_name]\",\n\t},\n\t{\n\t\t.name = \"usage\",\n\t\t.handler = handle_help_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Show basic command usage; \"\n\t\t\t\"command can be multiple tokens.\",\n\t\t.usage = \"[command_name]\",\n\t},\n\t{\n\t\t.name = \"command\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"core command group (introspection)\",\n\t\t.chain = command_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct command_context *command_init(const char *startup_tcl, Jim_Interp *interp)\n{\n\tstruct command_context *context = calloc(1, sizeof(struct command_context));\n\n\tcontext->mode = COMMAND_EXEC;\n\n\t/* context can be duplicated. Put list head on separate mem-chunk to keep list consistent */\n\tcontext->help_list = malloc(sizeof(*context->help_list));\n\tINIT_LIST_HEAD(context->help_list);\n\n\t/* Create a jim interpreter if we were not handed one */\n\tif (!interp) {\n\t\t/* Create an interpreter */\n\t\tinterp = Jim_CreateInterp();\n\t\t/* Add all the Jim core commands */\n\t\tJim_RegisterCoreCommands(interp);\n\t\tJim_InitStaticExtensions(interp);\n\t}\n\n\tcontext->interp = interp;\n\n\tregister_commands(context, NULL, command_builtin_handlers);\n\n\tJim_SetAssocData(interp, \"context\", NULL, context);\n\tif (Jim_Eval_Named(interp, startup_tcl, \"embedded:startup.tcl\", 1) == JIM_ERR) {\n\t\tLOG_ERROR(\"Failed to run startup.tcl (embedded into OpenOCD)\");\n\t\tJim_MakeErrorMessage(interp);\n\t\tLOG_USER_N(\"%s\", Jim_GetString(Jim_GetResult(interp), NULL));\n\t\texit(-1);\n\t}\n\tJim_DeleteAssocData(interp, \"context\");\n\n\treturn context;\n}\n\nvoid command_exit(struct command_context *context)\n{\n\tif (!context)\n\t\treturn;\n\n\tJim_FreeInterp(context->interp);\n\tfree(context->help_list);\n\tcommand_done(context);\n}\n\nint command_context_mode(struct command_context *cmd_ctx, enum command_mode mode)\n{\n\tif (!cmd_ctx)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcmd_ctx->mode = mode;\n\treturn ERROR_OK;\n}\n\nvoid process_jim_events(struct command_context *cmd_ctx)\n{\n\tstatic int recursion;\n\tif (recursion)\n\t\treturn;\n\n\trecursion++;\n\tJim_ProcessEvents(cmd_ctx->interp, JIM_ALL_EVENTS | JIM_DONT_WAIT);\n\trecursion--;\n}\n\n#define DEFINE_PARSE_NUM_TYPE(name, type, func, min, max) \\\n\tint parse ## name(const char *str, type * ul) \\\n\t{ \\\n\t\tif (!*str) { \\\n\t\t\tLOG_ERROR(\"Invalid command argument\"); \\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID; \\\n\t\t} \\\n\t\tchar *end; \\\n\t\terrno = 0; \\\n\t\t*ul = func(str, &end, 0); \\\n\t\tif (*end) { \\\n\t\t\tLOG_ERROR(\"Invalid command argument\"); \\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID; \\\n\t\t} \\\n\t\tif ((max == *ul) && (errno == ERANGE)) { \\\n\t\t\tLOG_ERROR(\"Argument overflow\");\t\\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_OVERFLOW;\t\\\n\t\t} \\\n\t\tif (min && (min == *ul) && (errno == ERANGE)) { \\\n\t\t\tLOG_ERROR(\"Argument underflow\"); \\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_UNDERFLOW; \\\n\t\t} \\\n\t\treturn ERROR_OK; \\\n\t}\nDEFINE_PARSE_NUM_TYPE(_ulong, unsigned long, strtoul, 0, ULONG_MAX)\nDEFINE_PARSE_NUM_TYPE(_ullong, unsigned long long, strtoull, 0, ULLONG_MAX)\nDEFINE_PARSE_NUM_TYPE(_long, long, strtol, LONG_MIN, LONG_MAX)\nDEFINE_PARSE_NUM_TYPE(_llong, long long, strtoll, LLONG_MIN, LLONG_MAX)\n\n#define DEFINE_PARSE_WRAPPER(name, type, min, max, functype, funcname) \\\n\tint parse ## name(const char *str, type * ul) \\\n\t{ \\\n\t\tfunctype n; \\\n\t\tint retval = parse ## funcname(str, &n); \\\n\t\tif (retval != ERROR_OK)\t\\\n\t\t\treturn retval; \\\n\t\tif (n > max) \\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_OVERFLOW;\t\\\n\t\tif (min) \\\n\t\t\treturn ERROR_COMMAND_ARGUMENT_UNDERFLOW; \\\n\t\t*ul = n; \\\n\t\treturn ERROR_OK; \\\n\t}\n\n#define DEFINE_PARSE_ULONGLONG(name, type, min, max) \\\n\tDEFINE_PARSE_WRAPPER(name, type, min, max, unsigned long long, _ullong)\nDEFINE_PARSE_ULONGLONG(_uint, unsigned, 0, UINT_MAX)\nDEFINE_PARSE_ULONGLONG(_u64,  uint64_t, 0, UINT64_MAX)\nDEFINE_PARSE_ULONGLONG(_u32,  uint32_t, 0, UINT32_MAX)\nDEFINE_PARSE_ULONGLONG(_u16,  uint16_t, 0, UINT16_MAX)\nDEFINE_PARSE_ULONGLONG(_u8,   uint8_t,  0, UINT8_MAX)\n\nDEFINE_PARSE_ULONGLONG(_target_addr, target_addr_t, 0, TARGET_ADDR_MAX)\n\n#define DEFINE_PARSE_LONGLONG(name, type, min, max) \\\n\tDEFINE_PARSE_WRAPPER(name, type, min, max, long long, _llong)\nDEFINE_PARSE_LONGLONG(_int, int,     n < INT_MIN,   INT_MAX)\nDEFINE_PARSE_LONGLONG(_s64, int64_t, n < INT64_MIN, INT64_MAX)\nDEFINE_PARSE_LONGLONG(_s32, int32_t, n < INT32_MIN, INT32_MAX)\nDEFINE_PARSE_LONGLONG(_s16, int16_t, n < INT16_MIN, INT16_MAX)\nDEFINE_PARSE_LONGLONG(_s8,  int8_t,  n < INT8_MIN,  INT8_MAX)\n\nstatic int command_parse_bool(const char *in, bool *out,\n\tconst char *on, const char *off)\n{\n\tif (strcasecmp(in, on) == 0)\n\t\t*out = true;\n\telse if (strcasecmp(in, off) == 0)\n\t\t*out = false;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\treturn ERROR_OK;\n}\n\nint command_parse_bool_arg(const char *in, bool *out)\n{\n\tif (command_parse_bool(in, out, \"on\", \"off\") == ERROR_OK)\n\t\treturn ERROR_OK;\n\tif (command_parse_bool(in, out, \"enable\", \"disable\") == ERROR_OK)\n\t\treturn ERROR_OK;\n\tif (command_parse_bool(in, out, \"true\", \"false\") == ERROR_OK)\n\t\treturn ERROR_OK;\n\tif (command_parse_bool(in, out, \"yes\", \"no\") == ERROR_OK)\n\t\treturn ERROR_OK;\n\tif (command_parse_bool(in, out, \"1\", \"0\") == ERROR_OK)\n\t\treturn ERROR_OK;\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label)\n{\n\tswitch (CMD_ARGC) {\n\t\tcase 1: {\n\t\t\tconst char *in = CMD_ARGV[0];\n\t\t\tif (command_parse_bool_arg(in, out) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s: argument '%s' is not valid\", CMD_NAME, in);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\t\t\t/* fallthrough */\n\t\tcase 0:\n\t\t\tLOG_INFO(\"%s is %s\", label, *out ? \"enabled\" : \"disabled\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/command.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_COMMAND_H\n#define OPENOCD_HELPER_COMMAND_H\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#include <helper/jim-nvp.h>\n#include <helper/list.h>\n#include <helper/types.h>\n\n/* To achieve C99 printf compatibility in MinGW, gnu_printf should be\n * used for __attribute__((format( ... ))), with GCC v4.4 or later\n */\n#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))\n#define PRINTF_ATTRIBUTE_FORMAT gnu_printf\n#else\n#define PRINTF_ATTRIBUTE_FORMAT printf\n#endif\n\n/**\n * OpenOCD command mode is COMMAND_CONFIG at start, then switches to COMMAND_EXEC\n * during the execution of command 'init'.\n * The field 'mode' in struct command_registration specifies in which command mode\n * the command can be executed:\n * - during COMMAND_CONFIG only,\n * - during COMMAND_EXEC only,\n * - in both modes (COMMAND_ANY).\n */\nenum command_mode {\n\tCOMMAND_EXEC,\n\tCOMMAND_CONFIG,\n\tCOMMAND_ANY,\n\tCOMMAND_UNKNOWN = -1, /* error condition */\n};\n\nstruct command_context;\n\n/** The type signature for command context's output handler. */\ntypedef int (*command_output_handler_t)(struct command_context *context,\n\t\tconst char *line);\n\nstruct command_context {\n\tJim_Interp *interp;\n\tenum command_mode mode;\n\tstruct target *current_target;\n\t\t/* The target set by 'targets xx' command or the latest created */\n\tstruct target *current_target_override;\n\t\t/* If set overrides current_target\n\t\t * It happens during processing of\n\t\t *\t1) a target prefixed command\n\t\t *\t2) an event handler\n\t\t * Pay attention to reentrancy when setting override.\n\t\t */\n\tcommand_output_handler_t output_handler;\n\tvoid *output_handler_priv;\n\tstruct list_head *help_list;\n};\n\nstruct command;\n\n/**\n * When run_command is called, a new instance will be created on the\n * stack, filled with the proper values, and passed by reference to the\n * required COMMAND_HANDLER routine.\n */\nstruct command_invocation {\n\tstruct command_context *ctx;\n\tstruct command *current;\n\tconst char *name;\n\tunsigned argc;\n\tconst char **argv;\n\tJim_Obj *output;\n};\n\n/**\n * Return true if the command @c cmd is registered by OpenOCD.\n */\nbool jimcmd_is_oocd_command(Jim_Cmd *cmd);\n\n/**\n * Return the pointer to the command's private data specified during the\n * registration of command @a cmd .\n */\nvoid *jimcmd_privdata(Jim_Cmd *cmd);\n\n/**\n * Command handlers may be defined with more parameters than the base\n * set provided by command.c.  This macro uses C99 magic to allow\n * defining all such derivative types using this macro.\n */\n#define __COMMAND_HANDLER(name, extra ...) \\\n\t\tint name(struct command_invocation *cmd, ## extra)\n\n/**\n * Use this to macro to call a command helper (or a nested handler).\n * It provides command handler authors protection against reordering or\n * removal of unused parameters.\n *\n * @b Note: This macro uses lexical capture to provide some arguments.\n * As a result, this macro should be used @b only within functions\n * defined by the COMMAND_HANDLER or COMMAND_HELPER macros.  Those\n * macros provide the expected lexical context captured by this macro.\n * Furthermore, it should be used only from the top-level of handler or\n * helper function, or care must be taken to avoid redefining the same\n * variables in intervening scope(s) by accident.\n */\n#define CALL_COMMAND_HANDLER(name, extra ...) \\\n\t\tname(cmd, ## extra)\n\n/**\n * Always use this macro to define new command handler functions.\n * It ensures the parameters are ordered, typed, and named properly, so\n * they be can be used by other macros (e.g. COMMAND_PARSE_NUMBER).\n * All command handler functions must be defined as static in scope.\n */\n#define COMMAND_HANDLER(name) \\\n\t\tstatic __COMMAND_HANDLER(name)\n\n/**\n * Similar to COMMAND_HANDLER, except some parameters are expected.\n * A helper is globally-scoped because it may be shared between several\n * source files (e.g. the s3c24xx device command helper).\n */\n#define COMMAND_HELPER(name, extra ...) __COMMAND_HANDLER(name, extra)\n\n/**\n * Use this macro to access the command being handled,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD (cmd)\n/**\n * Use this macro to access the context of the command being handled,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_CTX (cmd->ctx)\n/**\n * Use this macro to access the number of arguments for the command being\n * handled, rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_ARGC (cmd->argc)\n/**\n * Use this macro to access the arguments for the command being handled,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_ARGV (cmd->argv)\n/**\n * Use this macro to access the name of the command being handled,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_NAME (cmd->name)\n/**\n * Use this macro to access the current command being handled,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_CURRENT (cmd->current)\n/**\n * Use this macro to access the invoked command handler's data pointer,\n * rather than accessing the variable directly.  It may be moved.\n */\n#define CMD_DATA (CMD_CURRENT->jim_handler_data)\n\n/**\n * The type signature for command handling functions.  They are\n * usually registered as part of command_registration, providing\n * a high-level means for executing a command.\n *\n * If the command fails, it *MUST* return a value != ERROR_OK\n * (many commands break this rule, patches welcome!)\n *\n * This is *especially* important for commands such as writing\n * to flash or verifying memory. The reason is that those commands\n * can be used by programs to determine if the operation succeeded\n * or not. If the operation failed, then a program can try\n * an alternative approach.\n *\n * Returning ERROR_COMMAND_SYNTAX_ERROR will have the effect of\n * printing out the syntax of the command.\n */\ntypedef __COMMAND_HANDLER((*command_handler_t));\n\nstruct command {\n\tchar *name;\n\tcommand_handler_t handler;\n\tJim_CmdProc *jim_handler;\n\tvoid *jim_handler_data;\n\t\t/* Command handlers can use it for any handler specific data */\n\tstruct target *jim_override_target;\n\t\t/* Used only for target of target-prefixed cmd */\n\tenum command_mode mode;\n};\n\n/*\n * Return the struct command pointer kept in private data\n * Used to enforce check on data type\n */\nstatic inline struct command *jim_to_command(Jim_Interp *interp)\n{\n\treturn Jim_CmdPrivData(interp);\n}\n\n/*\n * Commands should be registered by filling in one or more of these\n * structures and passing them to [un]register_commands().\n *\n * A conventional format should be used for help strings, to provide both\n * usage and basic information:\n * @code\n * \"@<options@> ... - some explanation text\"\n * @endcode\n *\n * @param name The name of the command to register, which must not have\n * been registered previously in the intended context.\n * @param handler The callback function that will be called.  If NULL,\n * then the command serves as a placeholder for its children or a script.\n * @param mode The command mode(s) in which this command may be run.\n * @param help The help text that will be displayed to the user.\n */\nstruct command_registration {\n\tconst char *name;\n\tcommand_handler_t handler;\n\tJim_CmdProc *jim_handler;\n\tenum command_mode mode;\n\tconst char *help;\n\t/** a string listing the options and arguments, required or optional */\n\tconst char *usage;\n\n\t/**\n\t * If non-NULL, the commands in @c chain will be registered in\n\t * the same context and scope of this registration record.\n\t * This allows modules to inherit lists commands from other\n\t * modules.\n\t */\n\tconst struct command_registration *chain;\n};\n\n/** Use this as the last entry in an array of command_registration records. */\n#define COMMAND_REGISTRATION_DONE { .name = NULL, .chain = NULL }\n\nint __register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,\n\t\tconst struct command_registration *cmds, void *data,\n\t\tstruct target *override_target);\n\n/**\n * Register one or more commands in the specified context, as children\n * of @c parent (or top-level commends, if NULL).  In a registration's\n * record contains a non-NULL @c chain member and name is NULL, the\n * commands on the chain will be registered in the same context.\n * Otherwise, the chained commands are added as children of the command.\n *\n * @param cmd_ctx The command_context in which to register the command.\n * @param cmd_prefix Register this command as a child of this, or NULL to\n * register a top-level command.\n * @param cmds Pointer to an array of command_registration records that\n * contains the desired command parameters.  The last record must have\n * NULL for all fields.\n * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.\n */\nstatic inline int register_commands(struct command_context *cmd_ctx, const char *cmd_prefix,\n\t\tconst struct command_registration *cmds)\n{\n\treturn __register_commands(cmd_ctx, cmd_prefix, cmds, NULL, NULL);\n}\n\n/**\n * Register one or more commands, as register_commands(), plus specify\n * that command should override the current target\n *\n * @param cmd_ctx The command_context in which to register the command.\n * @param cmd_prefix Register this command as a child of this, or NULL to\n * register a top-level command.\n * @param cmds Pointer to an array of command_registration records that\n * contains the desired command parameters.  The last record must have\n * NULL for all fields.\n * @param target The target that has to override current target.\n * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.\n */\nstatic inline int register_commands_override_target(struct command_context *cmd_ctx,\n\t\tconst char *cmd_prefix, const struct command_registration *cmds,\n\t\tstruct target *target)\n{\n\treturn __register_commands(cmd_ctx, cmd_prefix, cmds, NULL, target);\n}\n\n/**\n * Register one or more commands, as register_commands(), plus specify\n * a pointer to command private data that would be accessible through\n * the macro CMD_DATA. The private data will not be freed when command\n * is unregistered.\n *\n * @param cmd_ctx The command_context in which to register the command.\n * @param cmd_prefix Register this command as a child of this, or NULL to\n * register a top-level command.\n * @param cmds Pointer to an array of command_registration records that\n * contains the desired command parameters.  The last record must have\n * NULL for all fields.\n * @param data The command private data.\n * @returns ERROR_OK on success; ERROR_FAIL if any registration fails.\n */\nstatic inline int register_commands_with_data(struct command_context *cmd_ctx,\n\t\tconst char *cmd_prefix, const struct command_registration *cmds,\n\t\tvoid *data)\n{\n\treturn __register_commands(cmd_ctx, cmd_prefix, cmds, data, NULL);\n}\n\n/**\n * Unregisters all commands from the specified context.\n * @param cmd_ctx The context that will be cleared of registered commands.\n * @param cmd_prefix If given, only clear commands from under this one command.\n * @returns ERROR_OK on success, or an error code.\n */\nint unregister_all_commands(struct command_context *cmd_ctx,\n\t\tconst char *cmd_prefix);\n\n/**\n * Unregisters the help for all commands. Used at exit to remove the help\n * added through the commands 'add_help_text' and 'add_usage_text'.\n * @param cmd_ctx The context that will be cleared of registered helps.\n * @returns ERROR_OK on success, or an error code.\n */\nint help_del_all_commands(struct command_context *cmd_ctx);\n\nvoid command_set_output_handler(struct command_context *context,\n\t\tcommand_output_handler_t output_handler, void *priv);\n\n\nint command_context_mode(struct command_context *context, enum command_mode mode);\n\n/* Return the current command context associated with the Jim interpreter or\n * alternatively the global default command interpreter\n */\nstruct command_context *current_command_context(Jim_Interp *interp);\n/**\n * Creates a new command context using the startup TCL provided and\n * the existing Jim interpreter, if any. If interp == NULL, then command_init\n * creates a command interpreter.\n */\nstruct command_context *command_init(const char *startup_tcl, Jim_Interp *interp);\n/**\n * Shutdown a command context.\n *\n * Free the command context and the associated Jim interpreter.\n *\n * @param context The command_context that will be destroyed.\n */\nvoid command_exit(struct command_context *context);\n/**\n * Creates a copy of an existing command context.  This does not create\n * a deep copy of the command list, so modifications in one context will\n * affect all shared contexts.  The caller must track reference counting\n * and ensure the commands are freed before destroying the last instance.\n * @param cmd_ctx The command_context that will be copied.\n * @returns A new command_context with the same state as the original.\n */\nstruct command_context *copy_command_context(struct command_context *cmd_ctx);\n/**\n * Frees the resources associated with a command context.  The commands\n * are not removed, so unregister_all_commands() must be called first.\n * @param context The command_context that will be destroyed.\n */\nvoid command_done(struct command_context *context);\n\n/*\n * command_print() and command_print_sameline() are used to produce the TCL\n * output of OpenOCD commands. command_print() automatically adds a '\\n' at\n * the end or the format string. Use command_print_sameline() to avoid the\n * trailing '\\n', e.g. to concatenate the command output in the same line.\n * The very last '\\n' of the command is stripped away (see run_command()).\n * For commands that strictly require a '\\n' as last output character, add\n * it explicitly with either an empty command_print() or with a '\\n' in the\n * last command_print() and add a comment to document it.\n */\nvoid command_print(struct command_invocation *cmd, const char *format, ...)\n__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));\nvoid command_print_sameline(struct command_invocation *cmd, const char *format, ...)\n__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));\n\nint command_run_line(struct command_context *context, char *line);\nint command_run_linef(struct command_context *context, const char *format, ...)\n__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 2, 3)));\nvoid command_output_text(struct command_context *context, const char *data);\n\nvoid process_jim_events(struct command_context *cmd_ctx);\n\n#define ERROR_COMMAND_CLOSE_CONNECTION\t\t(-600)\n#define ERROR_COMMAND_SYNTAX_ERROR\t\t\t(-601)\n#define ERROR_COMMAND_NOTFOUND\t\t\t\t(-602)\n#define ERROR_COMMAND_ARGUMENT_INVALID\t\t(-603)\n#define ERROR_COMMAND_ARGUMENT_OVERFLOW\t\t(-604)\n#define ERROR_COMMAND_ARGUMENT_UNDERFLOW\t(-605)\n\nint parse_ulong(const char *str, unsigned long *ul);\nint parse_ullong(const char *str, unsigned long long *ul);\n\nint parse_long(const char *str, long *ul);\nint parse_llong(const char *str, long long *ul);\n\n#define DECLARE_PARSE_WRAPPER(name, type) \\\n\t\tint parse ## name(const char *str, type * ul)\n\nDECLARE_PARSE_WRAPPER(_uint, unsigned);\nDECLARE_PARSE_WRAPPER(_u64, uint64_t);\nDECLARE_PARSE_WRAPPER(_u32, uint32_t);\nDECLARE_PARSE_WRAPPER(_u16, uint16_t);\nDECLARE_PARSE_WRAPPER(_u8, uint8_t);\n\nDECLARE_PARSE_WRAPPER(_int, int);\nDECLARE_PARSE_WRAPPER(_s64, int64_t);\nDECLARE_PARSE_WRAPPER(_s32, int32_t);\nDECLARE_PARSE_WRAPPER(_s16, int16_t);\nDECLARE_PARSE_WRAPPER(_s8, int8_t);\n\nDECLARE_PARSE_WRAPPER(_target_addr, target_addr_t);\n\n/**\n * @brief parses the string @a in into @a out as a @a type, or prints\n * a command error and passes the error code to the caller.  If an error\n * does occur, the calling function will return the error code produced\n * by the parsing function (one of ERROR_COMMAND_ARGUMENT_*).\n *\n * This function may cause the calling function to return immediately,\n * so it should be used carefully to avoid leaking resources.  In most\n * situations, parsing should be completed in full before proceeding\n * to allocate resources, and this strategy will most prevents leaks.\n */\n#define COMMAND_PARSE_NUMBER(type, in, out) \\\n\tdo { \\\n\t\tint retval_macro_tmp = parse_ ## type(in, &(out)); \\\n\t\tif (retval_macro_tmp != ERROR_OK) { \\\n\t\t\tcommand_print(CMD, stringify(out) \\\n\t\t\t\t\" option value ('%s') is not valid\", in); \\\n\t\t\treturn retval_macro_tmp; \\\n\t\t} \\\n\t} while (0)\n\n#define COMMAND_PARSE_ADDRESS(in, out) \\\n\tCOMMAND_PARSE_NUMBER(target_addr, in, out)\n\n/**\n * @brief parses the command argument at position @a argn into @a out\n * as a @a type, or prints a command error referring to @a name_str\n * and passes the error code to the caller. @a argn will be incremented\n * if no error occurred. Otherwise the calling function will return\n * the error code produced by the parsing function.\n *\n * This function may cause the calling function to return immediately,\n * so it should be used carefully to avoid leaking resources.  In most\n * situations, parsing should be completed in full before proceeding\n * to allocate resources, and this strategy will most prevents leaks.\n */\n#define COMMAND_PARSE_ADDITIONAL_NUMBER(type, argn, out, name_str) \\\n\tdo { \\\n\t\tif (argn+1 >= CMD_ARGC || CMD_ARGV[argn+1][0] == '-') { \\\n\t\t\tcommand_print(CMD, \"no \" name_str \" given\"); \\\n\t\t\treturn ERROR_FAIL; \\\n\t\t} \\\n\t\t++argn; \\\n\t\tCOMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \\\n\t} while (0)\n\n/**\n * @brief parses the command argument at position @a argn into @a out\n * as a @a type if the argument @a argn does not start with '-'.\n * and passes the error code to the caller. @a argn will be incremented\n * if no error occurred. Otherwise the calling function will return\n * the error code produced by the parsing function.\n *\n * This function may cause the calling function to return immediately,\n * so it should be used carefully to avoid leaking resources.  In most\n * situations, parsing should be completed in full before proceeding\n * to allocate resources, and this strategy will most prevents leaks.\n */\n#define COMMAND_PARSE_OPTIONAL_NUMBER(type, argn, out) \\\n\tdo { \\\n\t\tif (argn+1 < CMD_ARGC && CMD_ARGV[argn+1][0] != '-') { \\\n\t\t\t++argn; \\\n\t\t\tCOMMAND_PARSE_NUMBER(type, CMD_ARGV[argn], out); \\\n\t\t} \\\n\t} while (0)\n\n/**\n * Parse the string @c as a binary parameter, storing the boolean value\n * in @c out.  The strings @c on and @c off are used to match different\n * strings for true and false options (e.g. \"on\" and \"off\" or\n * \"enable\" and \"disable\").\n */\n#define COMMAND_PARSE_BOOL(in, out, on, off) \\\n\tdo { \\\n\t\tbool value; \\\n\t\tint retval_macro_tmp = command_parse_bool_arg(in, &value); \\\n\t\tif (retval_macro_tmp != ERROR_OK) { \\\n\t\t\tcommand_print(CMD, stringify(out) \\\n\t\t\t\t\" option value ('%s') is not valid\", in); \\\n\t\t\tcommand_print(CMD, \"  choices are '%s' or '%s'\", \\\n\t\t\t\ton, off); \\\n\t\t\treturn retval_macro_tmp; \\\n\t\t} \\\n\t\tout = value; \\\n\t} while (0)\n\nint command_parse_bool_arg(const char *in, bool *out);\nCOMMAND_HELPER(handle_command_parse_bool, bool *out, const char *label);\n\n/** parses an on/off command argument */\n#define COMMAND_PARSE_ON_OFF(in, out) \\\n\tCOMMAND_PARSE_BOOL(in, out, \"on\", \"off\")\n/** parses an enable/disable command argument */\n#define COMMAND_PARSE_ENABLE(in, out) \\\n\tCOMMAND_PARSE_BOOL(in, out, \"enable\", \"disable\")\n\n#endif /* OPENOCD_HELPER_COMMAND_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/compiler.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * This file contains compiler specific workarounds to handle different\n * compilers and different compiler versions.\n * Inspired by Linux's include/linux/compiler_attributes.h\n * and file sys/cdefs.h in libc and newlib.\n */\n\n#ifndef OPENOCD_HELPER_COMPILER_H\n#define OPENOCD_HELPER_COMPILER_H\n\n/*\n * __has_attribute is supported on gcc >= 5, clang >= 2.9 and icc >= 17.\n */\n#ifndef __has_attribute\n# define __has_attribute(x) 0\n#endif\n\n/*\n * The __returns_nonnull function attribute marks the return type of the function\n * as always being non-null.\n */\n#ifndef __returns_nonnull\n# if __has_attribute(__returns_nonnull__)\n#  define __returns_nonnull __attribute__((__returns_nonnull__))\n# else\n#  define __returns_nonnull\n# endif\n#endif\n\n/*\n * The __nonnull function attribute marks pointer parameters that\n * must not be NULL.\n *\n * clang for Apple defines\n * #define __nonnull _Nonnull\n * that is a per argument attribute, incompatible with the gcc per function attribute __nonnull__.\n * gcc for Apple includes sys/cdefs.h from MacOSX.sdk that defines\n * #define __nonnull\n * In both cases, undefine __nonnull to keep compatibility among compilers and platforms.\n */\n#if defined(__APPLE__)\n# undef __nonnull\n#endif\n#ifndef __nonnull\n# if __has_attribute(__nonnull__)\n#  define __nonnull(params) __attribute__ ((__nonnull__ params))\n# else\n#  define __nonnull(params)\n# endif\n#endif\n\n#endif /* OPENOCD_HELPER_COMPILER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/configuration.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"configuration.h\"\n#include \"log.h\"\n#include \"replacements.h\"\n\nstatic size_t num_config_files;\nstatic char **config_file_names;\n\nstatic size_t num_script_dirs;\nstatic char **script_search_dirs;\n\nvoid add_script_search_dir(const char *dir)\n{\n\tnum_script_dirs++;\n\tscript_search_dirs = realloc(script_search_dirs, (num_script_dirs + 1) * sizeof(char *));\n\n\tscript_search_dirs[num_script_dirs-1] = strdup(dir);\n\tscript_search_dirs[num_script_dirs] = NULL;\n\n\tLOG_DEBUG(\"adding %s\", dir);\n}\n\nvoid add_config_command(const char *cfg)\n{\n\tnum_config_files++;\n\tconfig_file_names = realloc(config_file_names, (num_config_files + 1) * sizeof(char *));\n\n\tconfig_file_names[num_config_files-1] = strdup(cfg);\n\tconfig_file_names[num_config_files] = NULL;\n}\n\nvoid free_config(void)\n{\n\twhile (num_config_files)\n\t\tfree(config_file_names[--num_config_files]);\n\n\tfree(config_file_names);\n\tconfig_file_names = NULL;\n\n\twhile (num_script_dirs)\n\t\tfree(script_search_dirs[--num_script_dirs]);\n\n\tfree(script_search_dirs);\n\tscript_search_dirs = NULL;\n}\n\n/* return full path or NULL according to search rules */\nchar *find_file(const char *file)\n{\n\tFILE *fp = NULL;\n\tchar **search_dirs = script_search_dirs;\n\tchar *dir;\n\tchar const *mode = \"r\";\n\tchar *full_path;\n\n\t/* Check absolute and relative to current working dir first.\n\t * This keeps full_path reporting belowing working. */\n\tfull_path = alloc_printf(\"%s\", file);\n\tfp = fopen(full_path, mode);\n\n\twhile (!fp) {\n\t\tfree(full_path);\n\t\tfull_path = NULL;\n\t\tdir = *search_dirs++;\n\n\t\tif (!dir)\n\t\t\tbreak;\n\n\t\tfull_path = alloc_printf(\"%s/%s\", dir, file);\n\t\tfp = fopen(full_path, mode);\n\t}\n\n\tif (fp) {\n\t\tfclose(fp);\n\t\tLOG_DEBUG(\"found %s\", full_path);\n\t\treturn full_path;\n\t}\n\n\tfree(full_path);\n\n\treturn NULL;\n}\n\nFILE *open_file_from_path(const char *file, const char *mode)\n{\n\tif (mode[0] != 'r')\n\t\treturn fopen(file, mode);\n\telse {\n\t\tchar *full_path = find_file(file);\n\t\tif (!full_path)\n\t\t\treturn NULL;\n\t\tFILE *fp = NULL;\n\t\tfp = fopen(full_path, mode);\n\t\tfree(full_path);\n\t\treturn fp;\n\t}\n}\n\nint parse_config_file(struct command_context *cmd_ctx)\n{\n\tint retval;\n\tchar **cfg;\n\n\tif (!config_file_names) {\n\t\tcommand_run_line(cmd_ctx, \"script openocd.cfg\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcfg = config_file_names;\n\n\twhile (*cfg) {\n\t\tretval = command_run_line(cmd_ctx, *cfg);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcfg++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n#ifndef _WIN32\n#include <pwd.h>\n#endif\n\nchar *get_home_dir(const char *append_path)\n{\n#ifdef _WIN32\n\tchar homepath[MAX_PATH];\n#endif\n\n\tchar *home = getenv(\"HOME\");\n\n\tif (!home) {\n\n#ifdef _WIN32\n\t\thome = getenv(\"USERPROFILE\");\n\n\t\tif (!home) {\n\t\t\tchar *drive = getenv(\"HOMEDRIVE\");\n\t\t\tchar *path = getenv(\"HOMEPATH\");\n\t\t\tif (drive && path) {\n\t\t\t\tsnprintf(homepath, MAX_PATH, \"%s/%s\", drive, path);\n\t\t\t\thome = homepath;\n\t\t\t}\n\t\t}\n#else\n\t\tstruct passwd *pwd = getpwuid(getuid());\n\t\tif (pwd)\n\t\t\thome = pwd->pw_dir;\n\n#endif\n\t}\n\n\tif (!home)\n\t\treturn home;\n\n\tchar *home_path;\n\n\tif (append_path)\n\t\thome_path = alloc_printf(\"%s/%s\", home, append_path);\n\telse\n\t\thome_path = alloc_printf(\"%s\", home);\n\n\treturn home_path;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/configuration.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_CONFIGURATION_H\n#define OPENOCD_HELPER_CONFIGURATION_H\n\n#include <helper/command.h>\n#include <stdio.h>\nint parse_cmdline_args(struct command_context *cmd_ctx,\n\t\tint argc, char *argv[]);\n\nint parse_config_file(struct command_context *cmd_ctx);\nvoid add_config_command(const char *cfg);\n\nvoid add_script_search_dir(const char *dir);\n\nvoid free_config(void);\n\nint configuration_output_handler(struct command_context *cmd_ctx,\n\t\tconst char *line);\n\nFILE *open_file_from_path(const char *file, const char *mode);\n\nchar *find_file(const char *name);\nchar *get_home_dir(const char *append_path);\n\n#endif /* OPENOCD_HELPER_CONFIGURATION_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/crc32.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2014 by Franck Jullien                             *\n *   elec4fun@gmail.com                                                    *\n *                                                                         *\n *   Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg            *\n *   marian.buschsieweke@ovgu.de                                           *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"crc32.h\"\n#include <stdint.h>\n#include <stddef.h>\n\nstatic uint32_t crc_le_step(uint32_t poly, uint32_t crc, uint32_t data_in,\n\t\tunsigned int data_bits)\n{\n\tfor (unsigned int i = 0; i < data_bits; i++) {\n\t\tuint32_t d, c;\n\t\td = ((data_in >> i) & 0x1) ? 0xffffffff : 0;\n\t\tc = (crc & 0x1) ? 0xffffffff : 0;\n\t\tcrc = crc >> 1;\n\t\tcrc = crc ^ ((d ^ c) & poly);\n\t}\n\n\treturn crc;\n}\n\nuint32_t crc32_le(uint32_t poly, uint32_t seed, const void *_data,\n\t\tsize_t data_len)\n{\n\tif (((uintptr_t)_data & 0x3) || (data_len & 0x3)) {\n\t\t/* data is unaligned, processing data one byte at a time */\n\t\tconst uint8_t *data = _data;\n\t\tfor (size_t i = 0; i < data_len; i++)\n\t\t\tseed = crc_le_step(poly, seed, data[i], 8);\n\t} else {\n\t\t/* data is aligned, processing 32 bit at a time */\n\t\tdata_len >>= 2;\n\t\tconst uint32_t *data = _data;\n\t\tfor (size_t i = 0; i < data_len; i++)\n\t\t\tseed = crc_le_step(poly, seed, data[i], 32);\n\t}\n\n\treturn seed;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/crc32.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg            *\n *   marian.buschsieweke@ovgu.de                                           *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_CRC32_H\n#define OPENOCD_HELPER_CRC32_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n/** @file\n * A generic CRC32 implementation\n */\n\n/**\n * CRC32 polynomial commonly used for little endian CRC32\n */\n#define CRC32_POLY_LE\t0xedb88320\n\n/**\n * Calculate the CRC32 value of the given data\n * @param\tpoly\t\tThe polynomial of the CRC\n * @param\tseed\t\tThe seed to use (mostly either `0` or `0xffffffff`)\n * @param\tdata\t\tThe data to calculate the CRC32 of\n * @param\tdata_len\tThe length of the data in @p data in bytes\n * @return\tThe CRC value of the first @p data_len bytes at @p data\n * @note\tThis function can be used to incrementally compute the CRC one\n *\t\t\tchunk of data at a time by using the CRC32 of the previous chunk\n *\t\t\tas @p seed for the next chunk.\n */\nuint32_t crc32_le(uint32_t poly, uint32_t seed, const void *data,\n\t\tsize_t data_len);\n\n#endif /* OPENOCD_HELPER_CRC32_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/fileio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"log.h\"\n#include \"configuration.h\"\n#include \"fileio.h\"\n#include \"replacements.h\"\n\nstruct fileio {\n\tchar *url;\n\tsize_t size;\n\tenum fileio_type type;\n\tenum fileio_access access;\n\tFILE *file;\n};\n\nstatic inline int fileio_close_local(struct fileio *fileio)\n{\n\tint retval = fclose(fileio->file);\n\tif (retval != 0) {\n\t\tif (retval == EBADF)\n\t\t\tLOG_ERROR(\"BUG: fileio->file not a valid file descriptor\");\n\t\telse\n\t\t\tLOG_ERROR(\"couldn't close %s: %s\", fileio->url, strerror(errno));\n\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic inline int fileio_open_local(struct fileio *fileio)\n{\n\tchar file_access[4];\n\tssize_t file_size;\n\n\tswitch (fileio->access) {\n\t\tcase FILEIO_READ:\n\t\t\tstrcpy(file_access, \"r\");\n\t\t\tbreak;\n\t\tcase FILEIO_WRITE:\n\t\t\tstrcpy(file_access, \"w\");\n\t\t\tbreak;\n\t\tcase FILEIO_READWRITE:\n\t\t\tstrcpy(file_access, \"w+\");\n\t\t\tbreak;\n\t\tcase FILEIO_APPEND:\n\t\t\tstrcpy(file_access, \"a\");\n\t\t\tbreak;\n\t\tcase FILEIO_APPENDREAD:\n\t\t\tstrcpy(file_access, \"a+\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: access neither read, write nor readwrite\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* win32 always opens in binary mode */\n#ifndef _WIN32\n\tif (fileio->type == FILEIO_BINARY)\n#endif\n\t\tstrcat(file_access, \"b\");\n\n\tfileio->file = open_file_from_path(fileio->url, file_access);\n\tif (!fileio->file) {\n\t\tLOG_ERROR(\"couldn't open %s\", fileio->url);\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tfile_size = 0;\n\n\tif ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE)) {\n\t\t/* NB! Here we use fseek() instead of stat(), since stat is a\n\t\t * more advanced operation that might not apply to e.g. a disk path\n\t\t * that refers to e.g. a tftp client */\n\t\tint result, result2;\n\n\t\tresult = fseek(fileio->file, 0, SEEK_END);\n\n\t\tfile_size = ftell(fileio->file);\n\n\t\tresult2 = fseek(fileio->file, 0, SEEK_SET);\n\n\t\tif ((file_size < 0) || (result < 0) || (result2 < 0)) {\n\t\t\tfileio_close_local(fileio);\n\t\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t\t}\n\t}\n\n\tfileio->size = file_size;\n\n\treturn ERROR_OK;\n}\n\nint fileio_open(struct fileio **fileio, const char *url,\n\t\tenum fileio_access access_type, enum fileio_type type)\n{\n\tint retval;\n\tstruct fileio *tmp;\n\n\ttmp = malloc(sizeof(struct fileio));\n\n\ttmp->type = type;\n\ttmp->access = access_type;\n\ttmp->url = strdup(url);\n\n\tretval = fileio_open_local(tmp);\n\n\tif (retval != ERROR_OK) {\n\t\tfree(tmp->url);\n\t\tfree(tmp);\n\t\treturn retval;\n\t}\n\n\t*fileio = tmp;\n\n\treturn ERROR_OK;\n}\n\nint fileio_close(struct fileio *fileio)\n{\n\tint retval;\n\n\tretval = fileio_close_local(fileio);\n\n\tfree(fileio->url);\n\tfree(fileio);\n\n\treturn retval;\n}\n\nint fileio_feof(struct fileio *fileio)\n{\n\treturn feof(fileio->file);\n}\n\nint fileio_seek(struct fileio *fileio, size_t position)\n{\n\tint retval;\n\n\tretval = fseek(fileio->file, position, SEEK_SET);\n\n\tif (retval != 0) {\n\t\tLOG_ERROR(\"couldn't seek file %s: %s\", fileio->url, strerror(errno));\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int fileio_local_read(struct fileio *fileio, size_t size, void *buffer,\n\t\tsize_t *size_read)\n{\n\tssize_t retval;\n\n\tretval = fread(buffer, 1, size, fileio->file);\n\t*size_read = (retval >= 0) ? retval : 0;\n\n\treturn (retval < 0) ? retval : ERROR_OK;\n}\n\nint fileio_read(struct fileio *fileio, size_t size, void *buffer,\n\t\tsize_t *size_read)\n{\n\treturn fileio_local_read(fileio, size, buffer, size_read);\n}\n\nint fileio_read_u32(struct fileio *fileio, uint32_t *data)\n{\n\tint retval;\n\tuint8_t buf[4];\n\tsize_t size_read;\n\n\tretval = fileio_local_read(fileio, sizeof(uint32_t), buf, &size_read);\n\n\tif (retval == ERROR_OK && sizeof(uint32_t) != size_read)\n\t\tretval = -EIO;\n\tif (retval == ERROR_OK)\n\t\t*data = be_to_h_u32(buf);\n\n\treturn retval;\n}\n\nstatic int fileio_local_fgets(struct fileio *fileio, size_t size, void *buffer)\n{\n\tif (!fgets(buffer, size, fileio->file))\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\n\treturn ERROR_OK;\n}\n\nint fileio_fgets(struct fileio *fileio, size_t size, void *buffer)\n{\n\treturn fileio_local_fgets(fileio, size, buffer);\n}\n\nstatic int fileio_local_write(struct fileio *fileio, size_t size,\n\t\tconst void *buffer, size_t *size_written)\n{\n\tssize_t retval;\n\n\tretval = fwrite(buffer, 1, size, fileio->file);\n\t*size_written = (retval >= 0) ? retval : 0;\n\n\treturn (retval < 0) ? retval : ERROR_OK;\n}\n\nint fileio_write(struct fileio *fileio, size_t size, const void *buffer,\n\t\tsize_t *size_written)\n{\n\tint retval;\n\n\tretval = fileio_local_write(fileio, size, buffer, size_written);\n\n\tif (retval == ERROR_OK)\n\t\tfileio->size += *size_written;\n\n\treturn retval;\n}\n\nint fileio_write_u32(struct fileio *fileio, uint32_t data)\n{\n\tint retval;\n\tuint8_t buf[4];\n\th_u32_to_be(buf, data);\n\tsize_t size_written;\n\n\tretval = fileio_write(fileio, 4, buf, &size_written);\n\n\tif (retval == ERROR_OK && size_written != sizeof(uint32_t))\n\t\tretval = -EIO;\n\n\treturn retval;\n}\n\n/**\n * FIX!!!!\n *\n * For now this can not fail, but that's because a seek was executed\n * on startup.\n *\n * Avoiding the seek on startup opens up for using streams.\n *\n */\nint fileio_size(struct fileio *fileio, size_t *size)\n{\n\t*size = fileio->size;\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/fileio.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_FILEIO_H\n#define OPENOCD_HELPER_FILEIO_H\n\n#include \"types.h\"\n\n#define FILEIO_MAX_ERROR_STRING\t\t(128)\n\nenum fileio_type {\n\tFILEIO_TEXT,\n\tFILEIO_BINARY,\n};\n\nenum fileio_access {\n\tFILEIO_NONE,\t\t/* open without any access (invalid mode) */\n\tFILEIO_READ,\t\t/* open for reading, position at beginning */\n\tFILEIO_WRITE,\t\t/* open for writing, position at beginning */\n\tFILEIO_READWRITE,\t/* open for writing, position at beginning, allow reading */\n\tFILEIO_APPEND,\t\t/* open for writing, position at end */\n\tFILEIO_APPENDREAD,\t/* open for writing, position at end, allow reading */\n};\n\nstruct fileio;\n\nint fileio_open(struct fileio **fileio, const char *url,\n\t\tenum fileio_access access_type, enum fileio_type type);\nint fileio_close(struct fileio *fileio);\nint fileio_feof(struct fileio *fileio);\n\nint fileio_seek(struct fileio *fileio, size_t position);\nint fileio_fgets(struct fileio *fileio, size_t size, void *buffer);\n\nint fileio_read(struct fileio *fileio,\n\t\tsize_t size, void *buffer, size_t *size_read);\nint fileio_write(struct fileio *fileio,\n\t\tsize_t size, const void *buffer, size_t *size_written);\n\nint fileio_read_u32(struct fileio *fileio, uint32_t *data);\nint fileio_write_u32(struct fileio *fileio, uint32_t data);\nint fileio_size(struct fileio *fileio, size_t *size);\n\n#define ERROR_FILEIO_LOCATION_UNKNOWN\t\t\t(-1200)\n#define ERROR_FILEIO_NOT_FOUND\t\t\t\t\t(-1201)\n#define ERROR_FILEIO_OPERATION_FAILED\t\t\t(-1202)\n#define ERROR_FILEIO_ACCESS_NOT_SUPPORTED\t\t(-1203)\n#define ERROR_FILEIO_RESOURCE_TYPE_UNKNOWN\t\t(-1204)\n#define ERROR_FILEIO_OPERATION_NOT_SUPPORTED\t(-1205)\n\n#endif /* OPENOCD_HELPER_FILEIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/jep106.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 Andreas Fritiofson                                 *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jep106.h\"\n#include \"log.h\"\n\nstatic const char * const jep106[][126] = {\n#include \"jep106.inc\"\n};\n\nconst char *jep106_table_manufacturer(unsigned int bank, unsigned int id)\n{\n\tif (id < 1 || id > 126) {\n\t\tLOG_DEBUG(\"BUG: Caller passed out-of-range JEP106 ID!\");\n\t\treturn \"<invalid>\";\n\t}\n\n\t/* index is zero based */\n\tid--;\n\n\tif (bank >= ARRAY_SIZE(jep106) || !jep106[bank][id])\n\t\treturn \"<unknown>\";\n\n\treturn jep106[bank][id];\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/jep106.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 Andreas Fritiofson                                 *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_JEP106_H\n#define OPENOCD_HELPER_JEP106_H\n\n/**\n * Get the manufacturer name associated with a JEP106 ID.\n * @param bank The bank (number of continuation codes) of the manufacturer ID.\n * @param id The 7-bit manufacturer ID (i.e. with parity stripped).\n * @return A pointer to static const storage containing the name of the\n *         manufacturer associated with bank and id, or one of the strings\n *         \"<invalid>\" and \"<unknown>\".\n */\nconst char *jep106_table_manufacturer(unsigned int bank, unsigned int id);\n\nstatic inline const char *jep106_manufacturer(unsigned int manufacturer)\n{\n\treturn jep106_table_manufacturer(manufacturer >> 7, manufacturer & 0x7f);\n}\n\n#endif /* OPENOCD_HELPER_JEP106_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/jep106.inc",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * The manufacturer's standard identification code list appears in JEP106.\n * Copyright (c) 2022 JEDEC. All rights reserved.\n *\n * JEP106 is regularly updated. For the current manufacturer's standard\n * identification code list, please visit the JEDEC website at www.jedec.org .\n */\n\n/* This file is aligned to revision JEP106BG May 2023. */\n\n/* \"NXP (Philips)\" is reported below, while missing in JEP106BG */\n\n[0][0x01 - 1] = \"AMD\",\n[0][0x02 - 1] = \"AMI\",\n[0][0x03 - 1] = \"Fairchild\",\n[0][0x04 - 1] = \"Fujitsu\",\n[0][0x05 - 1] = \"GTE\",\n[0][0x06 - 1] = \"Harris\",\n[0][0x07 - 1] = \"Hitachi\",\n[0][0x08 - 1] = \"Inmos\",\n[0][0x09 - 1] = \"Intel\",\n[0][0x0a - 1] = \"I.T.T.\",\n[0][0x0b - 1] = \"Intersil\",\n[0][0x0c - 1] = \"Monolithic Memories\",\n[0][0x0d - 1] = \"Mostek\",\n[0][0x0e - 1] = \"Freescale (Motorola)\",\n[0][0x0f - 1] = \"National\",\n[0][0x10 - 1] = \"NEC\",\n[0][0x11 - 1] = \"RCA\",\n[0][0x12 - 1] = \"Raytheon\",\n[0][0x13 - 1] = \"Conexant (Rockwell)\",\n[0][0x14 - 1] = \"Seeq\",\n[0][0x15 - 1] = \"NXP (Philips)\",\n[0][0x16 - 1] = \"Synertek\",\n[0][0x17 - 1] = \"Texas Instruments\",\n[0][0x18 - 1] = \"Kioxia Corporation\",\n[0][0x19 - 1] = \"Xicor\",\n[0][0x1a - 1] = \"Zilog\",\n[0][0x1b - 1] = \"Eurotechnique\",\n[0][0x1c - 1] = \"Mitsubishi\",\n[0][0x1d - 1] = \"Lucent (AT&T)\",\n[0][0x1e - 1] = \"Exel\",\n[0][0x1f - 1] = \"Atmel\",\n[0][0x20 - 1] = \"STMicroelectronics\",\n[0][0x21 - 1] = \"Lattice Semi.\",\n[0][0x22 - 1] = \"NCR\",\n[0][0x23 - 1] = \"Wafer Scale Integration\",\n[0][0x24 - 1] = \"IBM\",\n[0][0x25 - 1] = \"Tristar\",\n[0][0x26 - 1] = \"Visic\",\n[0][0x27 - 1] = \"Intl. CMOS Technology\",\n[0][0x28 - 1] = \"SSSI\",\n[0][0x29 - 1] = \"Microchip Technology\",\n[0][0x2a - 1] = \"Ricoh Ltd\",\n[0][0x2b - 1] = \"VLSI\",\n[0][0x2c - 1] = \"Micron Technology\",\n[0][0x2d - 1] = \"SK Hynix\",\n[0][0x2e - 1] = \"OKI Semiconductor\",\n[0][0x2f - 1] = \"ACTEL\",\n[0][0x30 - 1] = \"Sharp\",\n[0][0x31 - 1] = \"Catalyst\",\n[0][0x32 - 1] = \"Panasonic\",\n[0][0x33 - 1] = \"IDT\",\n[0][0x34 - 1] = \"Cypress\",\n[0][0x35 - 1] = \"DEC\",\n[0][0x36 - 1] = \"LSI Logic\",\n[0][0x37 - 1] = \"Zarlink (Plessey)\",\n[0][0x38 - 1] = \"UTMC\",\n[0][0x39 - 1] = \"Thinking Machine\",\n[0][0x3a - 1] = \"Thomson CSF\",\n[0][0x3b - 1] = \"Integrated CMOS (Vertex)\",\n[0][0x3c - 1] = \"Honeywell\",\n[0][0x3d - 1] = \"Tektronix\",\n[0][0x3e - 1] = \"Oracle Corporation\",\n[0][0x3f - 1] = \"Silicon Storage Technology\",\n[0][0x40 - 1] = \"ProMos/Mosel Vitelic\",\n[0][0x41 - 1] = \"Infineon (Siemens)\",\n[0][0x42 - 1] = \"Macronix\",\n[0][0x43 - 1] = \"Xerox\",\n[0][0x44 - 1] = \"Plus Logic\",\n[0][0x45 - 1] = \"Western Digital Technologies Inc\",\n[0][0x46 - 1] = \"Elan Circuit Tech.\",\n[0][0x47 - 1] = \"European Silicon Str.\",\n[0][0x48 - 1] = \"Apple Computer\",\n[0][0x49 - 1] = \"Xilinx\",\n[0][0x4a - 1] = \"Compaq\",\n[0][0x4b - 1] = \"Protocol Engines\",\n[0][0x4c - 1] = \"SCI\",\n[0][0x4d - 1] = \"ABLIC\",\n[0][0x4e - 1] = \"Samsung\",\n[0][0x4f - 1] = \"I3 Design System\",\n[0][0x50 - 1] = \"Klic\",\n[0][0x51 - 1] = \"Crosspoint Solutions\",\n[0][0x52 - 1] = \"Alliance Memory Inc\",\n[0][0x53 - 1] = \"Tandem\",\n[0][0x54 - 1] = \"Hewlett-Packard\",\n[0][0x55 - 1] = \"Integrated Silicon Solutions\",\n[0][0x56 - 1] = \"Brooktree\",\n[0][0x57 - 1] = \"New Media\",\n[0][0x58 - 1] = \"MHS Electronic\",\n[0][0x59 - 1] = \"Performance Semi.\",\n[0][0x5a - 1] = \"Winbond Electronic\",\n[0][0x5b - 1] = \"Kawasaki Steel\",\n[0][0x5c - 1] = \"Bright Micro\",\n[0][0x5d - 1] = \"TECMAR\",\n[0][0x5e - 1] = \"Exar\",\n[0][0x5f - 1] = \"PCMCIA\",\n[0][0x60 - 1] = \"LG Semi (Goldstar)\",\n[0][0x61 - 1] = \"Northern Telecom\",\n[0][0x62 - 1] = \"Sanyo\",\n[0][0x63 - 1] = \"Array Microsystems\",\n[0][0x64 - 1] = \"Crystal Semiconductor\",\n[0][0x65 - 1] = \"Analog Devices\",\n[0][0x66 - 1] = \"PMC-Sierra\",\n[0][0x67 - 1] = \"Asparix\",\n[0][0x68 - 1] = \"Convex Computer\",\n[0][0x69 - 1] = \"Quality Semiconductor\",\n[0][0x6a - 1] = \"Nimbus Technology\",\n[0][0x6b - 1] = \"Transwitch\",\n[0][0x6c - 1] = \"Micronas (ITT Intermetall)\",\n[0][0x6d - 1] = \"Cannon\",\n[0][0x6e - 1] = \"Altera\",\n[0][0x6f - 1] = \"NEXCOM\",\n[0][0x70 - 1] = \"Qualcomm\",\n[0][0x71 - 1] = \"Sony\",\n[0][0x72 - 1] = \"Cray Research\",\n[0][0x73 - 1] = \"AMS(Austria Micro)\",\n[0][0x74 - 1] = \"Vitesse\",\n[0][0x75 - 1] = \"Aster Electronics\",\n[0][0x76 - 1] = \"Bay Networks (Synoptic)\",\n[0][0x77 - 1] = \"Zentrum/ZMD\",\n[0][0x78 - 1] = \"TRW\",\n[0][0x79 - 1] = \"Thesys\",\n[0][0x7a - 1] = \"Solbourne Computer\",\n[0][0x7b - 1] = \"Allied-Signal\",\n[0][0x7c - 1] = \"Dialog Semiconductor\",\n[0][0x7d - 1] = \"Media Vision\",\n[0][0x7e - 1] = \"Numonyx Corporation\",\n[1][0x01 - 1] = \"Cirrus Logic\",\n[1][0x02 - 1] = \"National Instruments\",\n[1][0x03 - 1] = \"ILC Data Device\",\n[1][0x04 - 1] = \"Alcatel Mietec\",\n[1][0x05 - 1] = \"Micro Linear\",\n[1][0x06 - 1] = \"Univ. of NC\",\n[1][0x07 - 1] = \"JTAG Technologies\",\n[1][0x08 - 1] = \"BAE Systems (Loral)\",\n[1][0x09 - 1] = \"Nchip\",\n[1][0x0a - 1] = \"Galileo Tech\",\n[1][0x0b - 1] = \"Bestlink Systems\",\n[1][0x0c - 1] = \"Graychip\",\n[1][0x0d - 1] = \"GENNUM\",\n[1][0x0e - 1] = \"Imagination Technologies Limited\",\n[1][0x0f - 1] = \"Robert Bosch\",\n[1][0x10 - 1] = \"Chip Express\",\n[1][0x11 - 1] = \"DATARAM\",\n[1][0x12 - 1] = \"United Microelectronics Corp\",\n[1][0x13 - 1] = \"TCSI\",\n[1][0x14 - 1] = \"Smart Modular\",\n[1][0x15 - 1] = \"Hughes Aircraft\",\n[1][0x16 - 1] = \"Lanstar Semiconductor\",\n[1][0x17 - 1] = \"Qlogic\",\n[1][0x18 - 1] = \"Kingston\",\n[1][0x19 - 1] = \"Music Semi\",\n[1][0x1a - 1] = \"Ericsson Components\",\n[1][0x1b - 1] = \"SpaSE\",\n[1][0x1c - 1] = \"Eon Silicon Devices\",\n[1][0x1d - 1] = \"Integrated Silicon Solution (ISSI)\",\n[1][0x1e - 1] = \"DoD\",\n[1][0x1f - 1] = \"Integ. Memories Tech.\",\n[1][0x20 - 1] = \"Corollary Inc\",\n[1][0x21 - 1] = \"Dallas Semiconductor\",\n[1][0x22 - 1] = \"Omnivision\",\n[1][0x23 - 1] = \"EIV(Switzerland)\",\n[1][0x24 - 1] = \"Novatel Wireless\",\n[1][0x25 - 1] = \"Zarlink (Mitel)\",\n[1][0x26 - 1] = \"Clearpoint\",\n[1][0x27 - 1] = \"Cabletron\",\n[1][0x28 - 1] = \"STEC (Silicon Tech)\",\n[1][0x29 - 1] = \"Vanguard\",\n[1][0x2a - 1] = \"Hagiwara Sys-Com\",\n[1][0x2b - 1] = \"Vantis\",\n[1][0x2c - 1] = \"Celestica\",\n[1][0x2d - 1] = \"Century\",\n[1][0x2e - 1] = \"Hal Computers\",\n[1][0x2f - 1] = \"Rohm Company Ltd\",\n[1][0x30 - 1] = \"Juniper Networks\",\n[1][0x31 - 1] = \"Libit Signal Processing\",\n[1][0x32 - 1] = \"Mushkin Enhanced Memory\",\n[1][0x33 - 1] = \"Tundra Semiconductor\",\n[1][0x34 - 1] = \"Adaptec Inc\",\n[1][0x35 - 1] = \"LightSpeed Semi.\",\n[1][0x36 - 1] = \"ZSP Corp\",\n[1][0x37 - 1] = \"AMIC Technology\",\n[1][0x38 - 1] = \"Adobe Systems\",\n[1][0x39 - 1] = \"Dynachip\",\n[1][0x3a - 1] = \"PNY Technologies Inc\",\n[1][0x3b - 1] = \"Newport Digital\",\n[1][0x3c - 1] = \"MMC Networks\",\n[1][0x3d - 1] = \"T Square\",\n[1][0x3e - 1] = \"Seiko Epson\",\n[1][0x3f - 1] = \"Broadcom\",\n[1][0x40 - 1] = \"Viking Components\",\n[1][0x41 - 1] = \"V3 Semiconductor\",\n[1][0x42 - 1] = \"Flextronics (Orbit Semiconductor)\",\n[1][0x43 - 1] = \"Suwa Electronics\",\n[1][0x44 - 1] = \"Transmeta\",\n[1][0x45 - 1] = \"Micron CMS\",\n[1][0x46 - 1] = \"American Computer & Digital Components Inc\",\n[1][0x47 - 1] = \"Enhance 3000 Inc\",\n[1][0x48 - 1] = \"Tower Semiconductor\",\n[1][0x49 - 1] = \"CPU Design\",\n[1][0x4a - 1] = \"Price Point\",\n[1][0x4b - 1] = \"Maxim Integrated Product\",\n[1][0x4c - 1] = \"Tellabs\",\n[1][0x4d - 1] = \"Centaur Technology\",\n[1][0x4e - 1] = \"Unigen Corporation\",\n[1][0x4f - 1] = \"Transcend Information\",\n[1][0x50 - 1] = \"Memory Card Technology\",\n[1][0x51 - 1] = \"CKD Corporation Ltd\",\n[1][0x52 - 1] = \"Capital Instruments Inc\",\n[1][0x53 - 1] = \"Aica Kogyo Ltd\",\n[1][0x54 - 1] = \"Linvex Technology\",\n[1][0x55 - 1] = \"MSC Vertriebs GmbH\",\n[1][0x56 - 1] = \"AKM Company Ltd\",\n[1][0x57 - 1] = \"Dynamem Inc\",\n[1][0x58 - 1] = \"NERA ASA\",\n[1][0x59 - 1] = \"GSI Technology\",\n[1][0x5a - 1] = \"Dane-Elec (C Memory)\",\n[1][0x5b - 1] = \"Acorn Computers\",\n[1][0x5c - 1] = \"Lara Technology\",\n[1][0x5d - 1] = \"Oak Technology Inc\",\n[1][0x5e - 1] = \"Itec Memory\",\n[1][0x5f - 1] = \"Tanisys Technology\",\n[1][0x60 - 1] = \"Truevision\",\n[1][0x61 - 1] = \"Wintec Industries\",\n[1][0x62 - 1] = \"Super PC Memory\",\n[1][0x63 - 1] = \"MGV Memory\",\n[1][0x64 - 1] = \"Galvantech\",\n[1][0x65 - 1] = \"Gadzoox Networks\",\n[1][0x66 - 1] = \"Multi Dimensional Cons.\",\n[1][0x67 - 1] = \"GateField\",\n[1][0x68 - 1] = \"Integrated Memory System\",\n[1][0x69 - 1] = \"Triscend\",\n[1][0x6a - 1] = \"XaQti\",\n[1][0x6b - 1] = \"Goldenram\",\n[1][0x6c - 1] = \"Clear Logic\",\n[1][0x6d - 1] = \"Cimaron Communications\",\n[1][0x6e - 1] = \"Nippon Steel Semi. Corp\",\n[1][0x6f - 1] = \"Advantage Memory\",\n[1][0x70 - 1] = \"AMCC\",\n[1][0x71 - 1] = \"LeCroy\",\n[1][0x72 - 1] = \"Yamaha Corporation\",\n[1][0x73 - 1] = \"Digital Microwave\",\n[1][0x74 - 1] = \"NetLogic Microsystems\",\n[1][0x75 - 1] = \"MIMOS Semiconductor\",\n[1][0x76 - 1] = \"Advanced Fibre\",\n[1][0x77 - 1] = \"BF Goodrich Data.\",\n[1][0x78 - 1] = \"Epigram\",\n[1][0x79 - 1] = \"Acbel Polytech Inc\",\n[1][0x7a - 1] = \"Apacer Technology\",\n[1][0x7b - 1] = \"Admor Memory\",\n[1][0x7c - 1] = \"FOXCONN\",\n[1][0x7d - 1] = \"Quadratics Superconductor\",\n[1][0x7e - 1] = \"3COM\",\n[2][0x01 - 1] = \"Camintonn Corporation\",\n[2][0x02 - 1] = \"ISOA Incorporated\",\n[2][0x03 - 1] = \"Agate Semiconductor\",\n[2][0x04 - 1] = \"ADMtek Incorporated\",\n[2][0x05 - 1] = \"HYPERTEC\",\n[2][0x06 - 1] = \"Adhoc Technologies\",\n[2][0x07 - 1] = \"MOSAID Technologies\",\n[2][0x08 - 1] = \"Ardent Technologies\",\n[2][0x09 - 1] = \"Switchcore\",\n[2][0x0a - 1] = \"Cisco Systems Inc\",\n[2][0x0b - 1] = \"Allayer Technologies\",\n[2][0x0c - 1] = \"WorkX AG (Wichman)\",\n[2][0x0d - 1] = \"Oasis Semiconductor\",\n[2][0x0e - 1] = \"Novanet Semiconductor\",\n[2][0x0f - 1] = \"E-M Solutions\",\n[2][0x10 - 1] = \"Power General\",\n[2][0x11 - 1] = \"Advanced Hardware Arch.\",\n[2][0x12 - 1] = \"Inova Semiconductors GmbH\",\n[2][0x13 - 1] = \"Telocity\",\n[2][0x14 - 1] = \"Delkin Devices\",\n[2][0x15 - 1] = \"Symagery Microsystems\",\n[2][0x16 - 1] = \"C-Port Corporation\",\n[2][0x17 - 1] = \"SiberCore Technologies\",\n[2][0x18 - 1] = \"Southland Microsystems\",\n[2][0x19 - 1] = \"Malleable Technologies\",\n[2][0x1a - 1] = \"Kendin Communications\",\n[2][0x1b - 1] = \"Great Technology Microcomputer\",\n[2][0x1c - 1] = \"Sanmina Corporation\",\n[2][0x1d - 1] = \"HADCO Corporation\",\n[2][0x1e - 1] = \"Corsair\",\n[2][0x1f - 1] = \"Actrans System Inc\",\n[2][0x20 - 1] = \"ALPHA Technologies\",\n[2][0x21 - 1] = \"Silicon Laboratories Inc (Cygnal)\",\n[2][0x22 - 1] = \"Artesyn Technologies\",\n[2][0x23 - 1] = \"Align Manufacturing\",\n[2][0x24 - 1] = \"Peregrine Semiconductor\",\n[2][0x25 - 1] = \"Chameleon Systems\",\n[2][0x26 - 1] = \"Aplus Flash Technology\",\n[2][0x27 - 1] = \"MIPS Technologies\",\n[2][0x28 - 1] = \"Chrysalis ITS\",\n[2][0x29 - 1] = \"ADTEC Corporation\",\n[2][0x2a - 1] = \"Kentron Technologies\",\n[2][0x2b - 1] = \"Win Technologies\",\n[2][0x2c - 1] = \"Tezzaron Semiconductor\",\n[2][0x2d - 1] = \"Extreme Packet Devices\",\n[2][0x2e - 1] = \"RF Micro Devices\",\n[2][0x2f - 1] = \"Siemens AG\",\n[2][0x30 - 1] = \"Sarnoff Corporation\",\n[2][0x31 - 1] = \"Itautec SA\",\n[2][0x32 - 1] = \"Radiata Inc\",\n[2][0x33 - 1] = \"Benchmark Elect. (AVEX)\",\n[2][0x34 - 1] = \"Legend\",\n[2][0x35 - 1] = \"SpecTek Incorporated\",\n[2][0x36 - 1] = \"Hi/fn\",\n[2][0x37 - 1] = \"Enikia Incorporated\",\n[2][0x38 - 1] = \"SwitchOn Networks\",\n[2][0x39 - 1] = \"AANetcom Incorporated\",\n[2][0x3a - 1] = \"Micro Memory Bank\",\n[2][0x3b - 1] = \"ESS Technology\",\n[2][0x3c - 1] = \"Virata Corporation\",\n[2][0x3d - 1] = \"Excess Bandwidth\",\n[2][0x3e - 1] = \"West Bay Semiconductor\",\n[2][0x3f - 1] = \"DSP Group\",\n[2][0x40 - 1] = \"Newport Communications\",\n[2][0x41 - 1] = \"Chip2Chip Incorporated\",\n[2][0x42 - 1] = \"Phobos Corporation\",\n[2][0x43 - 1] = \"Intellitech Corporation\",\n[2][0x44 - 1] = \"Nordic VLSI ASA\",\n[2][0x45 - 1] = \"Ishoni Networks\",\n[2][0x46 - 1] = \"Silicon Spice\",\n[2][0x47 - 1] = \"Alchemy Semiconductor\",\n[2][0x48 - 1] = \"Agilent Technologies\",\n[2][0x49 - 1] = \"Centillium Communications\",\n[2][0x4a - 1] = \"W.L. Gore\",\n[2][0x4b - 1] = \"HanBit Electronics\",\n[2][0x4c - 1] = \"GlobeSpan\",\n[2][0x4d - 1] = \"Element 14\",\n[2][0x4e - 1] = \"Pycon\",\n[2][0x4f - 1] = \"Saifun Semiconductors\",\n[2][0x50 - 1] = \"Sibyte Incorporated\",\n[2][0x51 - 1] = \"MetaLink Technologies\",\n[2][0x52 - 1] = \"Feiya Technology\",\n[2][0x53 - 1] = \"I & C Technology\",\n[2][0x54 - 1] = \"Shikatronics\",\n[2][0x55 - 1] = \"Elektrobit\",\n[2][0x56 - 1] = \"Megic\",\n[2][0x57 - 1] = \"Com-Tier\",\n[2][0x58 - 1] = \"Malaysia Micro Solutions\",\n[2][0x59 - 1] = \"Hyperchip\",\n[2][0x5a - 1] = \"Gemstone Communications\",\n[2][0x5b - 1] = \"Anadigm (Anadyne)\",\n[2][0x5c - 1] = \"3ParData\",\n[2][0x5d - 1] = \"Mellanox Technologies\",\n[2][0x5e - 1] = \"Tenx Technologies\",\n[2][0x5f - 1] = \"Helix AG\",\n[2][0x60 - 1] = \"Domosys\",\n[2][0x61 - 1] = \"Skyup Technology\",\n[2][0x62 - 1] = \"HiNT Corporation\",\n[2][0x63 - 1] = \"Chiaro\",\n[2][0x64 - 1] = \"MDT Technologies GmbH\",\n[2][0x65 - 1] = \"Exbit Technology A/S\",\n[2][0x66 - 1] = \"Integrated Technology Express\",\n[2][0x67 - 1] = \"AVED Memory\",\n[2][0x68 - 1] = \"Legerity\",\n[2][0x69 - 1] = \"Jasmine Networks\",\n[2][0x6a - 1] = \"Caspian Networks\",\n[2][0x6b - 1] = \"nCUBE\",\n[2][0x6c - 1] = \"Silicon Access Networks\",\n[2][0x6d - 1] = \"FDK Corporation\",\n[2][0x6e - 1] = \"High Bandwidth Access\",\n[2][0x6f - 1] = \"MultiLink Technology\",\n[2][0x70 - 1] = \"BRECIS\",\n[2][0x71 - 1] = \"World Wide Packets\",\n[2][0x72 - 1] = \"APW\",\n[2][0x73 - 1] = \"Chicory Systems\",\n[2][0x74 - 1] = \"Xstream Logic\",\n[2][0x75 - 1] = \"Fast-Chip\",\n[2][0x76 - 1] = \"Zucotto Wireless\",\n[2][0x77 - 1] = \"Realchip\",\n[2][0x78 - 1] = \"Galaxy Power\",\n[2][0x79 - 1] = \"eSilicon\",\n[2][0x7a - 1] = \"Morphics Technology\",\n[2][0x7b - 1] = \"Accelerant Networks\",\n[2][0x7c - 1] = \"Silicon Wave\",\n[2][0x7d - 1] = \"SandCraft\",\n[2][0x7e - 1] = \"Elpida\",\n[3][0x01 - 1] = \"Solectron\",\n[3][0x02 - 1] = \"Optosys Technologies\",\n[3][0x03 - 1] = \"Buffalo (Formerly Melco)\",\n[3][0x04 - 1] = \"TriMedia Technologies\",\n[3][0x05 - 1] = \"Cyan Technologies\",\n[3][0x06 - 1] = \"Global Locate\",\n[3][0x07 - 1] = \"Optillion\",\n[3][0x08 - 1] = \"Terago Communications\",\n[3][0x09 - 1] = \"Ikanos Communications\",\n[3][0x0a - 1] = \"Princeton Technology\",\n[3][0x0b - 1] = \"Nanya Technology\",\n[3][0x0c - 1] = \"Elite Flash Storage\",\n[3][0x0d - 1] = \"Mysticom\",\n[3][0x0e - 1] = \"LightSand Communications\",\n[3][0x0f - 1] = \"ATI Technologies\",\n[3][0x10 - 1] = \"Agere Systems\",\n[3][0x11 - 1] = \"NeoMagic\",\n[3][0x12 - 1] = \"AuroraNetics\",\n[3][0x13 - 1] = \"Golden Empire\",\n[3][0x14 - 1] = \"Mushkin\",\n[3][0x15 - 1] = \"Tioga Technologies\",\n[3][0x16 - 1] = \"Netlist\",\n[3][0x17 - 1] = \"TeraLogic\",\n[3][0x18 - 1] = \"Cicada Semiconductor\",\n[3][0x19 - 1] = \"Centon Electronics\",\n[3][0x1a - 1] = \"Tyco Electronics\",\n[3][0x1b - 1] = \"Magis Works\",\n[3][0x1c - 1] = \"Zettacom\",\n[3][0x1d - 1] = \"Cogency Semiconductor\",\n[3][0x1e - 1] = \"Chipcon AS\",\n[3][0x1f - 1] = \"Aspex Technology\",\n[3][0x20 - 1] = \"F5 Networks\",\n[3][0x21 - 1] = \"Programmable Silicon Solutions\",\n[3][0x22 - 1] = \"ChipWrights\",\n[3][0x23 - 1] = \"Acorn Networks\",\n[3][0x24 - 1] = \"Quicklogic\",\n[3][0x25 - 1] = \"Kingmax Semiconductor\",\n[3][0x26 - 1] = \"BOPS\",\n[3][0x27 - 1] = \"Flasys\",\n[3][0x28 - 1] = \"BitBlitz Communications\",\n[3][0x29 - 1] = \"eMemory Technology\",\n[3][0x2a - 1] = \"Procket Networks\",\n[3][0x2b - 1] = \"Purple Ray\",\n[3][0x2c - 1] = \"Trebia Networks\",\n[3][0x2d - 1] = \"Delta Electronics\",\n[3][0x2e - 1] = \"Onex Communications\",\n[3][0x2f - 1] = \"Ample Communications\",\n[3][0x30 - 1] = \"Memory Experts Intl\",\n[3][0x31 - 1] = \"Astute Networks\",\n[3][0x32 - 1] = \"Azanda Network Devices\",\n[3][0x33 - 1] = \"Dibcom\",\n[3][0x34 - 1] = \"Tekmos\",\n[3][0x35 - 1] = \"API NetWorks\",\n[3][0x36 - 1] = \"Bay Microsystems\",\n[3][0x37 - 1] = \"Firecron Ltd\",\n[3][0x38 - 1] = \"Resonext Communications\",\n[3][0x39 - 1] = \"Tachys Technologies\",\n[3][0x3a - 1] = \"Equator Technology\",\n[3][0x3b - 1] = \"Concept Computer\",\n[3][0x3c - 1] = \"SILCOM\",\n[3][0x3d - 1] = \"3Dlabs\",\n[3][0x3e - 1] = \"c't Magazine\",\n[3][0x3f - 1] = \"Sanera Systems\",\n[3][0x40 - 1] = \"Silicon Packets\",\n[3][0x41 - 1] = \"Viasystems Group\",\n[3][0x42 - 1] = \"Simtek\",\n[3][0x43 - 1] = \"Semicon Devices Singapore\",\n[3][0x44 - 1] = \"Satron Handelsges\",\n[3][0x45 - 1] = \"Improv Systems\",\n[3][0x46 - 1] = \"INDUSYS GmbH\",\n[3][0x47 - 1] = \"Corrent\",\n[3][0x48 - 1] = \"Infrant Technologies\",\n[3][0x49 - 1] = \"Ritek Corp\",\n[3][0x4a - 1] = \"empowerTel Networks\",\n[3][0x4b - 1] = \"Hypertec\",\n[3][0x4c - 1] = \"Cavium Networks\",\n[3][0x4d - 1] = \"PLX Technology\",\n[3][0x4e - 1] = \"Massana Design\",\n[3][0x4f - 1] = \"Intrinsity\",\n[3][0x50 - 1] = \"Valence Semiconductor\",\n[3][0x51 - 1] = \"Terawave Communications\",\n[3][0x52 - 1] = \"IceFyre Semiconductor\",\n[3][0x53 - 1] = \"Primarion\",\n[3][0x54 - 1] = \"Picochip Designs Ltd\",\n[3][0x55 - 1] = \"Silverback Systems\",\n[3][0x56 - 1] = \"Jade Star Technologies\",\n[3][0x57 - 1] = \"Pijnenburg Securealink\",\n[3][0x58 - 1] = \"takeMS - Ultron AG\",\n[3][0x59 - 1] = \"Cambridge Silicon Radio\",\n[3][0x5a - 1] = \"Swissbit\",\n[3][0x5b - 1] = \"Nazomi Communications\",\n[3][0x5c - 1] = \"eWave System\",\n[3][0x5d - 1] = \"Rockwell Collins\",\n[3][0x5e - 1] = \"Picocel Co Ltd (Paion)\",\n[3][0x5f - 1] = \"Alphamosaic Ltd\",\n[3][0x60 - 1] = \"Sandburst\",\n[3][0x61 - 1] = \"SiCon Video\",\n[3][0x62 - 1] = \"NanoAmp Solutions\",\n[3][0x63 - 1] = \"Ericsson Technology\",\n[3][0x64 - 1] = \"PrairieComm\",\n[3][0x65 - 1] = \"Mitac International\",\n[3][0x66 - 1] = \"Layer N Networks\",\n[3][0x67 - 1] = \"MtekVision (Atsana)\",\n[3][0x68 - 1] = \"Allegro Networks\",\n[3][0x69 - 1] = \"Marvell Semiconductors\",\n[3][0x6a - 1] = \"Netergy Microelectronic\",\n[3][0x6b - 1] = \"NVIDIA\",\n[3][0x6c - 1] = \"Internet Machines\",\n[3][0x6d - 1] = \"Memorysolution GmbH\",\n[3][0x6e - 1] = \"Litchfield Communication\",\n[3][0x6f - 1] = \"Accton Technology\",\n[3][0x70 - 1] = \"Teradiant Networks\",\n[3][0x71 - 1] = \"Scaleo Chip\",\n[3][0x72 - 1] = \"Cortina Systems\",\n[3][0x73 - 1] = \"RAM Components\",\n[3][0x74 - 1] = \"Raqia Networks\",\n[3][0x75 - 1] = \"ClearSpeed\",\n[3][0x76 - 1] = \"Matsushita Battery\",\n[3][0x77 - 1] = \"Xelerated\",\n[3][0x78 - 1] = \"SimpleTech\",\n[3][0x79 - 1] = \"Utron Technology\",\n[3][0x7a - 1] = \"Astec International\",\n[3][0x7b - 1] = \"AVM gmbH\",\n[3][0x7c - 1] = \"Redux Communications\",\n[3][0x7d - 1] = \"Dot Hill Systems\",\n[3][0x7e - 1] = \"TeraChip\",\n[4][0x01 - 1] = \"T-RAM Incorporated\",\n[4][0x02 - 1] = \"Innovics Wireless\",\n[4][0x03 - 1] = \"Teknovus\",\n[4][0x04 - 1] = \"KeyEye Communications\",\n[4][0x05 - 1] = \"Runcom Technologies\",\n[4][0x06 - 1] = \"RedSwitch\",\n[4][0x07 - 1] = \"Dotcast\",\n[4][0x08 - 1] = \"Silicon Mountain Memory\",\n[4][0x09 - 1] = \"Signia Technologies\",\n[4][0x0a - 1] = \"Pixim\",\n[4][0x0b - 1] = \"Galazar Networks\",\n[4][0x0c - 1] = \"White Electronic Designs\",\n[4][0x0d - 1] = \"Patriot Scientific\",\n[4][0x0e - 1] = \"Neoaxiom Corporation\",\n[4][0x0f - 1] = \"3Y Power Technology\",\n[4][0x10 - 1] = \"Scaleo Chip\",\n[4][0x11 - 1] = \"Potentia Power Systems\",\n[4][0x12 - 1] = \"C-guys Incorporated\",\n[4][0x13 - 1] = \"Digital Communications Technology Inc\",\n[4][0x14 - 1] = \"Silicon-Based Technology\",\n[4][0x15 - 1] = \"Fulcrum Microsystems\",\n[4][0x16 - 1] = \"Positivo Informatica Ltd\",\n[4][0x17 - 1] = \"XIOtech Corporation\",\n[4][0x18 - 1] = \"PortalPlayer\",\n[4][0x19 - 1] = \"Zhiying Software\",\n[4][0x1a - 1] = \"ParkerVision Inc\",\n[4][0x1b - 1] = \"Phonex Broadband\",\n[4][0x1c - 1] = \"Skyworks Solutions\",\n[4][0x1d - 1] = \"Entropic Communications\",\n[4][0x1e - 1] = \"I'M Intelligent Memory Ltd\",\n[4][0x1f - 1] = \"Zensys A/S\",\n[4][0x20 - 1] = \"Legend Silicon Corp\",\n[4][0x21 - 1] = \"Sci-worx GmbH\",\n[4][0x22 - 1] = \"SMSC (Standard Microsystems)\",\n[4][0x23 - 1] = \"Renesas Electronics\",\n[4][0x24 - 1] = \"Raza Microelectronics\",\n[4][0x25 - 1] = \"Phyworks\",\n[4][0x26 - 1] = \"MediaTek\",\n[4][0x27 - 1] = \"Non-cents Productions\",\n[4][0x28 - 1] = \"US Modular\",\n[4][0x29 - 1] = \"Wintegra Ltd\",\n[4][0x2a - 1] = \"Mathstar\",\n[4][0x2b - 1] = \"StarCore\",\n[4][0x2c - 1] = \"Oplus Technologies\",\n[4][0x2d - 1] = \"Mindspeed\",\n[4][0x2e - 1] = \"Just Young Computer\",\n[4][0x2f - 1] = \"Radia Communications\",\n[4][0x30 - 1] = \"OCZ\",\n[4][0x31 - 1] = \"Emuzed\",\n[4][0x32 - 1] = \"LOGIC Devices\",\n[4][0x33 - 1] = \"Inphi Corporation\",\n[4][0x34 - 1] = \"Quake Technologies\",\n[4][0x35 - 1] = \"Vixel\",\n[4][0x36 - 1] = \"SolusTek\",\n[4][0x37 - 1] = \"Kongsberg Maritime\",\n[4][0x38 - 1] = \"Faraday Technology\",\n[4][0x39 - 1] = \"Altium Ltd\",\n[4][0x3a - 1] = \"Insyte\",\n[4][0x3b - 1] = \"ARM Ltd\",\n[4][0x3c - 1] = \"DigiVision\",\n[4][0x3d - 1] = \"Vativ Technologies\",\n[4][0x3e - 1] = \"Endicott Interconnect Technologies\",\n[4][0x3f - 1] = \"Pericom\",\n[4][0x40 - 1] = \"Bandspeed\",\n[4][0x41 - 1] = \"LeWiz Communications\",\n[4][0x42 - 1] = \"CPU Technology\",\n[4][0x43 - 1] = \"Ramaxel Technology\",\n[4][0x44 - 1] = \"DSP Group\",\n[4][0x45 - 1] = \"Axis Communications\",\n[4][0x46 - 1] = \"Legacy Electronics\",\n[4][0x47 - 1] = \"Chrontel\",\n[4][0x48 - 1] = \"Powerchip Semiconductor\",\n[4][0x49 - 1] = \"MobilEye Technologies\",\n[4][0x4a - 1] = \"Excel Semiconductor\",\n[4][0x4b - 1] = \"A-DATA Technology\",\n[4][0x4c - 1] = \"VirtualDigm\",\n[4][0x4d - 1] = \"G Skill Intl\",\n[4][0x4e - 1] = \"Quanta Computer\",\n[4][0x4f - 1] = \"Yield Microelectronics\",\n[4][0x50 - 1] = \"Afa Technologies\",\n[4][0x51 - 1] = \"KINGBOX Technology Co Ltd\",\n[4][0x52 - 1] = \"Ceva\",\n[4][0x53 - 1] = \"iStor Networks\",\n[4][0x54 - 1] = \"Advance Modules\",\n[4][0x55 - 1] = \"Microsoft\",\n[4][0x56 - 1] = \"Open-Silicon\",\n[4][0x57 - 1] = \"Goal Semiconductor\",\n[4][0x58 - 1] = \"ARC International\",\n[4][0x59 - 1] = \"Simmtec\",\n[4][0x5a - 1] = \"Metanoia\",\n[4][0x5b - 1] = \"Key Stream\",\n[4][0x5c - 1] = \"Lowrance Electronics\",\n[4][0x5d - 1] = \"Adimos\",\n[4][0x5e - 1] = \"SiGe Semiconductor\",\n[4][0x5f - 1] = \"Fodus Communications\",\n[4][0x60 - 1] = \"Credence Systems Corp\",\n[4][0x61 - 1] = \"Genesis Microchip Inc\",\n[4][0x62 - 1] = \"Vihana Inc\",\n[4][0x63 - 1] = \"WIS Technologies\",\n[4][0x64 - 1] = \"GateChange Technologies\",\n[4][0x65 - 1] = \"High Density Devices AS\",\n[4][0x66 - 1] = \"Synopsys\",\n[4][0x67 - 1] = \"Gigaram\",\n[4][0x68 - 1] = \"Enigma Semiconductor Inc\",\n[4][0x69 - 1] = \"Century Micro Inc\",\n[4][0x6a - 1] = \"Icera Semiconductor\",\n[4][0x6b - 1] = \"Mediaworks Integrated Systems\",\n[4][0x6c - 1] = \"O'Neil Product Development\",\n[4][0x6d - 1] = \"Supreme Top Technology Ltd\",\n[4][0x6e - 1] = \"MicroDisplay Corporation\",\n[4][0x6f - 1] = \"Team Group Inc\",\n[4][0x70 - 1] = \"Sinett Corporation\",\n[4][0x71 - 1] = \"Toshiba Corporation\",\n[4][0x72 - 1] = \"Tensilica\",\n[4][0x73 - 1] = \"SiRF Technology\",\n[4][0x74 - 1] = \"Bacoc Inc\",\n[4][0x75 - 1] = \"SMaL Camera Technologies\",\n[4][0x76 - 1] = \"Thomson SC\",\n[4][0x77 - 1] = \"Airgo Networks\",\n[4][0x78 - 1] = \"Wisair Ltd\",\n[4][0x79 - 1] = \"SigmaTel\",\n[4][0x7a - 1] = \"Arkados\",\n[4][0x7b - 1] = \"Compete IT gmbH Co KG\",\n[4][0x7c - 1] = \"Eudar Technology Inc\",\n[4][0x7d - 1] = \"Focus Enhancements\",\n[4][0x7e - 1] = \"Xyratex\",\n[5][0x01 - 1] = \"Specular Networks\",\n[5][0x02 - 1] = \"Patriot Memory (PDP Systems)\",\n[5][0x03 - 1] = \"U-Chip Technology Corp\",\n[5][0x04 - 1] = \"Silicon Optix\",\n[5][0x05 - 1] = \"Greenfield Networks\",\n[5][0x06 - 1] = \"CompuRAM GmbH\",\n[5][0x07 - 1] = \"Stargen Inc\",\n[5][0x08 - 1] = \"NetCell Corporation\",\n[5][0x09 - 1] = \"Excalibrus Technologies Ltd\",\n[5][0x0a - 1] = \"SCM Microsystems\",\n[5][0x0b - 1] = \"Xsigo Systems Inc\",\n[5][0x0c - 1] = \"CHIPS & Systems Inc\",\n[5][0x0d - 1] = \"Tier 1 Multichip Solutions\",\n[5][0x0e - 1] = \"CWRL Labs\",\n[5][0x0f - 1] = \"Teradici\",\n[5][0x10 - 1] = \"Gigaram Inc\",\n[5][0x11 - 1] = \"g2 Microsystems\",\n[5][0x12 - 1] = \"PowerFlash Semiconductor\",\n[5][0x13 - 1] = \"P.A. Semi Inc\",\n[5][0x14 - 1] = \"NovaTech Solutions S.A.\",\n[5][0x15 - 1] = \"c2 Microsystems Inc\",\n[5][0x16 - 1] = \"Level5 Networks\",\n[5][0x17 - 1] = \"COS Memory AG\",\n[5][0x18 - 1] = \"Innovasic Semiconductor\",\n[5][0x19 - 1] = \"02IC Co Ltd\",\n[5][0x1a - 1] = \"Tabula Inc\",\n[5][0x1b - 1] = \"Crucial Technology\",\n[5][0x1c - 1] = \"Chelsio Communications\",\n[5][0x1d - 1] = \"Solarflare Communications\",\n[5][0x1e - 1] = \"Xambala Inc\",\n[5][0x1f - 1] = \"EADS Astrium\",\n[5][0x20 - 1] = \"Terra Semiconductor Inc\",\n[5][0x21 - 1] = \"Imaging Works Inc\",\n[5][0x22 - 1] = \"Astute Networks Inc\",\n[5][0x23 - 1] = \"Tzero\",\n[5][0x24 - 1] = \"Emulex\",\n[5][0x25 - 1] = \"Power-One\",\n[5][0x26 - 1] = \"Pulse~LINK Inc\",\n[5][0x27 - 1] = \"Hon Hai Precision Industry\",\n[5][0x28 - 1] = \"White Rock Networks Inc\",\n[5][0x29 - 1] = \"Telegent Systems USA Inc\",\n[5][0x2a - 1] = \"Atrua Technologies Inc\",\n[5][0x2b - 1] = \"Acbel Polytech Inc\",\n[5][0x2c - 1] = \"eRide Inc\",\n[5][0x2d - 1] = \"ULi Electronics Inc\",\n[5][0x2e - 1] = \"Magnum Semiconductor Inc\",\n[5][0x2f - 1] = \"neoOne Technology Inc\",\n[5][0x30 - 1] = \"Connex Technology Inc\",\n[5][0x31 - 1] = \"Stream Processors Inc\",\n[5][0x32 - 1] = \"Focus Enhancements\",\n[5][0x33 - 1] = \"Telecis Wireless Inc\",\n[5][0x34 - 1] = \"uNav Microelectronics\",\n[5][0x35 - 1] = \"Tarari Inc\",\n[5][0x36 - 1] = \"Ambric Inc\",\n[5][0x37 - 1] = \"Newport Media Inc\",\n[5][0x38 - 1] = \"VMTS\",\n[5][0x39 - 1] = \"Enuclia Semiconductor Inc\",\n[5][0x3a - 1] = \"Virtium Technology Inc\",\n[5][0x3b - 1] = \"Solid State System Co Ltd\",\n[5][0x3c - 1] = \"Kian Tech LLC\",\n[5][0x3d - 1] = \"Artimi\",\n[5][0x3e - 1] = \"Power Quotient International\",\n[5][0x3f - 1] = \"Avago Technologies\",\n[5][0x40 - 1] = \"ADTechnology\",\n[5][0x41 - 1] = \"Sigma Designs\",\n[5][0x42 - 1] = \"SiCortex Inc\",\n[5][0x43 - 1] = \"Ventura Technology Group\",\n[5][0x44 - 1] = \"eASIC\",\n[5][0x45 - 1] = \"M.H.S. SAS\",\n[5][0x46 - 1] = \"Micro Star International\",\n[5][0x47 - 1] = \"Rapport Inc\",\n[5][0x48 - 1] = \"Makway International\",\n[5][0x49 - 1] = \"Broad Reach Engineering Co\",\n[5][0x4a - 1] = \"Semiconductor Mfg Intl Corp\",\n[5][0x4b - 1] = \"SiConnect\",\n[5][0x4c - 1] = \"FCI USA Inc\",\n[5][0x4d - 1] = \"Validity Sensors\",\n[5][0x4e - 1] = \"Coney Technology Co Ltd\",\n[5][0x4f - 1] = \"Spans Logic\",\n[5][0x50 - 1] = \"Neterion Inc\",\n[5][0x51 - 1] = \"Qimonda\",\n[5][0x52 - 1] = \"New Japan Radio Co Ltd\",\n[5][0x53 - 1] = \"Velogix\",\n[5][0x54 - 1] = \"Montalvo Systems\",\n[5][0x55 - 1] = \"iVivity Inc\",\n[5][0x56 - 1] = \"Walton Chaintech\",\n[5][0x57 - 1] = \"AENEON\",\n[5][0x58 - 1] = \"Lorom Industrial Co Ltd\",\n[5][0x59 - 1] = \"Radiospire Networks\",\n[5][0x5a - 1] = \"Sensio Technologies Inc\",\n[5][0x5b - 1] = \"Nethra Imaging\",\n[5][0x5c - 1] = \"Hexon Technology Pte Ltd\",\n[5][0x5d - 1] = \"CompuStocx (CSX)\",\n[5][0x5e - 1] = \"Methode Electronics Inc\",\n[5][0x5f - 1] = \"Connect One Ltd\",\n[5][0x60 - 1] = \"Opulan Technologies\",\n[5][0x61 - 1] = \"Septentrio NV\",\n[5][0x62 - 1] = \"Goldenmars Technology Inc\",\n[5][0x63 - 1] = \"Kreton Corporation\",\n[5][0x64 - 1] = \"Cochlear Ltd\",\n[5][0x65 - 1] = \"Altair Semiconductor\",\n[5][0x66 - 1] = \"NetEffect Inc\",\n[5][0x67 - 1] = \"Spansion Inc\",\n[5][0x68 - 1] = \"Taiwan Semiconductor Mfg\",\n[5][0x69 - 1] = \"Emphany Systems Inc\",\n[5][0x6a - 1] = \"ApaceWave Technologies\",\n[5][0x6b - 1] = \"Mobilygen Corporation\",\n[5][0x6c - 1] = \"Tego\",\n[5][0x6d - 1] = \"Cswitch Corporation\",\n[5][0x6e - 1] = \"Haier (Beijing) IC Design Co\",\n[5][0x6f - 1] = \"MetaRAM\",\n[5][0x70 - 1] = \"Axel Electronics Co Ltd\",\n[5][0x71 - 1] = \"Tilera Corporation\",\n[5][0x72 - 1] = \"Aquantia\",\n[5][0x73 - 1] = \"Vivace Semiconductor\",\n[5][0x74 - 1] = \"Redpine Signals\",\n[5][0x75 - 1] = \"Octalica\",\n[5][0x76 - 1] = \"InterDigital Communications\",\n[5][0x77 - 1] = \"Avant Technology\",\n[5][0x78 - 1] = \"Asrock Inc\",\n[5][0x79 - 1] = \"Availink\",\n[5][0x7a - 1] = \"Quartics Inc\",\n[5][0x7b - 1] = \"Element CXI\",\n[5][0x7c - 1] = \"Innovaciones Microelectronicas\",\n[5][0x7d - 1] = \"VeriSilicon Microelectronics\",\n[5][0x7e - 1] = \"W5 Networks\",\n[6][0x01 - 1] = \"MOVEKING\",\n[6][0x02 - 1] = \"Mavrix Technology Inc\",\n[6][0x03 - 1] = \"CellGuide Ltd\",\n[6][0x04 - 1] = \"Faraday Technology\",\n[6][0x05 - 1] = \"Diablo Technologies Inc\",\n[6][0x06 - 1] = \"Jennic\",\n[6][0x07 - 1] = \"Octasic\",\n[6][0x08 - 1] = \"Molex Incorporated\",\n[6][0x09 - 1] = \"3Leaf Networks\",\n[6][0x0a - 1] = \"Bright Micron Technology\",\n[6][0x0b - 1] = \"Netxen\",\n[6][0x0c - 1] = \"NextWave Broadband Inc\",\n[6][0x0d - 1] = \"DisplayLink\",\n[6][0x0e - 1] = \"ZMOS Technology\",\n[6][0x0f - 1] = \"Tec-Hill\",\n[6][0x10 - 1] = \"Multigig Inc\",\n[6][0x11 - 1] = \"Amimon\",\n[6][0x12 - 1] = \"Euphonic Technologies Inc\",\n[6][0x13 - 1] = \"BRN Phoenix\",\n[6][0x14 - 1] = \"InSilica\",\n[6][0x15 - 1] = \"Ember Corporation\",\n[6][0x16 - 1] = \"Avexir Technologies Corporation\",\n[6][0x17 - 1] = \"Echelon Corporation\",\n[6][0x18 - 1] = \"Edgewater Computer Systems\",\n[6][0x19 - 1] = \"XMOS Semiconductor Ltd\",\n[6][0x1a - 1] = \"GENUSION Inc\",\n[6][0x1b - 1] = \"Memory Corp NV\",\n[6][0x1c - 1] = \"SiliconBlue Technologies\",\n[6][0x1d - 1] = \"Rambus Inc\",\n[6][0x1e - 1] = \"Andes Technology Corporation\",\n[6][0x1f - 1] = \"Coronis Systems\",\n[6][0x20 - 1] = \"Achronix Semiconductor\",\n[6][0x21 - 1] = \"Siano Mobile Silicon Ltd\",\n[6][0x22 - 1] = \"Semtech Corporation\",\n[6][0x23 - 1] = \"Pixelworks Inc\",\n[6][0x24 - 1] = \"Gaisler Research AB\",\n[6][0x25 - 1] = \"Teranetics\",\n[6][0x26 - 1] = \"Toppan Printing Co Ltd\",\n[6][0x27 - 1] = \"Kingxcon\",\n[6][0x28 - 1] = \"Silicon Integrated Systems\",\n[6][0x29 - 1] = \"I-O Data Device Inc\",\n[6][0x2a - 1] = \"NDS Americas Inc\",\n[6][0x2b - 1] = \"Solomon Systech Limited\",\n[6][0x2c - 1] = \"On Demand Microelectronics\",\n[6][0x2d - 1] = \"Amicus Wireless Inc\",\n[6][0x2e - 1] = \"SMARDTV SNC\",\n[6][0x2f - 1] = \"Comsys Communication Ltd\",\n[6][0x30 - 1] = \"Movidia Ltd\",\n[6][0x31 - 1] = \"Javad GNSS Inc\",\n[6][0x32 - 1] = \"Montage Technology Group\",\n[6][0x33 - 1] = \"Trident Microsystems\",\n[6][0x34 - 1] = \"Super Talent\",\n[6][0x35 - 1] = \"Optichron Inc\",\n[6][0x36 - 1] = \"Future Waves UK Ltd\",\n[6][0x37 - 1] = \"SiBEAM Inc\",\n[6][0x38 - 1] = \"InicoreInc\",\n[6][0x39 - 1] = \"Virident Systems\",\n[6][0x3a - 1] = \"M2000 Inc\",\n[6][0x3b - 1] = \"ZeroG Wireless Inc\",\n[6][0x3c - 1] = \"Gingle Technology Co Ltd\",\n[6][0x3d - 1] = \"Space Micro Inc\",\n[6][0x3e - 1] = \"Wilocity\",\n[6][0x3f - 1] = \"Novafora Inc\",\n[6][0x40 - 1] = \"iKoa Corporation\",\n[6][0x41 - 1] = \"ASint Technology\",\n[6][0x42 - 1] = \"Ramtron\",\n[6][0x43 - 1] = \"Plato Networks Inc\",\n[6][0x44 - 1] = \"IPtronics AS\",\n[6][0x45 - 1] = \"Infinite-Memories\",\n[6][0x46 - 1] = \"Parade Technologies Inc\",\n[6][0x47 - 1] = \"Dune Networks\",\n[6][0x48 - 1] = \"GigaDevice Semiconductor\",\n[6][0x49 - 1] = \"Modu Ltd\",\n[6][0x4a - 1] = \"CEITEC\",\n[6][0x4b - 1] = \"Northrop Grumman\",\n[6][0x4c - 1] = \"XRONET Corporation\",\n[6][0x4d - 1] = \"Sicon Semiconductor AB\",\n[6][0x4e - 1] = \"Atla Electronics Co Ltd\",\n[6][0x4f - 1] = \"TOPRAM Technology\",\n[6][0x50 - 1] = \"Silego Technology Inc\",\n[6][0x51 - 1] = \"Kinglife\",\n[6][0x52 - 1] = \"Ability Industries Ltd\",\n[6][0x53 - 1] = \"Silicon Power Computer & Communications\",\n[6][0x54 - 1] = \"Augusta Technology Inc\",\n[6][0x55 - 1] = \"Nantronics Semiconductors\",\n[6][0x56 - 1] = \"Hilscher Gesellschaft\",\n[6][0x57 - 1] = \"Quixant Ltd\",\n[6][0x58 - 1] = \"Percello Ltd\",\n[6][0x59 - 1] = \"NextIO Inc\",\n[6][0x5a - 1] = \"Scanimetrics Inc\",\n[6][0x5b - 1] = \"FS-Semi Company Ltd\",\n[6][0x5c - 1] = \"Infinera Corporation\",\n[6][0x5d - 1] = \"SandForce Inc\",\n[6][0x5e - 1] = \"Lexar Media\",\n[6][0x5f - 1] = \"Teradyne Inc\",\n[6][0x60 - 1] = \"Memory Exchange Corp\",\n[6][0x61 - 1] = \"Suzhou Smartek Electronics\",\n[6][0x62 - 1] = \"Avantium Corporation\",\n[6][0x63 - 1] = \"ATP Electronics Inc\",\n[6][0x64 - 1] = \"Valens Semiconductor Ltd\",\n[6][0x65 - 1] = \"Agate Logic Inc\",\n[6][0x66 - 1] = \"Netronome\",\n[6][0x67 - 1] = \"Zenverge Inc\",\n[6][0x68 - 1] = \"N-trig Ltd\",\n[6][0x69 - 1] = \"SanMax Technologies Inc\",\n[6][0x6a - 1] = \"Contour Semiconductor Inc\",\n[6][0x6b - 1] = \"TwinMOS\",\n[6][0x6c - 1] = \"Silicon Systems Inc\",\n[6][0x6d - 1] = \"V-Color Technology Inc\",\n[6][0x6e - 1] = \"Certicom Corporation\",\n[6][0x6f - 1] = \"JSC ICC Milandr\",\n[6][0x70 - 1] = \"PhotoFast Global Inc\",\n[6][0x71 - 1] = \"InnoDisk Corporation\",\n[6][0x72 - 1] = \"Muscle Power\",\n[6][0x73 - 1] = \"Energy Micro\",\n[6][0x74 - 1] = \"Innofidei\",\n[6][0x75 - 1] = \"CopperGate Communications\",\n[6][0x76 - 1] = \"Holtek Semiconductor Inc\",\n[6][0x77 - 1] = \"Myson Century Inc\",\n[6][0x78 - 1] = \"FIDELIX\",\n[6][0x79 - 1] = \"Red Digital Cinema\",\n[6][0x7a - 1] = \"Densbits Technology\",\n[6][0x7b - 1] = \"Zempro\",\n[6][0x7c - 1] = \"MoSys\",\n[6][0x7d - 1] = \"Provigent\",\n[6][0x7e - 1] = \"Triad Semiconductor Inc\",\n[7][0x01 - 1] = \"Siklu Communication Ltd\",\n[7][0x02 - 1] = \"A Force Manufacturing Ltd\",\n[7][0x03 - 1] = \"Strontium\",\n[7][0x04 - 1] = \"ALi Corp (Abilis Systems)\",\n[7][0x05 - 1] = \"Siglead Inc\",\n[7][0x06 - 1] = \"Ubicom Inc\",\n[7][0x07 - 1] = \"Unifosa Corporation\",\n[7][0x08 - 1] = \"Stretch Inc\",\n[7][0x09 - 1] = \"Lantiq Deutschland GmbH\",\n[7][0x0a - 1] = \"Visipro.\",\n[7][0x0b - 1] = \"EKMemory\",\n[7][0x0c - 1] = \"Microelectronics Institute ZTE\",\n[7][0x0d - 1] = \"u-blox AG\",\n[7][0x0e - 1] = \"Carry Technology Co Ltd\",\n[7][0x0f - 1] = \"Nokia\",\n[7][0x10 - 1] = \"King Tiger Technology\",\n[7][0x11 - 1] = \"Sierra Wireless\",\n[7][0x12 - 1] = \"HT Micron\",\n[7][0x13 - 1] = \"Albatron Technology Co Ltd\",\n[7][0x14 - 1] = \"Leica Geosystems AG\",\n[7][0x15 - 1] = \"BroadLight\",\n[7][0x16 - 1] = \"AEXEA\",\n[7][0x17 - 1] = \"ClariPhy Communications Inc\",\n[7][0x18 - 1] = \"Green Plug\",\n[7][0x19 - 1] = \"Design Art Networks\",\n[7][0x1a - 1] = \"Mach Xtreme Technology Ltd\",\n[7][0x1b - 1] = \"ATO Solutions Co Ltd\",\n[7][0x1c - 1] = \"Ramsta\",\n[7][0x1d - 1] = \"Greenliant Systems Ltd\",\n[7][0x1e - 1] = \"Teikon\",\n[7][0x1f - 1] = \"Antec Hadron\",\n[7][0x20 - 1] = \"NavCom Technology Inc\",\n[7][0x21 - 1] = \"Shanghai Fudan Microelectronics\",\n[7][0x22 - 1] = \"Calxeda Inc\",\n[7][0x23 - 1] = \"JSC EDC Electronics\",\n[7][0x24 - 1] = \"Kandit Technology Co Ltd\",\n[7][0x25 - 1] = \"Ramos Technology\",\n[7][0x26 - 1] = \"Goldenmars Technology\",\n[7][0x27 - 1] = \"XeL Technology Inc\",\n[7][0x28 - 1] = \"Newzone Corporation\",\n[7][0x29 - 1] = \"ShenZhen MercyPower Tech\",\n[7][0x2a - 1] = \"Nanjing Yihuo Technology\",\n[7][0x2b - 1] = \"Nethra Imaging Inc\",\n[7][0x2c - 1] = \"SiTel Semiconductor BV\",\n[7][0x2d - 1] = \"SolidGear Corporation\",\n[7][0x2e - 1] = \"Topower Computer Ind Co Ltd\",\n[7][0x2f - 1] = \"Wilocity\",\n[7][0x30 - 1] = \"Profichip GmbH\",\n[7][0x31 - 1] = \"Gerad Technologies\",\n[7][0x32 - 1] = \"Ritek Corporation\",\n[7][0x33 - 1] = \"Gomos Technology Limited\",\n[7][0x34 - 1] = \"Memoright Corporation\",\n[7][0x35 - 1] = \"D-Broad Inc\",\n[7][0x36 - 1] = \"HiSilicon Technologies\",\n[7][0x37 - 1] = \"Syndiant Inc.\",\n[7][0x38 - 1] = \"Enverv Inc\",\n[7][0x39 - 1] = \"Cognex\",\n[7][0x3a - 1] = \"Xinnova Technology Inc\",\n[7][0x3b - 1] = \"Ultron AG\",\n[7][0x3c - 1] = \"Concord Idea Corporation\",\n[7][0x3d - 1] = \"AIM Corporation\",\n[7][0x3e - 1] = \"Lifetime Memory Products\",\n[7][0x3f - 1] = \"Ramsway\",\n[7][0x40 - 1] = \"Recore Systems B.V.\",\n[7][0x41 - 1] = \"Haotian Jinshibo Science Tech\",\n[7][0x42 - 1] = \"Being Advanced Memory\",\n[7][0x43 - 1] = \"Adesto Technologies\",\n[7][0x44 - 1] = \"Giantec Semiconductor Inc\",\n[7][0x45 - 1] = \"HMD Electronics AG\",\n[7][0x46 - 1] = \"Gloway International (HK)\",\n[7][0x47 - 1] = \"Kingcore\",\n[7][0x48 - 1] = \"Anucell Technology Holding\",\n[7][0x49 - 1] = \"Accord Software & Systems Pvt. Ltd\",\n[7][0x4a - 1] = \"Active-Semi Inc\",\n[7][0x4b - 1] = \"Denso Corporation\",\n[7][0x4c - 1] = \"TLSI Inc\",\n[7][0x4d - 1] = \"Qidan\",\n[7][0x4e - 1] = \"Mustang\",\n[7][0x4f - 1] = \"Orca Systems\",\n[7][0x50 - 1] = \"Passif Semiconductor\",\n[7][0x51 - 1] = \"GigaDevice Semiconductor (Beijing)\",\n[7][0x52 - 1] = \"Memphis Electronic\",\n[7][0x53 - 1] = \"Beckhoff Automation GmbH\",\n[7][0x54 - 1] = \"Harmony Semiconductor Corp\",\n[7][0x55 - 1] = \"Air Computers SRL\",\n[7][0x56 - 1] = \"TMT Memory\",\n[7][0x57 - 1] = \"Eorex Corporation\",\n[7][0x58 - 1] = \"Xingtera\",\n[7][0x59 - 1] = \"Netsol\",\n[7][0x5a - 1] = \"Bestdon Technology Co Ltd\",\n[7][0x5b - 1] = \"Baysand Inc\",\n[7][0x5c - 1] = \"Uroad Technology Co Ltd\",\n[7][0x5d - 1] = \"Wilk Elektronik S.A.\",\n[7][0x5e - 1] = \"AAI\",\n[7][0x5f - 1] = \"Harman\",\n[7][0x60 - 1] = \"Berg Microelectronics Inc\",\n[7][0x61 - 1] = \"ASSIA Inc\",\n[7][0x62 - 1] = \"Visiontek Products LLC\",\n[7][0x63 - 1] = \"OCMEMORY\",\n[7][0x64 - 1] = \"Welink Solution Inc\",\n[7][0x65 - 1] = \"Shark Gaming\",\n[7][0x66 - 1] = \"Avalanche Technology\",\n[7][0x67 - 1] = \"R&D Center ELVEES OJSC\",\n[7][0x68 - 1] = \"KingboMars Technology Co Ltd\",\n[7][0x69 - 1] = \"High Bridge Solutions Industria Eletronica\",\n[7][0x6a - 1] = \"Transcend Technology Co Ltd\",\n[7][0x6b - 1] = \"Everspin Technologies\",\n[7][0x6c - 1] = \"Hon-Hai Precision\",\n[7][0x6d - 1] = \"Smart Storage Systems\",\n[7][0x6e - 1] = \"Toumaz Group\",\n[7][0x6f - 1] = \"Zentel Electronics Corporation\",\n[7][0x70 - 1] = \"Panram International Corporation\",\n[7][0x71 - 1] = \"Silicon Space Technology\",\n[7][0x72 - 1] = \"LITE-ON IT Corporation\",\n[7][0x73 - 1] = \"Inuitive\",\n[7][0x74 - 1] = \"HMicro\",\n[7][0x75 - 1] = \"BittWare Inc\",\n[7][0x76 - 1] = \"GLOBALFOUNDRIES\",\n[7][0x77 - 1] = \"ACPI Digital Co Ltd\",\n[7][0x78 - 1] = \"Annapurna Labs\",\n[7][0x79 - 1] = \"AcSiP Technology Corporation\",\n[7][0x7a - 1] = \"Idea! Electronic Systems\",\n[7][0x7b - 1] = \"Gowe Technology Co Ltd\",\n[7][0x7c - 1] = \"Hermes Testing Solutions Inc\",\n[7][0x7d - 1] = \"Positivo BGH\",\n[7][0x7e - 1] = \"Intelligence Silicon Technology\",\n[8][0x01 - 1] = \"3D PLUS\",\n[8][0x02 - 1] = \"Diehl Aerospace\",\n[8][0x03 - 1] = \"Fairchild\",\n[8][0x04 - 1] = \"Mercury Systems\",\n[8][0x05 - 1] = \"Sonics Inc\",\n[8][0x06 - 1] = \"Emerson Automation Solutions\",\n[8][0x07 - 1] = \"Shenzhen Jinge Information Co Ltd\",\n[8][0x08 - 1] = \"SCWW\",\n[8][0x09 - 1] = \"Silicon Motion Inc\",\n[8][0x0a - 1] = \"Anurag\",\n[8][0x0b - 1] = \"King Kong\",\n[8][0x0c - 1] = \"FROM30 Co Ltd\",\n[8][0x0d - 1] = \"Gowin Semiconductor Corp\",\n[8][0x0e - 1] = \"Fremont Micro Devices Ltd\",\n[8][0x0f - 1] = \"Ericsson Modems\",\n[8][0x10 - 1] = \"Exelis\",\n[8][0x11 - 1] = \"Satixfy Ltd\",\n[8][0x12 - 1] = \"Galaxy Microsystems Ltd\",\n[8][0x13 - 1] = \"Gloway International Co Ltd\",\n[8][0x14 - 1] = \"Lab\",\n[8][0x15 - 1] = \"Smart Energy Instruments\",\n[8][0x16 - 1] = \"Approved Memory Corporation\",\n[8][0x17 - 1] = \"Axell Corporation\",\n[8][0x18 - 1] = \"Essencore Limited\",\n[8][0x19 - 1] = \"Phytium\",\n[8][0x1a - 1] = \"Xi'an UniIC Semiconductors Co Ltd\",\n[8][0x1b - 1] = \"Ambiq Micro\",\n[8][0x1c - 1] = \"eveRAM Technology Inc\",\n[8][0x1d - 1] = \"Infomax\",\n[8][0x1e - 1] = \"Butterfly Network Inc\",\n[8][0x1f - 1] = \"Shenzhen City Gcai Electronics\",\n[8][0x20 - 1] = \"Stack Devices Corporation\",\n[8][0x21 - 1] = \"ADK Media Group\",\n[8][0x22 - 1] = \"TSP Global Co Ltd\",\n[8][0x23 - 1] = \"HighX\",\n[8][0x24 - 1] = \"Shenzhen Elicks Technology\",\n[8][0x25 - 1] = \"XinKai/Silicon Kaiser\",\n[8][0x26 - 1] = \"Google Inc\",\n[8][0x27 - 1] = \"Dasima International Development\",\n[8][0x28 - 1] = \"Leahkinn Technology Limited\",\n[8][0x29 - 1] = \"HIMA Paul Hildebrandt GmbH Co KG\",\n[8][0x2a - 1] = \"Keysight Technologies\",\n[8][0x2b - 1] = \"Techcomp International (Fastable)\",\n[8][0x2c - 1] = \"Ancore Technology Corporation\",\n[8][0x2d - 1] = \"Nuvoton\",\n[8][0x2e - 1] = \"Korea Uhbele International Group Ltd\",\n[8][0x2f - 1] = \"Ikegami Tsushinki Co Ltd\",\n[8][0x30 - 1] = \"RelChip Inc\",\n[8][0x31 - 1] = \"Baikal Electronics\",\n[8][0x32 - 1] = \"Nemostech Inc\",\n[8][0x33 - 1] = \"Memorysolution GmbH\",\n[8][0x34 - 1] = \"Silicon Integrated Systems Corporation\",\n[8][0x35 - 1] = \"Xiede\",\n[8][0x36 - 1] = \"BRC\",\n[8][0x37 - 1] = \"Flash Chi\",\n[8][0x38 - 1] = \"Jone\",\n[8][0x39 - 1] = \"GCT Semiconductor Inc\",\n[8][0x3a - 1] = \"Hong Kong Zetta Device Technology\",\n[8][0x3b - 1] = \"Unimemory Technology(s) Pte Ltd\",\n[8][0x3c - 1] = \"Cuso\",\n[8][0x3d - 1] = \"Kuso\",\n[8][0x3e - 1] = \"Uniquify Inc\",\n[8][0x3f - 1] = \"Skymedi Corporation\",\n[8][0x40 - 1] = \"Core Chance Co Ltd\",\n[8][0x41 - 1] = \"Tekism Co Ltd\",\n[8][0x42 - 1] = \"Seagate Technology PLC\",\n[8][0x43 - 1] = \"Hong Kong Gaia Group Co Limited\",\n[8][0x44 - 1] = \"Gigacom Semiconductor LLC\",\n[8][0x45 - 1] = \"V2 Technologies\",\n[8][0x46 - 1] = \"TLi\",\n[8][0x47 - 1] = \"Neotion\",\n[8][0x48 - 1] = \"Lenovo\",\n[8][0x49 - 1] = \"Shenzhen Zhongteng Electronic Corp Ltd\",\n[8][0x4a - 1] = \"Compound Photonics\",\n[8][0x4b - 1] = \"in2H2 inc\",\n[8][0x4c - 1] = \"Shenzhen Pango Microsystems Co Ltd\",\n[8][0x4d - 1] = \"Vasekey\",\n[8][0x4e - 1] = \"Cal-Comp Industria de Semicondutores\",\n[8][0x4f - 1] = \"Eyenix Co Ltd\",\n[8][0x50 - 1] = \"Heoriady\",\n[8][0x51 - 1] = \"Accelerated Memory Production Inc\",\n[8][0x52 - 1] = \"INVECAS Inc\",\n[8][0x53 - 1] = \"AP Memory\",\n[8][0x54 - 1] = \"Douqi Technology\",\n[8][0x55 - 1] = \"Etron Technology Inc\",\n[8][0x56 - 1] = \"Indie Semiconductor\",\n[8][0x57 - 1] = \"Socionext Inc\",\n[8][0x58 - 1] = \"HGST\",\n[8][0x59 - 1] = \"EVGA\",\n[8][0x5a - 1] = \"Audience Inc\",\n[8][0x5b - 1] = \"EpicGear\",\n[8][0x5c - 1] = \"Vitesse Enterprise Co\",\n[8][0x5d - 1] = \"Foxtronn International Corporation\",\n[8][0x5e - 1] = \"Bretelon Inc\",\n[8][0x5f - 1] = \"Graphcore\",\n[8][0x60 - 1] = \"Eoplex Inc\",\n[8][0x61 - 1] = \"MaxLinear Inc\",\n[8][0x62 - 1] = \"ETA Devices\",\n[8][0x63 - 1] = \"LOKI\",\n[8][0x64 - 1] = \"IMS Electronics Co Ltd\",\n[8][0x65 - 1] = \"Dosilicon Co Ltd\",\n[8][0x66 - 1] = \"Dolphin Integration\",\n[8][0x67 - 1] = \"Shenzhen Mic Electronics Technolog\",\n[8][0x68 - 1] = \"Boya Microelectronics Inc\",\n[8][0x69 - 1] = \"Geniachip (Roche)\",\n[8][0x6a - 1] = \"Axign\",\n[8][0x6b - 1] = \"Kingred Electronic Technology Ltd\",\n[8][0x6c - 1] = \"Chao Yue Zhuo Computer Business Dept.\",\n[8][0x6d - 1] = \"Guangzhou Si Nuo Electronic Technology.\",\n[8][0x6e - 1] = \"Crocus Technology Inc\",\n[8][0x6f - 1] = \"Creative Chips GmbH\",\n[8][0x70 - 1] = \"GE Aviation Systems LLC.\",\n[8][0x71 - 1] = \"Asgard\",\n[8][0x72 - 1] = \"Good Wealth Technology Ltd\",\n[8][0x73 - 1] = \"TriCor Technologies\",\n[8][0x74 - 1] = \"Nova-Systems GmbH\",\n[8][0x75 - 1] = \"JUHOR\",\n[8][0x76 - 1] = \"Zhuhai Douke Commerce Co Ltd\",\n[8][0x77 - 1] = \"DSL Memory\",\n[8][0x78 - 1] = \"Anvo-Systems Dresden GmbH\",\n[8][0x79 - 1] = \"Realtek\",\n[8][0x7a - 1] = \"AltoBeam\",\n[8][0x7b - 1] = \"Wave Computing\",\n[8][0x7c - 1] = \"Beijing TrustNet Technology Co Ltd\",\n[8][0x7d - 1] = \"Innovium Inc\",\n[8][0x7e - 1] = \"Starsway Technology Limited\",\n[9][0x01 - 1] = \"Weltronics Co LTD\",\n[9][0x02 - 1] = \"VMware Inc\",\n[9][0x03 - 1] = \"Hewlett Packard Enterprise\",\n[9][0x04 - 1] = \"INTENSO\",\n[9][0x05 - 1] = \"Puya Semiconductor\",\n[9][0x06 - 1] = \"MEMORFI\",\n[9][0x07 - 1] = \"MSC Technologies GmbH\",\n[9][0x08 - 1] = \"Txrui\",\n[9][0x09 - 1] = \"SiFive Inc\",\n[9][0x0a - 1] = \"Spreadtrum Communications\",\n[9][0x0b - 1] = \"XTX Technology Limited\",\n[9][0x0c - 1] = \"UMAX Technology\",\n[9][0x0d - 1] = \"Shenzhen Yong Sheng Technology\",\n[9][0x0e - 1] = \"SNOAMOO (Shenzhen Kai Zhuo Yue)\",\n[9][0x0f - 1] = \"Daten Tecnologia LTDA\",\n[9][0x10 - 1] = \"Shenzhen XinRuiYan Electronics\",\n[9][0x11 - 1] = \"Eta Compute\",\n[9][0x12 - 1] = \"Energous\",\n[9][0x13 - 1] = \"Raspberry Pi Trading Ltd\",\n[9][0x14 - 1] = \"Shenzhen Chixingzhe Tech Co Ltd\",\n[9][0x15 - 1] = \"Silicon Mobility\",\n[9][0x16 - 1] = \"IQ-Analog Corporation\",\n[9][0x17 - 1] = \"Uhnder Inc\",\n[9][0x18 - 1] = \"Impinj\",\n[9][0x19 - 1] = \"DEPO Computers\",\n[9][0x1a - 1] = \"Nespeed Sysems\",\n[9][0x1b - 1] = \"Yangtze Memory Technologies Co Ltd\",\n[9][0x1c - 1] = \"MemxPro Inc\",\n[9][0x1d - 1] = \"Tammuz Co Ltd\",\n[9][0x1e - 1] = \"Allwinner Technology\",\n[9][0x1f - 1] = \"Shenzhen City Futian District Qing Xuan Tong Computer Trading Firm\",\n[9][0x20 - 1] = \"XMC\",\n[9][0x21 - 1] = \"Teclast\",\n[9][0x22 - 1] = \"Maxsun\",\n[9][0x23 - 1] = \"Haiguang Integrated Circuit Design\",\n[9][0x24 - 1] = \"RamCENTER Technology\",\n[9][0x25 - 1] = \"Phison Electronics Corporation\",\n[9][0x26 - 1] = \"Guizhou Huaxintong Semi-Conductor\",\n[9][0x27 - 1] = \"Network Intelligence\",\n[9][0x28 - 1] = \"Continental Technology (Holdings)\",\n[9][0x29 - 1] = \"Guangzhou Huayan Suning Electronic\",\n[9][0x2a - 1] = \"Guangzhou Zhouji Electronic Co Ltd\",\n[9][0x2b - 1] = \"Shenzhen Giant Hui Kang Tech Co Ltd\",\n[9][0x2c - 1] = \"Shenzhen Yilong Innovative Co Ltd\",\n[9][0x2d - 1] = \"Neo Forza\",\n[9][0x2e - 1] = \"Lyontek Inc\",\n[9][0x2f - 1] = \"Shanghai Kuxin Microelectronics Ltd\",\n[9][0x30 - 1] = \"Shenzhen Larix Technology Co Ltd\",\n[9][0x31 - 1] = \"Qbit Semiconductor Ltd\",\n[9][0x32 - 1] = \"Insignis Technology Corporation\",\n[9][0x33 - 1] = \"Lanson Memory Co Ltd\",\n[9][0x34 - 1] = \"Shenzhen Superway Electronics Co Ltd\",\n[9][0x35 - 1] = \"Canaan-Creative Co Ltd\",\n[9][0x36 - 1] = \"Black Diamond Memory\",\n[9][0x37 - 1] = \"Shenzhen City Parker Baking Electronics\",\n[9][0x38 - 1] = \"Shenzhen Baihong Technology Co Ltd\",\n[9][0x39 - 1] = \"GEO Semiconductors\",\n[9][0x3a - 1] = \"OCPC\",\n[9][0x3b - 1] = \"Artery Technology Co Ltd\",\n[9][0x3c - 1] = \"Jinyu\",\n[9][0x3d - 1] = \"ShenzhenYing Chi Technology Development\",\n[9][0x3e - 1] = \"Shenzhen Pengcheng Xin Technology\",\n[9][0x3f - 1] = \"Pegasus Semiconductor (Shanghai) Co\",\n[9][0x40 - 1] = \"Mythic Inc\",\n[9][0x41 - 1] = \"Elmos Semiconductor AG\",\n[9][0x42 - 1] = \"Kllisre\",\n[9][0x43 - 1] = \"Shenzhen Winconway Technology\",\n[9][0x44 - 1] = \"Shenzhen Xingmem Technology Corp\",\n[9][0x45 - 1] = \"Gold Key Technology Co Ltd\",\n[9][0x46 - 1] = \"Habana Labs Ltd\",\n[9][0x47 - 1] = \"Hoodisk Electronics Co Ltd\",\n[9][0x48 - 1] = \"SemsoTai (SZ) Technology Co Ltd\",\n[9][0x49 - 1] = \"OM Nanotech Pvt. Ltd\",\n[9][0x4a - 1] = \"Shenzhen Zhifeng Weiye Technology\",\n[9][0x4b - 1] = \"Xinshirui (Shenzhen) Electronics Co\",\n[9][0x4c - 1] = \"Guangzhou Zhong Hao Tian Electronic\",\n[9][0x4d - 1] = \"Shenzhen Longsys Electronics Co Ltd\",\n[9][0x4e - 1] = \"Deciso B.V.\",\n[9][0x4f - 1] = \"Puya Semiconductor (Shenzhen)\",\n[9][0x50 - 1] = \"Shenzhen Veineda Technology Co Ltd\",\n[9][0x51 - 1] = \"Antec Memory\",\n[9][0x52 - 1] = \"Cortus SAS\",\n[9][0x53 - 1] = \"Dust Leopard\",\n[9][0x54 - 1] = \"MyWo AS\",\n[9][0x55 - 1] = \"J&A Information Inc\",\n[9][0x56 - 1] = \"Shenzhen JIEPEI Technology Co Ltd\",\n[9][0x57 - 1] = \"Heidelberg University\",\n[9][0x58 - 1] = \"Flexxon PTE Ltd\",\n[9][0x59 - 1] = \"Wiliot\",\n[9][0x5a - 1] = \"Raysun Electronics International Ltd\",\n[9][0x5b - 1] = \"Aquarius Production Company LLC\",\n[9][0x5c - 1] = \"MACNICA DHW LTDA\",\n[9][0x5d - 1] = \"Intelimem\",\n[9][0x5e - 1] = \"Zbit Semiconductor Inc\",\n[9][0x5f - 1] = \"Shenzhen Technology Co Ltd\",\n[9][0x60 - 1] = \"Signalchip\",\n[9][0x61 - 1] = \"Shenzen Recadata Storage Technology\",\n[9][0x62 - 1] = \"Hyundai Technology\",\n[9][0x63 - 1] = \"Shanghai Fudi Investment Development\",\n[9][0x64 - 1] = \"Aixi Technology\",\n[9][0x65 - 1] = \"Tecon MT\",\n[9][0x66 - 1] = \"Onda Electric Co Ltd\",\n[9][0x67 - 1] = \"Jinshen\",\n[9][0x68 - 1] = \"Kimtigo Semiconductor (HK) Limited\",\n[9][0x69 - 1] = \"IIT Madras\",\n[9][0x6a - 1] = \"Shenshan (Shenzhen) Electronic\",\n[9][0x6b - 1] = \"Hefei Core Storage Electronic Limited\",\n[9][0x6c - 1] = \"Colorful Technology Ltd\",\n[9][0x6d - 1] = \"Visenta (Xiamen) Technology Co Ltd\",\n[9][0x6e - 1] = \"Roa Logic BV\",\n[9][0x6f - 1] = \"NSITEXE Inc\",\n[9][0x70 - 1] = \"Hong Kong Hyunion Electronics\",\n[9][0x71 - 1] = \"ASK Technology Group Limited\",\n[9][0x72 - 1] = \"GIGA-BYTE Technology Co Ltd\",\n[9][0x73 - 1] = \"Terabyte Co Ltd\",\n[9][0x74 - 1] = \"Hyundai Inc\",\n[9][0x75 - 1] = \"EXCELERAM\",\n[9][0x76 - 1] = \"PsiKick\",\n[9][0x77 - 1] = \"Netac Technology Co Ltd\",\n[9][0x78 - 1] = \"PCCOOLER\",\n[9][0x79 - 1] = \"Jiangsu Huacun Electronic Technology\",\n[9][0x7a - 1] = \"Shenzhen Micro Innovation Industry\",\n[9][0x7b - 1] = \"Beijing Tongfang Microelectronics Co\",\n[9][0x7c - 1] = \"XZN Storage Technology\",\n[9][0x7d - 1] = \"ChipCraft Sp. z.o.o.\",\n[9][0x7e - 1] = \"ALLFLASH Technology Limited\",\n[10][0x01 - 1] = \"Foerd Technology Co Ltd\",\n[10][0x02 - 1] = \"KingSpec\",\n[10][0x03 - 1] = \"Codasip GmbH\",\n[10][0x04 - 1] = \"SL Link Co Ltd\",\n[10][0x05 - 1] = \"Shenzhen Kefu Technology Co Limited\",\n[10][0x06 - 1] = \"Shenzhen ZST Electronics Technology\",\n[10][0x07 - 1] = \"Kyokuto Electronic Inc\",\n[10][0x08 - 1] = \"Warrior Technology\",\n[10][0x09 - 1] = \"TRINAMIC Motion Control GmbH & Co\",\n[10][0x0a - 1] = \"PixelDisplay Inc\",\n[10][0x0b - 1] = \"Shenzhen Futian District Bo Yueda Elec\",\n[10][0x0c - 1] = \"Richtek Power\",\n[10][0x0d - 1] = \"Shenzhen LianTeng Electronics Co Ltd\",\n[10][0x0e - 1] = \"AITC Memory\",\n[10][0x0f - 1] = \"UNIC Memory Technology Co Ltd\",\n[10][0x10 - 1] = \"Shenzhen Huafeng Science Technology\",\n[10][0x11 - 1] = \"CXMT\",\n[10][0x12 - 1] = \"Guangzhou Xinyi Heng Computer Trading Firm\",\n[10][0x13 - 1] = \"SambaNova Systems\",\n[10][0x14 - 1] = \"V-GEN\",\n[10][0x15 - 1] = \"Jump Trading\",\n[10][0x16 - 1] = \"Ampere Computing\",\n[10][0x17 - 1] = \"Shenzhen Zhongshi Technology Co Ltd\",\n[10][0x18 - 1] = \"Shenzhen Zhongtian Bozhong Technology\",\n[10][0x19 - 1] = \"Tri-Tech International\",\n[10][0x1a - 1] = \"Silicon Intergrated Systems Corporation\",\n[10][0x1b - 1] = \"Shenzhen HongDingChen Information\",\n[10][0x1c - 1] = \"Plexton Holdings Limited\",\n[10][0x1d - 1] = \"AMS (Jiangsu Advanced Memory Semi)\",\n[10][0x1e - 1] = \"Wuhan Jing Tian Interconnected Tech Co\",\n[10][0x1f - 1] = \"Axia Memory Technology\",\n[10][0x20 - 1] = \"Chipset Technology Holding Limited\",\n[10][0x21 - 1] = \"Shenzhen Xinshida Technology Co Ltd\",\n[10][0x22 - 1] = \"Shenzhen Chuangshifeida Technology\",\n[10][0x23 - 1] = \"Guangzhou MiaoYuanJi Technology\",\n[10][0x24 - 1] = \"ADVAN Inc\",\n[10][0x25 - 1] = \"Shenzhen Qianhai Weishengda Electronic Commerce Company Ltd\",\n[10][0x26 - 1] = \"Guangzhou Guang Xie Cheng Trading\",\n[10][0x27 - 1] = \"StarRam International Co Ltd\",\n[10][0x28 - 1] = \"Shen Zhen XinShenHua Tech Co Ltd\",\n[10][0x29 - 1] = \"UltraMemory Inc\",\n[10][0x2a - 1] = \"New Coastline Global Tech Industry Co\",\n[10][0x2b - 1] = \"Sinker\",\n[10][0x2c - 1] = \"Diamond\",\n[10][0x2d - 1] = \"PUSKILL\",\n[10][0x2e - 1] = \"Guangzhou Hao Jia Ye Technology Co\",\n[10][0x2f - 1] = \"Ming Xin Limited\",\n[10][0x30 - 1] = \"Barefoot Networks\",\n[10][0x31 - 1] = \"Biwin Semiconductor (HK) Co Ltd\",\n[10][0x32 - 1] = \"UD INFO Corporation\",\n[10][0x33 - 1] = \"Trek Technology (S) PTE Ltd\",\n[10][0x34 - 1] = \"Xiamen Kingblaze Technology Co Ltd\",\n[10][0x35 - 1] = \"Shenzhen Lomica Technology Co Ltd\",\n[10][0x36 - 1] = \"Nuclei System Technology Co Ltd\",\n[10][0x37 - 1] = \"Wuhan Xun Zhan Electronic Technology\",\n[10][0x38 - 1] = \"Shenzhen Ingacom Semiconductor Ltd\",\n[10][0x39 - 1] = \"Zotac Technology Ltd\",\n[10][0x3a - 1] = \"Foxline\",\n[10][0x3b - 1] = \"Shenzhen Farasia Science Technology\",\n[10][0x3c - 1] = \"Efinix Inc\",\n[10][0x3d - 1] = \"Hua Nan San Xian Technology Co Ltd\",\n[10][0x3e - 1] = \"Goldtech Electronics Co Ltd\",\n[10][0x3f - 1] = \"Shanghai Han Rong Microelectronics Co\",\n[10][0x40 - 1] = \"Shenzhen Zhongguang Yunhe Trading\",\n[10][0x41 - 1] = \"Smart Shine(QingDao) Microelectronics\",\n[10][0x42 - 1] = \"Thermaltake Technology Co Ltd\",\n[10][0x43 - 1] = \"Shenzhen O'Yang Maile Technology Ltd\",\n[10][0x44 - 1] = \"UPMEM\",\n[10][0x45 - 1] = \"Chun Well Technology Holding Limited\",\n[10][0x46 - 1] = \"Astera Labs Inc\",\n[10][0x47 - 1] = \"Winconway\",\n[10][0x48 - 1] = \"Advantech Co Ltd\",\n[10][0x49 - 1] = \"Chengdu Fengcai Electronic Technology\",\n[10][0x4a - 1] = \"The Boeing Company\",\n[10][0x4b - 1] = \"Blaize Inc\",\n[10][0x4c - 1] = \"Ramonster Technology Co Ltd\",\n[10][0x4d - 1] = \"Wuhan Naonongmai Technology Co Ltd\",\n[10][0x4e - 1] = \"Shenzhen Hui ShingTong Technology\",\n[10][0x4f - 1] = \"Yourlyon\",\n[10][0x50 - 1] = \"Fabu Technology\",\n[10][0x51 - 1] = \"Shenzhen Yikesheng Technology Co Ltd\",\n[10][0x52 - 1] = \"NOR-MEM\",\n[10][0x53 - 1] = \"Cervoz Co Ltd\",\n[10][0x54 - 1] = \"Bitmain Technologies Inc.\",\n[10][0x55 - 1] = \"Facebook Inc\",\n[10][0x56 - 1] = \"Shenzhen Longsys Electronics Co Ltd\",\n[10][0x57 - 1] = \"Guangzhou Siye Electronic Technology\",\n[10][0x58 - 1] = \"Silergy\",\n[10][0x59 - 1] = \"Adamway\",\n[10][0x5a - 1] = \"PZG\",\n[10][0x5b - 1] = \"Shenzhen King Power Electronics\",\n[10][0x5c - 1] = \"Guangzhou ZiaoFu Tranding Co Ltd\",\n[10][0x5d - 1] = \"Shenzhen SKIHOTAR Semiconductor\",\n[10][0x5e - 1] = \"PulseRain Technology\",\n[10][0x5f - 1] = \"Seeker Technology Limited\",\n[10][0x60 - 1] = \"Shenzhen OSCOO Tech Co Ltd\",\n[10][0x61 - 1] = \"Shenzhen Yze Technology Co Ltd\",\n[10][0x62 - 1] = \"Shenzhen Jieshuo Electronic Commerce\",\n[10][0x63 - 1] = \"Gazda\",\n[10][0x64 - 1] = \"Hua Wei Technology Co Ltd\",\n[10][0x65 - 1] = \"Esperanto Technologies\",\n[10][0x66 - 1] = \"JinSheng Electronic (Shenzhen) Co Ltd\",\n[10][0x67 - 1] = \"Shenzhen Shi Bolunshuai Technology\",\n[10][0x68 - 1] = \"Shanghai Rei Zuan Information Tech\",\n[10][0x69 - 1] = \"Fraunhofer IIS\",\n[10][0x6a - 1] = \"Kandou Bus SA\",\n[10][0x6b - 1] = \"Acer\",\n[10][0x6c - 1] = \"Artmem Technology Co Ltd\",\n[10][0x6d - 1] = \"Gstar Semiconductor Co Ltd\",\n[10][0x6e - 1] = \"ShineDisk\",\n[10][0x6f - 1] = \"Shenzhen CHN Technology Co Ltd\",\n[10][0x70 - 1] = \"UnionChip Semiconductor Co Ltd\",\n[10][0x71 - 1] = \"Tanbassh\",\n[10][0x72 - 1] = \"Shenzhen Tianyu Jieyun Intl Logistics\",\n[10][0x73 - 1] = \"MCLogic Inc\",\n[10][0x74 - 1] = \"Eorex Corporation\",\n[10][0x75 - 1] = \"Arm Technology (China) Co Ltd\",\n[10][0x76 - 1] = \"Lexar Co Limited\",\n[10][0x77 - 1] = \"QinetiQ Group plc\",\n[10][0x78 - 1] = \"Exascend\",\n[10][0x79 - 1] = \"Hong Kong Hyunion Electronics Co Ltd\",\n[10][0x7a - 1] = \"Shenzhen Banghong Electronics Co Ltd\",\n[10][0x7b - 1] = \"MBit Wireless Inc\",\n[10][0x7c - 1] = \"Hex Five Security Inc\",\n[10][0x7d - 1] = \"ShenZhen Juhor Precision Tech Co Ltd\",\n[10][0x7e - 1] = \"Shenzhen Reeinno Technology Co Ltd\",\n[11][0x01 - 1] = \"ABIT Electronics (Shenzhen) Co Ltd\",\n[11][0x02 - 1] = \"Semidrive\",\n[11][0x03 - 1] = \"MyTek Electronics Corp\",\n[11][0x04 - 1] = \"Wxilicon Technology Co Ltd\",\n[11][0x05 - 1] = \"Shenzhen Meixin Electronics Ltd\",\n[11][0x06 - 1] = \"Ghost Wolf\",\n[11][0x07 - 1] = \"LiSion Technologies Inc\",\n[11][0x08 - 1] = \"Power Active Co Ltd\",\n[11][0x09 - 1] = \"Pioneer High Fidelity Taiwan Co. Ltd\",\n[11][0x0a - 1] = \"LuoSilk\",\n[11][0x0b - 1] = \"Shenzhen Chuangshifeida Technology\",\n[11][0x0c - 1] = \"Black Sesame Technologies Inc\",\n[11][0x0d - 1] = \"Jiangsu Xinsheng Intelligent Technology\",\n[11][0x0e - 1] = \"MLOONG\",\n[11][0x0f - 1] = \"Quadratica LLC\",\n[11][0x10 - 1] = \"Anpec Electronics\",\n[11][0x11 - 1] = \"Xi'an Morebeck Semiconductor Tech Co\",\n[11][0x12 - 1] = \"Kingbank Technology Co Ltd\",\n[11][0x13 - 1] = \"ITRenew Inc\",\n[11][0x14 - 1] = \"Shenzhen Eaget Innovation Tech Ltd\",\n[11][0x15 - 1] = \"Jazer\",\n[11][0x16 - 1] = \"Xiamen Semiconductor Investment Group\",\n[11][0x17 - 1] = \"Guangzhou Longdao Network Tech Co\",\n[11][0x18 - 1] = \"Shenzhen Futian SEC Electronic Market\",\n[11][0x19 - 1] = \"Allegro Microsystems LLC\",\n[11][0x1a - 1] = \"Hunan RunCore Innovation Technology\",\n[11][0x1b - 1] = \"C-Corsa Technology\",\n[11][0x1c - 1] = \"Zhuhai Chuangfeixin Technology Co Ltd\",\n[11][0x1d - 1] = \"Beijing InnoMem Technologies Co Ltd\",\n[11][0x1e - 1] = \"YooTin\",\n[11][0x1f - 1] = \"Shenzhen Pengxiong Technology Co Ltd\",\n[11][0x20 - 1] = \"Dongguan Yingbang Commercial Trading Co\",\n[11][0x21 - 1] = \"Shenzhen Ronisys Electronics Co Ltd\",\n[11][0x22 - 1] = \"Hongkong Xinlan Guangke Co Ltd\",\n[11][0x23 - 1] = \"Apex Microelectronics Co Ltd\",\n[11][0x24 - 1] = \"Beijing Hongda Jinming Technology Co Ltd\",\n[11][0x25 - 1] = \"Ling Rui Technology (Shenzhen) Co Ltd\",\n[11][0x26 - 1] = \"Hongkong Hyunion Electronics Co Ltd\",\n[11][0x27 - 1] = \"Starsystems Inc\",\n[11][0x28 - 1] = \"Shenzhen Yingjiaxun Industrial Co Ltd\",\n[11][0x29 - 1] = \"Dongguan Crown Code Electronic Commerce\",\n[11][0x2a - 1] = \"Monolithic Power Systems Inc\",\n[11][0x2b - 1] = \"WuHan SenNaiBo E-Commerce Co Ltd\",\n[11][0x2c - 1] = \"Hangzhou Hikstorage Technology Co\",\n[11][0x2d - 1] = \"Shenzhen Goodix Technology Co Ltd\",\n[11][0x2e - 1] = \"Aigo Electronic Technology Co Ltd\",\n[11][0x2f - 1] = \"Hefei Konsemi Storage Technology Co Ltd\",\n[11][0x30 - 1] = \"Cactus Technologies Limited\",\n[11][0x31 - 1] = \"DSIN\",\n[11][0x32 - 1] = \"Blu Wireless Technology\",\n[11][0x33 - 1] = \"Nanjing UCUN Technology Inc\",\n[11][0x34 - 1] = \"Acacia Communications\",\n[11][0x35 - 1] = \"Beijinjinshengyihe Technology Co Ltd\",\n[11][0x36 - 1] = \"Zyzyx\",\n[11][0x37 - 1] = \"T-HEAD Semiconductor Co Ltd\",\n[11][0x38 - 1] = \"Shenzhen Hystou Technology Co Ltd\",\n[11][0x39 - 1] = \"Syzexion\",\n[11][0x3a - 1] = \"Kembona\",\n[11][0x3b - 1] = \"Qingdao Thunderobot Technology Co Ltd\",\n[11][0x3c - 1] = \"Morse Micro\",\n[11][0x3d - 1] = \"Shenzhen Envida Technology Co Ltd\",\n[11][0x3e - 1] = \"UDStore Solution Limited\",\n[11][0x3f - 1] = \"Shunlie\",\n[11][0x40 - 1] = \"Shenzhen Xin Hong Rui Tech Ltd\",\n[11][0x41 - 1] = \"Shenzhen Yze Technology Co Ltd\",\n[11][0x42 - 1] = \"Shenzhen Huang Pu He Xin Technology\",\n[11][0x43 - 1] = \"Xiamen Pengpai Microelectronics Co Ltd\",\n[11][0x44 - 1] = \"JISHUN\",\n[11][0x45 - 1] = \"Shenzhen WODPOSIT Technology Co\",\n[11][0x46 - 1] = \"Unistar\",\n[11][0x47 - 1] = \"UNICORE Electronic (Suzhou) Co Ltd\",\n[11][0x48 - 1] = \"Axonne Inc\",\n[11][0x49 - 1] = \"Shenzhen SOVERECA Technology Co\",\n[11][0x4a - 1] = \"Dire Wolf\",\n[11][0x4b - 1] = \"Whampoa Core Technology Co Ltd\",\n[11][0x4c - 1] = \"CSI Halbleiter GmbH\",\n[11][0x4d - 1] = \"ONE Semiconductor\",\n[11][0x4e - 1] = \"SimpleMachines Inc\",\n[11][0x4f - 1] = \"Shenzhen Chengyi Qingdian Electronic\",\n[11][0x50 - 1] = \"Shenzhen Xinlianxin Network Technology\",\n[11][0x51 - 1] = \"Vayyar Imaging Ltd\",\n[11][0x52 - 1] = \"Paisen Network Technology Co Ltd\",\n[11][0x53 - 1] = \"Shenzhen Fengwensi Technology Co Ltd\",\n[11][0x54 - 1] = \"Caplink Technology Limited\",\n[11][0x55 - 1] = \"JJT Solution Co Ltd\",\n[11][0x56 - 1] = \"HOSIN Global Electronics Co Ltd\",\n[11][0x57 - 1] = \"Shenzhen KingDisk Century Technology\",\n[11][0x58 - 1] = \"SOYO\",\n[11][0x59 - 1] = \"DIT Technology Co Ltd\",\n[11][0x5a - 1] = \"iFound\",\n[11][0x5b - 1] = \"Aril Computer Company\",\n[11][0x5c - 1] = \"ASUS\",\n[11][0x5d - 1] = \"Shenzhen Ruiyingtong Technology Co\",\n[11][0x5e - 1] = \"HANA Micron\",\n[11][0x5f - 1] = \"RANSOR\",\n[11][0x60 - 1] = \"Axiado Corporation\",\n[11][0x61 - 1] = \"Tesla Corporation\",\n[11][0x62 - 1] = \"Pingtouge (Shanghai) Semiconductor Co\",\n[11][0x63 - 1] = \"S3Plus Technologies SA\",\n[11][0x64 - 1] = \"Integrated Silicon Solution Israel Ltd\",\n[11][0x65 - 1] = \"GreenWaves Technologies\",\n[11][0x66 - 1] = \"NUVIA Inc\",\n[11][0x67 - 1] = \"Guangzhou Shuvrwine Technology Co\",\n[11][0x68 - 1] = \"Shenzhen Hangshun Chip Technology\",\n[11][0x69 - 1] = \"Chengboliwei Electronic Business\",\n[11][0x6a - 1] = \"Kowin Technology HK Limited\",\n[11][0x6b - 1] = \"Euronet Technology Inc\",\n[11][0x6c - 1] = \"SCY\",\n[11][0x6d - 1] = \"Shenzhen Xinhongyusheng Electrical\",\n[11][0x6e - 1] = \"PICOCOM\",\n[11][0x6f - 1] = \"Shenzhen Toooogo Memory Technology\",\n[11][0x70 - 1] = \"VLSI Solution\",\n[11][0x71 - 1] = \"Costar Electronics Inc\",\n[11][0x72 - 1] = \"Shenzhen Huatop Technology Co Ltd\",\n[11][0x73 - 1] = \"Inspur Electronic Information Industry\",\n[11][0x74 - 1] = \"Shenzhen Boyuan Computer Technology\",\n[11][0x75 - 1] = \"Beijing Welldisk Electronics Co Ltd\",\n[11][0x76 - 1] = \"Suzhou EP Semicon Co Ltd\",\n[11][0x77 - 1] = \"Zhejiang Dahua Memory Technology\",\n[11][0x78 - 1] = \"Virtu Financial\",\n[11][0x79 - 1] = \"Datotek International Co Ltd\",\n[11][0x7a - 1] = \"Telecom and Microelectronics Industries\",\n[11][0x7b - 1] = \"Echow Technology Ltd\",\n[11][0x7c - 1] = \"APEX-INFO\",\n[11][0x7d - 1] = \"Yingpark\",\n[11][0x7e - 1] = \"Shenzhen Bigway Tech Co Ltd\",\n[12][0x01 - 1] = \"Beijing Haawking Technology Co Ltd\",\n[12][0x02 - 1] = \"Open HW Group\",\n[12][0x03 - 1] = \"JHICC\",\n[12][0x04 - 1] = \"ncoder AG\",\n[12][0x05 - 1] = \"ThinkTech Information Technology Co\",\n[12][0x06 - 1] = \"Shenzhen Chixingzhe Technology Co Ltd\",\n[12][0x07 - 1] = \"Biao Ram Technology Co Ltd\",\n[12][0x08 - 1] = \"Shenzhen Kaizhuoyue Electronics Co Ltd\",\n[12][0x09 - 1] = \"Shenzhen YC Storage Technology Co Ltd\",\n[12][0x0a - 1] = \"Shenzhen Chixingzhe Technology Co\",\n[12][0x0b - 1] = \"Wink Semiconductor (Shenzhen) Co Ltd\",\n[12][0x0c - 1] = \"AISTOR\",\n[12][0x0d - 1] = \"Palma Ceia SemiDesign\",\n[12][0x0e - 1] = \"EM Microelectronic-Marin SA\",\n[12][0x0f - 1] = \"Shenzhen Monarch Memory Technology\",\n[12][0x10 - 1] = \"Reliance Memory Inc\",\n[12][0x11 - 1] = \"Jesis\",\n[12][0x12 - 1] = \"Espressif Systems (Shanghai) Co Ltd\",\n[12][0x13 - 1] = \"Shenzhen Sati Smart Technology Co Ltd\",\n[12][0x14 - 1] = \"NeuMem Co Ltd\",\n[12][0x15 - 1] = \"Lifelong\",\n[12][0x16 - 1] = \"Beijing Oitech Technology Co Ltd\",\n[12][0x17 - 1] = \"Groupe LDLC\",\n[12][0x18 - 1] = \"Semidynamics Technology Services SLU\",\n[12][0x19 - 1] = \"swordbill\",\n[12][0x1a - 1] = \"YIREN\",\n[12][0x1b - 1] = \"Shenzhen Yinxiang Technology Co Ltd\",\n[12][0x1c - 1] = \"PoweV Electronic Technology Co Ltd\",\n[12][0x1d - 1] = \"LEORICE\",\n[12][0x1e - 1] = \"Waymo LLC\",\n[12][0x1f - 1] = \"Ventana Micro Systems\",\n[12][0x20 - 1] = \"Hefei Guangxin Microelectronics Co Ltd\",\n[12][0x21 - 1] = \"Shenzhen Sooner Industrial Co Ltd\",\n[12][0x22 - 1] = \"Horizon Robotics\",\n[12][0x23 - 1] = \"Tangem AG\",\n[12][0x24 - 1] = \"FuturePath Technology (Shenzhen) Co\",\n[12][0x25 - 1] = \"RC Module\",\n[12][0x26 - 1] = \"Timetec International Inc\",\n[12][0x27 - 1] = \"ICMAX Technologies Co Limited\",\n[12][0x28 - 1] = \"Lynxi Technologies Ltd Co\",\n[12][0x29 - 1] = \"Guangzhou Taisupanke Computer Equipment\",\n[12][0x2a - 1] = \"Ceremorphic Inc\",\n[12][0x2b - 1] = \"Biwin Storage Technology Co Ltd\",\n[12][0x2c - 1] = \"Beijing ESWIN Computing Technology\",\n[12][0x2d - 1] = \"WeForce Co Ltd\",\n[12][0x2e - 1] = \"Shenzhen Fanxiang Information Technology\",\n[12][0x2f - 1] = \"Unisoc\",\n[12][0x30 - 1] = \"YingChu\",\n[12][0x31 - 1] = \"GUANCUN\",\n[12][0x32 - 1] = \"IPASON\",\n[12][0x33 - 1] = \"Ayar Labs\",\n[12][0x34 - 1] = \"Amazon\",\n[12][0x35 - 1] = \"Shenzhen Xinxinshun Technology Co\",\n[12][0x36 - 1] = \"Galois Inc\",\n[12][0x37 - 1] = \"Ubilite Inc\",\n[12][0x38 - 1] = \"Shenzhen Quanxing Technology Co Ltd\",\n[12][0x39 - 1] = \"Group RZX Technology LTDA\",\n[12][0x3a - 1] = \"Yottac Technology (XI'AN) Cooperation\",\n[12][0x3b - 1] = \"Shenzhen RuiRen Technology Co Ltd\",\n[12][0x3c - 1] = \"Group Star Technology Co Ltd\",\n[12][0x3d - 1] = \"RWA (Hong Kong) Ltd\",\n[12][0x3e - 1] = \"Genesys Logic Inc\",\n[12][0x3f - 1] = \"T3 Robotics Inc.\",\n[12][0x40 - 1] = \"Biostar Microtech International Corp\",\n[12][0x41 - 1] = \"Shenzhen SXmicro Technology Co Ltd\",\n[12][0x42 - 1] = \"Shanghai Yili Computer Technology Co\",\n[12][0x43 - 1] = \"Zhixin Semicoducotor Co Ltd\",\n[12][0x44 - 1] = \"uFound\",\n[12][0x45 - 1] = \"Aigo Data Security Technology Co. Ltd\",\n[12][0x46 - 1] = \".GXore Technologies\",\n[12][0x47 - 1] = \"Shenzhen Pradeon Intelligent Technology\",\n[12][0x48 - 1] = \"Power LSI\",\n[12][0x49 - 1] = \"PRIME\",\n[12][0x4a - 1] = \"Shenzhen Juyang Innovative Technology\",\n[12][0x4b - 1] = \"CERVO\",\n[12][0x4c - 1] = \"SiEngine Technology Co., Ltd.\",\n[12][0x4d - 1] = \"Beijing Unigroup Tsingteng MicroSystem\",\n[12][0x4e - 1] = \"Brainsao GmbH\",\n[12][0x4f - 1] = \"Credo Technology Group Ltd\",\n[12][0x50 - 1] = \"Shanghai Biren Technology Co Ltd\",\n[12][0x51 - 1] = \"Nucleu Semiconductor\",\n[12][0x52 - 1] = \"Shenzhen Guangshuo Electronics Co Ltd\",\n[12][0x53 - 1] = \"ZhongsihangTechnology Co Ltd\",\n[12][0x54 - 1] = \"Suzhou Mainshine Electronic Co Ltd.\",\n[12][0x55 - 1] = \"Guangzhou Riss Electronic Technology\",\n[12][0x56 - 1] = \"Shenzhen Cloud Security Storage Co\",\n[12][0x57 - 1] = \"ROG\",\n[12][0x58 - 1] = \"Perceive\",\n[12][0x59 - 1] = \"e-peas\",\n[12][0x5a - 1] = \"Fraunhofer IPMS\",\n[12][0x5b - 1] = \"Shenzhen Daxinlang Electronic Tech Co\",\n[12][0x5c - 1] = \"Abacus Peripherals Private Limited\",\n[12][0x5d - 1] = \"OLOy Technology\",\n[12][0x5e - 1] = \"Wuhan P&S Semiconductor Co Ltd\",\n[12][0x5f - 1] = \"Sitrus Technology\",\n[12][0x60 - 1] = \"AnHui Conner Storage Co Ltd\",\n[12][0x61 - 1] = \"Rochester Electronics\",\n[12][0x62 - 1] = \"Wuxi Petabyte Technologies Co Ltd\",\n[12][0x63 - 1] = \"Star Memory\",\n[12][0x64 - 1] = \"Agile Memory Technology Co Ltd\",\n[12][0x65 - 1] = \"MEJEC\",\n[12][0x66 - 1] = \"Rockchip Electronics Co Ltd\",\n[12][0x67 - 1] = \"Dongguan Guanma e-commerce Co Ltd\",\n[12][0x68 - 1] = \"Rayson Hi-Tech (SZ) Limited\",\n[12][0x69 - 1] = \"MINRES Technologies GmbH\",\n[12][0x6a - 1] = \"Himax Technologies Inc\",\n[12][0x6b - 1] = \"Shenzhen Cwinner Technology Co Ltd\",\n[12][0x6c - 1] = \"Tecmiyo\",\n[12][0x6d - 1] = \"Shenzhen Suhuicun Technology Co Ltd\",\n[12][0x6e - 1] = \"Vickter Electronics Co. Ltd.\",\n[12][0x6f - 1] = \"lowRISC\",\n[12][0x70 - 1] = \"EXEGate FZE\",\n[12][0x71 - 1] = \"Shenzhen 9 Chapter Technologies Co\",\n[12][0x72 - 1] = \"Addlink\",\n[12][0x73 - 1] = \"Starsway\",\n[12][0x74 - 1] = \"Pensando Systems Inc.\",\n[12][0x75 - 1] = \"AirDisk\",\n[12][0x76 - 1] = \"Shenzhen Speedmobile Technology Co\",\n[12][0x77 - 1] = \"PEZY Computing\",\n[12][0x78 - 1] = \"Extreme Engineering Solutions Inc\",\n[12][0x79 - 1] = \"Shangxin Technology Co Ltd\",\n[12][0x7a - 1] = \"Shanghai Zhaoxin Semiconductor Co\",\n[12][0x7b - 1] = \"Xsight Labs Ltd\",\n[12][0x7c - 1] = \"Hangzhou Hikstorage Technology Co\",\n[12][0x7d - 1] = \"Dell Technologies\",\n[12][0x7e - 1] = \"Guangdong StarFive Technology Co\",\n[13][0x01 - 1] = \"TECOTON\",\n[13][0x02 - 1] = \"Abko Co Ltd\",\n[13][0x03 - 1] = \"Shenzhen Feisrike Technology Co Ltd\",\n[13][0x04 - 1] = \"Shenzhen Sunhome Electronics Co Ltd\",\n[13][0x05 - 1] = \"Global Mixed-mode Technology Inc\",\n[13][0x06 - 1] = \"Shenzhen Weien Electronics Co. Ltd.\",\n[13][0x07 - 1] = \"Shenzhen Cooyes Technology Co Ltd\",\n[13][0x08 - 1] = \"Keymos Electronics Co., Limited\",\n[13][0x09 - 1] = \"E-Rockic Technology Company Limited\",\n[13][0x0a - 1] = \"Aerospace Science Memory Shenzhen\",\n[13][0x0b - 1] = \"Shenzhen Quanji Technology Co Ltd\",\n[13][0x0c - 1] = \"Dukosi\",\n[13][0x0d - 1] = \"Maxell Corporation of America\",\n[13][0x0e - 1] = \"Shenshen Xinxintao Electronics Co Ltd\",\n[13][0x0f - 1] = \"Zhuhai Sanxia Semiconductor Co Ltd\",\n[13][0x10 - 1] = \"Groq Inc\",\n[13][0x11 - 1] = \"AstraTek\",\n[13][0x12 - 1] = \"Shenzhen Xinyuze Technology Co Ltd\",\n[13][0x13 - 1] = \"All Bit Semiconductor\",\n[13][0x14 - 1] = \"ACFlow\",\n[13][0x15 - 1] = \"Shenzhen Sipeed Technology Co Ltd\",\n[13][0x16 - 1] = \"Linzhi Hong Kong Co Limited\",\n[13][0x17 - 1] = \"Supreme Wise Limited\",\n[13][0x18 - 1] = \"Blue Cheetah Analog Design Inc\",\n[13][0x19 - 1] = \"Hefei Laiku Technology Co Ltd\",\n[13][0x1a - 1] = \"Zord\",\n[13][0x1b - 1] = \"SBO Hearing A/S\",\n[13][0x1c - 1] = \"Regent Sharp International Limited\",\n[13][0x1d - 1] = \"Permanent Potential Limited\",\n[13][0x1e - 1] = \"Creative World International Limited\",\n[13][0x1f - 1] = \"Base Creation International Limited\",\n[13][0x20 - 1] = \"Shenzhen Zhixin Chuanglian Technology\",\n[13][0x21 - 1] = \"Protected Logic Corporation\",\n[13][0x22 - 1] = \"Sabrent\",\n[13][0x23 - 1] = \"Union Memory\",\n[13][0x24 - 1] = \"NEUCHIPS Corporation\",\n[13][0x25 - 1] = \"Ingenic Semiconductor Co Ltd\",\n[13][0x26 - 1] = \"SiPearl\",\n[13][0x27 - 1] = \"Shenzhen Actseno Information Technology\",\n[13][0x28 - 1] = \"RIVAI Technologies (Shenzhen) Co Ltd\",\n[13][0x29 - 1] = \"Shenzhen Sunny Technology Co Ltd\",\n[13][0x2a - 1] = \"Cott Electronics Ltd\",\n[13][0x2b - 1] = \"Shanghai Synsense Technologies Co Ltd\",\n[13][0x2c - 1] = \"Shenzhen Jintang Fuming Optoelectronics\",\n[13][0x2d - 1] = \"CloudBEAR LLC\",\n[13][0x2e - 1] = \"Emzior, LLC\",\n[13][0x2f - 1] = \"Ehiway Microelectronic Science Tech Co\",\n[13][0x30 - 1] = \"UNIM Innovation Technology (Wu XI)\",\n[13][0x31 - 1] = \"GDRAMARS\",\n[13][0x32 - 1] = \"Meminsights Technology\",\n[13][0x33 - 1] = \"Zhuzhou Hongda Electronics Corp Ltd\",\n[13][0x34 - 1] = \"Luminous Computing Inc\",\n[13][0x35 - 1] = \"PROXMEM\",\n[13][0x36 - 1] = \"Draper Labs\",\n[13][0x37 - 1] = \"ORICO Technologies Co. Ltd.\",\n[13][0x38 - 1] = \"Space Exploration Technologies Corp\",\n[13][0x39 - 1] = \"AONDEVICES Inc\",\n[13][0x3a - 1] = \"Shenzhen Netforward Micro Electronic\",\n[13][0x3b - 1] = \"Syntacore Ltd\",\n[13][0x3c - 1] = \"Shenzhen Secmem Microelectronics Co\",\n[13][0x3d - 1] = \"ONiO As\",\n[13][0x3e - 1] = \"Shenzhen Peladn Technology Co Ltd\",\n[13][0x3f - 1] = \"O-Cubes Shanghai Microelectronics\",\n[13][0x40 - 1] = \"ASTC\",\n[13][0x41 - 1] = \"UMIS\",\n[13][0x42 - 1] = \"Paradromics\",\n[13][0x43 - 1] = \"Sinh Micro Co Ltd\",\n[13][0x44 - 1] = \"Metorage Semiconductor Technology Co\",\n[13][0x45 - 1] = \"Aeva Inc\",\n[13][0x46 - 1] = \"HongKong Hyunion Electronics Co Ltd\",\n[13][0x47 - 1] = \"China Flash Co Ltd\",\n[13][0x48 - 1] = \"Sunplus Technology Co Ltd\",\n[13][0x49 - 1] = \"Idaho Scientific\",\n[13][0x4a - 1] = \"Suzhou SF Micro Electronics Co Ltd\",\n[13][0x4b - 1] = \"IMEX Cap AG\",\n[13][0x4c - 1] = \"Fitipower Integrated Technology Co Ltd\",\n[13][0x4d - 1] = \"ShenzhenWooacme Technology Co Ltd\",\n[13][0x4e - 1] = \"KeepData Original Chips\",\n[13][0x4f - 1] = \"Rivos Inc\",\n[13][0x50 - 1] = \"Big Innovation Company Limited\",\n[13][0x51 - 1] = \"Wuhan YuXin Semiconductor Co Ltd\",\n[13][0x52 - 1] = \"United Memory Technology (Jiangsu)\",\n[13][0x53 - 1] = \"PQShield Ltd\",\n[13][0x54 - 1] = \"ArchiTek Corporation\",\n[13][0x55 - 1] = \"ShenZhen AZW Technology Co Ltd\",\n[13][0x56 - 1] = \"Hengchi Zhixin (Dongguan) Technology\",\n[13][0x57 - 1] = \"Eggtronic Engineering Spa\",\n[13][0x58 - 1] = \"Fusontai Technology\",\n[13][0x59 - 1] = \"PULP Platform\",\n[13][0x5a - 1] = \"Koitek Electronic Technology (Shenzhen) Co\",\n[13][0x5b - 1] = \"Shenzhen Jiteng Network Technology Co\",\n[13][0x5c - 1] = \"Aviva Links Inc\",\n[13][0x5d - 1] = \"Trilinear Technologies Inc\",\n[13][0x5e - 1] = \"Shenzhen Developer Microelectronics Co\",\n[13][0x5f - 1] = \"Guangdong OPPO Mobile Telecommunication\",\n[13][0x60 - 1] = \"Akeana\",\n[13][0x61 - 1] = \"Lyczar\",\n[13][0x62 - 1] = \"Shenzhen Qiji Technology Co Ltd\",\n[13][0x63 - 1] = \"Shenzhen Shangzhaoyuan Technology\",\n[13][0x64 - 1] = \"Han Stor\",\n[13][0x65 - 1] = \"China Micro Semicon Co., Ltd.\",\n[13][0x66 - 1] = \"Shenzhen Zhuqin Technology Co Ltd\",\n[13][0x67 - 1] = \"Shanghai Ningyuan Electronic Technology\",\n[13][0x68 - 1] = \"Auradine\",\n[13][0x69 - 1] = \"Suzhou Yishuo Electronics Co Ltd\",\n[13][0x6a - 1] = \"Faurecia Clarion Electronics\",\n[13][0x6b - 1] = \"SiMa Technologies\",\n[13][0x6c - 1] = \"CFD Sales Inc\",\n[13][0x6d - 1] = \"Suzhou Comay Information Co Ltd\",\n[13][0x6e - 1] = \"Yentek\",\n[13][0x6f - 1] = \"Qorvo Inc\",\n[13][0x70 - 1] = \"Shenzhen Youzhi Computer Technology\",\n[13][0x71 - 1] = \"Sychw Technology (Shenzhen) Co Ltd\",\n[13][0x72 - 1] = \"MK Founder Technology Co Ltd\",\n[13][0x73 - 1] = \"Siliconwaves Technologies Co Ltd\",\n[13][0x74 - 1] = \"Hongkong Hyunion Electronics Co Ltd\",\n[13][0x75 - 1] = \"Shenzhen Xinxinzhitao Electronics Business\",\n[13][0x76 - 1] = \"Shenzhen HenQi Electronic Commerce Co\",\n[13][0x77 - 1] = \"Shenzhen Jingyi Technology Co Ltd\",\n[13][0x78 - 1] = \"Xiaohua Semiconductor Co. Ltd.\",\n[13][0x79 - 1] = \"Shenzhen Dalu Semiconductor Technology\",\n[13][0x7a - 1] = \"Shenzhen Ninespeed Electronics Co Ltd\",\n[13][0x7b - 1] = \"ICYC Semiconductor Co Ltd\",\n[13][0x7c - 1] = \"Shenzhen Jaguar Microsystems Co Ltd\",\n[13][0x7d - 1] = \"Beijing EC-Founder Co Ltd\",\n[13][0x7e - 1] = \"Shenzhen Taike Industrial Automation Co\",\n[14][0x01 - 1] = \"Kalray SA\",\n[14][0x02 - 1] = \"Shanghai Iluvatar CoreX Semiconductor Co\",\n[14][0x03 - 1] = \"Fungible Inc\",\n[14][0x04 - 1] = \"Song Industria E Comercio de Eletronicos\",\n[14][0x05 - 1] = \"DreamBig Semiconductor Inc\",\n[14][0x06 - 1] = \"ChampTek Electronics Corp\",\n[14][0x07 - 1] = \"Fusontai Technology\",\n[14][0x08 - 1] = \"Endress Hauser AG\",\n[14][0x09 - 1] = \"altec ComputerSysteme GmbH\",\n[14][0x0a - 1] = \"UltraRISC Technology (Shanghai) Co Ltd\",\n[14][0x0b - 1] = \"Shenzhen Jing Da Kang Technology Co Ltd\",\n[14][0x0c - 1] = \"Hangzhou Hongjun Microelectronics Co Ltd\",\n[14][0x0d - 1] = \"Pliops Ltd\",\n[14][0x0e - 1] = \"Cix Technology (Shanghai) Co Ltd\",\n[14][0x0f - 1] = \"TeraDevices Inc\",\n[14][0x10 - 1] = \"SpacemiT (Hangzhou)Technology Co Ltd\",\n[14][0x11 - 1] = \"InnoPhase loT Inc\",\n[14][0x12 - 1] = \"InnoPhase loT Inc\",\n[14][0x13 - 1] = \"Yunhight Microelectronics\",\n[14][0x14 - 1] = \"Samnix\",\n[14][0x15 - 1] = \"HKC Storage Co Ltd\",\n[14][0x16 - 1] = \"Chiplego Technology (Shanghai) Co Ltd\",\n[14][0x17 - 1] = \"StoreSkill\",\n[14][0x18 - 1] = \"Shenzhen Astou Technology Company\",\n[14][0x19 - 1] = \"Guangdong LeafFive Technology Limited\",\n[14][0x1a - 1] = \"Jin JuQuan\",\n[14][0x1b - 1] = \"Huaxuan Technology (Shenzhen) Co Ltd\",\n[14][0x1c - 1] = \"Gigastone Corporation\",\n[14][0x1d - 1] = \"Kinsotin\",\n[14][0x1e - 1] = \"PengYing\",\n[14][0x1f - 1] = \"Shenzhen Xunhi Technology Co Ltd\",\n[14][0x20 - 1] = \"FOXX Storage Inc\",\n[14][0x21 - 1] = \"Shanghai Belling Corporation Ltd\",\n[14][0x22 - 1] = \"Glenfy Tech Co Ltd\",\n[14][0x23 - 1] = \"Sahasra Semiconductors Pvt Ltd\",\n[14][0x24 - 1] = \"Chongqing SeekWave Technology Co Ltd\",\n[14][0x25 - 1] = \"Shenzhen Zhixing Intelligent Manufacturing\",\n[14][0x26 - 1] = \"Ethernovia\",\n[14][0x27 - 1] = \"Shenzhen Xinrongda Technology Co Ltd\",\n[14][0x28 - 1] = \"Hangzhou Clounix Technology Limited\",\n[14][0x29 - 1] = \"JGINYUE\",\n[14][0x2a - 1] = \"Shenzhen Xinwei Semiconductor Co Ltd\",\n[14][0x2b - 1] = \"COLORFIRE Technology Co Ltd\",\n[14][0x2c - 1] = \"B LKE\",\n[14][0x2d - 1] = \"ZHUDIAN\",\n[14][0x2e - 1] = \"REECHO\",\n[14][0x2f - 1] = \"Enphase Energy Inc\",\n[14][0x30 - 1] = \"Shenzhen Yingrui Storage Technology Co Ltd\",\n[14][0x31 - 1] = \"Shenzhen Sinomos Semiconductor Technology\",\n[14][0x32 - 1] = \"O2micro International Limited\",\n[14][0x33 - 1] = \"Axelera AI BV\",\n[14][0x34 - 1] = \"Silicon Legend Technology (Suzhou) Co Ltd\",\n[14][0x35 - 1] = \"Suzhou Novosense Microelectronics Co Ltd\",\n[14][0x36 - 1] = \"Pirateman\",\n[14][0x37 - 1] = \"Yangtze MasonSemi\",\n[14][0x38 - 1] = \"Shanghai Yunsilicon Technology Co Ltd\",\n[14][0x39 - 1] = \"Rayson\",\n[14][0x3a - 1] = \"Alphawave IP\",\n[14][0x3b - 1] = \"Shenzhen Visions Chip Electronic Technology\",\n[14][0x3c - 1] = \"KYO Group\",\n[14][0x3d - 1] = \"Shenzhen Aboison Technology Co Ltd\",\n[14][0x3e - 1] = \"Shenzhen JingSheng Semiconducto Co Ltd\",\n[14][0x3f - 1] = \"Shenzhen Dingsheng Technology Co Ltd\",\n[14][0x40 - 1] = \"EVAS Intelligence Co Ltd\",\n[14][0x41 - 1] = \"Kaibright Electronic Technologies\",\n/* EOF */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/jim-nvp.c",
    "content": "// SPDX-License-Identifier: BSD-2-Clause-Views\n\n/* Jim - A small embeddable Tcl interpreter\n *\n * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\n * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\n * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>\n * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\n * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\n * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\n * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\n * Copyright 2008 Steve Bennett <steveb@workware.net.au>\n * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>\n * Copyright 2009 Zachary T Welch zw@superlucidity.net\n * Copyright 2009 David Brownell\n * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jim-nvp.h\"\n#include <string.h>\n\nint jim_get_nvp(Jim_Interp *interp,\n\tJim_Obj *objptr, const struct jim_nvp *nvp_table, const struct jim_nvp **result)\n{\n\tstruct jim_nvp *n;\n\tint e;\n\n\te = jim_nvp_name2value_obj(interp, nvp_table, objptr, &n);\n\tif (e == JIM_ERR)\n\t\treturn e;\n\n\t/* Success? found? */\n\tif (n->name) {\n\t\t/* remove const */\n\t\t*result = (struct jim_nvp *)n;\n\t\treturn JIM_OK;\n\t} else\n\t\treturn JIM_ERR;\n}\n\nstruct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *p, const char *name)\n{\n\twhile (p->name) {\n\t\tif (strcmp(name, p->name) == 0)\n\t\t\tbreak;\n\t\tp++;\n\t}\n\treturn (struct jim_nvp *)p;\n}\n\nstruct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *p, const char *name)\n{\n\twhile (p->name) {\n\t\tif (strcasecmp(name, p->name) == 0)\n\t\t\tbreak;\n\t\tp++;\n\t}\n\treturn (struct jim_nvp *)p;\n}\n\nint jim_nvp_name2value_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)\n{\n\treturn jim_nvp_name2value(interp, p, Jim_String(o), result);\n}\n\nint jim_nvp_name2value(Jim_Interp *interp, const struct jim_nvp *_p, const char *name, struct jim_nvp **result)\n{\n\tconst struct jim_nvp *p;\n\n\tp = jim_nvp_name2value_simple(_p, name);\n\n\t/* result */\n\tif (result)\n\t\t*result = (struct jim_nvp *)p;\n\n\t/* found? */\n\tif (p->name)\n\t\treturn JIM_OK;\n\telse\n\t\treturn JIM_ERR;\n}\n\nint jim_nvp_name2value_obj_nocase(Jim_Interp *interp,\n\tconst struct jim_nvp *p,\n\tJim_Obj *o,\n\tstruct jim_nvp **puthere)\n{\n\treturn jim_nvp_name2value_nocase(interp, p, Jim_String(o), puthere);\n}\n\nint jim_nvp_name2value_nocase(Jim_Interp *interp, const struct jim_nvp *_p, const char *name,\n\tstruct jim_nvp **puthere)\n{\n\tconst struct jim_nvp *p;\n\n\tp = jim_nvp_name2value_nocase_simple(_p, name);\n\n\tif (puthere)\n\t\t*puthere = (struct jim_nvp *)p;\n\t\t\t\t\t\t/* found */\n\tif (p->name)\n\t\treturn JIM_OK;\n\telse\n\t\treturn JIM_ERR;\n}\n\nint jim_nvp_value2name_obj(Jim_Interp *interp, const struct jim_nvp *p, Jim_Obj *o, struct jim_nvp **result)\n{\n\tint e;\n\tjim_wide w;\n\n\te = Jim_GetWide(interp, o, &w);\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\treturn jim_nvp_value2name(interp, p, w, result);\n}\n\nstruct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *p, int value)\n{\n\twhile (p->name) {\n\t\tif (value == p->value)\n\t\t\tbreak;\n\t\tp++;\n\t}\n\treturn (struct jim_nvp *)p;\n}\n\nint jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *_p, int value, struct jim_nvp **result)\n{\n\tconst struct jim_nvp *p;\n\n\tp = jim_nvp_value2name_simple(_p, value);\n\n\tif (result)\n\t\t*result = (struct jim_nvp *)p;\n\n\tif (p->name)\n\t\treturn JIM_OK;\n\telse\n\t\treturn JIM_ERR;\n}\n\nint jim_getopt_setup(struct jim_getopt_info *p, Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tmemset(p, 0, sizeof(*p));\n\tp->interp = interp;\n\tp->argc = argc;\n\tp->argv = argv;\n\n\treturn JIM_OK;\n}\n\nvoid jim_getopt_debug(struct jim_getopt_info *p)\n{\n\tint x;\n\n\tfprintf(stderr, \"---args---\\n\");\n\tfor (x = 0; x < p->argc; x++)\n\t\tfprintf(stderr, \"%2d) %s\\n\", x, Jim_String(p->argv[x]));\n\tfprintf(stderr, \"-------\\n\");\n}\n\nint jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere)\n{\n\tJim_Obj *o;\n\n\to = NULL;\t\t/* failure */\n\tif (goi->argc) {\n\t\t/* success */\n\t\to = goi->argv[0];\n\t\tgoi->argc -= 1;\n\t\tgoi->argv += 1;\n\t}\n\tif (puthere)\n\t\t*puthere = o;\n\tif (o)\n\t\treturn JIM_OK;\n\telse\n\t\treturn JIM_ERR;\n}\n\nint jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len)\n{\n\tint r;\n\tJim_Obj *o;\n\tconst char *cp;\n\n\tr = jim_getopt_obj(goi, &o);\n\tif (r == JIM_OK) {\n\t\tcp = Jim_GetString(o, len);\n\t\tif (puthere) {\n\t\t\t*puthere = cp;\n\t\t}\n\t}\n\treturn r;\n}\n\nint jim_getopt_double(struct jim_getopt_info *goi, double *puthere)\n{\n\tint r;\n\tJim_Obj *o;\n\tdouble _safe;\n\n\tif (!puthere)\n\t\tputhere = &_safe;\n\n\tr = jim_getopt_obj(goi, &o);\n\tif (r == JIM_OK) {\n\t\tr = Jim_GetDouble(goi->interp, o, puthere);\n\t\tif (r != JIM_OK)\n\t\t\tJim_SetResultFormatted(goi->interp, \"not a number: %#s\", o);\n\t}\n\treturn r;\n}\n\nint jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere)\n{\n\tint r;\n\tJim_Obj *o;\n\tjim_wide _safe;\n\n\tif (!puthere)\n\t\tputhere = &_safe;\n\n\tr = jim_getopt_obj(goi, &o);\n\tif (r == JIM_OK)\n\t\tr = Jim_GetWide(goi->interp, o, puthere);\n\treturn r;\n}\n\nint jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *nvp, struct jim_nvp **puthere)\n{\n\tstruct jim_nvp *_safe;\n\tJim_Obj *o;\n\tint e;\n\n\tif (!puthere)\n\t\tputhere = &_safe;\n\n\te = jim_getopt_obj(goi, &o);\n\tif (e == JIM_OK)\n\t\te = jim_nvp_name2value_obj(goi->interp, nvp, o, puthere);\n\n\treturn e;\n}\n\nvoid jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *nvptable, int hadprefix)\n{\n\tif (hadprefix)\n\t\tjim_set_result_nvp_unknown(goi->interp, goi->argv[-2], goi->argv[-1], nvptable);\n\telse\n\t\tjim_set_result_nvp_unknown(goi->interp, NULL, goi->argv[-1], nvptable);\n}\n\nint jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere)\n{\n\tint _safe;\n\tJim_Obj *o;\n\tint e;\n\n\tif (!puthere)\n\t\tputhere = &_safe;\n\te = jim_getopt_obj(goi, &o);\n\tif (e == JIM_OK)\n\t\te = Jim_GetEnum(goi->interp, o, lookup, puthere, \"option\", JIM_ERRMSG);\n\treturn e;\n}\n\nvoid jim_set_result_nvp_unknown(Jim_Interp *interp,\n\tJim_Obj *param_name, Jim_Obj *param_value, const struct jim_nvp *nvp)\n{\n\tif (param_name)\n\t\tJim_SetResultFormatted(interp,\n\t\t\t\"%#s: Unknown: %#s, try one of: \",\n\t\t\tparam_name,\n\t\t\tparam_value);\n\telse\n\t\tJim_SetResultFormatted(interp, \"Unknown param: %#s, try one of: \", param_value);\n\twhile (nvp->name) {\n\t\tconst char *a;\n\t\tconst char *b;\n\n\t\tif ((nvp + 1)->name) {\n\t\t\ta = nvp->name;\n\t\t\tb = \", \";\n\t\t} else {\n\t\t\ta = \"or \";\n\t\t\tb = nvp->name;\n\t\t}\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp), a, b, NULL);\n\t\tnvp++;\n\t}\n}\n\nconst char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstatic Jim_Obj *debug_string_obj;\n\n\tint x;\n\n\tif (debug_string_obj)\n\t\tJim_FreeObj(interp, debug_string_obj);\n\n\tdebug_string_obj = Jim_NewEmptyStringObj(interp);\n\tfor (x = 0; x < argc; x++)\n\t\tJim_AppendStrings(interp, debug_string_obj, Jim_String(argv[x]), \" \", NULL);\n\n\treturn Jim_String(debug_string_obj);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/jim-nvp.h",
    "content": "/* SPDX-License-Identifier: BSD-2-Clause-Views */\n\n/* Jim - A small embeddable Tcl interpreter\n *\n * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\n * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\n * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>\n * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\n * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\n * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\n * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\n * Copyright 2008 Steve Bennett <steveb@workware.net.au>\n * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>\n * Copyright 2009 Zachary T Welch zw@superlucidity.net\n * Copyright 2009 David Brownell\n * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.\n */\n\n#ifndef OPENOCD_HELPER_JIM_NVP_H\n#define OPENOCD_HELPER_JIM_NVP_H\n\n#include <jim.h>\n#include <stdio.h>\n/** Name Value Pairs, aka: NVP\n *   -  Given a string - return the associated int.\n *   -  Given a number - return the associated string.\n *   .\n *\n * Very useful when the number is not a simple index into an array of\n * known string, or there may be multiple strings (aliases) that mean then same\n * thing.\n *\n * An NVP Table is terminated with \".name = NULL\".\n *\n * During the 'name2value' operation, if no matching string is found\n * the pointer to the terminal element (with p->name == NULL) is returned.\n *\n * Example:\n * \\code\n *      const struct jim_nvp yn[] = {\n *          { \"yes\", 1 },\n *          { \"no\" , 0 },\n *          { \"yep\", 1 },\n *          { \"nope\", 0 },\n *          { NULL, -1 },\n *      };\n *\n *  struct jim_nvp *result\n *  e = jim_nvp_name2value(interp, yn, \"y\", &result);\n *         returns &yn[0];\n *  e = jim_nvp_name2value(interp, yn, \"n\", &result);\n *         returns &yn[1];\n *  e = jim_nvp_name2value(interp, yn, \"Blah\", &result);\n *         returns &yn[4];\n * \\endcode\n *\n * During the number2name operation, the first matching value is returned.\n */\nstruct jim_nvp {\n\tconst char *name;\n\tint value;\n};\n\nint jim_get_nvp(Jim_Interp *interp,\n\t\tJim_Obj *objptr,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tconst struct jim_nvp **result);\n\n/* Name Value Pairs Operations */\nstruct jim_nvp *jim_nvp_name2value_simple(const struct jim_nvp *nvp_table, const char *name);\nstruct jim_nvp *jim_nvp_name2value_nocase_simple(const struct jim_nvp *nvp_table, const char *name);\nstruct jim_nvp *jim_nvp_value2name_simple(const struct jim_nvp *nvp_table, int v);\n\nint jim_nvp_name2value(Jim_Interp *interp,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tconst char *name,\n\t\tstruct jim_nvp **result);\nint jim_nvp_name2value_nocase(Jim_Interp *interp,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tconst char *name,\n\t\tstruct jim_nvp **result);\nint jim_nvp_value2name(Jim_Interp *interp, const struct jim_nvp *nvp_table, int value, struct jim_nvp **result);\n\nint jim_nvp_name2value_obj(Jim_Interp *interp,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tJim_Obj *name_obj,\n\t\tstruct jim_nvp **result);\nint jim_nvp_name2value_obj_nocase(Jim_Interp *interp,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tJim_Obj *name_obj,\n\t\tstruct jim_nvp **result);\nint jim_nvp_value2name_obj(Jim_Interp *interp,\n\t\tconst struct jim_nvp *nvp_table,\n\t\tJim_Obj *value_obj,\n\t\tstruct jim_nvp **result);\n\n/** prints a nice 'unknown' parameter error message to the 'result' */\nvoid jim_set_result_nvp_unknown(Jim_Interp *interp,\n\t\tJim_Obj *param_name,\n\t\tJim_Obj *param_value,\n\t\tconst struct jim_nvp *nvp_table);\n\n/** Debug: convert argc/argv into a printable string for printf() debug\n *\n * \\param interp - the interpreter\n * \\param argc   - arg count\n * \\param argv   - the objects\n *\n * \\returns string pointer holding the text.\n *\n * Note, next call to this function will free the old (last) string.\n *\n * For example might want do this:\n * \\code\n *     fp = fopen(\"some.file.log\", \"a\");\n *     fprintf(fp, \"PARAMS are: %s\\n\", Jim_DebugArgvString(interp, argc, argv));\n *     fclose(fp);\n * \\endcode\n */\nconst char *jim_debug_argv_string(Jim_Interp *interp, int argc, Jim_Obj *const *argv);\n\n\n/** A TCL -ish GetOpt like code.\n *\n * Some TCL objects have various \"configuration\" values.\n * For example - in Tcl/Tk the \"buttons\" have many options.\n *\n * Useful when dealing with command options.\n * that may come in any order...\n *\n * Does not support \"-foo = 123\" type options.\n * Only supports tcl type options, like \"-foo 123\"\n */\n\nstruct jim_getopt_info {\n\tJim_Interp *interp;\n\tint argc;\n\tJim_Obj *const *argv;\n\tint isconfigure;\t\t/* non-zero if configure */\n};\n\n/** GetOpt - how to.\n *\n * Example (short and incomplete):\n * \\code\n *   struct jim_getopt_info goi;\n *\n *   jim_getopt_setup(&goi, interp, argc, argv);\n *\n *   while (goi.argc) {\n *         e = jim_getopt_nvp(&goi, nvp_options, &n);\n *         if (e != JIM_OK) {\n *               jim_getopt_nvp_unknown(&goi, nvp_options, 0);\n *               return e;\n *         }\n *\n *         switch (n->value) {\n *         case ALIVE:\n *             printf(\"Option ALIVE specified\\n\");\n *             break;\n *         case FIRST:\n *             if (goi.argc < 1) {\n *                     .. not enough args error ..\n *             }\n *             jim_getopt_string(&goi, &cp, NULL);\n *             printf(\"FIRSTNAME: %s\\n\", cp);\n *         case AGE:\n *             jim_getopt_wide(&goi, &w);\n *             printf(\"AGE: %d\\n\", (int)(w));\n *             break;\n *         case POLITICS:\n *             e = jim_getopt_nvp(&goi, nvp_politics, &n);\n *             if (e != JIM_OK) {\n *                 jim_getopt_nvp_unknown(&goi, nvp_politics, 1);\n *                 return e;\n *             }\n *         }\n *  }\n *\n * \\endcode\n *\n */\n\n/** Setup GETOPT\n *\n * \\param goi    - get opt info to be initialized\n * \\param interp - jim interp\n * \\param argc   - argc count.\n * \\param argv   - argv (will be copied)\n *\n * \\code\n *     struct jim_getopt_info  goi;\n *\n *     Jim_GetOptSetup(&goi, interp, argc, argv);\n * \\endcode\n */\n\nint jim_getopt_setup(struct jim_getopt_info *goi,\n\t\tJim_Interp *interp,\n\t\tint argc,\n\t\tJim_Obj *const *argv);\n\n\n/** Debug - Dump parameters to stderr\n * \\param goi - current parameters\n */\nvoid jim_getopt_debug(struct jim_getopt_info *goi);\n\n/** Remove argv[0] from the list.\n *\n * \\param goi - get opt info\n * \\param puthere - where param is put\n *\n */\nint jim_getopt_obj(struct jim_getopt_info *goi, Jim_Obj **puthere);\n\n/** Remove argv[0] as string.\n *\n * \\param goi     - get opt info\n * \\param puthere - where param is put\n * \\param len     - return its length\n */\nint jim_getopt_string(struct jim_getopt_info *goi, const char **puthere, int *len);\n\n/** Remove argv[0] as double.\n *\n * \\param goi     - get opt info\n * \\param puthere - where param is put.\n *\n */\nint jim_getopt_double(struct jim_getopt_info *goi, double *puthere);\n\n/** Remove argv[0] as wide.\n *\n * \\param goi     - get opt info\n * \\param puthere - where param is put.\n */\nint jim_getopt_wide(struct jim_getopt_info *goi, jim_wide *puthere);\n\n/** Remove argv[0] as NVP.\n *\n * \\param goi     - get opt info\n * \\param lookup  - nvp lookup table\n * \\param puthere - where param is put.\n *\n */\nint jim_getopt_nvp(struct jim_getopt_info *goi, const struct jim_nvp *lookup, struct jim_nvp **puthere);\n\n/** Create an appropriate error message for an NVP.\n *\n * \\param goi - options info\n * \\param lookup - the NVP table that was used.\n * \\param hadprefix - 0 or 1 if the option had a prefix.\n *\n * This function will set the \"interp->result\" to a human readable\n * error message listing the available options.\n *\n * This function assumes the previous option argv[-1] is the unknown string.\n *\n * If this option had some prefix, then pass \"hadprefix = 1\" else pass \"hadprefix = 0\"\n *\n * Example:\n * \\code\n *\n *  while (goi.argc) {\n *     // Get the next option\n *     e = jim_getopt_nvp(&goi, cmd_options, &n);\n *     if (e != JIM_OK) {\n *          // option was not recognized\n *          // pass 'hadprefix = 0' because there is no prefix\n *          jim_getopt_nvp_unknown(&goi, cmd_options, 0);\n *          return e;\n *     }\n *\n *     switch (n->value) {\n *     case OPT_SEX:\n *          // handle:  --sex male | female | lots | needmore\n *          e = jim_getopt_nvp(&goi, &nvp_sex, &n);\n *          if (e != JIM_OK) {\n *               jim_getopt_nvp_unknown(&ogi, nvp_sex, 1);\n *               return e;\n *          }\n *          printf(\"Code: (%d) is %s\\n\", n->value, n->name);\n *          break;\n *     case ...:\n *          [snip]\n *     }\n * }\n * \\endcode\n *\n */\nvoid jim_getopt_nvp_unknown(struct jim_getopt_info *goi, const struct jim_nvp *lookup, int hadprefix);\n\n\n/** Remove argv[0] as Enum\n *\n * \\param goi     - get opt info\n * \\param lookup  - lookup table.\n * \\param puthere - where param is put.\n *\n */\nint jim_getopt_enum(struct jim_getopt_info *goi, const char *const *lookup, int *puthere);\n\n#endif /* OPENOCD_HELPER_JIM_NVP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/list.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-only */\n\n/*\n * The content of this file is mainly copied/inspired from Linux kernel\n * code in include/linux/list.h, include/linux/types.h\n * Last aligned with kernel v5.12:\n * - skip the functions hlist_unhashed_lockless() and __list_del_clearprev()\n *   that are relevant only in kernel;\n * - Remove non-standard GCC extension \"omitted conditional operand\" from\n *   list_prepare_entry;\n * - expand READ_ONCE, WRITE_ONCE, smp_load_acquire, smp_store_release;\n * - make comments compatible with doxygen.\n *\n * There is an example of using this file in contrib/list_example.c.\n */\n\n#ifndef OPENOCD_HELPER_LIST_H\n#define OPENOCD_HELPER_LIST_H\n\n/* begin local changes */\n#include <helper/types.h>\n\n#define LIST_POISON1 NULL\n#define LIST_POISON2 NULL\n\nstruct list_head {\n\tstruct list_head *next, *prev;\n};\n\n/* end local changes */\n\n/*\n * Circular doubly linked list implementation.\n *\n * Some of the internal functions (\"__xxx\") are useful when\n * manipulating whole lists rather than single entries, as\n * sometimes we already know the next/prev entries and we can\n * generate better code by using them directly rather than\n * using the generic single-entry routines.\n */\n\n#define LIST_HEAD_INIT(name) { &(name), &(name) }\n\n#define LIST_HEAD(name) \\\n\tstruct list_head name = LIST_HEAD_INIT(name)\n\n/**\n * INIT_LIST_HEAD - Initialize a list_head structure\n * @param list list_head structure to be initialized.\n *\n * Initializes the list_head to point to itself.  If it is a list header,\n * the result is an empty list.\n */\nstatic inline void INIT_LIST_HEAD(struct list_head *list)\n{\n\tlist->next = list;\n\tlist->prev = list;\n}\n\n#ifdef CONFIG_DEBUG_LIST\nextern bool __list_add_valid(struct list_head *new,\n\t\t\t      struct list_head *prev,\n\t\t\t      struct list_head *next);\nextern bool __list_del_entry_valid(struct list_head *entry);\n#else\nstatic inline bool __list_add_valid(struct list_head *new,\n\t\t\t\tstruct list_head *prev,\n\t\t\t\tstruct list_head *next)\n{\n\treturn true;\n}\nstatic inline bool __list_del_entry_valid(struct list_head *entry)\n{\n\treturn true;\n}\n#endif\n\n/*\n * Insert a new entry between two known consecutive entries.\n *\n * This is only for internal list manipulation where we know\n * the prev/next entries already!\n */\nstatic inline void __list_add(struct list_head *new,\n\t\t\t      struct list_head *prev,\n\t\t\t      struct list_head *next)\n{\n\tif (!__list_add_valid(new, prev, next))\n\t\treturn;\n\n\tnext->prev = new;\n\tnew->next = next;\n\tnew->prev = prev;\n\tprev->next = new;\n}\n\n/**\n * list_add - add a new entry\n * @param new new entry to be added\n * @param head list head to add it after\n *\n * Insert a new entry after the specified head.\n * This is good for implementing stacks.\n */\nstatic inline void list_add(struct list_head *new, struct list_head *head)\n{\n\t__list_add(new, head, head->next);\n}\n\n\n/**\n * list_add_tail - add a new entry\n * @param new new entry to be added\n * @param head list head to add it before\n *\n * Insert a new entry before the specified head.\n * This is useful for implementing queues.\n */\nstatic inline void list_add_tail(struct list_head *new, struct list_head *head)\n{\n\t__list_add(new, head->prev, head);\n}\n\n/*\n * Delete a list entry by making the prev/next entries\n * point to each other.\n *\n * This is only for internal list manipulation where we know\n * the prev/next entries already!\n */\nstatic inline void __list_del(struct list_head *prev, struct list_head *next)\n{\n\tnext->prev = prev;\n\tprev->next = next;\n}\n\n/* Ignore kernel __list_del_clearprev() */\n\nstatic inline void __list_del_entry(struct list_head *entry)\n{\n\tif (!__list_del_entry_valid(entry))\n\t\treturn;\n\n\t__list_del(entry->prev, entry->next);\n}\n\n/**\n * list_del - deletes entry from list.\n * @param entry the element to delete from the list.\n * Note: list_empty() on entry does not return true after this, the entry is\n * in an undefined state.\n */\nstatic inline void list_del(struct list_head *entry)\n{\n\t__list_del_entry(entry);\n\tentry->next = LIST_POISON1;\n\tentry->prev = LIST_POISON2;\n}\n\n/**\n * list_replace - replace old entry by new one\n * @param old the element to be replaced\n * @param new the new element to insert\n *\n * If @a old was empty, it will be overwritten.\n */\nstatic inline void list_replace(struct list_head *old,\n\t\t\t\tstruct list_head *new)\n{\n\tnew->next = old->next;\n\tnew->next->prev = new;\n\tnew->prev = old->prev;\n\tnew->prev->next = new;\n}\n\n/**\n * list_replace_init - replace old entry by new one and initialize the old one\n * @param old the element to be replaced\n * @param new the new element to insert\n *\n * If @a old was empty, it will be overwritten.\n */\nstatic inline void list_replace_init(struct list_head *old,\n\t\t\t\t     struct list_head *new)\n{\n\tlist_replace(old, new);\n\tINIT_LIST_HEAD(old);\n}\n\n/**\n * list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position\n * @param entry1 the location to place entry2\n * @param entry2 the location to place entry1\n */\nstatic inline void list_swap(struct list_head *entry1,\n\t\t\t     struct list_head *entry2)\n{\n\tstruct list_head *pos = entry2->prev;\n\n\tlist_del(entry2);\n\tlist_replace(entry1, entry2);\n\tif (pos == entry1)\n\t\tpos = entry2;\n\tlist_add(entry1, pos);\n}\n\n/**\n * list_del_init - deletes entry from list and reinitialize it.\n * @param entry the element to delete from the list.\n */\nstatic inline void list_del_init(struct list_head *entry)\n{\n\t__list_del_entry(entry);\n\tINIT_LIST_HEAD(entry);\n}\n\n/**\n * list_move - delete from one list and add as another's head\n * @param list the entry to move\n * @param head the head that will precede our entry\n */\nstatic inline void list_move(struct list_head *list, struct list_head *head)\n{\n\t__list_del_entry(list);\n\tlist_add(list, head);\n}\n\n/**\n * list_move_tail - delete from one list and add as another's tail\n * @param list the entry to move\n * @param head the head that will follow our entry\n */\nstatic inline void list_move_tail(struct list_head *list,\n\t\t\t\t  struct list_head *head)\n{\n\t__list_del_entry(list);\n\tlist_add_tail(list, head);\n}\n\n/**\n * list_bulk_move_tail - move a subsection of a list to its tail\n * @param head  the head that will follow our entry\n * @param first the first entry to move\n * @param last  the last entry to move, can be the same as first\n *\n * Move all entries between @a first and including @a last before @a head.\n * All three entries must belong to the same linked list.\n */\nstatic inline void list_bulk_move_tail(struct list_head *head,\n\t\t\t\t       struct list_head *first,\n\t\t\t\t       struct list_head *last)\n{\n\tfirst->prev->next = last->next;\n\tlast->next->prev = first->prev;\n\n\thead->prev->next = first;\n\tfirst->prev = head->prev;\n\n\tlast->next = head;\n\thead->prev = last;\n}\n\n/**\n * list_is_first -- tests whether @a list is the first entry in list @a head\n * @param list the entry to test\n * @param head the head of the list\n */\nstatic inline int list_is_first(const struct list_head *list, const struct list_head *head)\n{\n\treturn list->prev == head;\n}\n\n/**\n * list_is_last - tests whether @a list is the last entry in list @a head\n * @param list the entry to test\n * @param head the head of the list\n */\nstatic inline int list_is_last(const struct list_head *list, const struct list_head *head)\n{\n\treturn list->next == head;\n}\n\n/**\n * list_is_head - tests whether @a list is the list @a head\n * @param list the entry to test\n * @param head the head of the list\n */\nstatic inline int list_is_head(const struct list_head *list, const struct list_head *head)\n{\n\treturn list == head;\n}\n\n/**\n * list_empty - tests whether a list is empty\n * @param head the list to test.\n */\nstatic inline int list_empty(const struct list_head *head)\n{\n\treturn head->next == head;\n}\n\n/**\n * list_del_init_careful - deletes entry from list and reinitialize it.\n * @param entry the element to delete from the list.\n *\n * This is the same as list_del_init(), except designed to be used\n * together with list_empty_careful() in a way to guarantee ordering\n * of other memory operations.\n *\n * Any memory operations done before a list_del_init_careful() are\n * guaranteed to be visible after a list_empty_careful() test.\n */\nstatic inline void list_del_init_careful(struct list_head *entry)\n{\n\t__list_del_entry(entry);\n\tentry->prev = entry;\n\tentry->next = entry;\n}\n\n/**\n * list_empty_careful - tests whether a list is empty and not being modified\n * @param head the list to test\n *\n * Description:\n * tests whether a list is empty _and_ checks that no other CPU might be\n * in the process of modifying either member (next or prev)\n *\n * NOTE: using list_empty_careful() without synchronization\n * can only be safe if the only activity that can happen\n * to the list entry is list_del_init(). Eg. it cannot be used\n * if another CPU could re-list_add() it.\n */\nstatic inline int list_empty_careful(const struct list_head *head)\n{\n\tstruct list_head *next = head->next;\n\treturn (next == head) && (next == head->prev);\n}\n\n/**\n * list_rotate_left - rotate the list to the left\n * @param head the head of the list\n */\nstatic inline void list_rotate_left(struct list_head *head)\n{\n\tstruct list_head *first;\n\n\tif (!list_empty(head)) {\n\t\tfirst = head->next;\n\t\tlist_move_tail(first, head);\n\t}\n}\n\n/**\n * list_rotate_to_front() - Rotate list to specific item.\n * @param list The desired new front of the list.\n * @param head The head of the list.\n *\n * Rotates list so that @a list becomes the new front of the list.\n */\nstatic inline void list_rotate_to_front(struct list_head *list,\n\t\t\t\t\tstruct list_head *head)\n{\n\t/*\n\t * Deletes the list head from the list denoted by @a head and\n\t * places it as the tail of @a list, this effectively rotates the\n\t * list so that @a list is at the front.\n\t */\n\tlist_move_tail(head, list);\n}\n\n/**\n * list_is_singular - tests whether a list has just one entry.\n * @param head the list to test.\n */\nstatic inline int list_is_singular(const struct list_head *head)\n{\n\treturn !list_empty(head) && (head->next == head->prev);\n}\n\nstatic inline void __list_cut_position(struct list_head *list,\n\t\tstruct list_head *head, struct list_head *entry)\n{\n\tstruct list_head *new_first = entry->next;\n\tlist->next = head->next;\n\tlist->next->prev = list;\n\tlist->prev = entry;\n\tentry->next = list;\n\thead->next = new_first;\n\tnew_first->prev = head;\n}\n\n/**\n * list_cut_position - cut a list into two\n * @param list a new list to add all removed entries\n * @param head a list with entries\n * @param entry an entry within head, could be the head itself\n *\tand if so we won't cut the list\n *\n * This helper moves the initial part of @a head, up to and\n * including @a entry, from @a head to @a list. You should\n * pass on @a entry an element you know is on @a head. @a list\n * should be an empty list or a list you do not care about\n * losing its data.\n *\n */\nstatic inline void list_cut_position(struct list_head *list,\n\t\tstruct list_head *head, struct list_head *entry)\n{\n\tif (list_empty(head))\n\t\treturn;\n\tif (list_is_singular(head) && !list_is_head(entry, head) && (entry != head->next))\n\t\treturn;\n\tif (list_is_head(entry, head))\n\t\tINIT_LIST_HEAD(list);\n\telse\n\t\t__list_cut_position(list, head, entry);\n}\n\n/**\n * list_cut_before - cut a list into two, before given entry\n * @param list  a new list to add all removed entries\n * @param head  a list with entries\n * @param entry an entry within head, could be the head itself\n *\n * This helper moves the initial part of @a head, up to but\n * excluding @a entry, from @a head to @a list.  You should pass\n * in @a entry an element you know is on @a head.  @a list should\n * be an empty list or a list you do not care about losing\n * its data.\n * If @a entry == @a head, all entries on @a head are moved to\n * @a list.\n */\nstatic inline void list_cut_before(struct list_head *list,\n\t\t\t\t   struct list_head *head,\n\t\t\t\t   struct list_head *entry)\n{\n\tif (head->next == entry) {\n\t\tINIT_LIST_HEAD(list);\n\t\treturn;\n\t}\n\tlist->next = head->next;\n\tlist->next->prev = list;\n\tlist->prev = entry->prev;\n\tlist->prev->next = list;\n\thead->next = entry;\n\tentry->prev = head;\n}\n\nstatic inline void __list_splice(const struct list_head *list,\n\t\t\t\t struct list_head *prev,\n\t\t\t\t struct list_head *next)\n{\n\tstruct list_head *first = list->next;\n\tstruct list_head *last = list->prev;\n\n\tfirst->prev = prev;\n\tprev->next = first;\n\n\tlast->next = next;\n\tnext->prev = last;\n}\n\n/**\n * list_splice - join two lists, this is designed for stacks\n * @param list the new list to add.\n * @param head the place to add it in the first list.\n */\nstatic inline void list_splice(const struct list_head *list,\n\t\t\t\tstruct list_head *head)\n{\n\tif (!list_empty(list))\n\t\t__list_splice(list, head, head->next);\n}\n\n/**\n * list_splice_tail - join two lists, each list being a queue\n * @param list the new list to add.\n * @param head the place to add it in the first list.\n */\nstatic inline void list_splice_tail(struct list_head *list,\n\t\t\t\tstruct list_head *head)\n{\n\tif (!list_empty(list))\n\t\t__list_splice(list, head->prev, head);\n}\n\n/**\n * list_splice_init - join two lists and reinitialise the emptied list.\n * @param list the new list to add.\n * @param head the place to add it in the first list.\n *\n * The list at @a list is reinitialised\n */\nstatic inline void list_splice_init(struct list_head *list,\n\t\t\t\t    struct list_head *head)\n{\n\tif (!list_empty(list)) {\n\t\t__list_splice(list, head, head->next);\n\t\tINIT_LIST_HEAD(list);\n\t}\n}\n\n/**\n * list_splice_tail_init - join two lists and reinitialise the emptied list\n * @param list the new list to add.\n * @param head the place to add it in the first list.\n *\n * Each of the lists is a queue.\n * The list at @a list is reinitialised\n */\nstatic inline void list_splice_tail_init(struct list_head *list,\n\t\t\t\t\t struct list_head *head)\n{\n\tif (!list_empty(list)) {\n\t\t__list_splice(list, head->prev, head);\n\t\tINIT_LIST_HEAD(list);\n\t}\n}\n\n/**\n * list_entry - get the struct for this entry\n * @param ptr    the &struct list_head pointer.\n * @param type   the type of the struct this is embedded in.\n * @param member the name of the list_head within the struct.\n */\n#define list_entry(ptr, type, member) \\\n\tcontainer_of(ptr, type, member)\n\n/**\n * list_first_entry - get the first element from a list\n * @param ptr    the list head to take the element from.\n * @param type   the type of the struct this is embedded in.\n * @param member the name of the list_head within the struct.\n *\n * Note, that list is expected to be not empty.\n */\n#define list_first_entry(ptr, type, member) \\\n\tlist_entry((ptr)->next, type, member)\n\n/**\n * list_last_entry - get the last element from a list\n * @param ptr    the list head to take the element from.\n * @param type   the type of the struct this is embedded in.\n * @param member the name of the list_head within the struct.\n *\n * Note, that list is expected to be not empty.\n */\n#define list_last_entry(ptr, type, member) \\\n\tlist_entry((ptr)->prev, type, member)\n\n/**\n * list_first_entry_or_null - get the first element from a list\n * @param ptr    the list head to take the element from.\n * @param type   the type of the struct this is embedded in.\n * @param member the name of the list_head within the struct.\n *\n * Note that if the list is empty, it returns NULL.\n */\n#define list_first_entry_or_null(ptr, type, member) ({ \\\n\tstruct list_head *head__ = (ptr); \\\n\tstruct list_head *pos__ = head__->next; \\\n\tpos__ != head__ ? list_entry(pos__, type, member) : NULL; \\\n})\n\n/**\n * list_next_entry - get the next element in list\n * @param pos    the type * to cursor\n * @param member the name of the list_head within the struct.\n */\n#define list_next_entry(pos, member) \\\n\tlist_entry((pos)->member.next, typeof(*(pos)), member)\n\n/**\n * list_next_entry_circular - get the next element in list\n * @param pos    the type * to cursor.\n * @param head   the list head to take the element from.\n * @param member the name of the list_head within the struct.\n *\n * Wraparound if pos is the last element (return the first element).\n * Note, that list is expected to be not empty.\n */\n#define list_next_entry_circular(pos, head, member) \\\n\t(list_is_last(&(pos)->member, head) ? \\\n\tlist_first_entry(head, typeof(*(pos)), member) : list_next_entry(pos, member))\n\n/**\n * list_prev_entry - get the prev element in list\n * @param pos    the type * to cursor\n * @param member the name of the list_head within the struct.\n */\n#define list_prev_entry(pos, member) \\\n\tlist_entry((pos)->member.prev, typeof(*(pos)), member)\n\n/**\n * list_prev_entry_circular - get the prev element in list\n * @param pos    the type * to cursor.\n * @param head   the list head to take the element from.\n * @param member the name of the list_head within the struct.\n *\n * Wraparound if pos is the first element (return the last element).\n * Note, that list is expected to be not empty.\n */\n#define list_prev_entry_circular(pos, head, member) \\\n\t(list_is_first(&(pos)->member, head) ? \\\n\tlist_last_entry(head, typeof(*(pos)), member) : list_prev_entry(pos, member))\n\n/**\n * list_for_each\t-\titerate over a list\n * @param pos  the &struct list_head to use as a loop cursor.\n * @param head the head for your list.\n */\n#define list_for_each(pos, head) \\\n\tfor (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)\n\n/* Ignore kernel list_for_each_rcu() */\n\n/**\n * list_for_each_continue - continue iteration over a list\n * @param pos  the &struct list_head to use as a loop cursor.\n * @param head the head for your list.\n *\n * Continue to iterate over a list, continuing after the current position.\n */\n#define list_for_each_continue(pos, head) \\\n\tfor (pos = pos->next; pos != (head); pos = pos->next)\n\n/**\n * list_for_each_prev\t-\titerate over a list backwards\n * @param pos  the &struct list_head to use as a loop cursor.\n * @param head the head for your list.\n */\n#define list_for_each_prev(pos, head) \\\n\tfor (pos = (head)->prev; pos != (head); pos = pos->prev)\n\n/**\n * list_for_each_safe - iterate over a list safe against removal of list entry\n * @param pos  the &struct list_head to use as a loop cursor.\n * @param n    another &struct list_head to use as temporary storage\n * @param head the head for your list.\n */\n#define list_for_each_safe(pos, n, head) \\\n\tfor (pos = (head)->next, n = pos->next; pos != (head); \\\n\t\tpos = n, n = pos->next)\n\n/**\n * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry\n * @param pos  the &struct list_head to use as a loop cursor.\n * @param n    another &struct list_head to use as temporary storage\n * @param head the head for your list.\n */\n#define list_for_each_prev_safe(pos, n, head) \\\n\tfor (pos = (head)->prev, n = pos->prev; \\\n\t     pos != (head); \\\n\t     pos = n, n = pos->prev)\n\n/**\n * list_count_nodes - count nodes in the list\n * @param head\tthe head for your list.\n */\nstatic inline size_t list_count_nodes(struct list_head *head)\n{\n\tstruct list_head *pos;\n\tsize_t count = 0;\n\n\tlist_for_each(pos, head)\n\t\tcount++;\n\n\treturn count;\n}\n\n/**\n * list_entry_is_head - test if the entry points to the head of the list\n * @param pos    the type * to cursor\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n */\n#define list_entry_is_head(pos, head, member)\t\t\t\t\\\n\t(&pos->member == (head))\n\n/**\n * list_for_each_entry\t-\titerate over list of given type\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n */\n#define list_for_each_entry(pos, head, member)\t\t\t\t\\\n\tfor (pos = list_first_entry(head, typeof(*pos), member);\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_next_entry(pos, member))\n\n/**\n * list_for_each_entry_reverse - iterate backwards over list of given type.\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n */\n#define list_for_each_entry_reverse(pos, head, member)\t\t\t\\\n\tfor (pos = list_last_entry(head, typeof(*pos), member);\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_prev_entry(pos, member))\n\n/**\n * list_for_each_entry_direction - iterate forward/backward over list of given type\n * @param forward the iterate direction, true for forward, false for backward.\n * @param pos     the type * to use as a loop cursor.\n * @param head    the head for your list.\n * @param member  the name of the list_head within the struct.\n */\n#define list_for_each_entry_direction(forward, pos, head, member)\t\t\\\n\tfor (pos = forward ? list_first_entry(head, typeof(*pos), member)\t\\\n\t\t\t\t\t   : list_last_entry(head, typeof(*pos), member);\t\\\n\t\t !list_entry_is_head(pos, head, member);\t\t\t\t\t\t\\\n\t\t pos = forward ? list_next_entry(pos, member)\t\t\t\t\t\\\n\t\t\t\t\t   : list_prev_entry(pos, member))\n\n/**\n * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()\n * @param pos    the type * to use as a start point\n * @param head   the head of the list\n * @param member the name of the list_head within the struct.\n *\n * Prepares a pos entry for use as a start point in list_for_each_entry_continue().\n */\n#define list_prepare_entry(pos, head, member) \\\n\t((pos) ? (pos) : list_entry(head, typeof(*pos), member))\n\n/**\n * list_for_each_entry_continue - continue iteration over list of given type\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Continue to iterate over list of given type, continuing after\n * the current position.\n */\n#define list_for_each_entry_continue(pos, head, member)\t\t\\\n\tfor (pos = list_next_entry(pos, member);\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_next_entry(pos, member))\n\n/**\n * list_for_each_entry_continue_reverse - iterate backwards from the given point\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Start to iterate over list of given type backwards, continuing after\n * the current position.\n */\n#define list_for_each_entry_continue_reverse(pos, head, member)\t\t\\\n\tfor (pos = list_prev_entry(pos, member);\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_prev_entry(pos, member))\n\n/**\n * list_for_each_entry_from - iterate over list of given type from the current point\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Iterate over list of given type, continuing from current position.\n */\n#define list_for_each_entry_from(pos, head, member)\t\t\t\\\n\tfor (; !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_next_entry(pos, member))\n\n/**\n * list_for_each_entry_from_reverse - iterate backwards over list of given type\n *                                    from the current point\n * @param pos    the type * to use as a loop cursor.\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Iterate backwards over list of given type, continuing from current position.\n */\n#define list_for_each_entry_from_reverse(pos, head, member)\t\t\\\n\tfor (; !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = list_prev_entry(pos, member))\n\n/**\n * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry\n * @param pos    the type * to use as a loop cursor.\n * @param n      another type * to use as temporary storage\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n */\n#define list_for_each_entry_safe(pos, n, head, member)\t\t\t\\\n\tfor (pos = list_first_entry(head, typeof(*pos), member),\t\\\n\t\tn = list_next_entry(pos, member);\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = n, n = list_next_entry(n, member))\n\n/**\n * list_for_each_entry_safe_continue - continue list iteration safe against removal\n * @param pos    the type * to use as a loop cursor.\n * @param n      another type * to use as temporary storage\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Iterate over list of given type, continuing after current point,\n * safe against removal of list entry.\n */\n#define list_for_each_entry_safe_continue(pos, n, head, member)\t\t\\\n\tfor (pos = list_next_entry(pos, member),\t\t\t\t\\\n\t\tn = list_next_entry(pos, member);\t\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\t\\\n\t     pos = n, n = list_next_entry(n, member))\n\n/**\n * list_for_each_entry_safe_from - iterate over list from current point safe against removal\n * @param pos    the type * to use as a loop cursor.\n * @param n      another type * to use as temporary storage\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Iterate over list of given type from current point, safe against\n * removal of list entry.\n */\n#define list_for_each_entry_safe_from(pos, n, head, member)\t\t\t\\\n\tfor (n = list_next_entry(pos, member);\t\t\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\t\\\n\t     pos = n, n = list_next_entry(n, member))\n\n/**\n * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal\n * @param pos    the type * to use as a loop cursor.\n * @param n      another type * to use as temporary storage\n * @param head   the head for your list.\n * @param member the name of the list_head within the struct.\n *\n * Iterate backwards over list of given type, safe against removal\n * of list entry.\n */\n#define list_for_each_entry_safe_reverse(pos, n, head, member)\t\t\\\n\tfor (pos = list_last_entry(head, typeof(*pos), member),\t\t\\\n\t\tn = list_prev_entry(pos, member);\t\t\t\\\n\t     !list_entry_is_head(pos, head, member);\t\t\t\\\n\t     pos = n, n = list_prev_entry(n, member))\n\n/**\n * list_safe_reset_next - reset a stale list_for_each_entry_safe loop\n * @param pos    the loop cursor used in the list_for_each_entry_safe loop\n * @param n      temporary storage used in list_for_each_entry_safe\n * @param member the name of the list_head within the struct.\n *\n * list_safe_reset_next is not safe to use in general if the list may be\n * modified concurrently (eg. the lock is dropped in the loop body). An\n * exception to this is if the cursor element (pos) is pinned in the list,\n * and list_safe_reset_next is called after re-taking the lock and before\n * completing the current iteration of the loop body.\n */\n#define list_safe_reset_next(pos, n, member)\t\t\t\t\\\n\tn = list_next_entry(pos, member)\n\n/*\n * Double linked lists with a single pointer list head.\n * IGNORED\n */\n\n#endif /* OPENOCD_HELPER_LIST_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/log.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"log.h\"\n#include \"command.h\"\n#include \"replacements.h\"\n#include \"time_support.h\"\n#include <server/gdb_server.h>\n#include <server/server.h>\n\n#include <stdarg.h>\n\n#ifdef _DEBUG_FREE_SPACE_\n#ifdef HAVE_MALLOC_H\n#include <malloc.h>\n#else\n#error \"malloc.h is required to use --enable-malloc-logging\"\n#endif\n#endif\n\nint debug_level = LOG_LVL_INFO;\n\nstatic FILE *log_output;\nstatic struct log_callback *log_callbacks;\n\nstatic int64_t last_time;\n\nstatic int64_t start;\n\nstatic const char * const log_strings[6] = {\n\t\"User : \",\n\t\"Error: \",\n\t\"Warn : \",\t/* want a space after each colon, all same width, colons aligned */\n\t\"Info : \",\n\t\"Debug: \",\n\t\"Debug: \"\n};\n\nstatic int count;\n\n/* forward the log to the listeners */\nstatic void log_forward(const char *file, unsigned line, const char *function, const char *string)\n{\n\tstruct log_callback *cb, *next;\n\tcb = log_callbacks;\n\t/* DANGER!!!! the log callback can remove itself!!!! */\n\twhile (cb) {\n\t\tnext = cb->next;\n\t\tcb->fn(cb->priv, file, line, function, string);\n\t\tcb = next;\n\t}\n}\n\n/* The log_puts() serves two somewhat different goals:\n *\n * - logging\n * - feeding low-level info to the user in GDB or Telnet\n *\n * The latter dictates that strings without newline are not logged, lest there\n * will be *MANY log lines when sending one char at the time(e.g.\n * target_request.c).\n *\n */\nstatic void log_puts(enum log_levels level,\n\tconst char *file,\n\tint line,\n\tconst char *function,\n\tconst char *string)\n{\n\tchar *f;\n\n\tif (!log_output) {\n\t\t/* log_init() not called yet; print on stderr */\n\t\tfputs(string, stderr);\n\t\tfflush(stderr);\n\t\treturn;\n\t}\n\n\tif (level == LOG_LVL_OUTPUT) {\n\t\t/* do not prepend any headers, just print out what we were given and return */\n\t\tfputs(string, log_output);\n\t\tfflush(log_output);\n\t\treturn;\n\t}\n\n\tf = strrchr(file, '/');\n\tif (f)\n\t\tfile = f + 1;\n\n\tif (debug_level >= LOG_LVL_DEBUG) {\n\t\t/* print with count and time information */\n\t\tint64_t t = timeval_ms() - start;\n#ifdef _DEBUG_FREE_SPACE_\n\t\tstruct mallinfo info;\n\t\tinfo = mallinfo();\n#endif\n\t\tfprintf(log_output, \"%s%d %\" PRId64 \" %s:%d %s()\"\n#ifdef _DEBUG_FREE_SPACE_\n\t\t\t\" %d\"\n#endif\n\t\t\t\": %s\", log_strings[level + 1], count, t, file, line, function,\n#ifdef _DEBUG_FREE_SPACE_\n\t\t\tinfo.fordblks,\n#endif\n\t\t\tstring);\n\t} else {\n\t\t/* if we are using gdb through pipes then we do not want any output\n\t\t * to the pipe otherwise we get repeated strings */\n\t\tfprintf(log_output, \"%s%s\",\n\t\t\t(level > LOG_LVL_USER) ? log_strings[level + 1] : \"\", string);\n\t}\n\n\tfflush(log_output);\n\n\t/* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */\n\tif (level <= LOG_LVL_INFO)\n\t\tlog_forward(file, line, function, string);\n}\n\nvoid log_printf(enum log_levels level,\n\tconst char *file,\n\tunsigned line,\n\tconst char *function,\n\tconst char *format,\n\t...)\n{\n\tchar *string;\n\tva_list ap;\n\n\tcount++;\n\tif (level > debug_level)\n\t\treturn;\n\n\tva_start(ap, format);\n\n\tstring = alloc_vprintf(format, ap);\n\tif (string) {\n\t\tlog_puts(level, file, line, function, string);\n\t\tfree(string);\n\t}\n\n\tva_end(ap);\n}\n\nvoid log_vprintf_lf(enum log_levels level, const char *file, unsigned line,\n\t\tconst char *function, const char *format, va_list args)\n{\n\tchar *tmp;\n\n\tcount++;\n\n\tif (level > debug_level)\n\t\treturn;\n\n\ttmp = alloc_vprintf(format, args);\n\n\tif (!tmp)\n\t\treturn;\n\n\t/*\n\t * Note: alloc_vprintf() guarantees that the buffer is at least one\n\t * character longer.\n\t */\n\tstrcat(tmp, \"\\n\");\n\tlog_puts(level, file, line, function, tmp);\n\tfree(tmp);\n}\n\nvoid log_printf_lf(enum log_levels level,\n\tconst char *file,\n\tunsigned line,\n\tconst char *function,\n\tconst char *format,\n\t...)\n{\n\tva_list ap;\n\n\tva_start(ap, format);\n\tlog_vprintf_lf(level, file, line, function, format, ap);\n\tva_end(ap);\n}\n\nCOMMAND_HANDLER(handle_debug_level_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tint new_level;\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);\n\t\tif ((new_level > LOG_LVL_DEBUG_IO) || (new_level < LOG_LVL_SILENT)) {\n\t\t\tLOG_ERROR(\"level must be between %d and %d\", LOG_LVL_SILENT, LOG_LVL_DEBUG_IO);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tdebug_level = new_level;\n\t} else if (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"debug_level: %i\", debug_level);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_log_output_command)\n{\n\tif (CMD_ARGC == 0 || (CMD_ARGC == 1 && strcmp(CMD_ARGV[0], \"default\") == 0)) {\n\t\tif (log_output != stderr && log_output) {\n\t\t\t/* Close previous log file, if it was open and wasn't stderr. */\n\t\t\tfclose(log_output);\n\t\t}\n\t\tlog_output = stderr;\n\t\tLOG_DEBUG(\"set log_output to default\");\n\t\treturn ERROR_OK;\n\t}\n\tif (CMD_ARGC == 1) {\n\t\tFILE *file = fopen(CMD_ARGV[0], \"w\");\n\t\tif (!file) {\n\t\t\tLOG_ERROR(\"failed to open output log '%s'\", CMD_ARGV[0]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (log_output != stderr && log_output) {\n\t\t\t/* Close previous log file, if it was open and wasn't stderr. */\n\t\t\tfclose(log_output);\n\t\t}\n\t\tlog_output = file;\n\t\tLOG_DEBUG(\"set log_output to \\\"%s\\\"\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nstatic const struct command_registration log_command_handlers[] = {\n\t{\n\t\t.name = \"log_output\",\n\t\t.handler = handle_log_output_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"redirect logging to a file (default: stderr)\",\n\t\t.usage = \"[file_name | \\\"default\\\"]\",\n\t},\n\t{\n\t\t.name = \"debug_level\",\n\t\t.handler = handle_debug_level_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Sets the verbosity level of debugging output. \"\n\t\t\t\"0 shows errors only; 1 adds warnings; \"\n\t\t\t\"2 (default) adds other info; 3 adds debugging; \"\n\t\t\t\"4 adds extra verbose debugging.\",\n\t\t.usage = \"number\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint log_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, log_command_handlers);\n}\n\nvoid log_init(void)\n{\n\t/* set defaults for daemon configuration,\n\t * if not set by cmdline or cfgfile */\n\tchar *debug_env = getenv(\"OPENOCD_DEBUG_LEVEL\");\n\tif (debug_env) {\n\t\tint value;\n\t\tint retval = parse_int(debug_env, &value);\n\t\tif (retval == ERROR_OK &&\n\t\t\t\tdebug_level >= LOG_LVL_SILENT &&\n\t\t\t\tdebug_level <= LOG_LVL_DEBUG_IO)\n\t\t\t\tdebug_level = value;\n\t}\n\n\tif (!log_output)\n\t\tlog_output = stderr;\n\n\tstart = last_time = timeval_ms();\n}\n\nvoid log_exit(void)\n{\n\tif (log_output && log_output != stderr) {\n\t\t/* Close log file, if it was open and wasn't stderr. */\n\t\tfclose(log_output);\n\t}\n\tlog_output = NULL;\n}\n\n/* add/remove log callback handler */\nint log_add_callback(log_callback_fn fn, void *priv)\n{\n\tstruct log_callback *cb;\n\n\t/* prevent the same callback to be registered more than once, just for sure */\n\tfor (cb = log_callbacks; cb; cb = cb->next) {\n\t\tif (cb->fn == fn && cb->priv == priv)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* alloc memory, it is safe just to return in case of an error, no need for the caller to\n\t *check this */\n\tcb = malloc(sizeof(struct log_callback));\n\tif (!cb)\n\t\treturn ERROR_BUF_TOO_SMALL;\n\n\t/* add item to the beginning of the linked list */\n\tcb->fn = fn;\n\tcb->priv = priv;\n\tcb->next = log_callbacks;\n\tlog_callbacks = cb;\n\n\treturn ERROR_OK;\n}\n\nint log_remove_callback(log_callback_fn fn, void *priv)\n{\n\tstruct log_callback *cb, **p;\n\n\tfor (p = &log_callbacks; (cb = *p); p = &(*p)->next) {\n\t\tif (cb->fn == fn && cb->priv == priv) {\n\t\t\t*p = cb->next;\n\t\t\tfree(cb);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* no such item */\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\n/* return allocated string w/printf() result */\nchar *alloc_vprintf(const char *fmt, va_list ap)\n{\n\tva_list ap_copy;\n\tint len;\n\tchar *string;\n\n\t/* determine the length of the buffer needed */\n\tva_copy(ap_copy, ap);\n\tlen = vsnprintf(NULL, 0, fmt, ap_copy);\n\tva_end(ap_copy);\n\n\t/* allocate and make room for terminating zero. */\n\t/* FIXME: The old version always allocated at least one byte extra and\n\t * other code depend on that. They should be probably be fixed, but for\n\t * now reserve the extra byte. */\n\tstring = malloc(len + 2);\n\tif (!string)\n\t\treturn NULL;\n\n\t/* do the real work */\n\tvsnprintf(string, len + 1, fmt, ap);\n\n\treturn string;\n}\n\nchar *alloc_printf(const char *format, ...)\n{\n\tchar *string;\n\tva_list ap;\n\tva_start(ap, format);\n\tstring = alloc_vprintf(format, ap);\n\tva_end(ap);\n\treturn string;\n}\n\n/* Code must return to the server loop before 1000ms has returned or invoke\n * this function.\n *\n * The GDB connection will time out if it spends >2000ms and you'll get nasty\n * error messages from GDB:\n *\n * Ignoring packet error, continuing...\n * Reply contains invalid hex digit 116\n *\n * While it is possible use \"set remotetimeout\" to more than the default 2000ms\n * in GDB, OpenOCD guarantees that it sends keep-alive packages on the\n * GDB protocol and it is a bug in OpenOCD not to either return to the server\n * loop or invoke keep_alive() every 1000ms.\n *\n * This function will send a keep alive packet if >500ms has passed since last time\n * it was invoked.\n *\n * Note that this function can be invoked often, so it needs to be relatively\n * fast when invoked more often than every 500ms.\n *\n */\n#define KEEP_ALIVE_KICK_TIME_MS  500\n#define KEEP_ALIVE_TIMEOUT_MS   1000\n\nstatic void gdb_timeout_warning(int64_t delta_time)\n{\n\tif (gdb_get_actual_connections())\n\t\tLOG_WARNING(\"keep_alive() was not invoked in the \"\n\t\t\t\"%d ms timelimit. GDB alive packet not \"\n\t\t\t\"sent! (%\" PRId64 \" ms). Workaround: increase \"\n\t\t\t\"\\\"set remotetimeout\\\" in GDB\",\n\t\t\tKEEP_ALIVE_TIMEOUT_MS,\n\t\t\tdelta_time);\n\telse\n\t\tLOG_DEBUG(\"keep_alive() was not invoked in the \"\n\t\t\t\"%d ms timelimit (%\" PRId64 \" ms). This may cause \"\n\t\t\t\"trouble with GDB connections.\",\n\t\t\tKEEP_ALIVE_TIMEOUT_MS,\n\t\t\tdelta_time);\n}\n\nvoid keep_alive(void)\n{\n\tint64_t current_time = timeval_ms();\n\tint64_t delta_time = current_time - last_time;\n\n\tif (delta_time > KEEP_ALIVE_TIMEOUT_MS) {\n\t\tlast_time = current_time;\n\n\t\tgdb_timeout_warning(delta_time);\n\t}\n\n\tif (delta_time > KEEP_ALIVE_KICK_TIME_MS) {\n\t\tlast_time = current_time;\n\n\t\t/* this will keep the GDB connection alive */\n\t\tserver_keep_clients_alive();\n\n\t\t/* DANGER!!!! do not add code to invoke e.g. target event processing,\n\t\t * jim timer processing, etc. it can cause infinite recursion +\n\t\t * jim event callbacks need to happen at a well defined time,\n\t\t * not anywhere keep_alive() is invoked.\n\t\t *\n\t\t * These functions should be invoked at a well defined spot in server.c\n\t\t */\n\t}\n}\n\n/* reset keep alive timer without sending message */\nvoid kept_alive(void)\n{\n\tint64_t current_time = timeval_ms();\n\n\tint64_t delta_time = current_time - last_time;\n\n\tlast_time = current_time;\n\n\tif (delta_time > KEEP_ALIVE_TIMEOUT_MS)\n\t\tgdb_timeout_warning(delta_time);\n}\n\n/* if we sleep for extended periods of time, we must invoke keep_alive() intermittently */\nvoid alive_sleep(uint64_t ms)\n{\n\tuint64_t nap_time = 10;\n\tfor (uint64_t i = 0; i < ms; i += nap_time) {\n\t\tuint64_t sleep_a_bit = ms - i;\n\t\tif (sleep_a_bit > nap_time)\n\t\t\tsleep_a_bit = nap_time;\n\n\t\tusleep(sleep_a_bit * 1000);\n\t\tkeep_alive();\n\t}\n}\n\nvoid busy_sleep(uint64_t ms)\n{\n\tuint64_t then = timeval_ms();\n\twhile (timeval_ms() - then < ms) {\n\t\t/*\n\t\t * busy wait\n\t\t */\n\t}\n}\n\n/* Maximum size of socket error message retrieved from operation system */\n#define MAX_SOCKET_ERR_MSG_LENGTH 256\n\n/* Provide log message for the last socket error.\n   Uses errno on *nix and WSAGetLastError() on Windows */\nvoid log_socket_error(const char *socket_desc)\n{\n\tint error_code;\n#ifdef _WIN32\n\terror_code = WSAGetLastError();\n\tchar error_message[MAX_SOCKET_ERR_MSG_LENGTH];\n\terror_message[0] = '\\0';\n\tDWORD retval = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0,\n\t\terror_message, MAX_SOCKET_ERR_MSG_LENGTH, NULL);\n\terror_message[MAX_SOCKET_ERR_MSG_LENGTH - 1] = '\\0';\n\tconst bool have_message = (retval != 0) && (error_message[0] != '\\0');\n\tLOG_ERROR(\"Error on socket '%s': WSAGetLastError==%d%s%s.\", socket_desc, error_code,\n\t\t(have_message ? \", message: \" : \"\"),\n\t\t(have_message ? error_message : \"\"));\n#else\n\terror_code = errno;\n\tLOG_ERROR(\"Error on socket '%s': errno==%d, message: %s.\", socket_desc, error_code, strerror(error_code));\n#endif\n}\n\n/**\n * Find the first non-printable character in the char buffer, return a pointer to it.\n * If no such character exists, return NULL.\n */\nchar *find_nonprint_char(char *buf, unsigned buf_len)\n{\n\tfor (unsigned int i = 0; i < buf_len; i++) {\n\t\tif (!isprint(buf[i]))\n\t\t\treturn buf + i;\n\t}\n\treturn NULL;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/log.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_LOG_H\n#define OPENOCD_HELPER_LOG_H\n\n#include <helper/command.h>\n\n/* To achieve C99 printf compatibility in MinGW, gnu_printf should be\n * used for __attribute__((format( ... ))), with GCC v4.4 or later\n */\n#if (defined(IS_MINGW) && (((__GNUC__ << 16) + __GNUC_MINOR__) >= 0x00040004))\n#define PRINTF_ATTRIBUTE_FORMAT gnu_printf\n#else\n#define PRINTF_ATTRIBUTE_FORMAT printf\n#endif\n\n/* logging priorities\n * LOG_LVL_SILENT - turn off all output. In lieu of try + catch this can be used as a\n *                  feeble ersatz.\n * LOG_LVL_USER - user messages. Could be anything from information\n *                to progress messages. These messages do not represent\n *                incorrect or unexpected behaviour, just normal execution.\n * LOG_LVL_ERROR - fatal errors, that are likely to cause program abort\n * LOG_LVL_WARNING - non-fatal errors, that may be resolved later\n * LOG_LVL_INFO - state information, etc.\n * LOG_LVL_DEBUG - debug statements, execution trace\n * LOG_LVL_DEBUG_IO - verbose debug, low-level I/O trace\n */\nenum log_levels {\n\tLOG_LVL_SILENT = -3,\n\tLOG_LVL_OUTPUT = -2,\n\tLOG_LVL_USER = -1,\n\tLOG_LVL_ERROR = 0,\n\tLOG_LVL_WARNING = 1,\n\tLOG_LVL_INFO = 2,\n\tLOG_LVL_DEBUG = 3,\n\tLOG_LVL_DEBUG_IO = 4,\n};\n\nvoid log_printf(enum log_levels level, const char *file, unsigned line,\n\t\tconst char *function, const char *format, ...)\n__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));\nvoid log_vprintf_lf(enum log_levels level, const char *file, unsigned line,\n\t\tconst char *function, const char *format, va_list args);\nvoid log_printf_lf(enum log_levels level, const char *file, unsigned line,\n\t\tconst char *function, const char *format, ...)\n__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6)));\n\n/**\n * Initialize logging module.  Call during program startup.\n */\nvoid log_init(void);\nvoid log_exit(void);\n\nint log_register_commands(struct command_context *cmd_ctx);\n\nvoid keep_alive(void);\nvoid kept_alive(void);\n\nvoid alive_sleep(uint64_t ms);\nvoid busy_sleep(uint64_t ms);\n\nvoid log_socket_error(const char *socket_desc);\n\ntypedef void (*log_callback_fn)(void *priv, const char *file, unsigned line,\n\t\tconst char *function, const char *string);\n\nstruct log_callback {\n\tlog_callback_fn fn;\n\tvoid *priv;\n\tstruct log_callback *next;\n};\n\nint log_add_callback(log_callback_fn fn, void *priv);\nint log_remove_callback(log_callback_fn fn, void *priv);\n\nchar *alloc_vprintf(const char *fmt, va_list ap);\nchar *alloc_printf(const char *fmt, ...)\n\t__attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 1, 2)));\n\nchar *find_nonprint_char(char *buf, unsigned buf_len);\n\nextern int debug_level;\n\n/* Avoid fn call and building parameter list if we're not outputting the information.\n * Matters on feeble CPUs for DEBUG/INFO statements that are involved frequently */\n\n#define LOG_LEVEL_IS(FOO)  ((debug_level) >= (FOO))\n\n#define LOG_DEBUG_IO(expr ...) \\\n\tdo { \\\n\t\tif (debug_level >= LOG_LVL_DEBUG_IO) \\\n\t\t\tlog_printf_lf(LOG_LVL_DEBUG, \\\n\t\t\t\t__FILE__, __LINE__, __func__, \\\n\t\t\t\texpr); \\\n\t} while (0)\n\n#define LOG_DEBUG(expr ...) \\\n\tdo { \\\n\t\tif (debug_level >= LOG_LVL_DEBUG) \\\n\t\t\tlog_printf_lf(LOG_LVL_DEBUG, \\\n\t\t\t\t__FILE__, __LINE__, __func__, \\\n\t\t\t\texpr); \\\n\t} while (0)\n\n#define LOG_INFO(expr ...) \\\n\tlog_printf_lf(LOG_LVL_INFO, __FILE__, __LINE__, __func__, expr)\n\n#define LOG_WARNING(expr ...) \\\n\tlog_printf_lf(LOG_LVL_WARNING, __FILE__, __LINE__, __func__, expr)\n\n#define LOG_ERROR(expr ...) \\\n\tlog_printf_lf(LOG_LVL_ERROR, __FILE__, __LINE__, __func__, expr)\n\n#define LOG_USER(expr ...) \\\n\tlog_printf_lf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr)\n\n#define LOG_USER_N(expr ...) \\\n\tlog_printf(LOG_LVL_USER, __FILE__, __LINE__, __func__, expr)\n\n#define LOG_OUTPUT(expr ...) \\\n\tlog_printf(LOG_LVL_OUTPUT, __FILE__, __LINE__, __func__, expr)\n\n/* Output a log entry that is related to a given target */\n\n#define LOG_TARGET_DEBUG_IO(target, fmt_str, ...) \\\n\tLOG_DEBUG_IO(\"[%s] \" fmt_str, target_name(target), ##__VA_ARGS__)\n\n#define LOG_TARGET_DEBUG(target, fmt_str, ...) \\\n\tLOG_DEBUG(\"[%s] \" fmt_str, target_name(target), ##__VA_ARGS__)\n\n#define LOG_TARGET_INFO(target, fmt_str, ...) \\\n\tLOG_INFO(\"[%s] \" fmt_str, target_name(target), ##__VA_ARGS__)\n\n#define LOG_TARGET_WARNING(target, fmt_str, ...) \\\n\tLOG_WARNING(\"[%s] \" fmt_str, target_name(target), ##__VA_ARGS__)\n\n#define LOG_TARGET_ERROR(target, fmt_str, ...) \\\n\tLOG_ERROR(\"[%s] \" fmt_str, target_name(target), ##__VA_ARGS__)\n\n/* general failures\n * error codes < 100\n */\n#define ERROR_OK\t\t\t\t\t\t(0)\n#define ERROR_NO_CONFIG_FILE\t\t\t(-2)\n#define ERROR_BUF_TOO_SMALL\t\t\t\t(-3)\n/* see \"Error:\" log entry for meaningful message to the user. The caller should\n * make no assumptions about what went wrong and try to handle the problem.\n */\n#define ERROR_FAIL\t\t\t\t\t\t(-4)\n#define ERROR_WAIT\t\t\t\t\t\t(-5)\n/* ERROR_TIMEOUT is already taken by winerror.h. */\n#define ERROR_TIMEOUT_REACHED\t\t\t(-6)\n#define ERROR_NOT_IMPLEMENTED\t\t\t(-7)\n\n\n#endif /* OPENOCD_HELPER_LOG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/nvp.c",
    "content": "// SPDX-License-Identifier: BSD-2-Clause-Views\n\n/*\n * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\n * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\n * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>\n * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\n * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\n * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\n * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\n * Copyright 2008 Steve Bennett <steveb@workware.net.au>\n * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>\n * Copyright 2009 Zachary T Welch zw@superlucidity.net\n * Copyright 2009 David Brownell\n * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.\n *\n * This file is extracted from jim_nvp.c, originally part of jim TCL code.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include <helper/command.h>\n#include <helper/nvp.h>\n\nconst struct nvp *nvp_name2value(const struct nvp *p, const char *name)\n{\n\twhile (p->name) {\n\t\tif (strcmp(name, p->name) == 0)\n\t\t\tbreak;\n\t\tp++;\n\t}\n\treturn p;\n}\n\nconst struct nvp *nvp_value2name(const struct nvp *p, int value)\n{\n\twhile (p->name) {\n\t\tif (value == p->value)\n\t\t\tbreak;\n\t\tp++;\n\t}\n\treturn p;\n}\n\nvoid nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp,\n\tconst char *param_name, const char *param_value)\n{\n\tif (param_name)\n\t\tcommand_print_sameline(cmd, \"%s: Unknown: %s, try one of: \", param_name, param_value);\n\telse\n\t\tcommand_print_sameline(cmd, \"Unknown param: %s, try one of: \", param_value);\n\n\twhile (nvp->name) {\n\t\tif ((nvp + 1)->name)\n\t\t\tcommand_print_sameline(cmd, \"%s, \", nvp->name);\n\t\telse\n\t\t\tcommand_print(cmd, \"or %s\", nvp->name);\n\n\t\tnvp++;\n\t}\n\n\t/* We assume nvp to be not empty and loop has been taken; no need to add a '\\n' */\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/nvp.h",
    "content": "/* SPDX-License-Identifier: BSD-2-Clause-Views */\n\n/*\n * Copyright 2005 Salvatore Sanfilippo <antirez@invece.org>\n * Copyright 2005 Clemens Hintze <c.hintze@gmx.net>\n * Copyright 2005 patthoyts - Pat Thoyts <patthoyts@users.sf.net>\n * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com\n * Copyright 2008 Andrew Lunn <andrew@lunn.ch>\n * Copyright 2008 Duane Ellis <openocd@duaneellis.com>\n * Copyright 2008 Uwe Klein <uklein@klein-messgeraete.de>\n * Copyright 2008 Steve Bennett <steveb@workware.net.au>\n * Copyright 2009 Nico Coesel <ncoesel@dealogic.nl>\n * Copyright 2009 Zachary T Welch zw@superlucidity.net\n * Copyright 2009 David Brownell\n * Copyright (c) 2005-2011 Jim Tcl Project. All rights reserved.\n *\n * This file is extracted from jim_nvp.h, originally part of jim TCL code.\n */\n\n#ifndef OPENOCD_HELPER_NVP_H\n#define OPENOCD_HELPER_NVP_H\n\n#include <helper/compiler.h>\n\n/** Name Value Pairs, aka: NVP\n *   -  Given a string - return the associated int.\n *   -  Given a number - return the associated string.\n *   .\n *\n * Very useful when the number is not a simple index into an array of\n * known string, or there may be multiple strings (aliases) that mean then same\n * thing.\n *\n * An NVP Table is terminated with \".name = NULL\".\n *\n * During the 'name2value' operation, if no matching string is found\n * the pointer to the terminal element (with p->name == NULL) is returned.\n *\n * Example:\n * \\code\n *      const struct nvp yn[] = {\n *          { \"yes\", 1 },\n *          { \"no\" , 0 },\n *          { \"yep\", 1 },\n *          { \"nope\", 0 },\n *          { NULL, -1 },\n *      };\n *\n *  struct nvp *result;\n *  result = nvp_name2value(yn, \"yes\");\n *         returns &yn[0];\n *  result = nvp_name2value(yn, \"no\");\n *         returns &yn[1];\n *  result = jim_nvp_name2value(yn, \"Blah\");\n *         returns &yn[4];\n * \\endcode\n *\n * During the number2name operation, the first matching value is returned.\n */\n\nstruct nvp {\n\tconst char *name;\n\tint value;\n};\n\nstruct command_invocation;\n\n/* Name Value Pairs Operations */\nconst struct nvp *nvp_name2value(const struct nvp *nvp_table, const char *name)\n\t__returns_nonnull __nonnull((1));\nconst struct nvp *nvp_value2name(const struct nvp *nvp_table, int v)\n\t__returns_nonnull __nonnull((1));\n\nvoid nvp_unknown_command_print(struct command_invocation *cmd, const struct nvp *nvp,\n\tconst char *param_name, const char *param_value);\n\n#endif /* OPENOCD_HELPER_NVP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/options.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"configuration.h\"\n#include \"log.h\"\n#include \"command.h\"\n\n#include <getopt.h>\n\n#include <limits.h>\n#include <stdlib.h>\n#include <string.h>\n#if IS_DARWIN\n#include <libproc.h>\n#endif\n/* sys/sysctl.h is deprecated on Linux from glibc 2.30 */\n#ifndef __linux__\n#ifdef HAVE_SYS_SYSCTL_H\n#include <sys/sysctl.h>\n#endif\n#endif\n#if IS_WIN32 && !IS_CYGWIN\n#include <windows.h>\n#endif\n\nstatic int help_flag, version_flag;\n\nstatic const struct option long_options[] = {\n\t{\"help\",\t\tno_argument,\t\t\t&help_flag,\t\t1},\n\t{\"version\",\t\tno_argument,\t\t\t&version_flag,\t1},\n\t{\"debug\",\t\toptional_argument,\t\tNULL,\t\t\t'd'},\n\t{\"file\",\t\trequired_argument,\t\tNULL,\t\t\t'f'},\n\t{\"search\",\t\trequired_argument,\t\tNULL,\t\t\t's'},\n\t{\"log_output\",\trequired_argument,\t\tNULL,\t\t\t'l'},\n\t{\"command\",\t\trequired_argument,\t\tNULL,\t\t\t'c'},\n\t{NULL, 0, NULL, 0}\n};\n\nint configuration_output_handler(struct command_context *context, const char *line)\n{\n\tLOG_USER_N(\"%s\", line);\n\n\treturn ERROR_OK;\n}\n\n/* Return the canonical path to the directory the openocd executable is in.\n * The path should be absolute, use / as path separator and have all symlinks\n * resolved. The returned string is malloc'd. */\nstatic char *find_exe_path(void)\n{\n\tchar *exepath = NULL;\n\n\tdo {\n#if IS_WIN32 && !IS_CYGWIN\n\t\texepath = malloc(MAX_PATH);\n\t\tif (!exepath)\n\t\t\tbreak;\n\t\tGetModuleFileName(NULL, exepath, MAX_PATH);\n\n\t\t/* Convert path separators to UNIX style, should work on Windows also. */\n\t\tfor (char *p = exepath; *p; p++) {\n\t\t\tif (*p == '\\\\')\n\t\t\t\t*p = '/';\n\t\t}\n\n#elif IS_DARWIN\n\t\texepath = malloc(PROC_PIDPATHINFO_MAXSIZE);\n\t\tif (!exepath)\n\t\t\tbreak;\n\t\tif (proc_pidpath(getpid(), exepath, PROC_PIDPATHINFO_MAXSIZE) <= 0) {\n\t\t\tfree(exepath);\n\t\t\texepath = NULL;\n\t\t}\n\n#elif defined(CTL_KERN) && defined(KERN_PROC) && defined(KERN_PROC_PATHNAME) /* *BSD */\n#ifndef PATH_MAX\n#define PATH_MAX 1024\n#endif\n\t\tchar *path = malloc(PATH_MAX);\n\t\tif (!path)\n\t\t\tbreak;\n\t\tint mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };\n\t\tsize_t size = PATH_MAX;\n\n\t\tif (sysctl(mib, (u_int)ARRAY_SIZE(mib), path, &size, NULL, 0) != 0)\n\t\t\tbreak;\n\n#ifdef HAVE_REALPATH\n\t\texepath = realpath(path, NULL);\n\t\tfree(path);\n#else\n\t\texepath = path;\n#endif\n\n#elif defined(HAVE_REALPATH) /* Assume POSIX.1-2008 */\n\t\t/* Try Unices in order of likelihood. */\n\t\texepath = realpath(\"/proc/self/exe\", NULL); /* Linux/Cygwin */\n\t\tif (!exepath)\n\t\t\texepath = realpath(\"/proc/self/path/a.out\", NULL); /* Solaris */\n\t\tif (!exepath)\n\t\t\texepath = realpath(\"/proc/curproc/file\", NULL); /* FreeBSD (Should be covered above) */\n#endif\n\t} while (0);\n\n\tif (exepath) {\n\t\t/* Strip executable file name, leaving path */\n\t\t*strrchr(exepath, '/') = '\\0';\n\t} else {\n\t\tLOG_WARNING(\"Could not determine executable path, using configured BINDIR.\");\n\t\tLOG_DEBUG(\"BINDIR = %s\", BINDIR);\n#ifdef HAVE_REALPATH\n\t\texepath = realpath(BINDIR, NULL);\n#else\n\t\texepath = strdup(BINDIR);\n#endif\n\t}\n\n\treturn exepath;\n}\n\nstatic char *find_relative_path(const char *from, const char *to)\n{\n\tsize_t i;\n\n\t/* Skip common /-separated parts of from and to */\n\ti = 0;\n\tfor (size_t n = 0; from[n] == to[n]; n++) {\n\t\tif (from[n] == '\\0') {\n\t\t\ti = n;\n\t\t\tbreak;\n\t\t}\n\t\tif (from[n] == '/')\n\t\t\ti = n + 1;\n\t}\n\tfrom += i;\n\tto += i;\n\n\t/* Count number of /-separated non-empty parts of from */\n\ti = 0;\n\twhile (from[0] != '\\0') {\n\t\tif (from[0] != '/')\n\t\t\ti++;\n\t\tchar *next = strchr(from, '/');\n\t\tif (!next)\n\t\t\tbreak;\n\t\tfrom = next + 1;\n\t}\n\n\t/* Prepend that number of ../ in front of to */\n\tchar *relpath = malloc(i * 3 + strlen(to) + 1);\n\trelpath[0] = '\\0';\n\tfor (size_t n = 0; n < i; n++)\n\t\tstrcat(relpath, \"../\");\n\tstrcat(relpath, to);\n\n\treturn relpath;\n}\n\nstatic void add_user_dirs(void)\n{\n\tchar *path;\n\n#if IS_WIN32\n\tconst char *appdata = getenv(\"APPDATA\");\n\n\tif (appdata) {\n\t\tpath = alloc_printf(\"%s/OpenOCD\", appdata);\n\t\tif (path) {\n\t\t\t/* Convert path separators to UNIX style, should work on Windows also. */\n\t\t\tfor (char *p = path; *p; p++) {\n\t\t\t\tif (*p == '\\\\')\n\t\t\t\t\t*p = '/';\n\t\t\t}\n\t\t\tadd_script_search_dir(path);\n\t\t\tfree(path);\n\t\t}\n\t}\n\t/* WIN32 may also have HOME defined, particularly under Cygwin, so add those paths below too */\n#endif\n\n\tconst char *home = getenv(\"HOME\");\n#if IS_DARWIN\n\tif (home) {\n\t\tpath = alloc_printf(\"%s/Library/Preferences/org.openocd\", home);\n\t\tif (path) {\n\t\t\tadd_script_search_dir(path);\n\t\t\tfree(path);\n\t\t}\n\t}\n#endif\n\tconst char *xdg_config = getenv(\"XDG_CONFIG_HOME\");\n\n\tif (xdg_config) {\n\t\tpath = alloc_printf(\"%s/openocd\", xdg_config);\n\t\tif (path) {\n\t\t\tadd_script_search_dir(path);\n\t\t\tfree(path);\n\t\t}\n\t} else if (home) {\n\t\tpath = alloc_printf(\"%s/.config/openocd\", home);\n\t\tif (path) {\n\t\t\tadd_script_search_dir(path);\n\t\t\tfree(path);\n\t\t}\n\t}\n\n\tif (home) {\n\t\tpath = alloc_printf(\"%s/.openocd\", home);\n\t\tif (path) {\n\t\t\tadd_script_search_dir(path);\n\t\t\tfree(path);\n\t\t}\n\t}\n}\n\nstatic void add_default_dirs(void)\n{\n\tchar *path;\n\tchar *exepath = find_exe_path();\n\tchar *bin2data = find_relative_path(BINDIR, PKGDATADIR);\n\n\tLOG_DEBUG(\"bindir=%s\", BINDIR);\n\tLOG_DEBUG(\"pkgdatadir=%s\", PKGDATADIR);\n\tLOG_DEBUG(\"exepath=%s\", exepath);\n\tLOG_DEBUG(\"bin2data=%s\", bin2data);\n\n\t/*\n\t * The directory containing OpenOCD-supplied scripts should be\n\t * listed last in the built-in search order, so the user can\n\t * override these scripts with site-specific customizations.\n\t */\n\tpath = getenv(\"OPENOCD_SCRIPTS\");\n\tif (path)\n\t\tadd_script_search_dir(path);\n\n\tadd_user_dirs();\n\n\tpath = alloc_printf(\"%s/%s/%s\", exepath, bin2data, \"site\");\n\tif (path) {\n\t\tadd_script_search_dir(path);\n\t\tfree(path);\n\t}\n\n\tpath = alloc_printf(\"%s/%s/%s\", exepath, bin2data, \"scripts\");\n\tif (path) {\n\t\tadd_script_search_dir(path);\n\t\tfree(path);\n\t}\n\n\tfree(exepath);\n\tfree(bin2data);\n}\n\nint parse_cmdline_args(struct command_context *cmd_ctx, int argc, char *argv[])\n{\n\tint c;\n\n\twhile (1) {\n\t\t/* getopt_long stores the option index here. */\n\t\tint option_index = 0;\n\n\t\tc = getopt_long(argc, argv, \"hvd::l:f:s:c:\", long_options, &option_index);\n\n\t\t/* Detect the end of the options. */\n\t\tif (c == -1)\n\t\t\tbreak;\n\n\t\tswitch (c) {\n\t\t\tcase 0:\n\t\t\t\tbreak;\n\t\t\tcase 'h':\t\t/* --help | -h */\n\t\t\t\thelp_flag = 1;\n\t\t\t\tbreak;\n\t\t\tcase 'v':\t\t/* --version | -v */\n\t\t\t\tversion_flag = 1;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\t\t/* --file | -f */\n\t\t\t{\n\t\t\t\tchar *command = alloc_printf(\"script {%s}\", optarg);\n\t\t\t\tadd_config_command(command);\n\t\t\t\tfree(command);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 's':\t\t/* --search | -s */\n\t\t\t\tadd_script_search_dir(optarg);\n\t\t\t\tbreak;\n\t\t\tcase 'd':\t\t/* --debug | -d */\n\t\t\t{\n\t\t\t\tint retval = command_run_linef(cmd_ctx, \"debug_level %s\", optarg ? optarg : \"3\");\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'l':\t\t/* --log_output | -l */\n\t\t\t\tif (optarg)\n\t\t\t\t\tcommand_run_linef(cmd_ctx, \"log_output %s\", optarg);\n\t\t\t\tbreak;\n\t\t\tcase 'c':\t\t/* --command | -c */\n\t\t\t\tif (optarg)\n\t\t\t\t    add_config_command(optarg);\n\t\t\t\tbreak;\n\t\t\tdefault:  /* '?' */\n\t\t\t\t/* getopt will emit an error message, all we have to do is bail. */\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (optind < argc) {\n\t\t/* Catch extra arguments on the command line. */\n\t\tLOG_OUTPUT(\"Unexpected command line argument: %s\\n\", argv[optind]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (help_flag) {\n\t\tLOG_OUTPUT(\"Open On-Chip Debugger\\nLicensed under GNU GPL v2\\n\");\n\t\tLOG_OUTPUT(\"--help       | -h\\tdisplay this help\\n\");\n\t\tLOG_OUTPUT(\"--version    | -v\\tdisplay OpenOCD version\\n\");\n\t\tLOG_OUTPUT(\"--file       | -f\\tuse configuration file <name>\\n\");\n\t\tLOG_OUTPUT(\"--search     | -s\\tdir to search for config files and scripts\\n\");\n\t\tLOG_OUTPUT(\"--debug      | -d\\tset debug level to 3\\n\");\n\t\tLOG_OUTPUT(\"             | -d<n>\\tset debug level to <level>\\n\");\n\t\tLOG_OUTPUT(\"--log_output | -l\\tredirect log output to file <name>\\n\");\n\t\tLOG_OUTPUT(\"--command    | -c\\trun <command>\\n\");\n\t\texit(-1);\n\t}\n\n\tif (version_flag) {\n\t\t/* Nothing to do, version gets printed automatically. */\n\t\t/* It is not an error to request the VERSION number. */\n\t\texit(0);\n\t}\n\n\t/* paths specified on the command line take precedence over these\n\t * built-in paths\n\t */\n\tadd_default_dirs();\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/replacements.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* define IN_REPLACEMENTS_C before include replacements.h */\n#define IN_REPLACEMENTS_C\n#include \"replacements.h\"\n\n#include <stdlib.h>\n#include <string.h>\n\n/*\n * clear_malloc\n *\n * will alloc memory and clear it\n */\nvoid *clear_malloc(size_t size)\n{\n\tvoid *t = malloc(size);\n\tif (t)\n\t\tmemset(t, 0x00, size);\n\treturn t;\n}\n\nvoid *fill_malloc(size_t size)\n{\n\tvoid *t = malloc(size);\n\tif (t) {\n\t\t/* We want to initialize memory to some known bad state.\n\t\t * 0 and 0xff yields 0 and -1 as integers, which often\n\t\t * have meaningful values. 0x5555... is not often a valid\n\t\t * integer and is quite easily spotted in the debugger\n\t\t * also it is almost certainly an invalid address */\n\t\tmemset(t, 0x55, size);\n\t}\n\treturn t;\n}\n\n#ifdef HAVE_STRINGS_H\n#include <strings.h>\n#endif\n\n#ifdef _WIN32\n#include <io.h>\n#include <winsock2.h>\n#endif\n\n/* replacements for gettimeofday */\n#ifndef HAVE_GETTIMEOFDAY\n\n/* Windows */\n#ifdef _WIN32\n\n#ifndef __GNUC__\n#define EPOCHFILETIME (116444736000000000i64)\n#else\n#define EPOCHFILETIME (116444736000000000LL)\n#endif\n\nint gettimeofday(struct timeval *tv, struct timezone *tz)\n{\n\tFILETIME ft;\n\tLARGE_INTEGER li;\n\t__int64 t;\n\tstatic int tzflag;\n\n\tif (tv) {\n\t\tGetSystemTimeAsFileTime(&ft);\n\t\tli.LowPart  = ft.dwLowDateTime;\n\t\tli.HighPart = ft.dwHighDateTime;\n\t\tt  = li.QuadPart;\t\t\t\t\t/* In 100-nanosecond intervals */\n\t\tt -= EPOCHFILETIME;\t\t\t\t\t/* Offset to the Epoch time */\n\t\tt /= 10;\t\t\t\t\t\t\t/* In microseconds */\n\t\ttv->tv_sec  = (long)(t / 1000000);\n\t\ttv->tv_usec = (long)(t % 1000000);\n\t}\n\n\tif (tz) {\n\t\tif (!tzflag) {\n\t\t\t_tzset();\n\t\t\ttzflag++;\n\t\t}\n\t\ttz->tz_minuteswest = _timezone / 60;\n\t\ttz->tz_dsttime = _daylight;\n\t}\n\n\treturn 0;\n}\n#endif\t/* _WIN32 */\n\n#endif\t/* HAVE_GETTIMEOFDAY */\n\n#ifndef HAVE_STRNLEN\nsize_t strnlen(const char *s, size_t maxlen)\n{\n\tconst char *end = (const char *)memchr(s, '\\0', maxlen);\n\treturn end ? (size_t) (end - s) : maxlen;\n}\n#endif\n\n#ifndef HAVE_STRNDUP\nchar *strndup(const char *s, size_t n)\n{\n\tsize_t len = strnlen(s, n);\n\tchar *new = malloc(len + 1);\n\n\tif (!new)\n\t\treturn NULL;\n\n\tnew[len] = '\\0';\n\treturn (char *) memcpy(new, s, len);\n}\n#endif\n\n#ifdef _WIN32\nint win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)\n{\n\tDWORD ms_total, limit;\n\tHANDLE handles[MAXIMUM_WAIT_OBJECTS];\n\tint handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];\n\tint n_handles = 0, i;\n\tfd_set sock_read, sock_write, sock_except;\n\tfd_set aread, awrite, aexcept;\n\tint sock_max_fd = -1;\n\tstruct timeval tvslice;\n\tint retcode;\n\n#define SAFE_FD_ISSET(fd, set)  (set && FD_ISSET(fd, set))\n\n\t/* calculate how long we need to wait in milliseconds */\n\tif (!tv)\n\t\tms_total = INFINITE;\n\telse {\n\t\tms_total = tv->tv_sec * 1000;\n\t\tms_total += tv->tv_usec / 1000;\n\t}\n\n\tFD_ZERO(&sock_read);\n\tFD_ZERO(&sock_write);\n\tFD_ZERO(&sock_except);\n\n\t/* build an array of handles for non-sockets */\n\tfor (i = 0; i < max_fd; i++) {\n\t\tif (SAFE_FD_ISSET(i, rfds) || SAFE_FD_ISSET(i, wfds) || SAFE_FD_ISSET(i, efds)) {\n\t\t\tintptr_t handle = (intptr_t) _get_osfhandle(i);\n\t\t\thandles[n_handles] = (HANDLE)handle;\n\t\t\tif (handles[n_handles] == INVALID_HANDLE_VALUE) {\n\t\t\t\t/* socket */\n\t\t\t\tif (SAFE_FD_ISSET(i, rfds))\n\t\t\t\t\tFD_SET(i, &sock_read);\n\t\t\t\tif (SAFE_FD_ISSET(i, wfds))\n\t\t\t\t\tFD_SET(i, &sock_write);\n\t\t\t\tif (SAFE_FD_ISSET(i, efds))\n\t\t\t\t\tFD_SET(i, &sock_except);\n\t\t\t\tif (i > sock_max_fd)\n\t\t\t\t\tsock_max_fd = i;\n\t\t\t} else {\n\t\t\t\thandle_slot_to_fd[n_handles] = i;\n\t\t\t\tn_handles++;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (n_handles == 0) {\n\t\t/* plain sockets only - let winsock handle the whole thing */\n\t\treturn select(max_fd, rfds, wfds, efds, tv);\n\t}\n\n\t/* mixture of handles and sockets; lets multiplex between\n\t * winsock and waiting on the handles */\n\n\tFD_ZERO(&aread);\n\tFD_ZERO(&awrite);\n\tFD_ZERO(&aexcept);\n\n\tlimit = GetTickCount() + ms_total;\n\tdo {\n\t\tretcode = 0;\n\n\t\tif (sock_max_fd >= 0) {\n\t\t\t/* overwrite the zero'd sets here; the select call\n\t\t\t * will clear those that are not active */\n\t\t\taread = sock_read;\n\t\t\tawrite = sock_write;\n\t\t\taexcept = sock_except;\n\n\t\t\ttvslice.tv_sec = 0;\n\t\t\ttvslice.tv_usec = 1000;\n\n\t\t\tretcode = select(sock_max_fd + 1, &aread, &awrite, &aexcept, &tvslice);\n\t\t}\n\n\t\tif (n_handles > 0) {\n\t\t\t/* check handles */\n\t\t\tDWORD wret;\n\n\t\t\twret = MsgWaitForMultipleObjects(n_handles,\n\t\t\t\t\thandles,\n\t\t\t\t\tFALSE,\n\t\t\t\t\tretcode > 0 ? 0 : 1,\n\t\t\t\t\tQS_ALLEVENTS);\n\n\t\t\tif (wret == WAIT_TIMEOUT) {\n\t\t\t\t/* set retcode to 0; this is the default.\n\t\t\t\t * select() may have set it to something else,\n\t\t\t\t * in which case we leave it alone, so this branch\n\t\t\t\t * does nothing */\n\t\t\t\t;\n\t\t\t} else if (wret == WAIT_FAILED) {\n\t\t\t\tif (retcode == 0)\n\t\t\t\t\tretcode = -1;\n\t\t\t} else {\n\t\t\t\tif (retcode < 0)\n\t\t\t\t\tretcode = 0;\n\t\t\t\tfor (i = 0; i < n_handles; i++) {\n\t\t\t\t\tif (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0) {\n\t\t\t\t\t\tif (SAFE_FD_ISSET(handle_slot_to_fd[i], rfds)) {\n\t\t\t\t\t\t\tDWORD bytes;\n\t\t\t\t\t\t\tintptr_t handle = (intptr_t) _get_osfhandle(\n\t\t\t\t\t\t\t\t\thandle_slot_to_fd[i]);\n\n\t\t\t\t\t\t\tif (PeekNamedPipe((HANDLE)handle, NULL, 0,\n\t\t\t\t\t\t\t\t    NULL, &bytes, NULL)) {\n\t\t\t\t\t\t\t\t/* check to see if gdb pipe has data available */\n\t\t\t\t\t\t\t\tif (bytes) {\n\t\t\t\t\t\t\t\t\tFD_SET(handle_slot_to_fd[i], &aread);\n\t\t\t\t\t\t\t\t\tretcode++;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tFD_SET(handle_slot_to_fd[i], &aread);\n\t\t\t\t\t\t\t\tretcode++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (SAFE_FD_ISSET(handle_slot_to_fd[i], wfds)) {\n\t\t\t\t\t\t\tFD_SET(handle_slot_to_fd[i], &awrite);\n\t\t\t\t\t\t\tretcode++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (SAFE_FD_ISSET(handle_slot_to_fd[i], efds)) {\n\t\t\t\t\t\t\tFD_SET(handle_slot_to_fd[i], &aexcept);\n\t\t\t\t\t\t\tretcode++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));\n\n\tif (rfds)\n\t\t*rfds = aread;\n\tif (wfds)\n\t\t*wfds = awrite;\n\tif (efds)\n\t\t*efds = aexcept;\n\n\treturn retcode;\n}\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/replacements.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_REPLACEMENTS_H\n#define OPENOCD_HELPER_REPLACEMENTS_H\n\n#include <stdint.h>\n#include <helper/system.h>\n\n/* MIN,MAX macros */\n#ifndef MIN\n#define MIN(a, b) (((a) < (b)) ? (a) : (b))\n#endif\n#ifndef MAX\n#define MAX(a, b) (((a) > (b)) ? (a) : (b))\n#endif\n\n/* for systems that do not support ENOTSUP\n * win32 being one of them */\n#ifndef ENOTSUP\n#define ENOTSUP 134\t\t/* Not supported */\n#endif\n\n/* for systems that do not support O_BINARY\n * linux being one of them */\n#ifndef O_BINARY\n#define O_BINARY 0\n#endif\n\n#ifndef HAVE_SYS_TIME_H\n\n#ifndef _TIMEVAL_DEFINED\n#define _TIMEVAL_DEFINED\n\nstruct timeval {\n\tlong tv_sec;\n\tlong tv_usec;\n};\n\n#endif\t/* _TIMEVAL_DEFINED */\n\n#endif\n\n/* gettimeofday() */\n#ifndef HAVE_GETTIMEOFDAY\n\n#ifdef _WIN32\nstruct timezone {\n\tint tz_minuteswest;\n\tint tz_dsttime;\n};\n#endif\nstruct timezone;\n\nint gettimeofday(struct timeval *tv, struct timezone *tz);\n\n#endif\n\nvoid *clear_malloc(size_t size);\nvoid *fill_malloc(size_t size);\n\n#ifndef IN_REPLACEMENTS_C\n/*\n * Now you have 3 ways for the malloc function:\n *\n * 1. Do not change anything, use the original malloc\n *\n * 2. Use the clear_malloc function instead of the original malloc.\n *    In this case you must use the following define:\n *    #define malloc((_a)) clear_malloc((_a))\n *\n * 3. Use the fill_malloc function instead of the original malloc.\n *    In this case you must use the following define:\n *    #define malloc((_a)) fill_malloc((_a))\n *\n * We have figured out that there could exist some malloc problems\n * where variables are using without to be initialise. To find this\n * places, use the fill_malloc function. With this function we want\n * to initialize memory to some known bad state. This is quite easily\n * spotted in the debugger and will trap to an invalid address.\n *\n * clear_malloc can be used if you want to set not initialise\n * variable to 0.\n *\n * If you do not want to change the malloc function, to not use one of\n * the following macros. Which is the default way.\n */\n\n/* #define malloc(_a) clear_malloc(_a)\n * #define malloc(_a) fill_malloc(_a) */\n#endif  /* IN_REPLACEMENTS_C */\n\n/* GNU extensions to the C library that may be missing on some systems */\n#ifndef HAVE_STRNDUP\nchar *strndup(const char *s, size_t n);\n#endif\t/* HAVE_STRNDUP */\n\n#ifndef HAVE_STRNLEN\nsize_t strnlen(const char *s, size_t maxlen);\n#endif\t/* HAVE_STRNLEN */\n\n#ifndef HAVE_USLEEP\n#ifdef _WIN32\nstatic inline unsigned usleep(unsigned int usecs)\n{\n\tSleep((usecs/1000));\n\treturn 0;\n}\n#else\n#error no usleep defined for your platform\n#endif\n#endif\t/* HAVE_USLEEP */\n\n/* Windows specific */\n#ifdef _WIN32\n\n#include <windows.h>\n#include <time.h>\n\n/* Windows does not declare sockaddr_un */\n#define UNIX_PATH_LEN 108\nstruct sockaddr_un {\n\tuint16_t sun_family;\n\tchar sun_path[UNIX_PATH_LEN];\n};\n\n/* win32 systems do not support ETIMEDOUT */\n\n#ifndef ETIMEDOUT\n#define ETIMEDOUT WSAETIMEDOUT\n#endif\n\n#if IS_MINGW == 1\nstatic inline unsigned char inb(unsigned short int port)\n{\n\tunsigned char _v;\n\t__asm__ __volatile__ (\"inb %w1,%0\" : \"=a\" (_v) : \"Nd\" (port));\n\treturn _v;\n}\n\nstatic inline void outb(unsigned char value, unsigned short int port)\n{\n\t__asm__ __volatile__ (\"outb %b0,%w1\" : : \"a\" (value), \"Nd\" (port));\n}\n\n/* mingw does not have ffs, so use gcc builtin types */\n#define ffs __builtin_ffs\n\n#endif\t/* IS_MINGW */\n\nint win_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv);\n\n#endif\t/* _WIN32 */\n\n/* generic socket functions for Windows and Posix */\nstatic inline int write_socket(int handle, const void *buffer, unsigned int count)\n{\n#ifdef _WIN32\n\treturn send(handle, buffer, count, 0);\n#else\n\treturn write(handle, buffer, count);\n#endif\n}\n\nstatic inline int read_socket(int handle, void *buffer, unsigned int count)\n{\n#ifdef _WIN32\n\treturn recv(handle, buffer, count, 0);\n#else\n\treturn read(handle, buffer, count);\n#endif\n}\n\nstatic inline int close_socket(int sock)\n{\n#ifdef _WIN32\n\treturn closesocket(sock);\n#else\n\treturn close(sock);\n#endif\n}\n\nstatic inline void socket_block(int fd)\n{\n#ifdef _WIN32\n\tunsigned long nonblock = 0;\n\tioctlsocket(fd, FIONBIO, &nonblock);\n#else\n\tint oldopts = fcntl(fd, F_GETFL, 0);\n\tfcntl(fd, F_SETFL, oldopts & ~O_NONBLOCK);\n#endif\n}\n\nstatic inline void socket_nonblock(int fd)\n{\n#ifdef _WIN32\n\tunsigned long nonblock = 1;\n\tioctlsocket(fd, FIONBIO, &nonblock);\n#else\n\tint oldopts = fcntl(fd, F_GETFL, 0);\n\tfcntl(fd, F_SETFL, oldopts | O_NONBLOCK);\n#endif\n}\n\nstatic inline int socket_select(int max_fd,\n\tfd_set *rfds,\n\tfd_set *wfds,\n\tfd_set *efds,\n\tstruct timeval *tv)\n{\n#ifdef _WIN32\n\treturn win_select(max_fd, rfds, wfds, efds, tv);\n#else\n\treturn select(max_fd, rfds, wfds, efds, tv);\n#endif\n}\n\n#ifndef HAVE_ELF_H\n\ntypedef uint32_t Elf32_Addr;\ntypedef uint16_t Elf32_Half;\ntypedef uint32_t Elf32_Off;\ntypedef uint32_t Elf32_Word;\ntypedef uint32_t Elf32_Size;\n\n#define EI_NIDENT   16\n\ntypedef struct {\n\tunsigned char e_ident[EI_NIDENT];\t/* Magic number and other info */\n\tElf32_Half e_type;\t\t\t/* Object file type */\n\tElf32_Half e_machine;\t\t\t/* Architecture */\n\tElf32_Word e_version;\t\t\t/* Object file version */\n\tElf32_Addr e_entry;\t\t\t/* Entry point virtual address */\n\tElf32_Off e_phoff;\t\t\t/* Program header table file offset */\n\tElf32_Off e_shoff;\t\t\t/* Section header table file offset */\n\tElf32_Word e_flags;\t\t\t/* Processor-specific flags */\n\tElf32_Half e_ehsize;\t\t\t/* ELF header size in bytes */\n\tElf32_Half e_phentsize;\t\t/* Program header table entry size */\n\tElf32_Half e_phnum;\t\t\t/* Program header table entry count */\n\tElf32_Half e_shentsize;\t\t/* Section header table entry size */\n\tElf32_Half e_shnum;\t\t\t/* Section header table entry count */\n\tElf32_Half e_shstrndx;\t\t\t/* Section header string table index */\n} Elf32_Ehdr;\n\n#define ELFMAG\t\t\t\"\\177ELF\"\n#define SELFMAG\t\t\t4\n\n#define EI_CLASS\t\t4\t\t/* File class byte index */\n#define ELFCLASS32\t\t1\t\t/* 32-bit objects */\n#define ELFCLASS64\t\t2\t\t/* 64-bit objects */\n\n#define EI_DATA\t\t\t5\t\t/* Data encoding byte index */\n#define ELFDATA2LSB\t\t1\t\t/* 2's complement, little endian */\n#define ELFDATA2MSB\t\t2\t\t/* 2's complement, big endian */\n\ntypedef struct {\n\tElf32_Word p_type;\t\t/* Segment type */\n\tElf32_Off p_offset;\t\t/* Segment file offset */\n\tElf32_Addr p_vaddr;\t\t/* Segment virtual address */\n\tElf32_Addr p_paddr;\t\t/* Segment physical address */\n\tElf32_Size p_filesz;\t/* Segment size in file */\n\tElf32_Size p_memsz;\t\t/* Segment size in memory */\n\tElf32_Word p_flags;\t\t/* Segment flags */\n\tElf32_Size p_align;\t\t/* Segment alignment */\n} Elf32_Phdr;\n\n#define PT_LOAD\t\t\t1\t\t/* Loadable program segment */\n\n#endif\t/* HAVE_ELF_H */\n\n#ifndef HAVE_ELF64\n\ntypedef uint64_t Elf64_Addr;\ntypedef uint16_t Elf64_Half;\ntypedef uint64_t Elf64_Off;\ntypedef uint32_t Elf64_Word;\ntypedef uint64_t Elf64_Xword;\n\ntypedef struct {\n\tunsigned char e_ident[EI_NIDENT];\t/* Magic number and other info */\n\tElf64_Half e_type;\t\t\t/* Object file type */\n\tElf64_Half e_machine;\t\t/* Architecture */\n\tElf64_Word e_version;\t\t/* Object file version */\n\tElf64_Addr e_entry;\t\t\t/* Entry point virtual address */\n\tElf64_Off e_phoff;\t\t\t/* Program header table file offset */\n\tElf64_Off e_shoff;\t\t\t/* Section header table file offset */\n\tElf64_Word e_flags;\t\t\t/* Processor-specific flags */\n\tElf64_Half e_ehsize;\t\t/* ELF header size in bytes */\n\tElf64_Half e_phentsize;\t\t/* Program header table entry size */\n\tElf64_Half e_phnum;\t\t\t/* Program header table entry count */\n\tElf64_Half e_shentsize;\t\t/* Section header table entry size */\n\tElf64_Half e_shnum;\t\t\t/* Section header table entry count */\n\tElf64_Half e_shstrndx;\t\t/* Section header string table index */\n} Elf64_Ehdr;\n\ntypedef struct {\n\tElf64_Word p_type;\t\t/* Segment type */\n\tElf64_Word p_flags;\t\t/* Segment flags */\n\tElf64_Off p_offset;\t\t/* Segment file offset */\n\tElf64_Addr p_vaddr;\t\t/* Segment virtual address */\n\tElf64_Addr p_paddr;\t\t/* Segment physical address */\n\tElf64_Xword p_filesz;\t/* Segment size in file */\n\tElf64_Xword p_memsz;\t/* Segment size in memory */\n\tElf64_Xword p_align;\t/* Segment alignment */\n} Elf64_Phdr;\n\n#endif /* HAVE_ELF64 */\n\n#endif /* OPENOCD_HELPER_REPLACEMENTS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/startup.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Defines basic Tcl procs that must exist for OpenOCD scripts to work.\n#\n# Embedded into OpenOCD executable\n#\n\n# Try flipping / and \\ to find file if the filename does not\n# match the precise spelling\nproc find {filename} {\n\tif {[catch {ocd_find $filename} t]==0} {\n\t\treturn $t\n\t}\n\tif {[catch {ocd_find [string map {\\ /} $filename} t]==0} {\n\t\treturn $t\n\t}\n\tif {[catch {ocd_find [string map {/ \\\\} $filename} t]==0} {\n\t\treturn $t\n\t}\n\t# make sure error message matches original input string\n\treturn -code error \"Can't find $filename\"\n}\nadd_usage_text find \"<file>\"\nadd_help_text find \"print full path to file according to OpenOCD search rules\"\n\n# Find and run a script\nproc script {filename} {\n\tuplevel #0 [list source [find $filename]]\n}\nadd_help_text script \"filename of OpenOCD script (tcl) to run\"\nadd_usage_text script \"<file>\"\n\n# Run a list of post-init commands\n# Each command should be added with 'lappend post_init_commands command'\nlappend _telnet_autocomplete_skip _run_post_init_commands\nproc _run_post_init_commands {} {\n\tif {[info exists ::post_init_commands]} {\n\t\tforeach cmd $::post_init_commands {\n\t\t\teval $cmd\n\t\t}\n\t}\n}\n\n# Run a list of pre-shutdown commands\n# Each command should be added with 'lappend pre_shutdown_commands command'\nlappend _telnet_autocomplete_skip _run_pre_shutdown_commands\nproc _run_pre_shutdown_commands {} {\n\tif {[info exists ::pre_shutdown_commands]} {\n\t\tforeach cmd $::pre_shutdown_commands {\n\t\t\teval $cmd\n\t\t}\n\t}\n}\n\n#########\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/system.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007-2008 by Øyvind Harboe <oyvind.harboe@zylin.com>    *\n *   Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>           *\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_SYSTEM_H\n#define OPENOCD_HELPER_SYSTEM_H\n\n/* +++ platform specific headers +++ */\n#ifdef _WIN32\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#endif\n/* --- platform specific headers --- */\n\n/* standard C library header files */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <time.h>\n\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n\n#ifdef HAVE_SYS_SOCKET_H\n#include <sys/socket.h>\n#endif\n#ifdef HAVE_POLL_H\n#include <poll.h>\n#endif\n\n#ifdef __ECOS\n/* missing from eCos */\n#ifndef EFAULT\n#define EFAULT 14\t/* Bad address */\n#endif\n#endif\n\n#ifdef HAVE_NETINET_IN_H\n#include <netinet/in.h>\n#endif\n#ifdef HAVE_SYS_SELECT_H\n#include <sys/select.h>\t/* select, FD_SET and friends (POSIX.1-2001) */\n#endif\n#ifdef HAVE_SYS_PARAM_H\n#include <sys/param.h>\t/* for MIN/MAX macros */\n#endif\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>\n#endif\n#ifdef HAVE_FCNTL_H\n#include <fcntl.h>\n#endif\n\n#ifndef true\n#define true    1\n#define false   0\n#endif\n\n#endif /* OPENOCD_HELPER_SYSTEM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/time_support.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"time_support.h\"\n\n/* calculate difference between two struct timeval values */\nint timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)\n{\n\tif (x->tv_usec < y->tv_usec) {\n\t\tint nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;\n\t\ty->tv_usec -= 1000000 * nsec;\n\t\ty->tv_sec += nsec;\n\t}\n\tif (x->tv_usec - y->tv_usec > 1000000) {\n\t\tint nsec = (x->tv_usec - y->tv_usec) / 1000000;\n\t\ty->tv_usec += 1000000 * nsec;\n\t\ty->tv_sec -= nsec;\n\t}\n\n\tresult->tv_sec = x->tv_sec - y->tv_sec;\n\tresult->tv_usec = x->tv_usec - y->tv_usec;\n\n\t/* Return 1 if result is negative. */\n\treturn x->tv_sec < y->tv_sec;\n}\n\nint timeval_add_time(struct timeval *result, long sec, long usec)\n{\n\tresult->tv_sec += sec;\n\tresult->tv_usec += usec;\n\n\twhile (result->tv_usec > 1000000) {\n\t\tresult->tv_usec -= 1000000;\n\t\tresult->tv_sec++;\n\t}\n\n\treturn 0;\n}\n\n/* compare two timevals and return -1/0/+1 accordingly */\nint timeval_compare(const struct timeval *x, const struct timeval *y)\n{\n\tif (x->tv_sec < y->tv_sec)\n\t\treturn -1;\n\telse if (x->tv_sec > y->tv_sec)\n\t\treturn 1;\n\telse if (x->tv_usec < y->tv_usec)\n\t\treturn -1;\n\telse if (x->tv_usec > y->tv_usec)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n\nint duration_start(struct duration *duration)\n{\n\treturn gettimeofday(&duration->start, NULL);\n}\n\nint duration_measure(struct duration *duration)\n{\n\tstruct timeval end;\n\tint retval = gettimeofday(&end, NULL);\n\tif (retval == 0)\n\t\ttimeval_subtract(&duration->elapsed, &end, &duration->start);\n\treturn retval;\n}\n\nfloat duration_elapsed(const struct duration *duration)\n{\n\tfloat t = duration->elapsed.tv_sec;\n\tt += (float)duration->elapsed.tv_usec / 1000000.0;\n\treturn t;\n}\n\nfloat duration_kbps(const struct duration *duration, size_t count)\n{\n\treturn count / (1024.0 * duration_elapsed(duration));\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/time_support.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_TIME_SUPPORT_H\n#define OPENOCD_HELPER_TIME_SUPPORT_H\n\n#include <time.h>\n#include \"types.h\"\n\n#ifdef HAVE_SYS_TIME_H\n#include <sys/time.h>\n#endif\n\nint timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);\nint timeval_add_time(struct timeval *result, long sec, long usec);\nint timeval_compare(const struct timeval *x, const struct timeval *y);\n\n/** @returns gettimeofday() timeval as 64-bit in ms */\nint64_t timeval_ms(void);\n\nstruct duration {\n\tstruct timeval start;\n\tstruct timeval elapsed;\n};\n\n/** Update the duration->start field to start the @a duration measurement. */\nint duration_start(struct duration *duration);\n/** Update the duration->elapsed field to finish the @a duration measurement. */\nint duration_measure(struct duration *duration);\n\n/** @returns Elapsed time in seconds. */\nfloat duration_elapsed(const struct duration *duration);\n/** @returns KB/sec for the elapsed @a duration and @a count bytes. */\nfloat duration_kbps(const struct duration *duration, size_t count);\n\n#endif /* OPENOCD_HELPER_TIME_SUPPORT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/time_support_common.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"time_support.h\"\n\n/* simple and low overhead fetching of ms counter. Use only\n * the difference between ms counters returned from this fn.\n */\nint64_t timeval_ms(void)\n{\n\tstruct timeval now;\n\tint retval = gettimeofday(&now, NULL);\n\tif (retval < 0)\n\t\treturn retval;\n\treturn (int64_t)now.tv_sec * 1000 + now.tv_usec / 1000;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/types.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2004, 2005 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_TYPES_H\n#define OPENOCD_HELPER_TYPES_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stddef.h>\n#include <assert.h>\n#ifdef HAVE_SYS_TYPES_H\n#include <sys/types.h>\n#endif\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n#ifdef HAVE_INTTYPES_H\n#include <inttypes.h>\n#endif\n\n#ifdef HAVE_STDBOOL_H\n#include <stdbool.h>\n#else\t/* HAVE_STDBOOL_H */\n#define __bool_true_false_are_defined 1\n\n#ifndef HAVE__BOOL\n#ifndef __cplusplus\n\n#define false\t0\n#define true\t1\n\n#endif\t/* __cplusplus */\n#endif\t/* HAVE__BOOL */\n#endif\t/* HAVE_STDBOOL_H */\n\n/// turns a macro argument into a string constant\n#define stringify(s) __stringify(s)\n#define __stringify(s) #s\n\n\n/**\n * Compute the number of elements of a variable length array.\n * <code>\n * const char *strs[] = { \"a\", \"b\", \"c\" };\n * unsigned num_strs = ARRAY_SIZE(strs);\n * </code>\n */\n#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))\n\n\n/**\n * Cast a member of a structure out to the containing structure.\n * @param ptr The pointer to the member.\n * @param type The type of the container struct this is embedded in.\n * @param member The name of the member within the struct.\n *\n * This is a mechanism which is used throughout the Linux kernel.\n */\n#define container_of(ptr, type, member) ({\t\t\t\\\n\tconst typeof( ((type *)0)->member ) *__mptr = (ptr);\t\\\n\t(type *)( (void *) ( (char *)__mptr - offsetof(type,member) ) );})\n\n\n/**\n * Rounds @c m up to the nearest multiple of @c n using division.\n * @param m The value to round up to @c n.\n * @param n Round @c m up to a multiple of this number.\n * @returns The rounded integer value.\n */\n#define DIV_ROUND_UP(m, n)\t(((m) + (n) - 1) / (n))\n\n\n/* DANGER!!!! here be dragons!\n *\n * Leave these fn's as byte accesses because it is safe\n * across architectures. Clever usage of 32 bit access\n * will create problems on some hosts.\n *\n * Note that the \"buf\" pointer in memory is probably unaligned.\n *\n * Were these functions to be re-written to take a 32 bit wide or 16 bit wide\n * memory access shortcut, then on some CPU's, i.e. ARM7, the 2 lsbytes of the address are\n * ignored for 32 bit access, whereas on other CPU's a 32 bit wide unaligned memory access\n * will cause an exception, and lastly on x86, an unaligned \"greater than bytewide\"\n * memory access works as if aligned.  So what follows below will work for all\n * platforms and gives the compiler leeway to do its own platform specific optimizations.\n *\n * Again, note that the \"buf\" pointer in memory is probably unaligned.\n */\n\nstatic inline uint64_t le_to_h_u64(const uint8_t *buf)\n{\n\treturn (uint64_t)((uint64_t)buf[0] |\n\t\t\t  (uint64_t)buf[1] << 8 |\n\t\t\t  (uint64_t)buf[2] << 16 |\n\t\t\t  (uint64_t)buf[3] << 24 |\n\t\t\t  (uint64_t)buf[4] << 32 |\n\t\t\t  (uint64_t)buf[5] << 40 |\n\t\t\t  (uint64_t)buf[6] << 48 |\n\t\t\t  (uint64_t)buf[7] << 56);\n}\n\nstatic inline uint32_t le_to_h_u32(const uint8_t *buf)\n{\n\treturn (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24);\n}\n\nstatic inline uint32_t le_to_h_u24(const uint8_t *buf)\n{\n\treturn (uint32_t)((uint32_t)buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16);\n}\n\nstatic inline uint16_t le_to_h_u16(const uint8_t *buf)\n{\n\treturn (uint16_t)((uint16_t)buf[0] | (uint16_t)buf[1] << 8);\n}\n\nstatic inline uint64_t be_to_h_u64(const uint8_t *buf)\n{\n\treturn (uint64_t)((uint64_t)buf[7] |\n\t\t\t  (uint64_t)buf[6] << 8 |\n\t\t\t  (uint64_t)buf[5] << 16 |\n\t\t\t  (uint64_t)buf[4] << 24 |\n\t\t\t  (uint64_t)buf[3] << 32 |\n\t\t\t  (uint64_t)buf[2] << 40 |\n\t\t\t  (uint64_t)buf[1] << 48 |\n\t\t\t  (uint64_t)buf[0] << 56);\n}\n\nstatic inline uint32_t be_to_h_u32(const uint8_t *buf)\n{\n\treturn (uint32_t)((uint32_t)buf[3] | (uint32_t)buf[2] << 8 | (uint32_t)buf[1] << 16 | (uint32_t)buf[0] << 24);\n}\n\nstatic inline uint32_t be_to_h_u24(const uint8_t *buf)\n{\n\treturn (uint32_t)((uint32_t)buf[2] | (uint32_t)buf[1] << 8 | (uint32_t)buf[0] << 16);\n}\n\nstatic inline uint16_t be_to_h_u16(const uint8_t *buf)\n{\n\treturn (uint16_t)((uint16_t)buf[1] | (uint16_t)buf[0] << 8);\n}\n\nstatic inline void h_u64_to_le(uint8_t *buf, uint64_t val)\n{\n\tbuf[7] = (uint8_t) (val >> 56);\n\tbuf[6] = (uint8_t) (val >> 48);\n\tbuf[5] = (uint8_t) (val >> 40);\n\tbuf[4] = (uint8_t) (val >> 32);\n\tbuf[3] = (uint8_t) (val >> 24);\n\tbuf[2] = (uint8_t) (val >> 16);\n\tbuf[1] = (uint8_t) (val >> 8);\n\tbuf[0] = (uint8_t) (val >> 0);\n}\n\nstatic inline void h_u64_to_be(uint8_t *buf, uint64_t val)\n{\n\tbuf[0] = (uint8_t) (val >> 56);\n\tbuf[1] = (uint8_t) (val >> 48);\n\tbuf[2] = (uint8_t) (val >> 40);\n\tbuf[3] = (uint8_t) (val >> 32);\n\tbuf[4] = (uint8_t) (val >> 24);\n\tbuf[5] = (uint8_t) (val >> 16);\n\tbuf[6] = (uint8_t) (val >> 8);\n\tbuf[7] = (uint8_t) (val >> 0);\n}\n\nstatic inline void h_u32_to_le(uint8_t *buf, uint32_t val)\n{\n\tbuf[3] = (val >> 24) & 0xff;\n\tbuf[2] = (val >> 16) & 0xff;\n\tbuf[1] = (val >> 8) & 0xff;\n\tbuf[0] = (val >> 0) & 0xff;\n}\n\nstatic inline void h_u32_to_be(uint8_t *buf, uint32_t val)\n{\n\tbuf[0] = (val >> 24) & 0xff;\n\tbuf[1] = (val >> 16) & 0xff;\n\tbuf[2] = (val >> 8) & 0xff;\n\tbuf[3] = (val >> 0) & 0xff;\n}\n\nstatic inline void h_u24_to_le(uint8_t *buf, unsigned int val)\n{\n\tbuf[2] = (val >> 16) & 0xff;\n\tbuf[1] = (val >> 8) & 0xff;\n\tbuf[0] = (val >> 0) & 0xff;\n}\n\nstatic inline void h_u24_to_be(uint8_t *buf, unsigned int val)\n{\n\tbuf[0] = (val >> 16) & 0xff;\n\tbuf[1] = (val >> 8) & 0xff;\n\tbuf[2] = (val >> 0) & 0xff;\n}\n\nstatic inline void h_u16_to_le(uint8_t *buf, uint16_t val)\n{\n\tbuf[1] = (val >> 8) & 0xff;\n\tbuf[0] = (val >> 0) & 0xff;\n}\n\nstatic inline void h_u16_to_be(uint8_t *buf, uint16_t val)\n{\n\tbuf[0] = (val >> 8) & 0xff;\n\tbuf[1] = (val >> 0) & 0xff;\n}\n\n/**\n * Byte-swap buffer 16-bit.\n *\n * Len must be even, dst and src must be either the same or non-overlapping.\n *\n * @param dst Destination buffer.\n * @param src Source buffer.\n * @param len Length of source (and destination) buffer, in bytes.\n */\nstatic inline void buf_bswap16(uint8_t *dst, const uint8_t *src, size_t len)\n{\n\tassert(len % 2 == 0);\n\tassert(dst == src || dst + len <= src || src + len <= dst);\n\n\tfor (size_t n = 0; n < len; n += 2) {\n\t\tuint16_t x = be_to_h_u16(src + n);\n\t\th_u16_to_le(dst + n, x);\n\t}\n}\n\n/**\n * Byte-swap buffer 32-bit.\n *\n * Len must be divisible by four, dst and src must be either the same or non-overlapping.\n *\n * @param dst Destination buffer.\n * @param src Source buffer.\n * @param len Length of source (and destination) buffer, in bytes.\n */\nstatic inline void buf_bswap32(uint8_t *dst, const uint8_t *src, size_t len)\n{\n\tassert(len % 4 == 0);\n\tassert(dst == src || dst + len <= src || src + len <= dst);\n\n\tfor (size_t n = 0; n < len; n += 4) {\n\t\tuint32_t x = be_to_h_u32(src + n);\n\t\th_u32_to_le(dst + n, x);\n\t}\n}\n\n/**\n * Calculate the (even) parity of a 32-bit datum.\n * @param x The datum.\n * @return 1 if the number of set bits in x is odd, 0 if it is even.\n */\nstatic inline int parity_u32(uint32_t x)\n{\n#ifdef __GNUC__\n\treturn __builtin_parityl(x);\n#else\n\tx ^= x >> 16;\n\tx ^= x >> 8;\n\tx ^= x >> 4;\n\tx ^= x >> 2;\n\tx ^= x >> 1;\n\treturn x & 1;\n#endif\n}\n\n#if defined(__ECOS)\n\n/* eCos plain lacks these definition... A series of upstream patches\n * could probably repair it, but it seems like too much work to be\n * worth it.\n */\n\n#if !defined(_STDINT_H)\n#define PRId32 \"d\"\n#define PRIi32 \"i\"\n#define PRIo32 \"o\"\n#define PRIu32 \"u\"\n#define PRIx32 \"x\"\n#define PRIX32 \"X\"\n#define SCNx32 \"x\"\n#define PRId8 PRId32\n#define SCNx64 \"llx\"\n#define PRId64 \"lld\"\n#define PRIi64 \"lli\"\n#define PRIo64 \"llo\"\n#define PRIu64 \"llu\"\n#define PRIx64 \"llx\"\n#define PRIX64 \"llX\"\n\ntypedef CYG_ADDRWORD intptr_t;\ntypedef int64_t intmax_t;\ntypedef uint64_t uintmax_t;\n#define INT8_MAX 0x7f\n#define INT8_MIN (-INT8_MAX - 1)\n# define UINT8_MAX\t\t(255)\n#define INT16_MAX 0x7fff\n#define INT16_MIN (-INT16_MAX - 1)\n# define UINT16_MAX\t\t(65535)\n#define INT32_MAX 0x7fffffffL\n#define INT32_MIN (-INT32_MAX - 1L)\n# define UINT32_MAX\t\t(4294967295U)\n#define INT64_MAX 0x7fffffffffffffffLL\n#define INT64_MIN (-INT64_MAX - 1LL)\n#define UINT64_MAX (__CONCAT(INT64_MAX, U) * 2ULL + 1ULL)\n#endif\n\n\t#ifndef LLONG_MAX\n\t#define ULLONG_MAX\tUINT64_C(0xFFFFFFFFFFFFFFFF)\n\t#define LLONG_MAX\tINT64_C(0x7FFFFFFFFFFFFFFF)\n\t#define LLONG_MIN\tULLONG_MAX\n\t#endif\n\n\n#define ULLONG_MAX 18446744073709551615\n\n/* C99, eCos is C90 compliant (with bits of C99) */\n#define isblank(c) ((c) == ' ' || (c) == '\\t')\n\n\n#endif\n\ntypedef uint64_t target_addr_t;\n#define TARGET_ADDR_MAX UINT64_MAX\n#define TARGET_PRIdADDR PRId64\n#define TARGET_PRIuADDR PRIu64\n#define TARGET_PRIoADDR PRIo64\n#define TARGET_PRIxADDR PRIx64\n#define TARGET_PRIXADDR PRIX64\n#define TARGET_ADDR_FMT \"0x%8.8\" TARGET_PRIxADDR\n\n#endif /* OPENOCD_HELPER_TYPES_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/update_jep106.pl",
    "content": "#!/usr/bin/perl\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nuse strict;\nuse warnings;\nuse File::Basename;\n\nif (@ARGV != 1) {\n\tdie \"Usage: $0 <JEP106 PDF document>\\n\\n\"\n\t. \"Convert the JEDEC document containing manufacturer identification codes\\n\"\n\t. \"to an array initializer suitable for inclusion into jep106.c. The latest\\n\"\n\t. \"version of the document can be found here:\\n\"\n\t. \"http://www.jedec.org/standards-documents/results/jep106\\n\";\n};\n\nmy $outfile = dirname($0) . \"/jep106.inc\";\n\nopen(my $out, \">\", $outfile) || die \"Cannot open $outfile: $!\\n\";\nopen(my $pdftotext, \"pdftotext -layout $ARGV[0] - |\") || die \"Cannot fork: $!\\n\";\n\nprint $out \"/* Autogenerated with \" . basename($0) . \"*/\\n\";\n\nmy $bank = -1;\n\nwhile (<$pdftotext>) {\n\tif (/^[0-9]+[[:space:]]+(.*?)[[:space:]]+([01][[:space:]]+){8}([0-9A-F]{2})$/) {\n\t\tif ($3 eq \"01\") {\n\t\t\t$bank++\n\t\t}\n\t\tmy $id=sprintf(\"0x%02x\",hex($3)&0x7f);\n\t\tprint $out \"[$bank][$id - 1] = \\\"$1\\\",\\n\";\n\t}\n}\n\nclose $pdftotext || die \"Error: $! $?\\n\";\n\nprint $out \"/* EOF */\\n\";\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/util.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Øyvind Harboe                                   *\n ***************************************************************************/\n\n/* this file contains various functionality useful to standalone systems */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"log.h\"\n#include \"time_support.h\"\n#include \"util.h\"\n\nCOMMAND_HANDLER(handler_util_ms)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"%\" PRId64, timeval_ms());\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration util_command_handlers[] = {\n\t{\n\t\t.name = \"ms\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handler_util_ms,\n\t\t.help =\n\t\t\t\"Returns ever increasing milliseconds. Used to calculate differences in time.\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint util_init(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, util_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/helper/util.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Øyvind Harboe                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_HELPER_UTIL_H\n#define OPENOCD_HELPER_UTIL_H\n\nstruct command_context;\n\nint util_init(struct command_context *cmd_ctx);\n\n#endif /* OPENOCD_HELPER_UTIL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libjtag.la\n\n%C%_libjtag_la_LIBADD =\n\nif HLADAPTER\ninclude %D%/hla/Makefile.am\n%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/hla/libocdhla.la\nendif\n\ninclude %D%/drivers/Makefile.am\n%C%_libjtag_la_LIBADD += $(top_builddir)/%D%/drivers/libocdjtagdrivers.la\n\n%C%_libjtag_la_SOURCES = \\\n\t%D%/adapter.c \\\n\t%D%/adapter.h \\\n\t%D%/commands.c \\\n\t%D%/core.c \\\n\t%D%/interface.c \\\n\t%D%/interfaces.c \\\n\t%D%/tcl.c \\\n\t%D%/swim.c \\\n\t%D%/commands.h \\\n\t%D%/interface.h \\\n\t%D%/interfaces.h \\\n\t%D%/minidriver.h \\\n\t%D%/jtag.h \\\n\t%D%/swd.h \\\n\t%D%/swim.h \\\n\t%D%/tcl.h\n\nSTARTUP_TCL_SRCS += %D%/startup.tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/adapter.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n/*\n * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>\n * Copyright (C) 2007-2010 Øyvind Harboe <oyvind.harboe@zylin.com>\n * Copyright (C) 2009 SoftPLC Corporation, http://softplc.com, Dick Hollenbeck <dick@softplc.com>\n * Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>\n * Copyright (C) 2018 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"adapter.h\"\n#include \"jtag.h\"\n#include \"minidriver.h\"\n#include \"interface.h\"\n#include \"interfaces.h\"\n#include <transport/transport.h>\n\n/**\n * @file\n * Holds support for configuring debug adapters from TCl scripts.\n */\n\nstruct adapter_driver *adapter_driver;\nconst char * const jtag_only[] = { \"jtag\", NULL };\n\nenum adapter_clk_mode {\n\tCLOCK_MODE_UNSELECTED = 0,\n\tCLOCK_MODE_KHZ,\n\tCLOCK_MODE_RCLK\n};\n\n#define DEFAULT_CLOCK_SPEED_KHZ\t\t100U\n\n/**\n * Adapter configuration\n */\nstatic struct {\n\tbool adapter_initialized;\n\tchar *usb_location;\n\tchar *serial;\n\tenum adapter_clk_mode clock_mode;\n\tint speed_khz;\n\tint rclk_fallback_speed_khz;\n\tstruct adapter_gpio_config gpios[ADAPTER_GPIO_IDX_NUM];\n\tbool gpios_initialized; /* Initialization of GPIOs to their unset values performed at run time */\n} adapter_config;\n\nstatic const struct gpio_map {\n\tconst char *name;\n\tenum adapter_gpio_direction direction;\n\tbool permit_drive_option;\n\tbool permit_init_state_option;\n} gpio_map[ADAPTER_GPIO_IDX_NUM] = {\n\t[ADAPTER_GPIO_IDX_TDO] = { \"tdo\", ADAPTER_GPIO_DIRECTION_INPUT, false, true, },\n\t[ADAPTER_GPIO_IDX_TDI] = { \"tdi\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },\n\t[ADAPTER_GPIO_IDX_TMS] = { \"tms\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },\n\t[ADAPTER_GPIO_IDX_TCK] = { \"tck\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },\n\t[ADAPTER_GPIO_IDX_SWDIO] = { \"swdio\", ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL, true, true, },\n\t[ADAPTER_GPIO_IDX_SWDIO_DIR] = { \"swdio_dir\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, false, },\n\t[ADAPTER_GPIO_IDX_SWCLK] = { \"swclk\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },\n\t[ADAPTER_GPIO_IDX_TRST] = { \"trst\", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },\n\t[ADAPTER_GPIO_IDX_SRST] = { \"srst\", ADAPTER_GPIO_DIRECTION_OUTPUT, false, true, },\n\t[ADAPTER_GPIO_IDX_LED] = { \"led\", ADAPTER_GPIO_DIRECTION_OUTPUT, true, true, },\n};\n\nbool is_adapter_initialized(void)\n{\n\treturn adapter_config.adapter_initialized;\n}\n\n/* For convenience of the bit-banging drivers keep the gpio_config drive\n * settings for srst and trst in sync with values set by the \"adapter\n * reset_config\" command.\n */\nstatic void sync_adapter_reset_with_gpios(void)\n{\n\tenum reset_types cfg = jtag_get_reset_config();\n\tif (cfg & RESET_SRST_PUSH_PULL)\n\t\tadapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;\n\telse\n\t\tadapter_config.gpios[ADAPTER_GPIO_IDX_SRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;\n\tif (cfg & RESET_TRST_OPEN_DRAIN)\n\t\tadapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;\n\telse\n\t\tadapter_config.gpios[ADAPTER_GPIO_IDX_TRST].drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;\n}\n\nstatic void adapter_driver_gpios_init(void)\n{\n\tif (adapter_config.gpios_initialized)\n\t\treturn;\n\n\tfor (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {\n\t\tadapter_config.gpios[i].gpio_num = -1;\n\t\tadapter_config.gpios[i].chip_num = -1;\n\t\tif (gpio_map[i].direction == ADAPTER_GPIO_DIRECTION_INPUT)\n\t\t\tadapter_config.gpios[i].init_state = ADAPTER_GPIO_INIT_STATE_INPUT;\n\t}\n\n\t/* Drivers assume active low, and this is the normal behaviour for reset\n\t * lines so should be the default. */\n\tadapter_config.gpios[ADAPTER_GPIO_IDX_SRST].active_low = true;\n\tadapter_config.gpios[ADAPTER_GPIO_IDX_TRST].active_low = true;\n\tsync_adapter_reset_with_gpios();\n\n\t/* JTAG GPIOs should be inactive except for tms */\n\tadapter_config.gpios[ADAPTER_GPIO_IDX_TMS].init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;\n\n\tadapter_config.gpios_initialized = true;\n}\n\n/**\n * Do low-level setup like initializing registers, output signals,\n * and clocking.\n */\nint adapter_init(struct command_context *cmd_ctx)\n{\n\tif (is_adapter_initialized())\n\t\treturn ERROR_OK;\n\n\tif (!adapter_driver) {\n\t\t/* nothing was previously specified by \"adapter driver\" command */\n\t\tLOG_ERROR(\"Debug Adapter has to be specified, \"\n\t\t\t\"see \\\"adapter driver\\\" command\");\n\t\treturn ERROR_JTAG_INVALID_INTERFACE;\n\t}\n\n\tadapter_driver_gpios_init();\n\n\tint retval;\n\n\t/* If the adapter supports configurable speed but the speed is not configured,\n\t * provide a hint to the user. */\n\tif (adapter_driver->speed && adapter_config.clock_mode == CLOCK_MODE_UNSELECTED) {\n\t\tLOG_WARNING(\"An adapter speed is not selected in the init scripts.\"\n\t\t\t\" OpenOCD will try to run the adapter at very low speed (%d kHz).\",\n\t\t\tDEFAULT_CLOCK_SPEED_KHZ);\n\t\tLOG_WARNING(\"To remove this warnings and achieve reasonable communication speed with the target,\"\n\t\t    \" set \\\"adapter speed\\\" or \\\"jtag_rclk\\\" in the init scripts.\");\n\t\tretval = adapter_config_khz(DEFAULT_CLOCK_SPEED_KHZ);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tretval = adapter_driver->init();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tadapter_config.adapter_initialized = true;\n\n\tif (!adapter_driver->speed) {\n\t\tLOG_INFO(\"Note: The adapter \\\"%s\\\" doesn't support configurable speed\", adapter_driver->name);\n\t\treturn ERROR_OK;\n\t}\n\n\tint requested_khz = adapter_get_speed_khz();\n\tint actual_khz = requested_khz;\n\tint speed_var = 0;\n\tretval = adapter_get_speed(&speed_var);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = adapter_driver->speed(speed_var);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = adapter_get_speed_readable(&actual_khz);\n\tif (retval != ERROR_OK)\n\t\tLOG_INFO(\"adapter-specific clock speed value %d\", speed_var);\n\telse if (actual_khz) {\n\t\t/* Adaptive clocking -- JTAG-specific */\n\t\tif ((adapter_config.clock_mode == CLOCK_MODE_RCLK)\n\t\t\t\t|| ((adapter_config.clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) {\n\t\t\tLOG_INFO(\"RCLK (adaptive clock speed) not supported - fallback to %d kHz\"\n\t\t\t, actual_khz);\n\t\t} else\n\t\t\tLOG_INFO(\"clock speed %d kHz\", actual_khz);\n\t} else\n\t\tLOG_INFO(\"RCLK (adaptive clock speed)\");\n\n\treturn ERROR_OK;\n}\n\nint adapter_quit(void)\n{\n\tif (is_adapter_initialized() && adapter_driver->quit) {\n\t\t/* close the JTAG interface */\n\t\tint result = adapter_driver->quit();\n\t\tif (result != ERROR_OK)\n\t\t\tLOG_ERROR(\"failed: %d\", result);\n\t}\n\n\tfree(adapter_config.serial);\n\tfree(adapter_config.usb_location);\n\n\tstruct jtag_tap *t = jtag_all_taps();\n\twhile (t) {\n\t\tstruct jtag_tap *n = t->next_tap;\n\t\tjtag_tap_free(t);\n\t\tt = n;\n\t}\n\n\treturn ERROR_OK;\n}\n\nunsigned int adapter_get_speed_khz(void)\n{\n\treturn adapter_config.speed_khz;\n}\n\nstatic int adapter_khz_to_speed(unsigned int khz, int *speed)\n{\n\tLOG_DEBUG(\"convert khz to adapter specific speed value\");\n\tadapter_config.speed_khz = khz;\n\tif (!is_adapter_initialized())\n\t\treturn ERROR_OK;\n\tLOG_DEBUG(\"have adapter set up\");\n\tif (!adapter_driver->khz) {\n\t\tLOG_ERROR(\"Translation from khz to adapter speed not implemented\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint speed_div1;\n\tint retval = adapter_driver->khz(adapter_get_speed_khz(), &speed_div1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t*speed = speed_div1;\n\treturn ERROR_OK;\n}\n\nstatic int adapter_rclk_to_speed(unsigned int fallback_speed_khz, int *speed)\n{\n\tint retval = adapter_khz_to_speed(0, speed);\n\tif ((retval != ERROR_OK) && fallback_speed_khz) {\n\t\tLOG_DEBUG(\"trying fallback speed...\");\n\t\tretval = adapter_khz_to_speed(fallback_speed_khz, speed);\n\t}\n\treturn retval;\n}\n\nstatic int adapter_set_speed(int speed)\n{\n\t/* this command can be called during CONFIG,\n\t * in which case adapter isn't initialized */\n\treturn is_adapter_initialized() ? adapter_driver->speed(speed) : ERROR_OK;\n}\n\nint adapter_config_khz(unsigned int khz)\n{\n\tLOG_DEBUG(\"handle adapter khz\");\n\tadapter_config.clock_mode = CLOCK_MODE_KHZ;\n\tint speed = 0;\n\tint retval = adapter_khz_to_speed(khz, &speed);\n\treturn (retval != ERROR_OK) ? retval : adapter_set_speed(speed);\n}\n\nint adapter_config_rclk(unsigned int fallback_speed_khz)\n{\n\tLOG_DEBUG(\"handle adapter rclk\");\n\tadapter_config.clock_mode = CLOCK_MODE_RCLK;\n\tadapter_config.rclk_fallback_speed_khz = fallback_speed_khz;\n\tint speed = 0;\n\tint retval = adapter_rclk_to_speed(fallback_speed_khz, &speed);\n\treturn (retval != ERROR_OK) ? retval : adapter_set_speed(speed);\n}\n\nint adapter_get_speed(int *speed)\n{\n\tswitch (adapter_config.clock_mode) {\n\t\tcase CLOCK_MODE_KHZ:\n\t\t\tadapter_khz_to_speed(adapter_get_speed_khz(), speed);\n\t\t\tbreak;\n\t\tcase CLOCK_MODE_RCLK:\n\t\t\tadapter_rclk_to_speed(adapter_config.rclk_fallback_speed_khz, speed);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown adapter clock mode\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nint adapter_get_speed_readable(int *khz)\n{\n\tint speed_var = 0;\n\tint retval = adapter_get_speed(&speed_var);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (!is_adapter_initialized())\n\t\treturn ERROR_OK;\n\tif (!adapter_driver->speed_div) {\n\t\tLOG_ERROR(\"Translation from adapter speed to khz not implemented\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn adapter_driver->speed_div(speed_var, khz);\n}\n\nconst char *adapter_get_required_serial(void)\n{\n\treturn adapter_config.serial;\n}\n\n/*\n * 1 char: bus\n * 2 * 7 chars: max 7 ports\n * 1 char: test for overflow\n * ------\n * 16 chars\n */\n#define USB_MAX_LOCATION_LENGTH         16\n\n#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS\nstatic void adapter_usb_set_location(const char *location)\n{\n\tif (strnlen(location, USB_MAX_LOCATION_LENGTH) == USB_MAX_LOCATION_LENGTH)\n\t\tLOG_WARNING(\"usb location string is too long!!\");\n\n\tfree(adapter_config.usb_location);\n\n\tadapter_config.usb_location = strndup(location, USB_MAX_LOCATION_LENGTH);\n}\n#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */\n\nconst char *adapter_usb_get_location(void)\n{\n\treturn adapter_config.usb_location;\n}\n\nbool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len)\n{\n\tsize_t path_step, string_length;\n\tchar *ptr, *loc;\n\tbool equal = false;\n\n\tif (!adapter_usb_get_location())\n\t\treturn equal;\n\n\t/* strtok need non const char */\n\tloc = strndup(adapter_usb_get_location(), USB_MAX_LOCATION_LENGTH);\n\tstring_length = strnlen(loc, USB_MAX_LOCATION_LENGTH);\n\n\tptr = strtok(loc, \"-\");\n\tif (!ptr) {\n\t\tLOG_WARNING(\"no '-' in usb path\\n\");\n\t\tgoto done;\n\t}\n\n\tstring_length -= strnlen(ptr, string_length);\n\t/* check bus mismatch */\n\tif (atoi(ptr) != dev_bus)\n\t\tgoto done;\n\n\tpath_step = 0;\n\twhile (path_step < path_len) {\n\t\tptr = strtok(NULL, \".\");\n\n\t\t/* no more tokens in path */\n\t\tif (!ptr)\n\t\t\tbreak;\n\n\t\t/* path mismatch at some step */\n\t\tif (path_step < path_len && atoi(ptr) != port_path[path_step])\n\t\t\tbreak;\n\n\t\tpath_step++;\n\t\tstring_length -= strnlen(ptr, string_length) + 1;\n\t};\n\n\t/* walked the full path, all elements match */\n\tif (path_step == path_len && !string_length)\n\t\tequal = true;\n\ndone:\n\tfree(loc);\n\treturn equal;\n}\n\nCOMMAND_HANDLER(handle_adapter_name)\n{\n\t/* return the name of the interface */\n\t/* TCL code might need to know the exact type... */\n\t/* FUTURE: we allow this as a means to \"set\" the interface. */\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"%s\", adapter_driver ? adapter_driver->name : \"undefined\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(adapter_transports_command)\n{\n\tchar **transports;\n\tint retval;\n\n\tretval = CALL_COMMAND_HANDLER(transport_list_parse, &transports);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = allow_transports(CMD_CTX, (const char **)transports);\n\n\tif (retval != ERROR_OK) {\n\t\tfor (unsigned i = 0; transports[i]; i++)\n\t\t\tfree(transports[i]);\n\t\tfree(transports);\n\t}\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_adapter_list_command)\n{\n\tif (strcmp(CMD_NAME, \"list\") == 0 && CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"The following debug adapters are available:\");\n\tfor (unsigned i = 0; adapter_drivers[i]; i++) {\n\t\tconst char *name = adapter_drivers[i]->name;\n\t\tcommand_print(CMD, \"%u: %s\", i + 1, name);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_adapter_driver_command)\n{\n\tint retval;\n\n\t/* check whether the interface is already configured */\n\tif (adapter_driver) {\n\t\tLOG_WARNING(\"Interface already configured, ignoring\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* interface name is a mandatory argument */\n\tif (CMD_ARGC != 1 || CMD_ARGV[0][0] == '\\0')\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned i = 0; adapter_drivers[i]; i++) {\n\t\tif (strcmp(CMD_ARGV[0], adapter_drivers[i]->name) != 0)\n\t\t\tcontinue;\n\n\t\tif (adapter_drivers[i]->commands) {\n\t\t\tretval = register_commands(CMD_CTX, NULL, adapter_drivers[i]->commands);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tadapter_driver = adapter_drivers[i];\n\n\t\treturn allow_transports(CMD_CTX, adapter_driver->transports);\n\t}\n\n\t/* no valid interface was found (i.e. the configuration option,\n\t * didn't match one of the compiled-in interfaces\n\t */\n\tLOG_ERROR(\"The specified debug interface was not found (%s)\",\n\t\t\t\tCMD_ARGV[0]);\n\tCALL_COMMAND_HANDLER(handle_adapter_list_command);\n\treturn ERROR_JTAG_INVALID_INTERFACE;\n}\n\nCOMMAND_HANDLER(handle_reset_config_command)\n{\n\tint new_cfg = 0;\n\tint mask = 0;\n\n\t/* Original versions cared about the order of these tokens:\n\t *   reset_config signals [combination [trst_type [srst_type]]]\n\t * They also clobbered the previous configuration even on error.\n\t *\n\t * Here we don't care about the order, and only change values\n\t * which have been explicitly specified.\n\t */\n\tfor (; CMD_ARGC; CMD_ARGC--, CMD_ARGV++) {\n\t\tint tmp = 0;\n\t\tint m;\n\n\t\t/* gating */\n\t\tm = RESET_SRST_NO_GATING;\n\t\tif (strcmp(*CMD_ARGV, \"srst_gates_jtag\") == 0)\n\t\t\t/* default: don't use JTAG while SRST asserted */;\n\t\telse if (strcmp(*CMD_ARGV, \"srst_nogate\") == 0)\n\t\t\ttmp = RESET_SRST_NO_GATING;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"gating\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* signals */\n\t\tm = RESET_HAS_TRST | RESET_HAS_SRST;\n\t\tif (strcmp(*CMD_ARGV, \"none\") == 0)\n\t\t\ttmp = RESET_NONE;\n\t\telse if (strcmp(*CMD_ARGV, \"trst_only\") == 0)\n\t\t\ttmp = RESET_HAS_TRST;\n\t\telse if (strcmp(*CMD_ARGV, \"srst_only\") == 0)\n\t\t\ttmp = RESET_HAS_SRST;\n\t\telse if (strcmp(*CMD_ARGV, \"trst_and_srst\") == 0)\n\t\t\ttmp = RESET_HAS_TRST | RESET_HAS_SRST;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"signal\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* combination (options for broken wiring) */\n\t\tm = RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;\n\t\tif (strcmp(*CMD_ARGV, \"separate\") == 0)\n\t\t\t/* separate reset lines - default */;\n\t\telse if (strcmp(*CMD_ARGV, \"srst_pulls_trst\") == 0)\n\t\t\ttmp |= RESET_SRST_PULLS_TRST;\n\t\telse if (strcmp(*CMD_ARGV, \"trst_pulls_srst\") == 0)\n\t\t\ttmp |= RESET_TRST_PULLS_SRST;\n\t\telse if (strcmp(*CMD_ARGV, \"combined\") == 0)\n\t\t\ttmp |= RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"combination\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* trst_type (NOP without HAS_TRST) */\n\t\tm = RESET_TRST_OPEN_DRAIN;\n\t\tif (strcmp(*CMD_ARGV, \"trst_open_drain\") == 0)\n\t\t\ttmp |= RESET_TRST_OPEN_DRAIN;\n\t\telse if (strcmp(*CMD_ARGV, \"trst_push_pull\") == 0)\n\t\t\t/* push/pull from adapter - default */;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"trst_type\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* srst_type (NOP without HAS_SRST) */\n\t\tm = RESET_SRST_PUSH_PULL;\n\t\tif (strcmp(*CMD_ARGV, \"srst_push_pull\") == 0)\n\t\t\ttmp |= RESET_SRST_PUSH_PULL;\n\t\telse if (strcmp(*CMD_ARGV, \"srst_open_drain\") == 0)\n\t\t\t/* open drain from adapter - default */;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"srst_type\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* connect_type - only valid when srst_nogate */\n\t\tm = RESET_CNCT_UNDER_SRST;\n\t\tif (strcmp(*CMD_ARGV, \"connect_assert_srst\") == 0)\n\t\t\ttmp |= RESET_CNCT_UNDER_SRST;\n\t\telse if (strcmp(*CMD_ARGV, \"connect_deassert_srst\") == 0)\n\t\t\t/* connect normally - default */;\n\t\telse\n\t\t\tm = 0;\n\t\tif (mask & m) {\n\t\t\tLOG_ERROR(\"extra reset_config %s spec (%s)\",\n\t\t\t\t\t\"connect_type\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif (m)\n\t\t\tgoto next;\n\n\t\t/* caller provided nonsense; fail */\n\t\tLOG_ERROR(\"unknown reset_config flag (%s)\", *CMD_ARGV);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\nnext:\n\t\t/* Remember the bits which were specified (mask)\n\t\t * and their new values (new_cfg).\n\t\t */\n\t\tmask |= m;\n\t\tnew_cfg |= tmp;\n\t}\n\n\t/* clear previous values of those bits, save new values */\n\tif (mask) {\n\t\tint old_cfg = jtag_get_reset_config();\n\n\t\told_cfg &= ~mask;\n\t\tnew_cfg |= old_cfg;\n\t\tjtag_set_reset_config(new_cfg);\n\t\tsync_adapter_reset_with_gpios();\n\n\t} else\n\t\tnew_cfg = jtag_get_reset_config();\n\n\t/*\n\t * Display the (now-)current reset mode\n\t */\n\tchar *modes[6];\n\n\t/* minimal JTAG has neither SRST nor TRST (so that's the default) */\n\tswitch (new_cfg & (RESET_HAS_TRST | RESET_HAS_SRST)) {\n\t\tcase RESET_HAS_SRST:\n\t\t\tmodes[0] = \"srst_only\";\n\t\t\tbreak;\n\t\tcase RESET_HAS_TRST:\n\t\t\tmodes[0] = \"trst_only\";\n\t\t\tbreak;\n\t\tcase RESET_TRST_AND_SRST:\n\t\t\tmodes[0] = \"trst_and_srst\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmodes[0] = \"none\";\n\t\t\tbreak;\n\t}\n\n\t/* normally SRST and TRST are decoupled; but bugs happen ... */\n\tswitch (new_cfg & (RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST)) {\n\t\tcase RESET_SRST_PULLS_TRST:\n\t\t\tmodes[1] = \"srst_pulls_trst\";\n\t\t\tbreak;\n\t\tcase RESET_TRST_PULLS_SRST:\n\t\t\tmodes[1] = \"trst_pulls_srst\";\n\t\t\tbreak;\n\t\tcase RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST:\n\t\t\tmodes[1] = \"combined\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tmodes[1] = \"separate\";\n\t\t\tbreak;\n\t}\n\n\t/* TRST-less connectors include Altera, Xilinx, and minimal JTAG */\n\tif (new_cfg & RESET_HAS_TRST) {\n\t\tif (new_cfg & RESET_TRST_OPEN_DRAIN)\n\t\t\tmodes[3] = \" trst_open_drain\";\n\t\telse\n\t\t\tmodes[3] = \" trst_push_pull\";\n\t} else\n\t\tmodes[3] = \"\";\n\n\t/* SRST-less connectors include TI-14, Xilinx, and minimal JTAG */\n\tif (new_cfg & RESET_HAS_SRST) {\n\t\tif (new_cfg & RESET_SRST_NO_GATING)\n\t\t\tmodes[2] = \" srst_nogate\";\n\t\telse\n\t\t\tmodes[2] = \" srst_gates_jtag\";\n\n\t\tif (new_cfg & RESET_SRST_PUSH_PULL)\n\t\t\tmodes[4] = \" srst_push_pull\";\n\t\telse\n\t\t\tmodes[4] = \" srst_open_drain\";\n\n\t\tif (new_cfg & RESET_CNCT_UNDER_SRST)\n\t\t\tmodes[5] = \" connect_assert_srst\";\n\t\telse\n\t\t\tmodes[5] = \" connect_deassert_srst\";\n\t} else {\n\t\tmodes[2] = \"\";\n\t\tmodes[4] = \"\";\n\t\tmodes[5] = \"\";\n\t}\n\n\tcommand_print(CMD, \"%s %s%s%s%s%s\",\n\t\t\tmodes[0], modes[1],\n\t\t\tmodes[2], modes[3], modes[4], modes[5]);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_adapter_srst_delay_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned delay;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);\n\n\t\tjtag_set_nsrst_delay(delay);\n\t}\n\tcommand_print(CMD, \"adapter srst delay: %u\", jtag_get_nsrst_delay());\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_adapter_srst_pulse_width_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned width;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], width);\n\n\t\tjtag_set_nsrst_assert_width(width);\n\t}\n\tcommand_print(CMD, \"adapter srst pulse_width: %u\", jtag_get_nsrst_assert_width());\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_adapter_speed_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint retval = ERROR_OK;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned khz = 0;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);\n\n\t\tretval = adapter_config_khz(khz);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tint cur_speed = adapter_get_speed_khz();\n\tretval = adapter_get_speed_readable(&cur_speed);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cur_speed)\n\t\tcommand_print(CMD, \"adapter speed: %d kHz\", cur_speed);\n\telse\n\t\tcommand_print(CMD, \"adapter speed: RCLK - adaptive\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_adapter_serial_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfree(adapter_config.serial);\n\tadapter_config.serial = strdup(CMD_ARGV[0]);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_adapter_reset_de_assert)\n{\n\tenum values {\n\t\tVALUE_UNDEFINED = -1,\n\t\tVALUE_DEASSERT  = 0,\n\t\tVALUE_ASSERT    = 1,\n\t};\n\tenum values value;\n\tenum values srst = VALUE_UNDEFINED;\n\tenum values trst = VALUE_UNDEFINED;\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tchar *signal;\n\n\tif (CMD_ARGC == 0) {\n\t\tif (transport_is_jtag()) {\n\t\t\tif (jtag_reset_config & RESET_HAS_TRST)\n\t\t\t\tsignal = jtag_get_trst() ? \"asserted\" : \"deasserted\";\n\t\t\telse\n\t\t\t\tsignal = \"not present\";\n\t\t\tcommand_print(CMD, \"trst %s\", signal);\n\t\t}\n\n\t\tif (jtag_reset_config & RESET_HAS_SRST)\n\t\t\tsignal = jtag_get_srst() ? \"asserted\" : \"deasserted\";\n\t\telse\n\t\t\tsignal = \"not present\";\n\t\tcommand_print(CMD, \"srst %s\", signal);\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC != 1 && CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tvalue = (strcmp(CMD_NAME, \"assert\") == 0) ? VALUE_ASSERT : VALUE_DEASSERT;\n\tif (strcmp(CMD_ARGV[0], \"srst\") == 0)\n\t\tsrst = value;\n\telse if (strcmp(CMD_ARGV[0], \"trst\") == 0)\n\t\ttrst = value;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 3) {\n\t\tif (strcmp(CMD_ARGV[1], \"assert\") == 0)\n\t\t\tvalue = VALUE_ASSERT;\n\t\telse if (strcmp(CMD_ARGV[1], \"deassert\") == 0)\n\t\t\tvalue = VALUE_DEASSERT;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tif (strcmp(CMD_ARGV[2], \"srst\") == 0 && srst == VALUE_UNDEFINED)\n\t\t\tsrst = value;\n\t\telse if (strcmp(CMD_ARGV[2], \"trst\") == 0 && trst == VALUE_UNDEFINED)\n\t\t\ttrst = value;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (trst == VALUE_UNDEFINED) {\n\t\tif (transport_is_jtag())\n\t\t\ttrst = jtag_get_trst() ? VALUE_ASSERT : VALUE_DEASSERT;\n\t\telse\n\t\t\ttrst = VALUE_DEASSERT; /* unused, safe value */\n\t}\n\n\tif (srst == VALUE_UNDEFINED) {\n\t\tif (jtag_reset_config & RESET_HAS_SRST)\n\t\t\tsrst = jtag_get_srst() ? VALUE_ASSERT : VALUE_DEASSERT;\n\t\telse\n\t\t\tsrst = VALUE_DEASSERT; /* unused, safe value */\n\t}\n\n\tif (trst == VALUE_ASSERT && !transport_is_jtag()) {\n\t\tLOG_ERROR(\"transport has no trst signal\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (srst == VALUE_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {\n\t\tLOG_ERROR(\"adapter has no srst signal\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn adapter_resets((trst == VALUE_DEASSERT) ? TRST_DEASSERT : TRST_ASSERT,\n\t\t\t\t\t\t  (srst == VALUE_DEASSERT) ? SRST_DEASSERT : SRST_ASSERT);\n}\n\nstatic int get_gpio_index(const char *signal_name)\n{\n\tfor (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i) {\n\t\tif (strcmp(gpio_map[i].name, signal_name) == 0)\n\t\t\treturn i;\n\t}\n\treturn -1;\n}\n\nstatic COMMAND_HELPER(helper_adapter_gpio_print_config, enum adapter_gpio_config_index gpio_idx)\n{\n\tstruct adapter_gpio_config *gpio_config = &adapter_config.gpios[gpio_idx];\n\tconst char *active_state = gpio_config->active_low ? \"low\" : \"high\";\n\tconst char *dir = \"\";\n\tconst char *drive = \"\";\n\tconst char *pull = \"\";\n\tconst char *init_state = \"\";\n\n\tswitch (gpio_map[gpio_idx].direction) {\n\tcase ADAPTER_GPIO_DIRECTION_INPUT:\n\t\tdir = \"input\";\n\t\tbreak;\n\tcase ADAPTER_GPIO_DIRECTION_OUTPUT:\n\t\tdir = \"output\";\n\t\tbreak;\n\tcase ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL:\n\t\tdir = \"bidirectional\";\n\t\tbreak;\n\t}\n\n\tif (gpio_map[gpio_idx].permit_drive_option) {\n\t\tswitch (gpio_config->drive) {\n\t\tcase ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:\n\t\t\tdrive = \", push-pull\";\n\t\t\tbreak;\n\t\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:\n\t\t\tdrive = \", open-drain\";\n\t\t\tbreak;\n\t\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:\n\t\t\tdrive = \", open-source\";\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tswitch (gpio_config->pull) {\n\tcase ADAPTER_GPIO_PULL_NONE:\n\t\tpull = \", pull-none\";\n\t\tbreak;\n\tcase ADAPTER_GPIO_PULL_UP:\n\t\tpull = \", pull-up\";\n\t\tbreak;\n\tcase ADAPTER_GPIO_PULL_DOWN:\n\t\tpull = \", pull-down\";\n\t\tbreak;\n\t}\n\n\tif (gpio_map[gpio_idx].permit_init_state_option) {\n\t\tswitch (gpio_config->init_state) {\n\t\tcase ADAPTER_GPIO_INIT_STATE_INACTIVE:\n\t\t\tinit_state = \", init-state inactive\";\n\t\t\tbreak;\n\t\tcase ADAPTER_GPIO_INIT_STATE_ACTIVE:\n\t\t\tinit_state = \", init-state active\";\n\t\t\tbreak;\n\t\tcase ADAPTER_GPIO_INIT_STATE_INPUT:\n\t\t\tinit_state = \", init-state input\";\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"adapter gpio %s (%s): num %d, chip %d, active-%s%s%s%s\",\n\t\tgpio_map[gpio_idx].name, dir, gpio_config->gpio_num, gpio_config->chip_num, active_state,\n\t\tdrive, pull, init_state);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(helper_adapter_gpio_print_all_configs)\n{\n\tfor (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)\n\t\tCALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, i);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(adapter_gpio_config_handler)\n{\n\tunsigned int i = 1;\n\tstruct adapter_gpio_config *gpio_config;\n\n\tadapter_driver_gpios_init();\n\n\tif (CMD_ARGC == 0) {\n\t\tCALL_COMMAND_HANDLER(helper_adapter_gpio_print_all_configs);\n\t\treturn ERROR_OK;\n\t}\n\n\tint gpio_idx = get_gpio_index(CMD_ARGV[0]);\n\tif (gpio_idx == -1) {\n\t\tLOG_ERROR(\"adapter has no gpio named %s\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC == 1) {\n\t\tCALL_COMMAND_HANDLER(helper_adapter_gpio_print_config, gpio_idx);\n\t\treturn ERROR_OK;\n\t}\n\n\tgpio_config = &adapter_config.gpios[gpio_idx];\n\twhile (i < CMD_ARGC) {\n\t\tLOG_DEBUG(\"Processing %s\", CMD_ARGV[i]);\n\n\t\tif (isdigit(*CMD_ARGV[i])) {\n\t\t\tint gpio_num; /* Use a meaningful output parameter for more helpful error messages */\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[i], gpio_num);\n\t\t\tgpio_config->gpio_num = gpio_num;\n\t\t\t++i;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (strcmp(CMD_ARGV[i], \"-chip\") == 0) {\n\t\t\tif (CMD_ARGC - i < 2) {\n\t\t\t\tLOG_ERROR(\"-chip option requires a parameter\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"-chip arg is %s\", CMD_ARGV[i + 1]);\n\t\t\tint chip_num; /* Use a meaningful output parameter for more helpful error messages */\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[i + 1], chip_num);\n\t\t\tgpio_config->chip_num = chip_num;\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (strcmp(CMD_ARGV[i], \"-active-high\") == 0) {\n\t\t\t++i;\n\t\t\tgpio_config->active_low = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (strcmp(CMD_ARGV[i], \"-active-low\") == 0) {\n\t\t\t++i;\n\t\t\tgpio_config->active_low = true;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (gpio_map[gpio_idx].permit_drive_option) {\n\t\t\tif (strcmp(CMD_ARGV[i], \"-push-pull\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (strcmp(CMD_ARGV[i], \"-open-drain\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (strcmp(CMD_ARGV[i], \"-open-source\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->drive = ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (strcmp(CMD_ARGV[i], \"-pull-none\") == 0) {\n\t\t\t++i;\n\t\t\tgpio_config->pull = ADAPTER_GPIO_PULL_NONE;\n\t\t\tcontinue;\n\t\t}\n\t\tif (strcmp(CMD_ARGV[i], \"-pull-up\") == 0) {\n\t\t\t++i;\n\t\t\tgpio_config->pull = ADAPTER_GPIO_PULL_UP;\n\t\t\tcontinue;\n\t\t}\n\t\tif (strcmp(CMD_ARGV[i], \"-pull-down\") == 0) {\n\t\t\t++i;\n\t\t\tgpio_config->pull = ADAPTER_GPIO_PULL_DOWN;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (gpio_map[gpio_idx].permit_init_state_option) {\n\t\t\tif (strcmp(CMD_ARGV[i], \"-init-inactive\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INACTIVE;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (strcmp(CMD_ARGV[i], \"-init-active\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->init_state = ADAPTER_GPIO_INIT_STATE_ACTIVE;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (gpio_map[gpio_idx].direction == ADAPTER_GPIO_DIRECTION_BIDIRECTIONAL &&\n\t\t\t\t\tstrcmp(CMD_ARGV[i], \"-init-input\") == 0) {\n\t\t\t\t++i;\n\t\t\t\tgpio_config->init_state = ADAPTER_GPIO_INIT_STATE_INPUT;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tLOG_ERROR(\"illegal option for adapter %s %s: %s\",\n\t\t\t\tCMD_NAME, gpio_map[gpio_idx].name, CMD_ARGV[i]);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* Force swdio_dir init state to be compatible with swdio init state */\n\tif (gpio_idx == ADAPTER_GPIO_IDX_SWDIO)\n\t\tadapter_config.gpios[ADAPTER_GPIO_IDX_SWDIO_DIR].init_state =\n\t\t(gpio_config->init_state == ADAPTER_GPIO_INIT_STATE_INPUT) ?\n\t\tADAPTER_GPIO_INIT_STATE_INACTIVE :\n\t\tADAPTER_GPIO_INIT_STATE_ACTIVE;\n\n\treturn ERROR_OK;\n}\n\n#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS\nCOMMAND_HANDLER(handle_usb_location_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tadapter_usb_set_location(CMD_ARGV[0]);\n\n\tcommand_print(CMD, \"adapter usb location: %s\", adapter_usb_get_location());\n\n\treturn ERROR_OK;\n}\n#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */\n\nstatic const struct command_registration adapter_usb_command_handlers[] = {\n#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS\n\t{\n\t\t.name = \"location\",\n\t\t.handler = &handle_usb_location_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"display or set the USB bus location of the USB device\",\n\t\t.usage = \"[<bus>-port[.port]...]\",\n\t},\n#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration adapter_srst_command_handlers[] = {\n\t{\n\t\t.name = \"delay\",\n\t\t.handler = handle_adapter_srst_delay_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"delay after deasserting SRST in ms\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"pulse_width\",\n\t\t.handler = handle_adapter_srst_pulse_width_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"SRST assertion pulse width in ms\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration adapter_command_handlers[] = {\n\t{\n\t\t.name = \"driver\",\n\t\t.handler = handle_adapter_driver_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Select a debug adapter driver\",\n\t\t.usage = \"driver_name\",\n\t},\n\t{\n\t\t.name = \"speed\",\n\t\t.handler = handle_adapter_speed_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"With an argument, change to the specified maximum \"\n\t\t\t\"jtag speed.  For JTAG, 0 KHz signifies adaptive \"\n\t\t\t\"clocking. \"\n\t\t\t\"With or without argument, display current setting.\",\n\t\t.usage = \"[khz]\",\n\t},\n\t{\n\t\t.name = \"serial\",\n\t\t.handler = handle_adapter_serial_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set the serial number of the adapter\",\n\t\t.usage = \"serial_string\",\n\t},\n\t{\n\t\t.name = \"list\",\n\t\t.handler = handle_adapter_list_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"List all built-in debug adapter drivers\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"name\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_adapter_name,\n\t\t.help = \"Returns the name of the currently \"\n\t\t\t\"selected adapter (driver)\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"srst\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"srst adapter command group\",\n\t\t.usage = \"\",\n\t\t.chain = adapter_srst_command_handlers,\n\t},\n\t{\n\t\t.name = \"transports\",\n\t\t.handler = adapter_transports_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Declare transports the adapter supports.\",\n\t\t.usage = \"transport ...\",\n\t},\n\t{\n\t\t.name = \"usb\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"usb adapter command group\",\n\t\t.usage = \"\",\n\t\t.chain = adapter_usb_command_handlers,\n\t},\n\t{\n\t\t.name = \"assert\",\n\t\t.handler = handle_adapter_reset_de_assert,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Controls SRST and TRST lines.\",\n\t\t.usage = \"|deassert [srst|trst [assert|deassert srst|trst]]\",\n\t},\n\t{\n\t\t.name = \"deassert\",\n\t\t.handler = handle_adapter_reset_de_assert,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Controls SRST and TRST lines.\",\n\t\t.usage = \"|assert [srst|trst [deassert|assert srst|trst]]\",\n\t},\n\t{\n\t\t.name = \"gpio\",\n\t\t.handler = adapter_gpio_config_handler,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio adapter command group\",\n\t\t.usage = \"[ tdo|tdi|tms|tck|trst|swdio|swdio_dir|swclk|srst|led\"\n\t\t\t\"[gpio_number] \"\n\t\t\t\"[-chip chip_number] \"\n\t\t\t\"[-active-high|-active-low] \"\n\t\t\t\"[-push-pull|-open-drain|-open-source] \"\n\t\t\t\"[-pull-none|-pull-up|-pull-down]\"\n\t\t\t\"[-init-inactive|-init-active|-init-input] ]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration interface_command_handlers[] = {\n\t{\n\t\t.name = \"adapter\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"adapter command group\",\n\t\t.usage = \"\",\n\t\t.chain = adapter_command_handlers,\n\t},\n\t{\n\t\t.name = \"reset_config\",\n\t\t.handler = handle_reset_config_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure adapter reset behavior\",\n\t\t.usage = \"[none|trst_only|srst_only|trst_and_srst] \"\n\t\t\t\"[srst_pulls_trst|trst_pulls_srst|combined|separate] \"\n\t\t\t\"[srst_gates_jtag|srst_nogate] \"\n\t\t\t\"[trst_push_pull|trst_open_drain] \"\n\t\t\t\"[srst_push_pull|srst_open_drain] \"\n\t\t\t\"[connect_deassert_srst|connect_assert_srst]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/**\n * Register the commands which deal with arbitrary debug adapter drivers.\n *\n * @todo Remove internal assumptions that all debug adapters use JTAG for\n * transport.  Various types and data structures are not named generically.\n */\nint adapter_register_commands(struct command_context *ctx)\n{\n\treturn register_commands(ctx, NULL, interface_command_handlers);\n}\n\nconst char *adapter_gpio_get_name(enum adapter_gpio_config_index idx)\n{\n\treturn gpio_map[idx].name;\n}\n\n/* Allow drivers access to the GPIO configuration */\nconst struct adapter_gpio_config *adapter_gpio_get_config(void)\n{\n\treturn adapter_config.gpios;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/adapter.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/*\n * Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>\n * Copyright (c) 2018 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>\n */\n\n#ifndef OPENOCD_JTAG_ADAPTER_H\n#define OPENOCD_JTAG_ADAPTER_H\n\n#include <stdbool.h>\n#include <stddef.h>\n#include <stdint.h>\n\n/** Supported output drive modes for adaptor GPIO */\nenum adapter_gpio_drive_mode {\n\tADAPTER_GPIO_DRIVE_MODE_PUSH_PULL,\n\tADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN,\n\tADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE,\n};\n\n/** Supported GPIO directions */\nenum adapter_gpio_direction {\n\tADAPTER_GPIO_DIRECTION_INPUT,\n\tADAPTER_GPIO_DIRECTION_OUTPUT,\n\tADAPTER_GPIO_DIRECTION_BIDIRECTIONAL,\n};\n\n/** Supported initial states for GPIO */\nenum adapter_gpio_init_state {\n\tADAPTER_GPIO_INIT_STATE_INACTIVE, /* Should be zero so it is the default state */\n\tADAPTER_GPIO_INIT_STATE_ACTIVE,\n\tADAPTER_GPIO_INIT_STATE_INPUT,\n};\n\n/** Supported pull directions for GPIO */\nenum adapter_gpio_pull {\n\tADAPTER_GPIO_PULL_NONE,\n\tADAPTER_GPIO_PULL_UP,\n\tADAPTER_GPIO_PULL_DOWN,\n};\n\n/** Adapter GPIO */\nenum adapter_gpio_config_index {\n\tADAPTER_GPIO_IDX_TDO,\n\tADAPTER_GPIO_IDX_TDI,\n\tADAPTER_GPIO_IDX_TMS,\n\tADAPTER_GPIO_IDX_TCK,\n\tADAPTER_GPIO_IDX_TRST,\n\tADAPTER_GPIO_IDX_SWDIO,\n\tADAPTER_GPIO_IDX_SWDIO_DIR,\n\tADAPTER_GPIO_IDX_SWCLK,\n\tADAPTER_GPIO_IDX_SRST,\n\tADAPTER_GPIO_IDX_LED,\n\tADAPTER_GPIO_IDX_NUM, /* must be the last item */\n};\n\n/** Configuration options for a single GPIO */\nstruct adapter_gpio_config {\n\tint gpio_num;\n\tint chip_num;\n\tenum adapter_gpio_drive_mode drive; /* For outputs only */\n\tenum adapter_gpio_init_state init_state;\n\tbool active_low;\n\tenum adapter_gpio_pull pull;\n};\n\nstruct command_context;\n\n/** Register the adapter's commands */\nint adapter_register_commands(struct command_context *ctx);\n\n/** Initialize debug adapter upon startup.  */\nint adapter_init(struct command_context *cmd_ctx);\n\n/** Shutdown the debug adapter upon program exit. */\nint adapter_quit(void);\n\n/** @returns true if adapter has been initialized */\nbool is_adapter_initialized(void);\n\n/** @returns USB location string set with command 'adapter usb location' */\nconst char *adapter_usb_get_location(void);\n\n/** @returns true if USB location string is \"<dev_bus>-<port_path[0]>[.<port_path[1]>[...]]\" */\nbool adapter_usb_location_equal(uint8_t dev_bus, uint8_t *port_path, size_t path_len);\n\n/** @returns The current adapter speed setting. */\nint adapter_get_speed(int *speed);\n\n/**\n * Given a @a speed setting, use the interface @c speed_div callback to\n * adjust the setting.\n * @param speed The speed setting to convert back to readable kHz.\n * @returns ERROR_OK if the interface has not been initialized or on success;\n *  otherwise, the error code produced by the @c speed_div callback.\n */\nint adapter_get_speed_readable(int *speed);\n\n/** Attempt to configure the adapter for the specified kHz. */\nint adapter_config_khz(unsigned int khz);\n\n/**\n * Attempt to enable RTCK/RCLK. If that fails, fallback to the\n * specified frequency.\n */\nint adapter_config_rclk(unsigned int fallback_speed_khz);\n\n/** Retrieves the clock speed of the adapter in kHz. */\nunsigned int adapter_get_speed_khz(void);\n\n/** Retrieves the serial number set with command 'adapter serial' */\nconst char *adapter_get_required_serial(void);\n\n/**\n * Retrieves gpio name\n */\nconst char *adapter_gpio_get_name(enum adapter_gpio_config_index idx);\n\n/**\n * Retrieves gpio configuration set with command \"adapter gpio <signal_name>\"\n */\nconst struct adapter_gpio_config *adapter_gpio_get_config(void);\n\n#endif /* OPENOCD_JTAG_ADAPTER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/commands.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <transport/transport.h>\n#include \"commands.h\"\n\nstruct cmd_queue_page {\n\tstruct cmd_queue_page *next;\n\tvoid *address;\n\tsize_t used;\n};\n\n#define CMD_QUEUE_PAGE_SIZE (1024 * 1024)\nstatic struct cmd_queue_page *cmd_queue_pages;\nstatic struct cmd_queue_page *cmd_queue_pages_tail;\n\nstruct jtag_command *jtag_command_queue;\nstatic struct jtag_command **next_command_pointer = &jtag_command_queue;\n\nvoid jtag_queue_command(struct jtag_command *cmd)\n{\n\tif (!transport_is_jtag()) {\n\t\t/*\n\t\t * FIXME: This should not happen!\n\t\t * There could be old code that queues jtag commands with non jtag interfaces so, for\n\t\t * the moment simply highlight it by log an error.\n\t\t * We should fix it quitting with assert(0) because it is an internal error, or returning\n\t\t * an error after call to jtag_command_queue_reset() to free the jtag queue and avoid\n\t\t * memory leaks.\n\t\t * The fix can be applied immediately after next release (v0.11.0 ?)\n\t\t */\n\t\tLOG_ERROR(\"JTAG API jtag_queue_command() called on non JTAG interface\");\n\t}\n\n\t/* this command goes on the end, so ensure the queue terminates */\n\tcmd->next = NULL;\n\n\tstruct jtag_command **last_cmd = next_command_pointer;\n\tassert(last_cmd);\n\tassert(!*last_cmd);\n\t*last_cmd = cmd;\n\n\t/* store location where the next command pointer will be stored */\n\tnext_command_pointer = &cmd->next;\n}\n\nvoid *cmd_queue_alloc(size_t size)\n{\n\tstruct cmd_queue_page **p_page = &cmd_queue_pages;\n\tint offset;\n\tuint8_t *t;\n\n\t/*\n\t * WARNING:\n\t *    We align/round the *SIZE* per below\n\t *    so that all pointers returned by\n\t *    this function are reasonably well\n\t *    aligned.\n\t *\n\t * If we did not, then an \"odd-length\" request would cause the\n\t * *next* allocation to be at an *odd* address, and because\n\t * this function has the same type of api as malloc() - we\n\t * must also return pointers that have the same type of\n\t * alignment.\n\t *\n\t * What I do not/have is a reasonable portable means\n\t * to align by...\n\t *\n\t * The solution here, is based on these suggestions.\n\t * http://gcc.gnu.org/ml/gcc-help/2008-12/msg00041.html\n\t *\n\t */\n\tunion worse_case_align {\n\t\tint i;\n\t\tlong l;\n\t\tfloat f;\n\t\tvoid *v;\n\t};\n#define ALIGN_SIZE  (sizeof(union worse_case_align))\n\n\t/* The alignment process. */\n\tsize = (size + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1));\n\t/* Done... */\n\n\tif (*p_page) {\n\t\tp_page = &cmd_queue_pages_tail;\n\t\tif (CMD_QUEUE_PAGE_SIZE - (*p_page)->used < size)\n\t\t\tp_page = &((*p_page)->next);\n\t}\n\n\tif (!*p_page) {\n\t\t*p_page = malloc(sizeof(struct cmd_queue_page));\n\t\t(*p_page)->used = 0;\n\t\tsize_t alloc_size = (size < CMD_QUEUE_PAGE_SIZE) ?\n\t\t\t\t\tCMD_QUEUE_PAGE_SIZE : size;\n\t\t(*p_page)->address = malloc(alloc_size);\n\t\t(*p_page)->next = NULL;\n\t\tcmd_queue_pages_tail = *p_page;\n\t}\n\n\toffset = (*p_page)->used;\n\t(*p_page)->used += size;\n\n\tt = (*p_page)->address;\n\treturn t + offset;\n}\n\nstatic void cmd_queue_free(void)\n{\n\tstruct cmd_queue_page *page = cmd_queue_pages;\n\n\twhile (page) {\n\t\tstruct cmd_queue_page *last = page;\n\t\tfree(page->address);\n\t\tpage = page->next;\n\t\tfree(last);\n\t}\n\n\tcmd_queue_pages = NULL;\n\tcmd_queue_pages_tail = NULL;\n}\n\nvoid jtag_command_queue_reset(void)\n{\n\tcmd_queue_free();\n\n\tjtag_command_queue = NULL;\n\tnext_command_pointer = &jtag_command_queue;\n}\n\n/**\n * Copy a struct scan_field for insertion into the queue.\n *\n * This allocates a new copy of out_value using cmd_queue_alloc.\n */\nvoid jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src)\n{\n\tdst->num_bits\t= src->num_bits;\n\tdst->out_value\t= buf_cpy(src->out_value, cmd_queue_alloc(DIV_ROUND_UP(src->num_bits, 8)), src->num_bits);\n\tdst->in_value\t= src->in_value;\n}\n\nenum scan_type jtag_scan_type(const struct scan_command *cmd)\n{\n\tint i;\n\tint type = 0;\n\n\tfor (i = 0; i < cmd->num_fields; i++) {\n\t\tif (cmd->fields[i].in_value)\n\t\t\ttype |= SCAN_IN;\n\t\tif (cmd->fields[i].out_value)\n\t\t\ttype |= SCAN_OUT;\n\t}\n\n\treturn type;\n}\n\nint jtag_scan_size(const struct scan_command *cmd)\n{\n\tint bit_count = 0;\n\tint i;\n\n\t/* count bits in scan command */\n\tfor (i = 0; i < cmd->num_fields; i++)\n\t\tbit_count += cmd->fields[i].num_bits;\n\n\treturn bit_count;\n}\n\nint jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)\n{\n\tint bit_count = 0;\n\tint i;\n\n\tbit_count = jtag_scan_size(cmd);\n\t*buffer = calloc(1, DIV_ROUND_UP(bit_count, 8));\n\n\tbit_count = 0;\n\n\tLOG_DEBUG_IO(\"%s num_fields: %i\",\n\t\t\tcmd->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\t\tcmd->num_fields);\n\n\tfor (i = 0; i < cmd->num_fields; i++) {\n\t\tif (cmd->fields[i].out_value) {\n\t\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {\n\t\t\t\tchar *char_buf = buf_to_hex_str(cmd->fields[i].out_value,\n\t\t\t\t\t\t(cmd->fields[i].num_bits > DEBUG_JTAG_IOZ)\n\t\t\t\t\t\t? DEBUG_JTAG_IOZ\n\t\t\t\t\t\t\t\t: cmd->fields[i].num_bits);\n\n\t\t\t\tLOG_DEBUG(\"fields[%i].out_value[%i]: 0x%s\", i,\n\t\t\t\t\t\tcmd->fields[i].num_bits, char_buf);\n\t\t\t\tfree(char_buf);\n\t\t\t}\n\t\t\tbuf_set_buf(cmd->fields[i].out_value, 0, *buffer,\n\t\t\t\t\tbit_count, cmd->fields[i].num_bits);\n\t\t} else {\n\t\t\tLOG_DEBUG_IO(\"fields[%i].out_value[%i]: NULL\",\n\t\t\t\t\ti, cmd->fields[i].num_bits);\n\t\t}\n\n\t\tbit_count += cmd->fields[i].num_bits;\n\t}\n\n\t/*LOG_DEBUG_IO(\"bit_count totalling: %i\",  bit_count); */\n\n\treturn bit_count;\n}\n\nint jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)\n{\n\tint i;\n\tint bit_count = 0;\n\tint retval;\n\n\t/* we return ERROR_OK, unless a check fails, or a handler reports a problem */\n\tretval = ERROR_OK;\n\n\tfor (i = 0; i < cmd->num_fields; i++) {\n\t\t/* if neither in_value nor in_handler\n\t\t * are specified we don't have to examine this field\n\t\t */\n\t\tif (cmd->fields[i].in_value) {\n\t\t\tint num_bits = cmd->fields[i].num_bits;\n\t\t\tuint8_t *captured = buf_set_buf(buffer, bit_count,\n\t\t\t\t\tmalloc(DIV_ROUND_UP(num_bits, 8)), 0, num_bits);\n\n\t\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {\n\t\t\t\tchar *char_buf = buf_to_hex_str(captured,\n\t\t\t\t\t\t(num_bits > DEBUG_JTAG_IOZ)\n\t\t\t\t\t\t? DEBUG_JTAG_IOZ\n\t\t\t\t\t\t\t\t: num_bits);\n\n\t\t\t\tLOG_DEBUG(\"fields[%i].in_value[%i]: 0x%s\",\n\t\t\t\t\t\ti, num_bits, char_buf);\n\t\t\t\tfree(char_buf);\n\t\t\t}\n\n\t\t\tif (cmd->fields[i].in_value)\n\t\t\t\tbuf_cpy(captured, cmd->fields[i].in_value, num_bits);\n\n\t\t\tfree(captured);\n\t\t}\n\t\tbit_count += cmd->fields[i].num_bits;\n\t}\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/commands.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_COMMANDS_H\n#define OPENOCD_JTAG_COMMANDS_H\n\n/**\n * The inferred type of a scan_command_s structure, indicating whether\n * the command has the host scan in from the device, the host scan out\n * to the device, or both.\n */\nenum scan_type {\n\t/** From device to host, */\n\tSCAN_IN = 1,\n\t/** From host to device, */\n\tSCAN_OUT = 2,\n\t/** Full-duplex scan. */\n\tSCAN_IO = 3\n};\n\n/**\n * The scan_command provide a means of encapsulating a set of scan_field_s\n * structures that should be scanned in/out to the device.\n */\nstruct scan_command {\n\t/** instruction/not data scan */\n\tbool ir_scan;\n\t/** number of fields in *fields array */\n\tint num_fields;\n\t/** pointer to an array of data scan fields */\n\tstruct scan_field *fields;\n\t/** state in which JTAG commands should finish */\n\ttap_state_t end_state;\n};\n\nstruct statemove_command {\n\t/** state in which JTAG commands should finish */\n\ttap_state_t end_state;\n};\n\nstruct pathmove_command {\n\t/** number of states in *path */\n\tint num_states;\n\t/** states that have to be passed */\n\ttap_state_t *path;\n};\n\nstruct runtest_command {\n\t/** number of cycles to spend in Run-Test/Idle state */\n\tint num_cycles;\n\t/** state in which JTAG commands should finish */\n\ttap_state_t end_state;\n};\n\n\nstruct stableclocks_command {\n\t/** number of clock cycles that should be sent */\n\tint num_cycles;\n};\n\n\nstruct reset_command {\n\t/** Set TRST output: 0 = deassert, 1 = assert, -1 = no change */\n\tint trst;\n\t/** Set SRST output: 0 = deassert, 1 = assert, -1 = no change */\n\tint srst;\n};\n\nstruct end_state_command {\n\t/** state in which JTAG commands should finish */\n\ttap_state_t end_state;\n};\n\nstruct sleep_command {\n\t/** number of microseconds to sleep */\n\tuint32_t us;\n};\n\n/**\n * Encapsulates a series of bits to be clocked out, affecting state\n * and mode of the interface.\n *\n * In JTAG mode these are clocked out on TMS, using TCK.  They may be\n * used for link resets, transitioning between JTAG and SWD modes, or\n * to implement JTAG state machine transitions (implementing pathmove\n * or statemove operations).\n *\n * In SWD mode these are clocked out on SWDIO, using SWCLK, and are\n * used for link resets and transitioning between SWD and JTAG modes.\n */\nstruct tms_command {\n\t/** How many bits should be clocked out. */\n\tunsigned num_bits;\n\t/** The bits to clock out; the LSB is bit 0 of bits[0]. */\n\tconst uint8_t *bits;\n};\n\n/**\n * Defines a container type that hold a pointer to a JTAG command\n * structure of any defined type.\n */\nunion jtag_command_container {\n\tstruct scan_command *scan;\n\tstruct statemove_command *statemove;\n\tstruct pathmove_command *pathmove;\n\tstruct runtest_command *runtest;\n\tstruct stableclocks_command *stableclocks;\n\tstruct reset_command *reset;\n\tstruct end_state_command *end_state;\n\tstruct sleep_command *sleep;\n\tstruct tms_command *tms;\n};\n\n/**\n * The type of the @c jtag_command_container contained by a\n * @c jtag_command_s structure.\n */\nenum jtag_command_type {\n\tJTAG_SCAN         = 1,\n\t/* JTAG_TLR_RESET's non-minidriver implementation is a\n\t * vestige from a statemove cmd. The statemove command\n\t * is obsolete and replaced by pathmove.\n\t *\n\t * pathmove does not support reset as one of it's states,\n\t * hence the need for an explicit statemove command.\n\t */\n\tJTAG_TLR_RESET    = 2,\n\tJTAG_RUNTEST      = 3,\n\tJTAG_RESET        = 4,\n\tJTAG_PATHMOVE     = 6,\n\tJTAG_SLEEP        = 7,\n\tJTAG_STABLECLOCKS = 8,\n\tJTAG_TMS          = 9,\n};\n\nstruct jtag_command {\n\tunion jtag_command_container cmd;\n\tenum jtag_command_type type;\n\tstruct jtag_command *next;\n};\n\n/** The current queue of jtag_command_s structures. */\nextern struct jtag_command *jtag_command_queue;\n\nvoid *cmd_queue_alloc(size_t size);\n\nvoid jtag_queue_command(struct jtag_command *cmd);\nvoid jtag_command_queue_reset(void);\n\nvoid jtag_scan_field_clone(struct scan_field *dst, const struct scan_field *src);\nenum scan_type jtag_scan_type(const struct scan_command *cmd);\nint jtag_scan_size(const struct scan_command *cmd);\nint jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd);\nint jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer);\n\n#endif /* OPENOCD_JTAG_COMMANDS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/core.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n *                                                                         *\n *   Copyright (C) 2007,2008,2009 Øyvind Harboe                            *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"adapter.h\"\n#include \"jtag.h\"\n#include \"swd.h\"\n#include \"interface.h\"\n#include <transport/transport.h>\n#include <helper/jep106.h>\n#include \"helper/system.h\"\n\n#ifdef HAVE_STRINGS_H\n#include <strings.h>\n#endif\n\n/* SVF and XSVF are higher level JTAG command sets (for boundary scan) */\n#include \"svf/svf.h\"\n#include \"xsvf/xsvf.h\"\n\n/* ipdbg are utilities to debug IP-cores. It uses JTAG for transport. */\n#include \"server/ipdbg.h\"\n\n/** The number of JTAG queue flushes (for profiling and debugging purposes). */\nstatic int jtag_flush_queue_count;\n\n/* Sleep this # of ms after flushing the queue */\nstatic int jtag_flush_queue_sleep;\n\nstatic void jtag_add_scan_check(struct jtag_tap *active,\n\t\tvoid (*jtag_add_scan)(struct jtag_tap *active,\n\t\tint in_num_fields,\n\t\tconst struct scan_field *in_fields,\n\t\ttap_state_t state),\n\t\tint in_num_fields, struct scan_field *in_fields, tap_state_t state);\n\n/**\n * The jtag_error variable is set when an error occurs while executing\n * the queue.  Application code may set this using jtag_set_error(),\n * when an error occurs during processing that should be reported during\n * jtag_execute_queue().\n *\n * The value is set and cleared, but never read by normal application code.\n *\n * This value is returned (and cleared) by jtag_execute_queue().\n */\nstatic int jtag_error = ERROR_OK;\n\nstatic const char *jtag_event_strings[] = {\n\t[JTAG_TRST_ASSERTED] = \"TAP reset\",\n\t[JTAG_TAP_EVENT_SETUP] = \"TAP setup\",\n\t[JTAG_TAP_EVENT_ENABLE] = \"TAP enabled\",\n\t[JTAG_TAP_EVENT_DISABLE] = \"TAP disabled\",\n};\n\n/*\n * JTAG adapters must initialize with TRST and SRST de-asserted\n * (they're negative logic, so that means *high*).  But some\n * hardware doesn't necessarily work that way ... so set things\n * up so that jtag_init() always forces that state.\n */\nstatic int jtag_trst = -1;\nstatic int jtag_srst = -1;\n\n/**\n * List all TAPs that have been created.\n */\nstatic struct jtag_tap *__jtag_all_taps;\n\nstatic enum reset_types jtag_reset_config = RESET_NONE;\ntap_state_t cmd_queue_cur_state = TAP_RESET;\n\nstatic bool jtag_verify_capture_ir = true;\nstatic int jtag_verify = 1;\n\n/* how long the OpenOCD should wait before attempting JTAG communication after reset lines\n *deasserted (in ms) */\nstatic int adapter_nsrst_delay;\t/* default to no nSRST delay */\nstatic int jtag_ntrst_delay;/* default to no nTRST delay */\nstatic int adapter_nsrst_assert_width;\t/* width of assertion */\nstatic int jtag_ntrst_assert_width;\t/* width of assertion */\n\n/**\n * Contains a single callback along with a pointer that will be passed\n * when an event occurs.\n */\nstruct jtag_event_callback {\n\t/** a event callback */\n\tjtag_event_handler_t callback;\n\t/** the private data to pass to the callback */\n\tvoid *priv;\n\t/** the next callback */\n\tstruct jtag_event_callback *next;\n};\n\n/* callbacks to inform high-level handlers about JTAG state changes */\nstatic struct jtag_event_callback *jtag_event_callbacks;\n\nextern struct adapter_driver *adapter_driver;\n\nvoid jtag_set_flush_queue_sleep(int ms)\n{\n\tjtag_flush_queue_sleep = ms;\n}\n\nvoid jtag_set_error(int error)\n{\n\tif ((error == ERROR_OK) || (jtag_error != ERROR_OK))\n\t\treturn;\n\tjtag_error = error;\n}\n\nint jtag_error_clear(void)\n{\n\tint temp = jtag_error;\n\tjtag_error = ERROR_OK;\n\treturn temp;\n}\n\n/************/\n\nstatic bool jtag_poll = true;\nstatic bool jtag_poll_en = true;\n\nbool is_jtag_poll_safe(void)\n{\n\t/* Polling can be disabled explicitly with set_enabled(false).\n\t * It can also be masked with mask().\n\t * It is also implicitly disabled while TRST is active and\n\t * while SRST is gating the JTAG clock.\n\t */\n\tif (!jtag_poll_en)\n\t\treturn false;\n\n\tif (!transport_is_jtag())\n\t\treturn jtag_poll;\n\n\tif (!jtag_poll || jtag_trst != 0)\n\t\treturn false;\n\treturn jtag_srst == 0 || (jtag_reset_config & RESET_SRST_NO_GATING);\n}\n\nbool jtag_poll_get_enabled(void)\n{\n\treturn jtag_poll;\n}\n\nvoid jtag_poll_set_enabled(bool value)\n{\n\tjtag_poll = value;\n}\n\nbool jtag_poll_mask(void)\n{\n\tbool retval = jtag_poll_en;\n\tjtag_poll_en = false;\n\treturn retval;\n}\n\nvoid jtag_poll_unmask(bool saved)\n{\n\tjtag_poll_en = saved;\n}\n\n/************/\n\nstruct jtag_tap *jtag_all_taps(void)\n{\n\treturn __jtag_all_taps;\n};\n\nunsigned jtag_tap_count(void)\n{\n\tstruct jtag_tap *t = jtag_all_taps();\n\tunsigned n = 0;\n\twhile (t) {\n\t\tn++;\n\t\tt = t->next_tap;\n\t}\n\treturn n;\n}\n\nunsigned jtag_tap_count_enabled(void)\n{\n\tstruct jtag_tap *t = jtag_all_taps();\n\tunsigned n = 0;\n\twhile (t) {\n\t\tif (t->enabled)\n\t\t\tn++;\n\t\tt = t->next_tap;\n\t}\n\treturn n;\n}\n\n/** Append a new TAP to the chain of all taps. */\nstatic void jtag_tap_add(struct jtag_tap *t)\n{\n\tunsigned jtag_num_taps = 0;\n\n\tstruct jtag_tap **tap = &__jtag_all_taps;\n\twhile (*tap) {\n\t\tjtag_num_taps++;\n\t\ttap = &(*tap)->next_tap;\n\t}\n\t*tap = t;\n\tt->abs_chain_position = jtag_num_taps;\n}\n\n/* returns a pointer to the n-th device in the scan chain */\nstruct jtag_tap *jtag_tap_by_position(unsigned n)\n{\n\tstruct jtag_tap *t = jtag_all_taps();\n\n\twhile (t && n-- > 0)\n\t\tt = t->next_tap;\n\n\treturn t;\n}\n\nstruct jtag_tap *jtag_tap_by_string(const char *s)\n{\n\t/* try by name first */\n\tstruct jtag_tap *t = jtag_all_taps();\n\n\twhile (t) {\n\t\tif (strcmp(t->dotted_name, s) == 0)\n\t\t\treturn t;\n\t\tt = t->next_tap;\n\t}\n\n\t/* no tap found by name, so try to parse the name as a number */\n\tunsigned n;\n\tif (parse_uint(s, &n) != ERROR_OK)\n\t\treturn NULL;\n\n\t/* FIXME remove this numeric fallback code late June 2010, along\n\t * with all info in the User's Guide that TAPs have numeric IDs.\n\t * Also update \"scan_chain\" output to not display the numbers.\n\t */\n\tt = jtag_tap_by_position(n);\n\tif (t)\n\t\tLOG_WARNING(\"Specify TAP '%s' by name, not number %u\",\n\t\t\tt->dotted_name, n);\n\n\treturn t;\n}\n\nstruct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p)\n{\n\tp = p ? p->next_tap : jtag_all_taps();\n\twhile (p) {\n\t\tif (p->enabled)\n\t\t\treturn p;\n\t\tp = p->next_tap;\n\t}\n\treturn NULL;\n}\n\nconst char *jtag_tap_name(const struct jtag_tap *tap)\n{\n\treturn (!tap) ? \"(unknown)\" : tap->dotted_name;\n}\n\n\nint jtag_register_event_callback(jtag_event_handler_t callback, void *priv)\n{\n\tstruct jtag_event_callback **callbacks_p = &jtag_event_callbacks;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (*callbacks_p) {\n\t\twhile ((*callbacks_p)->next)\n\t\t\tcallbacks_p = &((*callbacks_p)->next);\n\t\tcallbacks_p = &((*callbacks_p)->next);\n\t}\n\n\t(*callbacks_p) = malloc(sizeof(struct jtag_event_callback));\n\t(*callbacks_p)->callback = callback;\n\t(*callbacks_p)->priv = priv;\n\t(*callbacks_p)->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nint jtag_unregister_event_callback(jtag_event_handler_t callback, void *priv)\n{\n\tstruct jtag_event_callback **p = &jtag_event_callbacks, *temp;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\twhile (*p) {\n\t\tif (((*p)->priv != priv) || ((*p)->callback != callback)) {\n\t\t\tp = &(*p)->next;\n\t\t\tcontinue;\n\t\t}\n\n\t\ttemp = *p;\n\t\t*p = (*p)->next;\n\t\tfree(temp);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint jtag_call_event_callbacks(enum jtag_event event)\n{\n\tstruct jtag_event_callback *callback = jtag_event_callbacks;\n\n\tLOG_DEBUG(\"jtag event: %s\", jtag_event_strings[event]);\n\n\twhile (callback) {\n\t\tstruct jtag_event_callback *next;\n\n\t\t/* callback may remove itself */\n\t\tnext = callback->next;\n\t\tcallback->callback(event, callback->priv);\n\t\tcallback = next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void jtag_checks(void)\n{\n\tassert(jtag_trst == 0);\n}\n\nstatic void jtag_prelude(tap_state_t state)\n{\n\tjtag_checks();\n\n\tassert(state != TAP_INVALID);\n\n\tcmd_queue_cur_state = state;\n}\n\nvoid jtag_add_ir_scan_noverify(struct jtag_tap *active, const struct scan_field *in_fields,\n\ttap_state_t state)\n{\n\tjtag_prelude(state);\n\n\tint retval = interface_jtag_add_ir_scan(active, in_fields, state);\n\tjtag_set_error(retval);\n}\n\nstatic void jtag_add_ir_scan_noverify_callback(struct jtag_tap *active,\n\tint dummy,\n\tconst struct scan_field *in_fields,\n\ttap_state_t state)\n{\n\tjtag_add_ir_scan_noverify(active, in_fields, state);\n}\n\n/* If fields->in_value is filled out, then the captured IR value will be checked */\nvoid jtag_add_ir_scan(struct jtag_tap *active, struct scan_field *in_fields, tap_state_t state)\n{\n\tassert(state != TAP_RESET);\n\n\tif (jtag_verify && jtag_verify_capture_ir) {\n\t\t/* 8 x 32 bit id's is enough for all invocations */\n\n\t\t/* if we are to run a verification of the ir scan, we need to get the input back.\n\t\t * We may have to allocate space if the caller didn't ask for the input back.\n\t\t */\n\t\tin_fields->check_value = active->expected;\n\t\tin_fields->check_mask = active->expected_mask;\n\t\tjtag_add_scan_check(active, jtag_add_ir_scan_noverify_callback, 1, in_fields,\n\t\t\tstate);\n\t} else\n\t\tjtag_add_ir_scan_noverify(active, in_fields, state);\n}\n\nvoid jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits,\n\ttap_state_t state)\n{\n\tassert(out_bits);\n\tassert(state != TAP_RESET);\n\n\tjtag_prelude(state);\n\n\tint retval = interface_jtag_add_plain_ir_scan(\n\t\t\tnum_bits, out_bits, in_bits, state);\n\tjtag_set_error(retval);\n}\n\nstatic int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value,\n\t\t\t\t  uint8_t *in_check_mask, int num_bits);\n\nstatic int jtag_check_value_mask_callback(jtag_callback_data_t data0,\n\tjtag_callback_data_t data1,\n\tjtag_callback_data_t data2,\n\tjtag_callback_data_t data3)\n{\n\treturn jtag_check_value_inner((uint8_t *)data0,\n\t\t(uint8_t *)data1,\n\t\t(uint8_t *)data2,\n\t\t(int)data3);\n}\n\nstatic void jtag_add_scan_check(struct jtag_tap *active, void (*jtag_add_scan)(\n\t\tstruct jtag_tap *active,\n\t\tint in_num_fields,\n\t\tconst struct scan_field *in_fields,\n\t\ttap_state_t state),\n\tint in_num_fields, struct scan_field *in_fields, tap_state_t state)\n{\n\tjtag_add_scan(active, in_num_fields, in_fields, state);\n\n\tfor (int i = 0; i < in_num_fields; i++) {\n\t\tif ((in_fields[i].check_value) && (in_fields[i].in_value)) {\n\t\t\tjtag_add_callback4(jtag_check_value_mask_callback,\n\t\t\t\t(jtag_callback_data_t)in_fields[i].in_value,\n\t\t\t\t(jtag_callback_data_t)in_fields[i].check_value,\n\t\t\t\t(jtag_callback_data_t)in_fields[i].check_mask,\n\t\t\t\t(jtag_callback_data_t)in_fields[i].num_bits);\n\t\t}\n\t}\n}\n\nvoid jtag_add_dr_scan_check(struct jtag_tap *active,\n\tint in_num_fields,\n\tstruct scan_field *in_fields,\n\ttap_state_t state)\n{\n\tif (jtag_verify)\n\t\tjtag_add_scan_check(active, jtag_add_dr_scan, in_num_fields, in_fields, state);\n\telse\n\t\tjtag_add_dr_scan(active, in_num_fields, in_fields, state);\n}\n\n\nvoid jtag_add_dr_scan(struct jtag_tap *active,\n\tint in_num_fields,\n\tconst struct scan_field *in_fields,\n\ttap_state_t state)\n{\n\tassert(state != TAP_RESET);\n\n\tjtag_prelude(state);\n\n\tint retval;\n\tretval = interface_jtag_add_dr_scan(active, in_num_fields, in_fields, state);\n\tjtag_set_error(retval);\n}\n\nvoid jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits,\n\ttap_state_t state)\n{\n\tassert(out_bits);\n\tassert(state != TAP_RESET);\n\n\tjtag_prelude(state);\n\n\tint retval;\n\tretval = interface_jtag_add_plain_dr_scan(num_bits, out_bits, in_bits, state);\n\tjtag_set_error(retval);\n}\n\nvoid jtag_add_tlr(void)\n{\n\tjtag_prelude(TAP_RESET);\n\tjtag_set_error(interface_jtag_add_tlr());\n\n\t/* NOTE: order here matches TRST path in jtag_add_reset() */\n\tjtag_call_event_callbacks(JTAG_TRST_ASSERTED);\n\tjtag_notify_event(JTAG_TRST_ASSERTED);\n}\n\n/**\n * If supported by the underlying adapter, this clocks a raw bit sequence\n * onto TMS for switching between JTAG and SWD modes.\n *\n * DO NOT use this to bypass the integrity checks and logging provided\n * by the jtag_add_pathmove() and jtag_add_statemove() calls.\n *\n * @param nbits How many bits to clock out.\n * @param seq The bit sequence.  The LSB is bit 0 of seq[0].\n * @param state The JTAG tap state to record on completion.  Use\n *\tTAP_INVALID to represent being in in SWD mode.\n *\n * @todo Update naming conventions to stop assuming everything is JTAG.\n */\nint jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)\n{\n\tint retval;\n\n\tif (!(adapter_driver->jtag_ops->supported & DEBUG_CAP_TMS_SEQ))\n\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\n\tjtag_checks();\n\tcmd_queue_cur_state = state;\n\n\tretval = interface_add_tms_seq(nbits, seq, state);\n\tjtag_set_error(retval);\n\treturn retval;\n}\n\nvoid jtag_add_pathmove(int num_states, const tap_state_t *path)\n{\n\ttap_state_t cur_state = cmd_queue_cur_state;\n\n\t/* the last state has to be a stable state */\n\tif (!tap_is_state_stable(path[num_states - 1])) {\n\t\tLOG_ERROR(\"BUG: TAP path doesn't finish in a stable state\");\n\t\tjtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);\n\t\treturn;\n\t}\n\n\tfor (int i = 0; i < num_states; i++) {\n\t\tif (path[i] == TAP_RESET) {\n\t\t\tLOG_ERROR(\"BUG: TAP_RESET is not a valid state for pathmove sequences\");\n\t\t\tjtag_set_error(ERROR_JTAG_STATE_INVALID);\n\t\t\treturn;\n\t\t}\n\n\t\tif (tap_state_transition(cur_state, true) != path[i] &&\n\t\t\t\ttap_state_transition(cur_state, false) != path[i]) {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(cur_state), tap_state_name(path[i]));\n\t\t\tjtag_set_error(ERROR_JTAG_TRANSITION_INVALID);\n\t\t\treturn;\n\t\t}\n\t\tcur_state = path[i];\n\t}\n\n\tjtag_checks();\n\n\tjtag_set_error(interface_jtag_add_pathmove(num_states, path));\n\tcmd_queue_cur_state = path[num_states - 1];\n}\n\nint jtag_add_statemove(tap_state_t goal_state)\n{\n\ttap_state_t cur_state = cmd_queue_cur_state;\n\n\tif (goal_state != cur_state) {\n\t\tLOG_DEBUG(\"cur_state=%s goal_state=%s\",\n\t\t\ttap_state_name(cur_state),\n\t\t\ttap_state_name(goal_state));\n\t}\n\n\t/* If goal is RESET, be paranoid and force that that transition\n\t * (e.g. five TCK cycles, TMS high).  Else trust \"cur_state\".\n\t */\n\tif (goal_state == TAP_RESET)\n\t\tjtag_add_tlr();\n\telse if (goal_state == cur_state)\n\t\t/* nothing to do */;\n\n\telse if (tap_is_state_stable(cur_state) && tap_is_state_stable(goal_state)) {\n\t\tunsigned tms_bits  = tap_get_tms_path(cur_state, goal_state);\n\t\tunsigned tms_count = tap_get_tms_path_len(cur_state, goal_state);\n\t\ttap_state_t moves[8];\n\t\tassert(tms_count < ARRAY_SIZE(moves));\n\n\t\tfor (unsigned i = 0; i < tms_count; i++, tms_bits >>= 1) {\n\t\t\tbool bit = tms_bits & 1;\n\n\t\t\tcur_state = tap_state_transition(cur_state, bit);\n\t\t\tmoves[i] = cur_state;\n\t\t}\n\n\t\tjtag_add_pathmove(tms_count, moves);\n\t} else if (tap_state_transition(cur_state, true)  == goal_state\n\t\t\t|| tap_state_transition(cur_state, false) == goal_state)\n\t\tjtag_add_pathmove(1, &goal_state);\n\telse\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nvoid jtag_add_runtest(int num_cycles, tap_state_t state)\n{\n\tjtag_prelude(state);\n\tjtag_set_error(interface_jtag_add_runtest(num_cycles, state));\n}\n\n\nvoid jtag_add_clocks(int num_cycles)\n{\n\tif (!tap_is_state_stable(cmd_queue_cur_state)) {\n\t\tLOG_ERROR(\"jtag_add_clocks() called with TAP in unstable state \\\"%s\\\"\",\n\t\t\ttap_state_name(cmd_queue_cur_state));\n\t\tjtag_set_error(ERROR_JTAG_NOT_STABLE_STATE);\n\t\treturn;\n\t}\n\n\tif (num_cycles > 0) {\n\t\tjtag_checks();\n\t\tjtag_set_error(interface_jtag_add_clocks(num_cycles));\n\t}\n}\n\nstatic int adapter_system_reset(int req_srst)\n{\n\tint retval;\n\n\tif (req_srst) {\n\t\tif (!(jtag_reset_config & RESET_HAS_SRST)) {\n\t\t\tLOG_ERROR(\"BUG: can't assert SRST\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\treq_srst = 1;\n\t}\n\n\t/* Maybe change SRST signal state */\n\tif (jtag_srst != req_srst) {\n\t\tretval = adapter_driver->reset(0, req_srst);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"SRST error\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tjtag_srst = req_srst;\n\n\t\tif (req_srst) {\n\t\t\tLOG_DEBUG(\"SRST line asserted\");\n\t\t\tif (adapter_nsrst_assert_width)\n\t\t\t\tjtag_sleep(adapter_nsrst_assert_width * 1000);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"SRST line released\");\n\t\t\tif (adapter_nsrst_delay)\n\t\t\t\tjtag_sleep(adapter_nsrst_delay * 1000);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void legacy_jtag_add_reset(int req_tlr_or_trst, int req_srst)\n{\n\tint trst_with_tlr = 0;\n\tint new_srst = 0;\n\tint new_trst = 0;\n\n\t/* Without SRST, we must use target-specific JTAG operations\n\t * on each target; callers should not be requesting SRST when\n\t * that signal doesn't exist.\n\t *\n\t * RESET_SRST_PULLS_TRST is a board or chip level quirk, which\n\t * can kick in even if the JTAG adapter can't drive TRST.\n\t */\n\tif (req_srst) {\n\t\tif (!(jtag_reset_config & RESET_HAS_SRST)) {\n\t\t\tLOG_ERROR(\"BUG: can't assert SRST\");\n\t\t\tjtag_set_error(ERROR_FAIL);\n\t\t\treturn;\n\t\t}\n\t\tif ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0\n\t\t\t\t&& !req_tlr_or_trst) {\n\t\t\tLOG_ERROR(\"BUG: can't assert only SRST\");\n\t\t\tjtag_set_error(ERROR_FAIL);\n\t\t\treturn;\n\t\t}\n\t\tnew_srst = 1;\n\t}\n\n\t/* JTAG reset (entry to TAP_RESET state) can always be achieved\n\t * using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE\n\t * state first.  TRST accelerates it, and bypasses those states.\n\t *\n\t * RESET_TRST_PULLS_SRST is a board or chip level quirk, which\n\t * can kick in even if the JTAG adapter can't drive SRST.\n\t */\n\tif (req_tlr_or_trst) {\n\t\tif (!(jtag_reset_config & RESET_HAS_TRST))\n\t\t\ttrst_with_tlr = 1;\n\t\telse if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0\n\t\t\t && !req_srst)\n\t\t\ttrst_with_tlr = 1;\n\t\telse\n\t\t\tnew_trst = 1;\n\t}\n\n\t/* Maybe change TRST and/or SRST signal state */\n\tif (jtag_srst != new_srst || jtag_trst != new_trst) {\n\t\tint retval;\n\n\t\tretval = interface_jtag_add_reset(new_trst, new_srst);\n\t\tif (retval != ERROR_OK)\n\t\t\tjtag_set_error(retval);\n\t\telse\n\t\t\tretval = jtag_execute_queue();\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"TRST/SRST error\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* SRST resets everything hooked up to that signal */\n\tif (jtag_srst != new_srst) {\n\t\tjtag_srst = new_srst;\n\t\tif (jtag_srst) {\n\t\t\tLOG_DEBUG(\"SRST line asserted\");\n\t\t\tif (adapter_nsrst_assert_width)\n\t\t\t\tjtag_add_sleep(adapter_nsrst_assert_width * 1000);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"SRST line released\");\n\t\t\tif (adapter_nsrst_delay)\n\t\t\t\tjtag_add_sleep(adapter_nsrst_delay * 1000);\n\t\t}\n\t}\n\n\t/* Maybe enter the JTAG TAP_RESET state ...\n\t *  - using only TMS, TCK, and the JTAG state machine\n\t *  - or else more directly, using TRST\n\t *\n\t * TAP_RESET should be invisible to non-debug parts of the system.\n\t */\n\tif (trst_with_tlr) {\n\t\tLOG_DEBUG(\"JTAG reset with TLR instead of TRST\");\n\t\tjtag_add_tlr();\n\n\t} else if (jtag_trst != new_trst) {\n\t\tjtag_trst = new_trst;\n\t\tif (jtag_trst) {\n\t\t\tLOG_DEBUG(\"TRST line asserted\");\n\t\t\ttap_set_state(TAP_RESET);\n\t\t\tif (jtag_ntrst_assert_width)\n\t\t\t\tjtag_add_sleep(jtag_ntrst_assert_width * 1000);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"TRST line released\");\n\t\t\tif (jtag_ntrst_delay)\n\t\t\t\tjtag_add_sleep(jtag_ntrst_delay * 1000);\n\n\t\t\t/* We just asserted nTRST, so we're now in TAP_RESET.\n\t\t\t * Inform possible listeners about this, now that\n\t\t\t * JTAG instructions and data can be shifted.  This\n\t\t\t * sequence must match jtag_add_tlr().\n\t\t\t */\n\t\t\tjtag_call_event_callbacks(JTAG_TRST_ASSERTED);\n\t\t\tjtag_notify_event(JTAG_TRST_ASSERTED);\n\t\t}\n\t}\n}\n\n/* FIXME: name is misleading; we do not plan to \"add\" reset into jtag queue */\nvoid jtag_add_reset(int req_tlr_or_trst, int req_srst)\n{\n\tint retval;\n\tint trst_with_tlr = 0;\n\tint new_srst = 0;\n\tint new_trst = 0;\n\n\tif (!adapter_driver->reset) {\n\t\tlegacy_jtag_add_reset(req_tlr_or_trst, req_srst);\n\t\treturn;\n\t}\n\n\t/* Without SRST, we must use target-specific JTAG operations\n\t * on each target; callers should not be requesting SRST when\n\t * that signal doesn't exist.\n\t *\n\t * RESET_SRST_PULLS_TRST is a board or chip level quirk, which\n\t * can kick in even if the JTAG adapter can't drive TRST.\n\t */\n\tif (req_srst) {\n\t\tif (!(jtag_reset_config & RESET_HAS_SRST)) {\n\t\t\tLOG_ERROR(\"BUG: can't assert SRST\");\n\t\t\tjtag_set_error(ERROR_FAIL);\n\t\t\treturn;\n\t\t}\n\t\tif ((jtag_reset_config & RESET_SRST_PULLS_TRST) != 0\n\t\t\t\t&& !req_tlr_or_trst) {\n\t\t\tLOG_ERROR(\"BUG: can't assert only SRST\");\n\t\t\tjtag_set_error(ERROR_FAIL);\n\t\t\treturn;\n\t\t}\n\t\tnew_srst = 1;\n\t}\n\n\t/* JTAG reset (entry to TAP_RESET state) can always be achieved\n\t * using TCK and TMS; that may go through a TAP_{IR,DR}UPDATE\n\t * state first.  TRST accelerates it, and bypasses those states.\n\t *\n\t * RESET_TRST_PULLS_SRST is a board or chip level quirk, which\n\t * can kick in even if the JTAG adapter can't drive SRST.\n\t */\n\tif (req_tlr_or_trst) {\n\t\tif (!(jtag_reset_config & RESET_HAS_TRST))\n\t\t\ttrst_with_tlr = 1;\n\t\telse if ((jtag_reset_config & RESET_TRST_PULLS_SRST) != 0\n\t\t\t && !req_srst)\n\t\t\ttrst_with_tlr = 1;\n\t\telse\n\t\t\tnew_trst = 1;\n\t}\n\n\t/* Maybe change TRST and/or SRST signal state */\n\tif (jtag_srst != new_srst || jtag_trst != new_trst) {\n\t\t/* guarantee jtag queue empty before changing reset status */\n\t\tjtag_execute_queue();\n\n\t\tretval = adapter_driver->reset(new_trst, new_srst);\n\t\tif (retval != ERROR_OK) {\n\t\t\tjtag_set_error(retval);\n\t\t\tLOG_ERROR(\"TRST/SRST error\");\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* SRST resets everything hooked up to that signal */\n\tif (jtag_srst != new_srst) {\n\t\tjtag_srst = new_srst;\n\t\tif (jtag_srst) {\n\t\t\tLOG_DEBUG(\"SRST line asserted\");\n\t\t\tif (adapter_nsrst_assert_width)\n\t\t\t\tjtag_add_sleep(adapter_nsrst_assert_width * 1000);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"SRST line released\");\n\t\t\tif (adapter_nsrst_delay)\n\t\t\t\tjtag_add_sleep(adapter_nsrst_delay * 1000);\n\t\t}\n\t}\n\n\t/* Maybe enter the JTAG TAP_RESET state ...\n\t *  - using only TMS, TCK, and the JTAG state machine\n\t *  - or else more directly, using TRST\n\t *\n\t * TAP_RESET should be invisible to non-debug parts of the system.\n\t */\n\tif (trst_with_tlr) {\n\t\tLOG_DEBUG(\"JTAG reset with TLR instead of TRST\");\n\t\tjtag_add_tlr();\n\t\tjtag_execute_queue();\n\n\t} else if (jtag_trst != new_trst) {\n\t\tjtag_trst = new_trst;\n\t\tif (jtag_trst) {\n\t\t\tLOG_DEBUG(\"TRST line asserted\");\n\t\t\ttap_set_state(TAP_RESET);\n\t\t\tif (jtag_ntrst_assert_width)\n\t\t\t\tjtag_add_sleep(jtag_ntrst_assert_width * 1000);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"TRST line released\");\n\t\t\tif (jtag_ntrst_delay)\n\t\t\t\tjtag_add_sleep(jtag_ntrst_delay * 1000);\n\n\t\t\t/* We just asserted nTRST, so we're now in TAP_RESET.\n\t\t\t * Inform possible listeners about this, now that\n\t\t\t * JTAG instructions and data can be shifted.  This\n\t\t\t * sequence must match jtag_add_tlr().\n\t\t\t */\n\t\t\tjtag_call_event_callbacks(JTAG_TRST_ASSERTED);\n\t\t\tjtag_notify_event(JTAG_TRST_ASSERTED);\n\t\t}\n\t}\n}\n\nvoid jtag_add_sleep(uint32_t us)\n{\n\t/** @todo Here, keep_alive() appears to be a layering violation!!! */\n\tkeep_alive();\n\tjtag_set_error(interface_jtag_add_sleep(us));\n}\n\nstatic int jtag_check_value_inner(uint8_t *captured, uint8_t *in_check_value,\n\tuint8_t *in_check_mask, int num_bits)\n{\n\tint retval = ERROR_OK;\n\tint compare_failed;\n\n\tif (in_check_mask)\n\t\tcompare_failed = buf_cmp_mask(captured, in_check_value, in_check_mask, num_bits);\n\telse\n\t\tcompare_failed = buf_cmp(captured, in_check_value, num_bits);\n\n\tif (compare_failed) {\n\t\tchar *captured_str, *in_check_value_str;\n\t\tint bits = (num_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : num_bits;\n\n\t\t/* NOTE:  we've lost diagnostic context here -- 'which tap' */\n\n\t\tcaptured_str = buf_to_hex_str(captured, bits);\n\t\tin_check_value_str = buf_to_hex_str(in_check_value, bits);\n\n\t\tLOG_WARNING(\"Bad value '%s' captured during DR or IR scan:\",\n\t\t\tcaptured_str);\n\t\tLOG_WARNING(\" check_value: 0x%s\", in_check_value_str);\n\n\t\tfree(captured_str);\n\t\tfree(in_check_value_str);\n\n\t\tif (in_check_mask) {\n\t\t\tchar *in_check_mask_str;\n\n\t\t\tin_check_mask_str = buf_to_hex_str(in_check_mask, bits);\n\t\t\tLOG_WARNING(\" check_mask: 0x%s\", in_check_mask_str);\n\t\t\tfree(in_check_mask_str);\n\t\t}\n\n\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t}\n\treturn retval;\n}\n\nvoid jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask)\n{\n\tassert(field->in_value);\n\n\tif (!value) {\n\t\t/* no checking to do */\n\t\treturn;\n\t}\n\n\tjtag_execute_queue_noclear();\n\n\tint retval = jtag_check_value_inner(field->in_value, value, mask, field->num_bits);\n\tjtag_set_error(retval);\n}\n\nint default_interface_jtag_execute_queue(void)\n{\n\tif (!is_adapter_initialized()) {\n\t\tLOG_ERROR(\"No JTAG interface configured yet.  \"\n\t\t\t\"Issue 'init' command in startup scripts \"\n\t\t\t\"before communicating with targets.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!transport_is_jtag()) {\n\t\t/*\n\t\t * FIXME: This should not happen!\n\t\t * There could be old code that queues jtag commands with non jtag interfaces so, for\n\t\t * the moment simply highlight it by log an error and return on empty execute_queue.\n\t\t * We should fix it quitting with assert(0) because it is an internal error.\n\t\t * The fix can be applied immediately after next release (v0.11.0 ?)\n\t\t */\n\t\tLOG_ERROR(\"JTAG API jtag_execute_queue() called on non JTAG interface\");\n\t\tif (!adapter_driver->jtag_ops || !adapter_driver->jtag_ops->execute_queue)\n\t\t\treturn ERROR_OK;\n\t}\n\n\tint result = adapter_driver->jtag_ops->execute_queue();\n\n\tstruct jtag_command *cmd = jtag_command_queue;\n\twhile (debug_level >= LOG_LVL_DEBUG_IO && cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG %s SCAN to %s\",\n\t\t\t\t\t\tcmd->cmd.scan->ir_scan ? \"IR\" : \"DR\",\n\t\t\t\t\t\ttap_state_name(cmd->cmd.scan->end_state));\n\t\t\t\tfor (int i = 0; i < cmd->cmd.scan->num_fields; i++) {\n\t\t\t\t\tstruct scan_field *field = cmd->cmd.scan->fields + i;\n\t\t\t\t\tif (field->out_value) {\n\t\t\t\t\t\tchar *str = buf_to_hex_str(field->out_value, field->num_bits);\n\t\t\t\t\t\tLOG_DEBUG_IO(\"  %db out: %s\", field->num_bits, str);\n\t\t\t\t\t\tfree(str);\n\t\t\t\t\t}\n\t\t\t\t\tif (field->in_value) {\n\t\t\t\t\t\tchar *str = buf_to_hex_str(field->in_value, field->num_bits);\n\t\t\t\t\t\tLOG_DEBUG_IO(\"  %db  in: %s\", field->num_bits, str);\n\t\t\t\t\t\tfree(str);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG TLR RESET to %s\",\n\t\t\t\t\t\ttap_state_name(cmd->cmd.statemove->end_state));\n\t\t\t\tbreak;\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG RUNTEST %d cycles to %s\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\ttap_state_name(cmd->cmd.runtest->end_state));\n\t\t\t\tbreak;\n\t\t\tcase JTAG_RESET:\n\t\t\t\t{\n\t\t\t\t\tconst char *reset_str[3] = {\n\t\t\t\t\t\t\"leave\", \"deassert\", \"assert\"\n\t\t\t\t\t};\n\t\t\t\t\tLOG_DEBUG_IO(\"JTAG RESET %s TRST, %s SRST\",\n\t\t\t\t\t\t\treset_str[cmd->cmd.reset->trst + 1],\n\t\t\t\t\t\t\treset_str[cmd->cmd.reset->srst + 1]);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG PATHMOVE (TODO)\");\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG SLEEP (TODO)\");\n\t\t\t\tbreak;\n\t\t\tcase JTAG_STABLECLOCKS:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG STABLECLOCKS (TODO)\");\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TMS:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG TMS (TODO)\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unknown JTAG command: %d\", cmd->type);\n\t\t\t\tbreak;\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\treturn result;\n}\n\nvoid jtag_execute_queue_noclear(void)\n{\n\tjtag_flush_queue_count++;\n\tjtag_set_error(interface_jtag_execute_queue());\n\n\tif (jtag_flush_queue_sleep > 0) {\n\t\t/* For debug purposes it can be useful to test performance\n\t\t * or behavior when delaying after flushing the queue,\n\t\t * e.g. to simulate long roundtrip times.\n\t\t */\n\t\tusleep(jtag_flush_queue_sleep * 1000);\n\t}\n}\n\nint jtag_get_flush_queue_count(void)\n{\n\treturn jtag_flush_queue_count;\n}\n\nint jtag_execute_queue(void)\n{\n\tjtag_execute_queue_noclear();\n\treturn jtag_error_clear();\n}\n\nstatic int jtag_reset_callback(enum jtag_event event, void *priv)\n{\n\tstruct jtag_tap *tap = priv;\n\n\tif (event == JTAG_TRST_ASSERTED) {\n\t\ttap->enabled = !tap->disabled_after_reset;\n\n\t\t/* current instruction is either BYPASS or IDCODE */\n\t\tbuf_set_ones(tap->cur_instr, tap->ir_length);\n\t\ttap->bypass = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* sleep at least us microseconds. When we sleep more than 1000ms we\n * do an alive sleep, i.e. keep GDB alive. Note that we could starve\n * GDB if we slept for <1000ms many times.\n */\nvoid jtag_sleep(uint32_t us)\n{\n\tif (us < 1000)\n\t\tusleep(us);\n\telse\n\t\talive_sleep((us+999)/1000);\n}\n\n#define JTAG_MAX_AUTO_TAPS 20\n\n#define EXTRACT_MFG(X)  (((X) & 0xffe) >> 1)\n#define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)\n#define EXTRACT_VER(X)  (((X) & 0xf0000000) >> 28)\n\n/* A reserved manufacturer ID is used in END_OF_CHAIN_FLAG, so we\n * know that no valid TAP will have it as an IDCODE value.\n */\n#define END_OF_CHAIN_FLAG       0xffffffff\n\n/* a larger IR length than we ever expect to autoprobe */\n#define JTAG_IRLEN_MAX          60\n\nstatic int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcode)\n{\n\tstruct scan_field field = {\n\t\t.num_bits = num_idcode * 32,\n\t\t.out_value = idcode_buffer,\n\t\t.in_value = idcode_buffer,\n\t};\n\n\t/* initialize to the end of chain ID value */\n\tfor (unsigned i = 0; i < num_idcode; i++)\n\t\tbuf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG);\n\n\tjtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE);\n\tjtag_add_tlr();\n\treturn jtag_execute_queue();\n}\n\nstatic bool jtag_examine_chain_check(uint8_t *idcodes, unsigned count)\n{\n\tuint8_t zero_check = 0x0;\n\tuint8_t one_check = 0xff;\n\n\tfor (unsigned i = 0; i < count * 4; i++) {\n\t\tzero_check |= idcodes[i];\n\t\tone_check &= idcodes[i];\n\t}\n\n\t/* if there wasn't a single non-zero bit or if all bits were one,\n\t * the scan is not valid.  We wrote a mix of both values; either\n\t *\n\t *  - There's a hardware issue (almost certainly):\n\t *     + all-zeroes can mean a target stuck in JTAG reset\n\t *     + all-ones tends to mean no target\n\t *  - The scan chain is WAY longer than we can handle, *AND* either\n\t *     + there are several hundreds of TAPs in bypass, or\n\t *     + at least a few dozen TAPs all have an all-ones IDCODE\n\t */\n\tif (zero_check == 0x00 || one_check == 0xff) {\n\t\tLOG_ERROR(\"JTAG scan chain interrogation failed: all %s\",\n\t\t\t(zero_check == 0x00) ? \"zeroes\" : \"ones\");\n\t\tLOG_ERROR(\"Check JTAG interface, timings, target power, etc.\");\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nstatic void jtag_examine_chain_display(enum log_levels level, const char *msg,\n\tconst char *name, uint32_t idcode)\n{\n\tlog_printf_lf(level, __FILE__, __LINE__, __func__,\n\t\t\"JTAG tap: %s %16.16s: 0x%08x \"\n\t\t\"(mfg: 0x%3.3x (%s), part: 0x%4.4x, ver: 0x%1.1x)\",\n\t\tname, msg,\n\t\t(unsigned int)idcode,\n\t\t(unsigned int)EXTRACT_MFG(idcode),\n\t\tjep106_manufacturer(EXTRACT_MFG(idcode)),\n\t\t(unsigned int)EXTRACT_PART(idcode),\n\t\t(unsigned int)EXTRACT_VER(idcode));\n}\n\nstatic bool jtag_idcode_is_final(uint32_t idcode)\n{\n\t/*\n\t * Some devices, such as AVR8, will output all 1's instead\n\t * of TDI input value at end of chain. Allow those values\n\t * instead of failing.\n\t */\n\treturn idcode == END_OF_CHAIN_FLAG;\n}\n\n/**\n * This helper checks that remaining bits in the examined chain data are\n * all as expected, but a single JTAG device requires only 64 bits to be\n * read back correctly.  This can help identify and diagnose problems\n * with the JTAG chain earlier, gives more helpful/explicit error messages.\n * Returns TRUE iff garbage was found.\n */\nstatic bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned max)\n{\n\tbool triggered = false;\n\tfor (; count < max - 31; count += 32) {\n\t\tuint32_t idcode = buf_get_u32(idcodes, count, 32);\n\n\t\t/* do not trigger the warning if the data looks good */\n\t\tif (jtag_idcode_is_final(idcode))\n\t\t\tcontinue;\n\t\tLOG_WARNING(\"Unexpected idcode after end of chain: %d 0x%08x\",\n\t\t\tcount, (unsigned int)idcode);\n\t\ttriggered = true;\n\t}\n\treturn triggered;\n}\n\nstatic bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)\n{\n\n\tif (tap->expected_ids_cnt == 0 || !tap->hasidcode)\n\t\treturn true;\n\n\t/* optionally ignore the JTAG version field - bits 28-31 of IDCODE */\n\tuint32_t mask = tap->ignore_version ? ~(0xfU << 28) : ~0U;\n\tuint32_t idcode = tap->idcode & mask;\n\n\t/* Loop over the expected identification codes and test for a match */\n\tfor (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {\n\t\tuint32_t expected = tap->expected_ids[ii] & mask;\n\n\t\tif (idcode == expected)\n\t\t\treturn true;\n\n\t\t/* treat \"-expected-id 0\" as a \"don't-warn\" wildcard */\n\t\tif (tap->expected_ids[ii] == 0)\n\t\t\treturn true;\n\t}\n\n\t/* If none of the expected ids matched, warn */\n\tjtag_examine_chain_display(LOG_LVL_WARNING, \"UNEXPECTED\",\n\t\ttap->dotted_name, tap->idcode);\n\tfor (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {\n\t\tchar msg[32];\n\n\t\tsnprintf(msg, sizeof(msg), \"expected %u of %u\", ii + 1, tap->expected_ids_cnt);\n\t\tjtag_examine_chain_display(LOG_LVL_ERROR, msg,\n\t\t\ttap->dotted_name, tap->expected_ids[ii]);\n\t}\n\treturn false;\n}\n\n/* Try to examine chain layout according to IEEE 1149.1 §12\n * This is called a \"blind interrogation\" of the scan chain.\n */\nstatic int jtag_examine_chain(void)\n{\n\tint retval;\n\tunsigned max_taps = jtag_tap_count();\n\n\t/* Autoprobe up to this many. */\n\tif (max_taps < JTAG_MAX_AUTO_TAPS)\n\t\tmax_taps = JTAG_MAX_AUTO_TAPS;\n\n\t/* Add room for end-of-chain marker. */\n\tmax_taps++;\n\n\tuint8_t *idcode_buffer = calloc(4, max_taps);\n\tif (!idcode_buffer)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\t/* DR scan to collect BYPASS or IDCODE register contents.\n\t * Then make sure the scan data has both ones and zeroes.\n\t */\n\tLOG_DEBUG(\"DR scan interrogation for IDCODE/BYPASS\");\n\tretval = jtag_examine_chain_execute(idcode_buffer, max_taps);\n\tif (retval != ERROR_OK)\n\t\tgoto out;\n\tif (!jtag_examine_chain_check(idcode_buffer, max_taps)) {\n\t\tretval = ERROR_JTAG_INIT_FAILED;\n\t\tgoto out;\n\t}\n\n\t/* Point at the 1st predefined tap, if any */\n\tstruct jtag_tap *tap = jtag_tap_next_enabled(NULL);\n\n\tunsigned bit_count = 0;\n\tunsigned autocount = 0;\n\tfor (unsigned i = 0; i < max_taps; i++) {\n\t\tassert(bit_count < max_taps * 32);\n\t\tuint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);\n\n\t\t/* No predefined TAP? Auto-probe. */\n\t\tif (!tap) {\n\t\t\t/* Is there another TAP? */\n\t\t\tif (jtag_idcode_is_final(idcode))\n\t\t\t\tbreak;\n\n\t\t\t/* Default everything in this TAP except IR length.\n\t\t\t *\n\t\t\t * REVISIT create a jtag_alloc(chip, tap) routine, and\n\t\t\t * share it with jim_newtap_cmd().\n\t\t\t */\n\t\t\ttap = calloc(1, sizeof(*tap));\n\t\t\tif (!tap) {\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto out;\n\t\t\t}\n\n\t\t\ttap->chip = alloc_printf(\"auto%u\", autocount++);\n\t\t\ttap->tapname = strdup(\"tap\");\n\t\t\ttap->dotted_name = alloc_printf(\"%s.%s\", tap->chip, tap->tapname);\n\n\t\t\ttap->ir_length = 0; /* ... signifying irlen autoprobe */\n\t\t\ttap->ir_capture_mask = 0x03;\n\t\t\ttap->ir_capture_value = 0x01;\n\n\t\t\ttap->enabled = true;\n\n\t\t\tjtag_tap_init(tap);\n\t\t}\n\n\t\tif ((idcode & 1) == 0 && !tap->ignore_bypass) {\n\t\t\t/* Zero for LSB indicates a device in bypass */\n\t\t\tLOG_INFO(\"TAP %s does not have valid IDCODE (idcode=0x%\" PRIx32 \")\",\n\t\t\t\t\ttap->dotted_name, idcode);\n\t\t\ttap->hasidcode = false;\n\t\t\ttap->idcode = 0;\n\n\t\t\tbit_count += 1;\n\t\t} else {\n\t\t\t/* Friendly devices support IDCODE */\n\t\t\ttap->hasidcode = true;\n\t\t\ttap->idcode = idcode;\n\t\t\tjtag_examine_chain_display(LOG_LVL_INFO, \"tap/device found\", tap->dotted_name, idcode);\n\n\t\t\tbit_count += 32;\n\t\t}\n\n\t\t/* ensure the TAP ID matches what was expected */\n\t\tif (!jtag_examine_chain_match_tap(tap))\n\t\t\tretval = ERROR_JTAG_INIT_SOFT_FAIL;\n\n\t\ttap = jtag_tap_next_enabled(tap);\n\t}\n\n\t/* After those IDCODE or BYPASS register values should be\n\t * only the data we fed into the scan chain.\n\t */\n\tif (jtag_examine_chain_end(idcode_buffer, bit_count, max_taps * 32)) {\n\t\tLOG_ERROR(\"double-check your JTAG setup (interface, speed, ...)\");\n\t\tretval = ERROR_JTAG_INIT_FAILED;\n\t\tgoto out;\n\t}\n\n\t/* Return success or, for backwards compatibility if only\n\t * some IDCODE values mismatched, a soft/continuable fault.\n\t */\nout:\n\tfree(idcode_buffer);\n\treturn retval;\n}\n\n/*\n * Validate the date loaded by entry to the Capture-IR state, to help\n * find errors related to scan chain configuration (wrong IR lengths)\n * or communication.\n *\n * Entry state can be anything.  On non-error exit, all TAPs are in\n * bypass mode.  On error exits, the scan chain is reset.\n */\nstatic int jtag_validate_ircapture(void)\n{\n\tstruct jtag_tap *tap;\n\tuint8_t *ir_test = NULL;\n\tstruct scan_field field;\n\tint chain_pos = 0;\n\tint retval;\n\n\t/* when autoprobing, accommodate huge IR lengths */\n\tint total_ir_length = 0;\n\tfor (tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {\n\t\tif (tap->ir_length == 0)\n\t\t\ttotal_ir_length += JTAG_IRLEN_MAX;\n\t\telse\n\t\t\ttotal_ir_length += tap->ir_length;\n\t}\n\n\t/* increase length to add 2 bit sentinel after scan */\n\ttotal_ir_length += 2;\n\n\tir_test = malloc(DIV_ROUND_UP(total_ir_length, 8));\n\tif (!ir_test)\n\t\treturn ERROR_FAIL;\n\n\t/* after this scan, all TAPs will capture BYPASS instructions */\n\tbuf_set_ones(ir_test, total_ir_length);\n\n\tfield.num_bits = total_ir_length;\n\tfield.out_value = ir_test;\n\tfield.in_value = ir_test;\n\n\tjtag_add_plain_ir_scan(field.num_bits, field.out_value, field.in_value, TAP_IDLE);\n\n\tLOG_DEBUG(\"IR capture validation scan\");\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\ttap = NULL;\n\tchain_pos = 0;\n\n\tfor (;; ) {\n\t\ttap = jtag_tap_next_enabled(tap);\n\t\tif (!tap)\n\t\t\tbreak;\n\n\t\t/* If we're autoprobing, guess IR lengths.  They must be at\n\t\t * least two bits.  Guessing will fail if (a) any TAP does\n\t\t * not conform to the JTAG spec; or (b) when the upper bits\n\t\t * captured from some conforming TAP are nonzero.  Or if\n\t\t * (c) an IR length is longer than JTAG_IRLEN_MAX bits,\n\t\t * an implementation limit, which could someday be raised.\n\t\t *\n\t\t * REVISIT optimization:  if there's a *single* TAP we can\n\t\t * lift restrictions (a) and (b) by scanning a recognizable\n\t\t * pattern before the all-ones BYPASS.  Check for where the\n\t\t * pattern starts in the result, instead of an 0...01 value.\n\t\t *\n\t\t * REVISIT alternative approach: escape to some tcl code\n\t\t * which could provide more knowledge, based on IDCODE; and\n\t\t * only guess when that has no success.\n\t\t */\n\t\tif (tap->ir_length == 0) {\n\t\t\ttap->ir_length = 2;\n\t\t\twhile (buf_get_u64(ir_test, chain_pos, tap->ir_length + 1) == 1\n\t\t\t\t\t&& tap->ir_length < JTAG_IRLEN_MAX) {\n\t\t\t\ttap->ir_length++;\n\t\t\t}\n\t\t\tLOG_WARNING(\"AUTO %s - use \\\"jtag newtap %s %s -irlen %d \"\n\t\t\t\t\t\"-expected-id 0x%08\" PRIx32 \"\\\"\",\n\t\t\t\t\ttap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);\n\t\t}\n\n\t\t/* Validate the two LSBs, which must be 01 per JTAG spec.\n\t\t *\n\t\t * Or ... more bits could be provided by TAP declaration.\n\t\t * Plus, some taps (notably in i.MX series chips) violate\n\t\t * this part of the JTAG spec, so their capture mask/value\n\t\t * attributes might disable this test.\n\t\t */\n\t\tuint64_t val = buf_get_u64(ir_test, chain_pos, tap->ir_length);\n\t\tif ((val & tap->ir_capture_mask) != tap->ir_capture_value) {\n\t\t\tLOG_ERROR(\"%s: IR capture error; saw 0x%0*\" PRIx64 \" not 0x%0*\" PRIx32,\n\t\t\t\tjtag_tap_name(tap),\n\t\t\t\t(tap->ir_length + 7) / tap->ir_length, val,\n\t\t\t\t(tap->ir_length + 7) / tap->ir_length, tap->ir_capture_value);\n\n\t\t\tretval = ERROR_JTAG_INIT_FAILED;\n\t\t\tgoto done;\n\t\t}\n\t\tLOG_DEBUG(\"%s: IR capture 0x%0*\" PRIx64, jtag_tap_name(tap),\n\t\t\t(tap->ir_length + 7) / tap->ir_length, val);\n\t\tchain_pos += tap->ir_length;\n\t}\n\n\t/* verify the '11' sentinel we wrote is returned at the end */\n\tuint64_t val = buf_get_u64(ir_test, chain_pos, 2);\n\tif (val != 0x3) {\n\t\tchar *cbuf = buf_to_hex_str(ir_test, total_ir_length);\n\n\t\tLOG_ERROR(\"IR capture error at bit %d, saw 0x%s not 0x...3\",\n\t\t\tchain_pos, cbuf);\n\t\tfree(cbuf);\n\t\tretval = ERROR_JTAG_INIT_FAILED;\n\t}\n\ndone:\n\tfree(ir_test);\n\tif (retval != ERROR_OK) {\n\t\tjtag_add_tlr();\n\t\tjtag_execute_queue();\n\t}\n\treturn retval;\n}\n\nvoid jtag_tap_init(struct jtag_tap *tap)\n{\n\tunsigned ir_len_bits;\n\tunsigned ir_len_bytes;\n\n\t/* if we're autoprobing, cope with potentially huge ir_length */\n\tir_len_bits = tap->ir_length ? tap->ir_length : JTAG_IRLEN_MAX;\n\tir_len_bytes = DIV_ROUND_UP(ir_len_bits, 8);\n\n\ttap->expected = calloc(1, ir_len_bytes);\n\ttap->expected_mask = calloc(1, ir_len_bytes);\n\ttap->cur_instr = malloc(ir_len_bytes);\n\n\t/** @todo cope better with ir_length bigger than 32 bits */\n\tif (ir_len_bits > 32)\n\t\tir_len_bits = 32;\n\n\tbuf_set_u32(tap->expected, 0, ir_len_bits, tap->ir_capture_value);\n\tbuf_set_u32(tap->expected_mask, 0, ir_len_bits, tap->ir_capture_mask);\n\n\t/* TAP will be in bypass mode after jtag_validate_ircapture() */\n\ttap->bypass = 1;\n\tbuf_set_ones(tap->cur_instr, tap->ir_length);\n\n\t/* register the reset callback for the TAP */\n\tjtag_register_event_callback(&jtag_reset_callback, tap);\n\tjtag_tap_add(tap);\n\n\tLOG_DEBUG(\"Created Tap: %s @ abs position %d, \"\n\t\t\t\"irlen %d, capture: 0x%x mask: 0x%x\", tap->dotted_name,\n\t\t\ttap->abs_chain_position, tap->ir_length,\n\t\t\t(unsigned) tap->ir_capture_value,\n\t\t\t(unsigned) tap->ir_capture_mask);\n}\n\nvoid jtag_tap_free(struct jtag_tap *tap)\n{\n\tjtag_unregister_event_callback(&jtag_reset_callback, tap);\n\n\tstruct jtag_tap_event_action *jteap = tap->event_action;\n\twhile (jteap) {\n\t\tstruct jtag_tap_event_action *next = jteap->next;\n\t\tJim_DecrRefCount(jteap->interp, jteap->body);\n\t\tfree(jteap);\n\t\tjteap = next;\n\t}\n\n\tfree(tap->expected);\n\tfree(tap->expected_mask);\n\tfree(tap->expected_ids);\n\tfree(tap->cur_instr);\n\tfree(tap->chip);\n\tfree(tap->tapname);\n\tfree(tap->dotted_name);\n\tfree(tap);\n}\n\nint jtag_init_inner(struct command_context *cmd_ctx)\n{\n\tstruct jtag_tap *tap;\n\tint retval;\n\tbool issue_setup = true;\n\n\tLOG_DEBUG(\"Init JTAG chain\");\n\n\ttap = jtag_tap_next_enabled(NULL);\n\tif (!tap) {\n\t\t/* Once JTAG itself is properly set up, and the scan chain\n\t\t * isn't absurdly large, IDCODE autoprobe should work fine.\n\t\t *\n\t\t * But ... IRLEN autoprobe can fail even on systems which\n\t\t * are fully conformant to JTAG.  Also, JTAG setup can be\n\t\t * quite finicky on some systems.\n\t\t *\n\t\t * REVISIT: if TAP autoprobe works OK, then in many cases\n\t\t * we could escape to tcl code and set up targets based on\n\t\t * the TAP's IDCODE values.\n\t\t */\n\t\tLOG_WARNING(\"There are no enabled taps.  \"\n\t\t\t\"AUTO PROBING MIGHT NOT WORK!!\");\n\n\t\t/* REVISIT default clock will often be too fast ... */\n\t}\n\n\tjtag_add_tlr();\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Examine DR values first.  This discovers problems which will\n\t * prevent communication ... hardware issues like TDO stuck, or\n\t * configuring the wrong number of (enabled) TAPs.\n\t */\n\tretval = jtag_examine_chain();\n\tswitch (retval) {\n\t\tcase ERROR_OK:\n\t\t\t/* complete success */\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* For backward compatibility reasons, try coping with\n\t\t\t * configuration errors involving only ID mismatches.\n\t\t\t * We might be able to talk to the devices.\n\t\t\t *\n\t\t\t * Also the device might be powered down during startup.\n\t\t\t *\n\t\t\t * After OpenOCD starts, we can try to power on the device\n\t\t\t * and run a reset.\n\t\t\t */\n\t\t\tLOG_ERROR(\"Trying to use configured scan chain anyway...\");\n\t\t\tissue_setup = false;\n\t\t\tbreak;\n\t}\n\n\t/* Now look at IR values.  Problems here will prevent real\n\t * communication.  They mostly mean that the IR length is\n\t * wrong ... or that the IR capture value is wrong.  (The\n\t * latter is uncommon, but easily worked around:  provide\n\t * ircapture/irmask values during TAP setup.)\n\t */\n\tretval = jtag_validate_ircapture();\n\tif (retval != ERROR_OK) {\n\t\t/* The target might be powered down. The user\n\t\t * can power it up and reset it after firing\n\t\t * up OpenOCD.\n\t\t */\n\t\tissue_setup = false;\n\t}\n\n\tif (issue_setup)\n\t\tjtag_notify_event(JTAG_TAP_EVENT_SETUP);\n\telse\n\t\tLOG_WARNING(\"Bypassing JTAG setup events due to errors\");\n\n\n\treturn ERROR_OK;\n}\n\nint swd_init_reset(struct command_context *cmd_ctx)\n{\n\tint retval, retval1;\n\n\tretval = adapter_init(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"Initializing with hard SRST reset\");\n\n\tif (jtag_reset_config & RESET_HAS_SRST)\n\t\tretval = adapter_system_reset(1);\n\tretval1 = adapter_system_reset(0);\n\n\treturn (retval == ERROR_OK) ? retval1 : retval;\n}\n\nint jtag_init_reset(struct command_context *cmd_ctx)\n{\n\tint retval = adapter_init(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"Initializing with hard TRST+SRST reset\");\n\n\t/*\n\t * This procedure is used by default when OpenOCD triggers a reset.\n\t * It's now done through an overridable Tcl \"init_reset\" wrapper.\n\t *\n\t * This started out as a more powerful \"get JTAG working\" reset than\n\t * jtag_init_inner(), applying TRST because some chips won't activate\n\t * JTAG without a TRST cycle (presumed to be async, though some of\n\t * those chips synchronize JTAG activation using TCK).\n\t *\n\t * But some chips only activate JTAG as part of an SRST cycle; SRST\n\t * got mixed in.  So it became a hard reset routine, which got used\n\t * in more places, and which coped with JTAG reset being forced as\n\t * part of SRST (srst_pulls_trst).\n\t *\n\t * And even more corner cases started to surface:  TRST and/or SRST\n\t * assertion timings matter; some chips need other JTAG operations;\n\t * TRST/SRST sequences can need to be different from these, etc.\n\t *\n\t * Systems should override that wrapper to support system-specific\n\t * requirements that this not-fully-generic code doesn't handle.\n\t *\n\t * REVISIT once Tcl code can read the reset_config modes, this won't\n\t * need to be a C routine at all...\n\t */\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\tjtag_add_reset(1, 1);\n\t\tif ((jtag_reset_config & RESET_SRST_PULLS_TRST) == 0)\n\t\t\tjtag_add_reset(0, 1);\n\t} else {\n\t\tjtag_add_reset(1, 0);\t/* TAP_RESET, using TMS+TCK or TRST */\n\t}\n\n\t/* some targets enable us to connect with srst asserted */\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\tjtag_add_reset(0, 1);\n\t\telse {\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t\t\tjtag_add_reset(0, 0);\n\t\t}\n\t} else\n\t\tjtag_add_reset(0, 0);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check that we can communication on the JTAG chain + eventually we want to\n\t * be able to perform enumeration only after OpenOCD has started\n\t * telnet and GDB server\n\t *\n\t * That would allow users to more easily perform any magic they need to before\n\t * reset happens.\n\t */\n\treturn jtag_init_inner(cmd_ctx);\n}\n\nint jtag_init(struct command_context *cmd_ctx)\n{\n\tint retval = adapter_init(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* guard against oddball hardware: force resets to be inactive */\n\tjtag_add_reset(0, 0);\n\n\t/* some targets enable us to connect with srst asserted */\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\tjtag_add_reset(0, 1);\n\t\telse\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t}\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (Jim_Eval_Named(cmd_ctx->interp, \"jtag_init\", __FILE__, __LINE__) != JIM_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nvoid jtag_set_verify(bool enable)\n{\n\tjtag_verify = enable;\n}\n\nbool jtag_will_verify(void)\n{\n\treturn jtag_verify;\n}\n\nvoid jtag_set_verify_capture_ir(bool enable)\n{\n\tjtag_verify_capture_ir = enable;\n}\n\nbool jtag_will_verify_capture_ir(void)\n{\n\treturn jtag_verify_capture_ir;\n}\n\nint jtag_power_dropout(int *dropout)\n{\n\tif (!is_adapter_initialized()) {\n\t\t/* TODO: as the jtag interface is not valid all\n\t\t * we can do at the moment is exit OpenOCD */\n\t\tLOG_ERROR(\"No Valid JTAG Interface Configured.\");\n\t\texit(-1);\n\t}\n\tif (adapter_driver->power_dropout)\n\t\treturn adapter_driver->power_dropout(dropout);\n\n\t*dropout = 0; /* by default we can't detect power dropout */\n\treturn ERROR_OK;\n}\n\nint jtag_srst_asserted(int *srst_asserted)\n{\n\tif (adapter_driver->srst_asserted)\n\t\treturn adapter_driver->srst_asserted(srst_asserted);\n\n\t*srst_asserted = 0; /* by default we can't detect srst asserted */\n\treturn ERROR_OK;\n}\n\nenum reset_types jtag_get_reset_config(void)\n{\n\treturn jtag_reset_config;\n}\nvoid jtag_set_reset_config(enum reset_types type)\n{\n\tjtag_reset_config = type;\n}\n\nint jtag_get_trst(void)\n{\n\treturn jtag_trst == 1;\n}\nint jtag_get_srst(void)\n{\n\treturn jtag_srst == 1;\n}\n\nvoid jtag_set_nsrst_delay(unsigned delay)\n{\n\tadapter_nsrst_delay = delay;\n}\nunsigned jtag_get_nsrst_delay(void)\n{\n\treturn adapter_nsrst_delay;\n}\nvoid jtag_set_ntrst_delay(unsigned delay)\n{\n\tjtag_ntrst_delay = delay;\n}\nunsigned jtag_get_ntrst_delay(void)\n{\n\treturn jtag_ntrst_delay;\n}\n\n\nvoid jtag_set_nsrst_assert_width(unsigned delay)\n{\n\tadapter_nsrst_assert_width = delay;\n}\nunsigned jtag_get_nsrst_assert_width(void)\n{\n\treturn adapter_nsrst_assert_width;\n}\nvoid jtag_set_ntrst_assert_width(unsigned delay)\n{\n\tjtag_ntrst_assert_width = delay;\n}\nunsigned jtag_get_ntrst_assert_width(void)\n{\n\treturn jtag_ntrst_assert_width;\n}\n\nstatic int jtag_select(struct command_context *ctx)\n{\n\tint retval;\n\n\t/* NOTE:  interface init must already have been done.\n\t * That works with only C code ... no Tcl glue required.\n\t */\n\n\tretval = jtag_register_commands(ctx);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = svf_register_commands(ctx);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = xsvf_register_commands(ctx);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ipdbg_register_commands(ctx);\n}\n\nstatic struct transport jtag_transport = {\n\t.name = \"jtag\",\n\t.select = jtag_select,\n\t.init = jtag_init,\n};\n\nstatic void jtag_constructor(void) __attribute__((constructor));\nstatic void jtag_constructor(void)\n{\n\ttransport_register(&jtag_transport);\n}\n\n/** Returns true if the current debug session\n * is using JTAG as its transport.\n */\nbool transport_is_jtag(void)\n{\n\treturn get_current_transport() == &jtag_transport;\n}\n\nint adapter_resets(int trst, int srst)\n{\n\tif (!get_current_transport()) {\n\t\tLOG_ERROR(\"transport is not selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (transport_is_jtag()) {\n\t\tif (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {\n\t\t\tLOG_ERROR(\"adapter has no srst signal\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* adapters without trst signal will eventually use tlr sequence */\n\t\tjtag_add_reset(trst, srst);\n\t\t/*\n\t\t * The jtag queue is still used for reset by some adapter. Flush it!\n\t\t * FIXME: To be removed when all adapter drivers will be updated!\n\t\t */\n\t\tjtag_execute_queue();\n\t\treturn ERROR_OK;\n\t} else if (transport_is_swd() || transport_is_hla() ||\n\t\t\t   transport_is_dapdirect_swd() || transport_is_dapdirect_jtag() ||\n\t\t\t   transport_is_swim()) {\n\t\tif (trst == TRST_ASSERT) {\n\t\t\tLOG_ERROR(\"transport %s has no trst signal\",\n\t\t\t\tget_current_transport()->name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {\n\t\t\tLOG_ERROR(\"adapter has no srst signal\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tadapter_system_reset(srst);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (trst == TRST_DEASSERT && srst == SRST_DEASSERT)\n\t\treturn ERROR_OK;\n\n\tLOG_ERROR(\"reset is not supported on transport %s\",\n\t\tget_current_transport()->name);\n\n\treturn ERROR_FAIL;\n}\n\nint adapter_assert_reset(void)\n{\n\tif (transport_is_jtag()) {\n\t\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\tjtag_add_reset(1, 1);\n\t\telse\n\t\t\tjtag_add_reset(0, 1);\n\t\treturn ERROR_OK;\n\t} else if (transport_is_swd() || transport_is_hla() ||\n\t\t\t   transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||\n\t\t\t   transport_is_swim())\n\t\treturn adapter_system_reset(1);\n\telse if (get_current_transport())\n\t\tLOG_ERROR(\"reset is not supported on %s\",\n\t\t\tget_current_transport()->name);\n\telse\n\t\tLOG_ERROR(\"transport is not selected\");\n\treturn ERROR_FAIL;\n}\n\nint adapter_deassert_reset(void)\n{\n\tif (transport_is_jtag()) {\n\t\tjtag_add_reset(0, 0);\n\t\treturn ERROR_OK;\n\t} else if (transport_is_swd() || transport_is_hla() ||\n\t\t\t   transport_is_dapdirect_jtag() || transport_is_dapdirect_swd() ||\n\t\t\t   transport_is_swim())\n\t\treturn adapter_system_reset(0);\n\telse if (get_current_transport())\n\t\tLOG_ERROR(\"reset is not supported on %s\",\n\t\t\tget_current_transport()->name);\n\telse\n\t\tLOG_ERROR(\"transport is not selected\");\n\treturn ERROR_FAIL;\n}\n\nint adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,\n\t\tuint32_t port_size, unsigned int *trace_freq,\n\t\tunsigned int traceclkin_freq, uint16_t *prescaler)\n{\n\tif (adapter_driver->config_trace) {\n\t\treturn adapter_driver->config_trace(enabled, pin_protocol, port_size, trace_freq,\n\t\t\ttraceclkin_freq, prescaler);\n\t} else if (enabled) {\n\t\tLOG_ERROR(\"The selected interface does not support tracing\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint adapter_poll_trace(uint8_t *buf, size_t *size)\n{\n\tif (adapter_driver->poll_trace)\n\t\treturn adapter_driver->poll_trace(buf, size);\n\n\treturn ERROR_FAIL;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libocdjtagdrivers.la\n%C%_libocdjtagdrivers_la_LIBADD =\n\n%C%_libocdjtagdrivers_la_SOURCES = \\\n\t$(DRIVERFILES) \\\n\t$(DRIVERHEADERS)\n\n%C%_libocdjtagdrivers_la_CPPFLAGS = $(AM_CPPFLAGS)\n\nULINK_FIRMWARE = %D%/OpenULINK\n\nEXTRA_DIST += $(ULINK_FIRMWARE) \\\n\t%D%/usb_blaster/README.CheapClone \\\n\t%D%/Makefile.rlink \\\n\t%D%/rlink_call.m4 \\\n\t%D%/rlink_init.m4\n\nDRIVERFILES =\n\n# Standard Driver: common files\nDRIVERFILES += %D%/driver.c\n\nif USE_LIBUSB1\nDRIVERFILES += %D%/libusb_helper.c\n%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBUSB1_CFLAGS)\n%C%_libocdjtagdrivers_la_LIBADD += $(LIBUSB1_LIBS)\nendif\n\nif USE_LIBFTDI\n%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBFTDI_CFLAGS)\n%C%_libocdjtagdrivers_la_LIBADD += $(LIBFTDI_LIBS)\nendif\n\nif USE_LIBGPIOD\n%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBGPIOD_CFLAGS)\n%C%_libocdjtagdrivers_la_LIBADD += $(LIBGPIOD_LIBS)\nendif\n\nif USE_HIDAPI\n%C%_libocdjtagdrivers_la_CPPFLAGS += $(HIDAPI_CFLAGS)\n%C%_libocdjtagdrivers_la_LIBADD += $(HIDAPI_LIBS)\nendif\n\nif USE_LIBJAYLINK\n%C%_libocdjtagdrivers_la_CPPFLAGS += $(LIBJAYLINK_CFLAGS)\n%C%_libocdjtagdrivers_la_LIBADD += $(LIBJAYLINK_LIBS)\nendif\n\nif JLINK\nDRIVERFILES += %D%/jlink.c\nif INTERNAL_LIBJAYLINK\nSUBDIRS += %D%/libjaylink\nDIST_SUBDIRS += %D%/libjaylink\n\n%C%_libocdjtagdrivers_la_LIBADD += %D%/libjaylink/libjaylink/libjaylink.la\n%C%_libocdjtagdrivers_la_CPPFLAGS += -I$(builddir)/%D%/libjaylink/libjaylink -I$(srcdir)/%D%/libjaylink\nendif\nendif\n\nif BITBANG\nDRIVERFILES += %D%/bitbang.c\nendif\nif PARPORT\nDRIVERFILES += %D%/parport.c\nendif\nif DUMMY\nDRIVERFILES += %D%/dummy.c\nendif\nif FTDI\nDRIVERFILES += %D%/ftdi.c %D%/mpsse.c\nendif\nif LINUXGPIOD\nDRIVERFILES += %D%/linuxgpiod.c\nendif\nif JTAG_VPI\nDRIVERFILES += %D%/jtag_vpi.c\nendif\nif VDEBUG\nDRIVERFILES += %D%/vdebug.c\nendif\nif JTAG_DPI\nDRIVERFILES += %D%/jtag_dpi.c\nendif\nif USB_BLASTER_DRIVER\n%C%_libocdjtagdrivers_la_LIBADD += %D%/usb_blaster/libocdusbblaster.la\ninclude %D%/usb_blaster/Makefile.am\nendif\nif FT232R\nDRIVERFILES += %D%/ft232r.c\nendif\nif AMTJTAGACCEL\nDRIVERFILES += %D%/amt_jtagaccel.c\nendif\nif EP93XX\nDRIVERFILES += %D%/ep93xx.c\nendif\nif AT91RM9200\nDRIVERFILES += %D%/at91rm9200.c\nendif\nif GW16012\nDRIVERFILES += %D%/gw16012.c\nendif\nif BITQ\nDRIVERFILES += %D%/bitq.c\nendif\nif PRESTO\nDRIVERFILES += %D%/presto.c\nendif\nif ESP_USB_JTAG\nDRIVERFILES += %D%/esp_usb_jtag.c\nendif\nif USBPROG\nDRIVERFILES += %D%/usbprog.c\nendif\nif RLINK\nDRIVERFILES += %D%/rlink.c %D%/rlink_speed_table.c\nendif\nif ULINK\nDRIVERFILES += %D%/ulink.c\nulinkdir = $(pkgdatadir)/OpenULINK\ndist_ulink_DATA = $(ULINK_FIRMWARE)/ulink_firmware.hex\n%C%_libocdjtagdrivers_la_LIBADD += -lm\nendif\nif VSLLINK\nDRIVERFILES += %D%/versaloon/usbtoxxx/usbtogpio.c\nDRIVERFILES += %D%/versaloon/usbtoxxx/usbtojtagraw.c\nDRIVERFILES += %D%/versaloon/usbtoxxx/usbtoswd.c\nDRIVERFILES += %D%/versaloon/usbtoxxx/usbtopwr.c\nDRIVERFILES += %D%/versaloon/usbtoxxx/usbtoxxx.c\nDRIVERFILES += %D%/versaloon/versaloon.c\nDRIVERFILES += %D%/vsllink.c\nendif\nif ARMJTAGEW\nDRIVERFILES += %D%/arm-jtag-ew.c\nendif\nif BUSPIRATE\nDRIVERFILES += %D%/buspirate.c\nendif\nif REMOTE_BITBANG\nDRIVERFILES += %D%/remote_bitbang.c\nendif\nif HLADAPTER_STLINK\nDRIVERFILES += %D%/stlink_usb.c\nendif\nif HLADAPTER_ICDI\nDRIVERFILES += %D%/ti_icdi_usb.c\nendif\nif HLADAPTER_NULINK\nDRIVERFILES += %D%/nulink_usb.c\nendif\nif RSHIM\nDRIVERFILES += %D%/rshim.c\nendif\nif OSBDM\nDRIVERFILES += %D%/osbdm.c\nendif\nif OPENDOUS\nDRIVERFILES += %D%/opendous.c\nendif\nif SYSFSGPIO\nDRIVERFILES += %D%/sysfsgpio.c\nendif\nif XLNX_PCIE_XVC\nDRIVERFILES += %D%/xlnx-pcie-xvc.c\nendif\nif BCM2835GPIO\nDRIVERFILES += %D%/bcm2835gpio.c\nendif\nif OPENJTAG\nDRIVERFILES += %D%/openjtag.c\nendif\nif CMSIS_DAP_HID\nDRIVERFILES += %D%/cmsis_dap_usb_hid.c\nDRIVERFILES += %D%/cmsis_dap.c\nendif\nif CMSIS_DAP_USB\nDRIVERFILES += %D%/cmsis_dap_usb_bulk.c\nif !CMSIS_DAP_HID\nDRIVERFILES += %D%/cmsis_dap.c\nendif\nendif\nif IMX_GPIO\nDRIVERFILES += %D%/imx_gpio.c\nendif\nif KITPROG\nDRIVERFILES += %D%/kitprog.c\nendif\nif XDS110\nDRIVERFILES += %D%/xds110.c\nendif\nif AM335XGPIO\nDRIVERFILES += %D%/am335xgpio.c\nendif\nif CH347\nDRIVERFILES += %D%/ch347.c\nendif\n\nDRIVERHEADERS = \\\n\t%D%/bitbang.h \\\n\t%D%/bitq.h \\\n\t%D%/libftdi_helper.h \\\n\t%D%/libusb_helper.h \\\n\t%D%/cmsis_dap.h \\\n\t%D%/minidriver_imp.h \\\n\t%D%/mpsse.h \\\n\t%D%/rlink.h \\\n\t%D%/rlink_dtc_cmd.h \\\n\t%D%/rlink_ep1_cmd.h \\\n\t%D%/rlink_st7.h \\\n\t%D%/versaloon/usbtoxxx/usbtoxxx.h \\\n\t%D%/versaloon/usbtoxxx/usbtoxxx_internal.h \\\n\t%D%/versaloon/versaloon.h \\\n\t%D%/versaloon/versaloon_include.h \\\n\t%D%/versaloon/versaloon_internal.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/Makefile.rlink",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright (C) 2008 Lou Deluxe\n# lou.openocd012@fixit.nospammail.net\n#\n\nTOP = ../../..\nINTERFACE_NAME = rlink\n\nPERL = perl\nM4 = m4\n\nTARGETDIR = ${TOP}/src/target\nTOOLSDIR = ${TOP}/tools\n\nMAKE_SPEED_TABLE = ${TOOLSDIR}/rlink_make_speed_table/rlink_make_speed_table\nST7_DTC_AS = ${TOOLSDIR}/st7_dtc_as/st7_dtc_as\n\nOPENOCD = ${TOP}/src/openocd\nOPENOCD_CONFIG = -s ${TARGETDIR}\nOPENOCD_CONFIG += -f interface/rlink.cfg\nOPENOCD_CONFIG += -f board/stm32f10x_128k_eval.cfg\n\nPATCHFILE = /tmp/openocd_${INTERFACE_NAME}.diff.gz\n\n# relative to ${TOP}\nSVNADDFILES =\nSVNADDFILES += src/target/interface/rlink.cfg\nSVNADDFILES += src/jtag/${INTERFACE_NAME}.c\nSVNADDFILES += src/jtag/${INTERFACE_NAME}\n\nPRESCALERS = 64 11 8 2\n\nDTCFILES =\nDTCFILES += $(addsuffix _init.dtc, ${PRESCALERS})\nDTCFILES += $(addsuffix _call.dtc, ${PRESCALERS})\n\ndefault: rlink_speed_table.c clean\n\n%_init.fsm: rlink_init.m4\n\t${M4} -P -DSHIFTER_PRESCALER=`echo \"$@\" | sed -e's/_.*//'` $< > $@\n\n%_call.fsm: rlink_call.m4\n\t${M4} -P -DSHIFTER_PRESCALER=`echo \"$@\" | sed -e's/_.*//'` $< > $@\n\n%.dtc: %.fsm\n\t${ST7_DTC_AS} -b -o $@ -i $< > /dev/null\n\nrlink_speed_table.c: ${DTCFILES}\n\t${MAKE_SPEED_TABLE} ${PRESCALERS} > $@ || rm $@\n\nclean:\n\t-rm *.dtc *.fsm\n\ndistclean: clean\n\ntest: default\n\t(cd ${TOP} && (rm src/jtag/${INTERFACE_NAME}.o; ${MAKE}))\n\t${OPENOCD} -d0 ${OPENOCD_CONFIG} -c init -c 'poll off'\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/README",
    "content": "This is the OpenULINK firmware for the Keil ULINK JTAG adapter.\n\nThe main components of the Keil ULINK adapter are:\n- Cypress EZ-USB microcontroller: enhanced 8051 CPU + USB core (1.1 Full-Speed)\n- SRAM memory chip\n- Level shifters to support different JTAG signal voltage levels\n- Pin headers for various JTAG pin assignments\n\nThis firmware can only be run on the ORIGINAL Keil ULINK adapter, not on the\nnewer ULINK2, ULINK-ME or ULINK-PRO, as these adapters are based on different\nhardware.\n\nTo compile the firmware, the SDCC compiler package is required. Most Linux\ndistributions include SDCC in their official package repositories. The SDCC\nsource code can be found at http://sdcc.sourceforge.net/\nSimply type \"make hex\" in the OpenULINK directory to compile the firmware.\n\"make clean\" will remove all generated files except the Intel HEX file required\nfor downloading the firmware to the ULINK adapter.\n\nNote that the EZ-USB microcontroller does not have on-chip flash, nor does the\nKeil ULINK include on-board memory to store the firmware program of the EZ-USB.\nInstead, upon initial connection of the ULINK adapter to the host PC via USB,\nthe EZ-USB core has enough intelligence to act as a stand-alone USB device,\nresponding to USB control requests and allowing firmware download via a special\nVENDOR-type control request. Then, the EZ-USB microcontroller simulates a\ndisconnect and re-connect to the USB bus. It may take up to two seconds for the\nhost to recognize the newly connected device before OpenOCD can proceed to\nexecute JTAG commands. This delay is only visible when OpenOCD first uses a\nblank (unconfigured) ULINK device.\n\nOnce the user disconnects the ULINK adapter, all its memory contents are lost\nand the firmware download process has to be executed again. This also maintains\ncompatibility with the original Keil uVision IDE, which will happily download\nits own firmware image to a blank ULINK adapter.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/common.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __COMMON_H\n#define __COMMON_H\n\n#define DIV_ROUND_UP(m, n)  (((m) + (n) - 1) / (n))\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/delay.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __DELAY_H\n#define __DELAY_H\n\n#include <stdint.h>\n\n#define NOP { __asm nop __endasm; }\n\nvoid delay_5us(void);\nvoid delay_1ms(void);\n\nvoid delay_us(uint16_t delay);\nvoid delay_ms(uint16_t delay);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/io.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __IO_H\n#define __IO_H\n\n#include \"reg_ezusb.h\"\n\n/***************************************************************************\n *  JTAG Signals:                                                          *\n ***************************************************************************\n * TMS ....... Test Mode Select                                            *\n * TCK ....... Test Clock                                                  *\n * TDI ....... Test Data Input  (from device point of view, not JTAG       *\n *             adapter point of view!)                                     *\n * TDO ....... Test Data Output (from device point of view, not JTAG       *\n *             adapter point of view!)                                     *\n * TRST ...... Test Reset: Used to reset the TAP Finite State Machine      *\n *             into the Test Logic Reset state                             *\n * RTCK ...... Return Test Clock                                           *\n * OCDSE ..... Enable/Disable OCDS interface (Infineon specific) - shared  *\n *             with /JEN                                                   *\n * TRAP ...... Trap Condition (Infineon specific) - shared with TSTAT      *\n * BRKIN ..... Hardware Break-In (Infineon specific)                       *\n * BRKOUT .... Hardware Break-Out (Infineon specific)                      *\n * /JEN ...... JTAG-Enable (STMicroelectronics specific) - shared          *\n *             with OCDSE                                                  *\n * TSTAT ..... JTAG ISP Status (STMicroelectronics specific) - shared      *\n *             with TRAP                                                   *\n * RESET ..... Chip Reset (STMicroelectronics specific)                    *\n * /TERR ..... JTAG ISP Error (STMicroelectronics specific) - shared       *\n *             with BRKOUT                                                 *\n ***************************************************************************/\n\n/* PORT A */\n#define PIN_U_OE      OUTA0\n/* PA1 Not Connected */\n#define PIN_OE        OUTA2\n/* PA3 Not Connected */\n#define PIN_RUN_LED   OUTA4\n#define PIN_TDO       PINA5\n#define PIN_BRKOUT    PINA6\n#define PIN_COM_LED   OUTA7\n\n/* PORT B */\n#define PIN_TDI       OUTB0\n#define PIN_TMS       OUTB1\n#define PIN_TCK       OUTB2\n#define PIN_TRST      OUTB3\n#define PIN_BRKIN     OUTB4\n#define PIN_RESET     OUTB5\n#define PIN_OCDSE     OUTB6\n#define PIN_TRAP      PINB7\n\n/* JTAG Signals with direction 'OUT' on port B */\n#define MASK_PORTB_DIRECTION_OUT (PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET | PIN_OCDSE)\n\n/* PORT C */\n#define PIN_RXD0      PINC0\n#define PIN_TXD0      OUTC1\n#define PIN_RESET_2   PINC2\n/* PC3 Not Connected */\n/* PC4 Not Connected */\n#define PIN_RTCK      PINC5\n#define PIN_WR        OUTC6\n/* PC7 Not Connected */\n\n/* LED Macros */\n#define SET_RUN_LED()     (OUTA &= ~PIN_RUN_LED)\n#define CLEAR_RUN_LED()   (OUTA |=  PIN_RUN_LED)\n\n#define SET_COM_LED()     (OUTA &= ~PIN_COM_LED)\n#define CLEAR_COM_LED()   (OUTA |=  PIN_COM_LED)\n\n/* JTAG Pin Macros */\n#define GET_TMS()         (PINSB & PIN_TMS)\n#define GET_TCK()         (PINSB & PIN_TCK)\n\n#define GET_TDO()         (PINSA & PIN_TDO)\n#define GET_BRKOUT()      (PINSA & PIN_BRKOUT)\n#define GET_TRAP()        (PINSB & PIN_TRAP)\n#define GET_RTCK()        (PINSC & PIN_RTCK)\n\n#define SET_TMS_HIGH()    (OUTB |=  PIN_TMS)\n#define SET_TMS_LOW()     (OUTB &= ~PIN_TMS)\n\n#define SET_TCK_HIGH()    (OUTB |=  PIN_TCK)\n#define SET_TCK_LOW()     (OUTB &= ~PIN_TCK)\n\n#define SET_TDI_HIGH()    (OUTB |=  PIN_TDI)\n#define SET_TDI_LOW()     (OUTB &= ~PIN_TDI)\n\n/* TRST and RESET are low-active and inverted by hardware. SET_HIGH de-asserts\n * the signal (enabling reset), SET_LOW asserts the signal (disabling reset) */\n#define SET_TRST_HIGH()   (OUTB |=  PIN_TRST)\n#define SET_TRST_LOW()    (OUTB &= ~PIN_TRST)\n\n#define SET_RESET_HIGH()  (OUTB |=  PIN_RESET)\n#define SET_RESET_LOW()   (OUTB &= ~PIN_RESET)\n\n#define SET_OCDSE_HIGH()  (OUTB |=  PIN_OCDSE)\n#define SET_OCDSE_LOW()   (OUTB &= ~PIN_OCDSE)\n\n#define SET_BRKIN_HIGH()  (OUTB |=  PIN_BRKIN)\n#define SET_BRKIN_LOW()   (OUTB &= ~PIN_BRKIN)\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __JTAG_H\n#define __JTAG_H\n\n#include <stdint.h>\n\n#define NOP { __asm nop __endasm; }\n\nvoid jtag_scan_in(uint8_t out_offset, uint8_t in_offset);\nvoid jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset);\n\nvoid jtag_scan_out(uint8_t out_offset);\nvoid jtag_slow_scan_out(uint8_t out_offset);\n\nvoid jtag_scan_io(uint8_t out_offset, uint8_t in_offset);\nvoid jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset);\n\nvoid jtag_clock_tck(uint16_t count);\nvoid jtag_slow_clock_tck(uint16_t count);\nvoid jtag_clock_tms(uint8_t count, uint8_t sequence);\nvoid jtag_slow_clock_tms(uint8_t count, uint8_t sequence);\n\nuint16_t  jtag_get_signals(void);\nvoid jtag_set_signals(uint8_t low, uint8_t high);\n\nvoid jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,\n\t\tuint8_t scan_io, uint8_t tck, uint8_t tms);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/main.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __MAIN_H\n#define __MAIN_H\n\nvoid io_init(void);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/msgtypes.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n/**\n * @file\n * Definition of the commands supported by the OpenULINK firmware.\n *\n * Basically, two types of commands can be distinguished:\n *  - Commands with fixed payload size\n *  - Commands with variable payload size\n *\n * SCAN commands (in all variations) carry payloads of variable size, all\n * other commands carry payloads of fixed size.\n *\n * In the case of SCAN commands, the payload size (n) is calculated by\n * dividing the scan_size_bits variable by 8, rounding up the result.\n *\n * Offset zero always contains the command ID.\n *\n ****************************************************************************\n * CMD_SCAN_IN, CMD_SLOW_SCAN_IN:                                           *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: scan_size_bytes                                                *\n * offset 2: bits_last_byte                                                 *\n * offset 3: tms_count_start + tms_count_end                                *\n * offset 4: tms_sequence_start                                             *\n * offset 5: tms_sequence_end                                               *\n *                                                                          *\n * IN:                                                                      *\n * offset 0..n: TDO data                                                    *\n ****************************************************************************\n * CMD_SCAN_OUT, CMD_SLOW_SCAN_OUT:                                         *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: scan_size_bytes                                                *\n * offset 2: bits_last_byte                                                 *\n * offset 3: tms_count_start + tms_count_end                                *\n * offset 4: tms_sequence_start                                             *\n * offset 5: tms_sequence_end                                               *\n * offset 6..x: TDI data                                                    *\n ****************************************************************************\n * CMD_SCAN_IO, CMD_SLOW_SCAN_IO:                                           *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: scan_size_bytes                                                *\n * offset 2: bits_last_byte                                                 *\n * offset 3: tms_count_start + tms_count_end                                *\n * offset 4: tms_sequence_start                                             *\n * offset 5: tms_sequence_end                                               *\n * offset 6..x: TDI data                                                    *\n *                                                                          *\n * IN:                                                                      *\n * offset 0..n: TDO data                                                    *\n ****************************************************************************\n * CMD_CLOCK_TMS, CMD_SLOW_CLOCK_TMS:                                       *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: tms_count                                                      *\n * offset 2: tms_sequence                                                   *\n ****************************************************************************\n * CMD_CLOCK_TCK, CMD_SLOW_CLOCK_TCK:                                       *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: low byte of tck_count                                          *\n * offset 2: high byte of tck_count                                         *\n ****************************************************************************\n * CMD_CLOCK_SLEEP_US:                                                      *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: low byte of sleep_us                                           *\n * offset 2: high byte of sleep_us                                          *\n ****************************************************************************\n * CMD_CLOCK_SLEEP_MS:                                                      *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: low byte of sleep_ms                                           *\n * offset 2: high byte of sleep_ms                                          *\n ****************************************************************************\n * CMD_GET_SIGNALS:                                                         *\n *                                                                          *\n * IN:                                                                      *\n * offset 0: current state of input signals                                 *\n * offset 1: current state of output signals                                *\n ****************************************************************************\n * CMD_SET_SIGNALS:                                                         *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: signals that should be de-asserted                             *\n * offset 2: signals that should be asserted                                *\n ****************************************************************************\n * CMD_CONFIGURE_TCK_FREQ:                                                  *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: delay value for scan_in function                               *\n * offset 2: delay value for scan_out function                              *\n * offset 3: delay value for scan_io function                               *\n * offset 4: delay value for clock_tck function                             *\n * offset 5: delay value for clock_tms function                             *\n ****************************************************************************\n * CMD_SET_LEDS:                                                            *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: LED states:                                                    *\n *           Bit 0: turn COM LED on                                         *\n *           Bit 1: turn RUN LED on                                         *\n *           Bit 2: turn COM LED off                                        *\n *           Bit 3: turn RUN LED off                                        *\n *           Bits 7..4: Reserved                                            *\n ****************************************************************************\n * CMD_TEST:                                                                *\n *                                                                          *\n * OUT:                                                                     *\n * offset 1: unused dummy value                                             *\n ****************************************************************************\n */\n\n#ifndef __MSGTYPES_H\n#define __MSGTYPES_H\n\n/*\n * Command IDs:\n *\n * Bits 7..6: Reserved, should always be zero\n * Bits 5..0: Command ID. There are 62 usable IDs. Of this 63 available IDs,\n *            the IDs 0x00..0x1F are commands with variable payload size,\n *            the IDs 0x20..0x3F are commands with fixed payload size.\n */\n\n#define CMD_ID_MASK             0x3F\n\n/* Commands with variable payload size */\n#define CMD_SCAN_IN             0x00\n#define CMD_SLOW_SCAN_IN        0x01\n#define CMD_SCAN_OUT            0x02\n#define CMD_SLOW_SCAN_OUT       0x03\n#define CMD_SCAN_IO             0x04\n#define CMD_SLOW_SCAN_IO        0x05\n\n/* Commands with fixed payload size */\n#define CMD_CLOCK_TMS           0x20\n#define CMD_SLOW_CLOCK_TMS      0x21\n#define CMD_CLOCK_TCK           0x22\n#define CMD_SLOW_CLOCK_TCK      0x23\n#define CMD_SLEEP_US            0x24\n#define CMD_SLEEP_MS            0x25\n#define CMD_GET_SIGNALS         0x26\n#define CMD_SET_SIGNALS         0x27\n#define CMD_CONFIGURE_TCK_FREQ  0x28\n#define CMD_SET_LEDS            0x29\n#define CMD_TEST                0x2A\n\n/* JTAG signal definition for jtag_get_signals() -- Input signals! */\n#define SIGNAL_TDO      (1<<0)\n#define SIGNAL_BRKOUT   (1<<1)\n#define SIGNAL_TRAP     (1<<2)\n#define SIGNAL_RTCK     (1<<3)\n\n/* JTAG signal definition for jtag_get_signals() -- Output signals! */\n#define SIGNAL_TDI      (1<<0)\n#define SIGNAL_TMS      (1<<1)\n#define SIGNAL_TCK      (1<<2)\n#define SIGNAL_TRST     (1<<3)\n#define SIGNAL_BRKIN    (1<<4)\n#define SIGNAL_RESET    (1<<5)\n#define SIGNAL_OCDSE    (1<<6)\n\n/* LED definitions for CMD_SET_LEDS and CMD_CLEAR_LEDS commands */\n#define COM_LED_ON      (1<<0)\n#define RUN_LED_ON      (1<<1)\n#define COM_LED_OFF     (1<<2)\n#define RUN_LED_OFF     (1<<3)\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/protocol.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __PROTOCOL_H\n#define __PROTOCOL_H\n\n#include \"common.h\"\n#include <stdbool.h>\n\nvoid execute_set_led_command(void);\n\nbool execute_command(void);\nvoid command_loop(void);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/reg_ezusb.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef REG_EZUSB_H\n#define REG_EZUSB_H\n\n/**\n * @file\n * All information in this file was taken from the EZ-USB Technical\n * Reference Manual, Cypress Semiconductor, 3901 North First Street\n * San Jose, CA 95134 (www.cypress.com).\n *\n * The EZ-USB Technical Reference Manual is called \"EZ-USB TRM\" hereafter.\n *\n * The following bit name  definitions differ from those in the EZ-USB TRM:\n * - All lowercase characters in the EZ-USB TRM bit names have been converted\n *   to capitals (e. g. \"WakeSRC\" converted to \"WAKESRC\").\n * - CPUCS:  8051RES is named \"RES8051\".\n * - ISOCTL: Two MBZ (\"Must Be Zero\") bits are named \"MBZ0\" and \"MBZ1\".\n * - I2CS: STOP and START bits are preceded by \"I2C_\"\n * - INxCS, OUTxCS: the busy and stall bits are named \"EPBSY\" and \"EPSTALL\".\n * - TOGCTL: EZ-USB TRM bit names are preceded by \"TOG_\".\n */\n\n/* Compiler-specific definitions of SBIT, SFR, SFRX, ... macros */\n#include <mcs51/compiler.h>\n\n/* Bit vectors */\n#define bmBit0      0x01\n#define bmBit1      0x02\n#define bmBit2      0x04\n#define bmBit3      0x08\n#define bmBit4      0x10\n#define bmBit5      0x20\n#define bmBit6      0x40\n#define bmBit7      0x80\n\n/**************************************************************************\n ************************ Special Function Registers **********************\n ***************************************************************************/\n\n/* See EZ-USB TRM, pp. A-9 - A-10 */\n\nSFR(SP,             0x81);\nSFR(DPL0,           0x82);\nSFR(DPH0,           0x83);\nSFR(DPL1,           0x84);\nSFR(DPL2,           0x85);\n\nSFR(DPS,            0x86);\n#define SEL         bmBit0\n/* Bit 1 read-only, always reads '0' */\n/* Bit 2 read-only, always reads '0' */\n/* Bit 3 read-only, always reads '0' */\n/* Bit 4 read-only, always reads '0' */\n/* Bit 5 read-only, always reads '0' */\n/* Bit 6 read-only, always reads '0' */\n/* Bit 7 read-only, always reads '0' */\n\nSFR(PCON,           0x87);\n#define IDLE        bmBit0\n#define STOP        bmBit1\n#define GF0         bmBit2\n#define GF1         bmBit3\n/* Bit 4 read-only, always reads '1' */\n/* Bit 5 read-only, always reads '1' */\n/* Bit 6 unused */\n#define SMOD0     bmBit7\n\nSFR(TCON,           0x88);\nSBIT(IT0,           0x88, 0);\nSBIT(IE0,           0x88, 1);\nSBIT(IT1,           0x88, 2);\nSBIT(IE1,           0x88, 3);\nSBIT(TR0,           0x88, 4);\nSBIT(TF0,           0x88, 5);\nSBIT(TR1,           0x88, 6);\nSBIT(TF1,           0x88, 7);\n\nSFR(TMOD,           0x89);\n/* Some bits in this register share the same name in the EZ-USB TRM. Therefore,\n * we add a '0'/'1' to distinguish them */\n#define M00         bmBit0\n#define M01         bmBit1\n#define CT0         bmBit2\n#define GATE0       bmBit3\n#define M10         bmBit4\n#define M11         bmBit5\n#define CT1         bmBit6\n#define GATE1       bmBit7\n\nSFR(TL0,            0x8A);\nSFR(TL1,            0x8B);\nSFR(TH0,            0x8C);\nSFR(TH1,            0x8D);\n\nSFR(CKCON,          0x8E);\n#define MD0         bmBit0\n#define MD1         bmBit1\n#define MD2         bmBit2\n#define T0M         bmBit3\n#define T1M         bmBit4\n#define T2M         bmBit5\n/* Bit 6 unused */\n/* Bit 7 unused */\n\nSFR(SPC_FNC,        0x8D);\n#define bmWRS       bmBit0\n/* Bit 1 read-only, always reads '0' */\n/* Bit 2 read-only, always reads '0' */\n/* Bit 3 read-only, always reads '0' */\n/* Bit 4 read-only, always reads '0' */\n/* Bit 5 read-only, always reads '0' */\n/* Bit 6 read-only, always reads '0' */\n/* Bit 7 read-only, always reads '0' */\n\nSFR(EXIF,           0x91);\n/* Bit 0 read-only, always reads '0' */\n/* Bit 1 read-only, always reads '0' */\n/* Bit 2 read-only, always reads '0' */\n/* Bit 3 read-only, always reads '1' */\n#define USBINT      bmBit4\n#define I2CINT      bmBit5\n#define IE4         bmBit6\n#define IE5         bmBit7\n\n/* Definition of the _XPAGE register, according to SDCC Compiler User Guide,\n * Version 3.0.1, Chapter 4, p. 61. Also see EZ-USB TRM, p. 2-4. */\nSFR(MPAGE,          0x92);\nSFR(_XPAGE,         0x92);\n\nSFR(SCON0,          0x98);\nSBIT(RI_0,          0x98, 0);\nSBIT(TI_0,          0x98, 1);\nSBIT(RB8_0,         0x98, 2);\nSBIT(TB8_0,         0x98, 3);\nSBIT(REN_0,         0x98, 4);\nSBIT(SM2_0,         0x98, 5);\nSBIT(SM1_0,         0x98, 6);\nSBIT(SM0_0,         0x98, 7);\n\nSFR(SBUF0,          0x99);\n\nSFR(IE,             0xA8);\nSBIT(EX0,           0xA8, 0);\nSBIT(ET0,           0xA8, 1);\nSBIT(EX1,           0xA8, 2);\nSBIT(ET1,           0xA8, 3);\nSBIT(ES0,           0xA8, 4);\nSBIT(ET2,           0xA8, 5);\nSBIT(ES1,           0xA8, 6);\nSBIT(EA,            0xA8, 7);\n\nSFR(IP,             0xB8);\nSBIT(PX0,           0xB8, 0);\nSBIT(PT0,           0xB8, 1);\nSBIT(PX1,           0xB8, 2);\nSBIT(PT1,           0xB8, 3);\nSBIT(PS0,           0xB8, 4);\nSBIT(PT2,           0xB8, 5);\nSBIT(PS1,           0xB8, 6);\n/* Bit 7 read-only, always reads '1' */\n\nSFR(SCON1,          0xC0);\nSBIT(RI_1,          0xC0, 0);\nSBIT(TI_1,          0xC0, 1);\nSBIT(RB8_1,         0xC0, 2);\nSBIT(TB8_1,         0xC0, 3);\nSBIT(REN_1,         0xC0, 4);\nSBIT(SM2_1,         0xC0, 5);\nSBIT(SM1_1,         0xC0, 6);\nSBIT(SM0_1,         0xC0, 7);\n\nSFR(SBUF1,          0xC1);\n\nSFR(T2CON,          0xC8);\nSBIT(CPRL2,         0xC8, 0);\nSBIT(CT2,           0xC8, 1);\nSBIT(TR2,           0xC8, 2);\nSBIT(EXEN2,         0xC8, 3);\nSBIT(TCLK,          0xC8, 4);\nSBIT(RCLK,          0xC8, 5);\nSBIT(EXF2,          0xC8, 6);\nSBIT(TF2,           0xC8, 7);\n\nSFR(RCAP2L,         0xCA);\nSFR(RCAP2H,         0xCB);\nSFR(TL2,            0xCC);\nSFR(TH2,            0xCD);\n\nSFR(PSW,            0xD0);\nSBIT(P,             0xD0, 0);\nSBIT(F1,            0xD0, 1);\nSBIT(OV,            0xD0, 2);\nSBIT(RS0,           0xD0, 3);\nSBIT(RS1,           0xD0, 4);\nSBIT(F0,            0xD0, 5);\nSBIT(AC,            0xD0, 6);\nSBIT(CY,            0xD0, 7);\n\nSFR(EICON,          0xD8);\n/* Bit 0 read-only, always reads '0' */\n/* Bit 1 read-only, always reads '0' */\n/* Bit 2 read-only, always reads '0' */\nSBIT(INT6,          0xD8, 3);\nSBIT(RESI,          0xD8, 4);\nSBIT(ERESI,         0xD8, 5);\n/* Bit 6 read-only, always reads '1' */\nSBIT(SMOD1,         0xD8, 7);\n\nSFR(ACC,            0xE0);\n\nSFR(EIE,            0xE8);\nSBIT(EUSB,          0xE8, 0);\nSBIT(EI2C,          0xE8, 1);\nSBIT(EX4,           0xE8, 2);\nSBIT(EX5,           0xE8, 3);\nSBIT(EWDI,          0xE8, 4);\n/* Bit 5 read-only, always reads '1' */\n/* Bit 6 read-only, always reads '1' */\n/* Bit 7 read-only, always reads '1' */\n\nSFR(B,              0xF0);\n\nSFR(EIP,            0xF8);\nSBIT(PUSB,          0xF8, 0);\nSBIT(PI2C,          0xF8, 1);\nSBIT(PX4,           0xF8, 2);\nSBIT(PX5,           0xF8, 3);\nSBIT(PX6,           0xF8, 4);\n/* Bit 5 read-only, always reads '1' */\n/* Bit 6 read-only, always reads '1' */\n/* Bit 7 read-only, always reads '1' */\n\n/**************************************************************************\n ***************************** XDATA Registers ****************************\n ***************************************************************************/\n\n/************************ Endpoint 0-7 Data Buffers ************************/\nSFRX(OUT7BUF[64],   0x7B40);\nSFRX(IN7BUF[64],    0x7B80);\nSFRX(OUT6BUF[64],   0x7BC0);\nSFRX(IN6BUF[64],    0x7C00);\nSFRX(OUT5BUF[64],   0x7C40);\nSFRX(IN5BUF[64],    0x7C80);\nSFRX(OUT4BUF[64],   0x7CC0);\nSFRX(IN4BUF[64],    0x7D00);\nSFRX(OUT3BUF[64],   0x7D40);\nSFRX(IN3BUF[64],    0x7D80);\nSFRX(OUT2BUF[64],   0x7DC0);\nSFRX(IN2BUF[64],    0x7E00);\nSFRX(OUT1BUF[64],   0x7E40);\nSFRX(IN1BUF[64],    0x7E80);\nSFRX(OUT0BUF[64],   0x7EC0);\nSFRX(IN0BUF[64],    0x7F00);\n/* 0x7F40 - 0x7F5F reserved */\n\n/**************************** Isochronous Data *****************************/\nSFRX(OUT8DATA,      0x7F60);\nSFRX(OUT9DATA,      0x7F61);\nSFRX(OUT10DATA,     0x7F62);\nSFRX(OUT11DATA,     0x7F63);\nSFRX(OUT12DATA,     0x7F64);\nSFRX(OUT13DATA,     0x7F65);\nSFRX(OUT14DATA,     0x7F66);\nSFRX(OUT15DATA,     0x7F67);\n\nSFRX(IN8DATA,       0x7F68);\nSFRX(IN9DATA,       0x7F69);\nSFRX(IN10DATA,      0x7F6A);\nSFRX(IN11DATA,      0x7F6B);\nSFRX(IN12DATA,      0x7F6C);\nSFRX(IN13DATA,      0x7F6D);\nSFRX(IN14DATA,      0x7F6E);\nSFRX(IN15DATA,      0x7F6F);\n\n/************************* Isochronous Byte Counts *************************/\nSFRX(OUT8BCH,       0x7F70);\nSFRX(OUT8BCL,       0x7F71);\nSFRX(OUT9BCH,       0x7F72);\nSFRX(OUT9BCL,       0x7F73);\nSFRX(OUT10BCH,      0x7F74);\nSFRX(OUT10BCL,      0x7F75);\nSFRX(OUT11BCH,      0x7F76);\nSFRX(OUT11BCL,      0x7F77);\nSFRX(OUT12BCH,      0x7F78);\nSFRX(OUT12BCL,      0x7F79);\nSFRX(OUT13BCH,      0x7F7A);\nSFRX(OUT13BCL,      0x7F7B);\nSFRX(OUT14BCH,      0x7F7C);\nSFRX(OUT14BCL,      0x7F7D);\nSFRX(OUT15BCH,      0x7F7E);\nSFRX(OUT16BCL,      0x7F7F);\n\n/****************************** CPU Registers ******************************/\nSFRX(CPUCS,         0x7F92);\n#define RES8051     bmBit0\n#define CLK24OE     bmBit1\n/* Bit 2 read-only, always reads '0' */\n/* Bit 3 read-only, always reads '0' */\n/* Bits 4...7: Chip Revision */\n\nSFRX(PORTACFG,      0x7F93);\n#define T0OUT       bmBit0\n#define T1OUT       bmBit1\n#define OE          bmBit2\n#define CS          bmBit3\n#define FWR         bmBit4\n#define FRD         bmBit5\n#define RXD0OUT     bmBit6\n#define RXD1OUT     bmBit7\n\nSFRX(PORTBCFG,      0x7F94);\n#define T2          bmBit0\n#define T2EX        bmBit1\n#define RXD1        bmBit2\n#define TXD1        bmBit3\n#define INT4        bmBit4\n#define INT5        bmBit5\n#define INT6        bmBit6\n#define T2OUT       bmBit7\n\nSFRX(PORTCCFG,      0x7F95);\n#define RXD0        bmBit0\n#define TXD0        bmBit1\n#define INT0        bmBit2\n#define INT1        bmBit3\n#define T0          bmBit4\n#define T1          bmBit5\n#define WR          bmBit6\n#define RD          bmBit7\n\n/*********************** Input-Output Port Registers ***********************/\nSFRX(OUTA,          0x7F96);\n#define OUTA0       bmBit0\n#define OUTA1       bmBit1\n#define OUTA2       bmBit2\n#define OUTA3       bmBit3\n#define OUTA4       bmBit4\n#define OUTA5       bmBit5\n#define OUTA6       bmBit6\n#define OUTA7       bmBit7\n\nSFRX(OUTB,          0x7F97);\n#define OUTB0       bmBit0\n#define OUTB1       bmBit1\n#define OUTB2       bmBit2\n#define OUTB3       bmBit3\n#define OUTB4       bmBit4\n#define OUTB5       bmBit5\n#define OUTB6       bmBit6\n#define OUTB7       bmBit7\n\nSFRX(OUTC,          0x7F98);\n#define OUTC0       bmBit0\n#define OUTC1       bmBit1\n#define OUTC2       bmBit2\n#define OUTC3       bmBit3\n#define OUTC4       bmBit4\n#define OUTC5       bmBit5\n#define OUTC6       bmBit6\n#define OUTC7       bmBit7\n\nSFRX(PINSA,         0x7F99);\n#define PINA0       bmBit0\n#define PINA1       bmBit1\n#define PINA2       bmBit2\n#define PINA3       bmBit3\n#define PINA4       bmBit4\n#define PINA5       bmBit5\n#define PINA6       bmBit6\n#define PINA7       bmBit7\n\nSFRX(PINSB,         0x7F9A);\n#define PINB0       bmBit0\n#define PINB1       bmBit1\n#define PINB2       bmBit2\n#define PINB3       bmBit3\n#define PINB4       bmBit4\n#define PINB5       bmBit5\n#define PINB6       bmBit6\n#define PINB7       bmBit7\n\nSFRX(PINSC,         0x7F9B);\n#define PINC0       bmBit0\n#define PINC1       bmBit1\n#define PINC2       bmBit2\n#define PINC3       bmBit3\n#define PINC4       bmBit4\n#define PINC5       bmBit5\n#define PINC6      bmBit6\n#define PINC7       bmBit7\n\nSFRX(OEA,           0x7F9C);\n#define OEA0        bmBit0\n#define OEA1        bmBit1\n#define OEA2        bmBit2\n#define OEA3        bmBit3\n#define OEA4        bmBit4\n#define OEA5        bmBit5\n#define OEA6        bmBit6\n#define OEA7        bmBit7\n\nSFRX(OEB,           0x7F9D);\n#define OEB0        bmBit0\n#define OEB1        bmBit1\n#define OEB2        bmBit2\n#define OEB3        bmBit3\n#define OEB4        bmBit4\n#define OEB5        bmBit5\n#define OEB6        bmBit6\n#define OEB7        bmBit7\n\nSFRX(OEC,           0x7F9E);\n#define OEC0        bmBit0\n#define OEC1        bmBit1\n#define OEC2        bmBit2\n#define OEC3        bmBit3\n#define OEC4        bmBit4\n#define OEC5        bmBit5\n#define OEC6        bmBit6\n#define OEC7        bmBit7\n\n/* 0x7F9F reserved */\n\n/****************** Isochronous Control/Status Registers *******************/\nSFRX(ISOERR,        0x7FA0);\n#define ISO8ERR     bmBit0\n#define ISO9ERR     bmBit1\n#define ISO10ERR    bmBit2\n#define ISO11ERR    bmBit3\n#define ISO12ERR    bmBit4\n#define ISO13ERR    bmBit5\n#define ISO14ERR    bmBit6\n#define ISO15ERR    bmBit7\n\nSFRX(ISOCTL,        0x7FA1);\n#define ISODISAB    bmBit0\n#define MBZ0        bmBit1\n#define MBZ1        bmBit2\n#define PPSTAT      bmBit3\n/* Bit 4 unused */\n/* Bit 5 unused */\n/* Bit 6 unused */\n/* Bit 7 unused */\n\nSFRX(ZBCOUT,        0x7FA2);\n#define EP8         bmBit0\n#define EP9         bmBit1\n#define EP10        bmBit2\n#define EP11        bmBit3\n#define EP12        bmBit4\n#define EP13        bmBit5\n#define EP14        bmBit6\n#define EP15        bmBit7\n\n/* 0x7FA3 reserved */\n/* 0x7FA4 reserved */\n\n/****************************** I2C Registers ******************************/\nSFRX(I2CS,          0x7FA5);\n#define DONE        bmBit0\n#define ACK         bmBit1\n#define BERR        bmBit2\n#define ID0         bmBit3\n#define ID1         bmBit4\n#define LASTRD      bmBit5\n#define I2C_STOP    bmBit6\n#define I2C_START   bmBit7\n\nSFRX(I2DAT,         0x7FA6);\n/* 0x7FA7 reserved */\n\n/******************************* Interrupts ********************************/\nSFRX(IVEC,          0x7FA8);\n/* Bit 0 read-only, always reads '0' */\n/* Bit 1 read-only, always reads '0' */\n#define IV0         bmBit2\n#define IV1         bmBit3\n#define IV2         bmBit4\n#define IV3         bmBit5\n#define IV4         bmBit6\n/* Bit 7 read-only, always reads '0' */\n\nSFRX(IN07IRQ,       0x7FA9);\n#define IN0IR       bmBit0\n#define IN1IR       bmBit1\n#define IN2IR       bmBit2\n#define IN3IR       bmBit3\n#define IN4IR       bmBit4\n#define IN5IR       bmBit5\n#define IN6IR       bmBit6\n#define IN7IR       bmBit7\n\nSFRX(OUT07IRQ,      0x7FAA);\n#define OUT0IR      bmBit0\n#define OUT1IR      bmBit1\n#define OUT2IR      bmBit2\n#define OUT3IR      bmBit3\n#define OUT4IR      bmBit4\n#define OUT5IR      bmBit5\n#define OUT6IR      bmBit6\n#define OUT7IR      bmBit7\n\nSFRX(USBIRQ,        0x7FAB);\n#define SUDAVIR     bmBit0\n#define SOFIR       bmBit1\n#define SUTOKIR     bmBit2\n#define SUSPIR      bmBit3\n#define URESIR      bmBit4\n/* Bit 5 unused */\n/* Bit 6 unused */\n/* Bit 7 unused */\n\nSFRX(IN07IEN,       0x7FAC);\n#define IN0IEN      bmBit0\n#define IN1IEN      bmBit1\n#define IN2IEN      bmBit2\n#define IN3IEN      bmBit3\n#define IN4IEN      bmBit4\n#define IN5IEN      bmBit5\n#define IN6IEN      bmBit6\n#define IN7IEN      bmBit7\n\nSFRX(OUT07IEN,      0x7FAD);\n#define OUT0IEN     bmBit0\n#define OUT1IEN     bmBit1\n#define OUT2IEN     bmBit2\n#define OUT3IEN     bmBit3\n#define OUT4IEN     bmBit4\n#define OUT5IEN     bmBit5\n#define OUT6IEN     bmBit6\n#define OUT7IEN     bmBit7\n\nSFRX(USBIEN,        0x7FAE);\n#define SUDAVIE     bmBit0\n#define SOFIE       bmBit1\n#define SUTOKIE     bmBit2\n#define SUSPIE      bmBit3\n#define URESIE      bmBit4\n/* Bit 5 unused */\n/* Bit 6 unused */\n/* Bit 7 unused */\n\nSFRX(USBBAV,        0x7FAF);\n#define AVEN        bmBit0\n#define BPEN        bmBit1\n#define BPPULSE     bmBit2\n#define BREAK       bmBit3\n/* Bit 4 unused */\n/* Bit 5 unused */\n/* Bit 6 unused */\n/* Bit 7 unused */\n\n/* 0x7FB0 reserved */\n/* 0x7FB1 reserved */\nSFRX(BPADDRH,       0x7FB2);\nSFRX(BPADDRL,       0x7FB3);\n\n/****************************** Endpoints 0-7 ******************************/\nSFRX(EP0CS,         0x7FB4);\n#define EP0STALL    bmBit0\n#define HSNAK       bmBit1\n#define IN0BSY      bmBit2\n#define OUT0BSY     bmBit3\n/* Bit 4 unused */\n/* Bit 5 unused */\n/* Bit 6 unused */\n/* Bit 7 unused */\n\nSFRX(IN0BC,         0x7FB5);\nSFRX(IN1CS,         0x7FB6);\nSFRX(IN1BC,         0x7FB7);\nSFRX(IN2CS,         0x7FB8);\nSFRX(IN2BC,         0x7FB9);\nSFRX(IN3CS,         0x7FBA);\nSFRX(IN3BC,         0x7FBB);\nSFRX(IN4CS,         0x7FBC);\nSFRX(IN4BC,         0x7FBD);\nSFRX(IN5CS,         0x7FBE);\nSFRX(IN5BC,         0x7FBF);\nSFRX(IN6CS,         0x7FC0);\nSFRX(IN6BC,         0x7FC1);\nSFRX(IN7CS,         0x7FC2);\nSFRX(IN7BC,         0x7FC3);\n/* 0x7FC4 reserved */\nSFRX(OUT0BC,        0x7FC5);\nSFRX(OUT1CS,        0x7FC6);\nSFRX(OUT1BC,        0x7FC7);\nSFRX(OUT2CS,        0x7FC8);\nSFRX(OUT2BC,        0x7FC9);\nSFRX(OUT3CS,        0x7FCA);\nSFRX(OUT3BC,        0x7FCB);\nSFRX(OUT4CS,        0x7FCC);\nSFRX(OUT4BC,        0x7FCD);\nSFRX(OUT5CS,        0x7FCE);\nSFRX(OUT5BC,        0x7FCF);\nSFRX(OUT6CS,        0x7FD0);\nSFRX(OUT6BC,        0x7FD1);\nSFRX(OUT7CS,        0x7FD2);\nSFRX(OUT7BC,        0x7FD3);\n\n/* The INxSTALL, OUTxSTALL, INxBSY and OUTxBSY bits are the same for all\n * INxCS/OUTxCS registers. For better readability, we define them only once */\n#define EPSTALL     bmBit0\n#define EPBSY       bmBit1\n\n/************************** Global USB Registers ***************************/\nSFRX(SUDPTRH,       0x7FD4);\nSFRX(SUDPTRL,       0x7FD5);\n\nSFRX(USBCS,         0x7FD6);\n#define SIGRSUME    bmBit0\n#define RENUM       bmBit1\n#define DISCOE      bmBit2\n#define DISCON      bmBit3\n/* Bit 4 unused */\n/* Bit 5 unused */\n/* Bit 6 unused */\n#define WAKESRC     bmBit7\n\nSFRX(TOGCTL,        0x7FD7);\n#define TOG_EP0     bmBit0\n#define TOG_EP1     bmBit1\n#define TOG_EP2     bmBit2\n/* Bit 3 is read-only, always reads '0' */\n#define TOG_IO      bmBit4\n#define TOG_R       bmBit5\n#define TOG_S       bmBit6\n#define TOG_Q       bmBit7\n\nSFRX(USBFRAMEL,     0x7FD8);\nSFRX(USBFRAMEH,     0x7FD9);\n/* 0x7FDA reserved */\nSFRX(FNADDR,        0x7FDB);\n/* 0x7FDC reserved */\n\nSFRX(USBPAIR,       0x7FDD);\n#define PR2IN       bmBit0\n#define PR4IN       bmBit1\n#define PR6IN       bmBit2\n#define PR2OUT      bmBit3\n#define PR4OUT      bmBit4\n#define PR6OUT      bmBit5\n/* Bit 6 unused */\n#define ISOSEND0    bmBit7\n\nSFRX(IN07VAL,       0x7FDE);\n/* Bit 0 is read-only, always reads '1' */\n#define IN1VAL      bmBit1\n#define IN2VAL      bmBit2\n#define IN3VAL      bmBit3\n#define IN4VAL      bmBit4\n#define IN5VAL      bmBit5\n#define IN6VAL      bmBit6\n#define IN7VAL      bmBit7\n\nSFRX(OUT07VAL,      0x7FDF);\n/* Bit 0 is read-only, always reads '1' */\n#define OUT1VAL     bmBit1\n#define OUT2VAL     bmBit2\n#define OUT3VAL     bmBit3\n#define OUT4VAL     bmBit4\n#define OUT5VAL     bmBit5\n#define OUT6VAL     bmBit6\n#define OUT7VAL     bmBit7\n\nSFRX(INISOVAL,      0x7FE0);\n#define IN8VAL      bmBit0\n#define IN9VAL      bmBit1\n#define IN10VAL     bmBit2\n#define IN11VAL     bmBit3\n#define IN12VAL     bmBit4\n#define IN13VAL     bmBit5\n#define IN14VAL     bmBit6\n#define IN15VAL     bmBit7\n\nSFRX(OUTISOVAL,     0x7FE1);\n#define OUT8VAL     bmBit0\n#define OUT9VAL     bmBit1\n#define OUT10VAL    bmBit2\n#define OUT11VAL    bmBit3\n#define OUT12VAL    bmBit4\n#define OUT13VAL    bmBit5\n#define OUT14VAL    bmBit6\n#define OUT15VAL    bmBit7\n\nSFRX(FASTXFR,       0x7FE2);\n#define WMOD0       bmBit0\n#define WMOD1       bmBit1\n#define WPOL        bmBit2\n#define RMOD0       bmBit3\n#define RMOD1       bmBit4\n#define RPOL        bmBit5\n#define FBLK        bmBit6\n#define FISO        bmBit7\n\nSFRX(AUTOPTRH,      0x7FE3);\nSFRX(AUTOPTRL,      0x7FE4);\nSFRX(AUTODATA,      0x7FE5);\n/* 0x7FE6 reserved */\n/* 0x7FE7 reserved */\n\n/******************************* Setup Data ********************************/\nSFRX(SETUPDAT[8],   0x7FE8);\n\n/************************* Isochronous FIFO sizes **************************/\nSFRX(OUT8ADDR,      0x7FF0);\nSFRX(OUT9ADDR,      0x7FF1);\nSFRX(OUT10ADDR,     0x7FF2);\nSFRX(OUT11ADDR,     0x7FF3);\nSFRX(OUT12ADDR,     0x7FF4);\nSFRX(OUT13ADDR,     0x7FF5);\nSFRX(OUT14ADDR,     0x7FF6);\nSFRX(OUT15ADDR,     0x7FF7);\n\nSFRX(IN8ADDR,       0x7FF8);\nSFRX(IN9ADDR,       0x7FF9);\nSFRX(IN10ADDR,      0x7FFA);\nSFRX(IN11ADDR,      0x7FFB);\nSFRX(IN12ADDR,      0x7FFC);\nSFRX(IN13ADDR,      0x7FFD);\nSFRX(IN14ADDR,      0x7FFE);\nSFRX(IN15ADDR,      0x7FFF);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/include/usb.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifndef __USB_H\n#define __USB_H\n\n#include \"reg_ezusb.h\"\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#define NULL        (void *)0;\n\n/* High and Low byte of a word (uint16_t) */\n#define HI8(word)   (uint8_t)(((uint16_t)word >> 8) & 0xff)\n#define LO8(word)   (uint8_t)((uint16_t)word & 0xff)\n\n/* Convenience functions */\n#define STALL_EP0()   (EP0CS |= EP0STALL)\n#define CLEAR_IRQ()   (EXIF &= ~USBINT)\n\n/*********** USB descriptors. See section 9.5 of the USB 1.1 spec **********/\n\n/* USB Descriptor Types. See USB 1.1 spec, page 187, table 9-5 */\n#define DESCRIPTOR_TYPE_DEVICE         0x01\n#define DESCRIPTOR_TYPE_CONFIGURATION  0x02\n#define DESCRIPTOR_TYPE_STRING         0x03\n#define DESCRIPTOR_TYPE_INTERFACE      0x04\n#define DESCRIPTOR_TYPE_ENDPOINT       0x05\n\n#define STR_DESCR(len, ...) { len * 2 + 2, DESCRIPTOR_TYPE_STRING, { __VA_ARGS__ } }\n\n/** USB Device Descriptor. See USB 1.1 spec, pp. 196 - 198 */\nstruct usb_device_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< DEVICE Descriptor Type. */\n\tuint16_t bcdUSB;\t\t/**< USB specification release number (BCD). */\n\tuint8_t bDeviceClass;\t\t/**< Class code. */\n\tuint8_t bDeviceSubClass;\t/**< Subclass code. */\n\tuint8_t bDeviceProtocol;\t/**< Protocol code. */\n\tuint8_t bMaxPacketSize0;\t/**< Maximum packet size for EP0 (8, 16, 32, 64). */\n\tuint16_t idVendor;\t\t/**< USB Vendor ID. */\n\tuint16_t idProduct;\t\t/**< USB Product ID. */\n\tuint16_t bcdDevice;\t\t/**< Device Release Number (BCD). */\n\tuint8_t iManufacturer;\t\t/**< Index of manufacturer string descriptor. */\n\tuint8_t iProduct;\t\t/**< Index of product string descriptor. */\n\tuint8_t iSerialNumber;\t\t/**< Index of string descriptor containing serial #. */\n\tuint8_t bNumConfigurations;\t/**< Number of possible configurations. */\n};\n\n/** USB Configuration Descriptor. See USB 1.1 spec, pp. 199 - 200 */\nstruct usb_config_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< CONFIGURATION descriptor type. */\n\tuint16_t wTotalLength;\t\t/**< Combined total length of all descriptors. */\n\tuint8_t bNumInterfaces;\t\t/**< Number of interfaces in this configuration. */\n\tuint8_t bConfigurationValue;\t/**< Value used to select this configuration. */\n\tuint8_t iConfiguration;\t\t/**< Index of configuration string descriptor. */\n\tuint8_t bmAttributes;\t\t/**< Configuration characteristics. */\n\tuint8_t MaxPower;\t\t/**< Maximum power consumption in 2 mA units. */\n};\n\n/** USB Interface Descriptor. See USB 1.1 spec, pp. 201 - 203 */\nstruct usb_interface_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< INTERFACE descriptor type. */\n\tuint8_t bInterfaceNumber;\t/**< Interface number. */\n\tuint8_t bAlternateSetting;\t/**< Value used to select alternate setting. */\n\tuint8_t bNumEndpoints;\t\t/**< Number of endpoints used by this interface. */\n\tuint8_t bInterfaceClass;\t/**< Class code. */\n\tuint8_t bInterfaceSubclass;\t/**< Subclass code. */\n\tuint8_t bInterfaceProtocol;\t/**< Protocol code. */\n\tuint8_t iInterface;\t\t/**< Index of interface string descriptor. */\n};\n\n/** USB Endpoint Descriptor. See USB 1.1 spec, pp. 203 - 204 */\nstruct usb_endpoint_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< ENDPOINT descriptor type. */\n\tuint8_t bEndpointAddress;\t/**< Endpoint Address: USB 1.1 spec, table 9-10. */\n\tuint8_t bmAttributes;\t\t/**< Endpoint Attributes: USB 1.1 spec, table 9-10. */\n\tuint16_t wMaxPacketSize;\t/**< Maximum packet size for this endpoint. */\n\tuint8_t bInterval;\t\t/**< Polling interval (in ms) for this endpoint. */\n};\n\n/** USB Language Descriptor. See USB 1.1 spec, pp. 204 - 205 */\nstruct usb_language_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< STRING descriptor type. */\n\tuint16_t wLANGID[];\t\t/**< LANGID codes. */\n};\n\n/** USB String Descriptor. See USB 1.1 spec, pp. 204 - 205 */\nstruct usb_string_descriptor {\n\tuint8_t bLength;\t\t/**< Size of this descriptor in bytes. */\n\tuint8_t bDescriptorType;\t/**< STRING descriptor type. */\n\tuint16_t bString[];\t\t/**< UNICODE encoded string. */\n};\n\n/********************** USB Control Endpoint 0 related *********************/\n\n/** USB Control Setup Data. See USB 1.1 spec, pp. 183 - 185 */\nstruct setup_data {\n\tuint8_t bmRequestType;\t\t/**< Characteristics of a request. */\n\tuint8_t bRequest;\t\t/**< Specific request. */\n\tuint16_t wValue;\t\t/**< Field that varies according to request. */\n\tuint16_t wIndex;\t\t/**< Field that varies according to request. */\n\tuint16_t wLength;\t\t/**< Number of bytes to transfer in data stage. */\n};\n\n/* External declarations for variables that need to be accessed outside of\n * the USB module */\nextern volatile bool EP2_out;\nextern volatile bool EP2_in;\nextern volatile __xdata __at 0x7FE8 struct setup_data setup_data;\n\n/*\n * USB Request Types (bmRequestType): See USB 1.1 spec, page 183, table 9-2\n *\n * Bit 7: Data transfer direction\n *    0 = Host-to-device\n *    1 = Device-to-host\n * Bit 6...5: Type\n *    0 = Standard\n *    1 = Class\n *    2 = Vendor\n *    3 = Reserved\n * Bit 4...0: Recipient\n *    0 = Device\n *    1 = Interface\n *    2 = Endpoint\n *    3 = Other\n *    4...31 = Reserved\n */\n\n#define USB_DIR_OUT             0x00\n#define USB_DIR_IN              0x80\n\n#define USB_REQ_TYPE_STANDARD   (0x00 << 5)\n#define USB_REQ_TYPE_CLASS      (0x01 << 5)\n#define USB_REQ_TYPE_VENDOR     (0x02 << 5)\n#define USB_REQ_TYPE_RESERVED   (0x03 << 5)\n\n#define USB_RECIP_DEVICE        0x00\n#define USB_RECIP_INTERFACE     0x01\n#define USB_RECIP_ENDPOINT      0x02\n#define USB_RECIP_OTHER         0x03\n\n/* bmRequestType for USB Standard Requests */\n\n/* Clear Interface Request */\n#define CF_DEVICE    (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n#define CF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)\n#define CF_ENDPOINT  (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)\n\n/* Get Configuration Request */\n#define GC_DEVICE    (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n\n/* Get Descriptor Request */\n#define GD_DEVICE    (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n\n/* Get Interface Request */\n#define GI_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)\n\n/* Get Status Request: See USB 1.1 spec, page 190 */\n#define GS_DEVICE    (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n#define GS_INTERFACE (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)\n#define GS_ENDPOINT  (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)\n\n/* Set Address Request is handled by EZ-USB core */\n\n/* Set Configuration Request */\n#define SC_DEVICE    (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n\n/* Set Descriptor Request */\n#define SD_DEVICE    (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n\n/* Set Feature Request */\n#define SF_DEVICE    (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_DEVICE)\n#define SF_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)\n#define SF_ENDPOINT  (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)\n\n/* Set Interface Request */\n#define SI_INTERFACE (USB_DIR_OUT | USB_REQ_TYPE_STANDARD | USB_RECIP_INTERFACE)\n\n/* Synch Frame Request */\n#define SY_ENDPOINT  (USB_DIR_IN | USB_REQ_TYPE_STANDARD | USB_RECIP_ENDPOINT)\n\n/* USB Requests (bRequest): See USB 1.1 spec, table 9-4 on page 187 */\n#define GET_STATUS               0\n#define CLEAR_FEATURE            1\n/* Value '2' is reserved for future use */\n#define SET_FEATURE              3\n/* Value '4' is reserved for future use */\n#define SET_ADDRESS              5\n#define GET_DESCRIPTOR           6\n#define SET_DESCRIPTOR           7\n#define GET_CONFIGURATION        8\n#define SET_CONFIGURATION        9\n#define GET_INTERFACE           10\n#define SET_INTERFACE           11\n#define SYNCH_FRAME             12\n\n/* Standard Feature Selectors: See USB 1.1 spec, table 9-6 on page 188 */\n#define DEVICE_REMOTE_WAKEUP     1\n#define ENDPOINT_HALT            0\n\n/************************** EZ-USB specific stuff **************************/\n\n/** USB Interrupts. See AN2131-TRM, page 9-4 for details */\nenum usb_isr {\n\tSUDAV_ISR = 13,\n\tSOF_ISR,\n\tSUTOK_ISR,\n\tSUSPEND_ISR,\n\tUSBRESET_ISR,\n\tIBN_ISR,\n\tEP0IN_ISR,\n\tEP0OUT_ISR,\n\tEP1IN_ISR,\n\tEP1OUT_ISR,\n\tEP2IN_ISR,\n\tEP2OUT_ISR,\n\tEP3IN_ISR,\n\tEP3OUT_ISR,\n\tEP4IN_ISR,\n\tEP4OUT_ISR,\n\tEP5IN_ISR,\n\tEP5OUT_ISR,\n\tEP6IN_ISR,\n\tEP6OUT_ISR,\n\tEP7IN_ISR,\n\tEP7OUT_ISR\n};\n\n/*************************** Function Prototypes ***************************/\n\n__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep);\nvoid usb_reset_data_toggle(uint8_t ep);\n\nbool usb_handle_get_status(void);\nbool usb_handle_clear_feature(void);\nbool usb_handle_set_feature(void);\nbool usb_handle_get_descriptor(void);\nvoid usb_handle_set_interface(void);\n\nvoid usb_handle_setup_data(void);\nvoid usb_init(void);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/USBJmpTb.a51",
    "content": "; SPDX-License-Identifier: GPL-2.0-or-later\n\n;\n; Copyright (C) 2011-2013 by Martin Schmoelzer\n; <martin.schmoelzer@student.tuwien.ac.at>\n;\n\n.module JUMPTABLE\n.globl USB_AutoVector\n.globl USB_Jump_Table\n\n;--------------------------------------------------------------------------;\n; Interrupt Vectors                                                        ;\n;--------------------------------------------------------------------------;\n.area   USB_JV (ABS,OVR)   ; Absolute, Overlay\n.org    0x43               ; USB interrupt (INT2) jumps here\nUSB_AutoVector = #. + 2\n    ljmp  USB_Jump_Table\n\n;--------------------------------------------------------------------------;\n; USB Jump Table                                                           ;\n;--------------------------------------------------------------------------;\n.area  USB_JT (ABS)        ; Absolute placement\n.org   0x1B00              ; Place jump table at 0x1B00\n\nUSB_Jump_Table:            ; autovector jump table\n    ljmp  _sudav_isr       ; Setup Data Available\n    .db 0\n    ljmp  _sof_isr         ; Start of Frame\n    .db 0\n    ljmp  _sutok_isr       ; Setup Data Loading\n    .db 0\n    ljmp  _suspend_isr     ; Global Suspend\n    .db 0\n    ljmp  _usbreset_isr    ; USB Reset\n    .db 0\n    ljmp  _ibn_isr         ; IN Bulk NAK interrupt\n    .db 0\n    ljmp  _ep0in_isr       ; Endpoint 0 IN\n    .db 0\n    ljmp  _ep0out_isr      ; Endpoint 0 OUT\n    .db 0\n    ljmp  _ep1in_isr       ; Endpoint 1 IN\n    .db 0\n    ljmp  _ep1out_isr      ; Endpoint 1 OUT\n    .db 0\n    ljmp  _ep2in_isr       ; Endpoint 2 IN\n    .db 0\n    ljmp  _ep2out_isr      ; Endpoint 2 OUT\n    .db 0\n    ljmp  _ep3in_isr       ; Endpoint 3 IN\n    .db 0\n    ljmp  _ep3out_isr      ; Endpoint 3 OUT\n    .db 0\n    ljmp  _ep4in_isr       ; Endpoint 4 IN\n    .db 0\n    ljmp  _ep4out_isr      ; Endpoint 4 OUT\n    .db 0\n    ljmp  _ep5in_isr       ; Endpoint 5 IN\n    .db 0\n    ljmp  _ep5out_isr      ; Endpoint 5 OUT\n    .db 0\n    ljmp  _ep6in_isr       ; Endpoint 6 IN\n    .db 0\n    ljmp  _ep6out_isr      ; Endpoint 6 OUT\n    .db 0\n    ljmp  _ep7in_isr       ; Endpoint 7 IN\n    .db 0\n    ljmp  _ep7out_isr      ; Endpoint 7 OUT\n    .db 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/delay.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#include \"delay.h\"\n\nvoid delay_5us(void)\n{\n\tNOP;\n}\n\nvoid delay_1ms(void)\n{\n\tuint16_t i;\n\n\tfor (i = 0; i < 598; i++)\n\t\t;\n}\n\nvoid delay_us(uint16_t delay)\n{\n\tuint16_t i;\n\tuint16_t maxcount = (delay / 5);\n\n\tfor (i = 0; i < maxcount; i++)\n\t\tdelay_5us();\n}\n\nvoid delay_ms(uint16_t delay)\n{\n\tuint16_t i;\n\n\tfor (i = 0; i < delay; i++)\n\t\tdelay_1ms();\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#include \"jtag.h\"\n\n#include \"io.h\"\n#include \"msgtypes.h\"\n#include \"common.h\"\n\n#include <stdbool.h>\n\n/** Delay value for SCAN_IN operations with less than maximum TCK frequency */\nuint8_t delay_scan_in;\n\n/** Delay value for SCAN_OUT operations with less than maximum TCK frequency */\nuint8_t delay_scan_out;\n\n/** Delay value for SCAN_IO operations with less than maximum TCK frequency */\nuint8_t delay_scan_io;\n\n/** Delay value for CLOCK_TCK operations with less than maximum frequency */\nuint8_t delay_tck;\n\n/** Delay value for CLOCK_TMS operations with less than maximum frequency */\nuint8_t delay_tms;\n\n/**\n * Perform JTAG SCAN-IN operation at maximum TCK frequency.\n *\n * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and\n * stored in the EP2 IN buffer.\n *\n * Maximum achievable TCK frequency is 182 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n * @param in_offset\n */\nvoid jtag_scan_in(uint8_t out_offset, uint8_t in_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdo_data, i, j;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdo_data = 0;\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tOUTB = outb_buffer;\t/* TCK changes here */\n\t\t\ttdo_data = tdo_data >> 1;\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\n\t\t\tif (GET_TDO())\n\t\t\t\ttdo_data |= 0x80;\n\t\t}\n\n\t\t/* Copy TDO data to IN2BUF */\n\t\tIN2BUF[i + in_offset] = tdo_data;\n\t}\n\n\ttdo_data = 0;\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TCK changes here */\n\t\ttdo_data = tdo_data >> 1;\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\n\t\tif (GET_TDO())\n\t\t\ttdo_data |= 0x80;\n\t}\n\ttdo_data = tdo_data >> (8 - bits_last_byte);\n\n\t/* Copy TDO data to IN2BUF */\n\tIN2BUF[i + in_offset] = tdo_data;\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Perform JTAG SCAN-IN operation at variable TCK frequency.\n *\n * Dummy data is shifted into the JTAG chain via TDI, TDO data is sampled and\n * stored in the EP2 IN buffer.\n *\n * Maximum achievable TCK frequency is 113 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n * @param in_offset\n */\nvoid jtag_slow_scan_in(uint8_t out_offset, uint8_t in_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdo_data, i, j, k;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_slow_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TDI | PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdo_data = 0;\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tOUTB = outb_buffer;\t/* TCK changes here */\n\t\t\tfor (k = 0; k < delay_scan_in; k++)\n\t\t\t\t;\n\t\t\ttdo_data = tdo_data >> 1;\n\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\t\tfor (k = 0; k < delay_scan_in; k++)\n\t\t\t\t;\n\n\t\t\tif (GET_TDO())\n\t\t\t\ttdo_data |= 0x80;\n\t\t}\n\n\t\t/* Copy TDO data to IN2BUF */\n\t\tIN2BUF[i + in_offset] = tdo_data;\n\t}\n\n\ttdo_data = 0;\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TCK changes here */\n\t\tfor (k = 0; k < delay_scan_in; k++)\n\t\t\t;\n\t\ttdo_data = tdo_data >> 1;\n\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\tfor (k = 0; k < delay_scan_in; k++)\n\t\t\t;\n\n\t\tif (GET_TDO())\n\t\t\ttdo_data |= 0x80;\n\t}\n\ttdo_data = tdo_data >> (8 - bits_last_byte);\n\n\t/* Copy TDO data to IN2BUF */\n\tIN2BUF[i + in_offset] = tdo_data;\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_slow_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Perform JTAG SCAN-OUT operation at maximum TCK frequency.\n *\n * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO\n * data is not sampled.\n * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.\n *\n * Maximum achievable TCK frequency is 142 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n */\nvoid jtag_scan_out(uint8_t out_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdi_data, i, j;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdi_data = OUT2BUF[i + out_offset + 5];\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tif (tdi_data & 0x01)\n\t\t\t\toutb_buffer |= PIN_TDI;\n\t\t\telse\n\t\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\t\ttdi_data = tdi_data >> 1;\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\t}\n\t}\n\n\ttdi_data = OUT2BUF[i + out_offset + 5];\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\tif (tdi_data & 0x01)\n\t\t\toutb_buffer |= PIN_TDI;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\ttdi_data = tdi_data >> 1;\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\t}\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Perform JTAG SCAN-OUT operation at maximum TCK frequency.\n *\n * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO\n * data is not sampled.\n * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.\n *\n * Maximum achievable TCK frequency is 97 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n */\nvoid jtag_slow_scan_out(uint8_t out_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdi_data, i, j, k;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_slow_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdi_data = OUT2BUF[i + out_offset + 5];\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tif (tdi_data & 0x01)\n\t\t\t\toutb_buffer |= PIN_TDI;\n\t\t\telse\n\t\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\t\tfor (k = 0; k < delay_scan_out; k++)\n\t\t\t\t;\n\t\t\ttdi_data = tdi_data >> 1;\n\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\t\tfor (k = 0; k < delay_scan_out; k++)\n\t\t\t\t;\n\t\t}\n\t}\n\n\ttdi_data = OUT2BUF[i + out_offset + 5];\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\tif (tdi_data & 0x01)\n\t\t\toutb_buffer |= PIN_TDI;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\tfor (k = 0; k < delay_scan_out; k++)\n\t\t\t;\n\t\ttdi_data = tdi_data >> 1;\n\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\tfor (k = 0; k < delay_scan_out; k++)\n\t\t\t;\n\t}\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_slow_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.\n *\n * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO\n * data is sampled and stored in the EP2 IN buffer.\n * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.\n *\n * Maximum achievable TCK frequency is 100 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n * @param in_offset\n */\nvoid jtag_scan_io(uint8_t out_offset, uint8_t in_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdi_data, tdo_data, i, j;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdi_data = OUT2BUF[i + out_offset + 5];\n\t\ttdo_data = 0;\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tif (tdi_data & 0x01)\n\t\t\t\toutb_buffer |= PIN_TDI;\n\t\t\telse\n\t\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\t\ttdi_data = tdi_data >> 1;\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\t\ttdo_data = tdo_data >> 1;\n\n\t\t\tif (GET_TDO())\n\t\t\t\ttdo_data |= 0x80;\n\t\t}\n\n\t\t/* Copy TDO data to IN2BUF */\n\t\tIN2BUF[i + in_offset] = tdo_data;\n\t}\n\n\ttdi_data = OUT2BUF[i + out_offset + 5];\n\ttdo_data = 0;\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\tif (tdi_data & 0x01)\n\t\t\toutb_buffer |= PIN_TDI;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\ttdi_data = tdi_data >> 1;\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\ttdo_data = tdo_data >> 1;\n\n\t\tif (GET_TDO())\n\t\t\ttdo_data |= 0x80;\n\t}\n\ttdo_data = tdo_data >> (8 - bits_last_byte);\n\n\t/* Copy TDO data to IN2BUF */\n\tIN2BUF[i + in_offset] = tdo_data;\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Perform bidirectional JTAG SCAN operation at maximum TCK frequency.\n *\n * Data stored in EP2 OUT buffer is shifted into the JTAG chain via TDI, TDO\n * data is sampled and stored in the EP2 IN buffer.\n * The TAP-FSM state is always left in the PAUSE-DR/PAUSE-IR state.\n *\n * Maximum achievable TCK frequency is 78 kHz for ULINK clocked at 24 MHz.\n *\n * @param out_offset offset in OUT2BUF where payload data starts\n * @param in_offset\n */\nvoid jtag_slow_scan_io(uint8_t out_offset, uint8_t in_offset)\n{\n\tuint8_t scan_size_bytes, bits_last_byte;\n\tuint8_t tms_count_start, tms_count_end;\n\tuint8_t tms_sequence_start, tms_sequence_end;\n\tuint8_t tdi_data, tdo_data, i, j, k;\n\n\tuint8_t outb_buffer;\n\n\t/* Get parameters from OUT2BUF */\n\tscan_size_bytes = OUT2BUF[out_offset];\n\tbits_last_byte = OUT2BUF[out_offset + 1];\n\ttms_count_start = (OUT2BUF[out_offset + 2] >> 4) & 0x0F;\n\ttms_count_end = OUT2BUF[out_offset + 2] & 0x0F;\n\ttms_sequence_start = OUT2BUF[out_offset + 3];\n\ttms_sequence_end = OUT2BUF[out_offset + 4];\n\n\tif (tms_count_start > 0)\n\t\tjtag_slow_clock_tms(tms_count_start, tms_sequence_start);\n\n\toutb_buffer = OUTB & ~(PIN_TCK | PIN_TMS);\n\n\t/* Shift all bytes except the last byte */\n\tfor (i = 0; i < scan_size_bytes - 1; i++) {\n\t\ttdi_data = OUT2BUF[i + out_offset + 5];\n\t\ttdo_data = 0;\n\n\t\tfor (j = 0; j < 8; j++) {\n\t\t\tif (tdi_data & 0x01)\n\t\t\t\toutb_buffer |= PIN_TDI;\n\t\t\telse\n\t\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\t\tfor (k = 0; k < delay_scan_io; k++)\n\t\t\t\t;\n\t\t\ttdi_data = tdi_data >> 1;\n\n\t\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\t\tfor (k = 0; k < delay_scan_io; k++)\n\t\t\t\t;\n\t\t\ttdo_data = tdo_data >> 1;\n\n\t\t\tif (GET_TDO())\n\t\t\t\ttdo_data |= 0x80;\n\t\t}\n\n\t\t/* Copy TDO data to IN2BUF */\n\t\tIN2BUF[i + in_offset] = tdo_data;\n\t}\n\n\ttdi_data = OUT2BUF[i + out_offset + 5];\n\ttdo_data = 0;\n\n\t/* Shift the last byte */\n\tfor (j = 0; j < bits_last_byte; j++) {\n\t\tif (tdi_data & 0x01)\n\t\t\toutb_buffer |= PIN_TDI;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TDI;\n\n\t\t/* Assert TMS signal if requested and this is the last bit */\n\t\tif ((j == bits_last_byte - 1) && (tms_count_end > 0)) {\n\t\t\toutb_buffer |= PIN_TMS;\n\t\t\ttms_count_end--;\n\t\t\ttms_sequence_end = tms_sequence_end >> 1;\n\t\t}\n\n\t\tOUTB = outb_buffer;\t/* TDI and TCK change here */\n\t\tfor (k = 0; k < delay_scan_io; k++)\n\t\t\t;\n\t\ttdi_data = tdi_data >> 1;\n\n\t\tOUTB = (outb_buffer | PIN_TCK);\n\t\tfor (k = 0; k < delay_scan_io; k++)\n\t\t\t;\n\t\ttdo_data = tdo_data >> 1;\n\n\t\tif (GET_TDO())\n\t\t\ttdo_data |= 0x80;\n\t}\n\ttdo_data = tdo_data >> (8 - bits_last_byte);\n\n\t/* Copy TDO data to IN2BUF */\n\tIN2BUF[i + in_offset] = tdo_data;\n\n\t/* Move to correct end state */\n\tif (tms_count_end > 0)\n\t\tjtag_slow_clock_tms(tms_count_end, tms_sequence_end);\n}\n\n/**\n * Generate TCK clock cycles.\n *\n * Maximum achievable TCK frequency is 375 kHz for ULINK clocked at 24 MHz.\n *\n * @param count number of TCK clock cycles to generate.\n */\nvoid jtag_clock_tck(uint16_t count)\n{\n\tuint16_t i;\n\tuint8_t outb_buffer = OUTB & ~(PIN_TCK);\n\n\tfor (i = 0; i < count; i++) {\n\t\tOUTB = outb_buffer;\n\t\tOUTB = outb_buffer | PIN_TCK;\n\t}\n}\n\n/**\n * Generate TCK clock cycles at variable frequency.\n *\n * Maximum achievable TCK frequency is 166.6 kHz for ULINK clocked at 24 MHz.\n *\n * @param count number of TCK clock cycles to generate.\n */\nvoid jtag_slow_clock_tck(uint16_t count)\n{\n\tuint16_t i;\n\tuint8_t j;\n\tuint8_t outb_buffer = OUTB & ~(PIN_TCK);\n\n\tfor (i = 0; i < count; i++) {\n\t\tOUTB = outb_buffer;\n\t\tfor (j = 0; j < delay_tck; j++)\n\t\t\t;\n\t\tOUTB = outb_buffer | PIN_TCK;\n\t\tfor (j = 0; j < delay_tck; j++)\n\t\t\t;\n\t}\n}\n\n/**\n * Perform TAP FSM state transitions at maximum TCK frequency.\n *\n * Maximum achievable TCK frequency is 176 kHz for ULINK clocked at 24 MHz.\n *\n * @param count the number of state transitions to perform.\n * @param sequence the TMS pin levels for each state transition, starting with\n *  the least-significant bit.\n */\nvoid jtag_clock_tms(uint8_t count, uint8_t sequence)\n{\n\tuint8_t outb_buffer = OUTB & ~(PIN_TCK);\n\tuint8_t i;\n\n\tfor (i = 0; i < count; i++) {\n\t\t/* Set TMS pin according to sequence parameter */\n\t\tif (sequence & 0x1)\n\t\t\toutb_buffer |= PIN_TMS;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TMS;\n\n\t\tOUTB = outb_buffer;\n\t\tsequence = sequence >> 1;\n\t\tOUTB = outb_buffer | PIN_TCK;\n\t}\n}\n\n/**\n * Perform TAP-FSM state transitions at less than maximum TCK frequency.\n *\n * Maximum achievable TCK frequency is 117 kHz for ULINK clocked at 24 MHz.\n *\n * @param count the number of state transitions to perform.\n * @param sequence the TMS pin levels for each state transition, starting with\n *  the least-significant bit.\n */\nvoid jtag_slow_clock_tms(uint8_t count, uint8_t sequence)\n{\n\tuint8_t outb_buffer = OUTB & ~(PIN_TCK);\n\tuint8_t i, j;\n\n\tfor (i = 0; i < count; i++) {\n\t\t/* Set TMS pin according to sequence parameter */\n\t\tif (sequence & 0x1)\n\t\t\toutb_buffer |= PIN_TMS;\n\t\telse\n\t\t\toutb_buffer &= ~PIN_TMS;\n\n\t\tOUTB = outb_buffer;\n\t\tfor (j = 0; j < delay_tms; j++)\n\t\t\t;\n\t\tsequence = sequence >> 1;\n\t\tOUTB = outb_buffer | PIN_TCK;\n\t\tfor (j = 0; j < delay_tms; j++)\n\t\t\t;\n\t}\n}\n\n/**\n * Get current JTAG signal states.\n *\n * @return a 16-bit integer where the most-significant byte contains the state\n *  of the JTAG input signals and the least-significant byte contains the state\n *  of the JTAG output signals.\n */\nuint16_t jtag_get_signals(void)\n{\n\tuint8_t input_signal_state, output_signal_state;\n\n\tinput_signal_state = 0;\n\toutput_signal_state = 0;\n\n\t/* Get states of input pins */\n\tif (GET_TDO())\n\t\tinput_signal_state |= SIGNAL_TDO;\n\tif (GET_BRKOUT())\n\t\tinput_signal_state |= SIGNAL_BRKOUT;\n\tif (GET_TRAP())\n\t\tinput_signal_state |= SIGNAL_TRAP;\n\tif (GET_RTCK()) {\n\t\t/* Using RTCK this way would be extremely slow,\n\t\t * implemented only for the sake of completeness */\n\t\tinput_signal_state |= SIGNAL_RTCK;\n\t}\n\n\t/* Get states of output pins */\n\toutput_signal_state = PINSB & MASK_PORTB_DIRECTION_OUT;\n\n\treturn ((uint16_t)input_signal_state << 8) | ((uint16_t)output_signal_state);\n}\n\n/**\n * Set state of JTAG output signals.\n *\n * @param low signals which should be de-asserted.\n * @param high signals which should be asserted.\n */\nvoid jtag_set_signals(uint8_t low, uint8_t high)\n{\n\tOUTB &= ~(low & MASK_PORTB_DIRECTION_OUT);\n\tOUTB |= (high & MASK_PORTB_DIRECTION_OUT);\n}\n\n/**\n * Configure TCK delay parameters.\n *\n * @param scan_in number of delay cycles in scan_in operations.\n * @param scan_out number of delay cycles in scan_out operations.\n * @param scan_io number of delay cycles in scan_io operations.\n * @param tck number of delay cycles in clock_tck operations.\n * @param tms number of delay cycles in clock_tms operations.\n */\nvoid jtag_configure_tck_delay(uint8_t scan_in, uint8_t scan_out,\n\tuint8_t scan_io, uint8_t tck, uint8_t tms)\n{\n\tdelay_scan_in = scan_in;\n\tdelay_scan_out = scan_out;\n\tdelay_scan_io = scan_io;\n\tdelay_tck = tck;\n\tdelay_tms = tms;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/main.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#include \"main.h\"\n\n#include \"io.h\"\n#include \"usb.h\"\n#include \"protocol.h\"\n\nextern void sudav_isr(void)    __interrupt SUDAV_ISR;\nextern void sof_isr(void)      __interrupt;\nextern void sutok_isr(void)    __interrupt;\nextern void suspend_isr(void)  __interrupt;\nextern void usbreset_isr(void) __interrupt;\nextern void ibn_isr(void)      __interrupt;\nextern void ep0in_isr(void)    __interrupt;\nextern void ep0out_isr(void)   __interrupt;\nextern void ep1in_isr(void)    __interrupt;\nextern void ep1out_isr(void)   __interrupt;\nextern void ep2in_isr(void)    __interrupt;\nextern void ep2out_isr(void)   __interrupt;\nextern void ep3in_isr(void)    __interrupt;\nextern void ep3out_isr(void)   __interrupt;\nextern void ep4in_isr(void)    __interrupt;\nextern void ep4out_isr(void)   __interrupt;\nextern void ep5in_isr(void)    __interrupt;\nextern void ep5out_isr(void)   __interrupt;\nextern void ep6in_isr(void)    __interrupt;\nextern void ep6out_isr(void)   __interrupt;\nextern void ep7in_isr(void)    __interrupt;\nextern void ep7out_isr(void)   __interrupt;\n\nvoid io_init(void)\n{\n\t/* PORTxCFG register bits select alternate functions (1 == alternate function,\n\t *                                                    0 == standard I/O)\n\t * OEx register bits turn on/off output buffer (1 == output, 0 == input)\n\t * OUTx register bits determine pin state of output\n\t * PINx register bits reflect pin state (high == 1, low == 0) */\n\n\t/* PORT A */\n\tPORTACFG = PIN_OE;\n\tOEA = PIN_U_OE | PIN_OE | PIN_RUN_LED | PIN_COM_LED;\n\tOUTA = PIN_RUN_LED | PIN_COM_LED;\n\n\t/* PORT B */\n\tPORTBCFG = 0x00;\n\tOEB = PIN_TDI | PIN_TMS | PIN_TCK | PIN_TRST | PIN_BRKIN | PIN_RESET\n\t\t| PIN_OCDSE;\n\n\t/* TRST and RESET signals are low-active but inverted by hardware, so we clear\n\t * these signals here! */\n\tOUTB = 0x00;\n\n\t/* PORT C */\n\tPORTCCFG = PIN_WR;\n\tOEC = PIN_TXD0 | PIN_WR;\n\tOUTC = 0x00;\n}\n\nint main(void)\n{\n\tio_init();\n\tusb_init();\n\n\t/* Enable Interrupts */\n\tEA = 1;\n\n\t/* Begin executing command(s). This function never returns. */\n\tcommand_loop();\n\n\t/* Never reached, but SDCC complains about missing return statement */\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/protocol.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Martin Schmoelzer                               *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#include \"protocol.h\"\n#include \"jtag.h\"\n#include \"delay.h\"\n#include \"usb.h\"\n#include \"io.h\"\n#include \"msgtypes.h\"\n\n#include \"reg_ezusb.h\"\n\n/**\n * @file\n * Implementation of the OpenULINK communication protocol.\n *\n * The OpenULINK protocol uses one OUT and one IN endpoint. These two endpoints\n * are configured to use the maximum packet size for full-speed transfers,\n * 64 bytes. Commands always start with a command ID (see msgtypes.h for\n * command ID definitions) and contain zero or more payload data bytes in both\n * transfer directions (IN and OUT). The payload\n *\n * Almost all commands contain a fixed number of payload data bytes. The number\n * of payload data bytes for the IN and OUT direction does not need to be the\n * same.\n *\n * Multiple commands may be sent in one EP2 Bulk-OUT packet. Because the\n * OpenULINK firmware does not perform bounds checking for EP2 Bulk-IN packets,\n * the host MUST ensure that the commands sent in the OUT packet require a\n * maximum of 64 bytes of IN data.\n */\n\n/** Index in EP2 Bulk-OUT data buffer that contains the current command ID */\nvolatile uint8_t cmd_id_index;\n\n/** Number of data bytes already in EP2 Bulk-IN buffer */\nvolatile uint8_t payload_index_in;\n\n/**\n * Execute a SET_LEDS command.\n */\nvoid execute_set_led_command(void)\n{\n\tuint8_t led_state = OUT2BUF[cmd_id_index + 1];\n\n\tif (led_state & RUN_LED_ON)\n\t\tSET_RUN_LED();\n\n\tif (led_state & COM_LED_ON)\n\t\tSET_COM_LED();\n\n\tif (led_state & RUN_LED_OFF)\n\t\tCLEAR_RUN_LED();\n\n\tif (led_state & COM_LED_OFF)\n\t\tCLEAR_COM_LED();\n}\n\n/**\n * Executes one command and updates global command indexes.\n *\n * @return true if this command was the last command.\n * @return false if there are more commands within the current contents of the\n * Bulk EP2-OUT data buffer.\n */\nbool execute_command(void)\n{\n\tuint8_t usb_out_bytecount, usb_in_bytecount;\n\tuint16_t signal_state;\n\tuint16_t count;\n\n\t/* Most commands do not transfer IN data. To save code space, we write 0 to\n\t * usb_in_bytecount here, then modify it in the switch statement below where\n\t * necessary */\n\tusb_in_bytecount = 0;\n\n\tswitch (OUT2BUF[cmd_id_index] /* Command ID */) {\n\t\tcase CMD_SCAN_IN:\n\t\t\tusb_out_bytecount = 5;\n\t\t\tusb_in_bytecount = OUT2BUF[cmd_id_index + 1];\n\t\t\tjtag_scan_in(cmd_id_index + 1, payload_index_in);\n\t\t\tbreak;\n\t\tcase CMD_SCAN_OUT:\n\t\t\tusb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;\n\t\t\tjtag_scan_out(cmd_id_index + 1);\n\t\t\tbreak;\n\t\tcase CMD_SCAN_IO:\n\t\t\tusb_in_bytecount = OUT2BUF[cmd_id_index + 1];\n\t\t\tusb_out_bytecount = usb_in_bytecount + 5;\n\t\t\tjtag_scan_io(cmd_id_index + 1, payload_index_in);\n\t\t\tbreak;\n\t\tcase CMD_CLOCK_TMS:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tjtag_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);\n\t\t\tbreak;\n\t\tcase CMD_CLOCK_TCK:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tcount = (uint16_t)OUT2BUF[cmd_id_index + 1];\n\t\t\tcount |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;\n\t\t\tjtag_clock_tck(count);\n\t\t\tbreak;\n\t\tcase CMD_SLOW_SCAN_IN:\n\t\t\tusb_out_bytecount = 5;\n\t\t\tusb_in_bytecount = OUT2BUF[cmd_id_index + 1];\n\t\t\tjtag_slow_scan_in(cmd_id_index + 1, payload_index_in);\n\t\t\tbreak;\n\t\tcase CMD_SLOW_SCAN_OUT:\n\t\t\tusb_out_bytecount = OUT2BUF[cmd_id_index + 1] + 5;\n\t\t\tjtag_slow_scan_out(cmd_id_index + 1);\n\t\t\tbreak;\n\t\tcase CMD_SLOW_SCAN_IO:\n\t\t\tusb_in_bytecount = OUT2BUF[cmd_id_index + 1];\n\t\t\tusb_out_bytecount = usb_in_bytecount + 5;\n\t\t\tjtag_slow_scan_io(cmd_id_index + 1, payload_index_in);\n\t\t\tbreak;\n\t\tcase CMD_SLOW_CLOCK_TMS:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tjtag_slow_clock_tms(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);\n\t\t\tbreak;\n\t\tcase CMD_SLOW_CLOCK_TCK:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tcount = (uint16_t)OUT2BUF[cmd_id_index + 1];\n\t\t\tcount |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;\n\t\t\tjtag_slow_clock_tck(count);\n\t\t\tbreak;\n\t\tcase CMD_SLEEP_US:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tcount = (uint16_t)OUT2BUF[cmd_id_index + 1];\n\t\t\tcount |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;\n\t\t\tdelay_us(count);\n\t\t\tbreak;\n\t\tcase CMD_SLEEP_MS:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tcount = (uint16_t)OUT2BUF[cmd_id_index + 1];\n\t\t\tcount |= ((uint16_t)OUT2BUF[cmd_id_index + 2]) << 8;\n\t\t\tdelay_ms(count);\n\t\t\tbreak;\n\t\tcase CMD_GET_SIGNALS:\n\t\t\tusb_out_bytecount = 0;\n\t\t\tusb_in_bytecount = 2;\n\t\t\tsignal_state = jtag_get_signals();\n\t\t\tIN2BUF[payload_index_in] = (signal_state >> 8) & 0x00FF;\n\t\t\tIN2BUF[payload_index_in + 1] = signal_state & 0x00FF;\n\t\t\tbreak;\n\t\tcase CMD_SET_SIGNALS:\n\t\t\tusb_out_bytecount = 2;\n\t\t\tjtag_set_signals(OUT2BUF[cmd_id_index + 1], OUT2BUF[cmd_id_index + 2]);\n\t\t\tbreak;\n\t\tcase CMD_CONFIGURE_TCK_FREQ:\n\t\t\tusb_out_bytecount = 5;\n\t\t\tjtag_configure_tck_delay(\n\t\t\tOUT2BUF[cmd_id_index + 1],\t/* scan_in */\n\t\t\tOUT2BUF[cmd_id_index + 2],\t/* scan_out */\n\t\t\tOUT2BUF[cmd_id_index + 3],\t/* scan_io */\n\t\t\tOUT2BUF[cmd_id_index + 4],\t/* clock_tck */\n\t\t\tOUT2BUF[cmd_id_index + 5]);\t/* clock_tms */\n\t\t\tbreak;\n\t\tcase CMD_SET_LEDS:\n\t\t\tusb_out_bytecount = 1;\n\t\t\texecute_set_led_command();\n\t\t\tbreak;\n\t\tcase CMD_TEST:\n\t\t\tusb_out_bytecount = 1;\n\t\t\t/* Do nothing... This command is only used to test if the device is ready\n\t\t\t * to accept new commands */\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* Should never be reached */\n\t\t\tusb_out_bytecount = 0;\n\t\t\tbreak;\n\t}\n\n\t/* Update EP2 Bulk-IN data byte count */\n\tpayload_index_in += usb_in_bytecount;\n\n\t/* Determine if this was the last command */\n\tif ((cmd_id_index + usb_out_bytecount + 1) >= OUT2BC)\n\t\treturn true;\n\telse {\n\t\t/* Not the last command, update cmd_id_index */\n\t\tcmd_id_index += (usb_out_bytecount + 1);\n\t\treturn false;\n\t}\n}\n\n/**\n * Forever wait for commands and execute them as they arrive.\n */\nvoid command_loop(void)\n{\n\tbool last_command;\n\n\twhile (1) {\n\t\tcmd_id_index = 0;\n\t\tpayload_index_in = 0;\n\n\t\t/* Wait until host sends EP2 Bulk-OUT packet */\n\t\twhile (!EP2_out)\n\t\t\t;\n\t\tEP2_out = 0;\n\n\t\t/* Turn on COM LED to indicate command execution */\n\t\tSET_COM_LED();\n\n\t\t/* Execute the commands */\n\t\tlast_command = false;\n\t\twhile (last_command == false)\n\t\t\tlast_command = execute_command();\n\n\t\tCLEAR_COM_LED();\n\n\t\t/* Send back EP2 Bulk-IN packet if required */\n\t\tif (payload_index_in > 0) {\n\t\t\tIN2BC = payload_index_in;\n\t\t\twhile (!EP2_in)\n\t\t\t\t;\n\t\t\tEP2_in = 0;\n\t\t}\n\n\t\t/* Re-arm EP2-OUT after command execution */\n\t\tOUT2BC = 0;\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/src/usb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011-2013 by Martin Schmoelzer                          *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n/**\n * @file\n * Defines USB descriptors, interrupt routines and helper functions.\n * To minimize code size, we make the following assumptions:\n *  - The OpenULINK has exactly one configuration\n *  - and exactly one alternate setting\n *\n * Therefore, we do not have to support the Set Configuration USB request.\n */\n\n#include \"usb.h\"\n#include \"delay.h\"\n#include \"io.h\"\n\n/* Also update external declarations in \"include/usb.h\" if making changes to\n * these variables! */\nvolatile bool EP2_out;\nvolatile bool EP2_in;\n\nvolatile __xdata __at 0x7FE8 struct setup_data setup_data;\n\n/* Define number of endpoints (except Control Endpoint 0) in a central place.\n * Be sure to include the necessary endpoint descriptors! */\n#define NUM_ENDPOINTS 2\n\n__code struct usb_device_descriptor device_descriptor = {\n\t.bLength =\t\tsizeof(struct usb_device_descriptor),\n\t.bDescriptorType =\tDESCRIPTOR_TYPE_DEVICE,\n\t.bcdUSB =\t\t0x0110,\t/* BCD: 01.00 (Version 1.0 USB spec) */\n\t.bDeviceClass =\t\t0xFF,\t/* 0xFF = vendor-specific */\n\t.bDeviceSubClass =\t0xFF,\n\t.bDeviceProtocol =\t0xFF,\n\t.bMaxPacketSize0 =\t64,\n\t.idVendor =\t\t0xC251,\n\t.idProduct =\t\t0x2710,\n\t.bcdDevice =\t\t0x0100,\n\t.iManufacturer =\t1,\n\t.iProduct =\t\t2,\n\t.iSerialNumber =\t3,\n\t.bNumConfigurations =\t1\n};\n\n/* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */\n\n__code struct usb_config_descriptor config_descriptor = {\n\t.bLength =\t\tsizeof(struct usb_config_descriptor),\n\t.bDescriptorType =\tDESCRIPTOR_TYPE_CONFIGURATION,\n\t.wTotalLength =\t\tsizeof(struct usb_config_descriptor) +\n\t\tsizeof(struct usb_interface_descriptor) +\n\t\t(NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)),\n\t.bNumInterfaces =\t1,\n\t.bConfigurationValue =\t1,\n\t.iConfiguration =\t4,\t/* String describing this configuration */\n\t.bmAttributes =\t\t0x80,\t/* Only MSB set according to USB spec */\n\t.MaxPower =\t\t50\t/* 100 mA */\n};\n\n__code struct usb_interface_descriptor interface_descriptor00 = {\n\t.bLength = sizeof(struct usb_interface_descriptor),\n\t.bDescriptorType =\tDESCRIPTOR_TYPE_INTERFACE,\n\t.bInterfaceNumber =\t0,\n\t.bAlternateSetting =\t0,\n\t.bNumEndpoints =\tNUM_ENDPOINTS,\n\t.bInterfaceClass =\t0xFF,\n\t.bInterfaceSubclass =\t0xFF,\n\t.bInterfaceProtocol =\t0xFF,\n\t.iInterface =\t\t0\n};\n\n__code struct usb_endpoint_descriptor Bulk_EP2_IN_Endpoint_Descriptor = {\n\t.bLength =\t\tsizeof(struct usb_endpoint_descriptor),\n\t.bDescriptorType =\t0x05,\n\t.bEndpointAddress =\t(2 | USB_DIR_IN),\n\t.bmAttributes =\t\t0x02,\n\t.wMaxPacketSize =\t64,\n\t.bInterval =\t\t0\n};\n\n__code struct usb_endpoint_descriptor Bulk_EP2_OUT_Endpoint_Descriptor = {\n\t.bLength =\t\tsizeof(struct usb_endpoint_descriptor),\n\t.bDescriptorType =\t0x05,\n\t.bEndpointAddress =\t(2 | USB_DIR_OUT),\n\t.bmAttributes =\t\t0x02,\n\t.wMaxPacketSize =\t64,\n\t.bInterval =\t\t0\n};\n\n__code struct usb_language_descriptor language_descriptor = {\n\t.bLength =\t\t4,\n\t.bDescriptorType =\tDESCRIPTOR_TYPE_STRING,\n\t.wLANGID =\t\t{0x0409 /* US English */}\n};\n\n__code struct usb_string_descriptor strManufacturer =\n\tSTR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');\n\n__code struct usb_string_descriptor strProduct =\n\tSTR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');\n\n__code struct usb_string_descriptor strSerialNumber =\n\tSTR_DESCR(6, '0', '0', '0', '0', '0', '1');\n\n__code struct usb_string_descriptor strConfigDescr  =\n\tSTR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');\n\n/* Table containing pointers to string descriptors */\n__code struct usb_string_descriptor *__code en_string_descriptors[4] = {\n\t&strManufacturer,\n\t&strProduct,\n\t&strSerialNumber,\n\t&strConfigDescr\n};\n\nvoid sudav_isr(void) __interrupt SUDAV_ISR\n{\n\tCLEAR_IRQ();\n\n\tusb_handle_setup_data();\n\n\tUSBIRQ = SUDAVIR;\n\tEP0CS |= HSNAK;\n}\n\nvoid sof_isr(void)      __interrupt SOF_ISR\n{\n}\nvoid sutok_isr(void)    __interrupt SUTOK_ISR\n{\n}\nvoid suspend_isr(void)  __interrupt SUSPEND_ISR\n{\n}\nvoid usbreset_isr(void) __interrupt USBRESET_ISR\n{\n}\nvoid ibn_isr(void)      __interrupt IBN_ISR\n{\n}\n\nvoid ep0in_isr(void)    __interrupt EP0IN_ISR\n{\n}\nvoid ep0out_isr(void)   __interrupt EP0OUT_ISR\n{\n}\nvoid ep1in_isr(void)    __interrupt EP1IN_ISR\n{\n}\nvoid ep1out_isr(void)   __interrupt EP1OUT_ISR\n{\n}\n\n/**\n * EP2 IN: called after the transfer from uC->Host has finished: we sent data\n */\nvoid ep2in_isr(void)    __interrupt EP2IN_ISR\n{\n\tEP2_in = 1;\n\n\tCLEAR_IRQ();\n\tIN07IRQ = IN2IR;/* Clear OUT2 IRQ */\n}\n\n/**\n * EP2 OUT: called after the transfer from Host->uC has finished: we got data\n */\nvoid ep2out_isr(void)   __interrupt EP2OUT_ISR\n{\n\tEP2_out = 1;\n\n\tCLEAR_IRQ();\n\tOUT07IRQ = OUT2IR;\t/* Clear OUT2 IRQ */\n}\n\nvoid ep3in_isr(void)    __interrupt EP3IN_ISR\n{\n}\nvoid ep3out_isr(void)   __interrupt EP3OUT_ISR\n{\n}\nvoid ep4in_isr(void)    __interrupt EP4IN_ISR\n{\n}\nvoid ep4out_isr(void)   __interrupt EP4OUT_ISR\n{\n}\nvoid ep5in_isr(void)    __interrupt EP5IN_ISR\n{\n}\nvoid ep5out_isr(void)   __interrupt EP5OUT_ISR\n{\n}\nvoid ep6in_isr(void)    __interrupt EP6IN_ISR\n{\n}\nvoid ep6out_isr(void)   __interrupt EP6OUT_ISR\n{\n}\nvoid ep7in_isr(void)    __interrupt EP7IN_ISR\n{\n}\nvoid ep7out_isr(void)   __interrupt EP7OUT_ISR\n{\n}\n\n/**\n * Return the control/status register for an endpoint\n *\n * @param ep endpoint address\n * @return on success: pointer to Control & Status register for endpoint\n *  specified in \\a ep\n * @return on failure: NULL\n */\n__xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)\n{\n\t/* Mask direction bit */\n\tuint8_t ep_num = ep & 0x7F;\n\n\tswitch (ep_num) {\n\t    case 0:\n\t\t    return &EP0CS;\n\t\t    break;\n\t    case 1:\n\t\t    return ep & 0x80 ? &IN1CS : &OUT1CS;\n\t\t    break;\n\t    case 2:\n\t\t    return ep & 0x80 ? &IN2CS : &OUT2CS;\n\t\t    break;\n\t    case 3:\n\t\t    return ep & 0x80 ? &IN3CS : &OUT3CS;\n\t\t    break;\n\t    case 4:\n\t\t    return ep & 0x80 ? &IN4CS : &OUT4CS;\n\t\t    break;\n\t    case 5:\n\t\t    return ep & 0x80 ? &IN5CS : &OUT5CS;\n\t\t    break;\n\t    case 6:\n\t\t    return ep & 0x80 ? &IN6CS : &OUT6CS;\n\t\t    break;\n\t    case 7:\n\t\t    return ep & 0x80 ? &IN7CS : &OUT7CS;\n\t\t    break;\n\t}\n\n\treturn NULL;\n}\n\nvoid usb_reset_data_toggle(uint8_t ep)\n{\n\t/* TOGCTL register:\n\t   +----+-----+-----+------+-----+-------+-------+-------+\n\t   | Q  |  S  |  R  |  IO  |  0  |  EP2  |  EP1  |  EP0  |\n\t   +----+-----+-----+------+-----+-------+-------+-------+\n\n\t   To reset data toggle bits, we have to write the endpoint direction (IN/OUT)\n\t   to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a\n\t   separate write cycle, the R bit needs to be set.\n\t*/\n\tuint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);\n\n\t/* First step: Write EP number and direction bit */\n\tTOGCTL = togctl_value;\n\n\t/* Second step: Set R bit */\n\ttogctl_value |= TOG_R;\n\tTOGCTL = togctl_value;\n}\n\n/**\n * Handle GET_STATUS request.\n *\n * @return on success: true\n * @return on failure: false\n */\nbool usb_handle_get_status(void)\n{\n\tuint8_t *ep_cs;\n\n\tswitch (setup_data.bmRequestType) {\n\t    case GS_DEVICE:\n\t\t\t/* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.\n\t\t\t *                    Byte 1: reserved, reset to zero */\n\t\t    IN0BUF[0] = 0;\n\t\t    IN0BUF[1] = 0;\n\n\t\t\t/* Send response */\n\t\t    IN0BC = 2;\n\t\t    break;\n\t    case GS_INTERFACE:\n\t\t\t/* Always return two zero bytes according to USB 1.1 spec, p. 191 */\n\t\t    IN0BUF[0] = 0;\n\t\t    IN0BUF[1] = 0;\n\n\t\t\t/* Send response */\n\t\t    IN0BC = 2;\n\t\t    break;\n\t    case GS_ENDPOINT:\n\t\t\t/* Get stall bit for endpoint specified in low byte of wIndex */\n\t\t    ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);\n\n\t\t    if (*ep_cs & EPSTALL)\n\t\t\t    IN0BUF[0] = 0x01;\n\t\t    else\n\t\t\t    IN0BUF[0] = 0x00;\n\n\t\t\t/* Second byte sent has to be always zero */\n\t\t    IN0BUF[1] = 0;\n\n\t\t\t/* Send response */\n\t\t    IN0BC = 2;\n\t\t    break;\n\t    default:\n\t\t    return false;\n\t\t    break;\n\t}\n\n\treturn true;\n}\n\n/**\n * Handle CLEAR_FEATURE request.\n *\n * @return on success: true\n * @return on failure: false\n */\nbool usb_handle_clear_feature(void)\n{\n\t__xdata uint8_t *ep_cs;\n\n\tswitch (setup_data.bmRequestType) {\n\t    case CF_DEVICE:\n\t\t\t/* Clear remote wakeup not supported: stall EP0 */\n\t\t    STALL_EP0();\n\t\t    break;\n\t    case CF_ENDPOINT:\n\t\t    if (setup_data.wValue == 0) {\n\t\t\t\t/* Unstall the endpoint specified in wIndex */\n\t\t\t    ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);\n\t\t\t    if (!ep_cs)\n\t\t\t\t    return false;\n\t\t\t    *ep_cs &= ~EPSTALL;\n\t\t    } else {\n\t\t\t\t/* Unsupported feature, stall EP0 */\n\t\t\t    STALL_EP0();\n\t\t    }\n\t\t    break;\n\t    default:\n\t\t\t/* Vendor commands... */\n\t}\n\n\treturn true;\n}\n\n/**\n * Handle SET_FEATURE request.\n *\n * @return on success: true\n * @return on failure: false\n */\nbool usb_handle_set_feature(void)\n{\n\t__xdata uint8_t *ep_cs;\n\n\tswitch (setup_data.bmRequestType) {\n\t    case SF_DEVICE:\n\t\t    if (setup_data.wValue == 2)\n\t\t\t    return true;\n\t\t    break;\n\t    case SF_ENDPOINT:\n\t\t    if (setup_data.wValue == 0) {\n\t\t\t\t/* Stall the endpoint specified in wIndex */\n\t\t\t    ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);\n\t\t\t    if (!ep_cs)\n\t\t\t\t    return false;\n\t\t\t    *ep_cs |= EPSTALL;\n\t\t    } else {\n\t\t\t\t/* Unsupported endpoint feature */\n\t\t\t    return false;\n\t\t    }\n\t\t    break;\n\t    default:\n\t\t\t/* Vendor commands... */\n\t\t    break;\n\t}\n\n\treturn true;\n}\n\n/**\n * Handle GET_DESCRIPTOR request.\n *\n * @return on success: true\n * @return on failure: false\n */\nbool usb_handle_get_descriptor(void)\n{\n\t__xdata uint8_t descriptor_type;\n\t__xdata uint8_t descriptor_index;\n\n\tdescriptor_type = (setup_data.wValue & 0xff00) >> 8;\n\tdescriptor_index = setup_data.wValue & 0x00ff;\n\n\tswitch (descriptor_type) {\n\t    case DESCRIPTOR_TYPE_DEVICE:\n\t\t    SUDPTRH = HI8(&device_descriptor);\n\t\t    SUDPTRL = LO8(&device_descriptor);\n\t\t    break;\n\t    case DESCRIPTOR_TYPE_CONFIGURATION:\n\t\t    SUDPTRH = HI8(&config_descriptor);\n\t\t    SUDPTRL = LO8(&config_descriptor);\n\t\t    break;\n\t    case DESCRIPTOR_TYPE_STRING:\n\t\t    if (setup_data.wIndex == 0) {\n\t\t\t\t/* Supply language descriptor */\n\t\t\t    SUDPTRH = HI8(&language_descriptor);\n\t\t\t    SUDPTRL = LO8(&language_descriptor);\n\t\t    } else if (setup_data.wIndex == 0x0409 /* US English */)   {\n\t\t\t\t/* Supply string descriptor */\n\t\t\t    SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);\n\t\t\t    SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);\n\t\t    } else\n\t\t\t    return false;\n\t\t    break;\n\t    default:\n\t\t\t/* Unsupported descriptor type */\n\t\t    return false;\n\t\t    break;\n\t}\n\n\treturn true;\n}\n\n/**\n * Handle SET_INTERFACE request.\n */\nvoid usb_handle_set_interface(void)\n{\n\t/* Reset Data Toggle */\n\tusb_reset_data_toggle(USB_DIR_IN  | 2);\n\tusb_reset_data_toggle(USB_DIR_OUT | 2);\n\n\t/* Unstall & clear busy flag of all valid IN endpoints */\n\tIN2CS = 0 | EPBSY;\n\n\t/* Unstall all valid OUT endpoints, reset bytecounts */\n\tOUT2CS = 0;\n\tOUT2BC = 0;\n}\n\n/**\n * Handle the arrival of a USB Control Setup Packet.\n */\nvoid usb_handle_setup_data(void)\n{\n\tswitch (setup_data.bRequest) {\n\t    case GET_STATUS:\n\t\t    if (!usb_handle_get_status())\n\t\t\t    STALL_EP0();\n\t\t    break;\n\t    case CLEAR_FEATURE:\n\t\t    if (!usb_handle_clear_feature())\n\t\t\t    STALL_EP0();\n\t\t    break;\n\t    case 2: case 4:\n\t\t\t/* Reserved values */\n\t\t    STALL_EP0();\n\t\t    break;\n\t    case SET_FEATURE:\n\t\t    if (!usb_handle_set_feature())\n\t\t\t    STALL_EP0();\n\t\t    break;\n\t    case SET_ADDRESS:\n\t\t\t/* Handled by USB core */\n\t\t    break;\n\t    case SET_DESCRIPTOR:\n\t\t\t/* Set Descriptor not supported. */\n\t\t    STALL_EP0();\n\t\t    break;\n\t    case GET_DESCRIPTOR:\n\t\t    if (!usb_handle_get_descriptor())\n\t\t\t    STALL_EP0();\n\t\t    break;\n\t    case GET_CONFIGURATION:\n\t\t\t/* OpenULINK has only one configuration, return its index */\n\t\t    IN0BUF[0] = config_descriptor.bConfigurationValue;\n\t\t    IN0BC = 1;\n\t\t    break;\n\t    case SET_CONFIGURATION:\n\t\t\t/* OpenULINK has only one configuration -> nothing to do */\n\t\t    break;\n\t    case GET_INTERFACE:\n\t\t\t/* OpenULINK only has one interface, return its number */\n\t\t    IN0BUF[0] = interface_descriptor00.bInterfaceNumber;\n\t\t    IN0BC = 1;\n\t\t    break;\n\t    case SET_INTERFACE:\n\t\t    usb_handle_set_interface();\n\t\t    break;\n\t    case SYNCH_FRAME:\n\t\t\t/* Isochronous endpoints not used -> nothing to do */\n\t\t    break;\n\t    default:\n\t\t\t/* Any other requests: do nothing */\n\t\t    break;\n\t}\n}\n\n/**\n * USB initialization. Configures USB interrupts, endpoints and performs\n * ReNumeration.\n */\nvoid usb_init(void)\n{\n\t/* Mark endpoint 2 IN & OUT as valid */\n\tIN07VAL  = IN2VAL;\n\tOUT07VAL = OUT2VAL;\n\n\t/* Make sure no isochronous endpoints are marked valid */\n\tINISOVAL  = 0;\n\tOUTISOVAL = 0;\n\n\t/* Disable isochronous endpoints. This makes the isochronous data buffers\n\t * available as 8051 XDATA memory at address 0x2000 - 0x27FF */\n\tISOCTL = ISODISAB;\n\n\t/* Enable USB Autovectoring */\n\tUSBBAV |= AVEN;\n\n\t/* Enable SUDAV interrupt */\n\tUSBIEN |= SUDAVIE;\n\n\t/* Enable EP2 OUT & IN interrupts */\n\tOUT07IEN = OUT2IEN;\n\tIN07IEN  = IN2IEN;\n\n\t/* Enable USB interrupt (EIE register) */\n\tEUSB = 1;\n\n\t/* Perform ReNumeration */\n\tUSBCS = DISCON | RENUM;\n\tdelay_ms(200);\n\tUSBCS = DISCOE | RENUM;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/OpenULINK/ulink_firmware.hex",
    "content": ":040000000200713257\n:01000B0032C2\n:0100130032BA\n:01001B0032B2\n:0100230032AA\n:01002B0032A2\n:01003300329A\n:01003B003292\n:01004300328A\n:01004B003282\n:01005300327A\n:01005B003272\n:01006300326A\n:03006B000201107F\n:0300CA0002006EC3\n:03006E000201018B\n:1000CD00907F937404F0907F9C7495F0907F96745C\n:1000DD0090F0907F94E4F0907F9D747FF0907F97E7\n:1000ED00E4F0907F957440F0907F9E7442F0907F85\n:1000FD0098E4F0221200CD1204ADD2AF1208E090B8\n:10010D00000022C021C0E0C0F0C082C083C007C083\n:10011D0006C005C004C003C002C001C000C0D07538\n:10012D00D000AF9174EF5FF59112040C907FAB741A\n:10013D0001F0907FB4E04402F0D0D0D000D001D0D7\n:10014D0002D003D004D005D006D007D083D082D002\n:10015D00F0D0E0D02132323232323232323232C04D\n:10016D00E0C082C083C007C0D075D000D201AF916E\n:10017D0074EF5FF591907FA97404F0D0D0D007D0C3\n:10018D0083D082D0E032C0E0C082C083C007C0D02F\n:10019D0075D000D200AF9174EF5FF591907FAA7486\n:1001AD0004F0D0D0D007D083D082D0E032323232BA\n:1001BD0032323232323232AF82747F5FFE24F850E7\n:1001CD0003020278EE240A83F582EE240C83F58374\n:1001DD00E473EFF306192C3F52650101020202028E\n:1001ED000202907FB422EF30E7067DB67E7F800459\n:1001FD007DC67E7F8D828E8322EF30E7067DB87EB1\n:10020D007F80047DC87E7F8D828E8322EF30E7064E\n:10021D007DBA7E7F80047DCA7E7F8D828E8322EFA4\n:10022D0030E7067DBC7E7F80047DCC7E7F8D828E07\n:10023D008322EF30E7067DBE7E7F80047DCE7E7FFC\n:10024D008D828E8322EF30E7067DC07E7F80047D18\n:10025D00D07E7F8D828E8322EF30E7067EC27F7F38\n:10026D0080047ED27F7F8E828F832290000022AF0A\n:10027D008274105FFE74075F4206907FD7EEF074B4\n:10028D00204EF022907FE8E0C322907FE8E0FF60EF\n:10029D0005BF0246800A907FB4E0FF4401F0803A2A\n:1002AD00907FEAE0FEA3E0FF4E7027907FECE0FE2A\n:1002BD00A3E08E821201C4AE82AF83EE4F7002C3F3\n:1002CD00228E828F83E0FD5305FE8E828F83EDF0AB\n:1002DD008008907FB4E0FF4401F0D322907FE8E0E6\n:1002ED00FF6005BF02468010907FEAE0FEA3E0FFAD\n:1002FD00BE0239BF0036D322907FEAE0FEA3E0FFB5\n:10030D004E7027907FECE0FEA3E08E821201C4AE0A\n:10031D0082AF83EE4F7002C3228E828F83E0FD4346\n:10032D0005018E828F83EDF08002C322D322907F50\n:10033D00EAE0A3E0FF907FEAE0FDA3E07E00BF01CD\n:10034D0002800DBF02028021BF030280340203EC44\n:10035D007ED37F138F06907FD4EEF07ED37F137FF5\n:10036D0000907FD5EEF00203EE7EE57F138F0690B1\n:10037D007FD4EEF07EE57F137F00907FD5EEF08089\n:10038D0060907FECE0FEA3E0FF4E70187E057F14B9\n:10039D008F06907FD4EEF07E057F147F00907FD581\n:1003AD00EEF0803D907FECE0FEA3E0FFBE092EBF96\n:1003BD00042BED1475F002A42459F582741435F054\n:1003CD00F583E493FEA3E493FF8E048F058D0490D3\n:1003DD007FD4ECF07F00907FD5EEF08004C322C374\n:1003ED0022D32275828212027C75820212027C90C7\n:1003FD007FB87402F0907FC8E4F0907FC9F022902E\n:10040D007FE9E0FF24F3500122EFF5F0240B83F593\n:10041D0082E5F0241183F583E473414F5D655D72D0\n:10042D007B73889899A9AC0404040404040404049F\n:10043D0004040404120291500122907FB4E044019F\n:10044D00F022120297500122907FB4E04401F02275\n:10045D00907FB4E04401F0221202E94042907FB453\n:10046D00E04401F02222907FB4E04401F022120317\n:10047D003B402C907FB4E04401F0229013EAE493CA\n:10048D00907F00F0907FB57401F022229013F0E47C\n:10049D0093907F00F0907FB57401F0221203F0224B\n:1004AD00907FDE7404F0907FDF7404F0907FE0E4C1\n:1004BD00F0907FE1F0907FA17401F0907FAFE04468\n:1004CD0001F0907FAEE04401F0907FAD7404F090A8\n:1004DD007FAC7404F0D2E8907FD6740AF09000C817\n:0A04ED0012137C907FD67406F022F3\n:1013D30012011001FFFFFF4051C21027000101025B\n:1013E3000301090220000101048032090400000204\n:1013F300FFFFFF00070582024000000705020240CD\n:1014030000000403090414034F00700065006E001C\n:1014130055004C0049004E004B0014034F00700070\n:1014230065006E0055004C0049004E004B000E0352\n:101433003000300030003000300031001A034A0021\n:101443005400410047002000410064006100700027\n:0E14530074006500720009141D1431143F145A\n:1004F700E5080424C0F582E4347DF583E0FF30E1AC\n:1005070008907F96E0FE54EFF08F06EE30E00890FB\n:100517007F96E0FE547FF0EF30E308907F96E0FE91\n:100527004410F0EF30E208907F96E0FF4480F0221D\n:100537007F00E50824C0F582E4347DF583E0FE24DE\n:10054700D550030208A6EE240A83F582EE242F83F2\n:10055700F583E473B18AD7B0FAD3A6A6A6A6A6A652\n:10056700A6A6A6A6A6A6A6A6A6A6A6A6A6A6A6A624\n:10057700A6A6A6A621FA512A639CD5053493A205FF\n:1005870006050605060808080808080808080808F0\n:1005970008080808080808080808080808080806D6\n:1005A700060607070707080808087E05E508042464\n:1005B700C0F582E4347DF583E0FFE50804F5828524\n:1005C7000927C007C00612091DD006D0070208A8D0\n:1005D700E5080424C0F582E4347DF583E02405FEB4\n:1005E700E50804F582C007C006120BDED006D00767\n:1005F7000208A8E5080424C0F582E4347DF583E009\n:10060700FF2405FEE50804F58285093CC007C006FE\n:10061700120E79D006D0070208A87E02E508042446\n:10062700C0F582E4347DF583E0FD7402250824C01B\n:10063700F582E4347DF583E0F50A8D82C007C006B4\n:1006470012124AD006D0070208A87E02E508042441\n:10065700C0F582E4347DF583E0FC7D007402250853\n:1006670024C0F582E4347DF583E0FAE44204EA42EB\n:10067700058C828D83C007C0061211DDD006D00716\n:100687000208A87E05E5080424C0F582E4347DF558\n:1006970083E0FFE50804F58285092DC007C006122F\n:1006A7000A67D006D0070208A8E5080424C0F58227\n:1006B700E4347DF583E02405FEE50804F582C007F0\n:1006C700C006120D14D006D0070208A8E5080424B6\n:1006D700C0F582E4347DF583E0FF2405FEE50804D8\n:1006E700F582850943C007C006121013D006D0074C\n:1006F7000208A87E02E5080424C0F582E4347DF5EB\n:1007070083E0FB7402250824C0F582E4347DF58379\n:10071700E0F50A8B82C007C006121281D006D00707\n:100727000208A87E02E5080424C0F582E4347DF5BA\n:1007370083E0FC7D007402250824C0F582E4347D43\n:10074700F583E0FAE44204EA42058C828D83C00710\n:10075700C006121207D006D0070208A87E02E508D5\n:100767000424C0F582E4347DF583E0FC7D00740247\n:10077700250824C0F582E4347DF583E0FAE44204D9\n:10078700EA42058C828D83C007C006121349D00642\n:10079700D0070208A87E02E5080424C0F582E434E5\n:1007A7007DF583E0FC7D007402250824C0F582E412\n:1007B700347DF583E0FAE44204EA42058C828D83B6\n:1007C700C007C00612137CD006D0070208A87E0017\n:1007D7007F02C007C0061212CEAC82AD83D006D00E\n:1007E7000785098275837E8D03EBF0E509042400F4\n:1007F700F582E4347EF5837D00ECF00208A87E02E2\n:10080700E5080424C0F582E4347DF583E0FD740235\n:10081700250824C0F582E4347DF583E0F50A8D824E\n:10082700C007C006121311D006D00780747E05E5F5\n:10083700080424C0F582E4347DF583E0FD740225C5\n:100847000824C0F582E4347DF583E0F50A740325B6\n:100857000824C0F582E4347DF583E0F50B740425A4\n:100867000824C0F582E4347DF583E0F50C74052592\n:100877000824C0F582E4347DF583E0F50D8D82C050\n:1008870007C006121329D006D00780157E01C007BE\n:10089700C0061204F7D006D00780067E0180027ECC\n:1008A70000EF2509F509AD087F008E037C00EB2DCD\n:1008B700FDEC3FFF0DBD00010F907FC9E0FC7B0001\n:1008C700C3ED9CEF64808BF063F08095F04002D31A\n:1008D70022EE042508F508C32275080075090010E3\n:1008E700000280FB907F96E0FF547FF0C202200257\n:1008F70007120537920280F6907F96E0FF4480F05A\n:10090700E509600B907FB9E509F010010280FB90C3\n:100917007FC9E4F080C3E582FF24C0F582E4347D1B\n:10092700F583E0F528EF0424C0F582E4347DF583F0\n:10093700E0F52974022FFC24C0F582E4347DF583A9\n:10094700E0C4540FFB53030FEC24C0F582E4347D5D\n:10095700F583E0FC740F5CF52A74032F24C0F5823D\n:10096700E4347DF583E0FA74042F24C0F582E4347F\n:100977007DF583E0F52BEB60078A0A8B8212124A1A\n:10098700907F97E0FB5303F874044BFA7900A8288B\n:100997007C0018B8FF011C89067F00C3EE98EF643E\n:1009A700808CF063F08095F050347F007E00907F5C\n:1009B70097EBF0EFC313FF907F97EAF0907F99E0F2\n:1009C700FC30E5034307800EBE080040E1E5272918\n:1009D7002400F582E4347EF583EFF00980B0892C9A\n:1009E7007F00AC2A7A00C3EA95295040A8297900EC\n:1009F70018B8FF01198A057E00EDB50011EEB501A3\n:100A07000DEC600A4303021CE52BC313F52B907F03\n:100A170097EBF0EFC313FF907F9774044BF0907F31\n:100A270099E0FE30E5034307800A80BAAD297E00CE\n:100A37007408C39DFDE49EFE8DF005F0EF8002C3B0\n:100A470013D5F0FBFFE527252C2400F582E4347E3F\n:100A5700F583EFF0EC6008852B0A8C8202124A229C\n:100A6700E582FF24C0F582E4347DF583E0F52EEFBF\n:100A77000424C0F582E4347DF583E0F52F74022F5A\n:100A8700FC24C0F582E4347DF583E0C4540FFB53A6\n:100A9700030FEC24C0F582E4347DF583E0FC740F8A\n:100AA7005CF53074032F24C0F582E4347DF583E0D0\n:100AB700FA74042F24C0F582E4347DF583E0F53120\n:100AC700EB60078A0A8B82121281907F97E0FB53B3\n:100AD70003F874044BFA753200A82E7C0018B8FF8F\n:100AE700011CA9327E00C3E998EE64808CF063F0A4\n:100AF7008095F0504C7E007C00907F97EBF079005A\n:100B0700C3E9952250030980F7EEC313FE907F9740\n:100B1700EAF07900C3E9952250030980F7907F999D\n:100B2700E0F930E5034306800CBC080040CBE52D17\n:100B370025322400F582E4347EF583EEF005328019\n:100B4700987E00AA307900C3E9952F5056A82F7CCC\n:100B57000018B8FF011C89057F00EDB50011EFB53E\n:100B6700040DEA600A4303021AE531C313F5319015\n:100B77007F97EBF07F00C3EF952250030F80F7EECE\n:100B8700C313FE907F9774044BF07F00C3EF952249\n:100B970050030F80F7907F99E0FF30E5034306800D\n:100BA7000980A4AD2F7F007408C39DFDE49FFF8DCE\n:100BB700F005F0EE8002C313D5F0FBFEE52D2532DC\n:100BC7002400F582E4347EF583EEF0EA600885318F\n:100BD7000A8A8202128122E582FF24C0F582E43468\n:100BE7007DF583E0F533EF0424C0F582E4347DF529\n:100BF70083E0F53474022FFC24C0F582E4347DF5DC\n:100C070083E0C4540FFB53030FEC24C0F582E43494\n:100C17007DF583E0FC740F5CF53574032F24C0F574\n:100C270082E4347DF583E0FA74042F24C0F582E46E\n:100C3700347DF583E0F536EB600B8A0A8B82C007BB\n:100C470012124AD007907F97E0FB5303F97A00A866\n:100C5700337C0018B8FF011C8A017E00C3E998EEB7\n:100C670064808CF063F08095F05039EF2A240524D6\n:100C7700C0F582E4347DF583E0FE7C00EE30E005CC\n:100C870043030180068B0174FE59FB907F97EBF0BD\n:100C9700EEC313FE907F9774044BF00CBC08004022\n:100CA700DB0A80ABEF2A240524C0F582E4347DF506\n:100CB70083E0FEAF357C00C3EC95345044EE30E062\n:100CC7000543030180068B0274FE5AFBA9347A00A0\n:100CD70019B9FF011A8C007D00E8B50111EDB502C5\n:100CE7000DEF600A4303021FE536C313F536907F05\n:100CF70097EBF0EEC313FE907F9774044BF00C80D4\n:100D0700B6EF600885360A8F8202124A22E582F51D\n:100D17003724C0F582E4347DF583E0F538E5370400\n:100D270024C0F582E4347DF583E0F5397402253774\n:100D3700FC24C0F582E4347DF583E0C4540FFB53F3\n:100D4700030FEC24C0F582E4347DF583E0FC740FD7\n:100D57005CF53A7403253724C0F582E4347DF583C6\n:100D6700E0FA7404253724C0F582E4347DF583E086\n:100D7700F53BEB60078A0A8B82121281907F97E01E\n:100D8700FB5303F97A00A8387C0018B8FF011C8AC6\n:100D9700067F00C3EE98EF64808CF063F08095F0D7\n:100DA7005050E5372A240524C0F582E4347DF583C5\n:100DB700E0FF7E00EF30E00543030180068B0474FB\n:100DC700FE5CFB907F97EBF07C00C3EC9523500310\n:100DD7000C80F7EFC313FF907F9774044BF07C00F0\n:100DE700C3EC952350030C80F70EBE080040C50ADC\n:100DF7008094E5372A240524C0F582E4347DF58301\n:100E0700E0FFAE3A7C00C3EC9539505AEF30E0056D\n:100E170043030180068B0274FE5AFBA8397A001837\n:100E2700B8FF011A8C017D00E9B50011EDB5020D7F\n:100E3700EE600A4303021EE53BC313F53B907F9721\n:100E4700EBF07D00C3ED952350030D80F7EFC3133F\n:100E5700FF907F9774044BF07D00C3ED95235003FB\n:100E67000D80F70C80A0EE6008853B0A8E82021287\n:100E77008122E582FF24C0F582E4347DF583E0F525\n:100E87003DEF0424C0F582E4347DF583E0F53E743C\n:100E9700022FFC24C0F582E4347DF583E0C4540FAF\n:100EA700FB53030FEC24C0F582E4347DF583E0FCAB\n:100EB700740F5CF53F74032F24C0F582E4347DF58D\n:100EC70083E0FA74042F24C0F582E4347DF583E0CF\n:100ED700F540EB600B8A0A8B82C00712124AD007D3\n:100EE700907F97E0FB5303F97A00A83D7C0018B880\n:100EF700FF011C8A017E00C3E998EE64808CF063D1\n:100F0700F08095F0505CEF2A240524C0F582E43484\n:100F17007DF583E0F5417C007900E54130E005434C\n:100F2700030180068B0074FE58FB907F97EBF0E57A\n:100F370041C313F541907F9774044BF0ECC313FC46\n:100F4700907F99E0F830E50343048009B908004031\n:100F5700C9E53C2A2400F582E4347EF583ECF00AE7\n:100F670080888A01EF2A240524C0F582E4347DF5C0\n:100F770083E0F5417C00AF3F754200C3E542953EF3\n:100F87005057E54130E00543030180068B0074FEAE\n:100F970058FBA83E7D0018B8FF011DAA427E00EA53\n:100FA700B50011EEB5050DEF600A4303021FE540DA\n:100FB700C313F540907F97EBF0E541C313F54190DC\n:100FC7007F9774044BF0ECC313FC907F99E0FE30DD\n:100FD700E503430480054280A2AD3E7E007408C34A\n:100FE7009DFDE49EFE8DF005F0EC8002C313D5F065\n:100FF700FBFCE53C292400F582E4347EF583ECF024\n:10100700EF600885400A8F8202124A22E582F54482\n:1010170024C0F582E4347DF583E0F545E5440424F6\n:10102700C0F582E4347DF583E0F54674022544FC7F\n:1010370024C0F582E4347DF583E0C4540FFB5303E9\n:101047000FEC24C0F582E4347DF583E0FC740F5C7B\n:10105700F5477403254424C0F582E4347DF583E025\n:10106700FA7404254424C0F582E4347DF583E0F561\n:1010770048EB60078A0A8B82121281907F97E0FB08\n:101087005303F97A00A8457C0018B8FF011C8A06AB\n:101097007F00C3EE98EF64808CF063F08095F0508A\n:1010A70074E5442A240524C0F582E4347DF583E001\n:1010B700F5497E007C00E54930E0054303018006E1\n:1010C7008B0074FE58FB907F97EBF07800C3E89590\n:1010D7002450030880F7E549C313F549907F9774B7\n:1010E700044BF07800C3E8952450030880F7EEC35B\n:1010F70013FE907F99E0F830E5034306800CBC08A7\n:101107000040B3E5432A2400F582E4347EF583EEFC\n:10111700F00A02108C8A04E5442A240524C0F582CB\n:10112700E4347DF583E0F5497E00AA47754A00C39C\n:10113700E54A9546506DE54930E0054303018006D1\n:101147008B0174FE59FBA9467D0019B9FF011DA843\n:101157004A7F00E8B50111EFB5050DEA600A4303C0\n:10116700021AE548C313F548907F97EBF07F00C359\n:10117700EF952450030F80F7E549C313F549907F96\n:101187009774044BF07F00C3EF952450030F80F74B\n:10119700EEC313FE907F99E0FF30E5034306800519\n:1011A7004A808CAD467F007408C39DFDE49FFF8D88\n:1011B700F005F0EE8002C313D5F0FBFEE5432C24C7\n:1011C70000F582E4347EF583EEF0EA600885480A8C\n:1011D7008A8202128122AE82AF83907F97E0FD530D\n:1011E70005FB74044DFC7A007B00C3EA9EEB9F501D\n:1011F7000E907F97EDF0ECF00ABA00EE0B80EB2231\n:10120700AE82AF83907F97E0FD5305FB74044DFCDE\n:101217007A007B00C3EA9EEB9F5027907F97EDF003\n:101227007900C3E9952550030980F7907F97ECF083\n:101237007900C3E9952550030980F70ABA00D50B51\n:1012470080D222AF82907F97E0FE5306FB7D00C3DA\n:10125700ED9F5025E50A30E00543060280068E041F\n:1012670074FD5CFE907F97EEF0E50AC313F50A90D4\n:101277007F9774044EF00D80D622AF82907F97E05F\n:10128700FE5306FB7D00C3ED9F503BE50A30E005AA\n:1012970043060280068E0474FD5CFE907F97EEF095\n:1012A7007C00C3EC952650030C80F7E50AC313F5C1\n:1012B7000A907F9774044EF07C00C3EC9526500388\n:1012C7000C80F70D80C0227F00907F99E0FE30E50B\n:1012D700027F01907F99E0FE30E603430702907F8B\n:1012E7009AE0FE30E703430704907F9BE0FE30E57A\n:1012F70003430708907F9AE0FE53067F8F05E4FFBC\n:10130700FCEE4FF582EC4DF58322E582547FF4FF26\n:10131700907F97E05FF0747F550AFF907F97E04FCB\n:10132700F022858222850A23850B24850C25850DCD\n:10133700262200227E567F021EBEFF011FEE4F703F\n:10134700F722750A05750B001213A6AE82AF837CD0\n:10135700007D00C3EC9EED9F501AC007C006C00574\n:10136700C004121339D004D005D006D0070CBC0036\n:10137700E20D80DF22AE82AF837C007D00C3EC9E4E\n:10138700ED9F501AC007C006C005C00412133BD01A\n:0F13970004D005D006D0070CBC00E20D80DF2289\n:03004300021B009D\n:101B0000020110000201630002016400020165008D\n:101B1000020166000201670002016800020169001B\n:101B200002016A0002016B0002016C0002019300D5\n:101B30000201BA000201BB000201BC000201BD00AB\n:101B40000201BE000201BF000201C0000201C1008B\n:081B50000201C2000201C30002\n:1013A6007A10E4FBFCE58225E0F582E58333F583DC\n:1013B600EB33FBEC33FCEB950AF5F0EC950B4006B2\n:0913C600FCABF0438201DADD22E8\n:0600A000E478FFF6D8FD34\n:10007E007900E94400601B7A009014617800759253\n:10008E0020E493F2A308B800020592D9F4DAF275CF\n:02009E0092FFCF\n:1000A6007800E84400600A7900759220E4F309D8E4\n:1000B600FC7800E84400600C7900902000E4F0A38E\n:0400C600D8FCD9FA8F\n:0D00710075814A1213CFE582600302006E14\n:0413CF007582002201\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/am335xgpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Steve Marple, stevemarple@googlemail.com        *\n *                                                                         *\n *   Based on bcm2835gpio.c and linuxgpiod.c                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include \"bitbang.h\"\n\n#include <sys/mman.h>\n\n/* GPIO register base addresses. Values taken from \"AM335x and AMIC110 Sitara\n * Processors Technical Reference Manual\", Chapter 2 Memory Map.\n */\n#define AM335XGPIO_NUM_GPIO_PER_CHIP 32\n#define AM335XGPIO_NUM_GPIO_CHIPS 4\n#define AM335XGPIO_GPIO0_HW_ADDR 0x44E07000\n#define AM335XGPIO_GPIO1_HW_ADDR 0x4804C000\n#define AM335XGPIO_GPIO2_HW_ADDR 0x481AC000\n#define AM335XGPIO_GPIO3_HW_ADDR 0x481AE000\n\n/* 32-bit offsets from GPIO chip base address. Values taken from \"AM335x and\n * AMIC110 Sitara Processors Technical Reference Manual\", Chapter 25\n * General-Purpose Input/Output.\n */\n#define AM335XGPIO_GPIO_OE_OFFSET (0x134 / 4)\n#define AM335XGPIO_GPIO_DATAIN_OFFSET (0x138 / 4)\n#define AM335XGPIO_GPIO_DATAOUT_OFFSET (0x13C / 4)  /* DATAOUT register uses 0 for output, 1 for input */\n#define AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET (0x190 / 4)\n#define AM335XGPIO_GPIO_SETDATAOUT_OFFSET (0x194 / 4)\n\n#define AM335XGPIO_READ_REG(chip_num, offset) \\\n\t(*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)))\n\n#define AM335XGPIO_WRITE_REG(chip_num, offset, value) \\\n\t(*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) = (value))\n\n#define AM335XGPIO_SET_REG_BITS(chip_num, offset, bit_mask) \\\n\t(*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) |= (bit_mask))\n\n#define AM335XGPIO_CLEAR_REG_BITS(chip_num, offset, bit_mask) \\\n\t(*(am335xgpio_gpio_chip_mmap_addr[(chip_num)] + (offset)) &= ~(bit_mask))\n\n#define AM335XGPIO_SET_INPUT(gpio_config) \\\n\tAM335XGPIO_SET_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))\n#define AM335XGPIO_SET_OUTPUT(gpio_config) \\\n\tAM335XGPIO_CLEAR_REG_BITS((gpio_config)->chip_num, AM335XGPIO_GPIO_OE_OFFSET, BIT((gpio_config)->gpio_num))\n#define AM335XGPIO_SET_HIGH(gpio_config) \\\n\tAM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_SETDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))\n#define AM335XGPIO_SET_LOW(gpio_config) \\\n\tAM335XGPIO_WRITE_REG((gpio_config)->chip_num, AM335XGPIO_GPIO_CLEARDATAOUT_OFFSET, BIT((gpio_config)->gpio_num))\n\nenum amx335gpio_initial_gpio_mode {\n\tAM335XGPIO_GPIO_MODE_INPUT,\n\tAM335XGPIO_GPIO_MODE_OUTPUT_LOW,\n\tAM335XGPIO_GPIO_MODE_OUTPUT_HIGH,\n};\n\nstatic const uint32_t am335xgpio_gpio_chip_hw_addr[AM335XGPIO_NUM_GPIO_CHIPS] = {\n\tAM335XGPIO_GPIO0_HW_ADDR,\n\tAM335XGPIO_GPIO1_HW_ADDR,\n\tAM335XGPIO_GPIO2_HW_ADDR,\n\tAM335XGPIO_GPIO3_HW_ADDR,\n};\n\n/* Memory-mapped address pointers */\nstatic volatile uint32_t *am335xgpio_gpio_chip_mmap_addr[AM335XGPIO_NUM_GPIO_CHIPS];\n\nstatic int dev_mem_fd;\nstatic enum amx335gpio_initial_gpio_mode initial_gpio_mode[ADAPTER_GPIO_IDX_NUM];\n\n/* Transition delay coefficients */\nstatic int speed_coeff = 600000;\nstatic int speed_offset = 575;\nstatic unsigned int jtag_delay;\n\nstatic const struct adapter_gpio_config *adapter_gpio_config;\n\nstatic bool is_gpio_config_valid(const struct adapter_gpio_config *gpio_config)\n{\n\treturn gpio_config->chip_num >= 0\n\t\t&& gpio_config->chip_num < AM335XGPIO_NUM_GPIO_CHIPS\n\t\t&& gpio_config->gpio_num >= 0\n\t\t&& gpio_config->gpio_num < AM335XGPIO_NUM_GPIO_PER_CHIP;\n}\n\nstatic int get_gpio_value(const struct adapter_gpio_config *gpio_config)\n{\n\tunsigned int shift = gpio_config->gpio_num;\n\tuint32_t value = AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAIN_OFFSET);\n\tvalue = (value >> shift) & 1;\n\treturn value ^ (gpio_config->active_low ? 1 : 0);\n}\n\nstatic void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)\n{\n\tvalue = value ^ (gpio_config->active_low ? 1 : 0);\n\tswitch (gpio_config->drive) {\n\tcase ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:\n\t\tif (value)\n\t\t\tAM335XGPIO_SET_HIGH(gpio_config);\n\t\telse\n\t\t\tAM335XGPIO_SET_LOW(gpio_config);\n\t\t/* For performance reasons assume the GPIO is already set as an output\n\t\t * and therefore the call can be omitted here.\n\t\t */\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:\n\t\tif (value) {\n\t\t\tAM335XGPIO_SET_INPUT(gpio_config);\n\t\t} else {\n\t\t\tAM335XGPIO_SET_LOW(gpio_config);\n\t\t\tAM335XGPIO_SET_OUTPUT(gpio_config);\n\t\t}\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:\n\t\tif (value) {\n\t\t\tAM335XGPIO_SET_HIGH(gpio_config);\n\t\t\tAM335XGPIO_SET_OUTPUT(gpio_config);\n\t\t} else {\n\t\t\tAM335XGPIO_SET_INPUT(gpio_config);\n\t\t}\n\t\tbreak;\n\t}\n}\n\nstatic enum amx335gpio_initial_gpio_mode get_gpio_mode(const struct adapter_gpio_config *gpio_config)\n{\n\tif (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_OE_OFFSET) & BIT(gpio_config->gpio_num))\n\t\treturn AM335XGPIO_GPIO_MODE_INPUT;\n\n\t/* Return output level too so that pin mode can be fully restored */\n\tif (AM335XGPIO_READ_REG(gpio_config->chip_num, AM335XGPIO_GPIO_DATAOUT_OFFSET) & BIT(gpio_config->gpio_num))\n\t\treturn AM335XGPIO_GPIO_MODE_OUTPUT_HIGH;\n\treturn AM335XGPIO_GPIO_MODE_OUTPUT_LOW;\n}\n\nstatic const char *get_gpio_mode_name(enum amx335gpio_initial_gpio_mode gpio_mode)\n{\n\tswitch (gpio_mode) {\n\tcase AM335XGPIO_GPIO_MODE_INPUT:\n\t\treturn \"input\";\n\tcase AM335XGPIO_GPIO_MODE_OUTPUT_LOW:\n\t\treturn \"output (low)\";\n\tcase AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:\n\t\treturn \"output (high)\";\n\t}\n\treturn \"unknown\";\n}\n\nstatic void initialize_gpio(enum adapter_gpio_config_index idx)\n{\n\tif (!is_gpio_config_valid(&adapter_gpio_config[idx]))\n\t\treturn;\n\n\tinitial_gpio_mode[idx] = get_gpio_mode(&adapter_gpio_config[idx]);\n\tLOG_DEBUG(\"saved GPIO mode for %s (GPIO %d %d): %s\",\n\t\t\tadapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,\n\t\t\tget_gpio_mode_name(initial_gpio_mode[idx]));\n\n\tif (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {\n\t\tLOG_WARNING(\"am335xgpio does not support pull-up or pull-down settings (signal %s)\",\n\t\t\tadapter_gpio_get_name(idx));\n\t}\n\n\tswitch (adapter_gpio_config[idx].init_state) {\n\tcase ADAPTER_GPIO_INIT_STATE_INACTIVE:\n\t\tset_gpio_value(&adapter_gpio_config[idx], 0);\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_ACTIVE:\n\t\tset_gpio_value(&adapter_gpio_config[idx], 1);\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_INPUT:\n\t\tAM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);\n\t\tbreak;\n\t}\n\n\t/* Direction for non push-pull is already set by set_gpio_value() */\n\tif (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)\n\t\tAM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);\n}\n\nstatic void restore_gpio(enum adapter_gpio_config_index idx)\n{\n\tif (is_gpio_config_valid(&adapter_gpio_config[idx])) {\n\t\tswitch (initial_gpio_mode[idx]) {\n\t\tcase AM335XGPIO_GPIO_MODE_INPUT:\n\t\t\tAM335XGPIO_SET_INPUT(&adapter_gpio_config[idx]);\n\t\t\tbreak;\n\t\tcase AM335XGPIO_GPIO_MODE_OUTPUT_LOW:\n\t\t\tAM335XGPIO_SET_LOW(&adapter_gpio_config[idx]);\n\t\t\tAM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);\n\t\t\tbreak;\n\t\tcase AM335XGPIO_GPIO_MODE_OUTPUT_HIGH:\n\t\t\tAM335XGPIO_SET_HIGH(&adapter_gpio_config[idx]);\n\t\t\tAM335XGPIO_SET_OUTPUT(&adapter_gpio_config[idx]);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nstatic bb_value_t am335xgpio_read(void)\n{\n\treturn get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]) ? BB_HIGH : BB_LOW;\n}\n\nstatic int am335xgpio_write(int tck, int tms, int tdi)\n{\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI], tdi);\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS], tms);\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK], tck); /* Write clock last */\n\n\tfor (unsigned int i = 0; i < jtag_delay; ++i)\n\t\tasm volatile (\"\");\n\n\treturn ERROR_OK;\n}\n\nstatic int am335xgpio_swd_write(int swclk, int swdio)\n{\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */\n\n\tfor (unsigned int i = 0; i < jtag_delay; ++i)\n\t\tasm volatile (\"\");\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int am335xgpio_reset(int trst, int srst)\n{\n\t/* As the \"adapter reset_config\" command keeps the srst and trst gpio drive\n\t * mode settings in sync we can use our standard set_gpio_value() function\n\t * that honours drive mode and active low.\n\t */\n\tif (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST]))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);\n\n\tif (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST]))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);\n\n\tLOG_DEBUG(\"am335xgpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d\",\n\t\ttrst, srst,\n\t\tadapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,\n\t\tadapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);\n\treturn ERROR_OK;\n}\n\nstatic void am335xgpio_swdio_drive(bool is_output)\n{\n\tif (is_output) {\n\t\tif (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))\n\t\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);\n\t\tAM335XGPIO_SET_OUTPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);\n\t} else {\n\t\tAM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);\n\t\tif (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR]))\n\t\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);\n\t}\n}\n\nstatic int am335xgpio_swdio_read(void)\n{\n\treturn get_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);\n}\n\nstatic int am335xgpio_blink(int on)\n{\n\tif (is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED]))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on);\n\n\treturn ERROR_OK;\n}\n\nstatic struct bitbang_interface am335xgpio_bitbang = {\n\t.read = am335xgpio_read,\n\t.write = am335xgpio_write,\n\t.swdio_read = am335xgpio_swdio_read,\n\t.swdio_drive = am335xgpio_swdio_drive,\n\t.swd_write = am335xgpio_swd_write,\n\t.blink = am335xgpio_blink\n};\n\nstatic int am335xgpio_khz(int khz, int *jtag_speed)\n{\n\tif (!khz) {\n\t\tLOG_DEBUG(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*jtag_speed = speed_coeff / khz - speed_offset;\n\tif (*jtag_speed < 0)\n\t\t*jtag_speed = 0;\n\treturn ERROR_OK;\n}\n\nstatic int am335xgpio_speed_div(int speed, int *khz)\n{\n\t*khz = speed_coeff / (speed + speed_offset);\n\treturn ERROR_OK;\n}\n\nstatic int am335xgpio_speed(int speed)\n{\n\tjtag_delay = speed;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(am335xgpio_handle_speed_coeffs)\n{\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);\n\t}\n\n\tcommand_print(CMD, \"AM335x GPIO config: speed_coeffs = %d, speed_offset = %d\",\n\t\t\t\t  speed_coeff, speed_offset);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration am335xgpio_subcommand_handlers[] = {\n\t{\n\t\t.name = \"speed_coeffs\",\n\t\t.handler = am335xgpio_handle_speed_coeffs,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"SPEED_COEFF and SPEED_OFFSET for delay calculations.\",\n\t\t.usage = \"[SPEED_COEFF SPEED_OFFSET]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration am335xgpio_command_handlers[] = {\n\t{\n\t\t.name = \"am335xgpio\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform am335xgpio management\",\n\t\t.chain = am335xgpio_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const char * const am335xgpio_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface am335xgpio_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstatic bool am335xgpio_jtag_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TCK]))\n\t\treturn false;\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TMS]))\n\t\treturn false;\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDI]))\n\t\treturn false;\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_TDO]))\n\t\treturn false;\n\treturn true;\n}\n\nstatic bool am335xgpio_swd_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK]))\n\t\treturn false;\n\tif (!is_gpio_config_valid(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]))\n\t\treturn false;\n\treturn true;\n}\n\nstatic void am335xgpio_munmap(void)\n{\n\tfor (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS && am335xgpio_gpio_chip_mmap_addr[i] != MAP_FAILED; ++i)\n\t\tif (munmap((void *)am335xgpio_gpio_chip_mmap_addr[i], sysconf(_SC_PAGE_SIZE)) < 0)\n\t\t\tLOG_ERROR(\"Cannot unmap GPIO memory for chip %d: %s\", i, strerror(errno));\n}\n\nstatic int am335xgpio_init(void)\n{\n\tLOG_INFO(\"AM335x GPIO JTAG/SWD bitbang driver\");\n\n\tbitbang_interface = &am335xgpio_bitbang;\n\tadapter_gpio_config = adapter_gpio_get_config();\n\n\tif (transport_is_jtag() && !am335xgpio_jtag_mode_possible()) {\n\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios for JTAG mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (transport_is_swd() && !am335xgpio_swd_mode_possible()) {\n\t\tLOG_ERROR(\"Require swclk and swdio gpio for SWD mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tdev_mem_fd = open(\"/dev/gpiomem\", O_RDWR | O_SYNC);\n\tif (dev_mem_fd < 0) {\n\t\tLOG_DEBUG(\"Cannot open /dev/gpiomem, fallback to /dev/mem\");\n\t\tdev_mem_fd = open(\"/dev/mem\", O_RDWR | O_SYNC);\n\t}\n\tif (dev_mem_fd < 0) {\n\t\tLOG_ERROR(\"open: %s\", strerror(errno));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tfor (unsigned int i = 0; i < AM335XGPIO_NUM_GPIO_CHIPS; ++i) {\n\t\tam335xgpio_gpio_chip_mmap_addr[i] = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, am335xgpio_gpio_chip_hw_addr[i]);\n\n\t\tif (am335xgpio_gpio_chip_mmap_addr[i] == MAP_FAILED) {\n\t\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\t\tam335xgpio_munmap();\n\t\t\tclose(dev_mem_fd);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t}\n\tclose(dev_mem_fd);\n\n\t/* Configure JTAG/SWD signals. Default directions and initial states are handled\n\t * by adapter.c and \"adapter gpio\" command.\n\t */\n\tif (transport_is_jtag()) {\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TDO);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TDI);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TMS);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TCK);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TRST);\n\t}\n\n\tif (transport_is_swd()) {\n\t\t/* swdio and its buffer should be initialized in the order that prevents\n\t\t * two outputs from being connected together. This will occur if the\n\t\t * swdio GPIO of the AM335x is configured as an output while its\n\t\t * external buffer is configured to send the swdio signal from the\n\t\t * target to the AM335x.\n\t\t */\n\t\tif (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t} else {\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\t\t}\n\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWCLK);\n\t}\n\n\tinitialize_gpio(ADAPTER_GPIO_IDX_SRST);\n\tinitialize_gpio(ADAPTER_GPIO_IDX_LED);\n\n\treturn ERROR_OK;\n}\n\nstatic int am335xgpio_quit(void)\n{\n\tif (transport_is_jtag()) {\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TDO);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TDI);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TMS);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TCK);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TRST);\n\t}\n\n\tif (transport_is_swd()) {\n\t\t/* Restore swdio/swdio_dir to their initial modes, even if that means\n\t\t * connecting two outputs. Begin by making swdio an input so that the\n\t\t * current and final states of swdio and swdio_dir do not have to be\n\t\t * considered to calculate the safe restoration order.\n\t\t */\n\t\tAM335XGPIO_SET_INPUT(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO]);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWCLK);\n\t}\n\n\trestore_gpio(ADAPTER_GPIO_IDX_SRST);\n\trestore_gpio(ADAPTER_GPIO_IDX_LED);\n\n\tam335xgpio_munmap();\n\n\treturn ERROR_OK;\n}\n\nstruct adapter_driver am335xgpio_adapter_driver = {\n\t.name = \"am335xgpio\",\n\t.transports = am335xgpio_transports,\n\t.commands = am335xgpio_command_handlers,\n\n\t.init = am335xgpio_init,\n\t.quit = am335xgpio_quit,\n\t.reset = am335xgpio_reset,\n\t.speed = am335xgpio_speed,\n\t.khz = am335xgpio_khz,\n\t.speed_div = am335xgpio_speed_div,\n\n\t.jtag_ops = &am335xgpio_interface,\n\t.swd_ops = &bitbang_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/amt_jtagaccel.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n\n#if PARPORT_USE_PPDEV == 1\n#include <linux/parport.h>\n#include <linux/ppdev.h>\n#include <sys/ioctl.h>\n#else\t/* not PARPORT_USE_PPDEV */\n#ifndef _WIN32\n#include <sys/io.h>\n#endif\n#endif\n\n#if PARPORT_USE_GIVEIO == 1\n#if IS_CYGWIN == 1\n#include <windows.h>\n#endif\n#endif\n\n/**\n * @file\n * Support the Amontec Chameleon POD with JTAG Accelerator support.\n * This is a parallel port JTAG adapter with a CPLD between the\n * parallel port and the JTAG connection.  VHDL code running in the\n * CPLD significantly accelerates JTAG operations compared to the\n * bitbanging \"Wiggler\" style of most parallel port adapters.\n */\n\n/* configuration */\nstatic uint16_t amt_jtagaccel_port;\n\n/* interface variables\n */\nstatic uint8_t aw_control_rst;\nstatic uint8_t aw_control_fsm = 0x10;\nstatic uint8_t aw_control_baudrate = 0x20;\n\nstatic int rtck_enabled;\n\n#if PARPORT_USE_PPDEV == 1\nstatic int device_handle;\n\nstatic const int addr_mode = IEEE1284_MODE_EPP | IEEE1284_ADDR;\n\n/* FIXME do something sane when these ioctl/read/write calls fail. */\n\n#define AMT_AW(val) \\\n\tdo { \\\n\t\tint __retval; \\\n\t\t\\\n\t\t__retval = ioctl(device_handle, PPSETMODE, &addr_mode);\t\\\n\t\tassert(__retval >= 0); \\\n\t\t__retval = write(device_handle, &val, 1); \\\n\t\tassert(__retval >= 0); \\\n\t} while (0)\n#define AMT_AR(val) \\\n\tdo { \\\n\t\tint __retval; \\\n\t\t\\\n\t\t__retval = ioctl(device_handle, PPSETMODE, &addr_mode);\t\\\n\t\tassert(__retval >= 0); \\\n\t\t__retval = read(device_handle, &val, 1); \\\n\t\tassert(__retval >= 0); \\\n\t} while (0)\n\nstatic const int data_mode = IEEE1284_MODE_EPP | IEEE1284_DATA;\n\n#define AMT_DW(val) \\\n\tdo { \\\n\t\tint __retval; \\\n\t\t\\\n\t\t__retval = ioctl(device_handle, PPSETMODE, &data_mode);\t\\\n\t\tassert(__retval >= 0); \\\n\t\t__retval = write(device_handle, &val, 1); \\\n\t\tassert(__retval >= 0); \\\n\t} while (0)\n#define AMT_DR(val) \\\n\tdo { \\\n\t\tint __retval; \\\n\t\t\\\n\t\t__retval = ioctl(device_handle, PPSETMODE, &data_mode);\t\\\n\t\tassert(__retval >= 0); \\\n\t\t__retval = read(device_handle, &val, 1); \\\n\t\tassert(__retval >= 0); \\\n\t} while (0)\n\n#else\n\n#define AMT_AW(val) do { outb(val, amt_jtagaccel_port + 3); } while (0)\n#define AMT_AR(val) do { val = inb(amt_jtagaccel_port + 3); } while (0)\n#define AMT_DW(val) do { outb(val, amt_jtagaccel_port + 4); } while (0)\n#define AMT_DR(val) do { val = inb(amt_jtagaccel_port + 4); } while (0)\n\n#endif\t/* PARPORT_USE_PPDEV */\n\n/* tap_move[i][j]: tap movement command to go from state i to state j\n * 0: Test-Logic-Reset\n * 1: Run-Test/Idle\n * 2: Shift-DR\n * 3: Pause-DR\n * 4: Shift-IR\n * 5: Pause-IR\n */\nstatic const uint8_t amt_jtagaccel_tap_move[6][6][2] = {\n\t/*\t   RESET         IDLE        DRSHIFT       DRPAUSE       IRSHIFT       IRPAUSE             */\n\t{ {0x1f, 0x00}, {0x0f, 0x00}, {0x05, 0x00}, {0x0a, 0x00}, {0x06, 0x00}, {0x96, 0x00} },\t/* RESET */\n\t{ {0x1f, 0x00}, {0x00, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x0b, 0x00} },\t/* IDLE */\n\t{ {0x1f, 0x00}, {0x0d, 0x00}, {0x00, 0x00}, {0x01, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} },\t/* DRSHIFT  */\n\t{ {0x1f, 0x00}, {0x0c, 0x00}, {0x08, 0x00}, {0x00, 0x00}, {0x8f, 0x09}, {0x8f, 0x01} },\t/* DRPAUSE  */\n\t{ {0x1f, 0x00}, {0x0d, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x00, 0x00}, {0x01, 0x00} },\t/* IRSHIFT  */\n\t{ {0x1f, 0x00}, {0x0c, 0x00}, {0x07, 0x00}, {0x97, 0x00}, {0x08, 0x00}, {0x00, 0x00} },\t/* IRPAUSE  */\n};\n\nstatic void amt_jtagaccel_reset(int trst, int srst)\n{\n\tif (trst == 1)\n\t\taw_control_rst |= 0x4;\n\telse if (trst == 0)\n\t\taw_control_rst &= ~0x4;\n\n\tif (srst == 1)\n\t\taw_control_rst |= 0x1;\n\telse if (srst == 0)\n\t\taw_control_rst &= ~0x1;\n\n\tAMT_AW(aw_control_rst);\n}\n\nstatic int amt_jtagaccel_speed(int speed)\n{\n\taw_control_baudrate &= 0xf0;\n\taw_control_baudrate |= speed & 0x0f;\n\tAMT_AW(aw_control_baudrate);\n\n\treturn ERROR_OK;\n}\n\nstatic void amt_jtagaccel_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void amt_wait_scan_busy(void)\n{\n\tint timeout = 4096;\n\tuint8_t ar_status;\n\n\tAMT_AR(ar_status);\n\twhile (((ar_status) & 0x80) && (timeout-- > 0))\n\t\tAMT_AR(ar_status);\n\n\tif (ar_status & 0x80) {\n\t\tLOG_ERROR(\n\t\t\t\"amt_jtagaccel timed out while waiting for end of scan, rtck was %s, last AR_STATUS: 0x%2.2x\",\n\t\t\t(rtck_enabled) ? \"enabled\" : \"disabled\",\n\t\t\tar_status);\n\t\texit(-1);\n\t}\n}\n\nstatic void amt_jtagaccel_state_move(void)\n{\n\tuint8_t aw_scan_tms_5;\n\tuint8_t tms_scan[2];\n\n\ttap_state_t cur_state = tap_get_state();\n\ttap_state_t end_state = tap_get_end_state();\n\n\ttms_scan[0] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][0];\n\ttms_scan[1] = amt_jtagaccel_tap_move[tap_move_ndx(cur_state)][tap_move_ndx(end_state)][1];\n\n\taw_scan_tms_5 = 0x40 | (tms_scan[0] & 0x1f);\n\tAMT_AW(aw_scan_tms_5);\n\tint jtag_speed = 0;\n\tint retval = adapter_get_speed(&jtag_speed);\n\tassert(retval == ERROR_OK);\n\tif (jtag_speed > 3 || rtck_enabled)\n\t\tamt_wait_scan_busy();\n\n\tif (tms_scan[0] & 0x80) {\n\t\taw_scan_tms_5 = 0x40 | (tms_scan[1] & 0x1f);\n\t\tAMT_AW(aw_scan_tms_5);\n\t\tif (jtag_speed > 3 || rtck_enabled)\n\t\t\tamt_wait_scan_busy();\n\t}\n\n\ttap_set_state(end_state);\n}\n\nstatic void amt_jtagaccel_runtest(int num_cycles)\n{\n\tint i = 0;\n\tuint8_t aw_scan_tms_5;\n\tuint8_t aw_scan_tms_1to4;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tamt_jtagaccel_end_state(TAP_IDLE);\n\t\tamt_jtagaccel_state_move();\n\t}\n\n\twhile (num_cycles - i >= 5) {\n\t\taw_scan_tms_5 = 0x40;\n\t\tAMT_AW(aw_scan_tms_5);\n\t\ti += 5;\n\t}\n\n\tif (num_cycles - i > 0) {\n\t\taw_scan_tms_1to4 = 0x80 | ((num_cycles - i - 1) & 0x3) << 4;\n\t\tAMT_AW(aw_scan_tms_1to4);\n\t}\n\n\tamt_jtagaccel_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tamt_jtagaccel_state_move();\n}\n\nstatic void amt_jtagaccel_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)\n{\n\tint bits_left = scan_size;\n\tint bit_count = 0;\n\ttap_state_t saved_end_state = tap_get_end_state();\n\tuint8_t aw_tdi_option;\n\tuint8_t dw_tdi_scan;\n\tuint8_t dr_tdo;\n\tuint8_t aw_tms_scan;\n\tuint8_t tms_scan[2];\n\tint jtag_speed_var;\n\tint retval = adapter_get_speed(&jtag_speed_var);\n\tassert(retval == ERROR_OK);\n\n\tif (ir_scan)\n\t\tamt_jtagaccel_end_state(TAP_IRSHIFT);\n\telse\n\t\tamt_jtagaccel_end_state(TAP_DRSHIFT);\n\n\t/* Only move if we're not already there */\n\tif (tap_get_state() != tap_get_end_state())\n\t\tamt_jtagaccel_state_move();\n\n\tamt_jtagaccel_end_state(saved_end_state);\n\n\t/* handle unaligned bits at the beginning */\n\tif ((scan_size - 1) % 8) {\n\t\taw_tdi_option = 0x30 | (((scan_size - 1) % 8) - 1);\n\t\tAMT_AW(aw_tdi_option);\n\n\t\tdw_tdi_scan = buf_get_u32(buffer, bit_count, (scan_size - 1) % 8) & 0xff;\n\t\tAMT_DW(dw_tdi_scan);\n\t\tif (jtag_speed_var > 3 || rtck_enabled)\n\t\t\tamt_wait_scan_busy();\n\n\t\tif ((type == SCAN_IN) || (type == SCAN_IO)) {\n\t\t\tAMT_DR(dr_tdo);\n\t\t\tdr_tdo = dr_tdo >> (8 - ((scan_size - 1) % 8));\n\t\t\tbuf_set_u32(buffer, bit_count, (scan_size - 1) % 8, dr_tdo);\n\t\t}\n\n\t\tbit_count += (scan_size - 1) % 8;\n\t\tbits_left -= (scan_size - 1) % 8;\n\t}\n\n\twhile (bits_left - 1 >= 8) {\n\t\tdw_tdi_scan = buf_get_u32(buffer, bit_count, 8) & 0xff;\n\t\tAMT_DW(dw_tdi_scan);\n\t\tif (jtag_speed_var > 3 || rtck_enabled)\n\t\t\tamt_wait_scan_busy();\n\n\t\tif ((type == SCAN_IN) || (type == SCAN_IO)) {\n\t\t\tAMT_DR(dr_tdo);\n\t\t\tbuf_set_u32(buffer, bit_count, 8, dr_tdo);\n\t\t}\n\n\t\tbit_count += 8;\n\t\tbits_left -= 8;\n\t}\n\n\ttms_scan[0] =\n\t\tamt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][0];\n\ttms_scan[1] =\n\t\tamt_jtagaccel_tap_move[tap_move_ndx(tap_get_state())][tap_move_ndx(tap_get_end_state())][1];\n\taw_tms_scan = 0x40 | (tms_scan[0] & 0x1f) | (buf_get_u32(buffer, bit_count, 1) << 5);\n\tAMT_AW(aw_tms_scan);\n\tif (jtag_speed_var > 3 || rtck_enabled)\n\t\tamt_wait_scan_busy();\n\n\tif ((type == SCAN_IN) || (type == SCAN_IO)) {\n\t\tAMT_DR(dr_tdo);\n\t\tdr_tdo = dr_tdo >> 7;\n\t\tbuf_set_u32(buffer, bit_count, 1, dr_tdo);\n\t}\n\n\tif (tms_scan[0] & 0x80) {\n\t\taw_tms_scan = 0x40 | (tms_scan[1] & 0x1f);\n\t\tAMT_AW(aw_tms_scan);\n\t\tif (jtag_speed_var > 3 || rtck_enabled)\n\t\t\tamt_wait_scan_busy();\n\t}\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic int amt_jtagaccel_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\t/* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\tint retval;\n\n\t/* return ERROR_OK, unless a jtag_read_buffer returns a failed check\n\t * that wasn't handled by a caller-provided error handler\n\t */\n\tretval = ERROR_OK;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\",\n\t\t\t\t\t\tcmd->cmd.reset->trst,\n\t\t\t\t\t\tcmd->cmd.reset->srst);\n\t\t\t\tif (cmd->cmd.reset->trst == 1)\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\tamt_jtagaccel_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\tcmd->cmd.runtest->end_state);\n\t\t\t\tamt_jtagaccel_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tamt_jtagaccel_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\t\t\t\tamt_jtagaccel_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tamt_jtagaccel_state_move();\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"scan end in %i\", cmd->cmd.scan->end_state);\n\t\t\t\tamt_jtagaccel_end_state(cmd->cmd.scan->end_state);\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tamt_jtagaccel_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\n\t\t\t\tif (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\treturn retval;\n}\n\n#if PARPORT_USE_GIVEIO == 1\nint amt_jtagaccel_get_giveio_access(void)\n{\n\tHANDLE h;\n\tOSVERSIONINFO version;\n\n\tversion.dwOSVersionInfoSize = sizeof(version);\n\tif (!GetVersionEx(&version)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (version.dwPlatformId != VER_PLATFORM_WIN32_NT)\n\t\treturn 0;\n\n\th = CreateFile(\"\\\\\\\\.\\\\giveio\",\n\t\t\tGENERIC_READ,\n\t\t\t0,\n\t\t\tNULL,\n\t\t\tOPEN_EXISTING,\n\t\t\tFILE_ATTRIBUTE_NORMAL,\n\t\t\tNULL);\n\tif (h == INVALID_HANDLE_VALUE) {\n\t\terrno = ENODEV;\n\t\treturn -1;\n\t}\n\n\tCloseHandle(h);\n\n\treturn 0;\n}\n#endif\n\nstatic int amt_jtagaccel_init(void)\n{\n#if PARPORT_USE_PPDEV == 1\n\tchar buffer[256];\n\tint i = 0;\n\tuint8_t control_port;\n#else\n\tuint8_t status_port;\n#endif\n\tuint8_t ar_status;\n\n#if PARPORT_USE_PPDEV == 1\n\tif (device_handle > 0) {\n\t\tLOG_ERROR(\"device is already opened\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tsnprintf(buffer, 256, \"/dev/parport%d\", amt_jtagaccel_port);\n\tdevice_handle = open(buffer, O_RDWR);\n\n\tif (device_handle < 0) {\n\t\tLOG_ERROR(\n\t\t\t\"cannot open device. check it exists and that user read and write rights are set\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ti = ioctl(device_handle, PPCLAIM);\n\tif (i < 0) {\n\t\tLOG_ERROR(\"cannot claim device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ti = IEEE1284_MODE_EPP;\n\ti = ioctl(device_handle, PPSETMODE, &i);\n\tif (i < 0) {\n\t\tLOG_ERROR(\" cannot set compatible mode to device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tcontrol_port = 0x00;\n\ti = ioctl(device_handle, PPWCONTROL, &control_port);\n\n\tcontrol_port = 0x04;\n\ti = ioctl(device_handle, PPWCONTROL, &control_port);\n\n#else\n\tif (amt_jtagaccel_port == 0) {\n\t\tamt_jtagaccel_port = 0x378;\n\t\tLOG_WARNING(\"No parport port specified, using default '0x378' (LPT1)\");\n\t}\n\n#if PARPORT_USE_GIVEIO == 1\n\tif (amt_jtagaccel_get_giveio_access() != 0) {\n#else\t/* PARPORT_USE_GIVEIO */\n\tif (ioperm(amt_jtagaccel_port, 5, 1) != 0) {\n#endif\t/* PARPORT_USE_GIVEIO */\n\t\tLOG_ERROR(\"missing privileges for direct i/o\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* prepare epp port\n\t * clear timeout */\n\tstatus_port = inb(amt_jtagaccel_port + 1);\n\toutb(status_port | 0x1, amt_jtagaccel_port + 1);\n\n\t/* reset epp port */\n\toutb(0x00, amt_jtagaccel_port + 2);\n\toutb(0x04, amt_jtagaccel_port + 2);\n#endif\n\n\tif (rtck_enabled) {\n\t\t/* set RTCK enable bit */\n\t\taw_control_fsm |= 0x02;\n\t}\n\n\t/* enable JTAG port */\n\taw_control_fsm |= 0x04;\n\tAMT_AW(aw_control_fsm);\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tif (jtag_reset_config & RESET_TRST_OPEN_DRAIN)\n\t\taw_control_rst &= ~0x8;\n\telse\n\t\taw_control_rst |= 0x8;\n\n\tif (jtag_reset_config & RESET_SRST_PUSH_PULL)\n\t\taw_control_rst &= ~0x2;\n\telse\n\t\taw_control_rst |= 0x2;\n\n\tamt_jtagaccel_reset(0, 0);\n\n\t/* read status register */\n\tAMT_AR(ar_status);\n\tLOG_DEBUG(\"AR_STATUS: 0x%2.2x\", ar_status);\n\n\treturn ERROR_OK;\n}\n\nstatic int amt_jtagaccel_quit(void)\n{\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(amt_jtagaccel_handle_parport_port_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\t/* only if the port wasn't overwritten by cmdline */\n\t\tif (amt_jtagaccel_port == 0) {\n\t\t\tuint16_t port;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);\n\t\t\tamt_jtagaccel_port = port;\n\t\t} else {\n\t\t\tLOG_ERROR(\"The parport port was already configured!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"parport port = %u\", amt_jtagaccel_port);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(amt_jtagaccel_handle_rtck_command)\n{\n\tif (CMD_ARGC == 0) {\n\t\tcommand_print(CMD,\n\t\t\t\"amt_jtagaccel RTCK feature %s\",\n\t\t\t(rtck_enabled) ? \"enabled\" : \"disabled\");\n\t\treturn ERROR_OK;\n\t} else {\n\t\tif (strcmp(CMD_ARGV[0], \"enabled\") == 0)\n\t\t\trtck_enabled = 1;\n\t\telse\n\t\t\trtck_enabled = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration amtjtagaccel_command_handlers[] = {\n\t{\n\t\t.name = \"parport_port\",\n\t\t.handler = &amt_jtagaccel_handle_parport_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"configure or display the parallel port to use\",\n\t\t.usage = \"[port_num]\",\n\t},\n\t{\n\t\t/**\n\t\t * @todo Remove this \"rtck\" command; just use the standard\n\t\t * mechanism to enable/disable adaptive clocking.  First\n\t\t * implement the standard mechanism and deprecate \"rtck\";\n\t\t * after a year or so, it'll be safe to remove this.\n\t\t */\n\t\t.name = \"rtck\",\n\t\t.handler = &amt_jtagaccel_handle_rtck_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"configure or display RTCK support\",\n\t\t.usage = \"[enable|disable]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface amt_jtagaccel_interface = {\n\t.execute_queue = amt_jtagaccel_execute_queue,\n};\n\nstruct adapter_driver amt_jtagaccel_adapter_driver = {\n\t.name = \"amt_jtagaccel\",\n\t.transports = jtag_only,\n\t.commands = amtjtagaccel_command_handlers,\n\n\t.init = amt_jtagaccel_init,\n\t.quit = amt_jtagaccel_quit,\n\t.speed = amt_jtagaccel_speed,\n\n\t.jtag_ops = &amt_jtagaccel_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/arm-jtag-ew.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Dimitar Dimitrov <dinuxbg@gmail.com>            *\n *   based on Dominic Rath's and Benedikt Sauter's usbprog.c               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"helper/system.h\"\n#include \"libusb_helper.h\"\n\n#define USB_VID\t\t\t\t\t\t0x15ba\n#define USB_PID\t\t\t\t\t\t0x001e\n\n#define ARMJTAGEW_EPT_BULK_OUT\t\t0x01u\n#define ARMJTAGEW_EPT_BULK_IN\t\t0x82u\n\n#define ARMJTAGEW_USB_TIMEOUT\t\t2000\n\n#define ARMJTAGEW_IN_BUFFER_SIZE\t(4*1024)\n#define ARMJTAGEW_OUT_BUFFER_SIZE\t(4*1024)\n\n/* USB command request codes. */\n#define CMD_GET_VERSION\t\t\t\t0x00\n#define CMD_SELECT_DPIMPL\t\t\t0x10\n#define CMD_SET_TCK_FREQUENCY\t\t0x11\n#define CMD_GET_TCK_FREQUENCY\t\t0x12\n#define CMD_MEASURE_MAX_TCK_FREQ\t0x15\n#define CMD_MEASURE_RTCK_RESPONSE\t0x16\n#define CMD_TAP_SHIFT\t\t\t\t0x17\n#define CMD_SET_TAPHW_STATE\t\t\t0x20\n#define CMD_GET_TAPHW_STATE\t\t\t0x21\n#define CMD_TGPWR_SETUP\t\t\t\t0x22\n\n/* Global USB buffers */\nstatic uint8_t usb_in_buffer[ARMJTAGEW_IN_BUFFER_SIZE];\nstatic uint8_t usb_out_buffer[ARMJTAGEW_OUT_BUFFER_SIZE];\n\n/* Queue command functions */\nstatic void armjtagew_end_state(tap_state_t state);\nstatic void armjtagew_state_move(void);\nstatic void armjtagew_path_move(int num_states, tap_state_t *path);\nstatic void armjtagew_runtest(int num_cycles);\nstatic void armjtagew_scan(bool ir_scan,\n\t\tenum scan_type type,\n\t\tuint8_t *buffer,\n\t\tint scan_size,\n\t\tstruct scan_command *command);\nstatic void armjtagew_reset(int trst, int srst);\n/* static void armjtagew_simple_command(uint8_t command); */\nstatic int armjtagew_get_status(void);\n\n/* tap buffer functions */\nstatic void armjtagew_tap_init(void);\nstatic int armjtagew_tap_execute(void);\nstatic void armjtagew_tap_ensure_space(int scans, int bits);\nstatic void armjtagew_tap_append_step(int tms, int tdi);\nstatic void armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);\n\n/* ARM-JTAG-EW lowlevel functions */\nstruct armjtagew {\n\tstruct libusb_device_handle *usb_handle;\n};\n\nstatic struct armjtagew *armjtagew_usb_open(void);\nstatic void armjtagew_usb_close(struct armjtagew *armjtagew);\nstatic int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length);\nstatic int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length);\nstatic int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length);\n\n/* helper functions */\nstatic int armjtagew_get_version_info(void);\n\n#ifdef _DEBUG_USB_COMMS_\nstatic void armjtagew_debug_buffer(uint8_t *buffer, int length);\n#endif\n\nstatic struct armjtagew *armjtagew_handle;\n\n/**************************************************************************\n * External interface implementation */\n\nstatic int armjtagew_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\tcmd->cmd.runtest->end_state);\n\n\t\t\t\tarmjtagew_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tarmjtagew_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\n\t\t\t\tarmjtagew_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tarmjtagew_state_move();\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\n\t\t\t\tarmjtagew_path_move(cmd->cmd.pathmove->num_states,\n\t\t\t\t\t\tcmd->cmd.pathmove->path);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"scan end in %i\", cmd->cmd.scan->end_state);\n\n\t\t\t\tarmjtagew_end_state(cmd->cmd.scan->end_state);\n\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\tLOG_DEBUG_IO(\"scan input, length = %d\", scan_size);\n\n#ifdef _DEBUG_USB_COMMS_\n\t\t\t\tarmjtagew_debug_buffer(buffer, (scan_size + 7) / 8);\n#endif\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tarmjtagew_scan(cmd->cmd.scan->ir_scan,\n\t\t\t\t\t\ttype, buffer,\n\t\t\t\t\t\tscan_size, cmd->cmd.scan);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\",\n\t\t\t\t\t\tcmd->cmd.reset->trst,\n\t\t\t\t\t\tcmd->cmd.reset->srst);\n\n\t\t\t\tarmjtagew_tap_execute();\n\n\t\t\t\tif (cmd->cmd.reset->trst == 1)\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\tarmjtagew_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tarmjtagew_tap_execute();\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\treturn armjtagew_tap_execute();\n}\n\n/* Sets speed in kHz. */\nstatic int armjtagew_speed(int speed)\n{\n\tint result;\n\tint speed_real;\n\n\n\tusb_out_buffer[0] = CMD_SET_TCK_FREQUENCY;\n\tbuf_set_u32(usb_out_buffer + 1, 0, 32, speed*1000);\n\n\tresult = armjtagew_usb_message(armjtagew_handle, 5, 4);\n\n\tif (result < 0) {\n\t\tLOG_ERROR(\"ARM-JTAG-EW setting speed failed (%d)\", result);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tusb_out_buffer[0] = CMD_GET_TCK_FREQUENCY;\n\tresult = armjtagew_usb_message(armjtagew_handle, 1, 4);\n\tspeed_real = (int)buf_get_u32(usb_in_buffer, 0, 32) / 1000;\n\tif (result < 0) {\n\t\tLOG_ERROR(\"ARM-JTAG-EW getting speed failed (%d)\", result);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t} else\n\t\tLOG_INFO(\"Requested speed %dkHz, emulator reported %dkHz.\", speed, speed_real);\n\n\treturn ERROR_OK;\n}\n\nstatic int armjtagew_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\n\treturn ERROR_OK;\n}\n\nstatic int armjtagew_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\n\treturn ERROR_OK;\n}\n\nstatic int armjtagew_init(void)\n{\n\tint check_cnt;\n\n\tarmjtagew_handle = armjtagew_usb_open();\n\n\tif (!armjtagew_handle) {\n\t\tLOG_ERROR(\n\t\t\t\"Cannot find ARM-JTAG-EW Interface! Please check connection and permissions.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tcheck_cnt = 0;\n\twhile (check_cnt < 3) {\n\t\tif (armjtagew_get_version_info() == ERROR_OK) {\n\t\t\t/* attempt to get status */\n\t\t\tarmjtagew_get_status();\n\t\t\tbreak;\n\t\t}\n\n\t\tcheck_cnt++;\n\t}\n\n\tif (check_cnt == 3)\n\t\tLOG_INFO(\"ARM-JTAG-EW initial read failed, don't worry\");\n\n\t/* Initial JTAG speed (for reset and initialization): 32 kHz */\n\tarmjtagew_speed(32);\n\n\tLOG_INFO(\"ARM-JTAG-EW JTAG Interface ready\");\n\n\tarmjtagew_reset(0, 0);\n\tarmjtagew_tap_init();\n\n\treturn ERROR_OK;\n}\n\nstatic int armjtagew_quit(void)\n{\n\tarmjtagew_usb_close(armjtagew_handle);\n\treturn ERROR_OK;\n}\n\n/**************************************************************************\n * Queue command implementations */\n\nstatic void armjtagew_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\n/* Goes to the end state. */\nstatic void armjtagew_state_move(void)\n{\n\tint i;\n\tint tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tfor (i = 0; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\tarmjtagew_tap_append_step(tms, 0);\n\t}\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void armjtagew_path_move(int num_states, tap_state_t *path)\n{\n\tint i;\n\n\tfor (i = 0; i < num_states; i++) {\n\t\t/*\n\t\t * TODO: The ARM-JTAG-EW hardware delays TDI with 3 TCK cycles when in RTCK mode.\n\t\t * Either handle that here, or update the documentation with examples\n\t\t * how to fix that in the configuration files.\n\t\t */\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false))\n\t\t\tarmjtagew_tap_append_step(0, 0);\n\t\telse if (path[i] == tap_state_transition(tap_get_state(), true))\n\t\t\tarmjtagew_tap_append_step(1, 0);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()), tap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void armjtagew_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tarmjtagew_end_state(TAP_IDLE);\n\t\tarmjtagew_state_move();\n\t}\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++)\n\t\tarmjtagew_tap_append_step(0, 0);\n\n\t/* finish in end_state */\n\tarmjtagew_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tarmjtagew_state_move();\n}\n\nstatic void armjtagew_scan(bool ir_scan,\n\tenum scan_type type,\n\tuint8_t *buffer,\n\tint scan_size,\n\tstruct scan_command *command)\n{\n\ttap_state_t saved_end_state;\n\n\tarmjtagew_tap_ensure_space(1, scan_size + 8);\n\n\tsaved_end_state = tap_get_end_state();\n\n\t/* Move to appropriate scan state */\n\tarmjtagew_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\n\t/* Only move if we're not already there */\n\tif (tap_get_state() != tap_get_end_state())\n\t\tarmjtagew_state_move();\n\n\tarmjtagew_end_state(saved_end_state);\n\n\t/* Scan */\n\tarmjtagew_tap_append_scan(scan_size, buffer, command);\n\n\t/* We are in Exit1, go to Pause */\n\tarmjtagew_tap_append_step(0, 0);\n\n\ttap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tarmjtagew_state_move();\n}\n\nstatic void armjtagew_reset(int trst, int srst)\n{\n\tconst uint8_t trst_mask = (1u << 5);\n\tconst uint8_t srst_mask = (1u << 6);\n\tuint8_t val = 0;\n\tuint8_t outp_en = 0;\n\tuint8_t change_mask = 0;\n\tint result;\n\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (srst == 0) {\n\t\tval |= srst_mask;\n\t\toutp_en &= ~srst_mask;\t\t/* tristate */\n\t\tchange_mask |= srst_mask;\n\t} else if (srst == 1) {\n\t\tval &= ~srst_mask;\n\t\toutp_en |= srst_mask;\n\t\tchange_mask |= srst_mask;\n\t}\n\n\tif (trst == 0) {\n\t\tval |= trst_mask;\n\t\toutp_en &= ~trst_mask;\t\t/* tristate */\n\t\tchange_mask |= trst_mask;\n\t} else if (trst == 1) {\n\t\tval &= ~trst_mask;\n\t\toutp_en |= trst_mask;\n\t\tchange_mask |= trst_mask;\n\t}\n\n\tusb_out_buffer[0] = CMD_SET_TAPHW_STATE;\n\tusb_out_buffer[1] = val;\n\tusb_out_buffer[2] = outp_en;\n\tusb_out_buffer[3] = change_mask;\n\tresult = armjtagew_usb_write(armjtagew_handle, 4);\n\tif (result != 4)\n\t\tLOG_ERROR(\"ARM-JTAG-EW TRST/SRST pin set failed failed (%d)\", result);\n}\n\nstatic int armjtagew_get_status(void)\n{\n\tint result;\n\n\tusb_out_buffer[0] = CMD_GET_TAPHW_STATE;\n\tresult = armjtagew_usb_message(armjtagew_handle, 1, 12);\n\n\tif (result == 0) {\n\t\tunsigned int u_tg = buf_get_u32(usb_in_buffer, 0, 16);\n\t\tLOG_INFO(\n\t\t\t\"U_tg = %d mV, U_aux = %d mV, U_tgpwr = %d mV, I_tgpwr = %d mA, D1 = %d, Target power %s %s\",\n\t\t\t(int)(buf_get_u32(usb_in_buffer + 0, 0, 16)),\n\t\t\t(int)(buf_get_u32(usb_in_buffer + 2, 0, 16)),\n\t\t\t(int)(buf_get_u32(usb_in_buffer + 4, 0, 16)),\n\t\t\t(int)(buf_get_u32(usb_in_buffer + 6, 0, 16)),\n\t\t\tusb_in_buffer[9],\n\t\t\tusb_in_buffer[11] ? \"OVERCURRENT\" : \"OK\",\n\t\t\tusb_in_buffer[10] ? \"enabled\" : \"disabled\");\n\n\t\tif (u_tg < 1500)\n\t\t\tLOG_ERROR(\"Vref too low. Check Target Power\");\n\t} else\n\t\tLOG_ERROR(\"ARM-JTAG-EW command CMD_GET_TAPHW_STATE failed (%d)\", result);\n\n\treturn ERROR_OK;\n}\n\nstatic int armjtagew_get_version_info(void)\n{\n\tint result;\n\tchar sn[16];\n\tchar auxinfo[257];\n\n\t/* query hardware version */\n\tusb_out_buffer[0] = CMD_GET_VERSION;\n\tresult = armjtagew_usb_message(armjtagew_handle, 1, 4 + 15 + 256);\n\n\tif (result != 0) {\n\t\tLOG_ERROR(\"ARM-JTAG-EW command CMD_GET_VERSION failed (%d)\", result);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tmemcpy(sn, usb_in_buffer + 4, 15);\n\tsn[15] = '\\0';\n\tmemcpy(auxinfo, usb_in_buffer + 4+15, 256);\n\tauxinfo[256] = '\\0';\n\n\tLOG_INFO(\n\t\t\"ARM-JTAG-EW firmware version %d.%d, hardware revision %c, SN=%s, Additional info: %s\",\n\t\tusb_in_buffer[1],\n\t\tusb_in_buffer[0],\n\t\tisgraph(usb_in_buffer[2]) ? usb_in_buffer[2] : 'X',\n\t\tsn,\n\t\tauxinfo);\n\n\tif (1 != usb_in_buffer[1] || 6 != usb_in_buffer[0])\n\t\tLOG_WARNING(\n\t\t\t\"ARM-JTAG-EW firmware version %d.%d is untested with this version of OpenOCD. You might experience unexpected behavior.\",\n\t\t\tusb_in_buffer[1],\n\t\t\tusb_in_buffer[0]);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(armjtagew_handle_armjtagew_info_command)\n{\n\tif (armjtagew_get_version_info() == ERROR_OK) {\n\t\t/* attempt to get status */\n\t\tarmjtagew_get_status();\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration armjtagew_command_handlers[] = {\n\t{\n\t\t.name = \"armjtagew_info\",\n\t\t.handler = &armjtagew_handle_armjtagew_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"query armjtagew info\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface armjtagew_interface = {\n\t.execute_queue = armjtagew_execute_queue,\n};\n\nstruct adapter_driver armjtagew_adapter_driver = {\n\t.name = \"arm-jtag-ew\",\n\t.transports = jtag_only,\n\t.commands = armjtagew_command_handlers,\n\n\t.init = armjtagew_init,\n\t.quit = armjtagew_quit,\n\t.speed = armjtagew_speed,\n\t.khz = armjtagew_khz,\n\t.speed_div = armjtagew_speed_div,\n\n\t.jtag_ops = &armjtagew_interface,\n};\n\n/**************************************************************************\n * ARM-JTAG-EW tap functions */\n\n/* 2048 is the max value we can use here */\n#define ARMJTAGEW_TAP_BUFFER_SIZE 2048\n\nstatic int tap_length;\nstatic uint8_t tms_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];\nstatic uint8_t tdi_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];\nstatic uint8_t tdo_buffer[ARMJTAGEW_TAP_BUFFER_SIZE];\n\nstruct pending_scan_result {\n\tint first;\t/* First bit position in tdo_buffer to read */\n\tint length;\t/* Number of bits to read */\n\tstruct scan_command *command;\t/* Corresponding scan command */\n\tuint8_t *buffer;\n};\n\n#define MAX_PENDING_SCAN_RESULTS 256\n\nstatic int pending_scan_results_length;\nstatic struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];\n\nstatic int last_tms;\n\nstatic void armjtagew_tap_init(void)\n{\n\ttap_length = 0;\n\tpending_scan_results_length = 0;\n}\n\nstatic void armjtagew_tap_ensure_space(int scans, int bits)\n{\n\tint available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;\n\tint available_bits = ARMJTAGEW_TAP_BUFFER_SIZE * 8 - tap_length;\n\n\tif (scans > available_scans || bits > available_bits)\n\t\tarmjtagew_tap_execute();\n}\n\nstatic void armjtagew_tap_append_step(int tms, int tdi)\n{\n\tlast_tms = tms;\n\tint index_local = tap_length / 8;\n\n\tif (index_local < ARMJTAGEW_TAP_BUFFER_SIZE) {\n\t\tint bit_index = tap_length % 8;\n\t\tuint8_t bit = 1 << bit_index;\n\n\t\tif (tms)\n\t\t\ttms_buffer[index_local] |= bit;\n\t\telse\n\t\t\ttms_buffer[index_local] &= ~bit;\n\n\t\tif (tdi)\n\t\t\ttdi_buffer[index_local] |= bit;\n\t\telse\n\t\t\ttdi_buffer[index_local] &= ~bit;\n\n\t\ttap_length++;\n\t} else\n\t\tLOG_ERROR(\"armjtagew_tap_append_step, overflow\");\n}\n\nvoid armjtagew_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)\n{\n\tstruct pending_scan_result *pending_scan_result =\n\t\t&pending_scan_results_buffer[pending_scan_results_length];\n\tint i;\n\n\tpending_scan_result->first = tap_length;\n\tpending_scan_result->length = length;\n\tpending_scan_result->command = command;\n\tpending_scan_result->buffer = buffer;\n\n\tfor (i = 0; i < length; i++)\n\t\tarmjtagew_tap_append_step((i < length-1 ? 0 : 1), (buffer[i/8] >> (i%8)) & 1);\n\tpending_scan_results_length++;\n}\n\n/* Pad and send a tap sequence to the device, and receive the answer.\n * For the purpose of padding we assume that we are in idle or pause state. */\nstatic int armjtagew_tap_execute(void)\n{\n\tint byte_length;\n\tint tms_offset;\n\tint tdi_offset;\n\tint i;\n\tint result;\n\n\tif (tap_length > 0) {\n\t\t/* Pad last byte so that tap_length is divisible by 8 */\n\t\twhile (tap_length % 8 != 0) {\n\t\t\t/* More of the last TMS value keeps us in the same state,\n\t\t\t * analogous to free-running JTAG interfaces. */\n\t\t\tarmjtagew_tap_append_step(last_tms, 0);\n\t\t}\n\n\t\tbyte_length = tap_length / 8;\n\n\t\tusb_out_buffer[0] = CMD_TAP_SHIFT;\n\t\tbuf_set_u32(usb_out_buffer + 1, 0, 16, byte_length);\n\n\t\ttms_offset = 3;\n\t\tfor (i = 0; i < byte_length; i++)\n\t\t\tusb_out_buffer[tms_offset + i] = flip_u32(tms_buffer[i], 8);\n\n\t\ttdi_offset = tms_offset + byte_length;\n\t\tfor (i = 0; i < byte_length; i++)\n\t\t\tusb_out_buffer[tdi_offset + i] = flip_u32(tdi_buffer[i], 8);\n\n\t\tresult = armjtagew_usb_message(armjtagew_handle,\n\t\t\t\t3 + 2 * byte_length,\n\t\t\t\tbyte_length + 4);\n\n\t\tif (result == 0) {\n\t\t\tint stat_local;\n\n\t\t\tstat_local = (int)buf_get_u32(usb_in_buffer + byte_length, 0, 32);\n\t\t\tif (stat_local) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"armjtagew_tap_execute, emulator returned error code %d for a CMD_TAP_SHIFT command\",\n\t\t\t\t\tstat_local);\n\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < byte_length; i++)\n\t\t\t\ttdo_buffer[i] = flip_u32(usb_in_buffer[i], 8);\n\n\t\t\tfor (i = 0; i < pending_scan_results_length; i++) {\n\t\t\t\tstruct pending_scan_result *pending_scan_result =\n\t\t\t\t\t&pending_scan_results_buffer[i];\n\t\t\t\tuint8_t *buffer = pending_scan_result->buffer;\n\t\t\t\tint length = pending_scan_result->length;\n\t\t\t\tint first = pending_scan_result->first;\n\t\t\t\tstruct scan_command *command = pending_scan_result->command;\n\n\t\t\t\t/* Copy to buffer */\n\t\t\t\tbuf_set_buf(tdo_buffer, first, buffer, 0, length);\n\n\t\t\t\tLOG_DEBUG_IO(\"pending scan result, length = %d\", length);\n\n#ifdef _DEBUG_USB_COMMS_\n\t\t\t\tarmjtagew_debug_buffer(buffer, byte_length);\n#endif\n\n\t\t\t\tif (jtag_read_buffer(buffer, command) != ERROR_OK) {\n\t\t\t\t\tarmjtagew_tap_init();\n\t\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\t}\n\n\t\t\t\tfree(pending_scan_result->buffer);\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"armjtagew_tap_execute, wrong result %d, expected %d\",\n\t\t\t\tresult,\n\t\t\t\tbyte_length);\n\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t}\n\n\t\tarmjtagew_tap_init();\n\t}\n\n\treturn ERROR_OK;\n}\n\n/****************************************************************************\n * JLink USB low-level functions */\n\nstatic struct armjtagew *armjtagew_usb_open(void)\n{\n\tconst uint16_t vids[] = { USB_VID, 0 };\n\tconst uint16_t pids[] = { USB_PID, 0 };\n\tstruct libusb_device_handle *dev;\n\n\tif (jtag_libusb_open(vids, pids, &dev, NULL) != ERROR_OK)\n\t\treturn NULL;\n\n\tstruct armjtagew *result = malloc(sizeof(struct armjtagew));\n\tresult->usb_handle = dev;\n\n#if 0\n\t/* libusb_set_configuration required under win32 */\n\tstruct libusb_config_descriptor *config;\n\tstruct libusb_device *usb_dev = libusb_get_device(dev);\n\tlibusb_get_config_descriptor(usb_dev, 0, &config);\n\tlibusb_set_configuration(dev, config->bConfigurationValue);\n#endif\n\tlibusb_claim_interface(dev, 0);\n#if 0\n\t/*\n\t * This makes problems under Mac OS X. And is not needed\n\t * under Windows. Hopefully this will not break a linux build\n\t */\n\tlibusb_set_interface_alt_setting(dev, 0, 0);\n#endif\n\treturn result;\n}\n\nstatic void armjtagew_usb_close(struct armjtagew *armjtagew)\n{\n\tlibusb_close(armjtagew->usb_handle);\n\tfree(armjtagew);\n}\n\n/* Send a message and receive the reply. */\nstatic int armjtagew_usb_message(struct armjtagew *armjtagew, int out_length, int in_length)\n{\n\tint result;\n\n\tresult = armjtagew_usb_write(armjtagew, out_length);\n\tif (result == out_length) {\n\t\tresult = armjtagew_usb_read(armjtagew, in_length);\n\t\tif (result != in_length) {\n\t\t\tLOG_ERROR(\"jtag_libusb_bulk_read failed (requested=%d, result=%d)\",\n\t\t\t\tin_length,\n\t\t\t\tresult);\n\t\t\treturn -1;\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"jtag_libusb_bulk_write failed (requested=%d, result=%d)\", out_length, result);\n\t\treturn -1;\n\t}\n\treturn 0;\n}\n\n/* Write data from out_buffer to USB. */\nstatic int armjtagew_usb_write(struct armjtagew *armjtagew, int out_length)\n{\n\tint result;\n\tint transferred;\n\n\tif (out_length > ARMJTAGEW_OUT_BUFFER_SIZE) {\n\t\tLOG_ERROR(\"armjtagew_write illegal out_length=%d (max=%d)\",\n\t\t\tout_length,\n\t\t\tARMJTAGEW_OUT_BUFFER_SIZE);\n\t\treturn -1;\n\t}\n\n\tresult = jtag_libusb_bulk_write(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_OUT,\n\t\t\t(char *)usb_out_buffer, out_length, ARMJTAGEW_USB_TIMEOUT, &transferred);\n\n\tLOG_DEBUG_IO(\"armjtagew_usb_write, out_length = %d, result = %d\", out_length, result);\n\n#ifdef _DEBUG_USB_COMMS_\n\tarmjtagew_debug_buffer(usb_out_buffer, out_length);\n#endif\n\tif (result != ERROR_OK)\n\t\treturn -1;\n\treturn transferred;\n}\n\n/* Read data from USB into in_buffer. */\nstatic int armjtagew_usb_read(struct armjtagew *armjtagew, int exp_in_length)\n{\n\tint transferred;\n\tint result = jtag_libusb_bulk_read(armjtagew->usb_handle, ARMJTAGEW_EPT_BULK_IN,\n\t\t\t(char *)usb_in_buffer, exp_in_length, ARMJTAGEW_USB_TIMEOUT, &transferred);\n\n\tLOG_DEBUG_IO(\"armjtagew_usb_read, result = %d\", result);\n\n#ifdef _DEBUG_USB_COMMS_\n\tarmjtagew_debug_buffer(usb_in_buffer, result);\n#endif\n\tif (result != ERROR_OK)\n\t\treturn -1;\n\treturn transferred;\n}\n\n#ifdef _DEBUG_USB_COMMS_\n#define BYTES_PER_LINE  16\n\nstatic void armjtagew_debug_buffer(uint8_t *buffer, int length)\n{\n\tchar line[8 + 3 * BYTES_PER_LINE + 1];\n\n\tfor (int i = 0; i < length; i += BYTES_PER_LINE) {\n\t\tint n = snprintf(line, 9, \"%04x\", i);\n\t\tfor (int j = i; j < i + BYTES_PER_LINE && j < length; j++)\n\t\t\tn += snprintf(line + n, 4, \" %02x\", buffer[j]);\n\t\tLOG_DEBUG(\"%s\", line);\n\n\t\t/* Prevent GDB timeout (writing to log might take some time) */\n\t\tkeep_alive();\n\t}\n}\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/at91rm9200.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Anders Larsen                                   *\n *   al@alarsen.net                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include \"bitbang.h\"\n\n#include <sys/mman.h>\n\n/* AT91RM9200 */\n#define AT91C_BASE_SYS\t(0xfffff000)\n\n/* GPIO assignment */\n#define PIOA\t(0 << 7)\n#define PIOB\t(1 << 7)\n#define PIOC\t(2 << 7)\n#define PIOD\t(3 << 7)\n\n#define PIO_PER\t\t(0)\t\t/* PIO enable */\n#define PIO_OER\t\t(4)\t\t/* output enable */\n#define PIO_ODR\t\t(5)\t\t/* output disable */\n#define PIO_SODR\t(12)\t\t/* set output data */\n#define PIO_CODR\t(13)\t\t/* clear output data */\n#define PIO_PDSR\t(15)\t\t/* pin data status */\n#define PIO_PPUER\t(25)\t\t/* pull-up enable */\n\n#define NC\t(0)\t\t\t/* not connected */\n#define P0\t(1 << 0)\n#define P1\t(1 << 1)\n#define P2\t(1 << 2)\n#define P3\t(1 << 3)\n#define P4\t(1 << 4)\n#define P5\t(1 << 5)\n#define P6\t(1 << 6)\n#define P7\t(1 << 7)\n#define P8\t(1 << 8)\n#define P9\t(1 << 9)\n#define P10\t(1 << 10)\n#define P11\t(1 << 11)\n#define P12\t(1 << 12)\n#define P13\t(1 << 13)\n#define P14\t(1 << 14)\n#define P15\t(1 << 15)\n#define P16\t(1 << 16)\n#define P17\t(1 << 17)\n#define P18\t(1 << 18)\n#define P19\t(1 << 19)\n#define P20\t(1 << 20)\n#define P21\t(1 << 21)\n#define P22\t(1 << 22)\n#define P23\t(1 << 23)\n#define P24\t(1 << 24)\n#define P25\t(1 << 25)\n#define P26\t(1 << 26)\n#define P27\t(1 << 27)\n#define P28\t(1 << 28)\n#define P29\t(1 << 29)\n#define P30\t(1 << 30)\n#define P31\t(1 << 31)\n\nstruct device_t {\n\tconst char *name;\n\tint TDO_PIO;\t/* PIO holding TDO */\n\tuint32_t TDO_MASK;\t/* TDO bitmask */\n\tint TRST_PIO;\t/* PIO holding TRST */\n\tuint32_t TRST_MASK;\t/* TRST bitmask */\n\tint TMS_PIO;\t/* PIO holding TMS */\n\tuint32_t TMS_MASK;\t/* TMS bitmask */\n\tint TCK_PIO;\t/* PIO holding TCK */\n\tuint32_t TCK_MASK;\t/* TCK bitmask */\n\tint TDI_PIO;\t/* PIO holding TDI */\n\tuint32_t TDI_MASK;\t/* TDI bitmask */\n\tint SRST_PIO;\t/* PIO holding SRST */\n\tuint32_t SRST_MASK;\t/* SRST bitmask */\n};\n\nstatic const struct device_t devices[] = {\n\t{ \"rea_ecr\", PIOD, P27, PIOA, NC, PIOD, P23, PIOD, P24, PIOD, P26, PIOC, P5 },\n\t{ .name = NULL },\n};\n\n/* configuration */\nstatic char *at91rm9200_device;\n\n/* interface variables\n */\nstatic const struct device_t *device;\nstatic int dev_mem_fd;\nstatic void *sys_controller;\nstatic uint32_t *pio_base;\n\n/* low level command set\n */\nstatic bb_value_t at91rm9200_read(void);\nstatic int at91rm9200_write(int tck, int tms, int tdi);\n\nstatic int at91rm9200_init(void);\nstatic int at91rm9200_quit(void);\n\nstatic struct bitbang_interface at91rm9200_bitbang = {\n\t.read = at91rm9200_read,\n\t.write = at91rm9200_write,\n\t.blink = NULL,\n};\n\nstatic bb_value_t at91rm9200_read(void)\n{\n\treturn (pio_base[device->TDO_PIO + PIO_PDSR] & device->TDO_MASK) ? BB_HIGH : BB_LOW;\n}\n\nstatic int at91rm9200_write(int tck, int tms, int tdi)\n{\n\tif (tck)\n\t\tpio_base[device->TCK_PIO + PIO_SODR] = device->TCK_MASK;\n\telse\n\t\tpio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;\n\n\tif (tms)\n\t\tpio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;\n\telse\n\t\tpio_base[device->TMS_PIO + PIO_CODR] = device->TMS_MASK;\n\n\tif (tdi)\n\t\tpio_base[device->TDI_PIO + PIO_SODR] = device->TDI_MASK;\n\telse\n\t\tpio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int at91rm9200_reset(int trst, int srst)\n{\n\tif (trst == 0)\n\t\tpio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;\n\telse if (trst == 1)\n\t\tpio_base[device->TRST_PIO + PIO_CODR] = device->TRST_MASK;\n\n\tif (srst == 0)\n\t\tpio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;\n\telse if (srst == 1)\n\t\tpio_base[device->SRST_PIO + PIO_CODR] = device->SRST_MASK;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(at91rm9200_handle_device_command)\n{\n\tif (CMD_ARGC == 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* only if the device name wasn't overwritten by cmdline */\n\tif (!at91rm9200_device) {\n\t\tat91rm9200_device = malloc(strlen(CMD_ARGV[0]) + sizeof(char));\n\t\tif (!at91rm9200_device) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tstrcpy(at91rm9200_device, CMD_ARGV[0]);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration at91rm9200_command_handlers[] = {\n\t{\n\t\t.name = \"at91rm9200_device\",\n\t\t.handler = &at91rm9200_handle_device_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set at91rm9200 device [default \\\"rea_ecr\\\"]\",\n\t\t.usage = \"<device>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface at91rm9200_interface = {\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver at91rm9200_adapter_driver = {\n\t.name = \"at91rm9200\",\n\t.transports = jtag_only,\n\t.commands = at91rm9200_command_handlers,\n\n\t.init = at91rm9200_init,\n\t.quit = at91rm9200_quit,\n\t.reset = at91rm9200_reset,\n\n\t.jtag_ops = &at91rm9200_interface,\n};\n\nstatic int at91rm9200_init(void)\n{\n\tconst struct device_t *cur_device;\n\n\tcur_device = devices;\n\n\tif (!at91rm9200_device || at91rm9200_device[0] == 0) {\n\t\tat91rm9200_device = \"rea_ecr\";\n\t\tLOG_WARNING(\"No at91rm9200 device specified, using default 'rea_ecr'\");\n\t}\n\n\twhile (cur_device->name) {\n\t\tif (strcmp(cur_device->name, at91rm9200_device) == 0) {\n\t\t\tdevice = cur_device;\n\t\t\tbreak;\n\t\t}\n\t\tcur_device++;\n\t}\n\n\tif (!device) {\n\t\tLOG_ERROR(\"No matching device found for %s\", at91rm9200_device);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tbitbang_interface = &at91rm9200_bitbang;\n\n\tdev_mem_fd = open(\"/dev/mem\", O_RDWR | O_SYNC);\n\tif (dev_mem_fd < 0) {\n\t\tLOG_ERROR(\"open: %s\", strerror(errno));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tsys_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, AT91C_BASE_SYS);\n\tif (sys_controller == MAP_FAILED) {\n\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\tclose(dev_mem_fd);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tpio_base = (uint32_t *)sys_controller + 0x100;\n\n\t/*\n\t * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST\n\t * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.\n\t */\n\tpio_base[device->TDI_PIO + PIO_CODR] = device->TDI_MASK;\n\tpio_base[device->TDI_PIO + PIO_OER] = device->TDI_MASK;\n\tpio_base[device->TDI_PIO + PIO_PER] = device->TDI_MASK;\n\tpio_base[device->TCK_PIO + PIO_CODR] = device->TCK_MASK;\n\tpio_base[device->TCK_PIO + PIO_OER] = device->TCK_MASK;\n\tpio_base[device->TCK_PIO + PIO_PER] = device->TCK_MASK;\n\tpio_base[device->TMS_PIO + PIO_SODR] = device->TMS_MASK;\n\tpio_base[device->TMS_PIO + PIO_OER] = device->TMS_MASK;\n\tpio_base[device->TMS_PIO + PIO_PER] = device->TMS_MASK;\n\tpio_base[device->TRST_PIO + PIO_SODR] = device->TRST_MASK;\n\tpio_base[device->TRST_PIO + PIO_OER] = device->TRST_MASK;\n\tpio_base[device->TRST_PIO + PIO_PER] = device->TRST_MASK;\n\tpio_base[device->SRST_PIO + PIO_SODR] = device->SRST_MASK;\n\tpio_base[device->SRST_PIO + PIO_OER] = device->SRST_MASK;\n\tpio_base[device->SRST_PIO + PIO_PER] = device->SRST_MASK;\n\tpio_base[device->TDO_PIO + PIO_ODR] = device->TDO_MASK;\n\tpio_base[device->TDO_PIO + PIO_PPUER] = device->TDO_MASK;\n\tpio_base[device->TDO_PIO + PIO_PER] = device->TDO_MASK;\n\n\treturn ERROR_OK;\n}\n\nstatic int at91rm9200_quit(void)\n{\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/bcm2835gpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Paul Fertser, fercerpav@gmail.com               *\n *                                                                         *\n *   Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *\n *   Based on at91rm9200.c (c) Anders Larsen                               *\n *   and RPi GPIO examples by Gert van Loo & Dom                           *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include \"bitbang.h\"\n\n#include <sys/mman.h>\n\nstatic char *bcm2835_peri_mem_dev;\nstatic off_t bcm2835_peri_base = 0x20000000;\n#define BCM2835_GPIO_BASE\t(bcm2835_peri_base + 0x200000) /* GPIO controller */\n\n#define BCM2835_PADS_GPIO_0_27\t\t(bcm2835_peri_base + 0x100000)\n#define BCM2835_PADS_GPIO_0_27_OFFSET\t(0x2c / 4)\n\n/* See \"GPIO Function Select Registers (GPFSELn)\" in \"Broadcom BCM2835 ARM Peripherals\" datasheet. */\n#define BCM2835_GPIO_MODE_INPUT 0\n#define BCM2835_GPIO_MODE_OUTPUT 1\n\n/* GPIO setup macros */\n#define MODE_GPIO(g) (*(pio_base+((g)/10))>>(((g)%10)*3) & 7)\n#define INP_GPIO(g) do { *(pio_base+((g)/10)) &= ~(7<<(((g)%10)*3)); } while (0)\n#define SET_MODE_GPIO(g, m) do { /* clear the mode bits first, then set as necessary */ \\\n\t\tINP_GPIO(g);\t\t\t\t\t\t\\\n\t\t*(pio_base+((g)/10)) |=  ((m)<<(((g)%10)*3)); } while (0)\n#define OUT_GPIO(g) SET_MODE_GPIO(g, BCM2835_GPIO_MODE_OUTPUT)\n\n#define GPIO_SET (*(pio_base+7))  /* sets   bits which are 1, ignores bits which are 0 */\n#define GPIO_CLR (*(pio_base+10)) /* clears bits which are 1, ignores bits which are 0 */\n#define GPIO_LEV (*(pio_base+13)) /* current level of the pin */\n\nstatic int dev_mem_fd;\nstatic volatile uint32_t *pio_base = MAP_FAILED;\nstatic volatile uint32_t *pads_base = MAP_FAILED;\n\n/* Transition delay coefficients */\nstatic int speed_coeff = 113714;\nstatic int speed_offset = 28;\nstatic unsigned int jtag_delay;\n\nstatic const struct adapter_gpio_config *adapter_gpio_config;\nstatic struct initial_gpio_state {\n\tunsigned int mode;\n\tunsigned int output_level;\n} initial_gpio_state[ADAPTER_GPIO_IDX_NUM];\nstatic uint32_t initial_drive_strength_etc;\n\nstatic inline const char *bcm2835_get_mem_dev(void)\n{\n\tif (bcm2835_peri_mem_dev)\n\t\treturn bcm2835_peri_mem_dev;\n\n\treturn \"/dev/gpiomem\";\n}\n\nstatic inline void bcm2835_gpio_synchronize(void)\n{\n\t/* Ensure that previous writes to GPIO registers are flushed out of\n\t * the inner shareable domain to prevent pipelined writes to the\n\t * same address being merged.\n\t */\n\t__sync_synchronize();\n}\n\nstatic inline void bcm2835_delay(void)\n{\n\tfor (unsigned int i = 0; i < jtag_delay; i++)\n\t\tasm volatile (\"\");\n}\n\nstatic bool is_gpio_config_valid(enum adapter_gpio_config_index idx)\n{\n\t/* Only chip 0 is supported, accept unset value (-1) too */\n\treturn adapter_gpio_config[idx].chip_num >= -1\n\t\t&& adapter_gpio_config[idx].chip_num <= 0\n\t\t&& adapter_gpio_config[idx].gpio_num >= 0\n\t\t&& adapter_gpio_config[idx].gpio_num <= 31;\n}\n\nstatic void set_gpio_value(const struct adapter_gpio_config *gpio_config, int value)\n{\n\tvalue = value ^ (gpio_config->active_low ? 1 : 0);\n\tswitch (gpio_config->drive) {\n\tcase ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:\n\t\tif (value)\n\t\t\tGPIO_SET = 1 << gpio_config->gpio_num;\n\t\telse\n\t\t\tGPIO_CLR = 1 << gpio_config->gpio_num;\n\t\t/* For performance reasons assume the GPIO is already set as an output\n\t\t * and therefore the call can be omitted here.\n\t\t */\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:\n\t\tif (value) {\n\t\t\tINP_GPIO(gpio_config->gpio_num);\n\t\t} else {\n\t\t\tGPIO_CLR = 1 << gpio_config->gpio_num;\n\t\t\tOUT_GPIO(gpio_config->gpio_num);\n\t\t}\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:\n\t\tif (value) {\n\t\t\tGPIO_SET = 1 << gpio_config->gpio_num;\n\t\t\tOUT_GPIO(gpio_config->gpio_num);\n\t\t} else {\n\t\t\tINP_GPIO(gpio_config->gpio_num);\n\t\t}\n\t\tbreak;\n\t}\n\tbcm2835_gpio_synchronize();\n}\n\nstatic void restore_gpio(enum adapter_gpio_config_index idx)\n{\n\tif (is_gpio_config_valid(idx)) {\n\t\tSET_MODE_GPIO(adapter_gpio_config[idx].gpio_num, initial_gpio_state[idx].mode);\n\t\tif (initial_gpio_state[idx].mode == BCM2835_GPIO_MODE_OUTPUT) {\n\t\t\tif (initial_gpio_state[idx].output_level)\n\t\t\t\tGPIO_SET = 1 << adapter_gpio_config[idx].gpio_num;\n\t\t\telse\n\t\t\t\tGPIO_CLR = 1 << adapter_gpio_config[idx].gpio_num;\n\t\t}\n\t}\n\tbcm2835_gpio_synchronize();\n}\n\nstatic void initialize_gpio(enum adapter_gpio_config_index idx)\n{\n\tif (!is_gpio_config_valid(idx))\n\t\treturn;\n\n\tinitial_gpio_state[idx].mode = MODE_GPIO(adapter_gpio_config[idx].gpio_num);\n\tunsigned int shift = adapter_gpio_config[idx].gpio_num;\n\tinitial_gpio_state[idx].output_level = (GPIO_LEV >> shift) & 1;\n\tLOG_DEBUG(\"saved GPIO mode for %s (GPIO %d %d): %d\",\n\t\t\tadapter_gpio_get_name(idx), adapter_gpio_config[idx].chip_num, adapter_gpio_config[idx].gpio_num,\n\t\t\tinitial_gpio_state[idx].mode);\n\n\tif (adapter_gpio_config[idx].pull != ADAPTER_GPIO_PULL_NONE) {\n\t\tLOG_WARNING(\"BCM2835 GPIO does not support pull-up or pull-down settings (signal %s)\",\n\t\t\tadapter_gpio_get_name(idx));\n\t}\n\n\tswitch (adapter_gpio_config[idx].init_state) {\n\tcase ADAPTER_GPIO_INIT_STATE_INACTIVE:\n\t\tset_gpio_value(&adapter_gpio_config[idx], 0);\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_ACTIVE:\n\t\tset_gpio_value(&adapter_gpio_config[idx], 1);\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_INPUT:\n\t\tINP_GPIO(adapter_gpio_config[idx].gpio_num);\n\t\tbreak;\n\t}\n\n\t/* Direction for non push-pull is already set by set_gpio_value() */\n\tif (adapter_gpio_config[idx].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL)\n\t\tOUT_GPIO(adapter_gpio_config[idx].gpio_num);\n\tbcm2835_gpio_synchronize();\n}\n\nstatic bb_value_t bcm2835gpio_read(void)\n{\n\tunsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].gpio_num;\n\tuint32_t value = (GPIO_LEV >> shift) & 1;\n\treturn value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_TDO].active_low ? BB_HIGH : BB_LOW);\n\n}\n\nstatic int bcm2835gpio_write(int tck, int tms, int tdi)\n{\n\tuint32_t set = tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |\n\t\t\ttms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |\n\t\t\ttdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;\n\tuint32_t clear = !tck << adapter_gpio_config[ADAPTER_GPIO_IDX_TCK].gpio_num |\n\t\t\t!tms << adapter_gpio_config[ADAPTER_GPIO_IDX_TMS].gpio_num |\n\t\t\t!tdi << adapter_gpio_config[ADAPTER_GPIO_IDX_TDI].gpio_num;\n\n\tGPIO_SET = set;\n\tGPIO_CLR = clear;\n\tbcm2835_gpio_synchronize();\n\n\tbcm2835_delay();\n\n\treturn ERROR_OK;\n}\n\n/* Requires push-pull drive mode for swclk and swdio */\nstatic int bcm2835gpio_swd_write_fast(int swclk, int swdio)\n{\n\tswclk = swclk ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].active_low ? 1 : 0);\n\tswdio = swdio ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);\n\n\tuint32_t set = swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |\n\t\t\t\t\tswdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;\n\tuint32_t clear = !swclk << adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].gpio_num |\n\t\t\t\t\t!swdio << adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;\n\n\tGPIO_SET = set;\n\tGPIO_CLR = clear;\n\tbcm2835_gpio_synchronize();\n\n\tbcm2835_delay();\n\n\treturn ERROR_OK;\n}\n\n/* Generic mode that works for open-drain/open-source drive modes, but slower */\nstatic int bcm2835gpio_swd_write_generic(int swclk, int swdio)\n{\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO], swdio);\n\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK], swclk); /* Write clock last */\n\n\tbcm2835_delay();\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int bcm2835gpio_reset(int trst, int srst)\n{\n\t/* As the \"adapter reset_config\" command keeps the srst and trst gpio drive\n\t * mode settings in sync we can use our standard set_gpio_value() function\n\t * that honours drive mode and active low.\n\t */\n\tif (is_gpio_config_valid(ADAPTER_GPIO_IDX_SRST))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SRST], srst);\n\n\tif (is_gpio_config_valid(ADAPTER_GPIO_IDX_TRST))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_TRST], trst);\n\n\tLOG_DEBUG(\"BCM2835 GPIO: bcm2835gpio_reset(%d, %d), trst_gpio: %d %d, srst_gpio: %d %d\",\n\t\ttrst, srst,\n\t\tadapter_gpio_config[ADAPTER_GPIO_IDX_TRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_TRST].gpio_num,\n\t\tadapter_gpio_config[ADAPTER_GPIO_IDX_SRST].chip_num, adapter_gpio_config[ADAPTER_GPIO_IDX_SRST].gpio_num);\n\treturn ERROR_OK;\n}\n\nstatic void bcm2835_swdio_drive(bool is_output)\n{\n\tif (is_output) {\n\t\tif (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))\n\t\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);\n\t\tOUT_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);\n\t} else {\n\t\tINP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);\n\t\tif (is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO_DIR))\n\t\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);\n\t}\n\tbcm2835_gpio_synchronize();\n}\n\nstatic int bcm2835_swdio_read(void)\n{\n\tunsigned int shift = adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num;\n\tuint32_t value = (GPIO_LEV >> shift) & 1;\n\treturn value ^ (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].active_low ? 1 : 0);\n}\n\nstatic int bcm2835gpio_khz(int khz, int *jtag_speed)\n{\n\tif (!khz) {\n\t\tLOG_DEBUG(\"BCM2835 GPIO: RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*jtag_speed = DIV_ROUND_UP(speed_coeff, khz) - speed_offset;\n\tLOG_DEBUG(\"jtag_delay %d\", *jtag_speed);\n\tif (*jtag_speed < 0)\n\t\t*jtag_speed = 0;\n\treturn ERROR_OK;\n}\n\nstatic int bcm2835gpio_speed_div(int speed, int *khz)\n{\n\tint divisor = speed + speed_offset;\n\t/* divide with roundig to the closest */\n\t*khz = (speed_coeff + divisor / 2) / divisor;\n\treturn ERROR_OK;\n}\n\nstatic int bcm2835gpio_speed(int speed)\n{\n\tjtag_delay = speed;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(bcm2835gpio_handle_speed_coeffs)\n{\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);\n\t}\n\n\tcommand_print(CMD, \"BCM2835 GPIO: speed_coeffs = %d, speed_offset = %d\",\n\t\t\t\t  speed_coeff, speed_offset);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(bcm2835gpio_handle_peripheral_mem_dev)\n{\n\tif (CMD_ARGC == 1) {\n\t\tfree(bcm2835_peri_mem_dev);\n\t\tbcm2835_peri_mem_dev = strdup(CMD_ARGV[0]);\n\t}\n\n\tcommand_print(CMD, \"BCM2835 GPIO: peripheral_mem_dev = %s\",\n\t\t\t\t  bcm2835_get_mem_dev());\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(bcm2835gpio_handle_peripheral_base)\n{\n\tuint64_t tmp_base;\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], tmp_base);\n\t\tbcm2835_peri_base = (off_t)tmp_base;\n\t}\n\n\ttmp_base = bcm2835_peri_base;\n\tcommand_print(CMD, \"BCM2835 GPIO: peripheral_base = 0x%08\" PRIu64,\n\t\t\t\t  tmp_base);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration bcm2835gpio_subcommand_handlers[] = {\n\t{\n\t\t.name = \"speed_coeffs\",\n\t\t.handler = &bcm2835gpio_handle_speed_coeffs,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"SPEED_COEFF and SPEED_OFFSET for delay calculations.\",\n\t\t.usage = \"[SPEED_COEFF SPEED_OFFSET]\",\n\t},\n\t{\n\t\t.name = \"peripheral_mem_dev\",\n\t\t.handler = &bcm2835gpio_handle_peripheral_mem_dev,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"device to map memory mapped GPIOs from.\",\n\t\t.usage = \"[device]\",\n\t},\n\t{\n\t\t.name = \"peripheral_base\",\n\t\t.handler = &bcm2835gpio_handle_peripheral_base,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"peripheral base to access GPIOs, not needed with /dev/gpiomem.\",\n\t\t.usage = \"[base]\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration bcm2835gpio_command_handlers[] = {\n\t{\n\t\t.name = \"bcm2835gpio\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform bcm2835gpio management\",\n\t\t.chain = bcm2835gpio_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic bool bcm2835gpio_jtag_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))\n\t\treturn false;\n\treturn true;\n}\n\nstatic bool bcm2835gpio_swd_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))\n\t\treturn false;\n\treturn true;\n}\n\nstatic void bcm2835gpio_munmap(void)\n{\n\tif (pio_base != MAP_FAILED) {\n\t\tmunmap((void *)pio_base, sysconf(_SC_PAGE_SIZE));\n\t\tpio_base = MAP_FAILED;\n\t}\n\n\tif (pads_base != MAP_FAILED) {\n\t\tmunmap((void *)pads_base, sysconf(_SC_PAGE_SIZE));\n\t\tpads_base = MAP_FAILED;\n\t}\n}\n\nstatic int bcm2835gpio_blink(int on)\n{\n\tif (is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))\n\t\tset_gpio_value(&adapter_gpio_config[ADAPTER_GPIO_IDX_LED], on);\n\n\treturn ERROR_OK;\n}\n\nstatic struct bitbang_interface bcm2835gpio_bitbang = {\n\t.read = bcm2835gpio_read,\n\t.write = bcm2835gpio_write,\n\t.swdio_read = bcm2835_swdio_read,\n\t.swdio_drive = bcm2835_swdio_drive,\n\t.swd_write = bcm2835gpio_swd_write_generic,\n\t.blink = bcm2835gpio_blink,\n};\n\nstatic int bcm2835gpio_init(void)\n{\n\tLOG_INFO(\"BCM2835 GPIO JTAG/SWD bitbang driver\");\n\n\tbitbang_interface = &bcm2835gpio_bitbang;\n\tadapter_gpio_config = adapter_gpio_get_config();\n\n\tif (transport_is_jtag() && !bcm2835gpio_jtag_mode_possible()) {\n\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios for JTAG mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (transport_is_swd() && !bcm2835gpio_swd_mode_possible()) {\n\t\tLOG_ERROR(\"Require swclk and swdio gpio for SWD mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tbool is_gpiomem = strcmp(bcm2835_get_mem_dev(), \"/dev/gpiomem\") == 0;\n\tbool pad_mapping_possible = !is_gpiomem;\n\n\tdev_mem_fd = open(bcm2835_get_mem_dev(), O_RDWR | O_SYNC);\n\tif (dev_mem_fd < 0) {\n\t\tLOG_ERROR(\"open %s: %s\", bcm2835_get_mem_dev(), strerror(errno));\n\t\t/* TODO: add /dev/mem specific doc and refer to it\n\t\t * if (!is_gpiomem && (errno == EACCES || errno == EPERM))\n\t\t *\tLOG_INFO(\"Consult the user's guide chapter 4.? how to set permissions and capabilities\");\n\t\t */\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tpio_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, BCM2835_GPIO_BASE);\n\n\tif (pio_base == MAP_FAILED) {\n\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\tclose(dev_mem_fd);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* TODO: move pads config to a separate utility */\n\tif (pad_mapping_possible) {\n\t\tpads_base = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, BCM2835_PADS_GPIO_0_27);\n\n\t\tif (pads_base == MAP_FAILED) {\n\t\t\tLOG_ERROR(\"mmap pads: %s\", strerror(errno));\n\t\t\tLOG_WARNING(\"Continuing with unchanged GPIO pad settings (drive strength and slew rate)\");\n\t\t}\n\t} else {\n\t\tpads_base = MAP_FAILED;\n\t}\n\n\tclose(dev_mem_fd);\n\n\tif (pads_base != MAP_FAILED) {\n\t\t/* set 4mA drive strength, slew rate limited, hysteresis on */\n\t\tinitial_drive_strength_etc = pads_base[BCM2835_PADS_GPIO_0_27_OFFSET] & 0x1f;\nLOG_INFO(\"initial pads conf %08x\", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);\n\t\tpads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5a000008 + 1;\nLOG_INFO(\"pads conf set to %08x\", pads_base[BCM2835_PADS_GPIO_0_27_OFFSET]);\n\t}\n\n\t/* Configure JTAG/SWD signals. Default directions and initial states are handled\n\t * by adapter.c and \"adapter gpio\" command.\n\t */\n\tif (transport_is_jtag()) {\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TDO);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TDI);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TMS);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TCK);\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_TRST);\n\t}\n\n\tif (transport_is_swd()) {\n\t\t/* swdio and its buffer should be initialized in the order that prevents\n\t\t * two outputs from being connected together. This will occur if the\n\t\t * swdio GPIO of the AM335x is configured as an output while its\n\t\t * external buffer is configured to send the swdio signal from the\n\t\t * target to the AM335x.\n\t\t */\n\t\tif (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t} else {\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\t\t}\n\n\t\tinitialize_gpio(ADAPTER_GPIO_IDX_SWCLK);\n\n\t\tif (adapter_gpio_config[ADAPTER_GPIO_IDX_SWCLK].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL &&\n\t\t\t\tadapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].drive == ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL) {\n\t\t\tLOG_DEBUG(\"BCM2835 GPIO using fast mode for SWD write\");\n\t\t\tbcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_fast;\n\t\t} else {\n\t\t\tLOG_DEBUG(\"BCM2835 GPIO using generic mode for SWD write\");\n\t\t\tbcm2835gpio_bitbang.swd_write = bcm2835gpio_swd_write_generic;\n\t\t}\n\t}\n\n\tinitialize_gpio(ADAPTER_GPIO_IDX_SRST);\n\tinitialize_gpio(ADAPTER_GPIO_IDX_LED);\n\n\treturn ERROR_OK;\n}\n\nstatic int bcm2835gpio_quit(void)\n{\n\tif (transport_is_jtag()) {\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TDO);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TDI);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TCK);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TMS);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_TRST);\n\t}\n\n\tif (transport_is_swd()) {\n\t\t/* Restore swdio/swdio_dir to their initial modes, even if that means\n\t\t * connecting two outputs. Begin by making swdio an input so that the\n\t\t * current and final states of swdio and swdio_dir do not have to be\n\t\t * considered to calculate the safe restoration order.\n\t\t */\n\t\tINP_GPIO(adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].gpio_num);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWDIO);\n\t\trestore_gpio(ADAPTER_GPIO_IDX_SWCLK);\n\t}\n\n\trestore_gpio(ADAPTER_GPIO_IDX_SRST);\n\trestore_gpio(ADAPTER_GPIO_IDX_LED);\n\n\tif (pads_base != MAP_FAILED) {\n\t\t/* Restore drive strength. MSB is password (\"5A\") */\n\t\tpads_base[BCM2835_PADS_GPIO_0_27_OFFSET] = 0x5A000000 | initial_drive_strength_etc;\n\t}\n\tbcm2835gpio_munmap();\n\tfree(bcm2835_peri_mem_dev);\n\n\treturn ERROR_OK;\n}\n\n\nstatic const char * const bcm2835_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface bcm2835gpio_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\nstruct adapter_driver bcm2835gpio_adapter_driver = {\n\t.name = \"bcm2835gpio\",\n\t.transports = bcm2835_transports,\n\t.commands = bcm2835gpio_command_handlers,\n\n\t.init = bcm2835gpio_init,\n\t.quit = bcm2835gpio_quit,\n\t.reset = bcm2835gpio_reset,\n\t.speed = bcm2835gpio_speed,\n\t.khz = bcm2835gpio_khz,\n\t.speed_div = bcm2835gpio_speed_div,\n\n\t.jtag_ops = &bcm2835gpio_interface,\n\t.swd_ops = &bitbang_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/bitbang.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n/* 2014-12: Addition of the SWD protocol support is based on the initial work\n * by Paul Fertser and modifications by Jean-Christian de Rivaz. */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"bitbang.h\"\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n\n/**\n * Function bitbang_stableclocks\n * issues a number of clock cycles while staying in a stable state.\n * Because the TMS value required to stay in the RESET state is a 1, whereas\n * the TMS value required to stay in any of the other stable states is a 0,\n * this function checks the current stable state to decide on the value of TMS\n * to use.\n */\nstatic int bitbang_stableclocks(int num_cycles);\n\nstatic void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);\n\nstruct bitbang_interface *bitbang_interface;\n\n/* DANGER!!!! clock absolutely *MUST* be 0 in idle or reset won't work!\n *\n * Set this to 1 and str912 reset halt will fail.\n *\n * If someone can submit a patch with an explanation it will be greatly\n * appreciated, but as far as I can tell (ØH) DCLK is generated upon\n * clk = 0 in TAP_IDLE. Good luck deducing that from the ARM documentation!\n * The ARM documentation uses the term \"DCLK is asserted while in the TAP_IDLE\n * state\". With hardware there is no such thing as *while* in a state. There\n * are only edges. So clk => 0 is in fact a very subtle state transition that\n * happens *while* in the TAP_IDLE state. \"#&¤\"#¤&\"#&\"#&\n *\n * For \"reset halt\" the last thing that happens before srst is asserted\n * is that the breakpoint is set up. If DCLK is not wiggled one last\n * time before the reset, then the breakpoint is not set up and\n * \"reset halt\" will fail to halt.\n *\n */\n#define CLOCK_IDLE() 0\n\n/* The bitbang driver leaves the TCK 0 when in idle */\nstatic void bitbang_end_state(tap_state_t state)\n{\n\tassert(tap_is_state_stable(state));\n\ttap_set_end_state(state);\n}\n\nstatic int bitbang_state_move(int skip)\n{\n\tint i = 0, tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tfor (i = skip; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\tif (bitbang_interface->write(0, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (bitbang_interface->write(1, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\tif (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttap_set_state(tap_get_end_state());\n\treturn ERROR_OK;\n}\n\n/**\n * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG\n * (or SWD) state machine.\n */\nstatic int bitbang_execute_tms(struct jtag_command *cmd)\n{\n\tunsigned num_bits = cmd->cmd.tms->num_bits;\n\tconst uint8_t *bits = cmd->cmd.tms->bits;\n\n\tLOG_DEBUG_IO(\"TMS: %d bits\", num_bits);\n\n\tint tms = 0;\n\tfor (unsigned i = 0; i < num_bits; i++) {\n\t\ttms = ((bits[i/8] >> (i % 8)) & 1);\n\t\tif (bitbang_interface->write(0, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (bitbang_interface->write(1, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\tif (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int bitbang_path_move(struct pathmove_command *cmd)\n{\n\tint num_states = cmd->num_states;\n\tint state_count;\n\tint tms = 0;\n\n\tstate_count = 0;\n\twhile (num_states) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])\n\t\t\ttms = 0;\n\t\telse if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])\n\t\t\ttms = 1;\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(cmd->path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\tif (bitbang_interface->write(0, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (bitbang_interface->write(1, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\ttap_set_state(cmd->path[state_count]);\n\t\tstate_count++;\n\t\tnum_states--;\n\t}\n\n\tif (bitbang_interface->write(CLOCK_IDLE(), tms, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttap_set_end_state(tap_get_state());\n\treturn ERROR_OK;\n}\n\nstatic int bitbang_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tbitbang_end_state(TAP_IDLE);\n\t\tif (bitbang_state_move(0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tif (bitbang_interface->write(0, 0, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (bitbang_interface->write(1, 0, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\tif (bitbang_interface->write(CLOCK_IDLE(), 0, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* finish in end_state */\n\tbitbang_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tif (bitbang_state_move(0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int bitbang_stableclocks(int num_cycles)\n{\n\tint tms = (tap_get_state() == TAP_RESET ? 1 : 0);\n\tint i;\n\n\t/* send num_cycles clocks onto the cable */\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tif (bitbang_interface->write(1, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (bitbang_interface->write(0, tms, 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int bitbang_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,\n\t\tunsigned scan_size)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\tunsigned bit_cnt;\n\n\tif (!((!ir_scan &&\n\t\t\t(tap_get_state() == TAP_DRSHIFT)) ||\n\t\t\t(ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {\n\t\tif (ir_scan)\n\t\t\tbitbang_end_state(TAP_IRSHIFT);\n\t\telse\n\t\t\tbitbang_end_state(TAP_DRSHIFT);\n\n\t\tif (bitbang_state_move(0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tbitbang_end_state(saved_end_state);\n\t}\n\n\tsize_t buffered = 0;\n\tfor (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {\n\t\tint tms = (bit_cnt == scan_size-1) ? 1 : 0;\n\t\tint tdi;\n\t\tint bytec = bit_cnt/8;\n\t\tint bcval = 1 << (bit_cnt % 8);\n\n\t\t/* if we're just reading the scan, but don't care about the output\n\t\t * default to outputting 'low', this also makes valgrind traces more readable,\n\t\t * as it removes the dependency on an uninitialised value\n\t\t */\n\t\ttdi = 0;\n\t\tif ((type != SCAN_IN) && (buffer[bytec] & bcval))\n\t\t\ttdi = 1;\n\n\t\tif (bitbang_interface->write(0, tms, tdi) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (type != SCAN_OUT) {\n\t\t\tif (bitbang_interface->buf_size) {\n\t\t\t\tif (bitbang_interface->sample() != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbuffered++;\n\t\t\t} else {\n\t\t\t\tswitch (bitbang_interface->read()) {\n\t\t\t\t\tcase BB_LOW:\n\t\t\t\t\t\tbuffer[bytec] &= ~bcval;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BB_HIGH:\n\t\t\t\t\t\tbuffer[bytec] |= bcval;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (bitbang_interface->write(1, tms, tdi) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (type != SCAN_OUT && bitbang_interface->buf_size &&\n\t\t\t\t(buffered == bitbang_interface->buf_size ||\n\t\t\t\t bit_cnt == scan_size - 1)) {\n\t\t\tfor (unsigned i = bit_cnt + 1 - buffered; i <= bit_cnt; i++) {\n\t\t\t\tswitch (bitbang_interface->read_sample()) {\n\t\t\t\t\tcase BB_LOW:\n\t\t\t\t\t\tbuffer[i/8] &= ~(1 << (i % 8));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase BB_HIGH:\n\t\t\t\t\t\tbuffer[i/8] |= 1 << (i % 8);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuffered = 0;\n\t\t}\n\t}\n\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\t/* we *KNOW* the above loop transitioned out of\n\t\t * the shift state, so we skip the first state\n\t\t * and move directly to the end state.\n\t\t */\n\t\tif (bitbang_state_move(1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nint bitbang_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\t/* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\tint retval;\n\n\tif (!bitbang_interface) {\n\t\tLOG_ERROR(\"BUG: Bitbang interface called, but not yet initialized\");\n\t\texit(-1);\n\t}\n\n\t/* return ERROR_OK, unless a jtag_read_buffer returns a failed check\n\t * that wasn't handled by a caller-provided error handler\n\t */\n\tretval = ERROR_OK;\n\n\tif (bitbang_interface->blink) {\n\t\tif (bitbang_interface->blink(1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %s\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\ttap_state_name(cmd->cmd.runtest->end_state));\n\t\t\t\tbitbang_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tif (bitbang_runtest(cmd->cmd.runtest->num_cycles) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_STABLECLOCKS:\n\t\t\t\t/* this is only allowed while in a stable state.  A check for a stable\n\t\t\t\t * state was done in jtag_add_clocks()\n\t\t\t\t */\n\t\t\t\tif (bitbang_stableclocks(cmd->cmd.stableclocks->num_cycles) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %s\",\n\t\t\t\t\t\ttap_state_name(cmd->cmd.statemove->end_state));\n\t\t\t\tbitbang_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tif (bitbang_state_move(0) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %s\",\n\t\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\t\ttap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));\n\t\t\t\tif (bitbang_path_move(cmd->cmd.pathmove) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tbitbang_end_state(cmd->cmd.scan->end_state);\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\tLOG_DEBUG_IO(\"%s scan %d bits; end in %s\",\n\t\t\t\t\t\t(cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\",\n\t\t\t\t\t\tscan_size,\n\t\t\t\t\ttap_state_name(cmd->cmd.scan->end_state));\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tif (bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer,\n\t\t\t\t\t\t\tscan_size) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tif (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TMS:\n\t\t\t\tretval = bitbang_execute_tms(cmd);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\tif (bitbang_interface->blink) {\n\t\tif (bitbang_interface->blink(0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic int queued_retval;\n\nstatic int bitbang_swd_init(void)\n{\n\tLOG_DEBUG(\"bitbang_swd_init\");\n\treturn ERROR_OK;\n}\n\nstatic void bitbang_swd_exchange(bool rnw, uint8_t buf[], unsigned int offset, unsigned int bit_cnt)\n{\n\tif (bitbang_interface->blink) {\n\t\t/* FIXME: we should manage errors */\n\t\tbitbang_interface->blink(1);\n\t}\n\n\tfor (unsigned int i = offset; i < bit_cnt + offset; i++) {\n\t\tint bytec = i/8;\n\t\tint bcval = 1 << (i % 8);\n\t\tint swdio = !rnw && (buf[bytec] & bcval);\n\n\t\tbitbang_interface->swd_write(0, swdio);\n\n\t\tif (rnw && buf) {\n\t\t\tif (bitbang_interface->swdio_read())\n\t\t\t\tbuf[bytec] |= bcval;\n\t\t\telse\n\t\t\t\tbuf[bytec] &= ~bcval;\n\t\t}\n\n\t\tbitbang_interface->swd_write(1, swdio);\n\t}\n\n\tif (bitbang_interface->blink) {\n\t\t/* FIXME: we should manage errors */\n\t\tbitbang_interface->blink(0);\n\t}\n}\n\nstatic int bitbang_swd_switch_seq(enum swd_special_seq seq)\n{\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG_IO(\"SWD line reset\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_line_reset, 0, swd_seq_line_reset_len);\n\t\tbreak;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len);\n\t\tbreak;\n\tcase JTAG_TO_DORMANT:\n\t\tLOG_DEBUG(\"JTAG-to-DORMANT\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_jtag_to_dormant, 0, swd_seq_jtag_to_dormant_len);\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len);\n\t\tbreak;\n\tcase SWD_TO_DORMANT:\n\t\tLOG_DEBUG(\"SWD-to-DORMANT\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_swd_to_dormant, 0, swd_seq_swd_to_dormant_len);\n\t\tbreak;\n\tcase DORMANT_TO_SWD:\n\t\tLOG_DEBUG(\"DORMANT-to-SWD\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_swd, 0, swd_seq_dormant_to_swd_len);\n\t\tbreak;\n\tcase DORMANT_TO_JTAG:\n\t\tLOG_DEBUG(\"DORMANT-to-JTAG\");\n\t\tbitbang_swd_exchange(false, (uint8_t *)swd_seq_dormant_to_jtag, 0, swd_seq_dormant_to_jtag_len);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void swd_clear_sticky_errors(void)\n{\n\tbitbang_swd_write_reg(swd_cmd(false,  false, DP_ABORT),\n\t\tSTKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);\n}\n\nstatic void bitbang_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skip bitbang_swd_read_reg because queued_retval=%d\", queued_retval);\n\t\treturn;\n\t}\n\n\tfor (;;) {\n\t\tuint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];\n\n\t\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\t\tbitbang_swd_exchange(false, &cmd, 0, 8);\n\n\t\tbitbang_interface->swdio_drive(false);\n\t\tbitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3 + 32 + 1 + 1);\n\t\tbitbang_interface->swdio_drive(true);\n\n\t\tint ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);\n\t\tuint32_t data = buf_get_u32(trn_ack_data_parity_trn, 1 + 3, 32);\n\t\tint parity = buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 32, 1);\n\n\t\tLOG_DEBUG_IO(\"%s %s read reg %X = %08\" PRIx32,\n\t\t\t  ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t\t  cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t  (cmd & SWD_CMD_A32) >> 1,\n\t\t\t  data);\n\n\t\tif (ack == SWD_ACK_WAIT) {\n\t\t\tswd_clear_sticky_errors();\n\t\t\tcontinue;\n\t\t} else if (ack != SWD_ACK_OK) {\n\t\t\tqueued_retval = swd_ack_to_error_code(ack);\n\t\t\treturn;\n\t\t}\n\n\t\tif (parity != parity_u32(data)) {\n\t\t\tLOG_ERROR(\"Wrong parity detected\");\n\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\treturn;\n\t\t}\n\t\tif (value)\n\t\t\t*value = data;\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\tbitbang_swd_exchange(true, NULL, 0, ap_delay_clk);\n\t\treturn;\n\t}\n}\n\nstatic void bitbang_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skip bitbang_swd_write_reg because queued_retval=%d\", queued_retval);\n\t\treturn;\n\t}\n\n\t/* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */\n\tbool check_ack = swd_cmd_returns_ack(cmd);\n\n\t/* init the array to silence scan-build */\n\tuint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)] = {0};\n\tfor (;;) {\n\t\tbuf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32, value);\n\t\tbuf_set_u32(trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(value));\n\n\t\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\t\tbitbang_swd_exchange(false, &cmd, 0, 8);\n\n\t\tbitbang_interface->swdio_drive(false);\n\t\tbitbang_swd_exchange(true, trn_ack_data_parity_trn, 0, 1 + 3);\n\n\t\t/* Avoid a glitch on SWDIO when changing the direction to output.\n\t\t * To keep performance penalty minimal, pre-write the first data\n\t\t * bit to SWDIO GPIO output buffer while clocking the turnaround bit.\n\t\t * Following swdio_drive(true) outputs the pre-written value\n\t\t * and the same value is rewritten by the next swd_write()\n\t\t * instead of glitching SWDIO\n\t\t * HiZ/pull-up --------------> 0 -------------> 1\n\t\t *           swdio_drive(true)   swd_write(0,1)\n\t\t * in case of data bit 0 = 1\n\t\t */\n\t\tbitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 1);\n\t\tbitbang_interface->swdio_drive(true);\n\t\tbitbang_swd_exchange(false, trn_ack_data_parity_trn, 1 + 3 + 1, 32 + 1);\n\n\t\tint ack = buf_get_u32(trn_ack_data_parity_trn, 1, 3);\n\n\t\tLOG_DEBUG_IO(\"%s%s %s write reg %X = %08\" PRIx32,\n\t\t\t  check_ack ? \"\" : \"ack ignored \",\n\t\t\t  ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t\t  cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t  (cmd & SWD_CMD_A32) >> 1,\n\t\t\t  buf_get_u32(trn_ack_data_parity_trn, 1 + 3 + 1, 32));\n\n\t\tif (check_ack) {\n\t\t\tif (ack == SWD_ACK_WAIT) {\n\t\t\t\tswd_clear_sticky_errors();\n\t\t\t\tcontinue;\n\t\t\t} else if (ack != SWD_ACK_OK) {\n\t\t\t\tqueued_retval = swd_ack_to_error_code(ack);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\tbitbang_swd_exchange(true, NULL, 0, ap_delay_clk);\n\t\treturn;\n\t}\n}\n\nstatic int bitbang_swd_run_queue(void)\n{\n\t/* A transaction must be followed by another transaction or at least 8 idle cycles to\n\t * ensure that data is clocked through the AP. */\n\tbitbang_swd_exchange(true, NULL, 0, 8);\n\n\tint retval = queued_retval;\n\tqueued_retval = ERROR_OK;\n\tLOG_DEBUG_IO(\"SWD queue return value: %02x\", retval);\n\treturn retval;\n}\n\nconst struct swd_driver bitbang_swd = {\n\t.init = bitbang_swd_init,\n\t.switch_seq = bitbang_swd_switch_seq,\n\t.read_reg = bitbang_swd_read_reg,\n\t.write_reg = bitbang_swd_write_reg,\n\t.run = bitbang_swd_run_queue,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/bitbang.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_BITBANG_H\n#define OPENOCD_JTAG_DRIVERS_BITBANG_H\n\n#include <jtag/swd.h>\n\ntypedef enum {\n\tBB_LOW,\n\tBB_HIGH,\n\tBB_ERROR\n} bb_value_t;\n\n/** Low level callbacks (for bitbang).\n *\n * Either read(), or sample() and read_sample() must be implemented.\n *\n * The sample functions allow an interface to batch a number of writes and\n * sample requests together. Not waiting for a value to come back can greatly\n * increase throughput. */\nstruct bitbang_interface {\n\t/** Sample TDO and return the value. */\n\tbb_value_t (*read)(void);\n\n\t/** The number of TDO samples that can be buffered up before the caller has\n\t * to call read_sample. */\n\tsize_t buf_size;\n\n\t/** Sample TDO and put the result in a buffer. */\n\tint (*sample)(void);\n\n\t/** Return the next unread value from the buffer. */\n\tbb_value_t (*read_sample)(void);\n\n\t/** Set TCK, TMS, and TDI to the given values. */\n\tint (*write)(int tck, int tms, int tdi);\n\n\t/** Blink led (optional). */\n\tint (*blink)(int on);\n\n\t/** Sample SWDIO and return the value. */\n\tint (*swdio_read)(void);\n\n\t/** Set direction of SWDIO. */\n\tvoid (*swdio_drive)(bool on);\n\n\t/** Set SWCLK and SWDIO to the given value. */\n\tint (*swd_write)(int swclk, int swdio);\n};\n\nextern const struct swd_driver bitbang_swd;\n\nint bitbang_execute_queue(void);\n\nextern struct bitbang_interface *bitbang_interface;\n\n#endif /* OPENOCD_JTAG_DRIVERS_BITBANG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/bitq.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n*   Copyright (C) 2007 by Pavel Chromy                                    *\n*   chromy@asix.cz                                                        *\n***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include \"bitq.h\"\n#include <jtag/interface.h>\n\nstruct bitq_interface *bitq_interface; /* low level bit queue interface */\n\n/* state of input queue */\nstruct bitq_state {\n\tstruct jtag_command *cmd; /* command currently processed */\n\tint field_idx; /* index of field currently being processed */\n\tint bit_pos; /* position of bit currently being processed */\n\tint status; /* processing status */\n};\nstatic struct bitq_state bitq_in_state;\n\n/*\n * input queue processing does not use jtag_read_buffer() to avoid unnecessary overhead\n * no parameters, makes use of stored state information\n */\nstatic void bitq_in_proc(void)\n{\n\t/* loop through the queue */\n\twhile (bitq_in_state.cmd) {\n\t\t/* only JTAG_SCAN command may return data */\n\t\tif (bitq_in_state.cmd->type == JTAG_SCAN) {\n\t\t\t/* loop through the fields */\n\t\t\twhile (bitq_in_state.field_idx < bitq_in_state.cmd->cmd.scan->num_fields) {\n\t\t\t\tstruct scan_field *field;\n\t\t\t\tfield = &bitq_in_state.cmd->cmd.scan->fields[bitq_in_state.field_idx];\n\t\t\t\tif (field->in_value) {\n\t\t\t\t\t/* field scanning */\n\t\t\t\t\twhile (bitq_in_state.bit_pos < field->num_bits) {\n\t\t\t\t\t\t/* index of byte being scanned */\n\t\t\t\t\t\tint in_idx = bitq_in_state.bit_pos / 8;\n\t\t\t\t\t\t/* mask of next bit to be scanned */\n\t\t\t\t\t\tuint8_t in_mask = 1 << (bitq_in_state.bit_pos % 8);\n\n\t\t\t\t\t\tint tdo = bitq_interface->in();\n\t\t\t\t\t\tif (tdo < 0) {\n\t\t\t\t\t\t\tLOG_DEBUG_IO(\"bitq in EOF\");\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (in_mask == 0x01)\n\t\t\t\t\t\t\tfield->in_value[in_idx] = 0;\n\t\t\t\t\t\tif (tdo)\n\t\t\t\t\t\t\tfield->in_value[in_idx] |= in_mask;\n\t\t\t\t\t\tbitq_in_state.bit_pos++;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbitq_in_state.field_idx++;  /* advance to next field */\n\t\t\t\tbitq_in_state.bit_pos = 0;  /* start next field from the first bit */\n\t\t\t}\n\t\t}\n\t\tbitq_in_state.cmd = bitq_in_state.cmd->next;    /* advance to next command */\n\t\tbitq_in_state.field_idx = 0;                    /* preselect first field */\n\t}\n}\n\nstatic void bitq_io(int tms, int tdi, int tdo_req)\n{\n\tbitq_interface->out(tms, tdi, tdo_req);\n\t/* check and process the input queue */\n\tif (bitq_interface->in_rdy())\n\t\tbitq_in_proc();\n}\n\nstatic void bitq_end_state(tap_state_t state)\n{\n\tif (!tap_is_state_stable(state)) {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n\ttap_set_end_state(state);\n}\n\nstatic void bitq_state_move(tap_state_t new_state)\n{\n\tint i = 0;\n\tuint8_t  tms_scan;\n\n\tif (!tap_is_state_stable(tap_get_state()) || !tap_is_state_stable(new_state)) {\n\t\tLOG_ERROR(\"TAP move from or to unstable state\");\n\t\texit(-1);\n\t}\n\n\ttms_scan = tap_get_tms_path(tap_get_state(), new_state);\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), new_state);\n\n\tfor (i = 0; i < tms_count; i++) {\n\t\tbitq_io(tms_scan & 1, 0, 0);\n\t\ttms_scan >>= 1;\n\t}\n\n\ttap_set_state(new_state);\n}\n\nstatic void bitq_path_move(struct pathmove_command *cmd)\n{\n\tint i;\n\n\tfor (i = 0; i < cmd->num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[i])\n\t\t\tbitq_io(0, 0, 0);\n\t\telse if (tap_state_transition(tap_get_state(), true) == cmd->path[i])\n\t\t\tbitq_io(1, 0, 0);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\", tap_state_name(\n\t\t\t\t\t\t\t tap_get_state()), tap_state_name(cmd->path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(cmd->path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void bitq_runtest(int num_cycles)\n{\n\tint i;\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE)\n\t\tbitq_state_move(TAP_IDLE);\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++)\n\t\tbitq_io(0, 0, 0);\n\n\t/* finish in end_state */\n\tif (tap_get_state() != tap_get_end_state())\n\t\tbitq_state_move(tap_get_end_state());\n}\n\nstatic void bitq_scan_field(struct scan_field *field, int do_pause)\n{\n\tint bit_cnt;\n\tint tdo_req;\n\n\tconst uint8_t *out_ptr;\n\tuint8_t  out_mask;\n\n\tif (field->in_value)\n\t\ttdo_req = 1;\n\telse\n\t\ttdo_req = 0;\n\n\tif (!field->out_value) {\n\t\t/* just send zeros and request data from TDO */\n\t\tfor (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--)\n\t\t\tbitq_io(0, 0, tdo_req);\n\n\t\tbitq_io(do_pause, 0, tdo_req);\n\t} else {\n\t\t/* send data, and optionally request TDO */\n\t\tout_mask = 0x01;\n\t\tout_ptr  = field->out_value;\n\t\tfor (bit_cnt = field->num_bits; bit_cnt > 1; bit_cnt--) {\n\t\t\tbitq_io(0, ((*out_ptr) & out_mask) != 0, tdo_req);\n\t\t\tif (out_mask == 0x80) {\n\t\t\t\tout_mask = 0x01;\n\t\t\t\tout_ptr++;\n\t\t\t} else\n\t\t\t\tout_mask <<= 1;\n\t\t}\n\n\t\tbitq_io(do_pause, ((*out_ptr) & out_mask) != 0, tdo_req);\n\t}\n\n\tif (do_pause) {\n\t\tbitq_io(0, 0, 0);\n\t\tif (tap_get_state() == TAP_IRSHIFT)\n\t\t\ttap_set_state(TAP_IRPAUSE);\n\t\telse if (tap_get_state() == TAP_DRSHIFT)\n\t\t\ttap_set_state(TAP_DRPAUSE);\n\t}\n}\n\nstatic void bitq_scan(struct scan_command *cmd)\n{\n\tint i;\n\n\tif (cmd->ir_scan)\n\t\tbitq_state_move(TAP_IRSHIFT);\n\telse\n\t\tbitq_state_move(TAP_DRSHIFT);\n\n\tfor (i = 0; i < cmd->num_fields - 1; i++)\n\t\tbitq_scan_field(&cmd->fields[i], 0);\n\n\tbitq_scan_field(&cmd->fields[i], 1);\n}\n\nint bitq_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue; /* currently processed command */\n\n\tbitq_in_state.cmd = jtag_command_queue;\n\tbitq_in_state.field_idx = 0;\n\tbitq_in_state.bit_pos   = 0;\n\tbitq_in_state.status    = ERROR_OK;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RESET:\n\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tif ((cmd->cmd.reset->trst == 1) ||\n\t\t\t\t\t(cmd->cmd.reset->srst &&\n\t\t\t\t\t(jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))\n\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\tbitq_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tif (bitq_interface->in_rdy())\n\t\t\t\tbitq_in_proc();\n\t\t\tbreak;\n\n\t\tcase JTAG_RUNTEST:\n\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);\n\t\t\tbitq_end_state(cmd->cmd.runtest->end_state);\n\t\t\tbitq_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\tbreak;\n\n\t\tcase JTAG_TLR_RESET:\n\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\t\t\tbitq_end_state(cmd->cmd.statemove->end_state);\n\t\t\tbitq_state_move(tap_get_end_state());   /* unconditional TAP move */\n\t\t\tbreak;\n\n\t\tcase JTAG_PATHMOVE:\n\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\", cmd->cmd.pathmove->num_states,\n\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\t\t\tbitq_path_move(cmd->cmd.pathmove);\n\t\t\tbreak;\n\n\t\tcase JTAG_SCAN:\n\t\t\tLOG_DEBUG_IO(\"scan end in %i\", cmd->cmd.scan->end_state);\n\t\t\tLOG_DEBUG_IO(\"scan %s\", cmd->cmd.scan->ir_scan ? \"ir\" : \"dr\");\n\t\t\tbitq_end_state(cmd->cmd.scan->end_state);\n\t\t\tbitq_scan(cmd->cmd.scan);\n\t\t\tif (tap_get_state() != tap_get_end_state())\n\t\t\t\tbitq_state_move(tap_get_end_state());\n\t\t\tbreak;\n\n\t\tcase JTAG_SLEEP:\n\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\tbitq_interface->sleep(cmd->cmd.sleep->us);\n\t\t\tif (bitq_interface->in_rdy())\n\t\t\t\tbitq_in_proc();\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\texit(-1);\n\t\t}\n\n\t\tcmd = cmd->next;\n\t}\n\n\tbitq_interface->flush();\n\tbitq_in_proc();\n\n\tif (bitq_in_state.cmd) {\n\t\tLOG_ERROR(\"missing data from bitq interface\");\n\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\tif (bitq_interface->in() >= 0) {\n\t\tLOG_ERROR(\"extra data from bitq interface\");\n\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\n\treturn bitq_in_state.status;\n}\n\nvoid bitq_cleanup(void)\n{\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/bitq.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_BITQ_H\n#define OPENOCD_JTAG_DRIVERS_BITQ_H\n\n#include <jtag/commands.h>\n\nstruct bitq_interface {\n\t/* function to enqueueing low level IO requests */\n\tint (*out)(int tms, int tdi, int tdo_req);\n\tint (*flush)(void);\n\n\tint (*sleep)(unsigned long us);\n\tint (*reset)(int trst, int srst);\n\n\t/* delayed read of requested TDO data,\n\t * the input shall be checked after call to any enqueuing function\n\t */\n\tint (*in_rdy)(void);\n\tint (*in)(void);\n};\n\nextern struct bitq_interface *bitq_interface;\n\nint bitq_execute_queue(void);\n\nvoid bitq_cleanup(void);\n\n#endif /* OPENOCD_JTAG_DRIVERS_BITQ_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/buspirate.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Michal Demin                                    *\n *   based on usbprog.c and arm-jtag-ew.c                                  *\n *   Several fixes by R. Diez in 2013.                                     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/swd.h>\n#include <jtag/commands.h>\n\n#include <termios.h>\n#include <fcntl.h>\n#include <sys/ioctl.h>\n\n#undef DEBUG_SERIAL\n/*#define DEBUG_SERIAL */\nstatic int buspirate_execute_queue(void);\nstatic int buspirate_init(void);\nstatic int buspirate_quit(void);\nstatic int buspirate_reset(int trst, int srst);\n\nstatic void buspirate_end_state(tap_state_t state);\nstatic void buspirate_state_move(void);\nstatic void buspirate_path_move(int num_states, tap_state_t *path);\nstatic void buspirate_runtest(int num_cycles);\nstatic void buspirate_scan(bool ir_scan, enum scan_type type,\n\tuint8_t *buffer, int scan_size, struct scan_command *command);\nstatic void buspirate_stableclocks(int num_cycles);\n\n#define CMD_UNKNOWN       0x00\n#define CMD_PORT_MODE     0x01\n#define CMD_FEATURE       0x02\n#define CMD_READ_ADCS     0x03\n/*#define CMD_TAP_SHIFT     0x04 // old protocol */\n#define CMD_TAP_SHIFT     0x05\n#define CMD_ENTER_RWIRE   0x05\n#define CMD_ENTER_OOCD    0x06\n#define CMD_UART_SPEED    0x07\n#define CMD_JTAG_SPEED    0x08\n#define CMD_RAW_PERIPH    0x40\n#define CMD_RAW_SPEED     0x60\n#define CMD_RAW_MODE      0x80\n\n#define CMD_TAP_SHIFT_HEADER_LEN 3\n\n/* raw-wire mode configuration */\n#define CMD_RAW_CONFIG_HIZ 0x00\n#define CMD_RAW_CONFIG_3V3 0x08\n#define CMD_RAW_CONFIG_2W  0x00\n#define CMD_RAW_CONFIG_3W  0x04\n#define CMD_RAW_CONFIG_MSB 0x00\n#define CMD_RAW_CONFIG_LSB 0x02\n\n/* Not all OSes have this speed defined */\n#if !defined(B1000000)\n#define  B1000000 0010010\n#endif\n\n#define SHORT_TIMEOUT  1  /* Must be at least 1. */\n#define NORMAL_TIMEOUT 10\n\nenum {\n\tMODE_HIZ = 0,\n\tMODE_JTAG = 1,\t\t/* push-pull outputs */\n\tMODE_JTAG_OD = 2,\t/* open-drain outputs */\n};\n\nenum {\n\tFEATURE_LED = 0x01,\n\tFEATURE_VREG = 0x02,\n\tFEATURE_TRST = 0x04,\n\tFEATURE_SRST = 0x08,\n\tFEATURE_PULLUP = 0x10\n};\n\nenum {\n\tACTION_DISABLE = 0,\n\tACTION_ENABLE = 1\n};\n\nenum {\n\tSERIAL_NORMAL = 0,\n\tSERIAL_FAST = 1\n};\n\nenum {\n\tSPEED_RAW_5_KHZ   = 0x0,\n\tSPEED_RAW_50_KHZ  = 0x1,\n\tSPEED_RAW_100_KHZ = 0x2,\n\tSPEED_RAW_400_KHZ = 0x3\n};\n\n/* SWD mode specific */\nstatic bool swd_mode;\nstatic int  queued_retval;\nstatic char swd_features;\n\nstatic int buspirate_fd = -1;\nstatic int buspirate_pinmode = MODE_JTAG_OD;\nstatic int buspirate_baudrate = SERIAL_NORMAL;\nstatic int buspirate_vreg;\nstatic int buspirate_pullup;\nstatic char *buspirate_port;\n\nstatic enum tap_state last_tap_state = TAP_RESET;\n\n/* SWD interface */\nstatic int buspirate_swd_init(void);\nstatic void buspirate_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk);\nstatic void buspirate_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk);\nstatic int buspirate_swd_switch_seq(enum swd_special_seq seq);\nstatic int buspirate_swd_run_queue(void);\n\n/* TAP interface */\nstatic void buspirate_tap_init(void);\nstatic int buspirate_tap_execute(void);\nstatic void buspirate_tap_append(int tms, int tdi);\nstatic void buspirate_tap_append_scan(int length, uint8_t *buffer,\n\t\tstruct scan_command *command);\nstatic void buspirate_tap_make_space(int scan, int bits);\n\nstatic void buspirate_set_feature(int, char, char);\nstatic void buspirate_set_mode(int, char);\nstatic void buspirate_set_speed(int, char);\n\n/* low level interface */\nstatic void buspirate_bbio_enable(int);\nstatic void buspirate_jtag_reset(int);\nstatic unsigned char buspirate_jtag_command(int, uint8_t *, int);\nstatic void buspirate_jtag_set_speed(int, char);\nstatic void buspirate_jtag_set_mode(int, char);\nstatic void buspirate_jtag_set_feature(int, char, char);\nstatic void buspirate_jtag_get_adcs(int);\n\n/* low level two-wire interface */\nstatic void buspirate_swd_set_speed(int, char);\nstatic void buspirate_swd_set_feature(int, char, char);\nstatic void buspirate_swd_set_mode(int, char);\n\n/* low level HW communication interface */\nstatic int buspirate_serial_open(char *port);\nstatic int buspirate_serial_setspeed(int fd, char speed, cc_t timeout);\nstatic int buspirate_serial_write(int fd, uint8_t *buf, int size);\nstatic int buspirate_serial_read(int fd, uint8_t *buf, int size);\nstatic void buspirate_serial_close(int fd);\nstatic void buspirate_print_buffer(uint8_t *buf, int size);\n\nstatic int buspirate_execute_queue(void)\n{\n\t/* currently processed command */\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RUNTEST:\n\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %s\",\n\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\ttap_state_name(cmd->cmd.runtest\n\t\t\t\t\t->end_state));\n\t\t\tbuspirate_end_state(cmd->cmd.runtest\n\t\t\t\t\t->end_state);\n\t\t\tbuspirate_runtest(cmd->cmd.runtest\n\t\t\t\t\t->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tLOG_DEBUG_IO(\"statemove end in %s\",\n\t\t\t\ttap_state_name(cmd->cmd.statemove\n\t\t\t\t\t\t->end_state));\n\t\t\tbuspirate_end_state(cmd->cmd.statemove\n\t\t\t\t\t->end_state);\n\t\t\tbuspirate_state_move();\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %s\",\n\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\ttap_state_name(cmd->cmd.pathmove\n\t\t\t\t\t->path[cmd->cmd.pathmove\n\t\t\t\t\t\t->num_states - 1]));\n\t\t\tbuspirate_path_move(cmd->cmd.pathmove\n\t\t\t\t\t->num_states,\n\t\t\t\t\tcmd->cmd.pathmove->path);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tLOG_DEBUG_IO(\"scan end in %s\",\n\t\t\t\ttap_state_name(cmd->cmd.scan\n\t\t\t\t\t->end_state));\n\n\t\t\tbuspirate_end_state(cmd->cmd.scan\n\t\t\t\t\t->end_state);\n\n\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan,\n\t\t\t\t\t&buffer);\n\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\tbuspirate_scan(cmd->cmd.scan->ir_scan, type,\n\t\t\t\tbuffer, scan_size, cmd->cmd.scan);\n\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\tbuspirate_tap_execute();\n\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tLOG_DEBUG_IO(\"stable clock %i cycles\", cmd->cmd.stableclocks->num_cycles);\n\t\t\tbuspirate_stableclocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\texit(-1);\n\t\t}\n\n\t\tcmd = cmd->next;\n\t}\n\n\treturn buspirate_tap_execute();\n}\n\n\n/* Returns true if successful, false if error. */\n\nstatic bool read_and_discard_all_data(const int fd)\n{\n\t/* LOG_INFO(\"Discarding any stale data from a previous connection...\"); */\n\n\tbool was_msg_already_printed = false;\n\n\tfor ( ; ; ) {\n\t\tuint8_t buffer[1024];  /* Any size will do, it's a trade-off between stack size and performance. */\n\n\t\tconst ssize_t read_count = read(fd, buffer, sizeof(buffer));\n\n\t\tif (read_count == 0) {\n\t\t\t/* This is the \"end of file\" or \"connection closed at the other end\" condition. */\n\t\t\treturn true;\n\t\t}\n\n\t\tif (read_count > 0) {\n\t\t\tif (!was_msg_already_printed)\t{\n\t\t\t\tLOG_INFO(\"Some stale data from a previous connection was discarded.\");\n\t\t\t\twas_msg_already_printed = true;\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tassert(read_count == -1);  /* According to the specification. */\n\n\t\tconst int errno_code = errno;\n\n\t\tif (errno_code == EINTR)\n\t\t\tcontinue;\n\n\t\tif (errno_code == EAGAIN ||\n\t\t\terrno_code == EWOULDBLOCK) {\n\t\t\t/* We know that the file descriptor has been opened with O_NONBLOCK or O_NDELAY,\n\t\t\t   and these codes mean that there is no data to read at present. */\n\t\t\treturn true;\n\t\t}\n\n\t\t/* Some other error has occurred. */\n\t\treturn false;\n\t}\n}\n\n\nstatic int buspirate_init(void)\n{\n\tif (!buspirate_port) {\n\t\tLOG_ERROR(\"You need to specify the serial port!\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tbuspirate_fd = buspirate_serial_open(buspirate_port);\n\tif (buspirate_fd == -1) {\n\t\tLOG_ERROR(\"Could not open serial port\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* The Operating System or the device itself may deliver stale data from the last connection,\n\t   so discard all available bytes right after the new connection has been established.\n\t   After all, we are implementing here a master/slave protocol, so the slave should have nothing\n\t   to say until the master sends the first command.\n\n\t   In the past, there was a tcflush() call in buspirate_serial_setspeed(), but that\n\t   was not enough. I guess you must actively read from the serial port to trigger any\n\t   data collection from the device and/or lower USB layers. If you disable the serial port\n\t   read timeout (if you set SHORT_TIMEOUT to 0), then the discarding does not work any more.\n\n\t   Note that we are lowering the serial port timeout for this first read operation,\n\t   otherwise the normal initialisation would be delayed for too long. */\n\n\tif (-1 == buspirate_serial_setspeed(buspirate_fd, SERIAL_NORMAL, SHORT_TIMEOUT)) {\n\t\tLOG_ERROR(\"Error configuring the serial port.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (!read_and_discard_all_data(buspirate_fd)) {\n\t\tLOG_ERROR(\"Error while attempting to discard any stale data right after establishing the connection.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (-1 == buspirate_serial_setspeed(buspirate_fd, SERIAL_NORMAL, NORMAL_TIMEOUT)) {\n\t\tLOG_ERROR(\"Error configuring the serial port.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tbuspirate_bbio_enable(buspirate_fd);\n\n\tif (swd_mode || buspirate_baudrate != SERIAL_NORMAL)\n\t\tbuspirate_set_speed(buspirate_fd, SERIAL_FAST);\n\n\tLOG_INFO(\"Buspirate %s Interface ready!\", swd_mode ? \"SWD\" : \"JTAG\");\n\n\tif (!swd_mode)\n\t\tbuspirate_tap_init();\n\n\tbuspirate_set_mode(buspirate_fd, buspirate_pinmode);\n\tbuspirate_set_feature(buspirate_fd, FEATURE_VREG,\n\t\t(buspirate_vreg == 1) ? ACTION_ENABLE : ACTION_DISABLE);\n\tbuspirate_set_feature(buspirate_fd, FEATURE_PULLUP,\n\t\t(buspirate_pullup == 1) ? ACTION_ENABLE : ACTION_DISABLE);\n\tbuspirate_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int buspirate_quit(void)\n{\n\tLOG_INFO(\"Shutting down buspirate.\");\n\tbuspirate_set_mode(buspirate_fd, MODE_HIZ);\n\tbuspirate_set_speed(buspirate_fd, SERIAL_NORMAL);\n\n\tbuspirate_jtag_reset(buspirate_fd);\n\n\tbuspirate_serial_close(buspirate_fd);\n\n\tfree(buspirate_port);\n\tbuspirate_port = NULL;\n\treturn ERROR_OK;\n}\n\n/* openocd command interface */\nCOMMAND_HANDLER(buspirate_handle_adc_command)\n{\n\tif (buspirate_fd == -1)\n\t\treturn ERROR_OK;\n\n\t/* unavailable in SWD mode */\n\tif (swd_mode)\n\t\treturn ERROR_OK;\n\n\t/* send the command */\n\tbuspirate_jtag_get_adcs(buspirate_fd);\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_vreg_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (atoi(CMD_ARGV[0]) == 1)\n\t\tbuspirate_vreg = 1;\n\telse if (atoi(CMD_ARGV[0]) == 0)\n\t\tbuspirate_vreg = 0;\n\telse\n\t\tLOG_ERROR(\"usage: buspirate_vreg <1|0>\");\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_pullup_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (atoi(CMD_ARGV[0]) == 1)\n\t\tbuspirate_pullup = 1;\n\telse if (atoi(CMD_ARGV[0]) == 0)\n\t\tbuspirate_pullup = 0;\n\telse\n\t\tLOG_ERROR(\"usage: buspirate_pullup <1|0>\");\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_led_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (atoi(CMD_ARGV[0]) == 1) {\n\t\t/* enable led */\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_LED,\n\t\t\t\tACTION_ENABLE);\n\t} else if (atoi(CMD_ARGV[0]) == 0) {\n\t\t/* disable led */\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_LED,\n\t\t\t\tACTION_DISABLE);\n\t} else {\n\t\tLOG_ERROR(\"usage: buspirate_led <1|0>\");\n\t}\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_mode_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGV[0][0] == 'n')\n\t\tbuspirate_pinmode = MODE_JTAG;\n\telse if (CMD_ARGV[0][0] == 'o')\n\t\tbuspirate_pinmode = MODE_JTAG_OD;\n\telse\n\t\tLOG_ERROR(\"usage: buspirate_mode <normal|open-drain>\");\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_speed_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGV[0][0] == 'n')\n\t\tbuspirate_baudrate = SERIAL_NORMAL;\n\telse if (CMD_ARGV[0][0] == 'f')\n\t\tbuspirate_baudrate = SERIAL_FAST;\n\telse\n\t\tLOG_ERROR(\"usage: buspirate_speed <normal|fast>\");\n\n\treturn ERROR_OK;\n\n}\n\nCOMMAND_HANDLER(buspirate_handle_port_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!buspirate_port)\n\t\tbuspirate_port = strdup(CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n\n}\n\nstatic const struct command_registration buspirate_subcommand_handlers[] = {\n\t{\n\t\t.name = \"adc\",\n\t\t.handler = &buspirate_handle_adc_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"reads voltages on adc pins\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"vreg\",\n\t\t.usage = \"<1|0>\",\n\t\t.handler = &buspirate_handle_vreg_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"changes the state of voltage regulators\",\n\t},\n\t{\n\t\t.name = \"pullup\",\n\t\t.usage = \"<1|0>\",\n\t\t.handler = &buspirate_handle_pullup_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"changes the state of pullup\",\n\t},\n\t{\n\t\t.name = \"led\",\n\t\t.usage = \"<1|0>\",\n\t\t.handler = &buspirate_handle_led_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"changes the state of led\",\n\t},\n\t{\n\t\t.name = \"speed\",\n\t\t.usage = \"<normal|fast>\",\n\t\t.handler = &buspirate_handle_speed_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"speed of the interface\",\n\t},\n\t{\n\t\t.name = \"mode\",\n\t\t.usage = \"<normal|open-drain>\",\n\t\t.handler = &buspirate_handle_mode_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"pin mode of the interface\",\n\t},\n\t{\n\t\t.name = \"port\",\n\t\t.usage = \"/dev/ttyUSB0\",\n\t\t.handler = &buspirate_handle_port_command,\n\t\t.mode =\tCOMMAND_CONFIG,\n\t\t.help = \"name of the serial port to open\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration buspirate_command_handlers[] = {\n\t{\n\t\t.name = \"buspirate\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform buspirate management\",\n\t\t.chain = buspirate_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct swd_driver buspirate_swd = {\n\t.init = buspirate_swd_init,\n\t.switch_seq = buspirate_swd_switch_seq,\n\t.read_reg = buspirate_swd_read_reg,\n\t.write_reg = buspirate_swd_write_reg,\n\t.run = buspirate_swd_run_queue,\n};\n\nstatic const char * const buspirate_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface buspirate_interface = {\n\t.execute_queue = buspirate_execute_queue,\n};\n\nstruct adapter_driver buspirate_adapter_driver = {\n\t.name = \"buspirate\",\n\t.transports = buspirate_transports,\n\t.commands = buspirate_command_handlers,\n\n\t.init = buspirate_init,\n\t.quit = buspirate_quit,\n\t.reset = buspirate_reset,\n\n\t.jtag_ops = &buspirate_interface,\n\t.swd_ops = &buspirate_swd,\n};\n\n/*************** jtag execute commands **********************/\nstatic void buspirate_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void buspirate_state_move(void)\n{\n\tint i = 0, tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(),\n\t\t\ttap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(),\n\t\t\ttap_get_end_state());\n\n\tfor (i = 0; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\tbuspirate_tap_append(tms, 0);\n\t}\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void buspirate_path_move(int num_states, tap_state_t *path)\n{\n\tint i;\n\n\tfor (i = 0; i < num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), false) == path[i]) {\n\t\t\tbuspirate_tap_append(0, 0);\n\t\t} else if (tap_state_transition(tap_get_state(), true)\n\t\t\t\t== path[i]) {\n\t\t\tbuspirate_tap_append(1, 0);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid \"\n\t\t\t\t\"TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void buspirate_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tbuspirate_end_state(TAP_IDLE);\n\t\tbuspirate_state_move();\n\t}\n\n\tfor (i = 0; i < num_cycles; i++)\n\t\tbuspirate_tap_append(0, 0);\n\n\tLOG_DEBUG_IO(\"runtest: cur_state %s end_state %s\",\n\t\t\ttap_state_name(tap_get_state()),\n\t\t\ttap_state_name(tap_get_end_state()));\n\n\t/* finish in end_state */\n\tbuspirate_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tbuspirate_state_move();\n}\n\nstatic void buspirate_scan(bool ir_scan, enum scan_type type,\n\tuint8_t *buffer, int scan_size, struct scan_command *command)\n{\n\ttap_state_t saved_end_state;\n\n\tbuspirate_tap_make_space(1, scan_size+8);\n\t/* is 8 correct ? (2 moves = 16) */\n\n\tsaved_end_state = tap_get_end_state();\n\n\tbuspirate_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\n\t/* Only move if we're not already there */\n\tif (tap_get_state() != tap_get_end_state())\n\t\tbuspirate_state_move();\n\n\tbuspirate_tap_append_scan(scan_size, buffer, command);\n\n\t/* move to PAUSE */\n\tbuspirate_tap_append(0, 0);\n\n\t/* restore the saved state */\n\tbuspirate_end_state(saved_end_state);\n\ttap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tbuspirate_state_move();\n}\n\nstatic void buspirate_stableclocks(int num_cycles)\n{\n\tint i;\n\tint tms = (tap_get_state() == TAP_RESET ? 1 : 0);\n\n\tbuspirate_tap_make_space(0, num_cycles);\n\n\tfor (i = 0; i < num_cycles; i++)\n\t\tbuspirate_tap_append(tms, 0);\n}\n\n/************************* TAP related stuff **********/\n\n/* This buffer size matches the maximum CMD_TAP_SHIFT bit length in the Bus Pirate firmware,\n   look for constant 0x2000 in OpenOCD.c . */\n#define BUSPIRATE_BUFFER_SIZE 1024\n\n/* The old value of 32 scans was not enough to achieve near 100% utilisation ratio\n   for the current BUSPIRATE_BUFFER_SIZE value of 1024.\n   With 128 scans I am getting full USB 2.0 high speed packets (512 bytes long) when\n   using the JtagDue firmware on the Arduino Due instead of the Bus Pirate, which\n   amounts approximately to a 10% overall speed gain. Bigger packets should also\n   benefit the Bus Pirate, but the speed difference is much smaller.\n   Unfortunately, each 512-byte packet is followed by a 329-byte one, which is not ideal.\n   However, increasing BUSPIRATE_BUFFER_SIZE for the benefit of the JtagDue would\n   make it incompatible with the Bus Pirate firmware. */\n#define BUSPIRATE_MAX_PENDING_SCANS 128\n\nstatic uint8_t tms_chain[BUSPIRATE_BUFFER_SIZE]; /* send */\nstatic uint8_t tdi_chain[BUSPIRATE_BUFFER_SIZE]; /* send */\nstatic int tap_chain_index;\n\nstruct pending_scan_result /* this was stolen from arm-jtag-ew */\n{\n\tint first; /* First bit position in tdo_buffer to read */\n\tint length; /* Number of bits to read */\n\tstruct scan_command *command; /* Corresponding scan command */\n\tuint8_t *buffer;\n};\n\nstatic struct pending_scan_result\ntap_pending_scans[BUSPIRATE_MAX_PENDING_SCANS];\nstatic int tap_pending_scans_num;\n\nstatic void buspirate_tap_init(void)\n{\n\ttap_chain_index = 0;\n\ttap_pending_scans_num = 0;\n}\n\nstatic int buspirate_tap_execute(void)\n{\n\tuint8_t tmp[4096];\n\tuint8_t *in_buf;\n\tint i;\n\tint fill_index = 0;\n\tint ret;\n\tint bytes_to_send;\n\n\tif (tap_chain_index <= 0)\n\t\treturn ERROR_OK;\n\n\tLOG_DEBUG(\"executing tap num bits = %i scans = %i\",\n\t\t\ttap_chain_index, tap_pending_scans_num);\n\n\tbytes_to_send = DIV_ROUND_UP(tap_chain_index, 8);\n\n\ttmp[0] = CMD_TAP_SHIFT; /* this command expects number of bits */\n\ttmp[1] = tap_chain_index >> 8;  /* high */\n\ttmp[2] = tap_chain_index;  /* low */\n\n\tfill_index = CMD_TAP_SHIFT_HEADER_LEN;\n\tfor (i = 0; i < bytes_to_send; i++) {\n\t\ttmp[fill_index] = tdi_chain[i];\n\t\tfill_index++;\n\t\ttmp[fill_index] = tms_chain[i];\n\t\tfill_index++;\n\t}\n\n\t/* jlink.c calls the routine below, which may be useful for debugging purposes.\n\t   For example, enabling this allows you to compare the log outputs from jlink.c\n\t   and from this module for JTAG development or troubleshooting purposes. */\n\tif (false) {\n\t\tlast_tap_state = jtag_debug_state_machine(tms_chain, tdi_chain,\n\t\t\t\t\t\t\t\t\t\t\t\t  tap_chain_index, last_tap_state);\n\t}\n\n\tret = buspirate_serial_write(buspirate_fd, tmp, CMD_TAP_SHIFT_HEADER_LEN + bytes_to_send*2);\n\tif (ret != bytes_to_send*2+CMD_TAP_SHIFT_HEADER_LEN) {\n\t\tLOG_ERROR(\"error writing :(\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tret = buspirate_serial_read(buspirate_fd, tmp, bytes_to_send + CMD_TAP_SHIFT_HEADER_LEN);\n\tif (ret != bytes_to_send + CMD_TAP_SHIFT_HEADER_LEN) {\n\t\tLOG_ERROR(\"error reading\");\n\t\treturn ERROR_FAIL;\n\t}\n\tin_buf = (uint8_t *)(&tmp[CMD_TAP_SHIFT_HEADER_LEN]);\n\n\t/* parse the scans */\n\tfor (i = 0; i < tap_pending_scans_num; i++) {\n\t\tuint8_t *buffer = tap_pending_scans[i].buffer;\n\t\tint length = tap_pending_scans[i].length;\n\t\tint first = tap_pending_scans[i].first;\n\t\tstruct scan_command *command = tap_pending_scans[i].command;\n\n\t\t/* copy bits from buffer */\n\t\tbuf_set_buf(in_buf, first, buffer, 0, length);\n\n\t\t/* return buffer to higher level */\n\t\tif (jtag_read_buffer(buffer, command) != ERROR_OK) {\n\t\t\tbuspirate_tap_init();\n\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t}\n\n\t\tfree(buffer);\n\t}\n\tbuspirate_tap_init();\n\treturn ERROR_OK;\n}\n\nstatic void buspirate_tap_make_space(int scans, int bits)\n{\n\tint have_scans = BUSPIRATE_MAX_PENDING_SCANS - tap_pending_scans_num;\n\tint have_bits = BUSPIRATE_BUFFER_SIZE * 8 - tap_chain_index;\n\n\tif ((have_scans < scans) || (have_bits < bits))\n\t\tbuspirate_tap_execute();\n}\n\nstatic void buspirate_tap_append(int tms, int tdi)\n{\n\tint chain_index;\n\n\tbuspirate_tap_make_space(0, 1);\n\tchain_index = tap_chain_index / 8;\n\n\tif (chain_index < BUSPIRATE_BUFFER_SIZE) {\n\t\tint bit_index = tap_chain_index % 8;\n\t\tuint8_t bit = 1 << bit_index;\n\n\t\tif (bit_index == 0) {\n\t\t\t/* Let's say that the TAP shift operation wants to shift 9 bits,\n\t\t\t   so we will be sending to the Bus Pirate a bit count of 9 but still\n\t\t\t   full 16 bits (2 bytes) of shift data.\n\t\t\t   If we don't clear all bits at this point, the last 7 bits will contain\n\t\t\t   random data from the last buffer contents, which is not pleasant to the eye.\n\t\t\t   Besides, the Bus Pirate (or some clone) may want to assert in debug builds\n\t\t\t   that, after consuming all significant data bits, the rest of them are zero.\n\t\t\t   Therefore, for aesthetic and for assert purposes, we clear all bits below. */\n\t\t\ttms_chain[chain_index] = 0;\n\t\t\ttdi_chain[chain_index] = 0;\n\t\t}\n\n\t\tif (tms)\n\t\t\ttms_chain[chain_index] |= bit;\n\t\telse\n\t\t\ttms_chain[chain_index] &= ~bit;\n\n\t\tif (tdi)\n\t\t\ttdi_chain[chain_index] |= bit;\n\t\telse\n\t\t\ttdi_chain[chain_index] &= ~bit;\n\n\t\ttap_chain_index++;\n\t} else {\n\t\tLOG_ERROR(\"tap_chain overflow, bad things will happen\");\n\t\t/* Exit abruptly, like jlink.c does. After a buffer overflow we don't want\n\t\t   to carry on, as data will be corrupt. Another option would be to return\n\t\t   some error code at this point. */\n\t\texit(-1);\n\t}\n}\n\nstatic void buspirate_tap_append_scan(int length, uint8_t *buffer,\n\t\tstruct scan_command *command)\n{\n\tint i;\n\ttap_pending_scans[tap_pending_scans_num].length = length;\n\ttap_pending_scans[tap_pending_scans_num].buffer = buffer;\n\ttap_pending_scans[tap_pending_scans_num].command = command;\n\ttap_pending_scans[tap_pending_scans_num].first = tap_chain_index;\n\n\tfor (i = 0; i < length; i++) {\n\t\tint tms = (i < length-1 ? 0 : 1);\n\t\tint tdi = (buffer[i/8] >> (i%8)) & 1;\n\t\tbuspirate_tap_append(tms, tdi);\n\t}\n\ttap_pending_scans_num++;\n}\n\n/*************** wrapper functions *********************/\n\n/* (1) assert or (0) deassert reset lines */\nstatic int buspirate_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (trst)\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_TRST, ACTION_DISABLE);\n\telse\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_TRST, ACTION_ENABLE);\n\n\tif (srst)\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_DISABLE);\n\telse\n\t\tbuspirate_set_feature(buspirate_fd, FEATURE_SRST, ACTION_ENABLE);\n\n\treturn ERROR_OK;\n}\n\nstatic void buspirate_set_feature(int fd, char feat, char action)\n{\n\tif (swd_mode)\n\t\tbuspirate_swd_set_feature(fd, feat, action);\n\telse\n\t\tbuspirate_jtag_set_feature(fd, feat, action);\n}\n\nstatic void buspirate_set_mode(int fd, char mode)\n{\n\tif (swd_mode)\n\t\tbuspirate_swd_set_mode(fd, mode);\n\telse\n\t\tbuspirate_jtag_set_mode(fd, mode);\n}\n\nstatic void buspirate_set_speed(int fd, char speed)\n{\n\tif (swd_mode)\n\t\tbuspirate_swd_set_speed(fd, speed);\n\telse\n\t\tbuspirate_jtag_set_speed(fd, speed);\n}\n\n\n/*************** swd lowlevel functions ********************/\n\nstatic void buspirate_swd_set_speed(int fd, char speed)\n{\n\tint  ret;\n\tuint8_t tmp[1];\n\n\tLOG_DEBUG(\"Buspirate speed setting in SWD mode defaults to 400 kHz\");\n\n\t/* speed settings */\n\ttmp[0] = CMD_RAW_SPEED | SPEED_RAW_400_KHZ;\n\tbuspirate_serial_write(fd, tmp, 1);\n\tret = buspirate_serial_read(fd, tmp, 1);\n\tif (ret != 1) {\n\t\tLOG_ERROR(\"Buspirate did not answer correctly\");\n\t\texit(-1);\n\t}\n\tif (tmp[0] != 1) {\n\t\tLOG_ERROR(\"Buspirate did not reply as expected to the speed change command\");\n\t\texit(-1);\n\t}\n}\n\nstatic void buspirate_swd_set_mode(int fd, char mode)\n{\n\tint ret;\n\tuint8_t tmp[1];\n\n\t/* raw-wire mode configuration */\n\tif (mode == MODE_HIZ)\n\t\ttmp[0] = CMD_RAW_MODE | CMD_RAW_CONFIG_LSB;\n\telse\n\t\ttmp[0] = CMD_RAW_MODE | CMD_RAW_CONFIG_LSB | CMD_RAW_CONFIG_3V3;\n\n\tbuspirate_serial_write(fd, tmp, 1);\n\tret = buspirate_serial_read(fd, tmp, 1);\n\tif (ret != 1) {\n\t\tLOG_ERROR(\"Buspirate did not answer correctly\");\n\t\texit(-1);\n\t}\n\tif (tmp[0] != 1) {\n\t\tLOG_ERROR(\"Buspirate did not reply as expected to the configure command\");\n\t\texit(-1);\n\t}\n}\n\nstatic void buspirate_swd_set_feature(int fd, char feat, char action)\n{\n\tint  ret;\n\tuint8_t tmp[1];\n\n\tswitch (feat) {\n\t\tcase FEATURE_TRST:\n\t\t\tLOG_DEBUG(\"Buspirate TRST feature not available in SWD mode\");\n\t\t\treturn;\n\t\tcase FEATURE_LED:\n\t\t\tLOG_ERROR(\"Buspirate LED feature not available in SWD mode\");\n\t\t\treturn;\n\t\tcase FEATURE_SRST:\n\t\t\tswd_features = (action == ACTION_ENABLE) ? swd_features | 0x02 : swd_features & 0x0D;\n\t\t\tbreak;\n\t\tcase FEATURE_PULLUP:\n\t\t\tswd_features = (action == ACTION_ENABLE) ? swd_features | 0x04 : swd_features & 0x0B;\n\t\t\tbreak;\n\t\tcase FEATURE_VREG:\n\t\t\tswd_features = (action == ACTION_ENABLE) ? swd_features | 0x08 : swd_features & 0x07;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_DEBUG(\"Buspirate unknown feature %d\", feat);\n\t\t\treturn;\n\t}\n\n\ttmp[0] = CMD_RAW_PERIPH | swd_features;\n\tbuspirate_serial_write(fd, tmp, 1);\n\tret = buspirate_serial_read(fd, tmp, 1);\n\tif (ret != 1) {\n\t\tLOG_DEBUG(\"Buspirate feature %d not supported in SWD mode\", feat);\n\t} else if (tmp[0] != 1) {\n\t\tLOG_ERROR(\"Buspirate did not reply as expected to the configure command\");\n\t\texit(-1);\n\t}\n}\n\n/*************** jtag lowlevel functions ********************/\nstatic void buspirate_bbio_enable(int fd)\n{\n\tint ret;\n\tchar command;\n\tconst char *mode_answers[2] = { \"OCD1\", \"RAW1\" };\n\tconst char *correct_ans     = NULL;\n\tuint8_t tmp[21] = { [0 ... 20] = 0x00 };\n\tint done = 0;\n\tint cmd_sent = 0;\n\n\tif (swd_mode) {\n\t\tcommand     = CMD_ENTER_RWIRE;\n\t\tcorrect_ans = mode_answers[1];\n\t} else {\n\t\tcommand     = CMD_ENTER_OOCD;\n\t\tcorrect_ans = mode_answers[0];\n\t}\n\n\tLOG_DEBUG(\"Entering binary mode, that is %s\", correct_ans);\n\tbuspirate_serial_write(fd, tmp, 20);\n\tusleep(10000);\n\n\t/* reads 1 to n \"BBIO1\"s and one \"OCD1\" or \"RAW1\" */\n\twhile (!done) {\n\t\tret = buspirate_serial_read(fd, tmp, 4);\n\t\tif (ret != 4) {\n\t\t\tLOG_ERROR(\"Buspirate error. Is binary\"\n\t\t\t\t\"/OpenOCD support enabled?\");\n\t\t\texit(-1);\n\t\t}\n\t\tif (strncmp((char *)tmp, \"BBIO\", 4) == 0) {\n\t\t\tret = buspirate_serial_read(fd, tmp, 1);\n\t\t\tif (ret != 1) {\n\t\t\t\tLOG_ERROR(\"Buspirate did not answer correctly! \"\n\t\t\t\t\t\"Do you have correct firmware?\");\n\t\t\t\texit(-1);\n\t\t\t}\n\t\t\tif (tmp[0] != '1') {\n\t\t\t\tLOG_ERROR(\"Unsupported binary protocol\");\n\t\t\t\texit(-1);\n\t\t\t}\n\t\t\tif (cmd_sent == 0) {\n\t\t\t\tcmd_sent = 1;\n\t\t\t\ttmp[0] = command;\n\t\t\t\tret = buspirate_serial_write(fd, tmp, 1);\n\t\t\t\tif (ret != 1) {\n\t\t\t\t\tLOG_ERROR(\"error reading\");\n\t\t\t\t\texit(-1);\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (strncmp((char *)tmp, correct_ans, 4) == 0)\n\t\t\tdone = 1;\n\t\telse {\n\t\t\tLOG_ERROR(\"Buspirate did not answer correctly! \"\n\t\t\t\t\"Do you have correct firmware?\");\n\t\t\texit(-1);\n\t\t}\n\t}\n\n}\n\nstatic void buspirate_jtag_reset(int fd)\n{\n\tuint8_t tmp[5];\n\n\ttmp[0] = 0x00; /* exit OCD1 mode */\n\tbuspirate_serial_write(fd, tmp, 1);\n\tusleep(10000);\n\t/* We ignore the return value here on purpose, nothing we can do */\n\tbuspirate_serial_read(fd, tmp, 5);\n\tif (strncmp((char *)tmp, \"BBIO1\", 5) == 0) {\n\t\ttmp[0] = 0x0F; /*  reset BP */\n\t\tbuspirate_serial_write(fd, tmp, 1);\n\t} else\n\t\tLOG_ERROR(\"Unable to restart buspirate!\");\n}\n\nstatic void buspirate_jtag_set_speed(int fd, char speed)\n{\n\tint ret;\n\tuint8_t tmp[2];\n\tuint8_t ack[2];\n\n\tack[0] = 0xAA;\n\tack[1] = 0x55;\n\n\ttmp[0] = CMD_UART_SPEED;\n\ttmp[1] = speed;\n\tbuspirate_jtag_command(fd, tmp, 2);\n\n\t/* here the adapter changes speed, we need follow */\n\tif (-1 == buspirate_serial_setspeed(fd, speed, NORMAL_TIMEOUT)) {\n\t\tLOG_ERROR(\"Error configuring the serial port.\");\n\t\texit(-1);\n\t}\n\n\tbuspirate_serial_write(fd, ack, 2);\n\tret = buspirate_serial_read(fd, tmp, 2);\n\tif (ret != 2) {\n\t\tLOG_ERROR(\"Buspirate did not ack speed change\");\n\t\texit(-1);\n\t}\n\tif ((tmp[0] != CMD_UART_SPEED) || (tmp[1] != speed)) {\n\t\tLOG_ERROR(\"Buspirate did not reply as expected to the speed change command\");\n\t\texit(-1);\n\t}\n\tLOG_INFO(\"Buspirate switched to %s mode\",\n\t\t(speed == SERIAL_NORMAL) ? \"normal\" : \"FAST\");\n}\n\n\nstatic void buspirate_jtag_set_mode(int fd, char mode)\n{\n\tuint8_t tmp[2];\n\ttmp[0] = CMD_PORT_MODE;\n\ttmp[1] = mode;\n\tbuspirate_jtag_command(fd, tmp, 2);\n}\n\nstatic void buspirate_jtag_set_feature(int fd, char feat, char action)\n{\n\tuint8_t tmp[3];\n\ttmp[0] = CMD_FEATURE;\n\ttmp[1] = feat;   /* what */\n\ttmp[2] = action; /* action */\n\tbuspirate_jtag_command(fd, tmp, 3);\n}\n\nstatic void buspirate_jtag_get_adcs(int fd)\n{\n\tuint8_t tmp[10];\n\tuint16_t a, b, c, d;\n\ttmp[0] = CMD_READ_ADCS;\n\tbuspirate_jtag_command(fd, tmp, 1);\n\ta = tmp[2] << 8 | tmp[3];\n\tb = tmp[4] << 8 | tmp[5];\n\tc = tmp[6] << 8 | tmp[7];\n\td = tmp[8] << 8 | tmp[9];\n\n\tLOG_INFO(\"ADC: ADC_Pin = %.02f VPullup = %.02f V33 = %.02f \"\n\t\t\"V50 = %.02f\",\n\t\t((float)a)/155.1515, ((float)b)/155.1515,\n\t\t((float)c)/155.1515, ((float)d)/155.1515);\n}\n\nstatic unsigned char buspirate_jtag_command(int fd,\n\t\tuint8_t *cmd, int cmdlen)\n{\n\tint res;\n\tint len = 0;\n\n\tres = buspirate_serial_write(fd, cmd, cmdlen);\n\n\tif ((cmd[0] == CMD_UART_SPEED)\n\t\t\t\t|| (cmd[0] == CMD_PORT_MODE)\n\t\t\t\t|| (cmd[0] == CMD_FEATURE)\n\t\t\t\t|| (cmd[0] == CMD_JTAG_SPEED))\n\t\treturn 1;\n\n\tif (res == cmdlen) {\n\t\tswitch (cmd[0]) {\n\t\tcase CMD_READ_ADCS:\n\t\t\tlen = 10; /* 2*sizeof(char)+4*sizeof(uint16_t) */\n\t\t\tbreak;\n\t\tcase CMD_TAP_SHIFT:\n\t\t\tlen = cmdlen;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_INFO(\"Wrong !\");\n\t\t}\n\t\tres =  buspirate_serial_read(fd, cmd, len);\n\t\tif (res > 0)\n\t\t\treturn (unsigned char)cmd[1];\n\t\telse\n\t\t\treturn -1;\n\t} else\n\t\treturn -1;\n\treturn 0;\n}\n\n/* low level serial port */\n/* TODO add support for WIN32 and others ! */\nstatic int buspirate_serial_open(char *port)\n{\n\tint fd;\n\tfd = open(buspirate_port, O_RDWR | O_NOCTTY | O_NDELAY);\n\treturn fd;\n}\n\n\n/* Returns -1 on error. */\n\nstatic int buspirate_serial_setspeed(int fd, char speed, cc_t timeout)\n{\n\tstruct termios t_opt;\n\tspeed_t baud = (speed == SERIAL_FAST) ? B1000000 : B115200;\n\n\t/* set the serial port parameters */\n\tfcntl(fd, F_SETFL, 0);\n\tif (tcgetattr(fd, &t_opt) != 0)\n\t\treturn -1;\n\n\tif (cfsetispeed(&t_opt, baud) != 0)\n\t\treturn -1;\n\n\tif (cfsetospeed(&t_opt, baud) != 0)\n\t\treturn -1;\n\n\tt_opt.c_cflag |= (CLOCAL | CREAD);\n\tt_opt.c_cflag &= ~PARENB;\n\tt_opt.c_cflag &= ~CSTOPB;\n\tt_opt.c_cflag &= ~CSIZE;\n\tt_opt.c_cflag |= CS8;\n\tt_opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);\n\n\t/* The serial port may have been configured for human interaction with\n\t   the Bus Pirate console, but OpenOCD is going to use a binary protocol,\n\t   so make sure to turn off any CR/LF translation and the like. */\n\tt_opt.c_iflag &= ~(IXON | IXOFF | IXANY | INLCR | ICRNL);\n\n\tt_opt.c_oflag &= ~OPOST;\n\tt_opt.c_cc[VMIN] = 0;\n\tt_opt.c_cc[VTIME] = timeout;\n\n\t/* Note that, in the past, TCSANOW was used below instead of TCSADRAIN,\n\t   and CMD_UART_SPEED did not work properly then, at least with\n\t   the Bus Pirate v3.5 (USB). */\n\tif (tcsetattr(fd, TCSADRAIN, &t_opt) != 0) {\n\t\t/* According to the Linux documentation, this is actually not enough\n\t\t   to detect errors, you need to call tcgetattr() and check that\n\t\t   all changes have been performed successfully. */\n\t\treturn -1;\n\t}\n\n\treturn 0;\n}\n\nstatic int buspirate_serial_write(int fd, uint8_t *buf, int size)\n{\n\tint ret = 0;\n\n\tret = write(fd, buf, size);\n\n\tLOG_DEBUG(\"size = %d ret = %d\", size, ret);\n\tbuspirate_print_buffer(buf, size);\n\n\tif (ret != size)\n\t\tLOG_ERROR(\"Error sending data\");\n\n\treturn ret;\n}\n\nstatic int buspirate_serial_read(int fd, uint8_t *buf, int size)\n{\n\tint len = 0;\n\tint ret = 0;\n\tint timeout = 0;\n\n\twhile (len < size) {\n\t\tret = read(fd, buf+len, size-len);\n\t\tif (ret == -1)\n\t\t\treturn -1;\n\n\t\tif (ret == 0) {\n\t\t\ttimeout++;\n\n\t\t\tif (timeout >= 10)\n\t\t\t\tbreak;\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tlen += ret;\n\t}\n\n\tLOG_DEBUG(\"should have read = %d actual size = %d\", size, len);\n\tbuspirate_print_buffer(buf, len);\n\n\tif (len != size)\n\t\tLOG_ERROR(\"Error reading data\");\n\n\treturn len;\n}\n\nstatic void buspirate_serial_close(int fd)\n{\n\tclose(fd);\n}\n\n#define LINE_SIZE      81\n#define BYTES_PER_LINE 16\nstatic void buspirate_print_buffer(uint8_t *buf, int size)\n{\n\tchar line[LINE_SIZE];\n\tchar tmp[10];\n\tint offset = 0;\n\n\tline[0] = 0;\n\twhile (offset < size) {\n\t\tsnprintf(tmp, 5, \"%02x \", (uint8_t)buf[offset]);\n\t\toffset++;\n\n\t\tstrcat(line, tmp);\n\n\t\tif (offset % BYTES_PER_LINE == 0) {\n\t\t\tLOG_DEBUG(\"%s\", line);\n\t\t\tline[0] = 0;\n\t\t}\n\t}\n\n\tif (line[0] != 0)\n\t\tLOG_DEBUG(\"%s\", line);\n}\n\n/************************* SWD related stuff **********/\n\nstatic int buspirate_swd_init(void)\n{\n\tLOG_INFO(\"Buspirate SWD mode enabled\");\n\tswd_mode = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int buspirate_swd_switch_seq(enum swd_special_seq seq)\n{\n\tconst uint8_t *sequence;\n\tint sequence_len;\n\tuint32_t no_bytes, sequence_offset;\n\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG(\"SWD line reset\");\n\t\tsequence = swd_seq_line_reset;\n\t\tsequence_len = DIV_ROUND_UP(swd_seq_line_reset_len, 8);\n\t\tbreak;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\tsequence = swd_seq_jtag_to_swd;\n\t\tsequence_len = DIV_ROUND_UP(swd_seq_jtag_to_swd_len, 8);\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\tsequence = swd_seq_swd_to_jtag;\n\t\tsequence_len = DIV_ROUND_UP(swd_seq_swd_to_jtag_len, 8);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tno_bytes = sequence_len;\n\tsequence_offset = 0;\n\n\twhile (no_bytes) {\n\t\tuint8_t tmp[17];\n\t\tuint32_t to_send;\n\n\t\tto_send = no_bytes > 16 ? 16 : no_bytes;\n\n\t\ttmp[0] = 0x10 + ((to_send - 1) & 0x0F);\n\t\tmemcpy(tmp + 1, &sequence[sequence_offset], to_send);\n\n\t\tbuspirate_serial_write(buspirate_fd, tmp, to_send + 1);\n\t\tbuspirate_serial_read(buspirate_fd, tmp, to_send + 1);\n\n\t\tno_bytes -= to_send;\n\t\tsequence_offset += to_send;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic uint8_t buspirate_swd_write_header(uint8_t cmd)\n{\n\tuint8_t tmp[8];\n\tint  to_send;\n\n\ttmp[0] = 0x10; /* bus pirate: send 1 byte */\n\ttmp[1] = cmd;  /* swd cmd */\n\ttmp[2] = 0x07; /* ack __x */\n\ttmp[3] = 0x07; /* ack _x_ */\n\ttmp[4] = 0x07; /* ack x__ */\n\ttmp[5] = 0x07; /* write mode trn_1 */\n\ttmp[6] = 0x07; /* write mode trn_2 */\n\n\tto_send = ((cmd & SWD_CMD_RNW) == 0) ? 7 : 5;\n\tbuspirate_serial_write(buspirate_fd, tmp, to_send);\n\n\t/* read ack */\n\tbuspirate_serial_read(buspirate_fd, tmp, 2); /* drop pirate command ret vals */\n\tbuspirate_serial_read(buspirate_fd, tmp, to_send - 2); /* ack bits */\n\n\treturn tmp[2] << 2 | tmp[1] << 1 | tmp[0];\n}\n\nstatic void buspirate_swd_idle_clocks(uint32_t no_bits)\n{\n\tuint32_t no_bytes;\n\tuint8_t tmp[20];\n\n\tno_bytes = (no_bits + 7) / 8;\n\tmemset(tmp + 1, 0x00, sizeof(tmp) - 1);\n\n\t/* unfortunately bus pirate misbehaves when clocks are sent in parts\n\t * so we need to limit at 128 clock cycles\n\t */\n\tif (no_bytes > 16)\n\t\tno_bytes = 16;\n\n\twhile (no_bytes) {\n\t\tuint8_t to_send = no_bytes > 16 ? 16 : no_bytes;\n\t\ttmp[0] = 0x10 + ((to_send - 1) & 0x0F);\n\n\t\tbuspirate_serial_write(buspirate_fd, tmp, to_send + 1);\n\t\tbuspirate_serial_read(buspirate_fd, tmp, to_send + 1);\n\n\t\tno_bytes -= to_send;\n\t}\n}\n\nstatic void buspirate_swd_clear_sticky_errors(void)\n{\n\tbuspirate_swd_write_reg(swd_cmd(false,  false, DP_ABORT),\n\t\tSTKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);\n}\n\nstatic void buspirate_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tuint8_t tmp[16];\n\n\tLOG_DEBUG(\"buspirate_swd_read_reg\");\n\tassert(cmd & SWD_CMD_RNW);\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skip buspirate_swd_read_reg because queued_retval=%d\", queued_retval);\n\t\treturn;\n\t}\n\n\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\tuint8_t ack = buspirate_swd_write_header(cmd);\n\n\t/* do a read transaction */\n\ttmp[0] = 0x06; /* 4 data bytes */\n\ttmp[1] = 0x06;\n\ttmp[2] = 0x06;\n\ttmp[3] = 0x06;\n\ttmp[4] = 0x07; /* parity bit */\n\ttmp[5] = 0x21; /* 2 turnaround clocks */\n\n\tbuspirate_serial_write(buspirate_fd, tmp, 6);\n\tbuspirate_serial_read(buspirate_fd, tmp, 6);\n\n\t/* store the data and parity */\n\tuint32_t data = (uint8_t) tmp[0];\n\tdata |= (uint8_t) tmp[1] << 8;\n\tdata |= (uint8_t) tmp[2] << 16;\n\tdata |= (uint8_t) tmp[3] << 24;\n\tint parity = tmp[4] ? 0x01 : 0x00;\n\n\tLOG_DEBUG(\"%s %s %s reg %X = %08\"PRIx32,\n\t\t\tack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t\tcmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\tcmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t(cmd & SWD_CMD_A32) >> 1,\n\t\t\tdata);\n\n\tswitch (ack) {\n\t case SWD_ACK_OK:\n\t\tif (parity != parity_u32(data)) {\n\t\t\tLOG_DEBUG(\"Read data parity mismatch %x %x\", parity, parity_u32(data));\n\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\treturn;\n\t\t}\n\t\tif (value)\n\t\t\t*value = data;\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\tbuspirate_swd_idle_clocks(ap_delay_clk);\n\t\treturn;\n\t case SWD_ACK_WAIT:\n\t\tLOG_DEBUG(\"SWD_ACK_WAIT\");\n\t\tbuspirate_swd_clear_sticky_errors();\n\t\treturn;\n\t case SWD_ACK_FAULT:\n\t\tLOG_DEBUG(\"SWD_ACK_FAULT\");\n\t\tqueued_retval = ack;\n\t\treturn;\n\t default:\n\t\tLOG_DEBUG(\"No valid acknowledge: ack=%d\", ack);\n\t\tqueued_retval = ack;\n\t\treturn;\n\t}\n}\n\nstatic void buspirate_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tuint8_t tmp[16];\n\n\tLOG_DEBUG(\"buspirate_swd_write_reg\");\n\tassert(!(cmd & SWD_CMD_RNW));\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skip buspirate_swd_write_reg because queued_retval=%d\", queued_retval);\n\t\treturn;\n\t}\n\n\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\tuint8_t ack = buspirate_swd_write_header(cmd);\n\n\t/* do a write transaction */\n\ttmp[0] = 0x10 + ((4 + 1 - 1) & 0xF); /* bus pirate: send 4+1 bytes */\n\tbuf_set_u32((uint8_t *) tmp + 1, 0, 32, value);\n\t/* write sequence ends with parity bit and 7 idle ticks */\n\ttmp[5] = parity_u32(value) ? 0x01 : 0x00;\n\n\tbuspirate_serial_write(buspirate_fd, tmp, 6);\n\tbuspirate_serial_read(buspirate_fd, tmp, 6);\n\n\tLOG_DEBUG(\"%s %s %s reg %X = %08\"PRIx32,\n\t\t\tack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t\tcmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\tcmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t(cmd & SWD_CMD_A32) >> 1,\n\t\t\tvalue);\n\n\tswitch (ack) {\n\t case SWD_ACK_OK:\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\tbuspirate_swd_idle_clocks(ap_delay_clk);\n\t\treturn;\n\t case SWD_ACK_WAIT:\n\t\tLOG_DEBUG(\"SWD_ACK_WAIT\");\n\t\tbuspirate_swd_clear_sticky_errors();\n\t\treturn;\n\t case SWD_ACK_FAULT:\n\t\tLOG_DEBUG(\"SWD_ACK_FAULT\");\n\t\tqueued_retval = ack;\n\t\treturn;\n\t default:\n\t\tLOG_DEBUG(\"No valid acknowledge: ack=%d\", ack);\n\t\tqueued_retval = ack;\n\t\treturn;\n\t}\n}\n\nstatic int buspirate_swd_run_queue(void)\n{\n\tLOG_DEBUG(\"buspirate_swd_run_queue\");\n\t/* A transaction must be followed by another transaction or at least 8 idle cycles to\n\t * ensure that data is clocked through the AP. */\n\tbuspirate_swd_idle_clocks(8);\n\n\tint retval = queued_retval;\n\tqueued_retval = ERROR_OK;\n\tLOG_DEBUG(\"SWD queue return value: %02x\", retval);\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ch347.c",
    "content": "/***************************************************************************\n *   Driver for CH347-JTAG interface V1.1                                  *\n *                                                                         *\n *   Copyright (C) 2022 by oidcat.                                         *\n *   Author: oidcatiot@163.com                                             *\n *                                                                         *\n *   CH347 is a high-speed USB bus converter chip that provides UART, I2C  *\n *   and SPI synchronous serial ports and JTAG interface through USB bus.  *\n *                                                                         *\n *   The Jtag interface by CH347 can supports transmission frequency       *\n *   configuration up to 60MHz.                                            *\n *                                                                         *\n *   The USB2.0 to JTAG scheme based on CH347 can be used to build         *\n *   customized USB high-speed JTAG debugger and other products.           *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *            _____________                                                *\n *           |             |____JTAG/SWD (TDO,TDI,TMS,TCK,TRST)            *\n *      USB__|   CH347T/F  |                                               *\n *           |_____________|____UART(TXD1,RXD1,RTS1,CTS1,DTR1)             *\n *            ______|______                                                *\n *           |             |                                               *\n *           | 8 MHz XTAL  |                                               *\n *           |_____________|                                               *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if IS_CYGWIN == 1\n#include \"windows.h\"\n#undef LOG_ERROR\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <jtag/swd.h>\n#include <helper/time_support.h>\n#include <helper/replacements.h>\n#include <helper/list.h>\n#include <helper/binarybuffer.h>\n#include \"libusb_helper.h\"\n\n/* system includes */\n#include <stdlib.h>\n#include <string.h>\n#include <sys/time.h>\n#include <time.h>\n#include <unistd.h>\n#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)\n#define JTAGIO_STA_OUT_TDI  (0x10)\n#define JTAGIO_STA_OUT_TMS  (0x02)\n#define JTAGIO_STA_OUT_TCK  (0x01)\n#define JTAGIO_STA_OUT_TRST (0x20)\n#define JTAGIO_STA_OUT_SRST (0x40)\n#define TDI_H               JTAGIO_STA_OUT_TDI\n#define TDI_L               0\n#define TMS_H               JTAGIO_STA_OUT_TMS\n#define TMS_L               0\n#define TCK_H               JTAGIO_STA_OUT_TCK\n#define TCK_L               0\n#define TRST_H              JTAGIO_STA_OUT_TRST\n#define TRST_L              0\n#define SRST_H              JTAGIO_STA_OUT_SRST\n#define SRST_L              0\n\n#define KHZ(n) ((n)*UINT64_C(1000))\n#define MHZ(n) ((n)*UINT64_C(1000000))\n#define GHZ(n) ((n)*UINT64_C(1000000000))\n\n#define HW_TDO_BUF_SIZE              4096\n#define SF_PACKET_BUF_SIZE           51200 /* Command packet length */\n#define UCMDPKT_DATA_MAX_BYTES_USBHS 507   /* The data length contained in each\n\t\t\t\t\t      command packet during USB\n\t\t\t\t\t      high-speed operation */\n#define USBC_PACKET_USBHS            512   /* Maximum data length per packet at\n\t\t\t\t\t      USB high speed */\n#define USBC_PACKET_USBHS_SINGLE     510   /* usb high speed max\n\t\t\t\t\t      package length */\n#define CH347_CMD_HEADER             3     /* Protocol header length */\n\n/* Protocol transmission format: CMD (1 byte)+Length (2 bytes)+Data */\n#define CH347_CMD_INFO_RD            0xCA /* Parameter acquisition, used to\n\t\t\t\t\t     obtain firmware version,\n\t\t\t\t\t     JTAG interface related parameters,\n\t\t\t\t\t     etc */\n#define CH347_CMD_JTAG_INIT          0xD0 /* JTAG Interface Initialization\n\t\t\t\t\t     Command */\n#define CH347_CMD_JTAG_BIT_OP        0xD1 /* JTAG interface pin bit control\n\t\t\t\t\t     command */\n#define CH347_CMD_JTAG_BIT_OP_RD     0xD2 /* JTAG interface pin bit control and\n\t\t\t\t\t     read commands */\n#define CH347_CMD_JTAG_DATA_SHIFT    0xD3 /* JTAG interface data shift\n\t\t\t\t\t     command */\n#define CH347_CMD_JTAG_DATA_SHIFT_RD 0xD4 /* JTAG interface data shift and read\n\t\t\t\t\t     command */\n/* SWD */\n#define CH347_CMD_SWD_INIT  0xE5 /* SWD Interface Initialization Command */\n#define CH347_CMD_SWD       0xE8\n#define CH347_CMD_SWD_REG_W 0xA0 /* SWD Interface write reg */\n#define CH347_CMD_SWD_SEQ_W 0xA1 /* SWD Interface write spec seq */\n#define CH347_CMD_SWD_REG_R 0xA2 /* SWD Interface read  reg */\n#define CH347_MAX_SEND_CMD  0X20 /* max send cmd number */\n#define CH347_MAX_SEND_BUF  0X200\n#define CH347_MAX_RECV_BUF  0X200\n#define BUILD_UINT16(loByte, hiByte)\t\t\t\t\t\\\n\t((uint16_t)(((loByte)&0x00FF) + (((hiByte)&0x00FF) << 8)))\n#pragma pack(1)\n\ntypedef unsigned char UCHAR;\n\ntypedef enum pack {\n\tSTANDARD_PACK = 0,\n\tLARGER_PACK = 1,\n} PACK_SIZE;\n\ntypedef struct _CH347_info /* Record the CH347 pin status */\n{\n\tint TMS;\n\tint TDI;\n\tint TCK;\n\tint TRST;\n\tint SRST;\n\n\tint buffer_idx;\n\tuint8_t buffer[SF_PACKET_BUF_SIZE];\n\n\tint len_idx;\n\tint len_value;\n\tuint8_t lastCmd;\n\n\tuint8_t read_buffer[SF_PACKET_BUF_SIZE];\n\tuint32_t read_idx;\n\tuint32_t read_count;\n\tstruct bit_copy_queue read_queue;\n\tPACK_SIZE pack_size;\n} _CH347_Info;\n\nint DevIsOpened; /* Whether the device is turned on */\nbool UsbHighDev = true;\nunsigned long USBC_PACKET;\n\ntypedef struct _CH347_SWD_IO {\n\tuint8_t usbcmd; /* 0xA0, 0xA1, 0xA2 */\n\tuint8_t cmd;\n\tuint32_t *dst;\n\tuint32_t value;\n\tstruct list_head list_entry;\n} CH347_SWD_IO, *PCH347_SWD_IO;\n\ntypedef struct _CH347_SWD_CONTEXT {\n\tuint8_t send_buf[CH347_MAX_SEND_BUF];\n\tuint8_t recv_buf[CH347_MAX_RECV_BUF];\n\tuint32_t send_len;\n\tuint32_t recv_len;\n\tuint32_t need_recv_len;\n\tint queued_retval;\n\tuint8_t sent_cmd_count;\n\tstruct list_head send_cmd_head;\n\tstruct list_head free_cmd_head;\n\tuint8_t *ch347_cmd_buf;\n} CH347_SWD_CONTEXT;\nstatic CH347_SWD_CONTEXT ch347_swd_context;\nstatic bool swd_mode = false;\nstatic int ch347_srst_enable(void);\n#pragma pack()\n#ifdef _WIN32\n#include <windows.h>\n\n//Device Information \ntypedef struct _DEV_INFOR{\n\tUCHAR    iIndex;                 // Current open number\n\tUCHAR    DevicePath[MAX_PATH];   // Device link name, used for CreateFile\n\tUCHAR    UsbClass;               // 0:CH347_USB_CH341, 2:CH347_USB_HID,3:CH347_USB_VCP\n\tUCHAR    FuncType;               // 0:CH347_FUNC_UART,1:CH347_FUNC_SPI_IIC,2:CH347_FUNC_JTAG_IIC\n\tCHAR     DeviceID[64];           // USB\\VID_xxxx&PID_xxxx\n\tUCHAR    ChipMode;               // Chip Mode, 0:Mode0(UART0/1); 1:Mode1(Uart1+SPI+IIC); 2:Mode2(HID Uart1+SPI+IIC) 3:Mode3(Uart1+Jtag+IIC)\n\tHANDLE   DevHandle;              // Device handle\n\tUSHORT   BulkOutEndpMaxSize;     // Upload endpoint size\n\tUSHORT   BulkInEndpMaxSize;      // The size of the downstream endpoint\n\tUCHAR    UsbSpeedType;           // USB Speed type,0:FS,1:HS,2:SS\n\tUCHAR    CH347IfNum;             // USB interface number: 0:UART,1:SPI/IIC/JTAG/GPIO\n\tUCHAR    DataUpEndp;             // The endpoint address\n\tUCHAR    DataDnEndp;             // The endpoint address\n\tCHAR     ProductString[64];      // Product string in USB descriptor\n\tCHAR     ManufacturerString[64]; // Manufacturer string in USB descriptor\n\tULONG    WriteTimeout;           // USB write timeout\n\tULONG    ReadTimeout;            // USB read timeout\n\tCHAR     FuncDescStr[64];        // Interface functions\n\tUCHAR    FirewareVer;            // Firmware version\n}mDeviceInforS,*mPDeviceInforS;\n\ntypedef int(__stdcall  * pCH347OpenDevice)(unsigned long iIndex);\n\ntypedef int(__stdcall * pCH347CloseDevice)(unsigned long iIndex);\n\ntypedef unsigned long(__stdcall * pCH347SetTimeout)(\n\tunsigned long iIndex,        /* Specify equipment serial number */\n\tunsigned long iWriteTimeout, /* Specifies the timeout period for USB\n\t\t\t\t\twrite out data blocks, in milliseconds\n\t\t\t\t\tmS, and 0xFFFFFFFF specifies no timeout\n\t\t\t\t\t(default) */\n\tunsigned long iReadTimeout); /* Specifies the timeout period for USB\n\t\t\t\t\treading data blocks, in milliseconds mS,\n\t\t\t\t\tand 0xFFFFFFFF specifies no timeout\n\t\t\t\t\t(default) */\n\ntypedef unsigned long(__stdcall * pCH347WriteData)(\n\tunsigned long iIndex,         /* Specify equipment serial number */\n\tvoid *oBuffer,                /* Point to a buffer large enough to hold\n\t\t\t\t\t the descriptor */\n\tunsigned long *ioLength);     /* Pointing to the length unit, the input\n\t\t\t\t\t is the length to be read, and the\n\t\t\t\t\t return is the actual read length */\n\ntypedef unsigned long(__stdcall * pCH347ReadData)(\n\tunsigned long iIndex,          /* Specify equipment serial number */\n\tvoid *oBuffer,                 /* Point to a buffer large enough to\n\t\t\t\t\t  hold the descriptor */\n\tunsigned long *ioLength);      /* Pointing to the length unit, the input\n\t\t\t\t\t  is the length to be read, and the\n\t\t\t\t\t  return is the actual read length */\n\ntypedef unsigned long(__stdcall * pCH347Jtag_INIT)(\n\tunsigned long iIndex,         /* Specify equipment serial number */\n\tunsigned char iClockRate);    /* Pointing to the length unit, the input\n\t\t\t\t\t is the length to be read, and the\n\t\t\t\t\t return is the actual read length */\n\ntypedef unsigned long(__stdcall  * pCH347GetDeviceInfor)(unsigned long iIndex, mDeviceInforS *DevInformation);\n\nHMODULE uhModule;\nBOOL ugOpen;\nunsigned long ugIndex;\npCH347OpenDevice CH347OpenDevice;\npCH347CloseDevice CH347CloseDevice;\npCH347SetTimeout CH347SetTimeout;\npCH347ReadData CH347ReadData;\npCH347WriteData CH347WriteData;\npCH347GetDeviceInfor CH347GetDeviceInfor;\n/* pCH347Jtag_INIT CH347Jtag_INIT; */\n#elif defined(__linux__)\n\n#include <jtag/drivers/libusb_helper.h>\n\n#define CH347_EPOUT 0x06u\n#define CH347_EPIN  0x86u\nint g_bus_num = 0;\nint g_device_addr = 0;\nbool ugOpen;\nunsigned long ugIndex;\nstruct libusb_device_handle *ch347_handle;\n\nstatic const uint16_t ch347_vids[] = {0x1a86, 0x1a86, 0x1a86};\nstatic const uint16_t ch347_pids[] = {0x55dd, 0x55de, 0x55e7};\n\nstatic uint32_t CH347OpenDevice(uint64_t iIndex)\n{\n\tlibusb_device** devs;\n\tint i = 0;\n\tssize_t cnt;\n\tint ret;\n\tstruct libusb_device *dev;\n\tstruct libusb_device_descriptor desc;\n\t\n\tif (libusb_init(NULL) < 0) {\n\t\treturn false;\n\t}\n\tif (g_bus_num != 0 && g_device_addr != 0) {\n\t\tcnt = libusb_get_device_list(NULL, &devs);\n\t\tif (cnt < 0) return false;\n\t\twhile ((dev = devs[i++]) != NULL)  {\n\t\t\tif (g_bus_num != 0 && g_device_addr != 0 && (libusb_get_bus_number(dev) != g_bus_num || libusb_get_device_address(dev) != g_device_addr))\n\t\t\t\tcontinue;\n\t\t\tif (libusb_open(dev, &ch347_handle) < 0){\n\t\t\t\treturn false;\n\t\t\t}else{\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tlibusb_free_device_list(devs, 1);\n\t}else{\n\t\tif (jtag_libusb_open(ch347_vids, ch347_pids,\n\t\t\t\t &ch347_handle, NULL) != ERROR_OK) {\n\t\t\treturn false;\n\t\t} else {\n\t\t\tdev = libusb_get_device(ch347_handle);\n\t\t\tret = libusb_get_device_descriptor(dev, &desc);\n\t\t\tif (ret < 0) {\n\t\t\t\tLOG_ERROR(\"Failed to get device descriptor: '%s'\\n\", libusb_error_name(ret));\n\t\t\t}\n\t\t\tif (desc.idProduct != 0x55dd){\n\t\t\t\tif (ERROR_OK != ch347_srst_enable()) {\n\t\t\t\t\tLOG_ERROR(\"ch347 enable srst Error.\");\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn true;\n}\n\nstatic bool CH347WriteData(uint64_t iIndex, uint8_t *data, uint64_t *length)\n{\n\tint ret, tmp = 0;\n\tret = jtag_libusb_bulk_write(ch347_handle,\n\t\t\t\t     CH347_EPOUT,\n\t\t\t\t     (char *)data,\n\t\t\t\t     *length,\n\t\t\t\t     2000, &tmp);\n\t*length = tmp;\n\n\tif (!ret)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic bool CH347ReadData(uint64_t iIndex, uint8_t *data, uint64_t *length)\n{\n\tint ret, tmp = 0;\n\n\tint size = *length;\n\tret = jtag_libusb_bulk_read(ch347_handle,\n\t\t\t\t    CH347_EPIN,\n\t\t\t\t    (char *)data,\n\t\t\t\t    size,\n\t\t\t\t    2000, &tmp);\n\n\t*length = tmp;\n\tif (!ret)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic bool CH347CloseDevice(uint64_t iIndex)\n{\n\tjtag_libusb_close(ch347_handle);\n\treturn true;\n}\n\n#endif\n\n_CH347_Info ch347;\n\nstatic int ch347_swd_run_queue(void);\n/* swd init func */\nstatic bool CH347SWD_INIT(uint64_t iIndex, uint8_t iClockRate)\n{\n\tuint8_t cmdBuf[128] = \"\";\n\tunsigned long i = 0;\n\tcmdBuf[i++] = CH347_CMD_SWD_INIT;\n\tcmdBuf[i++] = 8; /* Data length is 6 */\n\tcmdBuf[i++] = 0;\n\tcmdBuf[i++] = 0x40;\n\tcmdBuf[i++] = 0x42;\n\n\tcmdBuf[i++] = 0x0f;       /* Reserved Bytes */\n\tcmdBuf[i++] = 0x00;       /* Reserved Bytes */\n\tcmdBuf[i++] = iClockRate; /* JTAG clock speed */\n\ti += 3;                   /* Reserved Bytes */\n\n\tunsigned long mLength = i;\n\tif (!CH347WriteData(iIndex, cmdBuf, &mLength) || (mLength != i))\n\t\treturn false;\n\n\tmLength = 4;\n\tmemset(cmdBuf, 0, sizeof(cmdBuf));\n\n\tif (!CH347ReadData(iIndex, cmdBuf, &mLength) || (mLength != 4))\n\t\treturn false;\n\n\treturn true;\n}\n\n/**\n *  HexToString - Hex Conversion String Function\n *  @param buf    Point to a buffer to place the Hex data to be converted\n *  @param size   Pointing to the length unit where data needs to be converted\n *\n *  @return Returns a converted string\n */\nstatic char *HexToString(uint8_t *buf, uint32_t size)\n{\n\tuint32_t i;\n\tif (buf == NULL)\n\t\treturn \"NULL\";\n\n\tchar *str = calloc(size * 2 + 1, 1);\n\n\tfor (i = 0; i < size; i++)\n\t\tsprintf(str + 2 * i, \"%02x \", buf[i]);\n\treturn str;\n}\n\n/**\n *  CH347_Write - CH347 Write\n *  @param oBuffer    Point to a buffer to place the data to be written out\n *  @param ioLength   Pointing to the length unit, the input is the length to be\n *                    written out, and the return is the actual written length\n *\n *  @return Write success returns 1, failure returns 0\n */\nstatic int CH347_Write(void *oBuffer, unsigned long *ioLength)\n{\n\tint ret = -1;\n\tchar *log_buf = NULL;\n\tunsigned long wlength = *ioLength, WI;\n\tif (*ioLength >= HW_TDO_BUF_SIZE)\n\t\twlength = HW_TDO_BUF_SIZE;\n\tWI = 0;\n\twhile (1) {\n\t\tret = CH347WriteData(ugIndex, (uint8_t *)oBuffer + WI,\n\t\t\t\t     &wlength);\n\t\tif (!ret) {\n\t\t\t*ioLength = 0;\n\t\t\treturn false;\n\t\t}\n\t\tLOG_DEBUG_IO(\"(size=%lu, buf=[%s]) -> %\" PRIu32, wlength,\n\t\t\t     (log_buf = HexToString((uint8_t *)oBuffer, wlength)),\n\t\t\t     (uint32_t)wlength);\n\t\tWI += wlength;\n\t\tif (WI >= *ioLength)\n\t\t\tbreak;\n\t\tif ((*ioLength - WI) > HW_TDO_BUF_SIZE)\n\t\t\twlength = HW_TDO_BUF_SIZE;\n\t\telse\n\t\t\twlength = *ioLength - WI;\n\t\tfree(log_buf);\n\t}\n\n\t*ioLength = WI;\n\treturn true;\n}\n\n/**\n * CH347_Read - CH347 Read\n * @param oBuffer  Point to a buffer to place the data to be read in\n * @param ioLength Pointing to the length unit, the input is the length to\n *                 be read, and the return is the actual read length\n *\n * @return Write success returns 1, failure returns 0\n */\nstatic int CH347_Read(void *oBuffer, unsigned long *ioLength)\n{\n\tunsigned long rlength = *ioLength, WI;\n\tchar* log_buf = NULL;\n\t/* The maximum allowable reading for a single read is 4096B of data.\n\t   If it exceeds the allowable reading limit, it will be calculated as\n\t   4096B */\n\tif (rlength > HW_TDO_BUF_SIZE)\n\t\trlength = HW_TDO_BUF_SIZE;\n\tWI = 0;\n\n\twhile (1) {\n\t\tif (!CH347ReadData(ugIndex, (uint8_t *)oBuffer + WI,\n\t\t\t\t   &rlength)) {\n\t\t\tLOG_ERROR(\"CH347_Read read data failure.\");\n\t\t\treturn false;\n\t\t}\n\n\t\tWI += rlength;\n\t\tif (WI >= *ioLength)\n\t\t\tbreak;\n\t\tif ((*ioLength - WI) > HW_TDO_BUF_SIZE)\n\t\t\trlength = HW_TDO_BUF_SIZE;\n\t\telse\n\t\t\trlength = *ioLength - WI;\n\t}\n\tLOG_DEBUG_IO(\"(size=%lu, buf=[%s]) -> %\" PRIu32, WI,\n\t\t     (log_buf = HexToString((uint8_t *)oBuffer, WI)), (uint32_t)WI);\n\t*ioLength = WI;\n\tfree(log_buf);\n\treturn true;\n}\n\nstatic int ch347_srst_out(unsigned char status)\n{\n\tunsigned long int BI = 0;\n\tunsigned char byte = 0;\n\tunsigned char cmdPacket[4] = \"\";\n\tcmdPacket[BI++] = CH347_CMD_JTAG_BIT_OP;\n\tcmdPacket[BI++] = 0x01;\n\tcmdPacket[BI++] = 0;\n\tbyte = ch347.TCK | ch347.TDI | ch347.TMS | (ch347.SRST =\n\t\t\t\t\t\t\t(status ? SRST_H : SRST_L));\n\tcmdPacket[BI++] = byte;\n\n\tif (!CH347_Write(cmdPacket, &BI)) {\n\t\tLOG_ERROR(\"SRST set failure.\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic void CH347_Sleep(int us)\n{\n\tLOG_DEBUG_IO(\"%s(us=%d)\", __func__, us);\n\tjtag_sleep(us);\n}\n\nstatic int ch347_srst_enable(void)\n{\n\tuint8_t srst_enable[11] = {0xe2, 0x08, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};\n\tunsigned long wLen = 11;\n\tunsigned long rLen = 4;\n\tCH347_Write(srst_enable, &wLen);\n\tCH347_Read(srst_enable, &rLen);\n\tif (srst_enable[1] != 0x01) {\n\t\tLOG_ERROR(\"ch347 enable srst Error.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tch347_srst_out(SRST_H);\n\treturn ERROR_OK;\n}\n\nstatic void CH347_Read_Scan(UCHAR *pBuffer, uint32_t length)\n{\n\tunsigned long read_size = 0;\n\tunsigned long RxLen = 0;\n\tunsigned long index = 0;\n\tunsigned long read_buf_index = 0;\n\tunsigned char *read_buf = NULL;\n\tint dataLen = 0, i = 0; /*, this_bits = 0; */\n\n\tread_size = length;\n\tRxLen = read_size;\n\tindex = 0;\n\tread_buf_index = 0;\n\tread_buf = calloc(sizeof(unsigned char), read_size);\n\tif (!CH347_Read(read_buf, &RxLen)) {\n\t\tLOG_ERROR(\"CH347_Read read data failure.\");\n\t\treturn;\n\t}\n\twhile (index < read_size) { /* deal with the CH347_CMD_JTAG_BIT_OP_RD  or  CH347_CMD_JTAG_DATA_SHIFT_RD */\n\t\tif (read_buf[index] == CH347_CMD_JTAG_DATA_SHIFT_RD) {\n\t\t\tdataLen = read_buf[++index] & 0xFF;\n\t\t\tdataLen += (read_buf[++index] & 0xFF) << 8;\n\t\t\tmemcpy(pBuffer + read_buf_index, &read_buf[index + 1],\n\t\t\t       dataLen);\n\t\t\tread_buf_index += dataLen;\n\t\t\tindex += dataLen + 1;\n\t\t} else if (read_buf[index] == CH347_CMD_JTAG_BIT_OP_RD) {\n\t\t\tdataLen = read_buf[++index] & 0xFF;\n\t\t\tdataLen += (read_buf[++index] & 0xFF) << 8;\n\t\t\tfor (i = 0; i < dataLen; i++) {\n\t\t\t\tif (read_buf[index + 1 + i] == 0x01)\n\t\t\t\t\t*(pBuffer + read_buf_index) |= (1 << i);\n\t\t\t\telse\n\t\t\t\t\t*(pBuffer + read_buf_index) &= ~(1 << i);\n\t\t\t}\n\t\t\tread_buf_index += 1;\n\t\t\tindex += dataLen + 1;\n\t\t} else {\n\t\t\t// LOG_ERROR(\"readbuf read_commend error\");\n\t\t\t*(pBuffer + read_buf_index) = read_buf[index];\n\t\t\tread_buf_index++;\n\t\t\tindex++;\n\t\t}\n\t}\n\tif (read_buf) {\n\t\tfree(read_buf);\n\t\tread_buf = NULL;\n\t}\n}\n\nstatic void CH347_Flush_Buffer(void)\n{\n\tunsigned long retlen = ch347.buffer_idx;\n\tint nb = ch347.buffer_idx, ret = ERROR_OK;\n\n\twhile (ret == ERROR_OK && nb > 0) {\n\t\tret = CH347_Write(ch347.buffer, &retlen);\n\t\tnb -= retlen;\n\t}\n\tmemset(&ch347.buffer, 0, sizeof(ch347.buffer));\n\tch347.buffer_idx = 0;\n\tch347.lastCmd = 0;\n\tch347.len_idx = 0;\n\tch347.len_value = 0;\n\n\tif (ch347.read_count == 0)\n\t\treturn;\n\tif (ch347.pack_size == LARGER_PACK) {\n\t\tCH347_Read_Scan(&ch347.read_buffer[0], ch347.read_count);\n\t\tbit_copy_execute(&ch347.read_queue);\n\t\tmemset(ch347.read_buffer, 0, SF_PACKET_BUF_SIZE);\n\t\tch347.read_count = 0;\n\t\tch347.read_idx = 0;\n\t}\n}\n\nstatic void CH347_In_Buffer(uint8_t byte)\n{\n\tif ((SF_PACKET_BUF_SIZE - ch347.buffer_idx) < 1)\n\t\tCH347_Flush_Buffer();\n\tch347.buffer[ch347.buffer_idx] = byte;\n\tch347.buffer_idx++;\n\tif ((SF_PACKET_BUF_SIZE - ch347.buffer_idx) == 0)\n\t\tCH347_Flush_Buffer();\n}\n\nstatic void CH347_In_Buffer_bytes(uint8_t *bytes, unsigned long bytes_length)\n{\n\tif ((ch347.buffer_idx + bytes_length) > SF_PACKET_BUF_SIZE)\n\t\tCH347_Flush_Buffer();\n\tmemcpy(&ch347.buffer[ch347.buffer_idx], bytes, bytes_length);\n\tch347.buffer_idx += bytes_length;\n\tif ((SF_PACKET_BUF_SIZE - ch347.buffer_idx) < 1)\n\t\tCH347_Flush_Buffer();\n}\n\nstatic void combinePackets(uint8_t cmd, int cur_idx, unsigned long int len)\n{\n\tif (cmd != ch347.lastCmd) {\n\t\tch347.buffer[cur_idx] = cmd;\n\t\tch347.buffer[cur_idx + 1] =\n\t\t\t(uint8_t)(((len - CH347_CMD_HEADER) >> 0) & 0xFF);\n\t\tch347.buffer[cur_idx + 2] =\n\t\t\t(uint8_t)(((len - CH347_CMD_HEADER) >> 8) & 0xFF);\n\n\t\t/* update the ch347 struct */\n\t\tch347.lastCmd = cmd;\n\t\tch347.len_idx = cur_idx + 1;\n\t\tch347.len_value = (len - CH347_CMD_HEADER);\n\t} else {\n\t\t/* update the ch347 struct cmd data leng */\n\t\tch347.len_value += (len - CH347_CMD_HEADER);\n\n\t\t/* update the cmd packet valid leng */\n\t\tch347.buffer[ch347.len_idx] = (uint8_t)((ch347.len_value >> 0) \\\n\t\t\t\t\t\t\t& 0xFF);\n\t\tch347.buffer[ch347.len_idx + 1] = (uint8_t)(\n\t\t\t(ch347.len_value >> 8) & 0xFF);\n\n\t\t/* update the buffer data leng */\n\t\tmemcpy(&ch347.buffer[cur_idx],\n\t\t       &ch347.buffer[cur_idx + CH347_CMD_HEADER],\n\t\t       (len - CH347_CMD_HEADER));\n\n\t\t/* update the ch347 buffer index */\n\t\tch347.buffer_idx -= CH347_CMD_HEADER;\n\t}\n}\n/**\n * CH347_ClockTms - Function function used to change the TMS value at the\n * rising edge of TCK to switch its Tap state\n * @param BitBangPkt Protocol package\n * @param tms TMS value to be changed\n * @param BI Protocol packet length\n *\n * @return Return protocol packet length\n */\nstatic unsigned long CH347_ClockTms(int tms, unsigned long BI)\n{\n\tuint8_t data = 0;\n\tunsigned char cmd = 0;\n\n\tif (tms == 1)\n\t\tcmd = TMS_H;\n\telse\n\t\tcmd = TMS_L;\n\n\tBI += 2;\n\n\tdata = cmd | TDI_L | TCK_L | TRST_H | SRST_H;\n\tCH347_In_Buffer(data);\n\tdata = cmd | TDI_L | TCK_H | TRST_H | SRST_H;\n\tCH347_In_Buffer(data);\n\tch347.TMS = cmd;\n\tch347.TDI = TDI_L;\n\tch347.TCK = TCK_H;\n\tch347.TRST = TRST_H;\n\tch347.SRST = SRST_H;\n\treturn BI;\n}\n\n/**\n * CH347_IdleClock - Function function to ensure that the clock is in a low state\n * @param BitBangPkt Protocol package\n * @param BI Protocol packet length\n *\n * @return Return protocol packet length\n */\nstatic unsigned long CH347_IdleClock(unsigned long BI)\n{\n\tunsigned char byte = 0;\n\tbyte |= ch347.TMS ? TMS_H : TMS_L;\n\tbyte |= ch347.TDI ? TDI_H : TDI_L;\n\tbyte |= ch347.TRST ? TRST_H : TRST_L;\n\tbyte |= ch347.SRST ? SRST_H : SRST_L;\n\tBI++;\n\tCH347_In_Buffer(byte);\n\n\treturn BI;\n}\n\n/**\n * CH347_TmsChange - Function function that performs state switching by changing the value of TMS\n * @param tmsValue The TMS values that need to be switched form one byte of data in the switching order\n * @param step The number of bit values that need to be read from the tmsValue value\n * @param skip Count from the skip bit of tmsValue to step\n *\n */\nstatic void CH347_TmsChange(const unsigned char *tmsValue, int step, int skip)\n{\n\tint i;\n\tint index = ch347.buffer_idx;\n\tunsigned long BI, retlen, cmdLen;\n\n\tBI = CH347_CMD_HEADER;\n\tretlen = CH347_CMD_HEADER;\n\tLOG_DEBUG_IO(\"(TMS Value: %02x..., step = %d, skip = %d)\", tmsValue[0],\n\t\t     step, skip);\n\n\tfor (i = 0; i < 3; i++)\n\t\tCH347_In_Buffer(0);\n\n\tfor (i = skip; i < step; i++) {\n\t\tretlen = CH347_ClockTms((tmsValue[i / 8] >> (i % 8)) & 0x01, BI);\n\t\tBI = retlen;\n\t}\n\tcmdLen = CH347_IdleClock(BI);\n\n\tcombinePackets(CH347_CMD_JTAG_BIT_OP, index, cmdLen);\n}\n\n/**\n * CH347_TMS - By ch347_ execute_ Queue call\n * @param cmd Upper layer transfer command parameters\n *\n */\nstatic void CH347_TMS(struct tms_command *cmd)\n{\n\tLOG_DEBUG_IO(\"(step: %d)\", cmd->num_bits);\n\tCH347_TmsChange(cmd->bits, cmd->num_bits, 0);\n}\n\n/**\n * CH347_Reset - CH347 Reset Tap Status Function\n * @brief If there are more than six consecutive TCKs and TMS is high, the state\n *         machine can be set to a Test-Logic-Reset state\n *\n */\nstatic int ch347_reset(int trst, int srst)\n{\n\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", trst, srst);\n\tunsigned char BitBang[512] = \"\", BII, i;\n\tunsigned long TxLen;\n\tif (!swd_mode) {\n\t\tBII = CH347_CMD_HEADER;\n\t\tfor (i = 0; i < 7; i++) {\n\t\t\tBitBang[BII++] = TMS_H | TDI_L | TCK_L | SRST_H;\n\t\t\tBitBang[BII++] = TMS_H | TDI_L | TCK_H | SRST_H;\n\t\t}\n\t\tBitBang[BII++] = TMS_H | TDI_L | TCK_L | SRST_H;\n\n\t\tch347.TCK = TCK_L;\n\t\tch347.TDI = TDI_L;\n\t\tch347.TMS = 0;\n\n\t\tBitBang[0] = CH347_CMD_JTAG_BIT_OP;\n\t\tBitBang[1] = BII - CH347_CMD_HEADER;\n\t\tBitBang[2] = 0;\n\n\t\tTxLen = BII;\n\n\t\tif (!CH347_Write(BitBang, &TxLen) && (TxLen != BII)) {\n\t\t\tLOG_ERROR(\"JTAG_Init send usb data failure.\");\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * CH347_MovePath - Obtain the current Tap status and switch to the status TMS\n *                  value passed down by cmd\n * @param cmd Upper layer transfer command parameters\n *\n */\nstatic void CH347_MovePath(struct pathmove_command *cmd)\n{\n\tint i;\n\tint index = ch347.buffer_idx;\n\tunsigned long BI, retlen = 0, cmdLen;\n\n\tBI = CH347_CMD_HEADER;\n\n\tfor (i = 0; i < 3; i++)\n\t\tCH347_In_Buffer(0);\n\tLOG_DEBUG_IO(\"(num_states=%d, last_state=%d)\",\n\t\t     cmd->num_states, cmd->path[cmd->num_states - 1]);\n\n\tfor (i = 0; i < cmd->num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), false) ==\n\t\t    cmd->path[i])\n\t\t\tretlen = CH347_ClockTms(0, BI);\n\t\tBI = retlen;\n\t\tif (tap_state_transition(tap_get_state(), true) == cmd->path[i])\n\t\t\tretlen = CH347_ClockTms(1, BI);\n\t\tBI = retlen;\n\t\ttap_set_state(cmd->path[i]);\n\t}\n\n\tcmdLen = CH347_IdleClock(BI);\n\n\tcombinePackets(CH347_CMD_JTAG_BIT_OP, index, cmdLen);\n}\n\n/**\n * CH347_MoveState - Toggle the Tap state to the Target state stat\n * @param stat Pre switch target path\n * @param skip Number of digits to skip\n *\n */\nstatic void CH347_MoveState(tap_state_t state, int skip)\n{\n\tuint8_t tms_scan;\n\tint tms_len;\n\n\tLOG_DEBUG_IO(\"(from %s to %s)\", tap_state_name(tap_get_state()),\n\t\t     tap_state_name(state));\n\tif (tap_get_state() == state)\n\t\treturn;\n\ttms_scan = tap_get_tms_path(tap_get_state(), state);\n\ttms_len = tap_get_tms_path_len(tap_get_state(), state);\n\tCH347_TmsChange(&tms_scan, tms_len, skip);\n\ttap_set_state(state);\n}\n\n/**\n * CH347_WriteRead - CH347 Batch read/write function\n * @param bits     Read and write data this time\n * @param nb_bits  Incoming data length\n * @param scan     The transmission method of incoming data to determine whether\n *                 to perform data reading\n */\nstatic void CH347_WriteRead(struct scan_command *cmd, uint8_t *bits,\n\t\t\t    int nb_bits, enum scan_type scan)\n{\n\tint nb8 = nb_bits / 8;\n\tint nb1 = nb_bits % 8;\n\tint i, num_bits = 0;\n\tbool IsRead = false; /*, isLastByte = false */\n\tuint8_t TMS_Bit = 0, TDI_Bit = 0, CMD_Bit;\n\tstatic uint8_t byte0[SF_PACKET_BUF_SIZE];\n\tuint8_t *readData = calloc(SF_PACKET_BUF_SIZE, 1);\n\tunsigned long readLen = 0;\n\tunsigned long BI = 0, DI, DII, PktDataLen, DLen = 0, tempIndex,\n\t\ttotalReadLength = 0, tempLength = 0;\n\tif (ch347.pack_size == LARGER_PACK) {\n\t\tif ((ch347.read_count >= (510 * 1)))\n\t\t\tCH347_Flush_Buffer();\n\t} else {\n\t\tCH347_Flush_Buffer();\n\t}\n\n\tif (nb8 > 0 && nb1 == 0) {\n\t\tnb8--;\n\t\tnb1 = 8;\n\t}\n\n\tIsRead = (scan == SCAN_IN || scan == SCAN_IO);\n\tDI = BI = 0;\n\twhile (DI < (unsigned long)nb8) {\n\t\tif ((nb8 - DI) > UCMDPKT_DATA_MAX_BYTES_USBHS)\n\t\t\tPktDataLen = UCMDPKT_DATA_MAX_BYTES_USBHS;\n\t\telse\n\t\t\tPktDataLen = nb8 - DI;\n\n\t\tDII = PktDataLen;\n\n\t\tif (IsRead)\n\t\t\tCH347_In_Buffer(CH347_CMD_JTAG_DATA_SHIFT_RD);\n\t\telse\n\t\t\tCH347_In_Buffer(CH347_CMD_JTAG_DATA_SHIFT);\n\n\t\t/* packet data don't deal D3 & D4 */\n\t\tif ((CH347_CMD_JTAG_DATA_SHIFT_RD != ch347.lastCmd) |\n\t\t    (CH347_CMD_JTAG_DATA_SHIFT != ch347.lastCmd)) {\n\t\t\t/* update the ch347 struct */\n\t\t\tch347.lastCmd = 0;\n\t\t\tch347.len_idx = 0;\n\t\t\tch347.len_value = 0;\n\t\t}\n\n\t\tCH347_In_Buffer((uint8_t)(PktDataLen >> 0) & 0xFF);\n\t\tCH347_In_Buffer((uint8_t)(PktDataLen >> 8) & 0xFF);\n\n\t\tif (bits)\n\t\t\tCH347_In_Buffer_bytes(&bits[DI], PktDataLen);\n\t\telse\n\t\t\tCH347_In_Buffer_bytes(byte0, PktDataLen);\n\t\tDI += DII;\n\n\t\ttempLength += (DII + CH347_CMD_HEADER);\n\t}\n\n\ttotalReadLength += tempLength;\n\n\tif (IsRead) {\n\t\tch347.read_count += tempLength;\n\t\treadLen += tempLength;\n\t}\n\n\tif (bits) {\n\t\tCMD_Bit = IsRead ? CH347_CMD_JTAG_BIT_OP_RD :\t\\\n\t\t\tCH347_CMD_JTAG_BIT_OP;\n\t\tDLen = (nb1 * 2) + 1;\n\n\t\tif (CMD_Bit != ch347.lastCmd) {\n\t\t\tCH347_In_Buffer(CMD_Bit);\n\t\t\tCH347_In_Buffer((uint8_t)(DLen >> 0) & 0xFF);\n\t\t\tCH347_In_Buffer((uint8_t)(DLen >> 8) & 0xFF);\n\t\t\tch347.lastCmd = CMD_Bit;\n\t\t\tch347.len_idx = ch347.buffer_idx - 2;\n\t\t\tch347.len_value = DLen;\n\t\t} else {\n\t\t\t/* update the ch347 struct cmd data leng */\n\t\t\tch347.len_value += DLen;\n\t\t\t/* update the cmd packet valid leng */\n\t\t\tch347.buffer[ch347.len_idx] =\n\t\t\t\t(uint8_t)(ch347.len_value >> 0) & 0xFF;\n\t\t\tch347.buffer[ch347.len_idx + 1] =\n\t\t\t\t(uint8_t)(ch347.len_value >> 8) & 0xFF;\n\t\t}\n\n\t\tTMS_Bit = TMS_L;\n\t\tfor (i = 0; i < nb1; i++) {\n\t\t\tif ((bits[nb8] >> i) & 0x01)\n\t\t\t\tTDI_Bit = TDI_H;\n\t\t\telse\n\t\t\t\tTDI_Bit = TDI_L;\n\n\t\t\tif ((i + 1) == nb1)\n\t\t\t\tTMS_Bit = TMS_H;\n\n\t\t\tCH347_In_Buffer(TMS_Bit | TDI_Bit | TCK_L | TRST_H | SRST_H);\n\t\t\tCH347_In_Buffer(TMS_Bit | TDI_Bit | TCK_H | TRST_H | SRST_H);\n\t\t}\n\t\tCH347_In_Buffer(TMS_Bit | TDI_Bit | TCK_L | TRST_H | SRST_H);\n\t}\n\n\tch347.TMS = TMS_Bit;\n\tch347.TDI = TDI_Bit;\n\tch347.TCK = TCK_L;\n\n\tif (IsRead) {\n\t\ttempLength = ((DLen / 2) + CH347_CMD_HEADER);\n\t\ttotalReadLength += tempLength;\n\t\tch347.read_count += tempLength;\n\t\treadLen += tempLength;\n\t\tDI = BI = 0;\n\t}\n\tint offset = 0, bit_count = 0;\n\tif (IsRead && totalReadLength > 0) {\n\t\tif (ch347.pack_size == STANDARD_PACK && bits && cmd) {\n\t\t\tCH347_Flush_Buffer();\n\t\t\tCH347_Read_Scan(readData, readLen);\n\t\t}\n\t\tfor (i = 0; i < cmd->num_fields; i++) {\n\t\t\t/* if neither in_value nor in_handler\n\t\t\t * are specified we don't have to examine this field\n\t\t\t */\n\t\t\tLOG_DEBUG(\"fields[%i].in_value[%i], offset: %d\",\n\t\t\t\t  i, cmd->fields[i].num_bits, offset);\n\t\t\tnum_bits = cmd->fields[i].num_bits;\n\t\t\tif (ch347.pack_size == LARGER_PACK)\n\t\t\t\tbit_count += num_bits;\n\t\t\tif (cmd->fields[i].in_value) {\n\t\t\t\tif (ch347.pack_size == LARGER_PACK) {\n\t\t\t\t\tbit_copy_queued(\n\t\t\t\t\t\t&ch347.read_queue,\n\t\t\t\t\t\tcmd->fields[i].in_value,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&ch347.read_buffer[ch347.read_idx],\n\t\t\t\t\t\toffset, num_bits);\n\t\t\t\t\tif (num_bits > 7)\n                    \tch347.read_idx += DIV_ROUND_UP(bit_count, 8);\n\t\t\t\t} else {\n\t\t\t\t\tnum_bits = cmd->fields[i].num_bits;\n\t\t\t\t\tuint8_t *captured = buf_set_buf(\n\t\t\t\t\t\treadData, bit_count,\n\t\t\t\t\t\tmalloc(DIV_ROUND_UP(num_bits,\n\t\t\t\t\t\t\t\t    8)), 0,\n\t\t\t\t\t\tnum_bits);\n\t\t\t\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {\n\t\t\t\t\t\tchar *char_buf =\n\t\t\t\t\t\t\tbuf_to_hex_str(\n\t\t\t\t\t\t\t\tcaptured,\n\t\t\t\t\t\t\t\t(num_bits >\n\t\t\t\t\t\t\t\t DEBUG_JTAG_IOZ)\n\t\t\t\t\t\t\t\t? DEBUG_JTAG_IOZ\n\t\t\t\t\t\t\t\t: num_bits);\n\t\t\t\t\t\tfree(char_buf);\n\t\t\t\t\t}\n\t\t\t\t\tbuf_cpy(captured,\n\t\t\t\t\t\tcmd->fields[i].in_value,\n\t\t\t\t\t\tnum_bits);\n\t\t\t\t\tfree(captured);\n\t\t\t\t}\n\t\t\t}else {\n\t\t\t\tLOG_DEBUG_IO(\"cmd->fields with no data\");\n\t\t\t}\n\t\t\tif (ch347.pack_size == LARGER_PACK) {\n\t\t\t\toffset += num_bits;\n\t\t\t}else{\n\t\t\t\tbit_count += cmd->fields[i].num_bits;\n\t\t\t}\n\t\t}\n\t}\n\n\ttempIndex = ch347.buffer_idx;\n\tfor (i = 0; i < CH347_CMD_HEADER; i++)\n\t\tCH347_In_Buffer(0);\n\tBI = CH347_CMD_HEADER;\n\tBI = CH347_IdleClock(BI);\n\n\tcombinePackets(CH347_CMD_JTAG_BIT_OP, tempIndex, BI);\n\tif (readData) {\n\t\tfree(readData);\n\t\treadData = NULL;\n\t}\n}\n\nstatic void CH347_RunTest(int cycles, tap_state_t state)\n{\n\tLOG_DEBUG_IO(\"%s(cycles=%i, end_state=%d)\", __func__, cycles, state);\n\tif (tap_get_state() != TAP_IDLE)\n\t\tCH347_MoveState(TAP_IDLE, 0);\n\n\tuint8_t tmsValue = 0;\n\tCH347_TmsChange(&tmsValue, 7, 1);\n\n\tCH347_WriteRead(NULL, NULL, cycles, SCAN_OUT);\n\tCH347_MoveState(state, 0);\n}\n\nstatic void CH347_TableClocks(int cycles)\n{\n\tLOG_DEBUG_IO(\"%s(cycles=%i)\", __func__, cycles);\n\tCH347_WriteRead(NULL, NULL, cycles, SCAN_OUT);\n}\n\n/**\n * CH347_Scan - Switch to SHIFT-DR or SHIFT-IR status for scanning\n * @param cmd Upper layer transfer command parameters\n *\n * @return Success returns ERROR_OK\n */\nstatic int CH347_Scan(struct scan_command *cmd)\n{\n\tint scan_bits;\n\tuint8_t *buf = NULL;\n\tenum scan_type type;\n\tint ret = ERROR_OK;\n\tstatic const char *const type2str[] = {\n\t\t\"\", \"SCAN_IN\", \"SCAN_OUT\", \"SCAN_IO\"\n\t};\n\tchar *log_buf = NULL;\n\n\ttype = jtag_scan_type(cmd);\n\tscan_bits = jtag_build_buffer(cmd, &buf);\n\n\tif (cmd->ir_scan)\n\t\tCH347_MoveState(TAP_IRSHIFT, 0);\n\telse\n\t\tCH347_MoveState(TAP_DRSHIFT, 0);\n\n\tlog_buf = HexToString(buf, DIV_ROUND_UP(scan_bits, 8));\n\tLOG_DEBUG_IO(\"Scan\");\n\tLOG_DEBUG_IO(\"%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)\",\n\t\t     __func__,\n\t\t     cmd->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\t     type2str[type],\n\t\t     scan_bits, log_buf, cmd->end_state);\n\n\tfree(log_buf);\n\n\tCH347_WriteRead(cmd, buf, scan_bits, type);\n\n\tfree(buf);\n\n\tCH347_MoveState(cmd->end_state, 1);\n\n\treturn ret;\n}\n\nstatic int ch347_execute_queue(void)\n{\n\tstruct jtag_command *cmd;\n\tint ret = ERROR_OK;\n\n\tfor (cmd = jtag_command_queue; ret == ERROR_OK && cmd;\n\t     cmd = cmd->next) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RESET:\n\t\t\tLOG_DEBUG_IO(\"JTAG_RESET : %d %d.\\n\",\n\t\t\t\t     cmd->cmd.reset->trst,\n\t\t\t\t     cmd->cmd.reset->srst);\n\t\t\tch347_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tCH347_RunTest(cmd->cmd.runtest->num_cycles,\n\t\t\t\t      cmd->cmd.runtest->end_state);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tCH347_TableClocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tCH347_MoveState(cmd->cmd.statemove->end_state, 0);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tCH347_MovePath(cmd->cmd.pathmove);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\tCH347_TMS(cmd->cmd.tms);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tCH347_Sleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tret = CH347_Scan(cmd->cmd.scan);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%X\",\n\t\t\t\t  cmd->type);\n\t\t\tret = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tCH347_Flush_Buffer();\n\treturn ret;\n}\n\n/**\n * ch347_init - CH347 Initialization function\n *\n *  Todo:\n *                Initialize dynamic library functions\n *                Open Device\n *  @return Success returns 0, failure returns ERROR_FAIL\n */\nstatic int ch347_init(void)\n{\n#ifdef _WIN32\n\tif (uhModule == 0) {\n\t\t#ifdef _WIN64\n\t\tuhModule = LoadLibrary(\"CH347DLLA64.DLL\");\n\t\t#else\n\t\tuhModule = LoadLibrary(\"CH347DLL.DLL\");\n\t\t#endif\n\t\tif (uhModule) {\n\t\t\tCH347OpenDevice = (pCH347OpenDevice)GetProcAddress(\n\t\t\t\tuhModule, \"CH347OpenDevice\");\n\t\t\tCH347CloseDevice = (pCH347CloseDevice)GetProcAddress(\n\t\t\t\tuhModule, \"CH347CloseDevice\");\n\t\t\tCH347ReadData = (pCH347ReadData)GetProcAddress(\n\t\t\t\tuhModule, \"CH347ReadData\");\n\t\t\tCH347WriteData = (pCH347WriteData)GetProcAddress(\n\t\t\t\tuhModule, \"CH347WriteData\");\n\t\t\tCH347SetTimeout = (pCH347SetTimeout)GetProcAddress(\n\t\t\t\tuhModule, \"CH347SetTimeout\");\n\t\t\tCH347GetDeviceInfor = (pCH347GetDeviceInfor)GetProcAddress(\n\t\t\t\tuhModule, \"CH347GetDeviceInfor\");\n\t\t\tif (CH347OpenDevice == NULL || CH347CloseDevice == NULL\n\t\t\t\t|| CH347SetTimeout == NULL || CH347ReadData == NULL\n\t\t\t\t|| CH347WriteData == NULL || CH347GetDeviceInfor == NULL) {\n\t\t\t\tLOG_ERROR(\"Jtag_init error \");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\tDevIsOpened = CH347OpenDevice(ugIndex);\n\tif (DevIsOpened == INVALID_HANDLE_VALUE) {\n#elif defined(__linux__)\n\tDevIsOpened = CH347OpenDevice(ugIndex);\n\tugIndex = DevIsOpened;\n\tif (DevIsOpened == false) {\n#endif\n\t\tLOG_ERROR(\"CH347 Open Error.\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_INFO(\"CH347 Open Succ.\");\n\t\t\n\t}\n#ifdef _WIN32\n\tmDeviceInforS devInfo;\n\tCH347GetDeviceInfor(ugIndex, &devInfo);\n\tchar* pidstr = strstr(devInfo.DeviceID, \"PID_\");\n\tif (pidstr){\n\t\tpidstr += 4;\n\t}\n\tif (strncmp(\"55DD\", pidstr, 4) != 0) {\n\t\tif (ch347_srst_enable() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"ch347 enable srst Error.\");\n\t\t}\n\t}\n#endif\n\tif (!swd_mode) {\n\t\tUSBC_PACKET = USBC_PACKET_USBHS;\n\t\t/* ch347 init */\n\t\tch347.TCK = TCK_L;\n\t\tch347.TMS = TMS_H;\n\t\tch347.TDI = TDI_L;\n\t\tch347.TRST = TRST_H;\n\t\tch347.SRST = SRST_H;\n\t\tch347.buffer_idx = 0;\n\n\t\tmemset(&ch347.buffer, 0, SF_PACKET_BUF_SIZE);\n\t\tch347.len_idx = 0;\n\t\tch347.len_value = 0;\n\t\tch347.lastCmd = 0;\n\n\t\tmemset(&ch347.read_buffer, 0, SF_PACKET_BUF_SIZE);\n\t\tch347.read_count = 0;\n\t\tch347.read_idx = 0;\n\n\t\tbit_copy_queue_init(&ch347.read_queue);\n\n\t\t/* CH347SetTimeout(ugIndex, 500, 500); */\n\n\t\ttap_set_state(TAP_RESET);\n\t}\n\treturn 0;\n}\n\n/**\n * ch347_quit - CH347 Device Release Function\n *\n * Todo:\n *              Reset JTAG pin signal\n *              Close\n *  @return always returns 0\n */\nstatic int ch347_quit(void)\n{\n\tunsigned long retlen = 4;\n\tuint8_t byte[4] = {CH347_CMD_JTAG_BIT_OP, 0x01, 0x00, ch347.TRST | ch347.SRST};\n\tif (!swd_mode) {\n\t\tCH347_Write(byte, &retlen);\n\t\tbit_copy_discard(&ch347.read_queue);\n\t}\n\tif (DevIsOpened) {\n\t\tCH347CloseDevice(ugIndex);\n\t\tLOG_INFO(\"Close the CH347.\");\n\t\tDevIsOpened = false;\n\t}\n\treturn 0;\n}\n\nstatic bool Check_Speed(uint64_t iIndex, uint8_t iClockRate)\n{\n\tunsigned long int i = 0, j;\n\tbool retVal;\n\tuint8_t cmdBuf[32] = \"\";\n\tcmdBuf[i++] = CH347_CMD_JTAG_INIT;\n\tcmdBuf[i++] = 6;\n\tcmdBuf[i++] = 0;\n\n\tcmdBuf[i++] = 0;\n\tcmdBuf[i++] = iClockRate;\n\n\tfor (j = 0; j < 4; j++)\n\t\tcmdBuf[i++] = ch347.TCK | ch347.TDI | ch347.TMS | ch347.TRST | ch347.SRST;\n\n\tunsigned long int mLength = i;\n\tif (!CH347WriteData(iIndex, cmdBuf, &mLength) || (mLength != i))\n\t\treturn false;\n\n\tmLength = 4;\n\tmemset(cmdBuf, 0, sizeof(cmdBuf));\n\n\tif (!CH347ReadData(iIndex, cmdBuf, &mLength) || (mLength != 4))\n\t\treturn false;\n\n\tretVal = ((cmdBuf[0] == CH347_CMD_JTAG_INIT) && \\\n\t\t  (cmdBuf[CH347_CMD_HEADER] == 0));\n\treturn retVal;\n}\n\nstatic bool CH347Jtag_INIT(uint64_t iIndex, uint8_t iClockRate)\n{\n\tch347.pack_size = (Check_Speed(iIndex, 0x09) == true) ? \\\n\t\tSTANDARD_PACK : LARGER_PACK;\n\tif (ch347.pack_size == STANDARD_PACK) {\n\t\tif (iClockRate - 2 < 0)\n\t\t\treturn Check_Speed(iIndex, 0);\n\t\telse\n\t\t\treturn Check_Speed(iIndex, iClockRate - 2);\n\t}\n\treturn Check_Speed(iIndex, iClockRate);\n}\n\n/**\n * ch347_speed - CH347 TCK frequency setting\n *  @param speed Frequency size set\n *  @return Success returns ERROR_OK,failed returns FALSE\n */\nstatic int ch347_speed(int speed)\n{\n\tunsigned long i = 0;\n\tuint8_t clockRate;\n\tint retval = -1;\n\tint speed_clock[8] = {\n\t\tKHZ(468.75), KHZ(937.5), MHZ(1.875),\n\t\tMHZ(3.75), MHZ(7.5), MHZ(15), MHZ(30), MHZ(60)\n\t};\n\n\tif (!swd_mode) {\n\t\tfor (i = 0; i < ARRAY_SIZE(speed_clock); i++) {\n\t\t\tif ((speed >= speed_clock[i]) &&\n\t\t\t    (speed <= speed_clock[i + 1])) {\n\t\t\t\tclockRate = i + 1;\n\t\t\t\tretval = CH347Jtag_INIT(ugIndex, clockRate);\n\t\t\t\tif (!retval) {\n\t\t\t\t\tLOG_ERROR(\"Couldn't set CH347 TCK speed\");\n\t\t\t\t\treturn retval;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if (speed < speed_clock[0]) {\n\t\t\t\tretval = CH347Jtag_INIT(ugIndex, 0);\n\t\t\t\tif (!retval) {\n\t\t\t\t\tLOG_ERROR(\"Couldn't set CH347 TCK speed\");\n\t\t\t\t\treturn retval;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t\tif (speed > MHZ(5) ) {\n\t\t\t\tCH347SWD_INIT(ugIndex, 0);  //5Mhz\n\t\t\t} else if (speed <= MHZ(5) && speed >= MHZ(1)) {\n\t\t\t\tCH347SWD_INIT(ugIndex, 1);  //1Mhz\n\t\t\t} else {\n\t\t\t\tCH347SWD_INIT(ugIndex, 2);  //500Khz\n\t\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ch347_speed_div(int speed, int *khz)\n{\n\t*khz = speed / 1000;\n\treturn ERROR_OK;\n}\n\nstatic int ch347_khz(int khz, int *jtag_speed)\n{\n\tif (khz == 0) {\n\t\tLOG_ERROR(\"Couldn't support the adapter speed\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*jtag_speed = khz * 1000;\n\treturn ERROR_OK;\n}\n\nstatic int ch347_trst_out(unsigned char status)\n{\n\tunsigned long int BI = 0;\n\tunsigned char byte = 0;\n\tunsigned char cmdPacket[4] = \"\";\n\tcmdPacket[BI++] = CH347_CMD_JTAG_BIT_OP;\n\tcmdPacket[BI++] = 0x01;\n\tcmdPacket[BI++] = 0;\n\tbyte = ch347.TCK | ch347.TDI | ch347.TMS | (ch347.TRST =\n\t\t\t\t\t\t    (status ? TRST_H : TRST_L));\n\tcmdPacket[BI++] = byte;\n\n\tif (!CH347_Write(cmdPacket, &BI)) {\n\t\tLOG_ERROR(\"TRST set failure.\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ch347_handle_vid_pid_command)\n{\n\t/* TODO */\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ch347_trst)\n{\n\tch347_trst_out(TRST_L);\n\tjtag_sleep(atoi(CMD_ARGV[0]) * 1000);\n\tch347_trst_out(TRST_H);\n\treturn ERROR_OK;\n}\nCOMMAND_HANDLER(ch347_set_index)\n{\n\tLOG_INFO(\"ch347_index is %d\", atoi(CMD_ARGV[0]));\n\tugIndex = atoi(CMD_ARGV[0]);\n\t\n\treturn ERROR_OK;\n}\n/* Obtaining the device sn is a follow-up function. Temporarily unavailable */\n\nCOMMAND_HANDLER(ch347_set_busdev)\n{\n#ifdef __linux__\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\t\n\tLOG_INFO(\"ch347_set_busdev is %d and %d\", atoi(CMD_ARGV[0]), atoi(CMD_ARGV[1]));\n\tg_bus_num = atoi(CMD_ARGV[0]);\n\tg_device_addr = atoi(CMD_ARGV[1]);\n\treturn ERROR_OK;\n#endif\n}\n\nstatic const struct command_registration ch347_subcommand_handlers[] = {\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = &ch347_handle_vid_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"ch347_index\",\n\t\t.handler = &ch347_set_index,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"set deivice index of the CH347\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"jtag_ntrst_delay\",\n\t\t.handler = &ch347_trst,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"set the trst of the CH347 device that is used as JTAG\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"busdev-num\",\n\t\t.handler = &ch347_set_busdev,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"set bus_num and device_addr of the CH347\",\n\t\t.usage = \"\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE};\n\nstatic const struct command_registration ch347_command_handlers[] = {\n\t{\n\t\t.name = \"ch347\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform ch347 management\",\n\t\t.chain = ch347_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE};\n\nstatic int ch347_swd_init(void)\n{\n\tPCH347_SWD_IO pswd_io;\n\tLOG_INFO(\"CH347 SWD mode enabled\");\n\tswd_mode = true;\n\tmemset(&ch347_swd_context, 0, sizeof(ch347_swd_context));\n\n\tINIT_LIST_HEAD(&ch347_swd_context.send_cmd_head);\n\tINIT_LIST_HEAD(&ch347_swd_context.free_cmd_head);\n\n\tch347_swd_context.queued_retval = ERROR_OK;\n\t/* 0XE8 + 2byte len + N byte cmds */\n\tch347_swd_context.send_len = CH347_CMD_HEADER;\n\t/*  0XE8 + 2byte len + N byte ack + data */\n\tch347_swd_context.need_recv_len = CH347_CMD_HEADER;\n\tch347_swd_context.ch347_cmd_buf = malloc(128 * sizeof(CH347_SWD_IO));\n\tif (ch347_swd_context.ch347_cmd_buf) {\n\t\tpswd_io = (PCH347_SWD_IO)ch347_swd_context.ch347_cmd_buf;\n\t\tfor (int i = 0; i < 128; i++, pswd_io++) {\n\t\t\tINIT_LIST_HEAD(&pswd_io->list_entry);\n\t\t\tlist_add_tail(&pswd_io->list_entry,\n\t\t\t\t      &ch347_swd_context.free_cmd_head);\n\t\t}\n\t}\n\treturn ch347_swd_context.ch347_cmd_buf ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic PCH347_SWD_IO ch347_get_one_swd_io(void)\n{\n\tPCH347_SWD_IO pswd_io;\n\tif (list_empty(&ch347_swd_context.free_cmd_head)) {\n\t\treturn NULL;\n\t} else {\n\t\tpswd_io = list_first_entry(&ch347_swd_context.free_cmd_head,\n\t\t\t\t\t   CH347_SWD_IO, list_entry);\n\t\tlist_del_init(&pswd_io->list_entry);\n\t\tpswd_io->cmd = 0;\n\t\tpswd_io->usbcmd = CH347_CMD_SWD_SEQ_W;\n\t\tpswd_io->dst = NULL;\n\t\treturn pswd_io;\n\t}\n}\n\nstatic void ch347_swd_queue_flush(void)\n{\n\tunsigned long mLength = ch347_swd_context.send_len;\n\tch347_swd_context.send_buf[0] = (uint8_t)CH347_CMD_SWD;\n\tch347_swd_context.send_buf[1] = (uint8_t)(ch347_swd_context.send_len -\n\t\t\t\t\t\t  CH347_CMD_HEADER);\n\tch347_swd_context.send_buf[2] = (uint8_t)((ch347_swd_context.send_len -\n\t\t\t\t\t\t   CH347_CMD_HEADER) >> 8);\n\tif (!CH347WriteData(ugIndex, ch347_swd_context.send_buf, &mLength) ||\n\t    (mLength != ch347_swd_context.send_len)) {\n\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\tLOG_DEBUG(\"CH347WriteData error \");\n\t\treturn;\n\t}\n\tch347_swd_context.recv_len = 0;\n\tdo {\n\t\tmLength = CH347_MAX_RECV_BUF - ch347_swd_context.recv_len;\n\t\tif (!CH347ReadData(ugIndex,\n\t\t\t\t   &ch347_swd_context.recv_buf[ch347_swd_context.recv_len],\n\t\t\t\t   &mLength)) {\n\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\tLOG_DEBUG(\"CH347ReadData error \");\n\t\t\treturn;\n\t\t}\n\t\tch347_swd_context.recv_len += mLength;\n\t} while (ch347_swd_context.recv_len < ch347_swd_context.need_recv_len);\n\n\tif (ch347_swd_context.need_recv_len > ch347_swd_context.recv_len) {\n\t\tLOG_ERROR(\"ch347_swd_queue_flush write/read failed %d %d %d\",\n\t\t\t  __LINE__,\n\t\t\t  ch347_swd_context.recv_len,\n\t\t\t  ch347_swd_context.need_recv_len);\n\t}\n}\nstatic void ch347_wrtie_swd_reg(uint8_t cmd, const uint8_t *out, uint8_t parity)\n{\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] =\n\t\tCH347_CMD_SWD_REG_W;\n\t/* 8bit + 32bit +1bit */\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x29;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x00;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = cmd;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[0];\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[1];\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[2];\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = out[3];\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = parity;\n\t/* 0xA0 +  1 byte(3bit ACK) */\n\tch347_swd_context.need_recv_len += (1 + 1);\n}\n\nstatic void ch347_wrtie_spec_seq(const uint8_t *out, uint8_t out_len)\n{\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] =\n\t\tCH347_CMD_SWD_SEQ_W;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = out_len;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x00;\n\tfor (uint8_t i = 0; i < DIV_ROUND_UP(out_len, 8); i++) {\n\t\tif (out) {\n\t\t\tch347_swd_context.send_buf[ch347_swd_context.send_len++]\n\t\t\t\t= out[i];\n\t\t} else {\n\t\t\tch347_swd_context.send_buf[ch347_swd_context.send_len++]\n\t\t\t\t= 0x00;\n\t\t}\n\t}\n\tch347_swd_context.need_recv_len += 1; /* 0xA1 */\n}\n\nstatic void ch347_read_swd_reg(uint8_t cmd)\n{\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] =\n\t\tCH347_CMD_SWD_REG_R;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x22;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = 0x00;\n\tch347_swd_context.send_buf[ch347_swd_context.send_len++] = cmd;\n\t/* 0xA2 + 1 byte(3bit ACK) + 4 byte(data) +\n\t   1 byte(1bit parity+1bit trn) */\n\tch347_swd_context.need_recv_len += 1 + 1 + 4 + 1;\n}\n\nstatic int ch347_swd_switch_out(enum swd_special_seq seq, const uint8_t *out,\n\t\t\t\tunsigned out_len)\n{\n\tPCH347_SWD_IO pswd_io;\n\tif ((ch347_swd_context.send_len +\n\t     (1 + 2 + DIV_ROUND_UP(out_len, 8))) > CH347_MAX_SEND_BUF) {\n\t\treturn ERROR_FAIL;\n\t}\n\tif ((ch347_swd_context.need_recv_len + 2) > CH347_MAX_RECV_BUF)\n\t\treturn ERROR_FAIL;\n\n\tpswd_io = ch347_get_one_swd_io();\n\tif (pswd_io) {\n\t\tch347_wrtie_spec_seq(out, out_len);\n\t\tlist_add_tail(&pswd_io->list_entry,\n\t\t\t      &ch347_swd_context.send_cmd_head);\n\t\treturn ERROR_OK;\n\t} else {\n\t\treturn ERROR_FAIL;\n\t}\n}\n\n/* check read/write REG can fill in remaining buff */\nstatic bool ch347_chk_buf_size(uint8_t cmd, uint32_t ap_delay_clk)\n{\n\tbool bflush;\n\tuint32_t send_len, recv_len, len;\n\tbflush = false;\n\tsend_len = ch347_swd_context.send_len;\n\trecv_len = ch347_swd_context.need_recv_len;\n\tdo {\n\n\t\tif (cmd & SWD_CMD_RNW) {\n\t\t\tlen = 1 + 1 + 1 + 1; /* 0xA2 + len + rev + cmd */\n\t\t\tif (send_len + len > CH347_MAX_SEND_BUF)\n\t\t\t\tbreak;\n\t\t\tsend_len += len;\n\t\t\tlen = 1 + 1 + 4 + 1;\n\t\t\t/* 0xA2 + 1byte(3bit ack) +  4byte(data) +\n\t\t\t   1byte(1bit parity+1bit trn) */\n\t\t\tif (recv_len + len > CH347_MAX_RECV_BUF)\n\t\t\t\tbreak;\n\t\t\trecv_len += len;\n\t\t} else {                         /* write reg */\n\t\t\tlen = 1 + 1 + 1 + 1 + 4 + 1;\n\t\t\t/* 0xA0 + len + rev  + cmd +data + parity */\n\t\t\tif (send_len + len > CH347_MAX_SEND_BUF)\n\t\t\t\tbreak;\n\t\t\tsend_len += len;\n\t\t\tlen = 1 + 1; /* 0xA0 + 1byte(3bit ack) */\n\t\t\tif (recv_len + len > CH347_MAX_RECV_BUF)\n\t\t\t\tbreak;\n\t\t\trecv_len += len;\n\t\t}\n\t\tif (cmd & SWD_CMD_APNDP) {\n\t\t\tlen = 1 + 1 + 1 + DIV_ROUND_UP(ap_delay_clk, 8);\n\t\t\t/* 0xA1 + Len  + rev  + n byte(delay) */\n\t\t\tif (send_len + len > CH347_MAX_SEND_BUF)\n\t\t\t\tbreak;\n\t\t\tlen = 1; /* 0xA1 */\n\t\t\tif ((recv_len + len) > CH347_MAX_RECV_BUF)\n\t\t\t\tbreak;\n\t\t}\n\t\t/* swd packet requests */\n\t\tbflush = true;\n\t} while (false);\n\n\treturn bflush;\n}\n\nstatic void ch347_swd_send_idle(uint32_t ap_delay_clk)\n{\n\tPCH347_SWD_IO pswd_io;\n\n\tpswd_io = ch347_get_one_swd_io();\n\tif (!pswd_io) {\n\t\tch347_swd_run_queue();\n\t\tpswd_io = ch347_get_one_swd_io();\n\t\tif (!pswd_io) {\n\t\t\tLOG_DEBUG(\"ch347_swd_queue_cmd error \");\n\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\treturn;\n\t\t}\n\t}\n\tch347_wrtie_spec_seq(NULL, ap_delay_clk);\n\n\tlist_add_tail(&pswd_io->list_entry, &ch347_swd_context.send_cmd_head);\n}\n\nstatic void ch347_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data,\n\t\t\t\tuint32_t ap_delay_clk)\n{\n\tPCH347_SWD_IO pswd_io;\n\tif (ap_delay_clk > 255)\n\t\tprintf(\"ch347_swd_queue_cmd ap_delay_clk = %d\\r\\n\",\n\t\t       ap_delay_clk);\n\n\tif (ch347_swd_context.sent_cmd_count >= CH347_MAX_SEND_CMD)\n\t\tch347_swd_run_queue();\n\n\tif (!ch347_chk_buf_size(cmd, ap_delay_clk))\n\t\tch347_swd_run_queue();\n\n\tpswd_io = ch347_get_one_swd_io();\n\tif (!pswd_io) {\n\t\tch347_swd_run_queue();\n\t\tpswd_io = ch347_get_one_swd_io();\n\t\tif (!pswd_io) {\n\t\t\tLOG_DEBUG(\"ch347_swd_queue_cmd error \");\n\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tpswd_io->cmd = cmd | SWD_CMD_START | SWD_CMD_PARK;\n\n\tif (pswd_io->cmd & SWD_CMD_RNW) {\n\t\tpswd_io->usbcmd = CH347_CMD_SWD_REG_R;\n\t\tpswd_io->dst = dst;\n\t\tch347_read_swd_reg(pswd_io->cmd);\n\t} else {\n\t\tpswd_io->usbcmd = CH347_CMD_SWD_REG_W;\n\t\tpswd_io->value = data;\n\t\tch347_wrtie_swd_reg(pswd_io->cmd, (uint8_t *)&data,\n\t\t\t\t    parity_u32(data));\n\t}\n\n\tch347_swd_context.sent_cmd_count++;\n\tlist_add_tail(&pswd_io->list_entry, &ch347_swd_context.send_cmd_head);\n\t/* Insert idle cycles after AP accesses to avoid WAIT */\n\tif (cmd & SWD_CMD_APNDP) {\n\t\tif (ap_delay_clk == 0)\n\t\t\tprintf(\"ap_delay_clk == 0\");\n\t\tch347_swd_send_idle(ap_delay_clk);\n\t}\n}\n\nstatic int ch347_swd_switch_seq(enum swd_special_seq seq)\n{\n\tprintf(\"ch347_swd_switch_seq %d \\r\\n\", seq);\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG(\"SWD line reset\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_line_reset,\n\t\t\t\t\t    swd_seq_line_reset_len);\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_jtag_to_swd,\n\t\t\t\t\t    swd_seq_jtag_to_swd_len);\n\tcase JTAG_TO_DORMANT:\n\t\tLOG_DEBUG(\"JTAG-to-DORMANT\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_jtag_to_dormant,\n\t\t\t\t\t    swd_seq_jtag_to_dormant_len);\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_swd_to_jtag,\n\t\t\t\t\t    swd_seq_swd_to_jtag_len);\n\tcase SWD_TO_DORMANT:\n\t\tLOG_DEBUG(\"SWD-to-DORMANT\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_swd_to_dormant,\n\t\t\t\t\t    swd_seq_swd_to_dormant_len);\n\tcase DORMANT_TO_SWD:\n\t\tLOG_DEBUG(\"DORMANT-to-SWD\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_dormant_to_swd,\n\t\t\t\t\t    swd_seq_dormant_to_swd_len);\n\tcase DORMANT_TO_JTAG:\n\t\tLOG_DEBUG(\"DORMANT-to-JTAG\");\n\t\treturn ch347_swd_switch_out(seq, swd_seq_dormant_to_jtag,\n\t\t\t\t\t    swd_seq_dormant_to_jtag_len);\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nstatic void ch347_swd_read_reg(uint8_t cmd, uint32_t *value,\n\t\t\t       uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\tch347_swd_queue_cmd(cmd, value, 0, ap_delay_clk);\n}\n\nstatic void ch347_swd_write_reg(uint8_t cmd, uint32_t value,\n\t\t\t\tuint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\tch347_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);\n}\n\nstatic int ch347_swd_run_queue(void)\n{\n\tLOG_DEBUG_IO(\"Executing %u queued transactions\",\n\t\t     ch347_swd_context.sent_cmd_count);\n\tint retval, parity;\n\tstruct list_head *tmp, *pos;\n\tuint8_t *recv_buf;\n\tuint32_t recv_len, cmds_len, data;\n\tPCH347_SWD_IO pswd_io;\n\tif (ch347_swd_context.queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Skipping due to previous errors: %d\",\n\t\t\t     ch347_swd_context.queued_retval);\n\t\tgoto skip;\n\t}\n\n\t/* A transaction must be followed by another transaction or at least 8\n\t   idle cycles to ensure that data is clocked through the AP. */\n\tif ((ch347_swd_context.send_len + (1 + 2 + 1)) > CH347_MAX_SEND_BUF)\n\t\tgoto skip_idle;\n\n\tif ((ch347_swd_context.need_recv_len + 1) > CH347_MAX_RECV_BUF)\n\t\tgoto skip_idle;\n\n\tch347_swd_send_idle(8);\n\nskip_idle:\n\n\tch347_swd_queue_flush();\n\n\tif (ch347_swd_context.queued_retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CH347 usb write/read failed %d\", __LINE__);\n\t\tgoto skip;\n\t}\n\trecv_buf = ch347_swd_context.recv_buf;\n\trecv_len = 0;\n\tif (recv_buf[recv_len++] != CH347_CMD_SWD) { /* 0XE8 */\n\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\tLOG_ERROR(\"CH347 usb write/read failed %d\", __LINE__);\n\t\tgoto skip;\n\t}\n\n\tcmds_len = BUILD_UINT16(recv_buf[recv_len], recv_buf[recv_len + 1]);\n\trecv_len += 2; /* cmds_len */\n\tif ((cmds_len + CH347_CMD_HEADER) > ch347_swd_context.recv_len) {\n\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\tLOG_ERROR(\"CH347 usb write/read failed %d\", __LINE__);\n\t\tgoto skip;\n\t}\n\n\tlist_for_each_safe(pos, tmp, &ch347_swd_context.send_cmd_head) {\n\t\tpswd_io = list_entry(pos, CH347_SWD_IO, list_entry);\n\t\tif (pswd_io->usbcmd == CH347_CMD_SWD_SEQ_W) {\n\t\t\tif (recv_buf[recv_len++] != CH347_CMD_SWD_SEQ_W) {\n\t\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\t\tLOG_ERROR(\"CH347 usb write/read failed %d\",\n\t\t\t\t\t  __LINE__);\n\t\t\t\tgoto skip;\n\t\t\t}\n\t\t} else { /* read/write Reg */\n\t\t\tint ack;\n\t\t\tbool check_ack;\n\t\t\t/* read  Reg */\n\t\t\tif (recv_buf[recv_len] == CH347_CMD_SWD_REG_R) {\n\t\t\t\trecv_len++;\n\t\t\t\tack = buf_get_u32(&recv_buf[recv_len++], 0, 3);\n\t\t\t\t/* Devices do not reply to DP_TARGETSEL write\n\t\t\t\t   cmd, ignore received ack */\n\t\t\t\tcheck_ack = swd_cmd_returns_ack(pswd_io->cmd);\n\t\t\t\tif (ack != SWD_ACK_OK && check_ack) {\n\t\t\t\t\tch347_swd_context.queued_retval =\n\t\t\t\t\t\tswd_ack_to_error_code(ack);\n\t\t\t\t\tLOG_ERROR(\"ack != SWD_ACK_OK %d\",\n\t\t\t\t\t\t  __LINE__);\n\t\t\t\t\tgoto skip;\n\t\t\t\t}\n\t\t\t\tif (pswd_io->cmd & SWD_CMD_RNW) {\n\t\t\t\t\tdata = buf_get_u32(&recv_buf[recv_len],\n\t\t\t\t\t\t\t   0, 32);\n\t\t\t\t\tparity = buf_get_u32(\n\t\t\t\t\t\t&recv_buf[recv_len], 32, 1);\n\t\t\t\t\tif (parity != parity_u32(data)) {\n\t\t\t\t\t\tLOG_ERROR(\"SWD Read data parity mismatch %d\",\n\t\t\t\t\t\t\t  __LINE__);\n\t\t\t\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\t\t\t\tgoto skip;\n\t\t\t\t\t}\n\n\t\t\t\t\tLOG_DEBUG_IO(\"%s%s %s %s reg %X = %08X\\n\" PRIx32,\n\t\t\t\t\t\t     check_ack ? \"\" : \"ack ignored \",\n\t\t\t\t\t\t     ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : \\\n\t\t\t\t\t\t     ack == SWD_ACK_FAULT  ? \"FAULT\" : \"JUNK\",\n\t\t\t\t\t\t     pswd_io->cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t\t\t\t     pswd_io->cmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t\t\t\t     (pswd_io->cmd & SWD_CMD_A32) >> 1,\n\t\t\t\t\t\t     data);\n\n\t\t\t\t\tif (pswd_io->dst)\n\t\t\t\t\t\t*pswd_io->dst = data;\n\t\t\t\t} else {\n\t\t\t\t\tch347_swd_context.queued_retval =\n\t\t\t\t\t\tERROR_FAIL;\n\t\t\t\t\tLOG_ERROR(\"CH347 usb write/read failed %d\", __LINE__);\n\t\t\t\t\tgoto skip;\n\t\t\t\t}\n\t\t\t\trecv_len += 5;\n\t\t\t} else if (recv_buf[recv_len] == CH347_CMD_SWD_REG_W) {\n\t\t\t\trecv_len++;\n\t\t\t\tack = buf_get_u32(&recv_buf[recv_len++], 0, 3);\n\t\t\t\t/* Devices do not reply to DP_TARGETSEL write\n\t\t\t\t   cmd, ignore received ack */\n\t\t\t\tcheck_ack = swd_cmd_returns_ack(pswd_io->cmd);\n\t\t\t\tif (ack != SWD_ACK_OK && check_ack) {\n\t\t\t\t\tch347_swd_context.queued_retval =\n\t\t\t\t\t\tswd_ack_to_error_code(ack);\n\t\t\t\t\tLOG_ERROR(\"SWD Read data parity mismatch%d\", __LINE__);\n\t\t\t\t\tgoto skip;\n\t\t\t\t}\n\t\t\t\tLOG_DEBUG_IO(\"%s%s %s %s reg %X = %08X\\n\" PRIx32,\n\t\t\t\t\t     check_ack ? \"\" : \"ack ignored \",\n\t\t\t\t\t     ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : \\\n\t\t\t\t\t     ack == SWD_ACK_FAULT  ? \"FAULT\" : \"JUNK\",\n\t\t\t\t\t     pswd_io->cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t\t\t     pswd_io->cmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t\t\t     (pswd_io->cmd & SWD_CMD_A32) >> 1,\n\t\t\t\t\t     pswd_io->value);\n\t\t\t} else {\n\t\t\t\tch347_swd_context.queued_retval = ERROR_FAIL;\n\t\t\t\tLOG_ERROR(\"CH347 usb write/read failed %d recv_len = %d\",\n\t\t\t\t\t  __LINE__, recv_len);\n\t\t\t\tgoto skip;\n\t\t\t}\n\t\t}\n\t\tlist_del_init(&pswd_io->list_entry);\n\t\tlist_add_tail(&pswd_io->list_entry,\n\t\t\t      &ch347_swd_context.free_cmd_head);\n\t}\n\nskip:\n\tif (!list_empty(&ch347_swd_context.send_cmd_head)) {\n\t\tlist_for_each_safe(pos, tmp, &ch347_swd_context.send_cmd_head)\n\t\t{\n\t\t\tpswd_io = list_entry(pos, CH347_SWD_IO, list_entry);\n\t\t\tlist_del_init(&pswd_io->list_entry);\n\t\t\tlist_add_tail(&pswd_io->list_entry,\n\t\t\t\t      &ch347_swd_context.free_cmd_head);\n\t\t}\n\t}\n\t/* 0xE8 + 2byte len */\n\tch347_swd_context.send_len = CH347_CMD_HEADER;\n\t/* 0xE8 + 2byte len */\n\tch347_swd_context.need_recv_len = CH347_CMD_HEADER;\n\tch347_swd_context.recv_len = 0;\n\tch347_swd_context.sent_cmd_count = 0;\n\tretval = ch347_swd_context.queued_retval;\n\tch347_swd_context.queued_retval = ERROR_OK;\n\n\treturn retval;\n}\n\nstatic const struct swd_driver ch347_swd = {\n\t.init = ch347_swd_init,\n\t.switch_seq = ch347_swd_switch_seq,\n\t.read_reg = ch347_swd_read_reg,\n\t.write_reg = ch347_swd_write_reg,\n\t.run = ch347_swd_run_queue,\n};\n\nstatic const char *const ch347_transports[] = {\"jtag\", \"swd\", NULL};\n\nstatic struct jtag_interface ch347_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = ch347_execute_queue,\n};\n\nstruct adapter_driver ch347_adapter_driver = {\n\t.name = \"ch347\",\n\t.transports = ch347_transports,\n\t.commands = ch347_command_handlers,\n\n\t.init = ch347_init,\n\t.quit = ch347_quit,\n\t.reset = ch347_reset,\n\t.speed = ch347_speed,\n\t.khz = ch347_khz,\n\t.speed_div = ch347_speed_div,\n\n\t.jtag_ops = &ch347_interface,\n\t.swd_ops = &ch347_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/cmsis_dap.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2021 by Adrian Negreanu                                 *\n *   groleo@gmail.com                                                      *\n *                                                                         *\n *   Copyright (C) 2018 by Mickaël Thomas                                  *\n *   mickael9@gmail.com                                                    *\n *                                                                         *\n *   Copyright (C) 2016 by Maksym Hilliaka                                 *\n *   oter@frozen-team.com                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Phillip Pearson                                 *\n *   pp@myelin.co.nz                                                       *\n *                                                                         *\n *   Copyright (C) 2014 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n *                                                                         *\n *   Copyright (C) 2013 by mike brown                                      *\n *   mike@theshedworks.org.uk                                              *\n *                                                                         *\n *   Copyright (C) 2013 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <transport/transport.h>\n#include \"helper/replacements.h\"\n#include <jtag/adapter.h>\n#include <jtag/swd.h>\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <jtag/tcl.h>\n#include <target/cortex_m.h>\n\n#include \"cmsis_dap.h\"\n#include \"libusb_helper.h\"\n\nstatic const struct cmsis_dap_backend *const cmsis_dap_backends[] = {\n#if BUILD_CMSIS_DAP_USB == 1\n\t&cmsis_dap_usb_backend,\n#endif\n\n#if BUILD_CMSIS_DAP_HID == 1\n\t&cmsis_dap_hid_backend,\n#endif\n};\n\n/* USB Config */\n\n/* Known vid/pid pairs:\n * VID 0xc251: Keil Software\n * PID 0xf001: LPC-Link-II CMSIS_DAP\n * PID 0xf002: OPEN-SDA CMSIS_DAP (Freedom Board)\n * PID 0x2722: Keil ULINK2 CMSIS-DAP\n * PID 0x2750: Keil ULINKplus CMSIS-DAP\n *\n * VID 0x0d28: mbed Software\n * PID 0x0204: MBED CMSIS-DAP\n */\n\n#define MAX_USB_IDS 8\n/* vid = pid = 0 marks the end of the list */\nstatic uint16_t cmsis_dap_vid[MAX_USB_IDS + 1] = { 0 };\nstatic uint16_t cmsis_dap_pid[MAX_USB_IDS + 1] = { 0 };\nstatic int cmsis_dap_backend = -1;\nstatic bool swd_mode;\n\n/* CMSIS-DAP General Commands */\n#define CMD_DAP_INFO              0x00\n#define CMD_DAP_LED               0x01\n#define CMD_DAP_CONNECT           0x02\n#define CMD_DAP_DISCONNECT        0x03\n#define CMD_DAP_WRITE_ABORT       0x08\n#define CMD_DAP_DELAY             0x09\n#define CMD_DAP_RESET_TARGET      0x0A\n\n/* CMD_INFO */\n#define INFO_ID_VENDOR            0x01      /* string */\n#define INFO_ID_PRODUCT           0x02      /* string */\n#define INFO_ID_SERNUM            0x03      /* string */\n#define INFO_ID_FW_VER            0x04      /* string */\n#define INFO_ID_TD_VEND           0x05      /* string */\n#define INFO_ID_TD_NAME           0x06      /* string */\n#define INFO_ID_CAPS              0xf0      /* byte */\n#define INFO_ID_PKT_CNT           0xfe      /* byte */\n#define INFO_ID_PKT_SZ            0xff      /* short */\n#define INFO_ID_SWO_BUF_SZ        0xfd      /* word */\n\n#define INFO_CAPS_SWD                 BIT(0)\n#define INFO_CAPS_JTAG                BIT(1)\n#define INFO_CAPS_SWO_UART            BIT(2)\n#define INFO_CAPS_SWO_MANCHESTER      BIT(3)\n#define INFO_CAPS_ATOMIC_CMDS         BIT(4)\n#define INFO_CAPS_TEST_DOMAIN_TIMER   BIT(5)\n#define INFO_CAPS_SWO_STREAMING_TRACE BIT(6)\n#define INFO_CAPS_UART_PORT           BIT(7)\n#define INFO_CAPS_USB_COM_PORT        BIT(8)\n#define INFO_CAPS__NUM_CAPS               9\n\n/* CMD_LED */\n#define LED_ID_CONNECT            0x00\n#define LED_ID_RUN                0x01\n\n#define LED_OFF                   0x00\n#define LED_ON                    0x01\n\n/* CMD_CONNECT */\n#define CONNECT_DEFAULT           0x00\n#define CONNECT_SWD               0x01\n#define CONNECT_JTAG              0x02\n\n/* CMSIS-DAP Common SWD/JTAG Commands */\n#define CMD_DAP_DELAY             0x09\n#define CMD_DAP_SWJ_PINS          0x10\n#define CMD_DAP_SWJ_CLOCK         0x11\n#define CMD_DAP_SWJ_SEQ           0x12\n\n/*\n * PINS\n * Bit 0: SWCLK/TCK\n * Bit 1: SWDIO/TMS\n * Bit 2: TDI\n * Bit 3: TDO\n * Bit 5: nTRST\n * Bit 7: nRESET\n */\n\n#define SWJ_PIN_TCK               (1<<0)\n#define SWJ_PIN_TMS               (1<<1)\n#define SWJ_PIN_TDI               (1<<2)\n#define SWJ_PIN_TDO               (1<<3)\n#define SWJ_PIN_TRST              (1<<5)\n#define SWJ_PIN_SRST              (1<<7)\n\n/* CMSIS-DAP SWD Commands */\n#define CMD_DAP_SWD_CONFIGURE     0x13\n#define CMD_DAP_SWD_SEQUENCE      0x1D\n\n/* CMSIS-DAP JTAG Commands */\n#define CMD_DAP_JTAG_SEQ          0x14\n#define CMD_DAP_JTAG_CONFIGURE    0x15\n#define CMD_DAP_JTAG_IDCODE       0x16\n\n/* CMSIS-DAP JTAG sequence info masks */\n/* Number of bits to clock through (0 means 64) */\n#define DAP_JTAG_SEQ_TCK          0x3F\n/* TMS will be set during the sequence if this bit is set */\n#define DAP_JTAG_SEQ_TMS          0x40\n/* TDO output will be captured if this bit is set */\n#define DAP_JTAG_SEQ_TDO          0x80\n\n\n/* CMSIS-DAP Transfer Commands */\n#define CMD_DAP_TFER_CONFIGURE    0x04\n#define CMD_DAP_TFER              0x05\n#define CMD_DAP_TFER_BLOCK        0x06\n#define CMD_DAP_TFER_ABORT        0x07\n\n/* DAP_TransferBlock increases the sum of command/response sizes\n * (due to 16-bit Transfer Count) if used in a small packet.\n * Prevent using it until we have at least r/w operations. */\n#define CMD_DAP_TFER_BLOCK_MIN_OPS 4\n\n/* DAP Status Code */\n#define DAP_OK                    0\n#define DAP_ERROR                 0xFF\n\n/* CMSIS-DAP SWO Commands */\n#define CMD_DAP_SWO_TRANSPORT     0x17\n#define CMD_DAP_SWO_MODE          0x18\n#define CMD_DAP_SWO_BAUDRATE      0x19\n#define CMD_DAP_SWO_CONTROL       0x1A\n#define CMD_DAP_SWO_STATUS        0x1B\n#define CMD_DAP_SWO_DATA          0x1C\n#define CMD_DAP_SWO_EX_STATUS     0x1E\n\n/* SWO transport mode for reading trace data */\n#define DAP_SWO_TRANSPORT_NONE    0\n#define DAP_SWO_TRANSPORT_DATA    1\n#define DAP_SWO_TRANSPORT_WINUSB  2\n\n/* SWO trace capture mode */\n#define DAP_SWO_MODE_OFF          0\n#define DAP_SWO_MODE_UART         1\n#define DAP_SWO_MODE_MANCHESTER   2\n\n/* SWO trace data capture */\n#define DAP_SWO_CONTROL_STOP      0\n#define DAP_SWO_CONTROL_START     1\n\n/* SWO trace status */\n#define DAP_SWO_STATUS_CAPTURE_INACTIVE      0\n#define DAP_SWO_STATUS_CAPTURE_ACTIVE        1\n#define DAP_SWO_STATUS_CAPTURE_MASK          BIT(0)\n#define DAP_SWO_STATUS_STREAM_ERROR_MASK     BIT(6)\n#define DAP_SWO_STATUS_BUFFER_OVERRUN_MASK   BIT(7)\n\n/* CMSIS-DAP Vendor Commands\n * None as yet... */\n\nstatic const char * const info_caps_str[INFO_CAPS__NUM_CAPS] = {\n\t\"SWD supported\",\n\t\"JTAG supported\",\n\t\"SWO-UART supported\",\n\t\"SWO-MANCHESTER supported\",\n\t\"Atomic commands supported\",\n\t\"Test domain timer supported\",\n\t\"SWO streaming trace supported\",\n\t\"UART communication port supported\",\n\t\"UART via USB COM port supported\",\n};\n\nstruct pending_scan_result {\n\t/** Offset in bytes in the CMD_DAP_JTAG_SEQ response buffer. */\n\tunsigned int first;\n\t/** Number of bits to read. */\n\tunsigned int length;\n\t/** Location to store the result */\n\tuint8_t *buffer;\n\t/** Offset in the destination buffer */\n\tunsigned int buffer_offset;\n};\n\n/* Each block in FIFO can contain up to pending_queue_len transfers */\nstatic unsigned int pending_queue_len;\nstatic unsigned int tfer_max_command_size;\nstatic unsigned int tfer_max_response_size;\n\n/* pointers to buffers that will receive jtag scan results on the next flush */\n#define MAX_PENDING_SCAN_RESULTS 256\nstatic int pending_scan_result_count;\nstatic struct pending_scan_result pending_scan_results[MAX_PENDING_SCAN_RESULTS];\n\n/* queued JTAG sequences that will be executed on the next flush */\n#define QUEUED_SEQ_BUF_LEN (cmsis_dap_handle->packet_usable_size - 3)\nstatic int queued_seq_count;\nstatic int queued_seq_buf_end;\nstatic int queued_seq_tdo_ptr;\nstatic uint8_t queued_seq_buf[1024]; /* TODO: make dynamic / move into cmsis object */\n\nstatic int queued_retval;\n\nstatic uint8_t output_pins = SWJ_PIN_SRST | SWJ_PIN_TRST;\n\nstatic struct cmsis_dap *cmsis_dap_handle;\n\n\nstatic int cmsis_dap_quit(void);\n\nstatic int cmsis_dap_open(void)\n{\n\tconst struct cmsis_dap_backend *backend = NULL;\n\n\tstruct cmsis_dap *dap = calloc(1, sizeof(struct cmsis_dap));\n\tif (!dap) {\n\t\tLOG_ERROR(\"unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (cmsis_dap_backend >= 0) {\n\t\t/* Use forced backend */\n\t\tbackend = cmsis_dap_backends[cmsis_dap_backend];\n\t\tif (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) != ERROR_OK)\n\t\t\tbackend = NULL;\n\t} else {\n\t\t/* Try all backends */\n\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(cmsis_dap_backends); i++) {\n\t\t\tbackend = cmsis_dap_backends[i];\n\t\t\tif (backend->open(dap, cmsis_dap_vid, cmsis_dap_pid, adapter_get_required_serial()) == ERROR_OK)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\tbackend = NULL;\n\t\t}\n\t}\n\n\tif (!backend) {\n\t\tLOG_ERROR(\"unable to find a matching CMSIS-DAP device\");\n\t\tfree(dap);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdap->backend = backend;\n\n\tcmsis_dap_handle = dap;\n\n\treturn ERROR_OK;\n}\n\nstatic void cmsis_dap_close(struct cmsis_dap *dap)\n{\n\tif (dap->backend) {\n\t\tdap->backend->close(dap);\n\t\tdap->backend = NULL;\n\t}\n\n\tfree(dap->packet_buffer);\n\n\tfor (unsigned int i = 0; i < MAX_PENDING_REQUESTS; i++) {\n\t\tfree(dap->pending_fifo[i].transfers);\n\t\tdap->pending_fifo[i].transfers = NULL;\n\t}\n\n\tfree(cmsis_dap_handle);\n\tcmsis_dap_handle = NULL;\n}\n\nstatic void cmsis_dap_flush_read(struct cmsis_dap *dap)\n{\n\tunsigned int i;\n\t/* Some CMSIS-DAP adapters keep buffered packets over\n\t * USB close/open so we need to flush up to 64 old packets\n\t * to be sure all buffers are empty */\n\tfor (i = 0; i < 64; i++) {\n\t\tint retval = dap->backend->read(dap, 10);\n\t\tif (retval == ERROR_TIMEOUT_REACHED)\n\t\t\tbreak;\n\t}\n\tif (i)\n\t\tLOG_DEBUG(\"Flushed %u packets\", i);\n}\n\n/* Send a message and receive the reply */\nstatic int cmsis_dap_xfer(struct cmsis_dap *dap, int txlen)\n{\n\tif (dap->pending_fifo_block_count) {\n\t\tLOG_ERROR(\"pending %u blocks, flushing\", dap->pending_fifo_block_count);\n\t\twhile (dap->pending_fifo_block_count) {\n\t\t\tdap->backend->read(dap, 10);\n\t\t\tdap->pending_fifo_block_count--;\n\t\t}\n\t\tdap->pending_fifo_put_idx = 0;\n\t\tdap->pending_fifo_get_idx = 0;\n\t}\n\n\tuint8_t current_cmd = dap->command[0];\n\tint retval = dap->backend->write(dap, txlen, LIBUSB_TIMEOUT_MS);\n\tif (retval < 0)\n\t\treturn retval;\n\n\t/* get reply */\n\tretval = dap->backend->read(dap, LIBUSB_TIMEOUT_MS);\n\tif (retval < 0)\n\t\treturn retval;\n\n\tuint8_t *resp = dap->response;\n\tif (resp[0] == DAP_ERROR) {\n\t\tLOG_ERROR(\"CMSIS-DAP command 0x%\" PRIx8 \" not implemented\", current_cmd);\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tif (resp[0] != current_cmd) {\n\t\tLOG_ERROR(\"CMSIS-DAP command mismatch. Sent 0x%\" PRIx8\n\t\t\t \" received 0x%\" PRIx8, current_cmd, resp[0]);\n\n\t\tcmsis_dap_flush_read(dap);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_swj_pins(uint8_t pins, uint8_t mask, uint32_t delay, uint8_t *input)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWJ_PINS;\n\tcommand[1] = pins;\n\tcommand[2] = mask;\n\th_u32_to_le(&command[3], delay);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 7);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_DAP_SWJ_PINS failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (input)\n\t\t*input = cmsis_dap_handle->response[1];\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_swj_clock(uint32_t swj_clock)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\t/* set clock in Hz */\n\tswj_clock *= 1000;\n\n\tcommand[0] = CMD_DAP_SWJ_CLOCK;\n\th_u32_to_le(&command[1], swj_clock);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 5);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_DAP_SWJ_CLOCK failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* clock a sequence of bits out on TMS, to change JTAG states */\nstatic int cmsis_dap_cmd_dap_swj_sequence(uint8_t s_len, const uint8_t *sequence)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n#ifdef CMSIS_DAP_JTAG_DEBUG\n\tLOG_DEBUG(\"cmsis-dap TMS sequence: len=%d\", s_len);\n\tfor (unsigned int i = 0; i < DIV_ROUND_UP(s_len, 8); ++i)\n\t\tprintf(\"%02X \", sequence[i]);\n\n\tprintf(\"\\n\");\n#endif\n\n\tcommand[0] = CMD_DAP_SWJ_SEQ;\n\tcommand[1] = s_len;\n\tbit_copy(&command[2], 0, sequence, 0, s_len);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2 + DIV_ROUND_UP(s_len, 8));\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_info(uint8_t info, uint8_t **data)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_INFO;\n\tcommand[1] = info;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_INFO failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t*data = &cmsis_dap_handle->response[1];\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_led(uint8_t led, uint8_t state)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_LED;\n\tcommand[1] = led;\n\tcommand[2] = state;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 3);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_LED failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_connect(uint8_t mode)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_CONNECT;\n\tcommand[1] = mode;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_CONNECT failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (cmsis_dap_handle->response[1] != mode) {\n\t\tLOG_ERROR(\"CMSIS-DAP failed to connect in mode (%d)\", mode);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_disconnect(void)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_DISCONNECT;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 1);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_DISCONNECT failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_tfer_configure(uint8_t idle, uint16_t retry_count, uint16_t match_retry)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_TFER_CONFIGURE;\n\tcommand[1] = idle;\n\th_u16_to_le(&command[2], retry_count);\n\th_u16_to_le(&command[4], match_retry);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 6);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_TFER_Configure failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_cmd_dap_swd_configure(uint8_t cfg)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWD_CONFIGURE;\n\tcommand[1] = cfg;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_SWD_Configure failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n#if 0\nstatic int cmsis_dap_cmd_dap_delay(uint16_t delay_us)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_DELAY;\n\th_u16_to_le(&command[1], delay_us);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 3);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_Delay failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n#endif\n\nstatic int cmsis_dap_metacmd_targetsel(uint32_t instance_id)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\tconst uint32_t SEQ_RD = 0x80, SEQ_WR = 0x00;\n\n\t/* SWD multi-drop requires a transfer ala CMD_DAP_TFER,\n\tbut with no expectation of an SWD ACK response.  In\n\tCMSIS-DAP v1.20 and v2.00, CMD_DAP_SWD_SEQUENCE was\n\tadded to allow this special sequence to be generated.\n\tThe purpose of this operation is to select the target\n\tcorresponding to the instance_id that is written */\n\n\tLOG_DEBUG_IO(\"DP write reg TARGETSEL %\" PRIx32, instance_id);\n\n\tsize_t idx = 0;\n\tcommand[idx++] = CMD_DAP_SWD_SEQUENCE;\n\tcommand[idx++] = 3;\t/* sequence count */\n\n\t/* sequence 0: packet request for TARGETSEL */\n\tcommand[idx++] = SEQ_WR | 8;\n\tcommand[idx++] = SWD_CMD_START | swd_cmd(false, false, DP_TARGETSEL) | SWD_CMD_STOP | SWD_CMD_PARK;\n\n\t/* sequence 1: read Trn ACK Trn, no expectation for target to ACK  */\n\tcommand[idx++] = SEQ_RD | 5;\n\n\t/* sequence 2: WDATA plus parity */\n\tcommand[idx++] = SEQ_WR | (32 + 1);\n\th_u32_to_le(command + idx, instance_id);\n\tidx += 4;\n\tcommand[idx++] = parity_u32(instance_id);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, idx);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command SWD_Sequence failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sets the SWO transport mode.\n * @param[in] transport     The transport mode. Can be None, SWO_Data or\n *                          WinUSB (requires CMSIS-DAP v2).\n */\nstatic int cmsis_dap_cmd_dap_swo_transport(uint8_t transport)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_TRANSPORT;\n\tcommand[1] = transport;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Transport(%d) failed.\", transport);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sets the SWO trace capture mode.\n * @param[in] mode          Trace capture mode. Can be UART or MANCHESTER.\n */\nstatic int cmsis_dap_cmd_dap_swo_mode(uint8_t mode)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_MODE;\n\tcommand[1] = mode;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Mode(%d) failed.\", mode);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sets the baudrate for capturing SWO trace data.\n * Can be called iteratively to determine supported baudrates.\n * @param[in]  in_baudrate  Requested baudrate.\n * @param[out] dev_baudrate Actual baudrate or 0 (baudrate not configured).\n *                          When requested baudrate is not achievable the\n *                          closest configured baudrate can be returned or\n *                          0 which indicates that baudrate was not configured.\n */\nstatic int cmsis_dap_cmd_dap_swo_baudrate(\n\t\t\t\t\tuint32_t in_baudrate,\n\t\t\t\t\tuint32_t *dev_baudrate)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_BAUDRATE;\n\th_u32_to_le(&command[1], in_baudrate);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 5);\n\tuint32_t rvbr = le_to_h_u32(&cmsis_dap_handle->response[1]);\n\tif (retval != ERROR_OK || rvbr == 0) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Baudrate(%u) -> %u failed.\", in_baudrate, rvbr);\n\t\tif (dev_baudrate)\n\t\t\t*dev_baudrate = 0;\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (dev_baudrate)\n\t\t*dev_baudrate = rvbr;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Controls the SWO trace data capture.\n * @param[in] control       Start or stop a trace. Starting capture automatically\n *                          flushes any existing trace data in buffers which has\n *                          not yet been read.\n */\nstatic int cmsis_dap_cmd_dap_swo_control(uint8_t control)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_CONTROL;\n\tcommand[1] = control;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 2);\n\tif (retval != ERROR_OK || cmsis_dap_handle->response[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Control(%d) failed.\", control);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Reads the SWO trace status.\n * @param[out] trace_status The trace's status.\n *                          Bit0: Trace Capture (1 - active, 0 - inactive).\n *                          Bit6: Trace Stream Error.\n *                          Bit7: Trace Buffer Overrun.\n * @param[out] trace_count  Number of bytes in Trace Buffer (not yet read).\n */\nstatic int cmsis_dap_cmd_dap_swo_status(\n\t\t\t\t\tuint8_t *trace_status,\n\t\t\t\t\tsize_t *trace_count)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_STATUS;\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Status failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (trace_status)\n\t\t*trace_status = cmsis_dap_handle->response[1];\n\tif (trace_count)\n\t\t*trace_count = le_to_h_u32(&cmsis_dap_handle->response[2]);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Reads the captured SWO trace data from Trace Buffer.\n * @param[in]  max_trace_count Maximum number of Trace Data bytes to read.\n * @param[out] trace_status The trace's status.\n * @param[out] trace_count  Number of Trace Data bytes read.\n * @param[out] data         Trace Data bytes read.\n */\nstatic int cmsis_dap_cmd_dap_swo_data(\n\t\t\t\t\tsize_t max_trace_count,\n\t\t\t\t\tuint8_t *trace_status,\n\t\t\t\t\tsize_t *trace_count,\n\t\t\t\t\tuint8_t *data)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tcommand[0] = CMD_DAP_SWO_DATA;\n\th_u16_to_le(&command[1], max_trace_count);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, 3);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP: command CMD_SWO_Data failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t*trace_status = cmsis_dap_handle->response[1];\n\t*trace_count = le_to_h_u16(&cmsis_dap_handle->response[2]);\n\n\tif (*trace_count > 0)\n\t\tmemcpy(data, &cmsis_dap_handle->response[4], *trace_count);\n\n\treturn ERROR_OK;\n}\n\n\nstatic void cmsis_dap_swd_write_from_queue(struct cmsis_dap *dap)\n{\n\tuint8_t *command = dap->command;\n\tstruct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_put_idx];\n\n\tassert(dap->write_count + dap->read_count == block->transfer_count);\n\n\t/* Reset packet size check counters for the next packet */\n\tdap->write_count = 0;\n\tdap->read_count = 0;\n\n\tLOG_DEBUG_IO(\"Executing %d queued transactions from FIFO index %u%s\",\n\t\t\t\t block->transfer_count, dap->pending_fifo_put_idx,\n\t\t\t\t cmsis_dap_handle->swd_cmds_differ ? \"\" : \", same swd ops\");\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skipping due to previous errors: %d\", queued_retval);\n\t\tgoto skip;\n\t}\n\n\tif (block->transfer_count == 0)\n\t\tgoto skip;\n\n\tbool block_cmd = !cmsis_dap_handle->swd_cmds_differ\n\t\t\t\t\t && block->transfer_count >= CMD_DAP_TFER_BLOCK_MIN_OPS;\n\tblock->command = block_cmd ? CMD_DAP_TFER_BLOCK : CMD_DAP_TFER;\n\n\tcommand[0] = block->command;\n\tcommand[1] = 0x00;\t/* DAP Index */\n\n\tunsigned int idx;\n\tif (block_cmd) {\n\t\th_u16_to_le(&command[2], block->transfer_count);\n\t\tidx = 4;\t/* The first transfer will store the common DAP register */\n\t} else {\n\t\tcommand[2] = block->transfer_count;\n\t\tidx = 3;\n\t}\n\n\tfor (unsigned int i = 0; i < block->transfer_count; i++) {\n\t\tstruct pending_transfer_result *transfer = &(block->transfers[i]);\n\t\tuint8_t cmd = transfer->cmd;\n\t\tuint32_t data = transfer->data;\n\n\t\tLOG_DEBUG_IO(\"%s %s reg %x %\" PRIx32,\n\t\t\t\tcmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t\tcmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t  (cmd & SWD_CMD_A32) >> 1, data);\n\n\t\t/* When proper WAIT handling is implemented in the\n\t\t * common SWD framework, this kludge can be\n\t\t * removed. However, this might lead to minor\n\t\t * performance degradation as the adapter wouldn't be\n\t\t * able to automatically retry anything (because ARM\n\t\t * has forgotten to implement sticky error flags\n\t\t * clearing). See also comments regarding\n\t\t * cmsis_dap_cmd_dap_tfer_configure() and\n\t\t * cmsis_dap_cmd_dap_swd_configure() in\n\t\t * cmsis_dap_init().\n\t\t */\n\t\tif (!(cmd & SWD_CMD_RNW) &&\n\t\t    !(cmd & SWD_CMD_APNDP) &&\n\t\t    (cmd & SWD_CMD_A32) >> 1 == DP_CTRL_STAT &&\n\t\t    (data & CORUNDETECT)) {\n\t\t\tLOG_DEBUG(\"refusing to enable sticky overrun detection\");\n\t\t\tdata &= ~CORUNDETECT;\n\t\t}\n\n\t\tif (!block_cmd || i == 0)\n\t\t\tcommand[idx++] = (cmd >> 1) & 0x0f;\n\n\t\tif (!(cmd & SWD_CMD_RNW)) {\n\t\t\th_u32_to_le(&command[idx], data);\n\t\t\tidx += 4;\n\t\t}\n\t}\n\n\tint retval = dap->backend->write(dap, idx, LIBUSB_TIMEOUT_MS);\n\tif (retval < 0) {\n\t\tqueued_retval = retval;\n\t\tgoto skip;\n\t} else {\n\t\tqueued_retval = ERROR_OK;\n\t}\n\n\tdap->pending_fifo_put_idx = (dap->pending_fifo_put_idx + 1) % dap->packet_count;\n\tdap->pending_fifo_block_count++;\n\tif (dap->pending_fifo_block_count > dap->packet_count)\n\t\tLOG_ERROR(\"too much pending writes %u\", dap->pending_fifo_block_count);\n\n\treturn;\n\nskip:\n\tblock->transfer_count = 0;\n}\n\nstatic void cmsis_dap_swd_read_process(struct cmsis_dap *dap, int timeout_ms)\n{\n\tstruct pending_request_block *block = &dap->pending_fifo[dap->pending_fifo_get_idx];\n\n\tif (dap->pending_fifo_block_count == 0)\n\t\tLOG_ERROR(\"no pending write\");\n\n\t/* get reply */\n\tint retval = dap->backend->read(dap, timeout_ms);\n\tif (retval == ERROR_TIMEOUT_REACHED && timeout_ms < LIBUSB_TIMEOUT_MS)\n\t\treturn;\n\n\tif (retval <= 0) {\n\t\tLOG_DEBUG(\"error reading data\");\n\t\tqueued_retval = ERROR_FAIL;\n\t\tgoto skip;\n\t}\n\n\tuint8_t *resp = dap->response;\n\tif (resp[0] != block->command) {\n\t\tLOG_ERROR(\"CMSIS-DAP command mismatch. Expected 0x%x received 0x%\" PRIx8,\n\t\t\tblock->command, resp[0]);\n\t\tqueued_retval = ERROR_FAIL;\n\t\tgoto skip;\n\t}\n\n\tunsigned int transfer_count;\n\tunsigned int idx;\n\tif (block->command == CMD_DAP_TFER_BLOCK) {\n\t\ttransfer_count = le_to_h_u16(&resp[1]);\n\t\tidx = 3;\n\t} else {\n\t\ttransfer_count = resp[1];\n\t\tidx = 2;\n\t}\n\tif (resp[idx] & 0x08) {\n\t\tLOG_DEBUG(\"CMSIS-DAP Protocol Error @ %d (wrong parity)\", transfer_count);\n\t\tqueued_retval = ERROR_FAIL;\n\t\tgoto skip;\n\t}\n\tuint8_t ack = resp[idx++] & 0x07;\n\tif (ack != SWD_ACK_OK) {\n\t\tLOG_DEBUG(\"SWD ack not OK @ %d %s\", transfer_count,\n\t\t\t  ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\");\n\t\tqueued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;\n\t\t/* TODO: use results of transfers completed before the error occurred? */\n\t\tgoto skip;\n\t}\n\n\tif (block->transfer_count != transfer_count)\n\t\tLOG_ERROR(\"CMSIS-DAP transfer count mismatch: expected %d, got %d\",\n\t\t\t  block->transfer_count, transfer_count);\n\n\tLOG_DEBUG_IO(\"Received results of %d queued transactions FIFO index %u timeout %i\",\n\t\t transfer_count, dap->pending_fifo_get_idx, timeout_ms);\n\n\tfor (unsigned int i = 0; i < transfer_count; i++) {\n\t\tstruct pending_transfer_result *transfer = &(block->transfers[i]);\n\t\tif (transfer->cmd & SWD_CMD_RNW) {\n\t\t\tstatic uint32_t last_read;\n\t\t\tuint32_t data = le_to_h_u32(&resp[idx]);\n\t\t\tuint32_t tmp = data;\n\t\t\tidx += 4;\n\n\t\t\tLOG_DEBUG_IO(\"Read result: %\" PRIx32, data);\n\n\t\t\t/* Imitate posted AP reads */\n\t\t\tif ((transfer->cmd & SWD_CMD_APNDP) ||\n\t\t\t    ((transfer->cmd & SWD_CMD_A32) >> 1 == DP_RDBUFF)) {\n\t\t\t\ttmp = last_read;\n\t\t\t\tlast_read = data;\n\t\t\t}\n\n\t\t\tif (transfer->buffer)\n\t\t\t\t*(uint32_t *)(transfer->buffer) = tmp;\n\t\t}\n\t}\n\nskip:\n\tblock->transfer_count = 0;\n\tdap->pending_fifo_get_idx = (dap->pending_fifo_get_idx + 1) % dap->packet_count;\n\tdap->pending_fifo_block_count--;\n}\n\nstatic int cmsis_dap_swd_run_queue(void)\n{\n\tif (cmsis_dap_handle->pending_fifo_block_count)\n\t\tcmsis_dap_swd_read_process(cmsis_dap_handle, 0);\n\n\tcmsis_dap_swd_write_from_queue(cmsis_dap_handle);\n\n\twhile (cmsis_dap_handle->pending_fifo_block_count)\n\t\tcmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);\n\n\tcmsis_dap_handle->pending_fifo_put_idx = 0;\n\tcmsis_dap_handle->pending_fifo_get_idx = 0;\n\n\tint retval = queued_retval;\n\tqueued_retval = ERROR_OK;\n\n\treturn retval;\n}\n\nstatic unsigned int cmsis_dap_tfer_cmd_size(unsigned int write_count,\n\t\t\t\t\t\t\tunsigned int read_count, bool block_tfer)\n{\n\tunsigned int size;\n\tif (block_tfer) {\n\t\tsize = 5;\t\t\t\t\t\t/* DAP_TransferBlock header */\n\t\tsize += write_count * 4;\t\t/* data */\n\t} else {\n\t\tsize = 3;\t\t\t\t\t\t/* DAP_Transfer header */\n\t\tsize += write_count * (1 + 4);\t/* DAP register + data */\n\t\tsize += read_count;\t\t\t\t/* DAP register */\n\t}\n\treturn size;\n}\n\nstatic unsigned int cmsis_dap_tfer_resp_size(unsigned int write_count,\n\t\t\t\t\t\t\tunsigned int read_count, bool block_tfer)\n{\n\tunsigned int size;\n\tif (block_tfer)\n\t\tsize = 4;\t\t\t\t\t\t/* DAP_TransferBlock response header */\n\telse\n\t\tsize = 3;\t\t\t\t\t\t/* DAP_Transfer response header */\n\n\tsize += read_count * 4;\t\t\t\t/* data */\n\treturn size;\n}\n\nstatic void cmsis_dap_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)\n{\n\t/* Compute sizes of the DAP Transfer command and the expected response\n\t * for all queued and this operation */\n\tbool targetsel_cmd = swd_cmd(false, false, DP_TARGETSEL) == cmd;\n\n\tunsigned int write_count = cmsis_dap_handle->write_count;\n\tunsigned int read_count = cmsis_dap_handle->read_count;\n\tbool block_cmd;\n\tif (write_count + read_count < CMD_DAP_TFER_BLOCK_MIN_OPS)\n\t\tblock_cmd = false;\n\telse\n\t\tblock_cmd = !cmsis_dap_handle->swd_cmds_differ\n\t\t\t\t\t&& cmd == cmsis_dap_handle->common_swd_cmd;\n\n\tif (cmd & SWD_CMD_RNW)\n\t\tread_count++;\n\telse\n\t\twrite_count++;\n\n\tunsigned int cmd_size = cmsis_dap_tfer_cmd_size(write_count, read_count,\n\t\t\t\t\t\t\t\t\t\t\t\t\tblock_cmd);\n\tunsigned int resp_size = cmsis_dap_tfer_resp_size(write_count, read_count,\n\t\t\t\t\t\t\t\t\t\t\t\t\tblock_cmd);\n\tunsigned int max_transfer_count = block_cmd ? 65535 : 255;\n\n\t/* Does the DAP Transfer command and the expected response fit into one packet?\n\t * Run the queue also before a targetsel - it cannot be queued */\n\tif (cmd_size > tfer_max_command_size\n\t\t\t|| resp_size > tfer_max_response_size\n\t\t\t|| targetsel_cmd\n\t\t\t|| write_count + read_count > max_transfer_count) {\n\t\tif (cmsis_dap_handle->pending_fifo_block_count)\n\t\t\tcmsis_dap_swd_read_process(cmsis_dap_handle, 0);\n\n\t\t/* Not enough room in the queue. Run the queue. */\n\t\tcmsis_dap_swd_write_from_queue(cmsis_dap_handle);\n\n\t\tif (cmsis_dap_handle->pending_fifo_block_count >= cmsis_dap_handle->packet_count)\n\t\t\tcmsis_dap_swd_read_process(cmsis_dap_handle, LIBUSB_TIMEOUT_MS);\n\t}\n\n\tassert(cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx].transfer_count < pending_queue_len);\n\n\tif (queued_retval != ERROR_OK)\n\t\treturn;\n\n\tif (targetsel_cmd) {\n\t\tcmsis_dap_metacmd_targetsel(data);\n\t\treturn;\n\t}\n\n\tstruct pending_request_block *block = &cmsis_dap_handle->pending_fifo[cmsis_dap_handle->pending_fifo_put_idx];\n\tstruct pending_transfer_result *transfer = &(block->transfers[block->transfer_count]);\n\ttransfer->data = data;\n\ttransfer->cmd = cmd;\n\tif (block->transfer_count == 0) {\n\t\tcmsis_dap_handle->swd_cmds_differ = false;\n\t\tcmsis_dap_handle->common_swd_cmd = cmd;\n\t} else if (cmd != cmsis_dap_handle->common_swd_cmd) {\n\t\tcmsis_dap_handle->swd_cmds_differ = true;\n\t}\n\n\tif (cmd & SWD_CMD_RNW) {\n\t\t/* Queue a read transaction */\n\t\ttransfer->buffer = dst;\n\t\tcmsis_dap_handle->read_count++;\n\t} else {\n\t\tcmsis_dap_handle->write_count++;\n\t}\n\tblock->transfer_count++;\n}\n\nstatic void cmsis_dap_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\tcmsis_dap_swd_queue_cmd(cmd, NULL, value);\n}\n\nstatic void cmsis_dap_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\tcmsis_dap_swd_queue_cmd(cmd, value, 0);\n}\n\nstatic int cmsis_dap_get_serial_info(void)\n{\n\tuint8_t *data;\n\n\tint retval = cmsis_dap_cmd_dap_info(INFO_ID_SERNUM, &data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data[0]) /* strlen */\n\t\tLOG_INFO(\"CMSIS-DAP: Serial# = %s\", &data[1]);\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_get_version_info(void)\n{\n\tuint8_t *data;\n\n\t/* INFO_ID_FW_VER - string */\n\tint retval = cmsis_dap_cmd_dap_info(INFO_ID_FW_VER, &data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data[0]) /* strlen */\n\t\tLOG_INFO(\"CMSIS-DAP: FW Version = %s\", &data[1]);\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_get_caps_info(void)\n{\n\tuint8_t *data;\n\n\t/* INFO_ID_CAPS - byte */\n\tint retval = cmsis_dap_cmd_dap_info(INFO_ID_CAPS, &data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data[0] == 1 || data[0] == 2) {\n\t\tuint16_t caps = data[1];\n\t\tif (data[0] == 2)\n\t\t\tcaps |= (uint16_t)data[2] << 8;\n\n\t\tcmsis_dap_handle->caps = caps;\n\n\t\tfor (unsigned int i = 0; i < INFO_CAPS__NUM_CAPS; ++i) {\n\t\t\tif (caps & BIT(i))\n\t\t\t\tLOG_INFO(\"CMSIS-DAP: %s\", info_caps_str[i]);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_get_swo_buf_sz(uint32_t *swo_buf_sz)\n{\n\tuint8_t *data;\n\n\t/* INFO_ID_SWO_BUF_SZ - word */\n\tint retval = cmsis_dap_cmd_dap_info(INFO_ID_SWO_BUF_SZ, &data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (data[0] != 4)\n\t\treturn ERROR_FAIL;\n\n\t*swo_buf_sz = le_to_h_u32(&data[1]);\n\n\tLOG_INFO(\"CMSIS-DAP: SWO Trace Buffer Size = %u bytes\", *swo_buf_sz);\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_get_status(void)\n{\n\tuint8_t d;\n\n\tint retval = cmsis_dap_cmd_dap_swj_pins(0, 0, 0, &d);\n\n\tif (retval == ERROR_OK) {\n\t\tLOG_INFO(\"SWCLK/TCK = %d SWDIO/TMS = %d TDI = %d TDO = %d nTRST = %d nRESET = %d\",\n\t\t\t(d & SWJ_PIN_TCK) ? 1 : 0,\n\t\t\t(d & SWJ_PIN_TMS) ? 1 : 0,\n\t\t\t(d & SWJ_PIN_TDI) ? 1 : 0,\n\t\t\t(d & SWJ_PIN_TDO) ? 1 : 0,\n\t\t\t(d & SWJ_PIN_TRST) ? 1 : 0,\n\t\t\t(d & SWJ_PIN_SRST) ? 1 : 0);\n\t}\n\n\treturn retval;\n}\n\nstatic int cmsis_dap_swd_switch_seq(enum swd_special_seq seq)\n{\n\tconst uint8_t *s;\n\tunsigned int s_len;\n\tint retval;\n\n\tif (seq != LINE_RESET &&\n\t\t\t(output_pins & (SWJ_PIN_SRST | SWJ_PIN_TRST))\n\t\t\t\t== (SWJ_PIN_SRST | SWJ_PIN_TRST)) {\n\t\t/* Following workaround deasserts reset on most adapters.\n\t\t * Do not reconnect if a reset line is active!\n\t\t * Reconnecting would break connecting under reset. */\n\n\t\t/* First disconnect before connecting, Atmel EDBG needs it for SAMD/R/L/C */\n\t\tcmsis_dap_cmd_dap_disconnect();\n\n\t\t/* When we are reconnecting, DAP_Connect needs to be rerun, at\n\t\t * least on Keil ULINK-ME */\n\t\tretval = cmsis_dap_cmd_dap_connect(CONNECT_SWD);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG_IO(\"SWD line reset\");\n\t\ts = swd_seq_line_reset;\n\t\ts_len = swd_seq_line_reset_len;\n\t\tbreak;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\ts = swd_seq_jtag_to_swd;\n\t\ts_len = swd_seq_jtag_to_swd_len;\n\t\tbreak;\n\tcase JTAG_TO_DORMANT:\n\t\tLOG_DEBUG(\"JTAG-to-DORMANT\");\n\t\ts = swd_seq_jtag_to_dormant;\n\t\ts_len = swd_seq_jtag_to_dormant_len;\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\ts = swd_seq_swd_to_jtag;\n\t\ts_len = swd_seq_swd_to_jtag_len;\n\t\tbreak;\n\tcase SWD_TO_DORMANT:\n\t\tLOG_DEBUG(\"SWD-to-DORMANT\");\n\t\ts = swd_seq_swd_to_dormant;\n\t\ts_len = swd_seq_swd_to_dormant_len;\n\t\tbreak;\n\tcase DORMANT_TO_SWD:\n\t\tLOG_DEBUG(\"DORMANT-to-SWD\");\n\t\ts = swd_seq_dormant_to_swd;\n\t\ts_len = swd_seq_dormant_to_swd_len;\n\t\tbreak;\n\tcase DORMANT_TO_JTAG:\n\t\tLOG_DEBUG(\"DORMANT-to-JTAG\");\n\t\ts = swd_seq_dormant_to_jtag;\n\t\ts_len = swd_seq_dormant_to_jtag_len;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = cmsis_dap_cmd_dap_swj_sequence(s_len, s);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Atmel EDBG needs renew clock setting after SWJ_Sequence\n\t * otherwise default frequency is used */\n\treturn cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz());\n}\n\nstatic int cmsis_dap_swd_open(void)\n{\n\tif (!(cmsis_dap_handle->caps & INFO_CAPS_SWD)) {\n\t\tLOG_ERROR(\"CMSIS-DAP: SWD not supported\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tint retval = cmsis_dap_cmd_dap_connect(CONNECT_SWD);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Add more setup here.??... */\n\n\tLOG_INFO(\"CMSIS-DAP: Interface Initialised (SWD)\");\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_init(void)\n{\n\tuint8_t *data;\n\n\tint retval = cmsis_dap_open();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcmsis_dap_flush_read(cmsis_dap_handle);\n\n\tretval = cmsis_dap_get_caps_info();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cmsis_dap_get_version_info();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cmsis_dap_get_serial_info();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (swd_mode) {\n\t\tretval = cmsis_dap_swd_open();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\t/* Connect in JTAG mode */\n\t\tif (!(cmsis_dap_handle->caps & INFO_CAPS_JTAG)) {\n\t\t\tLOG_ERROR(\"CMSIS-DAP: JTAG not supported\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tretval = cmsis_dap_cmd_dap_connect(CONNECT_JTAG);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_INFO(\"CMSIS-DAP: Interface Initialised (JTAG)\");\n\t}\n\n\t/* Be conservative and suppress submitting multiple HID requests\n\t * until we get packet count info from the adaptor */\n\tcmsis_dap_handle->packet_count = 1;\n\n\t/* INFO_ID_PKT_SZ - short */\n\tretval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_SZ, &data);\n\tif (retval != ERROR_OK)\n\t\tgoto init_err;\n\n\tif (data[0] == 2) {  /* short */\n\t\tuint16_t pkt_sz = data[1] + (data[2] << 8);\n\t\tif (pkt_sz != cmsis_dap_handle->packet_size) {\n\t\t\tfree(cmsis_dap_handle->packet_buffer);\n\t\t\tretval = cmsis_dap_handle->backend->packet_buffer_alloc(cmsis_dap_handle, pkt_sz);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto init_err;\n\n\t\t\tLOG_DEBUG(\"CMSIS-DAP: Packet Size = %\" PRIu16, pkt_sz);\n\t\t}\n\t}\n\n\t/* Maximal number of transfers which fit to one packet:\n\t * Limited by response size: 3 bytes of response header + 4 per read\n\t * Plus writes to full command size: 3 bytes cmd header + 1 per read + 5 per write */\n\ttfer_max_command_size = cmsis_dap_handle->packet_usable_size;\n\ttfer_max_response_size = cmsis_dap_handle->packet_usable_size;\n\tunsigned int max_reads = tfer_max_response_size / 4;\n\tpending_queue_len = max_reads + (tfer_max_command_size - max_reads) / 5;\n\tcmsis_dap_handle->write_count = 0;\n\tcmsis_dap_handle->read_count = 0;\n\n\t/* INFO_ID_PKT_CNT - byte */\n\tretval = cmsis_dap_cmd_dap_info(INFO_ID_PKT_CNT, &data);\n\tif (retval != ERROR_OK)\n\t\tgoto init_err;\n\n\tif (data[0] == 1) { /* byte */\n\t\tunsigned int pkt_cnt = data[1];\n\t\tif (pkt_cnt > 1)\n\t\t\tcmsis_dap_handle->packet_count = MIN(MAX_PENDING_REQUESTS, pkt_cnt);\n\n\t\tLOG_DEBUG(\"CMSIS-DAP: Packet Count = %u\", pkt_cnt);\n\t}\n\n\tLOG_DEBUG(\"Allocating FIFO for %u pending packets\", cmsis_dap_handle->packet_count);\n\tfor (unsigned int i = 0; i < cmsis_dap_handle->packet_count; i++) {\n\t\tcmsis_dap_handle->pending_fifo[i].transfers = malloc(pending_queue_len\n\t\t\t\t\t\t\t\t\t * sizeof(struct pending_transfer_result));\n\t\tif (!cmsis_dap_handle->pending_fifo[i].transfers) {\n\t\t\tLOG_ERROR(\"Unable to allocate memory for CMSIS-DAP queue\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto init_err;\n\t\t}\n\t}\n\n\t/* Intentionally not checked for error, just logs an info message\n\t * not vital for further debugging */\n\t(void)cmsis_dap_get_status();\n\n\t/* Now try to connect to the target\n\t * TODO: This is all SWD only @ present */\n\tretval = cmsis_dap_cmd_dap_swj_clock(adapter_get_speed_khz());\n\tif (retval != ERROR_OK)\n\t\tgoto init_err;\n\n\t/* Ask CMSIS-DAP to automatically retry on receiving WAIT for\n\t * up to 64 times. This must be changed to 0 if sticky\n\t * overrun detection is enabled. */\n\tretval = cmsis_dap_cmd_dap_tfer_configure(0, 64, 0);\n\tif (retval != ERROR_OK)\n\t\tgoto init_err;\n\n\tif (swd_mode) {\n\t\t/* Data Phase (bit 2) must be set to 1 if sticky overrun\n\t\t * detection is enabled */\n\t\tretval = cmsis_dap_cmd_dap_swd_configure(0);\t/* 1 TRN, no Data Phase */\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto init_err;\n\t}\n\t/* Both LEDs on */\n\t/* Intentionally not checked for error, debugging will work\n\t * without LEDs */\n\t(void)cmsis_dap_cmd_dap_led(LED_ID_CONNECT, LED_ON);\n\t(void)cmsis_dap_cmd_dap_led(LED_ID_RUN, LED_ON);\n\n\t/* support connecting with srst asserted */\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING) {\n\t\t\tretval = cmsis_dap_cmd_dap_swj_pins(0, SWJ_PIN_SRST, 0, NULL);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto init_err;\n\t\t\tLOG_INFO(\"Connecting under reset\");\n\t\t}\n\t}\n\tLOG_INFO(\"CMSIS-DAP: Interface ready\");\n\treturn ERROR_OK;\n\ninit_err:\n\tcmsis_dap_quit();\n\treturn retval;\n}\n\nstatic int cmsis_dap_swd_init(void)\n{\n\tswd_mode = true;\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_quit(void)\n{\n\tcmsis_dap_cmd_dap_disconnect();\n\n\t/* Both LEDs off */\n\tcmsis_dap_cmd_dap_led(LED_ID_RUN, LED_OFF);\n\tcmsis_dap_cmd_dap_led(LED_ID_CONNECT, LED_OFF);\n\n\tcmsis_dap_close(cmsis_dap_handle);\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_reset(int trst, int srst)\n{\n\t/* Set both TRST and SRST even if they're not enabled as\n\t * there's no way to tristate them */\n\n\toutput_pins = 0;\n\tif (!srst)\n\t\toutput_pins |= SWJ_PIN_SRST;\n\tif (!trst)\n\t\toutput_pins |= SWJ_PIN_TRST;\n\n\tint retval = cmsis_dap_cmd_dap_swj_pins(output_pins,\n\t\t\tSWJ_PIN_TRST | SWJ_PIN_SRST, 0, NULL);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"CMSIS-DAP: Interface reset failed\");\n\treturn retval;\n}\n\nstatic void cmsis_dap_execute_sleep(struct jtag_command *cmd)\n{\n#if 0\n\tint retval = cmsis_dap_cmd_dap_delay(cmd->cmd.sleep->us);\n\tif (retval != ERROR_OK)\n#endif\n\t\tjtag_sleep(cmd->cmd.sleep->us);\n}\n\n/* Set TMS high for five TCK clocks, to move the TAP to the Test-Logic-Reset state */\nstatic int cmsis_dap_execute_tlr_reset(struct jtag_command *cmd)\n{\n\tLOG_INFO(\"cmsis-dap JTAG TLR_RESET\");\n\tuint8_t seq = 0xff;\n\n\tint retval = cmsis_dap_cmd_dap_swj_sequence(8, &seq);\n\tif (retval == ERROR_OK)\n\t\ttap_set_state(TAP_RESET);\n\treturn retval;\n}\n\n/* Set new end state */\nstatic void cmsis_dap_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\n#ifdef SPRINT_BINARY\nstatic void sprint_binary(char *s, const uint8_t *buf, unsigned int offset, unsigned int len)\n{\n\tif (!len)\n\t\treturn;\n\n\t/*\n\tbuf = { 0x18 } len=5 should result in: 11000\n\tbuf = { 0xff 0x18 } len=13 should result in: 11111111 11000\n\tbuf = { 0xc0 0x18 } offset=3 len=10 should result in: 11000 11000\n\t\ti=3 there means i/8 = 0 so c = 0xFF, and\n\t*/\n\tfor (unsigned int i = offset; i < offset + len; ++i) {\n\t\tuint8_t c = buf[i / 8], mask = 1 << (i % 8);\n\t\tif ((i != offset) && !(i % 8))\n\t\t\tputchar(' ');\n\t\t*s++ = (c & mask) ? '1' : '0';\n\t}\n\t*s = 0;\n}\n#endif\n\n#ifdef CMSIS_DAP_JTAG_DEBUG\nstatic void debug_parse_cmsis_buf(const uint8_t *cmd, int cmdlen)\n{\n\t/* cmd is a usb packet to go to the cmsis-dap interface */\n\tprintf(\"cmsis-dap buffer (%d b): \", cmdlen);\n\tfor (int i = 0; i < cmdlen; ++i)\n\t\tprintf(\" %02x\", cmd[i]);\n\tprintf(\"\\n\");\n\tswitch (cmd[0]) {\n\t\tcase CMD_DAP_JTAG_SEQ: {\n\t\t\tprintf(\"cmsis-dap jtag sequence command %02x (n=%d)\\n\", cmd[0], cmd[1]);\n\t\t\t/*\n\t\t\t * #1 = number of sequences\n\t\t\t * #2 = sequence info 1\n\t\t\t * #3...4+n_bytes-1 = sequence 1\n\t\t\t * #4+n_bytes = sequence info 2\n\t\t\t * #5+n_bytes = sequence 2 (single bit)\n\t\t\t */\n\t\t\tint pos = 2;\n\t\t\tfor (int seq = 0; seq < cmd[1]; ++seq) {\n\t\t\t\tuint8_t info = cmd[pos++];\n\t\t\t\tint len = info & DAP_JTAG_SEQ_TCK;\n\t\t\t\tif (len == 0)\n\t\t\t\t\tlen = 64;\n\t\t\t\tprintf(\"  sequence %d starting %d: info %02x (len=%d tms=%d read_tdo=%d): \",\n\t\t\t\t\tseq, pos, info, len, info & DAP_JTAG_SEQ_TMS, info & DAP_JTAG_SEQ_TDO);\n\t\t\t\tfor (int i = 0; i < DIV_ROUND_UP(len, 8); ++i)\n\t\t\t\t\tprintf(\" %02x\", cmd[pos+i]);\n\t\t\t\tpos += DIV_ROUND_UP(len, 8);\n\t\t\t\tprintf(\"\\n\");\n\t\t\t}\n\t\t\tif (pos != cmdlen) {\n\t\t\t\tprintf(\"BUFFER LENGTH MISMATCH looks like %d but %d specified\", pos, cmdlen);\n\t\t\t\texit(-1);\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tLOG_DEBUG(\"unknown cmsis-dap command %02x\", cmd[1]);\n\t\t\tbreak;\n\t}\n}\n#endif\n\nstatic void cmsis_dap_flush(void)\n{\n\tif (!queued_seq_count)\n\t\treturn;\n\n\tLOG_DEBUG_IO(\"Flushing %d queued sequences (%d bytes) with %d pending scan results to capture\",\n\t\tqueued_seq_count, queued_seq_buf_end, pending_scan_result_count);\n\n\t/* prepare CMSIS-DAP packet */\n\tuint8_t *command = cmsis_dap_handle->command;\n\tcommand[0] = CMD_DAP_JTAG_SEQ;\n\tcommand[1] = queued_seq_count;\n\tmemcpy(&command[2], queued_seq_buf, queued_seq_buf_end);\n\n#ifdef CMSIS_DAP_JTAG_DEBUG\n\tdebug_parse_cmsis_buf(command, queued_seq_buf_end + 2);\n#endif\n\n\t/* send command to USB device */\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, queued_seq_buf_end + 2);\n\n\tuint8_t *resp = cmsis_dap_handle->response;\n\tif (retval != ERROR_OK || resp[1] != DAP_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command CMD_DAP_JTAG_SEQ failed.\");\n\t\texit(-1);\n\t}\n\n#ifdef CMSIS_DAP_JTAG_DEBUG\n\tLOG_DEBUG_IO(\"USB response buf:\");\n\tfor (int c = 0; c < queued_seq_buf_end + 3; ++c)\n\t\tprintf(\"%02X \", resp[c]);\n\tprintf(\"\\n\");\n#endif\n\n\t/* copy scan results into client buffers */\n\tfor (int i = 0; i < pending_scan_result_count; ++i) {\n\t\tstruct pending_scan_result *scan = &pending_scan_results[i];\n\t\tLOG_DEBUG_IO(\"Copying pending_scan_result %d/%d: %d bits from byte %d -> buffer + %d bits\",\n\t\t\ti, pending_scan_result_count, scan->length, scan->first + 2, scan->buffer_offset);\n#ifdef CMSIS_DAP_JTAG_DEBUG\n\t\tfor (uint32_t b = 0; b < DIV_ROUND_UP(scan->length, 8); ++b)\n\t\t\tprintf(\"%02X \", resp[2+scan->first+b]);\n\t\tprintf(\"\\n\");\n#endif\n\t\tbit_copy(scan->buffer, scan->buffer_offset, &resp[2 + scan->first], 0, scan->length);\n\t}\n\n\t/* reset */\n\tqueued_seq_count = 0;\n\tqueued_seq_buf_end = 0;\n\tqueued_seq_tdo_ptr = 0;\n\tpending_scan_result_count = 0;\n}\n\n/* queue a sequence of bits to clock out TDI / in TDO, executing if the buffer is full.\n *\n * sequence=NULL means clock out zeros on TDI\n * tdo_buffer=NULL means don't capture TDO\n */\nstatic void cmsis_dap_add_jtag_sequence(unsigned int s_len, const uint8_t *sequence,\n\t\t\t\t\tunsigned int s_offset, bool tms,\n\t\t\t\t\tuint8_t *tdo_buffer, unsigned int tdo_buffer_offset)\n{\n\tLOG_DEBUG_IO(\"[at %d] %u bits, tms %s, seq offset %u, tdo buf %p, tdo offset %u\",\n\t\tqueued_seq_buf_end,\n\t\ts_len, tms ? \"HIGH\" : \"LOW\", s_offset, tdo_buffer, tdo_buffer_offset);\n\n\tif (s_len == 0)\n\t\treturn;\n\n\tif (s_len > 64) {\n\t\tLOG_DEBUG_IO(\"START JTAG SEQ SPLIT\");\n\t\tfor (unsigned int offset = 0; offset < s_len; offset += 64) {\n\t\t\tunsigned int len = s_len - offset;\n\t\t\tif (len > 64)\n\t\t\t\tlen = 64;\n\t\t\tLOG_DEBUG_IO(\"Splitting long jtag sequence: %u-bit chunk starting at offset %u\", len, offset);\n\t\t\tcmsis_dap_add_jtag_sequence(\n\t\t\t\tlen,\n\t\t\t\tsequence,\n\t\t\t\ts_offset + offset,\n\t\t\t\ttms,\n\t\t\t\ttdo_buffer,\n\t\t\t\t!tdo_buffer ? 0 : (tdo_buffer_offset + offset)\n\t\t\t\t);\n\t\t}\n\t\tLOG_DEBUG_IO(\"END JTAG SEQ SPLIT\");\n\t\treturn;\n\t}\n\n\tunsigned int cmd_len = 1 + DIV_ROUND_UP(s_len, 8);\n\tif (queued_seq_count >= 255 || queued_seq_buf_end + cmd_len > QUEUED_SEQ_BUF_LEN)\n\t\t/* empty out the buffer */\n\t\tcmsis_dap_flush();\n\n\t++queued_seq_count;\n\n\t/* control byte */\n\tqueued_seq_buf[queued_seq_buf_end] =\n\t\t(tms ? DAP_JTAG_SEQ_TMS : 0) |\n\t\t(tdo_buffer ? DAP_JTAG_SEQ_TDO : 0) |\n\t\t(s_len == 64 ? 0 : s_len);\n\n\tif (sequence)\n\t\tbit_copy(&queued_seq_buf[queued_seq_buf_end + 1], 0, sequence, s_offset, s_len);\n\telse\n\t\tmemset(&queued_seq_buf[queued_seq_buf_end + 1], 0, DIV_ROUND_UP(s_len, 8));\n\n\tqueued_seq_buf_end += cmd_len;\n\n\tif (tdo_buffer) {\n\t\tstruct pending_scan_result *scan = &pending_scan_results[pending_scan_result_count++];\n\t\tscan->first = queued_seq_tdo_ptr;\n\t\tqueued_seq_tdo_ptr += DIV_ROUND_UP(s_len, 8);\n\t\tscan->length = s_len;\n\t\tscan->buffer = tdo_buffer;\n\t\tscan->buffer_offset = tdo_buffer_offset;\n\t}\n}\n\n/* queue a sequence of bits to clock out TMS, executing if the buffer is full */\nstatic void cmsis_dap_add_tms_sequence(const uint8_t *sequence, int s_len)\n{\n\tLOG_DEBUG_IO(\"%d bits: %02X\", s_len, *sequence);\n\t/* we use a series of CMD_DAP_JTAG_SEQ commands to toggle TMS,\n\t   because even though it seems ridiculously inefficient, it\n\t   allows us to combine TMS and scan sequences into the same\n\t   USB packet. */\n\t/* TODO: combine runs of the same tms value */\n\tfor (int i = 0; i < s_len; ++i) {\n\t\tbool bit = (sequence[i / 8] & (1 << (i % 8))) != 0;\n\t\tcmsis_dap_add_jtag_sequence(1, NULL, 0, bit, NULL, 0);\n\t}\n}\n\n/* Move to the end state by queuing a sequence to clock into TMS */\nstatic void cmsis_dap_state_move(void)\n{\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tuint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tLOG_DEBUG_IO(\"state move from %s to %s: %d clocks, %02X on tms\",\n\t\ttap_state_name(tap_get_state()), tap_state_name(tap_get_end_state()),\n\t\ttms_scan_bits, tms_scan);\n\tcmsis_dap_add_tms_sequence(&tms_scan, tms_scan_bits);\n\n\ttap_set_state(tap_get_end_state());\n}\n\n\n/* Execute a JTAG scan operation by queueing TMS and TDI/TDO sequences */\nstatic void cmsis_dap_execute_scan(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"%s type:%d\", cmd->cmd.scan->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\tjtag_scan_type(cmd->cmd.scan));\n\n\t/* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */\n\twhile (cmd->cmd.scan->num_fields > 0\n\t\t\t&& cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {\n\t\tcmd->cmd.scan->num_fields--;\n\t\tLOG_DEBUG(\"discarding trailing empty field\");\n\t}\n\n\tif (cmd->cmd.scan->num_fields == 0) {\n\t\tLOG_DEBUG(\"empty scan, doing nothing\");\n\t\treturn;\n\t}\n\n\tif (cmd->cmd.scan->ir_scan) {\n\t\tif (tap_get_state() != TAP_IRSHIFT) {\n\t\t\tcmsis_dap_end_state(TAP_IRSHIFT);\n\t\t\tcmsis_dap_state_move();\n\t\t}\n\t} else {\n\t\tif (tap_get_state() != TAP_DRSHIFT) {\n\t\t\tcmsis_dap_end_state(TAP_DRSHIFT);\n\t\t\tcmsis_dap_state_move();\n\t\t}\n\t}\n\n\tcmsis_dap_end_state(cmd->cmd.scan->end_state);\n\n\tstruct scan_field *field = cmd->cmd.scan->fields;\n\tunsigned scan_size = 0;\n\n\tfor (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {\n\t\tscan_size += field->num_bits;\n\t\tLOG_DEBUG_IO(\"%s%s field %d/%d %d bits\",\n\t\t\tfield->in_value ? \"in\" : \"\",\n\t\t\tfield->out_value ? \"out\" : \"\",\n\t\t\ti,\n\t\t\tcmd->cmd.scan->num_fields,\n\t\t\tfield->num_bits);\n\n\t\tif (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {\n\t\t\tLOG_DEBUG_IO(\"Last field and have to move out of SHIFT state\");\n\t\t\t/* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap\n\t\t\t * movement. This last field can't have length zero, it was checked above. */\n\t\t\tcmsis_dap_add_jtag_sequence(\n\t\t\t\tfield->num_bits - 1, /* number of bits to clock */\n\t\t\t\tfield->out_value, /* output sequence */\n\t\t\t\t0, /* output offset */\n\t\t\t\tfalse, /* TMS low */\n\t\t\t\tfield->in_value,\n\t\t\t\t0);\n\n\t\t\t/* Clock the last bit out, with TMS high */\n\t\t\tuint8_t last_bit = 0;\n\t\t\tif (field->out_value)\n\t\t\t\tbit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);\n\t\t\tcmsis_dap_add_jtag_sequence(\n\t\t\t\t1,\n\t\t\t\t&last_bit,\n\t\t\t\t0,\n\t\t\t\ttrue,\n\t\t\t\tfield->in_value,\n\t\t\t\tfield->num_bits - 1);\n\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 1));\n\n\t\t\t/* Now clock one more cycle, with TMS low, to get us into a PAUSE state */\n\t\t\tcmsis_dap_add_jtag_sequence(\n\t\t\t\t1,\n\t\t\t\t&last_bit,\n\t\t\t\t0,\n\t\t\t\tfalse,\n\t\t\t\tNULL,\n\t\t\t\t0);\n\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 0));\n\t\t} else {\n\t\t\tLOG_DEBUG_IO(\"Internal field, staying in SHIFT state afterwards\");\n\t\t\t/* Clocking part of a sequence into DR or IR with TMS=0,\n\t\t\t   leaving TMS=0 at the end so we can continue later */\n\t\t\tcmsis_dap_add_jtag_sequence(\n\t\t\t\tfield->num_bits,\n\t\t\t\tfield->out_value,\n\t\t\t\t0,\n\t\t\t\tfalse,\n\t\t\t\tfield->in_value,\n\t\t\t\t0);\n\t\t}\n\t}\n\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\tcmsis_dap_end_state(tap_get_end_state());\n\t\tcmsis_dap_state_move();\n\t}\n\n\tLOG_DEBUG_IO(\"%s scan, %i bits, end in %s\",\n\t\t(cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\", scan_size,\n\t\ttap_state_name(tap_get_end_state()));\n}\n\nstatic void cmsis_dap_pathmove(int num_states, tap_state_t *path)\n{\n\tuint8_t tms0 = 0x00;\n\tuint8_t tms1 = 0xff;\n\n\tfor (int i = 0; i < num_states; i++) {\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false))\n\t\t\tcmsis_dap_add_tms_sequence(&tms0, 1);\n\t\telse if (path[i] == tap_state_transition(tap_get_state(), true))\n\t\t\tcmsis_dap_add_tms_sequence(&tms1, 1);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition.\",\n\t\t\t\t  tap_state_name(tap_get_state()), tap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\tcmsis_dap_end_state(tap_get_state());\n}\n\nstatic void cmsis_dap_execute_pathmove(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\t      cmd->cmd.pathmove->num_states,\n\t       cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\n\tcmsis_dap_pathmove(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);\n}\n\nstatic void cmsis_dap_stableclocks(int num_cycles)\n{\n\tuint8_t tms = tap_get_state() == TAP_RESET;\n\t/* TODO: Perform optimizations? */\n\t/* Execute num_cycles. */\n\tfor (int i = 0; i < num_cycles; i++)\n\t\tcmsis_dap_add_tms_sequence(&tms, 1);\n}\n\nstatic void cmsis_dap_runtest(int num_cycles)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* Only do a state_move when we're not already in IDLE. */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tcmsis_dap_end_state(TAP_IDLE);\n\t\tcmsis_dap_state_move();\n\t}\n\tcmsis_dap_stableclocks(num_cycles);\n\n\t/* Finish in end_state. */\n\tcmsis_dap_end_state(saved_end_state);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tcmsis_dap_state_move();\n}\n\nstatic void cmsis_dap_execute_runtest(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\", cmd->cmd.runtest->num_cycles,\n\t\t      cmd->cmd.runtest->end_state);\n\n\tcmsis_dap_end_state(cmd->cmd.runtest->end_state);\n\tcmsis_dap_runtest(cmd->cmd.runtest->num_cycles);\n}\n\nstatic void cmsis_dap_execute_stableclocks(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"stableclocks %i cycles\", cmd->cmd.runtest->num_cycles);\n\tcmsis_dap_stableclocks(cmd->cmd.runtest->num_cycles);\n}\n\nstatic void cmsis_dap_execute_tms(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"TMS: %d bits\", cmd->cmd.tms->num_bits);\n\tcmsis_dap_cmd_dap_swj_sequence(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);\n}\n\n/* TODO: Is there need to call cmsis_dap_flush() for the JTAG_PATHMOVE,\n * JTAG_RUNTEST, JTAG_STABLECLOCKS? */\nstatic void cmsis_dap_execute_command(struct jtag_command *cmd)\n{\n\tswitch (cmd->type) {\n\t\tcase JTAG_SLEEP:\n\t\t\tcmsis_dap_flush();\n\t\t\tcmsis_dap_execute_sleep(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tcmsis_dap_flush();\n\t\t\tcmsis_dap_execute_tlr_reset(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tcmsis_dap_execute_scan(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tcmsis_dap_execute_pathmove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tcmsis_dap_execute_runtest(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tcmsis_dap_execute_stableclocks(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\tcmsis_dap_execute_tms(cmd);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%X encountered\", cmd->type);\n\t\t\texit(-1);\n\t}\n}\n\nstatic int cmsis_dap_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\n\twhile (cmd) {\n\t\tcmsis_dap_execute_command(cmd);\n\t\tcmd = cmd->next;\n\t}\n\n\tcmsis_dap_flush();\n\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_speed(int speed)\n{\n\tif (speed == 0) {\n\t\tLOG_ERROR(\"RTCK not supported. Set nonzero \\\"adapter speed\\\".\");\n\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\t}\n\n\treturn cmsis_dap_cmd_dap_swj_clock(speed);\n}\n\nstatic int cmsis_dap_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\treturn ERROR_OK;\n}\n\nstatic int cmsis_dap_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\treturn ERROR_OK;\n}\n\nstatic bool calculate_swo_prescaler(unsigned int traceclkin_freq,\n\t\tuint32_t trace_freq, uint16_t *prescaler)\n{\n\tunsigned int presc = (traceclkin_freq + trace_freq / 2) / trace_freq;\n\tif (presc == 0 || presc > TPIU_ACPR_MAX_SWOSCALER + 1)\n\t\treturn false;\n\n\t/* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */\n\tunsigned int max_deviation = (traceclkin_freq * 3) / 100;\n\tif (presc * trace_freq < traceclkin_freq - max_deviation ||\n\t    presc * trace_freq > traceclkin_freq + max_deviation)\n\t\treturn false;\n\n\t*prescaler = presc;\n\n\treturn true;\n}\n\n/**\n * @see adapter_driver::config_trace\n */\nstatic int cmsis_dap_config_trace(\n\t\t\t\tbool trace_enabled,\n\t\t\t\tenum tpiu_pin_protocol pin_protocol,\n\t\t\t\tuint32_t port_size,\n\t\t\t\tunsigned int *swo_freq,\n\t\t\t\tunsigned int traceclkin_hz,\n\t\t\t\tuint16_t *swo_prescaler)\n{\n\tint retval;\n\n\tif (!trace_enabled) {\n\t\tif (cmsis_dap_handle->trace_enabled) {\n\t\t\tretval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to disable the SWO-trace.\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t\tcmsis_dap_handle->trace_enabled = false;\n\t\tLOG_INFO(\"SWO-trace disabled.\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!(cmsis_dap_handle->caps & INFO_CAPS_SWO_UART) &&\n\t    !(cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) {\n\t\tLOG_ERROR(\"SWO-trace is not supported by the device.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t swo_mode;\n\tif (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_UART &&\n\t   (cmsis_dap_handle->caps & INFO_CAPS_SWO_UART)) {\n\t\tswo_mode = DAP_SWO_MODE_UART;\n\t} else if (pin_protocol == TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER &&\n\t\t  (cmsis_dap_handle->caps & INFO_CAPS_SWO_MANCHESTER)) {\n\t\tswo_mode = DAP_SWO_MODE_MANCHESTER;\n\t} else {\n\t\tLOG_ERROR(\"Selected pin protocol is not supported.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (*swo_freq == 0) {\n\t\tLOG_INFO(\"SWO-trace frequency autodetection not implemented.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_STOP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcmsis_dap_handle->trace_enabled = false;\n\n\tretval = cmsis_dap_get_swo_buf_sz(&cmsis_dap_handle->swo_buf_sz);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cmsis_dap_cmd_dap_swo_transport(DAP_SWO_TRANSPORT_DATA);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cmsis_dap_cmd_dap_swo_mode(swo_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cmsis_dap_cmd_dap_swo_baudrate(*swo_freq, swo_freq);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!calculate_swo_prescaler(traceclkin_hz, *swo_freq,\n\t\t\tswo_prescaler)) {\n\t\tLOG_ERROR(\"SWO frequency is not suitable. Please choose a \"\n\t\t\t\"different frequency or use auto-detection.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"SWO frequency: %u Hz.\", *swo_freq);\n\tLOG_INFO(\"SWO prescaler: %u.\", *swo_prescaler);\n\n\tretval = cmsis_dap_cmd_dap_swo_control(DAP_SWO_CONTROL_START);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcmsis_dap_handle->trace_enabled = true;\n\n\treturn ERROR_OK;\n}\n\n/**\n * @see adapter_driver::poll_trace\n */\nstatic int cmsis_dap_poll_trace(uint8_t *buf, size_t *size)\n{\n\tuint8_t trace_status;\n\tsize_t trace_count;\n\n\tif (!cmsis_dap_handle->trace_enabled) {\n\t\t*size = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tint retval = cmsis_dap_cmd_dap_swo_status(&trace_status, &trace_count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE)\n\t\treturn ERROR_FAIL;\n\n\t*size = trace_count < *size ? trace_count : *size;\n\tsize_t read_so_far = 0;\n\tdo {\n\t\tsize_t rb = 0;\n\t\tuint32_t packet_size = cmsis_dap_handle->packet_size - 4 /*data-reply*/;\n\t\tuint32_t remaining = *size - read_so_far;\n\t\tif (remaining < packet_size)\n\t\t\tpacket_size = remaining;\n\t\tretval = cmsis_dap_cmd_dap_swo_data(\n\t\t\t\t\t\tpacket_size,\n\t\t\t\t\t\t&trace_status,\n\t\t\t\t\t\t&rb,\n\t\t\t\t\t\t&buf[read_so_far]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif ((trace_status & DAP_SWO_STATUS_CAPTURE_MASK) != DAP_SWO_STATUS_CAPTURE_ACTIVE)\n\t\t\treturn ERROR_FAIL;\n\n\t\tread_so_far += rb;\n\t} while (read_so_far < *size);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(cmsis_dap_handle_info_command)\n{\n\tif (cmsis_dap_get_version_info() == ERROR_OK)\n\t\tcmsis_dap_get_status();\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(cmsis_dap_handle_cmd_command)\n{\n\tuint8_t *command = cmsis_dap_handle->command;\n\n\tfor (unsigned i = 0; i < CMD_ARGC; i++)\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[i], command[i]);\n\n\tint retval = cmsis_dap_xfer(cmsis_dap_handle, CMD_ARGC);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"CMSIS-DAP command failed.\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tuint8_t *resp = cmsis_dap_handle->response;\n\tLOG_INFO(\"Returned data %02\" PRIx8 \" %02\" PRIx8 \" %02\" PRIx8 \" %02\" PRIx8,\n\t\tresp[1], resp[2], resp[3], resp[4]);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(cmsis_dap_handle_vid_pid_command)\n{\n\tif (CMD_ARGC > MAX_USB_IDS * 2) {\n\t\tLOG_WARNING(\"ignoring extra IDs in cmsis_dap_vid_pid \"\n\t\t\t\"(maximum is %d pairs)\", MAX_USB_IDS);\n\t\tCMD_ARGC = MAX_USB_IDS * 2;\n\t}\n\tif (CMD_ARGC < 2 || (CMD_ARGC & 1)) {\n\t\tLOG_WARNING(\"incomplete cmsis_dap_vid_pid configuration directive\");\n\t\tif (CMD_ARGC < 2)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t/* remove the incomplete trailing id */\n\t\tCMD_ARGC -= 1;\n\t}\n\n\tunsigned i;\n\tfor (i = 0; i < CMD_ARGC; i += 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], cmsis_dap_vid[i >> 1]);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], cmsis_dap_pid[i >> 1]);\n\t}\n\n\t/*\n\t * Explicitly terminate, in case there are multiples instances of\n\t * cmsis_dap_vid_pid.\n\t */\n\tcmsis_dap_vid[i >> 1] = cmsis_dap_pid[i >> 1] = 0;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(cmsis_dap_handle_backend_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tif (strcmp(CMD_ARGV[0], \"auto\") == 0) {\n\t\t\tcmsis_dap_backend = -1; /* autoselect */\n\t\t} else {\n\t\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(cmsis_dap_backends); i++) {\n\t\t\t\tif (strcasecmp(cmsis_dap_backends[i]->name, CMD_ARGV[0]) == 0) {\n\t\t\t\t\tcmsis_dap_backend = i;\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tLOG_ERROR(\"invalid backend argument to cmsis_dap_backend <backend>\");\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"expected exactly one argument to cmsis_dap_backend <backend>\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration cmsis_dap_subcommand_handlers[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = &cmsis_dap_handle_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"show cmsis-dap info\",\n\t},\n\t{\n\t\t.name = \"cmd\",\n\t\t.handler = &cmsis_dap_handle_cmd_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"issue cmsis-dap command\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\nstatic const struct command_registration cmsis_dap_command_handlers[] = {\n\t{\n\t\t.name = \"cmsis-dap\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform CMSIS-DAP management\",\n\t\t.usage = \"<cmd>\",\n\t\t.chain = cmsis_dap_subcommand_handlers,\n\t},\n\t{\n\t\t.name = \"cmsis_dap_vid_pid\",\n\t\t.handler = &cmsis_dap_handle_vid_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"the vendor ID and product ID of the CMSIS-DAP device\",\n\t\t.usage = \"(vid pid)*\",\n\t},\n\t{\n\t\t.name = \"cmsis_dap_backend\",\n\t\t.handler = &cmsis_dap_handle_backend_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the communication backend to use (USB bulk or HID).\",\n\t\t.usage = \"(auto | usb_bulk | hid)\",\n\t},\n#if BUILD_CMSIS_DAP_USB\n\t{\n\t\t.name = \"cmsis_dap_usb\",\n\t\t.chain = cmsis_dap_usb_subcommand_handlers,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"USB bulk backend-specific commands\",\n\t\t.usage = \"<cmd>\",\n\t},\n#endif\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct swd_driver cmsis_dap_swd_driver = {\n\t.init = cmsis_dap_swd_init,\n\t.switch_seq = cmsis_dap_swd_switch_seq,\n\t.read_reg = cmsis_dap_swd_read_reg,\n\t.write_reg = cmsis_dap_swd_write_reg,\n\t.run = cmsis_dap_swd_run_queue,\n};\n\nstatic const char * const cmsis_dap_transport[] = { \"swd\", \"jtag\", NULL };\n\nstatic struct jtag_interface cmsis_dap_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = cmsis_dap_execute_queue,\n};\n\nstruct adapter_driver cmsis_dap_adapter_driver = {\n\t.name = \"cmsis-dap\",\n\t.transports = cmsis_dap_transport,\n\t.commands = cmsis_dap_command_handlers,\n\n\t.init = cmsis_dap_init,\n\t.quit = cmsis_dap_quit,\n\t.reset = cmsis_dap_reset,\n\t.speed = cmsis_dap_speed,\n\t.khz = cmsis_dap_khz,\n\t.speed_div = cmsis_dap_speed_div,\n\t.config_trace = cmsis_dap_config_trace,\n\t.poll_trace = cmsis_dap_poll_trace,\n\n\t.jtag_ops = &cmsis_dap_interface,\n\t.swd_ops = &cmsis_dap_swd_driver,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/cmsis_dap.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H\n#define OPENOCD_JTAG_DRIVERS_CMSIS_DAP_H\n\n#include <stdint.h>\n\nstruct cmsis_dap_backend;\nstruct cmsis_dap_backend_data;\n\nstruct pending_transfer_result {\n\tuint8_t cmd;\n\tuint32_t data;\n\tvoid *buffer;\n};\n\n/* Up to MIN(packet_count, MAX_PENDING_REQUESTS) requests may be issued\n * until the first response arrives */\n#define MAX_PENDING_REQUESTS 4\n\nstruct pending_request_block {\n\tstruct pending_transfer_result *transfers;\n\tunsigned int transfer_count;\n\tuint8_t command;\n};\n\nstruct cmsis_dap {\n\tstruct cmsis_dap_backend_data *bdata;\n\tconst struct cmsis_dap_backend *backend;\n\tunsigned int packet_size;\n\tunsigned int packet_usable_size;\n\tunsigned int packet_buffer_size;\n\tuint8_t *packet_buffer;\n\tuint8_t *command;\n\tuint8_t *response;\n\n\t/* DP/AP register r/w operation counters used for checking the packet size\n\t * that would result from the queue run */\n\tunsigned int write_count;\n\tunsigned int read_count;\n\n\t/* We can use DAP_TransferBlock only if all SWD operations in the packet\n\t * are either all writes or all reads and use the same DP/AP register.\n\t * The following variables keep track of it */\n\tuint8_t common_swd_cmd;\n\tbool swd_cmds_differ;\n\n\t/* Pending requests are organized as a FIFO - circular buffer */\n\tstruct pending_request_block pending_fifo[MAX_PENDING_REQUESTS];\n\tunsigned int packet_count;\n\tunsigned int pending_fifo_put_idx, pending_fifo_get_idx;\n\tunsigned int pending_fifo_block_count;\n\n\tuint16_t caps;\n\tuint8_t mode;\n\tuint32_t swo_buf_sz;\n\tbool trace_enabled;\n};\n\nstruct cmsis_dap_backend {\n\tconst char *name;\n\tint (*open)(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial);\n\tvoid (*close)(struct cmsis_dap *dap);\n\tint (*read)(struct cmsis_dap *dap, int timeout_ms);\n\tint (*write)(struct cmsis_dap *dap, int len, int timeout_ms);\n\tint (*packet_buffer_alloc)(struct cmsis_dap *dap, unsigned int pkt_sz);\n};\n\nextern const struct cmsis_dap_backend cmsis_dap_hid_backend;\nextern const struct cmsis_dap_backend cmsis_dap_usb_backend;\nextern const struct command_registration cmsis_dap_usb_subcommand_handlers[];\n\n#define REPORT_ID_SIZE   1\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/cmsis_dap_usb_bulk.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Mickaël Thomas                                  *\n *   mickael9@gmail.com                                                    *\n *                                                                         *\n *   Copyright (C) 2016 by Maksym Hilliaka                                 *\n *   oter@frozen-team.com                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Phillip Pearson                                 *\n *   pp@myelin.co.nz                                                       *\n *                                                                         *\n *   Copyright (C) 2014 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n *                                                                         *\n *   Copyright (C) 2013 by mike brown                                      *\n *   mike@theshedworks.org.uk                                              *\n *                                                                         *\n *   Copyright (C) 2013 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/system.h>\n#include <libusb.h>\n#include <helper/log.h>\n#include <helper/replacements.h>\n\n#include \"cmsis_dap.h\"\n\nstruct cmsis_dap_backend_data {\n\tstruct libusb_context *usb_ctx;\n\tstruct libusb_device_handle *dev_handle;\n\tunsigned int ep_out;\n\tunsigned int ep_in;\n\tint interface;\n};\n\nstatic int cmsis_dap_usb_interface = -1;\n\nstatic void cmsis_dap_usb_close(struct cmsis_dap *dap);\nstatic int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);\n\nstatic int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial)\n{\n\tint err;\n\tstruct libusb_context *ctx;\n\tstruct libusb_device **device_list;\n\n\terr = libusb_init(&ctx);\n\tif (err) {\n\t\tLOG_ERROR(\"libusb initialization failed: %s\", libusb_strerror(err));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint num_devices = libusb_get_device_list(ctx, &device_list);\n\tif (num_devices < 0) {\n\t\tLOG_ERROR(\"could not enumerate USB devices: %s\", libusb_strerror(num_devices));\n\t\tlibusb_exit(ctx);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (int i = 0; i < num_devices; i++) {\n\t\tstruct libusb_device *dev = device_list[i];\n\t\tstruct libusb_device_descriptor dev_desc;\n\n\t\terr = libusb_get_device_descriptor(dev, &dev_desc);\n\t\tif (err) {\n\t\t\tLOG_ERROR(\"could not get device descriptor for device %d: %s\", i, libusb_strerror(err));\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Match VID/PID */\n\n\t\tbool id_match = false;\n\t\tbool id_filter = vids[0] || pids[0];\n\t\tfor (int id = 0; vids[id] || pids[id]; id++) {\n\t\t\tid_match = !vids[id] || dev_desc.idVendor == vids[id];\n\t\t\tid_match &= !pids[id] || dev_desc.idProduct == pids[id];\n\n\t\t\tif (id_match)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (id_filter && !id_match)\n\t\t\tcontinue;\n\n\t\t/* Don't continue if we asked for a serial number and the device doesn't have one */\n\t\tif (dev_desc.iSerialNumber == 0 && serial && serial[0])\n\t\t\tcontinue;\n\n\t\tstruct libusb_device_handle *dev_handle = NULL;\n\t\terr = libusb_open(dev, &dev_handle);\n\t\tif (err) {\n\t\t\t/* It's to be expected that most USB devices can't be opened\n\t\t\t * so only report an error if it was explicitly selected\n\t\t\t */\n\t\t\tif (id_filter) {\n\t\t\t\tLOG_ERROR(\"could not open device 0x%04x:0x%04x: %s\",\n\t\t\t\t\t\tdev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));\n\t\t\t} else {\n\t\t\t\tLOG_DEBUG(\"could not open device 0x%04x:0x%04x: %s\",\n\t\t\t\t\t\tdev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Match serial number */\n\n\t\tbool serial_match = false;\n\t\tchar dev_serial[256] = {0};\n\t\tif (dev_desc.iSerialNumber > 0) {\n\t\t\terr = libusb_get_string_descriptor_ascii(\n\t\t\t\t\tdev_handle, dev_desc.iSerialNumber,\n\t\t\t\t\t(uint8_t *)dev_serial, sizeof(dev_serial));\n\n\t\t\tif (err < 0) {\n\t\t\t\tconst char *msg = \"could not read serial number for device 0x%04x:0x%04x: %s\";\n\t\t\t\tif (serial)\n\t\t\t\t\tLOG_WARNING(msg, dev_desc.idVendor, dev_desc.idProduct,\n\t\t\t\t\t\t\t\tlibusb_strerror(err));\n\t\t\t\telse\n\t\t\t\t\tLOG_DEBUG(msg, dev_desc.idVendor, dev_desc.idProduct,\n\t\t\t\t\t\t\t\tlibusb_strerror(err));\n\t\t\t} else if (serial && strncmp(dev_serial, serial, sizeof(dev_serial)) == 0) {\n\t\t\t\tserial_match = true;\n\t\t\t}\n\t\t}\n\n\t\tif (serial && !serial_match) {\n\t\t\tlibusb_close(dev_handle);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Find the CMSIS-DAP string in product string */\n\n\t\tbool cmsis_dap_in_product_str = false;\n\t\tchar product_string[256] = {0};\n\t\tif (dev_desc.iProduct > 0) {\n\t\t\terr = libusb_get_string_descriptor_ascii(\n\t\t\t\t\tdev_handle, dev_desc.iProduct,\n\t\t\t\t\t(uint8_t *)product_string, sizeof(product_string));\n\t\t\tif (err < 0) {\n\t\t\t\tLOG_WARNING(\"could not read product string for device 0x%04x:0x%04x: %s\",\n\t\t\t\t\t\tdev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));\n\t\t\t} else if (strstr(product_string, \"CMSIS-DAP\")) {\n\t\t\t\tLOG_DEBUG(\"found product string of 0x%04x:0x%04x '%s'\",\n\t\t\t\t\t\t  dev_desc.idVendor, dev_desc.idProduct, product_string);\n\t\t\t\tcmsis_dap_in_product_str = true;\n\t\t\t}\n\t\t}\n\n\t\tbool device_identified_reliably = cmsis_dap_in_product_str\n\t\t\t\t\t\t\t\t\t\t\t|| serial_match || id_match;\n\n\t\t/* Find the CMSIS-DAP interface */\n\n\t\tfor (int config = 0; config < dev_desc.bNumConfigurations; config++) {\n\t\t\tstruct libusb_config_descriptor *config_desc;\n\t\t\terr = libusb_get_config_descriptor(dev, config, &config_desc);\n\t\t\tif (err) {\n\t\t\t\tLOG_ERROR(\"could not get configuration descriptor %d for device 0x%04x:0x%04x: %s\",\n\t\t\t\t\t\tconfig, dev_desc.idVendor, dev_desc.idProduct, libusb_strerror(err));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"enumerating interfaces of 0x%04x:0x%04x\",\n\t\t\t\t\t  dev_desc.idVendor, dev_desc.idProduct);\n\t\t\tint config_num = config_desc->bConfigurationValue;\n\t\t\tconst struct libusb_interface_descriptor *intf_desc_candidate = NULL;\n\t\t\tconst struct libusb_interface_descriptor *intf_desc_found = NULL;\n\n\t\t\tfor (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {\n\t\t\t\tconst struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];\n\t\t\t\tint interface_num = intf_desc->bInterfaceNumber;\n\n\t\t\t\t/* Skip this interface if another one was requested explicitly */\n\t\t\t\tif (cmsis_dap_usb_interface != -1 && cmsis_dap_usb_interface != interface_num)\n\t\t\t\t\tcontinue;\n\n\t\t\t\t/* CMSIS-DAP v2 spec says:\n\t\t\t\t *\n\t\t\t\t * CMSIS-DAP with default V2 configuration uses WinUSB and is therefore faster.\n\t\t\t\t * Optionally support for streaming SWO trace is provided via an additional USB endpoint.\n\t\t\t\t *\n\t\t\t\t * The WinUSB configuration requires custom class support with the interface setting\n\t\t\t\t *     Class Code: 0xFF (Vendor specific)\n\t\t\t\t *     Subclass: 0x00\n\t\t\t\t *     Protocol code: 0x00\n\t\t\t\t *\n\t\t\t\t * Depending on the configuration it uses the following USB endpoints which should be configured\n\t\t\t\t * in the interface descriptor in this order:\n\t\t\t\t *  - Endpoint 1: Bulk Out – used for commands received from host PC.\n\t\t\t\t *  - Endpoint 2: Bulk In – used for responses send to host PC.\n\t\t\t\t *  - Endpoint 3: Bulk In (optional) – used for streaming SWO trace (if enabled with SWO_STREAM).\n\t\t\t\t */\n\n\t\t\t\t/* Search for \"CMSIS-DAP\" in the interface string */\n\t\t\t\tbool cmsis_dap_in_interface_str = false;\n\t\t\t\tif (intf_desc->iInterface != 0) {\n\n\t\t\t\t\tchar interface_str[256] = {0};\n\n\t\t\t\t\terr = libusb_get_string_descriptor_ascii(\n\t\t\t\t\t\t\tdev_handle, intf_desc->iInterface,\n\t\t\t\t\t\t\t(uint8_t *)interface_str, sizeof(interface_str));\n\t\t\t\t\tif (err < 0) {\n\t\t\t\t\t\tLOG_DEBUG(\"could not read interface string %d for device 0x%04x:0x%04x: %s\",\n\t\t\t\t\t\t\t\t  intf_desc->iInterface,\n\t\t\t\t\t\t\t\t  dev_desc.idVendor, dev_desc.idProduct,\n\t\t\t\t\t\t\t\t  libusb_strerror(err));\n\t\t\t\t\t} else if (strstr(interface_str, \"CMSIS-DAP\")) {\n\t\t\t\t\t\tcmsis_dap_in_interface_str = true;\n\t\t\t\t\t\tLOG_DEBUG(\"found interface %d string '%s'\",\n\t\t\t\t\t\t\t\t  interface_num, interface_str);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Bypass the following check if this interface was explicitly requested. */\n\t\t\t\tif (cmsis_dap_usb_interface == -1) {\n\t\t\t\t\tif (!cmsis_dap_in_product_str && !cmsis_dap_in_interface_str)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t/* check endpoints */\n\t\t\t\tif (intf_desc->bNumEndpoints < 2) {\n\t\t\t\t\tLOG_DEBUG(\"skipping interface %d, has only %d endpoints\",\n\t\t\t\t\t\t\t  interface_num, intf_desc->bNumEndpoints);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ((intf_desc->endpoint[0].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||\n\t\t\t\t\t\t(intf_desc->endpoint[0].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_OUT) {\n\t\t\t\t\tLOG_DEBUG(\"skipping interface %d, endpoint[0] is not bulk out\",\n\t\t\t\t\t\t\t  interface_num);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif ((intf_desc->endpoint[1].bmAttributes & 3) != LIBUSB_TRANSFER_TYPE_BULK ||\n\t\t\t\t\t\t(intf_desc->endpoint[1].bEndpointAddress & 0x80) != LIBUSB_ENDPOINT_IN) {\n\t\t\t\t\tLOG_DEBUG(\"skipping interface %d, endpoint[1] is not bulk in\",\n\t\t\t\t\t\t\t  interface_num);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t/* We can rely on the interface is really CMSIS-DAP if\n\t\t\t\t * - we've seen CMSIS-DAP in the interface string\n\t\t\t\t * - config asked explicitly for an interface number\n\t\t\t\t * - the device has only one interface\n\t\t\t\t * The later two cases should be honored only if we know\n\t\t\t\t * we are on the right device */\n\t\t\t\tbool intf_identified_reliably = cmsis_dap_in_interface_str\n\t\t\t\t\t\t\t|| (device_identified_reliably &&\n\t\t\t\t\t\t\t\t\t(cmsis_dap_usb_interface != -1\n\t\t\t\t\t\t\t\t\t || config_desc->bNumInterfaces == 1));\n\n\t\t\t\tif (intf_desc->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC ||\n\t\t\t\t\t\tintf_desc->bInterfaceSubClass != 0 || intf_desc->bInterfaceProtocol != 0) {\n\t\t\t\t\t/* If the interface is reliably identified\n\t\t\t\t\t * then we need not insist on setting USB class, subclass and protocol\n\t\t\t\t\t * exactly as the specification requires.\n\t\t\t\t\t * Just filter out the well known classes, mainly CDC and MSC.\n\t\t\t\t\t * At least KitProg3 uses class 0 contrary to the specification */\n\t\t\t\t\tif (intf_identified_reliably &&\n\t\t\t\t\t\t\t(intf_desc->bInterfaceClass == 0 || intf_desc->bInterfaceClass > 0x12)) {\n\t\t\t\t\t\tLOG_WARNING(\"Using CMSIS-DAPv2 interface %d with wrong class %\" PRId8\n\t\t\t\t\t\t\t\t  \" subclass %\" PRId8 \" or protocol %\" PRId8,\n\t\t\t\t\t\t\t\t  interface_num,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceClass,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceSubClass,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceProtocol);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tLOG_DEBUG(\"skipping interface %d, class %\" PRId8\n\t\t\t\t\t\t\t\t  \" subclass %\" PRId8 \" protocol %\" PRId8,\n\t\t\t\t\t\t\t\t  interface_num,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceClass,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceSubClass,\n\t\t\t\t\t\t\t\t  intf_desc->bInterfaceProtocol);\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (intf_identified_reliably) {\n\t\t\t\t\t/* That's the one! */\n\t\t\t\t\tintf_desc_found = intf_desc;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (!intf_desc_candidate && device_identified_reliably) {\n\t\t\t\t\t/* This interface looks suitable for CMSIS-DAP. Store the pointer to it\n\t\t\t\t\t * and keep searching for another one with CMSIS-DAP in interface string */\n\t\t\t\t\tintf_desc_candidate = intf_desc;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!intf_desc_found) {\n\t\t\t\t/* We were not able to identify reliably which interface is CMSIS-DAP.\n\t\t\t\t * Let's use the first suitable if we found one */\n\t\t\t\tintf_desc_found = intf_desc_candidate;\n\t\t\t}\n\n\t\t\tif (!intf_desc_found) {\n\t\t\t\tlibusb_free_config_descriptor(config_desc);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* We've chosen an interface, connect to it */\n\t\t\tint interface_num = intf_desc_found->bInterfaceNumber;\n\t\t\tint packet_size = intf_desc_found->endpoint[0].wMaxPacketSize;\n\t\t\tint ep_out = intf_desc_found->endpoint[0].bEndpointAddress;\n\t\t\tint ep_in = intf_desc_found->endpoint[1].bEndpointAddress;\n\n\t\t\tlibusb_free_config_descriptor(config_desc);\n\t\t\tlibusb_free_device_list(device_list, true);\n\n\t\t\tLOG_INFO(\"Using CMSIS-DAPv2 interface with VID:PID=0x%04x:0x%04x, serial=%s\",\n\t\t\t\t\tdev_desc.idVendor, dev_desc.idProduct, dev_serial);\n\n\t\t\tint current_config;\n\t\t\terr = libusb_get_configuration(dev_handle, &current_config);\n\t\t\tif (err) {\n\t\t\t\tLOG_ERROR(\"could not find current configuration: %s\", libusb_strerror(err));\n\t\t\t\tlibusb_close(dev_handle);\n\t\t\t\tlibusb_exit(ctx);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tif (config_num != current_config) {\n\t\t\t\terr = libusb_set_configuration(dev_handle, config_num);\n\t\t\t\tif (err) {\n\t\t\t\t\tLOG_ERROR(\"could not set configuration: %s\", libusb_strerror(err));\n\t\t\t\t\tlibusb_close(dev_handle);\n\t\t\t\t\tlibusb_exit(ctx);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\terr = libusb_claim_interface(dev_handle, interface_num);\n\t\t\tif (err)\n\t\t\t\tLOG_WARNING(\"could not claim interface: %s\", libusb_strerror(err));\n\n\t\t\tdap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));\n\t\t\tif (!dap->bdata) {\n\t\t\t\tLOG_ERROR(\"unable to allocate memory\");\n\t\t\t\tlibusb_release_interface(dev_handle, interface_num);\n\t\t\t\tlibusb_close(dev_handle);\n\t\t\t\tlibusb_exit(ctx);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tdap->bdata->usb_ctx = ctx;\n\t\t\tdap->bdata->dev_handle = dev_handle;\n\t\t\tdap->bdata->ep_out = ep_out;\n\t\t\tdap->bdata->ep_in = ep_in;\n\t\t\tdap->bdata->interface = interface_num;\n\n\t\t\terr = cmsis_dap_usb_alloc(dap, packet_size);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\tcmsis_dap_usb_close(dap);\n\n\t\t\treturn err;\n\t\t}\n\n\t\tlibusb_close(dev_handle);\n\t}\n\n\tlibusb_free_device_list(device_list, true);\n\n\tlibusb_exit(ctx);\n\treturn ERROR_FAIL;\n}\n\nstatic void cmsis_dap_usb_close(struct cmsis_dap *dap)\n{\n\tlibusb_release_interface(dap->bdata->dev_handle, dap->bdata->interface);\n\tlibusb_close(dap->bdata->dev_handle);\n\tlibusb_exit(dap->bdata->usb_ctx);\n\tfree(dap->bdata);\n\tdap->bdata = NULL;\n\tfree(dap->packet_buffer);\n\tdap->packet_buffer = NULL;\n}\n\nstatic int cmsis_dap_usb_read(struct cmsis_dap *dap, int timeout_ms)\n{\n\tint transferred = 0;\n\tint err;\n\n\terr = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_in,\n\t\t\t\t\t\t\tdap->packet_buffer, dap->packet_size, &transferred, timeout_ms);\n\tif (err) {\n\t\tif (err == LIBUSB_ERROR_TIMEOUT) {\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t} else {\n\t\t\tLOG_ERROR(\"error reading data: %s\", libusb_strerror(err));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tmemset(&dap->packet_buffer[transferred], 0, dap->packet_buffer_size - transferred);\n\n\treturn transferred;\n}\n\nstatic int cmsis_dap_usb_write(struct cmsis_dap *dap, int txlen, int timeout_ms)\n{\n\tint transferred = 0;\n\tint err;\n\n\t/* skip the first byte that is only used by the HID backend */\n\terr = libusb_bulk_transfer(dap->bdata->dev_handle, dap->bdata->ep_out,\n\t\t\t\t\t\t\tdap->packet_buffer, txlen, &transferred, timeout_ms);\n\tif (err) {\n\t\tif (err == LIBUSB_ERROR_TIMEOUT) {\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t} else {\n\t\t\tLOG_ERROR(\"error writing data: %s\", libusb_strerror(err));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn transferred;\n}\n\nstatic int cmsis_dap_usb_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)\n{\n\tuint8_t *buf = malloc(pkt_sz);\n\tif (!buf) {\n\t\tLOG_ERROR(\"unable to allocate CMSIS-DAP packet buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdap->packet_buffer = buf;\n\tdap->packet_size = pkt_sz;\n\tdap->packet_buffer_size = pkt_sz;\n\t/* Prevent sending zero size USB packets */\n\tdap->packet_usable_size = pkt_sz - 1;\n\n\tdap->command = dap->packet_buffer;\n\tdap->response = dap->packet_buffer;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(cmsis_dap_handle_usb_interface_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cmsis_dap_usb_interface);\n\telse\n\t\tLOG_ERROR(\"expected exactly one argument to cmsis_dap_usb_interface <interface_number>\");\n\n\treturn ERROR_OK;\n}\n\nconst struct command_registration cmsis_dap_usb_subcommand_handlers[] = {\n\t{\n\t\t.name = \"interface\",\n\t\t.handler = &cmsis_dap_handle_usb_interface_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the USB interface number to use (for USB bulk backend only)\",\n\t\t.usage = \"<interface_number>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct cmsis_dap_backend cmsis_dap_usb_backend = {\n\t.name = \"usb_bulk\",\n\t.open = cmsis_dap_usb_open,\n\t.close = cmsis_dap_usb_close,\n\t.read = cmsis_dap_usb_read,\n\t.write = cmsis_dap_usb_write,\n\t.packet_buffer_alloc = cmsis_dap_usb_alloc,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/cmsis_dap_usb_hid.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Mickaël Thomas                                  *\n *   mickael9@gmail.com                                                    *\n *                                                                         *\n *   Copyright (C) 2016 by Maksym Hilliaka                                 *\n *   oter@frozen-team.com                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Phillip Pearson                                 *\n *   pp@myelin.co.nz                                                       *\n *                                                                         *\n *   Copyright (C) 2014 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n *                                                                         *\n *   Copyright (C) 2013 by mike brown                                      *\n *   mike@theshedworks.org.uk                                              *\n *                                                                         *\n *   Copyright (C) 2013 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n#include <hidapi.h>\n#include <helper/log.h>\n\n#include \"cmsis_dap.h\"\n\nstruct cmsis_dap_backend_data {\n\thid_device *dev_handle;\n};\n\nstatic void cmsis_dap_hid_close(struct cmsis_dap *dap);\nstatic int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz);\n\nstatic int cmsis_dap_hid_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial)\n{\n\thid_device *dev = NULL;\n\tint i;\n\tstruct hid_device_info *devs, *cur_dev;\n\tunsigned short target_vid, target_pid;\n\n\ttarget_vid = 0;\n\ttarget_pid = 0;\n\n\tif (hid_init() != 0) {\n\t\tLOG_ERROR(\"unable to open HIDAPI\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * The CMSIS-DAP specification stipulates:\n\t * \"The Product String must contain \"CMSIS-DAP\" somewhere in the string. This is used by the\n\t * debuggers to identify a CMSIS-DAP compliant Debug Unit that is connected to a host computer.\"\n\t */\n\tdevs = hid_enumerate(0x0, 0x0);\n\tcur_dev = devs;\n\twhile (cur_dev) {\n\t\tbool found = false;\n\n\t\tif (vids[0] == 0) {\n\t\t\tif (!cur_dev->product_string) {\n\t\t\t\tLOG_DEBUG(\"Cannot read product string of device 0x%x:0x%x\",\n\t\t\t\t\t  cur_dev->vendor_id, cur_dev->product_id);\n\t\t\t} else if (wcsstr(cur_dev->product_string, L\"CMSIS-DAP\")) {\n\t\t\t\t/* if the user hasn't specified VID:PID *and*\n\t\t\t\t * product string contains \"CMSIS-DAP\", pick it\n\t\t\t\t */\n\t\t\t\tfound = true;\n\t\t\t}\n\t\t} else {\n\t\t\t/* otherwise, exhaustively compare against all VID:PID in list */\n\t\t\tfor (i = 0; vids[i] || pids[i]; i++) {\n\t\t\t\tif ((vids[i] == cur_dev->vendor_id) && (pids[i] == cur_dev->product_id))\n\t\t\t\t\tfound = true;\n\t\t\t}\n\t\t}\n\n\t\t/* LPC-LINK2 has cmsis-dap on interface 0 and other HID functions on other interfaces */\n\t\tif (cur_dev->vendor_id == 0x1fc9 && cur_dev->product_id == 0x0090 && cur_dev->interface_number != 0)\n\t\t\tfound = false;\n\n\t\tif (found) {\n\t\t\t/* check serial number matches if given */\n\t\t\tif (!serial)\n\t\t\t\tbreak;\n\n\t\t\tif (cur_dev->serial_number) {\n\t\t\t\tsize_t len = (strlen(serial) + 1) * sizeof(wchar_t);\n\t\t\t\twchar_t *wserial = malloc(len);\n\t\t\t\tmbstowcs(wserial, serial, len);\n\n\t\t\t\tif (wcscmp(wserial, cur_dev->serial_number) == 0) {\n\t\t\t\t\tfree(wserial);\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tfree(wserial);\n\t\t\t\t\twserial = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcur_dev = cur_dev->next;\n\t}\n\n\tif (cur_dev) {\n\t\ttarget_vid = cur_dev->vendor_id;\n\t\ttarget_pid = cur_dev->product_id;\n\t}\n\n\tif (target_vid == 0 && target_pid == 0) {\n\t\thid_free_enumeration(devs);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdap->bdata = malloc(sizeof(struct cmsis_dap_backend_data));\n\tif (!dap->bdata) {\n\t\tLOG_ERROR(\"unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdev = hid_open_path(cur_dev->path);\n\thid_free_enumeration(devs);\n\n\tif (!dev) {\n\t\tLOG_ERROR(\"unable to open CMSIS-DAP device 0x%x:0x%x\", target_vid, target_pid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* allocate default packet buffer, may be changed later.\n\t * currently with HIDAPI we have no way of getting the output report length\n\t * without this info we cannot communicate with the adapter.\n\t * For the moment we have to hard code the packet size */\n\n\tunsigned int packet_size = 64;\n\n\t/* atmel cmsis-dap uses 512 byte reports */\n\t/* except when it doesn't e.g. with mEDBG on SAMD10 Xplained\n\t * board */\n\t/* TODO: HID report descriptor should be parsed instead of\n\t * hardcoding a match by VID */\n\tif (target_vid == 0x03eb && target_pid != 0x2145 && target_pid != 0x2175)\n\t\tpacket_size = 512;\n\n\tdap->bdata->dev_handle = dev;\n\n\tint retval = cmsis_dap_hid_alloc(dap, packet_size);\n\tif (retval != ERROR_OK) {\n\t\tcmsis_dap_hid_close(dap);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdap->command = dap->packet_buffer + REPORT_ID_SIZE;\n\tdap->response = dap->packet_buffer;\n\treturn ERROR_OK;\n}\n\nstatic void cmsis_dap_hid_close(struct cmsis_dap *dap)\n{\n\thid_close(dap->bdata->dev_handle);\n\thid_exit();\n\tfree(dap->bdata);\n\tdap->bdata = NULL;\n\tfree(dap->packet_buffer);\n\tdap->packet_buffer = NULL;\n}\n\nstatic int cmsis_dap_hid_read(struct cmsis_dap *dap, int timeout_ms)\n{\n\tint retval = hid_read_timeout(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size, timeout_ms);\n\n\tif (retval == 0) {\n\t\treturn ERROR_TIMEOUT_REACHED;\n\t} else if (retval == -1) {\n\t\tLOG_ERROR(\"error reading data: %ls\", hid_error(dap->bdata->dev_handle));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic int cmsis_dap_hid_write(struct cmsis_dap *dap, int txlen, int timeout_ms)\n{\n\t(void) timeout_ms;\n\n\tdap->packet_buffer[0] = 0; /* HID report number */\n\n\t/* Pad the rest of the TX buffer with 0's */\n\tmemset(dap->command + txlen, 0, dap->packet_size - txlen);\n\n\t/* write data to device */\n\tint retval = hid_write(dap->bdata->dev_handle, dap->packet_buffer, dap->packet_buffer_size);\n\tif (retval == -1) {\n\t\tLOG_ERROR(\"error writing data: %ls\", hid_error(dap->bdata->dev_handle));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic int cmsis_dap_hid_alloc(struct cmsis_dap *dap, unsigned int pkt_sz)\n{\n\tunsigned int packet_buffer_size = pkt_sz + REPORT_ID_SIZE;\n\tuint8_t *buf = malloc(packet_buffer_size);\n\tif (!buf) {\n\t\tLOG_ERROR(\"unable to allocate CMSIS-DAP packet buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdap->packet_buffer = buf;\n\tdap->packet_size = pkt_sz;\n\tdap->packet_usable_size = pkt_sz;\n\tdap->packet_buffer_size = packet_buffer_size;\n\n\tdap->command = dap->packet_buffer + REPORT_ID_SIZE;\n\tdap->response = dap->packet_buffer;\n\n\treturn ERROR_OK;\n}\n\nconst struct cmsis_dap_backend cmsis_dap_hid_backend = {\n\t.name = \"hid\",\n\t.open = cmsis_dap_hid_open,\n\t.close = cmsis_dap_hid_close,\n\t.read = cmsis_dap_hid_read,\n\t.write = cmsis_dap_hid_write,\n\t.packet_buffer_alloc = cmsis_dap_hid_alloc,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/driver.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <jtag/minidriver.h>\n#include <helper/command.h>\n\nstruct jtag_callback_entry {\n\tstruct jtag_callback_entry *next;\n\n\tjtag_callback_t callback;\n\tjtag_callback_data_t data0;\n\tjtag_callback_data_t data1;\n\tjtag_callback_data_t data2;\n\tjtag_callback_data_t data3;\n};\n\nstatic struct jtag_callback_entry *jtag_callback_queue_head;\nstatic struct jtag_callback_entry *jtag_callback_queue_tail;\n\nstatic void jtag_callback_queue_reset(void)\n{\n\tjtag_callback_queue_head = NULL;\n\tjtag_callback_queue_tail = NULL;\n}\n\n/**\n * see jtag_add_ir_scan()\n *\n */\nint interface_jtag_add_ir_scan(struct jtag_tap *active,\n\t\tconst struct scan_field *in_fields, tap_state_t state)\n{\n\tsize_t num_taps = jtag_tap_count_enabled();\n\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\tstruct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));\n\tstruct scan_field *out_fields = cmd_queue_alloc(num_taps  * sizeof(struct scan_field));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_SCAN;\n\tcmd->cmd.scan = scan;\n\n\tscan->ir_scan = true;\n\tscan->num_fields = num_taps;\t/* one field per device */\n\tscan->fields = out_fields;\n\tscan->end_state = state;\n\n\tstruct scan_field *field = out_fields;\t/* keep track where we insert data */\n\n\t/* loop over all enabled TAPs */\n\n\tfor (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {\n\t\t/* search the input field list for fields for the current TAP */\n\n\t\tif (tap == active) {\n\t\t\t/* if TAP is listed in input fields, copy the value */\n\t\t\ttap->bypass = 0;\n\n\t\t\tjtag_scan_field_clone(field, in_fields);\n\t\t} else {\n\t\t\t/* if a TAP isn't listed in input fields, set it to BYPASS */\n\n\t\t\ttap->bypass = 1;\n\n\t\t\tfield->num_bits = tap->ir_length;\n\t\t\tfield->out_value = buf_set_ones(cmd_queue_alloc(DIV_ROUND_UP(tap->ir_length, 8)), tap->ir_length);\n\t\t\tfield->in_value = NULL; /* do not collect input for tap's in bypass */\n\t\t}\n\n\t\t/* update device information */\n\t\tbuf_cpy(field->out_value, tap->cur_instr, tap->ir_length);\n\n\t\tfield++;\n\t}\n\t/* paranoia: jtag_tap_count_enabled() and jtag_tap_next_enabled() not in sync */\n\tassert(field == out_fields + num_taps);\n\n\treturn ERROR_OK;\n}\n\n/**\n * see jtag_add_dr_scan()\n *\n */\nint interface_jtag_add_dr_scan(struct jtag_tap *active, int in_num_fields,\n\t\tconst struct scan_field *in_fields, tap_state_t state)\n{\n\t/* count devices in bypass */\n\n\tsize_t bypass_devices = 0;\n\n\tfor (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {\n\t\tif (tap->bypass)\n\t\t\tbypass_devices++;\n\t}\n\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\tstruct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));\n\tstruct scan_field *out_fields = cmd_queue_alloc((in_num_fields + bypass_devices) * sizeof(struct scan_field));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_SCAN;\n\tcmd->cmd.scan = scan;\n\n\tscan->ir_scan = false;\n\tscan->num_fields = in_num_fields + bypass_devices;\n\tscan->fields = out_fields;\n\tscan->end_state = state;\n\n\tstruct scan_field *field = out_fields;\t/* keep track where we insert data */\n\n\t/* loop over all enabled TAPs */\n\n\tfor (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap; tap = jtag_tap_next_enabled(tap)) {\n\t\t/* if TAP is not bypassed insert matching input fields */\n\n\t\tif (!tap->bypass) {\n\t\t\tassert(active == tap);\n#ifndef NDEBUG\n\t\t\t/* remember initial position for assert() */\n\t\t\tstruct scan_field *start_field = field;\n#endif /* NDEBUG */\n\n\t\t\tfor (int j = 0; j < in_num_fields; j++) {\n\t\t\t\tjtag_scan_field_clone(field, in_fields + j);\n\n\t\t\t\tfield++;\n\t\t\t}\n\n\t\t\tassert(field > start_field);\t/* must have at least one input field per not bypassed TAP */\n\t\t}\n\n\t\t/* if a TAP is bypassed, generated a dummy bit*/\n\t\telse {\n\t\t\tfield->num_bits = 1;\n\t\t\tfield->out_value = NULL;\n\t\t\tfield->in_value = NULL;\n\n\t\t\tfield++;\n\t\t}\n\t}\n\n\tassert(field == out_fields + scan->num_fields); /* no superfluous input fields permitted */\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_add_plain_scan(int num_bits, const uint8_t *out_bits,\n\t\tuint8_t *in_bits, tap_state_t state, bool ir_scan)\n{\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\tstruct scan_command *scan = cmd_queue_alloc(sizeof(struct scan_command));\n\tstruct scan_field *out_fields = cmd_queue_alloc(sizeof(struct scan_field));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_SCAN;\n\tcmd->cmd.scan = scan;\n\n\tscan->ir_scan = ir_scan;\n\tscan->num_fields = 1;\n\tscan->fields = out_fields;\n\tscan->end_state = state;\n\n\tout_fields->num_bits = num_bits;\n\tout_fields->out_value = buf_cpy(out_bits, cmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);\n\tout_fields->in_value = in_bits;\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_plain_dr_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)\n{\n\treturn jtag_add_plain_scan(num_bits, out_bits, in_bits, state, false);\n}\n\nint interface_jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits, tap_state_t state)\n{\n\treturn jtag_add_plain_scan(num_bits, out_bits, in_bits, state, true);\n}\n\nint interface_jtag_add_tlr(void)\n{\n\ttap_state_t state = TAP_RESET;\n\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_TLR_RESET;\n\n\tcmd->cmd.statemove = cmd_queue_alloc(sizeof(struct statemove_command));\n\tcmd->cmd.statemove->end_state = state;\n\n\treturn ERROR_OK;\n}\n\nint interface_add_tms_seq(unsigned num_bits, const uint8_t *seq, enum tap_state state)\n{\n\tstruct jtag_command *cmd;\n\n\tcmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->type = JTAG_TMS;\n\tcmd->cmd.tms = cmd_queue_alloc(sizeof(*cmd->cmd.tms));\n\tif (!cmd->cmd.tms)\n\t\treturn ERROR_FAIL;\n\n\t/* copy the bits; our caller doesn't guarantee they'll persist */\n\tcmd->cmd.tms->num_bits = num_bits;\n\tcmd->cmd.tms->bits = buf_cpy(seq,\n\t\t\tcmd_queue_alloc(DIV_ROUND_UP(num_bits, 8)), num_bits);\n\tif (!cmd->cmd.tms->bits)\n\t\treturn ERROR_FAIL;\n\n\tjtag_queue_command(cmd);\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_pathmove(int num_states, const tap_state_t *path)\n{\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_PATHMOVE;\n\n\tcmd->cmd.pathmove = cmd_queue_alloc(sizeof(struct pathmove_command));\n\tcmd->cmd.pathmove->num_states = num_states;\n\tcmd->cmd.pathmove->path = cmd_queue_alloc(sizeof(tap_state_t) * num_states);\n\n\tfor (int i = 0; i < num_states; i++)\n\t\tcmd->cmd.pathmove->path[i] = path[i];\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_runtest(int num_cycles, tap_state_t state)\n{\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_RUNTEST;\n\n\tcmd->cmd.runtest = cmd_queue_alloc(sizeof(struct runtest_command));\n\tcmd->cmd.runtest->num_cycles = num_cycles;\n\tcmd->cmd.runtest->end_state = state;\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_clocks(int num_cycles)\n{\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_STABLECLOCKS;\n\n\tcmd->cmd.stableclocks = cmd_queue_alloc(sizeof(struct stableclocks_command));\n\tcmd->cmd.stableclocks->num_cycles = num_cycles;\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_reset(int req_trst, int req_srst)\n{\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_RESET;\n\n\tcmd->cmd.reset = cmd_queue_alloc(sizeof(struct reset_command));\n\tcmd->cmd.reset->trst = req_trst;\n\tcmd->cmd.reset->srst = req_srst;\n\n\treturn ERROR_OK;\n}\n\nint interface_jtag_add_sleep(uint32_t us)\n{\n\t/* allocate memory for a new list member */\n\tstruct jtag_command *cmd = cmd_queue_alloc(sizeof(struct jtag_command));\n\n\tjtag_queue_command(cmd);\n\n\tcmd->type = JTAG_SLEEP;\n\n\tcmd->cmd.sleep = cmd_queue_alloc(sizeof(struct sleep_command));\n\tcmd->cmd.sleep->us = us;\n\n\treturn ERROR_OK;\n}\n\n/* add callback to end of queue */\nvoid interface_jtag_add_callback4(jtag_callback_t callback,\n\t\tjtag_callback_data_t data0, jtag_callback_data_t data1,\n\t\tjtag_callback_data_t data2, jtag_callback_data_t data3)\n{\n\tstruct jtag_callback_entry *entry = cmd_queue_alloc(sizeof(struct jtag_callback_entry));\n\n\tentry->next = NULL;\n\tentry->callback = callback;\n\tentry->data0 = data0;\n\tentry->data1 = data1;\n\tentry->data2 = data2;\n\tentry->data3 = data3;\n\n\tif (!jtag_callback_queue_head) {\n\t\tjtag_callback_queue_head = entry;\n\t\tjtag_callback_queue_tail = entry;\n\t} else {\n\t\tjtag_callback_queue_tail->next = entry;\n\t\tjtag_callback_queue_tail = entry;\n\t}\n}\n\nint interface_jtag_execute_queue(void)\n{\n\tstatic int reentry;\n\n\tassert(reentry == 0);\n\treentry++;\n\n\tint retval = default_interface_jtag_execute_queue();\n\tif (retval == ERROR_OK) {\n\t\tstruct jtag_callback_entry *entry;\n\t\tfor (entry = jtag_callback_queue_head; entry; entry = entry->next) {\n\t\t\tretval = entry->callback(entry->data0, entry->data1, entry->data2, entry->data3);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tjtag_command_queue_reset();\n\tjtag_callback_queue_reset();\n\n\treentry--;\n\n\treturn retval;\n}\n\nstatic int jtag_convert_to_callback4(jtag_callback_data_t data0,\n\t\tjtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)\n{\n\t((jtag_callback1_t)data1)(data0);\n\treturn ERROR_OK;\n}\n\nvoid interface_jtag_add_callback(jtag_callback1_t callback, jtag_callback_data_t data0)\n{\n\tjtag_add_callback4(jtag_convert_to_callback4, data0, (jtag_callback_data_t)callback, 0, 0);\n}\n\nvoid jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0)\n{\n\tinterface_jtag_add_callback(f, data0);\n}\n\nvoid jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,\n\t\tjtag_callback_data_t data1, jtag_callback_data_t data2,\n\t\tjtag_callback_data_t data3)\n{\n\tinterface_jtag_add_callback4(f, data0, data1, data2, data3);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/dummy.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Øyvind Harboe                                   *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include \"bitbang.h\"\n#include \"hello.h\"\n\n/* my private tap controller state, which tracks state for calling code */\nstatic tap_state_t dummy_state = TAP_RESET;\n\nstatic int dummy_clock;\t\t/* edge detector */\n\nstatic int clock_count;\t\t/* count clocks in any stable state, only stable states */\n\nstatic uint32_t dummy_data;\n\nstatic bb_value_t dummy_read(void)\n{\n\tint data = 1 & dummy_data;\n\tdummy_data = (dummy_data >> 1) | (1 << 31);\n\treturn data ? BB_HIGH : BB_LOW;\n}\n\nstatic int dummy_write(int tck, int tms, int tdi)\n{\n\t/* TAP standard: \"state transitions occur on rising edge of clock\" */\n\tif (tck != dummy_clock) {\n\t\tif (tck) {\n\t\t\ttap_state_t old_state = dummy_state;\n\t\t\tdummy_state = tap_state_transition(old_state, tms);\n\n\t\t\tif (old_state != dummy_state) {\n\t\t\t\tif (clock_count) {\n\t\t\t\t\tLOG_DEBUG(\"dummy_tap: %d stable clocks\", clock_count);\n\t\t\t\t\tclock_count = 0;\n\t\t\t\t}\n\n\t\t\t\tLOG_DEBUG(\"dummy_tap: %s\", tap_state_name(dummy_state));\n\n#if defined(DEBUG)\n\t\t\t\tif (dummy_state == TAP_DRCAPTURE)\n\t\t\t\t\tdummy_data = 0x01255043;\n#endif\n\t\t\t} else {\n\t\t\t\t/* this is a stable state clock edge, no change of state here,\n\t\t\t\t * simply increment clock_count for subsequent logging\n\t\t\t\t */\n\t\t\t\t++clock_count;\n\t\t\t}\n\t\t}\n\t\tdummy_clock = tck;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int dummy_reset(int trst, int srst)\n{\n\tdummy_clock = 0;\n\n\tif (trst || (srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))\n\t\tdummy_state = TAP_RESET;\n\n\tLOG_DEBUG(\"reset to: %s\", tap_state_name(dummy_state));\n\treturn ERROR_OK;\n}\n\nstatic int dummy_led(int on)\n{\n\treturn ERROR_OK;\n}\n\nstatic struct bitbang_interface dummy_bitbang = {\n\t\t.read = &dummy_read,\n\t\t.write = &dummy_write,\n\t\t.blink = &dummy_led,\n\t};\n\nstatic int dummy_khz(int khz, int *jtag_speed)\n{\n\tif (khz == 0)\n\t\t*jtag_speed = 0;\n\telse\n\t\t*jtag_speed = 64000/khz;\n\treturn ERROR_OK;\n}\n\nstatic int dummy_speed_div(int speed, int *khz)\n{\n\tif (speed == 0)\n\t\t*khz = 0;\n\telse\n\t\t*khz = 64000/speed;\n\n\treturn ERROR_OK;\n}\n\nstatic int dummy_speed(int speed)\n{\n\treturn ERROR_OK;\n}\n\nstatic int dummy_init(void)\n{\n\tbitbang_interface = &dummy_bitbang;\n\n\treturn ERROR_OK;\n}\n\nstatic int dummy_quit(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration dummy_command_handlers[] = {\n\t{\n\t\t.name = \"dummy\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"dummy interface driver commands\",\n\t\t.chain = hello_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE,\n};\n\n/* The dummy driver is used to easily check the code path\n * where the target is unresponsive.\n */\nstatic struct jtag_interface dummy_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = &bitbang_execute_queue,\n};\n\nstruct adapter_driver dummy_adapter_driver = {\n\t.name = \"dummy\",\n\t.transports = jtag_only,\n\t.commands = dummy_command_handlers,\n\n\t.init = &dummy_init,\n\t.quit = &dummy_quit,\n\t.reset = &dummy_reset,\n\t.speed = &dummy_speed,\n\t.khz = &dummy_khz,\n\t.speed_div = &dummy_speed_div,\n\n\t.jtag_ops = &dummy_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ep93xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include \"bitbang.h\"\n\n#define TDO_BIT\t\t1\n#define TDI_BIT\t\t2\n#define TCK_BIT\t\t4\n#define TMS_BIT\t\t8\n#define TRST_BIT\t16\n#define SRST_BIT\t32\n#define VCC_BIT\t\t64\n\n#include <sys/mman.h>\n\nstatic uint8_t output_value;\nstatic int dev_mem_fd;\nstatic uint8_t *gpio_controller;\nstatic volatile uint8_t *gpio_data_register;\nstatic volatile uint8_t *gpio_data_direction_register;\n\n/* low level command set\n */\nstatic bb_value_t ep93xx_read(void);\nstatic int ep93xx_write(int tck, int tms, int tdi);\nstatic int ep93xx_reset(int trst, int srst);\n\nstatic int ep93xx_init(void);\nstatic int ep93xx_quit(void);\n\nstatic struct timespec ep93xx_zzzz;\n\nstatic struct jtag_interface ep93xx_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver ep93xx_adapter_driver = {\n\t.name = \"ep93xx\",\n\t.transports = jtag_only,\n\n\t.init = ep93xx_init,\n\t.quit = ep93xx_quit,\n\t.reset = ep93xx_reset,\n\n\t.jtag_ops = &ep93xx_interface,\n};\n\nstatic struct bitbang_interface ep93xx_bitbang = {\n\t.read = ep93xx_read,\n\t.write = ep93xx_write,\n\t.blink = NULL,\n};\n\nstatic bb_value_t ep93xx_read(void)\n{\n\treturn (*gpio_data_register & TDO_BIT) ? BB_HIGH : BB_LOW;\n}\n\nstatic int ep93xx_write(int tck, int tms, int tdi)\n{\n\tif (tck)\n\t\toutput_value |= TCK_BIT;\n\telse\n\t\toutput_value &= ~TCK_BIT;\n\n\tif (tms)\n\t\toutput_value |= TMS_BIT;\n\telse\n\t\toutput_value &= ~TMS_BIT;\n\n\tif (tdi)\n\t\toutput_value |= TDI_BIT;\n\telse\n\t\toutput_value &= ~TDI_BIT;\n\n\t*gpio_data_register = output_value;\n\tnanosleep(&ep93xx_zzzz, NULL);\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int ep93xx_reset(int trst, int srst)\n{\n\tif (trst == 0)\n\t\toutput_value |= TRST_BIT;\n\telse if (trst == 1)\n\t\toutput_value &= ~TRST_BIT;\n\n\tif (srst == 0)\n\t\toutput_value |= SRST_BIT;\n\telse if (srst == 1)\n\t\toutput_value &= ~SRST_BIT;\n\n\t*gpio_data_register = output_value;\n\tnanosleep(&ep93xx_zzzz, NULL);\n\n\treturn ERROR_OK;\n}\n\nstatic int set_gonk_mode(void)\n{\n\tvoid *syscon = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\n\t\t\tMAP_SHARED, dev_mem_fd, 0x80930000);\n\tif (syscon == MAP_FAILED) {\n\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tuint32_t devicecfg = *((volatile uint32_t *)((uintptr_t)syscon + 0x80));\n\t*((volatile uint32_t *)((uintptr_t)syscon + 0xc0)) = 0xaa;\n\t*((volatile uint32_t *)((uintptr_t)syscon + 0x80)) = devicecfg | 0x08000000;\n\n\tmunmap(syscon, 4096);\n\n\treturn ERROR_OK;\n}\n\nstatic int ep93xx_init(void)\n{\n\tint ret;\n\n\tbitbang_interface = &ep93xx_bitbang;\n\n\tep93xx_zzzz.tv_sec = 0;\n\tep93xx_zzzz.tv_nsec = 10000000;\n\n\tdev_mem_fd = open(\"/dev/mem\", O_RDWR | O_SYNC);\n\tif (dev_mem_fd < 0) {\n\t\tLOG_ERROR(\"open: %s\", strerror(errno));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tgpio_controller = mmap(NULL, 4096, PROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, 0x80840000);\n\tif (gpio_controller == MAP_FAILED) {\n\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\tclose(dev_mem_fd);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tret = set_gonk_mode();\n\tif (ret != ERROR_OK) {\n\t\tmunmap(gpio_controller, 4096);\n\t\tclose(dev_mem_fd);\n\t\treturn ret;\n\t}\n\n#if 0\n\t/* Use GPIO port A.  */\n\tgpio_data_register = gpio_controller + 0x00;\n\tgpio_data_direction_register = gpio_controller + 0x10;\n\n\n\t/* Use GPIO port B.  */\n\tgpio_data_register = gpio_controller + 0x04;\n\tgpio_data_direction_register = gpio_controller + 0x14;\n\n\t/* Use GPIO port C.  */\n\tgpio_data_register = gpio_controller + 0x08;\n\tgpio_data_direction_register = gpio_controller + 0x18;\n\n\t/* Use GPIO port D.  */\n\tgpio_data_register = gpio_controller + 0x0c;\n\tgpio_data_direction_register = gpio_controller + 0x1c;\n#endif\n\n\t/* Use GPIO port C.  */\n\tgpio_data_register = gpio_controller + 0x08;\n\tgpio_data_direction_register = gpio_controller + 0x18;\n\n\tLOG_INFO(\"gpio_data_register      = %p\", gpio_data_register);\n\tLOG_INFO(\"gpio_data_direction_reg = %p\", gpio_data_direction_register);\n\t/*\n\t * Configure bit 0 (TDO) as an input, and bits 1-5 (TDI, TCK\n\t * TMS, TRST, SRST) as outputs.  Drive TDI and TCK low, and\n\t * TMS/TRST/SRST high.\n\t */\n\toutput_value = TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;\n\t*gpio_data_register = output_value;\n\tnanosleep(&ep93xx_zzzz, NULL);\n\n\t/*\n\t * Configure the direction register.  1 = output, 0 = input.\n\t */\n\t*gpio_data_direction_register =\n\t\tTDI_BIT | TCK_BIT | TMS_BIT | TRST_BIT | SRST_BIT | VCC_BIT;\n\n\tnanosleep(&ep93xx_zzzz, NULL);\n\treturn ERROR_OK;\n}\n\nstatic int ep93xx_quit(void)\n{\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/esp_usb_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Espressif USB to Jtag adapter                                         *\n *   Copyright (C) 2020 Espressif Systems (Shanghai) Co. Ltd.              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <helper/time_support.h>\n#include <helper/bits.h>\n#include \"bitq.h\"\n#include \"libusb_helper.h\"\n\n/*\nHoly Crap, it's protocol documentation, and it's even vendor-provided!\n\nA device that speaks this protocol has two endpoints intended for JTAG debugging: one\nOUT for the host to send encoded commands to, one IN from which the host can read any read\nTDO bits. The device will also respond to vendor-defined interface requests on ep0.\n\nThe main communication method is over the IN/OUT endpoints. The commands that are expected\non the OUT endpoint are one nibble wide and are processed high-nibble-first, low-nibble-second,\nand in the order the bytes come in. Commands are defined as follows:\n\n    bit     3   2    1    0\nCMD_CLK   [ 0   cap  tdi  tms  ]\nCMD_RST   [ 1   0    0    srst ]\nCMD_FLUSH [ 1   0    1    0    ]\nCMD_RSV   [ 1   0    1    1    ]\nCMD_REP   [ 1   1    R1   R0   ]\n\nCMD_CLK sets the TDI and TMS lines to the value of `tdi` and `tms` and lowers, then raises, TCK. If\n`cap` is 1, the value of TDO is captured and can be retrieved over the IN endpoint. The bytes read from\nthe IN endpoint specifically are these bits, with the lowest it in every byte captured first and the\nbytes returned in the order the data in them was captured. The durations of TCK being high / low can\nbe set using the VEND_JTAG_SETDIV vendor-specific interface request.\n\nCMD_RST controls the SRST line; as soon as the command is processed, the SRST line will be set\nto the value of `srst`.\n\nCMD_FLUSH flushes the IN endpoint; zeroes will be added to the amount of bits in the endpoint until\nthe payload is a multiple of bytes, and the data is offered to the host. If the IN endpoint has\nno data, this effectively becomes a no-op; the endpoint won't send any 0-byte payloads.\n\nCMD_RSV is reserved for future use.\n\nCMD_REP repeats the last command that is not CMD_REP. The amount of times a CMD_REP command will\nre-execute this command is (r1*2+r0)<<(2*n), where n is the amount of previous repeat commands executed\nsince the command to be repeated.\n\nAn example for CMD_REP: Say the host queues:\n1. CMD_CLK - This will execute one CMD_CLK.\n2. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*0)=1 time.\n3. CMD_REP with r1=1 and r0=0 - This will execute 1. another (1*2+0)<<(2*1)=4 times.\n4. CMD_REP with r1=0 and r0=1 - This will execute 1. another (0*2+1)<<(2*2)=8 time.\n5. CMD_FLUSH - This will flush the IN pipeline.\n6. CMD_CLK - This will execute one CMD_CLK\n7. CMD_REP with r1=1 and r0=0 - This will execute 6. another (1*2+0)<<(2*0)=2 times.\n8. CMD_FLUSH - This will flush the IN pipeline.\n\nNote that the net effect of the repetitions is that command 1 is executed (1+1+4+8=) 14 times and\ncommand 6 is executed (1+2=) 3 times.\n\nNote that the device only has a fairly limited amount of endpoint RAM. It's probably best to keep\nan eye on the amount of bytes that are supposed to be in the IN endpoint and grab those before stuffing\nmore commands into the OUT endpoint: the OUT endpoint will not accept any more commands (writes will\ntime out) when the IN endpoint buffers are all filled up.\n\nThe device also supports some vendor-specific interface requests. These requests are sent as control\ntransfers on endpoint 0 to the JTAG endpoint. Note that these commands bypass the data in the OUT\nendpoint; if timing is important, it's important that this endpoint is empty. This can be done by\ne.g sending one CMD_CLK capturing TDI, then one CMD_FLUSH, then waiting until the bit appears on the\nIN endpoint.\n\nbmRequestType bRequest         wValue   wIndex    wLength Data\n01000000b     VEND_JTAG_SETDIV [divide] interface 0       None\n01000000b     VEND_JTAG_SETIO  [iobits] interface 0       None\n11000000b     VEND_JTAG_GETTDO  0       interface 1       [iostate]\n10000000b     GET_DESCRIPTOR(6) 0x2000  0         256     [jtag cap desc]\n\nVEND_JTAG_SETDIV indirectly controls the speed of the TCK clock. The value written here is the length\nof a TCK cycle, in ticks of the adapters base clock. Both the base clock value as well as the\nminimum and maximum divider can be read from the jtag capabilities descriptor, as explained\nbelow. Note that this should not be set to a value outside of the range described there,\notherwise results are undefined.\n\nVEND_JTAG_SETIO can be controlled to directly set the IO pins. The format of [iobits] normally is\n{11'b0, srst, trst, tck, tms, tdi}\nNote that the first 11 0 bits are reserved for future use, current hardware ignores them.\n\nVEND_JTAG_GETTDO returns one byte, of which bit 0 indicates the current state of the TDO input.\nNote that other bits are reserved for future use and should be ignored.\n\nTo describe the capabilities of the JTAG adapter, a specific descriptor (0x20) can be retrieved.\nThe format of the descriptor documented below. The descriptor works in the same fashion as USB\ndescriptors: a header indicating the version and total length followed by descriptors with a\nspecific type and size. Forward compatibility is guaranteed as software can skip over an unknown\ndescriptor.\n\n*/\n\n#define JTAG_PROTO_CAPS_VER 1\t/* Version field. At the moment, only version 1 is defined. */\nstruct jtag_proto_caps_hdr {\n\tuint8_t proto_ver;\t/* Protocol version. Expects JTAG_PROTO_CAPS_VER for now. */\n\tuint8_t length;\t/* of this plus any following descriptors */\n} __attribute__((packed));\n\n/* start of the descriptor headers */\n#define JTAG_BUILTIN_DESCR_START_OFF            0\t/* Devices with builtin usb jtag */\n/*\n* ESP USB Bridge https://github.com/espressif/esp-usb-bridge uses string descriptor.\n* Skip 1 byte length and 1 byte descriptor type\n*/\n#define JTAG_EUB_DESCR_START_OFF                2\t/* ESP USB Bridge */\n\n/*\nNote: At the moment, there is only a speed_caps version indicating the base speed of the JTAG\nhardware is derived from the APB bus speed of the SoC. If later on, there are standalone\nconverters using the protocol, we should define e.g. JTAG_PROTO_CAPS_SPEED_FIXED_TYPE to distinguish\nbetween the two.\n\nNote: If the JTAG device has larger buffers than endpoint-size-plus-a-bit, we should have some kind\nof caps header to assume this. If no such caps exist, assume a minimum (in) buffer of endpoint size + 4.\n*/\n\nstruct jtag_gen_hdr {\n\tuint8_t type;\n\tuint8_t length;\n} __attribute__((packed));\n\nstruct jtag_proto_caps_speed_apb {\n\tuint8_t type;\t\t\t\t\t/* Type, always JTAG_PROTO_CAPS_SPEED_APB_TYPE */\n\tuint8_t length;\t\t\t\t\t/* Length of this */\n\tuint8_t apb_speed_10khz[2];\t\t/* ABP bus speed, in 10KHz increments. Base speed is half this. */\n\tuint8_t div_min[2];\t\t\t\t/* minimum divisor (to base speed), inclusive */\n\tuint8_t div_max[2];\t\t\t\t/* maximum divisor (to base speed), inclusive */\n} __attribute__((packed));\n\n#define JTAG_PROTO_CAPS_DATA_LEN                255\n#define JTAG_PROTO_CAPS_SPEED_APB_TYPE          1\n\n#define VEND_DESCR_BUILTIN_JTAG_CAPS            0x2000\n\n#define VEND_JTAG_SETDIV        0\n#define VEND_JTAG_SETIO         1\n#define VEND_JTAG_GETTDO        2\n#define VEND_JTAG_SET_CHIPID    3\n\n#define VEND_JTAG_SETIO_TDI     BIT(0)\n#define VEND_JTAG_SETIO_TMS     BIT(1)\n#define VEND_JTAG_SETIO_TCK     BIT(2)\n#define VEND_JTAG_SETIO_TRST    BIT(3)\n#define VEND_JTAG_SETIO_SRST    BIT(4)\n\n#define CMD_CLK(cap, tdi, tms) ((cap ? BIT(2) : 0) | (tms ? BIT(1) : 0) | (tdi ? BIT(0) : 0))\n#define CMD_RST(srst)   (0x8 | (srst ? BIT(0) : 0))\n#define CMD_FLUSH       0xA\n#define CMD_RSVD        0xB\n#define CMD_REP(r)      (0xC + ((r) & 3))\n\n/* The internal repeats register is 10 bits, which means we can have 5 repeat commands in a\n *row at max. This translates to ('b1111111111+1=)1024 reps max. */\n#define CMD_REP_MAX_REPS 1024\n\n/* Currently we only support one USB device. */\n#define USB_CONFIGURATION 0\n\n/* Buffer size; is equal to the endpoint size. In bytes\n * TODO for future adapters: read from device configuration? */\n#define OUT_EP_SZ 64\n/* Out data can be buffered for longer without issues (as long as the in buffer does not overflow),\n * so we'll use an out buffer that is much larger than the out ep size. */\n#define OUT_BUF_SZ (OUT_EP_SZ * 32)\n/* The in buffer cannot be larger than the device can offer, though. */\n#define IN_BUF_SZ 64\n\n/* Because a series of out commands can lead to a multitude of IN_BUF_SZ-sized in packets\n *to be read, we have multiple buffers to store those before the bitq interface reads them out. */\n#define IN_BUF_CT 8\n\n#define ESP_USB_INTERFACE       1\n\n/* Private data */\nstruct esp_usb_jtag {\n\tstruct libusb_device_handle *usb_device;\n\tuint32_t base_speed_khz;\n\tuint16_t div_min;\n\tuint16_t div_max;\n\tuint8_t out_buf[OUT_BUF_SZ];\n\tunsigned int out_buf_pos_nibbles;\t\t\t/* write position in out_buf */\n\n\tuint8_t in_buf[IN_BUF_CT][IN_BUF_SZ];\n\tunsigned int in_buf_size_bits[IN_BUF_CT];\t/* size in bits of the data stored in an in_buf */\n\tunsigned int cur_in_buf_rd, cur_in_buf_wr;\t/* read/write index */\n\tunsigned int in_buf_pos_bits;\t/* which bit in the in buf needs to be returned to bitq next */\n\n\tunsigned int read_ep;\n\tunsigned int write_ep;\n\n\tunsigned int prev_cmd;\t\t/* previous command, stored here for RLEing. */\n\tint prev_cmd_repct;\t\t\t/* Amount of repetitions of that command we have seen until now */\n\n\t/* This is the total number of in bits we need to read, including in unsent commands */\n\tunsigned int pending_in_bits;\n\n\tunsigned int hw_in_fifo_len;\n\n\tstruct bitq_interface bitq_interface;\n};\n\n/* For now, we only use one static private struct. Technically, we can re-work this, but I don't think\n * OpenOCD supports multiple JTAG adapters anyway. */\nstatic struct esp_usb_jtag esp_usb_jtag_priv;\nstatic struct esp_usb_jtag *priv = &esp_usb_jtag_priv;\n\nstatic int esp_usb_vid;\nstatic int esp_usb_pid;\nstatic int esp_usb_jtag_caps;\nstatic int esp_usb_target_chip_id;\n\nstatic int esp_usb_jtag_init(void);\nstatic int esp_usb_jtag_quit(void);\n\n/* Try to receive from USB endpoint into the current priv->in_buf */\nstatic int esp_usb_jtag_recv_buf(void)\n{\n\tif (priv->in_buf_size_bits[priv->cur_in_buf_wr] != 0)\n\t\tLOG_ERROR(\"esp_usb_jtag: IN buffer overflow! (%d, size %d)\",\n\t\t\tpriv->cur_in_buf_wr,\n\t\t\tpriv->in_buf_size_bits[priv->cur_in_buf_wr]);\n\n\tunsigned int recvd = 0, ct = (priv->pending_in_bits + 7) / 8;\n\tif (ct > IN_BUF_SZ)\n\t\tct = IN_BUF_SZ;\n\tif (ct == 0) {\n\t\t/* Note that the adapters IN EP specifically does *not* usually generate 0-byte in\n\t\t * packets if there has been no data since the last flush.\n\t\t * As such, we don't need (and shouldn't) try to read it. */\n\t\treturn ERROR_OK;\n\t}\n\n\tpriv->in_buf_size_bits[priv->cur_in_buf_wr] = 0;\n\twhile (recvd < ct) {\n\t\tunsigned int tr;\n\t\tint ret = jtag_libusb_bulk_read(priv->usb_device,\n\t\t\tpriv->read_ep,\n\t\t\t(char *)priv->in_buf[priv->cur_in_buf_wr] + recvd,\n\t\t\tct,\n\t\t\tLIBUSB_TIMEOUT_MS,\t/*ms*/\n\t\t\t(int *)&tr);\n\t\tif (ret != ERROR_OK || tr == 0) {\n\t\t\t/* Sometimes the hardware returns 0 bytes instead of NAKking the transaction. Ignore this. */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (tr != ct) {\n\t\t\t/* Huh, short read? */\n\t\t\tLOG_DEBUG(\"esp_usb_jtag: usb received only %d out of %d bytes.\", tr, ct);\n\t\t}\n\t\t/* Adjust the amount of bits we still expect to read from the USB device after this. */\n\t\tunsigned int bits_in_buf = priv->pending_in_bits;\t/* initially assume we read\n\t\t\t\t\t\t\t\t\t* everything that was pending */\n\t\tif (bits_in_buf > tr * 8)\n\t\t\tbits_in_buf = tr * 8;\t/* ...but correct that if that was not the case. */\n\t\tpriv->pending_in_bits -= bits_in_buf;\n\t\tpriv->in_buf_size_bits[priv->cur_in_buf_wr] += bits_in_buf;\n\t\trecvd += tr;\n\t}\n\t/* next in buffer for the next time. */\n\tpriv->cur_in_buf_wr++;\n\tif (priv->cur_in_buf_wr == IN_BUF_CT)\n\t\tpriv->cur_in_buf_wr = 0;\n\tLOG_DEBUG_IO(\"esp_usb_jtag: In ep: received %d bytes; %d bytes (%d bits) left.\", recvd,\n\t\t(priv->pending_in_bits + 7) / 8, priv->pending_in_bits);\n\treturn ERROR_OK;\n}\n\n/* Sends priv->out_buf to the USB device. */\nstatic int esp_usb_jtag_send_buf(void)\n{\n\tunsigned int ct = priv->out_buf_pos_nibbles / 2;\n\tunsigned int written = 0;\n\n\twhile (written < ct) {\n\t\tint tr = 0, ret = jtag_libusb_bulk_write(priv->usb_device,\n\t\t\tpriv->write_ep,\n\t\t\t(char *)priv->out_buf + written,\n\t\t\tct - written,\n\t\t\tLIBUSB_TIMEOUT_MS,\t/*ms*/\n\t\t\t&tr);\n\t\tLOG_DEBUG_IO(\"esp_usb_jtag: sent %d bytes.\", tr);\n\t\tif (written + tr != ct) {\n\t\t\tLOG_DEBUG(\"esp_usb_jtag: usb sent only %d out of %d bytes.\",\n\t\t\t\twritten + tr,\n\t\t\t\tct);\n\t\t}\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\twritten += tr;\n\t}\n\tpriv->out_buf_pos_nibbles = 0;\n\n\t/* If there's more than a bufferful of data queuing up in the jtag adapters IN endpoint, empty\n\t * all but one buffer. */\n\twhile (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8)\n\t\tesp_usb_jtag_recv_buf();\n\n\treturn ERROR_OK;\n}\n\n/* Simply adds a command to the buffer. Is called by the RLE encoding mechanism.\n *Also sends the intermediate buffer if there's enough to go into one USB packet. */\nstatic int esp_usb_jtag_command_add_raw(unsigned int cmd)\n{\n\tint ret = ERROR_OK;\n\n\tif ((priv->out_buf_pos_nibbles & 1) == 0)\n\t\tpriv->out_buf[priv->out_buf_pos_nibbles / 2] = (cmd << 4);\n\telse\n\t\tpriv->out_buf[priv->out_buf_pos_nibbles / 2] |= cmd;\n\tpriv->out_buf_pos_nibbles++;\n\n\tif (priv->out_buf_pos_nibbles == OUT_BUF_SZ * 2)\n\t\tret = esp_usb_jtag_send_buf();\n\tif (ret == ERROR_OK && priv->out_buf_pos_nibbles % (OUT_EP_SZ * 2) == 0) {\n\t\tif (priv->pending_in_bits > (IN_BUF_SZ + priv->hw_in_fifo_len - 1) * 8)\n\t\t\tret = esp_usb_jtag_send_buf();\n\t}\n\treturn ret;\n}\n\n/* Writes a command stream equivalent to writing `cmd` `ct` times. */\nstatic int esp_usb_jtag_write_rlestream(unsigned int cmd, int ct)\n{\n\t/* Special case: stacking flush commands does not make sense (and may not make the hardware very happy) */\n\tif (cmd == CMD_FLUSH)\n\t\tct = 1;\n\t/* Output previous command and repeat commands */\n\tint ret = esp_usb_jtag_command_add_raw(cmd);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tct--;\t/* as the previous line already executes the command one time */\n\twhile (ct > 0) {\n\t\tret = esp_usb_jtag_command_add_raw(CMD_REP(ct & 3));\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\tct >>= 2;\n\t}\n\treturn ERROR_OK;\n}\n\n/* Adds a command to the buffer of things to be sent. Transparently handles RLE compression using\n * the CMD_REP_x commands */\nstatic int esp_usb_jtag_command_add(unsigned int cmd)\n{\n\tif (cmd == priv->prev_cmd && priv->prev_cmd_repct < CMD_REP_MAX_REPS) {\n\t\tpriv->prev_cmd_repct++;\n\t} else {\n\t\t/* We can now write out the previous command plus repeat count. */\n\t\tif (priv->prev_cmd_repct) {\n\t\t\tint ret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\t/* Ready for new command. */\n\t\tpriv->prev_cmd = cmd;\n\t\tpriv->prev_cmd_repct = 1;\n\t}\n\treturn ERROR_OK;\n}\n\n/* Called by bitq interface to output a bit on tdi and perhaps read a bit from tdo */\nstatic int esp_usb_jtag_out(int tms, int tdi, int tdo_req)\n{\n\tint ret = esp_usb_jtag_command_add(CMD_CLK(tdo_req, tdi, tms));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tif (tdo_req)\n\t\tpriv->pending_in_bits++;\n\treturn ERROR_OK;\n}\n\n/* Called by bitq interface to flush all output commands and get returned data ready to read */\nstatic int esp_usb_jtag_flush(void)\n{\n\tint ret;\n\t/*Make sure last command is written */\n\tif (priv->prev_cmd_repct) {\n\t\tret = esp_usb_jtag_write_rlestream(priv->prev_cmd, priv->prev_cmd_repct);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\tpriv->prev_cmd_repct = 0;\n\t/* Flush in buffer */\n\tret = esp_usb_jtag_command_add_raw(CMD_FLUSH);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\t/* Make sure we have an even amount of commands, as we can't write a nibble by itself. */\n\tif (priv->out_buf_pos_nibbles & 1) {\n\t\t/*If not, pad with an extra FLUSH */\n\t\tret = esp_usb_jtag_command_add_raw(CMD_FLUSH);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\tLOG_DEBUG_IO(\"esp_usb_jtag: Flush!\");\n\t/* Send off the buffer. */\n\tret = esp_usb_jtag_send_buf();\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Immediately fetch the response bits. */\n\twhile (priv->pending_in_bits > 0)\n\t\tesp_usb_jtag_recv_buf();\n\n\treturn ERROR_OK;\n}\n\n/* Called by bitq interface to sleep for a determined amount of time */\nstatic int esp_usb_jtag_sleep(unsigned long us)\n{\n\tesp_usb_jtag_flush();\n\t/* TODO: we can sleep more precisely (for small amounts of sleep at least) by sending dummy\n\t * commands to the adapter. */\n\tjtag_sleep(us);\n\treturn 0;\n}\n\n/* Called by the bitq interface to set the various resets */\nstatic int esp_usb_jtag_reset(int trst, int srst)\n{\n\t/* TODO: handle trst using setup commands. Kind-of superfluous, however, as we can also do\n\t * a tap reset using tms, and it's also not implemented on other ESP32 chips with external JTAG. */\n\treturn esp_usb_jtag_command_add(CMD_RST(srst));\n}\n\n/* Called by bitq to see if the IN data already is returned to the host. */\nstatic int esp_usb_jtag_in_rdy(void)\n{\n\t/* We read all bits in the flush() routine, so if we're here, we have bits or are at EOF. */\n\treturn 1;\n}\n\n/* Read one bit from the IN data */\nstatic int esp_usb_jtag_in(void)\n{\n\tif (!esp_usb_jtag_in_rdy()) {\n\t\tLOG_ERROR(\"esp_usb_jtag: Eeek! bitq asked us for in data while not ready!\");\n\t\treturn -1;\n\t}\n\tif (priv->cur_in_buf_rd == priv->cur_in_buf_wr &&\n\t\tpriv->in_buf_size_bits[priv->cur_in_buf_rd] == 0)\n\t\treturn -1;\n\n\t/* Extract the bit */\n\tint r = (priv->in_buf[priv->cur_in_buf_rd][priv->in_buf_pos_bits / 8] &\n\t\tBIT(priv->in_buf_pos_bits & 7)) ? 1 : 0;\n\t/* Move to next bit. */\n\tpriv->in_buf_pos_bits++;\n\tif (priv->in_buf_pos_bits == priv->in_buf_size_bits[priv->cur_in_buf_rd]) {\n\t\t/* No more bits in this buffer; mark as re-usable and move to next buffer. */\n\t\tpriv->in_buf_pos_bits = 0;\n\t\tpriv->in_buf_size_bits[priv->cur_in_buf_rd] = 0;/*indicate it is free again */\n\t\tpriv->cur_in_buf_rd++;\n\t\tif (priv->cur_in_buf_rd == IN_BUF_CT)\n\t\t\tpriv->cur_in_buf_rd = 0;\n\t}\n\treturn r;\n}\n\nstatic int esp_usb_jtag_init(void)\n{\n\tmemset(priv, 0, sizeof(struct esp_usb_jtag));\n\n\tconst uint16_t vids[] = { esp_usb_vid, 0 };\t\t/* must be null terminated */\n\tconst uint16_t pids[] = { esp_usb_pid, 0 };\t\t/* must be null terminated */\n\n\tbitq_interface = &priv->bitq_interface;\n\tbitq_interface->out = esp_usb_jtag_out;\n\tbitq_interface->flush = esp_usb_jtag_flush;\n\tbitq_interface->sleep = esp_usb_jtag_sleep;\n\tbitq_interface->reset = esp_usb_jtag_reset;\n\tbitq_interface->in_rdy = esp_usb_jtag_in_rdy;\n\tbitq_interface->in = esp_usb_jtag_in;\n\n\tint r = jtag_libusb_open(vids, pids, &priv->usb_device, NULL);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"esp_usb_jtag: could not find or open device!\");\n\t\tgoto out;\n\t}\n\n\tjtag_libusb_set_configuration(priv->usb_device, USB_CONFIGURATION);\n\n\tr = jtag_libusb_choose_interface(priv->usb_device, &priv->read_ep, &priv->write_ep,\n\t\tLIBUSB_CLASS_VENDOR_SPEC, LIBUSB_CLASS_VENDOR_SPEC, ESP_USB_INTERFACE, LIBUSB_TRANSFER_TYPE_BULK);\n\tif (r != ERROR_OK) {\n\t\tLOG_ERROR(\"esp_usb_jtag: error finding/claiming JTAG interface on device!\");\n\t\tgoto out;\n\t}\n\n\t/* TODO: This is not proper way to get caps data. Two requests can be done.\n\t * 1- With the minimum size required to get to know the total length of that struct,\n\t * 2- Then exactly the length of that struct. */\n\tuint8_t jtag_caps_desc[JTAG_PROTO_CAPS_DATA_LEN];\n\tint jtag_caps_read_len = jtag_libusb_control_transfer(priv->usb_device,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE,\n\t\tLIBUSB_REQUEST_GET_DESCRIPTOR, esp_usb_jtag_caps, 0,\n\t\t(char *)jtag_caps_desc, JTAG_PROTO_CAPS_DATA_LEN, LIBUSB_TIMEOUT_MS);\n\tif (jtag_caps_read_len <= 0) {\n\t\tLOG_ERROR(\"esp_usb_jtag: could not retrieve jtag_caps descriptor!\");\n\t\tgoto out;\n\t}\n\n\t/* defaults for values we normally get from the jtag caps descriptor */\n\tpriv->base_speed_khz = UINT32_MAX;\n\tpriv->div_min = 1;\n\tpriv->div_max = 1;\n\n\tint p = esp_usb_jtag_caps ==\n\t\tVEND_DESCR_BUILTIN_JTAG_CAPS ? JTAG_BUILTIN_DESCR_START_OFF : JTAG_EUB_DESCR_START_OFF;\n\n\tif (p + sizeof(struct jtag_proto_caps_hdr) > (unsigned int)jtag_caps_read_len) {\n\t\tLOG_ERROR(\"esp_usb_jtag: not enough data to get header\");\n\t\tgoto out;\n\t}\n\n\tstruct jtag_proto_caps_hdr *hdr = (struct jtag_proto_caps_hdr *)&jtag_caps_desc[p];\n\tif (hdr->proto_ver != JTAG_PROTO_CAPS_VER) {\n\t\tLOG_ERROR(\"esp_usb_jtag: unknown jtag_caps descriptor version 0x%X!\",\n\t\t\thdr->proto_ver);\n\t\tgoto out;\n\t}\n\tif (hdr->length > jtag_caps_read_len) {\n\t\tLOG_ERROR(\"esp_usb_jtag: header length (%d) bigger then max read bytes (%d)\",\n\t\t\thdr->length, jtag_caps_read_len);\n\t\tgoto out;\n\t}\n\n\tp += sizeof(struct jtag_proto_caps_hdr);\n\n\twhile (p + sizeof(struct jtag_gen_hdr) < hdr->length) {\n\t\tstruct jtag_gen_hdr *dhdr = (struct jtag_gen_hdr *)&jtag_caps_desc[p];\n\t\tif (dhdr->type == JTAG_PROTO_CAPS_SPEED_APB_TYPE) {\n\t\t\tif (p + sizeof(struct jtag_proto_caps_speed_apb) < hdr->length) {\n\t\t\t\tLOG_ERROR(\"esp_usb_jtag: not enough data to get caps speed\");\n\t\t\t\tgoto out;\n\t\t\t}\n\t\t\tstruct jtag_proto_caps_speed_apb *spcap = (struct jtag_proto_caps_speed_apb *)dhdr;\n\t\t\t/* base speed always is half APB speed */\n\t\t\tpriv->base_speed_khz = le_to_h_u16(spcap->apb_speed_10khz) * 10 / 2;\n\t\t\tpriv->div_min = le_to_h_u16(spcap->div_min);\n\t\t\tpriv->div_max = le_to_h_u16(spcap->div_max);\n\t\t\t/* TODO: mark in priv that this is apb-derived and as such may change if apb\n\t\t\t * ever changes? */\n\t\t} else {\n\t\t\tLOG_WARNING(\"esp_usb_jtag: unknown caps type 0x%X\", dhdr->type);\n\t\t}\n\t\tp += dhdr->length;\n\t}\n\tif (priv->base_speed_khz == UINT32_MAX) {\n\t\tLOG_WARNING(\"esp_usb_jtag: No speed caps found... using sane-ish defaults.\");\n\t\tpriv->base_speed_khz = 1000;\n\t}\n\tLOG_INFO(\"esp_usb_jtag: Device found. Base speed %dKHz, div range %d to %d\",\n\t\tpriv->base_speed_khz, priv->div_min, priv->div_max);\n\n\t/* TODO: grab from (future) descriptor if we ever have a device with larger IN buffers */\n\tpriv->hw_in_fifo_len = 4;\n\n\t/* inform bridge board about the connected target chip for the specific operations\n\t * it is also safe to send this info to chips that have builtin usb jtag */\n\tjtag_libusb_control_transfer(priv->usb_device,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR,\n\t\tVEND_JTAG_SET_CHIPID,\n\t\tesp_usb_target_chip_id,\n\t\t0,\n\t\tNULL,\n\t\t0,\n\t\tLIBUSB_TIMEOUT_MS);\n\n\treturn ERROR_OK;\n\nout:\n\tif (priv->usb_device)\n\t\tjtag_libusb_close(priv->usb_device);\n\tbitq_interface = NULL;\n\tpriv->usb_device = NULL;\n\treturn ERROR_FAIL;\n}\n\nstatic int esp_usb_jtag_quit(void)\n{\n\tif (!priv->usb_device)\n\t\treturn ERROR_OK;\n\tjtag_libusb_close(priv->usb_device);\n\tbitq_cleanup();\n\tbitq_interface = NULL;\n\treturn ERROR_OK;\n}\n\nstatic int esp_usb_jtag_speed_div(int divisor, int *khz)\n{\n\t*khz = priv->base_speed_khz / divisor;\n\treturn ERROR_OK;\n}\n\nstatic int esp_usb_jtag_khz(int khz, int *divisor)\n{\n\tif (khz == 0) {\n\t\tLOG_WARNING(\"esp_usb_jtag: RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*divisor = priv->base_speed_khz / khz;\n\tLOG_DEBUG(\"Divisor for %d KHz with base clock of %d khz is %d\",\n\t\tkhz,\n\t\tpriv->base_speed_khz,\n\t\t*divisor);\n\tif (*divisor < priv->div_min)\n\t\t*divisor = priv->div_min;\n\tif (*divisor > priv->div_max)\n\t\t*divisor = priv->div_max;\n\n\treturn ERROR_OK;\n}\n\nstatic int esp_usb_jtag_speed(int divisor)\n{\n\tif (divisor == 0) {\n\t\tLOG_ERROR(\"esp_usb_jtag: Adaptive clocking is not supported.\");\n\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\t}\n\n\tLOG_DEBUG(\"esp_usb_jtag: setting divisor %d\", divisor);\n\tjtag_libusb_control_transfer(priv->usb_device,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_SETDIV, divisor, 0, NULL, 0, LIBUSB_TIMEOUT_MS);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_usb_jtag_tdo_cmd)\n{\n\tchar tdo;\n\tif (!priv->usb_device)\n\t\treturn ERROR_FAIL;\n\tint r = jtag_libusb_control_transfer(priv->usb_device,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR, VEND_JTAG_GETTDO, 0, 0, &tdo, 1, LIBUSB_TIMEOUT_MS);\n\tif (r < 1)\n\t\treturn r;\n\n\tcommand_print(CMD, \"%d\", tdo);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_usb_jtag_setio_cmd)\n{\n\tuint32_t tdi, tms, tck, trst, srst;\n\tuint16_t d = 0;\n\n\tif (!priv->usb_device)\n\t\treturn ERROR_FAIL;\n\n\tif (CMD_ARGC != 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tdi);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], tms);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], tck);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], trst);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], srst);\n\tif (tdi)\n\t\td |= VEND_JTAG_SETIO_TDI;\n\tif (tms)\n\t\td |= VEND_JTAG_SETIO_TMS;\n\tif (tck)\n\t\td |= VEND_JTAG_SETIO_TCK;\n\tif (trst)\n\t\td |= VEND_JTAG_SETIO_TRST;\n\tif (srst)\n\t\td |= VEND_JTAG_SETIO_SRST;\n\n\tjtag_libusb_control_transfer(priv->usb_device,\n\t\t0x40, VEND_JTAG_SETIO, d, 0, NULL, 0, LIBUSB_TIMEOUT_MS);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_usb_jtag_vid_pid)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_vid);\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], esp_usb_pid);\n\tLOG_INFO(\"esp_usb_jtag: VID set to 0x%x and PID to 0x%x\", esp_usb_vid, esp_usb_pid);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_usb_jtag_caps_descriptor)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_jtag_caps);\n\tLOG_INFO(\"esp_usb_jtag: capabilities descriptor set to 0x%x\", esp_usb_jtag_caps);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_usb_jtag_chip_id)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], esp_usb_target_chip_id);\n\tLOG_INFO(\"esp_usb_jtag: target chip id set to %d\", esp_usb_target_chip_id);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration esp_usb_jtag_subcommands[] = {\n\t{\n\t\t.name = \"tdo\",\n\t\t.handler = &esp_usb_jtag_tdo_cmd,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Returns the current state of the TDO line\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"setio\",\n\t\t.handler = &esp_usb_jtag_setio_cmd,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Manually set the status of the output lines\",\n\t\t.usage = \"tdi tms tck trst srst\"\n\t},\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = &esp_usb_jtag_vid_pid,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set vendor ID and product ID for ESP usb jtag driver\",\n\t\t.usage = \"vid pid\",\n\t},\n\t{\n\t\t.name = \"caps_descriptor\",\n\t\t.handler = &esp_usb_jtag_caps_descriptor,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set jtag descriptor to read capabilities of ESP usb jtag driver\",\n\t\t.usage = \"descriptor\",\n\t},\n\t{\n\t\t.name = \"chip_id\",\n\t\t.handler = &esp_usb_jtag_chip_id,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set chip_id to transfer to the bridge\",\n\t\t.usage = \"chip_id\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esp_usb_jtag_commands[] = {\n\t{\n\t\t.name = \"espusbjtag\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ESP-USB-JTAG commands\",\n\t\t.chain = esp_usb_jtag_subcommands,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface esp_usb_jtag_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitq_execute_queue,\n};\n\nstruct adapter_driver esp_usb_adapter_driver = {\n\t.name = \"esp_usb_jtag\",\n\t.transports = jtag_only,\n\t.commands = esp_usb_jtag_commands,\n\n\t.init = esp_usb_jtag_init,\n\t.quit = esp_usb_jtag_quit,\n\t.speed_div = esp_usb_jtag_speed_div,\n\t.speed = esp_usb_jtag_speed,\n\t.khz = esp_usb_jtag_khz,\n\n\t.jtag_ops = &esp_usb_jtag_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ft232r.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 Serge Vakulenko                                    *\n *   serge@vak.ru                                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if IS_CYGWIN == 1\n#include \"windows.h\"\n#undef LOG_ERROR\n#endif\n\n/* project specific includes */\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <helper/time_support.h>\n#include \"libusb_helper.h\"\n\n/* system includes */\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/time.h>\n#include <time.h>\n\n/*\n * Sync bit bang mode is implemented as described in FTDI Application\n * Note AN232R-01: \"Bit Bang Modes for the FT232R and FT245R\".\n */\n\n/*\n * USB endpoints.\n */\n#define IN_EP\t\t\t0x02\n#define OUT_EP\t\t\t0x81\n\n/* Requests */\n#define SIO_RESET\t\t0 /* Reset the port */\n#define SIO_MODEM_CTRL\t\t1 /* Set the modem control register */\n#define SIO_SET_FLOW_CTRL\t2 /* Set flow control register */\n#define SIO_SET_BAUD_RATE\t3 /* Set baud rate */\n#define SIO_SET_DATA\t\t4 /* Set the data characteristics of the port */\n#define SIO_POLL_MODEM_STATUS\t5\n#define SIO_SET_EVENT_CHAR\t6\n#define SIO_SET_ERROR_CHAR\t7\n#define SIO_SET_LATENCY_TIMER\t9\n#define SIO_GET_LATENCY_TIMER\t10\n#define SIO_SET_BITMODE\t\t11\n#define SIO_READ_PINS\t\t12\n#define SIO_READ_EEPROM\t\t0x90\n#define SIO_WRITE_EEPROM\t0x91\n#define SIO_ERASE_EEPROM\t0x92\n\n#define FT232R_BUF_SIZE_EXTRA\t4096\n\nstatic uint16_t ft232r_vid = 0x0403; /* FTDI */\nstatic uint16_t ft232r_pid = 0x6001; /* FT232R */\nstatic struct libusb_device_handle *adapter;\n\nstatic uint8_t *ft232r_output;\nstatic size_t ft232r_output_len;\n\n/**\n * FT232R GPIO bit number to RS232 name\n */\n#define FT232R_BIT_COUNT 8\nstatic char *ft232r_bit_name_array[FT232R_BIT_COUNT] = {\n\t\"TXD\", /* 0: pin 1  TCK output */\n\t\"RXD\", /* 1: pin 5  TDI output */\n\t\"RTS\", /* 2: pin 3  TDO input */\n\t\"CTS\", /* 3: pin 11 TMS output */\n\t\"DTR\", /* 4: pin 2  /TRST output */\n\t\"DSR\", /* 5: pin 9  unused */\n\t\"DCD\", /* 6: pin 10 /SYSRST output */\n\t\"RI\"   /* 7: pin 6  unused */\n};\n\nstatic int tck_gpio; /* initialized to 0 by default */\nstatic int tdi_gpio = 1;\nstatic int tdo_gpio = 2;\nstatic int tms_gpio = 3;\nstatic int ntrst_gpio = 4;\nstatic int nsysrst_gpio = 6;\nstatic size_t ft232r_buf_size = FT232R_BUF_SIZE_EXTRA;\n/** 0xFFFF disables restore by default, after exit serial port will not work.\n *  0x15 sets TXD RTS DTR as outputs, after exit serial port will continue to work.\n */\nstatic uint16_t ft232r_restore_bitmode = 0xFFFF;\n\n/**\n * Perform sync bitbang output/input transaction.\n * Before call, an array ft232r_output[] should be filled with data to send.\n * Counter ft232r_output_len contains the number of bytes to send.\n * On return, received data is put back to array ft232r_output[].\n */\nstatic int ft232r_send_recv(void)\n{\n\t/* FIFO TX buffer has 128 bytes.\n\t * FIFO RX buffer has 256 bytes.\n\t * First two bytes of received packet contain contain modem\n\t * and line status and are ignored.\n\t * Unfortunately, transfer sizes bigger than 64 bytes\n\t * frequently cause hang ups. */\n\tassert(ft232r_output_len > 0);\n\n\tsize_t total_written = 0;\n\tsize_t total_read = 0;\n\tint rxfifo_free = 128;\n\n\twhile (total_read < ft232r_output_len) {\n\t\t/* Write */\n\t\tint bytes_to_write = ft232r_output_len - total_written;\n\t\tif (bytes_to_write > 64)\n\t\t\tbytes_to_write = 64;\n\t\tif (bytes_to_write > rxfifo_free)\n\t\t\tbytes_to_write = rxfifo_free;\n\n\t\tif (bytes_to_write) {\n\t\t\tint n;\n\n\t\t\tif (jtag_libusb_bulk_write(adapter, IN_EP,\n\t\t\t\t\t\t   (char *) ft232r_output + total_written,\n\t\t\t\t\t\t   bytes_to_write, 1000, &n) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"usb bulk write failed\");\n\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t}\n\n\t\t\ttotal_written += n;\n\t\t\trxfifo_free -= n;\n\t\t}\n\n\t\t/* Read */\n\t\tuint8_t reply[64];\n\t\tint n;\n\n\t\tif (jtag_libusb_bulk_read(adapter, OUT_EP, (char *) reply,\n\t\t\t\t\t  sizeof(reply), 1000, &n) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"usb bulk read failed\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\tif (n > 2) {\n\t\t\t/* Copy data, ignoring first 2 bytes. */\n\t\t\tmemcpy(ft232r_output + total_read, reply + 2, n - 2);\n\t\t\tint bytes_read = n - 2;\n\t\t\ttotal_read += bytes_read;\n\t\t\trxfifo_free += bytes_read;\n\t\t\tif (total_read > total_written) {\n\t\t\t\tLOG_ERROR(\"read more bytes than wrote\");\n\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t}\n\t\t}\n\t}\n\tft232r_output_len = 0;\n\treturn ERROR_OK;\n}\n\nstatic void ft232r_increase_buf_size(size_t new_buf_size)\n{\n\tuint8_t *new_buf_ptr;\n\tif (new_buf_size >= ft232r_buf_size) {\n\t\tnew_buf_size += FT232R_BUF_SIZE_EXTRA;\n\t\tnew_buf_ptr = realloc(ft232r_output, new_buf_size);\n\t\tif (new_buf_ptr) {\n\t\t\tft232r_output = new_buf_ptr;\n\t\t\tft232r_buf_size = new_buf_size;\n\t\t}\n\t}\n}\n\n/**\n * Add one TCK/TMS/TDI sample to send buffer.\n */\nstatic void ft232r_write(int tck, int tms, int tdi)\n{\n\tunsigned out_value = (1<<ntrst_gpio) | (1<<nsysrst_gpio);\n\tif (tck)\n\t\tout_value |= (1<<tck_gpio);\n\tif (tms)\n\t\tout_value |= (1<<tms_gpio);\n\tif (tdi)\n\t\tout_value |= (1<<tdi_gpio);\n\n\tft232r_increase_buf_size(ft232r_output_len);\n\n\tif (ft232r_output_len >= ft232r_buf_size) {\n\t\t/* FIXME: should we just execute queue here? */\n\t\tLOG_ERROR(\"ft232r_write: buffer overflow\");\n\t\treturn;\n\t}\n\tft232r_output[ft232r_output_len++] = out_value;\n}\n\n/**\n * Control /TRST and /SYSRST pins.\n * Perform immediate bitbang transaction.\n */\nstatic void ft232r_reset(int trst, int srst)\n{\n\tunsigned out_value = (1<<ntrst_gpio) | (1<<nsysrst_gpio);\n\tLOG_DEBUG(\"ft232r_reset(%d,%d)\", trst, srst);\n\n\tif (trst == 1)\n\t\tout_value &= ~(1<<ntrst_gpio);\t\t/* switch /TRST low */\n\telse if (trst == 0)\n\t\tout_value |= (1<<ntrst_gpio);\t\t\t/* switch /TRST high */\n\n\tif (srst == 1)\n\t\tout_value &= ~(1<<nsysrst_gpio);\t\t/* switch /SYSRST low */\n\telse if (srst == 0)\n\t\tout_value |= (1<<nsysrst_gpio);\t\t/* switch /SYSRST high */\n\n\tft232r_increase_buf_size(ft232r_output_len);\n\n\tif (ft232r_output_len >= ft232r_buf_size) {\n\t\t/* FIXME: should we just execute queue here? */\n\t\tLOG_ERROR(\"ft232r_write: buffer overflow\");\n\t\treturn;\n\t}\n\n\tft232r_output[ft232r_output_len++] = out_value;\n\tft232r_send_recv();\n}\n\nstatic int ft232r_speed(int divisor)\n{\n\tint baud = (divisor == 0) ? 3000000 :\n\t\t(divisor == 1) ? 2000000 :\n\t\t3000000 / divisor;\n\tLOG_DEBUG(\"ft232r_speed(%d) rate %d bits/sec\", divisor, baud);\n\n\tif (jtag_libusb_control_transfer(adapter,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\tSIO_SET_BAUD_RATE, divisor, 0, NULL, 0, 1000) != 0) {\n\t\tLOG_ERROR(\"cannot set baud rate\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ft232r_init(void)\n{\n\tuint16_t avids[] = {ft232r_vid, 0};\n\tuint16_t apids[] = {ft232r_pid, 0};\n\tif (jtag_libusb_open(avids, apids, &adapter, NULL)) {\n\t\tconst char *ft232r_serial_desc = adapter_get_required_serial();\n\t\tLOG_ERROR(\"ft232r not found: vid=%04x, pid=%04x, serial=%s\\n\",\n\t\t\tft232r_vid, ft232r_pid, (!ft232r_serial_desc) ? \"[any]\" : ft232r_serial_desc);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ft232r_restore_bitmode == 0xFFFF) /* serial port will not be restored after jtag: */\n\t\tlibusb_detach_kernel_driver(adapter, 0);\n\telse /* serial port will be restored after jtag: */\n\t\tlibusb_set_auto_detach_kernel_driver(adapter, 1); /* 1: DONT_DETACH_SIO_MODULE */\n\n\tif (libusb_claim_interface(adapter, 0)) {\n\t\tLOG_ERROR(\"unable to claim interface\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* Reset the device. */\n\tif (jtag_libusb_control_transfer(adapter,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\tSIO_RESET, 0, 0, NULL, 0, 1000) != 0) {\n\t\tLOG_ERROR(\"unable to reset device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* Sync bit bang mode. */\n\tif (jtag_libusb_control_transfer(adapter,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\tSIO_SET_BITMODE, (1<<tck_gpio) | (1<<tdi_gpio) | (1<<tms_gpio) | (1<<ntrst_gpio) | (1<<nsysrst_gpio) | 0x400,\n\t\t0, NULL, 0, 1000) != 0) {\n\t\tLOG_ERROR(\"cannot set sync bitbang mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* Exactly 500 nsec between updates. */\n\tunsigned divisor = 1;\n\tunsigned char latency_timer = 1;\n\n\t/* Frequency divisor is 14-bit non-zero value. */\n\tif (jtag_libusb_control_transfer(adapter,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\tSIO_SET_BAUD_RATE, divisor,\n\t\t0, NULL, 0, 1000) != 0) {\n\t\tLOG_ERROR(\"cannot set baud rate\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tif (jtag_libusb_control_transfer(adapter,\n\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\tSIO_SET_LATENCY_TIMER, latency_timer, 0, NULL, 0, 1000) != 0) {\n\t\tLOG_ERROR(\"unable to set latency timer\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tft232r_output = malloc(ft232r_buf_size);\n\tif (!ft232r_output) {\n\t\tLOG_ERROR(\"Unable to allocate memory for the buffer\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ft232r_quit(void)\n{\n\t/* to restore serial port: set TXD RTS DTR as outputs, others as inputs, disable sync bit bang mode. */\n\tif (ft232r_restore_bitmode != 0xFFFF) {\n\t\tif (jtag_libusb_control_transfer(adapter,\n\t\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\t\tSIO_SET_BITMODE, ft232r_restore_bitmode,\n\t\t\t0, NULL, 0, 1000) != 0) {\n\t\t\tLOG_ERROR(\"cannot set bitmode to restore serial port\");\n\t\t}\n\t}\n\n\tif (libusb_release_interface(adapter, 0) != 0)\n\t\tLOG_ERROR(\"usb release interface failed\");\n\n\tjtag_libusb_close(adapter);\n\n\tfree(ft232r_output); /* free used memory */\n\tft232r_output = NULL; /* reset pointer to memory */\n\tft232r_buf_size = FT232R_BUF_SIZE_EXTRA; /* reset next initial buffer size */\n\n\treturn ERROR_OK;\n}\n\nstatic int ft232r_speed_div(int divisor, int *khz)\n{\n\t/* Maximum 3 Mbaud for bit bang mode. */\n\tif (divisor == 0)\n\t\t*khz = 3000;\n\telse if (divisor == 1)\n\t\t*khz = 2000;\n\telse\n\t\t*khz = 3000 / divisor;\n\treturn ERROR_OK;\n}\n\nstatic int ft232r_khz(int khz, int *divisor)\n{\n\tif (khz == 0) {\n\t\tLOG_DEBUG(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Calculate frequency divisor. */\n\tif (khz > 2500)\n\t\t*divisor = 0;\t\t/* Special case: 3 MHz */\n\telse if (khz > 1700)\n\t\t*divisor = 1;\t\t/* Special case: 2 MHz */\n\telse {\n\t\t*divisor = (2*3000 / khz + 1) / 2;\n\t\tif (*divisor > 0x3FFF)\n\t\t\t*divisor = 0x3FFF;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic char *ft232r_bit_number_to_name(int bit)\n{\n\tif (bit >= 0 && bit < FT232R_BIT_COUNT)\n\t\treturn ft232r_bit_name_array[bit];\n\treturn \"?\";\n}\n\nstatic int ft232r_bit_name_to_number(const char *name)\n{\n\tint i;\n\tif (name[0] >= '0' && name[0] <= '9' && name[1] == '\\0') {\n\t\ti = atoi(name);\n\t\tif (i >= 0 && i < FT232R_BIT_COUNT)\n\t\t\treturn i;\n\t}\n\tfor (i = 0; i < FT232R_BIT_COUNT; i++)\n\t\tif (strcasecmp(name, ft232r_bit_name_array[i]) == 0)\n\t\t\treturn i;\n\treturn -1;\n}\n\nCOMMAND_HANDLER(ft232r_handle_vid_pid_command)\n{\n\tif (CMD_ARGC > 2) {\n\t\tLOG_WARNING(\"ignoring extra IDs in ft232r_vid_pid \"\n\t\t\t\t\t\"(maximum is 1 pair)\");\n\t\tCMD_ARGC = 2;\n\t}\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], ft232r_vid);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], ft232r_pid);\n\t} else\n\t\tLOG_WARNING(\"incomplete ft232r_vid_pid configuration\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_jtag_nums_command)\n{\n\tif (CMD_ARGC == 4) {\n\t\ttck_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\t\ttms_gpio = ft232r_bit_name_to_number(CMD_ARGV[1]);\n\t\ttdi_gpio = ft232r_bit_name_to_number(CMD_ARGV[2]);\n\t\ttdo_gpio = ft232r_bit_name_to_number(CMD_ARGV[3]);\n\t} else if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (tck_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (tms_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (tdi_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (tdo_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R nums: TCK = %d %s, TMS = %d %s, TDI = %d %s, TDO = %d %s\",\n\t\t\ttck_gpio, ft232r_bit_number_to_name(tck_gpio),\n\t\t\ttms_gpio, ft232r_bit_number_to_name(tms_gpio),\n\t\t\ttdi_gpio, ft232r_bit_number_to_name(tdi_gpio),\n\t\t\ttdo_gpio, ft232r_bit_number_to_name(tdo_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_tck_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\ttck_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (tck_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: TCK = %d %s\", tck_gpio, ft232r_bit_number_to_name(tck_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_tms_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\ttms_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (tms_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: TMS = %d %s\", tms_gpio, ft232r_bit_number_to_name(tms_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_tdo_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\ttdo_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (tdo_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: TDO = %d %s\", tdo_gpio, ft232r_bit_number_to_name(tdo_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_tdi_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\ttdi_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (tdi_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: TDI = %d %s\", tdi_gpio, ft232r_bit_number_to_name(tdi_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_trst_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tntrst_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (ntrst_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: TRST = %d %s\", ntrst_gpio, ft232r_bit_number_to_name(ntrst_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_srst_num_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tnsysrst_gpio = ft232r_bit_name_to_number(CMD_ARGV[0]);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (nsysrst_gpio < 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R num: SRST = %d %s\", nsysrst_gpio, ft232r_bit_number_to_name(nsysrst_gpio));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ft232r_handle_restore_serial_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], ft232r_restore_bitmode);\n\telse if (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD,\n\t\t\t\"FT232R restore serial: 0x%04X (%s)\",\n\t\t\tft232r_restore_bitmode, ft232r_restore_bitmode == 0xFFFF ? \"disabled\" : \"enabled\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration ft232r_subcommand_handlers[] = {\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = ft232r_handle_vid_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"USB VID and PID of the adapter\",\n\t\t.usage = \"vid pid\",\n\t},\n\t{\n\t\t.name = \"jtag_nums\",\n\t\t.handler = ft232r_handle_jtag_nums_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio numbers for tck, tms, tdi, tdo. (in that order)\",\n\t\t.usage = \"<0-7|TXD-RI> <0-7|TXD-RI> <0-7|TXD-RI> <0-7|TXD-RI>\",\n\t},\n\t{\n\t\t.name = \"tck_num\",\n\t\t.handler = ft232r_handle_tck_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tck.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"tms_num\",\n\t\t.handler = ft232r_handle_tms_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tms.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"tdo_num\",\n\t\t.handler = ft232r_handle_tdo_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdo.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"tdi_num\",\n\t\t.handler = ft232r_handle_tdi_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdi.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"srst_num\",\n\t\t.handler = ft232r_handle_srst_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for srst.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"trst_num\",\n\t\t.handler = ft232r_handle_trst_num_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for trst.\",\n\t\t.usage = \"<0-7|TXD|RXD|RTS|CTS|DTR|DSR|DCD|RI>\",\n\t},\n\t{\n\t\t.name = \"restore_serial\",\n\t\t.handler = ft232r_handle_restore_serial_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"bitmode control word that restores serial port.\",\n\t\t.usage = \"bitmode_control_word\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration ft232r_command_handlers[] = {\n\t{\n\t\t.name = \"ft232r\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform ft232r management\",\n\t\t.chain = ft232r_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/*\n * Synchronous bitbang protocol implementation.\n */\n\nstatic void syncbb_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void syncbb_state_move(int skip)\n{\n\tint i = 0, tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tfor (i = skip; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\tft232r_write(0, tms, 0);\n\t\tft232r_write(1, tms, 0);\n\t}\n\tft232r_write(0, tms, 0);\n\n\ttap_set_state(tap_get_end_state());\n}\n\n/**\n * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG\n * (or SWD) state machine.\n */\nstatic int syncbb_execute_tms(struct jtag_command *cmd)\n{\n\tunsigned num_bits = cmd->cmd.tms->num_bits;\n\tconst uint8_t *bits = cmd->cmd.tms->bits;\n\n\tLOG_DEBUG_IO(\"TMS: %d bits\", num_bits);\n\n\tint tms = 0;\n\tfor (unsigned i = 0; i < num_bits; i++) {\n\t\ttms = ((bits[i/8] >> (i % 8)) & 1);\n\t\tft232r_write(0, tms, 0);\n\t\tft232r_write(1, tms, 0);\n\t}\n\tft232r_write(0, tms, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic void syncbb_path_move(struct pathmove_command *cmd)\n{\n\tint num_states = cmd->num_states;\n\tint state_count;\n\tint tms = 0;\n\n\tstate_count = 0;\n\twhile (num_states) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) {\n\t\t\ttms = 0;\n\t\t} else if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count]) {\n\t\t\ttms = 1;\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(cmd->path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\tft232r_write(0, tms, 0);\n\t\tft232r_write(1, tms, 0);\n\n\t\ttap_set_state(cmd->path[state_count]);\n\t\tstate_count++;\n\t\tnum_states--;\n\t}\n\n\tft232r_write(0, tms, 0);\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void syncbb_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tsyncbb_end_state(TAP_IDLE);\n\t\tsyncbb_state_move(0);\n\t}\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tft232r_write(0, 0, 0);\n\t\tft232r_write(1, 0, 0);\n\t}\n\tft232r_write(0, 0, 0);\n\n\t/* finish in end_state */\n\tsyncbb_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tsyncbb_state_move(0);\n}\n\n/**\n * Function syncbb_stableclocks\n * issues a number of clock cycles while staying in a stable state.\n * Because the TMS value required to stay in the RESET state is a 1, whereas\n * the TMS value required to stay in any of the other stable states is a 0,\n * this function checks the current stable state to decide on the value of TMS\n * to use.\n */\nstatic void syncbb_stableclocks(int num_cycles)\n{\n\tint tms = (tap_get_state() == TAP_RESET ? 1 : 0);\n\tint i;\n\n\t/* send num_cycles clocks onto the cable */\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tft232r_write(1, tms, 0);\n\t\tft232r_write(0, tms, 0);\n\t}\n}\n\nstatic void syncbb_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\tint bit_cnt, bit0_index;\n\n\tif (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) || (ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {\n\t\tif (ir_scan)\n\t\t\tsyncbb_end_state(TAP_IRSHIFT);\n\t\telse\n\t\t\tsyncbb_end_state(TAP_DRSHIFT);\n\n\t\tsyncbb_state_move(0);\n\t\tsyncbb_end_state(saved_end_state);\n\t}\n\n\tbit0_index = ft232r_output_len;\n\tfor (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {\n\t\tint tms = (bit_cnt == scan_size-1) ? 1 : 0;\n\t\tint tdi;\n\t\tint bytec = bit_cnt/8;\n\t\tint bcval = 1 << (bit_cnt % 8);\n\n\t\t/* if we're just reading the scan, but don't care about the output\n\t\t * default to outputting 'low', this also makes valgrind traces more readable,\n\t\t * as it removes the dependency on an uninitialised value\n\t\t */\n\t\ttdi = 0;\n\t\tif ((type != SCAN_IN) && (buffer[bytec] & bcval))\n\t\t\ttdi = 1;\n\n\t\tft232r_write(0, tms, tdi);\n\t\tft232r_write(1, tms, tdi);\n\t}\n\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\t/* we *KNOW* the above loop transitioned out of\n\t\t * the shift state, so we skip the first state\n\t\t * and move directly to the end state.\n\t\t */\n\t\tsyncbb_state_move(1);\n\t}\n\tft232r_send_recv();\n\n\tif (type != SCAN_OUT)\n\t\tfor (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++) {\n\t\t\tint bytec = bit_cnt/8;\n\t\t\tint bcval = 1 << (bit_cnt % 8);\n\t\t\tint val = ft232r_output[bit0_index + bit_cnt*2 + 1];\n\n\t\t\tif (val & (1<<tdo_gpio))\n\t\t\t\tbuffer[bytec] |= bcval;\n\t\t\telse\n\t\t\t\tbuffer[bytec] &= ~bcval;\n\t\t}\n}\n\nstatic int syncbb_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue; /* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\tint retval;\n\n\t/* return ERROR_OK, unless a jtag_read_buffer returns a failed check\n\t * that wasn't handled by a caller-provided error handler\n\t */\n\tretval = ERROR_OK;\n\n/*\tft232r_blink(1);*/\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\n\t\t\t\tif ((cmd->cmd.reset->trst == 1) ||\n\t\t\t\t\t(cmd->cmd.reset->srst &&\n\t\t\t\t\t(jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) {\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\t}\n\t\t\t\tft232r_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %s\", cmd->cmd.runtest->num_cycles,\n\t\t\t\t\ttap_state_name(cmd->cmd.runtest->end_state));\n\n\t\t\t\tsyncbb_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tsyncbb_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_STABLECLOCKS:\n\t\t\t\t/* this is only allowed while in a stable state.  A check for a stable\n\t\t\t\t * state was done in jtag_add_clocks()\n\t\t\t\t */\n\t\t\t\tsyncbb_stableclocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TLR_RESET: /* renamed from JTAG_STATEMOVE */\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %s\", tap_state_name(cmd->cmd.statemove->end_state));\n\n\t\t\t\tsyncbb_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tsyncbb_state_move(0);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %s\", cmd->cmd.pathmove->num_states,\n\t\t\t\t\ttap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));\n\n\t\t\t\tsyncbb_path_move(cmd->cmd.pathmove);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"%s scan end in %s\",  (cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\",\n\t\t\t\t\ttap_state_name(cmd->cmd.scan->end_state));\n\n\t\t\t\tsyncbb_end_state(cmd->cmd.scan->end_state);\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tsyncbb_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\n\t\t\t\tif (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TMS:\n\t\t\t\tretval = syncbb_execute_tms(cmd);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tif (ft232r_output_len > 0)\n\t\t\tft232r_send_recv();\n\t\tcmd = cmd->next;\n\t}\n/*\tft232r_blink(0);*/\n\n\treturn retval;\n}\n\nstatic struct jtag_interface ft232r_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = syncbb_execute_queue,\n};\n\nstruct adapter_driver ft232r_adapter_driver = {\n\t.name = \"ft232r\",\n\t.transports = jtag_only,\n\t.commands = ft232r_command_handlers,\n\n\t.init = ft232r_init,\n\t.quit = ft232r_quit,\n\t.speed = ft232r_speed,\n\t.khz = ft232r_khz,\n\t.speed_div = ft232r_speed_div,\n\n\t.jtag_ops = &ft232r_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ftdi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/**************************************************************************\n*   Copyright (C) 2012 by Andreas Fritiofson                              *\n*   andreas.fritiofson@gmail.com                                          *\n***************************************************************************/\n\n/**\n * @file\n * JTAG adapters based on the FT2232 full and high speed USB parts are\n * popular low cost JTAG debug solutions.  Many FT2232 based JTAG adapters\n * are discrete, but development boards may integrate them as alternatives\n * to more capable (and expensive) third party JTAG pods.\n *\n * JTAG uses only one of the two communications channels (\"MPSSE engines\")\n * on these devices.  Adapters based on FT4232 parts have four ports/channels\n * (A/B/C/D), instead of just two (A/B).\n *\n * Especially on development boards integrating one of these chips (as\n * opposed to discrete pods/dongles), the additional channels can be used\n * for a variety of purposes, but OpenOCD only uses one channel at a time.\n *\n *  - As a USB-to-serial adapter for the target's console UART ...\n *    which may be able to support ROM boot loaders that load initial\n *    firmware images to flash (or SRAM).\n *\n *  - On systems which support ARM's SWD in addition to JTAG, or instead\n *    of it, that second port can be used for reading SWV/SWO trace data.\n *\n *  - Additional JTAG links, e.g. to a CPLD or * FPGA.\n *\n * FT2232 based JTAG adapters are \"dumb\" not \"smart\", because most JTAG\n * request/response interactions involve round trips over the USB link.\n * A \"smart\" JTAG adapter has intelligence close to the scan chain, so it\n * can for example poll quickly for a status change (usually taking on the\n * order of microseconds not milliseconds) before beginning a queued\n * transaction which require the previous one to have completed.\n *\n * There are dozens of adapters of this type, differing in details which\n * this driver needs to understand.  Those \"layout\" details are required\n * as part of FT2232 driver configuration.\n *\n * This code uses information contained in the MPSSE specification which was\n * found here:\n * https://www.ftdichip.com/Support/Documents/AppNotes/AN2232C-01_MPSSE_Cmnd.pdf\n * Hereafter this is called the \"MPSSE Spec\".\n *\n * The datasheet for the ftdichip.com's FT2232H part is here:\n * https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT2232H.pdf\n *\n * Also note the issue with code 0x4b (clock data to TMS) noted in\n * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html\n * which can affect longer JTAG state paths.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/swd.h>\n#include <transport/transport.h>\n#include <helper/time_support.h>\n#include <helper/log.h>\n#include <helper/nvp.h>\n\n#if IS_CYGWIN == 1\n#include <windows.h>\n#endif\n\n#include <assert.h>\n\n/* FTDI access library includes */\n#include \"mpsse.h\"\n\n#define JTAG_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)\n#define JTAG_MODE_ALT (LSB_FIRST | NEG_EDGE_IN | NEG_EDGE_OUT)\n#define SWD_MODE (LSB_FIRST | POS_EDGE_IN | NEG_EDGE_OUT)\n\nstatic char *ftdi_device_desc;\nstatic uint8_t ftdi_channel;\nstatic uint8_t ftdi_jtag_mode = JTAG_MODE;\n\nstatic bool swd_mode;\n\n#define MAX_USB_IDS 8\n/* vid = pid = 0 marks the end of the list */\nstatic uint16_t ftdi_vid[MAX_USB_IDS + 1] = { 0 };\nstatic uint16_t ftdi_pid[MAX_USB_IDS + 1] = { 0 };\n\nstatic struct mpsse_ctx *mpsse_ctx;\n\nstruct signal {\n\tconst char *name;\n\tuint16_t data_mask;\n\tuint16_t input_mask;\n\tuint16_t oe_mask;\n\tbool invert_data;\n\tbool invert_input;\n\tbool invert_oe;\n\tstruct signal *next;\n};\n\nstatic struct signal *signals;\n\n/* FIXME: Where to store per-instance data? We need an SWD context. */\nstatic struct swd_cmd_queue_entry {\n\tuint8_t cmd;\n\tuint32_t *dst;\n\tuint8_t trn_ack_data_parity_trn[DIV_ROUND_UP(4 + 3 + 32 + 1 + 4, 8)];\n} *swd_cmd_queue;\nstatic size_t swd_cmd_queue_length;\nstatic size_t swd_cmd_queue_alloced;\nstatic int queued_retval;\nstatic int freq;\n\nstatic uint16_t output;\nstatic uint16_t direction;\nstatic uint16_t jtag_output_init;\nstatic uint16_t jtag_direction_init;\n\nstatic int ftdi_swd_switch_seq(enum swd_special_seq seq);\n\nstatic struct signal *find_signal_by_name(const char *name)\n{\n\tfor (struct signal *sig = signals; sig; sig = sig->next) {\n\t\tif (strcmp(name, sig->name) == 0)\n\t\t\treturn sig;\n\t}\n\treturn NULL;\n}\n\nstatic struct signal *create_signal(const char *name)\n{\n\tstruct signal **psig = &signals;\n\twhile (*psig)\n\t\tpsig = &(*psig)->next;\n\n\t*psig = calloc(1, sizeof(**psig));\n\tif (!*psig)\n\t\treturn NULL;\n\n\t(*psig)->name = strdup(name);\n\tif (!(*psig)->name) {\n\t\tfree(*psig);\n\t\t*psig = NULL;\n\t}\n\treturn *psig;\n}\n\nstatic int ftdi_set_signal(const struct signal *s, char value)\n{\n\tbool data;\n\tbool oe;\n\n\tif (s->data_mask == 0 && s->oe_mask == 0) {\n\t\tLOG_ERROR(\"interface doesn't provide signal '%s'\", s->name);\n\t\treturn ERROR_FAIL;\n\t}\n\tswitch (value) {\n\tcase '0':\n\t\tdata = s->invert_data;\n\t\toe = !s->invert_oe;\n\t\tbreak;\n\tcase '1':\n\t\tif (s->data_mask == 0) {\n\t\t\tLOG_ERROR(\"interface can't drive '%s' high\", s->name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tdata = !s->invert_data;\n\t\toe = !s->invert_oe;\n\t\tbreak;\n\tcase 'z':\n\tcase 'Z':\n\t\tif (s->oe_mask == 0) {\n\t\t\tLOG_ERROR(\"interface can't tri-state '%s'\", s->name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tdata = s->invert_data;\n\t\toe = s->invert_oe;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"invalid signal level specifier \\'%c\\'(0x%02x)\", value, value);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint16_t old_output = output;\n\tuint16_t old_direction = direction;\n\n\toutput = data ? output | s->data_mask : output & ~s->data_mask;\n\tif (s->oe_mask == s->data_mask)\n\t\tdirection = oe ? direction | s->oe_mask : direction & ~s->oe_mask;\n\telse\n\t\toutput = oe ? output | s->oe_mask : output & ~s->oe_mask;\n\n\tif ((output & 0xff) != (old_output & 0xff) || (direction & 0xff) != (old_direction & 0xff))\n\t\tmpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);\n\tif ((output >> 8 != old_output >> 8) || (direction >> 8 != old_direction >> 8))\n\t\tmpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);\n\n\treturn ERROR_OK;\n}\n\nstatic int ftdi_get_signal(const struct signal *s, uint16_t *value_out)\n{\n\tuint8_t data_low = 0;\n\tuint8_t data_high = 0;\n\n\tif (s->input_mask == 0) {\n\t\tLOG_ERROR(\"interface doesn't provide signal '%s'\", s->name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (s->input_mask & 0xff)\n\t\tmpsse_read_data_bits_low_byte(mpsse_ctx, &data_low);\n\tif (s->input_mask >> 8)\n\t\tmpsse_read_data_bits_high_byte(mpsse_ctx, &data_high);\n\n\tmpsse_flush(mpsse_ctx);\n\n\t*value_out = (((uint16_t)data_high) << 8) | data_low;\n\n\tif (s->invert_input)\n\t\t*value_out = ~(*value_out);\n\n\t*value_out &= s->input_mask;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Function move_to_state\n * moves the TAP controller from the current state to a\n * \\a goal_state through a path given by tap_get_tms_path().  State transition\n * logging is performed by delegation to clock_tms().\n *\n * @param goal_state is the destination state for the move.\n */\nstatic void move_to_state(tap_state_t goal_state)\n{\n\ttap_state_t start_state = tap_get_state();\n\n\t/*\tgoal_state is 1/2 of a tuple/pair of states which allow convenient\n\t\tlookup of the required TMS pattern to move to this state from the\n\t\tstart state.\n\t*/\n\n\t/* do the 2 lookups */\n\tuint8_t tms_bits  = tap_get_tms_path(start_state, goal_state);\n\tint tms_count = tap_get_tms_path_len(start_state, goal_state);\n\tassert(tms_count <= 8);\n\n\tLOG_DEBUG_IO(\"start=%s goal=%s\", tap_state_name(start_state), tap_state_name(goal_state));\n\n\t/* Track state transitions step by step */\n\tfor (int i = 0; i < tms_count; i++)\n\t\ttap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 1));\n\n\tmpsse_clock_tms_cs_out(mpsse_ctx,\n\t\t&tms_bits,\n\t\t0,\n\t\ttms_count,\n\t\tfalse,\n\t\tftdi_jtag_mode);\n}\n\nstatic int ftdi_speed(int speed)\n{\n\tint retval;\n\tretval = mpsse_set_frequency(mpsse_ctx, speed);\n\n\tif (retval < 0) {\n\t\tLOG_ERROR(\"couldn't set FTDI TCK speed\");\n\t\treturn retval;\n\t}\n\n\tif (!swd_mode && speed >= 10000000 && ftdi_jtag_mode != JTAG_MODE_ALT)\n\t\tLOG_INFO(\"ftdi: if you experience problems at higher adapter clocks, try \"\n\t\t\t \"the command \\\"ftdi tdo_sample_edge falling\\\"\");\n\treturn ERROR_OK;\n}\n\nstatic int ftdi_speed_div(int speed, int *khz)\n{\n\t*khz = speed / 1000;\n\treturn ERROR_OK;\n}\n\nstatic int ftdi_khz(int khz, int *jtag_speed)\n{\n\tif (khz == 0 && !mpsse_is_high_speed(mpsse_ctx)) {\n\t\tLOG_DEBUG(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*jtag_speed = khz * 1000;\n\treturn ERROR_OK;\n}\n\nstatic void ftdi_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %s is not a stable end state\", tap_state_name(state));\n\t\texit(-1);\n\t}\n}\n\nstatic void ftdi_execute_runtest(struct jtag_command *cmd)\n{\n\tint i;\n\tuint8_t zero = 0;\n\n\tLOG_DEBUG_IO(\"runtest %i cycles, end in %s\",\n\t\tcmd->cmd.runtest->num_cycles,\n\t\ttap_state_name(cmd->cmd.runtest->end_state));\n\n\tif (tap_get_state() != TAP_IDLE)\n\t\tmove_to_state(TAP_IDLE);\n\n\t/* TODO: Reuse ftdi_execute_stableclocks */\n\ti = cmd->cmd.runtest->num_cycles;\n\twhile (i > 0) {\n\t\t/* there are no state transitions in this code, so omit state tracking */\n\t\tunsigned this_len = i > 7 ? 7 : i;\n\t\tmpsse_clock_tms_cs_out(mpsse_ctx, &zero, 0, this_len, false, ftdi_jtag_mode);\n\t\ti -= this_len;\n\t}\n\n\tftdi_end_state(cmd->cmd.runtest->end_state);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tmove_to_state(tap_get_end_state());\n\n\tLOG_DEBUG_IO(\"runtest: %i, end in %s\",\n\t\tcmd->cmd.runtest->num_cycles,\n\t\ttap_state_name(tap_get_end_state()));\n}\n\nstatic void ftdi_execute_statemove(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"statemove end in %s\",\n\t\ttap_state_name(cmd->cmd.statemove->end_state));\n\n\tftdi_end_state(cmd->cmd.statemove->end_state);\n\n\t/* shortest-path move to desired end state */\n\tif (tap_get_state() != tap_get_end_state() || tap_get_end_state() == TAP_RESET)\n\t\tmove_to_state(tap_get_end_state());\n}\n\n/**\n * Clock a bunch of TMS (or SWDIO) transitions, to change the JTAG\n * (or SWD) state machine. REVISIT: Not the best method, perhaps.\n */\nstatic void ftdi_execute_tms(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"TMS: %d bits\", cmd->cmd.tms->num_bits);\n\n\t/* TODO: Missing tap state tracking, also missing from ft2232.c! */\n\tmpsse_clock_tms_cs_out(mpsse_ctx,\n\t\tcmd->cmd.tms->bits,\n\t\t0,\n\t\tcmd->cmd.tms->num_bits,\n\t\tfalse,\n\t\tftdi_jtag_mode);\n}\n\nstatic void ftdi_execute_pathmove(struct jtag_command *cmd)\n{\n\ttap_state_t *path = cmd->cmd.pathmove->path;\n\tint num_states  = cmd->cmd.pathmove->num_states;\n\n\tLOG_DEBUG_IO(\"pathmove: %i states, current: %s  end: %s\", num_states,\n\t\ttap_state_name(tap_get_state()),\n\t\ttap_state_name(path[num_states-1]));\n\n\tint state_count = 0;\n\tunsigned bit_count = 0;\n\tuint8_t tms_byte = 0;\n\n\tLOG_DEBUG_IO(\"-\");\n\n\t/* this loop verifies that the path is legal and logs each state in the path */\n\twhile (num_states--) {\n\n\t\t/* either TMS=0 or TMS=1 must work ... */\n\t\tif (tap_state_transition(tap_get_state(), false)\n\t\t    == path[state_count])\n\t\t\tbuf_set_u32(&tms_byte, bit_count++, 1, 0x0);\n\t\telse if (tap_state_transition(tap_get_state(), true)\n\t\t\t == path[state_count]) {\n\t\t\tbuf_set_u32(&tms_byte, bit_count++, 1, 0x1);\n\n\t\t\t/* ... or else the caller goofed BADLY */\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid \"\n\t\t\t\t\"TAP state transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[state_count]);\n\t\tstate_count++;\n\n\t\tif (bit_count == 7 || num_states == 0) {\n\t\t\tmpsse_clock_tms_cs_out(mpsse_ctx,\n\t\t\t\t\t&tms_byte,\n\t\t\t\t\t0,\n\t\t\t\t\tbit_count,\n\t\t\t\t\tfalse,\n\t\t\t\t\tftdi_jtag_mode);\n\t\t\tbit_count = 0;\n\t\t}\n\t}\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void ftdi_execute_scan(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"%s type:%d\", cmd->cmd.scan->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\tjtag_scan_type(cmd->cmd.scan));\n\n\t/* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */\n\twhile (cmd->cmd.scan->num_fields > 0\n\t\t\t&& cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {\n\t\tcmd->cmd.scan->num_fields--;\n\t\tLOG_DEBUG_IO(\"discarding trailing empty field\");\n\t}\n\n\tif (cmd->cmd.scan->num_fields == 0) {\n\t\tLOG_DEBUG_IO(\"empty scan, doing nothing\");\n\t\treturn;\n\t}\n\n\tif (cmd->cmd.scan->ir_scan) {\n\t\tif (tap_get_state() != TAP_IRSHIFT)\n\t\t\tmove_to_state(TAP_IRSHIFT);\n\t} else {\n\t\tif (tap_get_state() != TAP_DRSHIFT)\n\t\t\tmove_to_state(TAP_DRSHIFT);\n\t}\n\n\tftdi_end_state(cmd->cmd.scan->end_state);\n\n\tstruct scan_field *field = cmd->cmd.scan->fields;\n\tunsigned scan_size = 0;\n\n\tfor (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {\n\t\tscan_size += field->num_bits;\n\t\tLOG_DEBUG_IO(\"%s%s field %d/%d %d bits\",\n\t\t\tfield->in_value ? \"in\" : \"\",\n\t\t\tfield->out_value ? \"out\" : \"\",\n\t\t\ti,\n\t\t\tcmd->cmd.scan->num_fields,\n\t\t\tfield->num_bits);\n\n\t\tif (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {\n\t\t\t/* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap\n\t\t\t * movement. This last field can't have length zero, it was checked above. */\n\t\t\tmpsse_clock_data(mpsse_ctx,\n\t\t\t\tfield->out_value,\n\t\t\t\t0,\n\t\t\t\tfield->in_value,\n\t\t\t\t0,\n\t\t\t\tfield->num_bits - 1,\n\t\t\t\tftdi_jtag_mode);\n\t\t\tuint8_t last_bit = 0;\n\t\t\tif (field->out_value)\n\t\t\t\tbit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);\n\n\t\t\t/* If endstate is TAP_IDLE, clock out 1-1-0 (->EXIT1 ->UPDATE ->IDLE)\n\t\t\t * Otherwise, clock out 1-0 (->EXIT1 ->PAUSE)\n\t\t\t */\n\t\t\tuint8_t tms_bits = 0x03;\n\t\t\tmpsse_clock_tms_cs(mpsse_ctx,\n\t\t\t\t\t&tms_bits,\n\t\t\t\t\t0,\n\t\t\t\t\tfield->in_value,\n\t\t\t\t\tfield->num_bits - 1,\n\t\t\t\t\t1,\n\t\t\t\t\tlast_bit,\n\t\t\t\t\tftdi_jtag_mode);\n\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 1));\n\t\t\tif (tap_get_end_state() == TAP_IDLE) {\n\t\t\t\tmpsse_clock_tms_cs_out(mpsse_ctx,\n\t\t\t\t\t\t&tms_bits,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\tlast_bit,\n\t\t\t\t\t\tftdi_jtag_mode);\n\t\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 1));\n\t\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 0));\n\t\t\t} else {\n\t\t\t\tmpsse_clock_tms_cs_out(mpsse_ctx,\n\t\t\t\t\t\t&tms_bits,\n\t\t\t\t\t\t2,\n\t\t\t\t\t\t1,\n\t\t\t\t\t\tlast_bit,\n\t\t\t\t\t\tftdi_jtag_mode);\n\t\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 0));\n\t\t\t}\n\t\t} else\n\t\t\tmpsse_clock_data(mpsse_ctx,\n\t\t\t\tfield->out_value,\n\t\t\t\t0,\n\t\t\t\tfield->in_value,\n\t\t\t\t0,\n\t\t\t\tfield->num_bits,\n\t\t\t\tftdi_jtag_mode);\n\t}\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tmove_to_state(tap_get_end_state());\n\n\tLOG_DEBUG_IO(\"%s scan, %i bits, end in %s\",\n\t\t(cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\", scan_size,\n\t\ttap_state_name(tap_get_end_state()));\n}\n\nstatic int ftdi_reset(int trst, int srst)\n{\n\tstruct signal *sig_ntrst = find_signal_by_name(\"nTRST\");\n\tstruct signal *sig_nsrst = find_signal_by_name(\"nSRST\");\n\n\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", trst, srst);\n\n\tif (!swd_mode) {\n\t\tif (trst == 1) {\n\t\t\tif (sig_ntrst)\n\t\t\t\tftdi_set_signal(sig_ntrst, '0');\n\t\t\telse\n\t\t\t\tLOG_ERROR(\"Can't assert TRST: nTRST signal is not defined\");\n\t\t} else if (sig_ntrst && jtag_get_reset_config() & RESET_HAS_TRST &&\n\t\t\t\ttrst == 0) {\n\t\t\tif (jtag_get_reset_config() & RESET_TRST_OPEN_DRAIN)\n\t\t\t\tftdi_set_signal(sig_ntrst, 'z');\n\t\t\telse\n\t\t\t\tftdi_set_signal(sig_ntrst, '1');\n\t\t}\n\t}\n\n\tif (srst == 1) {\n\t\tif (sig_nsrst)\n\t\t\tftdi_set_signal(sig_nsrst, '0');\n\t\telse\n\t\t\tLOG_ERROR(\"Can't assert SRST: nSRST signal is not defined\");\n\t} else if (sig_nsrst && jtag_get_reset_config() & RESET_HAS_SRST &&\n\t\t\tsrst == 0) {\n\t\tif (jtag_get_reset_config() & RESET_SRST_PUSH_PULL)\n\t\t\tftdi_set_signal(sig_nsrst, '1');\n\t\telse\n\t\t\tftdi_set_signal(sig_nsrst, 'z');\n\t}\n\n\treturn mpsse_flush(mpsse_ctx);\n}\n\nstatic void ftdi_execute_sleep(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\n\tmpsse_flush(mpsse_ctx);\n\tjtag_sleep(cmd->cmd.sleep->us);\n\tLOG_DEBUG_IO(\"sleep %\" PRIu32 \" usec while in %s\",\n\t\tcmd->cmd.sleep->us,\n\t\ttap_state_name(tap_get_state()));\n}\n\nstatic void ftdi_execute_stableclocks(struct jtag_command *cmd)\n{\n\t/* this is only allowed while in a stable state.  A check for a stable\n\t * state was done in jtag_add_clocks()\n\t */\n\tint num_cycles = cmd->cmd.stableclocks->num_cycles;\n\n\t/* 7 bits of either ones or zeros. */\n\tuint8_t tms = tap_get_state() == TAP_RESET ? 0x7f : 0x00;\n\n\t/* TODO: Use mpsse_clock_data with in=out=0 for this, if TMS can be set to\n\t * the correct level and remain there during the scan */\n\twhile (num_cycles > 0) {\n\t\t/* there are no state transitions in this code, so omit state tracking */\n\t\tunsigned this_len = num_cycles > 7 ? 7 : num_cycles;\n\t\tmpsse_clock_tms_cs_out(mpsse_ctx, &tms, 0, this_len, false, ftdi_jtag_mode);\n\t\tnum_cycles -= this_len;\n\t}\n\n\tLOG_DEBUG_IO(\"clocks %i while in %s\",\n\t\tcmd->cmd.stableclocks->num_cycles,\n\t\ttap_state_name(tap_get_state()));\n}\n\nstatic void ftdi_execute_command(struct jtag_command *cmd)\n{\n\tswitch (cmd->type) {\n\t\tcase JTAG_RUNTEST:\n\t\t\tftdi_execute_runtest(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tftdi_execute_statemove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tftdi_execute_pathmove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tftdi_execute_scan(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tftdi_execute_sleep(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tftdi_execute_stableclocks(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\tftdi_execute_tms(cmd);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered: %d\", cmd->type);\n\t\t\tbreak;\n\t}\n}\n\nstatic int ftdi_execute_queue(void)\n{\n\t/* blink, if the current layout has that feature */\n\tstruct signal *led = find_signal_by_name(\"LED\");\n\tif (led)\n\t\tftdi_set_signal(led, '1');\n\n\tfor (struct jtag_command *cmd = jtag_command_queue; cmd; cmd = cmd->next) {\n\t\t/* fill the write buffer with the desired command */\n\t\tftdi_execute_command(cmd);\n\t}\n\n\tif (led)\n\t\tftdi_set_signal(led, '0');\n\n\tint retval = mpsse_flush(mpsse_ctx);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"error while flushing MPSSE queue: %d\", retval);\n\n\treturn retval;\n}\n\nstatic int ftdi_initialize(void)\n{\n\tif (tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRPAUSE) == 7)\n\t\tLOG_DEBUG(\"ftdi interface using 7 step jtag state transitions\");\n\telse\n\t\tLOG_DEBUG(\"ftdi interface using shortest path jtag state transitions\");\n\n\tif (!ftdi_vid[0] && !ftdi_pid[0]) {\n\t\tLOG_ERROR(\"Please specify ftdi vid_pid\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tmpsse_ctx = mpsse_open(ftdi_vid, ftdi_pid, ftdi_device_desc,\n\t\t\t\tadapter_get_required_serial(), adapter_usb_get_location(), ftdi_channel);\n\tif (!mpsse_ctx)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\toutput = jtag_output_init;\n\tdirection = jtag_direction_init;\n\n\tif (swd_mode) {\n\t\tstruct signal *sig = find_signal_by_name(\"SWD_EN\");\n\t\tif (!sig) {\n\t\t\tLOG_ERROR(\"SWD mode is active but SWD_EN signal is not defined\");\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t\t/* A dummy SWD_EN would have zero mask */\n\t\tif (sig->data_mask)\n\t\t\tftdi_set_signal(sig, '1');\n\t}\n\n\tmpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);\n\tmpsse_set_data_bits_high_byte(mpsse_ctx, output >> 8, direction >> 8);\n\n\tmpsse_loopback_config(mpsse_ctx, false);\n\n\tfreq = mpsse_set_frequency(mpsse_ctx, adapter_get_speed_khz() * 1000);\n\n\treturn mpsse_flush(mpsse_ctx);\n}\n\nstatic int ftdi_quit(void)\n{\n\tmpsse_close(mpsse_ctx);\n\n\tstruct signal *sig = signals;\n\twhile (sig) {\n\t\tstruct signal *next = sig->next;\n\t\tfree((void *)sig->name);\n\t\tfree(sig);\n\t\tsig = next;\n\t}\n\n\tfree(ftdi_device_desc);\n\n\tfree(swd_cmd_queue);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_device_desc_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tfree(ftdi_device_desc);\n\t\tftdi_device_desc = strdup(CMD_ARGV[0]);\n\t} else {\n\t\tLOG_ERROR(\"expected exactly one argument to ftdi device_desc <description>\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_channel_command)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], ftdi_channel);\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_layout_init_command)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], jtag_output_init);\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], jtag_direction_init);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_layout_signal_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tbool invert_data = false;\n\tuint16_t data_mask = 0;\n\tbool invert_input = false;\n\tuint16_t input_mask = 0;\n\tbool invert_oe = false;\n\tuint16_t oe_mask = 0;\n\tfor (unsigned i = 1; i < CMD_ARGC; i += 2) {\n\t\tif (strcmp(\"-data\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_data = false;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], data_mask);\n\t\t} else if (strcmp(\"-ndata\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_data = true;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], data_mask);\n\t\t} else if (strcmp(\"-input\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_input = false;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);\n\t\t} else if (strcmp(\"-ninput\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_input = true;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], input_mask);\n\t\t} else if (strcmp(\"-oe\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_oe = false;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);\n\t\t} else if (strcmp(\"-noe\", CMD_ARGV[i]) == 0) {\n\t\t\tinvert_oe = true;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], oe_mask);\n\t\t} else if (!strcmp(\"-alias\", CMD_ARGV[i]) ||\n\t\t\t   !strcmp(\"-nalias\", CMD_ARGV[i])) {\n\t\t\tif (!strcmp(\"-nalias\", CMD_ARGV[i])) {\n\t\t\t\tinvert_data = true;\n\t\t\t\tinvert_input = true;\n\t\t\t}\n\t\t\tstruct signal *sig = find_signal_by_name(CMD_ARGV[i + 1]);\n\t\t\tif (!sig) {\n\t\t\t\tLOG_ERROR(\"signal %s is not defined\", CMD_ARGV[i + 1]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tdata_mask = sig->data_mask;\n\t\t\tinput_mask = sig->input_mask;\n\t\t\toe_mask = sig->oe_mask;\n\t\t\tinvert_input ^= sig->invert_input;\n\t\t\tinvert_oe = sig->invert_oe;\n\t\t\tinvert_data ^= sig->invert_data;\n\t\t} else {\n\t\t\tLOG_ERROR(\"unknown option '%s'\", CMD_ARGV[i]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tstruct signal *sig;\n\tsig = find_signal_by_name(CMD_ARGV[0]);\n\tif (!sig)\n\t\tsig = create_signal(CMD_ARGV[0]);\n\tif (!sig) {\n\t\tLOG_ERROR(\"failed to create signal %s\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsig->invert_data = invert_data;\n\tsig->data_mask = data_mask;\n\tsig->invert_input = invert_input;\n\tsig->input_mask = input_mask;\n\tsig->invert_oe = invert_oe;\n\tsig->oe_mask = oe_mask;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_set_signal_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct signal *sig;\n\tsig = find_signal_by_name(CMD_ARGV[0]);\n\tif (!sig) {\n\t\tLOG_ERROR(\"interface configuration doesn't define signal '%s'\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (*CMD_ARGV[1]) {\n\tcase '0':\n\tcase '1':\n\tcase 'z':\n\tcase 'Z':\n\t\t/* single character level specifier only */\n\t\tif (CMD_ARGV[1][1] == '\\0') {\n\t\t\tftdi_set_signal(sig, *CMD_ARGV[1]);\n\t\t\tbreak;\n\t\t}\n\t\t/* fallthrough */\n\tdefault:\n\t\tLOG_ERROR(\"unknown signal level '%s', use 0, 1 or z\", CMD_ARGV[1]);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn mpsse_flush(mpsse_ctx);\n}\n\nCOMMAND_HANDLER(ftdi_handle_get_signal_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct signal *sig;\n\tuint16_t sig_data = 0;\n\tsig = find_signal_by_name(CMD_ARGV[0]);\n\tif (!sig) {\n\t\tLOG_ERROR(\"interface configuration doesn't define signal '%s'\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = ftdi_get_signal(sig, &sig_data);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_USER(\"Signal %s = %#06x\", sig->name, sig_data);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_vid_pid_command)\n{\n\tif (CMD_ARGC > MAX_USB_IDS * 2) {\n\t\tLOG_WARNING(\"ignoring extra IDs in ftdi vid_pid \"\n\t\t\t\"(maximum is %d pairs)\", MAX_USB_IDS);\n\t\tCMD_ARGC = MAX_USB_IDS * 2;\n\t}\n\tif (CMD_ARGC < 2 || (CMD_ARGC & 1)) {\n\t\tLOG_WARNING(\"incomplete ftdi vid_pid configuration directive\");\n\t\tif (CMD_ARGC < 2)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t/* remove the incomplete trailing id */\n\t\tCMD_ARGC -= 1;\n\t}\n\n\tunsigned i;\n\tfor (i = 0; i < CMD_ARGC; i += 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], ftdi_vid[i >> 1]);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], ftdi_pid[i >> 1]);\n\t}\n\n\t/*\n\t * Explicitly terminate, in case there are multiples instances of\n\t * ftdi vid_pid.\n\t */\n\tftdi_vid[i >> 1] = ftdi_pid[i >> 1] = 0;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ftdi_handle_tdo_sample_edge_command)\n{\n\tconst struct nvp *n;\n\tstatic const struct nvp nvp_ftdi_jtag_modes[] = {\n\t\t{ .name = \"rising\", .value = JTAG_MODE },\n\t\t{ .name = \"falling\", .value = JTAG_MODE_ALT },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\n\tif (CMD_ARGC > 0) {\n\t\tn = nvp_name2value(nvp_ftdi_jtag_modes, CMD_ARGV[0]);\n\t\tif (!n->name)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tftdi_jtag_mode = n->value;\n\n\t}\n\n\tn = nvp_value2name(nvp_ftdi_jtag_modes, ftdi_jtag_mode);\n\tcommand_print(CMD, \"ftdi samples TDO on %s edge of TCK\", n->name);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration ftdi_subcommand_handlers[] = {\n\t{\n\t\t.name = \"device_desc\",\n\t\t.handler = &ftdi_handle_device_desc_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the USB device description of the FTDI device\",\n\t\t.usage = \"description_string\",\n\t},\n\t{\n\t\t.name = \"channel\",\n\t\t.handler = &ftdi_handle_channel_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the channel of the FTDI device that is used as JTAG\",\n\t\t.usage = \"(0-3)\",\n\t},\n\t{\n\t\t.name = \"layout_init\",\n\t\t.handler = &ftdi_handle_layout_init_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"initialize the FTDI GPIO signals used \"\n\t\t\t\"to control output-enables and reset signals\",\n\t\t.usage = \"data direction\",\n\t},\n\t{\n\t\t.name = \"layout_signal\",\n\t\t.handler = &ftdi_handle_layout_signal_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"define a signal controlled by one or more FTDI GPIO as data \"\n\t\t\t\"and/or output enable\",\n\t\t.usage = \"name [-data mask|-ndata mask] [-oe mask|-noe mask] [-alias|-nalias name]\",\n\t},\n\t{\n\t\t.name = \"set_signal\",\n\t\t.handler = &ftdi_handle_set_signal_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"control a layout-specific signal\",\n\t\t.usage = \"name (1|0|z)\",\n\t},\n\t{\n\t\t.name = \"get_signal\",\n\t\t.handler = &ftdi_handle_get_signal_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read the value of a layout-specific signal\",\n\t\t.usage = \"name\",\n\t},\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = &ftdi_handle_vid_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"the vendor ID and product ID of the FTDI device\",\n\t\t.usage = \"(vid pid)*\",\n\t},\n\t{\n\t\t.name = \"tdo_sample_edge\",\n\t\t.handler = &ftdi_handle_tdo_sample_edge_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"set which TCK clock edge is used for sampling TDO \"\n\t\t\t\"- default is rising-edge (Setting to falling-edge may \"\n\t\t\t\"allow signalling speed increase)\",\n\t\t.usage = \"(rising|falling)\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration ftdi_command_handlers[] = {\n\t{\n\t\t.name = \"ftdi\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform ftdi management\",\n\t\t.chain = ftdi_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int create_default_signal(const char *name, uint16_t data_mask)\n{\n\tstruct signal *sig = create_signal(name);\n\tif (!sig) {\n\t\tLOG_ERROR(\"failed to create signal %s\", name);\n\t\treturn ERROR_FAIL;\n\t}\n\tsig->invert_data = false;\n\tsig->data_mask = data_mask;\n\tsig->invert_oe = false;\n\tsig->oe_mask = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int create_signals(void)\n{\n\tif (create_default_signal(\"TCK\", 0x01) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (create_default_signal(\"TDI\", 0x02) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (create_default_signal(\"TDO\", 0x04) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (create_default_signal(\"TMS\", 0x08) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\nstatic int ftdi_swd_init(void)\n{\n\tLOG_INFO(\"FTDI SWD mode enabled\");\n\tswd_mode = true;\n\n\tif (create_signals() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tswd_cmd_queue_alloced = 10;\n\tswd_cmd_queue = malloc(swd_cmd_queue_alloced * sizeof(*swd_cmd_queue));\n\n\treturn swd_cmd_queue ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic void ftdi_swd_swdio_en(bool enable)\n{\n\tstruct signal *oe = find_signal_by_name(\"SWDIO_OE\");\n\tif (oe) {\n\t\tif (oe->data_mask)\n\t\t\tftdi_set_signal(oe, enable ? '1' : '0');\n\t\telse {\n\t\t\t/* Sets TDI/DO pin to input during rx when both pins are connected\n\t\t\t   to SWDIO */\n\t\t\tif (enable)\n\t\t\t\tdirection |= jtag_direction_init & 0x0002U;\n\t\t\telse\n\t\t\t\tdirection &= ~0x0002U;\n\t\t\tmpsse_set_data_bits_low_byte(mpsse_ctx, output & 0xff, direction & 0xff);\n\t\t}\n\t}\n}\n\n/**\n * Flush the MPSSE queue and process the SWD transaction queue\n * @return\n */\nstatic int ftdi_swd_run_queue(void)\n{\n\tLOG_DEBUG_IO(\"Executing %zu queued transactions\", swd_cmd_queue_length);\n\tint retval;\n\tstruct signal *led = find_signal_by_name(\"LED\");\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Skipping due to previous errors: %d\", queued_retval);\n\t\tgoto skip;\n\t}\n\n\t/* A transaction must be followed by another transaction or at least 8 idle cycles to\n\t * ensure that data is clocked through the AP. */\n\tmpsse_clock_data_out(mpsse_ctx, NULL, 0, 8, SWD_MODE);\n\n\t/* Terminate the \"blink\", if the current layout has that feature */\n\tif (led)\n\t\tftdi_set_signal(led, '0');\n\n\tqueued_retval = mpsse_flush(mpsse_ctx);\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_ERROR(\"MPSSE failed\");\n\t\tgoto skip;\n\t}\n\n\tfor (size_t i = 0; i < swd_cmd_queue_length; i++) {\n\t\tint ack = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1, 3);\n\n\t\t/* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */\n\t\tbool check_ack = swd_cmd_returns_ack(swd_cmd_queue[i].cmd);\n\n\t\tLOG_DEBUG_IO(\"%s%s %s %s reg %X = %08\"PRIx32,\n\t\t\t\tcheck_ack ? \"\" : \"ack ignored \",\n\t\t\t\tack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t\t\tswd_cmd_queue[i].cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t\tswd_cmd_queue[i].cmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t\t(swd_cmd_queue[i].cmd & SWD_CMD_A32) >> 1,\n\t\t\t\tbuf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn,\n\t\t\t\t\t\t1 + 3 + (swd_cmd_queue[i].cmd & SWD_CMD_RNW ? 0 : 1), 32));\n\n\t\tif (ack != SWD_ACK_OK && check_ack) {\n\t\t\tqueued_retval = swd_ack_to_error_code(ack);\n\t\t\tgoto skip;\n\n\t\t} else if (swd_cmd_queue[i].cmd & SWD_CMD_RNW) {\n\t\t\tuint32_t data = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3, 32);\n\t\t\tint parity = buf_get_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 32, 1);\n\n\t\t\tif (parity != parity_u32(data)) {\n\t\t\t\tLOG_ERROR(\"SWD Read data parity mismatch\");\n\t\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\t\tgoto skip;\n\t\t\t}\n\n\t\t\tif (swd_cmd_queue[i].dst)\n\t\t\t\t*swd_cmd_queue[i].dst = data;\n\t\t}\n\t}\n\nskip:\n\tswd_cmd_queue_length = 0;\n\tretval = queued_retval;\n\tqueued_retval = ERROR_OK;\n\n\t/* Queue a new \"blink\" */\n\tif (led && retval == ERROR_OK)\n\t\tftdi_set_signal(led, '1');\n\n\treturn retval;\n}\n\nstatic void ftdi_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)\n{\n\tif (swd_cmd_queue_length >= swd_cmd_queue_alloced) {\n\t\t/* Not enough room in the queue. Run the queue and increase its size for next time.\n\t\t * Note that it's not possible to avoid running the queue here, because mpsse contains\n\t\t * pointers into the queue which may be invalid after the realloc. */\n\t\tqueued_retval = ftdi_swd_run_queue();\n\t\tstruct swd_cmd_queue_entry *q = realloc(swd_cmd_queue, swd_cmd_queue_alloced * 2 * sizeof(*swd_cmd_queue));\n\t\tif (q) {\n\t\t\tswd_cmd_queue = q;\n\t\t\tswd_cmd_queue_alloced *= 2;\n\t\t\tLOG_DEBUG(\"Increased SWD command queue to %zu elements\", swd_cmd_queue_alloced);\n\t\t}\n\t}\n\n\tif (queued_retval != ERROR_OK)\n\t\treturn;\n\n\tsize_t i = swd_cmd_queue_length++;\n\tswd_cmd_queue[i].cmd = cmd | SWD_CMD_START | SWD_CMD_PARK;\n\n\tmpsse_clock_data_out(mpsse_ctx, &swd_cmd_queue[i].cmd, 0, 8, SWD_MODE);\n\n\tif (swd_cmd_queue[i].cmd & SWD_CMD_RNW) {\n\t\t/* Queue a read transaction */\n\t\tswd_cmd_queue[i].dst = dst;\n\n\t\tftdi_swd_swdio_en(false);\n\t\tmpsse_clock_data_in(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn,\n\t\t\t\t0, 1 + 3 + 32 + 1 + 1, SWD_MODE);\n\t\tftdi_swd_swdio_en(true);\n\t} else {\n\t\t/* Queue a write transaction */\n\t\tftdi_swd_swdio_en(false);\n\n\t\tmpsse_clock_data_in(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn,\n\t\t\t\t0, 1 + 3 + 1, SWD_MODE);\n\n\t\tftdi_swd_swdio_en(true);\n\n\t\tbuf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 1, 32, data);\n\t\tbuf_set_u32(swd_cmd_queue[i].trn_ack_data_parity_trn, 1 + 3 + 1 + 32, 1, parity_u32(data));\n\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_cmd_queue[i].trn_ack_data_parity_trn,\n\t\t\t\t1 + 3 + 1, 32 + 1, SWD_MODE);\n\t}\n\n\t/* Insert idle cycles after AP accesses to avoid WAIT */\n\tif (cmd & SWD_CMD_APNDP)\n\t\tmpsse_clock_data_out(mpsse_ctx, NULL, 0, ap_delay_clk, SWD_MODE);\n\n}\n\nstatic void ftdi_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\tftdi_swd_queue_cmd(cmd, value, 0, ap_delay_clk);\n}\n\nstatic void ftdi_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\tftdi_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);\n}\n\nstatic int ftdi_swd_switch_seq(enum swd_special_seq seq)\n{\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG(\"SWD line reset\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_line_reset, 0, swd_seq_line_reset_len, SWD_MODE);\n\t\tbreak;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_jtag_to_swd, 0, swd_seq_jtag_to_swd_len, SWD_MODE);\n\t\tbreak;\n\tcase JTAG_TO_DORMANT:\n\t\tLOG_DEBUG(\"JTAG-to-DORMANT\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_jtag_to_dormant, 0, swd_seq_jtag_to_dormant_len, SWD_MODE);\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_swd_to_jtag, 0, swd_seq_swd_to_jtag_len, SWD_MODE);\n\t\tbreak;\n\tcase SWD_TO_DORMANT:\n\t\tLOG_DEBUG(\"SWD-to-DORMANT\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_swd_to_dormant, 0, swd_seq_swd_to_dormant_len, SWD_MODE);\n\t\tbreak;\n\tcase DORMANT_TO_SWD:\n\t\tLOG_DEBUG(\"DORMANT-to-SWD\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_dormant_to_swd, 0, swd_seq_dormant_to_swd_len, SWD_MODE);\n\t\tbreak;\n\tcase DORMANT_TO_JTAG:\n\t\tLOG_DEBUG(\"DORMANT-to-JTAG\");\n\t\tftdi_swd_swdio_en(true);\n\t\tmpsse_clock_data_out(mpsse_ctx, swd_seq_dormant_to_jtag, 0, swd_seq_dormant_to_jtag_len, SWD_MODE);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct swd_driver ftdi_swd = {\n\t.init = ftdi_swd_init,\n\t.switch_seq = ftdi_swd_switch_seq,\n\t.read_reg = ftdi_swd_read_reg,\n\t.write_reg = ftdi_swd_write_reg,\n\t.run = ftdi_swd_run_queue,\n};\n\nstatic const char * const ftdi_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface ftdi_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = ftdi_execute_queue,\n};\n\nstruct adapter_driver ftdi_adapter_driver = {\n\t.name = \"ftdi\",\n\t.transports = ftdi_transports,\n\t.commands = ftdi_command_handlers,\n\n\t.init = ftdi_initialize,\n\t.quit = ftdi_quit,\n\t.reset = ftdi_reset,\n\t.speed = ftdi_speed,\n\t.khz = ftdi_khz,\n\t.speed_div = ftdi_speed_div,\n\n\t.jtag_ops = &ftdi_interface,\n\t.swd_ops = &ftdi_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/gw16012.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n\n#if 1\n#define _DEBUG_GW16012_IO_\n#endif\n\n/* system includes */\n/*  -ino: 060521-1036 */\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\n#include <machine/sysarch.h>\n#include <machine/cpufunc.h>\n#define ioperm(startport, length, enable) \\\n\t386_set_ioperm((startport), (length), (enable))\n\n#else\n\n#endif /* __FreeBSD__, __FreeBSD_kernel__ */\n\n#if PARPORT_USE_PPDEV == 1\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n#include <dev/ppbus/ppi.h>\n#include <dev/ppbus/ppbconf.h>\n#define PPRSTATUS\tPPIGSTATUS\n#define PPWDATA\t\tPPISDATA\n#else\n#include <linux/parport.h>\n#include <linux/ppdev.h>\n#endif\n#include <fcntl.h>\n#include <sys/ioctl.h>\n#else /* not PARPORT_USE_PPDEV */\n#ifndef _WIN32\n#include <sys/io.h>\n#endif\n#endif\n\n#if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1\n#include <windows.h>\n#endif\n\n/* configuration */\nstatic uint16_t gw16012_port;\n\n/* interface variables\n */\nstatic uint8_t gw16012_msb;\nstatic uint8_t gw16012_control_value;\n\n#if PARPORT_USE_PPDEV == 1\nstatic int device_handle;\n#endif\n\nstatic void gw16012_data(uint8_t value)\n{\n\tvalue = (value & 0x7f) | gw16012_msb;\n\tgw16012_msb ^= 0x80; /* toggle MSB */\n\n#ifdef _DEBUG_GW16012_IO_\n\tLOG_DEBUG(\"%2.2x\", value);\n#endif\n\n\t#if PARPORT_USE_PPDEV == 1\n\t\tioctl(device_handle, PPWDATA, &value);\n\t#else\n\t\t#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\t\t\toutb(gw16012_port, value);\n\t\t#else\n\t\t\toutb(value, gw16012_port);\n\t\t#endif\n\t#endif\n}\n\nstatic void gw16012_control(uint8_t value)\n{\n\tif (value != gw16012_control_value) {\n\t\tgw16012_control_value = value;\n\n#ifdef _DEBUG_GW16012_IO_\n\t\tLOG_DEBUG(\"%2.2x\", gw16012_control_value);\n#endif\n\n\t\t#if PARPORT_USE_PPDEV == 1\n\t\t\tioctl(device_handle, PPWCONTROL, &gw16012_control_value);\n\t\t#else\n\t\t\t#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\t\t\t\toutb(gw16012_port + 2, gw16012_control_value);\n\t\t\t#else\n\t\t\t\toutb(gw16012_control_value, gw16012_port + 2);\n\t\t\t#endif\n\t\t#endif\n\t}\n}\n\nstatic void gw16012_input(uint8_t *value)\n{\n\t#if PARPORT_USE_PPDEV == 1\n\t\tioctl(device_handle, PPRSTATUS, value);\n\t#else\n\t\t*value = inb(gw16012_port + 1);\n\t#endif\n\n#ifdef _DEBUG_GW16012_IO_\n\tLOG_DEBUG(\"%2.2x\", *value);\n#endif\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic void gw16012_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (trst == 0)\n\t\tgw16012_control(0x0d);\n\telse if (trst == 1)\n\t\tgw16012_control(0x0c);\n\n\tif (srst == 0)\n\t\tgw16012_control(0x0a);\n\telse if (srst == 1)\n\t\tgw16012_control(0x0b);\n}\n\nstatic void gw16012_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void gw16012_state_move(void)\n{\n\tint i = 0, tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tgw16012_control(0x0); /* single-bit mode */\n\n\tfor (i = 0; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\tgw16012_data(tms << 1); /* output next TMS bit */\n\t}\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void gw16012_path_move(struct pathmove_command *cmd)\n{\n\tint num_states = cmd->num_states;\n\tint state_count;\n\n\tstate_count = 0;\n\twhile (num_states) {\n\t\tgw16012_control(0x0); /* single-bit mode */\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])\n\t\t\tgw16012_data(0x0); /* TCK cycle with TMS low */\n\t\telse if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])\n\t\t\tgw16012_data(0x2); /* TCK cycle with TMS high */\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\t\ttap_state_name(tap_get_state()), tap_state_name(cmd->path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(cmd->path[state_count]);\n\t\tstate_count++;\n\t\tnum_states--;\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void gw16012_runtest(int num_cycles)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\tint i;\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tgw16012_end_state(TAP_IDLE);\n\t\tgw16012_state_move();\n\t}\n\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tgw16012_control(0x0); /* single-bit mode */\n\t\tgw16012_data(0x0); /* TMS cycle with TMS low */\n\t}\n\n\tgw16012_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tgw16012_state_move();\n}\n\nstatic void gw16012_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)\n{\n\tint bits_left = scan_size;\n\tint bit_count = 0;\n\ttap_state_t saved_end_state = tap_get_end_state();\n\tuint8_t scan_out, scan_in;\n\n\t/* only if we're not already in the correct Shift state */\n\tif (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) ||\n\t\t\t(ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {\n\t\tif (ir_scan)\n\t\t\tgw16012_end_state(TAP_IRSHIFT);\n\t\telse\n\t\t\tgw16012_end_state(TAP_DRSHIFT);\n\n\t\tgw16012_state_move();\n\t\tgw16012_end_state(saved_end_state);\n\t}\n\n\twhile (type == SCAN_OUT && ((bits_left - 1) > 7)) {\n\t\tgw16012_control(0x2); /* seven-bit mode */\n\t\tscan_out = buf_get_u32(buffer, bit_count, 7);\n\t\tgw16012_data(scan_out);\n\t\tbit_count += 7;\n\t\tbits_left -= 7;\n\t}\n\n\tgw16012_control(0x0); /* single-bit mode */\n\twhile (bits_left-- > 0) {\n\t\tuint8_t tms = 0;\n\n\t\tscan_out = buf_get_u32(buffer, bit_count, 1);\n\n\t\tif (bits_left == 0) /* last bit */ {\n\t\t\tif ((ir_scan && (tap_get_end_state() == TAP_IRSHIFT))\n\t\t\t\t|| (!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))\n\t\t\t\ttms = 0;\n\t\t\telse\n\t\t\t\ttms = 2;\n\t\t}\n\n\t\tgw16012_data(scan_out | tms);\n\n\t\tif (type != SCAN_OUT) {\n\t\t\tgw16012_input(&scan_in);\n\t\t\tbuf_set_u32(buffer, bit_count, 1, ((scan_in & 0x08) >> 3));\n\t\t}\n\n\t\tbit_count++;\n\t}\n\n\tif (!((ir_scan && (tap_get_end_state() == TAP_IRSHIFT)) ||\n\t\t(!ir_scan && (tap_get_end_state() == TAP_DRSHIFT)))) {\n\t\tgw16012_data(0x0);\n\t\tif (ir_scan)\n\t\t\ttap_set_state(TAP_IRPAUSE);\n\t\telse\n\t\t\ttap_set_state(TAP_DRPAUSE);\n\n\t\tif (tap_get_state() != tap_get_end_state())\n\t\t\tgw16012_state_move();\n\t}\n}\n\nstatic int gw16012_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue; /* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\tint retval;\n\n\t/* return ERROR_OK, unless a jtag_read_buffer returns a failed check\n\t * that wasn't handled by a caller-provided error handler\n\t */\n\tretval = ERROR_OK;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tif (cmd->cmd.reset->trst == 1)\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\tgw16012_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\", cmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\tcmd->cmd.runtest->end_state);\n\t\t\t\tgw16012_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tgw16012_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\t\t\t\tgw16012_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tgw16012_state_move();\n\t\t\t\tbreak;\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\", cmd->cmd.pathmove->num_states,\n\t\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\t\t\t\tgw16012_path_move(cmd->cmd.pathmove);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tgw16012_end_state(cmd->cmd.scan->end_state);\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tLOG_DEBUG_IO(\"%s scan (%i) %i bit end in %i\", (cmd->cmd.scan->ir_scan) ? \"ir\" : \"dr\",\n\t\t\t\t\ttype, scan_size, cmd->cmd.scan->end_state);\n\t\t\t\tgw16012_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\n\t\t\t\tif (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\treturn retval;\n}\n\n#if PARPORT_USE_GIVEIO == 1\nstatic int gw16012_get_giveio_access(void)\n{\n\tHANDLE h;\n\tOSVERSIONINFO version;\n\n\tversion.dwOSVersionInfoSize = sizeof(version);\n\tif (!GetVersionEx(&version)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (version.dwPlatformId != VER_PLATFORM_WIN32_NT)\n\t\treturn 0;\n\n\th = CreateFile(\"\\\\\\\\.\\\\giveio\", GENERIC_READ, 0, NULL, OPEN_EXISTING,\n\t\t\tFILE_ATTRIBUTE_NORMAL, NULL);\n\tif (h == INVALID_HANDLE_VALUE) {\n\t\terrno = ENODEV;\n\t\treturn -1;\n\t}\n\n\tCloseHandle(h);\n\n\treturn 0;\n}\n#endif\n\n#if PARPORT_USE_PPDEV == 1\n\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\n#define GW16012_PPDEV_NAME\t\"ppi\"\n\nstatic int gw16012_init_ioctls(void)\n{\n\tint temp = 0;\n\ttemp = ioctl(device_handle, PPCLAIM);\n\tif (temp < 0) {\n\t\tLOG_ERROR(\"cannot claim device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ttemp = PARPORT_MODE_COMPAT;\n\ttemp = ioctl(device_handle, PPSETMODE, &temp);\n\tif (temp < 0) {\n\t\tLOG_ERROR(\" cannot set compatible mode to device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ttemp = IEEE1284_MODE_COMPAT;\n\ttemp = ioctl(device_handle, PPNEGOT, &temp);\n\tif (temp < 0) {\n\t\tLOG_ERROR(\"cannot set compatible 1284 mode to device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\treturn ERROR_OK;\n}\n#else\n\n#define GW16012_PPDEV_NAME\t\"parport\"\n\nstatic int gw16012_init_ioctls(void)\n{\n\treturn ERROR_OK;\n}\n\n#endif /* defined(__FreeBSD__) || defined(__FreeBSD_kernel__) */\n\nstatic int gw16012_init_device(void)\n{\n\tconst char *device_name = GW16012_PPDEV_NAME;\n\tchar buffer[256];\n\n\tif (device_handle > 0) {\n\t\tLOG_ERROR(\"device is already opened\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tsnprintf(buffer, 256, \"/dev/%s%d\", device_name, gw16012_port);\n\tLOG_DEBUG(\"opening %s...\", buffer);\n\n\tdevice_handle = open(buffer, O_WRONLY);\n\tif (device_handle < 0) {\n\t\tLOG_ERROR(\"cannot open device. check it exists and that user read and write rights are set\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_DEBUG(\"...open\");\n\n\tif (gw16012_init_ioctls() != ERROR_OK)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\treturn ERROR_OK;\n}\n\n#else /* PARPORT_USE_PPDEV */\n\nstatic int gw16012_init_device(void)\n{\n\tif (gw16012_port == 0) {\n\t\tgw16012_port = 0x378;\n\t\tLOG_WARNING(\"No gw16012 port specified, using default '0x378' (LPT1)\");\n\t}\n\n\tLOG_DEBUG(\"requesting privileges for parallel port 0x%\" PRIx16 \"...\", gw16012_port);\n#if PARPORT_USE_GIVEIO == 1\n\tif (gw16012_get_giveio_access() != 0) {\n#else /* PARPORT_USE_GIVEIO */\n\tif (ioperm(gw16012_port, 3, 1) != 0) {\n#endif /* PARPORT_USE_GIVEIO */\n\t\tLOG_ERROR(\"missing privileges for direct i/o\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tLOG_DEBUG(\"...privileges granted\");\n\n\t/* make sure parallel port is in right mode (clear tristate and interrupt */\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\toutb(gw16012_port + 2, 0x0);\n#else\n\toutb(0x0, gw16012_port + 2);\n#endif\n\treturn ERROR_OK;\n}\n\n#endif /* PARPORT_USE_PPDEV */\n\nstatic int gw16012_init(void)\n{\n\tuint8_t status_port;\n\n\tif (gw16012_init_device() != ERROR_OK)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\tgw16012_input(&status_port);\n\tgw16012_msb = (status_port & 0x80) ^ 0x80;\n\n\tgw16012_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int gw16012_quit(void)\n{\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(gw16012_handle_parport_port_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\t/* only if the port wasn't overwritten by cmdline */\n\t\tif (gw16012_port == 0)\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], gw16012_port);\n\t\telse {\n\t\t\tLOG_ERROR(\"The parport port was already configured!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"parport port = %u\", gw16012_port);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration gw16012_command_handlers[] = {\n\t{\n\t\t.name = \"parport_port\",\n\t\t.handler = gw16012_handle_parport_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Display the address of the I/O port (e.g. 0x378) \"\n\t\t\t\"or the number of the '/dev/parport' device used.  \"\n\t\t\t\"If a parameter is provided, first change that port.\",\n\t\t.usage = \"[port_number]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface gw16012_interface = {\n\t.execute_queue = gw16012_execute_queue,\n};\n\nstruct adapter_driver gw16012_adapter_driver = {\n\t.name = \"gw16012\",\n\t.transports = jtag_only,\n\t.commands = gw16012_command_handlers,\n\n\t.init = gw16012_init,\n\t.quit = gw16012_quit,\n\n\t.jtag_ops = &gw16012_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/imx_gpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Grzegorz Kostka, kostka.grzegorz@gmail.com      *\n *                                                                         *\n *   Based on bcm2835gpio.c                                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include \"bitbang.h\"\n\n#include <sys/mman.h>\n\n#define IMX_GPIO_BASE 0x0209c000\n#define IMX_GPIO_SIZE 0x00004000\n#define IMX_GPIO_REGS_COUNT 8\n\nstatic uint32_t imx_gpio_peri_base = IMX_GPIO_BASE;\n\nstruct imx_gpio_regs {\n\tuint32_t dr;\n\tuint32_t gdir;\n\tuint32_t psr;\n\tuint32_t icr1;\n\tuint32_t icr2;\n\tuint32_t imr;\n\tuint32_t isr;\n\tuint32_t edge_sel;\n} __attribute__((aligned(IMX_GPIO_SIZE)));\n\nstatic int dev_mem_fd;\nstatic volatile struct imx_gpio_regs *pio_base;\n\n/* GPIO setup functions */\nstatic inline bool gpio_mode_get(int g)\n{\n\treturn pio_base[g / 32].gdir >> (g & 0x1F) & 1;\n}\n\nstatic inline void gpio_mode_input_set(int g)\n{\n\tpio_base[g / 32].gdir &=  ~(1u << (g & 0x1F));\n}\n\nstatic inline void gpio_mode_output_set(int g)\n{\n\tpio_base[g / 32].gdir |=  (1u << (g & 0x1F));\n}\n\nstatic inline void gpio_mode_set(int g, int m)\n{\n\t(m) ? gpio_mode_output_set(g) : gpio_mode_input_set(g);\n}\n\nstatic inline void gpio_set(int g)\n{\n\tpio_base[g / 32].dr |=  (1u << (g & 0x1F));\n}\n\nstatic inline void gpio_clear(int g)\n{\n\tpio_base[g / 32].dr &=  ~(1u << (g & 0x1F));\n}\n\nstatic inline bool gpio_level(int g)\n{\n\treturn pio_base[g / 32].dr >> (g & 0x1F) & 1;\n}\n\nstatic bb_value_t imx_gpio_read(void);\nstatic int imx_gpio_write(int tck, int tms, int tdi);\n\nstatic int imx_gpio_swdio_read(void);\nstatic void imx_gpio_swdio_drive(bool is_output);\nstatic int imx_gpio_swd_write(int swclk, int swdio);\n\nstatic int imx_gpio_init(void);\nstatic int imx_gpio_quit(void);\n\nstatic struct bitbang_interface imx_gpio_bitbang = {\n\t.read = imx_gpio_read,\n\t.write = imx_gpio_write,\n\t.swdio_read = imx_gpio_swdio_read,\n\t.swdio_drive = imx_gpio_swdio_drive,\n\t.swd_write = imx_gpio_swd_write,\n\t.blink = NULL\n};\n\n/* GPIO numbers for each signal. Negative values are invalid */\nstatic int tck_gpio = -1;\nstatic int tck_gpio_mode;\nstatic int tms_gpio = -1;\nstatic int tms_gpio_mode;\nstatic int tdi_gpio = -1;\nstatic int tdi_gpio_mode;\nstatic int tdo_gpio = -1;\nstatic int tdo_gpio_mode;\nstatic int trst_gpio = -1;\nstatic int trst_gpio_mode;\nstatic int srst_gpio = -1;\nstatic int srst_gpio_mode;\nstatic int swclk_gpio = -1;\nstatic int swclk_gpio_mode;\nstatic int swdio_gpio = -1;\nstatic int swdio_gpio_mode;\n\n/* Transition delay coefficients. Tuned for IMX6UL 528MHz. Adjusted\n * experimentally for:10kHz, 100Khz, 500KHz. Speeds above 800Khz are impossible\n * to reach via memory mapped method (at least for IMX6UL@528MHz).\n * Measured mmap raw GPIO toggling speed on IMX6UL@528MHz: 1.3MHz.\n */\nstatic int speed_coeff = 50000;\nstatic int speed_offset = 100;\nstatic unsigned int jtag_delay;\n\nstatic bb_value_t imx_gpio_read(void)\n{\n\treturn gpio_level(tdo_gpio) ? BB_HIGH : BB_LOW;\n}\n\nstatic int imx_gpio_write(int tck, int tms, int tdi)\n{\n\ttms ? gpio_set(tms_gpio) : gpio_clear(tms_gpio);\n\ttdi ? gpio_set(tdi_gpio) : gpio_clear(tdi_gpio);\n\ttck ? gpio_set(tck_gpio) : gpio_clear(tck_gpio);\n\n\tfor (unsigned int i = 0; i < jtag_delay; i++)\n\t\tasm volatile (\"\");\n\n\treturn ERROR_OK;\n}\n\nstatic int imx_gpio_swd_write(int swclk, int swdio)\n{\n\tswdio ? gpio_set(swdio_gpio) : gpio_clear(swdio_gpio);\n\tswclk ? gpio_set(swclk_gpio) : gpio_clear(swclk_gpio);\n\n\tfor (unsigned int i = 0; i < jtag_delay; i++)\n\t\tasm volatile (\"\");\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int imx_gpio_reset(int trst, int srst)\n{\n\tif (trst_gpio != -1)\n\t\ttrst ? gpio_clear(trst_gpio) : gpio_set(trst_gpio);\n\n\tif (srst_gpio != -1)\n\t\tsrst ? gpio_clear(srst_gpio) : gpio_set(srst_gpio);\n\n\treturn ERROR_OK;\n}\n\nstatic void imx_gpio_swdio_drive(bool is_output)\n{\n\tif (is_output)\n\t\tgpio_mode_output_set(swdio_gpio);\n\telse\n\t\tgpio_mode_input_set(swdio_gpio);\n}\n\nstatic int imx_gpio_swdio_read(void)\n{\n\treturn gpio_level(swdio_gpio);\n}\n\nstatic int imx_gpio_khz(int khz, int *jtag_speed)\n{\n\tif (!khz) {\n\t\tLOG_DEBUG(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*jtag_speed = speed_coeff/khz - speed_offset;\n\tif (*jtag_speed < 0)\n\t\t*jtag_speed = 0;\n\treturn ERROR_OK;\n}\n\nstatic int imx_gpio_speed_div(int speed, int *khz)\n{\n\t*khz = speed_coeff/(speed + speed_offset);\n\treturn ERROR_OK;\n}\n\nstatic int imx_gpio_speed(int speed)\n{\n\tjtag_delay = speed;\n\treturn ERROR_OK;\n}\n\nstatic int is_gpio_valid(int gpio)\n{\n\treturn gpio >= 0 && gpio < 32 * IMX_GPIO_REGS_COUNT;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionums)\n{\n\tif (CMD_ARGC == 4) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);\n\t} else if (CMD_ARGC != 0) {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD,\n\t\t\t\"imx_gpio GPIO config: tck = %d, tms = %d, tdi = %d, tdo = %d\",\n\t\t\ttck_gpio, tms_gpio, tdi_gpio, tdo_gpio);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tck)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: tck = %d\", tck_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tms)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: tms = %d\", tms_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tdo)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: tdo = %d\", tdo_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_tdi)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: tdi = %d\", tdi_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_srst)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: srst = %d\", srst_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_jtag_gpionum_trst)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);\n\n\tcommand_print(CMD, \"imx_gpio GPIO config: trst = %d\", trst_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_swd_gpionums)\n{\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);\n\t} else if (CMD_ARGC != 0) {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD,\n\t\t\t\"imx_gpio GPIO nums: swclk = %d, swdio = %d\",\n\t\t\tswclk_gpio, swdio_gpio);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_swd_gpionum_swclk)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);\n\n\tcommand_print(CMD, \"imx_gpio num: swclk = %d\", swclk_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_swd_gpionum_swdio)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);\n\n\tcommand_print(CMD, \"imx_gpio num: swdio = %d\", swdio_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_speed_coeffs)\n{\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], speed_coeff);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], speed_offset);\n\t}\n\n\tcommand_print(CMD, \"imx_gpio: speed_coeffs = %d, speed_offset = %d\",\n\t\t\t\t  speed_coeff, speed_offset);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(imx_gpio_handle_peripheral_base)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], imx_gpio_peri_base);\n\n\tcommand_print(CMD, \"imx_gpio: peripheral_base = 0x%08x\",\n\t\t\t\t  imx_gpio_peri_base);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration imx_gpio_command_handlers[] = {\n\t{\n\t\t.name = \"imx_gpio_jtag_nums\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionums,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio numbers for tck, tms, tdi, tdo. (in that order)\",\n\t\t.usage = \"[tck tms tdi tdo]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_tck_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_tck,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tck.\",\n\t\t.usage = \"[tck]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_tms_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_tms,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tms.\",\n\t\t.usage = \"[tms]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_tdo_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_tdo,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdo.\",\n\t\t.usage = \"[tdo]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_tdi_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_tdi,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdi.\",\n\t\t.usage = \"[tdi]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_swd_nums\",\n\t\t.handler = &imx_gpio_handle_swd_gpionums,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio numbers for swclk, swdio. (in that order)\",\n\t\t.usage = \"[swclk swdio]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_swclk_num\",\n\t\t.handler = &imx_gpio_handle_swd_gpionum_swclk,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for swclk.\",\n\t\t.usage = \"[swclk]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_swdio_num\",\n\t\t.handler = &imx_gpio_handle_swd_gpionum_swdio,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for swdio.\",\n\t\t.usage = \"[swdio]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_srst_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_srst,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for srst.\",\n\t\t.usage = \"[srst]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_trst_num\",\n\t\t.handler = &imx_gpio_handle_jtag_gpionum_trst,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for trst.\",\n\t\t.usage = \"[trst]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_speed_coeffs\",\n\t\t.handler = &imx_gpio_handle_speed_coeffs,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"SPEED_COEFF and SPEED_OFFSET for delay calculations.\",\n\t\t.usage = \"[SPEED_COEFF SPEED_OFFSET]\",\n\t},\n\t{\n\t\t.name = \"imx_gpio_peripheral_base\",\n\t\t.handler = &imx_gpio_handle_peripheral_base,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"peripheral base to access GPIOs (0x0209c000 for most IMX).\",\n\t\t.usage = \"[base]\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const char * const imx_gpio_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface imx_gpio_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver imx_gpio_adapter_driver = {\n\t.name = \"imx_gpio\",\n\t.transports = imx_gpio_transports,\n\t.commands = imx_gpio_command_handlers,\n\n\t.init = imx_gpio_init,\n\t.quit = imx_gpio_quit,\n\t.reset = imx_gpio_reset,\n\t.speed = imx_gpio_speed,\n\t.khz = imx_gpio_khz,\n\t.speed_div = imx_gpio_speed_div,\n\n\t.jtag_ops = &imx_gpio_interface,\n\t.swd_ops = &bitbang_swd,\n};\n\nstatic bool imx_gpio_jtag_mode_possible(void)\n{\n\tif (!is_gpio_valid(tck_gpio))\n\t\treturn 0;\n\tif (!is_gpio_valid(tms_gpio))\n\t\treturn 0;\n\tif (!is_gpio_valid(tdi_gpio))\n\t\treturn 0;\n\tif (!is_gpio_valid(tdo_gpio))\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic bool imx_gpio_swd_mode_possible(void)\n{\n\tif (!is_gpio_valid(swclk_gpio))\n\t\treturn 0;\n\tif (!is_gpio_valid(swdio_gpio))\n\t\treturn 0;\n\treturn 1;\n}\n\nstatic int imx_gpio_init(void)\n{\n\tbitbang_interface = &imx_gpio_bitbang;\n\n\tLOG_INFO(\"imx_gpio GPIO JTAG/SWD bitbang driver\");\n\n\tif (transport_is_jtag() && !imx_gpio_jtag_mode_possible()) {\n\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios for JTAG mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (transport_is_swd() && !imx_gpio_swd_mode_possible()) {\n\t\tLOG_ERROR(\"Require swclk and swdio gpio for SWD mode\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tdev_mem_fd = open(\"/dev/mem\", O_RDWR | O_SYNC);\n\tif (dev_mem_fd < 0) {\n\t\tLOG_ERROR(\"open: %s\", strerror(errno));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_INFO(\"imx_gpio mmap: pagesize: %u, regionsize: %u\",\n\t\t\t(unsigned int) sysconf(_SC_PAGE_SIZE), IMX_GPIO_REGS_COUNT * IMX_GPIO_SIZE);\n\tpio_base = mmap(NULL, IMX_GPIO_REGS_COUNT * IMX_GPIO_SIZE,\n\t\t\t\tPROT_READ | PROT_WRITE,\n\t\t\t\tMAP_SHARED, dev_mem_fd, imx_gpio_peri_base);\n\n\tif (pio_base == MAP_FAILED) {\n\t\tLOG_ERROR(\"mmap: %s\", strerror(errno));\n\t\tclose(dev_mem_fd);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/*\n\t * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST\n\t * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.\n\t */\n\tif (transport_is_jtag()) {\n\t\ttdo_gpio_mode = gpio_mode_get(tdo_gpio);\n\t\ttdi_gpio_mode = gpio_mode_get(tdi_gpio);\n\t\ttck_gpio_mode = gpio_mode_get(tck_gpio);\n\t\ttms_gpio_mode = gpio_mode_get(tms_gpio);\n\n\t\tgpio_clear(tdi_gpio);\n\t\tgpio_clear(tck_gpio);\n\t\tgpio_set(tms_gpio);\n\n\t\tgpio_mode_input_set(tdo_gpio);\n\t\tgpio_mode_output_set(tdi_gpio);\n\t\tgpio_mode_output_set(tck_gpio);\n\t\tgpio_mode_output_set(tms_gpio);\n\n\t\tif (trst_gpio != -1) {\n\t\t\ttrst_gpio_mode = gpio_mode_get(trst_gpio);\n\t\t\tgpio_set(trst_gpio);\n\t\t\tgpio_mode_output_set(trst_gpio);\n\t\t}\n\t}\n\n\tif (transport_is_swd()) {\n\t\tswclk_gpio_mode = gpio_mode_get(swclk_gpio);\n\t\tswdio_gpio_mode = gpio_mode_get(swdio_gpio);\n\n\t\tgpio_clear(swdio_gpio);\n\t\tgpio_clear(swclk_gpio);\n\t\tgpio_mode_output_set(swclk_gpio);\n\t\tgpio_mode_output_set(swdio_gpio);\n\t}\n\n\tif (srst_gpio != -1) {\n\t\tsrst_gpio_mode = gpio_mode_get(srst_gpio);\n\t\tgpio_set(srst_gpio);\n\t\tgpio_mode_output_set(srst_gpio);\n\t}\n\n\tLOG_DEBUG(\"saved pinmux settings: tck %d tms %d tdi %d \"\n\t\t  \"tdo %d trst %d srst %d\", tck_gpio_mode, tms_gpio_mode,\n\t\t  tdi_gpio_mode, tdo_gpio_mode, trst_gpio_mode, srst_gpio_mode);\n\n\treturn ERROR_OK;\n}\n\nstatic int imx_gpio_quit(void)\n{\n\tif (transport_is_jtag()) {\n\t\tgpio_mode_set(tdo_gpio, tdo_gpio_mode);\n\t\tgpio_mode_set(tdi_gpio, tdi_gpio_mode);\n\t\tgpio_mode_set(tck_gpio, tck_gpio_mode);\n\t\tgpio_mode_set(tms_gpio, tms_gpio_mode);\n\n\t\tif (trst_gpio != -1)\n\t\t\tgpio_mode_set(trst_gpio, trst_gpio_mode);\n\t}\n\n\tif (transport_is_swd()) {\n\t\tgpio_mode_set(swclk_gpio, swclk_gpio_mode);\n\t\tgpio_mode_set(swdio_gpio, swdio_gpio_mode);\n\t}\n\n\tif (srst_gpio != -1)\n\t\tgpio_mode_set(srst_gpio, srst_gpio_mode);\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/jlink.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net>            *\n *   based on Dominic Rath's and Benedikt Sauter's usbprog.c               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Jean-Christophe PLAGNIOL-VIILARD                *\n *   plagnioj@jcrosoft.com                                                 *\n *                                                                         *\n *   Copyright (C) 2015 by Marc Schink                                     *\n *   openocd-dev@marcschink.de                                             *\n *                                                                         *\n *   Copyright (C) 2015 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <math.h>\n\n#include <jtag/interface.h>\n#include <jtag/swd.h>\n#include <jtag/commands.h>\n#include <jtag/adapter.h>\n#include <helper/replacements.h>\n#include <target/cortex_m.h>\n\n#include <libjaylink/libjaylink.h>\n\nstatic struct jaylink_context *jayctx;\nstatic struct jaylink_device_handle *devh;\nstatic struct jaylink_connection conn;\nstatic struct jaylink_connection connlist[JAYLINK_MAX_CONNECTIONS];\nstatic enum jaylink_jtag_version jtag_command_version;\nstatic uint8_t caps[JAYLINK_DEV_EXT_CAPS_SIZE];\n\nstatic uint32_t serial_number;\nstatic bool use_serial_number;\nstatic bool use_usb_location;\nstatic enum jaylink_usb_address usb_address;\nstatic bool use_usb_address;\nstatic enum jaylink_target_interface iface = JAYLINK_TIF_JTAG;\nstatic bool trace_enabled;\n\n#define JLINK_MAX_SPEED\t\t\t12000\n#define JLINK_TAP_BUFFER_SIZE\t2048\n\nstatic unsigned int swd_buffer_size = JLINK_TAP_BUFFER_SIZE;\n\n/* Maximum SWO frequency deviation. */\n#define SWO_MAX_FREQ_DEV\t0.03\n\n/* 256 byte non-volatile memory */\nstruct device_config {\n\tuint8_t\tusb_address;\n\t/* 0ffset 0x01 to 0x03 */\n\tuint8_t\treserved_1[3];\n\tuint32_t target_power;\n\t/* 0ffset 0x08 to 0x1f */\n\tuint8_t reserved_2[24];\n\t/* IP only for J-Link Pro */\n\tuint8_t ip_address[4];\n\tuint8_t subnet_mask[4];\n\t/* 0ffset 0x28 to 0x2f */\n\tuint8_t reserved_3[8];\n\tuint8_t mac_address[6];\n\t/* 0ffset 0x36 to 0xff */\n\tuint8_t reserved_4[202];\n} __attribute__ ((packed));\n\nstatic struct device_config config;\nstatic struct device_config tmp_config;\n\n/* Queue command functions */\nstatic void jlink_end_state(tap_state_t state);\nstatic void jlink_state_move(void);\nstatic void jlink_path_move(int num_states, tap_state_t *path);\nstatic void jlink_stableclocks(int num_cycles);\nstatic void jlink_runtest(int num_cycles);\nstatic void jlink_reset(int trst, int srst);\nstatic int jlink_reset_safe(int trst, int srst);\nstatic int jlink_swd_run_queue(void);\nstatic void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk);\nstatic int jlink_swd_switch_seq(enum swd_special_seq seq);\n\n/* J-Link tap buffer functions */\nstatic void jlink_tap_init(void);\nstatic int jlink_flush(void);\n/**\n * Queue data to go out and in, flushing the queue as many times as\n * necessary.\n *\n * @param out A pointer to TDI data, if NULL, old stale data will be used.\n * @param out_offset A bit offset for TDI data.\n * @param tms_out A pointer to TMS data, if NULL, zeroes will be emitted.\n * @param tms_offset A bit offset for TMS data.\n * @param in A pointer to store TDO data to, if NULL the data will be discarded.\n * @param in_offset A bit offset for TDO data.\n * @param length Amount of bits to transfer out and in.\n */\nstatic void jlink_clock_data(const uint8_t *out, unsigned out_offset,\n\t\t\t     const uint8_t *tms_out, unsigned tms_offset,\n\t\t\t     uint8_t *in, unsigned in_offset,\n\t\t\t     unsigned length);\n\nstatic enum tap_state jlink_last_state = TAP_RESET;\nstatic int queued_retval;\n\n/***************************************************************************/\n/* External interface implementation */\n\nstatic void jlink_execute_stableclocks(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"stableclocks %i cycles\", cmd->cmd.runtest->num_cycles);\n\tjlink_stableclocks(cmd->cmd.runtest->num_cycles);\n}\n\nstatic void jlink_execute_runtest(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\", cmd->cmd.runtest->num_cycles,\n\t\tcmd->cmd.runtest->end_state);\n\n\tjlink_end_state(cmd->cmd.runtest->end_state);\n\tjlink_runtest(cmd->cmd.runtest->num_cycles);\n}\n\nstatic void jlink_execute_statemove(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\n\tjlink_end_state(cmd->cmd.statemove->end_state);\n\tjlink_state_move();\n}\n\nstatic void jlink_execute_pathmove(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\tcmd->cmd.pathmove->num_states,\n\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\n\tjlink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);\n}\n\nstatic void jlink_execute_scan(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"%s type:%d\", cmd->cmd.scan->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\tjtag_scan_type(cmd->cmd.scan));\n\n\t/* Make sure there are no trailing fields with num_bits == 0, or the logic below will fail. */\n\twhile (cmd->cmd.scan->num_fields > 0\n\t\t\t&& cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 1].num_bits == 0) {\n\t\tcmd->cmd.scan->num_fields--;\n\t\tLOG_DEBUG(\"discarding trailing empty field\");\n\t}\n\n\tif (cmd->cmd.scan->num_fields == 0) {\n\t\tLOG_DEBUG(\"empty scan, doing nothing\");\n\t\treturn;\n\t}\n\n\tif (cmd->cmd.scan->ir_scan) {\n\t\tif (tap_get_state() != TAP_IRSHIFT) {\n\t\t\tjlink_end_state(TAP_IRSHIFT);\n\t\t\tjlink_state_move();\n\t\t}\n\t} else {\n\t\tif (tap_get_state() != TAP_DRSHIFT) {\n\t\t\tjlink_end_state(TAP_DRSHIFT);\n\t\t\tjlink_state_move();\n\t\t}\n\t}\n\n\tjlink_end_state(cmd->cmd.scan->end_state);\n\n\tstruct scan_field *field = cmd->cmd.scan->fields;\n\tunsigned scan_size = 0;\n\n\tfor (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {\n\t\tscan_size += field->num_bits;\n\t\tLOG_DEBUG_IO(\"%s%s field %d/%d %d bits\",\n\t\t\tfield->in_value ? \"in\" : \"\",\n\t\t\tfield->out_value ? \"out\" : \"\",\n\t\t\ti,\n\t\t\tcmd->cmd.scan->num_fields,\n\t\t\tfield->num_bits);\n\n\t\tif (i == cmd->cmd.scan->num_fields - 1 && tap_get_state() != tap_get_end_state()) {\n\t\t\t/* Last field, and we're leaving IRSHIFT/DRSHIFT. Clock last bit during tap\n\t\t\t * movement. This last field can't have length zero, it was checked above. */\n\t\t\tjlink_clock_data(field->out_value,\n\t\t\t\t\t 0,\n\t\t\t\t\t NULL,\n\t\t\t\t\t 0,\n\t\t\t\t\t field->in_value,\n\t\t\t\t\t 0,\n\t\t\t\t\t field->num_bits - 1);\n\t\t\tuint8_t last_bit = 0;\n\t\t\tif (field->out_value)\n\t\t\t\tbit_copy(&last_bit, 0, field->out_value, field->num_bits - 1, 1);\n\t\t\tuint8_t tms_bits = 0x01;\n\t\t\tjlink_clock_data(&last_bit,\n\t\t\t\t\t 0,\n\t\t\t\t\t &tms_bits,\n\t\t\t\t\t 0,\n\t\t\t\t\t field->in_value,\n\t\t\t\t\t field->num_bits - 1,\n\t\t\t\t\t 1);\n\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 1));\n\t\t\tjlink_clock_data(NULL,\n\t\t\t\t\t 0,\n\t\t\t\t\t &tms_bits,\n\t\t\t\t\t 1,\n\t\t\t\t\t NULL,\n\t\t\t\t\t 0,\n\t\t\t\t\t 1);\n\t\t\ttap_set_state(tap_state_transition(tap_get_state(), 0));\n\t\t} else\n\t\t\tjlink_clock_data(field->out_value,\n\t\t\t\t\t 0,\n\t\t\t\t\t NULL,\n\t\t\t\t\t 0,\n\t\t\t\t\t field->in_value,\n\t\t\t\t\t 0,\n\t\t\t\t\t field->num_bits);\n\t}\n\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\tjlink_end_state(tap_get_end_state());\n\t\tjlink_state_move();\n\t}\n\n\tLOG_DEBUG_IO(\"%s scan, %i bits, end in %s\",\n\t\t(cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\", scan_size,\n\t\ttap_state_name(tap_get_end_state()));\n}\n\nstatic void jlink_execute_sleep(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"sleep %\" PRIu32 \"\", cmd->cmd.sleep->us);\n\tjlink_flush();\n\tjtag_sleep(cmd->cmd.sleep->us);\n}\n\nstatic int jlink_execute_command(struct jtag_command *cmd)\n{\n\tswitch (cmd->type) {\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tjlink_execute_stableclocks(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tjlink_execute_runtest(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tjlink_execute_statemove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tjlink_execute_pathmove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tjlink_execute_scan(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tjlink_execute_sleep(cmd);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: Unknown JTAG command type encountered\");\n\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_execute_queue(void)\n{\n\tint ret;\n\tstruct jtag_command *cmd = jtag_command_queue;\n\n\twhile (cmd) {\n\t\tret = jlink_execute_command(cmd);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tcmd = cmd->next;\n\t}\n\n\treturn jlink_flush();\n}\n\nstatic int jlink_speed(int speed)\n{\n\tint ret;\n\tstruct jaylink_speed tmp;\n\tint max_speed;\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_SPEEDS)) {\n\t\tret = jaylink_get_speeds(devh, &tmp);\n\n\t\tif (ret != JAYLINK_OK) {\n\t\t\tLOG_ERROR(\"jaylink_get_speeds() failed: %s\",\n\t\t\t\tjaylink_strerror(ret));\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\ttmp.freq /= 1000;\n\t\tmax_speed = tmp.freq / tmp.div;\n\t} else {\n\t\tmax_speed = JLINK_MAX_SPEED;\n\t}\n\n\tif (!speed) {\n\t\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING)) {\n\t\t\tLOG_ERROR(\"Adaptive clocking is not supported by the device\");\n\t\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\t\t}\n\n\t\tspeed = JAYLINK_SPEED_ADAPTIVE_CLOCKING;\n\t} else if (speed > max_speed) {\n\t\tLOG_INFO(\"Reduced speed from %d kHz to %d kHz (maximum)\", speed,\n\t\t\tmax_speed);\n\t\tspeed = max_speed;\n\t}\n\n\tret = jaylink_set_speed(devh, speed);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_set_speed() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\n\treturn ERROR_OK;\n}\n\nstatic bool read_device_config(struct device_config *cfg)\n{\n\tint ret;\n\n\tret = jaylink_read_raw_config(devh, (uint8_t *)cfg);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_read_raw_config() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn false;\n\t}\n\n\tif (cfg->usb_address == 0xff)\n\t\tcfg->usb_address = 0x00;\n\n\tif (cfg->target_power == 0xffffffff)\n\t\tcfg->target_power = 0;\n\n\treturn true;\n}\n\nstatic int select_interface(void)\n{\n\tint ret;\n\tuint32_t interfaces;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SELECT_TIF)) {\n\t\tif (iface != JAYLINK_TIF_JTAG) {\n\t\t\tLOG_ERROR(\"Device supports JTAG transport only\");\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\tret = jaylink_get_available_interfaces(devh, &interfaces);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_available_interfaces() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (!(interfaces & (1 << iface))) {\n\t\tLOG_ERROR(\"Selected transport is not supported by the device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tret = jaylink_select_interface(devh, iface, NULL);\n\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"jaylink_select_interface() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_register(void)\n{\n\tint ret;\n\tsize_t i;\n\tbool handle_found;\n\tsize_t count;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER))\n\t\treturn ERROR_OK;\n\n\tret = jaylink_register(devh, &conn, connlist, &count);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_register() failed: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\thandle_found = false;\n\n\tfor (i = 0; i < count; i++) {\n\t\tif (connlist[i].handle == conn.handle) {\n\t\t\thandle_found = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!handle_found) {\n\t\tLOG_ERROR(\"Registration failed: maximum number of connections on the \"\n\t\t\t\"device reached\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n * Adjust the SWD transaction buffer size depending on the free device internal\n * memory. This ensures that the SWD transactions sent to the device do not\n * exceed the internal memory of the device.\n */\nstatic bool adjust_swd_buffer_size(void)\n{\n\tint ret;\n\tuint32_t tmp;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY))\n\t\treturn true;\n\n\tret = jaylink_get_free_memory(devh, &tmp);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_free_memory() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn false;\n\t}\n\n\tif (tmp < 143) {\n\t\tLOG_ERROR(\"Not enough free device internal memory: %\" PRIu32 \" bytes\", tmp);\n\t\treturn false;\n\t}\n\n\ttmp = MIN(JLINK_TAP_BUFFER_SIZE, (tmp - 16) / 2);\n\n\tif (tmp != swd_buffer_size) {\n\t\tswd_buffer_size = tmp;\n\t\tLOG_DEBUG(\"Adjusted SWD transaction buffer size to %u bytes\",\n\t\t\tswd_buffer_size);\n\t}\n\n\treturn true;\n}\n\nstatic int jaylink_log_handler(const struct jaylink_context *ctx,\n\t\tenum jaylink_log_level level, const char *format, va_list args,\n\t\tvoid *user_data)\n{\n\tenum log_levels tmp;\n\n\tswitch (level) {\n\tcase JAYLINK_LOG_LEVEL_ERROR:\n\t\ttmp = LOG_LVL_ERROR;\n\t\tbreak;\n\tcase JAYLINK_LOG_LEVEL_WARNING:\n\t\ttmp = LOG_LVL_WARNING;\n\t\tbreak;\n\t/*\n\t * Forward info messages to the debug output because they are more verbose\n\t * than info messages of OpenOCD.\n\t */\n\tcase JAYLINK_LOG_LEVEL_INFO:\n\tcase JAYLINK_LOG_LEVEL_DEBUG:\n\t\ttmp = LOG_LVL_DEBUG;\n\t\tbreak;\n\tcase JAYLINK_LOG_LEVEL_DEBUG_IO:\n\t\ttmp = LOG_LVL_DEBUG_IO;\n\t\tbreak;\n\tdefault:\n\t\ttmp = LOG_LVL_WARNING;\n\t}\n\n\tlog_vprintf_lf(tmp, __FILE__, __LINE__, __func__, format, args);\n\n\treturn 0;\n}\n\nstatic bool jlink_usb_location_equal(struct jaylink_device *dev)\n{\n\tint retval;\n\tuint8_t bus;\n\tuint8_t *ports;\n\tsize_t num_ports;\n\tbool equal = false;\n\n\tretval = jaylink_device_get_usb_bus_ports(dev, &bus, &ports, &num_ports);\n\n\tif (retval == JAYLINK_ERR_NOT_SUPPORTED) {\n\t\treturn false;\n\t} else if (retval != JAYLINK_OK) {\n\t\tLOG_WARNING(\"jaylink_device_get_usb_bus_ports() failed: %s\",\n\t\t\tjaylink_strerror(retval));\n\t\treturn false;\n\t}\n\n\tequal = adapter_usb_location_equal(bus, ports, num_ports);\n\tfree(ports);\n\n\treturn equal;\n}\n\n\nstatic int jlink_open_device(uint32_t ifaces, bool *found_device)\n{\n\tint ret = jaylink_discovery_scan(jayctx, ifaces);\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_discovery_scan() failed: %s\", jaylink_strerror(ret));\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tsize_t num_devices;\n\tstruct jaylink_device **devs;\n\tret = jaylink_get_devices(jayctx, &devs, &num_devices);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_devices() failed: %s\", jaylink_strerror(ret));\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tuse_usb_location = !!adapter_usb_get_location();\n\n\tif (!use_serial_number && !use_usb_address && !use_usb_location && num_devices > 1) {\n\t\tLOG_ERROR(\"Multiple devices found, specify the desired device\");\n\t\tjaylink_free_devices(devs, true);\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t*found_device = false;\n\n\tfor (size_t i = 0; devs[i]; i++) {\n\t\tstruct jaylink_device *dev = devs[i];\n\n\t\tif (use_serial_number) {\n\t\t\tuint32_t tmp;\n\t\t\tret = jaylink_device_get_serial_number(dev, &tmp);\n\n\t\t\tif (ret == JAYLINK_ERR_NOT_AVAILABLE) {\n\t\t\t\tcontinue;\n\t\t\t} else if (ret != JAYLINK_OK) {\n\t\t\t\tLOG_WARNING(\"jaylink_device_get_serial_number() failed: %s\",\n\t\t\t\t\tjaylink_strerror(ret));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (serial_number != tmp)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (use_usb_address) {\n\t\t\tenum jaylink_usb_address address;\n\t\t\tret = jaylink_device_get_usb_address(dev, &address);\n\n\t\t\tif (ret == JAYLINK_ERR_NOT_SUPPORTED) {\n\t\t\t\tcontinue;\n\t\t\t} else if (ret != JAYLINK_OK) {\n\t\t\t\tLOG_WARNING(\"jaylink_device_get_usb_address() failed: %s\",\n\t\t\t\t\tjaylink_strerror(ret));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (usb_address != address)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (use_usb_location && !jlink_usb_location_equal(dev))\n\t\t\tcontinue;\n\n\t\tret = jaylink_open(dev, &devh);\n\n\t\tif (ret == JAYLINK_OK) {\n\t\t\t*found_device = true;\n\t\t\tbreak;\n\t\t}\n\n\t\tLOG_ERROR(\"Failed to open device: %s\", jaylink_strerror(ret));\n\t}\n\n\tjaylink_free_devices(devs, true);\n\treturn ERROR_OK;\n}\n\n\nstatic int jlink_init(void)\n{\n\tint ret;\n\tchar *firmware_version;\n\tstruct jaylink_hardware_version hwver;\n\tstruct jaylink_hardware_status hwstatus;\n\tsize_t length;\n\n\tLOG_DEBUG(\"Using libjaylink %s (compiled with %s)\",\n\t\tjaylink_version_package_get_string(), JAYLINK_VERSION_PACKAGE_STRING);\n\n\tif (!jaylink_library_has_cap(JAYLINK_CAP_HIF_USB) && use_usb_address) {\n\t\tLOG_ERROR(\"J-Link driver does not support USB devices\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tret = jaylink_init(&jayctx);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_init() failed: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tret = jaylink_log_set_callback(jayctx, &jaylink_log_handler, NULL);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_log_set_callback() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tconst char *serial = adapter_get_required_serial();\n\tif (serial) {\n\t\tret = jaylink_parse_serial_number(serial, &serial_number);\n\t\tif (ret == JAYLINK_ERR) {\n\t\t\tLOG_ERROR(\"Invalid serial number: %s\", serial);\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t\tif (ret != JAYLINK_OK) {\n\t\t\tLOG_ERROR(\"jaylink_parse_serial_number() failed: %s\", jaylink_strerror(ret));\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t\tuse_serial_number = true;\n\t\tuse_usb_address = false;\n\t}\n\n\tbool found_device;\n\tret = jlink_open_device(JAYLINK_HIF_USB, &found_device);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (!found_device && use_serial_number) {\n\t\tret = jlink_open_device(JAYLINK_HIF_TCP, &found_device);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tif (!found_device) {\n\t\tLOG_ERROR(\"No J-Link device found\");\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/*\n\t * Be careful with changing the following initialization sequence because\n\t * some devices are known to be sensitive regarding the order.\n\t */\n\n\tret = jaylink_get_firmware_version(devh, &firmware_version, &length);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_firmware_version() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\tjaylink_close(devh);\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t} else if (length > 0) {\n\t\tLOG_INFO(\"%s\", firmware_version);\n\t\tfree(firmware_version);\n\t} else {\n\t\tLOG_WARNING(\"Device responds empty firmware version string\");\n\t}\n\n\tmemset(caps, 0, JAYLINK_DEV_EXT_CAPS_SIZE);\n\tret = jaylink_get_caps(devh, caps);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_caps() failed: %s\", jaylink_strerror(ret));\n\t\tjaylink_close(devh);\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_EXT_CAPS)) {\n\t\tret = jaylink_get_extended_caps(devh, caps);\n\n\t\tif (ret != JAYLINK_OK) {\n\t\t\tLOG_ERROR(\"jaylink_get_extended_caps() failed:  %s\",\n\t\t\t\tjaylink_strerror(ret));\n\t\t\tjaylink_close(devh);\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t}\n\n\tjtag_command_version = JAYLINK_JTAG_VERSION_2;\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_HW_VERSION)) {\n\t\tret = jaylink_get_hardware_version(devh, &hwver);\n\n\t\tif (ret != JAYLINK_OK) {\n\t\t\tLOG_ERROR(\"Failed to retrieve hardware version: %s\",\n\t\t\t\tjaylink_strerror(ret));\n\t\t\tjaylink_close(devh);\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\n\t\tLOG_INFO(\"Hardware version: %u.%02u\", hwver.major, hwver.minor);\n\n\t\tif (hwver.major >= 5)\n\t\t\tjtag_command_version = JAYLINK_JTAG_VERSION_3;\n\t}\n\n\tif (iface == JAYLINK_TIF_SWD) {\n\t\t/*\n\t\t * Adjust the SWD transaction buffer size in case there is already\n\t\t * allocated memory on the device. This happens for example if the\n\t\t * memory for SWO capturing is still allocated because the software\n\t\t * which used the device before has not been shut down properly.\n\t\t */\n\t\tif (!adjust_swd_buffer_size()) {\n\t\t\tjaylink_close(devh);\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\t}\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tif (!read_device_config(&config)) {\n\t\t\tLOG_ERROR(\"Failed to read device configuration data\");\n\t\t\tjaylink_close(devh);\n\t\t\tjaylink_exit(jayctx);\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\n\t\tmemcpy(&tmp_config, &config, sizeof(struct device_config));\n\t}\n\n\tret = jaylink_get_hardware_status(devh, &hwstatus);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_hardware_status() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\tjaylink_close(devh);\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_INFO(\"VTarget = %u.%03u V\", hwstatus.target_voltage / 1000,\n\t\thwstatus.target_voltage % 1000);\n\n\tconn.handle = 0;\n\tconn.pid = 0;\n\tstrcpy(conn.hid, \"0.0.0.0\");\n\tconn.iid = 0;\n\tconn.cid = 0;\n\n\tret = jlink_register();\n\n\tif (ret != ERROR_OK) {\n\t\tjaylink_close(devh);\n\t\tjaylink_exit(jayctx);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tret = select_interface();\n\n\tif (ret != ERROR_OK) {\n\t\tjaylink_close(devh);\n\t\tjaylink_exit(jayctx);\n\t\treturn ret;\n\t}\n\n\tjlink_reset(0, 0);\n\tjtag_sleep(3000);\n\tjlink_tap_init();\n\n\tjlink_speed(adapter_get_speed_khz());\n\n\tif (iface == JAYLINK_TIF_JTAG) {\n\t\t/*\n\t\t * J-Link devices with firmware version v5 and v6 seems to have an issue\n\t\t * if the first tap move is not divisible by 8, so we send a TLR on\n\t\t * first power up.\n\t\t */\n\t\tuint8_t tms = 0xff;\n\t\tjlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 8);\n\n\t\tjlink_flush();\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_quit(void)\n{\n\tint ret;\n\tsize_t count;\n\n\tif (trace_enabled) {\n\t\tret = jaylink_swo_stop(devh);\n\n\t\tif (ret != JAYLINK_OK)\n\t\t\tLOG_ERROR(\"jaylink_swo_stop() failed: %s\", jaylink_strerror(ret));\n\t}\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_REGISTER)) {\n\t\tret = jaylink_unregister(devh, &conn, connlist, &count);\n\n\t\tif (ret != JAYLINK_OK)\n\t\t\tLOG_ERROR(\"jaylink_unregister() failed: %s\",\n\t\t\t\tjaylink_strerror(ret));\n\t}\n\n\tjaylink_close(devh);\n\tjaylink_exit(jayctx);\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************/\n/* Queue command implementations */\n\nstatic void jlink_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\n/* Goes to the end state. */\nstatic void jlink_state_move(void)\n{\n\tuint8_t tms_scan;\n\tuint8_t tms_scan_bits;\n\n\ttms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\ttms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tjlink_clock_data(NULL, 0, &tms_scan, 0, NULL, 0, tms_scan_bits);\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void jlink_path_move(int num_states, tap_state_t *path)\n{\n\tint i;\n\tuint8_t tms = 0xff;\n\n\tfor (i = 0; i < num_states; i++) {\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false))\n\t\t\tjlink_clock_data(NULL, 0, NULL, 0, NULL, 0, 1);\n\t\telse if (path[i] == tap_state_transition(tap_get_state(), true))\n\t\t\tjlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()), tap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void jlink_stableclocks(int num_cycles)\n{\n\tint i;\n\n\tuint8_t tms = tap_get_state() == TAP_RESET;\n\t/* Execute num_cycles. */\n\tfor (i = 0; i < num_cycles; i++)\n\t\tjlink_clock_data(NULL, 0, &tms, 0, NULL, 0, 1);\n}\n\nstatic void jlink_runtest(int num_cycles)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* Only do a state_move when we're not already in IDLE. */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tjlink_end_state(TAP_IDLE);\n\t\tjlink_state_move();\n\t\t/* num_cycles--; */\n\t}\n\n\tjlink_stableclocks(num_cycles);\n\n\t/* Finish in end_state. */\n\tjlink_end_state(saved_end_state);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tjlink_state_move();\n}\n\nstatic void jlink_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"TRST: %i, SRST: %i\", trst, srst);\n\n\t/* Signals are active low. */\n\tif (srst == 0)\n\t\tjaylink_set_reset(devh);\n\n\tif (srst == 1)\n\t\tjaylink_clear_reset(devh);\n\n\tif (trst == 1)\n\t\tjaylink_jtag_clear_trst(devh);\n\n\tif (trst == 0)\n\t\tjaylink_jtag_set_trst(devh);\n}\n\nstatic int jlink_reset_safe(int trst, int srst)\n{\n\tjlink_flush();\n\tjlink_reset(trst, srst);\n\treturn jlink_flush();\n}\n\nCOMMAND_HANDLER(jlink_usb_command)\n{\n\tint tmp;\n\n\tif (CMD_ARGC != 1) {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink usb\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (sscanf(CMD_ARGV[0], \"%i\", &tmp) != 1) {\n\t\tcommand_print(CMD, \"Invalid USB address: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (tmp < JAYLINK_USB_ADDRESS_0 || tmp > JAYLINK_USB_ADDRESS_3) {\n\t\tcommand_print(CMD, \"Invalid USB address: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tusb_address = tmp;\n\n\tuse_usb_address = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_hwstatus_command)\n{\n\tint ret;\n\tstruct jaylink_hardware_status status;\n\n\tret = jaylink_get_hardware_status(devh, &status);\n\n\tif (ret != JAYLINK_OK) {\n\t\tcommand_print(CMD, \"jaylink_get_hardware_status() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(CMD, \"VTarget = %u.%03u V\",\n\t\tstatus.target_voltage / 1000, status.target_voltage % 1000);\n\n\tcommand_print(CMD, \"TCK = %u TDI = %u TDO = %u TMS = %u SRST = %u \"\n\t\t\"TRST = %u\", status.tck, status.tdi, status.tdo, status.tms,\n\t\tstatus.tres, status.trst);\n\n\tif (status.target_voltage < 1500)\n\t\tcommand_print(CMD, \"Target voltage too low. Check target power\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_free_memory_command)\n{\n\tint ret;\n\tuint32_t tmp;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY)) {\n\t\tcommand_print(CMD, \"Retrieval of free memory is not supported by \"\n\t\t\t\"the device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tret = jaylink_get_free_memory(devh, &tmp);\n\n\tif (ret != JAYLINK_OK) {\n\t\tcommand_print(CMD, \"jaylink_get_free_memory() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(CMD, \"Device has %\" PRIu32 \" bytes of free memory\", tmp);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_jlink_jtag_command)\n{\n\tint tmp;\n\tint version;\n\n\tif (!CMD_ARGC) {\n\t\tswitch (jtag_command_version) {\n\t\t\tcase JAYLINK_JTAG_VERSION_2:\n\t\t\t\tversion = 2;\n\t\t\t\tbreak;\n\t\t\tcase JAYLINK_JTAG_VERSION_3:\n\t\t\t\tversion = 3;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tcommand_print(CMD, \"JTAG command version: %i\", version);\n\t} else if (CMD_ARGC == 1) {\n\t\tif (sscanf(CMD_ARGV[0], \"%i\", &tmp) != 1) {\n\t\t\tcommand_print(CMD, \"Invalid argument: %s\", CMD_ARGV[0]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tswitch (tmp) {\n\t\t\tcase 2:\n\t\t\t\tjtag_command_version = JAYLINK_JTAG_VERSION_2;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tjtag_command_version = JAYLINK_JTAG_VERSION_3;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcommand_print(CMD, \"Invalid argument: %s\", CMD_ARGV[0]);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t} else {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink jtag\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_target_power_command)\n{\n\tint ret;\n\tint enable;\n\n\tif (CMD_ARGC != 1) {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink targetpower\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {\n\t\tcommand_print(CMD, \"Target power supply is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!strcmp(CMD_ARGV[0], \"on\")) {\n\t\tenable = true;\n\t} else if (!strcmp(CMD_ARGV[0], \"off\")) {\n\t\tenable = false;\n\t} else {\n\t\tcommand_print(CMD, \"Invalid argument: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = jaylink_set_target_power(devh, enable);\n\n\tif (ret != JAYLINK_OK) {\n\t\tcommand_print(CMD, \"jaylink_set_target_power() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void show_config_usb_address(struct command_invocation *cmd)\n{\n\tif (config.usb_address != tmp_config.usb_address)\n\t\tcommand_print(cmd, \"USB address: %u [%u]\", config.usb_address,\n\t\t\ttmp_config.usb_address);\n\telse\n\t\tcommand_print(cmd, \"USB address: %u\", config.usb_address);\n}\n\nstatic void show_config_ip_address(struct command_invocation *cmd)\n{\n\tif (!memcmp(config.ip_address, tmp_config.ip_address, 4))\n\t\tcommand_print(cmd, \"IP address: %d.%d.%d.%d\",\n\t\t\tconfig.ip_address[3], config.ip_address[2],\n\t\t\tconfig.ip_address[1], config.ip_address[0]);\n\telse\n\t\tcommand_print(cmd, \"IP address: %d.%d.%d.%d [%d.%d.%d.%d]\",\n\t\t\tconfig.ip_address[3], config.ip_address[2],\n\t\t\tconfig.ip_address[1], config.ip_address[0],\n\t\t\ttmp_config.ip_address[3], tmp_config.ip_address[2],\n\t\t\ttmp_config.ip_address[1], tmp_config.ip_address[0]);\n\n\tif (!memcmp(config.subnet_mask, tmp_config.subnet_mask, 4))\n\t\tcommand_print(cmd, \"Subnet mask: %d.%d.%d.%d\",\n\t\t\tconfig.subnet_mask[3], config.subnet_mask[2],\n\t\t\tconfig.subnet_mask[1], config.subnet_mask[0]);\n\telse\n\t\tcommand_print(cmd, \"Subnet mask: %d.%d.%d.%d [%d.%d.%d.%d]\",\n\t\t\tconfig.subnet_mask[3], config.subnet_mask[2],\n\t\t\tconfig.subnet_mask[1], config.subnet_mask[0],\n\t\t\ttmp_config.subnet_mask[3], tmp_config.subnet_mask[2],\n\t\t\ttmp_config.subnet_mask[1], tmp_config.subnet_mask[0]);\n}\n\nstatic void show_config_mac_address(struct command_invocation *cmd)\n{\n\tif (!memcmp(config.mac_address, tmp_config.mac_address, 6))\n\t\tcommand_print(cmd, \"MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\",\n\t\t\tconfig.mac_address[5], config.mac_address[4],\n\t\t\tconfig.mac_address[3], config.mac_address[2],\n\t\t\tconfig.mac_address[1], config.mac_address[0]);\n\telse\n\t\tcommand_print(cmd, \"MAC address: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x \"\n\t\t\t\"[%.02x:%.02x:%.02x:%.02x:%.02x:%.02x]\",\n\t\t\tconfig.mac_address[5], config.mac_address[4],\n\t\t\tconfig.mac_address[3], config.mac_address[2],\n\t\t\tconfig.mac_address[1], config.mac_address[0],\n\t\t\ttmp_config.mac_address[5], tmp_config.mac_address[4],\n\t\t\ttmp_config.mac_address[3], tmp_config.mac_address[2],\n\t\t\ttmp_config.mac_address[1], tmp_config.mac_address[0]);\n}\n\nstatic void show_config_target_power(struct command_invocation *cmd)\n{\n\tconst char *target_power;\n\tconst char *current_target_power;\n\n\tif (!config.target_power)\n\t\ttarget_power = \"off\";\n\telse\n\t\ttarget_power = \"on\";\n\n\tif (!tmp_config.target_power)\n\t\tcurrent_target_power = \"off\";\n\telse\n\t\tcurrent_target_power = \"on\";\n\n\tif (config.target_power != tmp_config.target_power)\n\t\tcommand_print(cmd, \"Target power supply: %s [%s]\", target_power,\n\t\t\tcurrent_target_power);\n\telse\n\t\tcommand_print(cmd, \"Target power supply: %s\", target_power);\n}\n\nstatic void show_config(struct command_invocation *cmd)\n{\n\tcommand_print(cmd, \"J-Link device configuration:\");\n\n\tshow_config_usb_address(cmd);\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER))\n\t\tshow_config_target_power(cmd);\n\n\tif (jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) {\n\t\tshow_config_ip_address(cmd);\n\t\tshow_config_mac_address(cmd);\n\t}\n}\n\nstatic int poll_trace(uint8_t *buf, size_t *size)\n{\n\tint ret;\n\tuint32_t length;\n\n\tlength = *size;\n\n\tret = jaylink_swo_read(devh, buf, &length);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_swo_read() failed: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*size = length;\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t calculate_trace_buffer_size(void)\n{\n\tint ret;\n\tuint32_t tmp;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_GET_FREE_MEMORY))\n\t\treturn 0;\n\n\tret = jaylink_get_free_memory(devh, &tmp);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_get_free_memory() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (tmp > 0x3fff || tmp <= 0x600)\n\t\ttmp = tmp >> 1;\n\telse\n\t\ttmp = tmp - 0x400;\n\n\treturn tmp & 0xffffff00;\n}\n\nstatic bool calculate_swo_prescaler(unsigned int traceclkin_freq,\n\t\tuint32_t trace_freq, uint16_t *prescaler)\n{\n\tunsigned int presc = (traceclkin_freq + trace_freq / 2) / trace_freq;\n\tif (presc == 0 || presc > TPIU_ACPR_MAX_SWOSCALER + 1)\n\t\treturn false;\n\n\t/* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */\n\tunsigned int max_deviation = (traceclkin_freq * 3) / 100;\n\tif (presc * trace_freq < traceclkin_freq - max_deviation ||\n\t    presc * trace_freq > traceclkin_freq + max_deviation)\n\t\treturn false;\n\n\t*prescaler = presc;\n\n\treturn true;\n}\n\nstatic bool detect_swo_freq_and_prescaler(struct jaylink_swo_speed speed,\n\t\tunsigned int traceclkin_freq, unsigned int *trace_freq,\n\t\tuint16_t *prescaler)\n{\n\tuint32_t divider;\n\tunsigned int presc;\n\tdouble deviation;\n\n\tfor (divider = speed.min_div; divider <= speed.max_div; divider++) {\n\t\t*trace_freq = speed.freq / divider;\n\t\tpresc = ((1.0 - SWO_MAX_FREQ_DEV) * traceclkin_freq) / *trace_freq + 1;\n\n\t\tif (presc > TPIU_ACPR_MAX_SWOSCALER + 1)\n\t\t\tbreak;\n\n\t\tdeviation = fabs(1.0 - ((double)*trace_freq * presc / traceclkin_freq));\n\n\t\tif (deviation <= SWO_MAX_FREQ_DEV) {\n\t\t\t*prescaler = presc;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\nstatic int config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,\n\t\tuint32_t port_size, unsigned int *trace_freq,\n\t\tunsigned int traceclkin_freq, uint16_t *prescaler)\n{\n\tint ret;\n\tuint32_t buffer_size;\n\tstruct jaylink_swo_speed speed;\n\tuint32_t divider;\n\tuint32_t min_freq;\n\tuint32_t max_freq;\n\n\ttrace_enabled = enabled;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SWO)) {\n\t\tif (!enabled)\n\t\t\treturn ERROR_OK;\n\n\t\tLOG_ERROR(\"Trace capturing is not supported by the device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = jaylink_swo_stop(devh);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_swo_stop() failed: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!enabled) {\n\t\t/*\n\t\t * Adjust the SWD transaction buffer size as stopping SWO capturing\n\t\t * deallocates device internal memory.\n\t\t */\n\t\tif (!adjust_swd_buffer_size())\n\t\t\treturn ERROR_FAIL;\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) {\n\t\tLOG_ERROR(\"Selected pin protocol is not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbuffer_size = calculate_trace_buffer_size();\n\n\tif (!buffer_size) {\n\t\tLOG_ERROR(\"Not enough free device memory to start trace capturing\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = jaylink_swo_get_speeds(devh, JAYLINK_SWO_MODE_UART, &speed);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_swo_get_speeds() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (*trace_freq > 0) {\n\t\tdivider = speed.freq / *trace_freq;\n\t\tmin_freq = speed.freq / speed.max_div;\n\t\tmax_freq = speed.freq / speed.min_div;\n\n\t\tif (*trace_freq > max_freq) {\n\t\t\tLOG_INFO(\"Given SWO frequency too high, using %\" PRIu32 \" Hz instead\",\n\t\t\t\tmax_freq);\n\t\t\t*trace_freq = max_freq;\n\t\t} else if (*trace_freq < min_freq) {\n\t\t\tLOG_INFO(\"Given SWO frequency too low, using %\" PRIu32 \" Hz instead\",\n\t\t\t\tmin_freq);\n\t\t\t*trace_freq = min_freq;\n\t\t} else if (*trace_freq != speed.freq / divider) {\n\t\t\t*trace_freq = speed.freq / divider;\n\n\t\t\tLOG_INFO(\"Given SWO frequency is not supported by the device, \"\n\t\t\t\t\"using %u Hz instead\", *trace_freq);\n\t\t}\n\n\t\tif (!calculate_swo_prescaler(traceclkin_freq, *trace_freq,\n\t\t\t\tprescaler)) {\n\t\t\tLOG_ERROR(\"SWO frequency is not suitable. Please choose a \"\n\t\t\t\t\"different frequency or use auto-detection\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tLOG_INFO(\"Trying to auto-detect SWO frequency\");\n\n\t\tif (!detect_swo_freq_and_prescaler(speed, traceclkin_freq, trace_freq,\n\t\t\t\tprescaler)) {\n\t\t\tLOG_ERROR(\"Maximum permitted frequency deviation of %.02f %% \"\n\t\t\t\t\"could not be achieved\", SWO_MAX_FREQ_DEV);\n\t\t\tLOG_ERROR(\"Auto-detection of SWO frequency failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_INFO(\"Using SWO frequency of %u Hz\", *trace_freq);\n\t}\n\n\tret = jaylink_swo_start(devh, JAYLINK_SWO_MODE_UART, *trace_freq,\n\t\tbuffer_size);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_start_swo() failed: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Using %\" PRIu32 \" bytes device memory for trace capturing\",\n\t\tbuffer_size);\n\n\t/*\n\t * Adjust the SWD transaction buffer size as starting SWO capturing\n\t * allocates device internal memory.\n\t */\n\tif (!adjust_swd_buffer_size())\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_config_usb_address_command)\n{\n\tuint8_t tmp;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Reading configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!CMD_ARGC) {\n\t\tshow_config_usb_address(CMD);\n\t} else if (CMD_ARGC == 1) {\n\t\tif (sscanf(CMD_ARGV[0], \"%\" SCNd8, &tmp) != 1) {\n\t\t\tcommand_print(CMD, \"Invalid USB address: %s\", CMD_ARGV[0]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (tmp > JAYLINK_USB_ADDRESS_3) {\n\t\t\tcommand_print(CMD, \"Invalid USB address: %u\", tmp);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\ttmp_config.usb_address = tmp;\n\t} else {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink config usb\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_config_target_power_command)\n{\n\tint enable;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Reading configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_SET_TARGET_POWER)) {\n\t\tcommand_print(CMD, \"Target power supply is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!CMD_ARGC) {\n\t\tshow_config_target_power(CMD);\n\t} else if (CMD_ARGC == 1) {\n\t\tif (!strcmp(CMD_ARGV[0], \"on\")) {\n\t\t\tenable = true;\n\t\t} else if (!strcmp(CMD_ARGV[0], \"off\")) {\n\t\t\tenable = false;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"Invalid argument: %s\", CMD_ARGV[0]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\ttmp_config.target_power = enable;\n\t} else {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink config \"\n\t\t\t\"targetpower\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_config_mac_address_command)\n{\n\tuint8_t addr[6];\n\tint i;\n\tchar *e;\n\tconst char *str;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Reading configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) {\n\t\tcommand_print(CMD, \"Ethernet connectivity is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!CMD_ARGC) {\n\t\tshow_config_mac_address(CMD);\n\t} else if (CMD_ARGC == 1) {\n\t\tstr = CMD_ARGV[0];\n\n\t\tif ((strlen(str) != 17) || (str[2] != ':' || str[5] != ':' ||\n\t\t\t\tstr[8] != ':' || str[11] != ':' || str[14] != ':')) {\n\t\t\tcommand_print(CMD, \"Invalid MAC address format\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tfor (i = 5; i >= 0; i--) {\n\t\t\taddr[i] = strtoul(str, &e, 16);\n\t\t\tstr = e + 1;\n\t\t}\n\n\t\tif (!(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5])) {\n\t\t\tcommand_print(CMD, \"Invalid MAC address: zero address\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (!(0x01 & addr[0])) {\n\t\t\tcommand_print(CMD, \"Invalid MAC address: multicast address\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tmemcpy(tmp_config.mac_address, addr, sizeof(addr));\n\t} else {\n\t\tcommand_print(CMD, \"Need exactly one argument for jlink config mac\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool string_to_ip(const char *s, uint8_t *ip, int *pos)\n{\n\tuint8_t lip[4];\n\tchar *e;\n\tconst char *s_save = s;\n\tint i;\n\n\tif (!s)\n\t\treturn false;\n\n\tfor (i = 0; i < 4; i++) {\n\t\tlip[i] = strtoul(s, &e, 10);\n\n\t\tif (*e != '.' && i != 3)\n\t\t\treturn false;\n\n\t\ts = e + 1;\n\t}\n\n\t*pos = e - s_save;\n\tmemcpy(ip, lip, sizeof(lip));\n\n\treturn true;\n}\n\nstatic void cpy_ip(uint8_t *dst, uint8_t *src)\n{\n\tint i, j;\n\n\tfor (i = 0, j = 3; i < 4; i++, j--)\n\t\tdst[i] = src[j];\n}\n\nCOMMAND_HANDLER(jlink_handle_config_ip_address_command)\n{\n\tuint8_t ip_address[4];\n\tuint32_t subnet_mask = 0;\n\tint i, len;\n\tuint8_t subnet_bits = 24;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Reading configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_ETHERNET)) {\n\t\tcommand_print(CMD, \"Ethernet connectivity is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!CMD_ARGC) {\n\t\tshow_config_ip_address(CMD);\n\t} else {\n\t\tif (!string_to_ip(CMD_ARGV[0], ip_address, &i))\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tlen = strlen(CMD_ARGV[0]);\n\n\t\t/* Check for format A.B.C.D/E. */\n\t\tif (i < len) {\n\t\t\tif (CMD_ARGV[0][i] != '/')\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0] + i + 1, subnet_bits);\n\t\t} else if (CMD_ARGC > 1) {\n\t\t\tif (!string_to_ip(CMD_ARGV[1], (uint8_t *)&subnet_mask, &i))\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (!subnet_mask)\n\t\t\tsubnet_mask = (uint32_t)(subnet_bits < 32 ?\n\t\t\t\t((1ULL << subnet_bits) - 1) : 0xffffffff);\n\n\t\tcpy_ip(tmp_config.ip_address, ip_address);\n\t\tcpy_ip(tmp_config.subnet_mask, (uint8_t *)&subnet_mask);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_config_reset_command)\n{\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG))\n\t\treturn ERROR_OK;\n\n\tmemcpy(&tmp_config, &config, sizeof(struct device_config));\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(jlink_handle_config_write_command)\n{\n\tint ret;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Reading configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_WRITE_CONFIG)) {\n\t\tcommand_print(CMD, \"Writing configuration is not supported by the \"\n\t\t\t\"device\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!memcmp(&config, &tmp_config, sizeof(struct device_config))) {\n\t\tcommand_print(CMD, \"Operation not performed due to no changes in \"\n\t\t\t\"the configuration\");\n\t\treturn ERROR_OK;\n\t}\n\n\tret = jaylink_write_raw_config(devh, (const uint8_t *)&tmp_config);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_write_raw_config() failed: %s\",\n\t\t\tjaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!read_device_config(&config)) {\n\t\tLOG_ERROR(\"Failed to read device configuration for verification\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (memcmp(&config, &tmp_config, sizeof(struct device_config))) {\n\t\tLOG_ERROR(\"Verification of device configuration failed. Please check \"\n\t\t\t\"your device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmemcpy(&tmp_config, &config, sizeof(struct device_config));\n\tcommand_print(CMD, \"The new device configuration applies after power \"\n\t\t\"cycling the J-Link device\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_config_command)\n{\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_READ_CONFIG)) {\n\t\tcommand_print(CMD, \"Device doesn't support reading configuration\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC == 0)\n\t\tshow_config(CMD);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_emucom_write_command)\n{\n\tint ret;\n\tsize_t tmp;\n\tuint32_t channel;\n\tuint32_t length;\n\tuint8_t *buf;\n\tsize_t dummy;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {\n\t\tLOG_ERROR(\"Device does not support EMUCOM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);\n\n\ttmp = strlen(CMD_ARGV[1]);\n\n\tif (tmp % 2 != 0) {\n\t\tLOG_ERROR(\"Data must be encoded as hexadecimal pairs\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tbuf = malloc(tmp / 2);\n\n\tif (!buf) {\n\t\tLOG_ERROR(\"Failed to allocate buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdummy = unhexify(buf, CMD_ARGV[1], tmp / 2);\n\n\tif (dummy != (tmp / 2)) {\n\t\tLOG_ERROR(\"Data must be encoded as hexadecimal pairs\");\n\t\tfree(buf);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tlength = tmp / 2;\n\tret = jaylink_emucom_write(devh, channel, buf, &length);\n\n\tfree(buf);\n\n\tif (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {\n\t\tLOG_ERROR(\"Channel not supported by the device\");\n\t\treturn ERROR_FAIL;\n\t} else if (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"Failed to write to channel: %s\", jaylink_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (length != (tmp / 2))\n\t\tLOG_WARNING(\"Only %\" PRIu32 \" bytes written to the channel\", length);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jlink_handle_emucom_read_command)\n{\n\tint ret;\n\tuint32_t channel;\n\tuint32_t length;\n\tuint8_t *buf;\n\tsize_t tmp;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!jaylink_has_cap(caps, JAYLINK_DEV_CAP_EMUCOM)) {\n\t\tLOG_ERROR(\"Device does not support EMUCOM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], channel);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\n\tbuf = malloc(length * 3 + 1);\n\n\tif (!buf) {\n\t\tLOG_ERROR(\"Failed to allocate buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = jaylink_emucom_read(devh, channel, buf, &length);\n\n\tif (ret == JAYLINK_ERR_DEV_NOT_SUPPORTED) {\n\t\tLOG_ERROR(\"Channel is not supported by the device\");\n\t\tfree(buf);\n\t\treturn ERROR_FAIL;\n\t} else if (ret == JAYLINK_ERR_DEV_NOT_AVAILABLE) {\n\t\tLOG_ERROR(\"Channel is not available for the requested amount of data. \"\n\t\t\t\"%\" PRIu32 \" bytes are available\", length);\n\t\tfree(buf);\n\t\treturn ERROR_FAIL;\n\t} else if (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"Failed to read from channel: %s\", jaylink_strerror(ret));\n\t\tfree(buf);\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttmp = hexify((char *)buf + length, buf, length, 2 * length + 1);\n\n\tif (tmp != 2 * length) {\n\t\tLOG_ERROR(\"Failed to convert data into hexadecimal string\");\n\t\tfree(buf);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(CMD, \"%s\", buf + length);\n\tfree(buf);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration jlink_config_subcommand_handlers[] = {\n\t{\n\t\t.name = \"usb\",\n\t\t.handler = &jlink_handle_config_usb_address_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set the USB address\",\n\t\t.usage = \"[0-3]\",\n\t},\n\t{\n\t\t.name = \"targetpower\",\n\t\t.handler = &jlink_handle_config_target_power_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set the target power supply\",\n\t\t.usage = \"[on|off]\"\n\t},\n\t{\n\t\t.name = \"mac\",\n\t\t.handler = &jlink_handle_config_mac_address_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set the MAC Address\",\n\t\t.usage = \"[ff:ff:ff:ff:ff:ff]\",\n\t},\n\t{\n\t\t.name = \"ip\",\n\t\t.handler = &jlink_handle_config_ip_address_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set the IP address, where A.B.C.D is the IP address, \"\n\t\t\t\"E the bit of the subnet mask, F.G.H.I the subnet mask\",\n\t\t.usage = \"[A.B.C.D[/E] [F.G.H.I]]\",\n\t},\n\t{\n\t\t.name = \"reset\",\n\t\t.handler = &jlink_handle_config_reset_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"undo configuration changes\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"write\",\n\t\t.handler = &jlink_handle_config_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write configuration to the device\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jlink_emucom_subcommand_handlers[] = {\n\t{\n\t\t.name = \"write\",\n\t\t.handler = &jlink_handle_emucom_write_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write to a channel\",\n\t\t.usage = \"<channel> <data>\",\n\t},\n\t{\n\t\t.name = \"read\",\n\t\t.handler = &jlink_handle_emucom_read_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read from a channel\",\n\t\t.usage = \"<channel> <length>\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jlink_subcommand_handlers[] = {\n\t{\n\t\t.name = \"jtag\",\n\t\t.handler = &jlink_handle_jlink_jtag_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"select the JTAG command version\",\n\t\t.usage = \"[2|3]\",\n\t},\n\t{\n\t\t.name = \"targetpower\",\n\t\t.handler = &jlink_handle_target_power_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set the target power supply\",\n\t\t.usage = \"<on|off>\"\n\t},\n\t{\n\t\t.name = \"freemem\",\n\t\t.handler = &jlink_handle_free_memory_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"show free device memory\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"hwstatus\",\n\t\t.handler = &jlink_handle_hwstatus_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"show the hardware status\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"usb\",\n\t\t.handler = &jlink_usb_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the USB address of the device that should be used\",\n\t\t.usage = \"<0-3>\"\n\t},\n\t{\n\t\t.name = \"config\",\n\t\t.handler = &jlink_handle_config_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"access the device configuration. If no argument is given \"\n\t\t\t\"this will show the device configuration\",\n\t\t.chain = jlink_config_subcommand_handlers,\n\t\t.usage = \"[<cmd>]\",\n\t},\n\t{\n\t\t.name = \"emucom\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"access EMUCOM channel\",\n\t\t.chain = jlink_emucom_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jlink_command_handlers[] = {\n\t{\n\t\t.name = \"jlink\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform jlink management\",\n\t\t.chain = jlink_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int jlink_swd_init(void)\n{\n\tiface = JAYLINK_TIF_SWD;\n\n\treturn ERROR_OK;\n}\n\nstatic void jlink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\tjlink_swd_queue_cmd(cmd, NULL, value, ap_delay_clk);\n}\n\nstatic void jlink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\tjlink_swd_queue_cmd(cmd, value, 0, ap_delay_clk);\n}\n\n/***************************************************************************/\n/* J-Link tap functions */\n\nstatic unsigned tap_length;\n/* In SWD mode use tms buffer for direction control */\nstatic uint8_t tms_buffer[JLINK_TAP_BUFFER_SIZE];\nstatic uint8_t tdi_buffer[JLINK_TAP_BUFFER_SIZE];\nstatic uint8_t tdo_buffer[JLINK_TAP_BUFFER_SIZE];\n\nstruct pending_scan_result {\n\t/** First bit position in tdo_buffer to read. */\n\tunsigned first;\n\t/** Number of bits to read. */\n\tunsigned length;\n\t/** Location to store the result */\n\tvoid *buffer;\n\t/** Offset in the destination buffer */\n\tunsigned buffer_offset;\n\t/** SWD command */\n\tuint8_t swd_cmd;\n};\n\n#define MAX_PENDING_SCAN_RESULTS 256\n\nstatic int pending_scan_results_length;\nstatic struct pending_scan_result pending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];\n\nstatic void jlink_tap_init(void)\n{\n\ttap_length = 0;\n\tpending_scan_results_length = 0;\n\tmemset(tms_buffer, 0, sizeof(tms_buffer));\n\tmemset(tdi_buffer, 0, sizeof(tdi_buffer));\n}\n\nstatic void jlink_clock_data(const uint8_t *out, unsigned out_offset,\n\t\t\t     const uint8_t *tms_out, unsigned tms_offset,\n\t\t\t     uint8_t *in, unsigned in_offset,\n\t\t\t     unsigned length)\n{\n\tdo {\n\t\tunsigned available_length = JLINK_TAP_BUFFER_SIZE - tap_length / 8;\n\n\t\tif (!available_length ||\n\t\t    (in && pending_scan_results_length == MAX_PENDING_SCAN_RESULTS)) {\n\t\t\tif (jlink_flush() != ERROR_OK)\n\t\t\t\treturn;\n\t\t\tavailable_length = JLINK_TAP_BUFFER_SIZE;\n\t\t}\n\n\t\tstruct pending_scan_result *pending_scan_result =\n\t\t\t&pending_scan_results_buffer[pending_scan_results_length];\n\n\t\tunsigned scan_length = length > available_length ?\n\t\t\tavailable_length : length;\n\n\t\tif (out)\n\t\t\tbuf_set_buf(out, out_offset, tdi_buffer, tap_length, scan_length);\n\t\tif (tms_out)\n\t\t\tbuf_set_buf(tms_out, tms_offset, tms_buffer, tap_length, scan_length);\n\n\t\tif (in) {\n\t\t\tpending_scan_result->first = tap_length;\n\t\t\tpending_scan_result->length = scan_length;\n\t\t\tpending_scan_result->buffer = in;\n\t\t\tpending_scan_result->buffer_offset = in_offset;\n\t\t\tpending_scan_results_length++;\n\t\t}\n\n\t\ttap_length += scan_length;\n\t\tout_offset += scan_length;\n\t\ttms_offset += scan_length;\n\t\tin_offset += scan_length;\n\t\tlength -= scan_length;\n\t} while (length > 0);\n}\n\nstatic int jlink_flush(void)\n{\n\tint i;\n\tint ret;\n\n\tif (!tap_length)\n\t\treturn ERROR_OK;\n\n\tjlink_last_state = jtag_debug_state_machine(tms_buffer, tdi_buffer,\n\t\ttap_length, jlink_last_state);\n\n\tret = jaylink_jtag_io(devh, tms_buffer, tdi_buffer, tdo_buffer,\n\t\ttap_length, jtag_command_version);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_jtag_io() failed: %s\", jaylink_strerror(ret));\n\t\tjlink_tap_init();\n\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\n\tfor (i = 0; i < pending_scan_results_length; i++) {\n\t\tstruct pending_scan_result *p = &pending_scan_results_buffer[i];\n\n\t\tbuf_set_buf(tdo_buffer, p->first, p->buffer,\n\t\t\t    p->buffer_offset, p->length);\n\n\t\tLOG_DEBUG_IO(\"Pending scan result, length = %d\", p->length);\n\t}\n\n\tjlink_tap_init();\n\n\treturn ERROR_OK;\n}\n\nstatic void fill_buffer(uint8_t *buf, uint32_t val, uint32_t len)\n{\n\tunsigned int tap_pos = tap_length;\n\n\twhile (len > 32) {\n\t\tbuf_set_u32(buf, tap_pos, 32, val);\n\t\tlen -= 32;\n\t\ttap_pos += 32;\n\t}\n\n\tif (len)\n\t\tbuf_set_u32(buf, tap_pos, len, val);\n}\n\nstatic void jlink_queue_data_out(const uint8_t *data, uint32_t len)\n{\n\tconst uint32_t dir_out = 0xffffffff;\n\n\tif (data)\n\t\tbit_copy(tdi_buffer, tap_length, data, 0, len);\n\telse\n\t\tfill_buffer(tdi_buffer, 0, len);\n\n\tfill_buffer(tms_buffer, dir_out, len);\n\ttap_length += len;\n}\n\nstatic void jlink_queue_data_in(uint32_t len)\n{\n\tconst uint32_t dir_in = 0;\n\n\tfill_buffer(tms_buffer, dir_in, len);\n\ttap_length += len;\n}\n\nstatic int jlink_swd_switch_seq(enum swd_special_seq seq)\n{\n\tconst uint8_t *s;\n\tunsigned int s_len;\n\n\tswitch (seq) {\n\t\tcase LINE_RESET:\n\t\t\tLOG_DEBUG(\"SWD line reset\");\n\t\t\ts = swd_seq_line_reset;\n\t\t\ts_len = swd_seq_line_reset_len;\n\t\t\tbreak;\n\t\tcase JTAG_TO_SWD:\n\t\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\t\ts = swd_seq_jtag_to_swd;\n\t\t\ts_len = swd_seq_jtag_to_swd_len;\n\t\t\tbreak;\n\t\tcase JTAG_TO_DORMANT:\n\t\t\tLOG_DEBUG(\"JTAG-to-DORMANT\");\n\t\t\ts = swd_seq_jtag_to_dormant;\n\t\t\ts_len = swd_seq_jtag_to_dormant_len;\n\t\t\tbreak;\n\t\tcase SWD_TO_JTAG:\n\t\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\t\ts = swd_seq_swd_to_jtag;\n\t\t\ts_len = swd_seq_swd_to_jtag_len;\n\t\t\tbreak;\n\t\tcase SWD_TO_DORMANT:\n\t\t\tLOG_DEBUG(\"SWD-to-DORMANT\");\n\t\t\ts = swd_seq_swd_to_dormant;\n\t\t\ts_len = swd_seq_swd_to_dormant_len;\n\t\t\tbreak;\n\t\tcase DORMANT_TO_SWD:\n\t\t\tLOG_DEBUG(\"DORMANT-to-SWD\");\n\t\t\ts = swd_seq_dormant_to_swd;\n\t\t\ts_len = swd_seq_dormant_to_swd_len;\n\t\t\tbreak;\n\t\tcase DORMANT_TO_JTAG:\n\t\t\tLOG_DEBUG(\"DORMANT-to-JTAG\");\n\t\t\ts = swd_seq_dormant_to_jtag;\n\t\t\ts_len = swd_seq_dormant_to_jtag_len;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tjlink_queue_data_out(s, s_len);\n\n\treturn ERROR_OK;\n}\n\nstatic int jlink_swd_run_queue(void)\n{\n\tint i;\n\tint ret;\n\n\tLOG_DEBUG(\"Executing %d queued transactions\", pending_scan_results_length);\n\n\tif (queued_retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Skipping due to previous errors: %d\", queued_retval);\n\t\tgoto skip;\n\t}\n\n\t/*\n\t * A transaction must be followed by another transaction or at least 8 idle\n\t * cycles to ensure that data is clocked through the AP.\n\t */\n\tjlink_queue_data_out(NULL, 8);\n\n\tret = jaylink_swd_io(devh, tms_buffer, tdi_buffer, tdo_buffer, tap_length);\n\n\tif (ret != JAYLINK_OK) {\n\t\tLOG_ERROR(\"jaylink_swd_io() failed: %s\", jaylink_strerror(ret));\n\t\tgoto skip;\n\t}\n\n\tfor (i = 0; i < pending_scan_results_length; i++) {\n\t\t/* Devices do not reply to DP_TARGETSEL write cmd, ignore received ack */\n\t\tbool check_ack = swd_cmd_returns_ack(pending_scan_results_buffer[i].swd_cmd);\n\t\tint ack = buf_get_u32(tdo_buffer, pending_scan_results_buffer[i].first, 3);\n\t\tif (check_ack && ack != SWD_ACK_OK) {\n\t\t\tLOG_DEBUG(\"SWD ack not OK: %d %s\", ack,\n\t\t\t\t  ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\");\n\t\t\tqueued_retval = swd_ack_to_error_code(ack);\n\t\t\tgoto skip;\n\t\t} else if (pending_scan_results_buffer[i].length) {\n\t\t\tuint32_t data = buf_get_u32(tdo_buffer, 3 + pending_scan_results_buffer[i].first, 32);\n\t\t\tint parity = buf_get_u32(tdo_buffer, 3 + 32 + pending_scan_results_buffer[i].first, 1);\n\n\t\t\tif (parity != parity_u32(data)) {\n\t\t\t\tLOG_ERROR(\"SWD: Read data parity mismatch\");\n\t\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\t\tgoto skip;\n\t\t\t}\n\n\t\t\tif (pending_scan_results_buffer[i].buffer)\n\t\t\t\t*(uint32_t *)pending_scan_results_buffer[i].buffer = data;\n\t\t}\n\t}\n\nskip:\n\tjlink_tap_init();\n\tret = queued_retval;\n\tqueued_retval = ERROR_OK;\n\n\treturn ret;\n}\n\nstatic void jlink_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data, uint32_t ap_delay_clk)\n{\n\tuint8_t data_parity_trn[DIV_ROUND_UP(32 + 1, 8)];\n\tif (tap_length + 46 + 8 + ap_delay_clk >= swd_buffer_size * 8 ||\n\t    pending_scan_results_length == MAX_PENDING_SCAN_RESULTS) {\n\t\t/* Not enough room in the queue. Run the queue. */\n\t\tqueued_retval = jlink_swd_run_queue();\n\t}\n\n\tif (queued_retval != ERROR_OK)\n\t\treturn;\n\n\tpending_scan_results_buffer[pending_scan_results_length].swd_cmd = cmd;\n\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\n\tjlink_queue_data_out(&cmd, 8);\n\n\tpending_scan_results_buffer[pending_scan_results_length].first = tap_length;\n\n\tif (cmd & SWD_CMD_RNW) {\n\t\t/* Queue a read transaction. */\n\t\tpending_scan_results_buffer[pending_scan_results_length].length = 32;\n\t\tpending_scan_results_buffer[pending_scan_results_length].buffer = dst;\n\n\t\tjlink_queue_data_in(1 + 3 + 32 + 1 + 1);\n\t} else {\n\t\t/* Queue a write transaction. */\n\t\tpending_scan_results_buffer[pending_scan_results_length].length = 0;\n\t\tjlink_queue_data_in(1 + 3 + 1);\n\n\t\tbuf_set_u32(data_parity_trn, 0, 32, data);\n\t\tbuf_set_u32(data_parity_trn, 32, 1, parity_u32(data));\n\n\t\tjlink_queue_data_out(data_parity_trn, 32 + 1);\n\t}\n\n\tpending_scan_results_length++;\n\n\t/* Insert idle cycles after AP accesses to avoid WAIT. */\n\tif (cmd & SWD_CMD_APNDP)\n\t\tjlink_queue_data_out(NULL, ap_delay_clk);\n}\n\nstatic const struct swd_driver jlink_swd = {\n\t.init = &jlink_swd_init,\n\t.switch_seq = &jlink_swd_switch_seq,\n\t.read_reg = &jlink_swd_read_reg,\n\t.write_reg = &jlink_swd_write_reg,\n\t.run = &jlink_swd_run_queue,\n};\n\nstatic const char * const jlink_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface jlink_interface = {\n\t.execute_queue = &jlink_execute_queue,\n};\n\nstruct adapter_driver jlink_adapter_driver = {\n\t.name = \"jlink\",\n\t.transports = jlink_transports,\n\t.commands = jlink_command_handlers,\n\n\t.init = &jlink_init,\n\t.quit = &jlink_quit,\n\t.reset = &jlink_reset_safe,\n\t.speed = &jlink_speed,\n\t.khz = &jlink_khz,\n\t.speed_div = &jlink_speed_div,\n\t.config_trace = &config_trace,\n\t.poll_trace = &poll_trace,\n\n\t.jtag_ops = &jlink_interface,\n\t.swd_ops = &jlink_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/jtag_dpi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * JTAG to DPI driver\n *\n * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>\n *\n * Copyright (C) 2019-2020, Ampere Computing LLC\n *\n * See file CREDITS for list of people who contributed to this\n * project.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#ifdef HAVE_ARPA_INET_H\n#include <arpa/inet.h>\n#endif\n\n#ifndef _WIN32\n#include <netinet/tcp.h>\n#endif\n\n#define SERVER_ADDRESS\t\"127.0.0.1\"\n#define SERVER_PORT\t5555\n\nstatic uint16_t server_port = SERVER_PORT;\nstatic char *server_address;\n\nstatic int sockfd;\nstatic struct sockaddr_in serv_addr;\n\nstatic uint8_t *last_ir_buf;\nstatic int last_ir_num_bits;\n\nstatic int write_sock(char *buf, size_t len)\n{\n\tif (!buf) {\n\t\tLOG_ERROR(\"%s: NULL 'buf' argument, file %s, line %d\",\n\t\t\t__func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (write(sockfd, buf, len) != (ssize_t)len) {\n\t\tLOG_ERROR(\"%s: %s, file %s, line %d\", __func__,\n\t\t\tstrerror(errno), __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int read_sock(char *buf, size_t len)\n{\n\tif (!buf) {\n\t\tLOG_ERROR(\"%s: NULL 'buf' argument, file %s, line %d\",\n\t\t\t__func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (read(sockfd, buf, len) != (ssize_t)len) {\n\t\tLOG_ERROR(\"%s: %s, file %s, line %d\", __func__,\n\t\t\tstrerror(errno), __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * jtag_dpi_reset - ask to reset the JTAG device\n * @param trst 1 if TRST is to be asserted\n * @param srst 1 if SRST is to be asserted\n */\nstatic int jtag_dpi_reset(int trst, int srst)\n{\n\tchar *buf = \"reset\\n\";\n\tint ret = ERROR_OK;\n\n\tLOG_DEBUG_IO(\"JTAG DRIVER DEBUG: reset trst: %i srst %i\", trst, srst);\n\n\tif (trst == 1) {\n\t\t/* reset the JTAG TAP controller */\n\t\tret = write_sock(buf, strlen(buf));\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"write_sock() fail, file %s, line %d\",\n\t\t\t\t__FILE__, __LINE__);\n\t\t}\n\t}\n\n\tif (srst == 1) {\n\t\t/* System target reset not supported */\n\t\tLOG_ERROR(\"DPI SRST not supported\");\n\t\tret = ERROR_FAIL;\n\t}\n\n\treturn ret;\n}\n\n/**\n * jtag_dpi_scan - launches a DR-scan or IR-scan\n * @param cmd the command to launch\n *\n * Launch a JTAG IR-scan or DR-scan\n *\n * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.\n */\nstatic int jtag_dpi_scan(struct scan_command *cmd)\n{\n\tchar buf[20];\n\tuint8_t *data_buf;\n\tint num_bits, bytes;\n\tint ret = ERROR_OK;\n\n\tnum_bits = jtag_build_buffer(cmd, &data_buf);\n\tif (!data_buf) {\n\t\tLOG_ERROR(\"jtag_build_buffer call failed, data_buf == NULL, \"\n\t\t\t\"file %s, line %d\", __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbytes = DIV_ROUND_UP(num_bits, 8);\n\tif (cmd->ir_scan) {\n\t\tfree(last_ir_buf);\n\t\tlast_ir_buf = (uint8_t *)malloc(bytes * sizeof(uint8_t));\n\t\tif (!last_ir_buf) {\n\t\t\tLOG_ERROR(\"%s: malloc fail, file %s, line %d\",\n\t\t\t\t__func__, __FILE__, __LINE__);\n\t\t\tret = ERROR_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t\tmemcpy(last_ir_buf, data_buf, bytes);\n\t\tlast_ir_num_bits = num_bits;\n\t}\n\tsnprintf(buf, sizeof(buf), \"%s %d\\n\", cmd->ir_scan ? \"ib\" : \"db\", num_bits);\n\tret = write_sock(buf, strlen(buf));\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"write_sock() fail, file %s, line %d\",\n\t\t\t__FILE__, __LINE__);\n\t\tgoto out;\n\t}\n\tret = write_sock((char *)data_buf, bytes);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"write_sock() fail, file %s, line %d\",\n\t\t\t__FILE__, __LINE__);\n\t\tgoto out;\n\t}\n\tret = read_sock((char *)data_buf, bytes);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"read_sock() fail, file %s, line %d\",\n\t\t\t__FILE__, __LINE__);\n\t\tgoto out;\n\t}\n\n\tret = jtag_read_buffer(data_buf, cmd);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"jtag_read_buffer() fail, file %s, line %d\",\n\t\t\t__FILE__, __LINE__);\n\t\tgoto out;\n\t}\n\nout:\n\tfree(data_buf);\n\treturn ret;\n}\n\nstatic int jtag_dpi_runtest(int cycles)\n{\n\tchar buf[20];\n\tuint8_t *data_buf = last_ir_buf, *read_scan;\n\tint num_bits = last_ir_num_bits, bytes;\n\tint ret = ERROR_OK;\n\n\tif (!data_buf) {\n\t\tLOG_ERROR(\"%s: NULL 'data_buf' argument, file %s, line %d\",\n\t\t\t__func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (num_bits <= 0) {\n\t\tLOG_ERROR(\"%s: 'num_bits' invalid value, file %s, line %d\",\n\t\t\t__func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbytes = DIV_ROUND_UP(num_bits, 8);\n\tread_scan = (uint8_t *)malloc(bytes * sizeof(uint8_t));\n\tif (!read_scan) {\n\t\tLOG_ERROR(\"%s: malloc fail, file %s, line %d\",\n\t\t\t__func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\tsnprintf(buf, sizeof(buf), \"ib %d\\n\", num_bits);\n\twhile (cycles > 0) {\n\t\tret = write_sock(buf, strlen(buf));\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"write_sock() fail, file %s, line %d\",\n\t\t\t\t__FILE__, __LINE__);\n\t\t\tgoto out;\n\t\t}\n\t\tret = write_sock((char *)data_buf, bytes);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"write_sock() fail, file %s, line %d\",\n\t\t\t\t__FILE__, __LINE__);\n\t\t\tgoto out;\n\t\t}\n\t\tret = read_sock((char *)read_scan, bytes);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"read_sock() fail, file %s, line %d\",\n\t\t\t\t__FILE__, __LINE__);\n\t\t\tgoto out;\n\t\t}\n\n\t\tcycles -= num_bits + 6;\n\t}\n\nout:\n\tfree(read_scan);\n\treturn ret;\n}\n\nstatic int jtag_dpi_stableclocks(int cycles)\n{\n\treturn jtag_dpi_runtest(cycles);\n}\n\nstatic int jtag_dpi_execute_queue(void)\n{\n\tstruct jtag_command *cmd;\n\tint ret = ERROR_OK;\n\n\tfor (cmd = jtag_command_queue; ret == ERROR_OK && cmd;\n\t     cmd = cmd->next) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RUNTEST:\n\t\t\tret = jtag_dpi_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tret = jtag_dpi_stableclocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\t/* Enter Test-Logic-Reset state by asserting TRST */\n\t\t\tif (cmd->cmd.statemove->end_state == TAP_RESET)\n\t\t\t\tjtag_dpi_reset(1, 0);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\t/* unsupported */\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\t/* unsupported */\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tret = jtag_dpi_scan(cmd->cmd.scan);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%X\",\n\t\t\t\t  cmd->type);\n\t\t\tret = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nstatic int jtag_dpi_init(void)\n{\n\tsockfd = socket(AF_INET, SOCK_STREAM, 0);\n\tif (sockfd < 0) {\n\t\tLOG_ERROR(\"socket: %s, function %s, file %s, line %d\",\n\t\t\tstrerror(errno), __func__, __FILE__, __LINE__);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmemset(&serv_addr, 0, sizeof(serv_addr));\n\n\tserv_addr.sin_family = AF_INET;\n\tserv_addr.sin_port = htons(server_port);\n\n\tif (!server_address) {\n\t\tserver_address = strdup(SERVER_ADDRESS);\n\t\tif (!server_address) {\n\t\t\tLOG_ERROR(\"%s: strdup fail, file %s, line %d\",\n\t\t\t\t__func__, __FILE__, __LINE__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tserv_addr.sin_addr.s_addr = inet_addr(server_address);\n\n\tif (serv_addr.sin_addr.s_addr == INADDR_NONE) {\n\t\tLOG_ERROR(\"inet_addr error occurred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {\n\t\tclose(sockfd);\n\t\tLOG_ERROR(\"Can't connect to %s : %\" PRIu16, server_address, server_port);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {\n\t\t/* This increases performance dramatically for local\n\t\t* connections, which is the most likely arrangement\n\t\t* for a DPI connection. */\n\t\tint flag = 1;\n\t\tsetsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));\n\t}\n\n\tLOG_INFO(\"Connection to %s : %\" PRIu16 \" succeed\", server_address, server_port);\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_dpi_quit(void)\n{\n\tfree(server_address);\n\tserver_address = NULL;\n\n\treturn close(sockfd);\n}\n\nCOMMAND_HANDLER(jtag_dpi_set_port)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (CMD_ARGC == 0)\n\t\tLOG_INFO(\"Using server port %\" PRIu16, server_port);\n\telse {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], server_port);\n\t\tLOG_INFO(\"Set server port to %\" PRIu16, server_port);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtag_dpi_set_address)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (CMD_ARGC == 0) {\n\t\tif (!server_address) {\n\t\t\tserver_address = strdup(SERVER_ADDRESS);\n\t\t\tif (!server_address) {\n\t\t\t\tLOG_ERROR(\"%s: strdup fail, file %s, line %d\",\n\t\t\t\t\t__func__, __FILE__, __LINE__);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\tLOG_INFO(\"Using server address %s\", server_address);\n\t} else {\n\t\tfree(server_address);\n\t\tserver_address = strdup(CMD_ARGV[0]);\n\t\tif (!server_address) {\n\t\t\tLOG_ERROR(\"%s: strdup fail, file %s, line %d\",\n\t\t\t\t__func__, __FILE__, __LINE__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_INFO(\"Set server address to %s\", server_address);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration jtag_dpi_subcommand_handlers[] = {\n\t{\n\t\t.name = \"set_port\",\n\t\t.handler = &jtag_dpi_set_port,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the port of the DPI server\",\n\t\t.usage = \"[port]\",\n\t},\n\t{\n\t\t.name = \"set_address\",\n\t\t.handler = &jtag_dpi_set_address,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the address of the DPI server\",\n\t\t.usage = \"[address]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jtag_dpi_command_handlers[] = {\n\t{\n\t\t.name = \"jtag_dpi\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform jtag_dpi management\",\n\t\t.chain = jtag_dpi_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface jtag_dpi_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = jtag_dpi_execute_queue,\n};\n\nstruct adapter_driver jtag_dpi_adapter_driver = {\n\t.name = \"jtag_dpi\",\n\t.transports = jtag_only,\n\t.commands = jtag_dpi_command_handlers,\n\t.init = jtag_dpi_init,\n\t.quit = jtag_dpi_quit,\n\t.reset = jtag_dpi_reset,\n\t.jtag_ops = &jtag_dpi_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/jtag_vpi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * JTAG to VPI driver\n *\n * Copyright (C) 2013 Franck Jullien, <elec4fun@gmail.com>\n *\n * See file CREDITS for list of people who contributed to this\n * project.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#ifdef HAVE_ARPA_INET_H\n#include <arpa/inet.h>\n#endif\n\n#ifndef _WIN32\n#include <netinet/tcp.h>\n#endif\n\n#include \"helper/replacements.h\"\n\n#define NO_TAP_SHIFT\t0\n#define TAP_SHIFT\t1\n\n#define DEFAULT_SERVER_ADDRESS\t\"127.0.0.1\"\n#define DEFAULT_SERVER_PORT\t5555\n\n#define\tXFERT_MAX_SIZE\t\t512\n\n#define CMD_RESET\t\t0\n#define CMD_TMS_SEQ\t\t1\n#define CMD_SCAN_CHAIN\t\t2\n#define CMD_SCAN_CHAIN_FLIP_TMS\t3\n#define CMD_STOP_SIMU\t\t4\n\n/* jtag_vpi server port and address to connect to */\nstatic int server_port = DEFAULT_SERVER_PORT;\nstatic char *server_address;\n\n/* Send CMD_STOP_SIMU to server when OpenOCD exits? */\nstatic bool stop_sim_on_exit;\n\nstatic int sockfd;\nstatic struct sockaddr_in serv_addr;\n\n/* One jtag_vpi \"packet\" as sent over a TCP channel. */\nstruct vpi_cmd {\n\tunion {\n\t\tuint32_t cmd;\n\t\tunsigned char cmd_buf[4];\n\t};\n\tunsigned char buffer_out[XFERT_MAX_SIZE];\n\tunsigned char buffer_in[XFERT_MAX_SIZE];\n\tunion {\n\t\tuint32_t length;\n\t\tunsigned char length_buf[4];\n\t};\n\tunion {\n\t\tuint32_t nb_bits;\n\t\tunsigned char nb_bits_buf[4];\n\t};\n};\n\nstatic char *jtag_vpi_cmd_to_str(int cmd_num)\n{\n\tswitch (cmd_num) {\n\tcase CMD_RESET:\n\t\treturn \"CMD_RESET\";\n\tcase CMD_TMS_SEQ:\n\t\treturn \"CMD_TMS_SEQ\";\n\tcase CMD_SCAN_CHAIN:\n\t\treturn \"CMD_SCAN_CHAIN\";\n\tcase CMD_SCAN_CHAIN_FLIP_TMS:\n\t\treturn \"CMD_SCAN_CHAIN_FLIP_TMS\";\n\tcase CMD_STOP_SIMU:\n\t\treturn \"CMD_STOP_SIMU\";\n\tdefault:\n\t\treturn \"<unknown>\";\n\t}\n}\n\nstatic int jtag_vpi_send_cmd(struct vpi_cmd *vpi)\n{\n\tint retval;\n\n\t/* Optional low-level JTAG debug */\n\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {\n\t\tif (vpi->nb_bits > 0) {\n\t\t\t/* command with a non-empty data payload */\n\t\t\tchar *char_buf = buf_to_hex_str(vpi->buffer_out,\n\t\t\t\t\t(vpi->nb_bits > DEBUG_JTAG_IOZ)\n\t\t\t\t\t\t? DEBUG_JTAG_IOZ\n\t\t\t\t\t\t: vpi->nb_bits);\n\t\t\tLOG_DEBUG_IO(\"sending JTAG VPI cmd: cmd=%s, \"\n\t\t\t\t\t\"length=%\" PRIu32 \", \"\n\t\t\t\t\t\"nb_bits=%\" PRIu32 \", \"\n\t\t\t\t\t\"buf_out=0x%s%s\",\n\t\t\t\t\tjtag_vpi_cmd_to_str(vpi->cmd),\n\t\t\t\t\tvpi->length,\n\t\t\t\t\tvpi->nb_bits,\n\t\t\t\t\tchar_buf,\n\t\t\t\t\t(vpi->nb_bits > DEBUG_JTAG_IOZ) ? \"(...)\" : \"\");\n\t\t\tfree(char_buf);\n\t\t} else {\n\t\t\t/* command without data payload */\n\t\t\tLOG_DEBUG_IO(\"sending JTAG VPI cmd: cmd=%s, \"\n\t\t\t\t\t\"length=%\" PRIu32 \", \"\n\t\t\t\t\t\"nb_bits=%\" PRIu32,\n\t\t\t\t\tjtag_vpi_cmd_to_str(vpi->cmd),\n\t\t\t\t\tvpi->length,\n\t\t\t\t\tvpi->nb_bits);\n\t\t}\n\t}\n\n\t/* Use little endian when transmitting/receiving jtag_vpi cmds.\n\t   The choice of little endian goes against usual networking conventions\n\t   but is intentional to remain compatible with most older OpenOCD builds\n\t   (i.e. builds on little-endian platforms). */\n\th_u32_to_le(vpi->cmd_buf, vpi->cmd);\n\th_u32_to_le(vpi->length_buf, vpi->length);\n\th_u32_to_le(vpi->nb_bits_buf, vpi->nb_bits);\n\nretry_write:\n\tretval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd));\n\n\tif (retval < 0) {\n\t\t/* Account for the case when socket write is interrupted. */\n#ifdef _WIN32\n\t\tint wsa_err = WSAGetLastError();\n\t\tif (wsa_err == WSAEINTR)\n\t\t\tgoto retry_write;\n#else\n\t\tif (errno == EINTR)\n\t\t\tgoto retry_write;\n#endif\n\t\t/* Otherwise this is an error using the socket, most likely fatal\n\t\t   for the connection. B*/\n\t\tlog_socket_error(\"jtag_vpi xmit\");\n\t\t/* TODO: Clean way how adapter drivers can report fatal errors\n\t\t   to upper layers of OpenOCD and let it perform an orderly shutdown? */\n\t\texit(-1);\n\t} else if (retval < (int)sizeof(struct vpi_cmd)) {\n\t\t/* This means we could not send all data, which is most likely fatal\n\t\t   for the jtag_vpi connection (the underlying TCP connection likely not\n\t\t   usable anymore) */\n\t\tLOG_ERROR(\"jtag_vpi: Could not send all data through jtag_vpi connection.\");\n\t\texit(-1);\n\t}\n\n\t/* Otherwise the packet has been sent successfully. */\n\treturn ERROR_OK;\n}\n\nstatic int jtag_vpi_receive_cmd(struct vpi_cmd *vpi)\n{\n\tunsigned bytes_buffered = 0;\n\twhile (bytes_buffered < sizeof(struct vpi_cmd)) {\n\t\tint bytes_to_receive = sizeof(struct vpi_cmd) - bytes_buffered;\n\t\tint retval = read_socket(sockfd, ((char *)vpi) + bytes_buffered, bytes_to_receive);\n\t\tif (retval < 0) {\n#ifdef _WIN32\n\t\t\tint wsa_err = WSAGetLastError();\n\t\t\tif (wsa_err == WSAEINTR) {\n\t\t\t\t/* socket read interrupted by WSACancelBlockingCall() */\n\t\t\t\tcontinue;\n\t\t\t}\n#else\n\t\t\tif (errno == EINTR) {\n\t\t\t\t/* socket read interrupted by a signal */\n\t\t\t\tcontinue;\n\t\t\t}\n#endif\n\t\t\t/* Otherwise, this is an error when accessing the socket. */\n\t\t\tlog_socket_error(\"jtag_vpi recv\");\n\t\t\texit(-1);\n\t\t} else if (retval == 0) {\n\t\t\t/* Connection closed by the other side */\n\t\t\tLOG_ERROR(\"Connection prematurely closed by jtag_vpi server.\");\n\t\t\texit(-1);\n\t\t}\n\t\t/* Otherwise, we have successfully received some data */\n\t\tbytes_buffered += retval;\n\t}\n\n\t/* Use little endian when transmitting/receiving jtag_vpi cmds. */\n\tvpi->cmd = le_to_h_u32(vpi->cmd_buf);\n\tvpi->length = le_to_h_u32(vpi->length_buf);\n\tvpi->nb_bits = le_to_h_u32(vpi->nb_bits_buf);\n\n\treturn ERROR_OK;\n}\n\n/**\n * jtag_vpi_reset - ask to reset the JTAG device\n * @param trst 1 if TRST is to be asserted\n * @param srst 1 if SRST is to be asserted\n */\nstatic int jtag_vpi_reset(int trst, int srst)\n{\n\tstruct vpi_cmd vpi;\n\tmemset(&vpi, 0, sizeof(struct vpi_cmd));\n\n\tvpi.cmd = CMD_RESET;\n\tvpi.length = 0;\n\treturn jtag_vpi_send_cmd(&vpi);\n}\n\n/**\n * jtag_vpi_tms_seq - ask a TMS sequence transition to JTAG\n * @param bits TMS bits to be written (bit0, bit1 .. bitN)\n * @param nb_bits number of TMS bits (between 1 and 8)\n *\n * Write a series of TMS transitions, where each transition consists in :\n *  - writing out TCK=0, TMS=\\<new_state>, TDI=\\<???>\n *  - writing out TCK=1, TMS=\\<new_state>, TDI=\\<???> which triggers the transition\n * The function ensures that at the end of the sequence, the clock (TCK) is put\n * low.\n */\nstatic int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits)\n{\n\tstruct vpi_cmd vpi;\n\tint nb_bytes;\n\n\tmemset(&vpi, 0, sizeof(struct vpi_cmd));\n\tnb_bytes = DIV_ROUND_UP(nb_bits, 8);\n\n\tvpi.cmd = CMD_TMS_SEQ;\n\tmemcpy(vpi.buffer_out, bits, nb_bytes);\n\tvpi.length = nb_bytes;\n\tvpi.nb_bits = nb_bits;\n\n\treturn jtag_vpi_send_cmd(&vpi);\n}\n\n/**\n * jtag_vpi_path_move - ask a TMS sequence transition to JTAG\n * @param cmd path transition\n *\n * Write a series of TMS transitions, where each transition consists in :\n *  - writing out TCK=0, TMS=\\<new_state>, TDI=\\<???>\n *  - writing out TCK=1, TMS=\\<new_state>, TDI=\\<???> which triggers the transition\n * The function ensures that at the end of the sequence, the clock (TCK) is put\n * low.\n */\n\nstatic int jtag_vpi_path_move(struct pathmove_command *cmd)\n{\n\tuint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)];\n\n\tmemset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));\n\n\tfor (int i = 0; i < cmd->num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), true) == cmd->path[i])\n\t\t\tbuf_set_u32(trans, i, 1, 1);\n\t\ttap_set_state(cmd->path[i]);\n\t}\n\n\treturn jtag_vpi_tms_seq(trans, cmd->num_states);\n}\n\n/**\n * jtag_vpi_tms - ask a tms command\n * @param cmd tms command\n */\nstatic int jtag_vpi_tms(struct tms_command *cmd)\n{\n\treturn jtag_vpi_tms_seq(cmd->bits, cmd->num_bits);\n}\n\nstatic int jtag_vpi_state_move(tap_state_t state)\n{\n\tif (tap_get_state() == state)\n\t\treturn ERROR_OK;\n\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), state);\n\tint tms_len = tap_get_tms_path_len(tap_get_state(), state);\n\n\tint retval = jtag_vpi_tms_seq(&tms_scan, tms_len);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttap_set_state(state);\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)\n{\n\tstruct vpi_cmd vpi;\n\tint nb_bytes = DIV_ROUND_UP(nb_bits, 8);\n\n\tmemset(&vpi, 0, sizeof(struct vpi_cmd));\n\n\tvpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN;\n\n\tif (bits)\n\t\tmemcpy(vpi.buffer_out, bits, nb_bytes);\n\telse\n\t\tmemset(vpi.buffer_out, 0xff, nb_bytes);\n\n\tvpi.length = nb_bytes;\n\tvpi.nb_bits = nb_bits;\n\n\tint retval = jtag_vpi_send_cmd(&vpi);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_vpi_receive_cmd(&vpi);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Optional low-level JTAG debug */\n\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {\n\t\tchar *char_buf = buf_to_hex_str(vpi.buffer_in,\n\t\t\t\t(nb_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : nb_bits);\n\t\tLOG_DEBUG_IO(\"recvd JTAG VPI data: nb_bits=%d, buf_in=0x%s%s\",\n\t\t\tnb_bits, char_buf, (nb_bits > DEBUG_JTAG_IOZ) ? \"(...)\" : \"\");\n\t\tfree(char_buf);\n\t}\n\n\tif (bits)\n\t\tmemcpy(bits, vpi.buffer_in, nb_bytes);\n\n\treturn ERROR_OK;\n}\n\n/**\n * jtag_vpi_queue_tdi - short description\n * @param bits bits to be queued on TDI (or NULL if 0 are to be queued)\n * @param nb_bits number of bits\n * @param tap_shift\n */\nstatic int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift)\n{\n\tint nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);\n\tint retval;\n\n\twhile (nb_xfer) {\n\t\tif (nb_xfer ==  1) {\n\t\t\tretval = jtag_vpi_queue_tdi_xfer(bits, nb_bits, tap_shift);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tretval = jtag_vpi_queue_tdi_xfer(bits, XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tnb_bits -= XFERT_MAX_SIZE * 8;\n\t\t\tif (bits)\n\t\t\t\tbits += XFERT_MAX_SIZE;\n\t\t}\n\n\t\tnb_xfer--;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * jtag_vpi_clock_tms - clock a TMS transition\n * @param tms the TMS to be sent\n *\n * Triggers a TMS transition (ie. one JTAG TAP state move).\n */\nstatic int jtag_vpi_clock_tms(int tms)\n{\n\tconst uint8_t tms_0 = 0;\n\tconst uint8_t tms_1 = 1;\n\n\treturn jtag_vpi_tms_seq(tms ? &tms_1 : &tms_0, 1);\n}\n\n/**\n * jtag_vpi_scan - launches a DR-scan or IR-scan\n * @param cmd the command to launch\n *\n * Launch a JTAG IR-scan or DR-scan\n *\n * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.\n */\nstatic int jtag_vpi_scan(struct scan_command *cmd)\n{\n\tint scan_bits;\n\tuint8_t *buf = NULL;\n\tint retval = ERROR_OK;\n\n\tscan_bits = jtag_build_buffer(cmd, &buf);\n\n\tif (cmd->ir_scan) {\n\t\tretval = jtag_vpi_state_move(TAP_IRSHIFT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tretval = jtag_vpi_state_move(TAP_DRSHIFT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cmd->end_state == TAP_DRSHIFT) {\n\t\tretval = jtag_vpi_queue_tdi(buf, scan_bits, NO_TAP_SHIFT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tretval = jtag_vpi_queue_tdi(buf, scan_bits, TAP_SHIFT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cmd->end_state != TAP_DRSHIFT) {\n\t\t/*\n\t\t * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it\n\t\t * forward to a stable IRPAUSE or DRPAUSE.\n\t\t */\n\t\tretval = jtag_vpi_clock_tms(0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (cmd->ir_scan)\n\t\t\ttap_set_state(TAP_IRPAUSE);\n\t\telse\n\t\t\ttap_set_state(TAP_DRPAUSE);\n\t}\n\n\tretval = jtag_read_buffer(buf, cmd);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfree(buf);\n\n\tif (cmd->end_state != TAP_DRSHIFT) {\n\t\tretval = jtag_vpi_state_move(cmd->end_state);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_vpi_runtest(int cycles, tap_state_t state)\n{\n\tint retval;\n\n\tretval = jtag_vpi_state_move(TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn jtag_vpi_state_move(state);\n}\n\nstatic int jtag_vpi_stableclocks(int cycles)\n{\n\tuint8_t tms_bits[4];\n\tint cycles_remain = cycles;\n\tint nb_bits;\n\tint retval;\n\tconst int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;\n\n\tassert(cycles >= 0);\n\n\t/* use TMS=1 in TAP RESET state, TMS=0 in all other stable states */\n\tmemset(&tms_bits, (tap_get_state() == TAP_RESET) ? 0xff : 0x00, sizeof(tms_bits));\n\n\t/* send the TMS bits */\n\twhile (cycles_remain > 0) {\n\t\tnb_bits = (cycles_remain < CYCLES_ONE_BATCH) ? cycles_remain : CYCLES_ONE_BATCH;\n\t\tretval = jtag_vpi_tms_seq(tms_bits, nb_bits);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcycles_remain -= nb_bits;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_vpi_execute_queue(void)\n{\n\tstruct jtag_command *cmd;\n\tint retval = ERROR_OK;\n\n\tfor (cmd = jtag_command_queue; retval == ERROR_OK && cmd;\n\t     cmd = cmd->next) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RESET:\n\t\t\tretval = jtag_vpi_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tretval = jtag_vpi_runtest(cmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\t  cmd->cmd.runtest->end_state);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tretval = jtag_vpi_stableclocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tretval = jtag_vpi_state_move(cmd->cmd.statemove->end_state);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tretval = jtag_vpi_path_move(cmd->cmd.pathmove);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\tretval = jtag_vpi_tms(cmd->cmd.tms);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tretval = jtag_vpi_scan(cmd->cmd.scan);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%X\",\n\t\t\t\t  cmd->type);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int jtag_vpi_init(void)\n{\n\tint flag = 1;\n\n\tsockfd = socket(AF_INET, SOCK_STREAM, 0);\n\tif (sockfd < 0) {\n\t\tLOG_ERROR(\"jtag_vpi: Could not create client socket\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmemset(&serv_addr, 0, sizeof(serv_addr));\n\n\tserv_addr.sin_family = AF_INET;\n\tserv_addr.sin_port = htons(server_port);\n\n\tif (!server_address)\n\t\tserver_address = strdup(DEFAULT_SERVER_ADDRESS);\n\n\tserv_addr.sin_addr.s_addr = inet_addr(server_address);\n\n\tif (serv_addr.sin_addr.s_addr == INADDR_NONE) {\n\t\tLOG_ERROR(\"jtag_vpi: inet_addr error occurred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {\n\t\tclose(sockfd);\n\t\tLOG_ERROR(\"jtag_vpi: Can't connect to %s : %u\", server_address, server_port);\n\t\treturn ERROR_COMMAND_CLOSE_CONNECTION;\n\t}\n\n\tif (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {\n\t\t/* This increases performance dramatically for local\n\t\t * connections, which is the most likely arrangement\n\t\t * for a VPI connection. */\n\t\tsetsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));\n\t}\n\n\tLOG_INFO(\"jtag_vpi: Connection to %s : %u successful\", server_address, server_port);\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_vpi_stop_simulation(void)\n{\n\tstruct vpi_cmd cmd;\n\tmemset(&cmd, 0, sizeof(struct vpi_cmd));\n\tcmd.length = 0;\n\tcmd.nb_bits = 0;\n\tcmd.cmd = CMD_STOP_SIMU;\n\treturn jtag_vpi_send_cmd(&cmd);\n}\n\nstatic int jtag_vpi_quit(void)\n{\n\tif (stop_sim_on_exit) {\n\t\tif (jtag_vpi_stop_simulation() != ERROR_OK)\n\t\t\tLOG_WARNING(\"jtag_vpi: failed to send \\\"stop simulation\\\" command\");\n\t}\n\tif (close_socket(sockfd) != 0) {\n\t\tLOG_WARNING(\"jtag_vpi: could not close jtag_vpi client socket\");\n\t\tlog_socket_error(\"jtag_vpi\");\n\t}\n\tfree(server_address);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtag_vpi_set_port)\n{\n\tif (CMD_ARGC == 0) {\n\t\tLOG_ERROR(\"Command \\\"jtag_vpi set_port\\\" expects 1 argument (TCP port number)\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], server_port);\n\tLOG_INFO(\"jtag_vpi: server port set to %u\", server_port);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtag_vpi_set_address)\n{\n\n\tif (CMD_ARGC == 0) {\n\t\tLOG_ERROR(\"Command \\\"jtag_vpi set_address\\\" expects 1 argument (IP address)\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tfree(server_address);\n\tserver_address = strdup(CMD_ARGV[0]);\n\tLOG_INFO(\"jtag_vpi: server address set to %s\", server_address);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(jtag_vpi_stop_sim_on_exit_handler)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command \\\"jtag_vpi stop_sim_on_exit\\\" expects 1 argument (on|off)\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], stop_sim_on_exit);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration jtag_vpi_subcommand_handlers[] = {\n\t{\n\t\t.name = \"set_port\",\n\t\t.handler = &jtag_vpi_set_port,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the TCP port number of the jtag_vpi server (default: 5555)\",\n\t\t.usage = \"tcp_port_num\",\n\t},\n\t{\n\t\t.name = \"set_address\",\n\t\t.handler = &jtag_vpi_set_address,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the IP address of the jtag_vpi server (default: 127.0.0.1)\",\n\t\t.usage = \"ipv4_addr\",\n\t},\n\t{\n\t\t.name = \"stop_sim_on_exit\",\n\t\t.handler = &jtag_vpi_stop_sim_on_exit_handler,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure if simulation stop command shall be sent \"\n\t\t\t\"before OpenOCD exits (default: off)\",\n\t\t.usage = \"<on|off>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration jtag_vpi_command_handlers[] = {\n\t{\n\t\t.name = \"jtag_vpi\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform jtag_vpi management\",\n\t\t.chain = jtag_vpi_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface jtag_vpi_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = jtag_vpi_execute_queue,\n};\n\nstruct adapter_driver jtag_vpi_adapter_driver = {\n\t.name = \"jtag_vpi\",\n\t.transports = jtag_only,\n\t.commands = jtag_vpi_command_handlers,\n\n\t.init = jtag_vpi_init,\n\t.quit = jtag_vpi_quit,\n\n\t.jtag_ops = &jtag_vpi_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/kitprog.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net>            *\n *   based on Dominic Rath's and Benedikt Sauter's usbprog.c               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Jean-Christophe PLAGNIOL-VIILARD                *\n *   plagnioj@jcrosoft.com                                                 *\n *                                                                         *\n *   Copyright (C) 2015 by Marc Schink                                     *\n *   openocd-dev@marcschink.de                                             *\n *                                                                         *\n *   Copyright (C) 2015 by Paul Fertser                                    *\n *   fercerpav@gmail.com                                                   *\n *                                                                         *\n *   Copyright (C) 2015-2017 by Forest Crossman                            *\n *   cyrozap@gmail.com                                                     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n\n#include <hidapi.h>\n\n#include <jtag/interface.h>\n#include <jtag/swd.h>\n#include <jtag/commands.h>\n\n#include \"libusb_helper.h\"\n\n#define VID 0x04b4\n#define PID 0xf139\n\n#define BULK_EP_IN  1\n#define BULK_EP_OUT 2\n\n#define CONTROL_TYPE_READ  0x01\n#define CONTROL_TYPE_WRITE 0x02\n\n#define CONTROL_COMMAND_PROGRAM 0x07\n\n#define CONTROL_MODE_POLL_PROGRAMMER_STATUS  0x01\n#define CONTROL_MODE_RESET_TARGET            0x04\n#define CONTROL_MODE_SET_PROGRAMMER_PROTOCOL 0x40\n#define CONTROL_MODE_SYNCHRONIZE_TRANSFER    0x41\n#define CONTROL_MODE_ACQUIRE_SWD_TARGET      0x42\n#define CONTROL_MODE_SEND_SWD_SEQUENCE       0x43\n\n#define PROTOCOL_JTAG 0x00\n#define PROTOCOL_SWD  0x01\n\n#define DEVICE_PSOC4   0x00\n#define DEVICE_PSOC3   0x01\n#define DEVICE_UNKNOWN 0x02\n#define DEVICE_PSOC5   0x03\n\n#define ACQUIRE_MODE_RESET       0x00\n#define ACQUIRE_MODE_POWER_CYCLE 0x01\n\n#define SEQUENCE_LINE_RESET  0x00\n#define SEQUENCE_JTAG_TO_SWD 0x01\n\n#define PROGRAMMER_NOK_NACK 0x00\n#define PROGRAMMER_OK_ACK   0x01\n\n#define HID_TYPE_WRITE 0x00\n#define HID_TYPE_READ  0x01\n#define HID_TYPE_START 0x02\n\n#define HID_COMMAND_POWER      0x80\n#define HID_COMMAND_VERSION    0x81\n#define HID_COMMAND_RESET      0x82\n#define HID_COMMAND_CONFIGURE  0x8f\n#define HID_COMMAND_BOOTLOADER 0xa0\n\n/* 512 bytes seemed to work reliably.\n * It works with both full queue of mostly reads or mostly writes.\n *\n * Unfortunately the commit 88f429ead019fd6df96ec15f0d897385f3cef0d0\n * 5321: target/cortex_m: faster reading of all CPU registers\n * revealed a serious Kitprog firmware problem:\n * If the queue contains more than 63 transactions in the repeated pattern\n * one write, two reads, the firmware fails badly.\n * Sending 64 transactions makes the adapter to loose the connection with the\n * device. Sending 65 or more transactions causes the adapter to stop\n * receiving USB HID commands, next kitprog_hid_command() stops in hid_write().\n *\n * The problem was detected with KitProg v2.12 and v2.16.\n * We can guess the problem is something like a buffer or stack overflow.\n *\n * Use shorter buffer as a workaround. 300 bytes (= 60 transactions) works.\n */\n#define SWD_MAX_BUFFER_LENGTH 300\n\nstruct kitprog {\n\thid_device *hid_handle;\n\tstruct libusb_device_handle *usb_handle;\n\tuint16_t packet_size;\n\tuint16_t packet_index;\n\tuint8_t *packet_buffer;\n\tchar *serial;\n\tuint8_t hardware_version;\n\tuint8_t minor_version;\n\tuint8_t major_version;\n\tuint16_t millivolts;\n\n\tbool supports_jtag_to_swd;\n};\n\nstruct pending_transfer_result {\n\tuint8_t cmd;\n\tuint32_t data;\n\tvoid *buffer;\n};\n\nstatic bool kitprog_init_acquire_psoc;\n\nstatic int pending_transfer_count, pending_queue_len;\nstatic struct pending_transfer_result *pending_transfers;\n\nstatic int queued_retval;\n\nstatic struct kitprog *kitprog_handle;\n\nstatic int kitprog_usb_open(void);\nstatic void kitprog_usb_close(void);\n\nstatic int kitprog_hid_command(uint8_t *command, size_t command_length,\n\t\tuint8_t *data, size_t data_length);\nstatic int kitprog_get_version(void);\nstatic int kitprog_get_millivolts(void);\nstatic int kitprog_get_info(void);\nstatic int kitprog_set_protocol(uint8_t protocol);\nstatic int kitprog_get_status(void);\nstatic int kitprog_set_unknown(void);\nstatic int kitprog_acquire_psoc(uint8_t psoc_type, uint8_t acquire_mode,\n\t\tuint8_t max_attempts);\nstatic int kitprog_reset_target(void);\nstatic int kitprog_swd_sync(void);\nstatic int kitprog_swd_seq(uint8_t seq_type);\n\nstatic int kitprog_generic_acquire(void);\n\nstatic int kitprog_swd_run_queue(void);\nstatic void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data);\nstatic int kitprog_swd_switch_seq(enum swd_special_seq seq);\n\n\nstatic inline int mm_to_version(uint8_t major, uint8_t minor)\n{\n\treturn (major << 8) | minor;\n}\n\nstatic int kitprog_init(void)\n{\n\tint retval;\n\n\tkitprog_handle = malloc(sizeof(struct kitprog));\n\tif (!kitprog_handle) {\n\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (kitprog_usb_open() != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't find a KitProg device! Please check device connections and permissions.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\t/* Get the current KitProg version and target voltage */\n\tif (kitprog_get_info() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Compatibility check */\n\tkitprog_handle->supports_jtag_to_swd = true;\n\tint kitprog_version = mm_to_version(kitprog_handle->major_version, kitprog_handle->minor_version);\n\tif (kitprog_version < mm_to_version(2, 14)) {\n\t\tLOG_WARNING(\"KitProg firmware versions below v2.14 do not support sending JTAG to SWD sequences. These sequences will be substituted with SWD line resets.\");\n\t\tkitprog_handle->supports_jtag_to_swd = false;\n\t}\n\n\t/* I have no idea what this does */\n\tif (kitprog_set_unknown() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* SWD won't work unless we do this */\n\tif (kitprog_swd_sync() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Set the protocol to SWD */\n\tif (kitprog_set_protocol(PROTOCOL_SWD) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Reset the SWD bus */\n\tif (kitprog_swd_seq(SEQUENCE_LINE_RESET) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (kitprog_init_acquire_psoc) {\n\t\t/* Try to acquire any device that will respond */\n\t\tretval = kitprog_generic_acquire();\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"No PSoC devices found\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Allocate packet buffers and queues */\n\tkitprog_handle->packet_size = SWD_MAX_BUFFER_LENGTH;\n\tkitprog_handle->packet_buffer = malloc(SWD_MAX_BUFFER_LENGTH);\n\tif (!kitprog_handle->packet_buffer) {\n\t\tLOG_ERROR(\"Failed to allocate memory for the packet buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tpending_queue_len = SWD_MAX_BUFFER_LENGTH / 5;\n\tpending_transfers = malloc(pending_queue_len * sizeof(*pending_transfers));\n\tif (!pending_transfers) {\n\t\tLOG_ERROR(\"Failed to allocate memory for the SWD transfer queue\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_quit(void)\n{\n\tkitprog_usb_close();\n\n\tfree(kitprog_handle->packet_buffer);\n\tfree(kitprog_handle->serial);\n\tfree(kitprog_handle);\n\tfree(pending_transfers);\n\n\treturn ERROR_OK;\n}\n\n/*************** kitprog usb functions *********************/\n\nstatic int kitprog_get_usb_serial(void)\n{\n\tint retval;\n\tconst uint8_t str_index = 128; /* This seems to be a constant */\n\tchar desc_string[256+1]; /* Max size of string descriptor */\n\n\tretval = libusb_get_string_descriptor_ascii(kitprog_handle->usb_handle,\n\t\t\tstr_index, (unsigned char *)desc_string, sizeof(desc_string)-1);\n\tif (retval < 0) {\n\t\tLOG_ERROR(\"libusb_get_string_descriptor_ascii() failed with %d\", retval);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Null terminate descriptor string */\n\tdesc_string[retval] = '\\0';\n\n\t/* Allocate memory for the serial number */\n\tkitprog_handle->serial = calloc(retval + 1, sizeof(char));\n\tif (!kitprog_handle->serial) {\n\t\tLOG_ERROR(\"Failed to allocate memory for the serial number\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Store the serial number */\n\tstrncpy(kitprog_handle->serial, desc_string, retval + 1);\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_usb_open(void)\n{\n\tconst uint16_t vids[] = { VID, 0 };\n\tconst uint16_t pids[] = { PID, 0 };\n\n\tif (jtag_libusb_open(vids, pids, &kitprog_handle->usb_handle, NULL) != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to open or find the device\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Get the serial number for the device */\n\tif (kitprog_get_usb_serial() != ERROR_OK)\n\t\tLOG_WARNING(\"Failed to get KitProg serial number\");\n\n\t/* Convert the ASCII serial number into a (wchar_t *) */\n\tsize_t len = strlen(kitprog_handle->serial);\n\twchar_t *hid_serial = calloc(len + 1, sizeof(wchar_t));\n\tif (!hid_serial) {\n\t\tLOG_ERROR(\"Failed to allocate memory for the serial number\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (mbstowcs(hid_serial, kitprog_handle->serial, len + 1) == (size_t)-1) {\n\t\tfree(hid_serial);\n\t\tLOG_ERROR(\"Failed to convert serial number\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Use HID for the KitBridge interface */\n\tkitprog_handle->hid_handle = hid_open(VID, PID, hid_serial);\n\tfree(hid_serial);\n\tif (!kitprog_handle->hid_handle) {\n\t\tLOG_ERROR(\"Failed to open KitBridge (HID) interface\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Claim the KitProg Programmer (bulk transfer) interface */\n\tif (libusb_claim_interface(kitprog_handle->usb_handle, 1) != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to claim KitProg Programmer (bulk transfer) interface\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void kitprog_usb_close(void)\n{\n\tif (kitprog_handle->hid_handle) {\n\t\thid_close(kitprog_handle->hid_handle);\n\t\thid_exit();\n\t}\n\n\tjtag_libusb_close(kitprog_handle->usb_handle);\n}\n\n/*************** kitprog lowlevel functions *********************/\n\nstatic int kitprog_hid_command(uint8_t *command, size_t command_length,\n\t\tuint8_t *data, size_t data_length)\n{\n\tint ret;\n\n\tret = hid_write(kitprog_handle->hid_handle, command, command_length);\n\tif (ret < 0) {\n\t\tLOG_DEBUG(\"HID write returned %i\", ret);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = hid_read_timeout(kitprog_handle->hid_handle,\n\t\t\t\t\t\t\tdata, data_length, LIBUSB_TIMEOUT_MS);\n\tif (ret == 0) {\n\t\tLOG_ERROR(\"HID read timed out\");\n\t\treturn ERROR_TIMEOUT_REACHED;\n\t} else if (ret < 0) {\n\t\tLOG_ERROR(\"HID read error %ls\", hid_error(kitprog_handle->hid_handle));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_get_version(void)\n{\n\tint ret;\n\n\tunsigned char command[3] = {HID_TYPE_START | HID_TYPE_WRITE, 0x00, HID_COMMAND_VERSION};\n\tunsigned char data[64];\n\n\tret = kitprog_hid_command(command, sizeof(command), data, sizeof(data));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tkitprog_handle->hardware_version = data[1];\n\tkitprog_handle->minor_version = data[2];\n\tkitprog_handle->major_version = data[3];\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_get_millivolts(void)\n{\n\tint ret;\n\n\tunsigned char command[3] = {HID_TYPE_START | HID_TYPE_READ, 0x00, HID_COMMAND_POWER};\n\tunsigned char data[64];\n\n\tret = kitprog_hid_command(command, sizeof(command), data, sizeof(data));\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tkitprog_handle->millivolts = (data[4] << 8) | data[3];\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_get_info(void)\n{\n\t/* Get the device version information */\n\tif (kitprog_get_version() == ERROR_OK) {\n\t\tLOG_INFO(\"KitProg v%u.%02u\",\n\t\t\tkitprog_handle->major_version, kitprog_handle->minor_version);\n\t\tLOG_INFO(\"Hardware version: %u\",\n\t\t\tkitprog_handle->hardware_version);\n\t} else {\n\t\tLOG_ERROR(\"Failed to get KitProg version\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Get the current reported target voltage */\n\tif (kitprog_get_millivolts() == ERROR_OK) {\n\t\tLOG_INFO(\"VTARG = %u.%03u V\",\n\t\t\tkitprog_handle->millivolts / 1000, kitprog_handle->millivolts % 1000);\n\t} else {\n\t\tLOG_ERROR(\"Failed to get target voltage\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_set_protocol(uint8_t protocol)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(CONTROL_MODE_SET_PROGRAMMER_PROTOCOL << 8) | CONTROL_COMMAND_PROGRAM,\n\t\tprotocol, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_get_status(void)\n{\n\tint transferred = 0;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\t/* Try a maximum of three times */\n\tfor (int i = 0; (i < 3) && (transferred == 0); i++) {\n\t\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\t\tCONTROL_TYPE_READ,\n\t\t\t(CONTROL_MODE_POLL_PROGRAMMER_STATUS << 8) | CONTROL_COMMAND_PROGRAM,\n\t\t\t0, &status, 1, 0);\n\t\tjtag_sleep(1000);\n\t}\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_set_unknown(void)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(0x03 << 8) | 0x04,\n\t\t0, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_acquire_psoc(uint8_t psoc_type, uint8_t acquire_mode,\n\t\tuint8_t max_attempts)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(CONTROL_MODE_ACQUIRE_SWD_TARGET << 8) | CONTROL_COMMAND_PROGRAM,\n\t\t(max_attempts << 8) | (acquire_mode << 4) | psoc_type, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_reset_target(void)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(CONTROL_MODE_RESET_TARGET << 8) | CONTROL_COMMAND_PROGRAM,\n\t\t0, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_swd_sync(void)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(CONTROL_MODE_SYNCHRONIZE_TRANSFER << 8) | CONTROL_COMMAND_PROGRAM,\n\t\t0, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_swd_seq(uint8_t seq_type)\n{\n\tint transferred;\n\tchar status = PROGRAMMER_NOK_NACK;\n\n\ttransferred = jtag_libusb_control_transfer(kitprog_handle->usb_handle,\n\t\tLIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE,\n\t\tCONTROL_TYPE_WRITE,\n\t\t(CONTROL_MODE_SEND_SWD_SEQUENCE << 8) | CONTROL_COMMAND_PROGRAM,\n\t\tseq_type, &status, 1, 0);\n\n\tif (transferred == 0) {\n\t\tLOG_DEBUG(\"Zero bytes transferred\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (status != PROGRAMMER_OK_ACK) {\n\t\tLOG_DEBUG(\"Programmer did not respond OK\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_generic_acquire(void)\n{\n\tconst uint8_t devices[] = {DEVICE_PSOC4, DEVICE_PSOC3, DEVICE_PSOC5};\n\n\tint retval;\n\tint acquire_count = 0;\n\n\t/* Due to the way the SWD port is shared between the Test Controller (TC)\n\t * and the Cortex-M3 DAP on the PSoC 5LP, the TC is the default SWD target\n\t * after power is applied. To access the DAP, the PSoC 5LP requires at least\n\t * one acquisition sequence to be run (which switches the SWD mux from the\n\t * TC to the DAP). However, after the mux is switched, the Cortex-M3 will be\n\t * held in reset until a series of registers are written to (see section 5.2\n\t * of the PSoC 5LP Device Programming Specifications for details).\n\t *\n\t * Instead of writing the registers in this function, we just do what the\n\t * Cypress tools do and run the acquisition sequence a second time. This\n\t * will take the Cortex-M3 out of reset and enable debugging.\n\t */\n\tfor (int i = 0; i < 2; i++) {\n\t\tfor (uint8_t j = 0; j < sizeof(devices) && acquire_count == i; j++) {\n\t\t\tretval = kitprog_acquire_psoc(devices[j], ACQUIRE_MODE_RESET, 3);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"Acquisition function failed for device 0x%02x.\", devices[j]);\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tif (kitprog_get_status() == ERROR_OK)\n\t\t\t\tacquire_count++;\n\t\t}\n\n\t\tjtag_sleep(10);\n\t}\n\n\tif (acquire_count < 2)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n/*************** swd wrapper functions *********************/\n\nstatic int kitprog_swd_init(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic void kitprog_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\tkitprog_swd_queue_cmd(cmd, NULL, value);\n}\n\nstatic void kitprog_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\tkitprog_swd_queue_cmd(cmd, value, 0);\n}\n\n/*************** swd lowlevel functions ********************/\n\nstatic int kitprog_swd_switch_seq(enum swd_special_seq seq)\n{\n\tswitch (seq) {\n\t\tcase JTAG_TO_SWD:\n\t\t\tif (kitprog_handle->supports_jtag_to_swd) {\n\t\t\t\tLOG_DEBUG(\"JTAG to SWD\");\n\t\t\t\tif (kitprog_swd_seq(SEQUENCE_JTAG_TO_SWD) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tLOG_DEBUG(\"JTAG to SWD not supported\");\n\t\t\t\t/* Fall through to fix target reset issue */\n\t\t\t}\n\t\t\t/* fallthrough */\n\t\tcase LINE_RESET:\n\t\t\tLOG_DEBUG(\"SWD line reset\");\n\t\t\tif (kitprog_swd_seq(SEQUENCE_LINE_RESET) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Sequence %d not supported.\", seq);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int kitprog_swd_run_queue(void)\n{\n\tint ret;\n\n\tsize_t read_count = 0;\n\tsize_t read_index = 0;\n\tsize_t write_count = 0;\n\tuint8_t *buffer = kitprog_handle->packet_buffer;\n\n\tdo {\n\t\tLOG_DEBUG_IO(\"Executing %d queued transactions\", pending_transfer_count);\n\n\t\tif (queued_retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Skipping due to previous errors: %d\", queued_retval);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!pending_transfer_count)\n\t\t\tbreak;\n\n\t\tfor (int i = 0; i < pending_transfer_count; i++) {\n\t\t\tuint8_t cmd = pending_transfers[i].cmd;\n\t\t\tuint32_t data = pending_transfers[i].data;\n\n\t\t\t/* When proper WAIT handling is implemented in the\n\t\t\t * common SWD framework, this kludge can be\n\t\t\t * removed. However, this might lead to minor\n\t\t\t * performance degradation as the adapter wouldn't be\n\t\t\t * able to automatically retry anything (because ARM\n\t\t\t * has forgotten to implement sticky error flags\n\t\t\t * clearing). See also comments regarding\n\t\t\t * cmsis_dap_cmd_DAP_TFER_Configure() and\n\t\t\t * cmsis_dap_cmd_DAP_SWD_Configure() in\n\t\t\t * cmsis_dap_init().\n\t\t\t */\n\t\t\tif (!(cmd & SWD_CMD_RNW) &&\n\t\t\t\t!(cmd & SWD_CMD_APNDP) &&\n\t\t\t\t(cmd & SWD_CMD_A32) >> 1 == DP_CTRL_STAT &&\n\t\t\t\t(data & CORUNDETECT)) {\n\t\t\t\tLOG_DEBUG(\"refusing to enable sticky overrun detection\");\n\t\t\t\tdata &= ~CORUNDETECT;\n\t\t\t}\n\n\t\t\tLOG_DEBUG_IO(\"%s %s reg %x %\"PRIx32,\n\t\t\t\t\tcmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t\t\t\tcmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t\t\t  (cmd & SWD_CMD_A32) >> 1, data);\n\n\t\t\tbuffer[write_count++] = (cmd | SWD_CMD_START | SWD_CMD_PARK) & ~SWD_CMD_STOP;\n\t\t\tread_count++;\n\t\t\tif (!(cmd & SWD_CMD_RNW)) {\n\t\t\t\tbuffer[write_count++] = (data) & 0xff;\n\t\t\t\tbuffer[write_count++] = (data >> 8) & 0xff;\n\t\t\t\tbuffer[write_count++] = (data >> 16) & 0xff;\n\t\t\t\tbuffer[write_count++] = (data >> 24) & 0xff;\n\t\t\t} else {\n\t\t\t\tread_count += 4;\n\t\t\t}\n\t\t}\n\n\t\tif (jtag_libusb_bulk_write(kitprog_handle->usb_handle,\n\t\t\t\t\t   BULK_EP_OUT, (char *)buffer,\n\t\t\t\t\t   write_count, 0, &ret)) {\n\t\t\tLOG_ERROR(\"Bulk write failed\");\n\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tqueued_retval = ERROR_OK;\n\t\t}\n\n\t\t/* KitProg firmware does not send a zero length packet\n\t\t * after the bulk-in transmission of a length divisible by bulk packet\n\t\t * size (64 bytes) as required by the USB specification.\n\t\t * Therefore libusb would wait for continuation of transmission.\n\t\t * Workaround: Limit bulk read size to expected number of bytes\n\t\t * for problematic transfer sizes. Otherwise use the maximum buffer\n\t\t * size here because the KitProg sometimes doesn't like bulk reads\n\t\t * of fewer than 62 bytes. (?!?!)\n\t\t */\n\t\tsize_t read_count_workaround = SWD_MAX_BUFFER_LENGTH;\n\t\tif (read_count % 64 == 0)\n\t\t\tread_count_workaround = read_count;\n\n\t\tif (jtag_libusb_bulk_read(kitprog_handle->usb_handle,\n\t\t\t\tBULK_EP_IN | LIBUSB_ENDPOINT_IN, (char *)buffer,\n\t\t\t\tread_count_workaround, 1000, &ret)) {\n\t\t\tLOG_ERROR(\"Bulk read failed\");\n\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* Handle garbage data by offsetting the initial read index */\n\t\t\tif ((unsigned int)ret > read_count)\n\t\t\t\tread_index = ret - read_count;\n\t\t\tqueued_retval = ERROR_OK;\n\t\t}\n\n\t\tfor (int i = 0; i < pending_transfer_count; i++) {\n\t\t\tif (pending_transfers[i].cmd & SWD_CMD_RNW) {\n\t\t\t\tuint32_t data = le_to_h_u32(&buffer[read_index]);\n\n\t\t\t\tLOG_DEBUG_IO(\"Read result: %\"PRIx32, data);\n\n\t\t\t\tif (pending_transfers[i].buffer)\n\t\t\t\t\t*(uint32_t *)pending_transfers[i].buffer = data;\n\n\t\t\t\tread_index += 4;\n\t\t\t}\n\n\t\t\tuint8_t ack = buffer[read_index] & 0x07;\n\t\t\tif (ack != SWD_ACK_OK || (buffer[read_index] & 0x08)) {\n\t\t\t\tLOG_DEBUG(\"SWD ack not OK: %d %s\", i,\n\t\t\t\t\t  ack == SWD_ACK_WAIT ? \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\");\n\t\t\t\tqueued_retval = ack == SWD_ACK_WAIT ? ERROR_WAIT : ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tread_index++;\n\t\t}\n\t} while (0);\n\n\tpending_transfer_count = 0;\n\tint retval = queued_retval;\n\tqueued_retval = ERROR_OK;\n\n\treturn retval;\n}\n\nstatic void kitprog_swd_queue_cmd(uint8_t cmd, uint32_t *dst, uint32_t data)\n{\n\tif (pending_transfer_count == pending_queue_len) {\n\t\t/* Not enough room in the queue. Run the queue. */\n\t\tqueued_retval = kitprog_swd_run_queue();\n\t}\n\n\tif (queued_retval != ERROR_OK)\n\t\treturn;\n\n\tpending_transfers[pending_transfer_count].data = data;\n\tpending_transfers[pending_transfer_count].cmd = cmd;\n\tif (cmd & SWD_CMD_RNW) {\n\t\t/* Queue a read transaction */\n\t\tpending_transfers[pending_transfer_count].buffer = dst;\n\t}\n\tpending_transfer_count++;\n}\n\n/*************** jtag lowlevel functions ********************/\n\nstatic int kitprog_reset(int trst, int srst)\n{\n\tint retval = ERROR_OK;\n\n\tif (trst == 1) {\n\t\tLOG_ERROR(\"KitProg: Interface has no TRST\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (srst == 1) {\n\t\tretval = kitprog_reset_target();\n\t\t/* Since the previous command also disables SWCLK output, we need to send an\n\t\t * SWD bus reset command to re-enable it. For some reason, running\n\t\t * kitprog_swd_seq() immediately after kitprog_reset_target() won't\n\t\t * actually fix this. Instead, kitprog_swd_seq() will be run once OpenOCD\n\t\t * tries to send a JTAG-to-SWD sequence, which should happen during\n\t\t * swd_check_reconnect (see the JTAG_TO_SWD case in kitprog_swd_switch_seq).\n\t\t */\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"KitProg: Interface reset failed\");\n\treturn retval;\n}\n\nCOMMAND_HANDLER(kitprog_handle_info_command)\n{\n\tint retval = kitprog_get_info();\n\n\treturn retval;\n}\n\n\nCOMMAND_HANDLER(kitprog_handle_acquire_psoc_command)\n{\n\tint retval = kitprog_generic_acquire();\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(kitprog_handle_init_acquire_psoc_command)\n{\n\tkitprog_init_acquire_psoc = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration kitprog_subcommand_handlers[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = &kitprog_handle_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"show KitProg info\",\n\t},\n\t{\n\t\t.name = \"acquire_psoc\",\n\t\t.handler = &kitprog_handle_acquire_psoc_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"try to acquire a PSoC\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration kitprog_command_handlers[] = {\n\t{\n\t\t.name = \"kitprog\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform KitProg management\",\n\t\t.usage = \"<cmd>\",\n\t\t.chain = kitprog_subcommand_handlers,\n\t},\n\t{\n\t\t.name = \"kitprog_init_acquire_psoc\",\n\t\t.handler = &kitprog_handle_init_acquire_psoc_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"try to acquire a PSoC during init\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct swd_driver kitprog_swd = {\n\t.init = kitprog_swd_init,\n\t.switch_seq = kitprog_swd_switch_seq,\n\t.read_reg = kitprog_swd_read_reg,\n\t.write_reg = kitprog_swd_write_reg,\n\t.run = kitprog_swd_run_queue,\n};\n\nstatic const char * const kitprog_transports[] = { \"swd\", NULL };\n\nstruct adapter_driver kitprog_adapter_driver = {\n\t.name = \"kitprog\",\n\t.transports = kitprog_transports,\n\t.commands = kitprog_command_handlers,\n\n\t.init = kitprog_init,\n\t.quit = kitprog_quit,\n\t.reset = kitprog_reset,\n\n\t.swd_ops = &kitprog_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/libftdi_helper.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_JTAG_DRIVERS_LIBFTDI_HELPER_H\n#define OPENOCD_JTAG_DRIVERS_LIBFTDI_HELPER_H\n\n#include <ftdi.h>\n\n#ifndef HAVE_LIBFTDI_TCIOFLUSH\n/* Backward compatibility with libftdi pre 1.5 */\n\nstatic inline int ftdi_tciflush(struct ftdi_context *ftdi)\n{\n\treturn ftdi_usb_purge_rx_buffer(ftdi);\n}\n\nstatic inline int ftdi_tcoflush(struct ftdi_context *ftdi)\n{\n\treturn ftdi_usb_purge_tx_buffer(ftdi);\n}\n\nstatic inline int ftdi_tcioflush(struct ftdi_context *ftdi)\n{\n\treturn ftdi_usb_purge_buffers(ftdi);\n}\n#endif\n\n#endif /* OPENOCD_JTAG_DRIVERS_LIBFTDI_HELPER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/libusb_helper.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n *                                                                         *\n *   Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com>              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include <helper/log.h>\n#include <jtag/adapter.h>\n#include \"libusb_helper.h\"\n\n/*\n * comment from libusb:\n * As per the USB 3.0 specs, the current maximum limit for the depth is 7.\n */\n#define MAX_USB_PORTS\t7\n\nstatic struct libusb_context *jtag_libusb_context; /**< Libusb context **/\nstatic struct libusb_device **devs; /**< The usb device list **/\n\nstatic int jtag_libusb_error(int err)\n{\n\tswitch (err) {\n\tcase LIBUSB_SUCCESS:\n\t\treturn ERROR_OK;\n\tcase LIBUSB_ERROR_TIMEOUT:\n\t\treturn ERROR_TIMEOUT_REACHED;\n\tcase LIBUSB_ERROR_IO:\n\tcase LIBUSB_ERROR_INVALID_PARAM:\n\tcase LIBUSB_ERROR_ACCESS:\n\tcase LIBUSB_ERROR_NO_DEVICE:\n\tcase LIBUSB_ERROR_NOT_FOUND:\n\tcase LIBUSB_ERROR_BUSY:\n\tcase LIBUSB_ERROR_OVERFLOW:\n\tcase LIBUSB_ERROR_PIPE:\n\tcase LIBUSB_ERROR_INTERRUPTED:\n\tcase LIBUSB_ERROR_NO_MEM:\n\tcase LIBUSB_ERROR_NOT_SUPPORTED:\n\tcase LIBUSB_ERROR_OTHER:\n\t\treturn ERROR_FAIL;\n\tdefault:\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nbool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,\n\t\tconst uint16_t vids[], const uint16_t pids[])\n{\n\tfor (unsigned i = 0; vids[i]; i++) {\n\t\tif (dev_desc->idVendor == vids[i] &&\n\t\t\tdev_desc->idProduct == pids[i]) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS\nstatic bool jtag_libusb_location_equal(struct libusb_device *device)\n{\n\tuint8_t port_path[MAX_USB_PORTS];\n\tuint8_t dev_bus;\n\tint path_len;\n\n\tpath_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS);\n\tif (path_len == LIBUSB_ERROR_OVERFLOW) {\n\t\tLOG_WARNING(\"cannot determine path to usb device! (more than %i ports in path)\\n\",\n\t\t\tMAX_USB_PORTS);\n\t\treturn false;\n\t}\n\tdev_bus = libusb_get_bus_number(device);\n\n\treturn adapter_usb_location_equal(dev_bus, port_path, path_len);\n}\n#else /* HAVE_LIBUSB_GET_PORT_NUMBERS */\nstatic bool jtag_libusb_location_equal(struct libusb_device *device)\n{\n\treturn true;\n}\n#endif /* HAVE_LIBUSB_GET_PORT_NUMBERS */\n\n\n/* Returns true if the string descriptor indexed by str_index in device matches string */\nstatic bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,\n\t\t\t\t\t\t\t\t\tconst char *string)\n{\n\tint retval;\n\tbool matched;\n\tchar desc_string[256+1]; /* Max size of string descriptor */\n\n\tif (str_index == 0)\n\t\treturn false;\n\n\tretval = libusb_get_string_descriptor_ascii(device, str_index,\n\t\t\t(unsigned char *)desc_string, sizeof(desc_string)-1);\n\tif (retval < 0) {\n\t\tLOG_ERROR(\"libusb_get_string_descriptor_ascii() failed with %d\", retval);\n\t\treturn false;\n\t}\n\n\t/* Null terminate descriptor string in case it needs to be logged. */\n\tdesc_string[sizeof(desc_string)-1] = '\\0';\n\n\tmatched = strncmp(string, desc_string, sizeof(desc_string)) == 0;\n\tif (!matched)\n\t\tLOG_DEBUG(\"Device serial number '%s' doesn't match requested serial '%s'\",\n\t\t\tdesc_string, string);\n\treturn matched;\n}\n\nstatic bool jtag_libusb_match_serial(struct libusb_device_handle *device,\n\t\tstruct libusb_device_descriptor *dev_desc, const char *serial,\n\t\tadapter_get_alternate_serial_fn adapter_get_alternate_serial)\n{\n\tif (string_descriptor_equal(device, dev_desc->iSerialNumber, serial))\n\t\treturn true;\n\n\t/* check the alternate serial helper */\n\tif (!adapter_get_alternate_serial)\n\t\treturn false;\n\n\t/* get the alternate serial */\n\tchar *alternate_serial = adapter_get_alternate_serial(device, dev_desc);\n\n\t/* check possible failures */\n\tif (!alternate_serial)\n\t\treturn false;\n\n\t/* then compare and free the alternate serial */\n\tbool match = false;\n\tif (strcmp(serial, alternate_serial) == 0)\n\t\tmatch = true;\n\telse\n\t\tLOG_DEBUG(\"Device alternate serial number '%s' doesn't match requested serial '%s'\",\n\t\t\t\talternate_serial, serial);\n\n\tfree(alternate_serial);\n\treturn match;\n}\n\nint jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],\n\t\tstruct libusb_device_handle **out,\n\t\tadapter_get_alternate_serial_fn adapter_get_alternate_serial)\n{\n\tint cnt, idx, err_code;\n\tint retval = ERROR_FAIL;\n\tbool serial_mismatch = false;\n\tstruct libusb_device_handle *libusb_handle = NULL;\n\tconst char *serial = adapter_get_required_serial();\n\n\tif (libusb_init(&jtag_libusb_context) < 0)\n\t\treturn ERROR_FAIL;\n\n\tcnt = libusb_get_device_list(jtag_libusb_context, &devs);\n\n\tfor (idx = 0; idx < cnt; idx++) {\n\t\tstruct libusb_device_descriptor dev_desc;\n\n\t\tif (libusb_get_device_descriptor(devs[idx], &dev_desc) != 0)\n\t\t\tcontinue;\n\n\t\tif (!jtag_libusb_match_ids(&dev_desc, vids, pids))\n\t\t\tcontinue;\n\n\t\tif (adapter_usb_get_location() && !jtag_libusb_location_equal(devs[idx]))\n\t\t\tcontinue;\n\n\t\terr_code = libusb_open(devs[idx], &libusb_handle);\n\n\t\tif (err_code) {\n\t\t\tLOG_ERROR(\"libusb_open() failed with %s\",\n\t\t\t\t  libusb_error_name(err_code));\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Device must be open to use libusb_get_string_descriptor_ascii. */\n\t\tif (serial &&\n\t\t\t\t!jtag_libusb_match_serial(libusb_handle, &dev_desc, serial, adapter_get_alternate_serial)) {\n\t\t\tserial_mismatch = true;\n\t\t\tlibusb_close(libusb_handle);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Success. */\n\t\t*out = libusb_handle;\n\t\tretval = ERROR_OK;\n\t\tserial_mismatch = false;\n\t\tbreak;\n\t}\n\tif (cnt >= 0)\n\t\tlibusb_free_device_list(devs, 1);\n\n\tif (serial_mismatch)\n\t\tLOG_INFO(\"No device matches the serial string\");\n\n\tif (retval != ERROR_OK)\n\t\tlibusb_exit(jtag_libusb_context);\n\n\treturn retval;\n}\n\nvoid jtag_libusb_close(struct libusb_device_handle *dev)\n{\n\t/* Close device */\n\tlibusb_close(dev);\n\n\tlibusb_exit(jtag_libusb_context);\n}\n\nint jtag_libusb_control_transfer(struct libusb_device_handle *dev, uint8_t request_type,\n\t\tuint8_t request, uint16_t value, uint16_t index, char *bytes,\n\t\tuint16_t size, unsigned int timeout)\n{\n\tint transferred = 0;\n\n\ttransferred = libusb_control_transfer(dev, request_type, request, value, index,\n\t\t\t\t(unsigned char *)bytes, size, timeout);\n\n\tif (transferred < 0)\n\t\ttransferred = 0;\n\n\treturn transferred;\n}\n\nint jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep, char *bytes,\n\t\t\t   int size, int timeout, int *transferred)\n{\n\tint ret;\n\n\t*transferred = 0;\n\n\tret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,\n\t\t\t\t   transferred, timeout);\n\tif (ret != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_bulk_write error: %s\", libusb_error_name(ret));\n\t\treturn jtag_libusb_error(ret);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep, char *bytes,\n\t\t\t  int size, int timeout, int *transferred)\n{\n\tint ret;\n\n\t*transferred = 0;\n\n\tret = libusb_bulk_transfer(dev, ep, (unsigned char *)bytes, size,\n\t\t\t\t   transferred, timeout);\n\tif (ret != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_bulk_read error: %s\", libusb_error_name(ret));\n\t\treturn jtag_libusb_error(ret);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint jtag_libusb_set_configuration(struct libusb_device_handle *devh,\n\t\tint configuration)\n{\n\tstruct libusb_device *udev = libusb_get_device(devh);\n\tint retval = -99;\n\n\tstruct libusb_config_descriptor *config = NULL;\n\tint current_config = -1;\n\n\tretval = libusb_get_configuration(devh, &current_config);\n\tif (retval != 0)\n\t\treturn retval;\n\n\tretval = libusb_get_config_descriptor(udev, configuration, &config);\n\tif (retval != 0 || !config)\n\t\treturn retval;\n\n\t/* Only change the configuration if it is not already set to the\n\t   same one. Otherwise this issues a lightweight reset and hangs\n\t   LPC-Link2 with JLink firmware. */\n\tif (current_config != config->bConfigurationValue)\n\t\tretval = libusb_set_configuration(devh, config->bConfigurationValue);\n\n\tlibusb_free_config_descriptor(config);\n\n\treturn retval;\n}\n\nint jtag_libusb_choose_interface(struct libusb_device_handle *devh,\n\t\tunsigned int *usb_read_ep,\n\t\tunsigned int *usb_write_ep,\n\t\tint bclass, int subclass, int protocol, int trans_type)\n{\n\tstruct libusb_device *udev = libusb_get_device(devh);\n\tconst struct libusb_interface *inter;\n\tconst struct libusb_interface_descriptor *interdesc;\n\tconst struct libusb_endpoint_descriptor *epdesc;\n\tstruct libusb_config_descriptor *config;\n\n\t*usb_read_ep = *usb_write_ep = 0;\n\n\tlibusb_get_config_descriptor(udev, 0, &config);\n\tfor (int i = 0; i < (int)config->bNumInterfaces; i++) {\n\t\tinter = &config->interface[i];\n\n\t\tinterdesc = &inter->altsetting[0];\n\t\tfor (int k = 0;\n\t\t     k < (int)interdesc->bNumEndpoints; k++) {\n\t\t\tif ((bclass > 0 && interdesc->bInterfaceClass != bclass) ||\n\t\t\t    (subclass > 0 && interdesc->bInterfaceSubClass != subclass) ||\n\t\t\t    (protocol > 0 && interdesc->bInterfaceProtocol != protocol))\n\t\t\t\tcontinue;\n\n\t\t\tepdesc = &interdesc->endpoint[k];\n\t\t\tif (trans_type > 0 && (epdesc->bmAttributes & 0x3) != trans_type)\n\t\t\t\tcontinue;\n\n\t\t\tuint8_t epnum = epdesc->bEndpointAddress;\n\t\t\tbool is_input = epnum & 0x80;\n\t\t\tLOG_DEBUG(\"usb ep %s %02x\",\n\t\t\t\t  is_input ? \"in\" : \"out\", epnum);\n\n\t\t\tif (is_input)\n\t\t\t\t*usb_read_ep = epnum;\n\t\t\telse\n\t\t\t\t*usb_write_ep = epnum;\n\n\t\t\tif (*usb_read_ep && *usb_write_ep) {\n\t\t\t\tLOG_DEBUG(\"Claiming interface %d\", (int)interdesc->bInterfaceNumber);\n\t\t\t\tlibusb_claim_interface(devh, (int)interdesc->bInterfaceNumber);\n\t\t\t\tlibusb_free_config_descriptor(config);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\tlibusb_free_config_descriptor(config);\n\n\treturn ERROR_FAIL;\n}\n\nint jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid)\n{\n\tstruct libusb_device_descriptor dev_desc;\n\n\tif (libusb_get_device_descriptor(dev, &dev_desc) == 0) {\n\t\t*pid = dev_desc.idProduct;\n\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nint jtag_libusb_handle_events_completed(int *completed)\n{\n\treturn libusb_handle_events_completed(jtag_libusb_context, completed);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/libusb_helper.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n *                                                                         *\n *   Copyright (C) 2011 by Mauro Gamba <maurillo71@gmail.com>              *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H\n#define OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H\n\n#include <libusb.h>\n\n/* When we debug a target that works as a USB device, halting the target causes the\n * USB communication with the USB host to become unresponsive. The host will try\n * to reconnect/reset/setup the unresponsive device during which communication\n * with other devices on the same USB bus can get stalled for several seconds.\n * If the JTAG adapter is on the same bus, we need to make sure openOCD will wait\n * for packets at least as long as the host USB stack. Otherwise the USB stack\n * might deliver a valid packet, but openOCD would ignore it due to the timeout.\n * The xHCI spec uses 5 sec timeouts, so let's use that in openOCD with some margin.\n *\n * Use this value in all libusb calls. HID API might have a libusb backend and\n * would probably be victim to the same bug, so it should use this timeout, too.\n */\n#define LIBUSB_TIMEOUT_MS\t(6000)\n\n/* this callback should return a non NULL value only when the serial could not\n * be retrieved by the standard 'libusb_get_string_descriptor_ascii' */\ntypedef char * (*adapter_get_alternate_serial_fn)(struct libusb_device_handle *device,\n\t\tstruct libusb_device_descriptor *dev_desc);\n\nbool jtag_libusb_match_ids(struct libusb_device_descriptor *dev_desc,\n\t\tconst uint16_t vids[], const uint16_t pids[]);\nint jtag_libusb_open(const uint16_t vids[], const uint16_t pids[],\n\t\tstruct libusb_device_handle **out,\n\t\tadapter_get_alternate_serial_fn adapter_get_alternate_serial);\nvoid jtag_libusb_close(struct libusb_device_handle *dev);\nint jtag_libusb_control_transfer(struct libusb_device_handle *dev,\n\t\tuint8_t request_type, uint8_t request, uint16_t value,\n\t\tuint16_t index, char *bytes, uint16_t size, unsigned int timeout);\nint jtag_libusb_bulk_write(struct libusb_device_handle *dev, int ep,\n\t\tchar *bytes, int size, int timeout, int *transferred);\nint jtag_libusb_bulk_read(struct libusb_device_handle *dev, int ep,\n\t\tchar *bytes, int size, int timeout, int *transferred);\nint jtag_libusb_set_configuration(struct libusb_device_handle *devh,\n\t\tint configuration);\n/**\n * Find the first interface optionally matching class, subclass and\n * protocol and claim it.\n * @param devh _libusb_ device handle.\n * @param usb_read_ep A pointer to a variable where the _IN_ endpoint\n *\tnumber will be stored.\n * @param usb_write_ep A pointer to a variable where the _OUT_ endpoint\n *\tnumber will be stored.\n * @param bclass `bInterfaceClass` to match, or -1 to ignore this field.\n * @param subclass `bInterfaceSubClass` to match, or -1 to ignore this field.\n * @param protocol `bInterfaceProtocol` to match, or -1 to ignore this field.\n * @param trans_type `bmAttributes Bits 0..1 Transfer type` to match, or -1 to ignore this field.\n * @returns Returns ERROR_OK on success, ERROR_FAIL otherwise.\n */\nint jtag_libusb_choose_interface(struct libusb_device_handle *devh,\n\t\tunsigned int *usb_read_ep,\n\t\tunsigned int *usb_write_ep,\n\t\tint bclass, int subclass, int protocol, int trans_type);\nint jtag_libusb_get_pid(struct libusb_device *dev, uint16_t *pid);\nint jtag_libusb_handle_events_completed(int *completed);\n\n#endif /* OPENOCD_JTAG_DRIVERS_LIBUSB_HELPER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/linuxgpiod.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n/*\n * Bitbang driver for Linux GPIO descriptors through libgpiod\n * Copyright (C) 2020 Antonio Borneo <borneo.antonio@gmail.com>\n *\n * Largely based on sysfsgpio driver\n * Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au\n * Copyright (C) 2014 by Jean-Christian de Rivaz <jc@eclis.ch>\n * Copyright (C) 2014 by Paul Fertser <fercerpav@gmail.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <gpiod.h>\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include \"bitbang.h\"\n\nstatic struct gpiod_chip *gpiod_chip[ADAPTER_GPIO_IDX_NUM] = {};\nstatic struct gpiod_line *gpiod_line[ADAPTER_GPIO_IDX_NUM] = {};\n\nstatic int last_swclk;\nstatic int last_swdio;\nstatic bool last_stored;\nstatic bool swdio_input;\n\nstatic const struct adapter_gpio_config *adapter_gpio_config;\n\n/*\n * Helper function to determine if gpio config is valid\n *\n * Assume here that there will be less than 10000 gpios per gpiochip, and less\n * than 1000 gpiochips.\n */\nstatic bool is_gpio_config_valid(enum adapter_gpio_config_index idx)\n{\n\treturn adapter_gpio_config[idx].chip_num >= 0\n\t\t&& adapter_gpio_config[idx].chip_num < 1000\n\t\t&& adapter_gpio_config[idx].gpio_num >= 0\n\t\t&& adapter_gpio_config[idx].gpio_num < 10000;\n}\n\n/* Bitbang interface read of TDO */\nstatic bb_value_t linuxgpiod_read(void)\n{\n\tint retval;\n\n\tretval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_TDO]);\n\tif (retval < 0) {\n\t\tLOG_WARNING(\"reading tdo failed\");\n\t\treturn 0;\n\t}\n\n\treturn retval ? BB_HIGH : BB_LOW;\n}\n\n/*\n * Bitbang interface write of TCK, TMS, TDI\n *\n * Seeing as this is the only function where the outputs are changed,\n * we can cache the old value to avoid needlessly writing it.\n */\nstatic int linuxgpiod_write(int tck, int tms, int tdi)\n{\n\tstatic int last_tck;\n\tstatic int last_tms;\n\tstatic int last_tdi;\n\n\tstatic int first_time;\n\n\tint retval;\n\n\tif (!first_time) {\n\t\tlast_tck = !tck;\n\t\tlast_tms = !tms;\n\t\tlast_tdi = !tdi;\n\t\tfirst_time = 1;\n\t}\n\n\tif (tdi != last_tdi) {\n\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TDI], tdi);\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"writing tdi failed\");\n\t}\n\n\tif (tms != last_tms) {\n\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TMS], tms);\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"writing tms failed\");\n\t}\n\n\t/* write clk last */\n\tif (tck != last_tck) {\n\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TCK], tck);\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"writing tck failed\");\n\t}\n\n\tlast_tdi = tdi;\n\tlast_tms = tms;\n\tlast_tck = tck;\n\n\treturn ERROR_OK;\n}\n\nstatic int linuxgpiod_swdio_read(void)\n{\n\tint retval;\n\n\tretval = gpiod_line_get_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);\n\tif (retval < 0) {\n\t\tLOG_WARNING(\"Fail read swdio\");\n\t\treturn 0;\n\t}\n\n\treturn retval;\n}\n\nstatic void linuxgpiod_swdio_drive(bool is_output)\n{\n\tint retval;\n\n\t/*\n\t * FIXME: change direction requires release and re-require the line\n\t * https://stackoverflow.com/questions/58735140/\n\t * this would change in future libgpiod\n\t */\n\tgpiod_line_release(gpiod_line[ADAPTER_GPIO_IDX_SWDIO]);\n\n\tif (is_output) {\n\t\tif (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {\n\t\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 1);\n\t\t\tif (retval < 0)\n\t\t\t\tLOG_WARNING(\"Fail set swdio_dir\");\n\t\t}\n\t\tretval = gpiod_line_request_output(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], \"OpenOCD\", 1);\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"Fail request_output line swdio\");\n\t} else {\n\t\tretval = gpiod_line_request_input(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], \"OpenOCD\");\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"Fail request_input line swdio\");\n\t\tif (gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR]) {\n\t\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO_DIR], 0);\n\t\t\tif (retval < 0)\n\t\t\t\tLOG_WARNING(\"Fail set swdio_dir\");\n\t\t}\n\t}\n\n\tlast_stored = false;\n\tswdio_input = !is_output;\n}\n\nstatic int linuxgpiod_swd_write(int swclk, int swdio)\n{\n\tint retval;\n\n\tif (!swdio_input) {\n\t\tif (!last_stored || (swdio != last_swdio)) {\n\t\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWDIO], swdio);\n\t\t\tif (retval < 0)\n\t\t\t\tLOG_WARNING(\"Fail set swdio\");\n\t\t}\n\t}\n\n\t/* write swclk last */\n\tif (!last_stored || (swclk != last_swclk)) {\n\t\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SWCLK], swclk);\n\t\tif (retval < 0)\n\t\t\tLOG_WARNING(\"Fail set swclk\");\n\t}\n\n\tlast_swdio = swdio;\n\tlast_swclk = swclk;\n\tlast_stored = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int linuxgpiod_blink(int on)\n{\n\tint retval;\n\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_LED))\n\t\treturn ERROR_OK;\n\n\tretval = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_LED], on);\n\tif (retval < 0)\n\t\tLOG_WARNING(\"Fail set led\");\n\treturn retval;\n}\n\nstatic struct bitbang_interface linuxgpiod_bitbang = {\n\t.read = linuxgpiod_read,\n\t.write = linuxgpiod_write,\n\t.swdio_read = linuxgpiod_swdio_read,\n\t.swdio_drive = linuxgpiod_swdio_drive,\n\t.swd_write = linuxgpiod_swd_write,\n\t.blink = linuxgpiod_blink,\n};\n\n/*\n * Bitbang interface to manipulate reset lines SRST and TRST\n *\n * (1) assert or (0) deassert reset lines\n */\nstatic int linuxgpiod_reset(int trst, int srst)\n{\n\tint retval1 = 0, retval2 = 0;\n\n\tLOG_DEBUG(\"linuxgpiod_reset\");\n\n\t/*\n\t * active low behaviour handled by \"adaptor gpio\" command and\n\t * GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW flag when requesting the line.\n\t */\n\tif (gpiod_line[ADAPTER_GPIO_IDX_SRST]) {\n\t\tretval1 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_SRST], srst);\n\t\tif (retval1 < 0)\n\t\t\tLOG_WARNING(\"set srst value failed\");\n\t}\n\n\tif (gpiod_line[ADAPTER_GPIO_IDX_TRST]) {\n\t\tretval2 = gpiod_line_set_value(gpiod_line[ADAPTER_GPIO_IDX_TRST], trst);\n\t\tif (retval2 < 0)\n\t\t\tLOG_WARNING(\"set trst value failed\");\n\t}\n\n\treturn ((retval1 < 0) || (retval2 < 0)) ? ERROR_FAIL : ERROR_OK;\n}\n\nstatic bool linuxgpiod_jtag_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TCK))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TMS))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDI))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_TDO))\n\t\treturn false;\n\treturn true;\n}\n\nstatic bool linuxgpiod_swd_mode_possible(void)\n{\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWCLK))\n\t\treturn false;\n\tif (!is_gpio_config_valid(ADAPTER_GPIO_IDX_SWDIO))\n\t\treturn false;\n\treturn true;\n}\n\nstatic inline void helper_release(enum adapter_gpio_config_index idx)\n{\n\tif (gpiod_line[idx]) {\n\t\tgpiod_line_release(gpiod_line[idx]);\n\t\tgpiod_line[idx] = NULL;\n\t}\n\tif (gpiod_chip[idx]) {\n\t\tgpiod_chip_close(gpiod_chip[idx]);\n\t\tgpiod_chip[idx] = NULL;\n\t}\n}\n\nstatic int linuxgpiod_quit(void)\n{\n\tLOG_DEBUG(\"linuxgpiod_quit\");\n\tfor (int i = 0; i < ADAPTER_GPIO_IDX_NUM; ++i)\n\t\thelper_release(i);\n\n\treturn ERROR_OK;\n}\n\nstatic int helper_get_line(enum adapter_gpio_config_index idx)\n{\n\tif (!is_gpio_config_valid(idx))\n\t\treturn ERROR_OK;\n\n\tint dir = GPIOD_LINE_REQUEST_DIRECTION_INPUT, flags = 0, val = 0, retval;\n\n\tgpiod_chip[idx] = gpiod_chip_open_by_number(adapter_gpio_config[idx].chip_num);\n\tif (!gpiod_chip[idx]) {\n\t\tLOG_ERROR(\"Cannot open LinuxGPIOD chip %d for %s\", adapter_gpio_config[idx].chip_num,\n\t\t\tadapter_gpio_get_name(idx));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tgpiod_line[idx] = gpiod_chip_get_line(gpiod_chip[idx], adapter_gpio_config[idx].gpio_num);\n\tif (!gpiod_line[idx]) {\n\t\tLOG_ERROR(\"Error get line %s\", adapter_gpio_get_name(idx));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tswitch (adapter_gpio_config[idx].init_state) {\n\tcase ADAPTER_GPIO_INIT_STATE_INPUT:\n\t\tdir = GPIOD_LINE_REQUEST_DIRECTION_INPUT;\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_INACTIVE:\n\t\tdir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;\n\t\tval = 0;\n\t\tbreak;\n\tcase ADAPTER_GPIO_INIT_STATE_ACTIVE:\n\t\tdir = GPIOD_LINE_REQUEST_DIRECTION_OUTPUT;\n\t\tval = 1;\n\t\tbreak;\n\t}\n\n\tswitch (adapter_gpio_config[idx].drive) {\n\tcase ADAPTER_GPIO_DRIVE_MODE_PUSH_PULL:\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_DRAIN:\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_OPEN_DRAIN;\n\t\tbreak;\n\tcase ADAPTER_GPIO_DRIVE_MODE_OPEN_SOURCE:\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_OPEN_SOURCE;\n\t\tbreak;\n\t}\n\n\tswitch (adapter_gpio_config[idx].pull) {\n\tcase ADAPTER_GPIO_PULL_NONE:\n#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_BIAS_DISABLE;\n#endif\n\t\tbreak;\n\tcase ADAPTER_GPIO_PULL_UP:\n#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_UP;\n#else\n\t\tLOG_WARNING(\"linuxgpiod: ignoring request for pull-up on %s: not supported by gpiod v%s\",\n\t\t\tadapter_gpio_get_name(idx), gpiod_version_string());\n#endif\n\t\tbreak;\n\tcase ADAPTER_GPIO_PULL_DOWN:\n#ifdef GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_BIAS_PULL_DOWN;\n#else\n\t\tLOG_WARNING(\"linuxgpiod: ignoring request for pull-down on %s: not supported by gpiod v%s\",\n\t\t\tadapter_gpio_get_name(idx), gpiod_version_string());\n#endif\n\t\tbreak;\n\t}\n\n\tif (adapter_gpio_config[idx].active_low)\n\t\tflags |= GPIOD_LINE_REQUEST_FLAG_ACTIVE_LOW;\n\n\tstruct gpiod_line_request_config config = {\n\t\t.consumer = \"OpenOCD\",\n\t\t.request_type = dir,\n\t\t.flags = flags,\n\t};\n\n\tretval = gpiod_line_request(gpiod_line[idx], &config, val);\n\tif (retval < 0) {\n\t\tLOG_ERROR(\"Error requesting gpio line %s\", adapter_gpio_get_name(idx));\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int linuxgpiod_init(void)\n{\n\tLOG_INFO(\"Linux GPIOD JTAG/SWD bitbang driver\");\n\n\tbitbang_interface = &linuxgpiod_bitbang;\n\tadapter_gpio_config = adapter_gpio_get_config();\n\n\t/*\n\t * Configure JTAG/SWD signals. Default directions and initial states are handled\n\t * by adapter.c and \"adapter gpio\" command.\n\t */\n\n\tif (transport_is_jtag()) {\n\t\tif (!linuxgpiod_jtag_mode_possible()) {\n\t\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios for JTAG mode\");\n\t\t\tgoto out_error;\n\t\t}\n\n\t\tif (helper_get_line(ADAPTER_GPIO_IDX_TDO) != ERROR_OK ||\n\t\t\thelper_get_line(ADAPTER_GPIO_IDX_TDI) != ERROR_OK ||\n\t\t\thelper_get_line(ADAPTER_GPIO_IDX_TCK) != ERROR_OK ||\n\t\t\thelper_get_line(ADAPTER_GPIO_IDX_TMS) != ERROR_OK ||\n\t\t\thelper_get_line(ADAPTER_GPIO_IDX_TRST) != ERROR_OK)\n\t\t\t\tgoto out_error;\n\t}\n\n\tif (transport_is_swd()) {\n\t\tint retval1, retval2;\n\t\tif (!linuxgpiod_swd_mode_possible()) {\n\t\t\tLOG_ERROR(\"Require swclk and swdio gpio for SWD mode\");\n\t\t\tgoto out_error;\n\t\t}\n\n\t\t/*\n\t\t * swdio and its buffer should be initialized in the order that prevents\n\t\t * two outputs from being connected together. This will occur if the\n\t\t * swdio GPIO is configured as an output while the external buffer is\n\t\t * configured to send the swdio signal from the target to the GPIO.\n\t\t */\n\t\tif (adapter_gpio_config[ADAPTER_GPIO_IDX_SWDIO].init_state == ADAPTER_GPIO_INIT_STATE_INPUT) {\n\t\t\tretval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);\n\t\t\tretval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t} else {\n\t\t\tretval1 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO_DIR);\n\t\t\tretval2 = helper_get_line(ADAPTER_GPIO_IDX_SWDIO);\n\t\t}\n\t\tif (retval1 != ERROR_OK || retval2 != ERROR_OK)\n\t\t\tgoto out_error;\n\n\t\tif (helper_get_line(ADAPTER_GPIO_IDX_SWCLK) != ERROR_OK)\n\t\t\tgoto out_error;\n\t}\n\n\tif (helper_get_line(ADAPTER_GPIO_IDX_SRST) != ERROR_OK ||\n\t\thelper_get_line(ADAPTER_GPIO_IDX_LED) != ERROR_OK)\n\t\t\tgoto out_error;\n\n\treturn ERROR_OK;\n\nout_error:\n\tlinuxgpiod_quit();\n\n\treturn ERROR_JTAG_INIT_FAILED;\n}\n\nstatic const char *const linuxgpiod_transport[] = { \"swd\", \"jtag\", NULL };\n\nstatic struct jtag_interface linuxgpiod_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver linuxgpiod_adapter_driver = {\n\t.name = \"linuxgpiod\",\n\t.transports = linuxgpiod_transport,\n\n\t.init = linuxgpiod_init,\n\t.quit = linuxgpiod_quit,\n\t.reset = linuxgpiod_reset,\n\n\t.jtag_ops = &linuxgpiod_interface,\n\t.swd_ops = &bitbang_swd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/minidriver_imp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2007-2009 Øyvind Harboe <oyvind.harboe@zylin.com>       *\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H\n#define OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H\n\n#include <jtag/commands.h>\n\nstatic inline void interface_jtag_add_scan_check_alloc(struct scan_field *field)\n{\n\tunsigned num_bytes = DIV_ROUND_UP(field->num_bits, 8);\n\tfield->in_value = cmd_queue_alloc(num_bytes);\n}\n\nvoid interface_jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0);\n\nvoid interface_jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,\n\t\t\t\t  jtag_callback_data_t data1, jtag_callback_data_t data2,\n\t\t\t\t  jtag_callback_data_t data3);\n\nvoid jtag_add_callback4(jtag_callback_t f, jtag_callback_data_t data0,\n\t\t\tjtag_callback_data_t data1, jtag_callback_data_t data2,\n\t\t\tjtag_callback_data_t data3);\n\n#endif /* OPENOCD_JTAG_DRIVERS_MINIDRIVER_IMP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/mpsse.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/**************************************************************************\n *   Copyright (C) 2012 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mpsse.h\"\n#include \"helper/log.h\"\n#include \"helper/replacements.h\"\n#include \"helper/time_support.h\"\n#include \"libusb_helper.h\"\n#include <libusb.h>\n\n/* Compatibility define for older libusb-1.0 */\n#ifndef LIBUSB_CALL\n#define LIBUSB_CALL\n#endif\n\n#define DEBUG_PRINT_BUF(buf, len) \\\n\tdo { \\\n\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) { \\\n\t\t\tchar buf_string[32 * 3 + 1]; \\\n\t\t\tint buf_string_pos = 0; \\\n\t\t\tfor (int i = 0; i < len; i++) { \\\n\t\t\t\tbuf_string_pos += sprintf(buf_string + buf_string_pos, \" %02x\", buf[i]); \\\n\t\t\t\tif (i % 32 == 32 - 1) { \\\n\t\t\t\t\tLOG_DEBUG_IO(\"%s\", buf_string); \\\n\t\t\t\t\tbuf_string_pos = 0; \\\n\t\t\t\t} \\\n\t\t\t} \\\n\t\t\tif (buf_string_pos > 0) \\\n\t\t\t\tLOG_DEBUG_IO(\"%s\", buf_string);\\\n\t\t} \\\n\t} while (0)\n\n#define FTDI_DEVICE_OUT_REQTYPE (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE)\n#define FTDI_DEVICE_IN_REQTYPE (0x80 | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE)\n\n#define BITMODE_MPSSE 0x02\n\n#define SIO_RESET_REQUEST             0x00\n#define SIO_SET_LATENCY_TIMER_REQUEST 0x09\n#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A\n#define SIO_SET_BITMODE_REQUEST       0x0B\n\n#define SIO_RESET_SIO 0\n#define SIO_RESET_PURGE_RX 1\n#define SIO_RESET_PURGE_TX 2\n\nstruct mpsse_ctx {\n\tstruct libusb_context *usb_ctx;\n\tstruct libusb_device_handle *usb_dev;\n\tunsigned int usb_write_timeout;\n\tunsigned int usb_read_timeout;\n\tuint8_t in_ep;\n\tuint8_t out_ep;\n\tuint16_t max_packet_size;\n\tuint16_t index;\n\tuint8_t interface;\n\tenum ftdi_chip_type type;\n\tuint8_t *write_buffer;\n\tunsigned write_size;\n\tunsigned write_count;\n\tuint8_t *read_buffer;\n\tunsigned read_size;\n\tunsigned read_count;\n\tuint8_t *read_chunk;\n\tunsigned read_chunk_size;\n\tstruct bit_copy_queue read_queue;\n\tint retval;\n};\n\n/* Returns true if the string descriptor indexed by str_index in device matches string */\nstatic bool string_descriptor_equal(struct libusb_device_handle *device, uint8_t str_index,\n\tconst char *string)\n{\n\tint retval;\n\tchar desc_string[256]; /* Max size of string descriptor */\n\tretval = libusb_get_string_descriptor_ascii(device, str_index, (unsigned char *)desc_string,\n\t\t\tsizeof(desc_string));\n\tif (retval < 0) {\n\t\tLOG_ERROR(\"libusb_get_string_descriptor_ascii() failed with %s\", libusb_error_name(retval));\n\t\treturn false;\n\t}\n\treturn strncmp(string, desc_string, sizeof(desc_string)) == 0;\n}\n\nstatic bool device_location_equal(struct libusb_device *device, const char *location)\n{\n\tbool result = false;\n#ifdef HAVE_LIBUSB_GET_PORT_NUMBERS\n\tchar *loc = strdup(location);\n\tuint8_t port_path[7];\n\tint path_step, path_len;\n\tuint8_t dev_bus = libusb_get_bus_number(device);\n\tchar *ptr;\n\n\tpath_len = libusb_get_port_numbers(device, port_path, 7);\n\tif (path_len == LIBUSB_ERROR_OVERFLOW) {\n\t\tLOG_ERROR(\"cannot determine path to usb device! (more than 7 ports in path)\");\n\t\tgoto done;\n\t}\n\n\tLOG_DEBUG(\"device path has %i steps\", path_len);\n\n\tptr = strtok(loc, \"-:\");\n\tif (!ptr) {\n\t\tLOG_DEBUG(\"no ':' in path\");\n\t\tgoto done;\n\t}\n\tif (atoi(ptr) != dev_bus) {\n\t\tLOG_DEBUG(\"bus mismatch\");\n\t\tgoto done;\n\t}\n\n\tpath_step = 0;\n\twhile (path_step < 7) {\n\t\tptr = strtok(NULL, \".,\");\n\t\tif (!ptr) {\n\t\t\tLOG_DEBUG(\"no more tokens in path at step %i\", path_step);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (path_step < path_len\n\t\t\t&& atoi(ptr) != port_path[path_step]) {\n\t\t\tLOG_DEBUG(\"path mismatch at step %i\", path_step);\n\t\t\tbreak;\n\t\t}\n\n\t\tpath_step++;\n\t};\n\n\t/* walked the full path, all elements match */\n\tif (path_step == path_len)\n\t\tresult = true;\n\n done:\n\tfree(loc);\n#endif\n\treturn result;\n}\n\n/* Helper to open a libusb device that matches vid, pid, product string and/or serial string.\n * Set any field to 0 as a wildcard. If the device is found true is returned, with ctx containing\n * the already opened handle. ctx->interface must be set to the desired interface (channel) number\n * prior to calling this function. */\nstatic bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t vids[], const uint16_t pids[],\n\tconst char *product, const char *serial, const char *location)\n{\n\tstruct libusb_device **list;\n\tstruct libusb_device_descriptor desc;\n\tstruct libusb_config_descriptor *config0;\n\tint err;\n\tbool found = false;\n\tssize_t cnt = libusb_get_device_list(ctx->usb_ctx, &list);\n\tif (cnt < 0)\n\t\tLOG_ERROR(\"libusb_get_device_list() failed with %s\", libusb_error_name(cnt));\n\n\tfor (ssize_t i = 0; i < cnt; i++) {\n\t\tstruct libusb_device *device = list[i];\n\n\t\terr = libusb_get_device_descriptor(device, &desc);\n\t\tif (err != LIBUSB_SUCCESS) {\n\t\t\tLOG_ERROR(\"libusb_get_device_descriptor() failed with %s\", libusb_error_name(err));\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!jtag_libusb_match_ids(&desc, vids, pids))\n\t\t\tcontinue;\n\n\t\terr = libusb_open(device, &ctx->usb_dev);\n\t\tif (err != LIBUSB_SUCCESS) {\n\t\t\tLOG_ERROR(\"libusb_open() failed with %s\",\n\t\t\t\t  libusb_error_name(err));\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (location && !device_location_equal(device, location)) {\n\t\t\tlibusb_close(ctx->usb_dev);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (product && !string_descriptor_equal(ctx->usb_dev, desc.iProduct, product)) {\n\t\t\tlibusb_close(ctx->usb_dev);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (serial && !string_descriptor_equal(ctx->usb_dev, desc.iSerialNumber, serial)) {\n\t\t\tlibusb_close(ctx->usb_dev);\n\t\t\tcontinue;\n\t\t}\n\n\t\tfound = true;\n\t\tbreak;\n\t}\n\n\tlibusb_free_device_list(list, 1);\n\n\tif (!found) {\n\t\t/* The caller reports detailed error desc */\n\t\treturn false;\n\t}\n\n\terr = libusb_get_config_descriptor(libusb_get_device(ctx->usb_dev), 0, &config0);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_get_config_descriptor() failed with %s\", libusb_error_name(err));\n\t\tlibusb_close(ctx->usb_dev);\n\t\treturn false;\n\t}\n\n\t/* Make sure the first configuration is selected */\n\tint cfg;\n\terr = libusb_get_configuration(ctx->usb_dev, &cfg);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_get_configuration() failed with %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\tif (desc.bNumConfigurations > 0 && cfg != config0->bConfigurationValue) {\n\t\terr = libusb_set_configuration(ctx->usb_dev, config0->bConfigurationValue);\n\t\tif (err != LIBUSB_SUCCESS) {\n\t\t\tLOG_ERROR(\"libusb_set_configuration() failed with %s\", libusb_error_name(err));\n\t\t\tgoto error;\n\t\t}\n\t}\n\n\t/* Try to detach ftdi_sio kernel module */\n\terr = libusb_detach_kernel_driver(ctx->usb_dev, ctx->interface);\n\tif (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_NOT_FOUND\n\t\t\t&& err != LIBUSB_ERROR_NOT_SUPPORTED) {\n\t\tLOG_WARNING(\"libusb_detach_kernel_driver() failed with %s, trying to continue anyway\",\n\t\t\tlibusb_error_name(err));\n\t}\n\n\terr = libusb_claim_interface(ctx->usb_dev, ctx->interface);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_claim_interface() failed with %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\t/* Reset FTDI device */\n\terr = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE,\n\t\t\tSIO_RESET_REQUEST, SIO_RESET_SIO,\n\t\t\tctx->index, NULL, 0, ctx->usb_write_timeout);\n\tif (err < 0) {\n\t\tLOG_ERROR(\"failed to reset FTDI device: %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\tswitch (desc.bcdDevice) {\n\tcase 0x500:\n\t\tctx->type = TYPE_FT2232C;\n\t\tbreak;\n\tcase 0x700:\n\t\tctx->type = TYPE_FT2232H;\n\t\tbreak;\n\tcase 0x800:\n\t\tctx->type = TYPE_FT4232H;\n\t\tbreak;\n\tcase 0x900:\n\t\tctx->type = TYPE_FT232H;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"unsupported FTDI chip type: 0x%04x\", desc.bcdDevice);\n\t\tgoto error;\n\t}\n\n\t/* Determine maximum packet size and endpoint addresses */\n\tif (!(desc.bNumConfigurations > 0 && ctx->interface < config0->bNumInterfaces\n\t\t\t&& config0->interface[ctx->interface].num_altsetting > 0))\n\t\tgoto desc_error;\n\n\tconst struct libusb_interface_descriptor *descriptor;\n\tdescriptor = &config0->interface[ctx->interface].altsetting[0];\n\tif (descriptor->bNumEndpoints != 2)\n\t\tgoto desc_error;\n\n\tctx->in_ep = 0;\n\tctx->out_ep = 0;\n\tfor (int i = 0; i < descriptor->bNumEndpoints; i++) {\n\t\tif (descriptor->endpoint[i].bEndpointAddress & 0x80) {\n\t\t\tctx->in_ep = descriptor->endpoint[i].bEndpointAddress;\n\t\t\tctx->max_packet_size =\n\t\t\t\t\tdescriptor->endpoint[i].wMaxPacketSize;\n\t\t} else {\n\t\t\tctx->out_ep = descriptor->endpoint[i].bEndpointAddress;\n\t\t}\n\t}\n\n\tif (ctx->in_ep == 0 || ctx->out_ep == 0)\n\t\tgoto desc_error;\n\n\tlibusb_free_config_descriptor(config0);\n\treturn true;\n\ndesc_error:\n\tLOG_ERROR(\"unrecognized USB device descriptor\");\nerror:\n\tlibusb_free_config_descriptor(config0);\n\tlibusb_close(ctx->usb_dev);\n\treturn false;\n}\n\nstruct mpsse_ctx *mpsse_open(const uint16_t vids[], const uint16_t pids[], const char *description,\n\tconst char *serial, const char *location, int channel)\n{\n\tstruct mpsse_ctx *ctx = calloc(1, sizeof(*ctx));\n\tint err;\n\n\tif (!ctx)\n\t\treturn NULL;\n\n\tbit_copy_queue_init(&ctx->read_queue);\n\tctx->read_chunk_size = 16384;\n\tctx->read_size = 16384;\n\tctx->write_size = 16384;\n\tctx->read_chunk = malloc(ctx->read_chunk_size);\n\tctx->read_buffer = malloc(ctx->read_size);\n\n\t/* Use calloc to make valgrind happy: buffer_write() sets payload\n\t * on bit basis, so some bits can be left uninitialized in write_buffer.\n\t * Although this is perfectly ok with MPSSE, valgrind reports\n\t * Syscall param ioctl(USBDEVFS_SUBMITURB).buffer points to uninitialised byte(s) */\n\tctx->write_buffer = calloc(1, ctx->write_size);\n\n\tif (!ctx->read_chunk || !ctx->read_buffer || !ctx->write_buffer)\n\t\tgoto error;\n\n\tctx->interface = channel;\n\tctx->index = channel + 1;\n\tctx->usb_read_timeout = 5000;\n\tctx->usb_write_timeout = 5000;\n\n\terr = libusb_init(&ctx->usb_ctx);\n\tif (err != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_init() failed with %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\tif (!open_matching_device(ctx, vids, pids, description, serial, location)) {\n\t\tLOG_ERROR(\"unable to open ftdi device with description '%s', \"\n\t\t\t\t\"serial '%s' at bus location '%s'\",\n\t\t\t\tdescription ? description : \"*\",\n\t\t\t\tserial ? serial : \"*\",\n\t\t\t\tlocation ? location : \"*\");\n\t\tctx->usb_dev = NULL;\n\t\tgoto error;\n\t}\n\n\terr = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE,\n\t\t\tSIO_SET_LATENCY_TIMER_REQUEST, 255, ctx->index, NULL, 0,\n\t\t\tctx->usb_write_timeout);\n\tif (err < 0) {\n\t\tLOG_ERROR(\"unable to set latency timer: %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\terr = libusb_control_transfer(ctx->usb_dev,\n\t\t\tFTDI_DEVICE_OUT_REQTYPE,\n\t\t\tSIO_SET_BITMODE_REQUEST,\n\t\t\t0x0b | (BITMODE_MPSSE << 8),\n\t\t\tctx->index,\n\t\t\tNULL,\n\t\t\t0,\n\t\t\tctx->usb_write_timeout);\n\tif (err < 0) {\n\t\tLOG_ERROR(\"unable to set MPSSE bitmode: %s\", libusb_error_name(err));\n\t\tgoto error;\n\t}\n\n\tmpsse_purge(ctx);\n\n\treturn ctx;\nerror:\n\tmpsse_close(ctx);\n\treturn NULL;\n}\n\nvoid mpsse_close(struct mpsse_ctx *ctx)\n{\n\tif (ctx->usb_dev)\n\t\tlibusb_close(ctx->usb_dev);\n\tif (ctx->usb_ctx)\n\t\tlibusb_exit(ctx->usb_ctx);\n\tbit_copy_discard(&ctx->read_queue);\n\n\tfree(ctx->write_buffer);\n\tfree(ctx->read_buffer);\n\tfree(ctx->read_chunk);\n\tfree(ctx);\n}\n\nbool mpsse_is_high_speed(struct mpsse_ctx *ctx)\n{\n\treturn ctx->type != TYPE_FT2232C;\n}\n\nvoid mpsse_purge(struct mpsse_ctx *ctx)\n{\n\tint err;\n\tLOG_DEBUG(\"-\");\n\tctx->write_count = 0;\n\tctx->read_count = 0;\n\tctx->retval = ERROR_OK;\n\tbit_copy_discard(&ctx->read_queue);\n\terr = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,\n\t\t\tSIO_RESET_PURGE_RX, ctx->index, NULL, 0, ctx->usb_write_timeout);\n\tif (err < 0) {\n\t\tLOG_ERROR(\"unable to purge ftdi rx buffers: %s\", libusb_error_name(err));\n\t\treturn;\n\t}\n\n\terr = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST,\n\t\t\tSIO_RESET_PURGE_TX, ctx->index, NULL, 0, ctx->usb_write_timeout);\n\tif (err < 0) {\n\t\tLOG_ERROR(\"unable to purge ftdi tx buffers: %s\", libusb_error_name(err));\n\t\treturn;\n\t}\n}\n\nstatic unsigned buffer_write_space(struct mpsse_ctx *ctx)\n{\n\t/* Reserve one byte for SEND_IMMEDIATE */\n\treturn ctx->write_size - ctx->write_count - 1;\n}\n\nstatic unsigned buffer_read_space(struct mpsse_ctx *ctx)\n{\n\treturn ctx->read_size - ctx->read_count;\n}\n\nstatic void buffer_write_byte(struct mpsse_ctx *ctx, uint8_t data)\n{\n\tLOG_DEBUG_IO(\"%02x\", data);\n\tassert(ctx->write_count < ctx->write_size);\n\tctx->write_buffer[ctx->write_count++] = data;\n}\n\nstatic unsigned buffer_write(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,\n\tunsigned bit_count)\n{\n\tLOG_DEBUG_IO(\"%d bits\", bit_count);\n\tassert(ctx->write_count + DIV_ROUND_UP(bit_count, 8) <= ctx->write_size);\n\tbit_copy(ctx->write_buffer + ctx->write_count, 0, out, out_offset, bit_count);\n\tctx->write_count += DIV_ROUND_UP(bit_count, 8);\n\treturn bit_count;\n}\n\nstatic unsigned buffer_add_read(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset,\n\tunsigned bit_count, unsigned offset)\n{\n\tLOG_DEBUG_IO(\"%d bits, offset %d\", bit_count, offset);\n\tassert(ctx->read_count + DIV_ROUND_UP(bit_count, 8) <= ctx->read_size);\n\tbit_copy_queued(&ctx->read_queue, in, in_offset, ctx->read_buffer + ctx->read_count, offset,\n\t\tbit_count);\n\tctx->read_count += DIV_ROUND_UP(bit_count, 8);\n\treturn bit_count;\n}\n\nvoid mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,\n\tunsigned length, uint8_t mode)\n{\n\tmpsse_clock_data(ctx, out, out_offset, NULL, 0, length, mode);\n}\n\nvoid mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,\n\tuint8_t mode)\n{\n\tmpsse_clock_data(ctx, NULL, 0, in, in_offset, length, mode);\n}\n\nvoid mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,\n\tunsigned in_offset, unsigned length, uint8_t mode)\n{\n\t/* TODO: Fix MSB first modes */\n\tLOG_DEBUG_IO(\"%s%s %d bits\", in ? \"in\" : \"\", out ? \"out\" : \"\", length);\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\t/* TODO: On H chips, use command 0x8E/0x8F if in and out are both 0 */\n\tif (out || (!out && !in))\n\t\tmode |= 0x10;\n\tif (in)\n\t\tmode |= 0x20;\n\n\twhile (length > 0) {\n\t\t/* Guarantee buffer space enough for a minimum size transfer */\n\t\tif (buffer_write_space(ctx) + (length < 8) < (out || (!out && !in) ? 4 : 3)\n\t\t\t\t|| (in && buffer_read_space(ctx) < 1))\n\t\t\tctx->retval = mpsse_flush(ctx);\n\n\t\tif (length < 8) {\n\t\t\t/* Transfer remaining bits in bit mode */\n\t\t\tbuffer_write_byte(ctx, 0x02 | mode);\n\t\t\tbuffer_write_byte(ctx, length - 1);\n\t\t\tif (out)\n\t\t\t\tout_offset += buffer_write(ctx, out, out_offset, length);\n\t\t\tif (in)\n\t\t\t\tin_offset += buffer_add_read(ctx, in, in_offset, length, 8 - length);\n\t\t\tif (!out && !in)\n\t\t\t\tbuffer_write_byte(ctx, 0x00);\n\t\t\tlength = 0;\n\t\t} else {\n\t\t\t/* Byte transfer */\n\t\t\tunsigned this_bytes = length / 8;\n\t\t\t/* MPSSE command limit */\n\t\t\tif (this_bytes > 65536)\n\t\t\t\tthis_bytes = 65536;\n\t\t\t/* Buffer space limit. We already made sure there's space for the minimum\n\t\t\t * transfer. */\n\t\t\tif ((out || (!out && !in)) && this_bytes + 3 > buffer_write_space(ctx))\n\t\t\t\tthis_bytes = buffer_write_space(ctx) - 3;\n\t\t\tif (in && this_bytes > buffer_read_space(ctx))\n\t\t\t\tthis_bytes = buffer_read_space(ctx);\n\n\t\t\tif (this_bytes > 0) {\n\t\t\t\tbuffer_write_byte(ctx, mode);\n\t\t\t\tbuffer_write_byte(ctx, (this_bytes - 1) & 0xff);\n\t\t\t\tbuffer_write_byte(ctx, (this_bytes - 1) >> 8);\n\t\t\t\tif (out)\n\t\t\t\t\tout_offset += buffer_write(ctx,\n\t\t\t\t\t\t\tout,\n\t\t\t\t\t\t\tout_offset,\n\t\t\t\t\t\t\tthis_bytes * 8);\n\t\t\t\tif (in)\n\t\t\t\t\tin_offset += buffer_add_read(ctx,\n\t\t\t\t\t\t\tin,\n\t\t\t\t\t\t\tin_offset,\n\t\t\t\t\t\t\tthis_bytes * 8,\n\t\t\t\t\t\t\t0);\n\t\t\t\tif (!out && !in)\n\t\t\t\t\tfor (unsigned n = 0; n < this_bytes; n++)\n\t\t\t\t\t\tbuffer_write_byte(ctx, 0x00);\n\t\t\t\tlength -= this_bytes * 8;\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,\n\tunsigned length, bool tdi, uint8_t mode)\n{\n\tmpsse_clock_tms_cs(ctx, out, out_offset, NULL, 0, length, tdi, mode);\n}\n\nvoid mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,\n\tunsigned in_offset, unsigned length, bool tdi, uint8_t mode)\n{\n\tLOG_DEBUG_IO(\"%sout %d bits, tdi=%d\", in ? \"in\" : \"\", length, tdi);\n\tassert(out);\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tmode |= 0x42;\n\tif (in)\n\t\tmode |= 0x20;\n\n\twhile (length > 0) {\n\t\t/* Guarantee buffer space enough for a minimum size transfer */\n\t\tif (buffer_write_space(ctx) < 3 || (in && buffer_read_space(ctx) < 1))\n\t\t\tctx->retval = mpsse_flush(ctx);\n\n\t\t/* Byte transfer */\n\t\tunsigned this_bits = length;\n\t\t/* MPSSE command limit */\n\t\t/* NOTE: there's a report of an FT2232 bug in this area, where shifting\n\t\t * exactly 7 bits can make problems with TMS signaling for the last\n\t\t * clock cycle:\n\t\t *\n\t\t * http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00292.html\n\t\t */\n\t\tif (this_bits > 7)\n\t\t\tthis_bits = 7;\n\n\t\tif (this_bits > 0) {\n\t\t\tbuffer_write_byte(ctx, mode);\n\t\t\tbuffer_write_byte(ctx, this_bits - 1);\n\t\t\tuint8_t data = 0;\n\t\t\t/* TODO: Fix MSB first, if allowed in MPSSE */\n\t\t\tbit_copy(&data, 0, out, out_offset, this_bits);\n\t\t\tout_offset += this_bits;\n\t\t\tbuffer_write_byte(ctx, data | (tdi ? 0x80 : 0x00));\n\t\t\tif (in)\n\t\t\t\tin_offset += buffer_add_read(ctx,\n\t\t\t\t\t\tin,\n\t\t\t\t\t\tin_offset,\n\t\t\t\t\t\tthis_bits,\n\t\t\t\t\t\t8 - this_bits);\n\t\t\tlength -= this_bits;\n\t\t}\n\t}\n}\n\nvoid mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)\n{\n\tLOG_DEBUG_IO(\"-\");\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 3)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, 0x80);\n\tbuffer_write_byte(ctx, data);\n\tbuffer_write_byte(ctx, dir);\n}\n\nvoid mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir)\n{\n\tLOG_DEBUG_IO(\"-\");\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 3)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, 0x82);\n\tbuffer_write_byte(ctx, data);\n\tbuffer_write_byte(ctx, dir);\n}\n\nvoid mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data)\n{\n\tLOG_DEBUG_IO(\"-\");\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 1 || buffer_read_space(ctx) < 1)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, 0x81);\n\tbuffer_add_read(ctx, data, 0, 8, 0);\n}\n\nvoid mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data)\n{\n\tLOG_DEBUG_IO(\"-\");\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 1 || buffer_read_space(ctx) < 1)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, 0x83);\n\tbuffer_add_read(ctx, data, 0, 8, 0);\n}\n\nstatic void single_byte_boolean_helper(struct mpsse_ctx *ctx, bool var, uint8_t val_if_true,\n\tuint8_t val_if_false)\n{\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 1)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, var ? val_if_true : val_if_false);\n}\n\nvoid mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable)\n{\n\tLOG_DEBUG(\"%s\", enable ? \"on\" : \"off\");\n\tsingle_byte_boolean_helper(ctx, enable, 0x84, 0x85);\n}\n\nvoid mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor)\n{\n\tLOG_DEBUG(\"%d\", divisor);\n\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring command due to previous error\");\n\t\treturn;\n\t}\n\n\tif (buffer_write_space(ctx) < 3)\n\t\tctx->retval = mpsse_flush(ctx);\n\n\tbuffer_write_byte(ctx, 0x86);\n\tbuffer_write_byte(ctx, divisor & 0xff);\n\tbuffer_write_byte(ctx, divisor >> 8);\n}\n\nint mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable)\n{\n\tif (!mpsse_is_high_speed(ctx))\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"%s\", enable ? \"on\" : \"off\");\n\tsingle_byte_boolean_helper(ctx, enable, 0x8b, 0x8a);\n\n\treturn ERROR_OK;\n}\n\nint mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable)\n{\n\tif (!mpsse_is_high_speed(ctx))\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"%s\", enable ? \"on\" : \"off\");\n\tsingle_byte_boolean_helper(ctx, enable, 0x96, 0x97);\n\n\treturn ERROR_OK;\n}\n\nint mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency)\n{\n\tLOG_DEBUG(\"target %d Hz\", frequency);\n\tassert(frequency >= 0);\n\tint base_clock;\n\n\tif (frequency == 0)\n\t\treturn mpsse_rtck_config(ctx, true);\n\n\tmpsse_rtck_config(ctx, false); /* just try */\n\n\tif (frequency > 60000000 / 2 / 65536 && mpsse_divide_by_5_config(ctx, false) == ERROR_OK) {\n\t\tbase_clock = 60000000;\n\t} else {\n\t\tmpsse_divide_by_5_config(ctx, true); /* just try */\n\t\tbase_clock = 12000000;\n\t}\n\n\tint divisor = (base_clock / 2 + frequency - 1) / frequency - 1;\n\tif (divisor > 65535)\n\t\tdivisor = 65535;\n\tassert(divisor >= 0);\n\n\tmpsse_set_divisor(ctx, divisor);\n\n\tfrequency = base_clock / 2 / (1 + divisor);\n\tLOG_DEBUG(\"actually %d Hz\", frequency);\n\n\treturn frequency;\n}\n\n/* Context needed by the callbacks */\nstruct transfer_result {\n\tstruct mpsse_ctx *ctx;\n\tbool done;\n\tunsigned transferred;\n};\n\nstatic LIBUSB_CALL void read_cb(struct libusb_transfer *transfer)\n{\n\tstruct transfer_result *res = transfer->user_data;\n\tstruct mpsse_ctx *ctx = res->ctx;\n\n\tunsigned packet_size = ctx->max_packet_size;\n\n\tDEBUG_PRINT_BUF(transfer->buffer, transfer->actual_length);\n\n\t/* Strip the two status bytes sent at the beginning of each USB packet\n\t * while copying the chunk buffer to the read buffer */\n\tunsigned num_packets = DIV_ROUND_UP(transfer->actual_length, packet_size);\n\tunsigned chunk_remains = transfer->actual_length;\n\tfor (unsigned i = 0; i < num_packets && chunk_remains > 2; i++) {\n\t\tunsigned this_size = packet_size - 2;\n\t\tif (this_size > chunk_remains - 2)\n\t\t\tthis_size = chunk_remains - 2;\n\t\tif (this_size > ctx->read_count - res->transferred)\n\t\t\tthis_size = ctx->read_count - res->transferred;\n\t\tmemcpy(ctx->read_buffer + res->transferred,\n\t\t\tctx->read_chunk + packet_size * i + 2,\n\t\t\tthis_size);\n\t\tres->transferred += this_size;\n\t\tchunk_remains -= this_size + 2;\n\t\tif (res->transferred == ctx->read_count) {\n\t\t\tres->done = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tLOG_DEBUG_IO(\"raw chunk %d, transferred %d of %d\", transfer->actual_length, res->transferred,\n\t\tctx->read_count);\n\n\tif (!res->done)\n\t\tif (libusb_submit_transfer(transfer) != LIBUSB_SUCCESS)\n\t\t\tres->done = true;\n}\n\nstatic LIBUSB_CALL void write_cb(struct libusb_transfer *transfer)\n{\n\tstruct transfer_result *res = transfer->user_data;\n\tstruct mpsse_ctx *ctx = res->ctx;\n\n\tres->transferred += transfer->actual_length;\n\n\tLOG_DEBUG_IO(\"transferred %d of %d\", res->transferred, ctx->write_count);\n\n\tDEBUG_PRINT_BUF(transfer->buffer, transfer->actual_length);\n\n\tif (res->transferred == ctx->write_count)\n\t\tres->done = true;\n\telse {\n\t\ttransfer->length = ctx->write_count - res->transferred;\n\t\ttransfer->buffer = ctx->write_buffer + res->transferred;\n\t\tif (libusb_submit_transfer(transfer) != LIBUSB_SUCCESS)\n\t\t\tres->done = true;\n\t}\n}\n\nint mpsse_flush(struct mpsse_ctx *ctx)\n{\n\tint retval = ctx->retval;\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG_IO(\"Ignoring flush due to previous error\");\n\t\tassert(ctx->write_count == 0 && ctx->read_count == 0);\n\t\tctx->retval = ERROR_OK;\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG_IO(\"write %d%s, read %d\", ctx->write_count, ctx->read_count ? \"+1\" : \"\",\n\t\t\tctx->read_count);\n\tassert(ctx->write_count > 0 || ctx->read_count == 0); /* No read data without write data */\n\n\tif (ctx->write_count == 0)\n\t\treturn retval;\n\n\tstruct libusb_transfer *read_transfer = NULL;\n\tstruct transfer_result read_result = { .ctx = ctx, .done = true };\n\tif (ctx->read_count) {\n\t\tbuffer_write_byte(ctx, 0x87); /* SEND_IMMEDIATE */\n\t\tread_result.done = false;\n\t\t/* delay read transaction to ensure the FTDI chip can support us with data\n\t\t   immediately after processing the MPSSE commands in the write transaction */\n\t}\n\n\tstruct transfer_result write_result = { .ctx = ctx, .done = false };\n\tstruct libusb_transfer *write_transfer = libusb_alloc_transfer(0);\n\tlibusb_fill_bulk_transfer(write_transfer, ctx->usb_dev, ctx->out_ep, ctx->write_buffer,\n\t\tctx->write_count, write_cb, &write_result, ctx->usb_write_timeout);\n\tretval = libusb_submit_transfer(write_transfer);\n\tif (retval != LIBUSB_SUCCESS)\n\t\tgoto error_check;\n\n\tif (ctx->read_count) {\n\t\tread_transfer = libusb_alloc_transfer(0);\n\t\tlibusb_fill_bulk_transfer(read_transfer, ctx->usb_dev, ctx->in_ep, ctx->read_chunk,\n\t\t\tctx->read_chunk_size, read_cb, &read_result,\n\t\t\tctx->usb_read_timeout);\n\t\tretval = libusb_submit_transfer(read_transfer);\n\t\tif (retval != LIBUSB_SUCCESS)\n\t\t\tgoto error_check;\n\t}\n\n\t/* Polling loop, more or less taken from libftdi */\n\tint64_t start = timeval_ms();\n\tint64_t warn_after = 2000;\n\twhile (!write_result.done || !read_result.done) {\n\t\tstruct timeval timeout_usb;\n\n\t\ttimeout_usb.tv_sec = 1;\n\t\ttimeout_usb.tv_usec = 0;\n\n\t\tretval = libusb_handle_events_timeout_completed(ctx->usb_ctx, &timeout_usb, NULL);\n\t\tkeep_alive();\n\t\tif (retval == LIBUSB_ERROR_NO_DEVICE || retval == LIBUSB_ERROR_INTERRUPTED)\n\t\t\tbreak;\n\n\t\tif (retval != LIBUSB_SUCCESS) {\n\t\t\tlibusb_cancel_transfer(write_transfer);\n\t\t\tif (read_transfer)\n\t\t\t\tlibusb_cancel_transfer(read_transfer);\n\t\t\twhile (!write_result.done || !read_result.done) {\n\t\t\t\tretval = libusb_handle_events_timeout_completed(ctx->usb_ctx,\n\t\t\t\t\t\t\t\t&timeout_usb, NULL);\n\t\t\t\tif (retval != LIBUSB_SUCCESS)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tint64_t now = timeval_ms();\n\t\tif (now - start > warn_after) {\n\t\t\tLOG_WARNING(\"Haven't made progress in mpsse_flush() for %\" PRId64\n\t\t\t\t\t\"ms.\", now - start);\n\t\t\twarn_after *= 2;\n\t\t}\n\t}\n\nerror_check:\n\tif (retval != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_handle_events() failed with %s\", libusb_error_name(retval));\n\t\tretval = ERROR_FAIL;\n\t} else if (write_result.transferred < ctx->write_count) {\n\t\tLOG_ERROR(\"ftdi device did not accept all data: %d, tried %d\",\n\t\t\twrite_result.transferred,\n\t\t\tctx->write_count);\n\t\tretval = ERROR_FAIL;\n\t} else if (read_result.transferred < ctx->read_count) {\n\t\tLOG_ERROR(\"ftdi device did not return all data: %d, expected %d\",\n\t\t\tread_result.transferred,\n\t\t\tctx->read_count);\n\t\tretval = ERROR_FAIL;\n\t} else if (ctx->read_count) {\n\t\tctx->write_count = 0;\n\t\tctx->read_count = 0;\n\t\tbit_copy_execute(&ctx->read_queue);\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tctx->write_count = 0;\n\t\tbit_copy_discard(&ctx->read_queue);\n\t\tretval = ERROR_OK;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tmpsse_purge(ctx);\n\n\tlibusb_free_transfer(write_transfer);\n\tif (read_transfer)\n\t\tlibusb_free_transfer(read_transfer);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/mpsse.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/**************************************************************************\n *   Copyright (C) 2012 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_MPSSE_H\n#define OPENOCD_JTAG_DRIVERS_MPSSE_H\n\n#include <stdbool.h>\n#include \"helper/binarybuffer.h\"\n\n/* Mode flags */\n#define POS_EDGE_OUT 0x00\n#define NEG_EDGE_OUT 0x01\n#define POS_EDGE_IN 0x00\n#define NEG_EDGE_IN 0x04\n#define MSB_FIRST 0x00\n#define LSB_FIRST 0x08\n\nenum ftdi_chip_type {\n\tTYPE_FT2232C,\n\tTYPE_FT2232H,\n\tTYPE_FT4232H,\n\tTYPE_FT232H,\n};\n\nstruct mpsse_ctx;\n\n/* Device handling */\nstruct mpsse_ctx *mpsse_open(const uint16_t *vid, const uint16_t *pid, const char *description,\n\tconst char *serial, const char *location, int channel);\nvoid mpsse_close(struct mpsse_ctx *ctx);\nbool mpsse_is_high_speed(struct mpsse_ctx *ctx);\n\n/* Command queuing. These correspond to the MPSSE commands with the same names, but no need to care\n * about bit/byte transfer or data length limitation. Read data is guaranteed to be available only\n * after the following mpsse_flush(). */\nvoid mpsse_clock_data_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,\n\t\t\t unsigned length, uint8_t mode);\nvoid mpsse_clock_data_in(struct mpsse_ctx *ctx, uint8_t *in, unsigned in_offset, unsigned length,\n\t\t\tuint8_t mode);\nvoid mpsse_clock_data(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,\n\t\t     unsigned in_offset, unsigned length, uint8_t mode);\nvoid mpsse_clock_tms_cs_out(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset,\n\t\t\t   unsigned length, bool tdi, uint8_t mode);\nvoid mpsse_clock_tms_cs(struct mpsse_ctx *ctx, const uint8_t *out, unsigned out_offset, uint8_t *in,\n\t\t       unsigned in_offset, unsigned length, bool tdi, uint8_t mode);\nvoid mpsse_set_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);\nvoid mpsse_set_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t data, uint8_t dir);\nvoid mpsse_read_data_bits_low_byte(struct mpsse_ctx *ctx, uint8_t *data);\nvoid mpsse_read_data_bits_high_byte(struct mpsse_ctx *ctx, uint8_t *data);\nvoid mpsse_loopback_config(struct mpsse_ctx *ctx, bool enable);\nvoid mpsse_set_divisor(struct mpsse_ctx *ctx, uint16_t divisor);\nint mpsse_divide_by_5_config(struct mpsse_ctx *ctx, bool enable);\nint mpsse_rtck_config(struct mpsse_ctx *ctx, bool enable);\n\n/* Helper to set frequency in Hertz. Returns actual realizable frequency or negative error.\n * Frequency 0 means RTCK. */\nint mpsse_set_frequency(struct mpsse_ctx *ctx, int frequency);\n\n/* Queue handling */\nint mpsse_flush(struct mpsse_ctx *ctx);\nvoid mpsse_purge(struct mpsse_ctx *ctx);\n\n#endif /* OPENOCD_JTAG_DRIVERS_MPSSE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/nulink_usb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016-2017 by Nuvoton                                    *\n *   Zale Yu <cyyu@nuvoton.com>                                            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <helper/binarybuffer.h>\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/hla/hla_layout.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n#include <target/target.h>\n\n#include <target/cortex_m.h>\n\n#include <hidapi.h>\n\n#include \"libusb_helper.h\"\n\n#define NULINK_READ_TIMEOUT  LIBUSB_TIMEOUT_MS\n\n#define NULINK_HID_MAX_SIZE   (64)\n#define NULINK2_HID_MAX_SIZE   (1024)\n#define V6M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 2)\n#define V7M_MAX_COMMAND_LENGTH (NULINK_HID_MAX_SIZE - 3)\n\n#define NULINK2_USB_PID1  (0x5200)\n#define NULINK2_USB_PID2  (0x5201)\n\nstruct nulink_usb_handle_s {\n\thid_device *dev_handle;\n\tuint16_t max_packet_size;\n\tuint8_t usbcmdidx;\n\tuint8_t cmdidx;\n\tuint8_t cmdsize;\n\tuint8_t cmdbuf[NULINK2_HID_MAX_SIZE + 1];\n\tuint8_t tempbuf[NULINK2_HID_MAX_SIZE];\n\tuint8_t databuf[NULINK2_HID_MAX_SIZE];\n\tuint32_t max_mem_packet;\n\tuint16_t hardware_config; /* bit 0: 1:Nu-Link-Pro, 0:Nu-Link */\n\n\tint (*xfer)(void *handle, uint8_t *buf, int size);\n\tvoid (*init_buffer)(void *handle, uint32_t size);\n};\n\n/* ICE Command */\n#define CMD_READ_REG\t\t\t\t0xB5UL\n#define CMD_READ_RAM\t\t\t\t0xB1UL\n#define CMD_WRITE_REG\t\t\t\t0xB8UL\n#define CMD_WRITE_RAM\t\t\t\t0xB9UL\n#define CMD_CHECK_ID\t\t\t\t0xA3UL\n#define CMD_MCU_RESET\t\t\t\t0xE2UL\n#define CMD_CHECK_MCU_STOP\t\t\t0xD8UL\n#define CMD_MCU_STEP_RUN\t\t\t0xD1UL\n#define CMD_MCU_STOP_RUN\t\t\t0xD2UL\n#define CMD_MCU_FREE_RUN\t\t\t0xD3UL\n#define CMD_SET_CONFIG\t\t\t\t0xA2UL\n\n#define ARM_SRAM_BASE\t\t\t\t0x20000000UL\n\n#define HARDWARE_CONFIG_NULINKPRO\t1\n#define HARDWARE_CONFIG_NULINK2\t\t2\n\nenum nulink_reset {\n\tRESET_AUTO = 0,\n\tRESET_HW = 1,\n\tRESET_SYSRESETREQ = 2,\n\tRESET_VECTRESET = 3,\n\tRESET_FAST_RESCUE = 4, /* Rescue and erase the chip, need very fast speed */\n};\n\nenum nulink_connect {\n\tCONNECT_NORMAL = 0,      /* Support all reset method */\n\tCONNECT_PRE_RESET = 1,   /* Support all reset method */\n\tCONNECT_UNDER_RESET = 2, /* Support all reset method */\n\tCONNECT_NONE = 3,        /* Support RESET_HW, (RESET_AUTO = RESET_HW) */\n\tCONNECT_DISCONNECT = 4,  /* Support RESET_NONE, (RESET_AUTO = RESET_NONE) */\n\tCONNECT_ICP_MODE = 5     /* Support NUC505 ICP mode*/\n};\n\nstatic int nulink_usb_xfer_rw(void *handle, uint8_t *buf)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tint ret = hid_write(h->dev_handle, h->cmdbuf, h->max_packet_size + 1);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"hid_write\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = hid_read_timeout(h->dev_handle, buf, h->max_packet_size, NULINK_READ_TIMEOUT);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"hid_read_timeout\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int nulink1_usb_xfer(void *handle, uint8_t *buf, int size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tint err = nulink_usb_xfer_rw(h, h->tempbuf);\n\n\tmemcpy(buf, h->tempbuf + 2, V6M_MAX_COMMAND_LENGTH);\n\n\treturn err;\n}\n\nstatic int nulink2_usb_xfer(void *handle, uint8_t *buf, int size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tint err = nulink_usb_xfer_rw(h, h->tempbuf);\n\n\tmemcpy(buf, h->tempbuf + 3, V7M_MAX_COMMAND_LENGTH);\n\n\treturn err;\n}\n\nstatic void nulink1_usb_init_buffer(void *handle, uint32_t size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\th->cmdidx = 0;\n\n\tmemset(h->cmdbuf, 0, h->max_packet_size + 1);\n\tmemset(h->tempbuf, 0, h->max_packet_size);\n\tmemset(h->databuf, 0, h->max_packet_size);\n\n\th->cmdbuf[0] = 0; /* report number */\n\th->cmdbuf[1] = ++h->usbcmdidx & 0x7F;\n\th->cmdbuf[2] = size;\n\th->cmdidx += 3;\n}\n\nstatic void nulink2_usb_init_buffer(void *handle, uint32_t size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\th->cmdidx = 0;\n\n\tmemset(h->cmdbuf, 0, h->max_packet_size + 1);\n\tmemset(h->tempbuf, 0, h->max_packet_size);\n\tmemset(h->databuf, 0, h->max_packet_size);\n\n\th->cmdbuf[0] = 0; /* report number */\n\th->cmdbuf[1] = ++h->usbcmdidx & 0x7F;\n\th_u16_to_le(h->cmdbuf + 2, size);\n\th->cmdidx += 4;\n}\n\nstatic inline int nulink_usb_xfer(void *handle, uint8_t *buf, int size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\treturn h->xfer(handle, buf, size);\n}\n\nstatic inline void nulink_usb_init_buffer(void *handle, uint32_t size)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\th->init_buffer(handle, size);\n}\n\nstatic int nulink_usb_version(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_version\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, V6M_MAX_COMMAND_LENGTH);\n\n\tmemset(h->cmdbuf + h->cmdidx, 0xFF, V6M_MAX_COMMAND_LENGTH);\n\th->cmdbuf[h->cmdidx + 4] = 0xA1; /* host_rev_num: 6561 */;\n\th->cmdbuf[h->cmdidx + 5] = 0x19;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, h->cmdsize);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tLOG_INFO(\"Nu-Link firmware_version %\" PRIu32 \", product_id (0x%08\" PRIx32 \")\",\n\t\t\t le_to_h_u32(h->databuf),\n\t\t\t le_to_h_u32(h->databuf + 4 * 1));\n\n\tconst bool is_nulinkpro = !!(le_to_h_u32(h->databuf + 4 * 2) & 1);\n\tif (is_nulinkpro) {\n\t\tLOG_INFO(\"Adapter is Nu-Link-Pro, target_voltage_mv(%\" PRIu16 \"), usb_voltage_mv(%\" PRIu16 \")\",\n\t\t\t\t le_to_h_u16(h->databuf + 4 * 3 + 0),\n\t\t\t\t le_to_h_u16(h->databuf + 4 * 3 + 2));\n\n\t\th->hardware_config |= HARDWARE_CONFIG_NULINKPRO;\n\t} else {\n\t\tLOG_INFO(\"Adapter is Nu-Link\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int nulink_usb_idcode(void *handle, uint32_t *idcode)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_idcode\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_ID);\n\th->cmdidx += 4;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, 4 * 2);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t*idcode = le_to_h_u32(h->databuf + 4 * 1);\n\n\tLOG_INFO(\"IDCODE: 0x%08\" PRIX32, *idcode);\n\n\treturn ERROR_OK;\n}\n\nstatic int nulink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_write_debug_reg 0x%08\" PRIX32 \" 0x%08\" PRIX32, addr, val);\n\n\tnulink_usb_init_buffer(handle, 8 + 12 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);\n\th->cmdidx += 4;\n\t/* Count of registers */\n\th->cmdbuf[h->cmdidx] = 1;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8ReadOld) */\n\th->cmdbuf[h->cmdidx] = 0x00;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8Verify) */\n\th->cmdbuf[h->cmdidx] = 0x00;\n\th->cmdidx += 1;\n\t/* ignore */\n\th->cmdbuf[h->cmdidx] = 0;\n\th->cmdidx += 1;\n\t/* u32Addr */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\th->cmdidx += 4;\n\t/* u32Data */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, val);\n\th->cmdidx += 4;\n\t/* u32Mask */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);\n\th->cmdidx += 4;\n\n\treturn nulink_usb_xfer(handle, h->databuf, 4 * 2);\n}\n\nstatic enum target_state nulink_usb_state(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_CHECK_MCU_STOP);\n\th->cmdidx += 4;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, 4 * 4);\n\tif (res != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\n\tif (!le_to_h_u32(h->databuf + 4 * 2))\n\t\treturn TARGET_HALTED;\n\telse\n\t\treturn TARGET_RUNNING;\n}\n\nstatic int nulink_usb_assert_srst(void *handle, int srst)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_assert_srst\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 4);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);\n\th->cmdidx += 4;\n\t/* set reset type */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, RESET_SYSRESETREQ);\n\th->cmdidx += 4;\n\t/* set connect type */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);\n\th->cmdidx += 4;\n\t/* set extMode */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\th->cmdidx += 4;\n\n\treturn nulink_usb_xfer(handle, h->databuf, 4 * 4);\n}\n\nstatic int nulink_usb_reset(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_reset\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 4);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_RESET);\n\th->cmdidx += 4;\n\t/* set reset type */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, RESET_HW);\n\th->cmdidx += 4;\n\t/* set connect type */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CONNECT_NORMAL);\n\th->cmdidx += 4;\n\t/* set extMode */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\th->cmdidx += 4;\n\n\treturn nulink_usb_xfer(handle, h->databuf, 4 * 4);\n}\n\nstatic int nulink_usb_run(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_run\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_FREE_RUN);\n\th->cmdidx += 4;\n\n\treturn nulink_usb_xfer(handle, h->databuf, 4 * 4);\n}\n\nstatic int nulink_usb_halt(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_halt\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STOP_RUN);\n\th->cmdidx += 4;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, 4 * 4);\n\n\tLOG_DEBUG(\"Nu-Link stop_pc 0x%08\" PRIx32, le_to_h_u32(h->databuf + 4));\n\n\treturn res;\n}\n\nstatic int nulink_usb_step(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_step\");\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 4 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_MCU_STEP_RUN);\n\th->cmdidx += 4;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, 4 * 4);\n\n\tLOG_DEBUG(\"Nu-Link pc 0x%08\" PRIx32, le_to_h_u32(h->databuf + 4));\n\n\treturn res;\n}\n\nstatic int nulink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 8 + 12 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);\n\th->cmdidx += 4;\n\t/* Count of registers */\n\th->cmdbuf[h->cmdidx] = 1;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8ReadOld) */\n\th->cmdbuf[h->cmdidx] = 0xFF;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8Verify) */\n\th->cmdbuf[h->cmdidx] = 0x00;\n\th->cmdidx += 1;\n\t/* ignore */\n\th->cmdbuf[h->cmdidx] = 0;\n\th->cmdidx += 1;\n\t/* u32Addr */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, regsel);\n\th->cmdidx += 4;\n\t/* u32Data */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\th->cmdidx += 4;\n\t/* u32Mask */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);\n\th->cmdidx += 4;\n\n\tint res = nulink_usb_xfer(handle, h->databuf, 4 * 2);\n\n\t*val = le_to_h_u32(h->databuf + 4 * 1);\n\n\treturn res;\n}\n\nstatic int nulink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tnulink_usb_init_buffer(handle, 8 + 12 * 1);\n\t/* set command ID */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_REG);\n\th->cmdidx += 4;\n\t/* Count of registers */\n\th->cmdbuf[h->cmdidx] = 1;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8ReadOld) */\n\th->cmdbuf[h->cmdidx] = 0x00;\n\th->cmdidx += 1;\n\t/* Array of bool value (u8Verify) */\n\th->cmdbuf[h->cmdidx] = 0x00;\n\th->cmdidx += 1;\n\t/* ignore */\n\th->cmdbuf[h->cmdidx] = 0;\n\th->cmdidx += 1;\n\t/* u32Addr */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, regsel);\n\th->cmdidx += 4;\n\t/* u32Data */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, val);\n\th->cmdidx += 4;\n\t/* u32Mask */\n\th_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);\n\th->cmdidx += 4;\n\n\treturn nulink_usb_xfer(handle, h->databuf, 4 * 2);\n}\n\nstatic int nulink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len,\n\t\tuint8_t *buffer)\n{\n\tint res = ERROR_OK;\n\tuint32_t offset = 0;\n\tuint32_t bytes_remaining = 12;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_read_mem8: addr 0x%08\" PRIx32 \", len %\" PRId16, addr, len);\n\n\tassert(handle);\n\n\t/* check whether data is word aligned */\n\tif (addr % 4) {\n\t\tuint32_t aligned_addr = addr / 4;\n\t\taligned_addr = aligned_addr * 4;\n\t\toffset = addr - aligned_addr;\n\t\tLOG_DEBUG(\"nulink_usb_read_mem8: unaligned address addr 0x%08\" PRIx32\n\t\t\t\t\"/aligned addr 0x%08\" PRIx32 \" offset %\" PRIu32,\n\t\t\t\taddr, aligned_addr, offset);\n\n\t\taddr = aligned_addr;\n\t}\n\n\twhile (len) {\n\t\tunsigned int count;\n\n\t\tif (len < bytes_remaining)\n\t\t\tbytes_remaining = len;\n\n\t\tif (len < 4)\n\t\t\tcount = 1;\n\t\telse\n\t\t\tcount = 2;\n\n\t\tnulink_usb_init_buffer(handle, 8 + 12 * count);\n\t\t/* set command ID */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);\n\t\th->cmdidx += 4;\n\t\t/* Count of registers */\n\t\th->cmdbuf[h->cmdidx] = count;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8ReadOld) */\n\t\th->cmdbuf[h->cmdidx] = 0xFF;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8Verify) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* ignore */\n\t\th->cmdbuf[h->cmdidx] = 0;\n\t\th->cmdidx += 1;\n\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\t/* u32Addr */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Data */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Mask */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);\n\t\t\th->cmdidx += 4;\n\t\t\t/* proceed to the next one  */\n\t\t\taddr += 4;\n\t\t}\n\n\t\tres = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);\n\t\tif (res != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* fill in the output buffer */\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\tif (i == 0)\n\t\t\t\tmemcpy(buffer, h->databuf + 4 + offset, len);\n\t\t\telse\n\t\t\t\tmemcpy(buffer + 2 * i, h->databuf + 4 * (2 * i + 1), len - 2);\n\t\t}\n\n\t\tif (len >= bytes_remaining)\n\t\t\tlen -= bytes_remaining;\n\t}\n\n\treturn res;\n}\n\nstatic int nulink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len,\n\t\tconst uint8_t *buffer)\n{\n\tint res = ERROR_OK;\n\tuint32_t offset = 0;\n\tuint32_t bytes_remaining = 12;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_write_mem8: addr 0x%08\" PRIx32 \", len %\" PRIu16, addr, len);\n\n\tassert(handle);\n\n\t/* check whether data is word aligned */\n\tif (addr % 4) {\n\t\tuint32_t aligned_addr = addr / 4;\n\t\taligned_addr = aligned_addr * 4;\n\t\toffset = addr - aligned_addr;\n\t\tLOG_DEBUG(\"nulink_usb_write_mem8: address not aligned. addr(0x%08\" PRIx32\n\t\t\t\t\")/aligned_addr(0x%08\" PRIx32 \")/offset(%\" PRIu32 \")\",\n\t\t\t\taddr, aligned_addr, offset);\n\n\t\taddr = aligned_addr;\n\t}\n\n\twhile (len) {\n\t\tunsigned int count;\n\n\t\tif (len < bytes_remaining)\n\t\t\tbytes_remaining = len;\n\n\t\tif (len < 4)\n\t\t\tcount = 1;\n\t\telse\n\t\t\tcount = 2;\n\n\t\tnulink_usb_init_buffer(handle, 8 + 12 * count);\n\t\t/* set command ID */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);\n\t\th->cmdidx += 4;\n\t\t/* Count of registers */\n\t\th->cmdbuf[h->cmdidx] = count;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8ReadOld) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8Verify) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* ignore */\n\t\th->cmdbuf[h->cmdidx] = 0;\n\t\th->cmdidx += 1;\n\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\t/* u32Addr */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Data */\n\t\t\tuint32_t u32buffer = buf_get_u32(buffer, 0, len * 8);\n\t\t\tu32buffer = (u32buffer << offset * 8);\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Mask */\n\t\t\tif (i == 0) {\n\t\t\t\tif (offset == 0) {\n\t\t\t\t\tif (len == 1) {\n\t\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFF00UL);\n\t\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0xFFFFFF00\", i);\n\t\t\t\t\t} else {\n\t\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);\n\t\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000\", i);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (len == 1) {\n\t\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFF00FFFFUL);\n\t\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0xFF00FFFF\", i);\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0x0000FFFFUL);\n\t\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0x0000FFFF\", i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (len == 4) {\n\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFF0000UL);\n\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0xFFFF0000\", i);\n\t\t\t\t} else {\n\t\t\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000UL);\n\t\t\t\t\tLOG_DEBUG(\"nulink_usb_write_mem8: count(%u), mask: 0x00000000\", i);\n\t\t\t\t}\n\t\t\t}\n\t\t\th->cmdidx += 4;\n\n\t\t\t/* proceed to the next one */\n\t\t\taddr += 4;\n\t\t\tbuffer += 4;\n\t\t}\n\n\t\tres = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);\n\t\tif (res != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (len >= bytes_remaining)\n\t\t\tlen -= bytes_remaining;\n\t}\n\n\treturn res;\n}\n\nstatic int nulink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len,\n\t\tuint8_t *buffer)\n{\n\tint res = ERROR_OK;\n\tuint32_t bytes_remaining = 12;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_ERROR(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\twhile (len) {\n\t\tif (len < bytes_remaining)\n\t\t\tbytes_remaining = len;\n\n\t\tunsigned int count = bytes_remaining / 4;\n\n\t\tnulink_usb_init_buffer(handle, 8 + 12 * count);\n\t\t/* set command ID */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);\n\t\th->cmdidx += 4;\n\t\t/* Count of registers */\n\t\th->cmdbuf[h->cmdidx] = count;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8ReadOld) */\n\t\th->cmdbuf[h->cmdidx] = 0xFF;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8Verify) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* ignore */\n\t\th->cmdbuf[h->cmdidx] = 0;\n\t\th->cmdidx += 1;\n\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\t/* u32Addr */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Data */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Mask */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0xFFFFFFFFUL);\n\t\t\th->cmdidx += 4;\n\t\t\t/* proceed to the next one  */\n\t\t\taddr += 4;\n\t\t}\n\n\t\tres = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);\n\n\t\t/* fill in the output buffer */\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\tmemcpy(buffer, h->databuf + 4 * (2 * i + 1), 4);\n\t\t\tbuffer += 4;\n\t\t}\n\n\t\tif (len >= bytes_remaining)\n\t\t\tlen -= bytes_remaining;\n\t\telse\n\t\t\tlen = 0;\n\t}\n\n\treturn res;\n}\n\nstatic int nulink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len,\n\t\tconst uint8_t *buffer)\n{\n\tint res = ERROR_OK;\n\tuint32_t bytes_remaining = 12;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_ERROR(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\twhile (len) {\n\t\tif (len < bytes_remaining)\n\t\t\tbytes_remaining = len;\n\n\t\tunsigned int count = bytes_remaining / 4;\n\n\t\tnulink_usb_init_buffer(handle, 8 + 12 * count);\n\t\t/* set command ID */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_WRITE_RAM);\n\t\th->cmdidx += 4;\n\t\t/* Count of registers */\n\t\th->cmdbuf[h->cmdidx] = count;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8ReadOld) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* Array of bool value (u8Verify) */\n\t\th->cmdbuf[h->cmdidx] = 0x00;\n\t\th->cmdidx += 1;\n\t\t/* ignore */\n\t\th->cmdbuf[h->cmdidx] = 0;\n\t\th->cmdidx += 1;\n\n\t\tfor (unsigned int i = 0; i < count; i++) {\n\t\t\t/* u32Addr */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Data */\n\t\t\tuint32_t u32buffer = buf_get_u32(buffer, 0, 32);\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, u32buffer);\n\t\t\th->cmdidx += 4;\n\t\t\t/* u32Mask */\n\t\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0x00000000);\n\t\t\th->cmdidx += 4;\n\n\t\t\t/* proceed to the next one */\n\t\t\taddr += 4;\n\t\t\tbuffer += 4;\n\t\t}\n\n\t\tres = nulink_usb_xfer(handle, h->databuf, 4 * count * 2);\n\n\t\tif (len >= bytes_remaining)\n\t\t\tlen -= bytes_remaining;\n\t\telse\n\t\t\tlen = 0;\n\t}\n\n\treturn res;\n}\n\nstatic uint32_t nulink_max_block_size(uint32_t tar_autoincr_block, uint32_t address)\n{\n\tuint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address));\n\n\tif (max_tar_block == 0)\n\t\tmax_tar_block = 4;\n\n\treturn max_tar_block;\n}\n\nstatic int nulink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\twhile (count) {\n\t\tuint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);\n\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\tif (bytes_remaining >= 4)\n\t\t\tsize = 4;\n\n\t\t/* the nulink only supports 8/32bit memory read/writes\n\t\t * honour 32bit, all others will be handled as 8bit access */\n\t\tif (size == 4) {\n\t\t\t/* When in jtag mode the nulink uses the auto-increment functionality.\n\t\t\t * However it expects us to pass the data correctly, this includes\n\t\t\t * alignment and any page boundaries. We already do this as part of the\n\t\t\t * adi_v5 implementation, but the nulink is a hla adapter and so this\n\t\t\t * needs implementing manually.\n\t\t\t * currently this only affects jtag mode, they do single\n\t\t\t * access in SWD mode - but this may change and so we do it for both modes */\n\n\t\t\t/* we first need to check for any unaligned bytes */\n\t\t\tif (addr % 4) {\n\t\t\t\tuint32_t head_bytes = 4 - (addr % 4);\n\t\t\t\tretval = nulink_usb_read_mem8(handle, addr, head_bytes, buffer);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tbuffer += head_bytes;\n\t\t\t\taddr += head_bytes;\n\t\t\t\tcount -= head_bytes;\n\t\t\t\tbytes_remaining -= head_bytes;\n\t\t\t}\n\n\t\t\tif (bytes_remaining % 4)\n\t\t\t\tretval = nulink_usb_read_mem(handle, addr, 1, bytes_remaining, buffer);\n\t\t\telse\n\t\t\t\tretval = nulink_usb_read_mem32(handle, addr, bytes_remaining, buffer);\n\t\t} else {\n\t\t\tretval = nulink_usb_read_mem8(handle, addr, bytes_remaining, buffer);\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int nulink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tif (addr < ARM_SRAM_BASE) {\n\t\tLOG_DEBUG(\"nulink_usb_write_mem: address below ARM_SRAM_BASE, not supported.\\n\");\n\t\treturn retval;\n\t}\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\twhile (count) {\n\t\tuint32_t bytes_remaining = nulink_max_block_size(h->max_mem_packet, addr);\n\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\tif (bytes_remaining >= 4)\n\t\t\tsize = 4;\n\n\t\t/* the nulink only supports 8/32bit memory read/writes\n\t\t * honour 32bit, all others will be handled as 8bit access */\n\t\tif (size == 4) {\n\t\t\t/* When in jtag mode the nulink uses the auto-increment functionality.\n\t\t\t * However it expects us to pass the data correctly, this includes\n\t\t\t * alignment and any page boundaries. We already do this as part of the\n\t\t\t * adi_v5 implementation, but the nulink is a hla adapter and so this\n\t\t\t * needs implementing manually.\n\t\t\t * currently this only affects jtag mode, do single\n\t\t\t * access in SWD mode - but this may change and so we do it for both modes */\n\n\t\t\t/* we first need to check for any unaligned bytes */\n\t\t\tif (addr % 4) {\n\t\t\t\tuint32_t head_bytes = 4 - (addr % 4);\n\t\t\t\tretval = nulink_usb_write_mem8(handle, addr, head_bytes, buffer);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tbuffer += head_bytes;\n\t\t\t\taddr += head_bytes;\n\t\t\t\tcount -= head_bytes;\n\t\t\t\tbytes_remaining -= head_bytes;\n\t\t\t}\n\n\t\t\tif (bytes_remaining % 4)\n\t\t\t\tretval = nulink_usb_write_mem(handle, addr, 1, bytes_remaining, buffer);\n\t\t\telse\n\t\t\t\tretval = nulink_usb_write_mem32(handle, addr, bytes_remaining, buffer);\n\n\t\t} else {\n\t\t\tretval = nulink_usb_write_mem8(handle, addr, bytes_remaining, buffer);\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int nulink_usb_override_target(const char *targetname)\n{\n\tLOG_DEBUG(\"nulink_usb_override_target\");\n\n\treturn !strcmp(targetname, \"cortex_m\");\n}\n\nstatic int nulink_speed(void *handle, int khz, bool query)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\tunsigned long max_ice_clock = khz;\n\n\tLOG_DEBUG(\"nulink_speed: query %s\", query ? \"yes\" : \"no\");\n\n\tif (max_ice_clock > 12000)\n\t\tmax_ice_clock = 12000;\n\telse if ((max_ice_clock == 3 * 512) || (max_ice_clock == 1500))\n\t\tmax_ice_clock = 1500;\n\telse if (max_ice_clock >= 1000)\n\t\tmax_ice_clock = max_ice_clock / 1000 * 1000;\n\telse\n\t\tmax_ice_clock = max_ice_clock / 100 * 100;\n\n\tLOG_DEBUG(\"Nu-Link nulink_speed: %lu\", max_ice_clock);\n\n\tif (!query) {\n\t\tnulink_usb_init_buffer(handle, 4 * 6);\n\t\t/* set command ID */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, CMD_SET_CONFIG);\n\t\th->cmdidx += 4;\n\t\t/* set max SWD clock */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, max_ice_clock);\n\t\th->cmdidx += 4;\n\t\t/* chip type: NUC_CHIP_TYPE_GENERAL_V6M */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\t\th->cmdidx += 4;\n\t\t/* IO voltage */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 5000);\n\t\th->cmdidx += 4;\n\t\t/* If supply voltage to target or not */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 0);\n\t\th->cmdidx += 4;\n\t\t/* USB_FUNC_E: USB_FUNC_HID_BULK */\n\t\th_u32_to_le(h->cmdbuf + h->cmdidx, 2);\n\t\th->cmdidx += 4;\n\n\t\tnulink_usb_xfer(handle, h->databuf, 4 * 3);\n\n\t\tLOG_DEBUG(\"nulink_speed: h->hardware_config(%\" PRId16 \")\", h->hardware_config);\n\t\tif (h->hardware_config & HARDWARE_CONFIG_NULINKPRO)\n\t\t\tLOG_INFO(\"Nu-Link target_voltage_mv[0](%04\" PRIx16 \"), target_voltage_mv[1](%04\" PRIx16\n\t\t\t\t\"), target_voltage_mv[2](%04\" PRIx16 \"), if_target_power_supplied(%d)\",\n\t\t\t\tle_to_h_u16(h->databuf + 4 * 1 + 0),\n\t\t\t\tle_to_h_u16(h->databuf + 4 * 1 + 2),\n\t\t\t\tle_to_h_u16(h->databuf + 4 * 2 + 0),\n\t\t\t\tle_to_h_u16(h->databuf + 4 * 2 + 2) & 1);\n\t}\n\n\treturn max_ice_clock;\n}\n\nstatic int nulink_usb_close(void *handle)\n{\n\tstruct nulink_usb_handle_s *h = handle;\n\n\tLOG_DEBUG(\"nulink_usb_close\");\n\n\tif (h && h->dev_handle)\n\t\thid_close(h->dev_handle);\n\n\tfree(h);\n\n\thid_exit();\n\n\treturn ERROR_OK;\n}\n\nstatic int nulink_usb_open(struct hl_interface_param_s *param, void **fd)\n{\n\tstruct hid_device_info *devs, *cur_dev;\n\tuint16_t target_vid = 0;\n\tuint16_t target_pid = 0;\n\twchar_t *target_serial = NULL;\n\n\tLOG_DEBUG(\"nulink_usb_open\");\n\n\tif (param->transport != HL_TRANSPORT_SWD)\n\t\treturn TARGET_UNKNOWN;\n\n\tif (!param->vid[0] && !param->pid[0]) {\n\t\tLOG_ERROR(\"Missing vid/pid\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (hid_init() != 0) {\n\t\tLOG_ERROR(\"unable to open HIDAPI\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct nulink_usb_handle_s *h = calloc(1, sizeof(*h));\n\tif (!h) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tgoto error_open;\n\t}\n\n\tconst char *serial = adapter_get_required_serial();\n\tif (serial) {\n\t\tsize_t len = mbstowcs(NULL, serial, 0);\n\n\t\ttarget_serial = calloc(len + 1, sizeof(wchar_t));\n\t\tif (!target_serial) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tgoto error_open;\n\t\t}\n\n\t\tif (mbstowcs(target_serial, serial, len + 1) == (size_t)(-1)) {\n\t\t\tLOG_WARNING(\"unable to convert serial\");\n\t\t\tfree(target_serial);\n\t\t\ttarget_serial = NULL;\n\t\t}\n\t}\n\n\tdevs = hid_enumerate(0, 0);\n\tcur_dev = devs;\n\twhile (cur_dev) {\n\t\tbool found = false;\n\n\t\tfor (unsigned int i = 0; param->vid[i] || param->pid[i]; i++) {\n\t\t\tif (param->vid[i] == cur_dev->vendor_id && param->pid[i] == cur_dev->product_id) {\n\t\t\t\tfound = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (found) {\n\t\t\tif (!target_serial)\n\t\t\t\tbreak;\n\t\t\tif (cur_dev->serial_number && wcscmp(target_serial, cur_dev->serial_number) == 0)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tcur_dev = cur_dev->next;\n\t}\n\tif (cur_dev) {\n\t\ttarget_vid = cur_dev->vendor_id;\n\t\ttarget_pid = cur_dev->product_id;\n\t}\n\n\thid_free_enumeration(devs);\n\n\tif (target_vid == 0 && target_pid == 0) {\n\t\tLOG_ERROR(\"unable to find Nu-Link\");\n\t\tgoto error_open;\n\t}\n\n\thid_device *dev = hid_open(target_vid, target_pid, target_serial);\n\tif (!dev) {\n\t\tLOG_ERROR(\"unable to open Nu-Link device 0x%\" PRIx16 \":0x%\" PRIx16, target_vid, target_pid);\n\t\tgoto error_open;\n\t}\n\n\th->dev_handle = dev;\n\th->usbcmdidx = 0;\n\n\tswitch (target_pid) {\n\tcase NULINK2_USB_PID1:\n\tcase NULINK2_USB_PID2:\n\t\th->hardware_config = HARDWARE_CONFIG_NULINK2;\n\t\th->max_packet_size = NULINK2_HID_MAX_SIZE;\n\t\th->init_buffer = nulink2_usb_init_buffer;\n\t\th->xfer = nulink2_usb_xfer;\n\t\tbreak;\n\tdefault:\n\t\th->hardware_config = 0;\n\t\th->max_packet_size = NULINK_HID_MAX_SIZE;\n\t\th->init_buffer = nulink1_usb_init_buffer;\n\t\th->xfer = nulink1_usb_xfer;\n\t\tbreak;\n\t}\n\n\t/* get the device version */\n\th->cmdsize = 4 * 5;\n\tint err = nulink_usb_version(h);\n\tif (err != ERROR_OK) {\n\t\tLOG_DEBUG(\"nulink_usb_version failed with cmdSize(4 * 5)\");\n\t\th->cmdsize = 4 * 6;\n\t\terr = nulink_usb_version(h);\n\t\tif (err != ERROR_OK)\n\t\t\tLOG_DEBUG(\"nulink_usb_version failed with cmdSize(4 * 6)\");\n\t}\n\n\t/* SWD clock rate : 1MHz */\n\tnulink_speed(h, 1000, false);\n\n\t/* get cpuid, so we can determine the max page size\n\t * start with a safe default */\n\th->max_mem_packet = (1 << 10);\n\n\tLOG_DEBUG(\"nulink_usb_open: we manually perform nulink_usb_reset\");\n\tnulink_usb_reset(h);\n\n\t*fd = h;\n\n\tfree(target_serial);\n\treturn ERROR_OK;\n\nerror_open:\n\tnulink_usb_close(h);\n\tfree(target_serial);\n\n\treturn ERROR_FAIL;\n}\n\nstruct hl_layout_api_s nulink_usb_layout_api = {\n\t.open = nulink_usb_open,\n\t.close = nulink_usb_close,\n\t.idcode = nulink_usb_idcode,\n\t.state = nulink_usb_state,\n\t.reset = nulink_usb_reset,\n\t.assert_srst = nulink_usb_assert_srst,\n\t.run = nulink_usb_run,\n\t.halt = nulink_usb_halt,\n\t.step = nulink_usb_step,\n\t.read_reg = nulink_usb_read_reg,\n\t.write_reg = nulink_usb_write_reg,\n\t.read_mem = nulink_usb_read_mem,\n\t.write_mem = nulink_usb_write_mem,\n\t.write_debug_reg = nulink_usb_write_debug_reg,\n\t.override_target = nulink_usb_override_target,\n\t.speed = nulink_speed,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/opendous.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *                                                                         *\n *   Copyright (C) 2009 by Cahya Wirawan <cahya@gmx.at>                    *\n *   Based on opendous driver by Vladimir Fonov                            *\n *                                                                         *\n *   Copyright (C) 2009 by Vladimir Fonov <vladimir.fonov@gmai.com>        *\n *   Based on J-link driver by  Juergen Stuber                             *\n *                                                                         *\n *   Copyright (C) 2007 by Juergen Stuber <juergen@jstuber.net>            *\n *   based on Dominic Rath's and Benedikt Sauter's usbprog.c               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"libusb_helper.h\"\n#include <string.h>\n#include <time.h>\n\n#define OPENDOUS_MAX_VIDS_PIDS 4\n/* define some probes with similar interface */\nstruct opendous_probe {\n\tconst char *name;\n\tuint16_t VID[OPENDOUS_MAX_VIDS_PIDS];\n\tuint16_t PID[OPENDOUS_MAX_VIDS_PIDS];\n\tuint8_t READ_EP;\n\tuint8_t WRITE_EP;\n\tuint8_t CONTROL_TRANSFER;\n\tint BUFFERSIZE;\n};\n\nstatic const struct opendous_probe opendous_probes[] = {\n\t{\"usbprog-jtag\",\t{0x1781, 0},\t\t\t{0x0C63, 0},\t\t\t0x82, 0x02, 0x00, 510 },\n\t{\"opendous\",\t\t{0x1781, 0x03EB, 0},\t{0xC0C0, 0x204F, 0},\t0x81, 0x02, 0x00, 360 },\n\t{\"usbvlab\",\t\t\t{0x16C0, 0},\t\t\t{0x05DC, 0},\t\t\t0x81, 0x02, 0x01, 360 },\n\t{NULL,\t\t\t\t{0x0000},\t\t\t\t{0x0000},\t\t\t\t0x00, 0x00, 0x00,   0 }\n};\n\n#define OPENDOUS_WRITE_ENDPOINT   (opendous_probe->WRITE_EP)\n#define OPENDOUS_READ_ENDPOINT    (opendous_probe->READ_EP)\n\nstatic unsigned int opendous_hw_jtag_version = 1;\n\n#define OPENDOUS_USB_TIMEOUT      1000\n\n#define OPENDOUS_USB_BUFFER_SIZE  (opendous_probe->BUFFERSIZE)\n#define OPENDOUS_IN_BUFFER_SIZE   (OPENDOUS_USB_BUFFER_SIZE)\n#define OPENDOUS_OUT_BUFFER_SIZE  (OPENDOUS_USB_BUFFER_SIZE)\n\n/* Global USB buffers */\nstatic uint8_t *usb_in_buffer;\nstatic uint8_t *usb_out_buffer;\n\n/* Constants for OPENDOUS command */\n\n#define OPENDOUS_MAX_SPEED\t\t\t66\n#define OPENDOUS_MAX_TAP_TRANSMIT\t((opendous_probe->BUFFERSIZE)-10)\n#define OPENDOUS_MAX_INPUT_DATA\t\t(OPENDOUS_MAX_TAP_TRANSMIT*4)\n\n/* TAP */\n#define OPENDOUS_TAP_BUFFER_SIZE 65536\n\nstruct pending_scan_result {\n\tint first;\t/* First bit position in tdo_buffer to read */\n\tint length; /* Number of bits to read */\n\tstruct scan_command *command; /* Corresponding scan command */\n\tuint8_t *buffer;\n};\n\nstatic int pending_scan_results_length;\nstatic struct pending_scan_result *pending_scan_results_buffer;\n\n#define MAX_PENDING_SCAN_RESULTS (OPENDOUS_MAX_INPUT_DATA)\n\n/* JTAG usb commands */\n#define JTAG_CMD_TAP_OUTPUT\t\t0x0\n#define JTAG_CMD_SET_TRST\t\t0x1\n#define JTAG_CMD_SET_SRST\t\t0x2\n#define JTAG_CMD_READ_INPUT\t\t0x3\n#define JTAG_CMD_TAP_OUTPUT_EMU\t0x4\n#define JTAG_CMD_SET_DELAY\t\t0x5\n#define JTAG_CMD_SET_SRST_TRST\t0x6\n#define JTAG_CMD_READ_CONFIG\t0x7\n\n/* usbvlab control transfer */\n#define FUNC_START_BOOTLOADER 30\n#define FUNC_WRITE_DATA       0x50\n#define FUNC_READ_DATA        0x51\n\nstatic char *opendous_type;\nstatic const struct opendous_probe *opendous_probe;\n\n/* External interface functions */\nstatic int opendous_execute_queue(void);\nstatic int opendous_init(void);\nstatic int opendous_quit(void);\n\n/* Queue command functions */\nstatic void opendous_end_state(tap_state_t state);\nstatic void opendous_state_move(void);\nstatic void opendous_path_move(int num_states, tap_state_t *path);\nstatic void opendous_runtest(int num_cycles);\nstatic void opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer,\n\t\tint scan_size, struct scan_command *command);\nstatic void opendous_reset(int trst, int srst);\nstatic void opendous_simple_command(uint8_t command, uint8_t _data);\nstatic int opendous_get_status(void);\n\n/* opendous tap buffer functions */\nstatic void opendous_tap_init(void);\nstatic int opendous_tap_execute(void);\nstatic void opendous_tap_ensure_space(int scans, int bits);\nstatic void opendous_tap_append_step(int tms, int tdi);\nstatic void opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command);\n\n/* opendous lowlevel functions */\nstruct opendous_jtag {\n\tstruct libusb_device_handle *usb_handle;\n};\n\nstatic struct opendous_jtag *opendous_usb_open(void);\nstatic void opendous_usb_close(struct opendous_jtag *opendous_jtag);\nstatic int opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length);\nstatic int opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length);\nstatic int opendous_usb_read(struct opendous_jtag *opendous_jtag);\n\n/* helper functions */\nstatic int opendous_get_version_info(void);\n\n#ifdef _DEBUG_USB_COMMS_\nstatic void opendous_debug_buffer(uint8_t *buffer, int length);\n#endif\n\nstatic struct opendous_jtag *opendous_jtag_handle;\n\n/***************************************************************************/\n/* External interface implementation */\n\nCOMMAND_HANDLER(opendous_handle_opendous_type_command)\n{\n\tif (CMD_ARGC == 0)\n\t\treturn ERROR_OK;\n\n\t/* only if the cable name wasn't overwritten by cmdline */\n\tif (!opendous_type) {\n\t\t/* REVISIT first verify that it's listed in cables[] ... */\n\t\topendous_type = strdup(CMD_ARGV[0]);\n\t}\n\n\t/* REVISIT it's probably worth returning the current value ... */\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(opendous_handle_opendous_info_command)\n{\n\tif (opendous_get_version_info() == ERROR_OK) {\n\t\t/* attempt to get status */\n\t\topendous_get_status();\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(opendous_handle_opendous_hw_jtag_command)\n{\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tcommand_print(CMD, \"opendous hw jtag  %i\", opendous_hw_jtag_version);\n\t\t\tbreak;\n\n\t\tcase 1: {\n\t\t\tint request_version = atoi(CMD_ARGV[0]);\n\t\t\tswitch (request_version) {\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\t\topendous_hw_jtag_version = request_version;\n\t\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration opendous_command_handlers[] = {\n\t{\n\t\t.name = \"opendous_info\",\n\t\t.handler = &opendous_handle_opendous_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"show opendous info\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"opendous_hw_jtag\",\n\t\t.handler = &opendous_handle_opendous_hw_jtag_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"access opendous HW JTAG command version\",\n\t\t.usage = \"[2|3]\",\n\t},\n\t{\n\t\t.name = \"opendous_type\",\n\t\t.handler = &opendous_handle_opendous_type_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set opendous type\",\n\t\t.usage = \"[usbvlab|usbprog-jtag|opendous]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface opendous_interface = {\n\t.execute_queue = opendous_execute_queue,\n};\n\nstruct adapter_driver opendous_adapter_driver = {\n\t.name = \"opendous\",\n\t.transports = jtag_only,\n\t.commands = opendous_command_handlers,\n\n\t.init = opendous_init,\n\t.quit = opendous_quit,\n\n\t.jtag_ops = &opendous_interface,\n};\n\nstatic int opendous_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\", cmd->cmd.runtest->num_cycles,\n\t\t\t\t\tcmd->cmd.runtest->end_state);\n\n\t\t\t\tif (cmd->cmd.runtest->end_state != -1)\n\t\t\t\t\topendous_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\topendous_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\n\t\t\t\tif (cmd->cmd.statemove->end_state != -1)\n\t\t\t\t\topendous_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\topendous_state_move();\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\n\t\t\t\topendous_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"scan end in %i\", cmd->cmd.scan->end_state);\n\n\t\t\t\tif (cmd->cmd.scan->end_state != -1)\n\t\t\t\t\topendous_end_state(cmd->cmd.scan->end_state);\n\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\tLOG_DEBUG_IO(\"scan input, length = %d\", scan_size);\n\n#ifdef _DEBUG_USB_COMMS_\n\t\t\t\topendous_debug_buffer(buffer, (scan_size + 7) / 8);\n#endif\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\topendous_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size, cmd->cmd.scan);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\", cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\n\t\t\t\topendous_tap_execute();\n\n\t\t\t\tif (cmd->cmd.reset->trst == 1)\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\topendous_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\topendous_tap_execute();\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\treturn opendous_tap_execute();\n}\n\nstatic int opendous_init(void)\n{\n\tint check_cnt;\n\tconst struct opendous_probe *cur_opendous_probe;\n\n\tcur_opendous_probe = opendous_probes;\n\n\tif (!opendous_type) {\n\t\topendous_type = strdup(\"opendous\");\n\t\tLOG_WARNING(\"No opendous_type specified, using default 'opendous'\");\n\t}\n\n\twhile (cur_opendous_probe->name) {\n\t\tif (strcmp(cur_opendous_probe->name, opendous_type) == 0) {\n\t\t\topendous_probe = cur_opendous_probe;\n\t\t\tbreak;\n\t\t}\n\t\tcur_opendous_probe++;\n\t}\n\n\tif (!opendous_probe) {\n\t\tLOG_ERROR(\"No matching cable found for %s\", opendous_type);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\n\tusb_in_buffer = malloc(opendous_probe->BUFFERSIZE);\n\tusb_out_buffer = malloc(opendous_probe->BUFFERSIZE);\n\n\tpending_scan_results_buffer = malloc(\n\t\t\tMAX_PENDING_SCAN_RESULTS * sizeof(*pending_scan_results_buffer));\n\n\topendous_jtag_handle = opendous_usb_open();\n\n\tif (!opendous_jtag_handle) {\n\t\tLOG_ERROR(\"Cannot find opendous Interface! Please check connection and permissions.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tcheck_cnt = 0;\n\twhile (check_cnt < 3) {\n\t\tif (opendous_get_version_info() == ERROR_OK) {\n\t\t\t/* attempt to get status */\n\t\t\topendous_get_status();\n\t\t\tbreak;\n\t\t}\n\n\t\tcheck_cnt++;\n\t}\n\n\tLOG_INFO(\"opendous JTAG Interface ready\");\n\n\topendous_reset(0, 0);\n\topendous_tap_init();\n\n\treturn ERROR_OK;\n}\n\nstatic int opendous_quit(void)\n{\n\topendous_usb_close(opendous_jtag_handle);\n\n\tfree(usb_out_buffer);\n\tusb_out_buffer = NULL;\n\n\tfree(usb_in_buffer);\n\tusb_in_buffer = NULL;\n\n\tfree(pending_scan_results_buffer);\n\tpending_scan_results_buffer = NULL;\n\n\tfree(opendous_type);\n\topendous_type = NULL;\n\n\treturn ERROR_OK;\n}\n\n/***************************************************************************/\n/* Queue command implementations */\n\nvoid opendous_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\n/* Goes to the end state. */\nvoid opendous_state_move(void)\n{\n\tint i;\n\tint tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tuint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tfor (i = 0; i < tms_scan_bits; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\topendous_tap_append_step(tms, 0);\n\t}\n\n\ttap_set_state(tap_get_end_state());\n}\n\nvoid opendous_path_move(int num_states, tap_state_t *path)\n{\n\tint i;\n\n\tfor (i = 0; i < num_states; i++) {\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false))\n\t\t\topendous_tap_append_step(0, 0);\n\t\telse if (path[i] == tap_state_transition(tap_get_state(), true))\n\t\t\topendous_tap_append_step(1, 0);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\t\ttap_state_name(tap_get_state()), tap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nvoid opendous_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\topendous_end_state(TAP_IDLE);\n\t\topendous_state_move();\n\t}\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++)\n\t\topendous_tap_append_step(0, 0);\n\n\t/* finish in end_state */\n\topendous_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\topendous_state_move();\n}\n\nvoid opendous_scan(int ir_scan, enum scan_type type, uint8_t *buffer, int scan_size, struct scan_command *command)\n{\n\ttap_state_t saved_end_state;\n\n\topendous_tap_ensure_space(1, scan_size + 8);\n\n\tsaved_end_state = tap_get_end_state();\n\n\t/* Move to appropriate scan state */\n\topendous_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\topendous_state_move();\n\n\topendous_end_state(saved_end_state);\n\n\t/* Scan */\n\topendous_tap_append_scan(scan_size, buffer, command);\n\n\t/* We are in Exit1, go to Pause */\n\topendous_tap_append_step(0, 0);\n\n\ttap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\topendous_state_move();\n}\n\nvoid opendous_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\t/* Signals are active low */\n#if 0\n\tif (srst == 0)\n\t\topendous_simple_command(JTAG_CMD_SET_SRST, 1);\n\telse if (srst == 1)\n\t\topendous_simple_command(JTAG_CMD_SET_SRST, 0);\n\n\tif (trst == 0)\n\t\topendous_simple_command(JTAG_CMD_SET_TRST, 1);\n\telse if (trst == 1)\n\t\topendous_simple_command(JTAG_CMD_SET_TRST, 0);\n#endif\n\n\tsrst = srst ? 0 : 1;\n\ttrst = trst ? 0 : 2;\n\topendous_simple_command(JTAG_CMD_SET_SRST_TRST, srst | trst);\n}\n\nvoid opendous_simple_command(uint8_t command, uint8_t _data)\n{\n\tint result;\n\n\tLOG_DEBUG_IO(\"0x%02x 0x%02x\", command, _data);\n\n\tusb_out_buffer[0] = 2;\n\tusb_out_buffer[1] = 0;\n\tusb_out_buffer[2] = command;\n\tusb_out_buffer[3] = _data;\n\n\tresult = opendous_usb_message(opendous_jtag_handle, 4, 1);\n\tif (result != 1)\n\t\tLOG_ERROR(\"opendous command 0x%02x failed (%d)\", command, result);\n}\n\nint opendous_get_status(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic int opendous_get_version_info(void)\n{\n\treturn ERROR_OK;\n}\n\n/***************************************************************************/\n/* Estick tap functions */\n\nstatic int tap_length;\nstatic uint8_t tms_buffer[OPENDOUS_TAP_BUFFER_SIZE];\nstatic uint8_t tdo_buffer[OPENDOUS_TAP_BUFFER_SIZE];\n\nstatic int last_tms;\n\nvoid opendous_tap_init(void)\n{\n\ttap_length = 0;\n\tpending_scan_results_length = 0;\n}\n\nvoid opendous_tap_ensure_space(int scans, int bits)\n{\n\tint available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;\n\tint available_bits = OPENDOUS_TAP_BUFFER_SIZE / 2 - tap_length;\n\n\tif ((scans > available_scans) || (bits > available_bits))\n\t\topendous_tap_execute();\n}\n\nvoid opendous_tap_append_step(int tms, int tdi)\n{\n\tlast_tms = tms;\n\tunsigned char _tms = tms ? 1 : 0;\n\tunsigned char _tdi = tdi ? 1 : 0;\n\n\topendous_tap_ensure_space(0, 1);\n\n\tint tap_index =  tap_length / 4;\n\tint bits  = (tap_length % 4) * 2;\n\n\tif (tap_length < OPENDOUS_TAP_BUFFER_SIZE) {\n\t\tif (!bits)\n\t\t\ttms_buffer[tap_index] = 0;\n\n\t\ttms_buffer[tap_index] |= (_tdi << bits)|(_tms << (bits + 1));\n\t\ttap_length++;\n\t} else\n\t\tLOG_ERROR(\"opendous_tap_append_step, overflow\");\n}\n\nvoid opendous_tap_append_scan(int length, uint8_t *buffer, struct scan_command *command)\n{\n\tLOG_DEBUG_IO(\"append scan, length = %d\", length);\n\n\tstruct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length];\n\tint i;\n\n\tpending_scan_result->first = tap_length;\n\tpending_scan_result->length = length;\n\tpending_scan_result->command = command;\n\tpending_scan_result->buffer = buffer;\n\n\tfor (i = 0; i < length; i++)\n\t\topendous_tap_append_step((i < length-1 ? 0 : 1), (buffer[i / 8] >> (i % 8)) & 1);\n\tpending_scan_results_length++;\n}\n\n/* Pad and send a tap sequence to the device, and receive the answer.\n * For the purpose of padding we assume that we are in idle or pause state. */\nint opendous_tap_execute(void)\n{\n\tint byte_length;\n\tint i, j;\n\tint result;\n\n#ifdef _DEBUG_USB_COMMS_\n\tint byte_length_out;\n#endif\n\n\tif (tap_length > 0) {\n\n\t\t/* memset(tdo_buffer,0,OPENDOUS_TAP_BUFFER_SIZE); */\n\t\t/* LOG_INFO(\"OPENDOUS tap execute %d\",tap_length); */\n\t\tbyte_length = (tap_length + 3) / 4;\n\n#ifdef _DEBUG_USB_COMMS_\n\t\tbyte_length_out = (tap_length + 7) / 8;\n\t\tLOG_DEBUG(\"opendous is sending %d bytes\", byte_length);\n#endif\n\n\t\tfor (j = 0, i = 0; j <  byte_length;) {\n\n\t\t\tint receive;\n\t\t\tint transmit = byte_length - j;\n\t\t\tif (transmit > OPENDOUS_MAX_TAP_TRANSMIT) {\n\t\t\t\ttransmit = OPENDOUS_MAX_TAP_TRANSMIT;\n\t\t\t\treceive = (OPENDOUS_MAX_TAP_TRANSMIT) / 2;\n\t\t\t\tusb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT;\n\t\t\t} else {\n\t\t\t\tusb_out_buffer[2] = JTAG_CMD_TAP_OUTPUT | ((tap_length % 4) << 4);\n\t\t\t\treceive = (transmit + 1) / 2;\n\t\t\t}\n\t\t\tusb_out_buffer[0] = (transmit + 1) & 0xff;\n\t\t\tusb_out_buffer[1] = ((transmit + 1) >> 8) & 0xff;\n\n\t\t\tmemmove(usb_out_buffer + 3, tms_buffer + j, transmit);\n\t\t\tresult = opendous_usb_message(opendous_jtag_handle, 3 + transmit, receive);\n\t\t\tif (result != receive) {\n\t\t\t\tLOG_ERROR(\"opendous_tap_execute, wrong result %d, expected %d\", result, receive);\n\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\t}\n\n\t\t\tmemmove(tdo_buffer + i, usb_in_buffer, receive);\n\t\t\ti += receive;\n\t\t\tj += transmit;\n\t\t}\n\n#ifdef _DEBUG_USB_COMMS_\n\t\tLOG_DEBUG(\"opendous tap result %d\", byte_length_out);\n\t\topendous_debug_buffer(tdo_buffer, byte_length_out);\n#endif\n\n\t\t/* LOG_INFO(\"eStick tap execute %d\",tap_length); */\n\t\tfor (i = 0; i < pending_scan_results_length; i++) {\n\n\t\t\tstruct pending_scan_result *pending_scan_result = &pending_scan_results_buffer[i];\n\t\t\tuint8_t *buffer = pending_scan_result->buffer;\n\t\t\tint length = pending_scan_result->length;\n\t\t\tint first = pending_scan_result->first;\n\t\t\tstruct scan_command *command = pending_scan_result->command;\n\n\t\t\t/* Copy to buffer */\n\t\t\tbuf_set_buf(tdo_buffer, first, buffer, 0, length);\n\n\t\t\tLOG_DEBUG_IO(\"pending scan result, length = %d\", length);\n\n#ifdef _DEBUG_USB_COMMS_\n\t\t\topendous_debug_buffer(buffer, byte_length_out);\n#endif\n\n\t\t\tif (jtag_read_buffer(buffer, command) != ERROR_OK) {\n\t\t\t\topendous_tap_init();\n\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\t}\n\n\t\t\tfree(pending_scan_result->buffer);\n\t\t}\n\n\t\topendous_tap_init();\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*****************************************************************************/\n/* Estick USB low-level functions */\n\nstruct opendous_jtag *opendous_usb_open(void)\n{\n\tstruct opendous_jtag *result;\n\n\tstruct libusb_device_handle *devh;\n\tif (jtag_libusb_open(opendous_probe->VID, opendous_probe->PID, &devh, NULL) != ERROR_OK)\n\t\treturn NULL;\n\n\tjtag_libusb_set_configuration(devh, 0);\n\tlibusb_claim_interface(devh, 0);\n\n\tresult = malloc(sizeof(*result));\n\tresult->usb_handle = devh;\n\treturn result;\n}\n\nvoid opendous_usb_close(struct opendous_jtag *opendous_jtag)\n{\n\tjtag_libusb_close(opendous_jtag->usb_handle);\n\tfree(opendous_jtag);\n}\n\n/* Send a message and receive the reply. */\nint opendous_usb_message(struct opendous_jtag *opendous_jtag, int out_length, int in_length)\n{\n\tint result;\n\n\tresult = opendous_usb_write(opendous_jtag, out_length);\n\tif (result == out_length) {\n\t\tresult = opendous_usb_read(opendous_jtag);\n\t\tif (result == in_length)\n\t\t\treturn result;\n\t\telse {\n\t\t\tLOG_ERROR(\"usb_bulk_read failed (requested=%d, result=%d)\", in_length, result);\n\t\t\treturn -1;\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"usb_bulk_write failed (requested=%d, result=%d)\", out_length, result);\n\t\treturn -1;\n\t}\n}\n\n/* Write data from out_buffer to USB. */\nint opendous_usb_write(struct opendous_jtag *opendous_jtag, int out_length)\n{\n\tint result;\n\n\tif (out_length > OPENDOUS_OUT_BUFFER_SIZE) {\n\t\tLOG_ERROR(\"opendous_jtag_write illegal out_length=%d (max=%d)\", out_length, OPENDOUS_OUT_BUFFER_SIZE);\n\t\treturn -1;\n\t}\n\n#ifdef _DEBUG_USB_COMMS_\n\tLOG_DEBUG(\"USB write begin\");\n#endif\n\tif (opendous_probe->CONTROL_TRANSFER) {\n\t\tresult = jtag_libusb_control_transfer(opendous_jtag->usb_handle,\n\t\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT,\n\t\t\tFUNC_WRITE_DATA, 0, 0, (char *) usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT);\n\t} else {\n\t\tjtag_libusb_bulk_write(opendous_jtag->usb_handle, OPENDOUS_WRITE_ENDPOINT,\n\t\t\t(char *)usb_out_buffer, out_length, OPENDOUS_USB_TIMEOUT, &result);\n\t}\n#ifdef _DEBUG_USB_COMMS_\n\tLOG_DEBUG(\"USB write end: %d bytes\", result);\n#endif\n\n\tLOG_DEBUG_IO(\"opendous_usb_write, out_length = %d, result = %d\", out_length, result);\n\n#ifdef _DEBUG_USB_COMMS_\n\topendous_debug_buffer(usb_out_buffer, out_length);\n#endif\n\treturn result;\n}\n\n/* Read data from USB into in_buffer. */\nint opendous_usb_read(struct opendous_jtag *opendous_jtag)\n{\n#ifdef _DEBUG_USB_COMMS_\n\tLOG_DEBUG(\"USB read begin\");\n#endif\n\tint result;\n\tif (opendous_probe->CONTROL_TRANSFER) {\n\t\tresult = jtag_libusb_control_transfer(opendous_jtag->usb_handle,\n\t\t\tLIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,\n\t\t\tFUNC_READ_DATA, 0, 0, (char *) usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT);\n\t} else {\n\t\tjtag_libusb_bulk_read(opendous_jtag->usb_handle, OPENDOUS_READ_ENDPOINT,\n\t\t\t(char *)usb_in_buffer, OPENDOUS_IN_BUFFER_SIZE, OPENDOUS_USB_TIMEOUT, &result);\n\t}\n#ifdef _DEBUG_USB_COMMS_\n\tLOG_DEBUG(\"USB read end: %d bytes\", result);\n#endif\n\tLOG_DEBUG_IO(\"opendous_usb_read, result = %d\", result);\n\n#ifdef _DEBUG_USB_COMMS_\n\topendous_debug_buffer(usb_in_buffer, result);\n#endif\n\treturn result;\n}\n\n#ifdef _DEBUG_USB_COMMS_\n#define BYTES_PER_LINE  16\n\nvoid opendous_debug_buffer(uint8_t *buffer, int length)\n{\n\tchar line[8 + 3 * BYTES_PER_LINE + 1];\n\n\tfor (int i = 0; i < length; i += BYTES_PER_LINE) {\n\t\tint n = snprintf(line, 9, \"%04x\", i);\n\t\tfor (int j = i; j < i + BYTES_PER_LINE && j < length; j++)\n\t\t\tn += snprintf(line + n, 4, \" %02x\", buffer[j]);\n\t\tLOG_DEBUG(\"%s\", line);\n\t}\n}\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/openjtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*******************************************************************************\n *   Driver for OpenJTAG Project (www.openjtag.org)                            *\n *   Compatible with libftdi drivers.                                          *\n *                                                                             *\n *   Cypress CY7C65215 support                                                 *\n *   Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV        *\n *                      <vianney.leclement@essensium.com>                      *\n *                                                                             *\n *   Copyright (C) 2010 by Ivan Meleca <mileca@gmail.com>                      *\n *                                                                             *\n *   Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. <corbin.ryan@gmail.com> *\n *   Updated to work with OpenOCD v0.7.0. Fixed libftdi read speed issue.      *\n *                                                                             *\n *   Based on usb_blaster.c                                                    *\n *   Copyright (C) 2009 Catalin Patulea                                        *\n *   Copyright (C) 2006 Kolja Waschk                                           *\n *                                                                             *\n *   And jlink.c                                                               *\n *   Copyright (C) 2008 by Spencer Oliver                                      *\n *   spen@spen-soft.co.uk                                                      *\n ***************************************************************************/\n\n/***************************************************************************\n * Version 1.0  Tested on a MCBSTM32 board using a Cortex-M3 (stm32f103x), *\n *              GDB and Eclipse under Linux (Ubuntu 10.04)                 *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"libusb_helper.h\"\n\nstatic enum {\n\tOPENJTAG_VARIANT_STANDARD,\n\tOPENJTAG_VARIANT_CY7C65215,\n} openjtag_variant = OPENJTAG_VARIANT_STANDARD;\n\nstatic const char * const openjtag_variant_names[] = {\n\t\"standard\",\n\t\"cy7c65215\",\n\tNULL\n};\n\n/*\n * OpenJTAG-OpenOCD state conversion\n */\ntypedef enum openjtag_tap_state {\n\tOPENJTAG_TAP_INVALID    = -1,\n\tOPENJTAG_TAP_RESET  = 0,\n\tOPENJTAG_TAP_IDLE   = 1,\n\tOPENJTAG_TAP_SELECT_DR  = 2,\n\tOPENJTAG_TAP_CAPTURE_DR = 3,\n\tOPENJTAG_TAP_SHIFT_DR   = 4,\n\tOPENJTAG_TAP_EXIT1_DR   = 5,\n\tOPENJTAG_TAP_PAUSE_DR   = 6,\n\tOPENJTAG_TAP_EXIT2_DR   = 7,\n\tOPENJTAG_TAP_UPDATE_DR  = 8,\n\tOPENJTAG_TAP_SELECT_IR  = 9,\n\tOPENJTAG_TAP_CAPURE_IR  = 10,\n\tOPENJTAG_TAP_SHIFT_IR   = 11,\n\tOPENJTAG_TAP_EXIT1_IR   = 12,\n\tOPENJTAG_TAP_PAUSE_IR   = 13,\n\tOPENJTAG_TAP_EXIT2_IR   = 14,\n\tOPENJTAG_TAP_UPDATE_IR  = 15,\n} openjtag_tap_state_t;\n\n/* OPENJTAG access library includes */\n#include \"libftdi_helper.h\"\n\n/* OpenJTAG vid/pid */\nstatic uint16_t openjtag_vid = 0x0403;\nstatic uint16_t openjtag_pid = 0x6001;\n\nstatic char *openjtag_device_desc;\n\nstatic struct ftdi_context ftdic;\n\n#define OPENJTAG_BUFFER_SIZE        504\n#define OPENJTAG_MAX_PENDING_RESULTS    256\n\nstruct openjtag_scan_result {\n\tuint32_t bits;          /* Length in bits*/\n\tstruct scan_command *command;   /* Corresponding scan command */\n\tuint8_t *buffer;\n};\n\n/* USB RX/TX buffers */\nstatic int usb_tx_buf_offs;\nstatic uint8_t usb_tx_buf[OPENJTAG_BUFFER_SIZE];\nstatic uint32_t usb_rx_buf_len;\nstatic uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE];\n\n/* Pending readings */\nstatic struct openjtag_scan_result openjtag_scan_result_buffer[OPENJTAG_MAX_PENDING_RESULTS];\nstatic int openjtag_scan_result_count;\n\nstatic struct libusb_device_handle *usbh;\n\n/* CY7C65215 model only */\n#define CY7C65215_JTAG_REQUEST  0x40  /* bmRequestType: vendor host-to-device */\n#define CY7C65215_JTAG_ENABLE   0xD0  /* bRequest: enable JTAG */\n#define CY7C65215_JTAG_DISABLE  0xD1  /* bRequest: disable JTAG */\n#define CY7C65215_JTAG_READ     0xD2  /* bRequest: read buffer */\n#define CY7C65215_JTAG_WRITE    0xD3  /* bRequest: write buffer */\n\n#define CY7C65215_USB_TIMEOUT   100\n\nstatic const uint16_t cy7c65215_vids[] = {0x04b4, 0};\nstatic const uint16_t cy7c65215_pids[] = {0x0007, 0};\n\n#define CY7C65215_JTAG_CLASS     0xff\n#define CY7C65215_JTAG_SUBCLASS  0x04\n\nstatic unsigned int ep_in, ep_out;\n\n#ifdef _DEBUG_USB_COMMS_\n\n#define DEBUG_TYPE_READ     0\n#define DEBUG_TYPE_WRITE    1\n#define DEBUG_TYPE_OCD_READ 2\n#define DEBUG_TYPE_BUFFER   3\n\n#define LINE_LEN  16\nstatic void openjtag_debug_buffer(uint8_t *buffer, int length, uint8_t type)\n{\n\tchar line[128];\n\tchar s[4];\n\tint i;\n\tint j;\n\n\tswitch (type) {\n\t\tcase DEBUG_TYPE_READ:\n\t\t\tsprintf(line, \"USB READ %d bytes\", length);\n\t\t\tbreak;\n\t\tcase DEBUG_TYPE_WRITE:\n\t\t\tsprintf(line, \"USB WRITE %d bytes\", length);\n\t\t\tbreak;\n\t\tcase DEBUG_TYPE_OCD_READ:\n\t\t\tsprintf(line, \"TO OpenOCD %d bytes\", length);\n\t\t\tbreak;\n\t\tcase DEBUG_TYPE_BUFFER:\n\t\t\tsprintf(line, \"Buffer %d bytes\", length);\n\t\t\tbreak;\n\t}\n\n\tLOG_DEBUG(\"%s\", line);\n\n\tfor (i = 0; i < length; i += LINE_LEN) {\n\t\tswitch (type) {\n\t\t\tcase DEBUG_TYPE_READ:\n\t\t\t\tsprintf(line, \"USB READ: %04x\", i);\n\t\t\t\tbreak;\n\t\t\tcase DEBUG_TYPE_WRITE:\n\t\t\t\tsprintf(line, \"USB WRITE: %04x\", i);\n\t\t\t\tbreak;\n\t\t\tcase DEBUG_TYPE_OCD_READ:\n\t\t\t\tsprintf(line, \"TO OpenOCD: %04x\", i);\n\t\t\t\tbreak;\n\t\t\tcase DEBUG_TYPE_BUFFER:\n\t\t\t\tsprintf(line, \"BUFFER: %04x\", i);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tfor (j = i; j < i + LINE_LEN && j < length; j++) {\n\t\t\tsprintf(s, \" %02x\", buffer[j]);\n\t\t\tstrcat(line, s);\n\t\t}\n\t\tLOG_DEBUG(\"%s\", line);\n\t}\n\n}\n\n#endif\n\nstatic int8_t openjtag_get_tap_state(int8_t state)\n{\n\n\tswitch (state) {\n\t\tcase TAP_DREXIT2:   return OPENJTAG_TAP_EXIT2_DR;\n\t\tcase TAP_DREXIT1:   return OPENJTAG_TAP_EXIT1_DR;\n\t\tcase TAP_DRSHIFT:   return OPENJTAG_TAP_SHIFT_DR;\n\t\tcase TAP_DRPAUSE:   return OPENJTAG_TAP_PAUSE_DR;\n\t\tcase TAP_IRSELECT:  return OPENJTAG_TAP_SELECT_IR;\n\t\tcase TAP_DRUPDATE:  return OPENJTAG_TAP_UPDATE_DR;\n\t\tcase TAP_DRCAPTURE: return OPENJTAG_TAP_CAPTURE_DR;\n\t\tcase TAP_DRSELECT:  return OPENJTAG_TAP_SELECT_DR;\n\t\tcase TAP_IREXIT2:   return OPENJTAG_TAP_EXIT2_IR;\n\t\tcase TAP_IREXIT1:   return OPENJTAG_TAP_EXIT1_IR;\n\t\tcase TAP_IRSHIFT:   return OPENJTAG_TAP_SHIFT_IR;\n\t\tcase TAP_IRPAUSE:   return OPENJTAG_TAP_PAUSE_IR;\n\t\tcase TAP_IDLE:      return OPENJTAG_TAP_IDLE;\n\t\tcase TAP_IRUPDATE:  return OPENJTAG_TAP_UPDATE_IR;\n\t\tcase TAP_IRCAPTURE: return OPENJTAG_TAP_CAPURE_IR;\n\t\tcase TAP_RESET:     return OPENJTAG_TAP_RESET;\n\t\tcase TAP_INVALID:\n\t\tdefault:            return OPENJTAG_TAP_INVALID;\n\t}\n}\n\nstatic int openjtag_buf_write_standard(\n\tuint8_t *buf, int size, uint32_t *bytes_written)\n{\n\tint retval;\n#ifdef _DEBUG_USB_COMMS_\n\topenjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);\n#endif\n\n\tretval = ftdi_write_data(&ftdic, buf, size);\n\tif (retval < 0) {\n\t\t*bytes_written = 0;\n\t\tLOG_ERROR(\"ftdi_write_data: %s\", ftdi_get_error_string(&ftdic));\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t*bytes_written = retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_buf_write_cy7c65215(\n\tuint8_t *buf, int size, uint32_t *bytes_written)\n{\n\tint ret;\n\n#ifdef _DEBUG_USB_COMMS_\n\topenjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);\n#endif\n\n\tif (size == 0) {\n\t\t*bytes_written = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_WRITE, size, 0,\n\t\t\t\t\t\t\t\t\t   NULL, 0, CY7C65215_USB_TIMEOUT);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"vendor command failed, error %d\", ret);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size,\n\t\t\t\t   CY7C65215_USB_TIMEOUT, &ret)) {\n\t\tLOG_ERROR(\"bulk write failed, error\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\t*bytes_written = ret;\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_buf_write(\n\tuint8_t *buf, int size, uint32_t *bytes_written)\n{\n\tswitch (openjtag_variant) {\n\tcase OPENJTAG_VARIANT_CY7C65215:\n\t\treturn openjtag_buf_write_cy7c65215(buf, size, bytes_written);\n\tdefault:\n\t\treturn openjtag_buf_write_standard(buf, size, bytes_written);\n\t}\n}\n\nstatic int openjtag_buf_read_standard(\n\tuint8_t *buf, uint32_t qty, uint32_t *bytes_read)\n{\n\n\tint retval;\n\tint timeout = 5;\n\n\t*bytes_read = 0;\n\n\twhile ((*bytes_read < qty) && timeout--) {\n\t\tretval = ftdi_read_data(&ftdic, buf + *bytes_read,\n\t\t\t\tqty - *bytes_read);\n\t\tif (retval < 0) {\n\t\t\t*bytes_read = 0;\n\t\t\tLOG_DEBUG_IO(\"ftdi_read_data: %s\",\n\t\t\t\t\tftdi_get_error_string(&ftdic));\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\t*bytes_read += retval;\n\t}\n\n#ifdef _DEBUG_USB_COMMS_\n\topenjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_buf_read_cy7c65215(\n\tuint8_t *buf, uint32_t qty, uint32_t *bytes_read)\n{\n\tint ret;\n\n\tif (qty == 0) {\n\t\t*bytes_read = 0;\n\t\tgoto out;\n\t}\n\n\tret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_READ, qty, 0,\n\t\t\t\t\t\t\t\t\t   NULL, 0, CY7C65215_USB_TIMEOUT);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"vendor command failed, error %d\", ret);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty,\n\t\t\t\t  CY7C65215_USB_TIMEOUT, &ret)) {\n\t\tLOG_ERROR(\"bulk read failed, error\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\t*bytes_read = ret;\n\nout:\n#ifdef _DEBUG_USB_COMMS_\n\topenjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)\n{\n\tswitch (openjtag_variant) {\n\tcase OPENJTAG_VARIANT_CY7C65215:\n\t\treturn openjtag_buf_read_cy7c65215(buf, qty, bytes_read);\n\tdefault:\n\t\treturn openjtag_buf_read_standard(buf, qty, bytes_read);\n\t}\n}\n\nstatic int openjtag_sendcommand(uint8_t cmd)\n{\n\tuint32_t written;\n\treturn openjtag_buf_write(&cmd, 1, &written);\n}\n\nstatic int openjtag_speed(int speed)\n{\n\tint clockcmd;\n\tswitch (speed) {\n\t\tcase 48000:\n\t\t\tclockcmd = 0x00;\n\t\t\tbreak;\n\t\tcase 24000:\n\t\t\tclockcmd = 0x20;\n\t\t\tbreak;\n\t\tcase 12000:\n\t\t\tclockcmd = 0x40;\n\t\t\tbreak;\n\t\tcase 6000:\n\t\t\tclockcmd = 0x60;\n\t\t\tbreak;\n\t\tcase 3000:\n\t\t\tclockcmd = 0x80;\n\t\t\tbreak;\n\t\tcase 1500:\n\t\t\tclockcmd = 0xA0;\n\t\t\tbreak;\n\t\tcase 750:\n\t\t\tclockcmd = 0xC0;\n\t\t\tbreak;\n\t\tcase 375:\n\t\t\tclockcmd = 0xE0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tclockcmd = 0xE0;\n\t\t\tLOG_WARNING(\"adapter speed not recognized, reverting to 375 kHz\");\n\t\t\tbreak;\n\t}\n\topenjtag_sendcommand(clockcmd);\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_init_standard(void)\n{\n\tuint8_t latency_timer;\n\n\t/* Open by device description */\n\tif (!openjtag_device_desc) {\n\t\tLOG_WARNING(\"no openjtag device description specified, \"\n\t\t\t\t\"using default 'Open JTAG Project'\");\n\t\topenjtag_device_desc = \"Open JTAG Project\";\n\t}\n\n\tif (ftdi_init(&ftdic) < 0)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\t/* context, vendor id, product id, description, serial id */\n\tif (ftdi_usb_open_desc(&ftdic, openjtag_vid, openjtag_pid, openjtag_device_desc, NULL) < 0) {\n\t\tLOG_ERROR(\"unable to open ftdi device: %s\", ftdic.error_str);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_usb_reset(&ftdic) < 0) {\n\t\tLOG_ERROR(\"unable to reset ftdi device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_set_latency_timer(&ftdic, 2) < 0) {\n\t\tLOG_ERROR(\"unable to set latency timer\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_get_latency_timer(&ftdic, &latency_timer) < 0) {\n\t\tLOG_ERROR(\"unable to get latency timer\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tLOG_DEBUG(\"current latency timer: %u\", latency_timer);\n\n\tftdi_disable_bitbang(&ftdic);\n\t/* was (3000000 / 4) with a comment about a bug in libftdi when using high baudrate */\n\tif (ftdi_set_baudrate(&ftdic, 3000000) < 0) {\n\t\tLOG_ERROR(\"Can't set baud rate to max: %s\",\n\t\t\tftdi_get_error_string(&ftdic));\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (ftdi_tcioflush(&ftdic) < 0) {\n\t\tLOG_ERROR(\"ftdi flush: %s\", ftdic.error_str);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_init_cy7c65215(void)\n{\n\tint ret;\n\n\tusbh = NULL;\n\tret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, &usbh, NULL);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"unable to open cy7c65215 device\");\n\t\tgoto err;\n\t}\n\n\tret = jtag_libusb_choose_interface(usbh, &ep_in, &ep_out,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_CLASS,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_SUBCLASS, -1, LIBUSB_TRANSFER_TYPE_BULK);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"unable to claim JTAG interface\");\n\t\tgoto err;\n\t}\n\n\tret = jtag_libusb_control_transfer(usbh,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_REQUEST,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_ENABLE,\n\t\t\t\t\t\t\t\t\t   0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"could not enable JTAG module\");\n\t\tgoto err;\n\t}\n\n\treturn ERROR_OK;\n\nerr:\n\tif (usbh)\n\t\tjtag_libusb_close(usbh);\n\treturn ERROR_JTAG_INIT_FAILED;\n}\n\nstatic int openjtag_init(void)\n{\n\tint ret;\n\n\tusb_tx_buf_offs = 0;\n\tusb_rx_buf_len = 0;\n\topenjtag_scan_result_count = 0;\n\n\tswitch (openjtag_variant) {\n\tcase OPENJTAG_VARIANT_CY7C65215:\n\t\tret = openjtag_init_cy7c65215();\n\t\tbreak;\n\tdefault:\n\t\tret = openjtag_init_standard();\n\t}\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\topenjtag_speed(375); /* Start at slowest adapter speed */\n\topenjtag_sendcommand(0x75); /* MSB */\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_quit_standard(void)\n{\n\tftdi_usb_close(&ftdic);\n\tftdi_deinit(&ftdic);\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_quit_cy7c65215(void)\n{\n\tint ret;\n\n\tret = jtag_libusb_control_transfer(usbh,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_REQUEST,\n\t\t\t\t\t\t\t\t\t   CY7C65215_JTAG_DISABLE,\n\t\t\t\t\t\t\t\t\t   0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);\n\tif (ret < 0)\n\t\tLOG_WARNING(\"could not disable JTAG module\");\n\n\tjtag_libusb_close(usbh);\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_quit(void)\n{\n\tswitch (openjtag_variant) {\n\tcase OPENJTAG_VARIANT_CY7C65215:\n\t\treturn openjtag_quit_cy7c65215();\n\tdefault:\n\t\treturn openjtag_quit_standard();\n\t}\n}\n\nstatic void openjtag_write_tap_buffer(void)\n{\n\tuint32_t written;\n\n\topenjtag_buf_write(usb_tx_buf, usb_tx_buf_offs, &written);\n\topenjtag_buf_read(usb_rx_buf, usb_tx_buf_offs, &usb_rx_buf_len);\n\n\tusb_tx_buf_offs = 0;\n}\n\nstatic int openjtag_execute_tap_queue(void)\n{\n\topenjtag_write_tap_buffer();\n\n\tint res_count = 0;\n\n\tif (openjtag_scan_result_count && usb_rx_buf_len) {\n\n\t\tint count;\n\t\tint rx_offs = 0;\n\t\tint len;\n\n\t\t/* for every pending result */\n\t\twhile (res_count < openjtag_scan_result_count) {\n\n\t\t\t/* get sent bits */\n\t\t\tlen = openjtag_scan_result_buffer[res_count].bits;\n\n\t\t\tcount = 0;\n\n\t\t\tuint8_t *buffer = openjtag_scan_result_buffer[res_count].buffer;\n\n\t\t\twhile (len > 0) {\n\t\t\t\tif (len <= 8 && openjtag_variant != OPENJTAG_VARIANT_CY7C65215) {\n\t\t\t\t\tLOG_DEBUG_IO(\"bits < 8 buf = 0x%X, will be 0x%X\",\n\t\t\t\t\t\tusb_rx_buf[rx_offs], usb_rx_buf[rx_offs] >> (8 - len));\n\t\t\t\t\tbuffer[count] = usb_rx_buf[rx_offs] >> (8 - len);\n\t\t\t\t\tlen = 0;\n\t\t\t\t} else {\n\t\t\t\t\tbuffer[count] = usb_rx_buf[rx_offs];\n\t\t\t\t\tlen -= 8;\n\t\t\t\t}\n\n\t\t\t\trx_offs++;\n\t\t\t\tcount++;\n\t\t\t}\n\n#ifdef _DEBUG_USB_COMMS_\n\t\t\topenjtag_debug_buffer(buffer,\n\t\t\t\tDIV_ROUND_UP(openjtag_scan_result_buffer[res_count].bits, 8), DEBUG_TYPE_OCD_READ);\n#endif\n\t\t\tjtag_read_buffer(buffer, openjtag_scan_result_buffer[res_count].command);\n\n\t\t\tfree(openjtag_scan_result_buffer[res_count].buffer);\n\n\t\t\tres_count++;\n\t\t}\n\t}\n\n\topenjtag_scan_result_count = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic void openjtag_add_byte(char buf)\n{\n\n\tif (usb_tx_buf_offs == OPENJTAG_BUFFER_SIZE) {\n\t\tLOG_DEBUG_IO(\"Forcing execute_tap_queue\");\n\t\tLOG_DEBUG_IO(\"TX Buff offs=%d\", usb_tx_buf_offs);\n\t\topenjtag_execute_tap_queue();\n\t}\n\n\tusb_tx_buf[usb_tx_buf_offs] = buf;\n\tusb_tx_buf_offs++;\n}\n\nstatic void openjtag_add_scan(uint8_t *buffer, int length, struct scan_command *scan_cmd)\n{\n\n\t/* Ensure space to send long chains */\n\t/* We add two byte for each eight (or less) bits, one for command, one for data */\n\tif (usb_tx_buf_offs + (DIV_ROUND_UP(length, 8) * 2) >= OPENJTAG_BUFFER_SIZE) {\n\t\tLOG_DEBUG_IO(\"Forcing execute_tap_queue from scan\");\n\t\tLOG_DEBUG_IO(\"TX Buff offs=%d len=%d\", usb_tx_buf_offs, DIV_ROUND_UP(length, 8) * 2);\n\t\topenjtag_execute_tap_queue();\n\t}\n\n\topenjtag_scan_result_buffer[openjtag_scan_result_count].bits = length;\n\topenjtag_scan_result_buffer[openjtag_scan_result_count].command = scan_cmd;\n\topenjtag_scan_result_buffer[openjtag_scan_result_count].buffer = buffer;\n\n\tuint8_t command;\n\tuint8_t bits;\n\tint count = 0;\n\twhile (length) {\n\n\t\t/* write command */\n\t\tcommand = 6;\n\n\t\t/* last bits? */\n\t\tif (length <= 8) {\n\t\t\t/* tms high */\n\t\t\tcommand |= (1 << 4);\n\n\t\t\t/* bits to transfer */\n\t\t\tbits = (length - 1);\n\t\t\tcommand |= bits << 5;\n\t\t\tlength = 0;\n\t\t} else {\n\t\t\t/* whole byte */\n\n\t\t\t/* bits to transfer */\n\t\t\tcommand |= (7 << 5);\n\t\t\tlength -= 8;\n\t\t}\n\n\t\topenjtag_add_byte(command);\n\t\topenjtag_add_byte(buffer[count]);\n\t\tcount++;\n\t}\n\n\topenjtag_scan_result_count++;\n}\n\nstatic void openjtag_execute_reset(struct jtag_command *cmd)\n{\n\n\tLOG_DEBUG_IO(\"reset trst: %i srst %i\",\n\t\t\tcmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\n\tuint8_t buf = 0x00;\n\n\tif (cmd->cmd.reset->trst) {\n\t\tbuf = 0x03;\n\t} else {\n\t\tbuf |= 0x04;\n\t\tbuf |= 0x05 << 4;\n\t}\n\n\topenjtag_add_byte(buf);\n}\n\nstatic void openjtag_execute_sleep(struct jtag_command *cmd)\n{\n\tjtag_sleep(cmd->cmd.sleep->us);\n}\n\nstatic void openjtag_set_state(uint8_t openocd_state)\n{\n\tuint8_t state = openjtag_get_tap_state(openocd_state);\n\n\tuint8_t buf = 0;\n\tbuf = 0x01;\n\tbuf |= state << 4;\n\n\topenjtag_add_byte(buf);\n}\n\nstatic void openjtag_execute_statemove(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"state move to %i\", cmd->cmd.statemove->end_state);\n\n\ttap_set_end_state(cmd->cmd.statemove->end_state);\n\n\topenjtag_set_state(cmd->cmd.statemove->end_state);\n\n\ttap_set_state(tap_get_end_state());\n}\n\n\nstatic void openjtag_execute_scan(struct jtag_command *cmd)\n{\n\n\tint scan_size, old_state;\n\tuint8_t *buffer;\n\n\tLOG_DEBUG_IO(\"scan ends in %s\", tap_state_name(cmd->cmd.scan->end_state));\n\n\t/* get scan info */\n\ttap_set_end_state(cmd->cmd.scan->end_state);\n\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\n#ifdef _DEBUG_USB_COMMS_\n\topenjtag_debug_buffer(buffer, (scan_size + 7) / 8, DEBUG_TYPE_BUFFER);\n#endif\n\t/* set state */\n\told_state = tap_get_end_state();\n\topenjtag_set_state(cmd->cmd.scan->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\ttap_set_state(cmd->cmd.scan->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\ttap_set_end_state(old_state);\n\n\topenjtag_add_scan(buffer, scan_size, cmd->cmd.scan);\n\n\topenjtag_set_state(cmd->cmd.scan->ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\ttap_set_state(cmd->cmd.scan->ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\topenjtag_set_state(tap_get_end_state());\n\t\ttap_set_state(tap_get_end_state());\n\t}\n}\n\nstatic void openjtag_execute_runtest(struct jtag_command *cmd)\n{\n\n\ttap_state_t end_state = cmd->cmd.runtest->end_state;\n\ttap_set_end_state(end_state);\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\topenjtag_set_state(TAP_IDLE);\n\t\ttap_set_state(TAP_IDLE);\n\t}\n\n\tif (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||\n\t\tcmd->cmd.runtest->num_cycles) {\n\t\tuint8_t command;\n\t\tint cycles = cmd->cmd.runtest->num_cycles;\n\n\t\tdo {\n\t\t\tcommand = 7;\n\t\t\tcommand |= (((cycles > 16 ? 16 : cycles) - 1) & 0x0F) << 4;\n\n\t\t\topenjtag_add_byte(command);\n\t\t\tcycles -= 16;\n\t\t} while (cycles > 0);\n\t}\n\n\ttap_set_end_state(end_state);\n\tif (tap_get_end_state() != tap_get_state()) {\n\t\topenjtag_set_state(end_state);\n\t\ttap_set_state(end_state);\n\t}\n}\n\nstatic void openjtag_execute_command(struct jtag_command *cmd)\n{\n\tLOG_DEBUG_IO(\"openjtag_execute_command %i\", cmd->type);\n\tswitch (cmd->type) {\n\tcase JTAG_RESET:\n\t\t\topenjtag_execute_reset(cmd);\n\t\t\tbreak;\n\tcase JTAG_SLEEP:\n\t\t\topenjtag_execute_sleep(cmd);\n\t\t\tbreak;\n\tcase JTAG_TLR_RESET:\n\t\t\topenjtag_execute_statemove(cmd);\n\t\t\tbreak;\n\tcase JTAG_SCAN:\n\t\t\topenjtag_execute_scan(cmd);\n\t\t\tbreak;\n\tcase JTAG_RUNTEST:\n\t\t\topenjtag_execute_runtest(cmd);\n\t\t\tbreak;\n\tcase JTAG_PATHMOVE:\n\t\t/* jlink_execute_pathmove(cmd); break; */\n\tdefault:\n\t\tLOG_ERROR(\"BUG: unknown Open JTAG command type encountered\");\n\t\texit(-1);\n\t}\n}\n\nstatic int openjtag_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\n\twhile (cmd) {\n\t\topenjtag_execute_command(cmd);\n\t\tcmd = cmd->next;\n\t}\n\n\treturn openjtag_execute_tap_queue();\n}\n\nstatic int openjtag_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\n\treturn ERROR_OK;\n}\n\nstatic int openjtag_khz(int khz, int *jtag_speed)\n{\n\n\tif (khz >= 48000)\n\t\t*jtag_speed = 48000;\n\telse if (khz >= 24000)\n\t\t*jtag_speed = 24000;\n\telse if (khz >= 12000)\n\t\t*jtag_speed = 12000;\n\telse if (khz >= 6000)\n\t\t*jtag_speed = 6000;\n\telse if (khz >= 3000)\n\t\t*jtag_speed = 3000;\n\telse if (khz >= 1500)\n\t\t*jtag_speed = 1500;\n\telse if (khz >= 750)\n\t\t*jtag_speed = 750;\n\telse\n\t\t*jtag_speed = 375;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(openjtag_handle_device_desc_command)\n{\n\tif (CMD_ARGC == 1)\n\t\topenjtag_device_desc = strdup(CMD_ARGV[0]);\n\telse\n\t\tLOG_ERROR(\"require exactly one argument to \"\n\t\t\t\t  \"openjtag_device_desc <description>\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(openjtag_handle_variant_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tconst char * const *name = openjtag_variant_names;\n\t\tint variant = 0;\n\t\tfor (; *name; name++, variant++) {\n\t\t\tif (strcasecmp(CMD_ARGV[0], *name) == 0) {\n\t\t\t\topenjtag_variant = variant;\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t\tLOG_ERROR(\"unknown openjtag variant '%s'\", CMD_ARGV[0]);\n\t} else {\n\t\tLOG_ERROR(\"require exactly one argument to \"\n\t\t\t\t\"openjtag_variant <variant>\");\n\t}\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration openjtag_subcommand_handlers[] = {\n\t{\n\t\t.name = \"device_desc\",\n\t\t.handler = openjtag_handle_device_desc_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the USB device description of the OpenJTAG\",\n\t\t.usage = \"description-string\",\n\t},\n\t{\n\t\t.name = \"variant\",\n\t\t.handler = openjtag_handle_variant_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the OpenJTAG variant\",\n\t\t.usage = \"variant-string\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration openjtag_command_handlers[] = {\n\t{\n\t\t.name = \"openjtag\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform openjtag management\",\n\t\t.chain = openjtag_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface openjtag_interface = {\n\t.execute_queue = openjtag_execute_queue,\n};\n\nstruct adapter_driver openjtag_adapter_driver = {\n\t.name = \"openjtag\",\n\t.transports = jtag_only,\n\t.commands = openjtag_command_handlers,\n\n\t.init = openjtag_init,\n\t.quit = openjtag_quit,\n\t.speed = openjtag_speed,\n\t.khz = openjtag_khz,\n\t.speed_div = openjtag_speed_div,\n\n\t.jtag_ops = &openjtag_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/osbdm.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2012 by Jan Dakinevich                                  *\n *   jan.dakinevich@gmail.com                                              *\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#\tinclude \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <jtag/interface.h>\n#include \"libusb_helper.h\"\n\nstruct sequence {\n\tint len;\n\tvoid *tms;\n\tvoid *tdo;\n\tconst void *tdi;\n\tstruct sequence *next;\n};\n\nstruct queue {\n\tstruct sequence *head;\n\tstruct sequence *tail;\n};\n\nstatic struct sequence *queue_add_tail(struct queue *queue, int len)\n{\n\tif (len <= 0) {\n\t\tLOG_ERROR(\"BUG: sequences with zero length are not allowed\");\n\t\treturn NULL;\n\t}\n\n\tstruct sequence *next;\n\tnext = malloc(sizeof(*next));\n\tif (next) {\n\t\tnext->tms = calloc(1, DIV_ROUND_UP(len, 8));\n\t\tif (next->tms) {\n\t\t\tnext->len = len;\n\t\t\tnext->tdo = NULL;\n\t\t\tnext->tdi = NULL;\n\t\t\tnext->next = NULL;\n\n\t\t\tif (!queue->head) {\n\t\t\t\t/* Queue is empty at the moment */\n\t\t\t\tqueue->head = next;\n\t\t\t} else {\n\t\t\t\t/* Queue already contains at least one sequence */\n\t\t\t\tqueue->tail->next = next;\n\t\t\t}\n\n\t\t\tqueue->tail = next;\n\t\t} else {\n\t\t\tfree(next);\n\t\t\tnext = NULL;\n\t\t}\n\t}\n\n\tif (!next)\n\t\tLOG_ERROR(\"Not enough memory\");\n\n\treturn next;\n}\n\nstatic void queue_drop_head(struct queue *queue)\n{\n\tstruct sequence *head = queue->head->next; /* New head */\n\tfree(queue->head->tms);\n\tfree(queue->head);\n\tqueue->head = head;\n}\n\nstatic void queue_free(struct queue *queue)\n{\n\tif (queue) {\n\t\twhile (queue->head)\n\t\t\tqueue_drop_head(queue);\n\n\t\tfree(queue);\n\t}\n}\n\nstatic struct queue *queue_alloc(void)\n{\n\tstruct queue *queue = malloc(sizeof(*queue));\n\tif (queue)\n\t\tqueue->head = NULL;\n\telse\n\t\tLOG_ERROR(\"Not enough memory\");\n\n\treturn queue;\n}\n\n/* Size of usb communication buffer */\n#define OSBDM_USB_BUFSIZE 64\n/* Timeout for USB transfer, ms */\n#define OSBDM_USB_TIMEOUT 1000\n/* Write end point */\n#define OSBDM_USB_EP_WRITE 0x01\n/* Read end point */\n#define OSBDM_USB_EP_READ 0x82\n\n/* Initialize OSBDM device */\n#define OSBDM_CMD_INIT 0x11\n/* Execute special, not-BDM command. But only this\n * command is used for JTAG operation */\n#define OSBDM_CMD_SPECIAL 0x27\n/* Execute JTAG swap (tms/tdi -> tdo) */\n#define OSBDM_CMD_SPECIAL_SWAP 0x05\n/* Reset control */\n#define OSBDM_CMD_SPECIAL_SRST 0x01\n/* Maximum bit-length in one swap */\n#define OSBDM_SWAP_MAX (((OSBDM_USB_BUFSIZE - 6) / 5) * 16)\n\n/* Lists of valid VID/PID pairs\n */\nstatic const uint16_t osbdm_vid[] = { 0x15a2, 0x15a2, 0x15a2, 0 };\nstatic const uint16_t osbdm_pid[] = { 0x0042, 0x0058, 0x005e, 0 };\n\nstruct osbdm {\n\tstruct libusb_device_handle *devh; /* USB handle */\n\tuint8_t buffer[OSBDM_USB_BUFSIZE]; /* Data to send and receive */\n\tint count; /* Count data to send and to read */\n};\n\n/* osbdm instance\n */\nstatic struct osbdm osbdm_context;\n\nstatic int osbdm_send_and_recv(struct osbdm *osbdm)\n{\n\t/* Send request */\n\tint count, ret;\n\n\tret = jtag_libusb_bulk_write(osbdm->devh, OSBDM_USB_EP_WRITE,\n\t\t\t\t     (char *)osbdm->buffer, osbdm->count,\n\t\t\t\t     OSBDM_USB_TIMEOUT, &count);\n\tif (ret || count != osbdm->count) {\n\t\tLOG_ERROR(\"OSBDM communication error: can't write\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Save command code for next checking */\n\tuint8_t cmd_saved = osbdm->buffer[0];\n\n\t/* Reading answer */\n\tret = jtag_libusb_bulk_read(osbdm->devh, OSBDM_USB_EP_READ,\n\t\t\t\t    (char *)osbdm->buffer, OSBDM_USB_BUFSIZE,\n\t\t\t\t    OSBDM_USB_TIMEOUT, &osbdm->count);\n\t/* Now perform basic checks for data sent by BDM device\n\t */\n\tif (ret) {\n\t\tLOG_ERROR(\"OSBDM communication error: can't read\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (osbdm->count < 2) {\n\t\tLOG_ERROR(\"OSBDM communication error: reply too small\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (osbdm->count != osbdm->buffer[1])  {\n\t\tLOG_ERROR(\"OSBDM communication error: reply size mismatch\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (cmd_saved != osbdm->buffer[0]) {\n\t\tLOG_ERROR(\"OSBDM communication error: reply command mismatch\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_srst(struct osbdm *osbdm, int srst)\n{\n\tosbdm->count = 0;\n\t(void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);\n\n\t/* Composing request\n\t */\n\tosbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */\n\tosbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SRST; /* Subcommand */\n\t/* Length in bytes - not used */\n\tosbdm->buffer[osbdm->count++] = 0;\n\tosbdm->buffer[osbdm->count++] = 0;\n\t/* SRST state */\n\tosbdm->buffer[osbdm->count++] = (srst ? 0 : 0x08);\n\n\t/* Sending data\n\t */\n\tif (osbdm_send_and_recv(osbdm) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_swap(struct osbdm *osbdm, void *tms, void *tdi,\n\tvoid *tdo, int length)\n{\n\tif (length > OSBDM_SWAP_MAX) {\n\t\tLOG_ERROR(\"BUG: bit sequence too long\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (length <= 0) {\n\t\tLOG_ERROR(\"BUG: bit sequence equal or less than 0\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint swap_count = DIV_ROUND_UP(length, 16);\n\n\t/* cleanup */\n\tosbdm->count = 0;\n\t(void)memset(osbdm->buffer, 0, OSBDM_USB_BUFSIZE);\n\n\t/* Composing request\n\t */\n\n\tosbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL; /* Command */\n\tosbdm->buffer[osbdm->count++] = OSBDM_CMD_SPECIAL_SWAP; /* Subcommand */\n\t/* Length in bytes - not used */\n\tosbdm->buffer[osbdm->count++] = 0;\n\tosbdm->buffer[osbdm->count++] = 0;\n\t/* Swap count */\n\tosbdm->buffer[osbdm->count++] = 0;\n\tosbdm->buffer[osbdm->count++] = (uint8_t)swap_count;\n\n\tfor (int bit_idx = 0; bit_idx < length; ) {\n\t\t/* Bit count in swap */\n\t\tint bit_count = length - bit_idx;\n\t\tif (bit_count > 16)\n\t\t\tbit_count = 16;\n\n\t\tosbdm->buffer[osbdm->count++] = (uint8_t)bit_count;\n\n\t\t/* Copying TMS and TDI data to output buffer */\n\t\tuint32_t tms_data = buf_get_u32(tms, bit_idx, bit_count);\n\t\tuint32_t tdi_data = buf_get_u32(tdi, bit_idx, bit_count);\n\t\tosbdm->buffer[osbdm->count++] = (uint8_t)(tdi_data >> 8);\n\t\tosbdm->buffer[osbdm->count++] = (uint8_t)tdi_data;\n\t\tosbdm->buffer[osbdm->count++] = (uint8_t)(tms_data >> 8);\n\t\tosbdm->buffer[osbdm->count++] = (uint8_t)tms_data;\n\n\t\t/* Next bit offset */\n\t\tbit_idx += bit_count;\n\t}\n\n\tassert(osbdm->count <= OSBDM_USB_BUFSIZE);\n\n\t/* Sending data\n\t */\n\tif (osbdm_send_and_recv(osbdm) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/*\tExtra check\n\t */\n\tif (((osbdm->buffer[2] << 8) | osbdm->buffer[3]) != 2 * swap_count) {\n\t\tLOG_ERROR(\"OSBDM communication error: invalid swap command reply\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Copy TDO response\n\t */\n\tuint8_t *buffer = osbdm->buffer + 4;\n\tfor (int bit_idx = 0; bit_idx < length; ) {\n\t\tint bit_count = length - bit_idx;\n\t\tif (bit_count > 16)\n\t\t\tbit_count = 16;\n\n\t\t/* Prepare data */\n\t\tuint32_t tdo_data = 0;\n\t\ttdo_data |= (*buffer++) << 8;\n\t\ttdo_data |= (*buffer++);\n\t\ttdo_data >>= (16 - bit_count);\n\n\t\t/* Copy TDO to return */\n\t\tbuf_set_u32(tdo, bit_idx, bit_count, tdo_data);\n\n\t\tbit_idx += bit_count;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_flush(struct osbdm *osbdm, struct queue *queue)\n{\n\tuint8_t tms[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];\n\tuint8_t tdi[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];\n\tuint8_t tdo[DIV_ROUND_UP(OSBDM_SWAP_MAX, 8)];\n\n\tint seq_back_len = 0;\n\n\twhile (queue->head) {\n\t\t(void)memset(tms, 0, sizeof(tms));\n\t\t(void)memset(tdi, 0, sizeof(tdi));\n\t\t(void)memset(tdo, 0, sizeof(tdo));\n\n\t\tint seq_len;\n\t\tint swap_len;\n\t\tstruct sequence *seq;\n\n\t\t/* Copy from queue to tms/tdi streams\n\t\t */\n\t\tseq = queue->head;\n\t\tseq_len = seq_back_len;\n\t\tswap_len = 0;\n\n\t\twhile (seq && swap_len != OSBDM_SWAP_MAX) {\n\t\t\t/* Count bit for copy at this iteration.\n\t\t\t * len should fit into remaining space\n\t\t\t * in tms/tdo bitstreams\n\t\t\t */\n\t\t\tint len = seq->len - seq_len;\n\t\t\tif (len > OSBDM_SWAP_MAX - swap_len)\n\t\t\t\tlen = OSBDM_SWAP_MAX - swap_len;\n\n\t\t\t/* Set tms data */\n\t\t\tbuf_set_buf(seq->tms, seq_len, tms, swap_len, len);\n\n\t\t\t/* Set tdi data if they exists */\n\t\t\tif (seq->tdi)\n\t\t\t\tbuf_set_buf(seq->tdi, seq_len, tdi, swap_len, len);\n\n\t\t\tswap_len += len;\n\t\t\tseq_len += len;\n\t\t\tif (seq_len == seq->len) {\n\t\t\t\tseq = seq->next; /* Move to next sequence */\n\t\t\t\tseq_len = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (osbdm_swap(osbdm, tms, tdi, tdo, swap_len))\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Copy from tdo stream to queue\n\t\t */\n\n\t\tfor (int swap_back_len = 0; swap_back_len < swap_len; ) {\n\t\t\tint len = queue->head->len - seq_back_len;\n\t\t\tif (len > swap_len - swap_back_len)\n\t\t\t\tlen = swap_len - swap_back_len;\n\n\t\t\tif (queue->head->tdo)\n\t\t\t\tbuf_set_buf(tdo, swap_back_len,\tqueue->head->tdo, seq_back_len, len);\n\n\t\t\tswap_back_len += len;\n\t\t\tseq_back_len += len;\n\t\t\tif (seq_back_len == queue->head->len) {\n\t\t\t\tqueue_drop_head(queue);\n\t\t\t\tseq_back_len = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\tBasic operation for opening USB device */\nstatic int osbdm_open(struct osbdm *osbdm)\n{\n\t(void)memset(osbdm, 0, sizeof(*osbdm));\n\tif (jtag_libusb_open(osbdm_vid, osbdm_pid, &osbdm->devh, NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (libusb_claim_interface(osbdm->devh, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_quit(void)\n{\n\tjtag_libusb_close(osbdm_context.devh);\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_pathmove(\n\tstruct queue *queue,\n\ttap_state_t *path,\n\tint num_states)\n{\n\tassert(num_states <= 32);\n\n\tstruct sequence *next = queue_add_tail(queue, num_states);\n\tif (!next) {\n\t\tLOG_ERROR(\"BUG: can't allocate bit sequence\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t tms = 0;\n\tfor (int i = 0; i < num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), 1) == path[i]) {\n\t\t\ttms |= (1 << i);\n\t\t} else if (tap_state_transition(tap_get_state(), 0) == path[i]) {\n\t\t\ttms &= ~(1 << i); /* This line not so needed */\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP state transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(path[i]));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\tbuf_set_u32(next->tms, 0, num_states, tms);\n\ttap_set_end_state(tap_get_state());\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_statemove(\n\tstruct queue *queue,\n\ttap_state_t new_state,\n\tint skip_first)\n{\n\tint len = 0;\n\tint tms = 0;\n\n\ttap_set_end_state(new_state);\n\tif (tap_get_end_state() == TAP_RESET) {\n\t\t/* Ignore current state */\n\t\ttms = 0xff;\n\t\tlen = 5;\n\t} else if (tap_get_state() != tap_get_end_state()) {\n\t\ttms = tap_get_tms_path(tap_get_state(), new_state);\n\t\tlen = tap_get_tms_path_len(tap_get_state(), new_state);\n\t}\n\n\tif (len && skip_first) {\n\t\tlen--;\n\t\ttms >>= 1;\n\t}\n\n\tif (len) {\n\t\tstruct sequence *next = queue_add_tail(queue, len);\n\t\tif (!next) {\n\t\t\tLOG_ERROR(\"BUG: can't allocate bit sequence\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbuf_set_u32(next->tms, 0, len, tms);\n\t}\n\n\ttap_set_state(tap_get_end_state());\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_stableclocks(\n\tstruct queue *queue,\n\tint count)\n{\n\tif (!tap_is_state_stable(tap_get_state())) {\n\t\tLOG_ERROR(\"BUG: current state (%s) is not stable\",\n\t\t\ttap_state_name(tap_get_state()));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct sequence *next = queue_add_tail(queue, count);\n\tif (!next) {\n\t\tLOG_ERROR(\"BUG: can't allocate bit sequence\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (tap_get_state() == TAP_RESET)\n\t\t(void)memset(next->tms, 0xff, DIV_ROUND_UP(count, 8));\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_tms(\n\tstruct queue *queue,\n\tconst uint8_t *tms,\n\tint num_bits)\n{\n\tstruct sequence *next = queue_add_tail(queue, num_bits);\n\tif (!next) {\n\t\tLOG_ERROR(\"BUG: can't allocate bit sequence\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbuf_set_buf(tms, 0, next->tms, 0, num_bits);\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_scan(\n\tstruct queue *queue,\n\tstruct scan_field *fields,\n\tint num_fields,\n\ttap_state_t end_state,\n\tbool ir_scan)\n{\n\t/* Move to desired shift state */\n\tif (ir_scan) {\n\t\tif (tap_get_state() != TAP_IRSHIFT) {\n\t\t\tif (osbdm_add_statemove(queue, TAP_IRSHIFT, 0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tif (tap_get_state() != TAP_DRSHIFT) {\n\t\t\tif (osbdm_add_statemove(queue, TAP_DRSHIFT, 0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* Add scan */\n\ttap_set_end_state(end_state);\n\tfor (int idx = 0; idx < num_fields; idx++) {\n\t\tstruct sequence *next = queue_add_tail(queue, fields[idx].num_bits);\n\t\tif (!next) {\n\t\t\tLOG_ERROR(\"Can't allocate bit sequence\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t(void)memset(next->tms, 0, DIV_ROUND_UP(fields[idx].num_bits, 8));\n\t\tnext->tdi = fields[idx].out_value;\n\t\tnext->tdo = fields[idx].in_value;\n\t}\n\n\t/* Move to end state\n\t */\n\tif (tap_get_state() != tap_get_end_state()) {\n\t\t/* Exit from IRSHIFT/DRSHIFT */\n\t\tbuf_set_u32(queue->tail->tms, queue->tail->len - 1, 1, 1);\n\n\t\t/* Move with skip_first flag */\n\t\tif (osbdm_add_statemove(queue, tap_get_end_state(), 1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_add_runtest(\n\tstruct queue *queue,\n\tint num_cycles,\n\ttap_state_t end_state)\n{\n\tif (osbdm_add_statemove(queue, TAP_IDLE, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (osbdm_add_stableclocks(queue, num_cycles) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (osbdm_add_statemove(queue, end_state, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int osbdm_execute_command(\n\tstruct osbdm *osbdm,\n\tstruct queue *queue,\n\tstruct jtag_command *cmd)\n{\n\tint retval = ERROR_OK;\n\n\tswitch (cmd->type) {\n\tcase JTAG_RESET:\n\t\tif (cmd->cmd.reset->trst) {\n\t\t\tLOG_ERROR(\"BUG: nTRST signal is not supported\");\n\t\t\tretval = ERROR_FAIL;\n\t\t} else {\n\t\t\tretval = osbdm_flush(osbdm, queue);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tretval = osbdm_srst(osbdm, cmd->cmd.reset->srst);\n\t\t}\n\t\tbreak;\n\n\tcase JTAG_PATHMOVE:\n\t\tretval = osbdm_add_pathmove(\n\t\t\tqueue,\n\t\t\tcmd->cmd.pathmove->path,\n\t\t\tcmd->cmd.pathmove->num_states);\n\t\tbreak;\n\n\tcase JTAG_TLR_RESET:\n\t\tretval = osbdm_add_statemove(\n\t\t\tqueue,\n\t\t\tcmd->cmd.statemove->end_state,\n\t\t\t0);\n\t\tbreak;\n\n\tcase JTAG_STABLECLOCKS:\n\t\tretval = osbdm_add_stableclocks(\n\t\t\tqueue,\n\t\t\tcmd->cmd.stableclocks->num_cycles);\n\t\tbreak;\n\n\tcase JTAG_TMS:\n\t\tretval = osbdm_add_tms(\n\t\t\tqueue,\n\t\t\tcmd->cmd.tms->bits,\n\t\t\tcmd->cmd.tms->num_bits);\n\t\tbreak;\n\n\tcase JTAG_SCAN:\n\t\tretval = osbdm_add_scan(\n\t\t\tqueue,\n\t\t\tcmd->cmd.scan->fields,\n\t\t\tcmd->cmd.scan->num_fields,\n\t\t\tcmd->cmd.scan->end_state,\n\t\t\tcmd->cmd.scan->ir_scan);\n\t\tbreak;\n\n\tcase JTAG_SLEEP:\n\t\tretval = osbdm_flush(osbdm, queue);\n\t\tif (retval == ERROR_OK)\n\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\tbreak;\n\n\tcase JTAG_RUNTEST:\n\t\tretval = osbdm_add_runtest(\n\t\t\tqueue,\n\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\tcmd->cmd.runtest->end_state);\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int osbdm_execute_queue(void)\n{\n\tint retval = ERROR_OK;\n\n\tstruct queue *queue = queue_alloc();\n\tif (!queue) {\n\t\tLOG_ERROR(\"BUG: can't allocate bit queue\");\n\t\tretval = ERROR_FAIL;\n\t} else {\n\t\tstruct jtag_command *cmd = jtag_command_queue;\n\n\t\twhile (retval == ERROR_OK && cmd) {\n\t\t\tretval = osbdm_execute_command(&osbdm_context, queue, cmd);\n\t\t\tcmd = cmd->next;\n\t\t}\n\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = osbdm_flush(&osbdm_context, queue);\n\n\t\tqueue_free(queue);\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"FATAL: can't execute jtag command\");\n\t\texit(-1);\n\t}\n\n\treturn retval;\n}\n\nstatic int osbdm_init(void)\n{\n\t/* Open device */\n\tif (osbdm_open(&osbdm_context) != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't open OSBDM device\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\t/* Device successfully opened */\n\t\tLOG_DEBUG(\"OSBDM init\");\n\t}\n\n\t/* Perform initialize command */\n\tosbdm_context.count = 0;\n\tosbdm_context.buffer[osbdm_context.count++] = OSBDM_CMD_INIT;\n\tif (osbdm_send_and_recv(&osbdm_context) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic struct jtag_interface osbdm_interface = {\n\t.execute_queue = osbdm_execute_queue,\n};\n\nstruct adapter_driver osbdm_adapter_driver = {\n\t.name = \"osbdm\",\n\t.transports = jtag_only,\n\n\t.init = osbdm_init,\n\t.quit = osbdm_quit,\n\n\t.jtag_ops = &osbdm_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/parport.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include \"bitbang.h\"\n\n/* -ino: 060521-1036 */\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n#include <machine/sysarch.h>\n#include <machine/cpufunc.h>\n#define ioperm(startport, length, enable)\\\n\ti386_set_ioperm((startport), (length), (enable))\n#endif /* __FreeBSD__ */\n\n#if PARPORT_USE_PPDEV == 1\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n#include <dev/ppbus/ppi.h>\n#include <dev/ppbus/ppbconf.h>\n#define PPRSTATUS\tPPIGSTATUS\n#define PPWDATA\t\tPPISDATA\n#else\n#include <linux/parport.h>\n#include <linux/ppdev.h>\n#endif\n#include <sys/ioctl.h>\n#else /* not PARPORT_USE_PPDEV */\n#ifndef _WIN32\n#include <sys/io.h>\n#endif\n#endif\n\n#if PARPORT_USE_GIVEIO == 1 && IS_CYGWIN == 1\n#include <windows.h>\n#endif\n\n/* parallel port cable description\n */\nstruct cable {\n\tconst char *name;\n\tuint8_t TDO_MASK;\t/* status port bit containing current TDO value */\n\tuint8_t TRST_MASK;\t/* data port bit for TRST */\n\tuint8_t TMS_MASK;\t/* data port bit for TMS */\n\tuint8_t TCK_MASK;\t/* data port bit for TCK */\n\tuint8_t TDI_MASK;\t/* data port bit for TDI */\n\tuint8_t SRST_MASK;\t/* data port bit for SRST */\n\tuint8_t OUTPUT_INVERT;\t/* data port bits that should be inverted */\n\tuint8_t INPUT_INVERT;\t/* status port that should be inverted */\n\tuint8_t PORT_INIT;\t/* initialize data port with this value */\n\tuint8_t PORT_EXIT;\t/* de-initialize data port with this value */\n\tuint8_t LED_MASK;\t/* data port bit for LED */\n};\n\nstatic const struct cable cables[] = {\n\t/* name\t\t\t\ttdo   trst  tms   tck   tdi   srst  o_inv i_inv init  exit  led */\n\t{ \"wiggler\",\t\t\t0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x80, 0x00 },\n\t{ \"wiggler2\",\t\t\t0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x01, 0x80, 0x80, 0x00, 0x20 },\n\t{ \"wiggler_ntrst_inverted\",\t0x80, 0x10, 0x02, 0x04, 0x08, 0x01, 0x11, 0x80, 0x80, 0x80, 0x00 },\n\t{ \"old_amt_wiggler\",\t\t0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x11, 0x80, 0x80, 0x80, 0x00 },\n\t{ \"arm-jtag\",\t\t\t0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x01, 0x80, 0x80, 0x80, 0x00 },\n\t{ \"chameleon\",\t\t\t0x80, 0x00, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },\n\t{ \"dlc5\",\t\t\t\t0x10, 0x00, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00 },\n\t{ \"triton\",\t\t\t\t0x80, 0x08, 0x04, 0x01, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 },\n\t{ \"lattice\",\t\t\t0x40, 0x10, 0x04, 0x02, 0x01, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00 },\n\t{ \"flashlink\",\t\t\t0x20, 0x10, 0x02, 0x01, 0x04, 0x20, 0x30, 0x20, 0x00, 0x00, 0x00 },\n/* Altium Universal JTAG cable. Set the cable to Xilinx Mode and wire to target as follows:\n\tHARD TCK - Target TCK\n\tHARD TMS - Target TMS\n\tHARD TDI - Target TDI\n\tHARD TDO - Target TDO\n\tSOFT TCK - Target TRST\n\tSOFT TDI - Target SRST\n*/\n\t{ \"altium\",\t\t\t0x10, 0x20, 0x04, 0x02, 0x01, 0x80, 0x00, 0x00, 0x10, 0x00, 0x08 },\n\t{ \"aspo\",                       0x10, 0x01, 0x04, 0x08, 0x02, 0x10, 0x17, 0x00, 0x17, 0x17, 0x00 },\n\t{ NULL,\t\t\t\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }\n};\n\n/* configuration */\nstatic char *parport_cable;\nstatic uint16_t parport_port;\nstatic bool parport_exit;\nstatic uint32_t parport_toggling_time_ns = 1000;\nstatic int wait_states;\n\n/* interface variables\n */\nstatic const struct cable *cable;\nstatic uint8_t dataport_value;\n\n#if PARPORT_USE_PPDEV == 1\nstatic int device_handle;\n#else\nstatic unsigned long dataport;\nstatic unsigned long statusport;\n#endif\n\nstatic bb_value_t parport_read(void)\n{\n\tint data = 0;\n\n#if PARPORT_USE_PPDEV == 1\n\tioctl(device_handle, PPRSTATUS, &data);\n#else\n\tdata = inb(statusport);\n#endif\n\n\tif ((data ^ cable->INPUT_INVERT) & cable->TDO_MASK)\n\t\treturn BB_HIGH;\n\telse\n\t\treturn BB_LOW;\n}\n\nstatic inline void parport_write_data(void)\n{\n\tuint8_t output;\n\toutput = dataport_value ^ cable->OUTPUT_INVERT;\n\n#if PARPORT_USE_PPDEV == 1\n\tioctl(device_handle, PPWDATA, &output);\n#else\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\toutb(dataport, output);\n#else\n\toutb(output, dataport);\n#endif\n#endif\n}\n\nstatic int parport_write(int tck, int tms, int tdi)\n{\n\tint i = wait_states + 1;\n\n\tif (tck)\n\t\tdataport_value |= cable->TCK_MASK;\n\telse\n\t\tdataport_value &= ~cable->TCK_MASK;\n\n\tif (tms)\n\t\tdataport_value |= cable->TMS_MASK;\n\telse\n\t\tdataport_value &= ~cable->TMS_MASK;\n\n\tif (tdi)\n\t\tdataport_value |= cable->TDI_MASK;\n\telse\n\t\tdataport_value &= ~cable->TDI_MASK;\n\n\twhile (i-- > 0)\n\t\tparport_write_data();\n\n\treturn ERROR_OK;\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic int parport_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (trst == 0)\n\t\tdataport_value |= cable->TRST_MASK;\n\telse if (trst == 1)\n\t\tdataport_value &= ~cable->TRST_MASK;\n\n\tif (srst == 0)\n\t\tdataport_value |= cable->SRST_MASK;\n\telse if (srst == 1)\n\t\tdataport_value &= ~cable->SRST_MASK;\n\n\tparport_write_data();\n\n\treturn ERROR_OK;\n}\n\n/* turn LED on parport adapter on (1) or off (0) */\nstatic int parport_led(int on)\n{\n\tif (on)\n\t\tdataport_value |= cable->LED_MASK;\n\telse\n\t\tdataport_value &= ~cable->LED_MASK;\n\n\tparport_write_data();\n\n\treturn ERROR_OK;\n}\n\nstatic int parport_speed(int speed)\n{\n\twait_states = speed;\n\treturn ERROR_OK;\n}\n\nstatic int parport_khz(int khz, int *jtag_speed)\n{\n\tif (khz == 0) {\n\t\tLOG_DEBUG(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*jtag_speed = 499999 / (khz * parport_toggling_time_ns);\n\treturn ERROR_OK;\n}\n\nstatic int parport_speed_div(int speed, int *khz)\n{\n\tuint32_t denominator = (speed + 1) * parport_toggling_time_ns;\n\n\t*khz = (499999 + denominator) / denominator;\n\treturn ERROR_OK;\n}\n\n#if PARPORT_USE_GIVEIO == 1\nstatic int parport_get_giveio_access(void)\n{\n\tHANDLE h;\n\tOSVERSIONINFO version;\n\n\tversion.dwOSVersionInfoSize = sizeof(version);\n\tif (!GetVersionEx(&version)) {\n\t\terrno = EINVAL;\n\t\treturn -1;\n\t}\n\tif (version.dwPlatformId != VER_PLATFORM_WIN32_NT)\n\t\treturn 0;\n\n\th = CreateFile(\"\\\\\\\\.\\\\giveio\", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);\n\tif (h == INVALID_HANDLE_VALUE) {\n\t\terrno = ENODEV;\n\t\treturn -1;\n\t}\n\n\tCloseHandle(h);\n\n\treturn 0;\n}\n#endif\n\nstatic struct bitbang_interface parport_bitbang = {\n\t\t.read = &parport_read,\n\t\t.write = &parport_write,\n\t\t.blink = &parport_led,\n\t};\n\nstatic int parport_init(void)\n{\n\tconst struct cable *cur_cable;\n#if PARPORT_USE_PPDEV == 1\n\tchar buffer[256];\n#endif\n\n\tcur_cable = cables;\n\n\tif (!parport_cable) {\n\t\tparport_cable = strdup(\"wiggler\");\n\t\tLOG_WARNING(\"No parport cable specified, using default 'wiggler'\");\n\t}\n\n\twhile (cur_cable->name) {\n\t\tif (strcmp(cur_cable->name, parport_cable) == 0) {\n\t\t\tcable = cur_cable;\n\t\t\tbreak;\n\t\t}\n\t\tcur_cable++;\n\t}\n\n\tif (!cable) {\n\t\tLOG_ERROR(\"No matching cable found for %s\", parport_cable);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tdataport_value = cable->PORT_INIT;\n\n#if PARPORT_USE_PPDEV == 1\n\tif (device_handle > 0) {\n\t\tLOG_ERROR(\"device is already opened\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\tLOG_DEBUG(\"opening /dev/ppi%d...\", parport_port);\n\n\tsnprintf(buffer, 256, \"/dev/ppi%d\", parport_port);\n\tdevice_handle = open(buffer, O_WRONLY);\n#else /* not __FreeBSD__, __FreeBSD_kernel__ */\n\tLOG_DEBUG(\"opening /dev/parport%d...\", parport_port);\n\n\tsnprintf(buffer, 256, \"/dev/parport%d\", parport_port);\n\tdevice_handle = open(buffer, O_WRONLY);\n#endif /* __FreeBSD__, __FreeBSD_kernel__ */\n\n\tif (device_handle < 0) {\n\t\tint err = errno;\n\t\tLOG_ERROR(\"cannot open device. check it exists and that user read and write rights are set. errno=%d\", err);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_DEBUG(\"...open\");\n\n#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)\n\tint i = ioctl(device_handle, PPCLAIM);\n\n\tif (i < 0) {\n\t\tLOG_ERROR(\"cannot claim device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ti = PARPORT_MODE_COMPAT;\n\ti = ioctl(device_handle, PPSETMODE, &i);\n\tif (i < 0) {\n\t\tLOG_ERROR(\" cannot set compatible mode to device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\ti = IEEE1284_MODE_COMPAT;\n\ti = ioctl(device_handle, PPNEGOT, &i);\n\tif (i < 0) {\n\t\tLOG_ERROR(\"cannot set compatible 1284 mode to device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n#endif /* not __FreeBSD__, __FreeBSD_kernel__ */\n\n#else /* not PARPORT_USE_PPDEV */\n\tif (parport_port == 0) {\n\t\tparport_port = 0x378;\n\t\tLOG_WARNING(\"No parport port specified, using default '0x378' (LPT1)\");\n\t}\n\n\tdataport = parport_port;\n\tstatusport = parport_port + 1;\n\n\tLOG_DEBUG(\"requesting privileges for parallel port 0x%lx...\", dataport);\n#if PARPORT_USE_GIVEIO == 1\n\tif (parport_get_giveio_access() != 0) {\n#else /* PARPORT_USE_GIVEIO */\n\tif (ioperm(dataport, 3, 1) != 0) {\n#endif /* PARPORT_USE_GIVEIO */\n\t\tLOG_ERROR(\"missing privileges for direct i/o\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tLOG_DEBUG(\"...privileges granted\");\n\n\t/* make sure parallel port is in right mode (clear tristate and interrupt */\n\t#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)\n\t\toutb(parport_port + 2, 0x0);\n\t#else\n\t\toutb(0x0, parport_port + 2);\n\t#endif\n\n#endif /* PARPORT_USE_PPDEV */\n\n\tif (parport_reset(0, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (parport_write(0, 0, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (parport_led(1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tbitbang_interface = &parport_bitbang;\n\n\treturn ERROR_OK;\n}\n\nstatic int parport_quit(void)\n{\n\tif (parport_led(0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (parport_exit) {\n\t\tdataport_value = cable->PORT_EXIT;\n\t\tparport_write_data();\n\t}\n\n\tfree(parport_cable);\n\tparport_cable = NULL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(parport_handle_parport_port_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\t/* only if the port wasn't overwritten by cmdline */\n\t\tif (parport_port == 0)\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], parport_port);\n\t\telse {\n\t\t\tLOG_ERROR(\"The parport port was already configured!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"parport port = 0x%\" PRIx16 \"\", parport_port);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(parport_handle_parport_cable_command)\n{\n\tif (CMD_ARGC == 0)\n\t\treturn ERROR_OK;\n\n\t/* only if the cable name wasn't overwritten by cmdline */\n\tif (!parport_cable) {\n\t\t/* REVISIT first verify that it's listed in cables[] ... */\n\t\tparport_cable = malloc(strlen(CMD_ARGV[0]) + sizeof(char));\n\t\tif (!parport_cable) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tstrcpy(parport_cable, CMD_ARGV[0]);\n\t}\n\n\t/* REVISIT it's probably worth returning the current value ... */\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(parport_handle_write_on_exit_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], parport_exit);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(parport_handle_parport_toggling_time_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tuint32_t ns;\n\t\tint retval = parse_u32(CMD_ARGV[0], &ns);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (ns == 0) {\n\t\t\tLOG_ERROR(\"0 ns is not a valid parport toggling time\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tparport_toggling_time_ns = ns;\n\t\tretval = adapter_get_speed(&wait_states);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* if adapter_get_speed fails then the clock_mode\n\t\t\t * has not been configured, this happens if parport_toggling_time is\n\t\t\t * called before the adapter speed is set */\n\t\t\tLOG_INFO(\"no parport speed set - defaulting to zero wait states\");\n\t\t\twait_states = 0;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"parport toggling time = %\" PRIu32 \" ns\",\n\t\t\tparport_toggling_time_ns);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration parport_subcommand_handlers[] = {\n\t{\n\t\t.name = \"port\",\n\t\t.handler = parport_handle_parport_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Display the address of the I/O port (e.g. 0x378) \"\n\t\t\t\"or the number of the '/dev/parport' device used.  \"\n\t\t\t\"If a parameter is provided, first change that port.\",\n\t\t.usage = \"[port_number]\",\n\t},\n\t{\n\t\t.name = \"cable\",\n\t\t.handler = parport_handle_parport_cable_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set the layout of the parallel port cable \"\n\t\t\t\"used to connect to the target.\",\n\t\t/* REVISIT there's no way to list layouts we know ... */\n\t\t.usage = \"[layout]\",\n\t},\n\t{\n\t\t.name = \"write_on_exit\",\n\t\t.handler = parport_handle_write_on_exit_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure the parallel driver to write \"\n\t\t\t\"a known value to the parallel interface on exit.\",\n\t\t.usage = \"('on'|'off')\",\n\t},\n\t{\n\t\t.name = \"toggling_time\",\n\t\t.handler = parport_handle_parport_toggling_time_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Displays or assigns how many nanoseconds it \"\n\t\t\t\"takes for the hardware to toggle TCK.\",\n\t\t.usage = \"[nanoseconds]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration parport_command_handlers[] = {\n\t{\n\t\t.name = \"parport\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform parport management\",\n\t\t.chain = parport_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface parport_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver parport_adapter_driver = {\n\t.name = \"parport\",\n\t.transports = jtag_only,\n\t.commands = parport_command_handlers,\n\n\t.init = parport_init,\n\t.quit = parport_quit,\n\t.reset = parport_reset,\n\t.speed = parport_speed,\n\t.khz = parport_khz,\n\t.speed_div = parport_speed_div,\n\n\t.jtag_ops = &parport_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/presto.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Pavel Chromy                                    *\n *   chromy@asix.cz                                                        *\n ***************************************************************************/\n\n/**\n * @file\n * Holds driver for PRESTO programmer from ASIX.\n * http://tools.asix.net/prg_presto.htm\n */\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if IS_CYGWIN == 1\n#include \"windows.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <helper/time_support.h>\n#include \"bitq.h\"\n\n/* PRESTO access library includes */\n#include \"libftdi_helper.h\"\n\n/* -------------------------------------------------------------------------- */\n\n#define FT_DEVICE_NAME_LEN 64\n#define FT_DEVICE_SERNUM_LEN 64\n\n#define PRESTO_VID_PID 0x0403f1a0\n#define PRESTO_VID (0x0403)\n#define PRESTO_PID (0xf1a0)\n\n#define BUFFER_SIZE (64*62)\n\nstruct presto {\n\tstruct ftdi_context ftdic;\n\tint retval;\n\n\tchar serial[FT_DEVICE_SERNUM_LEN];\n\n\tuint8_t buff_out[BUFFER_SIZE];\n\tint buff_out_pos;\n\n\tuint8_t buff_in[BUFFER_SIZE];\n\tint buff_in_exp;/* expected in buffer length */\n\tint buff_in_len;/* length of data received */\n\tint buff_in_pos;\n\n\tunsigned long total_out;\n\tunsigned long total_in;\n\n\tint jtag_tms;\t/* last tms state */\n\tint jtag_tck;\t/* last tck state */\n\tint jtag_rst;\t/* last trst state */\n\n\tint jtag_tdi_data;\n\tint jtag_tdi_count;\n\n\tint jtag_speed;\n};\n\nstatic struct presto presto_state;\nstatic struct presto *presto = &presto_state;\n\nstatic uint8_t presto_init_seq[] = {\n\t0x80, 0xA0, 0xA8, 0xB0, 0xC0, 0xE0\n};\n\nstatic int presto_write(uint8_t *buf, uint32_t size)\n{\n\tuint32_t ftbytes;\n\tpresto->retval = ftdi_write_data(&presto->ftdic, buf, size);\n\tif (presto->retval < 0) {\n\t\tLOG_ERROR(\"ftdi_write_data: %s\", ftdi_get_error_string(&presto->ftdic));\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\tftbytes = presto->retval;\n\n\tif (ftbytes != size) {\n\t\tLOG_ERROR(\"couldn't write the requested number of bytes to PRESTO (%u < %u)\",\n\t\t\t(unsigned)ftbytes, (unsigned)size);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int presto_read(uint8_t *buf, uint32_t size)\n{\n\tuint32_t ftbytes = 0;\n\n\tstruct timeval timeout, now;\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, 1, 0);\t/* one second timeout */\n\n\twhile (ftbytes < size) {\n\t\tpresto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes);\n\t\tif (presto->retval < 0) {\n\t\t\tLOG_ERROR(\"ftdi_read_data: %s\", ftdi_get_error_string(&presto->ftdic));\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\tftbytes += presto->retval;\n\n\t\tgettimeofday(&now, NULL);\n\t\tif (timeval_compare(&now, &timeout) > 0)\n\t\t\tbreak;\n\t}\n\n\tif (ftbytes != size) {\n\t\t/* this is just a warning, there might have been timeout when detecting PRESTO,\n\t\t *which is not fatal */\n\t\tLOG_WARNING(\"couldn't read the requested number of bytes from PRESTO (%u < %u)\",\n\t\t\t(unsigned)ftbytes, (unsigned)size);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int presto_open_libftdi(const char *req_serial)\n{\n\tuint8_t presto_data;\n\n\tLOG_DEBUG(\"searching for PRESTO using libftdi\");\n\n\t/* initialize FTDI context structure */\n\tif (ftdi_init(&presto->ftdic) < 0) {\n\t\tLOG_ERROR(\"unable to init libftdi: %s\", presto->ftdic.error_str);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t/* context, vendor id, product id */\n\tif (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) {\n\t\tLOG_ERROR(\"unable to open PRESTO: %s\", presto->ftdic.error_str);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (ftdi_usb_reset(&presto->ftdic) < 0) {\n\t\tLOG_ERROR(\"unable to reset PRESTO device\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) {\n\t\tLOG_ERROR(\"unable to set latency timer\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (ftdi_tcioflush(&presto->ftdic) < 0) {\n\t\tLOG_ERROR(\"unable to flush PRESTO buffers\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tpresto_data = 0xD0;\n\tif (presto_write(&presto_data, 1) != ERROR_OK) {\n\t\tLOG_ERROR(\"error writing to PRESTO\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (presto_read(&presto_data, 1) != ERROR_OK) {\n\t\tLOG_DEBUG(\"no response from PRESTO, retrying\");\n\n\t\tif (ftdi_tcioflush(&presto->ftdic) < 0)\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\n\t\tpresto_data = 0xD0;\n\t\tif (presto_write(&presto_data, 1) != ERROR_OK)\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\n\t\tif (presto_read(&presto_data, 1) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"no response from PRESTO, giving up\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t}\n\n\tif (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) {\n\t\tLOG_ERROR(\"error writing PRESTO init sequence\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int presto_open(const char *req_serial)\n{\n\tpresto->buff_out_pos = 0;\n\tpresto->buff_in_pos = 0;\n\tpresto->buff_in_len = 0;\n\tpresto->buff_in_exp = 0;\n\n\tpresto->total_out = 0;\n\tpresto->total_in = 0;\n\n\tpresto->jtag_tms = 0;\n\tpresto->jtag_tck = 0;\n\tpresto->jtag_rst = 0;\n\tpresto->jtag_tdi_data = 0;\n\tpresto->jtag_tdi_count = 0;\n\n\tpresto->jtag_speed = 0;\n\n\treturn presto_open_libftdi(req_serial);\n}\n\nstatic int presto_close(void)\n{\n\n\tint result = ERROR_OK;\n\n\tpresto->retval = ftdi_write_data(&presto->ftdic, presto_init_seq, sizeof(presto_init_seq));\n\tif (presto->retval != sizeof(presto_init_seq))\n\t\tresult = ERROR_JTAG_DEVICE_ERROR;\n\n\tpresto->retval = ftdi_set_latency_timer(&presto->ftdic, 16);\n\tif (presto->retval < 0)\n\t\tresult = ERROR_JTAG_DEVICE_ERROR;\n\n\tpresto->retval = ftdi_usb_close(&presto->ftdic);\n\tif (presto->retval < 0)\n\t\tresult = ERROR_JTAG_DEVICE_ERROR;\n\telse\n\t\tftdi_deinit(&presto->ftdic);\n\n\treturn result;\n}\n\nstatic int presto_flush(void)\n{\n\tif (presto->buff_out_pos == 0)\n\t\treturn ERROR_OK;\n\n\tif (presto->retval < 0) {\n\t\tLOG_DEBUG(\"error in previous communication, canceling I/O operation\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) {\n\t\tpresto->buff_out_pos = 0;\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tpresto->total_out += presto->buff_out_pos;\n\tpresto->buff_out_pos = 0;\n\n\tif (presto->buff_in_exp == 0)\n\t\treturn ERROR_OK;\n\n\tpresto->buff_in_pos = 0;\n\tpresto->buff_in_len = 0;\n\n\tif (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) {\n\t\tpresto->buff_in_exp = 0;\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tpresto->total_in += presto->buff_in_exp;\n\tpresto->buff_in_len = presto->buff_in_exp;\n\tpresto->buff_in_exp = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int presto_sendbyte(int data)\n{\n\tif (data == EOF)\n\t\treturn presto_flush();\n\n\tif (presto->buff_out_pos < BUFFER_SIZE) {\n\t\tpresto->buff_out[presto->buff_out_pos++] = (uint8_t)data;\n\t\tif (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0))\n\t\t\tpresto->buff_in_exp++;\n\t} else\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\n\t/* libftdi does not do background read, be sure that USB IN buffer does not overflow (128\n\t *bytes only!) */\n\tif (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)\n\t\treturn presto_flush();\n\n\treturn ERROR_OK;\n}\n\n#if 0\nstatic int presto_getbyte(void)\n{\n\tif (presto->buff_in_pos < presto->buff_in_len)\n\t\treturn presto->buff_in[presto->buff_in_pos++];\n\n\tif (presto->buff_in_exp == 0)\n\t\treturn -1;\n\n\tif (presto_flush() != ERROR_OK)\n\t\treturn -1;\n\n\tif (presto->buff_in_pos < presto->buff_in_len)\n\t\treturn presto->buff_in[presto->buff_in_pos++];\n\n\treturn -1;\n}\n#endif\n\n/* -------------------------------------------------------------------------- */\n\nstatic int presto_tdi_flush(void)\n{\n\tif (presto->jtag_tdi_count == 0)\n\t\treturn 0;\n\n\tif (presto->jtag_tck == 0) {\n\t\tLOG_ERROR(\"BUG: unexpected TAP condition, TCK low\");\n\t\treturn -1;\n\t}\n\n\tpresto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;\n\tpresto_sendbyte(presto->jtag_tdi_data);\n\tpresto->jtag_tdi_count = 0;\n\tpresto->jtag_tdi_data = 0;\n\n\treturn 0;\n}\n\nstatic int presto_tck_idle(void)\n{\n\tif (presto->jtag_tck == 1) {\n\t\tpresto_sendbyte(0xCA);\n\t\tpresto->jtag_tck = 0;\n\t}\n\n\treturn 0;\n}\n\n/* -------------------------------------------------------------------------- */\n\nstatic int presto_bitq_out(int tms, int tdi, int tdo_req)\n{\n\tint i;\n\tunsigned char cmd;\n\n\tif (presto->jtag_tck == 0)\n\t\tpresto_sendbyte(0xA4);\t/* LED indicator - JTAG active */\n\telse if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) {\n\t\tpresto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;\n\n\t\tif (++presto->jtag_tdi_count == 4)\n\t\t\tpresto_tdi_flush();\n\n\t\treturn 0;\n\t}\n\n\tpresto_tdi_flush();\n\n\tcmd = tdi ? 0xCB : 0xCA;\n\tpresto_sendbyte(cmd);\n\n\tif (tms != presto->jtag_tms) {\n\t\tpresto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));\n\t\tpresto->jtag_tms = tms;\n\t}\n\n\t/* delay with TCK low */\n\tfor (i = presto->jtag_speed; i > 1; i--)\n\t\tpresto_sendbyte(cmd);\n\n\tcmd |= 0x04;\n\tpresto_sendbyte(cmd | (tdo_req ? 0x10 : 0));\n\n\t/* delay with TCK high */\n\tfor (i = presto->jtag_speed; i > 1; i--)\n\t\tpresto_sendbyte(cmd);\n\n\tpresto->jtag_tck = 1;\n\n\treturn 0;\n}\n\nstatic int presto_bitq_flush(void)\n{\n\tpresto_tdi_flush();\n\tpresto_tck_idle();\n\n\tpresto_sendbyte(0xA0);\t/* LED indicator - JTAG idle */\n\n\treturn presto_flush();\n}\n\nstatic int presto_bitq_in_rdy(void)\n{\n\tif (presto->buff_in_pos >= presto->buff_in_len)\n\t\treturn 0;\n\treturn presto->buff_in_len-presto->buff_in_pos;\n}\n\nstatic int presto_bitq_in(void)\n{\n\tif (presto->buff_in_pos >= presto->buff_in_len)\n\t\treturn -1;\n\tif (presto->buff_in[presto->buff_in_pos++]&0x08)\n\t\treturn 1;\n\treturn 0;\n}\n\nstatic int presto_bitq_sleep(unsigned long us)\n{\n\tlong waits;\n\n\tpresto_tdi_flush();\n\tpresto_tck_idle();\n\n\tif (us > 100000) {\n\t\tpresto_bitq_flush();\n\t\tjtag_sleep(us);\n\t\treturn 0;\n\t}\n\n\twaits = us / 170 + 2;\n\twhile (waits--)\n\t\tpresto_sendbyte(0x80);\n\n\treturn 0;\n}\n\nstatic int presto_bitq_reset(int trst, int srst)\n{\n\tpresto_tdi_flush();\n\tpresto_tck_idle();\n\n\t/* add a delay after possible TCK transition */\n\tpresto_sendbyte(0x80);\n\tpresto_sendbyte(0x80);\n\n\tpresto->jtag_rst = trst || srst;\n\tpresto_sendbyte((presto->jtag_rst ? 0xEA : 0xE8) | (presto->jtag_tms ? 0x04 : 0));\n\n\treturn 0;\n}\n\nstatic struct bitq_interface presto_bitq = {\n\t.out = &presto_bitq_out,\n\t.flush = &presto_bitq_flush,\n\t.sleep = &presto_bitq_sleep,\n\t.reset = &presto_bitq_reset,\n\t.in_rdy = &presto_bitq_in_rdy,\n\t.in = &presto_bitq_in,\n};\n\n/* -------------------------------------------------------------------------- */\n\nstatic int presto_adapter_khz(int khz, int *jtag_speed)\n{\n\tif (khz < 0) {\n\t\t*jtag_speed = 0;\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (khz >= 3000)\n\t\t*jtag_speed = 0;\n\telse\n\t\t*jtag_speed = (1000 + khz-1)/khz;\n\n\treturn 0;\n}\n\nstatic int presto_jtag_speed_div(int speed, int *khz)\n{\n\tif ((speed < 0) || (speed > 1000)) {\n\t\t*khz = 0;\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (speed == 0)\n\t\t*khz = 3000;\n\telse\n\t\t*khz = 1000/speed;\n\n\treturn 0;\n}\n\nstatic int presto_jtag_speed(int speed)\n{\n\tint khz;\n\n\tif (presto_jtag_speed_div(speed, &khz))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tpresto->jtag_speed = speed;\n\n\tif (khz%1000 == 0)\n\t\tLOG_INFO(\"setting speed to %d, max. TCK freq. is %d MHz\", speed, khz/1000);\n\telse\n\t\tLOG_INFO(\"setting speed to %d, max. TCK freq. is %d kHz\", speed, khz);\n\n\treturn 0;\n}\n\nstatic int presto_jtag_init(void)\n{\n\tconst char *presto_serial = adapter_get_required_serial();\n\n\tif (presto_open(presto_serial) != ERROR_OK) {\n\t\tpresto_close();\n\t\tif (presto_serial)\n\t\t\tLOG_ERROR(\"Cannot open PRESTO, serial number '%s'\", presto_serial);\n\t\telse\n\t\t\tLOG_ERROR(\"Cannot open PRESTO\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tLOG_INFO(\"PRESTO open, serial number '%s'\", presto->serial);\n\n\tbitq_interface = &presto_bitq;\n\treturn ERROR_OK;\n}\n\nstatic int presto_jtag_quit(void)\n{\n\tbitq_cleanup();\n\tpresto_close();\n\tLOG_INFO(\"PRESTO closed\");\n\treturn ERROR_OK;\n}\n\nstatic struct jtag_interface presto_interface = {\n\t.execute_queue = bitq_execute_queue,\n};\n\nstruct adapter_driver presto_adapter_driver = {\n\t.name = \"presto\",\n\t.transports = jtag_only,\n\n\t.init = presto_jtag_init,\n\t.quit = presto_jtag_quit,\n\t.speed = presto_jtag_speed,\n\t.khz = presto_adapter_khz,\n\t.speed_div = presto_jtag_speed_div,\n\n\t.jtag_ops = &presto_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/remote_bitbang.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Richard Uhler                                   *\n *   ruhler@mit.edu                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifndef _WIN32\n#include <sys/un.h>\n#include <netdb.h>\n#include <netinet/tcp.h>\n#endif\n#include \"helper/system.h\"\n#include \"helper/replacements.h\"\n#include <jtag/interface.h>\n#include \"bitbang.h\"\n\n/* arbitrary limit on host name length: */\n#define REMOTE_BITBANG_HOST_MAX 255\n\nstatic char *remote_bitbang_host;\nstatic char *remote_bitbang_port;\n\nstatic int remote_bitbang_fd;\nstatic uint8_t remote_bitbang_send_buf[512];\nstatic unsigned int remote_bitbang_send_buf_used;\n\n/* Circular buffer. When start == end, the buffer is empty. */\nstatic char remote_bitbang_recv_buf[256];\nstatic unsigned int remote_bitbang_recv_buf_start;\nstatic unsigned int remote_bitbang_recv_buf_end;\n\nstatic bool remote_bitbang_recv_buf_full(void)\n{\n\treturn remote_bitbang_recv_buf_end ==\n\t\t((remote_bitbang_recv_buf_start + sizeof(remote_bitbang_recv_buf) - 1) %\n\t\t sizeof(remote_bitbang_recv_buf));\n}\n\nstatic bool remote_bitbang_recv_buf_empty(void)\n{\n\treturn remote_bitbang_recv_buf_start == remote_bitbang_recv_buf_end;\n}\n\nstatic unsigned int remote_bitbang_recv_buf_contiguous_available_space(void)\n{\n\tif (remote_bitbang_recv_buf_end >= remote_bitbang_recv_buf_start) {\n\t\tunsigned int space = sizeof(remote_bitbang_recv_buf) -\n\t\t\t\t     remote_bitbang_recv_buf_end;\n\t\tif (remote_bitbang_recv_buf_start == 0)\n\t\t\tspace -= 1;\n\t\treturn space;\n\t} else {\n\t\treturn remote_bitbang_recv_buf_start -\n\t\t       remote_bitbang_recv_buf_end - 1;\n\t}\n}\n\nstatic int remote_bitbang_flush(void)\n{\n\tif (remote_bitbang_send_buf_used <= 0)\n\t\treturn ERROR_OK;\n\n\tunsigned int offset = 0;\n\twhile (offset < remote_bitbang_send_buf_used) {\n\t\tssize_t written = write_socket(remote_bitbang_fd, remote_bitbang_send_buf + offset,\n\t\t\t\t\t\t\t\t\t   remote_bitbang_send_buf_used - offset);\n\t\tif (written < 0) {\n\t\t\tlog_socket_error(\"remote_bitbang_putc\");\n\t\t\tremote_bitbang_send_buf_used = 0;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\toffset += written;\n\t}\n\tremote_bitbang_send_buf_used = 0;\n\treturn ERROR_OK;\n}\n\nenum block_bool {\n\tNO_BLOCK,\n\tBLOCK\n};\n\n/* Read any incoming data, placing it into the buffer. */\nstatic int remote_bitbang_fill_buf(enum block_bool block)\n{\n\tif (remote_bitbang_recv_buf_empty()) {\n\t\t/* If the buffer is empty, reset it to 0 so we get more\n\t\t * contiguous space. */\n\t\tremote_bitbang_recv_buf_start = 0;\n\t\tremote_bitbang_recv_buf_end = 0;\n\t}\n\n\tif (block == BLOCK) {\n\t\tif (remote_bitbang_flush() != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tsocket_block(remote_bitbang_fd);\n\t}\n\n\tbool first = true;\n\twhile (!remote_bitbang_recv_buf_full()) {\n\t\tunsigned int contiguous_available_space =\n\t\t\t\tremote_bitbang_recv_buf_contiguous_available_space();\n\t\tssize_t count = read_socket(remote_bitbang_fd,\n\t\t\t\tremote_bitbang_recv_buf + remote_bitbang_recv_buf_end,\n\t\t\t\tcontiguous_available_space);\n\t\tif (first && block == BLOCK)\n\t\t\tsocket_nonblock(remote_bitbang_fd);\n\t\tfirst = false;\n\t\tif (count > 0) {\n\t\t\tremote_bitbang_recv_buf_end += count;\n\t\t\tif (remote_bitbang_recv_buf_end == sizeof(remote_bitbang_recv_buf))\n\t\t\t\tremote_bitbang_recv_buf_end = 0;\n\t\t} else if (count == 0) {\n\t\t\treturn ERROR_OK;\n\t\t} else if (count < 0) {\n#ifdef _WIN32\n\t\t\tif (WSAGetLastError() == WSAEWOULDBLOCK) {\n#else\n\t\t\tif (errno == EAGAIN) {\n#endif\n\t\t\t\treturn ERROR_OK;\n\t\t\t} else {\n\t\t\t\tlog_socket_error(\"remote_bitbang_fill_buf\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\ntypedef enum {\n\tNO_FLUSH,\n\tFLUSH_SEND_BUF\n} flush_bool_t;\n\nstatic int remote_bitbang_queue(int c, flush_bool_t flush)\n{\n\tremote_bitbang_send_buf[remote_bitbang_send_buf_used++] = c;\n\tif (flush == FLUSH_SEND_BUF ||\n\t\t\tremote_bitbang_send_buf_used >= ARRAY_SIZE(remote_bitbang_send_buf))\n\t\treturn remote_bitbang_flush();\n\treturn ERROR_OK;\n}\n\nstatic int remote_bitbang_quit(void)\n{\n\tif (remote_bitbang_queue('Q', FLUSH_SEND_BUF) == ERROR_FAIL)\n\t\treturn ERROR_FAIL;\n\n\tif (close_socket(remote_bitbang_fd) != 0) {\n\t\tlog_socket_error(\"close_socket\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfree(remote_bitbang_host);\n\tfree(remote_bitbang_port);\n\n\tLOG_INFO(\"remote_bitbang interface quit\");\n\treturn ERROR_OK;\n}\n\nstatic bb_value_t char_to_int(int c)\n{\n\tswitch (c) {\n\t\tcase '0':\n\t\t\treturn BB_LOW;\n\t\tcase '1':\n\t\t\treturn BB_HIGH;\n\t\tdefault:\n\t\t\tremote_bitbang_quit();\n\t\t\tLOG_ERROR(\"remote_bitbang: invalid read response: %c(%i)\", c, c);\n\t\t\treturn BB_ERROR;\n\t}\n}\n\nstatic int remote_bitbang_sample(void)\n{\n\tif (remote_bitbang_fill_buf(NO_BLOCK) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tassert(!remote_bitbang_recv_buf_full());\n\treturn remote_bitbang_queue('R', NO_FLUSH);\n}\n\nstatic bb_value_t remote_bitbang_read_sample(void)\n{\n\tif (remote_bitbang_recv_buf_empty()) {\n\t\tif (remote_bitbang_fill_buf(BLOCK) != ERROR_OK)\n\t\t\treturn BB_ERROR;\n\t}\n\tassert(!remote_bitbang_recv_buf_empty());\n\tint c = remote_bitbang_recv_buf[remote_bitbang_recv_buf_start];\n\tremote_bitbang_recv_buf_start =\n\t\t(remote_bitbang_recv_buf_start + 1) % sizeof(remote_bitbang_recv_buf);\n\treturn char_to_int(c);\n}\n\nstatic int remote_bitbang_write(int tck, int tms, int tdi)\n{\n\tchar c = '0' + ((tck ? 0x4 : 0x0) | (tms ? 0x2 : 0x0) | (tdi ? 0x1 : 0x0));\n\treturn remote_bitbang_queue(c, NO_FLUSH);\n}\n\nstatic int remote_bitbang_reset(int trst, int srst)\n{\n\tchar c = 'r' + ((trst ? 0x2 : 0x0) | (srst ? 0x1 : 0x0));\n\t/* Always flush the send buffer on reset, because the reset call need not be\n\t * followed by jtag_execute_queue(). */\n\treturn remote_bitbang_queue(c, FLUSH_SEND_BUF);\n}\n\nstatic int remote_bitbang_blink(int on)\n{\n\tchar c = on ? 'B' : 'b';\n\treturn remote_bitbang_queue(c, FLUSH_SEND_BUF);\n}\n\nstatic struct bitbang_interface remote_bitbang_bitbang = {\n\t.buf_size = sizeof(remote_bitbang_recv_buf) - 1,\n\t.sample = &remote_bitbang_sample,\n\t.read_sample = &remote_bitbang_read_sample,\n\t.write = &remote_bitbang_write,\n\t.blink = &remote_bitbang_blink,\n};\n\nstatic int remote_bitbang_init_tcp(void)\n{\n\tstruct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM };\n\tstruct addrinfo *result, *rp;\n\tint fd = 0;\n\n\tLOG_INFO(\"Connecting to %s:%s\",\n\t\t\tremote_bitbang_host ? remote_bitbang_host : \"localhost\",\n\t\t\tremote_bitbang_port);\n\n\t/* Obtain address(es) matching host/port */\n\tint s = getaddrinfo(remote_bitbang_host, remote_bitbang_port, &hints, &result);\n\tif (s != 0) {\n\t\tLOG_ERROR(\"getaddrinfo: %s\\n\", gai_strerror(s));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* getaddrinfo() returns a list of address structures.\n\t Try each address until we successfully connect(2).\n\t If socket(2) (or connect(2)) fails, we (close the socket\n\t and) try the next address. */\n\n\tfor (rp = result; rp ; rp = rp->ai_next) {\n\t\tfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);\n\t\tif (fd == -1)\n\t\t\tcontinue;\n\n\t\tif (connect(fd, rp->ai_addr, rp->ai_addrlen) != -1)\n\t\t\tbreak; /* Success */\n\n\t\tclose(fd);\n\t}\n\n\t/* We work hard to collapse the writes into the minimum number, so when\n\t * we write something we want to get it to the other end of the\n\t * connection as fast as possible. */\n\tint one = 1;\n\t/* On Windows optval has to be a const char *. */\n\tsetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&one, sizeof(one));\n\n\tfreeaddrinfo(result); /* No longer needed */\n\n\tif (!rp) { /* No address succeeded */\n\t\tlog_socket_error(\"Failed to connect\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn fd;\n}\n\nstatic int remote_bitbang_init_unix(void)\n{\n\tif (!remote_bitbang_host) {\n\t\tLOG_ERROR(\"host/socket not specified\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Connecting to unix socket %s\", remote_bitbang_host);\n\tint fd = socket(PF_UNIX, SOCK_STREAM, 0);\n\tif (fd < 0) {\n\t\tlog_socket_error(\"socket\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct sockaddr_un addr;\n\taddr.sun_family = AF_UNIX;\n\tstrncpy(addr.sun_path, remote_bitbang_host, sizeof(addr.sun_path));\n\taddr.sun_path[sizeof(addr.sun_path)-1] = '\\0';\n\n\tif (connect(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {\n\t\tlog_socket_error(\"connect\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn fd;\n}\n\nstatic int remote_bitbang_init(void)\n{\n\tbitbang_interface = &remote_bitbang_bitbang;\n\n\tremote_bitbang_recv_buf_start = 0;\n\tremote_bitbang_recv_buf_end = 0;\n\n\tLOG_INFO(\"Initializing remote_bitbang driver\");\n\tif (!remote_bitbang_port)\n\t\tremote_bitbang_fd = remote_bitbang_init_unix();\n\telse\n\t\tremote_bitbang_fd = remote_bitbang_init_tcp();\n\n\tif (remote_bitbang_fd < 0)\n\t\treturn remote_bitbang_fd;\n\n\tsocket_nonblock(remote_bitbang_fd);\n\n\tLOG_INFO(\"remote_bitbang driver initialized\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_port_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tuint16_t port;\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);\n\t\tfree(remote_bitbang_port);\n\t\tremote_bitbang_port = port == 0 ? NULL : strdup(CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HANDLER(remote_bitbang_handle_remote_bitbang_host_command)\n{\n\tif (CMD_ARGC == 1) {\n\t\tfree(remote_bitbang_host);\n\t\tremote_bitbang_host = strdup(CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nstatic const struct command_registration remote_bitbang_subcommand_handlers[] = {\n\t{\n\t\t.name = \"port\",\n\t\t.handler = remote_bitbang_handle_remote_bitbang_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set the port to use to connect to the remote jtag.\\n\"\n\t\t\t\"  if 0 or unset, use unix sockets to connect to the remote jtag.\",\n\t\t.usage = \"port_number\",\n\t},\n\t{\n\t\t.name = \"host\",\n\t\t.handler = remote_bitbang_handle_remote_bitbang_host_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set the host to use to connect to the remote jtag.\\n\"\n\t\t\t\"  if port is 0 or unset, this is the name of the unix socket to use.\",\n\t\t.usage = \"host_name\",\n\t},\n\tCOMMAND_REGISTRATION_DONE,\n};\n\nstatic const struct command_registration remote_bitbang_command_handlers[] = {\n\t{\n\t\t.name = \"remote_bitbang\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform remote_bitbang management\",\n\t\t.chain = remote_bitbang_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int remote_bitbang_execute_queue(void)\n{\n\t/* safety: the send buffer must be empty, no leftover characters from\n\t * previous transactions */\n\tassert(remote_bitbang_send_buf_used == 0);\n\n\t/* process the JTAG command queue */\n\tint ret = bitbang_execute_queue();\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* flush not-yet-sent characters, if any */\n\treturn remote_bitbang_flush();\n}\n\nstatic struct jtag_interface remote_bitbang_interface = {\n\t.execute_queue = &remote_bitbang_execute_queue,\n};\n\nstruct adapter_driver remote_bitbang_adapter_driver = {\n\t.name = \"remote_bitbang\",\n\t.transports = jtag_only,\n\t.commands = remote_bitbang_command_handlers,\n\n\t.init = &remote_bitbang_init,\n\t.quit = &remote_bitbang_quit,\n\t.reset = &remote_bitbang_reset,\n\n\t.jtag_ops = &remote_bitbang_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 Rob Brown, Lou Deluxe                              *\n *   rob@cobbleware.com, lou.openocd012@fixit.nospammail.net               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"helper/replacements.h\"\n#include \"rlink.h\"\n#include \"rlink_st7.h\"\n#include \"rlink_ep1_cmd.h\"\n#include \"rlink_dtc_cmd.h\"\n#include \"libusb_helper.h\"\n\n/* This feature is made useless by running the DTC all the time.  When automatic, the LED is on\n *whenever the DTC is running.  Otherwise, USB messages are sent to turn it on and off. */\n#undef AUTOMATIC_BUSY_LED\n\n/* This feature may require derating the speed due to reduced hold time. */\n#undef USE_HARDWARE_SHIFTER_FOR_TMS\n\n#define INTERFACE_NAME          \"RLink\"\n\n#define USB_IDVENDOR            (0x138e)\n#define USB_IDPRODUCT           (0x9000)\n\n#define USB_EP1OUT_ADDR         (0x01)\n#define USB_EP1OUT_SIZE         (16)\n#define USB_EP1IN_ADDR          (USB_EP1OUT_ADDR | 0x80)\n#define USB_EP1IN_SIZE          (USB_EP1OUT_SIZE)\n\n#define USB_EP2OUT_ADDR         (0x02)\n#define USB_EP2OUT_SIZE         (64)\n#define USB_EP2IN_ADDR          (USB_EP2OUT_ADDR | 0x80)\n#define USB_EP2IN_SIZE          (USB_EP2OUT_SIZE)\n#define USB_EP2BANK_SIZE        (512)\n\n#define DTC_STATUS_POLL_BYTE    (ST7_USB_BUF_EP0OUT + 0xff)\n\n#define ST7_PD_NBUSY_LED                ST7_PD0\n#define ST7_PD_NRUN_LED                 ST7_PD1\n/* low enables VPP at adapter header, high connects it to GND instead */\n#define ST7_PD_VPP_SEL                  ST7_PD6\n/* low: VPP = 12v, high: VPP <= 5v */\n#define ST7_PD_VPP_SHDN                 ST7_PD7\n\n/* These pins are connected together */\n#define ST7_PE_ADAPTER_SENSE_IN         ST7_PE3\n#define ST7_PE_ADAPTER_SENSE_OUT        ST7_PE4\n\n/* Symbolic mapping between port pins and numbered IO lines */\n#define ST7_PA_IO1      ST7_PA1\n#define ST7_PA_IO2      ST7_PA2\n#define ST7_PA_IO4      ST7_PA4\n#define ST7_PA_IO8      ST7_PA6\n#define ST7_PA_IO10     ST7_PA7\n#define ST7_PB_IO5      ST7_PB5\n#define ST7_PC_IO9      ST7_PC1\n#define ST7_PC_IO3      ST7_PC2\n#define ST7_PC_IO7      ST7_PC3\n#define ST7_PE_IO6      ST7_PE5\n\n/* Symbolic mapping between numbered IO lines and adapter signals */\n#define ST7_PA_RTCK     ST7_PA_IO0\n#define ST7_PA_NTRST    ST7_PA_IO1\n#define ST7_PC_TDI      ST7_PC_IO3\n#define ST7_PA_DBGRQ    ST7_PA_IO4\n#define ST7_PB_NSRST    ST7_PB_IO5\n#define ST7_PE_TMS      ST7_PE_IO6\n#define ST7_PC_TCK      ST7_PC_IO7\n#define ST7_PC_TDO      ST7_PC_IO9\n#define ST7_PA_DBGACK   ST7_PA_IO10\n\nstatic struct libusb_device_handle *hdev;\n\n/*\n * ep1 commands are up to USB_EP1OUT_SIZE bytes in length.\n * This function takes care of zeroing the unused bytes before sending the packet.\n * Any reply packet is not handled by this function.\n */\nstatic int ep1_generic_commandl(struct libusb_device_handle *hdev_param, size_t length, ...)\n{\n\tuint8_t usb_buffer[USB_EP1OUT_SIZE];\n\tuint8_t *usb_buffer_p;\n\tva_list ap;\n\tint usb_ret;\n\tint transferred;\n\n\tif (length > sizeof(usb_buffer))\n\t\tlength = sizeof(usb_buffer);\n\n\tusb_buffer_p = usb_buffer;\n\n\tva_start(ap, length);\n\twhile (length > 0) {\n\t\t*usb_buffer_p++ = va_arg(ap, int);\n\t\tlength--;\n\t}\n\n\tmemset(\n\t\tusb_buffer_p,\n\t\t0,\n\t\tsizeof(usb_buffer) - (usb_buffer_p - usb_buffer)\n\t\t);\n\n\tusb_ret = jtag_libusb_bulk_write(\n\t\t\thdev_param,\n\t\t\tUSB_EP1OUT_ADDR,\n\t\t\t(char *)usb_buffer, sizeof(usb_buffer),\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\n\tif (usb_ret != ERROR_OK)\n\t\treturn usb_ret;\n\treturn transferred;\n}\n\n#if 0\nstatic ssize_t ep1_memory_read(\n\tstruct libusb_device_handle *hdev_param, uint16_t addr,\n\tsize_t length, uint8_t *buffer)\n{\n\tuint8_t usb_buffer[USB_EP1OUT_SIZE];\n\tint usb_ret;\n\tsize_t remain;\n\tssize_t count;\n\tint transferred;\n\n\tusb_buffer[0] = EP1_CMD_MEMORY_READ;\n\tmemset(\n\t\tusb_buffer + 4,\n\t\t0,\n\t\tsizeof(usb_buffer) - 4\n\t\t);\n\n\tremain = length;\n\tcount = 0;\n\n\twhile (remain) {\n\t\tif (remain > sizeof(usb_buffer))\n\t\t\tlength = sizeof(usb_buffer);\n\t\telse\n\t\t\tlength = remain;\n\n\t\tusb_buffer[1] = addr >> 8;\n\t\tusb_buffer[2] = addr;\n\t\tusb_buffer[3] = length;\n\n\t\tusb_ret = jtag_libusb_bulk_write(\n\t\t\t\thdev_param, USB_EP1OUT_ADDR,\n\t\t\t\t(char *)usb_buffer, sizeof(usb_buffer),\n\t\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t\t&transferred\n\t\t\t\t);\n\n\t\tif (usb_ret != ERROR_OK || transferred < (int)sizeof(usb_buffer))\n\t\t\tbreak;\n\n\t\tusb_ret = jtag_libusb_bulk_read(\n\t\t\t\thdev_param, USB_EP1IN_ADDR,\n\t\t\t\t(char *)buffer, length,\n\t\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t\t&transferred\n\t\t\t\t);\n\n\t\tif (usb_ret != ERROR_OK || transferred < (int)length)\n\t\t\tbreak;\n\n\t\taddr += length;\n\t\tbuffer += length;\n\t\tcount += length;\n\t\tremain -= length;\n\t}\n\n\treturn count;\n}\n#endif\n\nstatic ssize_t ep1_memory_write(struct libusb_device_handle *hdev_param, uint16_t addr,\n\tsize_t length, uint8_t const *buffer)\n{\n\tuint8_t usb_buffer[USB_EP1OUT_SIZE];\n\tint usb_ret;\n\tsize_t remain;\n\tssize_t count;\n\n\tusb_buffer[0] = EP1_CMD_MEMORY_WRITE;\n\n\tremain = length;\n\tcount = 0;\n\n\twhile (remain) {\n\t\tif (remain > (sizeof(usb_buffer) - 4))\n\t\t\tlength = (sizeof(usb_buffer) - 4);\n\t\telse\n\t\t\tlength = remain;\n\n\t\tusb_buffer[1] = addr >> 8;\n\t\tusb_buffer[2] = addr;\n\t\tusb_buffer[3] = length;\n\t\tmemcpy(\n\t\t\tusb_buffer + 4,\n\t\t\tbuffer,\n\t\t\tlength\n\t\t\t);\n\t\tmemset(\n\t\t\tusb_buffer + 4 + length,\n\t\t\t0,\n\t\t\tsizeof(usb_buffer) - 4 - length\n\t\t\t);\n\n\t\tint transferred;\n\n\t\tusb_ret = jtag_libusb_bulk_write(\n\t\t\t\thdev_param, USB_EP1OUT_ADDR,\n\t\t\t\t(char *)usb_buffer, sizeof(usb_buffer),\n\t\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t\t&transferred\n\t\t\t\t);\n\n\t\tif (usb_ret != ERROR_OK || transferred < (int)sizeof(usb_buffer))\n\t\t\tbreak;\n\n\t\taddr += length;\n\t\tbuffer += length;\n\t\tcount += length;\n\t\tremain -= length;\n\t}\n\n\treturn count;\n}\n\n\n#if 0\nstatic ssize_t ep1_memory_writel(struct libusb_device_handle *hdev_param, uint16_t addr,\n\tsize_t length, ...)\n{\n\tuint8_t buffer[USB_EP1OUT_SIZE - 4];\n\tuint8_t *buffer_p;\n\tva_list ap;\n\tsize_t remain;\n\n\tif (length > sizeof(buffer))\n\t\tlength = sizeof(buffer);\n\n\tremain = length;\n\tbuffer_p = buffer;\n\n\tva_start(ap, length);\n\twhile (remain > 0) {\n\t\t*buffer_p++ = va_arg(ap, int);\n\t\tremain--;\n\t}\n\n\treturn ep1_memory_write(hdev_param, addr, length, buffer);\n}\n#endif\n\n#define DTCLOAD_COMMENT         (0)\n#define DTCLOAD_ENTRY           (1)\n#define DTCLOAD_LOAD            (2)\n#define DTCLOAD_RUN                     (3)\n#define DTCLOAD_LUT_START       (4)\n#define DTCLOAD_LUT                     (5)\n\n#define DTC_LOAD_BUFFER         ST7_USB_BUF_EP2UIDO\n\n/* This gets set by the DTC loader */\nstatic uint8_t dtc_entry_download;\n\n/* The buffer is specially formatted to represent a valid image to load into the DTC. */\nstatic int dtc_load_from_buffer(struct libusb_device_handle *hdev_param, const uint8_t *buffer,\n\t\tsize_t length)\n{\n\tstruct header_s {\n\t\tuint8_t type;\n\t\tuint8_t length;\n\t};\n\n\tint usb_err;\n\tstruct header_s *header;\n\tuint8_t lut_start = 0xc0;\n\n\tdtc_entry_download = 0;\n\n\t/* Stop the DTC before loading anything. */\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev_param, 1,\n\t\t\tEP1_CMD_DTC_STOP\n\t\t\t);\n\tif (usb_err < 0)\n\t\treturn usb_err;\n\n\twhile (length) {\n\t\tif (length < sizeof(*header)) {\n\t\t\tLOG_ERROR(\"Malformed DTC image\");\n\t\t\texit(1);\n\t\t}\n\n\t\theader = (struct header_s *)buffer;\n\t\tbuffer += sizeof(*header);\n\t\tlength -= sizeof(*header);\n\n\t\tif (length < (size_t)header->length + 1) {\n\t\t\tLOG_ERROR(\"Malformed DTC image\");\n\t\t\texit(1);\n\t\t}\n\n\t\tswitch (header->type) {\n\t\t\tcase DTCLOAD_COMMENT:\n\t\t\t\tbreak;\n\n\t\t\tcase DTCLOAD_ENTRY:\n\t\t\t\t/* store entry addresses somewhere */\n\t\t\t\tif (!strncmp(\"download\", (char *)buffer + 1, 8))\n\t\t\t\t\tdtc_entry_download = buffer[0];\n\t\t\t\tbreak;\n\n\t\t\tcase DTCLOAD_LOAD:\n\t\t\t\t/* Send the DTC program to ST7 RAM. */\n\t\t\t\tusb_err = ep1_memory_write(\n\t\t\t\t\t\thdev_param,\n\t\t\t\t\t\tDTC_LOAD_BUFFER,\n\t\t\t\t\t\theader->length + 1, buffer\n\t\t\t\t\t);\n\t\t\t\tif (usb_err < 0)\n\t\t\t\t\treturn usb_err;\n\n\t\t\t\t/* Load it into the DTC. */\n\t\t\t\tusb_err = ep1_generic_commandl(\n\t\t\t\t\t\thdev_param, 3,\n\t\t\t\t\t\tEP1_CMD_DTC_LOAD,\n\t\t\t\t\t\t(DTC_LOAD_BUFFER >> 8),\n\t\t\t\t\t\tDTC_LOAD_BUFFER\n\t\t\t\t\t);\n\t\t\t\tif (usb_err < 0)\n\t\t\t\t\treturn usb_err;\n\n\t\t\t\tbreak;\n\n\t\t\tcase DTCLOAD_RUN:\n\t\t\t\tusb_err = ep1_generic_commandl(\n\t\t\t\t\t\thdev_param, 3,\n\t\t\t\t\t\tEP1_CMD_DTC_CALL,\n\t\t\t\t\t\tbuffer[0],\n\t\t\t\t\t\tEP1_CMD_DTC_WAIT\n\t\t\t\t\t);\n\t\t\t\tif (usb_err < 0)\n\t\t\t\t\treturn usb_err;\n\n\t\t\t\tbreak;\n\n\t\t\tcase DTCLOAD_LUT_START:\n\t\t\t\tlut_start = buffer[0];\n\t\t\t\tbreak;\n\n\t\t\tcase DTCLOAD_LUT:\n\t\t\t\tusb_err = ep1_memory_write(\n\t\t\t\t\t\thdev_param,\n\t\t\t\t\t\tST7_USB_BUF_EP0OUT + lut_start,\n\t\t\t\t\t\theader->length + 1, buffer\n\t\t\t\t\t);\n\t\t\t\tif (usb_err < 0)\n\t\t\t\t\treturn usb_err;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Invalid DTC image record type: 0x%02x\", header->type);\n\t\t\t\texit(1);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbuffer += (header->length + 1);\n\t\tlength -= (header->length + 1);\n\t}\n\n\treturn 0;\n}\n\n/*\n * Start the DTC running in download mode (waiting for 512 byte command packets on ep2).\n */\nstatic int dtc_start_download(void)\n{\n\tint usb_err;\n\tuint8_t ep2txr;\n\tint transferred;\n\n\t/* set up for download mode and make sure EP2 is set up to transmit */\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev, 7,\n\n\t\t\tEP1_CMD_DTC_STOP,\n\t\t\tEP1_CMD_SET_UPLOAD,\n\t\t\tEP1_CMD_SET_DOWNLOAD,\n\t\t\tEP1_CMD_MEMORY_READ,\t/* read EP2TXR for its data toggle */\n\t\t\tST7_EP2TXR >> 8,\n\t\t\tST7_EP2TXR,\n\t\t\t1\n\t\t\t);\n\tif (usb_err < 0)\n\t\treturn usb_err;\n\n\t/* read back ep2txr */\n\tusb_err = jtag_libusb_bulk_read(\n\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t(char *)&ep2txr, 1,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\tif (usb_err != ERROR_OK)\n\t\treturn usb_err;\n\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev, 13,\n\n\t\t\tEP1_CMD_MEMORY_WRITE,\t/* preinitialize poll byte */\n\t\t\tDTC_STATUS_POLL_BYTE >> 8,\n\t\t\tDTC_STATUS_POLL_BYTE,\n\t\t\t1,\n\t\t\t0x00,\n\t\t\tEP1_CMD_MEMORY_WRITE,\t/* set EP2IN to return data */\n\t\t\tST7_EP2TXR >> 8,\n\t\t\tST7_EP2TXR,\n\t\t\t1,\n\t\t\t(ep2txr & ST7_EP2TXR_DTOG_TX) | ST7_EP2TXR_STAT_VALID,\n\t\t\tEP1_CMD_DTC_CALL,\t/* start running the DTC */\n\t\t\tdtc_entry_download,\n\t\t\tEP1_CMD_DTC_GET_CACHED_STATUS\n\t\t\t);\n\tif (usb_err < 0)\n\t\treturn usb_err;\n\n\t/* wait for completion */\n\tusb_err = jtag_libusb_bulk_read(\n\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t(char *)&ep2txr, 1,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\n\treturn usb_err;\n}\n\nstatic int dtc_run_download(\n\tstruct libusb_device_handle *hdev_param,\n\tuint8_t *command_buffer,\n\tint command_buffer_size,\n\tuint8_t *reply_buffer,\n\tint reply_buffer_size\n\t)\n{\n\tchar dtc_status;\n\tint usb_err;\n\tint i;\n\tint transferred;\n\n\tLOG_DEBUG(\"%d/%d\", command_buffer_size, reply_buffer_size);\n\n\tusb_err = jtag_libusb_bulk_write(\n\t\t\thdev_param,\n\t\t\tUSB_EP2OUT_ADDR,\n\t\t\t(char *)command_buffer, USB_EP2BANK_SIZE,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\tif (usb_err < 0)\n\t\treturn usb_err;\n\n\n\t/* Wait for DTC to finish running command buffer */\n\tfor (i = 50;; ) {\n\t\tusb_err = ep1_generic_commandl(\n\t\t\t\thdev_param, 4,\n\n\t\t\t\tEP1_CMD_MEMORY_READ,\n\t\t\t\tDTC_STATUS_POLL_BYTE >> 8,\n\t\t\t\tDTC_STATUS_POLL_BYTE,\n\t\t\t\t1\n\t\t\t\t);\n\t\tif (usb_err < 0)\n\t\t\treturn usb_err;\n\n\t\tusb_err = jtag_libusb_bulk_read(\n\t\t\t\thdev_param,\n\t\t\t\tUSB_EP1IN_ADDR,\n\t\t\t\t&dtc_status, 1,\n\t\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t\t&transferred\n\t\t\t\t);\n\t\tif (usb_err < 0)\n\t\t\treturn usb_err;\n\n\t\tif (dtc_status & 0x01)\n\t\t\tbreak;\n\n\t\tif (!--i) {\n\t\t\tLOG_ERROR(\"too many retries waiting for DTC status\");\n\t\t\treturn LIBUSB_ERROR_TIMEOUT;\n\t\t}\n\t}\n\n\n\tif (reply_buffer && reply_buffer_size) {\n\t\tusb_err = jtag_libusb_bulk_read(\n\t\t\t\thdev_param,\n\t\t\t\tUSB_EP2IN_ADDR,\n\t\t\t\t(char *)reply_buffer, reply_buffer_size,\n\t\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t\t&transferred\n\t\t\t\t);\n\n\t\tif (usb_err != ERROR_OK || transferred < reply_buffer_size) {\n\t\t\tLOG_ERROR(\"Read of endpoint 2 returned %d, expected %d\",\n\t\t\t\tusb_err, reply_buffer_size\n\t\t\t\t);\n\t\t\treturn usb_err;\n\t\t}\n\t}\n\n\treturn usb_err;\n}\n\n/*\n * The dtc reply queue is a singly linked list that describes what to do\n * with the reply packet that comes from the DTC.  Only SCAN_IN and SCAN_IO generate\n * these entries.\n */\n\nstruct dtc_reply_queue_entry {\n\tstruct dtc_reply_queue_entry *next;\n\tstruct jtag_command *cmd;\t/* the command that resulted in this entry */\n\n\tstruct {\n\t\tuint8_t *buffer;\t\t/* the scan buffer */\n\t\tint size;\t\t\t/* size of the scan buffer in bits */\n\t\tint offset;\t\t\t/* how many bits were already done before this? */\n\t\tint length;\t\t\t/* how many bits are processed in this operation? */\n\t\tenum scan_type type;\t\t/* SCAN_IN/SCAN_OUT/SCAN_IO */\n\t} scan;\n};\n\n\n/*\n * The dtc_queue consists of a buffer of pending commands and a reply queue.\n * rlink_scan and tap_state_run add to the command buffer and maybe to the reply queue.\n */\n\nstatic struct {\n\tstruct dtc_reply_queue_entry *rq_head;\n\tstruct dtc_reply_queue_entry *rq_tail;\n\tuint32_t cmd_index;\n\tuint32_t reply_index;\n\tuint8_t cmd_buffer[USB_EP2BANK_SIZE];\n} dtc_queue;\n\n/*\n * The tap state queue is for accumulating TAP state changes without needlessly\n * flushing the dtc_queue.  When it fills or is run, it adds the accumulated bytes to\n * the dtc_queue.\n */\n\nstatic struct {\n\tuint32_t length;\n\tuint32_t buffer;\n} tap_state_queue;\n\nstatic int dtc_queue_init(void)\n{\n\tdtc_queue.rq_head = NULL;\n\tdtc_queue.rq_tail = NULL;\n\tdtc_queue.cmd_index = 0;\n\tdtc_queue.reply_index = 0;\n\treturn 0;\n}\n\nstatic inline struct dtc_reply_queue_entry *dtc_queue_enqueue_reply(\n\tenum scan_type type, uint8_t *buffer, int size, int offset,\n\tint length, struct jtag_command *cmd)\n{\n\tstruct dtc_reply_queue_entry *rq_entry;\n\n\trq_entry = malloc(sizeof(struct dtc_reply_queue_entry));\n\tif (rq_entry) {\n\t\trq_entry->scan.type = type;\n\t\trq_entry->scan.buffer = buffer;\n\t\trq_entry->scan.size = size;\n\t\trq_entry->scan.offset = offset;\n\t\trq_entry->scan.length = length;\n\t\trq_entry->cmd = cmd;\n\t\trq_entry->next = NULL;\n\n\t\tif (!dtc_queue.rq_head)\n\t\t\tdtc_queue.rq_head = rq_entry;\n\t\telse\n\t\t\tdtc_queue.rq_tail->next = rq_entry;\n\n\t\tdtc_queue.rq_tail = rq_entry;\n\t}\n\n\treturn rq_entry;\n}\n\n/*\n * Running the queue means that any pending command buffer is run\n * and any reply data dealt with.  The command buffer is then cleared for subsequent processing.\n * The queue is automatically run by append when it is necessary to get space for the append.\n */\n\nstatic int dtc_queue_run(void)\n{\n\tstruct dtc_reply_queue_entry *rq_p, *rq_next;\n\tint retval;\n\tint usb_err;\n\tint bit_cnt;\n\tint x;\n\tuint8_t *dtc_p, *tdo_p;\n\tuint8_t dtc_mask, tdo_mask;\n\tuint8_t reply_buffer[USB_EP2IN_SIZE];\n\n\tassert((!!dtc_queue.rq_head) == (dtc_queue.reply_index > 0));\n\tassert(dtc_queue.cmd_index < USB_EP2BANK_SIZE);\n\tassert(dtc_queue.reply_index <= USB_EP2IN_SIZE);\n\n\tretval = ERROR_OK;\n\n\tif (dtc_queue.cmd_index < 1)\n\t\treturn retval;\n\n\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] = DTC_CMD_STOP;\n\n\tusb_err = dtc_run_download(hdev,\n\t\t\tdtc_queue.cmd_buffer, dtc_queue.cmd_index,\n\t\t\treply_buffer, sizeof(reply_buffer)\n\t\t\t);\n\tif (usb_err < 0) {\n\t\tLOG_ERROR(\"dtc_run_download: %s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tif (dtc_queue.rq_head) {\n\t\t/* process the reply, which empties the reply queue and frees its entries */\n\t\tdtc_p = reply_buffer;\n\n\t\t/* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the\n\t\t *scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons.   It\n\t\t *was that or craft a function to do the reversal, and that wouldn't work with\n\t\t *bit-stuffing (supplying extra bits to use mostly byte operations), or any other\n\t\t *scheme which would throw the byte alignment off. */\n\n\t\tfor (\n\t\t\trq_p = dtc_queue.rq_head;\n\t\t\trq_p;\n\t\t\trq_p = rq_next\n\t\t\t) {\n\t\t\ttdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8);\n\t\t\ttdo_mask = 1 << (rq_p->scan.offset % 8);\n\n\n\t\t\tbit_cnt = rq_p->scan.length;\n\t\t\tif (bit_cnt >= 8) {\n\t\t\t\t/* bytes */\n\n\t\t\t\tdtc_mask = 1 << (8 - 1);\n\n\t\t\t\tfor (\n\t\t\t\t\t;\n\t\t\t\t\tbit_cnt;\n\t\t\t\t\tbit_cnt--\n\t\t\t\t\t) {\n\t\t\t\t\tif (*dtc_p & dtc_mask)\n\t\t\t\t\t\t*tdo_p |= tdo_mask;\n\t\t\t\t\telse\n\t\t\t\t\t\t*tdo_p &= ~tdo_mask;\n\n\t\t\t\t\tdtc_mask >>= 1;\n\t\t\t\t\tif (dtc_mask == 0) {\n\t\t\t\t\t\tdtc_p++;\n\t\t\t\t\t\tdtc_mask = 1 << (8 - 1);\n\t\t\t\t\t}\n\n\t\t\t\t\ttdo_mask <<= 1;\n\t\t\t\t\tif (tdo_mask == 0) {\n\t\t\t\t\t\ttdo_p++;\n\t\t\t\t\t\ttdo_mask = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/*  extra bits or last bit */\n\n\t\t\t\tx = *dtc_p++;\n\t\t\t\tif ((rq_p->scan.type == SCAN_IN) && (\n\t\t\t\t\t\trq_p->scan.offset != rq_p->scan.size - 1\n\t\t\t\t\t)) {\n\t\t\t\t\t/* extra bits were sent as a full byte with padding on the\n\t\t\t\t\t *end */\n\t\t\t\t\tdtc_mask = 1 << (8 - 1);\n\t\t\t\t} else\n\t\t\t\t\tdtc_mask = 1 << (bit_cnt - 1);\n\n\t\t\t\tfor (\n\t\t\t\t\t;\n\t\t\t\t\tbit_cnt;\n\t\t\t\t\tbit_cnt--\n\t\t\t\t\t) {\n\t\t\t\t\tif (x & dtc_mask)\n\t\t\t\t\t\t*tdo_p |= tdo_mask;\n\t\t\t\t\telse\n\t\t\t\t\t\t*tdo_p &= ~tdo_mask;\n\n\t\t\t\t\tdtc_mask >>= 1;\n\n\t\t\t\t\ttdo_mask <<= 1;\n\t\t\t\t\tif (tdo_mask == 0) {\n\t\t\t\t\t\ttdo_p++;\n\t\t\t\t\t\ttdo_mask = 1;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) {\n\t\t\t\t/* feed scan buffer back into openocd and free it */\n\t\t\t\tif (jtag_read_buffer(rq_p->scan.buffer,\n\t\t\t\t\t\trq_p->cmd->cmd.scan) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\tfree(rq_p->scan.buffer);\n\t\t\t}\n\n\t\t\trq_next = rq_p->next;\n\t\t\tfree(rq_p);\n\t\t}\n\t\tdtc_queue.rq_head = NULL;\n\t\tdtc_queue.rq_tail = NULL;\n\t}\n\n\t/* reset state for new appends */\n\tdtc_queue.cmd_index = 0;\n\tdtc_queue.reply_index = 0;\n\n\treturn retval;\n}\n\n/* runs the queue if it cannot take reserved_cmd bytes of command data\n * or reserved_reply bytes of reply data */\nstatic int dtc_queue_run_if_full(int reserved_cmd, int reserved_reply)\n{\n\t/* reserve one additional byte for the STOP cmd appended during run */\n\tif (dtc_queue.cmd_index + reserved_cmd + 1 > USB_EP2BANK_SIZE)\n\t\treturn dtc_queue_run();\n\n\tif (dtc_queue.reply_index + reserved_reply > USB_EP2IN_SIZE)\n\t\treturn dtc_queue_run();\n\n\treturn ERROR_OK;\n}\n\nstatic int tap_state_queue_init(void)\n{\n\ttap_state_queue.length = 0;\n\ttap_state_queue.buffer = 0;\n\treturn 0;\n}\n\nstatic int tap_state_queue_run(void)\n{\n\tint i;\n\tint bits;\n\tuint8_t byte_param;\n\tint retval;\n\n\tretval = 0;\n\tif (!tap_state_queue.length)\n\t\treturn retval;\n\tbits = 1;\n\tbyte_param = 0;\n\tfor (i = tap_state_queue.length; i--; ) {\n\n\t\tbyte_param <<= 1;\n\t\tif (tap_state_queue.buffer & 1)\n\t\t\tbyte_param |= 1;\n\t\tif ((bits >= 8) || !i) {\n\t\t\tbyte_param <<= (8 - bits);\n\n\t\t\t/* make sure there's room for two cmd bytes */\n\t\t\tdtc_queue_run_if_full(2, 0);\n\n#ifdef USE_HARDWARE_SHIFTER_FOR_TMS\n\t\t\tif (bits == 8) {\n\t\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\t\t\tDTC_CMD_SHIFT_TMS_BYTES(1);\n\t\t\t} else {\n#endif\n\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\t\tDTC_CMD_SHIFT_TMS_BITS(bits);\n#ifdef USE_HARDWARE_SHIFTER_FOR_TMS\n\t\t}\n#endif\n\n\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\t\tbyte_param;\n\n\t\t\tbyte_param = 0;\n\t\t\tbits = 1;\n\t\t} else\n\t\t\tbits++;\n\n\t\ttap_state_queue.buffer >>= 1;\n\t}\n\tretval = tap_state_queue_init();\n\treturn retval;\n}\n\nstatic int tap_state_queue_append(uint8_t tms)\n{\n\tint retval;\n\n\tif (tap_state_queue.length >= sizeof(tap_state_queue.buffer) * 8) {\n\t\tretval = tap_state_queue_run();\n\t\tif (retval != 0)\n\t\t\treturn retval;\n\t}\n\n\tif (tms)\n\t\ttap_state_queue.buffer |= (1 << tap_state_queue.length);\n\ttap_state_queue.length++;\n\n\treturn 0;\n}\n\nstatic void rlink_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void rlink_state_move(void)\n{\n\n\tint i = 0, tms = 0;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tfor (i = 0; i < tms_count; i++) {\n\t\ttms = (tms_scan >> i) & 1;\n\t\ttap_state_queue_append(tms);\n\t}\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void rlink_path_move(struct pathmove_command *cmd)\n{\n\tint num_states = cmd->num_states;\n\tint state_count;\n\tint tms = 0;\n\n\tstate_count = 0;\n\twhile (num_states) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[state_count])\n\t\t\ttms = 0;\n\t\telse if (tap_state_transition(tap_get_state(), true) == cmd->path[state_count])\n\t\t\ttms = 1;\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(cmd->path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_state_queue_append(tms);\n\n\t\ttap_set_state(cmd->path[state_count]);\n\t\tstate_count++;\n\t\tnum_states--;\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void rlink_runtest(int num_cycles)\n{\n\tint i;\n\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\t/* only do a state_move when we're not already in RTI */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\trlink_end_state(TAP_IDLE);\n\t\trlink_state_move();\n\t}\n\n\t/* execute num_cycles */\n\tfor (i = 0; i < num_cycles; i++)\n\t\ttap_state_queue_append(0);\n\n\t/* finish in end_state */\n\trlink_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\trlink_state_move();\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic void rlink_reset(int trst, int srst)\n{\n\tuint8_t bitmap;\n\tint usb_err;\n\tint transferred;\n\n\t/* Read port A for bit op */\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev, 4,\n\t\t\tEP1_CMD_MEMORY_READ,\n\t\t\tST7_PADR >> 8,\n\t\t\tST7_PADR,\n\t\t\t1\n\t\t\t);\n\tif (usb_err < 0) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tusb_err = jtag_libusb_bulk_read(\n\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t(char *)&bitmap, 1,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\tif (usb_err != ERROR_OK || transferred < 1) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tif (trst)\n\t\tbitmap &= ~ST7_PA_NTRST;\n\telse\n\t\tbitmap |= ST7_PA_NTRST;\n\n\t/* Write port A and read port B for bit op\n\t * port B has no OR, and we want to emulate open drain on NSRST, so we initialize DR to 0\n\t *and assert NSRST by setting DDR to 1. */\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev, 9,\n\t\t\tEP1_CMD_MEMORY_WRITE,\n\t\t\tST7_PADR >> 8,\n\t\t\tST7_PADR,\n\t\t\t1,\n\t\t\tbitmap,\n\t\t\tEP1_CMD_MEMORY_READ,\n\t\t\tST7_PBDDR >> 8,\n\t\t\tST7_PBDDR,\n\t\t\t1\n\t\t\t);\n\tif (usb_err < 0) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tusb_err = jtag_libusb_bulk_read(\n\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t(char *)&bitmap, 1,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\tif (usb_err != ERROR_OK || transferred < 1) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tif (srst)\n\t\tbitmap |= ST7_PB_NSRST;\n\telse\n\t\tbitmap &= ~ST7_PB_NSRST;\n\n\t/* write port B and read dummy to ensure completion before returning */\n\tusb_err = ep1_generic_commandl(\n\t\t\thdev, 6,\n\t\t\tEP1_CMD_MEMORY_WRITE,\n\t\t\tST7_PBDDR >> 8,\n\t\t\tST7_PBDDR,\n\t\t\t1,\n\t\t\tbitmap,\n\t\t\tEP1_CMD_DTC_GET_CACHED_STATUS\n\t\t\t);\n\tif (usb_err < 0) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n\n\tusb_err = jtag_libusb_bulk_read(\n\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t(char *)&bitmap, 1,\n\t\t\tLIBUSB_TIMEOUT_MS,\n\t\t\t&transferred\n\t\t\t);\n\tif (usb_err != ERROR_OK || transferred < 1) {\n\t\tLOG_ERROR(\"%s\", libusb_error_name(usb_err));\n\t\texit(1);\n\t}\n}\n\nstatic int rlink_scan(struct jtag_command *cmd, enum scan_type type,\n\t\tuint8_t *buffer, int scan_size)\n{\n\tbool ir_scan;\n\ttap_state_t saved_end_state;\n\tint byte_bits;\n\tint extra_bits;\n\tint chunk_bits;\n\tint chunk_bytes;\n\tint x;\n\n\tint tdi_bit_offset;\n\tuint8_t tdi_mask, *tdi_p;\n\tuint8_t dtc_mask;\n\n\tif (scan_size < 1) {\n\t\tLOG_ERROR(\"scan_size cannot be less than 1 bit\");\n\t\texit(1);\n\t}\n\n\tir_scan = cmd->cmd.scan->ir_scan;\n\n\t/* Move to the proper state before starting to shift TDI/TDO. */\n\tif (!((!ir_scan && (tap_get_state() == TAP_DRSHIFT)) ||\n\t\t\t(ir_scan && (tap_get_state() == TAP_IRSHIFT)))) {\n\t\tsaved_end_state = tap_get_end_state();\n\t\trlink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\t\trlink_state_move();\n\t\trlink_end_state(saved_end_state);\n\t}\n\n\ttap_state_queue_run();\n\n\n#if 0\n\tprintf(\"scan_size = %d, type = 0x%x\\n\", scan_size, type);\n\t{\n\t\tint i;\n\n\t\t/* clear unused bits in scan buffer for ease of debugging\n\t\t * (it makes diffing output easier) */\n\t\tbuffer[scan_size / 8] &= ((1 << ((scan_size - 1) % 8) + 1) - 1);\n\n\t\tprintf(\"before scan:\");\n\t\tfor (i = 0; i < (scan_size + 7) / 8; i++)\n\t\t\tprintf(\" %02x\", buffer[i]);\n\t\tprintf(\"\\n\");\n\t}\n#endif\n\n\t/* The number of bits that can be shifted as complete bytes */\n\tbyte_bits = (int)(scan_size - 1) / 8 * 8;\n\t/* The number of bits left over, not counting the last bit */\n\textra_bits = (scan_size - 1) - byte_bits;\n\n\ttdi_bit_offset = 0;\n\ttdi_p = buffer;\n\ttdi_mask = 1;\n\n\tif (extra_bits && (type == SCAN_OUT)) {\n\t\t/* Schedule any extra bits into the DTC command buffer, padding as needed\n\t\t * For SCAN_OUT, this comes before the full bytes so the (leading) padding bits will\n\t\t *fall off the end */\n\n\t\t/* make sure there's room for two cmd bytes */\n\t\tdtc_queue_run_if_full(2, 0);\n\n\t\tx = 0;\n\t\tdtc_mask = 1 << (extra_bits - 1);\n\n\t\twhile (extra_bits--) {\n\t\t\tif (*tdi_p & tdi_mask)\n\t\t\t\tx |= dtc_mask;\n\n\t\t\tdtc_mask >>= 1;\n\n\t\t\ttdi_mask <<= 1;\n\t\t\tif (tdi_mask == 0) {\n\t\t\t\ttdi_p++;\n\t\t\t\ttdi_mask = 1;\n\t\t\t}\n\t\t}\n\n\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\tDTC_CMD_SHIFT_TDI_BYTES(1);\n\n\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;\n\t}\n\n\t/* Loop scheduling full bytes into the DTC command buffer */\n\twhile (byte_bits) {\n\t\t/* make sure there's room for one (for in scans) or two cmd bytes and\n\t\t * at least one reply byte for in or inout scans*/\n\t\tdtc_queue_run_if_full(type == SCAN_IN ? 1 : 2, type != SCAN_OUT ? 1 : 0);\n\n\t\tchunk_bits = byte_bits;\n\t\t/* we can only use up to 16 bytes at a time */\n\t\tif (chunk_bits > (16 * 8))\n\t\t\tchunk_bits = (16 * 8);\n\n\t\tif (type != SCAN_IN) {\n\t\t\t/* how much is there room for, considering stop and byte op? */\n\t\t\tx = (sizeof(dtc_queue.cmd_buffer) - (dtc_queue.cmd_index + 1 + 1)) * 8;\n\t\t\tif (chunk_bits > x)\n\t\t\t\tchunk_bits = x;\n\t\t}\n\n\t\tif (type != SCAN_OUT) {\n\t\t\t/* how much is there room for in the reply buffer? */\n\t\t\tx = (USB_EP2IN_SIZE - dtc_queue.reply_index) * 8;\n\t\t\tif (chunk_bits > x)\n\t\t\t\tchunk_bits = x;\n\t\t}\n\n\t\t/* so the loop will end */\n\t\tbyte_bits -= chunk_bits;\n\n\t\tif (type != SCAN_OUT) {\n\t\t\tif (!dtc_queue_enqueue_reply(type, buffer, scan_size, tdi_bit_offset,\n\t\t\t\t\tchunk_bits, cmd)) {\n\t\t\t\tLOG_ERROR(\"enqueuing DTC reply entry: %s\", strerror(errno));\n\t\t\t\texit(1);\n\t\t\t}\n\t\t\tdtc_queue.reply_index += (chunk_bits + 7) / 8;\n\n\t\t\ttdi_bit_offset += chunk_bits;\n\t\t}\n\n\t\t/* chunk_bits is a multiple of 8, so there are no rounding issues. */\n\t\tchunk_bytes = chunk_bits / 8;\n\n\t\tswitch (type) {\n\t\t\tcase SCAN_IN:\n\t\t\t\tx = DTC_CMD_SHIFT_TDO_BYTES(chunk_bytes);\n\t\t\t\tbreak;\n\t\t\tcase SCAN_OUT:\n\t\t\t\tx = DTC_CMD_SHIFT_TDI_BYTES(chunk_bytes);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tx = DTC_CMD_SHIFT_TDIO_BYTES(chunk_bytes);\n\t\t\t\tbreak;\n\t\t}\n\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;\n\n\t\tif (type != SCAN_IN) {\n\t\t\tx = 0;\n\t\t\tdtc_mask = 1 << (8 - 1);\n\n\t\t\twhile (chunk_bits--) {\n\t\t\t\tif (*tdi_p & tdi_mask)\n\t\t\t\t\tx |= dtc_mask;\n\n\t\t\t\tdtc_mask >>= 1;\n\t\t\t\tif (dtc_mask == 0) {\n\t\t\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;\n\t\t\t\t\tx = 0;\n\t\t\t\t\tdtc_mask = 1 << (8 - 1);\n\t\t\t\t}\n\n\t\t\t\ttdi_mask <<= 1;\n\t\t\t\tif (tdi_mask == 0) {\n\t\t\t\t\ttdi_p++;\n\t\t\t\t\ttdi_mask = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (extra_bits && (type != SCAN_OUT)) {\n\t\t/* Schedule any extra bits into the DTC command buffer */\n\n\t\t/* make sure there's room for one (for in scans) or two cmd bytes\n\t\t * and one reply byte */\n\t\tdtc_queue_run_if_full(type == SCAN_IN ? 1 : 2, 1);\n\n\t\tif (!dtc_queue_enqueue_reply(type, buffer, scan_size, tdi_bit_offset,\n\t\t\t\textra_bits, cmd)) {\n\t\t\tLOG_ERROR(\"enqueuing DTC reply entry: %s\", strerror(errno));\n\t\t\texit(1);\n\t\t}\n\n\t\tdtc_queue.reply_index++;\n\n\t\ttdi_bit_offset += extra_bits;\n\n\t\tif (type == SCAN_IN) {\n\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\t\tDTC_CMD_SHIFT_TDO_BYTES(1);\n\n\t\t} else {\n\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\t\tDTC_CMD_SHIFT_TDIO_BITS(extra_bits);\n\n\t\t\tx = 0;\n\t\t\tdtc_mask = 1 << (8 - 1);\n\n\t\t\twhile (extra_bits--) {\n\t\t\t\tif (*tdi_p & tdi_mask)\n\t\t\t\t\tx |= dtc_mask;\n\n\t\t\t\tdtc_mask >>= 1;\n\n\t\t\t\ttdi_mask <<= 1;\n\t\t\t\tif (tdi_mask == 0) {\n\t\t\t\t\ttdi_p++;\n\t\t\t\t\ttdi_mask = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;\n\t\t}\n\t}\n\n\t/* Schedule the last bit into the DTC command buffer */\n\n\t/* make sure there's room for one cmd byte and one reply byte\n\t * for in or inout scans*/\n\tdtc_queue_run_if_full(1, type == SCAN_OUT ? 0 : 1);\n\n\tif (type == SCAN_OUT) {\n\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\tDTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 0);\n\n\t} else {\n\t\tif (!dtc_queue_enqueue_reply(type, buffer, scan_size, tdi_bit_offset,\n\t\t\t\t1, cmd)) {\n\t\t\tLOG_ERROR(\"enqueuing DTC reply entry: %s\", strerror(errno));\n\t\t\texit(1);\n\t\t}\n\n\t\tdtc_queue.reply_index++;\n\n\t\tdtc_queue.cmd_buffer[dtc_queue.cmd_index++] =\n\t\t\tDTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 1);\n\t}\n\n\t/* Move to pause state */\n\ttap_state_queue_append(0);\n\ttap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\tif (tap_get_state() != tap_get_end_state())\n\t\trlink_state_move();\n\n\treturn 0;\n}\n\nstatic int rlink_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\t/* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\tint retval, tmp_retval;\n\n\t/* return ERROR_OK, unless something goes wrong */\n\tretval = ERROR_OK;\n\n#ifndef AUTOMATIC_BUSY_LED\n\t/* turn LED on */\n\tep1_generic_commandl(hdev, 2,\n\t\tEP1_CMD_SET_PORTD_LEDS,\n\t\t~(ST7_PD_NBUSY_LED)\n\t\t);\n#endif\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RUNTEST:\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t/* some events, such as resets, need a queue flush to ensure\n\t\t\t\t *consistency */\n\t\t\t\ttap_state_queue_run();\n\t\t\t\tdtc_queue_run();\n\t\t\t\tbreak;\n\t\t}\n\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\",\n\t\t\t\t\t\tcmd->cmd.reset->trst,\n\t\t\t\t\t\tcmd->cmd.reset->srst);\n\t\t\t\tif ((cmd->cmd.reset->trst == 1) ||\n\t\t\t\t\t\t(cmd->cmd.reset->srst &&\n\t\t\t\t\t\t\t\t(jtag_get_reset_config() & RESET_SRST_PULLS_TRST)))\n\t\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\t\trlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\tcmd->cmd.runtest->end_state);\n\t\t\t\tif (cmd->cmd.runtest->end_state != -1)\n\t\t\t\t\trlink_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\trlink_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\t\t\t\tif (cmd->cmd.statemove->end_state != -1)\n\t\t\t\t\trlink_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\trlink_state_move();\n\t\t\t\tbreak;\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\t\t\t\trlink_path_move(cmd->cmd.pathmove);\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"%s scan end in %i\",\n\t\t\t\t\t\t(cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\",\n\t\t\t\t\t\t\t\tcmd->cmd.scan->end_state);\n\t\t\t\tif (cmd->cmd.scan->end_state != -1)\n\t\t\t\t\trlink_end_state(cmd->cmd.scan->end_state);\n\t\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\t\tif (rlink_scan(cmd, type, buffer, scan_size) != ERROR_OK)\n\t\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\t/* Flush the DTC queue to make sure any pending reads have been done before exiting this\n\t *function */\n\ttap_state_queue_run();\n\ttmp_retval = dtc_queue_run();\n\tif (tmp_retval != ERROR_OK)\n\t\tretval = tmp_retval;\n\n#ifndef AUTOMATIC_BUSY_LED\n\t/* turn LED off */\n\tep1_generic_commandl(hdev, 2,\n\t\tEP1_CMD_SET_PORTD_LEDS,\n\t\t~0\n\t\t);\n#endif\n\n\treturn retval;\n}\n\n/* Using an unindexed table because it is infrequently accessed and it is short.  The table must be\n *in order of ascending speed (and descending prescaler), as it is scanned in reverse. */\n\nstatic int rlink_speed(int speed)\n{\n\tint i;\n\n\tif (speed == 0) {\n\t\t/* fastest speed */\n\t\tspeed = rlink_speed_table[rlink_speed_table_size - 1].prescaler;\n\t}\n\n\tfor (i = rlink_speed_table_size; i--; ) {\n\t\tif (rlink_speed_table[i].prescaler == speed) {\n\t\t\tif (dtc_load_from_buffer(hdev, rlink_speed_table[i].dtc,\n\t\t\t\t\trlink_speed_table[i].dtc_size) != 0) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"An error occurred while trying to load DTC code for speed \\\"%d\\\".\",\n\t\t\t\t\tspeed);\n\t\t\t\texit(1);\n\t\t\t}\n\n\t\t\tint ret = dtc_start_download();\n\t\t\tif (ret < 0) {\n\t\t\t\tLOG_ERROR(\"starting DTC: %s\", libusb_error_name(ret));\n\t\t\t\texit(1);\n\t\t\t}\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"%d is not a supported speed\", speed);\n\treturn ERROR_FAIL;\n}\n\nstatic int rlink_speed_div(int speed, int *khz)\n{\n\tint i;\n\n\tfor (i = rlink_speed_table_size; i--; ) {\n\t\tif (rlink_speed_table[i].prescaler == speed) {\n\t\t\t*khz = rlink_speed_table[i].khz;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"%d is not a supported speed\", speed);\n\treturn ERROR_FAIL;\n}\n\nstatic int rlink_khz(int khz, int *speed)\n{\n\tint i;\n\n\tif (khz == 0) {\n\t\tLOG_ERROR(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = rlink_speed_table_size; i--; ) {\n\t\tif (rlink_speed_table[i].khz <= khz) {\n\t\t\t*speed = rlink_speed_table[i].prescaler;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_WARNING(\"The lowest supported JTAG speed is %d KHz\", rlink_speed_table[0].khz);\n\t*speed = rlink_speed_table[0].prescaler;\n\treturn ERROR_OK;\n}\n\nstatic int rlink_init(void)\n{\n\tint i, j, retries;\n\tuint8_t reply_buffer[USB_EP1IN_SIZE];\n\tint transferred;\n\n\tconst uint16_t vids[] = { USB_IDVENDOR, 0 };\n\tconst uint16_t pids[] = { USB_IDPRODUCT, 0 };\n\tif (jtag_libusb_open(vids, pids, &hdev, NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tstruct libusb_device_descriptor descriptor;\n\tstruct libusb_device *usb_dev = libusb_get_device(hdev);\n\tint r = libusb_get_device_descriptor(usb_dev, &descriptor);\n\tif (r < 0) {\n\t\tLOG_ERROR(\"error %d getting device descriptor\", r);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (descriptor.bNumConfigurations > 1) {\n\t\tLOG_ERROR(\"Whoops! NumConfigurations is not 1, don't know what to do...\");\n\t\treturn ERROR_FAIL;\n\t}\n\tstruct libusb_config_descriptor *config;\n\tlibusb_get_config_descriptor(usb_dev, 0, &config);\n\tif (config->bNumInterfaces > 1) {\n\t\tLOG_ERROR(\"Whoops! NumInterfaces is not 1, don't know what to do...\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Opened device, hdev = %p\", hdev);\n\n\t/* usb_set_configuration required under win32 */\n\tlibusb_set_configuration(hdev, config->bConfigurationValue);\n\n\tretries = 3;\n\tdo {\n\t\ti = libusb_claim_interface(hdev, 0);\n\t\tif (i != LIBUSB_SUCCESS) {\n\t\t\tLOG_ERROR(\"usb_claim_interface: %s\", libusb_error_name(i));\n\t\t\tj = libusb_detach_kernel_driver(hdev, 0);\n\t\t\tif (j != LIBUSB_SUCCESS)\n\t\t\t\tLOG_ERROR(\"detach kernel driver: %s\", libusb_error_name(j));\n\t\t} else {\n\t\t\tLOG_DEBUG(\"interface claimed!\");\n\t\t\tbreak;\n\t\t}\n\t} while (--retries);\n\n\tif (i != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"Initialisation failed.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (libusb_set_interface_alt_setting(hdev, 0, 0) != LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"Failed to set interface.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* The device starts out in an unknown state on open.  As such,\n\t * result reads time out, and it's not even known whether the\n\t * command was accepted.  So, for this first command, we issue\n\t * it repeatedly until its response doesn't time out.  Also, if\n\t * sending a command is going to time out, we find that out here.\n\t *\n\t * It must be possible to open the device in such a way that\n\t * this special magic isn't needed, but, so far, it escapes us.\n\t */\n\tfor (i = 0; i < 5; i++) {\n\t\tj = ep1_generic_commandl(\n\t\t\t\thdev, 1,\n\t\t\t\tEP1_CMD_GET_FWREV\n\t\t\t\t);\n\t\tif (j < USB_EP1OUT_SIZE) {\n\t\t\tLOG_ERROR(\"USB write error: %s\", libusb_error_name(j));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tj = jtag_libusb_bulk_read(\n\t\t\t\thdev, USB_EP1IN_ADDR,\n\t\t\t\t(char *)reply_buffer, sizeof(reply_buffer),\n\t\t\t\t200,\n\t\t\t\t&transferred\n\t\t\t\t);\n\t\tif (j != LIBUSB_ERROR_TIMEOUT)\n\t\t\tbreak;\n\t}\n\n\tif (j != ERROR_OK || transferred != (int)sizeof(reply_buffer)) {\n\t\tLOG_ERROR(\"USB read error: %s\", libusb_error_name(j));\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(INTERFACE_NAME \" firmware version: %d.%d.%d\",\n\t\treply_buffer[0],\n\t\treply_buffer[1],\n\t\treply_buffer[2]);\n\n\tif ((reply_buffer[0] != 0) || (reply_buffer[1] != 0) || (reply_buffer[2] != 3))\n\t\tLOG_WARNING(\n\t\t\t\"The rlink device is not of the version that the developers have played with.  It may or may not work.\");\n\n\t/* Probe port E for adapter presence */\n\tep1_generic_commandl(\n\t\thdev, 16,\n\t\tEP1_CMD_MEMORY_WRITE,\t\t/* Drive sense pin with 0 */\n\t\tST7_PEDR >> 8,\n\t\tST7_PEDR,\n\t\t3,\n\t\t0x00,\t\t\t\t\t\t\t/* DR */\n\t\tST7_PE_ADAPTER_SENSE_OUT,\t\t/* DDR */\n\t\tST7_PE_ADAPTER_SENSE_OUT,\t\t/* OR */\n\t\tEP1_CMD_MEMORY_READ,\t\t/* Read back */\n\t\tST7_PEDR >> 8,\n\t\tST7_PEDR,\n\t\t1,\n\t\tEP1_CMD_MEMORY_WRITE,\t\t/* Drive sense pin with 1 */\n\t\tST7_PEDR >> 8,\n\t\tST7_PEDR,\n\t\t1,\n\t\tST7_PE_ADAPTER_SENSE_OUT\n\t\t);\n\n\tjtag_libusb_bulk_read(\n\t\thdev, USB_EP1IN_ADDR,\n\t\t(char *)reply_buffer, 1,\n\t\tLIBUSB_TIMEOUT_MS,\n\t\t&transferred\n\t\t);\n\n\tif ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) != 0)\n\t\tLOG_WARNING(\"target detection problem\");\n\n\tep1_generic_commandl(\n\t\thdev, 11,\n\t\tEP1_CMD_MEMORY_READ,\t\t/* Read back */\n\t\tST7_PEDR >> 8,\n\t\tST7_PEDR,\n\t\t1,\n\t\tEP1_CMD_MEMORY_WRITE,\t\t/* float port E */\n\t\tST7_PEDR >> 8,\n\t\tST7_PEDR,\n\t\t3,\n\t\t0x00,\t\t/* DR */\n\t\t0x00,\t\t/* DDR */\n\t\t0x00\t\t/* OR */\n\t\t);\n\n\tjtag_libusb_bulk_read(\n\t\thdev, USB_EP1IN_ADDR,\n\t\t(char *)reply_buffer, 1,\n\t\tLIBUSB_TIMEOUT_MS,\n\t\t&transferred\n\t\t);\n\n\n\tif ((reply_buffer[0] & ST7_PE_ADAPTER_SENSE_IN) == 0)\n\t\tLOG_WARNING(\"target not plugged in\");\n\n\t/* float ports A and B */\n\tep1_generic_commandl(\n\t\thdev, 11,\n\t\tEP1_CMD_MEMORY_WRITE,\n\t\tST7_PADDR >> 8,\n\t\tST7_PADDR,\n\t\t2,\n\t\t0x00,\n\t\t0x00,\n\t\tEP1_CMD_MEMORY_WRITE,\n\t\tST7_PBDDR >> 8,\n\t\tST7_PBDDR,\n\t\t1,\n\t\t0x00\n\t\t);\n\n\t/* make sure DTC is stopped, set VPP control, set up ports A and B */\n\tep1_generic_commandl(\n\t\thdev, 14,\n\t\tEP1_CMD_DTC_STOP,\n\t\tEP1_CMD_SET_PORTD_VPP,\n\t\t~(ST7_PD_VPP_SHDN),\n\t\tEP1_CMD_MEMORY_WRITE,\n\t\tST7_PADR >> 8,\n\t\tST7_PADR,\n\t\t2,\n\t\t((~(0)) & (ST7_PA_NTRST)),\n\t\t(ST7_PA_NTRST),\n\t\t/* port B has no OR, and we want to emulate open drain on NSRST, so we set DR to 0\n\t\t *here and later assert NSRST by setting DDR bit to 1. */\n\t\tEP1_CMD_MEMORY_WRITE,\n\t\tST7_PBDR >> 8,\n\t\tST7_PBDR,\n\t\t1,\n\t\t0x00\n\t\t);\n\n\t/* set LED updating mode and make sure they're unlit */\n\tep1_generic_commandl(\n\t\thdev, 3,\n#ifdef AUTOMATIC_BUSY_LED\n\t\tEP1_CMD_LEDUE_BUSY,\n#else\n\t\tEP1_CMD_LEDUE_NONE,\n#endif\n\t\tEP1_CMD_SET_PORTD_LEDS,\n\t\t~0\n\t\t);\n\n\ttap_state_queue_init();\n\tdtc_queue_init();\n\trlink_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int rlink_quit(void)\n{\n\t/* stop DTC and make sure LEDs are off */\n\tep1_generic_commandl(\n\t\thdev, 6,\n\t\tEP1_CMD_DTC_STOP,\n\t\tEP1_CMD_LEDUE_NONE,\n\t\tEP1_CMD_SET_PORTD_LEDS,\n\t\t~0,\n\t\tEP1_CMD_SET_PORTD_VPP,\n\t\t~0\n\t\t);\n\n\tlibusb_release_interface(hdev, 0);\n\tlibusb_close(hdev);\n\n\treturn ERROR_OK;\n}\n\nstatic struct jtag_interface rlink_interface = {\n\t.execute_queue = rlink_execute_queue,\n};\n\nstruct adapter_driver rlink_adapter_driver = {\n\t.name = \"rlink\",\n\t.transports = jtag_only,\n\n\t.init = rlink_init,\n\t.quit = rlink_quit,\n\t.speed = rlink_speed,\n\t.khz = rlink_khz,\n\t.speed_div = rlink_speed_div,\n\n\t.jtag_ops = &rlink_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 Lou Deluxe                                         *\n *   lou.openocd012@fixit.nospammail.net                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_RLINK_H\n#define OPENOCD_JTAG_DRIVERS_RLINK_H\n\n#include \"helper/types.h\"\nstruct rlink_speed_table {\n\tuint8_t const *dtc;\n\tuint16_t dtc_size;\n\tuint16_t khz;\n\tuint8_t prescaler;\n};\n\nextern const struct rlink_speed_table rlink_speed_table[];\nextern const size_t rlink_speed_table_size;\n\n#endif /* OPENOCD_JTAG_DRIVERS_RLINK_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_call.m4",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright (C) 2008 Lou Deluxe\n# lou.openocd012@fixit.nospammail.net\n#\n\nm4_divert(`-1')\n\nm4_dnl Setup and hold times depend on SHIFTER_PRESCALER\nm4_define(`SETUP_DELAY_CYCLES', m4_eval(`('SHIFTER_PRESCALER` + 1) / 2'))\nm4_define(`HOLD_DELAY_CYCLES', m4_eval(`'SHIFTER_PRESCALER` / 2'))\n\nm4_dnl Some macros to make nybble handling a little easier\nm4_define(`m4_high_nybble', `m4_eval(`(($1) >> 4) & 0xf')')\nm4_define(`m4_low_nybble', `m4_eval(`($1) & 0xf')')\n\nm4_dnl A macro to generate a number of NOPs depending on the argument\nm4_define(`m4_0_to_5_nops', `m4_ifelse(m4_eval(`($1) >= 1'), 1, `\tNOP\n'm4_ifelse(m4_eval(`($1) >= 2'), 1, `\tNOP\n'm4_ifelse(m4_eval(`($1) >= 3'), 1, `\tNOP\n'm4_ifelse(m4_eval(`($1) >= 4'), 1, `\tNOP\n'm4_ifelse(m4_eval(`($1) >= 5'), 1, `\tNOP\n')))))')\n\n\nm4_dnl Some macros to facilitate bit-banging delays.\nm4_dnl There are 3 of them.  One for self-contained delays, and two for those which must be split between setup and loop to keep from disturbing A at delay time.\nm4_dnl The argument passed to any of them is the number of cycles which the delay should consume.\n\nm4_dnl This one is self-contained.\n\nm4_define(`m4_delay',\n`; delay (m4_eval($1) cycles)'\n`m4_ifelse(m4_eval(`('$1`) < 6'), 1,\n\tm4_0_to_5_nops($1)\n,\n\tm4_ifelse(m4_eval(`(('$1`) - 3) % 2'), 1, `\tNOP')\n\tA.H = m4_high_nybble(`(('$1`) - 3) / 2')\n\tA.L = m4_low_nybble(`(('$1`) - 3) / 2')\n\tY = A\n\tDECY\n\tJP -1\n)')\n\n\nm4_dnl These are the setup and loop parts of the split delay.\nm4_dnl The argument passed to both must match for the result to make sense.\nm4_dnl The setup does not figure into the delay.  It takes 3 cycles when a loop is used and none if nops are used.\n\nm4_define(`m4_delay_setup',\n`; delay setup (m4_eval($1) cycles)'\n`m4_ifelse(m4_eval(`('$1`) < 6'), 0, `\t'\n\tA.H = m4_high_nybble(`('$1`) / 2')\n\tA.L = m4_low_nybble(`('$1`) / 2')\n\tY = A\n)')\n\nm4_define(`m4_delay_loop',\n`; delay loop (m4_eval($1) cycles)'\n`m4_ifelse(m4_eval(`('$1`) < 6'), 1,\n\tm4_0_to_5_nops($1)\n,\n\tm4_ifelse(m4_eval(`('$1`) % 2'), 1, `\tNOP')\n\tDECY\n\tJP -1\n)')\n\nm4_dnl These are utility macros for use with delays.  Specifically, there is code below which needs some predictability in code size for relative jumps to reach.  The m4_delay macro generates an extra NOP when an even delay is needed, and the m4_delay_loop macro generates an extra NOP when an odd delay is needed.  Using this for the argument to the respective macro rounds up the argument so that the extra NOP will not be generated.  There is also logic built in to cancel the rounding when the result is small enough that a loop would not be generated.\n\nm4_define(`m4_delay_loop_round_up', `m4_ifelse(m4_eval($1` < 6'), 1, $1, m4_eval(`(('$1`) + 1) / 2 * 2'))')\nm4_define(`m4_delay_round_up', `m4_ifelse(m4_eval($1` < 6'), 1, $1, m4_eval(`(('$1`) / 2 * 2) + 1'))')\n\n\nm4_divert(`0')m4_dnl\n\n;------------------------------------------------------------------------------\n:opcode_error\n; This is at address 0x00 in case of empty LUT entries\n\tSTATUS STOP ERROR\n\n;------------------------------------------------------------------------------\n; Command interpreter at address 0x01 because it is branched to a lot and having it be 0x01 means we can use X for it, which is already used for other purposes which want it to be 1.\n; Assumes X is 1\n; Assumes ADR_BUFFER0 points to the next command byte\n; Stores the current command byte in CMP01\n\n:command_interpreter\n\tA = DATA_BUFFER0\n\tADR_BUFFER0 += X\n\tCMP01 = A\t; store the current command for later\n\n\tEXCHANGE\t; put MSN into LSN\n\tA.H = 0xc\t; lookup table at 0x1550 + 0xc0 = 0x1610\n\n\t; branch to address in lookup table\n\tY = A\n\tA = <Y>\n\tBRANCH\n\n;------------------------------------------------------------------------------\n; LUT for high nybble\n\n;LUT; c0 opcode_error\n;LUT; c1 opcode_shift_tdi_andor_tms_bytes\n;LUT; c2 opcode_shift_tdi_andor_tms_bytes\n;LUT; c3 opcode_shift_tdi_andor_tms_bytes\n;LUT; c4 opcode_shift_tdo_bytes\n;LUT; c5 opcode_error\n;LUT; c6 opcode_shift_tdio_bytes\n;LUT; c7 opcode_error\n;LUT; c8 opcode_shift_tms_tdi_bit_pair\n;LUT; c9 opcode_shift_tms_bits\n;LUT; ca opcode_error\n;LUT; cb opcode_error\n;LUT; cc opcode_error\n;LUT; cd opcode_error\n;LUT; ce opcode_shift_tdio_bits\n;LUT; cf opcode_stop\n\n\n;------------------------------------------------------------------------------\n; USB/buffer handling\n;\n\n;ENTRY; download entry_download\n\nopcode_stop:\nopcode_next_buffer:\n\t; pointer to completion flag\n\tA.H = 0xf\n\tA.L = 0xf\n\tY = A\n\n\tA = OR_MPEG\t; buffer indicator from previous iteration\n\t<Y> = A\t\t; either indicator will have bit 0 set\n\tBSET 1\t\t; was buffer 1 previously current?\n;\tA.H = 0\t\t; already zero from OR_MPEG\n\tJP opcode_next_buffer_0\n\nopcode_next_buffer_1:\n\tA.L = 0x1\t; ack buffer 0\n\tBUFFER_MNGT = A\n;\tA.H = 0x0\t; already zero from BUFFER_MNGT\n\tA.L = 0x3\t; Input buffer 1 = 0x1850 (0x0300)\n\tJP +4\n\nopcode_next_buffer_0:\n\tA.L = 0x2\t; ack buffer 1\n\tBUFFER_MNGT = A\nentry_download:\n\tA = X\t\t; Input buffer 0 = 0x1650 (0x0100)\n\n\tADR_BUFFER01 = A\n\tOR_MPEG = A\t; store for next iteration\n\n\tA.L = 0x0\n\tBUFFER_MNGT = A\t; finish acking previous buffer\n\tY = A\n\tADR_BUFFER00 = A\n\tADR_BUFFER11 = A\n\n\tA.H = 0x4\t; Output buffer = 0x1590 (0x0040)\n\tADR_BUFFER10 = A\n\n\tEXCHANGE\t; 0x04\n\tX = A\t\t; for the spin loop below\n\n\t; pointer to status in shared memory\n\tDECY\t\t; setting to 0 above and decrementing here saves a byte\n\n\t; wait until a command buffer is available\n\tA = BUFFER_MNGT\t; spin while neither of bits 2 or 3 are set\n\tCP A<X\t\t; this is slightly faster and smaller than trying to AND and compare the result, and it lets us just use the nybble-swapped 0x40 from the output buffer setup.\n\tJP -2\n\t<Y> = A\t\t; update status once done spinning\n\n\t; restore X, since we used it\n;\tA.H = 0\t; high nybble of BUFFER_MNGT will always be 0 the way we use it\n\tA.L = 1\n\tX = A\n\n\t; go to command interpreter\n\tBRANCH\n\n\n;;------------------------------------------------------------------------------\n;:opcode_stop\n;;\n;\n;\t; Ack buffer 0 in download mode\n;\tA.L = 0x1\n;\tBUFFER_MNGT = A\n;\n;\tSTATUS STOP\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tdi_andor_tms_bytes\n;\n\n\tA = CMP01\t; bits 3..0 contain the number of bytes to shift - 1\n\tA.H = 0\n\tY = A\t\t; loop counter\n\n\tA = CMP01\n\tEXCHANGE\n\tCMP01 = A\t; we're interested in bits in the high nybble\n\nopcode_shift_tdi_andor_tms_bytes__loop:\n\n; set tdi to supplied byte or zero\n\tA = CMP01\n\tBSET 1\n\tJP +4\n\tA.H = 0\n\tA.L = 0\n\tJP +3\n\tA = DATA_BUFFER0\n\tADR_BUFFER0 += X\n\tSHIFT_MPEG = A\n\n; set tms to supplied byte or zero\n\tA = CMP01\n\tBCLR 0\n\tJP +5\n\tA = DATA_BUFFER0\n\tADR_BUFFER0 += X\n\tSHIFT_CARD = A\n\tSHIFT CARD OUT=>PIN0\n\n; run both shifters as nearly simultaneously as possible\n\tSHIFT MPEG OUT=>PIN1\n\n\tA = CTRL_FCI\n\tEXCHANGE\n\tBCLR 3\n\tJP -3\n\n\tDECY\n\tJP opcode_shift_tdi_andor_tms_bytes__loop\n\n\tA = X\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tdo_bytes\n;\n\n\tA = CMP01\t; bits 3..0 contain the number of bytes to shift - 1\n\tA.H = 0\n\tY = A\t\t; loop counter\n\nopcode_shift_tdo_bytes__loop:\n\tSHIFT MPEG PIN0=>IN\n\n\tA = CTRL_FCI\n\tEXCHANGE\n\tBCLR 3\n\tJP -3\n\n\t; put shifted byte into output buffer\n\tA = SHIFT_MPEG\n\tDATA_BUFFER1 = A\n\tADR_BUFFER1 += X\n\n\tDECY\n\tJP opcode_shift_tdo_bytes__loop\n\n\tA = X\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tdio_bytes\n;\n\n\tA = CMP01\t; bits 3..0 contain the number of bytes to shift - 1\n\tA.H = 0\n\tCMP10 = A\t; byte loop counter\n\n\tA.H = opcode_shift_tdio_bytes__sub_return\n\tA.L = opcode_shift_tdio_bytes__sub_return\n\tCMP00 = A\t; return address\n\nopcode_shift_tdio_bytes__loop:\n\tA.H = 0\n\tA.L = 7\n\tCMP11 = A\t\t; always use 8 bits\n\n\tJP sub_shift_tdio_bits\nopcode_shift_tdio_bytes__sub_return:\n\n\tA = CMP10\t; byte loop counter\n\tCP A=>X\n\tCLC\n\tA -= X\n\tCMP10 = A\n\tJP opcode_shift_tdio_bytes__loop\n\n\tA = X\n;DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tdio_bits\n;\n\n\tA = CMP01\t; bits 2..0 contain the number of bits to shift - 1\n\tA.H = 0\n\tBCLR 3\t\t; set TMS=1 if bit 3 was set\n\tCMP11 = A\t; bit loop counter\n\n\tA.H = opcode_shift_tdio_bits__sub_return\n\tA.L = opcode_shift_tdio_bits__sub_return\n\tCMP00 = A\t; return address\n\n\tJP sub_shift_tdio_bits\n\tA.L = 0x1\t; TMS=1\n\tDR_CARD = A\n\tJP sub_shift_tdio_bits\nopcode_shift_tdio_bits__sub_return:\n\n\tA = X\n;DR_MPEG = A ; return TCK low, as str912 reset halt seems to require it\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:sub_shift_tdio_bits\n;\n\n\tA = DATA_BUFFER0\t; get byte from input buffer\n\tADR_BUFFER0 += X\n\tMASK = A\t\t; put it in MASK where bit routine will use it\n\n:sub_shift_tdio_bits__loop\nm4_delay_setup(m4_delay_loop_round_up(SETUP_DELAY_CYCLES - 1))\n\n\tA = MASK\t; shift TDO into and TDI out of MASK via carry\n\tA += MASK\n\tMASK = A\n\n\t; shifting out TDI\n\tA.L = 0x2\t; TCK=0, TDI=1\n\tCP CARRY\n\tJP +2\n\tA.L = 0x0\t; TCK=0, TDI=0\n\tDR_MPEG = A\n\nm4_delay_loop(m4_delay_loop_round_up(SETUP_DELAY_CYCLES - 1))\n\n\tBSET 2\t\t; TCK high\n\tDR_MPEG = A\n\n\tA = DR_MPEG\t; set carry bit to TDO\n\tCLC\n\tBCLR 0\n\tJP +2\n\tSEC\n\nm4_delay(HOLD_DELAY_CYCLES - 10)\n\n\tA = CMP11\t; bit loop counter\n\tY = A\t\t; use Y to avoid corrupting carry bit with subtract\n\tDECY\n\tA = Y\n\tCMP11 = A\n\tJP :sub_shift_tdio_bits__loop\n\n\t; shift last TDO bit into result\n\tA = MASK\n\tA += MASK\n\tDATA_BUFFER1 = A\n\tADR_BUFFER1 += X\n\n\tA = CMP00\t; return to caller\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tms_tdi_bit_pair\n;\n\n; set TMS line manually\n\tA = CMP01\t; bits 3..0 contain TDI and TMS bits and whether to return TDO\n\tBSET 0\t\t; TMS bit\n\tA.L = 0x1\t; TMS=1\n\tJP +2\n\tA.L = 0x0\t; TMS=0\n\tDR_CARD = A\n\n; stuff command buffer with bitmap of single TDI bit\n\tA = CMP01\n\tBSET 1\t\t; TDI bit\n\tA.H = 0x8\t; TDI=1\n\tJP +2\n\tA.H = 0x0\t; TDI=0\n\tADR_BUFFER0 -= X\n\tDATA_BUFFER0 = A\n\n\tA.H = 0\n\tA.L = 0\n\tCMP11 = A\t; bit loop counter (only doing one bit)\n\n\tA.H = opcode_shift_tms_tdi_bit_pair__sub_return\n\tA.L = opcode_shift_tms_tdi_bit_pair__sub_return\n\tCMP00 = A\t; return address\n\n; jump this way due to relative jump range issues\n\tA.H = sub_shift_tdio_bits\n\tA.L = sub_shift_tdio_bits\n\tBRANCH\nopcode_shift_tms_tdi_bit_pair__sub_return:\n\n\tA = CMP01\n\tBSET 3\t\t; bit says whether to return TDO\n\tJP +2\n\tADR_BUFFER1 -= X\t; subroutine returns it, so undo that\n\n\tA = X\n\tDR_MPEG = A ; return TCK low, as str912 reset halt seems to require it\n\tBRANCH\n\n\n;------------------------------------------------------------------------------\n:opcode_shift_tms_bits\n;\n\n\tA = CMP01\t; bits 3..0 contain the number of bits to shift - 1 (only 1-8 bits is valid... no checking, just improper operation)\n\tA.H = 0\n\tCMP11 = A\t; bit loop counter\n\n\tA = DATA_BUFFER0\t; get byte from input buffer\n\tADR_BUFFER0 += X\n\tMASK = A\t\t; The byte we'll be shifting\n\n:opcode_shift_tms_bits__loop\nm4_delay_setup(SETUP_DELAY_CYCLES - 1)\n\n\tA = MASK\t; shift TMS out of MASK via carry\n\tA += MASK\n\tMASK = A\n\n\t; shifting out TMS\n\tA.L = 0x1\t; TCK=0, TDI=0, TMS=1\n\tCP CARRY\n\tJP +2\n\tA.L = 0x0\t; TCK=0, TDI=0, TMS=0\n\tDR_CARD = A\n\tDR_MPEG = A\n\nm4_delay_loop(SETUP_DELAY_CYCLES - 1)\n\n\tBSET 2\t\t; TCK high\n\tDR_MPEG = A\n\nm4_delay(HOLD_DELAY_CYCLES - 10)\n\n\tA = CMP11\t; bit loop counter\n\tCP A=>X\n\tCLC\n\tA -= X\n\tCMP11 = A\n\tJP :opcode_shift_tms_bits__loop\n\n\tA = X\n\tDR_MPEG = A ; return TCK low, as str912 reset halt seems to require it\n\tBRANCH\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_dtc_cmd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 Lou Deluxe                                         *\n *   lou.openocd012@fixit.nospammail.net                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H\n#define OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H\n\n/* A command position with the high nybble of 0x0 is reserved for an error condition.\n * If executed, it stops the DTC and raises the ERROR flag */\n\n#define DTC_CMD_SHIFT_TMS_BYTES(bytes)\t((0x1 << 4) | ((bytes) - 1))\n/* Shift 1-16 bytes out TMS. TDI is 0. */\n/* Bytes to shift follow. */\n\n#define DTC_CMD_SHIFT_TDI_BYTES(bytes)\t((0x2 << 4) | ((bytes) - 1))\n/* Shift 1-16 bytes out TDI. TMS is 0. */\n/* Bytes to shift follow. */\n\n#define DTC_CMD_SHIFT_TDI_AND_TMS_BYTES(bytes)\t((0x3 << 4) | ((bytes) - 1))\n/* Shift 1-16 byte pairs out TDI and TMS. */\n/* Byte pairs to shift follow in TDI, TMS order. */\n\n#define DTC_CMD_SHIFT_TDO_BYTES(bytes)\t((0x4 << 4) | ((bytes) - 1))\n/* Shift 1-16 bytes in TDO. TMS is unaffected. */\n/* Reply buffer contains bytes shifted in. */\n\n#define DTC_CMD_SHIFT_TDIO_BYTES(bytes)\t((0x6 << 4) | ((bytes) - 1))\n/* Shift 1-16 bytes out TDI and in TDO. TMS is unaffected. */\n\n#define DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(tms, tdi, tdo)\t((0x8 << 4) | (\\\n\t\t(tms) ? (1 << 0) : 0\t\\\n) | (\\\n\t\t(tdi) ? (1 << 1) : 0\t\\\n) | (\\\n\t\t(tdo) ? (1 << 3) : 0\t\\\n))\n/* Single bit shift.\n * tms and tdi are the levels shifted out on TMS and TDI, respectively.\n * tdo indicates whether a byte will be returned in the reply buffer with its\n * least significant bit set to reflect TDO\n * Care should be taken when tdo is zero, as the underlying code actually does put\n * that byte in the reply buffer. Setting tdo to zero just moves the pointer back.\n * The result is that if this command is executed when the reply buffer is already full,\n * a byte will be written erroneously to memory not belonging to the reply buffer.\n * This could be worked around at the expense of DTC code space and speed. */\n\n#define DTC_CMD_SHIFT_TMS_BITS(bits)\t((0x9 << 4) | ((bits) - 1))\n/* Shift 1-8 bits out TMS. */\n/* Bits to be shifted out are left justified in the following byte. */\n\n#define DTC_CMD_SHIFT_TDIO_BITS(bits)\t((0xe << 4) | ((bits) - 1))\n/* Shift 1-8 bits out TDI and in TDO, TMS is unaffected. */\n/* Bits to be shifted out are left justified in the following byte. */\n/* Bits shifted in are right justified in the byte placed in the reply buffer. */\n\n#define DTC_CMD_STOP\t\t\t(0xf << 4)\n/* Stop processing the command buffer and wait for the next one. */\n/* A shared status byte is updated with bit 0 set when this has happened,\n * and it is cleared when a new command buffer becomes ready.\n * The host can poll that byte to see when it is safe to read a reply. */\n\n#endif /* OPENOCD_JTAG_DRIVERS_RLINK_DTC_CMD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_ep1_cmd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 Lou Deluxe                                         *\n *   lou.openocd012@fixit.nospammail.net                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H\n#define OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H\n\n/*\n * Command opcodes that can be sent over endpoint 1.\n * This codifies information provided by Rob Brown <rob@cobbleware.com>.\n * The buffer can contain several of these, but only one which returns data.\n * Some of these opcodes have arguments, which follow immediately.\n * If shorter than the packet size, trailing positions should be zero-filled.\n */\n\n/* LED update enables:\n *  When enabled, each LED is updated automatically.\n *  When not enabled, each LED can be controlled manually with EP1_CMD_SET_PORTD_LEDS.\n */\n#define EP1_CMD_LEDUE_BOTH\t\t\t\t(0x05)\n/* EP1_CMD_LEDUE_NONE has the side effect of turning the LEDs on */\n#define EP1_CMD_LEDUE_NONE\t\t\t\t(0x06)\n#define EP1_CMD_LEDUE_ERROR\t\t\t\t(0x17)\n#define EP1_CMD_LEDUE_BUSY\t\t\t\t(0x18)\n\n#define EP1_CMD_DTC_STOP\t\t\t\t(0x0b)\n#define EP1_CMD_DTC_LOAD\t\t\t\t(0x0c)\n#define EP1_CMD_DTC_CALL\t\t\t\t(0x0d)\n#define EP1_CMD_SET_UPLOAD\t\t\t\t(0x0f)\n#define EP1_CMD_SET_DOWNLOAD\t\t\t(0x10)\n#define EP1_CMD_DTC_WAIT\t\t\t\t(0x12)\n#define EP1_CMD_DTC_GET_STATUS\t\t\t(0x15)\n/* a quick way to just read back one byte */\n#define EP1_CMD_DTC_GET_CACHED_STATUS\t(0x16)\n\n/* Writes upper 2 bits (SHDN and SEL) of port D with argument */\n#define EP1_CMD_SET_PORTD_VPP\t\t\t(0x19)\n/* Writes lower 2 bits (BUSY and ERROR) of port D with argument */\n#define EP1_CMD_SET_PORTD_LEDS\t\t\t(0x1a)\n\n#define EP1_CMD_MEMORY_READ\t\t\t\t(0x28)\n#define EP1_CMD_MEMORY_WRITE\t\t\t(0x29)\n#define EP1_CMD_GET_FWREV\t\t\t\t(0xfe)\n#define EP1_CMD_GET_SERIAL\t\t\t\t(0xff)\n\n#endif /* OPENOCD_JTAG_DRIVERS_RLINK_EP1_CMD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_init.m4",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright (C) 2008 Lou Deluxe\n# lou.openocd012@fixit.nospammail.net\n#\n\nm4_divert(`-1')\n\nm4_undefine(`CTRL_MPEG_L')\nm4_undefine(`CTRL_CARD_L')\n\nm4_ifelse(SHIFTER_PRESCALER, 1, `\n\tm4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x0')')\n')\nm4_ifelse(SHIFTER_PRESCALER, 2, `\n\tm4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x2')')\n\tm4_define(`CTRL_CARD_L', `m4_eval(`0x8 | 0x1')')\n')\nm4_ifelse(SHIFTER_PRESCALER, 8, `\n\tm4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x3')')\n')\nm4_ifelse(SHIFTER_PRESCALER, 11, `\n\tm4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x4')')\n')\nm4_ifelse(SHIFTER_PRESCALER, 64, `\n\tm4_define(`CTRL_MPEG_L', `m4_eval(`0x8 | 0x7')')\n')\n\nm4_ifdef(`CTRL_MPEG_L',,`\n\tm4_errprint(`SHIFTER_PRESCALER was not defined with a supported value\n')\tm4_m4exit(`1')\n')\n\nm4_divert(`0')m4_dnl\n\ninit:\n\tA.H = 0\n\n\tA.L = 0\n\n\tDR_MPEG = A\t; TDI and TCK start out low\n\tDR_CARD = A\t; TMS starts out low\n\n\tA.L = 0x6\n\n\tCTRL_FCI = A\t; MPEG and CARD driven by FCI\n\tDDR_MPEG = A\t; TDI and TCK are outputs\n\n\tA.L = 0x1\n\n\tX = A\t\t; X == 1\n\tDDR_CARD = A\t; TMS is output\n\n\tA.L = CTRL_MPEG_L\n\tCTRL_MPEG = A\nm4_ifdef(`CTRL_CARD_L',\n`\tA.L = 'CTRL_CARD_L`\n')m4_dnl\n\tCTRL_CARD = A\n\n\tSTATUS STOP\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_speed_table.c",
    "content": "/* This file was created automatically by ../../../tools/rlink_make_speed_table/rlink_make_speed_table.pl. */\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rlink.h\"\n#include \"rlink_st7.h\"\n\nstatic const uint8_t dtc_64[] = {\n\t0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148,\n\t191, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42,\n\t42, 73, 0, 88, 0, 160, 189, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119,\n\t110, 108, 111, 97, 100, 2, 226, 7, 219, 39, 137, 51, 172, 130, 192, 96,\n\t175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133,\n\t153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177,\n\t129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39,\n\t154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193,\n\t96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96,\n\t201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105,\n\t193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219,\n\t39, 131, 161, 176, 130, 195, 53, 131, 178, 10, 66, 176, 151, 60, 97, 58,\n\t151, 215, 2, 40, 66, 1, 0, 160, 185, 130, 60, 97, 203, 130, 60, 194, 139,\n\t127, 195, 53, 156, 47, 200, 96, 201, 56, 177, 66, 176, 147, 201, 57, 168,\n\t66, 160, 38, 155, 160, 176, 139, 171, 182, 136, 167, 183, 96, 201, 59,\n\t66, 46, 193, 151, 96, 201, 160, 139, 219, 39, 131, 160, 191, 130, 195,\n\t53, 131, 177, 10, 66, 176, 147, 151, 0, 60, 97, 58, 151, 0, 160, 185, 130,\n\t60, 97, 203, 8, 2, 36, 139, 124, 193, 151, 96\n};\n\nstatic const uint8_t dtc_11[] = {\n\t0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148,\n\t188, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42,\n\t42, 73, 0, 88, 0, 154, 183, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119,\n\t110, 108, 111, 97, 100, 2, 213, 7, 219, 39, 137, 51, 172, 130, 192, 96,\n\t175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133,\n\t153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177,\n\t129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39,\n\t154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193,\n\t96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96,\n\t201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105,\n\t193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219,\n\t39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 0, 0, 0, 0, 0, 58, 151, 215,\n\t2, 40, 66, 1, 203, 130, 60, 194, 139, 121, 195, 53, 156, 47, 200, 96, 201,\n\t56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 171,\n\t176, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219,\n\t39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 0, 0, 0, 0, 0, 58, 151,\n\t203, 8, 2, 36, 139, 117, 193, 151, 96\n};\n\nstatic const uint8_t dtc_8[] = {\n\t0, 2, 68, 84, 67, 2, 13, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148,\n\t187, 143, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0, 42, 42,\n\t42, 73, 0, 88, 0, 152, 181, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100, 111, 119,\n\t110, 108, 111, 97, 100, 2, 209, 7, 219, 39, 137, 51, 172, 130, 192, 96,\n\t175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159, 193, 133,\n\t153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9, 98, 128, 177,\n\t129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176, 67, 219, 39,\n\t154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60, 118, 193,\n\t96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105, 193, 96,\n\t201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36, 138, 105,\n\t193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67, 193, 96, 219,\n\t39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 0, 0, 0, 58, 151, 215, 2,\n\t40, 66, 1, 203, 130, 60, 194, 139, 119, 195, 53, 156, 47, 200, 96, 201,\n\t56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 170,\n\t190, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219,\n\t39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 0, 0, 0, 58, 151, 203,\n\t8, 2, 36, 139, 115, 193, 151, 96\n};\n\nstatic const uint8_t dtc_2[] = {\n\t0, 2, 68, 84, 67, 2, 14, 160, 176, 151, 147, 182, 141, 152, 177, 129, 148,\n\t186, 143, 185, 142, 5, 3, 0, 0, 0, 2, 68, 84, 67, 4, 0, 192, 5, 15, 0,\n\t42, 42, 42, 73, 0, 88, 0, 149, 178, 0, 0, 0, 0, 106, 9, 1, 8, 22, 100,\n\t111, 119, 110, 108, 111, 97, 100, 2, 203, 7, 219, 39, 137, 51, 172, 130,\n\t192, 96, 175, 191, 130, 217, 128, 57, 69, 177, 159, 179, 68, 178, 159,\n\t193, 133, 153, 176, 159, 130, 132, 135, 164, 134, 51, 129, 60, 223, 9,\n\t98, 128, 177, 129, 96, 201, 160, 130, 201, 51, 137, 201, 57, 68, 160, 176,\n\t67, 219, 39, 154, 201, 40, 69, 219, 39, 150, 17, 27, 205, 51, 43, 99, 60,\n\t118, 193, 96, 201, 160, 130, 24, 205, 51, 43, 99, 218, 156, 47, 60, 105,\n\t193, 96, 201, 160, 138, 166, 178, 136, 160, 183, 139, 86, 202, 8, 2, 36,\n\t138, 105, 193, 96, 201, 160, 43, 139, 167, 181, 136, 70, 177, 147, 67,\n\t193, 96, 219, 39, 131, 195, 53, 131, 178, 10, 66, 176, 151, 58, 151, 215,\n\t2, 40, 66, 1, 203, 130, 60, 194, 139, 116, 195, 53, 156, 47, 200, 96, 201,\n\t56, 177, 66, 176, 147, 201, 57, 168, 66, 160, 38, 155, 160, 176, 139, 170,\n\t187, 136, 167, 183, 96, 201, 59, 66, 46, 193, 151, 96, 201, 160, 139, 219,\n\t39, 131, 195, 53, 131, 177, 10, 66, 176, 147, 151, 58, 151, 203, 8, 2,\n\t36, 139, 112, 193, 151, 96\n};\n\nconst struct rlink_speed_table rlink_speed_table[] = {{\n\tdtc_64, sizeof(dtc_64), (ST7_FOSC * 2) / (1000 * 64), 64\n}, {\n\tdtc_11, sizeof(dtc_11), (ST7_FOSC * 2) / (1000 * 11), 11\n}, {\n\tdtc_8, sizeof(dtc_8), (ST7_FOSC * 2) / (1000 * 8), 8\n}, {\n\tdtc_2, sizeof(dtc_2), (ST7_FOSC * 2) / (1000 * 2), 2\n} };\n\nconst size_t rlink_speed_table_size = ARRAY_SIZE(rlink_speed_table);\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rlink_st7.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 Lou Deluxe                                         *\n *   lou.openocd012@fixit.nospammail.net                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_RLINK_ST7_H\n#define OPENOCD_JTAG_DRIVERS_RLINK_ST7_H\n\n#define ST7_FOSC\t\t(12 * 1000000)\n\n/* This is not a complete enumeration of ST7 registers, but it is sufficient for this interface driver. */\n\n#define ST7_PADR\t\t(0x0000)\n#define ST7_PADDR\t\t(ST7_PADR + 1)\n#define ST7_PAOR\t\t(ST7_PADR + 2)\n#define ST7_PBDR\t\t(0x0003)\n#define ST7_PBDDR\t\t(ST7_PBDR + 1)\n#define ST7_PCDR\t\t(0x0006)\n#define ST7_PCDDR\t\t(ST7_PCDR + 1)\n#define ST7_PCOR\t\t(ST7_PCDR + 2)\n#define ST7_PDDR\t\t(0x0009)\n#define ST7_PDDDR\t\t(ST7_PDDR + 1)\n#define ST7_PDOR\t\t(ST7_PDDR + 2)\n#define ST7_PEDR\t\t(0x000c)\n#define ST7_PEDDR\t\t(ST7_PEDR + 1)\n#define ST7_PEOR\t\t(ST7_PEDR + 2)\n#define ST7_PFDR\t\t(0x000f)\n#define ST7_PFDDR\t\t(ST7_PFDR + 1)\n\n#define ST7_ADCDR\t\t(0x0012)\n#define ST7_ADCCSR\t\t(ST7_ADCDR + 1)\n\n#define ST7_EP2TXR\t\t(0x003e)\n#define ST7_EP2TXR_STAT_TX0\t(1 << 0)\n#define ST7_EP2TXR_STAT_TX1\t(1 << 1)\n#define ST7_EP2TXR_STAT_DISABLED\t(0)\n#define ST7_EP2TXR_STAT_STALL\t(ST7_EP2TXR_STAT_TX0)\n#define ST7_EP2TXR_STAT_VALID\t(ST7_EP2TXR_STAT_TX1 | ST7_EP2TXR_STAT_TX0)\n#define ST7_EP2TXR_STAT_NAK\t(ST7_EP2TXR_STAT_TX1)\n#define ST7_EP2TXR_DTOG_TX\t(1 << 2)\n#define ST7_EP2TXR_CTR_TX\t(1 << 3)\n\n#define ST7_USB_BUF_EP0OUT\t(0x1550)\n#define ST7_USB_BUF_EP0IN\t(0x1560)\n#define ST7_USB_BUF_EP1OUT\t(0x1570)\n#define ST7_USB_BUF_EP1IN\t(0x1580)\n#define ST7_USB_BUF_EP2UODI\t(0x1590)\n#define ST7_USB_BUF_EP2UIDO\t(0x1650)\n\n#define ST7_PA0\t\t\t(1 << 0)\n#define ST7_PA1\t\t\t(1 << 1)\n#define ST7_PA2\t\t\t(1 << 2)\n#define ST7_PA3\t\t\t(1 << 3)\n#define ST7_PA4\t\t\t(1 << 4)\n#define ST7_PA5\t\t\t(1 << 5)\n#define ST7_PA6\t\t\t(1 << 6)\n#define ST7_PA7\t\t\t(1 << 7)\n\n#define ST7_PB0\t\t\t(1 << 0)\n#define ST7_PB1\t\t\t(1 << 1)\n#define ST7_PB2\t\t\t(1 << 2)\n#define ST7_PB3\t\t\t(1 << 3)\n#define ST7_PB4\t\t\t(1 << 4)\n#define ST7_PB5\t\t\t(1 << 5)\n#define ST7_PB6\t\t\t(1 << 6)\n#define ST7_PB7\t\t\t(1 << 7)\n\n#define ST7_PC0\t\t\t(1 << 0)\n#define ST7_PC1\t\t\t(1 << 1)\n#define ST7_PC2\t\t\t(1 << 2)\n#define ST7_PC3\t\t\t(1 << 3)\n#define ST7_PC4\t\t\t(1 << 4)\n#define ST7_PC5\t\t\t(1 << 5)\n#define ST7_PC6\t\t\t(1 << 6)\n#define ST7_PC7\t\t\t(1 << 7)\n\n#define ST7_PD0\t\t\t(1 << 0)\n#define ST7_PD1\t\t\t(1 << 1)\n#define ST7_PD2\t\t\t(1 << 2)\n#define ST7_PD3\t\t\t(1 << 3)\n#define ST7_PD4\t\t\t(1 << 4)\n#define ST7_PD5\t\t\t(1 << 5)\n#define ST7_PD6\t\t\t(1 << 6)\n#define ST7_PD7\t\t\t(1 << 7)\n\n#define ST7_PE0\t\t\t(1 << 0)\n#define ST7_PE1\t\t\t(1 << 1)\n#define ST7_PE2\t\t\t(1 << 2)\n#define ST7_PE3\t\t\t(1 << 3)\n#define ST7_PE4\t\t\t(1 << 4)\n#define ST7_PE5\t\t\t(1 << 5)\n#define ST7_PE6\t\t\t(1 << 6)\n#define ST7_PE7\t\t\t(1 << 7)\n\n#define ST7_PF0\t\t\t(1 << 0)\n#define ST7_PF1\t\t\t(1 << 1)\n#define ST7_PF2\t\t\t(1 << 2)\n#define ST7_PF3\t\t\t(1 << 3)\n#define ST7_PF4\t\t\t(1 << 4)\n#define ST7_PF5\t\t\t(1 << 5)\n#define ST7_PF6\t\t\t(1 << 6)\n#define ST7_PF7\t\t\t(1 << 7)\n\n#endif /* OPENOCD_JTAG_DRIVERS_RLINK_ST7_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/rshim.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (c) 2020, Mellanox Technologies Ltd. - All Rights Reserved\n * Liming Sun <lsun@mellanox.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/types.h>\n#include <helper/system.h>\n#include <helper/time_support.h>\n#include <helper/list.h>\n#include <jtag/interface.h>\n#ifdef HAVE_SYS_IOCTL_H\n#include <sys/ioctl.h>\n#endif\n#include <target/arm_adi_v5.h>\n#include <transport/transport.h>\n\n/* Rshim channel where the CoreSight register resides. */\n#define RSH_MMIO_CHANNEL_RSHIM\t0x1\n\n/* APB and tile address translation. */\n#define RSH_CS_ROM_BASE\t\t0x80000000\n#define RSH_CS_TILE_BASE\t0x44000000\n#define RSH_CS_TILE_SIZE\t0x04000000\n\n/*\n * APB-AP Identification Register\n * The default value is defined in \"CoreSight on-chip trace and debug\n * (Revision: r1p0)\", Section 3.16.5 APB-AP register summary.\n */\n#define APB_AP_IDR\t\t\t0x44770002\n\n/* CoreSight register definition. */\n#define RSH_CORESIGHT_CTL\t\t0x0e00\n#define RSH_CORESIGHT_CTL_GO_SHIFT\t0\n#define RSH_CORESIGHT_CTL_GO_MASK\t0x1ULL\n#define RSH_CORESIGHT_CTL_ACTION_SHIFT\t1\n#define RSH_CORESIGHT_CTL_ACTION_MASK\t0x2ULL\n#define RSH_CORESIGHT_CTL_ADDR_SHIFT\t2\n#define RSH_CORESIGHT_CTL_ADDR_MASK\t0x7ffffffcULL\n#define RSH_CORESIGHT_CTL_ERR_SHIFT\t31\n#define RSH_CORESIGHT_CTL_ERR_MASK\t0x80000000ULL\n#define RSH_CORESIGHT_CTL_DATA_SHIFT\t32\n#define RSH_CORESIGHT_CTL_DATA_MASK\t0xffffffff00000000ULL\n\n/* Util macros to access the CoreSight register. */\n#define RSH_CS_GET_FIELD(reg, field) \\\n\t(((uint64_t)(reg) & RSH_CORESIGHT_CTL_##field##_MASK) >> \\\n\t\tRSH_CORESIGHT_CTL_##field##_SHIFT)\n\n#define RSH_CS_SET_FIELD(reg, field, value) \\\n\t(reg) = (((reg) & ~RSH_CORESIGHT_CTL_##field##_MASK) | \\\n\t\t(((uint64_t)(value) << RSH_CORESIGHT_CTL_##field##_SHIFT) & \\\n\t\tRSH_CORESIGHT_CTL_##field##_MASK))\n\n#ifdef HAVE_SYS_IOCTL_H\n/* Message used to program rshim via ioctl(). */\ntypedef struct {\n\tuint32_t addr;\n\tuint64_t data;\n} __attribute__((packed)) rshim_ioctl_msg;\n\nenum {\n\tRSH_IOC_READ = _IOWR('R', 0, rshim_ioctl_msg),\n\tRSH_IOC_WRITE = _IOWR('R', 1, rshim_ioctl_msg),\n};\n#endif\n\n/* Use local variable stub for DP/AP registers. */\nstatic uint32_t dp_ctrl_stat;\nstatic uint32_t dp_id_code;\nstatic uint32_t ap_sel, ap_bank;\nstatic uint32_t ap_csw;\nstatic uint32_t ap_drw;\nstatic uint32_t ap_tar, ap_tar_inc;\n\n/* Static functions to read/write via rshim/coresight. */\nstatic int (*rshim_read)(int chan, int addr, uint64_t *value);\nstatic int (*rshim_write)(int chan, int addr, uint64_t value);\nstatic int coresight_write(uint32_t tile, uint32_t addr, uint32_t wdata);\nstatic int coresight_read(uint32_t tile, uint32_t addr, uint32_t *value);\n\n/* RShim file handler. */\nstatic int rshim_fd = -1;\n\n/* DAP error code. */\nstatic int rshim_dap_retval = ERROR_OK;\n\n/* Default rshim device. */\n#define RSHIM_DEV_PATH_DEFAULT\t\"/dev/rshim0/rshim\"\nstatic char *rshim_dev_path;\n\nstatic int rshim_dev_read(int chan, int addr, uint64_t *value)\n{\n\tint rc;\n\n\taddr = (addr & 0xFFFF) | (1 << 16);\n\trc = pread(rshim_fd, value, sizeof(*value), addr);\n\n#ifdef HAVE_SYS_IOCTL_H\n\tif (rc < 0 && errno == ENOSYS) {\n\t\trshim_ioctl_msg msg;\n\n\t\tmsg.addr = addr;\n\t\tmsg.data = 0;\n\t\trc = ioctl(rshim_fd, RSH_IOC_READ, &msg);\n\t\tif (!rc)\n\t\t\t*value = msg.data;\n\t}\n#endif\n\n\treturn rc;\n}\n\nstatic int rshim_dev_write(int chan, int addr, uint64_t value)\n{\n\tint rc;\n\n\taddr = (addr & 0xFFFF) | (1 << 16);\n\trc = pwrite(rshim_fd, &value, sizeof(value), addr);\n\n#ifdef HAVE_SYS_IOCTL_H\n\tif (rc < 0 && errno == ENOSYS) {\n\t\trshim_ioctl_msg msg;\n\n\t\tmsg.addr = addr;\n\t\tmsg.data = value;\n\t\trc = ioctl(rshim_fd, RSH_IOC_WRITE, &msg);\n\t}\n#endif\n\n\treturn rc;\n}\n\n/* Convert AP address to tile local address. */\nstatic void ap_addr_2_tile(int *tile, uint32_t *addr)\n{\n\t*addr -= RSH_CS_ROM_BASE;\n\n\tif (*addr < RSH_CS_TILE_BASE) {\n\t\t*tile = 0;\n\t} else {\n\t\t*addr -= RSH_CS_TILE_BASE;\n\t\t*tile = *addr / RSH_CS_TILE_SIZE + 1;\n\t\t*addr = *addr % RSH_CS_TILE_SIZE;\n\t}\n}\n\n/*\n * Write 4 bytes on the APB bus.\n * tile = 0: access the root CS_ROM table\n *      > 0: access the ROM table of cluster (tile - 1)\n */\nstatic int coresight_write(uint32_t tile, uint32_t addr, uint32_t wdata)\n{\n\tuint64_t ctl = 0;\n\tint rc;\n\n\tif (!rshim_read || !rshim_write)\n\t\treturn ERROR_FAIL;\n\n\t/*\n\t * ADDR[28]    - must be set to 1 due to coresight ip.\n\t * ADDR[27:24] - linear tile id\n\t */\n\taddr = (addr >> 2) | (tile << 24);\n\tif (tile)\n\t\taddr |= (1 << 28);\n\tRSH_CS_SET_FIELD(ctl, ADDR, addr);\n\tRSH_CS_SET_FIELD(ctl, ACTION, 0);\t/* write */\n\tRSH_CS_SET_FIELD(ctl, DATA, wdata);\n\tRSH_CS_SET_FIELD(ctl, GO, 1);\t\t/* start */\n\n\trshim_write(RSH_MMIO_CHANNEL_RSHIM, RSH_CORESIGHT_CTL, ctl);\n\n\tdo {\n\t\trc = rshim_read(RSH_MMIO_CHANNEL_RSHIM,\n\t\t\t\tRSH_CORESIGHT_CTL, &ctl);\n\t\tif (rc < 0) {\n\t\t\tLOG_ERROR(\"Failed to read rshim.\\n\");\n\t\t\treturn rc;\n\t\t}\n\t} while (RSH_CS_GET_FIELD(ctl, GO));\n\n\treturn ERROR_OK;\n}\n\nstatic int coresight_read(uint32_t tile, uint32_t addr, uint32_t *value)\n{\n\tuint64_t ctl = 0;\n\tint rc;\n\n\tif (!rshim_read || !rshim_write)\n\t\treturn ERROR_FAIL;\n\n\t/*\n\t * ADDR[28]    - must be set to 1 due to coresight ip.\n\t * ADDR[27:24] - linear tile id\n\t */\n\taddr = (addr >> 2) | (tile << 24);\n\tif (tile)\n\t\taddr |= (1 << 28);\n\tRSH_CS_SET_FIELD(ctl, ADDR, addr);\n\tRSH_CS_SET_FIELD(ctl, ACTION, 1);\t/* read */\n\tRSH_CS_SET_FIELD(ctl, GO, 1);\t\t/* start */\n\n\trshim_write(RSH_MMIO_CHANNEL_RSHIM, RSH_CORESIGHT_CTL, ctl);\n\n\tdo {\n\t\trc = rshim_read(RSH_MMIO_CHANNEL_RSHIM,\n\t\t\t\tRSH_CORESIGHT_CTL, &ctl);\n\t\tif (rc < 0) {\n\t\t\tLOG_ERROR(\"Failed to write rshim.\\n\");\n\t\t\treturn rc;\n\t\t}\n\t} while (RSH_CS_GET_FIELD(ctl, GO));\n\n\t*value = RSH_CS_GET_FIELD(ctl, DATA);\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dp_q_read(struct adiv5_dap *dap, unsigned int reg,\n\t\t\t   uint32_t *data)\n{\n\tif (!data)\n\t\treturn ERROR_OK;\n\n\tswitch (reg) {\n\tcase DP_DPIDR:\n\t\t*data = dp_id_code;\n\t\tbreak;\n\n\tcase DP_CTRL_STAT:\n\t\t*data = CDBGPWRUPACK | CSYSPWRUPACK;\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dp_q_write(struct adiv5_dap *dap, unsigned int reg,\n\t\t\t    uint32_t data)\n{\n\tswitch (reg) {\n\tcase DP_CTRL_STAT:\n\t\tdp_ctrl_stat = data;\n\t\tbreak;\n\tcase DP_SELECT:\n\t\tap_sel = (data & DP_SELECT_APSEL) >> 24;\n\t\tap_bank = (data & DP_SELECT_APBANK) >> 4;\n\t\tbreak;\n\tdefault:\n\t\tLOG_INFO(\"Unknown command\");\n\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rshim_ap_q_read(struct adiv5_ap *ap, unsigned int reg,\n\t\t\t   uint32_t *data)\n{\n\tuint32_t addr;\n\tint rc = ERROR_OK, tile;\n\n\tif (is_adiv6(ap->dap)) {\n\t\tstatic bool error_flagged;\n\t\tif (!error_flagged)\n\t\t\tLOG_ERROR(\"ADIv6 dap not supported by rshim dap-direct mode\");\n\t\terror_flagged = true;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (reg) {\n\tcase ADIV5_MEM_AP_REG_CSW:\n\t\t*data = ap_csw;\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_CFG:\n\t\t*data = 0;\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_BASE:\n\t\t*data = RSH_CS_ROM_BASE;\n\t\tbreak;\n\n\tcase ADIV5_AP_REG_IDR:\n\t\tif (ap->ap_num == 0)\n\t\t\t*data = APB_AP_IDR;\n\t\telse\n\t\t\t*data = 0;\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_BD0:\n\tcase ADIV5_MEM_AP_REG_BD1:\n\tcase ADIV5_MEM_AP_REG_BD2:\n\tcase ADIV5_MEM_AP_REG_BD3:\n\t\taddr = (ap_tar & ~0xf) + (reg & 0x0C);\n\t\tap_addr_2_tile(&tile, &addr);\n\t\trc = coresight_read(tile, addr, data);\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_DRW:\n\t\taddr = (ap_tar & ~0x3) + ap_tar_inc;\n\t\tap_addr_2_tile(&tile, &addr);\n\t\trc = coresight_read(tile, addr, data);\n\t\tif (!rc && (ap_csw & CSW_ADDRINC_MASK))\n\t\t\tap_tar_inc += (ap_csw & 0x03) * 2;\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_INFO(\"Unknown command\");\n\t\trc = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\t/* Track the last error code. */\n\tif (rc != ERROR_OK)\n\t\trshim_dap_retval = rc;\n\n\treturn rc;\n}\n\nstatic int rshim_ap_q_write(struct adiv5_ap *ap, unsigned int reg,\n\t\t\t    uint32_t data)\n{\n\tint rc = ERROR_OK, tile;\n\tuint32_t addr;\n\n\tif (is_adiv6(ap->dap)) {\n\t\tstatic bool error_flagged;\n\t\tif (!error_flagged)\n\t\t\tLOG_ERROR(\"ADIv6 dap not supported by rshim dap-direct mode\");\n\t\terror_flagged = true;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (ap_bank != 0) {\n\t\trshim_dap_retval = ERROR_FAIL;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (reg) {\n\tcase ADIV5_MEM_AP_REG_CSW:\n\t\tap_csw = data;\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_TAR:\n\t\tap_tar = data;\n\t\tap_tar_inc = 0;\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_BD0:\n\tcase ADIV5_MEM_AP_REG_BD1:\n\tcase ADIV5_MEM_AP_REG_BD2:\n\tcase ADIV5_MEM_AP_REG_BD3:\n\t\taddr = (ap_tar & ~0xf) + (reg & 0x0C);\n\t\tap_addr_2_tile(&tile, &addr);\n\t\trc = coresight_write(tile, addr, data);\n\t\tbreak;\n\n\tcase ADIV5_MEM_AP_REG_DRW:\n\t\tap_drw = data;\n\t\taddr = (ap_tar & ~0x3) + ap_tar_inc;\n\t\tap_addr_2_tile(&tile, &addr);\n\t\trc = coresight_write(tile, addr, data);\n\t\tif (!rc && (ap_csw & CSW_ADDRINC_MASK))\n\t\t\tap_tar_inc += (ap_csw & 0x03) * 2;\n\t\tbreak;\n\n\tdefault:\n\t\trc = EINVAL;\n\t\tbreak;\n\t}\n\n\t/* Track the last error code. */\n\tif (rc != ERROR_OK)\n\t\trshim_dap_retval = rc;\n\n\treturn rc;\n}\n\nstatic int rshim_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dp_run(struct adiv5_dap *dap)\n{\n\tint retval = rshim_dap_retval;\n\n\t/* Clear the error code. */\n\trshim_dap_retval = ERROR_OK;\n\n\treturn retval;\n}\n\nstatic int rshim_connect(struct adiv5_dap *dap)\n{\n\tchar *path = rshim_dev_path ? rshim_dev_path : RSHIM_DEV_PATH_DEFAULT;\n\n\trshim_fd = open(path, O_RDWR | O_SYNC);\n\tif (rshim_fd == -1) {\n\t\tLOG_ERROR(\"Unable to open %s\\n\", path);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * Set read/write operation via the device file. Function pointers\n\t * are used here so more ways like remote accessing via socket could\n\t * be added later.\n\t */\n\trshim_read = rshim_dev_read;\n\trshim_write = rshim_dev_write;\n\n\treturn ERROR_OK;\n}\n\nstatic void rshim_disconnect(struct adiv5_dap *dap)\n{\n\tif (rshim_fd != -1) {\n\t\tclose(rshim_fd);\n\t\trshim_fd = -1;\n\t}\n}\n\nCOMMAND_HANDLER(rshim_dap_device_command)\n{\n\tif (CMD_ARGC != 1) {\n\t\tcommand_print(CMD, \"Too many arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tfree(rshim_dev_path);\n\trshim_dev_path = strdup(CMD_ARGV[0]);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration rshim_dap_subcommand_handlers[] = {\n\t{\n\t\t.name = \"device\",\n\t\t.handler = rshim_dap_device_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the rshim device\",\n\t\t.usage = \"</dev/rshim<N>/rshim>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration rshim_dap_command_handlers[] = {\n\t{\n\t\t.name = \"rshim\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform rshim management\",\n\t\t.chain = rshim_dap_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int rshim_dap_init(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dap_quit(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dap_reset(int req_trst, int req_srst)\n{\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dap_speed(int speed)\n{\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dap_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\treturn ERROR_OK;\n}\n\nstatic int rshim_dap_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\treturn ERROR_OK;\n}\n\n/* DAP operations. */\nstatic const struct dap_ops rshim_dap_ops = {\n\t.connect = rshim_connect,\n\t.queue_dp_read = rshim_dp_q_read,\n\t.queue_dp_write = rshim_dp_q_write,\n\t.queue_ap_read = rshim_ap_q_read,\n\t.queue_ap_write = rshim_ap_q_write,\n\t.queue_ap_abort = rshim_ap_q_abort,\n\t.run = rshim_dp_run,\n\t.quit = rshim_disconnect,\n};\n\nstatic const char *const rshim_dap_transport[] = { \"dapdirect_swd\", NULL };\n\nstruct adapter_driver rshim_dap_adapter_driver = {\n\t.name = \"rshim\",\n\t.transports = rshim_dap_transport,\n\t.commands = rshim_dap_command_handlers,\n\n\t.init = rshim_dap_init,\n\t.quit = rshim_dap_quit,\n\t.reset = rshim_dap_reset,\n\t.speed = rshim_dap_speed,\n\t.khz = rshim_dap_khz,\n\t.speed_div = rshim_dap_speed_div,\n\n\t.dap_swd_ops = &rshim_dap_ops,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/stlink_usb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2020 by Tarek Bochkati                                  *\n *   Tarek Bochkati <tarek.bouchkati@gmail.com>                            *\n *                                                                         *\n *   SWIM contributions by Ake Rehnman                                     *\n *   Copyright (C) 2017  Ake Rehnman                                       *\n *   ake.rehnman(at)gmail.com                                              *\n *                                                                         *\n *   Copyright (C) 2011-2012 by Mathias Kuester                            *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   This code is based on https://github.com/texane/stlink                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <helper/align.h>\n#include <helper/binarybuffer.h>\n#include <helper/bits.h>\n#include <helper/system.h>\n#include <helper/time_support.h>\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/hla/hla_layout.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n#include <jtag/swim.h>\n#include <target/arm_adi_v5.h>\n#include <target/target.h>\n#include <transport/transport.h>\n\n#include <target/cortex_m.h>\n\n#include <helper/system.h>\n\n#ifdef HAVE_ARPA_INET_H\n#include <arpa/inet.h>\n#endif\n\n#ifdef HAVE_NETINET_TCP_H\n#include <netinet/tcp.h>\n#endif\n\n#include \"libusb_helper.h\"\n\n#ifdef HAVE_LIBUSB1\n#define USE_LIBUSB_ASYNCIO\n#endif\n\n#define STLINK_SERIAL_LEN 24\n\n#define ENDPOINT_IN  0x80\n#define ENDPOINT_OUT 0x00\n\n#define STLINK_WRITE_TIMEOUT  (LIBUSB_TIMEOUT_MS)\n#define STLINK_READ_TIMEOUT   (LIBUSB_TIMEOUT_MS)\n\n#define STLINK_RX_EP          (1|ENDPOINT_IN)\n#define STLINK_TX_EP          (2|ENDPOINT_OUT)\n#define STLINK_TRACE_EP       (3|ENDPOINT_IN)\n\n#define STLINK_V2_1_TX_EP     (1|ENDPOINT_OUT)\n#define STLINK_V2_1_TRACE_EP  (2|ENDPOINT_IN)\n\n#define STLINK_SG_SIZE        (31)\n#define STLINK_DATA_SIZE      (6144)\n#define STLINK_CMD_SIZE_V2    (16)\n#define STLINK_CMD_SIZE_V1    (10)\n\n#define STLINK_V1_PID         (0x3744)\n#define STLINK_V2_PID         (0x3748)\n#define STLINK_V2_1_PID       (0x374B)\n#define STLINK_V2_1_NO_MSD_PID  (0x3752)\n#define STLINK_V3_USBLOADER_PID (0x374D)\n#define STLINK_V3E_PID          (0x374E)\n#define STLINK_V3S_PID          (0x374F)\n#define STLINK_V3_2VCP_PID      (0x3753)\n#define STLINK_V3E_NO_MSD_PID   (0x3754)\n#define STLINK_V3P_USBLOADER_PID (0x3755)\n#define STLINK_V3P_PID           (0x3757)\n\n/*\n * ST-Link/V1, ST-Link/V2 and ST-Link/V2.1 are full-speed USB devices and\n * this limits the bulk packet size and the 8bit read/writes to max 64 bytes.\n * STLINK-V3 is a high speed USB 2.0 and the limit is 512 bytes from FW V3J6.\n *\n * For 16 and 32bit read/writes stlink handles USB packet split and the limit\n * is the internal buffer size of 6144 bytes.\n * TODO: override ADIv5 layer's tar_autoincr_block that limits the transfer\n * to 1024 or 4096 bytes\n */\n#define STLINK_MAX_RW8          (64)\n#define STLINKV3_MAX_RW8        (512)\n#define STLINK_MAX_RW16_32      STLINK_DATA_SIZE\n#define STLINK_SWIM_DATA_SIZE   STLINK_DATA_SIZE\n\n/* \"WAIT\" responses will be retried (with exponential backoff) at\n * most this many times before failing to caller.\n */\n#define MAX_WAIT_RETRIES 8\n\n/* HLA is currently limited at AP#0 and no control on CSW */\n#define STLINK_HLA_AP_NUM       0\n#define STLINK_HLA_CSW          0\n\nenum stlink_jtag_api_version {\n\tSTLINK_JTAG_API_V1 = 1,\n\tSTLINK_JTAG_API_V2,\n\tSTLINK_JTAG_API_V3,\n};\n\nenum stlink_mode {\n\tSTLINK_MODE_UNKNOWN = 0,\n\tSTLINK_MODE_DFU,\n\tSTLINK_MODE_MASS,\n\tSTLINK_MODE_DEBUG_JTAG,\n\tSTLINK_MODE_DEBUG_SWD,\n\tSTLINK_MODE_DEBUG_SWIM\n};\n\n/** */\nstruct stlink_usb_version {\n\t/** */\n\tint stlink;\n\t/** */\n\tint jtag;\n\t/** */\n\tint swim;\n\t/** jtag api version supported */\n\tenum stlink_jtag_api_version jtag_api;\n\t/** one bit for each feature supported. See macros STLINK_F_* */\n\tuint32_t flags;\n};\n\nstruct stlink_usb_priv_s {\n\t/** */\n\tstruct libusb_device_handle *fd;\n\t/** */\n\tstruct libusb_transfer *trans;\n};\n\nstruct stlink_tcp_version {\n\tuint32_t api;\n\tuint32_t major;\n\tuint32_t minor;\n\tuint32_t build;\n};\n\nstruct stlink_tcp_priv_s {\n\t/** */\n\tint fd;\n\t/** */\n\tbool connected;\n\t/** */\n\tuint32_t device_id;\n\t/** */\n\tuint32_t connect_id;\n\t/** */\n\tuint8_t *send_buf;\n\t/** */\n\tuint8_t *recv_buf;\n\t/** */\n\tstruct stlink_tcp_version version;\n};\n\nstruct stlink_backend_s {\n\t/** */\n\tint (*open)(void *handle, struct hl_interface_param_s *param);\n\t/** */\n\tint (*close)(void *handle);\n\t/** */\n\tint (*xfer_noerrcheck)(void *handle, const uint8_t *buf, int size);\n\t/** */\n\tint (*read_trace)(void *handle, const uint8_t *buf, int size);\n};\n\n/* TODO: make queue size dynamic */\n/* TODO: don't allocate queue for HLA */\n#define MAX_QUEUE_DEPTH (4096)\n\nenum queue_cmd {\n\tCMD_DP_READ = 1,\n\tCMD_DP_WRITE,\n\n\tCMD_AP_READ,\n\tCMD_AP_WRITE,\n\n\t/*\n\t * encode the bytes size in the enum's value. This makes easy to extract it\n\t * with a simple logic AND, by using the macro CMD_MEM_AP_2_SIZE() below\n\t */\n\tCMD_MEM_AP_READ8   = 0x10 + 1,\n\tCMD_MEM_AP_READ16  = 0x10 + 2,\n\tCMD_MEM_AP_READ32  = 0x10 + 4,\n\n\tCMD_MEM_AP_WRITE8  = 0x20 + 1,\n\tCMD_MEM_AP_WRITE16 = 0x20 + 2,\n\tCMD_MEM_AP_WRITE32 = 0x20 + 4,\n};\n\n#define CMD_MEM_AP_2_SIZE(cmd) ((cmd) & 7)\n\nstruct dap_queue {\n\tenum queue_cmd cmd;\n\tunion {\n\t\tstruct dp_r {\n\t\t\tunsigned int reg;\n\t\t\tstruct adiv5_dap *dap;\n\t\t\tuint32_t *p_data;\n\t\t} dp_r;\n\t\tstruct dp_w {\n\t\t\tunsigned int reg;\n\t\t\tstruct adiv5_dap *dap;\n\t\t\tuint32_t data;\n\t\t} dp_w;\n\t\tstruct ap_r {\n\t\t\tunsigned int reg;\n\t\t\tstruct adiv5_ap *ap;\n\t\t\tuint32_t *p_data;\n\t\t} ap_r;\n\t\tstruct ap_w {\n\t\t\tunsigned int reg;\n\t\t\tstruct adiv5_ap *ap;\n\t\t\tuint32_t data;\n\t\t\tbool changes_csw_default;\n\t\t} ap_w;\n\t\tstruct mem_ap {\n\t\t\tuint32_t addr;\n\t\t\tstruct adiv5_ap *ap;\n\t\t\tunion {\n\t\t\t\tuint32_t *p_data;\n\t\t\t\tuint32_t data;\n\t\t\t};\n\t\t\tuint32_t csw;\n\t\t} mem_ap;\n\t};\n};\n\n/** */\nstruct stlink_usb_handle_s {\n\t/** */\n\tstruct stlink_backend_s *backend;\n\t/** */\n\tunion {\n\t\tstruct stlink_usb_priv_s usb_backend_priv;\n\t\tstruct stlink_tcp_priv_s tcp_backend_priv;\n\t};\n\t/** */\n\tuint8_t rx_ep;\n\t/** */\n\tuint8_t tx_ep;\n\t/** */\n\tuint8_t trace_ep;\n\t/** */\n\tuint8_t *cmdbuf;\n\t/** */\n\tuint8_t cmdidx;\n\t/** */\n\tuint8_t direction;\n\t/** */\n\tuint8_t *databuf;\n\t/** */\n\tuint32_t max_mem_packet;\n\t/** */\n\tenum stlink_mode st_mode;\n\t/** */\n\tstruct stlink_usb_version version;\n\t/** */\n\tuint16_t vid;\n\t/** */\n\tuint16_t pid;\n\t/** */\n\tstruct {\n\t\t/** whether SWO tracing is enabled or not */\n\t\tbool enabled;\n\t\t/** trace module source clock */\n\t\tuint32_t source_hz;\n\t} trace;\n\t/** reconnect is needed next time we try to query the\n\t * status */\n\tbool reconnect_pending;\n\t/** queue of dap_direct operations */\n\tstruct dap_queue queue[MAX_QUEUE_DEPTH];\n\t/** first element available in the queue */\n\tunsigned int queue_index;\n};\n\n/** */\nstatic inline int stlink_usb_open(void *handle, struct hl_interface_param_s *param)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\treturn h->backend->open(handle, param);\n}\n\n/** */\nstatic inline int stlink_usb_close(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\treturn h->backend->close(handle);\n}\n/** */\nstatic inline int stlink_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\treturn h->backend->xfer_noerrcheck(handle, buf, size);\n}\n\n#define STLINK_SWIM_ERR_OK             0x00\n#define STLINK_SWIM_BUSY               0x01\n#define STLINK_DEBUG_ERR_OK            0x80\n#define STLINK_DEBUG_ERR_FAULT         0x81\n#define STLINK_SWD_AP_WAIT             0x10\n#define STLINK_SWD_AP_FAULT            0x11\n#define STLINK_SWD_AP_ERROR            0x12\n#define STLINK_SWD_AP_PARITY_ERROR     0x13\n#define STLINK_JTAG_GET_IDCODE_ERROR   0x09\n#define STLINK_JTAG_WRITE_ERROR        0x0c\n#define STLINK_JTAG_WRITE_VERIF_ERROR  0x0d\n#define STLINK_SWD_DP_WAIT             0x14\n#define STLINK_SWD_DP_FAULT            0x15\n#define STLINK_SWD_DP_ERROR            0x16\n#define STLINK_SWD_DP_PARITY_ERROR     0x17\n\n#define STLINK_SWD_AP_WDATA_ERROR      0x18\n#define STLINK_SWD_AP_STICKY_ERROR     0x19\n#define STLINK_SWD_AP_STICKYORUN_ERROR 0x1a\n\n#define STLINK_BAD_AP_ERROR            0x1d\n\n#define STLINK_CORE_RUNNING            0x80\n#define STLINK_CORE_HALTED             0x81\n#define STLINK_CORE_STAT_UNKNOWN       -1\n\n#define STLINK_GET_VERSION             0xF1\n#define STLINK_DEBUG_COMMAND           0xF2\n#define STLINK_DFU_COMMAND             0xF3\n#define STLINK_SWIM_COMMAND            0xF4\n#define STLINK_GET_CURRENT_MODE        0xF5\n#define STLINK_GET_TARGET_VOLTAGE      0xF7\n\n#define STLINK_DEV_DFU_MODE            0x00\n#define STLINK_DEV_MASS_MODE           0x01\n#define STLINK_DEV_DEBUG_MODE          0x02\n#define STLINK_DEV_SWIM_MODE           0x03\n#define STLINK_DEV_BOOTLOADER_MODE     0x04\n#define STLINK_DEV_UNKNOWN_MODE        -1\n\n#define STLINK_DFU_EXIT                0x07\n\n/*\n\tSTLINK_SWIM_ENTER_SEQ\n\t1.3ms low then 750Hz then 1.5kHz\n\n\tSTLINK_SWIM_GEN_RST\n\tSTM8 DM pulls reset pin low 50us\n\n\tSTLINK_SWIM_SPEED\n\tuint8_t (0=low|1=high)\n\n\tSTLINK_SWIM_WRITEMEM\n\tuint16_t length\n\tuint32_t address\n\n\tSTLINK_SWIM_RESET\n\tsend synchronization seq (16us low, response 64 clocks low)\n*/\n#define STLINK_SWIM_ENTER                  0x00\n#define STLINK_SWIM_EXIT                   0x01\n#define STLINK_SWIM_READ_CAP               0x02\n#define STLINK_SWIM_SPEED                  0x03\n#define STLINK_SWIM_ENTER_SEQ              0x04\n#define STLINK_SWIM_GEN_RST                0x05\n#define STLINK_SWIM_RESET                  0x06\n#define STLINK_SWIM_ASSERT_RESET           0x07\n#define STLINK_SWIM_DEASSERT_RESET         0x08\n#define STLINK_SWIM_READSTATUS             0x09\n#define STLINK_SWIM_WRITEMEM               0x0a\n#define STLINK_SWIM_READMEM                0x0b\n#define STLINK_SWIM_READBUF                0x0c\n\n#define STLINK_DEBUG_GETSTATUS             0x01\n#define STLINK_DEBUG_FORCEDEBUG            0x02\n#define STLINK_DEBUG_APIV1_RESETSYS        0x03\n#define STLINK_DEBUG_APIV1_READALLREGS     0x04\n#define STLINK_DEBUG_APIV1_READREG         0x05\n#define STLINK_DEBUG_APIV1_WRITEREG        0x06\n#define STLINK_DEBUG_READMEM_32BIT         0x07\n#define STLINK_DEBUG_WRITEMEM_32BIT        0x08\n#define STLINK_DEBUG_RUNCORE               0x09\n#define STLINK_DEBUG_STEPCORE              0x0a\n#define STLINK_DEBUG_APIV1_SETFP           0x0b\n#define STLINK_DEBUG_READMEM_8BIT          0x0c\n#define STLINK_DEBUG_WRITEMEM_8BIT         0x0d\n#define STLINK_DEBUG_APIV1_CLEARFP         0x0e\n#define STLINK_DEBUG_APIV1_WRITEDEBUGREG   0x0f\n#define STLINK_DEBUG_APIV1_SETWATCHPOINT   0x10\n\n#define STLINK_DEBUG_ENTER_JTAG_RESET      0x00\n#define STLINK_DEBUG_ENTER_SWD_NO_RESET    0xa3\n#define STLINK_DEBUG_ENTER_JTAG_NO_RESET   0xa4\n\n#define STLINK_DEBUG_APIV1_ENTER           0x20\n#define STLINK_DEBUG_EXIT                  0x21\n#define STLINK_DEBUG_READCOREID            0x22\n\n#define STLINK_DEBUG_APIV2_ENTER           0x30\n#define STLINK_DEBUG_APIV2_READ_IDCODES    0x31\n#define STLINK_DEBUG_APIV2_RESETSYS        0x32\n#define STLINK_DEBUG_APIV2_READREG         0x33\n#define STLINK_DEBUG_APIV2_WRITEREG        0x34\n#define STLINK_DEBUG_APIV2_WRITEDEBUGREG   0x35\n#define STLINK_DEBUG_APIV2_READDEBUGREG    0x36\n\n#define STLINK_DEBUG_APIV2_READALLREGS     0x3A\n#define STLINK_DEBUG_APIV2_GETLASTRWSTATUS 0x3B\n#define STLINK_DEBUG_APIV2_DRIVE_NRST      0x3C\n\n#define STLINK_DEBUG_APIV2_GETLASTRWSTATUS2 0x3E\n\n#define STLINK_DEBUG_APIV2_START_TRACE_RX  0x40\n#define STLINK_DEBUG_APIV2_STOP_TRACE_RX   0x41\n#define STLINK_DEBUG_APIV2_GET_TRACE_NB    0x42\n#define STLINK_DEBUG_APIV2_SWD_SET_FREQ    0x43\n#define STLINK_DEBUG_APIV2_JTAG_SET_FREQ   0x44\n#define STLINK_DEBUG_APIV2_READ_DAP_REG    0x45\n#define STLINK_DEBUG_APIV2_WRITE_DAP_REG   0x46\n#define STLINK_DEBUG_APIV2_READMEM_16BIT   0x47\n#define STLINK_DEBUG_APIV2_WRITEMEM_16BIT  0x48\n\n#define STLINK_DEBUG_APIV2_INIT_AP         0x4B\n#define STLINK_DEBUG_APIV2_CLOSE_AP_DBG    0x4C\n\n#define STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC         0x50\n#define STLINK_DEBUG_APIV2_RW_MISC_OUT     0x51\n#define STLINK_DEBUG_APIV2_RW_MISC_IN      0x52\n\n#define STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC          0x54\n\n#define STLINK_APIV3_SET_COM_FREQ           0x61\n#define STLINK_APIV3_GET_COM_FREQ           0x62\n\n#define STLINK_APIV3_GET_VERSION_EX         0xFB\n\n#define STLINK_DEBUG_APIV2_DRIVE_NRST_LOW   0x00\n#define STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH  0x01\n#define STLINK_DEBUG_APIV2_DRIVE_NRST_PULSE 0x02\n\n#define STLINK_DEBUG_PORT_ACCESS            0xffff\n\n#define STLINK_TRACE_SIZE               4096\n#define STLINK_TRACE_MAX_HZ             2000000\n#define STLINK_V3_TRACE_MAX_HZ          24000000\n\n#define STLINK_V3_MAX_FREQ_NB               10\n\n#define REQUEST_SENSE        0x03\n#define REQUEST_SENSE_LENGTH 18\n\n/* STLINK TCP commands */\n#define STLINK_TCP_CMD_REFRESH_DEVICE_LIST   0x00\n#define STLINK_TCP_CMD_GET_NB_DEV            0x01\n#define STLINK_TCP_CMD_GET_DEV_INFO          0x02\n#define STLINK_TCP_CMD_OPEN_DEV              0x03\n#define STLINK_TCP_CMD_CLOSE_DEV             0x04\n#define STLINK_TCP_CMD_SEND_USB_CMD          0x05\n#define STLINK_TCP_CMD_GET_SERVER_VERSION    0x06\n#define STLINK_TCP_CMD_GET_NB_OF_DEV_CLIENTS 0x07\n\n/* STLINK TCP constants */\n#define OPENOCD_STLINK_TCP_API_VERSION       1\n#define STLINK_TCP_REQUEST_WRITE             0\n#define STLINK_TCP_REQUEST_READ              1\n#define STLINK_TCP_REQUEST_READ_SWO          3\n#define STLINK_TCP_SS_SIZE                   4\n#define STLINK_TCP_USB_CMD_SIZE              32\n#define STLINK_TCP_SERIAL_SIZE               32\n#define STLINK_TCP_SEND_BUFFER_SIZE          10240\n#define STLINK_TCP_RECV_BUFFER_SIZE          10240\n\n/* STLINK TCP command status */\n#define STLINK_TCP_SS_OK                     0x00000001\n#define STLINK_TCP_SS_MEMORY_PROBLEM         0x00001000\n#define STLINK_TCP_SS_TIMEOUT                0x00001001\n#define STLINK_TCP_SS_BAD_PARAMETER          0x00001002\n#define STLINK_TCP_SS_OPEN_ERR               0x00001003\n#define STLINK_TCP_SS_TRUNCATED_DATA         0x00001052\n#define STLINK_TCP_SS_CMD_NOT_AVAILABLE      0x00001053\n#define STLINK_TCP_SS_TCP_ERROR              0x00002001\n#define STLINK_TCP_SS_TCP_CANT_CONNECT       0x00002002\n#define STLINK_TCP_SS_TCP_CLOSE_ERROR        0x00002003\n#define STLINK_TCP_SS_TCP_BUSY               0x00002004\n#define STLINK_TCP_SS_WIN32_ERROR            0x00010000\n\n/*\n * Map the relevant features, quirks and workaround for specific firmware\n * version of stlink\n */\n#define STLINK_F_HAS_TRACE              BIT(0)  /* v2>=j13 || v3     */\n#define STLINK_F_HAS_GETLASTRWSTATUS2   BIT(1)  /* v2>=j15 || v3     */\n#define STLINK_F_HAS_SWD_SET_FREQ       BIT(2)  /* v2>=j22           */\n#define STLINK_F_HAS_JTAG_SET_FREQ      BIT(3)  /* v2>=j24           */\n#define STLINK_F_QUIRK_JTAG_DP_READ     BIT(4)  /* v2>=j24 && v2<j32 */\n#define STLINK_F_HAS_DAP_REG            BIT(5)  /* v2>=j24 || v3     */\n#define STLINK_F_HAS_MEM_16BIT          BIT(6)  /* v2>=j26 || v3     */\n#define STLINK_F_HAS_AP_INIT            BIT(7)  /* v2>=j28 || v3     */\n#define STLINK_F_FIX_CLOSE_AP           BIT(8)  /* v2>=j29 || v3     */\n#define STLINK_F_HAS_DPBANKSEL          BIT(9)  /* v2>=j32 || v3>=j2 */\n#define STLINK_F_HAS_RW8_512BYTES       BIT(10) /*            v3>=j6 */\n\n/* aliases */\n#define STLINK_F_HAS_TARGET_VOLT        STLINK_F_HAS_TRACE\n#define STLINK_F_HAS_FPU_REG            STLINK_F_HAS_GETLASTRWSTATUS2\n#define STLINK_F_HAS_MEM_WR_NO_INC      STLINK_F_HAS_MEM_16BIT\n#define STLINK_F_HAS_MEM_RD_NO_INC      STLINK_F_HAS_DPBANKSEL\n#define STLINK_F_HAS_RW_MISC            STLINK_F_HAS_DPBANKSEL\n#define STLINK_F_HAS_CSW                STLINK_F_HAS_DPBANKSEL\n\n#define STLINK_REGSEL_IS_FPU(x)         ((x) > 0x1F)\n\nstruct speed_map {\n\tint speed;\n\tint speed_divisor;\n};\n\n/* SWD clock speed */\nstatic const struct speed_map stlink_khz_to_speed_map_swd[] = {\n\t{4000, 0},\n\t{1800, 1}, /* default */\n\t{1200, 2},\n\t{950,  3},\n\t{480,  7},\n\t{240, 15},\n\t{125, 31},\n\t{100, 40},\n\t{50,  79},\n\t{25, 158},\n\t{15, 265},\n\t{5,  798}\n};\n\n/* JTAG clock speed */\nstatic const struct speed_map stlink_khz_to_speed_map_jtag[] = {\n\t{9000,  4},\n\t{4500,  8},\n\t{2250, 16},\n\t{1125, 32}, /* default */\n\t{562,  64},\n\t{281, 128},\n\t{140, 256}\n};\n\nstatic void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size);\nstatic int stlink_swim_status(void *handle);\nstatic void stlink_dump_speed_map(const struct speed_map *map, unsigned int map_size);\nstatic int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map);\nstatic int stlink_speed(void *handle, int khz, bool query);\nstatic int stlink_usb_open_ap(void *handle, unsigned short apsel);\n\n/** */\nstatic unsigned int stlink_usb_block(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.flags & STLINK_F_HAS_RW8_512BYTES)\n\t\treturn STLINKV3_MAX_RW8;\n\telse\n\t\treturn STLINK_MAX_RW8;\n}\n\n#ifdef USE_LIBUSB_ASYNCIO\n\nstatic LIBUSB_CALL void sync_transfer_cb(struct libusb_transfer *transfer)\n{\n\tint *completed = transfer->user_data;\n\t*completed = 1;\n\t/* caller interprets result and frees transfer */\n}\n\n\nstatic void sync_transfer_wait_for_completion(struct libusb_transfer *transfer)\n{\n\tint r, *completed = transfer->user_data;\n\n\twhile (!*completed) {\n\t\tr = jtag_libusb_handle_events_completed(completed);\n\t\tif (r < 0) {\n\t\t\tif (r == LIBUSB_ERROR_INTERRUPTED)\n\t\t\t\tcontinue;\n\t\t\tlibusb_cancel_transfer(transfer);\n\t\t\tcontinue;\n\t\t}\n\t}\n}\n\n\nstatic int transfer_error_status(const struct libusb_transfer *transfer)\n{\n\tint r = 0;\n\n\tswitch (transfer->status) {\n\t\tcase LIBUSB_TRANSFER_COMPLETED:\n\t\t\tr = 0;\n\t\t\tbreak;\n\t\tcase LIBUSB_TRANSFER_TIMED_OUT:\n\t\t\tr = LIBUSB_ERROR_TIMEOUT;\n\t\t\tbreak;\n\t\tcase LIBUSB_TRANSFER_STALL:\n\t\t\tr = LIBUSB_ERROR_PIPE;\n\t\t\tbreak;\n\t\tcase LIBUSB_TRANSFER_OVERFLOW:\n\t\t\tr = LIBUSB_ERROR_OVERFLOW;\n\t\t\tbreak;\n\t\tcase LIBUSB_TRANSFER_NO_DEVICE:\n\t\t\tr = LIBUSB_ERROR_NO_DEVICE;\n\t\t\tbreak;\n\t\tcase LIBUSB_TRANSFER_ERROR:\n\t\tcase LIBUSB_TRANSFER_CANCELLED:\n\t\t\tr = LIBUSB_ERROR_IO;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tr = LIBUSB_ERROR_OTHER;\n\t\t\tbreak;\n\t}\n\n\treturn r;\n}\n\nstruct jtag_xfer {\n\tint ep;\n\tuint8_t *buf;\n\tsize_t size;\n\t/* Internal */\n\tint retval;\n\tint completed;\n\tsize_t transfer_size;\n\tstruct libusb_transfer *transfer;\n};\n\nstatic int jtag_libusb_bulk_transfer_n(\n\t\tstruct libusb_device_handle *dev_handle,\n\t\tstruct jtag_xfer *transfers,\n\t\tsize_t n_transfers,\n\t\tint timeout)\n{\n\tint retval = 0;\n\tint returnval = ERROR_OK;\n\n\n\tfor (size_t i = 0; i < n_transfers; ++i) {\n\t\ttransfers[i].retval = 0;\n\t\ttransfers[i].completed = 0;\n\t\ttransfers[i].transfer_size = 0;\n\t\ttransfers[i].transfer = libusb_alloc_transfer(0);\n\n\t\tif (!transfers[i].transfer) {\n\t\t\tfor (size_t j = 0; j < i; ++j)\n\t\t\t\tlibusb_free_transfer(transfers[j].transfer);\n\n\t\t\tLOG_DEBUG(\"ERROR, failed to alloc usb transfers\");\n\t\t\tfor (size_t k = 0; k < n_transfers; ++k)\n\t\t\t\ttransfers[k].retval = LIBUSB_ERROR_NO_MEM;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tfor (size_t i = 0; i < n_transfers; ++i) {\n\t\tlibusb_fill_bulk_transfer(\n\t\t\t\ttransfers[i].transfer,\n\t\t\t\tdev_handle,\n\t\t\t\ttransfers[i].ep, transfers[i].buf, transfers[i].size,\n\t\t\t\tsync_transfer_cb, &transfers[i].completed, timeout);\n\t\ttransfers[i].transfer->type = LIBUSB_TRANSFER_TYPE_BULK;\n\n\t\tretval = libusb_submit_transfer(transfers[i].transfer);\n\t\tif (retval < 0) {\n\t\t\tLOG_DEBUG(\"ERROR, failed to submit transfer %zu, error %d\", i, retval);\n\n\t\t\t/* Probably no point continuing to submit transfers once a submission fails.\n\t\t\t * As a result, tag all remaining transfers as errors.\n\t\t\t */\n\t\t\tfor (size_t j = i; j < n_transfers; ++j)\n\t\t\t\ttransfers[j].retval = retval;\n\n\t\t\treturnval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Wait for every submitted USB transfer to complete.\n\t*/\n\tfor (size_t i = 0; i < n_transfers; ++i) {\n\t\tif (transfers[i].retval == 0) {\n\t\t\tsync_transfer_wait_for_completion(transfers[i].transfer);\n\n\t\t\tretval = transfer_error_status(transfers[i].transfer);\n\t\t\tif (retval) {\n\t\t\t\treturnval = ERROR_FAIL;\n\t\t\t\ttransfers[i].retval = retval;\n\t\t\t\tLOG_DEBUG(\"ERROR, transfer %zu failed, error %d\", i, retval);\n\t\t\t} else {\n\t\t\t\t/* Assuming actual_length is only valid if there is no transfer error.\n\t\t\t\t */\n\t\t\t\ttransfers[i].transfer_size = transfers[i].transfer->actual_length;\n\t\t\t}\n\t\t}\n\n\t\tlibusb_free_transfer(transfers[i].transfer);\n\t\ttransfers[i].transfer = NULL;\n\t}\n\n\treturn returnval;\n}\n\n#endif\n\n\n/** */\nstatic int stlink_usb_xfer_v1_get_status(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint tr, ret;\n\n\tassert(handle);\n\n\t/* read status */\n\tmemset(h->cmdbuf, 0, STLINK_SG_SIZE);\n\n\tret = jtag_libusb_bulk_read(h->usb_backend_priv.fd, h->rx_ep, (char *)h->cmdbuf, 13,\n\t\t\t\t    STLINK_READ_TIMEOUT, &tr);\n\tif (ret || tr != 13)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t t1;\n\n\tt1 = buf_get_u32(h->cmdbuf, 0, 32);\n\n\t/* check for USBS */\n\tif (t1 != 0x53425355)\n\t\treturn ERROR_FAIL;\n\t/*\n\t * CSW status:\n\t * 0 success\n\t * 1 command failure\n\t * 2 phase error\n\t */\n\tif (h->cmdbuf[12] != 0)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n#ifdef USE_LIBUSB_ASYNCIO\nstatic int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tsize_t n_transfers = 0;\n\tstruct jtag_xfer transfers[2];\n\n\tmemset(transfers, 0, sizeof(transfers));\n\n\ttransfers[0].ep = h->tx_ep;\n\ttransfers[0].buf = h->cmdbuf;\n\ttransfers[0].size = cmdsize;\n\n\t++n_transfers;\n\n\tif (h->direction == h->tx_ep && size) {\n\t\ttransfers[1].ep = h->tx_ep;\n\t\ttransfers[1].buf = (uint8_t *)buf;\n\t\ttransfers[1].size = size;\n\n\t\t++n_transfers;\n\t} else if (h->direction == h->rx_ep && size) {\n\t\ttransfers[1].ep = h->rx_ep;\n\t\ttransfers[1].buf = (uint8_t *)buf;\n\t\ttransfers[1].size = size;\n\n\t\t++n_transfers;\n\t}\n\n\treturn jtag_libusb_bulk_transfer_n(\n\t\t\th->usb_backend_priv.fd,\n\t\t\ttransfers,\n\t\t\tn_transfers,\n\t\t\tSTLINK_WRITE_TIMEOUT);\n}\n#else\nstatic int stlink_usb_xfer_rw(void *handle, int cmdsize, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint tr, ret;\n\n\tassert(handle);\n\n\tret = jtag_libusb_bulk_write(h->usb_backend_priv.fd, h->tx_ep, (char *)h->cmdbuf,\n\t\t\t\t     cmdsize, STLINK_WRITE_TIMEOUT, &tr);\n\tif (ret || tr != cmdsize)\n\t\treturn ERROR_FAIL;\n\n\tif (h->direction == h->tx_ep && size) {\n\t\tret = jtag_libusb_bulk_write(h->usb_backend_priv.fd, h->tx_ep, (char *)buf,\n\t\t\t\t\t     size, STLINK_WRITE_TIMEOUT, &tr);\n\t\tif (ret || tr != size) {\n\t\t\tLOG_DEBUG(\"bulk write failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else if (h->direction == h->rx_ep && size) {\n\t\tret = jtag_libusb_bulk_read(h->usb_backend_priv.fd, h->rx_ep, (char *)buf,\n\t\t\t\t\t    size, STLINK_READ_TIMEOUT, &tr);\n\t\tif (ret || tr != size) {\n\t\t\tLOG_DEBUG(\"bulk read failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n#endif\n\n/** */\nstatic int stlink_usb_xfer_v1_get_sense(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\n\th->cmdbuf[h->cmdidx++] = REQUEST_SENSE;\n\th->cmdbuf[h->cmdidx++] = 0;\n\th->cmdbuf[h->cmdidx++] = 0;\n\th->cmdbuf[h->cmdidx++] = 0;\n\th->cmdbuf[h->cmdidx++] = REQUEST_SENSE_LENGTH;\n\n\tres = stlink_usb_xfer_rw(handle, REQUEST_SENSE_LENGTH, h->databuf, 16);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_usb_read_trace(void *handle, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint tr, ret;\n\n\tret = jtag_libusb_bulk_read(h->usb_backend_priv.fd, h->trace_ep, (char *)buf, size,\n\t\t\t\t    STLINK_READ_TIMEOUT, &tr);\n\tif (ret || tr != size) {\n\t\tLOG_ERROR(\"bulk trace read failed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n\ttransfers block in cmdbuf\n\t<size> indicates number of bytes in the following\n\tdata phase.\n\tIgnore the (eventual) error code in the received packet.\n*/\nstatic int stlink_usb_usb_xfer_noerrcheck(void *handle, const uint8_t *buf, int size)\n{\n\tint err, cmdsize = STLINK_CMD_SIZE_V2;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.stlink == 1) {\n\t\tcmdsize = STLINK_SG_SIZE;\n\t\t/* put length in bCBWCBLength */\n\t\th->cmdbuf[14] = h->cmdidx-15;\n\t}\n\n\terr = stlink_usb_xfer_rw(handle, cmdsize, buf, size);\n\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (h->version.stlink == 1) {\n\t\tif (stlink_usb_xfer_v1_get_status(handle) != ERROR_OK) {\n\t\t\t/* check csw status */\n\t\t\tif (h->cmdbuf[12] == 1) {\n\t\t\t\tLOG_DEBUG(\"get sense\");\n\t\t\t\tif (stlink_usb_xfer_v1_get_sense(handle) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int stlink_tcp_send_cmd(void *handle, int send_size, int recv_size, bool check_tcp_status)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* send the TCP command */\n\tint sent_size = send(h->tcp_backend_priv.fd, (void *)h->tcp_backend_priv.send_buf, send_size, 0);\n\tif (sent_size != send_size) {\n\t\tLOG_ERROR(\"failed to send USB CMD\");\n\t\tif (sent_size == -1)\n\t\t\tLOG_DEBUG(\"socket send error: %s (errno %d)\", strerror(errno), errno);\n\t\telse\n\t\t\tLOG_DEBUG(\"sent size %d (expected %d)\", sent_size, send_size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* read the TCP response */\n\tint retval = ERROR_OK;\n\tint remaining_bytes = recv_size;\n\tuint8_t *recv_buf = h->tcp_backend_priv.recv_buf;\n\tconst int64_t timeout = timeval_ms() + 1000; /* 1 second */\n\n\twhile (remaining_bytes > 0) {\n\t\tif (timeval_ms() > timeout) {\n\t\t\tLOG_DEBUG(\"received size %d (expected %d)\", recv_size - remaining_bytes, recv_size);\n\t\t\tretval = ERROR_TIMEOUT_REACHED;\n\t\t\tbreak;\n\t\t}\n\n\t\tkeep_alive();\n\t\tint received = recv(h->tcp_backend_priv.fd, (void *)recv_buf, remaining_bytes, 0);\n\n\t\tif (received == -1) {\n\t\t\tLOG_DEBUG(\"socket recv error: %s (errno %d)\", strerror(errno), errno);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\trecv_buf += received;\n\t\tremaining_bytes -= received;\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed to receive USB CMD response\");\n\t\treturn retval;\n\t}\n\n\tif (check_tcp_status) {\n\t\tuint32_t tcp_ss = le_to_h_u32(h->tcp_backend_priv.recv_buf);\n\t\tif (tcp_ss != STLINK_TCP_SS_OK) {\n\t\t\tif (tcp_ss == STLINK_TCP_SS_TCP_BUSY) {\n\t\t\t\tLOG_DEBUG(\"TCP busy\");\n\t\t\t\treturn ERROR_WAIT;\n\t\t\t}\n\n\t\t\tLOG_ERROR(\"TCP error status 0x%X\", tcp_ss);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_tcp_xfer_noerrcheck(void *handle, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tint send_size = STLINK_TCP_USB_CMD_SIZE;\n\tint recv_size = STLINK_TCP_SS_SIZE;\n\n\tassert(handle);\n\n\t/* prepare the TCP command */\n\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_SEND_USB_CMD;\n\tmemset(&h->tcp_backend_priv.send_buf[1], 0, 3); /* reserved for alignment and future use, must be zero */\n\th_u32_to_le(&h->tcp_backend_priv.send_buf[4], h->tcp_backend_priv.connect_id);\n\t/* tcp_backend_priv.send_buf[8..23] already contains the constructed stlink command */\n\th->tcp_backend_priv.send_buf[24] = h->direction;\n\tmemset(&h->tcp_backend_priv.send_buf[25], 0, 3);  /* reserved for alignment and future use, must be zero */\n\n\th_u32_to_le(&h->tcp_backend_priv.send_buf[28], size);\n\n\t/*\n\t * if the xfer is a write request (tx_ep)\n\t *  > then buf content will be copied\n\t * into &cmdbuf[32].\n\t * else : the xfer is a read or trace read request (rx_ep or trace_ep)\n\t *  > the buf content will be filled from &databuf[4].\n\t *\n\t * note : if h->direction is trace_ep, h->cmdbuf is zeros.\n\t */\n\n\tif (h->direction == h->tx_ep) { /* STLINK_TCP_REQUEST_WRITE */\n\t\tsend_size += size;\n\t\tif (send_size > STLINK_TCP_SEND_BUFFER_SIZE) {\n\t\t\tLOG_ERROR(\"STLINK_TCP command buffer overflow\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tmemcpy(&h->tcp_backend_priv.send_buf[32], buf, size);\n\t} else { /* STLINK_TCP_REQUEST_READ or STLINK_TCP_REQUEST_READ_SWO */\n\t\trecv_size += size;\n\t\tif (recv_size > STLINK_TCP_RECV_BUFFER_SIZE) {\n\t\t\tLOG_ERROR(\"STLINK_TCP data buffer overflow\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tint ret = stlink_tcp_send_cmd(h, send_size, recv_size, true);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (h->direction != h->tx_ep) {\n\t\t/* the read data is located in tcp_backend_priv.recv_buf[4] */\n\t\t/* most of the case it will be copying the data from tcp_backend_priv.recv_buf[4]\n\t\t * to handle->cmd_buff which are the same, so let's avoid unnecessary copying */\n\t\tif (buf != &h->tcp_backend_priv.recv_buf[4])\n\t\t\tmemcpy((uint8_t *)buf, &h->tcp_backend_priv.recv_buf[4], size);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_tcp_read_trace(void *handle, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tstlink_usb_init_buffer(h, h->trace_ep, 0);\n\treturn stlink_tcp_xfer_noerrcheck(handle, buf, size);\n}\n\n/**\n    Converts an STLINK status code held in the first byte of a response\n    to an openocd error, logs any error/wait status as debug output.\n*/\nstatic int stlink_usb_error_check(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->st_mode == STLINK_MODE_DEBUG_SWIM) {\n\t\tswitch (h->databuf[0]) {\n\t\t\tcase STLINK_SWIM_ERR_OK:\n\t\t\t\treturn ERROR_OK;\n\t\t\tcase STLINK_SWIM_BUSY:\n\t\t\t\treturn ERROR_WAIT;\n\t\t\tdefault:\n\t\t\t\tLOG_DEBUG(\"unknown/unexpected STLINK status code 0x%x\", h->databuf[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* TODO: no error checking yet on api V1 */\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\th->databuf[0] = STLINK_DEBUG_ERR_OK;\n\n\tswitch (h->databuf[0]) {\n\t\tcase STLINK_DEBUG_ERR_OK:\n\t\t\treturn ERROR_OK;\n\t\tcase STLINK_DEBUG_ERR_FAULT:\n\t\t\tLOG_DEBUG(\"SWD fault response (0x%x)\", STLINK_DEBUG_ERR_FAULT);\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_WAIT:\n\t\t\tLOG_DEBUG(\"wait status SWD_AP_WAIT (0x%x)\", STLINK_SWD_AP_WAIT);\n\t\t\treturn ERROR_WAIT;\n\t\tcase STLINK_SWD_DP_WAIT:\n\t\t\tLOG_DEBUG(\"wait status SWD_DP_WAIT (0x%x)\", STLINK_SWD_DP_WAIT);\n\t\t\treturn ERROR_WAIT;\n\t\tcase STLINK_JTAG_GET_IDCODE_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_JTAG_GET_IDCODE_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_JTAG_WRITE_ERROR:\n\t\t\tLOG_DEBUG(\"Write error\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_JTAG_WRITE_VERIF_ERROR:\n\t\t\tLOG_DEBUG(\"Write verify error, ignoring\");\n\t\t\treturn ERROR_OK;\n\t\tcase STLINK_SWD_AP_FAULT:\n\t\t\t/* git://git.ac6.fr/openocd commit 657e3e885b9ee10\n\t\t\t * returns ERROR_OK with the comment:\n\t\t\t * Change in error status when reading outside RAM.\n\t\t\t * This fix allows CDT plugin to visualize memory.\n\t\t\t */\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_FAULT\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_PARITY_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_PARITY_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_DP_FAULT:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_DP_FAULT\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_DP_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_DP_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_DP_PARITY_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_DP_PARITY_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_WDATA_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_WDATA_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_STICKY_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_STICKY_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_SWD_AP_STICKYORUN_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_SWD_AP_STICKYORUN_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase STLINK_BAD_AP_ERROR:\n\t\t\tLOG_DEBUG(\"STLINK_BAD_AP_ERROR\");\n\t\t\treturn ERROR_FAIL;\n\t\tdefault:\n\t\t\tLOG_DEBUG(\"unknown/unexpected STLINK status code 0x%x\", h->databuf[0]);\n\t\t\treturn ERROR_FAIL;\n\t}\n}\n\n/*\n * Wrapper around stlink_usb_xfer_noerrcheck()\n * to check the error code in the received packet\n */\nstatic int stlink_usb_xfer_errcheck(void *handle, const uint8_t *buf, int size)\n{\n\tint retval;\n\n\tassert(size > 0);\n\n\tretval = stlink_usb_xfer_noerrcheck(handle, buf, size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn stlink_usb_error_check(handle);\n}\n\n/** Issue an STLINK command via USB transfer, with retries on any wait status responses.\n\n    Works for commands where the STLINK_DEBUG status is returned in the first\n    byte of the response packet. For SWIM a SWIM_READSTATUS is requested instead.\n\n    Returns an openocd result code.\n*/\nstatic int stlink_cmd_allow_retry(void *handle, const uint8_t *buf, int size)\n{\n\tint retries = 0;\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\twhile (1) {\n\t\tif ((h->st_mode != STLINK_MODE_DEBUG_SWIM) || !retries) {\n\t\t\tres = stlink_usb_xfer_noerrcheck(handle, buf, size);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\n\t\tif (h->st_mode == STLINK_MODE_DEBUG_SWIM) {\n\t\t\tres = stlink_swim_status(handle);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\n\t\tres = stlink_usb_error_check(handle);\n\t\tif (res == ERROR_WAIT && retries < MAX_WAIT_RETRIES) {\n\t\t\tunsigned int delay_us = (1<<retries++) * 1000;\n\t\t\tLOG_DEBUG(\"stlink_cmd_allow_retry ERROR_WAIT, retry %d, delaying %u microseconds\", retries, delay_us);\n\t\t\tusleep(delay_us);\n\t\t\tcontinue;\n\t\t}\n\t\treturn res;\n\t}\n}\n\n/** */\nstatic int stlink_usb_read_trace(void *handle, const uint8_t *buf, int size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tassert(h->version.flags & STLINK_F_HAS_TRACE);\n\n\treturn h->backend->read_trace(handle, buf, size);\n}\n\n/*\n\tthis function writes transfer length in\n\tthe right place in the cb\n*/\nstatic void stlink_usb_set_cbw_transfer_datalength(void *handle, uint32_t size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tbuf_set_u32(h->cmdbuf+8, 0, 32, size);\n}\n\nstatic void stlink_usb_xfer_v1_create_cmd(void *handle, uint8_t direction, uint32_t size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\t/* fill the send buffer */\n\tstrcpy((char *)h->cmdbuf, \"USBC\");\n\th->cmdidx += 4;\n\t/* csw tag not used */\n\tbuf_set_u32(h->cmdbuf+h->cmdidx, 0, 32, 0);\n\th->cmdidx += 4;\n\t/* cbw data transfer length (in the following data phase in or out) */\n\tbuf_set_u32(h->cmdbuf+h->cmdidx, 0, 32, size);\n\th->cmdidx += 4;\n\t/* cbw flags */\n\th->cmdbuf[h->cmdidx++] = (direction == h->rx_ep ? ENDPOINT_IN : ENDPOINT_OUT);\n\th->cmdbuf[h->cmdidx++] = 0; /* lun */\n\t/* cdb clength (is filled in at xfer) */\n\th->cmdbuf[h->cmdidx++] = 0;\n}\n\n/** */\nstatic void stlink_usb_init_buffer(void *handle, uint8_t direction, uint32_t size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\th->direction = direction;\n\n\th->cmdidx = 0;\n\n\tmemset(h->cmdbuf, 0, STLINK_SG_SIZE);\n\tmemset(h->databuf, 0, STLINK_DATA_SIZE);\n\n\tif (h->version.stlink == 1)\n\t\tstlink_usb_xfer_v1_create_cmd(handle, direction, size);\n}\n\n/** */\nstatic int stlink_usb_version(void *handle)\n{\n\tint res;\n\tuint32_t flags;\n\tuint16_t version;\n\tuint8_t v, x, y, jtag, swim, msd, bridge = 0;\n\tchar v_str[5 * (1 + 3) + 1]; /* VvJjMmBbSs */\n\tchar *p;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 6);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_GET_VERSION;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 6);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tversion = be_to_h_u16(h->databuf);\n\tv = (version >> 12) & 0x0f;\n\tx = (version >> 6) & 0x3f;\n\ty = version & 0x3f;\n\n\th->vid = le_to_h_u16(h->databuf + 2);\n\th->pid = le_to_h_u16(h->databuf + 4);\n\n\tswitch (h->pid) {\n\tcase STLINK_V2_1_PID:\n\tcase STLINK_V2_1_NO_MSD_PID:\n\t\tif ((x <= 22 && y == 7) || (x >= 25 && y >= 7 && y <= 12)) {\n\t\t\t/* MxSy : STM8 V2.1 - SWIM only */\n\t\t\tmsd = x;\n\t\t\tswim = y;\n\t\t\tjtag = 0;\n\t\t} else {\n\t\t\t/* JxMy : STM32 V2.1 - JTAG/SWD only */\n\t\t\tjtag = x;\n\t\t\tmsd = y;\n\t\t\tswim = 0;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tjtag = x;\n\t\tswim = y;\n\t\tmsd = 0;\n\t\tbreak;\n\t}\n\n\t/* STLINK-V3 & STLINK-V3P require a specific command */\n\tif (v >= 3 && x == 0 && y == 0) {\n\t\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\n\t\th->cmdbuf[h->cmdidx++] = STLINK_APIV3_GET_VERSION_EX;\n\n\t\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 12);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tv = h->databuf[0];\n\t\tswim = h->databuf[1];\n\t\tjtag = h->databuf[2];\n\t\tmsd  = h->databuf[3];\n\t\tbridge = h->databuf[4];\n\t\th->vid = le_to_h_u16(h->databuf + 8);\n\t\th->pid = le_to_h_u16(h->databuf + 10);\n\t}\n\n\th->version.stlink = v;\n\th->version.jtag = jtag;\n\th->version.swim = swim;\n\n\tflags = 0;\n\tswitch (h->version.stlink) {\n\tcase 1:\n\t\t/* ST-LINK/V1 from J11 switch to api-v2 (and support SWD) */\n\t\tif (h->version.jtag >= 11)\n\t\t\th->version.jtag_api = STLINK_JTAG_API_V2;\n\t\telse\n\t\t\th->version.jtag_api = STLINK_JTAG_API_V1;\n\n\t\tbreak;\n\tcase 2:\n\t\t/* all ST-LINK/V2 and ST-Link/V2.1 use api-v2 */\n\t\th->version.jtag_api = STLINK_JTAG_API_V2;\n\n\t\t/* API for trace from J13 */\n\t\t/* API for target voltage from J13 */\n\t\tif (h->version.jtag >= 13)\n\t\t\tflags |= STLINK_F_HAS_TRACE;\n\n\t\t/* preferred API to get last R/W status from J15 */\n\t\tif (h->version.jtag >= 15)\n\t\t\tflags |= STLINK_F_HAS_GETLASTRWSTATUS2;\n\n\t\t/* API to set SWD frequency from J22 */\n\t\tif (h->version.jtag >= 22)\n\t\t\tflags |= STLINK_F_HAS_SWD_SET_FREQ;\n\n\t\t/* API to set JTAG frequency from J24 */\n\t\t/* API to access DAP registers from J24 */\n\t\tif (h->version.jtag >= 24) {\n\t\t\tflags |= STLINK_F_HAS_JTAG_SET_FREQ;\n\t\t\tflags |= STLINK_F_HAS_DAP_REG;\n\t\t}\n\n\t\t/* Quirk for read DP in JTAG mode (V2 only) from J24, fixed in J32 */\n\t\tif (h->version.jtag >= 24 && h->version.jtag < 32)\n\t\t\tflags |= STLINK_F_QUIRK_JTAG_DP_READ;\n\n\t\t/* API to read/write memory at 16 bit from J26 */\n\t\t/* API to write memory without address increment from J26 */\n\t\tif (h->version.jtag >= 26)\n\t\t\tflags |= STLINK_F_HAS_MEM_16BIT;\n\n\t\t/* API required to init AP before any AP access from J28 */\n\t\tif (h->version.jtag >= 28)\n\t\t\tflags |= STLINK_F_HAS_AP_INIT;\n\n\t\t/* API required to return proper error code on close AP from J29 */\n\t\tif (h->version.jtag >= 29)\n\t\t\tflags |= STLINK_F_FIX_CLOSE_AP;\n\n\t\t/* Banked regs (DPv1 & DPv2) support from V2J32 */\n\t\t/* API to read memory without address increment from V2J32 */\n\t\t/* Memory R/W supports CSW from V2J32 */\n\t\tif (h->version.jtag >= 32)\n\t\t\tflags |= STLINK_F_HAS_DPBANKSEL;\n\n\t\tbreak;\n\tcase 3:\n\t\t/* all STLINK-V3 use api-v3 */\n\t\th->version.jtag_api = STLINK_JTAG_API_V3;\n\n\t\t/* STLINK-V3 is a superset of ST-LINK/V2 */\n\n\t\t/* API for trace */\n\t\t/* API for target voltage */\n\t\tflags |= STLINK_F_HAS_TRACE;\n\n\t\t/* preferred API to get last R/W status */\n\t\tflags |= STLINK_F_HAS_GETLASTRWSTATUS2;\n\n\t\t/* API to access DAP registers */\n\t\tflags |= STLINK_F_HAS_DAP_REG;\n\n\t\t/* API to read/write memory at 16 bit */\n\t\t/* API to write memory without address increment */\n\t\tflags |= STLINK_F_HAS_MEM_16BIT;\n\n\t\t/* API required to init AP before any AP access */\n\t\tflags |= STLINK_F_HAS_AP_INIT;\n\n\t\t/* API required to return proper error code on close AP */\n\t\tflags |= STLINK_F_FIX_CLOSE_AP;\n\n\t\t/* Banked regs (DPv1 & DPv2) support from V3J2 */\n\t\t/* API to read memory without address increment from V3J2 */\n\t\t/* Memory R/W supports CSW from V3J2 */\n\t\tif (h->version.jtag >= 2)\n\t\t\tflags |= STLINK_F_HAS_DPBANKSEL;\n\n\t\t/* 8bit read/write max packet size 512 bytes from V3J6 */\n\t\tif (h->version.jtag >= 6)\n\t\t\tflags |= STLINK_F_HAS_RW8_512BYTES;\n\n\t\tbreak;\n\tcase 4:\n\t\t/* STLINK-V3P use api-v3 */\n\t\th->version.jtag_api = STLINK_JTAG_API_V3;\n\n\t\t/* STLINK-V3P is a superset of ST-LINK/V3 */\n\n\t\t/* API for trace */\n\t\t/* API for target voltage */\n\t\tflags |= STLINK_F_HAS_TRACE;\n\n\t\t/* preferred API to get last R/W status */\n\t\tflags |= STLINK_F_HAS_GETLASTRWSTATUS2;\n\n\t\t/* API to access DAP registers */\n\t\tflags |= STLINK_F_HAS_DAP_REG;\n\n\t\t/* API to read/write memory at 16 bit */\n\t\t/* API to write memory without address increment */\n\t\tflags |= STLINK_F_HAS_MEM_16BIT;\n\n\t\t/* API required to init AP before any AP access */\n\t\tflags |= STLINK_F_HAS_AP_INIT;\n\n\t\t/* API required to return proper error code on close AP */\n\t\tflags |= STLINK_F_FIX_CLOSE_AP;\n\n\t\t/* Banked regs (DPv1 & DPv2) support */\n\t\t/* API to read memory without address increment */\n\t\t/* Memory R/W supports CSW */\n\t\tflags |= STLINK_F_HAS_DPBANKSEL;\n\n\t\t/* 8bit read/write max packet size 512 bytes */\n\t\tflags |= STLINK_F_HAS_RW8_512BYTES;\n\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\th->version.flags = flags;\n\n\tp = v_str;\n\tp += sprintf(p, \"V%d\", v);\n\tif (jtag || !msd)\n\t\tp += sprintf(p, \"J%d\", jtag);\n\tif (msd)\n\t\tp += sprintf(p, \"M%d\", msd);\n\tif (bridge)\n\t\tp += sprintf(p, \"B%d\", bridge);\n\tif (swim || !msd)\n\t\tsprintf(p, \"S%d\", swim);\n\n\tLOG_INFO(\"STLINK %s (API v%d) VID:PID %04X:%04X\",\n\t\tv_str,\n\t\th->version.jtag_api,\n\t\th->vid,\n\t\th->pid);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_check_voltage(void *handle, float *target_voltage)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tuint32_t adc_results[2];\n\n\t/* no error message, simply quit with error */\n\tif (!(h->version.flags & STLINK_F_HAS_TARGET_VOLT))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 8);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_GET_TARGET_VOLTAGE;\n\n\tint result = stlink_usb_xfer_noerrcheck(handle, h->databuf, 8);\n\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* convert result */\n\tadc_results[0] = le_to_h_u32(h->databuf);\n\tadc_results[1] = le_to_h_u32(h->databuf + 4);\n\n\t*target_voltage = 0;\n\n\tif (adc_results[0])\n\t\t*target_voltage = 2 * ((float)adc_results[1]) * (float)(1.2 / adc_results[0]);\n\n\tLOG_INFO(\"Target voltage: %f\", (double)*target_voltage);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_set_swdclk(void *handle, uint16_t clk_divisor)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_SWD_SET_FREQ))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_SWD_SET_FREQ;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, clk_divisor);\n\th->cmdidx += 2;\n\n\tint result = stlink_cmd_allow_retry(handle, h->databuf, 2);\n\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_set_jtagclk(void *handle, uint16_t clk_divisor)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_JTAG_SET_FREQ;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, clk_divisor);\n\th->cmdidx += 2;\n\n\tint result = stlink_cmd_allow_retry(handle, h->databuf, 2);\n\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_current_mode(void *handle, uint8_t *mode)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_GET_CURRENT_MODE;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t*mode = h->databuf[0];\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_mode_enter(void *handle, enum stlink_mode type)\n{\n\tint rx_size = 0;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* on api V2 we are able the read the latest command\n\t * status\n\t * TODO: we need the test on api V1 too\n\t */\n\tif (h->version.jtag_api != STLINK_JTAG_API_V1)\n\t\trx_size = 2;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, rx_size);\n\n\tswitch (type) {\n\t\tcase STLINK_MODE_DEBUG_JTAG:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\t\t\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_ENTER;\n\t\t\telse\n\t\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_ENTER;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_ENTER_JTAG_NO_RESET;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_DEBUG_SWD:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\t\t\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_ENTER;\n\t\t\telse\n\t\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_ENTER;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_ENTER_SWD_NO_RESET;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_DEBUG_SWIM:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_ENTER;\n\t\t\t/* swim enter does not return any response or status */\n\t\t\treturn stlink_usb_xfer_noerrcheck(handle, h->databuf, 0);\n\t\tcase STLINK_MODE_DFU:\n\t\tcase STLINK_MODE_MASS:\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, rx_size);\n}\n\n/** */\nstatic int stlink_usb_mode_leave(void *handle, enum stlink_mode type)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* command with no reply, use a valid endpoint but zero size */\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\n\tswitch (type) {\n\t\tcase STLINK_MODE_DEBUG_JTAG:\n\t\tcase STLINK_MODE_DEBUG_SWD:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_EXIT;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_DEBUG_SWIM:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_EXIT;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_DFU:\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DFU_COMMAND;\n\t\t\th->cmdbuf[h->cmdidx++] = STLINK_DFU_EXIT;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_MASS:\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 0);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_assert_srst(void *handle, int srst);\n\nstatic enum stlink_mode stlink_get_mode(enum hl_transports t)\n{\n\tswitch (t) {\n\tcase HL_TRANSPORT_SWD:\n\t\treturn STLINK_MODE_DEBUG_SWD;\n\tcase HL_TRANSPORT_JTAG:\n\t\treturn STLINK_MODE_DEBUG_JTAG;\n\tdefault:\n\t\treturn STLINK_MODE_UNKNOWN;\n\t}\n}\n\n/** */\nstatic int stlink_usb_exit_mode(void *handle)\n{\n\tint res;\n\tuint8_t mode;\n\tenum stlink_mode emode;\n\n\tassert(handle);\n\n\tres = stlink_usb_current_mode(handle, &mode);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tLOG_DEBUG(\"MODE: 0x%02X\", mode);\n\n\t/* try to exit current mode */\n\tswitch (mode) {\n\t\tcase STLINK_DEV_DFU_MODE:\n\t\t\temode = STLINK_MODE_DFU;\n\t\t\tbreak;\n\t\tcase STLINK_DEV_DEBUG_MODE:\n\t\t\temode = STLINK_MODE_DEBUG_SWD;\n\t\t\tbreak;\n\t\tcase STLINK_DEV_SWIM_MODE:\n\t\t\temode = STLINK_MODE_DEBUG_SWIM;\n\t\t\tbreak;\n\t\tcase STLINK_DEV_BOOTLOADER_MODE:\n\t\tcase STLINK_DEV_MASS_MODE:\n\t\tdefault:\n\t\t\temode = STLINK_MODE_UNKNOWN;\n\t\t\tbreak;\n\t}\n\n\tif (emode != STLINK_MODE_UNKNOWN)\n\t\treturn stlink_usb_mode_leave(handle, emode);\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_init_mode(void *handle, bool connect_under_reset, int initial_interface_speed)\n{\n\tint res;\n\tuint8_t mode;\n\tenum stlink_mode emode;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tres = stlink_usb_exit_mode(handle);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tres = stlink_usb_current_mode(handle, &mode);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* we check the target voltage here as an aid to debugging connection problems.\n\t * the stlink requires the target Vdd to be connected for reliable debugging.\n\t * this cmd is supported in all modes except DFU\n\t */\n\tif (mode != STLINK_DEV_DFU_MODE) {\n\n\t\tfloat target_voltage;\n\n\t\t/* check target voltage (if supported) */\n\t\tres = stlink_usb_check_voltage(h, &target_voltage);\n\n\t\tif (res != ERROR_OK) {\n\t\t\tif (res != ERROR_COMMAND_NOTFOUND)\n\t\t\t\tLOG_ERROR(\"voltage check failed\");\n\t\t\t/* attempt to continue as it is not a catastrophic failure */\n\t\t} else {\n\t\t\t/* check for a sensible target voltage, operating range is 1.65-5.5v\n\t\t\t * according to datasheet */\n\t\t\tif (target_voltage < 1.5)\n\t\t\t\tLOG_ERROR(\"target voltage may be too low for reliable debugging\");\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"MODE: 0x%02X\", mode);\n\n\t/* set selected mode */\n\temode = h->st_mode;\n\n\tif (emode == STLINK_MODE_UNKNOWN) {\n\t\tLOG_ERROR(\"selected mode (transport) not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* set the speed before entering the mode, as the chip discovery phase should be done at this speed too */\n\tif (emode == STLINK_MODE_DEBUG_JTAG) {\n\t\tif (h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ) {\n\t\t\tstlink_dump_speed_map(stlink_khz_to_speed_map_jtag, ARRAY_SIZE(stlink_khz_to_speed_map_jtag));\n\t\t\tstlink_speed(h, initial_interface_speed, false);\n\t\t}\n\t} else if (emode == STLINK_MODE_DEBUG_SWD) {\n\t\tif (h->version.flags & STLINK_F_HAS_SWD_SET_FREQ) {\n\t\t\tstlink_dump_speed_map(stlink_khz_to_speed_map_swd, ARRAY_SIZE(stlink_khz_to_speed_map_swd));\n\t\t\tstlink_speed(h, initial_interface_speed, false);\n\t\t}\n\t}\n\n\tif (h->version.jtag_api == STLINK_JTAG_API_V3 &&\n\t\t\t(emode == STLINK_MODE_DEBUG_JTAG || emode == STLINK_MODE_DEBUG_SWD)) {\n\t\tstruct speed_map map[STLINK_V3_MAX_FREQ_NB];\n\n\t\tstlink_get_com_freq(h, (emode == STLINK_MODE_DEBUG_JTAG), map);\n\t\tstlink_dump_speed_map(map, ARRAY_SIZE(map));\n\t\tstlink_speed(h, initial_interface_speed, false);\n\t}\n\n\t/* preliminary SRST assert:\n\t * We want SRST is asserted before activating debug signals (mode_enter).\n\t * As the required mode has not been set, the adapter may not know what pin to use.\n\t * Tested firmware STLINK v2 JTAG v29 API v2 SWIM v0 uses T_NRST pin by default\n\t * Tested firmware STLINK v2 JTAG v27 API v2 SWIM v6 uses T_NRST pin by default\n\t * after power on, SWIM_RST stays unchanged */\n\tif (connect_under_reset && emode != STLINK_MODE_DEBUG_SWIM)\n\t\tstlink_usb_assert_srst(handle, 0);\n\t\t/* do not check the return status here, we will\n\t\t   proceed and enter the desired mode below\n\t\t   and try asserting srst again. */\n\n\tres = stlink_usb_mode_enter(handle, emode);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* assert SRST again: a little bit late but now the adapter knows for sure what pin to use */\n\tif (connect_under_reset) {\n\t\tres = stlink_usb_assert_srst(handle, 0);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\tres = stlink_usb_current_mode(handle, &mode);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tLOG_DEBUG(\"MODE: 0x%02X\", mode);\n\n\treturn ERROR_OK;\n}\n\n/* request status from last swim request */\nstatic int stlink_swim_status(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 4);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_READSTATUS;\n\t/* error is checked by the caller */\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n/*\n\tthe purpose of this function is unknown...\n\tcapabilities? anyway for swim v6 it returns\n\t0001020600000000\n*/\n__attribute__((unused))\nstatic int stlink_swim_cap(void *handle, uint8_t *cap)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 8);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_READ_CAP;\n\th->cmdbuf[h->cmdidx++] = 0x01;\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 8);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tmemcpy(cap, h->databuf, 8);\n\treturn ERROR_OK;\n}\n\n/*\tdebug dongle assert/deassert sreset line */\nstatic int stlink_swim_assert_reset(void *handle, int reset)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\tif (!reset)\n\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_ASSERT_RESET;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_DEASSERT_RESET;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\n/*\n\tsend swim enter seq\n\t1.3ms low then 750Hz then 1.5kHz\n*/\nstatic int stlink_swim_enter(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_ENTER_SEQ;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\n/*\tswitch high/low speed swim */\nstatic int stlink_swim_speed(void *handle, int speed)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_SPEED;\n\tif (speed)\n\t\th->cmdbuf[h->cmdidx++] = 1;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = 0;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\n/*\n\tinitiate srst from swim.\n\tnrst is pulled low for 50us.\n*/\nstatic int stlink_swim_generate_rst(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_GEN_RST;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\n/*\n\tsend resynchronize sequence\n\tswim is pulled low for 16us\n\treply is 64 clks low\n*/\nstatic int stlink_swim_resync(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_RESET;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\nstatic int stlink_swim_writebytes(void *handle, uint32_t addr, uint32_t len, const uint8_t *data)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\tunsigned int i;\n\tunsigned int datalen = 0;\n\tint cmdsize = STLINK_CMD_SIZE_V2;\n\n\tif (len > STLINK_SWIM_DATA_SIZE)\n\t\treturn ERROR_FAIL;\n\n\tif (h->version.stlink == 1)\n\t\tcmdsize = STLINK_SG_SIZE;\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_WRITEMEM;\n\th_u16_to_be(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th_u32_to_be(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\tfor (i = 0; i < len; i++) {\n\t\tif (h->cmdidx == cmdsize)\n\t\t\th->databuf[datalen++] = *(data++);\n\t\telse\n\t\t\th->cmdbuf[h->cmdidx++] = *(data++);\n\t}\n\tif (h->version.stlink == 1)\n\t\tstlink_usb_set_cbw_transfer_datalength(handle, datalen);\n\n\tres = stlink_cmd_allow_retry(handle, h->databuf, datalen);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn ERROR_OK;\n}\n\nstatic int stlink_swim_readbytes(void *handle, uint32_t addr, uint32_t len, uint8_t *data)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tif (len > STLINK_SWIM_DATA_SIZE)\n\t\treturn ERROR_FAIL;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 0);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_READMEM;\n\th_u16_to_be(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th_u32_to_be(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, len);\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_SWIM_READBUF;\n\tres = stlink_usb_xfer_noerrcheck(handle, data, len);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_idcode(void *handle, uint32_t *idcode)\n{\n\tint res, offset;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\t/* there is no swim read core id cmd */\n\tif (h->st_mode == STLINK_MODE_DEBUG_SWIM) {\n\t\t*idcode = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 12);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1) {\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READCOREID;\n\n\t\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);\n\t\toffset = 0;\n\t} else {\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READ_IDCODES;\n\n\t\tres = stlink_usb_xfer_errcheck(handle, h->databuf, 12);\n\t\toffset = 4;\n\t}\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t*idcode = le_to_h_u32(h->databuf + offset);\n\n\tLOG_DEBUG(\"IDCODE: 0x%08\" PRIX32, *idcode);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_v2_read_debug_reg(void *handle, uint32_t addr, uint32_t *val)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint res;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 8);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READDEBUGREG;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\n\tres = stlink_cmd_allow_retry(handle, h->databuf, 8);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t*val = le_to_h_u32(h->databuf + 4);\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_WRITEDEBUGREG;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEDEBUGREG;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, val);\n\th->cmdidx += 4;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\n/** */\nstatic int stlink_usb_trace_read(void *handle, uint8_t *buf, size_t *size)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->trace.enabled && (h->version.flags & STLINK_F_HAS_TRACE)) {\n\t\tint res;\n\n\t\tstlink_usb_init_buffer(handle, h->rx_ep, 10);\n\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GET_TRACE_NB;\n\n\t\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\tsize_t bytes_avail = le_to_h_u16(h->databuf);\n\t\t*size = bytes_avail < *size ? bytes_avail : *size;\n\n\t\tif (*size > 0) {\n\t\t\tres = stlink_usb_read_trace(handle, buf, *size);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\t*size = 0;\n\treturn ERROR_OK;\n}\n\nstatic enum target_state stlink_usb_v2_get_status(void *handle)\n{\n\tint result;\n\tuint32_t status;\n\n\tresult = stlink_usb_v2_read_debug_reg(handle, DCB_DHCSR, &status);\n\tif  (result != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\n\tif (status & S_HALT)\n\t\treturn TARGET_HALTED;\n\telse if (status & S_RESET_ST)\n\t\treturn TARGET_RESET;\n\n\treturn TARGET_RUNNING;\n}\n\n/** */\nstatic enum target_state stlink_usb_state(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->reconnect_pending) {\n\t\tLOG_INFO(\"Previous state query failed, trying to reconnect\");\n\t\tres = stlink_usb_mode_enter(handle, h->st_mode);\n\t\tif (res != ERROR_OK)\n\t\t\treturn TARGET_UNKNOWN;\n\n\t\th->reconnect_pending = false;\n\t}\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V1) {\n\t\tres = stlink_usb_v2_get_status(handle);\n\t\tif (res == TARGET_UNKNOWN)\n\t\t\th->reconnect_pending = true;\n\t\treturn res;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_GETSTATUS;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);\n\n\tif (res != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\n\tif (h->databuf[0] == STLINK_CORE_RUNNING)\n\t\treturn TARGET_RUNNING;\n\tif (h->databuf[0] == STLINK_CORE_HALTED)\n\t\treturn TARGET_HALTED;\n\n\th->reconnect_pending = true;\n\n\treturn TARGET_UNKNOWN;\n}\n\nstatic int stlink_usb_assert_srst(void *handle, int srst)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->st_mode == STLINK_MODE_DEBUG_SWIM)\n\t\treturn stlink_swim_assert_reset(handle, srst);\n\n\tif (h->version.stlink == 1)\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_DRIVE_NRST;\n\th->cmdbuf[h->cmdidx++] = srst;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\n/** */\nstatic void stlink_usb_trace_disable(void *handle)\n{\n\tint res = ERROR_OK;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tassert(h->version.flags & STLINK_F_HAS_TRACE);\n\n\tLOG_DEBUG(\"Tracing: disable\");\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_STOP_TRACE_RX;\n\tres = stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n\n\tif (res == ERROR_OK)\n\t\th->trace.enabled = false;\n}\n\n\n/** */\nstatic int stlink_usb_trace_enable(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.flags & STLINK_F_HAS_TRACE) {\n\t\tstlink_usb_init_buffer(handle, h->rx_ep, 10);\n\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_START_TRACE_RX;\n\t\th_u16_to_le(h->cmdbuf+h->cmdidx, (uint16_t)STLINK_TRACE_SIZE);\n\t\th->cmdidx += 2;\n\t\th_u32_to_le(h->cmdbuf+h->cmdidx, h->trace.source_hz);\n\t\th->cmdidx += 4;\n\n\t\tres = stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n\n\t\tif (res == ERROR_OK)  {\n\t\t\th->trace.enabled = true;\n\t\t\tLOG_DEBUG(\"Tracing: recording at %\" PRIu32 \"Hz\", h->trace.source_hz);\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"Tracing is not supported by this version.\");\n\t\tres = ERROR_FAIL;\n\t}\n\n\treturn res;\n}\n\n/** */\nstatic int stlink_usb_reset(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint retval;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_RESETSYS;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RESETSYS;\n\n\tretval = stlink_cmd_allow_retry(handle, h->databuf, 2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (h->trace.enabled) {\n\t\tstlink_usb_trace_disable(h);\n\t\treturn stlink_usb_trace_enable(h);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_usb_run(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V1) {\n\t\tres = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);\n\n\t\treturn res;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_RUNCORE;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\n/** */\nstatic int stlink_usb_halt(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V1) {\n\t\tres = stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN);\n\n\t\treturn res;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_FORCEDEBUG;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\n/** */\nstatic int stlink_usb_step(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V1) {\n\t\t/* TODO: this emulates the v1 api, it should really use a similar auto mask isr\n\t\t * that the Cortex-M3 currently does. */\n\t\tstlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_MASKINTS|C_DEBUGEN);\n\t\tstlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_STEP|C_MASKINTS|C_DEBUGEN);\n\t\treturn stlink_usb_write_debug_reg(handle, DCB_DHCSR, DBGKEY|C_HALT|C_DEBUGEN);\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_STEPCORE;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\n/** */\nstatic int stlink_usb_read_regs(void *handle)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 88);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1) {\n\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READALLREGS;\n\t\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 84);\n\t\t/* regs data from offset 0 */\n\t} else {\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READALLREGS;\n\t\tres = stlink_usb_xfer_errcheck(handle, h->databuf, 88);\n\t\t/* status at offset 0, regs data from offset 4 */\n\t}\n\n\treturn res;\n}\n\n/** */\nstatic int stlink_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (STLINK_REGSEL_IS_FPU(regsel) && !(h->version.flags & STLINK_F_HAS_FPU_REG)) {\n\t\tres = stlink_usb_write_debug_reg(h, DCB_DCRSR, regsel & 0x7f);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\t/* FIXME: poll DHCSR.S_REGRDY before read DCRDR */\n\t\treturn stlink_usb_v2_read_debug_reg(h, DCB_DCRDR, val);\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, h->version.jtag_api == STLINK_JTAG_API_V1 ? 4 : 8);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_READREG;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READREG;\n\th->cmdbuf[h->cmdidx++] = regsel;\n\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1) {\n\t\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, 4);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\t*val = le_to_h_u32(h->databuf);\n\t\treturn ERROR_OK;\n\t} else {\n\t\tres = stlink_cmd_allow_retry(handle, h->databuf, 8);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\t*val = le_to_h_u32(h->databuf + 4);\n\t\treturn ERROR_OK;\n\t}\n}\n\n/** */\nstatic int stlink_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (STLINK_REGSEL_IS_FPU(regsel) && !(h->version.flags & STLINK_F_HAS_FPU_REG)) {\n\t\tint res = stlink_usb_write_debug_reg(h, DCB_DCRDR, val);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\n\t\treturn stlink_usb_write_debug_reg(h, DCB_DCRSR, DCRSR_WNR | (regsel & 0x7f));\n\t\t/* FIXME: poll DHCSR.S_REGRDY after write DCRSR */\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_WRITEREG;\n\telse\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEREG;\n\th->cmdbuf[h->cmdidx++] = regsel;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, val);\n\th->cmdidx += 4;\n\n\treturn stlink_cmd_allow_retry(handle, h->databuf, 2);\n}\n\nstatic int stlink_usb_get_rw_status(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\treturn ERROR_OK;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 2);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\tif (h->version.flags & STLINK_F_HAS_GETLASTRWSTATUS2) {\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS2;\n\t\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 12);\n\t} else {\n\t\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_GETLASTRWSTATUS;\n\t\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n\t}\n}\n\n/** */\nstatic int stlink_usb_read_mem8(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, uint8_t *buffer)\n{\n\tint res;\n\tuint16_t read_len = len;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\t/* max 8 bit read/write is 64 bytes or 512 bytes for v3 */\n\tif (len > stlink_usb_block(h)) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", stlink_usb_block(h));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, read_len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_8BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\t/* we need to fix read length for single bytes */\n\tif (read_len == 1)\n\t\tread_len++;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, read_len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tmemcpy(buffer, h->databuf, len);\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\n/** */\nstatic int stlink_usb_write_mem8(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, const uint8_t *buffer)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\t/* max 8 bit read/write is 64 bytes or 512 bytes for v3 */\n\tif (len > stlink_usb_block(h)) {\n\t\tLOG_DEBUG(\"max buffer length (%d) exceeded\", stlink_usb_block(h));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_8BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, buffer, len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\n/** */\nstatic int stlink_usb_read_mem16(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, uint8_t *buffer)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_MEM_16BIT))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 2 and half-word aligned */\n\tif (len % 2 || addr % 2) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READMEM_16BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tmemcpy(buffer, h->databuf, len);\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\n/** */\nstatic int stlink_usb_write_mem16(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, const uint8_t *buffer)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_MEM_16BIT))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 2 and half-word aligned */\n\tif (len % 2 || addr % 2) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITEMEM_16BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, buffer, len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\n/** */\nstatic int stlink_usb_read_mem32(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, uint8_t *buffer)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_32BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, h->databuf, len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tmemcpy(buffer, h->databuf, len);\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\n/** */\nstatic int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, const uint8_t *buffer)\n{\n\tint res;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif ((ap_num != 0 || csw != 0) && !(h->version.flags & STLINK_F_HAS_CSW))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT;\n\th_u32_to_le(h->cmdbuf+h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf+h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tres = stlink_usb_xfer_noerrcheck(handle, buffer, len);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\nstatic int stlink_usb_read_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, uint8_t *buffer)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle != NULL);\n\n\tif (!(h->version.flags & STLINK_F_HAS_MEM_RD_NO_INC))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC;\n\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf + h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tint retval = stlink_usb_xfer_noerrcheck(handle, h->databuf, len);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmemcpy(buffer, h->databuf, len);\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\nstatic int stlink_usb_write_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint16_t len, const uint8_t *buffer)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle != NULL);\n\n\tif (!(h->version.flags & STLINK_F_HAS_MEM_WR_NO_INC))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tif (len > STLINK_MAX_RW16_32) {\n\t\tLOG_DEBUG(\"max buffer (%d) length exceeded\", STLINK_MAX_RW16_32);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* data must be a multiple of 4 and word aligned */\n\tif (len % 4 || addr % 4) {\n\t\tLOG_DEBUG(\"Invalid data alignment\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, len);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC;\n\th_u32_to_le(h->cmdbuf + h->cmdidx, addr);\n\th->cmdidx += 4;\n\th_u16_to_le(h->cmdbuf + h->cmdidx, len);\n\th->cmdidx += 2;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\th_u24_to_le(h->cmdbuf + h->cmdidx, csw >> 8);\n\th->cmdidx += 3;\n\n\tint retval = stlink_usb_xfer_noerrcheck(handle, buffer, len);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn stlink_usb_get_rw_status(handle);\n}\n\nstatic uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t address)\n{\n\tuint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address));\n\tif (max_tar_block == 0)\n\t\tmax_tar_block = 4;\n\treturn max_tar_block;\n}\n\nstatic int stlink_usb_read_ap_mem(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tuint32_t bytes_remaining;\n\tint retries = 0;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\t/* switch to 8 bit if stlink does not support 16 bit memory read */\n\tif (size == 2 && !(h->version.flags & STLINK_F_HAS_MEM_16BIT))\n\t\tsize = 1;\n\n\twhile (count) {\n\t\tbytes_remaining = (size != 1) ?\n\t\t\t\tstlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h);\n\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\t/*\n\t\t * all stlink support 8/32bit memory read/writes and only from\n\t\t * stlink V2J26 there is support for 16 bit memory read/write.\n\t\t * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle\n\t\t * as 8bit access.\n\t\t */\n\t\tif (size != 1) {\n\t\t\t/* When in jtag mode the stlink uses the auto-increment functionality.\n\t\t\t * However it expects us to pass the data correctly, this includes\n\t\t\t * alignment and any page boundaries. We already do this as part of the\n\t\t\t * adi_v5 implementation, but the stlink is a hla adapter and so this\n\t\t\t * needs implementing manually.\n\t\t\t * currently this only affects jtag mode, according to ST they do single\n\t\t\t * access in SWD mode - but this may change and so we do it for both modes */\n\n\t\t\t/* we first need to check for any unaligned bytes */\n\t\t\tif (addr & (size - 1)) {\n\t\t\t\tuint32_t head_bytes = size - (addr & (size - 1));\n\t\t\t\tretval = stlink_usb_read_mem8(handle, ap_num, csw, addr, head_bytes, buffer);\n\t\t\t\tif (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) {\n\t\t\t\t\tusleep((1 << retries++) * 1000);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tbuffer += head_bytes;\n\t\t\t\taddr += head_bytes;\n\t\t\t\tcount -= head_bytes;\n\t\t\t\tbytes_remaining -= head_bytes;\n\t\t\t}\n\n\t\t\tif (bytes_remaining & (size - 1))\n\t\t\t\tretval = stlink_usb_read_ap_mem(handle, ap_num, csw, addr, 1, bytes_remaining, buffer);\n\t\t\telse if (size == 2)\n\t\t\t\tretval = stlink_usb_read_mem16(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\t\t\telse\n\t\t\t\tretval = stlink_usb_read_mem32(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\t\t} else {\n\t\t\tretval = stlink_usb_read_mem8(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\t\t}\n\n\t\tif (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) {\n\t\t\tusleep((1 << retries++) * 1000);\n\t\t\tcontinue;\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int stlink_usb_read_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, uint8_t *buffer)\n{\n\treturn stlink_usb_read_ap_mem(handle, STLINK_HLA_AP_NUM, STLINK_HLA_CSW,\n\t\t\t\t\t\t\t\t  addr, size, count, buffer);\n}\n\nstatic int stlink_usb_write_ap_mem(void *handle, uint8_t ap_num, uint32_t csw,\n\t\tuint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tuint32_t bytes_remaining;\n\tint retries = 0;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\t/* switch to 8 bit if stlink does not support 16 bit memory read */\n\tif (size == 2 && !(h->version.flags & STLINK_F_HAS_MEM_16BIT))\n\t\tsize = 1;\n\n\twhile (count) {\n\n\t\tbytes_remaining = (size != 1) ?\n\t\t\t\tstlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h);\n\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\t/*\n\t\t * all stlink support 8/32bit memory read/writes and only from\n\t\t * stlink V2J26 there is support for 16 bit memory read/write.\n\t\t * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle\n\t\t * as 8bit access.\n\t\t */\n\t\tif (size != 1) {\n\n\t\t\t/* When in jtag mode the stlink uses the auto-increment functionality.\n\t\t\t * However it expects us to pass the data correctly, this includes\n\t\t\t * alignment and any page boundaries. We already do this as part of the\n\t\t\t * adi_v5 implementation, but the stlink is a hla adapter and so this\n\t\t\t * needs implementing manually.\n\t\t\t * currently this only affects jtag mode, according to ST they do single\n\t\t\t * access in SWD mode - but this may change and so we do it for both modes */\n\n\t\t\t/* we first need to check for any unaligned bytes */\n\t\t\tif (addr & (size - 1)) {\n\n\t\t\t\tuint32_t head_bytes = size - (addr & (size - 1));\n\t\t\t\tretval = stlink_usb_write_mem8(handle, ap_num, csw, addr, head_bytes, buffer);\n\t\t\t\tif (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) {\n\t\t\t\t\tusleep((1<<retries++) * 1000);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tbuffer += head_bytes;\n\t\t\t\taddr += head_bytes;\n\t\t\t\tcount -= head_bytes;\n\t\t\t\tbytes_remaining -= head_bytes;\n\t\t\t}\n\n\t\t\tif (bytes_remaining & (size - 1))\n\t\t\t\tretval = stlink_usb_write_ap_mem(handle, ap_num, csw, addr, 1, bytes_remaining, buffer);\n\t\t\telse if (size == 2)\n\t\t\t\tretval = stlink_usb_write_mem16(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\t\t\telse\n\t\t\t\tretval = stlink_usb_write_mem32(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\n\t\t} else\n\t\t\tretval = stlink_usb_write_mem8(handle, ap_num, csw, addr, bytes_remaining, buffer);\n\t\tif (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) {\n\t\t\tusleep((1<<retries++) * 1000);\n\t\t\tcontinue;\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int stlink_usb_write_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, const uint8_t *buffer)\n{\n\treturn stlink_usb_write_ap_mem(handle, STLINK_HLA_AP_NUM, STLINK_HLA_CSW,\n\t\t\t\t\t\t\t\t   addr, size, count, buffer);\n}\n\n/** */\nstatic int stlink_usb_override_target(const char *targetname)\n{\n\treturn !strcmp(targetname, \"cortex_m\");\n}\n\nstatic int stlink_speed_swim(void *handle, int khz, bool query)\n{\n\tint retval;\n\n\t/*\n\t\t\twe only have low and high speed...\n\t\t\tbefore changing speed the SWIM_CSR HS bit\n\t\t\tmust be updated\n\t */\n\tif (!query) {\n\t\tretval = stlink_swim_speed(handle, (khz < SWIM_FREQ_HIGH) ? 0 : 1);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"Unable to set adapter speed\");\n\t}\n\n\treturn (khz < SWIM_FREQ_HIGH) ? SWIM_FREQ_LOW : SWIM_FREQ_HIGH;\n}\n\nstatic int stlink_match_speed_map(const struct speed_map *map, unsigned int map_size, int khz, bool query)\n{\n\tunsigned int i;\n\tint speed_index = -1;\n\tint speed_diff = INT_MAX;\n\tint last_valid_speed = -1;\n\tbool match = true;\n\n\tfor (i = 0; i < map_size; i++) {\n\t\tif (!map[i].speed)\n\t\t\tcontinue;\n\t\tlast_valid_speed = i;\n\t\tif (khz == map[i].speed) {\n\t\t\tspeed_index = i;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tint current_diff = khz - map[i].speed;\n\t\t\t/* get abs value for comparison */\n\t\t\tcurrent_diff = (current_diff > 0) ? current_diff : -current_diff;\n\t\t\tif ((current_diff < speed_diff) && khz >= map[i].speed) {\n\t\t\t\tspeed_diff = current_diff;\n\t\t\t\tspeed_index = i;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (speed_index == -1) {\n\t\t/* this will only be here if we cannot match the slow speed.\n\t\t * use the slowest speed we support.*/\n\t\tspeed_index = last_valid_speed;\n\t\tmatch = false;\n\t} else if (i == map_size)\n\t\tmatch = false;\n\n\tif (!match && query) {\n\t\tLOG_INFO(\"Unable to match requested speed %d kHz, using %d kHz\",\n\t\t\t\tkhz, map[speed_index].speed);\n\t}\n\n\treturn speed_index;\n}\n\nstatic int stlink_speed_swd(void *handle, int khz, bool query)\n{\n\tint speed_index;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\t/* old firmware cannot change it */\n\tif (!(h->version.flags & STLINK_F_HAS_SWD_SET_FREQ))\n\t\treturn khz;\n\n\tspeed_index = stlink_match_speed_map(stlink_khz_to_speed_map_swd,\n\t\tARRAY_SIZE(stlink_khz_to_speed_map_swd), khz, query);\n\n\tif (!query) {\n\t\tint result = stlink_usb_set_swdclk(h, stlink_khz_to_speed_map_swd[speed_index].speed_divisor);\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to set adapter speed\");\n\t\t\treturn khz;\n\t\t}\n\t}\n\n\treturn stlink_khz_to_speed_map_swd[speed_index].speed;\n}\n\nstatic int stlink_speed_jtag(void *handle, int khz, bool query)\n{\n\tint speed_index;\n\tstruct stlink_usb_handle_s *h = handle;\n\n\t/* old firmware cannot change it */\n\tif (!(h->version.flags & STLINK_F_HAS_JTAG_SET_FREQ))\n\t\treturn khz;\n\n\tspeed_index = stlink_match_speed_map(stlink_khz_to_speed_map_jtag,\n\t\tARRAY_SIZE(stlink_khz_to_speed_map_jtag), khz, query);\n\n\tif (!query) {\n\t\tint result = stlink_usb_set_jtagclk(h, stlink_khz_to_speed_map_jtag[speed_index].speed_divisor);\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to set adapter speed\");\n\t\t\treturn khz;\n\t\t}\n\t}\n\n\treturn stlink_khz_to_speed_map_jtag[speed_index].speed;\n}\n\nstatic void stlink_dump_speed_map(const struct speed_map *map, unsigned int map_size)\n{\n\tunsigned int i;\n\n\tLOG_DEBUG(\"Supported clock speeds are:\");\n\tfor (i = 0; i < map_size; i++)\n\t\tif (map[i].speed)\n\t\t\tLOG_DEBUG(\"%d kHz\", map[i].speed);\n}\n\nstatic int stlink_get_com_freq(void *handle, bool is_jtag, struct speed_map *map)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint i;\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V3) {\n\t\tLOG_ERROR(\"Unknown command\");\n\t\treturn 0;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_APIV3_GET_COM_FREQ;\n\th->cmdbuf[h->cmdidx++] = is_jtag ? 1 : 0;\n\n\tint res = stlink_usb_xfer_errcheck(handle, h->databuf, 52);\n\n\tint size = h->databuf[8];\n\n\tif (size > STLINK_V3_MAX_FREQ_NB)\n\t\tsize = STLINK_V3_MAX_FREQ_NB;\n\n\tfor (i = 0; i < size; i++) {\n\t\tmap[i].speed = le_to_h_u32(&h->databuf[12 + 4 * i]);\n\t\tmap[i].speed_divisor = i;\n\t}\n\n\t/* set to zero all the next entries */\n\tfor (i = size; i < STLINK_V3_MAX_FREQ_NB; i++)\n\t\tmap[i].speed = 0;\n\n\treturn res;\n}\n\nstatic int stlink_set_com_freq(void *handle, bool is_jtag, unsigned int frequency)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tif (h->version.jtag_api != STLINK_JTAG_API_V3) {\n\t\tLOG_ERROR(\"Unknown command\");\n\t\treturn 0;\n\t}\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_APIV3_SET_COM_FREQ;\n\th->cmdbuf[h->cmdidx++] = is_jtag ? 1 : 0;\n\th->cmdbuf[h->cmdidx++] = 0;\n\n\th_u32_to_le(&h->cmdbuf[4], frequency);\n\n\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 8);\n}\n\nstatic int stlink_speed_v3(void *handle, bool is_jtag, int khz, bool query)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint speed_index;\n\tstruct speed_map map[STLINK_V3_MAX_FREQ_NB];\n\n\tstlink_get_com_freq(h, is_jtag, map);\n\n\tspeed_index = stlink_match_speed_map(map, ARRAY_SIZE(map), khz, query);\n\n\tif (!query) {\n\t\tint result = stlink_set_com_freq(h, is_jtag, map[speed_index].speed);\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to set adapter speed\");\n\t\t\treturn khz;\n\t\t}\n\t}\n\treturn map[speed_index].speed;\n}\n\nstatic int stlink_speed(void *handle, int khz, bool query)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tif (!handle)\n\t\treturn khz;\n\n\tswitch (h->st_mode) {\n\tcase STLINK_MODE_DEBUG_SWIM:\n\t\treturn stlink_speed_swim(handle, khz, query);\n\tcase STLINK_MODE_DEBUG_SWD:\n\t\tif (h->version.jtag_api == STLINK_JTAG_API_V3)\n\t\t\treturn stlink_speed_v3(handle, false, khz, query);\n\t\telse\n\t\t\treturn stlink_speed_swd(handle, khz, query);\n\t\tbreak;\n\tcase STLINK_MODE_DEBUG_JTAG:\n\t\tif (h->version.jtag_api == STLINK_JTAG_API_V3)\n\t\t\treturn stlink_speed_v3(handle, true, khz, query);\n\t\telse\n\t\t\treturn stlink_speed_jtag(handle, khz, query);\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn khz;\n}\n\n/** */\nstatic int stlink_usb_usb_close(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tif (!h)\n\t\treturn ERROR_OK;\n\n\tif (h->usb_backend_priv.fd) {\n\t\tstlink_usb_exit_mode(h);\n\t\t/* do not check return code, it prevent\n\t\tus from closing jtag_libusb */\n\t\tjtag_libusb_close(h->usb_backend_priv.fd);\n\t}\n\n\tfree(h->cmdbuf);\n\tfree(h->databuf);\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_tcp_close(void *handle)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tif (!h)\n\t\treturn ERROR_OK;\n\n\tint ret = ERROR_OK;\n\tif (h->tcp_backend_priv.connected) {\n\t\tif (h->tcp_backend_priv.connect_id) {\n\t\t\tstlink_usb_exit_mode(h);\n\n\t\t\t/* close the stlink */\n\t\t\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_CLOSE_DEV;\n\t\t\tmemset(&h->tcp_backend_priv.send_buf[1], 0, 4); /* reserved */\n\t\t\th_u32_to_le(&h->tcp_backend_priv.send_buf[4], h->tcp_backend_priv.connect_id);\n\t\t\tret = stlink_tcp_send_cmd(h, 8, 4, true);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"cannot close the STLINK\");\n\t\t}\n\n\t\tif (close_socket(h->tcp_backend_priv.fd) != 0)\n\t\t\tLOG_ERROR(\"error closing the socket, errno: %s\", strerror(errno));\n\t}\n\n\tfree(h->tcp_backend_priv.send_buf);\n\tfree(h->tcp_backend_priv.recv_buf);\n\n\treturn ret;\n}\n\n/** */\nstatic int stlink_close(void *handle)\n{\n\tif (handle) {\n\t\tstruct stlink_usb_handle_s *h = handle;\n\n\t\tstlink_usb_close(handle);\n\n\t\tfree(h);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Compute ST-Link serial number from the device descriptor\n * this function will help to work-around a bug in old ST-Link/V2 DFU\n * the buggy DFU returns an incorrect serial in the USB descriptor\n * example for the following serial \"57FF72067265575742132067\"\n *  - the correct descriptor serial is:\n *    0x32, 0x03, 0x35, 0x00, 0x37, 0x00, 0x46, 0x00, 0x46, 0x00, 0x37, 0x00, 0x32, 0x00 ...\n *    this contains the length (0x32 = 50), the type (0x3 = DT_STRING) and the serial in unicode format\n *    the serial part is: 0x0035, 0x0037, 0x0046, 0x0046, 0x0037, 0x0032 ... >>  57FF72 ...\n *    this format could be read correctly by 'libusb_get_string_descriptor_ascii'\n *    so this case is managed by libusb_helper::string_descriptor_equal\n *  - the buggy DFU is not doing any unicode conversion and returns a raw serial data in the descriptor\n *    0x1a, 0x03, 0x57, 0x00, 0xFF, 0x00, 0x72, 0x00 ...\n *            >>    57          FF          72       ...\n *    based on the length (0x1a = 26) we could easily decide if we have to fixup the serial\n *    and then we have just to convert the raw data into printable characters using sprintf\n */\nstatic char *stlink_usb_get_alternate_serial(struct libusb_device_handle *device,\n\t\tstruct libusb_device_descriptor *dev_desc)\n{\n\tint usb_retval;\n\tunsigned char desc_serial[(STLINK_SERIAL_LEN + 1) * 2];\n\n\tif (dev_desc->iSerialNumber == 0)\n\t\treturn NULL;\n\n\t/* get the LANGID from String Descriptor Zero */\n\tusb_retval = libusb_get_string_descriptor(device, 0, 0, desc_serial,\n\t\t\tsizeof(desc_serial));\n\n\tif (usb_retval < LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_get_string_descriptor() failed: %s(%d)\",\n\t\t\t\tlibusb_error_name(usb_retval), usb_retval);\n\t\treturn NULL;\n\t} else if (usb_retval < 4) {\n\t\t/* the size should be least 4 bytes to contain a minimum of 1 supported LANGID */\n\t\tLOG_ERROR(\"could not get the LANGID\");\n\t\treturn NULL;\n\t}\n\n\tuint32_t langid = desc_serial[2] | (desc_serial[3] << 8);\n\n\t/* get the serial */\n\tusb_retval = libusb_get_string_descriptor(device, dev_desc->iSerialNumber,\n\t\t\tlangid, desc_serial, sizeof(desc_serial));\n\n\tunsigned char len = desc_serial[0];\n\n\tif (usb_retval < LIBUSB_SUCCESS) {\n\t\tLOG_ERROR(\"libusb_get_string_descriptor() failed: %s(%d)\",\n\t\t\t\tlibusb_error_name(usb_retval), usb_retval);\n\t\treturn NULL;\n\t} else if (desc_serial[1] != LIBUSB_DT_STRING || len > usb_retval) {\n\t\tLOG_ERROR(\"invalid string in ST-LINK USB serial descriptor\");\n\t\treturn NULL;\n\t}\n\n\tif (len == ((STLINK_SERIAL_LEN + 1) * 2)) {\n\t\t/* good ST-Link adapter, this case is managed by\n\t\t * libusb::libusb_get_string_descriptor_ascii */\n\t\treturn NULL;\n\t} else if (len != ((STLINK_SERIAL_LEN / 2 + 1) * 2)) {\n\t\tLOG_ERROR(\"unexpected serial length (%d) in descriptor\", len);\n\t\treturn NULL;\n\t}\n\n\t/* else (len == 26) => buggy ST-Link */\n\n\tchar *alternate_serial = malloc((STLINK_SERIAL_LEN + 1) * sizeof(char));\n\tif (!alternate_serial)\n\t\treturn NULL;\n\n\tfor (unsigned int i = 0; i < STLINK_SERIAL_LEN; i += 2)\n\t\tsprintf(alternate_serial + i, \"%02X\", desc_serial[i + 2]);\n\n\talternate_serial[STLINK_SERIAL_LEN] = '\\0';\n\n\treturn alternate_serial;\n}\n\n/** */\nstatic int stlink_usb_usb_open(void *handle, struct hl_interface_param_s *param)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint err, retry_count = 1;\n\n\th->cmdbuf = malloc(STLINK_SG_SIZE);\n\th->databuf = malloc(STLINK_DATA_SIZE);\n\n\tif (!h->cmdbuf || !h->databuf)\n\t\treturn ERROR_FAIL;\n\n\t/*\n\t  On certain host USB configurations(e.g. MacBook Air)\n\t  STLINKv2 dongle seems to have its FW in a funky state if,\n\t  after plugging it in, you try to use openocd with it more\n\t  then once (by launching and closing openocd). In cases like\n\t  that initial attempt to read the FW info via\n\t  stlink_usb_version will fail and the device has to be reset\n\t  in order to become operational.\n\t */\n\tdo {\n\t\tif (jtag_libusb_open(param->vid, param->pid,\n\t\t\t\t&h->usb_backend_priv.fd, stlink_usb_get_alternate_serial) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"open failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tjtag_libusb_set_configuration(h->usb_backend_priv.fd, 0);\n\n\t\tif (libusb_claim_interface(h->usb_backend_priv.fd, 0) != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"claim interface failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* RX EP is common for all versions */\n\t\th->rx_ep = STLINK_RX_EP;\n\n\t\tuint16_t pid;\n\t\tif (jtag_libusb_get_pid(libusb_get_device(h->usb_backend_priv.fd), &pid) != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"libusb_get_pid failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* wrap version for first read */\n\t\tswitch (pid) {\n\t\t\tcase STLINK_V1_PID:\n\t\t\t\th->version.stlink = 1;\n\t\t\t\th->tx_ep = STLINK_TX_EP;\n\t\t\t\tbreak;\n\t\t\tcase STLINK_V3_USBLOADER_PID:\n\t\t\tcase STLINK_V3E_PID:\n\t\t\tcase STLINK_V3S_PID:\n\t\t\tcase STLINK_V3_2VCP_PID:\n\t\t\tcase STLINK_V3E_NO_MSD_PID:\n\t\t\tcase STLINK_V3P_USBLOADER_PID:\n\t\t\tcase STLINK_V3P_PID:\n\t\t\t\th->version.stlink = 3;\n\t\t\t\th->tx_ep = STLINK_V2_1_TX_EP;\n\t\t\t\th->trace_ep = STLINK_V2_1_TRACE_EP;\n\t\t\t\tbreak;\n\t\t\tcase STLINK_V2_1_PID:\n\t\t\tcase STLINK_V2_1_NO_MSD_PID:\n\t\t\t\th->version.stlink = 2;\n\t\t\t\th->tx_ep = STLINK_V2_1_TX_EP;\n\t\t\t\th->trace_ep = STLINK_V2_1_TRACE_EP;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t/* fall through - we assume V2 to be the default version*/\n\t\t\tcase STLINK_V2_PID:\n\t\t\t\th->version.stlink = 2;\n\t\t\t\th->tx_ep = STLINK_TX_EP;\n\t\t\t\th->trace_ep = STLINK_TRACE_EP;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* get the device version */\n\t\terr = stlink_usb_version(h);\n\n\t\tif (err == ERROR_OK) {\n\t\t\tbreak;\n\t\t} else if (h->version.stlink == 1 ||\n\t\t\t   retry_count == 0) {\n\t\t\tLOG_ERROR(\"read version failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t} else {\n\t\t\terr = libusb_release_interface(h->usb_backend_priv.fd, 0);\n\t\t\tif (err != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"release interface failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\terr = libusb_reset_device(h->usb_backend_priv.fd);\n\t\t\tif (err != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"reset device failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tjtag_libusb_close(h->usb_backend_priv.fd);\n\t\t\t/*\n\t\t\t  Give the device one second to settle down and\n\t\t\t  reenumerate.\n\t\t\t */\n\t\t\tusleep(1 * 1000 * 1000);\n\t\t\tretry_count--;\n\t\t}\n\t} while (1);\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_tcp_open(void *handle, struct hl_interface_param_s *param)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint ret;\n\n\t/* SWIM is not supported using stlink-server */\n\tif (h->st_mode ==  STLINK_MODE_DEBUG_SWIM) {\n\t\tLOG_ERROR(\"stlink-server does not support SWIM mode\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\th->tcp_backend_priv.send_buf = malloc(STLINK_TCP_SEND_BUFFER_SIZE);\n\th->tcp_backend_priv.recv_buf = malloc(STLINK_TCP_RECV_BUFFER_SIZE);\n\n\tif (!h->tcp_backend_priv.send_buf || !h->tcp_backend_priv.recv_buf)\n\t\treturn ERROR_FAIL;\n\n\th->cmdbuf = &h->tcp_backend_priv.send_buf[8];\n\th->databuf = &h->tcp_backend_priv.recv_buf[4];\n\n\t/* configure directions */\n\th->rx_ep = STLINK_TCP_REQUEST_READ;\n\th->tx_ep = STLINK_TCP_REQUEST_WRITE;\n\th->trace_ep = STLINK_TCP_REQUEST_READ_SWO;\n\n\th->tcp_backend_priv.fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n\th->tcp_backend_priv.connected = false;\n\th->tcp_backend_priv.device_id = 0;\n\th->tcp_backend_priv.connect_id = 0;\n\n\tif (h->tcp_backend_priv.fd == -1) {\n\t\tLOG_ERROR(\"error creating the socket, errno: %s\", strerror(errno));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct sockaddr_in serv;\n\tmemset(&serv, 0, sizeof(struct sockaddr_in));\n\tserv.sin_family = AF_INET;\n\tserv.sin_port = htons(param->stlink_tcp_port);\n\tserv.sin_addr.s_addr = inet_addr(\"127.0.0.1\");\n\n\tLOG_DEBUG(\"socket : %x\", h->tcp_backend_priv.fd);\n\n\tint optval = 1;\n\tif (setsockopt(h->tcp_backend_priv.fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&optval, sizeof(int)) == -1) {\n\t\tLOG_ERROR(\"cannot set sock option 'TCP_NODELAY', errno: %s\", strerror(errno));\n\t\treturn ERROR_FAIL;\n\t}\n\n\toptval = STLINK_TCP_RECV_BUFFER_SIZE;\n\tif (setsockopt(h->tcp_backend_priv.fd, SOL_SOCKET, SO_RCVBUF, (const void *)&optval, sizeof(int)) == -1) {\n\t\tLOG_ERROR(\"cannot set sock option 'SO_RCVBUF', errno: %s\", strerror(errno));\n\t\treturn ERROR_FAIL;\n\t}\n\n\toptval = STLINK_TCP_SEND_BUFFER_SIZE;\n\tif (setsockopt(h->tcp_backend_priv.fd, SOL_SOCKET, SO_SNDBUF, (const void *)&optval, sizeof(int)) == -1) {\n\t\tLOG_ERROR(\"cannot set sock option 'SO_SNDBUF', errno: %s\", strerror(errno));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (connect(h->tcp_backend_priv.fd, (const struct sockaddr *)&serv, sizeof(serv)) == -1) {\n\t\tLOG_ERROR(\"cannot connect to stlink server, errno: %s\", strerror(errno));\n\t\treturn ERROR_FAIL;\n\t}\n\n\th->tcp_backend_priv.connected = true;\n\n\tLOG_INFO(\"connected to stlink-server\");\n\n\t/* print stlink-server version */\n\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_GET_SERVER_VERSION;\n\th->tcp_backend_priv.send_buf[1] = OPENOCD_STLINK_TCP_API_VERSION;\n\tmemset(&h->tcp_backend_priv.send_buf[2], 0, 2); /* reserved */\n\tret = stlink_tcp_send_cmd(h, 4, 16, false);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot get the stlink-server version\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\th->tcp_backend_priv.version.api = le_to_h_u32(&h->tcp_backend_priv.recv_buf[0]);\n\th->tcp_backend_priv.version.major = le_to_h_u32(&h->tcp_backend_priv.recv_buf[4]);\n\th->tcp_backend_priv.version.minor = le_to_h_u32(&h->tcp_backend_priv.recv_buf[8]);\n\th->tcp_backend_priv.version.build = le_to_h_u32(&h->tcp_backend_priv.recv_buf[12]);\n\tLOG_INFO(\"stlink-server API v%d, version %d.%d.%d\",\n\t\t\th->tcp_backend_priv.version.api,\n\t\t\th->tcp_backend_priv.version.major,\n\t\t\th->tcp_backend_priv.version.minor,\n\t\t\th->tcp_backend_priv.version.build);\n\n\t/* in stlink-server API v1 sending more than 1428 bytes will cause stlink-server\n\t * to crash in windows: select a safe default value (1K) */\n\tif (h->tcp_backend_priv.version.api < 2)\n\t\th->max_mem_packet = (1 << 10);\n\n\t/* refresh stlink list (re-enumerate) */\n\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_REFRESH_DEVICE_LIST;\n\th->tcp_backend_priv.send_buf[1] = 0; /* don't clear the list, just refresh it */\n\tret = stlink_tcp_send_cmd(h, 2, 4, true);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* get the number of connected stlinks */\n\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_GET_NB_DEV;\n\tret = stlink_tcp_send_cmd(h, 1, 4, false);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tuint32_t connected_stlinks = le_to_h_u32(h->tcp_backend_priv.recv_buf);\n\n\tif (connected_stlinks == 0) {\n\t\tLOG_ERROR(\"no ST-LINK detected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"%d ST-LINK detected\", connected_stlinks);\n\n\tif (connected_stlinks > 255) {\n\t\tLOG_WARNING(\"STLink server cannot handle more than 255 ST-LINK connected\");\n\t\tconnected_stlinks = 255;\n\t}\n\n\t/* list all connected ST-Link and seek for the requested vid:pid and serial */\n\tchar serial[STLINK_TCP_SERIAL_SIZE + 1] = {0};\n\tuint8_t stlink_used;\n\tbool stlink_id_matched = false;\n\tconst char *adapter_serial = adapter_get_required_serial();\n\tbool stlink_serial_matched = !adapter_serial;\n\n\tfor (uint32_t stlink_id = 0; stlink_id < connected_stlinks; stlink_id++) {\n\t\t/* get the stlink info */\n\t\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_GET_DEV_INFO;\n\t\th->tcp_backend_priv.send_buf[1] = (uint8_t)stlink_id;\n\t\tmemset(&h->tcp_backend_priv.send_buf[2], 0, 2); /* reserved */\n\t\th_u32_to_le(&h->tcp_backend_priv.send_buf[4], 41); /* size of TDeviceInfo2 */\n\t\tret = stlink_tcp_send_cmd(h, 8, 45, true);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\th->tcp_backend_priv.device_id = le_to_h_u32(&h->tcp_backend_priv.recv_buf[4]);\n\t\tmemcpy(serial, &h->tcp_backend_priv.recv_buf[8], STLINK_TCP_SERIAL_SIZE);\n\t\th->vid = le_to_h_u16(&h->tcp_backend_priv.recv_buf[40]);\n\t\th->pid = le_to_h_u16(&h->tcp_backend_priv.recv_buf[42]);\n\t\tstlink_used = h->tcp_backend_priv.recv_buf[44];\n\n\t\t/* check the vid:pid */\n\t\tfor (int i = 0; param->vid[i]; i++) {\n\t\t\tif (param->vid[i] == h->vid && param->pid[i] == h->pid) {\n\t\t\t\tstlink_id_matched = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!stlink_id_matched)\n\t\t\tcontinue;\n\n\t\t/* check the serial if specified */\n\t\tif (adapter_serial) {\n\t\t\t/* ST-Link server fixes the buggy serial returned by old ST-Link DFU\n\t\t\t * for further details refer to stlink_usb_get_alternate_serial\n\t\t\t * so if the user passes the buggy serial, we need to fix it before\n\t\t\t * comparing with the serial returned by ST-Link server */\n\t\t\tif (strlen(adapter_serial) == STLINK_SERIAL_LEN / 2) {\n\t\t\t\tchar fixed_serial[STLINK_SERIAL_LEN + 1];\n\n\t\t\t\tfor (unsigned int i = 0; i < STLINK_SERIAL_LEN; i += 2)\n\t\t\t\t\tsprintf(fixed_serial + i, \"%02X\", adapter_serial[i / 2]);\n\n\t\t\t\tfixed_serial[STLINK_SERIAL_LEN] = '\\0';\n\n\t\t\t\tstlink_serial_matched = strcmp(fixed_serial, serial) == 0;\n\t\t\t} else {\n\t\t\t\tstlink_serial_matched = strcmp(adapter_serial, serial) == 0;\n\t\t\t}\n\t\t}\n\n\t\tif (!stlink_serial_matched)\n\t\t\tLOG_DEBUG(\"Device serial number '%s' doesn't match requested serial '%s'\",\n\t\t\t\t\tserial, adapter_serial);\n\t\telse /* exit the search loop if there is match */\n\t\t\tbreak;\n\t}\n\n\tif (!stlink_id_matched) {\n\t\tLOG_ERROR(\"ST-LINK open failed (vid/pid mismatch)\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!stlink_serial_matched) {\n\t\tLOG_ERROR(\"ST-LINK open failed (serial mismatch)\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* check if device is 'exclusively' used by another application */\n\tif (stlink_used) {\n\t\tLOG_ERROR(\"the selected device is already used\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"transport: vid: 0x%04x pid: 0x%04x serial: %s\", h->vid, h->pid, serial);\n\n\t/* now let's open the stlink */\n\th->tcp_backend_priv.send_buf[0] = STLINK_TCP_CMD_OPEN_DEV;\n\tmemset(&h->tcp_backend_priv.send_buf[1], 0, 4); /* reserved */\n\th_u32_to_le(&h->tcp_backend_priv.send_buf[4], h->tcp_backend_priv.device_id);\n\tret = stlink_tcp_send_cmd(h, 8, 8, true);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\th->tcp_backend_priv.connect_id = le_to_h_u32(&h->tcp_backend_priv.recv_buf[4]);\n\n\t/* get stlink version */\n\treturn stlink_usb_version(h);\n}\n\nstatic struct stlink_backend_s stlink_usb_backend = {\n\t.open = stlink_usb_usb_open,\n\t.close = stlink_usb_usb_close,\n\t.xfer_noerrcheck = stlink_usb_usb_xfer_noerrcheck,\n\t.read_trace = stlink_usb_usb_read_trace,\n};\n\nstatic struct stlink_backend_s stlink_tcp_backend = {\n\t.open = stlink_tcp_open,\n\t.close = stlink_tcp_close,\n\t.xfer_noerrcheck = stlink_tcp_xfer_noerrcheck,\n\t.read_trace = stlink_tcp_read_trace,\n};\n\nstatic int stlink_open(struct hl_interface_param_s *param, enum stlink_mode mode, void **fd)\n{\n\tstruct stlink_usb_handle_s *h;\n\n\tLOG_DEBUG(\"stlink_open\");\n\n\th = calloc(1, sizeof(struct stlink_usb_handle_s));\n\n\tif (!h) {\n\t\tLOG_DEBUG(\"malloc failed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\th->st_mode = mode;\n\n\tfor (unsigned i = 0; param->vid[i]; i++) {\n\t\tLOG_DEBUG(\"transport: %d vid: 0x%04x pid: 0x%04x serial: %s\",\n\t\t\t  h->st_mode, param->vid[i], param->pid[i],\n\t\t\t  adapter_get_required_serial() ? adapter_get_required_serial() : \"\");\n\t}\n\n\tif (param->use_stlink_tcp)\n\t\th->backend = &stlink_tcp_backend;\n\telse\n\t\th->backend = &stlink_usb_backend;\n\n\tif (stlink_usb_open(h, param) != ERROR_OK)\n\t\tgoto error_open;\n\n\t/* check if mode is supported */\n\tint err = ERROR_OK;\n\n\tswitch (h->st_mode) {\n\t\tcase STLINK_MODE_DEBUG_SWD:\n\t\t\tif (h->version.jtag_api == STLINK_JTAG_API_V1)\n\t\t\t\terr = ERROR_FAIL;\n\t\t\t/* fall-through */\n\t\tcase STLINK_MODE_DEBUG_JTAG:\n\t\t\tif (h->version.jtag == 0)\n\t\t\t\terr = ERROR_FAIL;\n\t\t\tbreak;\n\t\tcase STLINK_MODE_DEBUG_SWIM:\n\t\t\tif (h->version.swim == 0)\n\t\t\t\terr = ERROR_FAIL;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\terr = ERROR_FAIL;\n\t\t\tbreak;\n\t}\n\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"mode (transport) not supported by device\");\n\t\tgoto error_open;\n\t}\n\n\t/* initialize the debug hardware */\n\terr = stlink_usb_init_mode(h, param->connect_under_reset, param->initial_interface_speed);\n\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"init mode failed (unable to connect to the target)\");\n\t\tgoto error_open;\n\t}\n\n\tif (h->st_mode == STLINK_MODE_DEBUG_SWIM) {\n\t\terr = stlink_swim_enter(h);\n\t\tif (err != ERROR_OK) {\n\t\t\tLOG_ERROR(\"stlink_swim_enter_failed (unable to connect to the target)\");\n\t\t\tgoto error_open;\n\t\t}\n\t\t*fd = h;\n\t\th->max_mem_packet = STLINK_SWIM_DATA_SIZE;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* set max_mem_packet if it was not set by the low-level interface */\n\tif (h->max_mem_packet == 0) {\n\t\t/* get cpuid, so we can determine the max page size\n\t\t * start with a safe default */\n\t\th->max_mem_packet = (1 << 10);\n\n\t\tuint8_t buffer[4];\n\t\tstlink_usb_open_ap(h, STLINK_HLA_AP_NUM);\n\t\terr = stlink_usb_read_mem32(h, STLINK_HLA_AP_NUM, STLINK_HLA_CSW, CPUID, 4, buffer);\n\t\tif (err == ERROR_OK) {\n\t\t\tuint32_t cpuid = le_to_h_u32(buffer);\n\t\t\tint i = (cpuid >> 4) & 0xf;\n\t\t\tif (i == 4 || i == 3) {\n\t\t\t\t/* Cortex-M3/M4 has 4096 bytes autoincrement range */\n\t\t\t\th->max_mem_packet = (1 << 12);\n\t\t\t}\n\t\t}\n\n\t\tLOG_DEBUG(\"Using TAR autoincrement: %\" PRIu32, h->max_mem_packet);\n\t}\n\n\t*fd = h;\n\n\treturn ERROR_OK;\n\nerror_open:\n\tstlink_close(h);\n\treturn ERROR_FAIL;\n}\n\nstatic int stlink_usb_hl_open(struct hl_interface_param_s *param, void **fd)\n{\n\treturn stlink_open(param, stlink_get_mode(param->transport), fd);\n}\n\nstatic int stlink_config_trace(void *handle, bool enabled,\n\t\tenum tpiu_pin_protocol pin_protocol, uint32_t port_size,\n\t\tunsigned int *trace_freq, unsigned int traceclkin_freq,\n\t\tuint16_t *prescaler)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tif (!(h->version.flags & STLINK_F_HAS_TRACE)) {\n\t\tLOG_ERROR(\"The attached ST-LINK version doesn't support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!enabled) {\n\t\tstlink_usb_trace_disable(h);\n\t\treturn ERROR_OK;\n\t}\n\n\tassert(trace_freq);\n\tassert(prescaler);\n\n\tif (pin_protocol != TPIU_PIN_PROTOCOL_ASYNC_UART) {\n\t\tLOG_ERROR(\"The attached ST-LINK version doesn't support this trace mode\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tunsigned int max_trace_freq = (h->version.stlink >= 3) ?\n\t\t\tSTLINK_V3_TRACE_MAX_HZ : STLINK_TRACE_MAX_HZ;\n\n\t/* Only concern ourselves with the frequency if the STlink is processing it. */\n\tif (*trace_freq > max_trace_freq) {\n\t\tLOG_ERROR(\"ST-LINK doesn't support SWO frequency higher than %u\",\n\t\t\t  max_trace_freq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!*trace_freq)\n\t\t*trace_freq = max_trace_freq;\n\n\tunsigned int presc = (traceclkin_freq + *trace_freq / 2) / *trace_freq;\n\tif (presc == 0 || presc > TPIU_ACPR_MAX_SWOSCALER + 1) {\n\t\tLOG_ERROR(\"SWO frequency is not suitable. Please choose a different \"\n\t\t\t\"frequency.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Probe's UART speed must be within 3% of the TPIU's SWO baud rate. */\n\tunsigned int max_deviation = (traceclkin_freq * 3) / 100;\n\tif (presc * *trace_freq < traceclkin_freq - max_deviation ||\n\t\t\tpresc * *trace_freq > traceclkin_freq + max_deviation) {\n\t\tLOG_ERROR(\"SWO frequency is not suitable. Please choose a different \"\n\t\t\t\"frequency.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*prescaler = presc;\n\n\tstlink_usb_trace_disable(h);\n\n\th->trace.source_hz = *trace_freq;\n\n\treturn stlink_usb_trace_enable(h);\n}\n\n/** */\nstatic int stlink_usb_init_access_port(void *handle, unsigned char ap_num)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_AP_INIT))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tLOG_DEBUG_IO(\"init ap_num = %d\", ap_num);\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_INIT_AP;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\n\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n}\n\n/** */\nstatic int stlink_usb_close_access_port(void *handle, unsigned char ap_num)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_AP_INIT))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tLOG_DEBUG_IO(\"close ap_num = %d\", ap_num);\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_CLOSE_AP_DBG;\n\th->cmdbuf[h->cmdidx++] = ap_num;\n\n\t/* ignore incorrectly returned error on bogus FW */\n\tif (h->version.flags & STLINK_F_FIX_CLOSE_AP)\n\t\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n\telse\n\t\treturn stlink_usb_xfer_noerrcheck(handle, h->databuf, 2);\n\n}\n\nstatic int stlink_usb_rw_misc_out(void *handle, uint32_t items, const uint8_t *buffer)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tunsigned int buflen = ALIGN_UP(items, 4) + 4 * items;\n\n\tLOG_DEBUG_IO(\"%s(%\" PRIu32 \")\", __func__, items);\n\n\tassert(handle != NULL);\n\n\tif (!(h->version.flags & STLINK_F_HAS_RW_MISC))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->tx_ep, buflen);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RW_MISC_OUT;\n\th_u32_to_le(&h->cmdbuf[2], items);\n\n\treturn stlink_usb_xfer_noerrcheck(handle, buffer, buflen);\n}\n\nstatic int stlink_usb_rw_misc_in(void *handle, uint32_t items, uint8_t *buffer)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tunsigned int buflen = 2 * 4 * items;\n\n\tLOG_DEBUG_IO(\"%s(%\" PRIu32 \")\", __func__, items);\n\n\tassert(handle != NULL);\n\n\tif (!(h->version.flags & STLINK_F_HAS_RW_MISC))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, buflen);\n\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RW_MISC_IN;\n\n\tint res = stlink_usb_xfer_noerrcheck(handle, h->databuf, buflen);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tmemcpy(buffer, h->databuf, buflen);\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_read_dap_register(void *handle, unsigned short dap_port,\n\t\t\tunsigned short addr, uint32_t *val)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint retval;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_DAP_REG))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_READ_DAP_REG;\n\th_u16_to_le(&h->cmdbuf[2], dap_port);\n\th_u16_to_le(&h->cmdbuf[4], addr);\n\n\tretval = stlink_usb_xfer_errcheck(handle, h->databuf, 8);\n\t*val = le_to_h_u32(h->databuf + 4);\n\tLOG_DEBUG_IO(\"dap_port_read = %d, addr =  0x%x, value = 0x%\" PRIx32, dap_port, addr, *val);\n\treturn retval;\n}\n\n/** */\nstatic int stlink_write_dap_register(void *handle, unsigned short dap_port,\n\t\t\tunsigned short addr, uint32_t val)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\n\tassert(handle);\n\n\tif (!(h->version.flags & STLINK_F_HAS_DAP_REG))\n\t\treturn ERROR_COMMAND_NOTFOUND;\n\n\tLOG_DEBUG_IO(\"dap_write port = %d, addr = 0x%x, value = 0x%\" PRIx32, dap_port, addr, val);\n\tstlink_usb_init_buffer(handle, h->rx_ep, 16);\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;\n\th->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_WRITE_DAP_REG;\n\th_u16_to_le(&h->cmdbuf[2], dap_port);\n\th_u16_to_le(&h->cmdbuf[4], addr);\n\th_u32_to_le(&h->cmdbuf[6], val);\n\treturn stlink_usb_xfer_errcheck(handle, h->databuf, 2);\n}\n\n/** */\nstruct hl_layout_api_s stlink_usb_layout_api = {\n\t/** */\n\t.open = stlink_usb_hl_open,\n\t/** */\n\t.close = stlink_close,\n\t/** */\n\t.idcode = stlink_usb_idcode,\n\t/** */\n\t.state = stlink_usb_state,\n\t/** */\n\t.reset = stlink_usb_reset,\n\t/** */\n\t.assert_srst = stlink_usb_assert_srst,\n\t/** */\n\t.run = stlink_usb_run,\n\t/** */\n\t.halt = stlink_usb_halt,\n\t/** */\n\t.step = stlink_usb_step,\n\t/** */\n\t.read_regs = stlink_usb_read_regs,\n\t/** */\n\t.read_reg = stlink_usb_read_reg,\n\t/** */\n\t.write_reg = stlink_usb_write_reg,\n\t/** */\n\t.read_mem = stlink_usb_read_mem,\n\t/** */\n\t.write_mem = stlink_usb_write_mem,\n\t/** */\n\t.write_debug_reg = stlink_usb_write_debug_reg,\n\t/** */\n\t.override_target = stlink_usb_override_target,\n\t/** */\n\t.speed = stlink_speed,\n\t/** */\n\t.config_trace = stlink_config_trace,\n\t/** */\n\t.poll_trace = stlink_usb_trace_read,\n};\n\n/*****************************************************************************\n * DAP direct interface\n */\n\nstatic struct stlink_usb_handle_s *stlink_dap_handle;\nstatic struct hl_interface_param_s stlink_dap_param;\nstatic DECLARE_BITMAP(opened_ap, DP_APSEL_MAX + 1);\nstatic uint32_t last_csw_default[DP_APSEL_MAX + 1];\nstatic int stlink_dap_error = ERROR_OK;\n\n/** */\nstatic int stlink_dap_record_error(int error)\n{\n\tif (stlink_dap_error == ERROR_OK)\n\t\tstlink_dap_error = error;\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_get_and_clear_error(void)\n{\n\tint retval = stlink_dap_error;\n\tstlink_dap_error = ERROR_OK;\n\treturn retval;\n}\n\nstatic int stlink_dap_get_error(void)\n{\n\treturn stlink_dap_error;\n}\n\nstatic int stlink_usb_open_ap(void *handle, unsigned short apsel)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tint retval;\n\n\t/* nothing to do on old versions */\n\tif (!(h->version.flags & STLINK_F_HAS_AP_INIT))\n\t\treturn ERROR_OK;\n\n\tif (apsel > DP_APSEL_MAX)\n\t\treturn ERROR_FAIL;\n\n\tif (test_bit(apsel, opened_ap))\n\t\treturn ERROR_OK;\n\n\tretval = stlink_usb_init_access_port(h, apsel);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"AP %d enabled\", apsel);\n\tset_bit(apsel, opened_ap);\n\tlast_csw_default[apsel] = 0;\n\treturn ERROR_OK;\n}\n\nstatic int stlink_dap_open_ap(unsigned short apsel)\n{\n\treturn stlink_usb_open_ap(stlink_dap_handle, apsel);\n}\n\n/** */\nstatic int stlink_dap_closeall_ap(void)\n{\n\tint retval, apsel;\n\n\t/* nothing to do on old versions */\n\tif (!(stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT))\n\t\treturn ERROR_OK;\n\n\tfor (apsel = 0; apsel <= DP_APSEL_MAX; apsel++) {\n\t\tif (!test_bit(apsel, opened_ap))\n\t\t\tcontinue;\n\t\tretval = stlink_usb_close_access_port(stlink_dap_handle, apsel);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tclear_bit(apsel, opened_ap);\n\t}\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_reinit_interface(void)\n{\n\tint retval;\n\n\t/*\n\t * On JTAG only, it should be enough to call stlink_usb_reset(). But on\n\t * some firmware version it does not work as expected, and there is no\n\t * equivalent for SWD.\n\t * At least for now, to reset the interface quit from JTAG/SWD mode then\n\t * select the mode again.\n\t */\n\n\tif (!stlink_dap_handle->reconnect_pending) {\n\t\tstlink_dap_handle->reconnect_pending = true;\n\t\tstlink_usb_mode_leave(stlink_dap_handle, stlink_dap_handle->st_mode);\n\t}\n\n\tretval = stlink_usb_mode_enter(stlink_dap_handle, stlink_dap_handle->st_mode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstlink_dap_handle->reconnect_pending = false;\n\t/* on new FW, calling mode-leave closes all the opened AP; reopen them! */\n\tif (stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT)\n\t\tfor (unsigned int apsel = 0; apsel <= DP_APSEL_MAX; apsel++)\n\t\t\tif (test_bit(apsel, opened_ap)) {\n\t\t\t\tclear_bit(apsel, opened_ap);\n\t\t\t\tstlink_dap_open_ap(apsel);\n\t\t\t}\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_op_connect(struct adiv5_dap *dap)\n{\n\tuint32_t idcode;\n\tint retval;\n\n\tLOG_INFO(\"stlink_dap_op_connect(%sconnect)\", dap->do_reconnect ? \"re\" : \"\");\n\n\t/* Check if we should reset srst already when connecting, but not if reconnecting. */\n\tif (!dap->do_reconnect) {\n\t\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\t\tadapter_assert_reset();\n\t\t\telse\n\t\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t\t}\n\t}\n\n\tdap->do_reconnect = false;\n\tdap_invalidate_cache(dap);\n\tfor (unsigned int i = 0; i <= DP_APSEL_MAX; i++)\n\t\tlast_csw_default[i] = 0;\n\n\tretval = dap_dp_init(dap);\n\tif (retval != ERROR_OK) {\n\t\tdap->do_reconnect = true;\n\t\treturn retval;\n\t}\n\n\tretval = stlink_usb_idcode(stlink_dap_handle, &idcode);\n\tif (retval == ERROR_OK)\n\t\tLOG_INFO(\"%s %#8.8\" PRIx32,\n\t\t\t(stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) ? \"JTAG IDCODE\" : \"SWD DPIDR\",\n\t\t\tidcode);\n\telse\n\t\tdap->do_reconnect = true;\n\n\treturn retval;\n}\n\n/** */\nstatic int stlink_dap_check_reconnect(struct adiv5_dap *dap)\n{\n\tint retval;\n\n\tif (!dap->do_reconnect)\n\t\treturn ERROR_OK;\n\n\tretval = stlink_dap_reinit_interface();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn stlink_dap_op_connect(dap);\n}\n\n/** */\nstatic int stlink_dap_op_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)\n{\n\t/* Ignore the request */\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)\n{\n\tuint32_t dummy;\n\tint retval;\n\n\tif (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DPBANKSEL))\n\t\tif (reg & 0x000000F0) {\n\t\t\tLOG_ERROR(\"Banked DP registers not supported in current STLink FW\");\n\t\t\treturn ERROR_COMMAND_NOTFOUND;\n\t\t}\n\n\tdata = data ? data : &dummy;\n\tif (stlink_dap_handle->version.flags & STLINK_F_QUIRK_JTAG_DP_READ\n\t\t&& stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG) {\n\t\t/* Quirk required in JTAG. Read RDBUFF to get the data */\n\t\tretval = stlink_read_dap_register(stlink_dap_handle,\n\t\t\t\t\tSTLINK_DEBUG_PORT_ACCESS, reg, &dummy);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = stlink_read_dap_register(stlink_dap_handle,\n\t\t\t\t\t\tSTLINK_DEBUG_PORT_ACCESS, DP_RDBUFF, data);\n\t} else {\n\t\tretval = stlink_read_dap_register(stlink_dap_handle,\n\t\t\t\t\tSTLINK_DEBUG_PORT_ACCESS, reg, data);\n\t}\n\n\treturn retval;\n}\n\n/** */\nstatic int stlink_dap_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)\n{\n\tint retval;\n\n\tif (!(stlink_dap_handle->version.flags & STLINK_F_HAS_DPBANKSEL))\n\t\tif (reg & 0x000000F0) {\n\t\t\tLOG_ERROR(\"Banked DP registers not supported in current STLink FW\");\n\t\t\treturn ERROR_COMMAND_NOTFOUND;\n\t\t}\n\n\tif (reg == DP_SELECT && (data & DP_SELECT_DPBANK) != 0) {\n\t\t/* ignored if STLINK_F_HAS_DPBANKSEL, not properly managed otherwise */\n\t\tLOG_DEBUG(\"Ignoring DPBANKSEL while write SELECT\");\n\t\tdata &= ~DP_SELECT_DPBANK;\n\t}\n\n\t/* ST-Link does not like that we set CORUNDETECT */\n\tif (reg == DP_CTRL_STAT)\n\t\tdata &= ~CORUNDETECT;\n\n\tretval = stlink_write_dap_register(stlink_dap_handle,\n\t\t\t\tSTLINK_DEBUG_PORT_ACCESS, reg, data);\n\treturn retval;\n}\n\n/** */\nstatic int stlink_dap_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tuint32_t dummy;\n\tint retval;\n\n\tif (is_adiv6(dap)) {\n\t\tstatic bool error_flagged;\n\t\tif (!error_flagged)\n\t\t\tLOG_ERROR(\"ADIv6 dap not supported by stlink dap-direct mode\");\n\t\terror_flagged = true;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (reg != ADIV5_AP_REG_IDR) {\n\t\tretval = stlink_dap_open_ap(ap->ap_num);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tdata = data ? data : &dummy;\n\tretval = stlink_read_dap_register(stlink_dap_handle, ap->ap_num, reg,\n\t\t\t\t data);\n\tdap->stlink_flush_ap_write = false;\n\treturn retval;\n}\n\n/** */\nstatic int stlink_dap_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tint retval;\n\n\tif (is_adiv6(dap)) {\n\t\tstatic bool error_flagged;\n\t\tif (!error_flagged)\n\t\t\tLOG_ERROR(\"ADIv6 dap not supported by stlink dap-direct mode\");\n\t\terror_flagged = true;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = stlink_dap_open_ap(ap->ap_num);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stlink_write_dap_register(stlink_dap_handle, ap->ap_num, reg,\n\t\t\t\tdata);\n\tdap->stlink_flush_ap_write = true;\n\treturn retval;\n}\n\n/** */\nstatic int stlink_dap_op_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\tLOG_WARNING(\"stlink_dap_op_queue_ap_abort()\");\n\treturn ERROR_OK;\n}\n\n#define RW_MISC_CMD_ADDRESS     1\n#define RW_MISC_CMD_WRITE       2\n#define RW_MISC_CMD_READ        3\n#define RW_MISC_CMD_APNUM       5\n\nstatic int stlink_usb_misc_rw_segment(void *handle, const struct dap_queue *q, unsigned int len, unsigned int items)\n{\n\tuint8_t buf[2 * 4 * items];\n\n\tLOG_DEBUG(\"Queue: %u commands in %u items\", len, items);\n\n\tuint32_t ap_num = DP_APSEL_INVALID;\n\tunsigned int cmd_index = 0;\n\tunsigned int val_index = ALIGN_UP(items, 4);\n\tfor (unsigned int i = 0; i < len; i++) {\n\t\tif (ap_num != q[i].mem_ap.ap->ap_num) {\n\t\t\tap_num = q[i].mem_ap.ap->ap_num;\n\t\t\tbuf[cmd_index++] = RW_MISC_CMD_APNUM;\n\t\t\th_u32_to_le(&buf[val_index], ap_num);\n\t\t\tval_index += 4;\n\t\t}\n\n\t\tswitch (q[i].cmd) {\n\t\tcase CMD_MEM_AP_READ32:\n\t\t\tbuf[cmd_index++] = RW_MISC_CMD_READ;\n\t\t\th_u32_to_le(&buf[val_index], q[i].mem_ap.addr);\n\t\t\tval_index += 4;\n\t\t\tbreak;\n\t\tcase CMD_MEM_AP_WRITE32:\n\t\t\tbuf[cmd_index++] = RW_MISC_CMD_ADDRESS;\n\t\t\th_u32_to_le(&buf[val_index], q[i].mem_ap.addr);\n\t\t\tval_index += 4;\n\t\t\tbuf[cmd_index++] = RW_MISC_CMD_WRITE;\n\t\t\th_u32_to_le(&buf[val_index], q[i].mem_ap.data);\n\t\t\tval_index += 4;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* Not supposed to happen */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\t/* pad after last command */\n\twhile (!IS_ALIGNED(cmd_index, 4))\n\t\tbuf[cmd_index++] = 0;\n\n\tint retval = stlink_usb_rw_misc_out(handle, items, buf);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = stlink_usb_rw_misc_in(handle, items, buf);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tap_num = DP_APSEL_INVALID;\n\tval_index = 0;\n\tunsigned int err_index = 4 * items;\n\tfor (unsigned int i = 0; i < len; i++) {\n\t\tuint32_t errcode = le_to_h_u32(&buf[err_index]);\n\t\tif (errcode != STLINK_DEBUG_ERR_OK) {\n\t\t\tLOG_ERROR(\"unknown/unexpected STLINK status code 0x%x\", errcode);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (ap_num != q[i].mem_ap.ap->ap_num) {\n\t\t\tap_num = q[i].mem_ap.ap->ap_num;\n\t\t\terr_index += 4;\n\t\t\tval_index += 4;\n\t\t\terrcode = le_to_h_u32(&buf[err_index]);\n\t\t\tif (errcode != STLINK_DEBUG_ERR_OK) {\n\t\t\t\tLOG_ERROR(\"unknown/unexpected STLINK status code 0x%x\", errcode);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tif (q[i].cmd == CMD_MEM_AP_READ32) {\n\t\t\t*q[i].mem_ap.p_data = le_to_h_u32(&buf[val_index]);\n\t\t} else { /* q[i]->cmd == CMD_MEM_AP_WRITE32 */\n\t\t\terr_index += 4;\n\t\t\tval_index += 4;\n\t\t\terrcode = le_to_h_u32(&buf[err_index]);\n\t\t\tif (errcode != STLINK_DEBUG_ERR_OK) {\n\t\t\t\tLOG_ERROR(\"unknown/unexpected STLINK status code 0x%x\", errcode);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\terr_index += 4;\n\t\tval_index += 4;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_usb_buf_rw_segment(void *handle, const struct dap_queue *q, unsigned int count)\n{\n\tuint32_t bufsize = count * CMD_MEM_AP_2_SIZE(q[0].cmd);\n\tuint8_t buf[bufsize];\n\tuint8_t ap_num = q[0].mem_ap.ap->ap_num;\n\tuint32_t addr = q[0].mem_ap.addr;\n\tuint32_t csw = q[0].mem_ap.csw;\n\n\tint retval = stlink_dap_open_ap(ap_num);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswitch (q[0].cmd) {\n\tcase CMD_MEM_AP_WRITE8:\n\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\tbuf[i] = q[i].mem_ap.data >> 8 * (q[i].mem_ap.addr & 3);\n\t\treturn stlink_usb_write_mem8(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\n\tcase CMD_MEM_AP_WRITE16:\n\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\th_u16_to_le(&buf[2 * i], q[i].mem_ap.data >> 8 * (q[i].mem_ap.addr & 2));\n\t\treturn stlink_usb_write_mem16(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\n\tcase CMD_MEM_AP_WRITE32:\n\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\th_u32_to_le(&buf[4 * i], q[i].mem_ap.data);\n\t\tif (count > 1 && q[0].mem_ap.addr == q[1].mem_ap.addr)\n\t\t\treturn stlink_usb_write_mem32_noaddrinc(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\t\telse\n\t\t\treturn stlink_usb_write_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\n\tcase CMD_MEM_AP_READ8:\n\t\tretval = stlink_usb_read_mem8(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\t\tif (retval == ERROR_OK)\n\t\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\t\t*q[i].mem_ap.p_data = buf[i] << 8 * (q[i].mem_ap.addr & 3);\n\t\treturn retval;\n\n\tcase CMD_MEM_AP_READ16:\n\t\tretval = stlink_usb_read_mem16(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\t\tif (retval == ERROR_OK)\n\t\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\t\t*q[i].mem_ap.p_data = le_to_h_u16(&buf[2 * i]) << 8 * (q[i].mem_ap.addr & 2);\n\t\treturn retval;\n\n\tcase CMD_MEM_AP_READ32:\n\t\tif (count > 1 && q[0].mem_ap.addr == q[1].mem_ap.addr)\n\t\t\tretval = stlink_usb_read_mem32_noaddrinc(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\t\telse\n\t\t\tretval = stlink_usb_read_mem32(stlink_dap_handle, ap_num, csw, addr, bufsize, buf);\n\t\tif (retval == ERROR_OK)\n\t\t\tfor (unsigned int i = 0; i < count; i++)\n\t\t\t\t*q[i].mem_ap.p_data = le_to_h_u32(&buf[4 * i]);\n\t\treturn retval;\n\n\tdefault:\n\t\treturn ERROR_FAIL;\n\t};\n}\n\n/* TODO: recover these values with cmd STLINK_DEBUG_APIV2_RW_MISC_GET_MAX (0x53) */\n#define STLINK_V2_RW_MISC_SIZE (64)\n#define STLINK_V3_RW_MISC_SIZE (1227)\n\nstatic int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue *q, unsigned int len,\n\t\tunsigned int *pkt_items)\n{\n\tstruct stlink_usb_handle_s *h = handle;\n\tunsigned int i, items = 0;\n\tuint32_t ap_num = DP_APSEL_INVALID;\n\tunsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE;\n\n\tif (!(h->version.flags & STLINK_F_HAS_RW_MISC))\n\t\treturn 0;\n\t/*\n\t * Before stlink-server API v3, RW_MISC sequence doesn't lock the st-link,\n\t * so are not safe in shared mode.\n\t * Don't use it with TCP backend to prevent any issue in case of sharing.\n\t * This further degrades the performance, on top of TCP server overhead.\n\t */\n\tif (h->backend == &stlink_tcp_backend && h->tcp_backend_priv.version.api < 3)\n\t\treturn 0;\n\n\tfor (i = 0; i < len; i++) {\n\t\tif (q[i].cmd != CMD_MEM_AP_READ32 && q[i].cmd != CMD_MEM_AP_WRITE32)\n\t\t\tbreak;\n\t\tunsigned int count = 1;\n\t\tif (ap_num != q[i].mem_ap.ap->ap_num) {\n\t\t\tcount++;\n\t\t\tap_num = q[i].mem_ap.ap->ap_num;\n\t\t}\n\t\tif (q[i].cmd == CMD_MEM_AP_WRITE32)\n\t\t\tcount++;\n\t\tif (items + count > misc_max_items)\n\t\t\tbreak;\n\t\titems += count;\n\t}\n\n\t*pkt_items = items;\n\n\treturn i;\n}\n\nstatic int stlink_usb_count_buf_rw_queue(const struct dap_queue *q, unsigned int len)\n{\n\tuint32_t incr = CMD_MEM_AP_2_SIZE(q[0].cmd);\n\tunsigned int len_max;\n\n\tif (incr == 1)\n\t\tlen_max = stlink_usb_block(stlink_dap_handle);\n\telse\n\t\tlen_max = STLINK_MAX_RW16_32 / incr;\n\n\t/* check for no address increment, 32 bits only */\n\tif (len > 1 && incr == 4 && q[0].mem_ap.addr == q[1].mem_ap.addr)\n\t\tincr = 0;\n\n\tif (len > len_max)\n\t\tlen = len_max;\n\n\tfor (unsigned int i = 1; i < len; i++)\n\t\tif (q[i].cmd != q[0].cmd ||\n\t\t\tq[i].mem_ap.ap != q[0].mem_ap.ap ||\n\t\t\tq[i].mem_ap.csw != q[0].mem_ap.csw ||\n\t\t\tq[i].mem_ap.addr != q[i - 1].mem_ap.addr + incr)\n\t\t\treturn i;\n\n\treturn len;\n}\n\nstatic int stlink_usb_mem_rw_queue(void *handle, const struct dap_queue *q, unsigned int len, unsigned int *skip)\n{\n\tunsigned int count, misc_items = 0;\n\tint retval;\n\n\tunsigned int count_misc = stlink_usb_count_misc_rw_queue(handle, q, len, &misc_items);\n\tunsigned int count_buf = stlink_usb_count_buf_rw_queue(q, len);\n\n\tif (count_misc > count_buf) {\n\t\tcount = count_misc;\n\t\tretval = stlink_usb_misc_rw_segment(handle, q, count, misc_items);\n\t} else {\n\t\tcount = count_buf;\n\t\tretval = stlink_usb_buf_rw_segment(handle, q, count_buf);\n\t}\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*skip = count;\n\treturn ERROR_OK;\n}\n\nstatic void stlink_dap_run_internal(struct adiv5_dap *dap)\n{\n\tint retval = stlink_dap_check_reconnect(dap);\n\tif (retval != ERROR_OK) {\n\t\tstlink_dap_handle->queue_index = 0;\n\t\tstlink_dap_record_error(retval);\n\t\treturn;\n\t}\n\n\tunsigned int i = stlink_dap_handle->queue_index;\n\tstruct dap_queue *q = &stlink_dap_handle->queue[0];\n\n\twhile (i && stlink_dap_get_error() == ERROR_OK) {\n\t\tunsigned int skip = 1;\n\n\t\tswitch (q->cmd) {\n\t\tcase CMD_DP_READ:\n\t\t\tretval = stlink_dap_dp_read(q->dp_r.dap, q->dp_r.reg, q->dp_r.p_data);\n\t\t\tbreak;\n\t\tcase CMD_DP_WRITE:\n\t\t\tretval = stlink_dap_dp_write(q->dp_w.dap, q->dp_w.reg, q->dp_w.data);\n\t\t\tbreak;\n\t\tcase CMD_AP_READ:\n\t\t\tretval = stlink_dap_ap_read(q->ap_r.ap, q->ap_r.reg, q->ap_r.p_data);\n\t\t\tbreak;\n\t\tcase CMD_AP_WRITE:\n\t\t\t/* ignore increment packed, not supported */\n\t\t\tif (q->ap_w.reg == ADIV5_MEM_AP_REG_CSW)\n\t\t\t\tq->ap_w.data &= ~CSW_ADDRINC_PACKED;\n\t\t\tretval = stlink_dap_ap_write(q->ap_w.ap, q->ap_w.reg, q->ap_w.data);\n\t\t\tbreak;\n\n\t\tcase CMD_MEM_AP_READ8:\n\t\tcase CMD_MEM_AP_READ16:\n\t\tcase CMD_MEM_AP_READ32:\n\t\tcase CMD_MEM_AP_WRITE8:\n\t\tcase CMD_MEM_AP_WRITE16:\n\t\tcase CMD_MEM_AP_WRITE32:\n\t\t\tretval = stlink_usb_mem_rw_queue(stlink_dap_handle, q, i, &skip);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"ST-Link: Unknown queue command %d\", q->cmd);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t\tstlink_dap_record_error(retval);\n\t\tq += skip;\n\t\ti -= skip;\n\t}\n\n\tstlink_dap_handle->queue_index = 0;\n}\n\n/** */\nstatic int stlink_dap_run_finalize(struct adiv5_dap *dap)\n{\n\tuint32_t ctrlstat, pwrmask;\n\tint retval, saved_retval;\n\n\t/* Here no LOG_DEBUG. This is called continuously! */\n\n\t/*\n\t * ST-Link returns immediately after a DAP write, without waiting for it\n\t * to complete.\n\t * Run a dummy read to DP_RDBUFF, as suggested in\n\t * http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka16363.html\n\t */\n\tif (dap->stlink_flush_ap_write) {\n\t\tdap->stlink_flush_ap_write = false;\n\t\tretval = stlink_dap_dp_read(dap, DP_RDBUFF, NULL);\n\t\tif (retval != ERROR_OK) {\n\t\t\tdap->do_reconnect = true;\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tsaved_retval = stlink_dap_get_and_clear_error();\n\n\tretval = stlink_dap_dp_read(dap, DP_CTRL_STAT, &ctrlstat);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Fail reading CTRL/STAT register. Force reconnect\");\n\t\tdap->do_reconnect = true;\n\t\treturn retval;\n\t}\n\n\tif (ctrlstat & SSTICKYERR) {\n\t\tif (stlink_dap_handle->st_mode == STLINK_MODE_DEBUG_JTAG)\n\t\t\tretval = stlink_dap_dp_write(dap, DP_CTRL_STAT,\n\t\t\t\t\tctrlstat & (dap->dp_ctrl_stat | SSTICKYERR));\n\t\telse\n\t\t\tretval = stlink_dap_dp_write(dap, DP_ABORT, STKERRCLR);\n\t\tif (retval != ERROR_OK) {\n\t\t\tdap->do_reconnect = true;\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* check for power lost */\n\tpwrmask = dap->dp_ctrl_stat & (CDBGPWRUPREQ | CSYSPWRUPREQ);\n\tif ((ctrlstat & pwrmask) != pwrmask)\n\t\tdap->do_reconnect = true;\n\n\treturn saved_retval;\n}\n\nstatic int stlink_dap_op_queue_run(struct adiv5_dap *dap)\n{\n\tstlink_dap_run_internal(dap);\n\treturn stlink_dap_run_finalize(dap);\n}\n\n/** */\nstatic void stlink_dap_op_quit(struct adiv5_dap *dap)\n{\n\tint retval;\n\n\tretval = stlink_dap_closeall_ap();\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error closing APs\");\n}\n\nstatic int stlink_dap_op_queue_dp_read(struct adiv5_dap *dap, unsigned int reg,\n\tuint32_t *data)\n{\n\tif (stlink_dap_get_error() != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\tunsigned int i = stlink_dap_handle->queue_index++;\n\tstruct dap_queue *q = &stlink_dap_handle->queue[i];\n\tq->cmd = CMD_DP_READ;\n\tq->dp_r.reg = reg;\n\tq->dp_r.dap = dap;\n\tq->dp_r.p_data = data;\n\n\tif (i == MAX_QUEUE_DEPTH - 1)\n\t\tstlink_dap_run_internal(dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_dap_op_queue_dp_write(struct adiv5_dap *dap, unsigned int reg,\n\tuint32_t data)\n{\n\tif (stlink_dap_get_error() != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\tunsigned int i = stlink_dap_handle->queue_index++;\n\tstruct dap_queue *q = &stlink_dap_handle->queue[i];\n\tq->cmd = CMD_DP_WRITE;\n\tq->dp_w.reg = reg;\n\tq->dp_w.dap = dap;\n\tq->dp_w.data = data;\n\n\tif (i == MAX_QUEUE_DEPTH - 1)\n\t\tstlink_dap_run_internal(dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_dap_op_queue_ap_read(struct adiv5_ap *ap, unsigned int reg,\n\tuint32_t *data)\n{\n\tif (stlink_dap_get_error() != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\tunsigned int i = stlink_dap_handle->queue_index++;\n\tstruct dap_queue *q = &stlink_dap_handle->queue[i];\n\n\t/* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_RD_NO_INC\n\t * and STLINK_F_HAS_RW_MISC */\n\tif ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) &&\n\t\t\t(reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 ||\n\t\t\t reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) {\n\t\t/* de-queue previous write-TAR */\n\t\tstruct dap_queue *prev_q = q - 1;\n\t\tif (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) {\n\t\t\tstlink_dap_handle->queue_index = i;\n\t\t\ti--;\n\t\t\tq = prev_q;\n\t\t\tprev_q--;\n\t\t}\n\t\t/* de-queue previous write-CSW if it didn't changed ap->csw_default */\n\t\tif (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW &&\n\t\t\t\t!prev_q->ap_w.changes_csw_default) {\n\t\t\tstlink_dap_handle->queue_index = i;\n\t\t\tq = prev_q;\n\t\t}\n\n\t\tswitch (ap->csw_value & CSW_SIZE_MASK) {\n\t\tcase CSW_8BIT:\n\t\t\tq->cmd = CMD_MEM_AP_READ8;\n\t\t\tbreak;\n\t\tcase CSW_16BIT:\n\t\t\tq->cmd = CMD_MEM_AP_READ16;\n\t\t\tbreak;\n\t\tcase CSW_32BIT:\n\t\t\tq->cmd = CMD_MEM_AP_READ32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"ST-Link: Unsupported CSW size %d\", ap->csw_value & CSW_SIZE_MASK);\n\t\t\tstlink_dap_record_error(ERROR_FAIL);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tq->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));\n\t\tq->mem_ap.ap = ap;\n\t\tq->mem_ap.p_data = data;\n\t\tq->mem_ap.csw = ap->csw_default;\n\n\t\t/* force TAR and CSW update */\n\t\tap->tar_valid = false;\n\t\tap->csw_value = 0;\n\t} else {\n\t\tq->cmd = CMD_AP_READ;\n\t\tq->ap_r.reg = reg;\n\t\tq->ap_r.ap = ap;\n\t\tq->ap_r.p_data = data;\n\t}\n\n\tif (i == MAX_QUEUE_DEPTH - 1)\n\t\tstlink_dap_run_internal(ap->dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg,\n\tuint32_t data)\n{\n\tif (stlink_dap_get_error() != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\tunsigned int i = stlink_dap_handle->queue_index++;\n\tstruct dap_queue *q = &stlink_dap_handle->queue[i];\n\n\t/* test STLINK_F_HAS_CSW implicitly tests STLINK_F_HAS_MEM_16BIT, STLINK_F_HAS_MEM_WR_NO_INC\n\t * and STLINK_F_HAS_RW_MISC */\n\tif ((stlink_dap_handle->version.flags & STLINK_F_HAS_CSW) &&\n\t\t\t(reg == ADIV5_MEM_AP_REG_DRW || reg == ADIV5_MEM_AP_REG_BD0 || reg == ADIV5_MEM_AP_REG_BD1 ||\n\t\t\t reg == ADIV5_MEM_AP_REG_BD2 || reg == ADIV5_MEM_AP_REG_BD3)) {\n\t\t/* de-queue previous write-TAR */\n\t\tstruct dap_queue *prev_q = q - 1;\n\t\tif (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_TAR) {\n\t\t\tstlink_dap_handle->queue_index = i;\n\t\t\ti--;\n\t\t\tq = prev_q;\n\t\t\tprev_q--;\n\t\t}\n\t\t/* de-queue previous write-CSW if it didn't changed ap->csw_default */\n\t\tif (i && prev_q->cmd == CMD_AP_WRITE && prev_q->ap_w.ap == ap && prev_q->ap_w.reg == ADIV5_MEM_AP_REG_CSW &&\n\t\t\t\t!prev_q->ap_w.changes_csw_default) {\n\t\t\tstlink_dap_handle->queue_index = i;\n\t\t\tq = prev_q;\n\t\t}\n\n\t\tswitch (ap->csw_value & CSW_SIZE_MASK) {\n\t\tcase CSW_8BIT:\n\t\t\tq->cmd = CMD_MEM_AP_WRITE8;\n\t\t\tbreak;\n\t\tcase CSW_16BIT:\n\t\t\tq->cmd = CMD_MEM_AP_WRITE16;\n\t\t\tbreak;\n\t\tcase CSW_32BIT:\n\t\t\tq->cmd = CMD_MEM_AP_WRITE32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"ST-Link: Unsupported CSW size %d\", ap->csw_value & CSW_SIZE_MASK);\n\t\t\tstlink_dap_record_error(ERROR_FAIL);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tq->mem_ap.addr = (reg == ADIV5_MEM_AP_REG_DRW) ? ap->tar_value : ((ap->tar_value & ~0x0f) | (reg & 0x0c));\n\t\tq->mem_ap.ap = ap;\n\t\tq->mem_ap.data = data;\n\t\tq->mem_ap.csw = ap->csw_default;\n\n\t\t/* force TAR and CSW update */\n\t\tap->tar_valid = false;\n\t\tap->csw_value = 0;\n\t} else {\n\t\tq->cmd = CMD_AP_WRITE;\n\t\tq->ap_w.reg = reg;\n\t\tq->ap_w.ap = ap;\n\t\tq->ap_w.data = data;\n\t\tuint8_t ap_num = ap->ap_num;\n\t\tif (reg == ADIV5_MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap_num]) {\n\t\t\tq->ap_w.changes_csw_default = true;\n\t\t\tlast_csw_default[ap_num] = ap->csw_default;\n\t\t} else {\n\t\t\tq->ap_w.changes_csw_default = false;\n\t\t}\n\t}\n\n\tif (i == MAX_QUEUE_DEPTH - 1)\n\t\tstlink_dap_run_internal(ap->dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_swim_op_srst(void)\n{\n\treturn stlink_swim_generate_rst(stlink_dap_handle);\n}\n\nstatic int stlink_swim_op_read_mem(uint32_t addr, uint32_t size,\n\t\t\t\t\t\t\t\t   uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\tuint32_t bytes_remaining;\n\n\tLOG_DEBUG_IO(\"read at 0x%08\" PRIx32 \" len %\" PRIu32 \"*0x%08\" PRIx32, addr, size, count);\n\tcount *= size;\n\n\twhile (count) {\n\t\tbytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count;\n\t\tretval = stlink_swim_readbytes(stlink_dap_handle, addr, bytes_remaining, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_swim_op_write_mem(uint32_t addr, uint32_t size,\n\t\t\t\t\t\t\t\t\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\tuint32_t bytes_remaining;\n\n\tLOG_DEBUG_IO(\"write at 0x%08\" PRIx32 \" len %\" PRIu32 \"*0x%08\" PRIx32, addr, size, count);\n\tcount *= size;\n\n\twhile (count) {\n\t\tbytes_remaining = (count > STLINK_SWIM_DATA_SIZE) ? STLINK_SWIM_DATA_SIZE : count;\n\t\tretval = stlink_swim_writebytes(stlink_dap_handle, addr, bytes_remaining, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stlink_swim_op_reconnect(void)\n{\n\tint retval;\n\n\tretval = stlink_usb_mode_enter(stlink_dap_handle, STLINK_MODE_DEBUG_SWIM);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn stlink_swim_resync(stlink_dap_handle);\n}\n\nstatic int stlink_dap_config_trace(bool enabled,\n\t\tenum tpiu_pin_protocol pin_protocol, uint32_t port_size,\n\t\tunsigned int *trace_freq, unsigned int traceclkin_freq,\n\t\tuint16_t *prescaler)\n{\n\treturn stlink_config_trace(stlink_dap_handle, enabled, pin_protocol,\n\t\t\t\t\t\t\t   port_size, trace_freq, traceclkin_freq,\n\t\t\t\t\t\t\t   prescaler);\n}\n\nstatic int stlink_dap_trace_read(uint8_t *buf, size_t *size)\n{\n\treturn stlink_usb_trace_read(stlink_dap_handle, buf, size);\n}\n\n/** */\nCOMMAND_HANDLER(stlink_dap_vid_pid)\n{\n\tunsigned int i, max_usb_ids = HLA_MAX_USB_IDS;\n\n\tif (CMD_ARGC > max_usb_ids * 2) {\n\t\tLOG_WARNING(\"ignoring extra IDs in vid_pid \"\n\t\t\t\"(maximum is %d pairs)\", max_usb_ids);\n\t\tCMD_ARGC = max_usb_ids * 2;\n\t}\n\tif (CMD_ARGC < 2 || (CMD_ARGC & 1)) {\n\t\tLOG_WARNING(\"incomplete vid_pid configuration directive\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tfor (i = 0; i < CMD_ARGC; i += 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], stlink_dap_param.vid[i / 2]);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], stlink_dap_param.pid[i / 2]);\n\t}\n\n\t/* null termination */\n\tstlink_dap_param.vid[i / 2] = stlink_dap_param.pid[i / 2] = 0;\n\n\treturn ERROR_OK;\n}\n\n/** */\nCOMMAND_HANDLER(stlink_dap_backend_command)\n{\n\t/* default values */\n\tbool use_stlink_tcp = false;\n\tuint16_t stlink_tcp_port = 7184;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (strcmp(CMD_ARGV[0], \"usb\") == 0) {\n\t\tif (CMD_ARGC > 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t/* else use_stlink_tcp = false (already the case ) */\n\t} else if (strcmp(CMD_ARGV[0], \"tcp\") == 0) {\n\t\tuse_stlink_tcp = true;\n\t\tif (CMD_ARGC == 2)\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_tcp_port);\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstlink_dap_param.use_stlink_tcp = use_stlink_tcp;\n\tstlink_dap_param.stlink_tcp_port = stlink_tcp_port;\n\n\treturn ERROR_OK;\n}\n\n#define BYTES_PER_LINE 16\nCOMMAND_HANDLER(stlink_dap_cmd_command)\n{\n\tunsigned int rx_n, tx_n;\n\tstruct stlink_usb_handle_s *h = stlink_dap_handle;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], rx_n);\n\ttx_n = CMD_ARGC - 1;\n\tif (tx_n > STLINK_SG_SIZE || rx_n > STLINK_DATA_SIZE) {\n\t\tLOG_ERROR(\"max %x byte sent and %d received\", STLINK_SG_SIZE, STLINK_DATA_SIZE);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstlink_usb_init_buffer(h, h->rx_ep, rx_n);\n\n\tfor (unsigned int i = 0; i < tx_n; i++) {\n\t\tuint8_t byte;\n\t\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[i + 1], byte);\n\t\th->cmdbuf[h->cmdidx++] = byte;\n\t}\n\n\tint retval = stlink_usb_xfer_noerrcheck(h, h->databuf, rx_n);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error %d\", retval);\n\t\treturn retval;\n\t}\n\n\tfor (unsigned int i = 0; i < rx_n; i++)\n\t\tcommand_print_sameline(CMD, \"0x%02x%c\", h->databuf[i],\n\t\t\t((i == (rx_n - 1)) || ((i % BYTES_PER_LINE) == (BYTES_PER_LINE - 1))) ? '\\n' : ' ');\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic const struct command_registration stlink_dap_subcommand_handlers[] = {\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = stlink_dap_vid_pid,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"USB VID and PID of the adapter\",\n\t\t.usage = \"(vid pid)+\",\n\t},\n\t{\n\t\t.name = \"backend\",\n\t\t.handler = &stlink_dap_backend_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"select which ST-Link backend to use\",\n\t\t.usage = \"usb | tcp [port]\",\n\t},\n\t{\n\t\t.name = \"cmd\",\n\t\t.handler = stlink_dap_cmd_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"send arbitrary command\",\n\t\t.usage = \"rx_n (tx_byte)+\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** */\nstatic const struct command_registration stlink_dap_command_handlers[] = {\n\t{\n\t\t.name = \"st-link\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform st-link management\",\n\t\t.chain = stlink_dap_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** */\nstatic int stlink_dap_init(void)\n{\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tenum stlink_mode mode;\n\tint retval;\n\n\tLOG_DEBUG(\"stlink_dap_init()\");\n\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\tstlink_dap_param.connect_under_reset = true;\n\t\telse\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t}\n\n\tif (transport_is_dapdirect_swd())\n\t\tmode = STLINK_MODE_DEBUG_SWD;\n\telse if (transport_is_dapdirect_jtag())\n\t\tmode = STLINK_MODE_DEBUG_JTAG;\n\telse if (transport_is_swim())\n\t\tmode = STLINK_MODE_DEBUG_SWIM;\n\telse {\n\t\tLOG_ERROR(\"Unsupported transport\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = stlink_open(&stlink_dap_param, mode, (void **)&stlink_dap_handle);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((mode != STLINK_MODE_DEBUG_SWIM) &&\n\t\t!(stlink_dap_handle->version.flags & STLINK_F_HAS_DAP_REG)) {\n\t\tLOG_ERROR(\"ST-Link version does not support DAP direct transport\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_quit(void)\n{\n\tLOG_DEBUG(\"stlink_dap_quit()\");\n\n\treturn stlink_close(stlink_dap_handle);\n}\n\n/** */\nstatic int stlink_dap_reset(int req_trst, int req_srst)\n{\n\tLOG_DEBUG(\"stlink_dap_reset(%d)\", req_srst);\n\treturn stlink_usb_assert_srst(stlink_dap_handle,\n\t\treq_srst ? STLINK_DEBUG_APIV2_DRIVE_NRST_LOW\n\t\t\t\t : STLINK_DEBUG_APIV2_DRIVE_NRST_HIGH);\n}\n\n/** */\nstatic int stlink_dap_speed(int speed)\n{\n\tif (speed == 0) {\n\t\tLOG_ERROR(\"RTCK not supported. Set nonzero adapter_khz.\");\n\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\t}\n\n\tstlink_dap_param.initial_interface_speed = speed;\n\tstlink_speed(stlink_dap_handle, speed, false);\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_khz(int khz, int *jtag_speed)\n{\n\tif (khz == 0) {\n\t\tLOG_ERROR(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*jtag_speed = stlink_speed(stlink_dap_handle, khz, true);\n\treturn ERROR_OK;\n}\n\n/** */\nstatic int stlink_dap_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\treturn ERROR_OK;\n}\n\nstatic const struct dap_ops stlink_dap_ops = {\n\t.connect = stlink_dap_op_connect,\n\t.send_sequence = stlink_dap_op_send_sequence,\n\t.queue_dp_read = stlink_dap_op_queue_dp_read,\n\t.queue_dp_write = stlink_dap_op_queue_dp_write,\n\t.queue_ap_read = stlink_dap_op_queue_ap_read,\n\t.queue_ap_write = stlink_dap_op_queue_ap_write,\n\t.queue_ap_abort = stlink_dap_op_queue_ap_abort,\n\t.run = stlink_dap_op_queue_run,\n\t.sync = NULL, /* optional */\n\t.quit = stlink_dap_op_quit, /* optional */\n};\n\nstatic const struct swim_driver stlink_swim_ops = {\n\t.srst = stlink_swim_op_srst,\n\t.read_mem = stlink_swim_op_read_mem,\n\t.write_mem = stlink_swim_op_write_mem,\n\t.reconnect = stlink_swim_op_reconnect,\n};\n\nstatic const char *const stlink_dap_transport[] = { \"dapdirect_swd\", \"dapdirect_jtag\", \"swim\", NULL };\n\nstruct adapter_driver stlink_dap_adapter_driver = {\n\t.name = \"st-link\",\n\t.transports = stlink_dap_transport,\n\t.commands = stlink_dap_command_handlers,\n\n\t.init = stlink_dap_init,\n\t.quit = stlink_dap_quit,\n\t.reset = stlink_dap_reset,\n\t.speed = stlink_dap_speed,\n\t.khz = stlink_dap_khz,\n\t.speed_div = stlink_dap_speed_div,\n\t.config_trace = stlink_dap_config_trace,\n\t.poll_trace = stlink_dap_trace_read,\n\n\t.dap_jtag_ops = &stlink_dap_ops,\n\t.dap_swd_ops = &stlink_dap_ops,\n\t.swim_ops = &stlink_swim_ops,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/sysfsgpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2012 by Creative Product Design, marc @ cpdesign.com.au *\n ***************************************************************************/\n\n/* 2014-12: Addition of the SWD protocol support is based on the initial work\n * on bcm2835gpio.c by Paul Fertser and modifications by Jean-Christian de Rivaz. */\n\n/**\n * @file\n * This driver implements a bitbang jtag interface using gpio lines via\n * sysfs.\n * The aim of this driver implementation is use system GPIOs but avoid the\n * need for a additional kernel driver.\n * (Note memory mapped IO is another option, however it doesn't mix well with\n * the kernel gpiolib driver - which makes sense I guess.)\n *\n * A gpio is required for tck, tms, tdi and tdo. One or both of srst and trst\n * must be also be specified. The required jtag gpios are specified via the\n * sysfsgpio_jtag_nums command or the relevant sysfsgpio_XXX_num commands.\n * The srst and trst gpios are set via the sysfsgpio_srst_num and\n * sysfsgpio_trst_num respectively. GPIO numbering follows the kernel\n * convention of starting from 0.\n *\n * The gpios should not be in use by another entity, and must not be requested\n * by a kernel driver without also being exported by it (otherwise they can't\n * be exported by sysfs).\n *\n * The sysfs gpio interface can only manipulate one gpio at a time, so the\n * bitbang write handler remembers the last state for tck, tms, tdi to avoid\n * superfluous writes.\n * For speed the sysfs \"value\" entry is opened at init and held open.\n * This results in considerable gains over open-write-close (45s vs 900s)\n *\n * Further work could address:\n *  -srst and trst open drain/ push pull\n *  -configurable active high/low for srst & trst\n */\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include \"bitbang.h\"\n\n/*\n * Helper func to determine if gpio number valid\n *\n * Assume here that there will be less than 10000 gpios on a system\n */\nstatic bool is_gpio_valid(int gpio)\n{\n\treturn gpio >= 0 && gpio < 10000;\n}\n\n/*\n * Helper func to open, write to and close a file\n * name and valstr must be null terminated.\n *\n * Returns negative on failure.\n */\nstatic int open_write_close(const char *name, const char *valstr)\n{\n\tint ret;\n\tint fd = open(name, O_WRONLY);\n\tif (fd < 0)\n\t\treturn fd;\n\n\tret = write(fd, valstr, strlen(valstr));\n\tclose(fd);\n\n\treturn ret;\n}\n\n/*\n * Helper func to unexport gpio from sysfs\n */\nstatic void unexport_sysfs_gpio(int gpio)\n{\n\tchar gpiostr[5];\n\n\tif (!is_gpio_valid(gpio))\n\t\treturn;\n\n\tsnprintf(gpiostr, sizeof(gpiostr), \"%d\", gpio);\n\tif (open_write_close(\"/sys/class/gpio/unexport\", gpiostr) < 0)\n\t\tLOG_ERROR(\"Couldn't unexport gpio %d\", gpio);\n}\n\n/*\n * Exports and sets up direction for gpio.\n * If the gpio is an output, it is initialized according to init_high,\n * otherwise it is ignored.\n *\n * If the gpio is already exported we just show a warning and continue; if\n * openocd happened to crash (or was killed by user) then the gpios will not\n * have been cleaned up.\n */\nstatic int setup_sysfs_gpio(int gpio, int is_output, int init_high)\n{\n\tstruct timeval timeout, now;\n\tchar buf[40];\n\tchar gpiostr[5];\n\tint ret;\n\n\tif (!is_gpio_valid(gpio))\n\t\treturn ERROR_OK;\n\n\tsnprintf(gpiostr, sizeof(gpiostr), \"%d\", gpio);\n\tret = open_write_close(\"/sys/class/gpio/export\", gpiostr);\n\tif (ret < 0) {\n\t\tif (errno == EBUSY) {\n\t\t\tLOG_WARNING(\"gpio %d is already exported\", gpio);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Couldn't export gpio %d\", gpio);\n\t\t\tLOG_ERROR(\"sysfsgpio: %s\", strerror(errno));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, 0, 500000);\n\n\tsnprintf(buf, sizeof(buf), \"/sys/class/gpio/gpio%d/direction\", gpio);\n\tfor (;;) {\n\t\tret = open_write_close(buf, is_output ? (init_high ? \"high\" : \"low\") : \"in\");\n\t\tif (ret >= 0 || errno != EACCES)\n\t\t\tbreak;\n\t\tgettimeofday(&now, NULL);\n\t\tif (timeval_compare(&now, &timeout) >= 0)\n\t\t\tbreak;\n\t\tjtag_sleep(10000);\n\t}\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"Couldn't set direction for gpio %d\", gpio);\n\t\tLOG_ERROR(\"sysfsgpio: %s\", strerror(errno));\n\t\tunexport_sysfs_gpio(gpio);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsnprintf(buf, sizeof(buf), \"/sys/class/gpio/gpio%d/value\", gpio);\n\tfor (;;) {\n\t\tret = open(buf, O_RDWR | O_NONBLOCK | O_SYNC);\n\t\tif (ret >= 0 || errno != EACCES)\n\t\t\tbreak;\n\t\tgettimeofday(&now, NULL);\n\t\tif (timeval_compare(&now, &timeout) >= 0)\n\t\t\tbreak;\n\t\tjtag_sleep(10000);\n\t}\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"Couldn't open value for gpio %d\", gpio);\n\t\tLOG_ERROR(\"sysfsgpio: %s\", strerror(errno));\n\t\tunexport_sysfs_gpio(gpio);\n\t}\n\n\treturn ret;\n}\n\n/* gpio numbers for each gpio. Negative values are invalid */\nstatic int tck_gpio = -1;\nstatic int tms_gpio = -1;\nstatic int tdi_gpio = -1;\nstatic int tdo_gpio = -1;\nstatic int trst_gpio = -1;\nstatic int srst_gpio = -1;\nstatic int swclk_gpio = -1;\nstatic int swdio_gpio = -1;\n\n/*\n * file descriptors for /sys/class/gpio/gpioXX/value\n * Set up during init.\n */\nstatic int tck_fd = -1;\nstatic int tms_fd = -1;\nstatic int tdi_fd = -1;\nstatic int tdo_fd = -1;\nstatic int trst_fd = -1;\nstatic int srst_fd = -1;\nstatic int swclk_fd = -1;\nstatic int swdio_fd = -1;\n\nstatic int last_swclk;\nstatic int last_swdio;\nstatic bool last_stored;\nstatic bool swdio_input;\n\nstatic void sysfsgpio_swdio_drive(bool is_output)\n{\n\tchar buf[40];\n\tint ret;\n\n\tsnprintf(buf, sizeof(buf), \"/sys/class/gpio/gpio%d/direction\", swdio_gpio);\n\tret = open_write_close(buf, is_output ? \"high\" : \"in\");\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"Couldn't set direction for gpio %d\", swdio_gpio);\n\t\tLOG_ERROR(\"sysfsgpio: %s\", strerror(errno));\n\t}\n\n\tlast_stored = false;\n\tswdio_input = !is_output;\n}\n\nstatic int sysfsgpio_swdio_read(void)\n{\n\tchar buf[1];\n\n\t/* important to seek to signal sysfs of new read */\n\tlseek(swdio_fd, 0, SEEK_SET);\n\tint ret = read(swdio_fd, &buf, sizeof(buf));\n\n\tif (ret < 0) {\n\t\tLOG_WARNING(\"reading swdio failed\");\n\t\treturn 0;\n\t}\n\n\treturn buf[0] != '0';\n}\n\nstatic int sysfsgpio_swd_write(int swclk, int swdio)\n{\n\tconst char one[] = \"1\";\n\tconst char zero[] = \"0\";\n\n\tsize_t bytes_written;\n\n\tif (!swdio_input) {\n\t\tif (!last_stored || (swdio != last_swdio)) {\n\t\t\tbytes_written = write(swdio_fd, swdio ? &one : &zero, 1);\n\t\t\tif (bytes_written != 1)\n\t\t\t\tLOG_WARNING(\"writing swdio failed\");\n\t\t}\n\t}\n\n\t/* write swclk last */\n\tif (!last_stored || (swclk != last_swclk)) {\n\t\tbytes_written = write(swclk_fd, swclk ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing swclk failed\");\n\t}\n\n\tlast_swdio = swdio;\n\tlast_swclk = swclk;\n\tlast_stored = true;\n\n\treturn ERROR_OK;\n}\n\n/*\n * Bitbang interface read of TDO\n *\n * The sysfs value will read back either '0' or '1'. The trick here is to call\n * lseek to bypass buffering in the sysfs kernel driver.\n */\nstatic bb_value_t sysfsgpio_read(void)\n{\n\tchar buf[1];\n\n\t/* important to seek to signal sysfs of new read */\n\tlseek(tdo_fd, 0, SEEK_SET);\n\tint ret = read(tdo_fd, &buf, sizeof(buf));\n\n\tif (ret < 0) {\n\t\tLOG_WARNING(\"reading tdo failed\");\n\t\treturn 0;\n\t}\n\n\treturn buf[0] == '0' ? BB_LOW : BB_HIGH;\n}\n\n/*\n * Bitbang interface write of TCK, TMS, TDI\n *\n * Seeing as this is the only function where the outputs are changed,\n * we can cache the old value to avoid needlessly writing it.\n */\nstatic int sysfsgpio_write(int tck, int tms, int tdi)\n{\n\tconst char one[] = \"1\";\n\tconst char zero[] = \"0\";\n\n\tstatic int last_tck;\n\tstatic int last_tms;\n\tstatic int last_tdi;\n\n\tstatic int first_time;\n\tsize_t bytes_written;\n\n\tif (!first_time) {\n\t\tlast_tck = !tck;\n\t\tlast_tms = !tms;\n\t\tlast_tdi = !tdi;\n\t\tfirst_time = 1;\n\t}\n\n\tif (tdi != last_tdi) {\n\t\tbytes_written = write(tdi_fd, tdi ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tdi failed\");\n\t}\n\n\tif (tms != last_tms) {\n\t\tbytes_written = write(tms_fd, tms ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tms failed\");\n\t}\n\n\t/* write clk last */\n\tif (tck != last_tck) {\n\t\tbytes_written = write(tck_fd, tck ? &one : &zero, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing tck failed\");\n\t}\n\n\tlast_tdi = tdi;\n\tlast_tms = tms;\n\tlast_tck = tck;\n\n\treturn ERROR_OK;\n}\n\n/*\n * Bitbang interface to manipulate reset lines SRST and TRST\n *\n * (1) assert or (0) deassert reset lines\n */\nstatic int sysfsgpio_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"sysfsgpio_reset\");\n\tconst char one[] = \"1\";\n\tconst char zero[] = \"0\";\n\tsize_t bytes_written;\n\n\t/* assume active low */\n\tif (srst_fd >= 0) {\n\t\tbytes_written = write(srst_fd, srst ? &zero : &one, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing srst failed\");\n\t}\n\n\t/* assume active low */\n\tif (trst_fd >= 0) {\n\t\tbytes_written = write(trst_fd, trst ? &zero : &one, 1);\n\t\tif (bytes_written != 1)\n\t\t\tLOG_WARNING(\"writing trst failed\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionums)\n{\n\tif (CMD_ARGC == 4) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tms_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[2], tdi_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[3], tdo_gpio);\n\t} else if (CMD_ARGC != 0) {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD,\n\t\t\t\"SysfsGPIO nums: tck = %d, tms = %d, tdi = %d, tdo = %d\",\n\t\t\ttck_gpio, tms_gpio, tdi_gpio, tdo_gpio);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tck)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tck_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: tck = %d\", tck_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tms)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tms_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: tms = %d\", tms_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdo)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdo_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: tdo = %d\", tdo_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_tdi)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tdi_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: tdi = %d\", tdi_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_srst)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], srst_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: srst = %d\", srst_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_jtag_gpionum_trst)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], trst_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: trst = %d\", trst_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_swd_gpionums)\n{\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], swdio_gpio);\n\t} else if (CMD_ARGC != 0) {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD,\n\t\t\t\"SysfsGPIO nums: swclk = %d, swdio = %d\",\n\t\t\tswclk_gpio, swdio_gpio);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swclk)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swclk_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: swclk = %d\", swclk_gpio);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(sysfsgpio_handle_swd_gpionum_swdio)\n{\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], swdio_gpio);\n\n\tcommand_print(CMD, \"SysfsGPIO num: swdio = %d\", swdio_gpio);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration sysfsgpio_subcommand_handlers[] = {\n\t{\n\t\t.name = \"jtag_nums\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionums,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio numbers for tck, tms, tdi, tdo. (in that order)\",\n\t\t.usage = \"[tck tms tdi tdo]\",\n\t},\n\t{\n\t\t.name = \"tck_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_tck,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tck.\",\n\t\t.usage = \"[tck]\",\n\t},\n\t{\n\t\t.name = \"tms_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_tms,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tms.\",\n\t\t.usage = \"[tms]\",\n\t},\n\t{\n\t\t.name = \"tdo_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_tdo,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdo.\",\n\t\t.usage = \"[tdo]\",\n\t},\n\t{\n\t\t.name = \"tdi_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_tdi,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for tdi.\",\n\t\t.usage = \"[tdi]\",\n\t},\n\t{\n\t\t.name = \"srst_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_srst,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for srst.\",\n\t\t.usage = \"[srst]\",\n\t},\n\t{\n\t\t.name = \"trst_num\",\n\t\t.handler = &sysfsgpio_handle_jtag_gpionum_trst,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for trst.\",\n\t\t.usage = \"[trst]\",\n\t},\n\t{\n\t\t.name = \"swd_nums\",\n\t\t.handler = &sysfsgpio_handle_swd_gpionums,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio numbers for swclk, swdio. (in that order)\",\n\t\t.usage = \"[swclk swdio]\",\n\t},\n\t{\n\t\t.name = \"swclk_num\",\n\t\t.handler = &sysfsgpio_handle_swd_gpionum_swclk,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for swclk.\",\n\t\t.usage = \"[swclk]\",\n\t},\n\t{\n\t\t.name = \"swdio_num\",\n\t\t.handler = &sysfsgpio_handle_swd_gpionum_swdio,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"gpio number for swdio.\",\n\t\t.usage = \"[swdio]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration sysfsgpio_command_handlers[] = {\n\t{\n\t\t.name = \"sysfsgpio\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform sysfsgpio management\",\n\t\t.chain = sysfsgpio_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int sysfsgpio_init(void);\nstatic int sysfsgpio_quit(void);\n\nstatic const char * const sysfsgpio_transports[] = { \"jtag\", \"swd\", NULL };\n\nstatic struct jtag_interface sysfsgpio_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = bitbang_execute_queue,\n};\n\nstruct adapter_driver sysfsgpio_adapter_driver = {\n\t.name = \"sysfsgpio\",\n\t.transports = sysfsgpio_transports,\n\t.commands = sysfsgpio_command_handlers,\n\n\t.init = sysfsgpio_init,\n\t.quit = sysfsgpio_quit,\n\t.reset = sysfsgpio_reset,\n\n\t.jtag_ops = &sysfsgpio_interface,\n\t.swd_ops = &bitbang_swd,\n};\n\nstatic struct bitbang_interface sysfsgpio_bitbang = {\n\t.read = sysfsgpio_read,\n\t.write = sysfsgpio_write,\n\t.swdio_read = sysfsgpio_swdio_read,\n\t.swdio_drive = sysfsgpio_swdio_drive,\n\t.swd_write = sysfsgpio_swd_write,\n\t.blink = NULL,\n};\n\n/* helper func to close and cleanup files only if they were valid/ used */\nstatic void cleanup_fd(int fd, int gpio)\n{\n\tif (gpio >= 0) {\n\t\tif (fd >= 0)\n\t\t\tclose(fd);\n\n\t\tunexport_sysfs_gpio(gpio);\n\t}\n}\n\nstatic void cleanup_all_fds(void)\n{\n\tif (transport_is_jtag()) {\n\t\tcleanup_fd(tck_fd, tck_gpio);\n\t\tcleanup_fd(tms_fd, tms_gpio);\n\t\tcleanup_fd(tdi_fd, tdi_gpio);\n\t\tcleanup_fd(tdo_fd, tdo_gpio);\n\t\tcleanup_fd(trst_fd, trst_gpio);\n\t}\n\tif (transport_is_swd()) {\n\t\tcleanup_fd(swclk_fd, swclk_gpio);\n\t\tcleanup_fd(swdio_fd, swdio_gpio);\n\t}\n\tcleanup_fd(srst_fd, srst_gpio);\n}\n\nstatic bool sysfsgpio_jtag_mode_possible(void)\n{\n\tif (!is_gpio_valid(tck_gpio))\n\t\treturn false;\n\tif (!is_gpio_valid(tms_gpio))\n\t\treturn false;\n\tif (!is_gpio_valid(tdi_gpio))\n\t\treturn false;\n\tif (!is_gpio_valid(tdo_gpio))\n\t\treturn false;\n\treturn true;\n}\n\nstatic bool sysfsgpio_swd_mode_possible(void)\n{\n\tif (!is_gpio_valid(swclk_gpio))\n\t\treturn false;\n\tif (!is_gpio_valid(swdio_gpio))\n\t\treturn false;\n\treturn true;\n}\n\nstatic int sysfsgpio_init(void)\n{\n\tbitbang_interface = &sysfsgpio_bitbang;\n\n\tLOG_INFO(\"SysfsGPIO JTAG/SWD bitbang driver\");\n\n\t/*\n\t * Configure TDO as an input, and TDI, TCK, TMS, TRST, SRST\n\t * as outputs.  Drive TDI and TCK low, and TMS/TRST/SRST high.\n\t * For SWD, SWCLK and SWDIO are configures as output high.\n\t */\n\n\tif (transport_is_jtag()) {\n\t\tif (!sysfsgpio_jtag_mode_possible()) {\n\t\t\tLOG_ERROR(\"Require tck, tms, tdi and tdo gpios for JTAG mode\");\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\n\t\ttck_fd = setup_sysfs_gpio(tck_gpio, 1, 0);\n\t\tif (tck_fd < 0)\n\t\t\tgoto out_error;\n\n\t\ttms_fd = setup_sysfs_gpio(tms_gpio, 1, 1);\n\t\tif (tms_fd < 0)\n\t\t\tgoto out_error;\n\n\t\ttdi_fd = setup_sysfs_gpio(tdi_gpio, 1, 0);\n\t\tif (tdi_fd < 0)\n\t\t\tgoto out_error;\n\n\t\ttdo_fd = setup_sysfs_gpio(tdo_gpio, 0, 0);\n\t\tif (tdo_fd < 0)\n\t\t\tgoto out_error;\n\n\t\t/* assume active low*/\n\t\tif (trst_gpio >= 0) {\n\t\t\ttrst_fd = setup_sysfs_gpio(trst_gpio, 1, 1);\n\t\t\tif (trst_fd < 0)\n\t\t\t\tgoto out_error;\n\t\t}\n\t}\n\n\tif (transport_is_swd()) {\n\t\tif (!sysfsgpio_swd_mode_possible()) {\n\t\t\tLOG_ERROR(\"Require swclk and swdio gpio for SWD mode\");\n\t\t\treturn ERROR_JTAG_INIT_FAILED;\n\t\t}\n\n\t\tswclk_fd = setup_sysfs_gpio(swclk_gpio, 1, 0);\n\t\tif (swclk_fd < 0)\n\t\t\tgoto out_error;\n\n\t\tswdio_fd = setup_sysfs_gpio(swdio_gpio, 1, 0);\n\t\tif (swdio_fd < 0)\n\t\t\tgoto out_error;\n\t}\n\n\t/* assume active low*/\n\tif (srst_gpio >= 0) {\n\t\tsrst_fd = setup_sysfs_gpio(srst_gpio, 1, 1);\n\t\tif (srst_fd < 0)\n\t\t\tgoto out_error;\n\t}\n\n\treturn ERROR_OK;\n\nout_error:\n\tcleanup_all_fds();\n\treturn ERROR_JTAG_INIT_FAILED;\n}\n\nstatic int sysfsgpio_quit(void)\n{\n\tcleanup_all_fds();\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ti_icdi_usb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <helper/binarybuffer.h>\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/hla/hla_layout.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n#include <target/target.h>\n\n#include <target/cortex_m.h>\n\n#include \"libusb_helper.h\"\n\n#define ICDI_WRITE_ENDPOINT 0x02\n#define ICDI_READ_ENDPOINT 0x83\n\n#define ICDI_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS)\n#define ICDI_READ_TIMEOUT (LIBUSB_TIMEOUT_MS)\n#define ICDI_PACKET_SIZE 2048\n\n#define PACKET_START \"$\"\n#define PACKET_END \"#\"\n\nstruct icdi_usb_handle_s {\n\tstruct libusb_device_handle *usb_dev;\n\n\tchar *read_buffer;\n\tchar *write_buffer;\n\tint max_packet;\n\tint read_count;\n\tuint32_t max_rw_packet; /* max X packet (read/write memory) transfers */\n};\n\nstatic int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, uint8_t *buffer);\nstatic int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, const uint8_t *buffer);\n\nstatic int remote_escape_output(const char *buffer, int len, char *out_buf, int *out_len, int out_maxlen)\n{\n\tint input_index, output_index;\n\n\toutput_index = 0;\n\n\tfor (input_index = 0; input_index < len; input_index++) {\n\n\t\tchar b = buffer[input_index];\n\n\t\tif (b == '$' || b == '#' || b == '}' || b == '*') {\n\t\t\t/* These must be escaped.  */\n\t\t\tif (output_index + 2 > out_maxlen)\n\t\t\t\tbreak;\n\t\t\tout_buf[output_index++] = '}';\n\t\t\tout_buf[output_index++] = b ^ 0x20;\n\t\t} else {\n\t\t\tif (output_index + 1 > out_maxlen)\n\t\t\t\tbreak;\n\t\t\tout_buf[output_index++] = b;\n\t\t}\n\t}\n\n\t*out_len = input_index;\n\treturn output_index;\n}\n\nstatic int remote_unescape_input(const char *buffer, int len, char *out_buf, int out_maxlen)\n{\n\tint input_index, output_index;\n\tint escaped;\n\n\toutput_index = 0;\n\tescaped = 0;\n\n\tfor (input_index = 0; input_index < len; input_index++) {\n\n\t\tchar b = buffer[input_index];\n\n\t\tif (output_index + 1 > out_maxlen)\n\t\t\tLOG_ERROR(\"Received too much data from the target.\");\n\n\t\tif (escaped) {\n\t\t\tout_buf[output_index++] = b ^ 0x20;\n\t\t\tescaped = 0;\n\t\t} else if (b == '}')\n\t\t\tescaped = 1;\n\t\telse\n\t\t\tout_buf[output_index++] = b;\n\t}\n\n\tif (escaped)\n\t\tLOG_ERROR(\"Unmatched escape character in target response.\");\n\n\treturn output_index;\n}\n\nstatic int icdi_send_packet(void *handle, int len)\n{\n\tunsigned char cksum = 0;\n\tstruct icdi_usb_handle_s *h = handle;\n\tint result, retry = 0;\n\tint transferred = 0;\n\n\tassert(handle);\n\n\t/* check we have a large enough buffer for checksum \"#00\" */\n\tif (len + 3 > h->max_packet) {\n\t\tLOG_ERROR(\"packet buffer too small\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* calculate checksum - offset start of packet */\n\tfor (int i = 1; i < len; i++)\n\t\tcksum += h->write_buffer[i];\n\n\tlen += sprintf(&h->write_buffer[len], PACKET_END \"%02x\", cksum);\n\n#ifdef _DEBUG_USB_COMMS_\n\tchar buffer[50];\n\tchar ch = h->write_buffer[1];\n\tif (ch == 'x' || ch == 'X')\n\t\tLOG_DEBUG(\"writing packet: <binary>\");\n\telse {\n\t\tmemcpy(buffer, h->write_buffer, len >= 50 ? 50-1 : len);\n\t\tbuffer[len] = 0;\n\t\tLOG_DEBUG(\"writing packet: %s\", buffer);\n\t}\n#endif\n\n\twhile (1) {\n\n\t\tresult = libusb_bulk_transfer(h->usb_dev, ICDI_WRITE_ENDPOINT, (unsigned char *)h->write_buffer, len,\n\t\t\t\t&transferred, ICDI_WRITE_TIMEOUT);\n\t\tif (result != 0 || transferred != len) {\n\t\t\tLOG_DEBUG(\"Error TX Data %d\", result);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* check that the client got the message ok, or shall we resend */\n\t\tresult = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer, h->max_packet,\n\t\t\t\t\t&transferred, ICDI_READ_TIMEOUT);\n\t\tif (result != 0 || transferred < 1) {\n\t\t\tLOG_DEBUG(\"Error RX Data %d\", result);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n#ifdef _DEBUG_USB_COMMS_\n\t\tLOG_DEBUG(\"received reply: '%c' : count %d\", h->read_buffer[0], transferred);\n#endif\n\n\t\tif (h->read_buffer[0] == '-') {\n\t\t\tLOG_DEBUG(\"Resending packet %d\", ++retry);\n\t\t} else {\n\t\t\tif (h->read_buffer[0] != '+')\n\t\t\t\tLOG_DEBUG(\"Unexpected Reply from ICDI: %c\", h->read_buffer[0]);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (retry == 3) {\n\t\t\tLOG_DEBUG(\"maximum nack retries attempted\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tretry = 0;\n\th->read_count = transferred;\n\n\twhile (1) {\n\n\t\t/* read reply from icdi */\n\t\tresult = libusb_bulk_transfer(h->usb_dev, ICDI_READ_ENDPOINT, (unsigned char *)h->read_buffer + h->read_count,\n\t\t\t\th->max_packet - h->read_count, &transferred, ICDI_READ_TIMEOUT);\n\n#ifdef _DEBUG_USB_COMMS_\n\t\tLOG_DEBUG(\"received data: count %d\", transferred);\n#endif\n\n\t\t/* check for errors but retry for timeout */\n\t\tif (result != 0) {\n\n\t\t\tif (result == LIBUSB_ERROR_TIMEOUT) {\n\t\t\t\tLOG_DEBUG(\"Error RX timeout %d\", result);\n\t\t\t} else {\n\t\t\t\tLOG_DEBUG(\"Error RX Data %d\", result);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\th->read_count += transferred;\n\n\t\t/* we need to make sure we have a full packet, including checksum */\n\t\tif (h->read_count > 5) {\n\n\t\t\t/* check that we have received an packet delimiter\n\t\t\t * we do not validate the checksum\n\t\t\t * reply should contain $...#AA - so we check for # */\n\t\t\tif (h->read_buffer[h->read_count - 3] == '#')\n\t\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tif (retry++ == 3) {\n\t\t\tLOG_DEBUG(\"maximum data retries attempted\");\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nstatic int icdi_send_cmd(void *handle, const char *cmd)\n{\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tint cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START \"%s\", cmd);\n\treturn icdi_send_packet(handle, cmd_len);\n}\n\nstatic int icdi_send_remote_cmd(void *handle, const char *data)\n{\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tsize_t cmd_len = sprintf(h->write_buffer, PACKET_START \"qRcmd,\");\n\tcmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data,\n\t\tstrlen(data), h->max_packet - cmd_len);\n\n\treturn icdi_send_packet(handle, cmd_len);\n}\n\nstatic int icdi_get_cmd_result(void *handle)\n{\n\tstruct icdi_usb_handle_s *h = handle;\n\tint offset = 0;\n\tchar ch;\n\n\tassert(handle);\n\n\tdo {\n\t\tch = h->read_buffer[offset++];\n\t\tif (offset > h->read_count)\n\t\t\treturn ERROR_FAIL;\n\t} while (ch != '$');\n\n\tif (memcmp(\"OK\", h->read_buffer + offset, 2) == 0)\n\t\treturn ERROR_OK;\n\n\tif (h->read_buffer[offset] == 'E') {\n\t\t/* get error code */\n\t\tuint8_t result;\n\t\tif (unhexify(&result, h->read_buffer + offset + 1, 1) != 1)\n\t\t\treturn ERROR_FAIL;\n\t\treturn result;\n\t}\n\n\t/* for now we assume everything else is ok */\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_idcode(void *handle, uint32_t *idcode)\n{\n\t*idcode = 0;\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val)\n{\n\tuint8_t buf[4];\n\t/* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32().\n\t * I guess all supported chips are little-endian anyway. */\n\th_u32_to_le(buf, val);\n\treturn icdi_usb_write_mem(handle, addr, 4, 1, buf);\n}\n\nstatic enum target_state icdi_usb_state(void *handle)\n{\n\tint result;\n\tstruct icdi_usb_handle_s *h = handle;\n\tuint32_t dhcsr;\n\tuint8_t buf[4];\n\n\tresult = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf);\n\tif (result != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\n\t/* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32().\n\t * I guess all supported chips are little-endian anyway. */\n\tdhcsr = le_to_h_u32(buf);\n\tif (dhcsr & S_HALT)\n\t\treturn TARGET_HALTED;\n\n\treturn TARGET_RUNNING;\n}\n\nstatic int icdi_usb_version(void *handle)\n{\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tchar version[20];\n\n\t/* get info about icdi */\n\tint result = icdi_send_remote_cmd(handle, \"version\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (h->read_count < 8) {\n\t\tLOG_ERROR(\"Invalid Reply Received\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* convert reply */\n\tif (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) {\n\t\tLOG_WARNING(\"unable to get ICDI version\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* null terminate and print info */\n\tversion[4] = 0;\n\n\tLOG_INFO(\"ICDI Firmware version: %s\", version);\n\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_query(void *handle)\n{\n\tint result;\n\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tresult = icdi_send_cmd(handle, \"qSupported\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"query supported failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* from this we can get the max packet supported */\n\n\t/* query packet buffer size */\n\tchar *offset = strstr(h->read_buffer, \"PacketSize\");\n\tif (offset) {\n\t\tchar *separator;\n\t\tint max_packet;\n\n\t\tmax_packet = strtol(offset + 11, &separator, 16);\n\t\tif (!max_packet)\n\t\t\tLOG_ERROR(\"invalid max packet, using defaults\");\n\t\telse\n\t\t\th->max_packet = max_packet;\n\t\tLOG_DEBUG(\"max packet supported : %i bytes\", h->max_packet);\n\t}\n\n\n\t/* if required re allocate packet buffer */\n\tif (h->max_packet != ICDI_PACKET_SIZE) {\n\t\th->read_buffer = realloc(h->read_buffer, h->max_packet);\n\t\th->write_buffer = realloc(h->write_buffer, h->max_packet);\n\t\tif (!h->read_buffer || !h->write_buffer) {\n\t\t\tLOG_ERROR(\"unable to reallocate memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* set extended mode */\n\tresult = icdi_send_cmd(handle, \"!\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"unable to enable extended mode: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_reset(void *handle)\n{\n\t/* we do this in hla_target.c */\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_assert_srst(void *handle, int srst)\n{\n\t/* TODO not supported yet */\n\treturn ERROR_COMMAND_NOTFOUND;\n}\n\nstatic int icdi_usb_run(void *handle)\n{\n\tint result;\n\n\t/* resume target at current address */\n\tresult = icdi_send_cmd(handle, \"c\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"continue failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int icdi_usb_halt(void *handle)\n{\n\tint result;\n\n\t/* this query halts the target ?? */\n\tresult = icdi_send_cmd(handle, \"?\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"halt failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int icdi_usb_step(void *handle)\n{\n\tint result;\n\n\t/* step target at current address */\n\tresult = icdi_send_cmd(handle, \"s\");\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"step failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int icdi_usb_read_regs(void *handle)\n{\n\t/* currently unsupported */\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val)\n{\n\tint result;\n\tstruct icdi_usb_handle_s *h = handle;\n\tchar cmd[10];\n\n\tsnprintf(cmd, sizeof(cmd), \"p%x\", regsel);\n\tresult = icdi_send_cmd(handle, cmd);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"register read failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* convert result */\n\tuint8_t buf[4];\n\tif (unhexify(buf, h->read_buffer + 2, 4) != 4) {\n\t\tLOG_ERROR(\"failed to convert result\");\n\t\treturn ERROR_FAIL;\n\t}\n\t*val = le_to_h_u32(buf);\n\n\treturn result;\n}\n\nstatic int icdi_usb_write_reg(void *handle, unsigned int regsel, uint32_t val)\n{\n\tint result;\n\tchar cmd[20];\n\tuint8_t buf[4];\n\th_u32_to_le(buf, val);\n\n\tint cmd_len = snprintf(cmd, sizeof(cmd), \"P%x=\", regsel);\n\thexify(cmd + cmd_len, buf, 4, sizeof(cmd));\n\n\tresult = icdi_send_cmd(handle, cmd);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"register write failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer)\n{\n\tint result;\n\tstruct icdi_usb_handle_s *h = handle;\n\tchar cmd[20];\n\n\tsnprintf(cmd, sizeof(cmd), \"x%\" PRIx32 \",%\" PRIx32, addr, len);\n\tresult = icdi_send_cmd(handle, cmd);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"memory read failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* unescape input */\n\tint read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len);\n\tif (read_len != (int)len) {\n\t\tLOG_ERROR(\"read more bytes than expected: actual 0x%x expected 0x%\" PRIx32, read_len, len);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer)\n{\n\tint result;\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tsize_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START \"X%\" PRIx32 \",%\" PRIx32 \":\", addr, len);\n\n\tint out_len;\n\tcmd_len += remote_escape_output((const char *)buffer, len, h->write_buffer + cmd_len,\n\t\t\t&out_len, h->max_packet - cmd_len);\n\n\tif (out_len < (int)len) {\n\t\t/* for now issue a error as we have no way of allocating a larger buffer */\n\t\tLOG_ERROR(\"memory buffer too small: requires 0x%x actual 0x%\" PRIx32, out_len, len);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tresult = icdi_send_packet(handle, cmd_len);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\t/* check result */\n\tresult = icdi_get_cmd_result(handle);\n\tif (result != ERROR_OK) {\n\t\tLOG_ERROR(\"memory write failed: 0x%x\", result);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tstruct icdi_usb_handle_s *h = handle;\n\tuint32_t bytes_remaining;\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\twhile (count) {\n\n\t\tbytes_remaining = h->max_rw_packet;\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\tretval = icdi_usb_read_mem_int(handle, addr, bytes_remaining, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size,\n\t\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tstruct icdi_usb_handle_s *h = handle;\n\tuint32_t bytes_remaining;\n\n\t/* calculate byte count */\n\tcount *= size;\n\n\twhile (count) {\n\n\t\tbytes_remaining = h->max_rw_packet;\n\t\tif (count < bytes_remaining)\n\t\t\tbytes_remaining = count;\n\n\t\tretval = icdi_usb_write_mem_int(handle, addr, bytes_remaining, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += bytes_remaining;\n\t\taddr += bytes_remaining;\n\t\tcount -= bytes_remaining;\n\t}\n\n\treturn retval;\n}\n\nstatic int icdi_usb_override_target(const char *targetname)\n{\n\treturn !strcmp(targetname, \"cortex_m\");\n}\n\nstatic int icdi_usb_close(void *handle)\n{\n\tstruct icdi_usb_handle_s *h = handle;\n\n\tif (!h)\n\t\treturn ERROR_OK;\n\n\tif (h->usb_dev)\n\t\tjtag_libusb_close(h->usb_dev);\n\n\tfree(h->read_buffer);\n\tfree(h->write_buffer);\n\tfree(handle);\n\treturn ERROR_OK;\n}\n\nstatic int icdi_usb_open(struct hl_interface_param_s *param, void **fd)\n{\n\t/* TODO: Convert remaining libusb_ calls to jtag_libusb_ */\n\tint retval;\n\tstruct icdi_usb_handle_s *h;\n\n\tLOG_DEBUG(\"icdi_usb_open\");\n\n\th = calloc(1, sizeof(struct icdi_usb_handle_s));\n\n\tif (!h) {\n\t\tLOG_ERROR(\"unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i)\n\t\tLOG_DEBUG(\"transport: %d vid: 0x%04x pid: 0x%04x serial: %s\", param->transport,\n\t\t\tparam->vid[i], param->pid[i], adapter_get_required_serial() ? adapter_get_required_serial() : \"\");\n\n\t/* TI (Stellaris) ICDI provides its serial number in the USB descriptor;\n\t   no need to provide a callback here. */\n\tjtag_libusb_open(param->vid, param->pid, &h->usb_dev, NULL);\n\n\tif (!h->usb_dev) {\n\t\tLOG_ERROR(\"open failed\");\n\t\tgoto error_open;\n\t}\n\n\tif (libusb_claim_interface(h->usb_dev, 2)) {\n\t\tLOG_DEBUG(\"claim interface failed\");\n\t\tgoto error_open;\n\t}\n\n\t/* check if mode is supported */\n\tretval = ERROR_OK;\n\n\tswitch (param->transport) {\n#if 0\n\t\t/* TODO place holder as swd is not currently supported */\n\t\tcase HL_TRANSPORT_SWD:\n#endif\n\t\tcase HL_TRANSPORT_JTAG:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"mode (transport) not supported by device\");\n\t\tgoto error_open;\n\t}\n\n\t/* allocate buffer */\n\th->read_buffer = malloc(ICDI_PACKET_SIZE);\n\th->write_buffer = malloc(ICDI_PACKET_SIZE);\n\th->max_packet = ICDI_PACKET_SIZE;\n\n\tif (!h->read_buffer || !h->write_buffer) {\n\t\tLOG_DEBUG(\"malloc failed\");\n\t\tgoto error_open;\n\t}\n\n\t/* query icdi version etc */\n\tretval = icdi_usb_version(h);\n\tif (retval != ERROR_OK)\n\t\tgoto error_open;\n\n\t/* query icdi support */\n\tretval = icdi_usb_query(h);\n\tif (retval != ERROR_OK)\n\t\tgoto error_open;\n\n\t*fd = h;\n\n\t/* set the max target read/write buffer in bytes\n\t * as we are using gdb binary packets to transfer memory we have to\n\t * reserve half the buffer for any possible escape chars plus\n\t * at least 64 bytes for the gdb packet header */\n\th->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2;\n\n\treturn ERROR_OK;\n\nerror_open:\n\ticdi_usb_close(h);\n\n\treturn ERROR_FAIL;\n}\n\nstruct hl_layout_api_s icdi_usb_layout_api = {\n\t.open = icdi_usb_open,\n\t.close = icdi_usb_close,\n\t.idcode = icdi_usb_idcode,\n\t.state = icdi_usb_state,\n\t.reset = icdi_usb_reset,\n\t.assert_srst = icdi_usb_assert_srst,\n\t.run = icdi_usb_run,\n\t.halt = icdi_usb_halt,\n\t.step = icdi_usb_step,\n\t.read_regs = icdi_usb_read_regs,\n\t.read_reg = icdi_usb_read_reg,\n\t.write_reg = icdi_usb_write_reg,\n\t.read_mem = icdi_usb_read_mem,\n\t.write_mem = icdi_usb_write_mem,\n\t.write_debug_reg = icdi_usb_write_debug_reg,\n\t.override_target = icdi_usb_override_target,\n\t.custom_command = icdi_send_remote_cmd,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/ulink.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011-2013 by Martin Schmoelzer                          *\n *   <martin.schmoelzer@student.tuwien.ac.at>                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <math.h>\n#include \"helper/system.h\"\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <target/image.h>\n#include <libusb.h>\n#include \"libusb_helper.h\"\n#include \"OpenULINK/include/msgtypes.h\"\n\n/** USB Vendor ID of ULINK device in unconfigured state (no firmware loaded\n *  yet) or with OpenULINK firmware. */\n#define ULINK_VID                0xC251\n\n/** USB Product ID of ULINK device in unconfigured state (no firmware loaded\n *  yet) or with OpenULINK firmware. */\n#define ULINK_PID                0x2710\n\n/** Address of EZ-USB CPU Control & Status register. This register can be\n *  written by issuing a Control EP0 vendor request. */\n#define CPUCS_REG                0x7F92\n\n/** USB Control EP0 bRequest: \"Firmware Load\". */\n#define REQUEST_FIRMWARE_LOAD    0xA0\n\n/** Value to write into CPUCS to put EZ-USB into reset. */\n#define CPU_RESET                0x01\n\n/** Value to write into CPUCS to put EZ-USB out of reset. */\n#define CPU_START                0x00\n\n/** Base address of firmware in EZ-USB code space. */\n#define FIRMWARE_ADDR            0x0000\n\n/** USB interface number */\n#define USB_INTERFACE            0\n\n/** Delay (in microseconds) to wait while EZ-USB performs ReNumeration. */\n#define ULINK_RENUMERATION_DELAY 1500000\n\n/** Default location of OpenULINK firmware image. */\n#define ULINK_FIRMWARE_FILE      PKGDATADIR \"/OpenULINK/ulink_firmware.hex\"\n\n/** Maximum size of a single firmware section. Entire EZ-USB code space = 8kB */\n#define SECTION_BUFFERSIZE       8192\n\n/** Tuning of OpenOCD SCAN commands split into multiple OpenULINK commands. */\n#define SPLIT_SCAN_THRESHOLD     10\n\n/** ULINK hardware type */\nenum ulink_type {\n\t/** Original ULINK adapter, based on Cypress EZ-USB (AN2131):\n\t *  Full JTAG support, no SWD support. */\n\tULINK_1,\n\n\t/** Newer ULINK adapter, based on NXP LPC2148. Currently unsupported. */\n\tULINK_2,\n\n\t/** Newer ULINK adapter, based on EZ-USB FX2 + FPGA. Currently unsupported. */\n\tULINK_PRO,\n\n\t/** Newer ULINK adapter, possibly based on ULINK 2. Currently unsupported. */\n\tULINK_ME\n};\n\nenum ulink_payload_direction {\n\tPAYLOAD_DIRECTION_OUT,\n\tPAYLOAD_DIRECTION_IN\n};\n\nenum ulink_delay_type {\n\tDELAY_CLOCK_TCK,\n\tDELAY_CLOCK_TMS,\n\tDELAY_SCAN_IN,\n\tDELAY_SCAN_OUT,\n\tDELAY_SCAN_IO\n};\n\n/**\n * OpenULINK command (OpenULINK command queue element).\n *\n * For the OUT direction payload, things are quite easy: Payload is stored\n * in a rather small array (up to 63 bytes), the payload is always allocated\n * by the function generating the command and freed by ulink_clear_queue().\n *\n * For the IN direction payload, things get a little bit more complicated:\n * The maximum IN payload size for a single command is 64 bytes. Assume that\n * a single OpenOCD command needs to scan 256 bytes. This results in the\n * generation of four OpenULINK commands. The function generating these\n * commands shall allocate an uint8_t[256] array. Each command's #payload_in\n * pointer shall point to the corresponding offset where IN data shall be\n * placed, while #payload_in_start shall point to the first element of the 256\n * byte array.\n * - first command:  #payload_in_start + 0\n * - second command: #payload_in_start + 64\n * - third command:  #payload_in_start + 128\n * - fourth command: #payload_in_start + 192\n *\n * The last command sets #needs_postprocessing to true.\n */\nstruct ulink_cmd {\n\tuint8_t id;\t\t\t/**< ULINK command ID */\n\n\tuint8_t *payload_out;\t\t/**< OUT direction payload data */\n\tuint8_t payload_out_size;\t/**< OUT direction payload size for this command */\n\n\tuint8_t *payload_in_start;\t/**< Pointer to first element of IN payload array */\n\tuint8_t *payload_in;\t\t/**< Pointer where IN payload shall be stored */\n\tuint8_t payload_in_size;\t/**< IN direction payload size for this command */\n\n\t/** Indicates if this command needs post-processing */\n\tbool needs_postprocessing;\n\n\t/** Indicates if ulink_clear_queue() should free payload_in_start  */\n\tbool free_payload_in_start;\n\n\t/** Pointer to corresponding OpenOCD command for post-processing */\n\tstruct jtag_command *cmd_origin;\n\n\tstruct ulink_cmd *next;\t\t/**< Pointer to next command (linked list) */\n};\n\n/** Describes one driver instance */\nstruct ulink {\n\tstruct libusb_context *libusb_ctx;\n\tstruct libusb_device_handle *usb_device_handle;\n\tenum ulink_type type;\n\n\tunsigned int ep_in;\t\t/**< IN endpoint number */\n\tunsigned int ep_out;\t\t/**< OUT endpoint number */\n\n\tint delay_scan_in;\t/**< Delay value for SCAN_IN commands */\n\tint delay_scan_out;\t/**< Delay value for SCAN_OUT commands */\n\tint delay_scan_io;\t/**< Delay value for SCAN_IO commands */\n\tint delay_clock_tck;\t/**< Delay value for CLOCK_TMS commands */\n\tint delay_clock_tms;\t/**< Delay value for CLOCK_TCK commands */\n\n\tint commands_in_queue;\t\t/**< Number of commands in queue */\n\tstruct ulink_cmd *queue_start;\t/**< Pointer to first command in queue */\n\tstruct ulink_cmd *queue_end;\t/**< Pointer to last command in queue */\n};\n\n/**************************** Function Prototypes *****************************/\n\n/* USB helper functions */\nstatic int ulink_usb_open(struct ulink **device);\nstatic int ulink_usb_close(struct ulink **device);\n\n/* ULINK MCU (Cypress EZ-USB) specific functions */\nstatic int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit);\nstatic int ulink_load_firmware_and_renumerate(struct ulink **device, const char *filename,\n\t\tuint32_t delay);\nstatic int ulink_load_firmware(struct ulink *device, const char *filename);\nstatic int ulink_write_firmware_section(struct ulink *device,\n\t\tstruct image *firmware_image, int section_index);\n\n/* Generic helper functions */\nstatic void ulink_print_signal_states(uint8_t input_signals, uint8_t output_signals);\n\n/* OpenULINK command generation helper functions */\nstatic int ulink_allocate_payload(struct ulink_cmd *ulink_cmd, int size,\n\t\tenum ulink_payload_direction direction);\n\n/* OpenULINK command queue helper functions */\nstatic int ulink_get_queue_size(struct ulink *device,\n\t\tenum ulink_payload_direction direction);\nstatic void ulink_clear_queue(struct ulink *device);\nstatic int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd);\nstatic int ulink_execute_queued_commands(struct ulink *device, int timeout);\n\nstatic void ulink_print_queue(struct ulink *device);\n\nstatic int ulink_append_scan_cmd(struct ulink *device,\n\t\tenum scan_type scan_type,\n\t\tint scan_size_bits,\n\t\tuint8_t *tdi,\n\t\tuint8_t *tdo_start,\n\t\tuint8_t *tdo,\n\t\tuint8_t tms_count_start,\n\t\tuint8_t tms_sequence_start,\n\t\tuint8_t tms_count_end,\n\t\tuint8_t tms_sequence_end,\n\t\tstruct jtag_command *origin,\n\t\tbool postprocess);\nstatic int ulink_append_clock_tms_cmd(struct ulink *device, uint8_t count,\n\t\tuint8_t sequence);\nstatic int ulink_append_clock_tck_cmd(struct ulink *device, uint16_t count);\nstatic int ulink_append_get_signals_cmd(struct ulink *device);\nstatic int ulink_append_set_signals_cmd(struct ulink *device, uint8_t low,\n\t\tuint8_t high);\nstatic int ulink_append_sleep_cmd(struct ulink *device, uint32_t us);\nstatic int ulink_append_configure_tck_cmd(struct ulink *device,\n\t\tint delay_scan_in,\n\t\tint delay_scan_out,\n\t\tint delay_scan_io,\n\t\tint delay_tck,\n\t\tint delay_tms);\nstatic int __attribute__((unused)) ulink_append_led_cmd(struct ulink *device, uint8_t led_state);\nstatic int ulink_append_test_cmd(struct ulink *device);\n\n/* OpenULINK TCK frequency helper functions */\nstatic int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay);\n\n/* Interface between OpenULINK and OpenOCD */\nstatic void ulink_set_end_state(tap_state_t endstate);\nstatic int ulink_queue_statemove(struct ulink *device);\n\nstatic int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_tlr_reset(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_runtest(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd);\nstatic int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd);\n\nstatic int ulink_post_process_scan(struct ulink_cmd *ulink_cmd);\nstatic int ulink_post_process_queue(struct ulink *device);\n\n/* adapter driver functions */\nstatic int ulink_execute_queue(void);\nstatic int ulink_khz(int khz, int *jtag_speed);\nstatic int ulink_speed(int speed);\nstatic int ulink_speed_div(int speed, int *khz);\nstatic int ulink_init(void);\nstatic int ulink_quit(void);\n\n/****************************** Global Variables ******************************/\n\nstatic struct ulink *ulink_handle;\n\n/**************************** USB helper functions ****************************/\n\n/**\n * Opens the ULINK device\n *\n * Currently, only the original ULINK is supported\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_usb_open(struct ulink **device)\n{\n\tssize_t num_devices, i;\n\tbool found;\n\tstruct libusb_device **usb_devices;\n\tstruct libusb_device_descriptor usb_desc;\n\tstruct libusb_device_handle *usb_device_handle;\n\n\tnum_devices = libusb_get_device_list((*device)->libusb_ctx, &usb_devices);\n\n\tif (num_devices <= 0)\n\t\treturn ERROR_FAIL;\n\n\tfound = false;\n\tfor (i = 0; i < num_devices; i++) {\n\t\tif (libusb_get_device_descriptor(usb_devices[i], &usb_desc) != 0)\n\t\t\tcontinue;\n\t\telse if (usb_desc.idVendor == ULINK_VID && usb_desc.idProduct == ULINK_PID) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!found)\n\t\treturn ERROR_FAIL;\n\n\tif (libusb_open(usb_devices[i], &usb_device_handle) != 0)\n\t\treturn ERROR_FAIL;\n\tlibusb_free_device_list(usb_devices, 1);\n\n\t(*device)->usb_device_handle = usb_device_handle;\n\t(*device)->type = ULINK_1;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Releases the ULINK interface and closes the USB device handle.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_usb_close(struct ulink **device)\n{\n\tif (libusb_release_interface((*device)->usb_device_handle, 0) != 0)\n\t\treturn ERROR_FAIL;\n\n\tlibusb_close((*device)->usb_device_handle);\n\n\t(*device)->usb_device_handle = NULL;\n\n\treturn ERROR_OK;\n}\n\n/******************* ULINK CPU (EZ-USB) specific functions ********************/\n\n/**\n * Writes '0' or '1' to the CPUCS register, putting the EZ-USB CPU into reset\n * or out of reset.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param reset_bit 0 to put CPU into reset, 1 to put CPU out of reset.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_cpu_reset(struct ulink *device, unsigned char reset_bit)\n{\n\tint ret;\n\n\tret = libusb_control_transfer(device->usb_device_handle,\n\t\t\t(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),\n\t\t\tREQUEST_FIRMWARE_LOAD, CPUCS_REG, 0, &reset_bit, 1, LIBUSB_TIMEOUT_MS);\n\n\t/* usb_control_msg() returns the number of bytes transferred during the\n\t * DATA stage of the control transfer - must be exactly 1 in this case! */\n\tif (ret != 1)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\n/**\n * Puts the ULINK's EZ-USB microcontroller into reset state, downloads\n * the firmware image, resumes the microcontroller and re-enumerates\n * USB devices.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n *  The usb_handle member will be modified during re-enumeration.\n * @param filename path to the Intel HEX file containing the firmware image.\n * @param delay the delay to wait for the device to re-enumerate.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_load_firmware_and_renumerate(struct ulink **device,\n\tconst char *filename, uint32_t delay)\n{\n\tint ret;\n\n\t/* Basic process: After downloading the firmware, the ULINK will disconnect\n\t * itself and re-connect after a short amount of time so we have to close\n\t * the handle and re-enumerate USB devices */\n\n\tret = ulink_load_firmware(*device, filename);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ulink_usb_close(device);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tusleep(delay);\n\n\tret = ulink_usb_open(device);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Downloads a firmware image to the ULINK's EZ-USB microcontroller\n * over the USB bus.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param filename an absolute or relative path to the Intel HEX file\n *  containing the firmware image.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_load_firmware(struct ulink *device, const char *filename)\n{\n\tstruct image ulink_firmware_image;\n\tint ret;\n\n\tret = ulink_cpu_reset(device, CPU_RESET);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not halt ULINK CPU\");\n\t\treturn ret;\n\t}\n\n\tulink_firmware_image.base_address = 0;\n\tulink_firmware_image.base_address_set = false;\n\n\tret = image_open(&ulink_firmware_image, filename, \"ihex\");\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not load firmware image\");\n\t\treturn ret;\n\t}\n\n\t/* Download all sections in the image to ULINK */\n\tfor (unsigned int i = 0; i < ulink_firmware_image.num_sections; i++) {\n\t\tret = ulink_write_firmware_section(device, &ulink_firmware_image, i);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\timage_close(&ulink_firmware_image);\n\n\tret = ulink_cpu_reset(device, CPU_START);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not restart ULINK CPU\");\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Send one contiguous firmware section to the ULINK's EZ-USB microcontroller\n * over the USB bus.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param firmware_image pointer to the firmware image that contains the section\n *  which should be sent to the ULINK's EZ-USB microcontroller.\n * @param section_index index of the section within the firmware image.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_write_firmware_section(struct ulink *device,\n\tstruct image *firmware_image, int section_index)\n{\n\tuint16_t addr, size, bytes_remaining, chunk_size;\n\tuint8_t data[SECTION_BUFFERSIZE];\n\tuint8_t *data_ptr = data;\n\tsize_t size_read;\n\tint ret;\n\n\tsize = (uint16_t)firmware_image->sections[section_index].size;\n\taddr = (uint16_t)firmware_image->sections[section_index].base_address;\n\n\tLOG_DEBUG(\"section %02i at addr 0x%04x (size 0x%04x)\", section_index, addr,\n\t\tsize);\n\n\t/* Copy section contents to local buffer */\n\tret = image_read_section(firmware_image, section_index, 0, size, data,\n\t\t\t&size_read);\n\n\tif ((ret != ERROR_OK) || (size_read != size)) {\n\t\t/* Propagating the return code would return '0' (misleadingly indicating\n\t\t * successful execution of the function) if only the size check fails. */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbytes_remaining = size;\n\n\t/* Send section data in chunks of up to 64 bytes to ULINK */\n\twhile (bytes_remaining > 0) {\n\t\tif (bytes_remaining > 64)\n\t\t\tchunk_size = 64;\n\t\telse\n\t\t\tchunk_size = bytes_remaining;\n\n\t\tret = libusb_control_transfer(device->usb_device_handle,\n\t\t\t\t(LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE),\n\t\t\t\tREQUEST_FIRMWARE_LOAD, addr, FIRMWARE_ADDR, (unsigned char *)data_ptr,\n\t\t\t\tchunk_size, LIBUSB_TIMEOUT_MS);\n\n\t\tif (ret != (int)chunk_size) {\n\t\t\t/* Abort if libusb sent less data than requested */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbytes_remaining -= chunk_size;\n\t\taddr += chunk_size;\n\t\tdata_ptr += chunk_size;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/************************** Generic helper functions **************************/\n\n/**\n * Print state of interesting signals via LOG_INFO().\n *\n * @param input_signals input signal states as returned by CMD_GET_SIGNALS\n * @param output_signals output signal states as returned by CMD_GET_SIGNALS\n */\nstatic void ulink_print_signal_states(uint8_t input_signals, uint8_t output_signals)\n{\n\tLOG_INFO(\"ULINK signal states: TDI: %i, TDO: %i, TMS: %i, TCK: %i, TRST: %i,\"\n\t\t\" SRST: %i\",\n\t\t(output_signals & SIGNAL_TDI   ? 1 : 0),\n\t\t(input_signals  & SIGNAL_TDO   ? 1 : 0),\n\t\t(output_signals & SIGNAL_TMS   ? 1 : 0),\n\t\t(output_signals & SIGNAL_TCK   ? 1 : 0),\n\t\t(output_signals & SIGNAL_TRST  ? 0 : 1),\t/* Inverted by hardware */\n\t\t(output_signals & SIGNAL_RESET ? 0 : 1));\t/* Inverted by hardware */\n}\n\n/**************** OpenULINK command generation helper functions ***************/\n\n/**\n * Allocate and initialize space in memory for OpenULINK command payload.\n *\n * @param ulink_cmd pointer to command whose payload should be allocated.\n * @param size the amount of memory to allocate (bytes).\n * @param direction which payload to allocate.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_allocate_payload(struct ulink_cmd *ulink_cmd, int size,\n\tenum ulink_payload_direction direction)\n{\n\tuint8_t *payload;\n\n\tpayload = calloc(size, sizeof(uint8_t));\n\n\tif (!payload) {\n\t\tLOG_ERROR(\"Could not allocate OpenULINK command payload: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (direction) {\n\t    case PAYLOAD_DIRECTION_OUT:\n\t\t    if (ulink_cmd->payload_out) {\n\t\t\t    LOG_ERROR(\"BUG: Duplicate payload allocation for OpenULINK command\");\n\t\t\t    free(payload);\n\t\t\t    return ERROR_FAIL;\n\t\t    } else {\n\t\t\t    ulink_cmd->payload_out = payload;\n\t\t\t    ulink_cmd->payload_out_size = size;\n\t\t    }\n\t\t    break;\n\t    case PAYLOAD_DIRECTION_IN:\n\t\t    if (ulink_cmd->payload_in_start) {\n\t\t\t    LOG_ERROR(\"BUG: Duplicate payload allocation for OpenULINK command\");\n\t\t\t    free(payload);\n\t\t\t    return ERROR_FAIL;\n\t\t    } else {\n\t\t\t    ulink_cmd->payload_in_start = payload;\n\t\t\t    ulink_cmd->payload_in = payload;\n\t\t\t    ulink_cmd->payload_in_size = size;\n\n\t\t\t\t/* By default, free payload_in_start in ulink_clear_queue(). Commands\n\t\t\t\t * that do not want this behavior (e. g. split scans) must turn it off\n\t\t\t\t * separately! */\n\t\t\t    ulink_cmd->free_payload_in_start = true;\n\t\t    }\n\t\t    break;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/****************** OpenULINK command queue helper functions ******************/\n\n/**\n * Get the current number of bytes in the queue, including command IDs.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param direction the transfer direction for which to get byte count.\n * @return the number of bytes currently stored in the queue for the specified\n *  direction.\n */\nstatic int ulink_get_queue_size(struct ulink *device,\n\tenum ulink_payload_direction direction)\n{\n\tstruct ulink_cmd *current = device->queue_start;\n\tint sum = 0;\n\n\twhile (current) {\n\t\tswitch (direction) {\n\t\t    case PAYLOAD_DIRECTION_OUT:\n\t\t\t    sum += current->payload_out_size + 1;\t/* + 1 byte for Command ID */\n\t\t\t    break;\n\t\t    case PAYLOAD_DIRECTION_IN:\n\t\t\t    sum += current->payload_in_size;\n\t\t\t    break;\n\t\t}\n\n\t\tcurrent = current->next;\n\t}\n\n\treturn sum;\n}\n\n/**\n * Clear the OpenULINK command queue.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n */\nstatic void ulink_clear_queue(struct ulink *device)\n{\n\tstruct ulink_cmd *current = device->queue_start;\n\tstruct ulink_cmd *next = NULL;\n\n\twhile (current) {\n\t\t/* Save pointer to next element */\n\t\tnext = current->next;\n\n\t\t/* Free payloads: OUT payload can be freed immediately */\n\t\tfree(current->payload_out);\n\t\tcurrent->payload_out = NULL;\n\n\t\t/* IN payload MUST be freed ONLY if no other commands use the\n\t\t * payload_in_start buffer */\n\t\tif (current->free_payload_in_start == true) {\n\t\t\tfree(current->payload_in_start);\n\t\t\tcurrent->payload_in_start = NULL;\n\t\t\tcurrent->payload_in = NULL;\n\t\t}\n\n\t\t/* Free queue element */\n\t\tfree(current);\n\n\t\t/* Proceed with next element */\n\t\tcurrent = next;\n\t}\n\n\tdevice->commands_in_queue = 0;\n\tdevice->queue_start = NULL;\n\tdevice->queue_end = NULL;\n}\n\n/**\n * Add a command to the OpenULINK command queue.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param ulink_cmd pointer to command that shall be appended to the OpenULINK\n *  command queue.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_queue(struct ulink *device, struct ulink_cmd *ulink_cmd)\n{\n\tint newsize_out, newsize_in;\n\tint ret = ERROR_OK;\n\n\tnewsize_out = ulink_get_queue_size(device, PAYLOAD_DIRECTION_OUT) + 1\n\t\t+ ulink_cmd->payload_out_size;\n\n\tnewsize_in = ulink_get_queue_size(device, PAYLOAD_DIRECTION_IN)\n\t\t+ ulink_cmd->payload_in_size;\n\n\t/* Check if the current command can be appended to the queue */\n\tif ((newsize_out > 64) || (newsize_in > 64)) {\n\t\t/* New command does not fit. Execute all commands in queue before starting\n\t\t * new queue with the current command as first entry. */\n\t\tret = ulink_execute_queued_commands(device, LIBUSB_TIMEOUT_MS);\n\n\t\tif (ret == ERROR_OK)\n\t\t\tret = ulink_post_process_queue(device);\n\n\t\tif (ret == ERROR_OK)\n\t\t\tulink_clear_queue(device);\n\t}\n\n\tif (!device->queue_start) {\n\t\t/* Queue was empty */\n\t\tdevice->commands_in_queue = 1;\n\n\t\tdevice->queue_start = ulink_cmd;\n\t\tdevice->queue_end = ulink_cmd;\n\t} else {\n\t\t/* There are already commands in the queue */\n\t\tdevice->commands_in_queue++;\n\n\t\tdevice->queue_end->next = ulink_cmd;\n\t\tdevice->queue_end = ulink_cmd;\n\t}\n\n\tif (ret != ERROR_OK)\n\t\tulink_clear_queue(device);\n\n\treturn ret;\n}\n\n/**\n * Sends all queued OpenULINK commands to the ULINK for execution.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param timeout\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_execute_queued_commands(struct ulink *device, int timeout)\n{\n\tstruct ulink_cmd *current;\n\tint ret, i, index_out, index_in, count_out, count_in, transferred;\n\tuint8_t buffer[64];\n\n\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))\n\t\tulink_print_queue(device);\n\n\tindex_out = 0;\n\tcount_out = 0;\n\tcount_in = 0;\n\n\tfor (current = device->queue_start; current; current = current->next) {\n\t\t/* Add command to packet */\n\t\tbuffer[index_out] = current->id;\n\t\tindex_out++;\n\t\tcount_out++;\n\n\t\tfor (i = 0; i < current->payload_out_size; i++)\n\t\t\tbuffer[index_out + i] = current->payload_out[i];\n\t\tindex_out += current->payload_out_size;\n\t\tcount_in += current->payload_in_size;\n\t\tcount_out += current->payload_out_size;\n\t}\n\n\t/* Send packet to ULINK */\n\tret = libusb_bulk_transfer(device->usb_device_handle, device->ep_out,\n\t\t\t(unsigned char *)buffer, count_out, &transferred, timeout);\n\tif (ret != 0)\n\t\treturn ERROR_FAIL;\n\tif (transferred != count_out)\n\t\treturn ERROR_FAIL;\n\n\t/* Wait for response if commands contain IN payload data */\n\tif (count_in > 0) {\n\t\tret = libusb_bulk_transfer(device->usb_device_handle, device->ep_in,\n\t\t\t\t(unsigned char *)buffer, 64, &transferred, timeout);\n\t\tif (ret != 0)\n\t\t\treturn ERROR_FAIL;\n\t\tif (transferred != count_in)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Write back IN payload data */\n\t\tindex_in = 0;\n\t\tfor (current = device->queue_start; current; current = current->next) {\n\t\t\tfor (i = 0; i < current->payload_in_size; i++) {\n\t\t\t\tcurrent->payload_in[i] = buffer[index_in];\n\t\t\t\tindex_in++;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Convert an OpenULINK command ID (\\a id) to a human-readable string.\n *\n * @param id the OpenULINK command ID.\n * @return the corresponding human-readable string.\n */\nstatic const char *ulink_cmd_id_string(uint8_t id)\n{\n\tswitch (id) {\n\tcase CMD_SCAN_IN:\n\t\treturn \"CMD_SCAN_IN\";\n\tcase CMD_SLOW_SCAN_IN:\n\t\treturn \"CMD_SLOW_SCAN_IN\";\n\tcase CMD_SCAN_OUT:\n\t\treturn \"CMD_SCAN_OUT\";\n\tcase CMD_SLOW_SCAN_OUT:\n\t\treturn \"CMD_SLOW_SCAN_OUT\";\n\tcase CMD_SCAN_IO:\n\t\treturn \"CMD_SCAN_IO\";\n\tcase CMD_SLOW_SCAN_IO:\n\t\treturn \"CMD_SLOW_SCAN_IO\";\n\tcase CMD_CLOCK_TMS:\n\t\treturn \"CMD_CLOCK_TMS\";\n\tcase CMD_SLOW_CLOCK_TMS:\n\t\treturn \"CMD_SLOW_CLOCK_TMS\";\n\tcase CMD_CLOCK_TCK:\n\t\treturn \"CMD_CLOCK_TCK\";\n\tcase CMD_SLOW_CLOCK_TCK:\n\t\treturn \"CMD_SLOW_CLOCK_TCK\";\n\tcase CMD_SLEEP_US:\n\t\treturn \"CMD_SLEEP_US\";\n\tcase CMD_SLEEP_MS:\n\t\treturn \"CMD_SLEEP_MS\";\n\tcase CMD_GET_SIGNALS:\n\t\treturn \"CMD_GET_SIGNALS\";\n\tcase CMD_SET_SIGNALS:\n\t\treturn \"CMD_SET_SIGNALS\";\n\tcase CMD_CONFIGURE_TCK_FREQ:\n\t\treturn \"CMD_CONFIGURE_TCK_FREQ\";\n\tcase CMD_SET_LEDS:\n\t\treturn \"CMD_SET_LEDS\";\n\tcase CMD_TEST:\n\t\treturn \"CMD_TEST\";\n\tdefault:\n\t\treturn \"CMD_UNKNOWN\";\n\t}\n}\n\n/**\n * Print one OpenULINK command to stdout.\n *\n * @param ulink_cmd pointer to OpenULINK command.\n */\nstatic void ulink_print_command(struct ulink_cmd *ulink_cmd)\n{\n\tint i;\n\n\tprintf(\"  %-22s | OUT size = %i, bytes = 0x\",\n\t\tulink_cmd_id_string(ulink_cmd->id), ulink_cmd->payload_out_size);\n\n\tfor (i = 0; i < ulink_cmd->payload_out_size; i++)\n\t\tprintf(\"%02X \", ulink_cmd->payload_out[i]);\n\tprintf(\"\\n                         | IN size  = %i\\n\",\n\t\tulink_cmd->payload_in_size);\n}\n\n/**\n * Print the OpenULINK command queue to stdout.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n */\nstatic void ulink_print_queue(struct ulink *device)\n{\n\tstruct ulink_cmd *current;\n\n\tprintf(\"OpenULINK command queue:\\n\");\n\n\tfor (current = device->queue_start; current; current = current->next)\n\t\tulink_print_command(current);\n}\n\n/**\n * Perform JTAG scan\n *\n * Creates and appends a JTAG scan command to the OpenULINK command queue.\n * A JTAG scan consists of three steps:\n * - Move to the desired SHIFT state, depending on scan type (IR/DR scan).\n * - Shift TDI data into the JTAG chain, optionally reading the TDO pin.\n * - Move to the desired end state.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param scan_type the type of the scan (IN, OUT, IO (bidirectional)).\n * @param scan_size_bits number of bits to shift into the JTAG chain.\n * @param tdi pointer to array containing TDI data.\n * @param tdo_start pointer to first element of array where TDO data shall be\n *  stored. See #ulink_cmd for details.\n * @param tdo pointer to array where TDO data shall be stored\n * @param tms_count_start number of TMS state transitions to perform BEFORE\n *  shifting data into the JTAG chain.\n * @param tms_sequence_start sequence of TMS state transitions that will be\n *  performed BEFORE shifting data into the JTAG chain.\n * @param tms_count_end number of TMS state transitions to perform AFTER\n *  shifting data into the JTAG chain.\n * @param tms_sequence_end sequence of TMS state transitions that will be\n *  performed AFTER shifting data into the JTAG chain.\n * @param origin pointer to OpenOCD command that generated this scan command.\n * @param postprocess whether this command needs to be post-processed after\n *  execution.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_scan_cmd(struct ulink *device, enum scan_type scan_type,\n\tint scan_size_bits, uint8_t *tdi, uint8_t *tdo_start, uint8_t *tdo,\n\tuint8_t tms_count_start, uint8_t tms_sequence_start, uint8_t tms_count_end,\n\tuint8_t tms_sequence_end, struct jtag_command *origin, bool postprocess)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret, i, scan_size_bytes;\n\tuint8_t bits_last_byte;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\t/* Check size of command. USB buffer can hold 64 bytes, 1 byte is command ID,\n\t * 5 bytes are setup data -> 58 remaining payload bytes for TDI data */\n\tif (scan_size_bits > (58 * 8)) {\n\t\tLOG_ERROR(\"BUG: Tried to create CMD_SCAN_IO OpenULINK command with too\"\n\t\t\t\" large payload\");\n\t\tfree(cmd);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tscan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8);\n\n\tbits_last_byte = scan_size_bits % 8;\n\tif (bits_last_byte == 0)\n\t\tbits_last_byte = 8;\n\n\t/* Allocate out_payload depending on scan type */\n\tswitch (scan_type) {\n\t    case SCAN_IN:\n\t\t    if (device->delay_scan_in < 0)\n\t\t\t    cmd->id = CMD_SCAN_IN;\n\t\t    else\n\t\t\t    cmd->id = CMD_SLOW_SCAN_IN;\n\t\t    ret = ulink_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_OUT);\n\t\t    break;\n\t    case SCAN_OUT:\n\t\t    if (device->delay_scan_out < 0)\n\t\t\t    cmd->id = CMD_SCAN_OUT;\n\t\t    else\n\t\t\t    cmd->id = CMD_SLOW_SCAN_OUT;\n\t\t    ret = ulink_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT);\n\t\t    break;\n\t    case SCAN_IO:\n\t\t    if (device->delay_scan_io < 0)\n\t\t\t    cmd->id = CMD_SCAN_IO;\n\t\t    else\n\t\t\t    cmd->id = CMD_SLOW_SCAN_IO;\n\t\t    ret = ulink_allocate_payload(cmd, scan_size_bytes + 5, PAYLOAD_DIRECTION_OUT);\n\t\t    break;\n\t    default:\n\t\t    LOG_ERROR(\"BUG: ulink_append_scan_cmd() encountered an unknown scan type\");\n\t\t    ret = ERROR_FAIL;\n\t\t    break;\n\t}\n\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\t/* Build payload_out that is common to all scan types */\n\tcmd->payload_out[0] = scan_size_bytes & 0xFF;\n\tcmd->payload_out[1] = bits_last_byte & 0xFF;\n\tcmd->payload_out[2] = ((tms_count_start & 0x0F) << 4) | (tms_count_end & 0x0F);\n\tcmd->payload_out[3] = tms_sequence_start;\n\tcmd->payload_out[4] = tms_sequence_end;\n\n\t/* Setup payload_out for types with OUT transfer */\n\tif ((scan_type == SCAN_OUT) || (scan_type == SCAN_IO)) {\n\t\tfor (i = 0; i < scan_size_bytes; i++)\n\t\t\tcmd->payload_out[i + 5] = tdi[i];\n\t}\n\n\t/* Setup payload_in pointers for types with IN transfer */\n\tif ((scan_type == SCAN_IN) || (scan_type == SCAN_IO)) {\n\t\tcmd->payload_in_start = tdo_start;\n\t\tcmd->payload_in = tdo;\n\t\tcmd->payload_in_size = scan_size_bytes;\n\t}\n\n\tcmd->needs_postprocessing = postprocess;\n\tcmd->cmd_origin = origin;\n\n\t/* For scan commands, we free payload_in_start only when the command is\n\t * the last in a series of split commands or a stand-alone command */\n\tcmd->free_payload_in_start = postprocess;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Perform TAP state transitions\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param count defines the number of TCK clock cycles generated (up to 8).\n * @param sequence defines the TMS pin levels for each state transition. The\n *  Least-Significant Bit is read first.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_clock_tms_cmd(struct ulink *device, uint8_t count,\n\tuint8_t sequence)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tif (device->delay_clock_tms < 0)\n\t\tcmd->id = CMD_CLOCK_TMS;\n\telse\n\t\tcmd->id = CMD_SLOW_CLOCK_TMS;\n\n\t/* CMD_CLOCK_TMS has two OUT payload bytes and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = count;\n\tcmd->payload_out[1] = sequence;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Generate a defined amount of TCK clock cycles\n *\n * All other JTAG signals are left unchanged.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param count the number of TCK clock cycles to generate.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_clock_tck_cmd(struct ulink *device, uint16_t count)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tif (device->delay_clock_tck < 0)\n\t\tcmd->id = CMD_CLOCK_TCK;\n\telse\n\t\tcmd->id = CMD_SLOW_CLOCK_TCK;\n\n\t/* CMD_CLOCK_TCK has two OUT payload bytes and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = count & 0xff;\n\tcmd->payload_out[1] = (count >> 8) & 0xff;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Read JTAG signals.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_get_signals_cmd(struct ulink *device)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_GET_SIGNALS;\n\tcmd->needs_postprocessing = true;\n\n\t/* CMD_GET_SIGNALS has two IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_IN);\n\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Arbitrarily set JTAG output signals.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param low defines which signals will be de-asserted. Each bit corresponds\n *  to a JTAG signal:\n *  - SIGNAL_TDI\n *  - SIGNAL_TMS\n *  - SIGNAL_TCK\n *  - SIGNAL_TRST\n *  - SIGNAL_BRKIN\n *  - SIGNAL_RESET\n *  - SIGNAL_OCDSE\n * @param high defines which signals will be asserted.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_set_signals_cmd(struct ulink *device, uint8_t low,\n\tuint8_t high)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_SET_SIGNALS;\n\n\t/* CMD_SET_SIGNALS has two OUT payload bytes and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);\n\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = low;\n\tcmd->payload_out[1] = high;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Sleep for a pre-defined number of microseconds\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param us the number microseconds to sleep.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_sleep_cmd(struct ulink *device, uint32_t us)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_SLEEP_US;\n\n\t/* CMD_SLEEP_US has two OUT payload bytes and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 2, PAYLOAD_DIRECTION_OUT);\n\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = us & 0x00ff;\n\tcmd->payload_out[1] = (us >> 8) & 0x00ff;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Set TCK delay counters\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param delay_scan_in delay count top value in jtag_slow_scan_in() function.\n * @param delay_scan_out delay count top value in jtag_slow_scan_out() function.\n * @param delay_scan_io delay count top value in jtag_slow_scan_io() function.\n * @param delay_tck delay count top value in jtag_clock_tck() function.\n * @param delay_tms delay count top value in jtag_slow_clock_tms() function.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_configure_tck_cmd(struct ulink *device, int delay_scan_in,\n\tint delay_scan_out, int delay_scan_io, int delay_tck, int delay_tms)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_CONFIGURE_TCK_FREQ;\n\n\t/* CMD_CONFIGURE_TCK_FREQ has five OUT payload bytes and zero\n\t * IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 5, PAYLOAD_DIRECTION_OUT);\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tif (delay_scan_in < 0)\n\t\tcmd->payload_out[0] = 0;\n\telse\n\t\tcmd->payload_out[0] = (uint8_t)delay_scan_in;\n\n\tif (delay_scan_out < 0)\n\t\tcmd->payload_out[1] = 0;\n\telse\n\t\tcmd->payload_out[1] = (uint8_t)delay_scan_out;\n\n\tif (delay_scan_io < 0)\n\t\tcmd->payload_out[2] = 0;\n\telse\n\t\tcmd->payload_out[2] = (uint8_t)delay_scan_io;\n\n\tif (delay_tck < 0)\n\t\tcmd->payload_out[3] = 0;\n\telse\n\t\tcmd->payload_out[3] = (uint8_t)delay_tck;\n\n\tif (delay_tms < 0)\n\t\tcmd->payload_out[4] = 0;\n\telse\n\t\tcmd->payload_out[4] = (uint8_t)delay_tms;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Turn on/off ULINK LEDs.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param led_state which LED(s) to turn on or off. The following bits\n *  influence the LEDS:\n *  - Bit 0: Turn COM LED on\n *  - Bit 1: Turn RUN LED on\n *  - Bit 2: Turn COM LED off\n *  - Bit 3: Turn RUN LED off\n *  If both the on-bit and the off-bit for the same LED is set, the LED is\n *  turned off.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_led_cmd(struct ulink *device, uint8_t led_state)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_SET_LEDS;\n\n\t/* CMD_SET_LEDS has one OUT payload byte and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 1, PAYLOAD_DIRECTION_OUT);\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = led_state;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/**\n * Test command. Used to check if the ULINK device is ready to accept new\n * commands.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_append_test_cmd(struct ulink *device)\n{\n\tstruct ulink_cmd *cmd = calloc(1, sizeof(struct ulink_cmd));\n\tint ret;\n\n\tif (!cmd)\n\t\treturn ERROR_FAIL;\n\n\tcmd->id = CMD_TEST;\n\n\t/* CMD_TEST has one OUT payload byte and zero IN payload bytes */\n\tret = ulink_allocate_payload(cmd, 1, PAYLOAD_DIRECTION_OUT);\n\tif (ret != ERROR_OK) {\n\t\tfree(cmd);\n\t\treturn ret;\n\t}\n\n\tcmd->payload_out[0] = 0xAA;\n\n\treturn ulink_append_queue(device, cmd);\n}\n\n/****************** OpenULINK TCK frequency helper functions ******************/\n\n/**\n * Calculate delay values for a given TCK frequency.\n *\n * The OpenULINK firmware uses five different speed values for different\n * commands. These speed values are calculated in these functions.\n *\n * The five different commands which support variable TCK frequency are\n * implemented twice in the firmware:\n *   1. Maximum possible frequency without any artificial delay\n *   2. Variable frequency with artificial linear delay loop\n *\n * To set the ULINK to maximum frequency, it is only necessary to use the\n * corresponding command IDs. To set the ULINK to a lower frequency, the\n * delay loop top values have to be calculated first. Then, a\n * CMD_CONFIGURE_TCK_FREQ command needs to be sent to the ULINK device.\n *\n * The delay values are described by linear equations:\n *    t = k * x + d\n *    (t = period, k = constant, x = delay value, d = constant)\n *\n * Thus, the delay can be calculated as in the following equation:\n *    x = (t - d) / k\n *\n * The constants in these equations have been determined and validated by\n * measuring the frequency resulting from different delay values.\n *\n * @param type for which command to calculate the delay value.\n * @param f TCK frequency for which to calculate the delay value in Hz.\n * @param delay where to store resulting delay value.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_calculate_delay(enum ulink_delay_type type, long f, int *delay)\n{\n\tfloat t, x, x_ceil;\n\n\t/* Calculate period of requested TCK frequency */\n\tt = 1.0 / (float)(f);\n\n\tswitch (type) {\n\t    case DELAY_CLOCK_TCK:\n\t\t    x = (t - (float)(6E-6)) / (float)(4E-6);\n\t\t    break;\n\t    case DELAY_CLOCK_TMS:\n\t\t    x = (t - (float)(8.5E-6)) / (float)(4E-6);\n\t\t    break;\n\t    case DELAY_SCAN_IN:\n\t\t    x = (t - (float)(8.8308E-6)) / (float)(4E-6);\n\t\t    break;\n\t    case DELAY_SCAN_OUT:\n\t\t    x = (t - (float)(1.0527E-5)) / (float)(4E-6);\n\t\t    break;\n\t    case DELAY_SCAN_IO:\n\t\t    x = (t - (float)(1.3132E-5)) / (float)(4E-6);\n\t\t    break;\n\t    default:\n\t\t    return ERROR_FAIL;\n\t\t    break;\n\t}\n\n\t/* Check if the delay value is negative. This happens when a frequency is\n\t * requested that is too high for the delay loop implementation. In this\n\t * case, set delay value to zero. */\n\tif (x < 0)\n\t\tx = 0;\n\n\t/* We need to convert the exact delay value to an integer. Therefore, we\n\t * round the exact value UP to ensure that the resulting frequency is NOT\n\t * higher than the requested frequency. */\n\tx_ceil = ceilf(x);\n\n\t/* Check if the value is within limits */\n\tif (x_ceil > 255)\n\t\treturn ERROR_FAIL;\n\n\t*delay = (int)x_ceil;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Calculate frequency for a given delay value.\n *\n * Similar to the #ulink_calculate_delay function, this function calculates the\n * TCK frequency for a given delay value by using linear equations of the form:\n *    t = k * x + d\n *    (t = period, k = constant, x = delay value, d = constant)\n *\n * @param type for which command to calculate the delay value.\n * @param delay delay value for which to calculate the resulting TCK frequency.\n * @return the resulting TCK frequency\n */\nstatic long ulink_calculate_frequency(enum ulink_delay_type type, int delay)\n{\n\tfloat t, f_float;\n\n\tif (delay > 255)\n\t\treturn 0;\n\n\tswitch (type) {\n\t    case DELAY_CLOCK_TCK:\n\t\t    if (delay < 0)\n\t\t\t    t = (float)(2.666E-6);\n\t\t    else\n\t\t\t    t = (float)(4E-6) * (float)(delay) + (float)(6E-6);\n\t\t    break;\n\t    case DELAY_CLOCK_TMS:\n\t\t    if (delay < 0)\n\t\t\t    t = (float)(5.666E-6);\n\t\t    else\n\t\t\t    t = (float)(4E-6) * (float)(delay) + (float)(8.5E-6);\n\t\t    break;\n\t    case DELAY_SCAN_IN:\n\t\t    if (delay < 0)\n\t\t\t    t = (float)(5.5E-6);\n\t\t    else\n\t\t\t    t = (float)(4E-6) * (float)(delay) + (float)(8.8308E-6);\n\t\t    break;\n\t    case DELAY_SCAN_OUT:\n\t\t    if (delay < 0)\n\t\t\t    t = (float)(7.0E-6);\n\t\t    else\n\t\t\t    t = (float)(4E-6) * (float)(delay) + (float)(1.0527E-5);\n\t\t    break;\n\t    case DELAY_SCAN_IO:\n\t\t    if (delay < 0)\n\t\t\t    t = (float)(9.926E-6);\n\t\t    else\n\t\t\t    t = (float)(4E-6) * (float)(delay) + (float)(1.3132E-5);\n\t\t    break;\n\t    default:\n\t\t    return 0;\n\t}\n\n\tf_float = 1.0 / t;\n\treturn roundf(f_float);\n}\n\n/******************* Interface between OpenULINK and OpenOCD ******************/\n\n/**\n * Sets the end state follower (see interface.h) if \\a endstate is a stable\n * state.\n *\n * @param endstate the state the end state follower should be set to.\n */\nstatic void ulink_set_end_state(tap_state_t endstate)\n{\n\tif (tap_is_state_stable(endstate))\n\t\ttap_set_end_state(endstate);\n\telse {\n\t\tLOG_ERROR(\"BUG: %s is not a valid end state\", tap_state_name(endstate));\n\t\texit(EXIT_FAILURE);\n\t}\n}\n\n/**\n * Move from the current TAP state to the current TAP end state.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_statemove(struct ulink *device)\n{\n\tuint8_t tms_sequence, tms_count;\n\tint ret;\n\n\tif (tap_get_state() == tap_get_end_state()) {\n\t\t/* Do nothing if we are already there */\n\t\treturn ERROR_OK;\n\t}\n\n\ttms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\ttms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\n\tret = ulink_append_clock_tms_cmd(device, tms_count, tms_sequence);\n\n\tif (ret == ERROR_OK)\n\t\ttap_set_state(tap_get_end_state());\n\n\treturn ret;\n}\n\n/**\n * Perform a scan operation on a JTAG register.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_scan(struct ulink *device, struct jtag_command *cmd)\n{\n\tuint32_t scan_size_bits, scan_size_bytes, bits_last_scan;\n\tuint32_t scans_max_payload, bytecount;\n\tuint8_t *tdi_buffer_start = NULL, *tdi_buffer = NULL;\n\tuint8_t *tdo_buffer_start = NULL, *tdo_buffer = NULL;\n\n\tuint8_t first_tms_count, first_tms_sequence;\n\tuint8_t last_tms_count, last_tms_sequence;\n\n\tuint8_t tms_count_pause, tms_sequence_pause;\n\tuint8_t tms_count_resume, tms_sequence_resume;\n\n\tuint8_t tms_count_start, tms_sequence_start;\n\tuint8_t tms_count_end, tms_sequence_end;\n\n\tenum scan_type type;\n\tint ret;\n\n\t/* Determine scan size */\n\tscan_size_bits = jtag_scan_size(cmd->cmd.scan);\n\tscan_size_bytes = DIV_ROUND_UP(scan_size_bits, 8);\n\n\t/* Determine scan type (IN/OUT/IO) */\n\ttype = jtag_scan_type(cmd->cmd.scan);\n\n\t/* Determine number of scan commands with maximum payload */\n\tscans_max_payload = scan_size_bytes / 58;\n\n\t/* Determine size of last shift command */\n\tbits_last_scan = scan_size_bits - (scans_max_payload * 58 * 8);\n\n\t/* Allocate TDO buffer if required */\n\tif ((type == SCAN_IN) || (type == SCAN_IO)) {\n\t\ttdo_buffer_start = calloc(sizeof(uint8_t), scan_size_bytes);\n\n\t\tif (!tdo_buffer_start)\n\t\t\treturn ERROR_FAIL;\n\n\t\ttdo_buffer = tdo_buffer_start;\n\t}\n\n\t/* Fill TDI buffer if required */\n\tif ((type == SCAN_OUT) || (type == SCAN_IO)) {\n\t\tjtag_build_buffer(cmd->cmd.scan, &tdi_buffer_start);\n\t\ttdi_buffer = tdi_buffer_start;\n\t}\n\n\t/* Get TAP state transitions */\n\tif (cmd->cmd.scan->ir_scan) {\n\t\tulink_set_end_state(TAP_IRSHIFT);\n\t\tfirst_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\t\tfirst_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\n\t\ttap_set_state(TAP_IRSHIFT);\n\t\ttap_set_end_state(cmd->cmd.scan->end_state);\n\t\tlast_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\t\tlast_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\n\t\t/* TAP state transitions for split scans */\n\t\ttms_count_pause = tap_get_tms_path_len(TAP_IRSHIFT, TAP_IRPAUSE);\n\t\ttms_sequence_pause = tap_get_tms_path(TAP_IRSHIFT, TAP_IRPAUSE);\n\t\ttms_count_resume = tap_get_tms_path_len(TAP_IRPAUSE, TAP_IRSHIFT);\n\t\ttms_sequence_resume = tap_get_tms_path(TAP_IRPAUSE, TAP_IRSHIFT);\n\t} else {\n\t\tulink_set_end_state(TAP_DRSHIFT);\n\t\tfirst_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\t\tfirst_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\n\t\ttap_set_state(TAP_DRSHIFT);\n\t\ttap_set_end_state(cmd->cmd.scan->end_state);\n\t\tlast_tms_count = tap_get_tms_path_len(tap_get_state(), tap_get_end_state());\n\t\tlast_tms_sequence = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\n\t\t/* TAP state transitions for split scans */\n\t\ttms_count_pause = tap_get_tms_path_len(TAP_DRSHIFT, TAP_DRPAUSE);\n\t\ttms_sequence_pause = tap_get_tms_path(TAP_DRSHIFT, TAP_DRPAUSE);\n\t\ttms_count_resume = tap_get_tms_path_len(TAP_DRPAUSE, TAP_DRSHIFT);\n\t\ttms_sequence_resume = tap_get_tms_path(TAP_DRPAUSE, TAP_DRSHIFT);\n\t}\n\n\t/* Generate scan commands */\n\tbytecount = scan_size_bytes;\n\twhile (bytecount > 0) {\n\t\tif (bytecount == scan_size_bytes) {\n\t\t\t/* This is the first scan */\n\t\t\ttms_count_start = first_tms_count;\n\t\t\ttms_sequence_start = first_tms_sequence;\n\t\t} else {\n\t\t\t/* Resume from previous scan */\n\t\t\ttms_count_start = tms_count_resume;\n\t\t\ttms_sequence_start = tms_sequence_resume;\n\t\t}\n\n\t\tif (bytecount > 58) {\t/* Full scan, at least one scan will follow */\n\t\t\ttms_count_end = tms_count_pause;\n\t\t\ttms_sequence_end = tms_sequence_pause;\n\n\t\t\tret = ulink_append_scan_cmd(device,\n\t\t\t\t\ttype,\n\t\t\t\t\t58 * 8,\n\t\t\t\t\ttdi_buffer,\n\t\t\t\t\ttdo_buffer_start,\n\t\t\t\t\ttdo_buffer,\n\t\t\t\t\ttms_count_start,\n\t\t\t\t\ttms_sequence_start,\n\t\t\t\t\ttms_count_end,\n\t\t\t\t\ttms_sequence_end,\n\t\t\t\t\tcmd,\n\t\t\t\t\tfalse);\n\n\t\t\tbytecount -= 58;\n\n\t\t\t/* Update TDI and TDO buffer pointers */\n\t\t\tif (tdi_buffer_start)\n\t\t\t\ttdi_buffer += 58;\n\t\t\tif (tdo_buffer_start)\n\t\t\t\ttdo_buffer += 58;\n\t\t} else if (bytecount == 58) {\t/* Full scan, no further scans */\n\t\t\ttms_count_end = last_tms_count;\n\t\t\ttms_sequence_end = last_tms_sequence;\n\n\t\t\tret = ulink_append_scan_cmd(device,\n\t\t\t\t\ttype,\n\t\t\t\t\t58 * 8,\n\t\t\t\t\ttdi_buffer,\n\t\t\t\t\ttdo_buffer_start,\n\t\t\t\t\ttdo_buffer,\n\t\t\t\t\ttms_count_start,\n\t\t\t\t\ttms_sequence_start,\n\t\t\t\t\ttms_count_end,\n\t\t\t\t\ttms_sequence_end,\n\t\t\t\t\tcmd,\n\t\t\t\t\ttrue);\n\n\t\t\tbytecount = 0;\n\t\t} else {/* Scan with less than maximum payload, no further scans */\n\t\t\ttms_count_end = last_tms_count;\n\t\t\ttms_sequence_end = last_tms_sequence;\n\n\t\t\tret = ulink_append_scan_cmd(device,\n\t\t\t\t\ttype,\n\t\t\t\t\tbits_last_scan,\n\t\t\t\t\ttdi_buffer,\n\t\t\t\t\ttdo_buffer_start,\n\t\t\t\t\ttdo_buffer,\n\t\t\t\t\ttms_count_start,\n\t\t\t\t\ttms_sequence_start,\n\t\t\t\t\ttms_count_end,\n\t\t\t\t\ttms_sequence_end,\n\t\t\t\t\tcmd,\n\t\t\t\t\ttrue);\n\n\t\t\tbytecount = 0;\n\t\t}\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tfree(tdi_buffer_start);\n\t\t\tfree(tdo_buffer_start);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\tfree(tdi_buffer_start);\n\n\t/* Set current state to the end state requested by the command */\n\ttap_set_state(cmd->cmd.scan->end_state);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Move the TAP into the Test Logic Reset state.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_tlr_reset(struct ulink *device, struct jtag_command *cmd)\n{\n\tint ret;\n\n\tret = ulink_append_clock_tms_cmd(device, 5, 0xff);\n\n\tif (ret == ERROR_OK)\n\t\ttap_set_state(TAP_RESET);\n\n\treturn ret;\n}\n\n/**\n * Run Test.\n *\n * Generate TCK clock cycles while remaining\n * in the Run-Test/Idle state.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_runtest(struct ulink *device, struct jtag_command *cmd)\n{\n\tint ret;\n\n\t/* Only perform statemove if the TAP currently isn't in the TAP_IDLE state */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tulink_set_end_state(TAP_IDLE);\n\t\tulink_queue_statemove(device);\n\t}\n\n\t/* Generate the clock cycles */\n\tret = ulink_append_clock_tck_cmd(device, cmd->cmd.runtest->num_cycles);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Move to end state specified in command */\n\tif (cmd->cmd.runtest->end_state != tap_get_state()) {\n\t\ttap_set_end_state(cmd->cmd.runtest->end_state);\n\t\tulink_queue_statemove(device);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Execute a JTAG_RESET command\n *\n * @param device\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_reset(struct ulink *device, struct jtag_command *cmd)\n{\n\tuint8_t low = 0, high = 0;\n\n\tif (cmd->cmd.reset->trst) {\n\t\ttap_set_state(TAP_RESET);\n\t\thigh |= SIGNAL_TRST;\n\t} else\n\t\tlow |= SIGNAL_TRST;\n\n\tif (cmd->cmd.reset->srst)\n\t\thigh |= SIGNAL_RESET;\n\telse\n\t\tlow |= SIGNAL_RESET;\n\n\treturn ulink_append_set_signals_cmd(device, low, high);\n}\n\n/**\n * Move to one TAP state or several states in succession.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_pathmove(struct ulink *device, struct jtag_command *cmd)\n{\n\tint ret, i, num_states, batch_size, state_count;\n\ttap_state_t *path;\n\tuint8_t tms_sequence;\n\n\tnum_states = cmd->cmd.pathmove->num_states;\n\tpath = cmd->cmd.pathmove->path;\n\tstate_count = 0;\n\n\twhile (num_states > 0) {\n\t\ttms_sequence = 0;\n\n\t\t/* Determine batch size */\n\t\tif (num_states >= 8)\n\t\t\tbatch_size = 8;\n\t\telse\n\t\t\tbatch_size = num_states;\n\n\t\tfor (i = 0; i < batch_size; i++) {\n\t\t\tif (tap_state_transition(tap_get_state(), false) == path[state_count]) {\n\t\t\t\t/* Append '0' transition: clear bit 'i' in tms_sequence */\n\t\t\t\tbuf_set_u32(&tms_sequence, i, 1, 0x0);\n\t\t\t} else if (tap_state_transition(tap_get_state(), true)\n\t\t\t\t   == path[state_count]) {\n\t\t\t\t/* Append '1' transition: set bit 'i' in tms_sequence */\n\t\t\t\tbuf_set_u32(&tms_sequence, i, 1, 0x1);\n\t\t\t} else {\n\t\t\t\t/* Invalid state transition */\n\t\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP state transition\",\n\t\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\t\ttap_state_name(path[state_count]));\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\ttap_set_state(path[state_count]);\n\t\t\tstate_count++;\n\t\t\tnum_states--;\n\t\t}\n\n\t\t/* Append CLOCK_TMS command to OpenULINK command queue */\n\t\tLOG_INFO(\n\t\t\t\"pathmove batch: count = %i, sequence = 0x%x\", batch_size, tms_sequence);\n\t\tret = ulink_append_clock_tms_cmd(ulink_handle, batch_size, tms_sequence);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sleep for a specific amount of time.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_queue_sleep(struct ulink *device, struct jtag_command *cmd)\n{\n\t/* IMPORTANT! Due to the time offset in command execution introduced by\n\t * command queueing, this needs to be implemented in the ULINK device */\n\treturn ulink_append_sleep_cmd(device, cmd->cmd.sleep->us);\n}\n\n/**\n * Generate TCK cycles while remaining in a stable state.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @param cmd pointer to the command that shall be executed.\n */\nstatic int ulink_queue_stableclocks(struct ulink *device, struct jtag_command *cmd)\n{\n\tint ret;\n\tunsigned num_cycles;\n\n\tif (!tap_is_state_stable(tap_get_state())) {\n\t\tLOG_ERROR(\"JTAG_STABLECLOCKS: state not stable\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tnum_cycles = cmd->cmd.stableclocks->num_cycles;\n\n\t/* TMS stays either high (Test Logic Reset state) or low (all other states) */\n\tif (tap_get_state() == TAP_RESET)\n\t\tret = ulink_append_set_signals_cmd(device, 0, SIGNAL_TMS);\n\telse\n\t\tret = ulink_append_set_signals_cmd(device, SIGNAL_TMS, 0);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\twhile (num_cycles > 0) {\n\t\tif (num_cycles > 0xFFFF) {\n\t\t\t/* OpenULINK CMD_CLOCK_TCK can generate up to 0xFFFF (uint16_t) cycles */\n\t\t\tret = ulink_append_clock_tck_cmd(device, 0xFFFF);\n\t\t\tnum_cycles -= 0xFFFF;\n\t\t} else {\n\t\t\tret = ulink_append_clock_tck_cmd(device, num_cycles);\n\t\t\tnum_cycles = 0;\n\t\t}\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Post-process JTAG_SCAN command\n *\n * @param ulink_cmd pointer to OpenULINK command that shall be processed.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_post_process_scan(struct ulink_cmd *ulink_cmd)\n{\n\tstruct jtag_command *cmd = ulink_cmd->cmd_origin;\n\tint ret;\n\n\tswitch (jtag_scan_type(cmd->cmd.scan)) {\n\t    case SCAN_IN:\n\t    case SCAN_IO:\n\t\t    ret = jtag_read_buffer(ulink_cmd->payload_in_start, cmd->cmd.scan);\n\t\t    break;\n\t    case SCAN_OUT:\n\t\t\t/* Nothing to do for OUT scans */\n\t\t    ret = ERROR_OK;\n\t\t    break;\n\t    default:\n\t\t    LOG_ERROR(\"BUG: ulink_post_process_scan() encountered an unknown\"\n\t\t\t\" JTAG scan type\");\n\t\t    ret = ERROR_FAIL;\n\t\t    break;\n\t}\n\n\treturn ret;\n}\n\n/**\n * Perform post-processing of commands after OpenULINK queue has been executed.\n *\n * @param device pointer to struct ulink identifying ULINK driver instance.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_post_process_queue(struct ulink *device)\n{\n\tstruct ulink_cmd *current;\n\tstruct jtag_command *openocd_cmd;\n\tint ret;\n\n\tcurrent = device->queue_start;\n\n\twhile (current) {\n\t\topenocd_cmd = current->cmd_origin;\n\n\t\t/* Check if a corresponding OpenOCD command is stored for this\n\t\t * OpenULINK command */\n\t\tif ((current->needs_postprocessing == true) && (openocd_cmd)) {\n\t\t\tswitch (openocd_cmd->type) {\n\t\t\t    case JTAG_SCAN:\n\t\t\t\t    ret = ulink_post_process_scan(current);\n\t\t\t\t    break;\n\t\t\t    case JTAG_TLR_RESET:\n\t\t\t    case JTAG_RUNTEST:\n\t\t\t    case JTAG_RESET:\n\t\t\t    case JTAG_PATHMOVE:\n\t\t\t    case JTAG_SLEEP:\n\t\t\t    case JTAG_STABLECLOCKS:\n\t\t\t\t\t/* Nothing to do for these commands */\n\t\t\t\t    ret = ERROR_OK;\n\t\t\t\t    break;\n\t\t\t    default:\n\t\t\t\t    ret = ERROR_FAIL;\n\t\t\t\t    LOG_ERROR(\"BUG: ulink_post_process_queue() encountered unknown JTAG \"\n\t\t\t\t\t\"command type\");\n\t\t\t\t    break;\n\t\t\t}\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\n\t\tcurrent = current->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**************************** JTAG driver functions ***************************/\n\n/**\n * Executes the JTAG Command Queue.\n *\n * This is done in three stages: First, all OpenOCD commands are processed into\n * queued OpenULINK commands. Next, the OpenULINK command queue is sent to the\n * ULINK device and data received from the ULINK device is cached. Finally,\n * the post-processing function writes back data to the corresponding OpenOCD\n * commands.\n *\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint ret;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t    case JTAG_SCAN:\n\t\t\t    ret = ulink_queue_scan(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_TLR_RESET:\n\t\t\t    ret = ulink_queue_tlr_reset(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_RUNTEST:\n\t\t\t    ret = ulink_queue_runtest(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_RESET:\n\t\t\t    ret = ulink_queue_reset(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_PATHMOVE:\n\t\t\t    ret = ulink_queue_pathmove(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_SLEEP:\n\t\t\t    ret = ulink_queue_sleep(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    case JTAG_STABLECLOCKS:\n\t\t\t    ret = ulink_queue_stableclocks(ulink_handle, cmd);\n\t\t\t    break;\n\t\t    default:\n\t\t\t    ret = ERROR_FAIL;\n\t\t\t    LOG_ERROR(\"BUG: encountered unknown JTAG command type\");\n\t\t\t    break;\n\t\t}\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tcmd = cmd->next;\n\t}\n\n\tif (ulink_handle->commands_in_queue > 0) {\n\t\tret = ulink_execute_queued_commands(ulink_handle, LIBUSB_TIMEOUT_MS);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = ulink_post_process_queue(ulink_handle);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tulink_clear_queue(ulink_handle);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Set the TCK frequency of the ULINK adapter.\n *\n * @param khz desired JTAG TCK frequency.\n * @param jtag_speed where to store corresponding adapter-specific speed value.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_khz(int khz, int *jtag_speed)\n{\n\tint ret;\n\n\tif (khz == 0) {\n\t\tLOG_ERROR(\"RCLK not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* CLOCK_TCK commands are decoupled from others. Therefore, the frequency\n\t * setting can be done independently from all other commands. */\n\tif (khz >= 375)\n\t\tulink_handle->delay_clock_tck = -1;\n\telse {\n\t\tret = ulink_calculate_delay(DELAY_CLOCK_TCK, khz * 1000,\n\t\t\t\t&ulink_handle->delay_clock_tck);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\t/* SCAN_{IN,OUT,IO} commands invoke CLOCK_TMS commands. Therefore, if the\n\t * requested frequency goes below the maximum frequency for SLOW_CLOCK_TMS\n\t * commands, all SCAN commands MUST also use the variable frequency\n\t * implementation! */\n\tif (khz >= 176) {\n\t\tulink_handle->delay_clock_tms = -1;\n\t\tulink_handle->delay_scan_in = -1;\n\t\tulink_handle->delay_scan_out = -1;\n\t\tulink_handle->delay_scan_io = -1;\n\t} else {\n\t\tret = ulink_calculate_delay(DELAY_CLOCK_TMS, khz * 1000,\n\t\t\t\t&ulink_handle->delay_clock_tms);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = ulink_calculate_delay(DELAY_SCAN_IN, khz * 1000,\n\t\t\t\t&ulink_handle->delay_scan_in);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = ulink_calculate_delay(DELAY_SCAN_OUT, khz * 1000,\n\t\t\t\t&ulink_handle->delay_scan_out);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = ulink_calculate_delay(DELAY_SCAN_IO, khz * 1000,\n\t\t\t\t&ulink_handle->delay_scan_io);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tLOG_DEBUG_IO(\"ULINK TCK setup: delay_tck      = %i (%li Hz),\",\n\t\tulink_handle->delay_clock_tck,\n\t\tulink_calculate_frequency(DELAY_CLOCK_TCK, ulink_handle->delay_clock_tck));\n\tLOG_DEBUG_IO(\"                 delay_tms      = %i (%li Hz),\",\n\t\tulink_handle->delay_clock_tms,\n\t\tulink_calculate_frequency(DELAY_CLOCK_TMS, ulink_handle->delay_clock_tms));\n\tLOG_DEBUG_IO(\"                 delay_scan_in  = %i (%li Hz),\",\n\t\tulink_handle->delay_scan_in,\n\t\tulink_calculate_frequency(DELAY_SCAN_IN, ulink_handle->delay_scan_in));\n\tLOG_DEBUG_IO(\"                 delay_scan_out = %i (%li Hz),\",\n\t\tulink_handle->delay_scan_out,\n\t\tulink_calculate_frequency(DELAY_SCAN_OUT, ulink_handle->delay_scan_out));\n\tLOG_DEBUG_IO(\"                 delay_scan_io  = %i (%li Hz),\",\n\t\tulink_handle->delay_scan_io,\n\t\tulink_calculate_frequency(DELAY_SCAN_IO, ulink_handle->delay_scan_io));\n\n\t/* Configure the ULINK device with the new delay values */\n\tret = ulink_append_configure_tck_cmd(ulink_handle,\n\t\t\tulink_handle->delay_scan_in,\n\t\t\tulink_handle->delay_scan_out,\n\t\t\tulink_handle->delay_scan_io,\n\t\t\tulink_handle->delay_clock_tck,\n\t\t\tulink_handle->delay_clock_tms);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t*jtag_speed = khz;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Set the TCK frequency of the ULINK adapter.\n *\n * Because of the way the TCK frequency is set up in the OpenULINK firmware,\n * there are five different speed settings. To simplify things, the\n * adapter-specific speed setting value is identical to the TCK frequency in\n * khz.\n *\n * @param speed desired adapter-specific speed value.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_speed(int speed)\n{\n\tint dummy;\n\n\treturn ulink_khz(speed, &dummy);\n}\n\n/**\n * Convert adapter-specific speed value to corresponding TCK frequency in kHz.\n *\n * Because of the way the TCK frequency is set up in the OpenULINK firmware,\n * there are five different speed settings. To simplify things, the\n * adapter-specific speed setting value is identical to the TCK frequency in\n * khz.\n *\n * @param speed adapter-specific speed value.\n * @param khz where to store corresponding TCK frequency in kHz.\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Initiates the firmware download to the ULINK adapter and prepares\n * the USB handle.\n *\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_init(void)\n{\n\tint ret, transferred;\n\tchar str_manufacturer[20];\n\tbool download_firmware = false;\n\tunsigned char *dummy;\n\tuint8_t input_signals, output_signals;\n\n\tulink_handle = calloc(1, sizeof(struct ulink));\n\tif (!ulink_handle)\n\t\treturn ERROR_FAIL;\n\n\tlibusb_init(&ulink_handle->libusb_ctx);\n\n\tret = ulink_usb_open(&ulink_handle);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not open ULINK device\");\n\t\tfree(ulink_handle);\n\t\tulink_handle = NULL;\n\t\treturn ret;\n\t}\n\n\t/* Get String Descriptor to determine if firmware needs to be loaded */\n\tret = libusb_get_string_descriptor_ascii(ulink_handle->usb_device_handle, 1, (unsigned char *)str_manufacturer, 20);\n\tif (ret < 0) {\n\t\t/* Could not get descriptor -> Unconfigured or original Keil firmware */\n\t\tdownload_firmware = true;\n\t} else {\n\t\t/* We got a String Descriptor, check if it is the correct one */\n\t\tif (strncmp(str_manufacturer, \"OpenULINK\", 9) != 0)\n\t\t\tdownload_firmware = true;\n\t}\n\n\tif (download_firmware == true) {\n\t\tLOG_INFO(\"Loading OpenULINK firmware. This is reversible by power-cycling\"\n\t\t\t\" ULINK device.\");\n\t\tret = ulink_load_firmware_and_renumerate(&ulink_handle,\n\t\t\t\tULINK_FIRMWARE_FILE, ULINK_RENUMERATION_DELAY);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not download firmware and re-numerate ULINK\");\n\t\t\tfree(ulink_handle);\n\t\t\tulink_handle = NULL;\n\t\t\treturn ret;\n\t\t}\n\t} else\n\t\tLOG_INFO(\"ULINK device is already running OpenULINK firmware\");\n\n\t/* Get OpenULINK USB IN/OUT endpoints and claim the interface */\n\tret = jtag_libusb_choose_interface(ulink_handle->usb_device_handle,\n\t\t&ulink_handle->ep_in, &ulink_handle->ep_out, -1, -1, -1, -1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* Initialize OpenULINK command queue */\n\tulink_clear_queue(ulink_handle);\n\n\t/* Issue one test command with short timeout */\n\tret = ulink_append_test_cmd(ulink_handle);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ulink_execute_queued_commands(ulink_handle, 200);\n\tif (ret != ERROR_OK) {\n\t\t/* Sending test command failed. The ULINK device may be forever waiting for\n\t\t * the host to fetch an USB Bulk IN packet (e. g. OpenOCD crashed or was\n\t\t * shut down by the user via Ctrl-C. Try to retrieve this Bulk IN packet. */\n\t\tdummy = calloc(64, sizeof(uint8_t));\n\n\t\tret = libusb_bulk_transfer(ulink_handle->usb_device_handle, ulink_handle->ep_in,\n\t\t\t\tdummy, 64, &transferred, 200);\n\n\t\tfree(dummy);\n\n\t\tif (ret != 0 || transferred == 0) {\n\t\t\t/* Bulk IN transfer failed -> unrecoverable error condition */\n\t\t\tLOG_ERROR(\"Cannot communicate with ULINK device. Disconnect ULINK from \"\n\t\t\t\t\"the USB port and re-connect, then re-run OpenOCD\");\n\t\t\tfree(ulink_handle);\n\t\t\tulink_handle = NULL;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n#ifdef _DEBUG_USB_COMMS_\n\t\telse {\n\t\t\t/* Successfully received Bulk IN packet -> continue */\n\t\t\tLOG_INFO(\"Recovered from lost Bulk IN packet\");\n\t\t}\n#endif\n\t}\n\tulink_clear_queue(ulink_handle);\n\n\tret = ulink_append_get_signals_cmd(ulink_handle);\n\tif (ret == ERROR_OK)\n\t\tret = ulink_execute_queued_commands(ulink_handle, 200);\n\n\tif (ret == ERROR_OK) {\n\t\t/* Post-process the single CMD_GET_SIGNALS command */\n\t\tinput_signals = ulink_handle->queue_start->payload_in[0];\n\t\toutput_signals = ulink_handle->queue_start->payload_in[1];\n\n\t\tulink_print_signal_states(input_signals, output_signals);\n\t}\n\n\tulink_clear_queue(ulink_handle);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Closes the USB handle for the ULINK device.\n *\n * @return on success: ERROR_OK\n * @return on failure: ERROR_FAIL\n */\nstatic int ulink_quit(void)\n{\n\tint ret;\n\n\tret = ulink_usb_close(&ulink_handle);\n\tfree(ulink_handle);\n\n\treturn ret;\n}\n\n/**\n * Set a custom path to ULINK firmware image and force downloading to ULINK.\n */\nCOMMAND_HANDLER(ulink_download_firmware_handler)\n{\n\tint ret;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\n\tLOG_INFO(\"Downloading ULINK firmware image %s\", CMD_ARGV[0]);\n\n\t/* Download firmware image in CMD_ARGV[0] */\n\tret = ulink_load_firmware_and_renumerate(&ulink_handle, CMD_ARGV[0],\n\t\t\tULINK_RENUMERATION_DELAY);\n\n\treturn ret;\n}\n\n/*************************** Command Registration **************************/\n\nstatic const struct command_registration ulink_subcommand_handlers[] = {\n\t{\n\t\t.name = \"download_firmware\",\n\t\t.handler = &ulink_download_firmware_handler,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"download firmware image to ULINK device\",\n\t\t.usage = \"path/to/ulink_firmware.hex\",\n\t},\n\tCOMMAND_REGISTRATION_DONE,\n};\n\nstatic const struct command_registration ulink_command_handlers[] = {\n\t{\n\t\t.name = \"ulink\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform ulink management\",\n\t\t.chain = ulink_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface ulink_interface = {\n\t.execute_queue = ulink_execute_queue,\n};\n\nstruct adapter_driver ulink_adapter_driver = {\n\t.name = \"ulink\",\n\t.transports = jtag_only,\n\t.commands = ulink_command_handlers,\n\n\t.init = ulink_init,\n\t.quit = ulink_quit,\n\t.speed = ulink_speed,\n\t.khz = ulink_khz,\n\t.speed_div = ulink_speed_div,\n\n\t.jtag_ops = &ulink_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libocdusbblaster.la\n%C%_libocdusbblaster_la_SOURCES = $(USB_BLASTER_SRC)\n%C%_libocdusbblaster_la_CPPFLAGS = -I$(top_srcdir)/src/jtag/drivers $(AM_CPPFLAGS) $(LIBUSB1_CFLAGS) $(LIBFTDI_CFLAGS)\n\nUSB_BLASTER_SRC = %D%/usb_blaster.c %D%/ublast_access.h\n\nif USB_BLASTER\nUSB_BLASTER_SRC += %D%/ublast_access_ftdi.c\nendif\n\nif USB_BLASTER_2\nUSB_BLASTER_SRC += %D%/ublast2_access_libusb.c\nendif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/README.CheapClone",
    "content": "USB Blaster Cheap Clone\n=======================\n\nThe Altera USB Blaster has a cheap clone, based on :\n - a Cypress CY7C68013A-56PVXC as the main chip\n - a 74HC244D as the output latch\n - a 24 MHz quartz\n - a EEPROM 24C64BN\n\nThe schematics (cut down to essential) is :\n\n                           /-----------------+----------------------\\\n     +--------------+      |                 |                      |\nUSB--|  CY7C68013A  |      |  +----------+   |                      |\n     |              |      |  | 74HC244D |   |                      |\n     .              .      |  |          |   |                      |\n     .              .      \\--o 1     20 o   |     10 pins header   |\n     |           47 o-- TCK --o 2     19 o---/        +-------+     |\n     |           46 o-- TDO --o 3     18 o-- TCK -----o 1   2 o     |\n     |           45 o-- TMS --o 4     17 o-- TDO -----o 3   4 o     |\n     |           44 o         o 5     16 o-- TMS -----o 5   6 o     |\n     |           43 o--       o 6     15 o            o 7   8 o     |\n     |           42 o--       o 7     14 o         +--o 9  10 o     |\n     |           41 o-- TDI --o 8     13 o-- ?     |  +-------+     |\n     .           40 o-- nOE \\ o 9     12 o-- TDI --+                |\n     .              .       | o 10    11 o                          |\n     o 28        29 o       | |          |                          |\n     |              |       | +----------+                          |\n     +--------------+       \\                                       |\n                             ---------------------------------------/\n\nFrom this one can deduce that :\n - the cypress emulates the Altera chip\n - as the cypress pins used are 41-47, all output/input are controlled by 8051\n   PortA.\n - as the 8051 is clocked at 24Mhz, and because each USB byte is handled by the\n   8051, assuming a 40 instruction cycles per USB packet, the maximum throughput\n   would be around 500 kHz.\n\nPinout\n======\n Port A.0: nOE (output enable of 74HC244D)\n Port A.1: TDI\n Port A.5: TMS\n Port A.6: TDO\n Port A.7: TCK\n\nThroughput considerations\n=========================\nMeasurements on a scope reveal that :\n - for bitbang mode, the throughput is 56.5 kbits/s\n   (as each clock transition is measured at 17.7us)\n - for byteshift mode, the throughput is 107.7 kbits/s\n   (as 63 bits TDI transmission is measured in 585 us)\n\nLet's suppose that to upload a 32 bits value, it is necessary to :\n - move from IDLE to DR-SHIFT : 3 bitbang (3 TMS transitions)\n - input the 32 bits of data : 1 byteshift (24 bits) + 8 bitbang (8 bits)\n - move from DR-SHIFT to IDLE : 5 bitbang (5 TMS transitions)\nSo for this 32 bits of data, the time would be :\n   3 * 17.7us + 1 * 585us/63*24 + 5 * 17.7us\n = 53.1us + 222us + 88.5us\n = 363us\n\nThroughput in bit/s: 32 * (1 / 363E-6) = 88000 bits/s\nThroughput in bytes/s: 11kBytes/s\n\nConclusion\n==========\nContrary to the original USB Blaster, the cheap clone will never reach high\ntransfer speeds over JTAG.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/ublast2_access_libusb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n *   Driver for USB-JTAG, Altera USB-Blaster II and compatibles\n *\n *   Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com\n *\n */\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"helper/system.h\"\n#include <libusb_helper.h>\n#include <target/image.h>\n\n#include \"ublast_access.h\"\n\n#define USBBLASTER_CTRL_READ_REV\t0x94\n#define USBBLASTER_CTRL_LOAD_FIRM\t0xA0\n#define USBBLASTER_EPOUT\t\t4\n#define USBBLASTER_EPIN\t\t\t8\n\n#define EZUSB_CPUCS\t\t\t0xe600\n#define CPU_RESET\t\t\t1\n\n/** Maximum size of a single firmware section. Entire EZ-USB code space = 16kB */\n#define SECTION_BUFFERSIZE\t\t16384\n\nstatic int ublast2_libusb_read(struct ublast_lowlevel *low, uint8_t *buf,\n\t\t\t      unsigned size, uint32_t *bytes_read)\n{\n\tint ret, tmp = 0;\n\n\tret = jtag_libusb_bulk_read(low->libusb_dev,\n\t\t\t\t\t    USBBLASTER_EPIN |\n\t\t\t\t\t    LIBUSB_ENDPOINT_IN,\n\t\t\t\t\t    (char *)buf,\n\t\t\t\t\t    size,\n\t\t\t\t\t    100, &tmp);\n\t*bytes_read = tmp;\n\n\treturn ret;\n}\n\nstatic int ublast2_libusb_write(struct ublast_lowlevel *low, uint8_t *buf,\n\t\t\t       int size, uint32_t *bytes_written)\n{\n\tint ret, tmp = 0;\n\n\tret = jtag_libusb_bulk_write(low->libusb_dev,\n\t\t\t\t\t\tUSBBLASTER_EPOUT |\n\t\t\t\t\t\tLIBUSB_ENDPOINT_OUT,\n\t\t\t\t\t\t(char *)buf,\n\t\t\t\t\t\tsize,\n\t\t\t\t\t\t100, &tmp);\n\t*bytes_written = tmp;\n\n\treturn ret;\n\n}\n\nstatic int ublast2_write_firmware_section(struct libusb_device_handle *libusb_dev,\n\t\t\t\t   struct image *firmware_image, int section_index)\n{\n\tuint16_t chunk_size;\n\tuint8_t data[SECTION_BUFFERSIZE];\n\tuint8_t *data_ptr = data;\n\tsize_t size_read;\n\n\tuint16_t size = (uint16_t)firmware_image->sections[section_index].size;\n\tuint16_t addr = (uint16_t)firmware_image->sections[section_index].base_address;\n\n\tLOG_DEBUG(\"section %02i at addr 0x%04x (size 0x%04x)\", section_index, addr,\n\t\tsize);\n\n\t/* Copy section contents to local buffer */\n\tint ret = image_read_section(firmware_image, section_index, 0, size, data,\n\t\t\t&size_read);\n\n\tif ((ret != ERROR_OK) || (size_read != size)) {\n\t\t/* Propagating the return code would return '0' (misleadingly indicating\n\t\t * successful execution of the function) if only the size check fails. */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint16_t bytes_remaining = size;\n\n\t/* Send section data in chunks of up to 64 bytes to ULINK */\n\twhile (bytes_remaining > 0) {\n\t\tif (bytes_remaining > 64)\n\t\t\tchunk_size = 64;\n\t\telse\n\t\t\tchunk_size = bytes_remaining;\n\n\t\tjtag_libusb_control_transfer(libusb_dev,\n\t\t\t\t\t     LIBUSB_REQUEST_TYPE_VENDOR |\n\t\t\t\t\t     LIBUSB_ENDPOINT_OUT,\n\t\t\t\t\t     USBBLASTER_CTRL_LOAD_FIRM,\n\t\t\t\t\t     addr,\n\t\t\t\t\t     0,\n\t\t\t\t\t     (char *)data_ptr,\n\t\t\t\t\t     chunk_size,\n\t\t\t\t\t     100);\n\n\t\tbytes_remaining -= chunk_size;\n\t\taddr += chunk_size;\n\t\tdata_ptr += chunk_size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int load_usb_blaster_firmware(struct libusb_device_handle *libusb_dev,\n\t\t\t\t     struct ublast_lowlevel *low)\n{\n\tstruct image ublast2_firmware_image;\n\n\tif (!low->firmware_path) {\n\t\tLOG_ERROR(\"No firmware path specified\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (libusb_claim_interface(libusb_dev, 0)) {\n\t\tLOG_ERROR(\"unable to claim interface\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tublast2_firmware_image.base_address = 0;\n\tublast2_firmware_image.base_address_set = false;\n\n\tint ret = image_open(&ublast2_firmware_image, low->firmware_path, \"ihex\");\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not load firmware image\");\n\t\tgoto error_release_usb;\n\t}\n\n\t/** A host loader program must write 0x01 to the CPUCS register\n\t * to put the CPU into RESET, load all or part of the EZUSB\n\t * RAM with firmware, then reload the CPUCS register\n\t * with ‘0’ to take the CPU out of RESET. The CPUCS register\n\t * (at 0xE600) is the only EZ-USB register that can be written\n\t * using the Firmware Download command.\n\t */\n\n\tchar value = CPU_RESET;\n\tjtag_libusb_control_transfer(libusb_dev,\n\t\t\t\t     LIBUSB_REQUEST_TYPE_VENDOR |\n\t\t\t\t     LIBUSB_ENDPOINT_OUT,\n\t\t\t\t     USBBLASTER_CTRL_LOAD_FIRM,\n\t\t\t\t     EZUSB_CPUCS,\n\t\t\t\t     0,\n\t\t\t\t     &value,\n\t\t\t\t     1,\n\t\t\t\t     100);\n\n\t/* Download all sections in the image to ULINK */\n\tfor (unsigned int i = 0; i < ublast2_firmware_image.num_sections; i++) {\n\t\tret = ublast2_write_firmware_section(libusb_dev,\n\t\t\t\t\t\t     &ublast2_firmware_image, i);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while downloading the firmware\");\n\t\t\tgoto error_close_firmware;\n\t\t}\n\t}\n\n\tvalue = !CPU_RESET;\n\tjtag_libusb_control_transfer(libusb_dev,\n\t\t\t\t     LIBUSB_REQUEST_TYPE_VENDOR |\n\t\t\t\t     LIBUSB_ENDPOINT_OUT,\n\t\t\t\t     USBBLASTER_CTRL_LOAD_FIRM,\n\t\t\t\t     EZUSB_CPUCS,\n\t\t\t\t     0,\n\t\t\t\t     &value,\n\t\t\t\t     1,\n\t\t\t\t     100);\n\nerror_close_firmware:\n\timage_close(&ublast2_firmware_image);\n\nerror_release_usb:\n\t/*\n\t * Release claimed interface. Most probably it is already disconnected\n\t * and re-enumerated as new devices after firmware upload, so we do\n\t * not need to care about errors.\n\t */\n\tlibusb_release_interface(libusb_dev, 0);\n\n\treturn ret;\n}\n\nstatic int ublast2_libusb_init(struct ublast_lowlevel *low)\n{\n\tconst uint16_t vids[] = { low->ublast_vid_uninit, 0 };\n\tconst uint16_t pids[] = { low->ublast_pid_uninit, 0 };\n\tstruct libusb_device_handle *temp;\n\tbool renumeration = false;\n\tint ret;\n\n\tif (jtag_libusb_open(vids, pids, &temp, NULL) == ERROR_OK) {\n\t\tLOG_INFO(\"Altera USB-Blaster II (uninitialized) found\");\n\t\tLOG_INFO(\"Loading firmware...\");\n\t\tret = load_usb_blaster_firmware(temp, low);\n\t\tjtag_libusb_close(temp);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\trenumeration = true;\n\t}\n\n\tconst uint16_t vids_renum[] = { low->ublast_vid, 0 };\n\tconst uint16_t pids_renum[] = { low->ublast_pid, 0 };\n\n\tif (renumeration == false) {\n\t\tif (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Altera USB-Blaster II not found\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tint retry = 10;\n\t\twhile (jtag_libusb_open(vids_renum, pids_renum, &low->libusb_dev, NULL) != ERROR_OK && retry--) {\n\t\t\tusleep(1000000);\n\t\t\tLOG_INFO(\"Waiting for reenumerate...\");\n\t\t}\n\n\t\tif (!retry) {\n\t\t\tLOG_ERROR(\"Altera USB-Blaster II not found\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (libusb_claim_interface(low->libusb_dev, 0)) {\n\t\tLOG_ERROR(\"unable to claim interface\");\n\t\tjtag_libusb_close(low->libusb_dev);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tchar buffer[5];\n\tjtag_libusb_control_transfer(low->libusb_dev,\n\t\t\t\t     LIBUSB_REQUEST_TYPE_VENDOR |\n\t\t\t\t     LIBUSB_ENDPOINT_IN,\n\t\t\t\t     USBBLASTER_CTRL_READ_REV,\n\t\t\t\t     0,\n\t\t\t\t     0,\n\t\t\t\t     buffer,\n\t\t\t\t     5,\n\t\t\t\t     100);\n\n\tLOG_INFO(\"Altera USB-Blaster II found (Firm. rev. = %s)\", buffer);\n\n\treturn ERROR_OK;\n}\n\nstatic int ublast2_libusb_quit(struct ublast_lowlevel *low)\n{\n\tif (libusb_release_interface(low->libusb_dev, 0))\n\t\tLOG_ERROR(\"usb release interface failed\");\n\n\tjtag_libusb_close(low->libusb_dev);\n\treturn ERROR_OK;\n};\n\nstatic struct ublast_lowlevel low = {\n\t.open = ublast2_libusb_init,\n\t.close = ublast2_libusb_quit,\n\t.read = ublast2_libusb_read,\n\t.write = ublast2_libusb_write,\n\t.flags = COPY_TDO_BUFFER,\n};\n\nstruct ublast_lowlevel *ublast2_register_libusb(void)\n{\n\treturn &low;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/ublast_access.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n *   Driver for USB-JTAG, Altera USB-Blaster and compatibles\n *\n *   Inspired from original code from Kolja Waschk's USB-JTAG project\n *   (http://www.ixo.de/info/usb_jtag/), and from openocd project.\n *\n *   Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com\n *   Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr\n *   Copyright (C) 2011 Ali Lown ali@lown.me.uk\n *   Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca\n *   Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de\n *\n */\n\n#ifndef OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H\n#define OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H\n\n/* Low level flags */\n#define COPY_TDO_BUFFER\t\t(1 << 0)\n\nstruct ublast_lowlevel {\n\tuint16_t ublast_vid;\n\tuint16_t ublast_pid;\n\tuint16_t ublast_vid_uninit;\n\tuint16_t ublast_pid_uninit;\n\tstruct libusb_device_handle *libusb_dev;\n\tchar *firmware_path;\n\n\tint (*write)(struct ublast_lowlevel *low, uint8_t *buf, int size,\n\t\t     uint32_t *bytes_written);\n\tint (*read)(struct ublast_lowlevel *low, uint8_t *buf, unsigned size,\n\t\t    uint32_t *bytes_read);\n\tint (*open)(struct ublast_lowlevel *low);\n\tint (*close)(struct ublast_lowlevel *low);\n\tint (*speed)(struct ublast_lowlevel *low, int speed);\n\n\tvoid *priv;\n\tint flags;\n};\n\n/**\n * ublast_register_ftdi - get a lowlevel USB Blaster driver\n * ublast2_register_libusb - get a lowlevel USB Blaster II driver\n *\n * Get a lowlevel USB-Blaster driver. In the current implementation, there are 2\n * possible lowlevel drivers :\n *  - one based on libftdi,\n *  - one based on libusb, specific to the USB-Blaster II\n *\n * Returns the lowlevel driver structure.\n */\nextern struct ublast_lowlevel *ublast_register_ftdi(void);\nextern struct ublast_lowlevel *ublast2_register_libusb(void);\n\n#endif /* OPENOCD_JTAG_DRIVERS_USB_BLASTER_UBLAST_ACCESS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/ublast_access_ftdi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n *   Driver for USB-JTAG, Altera USB-Blaster and compatibles\n *\n *   Inspired from original code from Kolja Waschk's USB-JTAG project\n *   (http://www.ixo.de/info/usb_jtag/), and from openocd project.\n *\n *   Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr\n *   Copyright (C) 2011 Ali Lown ali@lown.me.uk\n *   Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca\n *   Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de\n *\n */\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n\n#include \"ublast_access.h\"\n#include <ftdi.h>\n\nstatic struct ftdi_context *ublast_getftdic(struct ublast_lowlevel *low)\n{\n\treturn low->priv;\n}\n\nstatic int ublast_ftdi_read(struct ublast_lowlevel *low, uint8_t *buf,\n\t\t\t    unsigned size, uint32_t *bytes_read)\n{\n\tint retval;\n\tint timeout = 100;\n\tstruct ftdi_context *ftdic = ublast_getftdic(low);\n\n\t*bytes_read = 0;\n\twhile ((*bytes_read < size) && timeout--) {\n\t\tretval = ftdi_read_data(ftdic, buf + *bytes_read,\n\t\t\t\tsize - *bytes_read);\n\t\tif (retval < 0)\t{\n\t\t\t*bytes_read = 0;\n\t\t\tLOG_ERROR(\"ftdi_read_data: %s\",\n\t\t\t\t\tftdi_get_error_string(ftdic));\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\t*bytes_read += retval;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ublast_ftdi_write(struct ublast_lowlevel *low, uint8_t *buf, int size,\n\t\t\t     uint32_t *bytes_written)\n{\n\tint retval;\n\tstruct ftdi_context *ftdic = ublast_getftdic(low);\n\n\tretval = ftdi_write_data(ftdic, buf, size);\n\tif (retval < 0)\t{\n\t\t*bytes_written = 0;\n\t\tLOG_ERROR(\"ftdi_write_data: %s\",\n\t\t\t  ftdi_get_error_string(ftdic));\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\t*bytes_written = retval;\n\treturn ERROR_OK;\n}\n\nstatic int ublast_ftdi_init(struct ublast_lowlevel *low)\n{\n\tuint8_t latency_timer;\n\tstruct ftdi_context *ftdic = ublast_getftdic(low);\n\n\tLOG_INFO(\"usb blaster interface using libftdi\");\n\tif (ftdi_init(ftdic) < 0)\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\n\t/* context, vendor id, product id */\n\tif (ftdi_usb_open(ftdic, low->ublast_vid, low->ublast_pid) < 0)\t{\n\t\tLOG_ERROR(\"unable to open ftdi device: %s\", ftdic->error_str);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_usb_reset(ftdic) < 0) {\n\t\tLOG_ERROR(\"unable to reset ftdi device\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_set_latency_timer(ftdic, 2) < 0) {\n\t\tLOG_ERROR(\"unable to set latency timer\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tif (ftdi_get_latency_timer(ftdic, &latency_timer) < 0)\n\t\tLOG_ERROR(\"unable to get latency timer\");\n\telse\n\t\tLOG_DEBUG(\"current latency timer: %u\", latency_timer);\n\n\tftdi_disable_bitbang(ftdic);\n\treturn ERROR_OK;\n}\n\nstatic int ublast_ftdi_quit(struct ublast_lowlevel *low)\n{\n\tstruct ftdi_context *ftdic = ublast_getftdic(low);\n\n\tftdi_usb_close(ftdic);\n\tftdi_deinit(ftdic);\n\treturn ERROR_OK;\n};\n\nstatic struct ublast_lowlevel_priv {\n\tstruct ftdi_context ftdic;\n} info;\n\nstatic struct ublast_lowlevel low = {\n\t.open = ublast_ftdi_init,\n\t.close = ublast_ftdi_quit,\n\t.read = ublast_ftdi_read,\n\t.write = ublast_ftdi_write,\n\t.priv = &info,\n};\n\nstruct ublast_lowlevel *ublast_register_ftdi(void)\n{\n\treturn &low;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usb_blaster/usb_blaster.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n *   Driver for USB-JTAG, Altera USB-Blaster and compatibles\n *\n *   Inspired from original code from Kolja Waschk's USB-JTAG project\n *   (http://www.ixo.de/info/usb_jtag/), and from openocd project.\n *\n *   Copyright (C) 2013 Franck Jullien franck.jullien@gmail.com\n *   Copyright (C) 2012 Robert Jarzmik robert.jarzmik@free.fr\n *   Copyright (C) 2011 Ali Lown ali@lown.me.uk\n *   Copyright (C) 2009 Catalin Patulea cat@vv.carleton.ca\n *   Copyright (C) 2006 Kolja Waschk usbjtag@ixo.de\n *\n */\n\n/*\n * The following information is originally from Kolja Waschk's USB-JTAG,\n * where it was obtained by reverse engineering an Altera USB-Blaster.\n * See http://www.ixo.de/info/usb_jtag/ for USB-Blaster block diagram and\n * usb_jtag-20080705-1200.zip#usb_jtag/host/openocd for protocol.\n *\n * The same information is also on the UrJTAG mediawiki, with some additional\n * notes on bits marked as \"unknown\" by usb_jtag.\n * (http://sourceforge.net/apps/mediawiki/urjtag/index.php?\n *    title=Cable_Altera_USB-Blaster)\n *\n * USB-JTAG, Altera USB-Blaster and compatibles are typically implemented as\n * an FTDIChip FT245 followed by a CPLD which handles a two-mode protocol:\n *\n *            _________\n *           |         |\n *           | AT93C46 |\n *           |_________|\n *            __|__________    _________\n *           |             |  |         |\n *      USB__| FTDI 245BM  |__| EPM7064 |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK)\n *           |_____________|  |_________|\n *            __|__________    _|___________\n *           |             |  |             |\n *           | 6 MHz XTAL  |  | 24 MHz Osc. |\n *           |_____________|  |_____________|\n *\n * USB-JTAG, Altera USB-Blaster II are typically implemented as a Cypress\n * EZ-USB FX2LP followed by a CPLD.\n *            _____________    _________\n *           |             |  |         |\n *      USB__| EZ-USB FX2  |__| EPM570  |__JTAG (B_TDO,B_TDI,B_TMS,B_TCK)\n *           |_____________|  |_________|\n *            __|__________\n *           |             |\n *           | 24 MHz XTAL |\n *           |_____________|\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#if IS_CYGWIN == 1\n#include \"windows.h\"\n#undef LOG_ERROR\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <helper/time_support.h>\n#include <helper/replacements.h>\n#include \"ublast_access.h\"\n\n/* system includes */\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <sys/time.h>\n#include <time.h>\n\n/* Size of USB endpoint max packet size, ie. 64 bytes */\n#define MAX_PACKET_SIZE 64\n/*\n * Size of data buffer that holds bytes in byte-shift mode.\n * This buffer can hold multiple USB packets aligned to\n * MAX_PACKET_SIZE bytes boundaries.\n * BUF_LEN must be grater than or equal MAX_PACKET_SIZE.\n */\n#define BUF_LEN 4096\n\n/* USB-Blaster II specific command */\n#define CMD_COPY_TDO_BUFFER\t0x5F\n\nenum gpio_steer {\n\tFIXED_0 = 0,\n\tFIXED_1,\n\tSRST,\n\tTRST,\n};\n\nstruct ublast_info {\n\tenum gpio_steer pin6;\n\tenum gpio_steer pin8;\n\tint tms;\n\tint tdi;\n\tbool trst_asserted;\n\tbool srst_asserted;\n\tuint8_t buf[BUF_LEN];\n\tint bufidx;\n\n\tchar *lowlevel_name;\n\tstruct ublast_lowlevel *drv;\n\tuint16_t ublast_vid, ublast_pid;\n\tuint16_t ublast_vid_uninit, ublast_pid_uninit;\n\tint flags;\n\tchar *firmware_path;\n};\n\n/*\n * Global device control\n */\nstatic struct ublast_info info = {\n\t.ublast_vid = 0x09fb, /* Altera */\n\t.ublast_pid = 0x6001, /* USB-Blaster */\n\t.lowlevel_name = NULL,\n\t.srst_asserted = false,\n\t.trst_asserted = false,\n\t.pin6 = FIXED_1,\n\t.pin8 = FIXED_1,\n};\n\n/*\n * Available lowlevel drivers (FTDI, libusb, ...)\n */\nstruct drvs_map {\n\tchar *name;\n\tstruct ublast_lowlevel *(*drv_register)(void);\n};\n\nstatic struct drvs_map lowlevel_drivers_map[] = {\n#if BUILD_USB_BLASTER\n\t{ .name = \"ftdi\", .drv_register = ublast_register_ftdi },\n#endif\n#if BUILD_USB_BLASTER_2\n\t{ .name = \"ublast2\", .drv_register = ublast2_register_libusb },\n#endif\n\t{ NULL, NULL },\n};\n\n/*\n * Access functions to lowlevel driver, agnostic of libftdi/libftdxx\n */\nstatic char *hexdump(uint8_t *buf, unsigned int size)\n{\n\tunsigned int i;\n\tchar *str = calloc(size * 2 + 1, 1);\n\n\tfor (i = 0; i < size; i++)\n\t\tsprintf(str + 2*i, \"%02x\", buf[i]);\n\treturn str;\n}\n\nstatic int ublast_buf_read(uint8_t *buf, unsigned size, uint32_t *bytes_read)\n{\n\tint ret = info.drv->read(info.drv, buf, size, bytes_read);\n\tchar *str = hexdump(buf, *bytes_read);\n\n\tLOG_DEBUG_IO(\"(size=%d, buf=[%s]) -> %\" PRIu32, size, str,\n\t\t      *bytes_read);\n\tfree(str);\n\treturn ret;\n}\n\nstatic int ublast_buf_write(uint8_t *buf, int size, uint32_t *bytes_written)\n{\n\tint ret = info.drv->write(info.drv, buf, size, bytes_written);\n\tchar *str = hexdump(buf, *bytes_written);\n\n\tLOG_DEBUG_IO(\"(size=%d, buf=[%s]) -> %\" PRIu32, size, str,\n\t\t      *bytes_written);\n\tfree(str);\n\treturn ret;\n}\n\nstatic int nb_buf_remaining(void)\n{\n\treturn BUF_LEN - info.bufidx;\n}\n\nstatic void ublast_flush_buffer(void)\n{\n\tuint32_t retlen;\n\tint nb = info.bufidx, ret = ERROR_OK;\n\n\twhile (ret == ERROR_OK && nb > 0) {\n\t\tret = ublast_buf_write(info.buf, nb, &retlen);\n\t\tnb -= retlen;\n\t}\n\tinfo.bufidx = 0;\n}\n\n/*\n * Actually, the USB-Blaster offers a byte-shift mode to transmit up to 504 data\n * bits (bidirectional) in a single USB packet. A header byte has to be sent as\n * the first byte in a packet with the following meaning:\n *\n *   Bit 7 (0x80): Must be set to indicate byte-shift mode.\n *   Bit 6 (0x40): If set, the USB-Blaster will also read data, not just write.\n *   Bit 5..0:     Define the number N of following bytes\n *\n * All N following bytes will then be clocked out serially on TDI. If Bit 6 was\n * set, it will afterwards return N bytes with TDO data read while clocking out\n * the TDI data. LSB of the first byte after the header byte will appear first\n * on TDI.\n */\n\n/* Simple bit banging mode:\n *\n *   Bit 7 (0x80): Must be zero (see byte-shift mode above)\n *   Bit 6 (0x40): If set, you will receive a byte indicating the state of TDO\n *                 in return.\n *   Bit 5 (0x20): Output Enable/LED.\n *   Bit 4 (0x10): TDI Output.\n *   Bit 3 (0x08): nCS Output (not used in JTAG mode).\n *   Bit 2 (0x04): nCE Output (not used in JTAG mode).\n *   Bit 1 (0x02): TMS Output.\n *   Bit 0 (0x01): TCK Output.\n *\n * For transmitting a single data bit, you need to write two bytes (one for\n * setting up TDI/TMS/TCK=0, and one to trigger TCK high with same TDI/TMS\n * held). Up to 64 bytes can be combined in a single USB packet.\n * It isn't possible to read a data without transmitting data.\n */\n\n#define TCK\t\t(1 << 0)\n#define TMS\t\t(1 << 1)\n#define NCE\t\t(1 << 2)\n#define NCS\t\t(1 << 3)\n#define TDI\t\t(1 << 4)\n#define LED\t\t(1 << 5)\n#define READ\t\t(1 << 6)\n#define SHMODE\t\t(1 << 7)\n#define READ_TDO\t(1 << 0)\n\n/**\n * ublast_queue_byte - queue one 'bitbang mode' byte for USB Blaster\n * @param abyte the byte to queue\n *\n * Queues one byte in 'bitbang mode' to the USB Blaster. The byte is not\n * actually sent, but stored in a buffer. The write is performed once\n * the buffer is filled, or if an explicit ublast_flush_buffer() is called.\n */\nstatic void ublast_queue_byte(uint8_t abyte)\n{\n\tif (nb_buf_remaining() < 1)\n\t\tublast_flush_buffer();\n\tinfo.buf[info.bufidx++] = abyte;\n\tif (nb_buf_remaining() == 0)\n\t\tublast_flush_buffer();\n\tLOG_DEBUG_IO(\"(byte=0x%02x)\", abyte);\n}\n\n/**\n * ublast_compute_pin - compute if gpio should be asserted\n * @param steer control (ie. TRST driven, SRST driven, of fixed)\n *\n * Returns pin value (1 means driven high, 0 mean driven low)\n */\nstatic bool ublast_compute_pin(enum gpio_steer steer)\n{\n\tswitch (steer) {\n\tcase FIXED_0:\n\t\treturn 0;\n\tcase FIXED_1:\n\t\treturn 1;\n\tcase SRST:\n\t\treturn !info.srst_asserted;\n\tcase TRST:\n\t\treturn !info.trst_asserted;\n\tdefault:\n\t\treturn 1;\n\t}\n}\n\n/**\n * ublast_build_out - build bitbang mode output byte\n * @param type says if reading back TDO is required\n *\n * Returns the compute bitbang mode byte\n */\nstatic uint8_t ublast_build_out(enum scan_type type)\n{\n\tuint8_t abyte = 0;\n\n\tabyte |= info.tms ? TMS : 0;\n\tabyte |= ublast_compute_pin(info.pin6) ? NCE : 0;\n\tabyte |= ublast_compute_pin(info.pin8) ? NCS : 0;\n\tabyte |= info.tdi ? TDI : 0;\n\tabyte |= LED;\n\tif (type == SCAN_IN || type == SCAN_IO)\n\t\tabyte |= READ;\n\treturn abyte;\n}\n\n/**\n * ublast_reset - reset the JTAG device is possible\n * @param trst 1 if TRST is to be asserted\n * @param srst 1 if SRST is to be asserted\n */\nstatic void ublast_reset(int trst, int srst)\n{\n\tuint8_t out_value;\n\n\tinfo.trst_asserted = trst;\n\tinfo.srst_asserted = srst;\n\tout_value = ublast_build_out(SCAN_OUT);\n\tublast_queue_byte(out_value);\n\tublast_flush_buffer();\n}\n\n/**\n * ublast_clock_tms - clock a TMS transition\n * @param tms the TMS to be sent\n *\n * Triggers a TMS transition (ie. one JTAG TAP state move).\n */\nstatic void ublast_clock_tms(int tms)\n{\n\tuint8_t out;\n\n\tLOG_DEBUG_IO(\"(tms=%d)\", !!tms);\n\tinfo.tms = !!tms;\n\tinfo.tdi = 0;\n\tout = ublast_build_out(SCAN_OUT);\n\tublast_queue_byte(out);\n\tublast_queue_byte(out | TCK);\n}\n\n/**\n * ublast_idle_clock - put back TCK to low level\n *\n * See ublast_queue_tdi() comment for the usage of this function.\n */\nstatic void ublast_idle_clock(void)\n{\n\tuint8_t out = ublast_build_out(SCAN_OUT);\n\n\tLOG_DEBUG_IO(\".\");\n\tublast_queue_byte(out);\n}\n\n/**\n * ublast_clock_tdi - Output a TDI with bitbang mode\n * @param tdi the TDI bit to be shifted out\n * @param type scan type (ie. does a readback of TDO is required)\n *\n * Output a TDI bit and assert clock to push it into the JTAG device :\n *  - writing out TCK=0, TMS=\\<old_state>=0, TDI=\\<tdi>\n *  - writing out TCK=1, TMS=\\<new_state>, TDI=\\<tdi> which triggers the JTAG\n *    device acquiring the data.\n *\n * If a TDO is to be read back, the required read is requested (bitbang mode),\n * and the USB Blaster will send back a byte with bit0 representing the TDO.\n */\nstatic void ublast_clock_tdi(int tdi, enum scan_type type)\n{\n\tuint8_t out;\n\n\tLOG_DEBUG_IO(\"(tdi=%d)\",  !!tdi);\n\tinfo.tdi = !!tdi;\n\n\tout = ublast_build_out(SCAN_OUT);\n\tublast_queue_byte(out);\n\n\tout = ublast_build_out(type);\n\tublast_queue_byte(out | TCK);\n}\n\n/**\n * ublast_clock_tdi_flip_tms - Output a TDI with bitbang mode, change JTAG state\n * @param tdi the TDI bit to be shifted out\n * @param type scan type (ie. does a readback of TDO is required)\n *\n * This function is the same as ublast_clock_tdi(), but it changes also the TMS\n * while output the TDI. This should be the last TDI output of a TDI\n * sequence, which will change state from :\n *   - IRSHIFT -> IREXIT1\n *   - or DRSHIFT -> DREXIT1\n */\nstatic void ublast_clock_tdi_flip_tms(int tdi, enum scan_type type)\n{\n\tuint8_t out;\n\n\tLOG_DEBUG_IO(\"(tdi=%d)\", !!tdi);\n\tinfo.tdi = !!tdi;\n\tinfo.tms = !info.tms;\n\n\tout = ublast_build_out(SCAN_OUT);\n\tublast_queue_byte(out);\n\n\tout = ublast_build_out(type);\n\tublast_queue_byte(out | TCK);\n\n\tout = ublast_build_out(SCAN_OUT);\n\tublast_queue_byte(out);\n}\n\n/**\n * ublast_queue_bytes - queue bytes for the USB Blaster\n * @param bytes byte array\n * @param nb_bytes number of bytes\n *\n * Queues bytes to be sent to the USB Blaster. The bytes are not\n * actually sent, but stored in a buffer. The write is performed once\n * the buffer is filled, or if an explicit ublast_flush_buffer() is called.\n */\nstatic void ublast_queue_bytes(uint8_t *bytes, int nb_bytes)\n{\n\tif (info.bufidx + nb_bytes > BUF_LEN) {\n\t\tLOG_ERROR(\"buggy code, should never queue more that %d bytes\",\n\t\t\t  info.bufidx + nb_bytes);\n\t\texit(-1);\n\t}\n\tLOG_DEBUG_IO(\"(nb_bytes=%d, bytes=[0x%02x, ...])\", nb_bytes,\n\t\t      bytes ? bytes[0] : 0);\n\tif (bytes)\n\t\tmemcpy(&info.buf[info.bufidx], bytes, nb_bytes);\n\telse\n\t\tmemset(&info.buf[info.bufidx], 0, nb_bytes);\n\tinfo.bufidx += nb_bytes;\n\tif (nb_buf_remaining() == 0)\n\t\tublast_flush_buffer();\n}\n\n/**\n * ublast_tms_seq - write a TMS sequence transition to JTAG\n * @param bits TMS bits to be written (bit0, bit1 .. bitN)\n * @param nb_bits number of TMS bits (between 1 and 8)\n * @param skip number of TMS bits to skip at the beginning of the series\n *\n * Write a series of TMS transitions, where each transition consists in :\n *  - writing out TCK=0, TMS=\\<new_state>, TDI=\\<???>\n *  - writing out TCK=1, TMS=\\<new_state>, TDI=\\<???> which triggers the transition\n * The function ensures that at the end of the sequence, the clock (TCK) is put\n * low.\n */\nstatic void ublast_tms_seq(const uint8_t *bits, int nb_bits, int skip)\n{\n\tint i;\n\n\tLOG_DEBUG_IO(\"(bits=%02x..., nb_bits=%d)\", bits[0], nb_bits);\n\tfor (i = skip; i < nb_bits; i++)\n\t\tublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01);\n\tublast_idle_clock();\n}\n\n/**\n * ublast_tms - write a tms command\n * @param cmd tms command\n */\nstatic void ublast_tms(struct tms_command *cmd)\n{\n\tLOG_DEBUG_IO(\"(num_bits=%d)\", cmd->num_bits);\n\tublast_tms_seq(cmd->bits, cmd->num_bits, 0);\n}\n\n/**\n * ublast_path_move - write a TMS sequence transition to JTAG\n * @param cmd path transition\n *\n * Write a series of TMS transitions, where each transition consists in :\n *  - writing out TCK=0, TMS=\\<new_state>, TDI=\\<???>\n *  - writing out TCK=1, TMS=\\<new_state>, TDI=\\<???> which triggers the transition\n * The function ensures that at the end of the sequence, the clock (TCK) is put\n * low.\n */\nstatic void ublast_path_move(struct pathmove_command *cmd)\n{\n\tint i;\n\n\tLOG_DEBUG_IO(\"(num_states=%d, last_state=%d)\",\n\t\t  cmd->num_states, cmd->path[cmd->num_states - 1]);\n\tfor (i = 0; i < cmd->num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[i])\n\t\t\tublast_clock_tms(0);\n\t\tif (tap_state_transition(tap_get_state(), true) == cmd->path[i])\n\t\t\tublast_clock_tms(1);\n\t\ttap_set_state(cmd->path[i]);\n\t}\n\tublast_idle_clock();\n}\n\n/**\n * ublast_state_move - move JTAG state to the target state\n * @param state the target state\n * @param skip number of bits to skip at the beginning of the path\n *\n * Input the correct TMS sequence to the JTAG TAP so that we end up in the\n * target state. This assumes the current state (tap_get_state()) is correct.\n */\nstatic void ublast_state_move(tap_state_t state, int skip)\n{\n\tuint8_t tms_scan;\n\tint tms_len;\n\n\tLOG_DEBUG_IO(\"(from %s to %s)\", tap_state_name(tap_get_state()),\n\t\t  tap_state_name(state));\n\tif (tap_get_state() == state)\n\t\treturn;\n\ttms_scan = tap_get_tms_path(tap_get_state(), state);\n\ttms_len = tap_get_tms_path_len(tap_get_state(), state);\n\tublast_tms_seq(&tms_scan, tms_len, skip);\n\ttap_set_state(state);\n}\n\n/**\n * ublast_read_byteshifted_tdos - read TDO of byteshift writes\n * @param buf the buffer to store the bits\n * @param nb_bytes the number of bytes\n *\n * Reads back from USB Blaster TDO bits, triggered by a 'byteshift write', ie. eight\n * bits per received byte from USB interface, and store them in buffer.\n *\n * As the USB blaster stores the TDO bits in LSB (ie. first bit in (byte0,\n * bit0), second bit in (byte0, bit1), ...), which is what we want to return,\n * simply read bytes from USB interface and store them.\n *\n * Returns ERROR_OK if OK, ERROR_xxx if a read error occurred\n */\nstatic int ublast_read_byteshifted_tdos(uint8_t *buf, int nb_bytes)\n{\n\tuint32_t retlen;\n\tint ret = ERROR_OK;\n\n\tLOG_DEBUG_IO(\"%s(buf=%p, num_bits=%d)\", __func__, buf, nb_bytes * 8);\n\tublast_flush_buffer();\n\twhile (ret == ERROR_OK && nb_bytes > 0) {\n\t\tret = ublast_buf_read(buf, nb_bytes, &retlen);\n\t\tnb_bytes -= retlen;\n\t}\n\treturn ret;\n}\n\n/**\n * ublast_read_bitbang_tdos - read TDO of bitbang writes\n * @param buf the buffer to store the bits\n * @param nb_bits the number of bits\n *\n * Reads back from USB Blaster TDO bits, triggered by a 'bitbang write', ie. one\n * bit per received byte from USB interface, and store them in buffer, where :\n *  - first bit is stored in byte0, bit0 (LSB)\n *  - second bit is stored in byte0, bit 1\n *  ...\n *  - eight bit is stored in byte0, bit 7\n *  - ninth bit is stored in byte1, bit 0\n *  - etc ...\n *\n * Returns ERROR_OK if OK, ERROR_xxx if a read error occurred\n */\nstatic int ublast_read_bitbang_tdos(uint8_t *buf, int nb_bits)\n{\n\tint nb1 = nb_bits;\n\tint i, ret = ERROR_OK;\n\tuint32_t retlen;\n\tuint8_t tmp[8];\n\n\tLOG_DEBUG_IO(\"%s(buf=%p, num_bits=%d)\", __func__, buf, nb_bits);\n\n\t/*\n\t * Ensure all previous bitbang writes were issued to the dongle, so that\n\t * it returns back the read values.\n\t */\n\tublast_flush_buffer();\n\n\tret = ublast_buf_read(tmp, nb1, &retlen);\n\tfor (i = 0; ret == ERROR_OK && i < nb1; i++)\n\t\tif (tmp[i] & READ_TDO)\n\t\t\t*buf |= (1 << i);\n\t\telse\n\t\t\t*buf &= ~(1 << i);\n\treturn ret;\n}\n\n/**\n * ublast_queue_tdi - short description\n * @param bits bits to be queued on TDI (or NULL if 0 are to be queued)\n * @param nb_bits number of bits\n * @param scan scan type (ie. if TDO read back is required or not)\n *\n * Outputs a series of TDI bits on TDI.\n * As a side effect, the last TDI bit is sent along a TMS=1, and triggers a JTAG\n * TAP state shift if input bits were non NULL.\n *\n * In order to not saturate the USB Blaster queues, this method reads back TDO\n * if the scan type requests it, and stores them back in bits.\n *\n * As a side note, the state of TCK when entering this function *must* be\n * low. This is because byteshift mode outputs TDI on rising TCK and reads TDO\n * on falling TCK if and only if TCK is low before queuing byteshift mode bytes.\n * If TCK was high, the USB blaster will queue TDI on falling edge, and read TDO\n * on rising edge !!!\n */\nstatic void ublast_queue_tdi(uint8_t *bits, int nb_bits, enum scan_type scan)\n{\n\tint nb8 = nb_bits / 8;\n\tint nb1 = nb_bits % 8;\n\tint nbfree_in_packet, i, trans = 0, read_tdos;\n\tuint8_t *tdos = calloc(1, nb_bits / 8 + 1);\n\tstatic uint8_t byte0[BUF_LEN];\n\n\t/*\n\t * As the last TDI bit should always be output in bitbang mode in order\n\t * to activate the TMS=1 transition to EXIT_?R state. Therefore a\n\t * situation where nb_bits is a multiple of 8 is handled as follows:\n\t * - the number of TDI shifted out in \"byteshift mode\" is 8 less than\n\t *   nb_bits\n\t * - nb1 = 8\n\t * This ensures that nb1 is never 0, and allows the TMS transition.\n\t */\n\tif (nb8 > 0 && nb1 == 0) {\n\t\tnb8--;\n\t\tnb1 = 8;\n\t}\n\n\tread_tdos = (scan == SCAN_IN || scan == SCAN_IO);\n\tfor (i = 0; i < nb8; i += trans) {\n\t\t/*\n\t\t * Calculate number of bytes to fill USB packet of size MAX_PACKET_SIZE\n\t\t */\n\t\tnbfree_in_packet = (MAX_PACKET_SIZE - (info.bufidx%MAX_PACKET_SIZE));\n\t\ttrans = MIN(nbfree_in_packet - 1, nb8 - i);\n\n\t\t/*\n\t\t * Queue a byte-shift mode transmission, with as many bytes as\n\t\t * is possible with regard to :\n\t\t *  - current filling level of write buffer\n\t\t *  - remaining bytes to write in byte-shift mode\n\t\t */\n\t\tif (read_tdos)\n\t\t\tublast_queue_byte(SHMODE | READ | trans);\n\t\telse\n\t\t\tublast_queue_byte(SHMODE | trans);\n\t\tif (bits)\n\t\t\tublast_queue_bytes(&bits[i], trans);\n\t\telse\n\t\t\tublast_queue_bytes(byte0, trans);\n\t\tif (read_tdos) {\n\t\t\tif (info.flags & COPY_TDO_BUFFER)\n\t\t\t\tublast_queue_byte(CMD_COPY_TDO_BUFFER);\n\t\t\tublast_read_byteshifted_tdos(&tdos[i], trans);\n\t\t}\n\t}\n\n\t/*\n\t * Queue the remaining TDI bits in bitbang mode.\n\t */\n\tfor (i = 0; i < nb1; i++) {\n\t\tint tdi = bits ? bits[nb8 + i / 8] & (1 << i) : 0;\n\t\tif (bits && i == nb1 - 1)\n\t\t\tublast_clock_tdi_flip_tms(tdi, scan);\n\t\telse\n\t\t\tublast_clock_tdi(tdi, scan);\n\t}\n\tif (nb1 && read_tdos) {\n\t\tif (info.flags & COPY_TDO_BUFFER)\n\t\t\tublast_queue_byte(CMD_COPY_TDO_BUFFER);\n\t\tublast_read_bitbang_tdos(&tdos[nb8], nb1);\n\t}\n\n\tif (bits)\n\t\tmemcpy(bits, tdos, DIV_ROUND_UP(nb_bits, 8));\n\tfree(tdos);\n\n\t/*\n\t * Ensure clock is in lower state\n\t */\n\tublast_idle_clock();\n}\n\nstatic void ublast_runtest(int cycles, tap_state_t state)\n{\n\tLOG_DEBUG_IO(\"%s(cycles=%i, end_state=%d)\", __func__, cycles, state);\n\n\tublast_state_move(TAP_IDLE, 0);\n\tublast_queue_tdi(NULL, cycles, SCAN_OUT);\n\tublast_state_move(state, 0);\n}\n\nstatic void ublast_stableclocks(int cycles)\n{\n\tLOG_DEBUG_IO(\"%s(cycles=%i)\", __func__, cycles);\n\tublast_queue_tdi(NULL, cycles, SCAN_OUT);\n}\n\n/**\n * ublast_scan - launches a DR-scan or IR-scan\n * @param cmd the command to launch\n *\n * Launch a JTAG IR-scan or DR-scan\n *\n * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.\n */\nstatic int ublast_scan(struct scan_command *cmd)\n{\n\tint scan_bits;\n\tuint8_t *buf = NULL;\n\tenum scan_type type;\n\tint ret = ERROR_OK;\n\tstatic const char * const type2str[] = { \"\", \"SCAN_IN\", \"SCAN_OUT\", \"SCAN_IO\" };\n\tchar *log_buf = NULL;\n\n\ttype = jtag_scan_type(cmd);\n\tscan_bits = jtag_build_buffer(cmd, &buf);\n\n\tif (cmd->ir_scan)\n\t\tublast_state_move(TAP_IRSHIFT, 0);\n\telse\n\t\tublast_state_move(TAP_DRSHIFT, 0);\n\n\tlog_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8));\n\tLOG_DEBUG_IO(\"%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)\", __func__,\n\t\t  cmd->ir_scan ? \"IRSCAN\" : \"DRSCAN\",\n\t\t  type2str[type],\n\t\t  scan_bits, log_buf, cmd->end_state);\n\tfree(log_buf);\n\n\tublast_queue_tdi(buf, scan_bits, type);\n\n\tret = jtag_read_buffer(buf, cmd);\n\tfree(buf);\n\t/*\n\t * ublast_queue_tdi sends the last bit with TMS=1. We are therefore\n\t * already in Exit1-DR/IR and have to skip the first step on our way\n\t * to end_state.\n\t */\n\tublast_state_move(cmd->end_state, 1);\n\treturn ret;\n}\n\nstatic void ublast_usleep(int us)\n{\n\tLOG_DEBUG_IO(\"%s(us=%d)\",  __func__, us);\n\tjtag_sleep(us);\n}\n\nstatic void ublast_initial_wipeout(void)\n{\n\tstatic uint8_t tms_reset = 0xff;\n\tuint8_t out_value;\n\tuint32_t retlen;\n\tint i;\n\n\tout_value = ublast_build_out(SCAN_OUT);\n\tfor (i = 0; i < BUF_LEN; i++)\n\t\tinfo.buf[i] = out_value | ((i % 2) ? TCK : 0);\n\n\t/*\n\t * Flush USB-Blaster queue fifos\n\t *  - empty the write FIFO (128 bytes)\n\t *  - empty the read FIFO (384 bytes)\n\t */\n\tublast_buf_write(info.buf, BUF_LEN, &retlen);\n\t/*\n\t * Put JTAG in RESET state (five 1 on TMS)\n\t */\n\tublast_tms_seq(&tms_reset, 5, 0);\n\ttap_set_state(TAP_RESET);\n}\n\nstatic int ublast_execute_queue(void)\n{\n\tstruct jtag_command *cmd;\n\tstatic int first_call = 1;\n\tint ret = ERROR_OK;\n\n\tif (first_call) {\n\t\tfirst_call--;\n\t\tublast_initial_wipeout();\n\t}\n\n\tfor (cmd = jtag_command_queue; ret == ERROR_OK && cmd;\n\t     cmd = cmd->next) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RESET:\n\t\t\tublast_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tublast_runtest(cmd->cmd.runtest->num_cycles,\n\t\t\t\t       cmd->cmd.runtest->end_state);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\tublast_stableclocks(cmd->cmd.stableclocks->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tublast_state_move(cmd->cmd.statemove->end_state, 0);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tublast_path_move(cmd->cmd.pathmove);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\tublast_tms(cmd->cmd.tms);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tublast_usleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tret = ublast_scan(cmd->cmd.scan);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%X\",\n\t\t\t\t  cmd->type);\n\t\t\tret = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tublast_flush_buffer();\n\treturn ret;\n}\n\n/**\n * ublast_init - Initialize the Altera device\n *\n * Initialize the device :\n *  - open the USB device\n *  - pretend it's initialized while actual init is delayed until first jtag command\n *\n * Returns ERROR_OK if USB device found, error if not.\n */\nstatic int ublast_init(void)\n{\n\tint ret, i;\n\n\tfor (i = 0; lowlevel_drivers_map[i].name; i++) {\n\t\tif (info.lowlevel_name) {\n\t\t\tif (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name)) {\n\t\t\t\tinfo.drv = lowlevel_drivers_map[i].drv_register();\n\t\t\t\tif (!info.drv) {\n\t\t\t\t\tLOG_ERROR(\"Error registering lowlevel driver \\\"%s\\\"\",\n\t\t\t\t\t\t  info.lowlevel_name);\n\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tinfo.drv = lowlevel_drivers_map[i].drv_register();\n\t\t\tif (info.drv) {\n\t\t\t\tinfo.lowlevel_name = strdup(lowlevel_drivers_map[i].name);\n\t\t\t\tLOG_INFO(\"No lowlevel driver configured, using %s\", info.lowlevel_name);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!info.drv) {\n\t\tLOG_ERROR(\"No lowlevel driver available\");\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t/*\n\t * Register the lowlevel driver\n\t */\n\tinfo.drv->ublast_vid = info.ublast_vid;\n\tinfo.drv->ublast_pid = info.ublast_pid;\n\tinfo.drv->ublast_vid_uninit = info.ublast_vid_uninit;\n\tinfo.drv->ublast_pid_uninit = info.ublast_pid_uninit;\n\tinfo.drv->firmware_path = info.firmware_path;\n\n\tinfo.flags |= info.drv->flags;\n\n\tret = info.drv->open(info.drv);\n\n\t/*\n\t * Let lie here : the TAP is in an unknown state, but the first\n\t * execute_queue() will trigger a ublast_initial_wipeout(), which will\n\t * put the TAP in RESET.\n\t */\n\ttap_set_state(TAP_RESET);\n\treturn ret;\n}\n\n/**\n * ublast_quit - Release the Altera device\n *\n * Releases the device :\n *   - put the device pins in 'high impedance' mode\n *   - close the USB device\n *\n * Returns always ERROR_OK\n */\nstatic int ublast_quit(void)\n{\n\tuint8_t byte0 = 0;\n\tuint32_t retlen;\n\n\tublast_buf_write(&byte0, 1, &retlen);\n\treturn info.drv->close(info.drv);\n}\n\nCOMMAND_HANDLER(ublast_handle_vid_pid_command)\n{\n\tif (CMD_ARGC > 4) {\n\t\tLOG_WARNING(\"ignoring extra IDs in ublast_vid_pid \"\n\t\t\t\t\t\"(maximum is 2 pairs)\");\n\t\tCMD_ARGC = 4;\n\t}\n\n\tif (CMD_ARGC >= 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], info.ublast_vid);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], info.ublast_pid);\n\t} else {\n\t\tLOG_WARNING(\"incomplete ublast_vid_pid configuration\");\n\t}\n\n\tif (CMD_ARGC == 4) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[2], info.ublast_vid_uninit);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[3], info.ublast_pid_uninit);\n\t} else {\n\t\tLOG_WARNING(\"incomplete ublast_vid_pid configuration\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ublast_handle_pin_command)\n{\n\tuint8_t out_value;\n\tconst char * const pin_name = CMD_ARGV[0];\n\tenum gpio_steer *steer = NULL;\n\tstatic const char * const pin_val_str[] = {\n\t\t[FIXED_0] = \"0\",\n\t\t[FIXED_1] = \"1\",\n\t\t[SRST] = \"SRST driven\",\n\t\t[TRST] = \"TRST driven\",\n\t};\n\n\tif (CMD_ARGC > 2) {\n\t\tLOG_ERROR(\"%s takes exactly one or two arguments\", CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (!strcmp(pin_name, \"pin6\"))\n\t\tsteer = &info.pin6;\n\tif (!strcmp(pin_name, \"pin8\"))\n\t\tsteer = &info.pin8;\n\tif (!steer) {\n\t\tLOG_ERROR(\"%s: pin name must be \\\"pin6\\\" or \\\"pin8\\\"\",\n\t\t\t  CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC == 1) {\n\t\tLOG_INFO(\"%s: %s is set as %s\\n\", CMD_NAME, pin_name,\n\t\t\t pin_val_str[*steer]);\n\t}\n\n\tif (CMD_ARGC == 2) {\n\t\tconst char * const pin_value = CMD_ARGV[1];\n\t\tchar val = pin_value[0];\n\n\t\tif (strlen(pin_value) > 1)\n\t\t\tval = '?';\n\t\tswitch (tolower((unsigned char)val)) {\n\t\tcase '0':\n\t\t\t*steer = FIXED_0;\n\t\t\tbreak;\n\t\tcase '1':\n\t\t\t*steer = FIXED_1;\n\t\t\tbreak;\n\t\tcase 't':\n\t\t\t*steer = TRST;\n\t\t\tbreak;\n\t\tcase 's':\n\t\t\t*steer = SRST;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s: pin value must be 0, 1, s (SRST) or t (TRST)\",\n\t\t\t\tpin_value);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (info.drv) {\n\t\t\tout_value = ublast_build_out(SCAN_OUT);\n\t\t\tublast_queue_byte(out_value);\n\t\t\tublast_flush_buffer();\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ublast_handle_lowlevel_drv_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tinfo.lowlevel_name = strdup(CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(ublast_firmware_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tinfo.firmware_path = strdup(CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n}\n\n\nstatic const struct command_registration ublast_subcommand_handlers[] = {\n\t{\n\t\t.name = \"vid_pid\",\n\t\t.handler = ublast_handle_vid_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"the vendor ID and product ID of the USB-Blaster and \"\n\t\t\t\"vendor ID and product ID of the uninitialized device \"\n\t\t\t\"for USB-Blaster II\",\n\t\t.usage = \"vid pid vid_uninit pid_uninit\",\n\t},\n\t{\n\t\t.name = \"lowlevel_driver\",\n\t\t.handler = ublast_handle_lowlevel_drv_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the lowlevel access for the USB Blaster (ftdi, ublast2)\",\n\t\t.usage = \"(ftdi|ublast2)\",\n\t},\n\t{\n\t\t.name = \"pin\",\n\t\t.handler = ublast_handle_pin_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"show or set pin state for the unused GPIO pins\",\n\t\t.usage = \"(pin6|pin8) (0|1|s|t)\",\n\t},\n\t\t{\n\t\t.name = \"firmware\",\n\t\t.handler = &ublast_firmware_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"configure the USB-Blaster II firmware location\",\n\t\t.usage = \"path/to/blaster_xxxx.hex\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration ublast_command_handlers[] = {\n\t{\n\t\t.name = \"usb_blaster\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform usb_blaster management\",\n\t\t.chain = ublast_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface usb_blaster_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = ublast_execute_queue,\n};\n\nstruct adapter_driver usb_blaster_adapter_driver = {\n\t.name = \"usb_blaster\",\n\t.transports = jtag_only,\n\t.commands = ublast_command_handlers,\n\n\t.init = ublast_init,\n\t.quit = ublast_quit,\n\n\t.jtag_ops = &usb_blaster_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/usbprog.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Benedikt Sauter                                 *\n *   sauter@ixbat.de                                                       *\n ***************************************************************************/\n\n/*\n * This file is based on Dominic Rath's amt_jtagaccel.c.\n *\n * usbprog is a free programming adapter. You can easily install\n * different firmware versions from an \"online pool\" over USB.\n * The adapter can be used for programming and debugging AVR and ARM\n * processors, as USB to RS232 converter, as JTAG interface or as\n * simple I/O interface (5 lines).\n *\n * http://www.embedded-projects.net/usbprog\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include \"libusb_helper.h\"\n\n#define VID 0x1781\n#define PID 0x0c63\n\n/* Pins at usbprog */\n#define TDO_BIT                 0\n#define TDI_BIT                 3\n#define TCK_BIT                 2\n#define TMS_BIT                 1\n\nstatic void usbprog_end_state(tap_state_t state);\nstatic void usbprog_state_move(void);\nstatic void usbprog_path_move(struct pathmove_command *cmd);\nstatic void usbprog_runtest(int num_cycles);\nstatic void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size);\n\n#define UNKNOWN_COMMAND 0x00\n#define PORT_DIRECTION  0x01\n#define PORT_SET                0x02\n#define PORT_GET                0x03\n#define PORT_SETBIT             0x04\n#define PORT_GETBIT             0x05\n#define WRITE_TDI               0x06\n#define READ_TDO                0x07\n#define WRITE_AND_READ  0x08\n#define WRITE_TMS               0x09\n#define WRITE_TMS_CHAIN 0x0A\n\nstruct usbprog_jtag {\n\tstruct libusb_device_handle *usb_handle;\n};\n\nstatic struct usbprog_jtag *usbprog_jtag_handle;\n\nstatic struct usbprog_jtag *usbprog_jtag_open(void);\n/* static void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag); */\nstatic void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag);\nstatic unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen);\n\nstatic void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char *buffer, int size);\nstatic void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char *buffer, int size);\nstatic void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char *buffer, int size);\nstatic void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan);\n\nstatic char tms_chain[64];\nstatic int tms_chain_index;\n\nstatic void usbprog_jtag_tms_collect(char tms_scan);\nstatic void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag);\n\nstatic void usbprog_write(int tck, int tms, int tdi);\nstatic void usbprog_reset(int trst, int srst);\n\nstatic void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction);\nstatic void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag, unsigned char value);\n/* static unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag); */\nstatic void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag, int bit, int value);\n/* static int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit); */\n\nstatic int usbprog_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\t/* currently processed command */\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RESET:\n\t\t\tLOG_DEBUG_IO(\"reset trst: %i srst %i\",\n\t\t\t\t\tcmd->cmd.reset->trst,\n\t\t\t\t\tcmd->cmd.reset->srst);\n\t\t\tif (cmd->cmd.reset->trst == 1)\n\t\t\t\ttap_set_state(TAP_RESET);\n\t\t\tusbprog_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %i\",\n\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\tcmd->cmd.runtest->end_state);\n\t\t\tusbprog_end_state(cmd->cmd.runtest->end_state);\n\t\t\tusbprog_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\tLOG_DEBUG_IO(\"statemove end in %i\", cmd->cmd.statemove->end_state);\n\t\t\tusbprog_end_state(cmd->cmd.statemove->end_state);\n\t\t\tusbprog_state_move();\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %i\",\n\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\tcmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\t\t\tusbprog_path_move(cmd->cmd.pathmove);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\tLOG_DEBUG_IO(\"scan end in %i\", cmd->cmd.scan->end_state);\n\t\t\tusbprog_end_state(cmd->cmd.scan->end_state);\n\t\t\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);\n\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\t\t\tusbprog_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);\n\t\t\tif (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)\n\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\tfree(buffer);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type encountered\");\n\t\t\texit(-1);\n\t\t}\n\n\t\tcmd = cmd->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int usbprog_init(void)\n{\n\tusbprog_jtag_handle = usbprog_jtag_open();\n\n\ttms_chain_index = 0;\n\tif (!usbprog_jtag_handle) {\n\t\tLOG_ERROR(\"Can't find USB JTAG Interface! Please check connection and permissions.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_INFO(\"USB JTAG Interface ready!\");\n\n\tusbprog_jtag_init(usbprog_jtag_handle);\n\tusbprog_reset(0, 0);\n\tusbprog_write(0, 0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int usbprog_quit(void)\n{\n\treturn ERROR_OK;\n}\n\n/*************** jtag execute commands **********************/\nstatic void usbprog_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\nstatic void usbprog_state_move(void)\n{\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(), tap_get_end_state());\n\n\tusbprog_jtag_write_tms(usbprog_jtag_handle, (char)tms_scan);\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void usbprog_path_move(struct pathmove_command *cmd)\n{\n\tint num_states = cmd->num_states;\n\tint state_count;\n\n\t/* There may be queued transitions, and before following a specified\n\t   path, we must flush those queued transitions */\n\tusbprog_jtag_tms_send(usbprog_jtag_handle);\n\n\tstate_count = 0;\n\twhile (num_states) {\n\t\tif (tap_state_transition(tap_get_state(), false) == cmd->path[state_count]) {\n\t\t\t/* LOG_INFO(\"1\"); */\n\t\t\tusbprog_write(0, 0, 0);\n\t\t\tusbprog_write(1, 0, 0);\n\t\t} else if (tap_state_transition(tap_get_state(),\n\t\t\t\t   true) == cmd->path[state_count]) {\n\t\t\t/* LOG_INFO(\"2\"); */\n\t\t\tusbprog_write(0, 1, 0);\n\t\t\tusbprog_write(1, 1, 0);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(cmd->path[state_count]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(cmd->path[state_count]);\n\t\tstate_count++;\n\t\tnum_states--;\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void usbprog_runtest(int num_cycles)\n{\n\tint i;\n\n\t/* only do a state_move when we're not already in IDLE */\n\tif (tap_get_state() != TAP_IDLE) {\n\t\tusbprog_end_state(TAP_IDLE);\n\t\tusbprog_state_move();\n\t}\n\n\t/* execute num_cycles */\n\tif (num_cycles > 0) {\n\t\tusbprog_jtag_tms_send(usbprog_jtag_handle);\n\t\tusbprog_write(0, 0, 0);\n\t} else {\n\t\tusbprog_jtag_tms_send(usbprog_jtag_handle);\n\t\t/* LOG_INFO(\"NUM CYCLES %i\",num_cycles); */\n\t}\n\n\tfor (i = 0; i < num_cycles; i++) {\n\t\tusbprog_write(1, 0, 0);\n\t\tusbprog_write(0, 0, 0);\n\t}\n\n\tLOG_DEBUG_IO(\"runtest: cur_state %s end_state %s\", tap_state_name(\n\t\t\ttap_get_state()), tap_state_name(tap_get_end_state()));\n\n\t/* finish in end_state */\n\t/*\n\tusbprog_end_state(saved_end_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\tusbprog_state_move();\n\t*/\n}\n\nstatic void usbprog_scan(bool ir_scan, enum scan_type type, uint8_t *buffer, int scan_size)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\tif (ir_scan)\n\t\tusbprog_end_state(TAP_IRSHIFT);\n\telse\n\t\tusbprog_end_state(TAP_DRSHIFT);\n\n\t/* Only move if we're not already there */\n\tif (tap_get_state() != tap_get_end_state())\n\t\tusbprog_state_move();\n\n\tusbprog_end_state(saved_end_state);\n\n\tusbprog_jtag_tms_send(usbprog_jtag_handle);\n\n\tvoid (*f)(struct usbprog_jtag *usbprog_jtag, char *buffer_local, int size);\n\tswitch (type) {\n\t\tcase SCAN_OUT:\n\t\t\tf = &usbprog_jtag_write_tdi;\n\t\t\tbreak;\n\t\tcase SCAN_IN:\n\t\t\tf = &usbprog_jtag_read_tdo;\n\t\t\tbreak;\n\t\tcase SCAN_IO:\n\t\t\tf = &usbprog_jtag_write_and_read;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unknown scan type: %i\", type);\n\t\t\texit(-1);\n\t}\n\tf(usbprog_jtag_handle, (char *)buffer, scan_size);\n\n\t/* The adapter does the transition to PAUSE internally */\n\tif (ir_scan)\n\t\ttap_set_state(TAP_IRPAUSE);\n\telse\n\t\ttap_set_state(TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tusbprog_state_move();\n}\n\n/*************** jtag wrapper functions *********************/\n\nstatic void usbprog_write(int tck, int tms, int tdi)\n{\n\tunsigned char output_value = 0x00;\n\n\tif (tms)\n\t\toutput_value |= (1 << TMS_BIT);\n\tif (tdi)\n\t\toutput_value |= (1 << TDI_BIT);\n\tif (tck)\n\t\toutput_value |= (1 << TCK_BIT);\n\n\tusbprog_jtag_write_slice(usbprog_jtag_handle, output_value);\n}\n\n/* (1) assert or (0) deassert reset lines */\nstatic void usbprog_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (trst)\n\t\tusbprog_jtag_set_bit(usbprog_jtag_handle, 5, 0);\n\telse\n\t\tusbprog_jtag_set_bit(usbprog_jtag_handle, 5, 1);\n\n\tif (srst)\n\t\tusbprog_jtag_set_bit(usbprog_jtag_handle, 4, 0);\n\telse\n\t\tusbprog_jtag_set_bit(usbprog_jtag_handle, 4, 1);\n}\n\n/*************** jtag lowlevel functions ********************/\n\nstruct usbprog_jtag *usbprog_jtag_open(void)\n{\n\tconst uint16_t vids[] = { VID, 0 };\n\tconst uint16_t pids[] = { PID, 0 };\n\tstruct libusb_device_handle *dev;\n\n\tif (jtag_libusb_open(vids, pids, &dev, NULL) != ERROR_OK)\n\t\treturn NULL;\n\n\tstruct usbprog_jtag *tmp = malloc(sizeof(struct usbprog_jtag));\n\ttmp->usb_handle = dev;\n\n\tlibusb_set_configuration(dev, 1);\n\tlibusb_claim_interface(dev, 0);\n\tlibusb_set_interface_alt_setting(dev, 0, 0);\n\n\treturn tmp;\n}\n\n#if 0\nstatic void usbprog_jtag_close(struct usbprog_jtag *usbprog_jtag)\n{\n\tlibusb_close(usbprog_jtag->usb_handle);\n\tfree(usbprog_jtag);\n}\n#endif\n\nstatic unsigned char usbprog_jtag_message(struct usbprog_jtag *usbprog_jtag, char *msg, int msglen)\n{\n\tint transferred;\n\n\tint res = jtag_libusb_bulk_write(usbprog_jtag->usb_handle, 3, msg, msglen, 100, &transferred);\n\tif ((msg[0] == 2) || (msg[0] == 1) || (msg[0] == 4) || (msg[0] == 0) ||\n\t    (msg[0] == 6) || (msg[0] == 0x0A) || (msg[0] == 9))\n\t\treturn 1;\n\tif (res == ERROR_OK && transferred == msglen) {\n\t\t/* LOG_INFO(\"HALLLLOOO %i\",(int)msg[0]); */\n\t\tres = jtag_libusb_bulk_read(usbprog_jtag->usb_handle, 0x82, msg, 2, 100, &transferred);\n\t\tif (res == ERROR_OK && transferred > 0)\n\t\t\treturn (unsigned char)msg[1];\n\t\telse\n\t\t\treturn -1;\n\t} else\n\t\treturn -1;\n\treturn 0;\n}\n\nstatic void usbprog_jtag_init(struct usbprog_jtag *usbprog_jtag)\n{\n\tusbprog_jtag_set_direction(usbprog_jtag, 0xFE);\n}\n\nstatic void usbprog_jtag_write_and_read(struct usbprog_jtag *usbprog_jtag, char *buffer, int size)\n{\n\tchar tmp[64];\t/* fastest packet size for usb controller */\n\tint send_bits, bufindex = 0, fillindex = 0, i, loops;\n\n\tchar swap;\n\t/* 61 byte can be transferred (488 bit) */\n\n\twhile (size > 0) {\n\t\tif (size > 488) {\n\t\t\tsend_bits = 488;\n\t\t\tsize = size - 488;\n\t\t\tloops = 61;\n\t\t} else {\n\t\t\tsend_bits = size;\n\t\t\tloops = size / 8;\n\t\t\tloops++;\n\t\t\tsize = 0;\n\t\t}\n\t\ttmp[0] = WRITE_AND_READ;\n\t\ttmp[1] = (char)(send_bits >> 8);\t/* high */\n\t\ttmp[2] = (char)(send_bits);\t\t\t/* low */\n\n\t\tfor (i = 0; i < loops; i++) {\n\t\t\ttmp[3 + i] = buffer[bufindex];\n\t\t\tbufindex++;\n\t\t}\n\n\t\tint transferred;\n\t\tint res = jtag_libusb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000, &transferred);\n\t\tif (res == ERROR_OK && transferred == 64) {\n\t\t\t/* LOG_INFO(\"HALLLLOOO2 %i\",(int)tmp[0]); */\n\t\t\tusleep(1);\n\t\t\tint timeout = 0;\n\t\t\twhile (jtag_libusb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 1000, &transferred) != ERROR_OK) {\n\t\t\t\ttimeout++;\n\t\t\t\tif (timeout > 10)\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < loops; i++) {\n\t\t\t\tswap = tmp[3 + i];\n\t\t\t\tbuffer[fillindex++] = swap;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void usbprog_jtag_read_tdo(struct usbprog_jtag *usbprog_jtag, char *buffer, int size)\n{\n\tchar tmp[64];\t/* fastest packet size for usb controller */\n\tint send_bits, fillindex = 0, i, loops;\n\n\tchar swap;\n\t/* 61 byte can be transferred (488 bit) */\n\n\twhile (size > 0) {\n\t\tif (size > 488) {\n\t\t\tsend_bits = 488;\n\t\t\tsize = size - 488;\n\t\t\tloops = 61;\n\t\t} else {\n\t\t\tsend_bits = size;\n\t\t\tloops = size / 8;\n\t\t\tloops++;\n\t\t\tsize = 0;\n\t\t}\n\t\ttmp[0] = WRITE_AND_READ;\n\t\ttmp[1] = (char)(send_bits >> 8);\t/* high */\n\t\ttmp[2] = (char)(send_bits);\t\t\t/* low */\n\n\t\tint transferred;\n\t\tjtag_libusb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 3, 1000, &transferred);\n\n\t\t/* LOG_INFO(\"HALLLLOOO3 %i\",(int)tmp[0]); */\n\t\tint timeout = 0;\n\t\tusleep(1);\n\t\twhile (jtag_libusb_bulk_read(usbprog_jtag->usb_handle, 0x82, tmp, 64, 10, &transferred) != ERROR_OK) {\n\t\t\ttimeout++;\n\t\t\tif (timeout > 10)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tfor (i = 0; i < loops; i++) {\n\t\t\tswap = tmp[3 + i];\n\t\t\tbuffer[fillindex++] = swap;\n\t\t}\n\t}\n}\n\nstatic void usbprog_jtag_write_tdi(struct usbprog_jtag *usbprog_jtag, char *buffer, int size)\n{\n\tchar tmp[64];\t/* fastest packet size for usb controller */\n\tint send_bits, bufindex = 0, i, loops;\n\n\t/* 61 byte can be transferred (488 bit) */\n\twhile (size > 0) {\n\t\tif (size > 488) {\n\t\t\tsend_bits = 488;\n\t\t\tsize = size - 488;\n\t\t\tloops = 61;\n\t\t} else {\n\t\t\tsend_bits = size;\n\t\t\tloops = size/8;\n\t\t\t/* if (loops == 0) */\n\t\t\tloops++;\n\t\t\tsize = 0;\n\t\t}\n\t\ttmp[0] = WRITE_TDI;\n\t\ttmp[1] = (char)(send_bits >> 8);\t/* high */\n\t\ttmp[2] = (char)(send_bits);\t\t\t/* low */\n\n\t\tfor (i = 0; i < loops; i++) {\n\t\t\ttmp[3 + i] = buffer[bufindex];\n\t\t\tbufindex++;\n\t\t}\n\t\tint transferred;\n\t\tjtag_libusb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, 64, 1000, &transferred);\n\t}\n}\n\nstatic void usbprog_jtag_write_tms(struct usbprog_jtag *usbprog_jtag, char tms_scan)\n{\n\tusbprog_jtag_tms_collect(tms_scan);\n}\n\nstatic void usbprog_jtag_set_direction(struct usbprog_jtag *usbprog_jtag, unsigned char direction)\n{\n\tchar tmp[2];\n\ttmp[0] = PORT_DIRECTION;\n\ttmp[1] = (char)direction;\n\tusbprog_jtag_message(usbprog_jtag, tmp, 2);\n}\n\nstatic void usbprog_jtag_write_slice(struct usbprog_jtag *usbprog_jtag, unsigned char value)\n{\n\tchar tmp[2];\n\ttmp[0] = PORT_SET;\n\ttmp[1] = (char)value;\n\tusbprog_jtag_message(usbprog_jtag, tmp, 2);\n}\n\n#if 0\nstatic unsigned char usbprog_jtag_get_port(struct usbprog_jtag *usbprog_jtag)\n{\n\tchar tmp[2];\n\ttmp[0] = PORT_GET;\n\ttmp[1] = 0x00;\n\treturn usbprog_jtag_message(usbprog_jtag, tmp, 2);\n}\n#endif\n\nstatic void usbprog_jtag_set_bit(struct usbprog_jtag *usbprog_jtag, int bit, int value)\n{\n\tchar tmp[3];\n\ttmp[0] = PORT_SETBIT;\n\ttmp[1] = (char)bit;\n\tif (value == 1)\n\t\ttmp[2] = 0x01;\n\telse\n\t\ttmp[2] = 0x00;\n\tusbprog_jtag_message(usbprog_jtag, tmp, 3);\n}\n\n#if 0\nstatic int usbprog_jtag_get_bit(struct usbprog_jtag *usbprog_jtag, int bit)\n{\n\tchar tmp[2];\n\ttmp[0] = PORT_GETBIT;\n\ttmp[1] = (char)bit;\n\n\tif (usbprog_jtag_message(usbprog_jtag, tmp, 2) > 0)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n}\n#endif\n\nstatic void usbprog_jtag_tms_collect(char tms_scan)\n{\n\ttms_chain[tms_chain_index] = tms_scan;\n\ttms_chain_index++;\n}\n\nstatic void usbprog_jtag_tms_send(struct usbprog_jtag *usbprog_jtag)\n{\n\t/* LOG_INFO(\"TMS SEND\"); */\n\tif (tms_chain_index > 0) {\n\t\tchar tmp[tms_chain_index + 2];\n\t\ttmp[0] = WRITE_TMS_CHAIN;\n\t\ttmp[1] = (char)(tms_chain_index);\n\t\tfor (int i = 0; i < tms_chain_index + 1; i++)\n\t\t\ttmp[2 + i] = tms_chain[i];\n\t\tint transferred;\n\t\tjtag_libusb_bulk_write(usbprog_jtag->usb_handle, 3, tmp, tms_chain_index + 2, 1000, &transferred);\n\t\ttms_chain_index = 0;\n\t}\n}\n\nstatic struct jtag_interface usbprog_interface = {\n\t.execute_queue = usbprog_execute_queue,\n};\n\nstruct adapter_driver usbprog_adapter_driver = {\n\t.name = \"usbprog\",\n\t.transports = jtag_only,\n\n\t.init = usbprog_init,\n\t.quit = usbprog_quit,\n\n\t.jtag_ops = &usbprog_interface,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/vdebug.c",
    "content": "// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)\n\n/* Copyright 2020-2022 Cadence Design Systems, Inc. */\n\n/*!\n * @file\n *\n * @brief the virtual debug interface provides a connection between a sw debugger\n * and the simulated, emulated core. The openOCD client connects via TCP sockets\n * with vdebug server and over DPI-based transactor with the emulation or simulation\n * The vdebug debug driver supports JTAG and DAP-level transports\n *\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifdef _WIN32\n#define WIN32_LEAN_AND_MEAN\n#include <windows.h>\n#else\n#ifdef HAVE_UNISTD_H\n#include <unistd.h>          /* close */\n#endif\n#ifdef HAVE_SYS_SOCKET_H\n#include <sys/socket.h>\n#endif\n#ifdef HAVE_ARPA_INET_H\n#include <arpa/inet.h>\n#endif\n#ifdef HAVE_NETDB_H\n#include <netdb.h>\n#endif\n#endif\n#include <stdio.h>\n#ifdef HAVE_STDINT_H\n#include <stdint.h>\n#endif\n#ifdef HAVE_STDLIB_H\n#include <stdlib.h>\n#endif\n#include <stdarg.h>\n#include <string.h>\n#include <errno.h>\n\n#include \"jtag/interface.h\"\n#include \"jtag/commands.h\"\n#include \"transport/transport.h\"\n#include \"target/arm_adi_v5.h\"\n#include \"helper/time_support.h\"\n#include \"helper/replacements.h\"\n#include \"helper/log.h\"\n#include \"helper/list.h\"\n\n#define VD_VERSION 46\n#define VD_BUFFER_LEN 4024\n#define VD_CHEADER_LEN 24\n#define VD_SHEADER_LEN 16\n\n#define VD_MAX_MEMORIES 20\n#define VD_POLL_INTERVAL 500\n#define VD_SCALE_PSTOMS 1000000000\n\n/**\n * @brief List of transactor types\n */\nenum {\n\tVD_BFM_JTDP   = 0x0001,  /* transactor DAP JTAG DP */\n\tVD_BFM_SWDP   = 0x0002,  /* transactor DAP SWD DP */\n\tVD_BFM_AHB    = 0x0003,  /* transactor AMBA AHB */\n\tVD_BFM_APB    = 0x0004,  /* transactor AMBA APB */\n\tVD_BFM_AXI    = 0x0005,  /* transactor AMBA AXI */\n\tVD_BFM_JTAG   = 0x0006,  /* transactor serial JTAG */\n\tVD_BFM_SWD    = 0x0007,  /* transactor serial SWD */\n};\n\n/**\n * @brief List of signals that can be read or written by the debugger\n */\nenum {\n\tVD_SIG_TCK    = 0x0001,  /* JTAG clock; tclk */\n\tVD_SIG_TDI    = 0x0002,  /* JTAG TDI;   tdi */\n\tVD_SIG_TMS    = 0x0004,  /* JTAG TMS;   tms */\n\tVD_SIG_RESET  = 0x0008,  /* DUT reset;  rst */\n\tVD_SIG_TRST   = 0x0010,  /* JTAG Reset; trstn */\n\tVD_SIG_TDO    = 0x0020,  /* JTAG TDO;   tdo */\n\tVD_SIG_POWER  = 0x0100,  /* BFM power;  bfm_up */\n\tVD_SIG_TCKDIV = 0x0200,  /* JTAG clock divider; tclkdiv */\n\tVD_SIG_BUF    = 0x1000,  /* memory buffer; mem */\n};\n\n/**\n * @brief List of errors\n */\nenum {\n\tVD_ERR_NONE       = 0x0000,  /* no error */\n\tVD_ERR_NOT_IMPL   = 0x0100,  /* feature not implemented */\n\tVD_ERR_USAGE      = 0x0101,  /* incorrect usage */\n\tVD_ERR_PARAM      = 0x0102,  /* incorrect parameter */\n\tVD_ERR_CONFIG     = 0x0107,  /* incorrect configuration */\n\tVD_ERR_NO_MEMORY  = 0x0104,  /* out of memory */\n\tVD_ERR_SHM_OPEN   = 0x010a,  /* cannot open shared memory */\n\tVD_ERR_SHM_MAP    = 0x010b,  /* cannot map shared memory */\n\tVD_ERR_SOC_OPEN   = 0x011a,  /* cannot open socket */\n\tVD_ERR_SOC_OPT    = 0x011b,  /* cannot set socket option */\n\tVD_ERR_SOC_ADDR   = 0x011c,  /* cannot resolve host address */\n\tVD_ERR_SOC_CONN   = 0x011d,  /* cannot connect to host */\n\tVD_ERR_SOC_SEND   = 0x011e,  /* error sending data on socket */\n\tVD_ERR_SOC_RECV   = 0x011f,  /* error receiving data from socket */\n\tVD_ERR_LOCKED     = 0x0202,  /* device locked */\n\tVD_ERR_NOT_RUN    = 0x0204,  /* transactor not running */\n\tVD_ERR_NOT_OPEN   = 0x0205,  /* transactor not open/connected */\n\tVD_ERR_LICENSE    = 0x0206,  /* cannot check out the license */\n\tVD_ERR_VERSION    = 0x0207,  /* transactor version mismatch */\n\tVD_ERR_TIME_OUT   = 0x0301,  /* time out, waiting */\n\tVD_ERR_NO_POWER   = 0x0302,  /* power out error */\n\tVD_ERR_BUS_ERROR  = 0x0304,  /* bus protocol error, like pslverr */\n\tVD_ERR_NO_ACCESS  = 0x0306,  /* no access to an object */\n\tVD_ERR_INV_HANDLE = 0x0307,  /* invalid object handle */\n\tVD_ERR_INV_SCOPE  = 0x0308,  /* invalid scope */\n};\n\nenum {\n\tVD_CMD_OPEN       = 0x01,\n\tVD_CMD_CLOSE      = 0x02,\n\tVD_CMD_CONNECT    = 0x04,\n\tVD_CMD_DISCONNECT = 0x05,\n\tVD_CMD_WAIT       = 0x09,\n\tVD_CMD_SIGSET     = 0x0a,\n\tVD_CMD_SIGGET     = 0x0b,\n\tVD_CMD_JTAGCLOCK  = 0x0f,\n\tVD_CMD_REGWRITE   = 0x15,\n\tVD_CMD_REGREAD    = 0x16,\n\tVD_CMD_JTAGSHTAP  = 0x1a,\n\tVD_CMD_MEMOPEN    = 0x21,\n\tVD_CMD_MEMCLOSE   = 0x22,\n\tVD_CMD_MEMWRITE   = 0x23,\n};\n\nenum {\n\tVD_ASPACE_AP      = 0x01,\n\tVD_ASPACE_DP      = 0x02,\n\tVD_ASPACE_ID      = 0x03,\n\tVD_ASPACE_AB      = 0x04,\n};\n\nenum {\n\tVD_BATCH_NO       = 0,\n\tVD_BATCH_WO       = 1,\n\tVD_BATCH_WR       = 2,\n};\n\nstruct vd_shm {\n\tstruct {                     /* VD_CHEADER_LEN written by client */\n\t\tuint8_t cmd;             /* 000; command */\n\t\tuint8_t type;            /* 001; interface type */\n\t\tuint8_t waddr[2];        /* 002; write pointer */\n\t\tuint8_t wbytes[2];       /* 004; data bytes */\n\t\tuint8_t rbytes[2];       /* 006; data bytes to read */\n\t\tuint8_t wwords[2];       /* 008; data words */\n\t\tuint8_t rwords[2];       /* 00a; data words to read */\n\t\tuint8_t rwdata[4];       /* 00c; read/write data */\n\t\tuint8_t offset[4];       /* 010; address offset */\n\t\tuint8_t offseth[2];      /* 014; address offset 47:32 */\n\t\tuint8_t wid[2];          /* 016; request id*/\n\t};\n\tuint8_t wd8[VD_BUFFER_LEN];  /* 018; */\n\tstruct {                     /* VD_SHEADER_LEN written by server */\n\t\tuint8_t rid[2];          /* fd0: request id read */\n\t\tuint8_t awords[2];       /* fd2: actual data words read back */\n\t\tuint8_t status[4];       /* fd4; */\n\t\tuint8_t duttime[8];      /* fd8; */\n\t};\n\tuint8_t rd8[VD_BUFFER_LEN];  /* fe0: */\n\tuint8_t state[4];            /* 1f98; connection state */\n\tuint8_t count[4];            /* 1f9c; */\n\tuint8_t dummy[96];           /* 1fa0; 48+40B+8B; */\n} __attribute__((packed));\n\nstruct vd_rdata {\n\tstruct list_head lh;\n\tuint8_t *rdata;\n};\n\nstruct vd_client {\n\tuint8_t trans_batch;\n\tbool trans_first;\n\tbool trans_last;\n\tuint8_t mem_ndx;\n\tuint8_t buf_width;\n\tuint8_t addr_bits;\n\tuint8_t bfm_type;\n\tuint16_t sig_read;\n\tuint16_t sig_write;\n\tuint32_t bfm_period;\n\tuint32_t mem_base[VD_MAX_MEMORIES];\n\tuint32_t mem_size[VD_MAX_MEMORIES];\n\tuint32_t mem_width[VD_MAX_MEMORIES];\n\tuint32_t mem_depth[VD_MAX_MEMORIES];\n\tuint16_t server_port;\n\tuint32_t poll_cycles;\n\tuint32_t poll_min;\n\tuint32_t poll_max;\n\tuint32_t targ_time;\n\tint hsocket;\n\tchar server_name[32];\n\tchar bfm_path[128];\n\tchar mem_path[VD_MAX_MEMORIES][128];\n\tstruct vd_rdata rdataq;\n};\n\nstruct vd_jtag_hdr {\n\tuint64_t tlen:24;\n\tuint64_t post:3;\n\tuint64_t pre:3;\n\tuint64_t cmd:2;\n\tuint64_t wlen:16;\n\tuint64_t rlen:16;\n};\n\nstruct vd_reg_hdr {\n\tuint64_t prot:3;\n\tuint64_t nonincr:1;\n\tuint64_t haddr:12;\n\tuint64_t tlen:11;\n\tuint64_t asize:3;\n\tuint64_t cmd:2;\n\tuint64_t addr:32;\n};\n\nstatic struct vd_shm *pbuf;\nstatic struct vd_client vdc;\n\nstatic int vdebug_socket_error(void)\n{\n#ifdef _WIN32\n\treturn WSAGetLastError();\n#else\n\treturn errno;\n#endif\n}\n\nstatic int vdebug_socket_open(char *server_addr, uint32_t port)\n{\n\tint hsock;\n\tint rc = 0;\n\tuint32_t buflen = sizeof(struct vd_shm); /* size of the send and rcv buffer */\n\tstruct addrinfo *ainfo = NULL;\n\tstruct addrinfo ahint = { 0, AF_INET, SOCK_STREAM, 0, 0, NULL, NULL, NULL };\n\n#ifdef _WIN32\n\thsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);\n\tif (hsock == INVALID_SOCKET)\n\t\trc = vdebug_socket_error();\n#else\n\tuint32_t rcvwat = VD_SHEADER_LEN;    /* size of the rcv header, as rcv min watermark */\n\thsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);\n\tif (hsock < 0)\n\t\trc = errno;\n\telse if (setsockopt(hsock, SOL_SOCKET, SO_RCVLOWAT, &rcvwat, sizeof(rcvwat)) < 0)\n\t\trc = errno;\n#endif\n\telse if (setsockopt(hsock, SOL_SOCKET, SO_SNDBUF, (const char *)&buflen, sizeof(buflen)) < 0)\n\t\trc = vdebug_socket_error();\n\telse if (setsockopt(hsock, SOL_SOCKET, SO_RCVBUF, (const char *)&buflen, sizeof(buflen)) < 0)\n\t\trc = vdebug_socket_error();\n\n\tif (rc) {\n\t\tLOG_ERROR(\"socket_open: cannot set socket option, error %d\", rc);\n\t} else if (getaddrinfo(server_addr, NULL, &ahint, &ainfo) != 0) {\n\t\tLOG_ERROR(\"socket_open: cannot resolve address %s, error %d\", server_addr, vdebug_socket_error());\n\t\trc = VD_ERR_SOC_ADDR;\n\t} else {\n\t\th_u16_to_be((uint8_t *)ainfo->ai_addr->sa_data, port);\n\t\tif (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) {\n\t\t\tLOG_ERROR(\"socket_open: cannot connect to %s:%d, error %d\", server_addr, port, vdebug_socket_error());\n\t\t\trc = VD_ERR_SOC_CONN;\n\t\t}\n\t}\n\n\tif (rc) {\n\t\tclose_socket(hsock);\n\t\thsock = 0;\n\t}\n\n\tif (ainfo)\n\t\tfreeaddrinfo(ainfo);\n\n\treturn hsock;\n}\n\nstatic int vdebug_socket_receive(int hsock, struct vd_shm *pmem)\n{\n\tint rc;\n\tint dreceived = 0;\n\tint offset = &pmem->rid[0] - &pmem->cmd;\n\tint to_receive = VD_SHEADER_LEN + le_to_h_u16(pmem->rbytes);\n\tchar *pb = (char *)pmem;\n\n\tdo {\n\t\trc = recv(hsock, pb + offset, to_receive, 0);\n\t\tif (rc <= 0) {\n\t\t\tLOG_WARNING(\"socket_receive: recv failed, error %d\", rc < 0 ? vdebug_socket_error() : 0);\n\t\t\treturn rc;\n\t\t}\n\t\tto_receive -= rc;\n\t\toffset += rc;\n\t\tLOG_DEBUG_IO(\"socket_receive: received %d, to receive %d\", rc, to_receive);\n\t\tdreceived += rc;\n\t} while (to_receive);\n\n\treturn dreceived;\n}\n\nstatic int vdebug_socket_send(int hsock, struct vd_shm *pmem)\n{\n\tint rc = send(hsock, (const char *)&pmem->cmd, VD_CHEADER_LEN + le_to_h_u16(pmem->wbytes), 0);\n\tif (rc <= 0)\n\t\tLOG_WARNING(\"socket_send: send failed, error %d\", vdebug_socket_error());\n\telse\n\t\tLOG_DEBUG_IO(\"socket_send: sent %d, to send 0\", rc);\n\n\treturn rc;\n}\n\nstatic uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem)\n{\n\tif (!hsock)\n\t\treturn VD_ERR_SOC_OPEN;\n\n\tint st = vdebug_socket_send(hsock, pmem);\n\tif (st <= 0)\n\t\treturn VD_ERR_SOC_SEND;\n\n\tint rd = vdebug_socket_receive(hsock, pmem);\n\tif (rd  <= 0)\n\t\treturn VD_ERR_SOC_RECV;\n\n\tint rc = le_to_h_u32(pmem->status);\n\tLOG_DEBUG_IO(\"wait_server: cmd %02\" PRIx8 \" done, sent %d, rcvd %d, status %d\",\n\t\t\t\t pmem->cmd, st, rd, rc);\n\n\treturn rc;\n}\n\nstatic int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)\n{\n\tuint8_t  num_pre, num_post, tdi, tms;\n\tunsigned int num, anum, bytes, hwords, words;\n\tunsigned int req, waddr, rwords;\n\tint64_t ts, te;\n\tuint8_t *tdo;\n\tint rc;\n\tuint64_t jhdr;\n\tstruct vd_rdata *rd;\n\n\treq = 0;                            /* beginning of request */\n\twaddr = 0;\n\trwords = 0;\n\th_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width);\n\th_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width);\n\tts = timeval_ms();\n\trc = vdebug_wait_server(hsock, pm);\n\twhile (!rc && (req < count)) {      /* loop over requests to read data and print out */\n\t\tjhdr = le_to_h_u64(&pm->wd8[waddr * 4]);\n\t\twords = jhdr >> 48;\n\t\thwords = (jhdr >> 32) & 0xffff;\n\t\tanum = jhdr & 0xffffff;\n\t\tnum_pre = (jhdr >> 27) & 0x7;\n\t\tnum_post = (jhdr >> 24) & 0x7;\n\t\tif (num_post)\n\t\t\tnum = anum - num_pre - num_post + 1;\n\t\telse\n\t\t\tnum = anum - num_pre;\n\t\tbytes = (num + 7) / 8;\n\t\tvdc.trans_last = (req + 1) < count ? 0 : 1;\n\t\tvdc.trans_first = waddr ? 0 : 1;\n\t\tif (((jhdr >> 30) & 0x3) == 3) { /* cmd is read */\n\t\t\tif (!rwords) {\n\t\t\t\trd = &vdc.rdataq;\n\t\t\t\ttdo = rd->rdata;\n\t\t\t} else {\n\t\t\t\trd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);\n\t\t\t\ttdo = rd->rdata;\n\t\t\t\tlist_del(&rd->lh);\n\t\t\t\tfree(rd);\n\t\t\t}\n\t\t\tfor (unsigned int j = 0; j < bytes; j++) {\n\t\t\t\ttdo[j] = (pm->rd8[rwords * 8 + j] >> num_pre) | (pm->rd8[rwords * 8 + j + 1] << (8 - num_pre));\n\t\t\t\tLOG_DEBUG_IO(\"%04x D0[%02x]:%02x\", le_to_h_u16(pm->wid) - count + req, j, tdo[j]);\n\t\t\t}\n\t\t\trwords += words;           /* read data offset */\n\t\t} else {\n\t\t\ttdo = NULL;\n\t\t}\n\t\twaddr += sizeof(uint64_t) / 4; /* waddr past header */\n\t\ttdi = (pm->wd8[waddr * 4] >> num_pre) | (pm->wd8[waddr * 4 + 1] << (8 - num_pre));\n\t\ttms = (pm->wd8[waddr * 4 + 4] >> num_pre) | (pm->wd8[waddr * 4 + 4 + 1] << (8 - num_pre));\n\t\tLOG_DEBUG_IO(\"%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x\",\n\t\t\tle_to_h_u16(pm->wid) - count + req, num, (vdc.trans_first << 14) | (vdc.trans_last << 15),\n\t\t\twaddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd));\n\t\twaddr += hwords * 2;           /* start of next request */\n\t\treq += 1;\n\t}\n\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x executing transaction\", rc);\n\t\trc = ERROR_FAIL;\n\t}\n\n\tte = timeval_ms();\n\tvdc.targ_time += (uint32_t)(te - ts);\n\th_u16_to_le(pm->offseth, 0);      /* reset buffer write address */\n\th_u32_to_le(pm->offset, 0);\n\th_u16_to_le(pm->rwords, 0);\n\th_u16_to_le(pm->waddr, 0);\n\tassert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */\n\n\treturn rc;\n}\n\nstatic int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count)\n{\n\tunsigned int num, awidth, wwidth;\n\tunsigned int req, waddr, rwords;\n\tuint8_t aspace;\n\tuint32_t addr;\n\tint64_t ts, te;\n\tuint8_t *data;\n\tint rc;\n\tuint64_t rhdr;\n\tstruct vd_rdata *rd;\n\n\treq = 0;                            /* beginning of request */\n\twaddr = 0;\n\trwords = 0;\n\th_u16_to_le(pm->wbytes, le_to_h_u16(pm->wwords) * vdc.buf_width);\n\th_u16_to_le(pm->rbytes, le_to_h_u16(pm->rwords) * vdc.buf_width);\n\tts = timeval_ms();\n\trc = vdebug_wait_server(hsock, pm);\n\twhile (!rc && (req < count)) {      /* loop over requests to read data and print out */\n\t\trhdr = le_to_h_u64(&pm->wd8[waddr * 4]);\n\t\taddr = rhdr >> 32;              /* reconstruct data for a single request */\n\t\tnum = (rhdr >> 16) & 0x7ff;\n\t\taspace = rhdr & 0x3;\n\t\tawidth = (1 << ((rhdr >> 27) & 0x7));\n\t\twwidth = (awidth + vdc.buf_width - 1) / vdc.buf_width;\n\t\tvdc.trans_last = (req + 1) < count ? 0 : 1;\n\t\tvdc.trans_first = waddr ? 0 : 1;\n\t\tif (((rhdr >> 30) & 0x3) == 2) { /* cmd is read */\n\t\t\tif (num) {\n\t\t\t\tif (!rwords) {\n\t\t\t\t\trd = &vdc.rdataq;\n\t\t\t\t\tdata = rd->rdata;\n\t\t\t\t} else {\n\t\t\t\t\trd = list_first_entry(&vdc.rdataq.lh, struct vd_rdata, lh);\n\t\t\t\t\tdata = rd->rdata;\n\t\t\t\t\tlist_del(&rd->lh);\n\t\t\t\t\tfree(rd);\n\t\t\t\t}\n\t\t\t\tfor (unsigned int j = 0; j < num; j++)\n\t\t\t\t\tmemcpy(&data[j * awidth], &pm->rd8[(rwords + j) * awidth], awidth);\n\t\t\t}\n\t\t\tLOG_DEBUG_IO(\"read  %04x AS:%02x RG:%02x O:%05x @%03x D:%08x\", le_to_h_u16(pm->wid) - count + req,\n\t\t\t\taspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,\n\t\t\t\t(num ? le_to_h_u32(&pm->rd8[rwords * 4]) : 0xdead));\n\t\t\trwords += num * wwidth;\n\t\t\twaddr += sizeof(uint64_t) / 4; /* waddr past header */\n\t\t} else {\n\t\t\tLOG_DEBUG_IO(\"write %04x AS:%02x RG:%02x O:%05x @%03x D:%08x\", le_to_h_u16(pm->wid) - count + req,\n\t\t\t\taspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,\n\t\t\t\tle_to_h_u32(&pm->wd8[(waddr + num + 1) * 4]));\n\t\t\twaddr += sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4;\n\t\t}\n\t\treq += 1;\n\t}\n\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x executing transaction\", rc);\n\t\trc = ERROR_FAIL;\n\t}\n\n\tte = timeval_ms();\n\tvdc.targ_time += (uint32_t)(te - ts);\n\th_u16_to_le(pm->offseth, 0);      /* reset buffer write address */\n\th_u32_to_le(pm->offset, 0);\n\th_u16_to_le(pm->rwords, 0);\n\th_u16_to_le(pm->waddr, 0);\n\tassert(list_empty(&vdc.rdataq.lh));/* list should be empty after run queue */\n\n\treturn rc;\n}\n\nstatic int vdebug_open(int hsock, struct vd_shm *pm, const char *path,\n\t\t\t\t\t\tuint8_t type, uint32_t period_ps, uint32_t sig_mask)\n{\n\tint rc = VD_ERR_NOT_OPEN;\n\n\tpm->cmd = VD_CMD_OPEN;\n\th_u16_to_le(pm->wid, VD_VERSION);  /* client version */\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u16_to_le(pm->wwords, 0);\n\th_u16_to_le(pm->rwords, 0);\n\trc = vdebug_wait_server(hsock, pm);\n\tif (rc != 0) {                     /* communication problem */\n\t\tLOG_ERROR(\"0x%x connecting to server\", rc);\n\t} else if (le_to_h_u16(pm->rid) < le_to_h_u16(pm->wid)) {\n\t\tLOG_ERROR(\"server version %d too old for the client %d\", le_to_h_u16(pm->rid), le_to_h_u16(pm->wid));\n\t\tpm->cmd = VD_CMD_CLOSE;        /* let server close the connection */\n\t\tvdebug_wait_server(hsock, pm);\n\t\trc = VD_ERR_VERSION;\n\t} else {\n\t\tpm->cmd = VD_CMD_CONNECT;\n\t\tpm->type = type;               /* BFM type to connect to, here JTAG */\n\t\th_u32_to_le(pm->rwdata, sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16));\n\t\th_u16_to_le(pm->wbytes, strlen(path) + 1);\n\t\th_u16_to_le(pm->rbytes, 12);\n\t\th_u16_to_le(pm->wid, 0);       /* reset wid for transaction ID */\n\t\th_u16_to_le(pm->wwords, 0);\n\t\th_u16_to_le(pm->rwords, 0);\n\t\tmemcpy(pm->wd8, path, le_to_h_u16(pm->wbytes));\n\t\trc = vdebug_wait_server(hsock, pm);\n\t\tvdc.sig_read = le_to_h_u32(pm->rwdata) >> 16;  /* signal read mask */\n\t\tvdc.sig_write = le_to_h_u32(pm->rwdata);     /* signal write mask */\n\t\tvdc.bfm_period = period_ps;\n\t\tvdc.buf_width = le_to_h_u32(&pm->rd8[0]) / 8;/* access width in bytes */\n\t\tvdc.addr_bits = le_to_h_u32(&pm->rd8[2 * 4]);    /* supported address bits */\n\t}\n\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x connecting to BFM %s\", rc, path);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tINIT_LIST_HEAD(&vdc.rdataq.lh);\n\tLOG_DEBUG(\"%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x\",\n\t\tpath, type, vdc.bfm_period, VD_BUFFER_LEN / vdc.buf_width,\n\t\tvdc.buf_width, vdc.sig_read, vdc.sig_write);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type)\n{\n\tpm->cmd = VD_CMD_DISCONNECT;\n\tpm->type = type;              /* BFM type, here JTAG */\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u16_to_le(pm->wwords, 0);\n\th_u16_to_le(pm->rwords, 0);\n\tvdebug_wait_server(hsock, pm);\n\tpm->cmd = VD_CMD_CLOSE;\n\th_u16_to_le(pm->wid, VD_VERSION);    /* client version */\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u16_to_le(pm->wwords, 0);\n\th_u16_to_le(pm->rwords, 0);\n\tvdebug_wait_server(hsock, pm);\n\tLOG_DEBUG(\"type %0x\", type);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles)\n{\n\tif (cycles) {\n\t\tpm->cmd = VD_CMD_WAIT;\n\t\th_u16_to_le(pm->wbytes, 0);\n\t\th_u16_to_le(pm->rbytes, 0);\n\t\th_u32_to_le(pm->rwdata, cycles);  /* clock sycles to wait */\n\t\tint rc = vdebug_wait_server(hsock, pm);\n\t\tif (rc) {\n\t\t\tLOG_ERROR(\"0x%x waiting %\" PRIx32 \" cycles\", rc, cycles);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_DEBUG(\"%d cycles\", cycles);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value)\n{\n\tpm->cmd = VD_CMD_SIGSET;\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u32_to_le(pm->rwdata, (write_mask << 16) | (value & 0xffff)); /* mask and value of signals to set */\n\tint rc = vdebug_wait_server(hsock, pm);\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x setting signals %04\" PRIx32, rc, write_mask);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"setting signals %04\" PRIx32 \" to %04\" PRIx32, write_mask, value);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value)\n{\n\tpm->cmd = VD_CMD_JTAGCLOCK;\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u32_to_le(pm->rwdata, value);  /* divider value */\n\tint rc = vdebug_wait_server(hsock, pm);\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x setting jtag_clock\", rc);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"setting jtag clock divider to %\" PRIx32, value);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre,\n\t\t\t\t\t\t\t\t const uint8_t tms_pre, uint32_t num, const uint8_t *tdi,\n\t\t\t\t\t\t\t\t uint8_t num_post, const uint8_t tms_post, uint8_t *tdo,\n\t\t\t\t\t\t\t\t uint8_t f_last)\n{\n\tconst uint32_t tobits = 8;\n\tuint16_t bytes, hwords, anum, words, waddr;\n\tint rc = 0;\n\n\tpm->cmd = VD_CMD_JTAGSHTAP;\n\tvdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);\n\tif (vdc.trans_first)\n\t\twaddr = 0;             /* reset buffer offset */\n\telse\n\t\twaddr = le_to_h_u32(pm->offseth);   /* continue from the previous transaction */\n\tif (num_post)          /* actual number of bits to shift */\n\t\tanum = num + num_pre + num_post - 1;\n\telse\n\t\tanum = num + num_pre;\n\thwords = (anum + 4 * vdc.buf_width - 1) / (4 * vdc.buf_width); /* in 4B TDI/TMS words */\n\twords = (hwords + 1) / 2;    /* in 8B TDO words to read */\n\tbytes = (num + 7) / 8;       /* data only portion in bytes */\n\t/* buffer overflow check and flush */\n\tif (4 * waddr + sizeof(uint64_t) + 8 * hwords + 64 > VD_BUFFER_LEN) {\n\t\tvdc.trans_last = 1;        /* force flush within 64B of buffer end */\n\t} else if (4 * waddr + sizeof(uint64_t) + 8 * hwords > VD_BUFFER_LEN) {\n\t\t/* this req does not fit, discard it */\n\t\tLOG_ERROR(\"%04x L:%02d O:%05x @%04x too many bits to shift\",\n\t\t\tle_to_h_u16(pm->wid), anum, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr);\n\t\trc = ERROR_FAIL;\n\t}\n\n\tif (!rc && anum) {\n\t\tuint16_t i, j;       /* portability requires to use bit operations for 8B JTAG header */\n\t\tuint64_t jhdr = (tdo ? ((uint64_t)(words) << 48) : 0) + ((uint64_t)(hwords) << 32) +\n\t\t\t((tdo ? 3UL : 1UL) << 30) + (num_pre << 27) + (num_post << 24) + anum;\n\t\th_u64_to_le(&pm->wd8[4 * waddr], jhdr);\n\n\t\th_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1);    /* transaction ID */\n\t\twaddr += 2;              /* waddr past header */\n\t\t/* TDI/TMS data follows as 32 bit word pairs {TMS,TDI} */\n\t\tpm->wd8[4 * waddr] = (tdi ? (tdi[0] << num_pre) : 0);\n\t\tpm->wd8[4 * waddr + 4] = tms_pre;    /* init with tms_pre */\n\t\tif (num + num_pre <= 8)            /* and tms_post for num <=4 */\n\t\t\tpm->wd8[4 * waddr + 4] |= (tms_post << (num + num_pre - 1));\n\t\tfor (i = 1, j = 4 * waddr; i < bytes; i++) {\n\t\t\tif (i == bytes - 1 && num + num_pre <= bytes * tobits)\n\t\t\t\tpm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);\n\t\t\telse\n\t\t\t\tpm->wd8[j + i + 4] = 0x0;/* placing 4 bytes of TMS bits into high word */\n\t\t\tif (!tdi)             /* placing 4 bytes of TDI bits into low word */\n\t\t\t\tpm->wd8[j + i] = 0x0;\n\t\t\telse\n\t\t\t\tpm->wd8[j + i] = (tdi[i] << num_pre) | (tdi[i - 1] >> (8 - num_pre));\n\t\t\tif (i % 4 == 3)\n\t\t\t\tj += 4;\n\t\t}\n\n\t\tif (tdi)\n\t\t\tif (num + num_pre > bytes * tobits) /* in case 1 additional byte needed for TDI */\n\t\t\t\tpm->wd8[j + i] = (tdi[i - 1] >> (8 - num_pre)); /* put last TDI bits there */\n\n\t\tif (num + num_pre <= bytes * tobits) { /* in case no or 1 additional byte needed */\n\t\t\tpm->wd8[j + i + 4] = tms_post >> (8 - (num + num_pre - 1) % 8); /* may need to add higher part */\n\t\t/* in case exactly 1 additional byte needed */\n\t\t} else if (num + num_pre > bytes * tobits && anum <= (bytes + 1) * tobits) {\n\t\t\tpm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8); /* add whole tms_post */\n\t\t} else {                           /* in case 2 additional bytes, tms_post split */\n\t\t\tpm->wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);/* add lower part of tms_post */\n\t\t\tif (i % 4 == 3)              /* next byte is in the next 32b word */\n\t\t\t\tpm->wd8[j + i + 4 + 5] = tms_post >> (8 - (num + num_pre - 1) % 8); /* and higher part */\n\t\t\telse                         /* next byte is in the same 32b word */\n\t\t\t\tpm->wd8[j + i + 4 + 1] = tms_post >> (8 - (num + num_pre - 1) % 8); /* and higher part */\n\t\t}\n\n\t\tif (tdo) {\n\t\t\tstruct vd_rdata *rd;\n\t\t\tif (le_to_h_u16(pm->rwords) == 0) {\n\t\t\t\trd = &vdc.rdataq;\n\t\t\t} else {\n\t\t\t\trd = calloc(1, sizeof(struct vd_rdata));\n\t\t\t\tif (!rd)                   /* check allocation for 24B */\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tlist_add_tail(&rd->lh, &vdc.rdataq.lh);\n\t\t\t}\n\t\t\trd->rdata = tdo;\n\t\t\th_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + words);/* keep track of the words to read */\n\t\t}\n\t\th_u16_to_le(pm->wwords, waddr / 2 + hwords); /* payload size *2 to include both TDI and TMS data */\n\t\th_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);\n\t}\n\n\tif (!waddr)                        /* flush issued, but buffer empty */\n\t\t;\n\telse if (!vdc.trans_last)          /* buffered request */\n\t\th_u16_to_le(pm->offseth, waddr + hwords * 2);  /* offset for next transaction, must be even */\n\telse                               /* execute batch of requests */\n\t\trc = vdebug_run_jtag_queue(hsock, pm, le_to_h_u16(pm->waddr));\n\tvdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */\n\n\treturn rc;\n}\n\nstatic int vdebug_reg_write(int hsock, struct vd_shm *pm, const uint32_t reg,\n\t\t\t\t\t\t\tconst uint32_t data, uint8_t aspace, uint8_t f_last)\n{\n\tuint32_t waddr;\n\tint rc = ERROR_OK;\n\n\tpm->cmd = VD_CMD_REGWRITE;\n\tvdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);\n\tif (vdc.trans_first)\n\t\twaddr = 0;             /* reset buffer offset */\n\telse\n\t\twaddr = le_to_h_u16(pm->offseth);   /* continue from the previous transaction */\n\n\tif (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)\n\t\tvdc.trans_last = 1;    /* force flush, no room for next request */\n\n\tuint64_t rhdr = ((uint64_t)reg << 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace;\n\th_u64_to_le(&pm->wd8[4 * waddr], rhdr);\n\th_u32_to_le(&pm->wd8[4 * (waddr + 2)], data);\n\th_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1);\n\th_u16_to_le(pm->wwords, waddr + 3);\n\th_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);\n\tif (!vdc.trans_last)       /* buffered request */\n\t\th_u16_to_le(pm->offseth, waddr + 3);\n\telse\n\t\trc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr));\n\tvdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */\n\n\treturn rc;\n}\n\nstatic int vdebug_reg_read(int hsock, struct vd_shm *pm, const uint32_t reg,\n\t\t\t\t\t\t\tuint32_t *data, uint8_t aspace, uint8_t f_last)\n{\n\tuint32_t waddr;\n\tint rc = ERROR_OK;\n\n\tpm->cmd = VD_CMD_REGREAD;\n\tvdc.trans_last = f_last || (vdc.trans_batch == VD_BATCH_NO);\n\tif (vdc.trans_first)\n\t\twaddr = 0;             /* reset buffer offset */\n\telse\n\t\twaddr = le_to_h_u16(pm->offseth);   /* continue from the previous transaction */\n\n\tif (4 * waddr + 2 * sizeof(uint64_t) + 4 > VD_BUFFER_LEN)\n\t\tvdc.trans_last = 1;    /* force flush, no room for next request */\n\n\tuint64_t rhdr = ((uint64_t)reg << 32) + (2UL << 30) + (2UL << 27) + ((data ? 1UL : 0UL) << 16) + aspace;\n\th_u64_to_le(&pm->wd8[4 * waddr], rhdr);\n\th_u16_to_le(pm->wid, le_to_h_u16(pm->wid) + 1);\n\tif (data) {\n\t\tstruct vd_rdata *rd;\n\t\tif (le_to_h_u16(pm->rwords) == 0) {\n\t\t\trd = &vdc.rdataq;\n\t\t} else {\n\t\t\trd = calloc(1, sizeof(struct vd_rdata));\n\t\t\tif (!rd)                   /* check allocation for 24B */\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tlist_add_tail(&rd->lh, &vdc.rdataq.lh);\n\t\t}\n\t\trd->rdata = (uint8_t *)data;\n\t\th_u16_to_le(pm->rwords, le_to_h_u16(pm->rwords) + 1);\n\t}\n\th_u16_to_le(pm->wwords, waddr + 2);\n\th_u16_to_le(pm->waddr, le_to_h_u16(pm->waddr) + 1);\n\tif (!vdc.trans_last)       /* buffered request */\n\t\th_u16_to_le(pm->offseth, waddr + 2);\n\telse\n\t\trc = vdebug_run_reg_queue(hsock, pm, le_to_h_u16(pm->waddr));\n\tvdc.trans_first = vdc.trans_last; /* flush forces trans_first flag */\n\n\treturn rc;\n}\n\nstatic int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8_t ndx)\n{\n\tint rc;\n\n\tif (!path)\n\t\treturn ERROR_OK;\n\n\tpm->cmd = VD_CMD_MEMOPEN;\n\th_u16_to_le(pm->wbytes, strlen(path) + 1);   /* includes terminating 0 */\n\th_u16_to_le(pm->rbytes, 8);\n\th_u16_to_le(pm->wwords, 0);\n\th_u16_to_le(pm->rwords, 0);\n\tmemcpy(pm->wd8, path, le_to_h_u16(pm->wbytes));\n\trc = vdebug_wait_server(hsock, pm);\n\tif (rc) {\n\t\tLOG_ERROR(\"0x%x opening memory %s\", rc, path);\n\t} else if (ndx != pm->rd8[2]) {\n\t\tLOG_WARNING(\"Invalid memory index %\" PRIu16 \" returned. Direct memory access disabled\", pm->rd8[2]);\n\t} else {\n\t\tvdc.mem_width[ndx] = le_to_h_u16(&pm->rd8[0]) / 8;   /* memory width in bytes */\n\t\tvdc.mem_depth[ndx] = le_to_h_u32(&pm->rd8[4]);       /* memory depth in words */\n\t\tLOG_DEBUG(\"%\" PRIx8 \": %s memory %\" PRIu32 \"x%\" PRIu32 \"B, buffer %\" PRIu32 \"x%\" PRIu32 \"B\", ndx, path,\n\t\t\tvdc.mem_depth[ndx], vdc.mem_width[ndx], VD_BUFFER_LEN / vdc.mem_width[ndx], vdc.mem_width[ndx]);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx)\n{\n\tpm->cmd = VD_CMD_MEMCLOSE;\n\th_u32_to_le(pm->rwdata, ndx);        /* which memory */\n\th_u16_to_le(pm->wbytes, 0);\n\th_u16_to_le(pm->rbytes, 0);\n\th_u16_to_le(pm->wwords, 0);\n\th_u16_to_le(pm->rwords, 0);\n\tvdebug_wait_server(hsock, pm);\n\tLOG_DEBUG(\"%\" PRIx8 \": %s\", ndx, vdc.mem_path[ndx]);\n}\n\n\nstatic int vdebug_init(void)\n{\n\tvdc.hsocket = vdebug_socket_open(vdc.server_name, vdc.server_port);\n\tpbuf = calloc(1, sizeof(struct vd_shm));\n\tif (!pbuf) {\n\t\tclose_socket(vdc.hsocket);\n\t\tvdc.hsocket = 0;\n\t\tLOG_ERROR(\"cannot allocate %zu bytes\", sizeof(struct vd_shm));\n\t\treturn ERROR_FAIL;\n\t}\n\tif (vdc.hsocket <= 0) {\n\t\tfree(pbuf);\n\t\tpbuf = NULL;\n\t\tLOG_ERROR(\"cannot connect to vdebug server %s:%\" PRIu16,\n\t\t\tvdc.server_name, vdc.server_port);\n\t\treturn ERROR_FAIL;\n\t}\n\tvdc.trans_first = 1;\n\tvdc.poll_cycles = vdc.poll_max;\n\tuint32_t sig_mask = VD_SIG_RESET;\n\tif (transport_is_jtag())\n\t\tsig_mask |= VD_SIG_TRST | VD_SIG_TCKDIV;\n\n\tint rc = vdebug_open(vdc.hsocket, pbuf, vdc.bfm_path, vdc.bfm_type, vdc.bfm_period, sig_mask);\n\tif (rc != 0) {\n\t\tLOG_ERROR(\"0x%x cannot connect to %s\", rc, vdc.bfm_path);\n\t\tclose_socket(vdc.hsocket);\n\t\tvdc.hsocket = 0;\n\t\tfree(pbuf);\n\t\tpbuf = NULL;\n\t} else {\n\t\tfor (uint8_t i = 0; i < vdc.mem_ndx; i++) {\n\t\t\trc = vdebug_mem_open(vdc.hsocket, pbuf, vdc.mem_path[i], i);\n\t\t\tif (rc != 0)\n\t\t\t\tLOG_ERROR(\"0x%x cannot connect to %s\", rc, vdc.mem_path[i]);\n\t\t}\n\n\t\tLOG_INFO(\"vdebug %d connected to %s through %s:%\" PRIu16,\n\t\t\t\t VD_VERSION, vdc.bfm_path, vdc.server_name, vdc.server_port);\n\t}\n\n\treturn rc;\n}\n\nstatic int vdebug_quit(void)\n{\n\tfor (uint8_t i = 0; i < vdc.mem_ndx; i++)\n\t\tif (vdc.mem_width[i])\n\t\t\tvdebug_mem_close(vdc.hsocket, pbuf, i);\n\tint rc = vdebug_close(vdc.hsocket, pbuf, vdc.bfm_type);\n\tLOG_INFO(\"vdebug %d disconnected from %s through %s:%\" PRIu16 \" rc:%d\", VD_VERSION,\n\t\tvdc.bfm_path, vdc.server_name, vdc.server_port, rc);\n\tif (vdc.hsocket)\n\t\tclose_socket(vdc.hsocket);\n\tfree(pbuf);\n\tpbuf = NULL;\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_reset(int trst, int srst)\n{\n\tuint16_t sig_val = 0xffff;\n\tuint16_t sig_mask = 0;\n\n\tsig_mask |= VD_SIG_RESET;\n\tif (srst)\n\t\tsig_val &= ~VD_SIG_RESET;/* active low */\n\tif (transport_is_jtag()) {\n\t\tsig_mask |= VD_SIG_TRST;\n\t\tif (trst)\n\t\t\tsig_val &= ~VD_SIG_TRST; /* active low */\n\t}\n\n\tLOG_INFO(\"rst trst:%d srst:%d mask:%\" PRIx16 \" val:%\" PRIx16, trst, srst, sig_mask, sig_val);\n\tint rc = vdebug_sig_set(vdc.hsocket, pbuf, sig_mask, sig_val);\n\tif (rc == 0)\n\t\trc = vdebug_wait(vdc.hsocket, pbuf, 20); /* 20 clock cycles pulse */\n\n\treturn rc;\n}\n\nstatic int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)\n{\n\tLOG_INFO(\"tms  len:%d tms:%x\", num, *tms);\n\n\treturn vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush);\n}\n\nstatic int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)\n{\n\tuint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)];\n\tLOG_INFO(\"path num states %d\", cmd->num_states);\n\n\tmemset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8));\n\n\tfor (uint8_t i = 0; i < cmd->num_states; i++) {\n\t\tif (tap_state_transition(tap_get_state(), true) == cmd->path[i])\n\t\t\tbuf_set_u32(tms, i, 1, 1);\n\t\ttap_set_state(cmd->path[i]);\n\t}\n\n\treturn vdebug_jtag_tms_seq(tms, cmd->num_states, f_flush);\n}\n\nstatic int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush)\n{\n\tint rc = ERROR_OK;\n\n\ttap_state_t cur = tap_get_state();\n\tuint8_t tms_pre = tap_get_tms_path(cur, state);\n\tuint8_t num_pre = tap_get_tms_path_len(cur, state);\n\tLOG_INFO(\"tlr  from %x to %x\", cur, state);\n\tif (cur != state) {\n\t\trc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, 0, NULL, 0, 0, NULL, f_flush);\n\t\ttap_set_state(state);\n\t}\n\n\treturn rc;\n}\n\nstatic int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)\n{\n\tint rc = ERROR_OK;\n\n\ttap_state_t cur = tap_get_state();\n\tuint8_t state = cmd->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT;\n\tuint8_t tms_pre = tap_get_tms_path(cur, state);\n\tuint8_t num_pre = tap_get_tms_path_len(cur, state);\n\tuint8_t tms_post = tap_get_tms_path(state, cmd->end_state);\n\tuint8_t num_post = tap_get_tms_path_len(state, cmd->end_state);\n\tint num_bits = jtag_scan_size(cmd);\n\tLOG_DEBUG(\"scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x\",\n\t\t\t  num_bits, cmd->num_fields, cmd->ir_scan, cur, cmd->end_state);\n\tfor (int i = 0; i < cmd->num_fields; i++) {\n\t\tuint8_t cur_num_pre = i == 0 ? num_pre : 0;\n\t\tuint8_t cur_tms_pre = i == 0 ? tms_pre : 0;\n\t\tuint8_t cur_num_post = i == cmd->num_fields - 1 ? num_post : 0;\n\t\tuint8_t cur_tms_post = i == cmd->num_fields - 1 ? tms_post : 0;\n\t\tuint8_t cur_flush = i == cmd->num_fields - 1 ? f_flush : 0;\n\t\trc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, cur_num_pre, cur_tms_pre,\n\t\t\t\t\t\t\t\t   cmd->fields[i].num_bits, cmd->fields[i].out_value, cur_num_post, cur_tms_post,\n\t\t\t\t\t\t\t cmd->fields[i].in_value, cur_flush);\n\t\tif (rc)\n\t\t\tbreak;\n\t}\n\n\tif (cur != cmd->end_state)\n\t\ttap_set_state(cmd->end_state);\n\n\treturn rc;\n}\n\nstatic int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)\n{\n\ttap_state_t cur = tap_get_state();\n\tuint8_t tms_pre = tap_get_tms_path(cur, state);\n\tuint8_t num_pre = tap_get_tms_path_len(cur, state);\n\tLOG_DEBUG(\"idle len:%d state cur:%x end:%x\", cycles, cur, state);\n\tint rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, cycles, NULL, 0, 0, NULL, f_flush);\n\tif (cur != state)\n\t\ttap_set_state(state);\n\n\treturn rc;\n}\n\nstatic int vdebug_jtag_stableclocks(int num, uint8_t f_flush)\n{\n\tLOG_INFO(\"stab len:%d state cur:%x\", num, tap_get_state());\n\n\treturn vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush);\n}\n\nstatic int vdebug_sleep(int us)\n{\n\tLOG_INFO(\"sleep %d us\", us);\n\n\treturn vdebug_wait(vdc.hsocket, pbuf, us / 1000);\n}\n\nstatic int vdebug_jtag_speed(int speed)\n{\n\tunsigned int clkmax = VD_SCALE_PSTOMS / (vdc.bfm_period * 2); /* kHz */\n\tunsigned int divval = clkmax / speed;\n\tLOG_INFO(\"jclk speed:%d kHz set, BFM divider %u\", speed, divval);\n\n\treturn vdebug_jtag_clock(vdc.hsocket, pbuf, divval);\n}\n\nstatic int vdebug_jtag_khz(int khz, int *jtag_speed)\n{\n\tunsigned int clkmax = VD_SCALE_PSTOMS / (vdc.bfm_period * 2); /* kHz */\n\tunsigned int divval = khz ? clkmax / khz : 1;\n\t*jtag_speed = clkmax / divval;\n\tLOG_DEBUG(\"khz  speed:%d from khz:%d\", *jtag_speed, khz);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_jtag_div(int speed, int *khz)\n{\n\t*khz = speed;\n\tLOG_DEBUG(\"div  khz:%d from speed:%d\", *khz, speed);\n\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_jtag_execute_queue(void)\n{\n\tint rc = ERROR_OK;\n\n\tfor (struct jtag_command *cmd = jtag_command_queue; rc == ERROR_OK && cmd; cmd = cmd->next) {\n\t\tswitch (cmd->type) {\n\t\tcase JTAG_RUNTEST:\n\t\t\trc = vdebug_jtag_runtest(cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state, !cmd->next);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\trc = vdebug_jtag_stableclocks(cmd->cmd.stableclocks->num_cycles, !cmd->next);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\trc = vdebug_jtag_tlr(cmd->cmd.statemove->end_state, !cmd->next);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\trc = vdebug_jtag_path_move(cmd->cmd.pathmove, !cmd->next);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\t\trc = vdebug_jtag_tms_seq(cmd->cmd.tms->bits, cmd->cmd.tms->num_bits, !cmd->next);\n\t\t\tbreak;\n\t\tcase JTAG_SLEEP:\n\t\t\trc = vdebug_sleep(cmd->cmd.sleep->us);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\trc = vdebug_jtag_scan(cmd->cmd.scan, !cmd->next);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unknown JTAG command type 0x%x encountered\", cmd->type);\n\t\t\trc = ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn rc;\n}\n\nstatic int vdebug_dap_connect(struct adiv5_dap *dap)\n{\n\treturn dap_dp_init(dap);\n}\n\nstatic int vdebug_dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)\n{\n\treturn ERROR_OK;\n}\n\nstatic int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)\n{\n\treturn vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);\n}\n\nstatic int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)\n{\n\treturn vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);\n}\n\nstatic int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)\n{\n\tif ((reg & DP_SELECT_APBANK) != ap->dap->select) {\n\t\tvdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);\n\t\tap->dap->select = reg & DP_SELECT_APBANK;\n\t}\n\n\tvdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0);\n\n\treturn vdebug_reg_read(vdc.hsocket, pbuf, DP_RDBUFF >> 2, data, VD_ASPACE_DP, 0);\n}\n\nstatic int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)\n{\n\tif ((reg & DP_SELECT_APBANK) != ap->dap->select) {\n\t\tvdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);\n\t\tap->dap->select = reg & DP_SELECT_APBANK;\n\t}\n\n\treturn vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0);\n}\n\nstatic int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\treturn vdebug_reg_write(vdc.hsocket, pbuf, 0, 0x1, VD_ASPACE_AB, 0);\n}\n\nstatic int vdebug_dap_run(struct adiv5_dap *dap)\n{\n\tif (le_to_h_u16(pbuf->waddr))\n\t\treturn vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vdebug_set_server)\n{\n\tif ((CMD_ARGC != 1) || !strchr(CMD_ARGV[0], ':'))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tchar *pchar = strchr(CMD_ARGV[0], ':');\n\t*pchar = '\\0';\n\tstrncpy(vdc.server_name, CMD_ARGV[0], sizeof(vdc.server_name) - 1);\n\tint port = atoi(++pchar);\n\tif (port < 0 || port > UINT16_MAX) {\n\t\tLOG_ERROR(\"invalid port number %d specified\", port);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tvdc.server_port = port;\n\tLOG_DEBUG(\"server: %s port %u\", vdc.server_name, vdc.server_port);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vdebug_set_bfm)\n{\n\tchar prefix;\n\n\tif ((CMD_ARGC != 2) || (sscanf(CMD_ARGV[1], \"%u%c\", &vdc.bfm_period, &prefix) != 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstrncpy(vdc.bfm_path, CMD_ARGV[0], sizeof(vdc.bfm_path) - 1);\n\tswitch (prefix) {\n\tcase 'u':\n\t\tvdc.bfm_period *= 1000000;\n\t\tbreak;\n\tcase 'n':\n\t\tvdc.bfm_period *= 1000;\n\t\tbreak;\n\tcase 'p':\n\tdefault:\n\t\tbreak;\n\t}\n\tif (transport_is_dapdirect_swd())\n\t\tvdc.bfm_type = VD_BFM_SWDP;\n\telse\n\t\tvdc.bfm_type = VD_BFM_JTAG;\n\tLOG_DEBUG(\"bfm_path: %s clk_period %ups\", vdc.bfm_path, vdc.bfm_period);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vdebug_set_mem)\n{\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (vdc.mem_ndx >= VD_MAX_MEMORIES) {\n\t\tLOG_ERROR(\"mem_path declared more than %d allowed times\", VD_MAX_MEMORIES);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstrncpy(vdc.mem_path[vdc.mem_ndx], CMD_ARGV[0], sizeof(vdc.mem_path[vdc.mem_ndx]) - 1);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], vdc.mem_base[vdc.mem_ndx]);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], vdc.mem_size[vdc.mem_ndx]);\n\tLOG_DEBUG(\"mem_path: set %s @ 0x%08x+0x%08x\", vdc.mem_path[vdc.mem_ndx],\n\t\tvdc.mem_base[vdc.mem_ndx], vdc.mem_size[vdc.mem_ndx]);\n\tvdc.mem_ndx++;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vdebug_set_batching)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (isdigit((unsigned char)CMD_ARGV[0][0]))\n\t\tvdc.trans_batch = (CMD_ARGV[0][0] == '0' ? 0 : (CMD_ARGV[0][0] == '1' ? 1 : 2));\n\telse if (CMD_ARGV[0][0] == 'r')\n\t\tvdc.trans_batch = VD_BATCH_WR;\n\telse if (CMD_ARGV[0][0] == 'w')\n\t\tvdc.trans_batch = VD_BATCH_WO;\n\telse\n\t\tvdc.trans_batch = VD_BATCH_NO;\n\tLOG_DEBUG(\"batching: set to %u\", vdc.trans_batch);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vdebug_set_polling)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tvdc.poll_min = atoi(CMD_ARGV[0]);\n\tvdc.poll_max = atoi(CMD_ARGV[1]);\n\tLOG_DEBUG(\"polling: set min %u max %u\", vdc.poll_min, vdc.poll_max);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration vdebug_command_handlers[] = {\n\t{\n\t\t.name = \"server\",\n\t\t.handler = &vdebug_set_server,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the vdebug server name or address\",\n\t\t.usage = \"<host:port>\",\n\t},\n\t{\n\t\t.name = \"bfm_path\",\n\t\t.handler = &vdebug_set_bfm,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the vdebug BFM hierarchical path\",\n\t\t.usage = \"<path> <clk_period[p|n|u]s>\",\n\t},\n\t{\n\t\t.name = \"mem_path\",\n\t\t.handler = &vdebug_set_mem,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the design memory for the code load\",\n\t\t.usage = \"<path> <base_address> <size>\",\n\t},\n\t{\n\t\t.name = \"batching\",\n\t\t.handler = &vdebug_set_batching,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the transaction batching no|wr|rd [0|1|2]\",\n\t\t.usage = \"<level>\",\n\t},\n\t{\n\t\t.name = \"polling\",\n\t\t.handler = &vdebug_set_polling,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the polling pause, executing hardware cycles between min and max\",\n\t\t.usage = \"<min cycles> <max cycles>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration vdebug_command[] = {\n\t{\n\t\t.name = \"vdebug\",\n\t\t.chain = vdebug_command_handlers,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"vdebug command group\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface vdebug_jtag_ops = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = vdebug_jtag_execute_queue,\n};\n\nstatic const struct dap_ops vdebug_dap_ops = {\n\t.connect = vdebug_dap_connect,\n\t.send_sequence = vdebug_dap_send_sequence,\n\t.queue_dp_read = vdebug_dap_queue_dp_read,\n\t.queue_dp_write = vdebug_dap_queue_dp_write,\n\t.queue_ap_read = vdebug_dap_queue_ap_read,\n\t.queue_ap_write = vdebug_dap_queue_ap_write,\n\t.queue_ap_abort = vdebug_dap_queue_ap_abort,\n\t.run = vdebug_dap_run,\n\t.sync = NULL, /* optional */\n\t.quit = NULL, /* optional */\n};\n\nstatic const char *const vdebug_transports[] = { \"jtag\", \"dapdirect_swd\", NULL };\n\nstruct adapter_driver vdebug_adapter_driver = {\n\t.name = \"vdebug\",\n\t.transports = vdebug_transports,\n\t.speed = vdebug_jtag_speed,\n\t.khz = vdebug_jtag_khz,\n\t.speed_div = vdebug_jtag_div,\n\t.commands = vdebug_command,\n\t.init = vdebug_init,\n\t.quit = vdebug_quit,\n\t.reset = vdebug_reset,\n\t.jtag_ops = &vdebug_jtag_ops,\n\t.dap_swd_ops = &vdebug_dap_ops,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtogpio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"../versaloon_include.h\"\n#include \"../versaloon.h\"\n#include \"../versaloon_internal.h\"\n#include \"usbtoxxx.h\"\n#include \"usbtoxxx_internal.h\"\n\nRESULT usbtogpio_init(uint8_t interface_index)\n{\n\treturn usbtoxxx_init_command(USB_TO_GPIO, interface_index);\n}\n\nRESULT usbtogpio_fini(uint8_t interface_index)\n{\n\treturn usbtoxxx_fini_command(USB_TO_GPIO, interface_index);\n}\n\nRESULT usbtogpio_config(uint8_t interface_index, uint32_t mask,\n\tuint32_t dir_mask, uint32_t pull_en_mask,\n\tuint32_t input_pull_mask)\n{\n\tuint8_t conf[8];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tdir_mask &= mask;\n\tSET_LE_U16(&conf[0], mask);\n\tSET_LE_U16(&conf[2], dir_mask);\n\tSET_LE_U16(&conf[4], pull_en_mask);\n\tSET_LE_U16(&conf[6], input_pull_mask);\n\n\treturn usbtoxxx_conf_command(USB_TO_GPIO, interface_index, conf,\n\t\tsizeof(conf));\n}\n\nRESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value)\n{\n\tuint8_t buf[2];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tSET_LE_U16(&buf[0], mask);\n\n\treturn usbtoxxx_in_command(USB_TO_GPIO, interface_index, buf, 2, 2,\n\t\t(uint8_t *)value, 0, 2, 0);\n}\n\nRESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value)\n{\n\tuint8_t buf[4];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tSET_LE_U16(&buf[0], mask);\n\tSET_LE_U16(&buf[2], value);\n\n\treturn usbtoxxx_out_command(USB_TO_GPIO, interface_index, buf, 4, 0);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtojtagraw.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"../versaloon_include.h\"\n#include \"../versaloon.h\"\n#include \"../versaloon_internal.h\"\n#include \"usbtoxxx.h\"\n#include \"usbtoxxx_internal.h\"\n\nRESULT usbtojtagraw_init(uint8_t interface_index)\n{\n\treturn usbtoxxx_init_command(USB_TO_JTAG_RAW, interface_index);\n}\n\nRESULT usbtojtagraw_fini(uint8_t interface_index)\n{\n\treturn usbtoxxx_fini_command(USB_TO_JTAG_RAW, interface_index);\n}\n\nRESULT usbtojtagraw_config(uint8_t interface_index, uint32_t khz)\n{\n\tuint8_t cfg_buf[4];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tSET_LE_U32(&cfg_buf[0], khz);\n\n\treturn usbtoxxx_conf_command(USB_TO_JTAG_RAW, interface_index, cfg_buf, 4);\n}\n\nRESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi,\n\tuint8_t *tms, uint8_t *tdo, uint32_t bitlen)\n{\n\tuint16_t bytelen;\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tif (bitlen > 8 * 0xFFFF)\n\t\treturn ERROR_FAIL;\n\tbytelen = (uint16_t)((bitlen + 7) >> 3);\n\n\tSET_LE_U32(&versaloon_cmd_buf[0], bitlen);\n\tmemcpy(versaloon_cmd_buf + 4, tdi, bytelen);\n\tmemcpy(versaloon_cmd_buf + 4 + bytelen, tms, bytelen);\n\n\treturn usbtoxxx_inout_command(USB_TO_JTAG_RAW, interface_index,\n\t\tversaloon_cmd_buf, 4 + bytelen * 2, bytelen, tdo, 0, bytelen, 0);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtopwr.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"../versaloon_include.h\"\n#include \"../versaloon.h\"\n#include \"../versaloon_internal.h\"\n#include \"usbtoxxx.h\"\n#include \"usbtoxxx_internal.h\"\n\nRESULT usbtopwr_init(uint8_t interface_index)\n{\n\treturn usbtoxxx_init_command(USB_TO_POWER, interface_index);\n}\n\nRESULT usbtopwr_fini(uint8_t interface_index)\n{\n\treturn usbtoxxx_fini_command(USB_TO_POWER, interface_index);\n}\n\nRESULT usbtopwr_config(uint8_t interface_index)\n{\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\treturn usbtoxxx_conf_command(USB_TO_POWER, interface_index, NULL, 0);\n}\n\nRESULT usbtopwr_output(uint8_t interface_index, uint16_t millivolt)\n{\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\treturn usbtoxxx_out_command(USB_TO_POWER, interface_index, (uint8_t *)&millivolt,\n\t\t2, 0);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtoswd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <string.h>\n\n#include \"../versaloon_include.h\"\n#include \"../versaloon.h\"\n#include \"../versaloon_internal.h\"\n#include \"usbtoxxx.h\"\n#include \"usbtoxxx_internal.h\"\n\nstatic RESULT usbtoswd_read_callback(void *p, uint8_t *src, uint8_t *processed)\n{\n\tstruct versaloon_pending_t *pending = (struct versaloon_pending_t *)p;\n\n\tif (pending->extra_data)\n\t\t*((uint8_t *)pending->extra_data) = src[0];\n\n\treturn ERROR_OK;\n}\n\nstatic RESULT usbtoswd_write_callback(void *p, uint8_t *src, uint8_t *processed)\n{\n\tstruct versaloon_pending_t *pending = (struct versaloon_pending_t *)p;\n\n\tif (pending->extra_data)\n\t\t*((uint8_t *)pending->extra_data) = src[0];\n\n\t/* mark it processed to ignore other input data */\n\t*processed = 1;\n\treturn ERROR_OK;\n}\n\nRESULT usbtoswd_init(uint8_t interface_index)\n{\n\treturn usbtoxxx_init_command(USB_TO_SWD, interface_index);\n}\n\nRESULT usbtoswd_fini(uint8_t interface_index)\n{\n\treturn usbtoxxx_fini_command(USB_TO_SWD, interface_index);\n}\n\nRESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry,\n\tuint16_t dly)\n{\n\tuint8_t cfg_buf[5];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tcfg_buf[0] = trn;\n\tSET_LE_U16(&cfg_buf[1], retry);\n\tSET_LE_U16(&cfg_buf[3], dly);\n\n\treturn usbtoxxx_conf_command(USB_TO_SWD, interface_index, cfg_buf, 5);\n}\n\nRESULT usbtoswd_seqout(uint8_t interface_index, const uint8_t *data,\n\tuint16_t bitlen)\n{\n\tuint16_t bytelen = (bitlen + 7) >> 3;\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tSET_LE_U16(&versaloon_cmd_buf[0], bitlen);\n\tmemcpy(versaloon_cmd_buf + 2, data, bytelen);\n\n\treturn usbtoxxx_out_command(USB_TO_SWD, interface_index,\n\t\tversaloon_cmd_buf, bytelen + 2, 0);\n}\n\nRESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen)\n{\n\tuint16_t bytelen = (bitlen + 7) >> 3;\n\tuint8_t buff[2];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tSET_LE_U16(&buff[0], bitlen);\n\n\treturn usbtoxxx_in_command(USB_TO_SWD, interface_index, buff, 2, bytelen,\n\t\tdata, 0, bytelen, 0);\n}\n\nRESULT usbtoswd_transact(uint8_t interface_index, uint8_t request,\n\tuint32_t *data, uint8_t *ack)\n{\n\tuint8_t parity;\n\tuint8_t buff[5];\n\n#if PARAM_CHECK\n\tif (interface_index > 7) {\n\t\tLOG_BUG(ERRMSG_INVALID_INTERFACE_NUM, interface_index);\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tparity = (request >> 1) & 1;\n\tparity += (request >> 2) & 1;\n\tparity += (request >> 3) & 1;\n\tparity += (request >> 4) & 1;\n\tparity &= 1;\n\tbuff[0] = (request | 0x81 | (parity << 5)) & ~0x40;\n\tif (data)\n\t\tSET_LE_U32(&buff[1], *data);\n\telse\n\t\tmemset(buff + 1, 0, 4);\n\n\tversaloon_set_extra_data(ack);\n\tif (request & 0x04) {\n\t\t/* read */\n\t\tversaloon_set_callback(usbtoswd_read_callback);\n\t} else {\n\t\t/* write */\n\t\tversaloon_set_callback(usbtoswd_write_callback);\n\t}\n\n\t/* Input buffer must be passed even for write operations. Otherwise\n\t * the callback function is not called and ack value is not set. */\n\treturn usbtoxxx_inout_command(USB_TO_SWD, interface_index, buff, 5, 5,\n\t\t(uint8_t *)data, 1, 4, 0);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <string.h>\n\n#include \"../versaloon_include.h\"\n#include \"../versaloon.h\"\n#include \"../versaloon_internal.h\"\n#include \"usbtoxxx.h\"\n#include \"usbtoxxx_internal.h\"\n\n#define N_A \"n/a\"\n\nstatic const char *types_name[96] = {\n\t\"usbtousart\", \"usbtospi\", \"usbtoi2c\", \"usbtogpio\", \"usbtocan\", \"usbtopwm\",\n\t\"usbtoadc\", \"usbtodac\",\n\t\"usbtomicrowire\", \"usbtoswim\", \"usbtodusi\", N_A, N_A, N_A, \"usbtopower\", \"usbtodelay\",\n\tN_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,\n\tN_A, N_A, N_A, N_A, N_A, N_A, N_A,\n\t\"usbtojtagll\", \"usbtojtaghl\", \"usbtoissp\", \"usbtoc2\", \"usbtosbw\",\n\t\"usbtolpcicp\", \"usbtoswd\", \"usbtojtagraw\",\n\t\"usbtobdm\", N_A, N_A, N_A, N_A, N_A, N_A, N_A,\n\tN_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A,\n\t\"usbtomsp430jtag\", N_A, N_A, N_A, N_A, N_A, N_A, N_A,\n\t\"usbtopower\", \"usbtodelay\", \"usbtopoll\", N_A, N_A, N_A, N_A, N_A,\n\tN_A, N_A, N_A, N_A, N_A, N_A, N_A, \"usbtoall\"\n};\n\nuint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN];\n\n#define usbtoxxx_get_type_name(type)\t\\\n\ttypes_name[((type) - VERSALOON_USB_TO_XXX_CMD_START) \\\n\t\t   % ARRAY_SIZE(types_name)]\n\nstatic uint8_t type_pre;\nstatic uint16_t usbtoxxx_buffer_index;\nstatic uint16_t usbtoxxx_current_cmd_index;\nstatic uint8_t *usbtoxxx_buffer;\n\nstatic uint16_t collect_index;\nstatic uint8_t collect_cmd;\nstatic uint8_t poll_nesting;\n\nstruct usbtoxxx_context_t {\n\tuint8_t type_pre;\n\tuint8_t *usbtoxxx_buffer;\n\tuint16_t usbtoxxx_current_cmd_index;\n\tuint16_t usbtoxxx_buffer_index;\n\tuint16_t versaloon_pending_idx;\n};\nstatic struct usbtoxxx_context_t poll_context;\n\nstatic void usbtoxxx_save_context(struct usbtoxxx_context_t *c)\n{\n\tc->type_pre = type_pre;\n\tc->usbtoxxx_buffer = usbtoxxx_buffer;\n\tc->usbtoxxx_buffer_index = usbtoxxx_buffer_index;\n\tc->usbtoxxx_current_cmd_index = usbtoxxx_current_cmd_index;\n\tc->versaloon_pending_idx = versaloon_pending_idx;\n}\n\nstatic void usbtoxxx_pop_context(struct usbtoxxx_context_t *c)\n{\n\ttype_pre = c->type_pre;\n\tusbtoxxx_buffer = c->usbtoxxx_buffer;\n\tusbtoxxx_buffer_index = c->usbtoxxx_buffer_index;\n\tusbtoxxx_current_cmd_index = c->usbtoxxx_current_cmd_index;\n\tversaloon_pending_idx = c->versaloon_pending_idx;\n}\n\nstatic RESULT usbtoxxx_validate_current_command_type(void)\n{\n\tif (type_pre > 0) {\n\t\t/* not the first command */\n\t\tif (!usbtoxxx_buffer) {\n\t\t\tLOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(usbtoxxx_buffer));\n\t\t\treturn ERRCODE_INVALID_BUFFER;\n\t\t}\n\n\t\tusbtoxxx_buffer[0] = type_pre;\n\t\tSET_LE_U16(&usbtoxxx_buffer[1], usbtoxxx_current_cmd_index);\n\n\t\tusbtoxxx_buffer_index += usbtoxxx_current_cmd_index;\n\t} else {\n\t\t/* first command */\n\t\tusbtoxxx_buffer_index = 3;\n\t}\n\n\t/* prepare for next command */\n\tusbtoxxx_current_cmd_index = 3;\n\tusbtoxxx_buffer = versaloon_buf + usbtoxxx_buffer_index;\n\n\tcollect_index = 0;\n\tcollect_cmd = 0;\n\n\treturn ERROR_OK;\n}\n\nRESULT usbtoxxx_execute_command(void)\n{\n\tuint16_t i;\n\tuint16_t inlen;\n\tRESULT result = ERROR_OK;\n\n\tif (poll_nesting) {\n\t\tLOG_BUG(ERRMSG_INVALID_USAGE, \"USB_TO_POLL\");\n\t\tversaloon_free_want_pos();\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\tversaloon_free_want_pos();\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tif (usbtoxxx_buffer_index == 3) {\n\t\tversaloon_free_want_pos();\n\t\treturn ERROR_OK;\n\t}\n\n\tversaloon_buf[0] = USB_TO_ALL;\n\tSET_LE_U16(&versaloon_buf[1], usbtoxxx_buffer_index);\n\n\tif (versaloon_send_command(usbtoxxx_buffer_index, &inlen) != ERROR_OK) {\n\t\tversaloon_free_want_pos();\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* process return data */\n\tusbtoxxx_buffer_index = 0;\n\tfor (i = 0; i < versaloon_pending_idx; i++) {\n\t\t/* check result */\n\t\tif ((i == 0) || !((versaloon_pending[i].collect)\n\t\t\t\t  && (versaloon_pending[i - 1].collect)\n\t\t\t\t  && (versaloon_pending[i].cmd\n\t\t\t\t      == versaloon_pending[i - 1].cmd))) {\n\t\t\tif (USB_TO_XXX_CMD_NOT_SUPPORT\n\t\t\t\t\t== versaloon_buf[usbtoxxx_buffer_index]) {\n\t\t\t\tLOG_ERROR(ERRMSG_NOT_SUPPORT_BY,\n\t\t\t\t\tusbtoxxx_get_type_name(versaloon_pending[i].type),\n\t\t\t\t\t\"current dongle\");\n\t\t\t\tresult = ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t} else if (versaloon_buf[usbtoxxx_buffer_index] != USB_TO_XXX_OK) {\n\t\t\t\tLOG_ERROR(\"%s command 0x%02x failed with 0x%02x\",\n\t\t\t\t\tusbtoxxx_get_type_name(versaloon_pending[i].type),\n\t\t\t\t\tversaloon_pending[i].cmd,\n\t\t\t\t\tversaloon_buf[usbtoxxx_buffer_index]);\n\t\t\t\tresult = ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tusbtoxxx_buffer_index++;\n\t\t}\n\n\t\t/* get result data */\n\t\tif (versaloon_pending[i].pos) {\n\t\t\tuint8_t processed = 0;\n\n\t\t\tif (versaloon_pending[i].callback) {\n\t\t\t\tversaloon_pending[i].callback(&versaloon_pending[i],\n\t\t\t\t\tversaloon_buf + usbtoxxx_buffer_index, &processed);\n\t\t\t}\n\t\t\tif (!processed) {\n\t\t\t\tstruct versaloon_want_pos_t *tmp;\n\n\t\t\t\ttmp = versaloon_pending[i].pos;\n\t\t\t\twhile (tmp) {\n\t\t\t\t\tif ((tmp->buff) && (tmp->size > 0)) {\n\t\t\t\t\t\tmemcpy(tmp->buff,\n\t\t\t\t\t\t\tversaloon_buf + usbtoxxx_buffer_index\n\t\t\t\t\t\t\t+ tmp->offset,\n\t\t\t\t\t\t\ttmp->size);\n\t\t\t\t\t}\n\t\t\t\t\tstruct versaloon_want_pos_t *free_tmp;\n\t\t\t\t\tfree_tmp = tmp;\n\t\t\t\t\ttmp = tmp->next;\n\t\t\t\t\tfree(free_tmp);\n\t\t\t\t}\n\t\t\t\tversaloon_pending[i].pos = NULL;\n\t\t\t}\n\t\t} else if ((versaloon_pending[i].want_data_size > 0)\n\t\t\t\t&& (versaloon_pending[i].data_buffer)) {\n\t\t\tuint8_t processed = 0;\n\n\t\t\tif (versaloon_pending[i].callback) {\n\t\t\t\tversaloon_pending[i].callback(&versaloon_pending[i],\n\t\t\t\t\tversaloon_buf + usbtoxxx_buffer_index, &processed);\n\t\t\t}\n\t\t\tif (!processed) {\n\t\t\t\tmemcpy(versaloon_pending[i].data_buffer,\n\t\t\t\t\tversaloon_buf + usbtoxxx_buffer_index\n\t\t\t\t\t+ versaloon_pending[i].want_data_pos,\n\t\t\t\t\tversaloon_pending[i].want_data_size);\n\t\t\t}\n\t\t}\n\t\tusbtoxxx_buffer_index += versaloon_pending[i].actual_data_size;\n\t\tif (usbtoxxx_buffer_index > inlen) {\n\t\t\tLOG_BUG(\"%s command 0x%02x process error\",\n\t\t\t\tusbtoxxx_get_type_name(versaloon_pending[i].type),\n\t\t\t\tversaloon_pending[i].cmd);\n\t\t\tresult = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* data is not the right size */\n\tif (inlen != usbtoxxx_buffer_index) {\n\t\tLOG_ERROR(ERRMSG_INVALID_TARGET, \"length of return data\");\n\t\tresult = ERROR_FAIL;\n\t}\n\n\tif (versaloon_pending_idx > 0)\n\t\tversaloon_pending_idx = 0;\n\telse {\n\t\t/* no receive data, avoid collision */\n\t\tsleep_ms(10);\n\t}\n\n\ttype_pre = 0;\n\tcollect_cmd = 0;\n\tcollect_index = 0;\n\tversaloon_free_want_pos();\n\treturn result;\n}\n\nRESULT usbtoxxx_init(void)\n{\n\tversaloon_pending_idx = 0;\n\n\tif ((usbtoinfo_get_abilities(usbtoxxx_abilities) != ERROR_OK) ||\n\t\t\t(usbtoxxx_execute_command() != ERROR_OK))\n\t\treturn ERROR_FAIL;\n\tLOG_INFO(\"USB_TO_XXX abilities: 0x%08X:0x%08X:0x%08X\",\n\t\tGET_LE_U32(&usbtoxxx_abilities[0]),\n\t\tGET_LE_U32(&usbtoxxx_abilities[4]),\n\t\tGET_LE_U32(&usbtoxxx_abilities[8]));\n\treturn ERROR_OK;\n}\n\nRESULT usbtoxxx_fini(void)\n{\n\tusbtoxxx_buffer = NULL;\n\ttype_pre = 0;\n\treturn ERROR_OK;\n}\n\nbool usbtoxxx_interface_supported(uint8_t cmd)\n{\n\tif ((cmd < VERSALOON_USB_TO_XXX_CMD_START) ||\n\t\t\t(cmd > VERSALOON_USB_TO_XXX_CMD_END))\n\t\treturn false;\n\n\tcmd -= VERSALOON_USB_TO_XXX_CMD_START;\n\treturn (usbtoxxx_abilities[cmd  / 8] & (1 << (cmd % 8))) > 0;\n}\n\nstatic RESULT usbtoxxx_ensure_buffer_size(uint16_t cmdlen)\n{\n\t/* check free space, commit if not enough */\n\tif (((usbtoxxx_buffer_index + usbtoxxx_current_cmd_index + cmdlen)\n\t\t\t>= versaloon_buf_size)\n\t\t\t|| (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER)) {\n\t\tstruct usbtoxxx_context_t context_tmp;\n\t\tuint8_t poll_nesting_tmp = 0;\n\n\t\tmemset(&context_tmp, 0, sizeof(context_tmp));\n\t\tif (poll_nesting) {\n\t\t\tif (poll_context.type_pre == 0) {\n\t\t\t\tLOG_BUG(\"USB_TO_POLL toooooo long\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\n\t\t\tusbtoxxx_save_context(&context_tmp);\n\t\t\tusbtoxxx_pop_context(&poll_context);\n\t\t\tpoll_nesting_tmp = poll_nesting;\n\t\t\tpoll_nesting = 0;\n\t\t}\n\n\t\tif (usbtoxxx_execute_command() != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (poll_nesting_tmp) {\n\t\t\tuint16_t newlen, oldlen;\n\n\t\t\tnewlen = context_tmp.versaloon_pending_idx\n\t\t\t\t- poll_context.versaloon_pending_idx;\n\t\t\tmemcpy(&versaloon_pending[0],\n\t\t\t\t&versaloon_pending[poll_context.versaloon_pending_idx],\n\t\t\t\tsizeof(versaloon_pending[0]) * newlen);\n\t\t\tcontext_tmp.versaloon_pending_idx = newlen;\n\t\t\toldlen = poll_context.usbtoxxx_buffer_index\n\t\t\t\t+ poll_context.usbtoxxx_current_cmd_index;\n\t\t\tnewlen = context_tmp.usbtoxxx_buffer_index\n\t\t\t\t+ context_tmp.usbtoxxx_current_cmd_index;\n\t\t\tmemcpy(versaloon_buf + 3, versaloon_buf + oldlen, newlen - oldlen);\n\t\t\toldlen -= 3;\n\t\t\tcontext_tmp.usbtoxxx_buffer -= oldlen;\n\t\t\tcontext_tmp.usbtoxxx_buffer_index -= oldlen;\n\t\t\tusbtoxxx_pop_context(&context_tmp);\n\t\t\tpoll_nesting = poll_nesting_tmp;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nRESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,\n\tuint16_t cmdlen, uint16_t retlen, uint8_t *wantbuf,\n\tuint16_t wantpos, uint16_t wantlen, uint8_t collect)\n{\n\tuint16_t len_tmp;\n\n\t/* 3 more bytes by usbtoxxx_validate_current_command_type */\n\t/* 3 more bytes when ((0 == collect_index) || (collect_cmd != cmd)) */\n\tif (usbtoxxx_ensure_buffer_size(cmdlen + 6) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif ((type_pre != type) || (!usbtoxxx_buffer)) {\n\t\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\t\treturn ERRCODE_FAILURE_OPERATION;\n\t\t}\n\t\ttype_pre = type;\n\t}\n\n\tif ((collect_index == 0) || (collect_cmd != cmd)) {\n\t\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = cmd;\n\n\t\tif (collect) {\n\t\t\tcollect_index = usbtoxxx_current_cmd_index;\n\t\t\tcollect_cmd = cmd;\n\t\t} else {\n\t\t\tcollect_index = 0;\n\t\t\tcollect_cmd = 0;\n\t\t}\n\t\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], cmdlen);\n\t\tusbtoxxx_current_cmd_index += 2;\n\t} else {\n\t\tlen_tmp = GET_LE_U16(&usbtoxxx_buffer[collect_index]) + cmdlen;\n\t\tSET_LE_U16(&usbtoxxx_buffer[collect_index], len_tmp);\n\t}\n\n\tif (cmdbuf) {\n\t\tmemcpy(usbtoxxx_buffer + usbtoxxx_current_cmd_index, cmdbuf, cmdlen);\n\t\tusbtoxxx_current_cmd_index += cmdlen;\n\t}\n\n\treturn versaloon_add_pending(type, cmd, retlen, wantpos, wantlen,\n\t\twantbuf, collect);\n}\n\nRESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN])\n{\n\tif (usbtoxxx_ensure_buffer_size(3) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\ttype_pre = USB_TO_INFO;\n\n\treturn versaloon_add_pending(USB_TO_INFO, 0, USB_TO_XXX_ABILITIES_LEN, 0,\n\t\tUSB_TO_XXX_ABILITIES_LEN, abilities, 0);\n}\n\nRESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us)\n{\n\tif (usbtoxxx_ensure_buffer_size(3 + 5) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (!poll_nesting)\n\t\tusbtoxxx_save_context(&poll_context);\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tpoll_nesting++;\n\ttype_pre = USB_TO_POLL;\n\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_START;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], retry_cnt);\n\tusbtoxxx_current_cmd_index += 2;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], interval_us);\n\tusbtoxxx_current_cmd_index += 2;\n\n\treturn versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);\n}\n\nRESULT usbtopoll_end(void)\n{\n\tif (!poll_nesting) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"check poll nesting\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tif (usbtoxxx_ensure_buffer_size(3 + 1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\tpoll_nesting--;\n\ttype_pre = USB_TO_POLL;\n\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_END;\n\n\treturn versaloon_add_pending(USB_TO_POLL, 0, 0, 0, 0, NULL, 0);\n}\n\nRESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size,\n\tuint32_t mask, uint32_t value)\n{\n\tuint8_t i;\n\n\tif (size > 4) {\n\t\tLOG_BUG(ERRMSG_INVALID_PARAMETER, __func__);\n\t\treturn ERRCODE_INVALID_PARAMETER;\n\t}\n\tif (!poll_nesting) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"check poll nesting\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tif (usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\ttype_pre = USB_TO_POLL;\n\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKOK;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);\n\tusbtoxxx_current_cmd_index += 2;\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;\n\tfor (i = 0; i < size; i++)\n\t\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;\n\tfor (i = 0; i < size; i++)\n\t\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;\n\n\treturn ERROR_OK;\n}\n\nRESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size,\n\tuint32_t mask, uint32_t value)\n{\n\tuint8_t i;\n\n\tif (size > 4) {\n\t\tLOG_BUG(ERRMSG_INVALID_PARAMETER, __func__);\n\t\treturn ERRCODE_INVALID_PARAMETER;\n\t}\n\tif (!poll_nesting) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"check poll nesting\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tif (usbtoxxx_ensure_buffer_size(3 + 4 + 2 * size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\ttype_pre = USB_TO_POLL;\n\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_CHECKFAIL;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);\n\tusbtoxxx_current_cmd_index += 2;\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = size;\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = equ;\n\tfor (i = 0; i < size; i++)\n\t\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (mask >> (8 * i)) & 0xFF;\n\tfor (i = 0; i < size; i++)\n\t\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = (value >> (8 * i)) & 0xFF;\n\n\treturn ERROR_OK;\n}\n\nRESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff)\n{\n\tif (!poll_nesting) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"check poll nesting\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\tif (usbtoxxx_ensure_buffer_size(3 + 5 + size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\ttype_pre = USB_TO_POLL;\n\n\tusbtoxxx_buffer[usbtoxxx_current_cmd_index++] = USB_TO_POLL_VERIFYBUFF;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], offset);\n\tusbtoxxx_current_cmd_index += 2;\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], size);\n\tusbtoxxx_current_cmd_index += 2;\n\tmemcpy(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], buff, size);\n\tusbtoxxx_current_cmd_index += size;\n\n\treturn ERROR_OK;\n}\n\nRESULT usbtodelay_delay(uint16_t dly)\n{\n\tif (usbtoxxx_ensure_buffer_size(3 + 2) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (usbtoxxx_validate_current_command_type() != ERROR_OK) {\n\t\tLOG_BUG(ERRMSG_FAILURE_OPERATION, \"validate previous commands\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\ttype_pre = USB_TO_DELAY;\n\n\tSET_LE_U16(&usbtoxxx_buffer[usbtoxxx_current_cmd_index], dly);\n\tusbtoxxx_current_cmd_index += 2;\n\n\treturn versaloon_add_pending(USB_TO_DELAY, 0, 0, 0, 0, NULL, 0);\n}\n\nRESULT usbtodelay_delayms(uint16_t ms)\n{\n\treturn usbtodelay_delay(ms | 0x8000);\n}\n\nRESULT usbtodelay_delayus(uint16_t us)\n{\n\treturn usbtodelay_delay(us & 0x7FFF);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H\n#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H\n\nRESULT usbtoxxx_init(void);\nRESULT usbtoxxx_fini(void);\nRESULT usbtoxxx_execute_command(void);\n\n#define USB_TO_XXX_ABILITIES_LEN                        12\nextern uint8_t usbtoxxx_abilities[USB_TO_XXX_ABILITIES_LEN];\nbool usbtoxxx_interface_supported(uint8_t cmd);\n\n/* USB_TO_INFO */\nRESULT usbtoinfo_get_abilities(uint8_t abilities[USB_TO_XXX_ABILITIES_LEN]);\n\n/* USB_TO_DELAY */\nRESULT usbtodelay_delay(uint16_t dly);\nRESULT usbtodelay_delayms(uint16_t ms);\nRESULT usbtodelay_delayus(uint16_t us);\n\n/* USB_TO_USART */\nRESULT usbtousart_init(uint8_t interface_index);\nRESULT usbtousart_fini(uint8_t interface_index);\nRESULT usbtousart_config(uint8_t interface_index, uint32_t baudrate,\n\t\t\t uint8_t datalength, uint8_t mode);\nRESULT usbtousart_send(uint8_t interface_index, uint8_t *buf, uint16_t len);\nRESULT usbtousart_receive(uint8_t interface_index, uint8_t *buf, uint16_t len);\nRESULT usbtousart_status(uint8_t interface_index,\n\t\t\t struct usart_status_t *status);\n\n/* USB_TO_SPI */\nRESULT usbtospi_init(uint8_t interface_index);\nRESULT usbtospi_fini(uint8_t interface_index);\nRESULT usbtospi_config(uint8_t interface_index, uint32_t khz, uint8_t mode);\nRESULT usbtospi_io(uint8_t interface_index, uint8_t *out, uint8_t *in,\n\t\t   uint16_t bytelen);\n\n/* USB_TO_GPIO */\nRESULT usbtogpio_init(uint8_t interface_index);\nRESULT usbtogpio_fini(uint8_t interface_index);\nRESULT usbtogpio_config(uint8_t interface_index, uint32_t mask,\n\t\t\tuint32_t dir_mask, uint32_t pull_en_mask,\n\t\t\tuint32_t input_pull_mask);\nRESULT usbtogpio_in(uint8_t interface_index, uint32_t mask, uint32_t *value);\nRESULT usbtogpio_out(uint8_t interface_index, uint32_t mask, uint32_t value);\n\n/* USB_TO_ISSP */\nRESULT usbtoissp_init(uint8_t interface_index);\nRESULT usbtoissp_fini(uint8_t interface_index);\nRESULT usbtoissp_enter_program_mode(uint8_t interface_index, uint8_t mode);\nRESULT usbtoissp_leave_program_mode(uint8_t interface_index, uint8_t mode);\nRESULT usbtoissp_wait_and_poll(uint8_t interface_index);\nRESULT usbtoissp_vector(uint8_t interface_index, uint8_t operate, uint8_t addr,\n\t\t\tuint8_t data, uint8_t *buf);\n\n/* USB_TO_LPCICP */\nRESULT usbtolpcicp_init(uint8_t interface_index);\nRESULT usbtolpcicp_fini(uint8_t interface_index);\nRESULT usbtolpcicp_config(uint8_t interface_index);\nRESULT usbtolpcicp_enter_program_mode(uint8_t interface_index);\nRESULT usbtolpcicp_in(uint8_t interface_index, uint8_t *buff, uint16_t len);\nRESULT usbtolpcicp_out(uint8_t interface_index, uint8_t *buff, uint16_t len);\nRESULT usbtolpcicp_poll_ready(uint8_t interface_index, uint8_t data,\n\t\t\t      uint8_t *ret, uint8_t setmask, uint8_t clearmask, uint16_t pollcnt);\n\n/* USB_TO_JTAG_LL */\nRESULT usbtojtagll_init(uint8_t interface_index);\nRESULT usbtojtagll_fini(uint8_t interface_index);\nRESULT usbtojtagll_config(uint8_t interface_index, uint32_t khz);\nRESULT usbtojtagll_tms(uint8_t interface_index, uint8_t *tms, uint8_t bytelen);\nRESULT usbtojtagll_tms_clocks(uint8_t interface_index, uint32_t bytelen,\n\t\t\t      uint8_t tms);\nRESULT usbtojtagll_scan(uint8_t interface_index, uint8_t *data,\n\t\t\tuint16_t bitlen, uint8_t tms_before_valid,\n\t\t\tuint8_t tms_before, uint8_t tms_after0,\n\t\t\tuint8_t tms_after1);\n\n/* USB_TO_JTAG_HL */\nRESULT usbtojtaghl_init(uint8_t interface_index);\nRESULT usbtojtaghl_fini(uint8_t interface_index);\nRESULT usbtojtaghl_config(uint8_t interface_index, uint32_t khz, uint8_t ub,\n\t\t\t  uint8_t ua, uint16_t bb, uint16_t ba);\nRESULT usbtojtaghl_ir(uint8_t interface_index, uint8_t *ir, uint16_t bitlen,\n\t\t      uint8_t idle, uint8_t want_ret);\nRESULT usbtojtaghl_dr(uint8_t interface_index, uint8_t *dr, uint16_t bitlen,\n\t\t      uint8_t idle, uint8_t want_ret);\nRESULT usbtojtaghl_tms(uint8_t interface_index, uint8_t *tms, uint16_t bitlen);\nRESULT usbtojtaghl_runtest(uint8_t interface_index, uint32_t cycles);\nRESULT usbtojtaghl_register_callback(uint8_t index, jtag_callback_t send_callback,\n\t\t\t\t     jtag_callback_t receive_callback);\n\n/* USB_TO_JTAG_RAW */\nRESULT usbtojtagraw_init(uint8_t interface_index);\nRESULT usbtojtagraw_fini(uint8_t interface_index);\nRESULT usbtojtagraw_config(uint8_t interface_index, uint32_t khz);\nRESULT usbtojtagraw_execute(uint8_t interface_index, uint8_t *tdi,\n\t\t\t    uint8_t *tms, uint8_t *tdo, uint32_t bitlen);\n\n/* USB_TO_C2 */\nRESULT usbtoc2_init(uint8_t interface_index);\nRESULT usbtoc2_fini(uint8_t interface_index);\nRESULT usbtoc2_writeaddr(uint8_t interface_index, uint8_t addr);\nRESULT usbtoc2_readaddr(uint8_t interface_index, uint8_t *data);\nRESULT usbtoc2_writedata(uint8_t interface_index, uint8_t *buf, uint8_t len);\nRESULT usbtoc2_readdata(uint8_t interface_index, uint8_t *buf, uint8_t len);\n\n/* USB_TO_I2C */\nRESULT usbtoi2c_init(uint8_t interface_index);\nRESULT usbtoi2c_fini(uint8_t interface_index);\nRESULT usbtoi2c_config(uint8_t interface_index, uint16_t khz,\n\t\t       uint16_t byte_interval, uint16_t max_dly);\nRESULT usbtoi2c_read(uint8_t interface_index, uint16_t chip_addr,\n\t\t     uint8_t *data, uint16_t data_len, uint8_t stop,\n\t\t     bool nacklast);\nRESULT usbtoi2c_write(uint8_t interface_index, uint16_t chip_addr,\n\t\t      uint8_t *data, uint16_t data_len, uint8_t stop);\n\n/* USB_TO_MSP430_JTAG */\nRESULT usbtomsp430jtag_init(uint8_t interface_index);\nRESULT usbtomsp430jtag_fini(uint8_t interface_index);\nRESULT usbtomsp430jtag_config(uint8_t interface_index, uint8_t has_test);\nRESULT usbtomsp430jtag_ir(uint8_t interface_index, uint8_t *ir,\n\t\t\t  uint8_t want_ret);\nRESULT usbtomsp430jtag_dr(uint8_t interface_index, uint32_t *dr,\n\t\t\t  uint8_t bitlen, uint8_t want_ret);\nRESULT usbtomsp430jtag_tclk(uint8_t interface_index, uint8_t value);\nRESULT usbtomsp430jtag_tclk_strobe(uint8_t interface_index, uint16_t cnt);\nRESULT usbtomsp430jtag_reset(uint8_t interface_index);\nRESULT usbtomsp430jtag_poll(uint8_t interface_index, uint32_t dr,\n\t\t\t    uint32_t mask, uint32_t value, uint8_t len,\n\t\t\t    uint16_t poll_cnt, uint8_t toggle_tclk);\n\n/* USB_TO_MSP430_SBW */\nRESULT usbtomsp430sbw_init(uint8_t interface_index);\nRESULT usbtomsp430sbw_fini(uint8_t interface_index);\nRESULT usbtomsp430sbw_config(uint8_t interface_index, uint8_t has_test);\nRESULT usbtomsp430sbw_ir(uint8_t interface_index, uint8_t *ir,\n\t\t\t uint8_t want_ret);\nRESULT usbtomsp430sbw_dr(uint8_t interface_index, uint32_t *dr,\n\t\t\t uint8_t bitlen, uint8_t want_ret);\nRESULT usbtomsp430sbw_tclk(uint8_t interface_index, uint8_t value);\nRESULT usbtomsp430sbw_tclk_strobe(uint8_t interface_index, uint16_t cnt);\nRESULT usbtomsp430sbw_reset(uint8_t interface_index);\nRESULT usbtomsp430sbw_poll(uint8_t interface_index, uint32_t dr, uint32_t mask,\n\t\t\t   uint32_t value, uint8_t len, uint16_t poll_cnt,\n\t\t\t   uint8_t toggle_tclk);\n\n/* USB_TO_POWER */\nRESULT usbtopwr_init(uint8_t interface_index);\nRESULT usbtopwr_fini(uint8_t interface_index);\nRESULT usbtopwr_config(uint8_t interface_index);\nRESULT usbtopwr_output(uint8_t interface_index, uint16_t millivolt);\n\n/* USB_TO_POLL */\nRESULT usbtopoll_start(uint16_t retry_cnt, uint16_t interval_us);\nRESULT usbtopoll_end(void);\nRESULT usbtopoll_checkok(uint8_t equ, uint16_t offset, uint8_t size,\n\t\t\t uint32_t mask, uint32_t value);\nRESULT usbtopoll_checkfail(uint8_t equ, uint16_t offset, uint8_t size,\n\t\t\t   uint32_t mask, uint32_t value);\nRESULT usbtopoll_verifybuff(uint16_t offset, uint16_t size, uint8_t *buff);\n\n/* USB_TO_SWD */\nRESULT usbtoswd_init(uint8_t interface_index);\nRESULT usbtoswd_fini(uint8_t interface_index);\nRESULT usbtoswd_config(uint8_t interface_index, uint8_t trn, uint16_t retry,\n\t\t       uint16_t dly);\nRESULT usbtoswd_seqout(uint8_t interface_index, const uint8_t *data,\n\t\t       uint16_t bitlen);\nRESULT usbtoswd_seqin(uint8_t interface_index, uint8_t *data, uint16_t bitlen);\nRESULT usbtoswd_transact(uint8_t interface_index, uint8_t request,\n\t\t\t uint32_t *data, uint8_t *ack);\n\n/* USB_TO_SWIM */\nRESULT usbtoswim_init(uint8_t interface_index);\nRESULT usbtoswim_fini(uint8_t interface_index);\nRESULT usbtoswim_config(uint8_t interface_index, uint8_t mhz, uint8_t cnt0,\n\t\t\tuint8_t cnt1);\nRESULT usbtoswim_srst(uint8_t interface_index);\nRESULT usbtoswim_wotf(uint8_t interface_index, uint8_t *data,\n\t\t      uint16_t bytelen, uint32_t addr);\nRESULT usbtoswim_rotf(uint8_t interface_index, uint8_t *data,\n\t\t      uint16_t bytelen, uint32_t addr);\nRESULT usbtoswim_sync(uint8_t interface_index, uint8_t mhz);\nRESULT usbtoswim_enable(uint8_t interface_index);\n\n/* USB_TO_BDM */\nRESULT usbtobdm_init(uint8_t interface_index);\nRESULT usbtobdm_fini(uint8_t interface_index);\nRESULT usbtobdm_sync(uint8_t interface_index, uint16_t *khz);\nRESULT usbtobdm_transact(uint8_t interface_index, uint8_t *out,\n\t\t\t uint8_t outlen, uint8_t *in, uint8_t inlen, uint8_t delay, uint8_t ack);\n\n/* USB_TO_DUSI */\nRESULT usbtodusi_init(uint8_t interface_index);\nRESULT usbtodusi_fini(uint8_t interface_index);\nRESULT usbtodusi_config(uint8_t interface_index, uint32_t khz, uint8_t mode);\nRESULT usbtodusi_io(uint8_t interface_index, uint8_t *mo, uint8_t *mi,\n\t\t    uint8_t *so, uint8_t *si, uint32_t bitlen);\n\n/* USB_TO_MICROWIRE */\nRESULT usbtomicrowire_init(uint8_t interface_index);\nRESULT usbtomicrowire_fini(uint8_t interface_index);\nRESULT usbtomicrowire_config(uint8_t interface_index, uint16_t khz,\n\t\t\t     uint8_t sel_polarity);\nRESULT usbtomicrowire_transport(uint8_t interface_index,\n\t\t\t\tuint32_t opcode, uint8_t opcode_bitlen,\n\t\t\t\tuint32_t addr, uint8_t addr_bitlen,\n\t\t\t\tuint32_t data, uint8_t data_bitlen,\n\t\t\t\tuint8_t *reply, uint8_t reply_bitlen);\nRESULT usbtomicrowire_poll(uint8_t interface_index, uint16_t interval_us,\n\t\t\t   uint16_t retry_cnt);\n\n/* USB_TO_PWM */\nRESULT usbtopwm_init(uint8_t interface_index);\nRESULT usbtopwm_fini(uint8_t interface_index);\nRESULT usbtopwm_config(uint8_t interface_index, uint16_t khz, uint8_t mode);\nRESULT usbtopwm_out(uint8_t interface_index, uint16_t count, uint16_t *rate);\nRESULT usbtopwm_in(uint8_t interface_index, uint16_t count, uint16_t *rate);\n\n#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/usbtoxxx/usbtoxxx_internal.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H\n#define OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H\n\n/* USB_TO_XXX USB Commands */\n/* Page0 */\n#define USB_TO_USART                            (VERSALOON_USB_TO_XXX_CMD_START + 0x00)\n#define USB_TO_SPI                              (VERSALOON_USB_TO_XXX_CMD_START + 0x01)\n#define USB_TO_I2C                              (VERSALOON_USB_TO_XXX_CMD_START + 0x02)\n#define USB_TO_GPIO                             (VERSALOON_USB_TO_XXX_CMD_START + 0x03)\n#define USB_TO_CAN                              (VERSALOON_USB_TO_XXX_CMD_START + 0x04)\n#define USB_TO_PWM                              (VERSALOON_USB_TO_XXX_CMD_START + 0x05)\n#define USB_TO_ADC                              (VERSALOON_USB_TO_XXX_CMD_START + 0x06)\n#define USB_TO_DAC                              (VERSALOON_USB_TO_XXX_CMD_START + 0x07)\n#define USB_TO_MICROWIRE                        (VERSALOON_USB_TO_XXX_CMD_START + 0x08)\n#define USB_TO_SWIM                             (VERSALOON_USB_TO_XXX_CMD_START + 0x09)\n#define USB_TO_DUSI                             (VERSALOON_USB_TO_XXX_CMD_START + 0x0A)\n/* Page1 */\n#define USB_TO_JTAG_LL                          (VERSALOON_USB_TO_XXX_CMD_START + 0x20)\n#define USB_TO_JTAG_HL                          (VERSALOON_USB_TO_XXX_CMD_START + 0x21)\n#define USB_TO_ISSP                             (VERSALOON_USB_TO_XXX_CMD_START + 0x22)\n#define USB_TO_C2                               (VERSALOON_USB_TO_XXX_CMD_START + 0x23)\n#define USB_TO_SBW                              (VERSALOON_USB_TO_XXX_CMD_START + 0x24)\n#define USB_TO_LPCICP                           (VERSALOON_USB_TO_XXX_CMD_START + 0x25)\n#define USB_TO_SWD                              (VERSALOON_USB_TO_XXX_CMD_START + 0x26)\n#define USB_TO_JTAG_RAW                         (VERSALOON_USB_TO_XXX_CMD_START + 0x27)\n#define USB_TO_BDM                              (VERSALOON_USB_TO_XXX_CMD_START + 0x28)\n#define USB_TO_MSP430_JTAG                      (VERSALOON_USB_TO_XXX_CMD_START + 0x38)\n/* Page2 */\n#define USB_TO_POWER                            (VERSALOON_USB_TO_XXX_CMD_START + 0x40)\n#define USB_TO_DELAY                            (VERSALOON_USB_TO_XXX_CMD_START + 0x41)\n#define USB_TO_POLL                             (VERSALOON_USB_TO_XXX_CMD_START + 0x42)\n#define USB_TO_INFO                             (VERSALOON_USB_TO_XXX_CMD_START + 0x5E)\n#define USB_TO_ALL                              (VERSALOON_USB_TO_XXX_CMD_START + 0x5F)\n\n/* USB_TO_XXX Masks */\n#define USB_TO_XXX_CMDMASK                      0xF8\n#define USB_TO_XXX_CMDSHIFT                     3\n#define USB_TO_XXX_IDXMASK                      0x07\n/* USB_TO_XXX Sub Commands */\n/* Common Sub Commands */\n#define USB_TO_XXX_INIT                         (0x00 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_FINI                         (0x01 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_CONFIG                       (0x02 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_GETHWINFO                    (0x03 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_STATUS                       (0X04 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_IN_OUT                       (0x05 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_IN                           (0x06 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_OUT                          (0x07 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_POLL                         (0x08 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_SPECIAL                      (0x09 << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_RESET                        (0x0A << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_SYNC                         (0x0B << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_ENABLE                       (0x0C << USB_TO_XXX_CMDSHIFT)\n#define USB_TO_XXX_DISABLE                      (0x0D << USB_TO_XXX_CMDSHIFT)\n/* USB_TO_POLL */\n#define USB_TO_POLL_START                       0x00\n#define USB_TO_POLL_END                         0x01\n#define USB_TO_POLL_CHECKOK                     0x02\n#define USB_TO_POLL_CHECKFAIL                   0x03\n#define USB_TO_POLL_VERIFYBUFF                  0x04\n\n/* USB_TO_XXX Replies */\n#define USB_TO_XXX_OK                           0x00\n#define USB_TO_XXX_FAILED                       0x01\n#define USB_TO_XXX_TIME_OUT                     0x02\n#define USB_TO_XXX_INVALID_INDEX                0x03\n#define USB_TO_XXX_INVALID_PARA                 0x04\n#define USB_TO_XXX_INVALID_CMD                  0x05\n#define USB_TO_XXX_CMD_NOT_SUPPORT              0x06\n\n/* USB_TO_XXX */\nRESULT usbtoxxx_add_pending(uint8_t type, uint8_t cmd, uint16_t\n\t\tactual_szie, uint16_t want_pos,\n\t\tuint16_t want_size, uint8_t *buffer);\n\nRESULT usbtoxxx_add_command(uint8_t type, uint8_t cmd, uint8_t *cmdbuf,\n\t\tuint16_t cmdlen, uint16_t retlen,\n\t\tuint8_t *wantbuf, uint16_t wantpos,\n\t\tuint16_t wantlen, uint8_t collect);\n\n#define usbtoxxx_init_command(type, port)\t\t\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_INIT | (port)), \\\n\tNULL, 0, 0, NULL, 0, 0, 0)\n#define usbtoxxx_fini_command(type, port)\t\t\t\t\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_FINI | (port)), \\\n\tNULL, 0, 0, NULL, 0, 0, 0)\n#define usbtoxxx_conf_command(type, port, cmdbuf, cmdlen)\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_CONFIG | (port)), \\\n\t(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)\n#define usbtoxxx_inout_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \\\n\twantpos, wantlen, c)\t\t\t\t\t\t    \\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_IN_OUT | (port)), \\\n\t(cmdbuf), (cmdlen), (retlen), (wantbuf), \\\n\t(wantpos), (wantlen), (c))\n#define usbtoxxx_in_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \\\n\t\twantpos, wantlen, c)\t\t\t\t\t\t    \\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_IN | (port)), (cmdbuf), \\\n\t(cmdlen), (retlen), (wantbuf), (wantpos), \\\n\t(wantlen), (c))\n#define usbtoxxx_out_command(type, port, cmdbuf, cmdlen, c)\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_OUT | (port)), (cmdbuf), \\\n\t(cmdlen), 0, NULL, 0, 0, (c))\n#define usbtoxxx_poll_command(type, port, cmdbuf, cmdlen, retbuf, retlen)\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_POLL | (port)), (cmdbuf), \\\n\t(cmdlen), (retlen), (retbuf), 0, (retlen), 0)\n#define usbtoxxx_status_command(type, port, retlen, wantbuf, wantpos, wantlen, c) \\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_STATUS | (port)), \\\n\tNULL, 0, (retlen), (wantbuf), (wantpos), \\\n\t(wantlen), (c))\n#define usbtoxxx_special_command(type, port, cmdbuf, cmdlen, retlen, wantbuf, \\\n\twantpos, wantlen, c)\t\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_SPECIAL | (port)), \\\n\t(cmdbuf), (cmdlen), retlen, wantbuf, \\\n\twantpos, wantlen, (c))\n#define usbtoxxx_reset_command(type, port, cmdbuf, cmdlen)\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_RESET | (port)), \\\n\t(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)\n#define usbtoxxx_sync_command(type, port, cmdbuf, cmdlen, retlen, wantbuf)\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_SYNC | (port)), \\\n\t(cmdbuf), (cmdlen), (retlen), (wantbuf), 0, \\\n\t(retlen), 0)\n#define usbtoxxx_enable_command(type, port, cmdbuf, cmdlen)\t\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_ENABLE | (port)), \\\n\t(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)\n#define usbtoxxx_disable_command(type, port, cmdbuf, cmdlen)\t\t\t\t\\\n\tusbtoxxx_add_command((type), (USB_TO_XXX_DISABLE | (port)), \\\n\t(cmdbuf), (cmdlen), 0, NULL, 0, 0, 0)\n\n/* USB_TO_SPI */\n#define USB_TO_SPI_BAUDRATE_MSK\t\t0x1F\n#define USB_TO_SPI_CPOL_MSK\t\t\t0x20\n#define USB_TO_SPI_CPHA_MSK\t\t\t0x40\n#define USB_TO_SPI_MSB_FIRST\t\t0x80\n\n/* USB_TO_DUSI */\n#define USB_TO_DUSI_BAUDRATE_MSK\t0x1F\n#define USB_TO_DUSI_CPOL_MSK\t\t0x20\n#define USB_TO_DUSI_CPHA_MSK\t\t0x40\n#define USB_TO_DUSI_MSB_FIRST\t\t0x80\n\n/* USB_TO_GPIO */\n#define USB_TO_GPIO_DIR_MSK\t\t\t0x01\n\n#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_USBTOXXX_USBTOXXX_INTERNAL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/versaloon.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"versaloon_include.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <libusb.h>\n\n#include \"versaloon.h\"\n#include \"versaloon_internal.h\"\n#include \"usbtoxxx/usbtoxxx.h\"\n\nuint8_t *versaloon_buf;\nuint8_t *versaloon_cmd_buf;\nuint16_t versaloon_buf_size;\n\nstruct versaloon_pending_t versaloon_pending[VERSALOON_MAX_PENDING_NUMBER];\nuint16_t versaloon_pending_idx;\n\nstruct libusb_device_handle *versaloon_usb_device_handle;\nstatic uint32_t versaloon_usb_to = VERSALOON_TIMEOUT;\n\nstatic RESULT versaloon_init(void);\nstatic RESULT versaloon_fini(void);\nstatic RESULT versaloon_get_target_voltage(uint16_t *voltage);\nstatic RESULT versaloon_set_target_voltage(uint16_t voltage);\nstatic RESULT versaloon_delay_ms(uint16_t ms);\nstatic RESULT versaloon_delay_us(uint16_t us);\n\nstruct versaloon_interface_t versaloon_interface = {\n\t.init\t\t\t\t= versaloon_init,\n\t.fini\t\t\t\t= versaloon_fini,\n\t{\t/* adaptors */\n\t\t{\t/* target_voltage */\n\t\t\t.get\t\t= versaloon_get_target_voltage,\n\t\t\t.set\t\t= versaloon_set_target_voltage,\n\t\t},\n\t\t{\t/* gpio */\n\t\t\t.init\t\t= usbtogpio_init,\n\t\t\t.fini\t\t= usbtogpio_fini,\n\t\t\t.config\t\t= usbtogpio_config,\n\t\t\t.out\t\t= usbtogpio_out,\n\t\t\t.in\t\t\t= usbtogpio_in,\n\t\t},\n\t\t{\t/* delay */\n\t\t\t.delayms\t= versaloon_delay_ms,\n\t\t\t.delayus\t= versaloon_delay_us,\n\t\t},\n\t\t{\t/* swd */\n\t\t\t.init\t\t= usbtoswd_init,\n\t\t\t.fini\t\t= usbtoswd_fini,\n\t\t\t.config\t\t= usbtoswd_config,\n\t\t\t.seqout\t\t= usbtoswd_seqout,\n\t\t\t.seqin\t\t= usbtoswd_seqin,\n\t\t\t.transact\t= usbtoswd_transact,\n\t\t},\n\t\t{\t/* jtag_raw */\n\t\t\t.init\t\t= usbtojtagraw_init,\n\t\t\t.fini\t\t= usbtojtagraw_fini,\n\t\t\t.config\t\t= usbtojtagraw_config,\n\t\t\t.execute\t= usbtojtagraw_execute,\n\t\t},\n\t\t.peripheral_commit = usbtoxxx_execute_command,\n\t},\n\t{\t/* usb_setting */\n\t\t.vid\t\t\t= VERSALOON_VID,\n\t\t.pid\t\t\t= VERSALOON_PID,\n\t\t.ep_out\t\t\t= VERSALOON_OUTP,\n\t\t.ep_in\t\t\t= VERSALOON_INP,\n\t\t.interface\t\t= VERSALOON_IFACE,\n\t\t.buf_size\t\t= 256,\n\t}\n};\n\n/* programmer_cmd */\nstatic uint32_t versaloon_pending_id;\nstatic versaloon_callback_t versaloon_callback;\nstatic void *versaloon_extra_data;\nstatic struct versaloon_want_pos_t *versaloon_want_pos;\n\nvoid versaloon_set_pending_id(uint32_t id)\n{\n\tversaloon_pending_id = id;\n}\nvoid versaloon_set_callback(versaloon_callback_t callback)\n{\n\tversaloon_callback = callback;\n}\nvoid versaloon_set_extra_data(void *p)\n{\n\tversaloon_extra_data = p;\n}\n\nvoid versaloon_free_want_pos(void)\n{\n\tuint16_t i;\n\tstruct versaloon_want_pos_t *tmp, *free_tmp;\n\n\ttmp = versaloon_want_pos;\n\twhile (tmp) {\n\t\tfree_tmp = tmp;\n\t\ttmp = tmp->next;\n\t\tfree(free_tmp);\n\t}\n\tversaloon_want_pos = NULL;\n\n\tfor (i = 0; i < ARRAY_SIZE(versaloon_pending); i++) {\n\t\ttmp = versaloon_pending[i].pos;\n\t\twhile (tmp) {\n\t\t\tfree_tmp = tmp;\n\t\t\ttmp = tmp->next;\n\t\t\tfree(free_tmp);\n\t\t}\n\t\tversaloon_pending[i].pos = NULL;\n\t}\n}\n\nRESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff)\n{\n\tstruct versaloon_want_pos_t *new_pos = NULL;\n\n\tnew_pos = malloc(sizeof(*new_pos));\n\tif (!new_pos) {\n\t\tLOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);\n\t\treturn ERRCODE_NOT_ENOUGH_MEMORY;\n\t}\n\tnew_pos->offset = offset;\n\tnew_pos->size = size;\n\tnew_pos->buff = buff;\n\tnew_pos->next = NULL;\n\n\tif (!versaloon_want_pos)\n\t\tversaloon_want_pos = new_pos;\n\telse {\n\t\tstruct versaloon_want_pos_t *tmp = versaloon_want_pos;\n\n\t\twhile (tmp->next)\n\t\t\ttmp = tmp->next;\n\t\ttmp->next = new_pos;\n\t}\n\n\treturn ERROR_OK;\n}\n\nRESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie,\n\tuint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect)\n{\n#if PARAM_CHECK\n\tif (versaloon_pending_idx >= VERSALOON_MAX_PENDING_NUMBER) {\n\t\tLOG_BUG(ERRMSG_INVALID_INDEX, versaloon_pending_idx,\n\t\t\t\"versaloon pending data\");\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\n\tversaloon_pending[versaloon_pending_idx].type = type;\n\tversaloon_pending[versaloon_pending_idx].cmd = cmd;\n\tversaloon_pending[versaloon_pending_idx].actual_data_size = actual_szie;\n\tversaloon_pending[versaloon_pending_idx].want_data_pos = want_pos;\n\tversaloon_pending[versaloon_pending_idx].want_data_size = want_size;\n\tversaloon_pending[versaloon_pending_idx].data_buffer = buffer;\n\tversaloon_pending[versaloon_pending_idx].collect = collect;\n\tversaloon_pending[versaloon_pending_idx].id = versaloon_pending_id;\n\tversaloon_pending_id = 0;\n\tversaloon_pending[versaloon_pending_idx].extra_data = versaloon_extra_data;\n\tversaloon_extra_data = NULL;\n\tversaloon_pending[versaloon_pending_idx].callback = versaloon_callback;\n\tversaloon_callback = NULL;\n\tversaloon_pending[versaloon_pending_idx].pos = versaloon_want_pos;\n\tversaloon_want_pos = NULL;\n\tversaloon_pending_idx++;\n\n\treturn ERROR_OK;\n}\n\nRESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen)\n{\n\tint ret;\n\tint transferred;\n\n#if PARAM_CHECK\n\tif (!versaloon_buf) {\n\t\tLOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf));\n\t\treturn ERRCODE_INVALID_BUFFER;\n\t}\n\tif ((out_len == 0) || (out_len > versaloon_interface.usb_setting.buf_size)) {\n\t\tLOG_BUG(ERRMSG_INVALID_PARAMETER, __func__);\n\t\treturn ERRCODE_INVALID_PARAMETER;\n\t}\n#endif\n\n\tret = libusb_bulk_transfer(versaloon_usb_device_handle,\n\t\t\tversaloon_interface.usb_setting.ep_out,\n\t\t\tversaloon_buf, out_len, &transferred, versaloon_usb_to);\n\tif (ret != 0 || transferred != out_len) {\n\t\tLOG_ERROR(ERRMSG_FAILURE_OPERATION, \"send usb data\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\tif (inlen) {\n\t\tret = libusb_bulk_transfer(versaloon_usb_device_handle,\n\t\t\tversaloon_interface.usb_setting.ep_in,\n\t\t\tversaloon_buf, versaloon_interface.usb_setting.buf_size,\n\t\t\t&transferred, versaloon_usb_to);\n\t\tif (ret == 0) {\n\t\t\t*inlen = (uint16_t)transferred;\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tLOG_ERROR(ERRMSG_FAILURE_OPERATION, \"receive usb data\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else\n\t\treturn ERROR_OK;\n}\n\n#define VERSALOON_RETRY_CNT 10\nstatic RESULT versaloon_init(void)\n{\n\tuint16_t ret = 0;\n\tuint8_t retry;\n\tuint32_t timeout_tmp;\n\n\t/* malloc temporary buffer */\n\tversaloon_buf = malloc(versaloon_interface.usb_setting.buf_size);\n\tif (!versaloon_buf) {\n\t\tLOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);\n\t\treturn ERRCODE_NOT_ENOUGH_MEMORY;\n\t}\n\n\t/* connect to versaloon */\n\ttimeout_tmp = versaloon_usb_to;\n\t/* not output error message when connecting */\n\t/* 100ms delay when connect */\n\tversaloon_usb_to = 100;\n\tfor (retry = 0; retry < VERSALOON_RETRY_CNT; retry++) {\n\t\tversaloon_buf[0] = VERSALOON_GET_INFO;\n\t\tif ((versaloon_send_command(1, &ret) == ERROR_OK) && (ret >= 3))\n\t\t\tbreak;\n\t}\n\tversaloon_usb_to = timeout_tmp;\n\tif (retry == VERSALOON_RETRY_CNT) {\n\t\tversaloon_fini();\n\t\tLOG_ERROR(ERRMSG_FAILURE_OPERATION, \"communicate with versaloon\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t}\n\n\tversaloon_buf[ret] = 0;\n\tversaloon_buf_size = versaloon_buf[0] + (versaloon_buf[1] << 8);\n\tversaloon_interface.usb_setting.buf_size = versaloon_buf_size;\n\tLOG_INFO(\"%s\", versaloon_buf + 2);\n\n\t/* free temporary buffer */\n\tfree(versaloon_buf);\n\tversaloon_buf = NULL;\n\n\tversaloon_buf = malloc(versaloon_interface.usb_setting.buf_size);\n\tif (!versaloon_buf) {\n\t\tversaloon_fini();\n\t\tLOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);\n\t\treturn ERRCODE_NOT_ENOUGH_MEMORY;\n\t}\n\tversaloon_cmd_buf = malloc(versaloon_interface.usb_setting.buf_size - 3);\n\tif (!versaloon_cmd_buf) {\n\t\tversaloon_fini();\n\t\tLOG_ERROR(ERRMSG_NOT_ENOUGH_MEMORY);\n\t\treturn ERRCODE_NOT_ENOUGH_MEMORY;\n\t}\n\tif (usbtoxxx_init() != ERROR_OK) {\n\t\tLOG_ERROR(ERRMSG_FAILURE_OPERATION, \"initialize usbtoxxx\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn versaloon_get_target_voltage(&ret);\n}\n\nstatic RESULT versaloon_fini(void)\n{\n\tif (versaloon_usb_device_handle) {\n\t\tusbtoxxx_fini();\n\t\tversaloon_free_want_pos();\n\n\t\tversaloon_usb_device_handle = NULL;\n\n\t\tfree(versaloon_buf);\n\t\tversaloon_buf = NULL;\n\n\t\tfree(versaloon_cmd_buf);\n\t\tversaloon_cmd_buf = NULL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic RESULT versaloon_set_target_voltage(uint16_t voltage)\n{\n\tusbtopwr_init(0);\n\tusbtopwr_config(0);\n\tusbtopwr_output(0, voltage);\n\tusbtopwr_fini(0);\n\n\treturn usbtoxxx_execute_command();\n}\n\nstatic RESULT versaloon_get_target_voltage(uint16_t *voltage)\n{\n\tuint16_t inlen;\n\n#if PARAM_CHECK\n\tif (!versaloon_buf) {\n\t\tLOG_BUG(ERRMSG_INVALID_BUFFER, TO_STR(versaloon_buf));\n\t\treturn ERRCODE_INVALID_BUFFER;\n\t}\n\tif (!voltage) {\n\t\tLOG_BUG(ERRMSG_INVALID_PARAMETER, __func__);\n\t\treturn ERRCODE_INVALID_PARAMETER;\n\t}\n#endif\n\n\tversaloon_buf[0] = VERSALOON_GET_TVCC;\n\n\tif ((versaloon_send_command(1, &inlen) != ERROR_OK) || (inlen != 2)) {\n\t\tLOG_ERROR(ERRMSG_FAILURE_OPERATION, \"communicate with versaloon\");\n\t\treturn ERRCODE_FAILURE_OPERATION;\n\t} else {\n\t\t*voltage = versaloon_buf[0] + (versaloon_buf[1] << 8);\n\t\treturn ERROR_OK;\n\t}\n}\n\nstatic RESULT versaloon_delay_ms(uint16_t ms)\n{\n\treturn usbtodelay_delay(ms | 0x8000);\n}\n\nstatic RESULT versaloon_delay_us(uint16_t us)\n{\n\treturn usbtodelay_delay(us & 0x7FFF);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/versaloon.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com>            *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H\n#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H\n\n#include <libusb.h>\n\nstruct usart_status_t {\n\tuint32_t tx_buff_avail;\n\tuint32_t tx_buff_size;\n\tuint32_t rx_buff_avail;\n\tuint32_t rx_buff_size;\n};\n\n#include \"usbtoxxx/usbtoxxx.h\"\n\n/* GPIO pins */\n#define GPIO_SRST\t\t\t\t(1 << 0)\n#define GPIO_TRST\t\t\t\t(1 << 1)\n#define GPIO_USR1\t\t\t\t(1 << 2)\n#define GPIO_USR2\t\t\t\t(1 << 3)\n#define GPIO_TCK\t\t\t\t(1 << 4)\n#define GPIO_TDO\t\t\t\t(1 << 5)\n#define GPIO_TDI\t\t\t\t(1 << 6)\n#define GPIO_RTCK\t\t\t\t(1 << 7)\n#define GPIO_TMS\t\t\t\t(1 << 8)\n\nstruct interface_gpio_t {\n\tRESULT(*init)(uint8_t interface_index);\n\tRESULT(*fini)(uint8_t interface_index);\n\tRESULT(*config)(uint8_t interface_index, uint32_t pin_mask, uint32_t io,\n\t\t\tuint32_t pull_en_mask, uint32_t input_pull_mask);\n\tRESULT(*out)(uint8_t interface_index, uint32_t pin_mask, uint32_t value);\n\tRESULT(*in)(uint8_t interface_index, uint32_t pin_mask, uint32_t *value);\n};\n\nstruct interface_delay_t {\n\tRESULT(*delayms)(uint16_t ms);\n\tRESULT(*delayus)(uint16_t us);\n};\n\nstruct interface_swd_t {\n\tRESULT(*init)(uint8_t interface_index);\n\tRESULT(*fini)(uint8_t interface_index);\n\tRESULT(*config)(uint8_t interface_index, uint8_t trn, uint16_t retry,\n\t\tuint16_t dly);\n\tRESULT(*seqout)(uint8_t interface_index, const uint8_t *data,\n\t\t\tuint16_t bitlen);\n\tRESULT(*seqin)(uint8_t interface_index, uint8_t *data, uint16_t bitlen);\n\tRESULT(*transact)(uint8_t interface_index, uint8_t request,\n\t\tuint32_t *data, uint8_t *ack);\n};\n\nstruct interface_jtag_raw_t {\n\tRESULT(*init)(uint8_t interface_index);\n\tRESULT(*fini)(uint8_t interface_index);\n\tRESULT(*config)(uint8_t interface_index, uint32_t khz);\n\tRESULT(*execute)(uint8_t interface_index, uint8_t *tdi, uint8_t *tms,\n\t\tuint8_t *tdo, uint32_t bitlen);\n};\n\nstruct interface_target_voltage_t {\n\tRESULT(*get)(uint16_t *voltage);\n\tRESULT(*set)(uint16_t voltage);\n};\n\nstruct versaloon_adaptors_t {\n\tstruct interface_target_voltage_t target_voltage;\n\tstruct interface_gpio_t gpio;\n\tstruct interface_delay_t delay;\n\tstruct interface_swd_t swd;\n\tstruct interface_jtag_raw_t jtag_raw;\n\tRESULT(*peripheral_commit)(void);\n};\n\nstruct versaloon_usb_setting_t {\n\tuint16_t vid;\n\tuint16_t pid;\n\tuint8_t ep_out;\n\tuint8_t ep_in;\n\tuint8_t interface;\n\tuint16_t buf_size;\n};\n\nstruct versaloon_interface_t {\n\tRESULT(*init)(void);\n\tRESULT(*fini)(void);\n\tstruct versaloon_adaptors_t adaptors;\n\tstruct versaloon_usb_setting_t usb_setting;\n};\n\nextern struct versaloon_interface_t versaloon_interface;\nextern struct libusb_device_handle *versaloon_usb_device_handle;\n\n#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/versaloon_include.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian <SimonQian@SimonQian.com>            *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H\n#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H\n\n#include \"helper/system.h\"\n/* This file is used to include different header and macros */\n/* according to different platform */\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n\n#define PARAM_CHECK\t\t\t\t\t\t\t1\n\n#define sleep_ms(ms)\t\t\t\t\t\tjtag_sleep((ms) * 1000)\n#define TO_STR(name)\t\t\t\t\t\t#name\n\n#define RESULT\t\t\t\t\t\t\t\tint\n#define LOG_BUG\t\t\t\t\t\t\t\tLOG_ERROR\n\n/* Common error messages */\n#define ERRMSG_NOT_ENOUGH_MEMORY\t\t\t\"Lack of memory.\"\n#define ERRCODE_NOT_ENOUGH_MEMORY\t\t\tERROR_FAIL\n\n#define ERRMSG_INVALID_VALUE\t\t\t\t\"%d is invalid for %s.\"\n#define ERRMSG_INVALID_INDEX\t\t\t\t\"Index %d is invalid for %s.\"\n#define ERRMSG_INVALID_USAGE\t\t\t\t\"Invalid usage of %s\"\n#define ERRMSG_INVALID_TARGET\t\t\t\t\"Invalid %s\"\n#define ERRMSG_INVALID_PARAMETER\t\t\t\"Invalid parameter of %s.\"\n#define ERRMSG_INVALID_INTERFACE_NUM\t\t\"invalid interface %d\"\n#define ERRMSG_INVALID_BUFFER\t\t\t\t\"Buffer %s is not valid.\"\n#define ERRCODE_INVALID_BUFFER\t\t\t\tERROR_FAIL\n#define ERRCODE_INVALID_PARAMETER\t\t\tERROR_FAIL\n\n#define ERRMSG_NOT_SUPPORT_BY\t\t\t\t\"%s is not supported by %s.\"\n\n#define ERRMSG_FAILURE_OPERATION\t\t\t\"Fail to %s.\"\n#define ERRMSG_FAILURE_OPERATION_MESSAGE\t\"Fail to %s, %s\"\n#define ERRCODE_FAILURE_OPERATION\t\t\tERROR_FAIL\n\n#define GET_U16_MSBFIRST(p)\t\t\t(((*((uint8_t *)(p) + 0)) << 8) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 1)) << 0))\n#define GET_U32_MSBFIRST(p)\t\t\t(((*((uint8_t *)(p) + 0)) << 24) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 1)) << 16) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 2)) << 8) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 3)) << 0))\n#define GET_U16_LSBFIRST(p)\t\t\t(((*((uint8_t *)(p) + 0)) << 0) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 1)) << 8))\n#define GET_U32_LSBFIRST(p)\t\t\t(((*((uint8_t *)(p) + 0)) << 0) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 1)) << 8) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 2)) << 16) | \\\n\t\t\t\t\t\t\t\t\t((*((uint8_t *)(p) + 3)) << 24))\n\n#define SET_U16_MSBFIRST(p, v)\t\t\\\n\tdo {\\\n\t\t*((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 8) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 0) & 0xFF;\\\n\t} while (0)\n#define SET_U32_MSBFIRST(p, v)\t\t\\\n\tdo {\\\n\t\t*((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 24) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 16) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 8) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 0) & 0xFF;\\\n\t} while (0)\n#define SET_U16_LSBFIRST(p, v)\t\t\\\n\tdo {\\\n\t\t*((uint8_t *)(p) + 0) = (((uint16_t)(v)) >> 0) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 1) = (((uint16_t)(v)) >> 8) & 0xFF;\\\n\t} while (0)\n#define SET_U32_LSBFIRST(p, v)\t\t\\\n\tdo {\\\n\t\t*((uint8_t *)(p) + 0) = (((uint32_t)(v)) >> 0) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 1) = (((uint32_t)(v)) >> 8) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 2) = (((uint32_t)(v)) >> 16) & 0xFF;\\\n\t\t*((uint8_t *)(p) + 3) = (((uint32_t)(v)) >> 24) & 0xFF;\\\n\t} while (0)\n\n#define GET_LE_U16(p)\t\t\t\tGET_U16_LSBFIRST(p)\n#define GET_LE_U32(p)\t\t\t\tGET_U32_LSBFIRST(p)\n#define GET_BE_U16(p)\t\t\t\tGET_U16_MSBFIRST(p)\n#define GET_BE_U32(p)\t\t\t\tGET_U32_MSBFIRST(p)\n#define SET_LE_U16(p, v)\t\t\tSET_U16_LSBFIRST(p, v)\n#define SET_LE_U32(p, v)\t\t\tSET_U32_LSBFIRST(p, v)\n#define SET_BE_U16(p, v)\t\t\tSET_U16_MSBFIRST(p, v)\n#define SET_BE_U32(p, v)\t\t\tSET_U32_MSBFIRST(p, v)\n\n#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INCLUDE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/versaloon/versaloon_internal.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 - 2010 by Simon Qian <SimonQian@SimonQian.com>     *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H\n#define OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H\n\n#define VERSALOON_PRODUCTSTRING_INDEX\t2\n#define VERSALOON_SERIALSTRING_INDEX\t3\n\n#define VERSALOON_PRODUCTSTRING\t\t\t\"Versaloon\"\n\n#define VERSALOON_VID\t\t\t\t\t0x0483\n#define VERSALOON_PID\t\t\t\t\t0xA038\n#define VERSALOON_INP\t\t\t\t\t0x82\n#define VERSALOON_OUTP\t\t\t\t\t0x03\n#define VERSALOON_IFACE\t\t\t\t\t0x00\n\n#define VERSALOON_FULL\t\t\t\t\t1\n#define VERSALOON_MINI\t\t\t\t\t2\n#define VERSALOON_NANO\t\t\t\t\t3\n\n#define VERSALOON_TIMEOUT\t\t\t\t5000\n#define VERSALOON_TIMEOUT_LONG\t\t\t60000\n\n/* USB Commands */\n/* Common Commands */\n#define VERSALOON_COMMON_CMD_START\t\t0x00\n#define VERSALOON_COMMON_CMD_END\t\t0x0F\n\n#define VERSALOON_GET_INFO\t\t\t\t0x00\n#define VERSALOON_GET_TVCC\t\t\t\t0x01\n#define VERSALOON_GET_HARDWARE\t\t\t0x02\n#define VERSALOON_GET_OFFLINE_SIZE\t\t0x08\n#define VERSALOON_ERASE_OFFLINE_DATA\t0x09\n#define VERSALOON_WRITE_OFFLINE_DATA\t0x0A\n#define VERSALOON_GET_OFFLINE_CHECKSUM\t0x0B\n#define VERSALOON_FW_UPDATE\t\t\t\t0x0F\n#define VERSALOON_FW_UPDATE_KEY\t\t\t0xAA\n\n/* MCU Command */\n#define VERSALOON_MCU_CMD_START\t\t\t0x10\n#define VERSALOON_MCU_CMD_END\t\t\t0x1F\n\n/* USB_TO_XXX Command */\n#define VERSALOON_USB_TO_XXX_CMD_START\t0x20\n#define VERSALOON_USB_TO_XXX_CMD_END\t0x7F\n\n/* VSLLink Command */\n#define VERSALOON_VSLLINK_CMD_START\t\t0x80\n#define VERSALOON_VSLLINK_CMD_END\t\t0xFF\n\n/* Mass-product */\n#define MP_OK\t\t\t\t\t\t\t0x00\n#define MP_FAIL\t\t\t\t\t\t\t0x01\n\n#define MP_ISSP\t\t\t\t\t\t\t0x11\n\n/* pending struct */\n#define VERSALOON_MAX_PENDING_NUMBER\t4096\ntypedef RESULT(*versaloon_callback_t)(void *, uint8_t *, uint8_t *);\nstruct versaloon_want_pos_t {\n\tuint16_t offset;\n\tuint16_t size;\n\tuint8_t *buff;\n\tstruct versaloon_want_pos_t *next;\n};\nstruct versaloon_pending_t {\n\tuint8_t type;\n\tuint8_t cmd;\n\tuint16_t want_data_pos;\n\tuint16_t want_data_size;\n\tuint16_t actual_data_size;\n\tuint8_t *data_buffer;\n\tuint8_t collect;\n\tuint32_t id;\n\tstruct versaloon_want_pos_t *pos;\n\tvoid *extra_data;\n\tversaloon_callback_t callback;\n};\nextern struct versaloon_pending_t\n\tversaloon_pending[VERSALOON_MAX_PENDING_NUMBER];\nextern uint16_t versaloon_pending_idx;\nvoid versaloon_set_pending_id(uint32_t id);\nvoid versaloon_set_callback(versaloon_callback_t callback);\nvoid versaloon_set_extra_data(void *p);\nRESULT versaloon_add_want_pos(uint16_t offset, uint16_t size, uint8_t *buff);\nRESULT versaloon_add_pending(uint8_t type, uint8_t cmd, uint16_t actual_szie,\n\t\tuint16_t want_pos, uint16_t want_size, uint8_t *buffer, uint8_t collect);\nvoid versaloon_free_want_pos(void);\n\nRESULT versaloon_send_command(uint16_t out_len, uint16_t *inlen);\nextern uint8_t *versaloon_buf;\nextern uint8_t *versaloon_cmd_buf;\nextern uint16_t versaloon_buf_size;\n\n#endif /* OPENOCD_JTAG_DRIVERS_VERSALOON_VERSALOON_INTERNAL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/vsllink.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009-2010 by Simon Qian <SimonQian@SimonQian.com>       *\n ***************************************************************************/\n\n/* Versaloon is a programming tool for multiple MCUs.\n * It's distributed under GPLv3.\n * You can find it at http://www.Versaloon.com/.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/adapter.h>\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <jtag/swd.h>\n#include <libusb.h>\n\n#include \"versaloon/versaloon_include.h\"\n#include \"versaloon/versaloon.h\"\n\nstatic int vsllink_tms_offset;\n\nstruct pending_scan_result {\n\tint src_offset;\n\tint dest_offset;\n\tint length;\t/* Number of bits to read */\n\tstruct scan_command *command;\t/* Corresponding scan command */\n\tuint8_t *ack;\n\tuint8_t *buffer;\n\tbool last;\t/* indicate the last scan pending */\n};\n\n#define MAX_PENDING_SCAN_RESULTS 256\n\nstatic int pending_scan_results_length;\nstatic struct pending_scan_result\n\tpending_scan_results_buffer[MAX_PENDING_SCAN_RESULTS];\n\n/* Queue command functions */\nstatic void vsllink_end_state(tap_state_t state);\nstatic void vsllink_state_move(void);\nstatic void vsllink_path_move(int num_states, tap_state_t *path);\nstatic void vsllink_tms(int num_bits, const uint8_t *bits);\nstatic void vsllink_runtest(int num_cycles);\nstatic void vsllink_stableclocks(int num_cycles, int tms);\nstatic void vsllink_scan(bool ir_scan, enum scan_type type,\n\t\tuint8_t *buffer, int scan_size, struct scan_command *command);\nstatic int vsllink_reset(int trst, int srst);\n\n/* VSLLink tap buffer functions */\nstatic void vsllink_tap_append_step(int tms, int tdi);\nstatic void vsllink_tap_init(void);\nstatic int  vsllink_tap_execute(void);\nstatic void vsllink_tap_ensure_pending(int scans);\nstatic void vsllink_tap_append_scan(int length, uint8_t *buffer,\n\t\tstruct scan_command *command);\n\n/* VSLLink SWD functions */\nstatic int_least32_t vsllink_swd_frequency(int_least32_t hz);\nstatic int vsllink_swd_switch_seq(enum swd_special_seq seq);\n\n/* VSLLink lowlevel functions */\nstruct vsllink {\n\tstruct libusb_context *libusb_ctx;\n\tstruct libusb_device_handle *usb_device_handle;\n};\n\nstatic int vsllink_usb_open(struct vsllink *vsllink);\nstatic void vsllink_usb_close(struct vsllink *vsllink);\n\nstatic void vsllink_debug_buffer(uint8_t *buffer, int length);\n\nstatic int tap_length;\nstatic int tap_buffer_size;\nstatic uint8_t *tms_buffer;\nstatic uint8_t *tdi_buffer;\nstatic uint8_t *tdo_buffer;\n\nstatic bool swd_mode;\n\nstatic struct vsllink *vsllink_handle;\n\nstatic int vsllink_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint scan_size;\n\tenum scan_type type;\n\tuint8_t *buffer;\n\n\tLOG_DEBUG_IO(\"-------------------------------------\"\n\t\t\" vsllink \"\n\t\t\"-------------------------------------\");\n\n\twhile (cmd) {\n\t\tswitch (cmd->type) {\n\t\t\tcase JTAG_RUNTEST:\n\t\t\t\tLOG_DEBUG_IO(\"runtest %i cycles, end in %s\",\n\t\t\t\t\t\tcmd->cmd.runtest->num_cycles,\n\t\t\t\t\t\ttap_state_name(cmd->cmd.runtest->end_state));\n\n\t\t\t\tvsllink_end_state(cmd->cmd.runtest->end_state);\n\t\t\t\tvsllink_runtest(cmd->cmd.runtest->num_cycles);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_TLR_RESET:\n\t\t\t\tLOG_DEBUG_IO(\"statemove end in %s\",\n\t\t\t\t\t\ttap_state_name(cmd->cmd.statemove->end_state));\n\n\t\t\t\tvsllink_end_state(cmd->cmd.statemove->end_state);\n\t\t\t\tvsllink_state_move();\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_PATHMOVE:\n\t\t\t\tLOG_DEBUG_IO(\"pathmove: %i states, end in %s\",\n\t\t\t\t\t\tcmd->cmd.pathmove->num_states,\n\t\t\t\t\t\ttap_state_name(cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]));\n\n\t\t\t\tvsllink_path_move(cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SCAN:\n\t\t\t\tLOG_DEBUG_IO(\"JTAG Scan...\");\n\n\t\t\t\tvsllink_end_state(cmd->cmd.scan->end_state);\n\n\t\t\t\tscan_size = jtag_build_buffer(\n\t\t\t\t\t\tcmd->cmd.scan, &buffer);\n\n\t\t\t\tif (cmd->cmd.scan->ir_scan)\n\t\t\t\t\tLOG_DEBUG_IO(\n\t\t\t\t\t\t\t\"JTAG Scan write IR(%d bits), \"\n\t\t\t\t\t\t\t\"end in %s:\",\n\t\t\t\t\t\t\tscan_size,\n\t\t\t\t\t\t\ttap_state_name(cmd->cmd.scan->end_state));\n\n\t\t\t\telse\n\t\t\t\t\tLOG_DEBUG_IO(\n\t\t\t\t\t\t\t\"JTAG Scan write DR(%d bits), \"\n\t\t\t\t\t\t\t\"end in %s:\",\n\t\t\t\t\t\t\tscan_size,\n\t\t\t\t\t\t\ttap_state_name(cmd->cmd.scan->end_state));\n\n\t\t\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))\n\t\t\t\t\tvsllink_debug_buffer(buffer, DIV_ROUND_UP(scan_size, 8));\n\n\t\t\t\ttype = jtag_scan_type(cmd->cmd.scan);\n\n\t\t\t\tvsllink_scan(cmd->cmd.scan->ir_scan,\n\t\t\t\t\t\ttype, buffer, scan_size,\n\t\t\t\t\t\tcmd->cmd.scan);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_SLEEP:\n\t\t\t\tLOG_DEBUG_IO(\"sleep %\" PRIu32, cmd->cmd.sleep->us);\n\t\t\t\tvsllink_tap_execute();\n\t\t\t\tjtag_sleep(cmd->cmd.sleep->us);\n\t\t\t\tbreak;\n\n\t\t\tcase JTAG_STABLECLOCKS:\n\t\t\t\tLOG_DEBUG_IO(\"add %d clocks\",\n\t\t\t\t\t\tcmd->cmd.stableclocks->num_cycles);\n\n\t\t\t\tswitch (tap_get_state()) {\n\t\t\t\tcase TAP_RESET:\n\t\t\t\t\t/* tms must be '1' to stay\n\t\t\t\t\t * n TAP_RESET mode\n\t\t\t\t\t */\n\t\t\t\t\tscan_size = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase TAP_DRSHIFT:\n\t\t\t\tcase TAP_IDLE:\n\t\t\t\tcase TAP_DRPAUSE:\n\t\t\t\tcase TAP_IRSHIFT:\n\t\t\t\tcase TAP_IRPAUSE:\n\t\t\t\t\t/* else, tms should be '0' */\n\t\t\t\t\tscan_size = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t/* above stable states are OK */\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"jtag_add_clocks() \"\n\t\t\t\t\t\t\t\"in non-stable state \\\"%s\\\"\",\n\t\t\t\t\t\t\ttap_state_name(tap_get_state())\n\t\t\t\t\t);\n\t\t\t\t\texit(-1);\n\t\t\t\t}\n\t\t\t\tvsllink_stableclocks(cmd->cmd.stableclocks->num_cycles, scan_size);\n\t\t\t\tbreak;\n\n\t\t\t\tcase JTAG_TMS:\n\t\t\t\t\tLOG_DEBUG_IO(\"add %d jtag tms\",\n\t\t\t\t\t\t\tcmd->cmd.tms->num_bits);\n\n\t\t\t\t\tvsllink_tms(cmd->cmd.tms->num_bits, cmd->cmd.tms->bits);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type \"\n\t\t\t\t\t\t\t\"encountered: %d\", cmd->type);\n\t\t\t\t\texit(-1);\n\t\t}\n\t\tcmd = cmd->next;\n\t}\n\n\treturn vsllink_tap_execute();\n}\n\nstatic int vsllink_speed(int speed)\n{\n\tif (swd_mode) {\n\t\tvsllink_swd_frequency(speed * 1000);\n\t\treturn ERROR_OK;\n\t}\n\n\tversaloon_interface.adaptors.jtag_raw.config(0, (uint16_t)speed);\n\treturn versaloon_interface.adaptors.peripheral_commit();\n}\n\nstatic int vsllink_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\n\treturn ERROR_OK;\n}\n\nstatic int vsllink_speed_div(int jtag_speed, int *khz)\n{\n\t*khz = jtag_speed;\n\n\treturn ERROR_OK;\n}\n\nstatic void vsllink_free_buffer(void)\n{\n\tfree(tdi_buffer);\n\ttdi_buffer = NULL;\n\n\tfree(tdo_buffer);\n\ttdo_buffer = NULL;\n\n\tfree(tms_buffer);\n\ttms_buffer = NULL;\n}\n\nstatic int vsllink_quit(void)\n{\n\tversaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,\n\t\t0, 0, GPIO_SRST | GPIO_TRST);\n\tversaloon_interface.adaptors.gpio.fini(0);\n\n\tif (swd_mode)\n\t\tversaloon_interface.adaptors.swd.fini(0);\n\telse\n\t\tversaloon_interface.adaptors.jtag_raw.fini(0);\n\n\tversaloon_interface.adaptors.peripheral_commit();\n\tversaloon_interface.fini();\n\n\tvsllink_free_buffer();\n\tvsllink_usb_close(vsllink_handle);\n\n\tlibusb_exit(vsllink_handle->libusb_ctx);\n\tfree(vsllink_handle);\n\n\treturn ERROR_OK;\n}\n\nstatic int vsllink_interface_init(void)\n{\n\tvsllink_handle = malloc(sizeof(struct vsllink));\n\tif (!vsllink_handle) {\n\t\tLOG_ERROR(\"unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tlibusb_init(&vsllink_handle->libusb_ctx);\n\n\tif (vsllink_usb_open(vsllink_handle) != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't find USB JTAG Interface!\"\n\t\t\t\"Please check connection and permissions.\");\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\tLOG_DEBUG(\"vsllink found on %04X:%04X\",\n\t\tversaloon_interface.usb_setting.vid,\n\t\tversaloon_interface.usb_setting.pid);\n\tversaloon_usb_device_handle = vsllink_handle->usb_device_handle;\n\n\tif (versaloon_interface.init() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (versaloon_interface.usb_setting.buf_size < 32) {\n\t\tversaloon_interface.fini();\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int vsllink_init(void)\n{\n\tint retval = vsllink_interface_init();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tversaloon_interface.adaptors.gpio.init(0);\n\tversaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST,\n\t\tGPIO_SRST);\n\tversaloon_interface.adaptors.delay.delayms(100);\n\tversaloon_interface.adaptors.peripheral_commit();\n\n\tif (swd_mode) {\n\t\tversaloon_interface.adaptors.gpio.config(0, GPIO_TRST, 0,\n\t\t\tGPIO_TRST, GPIO_TRST);\n\t\tversaloon_interface.adaptors.swd.init(0);\n\t\tvsllink_swd_frequency(adapter_get_speed_khz() * 1000);\n\t\tvsllink_swd_switch_seq(JTAG_TO_SWD);\n\n\t} else {\n\t\t/* malloc buffer size for tap */\n\t\ttap_buffer_size = versaloon_interface.usb_setting.buf_size / 2 - 32;\n\t\tvsllink_free_buffer();\n\t\ttdi_buffer = malloc(tap_buffer_size);\n\t\ttdo_buffer = malloc(tap_buffer_size);\n\t\ttms_buffer = malloc(tap_buffer_size);\n\t\tif ((!tdi_buffer) || (!tdo_buffer) || (!tms_buffer)) {\n\t\t\tvsllink_quit();\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tversaloon_interface.adaptors.jtag_raw.init(0);\n\t\tversaloon_interface.adaptors.jtag_raw.config(0, adapter_get_speed_khz());\n\t\tversaloon_interface.adaptors.gpio.config(0, GPIO_SRST | GPIO_TRST,\n\t\t\tGPIO_TRST, GPIO_SRST, GPIO_SRST);\n\t}\n\n\tif (versaloon_interface.adaptors.peripheral_commit() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tvsllink_reset(0, 0);\n\tvsllink_tap_init();\n\treturn ERROR_OK;\n}\n\n/**************************************************************************\n * Queue command implementations */\n\nstatic void vsllink_end_state(tap_state_t state)\n{\n\tif (tap_is_state_stable(state))\n\t\ttap_set_end_state(state);\n\telse {\n\t\tLOG_ERROR(\"BUG: %i is not a valid end state\", state);\n\t\texit(-1);\n\t}\n}\n\n/* Goes to the end state. */\nstatic void vsllink_state_move(void)\n{\n\tint i;\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(),\n\t\t\ttap_get_end_state());\n\tuint8_t tms_scan_bits = tap_get_tms_path_len(tap_get_state(),\n\t\t\ttap_get_end_state());\n\n\tfor (i = 0; i < tms_scan_bits; i++)\n\t\tvsllink_tap_append_step((tms_scan >> i) & 1, 0);\n\n\ttap_set_state(tap_get_end_state());\n}\n\nstatic void vsllink_path_move(int num_states, tap_state_t *path)\n{\n\tfor (int i = 0; i < num_states; i++) {\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false))\n\t\t\tvsllink_tap_append_step(0, 0);\n\t\telse if (path[i] == tap_state_transition(tap_get_state(), true))\n\t\t\tvsllink_tap_append_step(1, 0);\n\t\telse {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition\",\n\t\t\t\ttap_state_name(tap_get_state()),\n\t\t\t\ttap_state_name(path[i]));\n\t\t\texit(-1);\n\t\t}\n\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n}\n\nstatic void vsllink_tms(int num_bits, const uint8_t *bits)\n{\n\tfor (int i = 0; i < num_bits; i++)\n\t\tvsllink_tap_append_step((bits[i / 8] >> (i % 8)) & 1, 0);\n}\n\nstatic void vsllink_stableclocks(int num_cycles, int tms)\n{\n\twhile (num_cycles > 0) {\n\t\tvsllink_tap_append_step(tms, 0);\n\t\tnum_cycles--;\n\t}\n}\n\nstatic void vsllink_runtest(int num_cycles)\n{\n\ttap_state_t saved_end_state = tap_get_end_state();\n\n\tif (tap_get_state() != TAP_IDLE) {\n\t\t/* enter IDLE state */\n\t\tvsllink_end_state(TAP_IDLE);\n\t\tvsllink_state_move();\n\t}\n\n\tvsllink_stableclocks(num_cycles, 0);\n\n\t/* post-process */\n\t/* set end_state */\n\tvsllink_end_state(saved_end_state);\n\tif (tap_get_end_state() != tap_get_end_state())\n\t\tvsllink_state_move();\n}\n\nstatic void vsllink_scan(bool ir_scan, enum scan_type type, uint8_t *buffer,\n\tint scan_size, struct scan_command *command)\n{\n\ttap_state_t saved_end_state;\n\n\tsaved_end_state = tap_get_end_state();\n\n\t/* Move to appropriate scan state */\n\tvsllink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tvsllink_state_move();\n\tvsllink_end_state(saved_end_state);\n\n\t/* Scan */\n\tvsllink_tap_append_scan(scan_size, buffer, command);\n\n\t/* Goto Pause and record position to insert tms:0 */\n\tvsllink_tap_append_step(0, 0);\n\tvsllink_tms_offset = tap_length;\n\n\ttap_set_state(ir_scan ? TAP_IRPAUSE : TAP_DRPAUSE);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\tvsllink_state_move();\n}\n\nstatic int vsllink_reset(int trst, int srst)\n{\n\tLOG_DEBUG(\"trst: %i, srst: %i\", trst, srst);\n\n\tif (!srst)\n\t\tversaloon_interface.adaptors.gpio.config(0, GPIO_SRST, 0, GPIO_SRST, GPIO_SRST);\n\telse\n\t\tversaloon_interface.adaptors.gpio.config(0, GPIO_SRST, GPIO_SRST, 0, 0);\n\n\tif (!swd_mode) {\n\t\tif (!trst)\n\t\t\tversaloon_interface.adaptors.gpio.out(0, GPIO_TRST, GPIO_TRST);\n\t\telse\n\t\t\tversaloon_interface.adaptors.gpio.out(0, GPIO_TRST, 0);\n\t}\n\n\treturn versaloon_interface.adaptors.peripheral_commit();\n}\n\nCOMMAND_HANDLER(vsllink_handle_usb_vid_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],\n\t\tversaloon_interface.usb_setting.vid);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vsllink_handle_usb_pid_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0],\n\t\tversaloon_interface.usb_setting.pid);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vsllink_handle_usb_bulkin_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],\n\t\tversaloon_interface.usb_setting.ep_in);\n\n\tversaloon_interface.usb_setting.ep_in |= 0x80;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vsllink_handle_usb_bulkout_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],\n\t\tversaloon_interface.usb_setting.ep_out);\n\n\tversaloon_interface.usb_setting.ep_out &= ~0x80;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(vsllink_handle_usb_interface_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0],\n\t\tversaloon_interface.usb_setting.interface);\n\treturn ERROR_OK;\n}\n\n/**************************************************************************\n * VSLLink tap functions */\n\nstatic void vsllink_tap_init(void)\n{\n\ttap_length = 0;\n\tpending_scan_results_length = 0;\n\tvsllink_tms_offset = 0;\n}\n\nstatic void vsllink_tap_ensure_pending(int scans)\n{\n\tint available_scans =\n\t\tMAX_PENDING_SCAN_RESULTS - pending_scan_results_length;\n\n\tif (scans > available_scans)\n\t\tvsllink_tap_execute();\n}\n\nstatic void vsllink_tap_append_step(int tms, int tdi)\n{\n\tint index_var = tap_length / 8;\n\n\tint bit_index = tap_length % 8;\n\tuint8_t bit = 1 << bit_index;\n\n\tif (tms)\n\t\ttms_buffer[index_var] |= bit;\n\telse\n\t\ttms_buffer[index_var] &= ~bit;\n\n\tif (tdi)\n\t\ttdi_buffer[index_var] |= bit;\n\telse\n\t\ttdi_buffer[index_var] &= ~bit;\n\n\ttap_length++;\n\n\tif (tap_buffer_size * 8 <= tap_length)\n\t\tvsllink_tap_execute();\n}\n\nstatic void vsllink_tap_append_scan(int length, uint8_t *buffer,\n\tstruct scan_command *command)\n{\n\tstruct pending_scan_result *pending_scan_result;\n\tint len_tmp, len_all, i;\n\n\tlen_all = 0;\n\twhile (len_all < length) {\n\t\tvsllink_tap_ensure_pending(1);\n\t\tpending_scan_result =\n\t\t\t&pending_scan_results_buffer[\n\t\t\t\tpending_scan_results_length];\n\n\t\tif ((length - len_all) > (tap_buffer_size * 8 - tap_length)) {\n\t\t\t/* Use all memory available\n\t\t\t   vsllink_tap_append_step will commit automatically */\n\t\t\tlen_tmp = tap_buffer_size * 8 - tap_length;\n\t\t\tpending_scan_result->last = false;\n\t\t} else {\n\t\t\tlen_tmp = length - len_all;\n\t\t\tpending_scan_result->last = true;\n\t\t}\n\t\tpending_scan_result->src_offset = tap_length;\n\t\tpending_scan_result->dest_offset = len_all;\n\t\tpending_scan_result->length = len_tmp;\n\t\tpending_scan_result->command = command;\n\t\tpending_scan_result->buffer = buffer;\n\t\tpending_scan_results_length++;\n\n\t\tfor (i = 0; i < len_tmp; i++) {\n\t\t\tvsllink_tap_append_step(((len_all + i) < length-1\n\t\t\t\t\t\t ? 0 : 1),\n\t\t\t\t(buffer[(len_all + i)/8]\n\t\t\t\t >> ((len_all + i)%8)) & 1);\n\t\t}\n\n\t\tlen_all += len_tmp;\n\t}\n}\n\nstatic int vsllink_jtag_execute(void)\n{\n\tint i;\n\tint result;\n\n\tif (tap_length <= 0)\n\t\treturn ERROR_OK;\n\n\tversaloon_interface.adaptors.jtag_raw.execute(0, tdi_buffer, tms_buffer,\n\t\ttdo_buffer, tap_length);\n\n\tresult = versaloon_interface.adaptors.peripheral_commit();\n\n\tif (result == ERROR_OK) {\n\t\tfor (i = 0; i < pending_scan_results_length; i++) {\n\t\t\tstruct pending_scan_result *pending_scan_result =\n\t\t\t\t&pending_scan_results_buffer[i];\n\t\t\tuint8_t *buffer = pending_scan_result->buffer;\n\t\t\tint length = pending_scan_result->length;\n\t\t\tint src_first = pending_scan_result->src_offset;\n\t\t\tint dest_first = pending_scan_result->dest_offset;\n\t\t\tbool last = pending_scan_result->last;\n\n\t\t\tstruct scan_command *command;\n\n\t\t\tcommand = pending_scan_result->command;\n\t\t\tbuf_set_buf(tdo_buffer, src_first, buffer, dest_first, length);\n\n\t\t\tLOG_DEBUG_IO(\n\t\t\t\t\"JTAG scan read(%d bits, from src %d bits to dest %d bits):\",\n\t\t\t\tlength, src_first, dest_first);\n\t\t\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))\n\t\t\t\tvsllink_debug_buffer(buffer + dest_first / 8, DIV_ROUND_UP(length, 7));\n\n\t\t\tif (last) {\n\t\t\t\tif (jtag_read_buffer(buffer, command)\n\t\t\t\t    != ERROR_OK) {\n\t\t\t\t\tvsllink_tap_init();\n\t\t\t\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t\t\t\t}\n\n\t\t\t\tfree(pending_scan_result->buffer);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"vsllink_jtag_execute failure\");\n\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\n\tvsllink_tap_init();\n\n\treturn ERROR_OK;\n}\n\nstatic int vsllink_tap_execute(void)\n{\n\tif (swd_mode)\n\t\treturn ERROR_OK;\n\n\treturn vsllink_jtag_execute();\n}\n\nstatic int vsllink_swd_init(void)\n{\n\tLOG_INFO(\"VSLLink SWD mode enabled\");\n\tswd_mode = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int_least32_t vsllink_swd_frequency(int_least32_t hz)\n{\n\tconst int_least32_t delay2hz[] = {\n\t\t1850000, 235000, 130000, 102000, 85000, 72000\n\t};\n\n\tif (hz > 0) {\n\t\tuint16_t delay = UINT16_MAX;\n\n\t\tfor (uint16_t i = 0; i < ARRAY_SIZE(delay2hz); i++) {\n\t\t\tif (hz >= delay2hz[i]) {\n\t\t\t\thz = delay2hz[i];\n\t\t\t\tdelay = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (delay == UINT16_MAX)\n\t\t\tdelay = (500000 / hz) - 1;\n\n\t\t/* Calculate retry count after a WAIT response. This will give\n\t\t * a retry timeout at about ~250 ms. 54 is the number of bits\n\t\t * found in a transaction. */\n\t\tuint16_t retry_count = 250 * hz / 1000 / 54;\n\n\t\tLOG_DEBUG(\"SWD delay: %d, retry count: %d\", delay, retry_count);\n\n\t\tversaloon_interface.adaptors.swd.config(0, 2, retry_count, delay);\n\t}\n\n\treturn hz;\n}\n\nstatic int vsllink_swd_switch_seq(enum swd_special_seq seq)\n{\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG(\"SWD line reset\");\n\t\tversaloon_interface.adaptors.swd.seqout(0, swd_seq_line_reset,\n\t\t\t\tswd_seq_line_reset_len);\n\t\tbreak;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\tversaloon_interface.adaptors.swd.seqout(0, swd_seq_jtag_to_swd,\n\t\t\t\tswd_seq_jtag_to_swd_len);\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\tversaloon_interface.adaptors.swd.seqout(0, swd_seq_swd_to_jtag,\n\t\t\t\tswd_seq_swd_to_jtag_len);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void vsllink_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)\n{\n\tversaloon_interface.adaptors.swd.transact(0, cmd, value, NULL);\n}\n\nstatic void vsllink_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)\n{\n\tversaloon_interface.adaptors.swd.transact(0, cmd, &value, NULL);\n}\n\nstatic int vsllink_swd_run_queue(void)\n{\n\treturn versaloon_interface.adaptors.peripheral_commit();\n}\n\n/****************************************************************************\n * VSLLink USB low-level functions */\n\nstatic int vsllink_check_usb_strings(\n\tstruct libusb_device_handle *usb_device_handle,\n\tstruct libusb_device_descriptor *usb_desc)\n{\n\tchar desc_string[256];\n\tint retval;\n\n\tif (adapter_get_required_serial()) {\n\t\tretval = libusb_get_string_descriptor_ascii(usb_device_handle,\n\t\t\tusb_desc->iSerialNumber, (unsigned char *)desc_string,\n\t\t\tsizeof(desc_string));\n\t\tif (retval < 0)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (strncmp(desc_string, adapter_get_required_serial(),\n\t\t\t\tsizeof(desc_string)))\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = libusb_get_string_descriptor_ascii(usb_device_handle,\n\t\tusb_desc->iProduct, (unsigned char *)desc_string,\n\t\tsizeof(desc_string));\n\tif (retval < 0)\n\t\treturn ERROR_FAIL;\n\n\tif (!strstr(desc_string, \"Versaloon\"))\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int vsllink_usb_open(struct vsllink *vsllink)\n{\n\tssize_t num_devices, i;\n\tstruct libusb_device **usb_devices;\n\tstruct libusb_device_descriptor usb_desc;\n\tstruct libusb_device_handle *usb_device_handle;\n\tint retval;\n\n\tnum_devices = libusb_get_device_list(vsllink->libusb_ctx, &usb_devices);\n\n\tif (num_devices <= 0)\n\t\treturn ERROR_FAIL;\n\n\tfor (i = 0; i < num_devices; i++) {\n\t\tstruct libusb_device *device = usb_devices[i];\n\n\t\tretval = libusb_get_device_descriptor(device, &usb_desc);\n\t\tif (retval != 0)\n\t\t\tcontinue;\n\n\t\tif (usb_desc.idVendor != versaloon_interface.usb_setting.vid ||\n\t\t\tusb_desc.idProduct != versaloon_interface.usb_setting.pid)\n\t\t\tcontinue;\n\n\t\tretval = libusb_open(device, &usb_device_handle);\n\t\tif (retval != 0)\n\t\t\tcontinue;\n\n\t\tretval = vsllink_check_usb_strings(usb_device_handle, &usb_desc);\n\t\tif (retval == ERROR_OK)\n\t\t\tbreak;\n\n\t\tlibusb_close(usb_device_handle);\n\t}\n\n\tlibusb_free_device_list(usb_devices, 1);\n\n\tif (i == num_devices)\n\t\treturn ERROR_FAIL;\n\n\tretval = libusb_claim_interface(usb_device_handle,\n\t\tversaloon_interface.usb_setting.interface);\n\tif (retval != 0) {\n\t\tLOG_ERROR(\"unable to claim interface\");\n\t\tlibusb_close(usb_device_handle);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tvsllink->usb_device_handle = usb_device_handle;\n\treturn ERROR_OK;\n}\n\nstatic void vsllink_usb_close(struct vsllink *vsllink)\n{\n\tlibusb_release_interface(vsllink->usb_device_handle,\n\t\tversaloon_interface.usb_setting.interface);\n\tlibusb_close(vsllink->usb_device_handle);\n}\n\n#define BYTES_PER_LINE  16\n\nstatic void vsllink_debug_buffer(uint8_t *buffer, int length)\n{\n\tchar line[81];\n\tchar s[4];\n\tint i;\n\tint j;\n\n\tfor (i = 0; i < length; i += BYTES_PER_LINE) {\n\t\tsnprintf(line, 5, \"%04x\", i & 0xffff);\n\t\tfor (j = i; j < i + BYTES_PER_LINE && j < length; j++) {\n\t\t\tsnprintf(s, 4, \" %02x\", buffer[j]);\n\t\t\tstrcat(line, s);\n\t\t}\n\t\tLOG_DEBUG_IO(\"%s\", line);\n\t}\n}\n\nstatic const struct command_registration vsllink_subcommand_handlers[] = {\n\t{\n\t\t.name = \"usb_vid\",\n\t\t.handler = &vsllink_handle_usb_vid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set USB VID\",\n\t\t.usage = \"<vid>\",\n\t},\n\t{\n\t\t.name = \"usb_pid\",\n\t\t.handler = &vsllink_handle_usb_pid_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set USB PID\",\n\t\t.usage = \"<pid>\",\n\t},\n\t{\n\t\t.name = \"usb_bulkin\",\n\t\t.handler = &vsllink_handle_usb_bulkin_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set USB input endpoint\",\n\t\t.usage = \"<ep_in>\",\n\t},\n\t{\n\t\t.name = \"usb_bulkout\",\n\t\t.handler = &vsllink_handle_usb_bulkout_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set USB output endpoint\",\n\t\t.usage = \"<ep_out>\",\n\t},\n\t{\n\t\t.name = \"usb_interface\",\n\t\t.handler = &vsllink_handle_usb_interface_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set USB output interface\",\n\t\t.usage = \"<interface>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration vsllink_command_handlers[] = {\n\t{\n\t\t.name = \"vsllink\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform vsllink management\",\n\t\t.chain = vsllink_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const char * const vsllink_transports[] = {\"jtag\", \"swd\", NULL};\n\nstatic const struct swd_driver vsllink_swd_driver = {\n\t.init = vsllink_swd_init,\n\t.switch_seq = vsllink_swd_switch_seq,\n\t.read_reg = vsllink_swd_read_reg,\n\t.write_reg = vsllink_swd_write_reg,\n\t.run = vsllink_swd_run_queue,\n};\n\nstatic struct jtag_interface vsllink_interface = {\n\t.supported = DEBUG_CAP_TMS_SEQ,\n\t.execute_queue = vsllink_execute_queue,\n};\n\nstruct adapter_driver vsllink_adapter_driver = {\n\t.name = \"vsllink\",\n\t.transports = vsllink_transports,\n\t.commands = vsllink_command_handlers,\n\n\t.init = vsllink_init,\n\t.quit = vsllink_quit,\n\t.reset = vsllink_reset,\n\t.speed = vsllink_speed,\n\t.khz = vsllink_khz,\n\t.speed_div = vsllink_speed_div,\n\n\t.jtag_ops = &vsllink_interface,\n\t.swd_ops = &vsllink_swd_driver,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/xds110.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Texas Instruments, Inc.                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <transport/transport.h>\n#include <jtag/adapter.h>\n#include <jtag/swd.h>\n#include <jtag/interface.h>\n#include <jtag/commands.h>\n#include <jtag/tcl.h>\n#include <libusb.h>\n\n/* XDS110 stand-alone probe voltage supply limits */\n#define XDS110_MIN_VOLTAGE 1800\n#define XDS110_MAX_VOLTAGE 3600\n\n/* XDS110 stand-alone probe hardware ID */\n#define XDS110_STAND_ALONE_ID 0x21\n\n/* Firmware version that introduced OpenOCD support via block accesses */\n#define OCD_FIRMWARE_VERSION 0x02030011\n#define OCD_FIRMWARE_UPGRADE \\\n\t\"XDS110: upgrade to version 2.3.0.11+ for improved support\"\n\n/* Firmware version that introduced improved TCK performance */\n#define FAST_TCK_FIRMWARE_VERSION 0x03000000\n\n/* Firmware version that introduced 10 MHz and 12 MHz TCK support */\n#define FAST_TCK_PLUS_FIRMWARE_VERSION 0x03000003\n\n/***************************************************************************\n *   USB Connection Buffer Definitions                                     *\n ***************************************************************************/\n\n/* Max USB packet size for up to USB 3.0 */\n#define MAX_PACKET 1024\n\n/*\n * Maximum data payload that can be handled in a single call\n * Limitation is the size of the buffers in the XDS110 firmware\n */\n#define MAX_DATA_BLOCK 4096\n\n#ifndef USB_PAYLOAD_SIZE\n/* Largest data block plus parameters */\n#define USB_PAYLOAD_SIZE (MAX_DATA_BLOCK + 60)\n#endif\n#define MAX_RESULT_QUEUE (MAX_DATA_BLOCK / 4)\n\n/***************************************************************************\n *   XDS110 Firmware API Definitions                                       *\n ***************************************************************************/\n\n/*\n * Default values controlling how the host communicates commands\n * with XDS110 firmware (automatic retry count and wait timeout)\n */\n#define DEFAULT_ATTEMPTS (1)\n#define DEFAULT_TIMEOUT  (4000)\n\n/* XDS110 API error codes */\n#define SC_ERR_NONE             0\n#define SC_ERR_XDS110_FAIL   -261\n#define SC_ERR_SWD_WAIT      -613\n#define SC_ERR_SWD_FAULT     -614\n#define SC_ERR_SWD_PROTOCOL  -615\n#define SC_ERR_SWD_PARITY    -616\n#define SC_ERR_SWD_DEVICE_ID -617\n\n/* TCK frequency limits */\n#define XDS110_MIN_TCK_SPEED  100 /* kHz */\n#define XDS110_MAX_SLOW_TCK_SPEED 2500 /* kHz */\n#define XDS110_MAX_FAST_TCK_SPEED 14000 /* kHz */\n#define XDS110_DEFAULT_TCK_SPEED 2500 /* kHz */\n\n/* Fixed TCK delay values for \"Fast\" TCK frequencies */\n#define FAST_TCK_DELAY_14000_KHZ 0\n#define FAST_TCK_DELAY_10000_KHZ 0xfffffffd\n#define FAST_TCK_DELAY_12000_KHZ 0xfffffffe\n#define FAST_TCK_DELAY_8500_KHZ 1\n#define FAST_TCK_DELAY_5500_KHZ 2\n/* For TCK frequencies below 5500 kHz, use calculated delay */\n\n/* Scan mode on connect */\n#define MODE_JTAG 1\n\n/* XDS110 API JTAG state definitions */\n#define XDS_JTAG_STATE_RESET       1\n#define XDS_JTAG_STATE_IDLE        2\n#define XDS_JTAG_STATE_SHIFT_DR    3\n#define XDS_JTAG_STATE_SHIFT_IR    4\n#define XDS_JTAG_STATE_PAUSE_DR    5\n#define XDS_JTAG_STATE_PAUSE_IR    6\n#define XDS_JTAG_STATE_EXIT1_DR    8\n#define XDS_JTAG_STATE_EXIT1_IR    9\n#define XDS_JTAG_STATE_EXIT2_DR   10\n#define XDS_JTAG_STATE_EXIT2_IR   11\n#define XDS_JTAG_STATE_SELECT_DR  12\n#define XDS_JTAG_STATE_SELECT_IR  13\n#define XDS_JTAG_STATE_UPDATE_DR  14\n#define XDS_JTAG_STATE_UPDATE_IR  15\n#define XDS_JTAG_STATE_CAPTURE_DR 16\n#define XDS_JTAG_STATE_CAPTURE_IR 17\n\n/* XDS110 API JTAG transit definitions */\n#define XDS_JTAG_TRANSIT_QUICKEST    1\n#define XDS_JTAG_TRANSIT_VIA_CAPTURE 2\n#define XDS_JTAG_TRANSIT_VIA_IDLE    3\n\n/* DAP register definitions as used by XDS110 APIs */\n\n#define DAP_AP 0 /* DAP AP register type */\n#define DAP_DP 1 /* DAP DP register type */\n\n#define DAP_DP_IDCODE 0x0 /* DAP DP IDCODE register (read only) */\n#define DAP_DP_ABORT  0x0 /* DAP DP ABORT register (write only) */\n#define DAP_DP_STAT   0x4 /* DAP DP STAT register (for read only) */\n#define DAP_DP_CTRL   0x4 /* DAP DP CTRL register (for write only) */\n#define DAP_DP_ADDR   0x8 /* DAP DP SELECT register (legacy name) */\n#define DAP_DP_RESEND 0x8 /* DAP DP RESEND register (read only) */\n#define DAP_DP_SELECT 0x8 /* DAP DP SELECT register (write only) */\n#define DAP_DP_RDBUFF 0xc /* DAP DP RDBUFF Read Buffer register */\n\n#define DAP_AP_CSW  0x00 /* DAP AP Control Status Word */\n#define DAP_AP_TAR  0x04 /* DAP AP Transfer Address */\n#define DAP_AP_DRW  0x0C /* DAP AP Data Read/Write */\n#define DAP_AP_BD0  0x10 /* DAP AP Banked Data 0 */\n#define DAP_AP_BD1  0x14 /* DAP AP Banked Data 1 */\n#define DAP_AP_BD2  0x18 /* DAP AP Banked Data 2 */\n#define DAP_AP_BD3  0x1C /* DAP AP Banked Data 3 */\n#define DAP_AP_RTBL 0xF8 /* DAP AP Debug ROM Table */\n#define DAP_AP_IDR  0xFC /* DAP AP Identification Register */\n\n/* Command packet definitions */\n\n#define XDS_OUT_LEN 1 /* command (byte) */\n#define XDS_IN_LEN  4 /* error code (int) */\n\n/* XDS API Commands */\n#define XDS_CONNECT      0x01 /* Connect JTAG connection */\n#define XDS_DISCONNECT   0x02 /* Disconnect JTAG connection */\n#define XDS_VERSION      0x03 /* Get firmware version and hardware ID */\n#define XDS_SET_TCK      0x04 /* Set TCK delay (to set TCK frequency) */\n#define XDS_SET_TRST     0x05 /* Assert or deassert nTRST signal */\n#define XDS_CYCLE_TCK    0x07 /* Toggle TCK for a number of cycles */\n#define XDS_GOTO_STATE   0x09 /* Go to requested JTAG state */\n#define XDS_JTAG_SCAN    0x0c /* Send and receive JTAG scan */\n#define XDS_SET_SRST     0x0e /* Assert or deassert nSRST signal */\n#define CMAPI_CONNECT    0x0f /* CMAPI connect */\n#define CMAPI_DISCONNECT 0x10 /* CMAPI disconnect */\n#define CMAPI_ACQUIRE    0x11 /* CMAPI acquire */\n#define CMAPI_RELEASE    0x12 /* CMAPI release */\n#define CMAPI_REG_READ   0x15 /* CMAPI DAP register read */\n#define CMAPI_REG_WRITE  0x16 /* CMAPI DAP register write */\n#define SWD_CONNECT      0x17 /* Switch from JTAG to SWD connection */\n#define SWD_DISCONNECT   0x18 /* Switch from SWD to JTAG connection */\n#define CJTAG_CONNECT    0x2b /* Switch from JTAG to cJTAG connection */\n#define CJTAG_DISCONNECT 0x2c /* Switch from cJTAG to JTAG connection */\n#define XDS_SET_SUPPLY   0x32 /* Set up stand-alone probe upply voltage */\n#define OCD_DAP_REQUEST  0x3a /* Handle block of DAP requests */\n#define OCD_SCAN_REQUEST 0x3b /* Handle block of JTAG scan requests */\n#define OCD_PATHMOVE     0x3c /* Handle PATHMOVE to navigate JTAG states */\n\n#define CMD_IR_SCAN      1\n#define CMD_DR_SCAN      2\n#define CMD_RUNTEST      3\n#define CMD_STABLECLOCKS 4\n\n/* Array to convert from OpenOCD tap_state_t to XDS JTAG state */\nstatic const uint32_t xds_jtag_state[] = {\n\tXDS_JTAG_STATE_EXIT2_DR,   /* TAP_DREXIT2   = 0x0 */\n\tXDS_JTAG_STATE_EXIT1_DR,   /* TAP_DREXIT1   = 0x1 */\n\tXDS_JTAG_STATE_SHIFT_DR,   /* TAP_DRSHIFT   = 0x2 */\n\tXDS_JTAG_STATE_PAUSE_DR,   /* TAP_DRPAUSE   = 0x3 */\n\tXDS_JTAG_STATE_SELECT_IR,  /* TAP_IRSELECT  = 0x4 */\n\tXDS_JTAG_STATE_UPDATE_DR,  /* TAP_DRUPDATE  = 0x5 */\n\tXDS_JTAG_STATE_CAPTURE_DR, /* TAP_DRCAPTURE = 0x6 */\n\tXDS_JTAG_STATE_SELECT_DR,  /* TAP_DRSELECT  = 0x7 */\n\tXDS_JTAG_STATE_EXIT2_IR,   /* TAP_IREXIT2   = 0x8 */\n\tXDS_JTAG_STATE_EXIT1_IR,   /* TAP_IREXIT1   = 0x9 */\n\tXDS_JTAG_STATE_SHIFT_IR,   /* TAP_IRSHIFT   = 0xa */\n\tXDS_JTAG_STATE_PAUSE_IR,   /* TAP_IRPAUSE   = 0xb */\n\tXDS_JTAG_STATE_IDLE,       /* TAP_IDLE      = 0xc */\n\tXDS_JTAG_STATE_UPDATE_IR,  /* TAP_IRUPDATE  = 0xd */\n\tXDS_JTAG_STATE_CAPTURE_IR, /* TAP_IRCAPTURE = 0xe */\n\tXDS_JTAG_STATE_RESET,      /* TAP_RESET     = 0xf */\n};\n\nstruct scan_result {\n\tbool first;\n\tuint8_t *buffer;\n\tuint32_t num_bits;\n};\n\nstruct xds110_info {\n\t/* USB connection handles and data buffers */\n\tstruct libusb_context *ctx;\n\tstruct libusb_device_handle *dev;\n\tunsigned char read_payload[USB_PAYLOAD_SIZE];\n\tunsigned char write_packet[3];\n\tunsigned char write_payload[USB_PAYLOAD_SIZE];\n\t/* Device vid/pid */\n\tuint16_t vid;\n\tuint16_t pid;\n\t/* Debug interface */\n\tuint8_t interface;\n\tuint8_t endpoint_in;\n\tuint8_t endpoint_out;\n\t/* Status flags */\n\tbool is_connected;\n\tbool is_cmapi_connected;\n\tbool is_cmapi_acquired;\n\tbool is_swd_mode;\n\tbool is_ap_dirty;\n\t/* DAP register caches */\n\tuint32_t select;\n\tuint32_t rdbuff;\n\tbool use_rdbuff;\n\t/* TCK speed and delay count*/\n\tuint32_t speed;\n\tuint32_t delay_count;\n\t/* XDS110 voltage supply setting */\n\tuint32_t voltage;\n\t/* XDS110 firmware and hardware version */\n\tuint32_t firmware;\n\tuint16_t hardware;\n\t/* Transaction queues */\n\tunsigned char txn_requests[MAX_DATA_BLOCK];\n\tuint32_t *txn_dap_results[MAX_DATA_BLOCK / 4];\n\tstruct scan_result txn_scan_results[MAX_DATA_BLOCK / 4];\n\tuint32_t txn_request_size;\n\tuint32_t txn_result_size;\n\tuint32_t txn_result_count;\n};\n\nstatic struct xds110_info xds110 = {\n\t.ctx = NULL,\n\t.dev = NULL,\n\t.vid = 0,\n\t.pid = 0,\n\t.interface = 0,\n\t.endpoint_in = 0,\n\t.endpoint_out = 0,\n\t.is_connected = false,\n\t.is_cmapi_connected = false,\n\t.is_cmapi_acquired = false,\n\t.is_swd_mode = false,\n\t.is_ap_dirty = false,\n\t.speed = XDS110_DEFAULT_TCK_SPEED,\n\t.delay_count = 0,\n\t.voltage = 0,\n\t.firmware = 0,\n\t.hardware = 0,\n\t.txn_request_size = 0,\n\t.txn_result_size = 0,\n\t.txn_result_count = 0\n};\n\nstatic inline void xds110_set_u32(uint8_t *buffer, uint32_t value)\n{\n\tbuffer[3] = (value >> 24) & 0xff;\n\tbuffer[2] = (value >> 16) & 0xff;\n\tbuffer[1] = (value >> 8) & 0xff;\n\tbuffer[0] = (value >> 0) & 0xff;\n}\n\nstatic inline void xds110_set_u16(uint8_t *buffer, uint16_t value)\n{\n\tbuffer[1] = (value >> 8) & 0xff;\n\tbuffer[0] = (value >> 0) & 0xff;\n}\n\nstatic inline uint32_t xds110_get_u32(uint8_t *buffer)\n{\n\tuint32_t value = (((uint32_t)buffer[3]) << 24) |\n\t\t\t\t\t (((uint32_t)buffer[2]) << 16) |\n\t\t\t\t\t (((uint32_t)buffer[1]) << 8)  |\n\t\t\t\t\t (((uint32_t)buffer[0]) << 0);\n\treturn value;\n}\n\nstatic inline uint16_t xds110_get_u16(uint8_t *buffer)\n{\n\tuint16_t value = (((uint32_t)buffer[1]) << 8) |\n\t\t\t\t\t (((uint32_t)buffer[0]) << 0);\n\treturn value;\n}\n\n/***************************************************************************\n *   usb connection routines                                               *\n *                                                                         *\n *   The following functions handle connecting, reading, and writing to    *\n *   the XDS110 over USB using the libusb library.                         *\n ***************************************************************************/\n\nstatic bool usb_connect(void)\n{\n\tstruct libusb_context *ctx  = NULL;\n\tstruct libusb_device **list = NULL;\n\tstruct libusb_device_handle *dev  = NULL;\n\n\tstruct libusb_device_descriptor desc;\n\n\t/* The vid/pids of possible XDS110 configurations */\n\tuint16_t vids[] = { 0x0451, 0x0451, 0x1cbe };\n\tuint16_t pids[] = { 0xbef3, 0xbef4, 0x02a5 };\n\t/* Corresponding interface and endpoint numbers for configurations */\n\tuint8_t interfaces[] = { 2, 2, 0 };\n\tuint8_t endpoints_in[] = { 3, 3, 1 };\n\tuint8_t endpoints_out[] = { 2, 2, 1 };\n\n\tssize_t count = 0;\n\tssize_t i = 0;\n\tint result = 0;\n\tbool found = false;\n\tuint32_t device = 0;\n\tbool match = false;\n\n\t/* Initialize libusb context */\n\tresult = libusb_init(&ctx);\n\n\tif (result == 0) {\n\t\t/* Get list of USB devices attached to system */\n\t\tcount = libusb_get_device_list(ctx, &list);\n\t\tif (count <= 0) {\n\t\t\tresult = -1;\n\t\t\tlist = NULL;\n\t\t}\n\t}\n\n\tif (result == 0) {\n\t\t/* Scan through list of devices for any XDS110s */\n\t\tfor (i = 0; i < count; i++) {\n\t\t\t/* Check for device vid/pid match */\n\t\t\tlibusb_get_device_descriptor(list[i], &desc);\n\t\t\tmatch = false;\n\t\t\tfor (device = 0; device < ARRAY_SIZE(vids); device++) {\n\t\t\t\tif (desc.idVendor == vids[device] &&\n\t\t\t\t\tdesc.idProduct == pids[device]) {\n\t\t\t\t\tmatch = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (match) {\n\t\t\t\tresult = libusb_open(list[i], &dev);\n\t\t\t\tif (result == 0) {\n\t\t\t\t\tconst int max_data = 256;\n\t\t\t\t\tunsigned char data[max_data + 1];\n\t\t\t\t\t*data = '\\0';\n\n\t\t\t\t\t/* May be the requested device if serial number matches */\n\t\t\t\t\tif (!adapter_get_required_serial()) {\n\t\t\t\t\t\t/* No serial number given; match first XDS110 found */\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Get the device's serial number string */\n\t\t\t\t\t\tresult = libusb_get_string_descriptor_ascii(dev,\n\t\t\t\t\t\t\t\t\tdesc.iSerialNumber, data, max_data);\n\t\t\t\t\t\tif (result > 0 &&\n\t\t\t\t\t\t\tstrcmp((char *)data, adapter_get_required_serial()) == 0) {\n\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t/* If we fall though to here, we don't want this device */\n\t\t\t\t\tlibusb_close(dev);\n\t\t\t\t\tdev = NULL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t * We can fall through the for() loop with two possible exit conditions:\n\t * 1) found the right XDS110, and that device is open\n\t * 2) didn't find the XDS110, and no devices are currently open\n\t */\n\n\tif (list) {\n\t\t/* Free the device list, we're done with it */\n\t\tlibusb_free_device_list(list, 1);\n\t}\n\n\tif (found) {\n\t\t/* Save the vid/pid of the device we're using */\n\t\txds110.vid = vids[device];\n\t\txds110.pid = pids[device];\n\n\t\t/* Save the debug interface and endpoints for the device */\n\t\txds110.interface = interfaces[device];\n\t\txds110.endpoint_in = endpoints_in[device] | LIBUSB_ENDPOINT_IN;\n\t\txds110.endpoint_out = endpoints_out[device] | LIBUSB_ENDPOINT_OUT;\n\n\t\t/* Save the context and device handles */\n\t\txds110.ctx = ctx;\n\t\txds110.dev = dev;\n\n\t\t/* Set libusb to auto detach kernel */\n\t\t(void)libusb_set_auto_detach_kernel_driver(dev, 1);\n\n\t\t/* Claim the debug interface on the XDS110 */\n\t\tresult = libusb_claim_interface(dev, xds110.interface);\n\t} else {\n\t\t/* Couldn't find an XDS110, flag the error */\n\t\tresult = -1;\n\t}\n\n\t/* On an error, clean up what we can */\n\tif (result != 0) {\n\t\tif (dev) {\n\t\t\t/* Release the debug and data interface on the XDS110 */\n\t\t\t(void)libusb_release_interface(dev, xds110.interface);\n\t\t\tlibusb_close(dev);\n\t\t}\n\t\tif (ctx)\n\t\t\tlibusb_exit(ctx);\n\t\txds110.ctx = NULL;\n\t\txds110.dev = NULL;\n\t}\n\n\t/* Log the results */\n\tif (result == 0)\n\t\tLOG_INFO(\"XDS110: connected\");\n\telse\n\t\tLOG_ERROR(\"XDS110: failed to connect\");\n\n\treturn (result == 0) ? true : false;\n}\n\nstatic void usb_disconnect(void)\n{\n\tif (xds110.dev) {\n\t\t/* Release the debug and data interface on the XDS110 */\n\t\t(void)libusb_release_interface(xds110.dev, xds110.interface);\n\t\tlibusb_close(xds110.dev);\n\t\txds110.dev = NULL;\n\t}\n\tif (xds110.ctx) {\n\t\tlibusb_exit(xds110.ctx);\n\t\txds110.ctx = NULL;\n\t}\n\n\tLOG_INFO(\"XDS110: disconnected\");\n}\n\nstatic bool usb_read(unsigned char *buffer, int size, int *bytes_read,\n\tint timeout)\n{\n\tint result;\n\n\tif (!xds110.dev || !buffer || !bytes_read)\n\t\treturn false;\n\n\t/* Force a non-zero timeout to prevent blocking */\n\tif (timeout == 0)\n\t\ttimeout = DEFAULT_TIMEOUT;\n\n\tresult = libusb_bulk_transfer(xds110.dev, xds110.endpoint_in, buffer, size,\n\t\t\t\tbytes_read, timeout);\n\n\treturn (result == 0) ? true : false;\n}\n\nstatic bool usb_write(unsigned char *buffer, int size, int *written)\n{\n\tint bytes_written = 0;\n\tint result = LIBUSB_SUCCESS;\n\tint retries = 0;\n\n\tif (!xds110.dev || !buffer)\n\t\treturn false;\n\n\tresult = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer,\n\t\t\t\tsize, &bytes_written, 0);\n\n\twhile (result == LIBUSB_ERROR_PIPE && retries < 3) {\n\t\t/* Try clearing the pipe stall and retry transfer */\n\t\tlibusb_clear_halt(xds110.dev, xds110.endpoint_out);\n\t\tresult = libusb_bulk_transfer(xds110.dev, xds110.endpoint_out, buffer,\n\t\t\t\t\tsize, &bytes_written, 0);\n\t\tretries++;\n\t}\n\n\tif (written)\n\t\t*written = bytes_written;\n\n\treturn (result == 0 && size == bytes_written) ? true : false;\n}\n\nstatic bool usb_get_response(uint32_t *total_bytes_read, uint32_t timeout)\n{\n\tstatic unsigned char buffer[MAX_PACKET];\n\tint bytes_read;\n\tuint16_t size;\n\tuint16_t count;\n\tbool success;\n\n\tsize = 0;\n\tsuccess = true;\n\twhile (success) {\n\t\tsuccess = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);\n\t\tif (success) {\n\t\t\t/*\n\t\t\t * Validate that this appears to be a good response packet\n\t\t\t * First check it contains enough data for header and error\n\t\t\t * code, plus the first character is the start character\n\t\t\t */\n\t\t\tif (bytes_read >= 7 && '*' == buffer[0]) {\n\t\t\t\t/* Extract the payload size */\n\t\t\t\tsize = xds110_get_u16(&buffer[1]);\n\t\t\t\t/* Sanity test on payload size */\n\t\t\t\tif (USB_PAYLOAD_SIZE >= size && 4 <= size) {\n\t\t\t\t\t/* Check we didn't get more data than expected */\n\t\t\t\t\tif ((bytes_read - 3) <= size) {\n\t\t\t\t\t\t/* Packet appears to be valid, move on */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t/*\n\t\t * Somehow received an invalid packet, retry till we\n\t\t * time out or a valid response packet is received\n\t\t */\n\t}\n\n\t/* Abort now if we didn't receive a valid response */\n\tif (!success) {\n\t\tif (total_bytes_read)\n\t\t\t*total_bytes_read = 0;\n\t\treturn false;\n\t}\n\n\t/* Build the return payload into xds110.read_payload */\n\n\t/* Copy over payload data from received buffer (skipping header) */\n\tcount = 0;\n\tbytes_read -= 3;\n\tmemcpy((void *)&xds110.read_payload[count], (void *)&buffer[3], bytes_read);\n\tcount += bytes_read;\n\t/*\n\t * Drop timeout to just 1/2 second. Once the XDS110 starts sending\n\t * a response, the remaining packets should arrive in short order\n\t */\n\tif (timeout > 500)\n\t\ttimeout = 500; /* ms */\n\n\t/* If there's more data to retrieve, get it now */\n\twhile ((count < size) && success) {\n\t\tsuccess = usb_read(buffer, sizeof(buffer), &bytes_read, timeout);\n\t\tif (success) {\n\t\t\tif ((count + bytes_read) > size) {\n\t\t\t\t/* Read too much data, not a valid packet, abort */\n\t\t\t\tsuccess = false;\n\t\t\t} else {\n\t\t\t\t/* Copy this data over to xds110.read_payload */\n\t\t\t\tmemcpy((void *)&xds110.read_payload[count], (void *)buffer,\n\t\t\t\t\tbytes_read);\n\t\t\t\tcount += bytes_read;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!success)\n\t\tcount = 0;\n\tif (total_bytes_read)\n\t\t*total_bytes_read = count;\n\n\treturn success;\n}\n\nstatic bool usb_send_command(uint16_t size)\n{\n\tint written;\n\tbool success = true;\n\n\t/* Check the packet length */\n\tif (size > USB_PAYLOAD_SIZE)\n\t\treturn false;\n\n\t/* Place the start character into the packet buffer */\n\txds110.write_packet[0] = '*';\n\n\t/* Place the payload size into the packet buffer */\n\txds110_set_u16(&xds110.write_packet[1], size);\n\n\t/* Adjust size to include header */\n\tsize += 3;\n\n\t/* Send the data via the USB connection */\n\tsuccess = usb_write(xds110.write_packet, (int)size, &written);\n\n\t/* Check if the correct number of bytes was written */\n\tif (written != (int)size)\n\t\tsuccess = false;\n\n\treturn success;\n}\n\n/***************************************************************************\n *   XDS110 firmware API routines                                          *\n *                                                                         *\n *   The following functions handle calling into the XDS110 firmware to    *\n *   perform requested debug actions.                                      *\n ***************************************************************************/\n\nstatic bool xds_execute(uint32_t out_length, uint32_t in_length,\n\tuint32_t attempts, uint32_t timeout)\n{\n\tbool done = false;\n\tbool success = true;\n\tint error = 0;\n\tuint32_t bytes_read = 0;\n\n\tif (!xds110.dev)\n\t\treturn false;\n\n\twhile (!done && attempts > 0) {\n\t\tattempts--;\n\n\t\t/* Send command to XDS110 */\n\t\tsuccess = usb_send_command(out_length);\n\n\t\tif (success) {\n\t\t\t/* Get response from XDS110 */\n\t\t\tsuccess = usb_get_response(&bytes_read, timeout);\n\t\t}\n\n\t\tif (success) {\n\t\t\t/* Check for valid response from XDS code handling */\n\t\t\tif (bytes_read != in_length) {\n\t\t\t\t/* Unexpected amount of data returned */\n\t\t\t\tsuccess = false;\n\t\t\t\tLOG_DEBUG(\"XDS110: command 0x%02x return %\" PRIu32 \" bytes, expected %\" PRIu32,\n\t\t\t\t\txds110.write_payload[0], bytes_read, in_length);\n\t\t\t} else {\n\t\t\t\t/* Extract error code from return packet */\n\t\t\t\terror = (int)xds110_get_u32(&xds110.read_payload[0]);\n\t\t\t\tdone = true;\n\t\t\t\tif (error != SC_ERR_NONE)\n\t\t\t\t\tLOG_DEBUG(\"XDS110: command 0x%02x returned error %d\",\n\t\t\t\t\t\txds110.write_payload[0], error);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!success)\n\t\terror = SC_ERR_XDS110_FAIL;\n\n\tif (error != 0)\n\t\tsuccess = false;\n\n\treturn success;\n}\n\nstatic bool xds_connect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = XDS_CONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_disconnect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = XDS_DISCONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_version(uint32_t *firmware_id, uint16_t *hardware_id)\n{\n\tuint8_t *fw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */\n\tuint8_t *hw_id_pntr = &xds110.read_payload[XDS_IN_LEN + 4]; /* 16-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_VERSION;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN + 6, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\tif (success) {\n\t\tif (firmware_id)\n\t\t\t*firmware_id = xds110_get_u32(fw_id_pntr);\n\t\tif (hardware_id)\n\t\t\t*hardware_id = xds110_get_u16(hw_id_pntr);\n\t}\n\n\treturn success;\n}\n\nstatic bool xds_set_tck_delay(uint32_t delay)\n{\n\tuint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_SET_TCK;\n\n\txds110_set_u32(delay_pntr, delay);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_set_trst(uint8_t trst)\n{\n\tuint8_t *trst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_SET_TRST;\n\n\t*trst_pntr = trst;\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_cycle_tck(uint32_t count)\n{\n\tuint8_t *count_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_CYCLE_TCK;\n\n\txds110_set_u32(count_pntr, count);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_goto_state(uint32_t state)\n{\n\tuint8_t *state_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\tuint8_t *transit_pntr = &xds110.write_payload[XDS_OUT_LEN+4]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_GOTO_STATE;\n\n\txds110_set_u32(state_pntr, state);\n\txds110_set_u32(transit_pntr, XDS_JTAG_TRANSIT_QUICKEST);\n\n\tsuccess = xds_execute(XDS_OUT_LEN+8, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_jtag_scan(uint32_t shift_state, uint16_t shift_bits,\n\tuint32_t end_state, uint8_t *data_out, uint8_t *data_in)\n{\n\tuint8_t *bits_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 16-bits */\n\tuint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */\n\tuint8_t *trans1_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 8-bits */\n\tuint8_t *end_pntr = &xds110.write_payload[XDS_OUT_LEN + 4]; /* 8-bits */\n\tuint8_t *trans2_pntr = &xds110.write_payload[XDS_OUT_LEN + 5]; /* 8-bits */\n\tuint8_t *pre_pntr = &xds110.write_payload[XDS_OUT_LEN + 6]; /* 16-bits */\n\tuint8_t *pos_pntr = &xds110.write_payload[XDS_OUT_LEN + 8]; /* 16-bits */\n\tuint8_t *delay_pntr = &xds110.write_payload[XDS_OUT_LEN + 10]; /* 16-bits */\n\tuint8_t *rep_pntr = &xds110.write_payload[XDS_OUT_LEN + 12]; /* 16-bits */\n\tuint8_t *out_pntr = &xds110.write_payload[XDS_OUT_LEN + 14]; /* 16-bits */\n\tuint8_t *in_pntr = &xds110.write_payload[XDS_OUT_LEN + 16]; /* 16-bits */\n\tuint8_t *data_out_pntr = &xds110.write_payload[XDS_OUT_LEN + 18];\n\tuint8_t *data_in_pntr = &xds110.read_payload[XDS_IN_LEN+0];\n\n\tuint16_t total_bytes = DIV_ROUND_UP(shift_bits, 8);\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_JTAG_SCAN;\n\n\txds110_set_u16(bits_pntr, shift_bits); /* bits to scan */\n\t*path_pntr = (uint8_t)(shift_state & 0xff); /* IR vs DR path */\n\t*trans1_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* start state route */\n\t*end_pntr = (uint8_t)(end_state & 0xff); /* JTAG state after scan */\n\t*trans2_pntr = (uint8_t)XDS_JTAG_TRANSIT_QUICKEST; /* end state route */\n\txds110_set_u16(pre_pntr, 0); /* number of preamble bits */\n\txds110_set_u16(pos_pntr, 0); /* number of postamble bits */\n\txds110_set_u16(delay_pntr, 0); /* number of extra TCKs after scan */\n\txds110_set_u16(rep_pntr, 1); /* number of repetitions */\n\txds110_set_u16(out_pntr, total_bytes); /* out buffer offset (if repeats) */\n\txds110_set_u16(in_pntr, total_bytes); /* in buffer offset (if repeats) */\n\n\tmemcpy((void *)data_out_pntr, (void *)data_out, total_bytes);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 18 + total_bytes,\n\t\tXDS_IN_LEN + total_bytes, DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);\n\n\tif (success)\n\t\tmemcpy((void *)data_in, (void *)data_in_pntr, total_bytes);\n\n\treturn success;\n}\n\nstatic bool xds_set_srst(uint8_t srst)\n{\n\tuint8_t *srst_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_SET_SRST;\n\n\t*srst_pntr = srst;\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 1, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cmapi_connect(uint32_t *idcode)\n{\n\tuint8_t *idcode_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = CMAPI_CONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN+4, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\tif (success) {\n\t\tif (idcode)\n\t\t\t*idcode = xds110_get_u32(idcode_pntr);\n\t}\n\n\treturn success;\n}\n\nstatic bool cmapi_disconnect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = CMAPI_DISCONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cmapi_acquire(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = CMAPI_ACQUIRE;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cmapi_release(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = CMAPI_RELEASE;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cmapi_read_dap_reg(uint32_t type, uint32_t ap_num,\n\tuint32_t address, uint32_t *value)\n{\n\tuint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */\n\tuint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */\n\tuint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */\n\tuint8_t *value_pntr = &xds110.read_payload[XDS_IN_LEN + 0]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = CMAPI_REG_READ;\n\n\t*type_pntr = (uint8_t)(type & 0xff);\n\t*ap_num_pntr = (uint8_t)(ap_num & 0xff);\n\t*address_pntr = (uint8_t)(address & 0xff);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 3, XDS_IN_LEN + 4, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\tif (success) {\n\t\tif (value)\n\t\t\t*value = xds110_get_u32(value_pntr);\n\t}\n\n\treturn success;\n}\n\nstatic bool cmapi_write_dap_reg(uint32_t type, uint32_t ap_num,\n\tuint32_t address, uint32_t *value)\n{\n\tuint8_t *type_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 8-bits */\n\tuint8_t *ap_num_pntr = &xds110.write_payload[XDS_OUT_LEN + 1]; /* 8-bits */\n\tuint8_t *address_pntr = &xds110.write_payload[XDS_OUT_LEN + 2]; /* 8-bits */\n\tuint8_t *value_pntr = &xds110.write_payload[XDS_OUT_LEN + 3]; /* 32-bits */\n\n\tbool success;\n\n\tif (!value)\n\t\treturn false;\n\n\txds110.write_payload[0] = CMAPI_REG_WRITE;\n\n\t*type_pntr = (uint8_t)(type & 0xff);\n\t*ap_num_pntr = (uint8_t)(ap_num & 0xff);\n\t*address_pntr = (uint8_t)(address & 0xff);\n\txds110_set_u32(value_pntr, *value);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 7, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool swd_connect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = SWD_CONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool swd_disconnect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = SWD_DISCONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cjtag_connect(uint32_t format)\n{\n\tuint8_t *format_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = CJTAG_CONNECT;\n\n\txds110_set_u32(format_pntr, format);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 4, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool cjtag_disconnect(void)\n{\n\tbool success;\n\n\txds110.write_payload[0] = CJTAG_DISCONNECT;\n\n\tsuccess = xds_execute(XDS_OUT_LEN, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool xds_set_supply(uint32_t voltage)\n{\n\tuint8_t *volts_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\tuint8_t *source_pntr = &xds110.write_payload[XDS_OUT_LEN + 4]; /* 8-bits */\n\n\tbool success;\n\n\txds110.write_payload[0] = XDS_SET_SUPPLY;\n\n\txds110_set_u32(volts_pntr, voltage);\n\t*source_pntr = (uint8_t)(voltage != 0 ? 1 : 0);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 5, XDS_IN_LEN, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\nstatic bool ocd_dap_request(uint8_t *dap_requests, uint32_t request_size,\n\tuint32_t *dap_results, uint32_t result_count)\n{\n\tuint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];\n\tuint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];\n\n\tbool success;\n\n\tif (!dap_requests || !dap_results)\n\t\treturn false;\n\n\txds110.write_payload[0] = OCD_DAP_REQUEST;\n\n\tmemcpy((void *)request_pntr, (void *)dap_requests, request_size);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + request_size,\n\t\t\t\tXDS_IN_LEN + (result_count * 4), DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\tif (success && (result_count > 0))\n\t\tmemcpy((void *)dap_results, (void *)result_pntr, result_count * 4);\n\n\treturn success;\n}\n\nstatic bool ocd_scan_request(uint8_t *scan_requests, uint32_t request_size,\n\tuint8_t *scan_results, uint32_t result_size)\n{\n\tuint8_t *request_pntr = &xds110.write_payload[XDS_OUT_LEN + 0];\n\tuint8_t *result_pntr = &xds110.read_payload[XDS_IN_LEN + 0];\n\n\tbool success;\n\n\tif (!scan_requests || !scan_results)\n\t\treturn false;\n\n\txds110.write_payload[0] = OCD_SCAN_REQUEST;\n\n\tmemcpy((void *)request_pntr, (void *)scan_requests, request_size);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + request_size,\n\t\t\t\tXDS_IN_LEN + result_size, DEFAULT_ATTEMPTS,\n\t\t\t\tDEFAULT_TIMEOUT);\n\n\tif (success && (result_size > 0))\n\t\tmemcpy((void *)scan_results, (void *)result_pntr, result_size);\n\n\treturn success;\n}\n\nstatic bool ocd_pathmove(uint32_t num_states, uint8_t *path)\n{\n\tuint8_t *num_pntr = &xds110.write_payload[XDS_OUT_LEN + 0]; /* 32-bits */\n\tuint8_t *path_pntr = &xds110.write_payload[XDS_OUT_LEN + 4];\n\n\tbool success;\n\n\tif (!path)\n\t\treturn false;\n\n\txds110.write_payload[0] = OCD_PATHMOVE;\n\n\txds110_set_u32(num_pntr, num_states);\n\n\tmemcpy((void *)path_pntr, (void *)path, num_states);\n\n\tsuccess = xds_execute(XDS_OUT_LEN + 4 + num_states, XDS_IN_LEN,\n\t\t\t\tDEFAULT_ATTEMPTS, DEFAULT_TIMEOUT);\n\n\treturn success;\n}\n\n/***************************************************************************\n *   swd driver interface                                                  *\n *                                                                         *\n *   The following functions provide SWD support to OpenOCD.               *\n ***************************************************************************/\n\nstatic int xds110_swd_init(void)\n{\n\txds110.is_swd_mode = true;\n\treturn ERROR_OK;\n}\n\nstatic int xds110_swd_switch_seq(enum swd_special_seq seq)\n{\n\tuint32_t idcode;\n\tbool success;\n\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_ERROR(\"Sequence SWD line reset (%d) not supported\", seq);\n\t\treturn ERROR_FAIL;\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\txds110.is_swd_mode = false;\n\t\txds110.is_cmapi_connected = false;\n\t\txds110.is_cmapi_acquired = false;\n\t\t/* Run sequence to put target in SWD mode */\n\t\tsuccess = swd_connect();\n\t\t/* Re-initialize CMAPI API for DAP access */\n\t\tif (success) {\n\t\t\txds110.is_swd_mode = true;\n\t\t\tsuccess = cmapi_connect(&idcode);\n\t\t\tif (success) {\n\t\t\t\txds110.is_cmapi_connected = true;\n\t\t\t\tsuccess = cmapi_acquire();\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\txds110.is_swd_mode = false;\n\t\txds110.is_cmapi_connected = false;\n\t\txds110.is_cmapi_acquired = false;\n\t\t/* Run sequence to put target in JTAG mode */\n\t\tsuccess = swd_disconnect();\n\t\tif (success) {\n\t\t\t/* Re-initialize JTAG interface */\n\t\t\tsuccess = cjtag_connect(MODE_JTAG);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (success)\n\t\treturn ERROR_OK;\n\telse\n\t\treturn ERROR_FAIL;\n}\n\nstatic bool xds110_legacy_read_reg(uint8_t cmd, uint32_t *value)\n{\n\t/* Make sure this is a read request */\n\tbool is_read_request = (0 != (SWD_CMD_RNW & cmd));\n\t/* Determine whether this is a DP or AP register access */\n\tuint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;\n\t/* Determine the AP number from cached SELECT value */\n\tuint32_t ap_num = (xds110.select & 0xff000000) >> 24;\n\t/* Extract register address from command */\n\tuint32_t address = ((cmd & SWD_CMD_A32) >> 1);\n\t/* Extract bank address from cached SELECT value */\n\tuint32_t bank = (xds110.select & 0x000000f0);\n\n\tuint32_t reg_value = 0;\n\tuint32_t temp_value = 0;\n\n\tbool success;\n\n\tif (!is_read_request)\n\t\treturn false;\n\n\tif (type == DAP_AP) {\n\t\t/* Add bank address to register address for CMAPI call */\n\t\taddress |= bank;\n\t}\n\n\tif (DAP_DP == type && DAP_DP_RDBUFF == address && xds110.use_rdbuff) {\n\t\t/* If RDBUFF is cached and this is a DP RDBUFF read, use the cache */\n\t\treg_value = xds110.rdbuff;\n\t\tsuccess = true;\n\t} else if (DAP_AP == type && DAP_AP_DRW == address && xds110.use_rdbuff) {\n\t\t/* If RDBUFF is cached and this is an AP DRW read, use the cache, */\n\t\t/* but still call into the firmware to get the next read. */\n\t\treg_value = xds110.rdbuff;\n\t\tsuccess = cmapi_read_dap_reg(type, ap_num, address, &temp_value);\n\t} else {\n\t\tsuccess = cmapi_read_dap_reg(type, ap_num, address, &temp_value);\n\t\tif (success)\n\t\t\treg_value = temp_value;\n\t}\n\n\t/* Mark that we have consumed or invalidated the RDBUFF cache */\n\txds110.use_rdbuff = false;\n\n\t/* Handle result of read attempt */\n\tif (!success)\n\t\tLOG_ERROR(\"XDS110: failed to read DAP register\");\n\telse if (value)\n\t\t*value = reg_value;\n\n\tif (success && DAP_AP == type) {\n\t\t/*\n\t\t * On a successful DAP AP read, we actually have the value from RDBUFF,\n\t\t * the firmware will have run the AP request and made the RDBUFF read\n\t\t */\n\t\txds110.use_rdbuff = true;\n\t\txds110.rdbuff = temp_value;\n\t}\n\n\treturn success;\n}\n\nstatic bool xds110_legacy_write_reg(uint8_t cmd, uint32_t value)\n{\n\t/* Make sure this isn't a read request */\n\tbool is_read_request = (0 != (SWD_CMD_RNW & cmd));\n\t/* Determine whether this is a DP or AP register access */\n\tuint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;\n\t/* Determine the AP number from cached SELECT value */\n\tuint32_t ap_num = (xds110.select & 0xff000000) >> 24;\n\t/* Extract register address from command */\n\tuint32_t address = ((cmd & SWD_CMD_A32) >> 1);\n\t/* Extract bank address from cached SELECT value */\n\tuint32_t bank = (xds110.select & 0x000000f0);\n\n\tbool success;\n\n\tif (is_read_request)\n\t\treturn false;\n\n\t/* Invalidate the RDBUFF cache */\n\txds110.use_rdbuff = false;\n\n\tif (type == DAP_AP) {\n\t\t/* Add bank address to register address for CMAPI call */\n\t\taddress |= bank;\n\t\t/* Any write to an AP register invalidates the firmware's cache */\n\t\txds110.is_ap_dirty = true;\n\t} else if (address == DAP_DP_SELECT) {\n\t\t/* Any write to the SELECT register invalidates the firmware's cache */\n\t\txds110.is_ap_dirty = true;\n\t}\n\n\tsuccess = cmapi_write_dap_reg(type, ap_num, address, &value);\n\n\tif (!success) {\n\t\tLOG_ERROR(\"XDS110: failed to write DAP register\");\n\t} else {\n\t\t/*\n\t\t * If the debugger wrote to SELECT, cache the value\n\t\t * to use to build the apNum and address values above\n\t\t */\n\t\tif ((type == DAP_DP) && (address == DAP_DP_SELECT))\n\t\t\txds110.select = value;\n\t}\n\n\treturn success;\n}\n\nstatic int xds110_swd_run_queue(void)\n{\n\tstatic uint32_t dap_results[MAX_RESULT_QUEUE];\n\tuint8_t cmd;\n\tuint32_t request;\n\tuint32_t result;\n\tuint32_t value;\n\tbool success = true;\n\n\tif (xds110.txn_request_size == 0)\n\t\treturn ERROR_OK;\n\n\t/* Terminate request queue */\n\txds110.txn_requests[xds110.txn_request_size++] = 0;\n\n\tif (xds110.firmware >= OCD_FIRMWARE_VERSION) {\n\t\t/* XDS110 firmware has the API to directly handle the queue */\n\t\tsuccess = ocd_dap_request(xds110.txn_requests,\n\t\t\txds110.txn_request_size, dap_results, xds110.txn_result_count);\n\t} else {\n\t\t/* Legacy firmware needs to handle queue via discrete DAP calls */\n\t\trequest = 0;\n\t\tresult = 0;\n\t\twhile (xds110.txn_requests[request] != 0) {\n\t\t\tcmd = xds110.txn_requests[request++];\n\t\t\tif (0 == (SWD_CMD_RNW & cmd)) {\n\t\t\t\t/* DAP register write command */\n\t\t\t\tvalue  = (uint32_t)(xds110.txn_requests[request++]) <<  0;\n\t\t\t\tvalue |= (uint32_t)(xds110.txn_requests[request++]) <<  8;\n\t\t\t\tvalue |= (uint32_t)(xds110.txn_requests[request++]) << 16;\n\t\t\t\tvalue |= (uint32_t)(xds110.txn_requests[request++]) << 24;\n\t\t\t\tif (success)\n\t\t\t\t\tsuccess = xds110_legacy_write_reg(cmd, value);\n\t\t\t} else {\n\t\t\t\t/* DAP register read command */\n\t\t\t\tvalue = 0;\n\t\t\t\tif (success)\n\t\t\t\t\tsuccess = xds110_legacy_read_reg(cmd, &value);\n\t\t\t\tdap_results[result++] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Transfer results into caller's buffers */\n\tfor (result = 0; result < xds110.txn_result_count; result++)\n\t\tif (xds110.txn_dap_results[result])\n\t\t\t*xds110.txn_dap_results[result] = dap_results[result];\n\n\txds110.txn_request_size = 0;\n\txds110.txn_result_size = 0;\n\txds110.txn_result_count = 0;\n\n\treturn (success) ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic void xds110_swd_queue_cmd(uint8_t cmd, uint32_t *value)\n{\n\t/* Check if this is a read or write request */\n\tbool is_read_request = (0 != (SWD_CMD_RNW & cmd));\n\t/* Determine whether this is a DP or AP register access */\n\tuint32_t type = (0 != (SWD_CMD_APNDP & cmd)) ? DAP_AP : DAP_DP;\n\t/* Extract register address from command */\n\tuint32_t address = ((cmd & SWD_CMD_A32) >> 1);\n\tuint32_t request_size = (is_read_request) ? 1 : 5;\n\n\t/* Check if new request would be too large to fit */\n\tif (((xds110.txn_request_size + request_size + 1) > MAX_DATA_BLOCK) ||\n\t\t((xds110.txn_result_count + 1) > MAX_RESULT_QUEUE))\n\t\txds110_swd_run_queue();\n\n\t/* Set the START bit in cmd to ensure cmd is not zero */\n\t/* (a value of zero is used to terminate the buffer) */\n\tcmd |= SWD_CMD_START;\n\n\t/* Add request to queue; queue is built marshalled for XDS110 call */\n\tif (is_read_request) {\n\t\t/* Queue read request, save pointer to pass back result */\n\t\txds110.txn_requests[xds110.txn_request_size++] = cmd;\n\t\txds110.txn_dap_results[xds110.txn_result_count++] = value;\n\t\txds110.txn_result_size += 4;\n\t} else {\n\t\t/* Check for and prevent sticky overrun detection */\n\t\tif (DAP_DP == type && DAP_DP_CTRL == address &&\n\t\t\t(*value & CORUNDETECT)) {\n\t\t\tLOG_DEBUG(\"XDS110: refusing to enable sticky overrun detection\");\n\t\t\t*value &= ~CORUNDETECT;\n\t\t}\n\t\t/* Queue write request, add value directly to queue buffer */\n\t\txds110.txn_requests[xds110.txn_request_size++] = cmd;\n\t\txds110.txn_requests[xds110.txn_request_size++] = (*value >>  0) & 0xff;\n\t\txds110.txn_requests[xds110.txn_request_size++] = (*value >>  8) & 0xff;\n\t\txds110.txn_requests[xds110.txn_request_size++] = (*value >> 16) & 0xff;\n\t\txds110.txn_requests[xds110.txn_request_size++] = (*value >> 24) & 0xff;\n\t}\n}\n\nstatic void xds110_swd_read_reg(uint8_t cmd, uint32_t *value,\n\tuint32_t ap_delay_clk)\n{\n\tassert(cmd & SWD_CMD_RNW);\n\txds110_swd_queue_cmd(cmd, value);\n}\nstatic void xds110_swd_write_reg(uint8_t cmd, uint32_t value,\n\tuint32_t ap_delay_clk)\n{\n\tassert(!(cmd & SWD_CMD_RNW));\n\txds110_swd_queue_cmd(cmd, &value);\n}\n\n/***************************************************************************\n *   jtag interface                                                        *\n *                                                                         *\n *   The following functions provide XDS110 interface to OpenOCD.          *\n ***************************************************************************/\n\nstatic void xds110_show_info(void)\n{\n\tuint32_t firmware = xds110.firmware;\n\n\tLOG_INFO(\"XDS110: vid/pid = %04x/%04x\", xds110.vid, xds110.pid);\n\tLOG_INFO(\"XDS110: firmware version = %\" PRIu32 \".%\" PRIu32 \".%\" PRIu32 \".%\" PRIu32,\n\t\t(((firmware >> 28) & 0xf) * 10) + ((firmware >> 24) & 0xf),\n\t\t(((firmware >> 20) & 0xf) * 10) + ((firmware >> 16) & 0xf),\n\t\t(((firmware >> 12) & 0xf) * 10) + ((firmware >>  8) & 0xf),\n\t\t(((firmware >>  4) & 0xf) * 10) + ((firmware >>  0) & 0xf));\n\tLOG_INFO(\"XDS110: hardware version = 0x%04x\", xds110.hardware);\n\tif (adapter_get_required_serial())\n\t\tLOG_INFO(\"XDS110: serial number = %s\", adapter_get_required_serial());\n\tif (xds110.is_swd_mode) {\n\t\tLOG_INFO(\"XDS110: connected to target via SWD\");\n\t\tLOG_INFO(\"XDS110: SWCLK set to %\" PRIu32 \" kHz\", xds110.speed);\n\t} else {\n\t\tLOG_INFO(\"XDS110: connected to target via JTAG\");\n\t\tLOG_INFO(\"XDS110: TCK set to %\" PRIu32 \" kHz\", xds110.speed);\n\t}\n\n\t/* Alert user that there's a better firmware to use */\n\tif (firmware < OCD_FIRMWARE_VERSION) {\n\t\tLOG_WARNING(\"XDS110: the firmware is not optimized for OpenOCD\");\n\t\tLOG_WARNING(OCD_FIRMWARE_UPGRADE);\n\t}\n}\n\nstatic int xds110_quit(void)\n{\n\tif (xds110.is_cmapi_acquired) {\n\t\t(void)cmapi_release();\n\t\txds110.is_cmapi_acquired = false;\n\t}\n\tif (xds110.is_cmapi_connected) {\n\t\t(void)cmapi_disconnect();\n\t\txds110.is_cmapi_connected = false;\n\t}\n\tif (xds110.is_connected) {\n\t\tif (xds110.is_swd_mode) {\n\t\t\t/* Switch out of SWD mode */\n\t\t\t(void)swd_disconnect();\n\t\t} else {\n\t\t\t/* Switch out of cJTAG mode */\n\t\t\t(void)cjtag_disconnect();\n\t\t}\n\t\t/* Tell firmware we're disconnecting */\n\t\t(void)xds_disconnect();\n\t\txds110.is_connected = false;\n\t}\n\t/* Close down the USB connection to the XDS110 debug probe */\n\tusb_disconnect();\n\n\treturn ERROR_OK;\n}\n\nstatic int xds110_init(void)\n{\n\tbool success;\n\n\t/* Establish USB connection to the XDS110 debug probe */\n\tsuccess = usb_connect();\n\n\tif (success) {\n\t\t/* Send connect message to XDS110 firmware */\n\t\tsuccess = xds_connect();\n\t\tif (success)\n\t\t\txds110.is_connected = true;\n\t}\n\n\tif (success) {\n\t\tuint32_t firmware;\n\t\tuint16_t hardware;\n\n\t\t/* Retrieve version IDs from firmware */\n\t\t/* Version numbers are stored in BCD format */\n\t\tsuccess = xds_version(&firmware, &hardware);\n\t\tif (success) {\n\t\t\t/* Save the firmware and hardware version */\n\t\t\txds110.firmware = firmware;\n\t\t\txds110.hardware = hardware;\n\t\t}\n\t}\n\n\tif (success) {\n\t\t/* Set supply voltage for stand-alone probes */\n\t\tif (xds110.hardware == XDS110_STAND_ALONE_ID) {\n\t\t\tsuccess = xds_set_supply(xds110.voltage);\n\t\t\t/* Allow time for target device to power up */\n\t\t\t/* (CC32xx takes up to 1300 ms before debug is enabled) */\n\t\t\talive_sleep(1500);\n\t\t} else if (xds110.voltage != 0) {\n\t\t\t/* Voltage supply not a feature of embedded probes */\n\t\t\tLOG_WARNING(\n\t\t\t\t\"XDS110: ignoring supply voltage, not supported on this probe\");\n\t\t}\n\t}\n\n\tif (success) {\n\t\tsuccess = xds_set_trst(0);\n\t\tif (success)\n\t\t\tsuccess = xds_cycle_tck(50);\n\t\tif (success)\n\t\t\tsuccess = xds_set_trst(1);\n\t\tif (success)\n\t\t\tsuccess = xds_cycle_tck(50);\n\t}\n\n\tif (success) {\n\t\tif (xds110.is_swd_mode) {\n\t\t\t/* Switch to SWD if needed */\n\t\t\tsuccess = swd_connect();\n\t\t} else {\n\t\t\tsuccess = cjtag_connect(MODE_JTAG);\n\t\t}\n\t}\n\n\tif (success && xds110.is_swd_mode) {\n\t\tuint32_t idcode;\n\n\t\t/* Connect to CMAPI interface in XDS110 */\n\t\tsuccess = cmapi_connect(&idcode);\n\n\t\t/* Acquire exclusive access to CMAPI interface */\n\t\tif (success) {\n\t\t\txds110.is_cmapi_connected = true;\n\t\t\tsuccess = cmapi_acquire();\n\t\t\tif (success)\n\t\t\t\txds110.is_cmapi_acquired = true;\n\t\t}\n\t}\n\n\tif (!success)\n\t\txds110_quit();\n\n\tif (success)\n\t\txds110_show_info();\n\n\treturn (success) ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic void xds110_legacy_scan(uint32_t shift_state, uint32_t total_bits,\n\tuint32_t end_state, uint8_t *data_out, uint8_t *data_in)\n{\n\t(void)xds_jtag_scan(shift_state, total_bits, end_state, data_out, data_in);\n}\n\nstatic void xds110_legacy_runtest(uint32_t clocks, uint32_t end_state)\n{\n\txds_goto_state(XDS_JTAG_STATE_IDLE);\n\txds_cycle_tck(clocks);\n\txds_goto_state(end_state);\n}\n\nstatic void xds110_legacy_stableclocks(uint32_t clocks)\n{\n\txds_cycle_tck(clocks);\n}\n\nstatic void xds110_flush(void)\n{\n\tuint8_t command;\n\tuint32_t clocks;\n\tuint32_t shift_state;\n\tuint32_t end_state;\n\tuint32_t bits;\n\tuint32_t bytes;\n\tuint32_t request;\n\tuint32_t result;\n\tuint8_t *data_out;\n\tuint8_t data_in[MAX_DATA_BLOCK];\n\tuint8_t *data_pntr;\n\n\tif (xds110.txn_request_size == 0)\n\t\treturn;\n\n\t/* Terminate request queue */\n\txds110.txn_requests[xds110.txn_request_size++] = 0;\n\n\tif (xds110.firmware >= OCD_FIRMWARE_VERSION) {\n\t\t/* Updated firmware has the API to directly handle the queue */\n\t\t(void)ocd_scan_request(xds110.txn_requests, xds110.txn_request_size,\n\t\t\tdata_in, xds110.txn_result_size);\n\t} else {\n\t\t/* Legacy firmware needs to handle queue via discrete JTAG calls */\n\t\trequest = 0;\n\t\tresult = 0;\n\t\twhile (xds110.txn_requests[request] != 0) {\n\t\t\tcommand = xds110.txn_requests[request++];\n\t\t\tswitch (command) {\n\t\t\t\tcase CMD_IR_SCAN:\n\t\t\t\tcase CMD_DR_SCAN:\n\t\t\t\t\tif (command == CMD_IR_SCAN)\n\t\t\t\t\t\tshift_state = XDS_JTAG_STATE_SHIFT_IR;\n\t\t\t\t\telse\n\t\t\t\t\t\tshift_state = XDS_JTAG_STATE_SHIFT_DR;\n\t\t\t\t\tend_state = (uint32_t)(xds110.txn_requests[request++]);\n\t\t\t\t\tbits  = (uint32_t)(xds110.txn_requests[request++]) << 0;\n\t\t\t\t\tbits |= (uint32_t)(xds110.txn_requests[request++]) << 8;\n\t\t\t\t\tdata_out = &xds110.txn_requests[request];\n\t\t\t\t\tbytes = DIV_ROUND_UP(bits, 8);\n\t\t\t\t\txds110_legacy_scan(shift_state, bits, end_state, data_out,\n\t\t\t\t\t\t&data_in[result]);\n\t\t\t\t\tresult += bytes;\n\t\t\t\t\trequest += bytes;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMD_RUNTEST:\n\t\t\t\t\tclocks  = (uint32_t)(xds110.txn_requests[request++]) <<  0;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) <<  8;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;\n\t\t\t\t\tend_state = (uint32_t)xds110.txn_requests[request++];\n\t\t\t\t\txds110_legacy_runtest(clocks, end_state);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMD_STABLECLOCKS:\n\t\t\t\t\tclocks  = (uint32_t)(xds110.txn_requests[request++]) <<  0;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) <<  8;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) << 16;\n\t\t\t\t\tclocks |= (uint32_t)(xds110.txn_requests[request++]) << 24;\n\t\t\t\t\txds110_legacy_stableclocks(clocks);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%x encountered\",\n\t\t\t\t\t\tcommand);\n\t\t\t\t\texit(-1);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Transfer results into caller's buffers from data_in buffer */\n\tbits = 0; /* Bit offset into current scan result */\n\tdata_pntr = data_in;\n\tfor (result = 0; result < xds110.txn_result_count; result++) {\n\t\tif (xds110.txn_scan_results[result].first) {\n\t\t\tif (bits != 0) {\n\t\t\t\tbytes = DIV_ROUND_UP(bits, 8);\n\t\t\t\tdata_pntr += bytes;\n\t\t\t}\n\t\t\tbits = 0;\n\t\t}\n\t\tif (xds110.txn_scan_results[result].buffer)\n\t\t\tbit_copy(xds110.txn_scan_results[result].buffer, 0, data_pntr,\n\t\t\t\tbits, xds110.txn_scan_results[result].num_bits);\n\t\tbits += xds110.txn_scan_results[result].num_bits;\n\t}\n\n\txds110.txn_request_size = 0;\n\txds110.txn_result_size = 0;\n\txds110.txn_result_count = 0;\n}\n\nstatic int xds110_reset(int trst, int srst)\n{\n\tuint8_t value;\n\tbool success;\n\tint retval = ERROR_OK;\n\n\tif (trst != -1) {\n\t\tif (trst == 0) {\n\t\t\t/* Deassert nTRST (active low) */\n\t\t\tvalue = 1;\n\t\t} else {\n\t\t\t/* Assert nTRST (active low) */\n\t\t\tvalue = 0;\n\t\t}\n\t\tsuccess = xds_set_trst(value);\n\t\tif (!success)\n\t\t\tretval = ERROR_FAIL;\n\t}\n\n\tif (srst != -1) {\n\t\tif (srst == 0) {\n\t\t\t/* Deassert nSRST (active low) */\n\t\t\tvalue = 1;\n\t\t} else {\n\t\t\t/* Assert nSRST (active low) */\n\t\t\tvalue = 0;\n\t\t}\n\t\tsuccess = xds_set_srst(value);\n\t\tif (!success)\n\t\t\tretval = ERROR_FAIL;\n\n\t\t/* Toggle TCK to trigger HIB on CC13x/CC26x devices */\n\t\tif (success && !xds110.is_swd_mode) {\n\t\t\t/* Toggle TCK for about 50 ms */\n\t\t\tsuccess = xds_cycle_tck(xds110.speed * 50);\n\t\t}\n\n\t\tif (!success)\n\t\t\tretval = ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic void xds110_execute_sleep(struct jtag_command *cmd)\n{\n\tjtag_sleep(cmd->cmd.sleep->us);\n}\n\nstatic void xds110_execute_tlr_reset(struct jtag_command *cmd)\n{\n\t(void)xds_goto_state(XDS_JTAG_STATE_RESET);\n}\n\nstatic void xds110_execute_pathmove(struct jtag_command *cmd)\n{\n\tuint32_t i;\n\tuint32_t num_states;\n\tuint8_t *path;\n\n\tnum_states = (uint32_t)cmd->cmd.pathmove->num_states;\n\n\tif (num_states == 0)\n\t\treturn;\n\n\tpath = malloc(num_states * sizeof(uint8_t));\n\tif (!path) {\n\t\tLOG_ERROR(\"XDS110: unable to allocate memory\");\n\t\treturn;\n\t}\n\n\t/* Convert requested path states into XDS API states */\n\tfor (i = 0; i < num_states; i++)\n\t\tpath[i] = (uint8_t)xds_jtag_state[cmd->cmd.pathmove->path[i]];\n\n\tif (xds110.firmware >= OCD_FIRMWARE_VERSION) {\n\t\t/* Updated firmware fully supports pathmove */\n\t\t(void)ocd_pathmove(num_states, path);\n\t} else {\n\t\t/* Notify user that legacy firmware simply cannot handle pathmove */\n\t\tLOG_ERROR(\"XDS110: the firmware does not support pathmove command\");\n\t\tLOG_ERROR(OCD_FIRMWARE_UPGRADE);\n\t\t/* If pathmove is required, then debug is not possible */\n\t\texit(-1);\n\t}\n\n\tfree((void *)path);\n}\n\nstatic void xds110_queue_scan(struct jtag_command *cmd)\n{\n\tint i;\n\tuint32_t offset;\n\tuint32_t total_fields;\n\tuint32_t total_bits;\n\tuint32_t total_bytes;\n\tuint8_t end_state;\n\tuint8_t *buffer;\n\n\t/* Calculate the total number of bits to scan */\n\ttotal_bits = 0;\n\ttotal_fields = 0;\n\tfor (i = 0; i < cmd->cmd.scan->num_fields; i++) {\n\t\ttotal_fields++;\n\t\ttotal_bits += (uint32_t)cmd->cmd.scan->fields[i].num_bits;\n\t}\n\n\tif (total_bits == 0)\n\t\treturn;\n\n\ttotal_bytes = DIV_ROUND_UP(total_bits, 8);\n\n\t/* Check if new request would be too large to fit */\n\tif (((xds110.txn_request_size + 1 + total_bytes + sizeof(end_state) + 1)\n\t\t> MAX_DATA_BLOCK) || ((xds110.txn_result_count + total_fields) >\n\t\tMAX_RESULT_QUEUE))\n\t\txds110_flush();\n\n\t/* Check if this single request is too large to fit */\n\tif ((1 + total_bytes + sizeof(end_state) + 1) > MAX_DATA_BLOCK) {\n\t\tLOG_ERROR(\"BUG: JTAG scan request is too large to handle (%\" PRIu32 \" bits)\",\n\t\t\ttotal_bits);\n\t\t/* Failing to run this scan mucks up debug on this target */\n\t\texit(-1);\n\t}\n\n\tif (cmd->cmd.scan->ir_scan)\n\t\txds110.txn_requests[xds110.txn_request_size++] = CMD_IR_SCAN;\n\telse\n\t\txds110.txn_requests[xds110.txn_request_size++] = CMD_DR_SCAN;\n\n\tend_state = (uint8_t)xds_jtag_state[cmd->cmd.scan->end_state];\n\txds110.txn_requests[xds110.txn_request_size++] = end_state;\n\n\txds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 0) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (total_bits >> 8) & 0xff;\n\n\t/* Build request data by flattening fields into single buffer */\n\t/* also populate the results array to return the results when run */\n\toffset = 0;\n\tbuffer = &xds110.txn_requests[xds110.txn_request_size];\n\t/* Clear data out buffer to default value of all zeros */\n\tmemset((void *)buffer, 0x00, total_bytes);\n\tfor (i = 0; i < cmd->cmd.scan->num_fields; i++) {\n\t\tif (cmd->cmd.scan->fields[i].out_value) {\n\t\t\t/* Copy over data to scan out into request buffer */\n\t\t\tbit_copy(buffer, offset, cmd->cmd.scan->fields[i].out_value, 0,\n\t\t\t\tcmd->cmd.scan->fields[i].num_bits);\n\t\t}\n\t\toffset += cmd->cmd.scan->fields[i].num_bits;\n\t\txds110.txn_scan_results[xds110.txn_result_count].first = (i == 0);\n\t\txds110.txn_scan_results[xds110.txn_result_count].num_bits =\n\t\t\tcmd->cmd.scan->fields[i].num_bits;\n\t\txds110.txn_scan_results[xds110.txn_result_count++].buffer =\n\t\t\tcmd->cmd.scan->fields[i].in_value;\n\t}\n\txds110.txn_request_size += total_bytes;\n\txds110.txn_result_size += total_bytes;\n}\n\nstatic void xds110_queue_runtest(struct jtag_command *cmd)\n{\n\tuint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;\n\tuint8_t end_state = (uint8_t)xds_jtag_state[cmd->cmd.runtest->end_state];\n\n\t/* Check if new request would be too large to fit */\n\tif ((xds110.txn_request_size + 1 + sizeof(clocks) + sizeof(end_state) + 1)\n\t\t> MAX_DATA_BLOCK)\n\t\txds110_flush();\n\n\t/* Queue request and cycle count directly to queue buffer */\n\txds110.txn_requests[xds110.txn_request_size++] = CMD_RUNTEST;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >>  0) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >>  8) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = end_state;\n}\n\nstatic void xds110_queue_stableclocks(struct jtag_command *cmd)\n{\n\tuint32_t clocks = (uint32_t)cmd->cmd.stableclocks->num_cycles;\n\n\t/* Check if new request would be too large to fit */\n\tif ((xds110.txn_request_size + 1 + sizeof(clocks) + 1) > MAX_DATA_BLOCK)\n\t\txds110_flush();\n\n\t/* Queue request and cycle count directly to queue buffer */\n\txds110.txn_requests[xds110.txn_request_size++] = CMD_STABLECLOCKS;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >>  0) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >>  8) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >> 16) & 0xff;\n\txds110.txn_requests[xds110.txn_request_size++] = (clocks >> 24) & 0xff;\n}\n\nstatic void xds110_execute_command(struct jtag_command *cmd)\n{\n\tswitch (cmd->type) {\n\t\tcase JTAG_SLEEP:\n\t\t\txds110_flush();\n\t\t\txds110_execute_sleep(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TLR_RESET:\n\t\t\txds110_flush();\n\t\t\txds110_execute_tlr_reset(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_PATHMOVE:\n\t\t\txds110_flush();\n\t\t\txds110_execute_pathmove(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_SCAN:\n\t\t\txds110_queue_scan(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_RUNTEST:\n\t\t\txds110_queue_runtest(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_STABLECLOCKS:\n\t\t\txds110_queue_stableclocks(cmd);\n\t\t\tbreak;\n\t\tcase JTAG_TMS:\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: unknown JTAG command type 0x%x encountered\",\n\t\t\t\tcmd->type);\n\t\t\texit(-1);\n\t}\n}\n\nstatic int xds110_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\n\twhile (cmd) {\n\t\txds110_execute_command(cmd);\n\t\tcmd = cmd->next;\n\t}\n\n\txds110_flush();\n\n\treturn ERROR_OK;\n}\n\nstatic int xds110_speed(int speed)\n{\n\tdouble freq_to_use;\n\tuint32_t delay_count;\n\tbool success;\n\n\tif (speed == 0) {\n\t\tLOG_INFO(\"XDS110: RTCK not supported\");\n\t\treturn ERROR_JTAG_NOT_IMPLEMENTED;\n\t}\n\n\tif (speed < XDS110_MIN_TCK_SPEED) {\n\t\tLOG_INFO(\"XDS110: increase speed request: %d kHz to %d kHz minimum\",\n\t\t\tspeed, XDS110_MIN_TCK_SPEED);\n\t\tspeed = XDS110_MIN_TCK_SPEED;\n\t}\n\n\t/* Older XDS110 firmware had inefficient scan routines and could only */\n\t/* achieve a peak TCK frequency of about 2500 kHz */\n\tif (xds110.firmware < FAST_TCK_FIRMWARE_VERSION) {\n\n\t\t/* Check for request for top speed or higher */\n\t\tif (speed >= XDS110_MAX_SLOW_TCK_SPEED) {\n\n\t\t\t/* Inform user that speed was adjusted down to max possible */\n\t\t\tif (speed > XDS110_MAX_SLOW_TCK_SPEED) {\n\t\t\t\tLOG_INFO(\n\t\t\t\t\t\"XDS110: reduce speed request: %d kHz to %d kHz maximum\",\n\t\t\t\t\tspeed, XDS110_MAX_SLOW_TCK_SPEED);\n\t\t\t\tspeed = XDS110_MAX_SLOW_TCK_SPEED;\n\t\t\t}\n\t\t\tdelay_count = 0;\n\n\t\t} else {\n\n\t\t\tconst double XDS110_TCK_PULSE_INCREMENT = 66.0;\n\t\t\tfreq_to_use = speed * 1000; /* Hz */\n\t\t\tdelay_count = 0;\n\n\t\t\t/* Calculate the delay count value */\n\t\t\tdouble one_giga = 1000000000;\n\t\t\t/* Get the pulse duration for the max frequency supported in ns */\n\t\t\tdouble max_freq_pulse_duration = one_giga /\n\t\t\t\t(XDS110_MAX_SLOW_TCK_SPEED * 1000);\n\n\t\t\t/* Convert frequency to pulse duration */\n\t\t\tdouble freq_to_pulse_width_in_ns = one_giga / freq_to_use;\n\n\t\t\t/*\n\t\t\t* Start with the pulse duration for the maximum frequency. Keep\n\t\t\t* decrementing time added by each count value till the requested\n\t\t\t* frequency pulse is less than the calculated value.\n\t\t\t*/\n\t\t\tdouble current_value = max_freq_pulse_duration;\n\n\t\t\twhile (current_value < freq_to_pulse_width_in_ns) {\n\t\t\t\tcurrent_value += XDS110_TCK_PULSE_INCREMENT;\n\t\t\t\t++delay_count;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t* Determine which delay count yields the best match.\n\t\t\t* The one obtained above or one less.\n\t\t\t*/\n\t\t\tif (delay_count) {\n\t\t\t\tdouble diff_freq_1 = freq_to_use -\n\t\t\t\t\t(one_giga / (max_freq_pulse_duration +\n\t\t\t\t\t(XDS110_TCK_PULSE_INCREMENT * delay_count)));\n\t\t\t\tdouble diff_freq_2 = (one_giga / (max_freq_pulse_duration +\n\t\t\t\t\t(XDS110_TCK_PULSE_INCREMENT * (delay_count - 1)))) -\n\t\t\t\t\tfreq_to_use;\n\n\t\t\t\t/* One less count value yields a better match */\n\t\t\t\tif (diff_freq_1 > diff_freq_2)\n\t\t\t\t\t--delay_count;\n\t\t\t}\n\t\t}\n\n\t/* Newer firmware has reworked TCK routines that are much more efficient */\n\t/* and can now achieve a peak TCK frequency of 14000 kHz */\n\t} else {\n\n\t\tif (speed >= XDS110_MAX_FAST_TCK_SPEED) {\n\t\t\tif (speed > XDS110_MAX_FAST_TCK_SPEED) {\n\t\t\t\tLOG_INFO(\n\t\t\t\t\t\"XDS110: reduce speed request: %d kHz to %d kHz maximum\",\n\t\t\t\t\tspeed, XDS110_MAX_FAST_TCK_SPEED);\n\t\t\t\tspeed = XDS110_MAX_FAST_TCK_SPEED;\n\t\t\t}\n\t\t\tdelay_count = 0;\n\t\t} else if (speed >= 12000 && xds110.firmware >=\n\t\t\tFAST_TCK_PLUS_FIRMWARE_VERSION) {\n\t\t\tdelay_count = FAST_TCK_DELAY_12000_KHZ;\n\t\t} else if (speed >= 10000 && xds110.firmware >=\n\t\t\tFAST_TCK_PLUS_FIRMWARE_VERSION) {\n\t\t\tdelay_count = FAST_TCK_DELAY_10000_KHZ;\n\t\t} else if (speed >= 8500) {\n\t\t\tdelay_count = FAST_TCK_DELAY_8500_KHZ;\n\t\t} else if (speed >= 5500) {\n\t\t\tdelay_count = FAST_TCK_DELAY_5500_KHZ;\n\t\t} else {\n\t\t\t/* Calculate the delay count to set the frequency */\n\t\t\t/* Formula determined by measuring the waveform on Saeleae logic */\n\t\t\t/* analyzer using known values for delay count */\n\t\t\tconst double m = 17100000.0; /* slope */\n\t\t\tconst double b = -1.02;      /* y-intercept */\n\n\t\t\tfreq_to_use = speed * 1000; /* Hz */\n\t\t\tdouble period = 1.0/freq_to_use;\n\t\t\tdouble delay = m * period + b;\n\n\t\t\tif (delay < 1.0)\n\t\t\t\tdelay_count = 1;\n\t\t\telse\n\t\t\t\tdelay_count = (uint32_t)delay;\n\t\t}\n\t}\n\n\t/* Send the delay count to the XDS110 firmware */\n\tsuccess = xds_set_tck_delay(delay_count);\n\n\tif (success) {\n\t\txds110.delay_count = delay_count;\n\t\txds110.speed = speed;\n\t}\n\n\treturn (success) ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic int xds110_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\treturn ERROR_OK;\n}\n\nstatic int xds110_khz(int khz, int *jtag_speed)\n{\n\t*jtag_speed = khz;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xds110_handle_info_command)\n{\n\txds110_show_info();\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xds110_handle_supply_voltage_command)\n{\n\tuint32_t voltage = 0;\n\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], voltage);\n\t\tif (voltage == 0 || (voltage >= XDS110_MIN_VOLTAGE && voltage\n\t\t\t<= XDS110_MAX_VOLTAGE)) {\n\t\t\t/* Requested voltage is in range */\n\t\t\txds110.voltage = voltage;\n\t\t} else {\n\t\t\tLOG_ERROR(\"XDS110: voltage must be 0 or between %d and %d \"\n\t\t\t\t\"millivolts\", XDS110_MIN_VOLTAGE, XDS110_MAX_VOLTAGE);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\txds110.voltage = voltage;\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration xds110_subcommand_handlers[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = &xds110_handle_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"show XDS110 info\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"supply\",\n\t\t.handler = &xds110_handle_supply_voltage_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set the XDS110 probe supply voltage\",\n\t\t.usage = \"voltage_in_millivolts\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration xds110_command_handlers[] = {\n\t{\n\t\t.name = \"xds110\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform XDS110 management\",\n\t\t.usage = \"\",\n\t\t.chain = xds110_subcommand_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct swd_driver xds110_swd_driver = {\n\t.init = xds110_swd_init,\n\t.switch_seq = xds110_swd_switch_seq,\n\t.read_reg = xds110_swd_read_reg,\n\t.write_reg = xds110_swd_write_reg,\n\t.run = xds110_swd_run_queue,\n};\n\nstatic const char * const xds110_transport[] = { \"swd\", \"jtag\", NULL };\n\nstatic struct jtag_interface xds110_interface = {\n\t.execute_queue = xds110_execute_queue,\n};\n\nstruct adapter_driver xds110_adapter_driver = {\n\t.name = \"xds110\",\n\t.transports = xds110_transport,\n\t.commands = xds110_command_handlers,\n\n\t.init = xds110_init,\n\t.quit = xds110_quit,\n\t.reset = xds110_reset,\n\t.speed = xds110_speed,\n\t.khz = xds110_khz,\n\t.speed_div = xds110_speed_div,\n\n\t.jtag_ops = &xds110_interface,\n\t.swd_ops = &xds110_swd_driver,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/drivers/xlnx-pcie-xvc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-only\n\n/*\n * Copyright (c) 2019 Google, LLC.\n * Author: Moritz Fischer <moritzf@google.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <stdlib.h>\n#include <math.h>\n#include <unistd.h>\n#include <linux/pci.h>\n\n#include <jtag/interface.h>\n#include <jtag/swd.h>\n#include <jtag/commands.h>\n#include <helper/replacements.h>\n#include <helper/bits.h>\n\n/* Available only from kernel v4.10 */\n#ifndef PCI_CFG_SPACE_EXP_SIZE\n#define PCI_CFG_SPACE_EXP_SIZE\t4096\n#endif\n\n#define PCIE_EXT_CAP_LST\t0x100\n\n#define XLNX_XVC_EXT_CAP\t0x00\n#define XLNX_XVC_VSEC_HDR\t0x04\n#define XLNX_XVC_LEN_REG\t0x0C\n#define XLNX_XVC_TMS_REG\t0x10\n#define XLNX_XVC_TDX_REG\t0x14\n\n#define XLNX_XVC_CAP_SIZE\t0x20\n#define XLNX_XVC_VSEC_ID\t0x8\n#define XLNX_XVC_MAX_BITS\t0x20\n\n#define MASK_ACK(x) (((x) >> 9) & 0x7)\n#define MASK_PAR(x) ((int)((x) & 0x1))\n\nstruct xlnx_pcie_xvc {\n\tint fd;\n\tunsigned offset;\n\tchar *device;\n};\n\nstatic struct xlnx_pcie_xvc xlnx_pcie_xvc_state;\nstatic struct xlnx_pcie_xvc *xlnx_pcie_xvc = &xlnx_pcie_xvc_state;\n\nstatic int xlnx_pcie_xvc_read_reg(const int offset, uint32_t *val)\n{\n\tuint32_t res;\n\tint err;\n\n\t/* Note: This should be ok endianness-wise because by going\n\t * through sysfs the kernel does the conversion in the config\n\t * space accessor functions\n\t */\n\terr = pread(xlnx_pcie_xvc->fd, &res, sizeof(res),\n\t\t    xlnx_pcie_xvc->offset + offset);\n\tif (err != sizeof(res)) {\n\t\tLOG_ERROR(\"Failed to read offset %x\", offset);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\tif (val)\n\t\t*val = res;\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_write_reg(const int offset, const uint32_t val)\n{\n\tint err;\n\n\t/* Note: This should be ok endianness-wise because by going\n\t * through sysfs the kernel does the conversion in the config\n\t * space accessor functions\n\t */\n\terr = pwrite(xlnx_pcie_xvc->fd, &val, sizeof(val),\n\t\t     xlnx_pcie_xvc->offset + offset);\n\tif (err != sizeof(val)) {\n\t\tLOG_ERROR(\"Failed to write offset: %x with value: %\" PRIx32,\n\t\t\t  offset, val);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_transact(size_t num_bits, uint32_t tms, uint32_t tdi,\n\t\t\t\t  uint32_t *tdo)\n{\n\tint err;\n\n\terr = xlnx_pcie_xvc_write_reg(XLNX_XVC_LEN_REG, num_bits);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = xlnx_pcie_xvc_write_reg(XLNX_XVC_TMS_REG, tms);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = xlnx_pcie_xvc_write_reg(XLNX_XVC_TDX_REG, tdi);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = xlnx_pcie_xvc_read_reg(XLNX_XVC_TDX_REG, tdo);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (tdo)\n\t\tLOG_DEBUG_IO(\"Transact num_bits: %zu, tms: %\" PRIx32 \", tdi: %\" PRIx32 \", tdo: %\" PRIx32,\n\t\t\t     num_bits, tms, tdi, *tdo);\n\telse\n\t\tLOG_DEBUG_IO(\"Transact num_bits: %zu, tms: %\" PRIx32 \", tdi: %\" PRIx32 \", tdo: <null>\",\n\t\t\t     num_bits, tms, tdi);\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_stableclocks(struct jtag_command *cmd)\n{\n\tint tms = tap_get_state() == TAP_RESET ? 1 : 0;\n\tsize_t left = cmd->cmd.stableclocks->num_cycles;\n\tsize_t write;\n\tint err;\n\n\tLOG_DEBUG(\"stableclocks %i cycles\", cmd->cmd.runtest->num_cycles);\n\n\twhile (left) {\n\t\twrite = MIN(XLNX_XVC_MAX_BITS, left);\n\t\terr = xlnx_pcie_xvc_transact(write, tms, 0, NULL);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tleft -= write;\n\t};\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_statemove(size_t skip)\n{\n\tuint8_t tms_scan = tap_get_tms_path(tap_get_state(),\n\t\t\t\t\t    tap_get_end_state());\n\tint tms_count = tap_get_tms_path_len(tap_get_state(),\n\t\t\t\t\t     tap_get_end_state());\n\tint err;\n\n\tLOG_DEBUG(\"statemove starting at (skip: %zu) %s end in %s\", skip,\n\t\t  tap_state_name(tap_get_state()),\n\t\t  tap_state_name(tap_get_end_state()));\n\n\n\terr = xlnx_pcie_xvc_transact(tms_count - skip, tms_scan >> skip, 0, NULL);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\ttap_set_state(tap_get_end_state());\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_runtest(struct jtag_command *cmd)\n{\n\tint err = ERROR_OK;\n\n\tLOG_DEBUG(\"runtest %i cycles, end in %i\",\n\t\t  cmd->cmd.runtest->num_cycles,\n\t\t  cmd->cmd.runtest->end_state);\n\n\ttap_state_t tmp_state = tap_get_end_state();\n\n\tif (tap_get_state() != TAP_IDLE) {\n\t\ttap_set_end_state(TAP_IDLE);\n\t\terr = xlnx_pcie_xvc_execute_statemove(0);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t};\n\n\tsize_t left = cmd->cmd.runtest->num_cycles;\n\tsize_t write;\n\n\twhile (left) {\n\t\twrite = MIN(XLNX_XVC_MAX_BITS, left);\n\t\terr = xlnx_pcie_xvc_transact(write, 0, 0, NULL);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tleft -= write;\n\t};\n\n\ttap_set_end_state(tmp_state);\n\tif (tap_get_state() != tap_get_end_state())\n\t\terr = xlnx_pcie_xvc_execute_statemove(0);\n\n\treturn err;\n}\n\nstatic int xlnx_pcie_xvc_execute_pathmove(struct jtag_command *cmd)\n{\n\tsize_t num_states = cmd->cmd.pathmove->num_states;\n\ttap_state_t *path = cmd->cmd.pathmove->path;\n\tint err = ERROR_OK;\n\tsize_t i;\n\n\tLOG_DEBUG(\"pathmove: %i states, end in %i\",\n\t\t  cmd->cmd.pathmove->num_states,\n\t\t  cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);\n\n\tfor (i = 0; i < num_states; i++) {\n\t\tif (path[i] == tap_state_transition(tap_get_state(), false)) {\n\t\t\terr = xlnx_pcie_xvc_transact(1, 1, 0, NULL);\n\t\t} else if (path[i] == tap_state_transition(tap_get_state(), true)) {\n\t\t\terr = xlnx_pcie_xvc_transact(1, 0, 0, NULL);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: %s -> %s isn't a valid TAP transition.\",\n\t\t\t\t  tap_state_name(tap_get_state()),\n\t\t\t\t  tap_state_name(path[i]));\n\t\t\terr = ERROR_JTAG_QUEUE_FAILED;\n\t\t}\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\ttap_set_state(path[i]);\n\t}\n\n\ttap_set_end_state(tap_get_state());\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_scan(struct jtag_command *cmd)\n{\n\tenum scan_type type = jtag_scan_type(cmd->cmd.scan);\n\ttap_state_t saved_end_state = cmd->cmd.scan->end_state;\n\tbool ir_scan = cmd->cmd.scan->ir_scan;\n\tuint32_t tdi, tms, tdo;\n\tuint8_t *buf, *rd_ptr;\n\tint err, scan_size;\n\tsize_t write;\n\tsize_t left;\n\n\tscan_size = jtag_build_buffer(cmd->cmd.scan, &buf);\n\trd_ptr = buf;\n\tLOG_DEBUG(\"%s scan type %d %d bits; starts in %s end in %s\",\n\t\t  (cmd->cmd.scan->ir_scan) ? \"IR\" : \"DR\", type, scan_size,\n\t\t  tap_state_name(tap_get_state()),\n\t\t  tap_state_name(cmd->cmd.scan->end_state));\n\n\t/* If we're in TAP_DR_SHIFT state but need to do a IR_SCAN or\n\t * vice-versa, do a statemove to corresponding other state, then restore\n\t * end state\n\t */\n\tif (ir_scan && tap_get_state() != TAP_IRSHIFT) {\n\t\ttap_set_end_state(TAP_IRSHIFT);\n\t\terr = xlnx_pcie_xvc_execute_statemove(0);\n\t\tif (err != ERROR_OK)\n\t\t\tgoto out_err;\n\t\ttap_set_end_state(saved_end_state);\n\t} else if (!ir_scan && (tap_get_state() != TAP_DRSHIFT)) {\n\t\ttap_set_end_state(TAP_DRSHIFT);\n\t\terr = xlnx_pcie_xvc_execute_statemove(0);\n\t\tif (err != ERROR_OK)\n\t\t\tgoto out_err;\n\t\ttap_set_end_state(saved_end_state);\n\t}\n\n\tleft = scan_size;\n\twhile (left) {\n\t\twrite = MIN(XLNX_XVC_MAX_BITS, left);\n\t\t/* the last TMS should be a 1, to leave the state */\n\t\ttms = left <= XLNX_XVC_MAX_BITS ? BIT(write - 1) : 0;\n\t\ttdi = (type != SCAN_IN) ? buf_get_u32(rd_ptr, 0, write) : 0;\n\t\terr = xlnx_pcie_xvc_transact(write, tms, tdi, type != SCAN_OUT ?\n\t\t\t\t\t     &tdo : NULL);\n\t\tif (err != ERROR_OK)\n\t\t\tgoto out_err;\n\t\tleft -= write;\n\t\tif (type != SCAN_OUT)\n\t\t\tbuf_set_u32(rd_ptr, 0, write, tdo);\n\t\trd_ptr += sizeof(uint32_t);\n\t};\n\n\terr = jtag_read_buffer(buf, cmd->cmd.scan);\n\tfree(buf);\n\n\tif (tap_get_state() != tap_get_end_state())\n\t\terr = xlnx_pcie_xvc_execute_statemove(1);\n\n\treturn err;\n\nout_err:\n\tfree(buf);\n\treturn err;\n}\n\nstatic void xlnx_pcie_xvc_execute_reset(struct jtag_command *cmd)\n{\n\tLOG_DEBUG(\"reset trst: %i srst: %i\", cmd->cmd.reset->trst,\n\t\t  cmd->cmd.reset->srst);\n}\n\nstatic void xlnx_pcie_xvc_execute_sleep(struct jtag_command *cmd)\n{\n\tLOG_DEBUG(\"sleep %\" PRIu32 \"\", cmd->cmd.sleep->us);\n\tusleep(cmd->cmd.sleep->us);\n}\n\nstatic int xlnx_pcie_xvc_execute_tms(struct jtag_command *cmd)\n{\n\tconst size_t num_bits = cmd->cmd.tms->num_bits;\n\tconst uint8_t *bits = cmd->cmd.tms->bits;\n\tsize_t left, write;\n\tuint32_t tms;\n\tint err;\n\n\tLOG_DEBUG(\"execute tms %zu\", num_bits);\n\n\tleft = num_bits;\n\twhile (left) {\n\t\twrite = MIN(XLNX_XVC_MAX_BITS, left);\n\t\ttms = buf_get_u32(bits, 0, write);\n\t\terr = xlnx_pcie_xvc_transact(write, tms, 0, NULL);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tleft -= write;\n\t\tbits += 4;\n\t};\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_command(struct jtag_command *cmd)\n{\n\tLOG_DEBUG(\"%s: cmd->type: %u\", __func__, cmd->type);\n\tswitch (cmd->type) {\n\tcase JTAG_STABLECLOCKS:\n\t\treturn xlnx_pcie_xvc_execute_stableclocks(cmd);\n\tcase JTAG_RUNTEST:\n\t\treturn xlnx_pcie_xvc_execute_runtest(cmd);\n\tcase JTAG_TLR_RESET:\n\t\ttap_set_end_state(cmd->cmd.statemove->end_state);\n\t\treturn xlnx_pcie_xvc_execute_statemove(0);\n\tcase JTAG_PATHMOVE:\n\t\treturn xlnx_pcie_xvc_execute_pathmove(cmd);\n\tcase JTAG_SCAN:\n\t\treturn xlnx_pcie_xvc_execute_scan(cmd);\n\tcase JTAG_RESET:\n\t\txlnx_pcie_xvc_execute_reset(cmd);\n\t\tbreak;\n\tcase JTAG_SLEEP:\n\t\txlnx_pcie_xvc_execute_sleep(cmd);\n\t\tbreak;\n\tcase JTAG_TMS:\n\t\treturn xlnx_pcie_xvc_execute_tms(cmd);\n\tdefault:\n\t\tLOG_ERROR(\"BUG: Unknown JTAG command type encountered.\");\n\t\treturn ERROR_JTAG_QUEUE_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_execute_queue(void)\n{\n\tstruct jtag_command *cmd = jtag_command_queue;\n\tint ret;\n\n\twhile (cmd) {\n\t\tret = xlnx_pcie_xvc_execute_command(cmd);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tcmd = cmd->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nstatic int xlnx_pcie_xvc_init(void)\n{\n\tchar filename[PATH_MAX];\n\tuint32_t cap, vh;\n\tint err;\n\n\tsnprintf(filename, PATH_MAX, \"/sys/bus/pci/devices/%s/config\",\n\t\t xlnx_pcie_xvc->device);\n\txlnx_pcie_xvc->fd = open(filename, O_RDWR | O_SYNC);\n\tif (xlnx_pcie_xvc->fd < 0) {\n\t\tLOG_ERROR(\"Failed to open device: %s\", filename);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_INFO(\"Scanning PCIe device %s's for Xilinx XVC/PCIe ...\",\n\t\t xlnx_pcie_xvc->device);\n\t/* Parse the PCIe extended capability list and try to find\n\t * vendor specific header */\n\txlnx_pcie_xvc->offset = PCIE_EXT_CAP_LST;\n\twhile (xlnx_pcie_xvc->offset <= PCI_CFG_SPACE_EXP_SIZE - sizeof(cap) &&\n\t       xlnx_pcie_xvc->offset >= PCIE_EXT_CAP_LST) {\n\t\terr = xlnx_pcie_xvc_read_reg(XLNX_XVC_EXT_CAP, &cap);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tLOG_DEBUG(\"Checking capability at 0x%x; id=0x%04\" PRIx32 \" version=0x%\" PRIx32 \" next=0x%\" PRIx32,\n\t\t\t xlnx_pcie_xvc->offset,\n\t\t\t PCI_EXT_CAP_ID(cap),\n\t\t\t PCI_EXT_CAP_VER(cap),\n\t\t\t PCI_EXT_CAP_NEXT(cap));\n\t\tif (PCI_EXT_CAP_ID(cap) == PCI_EXT_CAP_ID_VNDR) {\n\t\t\terr = xlnx_pcie_xvc_read_reg(XLNX_XVC_VSEC_HDR, &vh);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\t\t\tLOG_DEBUG(\"Checking possible match at 0x%x; id: 0x%\" PRIx32 \"; rev: 0x%\" PRIx32 \"; length: 0x%\" PRIx32,\n\t\t\t\t xlnx_pcie_xvc->offset,\n\t\t\t\t PCI_VNDR_HEADER_ID(vh),\n\t\t\t\t PCI_VNDR_HEADER_REV(vh),\n\t\t\t\t PCI_VNDR_HEADER_LEN(vh));\n\t\t\tif ((PCI_VNDR_HEADER_ID(vh) == XLNX_XVC_VSEC_ID) &&\n\t\t\t    (PCI_VNDR_HEADER_LEN(vh) == XLNX_XVC_CAP_SIZE))\n\t\t\t\tbreak;\n\t\t}\n\t\txlnx_pcie_xvc->offset = PCI_EXT_CAP_NEXT(cap);\n\t}\n\tif ((xlnx_pcie_xvc->offset > PCI_CFG_SPACE_EXP_SIZE - XLNX_XVC_CAP_SIZE) ||\n\t     xlnx_pcie_xvc->offset < PCIE_EXT_CAP_LST) {\n\t\tclose(xlnx_pcie_xvc->fd);\n\t\treturn ERROR_JTAG_INIT_FAILED;\n\t}\n\n\tLOG_INFO(\"Found Xilinx XVC/PCIe capability at offset: 0x%x\", xlnx_pcie_xvc->offset);\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_quit(void)\n{\n\tint err;\n\n\terr = close(xlnx_pcie_xvc->fd);\n\tif (err)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xlnx_pcie_xvc_handle_config_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* we can't really free this in a safe manner, so at least\n\t * limit the memory we're leaking by freeing the old one first\n\t * before allocating a new one ...\n\t */\n\tfree(xlnx_pcie_xvc->device);\n\n\txlnx_pcie_xvc->device = strdup(CMD_ARGV[0]);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration xlnx_pcie_xvc_subcommand_handlers[] = {\n\t{\n\t\t.name = \"config\",\n\t\t.handler = xlnx_pcie_xvc_handle_config_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure XVC/PCIe JTAG adapter\",\n\t\t.usage = \"device\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration xlnx_pcie_xvc_command_handlers[] = {\n\t{\n\t\t.name = \"xlnx_pcie_xvc\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform xlnx_pcie_xvc management\",\n\t\t.chain = xlnx_pcie_xvc_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic struct jtag_interface xlnx_pcie_xvc_jtag_ops = {\n\t.execute_queue = &xlnx_pcie_xvc_execute_queue,\n};\n\nstatic int xlnx_pcie_xvc_swd_sequence(const uint8_t *seq, size_t length)\n{\n\tsize_t left, write;\n\tuint32_t send;\n\tint err;\n\n\tleft = length;\n\twhile (left) {\n\t\twrite = MIN(XLNX_XVC_MAX_BITS, left);\n\t\tsend = buf_get_u32(seq, 0, write);\n\t\terr = xlnx_pcie_xvc_transact(write, send, 0, NULL);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tleft -= write;\n\t\tseq += sizeof(uint32_t);\n\t};\n\n\treturn ERROR_OK;\n}\n\nstatic int xlnx_pcie_xvc_swd_switch_seq(enum swd_special_seq seq)\n{\n\tswitch (seq) {\n\tcase LINE_RESET:\n\t\tLOG_DEBUG(\"SWD line reset\");\n\t\treturn xlnx_pcie_xvc_swd_sequence(swd_seq_line_reset,\n\t\t\t\t\t\t  swd_seq_line_reset_len);\n\tcase JTAG_TO_SWD:\n\t\tLOG_DEBUG(\"JTAG-to-SWD\");\n\t\treturn xlnx_pcie_xvc_swd_sequence(swd_seq_jtag_to_swd,\n\t\t\t\t\t\t  swd_seq_jtag_to_swd_len);\n\tcase SWD_TO_JTAG:\n\t\tLOG_DEBUG(\"SWD-to-JTAG\");\n\t\treturn xlnx_pcie_xvc_swd_sequence(swd_seq_swd_to_jtag,\n\t\t\t\t\t\t  swd_seq_swd_to_jtag_len);\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int queued_retval;\n\nstatic void xlnx_pcie_xvc_swd_write_reg(uint8_t cmd, uint32_t value,\n\t\t\t\t\tuint32_t ap_delay_clk);\n\nstatic void swd_clear_sticky_errors(void)\n{\n\txlnx_pcie_xvc_swd_write_reg(swd_cmd(false,  false, DP_ABORT),\n\t\tSTKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);\n}\n\nstatic void xlnx_pcie_xvc_swd_read_reg(uint8_t cmd, uint32_t *value,\n\t\t\t\t       uint32_t ap_delay_clk)\n{\n\tuint32_t res, ack, rpar;\n\tint err;\n\n\tassert(cmd & SWD_CMD_RNW);\n\n\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\t/* cmd + ack */\n\terr = xlnx_pcie_xvc_transact(12, cmd, 0, &res);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\tack = MASK_ACK(res);\n\n\t/* read data */\n\terr = xlnx_pcie_xvc_transact(32, 0, 0, &res);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\t/* parity + trn */\n\terr = xlnx_pcie_xvc_transact(2, 0, 0, &rpar);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\tLOG_DEBUG(\"%s %s %s reg %X = %08\"PRIx32,\n\t\t  ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ?\n\t\t  \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t  cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t  cmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t  (cmd & SWD_CMD_A32) >> 1,\n\t\t  res);\n\tswitch (ack) {\n\tcase SWD_ACK_OK:\n\t\tif (MASK_PAR(rpar) != parity_u32(res)) {\n\t\t\tLOG_DEBUG_IO(\"Wrong parity detected\");\n\t\t\tqueued_retval = ERROR_FAIL;\n\t\t\treturn;\n\t\t}\n\t\tif (value)\n\t\t\t*value = res;\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\terr = xlnx_pcie_xvc_transact(ap_delay_clk, 0, 0, NULL);\n\t\tqueued_retval = err;\n\t\treturn;\n\tcase SWD_ACK_WAIT:\n\t\tLOG_DEBUG_IO(\"SWD_ACK_WAIT\");\n\t\tswd_clear_sticky_errors();\n\t\treturn;\n\tcase SWD_ACK_FAULT:\n\t\tLOG_DEBUG_IO(\"SWD_ACK_FAULT\");\n\t\tqueued_retval = ack;\n\t\treturn;\n\tdefault:\n\t\tLOG_DEBUG_IO(\"No valid acknowledge: ack=%02\"PRIx32, ack);\n\t\tqueued_retval = ack;\n\t\treturn;\n\t}\nerr_out:\n\tqueued_retval = err;\n}\n\nstatic void xlnx_pcie_xvc_swd_write_reg(uint8_t cmd, uint32_t value,\n\t\t\t\t\tuint32_t ap_delay_clk)\n{\n\tuint32_t res, ack;\n\tint err;\n\n\tassert(!(cmd & SWD_CMD_RNW));\n\n\tcmd |= SWD_CMD_START | SWD_CMD_PARK;\n\t/* cmd + trn + ack */\n\terr = xlnx_pcie_xvc_transact(13, cmd, 0, &res);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\tack = MASK_ACK(res);\n\n\t/* write data */\n\terr = xlnx_pcie_xvc_transact(32, value, 0, NULL);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\t/* parity + trn */\n\terr = xlnx_pcie_xvc_transact(2, parity_u32(value), 0, NULL);\n\tif (err != ERROR_OK)\n\t\tgoto err_out;\n\n\tLOG_DEBUG(\"%s %s %s reg %X = %08\"PRIx32,\n\t\t  ack == SWD_ACK_OK ? \"OK\" : ack == SWD_ACK_WAIT ?\n\t\t  \"WAIT\" : ack == SWD_ACK_FAULT ? \"FAULT\" : \"JUNK\",\n\t\t  cmd & SWD_CMD_APNDP ? \"AP\" : \"DP\",\n\t\t  cmd & SWD_CMD_RNW ? \"read\" : \"write\",\n\t\t  (cmd & SWD_CMD_A32) >> 1,\n\t\t  value);\n\n\tswitch (ack) {\n\tcase SWD_ACK_OK:\n\t\tif (cmd & SWD_CMD_APNDP)\n\t\t\terr = xlnx_pcie_xvc_transact(ap_delay_clk, 0, 0, NULL);\n\t\tqueued_retval = err;\n\t\treturn;\n\tcase SWD_ACK_WAIT:\n\t\tLOG_DEBUG_IO(\"SWD_ACK_WAIT\");\n\t\tswd_clear_sticky_errors();\n\t\treturn;\n\tcase SWD_ACK_FAULT:\n\t\tLOG_DEBUG_IO(\"SWD_ACK_FAULT\");\n\t\tqueued_retval = ack;\n\t\treturn;\n\tdefault:\n\t\tLOG_DEBUG_IO(\"No valid acknowledge: ack=%02\"PRIx32, ack);\n\t\tqueued_retval = ack;\n\t\treturn;\n\t}\n\nerr_out:\n\tqueued_retval = err;\n}\n\nstatic int xlnx_pcie_xvc_swd_run_queue(void)\n{\n\tint err;\n\n\t/* we want at least 8 idle cycles between each transaction */\n\terr = xlnx_pcie_xvc_transact(8, 0, 0, NULL);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = queued_retval;\n\tqueued_retval = ERROR_OK;\n\tLOG_DEBUG(\"SWD queue return value: %02x\", err);\n\n\treturn err;\n}\n\nstatic int xlnx_pcie_xvc_swd_init(void)\n{\n\treturn ERROR_OK;\n}\n\nstatic const struct swd_driver xlnx_pcie_xvc_swd_ops = {\n\t.init = xlnx_pcie_xvc_swd_init,\n\t.switch_seq = xlnx_pcie_xvc_swd_switch_seq,\n\t.read_reg = xlnx_pcie_xvc_swd_read_reg,\n\t.write_reg = xlnx_pcie_xvc_swd_write_reg,\n\t.run = xlnx_pcie_xvc_swd_run_queue,\n};\n\nstatic const char * const xlnx_pcie_xvc_transports[] = { \"jtag\", \"swd\", NULL };\n\nstruct adapter_driver xlnx_pcie_xvc_adapter_driver = {\n\t.name = \"xlnx_pcie_xvc\",\n\t.transports = xlnx_pcie_xvc_transports,\n\t.commands = xlnx_pcie_xvc_command_handlers,\n\n\t.init = &xlnx_pcie_xvc_init,\n\t.quit = &xlnx_pcie_xvc_quit,\n\n\t.jtag_ops = &xlnx_pcie_xvc_jtag_ops,\n\t.swd_ops  = &xlnx_pcie_xvc_swd_ops,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libocdhla.la\n\n%C%_libocdhla_la_SOURCES = \\\n\t%D%/hla_transport.c \\\n\t%D%/hla_interface.c \\\n\t%D%/hla_layout.c \\\n\t%D%/hla_transport.h \\\n\t%D%/hla_interface.h \\\n\t%D%/hla_layout.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_interface.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include <helper/time_support.h>\n\n#include <jtag/hla/hla_layout.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n\n#include <target/target.h>\n\nstatic struct hl_interface_s hl_if = {\n\t.param = {\n\t\t.device_desc = NULL,\n\t\t.vid = { 0 },\n\t\t.pid = { 0 },\n\t\t.transport = HL_TRANSPORT_UNKNOWN,\n\t\t.connect_under_reset = false,\n\t\t.initial_interface_speed = -1,\n\t\t.use_stlink_tcp = false,\n\t\t.stlink_tcp_port = 7184,\n\t},\n\t.layout = NULL,\n\t.handle = NULL,\n};\n\nint hl_interface_open(enum hl_transports tr)\n{\n\tLOG_DEBUG(\"hl_interface_open\");\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\thl_if.param.connect_under_reset = true;\n\t\telse\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t}\n\n\t/* set transport mode */\n\thl_if.param.transport = tr;\n\n\tint result = hl_if.layout->open(&hl_if);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\treturn hl_interface_init_reset();\n}\n\nint hl_interface_init_target(struct target *t)\n{\n\tint res;\n\n\tLOG_DEBUG(\"hl_interface_init_target\");\n\n\t/* this is the interface for the current target and we\n\t * can setup the private pointer in the tap structure\n\t * if the interface match the tap idcode\n\t */\n\tres = hl_if.layout->api->idcode(hl_if.handle, &t->tap->idcode);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tunsigned ii, limit = t->tap->expected_ids_cnt;\n\tint found = 0;\n\n\tfor (ii = 0; ii < limit; ii++) {\n\t\tuint32_t expected = t->tap->expected_ids[ii];\n\n\t\t/* treat \"-expected-id 0\" as a \"don't-warn\" wildcard */\n\t\tif (!expected || !t->tap->idcode ||\n\t\t    (t->tap->idcode == expected)) {\n\t\t\tfound = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (found == 0) {\n\t\tLOG_WARNING(\"UNEXPECTED idcode: 0x%08\" PRIx32, t->tap->idcode);\n\t\tfor (ii = 0; ii < limit; ii++)\n\t\t\tLOG_ERROR(\"expected %u of %u: 0x%08\" PRIx32, ii + 1, limit,\n\t\t\t\tt->tap->expected_ids[ii]);\n\n\t\treturn ERROR_FAIL;\n\t}\n\n\tt->tap->priv = &hl_if;\n\tt->tap->hasidcode = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_init(void)\n{\n\tLOG_DEBUG(\"hl_interface_init\");\n\n\t/* here we can initialize the layout */\n\treturn hl_layout_init(&hl_if);\n}\n\nstatic int hl_interface_quit(void)\n{\n\tLOG_DEBUG(\"hl_interface_quit\");\n\n\tif (hl_if.layout->api->close)\n\t\thl_if.layout->api->close(hl_if.handle);\n\n\tjtag_command_queue_reset();\n\n\tfree((void *)hl_if.param.device_desc);\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_reset(int req_trst, int req_srst)\n{\n\treturn hl_if.layout->api->assert_srst(hl_if.handle, req_srst ? 0 : 1);\n}\n\nint hl_interface_init_reset(void)\n{\n\t/* in case the adapter has not already handled asserting srst\n\t * we will attempt it again */\n\tif (hl_if.param.connect_under_reset) {\n\t\tadapter_assert_reset();\n\t} else {\n\t\tadapter_deassert_reset();\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_khz(int khz, int *jtag_speed)\n{\n\tif (!hl_if.layout->api->speed)\n\t\treturn ERROR_OK;\n\n\t*jtag_speed = hl_if.layout->api->speed(hl_if.handle, khz, true);\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_speed_div(int speed, int *khz)\n{\n\t*khz = speed;\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_speed(int speed)\n{\n\tif (!hl_if.layout->api->speed)\n\t\treturn ERROR_OK;\n\n\tif (!hl_if.handle) {\n\t\t/* pass speed as initial param as interface not open yet */\n\t\thl_if.param.initial_interface_speed = speed;\n\t\treturn ERROR_OK;\n\t}\n\n\thl_if.layout->api->speed(hl_if.handle, speed, false);\n\n\treturn ERROR_OK;\n}\n\nint hl_interface_override_target(const char **targetname)\n{\n\tif (hl_if.layout->api->override_target) {\n\t\tif (hl_if.layout->api->override_target(*targetname)) {\n\t\t\t*targetname = \"hla_target\";\n\t\t\treturn ERROR_OK;\n\t\t} else\n\t\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic int hl_interface_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,\n\t\tuint32_t port_size, unsigned int *trace_freq,\n\t\tunsigned int traceclkin_freq, uint16_t *prescaler)\n{\n\tif (hl_if.layout->api->config_trace)\n\t\treturn hl_if.layout->api->config_trace(hl_if.handle, enabled,\n\t\t\tpin_protocol, port_size, trace_freq, traceclkin_freq, prescaler);\n\telse if (enabled) {\n\t\tLOG_ERROR(\"The selected interface does not support tracing\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_interface_poll_trace(uint8_t *buf, size_t *size)\n{\n\tif (hl_if.layout->api->poll_trace)\n\t\treturn hl_if.layout->api->poll_trace(hl_if.handle, buf, size);\n\n\treturn ERROR_FAIL;\n}\n\nCOMMAND_HANDLER(hl_interface_handle_device_desc_command)\n{\n\tLOG_DEBUG(\"hl_interface_handle_device_desc_command\");\n\n\tif (CMD_ARGC == 1) {\n\t\thl_if.param.device_desc = strdup(CMD_ARGV[0]);\n\t} else {\n\t\tLOG_ERROR(\"expected exactly one argument to hl_device_desc <description>\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(hl_interface_handle_layout_command)\n{\n\tLOG_DEBUG(\"hl_interface_handle_layout_command\");\n\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Need exactly one argument to stlink_layout\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (hl_if.layout) {\n\t\tLOG_ERROR(\"already specified hl_layout %s\",\n\t\t\t\thl_if.layout->name);\n\t\treturn (strcmp(hl_if.layout->name, CMD_ARGV[0]) != 0)\n\t\t    ? ERROR_FAIL : ERROR_OK;\n\t}\n\n\tfor (const struct hl_layout *l = hl_layout_get_list(); l->name;\n\t     l++) {\n\t\tif (strcmp(l->name, CMD_ARGV[0]) == 0) {\n\t\t\thl_if.layout = l;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"No adapter layout '%s' found\", CMD_ARGV[0]);\n\treturn ERROR_FAIL;\n}\n\nCOMMAND_HANDLER(hl_interface_handle_vid_pid_command)\n{\n\tif (CMD_ARGC > HLA_MAX_USB_IDS * 2) {\n\t\tLOG_WARNING(\"ignoring extra IDs in hla_vid_pid \"\n\t\t\t\"(maximum is %d pairs)\", HLA_MAX_USB_IDS);\n\t\tCMD_ARGC = HLA_MAX_USB_IDS * 2;\n\t}\n\tif (CMD_ARGC < 2 || (CMD_ARGC & 1)) {\n\t\tLOG_WARNING(\"incomplete hla_vid_pid configuration directive\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tunsigned i;\n\tfor (i = 0; i < CMD_ARGC; i += 2) {\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i], hl_if.param.vid[i / 2]);\n\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[i + 1], hl_if.param.pid[i / 2]);\n\t}\n\n\t/*\n\t * Explicitly terminate, in case there are multiple instances of\n\t * hla_vid_pid.\n\t */\n\thl_if.param.vid[i / 2] = hl_if.param.pid[i / 2] = 0;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(hl_interface_handle_stlink_backend_command)\n{\n\t/* default values */\n\tbool use_stlink_tcp = false;\n\tuint16_t stlink_tcp_port = 7184;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse if (strcmp(CMD_ARGV[0], \"usb\") == 0) {\n\t\tif (CMD_ARGC > 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t/* else use_stlink_tcp = false (already the case ) */\n\t} else if (strcmp(CMD_ARGV[0], \"tcp\") == 0) {\n\t\tuse_stlink_tcp = true;\n\t\tif (CMD_ARGC == 2)\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], stlink_tcp_port);\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\thl_if.param.use_stlink_tcp = use_stlink_tcp;\n\thl_if.param.stlink_tcp_port = stlink_tcp_port;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(interface_handle_hla_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!hl_if.layout->api->custom_command) {\n\t\tLOG_ERROR(\"The selected adapter doesn't support custom commands\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\thl_if.layout->api->custom_command(hl_if.handle, CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration hl_interface_command_handlers[] = {\n\t{\n\t .name = \"hla_device_desc\",\n\t .handler = &hl_interface_handle_device_desc_command,\n\t .mode = COMMAND_CONFIG,\n\t .help = \"set the device description of the adapter\",\n\t .usage = \"description_string\",\n\t },\n\t{\n\t .name = \"hla_layout\",\n\t .handler = &hl_interface_handle_layout_command,\n\t .mode = COMMAND_CONFIG,\n\t .help = \"set the layout of the adapter\",\n\t .usage = \"layout_name\",\n\t },\n\t{\n\t .name = \"hla_vid_pid\",\n\t .handler = &hl_interface_handle_vid_pid_command,\n\t .mode = COMMAND_CONFIG,\n\t .help = \"the vendor and product ID of the adapter\",\n\t .usage = \"(vid pid)*\",\n\t },\n\t{\n\t .name = \"hla_stlink_backend\",\n\t .handler = &hl_interface_handle_stlink_backend_command,\n\t .mode = COMMAND_CONFIG,\n\t .help = \"select which ST-Link backend to use\",\n\t .usage = \"usb | tcp [port]\",\n\t},\n\t {\n\t .name = \"hla_command\",\n\t .handler = &interface_handle_hla_command,\n\t .mode = COMMAND_EXEC,\n\t .help = \"execute a custom adapter-specific command\",\n\t .usage = \"<command>\",\n\t },\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct adapter_driver hl_adapter_driver = {\n\t.name = \"hla\",\n\t.transports = hl_transports,\n\t.commands = hl_interface_command_handlers,\n\n\t.init = hl_interface_init,\n\t.quit = hl_interface_quit,\n\t.reset = hl_interface_reset,\n\t.speed = &hl_interface_speed,\n\t.khz = &hl_interface_khz,\n\t.speed_div = &hl_interface_speed_div,\n\t.config_trace = &hl_interface_config_trace,\n\t.poll_trace = &hl_interface_poll_trace,\n\n\t/* no ops for HLA, targets hla_target and stm8 intercept them all */\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_interface.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_HLA_HLA_INTERFACE_H\n#define OPENOCD_JTAG_HLA_HLA_INTERFACE_H\n\n/** */\nstruct target;\n/** */\nenum e_hl_transports;\n/** */\nextern const char *hl_transports[];\n\n#define HLA_MAX_USB_IDS 16\n\nstruct hl_interface_param_s {\n\t/** */\n\tconst char *device_desc;\n\t/** List of recognised VIDs */\n\tuint16_t vid[HLA_MAX_USB_IDS + 1];\n\t/** List of recognised PIDs */\n\tuint16_t pid[HLA_MAX_USB_IDS + 1];\n\t/** */\n\tenum hl_transports transport;\n\t/** */\n\tbool connect_under_reset;\n\t/** Initial interface clock clock speed */\n\tint initial_interface_speed;\n\t/** */\n\tbool use_stlink_tcp;\n\t/** */\n\tuint16_t stlink_tcp_port;\n};\n\nstruct hl_interface_s {\n\t/** */\n\tstruct hl_interface_param_s param;\n\t/** */\n\tconst struct hl_layout *layout;\n\t/** */\n\tvoid *handle;\n};\n\n/** */\nint hl_interface_open(enum hl_transports tr);\n/** */\n\nint hl_interface_init_target(struct target *t);\nint hl_interface_init_reset(void);\nint hl_interface_override_target(const char **targetname);\n\n#endif /* OPENOCD_JTAG_HLA_HLA_INTERFACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_layout.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <transport/transport.h>\n#include <helper/time_support.h>\n\n#include <jtag/hla/hla_layout.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n\nstatic int hl_layout_open(struct hl_interface_s *adapter)\n{\n\tint res;\n\n\tLOG_DEBUG(\"hl_layout_open\");\n\n\tadapter->handle = NULL;\n\n\tres = adapter->layout->api->open(&adapter->param, &adapter->handle);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_DEBUG(\"failed\");\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_layout_close(struct hl_interface_s *adapter)\n{\n\treturn ERROR_OK;\n}\n\nstatic const struct hl_layout hl_layouts[] = {\n#if BUILD_HLADAPTER_STLINK\n\t{\n\t .name = \"stlink\",\n\t .open = hl_layout_open,\n\t .close = hl_layout_close,\n\t .api = &stlink_usb_layout_api,\n\t },\n#endif\n#if BUILD_HLADAPTER_ICDI\n\t{\n\t .name = \"ti-icdi\",\n\t .open = hl_layout_open,\n\t .close = hl_layout_close,\n\t .api = &icdi_usb_layout_api,\n\t},\n#endif\n#if BUILD_HLADAPTER_NULINK\n\t{\n\t .name = \"nulink\",\n\t .open = hl_layout_open,\n\t .close = hl_layout_close,\n\t .api = &nulink_usb_layout_api,\n\t},\n#endif\n\t{.name = NULL, /* END OF TABLE */ },\n};\n\n/** */\nconst struct hl_layout *hl_layout_get_list(void)\n{\n\treturn hl_layouts;\n}\n\nint hl_layout_init(struct hl_interface_s *adapter)\n{\n\tLOG_DEBUG(\"hl_layout_init\");\n\n\tif (!adapter->layout) {\n\t\tLOG_ERROR(\"no layout specified\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_layout.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_HLA_HLA_LAYOUT_H\n#define OPENOCD_JTAG_HLA_HLA_LAYOUT_H\n\n#include <target/armv7m_trace.h>\n#include <target/arm_tpiu_swo.h>\n\n/** */\nstruct hl_interface_s;\nstruct hl_interface_param_s;\n\n/** */\nextern struct hl_layout_api_s stlink_usb_layout_api;\nextern struct hl_layout_api_s icdi_usb_layout_api;\nextern struct hl_layout_api_s nulink_usb_layout_api;\n\n/** */\nstruct hl_layout_api_s {\n\t/** */\n\tint (*open)(struct hl_interface_param_s *param, void **handle);\n\t/** */\n\tint (*close)(void *handle);\n\t/** */\n\tint (*reset)(void *handle);\n\t/** */\n\tint (*assert_srst)(void *handle, int srst);\n\t/** */\n\tint (*run)(void *handle);\n\t/** */\n\tint (*halt)(void *handle);\n\t/** */\n\tint (*step)(void *handle);\n\t/** */\n\tint (*read_regs)(void *handle);\n\t/**\n\t * Read one register from the target\n\t *\n\t * @param handle A pointer to the device-specific handle\n\t * @param regsel Register selection index compatible with all the\n\t * values allowed by armv7m DCRSR.REGSEL\n\t * @param val A pointer to retrieve the register value\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*read_reg)(void *handle, unsigned int regsel, uint32_t *val);\n\t/**\n\t * Write one register to the target\n\t * @param handle A pointer to the device-specific handle\n\t * @param regsel Register selection index compatible with all the\n\t * values allowed by armv7m DCRSR.REGSEL\n\t * @param val The value to be written in the register\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*write_reg)(void *handle, unsigned int regsel, uint32_t val);\n\t/** */\n\tint (*read_mem)(void *handle, uint32_t addr, uint32_t size,\n\t\t\tuint32_t count, uint8_t *buffer);\n\t/** */\n\tint (*write_mem)(void *handle, uint32_t addr, uint32_t size,\n\t\t\tuint32_t count, const uint8_t *buffer);\n\t/** */\n\tint (*write_debug_reg)(void *handle, uint32_t addr, uint32_t val);\n\t/**\n\t * Read the idcode of the target connected to the adapter\n\t *\n\t * If the adapter doesn't support idcode retrieval, this callback should\n\t * store 0 to indicate a wildcard match.\n\t *\n\t * @param handle A pointer to the device-specific handle\n\t * @param idcode Storage for the detected idcode\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*idcode)(void *handle, uint32_t *idcode);\n\t/** */\n\tint (*override_target)(const char *targetname);\n\t/** */\n\tint (*custom_command)(void *handle, const char *command);\n\t/** */\n\tint (*speed)(void *handle, int khz, bool query);\n\t/**\n\t * Configure trace parameters for the adapter\n\t *\n\t * @param handle A handle to adapter\n\t * @param enabled Whether to enable trace\n\t * @param pin_protocol Configured pin protocol\n\t * @param port_size Trace port width for sync mode\n\t * @param trace_freq A pointer to the configured trace\n\t * frequency; if it points to 0, the adapter driver must write\n\t * its maximum supported rate there\n\t * @returns ERROR_OK on success, an error code on failure.\n\t */\n\tint (*config_trace)(void *handle, bool enabled,\n\t\t\t\tenum tpiu_pin_protocol pin_protocol, uint32_t port_size,\n\t\t\t\tunsigned int *trace_freq, unsigned int traceclkin_freq,\n\t\t\t\tuint16_t *prescaler);\n\t/**\n\t * Poll for new trace data\n\t *\n\t * @param handle A handle to adapter\n\t * @param buf A pointer to buffer to store received data\n\t * @param size A pointer to buffer size; must be filled with\n\t * the actual amount of bytes written\n\t *\n\t * @returns ERROR_OK on success, an error code on failure.\n\t */\n\tint (*poll_trace)(void *handle, uint8_t *buf, size_t *size);\n\t/** */\n\tenum target_state (*state)(void *fd);\n};\n\n/** */\nstruct hl_layout {\n\t/** */\n\tchar *name;\n\t/** */\n\tint (*open)(struct hl_interface_s *adapter);\n\t/** */\n\tint (*close)(struct hl_interface_s *adapter);\n\t/** */\n\tstruct hl_layout_api_s *api;\n};\n\n/** */\nconst struct hl_layout *hl_layout_get_list(void);\n/** */\nint hl_layout_init(struct hl_interface_s *adapter);\n\n#endif /* OPENOCD_JTAG_HLA_HLA_LAYOUT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_transport.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/* project specific includes */\n#include <jtag/interface.h>\n#include <jtag/tcl.h>\n#include <transport/transport.h>\n#include <helper/time_support.h>\n#include <target/target.h>\n#include <jtag/hla/hla_transport.h>\n#include <jtag/hla/hla_interface.h>\n\nCOMMAND_HANDLER(hl_transport_jtag_command)\n{\n\tLOG_DEBUG(\"hl_transport_jtag_command\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(hl_transport_reset_command)\n{\n\treturn hl_interface_init_reset();\n}\n\nstatic const struct command_registration hl_swd_transport_subcommand_handlers[] = {\n\t{\n\t .name = \"newdap\",\n\t .mode = COMMAND_CONFIG,\n\t .handler = handle_jtag_newtap,\n\t .help = \"declare a new SWD DAP\",\n\t .usage = \"basename dap_type ['-irlen' count] \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t },\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration hl_swd_transport_command_handlers[] = {\n\t{\n\t .name = \"swd\",\n\t .mode = COMMAND_ANY,\n\t .help = \"SWD command group\",\n\t .usage = \"\",\n\t .chain = hl_swd_transport_subcommand_handlers,\n\t },\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration hl_transport_jtag_subcommand_handlers[] = {\n\t{\n\t .name = \"newtap\",\n\t .mode = COMMAND_CONFIG,\n\t .handler = handle_jtag_newtap,\n\t .help = \"Create a new TAP instance named basename.tap_type, \"\n\t \"and appends it to the scan chain.\",\n\t .usage = \"basename tap_type '-irlen' count \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t },\n\t{\n\t .name = \"init\",\n\t .mode = COMMAND_ANY,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\"\n\t },\n\t{\n\t .name = \"arp_init\",\n\t .mode = COMMAND_ANY,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\"\n\t },\n\t{\n\t .name = \"arp_init-reset\",\n\t .mode = COMMAND_ANY,\n\t .handler = hl_transport_reset_command,\n\t .usage = \"\"\n\t },\n\t{\n\t .name = \"tapisenabled\",\n\t .mode = COMMAND_EXEC,\n\t .handler = handle_jtag_tap_enabler,\n\t .help = \"Returns a Tcl boolean (0/1) indicating whether \"\n\t\t\"the TAP is enabled (1) or not (0).\",\n\t .usage = \"tap_name\",\n\t },\n\t{\n\t .name = \"tapenable\",\n\t .mode = COMMAND_EXEC,\n\t .handler = handle_jtag_tap_enabler,\n\t .help = \"Try to enable the specified TAP using the \"\n\t\t\"'tap-enable' TAP event.\",\n\t .usage = \"tap_name\",\n\t },\n\t{\n\t .name = \"tapdisable\",\n\t .mode = COMMAND_EXEC,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\",\n\t },\n\t{\n\t .name = \"configure\",\n\t .mode = COMMAND_EXEC,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\",\n\t },\n\t{\n\t .name = \"cget\",\n\t .mode = COMMAND_EXEC,\n\t .jim_handler = jim_jtag_configure,\n\t },\n\t{\n\t .name = \"names\",\n\t .mode = COMMAND_ANY,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\",\n\t },\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration hl_jtag_transport_command_handlers[] = {\n\t{\n\t .name = \"jtag\",\n\t .mode = COMMAND_ANY,\n\t .help = \"perform jtag tap actions\",\n\t .usage = \"\",\n\t .chain = hl_transport_jtag_subcommand_handlers,\n\t },\n\t{\n\t .name = \"jtag_ntrst_delay\",\n\t .mode = COMMAND_ANY,\n\t .handler = hl_transport_jtag_command,\n\t .usage = \"\",\n\t },\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\nstatic int hl_transport_init(struct command_context *cmd_ctx)\n{\n\tLOG_DEBUG(\"hl_transport_init\");\n\tstruct target *t = get_current_target(cmd_ctx);\n\tstruct transport *transport;\n\tenum hl_transports tr;\n\n\tif (!t) {\n\t\tLOG_ERROR(\"no current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttransport = get_current_transport();\n\n\tif (!transport) {\n\t\tLOG_ERROR(\"no transport selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"current transport %s\", transport->name);\n\n\t/* get selected transport as enum */\n\ttr = HL_TRANSPORT_UNKNOWN;\n\n\tif (strcmp(transport->name, \"hla_swd\") == 0)\n\t\ttr = HL_TRANSPORT_SWD;\n\telse if (strcmp(transport->name, \"hla_jtag\") == 0)\n\t\ttr = HL_TRANSPORT_JTAG;\n\n\tint retval = hl_interface_open(tr);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn hl_interface_init_target(t);\n}\n\nstatic int hl_jtag_transport_select(struct command_context *cmd_ctx)\n{\n\tLOG_DEBUG(\"hl_jtag_transport_select\");\n\n\t/* NOTE:  interface init must already have been done.\n\t * That works with only C code ... no Tcl glue required.\n\t */\n\n\treturn register_commands(cmd_ctx, NULL, hl_jtag_transport_command_handlers);\n}\n\nstatic int hl_swd_transport_select(struct command_context *cmd_ctx)\n{\n\tLOG_DEBUG(\"hl_swd_transport_select\");\n\treturn register_commands(cmd_ctx, NULL, hl_swd_transport_command_handlers);\n}\n\nstatic struct transport hl_swd_transport = {\n\t.name = \"hla_swd\",\n\t.select = hl_swd_transport_select,\n\t.init = hl_transport_init,\n\t.override_target = hl_interface_override_target,\n};\n\nstatic struct transport hl_jtag_transport = {\n\t.name = \"hla_jtag\",\n\t.select = hl_jtag_transport_select,\n\t.init = hl_transport_init,\n\t.override_target = hl_interface_override_target,\n};\n\nconst char *hl_transports[] = { \"hla_swd\", \"hla_jtag\", NULL };\n\nstatic void hl_constructor(void) __attribute__ ((constructor));\nstatic void hl_constructor(void)\n{\n\ttransport_register(&hl_swd_transport);\n\ttransport_register(&hl_jtag_transport);\n}\n\nbool transport_is_hla(void)\n{\n\tstruct transport *t;\n\tt = get_current_transport();\n\treturn t == &hl_swd_transport || t == &hl_jtag_transport;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/hla/hla_transport.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2012 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_HLA_HLA_TRANSPORT_H\n#define OPENOCD_JTAG_HLA_HLA_TRANSPORT_H\n\nenum hl_transports {\n\tHL_TRANSPORT_UNKNOWN = 0,\n\tHL_TRANSPORT_SWD,\n\tHL_TRANSPORT_JTAG,\n};\n\n#endif /* OPENOCD_JTAG_HLA_HLA_TRANSPORT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/interface.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag.h\"\n#include \"interface.h\"\n\n/**\n * @see tap_set_state() and tap_get_state() accessors.\n * Actual name is not important since accessors hide it.\n */\nstatic tap_state_t state_follower = TAP_RESET;\n\nvoid tap_set_state_impl(tap_state_t new_state)\n{\n\t/* this is the state we think the TAPs are in now, was cur_state */\n\tstate_follower = new_state;\n}\n\ntap_state_t tap_get_state(void)\n{\n\treturn state_follower;\n}\n\n/**\n * @see tap_set_end_state() and tap_get_end_state() accessors.\n * Actual name is not important because accessors hide it.\n */\nstatic tap_state_t end_state_follower = TAP_RESET;\n\nvoid tap_set_end_state(tap_state_t new_end_state)\n{\n\t/* this is the state we think the TAPs will be in at completion of the\n\t * current TAP operation, was end_state\n\t*/\n\tend_state_follower = new_end_state;\n}\n\ntap_state_t tap_get_end_state(void)\n{\n\treturn end_state_follower;\n}\n\nint tap_move_ndx(tap_state_t astate)\n{\n\t/* given a stable state, return the index into the tms_seqs[]\n\t * array within tap_get_tms_path()\n\t */\n\n\tint ndx;\n\n\tswitch (astate) {\n\t\tcase TAP_RESET:\n\t\t\tndx = 0;\n\t\t\tbreak;\n\t\tcase TAP_IDLE:\n\t\t\tndx = 1;\n\t\t\tbreak;\n\t\tcase TAP_DRSHIFT:\n\t\t\tndx = 2;\n\t\t\tbreak;\n\t\tcase TAP_DRPAUSE:\n\t\t\tndx = 3;\n\t\t\tbreak;\n\t\tcase TAP_IRSHIFT:\n\t\t\tndx = 4;\n\t\t\tbreak;\n\t\tcase TAP_IRPAUSE:\n\t\t\tndx = 5;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"FATAL: unstable state \\\"%s\\\" in tap_move_ndx()\",\n\t\t\t\t\ttap_state_name(astate));\n\t\t\texit(1);\n\t}\n\n\treturn ndx;\n}\n\n/* tap_move[i][j]: tap movement command to go from state i to state j\n * encodings of i and j are what tap_move_ndx() reports.\n *\n * DRSHIFT->DRSHIFT and IRSHIFT->IRSHIFT have to be caught in interface specific code\n */\nstruct tms_sequences {\n\tuint8_t bits;\n\tuint8_t bit_count;\n};\n\n/*\n * These macros allow us to specify TMS state transitions by bits rather than hex bytes.\n * Read the bits from LSBit first to MSBit last (right-to-left).\n */\n#define HEX__(n) 0x##n##LU\n\n#define B8__(x)\t\\\n\t((((x) & 0x0000000FLU) ? (1 << 0) : 0) \\\n\t+(((x) & 0x000000F0LU) ? (1 << 1) : 0) \\\n\t+(((x) & 0x00000F00LU) ? (1 << 2) : 0) \\\n\t+(((x) & 0x0000F000LU) ? (1 << 3) : 0) \\\n\t+(((x) & 0x000F0000LU) ? (1 << 4) : 0) \\\n\t+(((x) & 0x00F00000LU) ? (1 << 5) : 0) \\\n\t+(((x) & 0x0F000000LU) ? (1 << 6) : 0) \\\n\t+(((x) & 0xF0000000LU) ? (1 << 7) : 0))\n\n#define B8(bits, count) {((uint8_t)B8__(HEX__(bits))), (count)}\n\nstatic const struct tms_sequences old_tms_seqs[6][6] = {\t/* [from_state_ndx][to_state_ndx] */\n\t/* value clocked to TMS to move from one of six stable states to another.\n\t * N.B. OOCD clocks TMS from LSB first, so read these right-to-left.\n\t * N.B. Reset only needs to be 0b11111, but in JLink an even byte of 1's is more stable.\n\t * These extra ones cause no TAP state problem, because we go into reset and stay in reset.\n\t */\n\n/* to state: */\n/*\tRESET\t\t IDLE\t\t\tDRSHIFT\t\t\tDRPAUSE\t\t\tIRSHIFT\t\t\tIRPAUSE\t\t*/\t/* from state: */\n{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)},/* RESET */\n{B8(1111111, 7), B8(0000000, 7), B8(0100101, 7), B8(0000101, 7), B8(0101011, 7), B8(0001011, 7)},/* IDLE */\n{B8(1111111, 7), B8(0110001, 7), B8(0000000, 7), B8(0000001, 7), B8(0001111, 7), B8(0101111, 7)},/* DRSHIFT */\n{B8(1111111, 7), B8(0110000, 7), B8(0100000, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* DRPAUSE */\n{B8(1111111, 7), B8(0110001, 7), B8(0000111, 7), B8(0010111, 7), B8(0000000, 7), B8(0000001, 7)},/* IRSHIFT */\n{B8(1111111, 7), B8(0110000, 7), B8(0011100, 7), B8(0010111, 7), B8(0011110, 7), B8(0101111, 7)},/* IRPAUSE */\n};\n\nstatic const struct tms_sequences short_tms_seqs[6][6] = { /* [from_state_ndx][to_state_ndx] */\n\t/* this is the table submitted by Jeff Williams on 3/30/2009 with this comment:\n\n\tOK, I added Peter's version of the state table, and it works OK for\n\tme on MC1322x. I've recreated the jlink portion of patch with this\n\tnew state table. His changes to my state table are pretty minor in\n\tterms of total transitions, but Peter feels that his version fixes\n\tsome long-standing problems.\n\tJeff\n\n\tI added the bit count into the table, reduced RESET column to 7 bits from 8.\n\tDick\n\n\tstate specific comments:\n\t------------------------\n\t*->RESET\t\ttried the 5 bit reset and it gave me problems, 7 bits seems to\n\t\t\t\t\twork better on ARM9 with ft2232 driver.  (Dick)\n\n\tRESET->DRSHIFT add 1 extra clock cycles in the RESET state before advancing.\n\t\t\t\t\tneeded on ARM9 with ft2232 driver.  (Dick)\n\t\t\t\t\t(For a total of *THREE* extra clocks in RESET; NOP.)\n\n\tRESET->IRSHIFT add 1 extra clock cycles in the RESET state before advancing.\n\t\t\t\t\tneeded on ARM9 with ft2232 driver.  (Dick)\n\t\t\t\t\t(For a total of *TWO* extra clocks in RESET; NOP.)\n\n\tRESET->*\t\talways adds one or more clocks in the target state,\n\t\t\t\t\twhich should be NOPS; except shift states which (as\n\t\t\t\t\tnoted above) add those clocks in RESET.\n\n\tThe X-to-X transitions always add clocks; from *SHIFT, they go\n\tvia IDLE and thus *DO HAVE SIDE EFFECTS* (capture and update).\n*/\n\n/* to state: */\n/*\tRESET\t\tIDLE\t\t\tDRSHIFT\t\t\tDRPAUSE\t\t\tIRSHIFT\t\t\tIRPAUSE */ /* from state: */\n{B8(1111111, 7), B8(0000000, 7), B8(0010111, 7), B8(0001010, 7), B8(0011011, 7), B8(0010110, 7)}, /* RESET */\n{B8(1111111, 7), B8(0000000, 7), B8(001, 3),\t B8(0101, 4),\t B8(0011, 4),\t B8(01011, 5)}, /* IDLE */\n{B8(1111111, 7), B8(011, 3),\t B8(00111, 5),\t B8(01, 2),\t\t B8(001111, 6),\t B8(0101111, 7)}, /* DRSHIFT */\n{B8(1111111, 7), B8(011, 3),\t B8(01, 2),\t\t B8(0, 1),\t\t B8(001111, 6),\t B8(0101111, 7)}, /* DRPAUSE */\n{B8(1111111, 7), B8(011, 3),\t B8(00111, 5),\t B8(010111, 6),\t B8(001111, 6),\t B8(01, 2)}, /* IRSHIFT */\n{B8(1111111, 7), B8(011, 3),\t B8(00111, 5),\t B8(010111, 6),\t B8(01, 2),\t\t B8(0, 1)} /* IRPAUSE */\n};\n\ntypedef const struct tms_sequences tms_table[6][6];\n\nstatic tms_table *tms_seqs = &short_tms_seqs;\n\nint tap_get_tms_path(tap_state_t from, tap_state_t to)\n{\n\treturn (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bits;\n}\n\nint tap_get_tms_path_len(tap_state_t from, tap_state_t to)\n{\n\treturn (*tms_seqs)[tap_move_ndx(from)][tap_move_ndx(to)].bit_count;\n}\n\nbool tap_is_state_stable(tap_state_t astate)\n{\n\tbool is_stable;\n\n\t/*\tA switch () is used because it is symbol dependent\n\t * (not value dependent like an array), and can also check bounds.\n\t*/\n\tswitch (astate) {\n\t\tcase TAP_RESET:\n\t\tcase TAP_IDLE:\n\t\tcase TAP_DRSHIFT:\n\t\tcase TAP_DRPAUSE:\n\t\tcase TAP_IRSHIFT:\n\t\tcase TAP_IRPAUSE:\n\t\t\tis_stable = true;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tis_stable = false;\n\t}\n\n\treturn is_stable;\n}\n\ntap_state_t tap_state_transition(tap_state_t cur_state, bool tms)\n{\n\ttap_state_t new_state;\n\n\t/*\tA switch is used because it is symbol dependent and not value dependent\n\t * like an array.  Also it can check for out of range conditions.\n\t*/\n\n\tif (tms) {\n\t\tswitch (cur_state) {\n\t\t\tcase TAP_RESET:\n\t\t\t\tnew_state = cur_state;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IDLE:\n\t\t\tcase TAP_DRUPDATE:\n\t\t\tcase TAP_IRUPDATE:\n\t\t\t\tnew_state = TAP_DRSELECT;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DRSELECT:\n\t\t\t\tnew_state = TAP_IRSELECT;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DRCAPTURE:\n\t\t\tcase TAP_DRSHIFT:\n\t\t\t\tnew_state = TAP_DREXIT1;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DREXIT1:\n\t\t\tcase TAP_DREXIT2:\n\t\t\t\tnew_state = TAP_DRUPDATE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DRPAUSE:\n\t\t\t\tnew_state = TAP_DREXIT2;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IRSELECT:\n\t\t\t\tnew_state = TAP_RESET;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IRCAPTURE:\n\t\t\tcase TAP_IRSHIFT:\n\t\t\t\tnew_state = TAP_IREXIT1;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IREXIT1:\n\t\t\tcase TAP_IREXIT2:\n\t\t\t\tnew_state = TAP_IRUPDATE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IRPAUSE:\n\t\t\t\tnew_state = TAP_IREXIT2;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"fatal: invalid argument cur_state=%d\", cur_state);\n\t\t\t\texit(1);\n\t\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tswitch (cur_state) {\n\t\t\tcase TAP_RESET:\n\t\t\tcase TAP_IDLE:\n\t\t\tcase TAP_DRUPDATE:\n\t\t\tcase TAP_IRUPDATE:\n\t\t\t\tnew_state = TAP_IDLE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DRSELECT:\n\t\t\t\tnew_state = TAP_DRCAPTURE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DRCAPTURE:\n\t\t\tcase TAP_DRSHIFT:\n\t\t\tcase TAP_DREXIT2:\n\t\t\t\tnew_state = TAP_DRSHIFT;\n\t\t\t\tbreak;\n\t\t\tcase TAP_DREXIT1:\n\t\t\tcase TAP_DRPAUSE:\n\t\t\t\tnew_state = TAP_DRPAUSE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IRSELECT:\n\t\t\t\tnew_state = TAP_IRCAPTURE;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IRCAPTURE:\n\t\t\tcase TAP_IRSHIFT:\n\t\t\tcase TAP_IREXIT2:\n\t\t\t\tnew_state = TAP_IRSHIFT;\n\t\t\t\tbreak;\n\t\t\tcase TAP_IREXIT1:\n\t\t\tcase TAP_IRPAUSE:\n\t\t\t\tnew_state = TAP_IRPAUSE;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"fatal: invalid argument cur_state=%d\", cur_state);\n\t\t\t\texit(1);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn new_state;\n}\n\n/* NOTE:  do not change these state names.  They're documented,\n * and we rely on them to match SVF input (except for \"RUN/IDLE\").\n */\nstatic const struct name_mapping {\n\tenum tap_state symbol;\n\tconst char *name;\n} tap_name_mapping[] = {\n\t{ TAP_RESET, \"RESET\", },\n\t{ TAP_IDLE, \"RUN/IDLE\", },\n\t{ TAP_DRSELECT, \"DRSELECT\", },\n\t{ TAP_DRCAPTURE, \"DRCAPTURE\", },\n\t{ TAP_DRSHIFT, \"DRSHIFT\", },\n\t{ TAP_DREXIT1, \"DREXIT1\", },\n\t{ TAP_DRPAUSE, \"DRPAUSE\", },\n\t{ TAP_DREXIT2, \"DREXIT2\", },\n\t{ TAP_DRUPDATE, \"DRUPDATE\", },\n\t{ TAP_IRSELECT, \"IRSELECT\", },\n\t{ TAP_IRCAPTURE, \"IRCAPTURE\", },\n\t{ TAP_IRSHIFT, \"IRSHIFT\", },\n\t{ TAP_IREXIT1, \"IREXIT1\", },\n\t{ TAP_IRPAUSE, \"IRPAUSE\", },\n\t{ TAP_IREXIT2, \"IREXIT2\", },\n\t{ TAP_IRUPDATE, \"IRUPDATE\", },\n\n\t/* only for input:  accept standard SVF name */\n\t{ TAP_IDLE, \"IDLE\", },\n};\n\nconst char *tap_state_name(tap_state_t state)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) {\n\t\tif (tap_name_mapping[i].symbol == state)\n\t\t\treturn tap_name_mapping[i].name;\n\t}\n\treturn \"???\";\n}\n\ntap_state_t tap_state_by_name(const char *name)\n{\n\tunsigned i;\n\n\tfor (i = 0; i < ARRAY_SIZE(tap_name_mapping); i++) {\n\t\t/* be nice to the human */\n\t\tif (strcasecmp(name, tap_name_mapping[i].name) == 0)\n\t\t\treturn tap_name_mapping[i].symbol;\n\t}\n\t/* not found */\n\treturn TAP_INVALID;\n}\n\n#define JTAG_DEBUG_STATE_APPEND(buf, len, bit) \\\n\tdo { buf[len] = bit ? '1' : '0'; } while (0)\n#define JTAG_DEBUG_STATE_PRINT(a, b, astr, bstr) \\\n\tLOG_DEBUG_IO(\"TAP/SM: %9s -> %5s\\tTMS: %s\\tTDI: %s\", \\\n\ttap_state_name(a), tap_state_name(b), astr, bstr)\n\ntap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf,\n\tunsigned int tap_bits, tap_state_t next_state)\n{\n\tconst uint8_t *tms_buffer;\n\tconst uint8_t *tdi_buffer;\n\tunsigned tap_bytes;\n\tunsigned cur_byte;\n\tunsigned cur_bit;\n\n\tunsigned tap_out_bits;\n\tchar tms_str[33];\n\tchar tdi_str[33];\n\n\ttap_state_t last_state;\n\n\t/* set startstate (and possibly last, if tap_bits == 0) */\n\tlast_state = next_state;\n\tLOG_DEBUG_IO(\"TAP/SM: START state: %s\", tap_state_name(next_state));\n\n\ttms_buffer = (const uint8_t *)tms_buf;\n\ttdi_buffer = (const uint8_t *)tdi_buf;\n\n\ttap_bytes = DIV_ROUND_UP(tap_bits, 8);\n\tLOG_DEBUG_IO(\"TAP/SM: TMS bits: %u (bytes: %u)\", tap_bits, tap_bytes);\n\n\ttap_out_bits = 0;\n\tfor (cur_byte = 0; cur_byte < tap_bytes; cur_byte++) {\n\t\tfor (cur_bit = 0; cur_bit < 8; cur_bit++) {\n\t\t\t/* make sure we do not run off the end of the buffers */\n\t\t\tunsigned tap_bit = cur_byte * 8 + cur_bit;\n\t\t\tif (tap_bit == tap_bits)\n\t\t\t\tbreak;\n\n\t\t\t/* check and save TMS bit */\n\t\t\ttap_bit = !!(tms_buffer[cur_byte] & (1 << cur_bit));\n\t\t\tJTAG_DEBUG_STATE_APPEND(tms_str, tap_out_bits, tap_bit);\n\n\t\t\t/* use TMS bit to find the next TAP state */\n\t\t\tnext_state = tap_state_transition(last_state, tap_bit);\n\n\t\t\t/* check and store TDI bit */\n\t\t\ttap_bit = !!(tdi_buffer[cur_byte] & (1 << cur_bit));\n\t\t\tJTAG_DEBUG_STATE_APPEND(tdi_str, tap_out_bits, tap_bit);\n\n\t\t\t/* increment TAP bits */\n\t\t\ttap_out_bits++;\n\n\t\t\t/* Only show TDO bits on state transitions, or */\n\t\t\t/* after some number of bits in the same state. */\n\t\t\tif ((next_state == last_state) && (tap_out_bits < 32))\n\t\t\t\tcontinue;\n\n\t\t\t/* terminate strings and display state transition */\n\t\t\ttms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;\n\t\t\tJTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);\n\n\t\t\t/* reset state */\n\t\t\tlast_state = next_state;\n\t\t\ttap_out_bits = 0;\n\t\t}\n\t}\n\n\tif (tap_out_bits) {\n\t\t/* terminate strings and display state transition */\n\t\ttms_str[tap_out_bits] = tdi_str[tap_out_bits] = 0;\n\t\tJTAG_DEBUG_STATE_PRINT(last_state, next_state, tms_str, tdi_str);\n\t}\n\n\tLOG_DEBUG_IO(\"TAP/SM: FINAL state: %s\", tap_state_name(next_state));\n\n\treturn next_state;\n}\n\nvoid tap_use_new_tms_table(bool use_new)\n{\n\ttms_seqs = use_new ? &short_tms_seqs : &old_tms_seqs;\n}\nbool tap_uses_new_tms_table(void)\n{\n\treturn tms_seqs == &short_tms_seqs;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/interface.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_INTERFACE_H\n#define OPENOCD_JTAG_INTERFACE_H\n\n#include <jtag/jtag.h>\n#include <jtag/swim.h>\n#include <target/arm_tpiu_swo.h>\n\n/* @file\n * The \"Cable Helper API\" is what the cable drivers can use to help\n * implement their \"Cable API\".  So a Cable Helper API is a set of\n * helper functions used by cable drivers, and this is different from a\n * Cable API.  A \"Cable API\" is what higher level code used to talk to a\n * cable.\n */\n\n\n/** implementation of wrapper function tap_set_state() */\nvoid tap_set_state_impl(tap_state_t new_state);\n\n/**\n * This function sets the state of a \"state follower\" which tracks the\n * state of the TAPs connected to the cable.  The state follower is\n * hopefully always in the same state as the actual TAPs in the jtag\n * chain, and will be so if there are no bugs in the tracking logic\n * within that cable driver.\n *\n * All the cable drivers call this function to indicate the state they\n * think the TAPs attached to their cables are in.  Because this\n * function can also log transitions, it will be helpful to call this\n * function with every transition that the TAPs being manipulated are\n * expected to traverse, not just end points of a multi-step state path.\n *\n * @param new_state The state we think the TAPs are currently in (or\n * are about to enter).\n */\n#define tap_set_state(new_state) \\\n\tdo { \\\n\t\tLOG_DEBUG_IO(\"tap_set_state(%s)\", tap_state_name(new_state)); \\\n\t\ttap_set_state_impl(new_state); \\\n\t} while (0)\n\n/**\n * This function gets the state of the \"state follower\" which tracks the\n * state of the TAPs connected to the cable. @see tap_set_state @return\n * tap_state_t The state the TAPs are in now.\n */\ntap_state_t tap_get_state(void);\n\n/**\n * This function sets the state of an \"end state follower\" which tracks\n * the state that any cable driver thinks will be the end (resultant)\n * state of the current TAP SIR or SDR operation.\n *\n * At completion of that TAP operation this value is copied into the\n * state follower via tap_set_state().\n *\n * @param new_end_state The state the TAPs should enter at completion of\n * a pending TAP operation.\n */\nvoid tap_set_end_state(tap_state_t new_end_state);\n\n/**\n * For more information, @see tap_set_end_state\n * @return tap_state_t - The state the TAPs should be in at completion of the current TAP operation.\n */\ntap_state_t tap_get_end_state(void);\n\n/**\n * This function provides a \"bit sequence\" indicating what has to be\n * done with TMS during a sequence of seven TAP clock cycles in order to\n * get from state \\a \"from\" to state \\a \"to\".\n *\n * The length of the sequence must be determined with a parallel call to\n * tap_get_tms_path_len().\n *\n * @param from The starting state.\n * @param to The desired final state.\n * @return int The required TMS bit sequence, with the first bit in the\n * sequence at bit 0.\n */\nint tap_get_tms_path(tap_state_t from, tap_state_t to);\n\n/**\n * Function int tap_get_tms_path_len\n * returns the total number of bits that represents a TMS path\n * transition as given by the function tap_get_tms_path().\n *\n * For at least one interface (JLink) it's not OK to simply \"pad\" TMS\n * sequences to fit a whole byte.  (I suspect this is a general TAP\n * problem within OOCD.) Padding TMS causes all manner of instability\n * that's not easily discovered.  Using this routine we can apply\n * EXACTLY the state transitions required to make something work - no\n * more - no less.\n *\n * @param from is the starting state\n * @param to is the resultant or final state\n * @return int - the total number of bits in a transition.\n */\nint tap_get_tms_path_len(tap_state_t from, tap_state_t to);\n\n\n/**\n * Function tap_move_ndx\n * when given a stable state, returns an index from 0-5.  The index corresponds to a\n * sequence of stable states which are given in this order: <p>\n * { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE }\n * <p>\n * This sequence corresponds to look up tables which are used in some of the\n * cable drivers.\n * @param astate is the stable state to find in the sequence.  If a non stable\n *  state is passed, this may cause the program to output an error message\n *  and terminate.\n * @return int - the array (or sequence) index as described above\n */\nint tap_move_ndx(tap_state_t astate);\n\n/**\n * Function tap_is_state_stable\n * returns true if the \\a astate is stable.\n */\nbool tap_is_state_stable(tap_state_t astate);\n\n/**\n * Function tap_state_transition\n * takes a current TAP state and returns the next state according to the tms value.\n * @param current_state is the state of a TAP currently.\n * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface.\n * @return tap_state_t - the next state a TAP would enter.\n */\ntap_state_t tap_state_transition(tap_state_t current_state, bool tms);\n\n/** Allow switching between old and new TMS tables. @see tap_get_tms_path */\nvoid tap_use_new_tms_table(bool use_new);\n/** @returns True if new TMS table is active; false otherwise. */\nbool tap_uses_new_tms_table(void);\n\ntap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf,\n\t\tunsigned int tap_len, tap_state_t start_tap_state);\n\n/**\n * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers.\n * @param tms_buf must points to a buffer containing the TMS bitstream.\n * @param tdi_buf must points to a buffer containing the TDI bitstream.\n * @param tap_len must specify the length of the TMS/TDI bitstreams.\n * @param start_tap_state must specify the current TAP state.\n * @returns the final TAP state; pass as @a start_tap_state in following call.\n */\nstatic inline tap_state_t jtag_debug_state_machine(const void *tms_buf,\n\t\tconst void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state)\n{\n\tif (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO))\n\t\treturn jtag_debug_state_machine_(tms_buf, tdi_buf, tap_len, start_tap_state);\n\telse\n\t\treturn start_tap_state;\n}\n\n/**\n * Represents a driver for a debugging interface.\n *\n * @todo Rename; perhaps \"debug_driver\".  This isn't an interface,\n * it's a driver!  Also, not all drivers support JTAG.\n *\n * @todo We need a per-instance structure too, and changes to pass\n * that structure to the driver.  Instances can for example be in\n * either SWD or JTAG modes.  This will help remove globals, and\n * eventually to cope with systems which have more than one such\n * debugging interface.\n */\nstruct jtag_interface {\n\t/**\n\t * Bit vector listing capabilities exposed by this driver.\n\t */\n\tunsigned supported;\n#define DEBUG_CAP_TMS_SEQ\t(1 << 0)\n\n\t/**\n\t * Execute queued commands.\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*execute_queue)(void);\n};\n\n/**\n * Represents a driver for a debugging interface\n *\n * @todo We need a per-instance structure too, and changes to pass\n * that structure to the driver.  Instances can for example be in\n * either SWD or JTAG modes.  This will help remove globals, and\n * eventually to cope with systems which have more than one such\n * debugging interface.\n */\nstruct adapter_driver {\n\t/** The name of the interface driver. */\n\tconst char * const name;\n\n\t/** transports supported in C code (NULL terminated vector) */\n\tconst char * const *transports;\n\n\t/**\n\t * The interface driver may register additional commands to expose\n\t * additional features not covered by the standard command set.\n\t */\n\tconst struct command_registration *commands;\n\n\t/**\n\t * Interface driver must initialize any resources and connect to a\n\t * JTAG device.\n\t *\n\t * quit() is invoked if and only if init() succeeds. quit() is always\n\t * invoked if init() succeeds. Same as malloc() + free(). Always\n\t * invoke free() if malloc() succeeds and do not invoke free()\n\t * otherwise.\n\t *\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*init)(void);\n\n\t/**\n\t * Interface driver must tear down all resources and disconnect from\n\t * the JTAG device.\n\t *\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*quit)(void);\n\n\t/**\n\t * Control (assert/deassert) the signals SRST and TRST on the interface.\n\t * This function is synchronous and should be called after the adapter\n\t * queue has been properly flushed.\n\t * This function is optional.\n\t * Adapters that don't support resets can either not define this function\n\t * or return an error code.\n\t * Adapters that don't support one of the two reset should ignore the\n\t * request to assert the missing signal and eventually log an error.\n\t *\n\t * @param srst 1 to assert SRST, 0 to deassert SRST.\n\t * @param trst 1 to assert TRST, 0 to deassert TRST.\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*reset)(int srst, int trst);\n\n\t/**\n\t * Set the interface speed.\n\t * @param speed The new interface speed setting.\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*speed)(int speed);\n\n\t/**\n\t * Returns JTAG maximum speed for KHz. 0 = RTCK. The function returns\n\t *  a failure if it can't support the KHz/RTCK.\n\t *\n\t *  WARNING!!!! if RTCK is *slow* then think carefully about\n\t *  whether you actually want to support this in the driver.\n\t *  Many target scripts are written to handle the absence of RTCK\n\t *  and use a fallback kHz TCK.\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*khz)(int khz, int *jtag_speed);\n\n\t/**\n\t * Calculate the clock frequency (in KHz) for the given @a speed.\n\t * @param speed The desired interface speed setting.\n\t * @param khz On return, contains the speed in KHz (0 for RTCK).\n\t * @returns ERROR_OK on success, or an error code if the\n\t * interface cannot support the specified speed (KHz or RTCK).\n\t */\n\tint (*speed_div)(int speed, int *khz);\n\n\t/**\n\t * Read and clear the power dropout flag. Note that a power dropout\n\t * can be transitionary, easily much less than a ms.\n\t *\n\t * To find out if the power is *currently* on, one must invoke this\n\t * method twice.  Once to clear the power dropout flag and a second\n\t * time to read the current state.  The default implementation\n\t * never reports power dropouts.\n\t *\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*power_dropout)(int *power_dropout);\n\n\t/**\n\t * Read and clear the srst asserted detection flag.\n\t *\n\t * Like power_dropout this does *not* read the current\n\t * state.  SRST assertion is transitionary and may be much\n\t * less than 1ms, so the interface driver must watch for these\n\t * events until this routine is called.\n\t *\n\t * @param srst_asserted On return, indicates whether SRST has\n\t * been asserted.\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*srst_asserted)(int *srst_asserted);\n\n\t/**\n\t * Configure trace parameters for the adapter\n\t *\n\t * @param enabled Whether to enable trace\n\t * @param pin_protocol Configured pin protocol\n\t * @param port_size Trace port width for sync mode\n\t * @param trace_freq A pointer to the configured trace\n\t * frequency; if it points to 0, the adapter driver must write\n\t * its maximum supported rate there\n\t * @param traceclkin_freq TRACECLKIN frequency provided to the TPIU in Hz\n\t * @param prescaler Pointer to the SWO prescaler calculated by the\n\t * adapter\n\t * @returns ERROR_OK on success, an error code on failure.\n\t */\n\tint (*config_trace)(bool enabled, enum tpiu_pin_protocol pin_protocol,\n\t\tuint32_t port_size, unsigned int *trace_freq,\n\t\tunsigned int traceclkin_freq, uint16_t *prescaler);\n\n\t/**\n\t * Poll for new trace data\n\t *\n\t * @param buf A pointer to buffer to store received data\n\t * @param size A pointer to buffer size; must be filled with\n\t * the actual amount of bytes written\n\t *\n\t * @returns ERROR_OK on success, an error code on failure.\n\t */\n\tint (*poll_trace)(uint8_t *buf, size_t *size);\n\n\t/** Low-level JTAG APIs */\n\tstruct jtag_interface *jtag_ops;\n\n\t/** Low-level SWD APIs */\n\tconst struct swd_driver *swd_ops;\n\n\t/* DAP APIs over JTAG transport */\n\tconst struct dap_ops *dap_jtag_ops;\n\n\t/* DAP APIs over SWD transport */\n\tconst struct dap_ops *dap_swd_ops;\n\n\t/* SWIM APIs */\n\tconst struct swim_driver *swim_ops;\n};\n\nextern const char * const jtag_only[];\n\nint adapter_resets(int assert_trst, int assert_srst);\nint adapter_assert_reset(void);\nint adapter_deassert_reset(void);\nint adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,\n\t\tuint32_t port_size, unsigned int *trace_freq,\n\t\tunsigned int traceclkin_freq, uint16_t *prescaler);\nint adapter_poll_trace(uint8_t *buf, size_t *size);\n\nextern struct adapter_driver am335xgpio_adapter_driver;\nextern struct adapter_driver amt_jtagaccel_adapter_driver;\nextern struct adapter_driver armjtagew_adapter_driver;\nextern struct adapter_driver at91rm9200_adapter_driver;\nextern struct adapter_driver bcm2835gpio_adapter_driver;\nextern struct adapter_driver buspirate_adapter_driver;\nextern struct adapter_driver cmsis_dap_adapter_driver;\nextern struct adapter_driver dummy_adapter_driver;\nextern struct adapter_driver ep93xx_adapter_driver;\nextern struct adapter_driver esp_usb_adapter_driver;\nextern struct adapter_driver ft232r_adapter_driver;\nextern struct adapter_driver ftdi_adapter_driver;\nextern struct adapter_driver gw16012_adapter_driver;\nextern struct adapter_driver hl_adapter_driver;\nextern struct adapter_driver imx_gpio_adapter_driver;\nextern struct adapter_driver jlink_adapter_driver;\nextern struct adapter_driver jtag_dpi_adapter_driver;\nextern struct adapter_driver jtag_vpi_adapter_driver;\nextern struct adapter_driver kitprog_adapter_driver;\nextern struct adapter_driver linuxgpiod_adapter_driver;\nextern struct adapter_driver opendous_adapter_driver;\nextern struct adapter_driver openjtag_adapter_driver;\nextern struct adapter_driver osbdm_adapter_driver;\nextern struct adapter_driver parport_adapter_driver;\nextern struct adapter_driver presto_adapter_driver;\nextern struct adapter_driver remote_bitbang_adapter_driver;\nextern struct adapter_driver rlink_adapter_driver;\nextern struct adapter_driver rshim_dap_adapter_driver;\nextern struct adapter_driver stlink_dap_adapter_driver;\nextern struct adapter_driver sysfsgpio_adapter_driver;\nextern struct adapter_driver ulink_adapter_driver;\nextern struct adapter_driver usb_blaster_adapter_driver;\nextern struct adapter_driver usbprog_adapter_driver;\nextern struct adapter_driver vdebug_adapter_driver;\nextern struct adapter_driver vsllink_adapter_driver;\nextern struct adapter_driver xds110_adapter_driver;\nextern struct adapter_driver xlnx_pcie_xvc_adapter_driver;\nextern struct adapter_driver ch347_adapter_driver;\n\n#endif /* OPENOCD_JTAG_INTERFACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/interfaces.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n *                                                                         *\n *   Copyright (C) 2020, Ampere Computing LLC                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"interfaces.h\"\n\n/** @file\n * This file collects all the built-in JTAG interfaces in the adapter_drivers\n * array.\n *\n * Dynamic loading can be implemented be searching for shared libraries\n * that contain an adapter_driver structure that can added to this list.\n */\n\n/**\n * The list of built-in JTAG interfaces, containing entries for those\n * drivers that were enabled by the @c configure script.\n */\nstruct adapter_driver *adapter_drivers[] = {\n#if BUILD_PARPORT == 1\n\t\t&parport_adapter_driver,\n#endif\n#if BUILD_DUMMY == 1\n\t\t&dummy_adapter_driver,\n#endif\n#if BUILD_FTDI == 1\n\t\t&ftdi_adapter_driver,\n#endif\n#if BUILD_USB_BLASTER || BUILD_USB_BLASTER_2 == 1\n\t\t&usb_blaster_adapter_driver,\n#endif\n#if BUILD_ESP_USB_JTAG == 1\n\t\t&esp_usb_adapter_driver,\n#endif\n#if BUILD_JTAG_VPI == 1\n\t\t&jtag_vpi_adapter_driver,\n#endif\n#if BUILD_VDEBUG == 1\n\t\t&vdebug_adapter_driver,\n#endif\n#if BUILD_JTAG_DPI == 1\n\t\t&jtag_dpi_adapter_driver,\n#endif\n#if BUILD_FT232R == 1\n\t\t&ft232r_adapter_driver,\n#endif\n#if BUILD_AMTJTAGACCEL == 1\n\t\t&amt_jtagaccel_adapter_driver,\n#endif\n#if BUILD_EP93XX == 1\n\t\t&ep93xx_adapter_driver,\n#endif\n#if BUILD_AT91RM9200 == 1\n\t\t&at91rm9200_adapter_driver,\n#endif\n#if BUILD_GW16012 == 1\n\t\t&gw16012_adapter_driver,\n#endif\n#if BUILD_PRESTO\n\t\t&presto_adapter_driver,\n#endif\n#if BUILD_USBPROG == 1\n\t\t&usbprog_adapter_driver,\n#endif\n#if BUILD_OPENJTAG == 1\n\t\t&openjtag_adapter_driver,\n#endif\n#if BUILD_JLINK == 1\n\t\t&jlink_adapter_driver,\n#endif\n#if BUILD_VSLLINK == 1\n\t\t&vsllink_adapter_driver,\n#endif\n#if BUILD_RLINK == 1\n\t\t&rlink_adapter_driver,\n#endif\n#if BUILD_ULINK == 1\n\t\t&ulink_adapter_driver,\n#endif\n#if BUILD_ARMJTAGEW == 1\n\t\t&armjtagew_adapter_driver,\n#endif\n#if BUILD_BUSPIRATE == 1\n\t\t&buspirate_adapter_driver,\n#endif\n#if BUILD_REMOTE_BITBANG == 1\n\t\t&remote_bitbang_adapter_driver,\n#endif\n#if BUILD_HLADAPTER == 1\n\t\t&hl_adapter_driver,\n#endif\n#if BUILD_OSBDM == 1\n\t\t&osbdm_adapter_driver,\n#endif\n#if BUILD_OPENDOUS == 1\n\t\t&opendous_adapter_driver,\n#endif\n#if BUILD_SYSFSGPIO == 1\n\t\t&sysfsgpio_adapter_driver,\n#endif\n#if BUILD_LINUXGPIOD == 1\n\t\t&linuxgpiod_adapter_driver,\n#endif\n#if BUILD_XLNX_PCIE_XVC == 1\n\t\t&xlnx_pcie_xvc_adapter_driver,\n#endif\n#if BUILD_BCM2835GPIO == 1\n\t\t&bcm2835gpio_adapter_driver,\n#endif\n#if BUILD_CMSIS_DAP_USB == 1 || BUILD_CMSIS_DAP_HID == 1\n\t\t&cmsis_dap_adapter_driver,\n#endif\n#if BUILD_KITPROG == 1\n\t\t&kitprog_adapter_driver,\n#endif\n#if BUILD_IMX_GPIO == 1\n\t\t&imx_gpio_adapter_driver,\n#endif\n#if BUILD_XDS110 == 1\n\t\t&xds110_adapter_driver,\n#endif\n#if BUILD_HLADAPTER_STLINK == 1\n\t\t&stlink_dap_adapter_driver,\n#endif\n#if BUILD_RSHIM == 1\n\t\t&rshim_dap_adapter_driver,\n#endif\n#if BUILD_AM335XGPIO == 1\n\t\t&am335xgpio_adapter_driver,\n#endif\n#if BUILD_CH347 == 1\n\t\t&ch347_adapter_driver,\n#endif\n\t\tNULL,\n\t};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/interfaces.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_INTERFACES_H\n#define OPENOCD_JTAG_INTERFACES_H\n\n/** @file\n * Exports the list of JTAG interface drivers, along with routines\n * for loading and unloading them dynamically from shared libraries.\n */\n\n#include <jtag/interface.h>\n\nextern struct adapter_driver *adapter_drivers[];\n\n#endif /* OPENOCD_JTAG_INTERFACES_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n*   Copyright (C) 2005 by Dominic Rath                                    *\n*   Dominic.Rath@gmx.de                                                   *\n*                                                                         *\n*   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n*   oyvind.harboe@zylin.com                                               *\n***************************************************************************/\n\n#ifndef OPENOCD_JTAG_JTAG_H\n#define OPENOCD_JTAG_JTAG_H\n\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <helper/log.h>\n#include <helper/replacements.h>\n\n#ifndef DEBUG_JTAG_IOZ\n#define DEBUG_JTAG_IOZ 64\n#endif\n\n/*-----</Macros>-------------------------------------------------*/\n\n/**\n * Defines JTAG Test Access Port states.\n *\n * These definitions were gleaned from the ARM7TDMI-S Technical\n * Reference Manual and validated against several other ARM core\n * technical manuals.\n *\n * FIXME some interfaces require specific numbers be used, as they\n * are handed-off directly to their hardware implementations.\n * Fix those drivers to map as appropriate ... then pick some\n * sane set of numbers here (where 0/uninitialized == INVALID).\n */\ntypedef enum tap_state {\n\tTAP_INVALID = -1,\n\n\t/* Proper ARM recommended numbers */\n\tTAP_DREXIT2 = 0x0,\n\tTAP_DREXIT1 = 0x1,\n\tTAP_DRSHIFT = 0x2,\n\tTAP_DRPAUSE = 0x3,\n\tTAP_IRSELECT = 0x4,\n\tTAP_DRUPDATE = 0x5,\n\tTAP_DRCAPTURE = 0x6,\n\tTAP_DRSELECT = 0x7,\n\tTAP_IREXIT2 = 0x8,\n\tTAP_IREXIT1 = 0x9,\n\tTAP_IRSHIFT = 0xa,\n\tTAP_IRPAUSE = 0xb,\n\tTAP_IDLE = 0xc,\n\tTAP_IRUPDATE = 0xd,\n\tTAP_IRCAPTURE = 0xe,\n\tTAP_RESET = 0x0f,\n} tap_state_t;\n\n/**\n * Defines arguments for reset functions\n */\n#define SRST_DEASSERT   0\n#define SRST_ASSERT     1\n#define TRST_DEASSERT   0\n#define TRST_ASSERT     1\n\n/**\n * Function tap_state_name\n * Returns a string suitable for display representing the JTAG tap_state\n */\nconst char *tap_state_name(tap_state_t state);\n\n/** Provides user-friendly name lookup of TAP states. */\ntap_state_t tap_state_by_name(const char *name);\n\n/** The current TAP state of the pending JTAG command queue. */\nextern tap_state_t cmd_queue_cur_state;\n\n/**\n * This structure defines a single scan field in the scan. It provides\n * fields for the field's width and pointers to scan input and output\n * values.\n *\n * In addition, this structure includes a value and mask that is used by\n * jtag_add_dr_scan_check() to validate the value that was scanned out.\n */\nstruct scan_field {\n\t/** The number of bits this field specifies */\n\tint num_bits;\n\t/** A pointer to value to be scanned into the device */\n\tconst uint8_t *out_value;\n\t/** A pointer to a 32-bit memory location for data scanned out */\n\tuint8_t *in_value;\n\n\t/** The value used to check the data scanned out. */\n\tuint8_t *check_value;\n\t/** The mask to go with check_value */\n\tuint8_t *check_mask;\n};\n\nstruct jtag_tap {\n\tchar *chip;\n\tchar *tapname;\n\tchar *dotted_name;\n\tint abs_chain_position;\n\t/** Is this TAP disabled after JTAG reset? */\n\tbool disabled_after_reset;\n\t/** Is this TAP currently enabled? */\n\tbool enabled;\n\tint ir_length; /**< size of instruction register */\n\tuint32_t ir_capture_value;\n\tuint8_t *expected; /**< Capture-IR expected value */\n\tuint32_t ir_capture_mask;\n\tuint8_t *expected_mask; /**< Capture-IR expected mask */\n\tuint32_t idcode; /**< device identification code */\n\t/** not all devices have idcode,\n\t * we'll discover this during chain examination */\n\tbool hasidcode;\n\n\t/** Array of expected identification codes */\n\tuint32_t *expected_ids;\n\t/** Number of expected identification codes */\n\tuint8_t expected_ids_cnt;\n\n\t/** Flag saying whether to ignore version field in expected_ids[] */\n\tbool ignore_version;\n\n\t/** Flag saying whether to ignore the bypass bit in the code */\n\tbool ignore_bypass;\n\n\t/** current instruction */\n\tuint8_t *cur_instr;\n\t/** Bypass register selected */\n\tint bypass;\n\n\tstruct jtag_tap_event_action *event_action;\n\n\tstruct jtag_tap *next_tap;\n\t/* private pointer to support none-jtag specific functions */\n\tvoid *priv;\n};\n\nvoid jtag_tap_init(struct jtag_tap *tap);\nvoid jtag_tap_free(struct jtag_tap *tap);\n\nstruct jtag_tap *jtag_all_taps(void);\nconst char *jtag_tap_name(const struct jtag_tap *tap);\nstruct jtag_tap *jtag_tap_by_string(const char *dotted_name);\nstruct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *obj);\nstruct jtag_tap *jtag_tap_by_position(unsigned abs_position);\nstruct jtag_tap *jtag_tap_next_enabled(struct jtag_tap *p);\nunsigned jtag_tap_count_enabled(void);\nunsigned jtag_tap_count(void);\n\n/*\n * - TRST_ASSERTED triggers two sets of callbacks, after operations to\n *   reset the scan chain -- via TMS+TCK signaling, or deasserting the\n *   nTRST signal -- are queued:\n *\n *    + Callbacks in C code fire first, patching internal state\n *    + Then post-reset event scripts fire ... activating JTAG circuits\n *      via TCK cycles, exiting SWD mode via TMS sequences, etc\n *\n *   During those callbacks, scan chain contents have not been validated.\n *   JTAG operations that address a specific TAP (primarily DR/IR scans)\n *   must *not* be queued.\n *\n * - TAP_EVENT_SETUP is reported after TRST_ASSERTED, and after the scan\n *   chain has been validated.  JTAG operations including scans that\n *   target specific TAPs may be performed.\n *\n * - TAP_EVENT_ENABLE and TAP_EVENT_DISABLE implement TAP activation and\n *   deactivation outside the core using scripted code that understands\n *   the specific JTAG router type.  They might be triggered indirectly\n *   from EVENT_SETUP operations.\n */\nenum jtag_event {\n\tJTAG_TRST_ASSERTED,\n\tJTAG_TAP_EVENT_SETUP,\n\tJTAG_TAP_EVENT_ENABLE,\n\tJTAG_TAP_EVENT_DISABLE,\n};\n\nstruct jtag_tap_event_action {\n\t/** The event for which this action will be triggered. */\n\tenum jtag_event event;\n\t/** The interpreter to use for evaluating the @c body. */\n\tJim_Interp *interp;\n\t/** Contains a script to 'eval' when the @c event is triggered. */\n\tJim_Obj *body;\n\t/* next action in linked list */\n\tstruct jtag_tap_event_action *next;\n};\n\n/**\n * Defines the function signature required for JTAG event callback\n * functions, which are added with jtag_register_event_callback()\n * and removed jtag_unregister_event_callback().\n * @param event The event to handle.\n * @param priv A pointer to data that was passed to\n *\tjtag_register_event_callback().\n * @returns Must return ERROR_OK on success, or an error code on failure.\n *\n * @todo Change to return void or define a use for its return code.\n */\ntypedef int (*jtag_event_handler_t)(enum jtag_event event, void *priv);\n\nint jtag_register_event_callback(jtag_event_handler_t f, void *x);\nint jtag_unregister_event_callback(jtag_event_handler_t f, void *x);\n\nint jtag_call_event_callbacks(enum jtag_event event);\n\nenum reset_types {\n\tRESET_NONE            = 0x0,\n\tRESET_HAS_TRST        = 0x1,\n\tRESET_HAS_SRST        = 0x2,\n\tRESET_TRST_AND_SRST   = 0x3,\n\tRESET_SRST_PULLS_TRST = 0x4,\n\tRESET_TRST_PULLS_SRST = 0x8,\n\tRESET_TRST_OPEN_DRAIN = 0x10,\n\tRESET_SRST_PUSH_PULL  = 0x20,\n\tRESET_SRST_NO_GATING  = 0x40,\n\tRESET_CNCT_UNDER_SRST = 0x80\n};\n\nenum reset_types jtag_get_reset_config(void);\nvoid jtag_set_reset_config(enum reset_types type);\n\nvoid jtag_set_nsrst_delay(unsigned delay);\nunsigned jtag_get_nsrst_delay(void);\n\nvoid jtag_set_ntrst_delay(unsigned delay);\nunsigned jtag_get_ntrst_delay(void);\n\nvoid jtag_set_nsrst_assert_width(unsigned delay);\nunsigned jtag_get_nsrst_assert_width(void);\n\nvoid jtag_set_ntrst_assert_width(unsigned delay);\nunsigned jtag_get_ntrst_assert_width(void);\n\n/** @returns The current state of TRST. */\nint jtag_get_trst(void);\n/** @returns The current state of SRST. */\nint jtag_get_srst(void);\n\n/** Enable or disable data scan verification checking. */\nvoid jtag_set_verify(bool enable);\n/** @returns True if data scan verification will be performed. */\nbool jtag_will_verify(void);\n\n/** Enable or disable verification of IR scan checking. */\nvoid jtag_set_verify_capture_ir(bool enable);\n/** @returns True if IR scan verification will be performed. */\nbool jtag_will_verify_capture_ir(void);\n\n/** Set ms to sleep after jtag_execute_queue() flushes queue. Debug purposes. */\nvoid jtag_set_flush_queue_sleep(int ms);\n\n/**\n * Initialize JTAG chain using only a RESET reset. If init fails,\n * try reset + init.\n */\nint jtag_init(struct command_context *cmd_ctx);\n\n/** reset, then initialize JTAG chain */\nint jtag_init_reset(struct command_context *cmd_ctx);\nint jtag_register_commands(struct command_context *cmd_ctx);\nint jtag_init_inner(struct command_context *cmd_ctx);\n\n/**\n * @file\n * The JTAG interface can be implemented with a software or hardware fifo.\n *\n * TAP_DRSHIFT and TAP_IRSHIFT are illegal end states; however,\n * TAP_DRSHIFT/IRSHIFT can be emulated as end states, by using longer\n * scans.\n *\n * Code that is relatively insensitive to the path taken through state\n * machine (as long as it is JTAG compliant) can use @a endstate for\n * jtag_add_xxx_scan(). Otherwise, the pause state must be specified as\n * end state and a subsequent jtag_add_pathmove() must be issued.\n */\n\n/**\n * Generate an IR SCAN with a list of scan fields with one entry for\n * each enabled TAP.\n *\n * If the input field list contains an instruction value for a TAP then\n * that is used otherwise the TAP is set to bypass.\n *\n * TAPs for which no fields are passed are marked as bypassed for\n * subsequent DR SCANs.\n *\n */\nvoid jtag_add_ir_scan(struct jtag_tap *tap,\n\t\tstruct scan_field *fields, tap_state_t endstate);\n/**\n * The same as jtag_add_ir_scan except no verification is performed out\n * the output values.\n */\nvoid jtag_add_ir_scan_noverify(struct jtag_tap *tap,\n\t\tconst struct scan_field *fields, tap_state_t state);\n/**\n * Scan out the bits in ir scan mode.\n *\n * If in_bits == NULL, discard incoming bits.\n */\nvoid jtag_add_plain_ir_scan(int num_bits, const uint8_t *out_bits, uint8_t *in_bits,\n\t\ttap_state_t endstate);\n\n/**\n * Generate a DR SCAN using the fields passed to the function.\n * For connected TAPs, the function checks in_fields and uses fields\n * specified there.  For bypassed TAPs, the function generates a dummy\n * 1-bit field.  The bypass status of TAPs is set by jtag_add_ir_scan().\n */\nvoid jtag_add_dr_scan(struct jtag_tap *tap, int num_fields,\n\t\tconst struct scan_field *fields, tap_state_t endstate);\n/** A version of jtag_add_dr_scan() that uses the check_value/mask fields */\nvoid jtag_add_dr_scan_check(struct jtag_tap *tap, int num_fields,\n\t\tstruct scan_field *fields, tap_state_t endstate);\n/**\n * Scan out the bits in ir scan mode.\n *\n * If in_bits == NULL, discard incoming bits.\n */\nvoid jtag_add_plain_dr_scan(int num_bits,\n\t\tconst uint8_t *out_bits, uint8_t *in_bits, tap_state_t endstate);\n\n/**\n * Defines the type of data passed to the jtag_callback_t interface.\n * The underlying type must allow storing an @c int or pointer type.\n */\ntypedef intptr_t jtag_callback_data_t;\n\n/**\n * Defines a simple JTAG callback that can allow conversions on data\n * scanned in from an interface.\n *\n * This callback should only be used for conversion that cannot fail.\n * For conversion types or checks that can fail, use the more complete\n * variant: jtag_callback_t.\n */\ntypedef void (*jtag_callback1_t)(jtag_callback_data_t data0);\n\n/** A simpler version of jtag_add_callback4(). */\nvoid jtag_add_callback(jtag_callback1_t f, jtag_callback_data_t data0);\n\n\n/**\n * Defines the interface of the JTAG callback mechanism.  Such\n * callbacks can be executed once the queue has been flushed.\n *\n * The JTAG queue can be executed synchronously or asynchronously.\n * Typically for USB, the queue is executed asynchronously.  For\n * low-latency interfaces, the queue may be executed synchronously.\n *\n * The callback mechanism is very general and does not make many\n * assumptions about what the callback does or what its arguments are.\n * These callbacks are typically executed *after* the *entire* JTAG\n * queue has been executed for e.g. USB interfaces, and they are\n * guaranteed to be invoked in the order that they were queued.\n *\n * If the execution of the queue fails before the callbacks, then --\n * depending on driver implementation -- the callbacks may or may not be\n * invoked.\n *\n * @todo Make that behavior consistent.\n *\n * @param data0 Typically used to point to the data to operate on.\n * Frequently this will be the data clocked in during a shift operation.\n * @param data1 An integer big enough to use as an @c int or a pointer.\n * @param data2 An integer big enough to use as an @c int or a pointer.\n * @param data3 An integer big enough to use as an @c int or a pointer.\n * @returns an error code\n */\ntypedef int (*jtag_callback_t)(jtag_callback_data_t data0,\n\t\t\t\tjtag_callback_data_t data1,\n\t\t\t\tjtag_callback_data_t data2,\n\t\t\t\tjtag_callback_data_t data3);\n\n/**\n * Run a TAP_RESET reset where the end state is TAP_RESET,\n * regardless of the start state.\n */\nvoid jtag_add_tlr(void);\n\n/**\n * Application code *must* assume that interfaces will\n * implement transitions between states with different\n * paths and path lengths through the state diagram. The\n * path will vary across interface and also across versions\n * of the same interface over time. Even if the OpenOCD code\n * is unchanged, the actual path taken may vary over time\n * and versions of interface firmware or PCB revisions.\n *\n * Use jtag_add_pathmove() when specific transition sequences\n * are required.\n *\n * Do not use jtag_add_pathmove() unless you need to, but do use it\n * if you have to.\n *\n * DANGER! If the target is dependent upon a particular sequence\n * of transitions for things to work correctly(e.g. as a workaround\n * for an errata that contradicts the JTAG standard), then pathmove\n * must be used, even if some jtag interfaces happen to use the\n * desired path. Worse, the jtag interface used for testing a\n * particular implementation, could happen to use the \"desired\"\n * path when transitioning to/from end\n * state.\n *\n * A list of unambiguous single clock state transitions, not\n * all drivers can support this, but it is required for e.g.\n * XScale and Xilinx support\n *\n * Note! TAP_RESET must not be used in the path!\n *\n * Note that the first on the list must be reachable\n * via a single transition from the current state.\n *\n * All drivers are required to implement jtag_add_pathmove().\n * However, if the pathmove sequence can not be precisely\n * executed, an interface_jtag_add_pathmove() or jtag_execute_queue()\n * must return an error. It is legal, but not recommended, that\n * a driver returns an error in all cases for a pathmove if it\n * can only implement a few transitions and therefore\n * a partial implementation of pathmove would have little practical\n * application.\n *\n * If an error occurs, jtag_error will contain one of these error codes:\n *   - ERROR_JTAG_NOT_STABLE_STATE -- The final state was not stable.\n *   - ERROR_JTAG_STATE_INVALID -- The path passed through TAP_RESET.\n *   - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid\n *     state transitions.\n */\nvoid jtag_add_pathmove(int num_states, const tap_state_t *path);\n\n/**\n * jtag_add_statemove() moves from the current state to @a goal_state.\n *\n * @param goal_state The final TAP state.\n * @return ERROR_OK on success, or an error code on failure.\n *\n * Moves from the current state to the goal \\a state.\n * Both states must be stable.\n */\nint jtag_add_statemove(tap_state_t goal_state);\n\n/**\n * Goes to TAP_IDLE (if we're not already there), cycle\n * precisely num_cycles in the TAP_IDLE state, after which move\n * to @a endstate (unless it is also TAP_IDLE).\n *\n * @param num_cycles Number of cycles in TAP_IDLE state.  This argument\n *\tmay be 0, in which case this routine will navigate to @a endstate\n *\tvia TAP_IDLE.\n * @param endstate The final state.\n */\nvoid jtag_add_runtest(int num_cycles, tap_state_t endstate);\n\n/**\n * A reset of the TAP state machine can be requested.\n *\n * Whether tms or trst reset is used depends on the capabilities of\n * the target and jtag interface(reset_config  command configures this).\n *\n * srst can driver a reset of the TAP state machine and vice\n * versa\n *\n * Application code may need to examine value of jtag_reset_config\n * to determine the proper codepath\n *\n * DANGER! Even though srst drives trst, trst might not be connected to\n * the interface, and it might actually be *harmful* to assert trst in this case.\n *\n * This is why combinations such as \"reset_config srst_only srst_pulls_trst\"\n * are supported.\n *\n * only req_tlr_or_trst and srst can have a transition for a\n * call as the effects of transitioning both at the \"same time\"\n * are undefined, but when srst_pulls_trst or vice versa,\n * then trst & srst *must* be asserted together.\n */\nvoid jtag_add_reset(int req_tlr_or_trst, int srst);\n\nvoid jtag_add_sleep(uint32_t us);\n\nint jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state t);\n\n/**\n * Function jtag_add_clocks\n * first checks that the state in which the clocks are to be issued is\n * stable, then queues up num_cycles clocks for transmission.\n */\nvoid jtag_add_clocks(int num_cycles);\n\n/**\n * For software FIFO implementations, the queued commands can be executed\n * during this call or earlier. A sw queue might decide to push out\n * some of the jtag_add_xxx() operations once the queue is \"big enough\".\n *\n * This fn will return an error code if any of the prior jtag_add_xxx()\n * calls caused a failure, e.g. check failure. Note that it does not\n * matter if the operation was executed *before* jtag_execute_queue(),\n * jtag_execute_queue() will still return an error code.\n *\n * All jtag_add_xxx() calls that have in_handler != NULL will have been\n * executed when this fn returns, but if what has been queued only\n * clocks data out, without reading anything back, then JTAG could\n * be running *after* jtag_execute_queue() returns. The API does\n * not define a way to flush a hw FIFO that runs *after*\n * jtag_execute_queue() returns.\n *\n * jtag_add_xxx() commands can either be executed immediately or\n * at some time between the jtag_add_xxx() fn call and jtag_execute_queue().\n */\nint jtag_execute_queue(void);\n\n/** same as jtag_execute_queue() but does not clear the error flag */\nvoid jtag_execute_queue_noclear(void);\n\n/** @returns the number of times the scan queue has been flushed */\nint jtag_get_flush_queue_count(void);\n\n/** Report Tcl event to all TAPs */\nvoid jtag_notify_event(enum jtag_event);\n\n/* can be implemented by hw + sw */\nint jtag_power_dropout(int *dropout);\nint jtag_srst_asserted(int *srst_asserted);\n\n/* JTAG support functions */\n\n/**\n * Execute jtag queue and check value with an optional mask.\n * @param field Pointer to scan field.\n * @param value Pointer to scan value.\n * @param mask Pointer to scan mask; may be NULL.\n *\n * returns Nothing, but calls jtag_set_error() on any error.\n */\nvoid jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *mask);\n\nvoid jtag_sleep(uint32_t us);\n\n/*\n * The JTAG subsystem defines a number of error codes,\n * using codes between -100 and -199.\n */\n#define ERROR_JTAG_INIT_FAILED       (-100)\n#define ERROR_JTAG_INVALID_INTERFACE (-101)\n#define ERROR_JTAG_NOT_IMPLEMENTED   (-102)\n#define ERROR_JTAG_TRST_ASSERTED     (-103)\n#define ERROR_JTAG_QUEUE_FAILED      (-104)\n#define ERROR_JTAG_NOT_STABLE_STATE  (-105)\n#define ERROR_JTAG_DEVICE_ERROR      (-107)\n#define ERROR_JTAG_STATE_INVALID     (-108)\n#define ERROR_JTAG_TRANSITION_INVALID (-109)\n#define ERROR_JTAG_INIT_SOFT_FAIL    (-110)\n\n/**\n * Set the current JTAG core execution error, unless one was set\n * by a previous call previously.  Driver or application code must\n * use jtag_error_clear to reset jtag_error once this routine has been\n * called with a non-zero error code.\n */\nvoid jtag_set_error(int error);\n/**\n * Resets jtag_error to ERROR_OK, returning its previous value.\n * @returns The previous value of @c jtag_error.\n */\nint jtag_error_clear(void);\n\n/**\n * Return true if it's safe for a background polling task to access the\n * JTAG scan chain.  Polling may be explicitly disallowed, and is also\n * unsafe while nTRST is active or the JTAG clock is gated off.\n */\nbool is_jtag_poll_safe(void);\n\n/**\n * Return flag reporting whether JTAG polling is disallowed.\n */\nbool jtag_poll_get_enabled(void);\n\n/**\n * Assign flag reporting whether JTAG polling is disallowed.\n */\nvoid jtag_poll_set_enabled(bool value);\n\n/**\n * Mask (disable) polling and return the current mask status that should be\n * feed to jtag_poll_unmask() to restore it.\n * Multiple nested calls to jtag_poll_mask() are allowed, each balanced with\n * its call to jtag_poll_unmask().\n */\nbool jtag_poll_mask(void);\n\n/**\n * Restore saved mask for polling.\n */\nvoid jtag_poll_unmask(bool saved);\n\n#include <jtag/minidriver.h>\n\n__COMMAND_HANDLER(handle_jtag_newtap);\n\n#endif /* OPENOCD_JTAG_JTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/minidriver.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_MINIDRIVER_H\n#define OPENOCD_JTAG_MINIDRIVER_H\n\n/**\n * @page jtagminidriver JTAG Mini-Driver\n *\n * The JTAG minidriver interface allows the definition of alternate\n * interface functions, instead of the built-in asynchronous driver\n * module that is used by the standard JTAG interface drivers.\n *\n * In addition to the functions defined in the @c minidriver.h file, the\n * @c jtag_minidriver.h file must declare the following functions (or\n * define static inline versions of them):\n * - jtag_add_callback\n * - jtag_add_callback4\n *\n * The following core functions are declared in this file for use by\n * the minidriver and do @b not need to be defined by an implementation:\n * - default_interface_jtag_execute_queue()\n */\n\n/* this header will be provided by the minidriver implementation, */\n/* and it may provide additional declarations that must be defined. */\n#include <jtag/drivers/minidriver_imp.h>\n\nint interface_jtag_add_ir_scan(struct jtag_tap *active,\n\t\tconst struct scan_field *fields,\n\t\ttap_state_t endstate);\nint interface_jtag_add_plain_ir_scan(\n\t\tint num_bits, const uint8_t *out_bits, uint8_t *in_bits,\n\t\ttap_state_t endstate);\n\nint interface_jtag_add_dr_scan(struct jtag_tap *active,\n\t\tint num_fields, const struct scan_field *fields,\n\t\ttap_state_t endstate);\nint interface_jtag_add_plain_dr_scan(\n\t\tint num_bits, const uint8_t *out_bits, uint8_t *in_bits,\n\t\ttap_state_t endstate);\n\nint interface_jtag_add_tlr(void);\nint interface_jtag_add_pathmove(int num_states, const tap_state_t *path);\nint interface_jtag_add_runtest(int num_cycles, tap_state_t endstate);\n\nint interface_add_tms_seq(unsigned num_bits,\n\t\tconst uint8_t *bits, enum tap_state state);\n\n/**\n * This drives the actual srst and trst pins. srst will always be 0\n * if jtag_reset_config & RESET_SRST_PULLS_TRST != 0 and ditto for\n * trst.\n *\n * the higher level jtag_add_reset will invoke jtag_add_tlr() if\n * appropriate\n */\nint interface_jtag_add_reset(int trst, int srst);\nint interface_jtag_add_sleep(uint32_t us);\nint interface_jtag_add_clocks(int num_cycles);\nint interface_jtag_execute_queue(void);\n\n/**\n * Calls the interface callback to execute the queue.  This routine\n * is used by the JTAG driver layer and should not be called directly.\n */\nint default_interface_jtag_execute_queue(void);\n\n#endif /* OPENOCD_JTAG_MINIDRIVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/startup.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Defines basic Tcl procs for OpenOCD JTAG module\n\n# Executed during \"init\". Can be overridden\n# by board/target/... scripts\nproc jtag_init {} {\n\tif {[catch {jtag arp_init} err]!=0} {\n\t\t# try resetting additionally\n\t\tinit_reset startup\n\t}\n}\n\n# This reset logic may be overridden by board/target/... scripts as needed\n# to provide a reset that, if possible, is close to a power-up reset.\n#\n# Exit requirements include:  (a) JTAG must be working, (b) the scan\n# chain was validated with \"jtag arp_init\" (or equivalent), (c) nothing\n# stays in reset.  No TAP-specific scans were performed.  It's OK if\n# some targets haven't been reset yet; they may need TAP-specific scans.\n#\n# The \"mode\" values include:  halt, init, run (from \"reset\" command);\n# startup (at OpenOCD server startup, when JTAG may not yet work); and\n# potentially more (for reset types like cold, warm, etc)\nproc init_reset { mode } {\n\tif {[using_jtag]} {\n\t\tjtag arp_init-reset\n\t}\n}\n\n#########\n\n# TODO: power_restore and power_dropout are currently neither\n# documented nor supported.\n\nproc power_restore {} {\n\techo \"Sensed power restore, running reset init and halting GDB.\"\n\treset init\n\n\t# Halt GDB so user can deal with a detected power restore.\n\t#\n\t# After GDB is halted, then output is no longer forwarded\n\t# to the GDB console.\n\tset targets [target names]\n\tforeach t $targets {\n\t\t# New event script.\n\t\t$t invoke-event arp_halt_gdb\n\t}\n}\n\nadd_help_text power_restore \"Overridable procedure run when power restore is detected. Runs 'reset init' by default.\"\n\nproc power_dropout {} {\n\techo \"Sensed power dropout.\"\n}\n\n#########\n\n# TODO: srst_deasserted and srst_asserted are currently neither\n# documented nor supported.\n\nproc srst_deasserted {} {\n\techo \"Sensed nSRST deasserted, running reset init and halting GDB.\"\n\treset init\n\n\t# Halt GDB so user can deal with a detected reset.\n\t#\n\t# After GDB is halted, then output is no longer forwarded\n\t# to the GDB console.\n\tset targets [target names]\n\tforeach t $targets {\n\t\t# New event script.\n\t\t$t invoke-event arp_halt_gdb\n\t}\n}\n\nadd_help_text srst_deasserted \"Overridable procedure run when srst deassert is detected. Runs 'reset init' by default.\"\n\nproc srst_asserted {} {\n\techo \"Sensed nSRST asserted.\"\n}\n\n# measure actual JTAG clock\nproc measure_clk {} {\n\tset start_time [ms];\n\tset iterations 10000000;\n\truntest $iterations;\n\tset speed [expr \"$iterations.0 / ([ms] - $start_time)\"]\n\techo \"Running at more than $speed kHz\";\n}\n\nadd_help_text measure_clk \"Runs a test to measure the JTAG clk. Useful with RCLK / RTCK.\"\n\nproc default_to_jtag { f args } {\n\tset current_transport [transport select]\n\tif {[using_jtag]} {\n\t\teval $f $args\n\t} {\n\t\terror \"session transport is \\\"$current_transport\\\" but your config requires JTAG\"\n\t}\n}\n\nproc jtag args {\n\teval default_to_jtag jtag $args\n}\n\nproc jtag_rclk args {\n\teval default_to_jtag jtag_rclk $args\n}\n\nproc jtag_ntrst_delay args {\n\teval default_to_jtag jtag_ntrst_delay $args\n}\n\nproc jtag_ntrst_assert_width args {\n\teval default_to_jtag jtag_ntrst_assert_width $args\n}\n\n# BEGIN MIGRATION AIDS ...  these adapter operations originally had\n# JTAG-specific names despite the fact that the operations were not\n# specific to JTAG, or otherwise had troublesome/misleading names.\n#\n# FIXME phase these aids out after some releases\n#\nlappend _telnet_autocomplete_skip adapter_gpio_helper_with_caller\n# Helper for deprecated driver functions that should call \"adapter gpio XXX\".\n\n# Call this function as:\n#               adapter_gpio_helper_with_caller caller sig_name\n#               adapter_gpio_helper_with_caller caller sig_name gpio_num\n#               adapter_gpio_helper_with_caller caller sig_name chip_num gpio_num\nproc adapter_gpio_helper_with_caller {caller sig_name args} {\n\techo \"DEPRECATED! use 'adapter gpio $sig_name' not '$caller'\"\n\tswitch [llength $args] {\n\t\t0 {}\n\t\t1 {eval adapter gpio $sig_name $args}\n\t\t2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]}\n\t\tdefault {return -code 1 -level 1 \"$caller: syntax error\"}\n\t}\n\teval adapter gpio $sig_name\n}\n\nlappend _telnet_autocomplete_skip adapter_gpio_helper\n# Call this function as:\n#               adapter_gpio_helper sig_name\n#               adapter_gpio_helper sig_name gpio_num\n#               adapter_gpio_helper sig_name chip_num gpio_num\nproc adapter_gpio_helper {sig_name args} {\n\tset caller [lindex [info level -1] 0]\n\teval adapter_gpio_helper_with_caller {\"$caller\"} $sig_name $args\n}\n\nlappend _telnet_autocomplete_skip adapter_gpio_jtag_nums_with_caller\n# Helper for deprecated driver functions that implemented jtag_nums\nproc adapter_gpio_jtag_nums_with_caller {caller tck_num tms_num tdi_num tdo_num} {\n\techo \"DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not '$caller'\"\n\teval adapter gpio tck $tck_num\n\teval adapter gpio tms $tms_num\n\teval adapter gpio tdi $tdi_num\n\teval adapter gpio tdo $tdo_num\n}\n\nlappend _telnet_autocomplete_skip adapter_gpio_jtag_nums\n# Helper for deprecated driver functions that implemented jtag_nums\nproc adapter_gpio_jtag_nums {args} {\n\tset caller [lindex [info level -1] 0]\n\teval adapter_gpio_jtag_nums_with_caller {\"$caller\"} $args\n}\n\nlappend _telnet_autocomplete_skip adapter_gpio_swd_nums_with_caller\n# Helper for deprecated driver functions that implemented swd_nums\nproc adapter_gpio_swd_nums_with_caller {caller swclk_num swdio_num} {\n\techo \"DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not '$caller'\"\n\teval adapter gpio swclk $swclk_num\n\teval adapter gpio swdio $swdio_num\n}\n\nlappend _telnet_autocomplete_skip adapter_gpio_swd_nums\n# Helper for deprecated driver functions that implemented jtag_nums\nproc adapter_gpio_swd_nums {args} {\n\tset caller [lindex [info level -1] 0]\n\teval adapter_gpio_swd_nums_with_caller {\"$caller\"} $args\n}\n\nlappend _telnet_autocomplete_skip jtag_reset\nproc jtag_reset args {\n\techo \"DEPRECATED! use 'adapter \\[de\\]assert' not 'jtag_reset'\"\n\tswitch $args {\n\t\t\"0 0\"\n\t\t\t{eval adapter deassert trst deassert srst}\n\t\t\"0 1\"\n\t\t\t{eval adapter deassert trst assert srst}\n\t\t\"1 0\"\n\t\t\t{eval adapter assert trst deassert srst}\n\t\t\"1 1\"\n\t\t\t{eval adapter assert trst assert srst}\n\t\tdefault\n\t\t\t{return -code 1 -level 1 \"jtag_reset: syntax error\"}\n\t}\n}\n\nlappend _telnet_autocomplete_skip adapter_khz\nproc adapter_khz args {\n\techo \"DEPRECATED! use 'adapter speed' not 'adapter_khz'\"\n\teval adapter speed $args\n}\n\nlappend _telnet_autocomplete_skip adapter_name\nproc adapter_name args {\n\techo \"DEPRECATED! use 'adapter name' not 'adapter_name'\"\n\teval adapter name $args\n}\n\nlappend _telnet_autocomplete_skip adapter_nsrst_delay\nproc adapter_nsrst_delay args {\n\techo \"DEPRECATED! use 'adapter srst delay' not 'adapter_nsrst_delay'\"\n\teval adapter srst delay $args\n}\n\nlappend _telnet_autocomplete_skip adapter_nsrst_assert_width\nproc adapter_nsrst_assert_width args {\n\techo \"DEPRECATED! use 'adapter srst pulse_width' not 'adapter_nsrst_assert_width'\"\n\teval adapter srst pulse_width $args\n}\n\nlappend _telnet_autocomplete_skip interface\nproc interface args {\n\techo \"DEPRECATED! use 'adapter driver' not 'interface'\"\n\teval adapter driver $args\n}\n\nlappend _telnet_autocomplete_skip interface_transports\nproc  interface_transports args {\n\techo \"DEPRECATED! use 'adapter transports' not 'interface_transports'\"\n\teval adapter transports $args\n}\n\nlappend _telnet_autocomplete_skip interface_list\nproc  interface_list args {\n\techo \"DEPRECATED! use 'adapter list' not 'interface_list'\"\n\teval adapter list $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_location\nproc ftdi_location args {\n\techo \"DEPRECATED! use 'adapter usb location' not 'ftdi_location'\"\n\teval adapter usb location $args\n}\n\nlappend _telnet_autocomplete_skip xds110_serial\nproc xds110_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'xds110_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip xds110_supply_voltage\nproc xds110_supply_voltage args {\n\techo \"DEPRECATED! use 'xds110 supply' not 'xds110_supply_voltage'\"\n\teval xds110 supply $args\n}\n\nproc hla {cmd args} {\n        tailcall \"hla $cmd\" {*}$args\n}\n\nlappend _telnet_autocomplete_skip \"hla newtap\"\nproc \"hla newtap\" {args} {\n\techo \"DEPRECATED! use 'swj_newdap' not 'hla newtap'\"\n\teval swj_newdap $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_device_desc\nproc ftdi_device_desc args {\n\techo \"DEPRECATED! use 'ftdi device_desc' not 'ftdi_device_desc'\"\n\teval ftdi device_desc $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_serial\nproc ftdi_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'ftdi_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_channel\nproc ftdi_channel args {\n\techo \"DEPRECATED! use 'ftdi channel' not 'ftdi_channel'\"\n\teval ftdi channel $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_layout_init\nproc ftdi_layout_init args {\n\techo \"DEPRECATED! use 'ftdi layout_init' not 'ftdi_layout_init'\"\n\teval ftdi layout_init $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_layout_signal\nproc ftdi_layout_signal args {\n\techo \"DEPRECATED! use 'ftdi layout_signal' not 'ftdi_layout_signal'\"\n\teval ftdi layout_signal $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_set_signal\nproc ftdi_set_signal args {\n\techo \"DEPRECATED! use 'ftdi set_signal' not 'ftdi_set_signal'\"\n\teval ftdi set_signal $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_get_signal\nproc ftdi_get_signal args {\n\techo \"DEPRECATED! use 'ftdi get_signal' not 'ftdi_get_signal'\"\n\teval ftdi get_signal $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_vid_pid\nproc ftdi_vid_pid args {\n\techo \"DEPRECATED! use 'ftdi vid_pid' not 'ftdi_vid_pid'\"\n\teval ftdi vid_pid $args\n}\n\nlappend _telnet_autocomplete_skip ftdi_tdo_sample_edge\nproc ftdi_tdo_sample_edge args {\n\techo \"DEPRECATED! use 'ftdi tdo_sample_edge' not 'ftdi_tdo_sample_edge'\"\n\teval ftdi tdo_sample_edge $args\n}\n\nlappend _telnet_autocomplete_skip remote_bitbang_host\nproc remote_bitbang_host args {\n\techo \"DEPRECATED! use 'remote_bitbang host' not 'remote_bitbang_host'\"\n\teval remote_bitbang host $args\n}\n\nlappend _telnet_autocomplete_skip remote_bitbang_port\nproc remote_bitbang_port args {\n\techo \"DEPRECATED! use 'remote_bitbang port' not 'remote_bitbang_port'\"\n\teval remote_bitbang port $args\n}\n\nlappend _telnet_autocomplete_skip openjtag_device_desc\nproc openjtag_device_desc args {\n\techo \"DEPRECATED! use 'openjtag device_desc' not 'openjtag_device_desc'\"\n\teval openjtag device_desc $args\n}\n\nlappend _telnet_autocomplete_skip openjtag_variant\nproc openjtag_variant args {\n\techo \"DEPRECATED! use 'openjtag variant' not 'openjtag_variant'\"\n\teval openjtag variant $args\n}\n\nlappend _telnet_autocomplete_skip parport_port\nproc parport_port args {\n\techo \"DEPRECATED! use 'parport port' not 'parport_port'\"\n\teval parport port $args\n}\n\nlappend _telnet_autocomplete_skip parport_cable\nproc parport_cable args {\n\techo \"DEPRECATED! use 'parport cable' not 'parport_cable'\"\n\teval parport cable $args\n}\n\nlappend _telnet_autocomplete_skip parport_write_on_exit\nproc parport_write_on_exit args {\n\techo \"DEPRECATED! use 'parport write_on_exit' not 'parport_write_on_exit'\"\n\teval parport write_on_exit $args\n}\n\nlappend _telnet_autocomplete_skip parport_toggling_time\nproc parport_toggling_time args {\n\techo \"DEPRECATED! use 'parport toggling_time' not 'parport_toggling_time'\"\n\teval parport toggling_time $args\n}\n\nlappend _telnet_autocomplete_skip jtag_dpi_set_port\nproc jtag_dpi_set_port args {\n\techo \"DEPRECATED! use 'jtag_dpi set_port' not 'jtag_dpi_set_port'\"\n\teval jtag_dpi set_port $args\n}\n\nlappend _telnet_autocomplete_skip jtag_dpi_set_address\nproc jtag_dpi_set_address args {\n\techo \"DEPRECATED! use 'jtag_dpi set_address' not 'jtag_dpi_set_address'\"\n\teval jtag_dpi set_address $args\n}\n\nlappend _telnet_autocomplete_skip jtag_vpi_set_port\nproc jtag_vpi_set_port args {\n\techo \"DEPRECATED! use 'jtag_vpi set_port' not 'jtag_vpi_set_port'\"\n\teval jtag_vpi set_port $args\n}\n\nlappend _telnet_autocomplete_skip jtag_vpi_set_address\nproc jtag_vpi_set_address args {\n\techo \"DEPRECATED! use 'jtag_vpi set_address' not 'jtag_vpi_set_address'\"\n\teval jtag_vpi set_address $args\n}\n\nlappend _telnet_autocomplete_skip jtag_vpi_stop_sim_on_exit\nproc jtag_vpi_stop_sim_on_exit args {\n\techo \"DEPRECATED! use 'jtag_vpi stop_sim_on_exit' not 'jtag_vpi_stop_sim_on_exit'\"\n\teval jtag_vpi stop_sim_on_exit $args\n}\n\nlappend _telnet_autocomplete_skip presto_serial\nproc presto_serial args {\n\techo \"DEPRECATED! use 'presto serial' not 'presto_serial'\"\n\teval presto serial $args\n}\n\nlappend _telnet_autocomplete_skip xlnx_pcie_xvc_config\nproc xlnx_pcie_xvc_config args {\n\techo \"DEPRECATED! use 'xlnx_pcie_xvc config' not 'xlnx_pcie_xvc_config'\"\n\teval xlnx_pcie_xvc config $args\n}\n\nlappend _telnet_autocomplete_skip ulink_download_firmware\nproc ulink_download_firmware args {\n\techo \"DEPRECATED! use 'ulink download_firmware' not 'ulink_download_firmware'\"\n\teval ulink download_firmware $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_vid\nproc vsllink_usb_vid args {\n\techo \"DEPRECATED! use 'vsllink usb_vid' not 'vsllink_usb_vid'\"\n\teval vsllink usb_vid $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_pid\nproc vsllink_usb_pid args {\n\techo \"DEPRECATED! use 'vsllink usb_pid' not 'vsllink_usb_pid'\"\n\teval vsllink usb_pid $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_serial\nproc vsllink_usb_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'vsllink_usb_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_bulkin\nproc vsllink_usb_bulkin args {\n\techo \"DEPRECATED! use 'vsllink usb_bulkin' not 'vsllink_usb_bulkin'\"\n\teval vsllink usb_bulkin $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_bulkout\nproc vsllink_usb_bulkout args {\n\techo \"DEPRECATED! use 'vsllink usb_bulkout' not 'vsllink_usb_bulkout'\"\n\teval vsllink usb_bulkout $args\n}\n\nlappend _telnet_autocomplete_skip vsllink_usb_interface\nproc vsllink_usb_interface args {\n\techo \"DEPRECATED! use 'vsllink usb_interface' not 'vsllink_usb_interface'\"\n\teval vsllink usb_interface $args\n}\n\n\nlappend _telnet_autocomplete_skip bcm2835_gpio_helper\nproc bcm2835_gpio_helper {sig_name args} {\n\tset caller [lindex [info level -1] 0]\n\techo \"DEPRECATED! use 'adapter gpio $sig_name' not '$caller'\"\n\tswitch [llength $args] {\n\t\t0 {}\n\t\t1 {eval adapter gpio $sig_name $args -chip 0}\n\t\t2 {eval adapter gpio $sig_name [lindex $args 1] -chip [lindex $args 0]}\n\t\tdefault {return -code 1 -level 1 \"$caller: syntax error\"}\n\t}\n\teval adapter gpio $sig_name\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_jtag_nums\nproc bcm2835gpio_jtag_nums {tck_num tms_num tdi_num tdo_num} {\n\techo \"DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio_jtag_nums'\"\n\teval adapter gpio tck $tck_num -chip 0\n\teval adapter gpio tms $tms_num -chip 0\n\teval adapter gpio tdi $tdi_num -chip 0\n\teval adapter gpio tdo $tdo_num -chip 0\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_tck_num\nproc bcm2835gpio_tck_num args {\n\teval bcm2835_gpio_helper tck $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_tms_num\nproc bcm2835gpio_tms_num args {\n\teval bcm2835_gpio_helper tms $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_tdo_num\nproc bcm2835gpio_tdo_num args {\n\teval bcm2835_gpio_helper tdo $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_tdi_num\nproc bcm2835gpio_tdi_num args {\n\teval bcm2835_gpio_helper tdi $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_swd_nums\nproc bcm2835gpio_swd_nums {swclk_num swdio_num} {\n\techo \"DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio_swd_nums'\"\n\teval adapter gpio swclk $swclk_num -chip 0\n\teval adapter gpio swdio $swdio_num -chip 0\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_swclk_num\nproc bcm2835gpio_swclk_num args {\n\teval bcm2835_gpio_helper swclk $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_swdio_num\nproc bcm2835gpio_swdio_num args {\n\teval bcm2835_gpio_helper swdio $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_swdio_dir_num\nproc bcm2835gpio_swdio_dir_num args {\n\teval bcm2835_gpio_helper swdio_dir $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_srst_num\nproc bcm2835gpio_srst_num args {\n\teval bcm2835_gpio_helper srst $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_trst_num\nproc bcm2835gpio_trst_num args {\n\teval bcm2835_gpio_helper trst $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio jtag_nums\"\nproc \"bcm2835gpio jtag_nums\" {tck_num tms_num tdi_num tdo_num} {\n\techo \"DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'bcm2835gpio jtag_nums'\"\n\teval adapter gpio tck $tck_num -chip 0\n\teval adapter gpio tms $tms_num -chip 0\n\teval adapter gpio tdi $tdi_num -chip 0\n\teval adapter gpio tdo $tdo_num -chip 0\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio tck_num\"\nproc \"bcm2835gpio tck_num\" args {\n\teval bcm2835_gpio_helper tck $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio tms_num\"\nproc \"bcm2835gpio tms_num\" args {\n\teval bcm2835_gpio_helper tms $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio tdo_num\"\nproc \"bcm2835gpio tdo_num\" args {\n\teval bcm2835_gpio_helper tdo $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio tdi_num\"\nproc \"bcm2835gpio tdi_num\" args {\n\teval bcm2835_gpio_helper tdi $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio swd_nums\"\nproc \"bcm2835gpio swd_nums\" {swclk_num swdio_num} {\n\techo \"DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'bcm2835gpio swd_nums'\"\n\teval adapter gpio swclk $swclk_num -chip 0\n\teval adapter gpio swdio $swdio_num -chip 0\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio swclk_num\"\nproc \"bcm2835gpio swclk_num\" args {\n\teval bcm2835_gpio_helper swclk $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio swdio_num\"\nproc \"bcm2835gpio swdio_num\" args {\n\teval bcm2835_gpio_helper swdio $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio swdio_dir_num\"\nproc \"bcm2835gpio swdio_dir_num\" args {\n\teval bcm2835_gpio_helper swdio_dir $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio srst_num\"\nproc \"bcm2835gpio srst_num\" args {\n\teval bcm2835_gpio_helper srst $args\n}\n\nlappend _telnet_autocomplete_skip \"bcm2835gpio trst_num\"\nproc \"bcm2835gpio trst_num\" args {\n\teval bcm2835_gpio_helper trst $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_speed_coeffs\nproc bcm2835gpio_speed_coeffs args {\n\techo \"DEPRECATED! use 'bcm2835gpio speed_coeffs' not 'bcm2835gpio_speed_coeffs'\"\n\teval bcm2835gpio speed_coeffs $args\n}\n\nlappend _telnet_autocomplete_skip bcm2835gpio_peripheral_base\nproc bcm2835gpio_peripheral_base args {\n\techo \"DEPRECATED! use 'bcm2835gpio peripheral_base' not 'bcm2835gpio_peripheral_base'\"\n\teval bcm2835gpio peripheral_base $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_jtag_nums\nproc linuxgpiod_jtag_nums args {\n\teval adapter_gpio_jtag_nums $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_tck_num\nproc linuxgpiod_tck_num args {\n\teval adapter_gpio_helper tck $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_tms_num\nproc linuxgpiod_tms_num args {\n\teval adapter_gpio_helper tms $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_tdo_num\nproc linuxgpiod_tdo_num args {\n\teval adapter_gpio_helper tdo $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_tdi_num\nproc linuxgpiod_tdi_num args {\n\teval adapter_gpio_helper tdi $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_srst_num\nproc linuxgpiod_srst_num args {\n\teval adapter_gpio_helper srst $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_trst_num\nproc linuxgpiod_trst_num args {\n\teval adapter_gpio_helper trst $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_swd_nums\nproc linuxgpiod_swd_nums args {\n\teval adapter_gpio_swd_nums $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_swclk_num\nproc linuxgpiod_swclk_num args {\n\teval adapter_gpio_helper swclk $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_swdio_num\nproc linuxgpiod_swdio_num args {\n\teval adapter_gpio_helper swdio $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_led_num\nproc linuxgpiod_led_num args {\n\teval adapter_gpio_helper led $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod_gpiochip\nproc linuxgpiod_gpiochip args {\n\techo \"DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod_gpiochip'\"\n\tswitch [llength $args] {\n\t\t0 { }\n\t\t1 {\n\t\t\tforeach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {\n\t\t\t\teval adapter gpio $sig_name -chip $args\n\t\t\t}\n\t\t}\n\t\tdefault {return -code 1 -level 1 \"linuxgpiod_gpiochip: syntax error\"}\n\t}\n\teval adapter gpio\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_jtag_nums\nproc sysfsgpio_jtag_nums args {\n\techo \"DEPRECATED! use 'sysfsgpio jtag_nums' not 'sysfsgpio_jtag_nums'\"\n\teval sysfsgpio jtag_nums $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_tck_num\nproc sysfsgpio_tck_num args {\n\techo \"DEPRECATED! use 'sysfsgpio tck_num' not 'sysfsgpio_tck_num'\"\n\teval sysfsgpio tck_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_tms_num\nproc sysfsgpio_tms_num args {\n\techo \"DEPRECATED! use 'sysfsgpio tms_num' not 'sysfsgpio_tms_num'\"\n\teval sysfsgpio tms_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_tdo_num\nproc sysfsgpio_tdo_num args {\n\techo \"DEPRECATED! use 'sysfsgpio tdo_num' not 'sysfsgpio_tdo_num'\"\n\teval sysfsgpio tdo_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_tdi_num\nproc sysfsgpio_tdi_num args {\n\techo \"DEPRECATED! use 'sysfsgpio tdi_num' not 'sysfsgpio_tdi_num'\"\n\teval sysfsgpio tdi_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_srst_num\nproc sysfsgpio_srst_num args {\n\techo \"DEPRECATED! use 'sysfsgpio srst_num' not 'sysfsgpio_srst_num'\"\n\teval sysfsgpio srst_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_trst_num\nproc sysfsgpio_trst_num args {\n\techo \"DEPRECATED! use 'sysfsgpio trst_num' not 'sysfsgpio_trst_num'\"\n\teval sysfsgpio trst_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_swd_nums\nproc sysfsgpio_swd_nums args {\n\techo \"DEPRECATED! use 'sysfsgpio swd_nums' not 'sysfsgpio_swd_nums'\"\n\teval sysfsgpio swd_nums $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_swclk_num\nproc sysfsgpio_swclk_num args {\n\techo \"DEPRECATED! use 'sysfsgpio swclk_num' not 'sysfsgpio_swclk_num'\"\n\teval sysfsgpio swclk_num $args\n}\n\nlappend _telnet_autocomplete_skip sysfsgpio_swdio_num\nproc sysfsgpio_swdio_num args {\n\techo \"DEPRECATED! use 'sysfsgpio swdio_num' not 'sysfsgpio_swdio_num'\"\n\teval sysfsgpio swdio_num $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_adc\nproc buspirate_adc args {\n\techo \"DEPRECATED! use 'buspirate adc' not 'buspirate_adc'\"\n\teval buspirate adc $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_vreg\nproc buspirate_vreg args {\n\techo \"DEPRECATED! use 'buspirate vreg' not 'buspirate_vreg'\"\n\teval buspirate vreg $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_pullup\nproc buspirate_pullup args {\n\techo \"DEPRECATED! use 'buspirate pullup' not 'buspirate_pullup'\"\n\teval buspirate pullup $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_led\nproc buspirate_led args {\n\techo \"DEPRECATED! use 'buspirate led' not 'buspirate_led'\"\n\teval buspirate led $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_speed\nproc buspirate_speed args {\n\techo \"DEPRECATED! use 'buspirate speed' not 'buspirate_speed'\"\n\teval buspirate speed $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_mode\nproc buspirate_mode args {\n\techo \"DEPRECATED! use 'buspirate mode' not 'buspirate_mode'\"\n\teval buspirate mode $args\n}\n\nlappend _telnet_autocomplete_skip buspirate_port\nproc buspirate_port args {\n\techo \"DEPRECATED! use 'buspirate port' not 'buspirate_port'\"\n\teval buspirate port $args\n}\n\nlappend _telnet_autocomplete_skip usb_blaster_device_desc\nproc usb_blaster_device_desc args {\n\techo \"DEPRECATED! use 'usb_blaster device_desc' not 'usb_blaster_device_desc'\"\n\teval usb_blaster device_desc $args\n}\n\nlappend _telnet_autocomplete_skip usb_blaster_vid_pid\nproc usb_blaster_vid_pid args {\n\techo \"DEPRECATED! use 'usb_blaster vid_pid' not 'usb_blaster_vid_pid'\"\n\teval usb_blaster vid_pid $args\n}\n\nlappend _telnet_autocomplete_skip usb_blaster_lowlevel_driver\nproc usb_blaster_lowlevel_driver args {\n\techo \"DEPRECATED! use 'usb_blaster lowlevel_driver' not 'usb_blaster_lowlevel_driver'\"\n\teval usb_blaster lowlevel_driver $args\n}\n\nlappend _telnet_autocomplete_skip usb_blaster_pin\nproc usb_blaster_pin args {\n\techo \"DEPRECATED! use 'usb_blaster pin' not 'usb_blaster_pin'\"\n\teval usb_blaster pin $args\n}\n\nlappend _telnet_autocomplete_skip usb_blaster_firmware\nproc usb_blaster_firmware args {\n\techo \"DEPRECATED! use 'usb_blaster firmware' not 'usb_blaster_firmware'\"\n\teval usb_blaster firmware $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_serial_desc\nproc ft232r_serial_desc args {\n\techo \"DEPRECATED! use 'adapter serial_desc' not 'ft232r_serial_desc'\"\n\teval adapter serial_desc $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_vid_pid\nproc ft232r_vid_pid args {\n\techo \"DEPRECATED! use 'ft232r vid_pid' not 'ft232r_vid_pid'\"\n\teval ft232r vid_pid $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_jtag_nums\nproc ft232r_jtag_nums args {\n\techo \"DEPRECATED! use 'ft232r jtag_nums' not 'ft232r_jtag_nums'\"\n\teval ft232r jtag_nums $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_tck_num\nproc ft232r_tck_num args {\n\techo \"DEPRECATED! use 'ft232r tck_num' not 'ft232r_tck_num'\"\n\teval ft232r tck_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_tms_num\nproc ft232r_tms_num args {\n\techo \"DEPRECATED! use 'ft232r tms_num' not 'ft232r_tms_num'\"\n\teval ft232r tms_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_tdo_num\nproc ft232r_tdo_num args {\n\techo \"DEPRECATED! use 'ft232r tdo_num' not 'ft232r_tdo_num'\"\n\teval ft232r tdo_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_tdi_num\nproc ft232r_tdi_num args {\n\techo \"DEPRECATED! use 'ft232r tdi_num' not 'ft232r_tdi_num'\"\n\teval ft232r tdi_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_srst_num\nproc ft232r_srst_num args {\n\techo \"DEPRECATED! use 'ft232r srst_num' not 'ft232r_srst_num'\"\n\teval ft232r srst_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_trst_num\nproc ft232r_trst_num args {\n\techo \"DEPRECATED! use 'ft232r trst_num' not 'ft232r_trst_num'\"\n\teval ft232r trst_num $args\n}\n\nlappend _telnet_autocomplete_skip ft232r_restore_serial\nproc ft232r_restore_serial args {\n\techo \"DEPRECATED! use 'ft232r restore_serial' not 'ft232r_restore_serial'\"\n\teval ft232r restore_serial $args\n}\n\nlappend _telnet_autocomplete_skip cmsis_dap_serial\nproc cmsis_dap_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'cmsis_dap_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"ft232r serial_desc\"\nproc \"ft232r serial_desc\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'ft232r serial_desc'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"ftdi serial\"\nproc \"ftdi serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'ftdi serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip hla_serial\nproc hla_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'hla_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"jlink serial\"\nproc \"jlink serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'jlink serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip kitprog_serial\nproc kitprog_serial args {\n\techo \"DEPRECATED! use 'adapter serial' not 'kitprog_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"presto serial\"\nproc \"presto serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'presto serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"st-link serial\"\nproc \"st-link serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'st-link serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"vsllink usb_serial\"\nproc \"vsllink usb_serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'vsllink usb_serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip \"xds110 serial\"\nproc \"xds110 serial\" {args} {\n\techo \"DEPRECATED! use 'adapter serial' not 'xds110 serial'\"\n\teval adapter serial $args\n}\n\nlappend _telnet_autocomplete_skip linuxgpiod\n# linuxgpiod command completely removed, this is required for the sub-commands to work\nproc linuxgpiod {subcommand args} {\n\teval {\"linuxgpiod $subcommand\"} $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod tck_num\"\nproc \"linuxgpiod tck_num\" {args} {\n\teval adapter_gpio_helper tck $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod tms_num\"\nproc \"linuxgpiod tms_num\" {args} {\n\teval adapter_gpio_helper tms $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod tdi_num\"\nproc \"linuxgpiod tdi_num\" {args} {\n\teval adapter_gpio_helper tdi $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod tdo_num\"\nproc \"linuxgpiod tdo_num\" {args} {\n\teval adapter_gpio_helper tdo $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod trst_num\"\nproc \"linuxgpiod trst_num\" {args} {\n\teval adapter_gpio_helper trst $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod srst_num\"\nproc \"linuxgpiod srst_num\" {args} {\n\teval adapter_gpio_helper srst $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod swclk_num\"\nproc \"linuxgpiod swclk_num\" {args} {\n\teval adapter_gpio_helper swclk $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod swdio_num\"\nproc \"linuxgpiod swdio_num\" {args} {\n\teval adapter_gpio_helper swdio $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod swdio_dir_num\"\nproc \"linuxgpiod swdio_dir_num\" {args} {\n\teval adapter_gpio_helper swdio_dir $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod led_num\"\nproc \"linuxgpiod led_num\" {args} {\n\teval adapter_gpio_helper led $args\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod gpiochip\"\nproc \"linuxgpiod gpiochip\" {num} {\n\techo \"DEPRECATED! use 'adapter <signal_name> -chip' not 'linuxgpiod gpiochip'\"\n\tforeach sig_name {tck tms tdi tdo trst srst swclk swdio swdio_dir led} {\n\t\teval adapter gpio $sig_name -chip $num\n\t}\n\teval adapter gpio\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod jtag_nums\"\nproc \"linuxgpiod jtag_nums\" {tck_num tms_num tdi_num tdo_num} {\n\techo \"DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'linuxgpiod jtag_nums'\"\n\teval adapter gpio tck $tck_num\n\teval adapter gpio tms $tms_num\n\teval adapter gpio tdi $tdi_num\n\teval adapter gpio tdo $tdo_num\n}\n\nlappend _telnet_autocomplete_skip \"linuxgpiod swd_nums\"\nproc \"linuxgpiod swd_nums\" {swclk swdio} {\n\techo \"DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'linuxgpiod jtag_nums'\"\n\teval adapter gpio swclk $swclk\n\teval adapter gpio swdio $swdio\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio jtag_nums\"\nproc \"am335xgpio jtag_nums\" {tck_num tms_num tdi_num tdo_num} {\n\techo \"DEPRECATED! use 'adapter gpio tck; adapter gpio tms; adapter gpio tdi; adapter gpio tdo' not 'am335xgpio jtag_nums'\"\n\teval adapter gpio tck [expr {$tck_num % 32}] -chip [expr {$tck_num / 32}]\n\teval adapter gpio tms [expr {$tms_num % 32}] -chip [expr {$tms_num / 32}]\n\teval adapter gpio tdi [expr {$tdi_num % 32}] -chip [expr {$tdi_num / 32}]\n\teval adapter gpio tdo [expr {$tdo_num % 32}] -chip [expr {$tdo_num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio tck_num\"\nproc \"am335xgpio tck_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio tck' not 'am335xgpio tck_num'\"\n\teval adapter gpio tck [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio tms_num\"\nproc \"am335xgpio tms_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio tms' not 'am335xgpio tms_num'\"\n\teval adapter gpio tms [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio tdi_num\"\nproc \"am335xgpio tdi_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio tdi' not 'am335xgpio tdi_num'\"\n\teval adapter gpio tdi [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio tdo_num\"\nproc \"am335xgpio tdo_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio tdo' not 'am335xgpio tdo_num'\"\n\teval adapter gpio tdo [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio swd_nums\"\nproc \"am335xgpio swd_nums\" {swclk swdio} {\n\techo \"DEPRECATED! use 'adapter gpio swclk; adapter gpio swdio' not 'am335xgpio jtag_nums'\"\n\teval adapter gpio swclk [expr {$swclk % 32}] -chip [expr {$swclk / 32}]\n\teval adapter gpio swdio [expr {$swdio % 32}] -chip [expr {$swdio / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio swclk_num\"\nproc \"am335xgpio swclk_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio swclk' not 'am335xgpio swclk_num'\"\n\teval adapter gpio swclk [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio swdio_num\"\nproc \"am335xgpio swdio_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio swdio' not 'am335xgpio swdio_num'\"\n\teval adapter gpio swdio [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio swdio_dir_num\"\nproc \"am335xgpio swdio_dir_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio swdio_dir' not 'am335xgpio swdio_dir_num'\"\n\teval adapter gpio swdio_dir [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio swdio_dir_output_state\"\nproc \"am335xgpio swdio_dir_output_state\" {state} {\n\techo \"DEPRECATED! use 'adapter gpio swdio_dir -active-high' or 'adapter gpio swdio_dir -active-low', not 'am335xgpio swdio_dir_output_state'\"\n\tswitch $state {\n\t\t\"high\"\n\t\t\t{eval adapter gpio swdio_dir -active-high}\n\t\t\"low\"\n\t\t\t{eval adapter gpio swdio_dir -active-low}\n\t\tdefault\n\t\t\t{return -code 1 -level 1 \"am335xgpio swdio_dir_output_state: syntax error\"}\n\t}\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio srst_num\"\nproc \"am335xgpio srst_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio srst' not 'am335xgpio srst_num'\"\n\teval adapter gpio srst [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio trst_num\"\nproc \"am335xgpio trst_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio trst' not 'am335xgpio trst_num'\"\n\teval adapter gpio trst [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio led_num\"\nproc \"am335xgpio led_num\" {num} {\n\techo \"DEPRECATED! use 'adapter gpio led' not 'am335xgpio led_num'\"\n\teval adapter gpio led [expr {$num % 32}] -chip [expr {$num / 32}]\n}\n\nlappend _telnet_autocomplete_skip \"am335xgpio led_on_state\"\nproc \"am335xgpio led_on_state\" {state} {\n\techo \"DEPRECATED! use 'adapter gpio led -active-high' or 'adapter gpio led -active-low', not 'am335xgpio led_on_state'\"\n\tswitch $state {\n\t\t\"high\"\n\t\t\t{eval adapter gpio led -active-high}\n\t\t\"low\"\n\t\t\t{eval adapter gpio led -active-low}\n\t\tdefault\n\t\t\t{return -code 1 -level 1 \"am335xgpio led_on_state: syntax error\"}\n\t}\n}\n\nlappend _telnet_autocomplete_skip \"pld device\"\nproc \"pld device\" {driver tap_name {opt 0}} {\n\techo \"DEPRECATED! use 'pld create ...', not 'pld device ...'\"\n\tif {[string is integer -strict $opt]} {\n\t\tif {$opt == 0} {\n\t\t\teval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name\n\t\t} else {\n\t\t\teval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name -no_jstart\n\t\t}\n\t} else {\n\t\teval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name -family $opt\n\t}\n}\n\n# END MIGRATION AIDS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/swd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009-2010 by David Brownell                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_SWD_H\n#define OPENOCD_JTAG_SWD_H\n\n#include <helper/log.h>\n#include <target/arm_adi_v5.h>\n\n/* Bits in SWD command packets, written from host to target\n * first bit on the wire is START\n */\n#define SWD_CMD_START\t(1 << 0)\t/* always set */\n#define SWD_CMD_APNDP\t(1 << 1)\t/* set only for AP access */\n#define SWD_CMD_RNW\t(1 << 2)\t\t/* set only for read access */\n#define SWD_CMD_A32\t(3 << 3)\t\t/* bits A[3:2] of register addr */\n#define SWD_CMD_PARITY\t(1 << 5)\t/* parity of APnDP|RnW|A32 */\n#define SWD_CMD_STOP\t(0 << 6)\t/* always clear for synch SWD */\n#define SWD_CMD_PARK\t(1 << 7)\t/* driven high by host */\n/* followed by TRN, 3-bits of ACK, TRN */\n\n/*\n * The SWD subsystem error codes\n */\n#define ERROR_SWD_FAIL\t(-400)\t/** protocol or parity error */\n#define ERROR_SWD_FAULT\t(-401)\t/** device returned FAULT in ACK field */\n\n/**\n * Construct a \"cmd\" byte, in lSB bit order, which swd_driver.read_reg()\n * and swd_driver.write_reg() methods will use directly.\n */\nstatic inline uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)\n{\n\tuint8_t cmd = (is_ap ? SWD_CMD_APNDP : 0)\n\t\t| (is_read ? SWD_CMD_RNW : 0)\n\t\t| ((regnum & 0xc) << 1);\n\n\t/* 8 cmd bits 4:1 may be set */\n\tif (parity_u32(cmd))\n\t\tcmd |= SWD_CMD_PARITY;\n\n\t/* driver handles START, STOP, and TRN */\n\n\treturn cmd;\n}\n\n/* SWD_ACK_* bits are defined in <target/arm_adi_v5.h> */\n\n/**\n * Test if we can rely on ACK returned by SWD command\n *\n * @param cmd Byte constructed by swd_cmd(), START, STOP and TRN are filtered off\n * @returns true if ACK should be checked, false if should be ignored\n */\nstatic inline bool swd_cmd_returns_ack(uint8_t cmd)\n{\n\tuint8_t base_cmd = cmd & (SWD_CMD_APNDP | SWD_CMD_RNW | SWD_CMD_A32);\n\n\t/* DPv2 does not reply to DP_TARGETSEL write cmd */\n\treturn base_cmd != swd_cmd(false, false, DP_TARGETSEL);\n}\n\n/**\n * Convert SWD ACK value returned from DP to OpenOCD error code\n *\n * @param ack\n * @returns error code\n */\nstatic inline int swd_ack_to_error_code(uint8_t ack)\n{\n\tswitch (ack) {\n\tcase SWD_ACK_OK:\n\t\treturn ERROR_OK;\n\tcase SWD_ACK_WAIT:\n\t\treturn ERROR_WAIT;\n\tcase SWD_ACK_FAULT:\n\t\treturn ERROR_SWD_FAULT;\n\tdefault:\n\t\treturn ERROR_SWD_FAIL;\n\t}\n}\n\n/*\n * The following sequences are updated to\n * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031E\n */\n\n/**\n * SWD Line reset.\n *\n * SWD Line reset is at least 50 SWCLK cycles with SWDIO driven high,\n * followed by at least two idle (low) cycle.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_line_reset[] = {\n\t/* At least 50 SWCLK cycles with SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t/* At least 2 idle (low) cycles */\n\t0x00,\n};\nstatic const unsigned swd_seq_line_reset_len = 64;\n\n/**\n * JTAG-to-SWD sequence.\n *\n * The JTAG-to-SWD sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO\n * high, putting either interface logic into reset state, followed by a\n * specific 16-bit sequence and finally a line reset in case the SWJ-DP was\n * already in SWD mode.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_jtag_to_swd[] = {\n\t/* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t/* Switching sequence from JTAG to SWD */\n\t0x9e, 0xe7,\n\t/* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t/* At least 2 idle (low) cycles */\n\t0x00,\n};\nstatic const unsigned swd_seq_jtag_to_swd_len = 136;\n\n/**\n * SWD-to-JTAG sequence.\n *\n * The SWD-to-JTAG sequence is at least 50 TCK/SWCLK cycles with TMS/SWDIO\n * high, putting either interface logic into reset state, followed by a\n * specific 16-bit sequence and finally at least 5 TCK/SWCLK cycles with\n * TMS/SWDIO high to put the JTAG TAP in Test-Logic-Reset state.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_swd_to_jtag[] = {\n\t/* At least 50 TCK/SWCLK cycles with TMS/SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t/* Switching sequence from SWD to JTAG */\n\t0x3c, 0xe7,\n\t/* At least 5 TCK/SWCLK cycles with TMS/SWDIO high */\n\t0xff,\n};\nstatic const unsigned swd_seq_swd_to_jtag_len = 80;\n\n/**\n * SWD-to-dormant sequence.\n *\n * This is at least 50 SWCLK cycles with SWDIO high to put the interface\n * in reset state, followed by a specific 16-bit sequence.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_swd_to_dormant[] = {\n\t/* At least 50 SWCLK cycles with SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t /* Switching sequence from SWD to dormant */\n\t0xbc, 0xe3,\n};\nstatic const unsigned swd_seq_swd_to_dormant_len = 72;\n\n/**\n * Dormant-to-SWD sequence.\n *\n * This is at least 8 TCK/SWCLK cycles with TMS/SWDIO high to abort any ongoing\n * selection alert sequence, followed by a specific 128-bit selection alert\n * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by\n * a specific protocol-dependent activation code. For SWD the activation code\n * is an 8-bit sequence. The sequence ends with a line reset.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_dormant_to_swd[] = {\n\t/* At least 8 SWCLK cycles with SWDIO high */\n\t0xff,\n\t/* Selection alert sequence */\n\t0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,\n\t0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,\n\t/*\n\t * 4 SWCLK cycles with SWDIO low ...\n\t * + SWD activation code 0x1a ...\n\t * + at least 8 SWCLK cycles with SWDIO high\n\t */\n\t0xa0, /* ((0x00)      & GENMASK(3, 0)) | ((0x1a << 4) & GENMASK(7, 4)) */\n\t0xf1, /* ((0x1a >> 4) & GENMASK(3, 0)) | ((0xff << 4) & GENMASK(7, 4)) */\n\t0xff,\n\t/* At least 50 SWCLK cycles with SWDIO high */\n\t0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t/* At least 2 idle (low) cycles */\n\t0x00,\n};\nstatic const unsigned swd_seq_dormant_to_swd_len = 224;\n\n/**\n * JTAG-to-dormant sequence.\n *\n * This is at least 5 TCK cycles with TMS high to put the interface\n * in test-logic-reset state, followed by a specific 31-bit sequence.\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_jtag_to_dormant[] = {\n\t/* At least 5 TCK cycles with TMS high */\n\t0xff,\n\t/*\n\t * Still one TCK cycle with TMS high followed by 31 bits JTAG-to-DS\n\t * select sequence 0xba, 0xbb, 0xbb, 0x33,\n\t */\n\t0x75, /* ((0xff >> 7) & GENMASK(0, 0)) | ((0xba << 1) & GENMASK(7, 1)) */\n\t0x77, /* ((0xba >> 7) & GENMASK(0, 0)) | ((0xbb << 1) & GENMASK(7, 1)) */\n\t0x77, /* ((0xbb >> 7) & GENMASK(0, 0)) | ((0xbb << 1) & GENMASK(7, 1)) */\n\t0x67, /* ((0xbb >> 7) & GENMASK(0, 0)) | ((0x33 << 1) & GENMASK(7, 1)) */\n};\nstatic const unsigned swd_seq_jtag_to_dormant_len = 40;\n\n/**\n * Dormant-to-JTAG sequence.\n *\n * This is at least 8 TCK/SWCLK cycles with TMS/SWDIO high to abort any ongoing\n * selection alert sequence, followed by a specific 128-bit selection alert\n * sequence, followed by 4 TCK/SWCLK cycles with TMS/SWDIO low, followed by\n * a specific protocol-dependent activation code. For JTAG there are two\n * possible activation codes:\n * - \"JTAG-Serial\": 12 bits 0x00, 0x00\n * - \"Arm CoreSight JTAG-DP\": 8 bits 0x0a\n * We use \"JTAG-Serial\" only, which seams more generic.\n * Since the target TAP can be either in Run/Test Idle or in Test-Logic-Reset\n * states, Arm recommends to put the TAP in Run/Test Idle using one TCK cycle\n * with TMS low. To keep the sequence length multiple of 8, 8 TCK cycle with\n * TMS low are sent (allowed by JTAG state machine).\n * Bits are stored (and transmitted) LSB-first.\n */\nstatic const uint8_t swd_seq_dormant_to_jtag[] = {\n\t/* At least 8 TCK/SWCLK cycles with TMS/SWDIO high */\n\t0xff,\n\t/* Selection alert sequence */\n\t0x92, 0xf3, 0x09, 0x62, 0x95, 0x2d, 0x85, 0x86,\n\t0xe9, 0xaf, 0xdd, 0xe3, 0xa2, 0x0e, 0xbc, 0x19,\n\t/*\n\t * 4 TCK/SWCLK cycles with TMS/SWDIO low ...\n\t * + 12 bits JTAG-serial activation code 0x00, 0x00\n\t */\n\t0x00, 0x00,\n\t/* put the TAP in Run/Test Idle */\n\t0x00,\n};\nstatic const unsigned swd_seq_dormant_to_jtag_len = 160;\n\nstruct swd_driver {\n\t/**\n\t * Initialize the debug link so it can perform SWD operations.\n\t *\n\t * As an example, this would switch a dual-mode debug adapter\n\t * into SWD mode and out of JTAG mode.\n\t *\n\t * @return ERROR_OK on success, else a negative fault code.\n\t */\n\tint (*init)(void);\n\n\t/**\n\t * Queue a special SWDIO sequence.\n\t *\n\t * @param seq The special sequence to generate.\n\t * @return ERROR_OK if the sequence was queued, negative error if the\n\t * sequence is unsupported.\n\t */\n\tint (*switch_seq)(enum swd_special_seq seq);\n\n\t/**\n\t * Queued read of an AP or DP register.\n\t *\n\t * @param Command byte with APnDP/RnW/addr/parity bits\n\t * @param Where to store value to read from register\n\t * @param ap_delay_hint Number of idle cycles that may be\n\t * needed after an AP access to avoid WAITs\n\t */\n\tvoid (*read_reg)(uint8_t cmd, uint32_t *value, uint32_t ap_delay_hint);\n\n\t/**\n\t * Queued write of an AP or DP register.\n\t *\n\t * @param Command byte with APnDP/RnW/addr/parity bits\n\t * @param Value to be written to the register\n\t * @param ap_delay_hint Number of idle cycles that may be\n\t * needed after an AP access to avoid WAITs\n\t */\n\tvoid (*write_reg)(uint8_t cmd, uint32_t value, uint32_t ap_delay_hint);\n\n\t/**\n\t * Execute any queued transactions and collect the result.\n\t *\n\t * @return ERROR_OK on success, Ack response code on WAIT/FAULT\n\t * or negative error code on other kinds of failure.\n\t */\n\tint (*run)(void);\n\n\t/**\n\t * Configures data collection from the Single-wire\n\t * trace (SWO) signal.\n\t * @param swo true if SWO data collection should be routed.\n\t *\n\t * For example,  some debug adapters include a UART which\n\t * is normally connected to a microcontroller's UART TX,\n\t * but which may instead be connected to SWO for use in\n\t * collecting ITM (and possibly ETM) trace data.\n\t *\n\t * @return ERROR_OK on success, else a negative fault code.\n\t */\n\tint *(*trace)(bool swo);\n};\n\nint swd_init_reset(struct command_context *cmd_ctx);\n\n#endif /* OPENOCD_JTAG_SWD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/swim.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com\n *\n * SWIM (Single Wire Interface Module) is a low-pin-count debug protocol\n * used by STMicroelectronics MCU family STM8 and documented in UM470\n * https://www.st.com/resource/en/user_manual/cd00173911.pdf\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"interface.h\"\n#include \"swim.h\"\n#include <helper/command.h>\n#include <transport/transport.h>\n\nextern struct adapter_driver *adapter_driver;\n\nint swim_system_reset(void)\n{\n\tassert(adapter_driver->swim_ops);\n\n\treturn adapter_driver->swim_ops->srst();\n}\n\nint swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t  uint8_t *buffer)\n{\n\tassert(adapter_driver->swim_ops);\n\n\treturn adapter_driver->swim_ops->read_mem(addr, size, count, buffer);\n}\n\nint swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t   const uint8_t *buffer)\n{\n\tassert(adapter_driver->swim_ops);\n\n\treturn adapter_driver->swim_ops->write_mem(addr, size, count, buffer);\n}\n\nint swim_reconnect(void)\n{\n\tassert(adapter_driver->swim_ops);\n\n\treturn adapter_driver->swim_ops->reconnect();\n}\n\nCOMMAND_HANDLER(handle_swim_newtap_command)\n{\n\tstruct jtag_tap *tap;\n\n\t/*\n\t * only need \"basename\" and \"tap_type\", but for backward compatibility\n\t * ignore extra parameters\n\t */\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttap = calloc(1, sizeof(*tap));\n\tif (!tap) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttap->chip = strdup(CMD_ARGV[0]);\n\ttap->tapname = strdup(CMD_ARGV[1]);\n\ttap->dotted_name = alloc_printf(\"%s.%s\", CMD_ARGV[0], CMD_ARGV[1]);\n\tif (!tap->chip || !tap->tapname || !tap->dotted_name) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(tap->dotted_name);\n\t\tfree(tap->tapname);\n\t\tfree(tap->chip);\n\t\tfree(tap);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Creating new SWIM \\\"tap\\\", Chip: %s, Tap: %s, Dotted: %s\",\n\t\t\t  tap->chip, tap->tapname, tap->dotted_name);\n\n\t/* default is enabled-after-reset */\n\ttap->enabled = true;\n\n\tjtag_tap_init(tap);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration swim_transport_subcommand_handlers[] = {\n\t{\n\t\t.name = \"newtap\",\n\t\t.handler = handle_swim_newtap_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Create a new TAP instance named basename.tap_type, \"\n\t\t\t\t\"and appends it to the scan chain.\",\n\t\t.usage = \"basename tap_type\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration swim_transport_command_handlers[] = {\n\t{\n\t\t.name = \"swim\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform swim adapter actions\",\n\t\t.usage = \"\",\n\t\t.chain = swim_transport_subcommand_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int swim_transport_select(struct command_context *cmd_ctx)\n{\n\tLOG_DEBUG(__func__);\n\n\treturn register_commands(cmd_ctx, NULL, swim_transport_command_handlers);\n}\n\nstatic int swim_transport_init(struct command_context *cmd_ctx)\n{\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tLOG_DEBUG(__func__);\n\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\tadapter_assert_reset();\n\t\telse\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t} else\n\t\tadapter_deassert_reset();\n\n\treturn ERROR_OK;\n}\n\nstatic struct transport swim_transport = {\n\t.name = \"swim\",\n\t.select = swim_transport_select,\n\t.init = swim_transport_init,\n};\n\nstatic void swim_constructor(void) __attribute__ ((constructor));\nstatic void swim_constructor(void)\n{\n\ttransport_register(&swim_transport);\n}\n\nbool transport_is_swim(void)\n{\n\treturn get_current_transport() == &swim_transport;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/swim.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com\n */\n\n/**\n * @file\n * This file implements support for STMicroelectronics debug protocol SWIM\n * (Single Wire Interface Module).\n */\n\n#ifndef OPENOCD_JTAG_SWIM_H\n#define OPENOCD_JTAG_SWIM_H\n\n#define SWIM_FREQ_LOW   363\n#define SWIM_FREQ_HIGH  800\n\nstruct swim_driver {\n\t/**\n\t * Send SRST (system reset) command to target.\n\t *\n\t * @return ERROR_OK on success, else a fault code.\n\t */\n\tint (*srst)(void);\n\n\t/**\n\t * Read target memory through ROTF (read on-the-fly) command.\n\t *\n\t * @param addr Start address to read data from target memory.\n\t * @param size Size in bytes of data units, 1, 2 or 4.\n\t * @param count Number of units (size units, not bytes) to read.\n\t * @param buffer Data buffer to receive data.\n\t * @return ERROR_OK on success, else a fault code.\n\t */\n\tint (*read_mem)(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t\tuint8_t *buffer);\n\n\t/**\n\t * Write target memory through WOTF (write on-the-fly) command.\n\t *\n\t * @param addr Start address to write data to target memory.\n\t * @param size Size in bytes of data units, 1, 2 or 4.\n\t * @param count Number of units (size units, not bytes) to write.\n\t * @param buffer Data buffer to write.\n\t * @return ERROR_OK on success, else a fault code.\n\t */\n\tint (*write_mem)(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t\t const uint8_t *buffer);\n\n\t/**\n\t * Reconnect to the target.\n\t * Should be reworked to be more generic and not linked to current\n\t * implementation in stlink driver.\n\t *\n\t * @return ERROR_OK on success, else a fault code.\n\t */\n\tint (*reconnect)(void);\n};\n\nint swim_system_reset(void);\nint swim_read_mem(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t  uint8_t *buffer);\nint swim_write_mem(uint32_t addr, uint32_t size, uint32_t count,\n\t\t\t\t   const uint8_t *buffer);\nint swim_reconnect(void);\n\n#endif /* OPENOCD_JTAG_SWIM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/tcl.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"adapter.h\"\n#include \"jtag.h\"\n#include \"swd.h\"\n#include \"minidriver.h\"\n#include \"interface.h\"\n#include \"interfaces.h\"\n#include \"tcl.h\"\n\n#ifdef HAVE_STRINGS_H\n#include <strings.h>\n#endif\n\n#include <helper/command.h>\n#include <helper/nvp.h>\n#include <helper/time_support.h>\n#include \"transport/transport.h\"\n\n/**\n * @file\n * Holds support for accessing JTAG-specific mechanisms from TCl scripts.\n */\n\nstatic const struct jim_nvp nvp_jtag_tap_event[] = {\n\t{ .value = JTAG_TRST_ASSERTED,          .name = \"post-reset\" },\n\t{ .value = JTAG_TAP_EVENT_SETUP,        .name = \"setup\" },\n\t{ .value = JTAG_TAP_EVENT_ENABLE,       .name = \"tap-enable\" },\n\t{ .value = JTAG_TAP_EVENT_DISABLE,      .name = \"tap-disable\" },\n\n\t{ .name = NULL, .value = -1 }\n};\n\nstruct jtag_tap *jtag_tap_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)\n{\n\tconst char *cp = Jim_GetString(o, NULL);\n\tstruct jtag_tap *t = cp ? jtag_tap_by_string(cp) : NULL;\n\tif (!cp)\n\t\tcp = \"(unknown)\";\n\tif (!t)\n\t\tJim_SetResultFormatted(interp, \"Tap '%s' could not be found\", cp);\n\treturn t;\n}\n\nstatic bool scan_is_safe(tap_state_t state)\n{\n\tswitch (state) {\n\t    case TAP_RESET:\n\t    case TAP_IDLE:\n\t    case TAP_DRPAUSE:\n\t    case TAP_IRPAUSE:\n\t\t    return true;\n\t    default:\n\t\t    return false;\n\t}\n}\n\nstatic COMMAND_HELPER(handle_jtag_command_drscan_fields, struct scan_field *fields)\n{\n\tunsigned int field_count = 0;\n\tfor (unsigned int i = 1; i < CMD_ARGC; i += 2) {\n\t\tunsigned int bits;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[i], bits);\n\t\tfields[field_count].num_bits = bits;\n\n\t\tvoid *t = malloc(DIV_ROUND_UP(bits, 8));\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tfields[field_count].out_value = t;\n\t\tstr_to_buf(CMD_ARGV[i + 1], strlen(CMD_ARGV[i + 1]), t, bits, 0);\n\t\tfields[field_count].in_value = t;\n\t\tfield_count++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_command_drscan)\n{\n\t/*\n\t * CMD_ARGV[0] = device\n\t * CMD_ARGV[1] = num_bits\n\t * CMD_ARGV[2] = hex string\n\t * ... repeat num bits and hex string ...\n\t *\n\t * ... optionally:\n\t * CMD_ARGV[CMD_ARGC-2] = \"-endstate\"\n\t * CMD_ARGV[CMD_ARGC-1] = statename\n\t */\n\n\tif (CMD_ARGC < 3 || (CMD_ARGC % 2) != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[0]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap '%s' could not be found\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (tap->bypass) {\n\t\tcommand_print(CMD, \"Can't execute as the selected tap is in BYPASS\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttap_state_t endstate = TAP_IDLE;\n\tif (CMD_ARGC > 3 && !strcmp(\"-endstate\", CMD_ARGV[CMD_ARGC - 2])) {\n\t\tconst char *state_name = CMD_ARGV[CMD_ARGC - 1];\n\t\tendstate = tap_state_by_name(state_name);\n\t\tif (endstate < 0) {\n\t\t\tcommand_print(CMD, \"endstate: %s invalid\", state_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\n\t\tif (!scan_is_safe(endstate))\n\t\t\tLOG_WARNING(\"drscan with unsafe endstate \\\"%s\\\"\", state_name);\n\n\t\tCMD_ARGC -= 2;\n\t}\n\n\tunsigned int num_fields = (CMD_ARGC - 1) / 2;\n\tstruct scan_field *fields = calloc(num_fields, sizeof(struct scan_field));\n\tif (!fields) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = CALL_COMMAND_HANDLER(handle_jtag_command_drscan_fields, fields);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\n\tjtag_add_dr_scan(tap, num_fields, fields, endstate);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"drscan: jtag execute failed\");\n\t\tgoto fail;\n\t}\n\n\tfor (unsigned int i = 0; i < num_fields; i++) {\n\t\tchar *str = buf_to_hex_str(fields[i].in_value, fields[i].num_bits);\n\t\tcommand_print(CMD, \"%s\", str);\n\t\tfree(str);\n\t}\n\nfail:\n\tfor (unsigned int i = 0; i < num_fields; i++)\n\t\tfree(fields[i].in_value);\n\tfree(fields);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_jtag_command_pathmove)\n{\n\ttap_state_t states[8];\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > ARRAY_SIZE(states))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tstates[i] = tap_state_by_name(CMD_ARGV[i]);\n\t\tif (states[i] < 0) {\n\t\t\tcommand_print(CMD, \"endstate: %s invalid\", CMD_ARGV[i]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tint retval = jtag_add_statemove(states[0]);\n\tif (retval == ERROR_OK)\n\t\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"pathmove: jtag execute failed\");\n\t\treturn retval;\n\t}\n\n\tjtag_add_pathmove(CMD_ARGC - 1, states + 1);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"pathmove: failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_flush_count)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint count = jtag_get_flush_queue_count();\n\tcommand_print_sameline(CMD, \"%d\", count);\n\n\treturn ERROR_OK;\n}\n\n/* REVISIT Just what about these should \"move\" ... ?\n * These registrations, into the main JTAG table?\n *\n * There's a minor compatibility issue, these all show up twice;\n * that's not desirable:\n *  - jtag drscan ... NOT DOCUMENTED!\n *  - drscan ...\n *\n * The \"irscan\" command (for example) doesn't show twice.\n */\nstatic const struct command_registration jtag_command_handlers_to_move[] = {\n\t{\n\t\t.name = \"drscan\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_command_drscan,\n\t\t.help = \"Execute Data Register (DR) scan for one TAP.  \"\n\t\t\t\"Other TAPs must be in BYPASS mode.\",\n\t\t.usage = \"tap_name (num_bits value)+ ['-endstate' state_name]\",\n\t},\n\t{\n\t\t.name = \"flush_count\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_flush_count,\n\t\t.help = \"Returns the number of times the JTAG queue \"\n\t\t\t\"has been flushed.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"pathmove\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_command_pathmove,\n\t\t.usage = \"start_state state1 [state2 [state3 ...]]\",\n\t\t.help = \"Move JTAG state machine from current state \"\n\t\t\t\"(start_state) to state1, then state2, state3, etc.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\nenum jtag_tap_cfg_param {\n\tJCFG_EVENT,\n\tJCFG_IDCODE,\n};\n\nstatic struct jim_nvp nvp_config_opts[] = {\n\t{ .name = \"-event\",      .value = JCFG_EVENT },\n\t{ .name = \"-idcode\",     .value = JCFG_IDCODE },\n\n\t{ .name = NULL,          .value = -1 }\n};\n\nstatic int jtag_tap_configure_event(struct jim_getopt_info *goi, struct jtag_tap *tap)\n{\n\tif (goi->argc == 0) {\n\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event <event-name> ...\");\n\t\treturn JIM_ERR;\n\t}\n\n\tstruct jim_nvp *n;\n\tint e = jim_getopt_nvp(goi, nvp_jtag_tap_event, &n);\n\tif (e != JIM_OK) {\n\t\tjim_getopt_nvp_unknown(goi, nvp_jtag_tap_event, 1);\n\t\treturn e;\n\t}\n\n\tif (goi->isconfigure) {\n\t\tif (goi->argc != 1) {\n\t\t\tJim_WrongNumArgs(goi->interp,\n\t\t\t\tgoi->argc,\n\t\t\t\tgoi->argv,\n\t\t\t\t\"-event <event-name> <event-body>\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\t} else {\n\t\tif (goi->argc != 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event <event-name>\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\t}\n\n\tstruct jtag_tap_event_action *jteap  = tap->event_action;\n\t/* replace existing event body */\n\tbool found = false;\n\twhile (jteap) {\n\t\tif (jteap->event == (enum jtag_event)n->value) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t\tjteap = jteap->next;\n\t}\n\n\tJim_SetEmptyResult(goi->interp);\n\n\tif (goi->isconfigure) {\n\t\tif (!found)\n\t\t\tjteap = calloc(1, sizeof(*jteap));\n\t\telse if (jteap->body)\n\t\t\tJim_DecrRefCount(goi->interp, jteap->body);\n\n\t\tjteap->interp = goi->interp;\n\t\tjteap->event = n->value;\n\n\t\tJim_Obj *o;\n\t\tjim_getopt_obj(goi, &o);\n\t\tjteap->body = Jim_DuplicateObj(goi->interp, o);\n\t\tJim_IncrRefCount(jteap->body);\n\n\t\tif (!found) {\n\t\t\t/* add to head of event list */\n\t\t\tjteap->next = tap->event_action;\n\t\t\ttap->event_action = jteap;\n\t\t}\n\t} else if (found) {\n\t\tjteap->interp = goi->interp;\n\t\tJim_SetResult(goi->interp,\n\t\t\tJim_DuplicateObj(goi->interp, jteap->body));\n\t}\n\treturn JIM_OK;\n}\n\nstatic int jtag_tap_configure_cmd(struct jim_getopt_info *goi, struct jtag_tap *tap)\n{\n\t/* parse config or cget options */\n\twhile (goi->argc > 0) {\n\t\tJim_SetEmptyResult(goi->interp);\n\n\t\tstruct jim_nvp *n;\n\t\tint e = jim_getopt_nvp(goi, nvp_config_opts, &n);\n\t\tif (e != JIM_OK) {\n\t\t\tjim_getopt_nvp_unknown(goi, nvp_config_opts, 0);\n\t\t\treturn e;\n\t\t}\n\n\t\tswitch (n->value) {\n\t\t\tcase JCFG_EVENT:\n\t\t\t\te = jtag_tap_configure_event(goi, tap);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tbreak;\n\t\t\tcase JCFG_IDCODE:\n\t\t\t\tif (goi->isconfigure) {\n\t\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\t\"not settable: %s\", n->name);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t} else {\n\t\t\t\t\tif (goi->argc != 0) {\n\t\t\t\t\t\tJim_WrongNumArgs(goi->interp,\n\t\t\t\t\t\t\t\tgoi->argc, goi->argv,\n\t\t\t\t\t\t\t\t\"NO PARAMS\");\n\t\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, tap->idcode));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tJim_SetResultFormatted(goi->interp, \"unknown value: %s\", n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t}\n\t}\n\n\treturn JIM_OK;\n}\n\n#define NTAP_OPT_IRLEN     0\n#define NTAP_OPT_IRMASK    1\n#define NTAP_OPT_IRCAPTURE 2\n#define NTAP_OPT_ENABLED   3\n#define NTAP_OPT_DISABLED  4\n#define NTAP_OPT_EXPECTED_ID 5\n#define NTAP_OPT_VERSION   6\n#define NTAP_OPT_BYPASS    7\n\nstatic const struct nvp jtag_newtap_opts[] = {\n\t{ .name = \"-irlen\",          .value = NTAP_OPT_IRLEN },\n\t{ .name = \"-irmask\",         .value = NTAP_OPT_IRMASK },\n\t{ .name = \"-ircapture\",      .value = NTAP_OPT_IRCAPTURE },\n\t{ .name = \"-enable\",         .value = NTAP_OPT_ENABLED },\n\t{ .name = \"-disable\",        .value = NTAP_OPT_DISABLED },\n\t{ .name = \"-expected-id\",    .value = NTAP_OPT_EXPECTED_ID },\n\t{ .name = \"-ignore-version\", .value = NTAP_OPT_VERSION },\n\t{ .name = \"-ignore-bypass\",  .value = NTAP_OPT_BYPASS },\n\t{ .name = NULL,              .value = -1 },\n};\n\nstatic COMMAND_HELPER(handle_jtag_newtap_args, struct jtag_tap *tap)\n{\n\t/* we expect CHIP + TAP + OPTIONS */\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttap->chip = strdup(CMD_ARGV[0]);\n\ttap->tapname = strdup(CMD_ARGV[1]);\n\ttap->dotted_name = alloc_printf(\"%s.%s\", CMD_ARGV[0], CMD_ARGV[1]);\n\tif (!tap->chip || !tap->tapname || !tap->dotted_name) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tCMD_ARGC -= 2;\n\tCMD_ARGV += 2;\n\n\tLOG_DEBUG(\"Creating New Tap, Chip: %s, Tap: %s, Dotted: %s, %d params\",\n\t\t  tap->chip, tap->tapname, tap->dotted_name, CMD_ARGC);\n\n\t/*\n\t * IEEE specifies that the two LSBs of an IR scan are 01, so make\n\t * that the default.  The \"-ircapture\" and \"-irmask\" options are only\n\t * needed to cope with nonstandard TAPs, or to specify more bits.\n\t */\n\ttap->ir_capture_mask = 0x03;\n\ttap->ir_capture_value = 0x01;\n\n\twhile (CMD_ARGC) {\n\t\tconst struct nvp *n = nvp_name2value(jtag_newtap_opts, CMD_ARGV[0]);\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tswitch (n->value) {\n\t    case NTAP_OPT_ENABLED:\n\t\t    tap->disabled_after_reset = false;\n\t\t    break;\n\n\t    case NTAP_OPT_DISABLED:\n\t\t    tap->disabled_after_reset = true;\n\t\t    break;\n\n\t\tcase NTAP_OPT_EXPECTED_ID:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\ttap->expected_ids = realloc(tap->expected_ids,\n\t\t\t\t\t\t\t\t\t\t(tap->expected_ids_cnt + 1) * sizeof(uint32_t));\n\t\t\tif (!tap->expected_ids) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tuint32_t id;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], id);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\ttap->expected_ids[tap->expected_ids_cnt++] = id;\n\n\t\t\tbreak;\n\n\t\tcase NTAP_OPT_IRLEN:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], tap->ir_length);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tif (tap->ir_length > (int)(8 * sizeof(tap->ir_capture_value)))\n\t\t\t\tLOG_WARNING(\"%s: huge IR length %d\", tap->dotted_name, tap->ir_length);\n\t\t\tbreak;\n\n\t\tcase NTAP_OPT_IRMASK:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_mask);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tif ((tap->ir_capture_mask & 3) != 3)\n\t\t\t\tLOG_WARNING(\"%s: nonstandard IR mask\", tap->dotted_name);\n\t\t\tbreak;\n\n\t\tcase NTAP_OPT_IRCAPTURE:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], tap->ir_capture_value);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tif ((tap->ir_capture_value & 3) != 1)\n\t\t\t\tLOG_WARNING(\"%s: nonstandard IR value\", tap->dotted_name);\n\t\t\tbreak;\n\n\t\tcase NTAP_OPT_VERSION:\n\t\t\ttap->ignore_version = true;\n\t\t\tbreak;\n\n\t\tcase NTAP_OPT_BYPASS:\n\t\t\ttap->ignore_bypass = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tnvp_unknown_command_print(CMD, jtag_newtap_opts, NULL, CMD_ARGV[-1]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\t/* default is enabled-after-reset */\n\ttap->enabled = !tap->disabled_after_reset;\n\n\tif (transport_is_jtag() && tap->ir_length == 0) {\n\t\tcommand_print(CMD, \"newtap: %s missing IR length\", tap->dotted_name);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\n__COMMAND_HANDLER(handle_jtag_newtap)\n{\n\tstruct jtag_tap *tap = calloc(1, sizeof(struct jtag_tap));\n\tif (!tap) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = CALL_COMMAND_HANDLER(handle_jtag_newtap_args, tap);\n\tif (retval != ERROR_OK) {\n\t\tfree(tap->chip);\n\t\tfree(tap->tapname);\n\t\tfree(tap->dotted_name);\n\t\tfree(tap->expected_ids);\n\t\tfree(tap);\n\t\treturn retval;\n\t}\n\n\tjtag_tap_init(tap);\n\treturn ERROR_OK;\n}\n\nstatic void jtag_tap_handle_event(struct jtag_tap *tap, enum jtag_event e)\n{\n\tstruct jtag_tap_event_action *jteap;\n\tint retval;\n\n\tfor (jteap = tap->event_action; jteap; jteap = jteap->next) {\n\t\tif (jteap->event != e)\n\t\t\tcontinue;\n\n\t\tstruct jim_nvp *nvp = jim_nvp_value2name_simple(nvp_jtag_tap_event, e);\n\t\tLOG_DEBUG(\"JTAG tap: %s event: %d (%s)\\n\\taction: %s\",\n\t\t\ttap->dotted_name, e, nvp->name,\n\t\t\tJim_GetString(jteap->body, NULL));\n\n\t\tretval = Jim_EvalObj(jteap->interp, jteap->body);\n\t\tif (retval == JIM_RETURN)\n\t\t\tretval = jteap->interp->returnCode;\n\n\t\tif (retval != JIM_OK) {\n\t\t\tJim_MakeErrorMessage(jteap->interp);\n\t\t\tLOG_USER(\"%s\", Jim_GetString(Jim_GetResult(jteap->interp), NULL));\n\t\t\tcontinue;\n\t\t}\n\n\t\tswitch (e) {\n\t\t    case JTAG_TAP_EVENT_ENABLE:\n\t\t    case JTAG_TAP_EVENT_DISABLE:\n\t\t\t\t/* NOTE:  we currently assume the handlers\n\t\t\t\t * can't fail.  Right here is where we should\n\t\t\t\t * really be verifying the scan chains ...\n\t\t\t\t */\n\t\t\t    tap->enabled = (e == JTAG_TAP_EVENT_ENABLE);\n\t\t\t    LOG_INFO(\"JTAG tap: %s %s\", tap->dotted_name,\n\t\t\t\ttap->enabled ? \"enabled\" : \"disabled\");\n\t\t\t    break;\n\t\t    default:\n\t\t\t    break;\n\t\t}\n\t}\n}\n\nCOMMAND_HANDLER(handle_jtag_arp_init)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn jtag_init_inner(CMD_CTX);\n}\n\nCOMMAND_HANDLER(handle_jtag_arp_init_reset)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (transport_is_jtag())\n\t\treturn jtag_init_reset(CMD_CTX);\n\n\tif (transport_is_swd())\n\t\treturn swd_init_reset(CMD_CTX);\n\n\treturn ERROR_OK;\n}\n\nstatic bool jtag_tap_enable(struct jtag_tap *t)\n{\n\tif (t->enabled)\n\t\treturn true;\n\tjtag_tap_handle_event(t, JTAG_TAP_EVENT_ENABLE);\n\tif (!t->enabled)\n\t\treturn false;\n\n\t/* FIXME add JTAG sanity checks, w/o TLR\n\t *  - scan chain length grew by one (this)\n\t *  - IDs and IR lengths are as expected\n\t */\n\tjtag_call_event_callbacks(JTAG_TAP_EVENT_ENABLE);\n\treturn true;\n}\nstatic bool jtag_tap_disable(struct jtag_tap *t)\n{\n\tif (!t->enabled)\n\t\treturn true;\n\tjtag_tap_handle_event(t, JTAG_TAP_EVENT_DISABLE);\n\tif (t->enabled)\n\t\treturn false;\n\n\t/* FIXME add JTAG sanity checks, w/o TLR\n\t *  - scan chain length shrank by one (this)\n\t *  - IDs and IR lengths are as expected\n\t */\n\tjtag_call_event_callbacks(JTAG_TAP_EVENT_DISABLE);\n\treturn true;\n}\n\n__COMMAND_HANDLER(handle_jtag_tap_enabler)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *t = jtag_tap_by_string(CMD_ARGV[0]);\n\tif (!t) {\n\t\tcommand_print(CMD, \"Tap '%s' could not be found\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (strcmp(CMD_NAME, \"tapisenabled\") == 0) {\n\t\t/* do nothing, just return the value */\n\t} else if (strcmp(CMD_NAME, \"tapenable\") == 0) {\n\t\tif (!jtag_tap_enable(t)) {\n\t\t\tcommand_print(CMD, \"failed to enable tap %s\", t->dotted_name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else if (strcmp(CMD_NAME, \"tapdisable\") == 0) {\n\t\tif (!jtag_tap_disable(t)) {\n\t\t\tcommand_print(CMD, \"failed to disable tap %s\", t->dotted_name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tcommand_print(CMD, \"command '%s' unknown\", CMD_NAME);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(CMD, \"%d\", t->enabled ? 1 : 0);\n\treturn ERROR_OK;\n}\n\nint jim_jtag_configure(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct command *c = jim_to_command(interp);\n\tconst char *cmd_name = c->name;\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc-1, argv + 1);\n\tgoi.isconfigure = !strcmp(cmd_name, \"configure\");\n\tif (goi.argc < 2 + goi.isconfigure) {\n\t\tJim_WrongNumArgs(goi.interp, 0, NULL,\n\t\t\t\"<tap_name> <attribute> ...\");\n\t\treturn JIM_ERR;\n\t}\n\n\tstruct jtag_tap *t;\n\n\tJim_Obj *o;\n\tjim_getopt_obj(&goi, &o);\n\tt = jtag_tap_by_jim_obj(goi.interp, o);\n\tif (!t)\n\t\treturn JIM_ERR;\n\n\treturn jtag_tap_configure_cmd(&goi, t);\n}\n\nCOMMAND_HANDLER(handle_jtag_names)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (struct jtag_tap *tap = jtag_all_taps(); tap; tap = tap->next_tap)\n\t\tcommand_print(CMD, \"%s\", tap->dotted_name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_init_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstatic bool jtag_initialized;\n\tif (jtag_initialized) {\n\t\tLOG_INFO(\"'jtag init' has already been called\");\n\t\treturn ERROR_OK;\n\t}\n\tjtag_initialized = true;\n\n\tLOG_DEBUG(\"Initializing jtag devices...\");\n\treturn jtag_init(CMD_CTX);\n}\n\nstatic const struct command_registration jtag_subcommand_handlers[] = {\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_jtag_init_command,\n\t\t.help = \"initialize jtag scan chain\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"arp_init\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_jtag_arp_init,\n\t\t.help = \"Validates JTAG scan chain against the list of \"\n\t\t\t\"declared TAPs using just the four standard JTAG \"\n\t\t\t\"signals.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_init-reset\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_jtag_arp_init_reset,\n\t\t.help = \"Uses TRST and SRST to try resetting everything on \"\n\t\t\t\"the JTAG scan chain, then performs 'jtag arp_init'.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"newtap\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_jtag_newtap,\n\t\t.help = \"Create a new TAP instance named basename.tap_type, \"\n\t\t\t\"and appends it to the scan chain.\",\n\t\t.usage = \"basename tap_type '-irlen' count \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t},\n\t{\n\t\t.name = \"tapisenabled\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_tap_enabler,\n\t\t.help = \"Returns a Tcl boolean (0/1) indicating whether \"\n\t\t\t\"the TAP is enabled (1) or not (0).\",\n\t\t.usage = \"tap_name\",\n\t},\n\t{\n\t\t.name = \"tapenable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_tap_enabler,\n\t\t.help = \"Try to enable the specified TAP using the \"\n\t\t\t\"'tap-enable' TAP event.\",\n\t\t.usage = \"tap_name\",\n\t},\n\t{\n\t\t.name = \"tapdisable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_tap_enabler,\n\t\t.help = \"Try to disable the specified TAP using the \"\n\t\t\t\"'tap-disable' TAP event.\",\n\t\t.usage = \"tap_name\",\n\t},\n\t{\n\t\t.name = \"configure\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_jtag_configure,\n\t\t.help = \"Provide a Tcl handler for the specified \"\n\t\t\t\"TAP event.\",\n\t\t.usage = \"tap_name '-event' event_name handler\",\n\t},\n\t{\n\t\t.name = \"cget\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = jim_jtag_configure,\n\t\t.help = \"Return any Tcl handler for the specified \"\n\t\t\t\"TAP event.\",\n\t\t.usage = \"tap_name '-event' event_name\",\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_jtag_names,\n\t\t.help = \"Returns list of all JTAG tap names.\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.chain = jtag_command_handlers_to_move,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nvoid jtag_notify_event(enum jtag_event event)\n{\n\tstruct jtag_tap *tap;\n\n\tfor (tap = jtag_all_taps(); tap; tap = tap->next_tap)\n\t\tjtag_tap_handle_event(tap, event);\n}\n\n\nCOMMAND_HANDLER(handle_scan_chain_command)\n{\n\tstruct jtag_tap *tap;\n\tchar expected_id[12];\n\n\ttap = jtag_all_taps();\n\tcommand_print(CMD,\n\t\t\"   TapName             Enabled  IdCode     Expected   IrLen IrCap IrMask\");\n\tcommand_print(CMD,\n\t\t\"-- ------------------- -------- ---------- ---------- ----- ----- ------\");\n\n\twhile (tap) {\n\t\tuint32_t expected, expected_mask, ii;\n\n\t\tsnprintf(expected_id, sizeof(expected_id), \"0x%08x\",\n\t\t\t(unsigned)((tap->expected_ids_cnt > 0)\n\t\t\t\t   ? tap->expected_ids[0]\n\t\t\t\t   : 0));\n\t\tif (tap->ignore_version)\n\t\t\texpected_id[2] = '*';\n\n\t\texpected = buf_get_u32(tap->expected, 0, tap->ir_length);\n\t\texpected_mask = buf_get_u32(tap->expected_mask, 0, tap->ir_length);\n\n\t\tcommand_print(CMD,\n\t\t\t\"%2d %-18s     %c     0x%08x %s %5d 0x%02x  0x%02x\",\n\t\t\ttap->abs_chain_position,\n\t\t\ttap->dotted_name,\n\t\t\ttap->enabled ? 'Y' : 'n',\n\t\t\t(unsigned int)(tap->idcode),\n\t\t\texpected_id,\n\t\t\t(unsigned int)(tap->ir_length),\n\t\t\t(unsigned int)(expected),\n\t\t\t(unsigned int)(expected_mask));\n\n\t\tfor (ii = 1; ii < tap->expected_ids_cnt; ii++) {\n\t\t\tsnprintf(expected_id, sizeof(expected_id), \"0x%08x\",\n\t\t\t\t(unsigned) tap->expected_ids[ii]);\n\t\t\tif (tap->ignore_version)\n\t\t\t\texpected_id[2] = '*';\n\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"                                           %s\",\n\t\t\t\texpected_id);\n\t\t}\n\n\t\ttap = tap->next_tap;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_ntrst_delay_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned delay;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);\n\n\t\tjtag_set_ntrst_delay(delay);\n\t}\n\tcommand_print(CMD, \"jtag_ntrst_delay: %u\", jtag_get_ntrst_delay());\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_ntrst_assert_width_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned delay;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], delay);\n\n\t\tjtag_set_ntrst_assert_width(delay);\n\t}\n\tcommand_print(CMD, \"jtag_ntrst_assert_width: %u\", jtag_get_ntrst_assert_width());\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_rclk_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint retval = ERROR_OK;\n\tif (CMD_ARGC == 1) {\n\t\tunsigned khz = 0;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], khz);\n\n\t\tretval = adapter_config_rclk(khz);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tint cur_khz = adapter_get_speed_khz();\n\tretval = adapter_get_speed_readable(&cur_khz);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cur_khz)\n\t\tcommand_print(CMD, \"RCLK not supported - fallback to %d kHz\", cur_khz);\n\telse\n\t\tcommand_print(CMD, \"RCLK - adaptive\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_runtest_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned num_clocks;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num_clocks);\n\n\tjtag_add_runtest(num_clocks, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\n/*\n * For \"irscan\" or \"drscan\" commands, the \"end\" (really, \"next\") state\n * should be stable ... and *NOT* a shift state, otherwise free-running\n * jtag clocks could change the values latched by the update state.\n * Not surprisingly, this is the same constraint as SVF; the \"irscan\"\n * and \"drscan\" commands are a write-only subset of what SVF provides.\n */\n\nCOMMAND_HANDLER(handle_irscan_command)\n{\n\tint i;\n\tstruct scan_field *fields;\n\tstruct jtag_tap *tap = NULL;\n\ttap_state_t endstate;\n\n\tif ((CMD_ARGC < 2) || (CMD_ARGC % 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* optional \"-endstate\" \"statename\" at the end of the arguments,\n\t * so that e.g. IRPAUSE can let us load the data register before\n\t * entering RUN/IDLE to execute the instruction we load here.\n\t */\n\tendstate = TAP_IDLE;\n\n\tif (CMD_ARGC >= 4) {\n\t\t/* have at least one pair of numbers.\n\t\t * is last pair the magic text? */\n\t\tif (strcmp(\"-endstate\", CMD_ARGV[CMD_ARGC - 2]) == 0) {\n\t\t\tendstate = tap_state_by_name(CMD_ARGV[CMD_ARGC - 1]);\n\t\t\tif (endstate == TAP_INVALID)\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tif (!scan_is_safe(endstate))\n\t\t\t\tLOG_WARNING(\"unstable irscan endstate \\\"%s\\\"\",\n\t\t\t\t\tCMD_ARGV[CMD_ARGC - 1]);\n\t\t\tCMD_ARGC -= 2;\n\t\t}\n\t}\n\n\tint num_fields = CMD_ARGC / 2;\n\tif (num_fields > 1) {\n\t\t/* we really should be looking at plain_ir_scan if we want\n\t\t * anything more fancy.\n\t\t */\n\t\tLOG_ERROR(\"Specify a single value for tap\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tfields = calloc(num_fields, sizeof(*fields));\n\n\tint retval;\n\tfor (i = 0; i < num_fields; i++) {\n\t\ttap = jtag_tap_by_string(CMD_ARGV[i*2]);\n\t\tif (!tap) {\n\t\t\tfree(fields);\n\t\t\tcommand_print(CMD, \"Tap: %s unknown\", CMD_ARGV[i*2]);\n\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tuint64_t value;\n\t\tretval = parse_u64(CMD_ARGV[i * 2 + 1], &value);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto error_return;\n\n\t\tint field_size = tap->ir_length;\n\t\tfields[i].num_bits = field_size;\n\t\tuint8_t *v = calloc(1, DIV_ROUND_UP(field_size, 8));\n\t\tif (!v) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tgoto error_return;\n\t\t}\n\n\t\tbuf_set_u64(v, 0, field_size, value);\n\t\tfields[i].out_value = v;\n\t\tfields[i].in_value = NULL;\n\t}\n\n\t/* did we have an endstate? */\n\tjtag_add_ir_scan(tap, fields, endstate);\n\n\tretval = jtag_execute_queue();\n\nerror_return:\n\tfor (i = 0; i < num_fields; i++)\n\t\tfree((void *)fields[i].out_value);\n\n\tfree(fields);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_verify_ircapture_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tjtag_set_verify_capture_ir(enable);\n\t}\n\n\tconst char *status = jtag_will_verify_capture_ir() ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"verify Capture-IR is %s\", status);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_verify_jtag_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tjtag_set_verify(enable);\n\t}\n\n\tconst char *status = jtag_will_verify() ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"verify jtag capture is %s\", status);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_tms_sequence_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tbool use_new_table;\n\t\tif (strcmp(CMD_ARGV[0], \"short\") == 0)\n\t\t\tuse_new_table = true;\n\t\telse if (strcmp(CMD_ARGV[0], \"long\") == 0)\n\t\t\tuse_new_table = false;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\ttap_use_new_tms_table(use_new_table);\n\t}\n\n\tcommand_print(CMD, \"tms sequence is  %s\",\n\t\ttap_uses_new_tms_table() ? \"short\" : \"long\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_jtag_flush_queue_sleep)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint sleep_ms;\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], sleep_ms);\n\n\tjtag_set_flush_queue_sleep(sleep_ms);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_wait_srst_deassert)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint timeout_ms;\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], timeout_ms);\n\tif ((timeout_ms <= 0) || (timeout_ms > 100000)) {\n\t\tLOG_ERROR(\"Timeout must be an integer between 0 and 100000\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_USER(\"Waiting for srst assert + deassert for at most %dms\", timeout_ms);\n\tint asserted_yet;\n\tint64_t then = timeval_ms();\n\twhile (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {\n\t\tif ((timeval_ms() - then) > timeout_ms) {\n\t\t\tLOG_ERROR(\"Timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (asserted_yet)\n\t\t\tbreak;\n\t}\n\twhile (jtag_srst_asserted(&asserted_yet) == ERROR_OK) {\n\t\tif ((timeval_ms() - then) > timeout_ms) {\n\t\t\tLOG_ERROR(\"Timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (!asserted_yet)\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration jtag_command_handlers[] = {\n\n\t{\n\t\t.name = \"jtag_flush_queue_sleep\",\n\t\t.handler = handle_jtag_flush_queue_sleep,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"For debug purposes(simulate long delays of interface) \"\n\t\t\t\"to test performance or change in behavior. Default 0ms.\",\n\t\t.usage = \"[sleep in ms]\",\n\t},\n\t{\n\t\t.name = \"jtag_rclk\",\n\t\t.handler = handle_jtag_rclk_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"With an argument, change to to use adaptive clocking \"\n\t\t\t\"if possible; else to use the fallback speed.  \"\n\t\t\t\"With or without argument, display current setting.\",\n\t\t.usage = \"[fallback_speed_khz]\",\n\t},\n\t{\n\t\t.name = \"jtag_ntrst_delay\",\n\t\t.handler = handle_jtag_ntrst_delay_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"delay after deasserting trst in ms\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"jtag_ntrst_assert_width\",\n\t\t.handler = handle_jtag_ntrst_assert_width_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"delay after asserting trst in ms\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"scan_chain\",\n\t\t.handler = handle_scan_chain_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"print current scan chain configuration\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"runtest\",\n\t\t.handler = handle_runtest_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Move to Run-Test/Idle, and issue TCK for num_cycles.\",\n\t\t.usage = \"num_cycles\"\n\t},\n\t{\n\t\t.name = \"irscan\",\n\t\t.handler = handle_irscan_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Execute Instruction Register (IR) scan.  The \"\n\t\t\t\"specified opcodes are put into each TAP's IR, \"\n\t\t\t\"and other TAPs are put in BYPASS.\",\n\t\t.usage = \"[tap_name instruction]* ['-endstate' state_name]\",\n\t},\n\t{\n\t\t.name = \"verify_ircapture\",\n\t\t.handler = handle_verify_ircapture_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or assign flag controlling whether to \"\n\t\t\t\"verify values captured during Capture-IR.\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"verify_jtag\",\n\t\t.handler = handle_verify_jtag_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or assign flag controlling whether to \"\n\t\t\t\"verify values captured during IR and DR scans.\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"tms_sequence\",\n\t\t.handler = handle_tms_sequence_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or change what style TMS sequences to use \"\n\t\t\t\"for JTAG state transitions:  short (default) or \"\n\t\t\t\"long.  Only for working around JTAG bugs.\",\n\t\t/* Specifically for working around DRIVER bugs... */\n\t\t.usage = \"['short'|'long']\",\n\t},\n\t{\n\t\t.name = \"wait_srst_deassert\",\n\t\t.handler = handle_wait_srst_deassert,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Wait for an SRST deassert. \"\n\t\t\t\"Useful for cases where you need something to happen within ms \"\n\t\t\t\"of an srst deassert. Timeout in ms\",\n\t\t.usage = \"ms\",\n\t},\n\t{\n\t\t.name = \"jtag\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"perform jtag tap actions\",\n\t\t.usage = \"\",\n\n\t\t.chain = jtag_subcommand_handlers,\n\t},\n\t{\n\t\t.chain = jtag_command_handlers_to_move,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint jtag_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, jtag_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/jtag/tcl.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation                                *\n *       http://softplc.com                                                *\n *   dick@softplc.com                                                      *\n *                                                                         *\n *   Copyright (C) 2009 Zachary T Welch                                    *\n *   zw@superlucidity.net                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_JTAG_TCL_H\n#define OPENOCD_JTAG_TCL_H\n\n#include <helper/command.h>\n\nint jim_jtag_configure(Jim_Interp *interp, int argc,\n\t\tJim_Obj * const *argv);\n__COMMAND_HANDLER(handle_jtag_tap_enabler);\n\n#endif /* OPENOCD_JTAG_TCL_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/main.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"openocd.h\"\n#include \"helper/system.h\"\n\n/* This is the main entry for developer PC hosted OpenOCD.\n *\n * OpenOCD can also be used as a library that is linked with\n * another application(not mainstream yet, but possible), e.g.\n * w/as an embedded application.\n *\n * Those applications will have their own main() implementation\n * and use bits and pieces from openocd.c. */\n\nint main(int argc, char *argv[])\n{\n\t/* disable buffering otherwise piping to logs causes problems work */\n\tsetvbuf(stdout, NULL, _IONBF, 0);\n\tsetvbuf(stderr, NULL, _IONBF, 0);\n\n\treturn openocd_main(argc, argv);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/openocd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 Richard Missenden                                  *\n *   richard.missenden@googlemail.com                                      *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"openocd.h\"\n#include <jtag/adapter.h>\n#include <jtag/jtag.h>\n#include <transport/transport.h>\n#include <helper/util.h>\n#include <helper/configuration.h>\n#include <flash/nor/core.h>\n#include <flash/nand/core.h>\n#include <pld/pld.h>\n#include <target/arm_cti.h>\n#include <target/arm_adi_v5.h>\n#include <target/arm_tpiu_swo.h>\n#include <rtt/rtt.h>\n\n#include <server/server.h>\n#include <server/gdb_server.h>\n#include <server/rtt_server.h>\n\n#ifdef HAVE_STRINGS_H\n#include <strings.h>\n#endif\n\n#ifdef PKGBLDDATE\n#define OPENOCD_VERSION\t\\\n\t\"Open On-Chip Debugger \" VERSION RELSTR \" (\" PKGBLDDATE \")\"\n#else\n#define OPENOCD_VERSION\t\\\n\t\"Open On-Chip Debugger \" VERSION RELSTR\n#endif\n\nstatic const char openocd_startup_tcl[] = {\n#include \"startup_tcl.inc\"\n0 /* Terminate with zero */\n};\n\n/* Give scripts and TELNET a way to find out what version this is */\nCOMMAND_HANDLER(handler_version_command)\n{\n\tchar *version_str = OPENOCD_VERSION;\n\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tif (strcmp(\"git\", CMD_ARGV[0]))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\tversion_str = GITVERSION;\n\t}\n\n\tcommand_print(CMD, \"%s\", version_str);\n\n\treturn ERROR_OK;\n}\n\nstatic int log_target_callback_event_handler(struct target *target,\n\tenum target_event event,\n\tvoid *priv)\n{\n\tswitch (event) {\n\t\tcase TARGET_EVENT_GDB_START:\n\t\t\ttarget->verbose_halt_msg = false;\n\t\t\tbreak;\n\t\tcase TARGET_EVENT_GDB_END:\n\t\t\ttarget->verbose_halt_msg = true;\n\t\t\tbreak;\n\t\tcase TARGET_EVENT_HALTED:\n\t\t\tif (target->verbose_halt_msg) {\n\t\t\t\t/* do not display information when debugger caused the halt */\n\t\t\t\ttarget_arch_state(target);\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool init_at_startup = true;\n\nCOMMAND_HANDLER(handle_noinit_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tinit_at_startup = false;\n\treturn ERROR_OK;\n}\n\n/* OpenOCD can't really handle failure of this command. Patches welcome! :-) */\nCOMMAND_HANDLER(handle_init_command)\n{\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint retval;\n\tstatic int initialized;\n\tif (initialized)\n\t\treturn ERROR_OK;\n\n\tinitialized = 1;\n\n\tbool save_poll_mask = jtag_poll_mask();\n\n\tretval = command_run_line(CMD_CTX, \"target init\");\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tretval = adapter_init(CMD_CTX);\n\tif (retval != ERROR_OK) {\n\t\t/* we must be able to set up the debug adapter */\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"Debug Adapter init complete\");\n\n\t/* \"transport init\" verifies the expected devices are present;\n\t * for JTAG, it checks the list of configured TAPs against\n\t * what's discoverable, possibly with help from the platform's\n\t * JTAG event handlers.  (which require COMMAND_EXEC)\n\t */\n\tcommand_context_mode(CMD_CTX, COMMAND_EXEC);\n\n\tretval = command_run_line(CMD_CTX, \"transport init\");\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tretval = command_run_line(CMD_CTX, \"dap init\");\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"Examining targets...\");\n\tif (target_examine() != ERROR_OK)\n\t\tLOG_DEBUG(\"target examination failed\");\n\n\tcommand_context_mode(CMD_CTX, COMMAND_CONFIG);\n\n\tif (command_run_line(CMD_CTX, \"flash init\") != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (command_run_line(CMD_CTX, \"nand init\") != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (command_run_line(CMD_CTX, \"pld init\") != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tcommand_context_mode(CMD_CTX, COMMAND_EXEC);\n\n\t/* in COMMAND_EXEC, after target_examine(), only tpiu or only swo */\n\tif (command_run_line(CMD_CTX, \"tpiu init\") != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tjtag_poll_unmask(save_poll_mask);\n\n\t/* initialize telnet subsystem */\n\tgdb_target_add_all(all_targets);\n\n\ttarget_register_event_callback(log_target_callback_event_handler, CMD_CTX);\n\n\tif (command_run_line(CMD_CTX, \"_run_post_init_commands\") != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_add_script_search_dir_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tadd_script_search_dir(CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration openocd_command_handlers[] = {\n\t{\n\t\t.name = \"version\",\n\t\t.handler = handler_version_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"show program version\",\n\t\t.usage = \"[git]\",\n\t},\n\t{\n\t\t.name = \"noinit\",\n\t\t.handler = &handle_noinit_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Prevent 'init' from being called at startup.\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.handler = &handle_init_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Initializes configured targets and servers.  \"\n\t\t\t\"Changes command mode from CONFIG to EXEC.  \"\n\t\t\t\"Unless 'noinit' is called, this command is \"\n\t\t\t\"called automatically at the end of startup.\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"add_script_search_dir\",\n\t\t.handler = &handle_add_script_search_dir_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"dir to search for config files and scripts\",\n\t\t.usage = \"<directory>\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int openocd_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, openocd_command_handlers);\n}\n\nstruct command_context *global_cmd_ctx;\n\nstatic struct command_context *setup_command_handler(Jim_Interp *interp)\n{\n\tlog_init();\n\tLOG_DEBUG(\"log_init: complete\");\n\n\tstruct command_context *cmd_ctx = command_init(openocd_startup_tcl, interp);\n\n\t/* register subsystem commands */\n\ttypedef int (*command_registrant_t)(struct command_context *cmd_ctx_value);\n\tstatic const command_registrant_t command_registrants[] = {\n\t\t&openocd_register_commands,\n\t\t&server_register_commands,\n\t\t&gdb_register_commands,\n\t\t&log_register_commands,\n\t\t&rtt_server_register_commands,\n\t\t&transport_register_commands,\n\t\t&adapter_register_commands,\n\t\t&target_register_commands,\n\t\t&flash_register_commands,\n\t\t&nand_register_commands,\n\t\t&pld_register_commands,\n\t\t&cti_register_commands,\n\t\t&dap_register_commands,\n\t\t&arm_tpiu_swo_register_commands,\n\t\tNULL\n\t};\n\tfor (unsigned i = 0; command_registrants[i]; i++) {\n\t\tint retval = (*command_registrants[i])(cmd_ctx);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_done(cmd_ctx);\n\t\t\treturn NULL;\n\t\t}\n\t}\n\tLOG_DEBUG(\"command registration: complete\");\n\n\tLOG_OUTPUT(OPENOCD_VERSION \"\\n\"\n\t\t\"Licensed under GNU GPL v2\\n\");\n\n\tglobal_cmd_ctx = cmd_ctx;\n\n\treturn cmd_ctx;\n}\n\n/** OpenOCD runtime meat that can become single-thread in future. It parse\n * commandline, reads configuration, sets up the target and starts server loop.\n * Commandline arguments are passed into this function from openocd_main().\n */\nstatic int openocd_thread(int argc, char *argv[], struct command_context *cmd_ctx)\n{\n\tint ret;\n\n\tif (parse_cmdline_args(cmd_ctx, argc, argv) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (server_preinit() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tret = parse_config_file(cmd_ctx);\n\tif (ret == ERROR_COMMAND_CLOSE_CONNECTION) {\n\t\tserver_quit(); /* gdb server may be initialized by -c init */\n\t\treturn ERROR_OK;\n\t} else if (ret != ERROR_OK) {\n\t\tserver_quit(); /* gdb server may be initialized by -c init */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = server_init(cmd_ctx);\n\tif (ret != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (init_at_startup) {\n\t\tret = command_run_line(cmd_ctx, \"init\");\n\t\tif (ret != ERROR_OK) {\n\t\t\tserver_quit();\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tret = server_loop(cmd_ctx);\n\n\tint last_signal = server_quit();\n\tif (last_signal != ERROR_OK)\n\t\treturn last_signal;\n\n\tif (ret != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\n/* normally this is the main() function entry, but if OpenOCD is linked\n * into application, then this fn will not be invoked, but rather that\n * application will have it's own implementation of main(). */\nint openocd_main(int argc, char *argv[])\n{\n\tint ret;\n\n\t/* initialize commandline interface */\n\tstruct command_context *cmd_ctx;\n\n\tcmd_ctx = setup_command_handler(NULL);\n\n\tif (util_init(cmd_ctx) != ERROR_OK)\n\t\treturn EXIT_FAILURE;\n\n\tif (rtt_init() != ERROR_OK)\n\t\treturn EXIT_FAILURE;\n\n\tLOG_OUTPUT(\"For bug reports, read\\n\\t\"\n\t\t\"http://openocd.org/doc/doxygen/bugs.html\"\n\t\t\"\\n\");\n\n\tcommand_context_mode(cmd_ctx, COMMAND_CONFIG);\n\tcommand_set_output_handler(cmd_ctx, configuration_output_handler, NULL);\n\n\tserver_host_os_entry();\n\n\t/* Start the executable meat that can evolve into thread in future. */\n\tret = openocd_thread(argc, argv, cmd_ctx);\n\n\tflash_free_all_banks();\n\tgdb_service_free();\n\tarm_tpiu_swo_cleanup_all();\n\tserver_free();\n\n\tunregister_all_commands(cmd_ctx, NULL);\n\thelp_del_all_commands(cmd_ctx);\n\n\t/* free all DAP and CTI objects */\n\tarm_cti_cleanup_all();\n\tdap_cleanup_all();\n\n\tadapter_quit();\n\n\tserver_host_os_close();\n\n\t/* Shutdown commandline interface */\n\tcommand_exit(cmd_ctx);\n\n\trtt_exit();\n\tfree_config();\n\n\tlog_exit();\n\n\tif (ret == ERROR_FAIL)\n\t\treturn EXIT_FAILURE;\n\telse if (ret != ERROR_OK)\n\t\texit_on_signal(ret);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/openocd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath <Dominic.Rath@gmx.de>              *\n *   Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>          *\n ***************************************************************************/\n\n#ifndef OPENOCD_OPENOCD_H\n#define OPENOCD_OPENOCD_H\n\n/**\n * Different applications can define this entry point to override\n * the default openocd main function.  On most systems, this will be\n * defined in src/openocd.c.\n * @param argc normally passed from main()\n * @param argv normally passed from main()\n * @returns return code for main()\n */\nint openocd_main(int argc, char *argv[]);\n\n#endif /* OPENOCD_OPENOCD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libpld.la\n%C%_libpld_la_SOURCES = \\\n\t%D%/certus.c \\\n\t%D%/ecp2_3.c \\\n\t%D%/ecp5.c \\\n\t%D%/efinix.c \\\n\t%D%/gatemate.c \\\n\t%D%/gowin.c \\\n\t%D%/intel.c \\\n\t%D%/lattice.c \\\n\t%D%/lattice_bit.c \\\n\t%D%/pld.c \\\n\t%D%/raw_bit.c \\\n\t%D%/xilinx_bit.c \\\n\t%D%/virtex2.c \\\n\t%D%/certus.h \\\n\t%D%/ecp2_3.h \\\n\t%D%/ecp5.h \\\n\t%D%/lattice.h \\\n\t%D%/lattice_bit.h \\\n\t%D%/lattice_cmd.h \\\n\t%D%/pld.h \\\n\t%D%/raw_bit.h \\\n\t%D%/xilinx_bit.h \\\n\t%D%/virtex2.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/certus.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"certus.h\"\n#include \"lattice.h\"\n#include \"lattice_cmd.h\"\n\n#define LSC_ENABLE_X    0x74\n#define LSC_REFRESH     0x79\n#define LSC_DEVICE_CTRL 0x7D\n\nint lattice_certus_read_status(struct jtag_tap *tap, uint64_t *status, uint64_t out)\n{\n\treturn lattice_read_u64_register(tap, LSC_READ_STATUS, status, out);\n}\n\nint lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)\n{\n\treturn lattice_read_u32_register(tap, READ_USERCODE, usercode, out, false);\n}\n\nint lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)\n{\n\tLOG_ERROR(\"Not supported to write usercode on certus devices\");\n\treturn ERROR_FAIL;\n}\n\nstatic int lattice_certus_enable_transparent_mode(struct jtag_tap *tap)\n{\n\tstruct scan_field field;\n\n\tint retval = lattice_set_instr(tap, LSC_ENABLE_X, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t buffer = 0x0;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_certus_erase_device(struct lattice_pld_device *lattice_device)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_set_instr(tap, LSC_DEVICE_CTRL, TAP_IRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field;\n\tuint8_t buffer = 8;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_set_instr(tap, LSC_DEVICE_CTRL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tbuffer = 0;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_set_instr(tap, ISC_ERASE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tbuffer = 0;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(100, TAP_IDLE);\n\tjtag_add_sleep(5000);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check done is cleared and fail is cleared */\n\tconst uint64_t status_done_flag =  0x100;\n\tconst uint64_t status_fail_flag = 0x2000;\n\treturn lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_done_flag | status_fail_flag);\n}\n\nstatic int lattice_certus_enable_programming(struct jtag_tap *tap)\n{\n\tstruct scan_field field;\n\n\tint retval = lattice_set_instr(tap, LSC_REFRESH, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tuint8_t buffer = 0;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_certus_init_address(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, LSC_INIT_ADDRESS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_certus_exit_programming_mode(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\tretval = lattice_set_instr(tap, BYPASS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(100, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_certus_program_config_map(struct jtag_tap *tap, struct lattice_bit_file *bit_file)\n{\n\tstruct scan_field field;\n\n\tint retval = lattice_set_instr(tap, LSC_BITSTREAM_BURST, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfield.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;\n\tfield.out_value = bit_file->raw_bit.data + bit_file->offset;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nint lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_preload(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*  check password protection is disabled */\n\tconst uint64_t status_pwd_protection = 0x20000;\n\tretval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_pwd_protection);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Password protection is set\");\n\t\treturn retval;\n\t}\n\n\tretval = lattice_certus_enable_transparent_mode(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check the SRAM Erase Lock */\n\tconst uint64_t status_otp = 0x40;\n\tretval = lattice_verify_status_register_u64(lattice_device, 0x0, status_otp, status_otp);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"NV User Feature Sector OTP is Set\");\n\t\treturn retval;\n\t}\n\n\t/* Check the SRAM Lock */\n\tconst uint64_t status_write_protected = 0x400;\n\tretval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x0, status_write_protected);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"NV User Feature Sector OTP is Set\");\n\t\treturn retval;\n\t}\n\n\tretval = lattice_certus_enable_programming(tap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed to enable programming mode\");\n\t\treturn retval;\n\t}\n\n\tretval = lattice_certus_erase_device(lattice_device);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"erasing device failed\");\n\t\treturn retval;\n\t}\n\n\tretval = lattice_certus_init_address(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_certus_program_config_map(tap, bit_file);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tconst uint32_t expected = 0x100; // done\n\tconst uint32_t mask = expected |\n\t\t\t0x3000 | // Busy Flag and Fail Flag\n\t\t\t0xf000000; // BSE Error\n\tretval = lattice_verify_status_register_u64(lattice_device, 0x0, 0x100, mask);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn lattice_certus_exit_programming_mode(tap);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/certus.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_CERTUS_H\n#define OPENOCD_PLD_CERTUS_H\n\n#include \"lattice.h\"\n\nint lattice_certus_read_status(struct jtag_tap *tap, uint64_t *status, uint64_t out);\nint lattice_certus_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);\nint lattice_certus_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);\nint lattice_certus_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);\n\n#endif /* OPENOCD_PLD_CERTUS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/ecp2_3.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"ecp2_3.h\"\n#include \"lattice.h\"\n\n#define LSCC_REFRESH         0x23\n#define ISC_ENABLE           0x15\n#define LSCC_RESET_ADDRESS   0x21\n#define ISC_PROGRAM_USERCODE 0x1A\n#define ISC_ERASE            0x03\n#define READ_USERCODE        0x17\n#define ISC_DISABLE          0x1E\n#define LSCC_READ_STATUS     0x53\n#define LSCC_BITSTREAM_BURST 0x02\n\n#define STATUS_DONE_BIT        0x00020000\n#define STATUS_ERROR_BITS_ECP2 0x00040003\n#define STATUS_ERROR_BITS_ECP3 0x00040007\n#define REGISTER_ALL_BITS_1    0xffffffff\n#define REGISTER_ALL_BITS_0    0x00000000\n\nint lattice_ecp2_3_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle)\n{\n\treturn lattice_read_u32_register(tap, LSCC_READ_STATUS, status, out, do_idle);\n}\n\nint lattice_ecp2_3_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)\n{\n\treturn lattice_read_u32_register(tap, READ_USERCODE, usercode, out, false);\n}\n\nint lattice_ecp2_3_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(20000);\n\n\tretval = lattice_set_instr(tap, ISC_PROGRAM_USERCODE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field;\n\tuint8_t buffer[4];\n\th_u32_to_le(buffer, usercode);\n\tfield.num_bits = 32;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\n\tretval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(200000);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn lattice_verify_usercode(lattice_device, 0x0, usercode, REGISTER_ALL_BITS_1);\n}\n\nstatic int lattice_ecp2_3_erase_device(struct lattice_pld_device *lattice_device)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\t/* program user code with all bits set */\n\tint retval = lattice_set_instr(tap, ISC_PROGRAM_USERCODE, TAP_IRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tstruct scan_field field;\n\tuint8_t buffer[4] = {0xff, 0xff, 0xff, 0xff};\n\tfield.num_bits = 32;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\n\t/* verify every bit is set */\n\tconst uint32_t out = REGISTER_ALL_BITS_1;\n\tconst uint32_t mask = REGISTER_ALL_BITS_1;\n\tconst uint32_t expected_pre = REGISTER_ALL_BITS_1;\n\tretval = lattice_verify_usercode(lattice_device, out, expected_pre, mask);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_set_instr(tap, ISC_ERASE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tif (lattice_device->family == LATTICE_ECP2)\n\t\tjtag_add_sleep(100000);\n\telse\n\t\tjtag_add_sleep(2000000);\n\n\tretval = lattice_set_instr(tap, LSCC_RESET_ADDRESS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\n\t/* after erasing check all bits in user register are cleared */\n\tconst uint32_t expected_post = REGISTER_ALL_BITS_0;\n\treturn lattice_verify_usercode(lattice_device, out, expected_post, mask);\n}\n\nstatic int lattice_ecp2_3_program_config_map(struct lattice_pld_device *lattice_device,\n\t\t\t\t\t\t\t\t\t\t\tstruct lattice_bit_file *bit_file)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_set_instr(tap, LSCC_RESET_ADDRESS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\n\tstruct scan_field field;\n\tretval = lattice_set_instr(tap, LSCC_BITSTREAM_BURST, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tfield.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;\n\tfield.out_value = bit_file->raw_bit.data + bit_file->offset;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(256, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_ecp2_3_exit_programming_mode(struct lattice_pld_device *lattice_device)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(200000);\n\tretval = lattice_set_instr(tap, BYPASS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(100, TAP_IDLE);\n\tjtag_add_sleep(1000);\n\treturn jtag_execute_queue();\n}\n\nint lattice_ecp2_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_preload(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enable the programming mode */\n\tretval = lattice_set_instr(tap, LSCC_REFRESH, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(20000);\n\n\t/* Erase the device */\n\tretval = lattice_ecp2_3_erase_device(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Program Fuse Map */\n\tretval = lattice_ecp2_3_program_config_map(lattice_device, bit_file);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp2_3_exit_programming_mode(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t out = REGISTER_ALL_BITS_1;\n\tconst uint32_t mask = STATUS_DONE_BIT | STATUS_ERROR_BITS_ECP2;\n\tconst uint32_t expected = STATUS_DONE_BIT;\n\treturn lattice_verify_status_register_u32(lattice_device, out, expected, mask, false);\n}\n\nint lattice_ecp3_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\t/* Program Bscan register */\n\tint retval = lattice_preload(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enable the programming mode */\n\tretval = lattice_set_instr(tap, LSCC_REFRESH, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(500000);\n\tretval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(20000);\n\n\tretval = lattice_ecp2_3_erase_device(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Program Fuse Map */\n\tretval = lattice_ecp2_3_program_config_map(lattice_device, bit_file);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp2_3_exit_programming_mode(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t out = REGISTER_ALL_BITS_1;\n\tconst uint32_t mask = STATUS_DONE_BIT | STATUS_ERROR_BITS_ECP3;\n\tconst uint32_t expected = STATUS_DONE_BIT;\n\treturn lattice_verify_status_register_u32(lattice_device, out, expected, mask, false);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/ecp2_3.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_ECP2_3_H\n#define OPENOCD_PLD_ECP2_3_H\n\n#include \"lattice.h\"\n\nint lattice_ecp2_3_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle);\nint lattice_ecp2_3_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);\nint lattice_ecp2_3_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);\nint lattice_ecp2_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);\nint lattice_ecp3_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);\n\n#endif /* OPENOCD_PLD_ECP2_3_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/ecp5.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"ecp5.h\"\n#include \"lattice.h\"\n#include \"lattice_cmd.h\"\n\n#define ISC_PROGRAM_USERCODE 0xC2\n\n#define STATUS_DONE_BIT        0x00000100\n#define STATUS_ERROR_BITS      0x00020040\n#define STATUS_FEA_OTP         0x00004000\n#define STATUS_FAIL_FLAG       0x00002000\n#define STATUS_BUSY_FLAG       0x00001000\n#define REGISTER_ALL_BITS_1    0xffffffff\n\nint lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle)\n{\n\treturn lattice_read_u32_register(tap, LSC_READ_STATUS, status, out, do_idle);\n}\n\nint lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)\n{\n\treturn lattice_read_u32_register(tap, READ_USERCODE, usercode, out, true);\n}\n\nint lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(20000);\n\n\tretval = lattice_set_instr(tap, ISC_PROGRAM_USERCODE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t buffer[4];\n\tstruct scan_field field;\n\th_u32_to_le(buffer, usercode);\n\tfield.num_bits = 32;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(2000);\n\n\tretval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(5, TAP_IDLE);\n\tjtag_add_sleep(200000);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn lattice_verify_usercode(lattice_device, 0x0, usercode, REGISTER_ALL_BITS_1);\n}\n\nstatic int lattice_ecp5_enable_sram_programming(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field;\n\tuint8_t buffer = 0x0;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(10000);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_ecp5_erase_sram(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field;\n\tuint8_t buffer = 1;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(200000);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_ecp5_init_address(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, LSC_INIT_ADDRESS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field;\n\tuint8_t buffer = 1;\n\tfield.num_bits = 8;\n\tfield.out_value = &buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(10000);\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_ecp5_program_config_map(struct jtag_tap *tap, struct lattice_bit_file *bit_file)\n{\n\tint retval = lattice_set_instr(tap, LSC_BITSTREAM_BURST, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(10000);\n\n\tstruct scan_field field;\n\tfield.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;\n\tfield.out_value = bit_file->raw_bit.data + bit_file->offset;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tretval = lattice_set_instr(tap, BYPASS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(100, TAP_IDLE);\n\tjtag_add_sleep(10000);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int lattice_ecp5_exit_programming_mode(struct jtag_tap *tap)\n{\n\tint retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(200000);\n\tretval = lattice_set_instr(tap, BYPASS, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2, TAP_IDLE);\n\tjtag_add_sleep(1000);\n\treturn jtag_execute_queue();\n}\n\nint lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_preload(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp5_enable_sram_programming(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t out = 0x0;\n\tconst uint32_t expected1 = 0x0;\n\tconst uint32_t mask1 = STATUS_ERROR_BITS | STATUS_FEA_OTP;\n\tretval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask1, true);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp5_erase_sram(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t mask2 = STATUS_FAIL_FLAG | STATUS_BUSY_FLAG;\n\tretval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask2, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp5_init_address(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp5_program_config_map(tap, bit_file);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_ecp5_exit_programming_mode(tap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tconst uint32_t expected2 = STATUS_DONE_BIT;\n\tconst uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG;\n\treturn lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/ecp5.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_ECP5_H\n#define OPENOCD_PLD_ECP5_H\n\n#include \"lattice.h\"\n\nint lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle);\nint lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out);\nint lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode);\nint lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file);\n\n#endif /* OPENOCD_PLD_ECP5_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/efinix.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n\n#include \"pld.h\"\n#include \"raw_bit.h\"\n\n#define PROGRAM   0x4\n#define ENTERUSER 0x7\n#define USER1     0x8\n#define USER2     0x9\n#define USER3     0xa\n#define USER4     0xb\n\nenum efinix_family_e {\n\tEFINIX_TRION,\n\tEFINIX_TITANIUM,\n\tEFINIX_UNKNOWN\n};\n\n#define TRAILING_ZEROS 4000\n#define RUNTEST_START_CYCLES 100\n#define RUNTEST_FINISH_CYCLES 100\n\nstruct efinix_device {\n\tuint32_t idcode;\n\tint num_user;\n};\n\nstruct efinix_pld_device {\n\tstruct jtag_tap *tap;\n\tenum efinix_family_e family;\n};\n\nstatic int efinix_read_bit_file(struct raw_bit_file *bit_file, const char *filename)\n{\n\tFILE *input_file = fopen(filename, \"r\");\n\tif (!input_file) {\n\t\tLOG_ERROR(\"couldn't open %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tfseek(input_file, 0, SEEK_END);\n\tlong length = ftell(input_file);\n\tfseek(input_file, 0, SEEK_SET);\n\n\tif (length < 0 || ((length % 3))) {\n\t\tfclose(input_file);\n\t\tLOG_ERROR(\"Failed to get length from file %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\tbit_file->length = DIV_ROUND_UP(length, 3);\n\n\tbit_file->data = malloc(bit_file->length);\n\tif (!bit_file->data) {\n\t\tfclose(input_file);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tbool end_detected = false;\n\tchar buffer[3];\n\tfor (size_t idx = 0; !end_detected && idx < bit_file->length; ++idx) {\n\t\tsize_t read_count = fread(buffer, sizeof(char), 3, input_file);\n\t\tend_detected = feof(input_file);\n\t\tif ((read_count == 3 && buffer[2] != '\\n') ||\n\t\t\t(read_count != 3 && !end_detected) ||\n\t\t\t(read_count != 2 && end_detected)) {\n\t\t\tfclose(input_file);\n\t\t\tfree(bit_file->data);\n\t\t\tbit_file->data = NULL;\n\t\t\tLOG_ERROR(\"unexpected line length\");\n\t\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t\t}\n\n\t\tif (!isxdigit(buffer[0]) || !isxdigit(buffer[1])) {\n\t\t\tfclose(input_file);\n\t\t\tfree(bit_file->data);\n\t\t\tbit_file->data = NULL;\n\t\t\tLOG_ERROR(\"unexpected char in hex string\");\n\t\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t\t}\n\t\tunhexify(&bit_file->data[idx], buffer, 2);\n\t}\n\n\tfclose(input_file);\n\n\treturn ERROR_OK;\n}\n\nstatic int efinix_read_file(struct raw_bit_file *bit_file, const char *filename)\n{\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* check if binary .bin or ascii .bit/.hex */\n\tconst char *file_ending_pos = strrchr(filename, '.');\n\tif (!file_ending_pos) {\n\t\tLOG_ERROR(\"Unable to detect filename suffix\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (strcasecmp(file_ending_pos, \".bin\") == 0) {\n\t\treturn cpld_read_raw_bit_file(bit_file, filename);\n\t} else if ((strcasecmp(file_ending_pos, \".bit\") == 0) ||\n\t\t\t(strcasecmp(file_ending_pos, \".hex\") == 0)) {\n\t\treturn efinix_read_bit_file(bit_file, filename);\n\t}\n\n\tLOG_ERROR(\"Unable to detect filetype\");\n\treturn ERROR_PLD_FILE_LOAD_FAILED;\n}\n\nstatic int efinix_set_instr(struct jtag_tap *tap, uint8_t new_instr)\n{\n\tstruct scan_field field;\n\tfield.num_bits = tap->ir_length;\n\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\tfree(t);\n\treturn ERROR_OK;\n}\n\nstatic int efinix_load(struct pld_device *pld_device, const char *filename)\n{\n\tstruct raw_bit_file bit_file;\n\tstruct scan_field field[2];\n\n\tif (!pld_device || !pld_device->driver_priv)\n\t\treturn ERROR_FAIL;\n\n\tstruct efinix_pld_device *efinix_info = pld_device->driver_priv;\n\tif (!efinix_info || !efinix_info->tap)\n\t\treturn ERROR_FAIL;\n\tstruct jtag_tap *tap = efinix_info->tap;\n\n\tjtag_add_tlr();\n\n\tint retval = efinix_set_instr(tap, PROGRAM);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(RUNTEST_START_CYCLES, TAP_IDLE);\n\tretval = efinix_set_instr(tap, PROGRAM); /* fix for T20 */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = efinix_read_file(&bit_file, filename);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (size_t i = 0; i < bit_file.length; i++)\n\t\tbit_file.data[i] = flip_u32(bit_file.data[i], 8);\n\n\t/* shift in the bitstream */\n\tfield[0].num_bits = bit_file.length * 8;\n\tfield[0].out_value = bit_file.data;\n\tfield[0].in_value = NULL;\n\n\t/* followed by zeros */\n\tfield[1].num_bits = TRAILING_ZEROS;\n\tuint8_t *buf = calloc(TRAILING_ZEROS / 8, 1);\n\tif (!buf) {\n\t\tfree(bit_file.data);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield[1].out_value = buf;\n\tfield[1].in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 2, field, TAP_DRPAUSE);\n\tretval = jtag_execute_queue();\n\tfree(bit_file.data);\n\tfree(buf);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = efinix_set_instr(tap, ENTERUSER);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* entering RUN/TEST for 100 cycles */\n\tjtag_add_runtest(RUNTEST_FINISH_CYCLES, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\n\treturn retval;\n}\n\nstatic int efinix_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct efinix_pld_device *pld_device_info = pld_device->driver_priv;\n\n\tif (!pld_device_info || !pld_device_info->tap)\n\t\treturn ERROR_FAIL;\n\n\thub->tap = pld_device_info->tap;\n\n\tif (pld_device_info->family == EFINIX_UNKNOWN) {\n\t\tLOG_ERROR(\"family unknown, please specify for 'pld create'\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint num_user = 2; /* trion */\n\tif (pld_device_info->family == EFINIX_TITANIUM)\n\t\tnum_user = 4;\n\n\tif (user_num > num_user) {\n\t\tLOG_ERROR(\"Devices has only user register 1 to %d\", num_user);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (user_num) {\n\tcase 1:\n\t\thub->user_ir_code = USER1;\n\t\tbreak;\n\tcase 2:\n\t\thub->user_ir_code = USER2;\n\t\tbreak;\n\tcase 3:\n\t\thub->user_ir_code = USER3;\n\t\tbreak;\n\tcase 4:\n\t\thub->user_ir_code = USER4;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"efinix devices only have user register 1 to %d\", num_user);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nPLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command)\n{\n\tif (CMD_ARGC != 4 && CMD_ARGC != 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tenum efinix_family_e family = EFINIX_UNKNOWN;\n\tif (CMD_ARGC == 6) {\n\t\tif (strcmp(CMD_ARGV[4], \"-family\") != 0)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tif (strcmp(CMD_ARGV[5], \"trion\") == 0) {\n\t\t\tfamily = EFINIX_TRION;\n\t\t} else if (strcmp(CMD_ARGV[5], \"titanium\") == 0) {\n\t\t\tfamily = EFINIX_TITANIUM;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"unknown family\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct efinix_pld_device *efinix_info = malloc(sizeof(struct efinix_pld_device));\n\tif (!efinix_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tefinix_info->tap = tap;\n\tefinix_info->family = family;\n\n\tpld->driver_priv = efinix_info;\n\n\treturn ERROR_OK;\n}\n\nstruct pld_driver efinix_pld = {\n\t.name = \"efinix\",\n\t.pld_create_command = &efinix_pld_create_command,\n\t.load = &efinix_load,\n\t.get_ipdbg_hub = efinix_get_ipdbg_hub,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/gatemate.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <jtag/adapter.h>\n#include \"pld.h\"\n#include \"raw_bit.h\"\n\n#define JTAG_CONFIGURE  0x06\n\nstruct gatemate_pld_device {\n\tstruct jtag_tap *tap;\n};\n\nstruct gatemate_bit_file {\n\tstruct raw_bit_file raw_file;\n\tsize_t capacity;\n};\n\nstatic int gatemate_add_byte_to_bitfile(struct gatemate_bit_file *bit_file, uint8_t byte)\n{\n\tconst size_t chunk_size = 8192;\n\tif (bit_file->raw_file.length + 1 > bit_file->capacity) {\n\t\tuint8_t *buffer;\n\t\tif (bit_file->raw_file.data)\n\t\t\tbuffer = realloc(bit_file->raw_file.data, bit_file->capacity + chunk_size);\n\t\telse\n\t\t\tbuffer = malloc(chunk_size);\n\t\tif (!buffer) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbit_file->raw_file.data = buffer;\n\t\tbit_file->capacity += chunk_size;\n\t}\n\n\tbit_file->raw_file.data[bit_file->raw_file.length++] = byte;\n\n\treturn ERROR_OK;\n}\n\nstatic int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file, const char *line_buffer, size_t nread)\n{\n\tfor (size_t idx = 0; idx < nread; ++idx) {\n\t\tif (line_buffer[idx] == ' ') {\n\t\t\tcontinue;\n\t\t} else if (line_buffer[idx] == 0) {\n\t\t\tbreak;\n\t\t} else if (idx + 1 < nread) {\n\t\t\tif (isxdigit(line_buffer[idx]) && isxdigit(line_buffer[idx + 1])) {\n\t\t\t\tuint8_t byte;\n\t\t\t\tunhexify(&byte, line_buffer + idx, 2);\n\t\t\t\tint retval = gatemate_add_byte_to_bitfile(bit_file, byte);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else if (line_buffer[idx] == '/' && line_buffer[idx + 1] == '/') {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t++idx;\n\t\t} else {\n\t\t\tLOG_ERROR(\"parsing failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int gatemate_getline(char **buffer, size_t *buf_size, FILE *input_file)\n{\n\tconst size_t chunk_size = 32;\n\tif (!*buffer)\n\t\t*buf_size = 0;\n\n\tsize_t read = 0;\n\tdo {\n\t\tif (read + 1 > *buf_size) {\n\t\t\tchar *new_buffer;\n\t\t\tif (*buffer)\n\t\t\t\tnew_buffer = realloc(*buffer, *buf_size + chunk_size);\n\t\t\telse\n\t\t\t\tnew_buffer = malloc(chunk_size);\n\t\t\tif (!new_buffer) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\t*buffer = new_buffer;\n\t\t\t*buf_size += chunk_size;\n\t\t}\n\n\t\tint c = fgetc(input_file);\n\t\tif ((c == EOF && read) || (char)c == '\\n') {\n\t\t\t(*buffer)[read++] = 0;\n\t\t\treturn read;\n\t\t} else if (c == EOF) {\n\t\t\treturn -1;\n\t\t}\n\n\t\t(*buffer)[read++] = (char)c;\n\t} while (1);\n\n\treturn -1;\n}\n\nstatic int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file, const char *filename)\n{\n\tFILE *input_file = fopen(filename, \"r\");\n\n\tif (!input_file) {\n\t\tLOG_ERROR(\"Couldn't open %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tint retval = ERROR_OK;\n\tchar *line_buffer = NULL;\n\tsize_t buffer_length = 0;\n\tint nread;\n\twhile (((nread = gatemate_getline(&line_buffer, &buffer_length, input_file)) != -1) && (retval == ERROR_OK))\n\t\tretval = gatemate_read_cfg_line(bit_file, line_buffer, (size_t)nread);\n\n\tif (line_buffer)\n\t\tfree(line_buffer);\n\n\tfclose(input_file);\n\tif (retval != ERROR_OK)\n\t\tfree(bit_file->raw_file.data);\n\treturn retval;\n}\n\nstatic int gatemate_read_file(struct gatemate_bit_file *bit_file, const char *filename)\n{\n\tmemset(bit_file, 0, sizeof(struct gatemate_bit_file));\n\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* check if binary .bit or ascii .cfg */\n\tconst char *file_suffix_pos = strrchr(filename, '.');\n\tif (!file_suffix_pos) {\n\t\tLOG_ERROR(\"Unable to detect filename suffix\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (strcasecmp(file_suffix_pos, \".bit\") == 0)\n\t\treturn cpld_read_raw_bit_file(&bit_file->raw_file, filename);\n\telse if (strcasecmp(file_suffix_pos, \".cfg\") == 0)\n\t\treturn gatemate_read_cfg_file(bit_file, filename);\n\n\tLOG_ERROR(\"Filetype not supported, expecting .bit or .cfg file\");\n\treturn ERROR_PLD_FILE_LOAD_FAILED;\n}\n\nstatic int gatemate_set_instr(struct jtag_tap *tap, uint8_t new_instr)\n{\n\tstruct scan_field field;\n\tfield.num_bits = tap->ir_length;\n\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\tjtag_add_runtest(3, TAP_IDLE);\n\tfree(t);\n\treturn ERROR_OK;\n}\n\nstatic int gatemate_load(struct pld_device *pld_device, const char *filename)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct gatemate_pld_device *gatemate_info = pld_device->driver_priv;\n\n\tif (!gatemate_info || !gatemate_info->tap)\n\t\treturn ERROR_FAIL;\n\tstruct jtag_tap *tap = gatemate_info->tap;\n\n\tstruct gatemate_bit_file bit_file;\n\tint retval = gatemate_read_file(&bit_file, filename);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = gatemate_set_instr(tap, JTAG_CONFIGURE);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\tstruct scan_field field;\n\tfield.num_bits = bit_file.raw_file.length * 8;\n\tfield.out_value = bit_file.raw_file.data;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tfree(bit_file.raw_file.data);\n\n\treturn retval;\n}\n\nPLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command)\n{\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct gatemate_pld_device *gatemate_info = malloc(sizeof(struct gatemate_pld_device));\n\tif (!gatemate_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tgatemate_info->tap = tap;\n\n\tpld->driver_priv = gatemate_info;\n\n\treturn ERROR_OK;\n}\n\nstruct pld_driver gatemate_pld = {\n\t.name = \"gatemate\",\n\t.pld_create_command = &gatemate_pld_create_command,\n\t.load = &gatemate_load,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/gowin.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <jtag/adapter.h>\n#include <helper/bits.h>\n#include \"pld.h\"\n#include \"raw_bit.h\"\n\n#define NO_OP                       0x02\n#define ERASE_SRAM                  0x05\n#define SRAM_ERASE_DONE             0x09\n#define IDCODE                      0x11\n#define ADDRESS_INITIALIZATION      0x12\n#define READ_USERCODE               0x13\n#define CONFIG_ENABLE               0x15\n#define TRANSFER_CONFIGURATION_DATA 0x17\n#define CONFIG_DISABLE              0x3A\n#define RELOAD                      0x3C\n#define STATUS_REGISTER             0x41\n#define ERASE_FLASH                 0x75\n#define ENABLE_2ND_FLASH            0x78\n\n#define USER1                       0x42\n#define USER2                       0x43\n\n#define STAUS_MASK_MEMORY_ERASE     BIT(5)\n#define STAUS_MASK_SYSTEM_EDIT_MODE BIT(7)\n\nstruct gowin_pld_device {\n\tstruct jtag_tap *tap;\n};\n\nstruct gowin_bit_file {\n\tstruct raw_bit_file raw_file;\n\tsize_t capacity;\n\tuint32_t id;\n\tuint16_t stored_checksum;\n\tint compressed;\n\tint crc_en;\n\tuint16_t checksum;\n\tuint8_t replace8x;\n\tuint8_t replace4x;\n\tuint8_t replace2x;\n};\n\nstatic uint64_t gowin_read_fs_file_bitsequence(const char *bits, int length)\n{\n\tuint64_t res = 0;\n\tfor (int i = 0; i < length; i++)\n\t\tres = (res << 1) | (*bits++ == '1' ? 1 : 0);\n\treturn res;\n}\n\nstatic int gowin_add_byte_to_bit_file(struct gowin_bit_file *bit_file, uint8_t byte)\n{\n\tif (bit_file->raw_file.length + 1 > bit_file->capacity) {\n\t\tuint8_t *buffer;\n\t\tif (bit_file->raw_file.data)\n\t\t\tbuffer = realloc(bit_file->raw_file.data, bit_file->capacity + 8192);\n\t\telse\n\t\t\tbuffer = malloc(8192);\n\t\tif (!buffer) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbit_file->raw_file.data = buffer;\n\t\tbit_file->capacity += 8192;\n\t}\n\n\tbit_file->raw_file.data[bit_file->raw_file.length++] = byte;\n\n\treturn ERROR_OK;\n}\n\nstatic int gowin_read_fs_file_header(struct gowin_bit_file *bit_file, FILE *stream)\n{\n\tif (!bit_file)\n\t\treturn ERROR_FAIL;\n\n\tint end_of_header = 0;\n\twhile (!end_of_header) {\n\t\tchar buffer[256];\n\t\tchar *line = fgets(buffer, 256, stream);\n\t\tif (!line || feof(stream) || ferror(stream))\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (line[0] == '/')\n\t\t\tcontinue;\n\n\t\tsize_t line_length = strlen(line);\n\t\tif (line[line_length - 1] != '\\n')\n\t\t\treturn ERROR_FAIL;\n\t\tline_length--;\n\n\t\tfor (unsigned int i = 0; i < line_length; i += 8) {\n\t\t\tuint8_t byte = gowin_read_fs_file_bitsequence(line + i, 8);\n\t\t\tint retval = gowin_add_byte_to_bit_file(bit_file, byte);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tuint8_t key = gowin_read_fs_file_bitsequence(line, 8);\n\t\tline += 8;\n\t\tuint64_t value = gowin_read_fs_file_bitsequence(line, line_length - 8);\n\n\t\tif (key == 0x06) {\n\t\t\tbit_file->id = value & 0xffffffff;\n\t\t} else if (key == 0x3B) {\n\t\t\tend_of_header = 1;\n\t\t\tbit_file->crc_en = (value & BIT(23)) ? 1 : 0;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int gowin_read_fs_file(struct gowin_bit_file *bit_file, const char *filename)\n{\n\tFILE *input_file = fopen(filename, \"r\");\n\n\tif (!input_file) {\n\t\tLOG_ERROR(\"Couldn't open %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tint retval = gowin_read_fs_file_header(bit_file, input_file);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file->raw_file.data);\n\t\tfclose(input_file);\n\t\treturn retval;\n\t}\n\n\tchar digits_buffer[9]; /* 8 + 1 trailing zero */\n\tdo {\n\t\tchar *digits = fgets(digits_buffer, 9, input_file);\n\t\tif (feof(input_file))\n\t\t\tbreak;\n\t\tif (!digits || ferror(input_file)) {\n\t\t\tfree(bit_file->raw_file.data);\n\t\t\tfclose(input_file);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (digits[0] == '\\n')\n\t\t\tcontinue;\n\n\t\tif (strlen(digits) != 8) {\n\t\t\tfree(bit_file->raw_file.data);\n\t\t\tfclose(input_file);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tuint8_t byte = gowin_read_fs_file_bitsequence(digits, 8);\n\t\tretval = gowin_add_byte_to_bit_file(bit_file, byte);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(bit_file->raw_file.data);\n\t\t\tfclose(input_file);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while (1);\n\n\tfclose(input_file);\n\treturn ERROR_OK;\n}\n\nstatic int gowin_read_file(struct gowin_bit_file *bit_file, const char *filename, bool *is_fs)\n{\n\tmemset(bit_file, 0, sizeof(struct gowin_bit_file));\n\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst char *file_suffix_pos = strrchr(filename, '.');\n\tif (!file_suffix_pos) {\n\t\tLOG_ERROR(\"Unable to detect filename suffix\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\t/* check if binary .bin or ascii .fs */\n\tif (strcasecmp(file_suffix_pos, \".bin\") == 0) {\n\t\t*is_fs = false;\n\t\treturn cpld_read_raw_bit_file(&bit_file->raw_file, filename);\n\t} else if (strcasecmp(file_suffix_pos, \".fs\") == 0) {\n\t\t*is_fs = true;\n\t\treturn gowin_read_fs_file(bit_file, filename);\n\t}\n\n\tLOG_ERROR(\"Filetype not supported, expecting .fs or .bin file\");\n\treturn ERROR_PLD_FILE_LOAD_FAILED;\n}\n\nstatic int gowin_set_instr(struct jtag_tap *tap, uint8_t new_instr)\n{\n\tstruct scan_field field;\n\tfield.num_bits = tap->ir_length;\n\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\tjtag_add_runtest(3, TAP_IDLE);\n\tfree(t);\n\treturn ERROR_OK;\n}\n\nstatic int gowin_read_register(struct jtag_tap *tap, uint32_t reg, uint32_t *result)\n{\n\tstruct scan_field field;\n\n\tint retval = gowin_set_instr(tap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t buf[4] = {0};\n\tfield.check_mask = NULL;\n\tfield.check_value = NULL;\n\tfield.num_bits = 32;\n\tfield.out_value = buf;\n\tfield.in_value = buf;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\t*result = le_to_h_u32(buf);\n\treturn retval;\n}\n\nstatic int gowin_check_status_flag(struct jtag_tap *tap, uint32_t mask, uint32_t flag)\n{\n\tuint32_t status = 0;\n\n\tint retries = 0;\n\tdo {\n\t\tint retval = gowin_read_register(tap, STATUS_REGISTER, &status);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (retries++ == 100000)\n\t\t\treturn ERROR_FAIL;\n\t} while ((status & mask) != flag);\n\n\treturn ERROR_OK;\n}\n\nstatic int gowin_enable_config(struct jtag_tap *tap)\n{\n\tint retval = gowin_set_instr(tap, CONFIG_ENABLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn gowin_check_status_flag(tap, STAUS_MASK_SYSTEM_EDIT_MODE, STAUS_MASK_SYSTEM_EDIT_MODE);\n}\n\nstatic int gowin_disable_config(struct jtag_tap *tap)\n{\n\tint retval = gowin_set_instr(tap, CONFIG_DISABLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn gowin_check_status_flag(tap, STAUS_MASK_SYSTEM_EDIT_MODE, 0);\n}\n\nstatic int gowin_reload(struct jtag_tap *tap)\n{\n\tint retval = gowin_set_instr(tap, RELOAD);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = gowin_set_instr(tap, NO_OP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn jtag_execute_queue();\n}\n\nstatic int gowin_runtest_idle(struct jtag_tap *tap, unsigned int frac_sec)\n{\n\tint speed = adapter_get_speed_khz() * 1000;\n\tint cycles = DIV_ROUND_UP(speed, frac_sec);\n\tjtag_add_runtest(cycles, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\nstatic int gowin_erase_sram(struct jtag_tap *tap, bool tx_erase_done)\n{\n\t/* config is already enabled */\n\tint retval = gowin_set_instr(tap, ERASE_SRAM);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = gowin_set_instr(tap, NO_OP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Delay or Run Test 2~10ms */\n\t/* 10 ms is worst case for GW2A-55 */\n\tjtag_add_sleep(10000);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = gowin_check_status_flag(tap, STAUS_MASK_MEMORY_ERASE,\n\t\t\t\t\t\t\t\t\tSTAUS_MASK_MEMORY_ERASE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (tx_erase_done) {\n\t\tretval = gowin_set_instr(tap, SRAM_ERASE_DONE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = gowin_set_instr(tap, NO_OP);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* gen clock cycles in RUN/IDLE for 500us -> 1/500us = 2000/s */\n\t\tretval = gowin_runtest_idle(tap, 2000);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = gowin_set_instr(tap, NO_OP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn jtag_execute_queue();\n}\n\nstatic int gowin_load_to_sram(struct pld_device *pld_device, const char *filename)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct gowin_pld_device *gowin_info = pld_device->driver_priv;\n\n\tif (!gowin_info || !gowin_info->tap)\n\t\treturn ERROR_FAIL;\n\tstruct jtag_tap *tap = gowin_info->tap;\n\n\tbool is_fs = false;\n\tstruct gowin_bit_file bit_file;\n\tint retval = gowin_read_file(&bit_file, filename, &is_fs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < bit_file.raw_file.length; i++)\n\t\tbit_file.raw_file.data[i] = flip_u32(bit_file.raw_file.data[i], 8);\n\n\tuint32_t id;\n\tretval = gowin_read_register(tap, IDCODE, &id);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\tif (is_fs && id != bit_file.id) {\n\t\tfree(bit_file.raw_file.data);\n\t\tLOG_ERROR(\"Id on device (0x%8.8\" PRIx32 \") and id in bit-stream (0x%8.8\" PRIx32 \") don't match.\",\n\t\t\tid, bit_file.id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = gowin_enable_config(tap);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\tretval = gowin_erase_sram(tap, false);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\tretval = gowin_set_instr(tap, ADDRESS_INITIALIZATION);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\tretval = gowin_set_instr(tap, TRANSFER_CONFIGURATION_DATA);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\t/* scan out the bitstream */\n\tstruct scan_field field;\n\tfield.num_bits = bit_file.raw_file.length * 8;\n\tfield.out_value = bit_file.raw_file.data;\n\tfield.in_value = bit_file.raw_file.data;\n\tjtag_add_dr_scan(gowin_info->tap, 1, &field, TAP_IDLE);\n\tjtag_add_runtest(3, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.raw_file.data);\n\t\treturn retval;\n\t}\n\n\tretval = gowin_disable_config(tap);\n\tfree(bit_file.raw_file.data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = gowin_set_instr(gowin_info->tap, NO_OP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_execute_queue();\n\n\treturn retval;\n}\n\nstatic int gowin_read_register_command(struct pld_device *pld_device, uint32_t cmd, uint32_t *value)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct gowin_pld_device *gowin_info = pld_device->driver_priv;\n\n\tif (!gowin_info || !gowin_info->tap)\n\t\treturn ERROR_FAIL;\n\n\treturn gowin_read_register(gowin_info->tap, cmd, value);\n}\n\nstatic int gowin_reload_command(struct pld_device *pld_device)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct gowin_pld_device *gowin_info = pld_device->driver_priv;\n\n\tif (!gowin_info || !gowin_info->tap)\n\t\treturn ERROR_FAIL;\n\n\treturn gowin_reload(gowin_info->tap);\n}\n\nstatic int gowin_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct gowin_pld_device *pld_device_info = pld_device->driver_priv;\n\n\tif (!pld_device_info || !pld_device_info->tap)\n\t\treturn ERROR_FAIL;\n\n\thub->tap = pld_device_info->tap;\n\n\tif (user_num == 1) {\n\t\thub->user_ir_code = USER1;\n\t} else if (user_num == 2) {\n\t\thub->user_ir_code = USER2;\n\t} else {\n\t\tLOG_ERROR(\"gowin devices only have user register 1 & 2\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(gowin_read_status_command_handler)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t status = 0;\n\tint retval = gowin_read_register_command(device, STATUS_REGISTER, &status);\n\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"0x%8.8\" PRIx32, status);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(gowin_read_user_register_command_handler)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t user_reg = 0;\n\tint retval = gowin_read_register_command(device, READ_USERCODE, &user_reg);\n\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"0x%8.8\" PRIx32, user_reg);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(gowin_reload_command_handler)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn gowin_reload_command(device);\n}\n\nstatic const struct command_registration gowin_exec_command_handlers[] = {\n\t{\n\t\t.name = \"read_status\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = gowin_read_status_command_handler,\n\t\t.help = \"reading status register from FPGA\",\n\t\t.usage = \"pld_name\",\n\t}, {\n\t\t.name = \"read_user\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = gowin_read_user_register_command_handler,\n\t\t.help = \"reading user register from FPGA\",\n\t\t.usage = \"pld_name\",\n\t}, {\n\t\t.name = \"reload\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = gowin_reload_command_handler,\n\t\t.help = \"reloading bitstream from flash to SRAM\",\n\t\t.usage = \"pld_name\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration gowin_command_handler[] = {\n\t{\n\t\t.name = \"gowin\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"gowin specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = gowin_exec_command_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nPLD_CREATE_COMMAND_HANDLER(gowin_pld_create_command)\n{\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct gowin_pld_device *gowin_info = malloc(sizeof(struct gowin_pld_device));\n\tif (!gowin_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tgowin_info->tap = tap;\n\n\tpld->driver_priv = gowin_info;\n\n\treturn ERROR_OK;\n}\n\nstruct pld_driver gowin_pld = {\n\t.name = \"gowin\",\n\t.commands = gowin_command_handler,\n\t.pld_create_command = &gowin_pld_create_command,\n\t.load = &gowin_load_to_sram,\n\t.get_ipdbg_hub = gowin_get_ipdbg_hub,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/intel.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <jtag/adapter.h>\n#include <helper/system.h>\n#include <helper/log.h>\n\n#include \"pld.h\"\n#include \"raw_bit.h\"\n\n#define BYPASS 0x3FF\n#define USER0  0x00C\n#define USER1  0x00E\n\nenum intel_family_e {\n\tINTEL_CYCLONEIII,\n\tINTEL_CYCLONEIV,\n\tINTEL_CYCLONEV,\n\tINTEL_CYCLONE10,\n\tINTEL_ARRIAII,\n\tINTEL_UNKNOWN\n};\n\nstruct intel_pld_device {\n\tstruct jtag_tap *tap;\n\tunsigned int boundary_scan_length;\n\tint checkpos;\n\tenum intel_family_e family;\n};\n\nstruct intel_device_parameters_elem {\n\tuint32_t id;\n\tunsigned int boundary_scan_length;\n\tint checkpos;\n\tenum intel_family_e family;\n};\n\nstatic const struct intel_device_parameters_elem intel_device_parameters[] = {\n\t{0x020f10dd,  603,  226, INTEL_CYCLONEIII}, /* EP3C5 EP3C10 */\n\t{0x020f20dd, 1080,  409, INTEL_CYCLONEIII}, /* EP3C16 */\n\t{0x020f30dd,  732,  286, INTEL_CYCLONEIII}, /* EP3C25 */\n\t{0x020f40dd, 1632,  604, INTEL_CYCLONEIII}, /* EP3C40 */\n\t{0x020f50dd, 1164,  442, INTEL_CYCLONEIII}, /* EP3C55 */\n\t{0x020f60dd, 1314,  502, INTEL_CYCLONEIII}, /* EP3C80 */\n\t{0x020f70dd, 1620,  613, INTEL_CYCLONEIII}, /* EP3C120*/\n\t{0x027010dd, 1314,  226, INTEL_CYCLONEIII}, /* EP3CLS70 */\n\t{0x027000dd, 1314,  226, INTEL_CYCLONEIII}, /* EP3CLS100 */\n\t{0x027030dd, 1314,  409, INTEL_CYCLONEIII}, /* EP3CLS150 */\n\t{0x027020dd, 1314,  409, INTEL_CYCLONEIII}, /* EP3CLS200 */\n\n\t{0x020f10dd,  603,  226, INTEL_CYCLONEIV}, /* EP4CE6 EP4CE10 */\n\t{0x020f20dd, 1080,  409, INTEL_CYCLONEIV}, /* EP4CE15 */\n\t{0x020f30dd,  732,  286, INTEL_CYCLONEIV}, /* EP4CE22 */\n\t{0x020f40dd, 1632,  604, INTEL_CYCLONEIV}, /* EP4CE30 EP4CE40 */\n\t{0x020f50dd, 1164,  442, INTEL_CYCLONEIV}, /* EP4CE55 */\n\t{0x020f60dd, 1314,  502, INTEL_CYCLONEIV}, /* EP4CE75 */\n\t{0x020f70dd, 1620,  613, INTEL_CYCLONEIV}, /* EP4CE115 */\n\t{0x028010dd,  260,  229, INTEL_CYCLONEIV}, /* EP4CGX15 */\n\t{0x028120dd,  494,  463, INTEL_CYCLONEIV}, /* EP4CGX22 */\n\t{0x028020dd,  494,  463, INTEL_CYCLONEIV}, /* EP4CGX30 */\n\t{0x028230dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX30 */\n\t{0x028130dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX50 */\n\t{0x028030dd, 1006,  943, INTEL_CYCLONEIV}, /* EP4CGX75 */\n\t{0x028140dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX110 */\n\t{0x028040dd, 1495, 1438, INTEL_CYCLONEIV}, /* EP4CGX150 */\n\n\t{0x02b150dd,  864, 163, INTEL_CYCLONEV}, /* 5CEBA2F23 5CEBA2F17 5CEFA2M13 5CEFA2F23 5CEBA2U15 5CEFA2U19 5CEBA2U19 */\n\t{0x02d020dd, 1485,  19, INTEL_CYCLONEV}, /* 5CSXFC6D6F31 5CSTFD6D5F31 5CSEBA6U23 5CSEMA6U23 5CSEBA6U19 5CSEBA6U23\n\t\t\t\t\t\t\t\t\t\t\t5CSEBA6U19 5CSEMA6F31 5CSXFC6C6U23 */\n\t{0x02b040dd, 1728,  -1, INTEL_CYCLONEV}, /* 5CGXFC9EF35 5CGXBC9AU19 5CGXBC9CF23 5CGTFD9CF23 5CGXFC9AU19 5CGXFC9CF23\n\t\t\t\t\t\t\t\t\t\t\t5CGXFC9EF31 5CGXFC9DF27 5CGXBC9DF27 5CGXBC9EF31 5CGTFD9EF31 5CGTFD9EF35\n\t\t\t\t\t\t\t\t\t\t\t5CGTFD9AU19 5CGXBC9EF35 5CGTFD9DF27 */\n\t{0x02b050dd,  864, 163, INTEL_CYCLONEV}, /* 5CEFA4U19 5CEFA4F23 5CEFA4M13 5CEBA4F17 5CEBA4U15 5CEBA4U19 5CEBA4F23 */\n\t{0x02b030dd, 1488,  19, INTEL_CYCLONEV}, /* 5CGXBC7CU19 5CGTFD7CU19 5CGTFD7DF27 5CGXFC7BM15 5CGXFC7DF27 5CGXFC7DF31\n\t\t\t\t\t\t\t\t\t\t\t5CGTFD7CF23 5CGXBC7CF23 5CGXBC7DF31 5CGTFD7BM15 5CGXFC7CU19 5CGTFD7DF31\n\t\t\t\t\t\t\t\t\t\t\t5CGXBC7BM15 5CGXFC7CF23 5CGXBC7DF27 */\n\t{0x02d120dd, 1485,  -1, INTEL_CYCLONEV}, /* 5CSEBA5U23 5CSEBA5U23 5CSTFD5D5F31 5CSEBA5U19 5CSXFC5D6F31 5CSEMA5U23\n\t\t\t\t\t\t\t\t\t\t\t5CSEMA5F31 5CSXFC5C6U23 5CSEBA5U19 */\n\t{0x02b220dd, 1104,  19, INTEL_CYCLONEV}, /* 5CEBA5U19 5CEFA5U19 5CEFA5M13 5CEBA5F23 5CEFA5F23 */\n\t{0x02b020dd, 1104,  19, INTEL_CYCLONEV}, /* 5CGXBC5CU19 5CGXFC5F6M11 5CGXFC5CM13 5CGTFD5CF23 5CGXBC5CF23 5CGTFD5CF27\n\t\t\t\t\t\t\t\t\t\t\t5CGTFD5F5M11 5CGXFC5CF27 5CGXFC5CU19 5CGTFD5CM13 5CGXFC5CF23 5CGXBC5CF27\n\t\t\t\t\t\t\t\t\t\t\t5CGTFD5CU19 */\n\t{0x02d010dd, 1197,  -1, INTEL_CYCLONEV}, /* 5CSEBA4U23 5CSXFC4C6U23 5CSEMA4U23 5CSEBA4U23 5CSEBA4U19 5CSEBA4U19\n\t\t\t\t\t\t\t\t\t\t\t5CSXFC2C6U23 */\n\t{0x02b120dd, 1104,  19, INTEL_CYCLONEV}, /* 5CGXFC4CM13 5CGXFC4CU19 5CGXFC4F6M11 5CGXBC4CU19 5CGXFC4CF27 5CGXBC4CF23\n\t\t\t\t\t\t\t\t\t\t\t5CGXBC4CF27 5CGXFC4CF23 */\n\t{0x02b140dd, 1728,  -1, INTEL_CYCLONEV}, /* 5CEFA9F31 5CEBA9F31 5CEFA9F27 5CEBA9U19 5CEBA9F27 5CEFA9U19 5CEBA9F23\n\t\t\t\t\t\t\t\t\t\t\t5CEFA9F23 */\n\t{0x02b010dd,  720,  19, INTEL_CYCLONEV}, /* 5CGXFC3U15 5CGXBC3U15 5CGXFC3F23 5CGXFC3U19 5CGXBC3U19 5CGXBC3F23 */\n\t{0x02b130dd, 1488,  19, INTEL_CYCLONEV}, /* 5CEFA7F31 5CEBA7F27 5CEBA7M15 5CEFA7U19 5CEBA7F23 5CEFA7F23 5CEFA7F27\n\t\t\t\t\t\t\t\t\t\t\t5CEFA7M15 5CEBA7U19 5CEBA7F31 */\n\t{0x02d110dd, 1197,  -1, INTEL_CYCLONEV}, /* 5CSEBA2U23 5CSEMA2U23 5CSEBA2U23 5CSEBA2U19 5CSEBA2U19 */\n\n\t{0x020f10dd,  603, 226, INTEL_CYCLONE10}, /* 10CL006E144 10CL006U256 10CL010M164 10CL010U256 10CL010E144 */\n\t{0x020f20dd, 1080, 409, INTEL_CYCLONE10}, /* 10CL016U256 10CL016E144 10CL016U484 10CL016F484 10CL016M164 */\n\t{0x020f30dd,  732, 286, INTEL_CYCLONE10}, /* 10CL025U256 10CL025E144 */\n\t{0x020f40dd, 1632, 604, INTEL_CYCLONE10}, /* 10CL040F484 10CL040U484 */\n\t{0x020f50dd, 1164, 442, INTEL_CYCLONE10}, /* 10CL055F484 10CL055U484 */\n\t{0x020f60dd, 1314, 502, INTEL_CYCLONE10}, /* 10CL080F484 10CL080F780 10CL080U484 */\n\t{0x020f70dd, 1620, 613, INTEL_CYCLONE10}, /* 10CL120F484 10CL120F780 */\n\n\t{0x02e120dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX085U484 10CX085F672 */\n\t{0x02e320dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX105F780 10CX105U484 10CX105F672 */\n\t{0x02e720dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX150F672 10CX150F780 10CX150U484 */\n\t{0x02ef20dd, 1339, -1, INTEL_CYCLONE10}, /* 10CX220F672 10CX220F780 10CX220U484 */\n\n\t{0x025120dd, 1227, 1174, INTEL_ARRIAII}, /* EP2AGX45 */\n\t{0x025020dd, 1227,   -1, INTEL_ARRIAII}, /* EP2AGX65 */\n\t{0x025130dd, 1467,   -1, INTEL_ARRIAII}, /* EP2AGX95 */\n\t{0x025030dd, 1467,   -1, INTEL_ARRIAII}, /* EP2AGX125 */\n\t{0x025140dd, 1971,   -1, INTEL_ARRIAII}, /* EP2AGX190 */\n\t{0x025040dd, 1971,   -1, INTEL_ARRIAII}, /* EP2AGX260 */\n\t{0x024810dd, 2274,   -1, INTEL_ARRIAII}, /* EP2AGZ225 */\n\t{0x0240a0dd, 2682,   -1, INTEL_ARRIAII}, /* EP2AGZ300 */\n\t{0x024820dd, 2682,   -1, INTEL_ARRIAII}, /* EP2AGZ350 */\n};\n\nstatic int intel_fill_device_parameters(struct intel_pld_device *intel_info)\n{\n\tfor (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) {\n\t\tif (intel_device_parameters[i].id == intel_info->tap->idcode &&\n\t\t\tintel_info->family == intel_device_parameters[i].family) {\n\t\t\tif (intel_info->boundary_scan_length == 0)\n\t\t\t\tintel_info->boundary_scan_length = intel_device_parameters[i].boundary_scan_length;\n\n\t\t\tif (intel_info->checkpos == -1)\n\t\t\t\tintel_info->checkpos = intel_device_parameters[i].checkpos;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nstatic int intel_check_for_unique_id(struct intel_pld_device *intel_info)\n{\n\tint found = 0;\n\tfor (size_t i = 0; i < ARRAY_SIZE(intel_device_parameters); ++i) {\n\t\tif (intel_device_parameters[i].id == intel_info->tap->idcode) {\n\t\t\t++found;\n\t\t\tintel_info->family = intel_device_parameters[i].family;\n\t\t}\n\t}\n\n\treturn (found == 1) ? ERROR_OK : ERROR_FAIL;\n}\n\nstatic int intel_check_config(struct intel_pld_device *intel_info)\n{\n\tif (!intel_info->tap->hasidcode) {\n\t\tLOG_ERROR(\"no IDCODE\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (intel_info->family == INTEL_UNKNOWN) {\n\t\tif (intel_check_for_unique_id(intel_info) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"id is ambiguous, please specify family\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (intel_info->boundary_scan_length == 0 || intel_info->checkpos == -1) {\n\t\tint ret = intel_fill_device_parameters(intel_info);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tif (intel_info->checkpos >= 0 && (unsigned int)intel_info->checkpos >= intel_info->boundary_scan_length) {\n\t\tLOG_ERROR(\"checkpos has to be smaller than scan length %d < %u\",\n\t\t\t\t\tintel_info->checkpos, intel_info->boundary_scan_length);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int intel_read_file(struct raw_bit_file *bit_file, const char *filename)\n{\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* check if binary .bin or ascii .bit/.hex */\n\tconst char *file_ending_pos = strrchr(filename, '.');\n\tif (!file_ending_pos) {\n\t\tLOG_ERROR(\"Unable to detect filename suffix\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (strcasecmp(file_ending_pos, \".rbf\") == 0)\n\t\treturn cpld_read_raw_bit_file(bit_file, filename);\n\n\tLOG_ERROR(\"Unable to detect filetype\");\n\treturn ERROR_PLD_FILE_LOAD_FAILED;\n}\n\nstatic int intel_set_instr(struct jtag_tap *tap, uint16_t new_instr)\n{\n\tstruct scan_field field;\n\tfield.num_bits = tap->ir_length;\n\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\tfree(t);\n\treturn ERROR_OK;\n}\n\n\nstatic int intel_load(struct pld_device *pld_device, const char *filename)\n{\n\tunsigned int speed = adapter_get_speed_khz();\n\tif (speed < 1)\n\t\tspeed = 1;\n\n\tunsigned int cycles = DIV_ROUND_UP(speed, 200);\n\tif (cycles < 1)\n\t\tcycles = 1;\n\n\tif (!pld_device || !pld_device->driver_priv)\n\t\treturn ERROR_FAIL;\n\n\tstruct intel_pld_device *intel_info = pld_device->driver_priv;\n\tif (!intel_info || !intel_info->tap)\n\t\treturn ERROR_FAIL;\n\tstruct jtag_tap *tap = intel_info->tap;\n\n\tint retval = intel_check_config(intel_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct raw_bit_file bit_file;\n\tretval = intel_read_file(&bit_file, filename);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = intel_set_instr(tap, 0x002);\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.data);\n\t\treturn retval;\n\t}\n\tjtag_add_runtest(speed, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tfree(bit_file.data);\n\t\treturn retval;\n\t}\n\n\t/* shift in the bitstream */\n\tstruct scan_field field;\n\tfield.num_bits = bit_file.length * 8;\n\tfield.out_value = bit_file.data;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);\n\tretval = jtag_execute_queue();\n\tfree(bit_file.data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = intel_set_instr(tap, 0x004);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(cycles, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (intel_info->boundary_scan_length != 0) {\n\t\tuint8_t *buf = calloc(DIV_ROUND_UP(intel_info->boundary_scan_length, 8), 1);\n\t\tif (!buf) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tfield.num_bits = intel_info->boundary_scan_length;\n\t\tfield.out_value = buf;\n\t\tfield.in_value = buf;\n\t\tjtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(buf);\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (intel_info->checkpos != -1)\n\t\t\tretval = ((buf[intel_info->checkpos / 8] & (1 << (intel_info->checkpos % 8)))) ?\n\t\t\t\t\tERROR_OK : ERROR_FAIL;\n\t\tfree(buf);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Check failed\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tretval = intel_set_instr(tap, 0x003);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tswitch (intel_info->family) {\n\tcase INTEL_CYCLONEIII:\n\tcase INTEL_CYCLONEIV:\n\t\tjtag_add_runtest(5 * speed + 512, TAP_IDLE);\n\t\tbreak;\n\tcase INTEL_CYCLONEV:\n\t\tjtag_add_runtest(5 * speed + 512, TAP_IDLE);\n\t\tbreak;\n\tcase INTEL_CYCLONE10:\n\t\tjtag_add_runtest(DIV_ROUND_UP(512ul * speed, 125ul) + 512, TAP_IDLE);\n\t\tbreak;\n\tcase INTEL_ARRIAII:\n\t\tjtag_add_runtest(DIV_ROUND_UP(64ul * speed, 125ul) + 512, TAP_IDLE);\n\t\tbreak;\n\tcase INTEL_UNKNOWN:\n\t\tLOG_ERROR(\"unknown family\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = intel_set_instr(tap, BYPASS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(speed, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\nstatic int intel_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct intel_pld_device *pld_device_info = pld_device->driver_priv;\n\n\tif (!pld_device_info || !pld_device_info->tap)\n\t\treturn ERROR_FAIL;\n\n\thub->tap = pld_device_info->tap;\n\n\tif (user_num == 0) {\n\t\thub->user_ir_code = USER0;\n\t} else if (user_num == 1) {\n\t\thub->user_ir_code = USER1;\n\t} else {\n\t\tLOG_ERROR(\"intel devices only have user register 0 & 1\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(intel_set_bscan_command_handler)\n{\n\tunsigned int boundary_scan_length;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *pld_device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!pld_device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], boundary_scan_length);\n\n\tstruct intel_pld_device *intel_info = pld_device->driver_priv;\n\n\tif (!intel_info)\n\t\treturn ERROR_FAIL;\n\n\tintel_info->boundary_scan_length = boundary_scan_length;\n\n\treturn  ERROR_OK;\n}\n\nCOMMAND_HANDLER(intel_set_check_pos_command_handler)\n{\n\tint checkpos;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *pld_device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!pld_device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], checkpos);\n\n\tstruct intel_pld_device *intel_info = pld_device->driver_priv;\n\n\tif (!intel_info)\n\t\treturn ERROR_FAIL;\n\n\tintel_info->checkpos = checkpos;\n\n\treturn ERROR_OK;\n}\n\n\nPLD_CREATE_COMMAND_HANDLER(intel_pld_create_command)\n{\n\tif (CMD_ARGC != 4 && CMD_ARGC != 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tenum intel_family_e family = INTEL_UNKNOWN;\n\tif (CMD_ARGC == 6) {\n\t\tif (strcmp(CMD_ARGV[4], \"-family\") != 0)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tif (strcmp(CMD_ARGV[5], \"cycloneiii\") == 0) {\n\t\t\tfamily = INTEL_CYCLONEIII;\n\t\t} else if (strcmp(CMD_ARGV[5], \"cycloneiv\") == 0) {\n\t\t\tfamily = INTEL_CYCLONEIV;\n\t\t} else if (strcmp(CMD_ARGV[5], \"cyclonev\") == 0) {\n\t\t\tfamily = INTEL_CYCLONEV;\n\t\t} else if (strcmp(CMD_ARGV[5], \"cyclone10\") == 0) {\n\t\t\tfamily = INTEL_CYCLONE10;\n\t\t} else if (strcmp(CMD_ARGV[5], \"arriaii\") == 0) {\n\t\t\tfamily = INTEL_ARRIAII;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"unknown family\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device));\n\tif (!intel_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tintel_info->tap = tap;\n\tintel_info->boundary_scan_length = 0;\n\tintel_info->checkpos = -1;\n\tintel_info->family = family;\n\n\tpld->driver_priv = intel_info;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration intel_exec_command_handlers[] = {\n\t{\n\t\t.name = \"set_bscan\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = intel_set_bscan_command_handler,\n\t\t.help = \"set boundary scan register length of FPGA\",\n\t\t.usage = \"pld_name len\",\n\t}, {\n\t\t.name = \"set_check_pos\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = intel_set_check_pos_command_handler,\n\t\t.help = \"set check_pos of FPGA\",\n\t\t.usage = \"pld_name pos\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration intel_command_handler[] = {\n\t{\n\t\t.name = \"intel\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"intel specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = intel_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct pld_driver intel_pld = {\n\t.name = \"intel\",\n\t.commands = intel_command_handler,\n\t.pld_create_command = &intel_pld_create_command,\n\t.load = &intel_load,\n\t.get_ipdbg_hub = intel_get_ipdbg_hub,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/lattice.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"lattice.h\"\n#include <jtag/jtag.h>\n#include \"pld.h\"\n#include \"lattice_bit.h\"\n#include \"ecp2_3.h\"\n#include \"ecp5.h\"\n#include \"certus.h\"\n\n#define PRELOAD              0x1C\n#define USER1                0x32\n#define USER2                0x38\n\n\nstruct lattice_devices_elem {\n\tuint32_t id;\n\tsize_t preload_length;\n\tenum lattice_family_e family;\n};\n\nstatic const struct lattice_devices_elem lattice_devices[] = {\n\t{0x01270043,  654, LATTICE_ECP2 /* ecp2-6e */},\n\t{0x01271043,  643, LATTICE_ECP2 /* ecp2-12e */},\n\t{0x01272043,  827, LATTICE_ECP2 /* ecp2-20e */},\n\t{0x01274043, 1011, LATTICE_ECP2 /* ecp2-35e */},\n\t{0x01273043, 1219, LATTICE_ECP2 /* ecp2-50e */},\n\t{0x01275043,  654, LATTICE_ECP2 /* ecp2-70e */},\n\t{0x01279043,  680, LATTICE_ECP2 /* ecp2m20e */},\n\t{0x0127A043,  936, LATTICE_ECP2 /* ecp2m35e */},\n\t{0x0127B043, 1056, LATTICE_ECP2 /* ecp2m50e */},\n\t{0x0127C043, 1039, LATTICE_ECP2 /* ecp2m70e */},\n\t{0x0127D043, 1311, LATTICE_ECP2 /* ecp2m100e */},\n\t{0x01010043,  467, LATTICE_ECP3 /* ecp3 lae3-17ea & lfe3-17ea*/},\n\t{0x01012043,  675, LATTICE_ECP3 /* ecp3 lae3-35ea & lfe3-35ea*/},\n\t{0x01014043, 1077, LATTICE_ECP3 /* ecp3 lfe3-70ea & lfe3-70e & lfe3-95ea && lfe3-95e*/},\n\t{0x01015043, 1326, LATTICE_ECP3 /* ecp3 lfe3-150e*/},\n\t{0x21111043,  409, LATTICE_ECP5 /* \"LAE5U-12F & LFE5U-12F\" */},\n\t{0x41111043,  409, LATTICE_ECP5 /* \"LFE5U-25F\" */},\n\t{0x41112043,  510, LATTICE_ECP5 /* \"LFE5U-45F\" */},\n\t{0x41113043,  750, LATTICE_ECP5 /* \"LFE5U-85F\" */},\n\t{0x81111043,  409, LATTICE_ECP5 /* \"LFE5UM5G-25F\" */},\n\t{0x81112043,  510, LATTICE_ECP5 /* \"LFE5UM5G-45F\" */},\n\t{0x81113043,  750, LATTICE_ECP5 /* \"LFE5UM5G-85F\" */},\n\t{0x01111043,  409, LATTICE_ECP5 /* \"LAE5UM-25F\" */},\n\t{0x01112043,  510, LATTICE_ECP5 /* \"LAE5UM-45F\" */},\n\t{0x01113043,  750, LATTICE_ECP5 /* \"LAE5UM-85F\" */},\n\t{0x310f0043,  362, LATTICE_CERTUS /* LFD2NX-17 */},\n\t{0x310f1043,  362, LATTICE_CERTUS /* LFD2NX-40 */},\n\t{0x010f4043,  362, LATTICE_CERTUS /* LFCPNX-100 */},\n};\n\nint lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t endstate)\n{\n\tstruct scan_field field;\n\tfield.num_bits = tap->ir_length;\n\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, endstate);\n\tfree(t);\n\treturn ERROR_OK;\n}\n\nstatic int lattice_check_device_family(struct lattice_pld_device *lattice_device)\n{\n\tif (lattice_device->family != LATTICE_UNKNOWN && lattice_device->preload_length != 0)\n\t\treturn ERROR_OK;\n\n\tif (!lattice_device->tap || !lattice_device->tap->hasidcode)\n\t\treturn ERROR_FAIL;\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(lattice_devices); ++i) {\n\t\tif (lattice_devices[i].id == lattice_device->tap->idcode) {\n\t\t\tif (lattice_device->family == LATTICE_UNKNOWN)\n\t\t\t\tlattice_device->family = lattice_devices[i].family;\n\t\t\tif (lattice_device->preload_length == 0)\n\t\t\t\tlattice_device->preload_length = lattice_devices[i].preload_length;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\tLOG_ERROR(\"Unknown id! Specify family and preload-length manually.\");\n\treturn ERROR_FAIL;\n}\n\nint lattice_read_u32_register(struct jtag_tap *tap, uint8_t cmd, uint32_t *in_val,\n\t\t\t\t\t\t\tuint32_t out_val, bool do_idle)\n{\n\tstruct scan_field field;\n\tuint8_t buffer[4];\n\n\tint retval = lattice_set_instr(tap, cmd, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (do_idle) {\n\t\tjtag_add_runtest(2, TAP_IDLE);\n\t\tjtag_add_sleep(1000);\n\t}\n\n\th_u32_to_le(buffer, out_val);\n\tfield.num_bits = 32;\n\tfield.out_value = buffer;\n\tfield.in_value = buffer;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval == ERROR_OK)\n\t\t*in_val = le_to_h_u32(buffer);\n\n\treturn retval;\n}\n\nint lattice_read_u64_register(struct jtag_tap *tap, uint8_t cmd, uint64_t *in_val,\n\t\t\t\t\t\t\tuint64_t out_val)\n{\n\tstruct scan_field field;\n\tuint8_t buffer[8];\n\n\tint retval = lattice_set_instr(tap, cmd, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\th_u64_to_le(buffer, out_val);\n\tfield.num_bits = 64;\n\tfield.out_value = buffer;\n\tfield.in_value = buffer;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval == ERROR_OK)\n\t\t*in_val = le_to_h_u64(buffer);\n\n\treturn retval;\n}\n\nint lattice_preload(struct lattice_pld_device *lattice_device)\n{\n\tstruct scan_field field;\n\tsize_t sz_bytes = DIV_ROUND_UP(lattice_device->preload_length, 8);\n\n\tint retval = lattice_set_instr(lattice_device->tap, PRELOAD, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tuint8_t *buffer = malloc(sz_bytes);\n\tif (!buffer) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tmemset(buffer, 0xff, sz_bytes);\n\n\tfield.num_bits = lattice_device->preload_length;\n\tfield.out_value = buffer;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(lattice_device->tap, 1, &field, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tfree(buffer);\n\treturn retval;\n}\n\nstatic int lattice_read_usercode(struct lattice_pld_device *lattice_device, uint32_t *usercode, uint32_t out)\n{\n\tstruct jtag_tap *tap = lattice_device->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)\n\t\treturn lattice_ecp2_3_read_usercode(tap, usercode, out);\n\telse if (lattice_device->family == LATTICE_ECP5)\n\t\treturn lattice_ecp5_read_usercode(tap, usercode, out);\n\telse if (lattice_device->family == LATTICE_CERTUS)\n\t\treturn lattice_certus_read_usercode(tap, usercode, out);\n\n\treturn ERROR_FAIL;\n}\n\nint lattice_verify_usercode(struct lattice_pld_device *lattice_device, uint32_t out,\n\t\t\t\t\t\tuint32_t expected, uint32_t mask)\n{\n\tuint32_t usercode;\n\n\tint retval = lattice_read_usercode(lattice_device, &usercode, out);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((usercode & mask) != expected) {\n\t\tLOG_ERROR(\"verifying user code register failed got: 0x%08\" PRIx32 \" expected: 0x%08\" PRIx32,\n\t\t\tusercode & mask, expected);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int lattice_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)\n{\n\tif (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)\n\t\treturn lattice_ecp2_3_write_usercode(lattice_device, usercode);\n\telse if (lattice_device->family == LATTICE_ECP5)\n\t\treturn lattice_ecp5_write_usercode(lattice_device, usercode);\n\telse if (lattice_device->family == LATTICE_CERTUS)\n\t\treturn lattice_certus_write_usercode(lattice_device, usercode);\n\n\treturn ERROR_FAIL;\n}\n\nstatic int lattice_read_status_u32(struct lattice_pld_device *lattice_device, uint32_t *status,\n\t\t\t\t\t\t\t\tuint32_t out, bool do_idle)\n{\n\tif (!lattice_device->tap)\n\t\treturn ERROR_FAIL;\n\n\tif (lattice_device->family == LATTICE_ECP2 || lattice_device->family == LATTICE_ECP3)\n\t\treturn lattice_ecp2_3_read_status(lattice_device->tap, status, out, do_idle);\n\telse if (lattice_device->family == LATTICE_ECP5)\n\t\treturn lattice_ecp5_read_status(lattice_device->tap, status, out, do_idle);\n\n\treturn ERROR_FAIL;\n}\nstatic int lattice_read_status_u64(struct lattice_pld_device *lattice_device, uint64_t *status,\n\t\t\t\t\t\t\t\tuint64_t out)\n{\n\tif (!lattice_device->tap)\n\t\treturn ERROR_FAIL;\n\n\tif (lattice_device->family == LATTICE_CERTUS)\n\t\treturn lattice_certus_read_status(lattice_device->tap, status, out);\n\n\treturn ERROR_FAIL;\n}\n\nint lattice_verify_status_register_u32(struct lattice_pld_device *lattice_device, uint32_t out,\n\t\t\t\t\t\tuint32_t expected, uint32_t mask, bool do_idle)\n{\n\tuint32_t status;\n\tint retval = lattice_read_status_u32(lattice_device, &status, out, do_idle);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((status & mask) != expected) {\n\t\tLOG_ERROR(\"verifying status register failed got: 0x%08\" PRIx32 \" expected: 0x%08\" PRIx32,\n\t\t\tstatus & mask, expected);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nint lattice_verify_status_register_u64(struct lattice_pld_device *lattice_device, uint64_t out,\n\t\t\t\t\t\tuint64_t expected, uint64_t mask)\n{\n\tuint64_t status;\n\tint retval = lattice_read_status_u64(lattice_device, &status, out);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((status & mask) != expected) {\n\t\tLOG_ERROR(\"verifying status register failed got: 0x%08\" PRIx64 \" expected: 0x%08\" PRIx64,\n\t\t\tstatus & mask, expected);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int lattice_load_command(struct pld_device *pld_device, const char *filename)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct lattice_pld_device *lattice_device = pld_device->driver_priv;\n\tif (!lattice_device || !lattice_device->tap)\n\t\treturn ERROR_FAIL;\n\tstruct jtag_tap *tap = lattice_device->tap;\n\n\tif (!tap || !tap->hasidcode)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_check_device_family(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct lattice_bit_file bit_file;\n\tretval = lattice_read_file(&bit_file, filename, lattice_device->family);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t id = tap->idcode;\n\tretval = ERROR_FAIL;\n\tswitch (lattice_device->family) {\n\tcase LATTICE_ECP2:\n\t\tretval = lattice_ecp2_load(lattice_device, &bit_file);\n\t\tbreak;\n\tcase LATTICE_ECP3:\n\t\tretval = lattice_ecp3_load(lattice_device, &bit_file);\n\t\tbreak;\n\tcase LATTICE_ECP5:\n\tcase LATTICE_CERTUS:\n\t\tif (bit_file.has_id && id != bit_file.idcode)\n\t\t\tLOG_WARNING(\"Id on device (0x%8.8\" PRIx32 \") and id in bit-stream (0x%8.8\" PRIx32 \") don't match.\",\n\t\t\t\tid, bit_file.idcode);\n\t\tif (lattice_device->family == LATTICE_ECP5)\n\t\t\tretval = lattice_ecp5_load(lattice_device, &bit_file);\n\t\telse\n\t\t\tretval = lattice_certus_load(lattice_device, &bit_file);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"loading unknown device family\");\n\t\tbreak;\n\t}\n\tfree(bit_file.raw_bit.data);\n\treturn retval;\n}\n\nint lattice_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct lattice_pld_device *pld_device_info = pld_device->driver_priv;\n\n\tif (!pld_device_info || !pld_device_info->tap)\n\t\treturn ERROR_FAIL;\n\n\thub->tap = pld_device_info->tap;\n\n\tif (user_num == 1) {\n\t\thub->user_ir_code = USER1;\n\t} else if (user_num == 2) {\n\t\thub->user_ir_code = USER2;\n\t} else {\n\t\tLOG_ERROR(\"lattice devices only have user register 1 & 2\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nPLD_CREATE_COMMAND_HANDLER(lattice_pld_create_command)\n{\n\tif (CMD_ARGC != 4 && CMD_ARGC != 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* id is not known yet -> postpone lattice_check_device_family() */\n\tenum lattice_family_e family = LATTICE_UNKNOWN;\n\tif (CMD_ARGC == 6) {\n\t\tif (strcmp(CMD_ARGV[4], \"-family\") != 0)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tif (strcasecmp(CMD_ARGV[5], \"ecp2\") == 0) {\n\t\t\tfamily = LATTICE_ECP2;\n\t\t} else if (strcasecmp(CMD_ARGV[5], \"ecp3\") == 0) {\n\t\t\tfamily = LATTICE_ECP3;\n\t\t} else if (strcasecmp(CMD_ARGV[5], \"ecp5\") == 0) {\n\t\t\tfamily = LATTICE_ECP5;\n\t\t} else if (strcasecmp(CMD_ARGV[5], \"certus\") == 0) {\n\t\t\tfamily = LATTICE_CERTUS;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"unknown family\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct lattice_pld_device *lattice_device = malloc(sizeof(struct lattice_pld_device));\n\tif (!lattice_device) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tlattice_device->tap = tap;\n\tlattice_device->family = family;\n\tlattice_device->preload_length = 0;\n\n\tpld->driver_priv = lattice_device;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(lattice_read_usercode_register_command_handler)\n{\n\tuint32_t usercode;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct lattice_pld_device *lattice_device = device->driver_priv;\n\tif (!lattice_device)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_check_device_family(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = lattice_read_usercode(lattice_device, &usercode, 0x0);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"0x%8.8\" PRIx32, usercode);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(lattice_set_preload_command_handler)\n{\n\tunsigned int preload_length;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], preload_length);\n\n\tstruct lattice_pld_device *lattice_device = device->driver_priv;\n\n\tif (!lattice_device)\n\t\treturn ERROR_FAIL;\n\n\tlattice_device->preload_length = preload_length;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(lattice_write_usercode_register_command_handler)\n{\n\tuint32_t usercode;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], usercode);\n\n\tstruct lattice_pld_device *lattice_device = device->driver_priv;\n\tif (!lattice_device)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_check_device_family(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn lattice_write_usercode(lattice_device, usercode);\n}\n\nCOMMAND_HANDLER(lattice_read_status_command_handler)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct lattice_pld_device *lattice_device = device->driver_priv;\n\tif (!lattice_device)\n\t\treturn ERROR_FAIL;\n\n\tint retval = lattice_check_device_family(lattice_device);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (lattice_device->family == LATTICE_CERTUS) {\n\t\tuint64_t status;\n\t\tretval = lattice_read_status_u64(lattice_device, &status, 0x0);\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(CMD, \"0x%016\" PRIx64, status);\n\t} else {\n\t\tuint32_t status;\n\t\tconst bool do_idle = lattice_device->family == LATTICE_ECP5;\n\t\tretval = lattice_read_status_u32(lattice_device, &status, 0x0, do_idle);\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(CMD, \"0x%8.8\" PRIx32, status);\n\t}\n\n\treturn retval;\n}\n\nstatic const struct command_registration lattice_exec_command_handlers[] = {\n\t{\n\t\t.name = \"read_status\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = lattice_read_status_command_handler,\n\t\t.help = \"reading status register from FPGA\",\n\t\t.usage = \"pld_name\",\n\t}, {\n\t\t.name = \"read_user\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = lattice_read_usercode_register_command_handler,\n\t\t.help = \"reading usercode register from FPGA\",\n\t\t.usage = \"pld_name\",\n\t}, {\n\t\t.name = \"write_user\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = lattice_write_usercode_register_command_handler,\n\t\t.help = \"writing usercode register to FPGA\",\n\t\t.usage = \"pld_name value\",\n\t}, {\n\t\t.name = \"set_preload\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = lattice_set_preload_command_handler,\n\t\t.help = \"set length for preload (device specific)\",\n\t\t.usage = \"pld_name value\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration lattice_command_handler[] = {\n\t{\n\t\t.name = \"lattice\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"lattice specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = lattice_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct pld_driver lattice_pld = {\n\t.name = \"lattice\",\n\t.commands = lattice_command_handler,\n\t.pld_create_command = &lattice_pld_create_command,\n\t.load = &lattice_load_command,\n\t.get_ipdbg_hub = lattice_get_ipdbg_hub,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/lattice.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_LATTICE_H\n#define OPENOCD_PLD_LATTICE_H\n\n#include <jtag/jtag.h>\n#include \"pld.h\"\n#include \"lattice_bit.h\"\n\n#define BYPASS 0xFF\n\nstruct lattice_pld_device {\n\tstruct jtag_tap *tap;\n\tsize_t preload_length;\n\tenum lattice_family_e family;\n};\n\nint lattice_set_instr(struct jtag_tap *tap, uint8_t new_instr, tap_state_t endstate);\nint lattice_read_u32_register(struct jtag_tap *tap, uint8_t cmd, uint32_t *in_val,\n\t\t\t\t\t\t\tuint32_t out_val, bool do_idle);\nint lattice_read_u64_register(struct jtag_tap *tap, uint8_t cmd, uint64_t *in_val,\n\t\t\t\t\t\t\tuint64_t out_val);\nint lattice_verify_usercode(struct lattice_pld_device *lattice_device, uint32_t out,\n\t\t\t\t\t\tuint32_t expected, uint32_t mask);\nint lattice_verify_status_register_u32(struct lattice_pld_device *lattice_device, uint32_t out,\n\t\t\t\t\t\tuint32_t expected, uint32_t mask, bool do_idle);\nint lattice_verify_status_register_u64(struct lattice_pld_device *lattice_device, uint64_t out,\n\t\t\t\t\t\tuint64_t expected, uint64_t mask);\nint lattice_preload(struct lattice_pld_device *lattice_device);\n\n#endif /* OPENOCD_PLD_LATTICE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/lattice_bit.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n#include \"lattice_bit.h\"\n#include \"raw_bit.h\"\n#include \"pld.h\"\n#include <helper/system.h>\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n\nenum read_bit_state {\n\tSEEK_HEADER_START,\n\tSEEK_HEADER_END,\n\tSEEK_PREAMBLE,\n\tSEEK_ID,\n\tDONE,\n};\n\nstatic int lattice_read_bit_file(struct lattice_bit_file *bit_file, const char *filename, enum lattice_family_e family)\n{\n\tint retval = cpld_read_raw_bit_file(&bit_file->raw_bit, filename);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tbit_file->part = NULL;\n\tbit_file->has_id = false;\n\tenum read_bit_state state = SEEK_HEADER_START;\n\tfor (size_t pos = 1; pos < bit_file->raw_bit.length && state != DONE; ++pos) {\n\t\tswitch (state) {\n\t\tcase SEEK_HEADER_START:\n\t\t\tif (bit_file->raw_bit.data[pos] == 0 && bit_file->raw_bit.data[pos - 1] == 0xff)\n\t\t\t\tstate = SEEK_HEADER_END;\n\t\t\tbreak;\n\t\tcase SEEK_HEADER_END:\n\t\t\tif (pos + 6 < bit_file->raw_bit.length &&\n\t\t\t\t\tstrncmp((const char *)(bit_file->raw_bit.data + pos), \"Part: \", 6) == 0) {\n\t\t\t\tbit_file->part = (const char *)bit_file->raw_bit.data + pos + 6;\n\t\t\t\tLOG_INFO(\"part found: %s\\n\", bit_file->part);\n\t\t\t} else if (bit_file->raw_bit.data[pos] == 0xff && bit_file->raw_bit.data[pos - 1] == 0) {\n\t\t\t\tbit_file->offset = pos;\n\t\t\t\tstate = (family != LATTICE_ECP2 && family != LATTICE_ECP3) ? SEEK_PREAMBLE : DONE;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SEEK_PREAMBLE:\n\t\t\tif (pos >= 4) {\n\t\t\t\tuint32_t preamble = be_to_h_u32(bit_file->raw_bit.data + pos - 3);\n\t\t\t\tswitch (preamble) {\n\t\t\t\tcase 0xffffbdb3:\n\t\t\t\t\tstate = SEEK_ID;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xffffbfb3:\n\t\t\t\tcase 0xffffbeb3:\n\t\t\t\t\tstate = DONE;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase SEEK_ID:\n\t\t\tif (pos + 7 < bit_file->raw_bit.length && bit_file->raw_bit.data[pos] == 0xe2) {\n\t\t\t\tbit_file->idcode = be_to_h_u32(&bit_file->raw_bit.data[pos + 4]);\n\t\t\t\tbit_file->has_id = true;\n\t\t\t\tstate = DONE;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (state != DONE) {\n\t\tLOG_ERROR(\"parsing bitstream failed\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tfor (size_t i = bit_file->offset; i < bit_file->raw_bit.length; i++)\n\t\tbit_file->raw_bit.data[i] = flip_u32(bit_file->raw_bit.data[i], 8);\n\n\treturn ERROR_OK;\n}\n\nint lattice_read_file(struct lattice_bit_file *bit_file, const char *filename, enum lattice_family_e family)\n{\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* check if binary .bin or ascii .bit/.hex */\n\tconst char *file_suffix_pos = strrchr(filename, '.');\n\tif (!file_suffix_pos) {\n\t\tLOG_ERROR(\"Unable to detect filename suffix\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (strcasecmp(file_suffix_pos, \".bit\") == 0)\n\t\treturn lattice_read_bit_file(bit_file, filename, family);\n\n\tLOG_ERROR(\"Filetype not supported\");\n\treturn ERROR_PLD_FILE_LOAD_FAILED;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/lattice_bit.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_LATTICE_BIT_H\n#define OPENOCD_PLD_LATTICE_BIT_H\n\n#include \"helper/types.h\"\n#include \"raw_bit.h\"\n\n\nstruct lattice_bit_file {\n\tstruct raw_bit_file raw_bit;\n\tsize_t offset;\n\tuint32_t idcode;\n\tconst char *part; /* reuses memory in raw_bit_file */\n\tbool has_id;\n};\n\nenum lattice_family_e {\n\tLATTICE_ECP2,\n\tLATTICE_ECP3,\n\tLATTICE_ECP5,\n\tLATTICE_CERTUS,\n\tLATTICE_UNKNOWN,\n};\n\nint lattice_read_file(struct lattice_bit_file *bit_file, const char *filename, enum lattice_family_e family);\n\n#endif /* OPENOCD_PLD_LATTICE_BIT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/lattice_cmd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_LATTICE_CMD_H\n#define OPENOCD_PLD_LATTICE_CMD_H\n\n#define ISC_ERASE            0x0E\n#define ISC_DISABLE          0x26\n#define LSC_READ_STATUS      0x3C\n#define LSC_INIT_ADDRESS     0x46\n#define LSC_BITSTREAM_BURST  0x7A\n#define READ_USERCODE        0xC0\n#define ISC_ENABLE           0xC6\n\n#endif /* OPENOCD_PLD_LATTICE_CMD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/pld.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"pld.h\"\n#include <sys/stat.h>\n#include <helper/log.h>\n#include <helper/replacements.h>\n#include <helper/time_support.h>\n\n\nstatic struct pld_driver *pld_drivers[] = {\n\t&efinix_pld,\n\t&gatemate_pld,\n\t&gowin_pld,\n\t&intel_pld,\n\t&lattice_pld,\n\t&virtex2_pld,\n\tNULL,\n};\n\nstatic struct pld_device *pld_devices;\n\nstruct pld_device *get_pld_device_by_num(int num)\n{\n\tstruct pld_device *p;\n\tint i = 0;\n\n\tfor (p = pld_devices; p; p = p->next) {\n\t\tif (i++ == num) {\n\t\t\tLOG_WARNING(\"DEPRECATED: use pld name \\\"%s\\\" instead of number %d\", p->name, num);\n\t\t\treturn p;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nstruct pld_device *get_pld_device_by_name(const char *name)\n{\n\tfor (struct pld_device *p = pld_devices; p; p = p->next) {\n\t\tif (strcmp(p->name, name) == 0)\n\t\t\treturn p;\n\t}\n\n\treturn NULL;\n}\n\nstruct pld_device *get_pld_device_by_name_or_numstr(const char *str)\n{\n\tstruct pld_device *dev = get_pld_device_by_name(str);\n\tif (dev)\n\t\treturn dev;\n\n\tchar *end;\n\tunsigned long dev_num = strtoul(str, &end, 0);\n\tif (*end || dev_num > INT_MAX) {\n\t\tLOG_ERROR(\"Invalid argument\");\n\t\treturn NULL;\n\t}\n\n\treturn get_pld_device_by_num(dev_num);\n}\n\n/* @deffn {Config Command} {pld create} pld_name driver -chain-position tap_name [options]\n*/\nCOMMAND_HANDLER(handle_pld_create_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_driver *pld_driver = NULL;\n\n\tfor (int i = 0; pld_drivers[i]; i++) {\n\t\tif (strcmp(CMD_ARGV[1], pld_drivers[i]->name) == 0) {\n\t\t\tpld_driver = pld_drivers[i];\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!pld_driver) {\n\t\tLOG_ERROR(\"pld driver '%s' not found\", CMD_ARGV[1]);\n\t\treturn ERROR_FAIL; /* exit(-1); */\n\t}\n\n\tif (get_pld_device_by_name(CMD_ARGV[0])) {\n\t\tLOG_ERROR(\"pld device with name '%s' already exists\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct pld_device *pld_device = malloc(sizeof(struct pld_device));\n\tif (!pld_device) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tpld_device->driver = pld_driver;\n\tpld_device->next = NULL;\n\n\tint retval = CALL_COMMAND_HANDLER(pld_driver->pld_create_command, pld_device);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"'%s' driver rejected pld device\",\n\t\t\tCMD_ARGV[1]);\n\t\tfree(pld_device);\n\t\treturn ERROR_OK;\n\t}\n\tpld_device->name = strdup(CMD_ARGV[0]);\n\tif (!pld_device->name) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(pld_device);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* register pld specific commands */\n\tif (pld_driver->commands) {\n\t\tretval = register_commands(CMD_CTX, NULL, pld_driver->commands);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"couldn't register '%s' commands\", CMD_ARGV[1]);\n\t\t\tfree(pld_device->name);\n\t\t\tfree(pld_device);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (pld_devices) {\n\t\t/* find last pld device */\n\t\tstruct pld_device *p = pld_devices;\n\t\tfor (; p && p->next; p = p->next)\n\t\t\t;\n\t\tif (p)\n\t\t\tp->next = pld_device;\n\t} else {\n\t\tpld_devices = pld_device;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_pld_devices_command)\n{\n\tstruct pld_device *p;\n\tint i = 0;\n\n\tif (!pld_devices) {\n\t\tcommand_print(CMD, \"no pld devices configured\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (p = pld_devices; p; p = p->next)\n\t\tcommand_print(CMD, \"#%i: %s (driver: %s)\", i++, p->name, p->driver->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_pld_load_command)\n{\n\tint retval;\n\tstruct timeval start, end, duration;\n\tstruct pld_device *p;\n\n\tgettimeofday(&start, NULL);\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tp = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!p) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct stat input_stat;\n\tif (stat(CMD_ARGV[1], &input_stat) == -1) {\n\t\tLOG_ERROR(\"couldn't stat() %s: %s\", CMD_ARGV[1], strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (S_ISDIR(input_stat.st_mode)) {\n\t\tLOG_ERROR(\"%s is a directory\", CMD_ARGV[1]);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (input_stat.st_size == 0) {\n\t\tLOG_ERROR(\"Empty file %s\", CMD_ARGV[1]);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tretval = p->driver->load(p, CMD_ARGV[1]);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"failed loading file %s to pld device %s\",\n\t\t\tCMD_ARGV[1], CMD_ARGV[0]);\n\t\treturn retval;\n\t} else {\n\t\tgettimeofday(&end, NULL);\n\t\ttimeval_subtract(&duration, &end, &start);\n\n\t\tcommand_print(CMD, \"loaded file %s to pld device %s in %jis %jius\",\n\t\t\tCMD_ARGV[1], CMD_ARGV[0],\n\t\t\t(intmax_t)duration.tv_sec, (intmax_t)duration.tv_usec);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration pld_exec_command_handlers[] = {\n\t{\n\t\t.name = \"devices\",\n\t\t.handler = handle_pld_devices_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list configured pld devices\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"load\",\n\t\t.handler = handle_pld_load_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"load configuration file into PLD\",\n\t\t.usage = \"pld_name filename\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int pld_init(struct command_context *cmd_ctx)\n{\n\tif (!pld_devices)\n\t\treturn ERROR_OK;\n\n\treturn register_commands(cmd_ctx, \"pld\", pld_exec_command_handlers);\n}\n\nCOMMAND_HANDLER(handle_pld_init_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstatic bool pld_initialized;\n\tif (pld_initialized) {\n\t\tLOG_INFO(\"'pld init' has already been called\");\n\t\treturn ERROR_OK;\n\t}\n\tpld_initialized = true;\n\n\tLOG_DEBUG(\"Initializing PLDs...\");\n\treturn pld_init(CMD_CTX);\n}\n\nstatic const struct command_registration pld_config_command_handlers[] = {\n\t{\n\t\t.name = \"create\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_pld_create_command,\n\t\t.help = \"create a PLD device\",\n\t\t.usage = \"name.pld driver_name [driver_args ... ]\",\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_pld_init_command,\n\t\t.help = \"initialize PLD devices\",\n\t\t.usage = \"\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration pld_command_handler[] = {\n\t{\n\t\t.name = \"pld\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"programmable logic device commands\",\n\t\t.usage = \"\",\n\t\t.chain = pld_config_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nint pld_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, pld_command_handler);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/pld.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_PLD_H\n#define OPENOCD_PLD_PLD_H\n\n#include <helper/command.h>\n\nstruct pld_device;\n\n#define __PLD_CREATE_COMMAND(name) \\\n\tCOMMAND_HELPER(name, struct pld_device *pld)\n\nstruct pld_ipdbg_hub {\n\tstruct jtag_tap *tap;\n\tunsigned int user_ir_code;\n};\n\nstruct pld_driver {\n\tconst char *name;\n\t__PLD_CREATE_COMMAND((*pld_create_command));\n\tconst struct command_registration *commands;\n\tint (*load)(struct pld_device *pld_device, const char *filename);\n\tint (*get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub);\n};\n\n#define PLD_CREATE_COMMAND_HANDLER(name) \\\n\tstatic __PLD_CREATE_COMMAND(name)\n\nstruct pld_device {\n\tstruct pld_driver *driver;\n\tvoid *driver_priv;\n\tstruct pld_device *next;\n\tchar *name;\n};\n\nint pld_register_commands(struct command_context *cmd_ctx);\n\nstruct pld_device *get_pld_device_by_num(int num);\nstruct pld_device *get_pld_device_by_name(const char *name);\nstruct pld_device *get_pld_device_by_name_or_numstr(const char *str);\n\n#define ERROR_PLD_DEVICE_INVALID        (-1000)\n#define ERROR_PLD_FILE_LOAD_FAILED      (-1001)\n\nextern struct pld_driver efinix_pld;\nextern struct pld_driver gatemate_pld;\nextern struct pld_driver gowin_pld;\nextern struct pld_driver intel_pld;\nextern struct pld_driver lattice_pld;\nextern struct pld_driver virtex2_pld;\n\n#endif /* OPENOCD_PLD_PLD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/raw_bit.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"raw_bit.h\"\n#include \"pld.h\"\n\n#include <helper/system.h>\n#include <helper/log.h>\n\n\nint cpld_read_raw_bit_file(struct raw_bit_file *bit_file, const char *filename)\n{\n\tFILE *input_file = fopen(filename, \"rb\");\n\n\tif (!input_file) {\n\t\tLOG_ERROR(\"Couldn't open %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tfseek(input_file, 0, SEEK_END);\n\tlong length = ftell(input_file);\n\tfseek(input_file, 0, SEEK_SET);\n\n\tif (length < 0) {\n\t\tfclose(input_file);\n\t\tLOG_ERROR(\"Failed to get length of file %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\tbit_file->length = (size_t)length;\n\n\tbit_file->data = malloc(bit_file->length);\n\tif (!bit_file->data) {\n\t\tfclose(input_file);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tsize_t read_count = fread(bit_file->data, sizeof(char), bit_file->length, input_file);\n\tfclose(input_file);\n\tif (read_count != bit_file->length) {\n\t\tfree(bit_file->data);\n\t\tbit_file->data = NULL;\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/raw_bit.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2022 by Daniel Anselmi                                  *\n *   danselmi@gmx.ch                                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_RAW_BIN_H\n#define OPENOCD_PLD_RAW_BIN_H\n\n#include <stddef.h>\n#include <stdint.h>\n\nstruct raw_bit_file {\n\tsize_t length;\n\tuint8_t *data;\n};\n\nint cpld_read_raw_bit_file(struct raw_bit_file *bit_file, const char *filename);\n\n#endif /* OPENOCD_PLD_RAW_BIN_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/virtex2.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"virtex2.h\"\n#include \"xilinx_bit.h\"\n#include \"pld.h\"\n\nstatic const struct virtex2_command_set virtex2_default_commands = {\n\t.cfg_out   = 0x04,\n\t.cfg_in    = 0x05,\n\t.jprog_b   = 0x0b,\n\t.jstart    = 0x0c,\n\t.jshutdown = 0x0d,\n\t.bypass    = 0x3f,\n\t.user      = {0x02, 0x03},\n\t.num_user  = 2, /* virtex II has only 2 user instructions */\n};\n\nstatic int virtex2_set_instr(struct jtag_tap *tap, uint64_t new_instr)\n{\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (buf_get_u64(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\t\tstruct scan_field field;\n\n\t\tfield.num_bits = tap->ir_length;\n\t\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tfield.out_value = t;\n\t\tbuf_set_u64(t, 0, field.num_bits, new_instr);\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\t\tfree(t);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int virtex2_send_32(struct pld_device *pld_device,\n\tint num_words, uint32_t *words)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tstruct scan_field scan_field;\n\tuint8_t *values;\n\tint i;\n\n\tvalues = malloc(num_words * 4);\n\tif (!values) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tscan_field.num_bits = num_words * 32;\n\tscan_field.out_value = values;\n\tscan_field.in_value = NULL;\n\n\tfor (i = 0; i < num_words; i++)\n\t\tbuf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));\n\n\tint retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_in);\n\tif (retval != ERROR_OK) {\n\t\tfree(values);\n\t\treturn retval;\n\t}\n\n\tjtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);\n\n\tfree(values);\n\n\treturn ERROR_OK;\n}\n\nstatic inline void virtexflip32(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32);\n}\n\nstatic int virtex2_receive_32(struct pld_device *pld_device,\n\tint num_words, uint32_t *words)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tstruct scan_field scan_field;\n\n\tscan_field.num_bits = 32;\n\tscan_field.out_value = NULL;\n\tscan_field.in_value = NULL;\n\n\tint retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_out);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twhile (num_words--) {\n\t\tscan_field.in_value = (uint8_t *)words;\n\n\t\tjtag_add_dr_scan(virtex2_info->tap, 1, &scan_field, TAP_DRPAUSE);\n\n\t\tjtag_add_callback(virtexflip32, (jtag_callback_data_t)words);\n\n\t\twords++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int virtex2_read_stat(struct pld_device *pld_device, uint32_t *status)\n{\n\tuint32_t data[5];\n\n\tjtag_add_tlr();\n\n\tdata[0] = 0xaa995566;\t/* synch word */\n\tdata[1] = 0x2800E001;\t/* Type 1, read, address 7, 1 word */\n\tdata[2] = 0x20000000;\t/* NOOP (Type 1, read, address 0, 0 words */\n\tdata[3] = 0x20000000;\t/* NOOP */\n\tdata[4] = 0x20000000;\t/* NOOP */\n\tint retval = virtex2_send_32(pld_device, 5, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = virtex2_receive_32(pld_device, 1, status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_execute_queue();\n\tif (retval == ERROR_OK)\n\t\tLOG_DEBUG(\"status: 0x%8.8\" PRIx32, *status);\n\n\treturn retval;\n}\n\nstatic int virtex2_program(struct pld_device *pld_device)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tif (!virtex2_info)\n\t\treturn ERROR_FAIL;\n\n\tint retval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jshutdown);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jprog_b);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tjtag_add_runtest(62000, TAP_IDLE);\n\tif (!(virtex2_info->no_jstart)) {\n\t\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jstart);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_runtest(2000, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int virtex2_load_prepare(struct pld_device *pld_device)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tint retval;\n\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jprog_b);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tjtag_add_sleep(1000);\n\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.cfg_in);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn jtag_execute_queue();\n}\n\nstatic int virtex2_load_cleanup(struct pld_device *pld_device)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tint retval;\n\n\tjtag_add_tlr();\n\n\tif (!(virtex2_info->no_jstart)) {\n\t\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jstart);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tjtag_add_runtest(13, TAP_IDLE);\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (!(virtex2_info->no_jstart)) {\n\t\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.jstart);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tjtag_add_runtest(13, TAP_IDLE);\n\tretval = virtex2_set_instr(virtex2_info->tap, virtex2_info->command_set.bypass);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn jtag_execute_queue();\n}\n\nstatic int virtex2_load(struct pld_device *pld_device, const char *filename)\n{\n\tstruct virtex2_pld_device *virtex2_info = pld_device->driver_priv;\n\tstruct xilinx_bit_file bit_file;\n\tint retval;\n\tunsigned int i;\n\tstruct scan_field field;\n\n\tfield.in_value = NULL;\n\n\tretval = xilinx_read_bit_file(&bit_file, filename);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = virtex2_load_prepare(pld_device);\n\tif (retval != ERROR_OK) {\n\t\txilinx_free_bit_file(&bit_file);\n\t\treturn retval;\n\t}\n\n\tfor (i = 0; i < bit_file.length; i++)\n\t\tbit_file.data[i] = flip_u32(bit_file.data[i], 8);\n\n\tfield.num_bits = bit_file.length * 8;\n\tfield.out_value = bit_file.data;\n\n\tjtag_add_dr_scan(virtex2_info->tap, 1, &field, TAP_DRPAUSE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\txilinx_free_bit_file(&bit_file);\n\t\treturn retval;\n\t}\n\n\tretval = virtex2_load_cleanup(pld_device);\n\n\txilinx_free_bit_file(&bit_file);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(virtex2_handle_program_command)\n{\n\tstruct pld_device *device;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tdevice = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn virtex2_program(device);\n}\n\nCOMMAND_HANDLER(virtex2_handle_read_stat_command)\n{\n\tstruct pld_device *device;\n\tuint32_t status;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tdevice = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = virtex2_read_stat(device, &status);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"cannot read virtex2 status register\");\n\t\treturn retval;\n\t}\n\n\tcommand_print(CMD, \"virtex2 status register: 0x%8.8\" PRIx32, status);\n\n\treturn ERROR_OK;\n}\n\nstatic int xilinx_get_ipdbg_hub(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub)\n{\n\tif (!pld_device)\n\t\treturn ERROR_FAIL;\n\n\tstruct virtex2_pld_device *pld_device_info = pld_device->driver_priv;\n\n\tif (!pld_device_info || !pld_device_info->tap)\n\t\treturn ERROR_FAIL;\n\n\thub->tap = pld_device_info->tap;\n\tif (user_num < 1 || (unsigned int)user_num > pld_device_info->command_set.num_user) {\n\t\tLOG_ERROR(\"device has only user register 1 to %d\", pld_device_info->command_set.num_user);\n\t\treturn ERROR_FAIL;\n\t}\n\n\thub->user_ir_code = pld_device_info->command_set.user[user_num - 1];\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)\n{\n\tif (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct virtex2_pld_device *virtex2_info = device->driver_priv;\n\tif (!virtex2_info)\n\t\treturn ERROR_FAIL;\n\n\tstruct virtex2_command_set instr_codes;\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], instr_codes.cfg_out);\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[2], instr_codes.cfg_in);\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[3], instr_codes.jprog_b);\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[4], instr_codes.jstart);\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[5], instr_codes.jshutdown);\n\tinstr_codes.bypass = 0xffffffffffffffff;\n\n\tunsigned int num_user = CMD_ARGC - 6;\n\tfor (unsigned int i = 0; i < num_user; ++i)\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[6 + i], instr_codes.user[i]);\n\tinstr_codes.num_user = num_user;\n\n\tvirtex2_info->command_set = instr_codes;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(virtex2_handle_set_user_codes_command)\n{\n\tif (CMD_ARGC < 2 || CMD_ARGC > (1 + VIRTEX2_MAX_USER_INSTRUCTIONS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);\n\tif (!device) {\n\t\tcommand_print(CMD, \"pld device '#%s' is unknown\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct virtex2_pld_device *virtex2_info = device->driver_priv;\n\tif (!virtex2_info)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t user[VIRTEX2_MAX_USER_INSTRUCTIONS];\n\tunsigned int num_user = CMD_ARGC - 1;\n\tfor (unsigned int i = 0; i < num_user; ++i)\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1 + i], user[i]);\n\tvirtex2_info->command_set.num_user = num_user;\n\tmemcpy(virtex2_info->command_set.user, user, num_user * sizeof(uint64_t));\n\treturn ERROR_OK;\n}\n\nPLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command)\n{\n\tif (CMD_ARGC < 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[2], \"-chain-position\") != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"Tap: %s does not exist\", CMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct virtex2_pld_device *virtex2_info = malloc(sizeof(struct virtex2_pld_device));\n\tif (!virtex2_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tvirtex2_info->tap = tap;\n\tvirtex2_info->command_set = virtex2_default_commands;\n\n\tvirtex2_info->no_jstart = 0;\n\tif (CMD_ARGC >= 5 && strcmp(CMD_ARGV[4], \"-no_jstart\") == 0)\n\t\tvirtex2_info->no_jstart = 1;\n\n\tpld->driver_priv = virtex2_info;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration virtex2_exec_command_handlers[] = {\n\t{\n\t\t.name = \"read_stat\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = virtex2_handle_read_stat_command,\n\t\t.help = \"read status register\",\n\t\t.usage = \"pld_name\",\n\t}, {\n\t\t.name = \"set_instr_codes\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = virtex2_handle_set_instuction_codes_command,\n\t\t.help = \"set instructions codes used for loading the bitstream/refreshing/jtag-hub\",\n\t\t.usage = \"pld_name cfg_out cfg_in jprogb jstart jshutdown\"\n\t\t\t\t \" [user1 [user2 [user3 [user4]]]]\",\n\t}, {\n\t\t.name = \"set_user_codes\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = virtex2_handle_set_user_codes_command,\n\t\t.help = \"set instructions codes used for jtag-hub\",\n\t\t.usage = \"pld_name user1 [user2 [user3 [user4]]]\",\n\t}, {\n\t\t.name = \"program\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = virtex2_handle_program_command,\n\t\t.help = \"start loading of configuration (refresh)\",\n\t\t.usage = \"pld_name\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration virtex2_command_handler[] = {\n\t{\n\t\t.name = \"virtex2\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Virtex-II specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = virtex2_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct pld_driver virtex2_pld = {\n\t.name = \"virtex2\",\n\t.commands = virtex2_command_handler,\n\t.pld_create_command = &virtex2_pld_create_command,\n\t.load = &virtex2_load,\n\t.get_ipdbg_hub = xilinx_get_ipdbg_hub,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/virtex2.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_VIRTEX2_H\n#define OPENOCD_PLD_VIRTEX2_H\n\n#include <jtag/jtag.h>\n\n#define VIRTEX2_MAX_USER_INSTRUCTIONS 4\n\nstruct virtex2_command_set {\n\tuint64_t cfg_out;\n\tuint64_t cfg_in;\n\tuint64_t jprog_b;\n\tuint64_t jstart;\n\tuint64_t jshutdown;\n\tuint64_t bypass;\n\tuint64_t user[VIRTEX2_MAX_USER_INSTRUCTIONS];\n\tunsigned int num_user;\n};\n\nstruct virtex2_pld_device {\n\tstruct jtag_tap *tap;\n\tint no_jstart;\n\tstruct virtex2_command_set command_set;\n};\n\n#endif /* OPENOCD_PLD_VIRTEX2_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/xilinx_bit.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"xilinx_bit.h\"\n#include \"pld.h\"\n#include <helper/log.h>\n\n#include <helper/system.h>\n\nstatic int read_section(FILE *input_file, int length_size, char section,\n\tuint32_t *buffer_length, uint8_t **buffer)\n{\n\tuint8_t length_buffer[4];\n\tint length;\n\tchar section_char;\n\tint read_count;\n\n\tif ((length_size != 2) && (length_size != 4)) {\n\t\tLOG_ERROR(\"BUG: length_size neither 2 nor 4\");\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tread_count = fread(&section_char, 1, 1, input_file);\n\tif (read_count != 1)\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\n\tif (section_char != section)\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\n\tread_count = fread(length_buffer, 1, length_size, input_file);\n\tif (read_count != length_size)\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\n\tif (length_size == 4)\n\t\tlength = be_to_h_u32(length_buffer);\n\telse\t/* (length_size == 2) */\n\t\tlength = be_to_h_u16(length_buffer);\n\n\tif (buffer_length)\n\t\t*buffer_length = length;\n\n\t*buffer = malloc(length);\n\n\tread_count = fread(*buffer, 1, length, input_file);\n\tif (read_count != length)\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\n\treturn ERROR_OK;\n}\n\nint xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename)\n{\n\tFILE *input_file;\n\tint read_count;\n\n\tif (!filename || !bit_file)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tinput_file = fopen(filename, \"rb\");\n\tif (!input_file) {\n\t\tLOG_ERROR(\"couldn't open %s: %s\", filename, strerror(errno));\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tbit_file->source_file = NULL;\n\tbit_file->part_name = NULL;\n\tbit_file->date = NULL;\n\tbit_file->time = NULL;\n\tbit_file->data = NULL;\n\n\tread_count = fread(bit_file->unknown_header, 1, 13, input_file);\n\tif (read_count != 13) {\n\t\tLOG_ERROR(\"couldn't read unknown_header from file '%s'\", filename);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (read_section(input_file, 2, 'a', NULL, &bit_file->source_file) != ERROR_OK) {\n\t\txilinx_free_bit_file(bit_file);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (read_section(input_file, 2, 'b', NULL, &bit_file->part_name) != ERROR_OK) {\n\t\txilinx_free_bit_file(bit_file);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (read_section(input_file, 2, 'c', NULL, &bit_file->date) != ERROR_OK) {\n\t\txilinx_free_bit_file(bit_file);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (read_section(input_file, 2, 'd', NULL, &bit_file->time) != ERROR_OK) {\n\t\txilinx_free_bit_file(bit_file);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tif (read_section(input_file, 4, 'e', &bit_file->length, &bit_file->data) != ERROR_OK) {\n\t\txilinx_free_bit_file(bit_file);\n\t\tfclose(input_file);\n\t\treturn ERROR_PLD_FILE_LOAD_FAILED;\n\t}\n\n\tLOG_DEBUG(\"bit_file: %s %s %s,%s %\" PRIu32 \"\", bit_file->source_file, bit_file->part_name,\n\t\tbit_file->date, bit_file->time, bit_file->length);\n\n\tfclose(input_file);\n\n\treturn ERROR_OK;\n}\n\nvoid xilinx_free_bit_file(struct xilinx_bit_file *bit_file)\n{\n\tfree(bit_file->source_file);\n\tfree(bit_file->part_name);\n\tfree(bit_file->date);\n\tfree(bit_file->time);\n\tfree(bit_file->data);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/pld/xilinx_bit.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_PLD_XILINX_BIT_H\n#define OPENOCD_PLD_XILINX_BIT_H\n\n#include \"helper/types.h\"\n\nstruct xilinx_bit_file {\n\tuint8_t unknown_header[13];\n\tuint8_t *source_file;\n\tuint8_t *part_name;\n\tuint8_t *date;\n\tuint8_t *time;\n\tuint32_t length;\n\tuint8_t *data;\n};\n\nint xilinx_read_bit_file(struct xilinx_bit_file *bit_file, const char *filename);\n\nvoid xilinx_free_bit_file(struct xilinx_bit_file *bit_file);\n\n#endif /* OPENOCD_PLD_XILINX_BIT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/FreeRTOS.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"target/armv7m.h\"\n#include \"target/cortex_m.h\"\n\n#define FREERTOS_MAX_PRIORITIES\t63\n\n/* FIXME: none of the _width parameters are actually observed properly!\n * you WILL need to edit more if you actually attempt to target a 8/16/64\n * bit target!\n */\n\nstruct freertos_params {\n\tconst char *target_name;\n\tconst unsigned char thread_count_width;\n\tconst unsigned char pointer_width;\n\tconst unsigned char list_next_offset;\n\tconst unsigned char list_width;\n\tconst unsigned char list_elem_next_offset;\n\tconst unsigned char list_elem_content_offset;\n\tconst unsigned char thread_stack_offset;\n\tconst unsigned char thread_name_offset;\n\tconst struct rtos_register_stacking *stacking_info_cm3;\n\tconst struct rtos_register_stacking *stacking_info_cm4f;\n\tconst struct rtos_register_stacking *stacking_info_cm4f_fpu;\n};\n\nstatic const struct freertos_params freertos_params_list[] = {\n\t{\n\t\"cortex_m\",\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t/* thread_count_width; */\n\t4,\t\t\t\t\t\t/* pointer_width; */\n\t16,\t\t\t\t\t\t/* list_next_offset; */\n\t20,\t\t\t\t\t\t/* list_width; */\n\t8,\t\t\t\t\t\t/* list_elem_next_offset; */\n\t12,\t\t\t\t\t\t/* list_elem_content_offset */\n\t0,\t\t\t\t\t\t/* thread_stack_offset; */\n\t52,\t\t\t\t\t\t/* thread_name_offset; */\n\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t&rtos_standard_cortex_m4f_stacking,\n\t&rtos_standard_cortex_m4f_fpu_stacking,\n\t},\n\t{\n\t\"hla_target\",\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t/* thread_count_width; */\n\t4,\t\t\t\t\t\t/* pointer_width; */\n\t16,\t\t\t\t\t\t/* list_next_offset; */\n\t20,\t\t\t\t\t\t/* list_width; */\n\t8,\t\t\t\t\t\t/* list_elem_next_offset; */\n\t12,\t\t\t\t\t\t/* list_elem_content_offset */\n\t0,\t\t\t\t\t\t/* thread_stack_offset; */\n\t52,\t\t\t\t\t\t/* thread_name_offset; */\n\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t&rtos_standard_cortex_m4f_stacking,\n\t&rtos_standard_cortex_m4f_fpu_stacking,\n\t},\n};\n\nstatic bool freertos_detect_rtos(struct target *target);\nstatic int freertos_create(struct target *target);\nstatic int freertos_update_threads(struct rtos *rtos);\nstatic int freertos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs);\nstatic int freertos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\n\nconst struct rtos_type freertos_rtos = {\n\t.name = \"FreeRTOS\",\n\n\t.detect_rtos = freertos_detect_rtos,\n\t.create = freertos_create,\n\t.update_threads = freertos_update_threads,\n\t.get_thread_reg_list = freertos_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = freertos_get_symbol_list_to_lookup,\n};\n\nenum freertos_symbol_values {\n\tFREERTOS_VAL_PX_CURRENT_TCB = 0,\n\tFREERTOS_VAL_PX_READY_TASKS_LISTS = 1,\n\tFREERTOS_VAL_X_DELAYED_TASK_LIST1 = 2,\n\tFREERTOS_VAL_X_DELAYED_TASK_LIST2 = 3,\n\tFREERTOS_VAL_PX_DELAYED_TASK_LIST = 4,\n\tFREERTOS_VAL_PX_OVERFLOW_DELAYED_TASK_LIST = 5,\n\tFREERTOS_VAL_X_PENDING_READY_LIST = 6,\n\tFREERTOS_VAL_X_TASKS_WAITING_TERMINATION = 7,\n\tFREERTOS_VAL_X_SUSPENDED_TASK_LIST = 8,\n\tFREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS = 9,\n\tFREERTOS_VAL_UX_TOP_USED_PRIORITY = 10,\n\tFREERTOS_VAL_X_SCHEDULER_RUNNING = 11,\n};\n\nstruct symbols {\n\tconst char *name;\n\tbool optional;\n};\n\nstatic const struct symbols freertos_symbol_list[] = {\n\t{ \"pxCurrentTCB\", false },\n\t{ \"pxReadyTasksLists\", false },\n\t{ \"xDelayedTaskList1\", false },\n\t{ \"xDelayedTaskList2\", false },\n\t{ \"pxDelayedTaskList\", false },\n\t{ \"pxOverflowDelayedTaskList\", false },\n\t{ \"xPendingReadyList\", false },\n\t{ \"xTasksWaitingTermination\", true }, /* Only if INCLUDE_vTaskDelete */\n\t{ \"xSuspendedTaskList\", true }, /* Only if INCLUDE_vTaskSuspend */\n\t{ \"uxCurrentNumberOfTasks\", false },\n\t{ \"uxTopUsedPriority\", true }, /* Unavailable since v7.5.3 */\n\t{ \"xSchedulerRunning\", false },\n\t{ NULL, false }\n};\n\n/* TODO: */\n/* this is not safe for little endian yet */\n/* may be problems reading if sizes are not 32 bit long integers. */\n/* test mallocs for failure */\n\nstatic int freertos_update_threads(struct rtos *rtos)\n{\n\tint retval;\n\tunsigned int tasks_found = 0;\n\tconst struct freertos_params *param;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tparam = (const struct freertos_params *) rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for FreeRTOS\");\n\t\treturn -3;\n\t}\n\n\tif (rtos->symbols[FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS].address == 0) {\n\t\tLOG_ERROR(\"Don't have the number of threads in FreeRTOS\");\n\t\treturn -2;\n\t}\n\n\tuint32_t thread_list_size = 0;\n\tretval = target_read_u32(rtos->target,\n\t\t\trtos->symbols[FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS].address,\n\t\t\t&thread_list_size);\n\tLOG_DEBUG(\"FreeRTOS: Read uxCurrentNumberOfTasks at 0x%\" PRIx64 \", value %\" PRIu32,\n\t\t\t\t\t\t\t\t\t\trtos->symbols[FREERTOS_VAL_UX_CURRENT_NUMBER_OF_TASKS].address,\n\t\t\t\t\t\t\t\t\t\tthread_list_size);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read FreeRTOS thread count from target\");\n\t\treturn retval;\n\t}\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\t/* read the current thread */\n\tuint32_t pointer_casts_are_bad;\n\tretval = target_read_u32(rtos->target,\n\t\t\trtos->symbols[FREERTOS_VAL_PX_CURRENT_TCB].address,\n\t\t\t&pointer_casts_are_bad);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading current thread in FreeRTOS thread list\");\n\t\treturn retval;\n\t}\n\trtos->current_thread = pointer_casts_are_bad;\n\tLOG_DEBUG(\"FreeRTOS: Read pxCurrentTCB at 0x%\" PRIx64 \", value 0x%\" PRIx64,\n\t\t\t\t\t\t\t\t\t\trtos->symbols[FREERTOS_VAL_PX_CURRENT_TCB].address,\n\t\t\t\t\t\t\t\t\t\trtos->current_thread);\n\n\t/* read scheduler running */\n\tuint32_t scheduler_running;\n\tretval = target_read_u32(rtos->target,\n\t\t\trtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address,\n\t\t\t&scheduler_running);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading FreeRTOS scheduler state\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"FreeRTOS: Read xSchedulerRunning at 0x%\" PRIx64 \", value 0x%\" PRIx32,\n\t\t\t\t\t\t\t\t\t\trtos->symbols[FREERTOS_VAL_X_SCHEDULER_RUNNING].address,\n\t\t\t\t\t\t\t\t\t\tscheduler_running);\n\n\tif ((thread_list_size  == 0) || (rtos->current_thread == 0) || (scheduler_running != 1)) {\n\t\t/* Either : No RTOS threads - there is always at least the current execution though */\n\t\t/* OR     : No current thread - all threads suspended - show the current execution\n\t\t * of idling */\n\t\tchar tmp_str[] = \"Current Execution\";\n\t\tthread_list_size++;\n\t\ttasks_found++;\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t\tif (!rtos->thread_details) {\n\t\t\tLOG_ERROR(\"Error allocating memory for %d threads\", thread_list_size);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\trtos->current_thread = 1;\n\t\trtos->thread_details->threadid = rtos->current_thread;\n\t\trtos->thread_details->exists = true;\n\t\trtos->thread_details->extra_info_str = NULL;\n\t\trtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));\n\t\tstrcpy(rtos->thread_details->thread_name_str, tmp_str);\n\n\t\tif (thread_list_size == 1) {\n\t\t\trtos->thread_count = 1;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* create space for new thread details */\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t\tif (!rtos->thread_details) {\n\t\t\tLOG_ERROR(\"Error allocating memory for %d threads\", thread_list_size);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* Find out how many lists are needed to be read from pxReadyTasksLists, */\n\tif (rtos->symbols[FREERTOS_VAL_UX_TOP_USED_PRIORITY].address == 0) {\n\t\tLOG_ERROR(\"FreeRTOS: uxTopUsedPriority is not defined, consult the OpenOCD manual for a work-around\");\n\t\treturn ERROR_FAIL;\n\t}\n\tuint32_t top_used_priority = 0;\n\tretval = target_read_u32(rtos->target,\n\t\t\trtos->symbols[FREERTOS_VAL_UX_TOP_USED_PRIORITY].address,\n\t\t\t&top_used_priority);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"FreeRTOS: Read uxTopUsedPriority at 0x%\" PRIx64 \", value %\" PRIu32,\n\t\t\t\t\t\t\t\t\t\trtos->symbols[FREERTOS_VAL_UX_TOP_USED_PRIORITY].address,\n\t\t\t\t\t\t\t\t\t\ttop_used_priority);\n\tif (top_used_priority > FREERTOS_MAX_PRIORITIES) {\n\t\tLOG_ERROR(\"FreeRTOS top used priority is unreasonably big, not proceeding: %\" PRIu32,\n\t\t\ttop_used_priority);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* uxTopUsedPriority was defined as configMAX_PRIORITIES - 1\n\t * in old FreeRTOS versions (before V7.5.3)\n\t * Use contrib/rtos-helpers/FreeRTOS-openocd.c to get compatible symbol\n\t * in newer FreeRTOS versions.\n\t * Here we restore the original configMAX_PRIORITIES value */\n\tunsigned int config_max_priorities = top_used_priority + 1;\n\n\tsymbol_address_t *list_of_lists =\n\t\tmalloc(sizeof(symbol_address_t) * (config_max_priorities + 5));\n\tif (!list_of_lists) {\n\t\tLOG_ERROR(\"Error allocating memory for %u priorities\", config_max_priorities);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tunsigned int num_lists;\n\tfor (num_lists = 0; num_lists < config_max_priorities; num_lists++)\n\t\tlist_of_lists[num_lists] = rtos->symbols[FREERTOS_VAL_PX_READY_TASKS_LISTS].address +\n\t\t\tnum_lists * param->list_width;\n\n\tlist_of_lists[num_lists++] = rtos->symbols[FREERTOS_VAL_X_DELAYED_TASK_LIST1].address;\n\tlist_of_lists[num_lists++] = rtos->symbols[FREERTOS_VAL_X_DELAYED_TASK_LIST2].address;\n\tlist_of_lists[num_lists++] = rtos->symbols[FREERTOS_VAL_X_PENDING_READY_LIST].address;\n\tlist_of_lists[num_lists++] = rtos->symbols[FREERTOS_VAL_X_SUSPENDED_TASK_LIST].address;\n\tlist_of_lists[num_lists++] = rtos->symbols[FREERTOS_VAL_X_TASKS_WAITING_TERMINATION].address;\n\n\tfor (unsigned int i = 0; i < num_lists; i++) {\n\t\tif (list_of_lists[i] == 0)\n\t\t\tcontinue;\n\n\t\t/* Read the number of threads in this list */\n\t\tuint32_t list_thread_count = 0;\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\tlist_of_lists[i],\n\t\t\t\t&list_thread_count);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading number of threads in FreeRTOS thread list\");\n\t\t\tfree(list_of_lists);\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"FreeRTOS: Read thread count for list %u at 0x%\" PRIx64 \", value %\" PRIu32,\n\t\t\t\t\t\t\t\t\t\ti, list_of_lists[i], list_thread_count);\n\n\t\tif (list_thread_count == 0)\n\t\t\tcontinue;\n\n\t\t/* Read the location of first list item */\n\t\tuint32_t prev_list_elem_ptr = -1;\n\t\tuint32_t list_elem_ptr = 0;\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\tlist_of_lists[i] + param->list_next_offset,\n\t\t\t\t&list_elem_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading first thread item location in FreeRTOS thread list\");\n\t\t\tfree(list_of_lists);\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"FreeRTOS: Read first item for list %u at 0x%\" PRIx64 \", value 0x%\" PRIx32,\n\t\t\t\t\t\t\t\t\t\ti, list_of_lists[i] + param->list_next_offset, list_elem_ptr);\n\n\t\twhile ((list_thread_count > 0) && (list_elem_ptr != 0) &&\n\t\t\t\t(list_elem_ptr != prev_list_elem_ptr) &&\n\t\t\t\t(tasks_found < thread_list_size)) {\n\t\t\t/* Get the location of the thread structure. */\n\t\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\tlist_elem_ptr + param->list_elem_content_offset,\n\t\t\t\t\t&pointer_casts_are_bad);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading thread list item object in FreeRTOS thread list\");\n\t\t\t\tfree(list_of_lists);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\trtos->thread_details[tasks_found].threadid = pointer_casts_are_bad;\n\t\t\tLOG_DEBUG(\"FreeRTOS: Read Thread ID at 0x%\" PRIx32 \", value 0x%\" PRIx64,\n\t\t\t\t\t\t\t\t\t\tlist_elem_ptr + param->list_elem_content_offset,\n\t\t\t\t\t\t\t\t\t\trtos->thread_details[tasks_found].threadid);\n\n\t\t\t/* get thread name */\n\n\t\t\t#define FREERTOS_THREAD_NAME_STR_SIZE (200)\n\t\t\tchar tmp_str[FREERTOS_THREAD_NAME_STR_SIZE];\n\n\t\t\t/* Read the thread name */\n\t\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t\trtos->thread_details[tasks_found].threadid + param->thread_name_offset,\n\t\t\t\t\tFREERTOS_THREAD_NAME_STR_SIZE,\n\t\t\t\t\t(uint8_t *)&tmp_str);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading first thread item location in FreeRTOS thread list\");\n\t\t\t\tfree(list_of_lists);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\ttmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\\x00';\n\t\t\tLOG_DEBUG(\"FreeRTOS: Read Thread Name at 0x%\" PRIx64 \", value '%s'\",\n\t\t\t\t\t\t\t\t\t\trtos->thread_details[tasks_found].threadid + param->thread_name_offset,\n\t\t\t\t\t\t\t\t\t\ttmp_str);\n\n\t\t\tif (tmp_str[0] == '\\x00')\n\t\t\t\tstrcpy(tmp_str, \"No Name\");\n\n\t\t\trtos->thread_details[tasks_found].thread_name_str =\n\t\t\t\tmalloc(strlen(tmp_str)+1);\n\t\t\tstrcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);\n\t\t\trtos->thread_details[tasks_found].exists = true;\n\n\t\t\tif (rtos->thread_details[tasks_found].threadid == rtos->current_thread) {\n\t\t\t\tchar running_str[] = \"State: Running\";\n\t\t\t\trtos->thread_details[tasks_found].extra_info_str = malloc(\n\t\t\t\t\t\tsizeof(running_str));\n\t\t\t\tstrcpy(rtos->thread_details[tasks_found].extra_info_str,\n\t\t\t\t\trunning_str);\n\t\t\t} else\n\t\t\t\trtos->thread_details[tasks_found].extra_info_str = NULL;\n\n\t\t\ttasks_found++;\n\t\t\tlist_thread_count--;\n\t\t\trtos->thread_count = tasks_found;\n\n\t\t\tprev_list_elem_ptr = list_elem_ptr;\n\t\t\tlist_elem_ptr = 0;\n\t\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\tprev_list_elem_ptr + param->list_elem_next_offset,\n\t\t\t\t\t&list_elem_ptr);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading next thread item location in FreeRTOS thread list\");\n\t\t\t\tfree(list_of_lists);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"FreeRTOS: Read next thread location at 0x%\" PRIx32 \", value 0x%\" PRIx32,\n\t\t\t\t\t\t\t\t\t\tprev_list_elem_ptr + param->list_elem_next_offset,\n\t\t\t\t\t\t\t\t\t\tlist_elem_ptr);\n\t\t}\n\t}\n\n\tfree(list_of_lists);\n\treturn 0;\n}\n\nstatic int freertos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tconst struct freertos_params *param;\n\tint64_t stack_ptr = 0;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tparam = (const struct freertos_params *) rtos->rtos_specific_params;\n\n\t/* Read the stack pointer */\n\tuint32_t pointer_casts_are_bad;\n\tretval = target_read_u32(rtos->target,\n\t\t\tthread_id + param->thread_stack_offset,\n\t\t\t&pointer_casts_are_bad);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack frame from FreeRTOS thread\");\n\t\treturn retval;\n\t}\n\tstack_ptr = pointer_casts_are_bad;\n\tLOG_DEBUG(\"FreeRTOS: Read stack pointer at 0x%\" PRIx64 \", value 0x%\" PRIx64,\n\t\t\t\t\t\t\t\t\t\tthread_id + param->thread_stack_offset,\n\t\t\t\t\t\t\t\t\t\tstack_ptr);\n\n\t/* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4F */\n\tint cm4_fpu_enabled = 0;\n\tstruct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);\n\tif (is_armv7m(armv7m_target)) {\n\t\tif ((armv7m_target->fp_feature == FPV4_SP) || (armv7m_target->fp_feature == FPV5_SP) ||\n\t\t\t\t(armv7m_target->fp_feature == FPV5_DP)) {\n\t\t\t/* Found ARM v7m target which includes a FPU */\n\t\t\tuint32_t cpacr;\n\n\t\t\tretval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not read CPACR register to check FPU state\");\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t/* Check if CP10 and CP11 are set to full access. */\n\t\t\tif (cpacr & 0x00F00000) {\n\t\t\t\t/* Found target with enabled FPU */\n\t\t\t\tcm4_fpu_enabled = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (cm4_fpu_enabled == 1) {\n\t\t/* Read the LR to decide between stacking with or without FPU */\n\t\tuint32_t lr_svc = 0;\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\tstack_ptr + 0x20,\n\t\t\t\t&lr_svc);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_OUTPUT(\"Error reading stack frame from FreeRTOS thread\");\n\t\t\treturn retval;\n\t\t}\n\t\tif ((lr_svc & 0x10) == 0)\n\t\t\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, reg_list, num_regs);\n\t\telse\n\t\t\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, reg_list, num_regs);\n\t} else\n\t\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, reg_list, num_regs);\n}\n\nstatic int freertos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tunsigned int i;\n\t*symbol_list = calloc(\n\t\t\tARRAY_SIZE(freertos_symbol_list), sizeof(struct symbol_table_elem));\n\n\tfor (i = 0; i < ARRAY_SIZE(freertos_symbol_list); i++) {\n\t\t(*symbol_list)[i].symbol_name = freertos_symbol_list[i].name;\n\t\t(*symbol_list)[i].optional = freertos_symbol_list[i].optional;\n\t}\n\n\treturn 0;\n}\n\n#if 0\n\nstatic int freertos_set_current_thread(struct rtos *rtos, threadid_t thread_id)\n{\n\treturn 0;\n}\n\nstatic int freertos_get_thread_ascii_info(struct rtos *rtos, threadid_t thread_id, char **info)\n{\n\tint retval;\n\tconst struct freertos_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = (const struct freertos_params *) rtos->rtos_specific_params;\n\n#define FREERTOS_THREAD_NAME_STR_SIZE (200)\n\tchar tmp_str[FREERTOS_THREAD_NAME_STR_SIZE];\n\n\t/* Read the thread name */\n\tretval = target_read_buffer(rtos->target,\n\t\t\tthread_id + param->thread_name_offset,\n\t\t\tFREERTOS_THREAD_NAME_STR_SIZE,\n\t\t\t(uint8_t *)&tmp_str);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading first thread item location in FreeRTOS thread list\");\n\t\treturn retval;\n\t}\n\ttmp_str[FREERTOS_THREAD_NAME_STR_SIZE-1] = '\\x00';\n\n\tif (tmp_str[0] == '\\x00')\n\t\tstrcpy(tmp_str, \"No Name\");\n\n\t*info = malloc(strlen(tmp_str)+1);\n\tstrcpy(*info, tmp_str);\n\treturn 0;\n}\n\n#endif\n\nstatic bool freertos_detect_rtos(struct target *target)\n{\n\tif ((target->rtos->symbols) &&\n\t\t\t(target->rtos->symbols[FREERTOS_VAL_PX_READY_TASKS_LISTS].address != 0)) {\n\t\t/* looks like FreeRTOS */\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic int freertos_create(struct target *target)\n{\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(freertos_params_list); i++)\n\t\tif (strcmp(freertos_params_list[i].target_name, target->type->name) == 0) {\n\t\t\ttarget->rtos->rtos_specific_params = (void *)&freertos_params_list[i];\n\t\t\treturn 0;\n\t\t}\n\n\tLOG_ERROR(\"Could not find target in FreeRTOS compatibility list\");\n\treturn -1;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/librtos.la\n%C%_librtos_la_SOURCES = \\\n\t%D%/rtos.c \\\n\t%D%/rtos_standard_stackings.c \\\n\t%D%/rtos_ecos_stackings.c  \\\n\t%D%/rtos_chibios_stackings.c \\\n\t%D%/rtos_embkernel_stackings.c \\\n\t%D%/rtos_mqx_stackings.c \\\n\t%D%/rtos_ucos_iii_stackings.c \\\n\t%D%/rtos_riot_stackings.c \\\n\t%D%/rtos_nuttx_stackings.c \\\n\t%D%/FreeRTOS.c \\\n\t%D%/ThreadX.c \\\n\t%D%/eCos.c \\\n\t%D%/linux.c \\\n\t%D%/chibios.c \\\n\t%D%/chromium-ec.c \\\n\t%D%/embKernel.c \\\n\t%D%/mqx.c \\\n\t%D%/uCOS-III.c \\\n\t%D%/nuttx.c \\\n\t%D%/rtkernel.c \\\n\t%D%/hwthread.c \\\n\t%D%/zephyr.c \\\n\t%D%/riot.c \\\n\t%D%/rtos.h \\\n\t%D%/rtos_standard_stackings.h \\\n\t%D%/rtos_ecos_stackings.h \\\n\t%D%/linux_header.h \\\n\t%D%/rtos_chibios_stackings.h \\\n\t%D%/rtos_embkernel_stackings.h \\\n\t%D%/rtos_mqx_stackings.h \\\n\t%D%/rtos_riot_stackings.h \\\n\t%D%/rtos_ucos_iii_stackings.h \\\n\t%D%/rtos_nuttx_stackings.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/ThreadX.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_standard_stackings.h\"\n\nstatic const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr);\nstatic const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr);\n\nstatic int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id);\nstatic int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id);\n\nstatic bool threadx_detect_rtos(struct target *target);\nstatic int threadx_create(struct target *target);\nstatic int threadx_update_threads(struct rtos *rtos);\nstatic int threadx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs);\nstatic int threadx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\n\n\n\nstruct threadx_thread_state {\n\tint value;\n\tconst char *desc;\n};\n\nstatic const struct threadx_thread_state threadx_thread_states[] = {\n\t{ 0,  \"Ready\" },\n\t{ 1,  \"Completed\" },\n\t{ 2,  \"Terminated\" },\n\t{ 3,  \"Suspended\" },\n\t{ 4,  \"Sleeping\" },\n\t{ 5,  \"Waiting - Queue\" },\n\t{ 6,  \"Waiting - Semaphore\" },\n\t{ 7,  \"Waiting - Event flag\" },\n\t{ 8,  \"Waiting - Memory\" },\n\t{ 9,  \"Waiting - Memory\" },\n\t{ 10, \"Waiting - I/O\" },\n\t{ 11, \"Waiting - Filesystem\" },\n\t{ 12, \"Waiting - Network\" },\n\t{ 13, \"Waiting - Mutex\" },\n};\n\n#define THREADX_NUM_STATES ARRAY_SIZE(threadx_thread_states)\n\n#define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4)\nstatic const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_solicited[] = {\n\t{ 0,  -1,   32 },\t\t/* r0        */\n\t{ 1,  -1,   32 },\t\t/* r1        */\n\t{ 2,  -1,   32 },\t\t/* r2        */\n\t{ 3,  -1,   32 },\t\t/* r3        */\n\t{ 4,  0x08, 32 },\t\t/* r4        */\n\t{ 5,  0x0C, 32 },\t\t/* r5        */\n\t{ 6,  0x10, 32 },\t\t/* r6        */\n\t{ 7,  0x14, 32 },\t\t/* r7        */\n\t{ 8,  0x18, 32 },\t\t/* r8        */\n\t{ 9,  0x1C, 32 },\t\t/* r9        */\n\t{ 10, 0x20, 32 },\t\t/* r10       */\n\t{ 11, 0x24, 32 },\t\t/* r11       */\n\t{ 12, -1,   32 },\t\t/* r12       */\n\t{ 13, -2,   32 },\t\t/* sp (r13)  */\n\t{ 14, 0x28, 32 },\t\t/* lr (r14)  */\n\t{ 15, -1,   32 },\t\t/* pc (r15)  */\n\t/*{ 16, -1,   32 },*/\t\t/* lr (r14)  */\n\t/*{ 17, 0x28, 32 },*/\t\t/* pc (r15)  */\n\t{ 16, 0x04, 32 },\t\t/* xPSR      */\n};\n#define ARM926EJS_REGISTERS_SIZE_INTERRUPT (17 * 4)\nstatic const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_interrupt[] = {\n\t{ 0,  0x08, 32 },\t\t/* r0        */\n\t{ 1,  0x0C, 32 },\t\t/* r1        */\n\t{ 2,  0x10, 32 },\t\t/* r2        */\n\t{ 3,  0x14, 32 },\t\t/* r3        */\n\t{ 4,  0x18, 32 },\t\t/* r4        */\n\t{ 5,  0x1C, 32 },\t\t/* r5        */\n\t{ 6,  0x20, 32 },\t\t/* r6        */\n\t{ 7,  0x24, 32 },\t\t/* r7        */\n\t{ 8,  0x28, 32 },\t\t/* r8        */\n\t{ 9,  0x2C, 32 },\t\t/* r9        */\n\t{ 10, 0x30, 32 },\t\t/* r10       */\n\t{ 11, 0x34, 32 },\t\t/* r11       */\n\t{ 12, 0x38, 32 },\t\t/* r12       */\n\t{ 13, -2,   32 },\t\t/* sp (r13)  */\n\t{ 14, 0x3C, 32 },\t\t/* lr (r14)  */\n\t{ 15, 0x40, 32 },\t\t/* pc (r15)  */\n\t{ 16, 0x04, 32 },\t\t/* xPSR      */\n};\n\nstatic const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = {\n{\n\t.stack_registers_size = ARM926EJS_REGISTERS_SIZE_SOLICITED,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 17,\n\t.register_offsets = rtos_threadx_arm926ejs_stack_offsets_solicited\n},\n{\n\t.stack_registers_size = ARM926EJS_REGISTERS_SIZE_INTERRUPT,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 17,\n\t.register_offsets = rtos_threadx_arm926ejs_stack_offsets_interrupt\n},\n};\n\nstruct threadx_params {\n\tconst char *target_name;\n\tunsigned char pointer_width;\n\tunsigned char thread_stack_offset;\n\tunsigned char thread_name_offset;\n\tunsigned char thread_state_offset;\n\tunsigned char thread_next_offset;\n\tconst struct rtos_register_stacking *stacking_info;\n\tsize_t stacking_info_nb;\n\tconst struct rtos_register_stacking* (*fn_get_stacking_info)(const struct rtos *rtos, int64_t stack_ptr);\n\tint (*fn_is_thread_id_valid)(const struct rtos *rtos, int64_t thread_id);\n};\n\nstatic const struct threadx_params threadx_params_list[] = {\n\t{\n\t\"cortex_m\",\t\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t\t/* pointer_width; */\n\t8,\t\t\t\t\t\t\t/* thread_stack_offset; */\n\t40,\t\t\t\t\t\t\t/* thread_name_offset; */\n\t48,\t\t\t\t\t\t\t/* thread_state_offset; */\n\t136,\t\t\t\t\t\t/* thread_next_offset */\n\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t1,\t\t\t\t\t\t\t/* stacking_info_nb */\n\tNULL,\t\t\t\t\t\t/* fn_get_stacking_info */\n\tNULL,\t\t\t\t\t\t/* fn_is_thread_id_valid */\n\t},\n\t{\n\t\"cortex_r4\",\t\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t\t/* pointer_width; */\n\t8,\t\t\t\t\t\t\t/* thread_stack_offset; */\n\t40,\t\t\t\t\t\t\t/* thread_name_offset; */\n\t48,\t\t\t\t\t\t\t/* thread_state_offset; */\n\t136,\t\t\t\t\t\t/* thread_next_offset */\n\t&rtos_standard_cortex_r4_stacking,\t/* stacking_info */\n\t1,\t\t\t\t\t\t\t/* stacking_info_nb */\n\tNULL,\t\t\t\t\t\t/* fn_get_stacking_info */\n\tNULL,\t\t\t\t\t\t/* fn_is_thread_id_valid */\n\t},\n\t{\n\t\"arm926ejs\",\t\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t\t/* pointer_width; */\n\t8,\t\t\t\t\t\t\t/* thread_stack_offset; */\n\t40,\t\t\t\t\t\t\t/* thread_name_offset; */\n\t48,\t\t\t\t\t\t\t/* thread_state_offset; */\n\t136,\t\t\t\t\t\t/* thread_next_offset */\n\trtos_threadx_arm926ejs_stacking,\t/* stacking_info */\n\t2,\t\t\t\t\t\t\t\t\t/* stacking_info_nb */\n\tget_stacking_info_arm926ejs,\t\t/* fn_get_stacking_info */\n\tis_thread_id_valid_arm926ejs,\t\t/* fn_is_thread_id_valid */\n\t},\n\t{\n\t\"hla_target\",\t\t\t\t/* target_name */\n\t4,\t\t\t\t\t\t\t/* pointer_width; */\n\t8,\t\t\t\t\t\t\t/* thread_stack_offset; */\n\t40,\t\t\t\t\t\t\t/* thread_name_offset; */\n\t48,\t\t\t\t\t\t\t/* thread_state_offset; */\n\t136,\t\t\t\t\t\t/* thread_next_offset */\n\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t1,\t\t\t\t\t\t\t/* stacking_info_nb */\n\tNULL,\t\t\t\t\t\t/* fn_get_stacking_info */\n\tNULL,\t\t\t\t\t\t/* fn_is_thread_id_valid */\n\t},\n};\n\nenum threadx_symbol_values {\n\tTHREADX_VAL_TX_THREAD_CURRENT_PTR = 0,\n\tTHREADX_VAL_TX_THREAD_CREATED_PTR = 1,\n\tTHREADX_VAL_TX_THREAD_CREATED_COUNT = 2,\n};\n\nstatic const char * const threadx_symbol_list[] = {\n\t\"_tx_thread_current_ptr\",\n\t\"_tx_thread_created_ptr\",\n\t\"_tx_thread_created_count\",\n\tNULL\n};\n\nconst struct rtos_type threadx_rtos = {\n\t.name = \"ThreadX\",\n\n\t.detect_rtos = threadx_detect_rtos,\n\t.create = threadx_create,\n\t.update_threads = threadx_update_threads,\n\t.get_thread_reg_list = threadx_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = threadx_get_symbol_list_to_lookup,\n};\n\nstatic const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr)\n{\n\tconst struct threadx_params *param = (const struct threadx_params *) rtos->rtos_specific_params;\n\n\tif (param->fn_get_stacking_info)\n\t\treturn param->fn_get_stacking_info(rtos, stack_ptr);\n\n\treturn param->stacking_info + 0;\n}\n\nstatic int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id)\n{\n\tconst struct threadx_params *param;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn 0; /* invalid */\n\n\tparam = (const struct threadx_params *) rtos->rtos_specific_params;\n\n\tif (param->fn_is_thread_id_valid)\n\t\treturn param->fn_is_thread_id_valid(rtos, thread_id);\n\n\treturn (thread_id != 0);\n}\n\nstatic const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr)\n{\n\tconst struct threadx_params *param = (const struct threadx_params *) rtos->rtos_specific_params;\n\tint\tretval;\n\tuint32_t flag;\n\n\tretval = target_read_buffer(rtos->target,\n\t\t\tstack_ptr,\n\t\t\tsizeof(flag),\n\t\t\t(uint8_t *)&flag);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack data from ThreadX thread: stack_ptr=0x%\" PRIx64, stack_ptr);\n\t\treturn NULL;\n\t}\n\n\tif (flag == 0) {\n\t\tLOG_DEBUG(\"  solicited stack\");\n\t\treturn param->stacking_info + 0;\n\t} else {\n\t\tLOG_DEBUG(\"  interrupt stack: %\" PRIu32, flag);\n\t\treturn param->stacking_info + 1;\n\t}\n}\n\nstatic int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id)\n{\n\treturn (thread_id != 0 && thread_id != 1);\n}\n\nstatic int threadx_update_threads(struct rtos *rtos)\n{\n\tint retval;\n\tint tasks_found = 0;\n\tint thread_list_size = 0;\n\tconst struct threadx_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = (const struct threadx_params *) rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for ThreadX\");\n\t\treturn -4;\n\t}\n\n\tif (rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_COUNT].address == 0) {\n\t\tLOG_ERROR(\"Don't have the number of threads in ThreadX\");\n\t\treturn -2;\n\t}\n\n\t/* read the number of threads */\n\tretval = target_read_buffer(rtos->target,\n\t\t\trtos->symbols[THREADX_VAL_TX_THREAD_CREATED_COUNT].address,\n\t\t\t4,\n\t\t\t(uint8_t *)&thread_list_size);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read ThreadX thread count from target\");\n\t\treturn retval;\n\t}\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\t/* read the current thread id */\n\tretval = target_read_buffer(rtos->target,\n\t\t\trtos->symbols[THREADX_VAL_TX_THREAD_CURRENT_PTR].address,\n\t\t\t4,\n\t\t\t(uint8_t *)&rtos->current_thread);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read ThreadX current thread from target\");\n\t\treturn retval;\n\t}\n\n\tif ((thread_list_size  == 0) || (rtos->current_thread == 0)) {\n\t\t/* Either : No RTOS threads - there is always at least the current execution though */\n\t\t/* OR     : No current thread - all threads suspended - show the current execution\n\t\t * of idling */\n\t\tchar tmp_str[] = \"Current Execution\";\n\t\tthread_list_size++;\n\t\ttasks_found++;\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t\trtos->thread_details->threadid = 1;\n\t\trtos->thread_details->exists = true;\n\t\trtos->thread_details->extra_info_str = NULL;\n\t\trtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));\n\t\tstrcpy(rtos->thread_details->thread_name_str, tmp_str);\n\n\t\t/* If we just invented thread 1 to represent the current execution, we\n\t\t * need to make sure the RTOS object also claims it's the current thread\n\t\t * so that threadx_get_thread_reg_list() doesn't attempt to read a\n\t\t * thread control block at 0x00000001. */\n\t\trtos->current_thread = 1;\n\n\t\tif (thread_list_size == 0) {\n\t\t\trtos->thread_count = 1;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* create space for new thread details */\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t}\n\n\t/* Read the pointer to the first thread */\n\tint64_t thread_ptr = 0;\n\tretval = target_read_buffer(rtos->target,\n\t\t\trtos->symbols[THREADX_VAL_TX_THREAD_CREATED_PTR].address,\n\t\t\tparam->pointer_width,\n\t\t\t(uint8_t *)&thread_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read ThreadX thread location from target\");\n\t\treturn retval;\n\t}\n\n\t/* loop over all threads */\n\tint64_t prev_thread_ptr = 0;\n\twhile ((thread_ptr != prev_thread_ptr) && (tasks_found < thread_list_size)) {\n\n\t\t#define THREADX_THREAD_NAME_STR_SIZE (200)\n\t\tchar tmp_str[THREADX_THREAD_NAME_STR_SIZE];\n\t\tunsigned int i = 0;\n\t\tint64_t name_ptr = 0;\n\n\t\t/* Save the thread pointer */\n\t\trtos->thread_details[tasks_found].threadid = thread_ptr;\n\n\t\t/* read the name pointer */\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_ptr + param->thread_name_offset,\n\t\t\t\tparam->pointer_width,\n\t\t\t\t(uint8_t *)&name_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read ThreadX thread name pointer from target\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Read the thread name */\n\t\ttmp_str[0] = '\\x00';\n\n\t\t/* Check if thread has a valid name */\n\t\tif (name_ptr != 0) {\n\t\t\tretval =\n\t\t\t\ttarget_read_buffer(rtos->target,\n\t\t\t\t\tname_ptr,\n\t\t\t\t\tTHREADX_THREAD_NAME_STR_SIZE,\n\t\t\t\t\t(uint8_t *)&tmp_str);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading thread name from ThreadX target\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\ttmp_str[THREADX_THREAD_NAME_STR_SIZE - 1] = '\\x00';\n\t\t}\n\n\t\tif (tmp_str[0] == '\\x00')\n\t\t\tstrcpy(tmp_str, \"No Name\");\n\n\t\trtos->thread_details[tasks_found].thread_name_str =\n\t\t\tmalloc(strlen(tmp_str)+1);\n\t\tstrcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);\n\n\t\t/* Read the thread status */\n\t\tint64_t thread_status = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_ptr + param->thread_state_offset,\n\t\t\t\t4,\n\t\t\t\t(uint8_t *)&thread_status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading thread state from ThreadX target\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tfor (i = 0; (i < THREADX_NUM_STATES) &&\n\t\t\t\t(threadx_thread_states[i].value != thread_status); i++) {\n\t\t\t/* empty */\n\t\t}\n\n\t\tconst char *state_desc;\n\t\tif  (i < THREADX_NUM_STATES)\n\t\t\tstate_desc = threadx_thread_states[i].desc;\n\t\telse\n\t\t\tstate_desc = \"Unknown state\";\n\n\t\trtos->thread_details[tasks_found].extra_info_str = malloc(strlen(\n\t\t\t\t\tstate_desc)+8);\n\t\tsprintf(rtos->thread_details[tasks_found].extra_info_str, \"State: %s\", state_desc);\n\n\t\trtos->thread_details[tasks_found].exists = true;\n\n\t\ttasks_found++;\n\t\tprev_thread_ptr = thread_ptr;\n\n\t\t/* Get the location of the next thread structure. */\n\t\tthread_ptr = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tprev_thread_ptr + param->thread_next_offset,\n\t\t\t\tparam->pointer_width,\n\t\t\t\t(uint8_t *) &thread_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading next thread pointer in ThreadX thread list\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\trtos->thread_count = tasks_found;\n\n\treturn 0;\n}\n\nstatic int threadx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tconst struct threadx_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (!is_thread_id_valid(rtos, thread_id))\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = (const struct threadx_params *) rtos->rtos_specific_params;\n\n\t/* Read the stack pointer */\n\tint64_t stack_ptr = 0;\n\tretval = target_read_buffer(rtos->target,\n\t\t\tthread_id + param->thread_stack_offset,\n\t\t\tparam->pointer_width,\n\t\t\t(uint8_t *)&stack_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack frame from ThreadX thread\");\n\t\treturn retval;\n\t}\n\n\tLOG_INFO(\"thread: 0x%\" PRIx64 \", stack_ptr=0x%\" PRIx64, (uint64_t)thread_id, (uint64_t)stack_ptr);\n\n\tif (stack_ptr == 0) {\n\t\tLOG_ERROR(\"null stack pointer in thread\");\n\t\treturn -5;\n\t}\n\n\tconst struct rtos_register_stacking *stacking_info =\n\t\t\tget_stacking_info(rtos, stack_ptr);\n\n\tif (!stacking_info) {\n\t\tLOG_ERROR(\"Unknown stacking info for thread id=0x%\" PRIx64, (uint64_t)thread_id);\n\t\treturn -6;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target, stacking_info, stack_ptr, reg_list, num_regs);\n}\n\nstatic int threadx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tunsigned int i;\n\t*symbol_list = calloc(\n\t\t\tARRAY_SIZE(threadx_symbol_list), sizeof(struct symbol_table_elem));\n\n\tfor (i = 0; i < ARRAY_SIZE(threadx_symbol_list); i++)\n\t\t(*symbol_list)[i].symbol_name = threadx_symbol_list[i];\n\n\treturn 0;\n}\n\nstatic bool threadx_detect_rtos(struct target *target)\n{\n\tif ((target->rtos->symbols) &&\n\t\t\t(target->rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_PTR].address != 0)) {\n\t\t/* looks like ThreadX */\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n#if 0\n\nstatic int threadx_set_current_thread(struct rtos *rtos, threadid_t thread_id)\n{\n\treturn 0;\n}\n\nstatic int threadx_get_thread_detail(struct rtos *rtos,\n\tthreadid_t thread_id,\n\tstruct thread_detail *detail)\n{\n\tunsigned int i = 0;\n\tint retval;\n\n#define THREADX_THREAD_NAME_STR_SIZE (200)\n\tchar tmp_str[THREADX_THREAD_NAME_STR_SIZE];\n\n\tconst struct threadx_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = (const struct threadx_params *) rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for ThreadX\");\n\t\treturn -3;\n\t}\n\n\tdetail->threadid = thread_id;\n\n\tint64_t name_ptr = 0;\n\t/* read the name pointer */\n\tretval = target_read_buffer(rtos->target,\n\t\t\tthread_id + param->thread_name_offset,\n\t\t\tparam->pointer_width,\n\t\t\t(uint8_t *)&name_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read ThreadX thread name pointer from target\");\n\t\treturn retval;\n\t}\n\n\t/* Read the thread name */\n\tretval = target_read_buffer(rtos->target,\n\t\t\tname_ptr,\n\t\t\tTHREADX_THREAD_NAME_STR_SIZE,\n\t\t\t(uint8_t *)&tmp_str);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading thread name from ThreadX target\");\n\t\treturn retval;\n\t}\n\ttmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\\x00';\n\n\tif (tmp_str[0] == '\\x00')\n\t\tstrcpy(tmp_str, \"No Name\");\n\n\tdetail->thread_name_str = malloc(strlen(tmp_str)+1);\n\n\t/* Read the thread status */\n\tint64_t thread_status = 0;\n\tretval =\n\t\ttarget_read_buffer(rtos->target,\n\t\t\tthread_id + param->thread_state_offset,\n\t\t\t4,\n\t\t\t(uint8_t *)&thread_status);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading thread state from ThreadX target\");\n\t\treturn retval;\n\t}\n\n\tfor (i = 0; (i < THREADX_NUM_STATES) &&\n\t\t\t(threadx_thread_states[i].value != thread_status); i++) {\n\t\t/* empty */\n\t}\n\n\tchar *state_desc;\n\tif  (i < THREADX_NUM_STATES)\n\t\tstate_desc = threadx_thread_states[i].desc;\n\telse\n\t\tstate_desc = \"Unknown state\";\n\n\tdetail->extra_info_str = malloc(strlen(state_desc)+1);\n\n\tdetail->exists = true;\n\n\treturn 0;\n}\n\n#endif\n\nstatic int threadx_create(struct target *target)\n{\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(threadx_params_list); i++)\n\t\tif (strcmp(threadx_params_list[i].target_name, target->type->name) == 0) {\n\t\t\ttarget->rtos->rtos_specific_params = (void *)&threadx_params_list[i];\n\t\t\ttarget->rtos->current_thread = 0;\n\t\t\ttarget->rtos->thread_details = NULL;\n\t\t\treturn 0;\n\t\t}\n\n\tLOG_ERROR(\"Could not find target in ThreadX compatibility list\");\n\treturn -1;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/chibios.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2012 by Matthias Blaicher                               *\n *   Matthias Blaicher - matthias@blaicher.com                             *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"target/armv7m.h\"\n#include \"target/cortex_m.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_chibios_stackings.h\"\n\n/**\n * @brief   ChibiOS/RT memory signature record.\n *\n * @details Definition copied from os/kernel/include/chregistry.h of ChibiOS/RT.\n */\nstruct chibios_chdebug {\n\tchar      ch_identifier[4];       /**< @brief Always set to \"main\".       */\n\tuint8_t   ch_zero;                /**< @brief Must be zero.               */\n\tuint8_t   ch_size;                /**< @brief Size of this structure.     */\n\tuint16_t  ch_version;             /**< @brief Encoded ChibiOS/RT version. */\n\tuint8_t   ch_ptrsize;             /**< @brief Size of a pointer.          */\n\tuint8_t   ch_timesize;            /**< @brief Size of a @p systime_t.     */\n\tuint8_t   ch_threadsize;          /**< @brief Size of a @p Thread struct. */\n\tuint8_t   cf_off_prio;            /**< @brief Offset of @p p_prio field.  */\n\tuint8_t   cf_off_ctx;             /**< @brief Offset of @p p_ctx field.   */\n\tuint8_t   cf_off_newer;           /**< @brief Offset of @p p_newer field. */\n\tuint8_t   cf_off_older;           /**< @brief Offset of @p p_older field. */\n\tuint8_t   cf_off_name;            /**< @brief Offset of @p p_name field.  */\n\tuint8_t   cf_off_stklimit;        /**< @brief Offset of @p p_stklimit\n\t\t\t\t\t\t\t\t\t\t\t\tfield.                        */\n\tuint8_t   cf_off_state;           /**< @brief Offset of @p p_state field. */\n\tuint8_t   cf_off_flags;           /**< @brief Offset of @p p_flags field. */\n\tuint8_t   cf_off_refs;            /**< @brief Offset of @p p_refs field.  */\n\tuint8_t   cf_off_preempt;         /**< @brief Offset of @p p_preempt\n\t\t\t\t\t\t\t\t\t\t\t\tfield.                        */\n\tuint8_t   cf_off_time;            /**< @brief Offset of @p p_time field.  */\n};\n\n#define GET_CH_KERNEL_MAJOR(coded_version) ((coded_version >> 11) & 0x1f)\n#define GET_CH_KERNEL_MINOR(coded_version) ((coded_version >> 6) & 0x1f)\n#define GET_CH_KERNEL_PATCH(coded_version) ((coded_version >> 0) & 0x3f)\n\n/**\n * @brief ChibiOS thread states.\n */\nstatic const char * const chibios_thread_states[] = { \"READY\", \"CURRENT\",\n\"WTSTART\", \"SUSPENDED\", \"QUEUED\", \"WTSEM\", \"WTMTX\", \"WTCOND\", \"SLEEPING\",\n\"WTEXIT\", \"WTOREVT\", \"WTANDEVT\", \"SNDMSGQ\", \"SNDMSG\", \"WTMSG\", \"FINAL\"\n};\n\n#define CHIBIOS_NUM_STATES ARRAY_SIZE(chibios_thread_states)\n\n/* Maximum ChibiOS thread name. There is no real limit set by ChibiOS but 64\n * chars ought to be enough.\n */\n#define CHIBIOS_THREAD_NAME_STR_SIZE (64)\n\nstruct chibios_params {\n\tconst char *target_name;\n\n\tstruct chibios_chdebug *signature;\n\tconst struct rtos_register_stacking *stacking_info;\n};\n\nstatic struct chibios_params chibios_params_list[] = {\n\t{\n\t\"cortex_m\",\t\t\t\t\t\t\t/* target_name */\n\tNULL,\n\tNULL,\t\t\t\t\t\t\t\t\t/* stacking_info */\n\t},\n\t{\n\t\"hla_target\",\t\t\t\t\t\t\t/* target_name */\n\tNULL,\n\tNULL,\t\t\t\t\t\t\t\t\t/* stacking_info */\n\t}\n};\n\nstatic bool chibios_detect_rtos(struct target *target);\nstatic int chibios_create(struct target *target);\nstatic int chibios_update_threads(struct rtos *rtos);\nstatic int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs);\nstatic int chibios_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\n\nconst struct rtos_type chibios_rtos = {\n\t.name = \"chibios\",\n\n\t.detect_rtos = chibios_detect_rtos,\n\t.create = chibios_create,\n\t.update_threads = chibios_update_threads,\n\t.get_thread_reg_list = chibios_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = chibios_get_symbol_list_to_lookup,\n};\n\n\n/* In ChibiOS/RT 3.0 the rlist structure has become part of a system\n * data structure ch. We declare both symbols as optional and later\n * use whatever is available.\n */\n\nenum chibios_symbol_values {\n\tCHIBIOS_VAL_RLIST = 0,\n\tCHIBIOS_VAL_CH = 1,\n\tCHIBIOS_VAL_CH_DEBUG = 2\n};\n\nstatic struct symbol_table_elem chibios_symbol_list[] = {\n\t{ \"rlist\", 0, true},\t\t/* Thread ready list */\n\t{ \"ch\", 0, true},\t\t\t/* System data structure */\n\t{ \"ch_debug\", 0, false},\t/* Memory Signature containing offsets of fields in rlist */\n\t{ NULL, 0, false}\n};\n\n/* Offset of the rlist structure within the system data structure (ch) */\n#define CH_RLIST_OFFSET 0x00\n\nstatic int chibios_update_memory_signature(struct rtos *rtos)\n{\n\tint retval;\n\tstruct chibios_params *param;\n\tstruct chibios_chdebug *signature;\n\n\tparam = (struct chibios_params *) rtos->rtos_specific_params;\n\n\t/* Free existing memory description.*/\n\tfree(param->signature);\n\tparam->signature = NULL;\n\n\tsignature = malloc(sizeof(*signature));\n\tif (!signature) {\n\t\tLOG_ERROR(\"Could not allocate space for ChibiOS/RT memory signature\");\n\t\treturn -1;\n\t}\n\n\tretval = target_read_buffer(rtos->target,\n\t\t\t\t\t\t\t\trtos->symbols[CHIBIOS_VAL_CH_DEBUG].address,\n\t\t\t\t\t\t\t\tsizeof(*signature),\n\t\t\t\t\t\t\t\t(uint8_t *) signature);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read ChibiOS/RT memory signature from target\");\n\t\tgoto errfree;\n\t}\n\n\tif (strncmp(signature->ch_identifier, \"main\", 4) != 0) {\n\t\tLOG_ERROR(\"Memory signature identifier does not contain magic bytes.\");\n\t\tgoto errfree;\n\t}\n\n\tif (signature->ch_size < sizeof(*signature)) {\n\t\tLOG_ERROR(\"ChibiOS/RT memory signature claims to be smaller \"\n\t\t\t\t\"than expected\");\n\t\tgoto errfree;\n\t}\n\n\tif (signature->ch_size > sizeof(*signature)) {\n\t\tLOG_WARNING(\"ChibiOS/RT memory signature claims to be bigger than\"\n\t\t\t\t\t\" expected. Assuming compatibility...\");\n\t}\n\n\t/* Convert endianness of version field */\n\tconst uint8_t *versiontarget = (const uint8_t *)\n\t\t\t\t\t\t\t\t\t\t&signature->ch_version;\n\tsignature->ch_version = rtos->target->endianness == TARGET_LITTLE_ENDIAN ?\n\t\t\tle_to_h_u32(versiontarget) : be_to_h_u32(versiontarget);\n\n\tconst uint16_t ch_version = signature->ch_version;\n\tLOG_INFO(\"Successfully loaded memory map of ChibiOS/RT target \"\n\t\t\t\"running version %i.%i.%i\", GET_CH_KERNEL_MAJOR(ch_version),\n\t\t\tGET_CH_KERNEL_MINOR(ch_version), GET_CH_KERNEL_PATCH(ch_version));\n\n\t/* Currently, we have the inherent assumption that all address pointers\n\t * are 32 bit wide. */\n\tif (signature->ch_ptrsize != sizeof(uint32_t)) {\n\t\tLOG_ERROR(\"ChibiOS/RT target memory signature claims an address \"\n\t\t\t\t  \"width unequal to 32 bits!\");\n\t\tfree(signature);\n\t\treturn -1;\n\t}\n\n\tparam->signature = signature;\n\treturn 0;\n\nerrfree:\n\t/* Error reading the ChibiOS memory structure */\n\tfree(signature);\n\tparam->signature = NULL;\n\treturn -1;\n}\n\n\nstatic int chibios_update_stacking(struct rtos *rtos)\n{\n\t/* Sometimes the stacking can not be determined only by looking at the\n\t * target name but only a runtime.\n\t *\n\t * For example, this is the case for Cortex-M4 targets and ChibiOS which\n\t * only stack the FPU registers if it is enabled during ChibiOS build.\n\t *\n\t * Terminating which stacking is used is target depending.\n\t *\n\t * Assumptions:\n\t *  - Once ChibiOS is actually initialized, the stacking is fixed.\n\t *  - During startup code, the FPU might not be initialized and the\n\t *    detection might fail.\n\t *  - Since no threads are running during startup, the problem is solved\n\t *    by delaying stacking detection until there are more threads\n\t *    available than the current execution. In which case\n\t *    chibios_get_thread_reg_list is called.\n\t */\n\tint retval;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tstruct chibios_params *param;\n\tparam = (struct chibios_params *) rtos->rtos_specific_params;\n\n\t/* Check for armv7m with *enabled* FPU, i.e. a Cortex-M4  */\n\tstruct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);\n\tif (is_armv7m(armv7m_target)) {\n\t\tif (armv7m_target->fp_feature != FP_NONE) {\n\t\t\t/* Found ARM v7m target which includes a FPU */\n\t\t\tuint32_t cpacr;\n\n\t\t\tretval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not read CPACR register to check FPU state\");\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t/* Check if CP10 and CP11 are set to full access.\n\t\t\t * In ChibiOS this is done in ResetHandler() in crt0.c */\n\t\t\tif (cpacr & 0x00F00000) {\n\t\t\t\tLOG_DEBUG(\"Enabled FPU detected.\");\n\t\t\t\tparam->stacking_info = &rtos_chibios_arm_v7m_stacking_w_fpu;\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\n\t\t/* Found ARM v7m target with no or disabled FPU */\n\t\tparam->stacking_info = &rtos_chibios_arm_v7m_stacking;\n\t\treturn 0;\n\t}\n\n\treturn -1;\n}\n\nstatic int chibios_update_threads(struct rtos *rtos)\n{\n\tint retval;\n\tconst struct chibios_params *param;\n\tint tasks_found = 0;\n\tint rtos_valid = -1;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for ChibiOS\");\n\t\treturn -3;\n\t}\n\n\tparam = (const struct chibios_params *) rtos->rtos_specific_params;\n\t/* Update the memory signature saved in the target memory */\n\tif (!param->signature) {\n\t\tretval = chibios_update_memory_signature(rtos);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Reading the memory signature of ChibiOS/RT failed\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\t/* ChibiOS does not save the current thread count. We have to first\n\t * parse the double linked thread list to check for errors and the number of\n\t * threads. */\n\tconst uint32_t rlist = rtos->symbols[CHIBIOS_VAL_RLIST].address ?\n\t\trtos->symbols[CHIBIOS_VAL_RLIST].address :\n\t\trtos->symbols[CHIBIOS_VAL_CH].address + CH_RLIST_OFFSET /* ChibiOS3 */;\n\tconst struct chibios_chdebug *signature = param->signature;\n\tuint32_t current;\n\tuint32_t previous;\n\tuint32_t older;\n\n\tcurrent = rlist;\n\tprevious = rlist;\n\twhile (1) {\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t\t current + signature->cf_off_newer, &current);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read next ChibiOS thread\");\n\t\t\treturn retval;\n\t\t}\n\t\t/* Could be NULL if the kernel is not initialized yet or if the\n\t\t * registry is corrupted. */\n\t\tif (current == 0) {\n\t\t\tLOG_ERROR(\"ChibiOS registry integrity check failed, NULL pointer\");\n\n\t\t\trtos_valid = 0;\n\t\t\tbreak;\n\t\t}\n\t\t/* Fetch previous thread in the list as a integrity check. */\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t\t current + signature->cf_off_older, &older);\n\t\tif ((retval != ERROR_OK) || (older == 0) || (older != previous)) {\n\t\t\tLOG_ERROR(\"ChibiOS registry integrity check failed, \"\n\t\t\t\t\t\t\"double linked list violation\");\n\t\t\trtos_valid = 0;\n\t\t\tbreak;\n\t\t}\n\t\t/* Check for full iteration of the linked list. */\n\t\tif (current == rlist)\n\t\t\tbreak;\n\t\ttasks_found++;\n\t\tprevious = current;\n\t}\n\tif (!rtos_valid) {\n\t\t/* No RTOS, there is always at least the current execution, though */\n\t\tLOG_INFO(\"Only showing current execution because of a broken \"\n\t\t\t\t\"ChibiOS thread registry.\");\n\n\t\tconst char tmp_thread_name[] = \"Current Execution\";\n\t\tconst char tmp_thread_extra_info[] = \"No RTOS thread\";\n\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail));\n\t\trtos->thread_details->threadid = 1;\n\t\trtos->thread_details->exists = true;\n\n\t\trtos->thread_details->extra_info_str = malloc(\n\t\t\t\tsizeof(tmp_thread_extra_info));\n\t\tstrcpy(rtos->thread_details->extra_info_str, tmp_thread_extra_info);\n\n\t\trtos->thread_details->thread_name_str = malloc(\n\t\t\t\tsizeof(tmp_thread_name));\n\t\tstrcpy(rtos->thread_details->thread_name_str, tmp_thread_name);\n\n\t\trtos->current_thread = 1;\n\t\trtos->thread_count = 1;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* create space for new thread details */\n\trtos->thread_details = malloc(\n\t\t\tsizeof(struct thread_detail) * tasks_found);\n\tif (!rtos->thread_details) {\n\t\tLOG_ERROR(\"Could not allocate space for thread details\");\n\t\treturn -1;\n\t}\n\n\trtos->thread_count = tasks_found;\n\t/* Loop through linked list. */\n\tstruct thread_detail *curr_thrd_details = rtos->thread_details;\n\twhile (curr_thrd_details < rtos->thread_details + tasks_found) {\n\t\tuint32_t name_ptr = 0;\n\t\tchar tmp_str[CHIBIOS_THREAD_NAME_STR_SIZE];\n\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t\t current + signature->cf_off_newer, &current);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read next ChibiOS thread\");\n\t\t\treturn -6;\n\t\t}\n\n\t\t/* Check for full iteration of the linked list. */\n\t\tif (current == rlist)\n\t\t\tbreak;\n\n\t\t/* Save the thread pointer */\n\t\tcurr_thrd_details->threadid = current;\n\n\t\t/* read the name pointer */\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t\t current + signature->cf_off_name, &name_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read ChibiOS thread name pointer from target\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Read the thread name */\n\t\tretval = target_read_buffer(rtos->target, name_ptr,\n\t\t\t\t\t\t\t\t\tCHIBIOS_THREAD_NAME_STR_SIZE,\n\t\t\t\t\t\t\t\t\t(uint8_t *)&tmp_str);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading thread name from ChibiOS target\");\n\t\t\treturn retval;\n\t\t}\n\t\ttmp_str[CHIBIOS_THREAD_NAME_STR_SIZE - 1] = '\\x00';\n\n\t\tif (tmp_str[0] == '\\x00')\n\t\t\tstrcpy(tmp_str, \"No Name\");\n\n\t\tcurr_thrd_details->thread_name_str = malloc(\n\t\t\t\tstrlen(tmp_str) + 1);\n\t\tstrcpy(curr_thrd_details->thread_name_str, tmp_str);\n\n\t\t/* State info */\n\t\tuint8_t thread_state;\n\t\tconst char *state_desc;\n\n\t\tretval = target_read_u8(rtos->target,\n\t\t\t\t\t\t\t\tcurrent + signature->cf_off_state, &thread_state);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading thread state from ChibiOS target\");\n\t\t\treturn retval;\n\t\t}\n\n\n\t\tif (thread_state < CHIBIOS_NUM_STATES)\n\t\t\tstate_desc = chibios_thread_states[thread_state];\n\t\telse\n\t\t\tstate_desc = \"Unknown\";\n\n\t\tcurr_thrd_details->extra_info_str = malloc(strlen(\n\t\t\t\t\tstate_desc)+8);\n\t\tsprintf(curr_thrd_details->extra_info_str, \"State: %s\", state_desc);\n\n\t\tcurr_thrd_details->exists = true;\n\n\t\tcurr_thrd_details++;\n\t}\n\n\tuint32_t current_thrd;\n\t/* NOTE: By design, cf_off_name equals readylist_current_offset */\n\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t rlist + signature->cf_off_name,\n\t\t\t\t\t\t\t &current_thrd);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read current Thread from ChibiOS target\");\n\t\treturn retval;\n\t}\n\trtos->current_thread = current_thrd;\n\n\treturn 0;\n}\n\nstatic int chibios_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tconst struct chibios_params *param;\n\tuint32_t stack_ptr = 0;\n\n\tif ((!rtos) || (thread_id == 0) ||\n\t\t\t(!rtos->rtos_specific_params))\n\t\treturn -1;\n\n\tparam = (const struct chibios_params *) rtos->rtos_specific_params;\n\n\tif (!param->signature)\n\t\treturn -1;\n\n\t/* Update stacking if it can only be determined from runtime information */\n\tif (!param->stacking_info &&\n\t\t(chibios_update_stacking(rtos) != ERROR_OK)) {\n\t\tLOG_ERROR(\"Failed to determine exact stacking for the target type %s\", rtos->target->type->name);\n\t\treturn -1;\n\t}\n\n\t/* Read the stack pointer */\n\tretval = target_read_u32(rtos->target,\n\t\t\t\t\t\t\t thread_id + param->signature->cf_off_ctx, &stack_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack frame from ChibiOS thread\");\n\t\treturn retval;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, reg_list, num_regs);\n}\n\nstatic int chibios_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = malloc(sizeof(chibios_symbol_list));\n\n\tif (!*symbol_list)\n\t\treturn ERROR_FAIL;\n\n\tmemcpy(*symbol_list, chibios_symbol_list, sizeof(chibios_symbol_list));\n\treturn 0;\n}\n\nstatic bool chibios_detect_rtos(struct target *target)\n{\n\tif ((target->rtos->symbols) &&\n\t\t\t((target->rtos->symbols[CHIBIOS_VAL_RLIST].address != 0) ||\n\t\t\t (target->rtos->symbols[CHIBIOS_VAL_CH].address != 0))) {\n\n\t\tif (target->rtos->symbols[CHIBIOS_VAL_CH_DEBUG].address == 0) {\n\t\t\tLOG_INFO(\"It looks like the target may be running ChibiOS \"\n\t\t\t\t\t\"without ch_debug.\");\n\t\t\treturn false;\n\t\t}\n\n\t\t/* looks like ChibiOS with memory map enabled.*/\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic int chibios_create(struct target *target)\n{\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(chibios_params_list); i++)\n\t\tif (strcmp(chibios_params_list[i].target_name, target->type->name) == 0) {\n\t\t\ttarget->rtos->rtos_specific_params = (void *)&chibios_params_list[i];\n\t\t\treturn 0;\n\t\t}\n\n\tLOG_WARNING(\"Could not find target \\\"%s\\\" in ChibiOS compatibility \"\n\t\t\t\t\"list\", target->type->name);\n\treturn -1;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/chromium-ec.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-only\n\n/*\n * Copyright (c) 2018 National Instruments Corp\n * Author: Moritz Fischer <moritz.fischer@ettus.com>\n *\n * Chromium-EC RTOS Task Awareness\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/bits.h>\n#include <rtos/rtos.h>\n#include <target/target.h>\n#include <target/target_type.h>\n\n#include \"rtos_standard_stackings.h\"\n\n#define CROS_EC_MAX_TASKS 32\n#define CROS_EC_MAX_NAME 200\n#define CROS_EC_IDLE_STRING \"<< idle >>\"\n\nstruct chromium_ec_params {\n\tconst char *target_name;\n\tsize_t ptr_size;\n\toff_t task_offset_next;\n\toff_t task_offset_sp;\n\toff_t task_offset_events;\n\toff_t task_offset_runtime;\n\tconst struct rtos_register_stacking *stacking;\n};\n\nstatic const struct chromium_ec_params chromium_ec_params_list[] = {\n\t{\n\t\t.target_name = \"hla_target\",\n\t\t.ptr_size = 4,\n\t\t.task_offset_next = 24,\n\t\t.task_offset_sp = 0,\n\t\t.task_offset_events = 4,\n\t\t.task_offset_runtime = 8,\n\t\t.stacking = &rtos_standard_cortex_m3_stacking,\n\n\t},\n\t{\n\t\t.target_name = \"cortex_m\",\n\t\t.ptr_size = 4,\n\t\t.task_offset_next = 24,\n\t\t.task_offset_sp = 0,\n\t\t.task_offset_events = 4,\n\t\t.task_offset_runtime = 8,\n\t\t.stacking = &rtos_standard_cortex_m3_stacking,\n\t},\n};\n\nstatic const char * const chromium_ec_symbol_list[] = {\n\t\"start_called\",\n\t\"current_task\",\n\t\"tasks\",\n\t\"tasks_enabled\",\n\t\"tasks_ready\",\n\t\"task_names\",\n\t\"build_info\",\n\tNULL,\n};\n\nenum chromium_ec_symbol_values {\n\tCHROMIUM_EC_VAL_START_CALLED = 0,\n\tCHROMIUM_EC_VAL_CURRENT_TASK,\n\tCHROMIUM_EC_VAL_TASKS,\n\tCHROMIUM_EC_VAL_TASKS_ENABLED,\n\tCHROMIUM_EC_VAL_TASKS_READY,\n\tCHROMIUM_EC_VAL_TASK_NAMES,\n\tCHROMIUM_EC_VAL_BUILD_INFO,\n\n\tCHROMIUM_EC_VAL_COUNT,\n};\n\n#define CROS_EC_MAX_BUILDINFO 512\n\nstatic bool chromium_ec_detect_rtos(struct target *target)\n{\n\tchar build_info_buf[CROS_EC_MAX_BUILDINFO];\n\tenum chromium_ec_symbol_values sym;\n\tint ret;\n\n\tif (!target || !target->rtos || !target->rtos->symbols)\n\t\treturn false;\n\n\tfor (sym = CHROMIUM_EC_VAL_START_CALLED;\n\t     sym < CHROMIUM_EC_VAL_COUNT; sym++) {\n\t\tif (target->rtos->symbols[sym].address) {\n\t\t\tLOG_DEBUG(\"Chromium-EC: Symbol \\\"%s\\\" found\",\n\t\t\t\t chromium_ec_symbol_list[sym]);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Chromium-EC: Symbol \\\"%s\\\" missing\",\n\t\t\t\t chromium_ec_symbol_list[sym]);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tret = target_read_buffer(target,\n\t\t\t\t target->rtos->symbols[CHROMIUM_EC_VAL_BUILD_INFO].address,\n\t\t\t\t sizeof(build_info_buf),\n\t\t\t\t (uint8_t *)build_info_buf);\n\n\tif (ret != ERROR_OK)\n\t\treturn false;\n\n\tLOG_INFO(\"Chromium-EC: Buildinfo: %s\", build_info_buf);\n\n\treturn target->rtos->symbols &&\n\t       target->rtos->symbols[CHROMIUM_EC_VAL_START_CALLED].address;\n}\n\nstatic int chromium_ec_create(struct target *target)\n{\n\tstruct chromium_ec_params *params;\n\tsize_t t;\n\n\tfor (t = 0; t < ARRAY_SIZE(chromium_ec_params_list); t++)\n\t\tif (!strcmp(chromium_ec_params_list[t].target_name, target->type->name)) {\n\t\t\tparams = malloc(sizeof(*params));\n\t\t\tif (!params) {\n\t\t\t\tLOG_ERROR(\"Chromium-EC: out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tmemcpy(params, &chromium_ec_params_list[t], sizeof(*params));\n\t\t\ttarget->rtos->rtos_specific_params = (void *)params;\n\t\t\ttarget->rtos->current_thread = 0;\n\t\t\ttarget->rtos->thread_details = NULL;\n\t\t\ttarget->rtos->thread_count = 0;\n\n\t\t\tLOG_INFO(\"Chromium-EC: Using target: %s\", target->type->name);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\tLOG_ERROR(\"Chromium-EC: target not supported: %s\", target->type->name);\n\treturn ERROR_FAIL;\n}\n\nstatic int chromium_ec_get_current_task_ptr(struct rtos *rtos, uint32_t *current_task)\n{\n\tif (!rtos || !rtos->symbols)\n\t\treturn ERROR_FAIL;\n\n\treturn target_read_u32(rtos->target,\n\t\t\t       rtos->symbols[CHROMIUM_EC_VAL_CURRENT_TASK].address,\n\t\t\t       current_task);\n}\n\nstatic int chromium_ec_get_num_tasks(struct rtos *rtos, int *num_tasks)\n{\n\tuint32_t tasks_enabled;\n\tint ret, t, found;\n\n\tret = target_read_u32(rtos->target,\n\t\t\t      rtos->symbols[CHROMIUM_EC_VAL_TASKS_ENABLED].address,\n\t\t\t      &tasks_enabled);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to determine #of tasks\");\n\t\treturn ret;\n\t}\n\n\tfound = 0;\n\tfor (t = 0; t < CROS_EC_MAX_TASKS; t++)\n\t\tif (tasks_enabled & BIT(t))\n\t\t\tfound++;\n\n\t*num_tasks = found;\n\n\treturn ERROR_OK;\n}\n\nstatic int chromium_ec_update_threads(struct rtos *rtos)\n{\n\tuint32_t tasks_enabled, tasks_ready, start_called;\n\tuint32_t current_task, thread_ptr, name_ptr;\n\tchar thread_str_buf[CROS_EC_MAX_NAME];\n\tint ret, t, num_tasks, tasks_found;\n\tstruct chromium_ec_params *params;\n\tuint8_t runtime_buf[8];\n\tuint64_t runtime;\n\tuint32_t events;\n\n\tparams = rtos->rtos_specific_params;\n\tif (!params)\n\t\treturn ERROR_FAIL;\n\n\tif (!rtos->symbols)\n\t\treturn ERROR_FAIL;\n\n\tnum_tasks = 0;\n\tret = chromium_ec_get_num_tasks(rtos, &num_tasks);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to get number of tasks\");\n\t\treturn ret;\n\t}\n\n\tcurrent_task = 0;\n\tret = chromium_ec_get_current_task_ptr(rtos, &current_task);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to get current task\");\n\t\treturn ret;\n\t}\n\tLOG_DEBUG(\"Current task: %lx tasks_found: %d\",\n\t\t  (unsigned long)current_task,\n\t\t  num_tasks);\n\n\t/* set current task to what we read */\n\trtos->current_thread = current_task;\n\n\t/* Nuke the old tasks */\n\trtos_free_threadlist(rtos);\n\n\t/* One check if task switching has started ... */\n\tstart_called = 0;\n\tret = target_read_u32(rtos->target, rtos->symbols[CHROMIUM_EC_VAL_START_CALLED].address,\n\t\t\t      &start_called);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to load start_called\");\n\t\treturn ret;\n\t}\n\n\tif (!rtos->current_thread || !num_tasks || !start_called) {\n\t\tnum_tasks++;\n\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * num_tasks);\n\t\trtos->thread_details->threadid = 1;\n\t\trtos->thread_details->exists = true;\n\t\trtos->thread_details->extra_info_str = NULL;\n\t\trtos->thread_details->thread_name_str = strdup(\"Current Execution\");\n\n\t\tif (!num_tasks || !start_called) {\n\t\t\trtos->thread_count = 1;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* create space for new thread details */\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * num_tasks);\n\t}\n\n\ttasks_enabled = 0;\n\tret = target_read_u32(rtos->target, rtos->symbols[CHROMIUM_EC_VAL_TASKS_ENABLED].address,\n\t\t\t      &tasks_enabled);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to load tasks_enabled\");\n\t\treturn ret;\n\t}\n\n\ttasks_ready = 0;\n\tret = target_read_u32(rtos->target, rtos->symbols[CHROMIUM_EC_VAL_TASKS_READY].address,\n\t\t\t      &tasks_ready);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to load tasks_ready\");\n\t\treturn ret;\n\t}\n\n\tthread_ptr = rtos->symbols[CHROMIUM_EC_VAL_TASKS].address;\n\n\ttasks_found = 0;\n\tfor (t = 0; t < CROS_EC_MAX_TASKS; t++) {\n\t\tif (!(tasks_enabled & BIT(t)))\n\t\t\tcontinue;\n\n\t\tif (thread_ptr == current_task)\n\t\t\trtos->current_thread = thread_ptr;\n\n\t\trtos->thread_details[tasks_found].threadid = thread_ptr;\n\t\tret = target_read_u32(rtos->target,\n\t\t\t\t\t rtos->symbols[CHROMIUM_EC_VAL_TASK_NAMES].address +\n\t\t\t\t\t params->ptr_size * t, &name_ptr);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read name_ptr\");\n\t\t\treturn ret;\n\t\t}\n\n\t\t/* read name buffer */\n\t\tret = target_read_buffer(rtos->target, name_ptr, CROS_EC_MAX_NAME,\n\t\t\t\t\t(uint8_t *)thread_str_buf);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read task name\");\n\t\t\treturn ret;\n\t\t}\n\n\t\t/* sanitize string, gdb chokes on \"<< idle >>\" */\n\t\tif (thread_str_buf[CROS_EC_MAX_NAME - 1] != '\\0')\n\t\t\tthread_str_buf[CROS_EC_MAX_NAME - 1] = '\\0';\n\t\tif (!strncmp(thread_str_buf, CROS_EC_IDLE_STRING, CROS_EC_MAX_NAME))\n\t\t    rtos->thread_details[tasks_found].thread_name_str = strdup(\"IDLE\");\n\t\telse\n\t\t    rtos->thread_details[tasks_found].thread_name_str = strdup(thread_str_buf);\n\n\t\tevents = 0;\n\t\tret = target_read_u32(rtos->target,\n\t\t\t\t      thread_ptr + params->task_offset_events,\n\t\t\t\t      &events);\n\t\tif (ret != ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to get task %d's events\", t);\n\n\t\t/* this is a bit kludgy but will do for now */\n\t\tret = target_read_buffer(rtos->target,\n\t\t\t\t\t thread_ptr + params->task_offset_runtime,\n\t\t\t\t\t sizeof(runtime_buf), runtime_buf);\n\t\tif (ret != ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to get task %d's runtime\", t);\n\t\truntime =  target_buffer_get_u64(rtos->target, runtime_buf);\n\n\t\t/* Priority is simply the position in the array */\n\t\tif (thread_ptr == current_task)\n\t\t\tsnprintf(thread_str_buf, sizeof(thread_str_buf),\n\t\t\t\t \"State: Running, Priority: %u, Events: %\" PRIx32 \", Runtime: %\" PRIu64 \"\\n\",\n\t\t\t\t t, events, runtime);\n\t\telse\n\t\t\tsnprintf(thread_str_buf, sizeof(thread_str_buf),\n\t\t\t\t \"State: %s, Priority: %u, Events: %\" PRIx32 \", Runtime: %\" PRIu64 \"\\n\",\n\t\t\t\t tasks_ready & BIT(t) ? \"Ready\" : \"Waiting\", t,\n\t\t\t\t events, runtime);\n\n\t\trtos->thread_details[tasks_found].extra_info_str = strdup(thread_str_buf);\n\t\trtos->thread_details[tasks_found].exists = true;\n\n\t\tthread_ptr += params->task_offset_next;\n\n\t\ttasks_found++;\n\t}\n\n\trtos->thread_count = tasks_found;\n\n\treturn ERROR_OK;\n}\n\nstatic int chromium_ec_get_thread_reg_list(struct rtos *rtos,\n\t\t\t\t\t   threadid_t threadid,\n\t\t\t\t\t   struct rtos_reg **reg_list,\n\t\t\t\t\t   int *num_regs)\n{\n\tstruct chromium_ec_params *params = rtos->rtos_specific_params;\n\tuint32_t stack_ptr = 0;\n\tint ret, t;\n\n\tfor (t = 0; t < rtos->thread_count; t++)\n\t\tif (threadid == rtos->thread_details[t].threadid)\n\t\t\tbreak;\n\n\t/* if we didn't find threadid, bail */\n\tif (t == rtos->thread_count)\n\t\treturn ERROR_FAIL;\n\n\tret = target_read_u32(rtos->target,\n\t\t\t   rtos->symbols[CHROMIUM_EC_VAL_TASKS].address +\n\t\t\t   params->task_offset_next * t,\n\t\t\t   &stack_ptr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to load TCB\");\n\t\treturn ret;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target, params->stacking,\n\t\t\t\t       stack_ptr, reg_list, num_regs);\n}\n\nstatic int chromium_ec_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tsize_t s;\n\n\t*symbol_list = calloc(ARRAY_SIZE(chromium_ec_symbol_list),\n\t\t\t      sizeof(struct symbol_table_elem));\n\tif (!(*symbol_list)) {\n\t\tLOG_ERROR(\"Chromium-EC: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (s = 0; s < ARRAY_SIZE(chromium_ec_symbol_list); s++)\n\t\t(*symbol_list)[s].symbol_name = chromium_ec_symbol_list[s];\n\n\treturn ERROR_OK;\n}\n\nconst struct rtos_type chromium_ec_rtos = {\n\t.name = \"Chromium-EC\",\n\t.detect_rtos = chromium_ec_detect_rtos,\n\t.create = chromium_ec_create,\n\t.update_threads = chromium_ec_update_threads,\n\t.get_thread_reg_list = chromium_ec_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = chromium_ec_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/eCos.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"target/armv7m.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"helper/bits.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"rtos_ecos_stackings.h\"\n#include \"server/gdb_server.h\"\n\n/* Unfortunately for the moment we are limited to returning the hardwired\n * register count (ARMV7M_NUM_CORE_REGS for Cortex-M) since the openocd RTOS\n * support does not yet support accessing all per-thread \"stacked\"\n * registers. e.g. For Cortex-M under eCos we have a per-thread BASEPRI, and for\n * all eCos targets we may have per-thread VFP/FPU register state.\n *\n * So, for the moment, we continue to use the hardwired limit for the depth of\n * the returned register description vector. The current openocd\n * rtos_standard_stackings.c just provides the main core regs for the Cortex_M*\n * targets regardless of whether FPU is present/enabled.\n *\n * However, this code is written with the expectation that we may eventually be\n * able to provide more register information (\"m-system\" and \"vfp\" for example)\n * and also with the expectation of supporting different register sets being\n * returned depending on the per-thread Cortex-M eCos contex_m for\n * example. Hence the fact that the eCos_stack_layout_*() functions below allow\n * for the stack context descriptor vector to be returned by those calls\n * allowing for eventual support where this code will potentially cache\n * different sets of register descriptors for the different shapes of contexts\n * in a *single* application/binary run-time.\n *\n * TODO: Extend openocd generic RTOS support to allow thread-specific system and\n * FPU register state to be returned. */\n\nstruct ecos_params;\n\nstatic bool ecos_detect_rtos(struct target *target);\nstatic int ecos_create(struct target *target);\nstatic int ecos_update_threads(struct rtos *rtos);\nstatic int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs);\nstatic int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\nstatic int ecos_stack_layout_cortexm(struct rtos *rtos, struct ecos_params *param,\n\t\t\t\tint64_t stack_ptr, const struct rtos_register_stacking **si);\nstatic int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param,\n\t\t\t\tint64_t stack_ptr, const struct rtos_register_stacking **si);\n\n/* The current eCos thread IDentifier uses 0 as an unused (not a valid thread\n * ID) value. Currently the unique_id field is 16-bits, but the eCos SMP support\n * convention is that only 12-bits of the ID will be used. This\n * ECOS_MAX_THREAD_COUNT manifest is provided to limit the potential for\n * interpreting stale/inconsistent thread list state when the debug host scans\n * the thread list before the target RTOS has completed its initialisation. This\n * support will need to revisited when eCos is re-engineered to support more\n * than 16 CPU SMP setups. */\n#define ECOS_MAX_THREAD_COUNT (4095)\n\nstruct ecos_thread_state {\n\tint value;\n\tconst char *desc;\n};\n\n/* The status is actually a logical-OR bitmask of states: */\nenum ecos_thread_state_flags {\n\tRUNNING    = 0, /* explicit no-bits-set value */\n\tSLEEPING   = BIT(0),\n\tCOUNTSLEEP = BIT(1),\n\tSUSPENDED  = BIT(2),\n\tCREATING   = BIT(3),\n\tEXITED     = BIT(4),\n\tSLEEPSET   = (SLEEPING | COUNTSLEEP)\n};\n\n/* Cyg_Thread:: reason codes for wake and sleep fields: */\nstatic const struct ecos_thread_state ecos_thread_reasons[] = {\n\t{ 0, \"NONE\" }, /* normally indicates \"not yet started\" */\n\t{ 1, \"WAIT\" }, /* wait with no timeout */\n\t{ 2, \"DELAY\" }, /* simple time delay */\n\t{ 3, \"TIMEOUT\" }, /* wait with timeout *or* timeout expired */\n\t{ 4, \"BREAK\" }, /* forced break out of sleep */\n\t{ 5, \"DESTRUCT\" }, /* wait on object being destroyed */\n\t{ 6, \"EXIT\" }, /* forced termination */\n\t{ 7, \"DONE\" } /* wait/delay completed */\n};\n\nstatic const char * const target_cortex_m[] = {\n\t\"cortex_m\",\n\t\"hla_target\",\n\tNULL\n};\n\nstatic const char * const target_arm[] = {\n\t\"cortex_a\",\n\t\"arm7tdmi\",\n\t\"arm720t\",\n\t\"arm9tdmi\",\n\t\"arm920t\",\n\t\"arm926ejs\",\n\t\"arm946e\",\n\t\"arm966e\",\n\t\"arm11\",\n\tNULL\n};\n\n/* Since individual eCos application configurations may have different thread\n * object structure layouts depending on the actual build-time enabled features\n * we provide support for applications built containing the relevant symbolic\n * support to match the actual application binary being debugged, rather than\n * relying on a set of default/fixed (and potentially incorrect)\n * offsets. However, for backwards compatibility, we do *NOT* enforce the\n * requirement for the common extra helper symbols to be present to allow the\n * fallback to the simple fixed CM3 model to avoid affecting existing users of\n * older eCos worlds. Similarly we need to provide support for per-thread\n * register context offsets, as well as for per-application-configurations,\n * since some targets can have different stacked state on a per-thread basis\n * (e.g. \"cortex_m\"). This is why the stacking_info is now set at run-time\n * rather than being fixed. */\n\nstruct ecos_params {\n\tconst char * const *target_names; /* NULL terminated list of targets */\n\tint (*target_stack_layout)(struct rtos *rtos, struct ecos_params *param,\n\t\tint64_t stack_ptr, const struct rtos_register_stacking **si);\n\tbool flush_common;\n\tunsigned char pointer_width;\n\tunsigned char uid_width;\n\tunsigned char state_width;\n\tunsigned int thread_stack_offset;\n\tunsigned int thread_name_offset;\n\tunsigned int thread_state_offset;\n\tunsigned int thread_next_offset;\n\tunsigned int thread_uniqueid_offset;\n\tconst struct rtos_register_stacking *stacking_info;\n};\n\n/* As mentioned above we provide default offset values for the \"cortex_m\"\n * targets for backwards compatibility with older eCos application builds and\n * previous users of this RTOS specific support that do not have the\n * configuration specific offsets provided in the symbol table. The support for\n * other targets (e.g. \"cortex_a\") we do expect the application to provide the\n * required symbolic information. We do not populate the stacking_info reference\n * until we have had a chance to interrogate the symbol table. */\n\nstatic struct ecos_params ecos_params_list[] = {\n\t{\n\t.target_names = target_cortex_m,\n\t.pointer_width = 4,\n\t.uid_width = 2,\n\t.state_width = 4,\n\t.thread_stack_offset = 0x0c,\n\t.thread_name_offset = 0x9c,\n\t.thread_state_offset = 0x3c,\n\t.thread_next_offset = 0xa0,\n\t.thread_uniqueid_offset = 0x4c,\n\t.target_stack_layout = ecos_stack_layout_cortexm,\n\t.stacking_info = NULL\n\t},\n\t{\n\t.target_names = target_arm,\n\t.pointer_width = 0,\n\t.uid_width = 0,\n\t.state_width = 0,\n\t.thread_stack_offset = 0,\n\t.thread_name_offset = 0,\n\t.thread_state_offset = 0,\n\t.thread_next_offset = 0,\n\t.thread_uniqueid_offset = 0,\n\t.target_stack_layout = ecos_stack_layout_arm,\n\t.stacking_info = NULL\n\t}\n};\n\n#define ECOS_NUM_PARAMS ARRAY_SIZE(ecos_params_list)\n\n/* To eventually allow for more than just the ARMV7M_NUM_CORE_REGS to be\n * returned by the Cortex-M support, and to avoid run-time lookups we manually\n * maintain our own mapping for the supplied stack register vector entries. This\n * enum needs to match the rtos_ecos_regoff_cortexm[] vector. Admittedly the\n * initial indices just match the corresponding ARMV7M_R* definitions, but after\n * the base registers the ARMV7M_* number space does not match the vector we\n * wish to populate in this eCos support code. */\nenum ecos_reglist_cortexm {\n\tECOS_REGLIST_R0 = 0,\n\tECOS_REGLIST_R1,\n\tECOS_REGLIST_R2,\n\tECOS_REGLIST_R3,\n\tECOS_REGLIST_R4,\n\tECOS_REGLIST_R5,\n\tECOS_REGLIST_R6,\n\tECOS_REGLIST_R7,\n\tECOS_REGLIST_R8,\n\tECOS_REGLIST_R9,\n\tECOS_REGLIST_R10,\n\tECOS_REGLIST_R11,\n\tECOS_REGLIST_R12,\n\tECOS_REGLIST_R13,\n\tECOS_REGLIST_R14,\n\tECOS_REGLIST_PC,\n\tECOS_REGLIST_XPSR,\t/* ARMV7M_NUM_CORE_REGS */\n\tECOS_REGLIST_BASEPRI,\n\tECOS_REGLIST_FPSCR,\t/* Following for FPU contexts */\n\tECOS_REGLIST_D0,\n\tECOS_REGLIST_D1,\n\tECOS_REGLIST_D2,\n\tECOS_REGLIST_D3,\n\tECOS_REGLIST_D4,\n\tECOS_REGLIST_D5,\n\tECOS_REGLIST_D6,\n\tECOS_REGLIST_D7,\n\tECOS_REGLIST_D8,\n\tECOS_REGLIST_D9,\n\tECOS_REGLIST_D10,\n\tECOS_REGLIST_D11,\n\tECOS_REGLIST_D12,\n\tECOS_REGLIST_D13,\n\tECOS_REGLIST_D14,\n\tECOS_REGLIST_D15\n};\n\n#define ECOS_CORTEXM_BASE_NUMREGS (ARMV7M_NUM_CORE_REGS)\n\n/* NOTE: The offsets in this vector are overwritten by the architecture specific\n * layout functions depending on the specific application configuration. The\n * ordering of this vector MUST match eCos_reglist. */\nstatic struct stack_register_offset rtos_ecos_regoff_cortexm[] = {\n\t{ ARMV7M_R0,      -1, 32 },\t/* r0            */\n\t{ ARMV7M_R1,      -1, 32 },\t/* r1            */\n\t{ ARMV7M_R2,      -1, 32 },\t/* r2            */\n\t{ ARMV7M_R3,      -1, 32 },\t/* r3            */\n\t{ ARMV7M_R4,      -1, 32 },\t/* r4            */\n\t{ ARMV7M_R5,      -1, 32 },\t/* r5            */\n\t{ ARMV7M_R6,      -1, 32 },\t/* r6            */\n\t{ ARMV7M_R7,      -1, 32 },\t/* r7            */\n\t{ ARMV7M_R8,      -1, 32 },\t/* r8            */\n\t{ ARMV7M_R9,      -1, 32 },\t/* r9            */\n\t{ ARMV7M_R10,     -1, 32 },\t/* r10           */\n\t{ ARMV7M_R11,     -1, 32 },\t/* r11           */\n\t{ ARMV7M_R12,     -1, 32 },\t/* r12           */\n\t{ ARMV7M_R13,     -1, 32 },\t/* sp            */\n\t{ ARMV7M_R14,     -1, 32 },\t/* lr            */\n\t{ ARMV7M_PC,      -1, 32 },\t/* pc            */\n\t{ ARMV7M_XPSR,    -1, 32 },\t/* xPSR          */\n\t{ ARMV7M_BASEPRI, -1, 32 },     /* BASEPRI       */\n\t{ ARMV7M_FPSCR,   -1, 32 },     /* FPSCR         */\n\t{ ARMV7M_D0,      -1, 64 },     /* D0  (S0/S1)   */\n\t{ ARMV7M_D1,      -1, 64 },     /* D1  (S2/S3)   */\n\t{ ARMV7M_D2,      -1, 64 },     /* D2  (S4/S5)   */\n\t{ ARMV7M_D3,      -1, 64 },     /* D3  (S6/S7)   */\n\t{ ARMV7M_D4,      -1, 64 },     /* D4  (S8/S9)   */\n\t{ ARMV7M_D5,      -1, 64 },     /* D5  (S10/S11) */\n\t{ ARMV7M_D6,      -1, 64 },     /* D6  (S12/S13) */\n\t{ ARMV7M_D7,      -1, 64 },     /* D7  (S14/S15) */\n\t{ ARMV7M_D8,      -1, 64 },     /* D8  (S16/S17) */\n\t{ ARMV7M_D9,      -1, 64 },     /* D9  (S18/S19) */\n\t{ ARMV7M_D10,     -1, 64 },     /* D10 (S20/S21) */\n\t{ ARMV7M_D11,     -1, 64 },     /* D11 (S22/S23) */\n\t{ ARMV7M_D12,     -1, 64 },     /* D12 (S24/S25) */\n\t{ ARMV7M_D13,     -1, 64 },     /* D13 (S26/S27) */\n\t{ ARMV7M_D14,     -1, 64 },     /* D14 (S28/S29) */\n\t{ ARMV7M_D15,     -1, 64 },     /* D15 (S30/S31) */\n};\n\nstatic struct stack_register_offset rtos_ecos_regoff_arm[] = {\n\t{ 0,  -1, 32 },\t\t/* r0       */\n\t{ 1,  -1, 32 },\t\t/* r1       */\n\t{ 2,  -1, 32 },\t\t/* r2       */\n\t{ 3,  -1, 32 },\t\t/* r3       */\n\t{ 4,  -1, 32 },\t\t/* r4       */\n\t{ 5,  -1, 32 },\t\t/* r5       */\n\t{ 6,  -1, 32 },\t\t/* r6       */\n\t{ 7,  -1, 32 },\t\t/* r7       */\n\t{ 8,  -1, 32 },\t\t/* r8       */\n\t{ 9,  -1, 32 },\t\t/* r9       */\n\t{ 10, -1, 32 },\t\t/* r10      */\n\t{ 11, -1, 32 },\t\t/* r11 (fp) */\n\t{ 12, -1, 32 },\t\t/* r12 (ip) */\n\t{ 13, -1, 32 },\t\t/* sp (r13) */\n\t{ 14, -1, 32 },\t\t/* lr (r14) */\n\t{ 15, -1, 32 },\t\t/* pc (r15) */\n\t{ 16, -1, 32 },\t\t/* xPSR     */\n};\n\nstatic struct rtos_register_stacking rtos_ecos_stacking = {\n\t.stack_registers_size = 0,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 0,\n\t.calculate_process_stack = NULL,\t/* stack_alignment */\n\t.register_offsets = NULL\n};\n\n/* To avoid the run-time cost of matching explicit symbol names we push the\n * lookup offsets to this *manually* maintained enumeration which must match the\n * ecos_symbol_list[] order below. */\nenum ecos_symbol_values {\n\tECOS_VAL_THREAD_LIST = 0,\n\tECOS_VAL_CURRENT_THREAD_PTR,\n\tECOS_VAL_COMMON_THREAD_NEXT_OFF,\n\tECOS_VAL_COMMON_THREAD_NEXT_SIZE,\n\tECOS_VAL_COMMON_THREAD_STATE_OFF,\n\tECOS_VAL_COMMON_THREAD_STATE_SIZE,\n\tECOS_VAL_COMMON_THREAD_SLEEP_OFF,\n\tECOS_VAL_COMMON_THREAD_SLEEP_SIZE,\n\tECOS_VAL_COMMON_THREAD_WAKE_OFF,\n\tECOS_VAL_COMMON_THREAD_WAKE_SIZE,\n\tECOS_VAL_COMMON_THREAD_ID_OFF,\n\tECOS_VAL_COMMON_THREAD_ID_SIZE,\n\tECOS_VAL_COMMON_THREAD_NAME_OFF,\n\tECOS_VAL_COMMON_THREAD_NAME_SIZE,\n\tECOS_VAL_COMMON_THREAD_PRI_OFF,\n\tECOS_VAL_COMMON_THREAD_PRI_SIZE,\n\tECOS_VAL_COMMON_THREAD_STACK_OFF,\n\tECOS_VAL_COMMON_THREAD_STACK_SIZE,\n\tECOS_VAL_CORTEXM_THREAD_SAVED,\n\tECOS_VAL_CORTEXM_CTX_THREAD_SIZE,\n\tECOS_VAL_CORTEXM_CTX_TYPE_OFF,\n\tECOS_VAL_CORTEXM_CTX_TYPE_SIZE,\n\tECOS_VAL_CORTEXM_CTX_BASEPRI_OFF,\n\tECOS_VAL_CORTEXM_CTX_BASEPRI_SIZE,\n\tECOS_VAL_CORTEXM_CTX_SP_OFF,\n\tECOS_VAL_CORTEXM_CTX_SP_SIZE,\n\tECOS_VAL_CORTEXM_CTX_REG_OFF,\n\tECOS_VAL_CORTEXM_CTX_REG_SIZE,\n\tECOS_VAL_CORTEXM_CTX_PC_OFF,\n\tECOS_VAL_CORTEXM_CTX_PC_SIZE,\n\tECOS_VAL_CORTEXM_VAL_EXCEPTION,\n\tECOS_VAL_CORTEXM_VAL_THREAD,\n\tECOS_VAL_CORTEXM_VAL_INTERRUPT,\n\tECOS_VAL_CORTEXM_VAL_FPU,\n\tECOS_VAL_CORTEXM_CTX_FPSCR_OFF,\n\tECOS_VAL_CORTEXM_CTX_FPSCR_SIZE,\n\tECOS_VAL_CORTEXM_CTX_S_OFF,\n\tECOS_VAL_CORTEXM_CTX_S_SIZE,\n\tECOS_VAL_ARM_REGSIZE,\n\tECOS_VAL_ARM_CTX_R0_OFF,\n\tECOS_VAL_ARM_CTX_R1_OFF,\n\tECOS_VAL_ARM_CTX_R2_OFF,\n\tECOS_VAL_ARM_CTX_R3_OFF,\n\tECOS_VAL_ARM_CTX_R4_OFF,\n\tECOS_VAL_ARM_CTX_R5_OFF,\n\tECOS_VAL_ARM_CTX_R6_OFF,\n\tECOS_VAL_ARM_CTX_R7_OFF,\n\tECOS_VAL_ARM_CTX_R8_OFF,\n\tECOS_VAL_ARM_CTX_R9_OFF,\n\tECOS_VAL_ARM_CTX_R10_OFF,\n\tECOS_VAL_ARM_CTX_FP_OFF,\n\tECOS_VAL_ARM_CTX_IP_OFF,\n\tECOS_VAL_ARM_CTX_SP_OFF,\n\tECOS_VAL_ARM_CTX_LR_OFF,\n\tECOS_VAL_ARM_CTX_PC_OFF,\n\tECOS_VAL_ARM_CTX_CPSR_OFF,\n\tECOS_VAL_ARM_FPUSIZE,\n\tECOS_VAL_ARM_CTX_FPSCR_OFF,\n\tECOS_VAL_ARM_SCOUNT,\n\tECOS_VAL_ARM_CTX_SVEC_OFF,\n\tECOS_VAL_ARM_VFPCOUNT,\n\tECOS_VAL_ARM_CTX_VFPVEC_OFF\n};\n\nstruct symbols {\n\tconst char *name;\n\tconst char * const *target_names; /* non-NULL when for a specific architecture */\n\tbool optional;\n};\n\n#define ECOSSYM(_n, _o, _t) { .name = _n, .optional = (_o), .target_names = _t }\n\n/* Some of offset/size helper symbols are common to all eCos\n * targets. Unfortunately, for historical reasons, some information is in\n * architecture specific namespaces leading to some duplication and a larger\n * vector below. */\nstatic const struct symbols ecos_symbol_list[] = {\n\tECOSSYM(\"Cyg_Thread::thread_list\", false, NULL),\n\tECOSSYM(\"Cyg_Scheduler_Base::current_thread\", false, NULL),\n\t/* Following symbols *are* required for generic application-specific\n\t * configuration support, but we mark as optional for backwards\n\t * compatibility with the previous fixed Cortex-M3 only RTOS plugin\n\t * implementation. */\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.list_next\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.list_next\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.state\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.state\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.sleep_reason\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.sleep_reason\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.wake_reason\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.wake_reason\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.unique_id\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.unique_id\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.name\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.name\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.priority\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.priority\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.off.cyg_thread.stack_ptr\", true, NULL),\n\tECOSSYM(\"__ecospro_syminfo.size.cyg_thread.stack_ptr\", true, NULL),\n\t/* optional Cortex-M: */\n\tECOSSYM(\"__ecospro_syminfo.cortexm.thread.saved\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.Thread\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.type\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.type\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.basepri\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.basepri\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.sp\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.sp\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.r\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.r\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.pc\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.pc\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.value.HAL_SAVEDREGISTERS.EXCEPTION\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.value.HAL_SAVEDREGISTERS.THREAD\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.value.HAL_SAVEDREGISTERS.INTERRUPT\", true, target_cortex_m),\n\t/* optional Cortex-M with H/W FPU configured: */\n\tECOSSYM(\"__ecospro_syminfo.value.HAL_SAVEDREGISTERS.WITH_FPU\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.fpscr\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.fpscr\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.off.HAL_SavedRegisters.u.thread.s\", true, target_cortex_m),\n\tECOSSYM(\"__ecospro_syminfo.size.HAL_SavedRegisters.u.thread.s\", true, target_cortex_m),\n\t/* optional ARM: */\n\tECOSSYM(\"ARMREG_SIZE\", true, target_arm),\n\tECOSSYM(\"armreg_r0\", true, target_arm),\n\tECOSSYM(\"armreg_r1\", true, target_arm),\n\tECOSSYM(\"armreg_r2\", true, target_arm),\n\tECOSSYM(\"armreg_r3\", true, target_arm),\n\tECOSSYM(\"armreg_r4\", true, target_arm),\n\tECOSSYM(\"armreg_r5\", true, target_arm),\n\tECOSSYM(\"armreg_r6\", true, target_arm),\n\tECOSSYM(\"armreg_r7\", true, target_arm),\n\tECOSSYM(\"armreg_r8\", true, target_arm),\n\tECOSSYM(\"armreg_r9\", true, target_arm),\n\tECOSSYM(\"armreg_r10\", true, target_arm),\n\tECOSSYM(\"armreg_fp\", true, target_arm),\n\tECOSSYM(\"armreg_ip\", true, target_arm),\n\tECOSSYM(\"armreg_sp\", true, target_arm),\n\tECOSSYM(\"armreg_lr\", true, target_arm),\n\tECOSSYM(\"armreg_pc\", true, target_arm),\n\tECOSSYM(\"armreg_cpsr\", true, target_arm),\n\t/* optional ARM FPU common: */\n\tECOSSYM(\"ARMREG_FPUCONTEXT_SIZE\", true, target_arm),\n\tECOSSYM(\"armreg_fpscr\", true, target_arm),\n\t/* optional ARM FPU single-precision: */\n\tECOSSYM(\"ARMREG_S_COUNT\", true, target_arm),\n\tECOSSYM(\"armreg_s_vec\", true, target_arm),\n\t/* optional ARM FPU double-precision: */\n\tECOSSYM(\"ARMREG_VFP_COUNT\", true, target_arm),\n\tECOSSYM(\"armreg_vfp_vec\", true, target_arm),\n};\n\nconst struct rtos_type ecos_rtos = {\n\t.name = \"eCos\",\n\n\t.detect_rtos = ecos_detect_rtos,\n\t.create = ecos_create,\n\t.update_threads = ecos_update_threads,\n\t.get_thread_reg_list = ecos_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = ecos_get_symbol_list_to_lookup,\n\n};\n\nstatic symbol_address_t ecos_value(struct rtos *rtos, unsigned int idx)\n{\n\tif (idx < ARRAY_SIZE(ecos_symbol_list))\n\t\treturn rtos->symbols[idx].address;\n\n\t/* We do not terminate, just return 0 in this case. */\n\tLOG_ERROR(\"eCos: Invalid symbol index %u\", idx);\n\treturn 0;\n}\n\n#define XMLENTRY(_c, _s) { .xc = (_c), .rs = (_s), .rlen = (sizeof(_s) - 1) }\n\nstatic const struct {\n\tchar xc;\n\tconst char *rs;\n\tsize_t rlen;\n} xmlchars[] = {\n\tXMLENTRY('<', \"&lt;\"),\n\tXMLENTRY('&', \"&amp;\"),\n\tXMLENTRY('>', \"&gt;\"),\n\tXMLENTRY('\\'', \"&apos;\"),\n\tXMLENTRY('\"', \"&quot;\")\n};\n\n/** Escape any XML reserved characters in a string. */\nstatic bool ecos_escape_string(const char *raw, char *out, size_t limit)\n{\n\tstatic const char *tokens = \"<&>\\'\\\"\";\n\tbool escaped = false;\n\n\tif (!out || !limit)\n\t\treturn false;\n\n\t(void)memset(out, '\\0', limit);\n\n\twhile (raw && *raw && limit) {\n\t\tsize_t lok = strcspn(raw, tokens);\n\t\tif (lok) {\n\t\t\tsize_t tocopy;\n\t\t\ttocopy = ((limit < lok) ? limit : lok);\n\t\t\t(void)memcpy(out, raw, tocopy);\n\t\t\tlimit -= tocopy;\n\t\t\tout += tocopy;\n\t\t\traw += lok;\n\t\t\tcontinue;\n\t\t}\n\n\t\tchar *fidx = strchr(tokens, *raw);\n\t\tif (!fidx) {\n\t\t\t/* Should never happen assuming xmlchars\n\t\t\t * vector and tokens string match. */\n\t\t\tLOG_ERROR(\"eCos: Unexpected XML char %c\", *raw);\n\t\t\tcontinue;\n\t\t}\n\n\t\tuint32_t cidx = (fidx - tokens);\n\t\tsize_t tocopy = xmlchars[cidx].rlen;\n\t\tif (limit < tocopy)\n\t\t\tbreak;\n\n\t\tescaped = true;\n\t\t(void)memcpy(out, xmlchars[cidx].rs, tocopy);\n\t\tlimit -= tocopy;\n\t\tout += tocopy;\n\t\traw++;\n\t}\n\n\treturn escaped;\n}\n\nstatic int ecos_check_app_info(struct rtos *rtos, struct ecos_params *param)\n{\n\tif (!rtos || !param)\n\t\treturn -1;\n\n\tif (param->flush_common) {\n\t\tif (debug_level >= LOG_LVL_DEBUG) {\n\t\t\tfor (unsigned int idx = 0; idx < ARRAY_SIZE(ecos_symbol_list); idx++) {\n\t\t\t\tLOG_DEBUG(\"eCos: %s 0x%016\" PRIX64 \" %s\",\n\t\t\t\t\trtos->symbols[idx].optional ? \"OPTIONAL\" : \"        \",\n\t\t\t\t\trtos->symbols[idx].address, rtos->symbols[idx].symbol_name);\n\t\t\t}\n\t\t}\n\n\t\t/* If \"__ecospro_syminfo.size.cyg_thread.list_next\" is non-zero then we\n\t\t * expect all of the generic thread structure symbols to have been\n\t\t * provided. */\n\t\tsymbol_address_t thread_next_size = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_SIZE);\n\t\tif (thread_next_size != 0) {\n\t\t\tparam->pointer_width = thread_next_size;\n\t\t\tparam->uid_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_SIZE);\n\t\t\tparam->state_width = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_SIZE);\n\t\t\tparam->thread_stack_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STACK_OFF);\n\t\t\tparam->thread_name_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NAME_OFF);\n\t\t\tparam->thread_state_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_STATE_OFF);\n\t\t\tparam->thread_next_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_NEXT_OFF);\n\t\t\tparam->thread_uniqueid_offset = ecos_value(rtos, ECOS_VAL_COMMON_THREAD_ID_OFF);\n\t\t}\n\n\t\tif (param->uid_width != sizeof(uint16_t)) {\n\t\t\t/* Currently all eCos configurations use a 16-bit field to hold the\n\t\t\t * unique thread ID. */\n\t\t\tLOG_WARNING(\"eCos: Unexpected unique_id width %\" PRIu8, param->uid_width);\n\t\t\tparam->uid_width = (unsigned char)sizeof(uint16_t);\n\t\t}\n\n\t\tparam->stacking_info = NULL;\n\t\tparam->flush_common = false;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* The Cortex-M eCosPro \"thread\" contexts have a \"type\" indicator, which tracks\n * the context state of (THREAD | EXCEPTION | INTERRUPT) and whether FPU\n * registers are saved.\n *\n * For thread-aware debugging from GDB we are only interested in THREAD states\n * and so do not need to implement support for INTERRUPT or EXCEPTION thread\n * contexts since this code does not expose those stack contexts via the\n * constructed thread list support. */\nstatic int ecos_stack_layout_cortexm(struct rtos *rtos,\n\t\tstruct ecos_params *param, int64_t stack_ptr,\n\t\tconst struct rtos_register_stacking **si)\n{\n\tint retval = ERROR_OK;\n\n\t/* CONSIDER: We could return\n\t * ecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) as the actual PC\n\t * address of a context switch, with the LR being set to the context PC\n\t * field to give a true representation of where the thread switch\n\t * occurs. However that would require extending the common\n\t * rtos_generic_stack_read() code with suitable support for applying a\n\t * supplied value, or just implementing our own version of that code that\n\t * can inject data into what is passed onwards to GDB. */\n\n\t/* UPDATE: When we can return VFP register state then we will NOT be\n\t * basing the cached state on the single param->stacking_info value,\n\t * since we will need a different stacking_info structure returned for\n\t * each thread type when FPU support is enabled. The use of the single\n\t * param->stacking_info is a holder whilst we are limited to the fixed\n\t * ARMV7M_NUM_CORE_REGS set of descriptors. */\n\n\tif (!param->stacking_info &&\n\t\tecos_value(rtos, ECOS_VAL_CORTEXM_THREAD_SAVED) &&\n\t\tecos_value(rtos, ECOS_VAL_CORTEXM_VAL_THREAD)) {\n\t\tunsigned char numoutreg = ECOS_CORTEXM_BASE_NUMREGS;\n\n\t\trtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_THREAD_SIZE);\n\t\trtos_ecos_stacking.calculate_process_stack = rtos_generic_stack_align8;\n\t\trtos_ecos_stacking.register_offsets = rtos_ecos_regoff_cortexm;\n\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R0].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x00);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R1].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x04);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R2].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x08);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R3].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x0C);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R4].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x10);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R5].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x14);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R6].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x18);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R7].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x1C);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R8].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x20);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R9].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x24);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R10].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x28);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R11].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x2C);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R12].offset = (ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_REG_OFF) + 0x30);\n\t\t/* Rather than using the stacked ECOS_VAL_CORTEXM_CTX_SP_OFF\n\t\t * value we force the reported sp to be after the stacked\n\t\t * register context. */\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R13].offset = -2;\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_R14].offset = -1;\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_PC].offset = ecos_value(rtos, ECOS_VAL_CORTEXM_CTX_PC_OFF);\n\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_XPSR].offset = -1;\n\n\t\tparam->stacking_info = &rtos_ecos_stacking;\n\n\t\t/* Common Cortex-M thread register offsets for the current\n\t\t * symbol table: */\n\t\tif (retval == ERROR_OK && param->stacking_info) {\n\t\t\tif (numoutreg > ECOS_REGLIST_BASEPRI) {\n\t\t\t\trtos_ecos_regoff_cortexm[ECOS_REGLIST_BASEPRI].offset =\n\t\t\t\t\tecos_value(rtos, ECOS_VAL_CORTEXM_CTX_BASEPRI_OFF);\n\t\t\t}\n\n\t\t\trtos_ecos_stacking.num_output_registers = numoutreg;\n\t\t}\n\t}\n\n\tif (si)\n\t\t*si = param->stacking_info;\n\n\treturn retval;\n}\n\nstatic int ecos_stack_layout_arm(struct rtos *rtos, struct ecos_params *param,\n\t\tint64_t stack_ptr, const struct rtos_register_stacking **si)\n{\n\tint retval = ERROR_OK;\n\n\tif (!param->stacking_info && ecos_value(rtos, ECOS_VAL_ARM_REGSIZE)) {\n\t\t/* When OpenOCD is extended to allow FPU registers to be returned from a\n\t\t * stacked thread context we can check:\n\t\t *\t\tif (0 != ecos_value(rtos, ECOS_VAL_ARM_FPUSIZE)) { FPU }\n\t\t * for presence of FPU registers in the context. */\n\n\t\trtos_ecos_stacking.stack_registers_size = ecos_value(rtos, ECOS_VAL_ARM_REGSIZE);\n\t\trtos_ecos_stacking.num_output_registers = ARRAY_SIZE(rtos_ecos_regoff_arm);\n\t\trtos_ecos_stacking.register_offsets = rtos_ecos_regoff_arm;\n\n\t\trtos_ecos_regoff_arm[0].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R0_OFF);\n\t\trtos_ecos_regoff_arm[1].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R1_OFF);\n\t\trtos_ecos_regoff_arm[2].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R2_OFF);\n\t\trtos_ecos_regoff_arm[3].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R3_OFF);\n\t\trtos_ecos_regoff_arm[4].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R4_OFF);\n\t\trtos_ecos_regoff_arm[5].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R5_OFF);\n\t\trtos_ecos_regoff_arm[6].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R6_OFF);\n\t\trtos_ecos_regoff_arm[7].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R7_OFF);\n\t\trtos_ecos_regoff_arm[8].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R8_OFF);\n\t\trtos_ecos_regoff_arm[9].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R9_OFF);\n\t\trtos_ecos_regoff_arm[10].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_R10_OFF);\n\t\trtos_ecos_regoff_arm[11].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_FP_OFF);\n\t\trtos_ecos_regoff_arm[12].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_IP_OFF);\n\t\trtos_ecos_regoff_arm[13].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_SP_OFF);\n\t\trtos_ecos_regoff_arm[14].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_LR_OFF);\n\t\trtos_ecos_regoff_arm[15].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_PC_OFF);\n\t\trtos_ecos_regoff_arm[16].offset = ecos_value(rtos, ECOS_VAL_ARM_CTX_CPSR_OFF);\n\n\t\tparam->stacking_info = &rtos_ecos_stacking;\n\t}\n\n\tif (si)\n\t\t*si = param->stacking_info;\n\n\treturn retval;\n}\n\n/* We see this function called on a new connection, it looks like before and\n * after the \"tar rem\"/\"tar extended-remote\". It might be the only point we can\n * decide to cache information (to check if the symbol table has changed). */\nstatic int ecos_update_threads(struct rtos *rtos)\n{\n\tint retval;\n\tint tasks_found = 0;\n\tint thread_list_size = 0;\n\tstruct ecos_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\t/* NOTE: We only see this when connecting from GDB the first\n\t\t * time before the application image is loaded. So it is not a\n\t\t * hook for detecting an application change. */\n\t\tparam->flush_common = true;\n\t\tLOG_ERROR(\"No symbols for eCos\");\n\t\treturn -4;\n\t}\n\n\tretval = ecos_check_app_info(rtos, param);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (rtos->symbols[ECOS_VAL_THREAD_LIST].address == 0) {\n\t\tLOG_ERROR(\"Don't have the thread list head\");\n\t\treturn -2;\n\t}\n\n\t/* determine the number of current threads */\n\tuint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address;\n\tuint32_t thread_index;\n\ttarget_read_buffer(rtos->target,\n\t\tthread_list_head,\n\t\tparam->pointer_width,\n\t\t(uint8_t *) &thread_index);\n\tuint32_t first_thread = thread_index;\n\n\t/* Even if 0==first_thread indicates a system with no defined eCos\n\t * threads, instead of early exiting here we fall through the code to\n\t * allow the creation of a faked \"Current Execution\" descriptor as\n\t * needed. */\n\n\tif (first_thread) {\n\t\t/* Since the OpenOCD RTOS support can attempt to obtain thread\n\t\t * information on initial connection when the system *may* have\n\t\t * undefined memory state it is possible for a simple thread count scan\n\t\t * to produce invalid results. To avoid blocking indefinitely when\n\t\t * encountering an invalid closed loop we limit the number of threads to\n\t\t * the maximum possible, and if we pass that limit then something is\n\t\t * wrong so treat the system as having no threads defined. */\n\t\tdo {\n\t\t\tthread_list_size++;\n\t\t\tif (thread_list_size > ECOS_MAX_THREAD_COUNT) {\n\t\t\t\t/* Treat as \"no threads\" case: */\n\t\t\t\tfirst_thread = 0;\n\t\t\t\tthread_list_size = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t\tthread_index + param->thread_next_offset,\n\t\t\t\t\tparam->pointer_width,\n\t\t\t\t\t(uint8_t *)&thread_index);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} while (thread_index != first_thread);\n\t}\n\n\t/* read the current thread id */\n\trtos->current_thread = 0;\n\n\tuint32_t current_thread_addr;\n\tretval = target_read_buffer(rtos->target,\n\t\t\trtos->symbols[ECOS_VAL_CURRENT_THREAD_PTR].address,\n\t\t\tparam->pointer_width,\n\t\t\t(uint8_t *)&current_thread_addr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Reading active thread address\");\n\t\treturn retval;\n\t}\n\n\tif (current_thread_addr) {\n\t\tuint16_t id = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tcurrent_thread_addr + param->thread_uniqueid_offset,\n\t\t\t\tparam->uid_width,\n\t\t\t\t(uint8_t *)&id);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read eCos current thread from target\");\n\t\t\treturn retval;\n\t\t}\n\t\trtos->current_thread = (threadid_t)id;\n\t}\n\n\tif (thread_list_size == 0 || rtos->current_thread == 0) {\n\t\t/* Either : No RTOS threads - there is always at least the current execution though */\n\t\t/* OR     : No current thread - all threads suspended - show the current execution\n\t\t * of idling */\n\t\tstatic const char tmp_str[] = \"Current Execution\";\n\t\tthread_list_size++;\n\t\ttasks_found++;\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t\t/* 1 is a valid eCos thread id, so we return 0 for this faked\n\t\t * \"current\" CPU state: */\n\t\trtos->thread_details->threadid = 0;\n\t\trtos->thread_details->exists = true;\n\t\trtos->thread_details->extra_info_str = NULL;\n\t\trtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));\n\t\tstrcpy(rtos->thread_details->thread_name_str, tmp_str);\n\n\t\t/* Early exit if current CPU state our only \"thread\": */\n\t\tif (thread_list_size == 1) {\n\t\t\trtos->thread_count = 1;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* create space for new thread details */\n\t\trtos->thread_details = malloc(\n\t\t\t\tsizeof(struct thread_detail) * thread_list_size);\n\t}\n\n\t/* loop over all threads */\n\tthread_index = first_thread;\n\tdo {\n\t\t#define ECOS_THREAD_NAME_STR_SIZE (200)\n\t\tchar tmp_str[ECOS_THREAD_NAME_STR_SIZE];\n\t\tuint32_t name_ptr = 0;\n\t\tuint32_t prev_thread_ptr;\n\n\t\t/* Save the thread ID. For eCos the thread has a unique ID distinct from\n\t\t * the thread_index descriptor pointer. We present this scheduler ID\n\t\t * instead of the descriptor memory address. */\n\t\tuint16_t thread_id = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_index + param->thread_uniqueid_offset,\n\t\t\t\tparam->uid_width,\n\t\t\t\t(uint8_t *)&thread_id);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read eCos thread id from target\");\n\t\t\treturn retval;\n\t\t}\n\t\trtos->thread_details[tasks_found].threadid = thread_id;\n\n\t\t/* Read the name pointer */\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_index + param->thread_name_offset,\n\t\t\t\tparam->pointer_width,\n\t\t\t\t(uint8_t *)&name_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read eCos thread name pointer from target\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* Read the thread name */\n\t\tretval =\n\t\t\ttarget_read_buffer(rtos->target,\n\t\t\t\tname_ptr,\n\t\t\t\tECOS_THREAD_NAME_STR_SIZE,\n\t\t\t\t(uint8_t *)&tmp_str);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading thread name from eCos target\");\n\t\t\treturn retval;\n\t\t}\n\t\ttmp_str[ECOS_THREAD_NAME_STR_SIZE-1] = '\\x00';\n\n\t\t/* Since eCos can have arbitrary C string names we can sometimes\n\t\t * get an internal warning from GDB about \"not well-formed\n\t\t * (invalid token)\" since the XML post-processing done by GDB on\n\t\t * the OpenOCD returned response containing the thread strings\n\t\t * is not escaped. For example the eCos kernel testsuite\n\t\t * application tm_basic uses the thread name \"<<NULL>>\" which\n\t\t * will trigger this failure unless escaped. */\n\t\tif (tmp_str[0] == '\\x00') {\n\t\t\tsnprintf(tmp_str, ECOS_THREAD_NAME_STR_SIZE, \"NoName:[0x%08\" PRIX32 \"]\", thread_index);\n\t\t} else {\n\t\t\t/* The following is a workaround to avoid any issues\n\t\t\t * from arbitrary eCos thread names causing GDB/OpenOCD\n\t\t\t * issues. We limit the escaped thread name passed to\n\t\t\t * GDB to the same length as the un-escaped just to\n\t\t\t * avoid overly long strings. */\n\t\t\tchar esc_str[ECOS_THREAD_NAME_STR_SIZE];\n\t\t\tbool escaped = ecos_escape_string(tmp_str, esc_str, sizeof(esc_str));\n\t\t\tif (escaped)\n\t\t\t\tstrcpy(tmp_str, esc_str);\n\t\t}\n\n\t\trtos->thread_details[tasks_found].thread_name_str =\n\t\t\tmalloc(strlen(tmp_str)+1);\n\t\tstrcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);\n\n\t\t/* Read the thread status */\n\t\tint64_t thread_status = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_index + param->thread_state_offset,\n\t\t\t\tparam->state_width,\n\t\t\t\t(uint8_t *)&thread_status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading thread state from eCos target\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* The thread_status is a BITMASK */\n\t\tchar state_desc[21];\t\t/* Enough for \"suspended+countsleep\\0\" maximum */\n\n\t\tif (thread_status & SUSPENDED)\n\t\t\tstrcpy(state_desc, \"suspended+\");\n\t\telse\n\t\t\tstate_desc[0] = '\\0';\n\n\t\tswitch (thread_status & ~SUSPENDED) {\n\t\tcase RUNNING:\n\t\t\tif (thread_index == current_thread_addr)\n\t\t\t\tstrcat(state_desc, \"running\");\n\t\t\telse if (thread_status & SUSPENDED)\n\t\t\t\tstate_desc[9] = '\\0';\t/* Drop '+' from \"suspended+\" */\n\t\t\telse\n\t\t\t\tstrcat(state_desc, \"ready\");\n\t\t\tbreak;\n\t\tcase SLEEPING:\n\t\t\tstrcat(state_desc, \"sleeping\");\n\t\t\tbreak;\n\t\tcase SLEEPSET:\n\t\tcase COUNTSLEEP:\n\t\t\tstrcat(state_desc, \"counted sleep\");\n\t\t\tbreak;\n\t\tcase CREATING:\n\t\t\tstrcpy(state_desc, \"creating\");\n\t\t\tbreak;\n\t\tcase EXITED:\n\t\t\tstrcpy(state_desc, \"exited\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tstrcpy(state_desc, \"unknown state\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* For the moment we do not bother decoding the wake reason for the\n\t\t * active \"running\" thread, but it is useful providing the sleep reason\n\t\t * for stacked threads. */\n\t\tint64_t sleep_reason = 0; /* sleep reason */\n\n\t\tif (thread_index != current_thread_addr &&\n\t\t\tecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE)) {\n\t\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t(thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_OFF)),\n\t\t\t\tecos_value(rtos, ECOS_VAL_COMMON_THREAD_SLEEP_SIZE),\n\t\t\t\t(uint8_t *)&sleep_reason);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading thread sleep reason from eCos target\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tif (sleep_reason < 0 ||\n\t\t\t\tsleep_reason > (int64_t)ARRAY_SIZE(ecos_thread_reasons)) {\n\t\t\t\tsleep_reason = 0;\n\t\t\t}\n\t\t}\n\n\t\t/* We do not display anything for the Cyg_Thread::NONE reason */\n\t\tsize_t tr_extra = 0;\n\t\tconst char *reason_desc = NULL;\n\t\tif (sleep_reason)\n\t\t\treason_desc = ecos_thread_reasons[sleep_reason].desc;\n\t\tif (reason_desc)\n\t\t\ttr_extra = 2 + strlen(reason_desc) + 1;\n\n\t\t/* Display thread priority if available: */\n\t\tint64_t priority = 0;\n\t\tsize_t pri_extra = 0;\n\t\tif (ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE)) {\n\t\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t(thread_index + ecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_OFF)),\n\t\t\t\tecos_value(rtos, ECOS_VAL_COMMON_THREAD_PRI_SIZE),\n\t\t\t\t(uint8_t *)&priority);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading thread priority from eCos target\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tpri_extra = (12 + 20); /* worst-case \", Priority: \" */\n\t\t}\n\n\t\tsize_t eilen = (8 + strlen(state_desc) + tr_extra + pri_extra);\n\t\tchar *eistr = malloc(eilen);\n\t\t/* We do not need to treat a malloc failure as a fatal error here since\n\t\t * the code below will just not report extra thread information if NULL,\n\t\t * thus allowing all of the threads to be enumerated even with reduced\n\t\t * information when the host is low on memory. However... */\n\t\tif (!eistr) {\n\t\t\tLOG_ERROR(\"OOM allocating extra information buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tint soff = snprintf(eistr, eilen, \"State: %s\", state_desc);\n\t\tif (tr_extra && reason_desc)\n\t\t\tsoff += snprintf(&eistr[soff], (eilen - soff), \" (%s)\", reason_desc);\n\t\tif (pri_extra)\n\t\t\t(void)snprintf(&eistr[soff], (eilen - soff), \", Priority: %\" PRId64 \"\", priority);\n\t\trtos->thread_details[tasks_found].extra_info_str = eistr;\n\n\t\trtos->thread_details[tasks_found].exists = true;\n\n\t\ttasks_found++;\n\t\tprev_thread_ptr = thread_index;\n\n\t\t/* Get the location of the next thread structure. */\n\t\tthread_index = rtos->symbols[ECOS_VAL_THREAD_LIST].address;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tprev_thread_ptr + param->thread_next_offset,\n\t\t\t\tparam->pointer_width,\n\t\t\t\t(uint8_t *) &thread_index);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading next thread pointer in eCos thread list\");\n\t\t\treturn retval;\n\t\t}\n\t} while (thread_index != first_thread);\n\n\trtos->thread_count = tasks_found;\n\treturn ERROR_OK;\n}\n\nstatic int ecos_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tstruct ecos_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tparam = rtos->rtos_specific_params;\n\n\tretval = ecos_check_app_info(rtos, param);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* We can get memory access errors reported by this function on\n\t * re-connecting to a board with stale thread information in memory. The\n\t * initial ecos_update_threads() is called twice and may read\n\t * stale/invalid information depending on the memory state. This happens\n\t * as part of the \"target remote\" connection so cannot be avoided by GDB\n\t * scripting. It is not critical and allowing the application to run and\n\t * initialise its BSS etc. will allow correct thread and register\n\t * information to be obtained. This really only affects debug sessions\n\t * where \"info thr\" is used before the initial run-time initialisation\n\t * has occurred. */\n\n\t/* Find the thread with that thread id */\n\tuint16_t id = 0;\n\tuint32_t thread_list_head = rtos->symbols[ECOS_VAL_THREAD_LIST].address;\n\tuint32_t thread_index;\n\ttarget_read_buffer(rtos->target, thread_list_head, param->pointer_width,\n\t\t\t(uint8_t *)&thread_index);\n\tbool done = false;\n\twhile (!done) {\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_index + param->thread_uniqueid_offset,\n\t\t\t\tparam->uid_width,\n\t\t\t\t(uint8_t *)&id);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading unique id from eCos thread 0x%08\" PRIX32 \"\", thread_index);\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (id == thread_id) {\n\t\t\tdone = true;\n\t\t\tbreak;\n\t\t}\n\t\ttarget_read_buffer(rtos->target,\n\t\t\tthread_index + param->thread_next_offset,\n\t\t\tparam->pointer_width,\n\t\t\t(uint8_t *) &thread_index);\n\t}\n\n\tif (done) {\n\t\t/* Read the stack pointer */\n\t\tint64_t stack_ptr = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_index + param->thread_stack_offset,\n\t\t\t\tparam->pointer_width,\n\t\t\t\t(uint8_t *)&stack_ptr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error reading stack frame from eCos thread\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (!stack_ptr) {\n\t\t\tLOG_ERROR(\"NULL stack pointer in thread %\" PRIu64, thread_id);\n\t\t\treturn -5;\n\t\t}\n\n\t\tconst struct rtos_register_stacking *stacking_info = NULL;\n\t\tif (param->target_stack_layout) {\n\t\t\tretval = param->target_stack_layout(rtos, param, stack_ptr, &stacking_info);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error reading stack layout for eCos thread\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t\tif (!stacking_info)\n\t\t\tstacking_info = &rtos_ecos_cortex_m3_stacking;\n\n\t\treturn rtos_generic_stack_read(rtos->target,\n\t\t\tstacking_info,\n\t\t\tstack_ptr,\n\t\t\treg_list,\n\t\t\tnum_regs);\n\t}\n\n\treturn -1;\n}\n\n/* NOTE: This is only called once when the first GDB connection is made to\n * OpenOCD and not on subsequent connections (when the application symbol table\n * may have changed, affecting the offsets of critical fields and the stacked\n * context shape). */\nstatic int ecos_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tunsigned int i;\n\t*symbol_list = calloc(\n\t\t\tARRAY_SIZE(ecos_symbol_list), sizeof(struct symbol_table_elem));\n\n\t/* If the target reference was passed into this function we could limit\n\t * the symbols we need to lookup to the target->type->name based\n\t * range. For the moment we need to provide a single vector with all of\n\t * the symbols across all of the supported architectures. */\n\tfor (i = 0; i < ARRAY_SIZE(ecos_symbol_list); i++) {\n\t\t(*symbol_list)[i].symbol_name = ecos_symbol_list[i].name;\n\t\t(*symbol_list)[i].optional = ecos_symbol_list[i].optional;\n\t}\n\n\treturn 0;\n}\n\n/* NOTE: Only called by rtos.c:rtos_qsymbol() when auto-detecting the RTOS. If\n * the target configuration uses the explicit \"-rtos\" config option then this\n * detection routine is NOT called. */\nstatic bool ecos_detect_rtos(struct target *target)\n{\n\tif ((target->rtos->symbols) &&\n\t\t\t(target->rtos->symbols[ECOS_VAL_THREAD_LIST].address != 0)) {\n\t\t/* looks like eCos */\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/* Since we should never have 0 as a valid eCos thread ID we use $Hg0 as the\n * indicator of a new session as regards flushing any cached state. */\nstatic int ecos_packet_hook(struct connection *connection,\n\t\tconst char *packet, int packet_size)\n{\n\tint64_t current_threadid;\n\n\tif (packet[0] == 'H' && packet[1] == 'g') {\n\t\tint numscan = sscanf(packet, \"Hg%16\" SCNx64, &current_threadid);\n\t\tif (numscan == 1 && current_threadid == 0) {\n\t\t\tstruct target *target = get_target_from_connection(connection);\n\t\t\tif (target && target->rtos && target->rtos->rtos_specific_params) {\n\t\t\t\tstruct ecos_params *param;\n\t\t\t\tparam = target->rtos->rtos_specific_params;\n\t\t\t\tparam->flush_common = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rtos_thread_packet(connection, packet, packet_size);\n}\n\n/* Called at start of day when eCos detected or specified in config file. */\nstatic int ecos_create(struct target *target)\n{\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(ecos_params_list); i++) {\n\t\tconst char * const *tnames = ecos_params_list[i].target_names;\n\t\twhile (*tnames) {\n\t\t\tif (strcmp(*tnames, target->type->name) == 0) {\n\t\t\t\t/* LOG_DEBUG(\"eCos: matched target \\\"%s\\\"\", target->type->name); */\n\t\t\t\ttarget->rtos->rtos_specific_params = (void *)&ecos_params_list[i];\n\t\t\t\tecos_params_list[i].flush_common = true;\n\t\t\t\tecos_params_list[i].stacking_info = NULL;\n\t\t\t\ttarget->rtos->current_thread = 0;\n\t\t\t\ttarget->rtos->thread_details = NULL;\n\n\t\t\t\t/* We use the $Hg0 packet as a new GDB connection \"start-of-day\" hook to\n\t\t\t\t * force a re-cache of information. It is possible for a single OpenOCD\n\t\t\t\t * session to be connected to a target with multiple GDB debug sessions\n\t\t\t\t * started/stopped. With eCos it is possible for those GDB sessions to\n\t\t\t\t * present applications with different offsets within a thread\n\t\t\t\t * descriptor for fields used by this module, and for the stacked\n\t\t\t\t * context within the connected target architecture to differ between\n\t\t\t\t * applications and even between threads in a single application. So we\n\t\t\t\t * need to ensure any information we cache is flushed on an application\n\t\t\t\t * change, and GDB referencing an invalid eCos thread ID (0) is a good\n\t\t\t\t * enough point, since we can accept the re-cache hit if that packet\n\t\t\t\t * appears during an established session, whilst benefiting from not\n\t\t\t\t * re-loading information on every update_threads or get_thread_reg_list\n\t\t\t\t * call. */\n\t\t\t\ttarget->rtos->gdb_thread_packet = ecos_packet_hook;\n\t\t\t\t/* We do not currently use the target->rtos->gdb_target_for_threadid\n\t\t\t\t * hook. */\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\ttnames++;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"Could not find target in eCos compatibility list\");\n\treturn -1;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/embKernel.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_embkernel_stackings.h\"\n\n#define EMBKERNEL_MAX_THREAD_NAME_STR_SIZE (64)\n\nstatic bool embkernel_detect_rtos(struct target *target);\nstatic int embkernel_create(struct target *target);\nstatic int embkernel_update_threads(struct rtos *rtos);\nstatic int embkernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs);\nstatic int embkernel_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\n\nconst struct rtos_type embkernel_rtos = {\n\t\t.name = \"embKernel\",\n\t\t.detect_rtos = embkernel_detect_rtos,\n\t\t.create = embkernel_create,\n\t\t.update_threads = embkernel_update_threads,\n\t\t.get_thread_reg_list =\n\t\tembkernel_get_thread_reg_list,\n\t\t.get_symbol_list_to_lookup = embkernel_get_symbol_list_to_lookup,\n};\n\nenum {\n\tSYMBOL_ID_S_CURRENT_TASK = 0,\n\tSYMBOL_ID_S_LIST_READY = 1,\n\tSYMBOL_ID_S_LIST_SLEEP = 2,\n\tSYMBOL_ID_S_LIST_SUSPENDED = 3,\n\tSYMBOL_ID_S_MAX_PRIORITIES = 4,\n\tSYMBOL_ID_S_CURRENT_TASK_COUNT = 5,\n};\n\nstatic const char * const embkernel_symbol_list[] = {\n\t\t\"Rtos::sCurrentTask\",\n\t\t\"Rtos::sListReady\",\n\t\t\"Rtos::sListSleep\",\n\t\t\"Rtos::sListSuspended\",\n\t\t\"Rtos::sMaxPriorities\",\n\t\t\"Rtos::sCurrentTaskCount\",\n\t\tNULL };\n\nstruct embkernel_params {\n\tconst char *target_name;\n\tconst unsigned char pointer_width;\n\tconst unsigned char thread_count_width;\n\tconst unsigned char rtos_list_size;\n\tconst unsigned char thread_stack_offset;\n\tconst unsigned char thread_name_offset;\n\tconst unsigned char thread_priority_offset;\n\tconst unsigned char thread_priority_width;\n\tconst unsigned char iterable_next_offset;\n\tconst unsigned char iterable_task_owner_offset;\n\tconst struct rtos_register_stacking *stacking_info;\n};\n\nstatic const struct embkernel_params embkernel_params_list[] = {\n\t\t{\n\t\t\t\"cortex_m\", /* target_name */\n\t\t\t4, /* pointer_width */\n\t\t\t4, /* thread_count_width */\n\t\t\t8, /*rtos_list_size */\n\t\t\t0, /*thread_stack_offset */\n\t\t\t4, /*thread_name_offset */\n\t\t\t8, /*thread_priority_offset */\n\t\t\t4, /*thread_priority_width */\n\t\t\t4, /*iterable_next_offset */\n\t\t\t12, /*iterable_task_owner_offset */\n\t\t\t&rtos_embkernel_cortex_m_stacking, /* stacking_info*/\n\t\t},\n\t\t{ \"hla_target\", /* target_name */\n\t\t\t4, /* pointer_width */\n\t\t\t4, /* thread_count_width */\n\t\t\t8, /*rtos_list_size */\n\t\t\t0, /*thread_stack_offset */\n\t\t\t4, /*thread_name_offset */\n\t\t\t8, /*thread_priority_offset */\n\t\t\t4, /*thread_priority_width */\n\t\t\t4, /*iterable_next_offset */\n\t\t\t12, /*iterable_task_owner_offset */\n\t\t\t&rtos_embkernel_cortex_m_stacking, /* stacking_info */\n\t\t}\n};\n\nstatic bool embkernel_detect_rtos(struct target *target)\n{\n\tif (target->rtos->symbols) {\n\t\tif (target->rtos->symbols[SYMBOL_ID_S_CURRENT_TASK].address != 0)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic int embkernel_create(struct target *target)\n{\n\tsize_t i = 0;\n\twhile ((i < ARRAY_SIZE(embkernel_params_list)) &&\n\t\t\t(strcmp(embkernel_params_list[i].target_name, target->type->name) != 0))\n\t\ti++;\n\n\tif (i >= ARRAY_SIZE(embkernel_params_list)) {\n\t\tLOG_WARNING(\"Could not find target \\\"%s\\\" in embKernel compatibility \"\n\t\t\t\t\"list\", target->type->name);\n\t\treturn -1;\n\t}\n\n\ttarget->rtos->rtos_specific_params = (void *) &embkernel_params_list[i];\n\treturn 0;\n}\n\nstatic int embkernel_get_tasks_details(struct rtos *rtos, int64_t iterable, const struct embkernel_params *param,\n\t\tstruct thread_detail *details, const char *state_str)\n{\n\tint64_t task = 0;\n\tint retval = target_read_buffer(rtos->target, iterable + param->iterable_task_owner_offset, param->pointer_width,\n\t\t\t(uint8_t *) &task);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tdetails->threadid = (threadid_t) task;\n\tdetails->exists = true;\n\n\tint64_t name_ptr = 0;\n\tretval = target_read_buffer(rtos->target, task + param->thread_name_offset, param->pointer_width,\n\t\t\t(uint8_t *) &name_ptr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdetails->thread_name_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE);\n\tif (name_ptr) {\n\t\tretval = target_read_buffer(rtos->target, name_ptr, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE,\n\t\t\t\t(uint8_t *) details->thread_name_str);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tdetails->thread_name_str[EMBKERNEL_MAX_THREAD_NAME_STR_SIZE - 1] = 0;\n\t} else {\n\t\tsnprintf(details->thread_name_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, \"NoName:[0x%08X]\", (unsigned int) task);\n\t}\n\n\tint64_t priority = 0;\n\tretval = target_read_buffer(rtos->target, task + param->thread_priority_offset, param->thread_priority_width,\n\t\t\t(uint8_t *) &priority);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tdetails->extra_info_str = malloc(EMBKERNEL_MAX_THREAD_NAME_STR_SIZE);\n\tif (task == rtos->current_thread) {\n\t\tsnprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, \"State: Running, Priority: %u\",\n\t\t\t\t(unsigned int) priority);\n\t} else {\n\t\tsnprintf(details->extra_info_str, EMBKERNEL_MAX_THREAD_NAME_STR_SIZE, \"State: %s, Priority: %u\",\n\t\t\t\tstate_str, (unsigned int) priority);\n\t}\n\n\tLOG_OUTPUT(\"Getting task details: iterable=0x%08X, task=0x%08X, name=%s\\n\", (unsigned int)iterable,\n\t\t\t(unsigned int)task, details->thread_name_str);\n\treturn 0;\n}\n\nstatic int embkernel_update_threads(struct rtos *rtos)\n{\n\t/* int i = 0; */\n\tint retval;\n\tconst struct embkernel_params *param;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for embKernel\");\n\t\treturn -4;\n\t}\n\n\tif (rtos->symbols[SYMBOL_ID_S_CURRENT_TASK].address == 0) {\n\t\tLOG_ERROR(\"Don't have the thread list head\");\n\t\treturn -2;\n\t}\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\tparam = (const struct embkernel_params *) rtos->rtos_specific_params;\n\n\tretval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_S_CURRENT_TASK].address, param->pointer_width,\n\t\t\t(uint8_t *) &rtos->current_thread);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading current thread in embKernel thread list\");\n\t\treturn retval;\n\t}\n\n\tint64_t max_used_priority = 0;\n\tretval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_S_MAX_PRIORITIES].address, param->pointer_width,\n\t\t\t(uint8_t *) &max_used_priority);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint thread_list_size = 0;\n\tretval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_S_CURRENT_TASK_COUNT].address,\n\t\t\tparam->thread_count_width, (uint8_t *) &thread_list_size);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read embKernel thread count from target\");\n\t\treturn retval;\n\t}\n\n\t/* create space for new thread details */\n\trtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size);\n\tif (!rtos->thread_details) {\n\t\tLOG_ERROR(\"Error allocating memory for %d threads\", thread_list_size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint thread_idx = 0;\n\t/* Look for ready tasks */\n\tfor (int pri = 0; pri < max_used_priority; pri++) {\n\t\t/* Get first item in queue */\n\t\tint64_t iterable = 0;\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\trtos->symbols[SYMBOL_ID_S_LIST_READY].address + (pri * param->rtos_list_size), param->pointer_width,\n\t\t\t\t(uint8_t *) &iterable);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tfor (; iterable && thread_idx < thread_list_size; thread_idx++) {\n\t\t\t/* Get info from this iterable item */\n\t\t\tretval = embkernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[thread_idx], \"Ready\");\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* Get next iterable item */\n\t\t\tretval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width,\n\t\t\t\t\t(uint8_t *) &iterable);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\t/* Look for sleeping tasks */\n\tint64_t iterable = 0;\n\tretval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_S_LIST_SLEEP].address, param->pointer_width,\n\t\t\t(uint8_t *) &iterable);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tfor (; iterable && thread_idx < thread_list_size; thread_idx++) {\n\t\t/*Get info from this iterable item */\n\t\tretval = embkernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[thread_idx], \"Sleeping\");\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/*Get next iterable item */\n\t\tretval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width,\n\t\t\t\t(uint8_t *) &iterable);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Look for suspended tasks  */\n\titerable = 0;\n\tretval = target_read_buffer(rtos->target, rtos->symbols[SYMBOL_ID_S_LIST_SUSPENDED].address, param->pointer_width,\n\t\t\t(uint8_t *) &iterable);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tfor (; iterable && thread_idx < thread_list_size; thread_idx++) {\n\t\t/* Get info from this iterable item */\n\t\tretval = embkernel_get_tasks_details(rtos, iterable, param, &rtos->thread_details[thread_idx], \"Suspended\");\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/*Get next iterable item */\n\t\tretval = target_read_buffer(rtos->target, iterable + param->iterable_next_offset, param->pointer_width,\n\t\t\t\t(uint8_t *) &iterable);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\trtos->thread_count = 0;\n\trtos->thread_count = thread_idx;\n\tLOG_OUTPUT(\"Found %u tasks\\n\", (unsigned int)thread_idx);\n\treturn 0;\n}\n\nstatic int embkernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tconst struct embkernel_params *param;\n\tint64_t stack_ptr = 0;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tparam = (const struct embkernel_params *) rtos->rtos_specific_params;\n\n\t/* Read the stack pointer */\n\tretval = target_read_buffer(rtos->target, thread_id + param->thread_stack_offset, param->pointer_width,\n\t\t\t(uint8_t *) &stack_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack frame from embKernel thread\");\n\t\treturn retval;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target, param->stacking_info, stack_ptr, reg_list, num_regs);\n}\n\nstatic int embkernel_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tunsigned int i;\n\t*symbol_list = calloc(ARRAY_SIZE(embkernel_symbol_list), sizeof(struct symbol_table_elem));\n\n\tfor (i = 0; i < ARRAY_SIZE(embkernel_symbol_list); i++)\n\t\t(*symbol_list)[i].symbol_name = embkernel_symbol_list[i];\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/hwthread.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"target/register.h\"\n#include <target/smp.h>\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"server/gdb_server.h\"\n\nstatic bool hwthread_detect_rtos(struct target *target);\nstatic int hwthread_create(struct target *target);\nstatic int hwthread_update_threads(struct rtos *rtos);\nstatic int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id,\n\t\tuint32_t reg_num, struct rtos_reg *rtos_reg);\nstatic int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs);\nstatic int hwthread_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\nstatic int hwthread_smp_init(struct target *target);\nstatic int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value);\nstatic int hwthread_read_buffer(struct rtos *rtos, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer);\nstatic int hwthread_write_buffer(struct rtos *rtos, target_addr_t address,\n\t\tuint32_t size, const uint8_t *buffer);\n\n#define HW_THREAD_NAME_STR_SIZE (32)\n\nstatic inline threadid_t threadid_from_target(const struct target *target)\n{\n\treturn target->coreid + 1;\n}\n\nconst struct rtos_type hwthread_rtos = {\n\t.name = \"hwthread\",\n\t.detect_rtos = hwthread_detect_rtos,\n\t.create = hwthread_create,\n\t.update_threads = hwthread_update_threads,\n\t.get_thread_reg_list = hwthread_get_thread_reg_list,\n\t.get_thread_reg = hwthread_get_thread_reg,\n\t.get_symbol_list_to_lookup = hwthread_get_symbol_list_to_lookup,\n\t.smp_init = hwthread_smp_init,\n\t.set_reg = hwthread_set_reg,\n\t.read_buffer = hwthread_read_buffer,\n\t.write_buffer = hwthread_write_buffer,\n};\n\nstruct hwthread_params {\n\tint dummy_param;\n};\n\nstatic int hwthread_fill_thread(struct rtos *rtos, struct target *curr, int thread_num)\n{\n\tchar tmp_str[HW_THREAD_NAME_STR_SIZE];\n\tthreadid_t tid = threadid_from_target(curr);\n\n\tmemset(tmp_str, 0, HW_THREAD_NAME_STR_SIZE);\n\n\t/* thread-id is the core-id of this core inside the SMP group plus 1 */\n\trtos->thread_details[thread_num].threadid = tid;\n\t/* create the thread name */\n\trtos->thread_details[thread_num].exists = true;\n\trtos->thread_details[thread_num].thread_name_str = strdup(target_name(curr));\n\tsnprintf(tmp_str, HW_THREAD_NAME_STR_SIZE-1, \"state: %s\", debug_reason_name(curr));\n\trtos->thread_details[thread_num].extra_info_str = strdup(tmp_str);\n\n\treturn ERROR_OK;\n}\n\nstatic int hwthread_update_threads(struct rtos *rtos)\n{\n\tint threads_found = 0;\n\tint thread_list_size = 0;\n\tstruct target_list *head;\n\tstruct target *target;\n\tint64_t current_thread = 0;\n\tint64_t current_threadid = rtos->current_threadid; /* thread selected by GDB */\n\tenum target_debug_reason current_reason = DBG_REASON_UNDEFINED;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\ttarget = rtos->target;\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\t/* determine the number of \"threads\" */\n\tif (target->smp) {\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\n\t\t\tif (!target_was_examined(curr))\n\t\t\t\tcontinue;\n\n\t\t\t++thread_list_size;\n\t\t}\n\t} else\n\t\tthread_list_size = 1;\n\n\t/* restore the threadid which is currently selected by GDB\n\t * because rtos_free_threadlist() wipes out it\n\t * (GDB thread id is 1-based indexing) */\n\tif (current_threadid <= thread_list_size)\n\t\trtos->current_threadid = current_threadid;\n\telse\n\t\tLOG_WARNING(\"SMP node change, disconnect GDB from core/thread %\" PRId64,\n\t\t\t    current_threadid);\n\n\t/* create space for new thread details */\n\trtos->thread_details = malloc(sizeof(struct thread_detail) * thread_list_size);\n\n\tif (target->smp) {\n\t\t/* loop over all threads */\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\n\t\t\tif (!target_was_examined(curr))\n\t\t\t\tcontinue;\n\n\t\t\tthreadid_t tid = threadid_from_target(curr);\n\n\t\t\thwthread_fill_thread(rtos, curr, threads_found);\n\n\t\t\t/* find an interesting thread to set as current */\n\t\t\tswitch (current_reason) {\n\t\t\tcase DBG_REASON_UNDEFINED:\n\t\t\t\tcurrent_reason = curr->debug_reason;\n\t\t\t\tcurrent_thread = tid;\n\t\t\t\tbreak;\n\t\t\tcase DBG_REASON_SINGLESTEP:\n\t\t\t\t/* single-step can only be overridden by itself */\n\t\t\t\tif (curr->debug_reason == DBG_REASON_SINGLESTEP) {\n\t\t\t\t\tif (tid == rtos->current_threadid)\n\t\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase DBG_REASON_BREAKPOINT:\n\t\t\t\t/* single-step overrides breakpoint */\n\t\t\t\tif (curr->debug_reason == DBG_REASON_SINGLESTEP) {\n\t\t\t\t\tcurrent_reason = curr->debug_reason;\n\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t} else\n\t\t\t\t/* multiple breakpoints, prefer gdbs' threadid */\n\t\t\t\tif (curr->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\t\t\t\tif (tid == rtos->current_threadid)\n\t\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase DBG_REASON_WATCHPOINT:\n\t\t\t\t/* breakpoint and single-step override watchpoint */\n\t\t\t\tif (curr->debug_reason == DBG_REASON_SINGLESTEP ||\n\t\t\t\t\t\tcurr->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\t\t\t\tcurrent_reason = curr->debug_reason;\n\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase DBG_REASON_DBGRQ:\n\t\t\t\t/* all other reasons override debug-request */\n\t\t\t\tif (curr->debug_reason == DBG_REASON_SINGLESTEP ||\n\t\t\t\t\t\tcurr->debug_reason == DBG_REASON_WATCHPOINT ||\n\t\t\t\t\t\tcurr->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\t\t\t\tcurrent_reason = curr->debug_reason;\n\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t} else\n\t\t\t\tif (curr->debug_reason == DBG_REASON_DBGRQ) {\n\t\t\t\t\tif (tid == rtos->current_threadid)\n\t\t\t\t\t\tcurrent_thread = tid;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthreads_found++;\n\t\t}\n\t} else {\n\t\thwthread_fill_thread(rtos, target, threads_found);\n\t\tcurrent_thread = threadid_from_target(target);\n\t\tthreads_found++;\n\t}\n\n\trtos->thread_count = threads_found;\n\n\t/* we found an interesting thread, set it as current */\n\tif (current_thread != 0)\n\t\trtos->current_thread = current_thread;\n\telse if (rtos->current_threadid != 0)\n\t\trtos->current_thread = rtos->current_threadid;\n\telse\n\t\trtos->current_thread = threadid_from_target(target);\n\n\tLOG_DEBUG(\"%s current_thread=%i\", __func__, (int)rtos->current_thread);\n\treturn 0;\n}\n\nstatic int hwthread_smp_init(struct target *target)\n{\n\treturn hwthread_update_threads(target->rtos);\n}\n\nstatic struct target *hwthread_find_thread(struct target *target, int64_t thread_id)\n{\n\t/* Find the thread with that thread_id */\n\tif (!target)\n\t\treturn NULL;\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tif (thread_id == threadid_from_target(head->target))\n\t\t\t\treturn head->target;\n\t\t}\n\t} else if (thread_id == threadid_from_target(target)) {\n\t\treturn target;\n\t}\n\treturn NULL;\n}\n\nstatic int hwthread_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **rtos_reg_list, int *rtos_reg_list_size)\n{\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tstruct target *target = rtos->target;\n\n\tstruct target *curr = hwthread_find_thread(target, thread_id);\n\tif (!curr)\n\t\treturn ERROR_FAIL;\n\n\tif (!target_was_examined(curr))\n\t\treturn ERROR_FAIL;\n\n\tint reg_list_size;\n\tstruct reg **reg_list;\n\tint retval = target_get_gdb_reg_list(curr, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_GENERAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint j = 0;\n\tfor (int i = 0; i < reg_list_size; i++) {\n\t\tif (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\tcontinue;\n\t\tj++;\n\t}\n\t*rtos_reg_list_size = j;\n\t*rtos_reg_list = calloc(*rtos_reg_list_size, sizeof(struct rtos_reg));\n\tif (!*rtos_reg_list) {\n\t\tfree(reg_list);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tj = 0;\n\tfor (int i = 0; i < reg_list_size; i++) {\n\t\tif (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\tcontinue;\n\t\tif (!reg_list[i]->valid) {\n\t\t\tretval = reg_list[i]->type->get(reg_list[i]);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Couldn't get register %s.\", reg_list[i]->name);\n\t\t\t\tfree(reg_list);\n\t\t\t\tfree(*rtos_reg_list);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t\t(*rtos_reg_list)[j].number = reg_list[i]->number;\n\t\t(*rtos_reg_list)[j].size = reg_list[i]->size;\n\t\tmemcpy((*rtos_reg_list)[j].value, reg_list[i]->value,\n\t\t\t\tDIV_ROUND_UP(reg_list[i]->size, 8));\n\t\tj++;\n\t}\n\tfree(reg_list);\n\n\treturn ERROR_OK;\n}\n\nstatic int hwthread_get_thread_reg(struct rtos *rtos, int64_t thread_id,\n\t\tuint32_t reg_num, struct rtos_reg *rtos_reg)\n{\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tstruct target *target = rtos->target;\n\n\tstruct target *curr = hwthread_find_thread(target, thread_id);\n\tif (!curr) {\n\t\tLOG_ERROR(\"Couldn't find RTOS thread for id %\" PRId64 \".\", thread_id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!target_was_examined(curr)) {\n\t\tLOG_ERROR(\"Target %d hasn't been examined yet.\", curr->coreid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct reg *reg = register_get_by_number(curr->reg_cache, reg_num, true);\n\tif (!reg) {\n\t\tLOG_ERROR(\"Couldn't find register %\" PRIu32 \" in thread %\" PRId64 \".\", reg_num,\n\t\t\t\tthread_id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (reg->type->get(reg) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\trtos_reg->number = reg->number;\n\trtos_reg->size = reg->size;\n\tunsigned bytes = (reg->size + 7) / 8;\n\tassert(bytes <= sizeof(rtos_reg->value));\n\tmemcpy(rtos_reg->value, reg->value, bytes);\n\n\treturn ERROR_OK;\n}\n\nstatic int hwthread_set_reg(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value)\n{\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tstruct target *target = rtos->target;\n\n\tstruct target *curr = hwthread_find_thread(target, rtos->current_thread);\n\tif (!curr)\n\t\treturn ERROR_FAIL;\n\n\tstruct reg *reg = register_get_by_number(curr->reg_cache, reg_num, true);\n\tif (!reg)\n\t\treturn ERROR_FAIL;\n\n\treturn reg->type->set(reg, reg_value);\n}\n\nstatic int hwthread_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t/* return an empty list, we don't have any symbols to look up */\n\t*symbol_list = calloc(1, sizeof(struct symbol_table_elem));\n\t(*symbol_list)[0].symbol_name = NULL;\n\treturn 0;\n}\n\nstatic int hwthread_target_for_threadid(struct connection *connection, int64_t thread_id, struct target **p_target)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\n\tstruct target *curr = hwthread_find_thread(target, thread_id);\n\tif (!curr)\n\t\treturn ERROR_FAIL;\n\n\t*p_target = curr;\n\n\treturn ERROR_OK;\n}\n\nstatic bool hwthread_detect_rtos(struct target *target)\n{\n\t/* always return 0, avoid auto-detection */\n\treturn false;\n}\n\nstatic int hwthread_thread_packet(struct connection *connection, const char *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\n\tstruct target *curr = NULL;\n\tint64_t current_threadid;\n\n\tif (packet[0] == 'H' && packet[1] == 'g') {\n\t\tsscanf(packet, \"Hg%16\" SCNx64, &current_threadid);\n\n\t\tif (current_threadid > 0) {\n\t\t\tif (hwthread_target_for_threadid(connection, current_threadid, &curr) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"hwthread: cannot find thread id %\"PRId64, current_threadid);\n\t\t\t\tgdb_put_packet(connection, \"E01\", 3);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ttarget->rtos->current_thread = current_threadid;\n\t\t} else\n\t\tif (current_threadid == 0 || current_threadid == -1)\n\t\t\ttarget->rtos->current_thread = threadid_from_target(target);\n\n\t\ttarget->rtos->current_threadid = current_threadid;\n\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn rtos_thread_packet(connection, packet, packet_size);\n}\n\nstatic int hwthread_create(struct target *target)\n{\n\tLOG_INFO(\"Hardware thread awareness created\");\n\n\ttarget->rtos->rtos_specific_params = NULL;\n\ttarget->rtos->current_thread = 0;\n\ttarget->rtos->thread_details = NULL;\n\ttarget->rtos->gdb_target_for_threadid = hwthread_target_for_threadid;\n\ttarget->rtos->gdb_thread_packet = hwthread_thread_packet;\n\treturn 0;\n}\n\nstatic int hwthread_read_buffer(struct rtos *rtos, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer)\n{\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tstruct target *target = rtos->target;\n\n\tstruct target *curr = hwthread_find_thread(target, rtos->current_thread);\n\tif (!curr)\n\t\treturn ERROR_FAIL;\n\n\treturn target_read_buffer(curr, address, size, buffer);\n}\n\nstatic int hwthread_write_buffer(struct rtos *rtos, target_addr_t address,\n\t\tuint32_t size, const uint8_t *buffer)\n{\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tstruct target *target = rtos->target;\n\n\tstruct target *curr = hwthread_find_thread(target, rtos->current_thread);\n\tif (!curr)\n\t\treturn ERROR_FAIL;\n\n\treturn target_write_buffer(curr, address, size, buffer);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/linux.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by STEricsson                                      *\n *   Heythem Bouhaja heythem.bouhaja@stericsson.com   : creation           *\n *   Michel JAOUEN michel.jaouen@stericsson.com : adaptation to rtos       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos.h\"\n#include \"rtos_standard_stackings.h\"\n#include <target/register.h>\n#include <target/smp.h>\n#include \"server/gdb_server.h\"\n\n#define LINUX_USER_KERNEL_BORDER 0xc0000000\n#include \"linux_header.h\"\n#define PHYS\n#define MAX_THREADS 200\n/*  specific task  */\nstruct linux_os {\n\tconst char *name;\n\tuint32_t init_task_addr;\n\tint thread_count;\n\tint threadid_count;\n\tint preupdtate_threadid_count;\n\tint nr_cpus;\n\tint threads_lookup;\n\tint threads_needs_update;\n\tstruct current_thread *current_threads;\n\tstruct threads *thread_list;\n\t/*  virt2phys parameter */\n\tuint32_t phys_mask;\n\tuint32_t phys_base;\n};\n\nstruct current_thread {\n\tint64_t threadid;\n\tint32_t core_id;\n#ifdef PID_CHECK\n\tuint32_t pid;\n#endif\n\tuint32_t TS;\n\tstruct current_thread *next;\n};\n\nstruct threads {\n\tchar name[17];\n\tuint32_t base_addr;\t/*  address to read magic */\n\tuint32_t state;\t\t/*  magic value : filled only at creation */\n\tuint32_t pid;\t\t/* linux pid : id for identifying a thread */\n\tuint32_t oncpu;\t\t/* content cpu number in current thread */\n\tuint32_t asid;\t\t/*  filled only at creation  */\n\tint64_t threadid;\n\tint status;\t\t/* dead = 1 alive = 2 current = 3 alive and current */\n\t/*  value that should not change during the live of a thread ? */\n\tuint32_t thread_info_addr;\t/*  contain latest thread_info_addr computed */\n\t/*  retrieve from thread_info */\n\tstruct cpu_context *context;\n\tstruct threads *next;\n};\n\nstruct cpu_context {\n\tuint32_t R4;\n\tuint32_t R5;\n\tuint32_t R6;\n\tuint32_t R7;\n\tuint32_t R8;\n\tuint32_t R9;\n\tuint32_t IP;\n\tuint32_t FP;\n\tuint32_t SP;\n\tuint32_t PC;\n\tuint32_t preempt_count;\n};\nstatic struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,\n\t\t\t\t     uint32_t *info_addr);\nstatic int insert_into_threadlist(struct target *target, struct threads *t);\n\nstatic int linux_os_create(struct target *target);\n\nstatic int linux_os_dummy_update(struct rtos *rtos)\n{\n\t/*  update is done only when thread request come\n\t *  too many thread to do it on each stop */\n\treturn 0;\n}\n\nstatic int linux_compute_virt2phys(struct target *target, target_addr_t address)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\ttarget_addr_t pa = 0;\n\tint retval = target->type->virt2phys(target, address, &pa);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Cannot compute linux virt2phys translation\");\n\t\t/*  fixes default address  */\n\t\tlinux_os->phys_base = 0;\n\t\treturn ERROR_FAIL;\n\t}\n\n\tlinux_os->init_task_addr = address;\n\taddress = address & linux_os->phys_mask;\n\tlinux_os->phys_base = pa - address;\n\treturn ERROR_OK;\n}\n\nstatic int linux_read_memory(struct target *target,\n\tuint32_t address, uint32_t size, uint32_t count,\n\tuint8_t *buffer)\n{\n#ifdef PHYS\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tuint32_t pa = (address & linux_os->phys_mask) + linux_os->phys_base;\n#endif\n\tif (address < 0xc0000000) {\n\t\tLOG_ERROR(\"linux awareness : address in user space\");\n\t\treturn ERROR_FAIL;\n\t}\n#ifdef PHYS\n\ttarget_read_phys_memory(target, pa, size, count, buffer);\n#endif\n\ttarget_read_memory(target, address, size, count, buffer);\n\treturn ERROR_OK;\n}\n\nstatic int fill_buffer(struct target *target, uint32_t addr, uint8_t *buffer)\n{\n\n\tif ((addr & 0xfffffffc) != addr)\n\t\tLOG_INFO(\"unaligned address %\" PRIx32 \"!!\", addr);\n\n\tint retval = linux_read_memory(target, addr, 4, 1, buffer);\n\treturn retval;\n\n}\n\nstatic uint32_t get_buffer(struct target *target, const uint8_t *buffer)\n{\n\tuint32_t value = 0;\n\tconst uint8_t *value_ptr = buffer;\n\tvalue = target_buffer_get_u32(target, value_ptr);\n\treturn value;\n}\n\nstatic int linux_os_thread_reg_list(struct rtos *rtos,\n\tint64_t thread_id, struct rtos_reg **reg_list, int *num_regs)\n{\n\tstruct target *target = rtos->target;\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct current_thread *tmp = linux_os->current_threads;\n\tstruct current_thread *next;\n\tint found = 0;\n\tint retval;\n\t/*  check if a current thread is requested  */\n\tnext = tmp;\n\n\tdo {\n\t\tif (next->threadid == thread_id)\n\t\t\tfound = 1;\n\t\telse\n\t\t\tnext = next->next;\n\t} while ((found == 0) && (next != tmp) && (next));\n\n\tif (found == 0) {\n\t\tLOG_ERROR(\"could not find thread: %\" PRIx64, thread_id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*  search target to perform the access  */\n\tstruct reg **gdb_reg_list;\n\tstruct target_list *head;\n\tfound = 0;\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tif (head->target->coreid == next->core_id) {\n\t\t\ttarget = head->target;\n\t\t\tfound = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (found == 0) {\n\t\tLOG_ERROR\n\t\t(\n\t\t\t\"current thread %\" PRIx64 \": no target to perform access of core id %\" PRIx32,\n\t\t\tthread_id,\n\t\t\tnext->core_id);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*LOG_INFO(\"thread %lx current on core %x\",thread_id, target->coreid);*/\n\tretval = target_get_gdb_reg_list(target, &gdb_reg_list, num_regs, REG_CLASS_GENERAL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*reg_list = calloc(*num_regs, sizeof(struct rtos_reg));\n\n\tfor (int i = 0; i < *num_regs; ++i) {\n\t\tif (!gdb_reg_list[i]->valid)\n\t\t\tgdb_reg_list[i]->type->get(gdb_reg_list[i]);\n\n\t\t(*reg_list)[i].number = gdb_reg_list[i]->number;\n\t\t(*reg_list)[i].size = gdb_reg_list[i]->size;\n\n\t\tbuf_cpy(gdb_reg_list[i]->value, (*reg_list)[i].value, (*reg_list)[i].size);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool linux_os_detect(struct target *target)\n{\n\tLOG_INFO(\"should no be called\");\n\treturn false;\n}\n\nstatic int linux_os_smp_init(struct target *target);\nstatic int linux_os_clean(struct target *target);\n#define INIT_TASK 0\nstatic const char * const linux_symbol_list[] = {\n\t\"init_task\",\n\tNULL\n};\n\nstatic int linux_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\tunsigned int i;\n\t*symbol_list = (struct symbol_table_elem *)\n\t\tcalloc(ARRAY_SIZE(linux_symbol_list), sizeof(struct symbol_table_elem));\n\n\tfor (i = 0; i < ARRAY_SIZE(linux_symbol_list); i++)\n\t\t(*symbol_list)[i].symbol_name = linux_symbol_list[i];\n\n\treturn 0;\n}\n\nstatic char *linux_ps_command(struct target *target);\n\nconst struct rtos_type linux_rtos = {\n\t.name = \"linux\",\n\t.detect_rtos = linux_os_detect,\n\t.create = linux_os_create,\n\t.smp_init = linux_os_smp_init,\n\t.update_threads = linux_os_dummy_update,\n\t.get_thread_reg_list = linux_os_thread_reg_list,\n\t.get_symbol_list_to_lookup = linux_get_symbol_list_to_lookup,\n\t.clean = linux_os_clean,\n\t.ps_command = linux_ps_command,\n};\n\nstatic int linux_thread_packet(struct connection *connection, char const *packet,\n\t\tint packet_size);\nstatic void linux_identify_current_threads(struct target *target);\n\n#ifdef PID_CHECK\nint fill_task_pid(struct target *target, struct threads *t)\n{\n\tuint32_t pid_addr = t->base_addr + PID;\n\tuint8_t buffer[4];\n\tint retval = fill_buffer(target, pid_addr, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\t\tt->pid = val;\n\t} else\n\t\tLOG_ERROR(\"fill_task_pid: unable to read memory\");\n\n\treturn retval;\n}\n#endif\n\nstatic int fill_task(struct target *target, struct threads *t)\n{\n\tint retval;\n\tuint32_t pid_addr = t->base_addr + PID;\n\tuint32_t mem_addr = t->base_addr + MEM;\n\tuint32_t on_cpu = t->base_addr + ONCPU;\n\tuint8_t *buffer = calloc(1, 4);\n\tretval = fill_buffer(target, t->base_addr, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\t\tt->state = val;\n\t} else\n\t\tLOG_ERROR(\"fill_task: unable to read memory\");\n\n\tretval = fill_buffer(target, pid_addr, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\t\tt->pid = val;\n\t} else\n\t\tLOG_ERROR(\"fill task: unable to read memory\");\n\n\tretval = fill_buffer(target, on_cpu, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\t\tt->oncpu = val;\n\t} else\n\t\tLOG_ERROR(\"fill task: unable to read memory\");\n\n\tretval = fill_buffer(target, mem_addr, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\n\t\tif (val != 0) {\n\t\t\tuint32_t asid_addr = val + MM_CTX;\n\t\t\tretval = fill_buffer(target, asid_addr, buffer);\n\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tval = get_buffer(target, buffer);\n\t\t\t\tt->asid = val;\n\t\t\t} else\n\t\t\t\tLOG_ERROR\n\t\t\t\t\t(\"fill task: unable to read memory -- ASID\");\n\t\t} else\n\t\t\tt->asid = 0;\n\t} else\n\t\tLOG_ERROR(\"fill task: unable to read memory\");\n\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int get_name(struct target *target, struct threads *t)\n{\n\tint retval;\n\tuint32_t full_name[4];\n\tuint32_t comm = t->base_addr + COMM;\n\tint i;\n\n\tfor (i = 0; i < 17; i++)\n\t\tt->name[i] = 0;\n\n\tretval = linux_read_memory(target, comm, 4, 4, (uint8_t *) full_name);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"get_name: unable to read memory\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t raw_name = target_buffer_get_u32(target,\n\t\t\t(const uint8_t *)\n\t\t\t&full_name[0]);\n\tt->name[3] = raw_name >> 24;\n\tt->name[2] = raw_name >> 16;\n\tt->name[1] = raw_name >> 8;\n\tt->name[0] = raw_name;\n\traw_name =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&full_name[1]);\n\tt->name[7] = raw_name >> 24;\n\tt->name[6] = raw_name >> 16;\n\tt->name[5] = raw_name >> 8;\n\tt->name[4] = raw_name;\n\traw_name =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&full_name[2]);\n\tt->name[11] = raw_name >> 24;\n\tt->name[10] = raw_name >> 16;\n\tt->name[9] = raw_name >> 8;\n\tt->name[8] = raw_name;\n\traw_name =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&full_name[3]);\n\tt->name[15] = raw_name >> 24;\n\tt->name[14] = raw_name >> 16;\n\tt->name[13] = raw_name >> 8;\n\tt->name[12] = raw_name;\n\treturn ERROR_OK;\n\n}\n\nstatic int get_current(struct target *target, int create)\n{\n\tstruct target_list *head;\n\tuint8_t *buf;\n\tuint32_t val;\n\tuint32_t ti_addr;\n\tuint8_t *buffer = calloc(1, 4);\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct current_thread *ctt = linux_os->current_threads;\n\n\t/*  invalid current threads content */\n\twhile (ctt) {\n\t\tctt->threadid = -1;\n\t\tctt->TS = 0xdeadbeef;\n\t\tctt = ctt->next;\n\t}\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct reg **reg_list;\n\t\tint reg_list_size;\n\t\tint retval;\n\n\t\tif (target_get_gdb_reg_list(head->target, &reg_list,\n\t\t\t\t&reg_list_size, REG_CLASS_GENERAL) != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t}\n\n\t\tif (!reg_list[13]->valid)\n\t\t\treg_list[13]->type->get(reg_list[13]);\n\n\t\tbuf = reg_list[13]->value;\n\t\tval = get_buffer(target, buf);\n\t\tti_addr = (val & 0xffffe000);\n\t\tuint32_t ts_addr = ti_addr + 0xc;\n\t\tretval = fill_buffer(target, ts_addr, buffer);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tuint32_t TS = get_buffer(target, buffer);\n\t\t\tuint32_t cpu, on_cpu = TS + ONCPU;\n\t\t\tretval = fill_buffer(target, on_cpu, buffer);\n\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\t/*uint32_t cpu = get_buffer(target, buffer);*/\n\t\t\t\tstruct current_thread *ct =\n\t\t\t\t\tlinux_os->current_threads;\n\t\t\t\tcpu = head->target->coreid;\n\n\t\t\t\twhile ((ct) && (ct->core_id != (int32_t) cpu))\n\t\t\t\t\tct = ct->next;\n\n\t\t\t\tif ((ct) && (ct->TS == 0xdeadbeef))\n\t\t\t\t\tct->TS = TS;\n\t\t\t\telse\n\t\t\t\t\tLOG_ERROR\n\t\t\t\t\t\t(\"error in linux current thread update\");\n\n\t\t\t\tif (create && ct) {\n\t\t\t\t\tstruct threads *t;\n\t\t\t\t\tt = calloc(1, sizeof(struct threads));\n\t\t\t\t\tt->base_addr = ct->TS;\n\t\t\t\t\tfill_task(target, t);\n\t\t\t\t\tget_name(target, t);\n\t\t\t\t\tt->oncpu = cpu;\n\t\t\t\t\tinsert_into_threadlist(target, t);\n\t\t\t\t\tt->status = 3;\n\t\t\t\t\tt->thread_info_addr = 0xdeadbeef;\n\t\t\t\t\tct->threadid = t->threadid;\n\t\t\t\t\tlinux_os->thread_count++;\n#ifdef PID_CHECK\n\t\t\t\t\tct->pid = t->pid;\n#endif\n\t\t\t\t\t/*LOG_INFO(\"Creation of current thread %s\",t->name);*/\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfree(reg_list);\n\t}\n\n\tfree(buffer);\n\n\treturn ERROR_OK;\n}\n\nstatic struct cpu_context *cpu_context_read(struct target *target, uint32_t base_addr,\n\tuint32_t *thread_info_addr_old)\n{\n\tstruct cpu_context *context = calloc(1, sizeof(struct cpu_context));\n\tuint32_t preempt_count_addr = 0;\n\tuint32_t registers[10];\n\tuint8_t *buffer = calloc(1, 4);\n\tuint32_t stack = base_addr + QAT;\n\tuint32_t thread_info_addr = 0;\n\tuint32_t thread_info_addr_update = 0;\n\tint retval = ERROR_FAIL;\n\tcontext->R4 = 0xdeadbeef;\n\tcontext->R5 = 0xdeadbeef;\n\tcontext->R6 = 0xdeadbeef;\n\tcontext->R7 = 0xdeadbeef;\n\tcontext->R8 = 0xdeadbeef;\n\tcontext->R9 = 0xdeadbeef;\n\tcontext->IP = 0xdeadbeef;\n\tcontext->FP = 0xdeadbeef;\n\tcontext->SP = 0xdeadbeef;\n\tcontext->PC = 0xdeadbeef;\nretry:\n\n\tif (*thread_info_addr_old == 0xdeadbeef) {\n\t\tretval = fill_buffer(target, stack, buffer);\n\n\t\tif (retval == ERROR_OK)\n\t\t\tthread_info_addr = get_buffer(target, buffer);\n\t\telse\n\t\t\tLOG_ERROR(\"cpu_context: unable to read memory\");\n\n\t\tthread_info_addr_update = thread_info_addr;\n\t} else\n\t\tthread_info_addr = *thread_info_addr_old;\n\n\tpreempt_count_addr = thread_info_addr + PREEMPT;\n\tretval = fill_buffer(target, preempt_count_addr, buffer);\n\n\tif (retval == ERROR_OK)\n\t\tcontext->preempt_count = get_buffer(target, buffer);\n\telse {\n\t\tif (*thread_info_addr_old != 0xdeadbeef) {\n\t\t\tLOG_ERROR\n\t\t\t\t(\"cpu_context: cannot read at thread_info_addr\");\n\n\t\t\tif (*thread_info_addr_old < LINUX_USER_KERNEL_BORDER)\n\t\t\t\tLOG_INFO\n\t\t\t\t\t(\"cpu_context : thread_info_addr in userspace!!!\");\n\n\t\t\t*thread_info_addr_old = 0xdeadbeef;\n\t\t\tgoto retry;\n\t\t}\n\n\t\tLOG_ERROR(\"cpu_context: unable to read memory\");\n\t}\n\n\tthread_info_addr += CPU_CONT;\n\n\tretval = linux_read_memory(target, thread_info_addr, 4, 10,\n\t\t\t(uint8_t *) registers);\n\n\tif (retval != ERROR_OK) {\n\t\tfree(buffer);\n\t\tLOG_ERROR(\"cpu_context: unable to read memory\\n\");\n\t\treturn context;\n\t}\n\n\tcontext->R4 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[0]);\n\tcontext->R5 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[1]);\n\tcontext->R6 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[2]);\n\tcontext->R7 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[3]);\n\tcontext->R8 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[4]);\n\tcontext->R9 =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[5]);\n\tcontext->IP =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[6]);\n\tcontext->FP =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[7]);\n\tcontext->SP =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[8]);\n\tcontext->PC =\n\t\ttarget_buffer_get_u32(target, (const uint8_t *)&registers[9]);\n\n\tif (*thread_info_addr_old == 0xdeadbeef)\n\t\t*thread_info_addr_old = thread_info_addr_update;\n\n\tfree(buffer);\n\n\treturn context;\n}\n\nstatic uint32_t next_task(struct target *target, struct threads *t)\n{\n\tuint8_t *buffer = calloc(1, 4);\n\tuint32_t next_addr = t->base_addr + NEXT;\n\tint retval = fill_buffer(target, next_addr, buffer);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t val = get_buffer(target, buffer);\n\t\tval = val - NEXT;\n\t\tfree(buffer);\n\t\treturn val;\n\t} else\n\t\tLOG_ERROR(\"next task: unable to read memory\");\n\n\tfree(buffer);\n\n\treturn 0;\n}\n\nstatic struct current_thread *add_current_thread(struct current_thread *currents,\n\tstruct current_thread *ct)\n{\n\tct->next = NULL;\n\n\tif (!currents) {\n\t\tcurrents = ct;\n\t\treturn currents;\n\t} else {\n\t\tstruct current_thread *temp = currents;\n\n\t\twhile (temp->next)\n\t\t\ttemp = temp->next;\n\n\t\ttemp->next = ct;\n\t\treturn currents;\n\t}\n}\n\nstatic struct threads *liste_del_task(struct threads *task_list, struct threads **t,\n\tstruct threads *prev)\n{\n\tLOG_INFO(\"del task %\" PRId64, (*t)->threadid);\n\tif (prev)\n\t\tprev->next = (*t)->next;\n\telse\n\t\ttask_list = (*t)->next;\n\n\t/*  free content of threads */\n\tfree((*t)->context);\n\n\tfree(*t);\n\t*t = prev ? prev : task_list;\n\treturn task_list;\n}\n\nstatic struct threads *liste_add_task(struct threads *task_list, struct threads *t,\n\tstruct threads **last)\n{\n\tt->next = NULL;\n\n\tif (!*last)\n\t\tif (!task_list) {\n\t\t\ttask_list = t;\n\t\t\treturn task_list;\n\t\t} else {\n\t\t\tstruct threads *temp = task_list;\n\n\t\t\twhile (temp->next)\n\t\t\t\ttemp = temp->next;\n\n\t\t\ttemp->next = t;\n\t\t\t*last = t;\n\t\t\treturn task_list;\n\t\t} else {\n\t\t(*last)->next = t;\n\t\t*last = t;\n\t\treturn task_list;\n\t}\n}\n\n#ifdef PID_CHECK\nstatic int current_pid(struct linux_os *linux_os, uint32_t pid)\n#else\nstatic int current_base_addr(struct linux_os *linux_os, uint32_t base_addr)\n#endif\n{\n\tstruct current_thread *ct = linux_os->current_threads;\n#ifdef PID_CHECK\n\n\twhile ((ct) && (ct->pid != pid))\n#else\n\twhile ((ct) && (ct->TS != base_addr))\n#endif\n\t\tct = ct->next;\n#ifdef PID_CHECK\n\tif ((ct) && (ct->pid == pid))\n#else\n\tif ((ct) && (ct->TS == base_addr))\n#endif\n\t\treturn 1;\n\n\treturn 0;\n}\n\nstatic int linux_get_tasks(struct target *target, int context)\n{\n\tint loop = 0;\n\tint retval = 0;\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tlinux_os->thread_list = NULL;\n\tlinux_os->thread_count = 0;\n\n\tif (linux_os->init_task_addr == 0xdeadbeef) {\n\t\tLOG_INFO(\"no init symbol\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint64_t start = timeval_ms();\n\n\tstruct threads *t = calloc(1, sizeof(struct threads));\n\tstruct threads *last = NULL;\n\tt->base_addr = linux_os->init_task_addr;\n\t/* retrieve the thread id , currently running in the different smp core */\n\tget_current(target, 1);\n\n\twhile (((t->base_addr != linux_os->init_task_addr) &&\n\t\t(t->base_addr != 0)) || (loop == 0)) {\n\t\tloop++;\n\t\tfill_task(target, t);\n\t\tretval = get_name(target, t);\n\n\t\tif (loop > MAX_THREADS) {\n\t\t\tfree(t);\n\t\t\tLOG_INFO(\"more than %d threads !!\", MAX_THREADS);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(t);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/*  check that this thread is not one the current threads already\n\t\t *  created */\n\t\tuint32_t base_addr;\n#ifdef PID_CHECK\n\n\t\tif (!current_pid(linux_os, t->pid)) {\n#else\n\t\tif (!current_base_addr(linux_os, t->base_addr)) {\n#endif\n\t\t\tt->threadid = linux_os->threadid_count;\n\t\t\tt->status = 1;\n\t\t\tlinux_os->threadid_count++;\n\n\t\t\tlinux_os->thread_list =\n\t\t\t\tliste_add_task(linux_os->thread_list, t, &last);\n\t\t\t/* no interest to fill the context if it is a current thread. */\n\t\t\tlinux_os->thread_count++;\n\t\t\tt->thread_info_addr = 0xdeadbeef;\n\n\t\t\tif (context)\n\t\t\t\tt->context =\n\t\t\t\t\tcpu_context_read(target, t->base_addr,\n\t\t\t\t\t\t&t->thread_info_addr);\n\t\t\tbase_addr = next_task(target, t);\n\t\t} else {\n\t\t\t/*LOG_INFO(\"thread %s is a current thread already created\",t->name); */\n\t\t\tbase_addr = next_task(target, t);\n\t\t\tfree(t);\n\t\t}\n\n\t\tt = calloc(1, sizeof(struct threads));\n\t\tt->base_addr = base_addr;\n\t}\n\n\tlinux_os->threads_lookup = 1;\n\tlinux_os->threads_needs_update = 0;\n\tlinux_os->preupdtate_threadid_count = linux_os->threadid_count - 1;\n\t/*  check that all current threads have been identified  */\n\n\tLOG_INFO(\"complete time %\" PRId64 \", thread mean %\" PRId64 \"\\n\",\n\t\t(timeval_ms() - start),\n\t\t(timeval_ms() - start) / linux_os->threadid_count);\n\n\tLOG_INFO(\"threadid count %d\", linux_os->threadid_count);\n\tfree(t);\n\n\treturn ERROR_OK;\n}\n\nstatic int clean_threadlist(struct target *target)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct threads *old, *temp = linux_os->thread_list;\n\n\twhile (temp) {\n\t\told = temp;\n\n\t\tfree(temp->context);\n\n\t\ttemp = temp->next;\n\t\tfree(old);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int linux_os_clean(struct target *target)\n{\n\tstruct linux_os *os_linux = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tclean_threadlist(target);\n\tos_linux->init_task_addr = 0xdeadbeef;\n\tos_linux->name = \"linux\";\n\tos_linux->thread_list = NULL;\n\tos_linux->thread_count = 0;\n\tos_linux->nr_cpus = 0;\n\tos_linux->threads_lookup = 0;\n\tos_linux->threads_needs_update = 0;\n\tos_linux->threadid_count = 1;\n\treturn ERROR_OK;\n}\n\nstatic int insert_into_threadlist(struct target *target, struct threads *t)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct threads *temp = linux_os->thread_list;\n\tt->threadid = linux_os->threadid_count;\n\tlinux_os->threadid_count++;\n\tt->status = 1;\n\tt->next = NULL;\n\n\tif (!temp)\n\t\tlinux_os->thread_list = t;\n\telse {\n\t\twhile (temp->next)\n\t\t\ttemp = temp->next;\n\n\t\tt->next = NULL;\n\t\ttemp->next = t;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void linux_identify_current_threads(struct target *target)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct threads *thread_list = linux_os->thread_list;\n\tstruct current_thread *ct = linux_os->current_threads;\n\tstruct threads *t = NULL;\n\n\twhile ((ct)) {\n\t\tif (ct->threadid == -1) {\n\n\t\t\t/*  un-identified thread */\n\t\t\tint found = 0;\n\t\t\tt = calloc(1, sizeof(struct threads));\n\t\t\tt->base_addr = ct->TS;\n#ifdef PID_CHECK\n\n\t\t\tif (fill_task_pid(target, t) != ERROR_OK) {\nerror_handling:\n\t\t\t\tfree(t);\n\t\t\t\tLOG_ERROR\n\t\t\t\t\t(\"linux identify_current_threads: unable to read pid\");\n\t\t\t\treturn;\n\t\t\t}\n#endif\n\n\t\t\t/* search in the list of threads if pid\n\t\t\t   already present */\n\t\t\twhile ((thread_list) && (found == 0)) {\n#ifdef PID_CHECK\n\t\t\t\tif (thread_list->pid == t->pid) {\n#else\n\t\t\t\tif (thread_list->base_addr == t->base_addr) {\n#endif\n\t\t\t\t\tfree(t);\n\t\t\t\t\tt = thread_list;\n\t\t\t\t\tfound = 1;\n\t\t\t\t}\n\t\t\t\tthread_list = thread_list->next;\n\t\t\t}\n\n\t\t\tif (!found) {\n\t\t\t\t/*  it is a new thread */\n\t\t\t\tif (fill_task(target, t) != ERROR_OK)\n\t\t\t\t\tgoto error_handling;\n\n\t\t\t\tget_name(target, t);\n\t\t\t\tinsert_into_threadlist(target, t);\n\t\t\t\tt->thread_info_addr = 0xdeadbeef;\n\t\t\t}\n\n\t\t\tt->status = 3;\n\t\t\tct->threadid = t->threadid;\n#ifdef PID_CHECK\n\t\t\tct->pid = t->pid;\n#endif\n\t\t\tlinux_os->thread_count++;\n#if 0\n\t\t\tif (found == 0)\n\t\t\t\tLOG_INFO(\"current thread core %x identified %s\",\n\t\t\t\t\tct->core_id, t->name);\n\t\t\telse\n\t\t\t\tLOG_INFO(\"current thread core %x, reused %s\",\n\t\t\t\t\tct->core_id, t->name);\n#endif\n\t\t}\n#if 0\n\t\telse {\n\t\t\tstruct threads tmp;\n\t\t\ttmp.base_addr = ct->TS;\n\t\t\tget_name(target, &tmp);\n\t\t\tLOG_INFO(\"current thread core %x , already identified %s !!!\",\n\t\t\t\tct->core_id, tmp.name);\n\t\t}\n#endif\n\t\tct = ct->next;\n\t}\n\n\treturn;\n#ifndef PID_CHECK\nerror_handling:\n\tfree(t);\n\tLOG_ERROR(\"unable to read pid\");\n\treturn;\n\n#endif\n}\n\nstatic int linux_task_update(struct target *target, int context)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct threads *thread_list = linux_os->thread_list;\n\tint retval;\n\tint loop = 0;\n\tlinux_os->thread_count = 0;\n\n\t/*thread_list = thread_list->next; skip init_task*/\n\twhile (thread_list) {\n\t\tthread_list->status = 0;\t/*setting all tasks to dead state*/\n\n\t\tfree(thread_list->context);\n\t\tthread_list->context = NULL;\n\n\t\tthread_list = thread_list->next;\n\t}\n\n\tint found = 0;\n\n\tif (linux_os->init_task_addr == 0xdeadbeef) {\n\t\tLOG_INFO(\"no init symbol\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint64_t start = timeval_ms();\n\tstruct threads *t = calloc(1, sizeof(struct threads));\n\tuint32_t previous = 0xdeadbeef;\n\tt->base_addr = linux_os->init_task_addr;\n\tretval = get_current(target, 0);\n\t/*check that all current threads have been identified  */\n\tlinux_identify_current_threads(target);\n\n\twhile (((t->base_addr != linux_os->init_task_addr) &&\n\t\t(t->base_addr != previous)) || (loop == 0)) {\n\t\t/*  for avoiding any permanent loop for any reason possibly due to\n\t\t *  target */\n\t\tloop++;\n\t\tprevious = t->base_addr;\n\t\t/*  read only pid */\n#ifdef PID_CHECK\n\t\tretval = fill_task_pid(target, t);\n#endif\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(t);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tthread_list = linux_os->thread_list;\n\n\t\twhile (thread_list) {\n#ifdef PID_CHECK\n\t\t\tif (t->pid == thread_list->pid) {\n#else\n\t\t\tif (t->base_addr == thread_list->base_addr) {\n#endif\n\t\t\t\tif (!thread_list->status) {\n#ifdef PID_CHECK\n\t\t\t\t\tif (t->base_addr != thread_list->base_addr)\n\t\t\t\t\t\tLOG_INFO(\"thread base_addr has changed !!\");\n#endif\n\t\t\t\t\t/*  this is not a current thread  */\n\t\t\t\t\tthread_list->base_addr = t->base_addr;\n\t\t\t\t\tthread_list->status = 1;\n\n\t\t\t\t\t/*  we don 't update this field any more */\n\n\t\t\t\t\t/*thread_list->state = t->state;\n\t\t\t\t\tthread_list->oncpu = t->oncpu;\n\t\t\t\t\tthread_list->asid = t->asid;\n\t\t\t\t\t*/\n\t\t\t\t\tif (context)\n\t\t\t\t\t\tthread_list->context =\n\t\t\t\t\t\t\tcpu_context_read(target,\n\t\t\t\t\t\t\t\tthread_list->base_addr,\n\t\t\t\t\t\t\t\t&thread_list->thread_info_addr);\n\t\t\t\t} else {\n\t\t\t\t\t/*  it is a current thread no need to read context */\n\t\t\t\t}\n\n\t\t\t\tlinux_os->thread_count++;\n\t\t\t\tfound = 1;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tfound = 0;\n\t\t\t\tthread_list = thread_list->next;\n\t\t\t}\n\t\t}\n\n\t\tif (found == 0) {\n\t\t\tuint32_t base_addr;\n\t\t\tfill_task(target, t);\n\t\t\tget_name(target, t);\n\t\t\tretval = insert_into_threadlist(target, t);\n\t\t\tt->thread_info_addr = 0xdeadbeef;\n\n\t\t\tif (context)\n\t\t\t\tt->context =\n\t\t\t\t\tcpu_context_read(target, t->base_addr,\n\t\t\t\t\t\t&t->thread_info_addr);\n\n\t\t\tbase_addr = next_task(target, t);\n\t\t\tt = calloc(1, sizeof(struct threads));\n\t\t\tt->base_addr = base_addr;\n\t\t\tlinux_os->thread_count++;\n\t\t} else\n\t\t\tt->base_addr = next_task(target, t);\n\t}\n\n\tLOG_INFO(\"update thread done %\" PRId64 \", mean%\" PRId64 \"\\n\",\n\t\t(timeval_ms() - start), (timeval_ms() - start) / loop);\n\tfree(t);\n\tlinux_os->threads_needs_update = 0;\n\treturn ERROR_OK;\n}\n\nstatic int linux_gdb_thread_packet(struct target *target,\n\tstruct connection *connection, char const *packet,\n\tint packet_size)\n{\n\tint retval;\n\tstruct linux_os *linux_os =\n\t\t(struct linux_os *)target->rtos->rtos_specific_params;\n\n\tif (linux_os->init_task_addr == 0xdeadbeef) {\n\t\t/* it has not been initialized */\n\t\tLOG_INFO(\"received thread request without init task address\");\n\t\tgdb_put_packet(connection, \"l\", 1);\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = linux_get_tasks(target, 1);\n\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_TARGET_FAILURE;\n\n\tchar *out_str = calloc(MAX_THREADS * 17 + 10, 1);\n\tchar *tmp_str = out_str;\n\ttmp_str += sprintf(tmp_str, \"m\");\n\tstruct threads *temp = linux_os->thread_list;\n\n\twhile (temp) {\n\t\ttmp_str += sprintf(tmp_str, \"%016\" PRIx64, temp->threadid);\n\t\ttemp = temp->next;\n\t\tif (temp)\n\t\t\ttmp_str += sprintf(tmp_str, \",\");\n\t}\n\n\tgdb_put_packet(connection, out_str, strlen(out_str));\n\tfree(out_str);\n\treturn ERROR_OK;\n}\n\nstatic int linux_gdb_thread_update(struct target *target,\n\tstruct connection *connection, char const *packet,\n\tint packet_size)\n{\n\tint found = 0;\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct threads *temp = linux_os->thread_list;\n\n\twhile (temp) {\n\t\tif (temp->threadid == linux_os->preupdtate_threadid_count + 1) {\n\t\t\t/*LOG_INFO(\"FOUND\");*/\n\t\t\tfound = 1;\n\t\t\tbreak;\n\t\t} else\n\t\t\ttemp = temp->next;\n\t}\n\n\tif (found == 1) {\n\t\t/*LOG_INFO(\"INTO GDB THREAD UPDATE FOUNDING START TASK\");*/\n\t\tchar *out_strr = calloc(MAX_THREADS * 17 + 10, 1);\n\t\tchar *tmp_strr = out_strr;\n\t\ttmp_strr += sprintf(tmp_strr, \"m\");\n\t\t/*LOG_INFO(\"CHAR MALLOC & M DONE\");*/\n\t\ttmp_strr += sprintf(tmp_strr, \"%016\" PRIx64, temp->threadid);\n\n\t\ttemp = temp->next;\n\n\t\twhile (temp) {\n\t\t\t/*LOG_INFO(\"INTO GDB THREAD UPDATE WHILE\");*/\n\t\t\ttmp_strr += sprintf(tmp_strr, \",\");\n\t\t\ttmp_strr +=\n\t\t\t\tsprintf(tmp_strr, \"%016\" PRIx64, temp->threadid);\n\t\t\ttemp = temp->next;\n\t\t}\n\n\t\t/*tmp_str[0] = 0;*/\n\t\tgdb_put_packet(connection, out_strr, strlen(out_strr));\n\t\tlinux_os->preupdtate_threadid_count =\n\t\t\tlinux_os->threadid_count - 1;\n\t\tfree(out_strr);\n\t} else\n\t\tgdb_put_packet(connection, \"l\", 1);\n\n\treturn ERROR_OK;\n}\n\nstatic int linux_thread_extra_info(struct target *target,\n\tstruct connection *connection, char const *packet,\n\tint packet_size)\n{\n\tint64_t threadid = 0;\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tsscanf(packet, \"qThreadExtraInfo,%\" SCNx64, &threadid);\n\t/*LOG_INFO(\"lookup extra info for thread %\" SCNx64, threadid);*/\n\tstruct threads *temp = linux_os->thread_list;\n\n\twhile (temp) {\n\t\tif (temp->threadid == threadid) {\n\t\t\tchar *pid = \" PID: \";\n\t\t\tchar *pid_current = \"*PID: \";\n\t\t\tchar *name = \"Name: \";\n\t\t\tint str_size = strlen(pid) + strlen(name);\n\t\t\tchar *tmp_str = calloc(1, str_size + 50);\n\t\t\tchar *tmp_str_ptr = tmp_str;\n\n\t\t\t/*  discriminate current task */\n\t\t\tif (temp->status == 3)\n\t\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \"%s\",\n\t\t\t\t\t\tpid_current);\n\t\t\telse\n\t\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \"%s\", pid);\n\n\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \"%d, \", (int)temp->pid);\n\t\t\tsprintf(tmp_str_ptr, \"%s\", name);\n\t\t\tsprintf(tmp_str_ptr, \"%s\", temp->name);\n\t\t\tchar *hex_str = calloc(1, strlen(tmp_str) * 2 + 1);\n\t\t\tsize_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,\n\t\t\t\tstrlen(tmp_str), strlen(tmp_str) * 2 + 1);\n\t\t\tgdb_put_packet(connection, hex_str, pkt_len);\n\t\t\tfree(hex_str);\n\t\t\tfree(tmp_str);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\ttemp = temp->next;\n\t}\n\n\tLOG_INFO(\"thread not found\");\n\treturn ERROR_OK;\n}\n\nstatic int linux_gdb_t_packet(struct connection *connection,\n\tstruct target *target, char const *packet, int packet_size)\n{\n\tint64_t threadid;\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tint retval = ERROR_OK;\n\tsscanf(packet, \"T%\" SCNx64, &threadid);\n\n\tif (linux_os->threads_needs_update == 0) {\n\t\tstruct threads *temp = linux_os->thread_list;\n\t\tstruct threads *prev = NULL;\n\n\t\twhile (temp) {\n\t\t\tif (temp->threadid == threadid) {\n\t\t\t\tif (temp->status != 0) {\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t} else {\n\t\t\t\t\t/* delete item in the list   */\n\t\t\t\t\tlinux_os->thread_list =\n\t\t\t\t\t\tliste_del_task(linux_os->thread_list,\n\t\t\t\t\t\t\t&temp, prev);\n\t\t\t\t\tlinux_os->thread_count--;\n\t\t\t\t\tgdb_put_packet(connection, \"E01\", 3);\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*  for deletion  */\n\t\t\tprev = temp;\n\t\t\ttemp = temp->next;\n\t\t}\n\n\t\tLOG_INFO(\"gdb requested status on non existing thread\");\n\t\tgdb_put_packet(connection, \"E01\", 3);\n\t\treturn ERROR_OK;\n\n\t} else {\n\t\tretval = linux_task_update(target, 1);\n\t\tstruct threads *temp = linux_os->thread_list;\n\n\t\twhile (temp) {\n\t\t\tif (temp->threadid == threadid) {\n\t\t\t\tif (temp->status == 1) {\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t} else {\n\t\t\t\t\tgdb_put_packet(connection, \"E01\", 3);\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttemp = temp->next;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int linux_gdb_h_packet(struct connection *connection,\n\tstruct target *target, char const *packet, int packet_size)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tstruct current_thread *ct = linux_os->current_threads;\n\n\t/* select to display the current thread of the selected target */\n\twhile ((ct) && (ct->core_id != target->coreid))\n\t\tct = ct->next;\n\n\tint64_t current_gdb_thread_rq;\n\n\tif (linux_os->threads_lookup == 1) {\n\t\tif ((ct) && (ct->threadid == -1)) {\n\t\t\tct = linux_os->current_threads;\n\n\t\t\twhile ((ct) && (ct->threadid == -1))\n\t\t\t\tct = ct->next;\n\t\t}\n\n\t\tif (!ct) {\n\t\t\t/*  no current thread can be identified\n\t\t\t *  any way with smp  */\n\t\t\tLOG_INFO(\"no current thread identified\");\n\t\t\t/* attempt to display the name of the 2 threads identified with\n\t\t\t * get_current */\n\t\t\tstruct threads t;\n\t\t\tct = linux_os->current_threads;\n\n\t\t\twhile ((ct) && (ct->threadid == -1)) {\n\t\t\t\tt.base_addr = ct->TS;\n\t\t\t\tget_name(target, &t);\n\t\t\t\tLOG_INFO(\"name of unidentified thread %s\",\n\t\t\t\t\tt.name);\n\t\t\t\tct = ct->next;\n\t\t\t}\n\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tif (packet[1] == 'g') {\n\t\t\tsscanf(packet, \"Hg%16\" SCNx64, &current_gdb_thread_rq);\n\n\t\t\tif (current_gdb_thread_rq == 0) {\n\t\t\t\ttarget->rtos->current_threadid = ct->threadid;\n\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t} else {\n\t\t\t\ttarget->rtos->current_threadid =\n\t\t\t\t\tcurrent_gdb_thread_rq;\n\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t}\n\t\t} else if (packet[1] == 'c') {\n\t\t\tsscanf(packet, \"Hc%16\" SCNx64, &current_gdb_thread_rq);\n\n\t\t\tif ((current_gdb_thread_rq == 0) ||\n\t\t\t\t\t(current_gdb_thread_rq == ct->threadid)) {\n\t\t\t\ttarget->rtos->current_threadid = ct->threadid;\n\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t} else\n\t\t\t\tgdb_put_packet(connection, \"E01\", 3);\n\t\t}\n\t} else\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\n\treturn ERROR_OK;\n}\n\nstatic int linux_thread_packet(struct connection *connection, char const *packet,\n\tint packet_size)\n{\n\tint retval = ERROR_OK;\n\tstruct current_thread *ct;\n\tstruct target *target = get_target_from_connection(connection);\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\n\tswitch (packet[0]) {\n\t\tcase 'T':\t\t/* Is thread alive?*/\n\n\t\t\tlinux_gdb_t_packet(connection, target, packet, packet_size);\n\t\t\tbreak;\n\t\tcase 'H':\t\t/* Set current thread */\n\t\t\t/*  ( 'c' for step and continue, 'g' for all other operations )*/\n\t\t\t/*LOG_INFO(\" H packet received '%s'\", packet);*/\n\t\t\tlinux_gdb_h_packet(connection, target, packet, packet_size);\n\t\t\tbreak;\n\t\tcase 'q':\n\n\t\t\tif (strncmp(packet, \"qSymbol\", 7) == 0) {\n\t\t\t\tif (rtos_qsymbol(connection, packet, packet_size) == 1) {\n\t\t\t\t\tlinux_compute_virt2phys(target,\n\t\t\t\t\t\t\ttarget->rtos->symbols[INIT_TASK].address);\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t} else if (strncmp(packet, \"qfThreadInfo\", 12) == 0) {\n\t\t\t\tif (!linux_os->thread_list) {\n\t\t\t\t\tretval = linux_gdb_thread_packet(target,\n\t\t\t\t\t\t\tconnection,\n\t\t\t\t\t\t\tpacket,\n\t\t\t\t\t\t\tpacket_size);\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tretval = linux_gdb_thread_update(target,\n\t\t\t\t\t\t\tconnection,\n\t\t\t\t\t\t\tpacket,\n\t\t\t\t\t\t\tpacket_size);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else if (strncmp(packet, \"qsThreadInfo\", 12) == 0) {\n\t\t\t\tgdb_put_packet(connection, \"l\", 1);\n\t\t\t\tbreak;\n\t\t\t} else if (strncmp(packet, \"qThreadExtraInfo,\", 17) == 0) {\n\t\t\t\tlinux_thread_extra_info(target, connection, packet,\n\t\t\t\t\t\tpacket_size);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tretval = GDB_THREAD_PACKET_NOT_CONSUMED;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tcase 'Q':\n\t\t\t/* previously response was : thread not found\n\t\t\t * gdb_put_packet(connection, \"E01\", 3); */\n\t\t\tretval = GDB_THREAD_PACKET_NOT_CONSUMED;\n\t\t\tbreak;\n\t\tcase 'c':\n\t\tcase 's': {\n\t\t\tif (linux_os->threads_lookup == 1) {\n\t\t\t\tct = linux_os->current_threads;\n\n\t\t\t\twhile ((ct) && (ct->core_id) != target->coreid)\n\t\t\t\t\tct = ct->next;\n\n\t\t\t\tif ((ct) && (ct->threadid == -1)) {\n\t\t\t\t\tct = linux_os->current_threads;\n\n\t\t\t\t\twhile ((ct) && (ct->threadid == -1))\n\t\t\t\t\t\tct = ct->next;\n\t\t\t\t}\n\n\t\t\t\tif ((ct) && (ct->threadid !=\n\t\t\t\t\t\t target->rtos->current_threadid)\n\t\t\t\t&& (target->rtos->current_threadid != -1))\n\t\t\t\t\tLOG_WARNING(\"WARNING! current GDB thread do not match \"\n\t\t\t\t\t\t\t\"current thread running. \"\n\t\t\t\t\t\t\t\"Switch thread in GDB to threadid %d\",\n\t\t\t\t\t\t\t(int)ct->threadid);\n\n\t\t\t\tLOG_INFO(\"threads_needs_update = 1\");\n\t\t\t\tlinux_os->threads_needs_update = 1;\n\t\t\t}\n\t\t}\n\n\t\t/* if a packet handler returned an error, exit input loop */\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int linux_os_smp_init(struct target *target)\n{\n\tstruct target_list *head;\n\t/* keep only target->rtos */\n\tstruct rtos *rtos = target->rtos;\n\tstruct linux_os *os_linux =\n\t\t(struct linux_os *)rtos->rtos_specific_params;\n\tstruct current_thread *ct;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tif (head->target->rtos != rtos) {\n\t\t\tstruct linux_os *smp_os_linux =\n\t\t\t\t(struct linux_os *)head->target->rtos->rtos_specific_params;\n\t\t\t/*  remap smp target on rtos  */\n\t\t\tfree(head->target->rtos);\n\t\t\thead->target->rtos = rtos;\n\t\t\t/*  reuse allocated ct */\n\t\t\tct = smp_os_linux->current_threads;\n\t\t\tct->threadid = -1;\n\t\t\tct->TS = 0xdeadbeef;\n\t\t\tct->core_id = head->target->coreid;\n\t\t\tos_linux->current_threads =\n\t\t\t\tadd_current_thread(os_linux->current_threads, ct);\n\t\t\tos_linux->nr_cpus++;\n\t\t\tfree(smp_os_linux);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int linux_os_create(struct target *target)\n{\n\tstruct linux_os *os_linux = calloc(1, sizeof(struct linux_os));\n\tstruct current_thread *ct = calloc(1, sizeof(struct current_thread));\n\tLOG_INFO(\"linux os creation\\n\");\n\tos_linux->init_task_addr = 0xdeadbeef;\n\tos_linux->name = \"linux\";\n\tos_linux->thread_list = NULL;\n\tos_linux->thread_count = 0;\n\ttarget->rtos->current_threadid = -1;\n\tos_linux->nr_cpus = 1;\n\tos_linux->threads_lookup = 0;\n\tos_linux->threads_needs_update = 0;\n\tos_linux->threadid_count = 1;\n\tos_linux->current_threads = NULL;\n\ttarget->rtos->rtos_specific_params = os_linux;\n\tct->core_id = target->coreid;\n\tct->threadid = -1;\n\tct->TS = 0xdeadbeef;\n\tos_linux->current_threads =\n\t\tadd_current_thread(os_linux->current_threads, ct);\n\t/*  overload rtos thread default handler */\n\ttarget->rtos->gdb_thread_packet = linux_thread_packet;\n\t/*  initialize a default virt 2 phys translation */\n\tos_linux->phys_mask = ~0xc0000000;\n\tos_linux->phys_base = 0x0;\n\treturn JIM_OK;\n}\n\nstatic char *linux_ps_command(struct target *target)\n{\n\tstruct linux_os *linux_os = (struct linux_os *)\n\t\ttarget->rtos->rtos_specific_params;\n\tint retval = ERROR_OK;\n\tchar *display;\n\n\tif (linux_os->threads_lookup == 0)\n\t\tretval = linux_get_tasks(target, 1);\n\telse {\n\t\tif (linux_os->threads_needs_update != 0)\n\t\t\tretval = linux_task_update(target, 0);\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\tstruct threads *temp = linux_os->thread_list;\n\t\tchar *tmp;\n\t\tLOG_INFO(\"allocation for %d threads line\",\n\t\t\tlinux_os->thread_count);\n\t\tdisplay = calloc((linux_os->thread_count + 2) * 80, 1);\n\n\t\tif (!display)\n\t\t\tgoto error;\n\n\t\ttmp = display;\n\t\ttmp += sprintf(tmp, \"PID\\t\\tCPU\\t\\tASID\\t\\tNAME\\n\");\n\t\ttmp += sprintf(tmp, \"---\\t\\t---\\t\\t----\\t\\t----\\n\");\n\n\t\twhile (temp) {\n\t\t\tif (temp->status) {\n\t\t\t\tif (temp->context)\n\t\t\t\t\ttmp +=\n\t\t\t\t\t\tsprintf(tmp,\n\t\t\t\t\t\t\t\"%\" PRIu32 \"\\t\\t%\" PRIu32 \"\\t\\t%\" PRIx32 \"\\t\\t%s\\n\",\n\t\t\t\t\t\t\ttemp->pid, temp->oncpu,\n\t\t\t\t\t\t\ttemp->asid, temp->name);\n\t\t\t\telse\n\t\t\t\t\ttmp +=\n\t\t\t\t\t\tsprintf(tmp,\n\t\t\t\t\t\t\t\"%\" PRIu32 \"\\t\\t%\" PRIu32 \"\\t\\t%\" PRIx32 \"\\t\\t%s\\n\",\n\t\t\t\t\t\t\ttemp->pid, temp->oncpu,\n\t\t\t\t\t\t\ttemp->asid, temp->name);\n\t\t\t}\n\n\t\t\ttemp = temp->next;\n\t\t}\n\n\t\treturn display;\n\t}\n\nerror:\n\tdisplay = calloc(40, 1);\n\tsprintf(display, \"linux_ps_command failed\\n\");\n\treturn display;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/linux_header.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_RTOS_LINUX_HEADER_H\n#define OPENOCD_RTOS_LINUX_HEADER_H\n\n/*  gdb script to update the header file\n  according to kernel version and build option\n  before executing function awareness\n  kernel symbol must be loaded : symbol vmlinux\n\ndefine awareness\n set logging off\n set logging file linux_header.h\n set logging on\n\n printf \"#define QAT %p\\n\",&((struct task_struct *)(0))->stack\n set $a=&((struct list_head *)(0))->next\n set $a=(int)$a+(int)&((struct task_struct *)(0))->tasks\n printf \"#define NEXT  %p\\n\",$a\n printf \"#define COMM  %p\\n\",&((struct task_struct *)(0))->comm\n printf \"#define MEM  %p\\n\",&((struct task_struct *)(0))->mm\n printf \"#define ONCPU %p\\n\",&((struct task_struct *)(0))->on_cpu\n printf \"#define PID %p\\n\",&((struct task_struct *)(0))->pid\n printf \"#define CPU_CONT %p\\n\",&((struct thread_info *)(0))->cpu_context\n printf \"#define PREEMPT %p\\n\",&((struct thread_info *)(0))->preempt_count\n printf \"#define MM_CTX %p\\n\",&((struct mm_struct *)(0))->context\n end\n*/\n#define QAT 0x4\n#define NEXT  0x1b0\n#define COMM  0x2d4\n#define MEM  0x1cc\n#define ONCPU 0x18\n#define PID 0x1f4\n#define CPU_CONT 0x1c\n#define PREEMPT 0x4\n#define MM_CTX 0x160\n\n#endif /* OPENOCD_RTOS_LINUX_HEADER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/mqx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2014 by Marian Cingel                                   *\n *   cingel.marian@gmail.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_mqx_stackings.h\"\n\n/* constants */\n#define MQX_THREAD_NAME_LENGTH\t\t\t(255)\n#define MQX_KERNEL_OFFSET_TDLIST\t\t(0x0108)\n#define MQX_KERNEL_OFFSET_SYSTEM_TASK\t(0x0050)\n#define MQX_KERNEL_OFFSET_ACTIVE_TASK\t(0x001C)\n#define MQX_KERNEL_OFFSET_CAPABILITY\t(0x0000)\n#define MQX_QUEUE_OFFSET_SIZE\t\t\t(0x0008)\n#define MQX_TASK_OFFSET_STATE\t\t\t(0x0008)\n#define MQX_TASK_OFFSET_ID\t\t\t\t(0x000c)\n#define MQX_TASK_OFFSET_TEMPLATE\t\t(0x0068)\n#define MQX_TASK_OFFSET_STACK\t\t\t(0x0014)\n#define MQX_TASK_OFFSET_TDLIST\t\t\t(0x006C)\n#define MQX_TASK_OFFSET_NEXT\t\t\t(0x0000)\n#define MQX_TASK_TEMPLATE_OFFSET_NAME\t(0x0010)\n#define MQX_TASK_OFFSET_ERROR_CODE\t\t(0x005C)\n#define MQX_TASK_STATE_MASK\t\t\t\t(0xFFF)\n\n/* types */\nenum mqx_symbols {\n\tMQX_VAL_MQX_KERNEL_DATA,\n\tMQX_VAL_MQX_INIT_STRUCT,\n};\n\nenum mqx_arch {\n\tmqx_arch_cortexm,\n};\n\nstruct mqx_params {\n\tconst char *target_name;\n\tconst enum mqx_arch target_arch;\n\tconst struct rtos_register_stacking *stacking_info;\n};\n\nstruct mqx_state {\n\tuint32_t state;\n\tchar *name;\n};\n\n/* local data */\nstatic const struct mqx_state mqx_states[] = {\n\t{ 0x0002, \"READY\" },\n\t{ 0x0003, \"BLOCKED\" },\n\t{ 0x0005, \"RCV_SPECIFIC_BLOCKED\" },\n\t{ 0x0007, \"RCV_ANY_BLOCKED\" },\n\t{ 0x0009, \"DYING\" },\n\t{ 0x000B, \"UNHANDLED_INT_BLOCKED\" },\n\t{ 0x000D, \"SEND_BLOCKED\" },\n\t{ 0x000F, \"BREAKPOINT_BLOCKED\" },\n\t{ 0x0211, \"IO_BLOCKED\" },\n\t{ 0x0021, \"SEM_BLOCKED\" },\n\t{ 0x0223, \"MUTEX_BLOCKED\" },\n\t{ 0x0025, \"EVENT_BLOCKED\" },\n\t{ 0x0229, \"TASK_QUEUE_BLOCKED\" },\n\t{ 0x042B, \"LWSEM_BLOCKED\" },\n\t{ 0x042D, \"LWEVENT_BLOCKED\" },\n};\n\nstatic const char * const mqx_symbol_list[] = {\n\t\"_mqx_kernel_data\",\n\t\"MQX_init_struct\",\n\tNULL\n};\n\nstatic const struct mqx_params mqx_params_list[] = {\n\t{ \"cortex_m\", mqx_arch_cortexm, &rtos_mqx_arm_v7m_stacking },\n};\n\n/*\n * Perform simple address check to avoid bus fault.\n */\nstatic int mqx_valid_address_check(\n\tstruct rtos *rtos,\n\tuint32_t address\n)\n{\n\tenum mqx_arch arch_type = ((struct mqx_params *)rtos->rtos_specific_params)->target_arch;\n\tconst char *targetname = ((struct mqx_params *)rtos->rtos_specific_params)->target_name;\n\n\t/* Cortex-M address range */\n\tif (arch_type == mqx_arch_cortexm) {\n\t\tif (\n\t\t\t/* code and sram area */\n\t\t\t(address && address <= 0x3FFFFFFFu) ||\n\t\t\t/* external ram area*/\n\t\t\t(address >= 0x6000000u && address <= 0x9FFFFFFFu)\n\t\t) {\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_ERROR(\"MQX RTOS - unknown architecture %s\", targetname);\n\treturn ERROR_FAIL;\n}\n\n/*\n * Wrapper of 'target_read_buffer' fn.\n * Include address check.\n */\nstatic int mqx_target_read_buffer(\n\tstruct target *target,\n\tuint32_t address,\n\tuint32_t size,\n\tuint8_t *buffer\n)\n{\n\tint status = mqx_valid_address_check(target->rtos, address);\n\tif (status != ERROR_OK) {\n\t\tLOG_WARNING(\"MQX RTOS - target address 0x%\" PRIx32 \" is not allowed to read\", address);\n\t\treturn status;\n\t}\n\tstatus = target_read_buffer(target, address, size, buffer);\n\tif (status != ERROR_OK) {\n\t\tLOG_ERROR(\"MQX RTOS - reading target address 0x%\" PRIx32\" failed\", address);\n\t\treturn status;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * Get symbol address if present\n */\nstatic int mqx_get_symbol(\n\tstruct rtos *rtos,\n\tenum mqx_symbols symbol,\n\tvoid *result\n)\n{\n\t/* TODO: additional check ?? */\n\t(*(int *)result) = (uint32_t)rtos->symbols[symbol].address;\n\treturn ERROR_OK;\n}\n\n/*\n * Get value of struct member by passing\n * member offset, width and name (debug purpose)\n */\nstatic int mqx_get_member(\n\tstruct rtos *rtos,\n\tconst uint32_t base_address,\n\tint32_t member_offset,\n\tint32_t member_width,\n\tconst char *member_name,\n\tvoid *result\n)\n{\n\tint status = ERROR_FAIL;\n\tstatus = mqx_target_read_buffer(\n\t\trtos->target, base_address + member_offset, member_width, result\n\t);\n\tif (status != ERROR_OK)\n\t\tLOG_WARNING(\"MQX RTOS - cannot read \\\"%s\\\" at address 0x%\" PRIx32,\n\t\t\t    member_name, (uint32_t)(base_address + member_offset));\n\treturn status;\n}\n\n/*\n * Check whether scheduler started\n */\nstatic int mqx_is_scheduler_running(\n\tstruct rtos *rtos\n)\n{\n\tuint32_t kernel_data_symbol = 0;\n\tuint32_t kernel_data_addr = 0;\n\tuint32_t system_td_addr = 0;\n\tuint32_t active_td_addr = 0;\n\tuint32_t capability_value = 0;\n\n\t/* get '_mqx_kernel_data' symbol */\n\tif (mqx_get_symbol(rtos, MQX_VAL_MQX_KERNEL_DATA, &kernel_data_symbol) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* get '_mqx_kernel_data' */\n\tif (mqx_get_member(rtos, kernel_data_symbol, 0, 4,\n\t\t\"_mqx_kernel_data\", &kernel_data_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* return if '_mqx_kernel_data' is NULL or default 0xFFFFFFFF */\n\tif (kernel_data_addr == 0 || kernel_data_addr == (uint32_t)(-1))\n\t\treturn ERROR_FAIL;\n\t/* get kernel_data->ADDRESSING_CAPABILITY */\n\tif (mqx_get_member(rtos, kernel_data_addr, MQX_KERNEL_OFFSET_CAPABILITY, 4,\n\t\t\"kernel_data->ADDRESSING_CAPABILITY\", (void *)&capability_value) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* check first member, the '_mqx_kernel_data->ADDRESSING_CAPABILITY'.\n\t   it suppose to be set to value 8 */\n\tif (capability_value != 8) {\n\t\tLOG_WARNING(\"MQX RTOS - value of '_mqx_kernel_data->ADDRESSING_CAPABILITY' contains invalid value\");\n\t\treturn ERROR_FAIL;\n\t}\n\t/* get active ptr */\n\tif (mqx_get_member(rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4,\n\t\t\"kernel_data->ACTIVE_PTR\", (void *)&active_td_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* active task is system task, scheduler has not not run yet */\n\tsystem_td_addr = kernel_data_addr + MQX_KERNEL_OFFSET_SYSTEM_TASK;\n\tif (active_td_addr == system_td_addr) {\n\t\tLOG_WARNING(\"MQX RTOS - scheduler does not run\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * API function, return true if MQX is present\n */\nstatic bool mqx_detect_rtos(\n\tstruct target *target\n)\n{\n\tif (\n\t\t(target->rtos->symbols) &&\n\t\t(target->rtos->symbols[MQX_VAL_MQX_KERNEL_DATA].address != 0)\n\t) {\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n/*\n * API function, pass MQX extra info to context data\n */\nstatic int mqx_create(\n\tstruct target *target\n)\n{\n\t/* check target name against supported architectures */\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(mqx_params_list); i++) {\n\t\tif (strcmp(mqx_params_list[i].target_name, target->type->name) == 0) {\n\t\t\ttarget->rtos->rtos_specific_params = (void *)&mqx_params_list[i];\n\t\t\t/* LOG_DEBUG(\"MQX RTOS - valid architecture: %s\", target->type->name); */\n\t\t\treturn 0;\n\t\t}\n\t}\n\tLOG_ERROR(\"MQX RTOS - could not find target \\\"%s\\\" in MQX compatibility list\", target->type->name);\n\treturn -1;\n}\n\n/*\n * API function, update list of threads\n */\nstatic int mqx_update_threads(\n\tstruct rtos *rtos\n)\n{\n\tuint32_t task_queue_addr = 0;\n\tuint32_t kernel_data_addr = 0;\n\tuint16_t task_queue_size = 0;\n\tuint32_t active_td_addr = 0;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -3;\n\n\tif (!rtos->symbols)\n\t\treturn -4;\n\n\t/* clear old data */\n\trtos_free_threadlist(rtos);\n\t/* check scheduler */\n\tif (mqx_is_scheduler_running(rtos) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t/* get kernel_data symbol */\n\tif (mqx_get_symbol(rtos, MQX_VAL_MQX_KERNEL_DATA, &kernel_data_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* read kernel_data */\n\tif (mqx_get_member(rtos, kernel_data_addr, 0, 4,\n\t\t\"_mqx_kernel_data\", &kernel_data_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* get task queue address */\n\ttask_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST;\n\t/* get task queue size */\n\tif (mqx_get_member(rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2,\n\t\t\"kernel_data->TD_LIST.SIZE\", &task_queue_size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* get active ptr */\n\tif (mqx_get_member(rtos, kernel_data_addr, MQX_KERNEL_OFFSET_ACTIVE_TASK, 4,\n\t\t\"kernel_data->ACTIVE_PTR\", (void *)&active_td_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* setup threads info */\n\trtos->thread_count = task_queue_size;\n\trtos->current_thread = 0;\n\trtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail));\n\tif (!rtos->thread_details)\n\t\treturn ERROR_FAIL;\n\n\t/*\tloop over each task and setup thread details,\n\t\tthe current_taskpool_addr is set to queue head\n\t\tNOTE: debugging functions task create/destroy\n\t\tmight cause to show invalid data.\n\t*/\n\tfor (\n\t\tuint32_t i = 0, taskpool_addr = task_queue_addr;\n\t\ti < (uint32_t)rtos->thread_count;\n\t\ti++\n\t) {\n\t\tuint8_t task_name[MQX_THREAD_NAME_LENGTH + 1];\n\t\tuint32_t task_addr = 0, task_template = 0, task_state = 0;\n\t\tuint32_t task_name_addr = 0, task_id = 0, task_errno = 0;\n\t\tuint32_t state_index = 0;\n\t\tuint32_t extra_info_length = 0;\n\t\tchar *state_name = \"Unknown\";\n\n\t\t/* set current taskpool address */\n\t\tif (mqx_get_member(rtos, taskpool_addr, MQX_TASK_OFFSET_NEXT, 4,\n\t\t\t\"td_struct_ptr->NEXT\", &taskpool_addr) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get task address from taskpool */\n\t\ttask_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST;\n\t\t/* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR' */\n\t\tif (mqx_get_member(rtos, task_addr, MQX_TASK_OFFSET_TEMPLATE, 4,\n\t\t\t\"td_struct_ptr->TEMPLATE_LIST_PTR\", &task_template) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get address of 'td_struct_ptr->TEMPLATE_LIST_PTR->NAME' */\n\t\tif (mqx_get_member(rtos, task_template, MQX_TASK_TEMPLATE_OFFSET_NAME, 4,\n\t\t\t\"td_struct_ptr->TEMPLATE_LIST_PTR->NAME\", &task_name_addr) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get value of 'td_struct->TEMPLATE_LIST_PTR->NAME' */\n\t\tif (mqx_get_member(rtos, task_name_addr, 0, MQX_THREAD_NAME_LENGTH,\n\t\t\t\"*td_struct_ptr->TEMPLATE_LIST_PTR->NAME\", task_name) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* always terminate last character by force,\n\t\t   otherwise openocd might fail if task_name\n\t\t   has corrupted data */\n\t\ttask_name[MQX_THREAD_NAME_LENGTH] = '\\0';\n\t\t/* get value of 'td_struct_ptr->TASK_ID' */\n\t\tif (mqx_get_member(rtos, task_addr, MQX_TASK_OFFSET_ID, 4,\n\t\t\t\"td_struct_ptr->TASK_ID\", &task_id) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get task errno */\n\t\tif (mqx_get_member(rtos, task_addr, MQX_TASK_OFFSET_ERROR_CODE, 4,\n\t\t\t\"td_struct_ptr->TASK_ERROR_CODE\", &task_errno) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get value of 'td_struct_ptr->STATE' */\n\t\tif (mqx_get_member(rtos, task_addr, MQX_TASK_OFFSET_STATE, 4,\n\t\t\t\"td_struct_ptr->STATE\", &task_state) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\ttask_state &= MQX_TASK_STATE_MASK;\n\t\t/* and search for defined state */\n\t\tfor (state_index = 0; state_index < ARRAY_SIZE(mqx_states); state_index++) {\n\t\t\tif (mqx_states[state_index].state == task_state) {\n\t\t\t\tstate_name = mqx_states[state_index].name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* setup thread details struct */\n\t\trtos->thread_details[i].threadid = task_id;\n\t\trtos->thread_details[i].exists = true;\n\t\t/* set thread name */\n\t\trtos->thread_details[i].thread_name_str = malloc(strlen((void *)task_name) + 1);\n\t\tif (!rtos->thread_details[i].thread_name_str)\n\t\t\treturn ERROR_FAIL;\n\t\tstrcpy(rtos->thread_details[i].thread_name_str, (void *)task_name);\n\t\t/* set thread extra info\n\t\t * - task state\n\t\t * - task address\n\t\t * - task errno\n\t\t * calculate length as:\n\t\t * state length + address length + errno length + formatter length\n\t\t */\n\t\textra_info_length += strlen((void *)state_name) + 7 + 13 + 8 + 15 + 8;\n\t\trtos->thread_details[i].extra_info_str = malloc(extra_info_length + 1);\n\t\tif (!rtos->thread_details[i].extra_info_str)\n\t\t\treturn ERROR_FAIL;\n\t\tsnprintf(rtos->thread_details[i].extra_info_str, extra_info_length,\n\t\t\t \"State: %s, Address: 0x%\" PRIx32 \",  Error Code: %\" PRIu32,\n\t\t\t state_name, task_addr, task_errno\n\t\t);\n\t\t/* set active thread */\n\t\tif (active_td_addr == task_addr)\n\t\t\trtos->current_thread = task_id;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * API function, get info of selected thread\n */\nstatic int mqx_get_thread_reg_list(\n\tstruct rtos *rtos,\n\tint64_t thread_id,\n\tstruct rtos_reg **reg_list,\n\tint *num_regs\n)\n{\n\tint64_t stack_ptr = 0;\n\tuint32_t my_task_addr = 0;\n\tuint32_t task_queue_addr = 0;\n\tuint32_t task_queue_size = 0;\n\tuint32_t kernel_data_addr = 0;\n\n\tif (thread_id == 0) {\n\t\tLOG_ERROR(\"MQX RTOS - invalid threadid: 0x%X\", (int)thread_id);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (mqx_is_scheduler_running(rtos) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t/* get kernel_data symbol */\n\tif (mqx_get_symbol(rtos, MQX_VAL_MQX_KERNEL_DATA, &kernel_data_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* read kernel_data */\n\tif (mqx_get_member(rtos, kernel_data_addr, 0, 4,\n\t\t\"_mqx_kernel_data\", &kernel_data_addr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* get task queue address */\n\ttask_queue_addr = kernel_data_addr + MQX_KERNEL_OFFSET_TDLIST;\n\t/* get task queue size */\n\tif (mqx_get_member(rtos, task_queue_addr, MQX_QUEUE_OFFSET_SIZE, 2,\n\t\t\"kernel_data->TD_LIST.SIZE\", &task_queue_size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* search for taskid */\n\tfor (\n\t\tuint32_t i = 0, taskpool_addr = task_queue_addr;\n\t\ti < (uint32_t)rtos->thread_count;\n\t\ti++\n\t) {\n\t\tuint32_t tmp_address = 0, task_addr = 0;\n\t\tuint32_t task_id = 0;\n\t\t/* set current taskpool address */\n\t\ttmp_address = taskpool_addr;\n\t\tif (mqx_get_member(rtos, tmp_address, MQX_TASK_OFFSET_NEXT, 4,\n\t\t\t\"td_struct_ptr->NEXT\", &taskpool_addr) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* get task address from taskpool */\n\t\ttask_addr = taskpool_addr - MQX_TASK_OFFSET_TDLIST;\n\t\t/* get value of td_struct->TASK_ID */\n\t\tif (mqx_get_member(rtos, task_addr, MQX_TASK_OFFSET_ID, 4,\n\t\t\t\"td_struct_ptr->TASK_ID\", &task_id) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* found taskid, break */\n\t\tif (task_id == thread_id) {\n\t\t\tmy_task_addr = task_addr;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!my_task_addr) {\n\t\tLOG_ERROR(\"MQX_RTOS - threadid %\" PRId64 \" does not match any task\", thread_id);\n\t\treturn ERROR_FAIL;\n\t}\n\t/* get task stack head address */\n\tif (mqx_get_member(rtos, my_task_addr, MQX_TASK_OFFSET_STACK, 4,\n\t\t\"task->STACK_PTR\", &stack_ptr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn rtos_generic_stack_read(\n\t\trtos->target, ((struct mqx_params *)rtos->rtos_specific_params)->stacking_info, stack_ptr, reg_list, num_regs\n\t);\n}\n\n/* API function, export list of required symbols */\nstatic int mqx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = calloc(ARRAY_SIZE(mqx_symbol_list), sizeof(struct symbol_table_elem));\n\tif (!*symbol_list)\n\t\treturn ERROR_FAIL;\n\t/* export required symbols */\n\tfor (int i = 0; i < (int)(ARRAY_SIZE(mqx_symbol_list)); i++)\n\t\t(*symbol_list)[i].symbol_name = mqx_symbol_list[i];\n\treturn ERROR_OK;\n}\n\nconst struct rtos_type mqx_rtos = {\n\t.name = \"mqx\",\n\t.detect_rtos = mqx_detect_rtos,\n\t.create = mqx_create,\n\t.update_threads = mqx_update_threads,\n\t.get_thread_reg_list = mqx_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = mqx_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/nuttx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright 2016,2017 Sony Video & Sound Products Inc.                  *\n *   Masatoshi Tateishi - Masatoshi.Tateishi@jp.sony.com                   *\n *   Masayuki Ishikawa - Masayuki.Ishikawa@jp.sony.com                     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"target/armv7m.h\"\n#include \"target/cortex_m.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"target/register.h\"\n#include \"rtos_nuttx_stackings.h\"\n\n#define NAME_SIZE       32\n#define EXTRAINFO_SIZE  256\n\n/* Only 32-bit CPUs are supported by the current implementation.  Supporting\n * other CPUs will require reading this information from the target and\n * adapting the code accordingly.\n */\n#define PTR_WIDTH 4\n\nstruct nuttx_params {\n\tconst char *target_name;\n\tconst struct rtos_register_stacking *stacking;\n\tconst struct rtos_register_stacking *(*select_stackinfo)(struct target *target);\n};\n\n/*\n * struct tcbinfo_s is located in the sched.h\n * https://github.com/apache/nuttx/blob/master/include/nuttx/sched.h\n */\n#define TCBINFO_TARGET_SIZE 22\nstruct tcbinfo {\n\tuint16_t pid_off;\t\t\t/* Offset of tcb.pid                */\n\tuint16_t state_off;\t\t\t/* Offset of tcb.task_state         */\n\tuint16_t pri_off;\t\t\t/* Offset of tcb.sched_priority     */\n\tuint16_t name_off;\t\t\t/* Offset of tcb.name               */\n\tuint16_t regs_off;\t\t\t/* Offset of tcb.regs               */\n\tuint16_t basic_num;\t\t\t/* Num of genernal regs             */\n\tuint16_t total_num;\t\t\t/* Num of regs in tcbinfo.reg_offs  */\n\ttarget_addr_t xcpreg_off;\t/* Offset pointer of xcp.regs       */\n};\n\nstruct symbols {\n\tconst char *name;\n\tbool optional;\n};\n\n/* Used to index the list of retrieved symbols. See nuttx_symbol_list for the order. */\nenum nuttx_symbol_vals {\n\tNX_SYM_READYTORUN = 0,\n\tNX_SYM_PIDHASH,\n\tNX_SYM_NPIDHASH,\n\tNX_SYM_TCB_INFO,\n};\n\nstatic const struct symbols nuttx_symbol_list[] = {\n\t{ \"g_readytorun\", false },\n\t{ \"g_pidhash\", false },\n\t{ \"g_npidhash\", false },\n\t{ \"g_tcbinfo\", false },\n\t{ NULL, false }\n};\n\nstatic char *task_state_str[] = {\n\t\"INVALID\",\n\t\"PENDING\",\n\t\"READYTORUN\",\n\t\"RUNNING\",\n\t\"INACTIVE\",\n\t\"WAIT_SEM\",\n\t\"WAIT_SIG\",\n\t\"WAIT_MQNOTEMPTY\",\n\t\"WAIT_MQNOTFULL\",\n\t\"WAIT_PAGEFILL\",\n\t\"STOPPED\",\n};\n\nstatic const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target);\n\nstatic const struct nuttx_params nuttx_params_list[] = {\n\t{\n\t\t.target_name = \"cortex_m\",\n\t\t.stacking = NULL,\n\t\t.select_stackinfo = cortexm_select_stackinfo,\n\t},\n\t{\n\t\t.target_name = \"hla_target\",\n\t\t.stacking = NULL,\n\t\t.select_stackinfo = cortexm_select_stackinfo,\n\t},\n\t{\n\t\t.target_name = \"esp32\",\n\t\t.stacking = &nuttx_esp32_stacking,\n\t},\n\t{\n\t\t.target_name = \"esp32s2\",\n\t\t.stacking = &nuttx_esp32s2_stacking,\n\t},\n\t{\n\t\t.target_name = \"esp32s3\",\n\t\t.stacking = &nuttx_esp32s3_stacking,\n\t},\n\t{\n\t\t.target_name = \"esp32c3\",\n\t\t.stacking = &nuttx_riscv_stacking,\n\t},\n};\n\nstatic bool cortexm_hasfpu(struct target *target)\n{\n\tuint32_t cpacr;\n\tstruct armv7m_common *armv7m_target = target_to_armv7m(target);\n\n\tif (!is_armv7m(armv7m_target) || armv7m_target->fp_feature == FP_NONE)\n\t\treturn false;\n\n\tint retval = target_read_u32(target, FPU_CPACR, &cpacr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read CPACR register to check FPU state\");\n\t\treturn false;\n\t}\n\n\treturn cpacr & 0x00F00000;\n}\n\nstatic const struct rtos_register_stacking *cortexm_select_stackinfo(struct target *target)\n{\n\treturn cortexm_hasfpu(target) ? &nuttx_stacking_cortex_m_fpu : &nuttx_stacking_cortex_m;\n}\n\nstatic bool nuttx_detect_rtos(struct target *target)\n{\n\tif (target->rtos->symbols &&\n\t\ttarget->rtos->symbols[NX_SYM_READYTORUN].address != 0 &&\n\t\ttarget->rtos->symbols[NX_SYM_PIDHASH].address != 0)\n\t\treturn true;\n\treturn false;\n}\n\nstatic int nuttx_create(struct target *target)\n{\n\tconst struct nuttx_params *param;\n\tunsigned int i;\n\n\tfor (i = 0; i < ARRAY_SIZE(nuttx_params_list); i++) {\n\t\tparam = &nuttx_params_list[i];\n\t\tif (strcmp(target_type_name(target), param->target_name) == 0) {\n\t\t\tLOG_INFO(\"Detected target \\\"%s\\\"\", param->target_name);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (i >= ARRAY_SIZE(nuttx_params_list)) {\n\t\tLOG_ERROR(\"Could not find \\\"%s\\\" target in NuttX compatibility list\", target_type_name(target));\n\t\treturn JIM_ERR;\n\t}\n\n\t/* We found a target in our list, copy its reference. */\n\ttarget->rtos->rtos_specific_params = (void *)param;\n\n\treturn JIM_OK;\n}\n\nstatic int nuttx_smp_init(struct target *target)\n{\n\t/* Return OK for now so that the initialisation sequence doesn't stop.\n\t * SMP case will be implemented later. */\n\treturn ERROR_OK;\n}\n\nstatic target_addr_t target_buffer_get_addr(struct target *target, const uint8_t *buffer)\n{\n#if PTR_WIDTH == 8\n\treturn target_buffer_get_u64(target, buffer);\n#else\n\treturn target_buffer_get_u32(target, buffer);\n#endif\n}\n\nstatic int nuttx_update_threads(struct rtos *rtos)\n{\n\tstruct tcbinfo tcbinfo;\n\tuint32_t pidhashaddr, npidhash, tcbaddr;\n\tuint16_t pid;\n\tuint8_t state;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for nuttx\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Free previous thread details */\n\trtos_free_threadlist(rtos);\n\n\t/* NuttX provides a hash table that keeps track of all the TCBs.\n\t * We first read its size from g_npidhash and its address from g_pidhash.\n\t * Its content is then read from these values.\n\t */\n\tint ret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_NPIDHASH].address, &npidhash);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read g_npidhash: ret = %d\", ret);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Hash table size (g_npidhash) = %\" PRId32, npidhash);\n\n\tret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_PIDHASH].address, &pidhashaddr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read g_pidhash address: ret = %d\", ret);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Hash table address (g_pidhash) = %\" PRIx32, pidhashaddr);\n\n\tuint8_t *pidhash = malloc(npidhash * PTR_WIDTH);\n\tif (!pidhash) {\n\t\tLOG_ERROR(\"Failed to allocate pidhash\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = target_read_buffer(rtos->target, pidhashaddr, PTR_WIDTH * npidhash, pidhash);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read tcbhash: ret = %d\", ret);\n\t\tgoto errout;\n\t}\n\n\t/* NuttX provides a struct that contains TCB offsets for required members.\n\t * Read its content from g_tcbinfo.\n\t */\n\tuint8_t buff[TCBINFO_TARGET_SIZE];\n\tret = target_read_buffer(rtos->target, rtos->symbols[NX_SYM_TCB_INFO].address, sizeof(buff), buff);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read tcbinfo: ret = %d\", ret);\n\t\tgoto errout;\n\t}\n\ttcbinfo.pid_off = target_buffer_get_u16(rtos->target, buff);\n\ttcbinfo.state_off = target_buffer_get_u16(rtos->target, buff + 2);\n\ttcbinfo.pri_off = target_buffer_get_u16(rtos->target, buff + 4);\n\ttcbinfo.name_off = target_buffer_get_u16(rtos->target, buff + 6);\n\ttcbinfo.regs_off = target_buffer_get_u16(rtos->target, buff + 8);\n\ttcbinfo.basic_num = target_buffer_get_u16(rtos->target, buff + 10);\n\ttcbinfo.total_num = target_buffer_get_u16(rtos->target, buff + 12);\n\ttcbinfo.xcpreg_off = target_buffer_get_addr(rtos->target, buff + 14);\n\n\t/* The head of the g_readytorun list is the currently running task.\n\t * Reading in a temporary variable first to avoid endianness issues,\n\t * rtos->current_thread is int64_t. */\n\tuint32_t current_thread;\n\tret = target_read_u32(rtos->target, rtos->symbols[NX_SYM_READYTORUN].address, &current_thread);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read g_readytorun: ret = %d\", ret);\n\t\tgoto errout;\n\t}\n\trtos->current_thread = current_thread;\n\n\tuint32_t thread_count = 0;\n\n\tfor (unsigned int i = 0; i < npidhash; i++) {\n\t\ttcbaddr = target_buffer_get_u32(rtos->target, &pidhash[i * PTR_WIDTH]);\n\n\t\tif (!tcbaddr)\n\t\t\tcontinue;\n\n\t\tret = target_read_u16(rtos->target, tcbaddr + tcbinfo.pid_off, &pid);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read PID of TCB@0x%x from pidhash[%d]: ret = %d\",\n\t\t\t\ttcbaddr, i, ret);\n\t\t\tgoto errout;\n\t\t}\n\n\t\tret = target_read_u8(rtos->target, tcbaddr + tcbinfo.state_off, &state);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read state of TCB@0x%x from pidhash[%d]: ret = %d\",\n\t\t\t\ttcbaddr, i, ret);\n\t\t\tgoto errout;\n\t\t}\n\n\t\tstruct thread_detail *new_thread_details = realloc(rtos->thread_details,\n\t\t\tsizeof(struct thread_detail) * (thread_count + 1));\n\t\tif (!new_thread_details) {\n\t\t\tret = ERROR_FAIL;\n\t\t\tgoto errout;\n\t\t}\n\n\t\tstruct thread_detail *thread = &new_thread_details[thread_count];\n\t\tthread->threadid = tcbaddr;\n\t\tthread->exists = true;\n\t\tthread->extra_info_str = NULL;\n\n\t\trtos->thread_details = new_thread_details;\n\t\tthread_count++;\n\n\t\tif (state < ARRAY_SIZE(task_state_str)) {\n\t\t\tthread->extra_info_str = malloc(EXTRAINFO_SIZE);\n\t\t\tif (!thread->extra_info_str) {\n\t\t\t\tret = ERROR_FAIL;\n\t\t\t\tgoto errout;\n\t\t\t}\n\t\t\tsnprintf(thread->extra_info_str, EXTRAINFO_SIZE, \"pid:%d, %s\",\n\t\t\t\tpid,\n\t\t\t\ttask_state_str[state]);\n\t\t}\n\n\t\tif (tcbinfo.name_off) {\n\t\t\tthread->thread_name_str = calloc(NAME_SIZE + 1, sizeof(char));\n\t\t\tif (!thread->thread_name_str) {\n\t\t\t\tret = ERROR_FAIL;\n\t\t\t\tgoto errout;\n\t\t\t}\n\t\t\tret = target_read_buffer(rtos->target, tcbaddr + tcbinfo.name_off,\n\t\t\t\tsizeof(char) * NAME_SIZE, (uint8_t *)thread->thread_name_str);\n\t\t\tif (ret != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to read thread's name: ret = %d\", ret);\n\t\t\t\tgoto errout;\n\t\t\t}\n\t\t} else {\n\t\t\tthread->thread_name_str = strdup(\"None\");\n\t\t}\n\t}\n\n\tret = ERROR_OK;\n\trtos->thread_count = thread_count;\nerrout:\n\tfree(pidhash);\n\treturn ret;\n}\n\nstatic int nuttx_getreg_current_thread(struct rtos *rtos,\n\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tstruct reg **gdb_reg_list;\n\n\t/* Registers for currently running thread are not on task's stack and\n\t * should be retrieved from reg caches via target_get_gdb_reg_list */\n\tint ret = target_get_gdb_reg_list(rtos->target, &gdb_reg_list, num_regs,\n\t\tREG_CLASS_GENERAL);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"target_get_gdb_reg_list failed %d\", ret);\n\t\treturn ret;\n\t}\n\n\t*reg_list = calloc(*num_regs, sizeof(struct rtos_reg));\n\tif (!(*reg_list)) {\n\t\tLOG_ERROR(\"Failed to alloc memory for %d\", *num_regs);\n\t\tfree(gdb_reg_list);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (int i = 0; i < *num_regs; i++) {\n\t\t(*reg_list)[i].number = gdb_reg_list[i]->number;\n\t\t(*reg_list)[i].size = gdb_reg_list[i]->size;\n\t\tmemcpy((*reg_list)[i].value, gdb_reg_list[i]->value, ((*reg_list)[i].size + 7) / 8);\n\t}\n\n\tfree(gdb_reg_list);\n\n\treturn ERROR_OK;\n}\n\nstatic int nuttx_getregs_fromstack(struct rtos *rtos, int64_t thread_id,\n\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tuint16_t xcpreg_off;\n\tuint32_t regsaddr;\n\tconst struct nuttx_params *priv = rtos->rtos_specific_params;\n\tconst struct rtos_register_stacking *stacking = priv->stacking;\n\n\tif (!stacking) {\n\t\tif (priv->select_stackinfo) {\n\t\t\tstacking = priv->select_stackinfo(rtos->target);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Can't find a way to get stacking info\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tint ret = target_read_u16(rtos->target,\n\t\trtos->symbols[NX_SYM_TCB_INFO].address + offsetof(struct tcbinfo, regs_off),\n\t\t&xcpreg_off);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read registers' offset: ret = %d\", ret);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = target_read_u32(rtos->target, thread_id + xcpreg_off, &regsaddr);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read registers' address: ret = %d\", ret);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target, stacking, regsaddr, reg_list, num_regs);\n}\n\nstatic int nuttx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tif (!rtos) {\n\t\tLOG_ERROR(\"NUTTX: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (thread_id == rtos->current_thread)\n\t\treturn nuttx_getreg_current_thread(rtos, reg_list, num_regs);\n\treturn nuttx_getregs_fromstack(rtos, thread_id, reg_list, num_regs);\n}\n\nstatic int nuttx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = calloc(ARRAY_SIZE(nuttx_symbol_list), sizeof(**symbol_list));\n\tif (!*symbol_list) {\n\t\tLOG_ERROR(\"NUTTX: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(nuttx_symbol_list); i++) {\n\t\t(*symbol_list)[i].symbol_name = nuttx_symbol_list[i].name;\n\t\t(*symbol_list)[i].optional = nuttx_symbol_list[i].optional;\n\t}\n\n\treturn ERROR_OK;\n}\n\nconst struct rtos_type nuttx_rtos = {\n\t.name = \"nuttx\",\n\t.detect_rtos = nuttx_detect_rtos,\n\t.create = nuttx_create,\n\t.smp_init = nuttx_smp_init,\n\t.update_threads = nuttx_update_threads,\n\t.get_thread_reg_list = nuttx_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = nuttx_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/riot.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Daniel Krebs                                    *\n *   Daniel Krebs - github@daniel-krebs.net                                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_riot_stackings.h\"\n\nstatic bool riot_detect_rtos(struct target *target);\nstatic int riot_create(struct target *target);\nstatic int riot_update_threads(struct rtos *rtos);\nstatic int riot_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\tstruct rtos_reg **reg_list, int *num_regs);\nstatic int riot_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);\n\nstruct riot_thread_state {\n\tint value;\n\tconst char *desc;\n};\n\n/* refer RIOT sched.h */\nstatic const struct riot_thread_state riot_thread_states[] = {\n\t{ 0, \"Stopped\" },\n\t{ 1, \"Zombie\" },\n\t{ 2, \"Sleeping\" },\n\t{ 3, \"Blocked mutex\" },\n\t{ 4, \"Blocked receive\" },\n\t{ 5, \"Blocked send\" },\n\t{ 6, \"Blocked reply\" },\n\t{ 7, \"Blocked any flag\" },\n\t{ 8, \"Blocked all flags\" },\n\t{ 9, \"Blocked mbox\" },\n\t{ 10, \"Blocked condition\" },\n\t{ 11, \"Running\" },\n\t{ 12, \"Pending\" },\n};\n#define RIOT_NUM_STATES ARRAY_SIZE(riot_thread_states)\n\nstruct riot_params {\n\tconst char *target_name;\n\tunsigned char thread_sp_offset;\n\tunsigned char thread_status_offset;\n};\n\nstatic const struct riot_params riot_params_list[] = {\n\t{\n\t\t\"cortex_m\",\t\t/* target_name */\n\t\t0x00,\t\t\t\t\t/* thread_sp_offset */\n\t\t0x04,\t\t\t\t\t/* thread_status_offset */\n\t},\n\t{\t/* STLink */\n\t\t\"hla_target\",\t\t/* target_name */\n\t\t0x00,\t\t\t/* thread_sp_offset */\n\t\t0x04,\t\t\t/* thread_status_offset */\n\t}\n};\n#define RIOT_NUM_PARAMS ARRAY_SIZE(riot_params_list)\n\n/* Initialize in riot_create() depending on architecture */\nstatic const struct rtos_register_stacking *stacking_info;\n\nenum riot_symbol_values {\n\tRIOT_THREADS_BASE = 0,\n\tRIOT_NUM_THREADS,\n\tRIOT_ACTIVE_PID,\n\tRIOT_MAX_THREADS,\n\tRIOT_NAME_OFFSET,\n};\n\nstruct riot_symbol {\n\tconst char *const name;\n\tbool optional;\n};\n\n/* refer RIOT core/sched.c */\nstatic struct riot_symbol const riot_symbol_list[] = {\n\t{\"sched_threads\", false},\n\t{\"sched_num_threads\", false},\n\t{\"sched_active_pid\", false},\n\t{\"max_threads\", false},\n\t{\"_tcb_name_offset\", true},\n\t{NULL, false}\n};\n\nconst struct rtos_type riot_rtos = {\n\t.name = \"RIOT\",\n\t.detect_rtos = riot_detect_rtos,\n\t.create = riot_create,\n\t.update_threads = riot_update_threads,\n\t.get_thread_reg_list = riot_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = riot_get_symbol_list_to_lookup,\n};\n\nstatic int riot_update_threads(struct rtos *rtos)\n{\n\tint retval;\n\tint tasks_found = 0;\n\tconst struct riot_params *param;\n\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn ERROR_FAIL;\n\n\tparam = (const struct riot_params *)rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for RIOT\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rtos->symbols[RIOT_THREADS_BASE].address == 0) {\n\t\tLOG_ERROR(\"Can't find symbol `%s`\",\n\t\t\triot_symbol_list[RIOT_THREADS_BASE].name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* wipe out previous thread details if any */\n\trtos_free_threadlist(rtos);\n\n\t/* Reset values */\n\trtos->current_thread = 0;\n\trtos->thread_count = 0;\n\n\t/* read the current thread id */\n\tint16_t active_pid = 0;\n\tretval = target_read_u16(rtos->target,\n\t\t\trtos->symbols[RIOT_ACTIVE_PID].address,\n\t\t\t(uint16_t *)&active_pid);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't read symbol `%s`\",\n\t\t\triot_symbol_list[RIOT_ACTIVE_PID].name);\n\t\treturn retval;\n\t}\n\trtos->current_thread = active_pid;\n\n\t/* read the current thread count\n\t * It's `int` in RIOT, but this is Cortex M* only anyway */\n\tint32_t thread_count = 0;\n\tretval = target_read_u16(rtos->target,\n\t\t\trtos->symbols[RIOT_NUM_THREADS].address,\n\t\t\t(uint16_t *)&thread_count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't read symbol `%s`\",\n\t\t\triot_symbol_list[RIOT_NUM_THREADS].name);\n\t\treturn retval;\n\t}\n\n\t/* read the maximum number of threads */\n\tuint8_t max_threads = 0;\n\tretval = target_read_u8(rtos->target,\n\t\t\trtos->symbols[RIOT_MAX_THREADS].address,\n\t\t\t&max_threads);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't read symbol `%s`\",\n\t\t\triot_symbol_list[RIOT_MAX_THREADS].name);\n\t\treturn retval;\n\t}\n\tif (thread_count > max_threads) {\n\t\tLOG_ERROR(\"Thread count is invalid\");\n\t\treturn ERROR_FAIL;\n\t}\n\trtos->thread_count = thread_count;\n\n\t/* Base address of thread array */\n\tuint32_t threads_base = rtos->symbols[RIOT_THREADS_BASE].address;\n\n\t/* Try to get the offset of tcb_t::name, if absent RIOT wasn't compiled\n\t * with DEVELHELP, so there are no thread names */\n\tuint8_t name_offset = 0;\n\tif (rtos->symbols[RIOT_NAME_OFFSET].address != 0) {\n\t\tretval = target_read_u8(rtos->target,\n\t\t\t\trtos->symbols[RIOT_NAME_OFFSET].address,\n\t\t\t\t&name_offset);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't read symbol `%s`\",\n\t\t\t\triot_symbol_list[RIOT_NAME_OFFSET].name);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Allocate memory for thread description */\n\trtos->thread_details = calloc(thread_count, sizeof(struct thread_detail));\n\tif (!rtos->thread_details) {\n\t\tLOG_ERROR(\"RIOT: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Buffer for thread names, maximum to display is 32 */\n\tchar buffer[32];\n\n\tfor (unsigned int i = 0; i < max_threads; i++) {\n\t\tif (tasks_found == rtos->thread_count)\n\t\t\tbreak;\n\n\t\t/* get pointer to tcb_t */\n\t\tuint32_t tcb_pointer = 0;\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\tthreads_base + (i * 4),\n\t\t\t\t&tcb_pointer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't parse `%s`\",\n\t\t\t\triot_symbol_list[RIOT_THREADS_BASE].name);\n\t\t\tgoto error;\n\t\t}\n\n\t\tif (tcb_pointer == 0) {\n\t\t\t/* PID unused */\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Index is PID */\n\t\trtos->thread_details[tasks_found].threadid = i;\n\n\t\t/* read thread state */\n\t\tuint8_t status = 0;\n\t\tretval = target_read_u8(rtos->target,\n\t\t\t\ttcb_pointer + param->thread_status_offset,\n\t\t\t\t&status);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't parse `%s`\",\n\t\t\t\triot_symbol_list[RIOT_THREADS_BASE].name);\n\t\t\tgoto error;\n\t\t}\n\n\t\t/* Search for state */\n\t\tunsigned int k;\n\t\tfor (k = 0; k < RIOT_NUM_STATES; k++) {\n\t\t\tif (riot_thread_states[k].value == status)\n\t\t\t\tbreak;\n\t\t}\n\n\t\t/* Copy state string */\n\t\tif (k >= RIOT_NUM_STATES) {\n\t\t\trtos->thread_details[tasks_found].extra_info_str =\n\t\t\tstrdup(\"unknown state\");\n\t\t} else {\n\t\t\trtos->thread_details[tasks_found].extra_info_str =\n\t\t\tstrdup(riot_thread_states[k].desc);\n\t\t}\n\n\t\tif (!rtos->thread_details[tasks_found].extra_info_str) {\n\t\t\tLOG_ERROR(\"RIOT: out of memory\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto error;\n\t\t}\n\n\t\t/* Thread names are only available if compiled with DEVELHELP */\n\t\tif (name_offset != 0) {\n\t\t\tuint32_t name_pointer = 0;\n\t\t\tretval = target_read_u32(rtos->target,\n\t\t\t\t\ttcb_pointer + name_offset,\n\t\t\t\t\t&name_pointer);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Can't parse `%s`\",\n\t\t\t\t\triot_symbol_list[RIOT_THREADS_BASE].name);\n\t\t\t\tgoto error;\n\t\t\t}\n\n\t\t\t/* read thread name */\n\t\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t\tname_pointer,\n\t\t\t\t\tsizeof(buffer),\n\t\t\t\t\t(uint8_t *)&buffer);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Can't parse `%s`\",\n\t\t\t\t\triot_symbol_list[RIOT_THREADS_BASE].name);\n\t\t\t\tgoto error;\n\t\t\t}\n\n\t\t\t/* Make sure the string in the buffer terminates */\n\t\t\tif (buffer[sizeof(buffer) - 1] != 0)\n\t\t\t\tbuffer[sizeof(buffer) - 1] = 0;\n\n\t\t\t/* Copy thread name */\n\t\t\trtos->thread_details[tasks_found].thread_name_str =\n\t\t\tstrdup(buffer);\n\n\t\t} else {\n\t\t\trtos->thread_details[tasks_found].thread_name_str =\n\t\t\tstrdup(\"Enable DEVELHELP to see task names\");\n\t\t}\n\n\t\tif (!rtos->thread_details[tasks_found].thread_name_str) {\n\t\t\tLOG_ERROR(\"RIOT: out of memory\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto error;\n\t\t}\n\n\t\trtos->thread_details[tasks_found].exists = true;\n\n\t\ttasks_found++;\n\t}\n\n\treturn ERROR_OK;\n\nerror:\n\trtos_free_threadlist(rtos);\n\treturn retval;\n}\n\nstatic int riot_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tint retval;\n\tconst struct riot_params *param;\n\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tif (thread_id == 0)\n\t\treturn ERROR_FAIL;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn ERROR_FAIL;\n\n\tparam = (const struct riot_params *)rtos->rtos_specific_params;\n\n\t/* find the thread with given thread id */\n\tuint32_t threads_base = rtos->symbols[RIOT_THREADS_BASE].address;\n\tuint32_t tcb_pointer = 0;\n\tretval = target_read_u32(rtos->target,\n\t\t\tthreads_base + (thread_id * 4),\n\t\t\t&tcb_pointer);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't parse `%s`\", riot_symbol_list[RIOT_THREADS_BASE].name);\n\t\treturn retval;\n\t}\n\n\t/* read stack pointer for that thread */\n\tuint32_t stackptr = 0;\n\tretval = target_read_u32(rtos->target,\n\t\t\ttcb_pointer + param->thread_sp_offset,\n\t\t\t&stackptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't parse `%s`\", riot_symbol_list[RIOT_THREADS_BASE].name);\n\t\treturn retval;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target,\n\t\t\tstacking_info,\n\t\t\tstackptr,\n\t\t\treg_list,\n\t\t\tnum_regs);\n}\n\nstatic int riot_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = calloc(ARRAY_SIZE(riot_symbol_list), sizeof(struct symbol_table_elem));\n\n\tif (!*symbol_list) {\n\t\tLOG_ERROR(\"RIOT: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(riot_symbol_list); i++) {\n\t\t(*symbol_list)[i].symbol_name = riot_symbol_list[i].name;\n\t\t(*symbol_list)[i].optional = riot_symbol_list[i].optional;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool riot_detect_rtos(struct target *target)\n{\n\tif ((target->rtos->symbols) &&\n\t\t(target->rtos->symbols[RIOT_THREADS_BASE].address != 0)) {\n\t\t/* looks like RIOT */\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic int riot_create(struct target *target)\n{\n\tunsigned int i = 0;\n\n\t/* lookup if target is supported by RIOT */\n\twhile ((i < RIOT_NUM_PARAMS) &&\n\t\t(strcmp(riot_params_list[i].target_name, target->type->name) != 0)) {\n\t\ti++;\n\t}\n\tif (i >= RIOT_NUM_PARAMS) {\n\t\tLOG_ERROR(\"Could not find target in RIOT compatibility list\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget->rtos->rtos_specific_params = (void *)&riot_params_list[i];\n\ttarget->rtos->current_thread = 0;\n\ttarget->rtos->thread_details = NULL;\n\n\t/* Stacking is different depending on architecture */\n\tstruct armv7m_common *armv7m_target = target_to_armv7m(target);\n\n\tif (armv7m_target->arm.arch == ARM_ARCH_V6M)\n\t\tstacking_info = &rtos_riot_cortex_m0_stacking;\n\telse if (is_armv7m(armv7m_target))\n\t\tstacking_info = &rtos_riot_cortex_m34_stacking;\n\telse {\n\t\tLOG_ERROR(\"No stacking info for architecture\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtkernel.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016-2023 by Andreas Fritiofson                         *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"rtos.h\"\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"target/armv7m.h\"\n#include \"target/cortex_m.h\"\n\n#define ST_DEAD     BIT(0)    /* Task is waiting to be deleted */\n#define ST_WAIT     BIT(1)    /* Task is blocked: */\n#define ST_SEM      BIT(2)    /*  on semaphore */\n#define ST_MTX      BIT(3)    /*  on mutex */\n#define ST_SIG      BIT(4)    /*  on signal */\n#define ST_DLY      BIT(5)    /*  on timer */\n#define ST_FLAG     BIT(6)    /*  on flag */\n#define ST_FLAG_ALL BIT(7)    /*  on flag and flag mode is \"ALL\" */\n#define ST_MBOX     BIT(8)    /*  on mailbox */\n#define ST_STP      BIT(9)    /*  self stopped */\n#define ST_SUSPEND  BIT(10)   /* Task is suspended */\n#define ST_TT       BIT(11)   /* Time triggered task */\n#define ST_TT_YIELD BIT(12)   /* Time triggered task that yields */\n#define ST_CREATE   BIT(13)   /* Task was created by task_create() */\n\nstruct rtkernel_params {\n\tconst char *target_name;\n\tconst struct rtos_register_stacking *stacking_info_cm3;\n\tconst struct rtos_register_stacking *stacking_info_cm4f;\n\tconst struct rtos_register_stacking *stacking_info_cm4f_fpu;\n};\n\nstatic const struct rtkernel_params rtkernel_params_list[] = {\n\t{\n\t\t\"cortex_m\",\t\t\t/* target_name */\n\t\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t\t&rtos_standard_cortex_m4f_stacking,\n\t\t&rtos_standard_cortex_m4f_fpu_stacking,\n\t},\n\t{\n\t\t\"hla_target\",\t\t\t/* target_name */\n\t\t&rtos_standard_cortex_m3_stacking,\t/* stacking_info */\n\t\t&rtos_standard_cortex_m4f_stacking,\n\t\t&rtos_standard_cortex_m4f_fpu_stacking,\n\t},\n};\n\nenum rtkernel_symbol_values {\n\tsym_os_state = 0,\n\tsym___off_os_state2chain = 1,\n\tsym___off_os_state2current = 2,\n\tsym___off_task2chain = 3,\n\tsym___off_task2magic = 4,\n\tsym___off_task2stack = 5,\n\tsym___off_task2state = 6,\n\tsym___off_task2name = 7,\n\tsym___val_task_magic = 8,\n};\n\nstruct symbols {\n\tconst char *name;\n\tbool optional;\n};\n\nstatic const struct symbols rtkernel_symbol_list[] = {\n\t{ \"os_state\", false },\n\t{ \"__off_os_state2chain\", false },\n\t{ \"__off_os_state2current\", false },\n\t{ \"__off_task2chain\", false },\n\t{ \"__off_task2magic\", false },\n\t{ \"__off_task2stack\", false },\n\t{ \"__off_task2state\", false },\n\t{ \"__off_task2name\", false },\n\t{ \"__val_task_magic\", false },\n\t{ NULL, false }\n};\n\nstatic void *realloc_preserve(void *ptr, size_t old_size, size_t new_size)\n{\n\tvoid *new_ptr = malloc(new_size);\n\n\tif (new_ptr) {\n\t\tmemcpy(new_ptr, ptr, MIN(old_size, new_size));\n\t\tfree(ptr);\n\t}\n\n\treturn new_ptr;\n}\n\nstatic int rtkernel_add_task(struct rtos *rtos, uint32_t task, uint32_t current_task)\n{\n\tint retval;\n\tint new_thread_count = rtos->thread_count + 1;\n\tstruct thread_detail *new_thread_details = realloc_preserve(rtos->thread_details,\n\t\t\trtos->thread_count * sizeof(struct thread_detail),\n\t\t\tnew_thread_count * sizeof(struct thread_detail));\n\tif (!new_thread_details) {\n\t\tLOG_ERROR(\"Error growing memory to %d threads\", new_thread_count);\n\t\treturn ERROR_FAIL;\n\t}\n\trtos->thread_details = new_thread_details;\n\tstruct thread_detail *thread = &new_thread_details[rtos->thread_count];\n\n\t*thread = (struct thread_detail){ .threadid = task, .exists = true };\n\n\t/* Read the task name */\n\tuint32_t name;\n\tretval = target_read_u32(rtos->target, task + rtos->symbols[sym___off_task2name].address, &name);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read task name pointer from target\");\n\t\treturn retval;\n\t}\n\tuint8_t tmp_str[33];\n\tretval = target_read_buffer(rtos->target, name, sizeof(tmp_str) - 1, tmp_str);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading task name from target\");\n\t\treturn retval;\n\t}\n\ttmp_str[sizeof(tmp_str) - 1] = '\\0';\n\tLOG_DEBUG(\"task name at 0x%\" PRIx32 \", value \\\"%s\\\"\", name, tmp_str);\n\n\tif (tmp_str[0] != '\\0')\n\t\tthread->thread_name_str = strdup((char *)tmp_str);\n\telse\n\t\tthread->thread_name_str = strdup(\"No Name\");\n\n\t/* Read the task state */\n\tuint16_t state;\n\tretval = target_read_u16(rtos->target, task + rtos->symbols[sym___off_task2state].address, &state);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read task state from target\");\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"task state 0x%\" PRIx16, state);\n\n\tchar state_str[64] = \"\";\n\tif (state & ST_TT)\n\t\tstrcat(state_str, \"TT|\");\n\tif (task == current_task) {\n\t\tstrcat(state_str, \"RUN\");\n\t} else {\n\t\tif (state & (ST_TT | ST_TT_YIELD))\n\t\t\tstrcat(state_str, \"YIELD\");\n\t\telse if (state & ST_DEAD)\n\t\t\tstrcat(state_str, \"DEAD\");\n\t\telse if (state & ST_WAIT)\n\t\t\tstrcat(state_str, \"WAIT\");\n\t\telse if (state & ST_SUSPEND)\n\t\t\tstrcat(state_str, \"SUSP\");\n\t\telse\n\t\t\tstrcat(state_str, \"READY\");\n\t}\n\tif (state & ST_SEM)\n\t\tstrcat(state_str, \"|SEM\");\n\tif (state & ST_MTX)\n\t\tstrcat(state_str, \"|MTX\");\n\tif (state & ST_SIG)\n\t\tstrcat(state_str, \"|SIG\");\n\tif (state & ST_DLY)\n\t\tstrcat(state_str, \"|DLY\");\n\tif ((state & ST_FLAG) || (state & ST_FLAG_ALL))\n\t\tstrcat(state_str, \"|FLAG\");\n\tif (state & ST_FLAG_ALL)\n\t\tstrcat(state_str, \"_ALL\");\n\tif (state & ST_MBOX)\n\t\tstrcat(state_str, \"|MBOX\");\n\tif (state & ST_STP)\n\t\tstrcat(state_str, \"|STP\");\n\n\tthread->extra_info_str = strdup(state_str);\n\n\trtos->thread_count = new_thread_count;\n\tif (task == current_task)\n\t\trtos->current_thread = task;\n\treturn ERROR_OK;\n}\n\nstatic int rtkernel_verify_task(struct rtos *rtos, uint32_t task)\n{\n\tint retval;\n\tuint32_t magic;\n\tretval = target_read_u32(rtos->target, task + rtos->symbols[sym___off_task2magic].address, &magic);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not read task magic from target\");\n\t\treturn retval;\n\t}\n\tif (magic != rtos->symbols[sym___val_task_magic].address) {\n\t\tLOG_ERROR(\"Invalid task found (magic=0x%\" PRIx32 \")\", magic);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn retval;\n}\n\nstatic int rtkernel_update_threads(struct rtos *rtos)\n{\n\t/* wipe out previous thread details if any */\n\t/* do this first because rtos layer does not check our retval */\n\trtos_free_threadlist(rtos);\n\trtos->current_thread = 0;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for rt-kernel\");\n\t\treturn -3;\n\t}\n\n\t/* read the current task */\n\tuint32_t current_task;\n\tint retval = target_read_u32(rtos->target,\n\t\t\trtos->symbols[sym_os_state].address + rtos->symbols[sym___off_os_state2current].address,\n\t\t\t&current_task);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading current task\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"current task is 0x%\" PRIx32, current_task);\n\n\tretval = rtkernel_verify_task(rtos, current_task);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Current task is invalid\");\n\t\treturn retval;\n\t}\n\n\t/* loop through kernel task list */\n\tuint32_t chain = rtos->symbols[sym_os_state].address + rtos->symbols[sym___off_os_state2chain].address;\n\tLOG_DEBUG(\"chain start at 0x%\" PRIx32, chain);\n\n\tuint32_t next = chain;\n\tfor (;;) {\n\t\tretval = target_read_u32(rtos->target, next, &next);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read rt-kernel data structure from target\");\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"next entry at 0x%\" PRIx32, next);\n\t\tif (next == chain) {\n\t\t\tLOG_DEBUG(\"end of chain detected\");\n\t\t\tbreak;\n\t\t}\n\t\tuint32_t task = next - rtos->symbols[sym___off_task2chain].address;\n\t\tLOG_DEBUG(\"found task at 0x%\" PRIx32, task);\n\n\t\tretval = rtkernel_verify_task(rtos, task);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Invalid task found\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tretval = rtkernel_add_task(rtos, task, current_task);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not add task to rtos system\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int rtkernel_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tuint32_t stack_ptr = 0;\n\n\tif (!rtos)\n\t\treturn -1;\n\n\tif (thread_id == 0)\n\t\treturn -2;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn -1;\n\n\tconst struct rtkernel_params *param = rtos->rtos_specific_params;\n\n\t/* Read the stack pointer */\n\tint retval = target_read_u32(rtos->target, thread_id + rtos->symbols[sym___off_task2stack].address, &stack_ptr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error reading stack pointer from rtkernel thread\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"stack pointer at 0x%\" PRIx64 \", value 0x%\" PRIx32,\n\t\t\tthread_id + rtos->symbols[sym___off_task2stack].address,\n\t\t\tstack_ptr);\n\n\t/* Adjust stack pointer to ignore non-standard BASEPRI register stacking */\n\tstack_ptr += 4;\n\n\t/* Check for armv7m with *enabled* FPU, i.e. a Cortex M4F */\n\tbool cm4_fpu_enabled = false;\n\tstruct armv7m_common *armv7m_target = target_to_armv7m(rtos->target);\n\tif (is_armv7m(armv7m_target)) {\n\t\tif (armv7m_target->fp_feature != FP_NONE) {\n\t\t\t/* Found ARM v7m target which includes a FPU */\n\t\t\tuint32_t cpacr;\n\n\t\t\tretval = target_read_u32(rtos->target, FPU_CPACR, &cpacr);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not read CPACR register to check FPU state\");\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t/* Check if CP10 and CP11 are set to full access. */\n\t\t\tif (cpacr & 0x00F00000) {\n\t\t\t\t/* Found target with enabled FPU */\n\t\t\t\tcm4_fpu_enabled = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!cm4_fpu_enabled) {\n\t\tLOG_DEBUG(\"cm3 stacking\");\n\t\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm3, stack_ptr, reg_list, num_regs);\n\t}\n\n\t/* Read the LR to decide between stacking with or without FPU */\n\tuint32_t lr_svc;\n\tretval = target_read_u32(rtos->target, stack_ptr + 0x20, &lr_svc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_OUTPUT(\"Error reading stack frame from rtkernel thread\\r\\n\");\n\t\treturn retval;\n\t}\n\n\tif ((lr_svc & 0x10) == 0) {\n\t\tLOG_DEBUG(\"cm4f_fpu stacking\");\n\t\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f_fpu, stack_ptr, reg_list, num_regs);\n\t}\n\n\tLOG_DEBUG(\"cm4f stacking\");\n\treturn rtos_generic_stack_read(rtos->target, param->stacking_info_cm4f, stack_ptr, reg_list, num_regs);\n}\n\nstatic int rtkernel_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = calloc(ARRAY_SIZE(rtkernel_symbol_list), sizeof(struct symbol_table_elem));\n\tif (!*symbol_list)\n\t\treturn ERROR_FAIL;\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(rtkernel_symbol_list); i++) {\n\t\t(*symbol_list)[i].symbol_name = rtkernel_symbol_list[i].name;\n\t\t(*symbol_list)[i].optional = rtkernel_symbol_list[i].optional;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic bool rtkernel_detect_rtos(struct target *target)\n{\n\treturn (target->rtos->symbols) &&\n\t\t\t(target->rtos->symbols[sym___off_os_state2chain].address != 0);\n}\n\nstatic int rtkernel_create(struct target *target)\n{\n\tfor (size_t i = 0; i < ARRAY_SIZE(rtkernel_params_list); i++) {\n\t\tif (strcmp(rtkernel_params_list[i].target_name, target->type->name) == 0) {\n\t\t\ttarget->rtos->rtos_specific_params = (void *)&rtkernel_params_list[i];\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"Could not find target in rt-kernel compatibility list\");\n\treturn -1;\n}\n\nconst struct rtos_type rtkernel_rtos = {\n\t.name = \"rtkernel\",\n\n\t.detect_rtos = rtkernel_detect_rtos,\n\t.create = rtkernel_create,\n\t.update_threads = rtkernel_update_threads,\n\t.get_thread_reg_list = rtkernel_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = rtkernel_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/target.h\"\n#include \"helper/log.h\"\n#include \"helper/binarybuffer.h\"\n#include \"server/gdb_server.h\"\n\nstatic const struct rtos_type *rtos_types[] = {\n\t&threadx_rtos,\n\t&freertos_rtos,\n\t&ecos_rtos,\n\t&linux_rtos,\n\t&chibios_rtos,\n\t&chromium_ec_rtos,\n\t&embkernel_rtos,\n\t&mqx_rtos,\n\t&ucos_iii_rtos,\n\t&nuttx_rtos,\n\t&riot_rtos,\n\t&zephyr_rtos,\n\t&rtkernel_rtos,\n\t/* keep this as last, as it always matches with rtos auto */\n\t&hwthread_rtos,\n\tNULL\n};\n\nstatic int rtos_try_next(struct target *target);\n\nint rtos_smp_init(struct target *target)\n{\n\tif (target->rtos->type->smp_init)\n\t\treturn target->rtos->type->smp_init(target);\n\treturn ERROR_TARGET_INIT_FAILED;\n}\n\nstatic int rtos_target_for_threadid(struct connection *connection, int64_t threadid, struct target **t)\n{\n\tstruct target *curr = get_target_from_connection(connection);\n\tif (t)\n\t\t*t = curr;\n\n\treturn ERROR_OK;\n}\n\nstatic int os_alloc(struct target *target, const struct rtos_type *ostype)\n{\n\tstruct rtos *os = target->rtos = calloc(1, sizeof(struct rtos));\n\n\tif (!os)\n\t\treturn JIM_ERR;\n\n\tos->type = ostype;\n\tos->current_threadid = -1;\n\tos->current_thread = 0;\n\tos->symbols = NULL;\n\tos->target = target;\n\n\t/* RTOS drivers can override the packet handler in _create(). */\n\tos->gdb_thread_packet = rtos_thread_packet;\n\tos->gdb_target_for_threadid = rtos_target_for_threadid;\n\n\treturn JIM_OK;\n}\n\nstatic void os_free(struct target *target)\n{\n\tif (!target->rtos)\n\t\treturn;\n\n\tfree(target->rtos->symbols);\n\tfree(target->rtos);\n\ttarget->rtos = NULL;\n}\n\nstatic int os_alloc_create(struct target *target, const struct rtos_type *ostype)\n{\n\tint ret = os_alloc(target, ostype);\n\n\tif (ret == JIM_OK) {\n\t\tret = target->rtos->type->create(target);\n\t\tif (ret != JIM_OK)\n\t\t\tos_free(target);\n\t}\n\n\treturn ret;\n}\n\nint rtos_create(struct jim_getopt_info *goi, struct target *target)\n{\n\tint x;\n\tconst char *cp;\n\tJim_Obj *res;\n\tint e;\n\n\tif (!goi->isconfigure && goi->argc != 0) {\n\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"NO PARAMS\");\n\t\treturn JIM_ERR;\n\t}\n\n\tos_free(target);\n\n\te = jim_getopt_string(goi, &cp, NULL);\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\tif (strcmp(cp, \"none\") == 0)\n\t\treturn JIM_OK;\n\n\tif (strcmp(cp, \"auto\") == 0) {\n\t\t/* Auto detect tries to look up all symbols for each RTOS,\n\t\t * and runs the RTOS driver's _detect() function when GDB\n\t\t * finds all symbols for any RTOS. See rtos_qsymbol(). */\n\t\ttarget->rtos_auto_detect = true;\n\n\t\t/* rtos_qsymbol() will iterate over all RTOSes. Allocate\n\t\t * target->rtos here, and set it to the first RTOS type. */\n\t\treturn os_alloc(target, rtos_types[0]);\n\t}\n\n\tfor (x = 0; rtos_types[x]; x++)\n\t\tif (strcmp(cp, rtos_types[x]->name) == 0)\n\t\t\treturn os_alloc_create(target, rtos_types[x]);\n\n\tJim_SetResultFormatted(goi->interp, \"Unknown RTOS type %s, try one of: \", cp);\n\tres = Jim_GetResult(goi->interp);\n\tfor (x = 0; rtos_types[x]; x++)\n\t\tJim_AppendStrings(goi->interp, res, rtos_types[x]->name, \", \", NULL);\n\tJim_AppendStrings(goi->interp, res, \", auto or none\", NULL);\n\n\treturn JIM_ERR;\n}\n\nvoid rtos_destroy(struct target *target)\n{\n\tos_free(target);\n}\n\nint gdb_thread_packet(struct connection *connection, char const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tif (!target->rtos)\n\t\treturn rtos_thread_packet(connection, packet, packet_size);\t/* thread not\n\t\t\t\t\t\t\t\t\t\t *found*/\n\treturn target->rtos->gdb_thread_packet(connection, packet, packet_size);\n}\n\nstatic struct symbol_table_elem *find_symbol(const struct rtos *os, const char *symbol)\n{\n\tstruct symbol_table_elem *s;\n\n\tfor (s = os->symbols; s->symbol_name; s++)\n\t\tif (!strcmp(s->symbol_name, symbol))\n\t\t\treturn s;\n\n\treturn NULL;\n}\n\nstatic struct symbol_table_elem *next_symbol(struct rtos *os, char *cur_symbol, uint64_t cur_addr)\n{\n\tif (!os->symbols)\n\t\tos->type->get_symbol_list_to_lookup(&os->symbols);\n\n\tif (!cur_symbol[0])\n\t\treturn &os->symbols[0];\n\n\tstruct symbol_table_elem *s = find_symbol(os, cur_symbol);\n\tif (!s)\n\t\treturn NULL;\n\n\ts->address = cur_addr;\n\ts++;\n\treturn s;\n}\n\n/* rtos_qsymbol() processes and replies to all qSymbol packets from GDB.\n *\n * GDB sends a qSymbol:: packet (empty address, empty name) to notify\n * that it can now answer qSymbol::hexcodedname queries, to look up symbols.\n *\n * If the qSymbol packet has no address that means GDB did not find the\n * symbol, in which case auto-detect will move on to try the next RTOS.\n *\n * rtos_qsymbol() then calls the next_symbol() helper function, which\n * iterates over symbol names for the current RTOS until it finds the\n * symbol in the received GDB packet, and then returns the next entry\n * in the list of symbols.\n *\n * If GDB replied about the last symbol for the RTOS and the RTOS was\n * specified explicitly, then no further symbol lookup is done. When\n * auto-detecting, the RTOS driver _detect() function must return success.\n *\n * The symbol is tried twice to handle the -flto case with gcc.  The first\n * attempt uses the symbol as-is, and the second attempt tries the symbol\n * with \".lto_priv.0\" appended to it.  We only consider the first static\n * symbol here from the -flto case.  (Each subsequent static symbol with\n * the same name is exported as .lto_priv.1, .lto_priv.2, etc.)\n *\n * rtos_qsymbol() returns 1 if an RTOS has been detected, or 0 otherwise.\n */\nint rtos_qsymbol(struct connection *connection, char const *packet, int packet_size)\n{\n\tint rtos_detected = 0;\n\tuint64_t addr = 0;\n\tsize_t reply_len;\n\tchar reply[GDB_BUFFER_SIZE + 1], cur_sym[GDB_BUFFER_SIZE / 2 + 1] = \"\"; /* Extra byte for null-termination */\n\tstruct symbol_table_elem *next_sym = NULL;\n\tstruct target *target = get_target_from_connection(connection);\n\tstruct rtos *os = target->rtos;\n\n\treply_len = sprintf(reply, \"OK\");\n\n\tif (!os)\n\t\tgoto done;\n\n\t/* Decode any symbol name in the packet*/\n\tsize_t len = unhexify((uint8_t *)cur_sym, strchr(packet + 8, ':') + 1, strlen(strchr(packet + 8, ':') + 1));\n\tcur_sym[len] = 0;\n\n\tconst char no_suffix[] = \"\";\n\tconst char lto_suffix[] = \".lto_priv.0\";\n\tconst size_t lto_suffix_len = strlen(lto_suffix);\n\n\tconst char *cur_suffix;\n\tconst char *next_suffix;\n\n\t/* Detect what suffix was used during the previous symbol lookup attempt, and\n\t * speculatively determine the next suffix (only used for the unknown address case) */\n\tif (len > lto_suffix_len && !strcmp(cur_sym + len - lto_suffix_len, lto_suffix)) {\n\t\t/* Trim the suffix from cur_sym for comparison purposes below */\n\t\tcur_sym[len - lto_suffix_len] = '\\0';\n\t\tcur_suffix = lto_suffix;\n\t\tnext_suffix = NULL;\n\t} else {\n\t\tcur_suffix = no_suffix;\n\t\tnext_suffix = lto_suffix;\n\t}\n\n\tif ((strcmp(packet, \"qSymbol::\") != 0) &&               /* GDB is not offering symbol lookup for the first time */\n\t    (!sscanf(packet, \"qSymbol:%\" SCNx64 \":\", &addr))) { /* GDB did not find an address for a symbol */\n\n\t\t/* GDB could not find an address for the previous symbol */\n\t\tstruct symbol_table_elem *sym = find_symbol(os, cur_sym);\n\n\t\tif (next_suffix) {\n\t\t\tnext_sym = sym;\n\t\t} else if (sym && !sym->optional) {\t/* the symbol is mandatory for this RTOS */\n\t\t\tif (!target->rtos_auto_detect) {\n\t\t\t\tLOG_WARNING(\"RTOS %s not detected. (GDB could not find symbol \\'%s\\')\", os->type->name, cur_sym);\n\t\t\t\tgoto done;\n\t\t\t} else {\n\t\t\t\t/* Autodetecting RTOS - try next RTOS */\n\t\t\t\tif (!rtos_try_next(target)) {\n\t\t\t\t\tLOG_WARNING(\"No RTOS could be auto-detected!\");\n\t\t\t\t\tgoto done;\n\t\t\t\t}\n\n\t\t\t\t/* Next RTOS selected - invalidate current symbol */\n\t\t\t\tcur_sym[0] = '\\x00';\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"RTOS: Address of symbol '%s%s' is 0x%\" PRIx64, cur_sym, cur_suffix, addr);\n\n\tif (!next_sym) {\n\t\tnext_sym = next_symbol(os, cur_sym, addr);\n\t\tnext_suffix = no_suffix;\n\t}\n\n\t/* Should never happen unless the debugger misbehaves */\n\tif (!next_sym) {\n\t\tLOG_WARNING(\"RTOS: Debugger sent us qSymbol with '%s%s' that we did not ask for\", cur_sym, cur_suffix);\n\t\tgoto done;\n\t}\n\n\tif (!next_sym->symbol_name) {\n\t\t/* No more symbols need looking up */\n\n\t\tif (!target->rtos_auto_detect) {\n\t\t\trtos_detected = 1;\n\t\t\tgoto done;\n\t\t}\n\n\t\tif (os->type->detect_rtos(target)) {\n\t\t\tLOG_INFO(\"Auto-detected RTOS: %s\", os->type->name);\n\t\t\trtos_detected = 1;\n\t\t\tgoto done;\n\t\t} else {\n\t\t\tLOG_WARNING(\"No RTOS could be auto-detected!\");\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\tassert(next_suffix);\n\n\treply_len = 8;                                   /* snprintf(..., \"qSymbol:\") */\n\treply_len += 2 * strlen(next_sym->symbol_name);  /* hexify(..., next_sym->symbol_name, ...) */\n\treply_len += 2 * strlen(next_suffix);            /* hexify(..., next_suffix, ...) */\n\treply_len += 1;                                  /* Terminating NUL */\n\tif (reply_len > sizeof(reply)) {\n\t\tLOG_ERROR(\"ERROR: RTOS symbol '%s%s' name is too long for GDB!\", next_sym->symbol_name, next_suffix);\n\t\tgoto done;\n\t}\n\n\tLOG_DEBUG(\"RTOS: Requesting symbol lookup of '%s%s' from the debugger\", next_sym->symbol_name, next_suffix);\n\n\treply_len = snprintf(reply, sizeof(reply), \"qSymbol:\");\n\treply_len += hexify(reply + reply_len,\n\t\t(const uint8_t *)next_sym->symbol_name, strlen(next_sym->symbol_name),\n\t\tsizeof(reply) - reply_len);\n\treply_len += hexify(reply + reply_len,\n\t\t(const uint8_t *)next_suffix, strlen(next_suffix),\n\t\tsizeof(reply) - reply_len);\n\ndone:\n\tgdb_put_packet(connection, reply, reply_len);\n\treturn rtos_detected;\n}\n\nint rtos_thread_packet(struct connection *connection, char const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\n\tif (strncmp(packet, \"qThreadExtraInfo,\", 17) == 0) {\n\t\tif ((target->rtos) && (target->rtos->thread_details) &&\n\t\t\t\t(target->rtos->thread_count != 0)) {\n\t\t\tthreadid_t threadid = 0;\n\t\t\tint found = -1;\n\t\t\tsscanf(packet, \"qThreadExtraInfo,%\" SCNx64, &threadid);\n\n\t\t\tif ((target->rtos) && (target->rtos->thread_details)) {\n\t\t\t\tint thread_num;\n\t\t\t\tfor (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {\n\t\t\t\t\tif (target->rtos->thread_details[thread_num].threadid == threadid) {\n\t\t\t\t\t\tif (target->rtos->thread_details[thread_num].exists)\n\t\t\t\t\t\t\tfound = thread_num;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (found == -1) {\n\t\t\t\tgdb_put_packet(connection, \"E01\", 3);\t/* thread not found */\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\n\t\t\tstruct thread_detail *detail = &target->rtos->thread_details[found];\n\n\t\t\tint str_size = 0;\n\t\t\tif (detail->thread_name_str)\n\t\t\t\tstr_size += strlen(detail->thread_name_str);\n\t\t\tif (detail->extra_info_str)\n\t\t\t\tstr_size += strlen(detail->extra_info_str);\n\n\t\t\tchar *tmp_str = calloc(str_size + 9, sizeof(char));\n\t\t\tchar *tmp_str_ptr = tmp_str;\n\n\t\t\tif (detail->thread_name_str)\n\t\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \"Name: %s\", detail->thread_name_str);\n\t\t\tif (detail->extra_info_str) {\n\t\t\t\tif (tmp_str_ptr != tmp_str)\n\t\t\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \", \");\n\t\t\t\ttmp_str_ptr += sprintf(tmp_str_ptr, \"%s\", detail->extra_info_str);\n\t\t\t}\n\n\t\t\tassert(strlen(tmp_str) ==\n\t\t\t\t(size_t) (tmp_str_ptr - tmp_str));\n\n\t\t\tchar *hex_str = malloc(strlen(tmp_str) * 2 + 1);\n\t\t\tsize_t pkt_len = hexify(hex_str, (const uint8_t *)tmp_str,\n\t\t\t\tstrlen(tmp_str), strlen(tmp_str) * 2 + 1);\n\n\t\t\tgdb_put_packet(connection, hex_str, pkt_len);\n\t\t\tfree(hex_str);\n\t\t\tfree(tmp_str);\n\t\t\treturn ERROR_OK;\n\n\t\t}\n\t\tgdb_put_packet(connection, \"\", 0);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qSymbol\", 7) == 0) {\n\t\tif (rtos_qsymbol(connection, packet, packet_size) == 1) {\n\t\t\tif (target->rtos_auto_detect == true) {\n\t\t\t\ttarget->rtos_auto_detect = false;\n\t\t\t\ttarget->rtos->type->create(target);\n\t\t\t}\n\t\t\ttarget->rtos->type->update_threads(target->rtos);\n\t\t}\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qfThreadInfo\", 12) == 0) {\n\t\tint i;\n\t\tif (target->rtos) {\n\t\t\tif (target->rtos->thread_count == 0) {\n\t\t\t\tgdb_put_packet(connection, \"l\", 1);\n\t\t\t} else {\n\t\t\t\t/*thread id are 16 char +1 for ',' */\n\t\t\t\tchar *out_str = malloc(17 * target->rtos->thread_count + 1);\n\t\t\t\tchar *tmp_str = out_str;\n\t\t\t\tfor (i = 0; i < target->rtos->thread_count; i++) {\n\t\t\t\t\ttmp_str += sprintf(tmp_str, \"%c%016\" PRIx64, i == 0 ? 'm' : ',',\n\t\t\t\t\t\t\t\t\t\ttarget->rtos->thread_details[i].threadid);\n\t\t\t\t}\n\t\t\t\tgdb_put_packet(connection, out_str, strlen(out_str));\n\t\t\t\tfree(out_str);\n\t\t\t}\n\t\t} else\n\t\t\tgdb_put_packet(connection, \"l\", 1);\n\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qsThreadInfo\", 12) == 0) {\n\t\tgdb_put_packet(connection, \"l\", 1);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qAttached\", 9) == 0) {\n\t\tgdb_put_packet(connection, \"1\", 1);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qOffsets\", 8) == 0) {\n\t\tchar offsets[] = \"Text=0;Data=0;Bss=0\";\n\t\tgdb_put_packet(connection, offsets, sizeof(offsets)-1);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qCRC:\", 5) == 0) {\n\t\t/* make sure we check this before \"qC\" packet below\n\t\t * otherwise it gets incorrectly handled */\n\t\treturn GDB_THREAD_PACKET_NOT_CONSUMED;\n\t} else if (strncmp(packet, \"qC\", 2) == 0) {\n\t\tif (target->rtos) {\n\t\t\tchar buffer[19];\n\t\t\tint size;\n\t\t\tsize = snprintf(buffer, 19, \"QC%016\" PRIx64, target->rtos->current_thread);\n\t\t\tgdb_put_packet(connection, buffer, size);\n\t\t} else\n\t\t\tgdb_put_packet(connection, \"QC0\", 3);\n\t\treturn ERROR_OK;\n\t} else if (packet[0] == 'T') {\t/* Is thread alive? */\n\t\tthreadid_t threadid;\n\t\tint found = -1;\n\t\tsscanf(packet, \"T%\" SCNx64, &threadid);\n\t\tif ((target->rtos) && (target->rtos->thread_details)) {\n\t\t\tint thread_num;\n\t\t\tfor (thread_num = 0; thread_num < target->rtos->thread_count; thread_num++) {\n\t\t\t\tif (target->rtos->thread_details[thread_num].threadid == threadid) {\n\t\t\t\t\tif (target->rtos->thread_details[thread_num].exists)\n\t\t\t\t\t\tfound = thread_num;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (found != -1)\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\t/* thread alive */\n\t\telse\n\t\t\tgdb_put_packet(connection, \"E01\", 3);\t/* thread not found */\n\t\treturn ERROR_OK;\n\t} else if (packet[0] == 'H') {\t/* Set current thread ( 'c' for step and continue, 'g' for\n\t\t\t\t\t * all other operations ) */\n\t\tif ((packet[1] == 'g') && (target->rtos)) {\n\t\t\tthreadid_t threadid;\n\t\t\tsscanf(packet, \"Hg%16\" SCNx64, &threadid);\n\t\t\tLOG_DEBUG(\"RTOS: GDB requested to set current thread to 0x%\" PRIx64, threadid);\n\t\t\t/* threadid of 0 indicates target should choose */\n\t\t\tif (threadid == 0)\n\t\t\t\ttarget->rtos->current_threadid = target->rtos->current_thread;\n\t\t\telse\n\t\t\t\ttarget->rtos->current_threadid = threadid;\n\t\t}\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn GDB_THREAD_PACKET_NOT_CONSUMED;\n}\n\nstatic int rtos_put_gdb_reg_list(struct connection *connection,\n\t\tstruct rtos_reg *reg_list, int num_regs)\n{\n\tsize_t num_bytes = 1; /* NUL */\n\tfor (int i = 0; i < num_regs; ++i)\n\t\tnum_bytes += DIV_ROUND_UP(reg_list[i].size, 8) * 2;\n\n\tchar *hex = malloc(num_bytes);\n\tchar *hex_p = hex;\n\n\tfor (int i = 0; i < num_regs; ++i) {\n\t\tsize_t count = DIV_ROUND_UP(reg_list[i].size, 8);\n\t\tsize_t n = hexify(hex_p, reg_list[i].value, count, num_bytes);\n\t\thex_p += n;\n\t\tnum_bytes -= n;\n\t}\n\n\tgdb_put_packet(connection, hex, strlen(hex));\n\tfree(hex);\n\n\treturn ERROR_OK;\n}\n\n/** Look through all registers to find this register. */\nint rtos_get_gdb_reg(struct connection *connection, int reg_num)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint64_t current_threadid = target->rtos->current_threadid;\n\tif ((target->rtos) && (current_threadid != -1) &&\n\t\t\t(current_threadid != 0) &&\n\t\t\t((current_threadid != target->rtos->current_thread) ||\n\t\t\t(target->smp))) {\t/* in smp several current thread are possible */\n\t\tstruct rtos_reg *reg_list;\n\t\tint num_regs;\n\n\t\tLOG_DEBUG(\"getting register %d for thread 0x%\" PRIx64\n\t\t\t\t  \", target->rtos->current_thread=0x%\" PRIx64,\n\t\t\t\t\t\t\t\t\t\treg_num,\n\t\t\t\t\t\t\t\t\t\tcurrent_threadid,\n\t\t\t\t\t\t\t\t\t\ttarget->rtos->current_thread);\n\n\t\tint retval;\n\t\tif (target->rtos->type->get_thread_reg) {\n\t\t\treg_list = calloc(1, sizeof(*reg_list));\n\t\t\tnum_regs = 1;\n\t\t\tretval = target->rtos->type->get_thread_reg(target->rtos,\n\t\t\t\t\tcurrent_threadid, reg_num, &reg_list[0]);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"RTOS: failed to get register %d\", reg_num);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tretval = target->rtos->type->get_thread_reg_list(target->rtos,\n\t\t\t\t\tcurrent_threadid,\n\t\t\t\t\t&reg_list,\n\t\t\t\t\t&num_regs);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"RTOS: failed to get register list\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\tfor (int i = 0; i < num_regs; ++i) {\n\t\t\tif (reg_list[i].number == (uint32_t)reg_num) {\n\t\t\t\trtos_put_gdb_reg_list(connection, reg_list + i, 1);\n\t\t\t\tfree(reg_list);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\n\t\tfree(reg_list);\n\t}\n\treturn ERROR_FAIL;\n}\n\n/** Return a list of general registers. */\nint rtos_get_gdb_reg_list(struct connection *connection)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint64_t current_threadid = target->rtos->current_threadid;\n\tif ((target->rtos) && (current_threadid != -1) &&\n\t\t\t(current_threadid != 0) &&\n\t\t\t((current_threadid != target->rtos->current_thread) ||\n\t\t\t(target->smp))) {\t/* in smp several current thread are possible */\n\t\tstruct rtos_reg *reg_list;\n\t\tint num_regs;\n\n\t\tLOG_DEBUG(\"RTOS: getting register list for thread 0x%\" PRIx64\n\t\t\t\t  \", target->rtos->current_thread=0x%\" PRIx64 \"\\r\\n\",\n\t\t\t\t\t\t\t\t\t\tcurrent_threadid,\n\t\t\t\t\t\t\t\t\t\ttarget->rtos->current_thread);\n\n\t\tint retval = target->rtos->type->get_thread_reg_list(target->rtos,\n\t\t\t\tcurrent_threadid,\n\t\t\t\t&reg_list,\n\t\t\t\t&num_regs);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"RTOS: failed to get register list\");\n\t\t\treturn retval;\n\t\t}\n\n\t\trtos_put_gdb_reg_list(connection, reg_list, num_regs);\n\t\tfree(reg_list);\n\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_FAIL;\n}\n\nint rtos_set_reg(struct connection *connection, int reg_num,\n\t\tuint8_t *reg_value)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint64_t current_threadid = target->rtos->current_threadid;\n\tif ((target->rtos) &&\n\t\t\t(target->rtos->type->set_reg) &&\n\t\t\t(current_threadid != -1) &&\n\t\t\t(current_threadid != 0)) {\n\t\treturn target->rtos->type->set_reg(target->rtos, reg_num, reg_value);\n\t}\n\treturn ERROR_FAIL;\n}\n\nint rtos_generic_stack_read(struct target *target,\n\tconst struct rtos_register_stacking *stacking,\n\tint64_t stack_ptr,\n\tstruct rtos_reg **reg_list,\n\tint *num_regs)\n{\n\tint retval;\n\n\tif (stack_ptr == 0) {\n\t\tLOG_ERROR(\"Error: null stack pointer in thread\");\n\t\treturn -5;\n\t}\n\t/* Read the stack */\n\tuint8_t *stack_data = malloc(stacking->stack_registers_size);\n\tuint32_t address = stack_ptr;\n\n\tif (stacking->stack_growth_direction == 1)\n\t\taddress -= stacking->stack_registers_size;\n\tif (stacking->read_stack)\n\t\tretval = stacking->read_stack(target, address, stacking, stack_data);\n\telse\n\t\tretval = target_read_buffer(target, address, stacking->stack_registers_size, stack_data);\n\tif (retval != ERROR_OK) {\n\t\tfree(stack_data);\n\t\tLOG_ERROR(\"Error reading stack frame from thread\");\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"RTOS: Read stack frame at 0x%\" PRIx32, address);\n\n#if 0\n\t\tLOG_OUTPUT(\"Stack Data :\");\n\t\tfor (i = 0; i < stacking->stack_registers_size; i++)\n\t\t\tLOG_OUTPUT(\"%02X\", stack_data[i]);\n\t\tLOG_OUTPUT(\"\\r\\n\");\n#endif\n\n\ttarget_addr_t new_stack_ptr;\n\tif (stacking->calculate_process_stack) {\n\t\tnew_stack_ptr = stacking->calculate_process_stack(target,\n\t\t\t\tstack_data, stacking, stack_ptr);\n\t} else {\n\t\tnew_stack_ptr = stack_ptr - stacking->stack_growth_direction *\n\t\t\tstacking->stack_registers_size;\n\t}\n\n\t*reg_list = calloc(stacking->num_output_registers, sizeof(struct rtos_reg));\n\t*num_regs = stacking->num_output_registers;\n\n\tfor (int i = 0; i < stacking->num_output_registers; ++i) {\n\t\t(*reg_list)[i].number = stacking->register_offsets[i].number;\n\t\t(*reg_list)[i].size = stacking->register_offsets[i].width_bits;\n\n\t\tint offset = stacking->register_offsets[i].offset;\n\t\tif (offset == -2)\n\t\t\tbuf_cpy(&new_stack_ptr, (*reg_list)[i].value, (*reg_list)[i].size);\n\t\telse if (offset != -1)\n\t\t\tbuf_cpy(stack_data + offset, (*reg_list)[i].value, (*reg_list)[i].size);\n\t}\n\n\tfree(stack_data);\n/*\tLOG_OUTPUT(\"Output register string: %s\\r\\n\", *hex_reg_list); */\n\treturn ERROR_OK;\n}\n\nstatic int rtos_try_next(struct target *target)\n{\n\tstruct rtos *os = target->rtos;\n\tconst struct rtos_type **type = rtos_types;\n\n\tif (!os)\n\t\treturn 0;\n\n\twhile (*type && os->type != *type)\n\t\ttype++;\n\n\tif (!*type || !*(++type))\n\t\treturn 0;\n\n\tos->type = *type;\n\n\tfree(os->symbols);\n\tos->symbols = NULL;\n\n\treturn 1;\n}\n\nint rtos_update_threads(struct target *target)\n{\n\tif ((target->rtos) && (target->rtos->type))\n\t\ttarget->rtos->type->update_threads(target->rtos);\n\treturn ERROR_OK;\n}\n\nvoid rtos_free_threadlist(struct rtos *rtos)\n{\n\tif (rtos->thread_details) {\n\t\tint j;\n\n\t\tfor (j = 0; j < rtos->thread_count; j++) {\n\t\t\tstruct thread_detail *current_thread = &rtos->thread_details[j];\n\t\t\tfree(current_thread->thread_name_str);\n\t\t\tfree(current_thread->extra_info_str);\n\t\t}\n\t\tfree(rtos->thread_details);\n\t\trtos->thread_details = NULL;\n\t\trtos->thread_count = 0;\n\t\trtos->current_threadid = -1;\n\t\trtos->current_thread = 0;\n\t}\n}\n\nint rtos_read_buffer(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer)\n{\n\tif (target->rtos->type->read_buffer)\n\t\treturn target->rtos->type->read_buffer(target->rtos, address, size, buffer);\n\treturn ERROR_NOT_IMPLEMENTED;\n}\n\nint rtos_write_buffer(struct target *target, target_addr_t address,\n\t\tuint32_t size, const uint8_t *buffer)\n{\n\tif (target->rtos->type->write_buffer)\n\t\treturn target->rtos->type->write_buffer(target->rtos, address, size, buffer);\n\treturn ERROR_NOT_IMPLEMENTED;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_H\n#define OPENOCD_RTOS_RTOS_H\n\n#include \"server/server.h\"\n#include \"target/target.h\"\n#include <helper/jim-nvp.h>\n\ntypedef int64_t threadid_t;\ntypedef int64_t symbol_address_t;\n\nstruct reg;\n\n/**\n * Table should be terminated by an element with NULL in symbol_name\n */\nstruct symbol_table_elem {\n\tconst char *symbol_name;\n\tsymbol_address_t address;\n\tbool optional;\n};\n\nstruct thread_detail {\n\tthreadid_t threadid;\n\tbool exists;\n\tchar *thread_name_str;\n\tchar *extra_info_str;\n};\n\nstruct rtos {\n\tconst struct rtos_type *type;\n\n\tstruct symbol_table_elem *symbols;\n\tstruct target *target;\n\t/*  add a context variable instead of global variable */\n\t/* The thread currently selected by gdb. */\n\tint64_t current_threadid;\n\t/* The currently selected thread according to the target. */\n\tthreadid_t current_thread;\n\tstruct thread_detail *thread_details;\n\tint thread_count;\n\tint (*gdb_thread_packet)(struct connection *connection, char const *packet, int packet_size);\n\tint (*gdb_target_for_threadid)(struct connection *connection, int64_t thread_id, struct target **p_target);\n\tvoid *rtos_specific_params;\n};\n\nstruct rtos_reg {\n\tuint32_t number;\n\tuint32_t size;\n\tuint8_t value[16];\n};\n\nstruct rtos_type {\n\tconst char *name;\n\tbool (*detect_rtos)(struct target *target);\n\tint (*create)(struct target *target);\n\tint (*smp_init)(struct target *target);\n\tint (*update_threads)(struct rtos *rtos);\n\t/** Return a list of general registers, with their values filled out. */\n\tint (*get_thread_reg_list)(struct rtos *rtos, int64_t thread_id,\n\t\t\tstruct rtos_reg **reg_list, int *num_regs);\n\tint (*get_thread_reg)(struct rtos *rtos, int64_t thread_id,\n\t\t\tuint32_t reg_num, struct rtos_reg *reg);\n\tint (*get_symbol_list_to_lookup)(struct symbol_table_elem *symbol_list[]);\n\tint (*clean)(struct target *target);\n\tchar * (*ps_command)(struct target *target);\n\tint (*set_reg)(struct rtos *rtos, uint32_t reg_num, uint8_t *reg_value);\n\t/* Implement these if different threads in the RTOS can see memory\n\t * differently (for instance because address translation might be different\n\t * for each thread). */\n\tint (*read_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size,\n\t\t\tuint8_t *buffer);\n\tint (*write_buffer)(struct rtos *rtos, target_addr_t address, uint32_t size,\n\t\t\tconst uint8_t *buffer);\n};\n\nstruct stack_register_offset {\n\tunsigned short number;\t\t/* register number */\n\tsigned short offset;\t\t/* offset in bytes from stack head, or -1 to indicate\n\t\t\t\t\t * register is not stacked, or -2 to indicate this is the\n\t\t\t\t\t * stack pointer register */\n\tunsigned short width_bits;\n};\n\nstruct rtos_register_stacking {\n\tunsigned char stack_registers_size;\n\tsigned char stack_growth_direction;\n\tunsigned char num_output_registers;\n\t/* Some targets require evaluating the stack to determine the\n\t * actual stack pointer for a process.  If this field is NULL,\n\t * just use stacking->stack_registers_size * stack_growth_direction\n\t * to calculate adjustment.\n\t */\n\ttarget_addr_t (*calculate_process_stack)(struct target *target,\n\t\tconst uint8_t *stack_data,\n\t\tconst struct rtos_register_stacking *stacking,\n\t\ttarget_addr_t stack_ptr);\n\tconst struct stack_register_offset *register_offsets;\n\t/* Optional field for targets which may have to implement their own stack read function.\n\t * Because stack format can be weird or stack data needed to be edited before passing to the gdb.\n\t */\n\tint (*read_stack)(struct target *target,\n\t\tint64_t stack_ptr,\n\t\tconst struct rtos_register_stacking *stacking,\n\t\tuint8_t *stack_data);\n};\n\n#define GDB_THREAD_PACKET_NOT_CONSUMED (-40)\n\nint rtos_create(struct jim_getopt_info *goi, struct target *target);\nvoid rtos_destroy(struct target *target);\nint rtos_set_reg(struct connection *connection, int reg_num,\n\t\tuint8_t *reg_value);\nint rtos_generic_stack_read(struct target *target,\n\t\tconst struct rtos_register_stacking *stacking,\n\t\tint64_t stack_ptr,\n\t\tstruct rtos_reg **reg_list,\n\t\tint *num_regs);\nint gdb_thread_packet(struct connection *connection, char const *packet, int packet_size);\nint rtos_thread_packet(struct connection *connection, const char *packet, int packet_size);\nint rtos_get_gdb_reg(struct connection *connection, int reg_num);\nint rtos_get_gdb_reg_list(struct connection *connection);\nint rtos_update_threads(struct target *target);\nvoid rtos_free_threadlist(struct rtos *rtos);\nint rtos_smp_init(struct target *target);\n/*  function for handling symbol access */\nint rtos_qsymbol(struct connection *connection, char const *packet, int packet_size);\nint rtos_read_buffer(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer);\nint rtos_write_buffer(struct target *target, target_addr_t address,\n\t\tuint32_t size, const uint8_t *buffer);\n\nextern const struct rtos_type chibios_rtos;\nextern const struct rtos_type chromium_ec_rtos;\nextern const struct rtos_type ecos_rtos;\nextern const struct rtos_type embkernel_rtos;\nextern const struct rtos_type freertos_rtos;\nextern const struct rtos_type hwthread_rtos;\nextern const struct rtos_type linux_rtos;\nextern const struct rtos_type mqx_rtos;\nextern const struct rtos_type nuttx_rtos;\nextern const struct rtos_type riot_rtos;\nextern const struct rtos_type rtkernel_rtos;\nextern const struct rtos_type threadx_rtos;\nextern const struct rtos_type ucos_iii_rtos;\nextern const struct rtos_type zephyr_rtos;\n\n#endif /* OPENOCD_RTOS_RTOS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_chibios_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2012 by Matthias Blaicher                               *\n *   Matthias Blaicher - matthias@blaicher.com                             *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_chibios_stackings.h\"\n\nstatic const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   -1,   32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   -1,   32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   -1,   32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   -1,   32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  -1,   32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  -1,   32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x20, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, -1,   32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_chibios_arm_v7m_stacking = {\n\t.stack_registers_size = 0x24,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.register_offsets = rtos_chibios_arm_v7m_stack_offsets\n};\n\nstatic const struct stack_register_offset rtos_chibios_arm_v7m_stack_offsets_w_fpu[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   -1,   32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   -1,   32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   -1,   32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   -1,   32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x40, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x44, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x48, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x4c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x50, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x54, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x58, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x5c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  -1,   32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  -1,   32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x60, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, -1,   32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu = {\n\t.stack_registers_size = 0x64,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.register_offsets = rtos_chibios_arm_v7m_stack_offsets_w_fpu\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_chibios_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking;\nextern const struct rtos_register_stacking rtos_chibios_arm_v7m_stacking_w_fpu;\n\n#endif /* OPENOCD_RTOS_RTOS_CHIBIOS_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_ecos_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"rtos_ecos_stackings.h\"\n\n/* For Cortex-M eCos applications the actual thread context register layout can\n * be different between active threads of an application depending on whether\n * the FPU is in use, configured for lazy FPU context saving, etc. */\n\n/* Default fixed thread register context description used for older eCos\n * application builds without the necessary symbolic information describing the\n * actual configuration-dependent offsets. */\nstatic const struct stack_register_offset rtos_ecos_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   0x0c, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   0x10, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   0x14, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   0x18, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x1c, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x20, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x24, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x28, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x2c, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x30, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x34, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x38, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  0x3c, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  -1,   32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x40, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, -1,   32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_ecos_cortex_m3_stacking = {\n\t.stack_registers_size = 0x44,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = rtos_ecos_cortex_m3_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_ecos_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_ecos_cortex_m3_stacking;\n\n#endif /* OPENOCD_RTOS_RTOS_ECOS_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_embkernel_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"rtos_embkernel_stackings.h\"\n\nstatic const struct stack_register_offset rtos_embkernel_cortex_m_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   0x24, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   0x28, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   0x2c, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   0x30, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  0x34, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t    /* sp   */\n\t{ ARMV7M_R14,  0x38, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x3c, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x40, 32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_embkernel_cortex_m_stacking = {\n\t.stack_registers_size = 0x40,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = rtos_embkernel_cortex_m_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_embkernel_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_embkernel_cortex_m_stacking;\n\n#endif /* OPENOCD_RTOS_RTOS_EMBKERNEL_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_mqx_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2014 by Marian Cingel                                   *\n *   cingel.marian@gmail.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_mqx_stackings.h\"\n\n/*\n * standard exception stack\n * ( stack base, higher memory address )\n * - xpsr\t\t- 0x48\n * - pc\t\t\t- 0x44\n * - lr\t\t\t- 0x40\n * - r12\t\t- 0x3C\n * - r3\t\t\t- 0x38\n * - r2\t\t\t- 0x34\n * - r1\t\t\t- 0x30\n * - r0\t\t\t- 0x2C\n * extended stack in svc_pending handler\n * - lr\t\t\t- 0x28\n * - r11\t\t- 0x24\n * - r10\t\t- 0x20\n * - r9\t\t\t- 0x1C\n * - r8\t\t\t- 0x18\n * - r7\t\t\t- 0x14\n * - r6\t\t\t- 0x10\n * - r5\t\t\t- 0x0C\n * - r4\t\t\t- 0x08\n * - BASEPRI\t- 0x04\n * - SHPR3\t\t- 0x00 ( contains pend_svc exception priority )\n * ( stack head, lower address, stored in 'task->STACK_PTR' )\n */\n\nstatic const struct stack_register_offset rtos_mqx_arm_v7m_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   0x2C, 32 }, /* r0   */\n\t{ ARMV7M_R1,   0x30, 32 }, /* r1   */\n\t{ ARMV7M_R2,   0x34, 32 }, /* r2   */\n\t{ ARMV7M_R3,   0x38, 32 }, /* r3   */\n\t{ ARMV7M_R4,   0x08, 32 }, /* r4   */\n\t{ ARMV7M_R5,   0x0C, 32 }, /* r5   */\n\t{ ARMV7M_R6,   0x10, 32 }, /* r6   */\n\t{ ARMV7M_R7,   0x14, 32 }, /* r7   */\n\t{ ARMV7M_R8,   0x18, 32 }, /* r8   */\n\t{ ARMV7M_R9,   0x1C, 32 }, /* r9   */\n\t{ ARMV7M_R10,  0x20, 32 }, /* r10  */\n\t{ ARMV7M_R11,  0x24, 32 }, /* r11  */\n\t{ ARMV7M_R12,  0x3C, 32 }, /* r12  */\n\t{ ARMV7M_R13,    -2, 32 }, /* sp   */\n\t{ ARMV7M_R14,  0x28, 32 }, /* lr   */\n\t{ ARMV7M_PC,   0x44, 32 }, /* pc   */\n\t{ ARMV7M_XPSR, 0x48, 32 }, /* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_mqx_arm_v7m_stacking = {\n\t.stack_registers_size = 0x4C,\t\t\t\t\t/* calculate offset base address */\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.register_offsets = rtos_mqx_arm_v7m_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_mqx_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2014 by Marian Cingel                                   *\n *   cingel.marian@gmail.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_MQX_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_MQX_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_mqx_arm_v7m_stacking;\n\n#endif /* OPENOCD_RTOS_RTOS_MQX_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_nuttx_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_nuttx_stackings.h\"\n#include \"rtos_standard_stackings.h\"\n#include <target/riscv/riscv.h>\n\n/* see arch/arm/include/armv7-m/irq_cmnvector.h */\nstatic const struct stack_register_offset nuttx_stack_offsets_cortex_m[] = {\n\t{ ARMV7M_R0, 0x28, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1, 0x2c, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2, 0x30, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3, 0x34, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4, 0x08, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5, 0x0c, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6, 0x10, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7, 0x14, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8, 0x18, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9, 0x1c, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10, 0x20, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11, 0x24, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12, 0x38, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13, 0, 32 },\t\t\t/* sp   */\n\t{ ARMV7M_R14, 0x3c, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC, 0x40, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x44, 32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking nuttx_stacking_cortex_m = {\n\t.stack_registers_size = 0x48,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 17,\n\t.register_offsets = nuttx_stack_offsets_cortex_m,\n};\n\nstatic const struct stack_register_offset nuttx_stack_offsets_cortex_m_fpu[] = {\n\t{ ARMV7M_R0, 0x6c, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1, 0x70, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2, 0x74, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3, 0x78, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4, 0x08, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5, 0x0c, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6, 0x10, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7, 0x14, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8, 0x18, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9, 0x1c, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10, 0x20, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11, 0x24, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12, 0x7c, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13, 0, 32 },\t\t\t/* sp   */\n\t{ ARMV7M_R14, 0x80, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC, 0x84, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x88, 32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking nuttx_stacking_cortex_m_fpu = {\n\t.stack_registers_size = 0x8c,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 17,\n\t.register_offsets = nuttx_stack_offsets_cortex_m_fpu,\n};\n\nstatic const struct stack_register_offset nuttx_stack_offsets_riscv[] = {\n\t{ GDB_REGNO_ZERO, -1, 32 },\n\t{ GDB_REGNO_RA, 0x04, 32 },\n\t{ GDB_REGNO_SP, 0x08, 32 },\n\t{ GDB_REGNO_GP, 0x0c, 32 },\n\t{ GDB_REGNO_TP, 0x10, 32 },\n\t{ GDB_REGNO_T0, 0x14, 32 },\n\t{ GDB_REGNO_T1, 0x18, 32 },\n\t{ GDB_REGNO_T2, 0x1c, 32 },\n\t{ GDB_REGNO_FP, 0x20, 32 },\n\t{ GDB_REGNO_S1, 0x24, 32 },\n\t{ GDB_REGNO_A0, 0x28, 32 },\n\t{ GDB_REGNO_A1, 0x2c, 32 },\n\t{ GDB_REGNO_A2, 0x30, 32 },\n\t{ GDB_REGNO_A3, 0x34, 32 },\n\t{ GDB_REGNO_A4, 0x38, 32 },\n\t{ GDB_REGNO_A5, 0x3c, 32 },\n\t{ GDB_REGNO_A6, 0x40, 32 },\n\t{ GDB_REGNO_A7, 0x44, 32 },\n\t{ GDB_REGNO_S2, 0x48, 32 },\n\t{ GDB_REGNO_S3, 0x4c, 32 },\n\t{ GDB_REGNO_S4, 0x50, 32 },\n\t{ GDB_REGNO_S5, 0x54, 32 },\n\t{ GDB_REGNO_S6, 0x58, 32 },\n\t{ GDB_REGNO_S7, 0x5c, 32 },\n\t{ GDB_REGNO_S8, 0x60, 32 },\n\t{ GDB_REGNO_S9, 0x64, 32 },\n\t{ GDB_REGNO_S10, 0x68, 32 },\n\t{ GDB_REGNO_S11, 0x6c, 32 },\n\t{ GDB_REGNO_T3, 0x70, 32 },\n\t{ GDB_REGNO_T4, 0x74, 32 },\n\t{ GDB_REGNO_T5, 0x78, 32 },\n\t{ GDB_REGNO_T6, 0x7c, 32 },\n\t{ GDB_REGNO_PC, 0x00, 32 },\n};\n\nconst struct rtos_register_stacking nuttx_riscv_stacking = {\n\t.stack_registers_size = 33 * 4,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 33,\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = nuttx_stack_offsets_riscv,\n};\n\nstatic int nuttx_esp_xtensa_stack_read(struct target *target,\n\tint64_t stack_ptr, const struct rtos_register_stacking *stacking,\n\tuint8_t *stack_data)\n{\n\tint retval = target_read_buffer(target, stack_ptr, stacking->stack_registers_size, stack_data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstack_data[4] &= ~0x10;\t/* Clear exception bit in PS */\n\n\treturn ERROR_OK;\n}\n\nstatic const struct stack_register_offset nuttx_stack_offsets_esp32[] = {\n\t{ 0, 0x00, 32 },\t\t/* PC */\n\t{ 1, 0x08, 32 },\t\t/* A0 */\n\t{ 2, 0x0c, 32 },\t\t/* A1 */\n\t{ 3, 0x10, 32 },\t\t/* A2 */\n\t{ 4, 0x14, 32 },\t\t/* A3 */\n\t{ 5, 0x18, 32 },\t\t/* A4 */\n\t{ 6, 0x1c, 32 },\t\t/* A5 */\n\t{ 7, 0x20, 32 },\t\t/* A6 */\n\t{ 8, 0x24, 32 },\t\t/* A7 */\n\t{ 9, 0x28, 32 },\t\t/* A8 */\n\t{ 10, 0x2c, 32 },\t\t/* A9 */\n\t{ 11, 0x30, 32 },\t\t/* A10 */\n\t{ 12, 0x34, 32 },\t\t/* A11 */\n\t{ 13, 0x38, 32 },\t\t/* A12 */\n\t{ 14, 0x3c, 32 },\t\t/* A13 */\n\t{ 15, 0x40, 32 },\t\t/* A14 */\n\t{ 16, 0x44, 32 },\t\t/* A15 */\n\t/* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */\n\t{ 17, -1, 32 },\t\t\t/* A16 */\n\t{ 18, -1, 32 },\t\t\t/* A17 */\n\t{ 19, -1, 32 },\t\t\t/* A18 */\n\t{ 20, -1, 32 },\t\t\t/* A19 */\n\t{ 21, -1, 32 },\t\t\t/* A20 */\n\t{ 22, -1, 32 },\t\t\t/* A21 */\n\t{ 23, -1, 32 },\t\t\t/* A22 */\n\t{ 24, -1, 32 },\t\t\t/* A23 */\n\t{ 25, -1, 32 },\t\t\t/* A24 */\n\t{ 26, -1, 32 },\t\t\t/* A25 */\n\t{ 27, -1, 32 },\t\t\t/* A26 */\n\t{ 28, -1, 32 },\t\t\t/* A27 */\n\t{ 29, -1, 32 },\t\t\t/* A28 */\n\t{ 30, -1, 32 },\t\t\t/* A29 */\n\t{ 31, -1, 32 },\t\t\t/* A30 */\n\t{ 32, -1, 32 },\t\t\t/* A31 */\n\t{ 33, -1, 32 },\t\t\t/* A32 */\n\t{ 34, -1, 32 },\t\t\t/* A33 */\n\t{ 35, -1, 32 },\t\t\t/* A34 */\n\t{ 36, -1, 32 },\t\t\t/* A35 */\n\t{ 37, -1, 32 },\t\t\t/* A36 */\n\t{ 38, -1, 32 },\t\t\t/* A37 */\n\t{ 39, -1, 32 },\t\t\t/* A38 */\n\t{ 40, -1, 32 },\t\t\t/* A39 */\n\t{ 41, -1, 32 },\t\t\t/* A40 */\n\t{ 42, -1, 32 },\t\t\t/* A41 */\n\t{ 43, -1, 32 },\t\t\t/* A42 */\n\t{ 44, -1, 32 },\t\t\t/* A43 */\n\t{ 45, -1, 32 },\t\t\t/* A44 */\n\t{ 46, -1, 32 },\t\t\t/* A45 */\n\t{ 47, -1, 32 },\t\t\t/* A46 */\n\t{ 48, -1, 32 },\t\t\t/* A47 */\n\t{ 49, -1, 32 },\t\t\t/* A48 */\n\t{ 50, -1, 32 },\t\t\t/* A49 */\n\t{ 51, -1, 32 },\t\t\t/* A50 */\n\t{ 52, -1, 32 },\t\t\t/* A51 */\n\t{ 53, -1, 32 },\t\t\t/* A52 */\n\t{ 54, -1, 32 },\t\t\t/* A53 */\n\t{ 55, -1, 32 },\t\t\t/* A54 */\n\t{ 56, -1, 32 },\t\t\t/* A55 */\n\t{ 57, -1, 32 },\t\t\t/* A56 */\n\t{ 58, -1, 32 },\t\t\t/* A57 */\n\t{ 59, -1, 32 },\t\t\t/* A58 */\n\t{ 60, -1, 32 },\t\t\t/* A59 */\n\t{ 61, -1, 32 },\t\t\t/* A60 */\n\t{ 62, -1, 32 },\t\t\t/* A61 */\n\t{ 63, -1, 32 },\t\t\t/* A62 */\n\t{ 64, -1, 32 },\t\t\t/* A63 */\n\t{ 65, 0x58, 32 },\t\t/* lbeg */\n\t{ 66, 0x5c, 32 },\t\t/* lend */\n\t{ 67, 0x60, 32 },\t\t/* lcount */\n\t{ 68, 0x48, 32 },\t\t/* SAR */\n\t{ 69, -1, 32 },\t\t\t/* windowbase */\n\t{ 70, -1, 32 },\t\t\t/* windowstart */\n\t{ 71, -1, 32 },\t\t\t/* configid0 */\n\t{ 72, -1, 32 },\t\t\t/* configid1 */\n\t{ 73, 0x04, 32 },\t\t/* PS */\n\t{ 74, -1, 32 },\t\t\t/* threadptr */\n\t{ 75, -1, 32 },\t\t\t/* br */\n\t{ 76, 0x54, 32 },\t\t/* scompare1 */\n\t{ 77, -1, 32 },\t\t\t/* acclo */\n\t{ 78, -1, 32 },\t\t\t/* acchi */\n\t{ 79, -1, 32 },\t\t\t/* m0 */\n\t{ 80, -1, 32 },\t\t\t/* m1 */\n\t{ 81, -1, 32 },\t\t\t/* m2 */\n\t{ 82, -1, 32 },\t\t\t/* m3 */\n\t{ 83, -1, 32 },\t\t\t/* expstate */\n\t{ 84, -1, 32 },\t\t\t/* f64r_lo */\n\t{ 85, -1, 32 },\t\t\t/* f64r_hi */\n\t{ 86, -1, 32 },\t\t\t/* f64s */\n\t{ 87, -1, 32 },\t\t\t/* f0 */\n\t{ 88, -1, 32 },\t\t\t/* f1 */\n\t{ 89, -1, 32 },\t\t\t/* f2 */\n\t{ 90, -1, 32 },\t\t\t/* f3 */\n\t{ 91, -1, 32 },\t\t\t/* f4 */\n\t{ 92, -1, 32 },\t\t\t/* f5 */\n\t{ 93, -1, 32 },\t\t\t/* f6 */\n\t{ 94, -1, 32 },\t\t\t/* f7 */\n\t{ 95, -1, 32 },\t\t\t/* f8 */\n\t{ 96, -1, 32 },\t\t\t/* f9 */\n\t{ 97, -1, 32 },\t\t\t/* f10 */\n\t{ 98, -1, 32 },\t\t\t/* f11 */\n\t{ 99, -1, 32 },\t\t\t/* f12 */\n\t{ 100, -1, 32 },\t\t/* f13 */\n\t{ 101, -1, 32 },\t\t/* f14 */\n\t{ 102, -1, 32 },\t\t/* f15 */\n\t{ 103, -1, 32 },\t\t/* fcr */\n\t{ 104, -1, 32 },\t\t/* fsr */\n};\n\nconst struct rtos_register_stacking nuttx_esp32_stacking = {\n\t.stack_registers_size = 26 * 4,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32),\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = nuttx_stack_offsets_esp32,\n\t.read_stack = nuttx_esp_xtensa_stack_read,\n};\n\nstatic const struct stack_register_offset nuttx_stack_offsets_esp32s2[] = {\n\t{ 0, 0x00, 32 },\t\t/* PC */\n\t{ 1, 0x08, 32 },\t\t/* A0 */\n\t{ 2, 0x0c, 32 },\t\t/* A1 */\n\t{ 3, 0x10, 32 },\t\t/* A2 */\n\t{ 4, 0x14, 32 },\t\t/* A3 */\n\t{ 5, 0x18, 32 },\t\t/* A4 */\n\t{ 6, 0x1c, 32 },\t\t/* A5 */\n\t{ 7, 0x20, 32 },\t\t/* A6 */\n\t{ 8, 0x24, 32 },\t\t/* A7 */\n\t{ 9, 0x28, 32 },\t\t/* A8 */\n\t{ 10, 0x2c, 32 },\t\t/* A9 */\n\t{ 11, 0x30, 32 },\t\t/* A10 */\n\t{ 12, 0x34, 32 },\t\t/* A11 */\n\t{ 13, 0x38, 32 },\t\t/* A12 */\n\t{ 14, 0x3c, 32 },\t\t/* A13 */\n\t{ 15, 0x40, 32 },\t\t/* A14 */\n\t{ 16, 0x44, 32 },\t\t/* A15 */\n\t/* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */\n\t{ 17, -1, 32 },\t\t\t/* A16 */\n\t{ 18, -1, 32 },\t\t\t/* A17 */\n\t{ 19, -1, 32 },\t\t\t/* A18 */\n\t{ 20, -1, 32 },\t\t\t/* A19 */\n\t{ 21, -1, 32 },\t\t\t/* A20 */\n\t{ 22, -1, 32 },\t\t\t/* A21 */\n\t{ 23, -1, 32 },\t\t\t/* A22 */\n\t{ 24, -1, 32 },\t\t\t/* A23 */\n\t{ 25, -1, 32 },\t\t\t/* A24 */\n\t{ 26, -1, 32 },\t\t\t/* A25 */\n\t{ 27, -1, 32 },\t\t\t/* A26 */\n\t{ 28, -1, 32 },\t\t\t/* A27 */\n\t{ 29, -1, 32 },\t\t\t/* A28 */\n\t{ 30, -1, 32 },\t\t\t/* A29 */\n\t{ 31, -1, 32 },\t\t\t/* A30 */\n\t{ 32, -1, 32 },\t\t\t/* A31 */\n\t{ 33, -1, 32 },\t\t\t/* A32 */\n\t{ 34, -1, 32 },\t\t\t/* A33 */\n\t{ 35, -1, 32 },\t\t\t/* A34 */\n\t{ 36, -1, 32 },\t\t\t/* A35 */\n\t{ 37, -1, 32 },\t\t\t/* A36 */\n\t{ 38, -1, 32 },\t\t\t/* A37 */\n\t{ 39, -1, 32 },\t\t\t/* A38 */\n\t{ 40, -1, 32 },\t\t\t/* A39 */\n\t{ 41, -1, 32 },\t\t\t/* A40 */\n\t{ 42, -1, 32 },\t\t\t/* A41 */\n\t{ 43, -1, 32 },\t\t\t/* A42 */\n\t{ 44, -1, 32 },\t\t\t/* A43 */\n\t{ 45, -1, 32 },\t\t\t/* A44 */\n\t{ 46, -1, 32 },\t\t\t/* A45 */\n\t{ 47, -1, 32 },\t\t\t/* A46 */\n\t{ 48, -1, 32 },\t\t\t/* A47 */\n\t{ 49, -1, 32 },\t\t\t/* A48 */\n\t{ 50, -1, 32 },\t\t\t/* A49 */\n\t{ 51, -1, 32 },\t\t\t/* A50 */\n\t{ 52, -1, 32 },\t\t\t/* A51 */\n\t{ 53, -1, 32 },\t\t\t/* A52 */\n\t{ 54, -1, 32 },\t\t\t/* A53 */\n\t{ 55, -1, 32 },\t\t\t/* A54 */\n\t{ 56, -1, 32 },\t\t\t/* A55 */\n\t{ 57, -1, 32 },\t\t\t/* A56 */\n\t{ 58, -1, 32 },\t\t\t/* A57 */\n\t{ 59, -1, 32 },\t\t\t/* A58 */\n\t{ 60, -1, 32 },\t\t\t/* A59 */\n\t{ 61, -1, 32 },\t\t\t/* A60 */\n\t{ 62, -1, 32 },\t\t\t/* A61 */\n\t{ 63, -1, 32 },\t\t\t/* A62 */\n\t{ 64, -1, 32 },\t\t\t/* A63 */\n\t{ 65, 0x48, 32 },\t\t/* SAR */\n\t{ 66, -1, 32 },\t\t\t/* windowbase */\n\t{ 67, -1, 32 },\t\t\t/* windowstart */\n\t{ 68, -1, 32 },\t\t\t/* configid0 */\n\t{ 69, -1, 32 },\t\t\t/* configid1 */\n\t{ 70, 0x04, 32 },\t\t/* PS */\n\t{ 71, -1, 32 },\t\t\t/* threadptr */\n\t{ 72, -1, 32 },\t\t\t/* gpio_out */\n};\n\nconst struct rtos_register_stacking nuttx_esp32s2_stacking = {\n\t.stack_registers_size = 25 * 4,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32s2),\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = nuttx_stack_offsets_esp32s2,\n\t.read_stack = nuttx_esp_xtensa_stack_read,\n};\n\nstatic const struct stack_register_offset nuttx_stack_offsets_esp32s3[] = {\n\t{ 0, 0x00, 32 },\t\t/* PC */\n\t{ 1, 0x08, 32 },\t\t/* A0 */\n\t{ 2, 0x0c, 32 },\t\t/* A1 */\n\t{ 3, 0x10, 32 },\t\t/* A2 */\n\t{ 4, 0x14, 32 },\t\t/* A3 */\n\t{ 5, 0x18, 32 },\t\t/* A4 */\n\t{ 6, 0x1c, 32 },\t\t/* A5 */\n\t{ 7, 0x20, 32 },\t\t/* A6 */\n\t{ 8, 0x24, 32 },\t\t/* A7 */\n\t{ 9, 0x28, 32 },\t\t/* A8 */\n\t{ 10, 0x2c, 32 },\t\t/* A9 */\n\t{ 11, 0x30, 32 },\t\t/* A10 */\n\t{ 12, 0x34, 32 },\t\t/* A11 */\n\t{ 13, 0x38, 32 },\t\t/* A12 */\n\t{ 14, 0x3c, 32 },\t\t/* A13 */\n\t{ 15, 0x40, 32 },\t\t/* A14 */\n\t{ 16, 0x44, 32 },\t\t/* A15 */\n\t/* A16-A63 aren't in the stack frame because they've been flushed to the stack earlier */\n\t{ 17, -1, 32 },\t\t\t/* A16 */\n\t{ 18, -1, 32 },\t\t\t/* A17 */\n\t{ 19, -1, 32 },\t\t\t/* A18 */\n\t{ 20, -1, 32 },\t\t\t/* A19 */\n\t{ 21, -1, 32 },\t\t\t/* A20 */\n\t{ 22, -1, 32 },\t\t\t/* A21 */\n\t{ 23, -1, 32 },\t\t\t/* A22 */\n\t{ 24, -1, 32 },\t\t\t/* A23 */\n\t{ 25, -1, 32 },\t\t\t/* A24 */\n\t{ 26, -1, 32 },\t\t\t/* A25 */\n\t{ 27, -1, 32 },\t\t\t/* A26 */\n\t{ 28, -1, 32 },\t\t\t/* A27 */\n\t{ 29, -1, 32 },\t\t\t/* A28 */\n\t{ 30, -1, 32 },\t\t\t/* A29 */\n\t{ 31, -1, 32 },\t\t\t/* A30 */\n\t{ 32, -1, 32 },\t\t\t/* A31 */\n\t{ 33, -1, 32 },\t\t\t/* A32 */\n\t{ 34, -1, 32 },\t\t\t/* A33 */\n\t{ 35, -1, 32 },\t\t\t/* A34 */\n\t{ 36, -1, 32 },\t\t\t/* A35 */\n\t{ 37, -1, 32 },\t\t\t/* A36 */\n\t{ 38, -1, 32 },\t\t\t/* A37 */\n\t{ 39, -1, 32 },\t\t\t/* A38 */\n\t{ 40, -1, 32 },\t\t\t/* A39 */\n\t{ 41, -1, 32 },\t\t\t/* A40 */\n\t{ 42, -1, 32 },\t\t\t/* A41 */\n\t{ 43, -1, 32 },\t\t\t/* A42 */\n\t{ 44, -1, 32 },\t\t\t/* A43 */\n\t{ 45, -1, 32 },\t\t\t/* A44 */\n\t{ 46, -1, 32 },\t\t\t/* A45 */\n\t{ 47, -1, 32 },\t\t\t/* A46 */\n\t{ 48, -1, 32 },\t\t\t/* A47 */\n\t{ 49, -1, 32 },\t\t\t/* A48 */\n\t{ 50, -1, 32 },\t\t\t/* A49 */\n\t{ 51, -1, 32 },\t\t\t/* A50 */\n\t{ 52, -1, 32 },\t\t\t/* A51 */\n\t{ 53, -1, 32 },\t\t\t/* A52 */\n\t{ 54, -1, 32 },\t\t\t/* A53 */\n\t{ 55, -1, 32 },\t\t\t/* A54 */\n\t{ 56, -1, 32 },\t\t\t/* A55 */\n\t{ 57, -1, 32 },\t\t\t/* A56 */\n\t{ 58, -1, 32 },\t\t\t/* A57 */\n\t{ 59, -1, 32 },\t\t\t/* A58 */\n\t{ 60, -1, 32 },\t\t\t/* A59 */\n\t{ 61, -1, 32 },\t\t\t/* A60 */\n\t{ 62, -1, 32 },\t\t\t/* A61 */\n\t{ 63, -1, 32 },\t\t\t/* A62 */\n\t{ 64, -1, 32 },\t\t\t/* A63 */\n\t{ 65, 0x58, 32 },\t\t/* lbeg */\n\t{ 66, 0x5c, 32 },\t\t/* lend */\n\t{ 67, 0x60, 32 },\t\t/* lcount */\n\t{ 68, 0x48, 32 },\t\t/* SAR */\n\t{ 69, -1, 32 },\t\t\t/* windowbase */\n\t{ 70, -1, 32 },\t\t\t/* windowstart */\n\t{ 71, -1, 32 },\t\t\t/* configid0 */\n\t{ 72, -1, 32 },\t\t\t/* configid1 */\n\t{ 73, 0x04, 32 },\t\t/* PS */\n\t{ 74, -1, 32 },\t\t\t/* threadptr */\n\t{ 75, -1, 32 },\t\t\t/* br */\n\t{ 76, 0x54, 32 },\t\t/* scompare1 */\n\t{ 77, -1, 32 },\t\t\t/* acclo */\n\t{ 78, -1, 32 },\t\t\t/* acchi */\n\t{ 79, -1, 32 },\t\t\t/* m0 */\n\t{ 80, -1, 32 },\t\t\t/* m1 */\n\t{ 81, -1, 32 },\t\t\t/* m2 */\n\t{ 82, -1, 32 },\t\t\t/* m3 */\n\t{ 83, -1, 32 },\t\t\t/* gpio_out */\n\t{ 84, -1, 32 },\t\t\t/* f0 */\n\t{ 85, -1, 32 },\t\t\t/* f1 */\n\t{ 86, -1, 32 },\t\t\t/* f2 */\n\t{ 87, -1, 32 },\t\t\t/* f3 */\n\t{ 88, -1, 32 },\t\t\t/* f4 */\n\t{ 89, -1, 32 },\t\t\t/* f5 */\n\t{ 90, -1, 32 },\t\t\t/* f6 */\n\t{ 91, -1, 32 },\t\t\t/* f7 */\n\t{ 92, -1, 32 },\t\t\t/* f8 */\n\t{ 93, -1, 32 },\t\t\t/* f9 */\n\t{ 94, -1, 32 },\t\t\t/* f10 */\n\t{ 95, -1, 32 },\t\t\t/* f11 */\n\t{ 96, -1, 32 },\t\t\t/* f12 */\n\t{ 97, -1, 32 },\t\t\t/* f13 */\n\t{ 98, -1, 32 },\t\t\t/* f14 */\n\t{ 99, -1, 32 },\t\t\t/* f15 */\n\t{ 100, -1, 32 },\t\t/* fcr */\n\t{ 101, -1, 32 },\t\t/* fsr */\n\t{ 102, -1, 32 },\t\t/* accx_0 */\n\t{ 103, -1, 32 },\t\t/* accx_1 */\n\t{ 104, -1, 32 },\t\t/* qacc_h_0 */\n\t{ 105, -1, 32 },\t\t/* qacc_h_1 */\n\t{ 106, -1, 32 },\t\t/* qacc_h_2 */\n\t{ 107, -1, 32 },\t\t/* qacc_h_3 */\n\t{ 108, -1, 32 },\t\t/* qacc_h_4 */\n\t{ 109, -1, 32 },\t\t/* qacc_l_0 */\n\t{ 110, -1, 32 },\t\t/* qacc_l_1 */\n\t{ 111, -1, 32 },\t\t/* qacc_l_2 */\n\t{ 112, -1, 32 },\t\t/* qacc_l_3 */\n\t{ 113, -1, 32 },\t\t/* qacc_l_4 */\n\t{ 114, -1, 32 },\t\t/* sar_byte */\n\t{ 115, -1, 32 },\t\t/* fft_bit_width */\n\t{ 116, -1, 32 },\t\t/* ua_state_0 */\n\t{ 117, -1, 32 },\t\t/* ua_state_1 */\n\t{ 118, -1, 32 },\t\t/* ua_state_2 */\n\t{ 119, -1, 32 },\t\t/* ua_state_3 */\n\t{ 120, -1, 128 },\t\t/* q0 */\n\t{ 121, -1, 128 },\t\t/* q1 */\n\t{ 122, -1, 128 },\t\t/* q2 */\n\t{ 123, -1, 128 },\t\t/* q3 */\n\t{ 124, -1, 128 },\t\t/* q4 */\n\t{ 125, -1, 128 },\t\t/* q5 */\n\t{ 126, -1, 128 },\t\t/* q6 */\n\t{ 127, -1, 128 },\t\t/* q7 */\n};\n\nconst struct rtos_register_stacking nuttx_esp32s3_stacking = {\n\t.stack_registers_size = 26 * 4,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(nuttx_stack_offsets_esp32s3),\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = nuttx_stack_offsets_esp32s3,\n\t.read_stack = nuttx_esp_xtensa_stack_read,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_nuttx_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef INCLUDED_RTOS_NUTTX_STACKINGS_H\n#define INCLUDED_RTOS_NUTTX_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking nuttx_stacking_cortex_m;\nextern const struct rtos_register_stacking nuttx_stacking_cortex_m_fpu;\nextern const struct rtos_register_stacking nuttx_riscv_stacking;\nextern const struct rtos_register_stacking nuttx_esp32_stacking;\nextern const struct rtos_register_stacking nuttx_esp32s2_stacking;\nextern const struct rtos_register_stacking nuttx_esp32s3_stacking;\n\n#endif\t/* INCLUDED_RTOS_NUTTX_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_riot_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Daniel Krebs                                    *\n *   Daniel Krebs - github@daniel-krebs.net                                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"rtos_riot_stackings.h\"\n\n/* This works for the M0 and M34 stackings as xPSR is in a fixed\n * location\n */\nstatic target_addr_t rtos_riot_cortex_m_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr)\n{\n\tconst int XPSR_OFFSET = 0x40;\n\treturn rtos_cortex_m_stack_align(target, stack_data, stacking,\n\t\tstack_ptr, XPSR_OFFSET);\n}\n\n/* see thread_arch.c */\nstatic const struct stack_register_offset rtos_riot_cortex_m0_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,    0x24, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,    0x28, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,    0x2c, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,    0x30, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,    0x14, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,    0x18, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,    0x1c, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,    0x20, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,    0x04, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,    0x08, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,   0x0c, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,   0x10, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,   0x34, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,   -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,   0x38, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC,    0x3c, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR,  0x40, 32 },\t\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_riot_cortex_m0_stacking = {\n\t.stack_registers_size = 0x44,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_riot_cortex_m_stack_align,\n\t.register_offsets = rtos_riot_cortex_m0_stack_offsets\n};\n\n/* see thread_arch.c */\nstatic const struct stack_register_offset rtos_riot_cortex_m34_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,    0x24, 32 },\t/* r0   */\n\t{ ARMV7M_R1,    0x28, 32 },\t/* r1   */\n\t{ ARMV7M_R2,    0x2c, 32 },\t/* r2   */\n\t{ ARMV7M_R3,    0x30, 32 },\t/* r3   */\n\t{ ARMV7M_R4,    0x04, 32 },\t/* r4   */\n\t{ ARMV7M_R5,    0x08, 32 },\t/* r5   */\n\t{ ARMV7M_R6,    0x0c, 32 },\t/* r6   */\n\t{ ARMV7M_R7,    0x10, 32 },\t/* r7   */\n\t{ ARMV7M_R8,    0x14, 32 },\t/* r8   */\n\t{ ARMV7M_R9,    0x18, 32 },\t/* r9   */\n\t{ ARMV7M_R10,   0x1c, 32 },\t/* r10  */\n\t{ ARMV7M_R11,   0x20, 32 },\t/* r11  */\n\t{ ARMV7M_R12,   0x34, 32 },\t/* r12  */\n\t{ ARMV7M_R13,   -2,   32 },\t/* sp   */\n\t{ ARMV7M_R14,   0x38, 32 },\t/* lr   */\n\t{ ARMV7M_PC,    0x3c, 32 },\t/* pc   */\n\t{ ARMV7M_XPSR,  0x40, 32 },\t/* xPSR */\n};\n\nconst struct rtos_register_stacking rtos_riot_cortex_m34_stacking = {\n\t.stack_registers_size = 0x44,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_riot_cortex_m_stack_align,\n\t.register_offsets = rtos_riot_cortex_m34_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_riot_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by Daniel Krebs                                    *\n *   Daniel Krebs - github@daniel-krebs.net                                *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_riot_cortex_m0_stacking;\nextern const struct rtos_register_stacking rtos_riot_cortex_m34_stacking;\n\n#endif\t/* OPENOCD_RTOS_RTOS_RIOT_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_standard_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"rtos_standard_stackings.h\"\n\nstatic const struct stack_register_offset rtos_standard_cortex_m3_stack_offsets[ARMV7M_NUM_CORE_REGS] = {\n\t{ ARMV7M_R0,   0x20, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   0x24, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   0x28, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   0x2c, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  0x30, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  0x34, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x38, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x3c, 32 },\t\t/* xPSR */\n};\n\nstatic const struct stack_register_offset rtos_standard_cortex_m4f_stack_offsets[] = {\n\t{ ARMV7M_R0,   0x24, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   0x28, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   0x2c, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   0x30, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  0x34, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  0x38, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x3c, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x40, 32 },\t\t/* xPSR */\n};\n\nstatic const struct stack_register_offset rtos_standard_cortex_m4f_fpu_stack_offsets[] = {\n\t{ ARMV7M_R0,   0x64, 32 },\t\t/* r0   */\n\t{ ARMV7M_R1,   0x68, 32 },\t\t/* r1   */\n\t{ ARMV7M_R2,   0x6c, 32 },\t\t/* r2   */\n\t{ ARMV7M_R3,   0x70, 32 },\t\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t\t/* r11  */\n\t{ ARMV7M_R12,  0x74, 32 },\t\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t\t/* sp   */\n\t{ ARMV7M_R14,  0x78, 32 },\t\t/* lr   */\n\t{ ARMV7M_PC,   0x7c, 32 },\t\t/* pc   */\n\t{ ARMV7M_XPSR, 0x80, 32 },\t\t/* xPSR */\n};\n\n\nstatic const struct stack_register_offset rtos_standard_cortex_r4_stack_offsets[] = {\n\t{ 0,  0x08, 32 },\t\t/* r0  (a1)   */\n\t{ 1,  0x0c, 32 },\t\t/* r1  (a2)  */\n\t{ 2,  0x10, 32 },\t\t/* r2  (a3)  */\n\t{ 3,  0x14, 32 },\t\t/* r3  (a4)  */\n\t{ 4,  0x18, 32 },\t\t/* r4  (v1)  */\n\t{ 5,  0x1c, 32 },\t\t/* r5  (v2)  */\n\t{ 6,  0x20, 32 },\t\t/* r6  (v3)  */\n\t{ 7,  0x24, 32 },\t\t/* r7  (v4)  */\n\t{ 8,  0x28, 32 },\t\t/* r8  (a1)  */\n\t{ 10, 0x2c, 32 },\t\t/* r9  (sb)  */\n\t{ 11, 0x30, 32 },\t\t/* r10 (sl) */\n\t{ 12, 0x34, 32 },\t\t/* r11 (fp) */\n\t{ 13, 0x38, 32 },\t\t/* r12 (ip) */\n\t{ 14, -2,   32 },\t\t/* sp   */\n\t{ 15, 0x3c, 32 },\t\t/* lr   */\n\t{ 16, 0x40, 32 },\t\t/* pc   */\n\t{ 17, -1,   96 },\t\t/* FPA1 */\n\t{ 18, -1,   96 },\t\t/* FPA2 */\n\t{ 19, -1,   96 },\t\t/* FPA3 */\n\t{ 20, -1,   96 },\t\t/* FPA4 */\n\t{ 21, -1,   96 },\t\t/* FPA5 */\n\t{ 22, -1,   96 },\t\t/* FPA6 */\n\t{ 23, -1,   96 },\t\t/* FPA7 */\n\t{ 24, -1,   96 },\t\t/* FPA8 */\n\t{ 25, -1,   32 },\t\t/* FPS  */\n\t{ 26, 0x04, 32 },\t\t/* CSPR */\n};\n\nstatic target_addr_t rtos_generic_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr, int align)\n{\n\ttarget_addr_t new_stack_ptr;\n\ttarget_addr_t aligned_stack_ptr;\n\tnew_stack_ptr = stack_ptr - stacking->stack_growth_direction *\n\t\tstacking->stack_registers_size;\n\taligned_stack_ptr = new_stack_ptr & ~((target_addr_t)align - 1);\n\tif (aligned_stack_ptr != new_stack_ptr &&\n\t\tstacking->stack_growth_direction == -1) {\n\t\t/* If we have a downward growing stack, the simple alignment code\n\t\t * above results in a wrong result (since it rounds down to nearest\n\t\t * alignment).  We want to round up so add an extra align.\n\t\t */\n\t\taligned_stack_ptr += (target_addr_t)align;\n\t}\n\treturn aligned_stack_ptr;\n}\n\ntarget_addr_t rtos_generic_stack_align8(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr)\n{\n\treturn rtos_generic_stack_align(target, stack_data,\n\t\t\tstacking, stack_ptr, 8);\n}\n\n/* The Cortex-M3 will indicate that an alignment adjustment\n * has been done on the stack by setting bit 9 of the stacked xPSR\n * register.  In this case, we can just add an extra 4 bytes to get\n * to the program stack.  Note that some places in the ARM documentation\n * make this a little unclear but the padding takes place before the\n * normal exception stacking - so xPSR is always available at a fixed\n * location.\n *\n * Relevant documentation:\n *    Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->\n *        Cortex-M3 Devices Generic User Guide -> The Cortex-M3 Processor ->\n *        Exception Model -> Exception entry and return -> Exception entry\n *    Cortex-M series processors -> Cortex-M3 -> Revision: xxx ->\n *        Cortex-M3 Devices Generic User Guide -> Cortex-M3 Peripherals ->\n *        System control block -> Configuration and Control Register (STKALIGN)\n *\n * This is just a helper function for use in the calculate_process_stack\n * function for a given architecture/rtos.\n */\ntarget_addr_t rtos_cortex_m_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr, size_t xpsr_offset)\n{\n\tconst uint32_t ALIGN_NEEDED = (1 << 9);\n\tuint32_t xpsr;\n\ttarget_addr_t new_stack_ptr;\n\n\tnew_stack_ptr = stack_ptr - stacking->stack_growth_direction *\n\t\tstacking->stack_registers_size;\n\txpsr = (target->endianness == TARGET_LITTLE_ENDIAN) ?\n\t\t\tle_to_h_u32(&stack_data[xpsr_offset]) :\n\t\t\tbe_to_h_u32(&stack_data[xpsr_offset]);\n\tif ((xpsr & ALIGN_NEEDED) != 0) {\n\t\tLOG_DEBUG(\"XPSR(0x%08\" PRIx32 \") indicated stack alignment was necessary\\r\\n\",\n\t\t\txpsr);\n\t\tnew_stack_ptr -= (stacking->stack_growth_direction * 4);\n\t}\n\treturn new_stack_ptr;\n}\n\nstatic target_addr_t rtos_standard_cortex_m3_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr)\n{\n\tconst int XPSR_OFFSET = 0x3c;\n\treturn rtos_cortex_m_stack_align(target, stack_data, stacking,\n\t\tstack_ptr, XPSR_OFFSET);\n}\n\nstatic target_addr_t rtos_standard_cortex_m4f_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr)\n{\n\tconst int XPSR_OFFSET = 0x40;\n\treturn rtos_cortex_m_stack_align(target, stack_data, stacking,\n\t\tstack_ptr, XPSR_OFFSET);\n}\n\nstatic target_addr_t rtos_standard_cortex_m4f_fpu_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr)\n{\n\tconst int XPSR_OFFSET = 0x80;\n\treturn rtos_cortex_m_stack_align(target, stack_data, stacking,\n\t\tstack_ptr, XPSR_OFFSET);\n}\n\n\nconst struct rtos_register_stacking rtos_standard_cortex_m3_stacking = {\n\t.stack_registers_size = 0x40,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_standard_cortex_m3_stack_align,\n\t.register_offsets = rtos_standard_cortex_m3_stack_offsets\n};\n\nconst struct rtos_register_stacking rtos_standard_cortex_m4f_stacking = {\n\t.stack_registers_size = 0x44,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_standard_cortex_m4f_stack_align,\n\t.register_offsets = rtos_standard_cortex_m4f_stack_offsets\n};\n\nconst struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking = {\n\t.stack_registers_size = 0xcc,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARMV7M_NUM_CORE_REGS,\n\t.calculate_process_stack = rtos_standard_cortex_m4f_fpu_stack_align,\n\t.register_offsets = rtos_standard_cortex_m4f_fpu_stack_offsets\n};\n\nconst struct rtos_register_stacking rtos_standard_cortex_r4_stacking = {\n\t.stack_registers_size = 0x48,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = 26,\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = rtos_standard_cortex_r4_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_standard_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_standard_cortex_m3_stacking;\nextern const struct rtos_register_stacking rtos_standard_cortex_m4f_stacking;\nextern const struct rtos_register_stacking rtos_standard_cortex_m4f_fpu_stacking;\nextern const struct rtos_register_stacking rtos_standard_cortex_r4_stacking;\ntarget_addr_t rtos_generic_stack_align8(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr);\ntarget_addr_t rtos_cortex_m_stack_align(struct target *target,\n\tconst uint8_t *stack_data, const struct rtos_register_stacking *stacking,\n\ttarget_addr_t stack_ptr, size_t xpsr_offset);\n\n#endif /* OPENOCD_RTOS_RTOS_STANDARD_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_ucos_iii_stackings.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rtos.h\"\n#include \"target/armv7m.h\"\n#include \"target/esirisc.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"rtos_ucos_iii_stackings.h\"\n\nstatic const struct stack_register_offset rtos_ucos_iii_cortex_m_stack_offsets[] = {\n\t{ ARMV7M_R0,   0x20, 32 },\t/* r0   */\n\t{ ARMV7M_R1,   0x24, 32 },\t/* r1   */\n\t{ ARMV7M_R2,   0x28, 32 },\t/* r2   */\n\t{ ARMV7M_R3,   0x2c, 32 },\t/* r3   */\n\t{ ARMV7M_R4,   0x00, 32 },\t/* r4   */\n\t{ ARMV7M_R5,   0x04, 32 },\t/* r5   */\n\t{ ARMV7M_R6,   0x08, 32 },\t/* r6   */\n\t{ ARMV7M_R7,   0x0c, 32 },\t/* r7   */\n\t{ ARMV7M_R8,   0x10, 32 },\t/* r8   */\n\t{ ARMV7M_R9,   0x14, 32 },\t/* r9   */\n\t{ ARMV7M_R10,  0x18, 32 },\t/* r10  */\n\t{ ARMV7M_R11,  0x1c, 32 },\t/* r11  */\n\t{ ARMV7M_R12,  0x30, 32 },\t/* r12  */\n\t{ ARMV7M_R13,  -2,   32 },\t/* sp   */\n\t{ ARMV7M_R14,  0x34, 32 },\t/* lr   */\n\t{ ARMV7M_PC,   0x38, 32 },\t/* pc   */\n\t{ ARMV7M_XPSR, 0x3c, 32 },\t/* xPSR */\n};\n\nstatic const struct stack_register_offset rtos_ucos_iii_esi_risc_stack_offsets[] = {\n\t{ ESIRISC_SP,  -2,   32 },\t/* sp   */\n\t{ ESIRISC_RA,  0x48, 32 },\t/* ra   */\n\t{ ESIRISC_R2,  0x44, 32 },\t/* r2   */\n\t{ ESIRISC_R3,  0x40, 32 },\t/* r3   */\n\t{ ESIRISC_R4,  0x3c, 32 },\t/* r4   */\n\t{ ESIRISC_R5,  0x38, 32 },\t/* r5   */\n\t{ ESIRISC_R6,  0x34, 32 },\t/* r6   */\n\t{ ESIRISC_R7,  0x30, 32 },\t/* r7   */\n\t{ ESIRISC_R8,  0x2c, 32 },\t/* r8   */\n\t{ ESIRISC_R9,  0x28, 32 },\t/* r9   */\n\t{ ESIRISC_R10, 0x24, 32 },\t/* r10  */\n\t{ ESIRISC_R11, 0x20, 32 },\t/* r11  */\n\t{ ESIRISC_R12, 0x1c, 32 },\t/* r12  */\n\t{ ESIRISC_R13, 0x18, 32 },\t/* r13  */\n\t{ ESIRISC_R14, 0x14, 32 },\t/* r14  */\n\t{ ESIRISC_R15, 0x10, 32 },\t/* r15  */\n\t{ ESIRISC_PC,  0x04, 32 },\t/* PC   */\n\t{ ESIRISC_CAS, 0x08, 32 },\t/* CAS  */\n};\n\nconst struct rtos_register_stacking rtos_ucos_iii_cortex_m_stacking = {\n\t.stack_registers_size = 0x40,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(rtos_ucos_iii_cortex_m_stack_offsets),\n\t.calculate_process_stack = rtos_generic_stack_align8,\n\t.register_offsets = rtos_ucos_iii_cortex_m_stack_offsets\n};\n\nconst struct rtos_register_stacking rtos_ucos_iii_esi_risc_stacking = {\n\t.stack_registers_size = 0x4c,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(rtos_ucos_iii_esi_risc_stack_offsets),\n\t.register_offsets = rtos_ucos_iii_esi_risc_stack_offsets\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/rtos_ucos_iii_stackings.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2017 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H\n#define OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H\n\n#include \"rtos.h\"\n\nextern const struct rtos_register_stacking rtos_ucos_iii_cortex_m_stacking;\nextern const struct rtos_register_stacking rtos_ucos_iii_esi_risc_stacking;\n\n#endif /* OPENOCD_RTOS_RTOS_UCOS_III_STACKINGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/uCOS-III.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n#include <rtos/rtos.h>\n#include <target/target.h>\n#include <target/target_type.h>\n\n#include \"rtos_ucos_iii_stackings.h\"\n\n#ifndef UCOS_III_MAX_STRLEN\n#define UCOS_III_MAX_STRLEN 64\n#endif\n\n#ifndef UCOS_III_MAX_THREADS\n#define UCOS_III_MAX_THREADS 256\n#endif\n\nstruct ucos_iii_params {\n\tconst char *target_name;\n\tconst unsigned char pointer_width;\n\tsize_t threadid_start;\n\tconst struct rtos_register_stacking *stacking_info;\n};\n\nstruct ucos_iii_private {\n\tconst struct ucos_iii_params *params;\n\tsymbol_address_t thread_stack_offset;\n\tsymbol_address_t thread_name_offset;\n\tsymbol_address_t thread_state_offset;\n\tsymbol_address_t thread_priority_offset;\n\tsymbol_address_t thread_prev_offset;\n\tsymbol_address_t thread_next_offset;\n\tbool thread_offsets_updated;\n\tsize_t num_threads;\n\tsymbol_address_t threads[UCOS_III_MAX_THREADS];\n};\n\nstatic const struct ucos_iii_params ucos_iii_params_list[] = {\n\t{\n\t\t.target_name    = \"cortex_m\",\n\t\t.pointer_width  = sizeof(uint32_t),\n\t\t.threadid_start = 1,\n\t\t.stacking_info  = &rtos_ucos_iii_cortex_m_stacking,\n\t},\n\t{\n\t\t.target_name    = \"esirisc\",\n\t\t.pointer_width  = sizeof(uint32_t),\n\t\t.threadid_start = 1,\n\t\t.stacking_info  = &rtos_ucos_iii_esi_risc_stacking,\n\t},\n};\n\nstatic const char * const ucos_iii_symbol_list[] = {\n\t\"OSRunning\",\n\t\"OSTCBCurPtr\",\n\t\"OSTaskDbgListPtr\",\n\t\"OSTaskQty\",\n\n\t/* also see: contrib/rtos-helpers/uCOS-III-openocd.c */\n\t\"openocd_OS_TCB_StkPtr_offset\",\n\t\"openocd_OS_TCB_NamePtr_offset\",\n\t\"openocd_OS_TCB_TaskState_offset\",\n\t\"openocd_OS_TCB_Prio_offset\",\n\t\"openocd_OS_TCB_DbgPrevPtr_offset\",\n\t\"openocd_OS_TCB_DbgNextPtr_offset\",\n\tNULL\n};\n\nenum ucos_iii_symbol_values {\n\tUCOS_III_VAL_OS_RUNNING,\n\tUCOS_III_VAL_OS_TCB_CUR_PTR,\n\tUCOS_III_VAL_OS_TASK_DBG_LIST_PTR,\n\tUCOS_III_VAL_OS_TASK_QTY,\n\n\t/* also see: contrib/rtos-helpers/uCOS-III-openocd.c */\n\tUCOS_III_VAL_OS_TCB_STK_PTR_OFFSET,\n\tUCOS_III_VAL_OS_TCB_NAME_PTR_OFFSET,\n\tUCOS_III_VAL_OS_TCB_TASK_STATE_OFFSET,\n\tUCOS_III_VAL_OS_TCB_PRIO_OFFSET,\n\tUCOS_III_VAL_OS_TCB_DBG_PREV_PTR_OFFSET,\n\tUCOS_III_VAL_OS_TCB_DBG_NEXT_PTR_OFFSET,\n};\n\nstatic const char * const ucos_iii_thread_state_list[] = {\n\t\"Ready\",\n\t\"Delay\",\n\t\"Pend\",\n\t\"Pend Timeout\",\n\t\"Suspended\",\n\t\"Delay Suspended\",\n\t\"Pend Suspended\",\n\t\"Pend Timeout Suspended\",\n};\n\nstatic int ucos_iii_find_or_create_thread(struct rtos *rtos, symbol_address_t thread_address,\n\t\tthreadid_t *threadid)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\tsize_t thread_index;\n\n\tfor (thread_index = 0; thread_index < params->num_threads; thread_index++)\n\t\tif (params->threads[thread_index] == thread_address)\n\t\t\tgoto found;\n\n\tif (params->num_threads == UCOS_III_MAX_THREADS) {\n\t\tLOG_WARNING(\"uCOS-III: too many threads; increase UCOS_III_MAX_THREADS\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tparams->threads[thread_index] = thread_address;\n\tparams->num_threads++;\nfound:\n\t*threadid = thread_index + params->params->threadid_start;\n\treturn ERROR_OK;\n}\n\nstatic int ucos_iii_find_thread_address(struct rtos *rtos, threadid_t threadid,\n\t\tsymbol_address_t *thread_address)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\tsize_t thread_index;\n\n\tthread_index = threadid - params->params->threadid_start;\n\tif (thread_index >= params->num_threads) {\n\t\tLOG_ERROR(\"uCOS-III: failed to find thread address\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*thread_address = params->threads[thread_index];\n\treturn ERROR_OK;\n}\n\nstatic int ucos_iii_find_last_thread_address(struct rtos *rtos, symbol_address_t *thread_address)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\tint retval;\n\n\t/* read the thread list head */\n\tsymbol_address_t thread_list_address = 0;\n\n\tretval = target_read_memory(rtos->target,\n\t\t\trtos->symbols[UCOS_III_VAL_OS_TASK_DBG_LIST_PTR].address,\n\t\t\tparams->params->pointer_width,\n\t\t\t1,\n\t\t\t(void *)&thread_list_address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to read thread list address\");\n\t\treturn retval;\n\t}\n\n\t/* advance to end of thread list */\n\tdo {\n\t\t*thread_address = thread_list_address;\n\n\t\tretval = target_read_memory(rtos->target,\n\t\t\t\tthread_list_address + params->thread_next_offset,\n\t\t\t\tparams->params->pointer_width,\n\t\t\t\t1,\n\t\t\t\t(void *)&thread_list_address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read next thread address\");\n\t\t\treturn retval;\n\t\t}\n\t} while (thread_list_address != 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int ucos_iii_update_thread_offsets(struct rtos *rtos)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\n\tif (params->thread_offsets_updated)\n\t\treturn ERROR_OK;\n\n\tconst struct thread_offset_map {\n\t\tenum ucos_iii_symbol_values symbol_value;\n\t\tsymbol_address_t *thread_offset;\n\t} thread_offset_maps[] = {\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_STK_PTR_OFFSET,\n\t\t\t&params->thread_stack_offset,\n\t\t},\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_NAME_PTR_OFFSET,\n\t\t\t&params->thread_name_offset,\n\t\t},\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_TASK_STATE_OFFSET,\n\t\t\t&params->thread_state_offset,\n\t\t},\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_PRIO_OFFSET,\n\t\t\t&params->thread_priority_offset,\n\t\t},\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_DBG_PREV_PTR_OFFSET,\n\t\t\t&params->thread_prev_offset,\n\t\t},\n\t\t{\n\t\t\tUCOS_III_VAL_OS_TCB_DBG_NEXT_PTR_OFFSET,\n\t\t\t&params->thread_next_offset,\n\t\t},\n\t};\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(thread_offset_maps); i++) {\n\t\tconst struct thread_offset_map *thread_offset_map = &thread_offset_maps[i];\n\n\t\tint retval = target_read_memory(rtos->target,\n\t\t\t\trtos->symbols[thread_offset_map->symbol_value].address,\n\t\t\t\tparams->params->pointer_width,\n\t\t\t\t1,\n\t\t\t\t(void *)thread_offset_map->thread_offset);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read thread offset\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tparams->thread_offsets_updated = true;\n\treturn ERROR_OK;\n}\n\nstatic bool ucos_iii_detect_rtos(struct target *target)\n{\n\treturn target->rtos->symbols &&\n\t\t\ttarget->rtos->symbols[UCOS_III_VAL_OS_RUNNING].address != 0;\n}\n\nstatic int ucos_iii_reset_handler(struct target *target, enum target_reset_mode reset_mode, void *priv)\n{\n\tstruct ucos_iii_private *params = target->rtos->rtos_specific_params;\n\n\tparams->thread_offsets_updated = false;\n\tparams->num_threads = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int ucos_iii_create(struct target *target)\n{\n\tstruct ucos_iii_private *params;\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(ucos_iii_params_list); i++)\n\t\tif (strcmp(ucos_iii_params_list[i].target_name, target->type->name) == 0) {\n\t\t\tparams = calloc(1, sizeof(*params));\n\t\t\tif (!params) {\n\t\t\t\tLOG_ERROR(\"uCOS-III: out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tparams->params = &ucos_iii_params_list[i];\n\t\t\ttarget->rtos->rtos_specific_params = (void *)params;\n\n\t\t\ttarget_register_reset_callback(ucos_iii_reset_handler, NULL);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\tLOG_ERROR(\"uCOS-III: target not supported: %s\", target->type->name);\n\treturn ERROR_FAIL;\n}\n\nstatic int ucos_iii_update_threads(struct rtos *rtos)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\tint retval;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"uCOS-III: symbol list not loaded\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* free previous thread details */\n\trtos_free_threadlist(rtos);\n\n\t/* verify RTOS is running */\n\tuint8_t rtos_running;\n\n\tretval = target_read_u8(rtos->target,\n\t\t\trtos->symbols[UCOS_III_VAL_OS_RUNNING].address,\n\t\t\t&rtos_running);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to read RTOS running\");\n\t\treturn retval;\n\t}\n\n\tif (rtos_running != 1 && rtos_running != 0) {\n\t\tLOG_ERROR(\"uCOS-III: invalid RTOS running value\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!rtos_running) {\n\t\trtos->thread_details = calloc(1, sizeof(struct thread_detail));\n\t\tif (!rtos->thread_details) {\n\t\t\tLOG_ERROR(\"uCOS-III: out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\trtos->thread_count = 1;\n\t\trtos->thread_details->threadid = 0;\n\t\trtos->thread_details->exists = true;\n\t\trtos->current_thread = 0;\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* update thread offsets */\n\tretval = ucos_iii_update_thread_offsets(rtos);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to update thread offsets\");\n\t\treturn retval;\n\t}\n\n\t/* read current thread address */\n\tsymbol_address_t current_thread_address = 0;\n\n\tretval = target_read_memory(rtos->target,\n\t\t\trtos->symbols[UCOS_III_VAL_OS_TCB_CUR_PTR].address,\n\t\t\tparams->params->pointer_width,\n\t\t\t1,\n\t\t\t(void *)&current_thread_address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to read current thread address\");\n\t\treturn retval;\n\t}\n\n\t/* read number of tasks */\n\tretval = target_read_u16(rtos->target,\n\t\t\trtos->symbols[UCOS_III_VAL_OS_TASK_QTY].address,\n\t\t\t(void *)&rtos->thread_count);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to read thread count\");\n\t\treturn retval;\n\t}\n\n\trtos->thread_details = calloc(rtos->thread_count, sizeof(struct thread_detail));\n\tif (!rtos->thread_details) {\n\t\tLOG_ERROR(\"uCOS-III: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*\n\t * uC/OS-III adds tasks in LIFO order; advance to the end of the\n\t * list and work backwards to preserve the intended order.\n\t */\n\tsymbol_address_t thread_address = 0;\n\n\tretval = ucos_iii_find_last_thread_address(rtos, &thread_address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to find last thread address\");\n\t\treturn retval;\n\t}\n\n\tfor (int i = 0; i < rtos->thread_count; i++) {\n\t\tstruct thread_detail *thread_detail = &rtos->thread_details[i];\n\t\tchar thread_str_buffer[UCOS_III_MAX_STRLEN + 1];\n\n\t\t/* find or create new threadid */\n\t\tretval = ucos_iii_find_or_create_thread(rtos, thread_address, &thread_detail->threadid);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to find or create thread\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (thread_address == current_thread_address)\n\t\t\trtos->current_thread = thread_detail->threadid;\n\n\t\tthread_detail->exists = true;\n\n\t\t/* read thread name */\n\t\tsymbol_address_t thread_name_address = 0;\n\n\t\tretval = target_read_memory(rtos->target,\n\t\t\t\tthread_address + params->thread_name_offset,\n\t\t\t\tparams->params->pointer_width,\n\t\t\t\t1,\n\t\t\t\t(void *)&thread_name_address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to name address\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\tthread_name_address,\n\t\t\t\tsizeof(thread_str_buffer),\n\t\t\t\t(void *)thread_str_buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read thread name\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tthread_str_buffer[sizeof(thread_str_buffer) - 1] = '\\0';\n\t\tthread_detail->thread_name_str = strdup(thread_str_buffer);\n\n\t\t/* read thread extra info */\n\t\tuint8_t thread_state;\n\t\tuint8_t thread_priority;\n\n\t\tretval = target_read_u8(rtos->target,\n\t\t\t\tthread_address + params->thread_state_offset,\n\t\t\t\t&thread_state);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read thread state\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tretval = target_read_u8(rtos->target,\n\t\t\t\tthread_address + params->thread_priority_offset,\n\t\t\t\t&thread_priority);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read thread priority\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tconst char *thread_state_str;\n\n\t\tif (thread_state < ARRAY_SIZE(ucos_iii_thread_state_list))\n\t\t\tthread_state_str = ucos_iii_thread_state_list[thread_state];\n\t\telse\n\t\t\tthread_state_str = \"Unknown\";\n\n\t\tsnprintf(thread_str_buffer, sizeof(thread_str_buffer), \"State: %s, Priority: %d\",\n\t\t\t\tthread_state_str, thread_priority);\n\t\tthread_detail->extra_info_str = strdup(thread_str_buffer);\n\n\t\t/* read previous thread address */\n\t\tretval = target_read_memory(rtos->target,\n\t\t\t\tthread_address + params->thread_prev_offset,\n\t\t\t\tparams->params->pointer_width,\n\t\t\t\t1,\n\t\t\t\t(void *)&thread_address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"uCOS-III: failed to read previous thread address\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ucos_iii_get_thread_reg_list(struct rtos *rtos, threadid_t threadid,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tstruct ucos_iii_private *params = rtos->rtos_specific_params;\n\tint retval;\n\n\t/* find thread address for threadid */\n\tsymbol_address_t thread_address = 0;\n\n\tretval = ucos_iii_find_thread_address(rtos, threadid, &thread_address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to find thread address\");\n\t\treturn retval;\n\t}\n\n\t/* read thread stack address */\n\tsymbol_address_t stack_address = 0;\n\n\tretval = target_read_memory(rtos->target,\n\t\t\tthread_address + params->thread_stack_offset,\n\t\t\tparams->params->pointer_width,\n\t\t\t1,\n\t\t\t(void *)&stack_address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"uCOS-III: failed to read stack address\");\n\t\treturn retval;\n\t}\n\n\treturn rtos_generic_stack_read(rtos->target,\n\t\t\tparams->params->stacking_info,\n\t\t\tstack_address,\n\t\t\treg_list,\n\t\t\tnum_regs);\n}\n\nstatic int ucos_iii_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])\n{\n\t*symbol_list = calloc(ARRAY_SIZE(ucos_iii_symbol_list), sizeof(struct symbol_table_elem));\n\tif (!*symbol_list) {\n\t\tLOG_ERROR(\"uCOS-III: out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(ucos_iii_symbol_list); i++)\n\t\t(*symbol_list)[i].symbol_name = ucos_iii_symbol_list[i];\n\n\treturn ERROR_OK;\n}\n\nconst struct rtos_type ucos_iii_rtos = {\n\t.name = \"uCOS-III\",\n\t.detect_rtos = ucos_iii_detect_rtos,\n\t.create = ucos_iii_create,\n\t.update_threads = ucos_iii_update_threads,\n\t.get_thread_reg_list = ucos_iii_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = ucos_iii_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtos/zephyr.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2017 by Intel Corporation\n *   Leandro Pereira <leandro.pereira@intel.com>\n *   Daniel Glöckner <dg@emlix.com>*\n *   Copyright (C) 2021 by Synopsys, Inc.\n *   Evgeniy Didin <didin@synopsys.com>\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n\n#include \"helper/log.h\"\n#include \"helper/types.h\"\n#include \"rtos.h\"\n#include \"rtos_standard_stackings.h\"\n#include \"target/target.h\"\n#include \"target/target_type.h\"\n#include \"target/armv7m.h\"\n#include \"target/arc.h\"\n\n#define UNIMPLEMENTED 0xFFFFFFFFU\n\n/* ARC specific defines */\n#define ARC_AUX_SEC_BUILD_REG 0xdb\n#define ARC_REG_NUM 38\n\n/* ARM specific defines */\n#define ARM_XPSR_OFFSET 28\n\nstruct zephyr_thread {\n\tuint32_t ptr, next_ptr;\n\tuint32_t entry;\n\tuint32_t stack_pointer;\n\tuint8_t state;\n\tuint8_t user_options;\n\tint8_t prio;\n\tchar name[64];\n};\n\nenum zephyr_offsets {\n\tOFFSET_VERSION,\n\tOFFSET_K_CURR_THREAD,\n\tOFFSET_K_THREADS,\n\tOFFSET_T_ENTRY,\n\tOFFSET_T_NEXT_THREAD,\n\tOFFSET_T_STATE,\n\tOFFSET_T_USER_OPTIONS,\n\tOFFSET_T_PRIO,\n\tOFFSET_T_STACK_POINTER,\n\tOFFSET_T_NAME,\n\tOFFSET_T_ARCH,\n\tOFFSET_T_PREEMPT_FLOAT,\n\tOFFSET_T_COOP_FLOAT,\n\tOFFSET_MAX\n};\n\nstruct zephyr_params {\n\tconst char *target_name;\n\tuint8_t size_width;\n\tuint8_t pointer_width;\n\tuint32_t num_offsets;\n\tuint32_t offsets[OFFSET_MAX];\n\tconst struct rtos_register_stacking *callee_saved_stacking;\n\tconst struct rtos_register_stacking *cpu_saved_nofp_stacking;\n\tconst struct rtos_register_stacking *cpu_saved_fp_stacking;\n\tint (*get_cpu_state)(struct rtos *rtos, target_addr_t *addr,\n\t\t\tstruct zephyr_params *params,\n\t\t\tstruct rtos_reg *callee_saved_reg_list,\n\t\t\tstruct rtos_reg **reg_list, int *num_regs);\n};\n\nstatic const struct stack_register_offset arm_callee_saved[] = {\n\t{ ARMV7M_R13, 32, 32 },\n\t{ ARMV7M_R4,  0,  32 },\n\t{ ARMV7M_R5,  4,  32 },\n\t{ ARMV7M_R6,  8,  32 },\n\t{ ARMV7M_R7,  12, 32 },\n\t{ ARMV7M_R8,  16, 32 },\n\t{ ARMV7M_R9,  20, 32 },\n\t{ ARMV7M_R10, 24, 32 },\n\t{ ARMV7M_R11, 28, 32 },\n};\n\nstatic const struct stack_register_offset arc_callee_saved[] = {\n\t{ ARC_R13,  0,  32 },\n\t{ ARC_R14,  4,  32 },\n\t{ ARC_R15,  8,  32 },\n\t{ ARC_R16,  12,  32 },\n\t{ ARC_R17,  16,  32 },\n\t{ ARC_R18,  20,  32 },\n\t{ ARC_R19,  24,  32 },\n\t{ ARC_R20,  28,  32 },\n\t{ ARC_R21,  32,  32 },\n\t{ ARC_R22,  36,  32 },\n\t{ ARC_R23,  40,  32 },\n\t{ ARC_R24,  44,  32 },\n\t{ ARC_R25,  48,  32 },\n\t{ ARC_GP,  52,  32 },\n\t{ ARC_FP,  56,  32 },\n\t{ ARC_R30,  60,  32 }\n};\nstatic const struct rtos_register_stacking arm_callee_saved_stacking = {\n\t.stack_registers_size = 36,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(arm_callee_saved),\n\t.register_offsets = arm_callee_saved,\n};\n\nstatic const struct rtos_register_stacking arc_callee_saved_stacking = {\n\t.stack_registers_size = 64,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(arc_callee_saved),\n\t.register_offsets = arc_callee_saved,\n};\n\nstatic const struct stack_register_offset arm_cpu_saved[] = {\n\t{ ARMV7M_R0,   0,  32 },\n\t{ ARMV7M_R1,   4,  32 },\n\t{ ARMV7M_R2,   8,  32 },\n\t{ ARMV7M_R3,   12, 32 },\n\t{ ARMV7M_R4,   -1, 32 },\n\t{ ARMV7M_R5,   -1, 32 },\n\t{ ARMV7M_R6,   -1, 32 },\n\t{ ARMV7M_R7,   -1, 32 },\n\t{ ARMV7M_R8,   -1, 32 },\n\t{ ARMV7M_R9,   -1, 32 },\n\t{ ARMV7M_R10,  -1, 32 },\n\t{ ARMV7M_R11,  -1, 32 },\n\t{ ARMV7M_R12,  16, 32 },\n\t{ ARMV7M_R13,  -2, 32 },\n\t{ ARMV7M_R14,  20, 32 },\n\t{ ARMV7M_PC,   24, 32 },\n\t{ ARMV7M_XPSR, 28, 32 },\n};\n\nstatic struct stack_register_offset arc_cpu_saved[] = {\n\t{ ARC_R0,\t\t-1,  32 },\n\t{ ARC_R1,\t\t-1,  32 },\n\t{ ARC_R2,\t\t-1,  32 },\n\t{ ARC_R3,\t\t-1,  32 },\n\t{ ARC_R4,\t\t-1,  32 },\n\t{ ARC_R5,\t\t-1,  32 },\n\t{ ARC_R6,\t\t-1,  32 },\n\t{ ARC_R7,\t\t-1,  32 },\n\t{ ARC_R8,\t\t-1,  32 },\n\t{ ARC_R9,\t\t-1,  32\t},\n\t{ ARC_R10,\t\t-1,  32\t},\n\t{ ARC_R11,\t\t-1,  32 },\n\t{ ARC_R12,\t\t-1,  32 },\n\t{ ARC_R13,\t\t-1,  32 },\n\t{ ARC_R14,\t\t-1,  32 },\n\t{ ARC_R15,\t\t-1,  32 },\n\t{ ARC_R16,\t\t-1,  32 },\n\t{ ARC_R17,\t\t-1,  32 },\n\t{ ARC_R18,\t\t-1,  32 },\n\t{ ARC_R19,\t\t-1,  32 },\n\t{ ARC_R20,\t\t-1,  32 },\n\t{ ARC_R21,\t\t-1,  32 },\n\t{ ARC_R22,\t\t-1,  32 },\n\t{ ARC_R23,\t\t-1,  32 },\n\t{ ARC_R24,\t\t-1,  32 },\n\t{ ARC_R25,\t\t-1,  32 },\n\t{ ARC_GP,\t\t-1,  32 },\n\t{ ARC_FP,\t\t-1,  32 },\n\t{ ARC_SP,\t\t-1,  32 },\n\t{ ARC_ILINK,\t\t-1,  32 },\n\t{ ARC_R30,\t\t-1,  32 },\n\t{ ARC_BLINK,\t\t 0,  32 },\n\t{ ARC_LP_COUNT,\t\t-1,  32 },\n\t{ ARC_PCL,\t\t-1,  32 },\n\t{ ARC_PC,\t\t-1,  32 },\n\t{ ARC_LP_START,\t\t-1,  32 },\n\t{ ARC_LP_END,\t\t-1,  32 },\n\t{ ARC_STATUS32,\t\t 4,  32 }\n};\n\n\nenum zephyr_symbol_values {\n\tZEPHYR_VAL__KERNEL,\n\tZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS,\n\tZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE,\n\tZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS,\n\tZEPHYR_VAL_COUNT\n};\n\nstatic target_addr_t zephyr_cortex_m_stack_align(struct target *target,\n\t\tconst uint8_t *stack_data,\n\t\tconst struct rtos_register_stacking *stacking, target_addr_t stack_ptr)\n{\n\treturn rtos_cortex_m_stack_align(target, stack_data, stacking,\n\t\t\tstack_ptr, ARM_XPSR_OFFSET);\n}\n\nstatic const struct rtos_register_stacking arm_cpu_saved_nofp_stacking = {\n\t.stack_registers_size = 32,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(arm_cpu_saved),\n\t.calculate_process_stack = zephyr_cortex_m_stack_align,\n\t.register_offsets = arm_cpu_saved,\n};\n\nstatic const struct rtos_register_stacking arm_cpu_saved_fp_stacking = {\n\t.stack_registers_size = 32 + 18 * 4,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(arm_cpu_saved),\n\t.calculate_process_stack = zephyr_cortex_m_stack_align,\n\t.register_offsets = arm_cpu_saved,\n};\n\n/* stack_registers_size is 8 because besides caller registers\n * there are only blink and Status32 registers on stack left */\nstatic struct rtos_register_stacking arc_cpu_saved_stacking = {\n\t.stack_registers_size = 8,\n\t.stack_growth_direction = -1,\n\t.num_output_registers = ARRAY_SIZE(arc_cpu_saved),\n\t.register_offsets = arc_cpu_saved,\n};\n\n/* ARCv2 specific implementation */\nstatic int zephyr_get_arc_state(struct rtos *rtos, target_addr_t *addr,\n\t\t\t struct zephyr_params *params,\n\t\t\t struct rtos_reg *callee_saved_reg_list,\n\t\t\t struct rtos_reg **reg_list, int *num_regs)\n{\n\n\tuint32_t real_stack_addr;\n\tint retval = 0;\n\tint num_callee_saved_regs;\n\tconst struct rtos_register_stacking *stacking;\n\n\t/* Getting real stack address from Kernel thread struct */\n\tretval = target_read_u32(rtos->target, *addr, &real_stack_addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Getting callee registers */\n\tretval = rtos_generic_stack_read(rtos->target,\n\t\t\tparams->callee_saved_stacking,\n\t\t\treal_stack_addr, &callee_saved_reg_list,\n\t\t\t&num_callee_saved_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstacking = params->cpu_saved_nofp_stacking;\n\n\t/* Getting blink and status32 registers */\n\tretval = rtos_generic_stack_read(rtos->target, stacking,\n\t\t\treal_stack_addr + num_callee_saved_regs * 4,\n\t\t\treg_list, num_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (int i = 0; i < num_callee_saved_regs; i++)\n\t\tbuf_cpy(callee_saved_reg_list[i].value,\n\t\t\t(*reg_list)[callee_saved_reg_list[i].number].value,\n\t\t\tcallee_saved_reg_list[i].size);\n\n\t/* The blink, sp, pc offsets in arc_cpu_saved structure may be changed,\n\t * but the registers number shall not. So the next code searches the\n\t * offsetst of these registers in arc_cpu_saved structure. */\n\tunsigned short blink_offset = 0, pc_offset = 0, sp_offset = 0;\n\tfor (size_t i = 0; i < ARRAY_SIZE(arc_cpu_saved); i++) {\n\t\tif (arc_cpu_saved[i].number == ARC_BLINK)\n\t\t\tblink_offset = i;\n\t\tif (arc_cpu_saved[i].number == ARC_SP)\n\t\t\tsp_offset = i;\n\t\tif (arc_cpu_saved[i].number == ARC_PC)\n\t\t\tpc_offset = i;\n\t}\n\n\tif (blink_offset == 0 || sp_offset == 0 || pc_offset == 0) {\n\t\tLOG_ERROR(\"Basic registers offsets are missing, check <arc_cpu_saved> struct\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Put blink value into PC */\n\tbuf_cpy((*reg_list)[blink_offset].value,\n\t\t(*reg_list)[pc_offset].value, sizeof((*reg_list)[blink_offset].value));\n\n\t/* Put address after callee/caller in SP. */\n\tint64_t stack_top;\n\n\tstack_top = real_stack_addr + num_callee_saved_regs * 4\n\t\t\t+ arc_cpu_saved_stacking.stack_registers_size;\n\tbuf_cpy(&stack_top, (*reg_list)[sp_offset].value, sizeof(stack_top));\n\n\treturn retval;\n}\n\n/* ARM Cortex-M-specific implementation */\nstatic int zephyr_get_arm_state(struct rtos *rtos, target_addr_t *addr,\n\t\t\t struct zephyr_params *params,\n\t\t\t struct rtos_reg *callee_saved_reg_list,\n\t\t\t struct rtos_reg **reg_list, int *num_regs)\n{\n\n\tint retval = 0;\n\tint num_callee_saved_regs;\n\tconst struct rtos_register_stacking *stacking;\n\n\tretval = rtos_generic_stack_read(rtos->target,\n\t\t\tparams->callee_saved_stacking,\n\t\t\t*addr, &callee_saved_reg_list,\n\t\t\t&num_callee_saved_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*addr = target_buffer_get_u32(rtos->target,\n\t\t\tcallee_saved_reg_list[0].value);\n\n\tif (params->offsets[OFFSET_T_PREEMPT_FLOAT] != UNIMPLEMENTED)\n\t\tstacking = params->cpu_saved_fp_stacking;\n\telse\n\t\tstacking = params->cpu_saved_nofp_stacking;\n\n\tretval = rtos_generic_stack_read(rtos->target, stacking, *addr, reg_list,\n\t\t\tnum_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (int i = 1; i < num_callee_saved_regs; i++)\n\t\tbuf_cpy(callee_saved_reg_list[i].value,\n\t\t\t(*reg_list)[callee_saved_reg_list[i].number].value,\n\t\t\tcallee_saved_reg_list[i].size);\n\treturn 0;\n}\n\nstatic struct zephyr_params zephyr_params_list[] = {\n\t{\n\t\t.target_name = \"cortex_m\",\n\t\t.pointer_width = 4,\n\t\t.callee_saved_stacking = &arm_callee_saved_stacking,\n\t\t.cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,\n\t\t.cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,\n\t\t.get_cpu_state = &zephyr_get_arm_state,\n\t},\n\t{\n\t\t.target_name = \"cortex_r4\",\n\t\t.pointer_width = 4,\n\t\t.callee_saved_stacking = &arm_callee_saved_stacking,\n\t\t.cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,\n\t\t.cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,\n\t\t.get_cpu_state = &zephyr_get_arm_state,\n\t},\n\t{\n\t\t.target_name = \"hla_target\",\n\t\t.pointer_width = 4,\n\t\t.callee_saved_stacking = &arm_callee_saved_stacking,\n\t\t.cpu_saved_nofp_stacking = &arm_cpu_saved_nofp_stacking,\n\t\t.cpu_saved_fp_stacking = &arm_cpu_saved_fp_stacking,\n\t\t.get_cpu_state = &zephyr_get_arm_state,\n\n\t},\n\t{\n\t\t.target_name = \"arcv2\",\n\t\t.pointer_width = 4,\n\t\t.callee_saved_stacking = &arc_callee_saved_stacking,\n\t\t.cpu_saved_nofp_stacking = &arc_cpu_saved_stacking,\n\t\t.get_cpu_state = &zephyr_get_arc_state,\n\t},\n\t{\n\t\t.target_name = NULL\n\t}\n};\n\nstatic const struct symbol_table_elem zephyr_symbol_list[] = {\n\t{\n\t\t.symbol_name = \"_kernel\",\n\t\t.optional = false\n\t},\n\t{\n\t\t.symbol_name = \"_kernel_thread_info_offsets\",\n\t\t.optional = false\n\t},\n\t{\n\t\t.symbol_name = \"_kernel_thread_info_size_t_size\",\n\t\t.optional = false\n\t},\n\t{\n\t\t.symbol_name = \"_kernel_thread_info_num_offsets\",\n\t\t.optional = true\n\t},\n\t{\n\t\t.symbol_name = NULL\n\t}\n};\n\nstatic bool zephyr_detect_rtos(struct target *target)\n{\n\tif (!target->rtos->symbols) {\n\t\tLOG_INFO(\"Zephyr: no symbols while detecting RTOS\");\n\t\treturn false;\n\t}\n\n\tfor (enum zephyr_symbol_values symbol = ZEPHYR_VAL__KERNEL;\n\t\t\t\t\tsymbol != ZEPHYR_VAL_COUNT; symbol++) {\n\t\tLOG_INFO(\"Zephyr: does it have symbol %d (%s)?\", symbol,\n\t\t\ttarget->rtos->symbols[symbol].optional ? \"optional\" : \"mandatory\");\n\n\t\tif (target->rtos->symbols[symbol].optional)\n\t\t\tcontinue;\n\t\tif (target->rtos->symbols[symbol].address == 0)\n\t\t\treturn false;\n\t}\n\n\tLOG_INFO(\"Zephyr: all mandatory symbols found\");\n\n\treturn true;\n}\n\nstatic int zephyr_create(struct target *target)\n{\n\tconst char *name;\n\n\tname = target_type_name(target);\n\n\tLOG_INFO(\"Zephyr: looking for target: %s\", name);\n\n\t/* ARC specific, check if EM target has security subsystem\n\t * In case of ARC_HAS_SECURE zephyr option enabled\n\t * the thread stack contains blink,sec_stat,status32 register\n\t * values. If ARC_HAS_SECURE is disabled, only blink and status32\n\t * register values are saved on stack. */\n\tif (!strcmp(name, \"arcv2\")) {\n\t\tuint32_t value;\n\t\tstruct arc_common *arc = target_to_arc(target);\n\t\t/* Reading SEC_BUILD bcr */\n\t\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, ARC_AUX_SEC_BUILD_REG, &value));\n\t\tif (value != 0) {\n\t\t\tLOG_DEBUG(\"ARC EM board has security subsystem, changing offsets\");\n\t\t\tarc_cpu_saved[ARC_REG_NUM - 1].offset = 8;\n\t\t\t/* After reading callee registers in stack\n\t\t\t * now blink,sec_stat,status32 registers\n\t\t\t * are located. */\n\t\t\tarc_cpu_saved_stacking.stack_registers_size = 12;\n\t\t}\n\t}\n\n\tfor (struct zephyr_params *p = zephyr_params_list; p->target_name; p++) {\n\t\tif (!strcmp(p->target_name, name)) {\n\t\t\tLOG_INFO(\"Zephyr: target known, params at %p\", p);\n\t\t\ttarget->rtos->rtos_specific_params = p;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"Could not find target in Zephyr compatibility list\");\n\treturn ERROR_FAIL;\n}\n\nstruct zephyr_array {\n\tvoid *ptr;\n\tsize_t elements;\n};\n\nstatic void zephyr_array_init(struct zephyr_array *array)\n{\n\tarray->ptr = NULL;\n\tarray->elements = 0;\n}\n\nstatic void zephyr_array_free(struct zephyr_array *array)\n{\n\tfree(array->ptr);\n\tzephyr_array_init(array);\n}\n\nstatic void *zephyr_array_append(struct zephyr_array *array, size_t size)\n{\n\tif (!(array->elements % 16)) {\n\t\tvoid *ptr = realloc(array->ptr, (array->elements + 16) * size);\n\n\t\tif (!ptr) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\tarray->ptr = ptr;\n\t}\n\n\treturn (unsigned char *)array->ptr + (array->elements++) * size;\n}\n\nstatic void *zephyr_array_detach_ptr(struct zephyr_array *array)\n{\n\tvoid *ptr = array->ptr;\n\n\tzephyr_array_init(array);\n\n\treturn ptr;\n}\n\nstatic uint32_t zephyr_kptr(const struct rtos *rtos, enum zephyr_offsets off)\n{\n\tconst struct zephyr_params *params = rtos->rtos_specific_params;\n\n\treturn rtos->symbols[ZEPHYR_VAL__KERNEL].address + params->offsets[off];\n}\n\nstatic int zephyr_fetch_thread(const struct rtos *rtos,\n\t\t\t\tstruct zephyr_thread *thread, uint32_t ptr)\n{\n\tconst struct zephyr_params *param = rtos->rtos_specific_params;\n\tint retval;\n\n\tthread->ptr = ptr;\n\n\tretval = target_read_u32(rtos->target, ptr + param->offsets[OFFSET_T_ENTRY],\n\t\t\t\t &thread->entry);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(rtos->target,\n\t\t\t\t ptr + param->offsets[OFFSET_T_NEXT_THREAD],\n\t\t\t\t &thread->next_ptr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(rtos->target,\n\t\t\t\t ptr + param->offsets[OFFSET_T_STACK_POINTER],\n\t\t\t\t &thread->stack_pointer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u8(rtos->target, ptr + param->offsets[OFFSET_T_STATE],\n\t\t\t\t&thread->state);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u8(rtos->target,\n\t\t\t\tptr + param->offsets[OFFSET_T_USER_OPTIONS],\n\t\t\t\t&thread->user_options);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t prio;\n\tretval = target_read_u8(rtos->target,\n\t\t\t\tptr + param->offsets[OFFSET_T_PRIO], &prio);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tthread->prio = prio;\n\n\tthread->name[0] = '\\0';\n\tif (param->offsets[OFFSET_T_NAME] != UNIMPLEMENTED) {\n\t\tretval = target_read_buffer(rtos->target,\n\t\t\t\t\tptr + param->offsets[OFFSET_T_NAME],\n\t\t\t\t\tsizeof(thread->name) - 1, (uint8_t *)thread->name);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tthread->name[sizeof(thread->name) - 1] = '\\0';\n\t}\n\n\tLOG_DEBUG(\"Fetched thread%\" PRIx32 \": {entry@0x%\" PRIx32\n\t\t\", state=%\" PRIu8 \", useropts=%\" PRIu8 \", prio=%\" PRId8 \"}\",\n\t\tptr, thread->entry, thread->state, thread->user_options, thread->prio);\n\n\treturn ERROR_OK;\n}\n\nstatic int zephyr_fetch_thread_list(struct rtos *rtos, uint32_t current_thread)\n{\n\tstruct zephyr_array thread_array;\n\tstruct zephyr_thread thread;\n\tstruct thread_detail *td;\n\tint64_t curr_id = -1;\n\tuint32_t curr;\n\tint retval;\n\n\tretval = target_read_u32(rtos->target, zephyr_kptr(rtos, OFFSET_K_THREADS),\n\t\t&curr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not fetch current thread pointer\");\n\t\treturn retval;\n\t}\n\n\tzephyr_array_init(&thread_array);\n\n\tfor (; curr; curr = thread.next_ptr) {\n\t\tretval = zephyr_fetch_thread(rtos, &thread, curr);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto error;\n\n\t\ttd = zephyr_array_append(&thread_array, sizeof(*td));\n\t\tif (!td)\n\t\t\tgoto error;\n\n\t\ttd->threadid = thread.ptr;\n\t\ttd->exists = true;\n\n\t\tif (thread.name[0])\n\t\t\ttd->thread_name_str = strdup(thread.name);\n\t\telse\n\t\t\ttd->thread_name_str = alloc_printf(\"thr_%\" PRIx32 \"_%\" PRIx32,\n\t\t\t\t\t\t\t   thread.entry, thread.ptr);\n\t\ttd->extra_info_str = alloc_printf(\"prio:%\" PRId8 \",useropts:%\" PRIu8,\n\t\t\t\t\t\t  thread.prio, thread.user_options);\n\t\tif (!td->thread_name_str || !td->extra_info_str)\n\t\t\tgoto error;\n\n\t\tif (td->threadid == current_thread)\n\t\t\tcurr_id = (int64_t)thread_array.elements - 1;\n\t}\n\n\tLOG_DEBUG(\"Got information for %zu threads\", thread_array.elements);\n\n\trtos_free_threadlist(rtos);\n\n\trtos->thread_count = (int)thread_array.elements;\n\trtos->thread_details = zephyr_array_detach_ptr(&thread_array);\n\n\trtos->current_threadid = curr_id;\n\trtos->current_thread = current_thread;\n\n\treturn ERROR_OK;\n\nerror:\n\ttd = thread_array.ptr;\n\tfor (size_t i = 0; i < thread_array.elements; i++) {\n\t\tfree(td[i].thread_name_str);\n\t\tfree(td[i].extra_info_str);\n\t}\n\n\tzephyr_array_free(&thread_array);\n\n\treturn ERROR_FAIL;\n}\n\nstatic int zephyr_update_threads(struct rtos *rtos)\n{\n\tstruct zephyr_params *param;\n\tint retval;\n\n\tif (!rtos->rtos_specific_params)\n\t\treturn ERROR_FAIL;\n\n\tparam = (struct zephyr_params *)rtos->rtos_specific_params;\n\n\tif (!rtos->symbols) {\n\t\tLOG_ERROR(\"No symbols for Zephyr\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rtos->symbols[ZEPHYR_VAL__KERNEL].address == 0) {\n\t\tLOG_ERROR(\"Can't obtain kernel struct from Zephyr\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address == 0) {\n\t\tLOG_ERROR(\"Please build Zephyr with CONFIG_OPENOCD option set\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target_read_u8(rtos->target,\n\t\trtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_SIZE_T_SIZE].address,\n\t\t&param->size_width);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Couldn't determine size of size_t from host\");\n\t\treturn retval;\n\t}\n\n\tif (param->size_width != 4) {\n\t\tLOG_ERROR(\"Only size_t of 4 bytes are supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address) {\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\trtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_NUM_OFFSETS].address,\n\t\t\t\t&param->num_offsets);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't not fetch number of offsets from Zephyr\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (param->num_offsets <= OFFSET_T_STACK_POINTER) {\n\t\t\tLOG_ERROR(\"Number of offsets too small\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tretval = target_read_u32(rtos->target,\n\t\t\t\trtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address,\n\t\t\t\t&param->offsets[OFFSET_VERSION]);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't not fetch offsets from Zephyr\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (param->offsets[OFFSET_VERSION] > 1) {\n\t\t\tLOG_ERROR(\"Unexpected OpenOCD support version %\" PRIu32,\n\t\t\t\t\tparam->offsets[OFFSET_VERSION]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tswitch (param->offsets[OFFSET_VERSION]) {\n\t\tcase 0:\n\t\t\tparam->num_offsets = OFFSET_T_STACK_POINTER + 1;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tparam->num_offsets = OFFSET_T_COOP_FLOAT + 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\t/* We can fetch the whole array for version 0, as they're supposed\n\t * to grow only */\n\tuint32_t address;\n\taddress  = rtos->symbols[ZEPHYR_VAL__KERNEL_OPENOCD_OFFSETS].address;\n\tfor (size_t i = 0; i < OFFSET_MAX; i++, address += param->size_width) {\n\t\tif (i >= param->num_offsets) {\n\t\t\tparam->offsets[i] = UNIMPLEMENTED;\n\t\t\tcontinue;\n\t\t}\n\n\t\tretval = target_read_u32(rtos->target, address, &param->offsets[i]);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not fetch offsets from Zephyr\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"Zephyr OpenOCD support version %\" PRId32,\n\t\t\t  param->offsets[OFFSET_VERSION]);\n\n\tuint32_t current_thread;\n\tretval = target_read_u32(rtos->target,\n\t\tzephyr_kptr(rtos, OFFSET_K_CURR_THREAD), &current_thread);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not obtain current thread ID\");\n\t\treturn retval;\n\t}\n\n\tretval = zephyr_fetch_thread_list(rtos, current_thread);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not obtain thread list\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int zephyr_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,\n\t\tstruct rtos_reg **reg_list, int *num_regs)\n{\n\tstruct zephyr_params *params;\n\tstruct rtos_reg *callee_saved_reg_list = NULL;\n\ttarget_addr_t addr;\n\tint retval;\n\n\tLOG_INFO(\"Getting thread %\" PRId64 \" reg list\", thread_id);\n\n\tif (!rtos)\n\t\treturn ERROR_FAIL;\n\n\tif (thread_id == 0)\n\t\treturn ERROR_FAIL;\n\n\tparams = rtos->rtos_specific_params;\n\tif (!params)\n\t\treturn ERROR_FAIL;\n\n\taddr = thread_id + params->offsets[OFFSET_T_STACK_POINTER]\n\t\t - params->callee_saved_stacking->register_offsets[0].offset;\n\n\tretval = params->get_cpu_state(rtos, &addr, params, callee_saved_reg_list, reg_list, num_regs);\n\n\tfree(callee_saved_reg_list);\n\n\treturn retval;\n}\n\nstatic int zephyr_get_symbol_list_to_lookup(struct symbol_table_elem **symbol_list)\n{\n\t*symbol_list = malloc(sizeof(zephyr_symbol_list));\n\tif (!*symbol_list) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmemcpy(*symbol_list, zephyr_symbol_list, sizeof(zephyr_symbol_list));\n\treturn ERROR_OK;\n}\n\nconst struct rtos_type zephyr_rtos = {\n\t.name = \"Zephyr\",\n\n\t.detect_rtos = zephyr_detect_rtos,\n\t.create = zephyr_create,\n\t.update_threads = zephyr_update_threads,\n\t.get_thread_reg_list = zephyr_get_thread_reg_list,\n\t.get_symbol_list_to_lookup = zephyr_get_symbol_list_to_lookup,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtt/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/librtt.la\n%C%_librtt_la_SOURCES = %D%/rtt.c %D%/rtt.h %D%/tcl.c\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtt/rtt.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <string.h>\n\n#include <helper/log.h>\n#include <helper/list.h>\n#include <target/target.h>\n#include <target/rtt.h>\n\n#include \"rtt.h\"\n\nstatic struct {\n\tstruct rtt_source source;\n\t/** Control block. */\n\tstruct rtt_control ctrl;\n\tstruct target *target;\n\t/** Start address to search for the control block. */\n\ttarget_addr_t addr;\n\t/** Size of the control block search area. */\n\tsize_t size;\n\t/** Control block identifier. */\n\tchar id[RTT_CB_MAX_ID_LENGTH];\n\t/** Whether RTT is configured. */\n\tbool configured;\n\t/** Whether RTT is started. */\n\tbool started;\n\t/** Whether configuration changed. */\n\tbool changed;\n\t/** Whether the control block was found. */\n\tbool found_cb;\n\n\tstruct rtt_sink_list **sink_list;\n\tsize_t sink_list_length;\n\n\tunsigned int polling_interval;\n} rtt;\n\nint rtt_init(void)\n{\n\trtt.sink_list_length = 1;\n\trtt.sink_list = calloc(rtt.sink_list_length,\n\t\tsizeof(struct rtt_sink_list *));\n\n\tif (!rtt.sink_list)\n\t\treturn ERROR_FAIL;\n\n\trtt.sink_list[0] = NULL;\n\trtt.started = false;\n\n\trtt.polling_interval = 100;\n\n\treturn ERROR_OK;\n}\n\nint rtt_exit(void)\n{\n\tfree(rtt.sink_list);\n\n\treturn ERROR_OK;\n}\n\nstatic int read_channel_callback(void *user_data)\n{\n\tint ret;\n\n\tret = rtt.source.read(rtt.target, &rtt.ctrl, rtt.sink_list,\n\t\trtt.sink_list_length, NULL);\n\n\tif (ret != ERROR_OK) {\n\t\ttarget_unregister_timer_callback(&read_channel_callback, NULL);\n\t\trtt.source.stop(rtt.target, NULL);\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint rtt_setup(target_addr_t address, size_t size, const char *id)\n{\n\tsize_t id_length = strlen(id);\n\n\tif (!id_length || id_length >= RTT_CB_MAX_ID_LENGTH) {\n\t\tLOG_ERROR(\"rtt: Invalid control block ID\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\trtt.addr = address;\n\trtt.size = size;\n\tstrncpy(rtt.id, id, id_length + 1);\n\trtt.changed = true;\n\trtt.configured = true;\n\n\treturn ERROR_OK;\n}\n\nint rtt_register_source(const struct rtt_source source,\n\t\tstruct target *target)\n{\n\tif (!source.find_cb || !source.read_cb || !source.read_channel_info)\n\t\treturn ERROR_FAIL;\n\n\tif (!source.start || !source.stop)\n\t\treturn ERROR_FAIL;\n\n\tif (!source.read || !source.write)\n\t\treturn ERROR_FAIL;\n\n\trtt.source = source;\n\trtt.target = target;\n\n\treturn ERROR_OK;\n}\n\nint rtt_start(void)\n{\n\tint ret;\n\ttarget_addr_t addr = rtt.addr;\n\n\tif (rtt.started)\n\t\treturn ERROR_OK;\n\n\tif (!rtt.found_cb || rtt.changed) {\n\t\trtt.source.find_cb(rtt.target, &addr, rtt.size, rtt.id,\n\t\t\t&rtt.found_cb, NULL);\n\n\t\trtt.changed = false;\n\n\t\tif (rtt.found_cb) {\n\t\t\tLOG_INFO(\"rtt: Control block found at 0x%\" TARGET_PRIxADDR,\n\t\t\t\taddr);\n\t\t\trtt.ctrl.address = addr;\n\t\t} else {\n\t\t\tLOG_INFO(\"rtt: No control block found\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tret = rtt.source.read_cb(rtt.target, rtt.ctrl.address, &rtt.ctrl, NULL);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = rtt.source.start(rtt.target, &rtt.ctrl, NULL);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\ttarget_register_timer_callback(&read_channel_callback,\n\t\trtt.polling_interval, 1, NULL);\n\trtt.started = true;\n\n\treturn ERROR_OK;\n}\n\nint rtt_stop(void)\n{\n\tint ret;\n\n\tif (!rtt.configured) {\n\t\tLOG_ERROR(\"rtt: Not configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_unregister_timer_callback(&read_channel_callback, NULL);\n\trtt.started = false;\n\n\tret = rtt.source.stop(rtt.target, NULL);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn ERROR_OK;\n}\n\nstatic int adjust_sink_list(size_t length)\n{\n\tstruct rtt_sink_list **tmp;\n\n\tif (length <= rtt.sink_list_length)\n\t\treturn ERROR_OK;\n\n\ttmp = realloc(rtt.sink_list, sizeof(struct rtt_sink_list *) * length);\n\n\tif (!tmp)\n\t\treturn ERROR_FAIL;\n\n\tfor (size_t i = rtt.sink_list_length; i < length; i++)\n\t\ttmp[i] = NULL;\n\n\trtt.sink_list = tmp;\n\trtt.sink_list_length = length;\n\n\treturn ERROR_OK;\n}\n\nint rtt_register_sink(unsigned int channel_index, rtt_sink_read read,\n\t\tvoid *user_data)\n{\n\tstruct rtt_sink_list *tmp;\n\n\tif (channel_index >= rtt.sink_list_length) {\n\t\tif (adjust_sink_list(channel_index + 1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"rtt: Registering sink for channel %u\", channel_index);\n\n\ttmp = malloc(sizeof(struct rtt_sink_list));\n\n\tif (!tmp)\n\t\treturn ERROR_FAIL;\n\n\ttmp->read = read;\n\ttmp->user_data = user_data;\n\ttmp->next = rtt.sink_list[channel_index];\n\n\trtt.sink_list[channel_index] = tmp;\n\n\treturn ERROR_OK;\n}\n\nint rtt_unregister_sink(unsigned int channel_index, rtt_sink_read read,\n\t\tvoid *user_data)\n{\n\tstruct rtt_sink_list *prev_sink;\n\n\tLOG_DEBUG(\"rtt: Unregistering sink for channel %u\", channel_index);\n\n\tif (channel_index >= rtt.sink_list_length)\n\t\treturn ERROR_FAIL;\n\n\tprev_sink = rtt.sink_list[channel_index];\n\n\tfor (struct rtt_sink_list *sink = rtt.sink_list[channel_index]; sink;\n\t\t\tprev_sink = sink, sink = sink->next) {\n\t\tif (sink->read == read && sink->user_data == user_data) {\n\n\t\t\tif (sink == rtt.sink_list[channel_index])\n\t\t\t\trtt.sink_list[channel_index] = sink->next;\n\t\t\telse\n\t\t\t\tprev_sink->next = sink->next;\n\n\t\t\tfree(sink);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint rtt_get_polling_interval(unsigned int *interval)\n{\n\tif (!interval)\n\t\treturn ERROR_FAIL;\n\n\t*interval = rtt.polling_interval;\n\n\treturn ERROR_OK;\n}\n\nint rtt_set_polling_interval(unsigned int interval)\n{\n\tif (!interval)\n\t\treturn ERROR_FAIL;\n\n\tif (rtt.polling_interval != interval) {\n\t\ttarget_unregister_timer_callback(&read_channel_callback, NULL);\n\t\ttarget_register_timer_callback(&read_channel_callback, interval, 1,\n\t\t\tNULL);\n\t}\n\n\trtt.polling_interval = interval;\n\n\treturn ERROR_OK;\n}\n\nint rtt_write_channel(unsigned int channel_index, const uint8_t *buffer,\n\t\tsize_t *length)\n{\n\tif (channel_index >= rtt.ctrl.num_up_channels) {\n\t\tLOG_WARNING(\"rtt: Down-channel %u is not available\", channel_index);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn rtt.source.write(rtt.target, &rtt.ctrl, channel_index, buffer,\n\t\tlength, NULL);\n}\n\nbool rtt_started(void)\n{\n\treturn rtt.started;\n}\n\nbool rtt_configured(void)\n{\n\treturn rtt.configured;\n}\n\nbool rtt_found_cb(void)\n{\n\treturn rtt.found_cb;\n}\n\nconst struct rtt_control *rtt_get_control(void)\n{\n\treturn &rtt.ctrl;\n}\n\nint rtt_read_channel_info(unsigned int channel_index,\n\tenum rtt_channel_type type, struct rtt_channel_info *info)\n{\n\treturn rtt.source.read_channel_info(rtt.target, &rtt.ctrl,\n\t\tchannel_index, type, info, NULL);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtt/rtt.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>\n */\n\n#ifndef OPENOCD_RTT_RTT_H\n#define OPENOCD_RTT_RTT_H\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#include <helper/command.h>\n#include <target/target.h>\n\n/**\n * Control block ID length in bytes, including the trailing null-terminator.\n */\n#define RTT_CB_MAX_ID_LENGTH\t16\n\n/* Control block size in bytes. */\n#define RTT_CB_SIZE\t\t(RTT_CB_MAX_ID_LENGTH + 2 * sizeof(uint32_t))\n\n/* Channel structure size in bytes. */\n#define RTT_CHANNEL_SIZE\t24\n\n/* Minimal channel buffer size in bytes. */\n#define RTT_CHANNEL_BUFFER_MIN_SIZE\t2\n\n/** RTT control block. */\nstruct rtt_control {\n\t/** Control block address on the target. */\n\ttarget_addr_t address;\n\t/** Control block identifier, including trailing null-terminator. */\n\tchar id[RTT_CB_MAX_ID_LENGTH];\n\t/** Maximum number of up-channels. */\n\tuint32_t num_up_channels;\n\t/** Maximum number of down-channels. */\n\tuint32_t num_down_channels;\n};\n\n/** RTT channel. */\nstruct rtt_channel {\n\t/** Channel structure address on the target. */\n\ttarget_addr_t address;\n\t/** Channel name address on the target. */\n\tuint32_t name_addr;\n\t/** Buffer address on the target. */\n\tuint32_t buffer_addr;\n\t/** Channel buffer size in bytes. */\n\tuint32_t size;\n\t/**  Write position within the buffer in bytes. */\n\tuint32_t write_pos;\n\t/** Read position within the buffer in bytes. */\n\tuint32_t read_pos;\n\t/**\n\t * Buffer flags.\n\t *\n\t * @note: Not used at the moment.\n\t */\n\tuint32_t flags;\n};\n\n/** RTT channel information. */\nstruct rtt_channel_info {\n\t/** Channel name. */\n\tchar *name;\n\t/** Length of the name in bytes, including the trailing null-terminator. */\n\tsize_t name_length;\n\t/** Buffer size in bytes. */\n\tuint32_t size;\n\t/**\n\t * Buffer flags.\n\t *\n\t * @note: Not used at the moment.\n\t */\n\tuint32_t flags;\n};\n\ntypedef int (*rtt_sink_read)(unsigned int channel, const uint8_t *buffer,\n\t\tsize_t length, void *user_data);\n\nstruct rtt_sink_list {\n\trtt_sink_read read;\n\tvoid *user_data;\n\n\tstruct rtt_sink_list *next;\n};\n\n/** Channel type. */\nenum rtt_channel_type {\n\t/** Up channel (target to host). */\n\tRTT_CHANNEL_TYPE_UP,\n\t/** Down channel (host to target). */\n\tRTT_CHANNEL_TYPE_DOWN\n};\n\ntypedef int (*rtt_source_find_ctrl_block)(struct target *target,\n\t\ttarget_addr_t *address, size_t size, const char *id, bool *found,\n\t\tvoid *user_data);\ntypedef int (*rtt_source_read_ctrl_block)(struct target *target,\n\t\ttarget_addr_t address, struct rtt_control *ctrl_block,\n\t\tvoid *user_data);\ntypedef int (*rtt_source_read_channel_info)(struct target *target,\n\t\tconst struct rtt_control *ctrl, unsigned int channel,\n\t\tenum rtt_channel_type type, struct rtt_channel_info *info,\n\t\tvoid *user_data);\ntypedef int (*rtt_source_start)(struct target *target,\n\t\tconst struct rtt_control *ctrl, void *user_data);\ntypedef int (*rtt_source_stop)(struct target *target, void *user_data);\ntypedef int (*rtt_source_read)(struct target *target,\n\t\tconst struct rtt_control *ctrl, struct rtt_sink_list **sinks,\n\t\tsize_t num_channels, void *user_data);\ntypedef int (*rtt_source_write)(struct target *target,\n\t\tstruct rtt_control *ctrl, unsigned int channel,\n\t\tconst uint8_t *buffer, size_t *length, void *user_data);\n\n/** RTT source. */\nstruct rtt_source {\n\trtt_source_find_ctrl_block find_cb;\n\trtt_source_read_ctrl_block read_cb;\n\trtt_source_read_channel_info read_channel_info;\n\trtt_source_start start;\n\trtt_source_stop stop;\n\trtt_source_read read;\n\trtt_source_write write;\n};\n\n/**\n * Initialize Real-Time Transfer (RTT).\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_init(void);\n\n/**\n * Shutdown Real-Time Transfer (RTT).\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_exit(void);\n\n/**\n * Register an RTT source for a target.\n *\n * @param[in] source RTT source.\n * @param[in,out] target Target.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_register_source(const struct rtt_source source,\n\t\tstruct target *target);\n\n/**\n * Setup RTT.\n *\n * @param[in] address Start address to search for the control block.\n * @param[in] size Size of the control block search area.\n * @param[in] id Identifier of the control block. Must be null-terminated.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_setup(target_addr_t address, size_t size, const char *id);\n\n/**\n * Start Real-Time Transfer (RTT).\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_start(void);\n\n/**\n * Stop Real-Time Transfer (RTT).\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_stop(void);\n\n/**\n * Get the polling interval.\n *\n * @param[out] interval Polling interval in milliseconds.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_get_polling_interval(unsigned int *interval);\n\n/**\n * Set the polling interval.\n *\n * @param[in] interval Polling interval in milliseconds.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_set_polling_interval(unsigned int interval);\n\n/**\n * Get whether RTT is started.\n *\n * @returns Whether RTT is started.\n */\nbool rtt_started(void);\n\n/**\n * Get whether RTT is configured.\n *\n * @returns Whether RTT is configured.\n */\nbool rtt_configured(void);\n\n/**\n * Get whether RTT control block was found.\n *\n * @returns Whether RTT was found.\n */\nbool rtt_found_cb(void);\n\n/**\n * Get the RTT control block.\n *\n * @returns The RTT control block.\n */\nconst struct rtt_control *rtt_get_control(void);\n\n/**\n * Read channel information.\n *\n * @param[in] channel_index Channel index.\n * @param[in] type Channel type.\n * @param[out] info Channel information.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_read_channel_info(unsigned int channel_index,\n\tenum rtt_channel_type type, struct rtt_channel_info *info);\n\n/**\n * Register an RTT sink.\n *\n * @param[in] channel_index Channel index.\n * @param[in] read Read callback function.\n * @param[in,out] user_data User data to be passed to the callback function.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_register_sink(unsigned int channel_index, rtt_sink_read read,\n\t\tvoid *user_data);\n\n/**\n * Unregister an RTT sink.\n *\n * @param[in] channel_index Channel index.\n * @param[in] read Read callback function.\n * @param[in,out] user_data User data to be passed to the callback function.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_unregister_sink(unsigned int channel_index, rtt_sink_read read,\n\t\tvoid *user_data);\n\n/**\n * Write to an RTT channel.\n *\n * @param[in] channel_index Channel index.\n * @param[in] buffer Buffer with data that should be written to the channel.\n * @param[in,out] length Number of bytes to write. On success, the argument gets\n *                       updated with the actual number of written bytes.\n *\n * @returns ERROR_OK on success, an error code on failure.\n */\nint rtt_write_channel(unsigned int channel_index, const uint8_t *buffer,\n\t\tsize_t *length);\n\nextern const struct command_registration rtt_target_command_handlers[];\n\n#endif /* OPENOCD_RTT_RTT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/rtt/tcl.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2019-2020 by Marc Schink <dev@zapb.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <target/rtt.h>\n\n#include \"rtt.h\"\n\n#define CHANNEL_NAME_SIZE\t128\n\nCOMMAND_HANDLER(handle_rtt_setup_command)\n{\nstruct rtt_source source;\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tsource.find_cb = &target_rtt_find_control_block;\n\tsource.read_cb = &target_rtt_read_control_block;\n\tsource.start = &target_rtt_start;\n\tsource.stop = &target_rtt_stop;\n\tsource.read = &target_rtt_read_callback;\n\tsource.write = &target_rtt_write_callback;\n\tsource.read_channel_info = &target_rtt_read_channel_info;\n\n\ttarget_addr_t address;\n\tuint32_t size;\n\n\tCOMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\n\trtt_register_source(source, get_current_target(CMD_CTX));\n\n\tif (rtt_setup(address, size, CMD_ARGV[2]) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_rtt_start_command)\n{\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!rtt_configured()) {\n\t\tcommand_print(CMD, \"RTT is not configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn rtt_start();\n}\n\nCOMMAND_HANDLER(handle_rtt_stop_command)\n{\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn rtt_stop();\n}\n\nCOMMAND_HANDLER(handle_rtt_polling_interval_command)\n{\n\tif (CMD_ARGC == 0) {\n\t\tint ret;\n\t\tunsigned int interval;\n\n\t\tret = rtt_get_polling_interval(&interval);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"Failed to get polling interval\");\n\t\t\treturn ret;\n\t\t}\n\n\t\tcommand_print(CMD, \"%u ms\", interval);\n\t} else if (CMD_ARGC == 1) {\n\t\tint ret;\n\t\tunsigned int interval;\n\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], interval);\n\t\tret = rtt_set_polling_interval(interval);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"Failed to set polling interval\");\n\t\t\treturn ret;\n\t\t}\n\t} else {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_rtt_channels_command)\n{\n\tint ret;\n\tchar channel_name[CHANNEL_NAME_SIZE];\n\tconst struct rtt_control *ctrl;\n\tstruct rtt_channel_info info;\n\n\tif (!rtt_found_cb()) {\n\t\tcommand_print(CMD, \"rtt: Control block not available\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tctrl = rtt_get_control();\n\n\tcommand_print(CMD, \"Channels: up=%u, down=%u\", ctrl->num_up_channels,\n\t\tctrl->num_down_channels);\n\n\tcommand_print(CMD, \"Up-channels:\");\n\n\tinfo.name = channel_name;\n\tinfo.name_length = sizeof(channel_name);\n\n\tfor (unsigned int i = 0; i < ctrl->num_up_channels; i++) {\n\t\tret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (!info.size)\n\t\t\tcontinue;\n\n\t\tcommand_print(CMD, \"%u: %s %u %u\", i, info.name, info.size,\n\t\t\tinfo.flags);\n\t}\n\n\tcommand_print(CMD, \"Down-channels:\");\n\n\tfor (unsigned int i = 0; i < ctrl->num_down_channels; i++) {\n\t\tret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (!info.size)\n\t\t\tcontinue;\n\n\t\tcommand_print(CMD, \"%u: %s %u %u\", i, info.name, info.size,\n\t\t\tinfo.flags);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_channel_list)\n{\n\tchar channel_name[CHANNEL_NAME_SIZE];\n\tconst struct rtt_control *ctrl;\n\tstruct rtt_channel_info info;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!rtt_found_cb()) {\n\t\tcommand_print(CMD, \"rtt: Control block not available\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tctrl = rtt_get_control();\n\n\tinfo.name = channel_name;\n\tinfo.name_length = sizeof(channel_name);\n\n\tcommand_print(CMD, \"{\");\n\n\tfor (unsigned int i = 0; i < ctrl->num_up_channels; i++) {\n\t\tint ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (!info.size)\n\t\t\tcontinue;\n\n\t\tcommand_print(CMD,\n\t\t\t\"    {\\n\"\n\t\t\t\"        name  %s\\n\"\n\t\t\t\"        size  0x%\" PRIx32 \"\\n\"\n\t\t\t\"        flags 0x%\" PRIx32 \"\\n\"\n\t\t\t\"    }\",\n\t\t\tinfo.name, info.size, info.flags);\n\t}\n\n\tcommand_print(CMD, \"}\\n{\");\n\n\tfor (unsigned int i = 0; i < ctrl->num_down_channels; i++) {\n\t\tint ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (!info.size)\n\t\t\tcontinue;\n\n\t\tcommand_print(CMD,\n\t\t\t\"    {\\n\"\n\t\t\t\"        name  %s\\n\"\n\t\t\t\"        size  0x%\" PRIx32 \"\\n\"\n\t\t\t\"        flags 0x%\" PRIx32 \"\\n\"\n\t\t\t\"    }\",\n\t\t\tinfo.name, info.size, info.flags);\n\t}\n\n\tcommand_print(CMD, \"}\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration rtt_subcommand_handlers[] = {\n\t{\n\t\t.name = \"setup\",\n\t\t.handler = handle_rtt_setup_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"setup RTT\",\n\t\t.usage = \"<address> <size> <ID>\"\n\t},\n\t{\n\t\t.name = \"start\",\n\t\t.handler = handle_rtt_start_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"start RTT\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"stop\",\n\t\t.handler = handle_rtt_stop_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"stop RTT\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"polling_interval\",\n\t\t.handler = handle_rtt_polling_interval_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"show or set polling interval in ms\",\n\t\t.usage = \"[interval]\"\n\t},\n\t{\n\t\t.name = \"channels\",\n\t\t.handler = handle_rtt_channels_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list available channels\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"channellist\",\n\t\t.handler = handle_channel_list,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list available channels\",\n\t\t.usage = \"\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration rtt_target_command_handlers[] = {\n\t{\n\t\t.name = \"rtt\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"RTT target commands\",\n\t\t.usage = \"\",\n\t\t.chain = rtt_subcommand_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libserver.la\n%C%_libserver_la_SOURCES = \\\n\t%D%/server.c \\\n\t%D%/telnet_server.c \\\n\t%D%/gdb_server.c \\\n\t%D%/server.h \\\n\t%D%/telnet_server.h \\\n\t%D%/gdb_server.h \\\n\t%D%/tcl_server.c \\\n\t%D%/tcl_server.h \\\n\t%D%/rtt_server.c \\\n\t%D%/rtt_server.h \\\n\t%D%/ipdbg.c \\\n\t%D%/ipdbg.h\n\nSTARTUP_TCL_SRCS += %D%/startup.tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/gdb_server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011                                     *\n *   michel.jaouen@stericsson.com : smp minimum support                    *\n *                                                                         *\n *   Copyright (C) 2013 Andes Technology                                   *\n *   Hsiangkai Wang <hkwang@andestech.com>                                 *\n *                                                                         *\n *   Copyright (C) 2013 Franck Jullien                                     *\n *   elec4fun@gmail.com                                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <target/breakpoints.h>\n#include <target/target_request.h>\n#include <target/register.h>\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/semihosting_common.h>\n#include \"server.h\"\n#include <flash/nor/core.h>\n#include \"gdb_server.h\"\n#include <target/image.h>\n#include <jtag/jtag.h>\n#include \"rtos/rtos.h\"\n#include \"target/smp.h\"\n\n/**\n * @file\n * GDB server implementation.\n *\n * This implements the GDB Remote Serial Protocol, over TCP connections,\n * giving GDB access to the JTAG or other hardware debugging facilities\n * found in most modern embedded processors.\n */\n\nenum gdb_output_flag {\n\t/* GDB doesn't accept 'O' packets */\n\tGDB_OUTPUT_NO,\n\t/* GDB accepts 'O' packets */\n\tGDB_OUTPUT_ALL,\n};\n\nstruct target_desc_format {\n\tchar *tdesc;\n\tuint32_t tdesc_length;\n};\n\n/* private connection data for GDB */\nstruct gdb_connection {\n\tchar buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for null-termination */\n\tchar *buf_p;\n\tint buf_cnt;\n\tbool ctrl_c;\n\tenum target_state frontend_state;\n\tstruct image *vflash_image;\n\tbool closed;\n\tbool busy;\n\tint noack_mode;\n\t/* set flag to true if you want the next stepi to return immediately.\n\t * allowing GDB to pick up a fresh set of register values from the target\n\t * without modifying the target state. */\n\tbool sync;\n\t/* We delay reporting memory write errors until next step/continue or memory\n\t * write. This improves performance of gdb load significantly as the GDB packet\n\t * can be replied immediately and a new GDB packet will be ready without delay\n\t * (ca. 10% or so...). */\n\tbool mem_write_error;\n\t/* with extended-remote it seems we need to better emulate attach/detach.\n\t * what this means is we reply with a W stop reply after a kill packet,\n\t * normally we reply with a S reply via gdb_last_signal_packet.\n\t * as a side note this behaviour only effects gdb > 6.8 */\n\tbool attached;\n\t/* set when extended protocol is used */\n\tbool extended_protocol;\n\t/* temporarily used for target description support */\n\tstruct target_desc_format target_desc;\n\t/* temporarily used for thread list support */\n\tchar *thread_list;\n\t/* flag to mask the output from gdb_log_callback() */\n\tenum gdb_output_flag output_flag;\n};\n\n#if 0\n#define _DEBUG_GDB_IO_\n#endif\n\nstatic struct gdb_connection *current_gdb_connection;\n\nstatic int gdb_breakpoint_override;\nstatic enum breakpoint_type gdb_breakpoint_override_type;\n\nstatic int gdb_error(struct connection *connection, int retval);\nstatic char *gdb_port;\nstatic char *gdb_port_next;\n\nstatic void gdb_log_callback(void *priv, const char *file, unsigned line,\n\t\tconst char *function, const char *string);\n\nstatic void gdb_sig_halted(struct connection *connection);\n\n/* number of gdb connections, mainly to suppress gdb related debugging spam\n * in helper/log.c when no gdb connections are actually active */\nstatic int gdb_actual_connections;\n\n/* set if we are sending a memory map to gdb\n * via qXfer:memory-map:read packet */\n/* enabled by default*/\nstatic int gdb_use_memory_map = 1;\n/* enabled by default*/\nstatic int gdb_flash_program = 1;\n\n/* if set, data aborts cause an error to be reported in memory read packets\n * see the code in gdb_read_memory_packet() for further explanations.\n * Disabled by default.\n */\nstatic int gdb_report_data_abort;\n/* If set, errors when accessing registers are reported to gdb. Disabled by\n * default. */\nstatic int gdb_report_register_access_error;\n\n/* set if we are sending target descriptions to gdb\n * via qXfer:features:read packet */\n/* enabled by default */\nstatic int gdb_use_target_description = 1;\n\n/* current processing free-run type, used by file-I/O */\nstatic char gdb_running_type;\n\nstatic int gdb_last_signal(struct target *target)\n{\n\tLOG_TARGET_DEBUG(target, \"Debug reason is: %s\",\n\t\t\ttarget_debug_reason_str(target->debug_reason));\n\n\tswitch (target->debug_reason) {\n\t\tcase DBG_REASON_DBGRQ:\n\t\t\treturn 0x2;\t\t/* SIGINT */\n\t\tcase DBG_REASON_BREAKPOINT:\n\t\tcase DBG_REASON_WATCHPOINT:\n\t\tcase DBG_REASON_WPTANDBKPT:\n\t\t\treturn 0x05;\t/* SIGTRAP */\n\t\tcase DBG_REASON_SINGLESTEP:\n\t\t\treturn 0x05;\t/* SIGTRAP */\n\t\tcase DBG_REASON_EXC_CATCH:\n\t\t\treturn 0x05;\n\t\tcase DBG_REASON_NOTHALTED:\n\t\t\treturn 0x0;\t\t/* no signal... shouldn't happen */\n\t\tdefault:\n\t\t\tLOG_USER(\"undefined debug reason %d (%s) - target needs reset\",\n\t\t\t\t\ttarget->debug_reason,\n\t\t\t\t\ttarget_debug_reason_str(target->debug_reason));\n\t\t\treturn 0x0;\n\t}\n}\n\nstatic int check_pending(struct connection *connection,\n\t\tint timeout_s, int *got_data)\n{\n\t/* a non-blocking socket will block if there is 0 bytes available on the socket,\n\t * but return with as many bytes as are available immediately\n\t */\n\tstruct timeval tv;\n\tfd_set read_fds;\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tint t;\n\tif (!got_data)\n\t\tgot_data = &t;\n\t*got_data = 0;\n\n\tif (gdb_con->buf_cnt > 0) {\n\t\t*got_data = 1;\n\t\treturn ERROR_OK;\n\t}\n\n\tFD_ZERO(&read_fds);\n\tFD_SET(connection->fd, &read_fds);\n\n\ttv.tv_sec = timeout_s;\n\ttv.tv_usec = 0;\n\tif (socket_select(connection->fd + 1, &read_fds, NULL, NULL, &tv) == 0) {\n\t\t/* This can typically be because a \"monitor\" command took too long\n\t\t * before printing any progress messages\n\t\t */\n\t\tif (timeout_s > 0)\n\t\t\treturn ERROR_GDB_TIMEOUT;\n\t\telse\n\t\t\treturn ERROR_OK;\n\t}\n\t*got_data = FD_ISSET(connection->fd, &read_fds) != 0;\n\treturn ERROR_OK;\n}\n\nstatic int gdb_get_char_inner(struct connection *connection, int *next_char)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tint retval = ERROR_OK;\n\n#ifdef _DEBUG_GDB_IO_\n\tchar *debug_buffer;\n#endif\n\tfor (;; ) {\n\t\tif (connection->service->type != CONNECTION_TCP)\n\t\t\tgdb_con->buf_cnt = read(connection->fd, gdb_con->buffer, GDB_BUFFER_SIZE);\n\t\telse {\n\t\t\tretval = check_pending(connection, 1, NULL);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tgdb_con->buf_cnt = read_socket(connection->fd,\n\t\t\t\t\tgdb_con->buffer,\n\t\t\t\t\tGDB_BUFFER_SIZE);\n\t\t}\n\n\t\tif (gdb_con->buf_cnt > 0)\n\t\t\tbreak;\n\t\tif (gdb_con->buf_cnt == 0) {\n\t\t\tLOG_DEBUG(\"GDB connection closed by the remote client\");\n\t\t\tgdb_con->closed = true;\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\n#ifdef _WIN32\n\t\tbool retry = (WSAGetLastError() == WSAEWOULDBLOCK);\n#else\n\t\tbool retry = (errno == EAGAIN);\n#endif\n\n\t\tif (retry) {\n\t\t\t// Try again after a delay\n\t\t\tusleep(1000);\n\t\t} else {\n\t\t\t// Print error and close the socket\n\t\t\tlog_socket_error(\"GDB\");\n\t\t\tgdb_con->closed = true;\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\t}\n\n#ifdef _DEBUG_GDB_IO_\n\tdebug_buffer = strndup(gdb_con->buffer, gdb_con->buf_cnt);\n\tLOG_DEBUG(\"received '%s'\", debug_buffer);\n\tfree(debug_buffer);\n#endif\n\n\tgdb_con->buf_p = gdb_con->buffer;\n\tgdb_con->buf_cnt--;\n\t*next_char = *(gdb_con->buf_p++);\n\tif (gdb_con->buf_cnt > 0)\n\t\tconnection->input_pending = true;\n\telse\n\t\tconnection->input_pending = false;\n#ifdef _DEBUG_GDB_IO_\n\tLOG_DEBUG(\"returned char '%c' (0x%2.2x)\", *next_char, *next_char);\n#endif\n\n\treturn retval;\n}\n\n/**\n * The cool thing about this fn is that it allows buf_p and buf_cnt to be\n * held in registers in the inner loop.\n *\n * For small caches and embedded systems this is important!\n */\nstatic inline int gdb_get_char_fast(struct connection *connection,\n\t\tint *next_char, char **buf_p, int *buf_cnt)\n{\n\tint retval = ERROR_OK;\n\n\tif ((*buf_cnt)-- > 0) {\n\t\t*next_char = **buf_p;\n\t\t(*buf_p)++;\n\t\tif (*buf_cnt > 0)\n\t\t\tconnection->input_pending = true;\n\t\telse\n\t\t\tconnection->input_pending = false;\n\n#ifdef _DEBUG_GDB_IO_\n\t\tLOG_DEBUG(\"returned char '%c' (0x%2.2x)\", *next_char, *next_char);\n#endif\n\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tgdb_con->buf_p = *buf_p;\n\tgdb_con->buf_cnt = *buf_cnt;\n\tretval = gdb_get_char_inner(connection, next_char);\n\t*buf_p = gdb_con->buf_p;\n\t*buf_cnt = gdb_con->buf_cnt;\n\n\treturn retval;\n}\n\nstatic int gdb_get_char(struct connection *connection, int *next_char)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\treturn gdb_get_char_fast(connection, next_char, &gdb_con->buf_p, &gdb_con->buf_cnt);\n}\n\nstatic int gdb_putback_char(struct connection *connection, int last_char)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\n\tif (gdb_con->buf_p > gdb_con->buffer) {\n\t\t*(--gdb_con->buf_p) = last_char;\n\t\tgdb_con->buf_cnt++;\n\t} else\n\t\tLOG_ERROR(\"BUG: couldn't put character back\");\n\n\treturn ERROR_OK;\n}\n\n/* The only way we can detect that the socket is closed is the first time\n * we write to it, we will fail. Subsequent write operations will\n * succeed. Shudder! */\nstatic int gdb_write(struct connection *connection, void *data, int len)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tif (gdb_con->closed) {\n\t\tLOG_DEBUG(\"GDB socket marked as closed, cannot write to it.\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tif (connection_write(connection, data, len) == len)\n\t\treturn ERROR_OK;\n\n\tLOG_WARNING(\"Error writing to GDB socket. Dropping the connection.\");\n\tgdb_con->closed = true;\n\treturn ERROR_SERVER_REMOTE_CLOSED;\n}\n\nstatic void gdb_log_incoming_packet(struct connection *connection, char *packet)\n{\n\tif (!LOG_LEVEL_IS(LOG_LVL_DEBUG))\n\t\treturn;\n\n\tstruct target *target = get_target_from_connection(connection);\n\n\t/* Avoid dumping non-printable characters to the terminal */\n\tconst unsigned packet_len = strlen(packet);\n\tconst char *nonprint = find_nonprint_char(packet, packet_len);\n\tif (nonprint) {\n\t\t/* Does packet at least have a prefix that is printable?\n\t\t * Look within the first 50 chars of the packet. */\n\t\tconst char *colon = memchr(packet, ':', MIN(50, packet_len));\n\t\tconst bool packet_has_prefix = (colon);\n\t\tconst bool packet_prefix_printable = (packet_has_prefix && nonprint > colon);\n\n\t\tif (packet_prefix_printable) {\n\t\t\tconst unsigned int prefix_len = colon - packet + 1;  /* + 1 to include the ':' */\n\t\t\tconst unsigned int payload_len = packet_len - prefix_len;\n\t\t\tLOG_TARGET_DEBUG(target, \"received packet: %.*s<binary-data-%u-bytes>\", prefix_len,\n\t\t\t\tpacket, payload_len);\n\t\t} else {\n\t\t\tLOG_TARGET_DEBUG(target, \"received packet: <binary-data-%u-bytes>\", packet_len);\n\t\t}\n\t} else {\n\t\t/* All chars printable, dump the packet as is */\n\t\tLOG_TARGET_DEBUG(target, \"received packet: %s\", packet);\n\t}\n}\n\nstatic void gdb_log_outgoing_packet(struct connection *connection, char *packet_buf,\n\tunsigned int packet_len, unsigned char checksum)\n{\n\tif (!LOG_LEVEL_IS(LOG_LVL_DEBUG))\n\t\treturn;\n\n\tstruct target *target = get_target_from_connection(connection);\n\n\tif (find_nonprint_char(packet_buf, packet_len))\n\t\tLOG_TARGET_DEBUG(target, \"sending packet: $<binary-data-%u-bytes>#%2.2x\",\n\t\t\tpacket_len, checksum);\n\telse\n\t\tLOG_TARGET_DEBUG(target, \"sending packet: $%.*s#%2.2x\", packet_len, packet_buf,\n\t\t\tchecksum);\n}\n\nstatic int gdb_put_packet_inner(struct connection *connection,\n\t\tchar *buffer, int len)\n{\n\tint i;\n\tunsigned char my_checksum = 0;\n\tint reply;\n\tint retval;\n\tstruct gdb_connection *gdb_con = connection->priv;\n\n\tfor (i = 0; i < len; i++)\n\t\tmy_checksum += buffer[i];\n\n#ifdef _DEBUG_GDB_IO_\n\t/*\n\t * At this point we should have nothing in the input queue from GDB,\n\t * however sometimes '-' is sent even though we've already received\n\t * an ACK (+) for everything we've sent off.\n\t */\n\tint gotdata;\n\tfor (;; ) {\n\t\tretval = check_pending(connection, 0, &gotdata);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (!gotdata)\n\t\t\tbreak;\n\t\tretval = gdb_get_char(connection, &reply);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (reply == '$') {\n\t\t\t/* fix a problem with some IAR tools */\n\t\t\tgdb_putback_char(connection, reply);\n\t\t\tLOG_DEBUG(\"Unexpected start of new packet\");\n\t\t\tbreak;\n\t\t}\n\n\t\tLOG_WARNING(\"Discard unexpected char %c\", reply);\n\t}\n#endif\n\n\twhile (1) {\n\t\tgdb_log_outgoing_packet(connection, buffer, len, my_checksum);\n\n\t\tchar local_buffer[1024];\n\t\tlocal_buffer[0] = '$';\n\t\tif ((size_t)len + 4 <= sizeof(local_buffer)) {\n\t\t\t/* performance gain on smaller packets by only a single call to gdb_write() */\n\t\t\tmemcpy(local_buffer + 1, buffer, len++);\n\t\t\tlen += snprintf(local_buffer + len, sizeof(local_buffer) - len, \"#%02x\", my_checksum);\n\t\t\tretval = gdb_write(connection, local_buffer, len);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* larger packets are transmitted directly from caller supplied buffer\n\t\t\t * by several calls to gdb_write() to avoid dynamic allocation */\n\t\t\tsnprintf(local_buffer + 1, sizeof(local_buffer) - 1, \"#%02x\", my_checksum);\n\t\t\tretval = gdb_write(connection, local_buffer, 1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = gdb_write(connection, buffer, len);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = gdb_write(connection, local_buffer + 1, 3);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tif (gdb_con->noack_mode)\n\t\t\tbreak;\n\n\t\tretval = gdb_get_char(connection, &reply);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (reply == '+') {\n\t\t\tgdb_log_incoming_packet(connection, \"+\");\n\t\t\tbreak;\n\t\t} else if (reply == '-') {\n\t\t\t/* Stop sending output packets for now */\n\t\t\tgdb_con->output_flag = GDB_OUTPUT_NO;\n\t\t\tgdb_log_incoming_packet(connection, \"-\");\n\t\t\tLOG_WARNING(\"negative reply, retrying\");\n\t\t} else if (reply == 0x3) {\n\t\t\tgdb_con->ctrl_c = true;\n\t\t\tgdb_log_incoming_packet(connection, \"<Ctrl-C>\");\n\t\t\tretval = gdb_get_char(connection, &reply);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (reply == '+') {\n\t\t\t\tgdb_log_incoming_packet(connection, \"+\");\n\t\t\t\tbreak;\n\t\t\t} else if (reply == '-') {\n\t\t\t\t/* Stop sending output packets for now */\n\t\t\t\tgdb_con->output_flag = GDB_OUTPUT_NO;\n\t\t\t\tgdb_log_incoming_packet(connection, \"-\");\n\t\t\t\tLOG_WARNING(\"negative reply, retrying\");\n\t\t\t} else if (reply == '$') {\n\t\t\t\tLOG_ERROR(\"GDB missing ack(1) - assumed good\");\n\t\t\t\tgdb_putback_char(connection, reply);\n\t\t\t\treturn ERROR_OK;\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"unknown character(1) 0x%2.2x in reply, dropping connection\", reply);\n\t\t\t\tgdb_con->closed = true;\n\t\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t\t}\n\t\t} else if (reply == '$') {\n\t\t\tLOG_ERROR(\"GDB missing ack(2) - assumed good\");\n\t\t\tgdb_putback_char(connection, reply);\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tLOG_ERROR(\"unknown character(2) 0x%2.2x in reply, dropping connection\",\n\t\t\t\treply);\n\t\t\tgdb_con->closed = true;\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\t}\n\tif (gdb_con->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\treturn ERROR_OK;\n}\n\nint gdb_put_packet(struct connection *connection, char *buffer, int len)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tgdb_con->busy = true;\n\tint retval = gdb_put_packet_inner(connection, buffer, len);\n\tgdb_con->busy = false;\n\n\t/* we sent some data, reset timer for keep alive messages */\n\tkept_alive();\n\n\treturn retval;\n}\n\nstatic inline int fetch_packet(struct connection *connection,\n\t\tint *checksum_ok, int noack, int *len, char *buffer)\n{\n\tunsigned char my_checksum = 0;\n\tchar checksum[3];\n\tint character;\n\tint retval = ERROR_OK;\n\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tmy_checksum = 0;\n\tint count = 0;\n\tcount = 0;\n\n\t/* move this over into local variables to use registers and give the\n\t * more freedom to optimize */\n\tchar *buf_p = gdb_con->buf_p;\n\tint buf_cnt = gdb_con->buf_cnt;\n\n\tfor (;; ) {\n\t\t/* The common case is that we have an entire packet with no escape chars.\n\t\t * We need to leave at least 2 bytes in the buffer to have\n\t\t * gdb_get_char() update various bits and bobs correctly.\n\t\t */\n\t\tif ((buf_cnt > 2) && ((buf_cnt + count) < *len)) {\n\t\t\t/* The compiler will struggle a bit with constant propagation and\n\t\t\t * aliasing, so we help it by showing that these values do not\n\t\t\t * change inside the loop\n\t\t\t */\n\t\t\tint i;\n\t\t\tchar *buf = buf_p;\n\t\t\tint run = buf_cnt - 2;\n\t\t\ti = 0;\n\t\t\tint done = 0;\n\t\t\twhile (i < run) {\n\t\t\t\tcharacter = *buf++;\n\t\t\t\ti++;\n\t\t\t\tif (character == '#') {\n\t\t\t\t\t/* Danger! character can be '#' when esc is\n\t\t\t\t\t * used so we need an explicit boolean for done here. */\n\t\t\t\t\tdone = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (character == '}') {\n\t\t\t\t\t/* data transmitted in binary mode (X packet)\n\t\t\t\t\t * uses 0x7d as escape character */\n\t\t\t\t\tmy_checksum += character & 0xff;\n\t\t\t\t\tcharacter = *buf++;\n\t\t\t\t\ti++;\n\t\t\t\t\tmy_checksum += character & 0xff;\n\t\t\t\t\tbuffer[count++] = (character ^ 0x20) & 0xff;\n\t\t\t\t} else {\n\t\t\t\t\tmy_checksum += character & 0xff;\n\t\t\t\t\tbuffer[count++] = character & 0xff;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbuf_p += i;\n\t\t\tbuf_cnt -= i;\n\t\t\tif (done)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (count > *len) {\n\t\t\tLOG_ERROR(\"packet buffer too small\");\n\t\t\tretval = ERROR_GDB_BUFFER_TOO_SMALL;\n\t\t\tbreak;\n\t\t}\n\n\t\tretval = gdb_get_char_fast(connection, &character, &buf_p, &buf_cnt);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (character == '#')\n\t\t\tbreak;\n\n\t\tif (character == '}') {\n\t\t\t/* data transmitted in binary mode (X packet)\n\t\t\t * uses 0x7d as escape character */\n\t\t\tmy_checksum += character & 0xff;\n\n\t\t\tretval = gdb_get_char_fast(connection, &character, &buf_p, &buf_cnt);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\tmy_checksum += character & 0xff;\n\t\t\tbuffer[count++] = (character ^ 0x20) & 0xff;\n\t\t} else {\n\t\t\tmy_checksum += character & 0xff;\n\t\t\tbuffer[count++] = character & 0xff;\n\t\t}\n\t}\n\n\tgdb_con->buf_p = buf_p;\n\tgdb_con->buf_cnt = buf_cnt;\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*len = count;\n\n\tretval = gdb_get_char(connection, &character);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tchecksum[0] = character;\n\tretval = gdb_get_char(connection, &character);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tchecksum[1] = character;\n\tchecksum[2] = 0;\n\n\tif (!noack)\n\t\t*checksum_ok = (my_checksum == strtoul(checksum, NULL, 16));\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_get_packet_inner(struct connection *connection,\n\t\tchar *buffer, int *len)\n{\n\tint character;\n\tint retval;\n\tstruct gdb_connection *gdb_con = connection->priv;\n\n\twhile (1) {\n\t\tdo {\n\t\t\tretval = gdb_get_char(connection, &character);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n#ifdef _DEBUG_GDB_IO_\n\t\t\tLOG_DEBUG(\"character: '%c'\", character);\n#endif\n\n\t\t\tswitch (character) {\n\t\t\t\tcase '$':\n\t\t\t\t\tbreak;\n\t\t\t\tcase '+':\n\t\t\t\t\tgdb_log_incoming_packet(connection, \"+\");\n\t\t\t\t\t/* According to the GDB documentation\n\t\t\t\t\t * (https://sourceware.org/gdb/onlinedocs/gdb/Packet-Acknowledgment.html):\n\t\t\t\t\t * \"gdb sends a final `+` acknowledgment of the stub's `OK`\n\t\t\t\t\t * response, which can be safely ignored by the stub.\"\n\t\t\t\t\t * However OpenOCD server already is in noack mode at this\n\t\t\t\t\t * point and instead of ignoring this it was emitting a\n\t\t\t\t\t * warning. This code makes server ignore the first ACK\n\t\t\t\t\t * that will be received after going into noack mode,\n\t\t\t\t\t * warning only about subsequent ACK's. */\n\t\t\t\t\tif (gdb_con->noack_mode > 1) {\n\t\t\t\t\t\tLOG_WARNING(\"acknowledgment received, but no packet pending\");\n\t\t\t\t\t} else if (gdb_con->noack_mode) {\n\t\t\t\t\t\tLOG_DEBUG(\"Received first acknowledgment after entering noack mode. Ignoring it.\");\n\t\t\t\t\t\tgdb_con->noack_mode = 2;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase '-':\n\t\t\t\t\tgdb_log_incoming_packet(connection, \"-\");\n\t\t\t\t\tLOG_WARNING(\"negative acknowledgment, but no packet pending\");\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x3:\n\t\t\t\t\tgdb_log_incoming_packet(connection, \"<Ctrl-C>\");\n\t\t\t\t\tgdb_con->ctrl_c = true;\n\t\t\t\t\t*len = 0;\n\t\t\t\t\treturn ERROR_OK;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_WARNING(\"ignoring character 0x%x\", character);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (character != '$');\n\n\t\tint checksum_ok = 0;\n\t\t/* explicit code expansion here to get faster inlined code in -O3 by not\n\t\t * calculating checksum */\n\t\tif (gdb_con->noack_mode) {\n\t\t\tretval = fetch_packet(connection, &checksum_ok, 1, len, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tretval = fetch_packet(connection, &checksum_ok, 0, len, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tif (gdb_con->noack_mode) {\n\t\t\t/* checksum is not checked in noack mode */\n\t\t\tbreak;\n\t\t}\n\t\tif (checksum_ok) {\n\t\t\tretval = gdb_write(connection, \"+\", 1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (gdb_con->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_get_packet(struct connection *connection, char *buffer, int *len)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tgdb_con->busy = true;\n\tint retval = gdb_get_packet_inner(connection, buffer, len);\n\tgdb_con->busy = false;\n\treturn retval;\n}\n\nstatic int gdb_output_con(struct connection *connection, const char *line)\n{\n\tchar *hex_buffer;\n\tint bin_size;\n\n\tbin_size = strlen(line);\n\n\thex_buffer = malloc(bin_size * 2 + 2);\n\tif (!hex_buffer)\n\t\treturn ERROR_GDB_BUFFER_TOO_SMALL;\n\n\thex_buffer[0] = 'O';\n\tsize_t pkt_len = hexify(hex_buffer + 1, (const uint8_t *)line, bin_size,\n\t\tbin_size * 2 + 1);\n\tint retval = gdb_put_packet(connection, hex_buffer, pkt_len + 1);\n\n\tfree(hex_buffer);\n\treturn retval;\n}\n\nstatic int gdb_output(struct command_context *context, const char *line)\n{\n\t/* this will be dumped to the log and also sent as an O packet if possible */\n\tLOG_USER_N(\"%s\", line);\n\treturn ERROR_OK;\n}\n\nstatic void gdb_signal_reply(struct target *target, struct connection *connection)\n{\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\tchar sig_reply[65];\n\tchar stop_reason[32];\n\tchar current_thread[25];\n\tint sig_reply_len;\n\tint signal_var;\n\n\trtos_update_threads(target);\n\n\tif (target->debug_reason == DBG_REASON_EXIT) {\n\t\tsig_reply_len = snprintf(sig_reply, sizeof(sig_reply), \"W00\");\n\t} else {\n\t\tstruct target *ct;\n\t\tif (target->rtos) {\n\t\t\ttarget->rtos->current_threadid = target->rtos->current_thread;\n\t\t\ttarget->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &ct);\n\t\t} else {\n\t\t\tct = target;\n\t\t}\n\n\t\tif (gdb_connection->ctrl_c) {\n\t\t\tLOG_TARGET_DEBUG(target, \"Responding with signal 2 (SIGINT) to debugger due to Ctrl-C\");\n\t\t\tsignal_var = 0x2;\n\t\t} else\n\t\t\tsignal_var = gdb_last_signal(ct);\n\n\t\tstop_reason[0] = '\\0';\n\t\tif (ct->debug_reason == DBG_REASON_WATCHPOINT) {\n\t\t\tenum watchpoint_rw hit_wp_type;\n\t\t\ttarget_addr_t hit_wp_address;\n\n\t\t\tif (watchpoint_hit(ct, &hit_wp_type, &hit_wp_address) == ERROR_OK) {\n\n\t\t\t\tswitch (hit_wp_type) {\n\t\t\t\t\tcase WPT_WRITE:\n\t\t\t\t\t\tsnprintf(stop_reason, sizeof(stop_reason),\n\t\t\t\t\t\t\t\t\"watch:%08\" TARGET_PRIxADDR \";\", hit_wp_address);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase WPT_READ:\n\t\t\t\t\t\tsnprintf(stop_reason, sizeof(stop_reason),\n\t\t\t\t\t\t\t\t\"rwatch:%08\" TARGET_PRIxADDR \";\", hit_wp_address);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase WPT_ACCESS:\n\t\t\t\t\t\tsnprintf(stop_reason, sizeof(stop_reason),\n\t\t\t\t\t\t\t\t\"awatch:%08\" TARGET_PRIxADDR \";\", hit_wp_address);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcurrent_thread[0] = '\\0';\n\t\tif (target->rtos)\n\t\t\tsnprintf(current_thread, sizeof(current_thread), \"thread:%\" PRIx64 \";\",\n\t\t\t\t\ttarget->rtos->current_thread);\n\n\t\tsig_reply_len = snprintf(sig_reply, sizeof(sig_reply), \"T%2.2x%s%s\",\n\t\t\t\tsignal_var, stop_reason, current_thread);\n\n\t\tgdb_connection->ctrl_c = false;\n\t}\n\n\tgdb_put_packet(connection, sig_reply, sig_reply_len);\n\tgdb_connection->frontend_state = TARGET_HALTED;\n}\n\nstatic void gdb_fileio_reply(struct target *target, struct connection *connection)\n{\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\tchar fileio_command[256];\n\tint command_len;\n\tbool program_exited = false;\n\n\tif (strcmp(target->fileio_info->identifier, \"open\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \"/%\" PRIx64 \",%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2 + 1,\t/* len + trailing zero */\n\t\t\t\ttarget->fileio_info->param_3,\n\t\t\t\ttarget->fileio_info->param_4);\n\telse if (strcmp(target->fileio_info->identifier, \"close\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1);\n\telse if (strcmp(target->fileio_info->identifier, \"read\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \",%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2,\n\t\t\t\ttarget->fileio_info->param_3);\n\telse if (strcmp(target->fileio_info->identifier, \"write\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \",%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2,\n\t\t\t\ttarget->fileio_info->param_3);\n\telse if (strcmp(target->fileio_info->identifier, \"lseek\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \",%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2,\n\t\t\t\ttarget->fileio_info->param_3);\n\telse if (strcmp(target->fileio_info->identifier, \"rename\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \"/%\" PRIx64 \",%\" PRIx64 \"/%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2 + 1,\t/* len + trailing zero */\n\t\t\t\ttarget->fileio_info->param_3,\n\t\t\t\ttarget->fileio_info->param_4 + 1);\t/* len + trailing zero */\n\telse if (strcmp(target->fileio_info->identifier, \"unlink\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \"/%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2 + 1);\t/* len + trailing zero */\n\telse if (strcmp(target->fileio_info->identifier, \"stat\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \"/%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2,\n\t\t\t\ttarget->fileio_info->param_3);\n\telse if (strcmp(target->fileio_info->identifier, \"fstat\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2);\n\telse if (strcmp(target->fileio_info->identifier, \"gettimeofday\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \",%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2);\n\telse if (strcmp(target->fileio_info->identifier, \"isatty\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1);\n\telse if (strcmp(target->fileio_info->identifier, \"system\") == 0)\n\t\tsprintf(fileio_command, \"F%s,%\" PRIx64 \"/%\" PRIx64, target->fileio_info->identifier,\n\t\t\t\ttarget->fileio_info->param_1,\n\t\t\t\ttarget->fileio_info->param_2 + 1);\t/* len + trailing zero */\n\telse if (strcmp(target->fileio_info->identifier, \"exit\") == 0) {\n\t\t/* If target hits exit syscall, report to GDB the program is terminated.\n\t\t * In addition, let target run its own exit syscall handler. */\n\t\tprogram_exited = true;\n\t\tsprintf(fileio_command, \"W%02\" PRIx64, target->fileio_info->param_1);\n\t} else {\n\t\tLOG_DEBUG(\"Unknown syscall: %s\", target->fileio_info->identifier);\n\n\t\t/* encounter unknown syscall, continue */\n\t\tgdb_connection->frontend_state = TARGET_RUNNING;\n\t\ttarget_resume(target, 1, 0x0, 0, 0);\n\t\treturn;\n\t}\n\n\tcommand_len = strlen(fileio_command);\n\tgdb_put_packet(connection, fileio_command, command_len);\n\n\tif (program_exited) {\n\t\t/* Use target_resume() to let target run its own exit syscall handler. */\n\t\tgdb_connection->frontend_state = TARGET_RUNNING;\n\t\ttarget_resume(target, 1, 0x0, 0, 0);\n\t} else {\n\t\tgdb_connection->frontend_state = TARGET_HALTED;\n\t\trtos_update_threads(target);\n\t}\n}\n\nstatic void gdb_frontend_halted(struct target *target, struct connection *connection)\n{\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\n\t/* In the GDB protocol when we are stepping or continuing execution,\n\t * we have a lingering reply. Upon receiving a halted event\n\t * when we have that lingering packet, we reply to the original\n\t * step or continue packet.\n\t *\n\t * Executing monitor commands can bring the target in and\n\t * out of the running state so we'll see lots of TARGET_EVENT_XXX\n\t * that are to be ignored.\n\t */\n\tif (gdb_connection->frontend_state == TARGET_RUNNING) {\n\t\t/* stop forwarding log packets! */\n\t\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\n\t\t/* check fileio first */\n\t\tif (target_get_gdb_fileio_info(target, target->fileio_info) == ERROR_OK)\n\t\t\tgdb_fileio_reply(target, connection);\n\t\telse\n\t\t\tgdb_signal_reply(target, connection);\n\t}\n}\n\nstatic int gdb_target_callback_event_handler(struct target *target,\n\t\tenum target_event event, void *priv)\n{\n\tstruct connection *connection = priv;\n\tstruct gdb_service *gdb_service = connection->service->priv;\n\n\tif (gdb_service->target != target)\n\t\treturn ERROR_OK;\n\n\tswitch (event) {\n\t\tcase TARGET_EVENT_GDB_HALT:\n\t\t\tgdb_frontend_halted(target, connection);\n\t\t\tbreak;\n\t\tcase TARGET_EVENT_HALTED:\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_END);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_new_connection(struct connection *connection)\n{\n\tstruct gdb_connection *gdb_connection = malloc(sizeof(struct gdb_connection));\n\tstruct target *target;\n\tint retval;\n\tint initial_ack;\n\n\ttarget = get_target_from_connection(connection);\n\tconnection->priv = gdb_connection;\n\tconnection->cmd_ctx->current_target = target;\n\n\t/* initialize gdb connection information */\n\tgdb_connection->buf_p = gdb_connection->buffer;\n\tgdb_connection->buf_cnt = 0;\n\tgdb_connection->ctrl_c = false;\n\tgdb_connection->frontend_state = TARGET_HALTED;\n\tgdb_connection->vflash_image = NULL;\n\tgdb_connection->closed = false;\n\tgdb_connection->busy = false;\n\tgdb_connection->noack_mode = 0;\n\tgdb_connection->sync = false;\n\tgdb_connection->mem_write_error = false;\n\tgdb_connection->attached = true;\n\tgdb_connection->extended_protocol = false;\n\tgdb_connection->target_desc.tdesc = NULL;\n\tgdb_connection->target_desc.tdesc_length = 0;\n\tgdb_connection->thread_list = NULL;\n\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\n\t/* send ACK to GDB for debug request */\n\tgdb_write(connection, \"+\", 1);\n\n\t/* output goes through gdb connection */\n\tcommand_set_output_handler(connection->cmd_ctx, gdb_output, connection);\n\n\t/* we must remove all breakpoints registered to the target as a previous\n\t * GDB session could leave dangling breakpoints if e.g. communication\n\t * timed out.\n\t */\n\tbreakpoint_clear_target(target);\n\twatchpoint_clear_target(target);\n\n\t/* Since version 3.95 (gdb-19990504), with the exclusion of 6.5~6.8, GDB\n\t * sends an ACK at connection with the following comment in its source code:\n\t * \"Ack any packet which the remote side has already sent.\"\n\t * LLDB does the same since the first gdb-remote implementation.\n\t * Remove the initial ACK from the incoming buffer.\n\t */\n\tretval = gdb_get_char(connection, &initial_ack);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (initial_ack != '+')\n\t\tgdb_putback_char(connection, initial_ack);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_ATTACH);\n\n\tif (target->rtos) {\n\t\t/* clean previous rtos session if supported*/\n\t\tif (target->rtos->type->clean)\n\t\t\ttarget->rtos->type->clean(target);\n\n\t\t/* update threads */\n\t\trtos_update_threads(target);\n\t}\n\n\tif (gdb_use_memory_map) {\n\t\t/* Connect must fail if the memory map can't be set up correctly.\n\t\t *\n\t\t * This will cause an auto_probe to be invoked, which is either\n\t\t * a no-op or it will fail when the target isn't ready(e.g. not halted).\n\t\t */\n\t\tfor (unsigned int i = 0; i < flash_get_bank_count(); i++) {\n\t\t\tstruct flash_bank *p;\n\t\t\tp = get_flash_bank_by_num_noprobe(i);\n\t\t\tif (p->target != target)\n\t\t\t\tcontinue;\n\t\t\tretval = get_flash_bank_by_num(i, &p);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Connect failed. Consider setting up a gdb-attach event for the target \"\n\t\t\t\t\t\t\"to prepare target for GDB connect, or use 'gdb_memory_map disable'.\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n\n\tgdb_actual_connections++;\n\tlog_printf_lf(all_targets->next ? LOG_LVL_INFO : LOG_LVL_DEBUG,\n\t\t\t__FILE__, __LINE__, __func__,\n\t\t\t\"New GDB Connection: %d, Target %s, state: %s\",\n\t\t\tgdb_actual_connections,\n\t\t\ttarget_name(target),\n\t\t\ttarget_state_name(target));\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target %s not examined yet, refuse gdb connection %d!\",\n\t\t\t\t  target_name(target), gdb_actual_connections);\n\t\tgdb_actual_connections--;\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tif (target->state != TARGET_HALTED)\n\t\tLOG_WARNING(\"GDB connection %d on target %s not halted\",\n\t\t\t\t\tgdb_actual_connections, target_name(target));\n\n\t/* DANGER! If we fail subsequently, we must remove this handler,\n\t * otherwise we occasionally see crashes as the timer can invoke the\n\t * callback fn.\n\t *\n\t * register callback to be informed about target events */\n\ttarget_register_event_callback(gdb_target_callback_event_handler, connection);\n\n\tlog_add_callback(gdb_log_callback, connection);\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_connection_closed(struct connection *connection)\n{\n\tstruct target *target;\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\n\ttarget = get_target_from_connection(connection);\n\n\t/* we're done forwarding messages. Tear down callback before\n\t * cleaning up connection.\n\t */\n\tlog_remove_callback(gdb_log_callback, connection);\n\n\tgdb_actual_connections--;\n\tLOG_DEBUG(\"GDB Close, Target: %s, state: %s, gdb_actual_connections=%d\",\n\t\ttarget_name(target),\n\t\ttarget_state_name(target),\n\t\tgdb_actual_connections);\n\n\t/* see if an image built with vFlash commands is left */\n\tif (gdb_connection->vflash_image) {\n\t\timage_close(gdb_connection->vflash_image);\n\t\tfree(gdb_connection->vflash_image);\n\t\tgdb_connection->vflash_image = NULL;\n\t}\n\n\t/* if this connection registered a debug-message receiver delete it */\n\tdelete_debug_msg_receiver(connection->cmd_ctx, target);\n\n\tfree(connection->priv);\n\tconnection->priv = NULL;\n\n\ttarget_unregister_event_callback(gdb_target_callback_event_handler, connection);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_END);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_DETACH);\n\n\treturn ERROR_OK;\n}\n\nstatic void gdb_send_error(struct connection *connection, uint8_t the_error)\n{\n\tchar err[4];\n\tsnprintf(err, 4, \"E%2.2X\", the_error);\n\tgdb_put_packet(connection, err, 3);\n}\n\nstatic int gdb_last_signal_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tchar sig_reply[4];\n\tint signal_var;\n\n\tif (!gdb_con->attached) {\n\t\t/* if we are here we have received a kill packet\n\t\t * reply W stop reply otherwise gdb gets very unhappy */\n\t\tgdb_put_packet(connection, \"W00\", 3);\n\t\treturn ERROR_OK;\n\t}\n\n\tsignal_var = gdb_last_signal(target);\n\n\tsnprintf(sig_reply, 4, \"S%2.2x\", signal_var);\n\tgdb_put_packet(connection, sig_reply, 3);\n\n\treturn ERROR_OK;\n}\n\nstatic inline int gdb_reg_pos(struct target *target, int pos, int len)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\treturn pos;\n\telse\n\t\treturn len - 1 - pos;\n}\n\n/* Convert register to string of bytes. NB! The # of bits in the\n * register might be non-divisible by 8(a byte), in which\n * case an entire byte is shown.\n *\n * NB! the format on the wire is the target endianness\n *\n * The format of reg->value is little endian\n *\n */\nstatic void gdb_str_to_target(struct target *target,\n\t\tchar *tstr, struct reg *reg)\n{\n\tint i;\n\n\tuint8_t *buf;\n\tint buf_len;\n\tbuf = reg->value;\n\tbuf_len = DIV_ROUND_UP(reg->size, 8);\n\n\tfor (i = 0; i < buf_len; i++) {\n\t\tint j = gdb_reg_pos(target, i, buf_len);\n\t\ttstr += sprintf(tstr, \"%02x\", buf[j]);\n\t}\n}\n\n/* copy over in register buffer */\nstatic void gdb_target_to_reg(struct target *target,\n\t\tchar const *tstr, int str_len, uint8_t *bin)\n{\n\tif (str_len % 2) {\n\t\tLOG_ERROR(\"BUG: gdb value with uneven number of characters encountered\");\n\t\texit(-1);\n\t}\n\n\tint i;\n\tfor (i = 0; i < str_len; i += 2) {\n\t\tunsigned t;\n\t\tif (sscanf(tstr + i, \"%02x\", &t) != 1) {\n\t\t\tLOG_ERROR(\"BUG: unable to convert register value\");\n\t\t\texit(-1);\n\t\t}\n\n\t\tint j = gdb_reg_pos(target, i/2, str_len/2);\n\t\tbin[j] = t;\n\t}\n}\n\nstatic int gdb_get_registers_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tstruct reg **reg_list;\n\tint reg_list_size;\n\tint retval;\n\tint reg_packet_size = 0;\n\tchar *reg_packet;\n\tchar *reg_packet_p;\n\tint i;\n\n#ifdef _DEBUG_GDB_IO_\n\tLOG_DEBUG(\"-\");\n#endif\n\n\tif ((target->rtos) && (rtos_get_gdb_reg_list(connection) == ERROR_OK))\n\t\treturn ERROR_OK;\n\n\tretval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_GENERAL);\n\tif (retval != ERROR_OK)\n\t\treturn gdb_error(connection, retval);\n\n\tfor (i = 0; i < reg_list_size; i++) {\n\t\tif (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\tcontinue;\n\t\treg_packet_size += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;\n\t}\n\n\tassert(reg_packet_size > 0);\n\n\treg_packet = malloc(reg_packet_size + 1); /* plus one for string termination null */\n\tif (!reg_packet)\n\t\treturn ERROR_FAIL;\n\n\treg_packet_p = reg_packet;\n\n\tfor (i = 0; i < reg_list_size; i++) {\n\t\tif (!reg_list[i] || reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\tcontinue;\n\t\tif (!reg_list[i]->valid) {\n\t\t\tretval = reg_list[i]->type->get(reg_list[i]);\n\t\t\tif (retval != ERROR_OK && gdb_report_register_access_error) {\n\t\t\t\tLOG_DEBUG(\"Couldn't get register %s.\", reg_list[i]->name);\n\t\t\t\tfree(reg_packet);\n\t\t\t\tfree(reg_list);\n\t\t\t\treturn gdb_error(connection, retval);\n\t\t\t}\n\t\t}\n\t\tgdb_str_to_target(target, reg_packet_p, reg_list[i]);\n\t\treg_packet_p += DIV_ROUND_UP(reg_list[i]->size, 8) * 2;\n\t}\n\n#ifdef _DEBUG_GDB_IO_\n\t{\n\t\tchar *reg_packet_p_debug;\n\t\treg_packet_p_debug = strndup(reg_packet, reg_packet_size);\n\t\tLOG_DEBUG(\"reg_packet: %s\", reg_packet_p_debug);\n\t\tfree(reg_packet_p_debug);\n\t}\n#endif\n\n\tgdb_put_packet(connection, reg_packet, reg_packet_size);\n\tfree(reg_packet);\n\n\tfree(reg_list);\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_set_registers_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint i;\n\tstruct reg **reg_list;\n\tint reg_list_size;\n\tint retval;\n\tchar const *packet_p;\n\n#ifdef _DEBUG_GDB_IO_\n\tLOG_DEBUG(\"-\");\n#endif\n\n\t/* skip command character */\n\tpacket++;\n\tpacket_size--;\n\n\tif (packet_size % 2) {\n\t\tLOG_WARNING(\"GDB set_registers packet with uneven characters received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tretval = target_get_gdb_reg_list(target, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_GENERAL);\n\tif (retval != ERROR_OK)\n\t\treturn gdb_error(connection, retval);\n\n\tpacket_p = packet;\n\tfor (i = 0; i < reg_list_size; i++) {\n\t\tuint8_t *bin_buf;\n\t\tif (!reg_list[i] || !reg_list[i]->exist || reg_list[i]->hidden)\n\t\t\tcontinue;\n\t\tint chars = (DIV_ROUND_UP(reg_list[i]->size, 8) * 2);\n\n\t\tif (packet_p + chars > packet + packet_size)\n\t\t\tLOG_ERROR(\"BUG: register packet is too small for registers\");\n\n\t\tbin_buf = malloc(DIV_ROUND_UP(reg_list[i]->size, 8));\n\t\tgdb_target_to_reg(target, packet_p, chars, bin_buf);\n\n\t\tretval = reg_list[i]->type->set(reg_list[i], bin_buf);\n\t\tif (retval != ERROR_OK && gdb_report_register_access_error) {\n\t\t\tLOG_DEBUG(\"Couldn't set register %s.\", reg_list[i]->name);\n\t\t\tfree(reg_list);\n\t\t\tfree(bin_buf);\n\t\t\treturn gdb_error(connection, retval);\n\t\t}\n\n\t\t/* advance packet pointer */\n\t\tpacket_p += chars;\n\n\t\tfree(bin_buf);\n\t}\n\n\t/* free struct reg *reg_list[] array allocated by get_gdb_reg_list */\n\tfree(reg_list);\n\n\tgdb_put_packet(connection, \"OK\", 2);\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_get_register_packet(struct connection *connection,\n\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *reg_packet;\n\tint reg_num = strtoul(packet + 1, NULL, 16);\n\tstruct reg **reg_list;\n\tint reg_list_size;\n\tint retval;\n\n#ifdef _DEBUG_GDB_IO_\n\tLOG_DEBUG(\"-\");\n#endif\n\n\tif ((target->rtos) && (rtos_get_gdb_reg(connection, reg_num) == ERROR_OK))\n\t\treturn ERROR_OK;\n\n\tretval = target_get_gdb_reg_list_noread(target, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_ALL);\n\tif (retval != ERROR_OK)\n\t\treturn gdb_error(connection, retval);\n\n\tif ((reg_list_size <= reg_num) || !reg_list[reg_num] ||\n\t\t!reg_list[reg_num]->exist || reg_list[reg_num]->hidden) {\n\t\tLOG_ERROR(\"gdb requested a non-existing register (reg_num=%d)\", reg_num);\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tif (!reg_list[reg_num]->valid) {\n\t\tretval = reg_list[reg_num]->type->get(reg_list[reg_num]);\n\t\tif (retval != ERROR_OK && gdb_report_register_access_error) {\n\t\t\tLOG_DEBUG(\"Couldn't get register %s.\", reg_list[reg_num]->name);\n\t\t\tfree(reg_list);\n\t\t\treturn gdb_error(connection, retval);\n\t\t}\n\t}\n\n\treg_packet = calloc(DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2 + 1, 1); /* plus one for string termination null */\n\n\tgdb_str_to_target(target, reg_packet, reg_list[reg_num]);\n\n\tgdb_put_packet(connection, reg_packet, DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2);\n\n\tfree(reg_list);\n\tfree(reg_packet);\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_set_register_packet(struct connection *connection,\n\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tint reg_num = strtoul(packet + 1, &separator, 16);\n\tstruct reg **reg_list;\n\tint reg_list_size;\n\tint retval;\n\n#ifdef _DEBUG_GDB_IO_\n\tLOG_DEBUG(\"-\");\n#endif\n\n\tif (*separator != '=') {\n\t\tLOG_ERROR(\"GDB 'set register packet', but no '=' following the register number\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\tsize_t chars = strlen(separator + 1);\n\tuint8_t *bin_buf = malloc(chars / 2);\n\tgdb_target_to_reg(target, separator + 1, chars, bin_buf);\n\n\tif ((target->rtos) &&\n\t\t\t(rtos_set_reg(connection, reg_num, bin_buf) == ERROR_OK)) {\n\t\tfree(bin_buf);\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = target_get_gdb_reg_list_noread(target, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_ALL);\n\tif (retval != ERROR_OK) {\n\t\tfree(bin_buf);\n\t\treturn gdb_error(connection, retval);\n\t}\n\n\tif ((reg_list_size <= reg_num) || !reg_list[reg_num] ||\n\t\t!reg_list[reg_num]->exist || reg_list[reg_num]->hidden) {\n\t\tLOG_ERROR(\"gdb requested a non-existing register (reg_num=%d)\", reg_num);\n\t\tfree(bin_buf);\n\t\tfree(reg_list);\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tif (chars != (DIV_ROUND_UP(reg_list[reg_num]->size, 8) * 2)) {\n\t\tLOG_ERROR(\"gdb sent %zu bits for a %\" PRIu32 \"-bit register (%s)\",\n\t\t\t\tchars * 4, reg_list[reg_num]->size, reg_list[reg_num]->name);\n\t\tfree(bin_buf);\n\t\tfree(reg_list);\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tgdb_target_to_reg(target, separator + 1, chars, bin_buf);\n\n\tretval = reg_list[reg_num]->type->set(reg_list[reg_num], bin_buf);\n\tif (retval != ERROR_OK && gdb_report_register_access_error) {\n\t\tLOG_DEBUG(\"Couldn't set register %s.\", reg_list[reg_num]->name);\n\t\tfree(bin_buf);\n\t\tfree(reg_list);\n\t\treturn gdb_error(connection, retval);\n\t}\n\n\tgdb_put_packet(connection, \"OK\", 2);\n\n\tfree(bin_buf);\n\tfree(reg_list);\n\n\treturn ERROR_OK;\n}\n\n/* No attempt is made to translate the \"retval\" to\n * GDB speak. This has to be done at the calling\n * site as no mapping really exists.\n */\nstatic int gdb_error(struct connection *connection, int retval)\n{\n\tLOG_DEBUG(\"Reporting %i to GDB as generic error\", retval);\n\tgdb_send_error(connection, EFAULT);\n\treturn ERROR_OK;\n}\n\n/* We don't have to worry about the default 2 second timeout for GDB packets,\n * because GDB breaks up large memory reads into smaller reads.\n */\nstatic int gdb_read_memory_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tuint64_t addr = 0;\n\tuint32_t len = 0;\n\n\tuint8_t *buffer;\n\tchar *hex_buffer;\n\n\tint retval = ERROR_OK;\n\n\t/* skip command character */\n\tpacket++;\n\n\taddr = strtoull(packet, &separator, 16);\n\n\tif (*separator != ',') {\n\t\tLOG_ERROR(\"incomplete read memory packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tlen = strtoul(separator + 1, NULL, 16);\n\n\tif (!len) {\n\t\tLOG_WARNING(\"invalid read memory packet received (len == 0)\");\n\t\tgdb_put_packet(connection, \"\", 0);\n\t\treturn ERROR_OK;\n\t}\n\n\tbuffer = malloc(len);\n\n\tLOG_DEBUG(\"addr: 0x%16.16\" PRIx64 \", len: 0x%8.8\" PRIx32 \"\", addr, len);\n\n\tretval = ERROR_NOT_IMPLEMENTED;\n\tif (target->rtos)\n\t\tretval = rtos_read_buffer(target, addr, len, buffer);\n\tif (retval == ERROR_NOT_IMPLEMENTED)\n\t\tretval = target_read_buffer(target, addr, len, buffer);\n\n\tif ((retval != ERROR_OK) && !gdb_report_data_abort) {\n\t\t/* TODO : Here we have to lie and send back all zero's lest stack traces won't work.\n\t\t * At some point this might be fixed in GDB, in which case this code can be removed.\n\t\t *\n\t\t * OpenOCD developers are acutely aware of this problem, but there is nothing\n\t\t * gained by involving the user in this problem that hopefully will get resolved\n\t\t * eventually\n\t\t *\n\t\t * http://sourceware.org/cgi-bin/gnatsweb.pl? \\\n\t\t * cmd = view%20audit-trail&database = gdb&pr = 2395\n\t\t *\n\t\t * For now, the default is to fix up things to make current GDB versions work.\n\t\t * This can be overwritten using the gdb_report_data_abort <'enable'|'disable'> command.\n\t\t */\n\t\tmemset(buffer, 0, len);\n\t\tretval = ERROR_OK;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\thex_buffer = malloc(len * 2 + 1);\n\n\t\tsize_t pkt_len = hexify(hex_buffer, buffer, len, len * 2 + 1);\n\n\t\tgdb_put_packet(connection, hex_buffer, pkt_len);\n\n\t\tfree(hex_buffer);\n\t} else\n\t\tretval = gdb_error(connection, retval);\n\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int gdb_write_memory_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tuint64_t addr = 0;\n\tuint32_t len = 0;\n\n\tuint8_t *buffer;\n\tint retval;\n\n\t/* skip command character */\n\tpacket++;\n\n\taddr = strtoull(packet, &separator, 16);\n\n\tif (*separator != ',') {\n\t\tLOG_ERROR(\"incomplete write memory packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tlen = strtoul(separator + 1, &separator, 16);\n\n\tif (*(separator++) != ':') {\n\t\tLOG_ERROR(\"incomplete write memory packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tbuffer = malloc(len);\n\n\tLOG_DEBUG(\"addr: 0x%\" PRIx64 \", len: 0x%8.8\" PRIx32 \"\", addr, len);\n\n\tif (unhexify(buffer, separator, len) != len)\n\t\tLOG_ERROR(\"unable to decode memory packet\");\n\n\tretval = ERROR_NOT_IMPLEMENTED;\n\tif (target->rtos)\n\t\tretval = rtos_write_buffer(target, addr, len, buffer);\n\tif (retval == ERROR_NOT_IMPLEMENTED)\n\t\tretval = target_write_buffer(target, addr, len, buffer);\n\n\tif (retval == ERROR_OK)\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\telse\n\t\tretval = gdb_error(connection, retval);\n\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int gdb_write_memory_binary_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tuint64_t addr = 0;\n\tuint32_t len = 0;\n\n\tint retval = ERROR_OK;\n\t/* Packets larger than fast_limit bytes will be acknowledged instantly on\n\t * the assumption that we're in a download and it's important to go as fast\n\t * as possible. */\n\tuint32_t fast_limit = 8;\n\n\t/* skip command character */\n\tpacket++;\n\n\taddr = strtoull(packet, &separator, 16);\n\n\tif (*separator != ',') {\n\t\tLOG_ERROR(\"incomplete write memory binary packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tlen = strtoul(separator + 1, &separator, 16);\n\n\tif (*(separator++) != ':') {\n\t\tLOG_ERROR(\"incomplete write memory binary packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\n\tif (gdb_connection->mem_write_error)\n\t\tretval = ERROR_FAIL;\n\n\tif (retval == ERROR_OK) {\n\t\tif (len >= fast_limit) {\n\t\t\t/* By replying the packet *immediately* GDB will send us a new packet\n\t\t\t * while we write the last one to the target.\n\t\t\t * We only do this for larger writes, so that users who do something like:\n\t\t\t * p *((int*)0xdeadbeef)=8675309\n\t\t\t * will get immediate feedback that that write failed.\n\t\t\t */\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t}\n\t} else {\n\t\tretval = gdb_error(connection, retval);\n\t\t/* now that we have reported the memory write error, we can clear the condition */\n\t\tgdb_connection->mem_write_error = false;\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (len) {\n\t\tLOG_DEBUG(\"addr: 0x%\" PRIx64 \", len: 0x%8.8\" PRIx32 \"\", addr, len);\n\n\t\tretval = ERROR_NOT_IMPLEMENTED;\n\t\tif (target->rtos)\n\t\t\tretval = rtos_write_buffer(target, addr, len, (uint8_t *)separator);\n\t\tif (retval == ERROR_NOT_IMPLEMENTED)\n\t\t\tretval = target_write_buffer(target, addr, len, (uint8_t *)separator);\n\n\t\tif (retval != ERROR_OK)\n\t\t\tgdb_connection->mem_write_error = true;\n\t}\n\n\tif (len < fast_limit) {\n\t\tif (retval != ERROR_OK) {\n\t\t\tgdb_error(connection, retval);\n\t\t\tgdb_connection->mem_write_error = false;\n\t\t} else {\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_step_continue_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint current = 0;\n\tuint64_t address = 0x0;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (packet_size > 1)\n\t\taddress = strtoull(packet + 1, NULL, 16);\n\telse\n\t\tcurrent = 1;\n\n\tgdb_running_type = packet[0];\n\tif (packet[0] == 'c') {\n\t\tLOG_DEBUG(\"continue\");\n\t\t/* resume at current address, don't handle breakpoints, not debugging */\n\t\tretval = target_resume(target, current, address, 0, 0);\n\t} else if (packet[0] == 's') {\n\t\tLOG_DEBUG(\"step\");\n\t\t/* step at current or address, don't handle breakpoints */\n\t\tretval = target_step(target, current, address, 0);\n\t}\n\treturn retval;\n}\n\nstatic int gdb_breakpoint_watchpoint_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint type;\n\tenum breakpoint_type bp_type = BKPT_SOFT /* dummy init to avoid warning */;\n\tenum watchpoint_rw wp_type = WPT_READ /* dummy init to avoid warning */;\n\tuint64_t address;\n\tuint32_t size;\n\tchar *separator;\n\tint retval;\n\n\tLOG_DEBUG(\"[%s]\", target_name(target));\n\n\ttype = strtoul(packet + 1, &separator, 16);\n\n\tif (type == 0)\t/* memory breakpoint */\n\t\tbp_type = BKPT_SOFT;\n\telse if (type == 1)\t/* hardware breakpoint */\n\t\tbp_type = BKPT_HARD;\n\telse if (type == 2)\t/* write watchpoint */\n\t\twp_type = WPT_WRITE;\n\telse if (type == 3)\t/* read watchpoint */\n\t\twp_type = WPT_READ;\n\telse if (type == 4)\t/* access watchpoint */\n\t\twp_type = WPT_ACCESS;\n\telse {\n\t\tLOG_ERROR(\"invalid gdb watch/breakpoint type(%d), dropping connection\", type);\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tif (gdb_breakpoint_override && ((bp_type == BKPT_SOFT) || (bp_type == BKPT_HARD)))\n\t\tbp_type = gdb_breakpoint_override_type;\n\n\tif (*separator != ',') {\n\t\tLOG_ERROR(\"incomplete breakpoint/watchpoint packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\taddress = strtoull(separator + 1, &separator, 16);\n\n\tif (*separator != ',') {\n\t\tLOG_ERROR(\"incomplete breakpoint/watchpoint packet received, dropping connection\");\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tsize = strtoul(separator + 1, &separator, 16);\n\n\tswitch (type) {\n\t\tcase 0:\n\t\tcase 1:\n\t\t\tif (packet[0] == 'Z') {\n\t\t\t\tretval = breakpoint_add(target, address, size, bp_type);\n\t\t\t\tif (retval == ERROR_NOT_IMPLEMENTED) {\n\t\t\t\t\t/* Send empty reply to report that breakpoints of this type are not supported */\n\t\t\t\t\tgdb_put_packet(connection, \"\", 0);\n\t\t\t\t} else if (retval != ERROR_OK) {\n\t\t\t\t\tretval = gdb_error(connection, retval);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t} else\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t} else {\n\t\t\t\tbreakpoint_remove(target, address);\n\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 2:\n\t\tcase 3:\n\t\tcase 4:\n\t\t{\n\t\t\tif (packet[0] == 'Z') {\n\t\t\t\tretval = watchpoint_add(target, address, size, wp_type, 0, 0xffffffffu);\n\t\t\t\tif (retval == ERROR_NOT_IMPLEMENTED) {\n\t\t\t\t\t/* Send empty reply to report that watchpoints of this type are not supported */\n\t\t\t\t\tgdb_put_packet(connection, \"\", 0);\n\t\t\t\t} else if (retval != ERROR_OK) {\n\t\t\t\t\tretval = gdb_error(connection, retval);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t} else\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t} else {\n\t\t\t\twatchpoint_remove(target, address);\n\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* print out a string and allocate more space as needed,\n * mainly used for XML at this point\n */\nstatic __attribute__ ((format (PRINTF_ATTRIBUTE_FORMAT, 5, 6))) void xml_printf(int *retval,\n\t\tchar **xml, int *pos, int *size, const char *fmt, ...)\n{\n\tif (*retval != ERROR_OK)\n\t\treturn;\n\tint first = 1;\n\n\tfor (;; ) {\n\t\tif ((!*xml) || (!first)) {\n\t\t\t/* start by 0 to exercise all the code paths.\n\t\t\t * Need minimum 2 bytes to fit 1 char and 0 terminator. */\n\n\t\t\t*size = *size * 2 + 2;\n\t\t\tchar *t = *xml;\n\t\t\t*xml = realloc(*xml, *size);\n\t\t\tif (!*xml) {\n\t\t\t\tfree(t);\n\t\t\t\t*retval = ERROR_SERVER_REMOTE_CLOSED;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tva_list ap;\n\t\tint ret;\n\t\tva_start(ap, fmt);\n\t\tret = vsnprintf(*xml + *pos, *size - *pos, fmt, ap);\n\t\tva_end(ap);\n\t\tif ((ret > 0) && ((ret + 1) < *size - *pos)) {\n\t\t\t*pos += ret;\n\t\t\treturn;\n\t\t}\n\t\t/* there was just enough or not enough space, allocate more. */\n\t\tfirst = 0;\n\t}\n}\n\nstatic int decode_xfer_read(char const *buf, char **annex, int *ofs, unsigned int *len)\n{\n\t/* Locate the annex. */\n\tconst char *annex_end = strchr(buf, ':');\n\tif (!annex_end)\n\t\treturn ERROR_FAIL;\n\n\t/* After the read marker and annex, qXfer looks like a\n\t * traditional 'm' packet. */\n\tchar *separator;\n\t*ofs = strtoul(annex_end + 1, &separator, 16);\n\n\tif (*separator != ',')\n\t\treturn ERROR_FAIL;\n\n\t*len = strtoul(separator + 1, NULL, 16);\n\n\t/* Extract the annex if needed */\n\tif (annex) {\n\t\t*annex = strndup(buf, annex_end - buf);\n\t\tif (!*annex)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int compare_bank(const void *a, const void *b)\n{\n\tstruct flash_bank *b1, *b2;\n\tb1 = *((struct flash_bank **)a);\n\tb2 = *((struct flash_bank **)b);\n\n\tif (b1->base == b2->base)\n\t\treturn 0;\n\telse if (b1->base > b2->base)\n\t\treturn 1;\n\telse\n\t\treturn -1;\n}\n\nstatic int gdb_memory_map(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\t/* We get away with only specifying flash here. Regions that are not\n\t * specified are treated as if we provided no memory map(if not we\n\t * could detect the holes and mark them as RAM).\n\t * Normally we only execute this code once, but no big deal if we\n\t * have to regenerate it a couple of times.\n\t */\n\n\tstruct target *target = get_target_from_connection(connection);\n\tstruct flash_bank *p;\n\tchar *xml = NULL;\n\tint size = 0;\n\tint pos = 0;\n\tint retval = ERROR_OK;\n\tstruct flash_bank **banks;\n\tint offset;\n\tint length;\n\tchar *separator;\n\ttarget_addr_t ram_start = 0;\n\tunsigned int target_flash_banks = 0;\n\n\t/* skip command character */\n\tpacket += 23;\n\n\toffset = strtoul(packet, &separator, 16);\n\tlength = strtoul(separator + 1, &separator, 16);\n\n\txml_printf(&retval, &xml, &pos, &size, \"<memory-map>\\n\");\n\n\t/* Sort banks in ascending order.  We need to report non-flash\n\t * memory as ram (or rather read/write) by default for GDB, since\n\t * it has no concept of non-cacheable read/write memory (i/o etc).\n\t */\n\tbanks = malloc(sizeof(struct flash_bank *)*flash_get_bank_count());\n\n\tfor (unsigned int i = 0; i < flash_get_bank_count(); i++) {\n\t\tp = get_flash_bank_by_num_noprobe(i);\n\t\tif (p->target != target)\n\t\t\tcontinue;\n\t\tretval = get_flash_bank_by_num(i, &p);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(banks);\n\t\t\tgdb_error(connection, retval);\n\t\t\treturn retval;\n\t\t}\n\t\tbanks[target_flash_banks++] = p;\n\t}\n\n\tqsort(banks, target_flash_banks, sizeof(struct flash_bank *),\n\t\tcompare_bank);\n\n\tfor (unsigned int i = 0; i < target_flash_banks; i++) {\n\t\tunsigned sector_size = 0;\n\t\tunsigned group_len = 0;\n\n\t\tp = banks[i];\n\n\t\tif (ram_start < p->base)\n\t\t\txml_printf(&retval, &xml, &pos, &size,\n\t\t\t\t\"<memory type=\\\"ram\\\" start=\\\"\" TARGET_ADDR_FMT \"\\\" \"\n\t\t\t\t\"length=\\\"\" TARGET_ADDR_FMT \"\\\"/>\\n\",\n\t\t\t\tram_start, p->base - ram_start);\n\n\t\t/* Report adjacent groups of same-size sectors.  So for\n\t\t * example top boot CFI flash will list an initial region\n\t\t * with several large sectors (maybe 128KB) and several\n\t\t * smaller ones at the end (maybe 32KB).  STR7 will have\n\t\t * regions with 8KB, 32KB, and 64KB sectors; etc.\n\t\t */\n\t\tfor (unsigned int j = 0; j < p->num_sectors; j++) {\n\n\t\t\t/* Maybe start a new group of sectors. */\n\t\t\tif (sector_size == 0) {\n\t\t\t\tif (p->sectors[j].offset + p->sectors[j].size > p->size) {\n\t\t\t\t\tLOG_WARNING(\"The flash sector at offset 0x%08\" PRIx32\n\t\t\t\t\t\t\" overflows the end of %s bank.\",\n\t\t\t\t\t\tp->sectors[j].offset, p->name);\n\t\t\t\t\tLOG_WARNING(\"The rest of bank will not show in gdb memory map.\");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ttarget_addr_t start;\n\t\t\t\tstart = p->base + p->sectors[j].offset;\n\t\t\t\txml_printf(&retval, &xml, &pos, &size,\n\t\t\t\t\t\"<memory type=\\\"flash\\\" \"\n\t\t\t\t\t\"start=\\\"\" TARGET_ADDR_FMT \"\\\" \",\n\t\t\t\t\tstart);\n\t\t\t\tsector_size = p->sectors[j].size;\n\t\t\t\tgroup_len = sector_size;\n\t\t\t} else {\n\t\t\t\tgroup_len += sector_size; /* equal to p->sectors[j].size */\n\t\t\t}\n\n\t\t\t/* Does this finish a group of sectors?\n\t\t\t * If not, continue an already-started group.\n\t\t\t */\n\t\t\tif (j < p->num_sectors - 1\n\t\t\t\t\t&& p->sectors[j + 1].size == sector_size\n\t\t\t\t\t&& p->sectors[j + 1].offset == p->sectors[j].offset + sector_size\n\t\t\t\t\t&& p->sectors[j + 1].offset + p->sectors[j + 1].size <= p->size)\n\t\t\t\tcontinue;\n\n\t\t\txml_printf(&retval, &xml, &pos, &size,\n\t\t\t\t\"length=\\\"0x%x\\\">\\n\"\n\t\t\t\t\"<property name=\\\"blocksize\\\">\"\n\t\t\t\t\"0x%x</property>\\n\"\n\t\t\t\t\"</memory>\\n\",\n\t\t\t\tgroup_len,\n\t\t\t\tsector_size);\n\t\t\tsector_size = 0;\n\t\t}\n\n\t\tram_start = p->base + p->size;\n\t}\n\n\tif (ram_start != 0)\n\t\txml_printf(&retval, &xml, &pos, &size,\n\t\t\t\"<memory type=\\\"ram\\\" start=\\\"\" TARGET_ADDR_FMT \"\\\" \"\n\t\t\t\"length=\\\"\" TARGET_ADDR_FMT \"\\\"/>\\n\",\n\t\t\tram_start, target_address_max(target) - ram_start + 1);\n\t/* ELSE a flash chip could be at the very end of the address space, in\n\t * which case ram_start will be precisely 0 */\n\n\tfree(banks);\n\n\txml_printf(&retval, &xml, &pos, &size, \"</memory-map>\\n\");\n\n\tif (retval != ERROR_OK) {\n\t\tfree(xml);\n\t\tgdb_error(connection, retval);\n\t\treturn retval;\n\t}\n\n\tif (offset + length > pos)\n\t\tlength = pos - offset;\n\n\tchar *t = malloc(length + 1);\n\tt[0] = 'l';\n\tmemcpy(t + 1, xml + offset, length);\n\tgdb_put_packet(connection, t, length + 1);\n\n\tfree(t);\n\tfree(xml);\n\treturn ERROR_OK;\n}\n\nstatic const char *gdb_get_reg_type_name(enum reg_type type)\n{\n\tswitch (type) {\n\t\tcase REG_TYPE_BOOL:\n\t\t\treturn \"bool\";\n\t\tcase REG_TYPE_INT:\n\t\t\treturn \"int\";\n\t\tcase REG_TYPE_INT8:\n\t\t\treturn \"int8\";\n\t\tcase REG_TYPE_INT16:\n\t\t\treturn \"int16\";\n\t\tcase REG_TYPE_INT32:\n\t\t\treturn \"int32\";\n\t\tcase REG_TYPE_INT64:\n\t\t\treturn \"int64\";\n\t\tcase REG_TYPE_INT128:\n\t\t\treturn \"int128\";\n\t\tcase REG_TYPE_UINT:\n\t\t\treturn \"uint\";\n\t\tcase REG_TYPE_UINT8:\n\t\t\treturn \"uint8\";\n\t\tcase REG_TYPE_UINT16:\n\t\t\treturn \"uint16\";\n\t\tcase REG_TYPE_UINT32:\n\t\t\treturn \"uint32\";\n\t\tcase REG_TYPE_UINT64:\n\t\t\treturn \"uint64\";\n\t\tcase REG_TYPE_UINT128:\n\t\t\treturn \"uint128\";\n\t\tcase REG_TYPE_CODE_PTR:\n\t\t\treturn \"code_ptr\";\n\t\tcase REG_TYPE_DATA_PTR:\n\t\t\treturn \"data_ptr\";\n\t\tcase REG_TYPE_FLOAT:\n\t\t\treturn \"float\";\n\t\tcase REG_TYPE_IEEE_SINGLE:\n\t\t\treturn \"ieee_single\";\n\t\tcase REG_TYPE_IEEE_DOUBLE:\n\t\t\treturn \"ieee_double\";\n\t\tcase REG_TYPE_ARCH_DEFINED:\n\t\t\treturn \"int\"; /* return arbitrary string to avoid compile warning. */\n\t}\n\n\treturn \"int\"; /* \"int\" as default value */\n}\n\nstatic int lookup_add_arch_defined_types(char const **arch_defined_types_list[], const char *type_id,\n\t\t\t\t\tint *num_arch_defined_types)\n{\n\tint tbl_sz = *num_arch_defined_types;\n\n\tif (type_id && (strcmp(type_id, \"\"))) {\n\t\tfor (int j = 0; j < (tbl_sz + 1); j++) {\n\t\t\tif (!((*arch_defined_types_list)[j])) {\n\t\t\t\t(*arch_defined_types_list)[tbl_sz++] = type_id;\n\t\t\t\t*arch_defined_types_list = realloc(*arch_defined_types_list,\n\t\t\t\t\t\t\t\tsizeof(char *) * (tbl_sz + 1));\n\t\t\t\t(*arch_defined_types_list)[tbl_sz] = NULL;\n\t\t\t\t*num_arch_defined_types = tbl_sz;\n\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\tif (!strcmp((*arch_defined_types_list)[j], type_id))\n\t\t\t\t\treturn 0;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n\nstatic int gdb_generate_reg_type_description(struct target *target,\n\t\tchar **tdesc, int *pos, int *size, struct reg_data_type *type,\n\t\tchar const **arch_defined_types_list[], int *num_arch_defined_types)\n{\n\tint retval = ERROR_OK;\n\n\tif (type->type_class == REG_TYPE_CLASS_VECTOR) {\n\t\tstruct reg_data_type *data_type = type->reg_type_vector->type;\n\t\tif (data_type->type == REG_TYPE_ARCH_DEFINED) {\n\t\t\tif (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,\n\t\t\t\t\t\t\tnum_arch_defined_types))\n\t\t\t\tgdb_generate_reg_type_description(target, tdesc, pos, size, data_type,\n\t\t\t\t\t\t\t\tarch_defined_types_list,\n\t\t\t\t\t\t\t\tnum_arch_defined_types);\n\t\t}\n\t\t/* <vector id=\"id\" type=\"type\" count=\"count\"/> */\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"<vector id=\\\"%s\\\" type=\\\"%s\\\" count=\\\"%\" PRIu32 \"\\\"/>\\n\",\n\t\t\t\ttype->id, type->reg_type_vector->type->id,\n\t\t\t\ttype->reg_type_vector->count);\n\n\t} else if (type->type_class == REG_TYPE_CLASS_UNION) {\n\t\tstruct reg_data_type_union_field *field;\n\t\tfield = type->reg_type_union->fields;\n\t\twhile (field) {\n\t\t\tstruct reg_data_type *data_type = field->type;\n\t\t\tif (data_type->type == REG_TYPE_ARCH_DEFINED) {\n\t\t\t\tif (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,\n\t\t\t\t\t\t\t\tnum_arch_defined_types))\n\t\t\t\t\tgdb_generate_reg_type_description(target, tdesc, pos, size, data_type,\n\t\t\t\t\t\t\t\t\tarch_defined_types_list,\n\t\t\t\t\t\t\t\t\tnum_arch_defined_types);\n\t\t\t}\n\n\t\t\tfield = field->next;\n\t\t}\n\t\t/* <union id=\"id\">\n\t\t *  <field name=\"name\" type=\"type\"/> ...\n\t\t * </union> */\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"<union id=\\\"%s\\\">\\n\",\n\t\t\t\ttype->id);\n\n\t\tfield = type->reg_type_union->fields;\n\t\twhile (field) {\n\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\"<field name=\\\"%s\\\" type=\\\"%s\\\"/>\\n\",\n\t\t\t\t\tfield->name, field->type->id);\n\n\t\t\tfield = field->next;\n\t\t}\n\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"</union>\\n\");\n\n\t} else if (type->type_class == REG_TYPE_CLASS_STRUCT) {\n\t\tstruct reg_data_type_struct_field *field;\n\t\tfield = type->reg_type_struct->fields;\n\n\t\tif (field->use_bitfields) {\n\t\t\t/* <struct id=\"id\" size=\"size\">\n\t\t\t *  <field name=\"name\" start=\"start\" end=\"end\"/> ...\n\t\t\t * </struct> */\n\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\"<struct id=\\\"%s\\\" size=\\\"%\" PRIu32 \"\\\">\\n\",\n\t\t\t\t\ttype->id, type->reg_type_struct->size);\n\t\t\twhile (field) {\n\t\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\t\"<field name=\\\"%s\\\" start=\\\"%\" PRIu32 \"\\\" end=\\\"%\" PRIu32 \"\\\" type=\\\"%s\\\" />\\n\",\n\t\t\t\t\t\tfield->name, field->bitfield->start, field->bitfield->end,\n\t\t\t\t\t\tgdb_get_reg_type_name(field->bitfield->type));\n\n\t\t\t\tfield = field->next;\n\t\t\t}\n\t\t} else {\n\t\t\twhile (field) {\n\t\t\t\tstruct reg_data_type *data_type = field->type;\n\t\t\t\tif (data_type->type == REG_TYPE_ARCH_DEFINED) {\n\t\t\t\t\tif (lookup_add_arch_defined_types(arch_defined_types_list, data_type->id,\n\t\t\t\t\t\t\t\t\tnum_arch_defined_types))\n\t\t\t\t\t\tgdb_generate_reg_type_description(target, tdesc, pos, size, data_type,\n\t\t\t\t\t\t\t\t\t\tarch_defined_types_list,\n\t\t\t\t\t\t\t\t\t\tnum_arch_defined_types);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* <struct id=\"id\">\n\t\t\t *  <field name=\"name\" type=\"type\"/> ...\n\t\t\t * </struct> */\n\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\"<struct id=\\\"%s\\\">\\n\",\n\t\t\t\t\ttype->id);\n\t\t\twhile (field) {\n\t\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\t\"<field name=\\\"%s\\\" type=\\\"%s\\\"/>\\n\",\n\t\t\t\t\t\tfield->name, field->type->id);\n\n\t\t\t\tfield = field->next;\n\t\t\t}\n\t\t}\n\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"</struct>\\n\");\n\n\t} else if (type->type_class == REG_TYPE_CLASS_FLAGS) {\n\t\t/* <flags id=\"id\" size=\"size\">\n\t\t *  <field name=\"name\" start=\"start\" end=\"end\"/> ...\n\t\t * </flags> */\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"<flags id=\\\"%s\\\" size=\\\"%\" PRIu32 \"\\\">\\n\",\n\t\t\t\ttype->id, type->reg_type_flags->size);\n\n\t\tstruct reg_data_type_flags_field *field;\n\t\tfield = type->reg_type_flags->fields;\n\t\twhile (field) {\n\t\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\t\"<field name=\\\"%s\\\" start=\\\"%\" PRIu32 \"\\\" end=\\\"%\" PRIu32 \"\\\" type=\\\"%s\\\" />\\n\",\n\t\t\t\t\tfield->name, field->bitfield->start, field->bitfield->end,\n\t\t\t\t\tgdb_get_reg_type_name(field->bitfield->type));\n\n\t\t\tfield = field->next;\n\t\t}\n\n\t\txml_printf(&retval, tdesc, pos, size,\n\t\t\t\t\"</flags>\\n\");\n\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Get a list of available target registers features. feature_list must\n * be freed by caller.\n */\nstatic int get_reg_features_list(struct target *target, char const **feature_list[], int *feature_list_size,\n\t\tstruct reg **reg_list, int reg_list_size)\n{\n\tint tbl_sz = 0;\n\n\t/* Start with only one element */\n\t*feature_list = calloc(1, sizeof(char *));\n\n\tfor (int i = 0; i < reg_list_size; i++) {\n\t\tif (reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\tcontinue;\n\n\t\tif (reg_list[i]->feature\n\t\t\t&& reg_list[i]->feature->name\n\t\t\t&& (strcmp(reg_list[i]->feature->name, \"\"))) {\n\t\t\t/* We found a feature, check if the feature is already in the\n\t\t\t * table. If not, allocate a new entry for the table and\n\t\t\t * put the new feature in it.\n\t\t\t */\n\t\t\tfor (int j = 0; j < (tbl_sz + 1); j++) {\n\t\t\t\tif (!((*feature_list)[j])) {\n\t\t\t\t\t(*feature_list)[tbl_sz++] = reg_list[i]->feature->name;\n\t\t\t\t\t*feature_list = realloc(*feature_list, sizeof(char *) * (tbl_sz + 1));\n\t\t\t\t\t(*feature_list)[tbl_sz] = NULL;\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tif (!strcmp((*feature_list)[j], reg_list[i]->feature->name))\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (feature_list_size)\n\t\t*feature_list_size = tbl_sz;\n\n\treturn ERROR_OK;\n}\n\n/* Create a register list that's the union of all the registers of the SMP\n * group this target is in. If the target is not part of an SMP group, this\n * returns the same as target_get_gdb_reg_list_noread().\n */\nstatic int smp_reg_list_noread(struct target *target,\n\t\tstruct reg **combined_list[], int *combined_list_size,\n\t\tenum target_register_class reg_class)\n{\n\tif (!target->smp)\n\t\treturn target_get_gdb_reg_list_noread(target, combined_list,\n\t\t\t\tcombined_list_size, REG_CLASS_ALL);\n\n\tunsigned int combined_allocated = 256;\n\tstruct reg **local_list = malloc(combined_allocated * sizeof(struct reg *));\n\tif (!local_list) {\n\t\tLOG_ERROR(\"malloc(%zu) failed\", combined_allocated * sizeof(struct reg *));\n\t\treturn ERROR_FAIL;\n\t}\n\tunsigned int local_list_size = 0;\n\n\tstruct target_list *head;\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tif (!target_was_examined(head->target))\n\t\t\tcontinue;\n\n\t\tstruct reg **reg_list = NULL;\n\t\tint reg_list_size;\n\t\tint result = target_get_gdb_reg_list_noread(head->target, &reg_list,\n\t\t\t\t&reg_list_size, reg_class);\n\t\tif (result != ERROR_OK) {\n\t\t\tfree(local_list);\n\t\t\treturn result;\n\t\t}\n\t\tfor (int i = 0; i < reg_list_size; i++) {\n\t\t\tbool found = false;\n\t\t\tstruct reg *a = reg_list[i];\n\t\t\tif (a->exist) {\n\t\t\t\t/* Nested loop makes this O(n^2), but this entire function with\n\t\t\t\t * 5 RISC-V targets takes just 2ms on my computer. Fast enough\n\t\t\t\t * for me. */\n\t\t\t\tfor (unsigned int j = 0; j < local_list_size; j++) {\n\t\t\t\t\tstruct reg *b = local_list[j];\n\t\t\t\t\tif (!strcmp(a->name, b->name)) {\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\tif (a->size != b->size) {\n\t\t\t\t\t\t\tLOG_ERROR(\"SMP register %s is %d bits on one \"\n\t\t\t\t\t\t\t\t\t\"target, but %d bits on another target.\",\n\t\t\t\t\t\t\t\t\ta->name, a->size, b->size);\n\t\t\t\t\t\t\tfree(reg_list);\n\t\t\t\t\t\t\tfree(local_list);\n\t\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!found) {\n\t\t\t\t\tLOG_DEBUG(\"[%s] %s not found in combined list\", target_name(target), a->name);\n\t\t\t\t\tif (local_list_size >= combined_allocated) {\n\t\t\t\t\t\tcombined_allocated *= 2;\n\t\t\t\t\t\tlocal_list = realloc(local_list, combined_allocated * sizeof(struct reg *));\n\t\t\t\t\t\tif (!local_list) {\n\t\t\t\t\t\t\tLOG_ERROR(\"realloc(%zu) failed\", combined_allocated * sizeof(struct reg *));\n\t\t\t\t\t\t\tfree(reg_list);\n\t\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlocal_list[local_list_size] = a;\n\t\t\t\t\tlocal_list_size++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfree(reg_list);\n\t}\n\n\tif (local_list_size == 0) {\n\t\tLOG_ERROR(\"Unable to get register list\");\n\t\tfree(local_list);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Now warn the user about any registers that weren't found in every target. */\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tif (!target_was_examined(head->target))\n\t\t\tcontinue;\n\n\t\tstruct reg **reg_list = NULL;\n\t\tint reg_list_size;\n\t\tint result = target_get_gdb_reg_list_noread(head->target, &reg_list,\n\t\t\t\t&reg_list_size, reg_class);\n\t\tif (result != ERROR_OK) {\n\t\t\tfree(local_list);\n\t\t\treturn result;\n\t\t}\n\t\tfor (unsigned int i = 0; i < local_list_size; i++) {\n\t\t\tbool found = false;\n\t\t\tstruct reg *a = local_list[i];\n\t\t\tfor (int j = 0; j < reg_list_size; j++) {\n\t\t\t\tstruct reg *b = reg_list[j];\n\t\t\t\tif (b->exist && !strcmp(a->name, b->name)) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found) {\n\t\t\t\tLOG_WARNING(\"Register %s does not exist in %s, which is part of an SMP group where \"\n\t\t\t\t\t    \"this register does exist.\",\n\t\t\t\t\t    a->name, target_name(head->target));\n\t\t\t}\n\t\t}\n\t\tfree(reg_list);\n\t}\n\n\t*combined_list = local_list;\n\t*combined_list_size = local_list_size;\n\treturn ERROR_OK;\n}\n\nstatic int gdb_generate_target_description(struct target *target, char **tdesc_out)\n{\n\tint retval = ERROR_OK;\n\tstruct reg **reg_list = NULL;\n\tint reg_list_size;\n\tchar const *architecture;\n\tchar const **features = NULL;\n\tint feature_list_size = 0;\n\tchar *tdesc = NULL;\n\tint pos = 0;\n\tint size = 0;\n\n\n\tretval = smp_reg_list_noread(target, &reg_list, &reg_list_size,\n\t\t\tREG_CLASS_ALL);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"get register list failed\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto error;\n\t}\n\n\tif (reg_list_size <= 0) {\n\t\tLOG_ERROR(\"get register list failed\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto error;\n\t}\n\n\t/* Get a list of available target registers features */\n\tretval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't get the registers feature list\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto error;\n\t}\n\n\t/* If we found some features associated with registers, create sections */\n\tint current_feature = 0;\n\n\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\"<?xml version=\\\"1.0\\\"?>\\n\"\n\t\t\t\"<!DOCTYPE target SYSTEM \\\"gdb-target.dtd\\\">\\n\"\n\t\t\t\"<target version=\\\"1.0\\\">\\n\");\n\n\t/* generate architecture element if supported by target */\n\tarchitecture = target_get_gdb_arch(target);\n\tif (architecture)\n\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\"<architecture>%s</architecture>\\n\", architecture);\n\n\t/* generate target description according to register list */\n\tif (features) {\n\t\twhile (features[current_feature]) {\n\t\t\tchar const **arch_defined_types = NULL;\n\t\t\tint num_arch_defined_types = 0;\n\n\t\t\tarch_defined_types = calloc(1, sizeof(char *));\n\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\"<feature name=\\\"%s\\\">\\n\",\n\t\t\t\t\tfeatures[current_feature]);\n\n\t\t\tint i;\n\t\t\tfor (i = 0; i < reg_list_size; i++) {\n\n\t\t\t\tif (reg_list[i]->exist == false || reg_list[i]->hidden)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tif (strcmp(reg_list[i]->feature->name, features[current_feature]))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tconst char *type_str;\n\t\t\t\tif (reg_list[i]->reg_data_type) {\n\t\t\t\t\tif (reg_list[i]->reg_data_type->type == REG_TYPE_ARCH_DEFINED) {\n\t\t\t\t\t\t/* generate <type... first, if there are architecture-defined types. */\n\t\t\t\t\t\tif (lookup_add_arch_defined_types(&arch_defined_types,\n\t\t\t\t\t\t\t\t\t\treg_list[i]->reg_data_type->id,\n\t\t\t\t\t\t\t\t\t\t&num_arch_defined_types))\n\t\t\t\t\t\t\tgdb_generate_reg_type_description(target, &tdesc, &pos, &size,\n\t\t\t\t\t\t\t\t\t\t\treg_list[i]->reg_data_type,\n\t\t\t\t\t\t\t\t\t\t\t&arch_defined_types,\n\t\t\t\t\t\t\t\t\t\t\t&num_arch_defined_types);\n\n\t\t\t\t\t\ttype_str = reg_list[i]->reg_data_type->id;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* predefined type */\n\t\t\t\t\t\ttype_str = gdb_get_reg_type_name(\n\t\t\t\t\t\t\t\treg_list[i]->reg_data_type->type);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* Default type is \"int\" */\n\t\t\t\t\ttype_str = \"int\";\n\t\t\t\t}\n\n\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\"<reg name=\\\"%s\\\"\", reg_list[i]->name);\n\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\" bitsize=\\\"%\" PRIu32 \"\\\"\", reg_list[i]->size);\n\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\" regnum=\\\"%\" PRIu32 \"\\\"\", reg_list[i]->number);\n\t\t\t\tif (reg_list[i]->caller_save)\n\t\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\t\" save-restore=\\\"yes\\\"\");\n\t\t\t\telse\n\t\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\t\" save-restore=\\\"no\\\"\");\n\n\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\" type=\\\"%s\\\"\", type_str);\n\n\t\t\t\tif (reg_list[i]->group)\n\t\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\t\" group=\\\"%s\\\"\", reg_list[i]->group);\n\n\t\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\t\"/>\\n\");\n\t\t\t}\n\n\t\t\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\t\t\"</feature>\\n\");\n\n\t\t\tcurrent_feature++;\n\t\t\tfree(arch_defined_types);\n\t\t}\n\t}\n\n\txml_printf(&retval, &tdesc, &pos, &size,\n\t\t\t\"</target>\\n\");\n\nerror:\n\tfree(features);\n\tfree(reg_list);\n\n\tif (retval == ERROR_OK)\n\t\t*tdesc_out = tdesc;\n\telse\n\t\tfree(tdesc);\n\n\treturn retval;\n}\n\nstatic int gdb_get_target_description_chunk(struct target *target, struct target_desc_format *target_desc,\n\t\tchar **chunk, int32_t offset, uint32_t length)\n{\n\tif (!target_desc) {\n\t\tLOG_ERROR(\"Unable to Generate Target Description\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchar *tdesc = target_desc->tdesc;\n\tuint32_t tdesc_length = target_desc->tdesc_length;\n\n\tif (!tdesc) {\n\t\tint retval = gdb_generate_target_description(target, &tdesc);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to Generate Target Description\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\ttdesc_length = strlen(tdesc);\n\t}\n\n\tchar transfer_type;\n\n\tif (length < (tdesc_length - offset))\n\t\ttransfer_type = 'm';\n\telse\n\t\ttransfer_type = 'l';\n\n\t*chunk = malloc(length + 2);\n\tif (!*chunk) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t(*chunk)[0] = transfer_type;\n\tif (transfer_type == 'm') {\n\t\tstrncpy((*chunk) + 1, tdesc + offset, length);\n\t\t(*chunk)[1 + length] = '\\0';\n\t} else {\n\t\tstrncpy((*chunk) + 1, tdesc + offset, tdesc_length - offset);\n\t\t(*chunk)[1 + (tdesc_length - offset)] = '\\0';\n\n\t\t/* After gdb-server sends out last chunk, invalidate tdesc. */\n\t\tfree(tdesc);\n\t\ttdesc = NULL;\n\t\ttdesc_length = 0;\n\t}\n\n\ttarget_desc->tdesc = tdesc;\n\ttarget_desc->tdesc_length = tdesc_length;\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_target_description_supported(struct target *target, int *supported)\n{\n\tint retval = ERROR_OK;\n\tstruct reg **reg_list = NULL;\n\tint reg_list_size = 0;\n\tchar const **features = NULL;\n\tint feature_list_size = 0;\n\n\tchar const *architecture = target_get_gdb_arch(target);\n\n\tretval = target_get_gdb_reg_list_noread(target, &reg_list,\n\t\t\t&reg_list_size, REG_CLASS_ALL);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"get register list failed\");\n\t\tgoto error;\n\t}\n\n\tif (reg_list_size <= 0) {\n\t\tLOG_ERROR(\"get register list failed\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto error;\n\t}\n\n\t/* Get a list of available target registers features */\n\tretval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't get the registers feature list\");\n\t\tgoto error;\n\t}\n\n\tif (supported) {\n\t\tif (architecture || feature_list_size)\n\t\t\t*supported = 1;\n\t\telse\n\t\t\t*supported = 0;\n\t}\n\nerror:\n\tfree(features);\n\n\tfree(reg_list);\n\n\treturn retval;\n}\n\nstatic int gdb_generate_thread_list(struct target *target, char **thread_list_out)\n{\n\tstruct rtos *rtos = target->rtos;\n\tint retval = ERROR_OK;\n\tchar *thread_list = NULL;\n\tint pos = 0;\n\tint size = 0;\n\n\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t   \"<?xml version=\\\"1.0\\\"?>\\n\"\n\t\t   \"<threads>\\n\");\n\n\tif (rtos) {\n\t\tfor (int i = 0; i < rtos->thread_count; i++) {\n\t\t\tstruct thread_detail *thread_detail = &rtos->thread_details[i];\n\n\t\t\tif (!thread_detail->exists)\n\t\t\t\tcontinue;\n\n\t\t\tif (thread_detail->thread_name_str)\n\t\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t\t   \"<thread id=\\\"%\" PRIx64 \"\\\" name=\\\"%s\\\">\",\n\t\t\t\t\t   thread_detail->threadid,\n\t\t\t\t\t   thread_detail->thread_name_str);\n\t\t\telse\n\t\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t\t   \"<thread id=\\\"%\" PRIx64 \"\\\">\", thread_detail->threadid);\n\n\t\t\tif (thread_detail->thread_name_str)\n\t\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t\t   \"Name: %s\", thread_detail->thread_name_str);\n\n\t\t\tif (thread_detail->extra_info_str) {\n\t\t\t\tif (thread_detail->thread_name_str)\n\t\t\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t\t\t   \", \");\n\t\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t\t   \"%s\", thread_detail->extra_info_str);\n\t\t\t}\n\n\t\t\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t\t\t   \"</thread>\\n\");\n\t\t}\n\t}\n\n\txml_printf(&retval, &thread_list, &pos, &size,\n\t\t   \"</threads>\\n\");\n\n\tif (retval == ERROR_OK)\n\t\t*thread_list_out = thread_list;\n\telse\n\t\tfree(thread_list);\n\n\treturn retval;\n}\n\nstatic int gdb_get_thread_list_chunk(struct target *target, char **thread_list,\n\t\tchar **chunk, int32_t offset, uint32_t length)\n{\n\tif (!*thread_list) {\n\t\tint retval = gdb_generate_thread_list(target, thread_list);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Unable to Generate Thread List\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tsize_t thread_list_length = strlen(*thread_list);\n\tchar transfer_type;\n\n\tlength = MIN(length, thread_list_length - offset);\n\tif (length < (thread_list_length - offset))\n\t\ttransfer_type = 'm';\n\telse\n\t\ttransfer_type = 'l';\n\n\t*chunk = malloc(length + 2 + 3);\n\t/* Allocating extra 3 bytes prevents false positive valgrind report\n\t * of strlen(chunk) word access:\n\t * Invalid read of size 4\n\t * Address 0x4479934 is 44 bytes inside a block of size 45 alloc'd */\n\tif (!*chunk) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t(*chunk)[0] = transfer_type;\n\tstrncpy((*chunk) + 1, (*thread_list) + offset, length);\n\t(*chunk)[1 + length] = '\\0';\n\n\t/* After gdb-server sends out last chunk, invalidate thread list. */\n\tif (transfer_type == 'l') {\n\t\tfree(*thread_list);\n\t\t*thread_list = NULL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_query_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct command_context *cmd_ctx = connection->cmd_ctx;\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\tstruct target *target = get_target_from_connection(connection);\n\n\tif (strncmp(packet, \"qRcmd,\", 6) == 0) {\n\t\tif (packet_size > 6) {\n\t\t\tJim_Interp *interp = cmd_ctx->interp;\n\t\t\tchar *cmd;\n\t\t\tcmd = malloc((packet_size - 6) / 2 + 1);\n\t\t\tsize_t len = unhexify((uint8_t *)cmd, packet + 6, (packet_size - 6) / 2);\n\t\t\tcmd[len] = 0;\n\n\t\t\t/* We want to print all debug output to GDB connection */\n\t\t\tgdb_connection->output_flag = GDB_OUTPUT_ALL;\n\t\t\ttarget_call_timer_callbacks_now();\n\t\t\t/* some commands need to know the GDB connection, make note of current\n\t\t\t * GDB connection. */\n\t\t\tcurrent_gdb_connection = gdb_connection;\n\n\t\t\tstruct target *saved_target_override = cmd_ctx->current_target_override;\n\t\t\tcmd_ctx->current_target_override = NULL;\n\n\t\t\tstruct command_context *old_context = Jim_GetAssocData(interp, \"context\");\n\t\t\tJim_DeleteAssocData(interp, \"context\");\n\t\t\tint retval = Jim_SetAssocData(interp, \"context\", NULL, cmd_ctx);\n\t\t\tif (retval == JIM_OK) {\n\t\t\t\tretval = Jim_EvalObj(interp, Jim_NewStringObj(interp, cmd, -1));\n\t\t\t\tJim_DeleteAssocData(interp, \"context\");\n\t\t\t}\n\t\t\tint inner_retval = Jim_SetAssocData(interp, \"context\", NULL, old_context);\n\t\t\tif (retval == JIM_OK)\n\t\t\t\tretval = inner_retval;\n\n\t\t\tcmd_ctx->current_target_override = saved_target_override;\n\n\t\t\tcurrent_gdb_connection = NULL;\n\t\t\ttarget_call_timer_callbacks_now();\n\t\t\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\t\t\tfree(cmd);\n\t\t\tif (retval == JIM_RETURN)\n\t\t\t\tretval = interp->returnCode;\n\t\t\tint lenmsg;\n\t\t\tconst char *cretmsg = Jim_GetString(Jim_GetResult(interp), &lenmsg);\n\t\t\tchar *retmsg;\n\t\t\tif (lenmsg && cretmsg[lenmsg - 1] != '\\n') {\n\t\t\t\tretmsg = alloc_printf(\"%s\\n\", cretmsg);\n\t\t\t\tlenmsg++;\n\t\t\t} else {\n\t\t\t\tretmsg = strdup(cretmsg);\n\t\t\t}\n\t\t\tif (!retmsg)\n\t\t\t\treturn ERROR_GDB_BUFFER_TOO_SMALL;\n\n\t\t\tif (retval == JIM_OK) {\n\t\t\t\tif (lenmsg) {\n\t\t\t\t\tchar *hex_buffer = malloc(lenmsg * 2 + 1);\n\t\t\t\t\tif (!hex_buffer) {\n\t\t\t\t\t\tfree(retmsg);\n\t\t\t\t\t\treturn ERROR_GDB_BUFFER_TOO_SMALL;\n\t\t\t\t\t}\n\n\t\t\t\t\tsize_t pkt_len = hexify(hex_buffer, (const uint8_t *)retmsg, lenmsg,\n\t\t\t\t\t\t\t\t\t\t\tlenmsg * 2 + 1);\n\t\t\t\t\tgdb_put_packet(connection, hex_buffer, pkt_len);\n\t\t\t\t\tfree(hex_buffer);\n\t\t\t\t} else {\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (lenmsg)\n\t\t\t\t\tgdb_output_con(connection, retmsg);\n\t\t\t\tgdb_send_error(connection, retval);\n\t\t\t}\n\t\t\tfree(retmsg);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qCRC:\", 5) == 0) {\n\t\tif (packet_size > 5) {\n\t\t\tint retval;\n\t\t\tchar gdb_reply[10];\n\t\t\tchar *separator;\n\t\t\tuint32_t checksum;\n\t\t\ttarget_addr_t addr = 0;\n\t\t\tuint32_t len = 0;\n\n\t\t\t/* skip command character */\n\t\t\tpacket += 5;\n\n\t\t\taddr = strtoull(packet, &separator, 16);\n\n\t\t\tif (*separator != ',') {\n\t\t\t\tLOG_ERROR(\"incomplete read memory packet received, dropping connection\");\n\t\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t\t}\n\n\t\t\tlen = strtoul(separator + 1, NULL, 16);\n\n\t\t\tretval = target_checksum_memory(target, addr, len, &checksum);\n\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tsnprintf(gdb_reply, 10, \"C%8.8\" PRIx32 \"\", checksum);\n\t\t\t\tgdb_put_packet(connection, gdb_reply, 9);\n\t\t\t} else {\n\t\t\t\tretval = gdb_error(connection, retval);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else if (strncmp(packet, \"qSupported\", 10) == 0) {\n\t\t/* we currently support packet size and qXfer:memory-map:read (if enabled)\n\t\t * qXfer:features:read is supported for some targets */\n\t\tint retval = ERROR_OK;\n\t\tchar *buffer = NULL;\n\t\tint pos = 0;\n\t\tint size = 0;\n\t\tint gdb_target_desc_supported = 0;\n\n\t\t/* we need to test that the target supports target descriptions */\n\t\tretval = gdb_target_description_supported(target, &gdb_target_desc_supported);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_INFO(\"Failed detecting Target Description Support, disabling\");\n\t\t\tgdb_target_desc_supported = 0;\n\t\t}\n\n\t\t/* support may be disabled globally */\n\t\tif (gdb_use_target_description == 0) {\n\t\t\tif (gdb_target_desc_supported)\n\t\t\t\tLOG_WARNING(\"Target Descriptions Supported, but disabled\");\n\t\t\tgdb_target_desc_supported = 0;\n\t\t}\n\n\t\txml_printf(&retval,\n\t\t\t&buffer,\n\t\t\t&pos,\n\t\t\t&size,\n\t\t\t\"PacketSize=%x;qXfer:memory-map:read%c;qXfer:features:read%c;qXfer:threads:read+;QStartNoAckMode+;vContSupported+\",\n\t\t\tGDB_BUFFER_SIZE,\n\t\t\t((gdb_use_memory_map == 1) && (flash_get_bank_count() > 0)) ? '+' : '-',\n\t\t\t(gdb_target_desc_supported == 1) ? '+' : '-');\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tgdb_send_error(connection, 01);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tgdb_put_packet(connection, buffer, strlen(buffer));\n\t\tfree(buffer);\n\n\t\treturn ERROR_OK;\n\t} else if ((strncmp(packet, \"qXfer:memory-map:read::\", 23) == 0)\n\t\t   && (flash_get_bank_count() > 0))\n\t\treturn gdb_memory_map(connection, packet, packet_size);\n\telse if (strncmp(packet, \"qXfer:features:read:\", 20) == 0) {\n\t\tchar *xml = NULL;\n\t\tint retval = ERROR_OK;\n\n\t\tint offset;\n\t\tunsigned int length;\n\n\t\t/* skip command character */\n\t\tpacket += 20;\n\n\t\tif (decode_xfer_read(packet, NULL, &offset, &length) < 0) {\n\t\t\tgdb_send_error(connection, 01);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Target should prepare correct target description for annex.\n\t\t * The first character of returned xml is 'm' or 'l'. 'm' for\n\t\t * there are *more* chunks to transfer. 'l' for it is the *last*\n\t\t * chunk of target description.\n\t\t */\n\t\tretval = gdb_get_target_description_chunk(target, &gdb_connection->target_desc,\n\t\t\t\t&xml, offset, length);\n\t\tif (retval != ERROR_OK) {\n\t\t\tgdb_error(connection, retval);\n\t\t\treturn retval;\n\t\t}\n\n\t\tgdb_put_packet(connection, xml, strlen(xml));\n\n\t\tfree(xml);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"qXfer:threads:read:\", 19) == 0) {\n\t\tchar *xml = NULL;\n\t\tint retval = ERROR_OK;\n\n\t\tint offset;\n\t\tunsigned int length;\n\n\t\t/* skip command character */\n\t\tpacket += 19;\n\n\t\tif (decode_xfer_read(packet, NULL, &offset, &length) < 0) {\n\t\t\tgdb_send_error(connection, 01);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Target should prepare correct thread list for annex.\n\t\t * The first character of returned xml is 'm' or 'l'. 'm' for\n\t\t * there are *more* chunks to transfer. 'l' for it is the *last*\n\t\t * chunk of target description.\n\t\t */\n\t\tretval = gdb_get_thread_list_chunk(target, &gdb_connection->thread_list,\n\t\t\t\t\t\t   &xml, offset, length);\n\t\tif (retval != ERROR_OK) {\n\t\t\tgdb_error(connection, retval);\n\t\t\treturn retval;\n\t\t}\n\n\t\tgdb_put_packet(connection, xml, strlen(xml));\n\n\t\tfree(xml);\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"QStartNoAckMode\", 15) == 0) {\n\t\tgdb_connection->noack_mode = 1;\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\treturn ERROR_OK;\n\t} else if (target->type->gdb_query_custom) {\n\t\tchar *buffer = NULL;\n\t\tint ret = target->type->gdb_query_custom(target, packet, &buffer);\n\t\tgdb_put_packet(connection, buffer, strlen(buffer));\n\t\treturn ret;\n\t}\n\n\tgdb_put_packet(connection, \"\", 0);\n\treturn ERROR_OK;\n}\n\nstatic bool gdb_handle_vcont_packet(struct connection *connection, const char *packet,\n\t__attribute__((unused)) int packet_size)\n{\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\tstruct target *target = get_target_from_connection(connection);\n\tconst char *parse = packet;\n\tint retval;\n\n\t/* query for vCont supported */\n\tif (parse[0] == '?') {\n\t\tif (target->type->step) {\n\t\t\t/* gdb doesn't accept c without C and s without S */\n\t\t\tgdb_put_packet(connection, \"vCont;c;C;s;S\", 13);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tif (parse[0] == ';') {\n\t\t++parse;\n\t}\n\n\t/* simple case, a continue packet */\n\tif (parse[0] == 'c') {\n\t\tgdb_running_type = 'c';\n\t\tLOG_DEBUG(\"target %s continue\", target_name(target));\n\t\tgdb_connection->output_flag = GDB_OUTPUT_ALL;\n\t\tretval = target_resume(target, 1, 0, 0, 0);\n\t\tif (retval == ERROR_TARGET_NOT_HALTED)\n\t\t\tLOG_INFO(\"target %s was not halted when resume was requested\", target_name(target));\n\n\t\t/* poll target in an attempt to make its internal state consistent */\n\t\tif (retval != ERROR_OK) {\n\t\t\tretval = target_poll(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_DEBUG(\"error polling target %s after failed resume\", target_name(target));\n\t\t}\n\n\t\t/*\n\t\t * We don't report errors to gdb here, move frontend_state to\n\t\t * TARGET_RUNNING to stay in sync with gdb's expectation of the\n\t\t * target state\n\t\t */\n\t\tgdb_connection->frontend_state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_START);\n\n\t\treturn true;\n\t}\n\n\t/* single-step or step-over-breakpoint */\n\tif (parse[0] == 's') {\n\t\tgdb_running_type = 's';\n\t\tbool fake_step = false;\n\n\t\tstruct target *ct = target;\n\t\tint current_pc = 1;\n\t\tint64_t thread_id;\n\t\tparse++;\n\t\tif (parse[0] == ':') {\n\t\t\tchar *endp;\n\t\t\tparse++;\n\t\t\tthread_id = strtoll(parse, &endp, 16);\n\t\t\tif (endp) {\n\t\t\t\tparse = endp;\n\t\t\t}\n\t\t} else {\n\t\t\tthread_id = 0;\n\t\t}\n\n\t\tif (target->rtos) {\n\t\t\t/* FIXME: why is this necessary? rtos state should be up-to-date here already! */\n\t\t\trtos_update_threads(target);\n\n\t\t\ttarget->rtos->gdb_target_for_threadid(connection, thread_id, &ct);\n\n\t\t\t/*\n\t\t\t * check if the thread to be stepped is the current rtos thread\n\t\t\t * if not, we must fake the step\n\t\t\t */\n\t\t\tif (target->rtos->current_thread != thread_id)\n\t\t\t\tfake_step = true;\n\t\t}\n\n\t\tif (parse[0] == ';') {\n\t\t\t++parse;\n\n\t\t\tif (parse[0] == 'c') {\n\t\t\t\tparse += 1;\n\n\t\t\t\t/* check if thread-id follows */\n\t\t\t\tif (parse[0] == ':') {\n\t\t\t\t\tint64_t tid;\n\t\t\t\t\tparse += 1;\n\n\t\t\t\t\ttid = strtoll(parse, NULL, 16);\n\t\t\t\t\tif (tid == thread_id) {\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * Special case: only step a single thread (core),\n\t\t\t\t\t\t * keep the other threads halted. Currently, only\n\t\t\t\t\t\t * aarch64 target understands it. Other target types don't\n\t\t\t\t\t\t * care (nobody checks the actual value of 'current')\n\t\t\t\t\t\t * and it doesn't really matter. This deserves\n\t\t\t\t\t\t * a symbolic constant and a formal interface documentation\n\t\t\t\t\t\t * at a later time.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tLOG_DEBUG(\"request to step current core only\");\n\t\t\t\t\t\t/* uncomment after checking that indeed other targets are safe */\n\t\t\t\t\t\t/*current_pc = 2;*/\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tLOG_DEBUG(\"target %s single-step thread %\"PRIx64, target_name(ct), thread_id);\n\t\tgdb_connection->output_flag = GDB_OUTPUT_ALL;\n\t\ttarget_call_event_callbacks(ct, TARGET_EVENT_GDB_START);\n\n\t\t/*\n\t\t * work around an annoying gdb behaviour: when the current thread\n\t\t * is changed in gdb, it assumes that the target can follow and also\n\t\t * make the thread current. This is an assumption that cannot hold\n\t\t * for a real target running a multi-threading OS. We just fake\n\t\t * the step to not trigger an internal error in gdb. See\n\t\t * https://sourceware.org/bugzilla/show_bug.cgi?id=22925 for details\n\t\t */\n\t\tif (fake_step) {\n\t\t\tint sig_reply_len;\n\t\t\tchar sig_reply[128];\n\n\t\t\tLOG_DEBUG(\"fake step thread %\"PRIx64, thread_id);\n\n\t\t\tsig_reply_len = snprintf(sig_reply, sizeof(sig_reply),\n\t\t\t\t\t\t\t\t\t\"T05thread:%016\"PRIx64\";\", thread_id);\n\n\t\t\tgdb_put_packet(connection, sig_reply, sig_reply_len);\n\t\t\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\n\t\t\treturn true;\n\t\t}\n\n\t\t/* support for gdb_sync command */\n\t\tif (gdb_connection->sync) {\n\t\t\tgdb_connection->sync = false;\n\t\t\tif (ct->state == TARGET_HALTED) {\n\t\t\t\tLOG_DEBUG(\"stepi ignored. GDB will now fetch the register state \"\n\t\t\t\t\t\t\t\t\"from the target.\");\n\t\t\t\tgdb_sig_halted(connection);\n\t\t\t\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\t\t\t} else\n\t\t\t\tgdb_connection->frontend_state = TARGET_RUNNING;\n\t\t\treturn true;\n\t\t}\n\n\t\tretval = target_step(ct, current_pc, 0, 0);\n\t\tif (retval == ERROR_TARGET_NOT_HALTED)\n\t\t\tLOG_INFO(\"target %s was not halted when step was requested\", target_name(ct));\n\n\t\t/* if step was successful send a reply back to gdb */\n\t\tif (retval == ERROR_OK) {\n\t\t\tretval = target_poll(ct);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_DEBUG(\"error polling target %s after successful step\", target_name(ct));\n\t\t\t/* send back signal information */\n\t\t\tgdb_signal_reply(ct, connection);\n\t\t\t/* stop forwarding log packets! */\n\t\t\tgdb_connection->output_flag = GDB_OUTPUT_NO;\n\t\t} else\n\t\t\tgdb_connection->frontend_state = TARGET_RUNNING;\n\t\treturn true;\n\t}\n\tLOG_ERROR(\"Unknown vCont packet\");\n\treturn false;\n}\n\nstatic char *next_hex_encoded_field(const char **str, char sep)\n{\n\tsize_t hexlen;\n\tconst char *hex = *str;\n\tif (hex[0] == '\\0')\n\t\treturn NULL;\n\n\tconst char *end = strchr(hex, sep);\n\tif (!end)\n\t\thexlen = strlen(hex);\n\telse\n\t\thexlen = end - hex;\n\t*str = hex + hexlen + 1;\n\n\tif (hexlen % 2 != 0) {\n\t\t/* Malformed hex data */\n\t\treturn NULL;\n\t}\n\n\tsize_t count = hexlen / 2;\n\tchar *decoded = malloc(count + 1);\n\tif (!decoded)\n\t\treturn NULL;\n\n\tsize_t converted = unhexify((void *)decoded, hex, count);\n\tif (converted != count) {\n\t\tfree(decoded);\n\t\treturn NULL;\n\t}\n\n\tdecoded[count] = '\\0';\n\treturn decoded;\n}\n\n/* handle extended restart packet */\nstatic void gdb_restart_inferior(struct connection *connection, const char *packet, int packet_size)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tstruct target *target = get_target_from_connection(connection);\n\n\tbreakpoint_clear_target(target);\n\twatchpoint_clear_target(target);\n\tcommand_run_linef(connection->cmd_ctx, \"ocd_gdb_restart %s\",\n\t\t\ttarget_name(target));\n\t/* set connection as attached after reset */\n\tgdb_con->attached = true;\n\t/*  info rtos parts */\n\tgdb_thread_packet(connection, packet, packet_size);\n}\n\nstatic bool gdb_handle_vrun_packet(struct connection *connection, const char *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tconst char *parse = packet;\n\n\t/* Skip \"vRun\" */\n\tparse += 4;\n\n\tif (parse[0] != ';')\n\t\treturn false;\n\tparse++;\n\n\t/* Skip first field \"filename\"; don't know what to do with it. */\n\tfree(next_hex_encoded_field(&parse, ';'));\n\n\tchar *cmdline = next_hex_encoded_field(&parse, ';');\n\twhile (cmdline) {\n\t\tchar *arg = next_hex_encoded_field(&parse, ';');\n\t\tif (!arg)\n\t\t\tbreak;\n\t\tchar *new_cmdline = alloc_printf(\"%s %s\", cmdline, arg);\n\t\tfree(cmdline);\n\t\tfree(arg);\n\t\tcmdline = new_cmdline;\n\t}\n\n\tif (cmdline) {\n\t\tif (target->semihosting) {\n\t\t\tLOG_INFO(\"GDB set inferior command line to '%s'\", cmdline);\n\t\t\tfree(target->semihosting->cmdline);\n\t\t\ttarget->semihosting->cmdline = cmdline;\n\t\t} else {\n\t\t\tLOG_INFO(\"GDB set inferior command line to '%s' but semihosting is unavailable\", cmdline);\n\t\t\tfree(cmdline);\n\t\t}\n\t}\n\n\tgdb_restart_inferior(connection, packet, packet_size);\n\tgdb_put_packet(connection, \"S00\", 3);\n\treturn true;\n}\n\nstatic int gdb_v_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct gdb_connection *gdb_connection = connection->priv;\n\tint result;\n\n\tstruct target *target = get_target_from_connection(connection);\n\n\tif (strncmp(packet, \"vCont\", 5) == 0) {\n\t\tbool handled;\n\n\t\tpacket += 5;\n\t\tpacket_size -= 5;\n\n\t\thandled = gdb_handle_vcont_packet(connection, packet, packet_size);\n\t\tif (!handled)\n\t\t\tgdb_put_packet(connection, \"\", 0);\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (strncmp(packet, \"vRun\", 4) == 0) {\n\t\tbool handled;\n\n\t\thandled = gdb_handle_vrun_packet(connection, packet, packet_size);\n\t\tif (!handled)\n\t\t\tgdb_put_packet(connection, \"\", 0);\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* if flash programming disabled - send a empty reply */\n\n\tif (gdb_flash_program == 0) {\n\t\tgdb_put_packet(connection, \"\", 0);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (strncmp(packet, \"vFlashErase:\", 12) == 0) {\n\t\tunsigned long addr;\n\t\tunsigned long length;\n\n\t\tchar const *parse = packet + 12;\n\t\tif (*parse == '\\0') {\n\t\t\tLOG_ERROR(\"incomplete vFlashErase packet received, dropping connection\");\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\n\t\taddr = strtoul(parse, (char **)&parse, 16);\n\n\t\tif (*(parse++) != ',' || *parse == '\\0') {\n\t\t\tLOG_ERROR(\"incomplete vFlashErase packet received, dropping connection\");\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\n\t\tlength = strtoul(parse, (char **)&parse, 16);\n\n\t\tif (*parse != '\\0') {\n\t\t\tLOG_ERROR(\"incomplete vFlashErase packet received, dropping connection\");\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\n\t\t/* assume all sectors need erasing - stops any problems\n\t\t * when flash_write is called multiple times */\n\t\tflash_set_dirty();\n\n\t\t/* perform any target specific operations before the erase */\n\t\ttarget_call_event_callbacks(target,\n\t\t\tTARGET_EVENT_GDB_FLASH_ERASE_START);\n\n\t\t/* vFlashErase:addr,length messages require region start and\n\t\t * end to be \"block\" aligned ... if padding is ever needed,\n\t\t * GDB will have become dangerously confused.\n\t\t */\n\t\tresult = flash_erase_address_range(target, false, addr,\n\t\t\tlength);\n\n\t\t/* perform any target specific operations after the erase */\n\t\ttarget_call_event_callbacks(target,\n\t\t\tTARGET_EVENT_GDB_FLASH_ERASE_END);\n\n\t\t/* perform erase */\n\t\tif (result != ERROR_OK) {\n\t\t\t/* GDB doesn't evaluate the actual error number returned,\n\t\t\t * treat a failed erase as an I/O error\n\t\t\t */\n\t\t\tgdb_send_error(connection, EIO);\n\t\t\tLOG_ERROR(\"flash_erase returned %i\", result);\n\t\t} else\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (strncmp(packet, \"vFlashWrite:\", 12) == 0) {\n\t\tint retval;\n\t\tunsigned long addr;\n\t\tunsigned long length;\n\t\tchar const *parse = packet + 12;\n\n\t\tif (*parse == '\\0') {\n\t\t\tLOG_ERROR(\"incomplete vFlashErase packet received, dropping connection\");\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\t\taddr = strtoul(parse, (char **)&parse, 16);\n\t\tif (*(parse++) != ':') {\n\t\t\tLOG_ERROR(\"incomplete vFlashErase packet received, dropping connection\");\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\t\tlength = packet_size - (parse - packet);\n\n\t\t/* create a new image if there isn't already one */\n\t\tif (!gdb_connection->vflash_image) {\n\t\t\tgdb_connection->vflash_image = malloc(sizeof(struct image));\n\t\t\timage_open(gdb_connection->vflash_image, \"\", \"build\");\n\t\t}\n\n\t\t/* create new section with content from packet buffer */\n\t\tretval = image_add_section(gdb_connection->vflash_image,\n\t\t\t\taddr, length, 0x0, (uint8_t const *)parse);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tgdb_put_packet(connection, \"OK\", 2);\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (strncmp(packet, \"vFlashDone\", 10) == 0) {\n\t\tuint32_t written;\n\n\t\t/* process the flashing buffer. No need to erase as GDB\n\t\t * always issues a vFlashErase first. */\n\t\ttarget_call_event_callbacks(target,\n\t\t\t\tTARGET_EVENT_GDB_FLASH_WRITE_START);\n\t\tresult = flash_write(target, gdb_connection->vflash_image,\n\t\t\t&written, false);\n\t\ttarget_call_event_callbacks(target,\n\t\t\tTARGET_EVENT_GDB_FLASH_WRITE_END);\n\t\tif (result != ERROR_OK) {\n\t\t\tif (result == ERROR_FLASH_DST_OUT_OF_BANK)\n\t\t\t\tgdb_put_packet(connection, \"E.memtype\", 9);\n\t\t\telse\n\t\t\t\tgdb_send_error(connection, EIO);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"wrote %u bytes from vFlash image to flash\", (unsigned)written);\n\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t}\n\n\t\timage_close(gdb_connection->vflash_image);\n\t\tfree(gdb_connection->vflash_image);\n\t\tgdb_connection->vflash_image = NULL;\n\n\t\treturn ERROR_OK;\n\t}\n\n\tgdb_put_packet(connection, \"\", 0);\n\treturn ERROR_OK;\n}\n\nstatic int gdb_detach(struct connection *connection)\n{\n\t/*\n\t * Only reply \"OK\" to GDB\n\t * it will close the connection and this will trigger a call to\n\t * gdb_connection_closed() that will in turn trigger the event\n\t * TARGET_EVENT_GDB_DETACH\n\t */\n\treturn gdb_put_packet(connection, \"OK\", 2);\n}\n\n/* The format of 'F' response packet is\n * Fretcode,errno,Ctrl-C flag;call-specific attachment\n */\nstatic int gdb_fileio_response_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tchar *parsing_point;\n\tint fileio_retcode = strtoul(packet + 1, &separator, 16);\n\tint fileio_errno = 0;\n\tbool fileio_ctrl_c = false;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (*separator == ',') {\n\t\tparsing_point = separator + 1;\n\t\tfileio_errno = strtoul(parsing_point, &separator, 16);\n\t\tif (*separator == ',') {\n\t\t\tif (*(separator + 1) == 'C') {\n\t\t\t\t/* TODO: process ctrl-c */\n\t\t\t\tfileio_ctrl_c = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"File-I/O response, retcode: 0x%x, errno: 0x%x, ctrl-c: %s\",\n\t\t\tfileio_retcode, fileio_errno, fileio_ctrl_c ? \"true\" : \"false\");\n\n\tretval = target_gdb_fileio_end(target, fileio_retcode, fileio_errno, fileio_ctrl_c);\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* After File-I/O ends, keep continue or step */\n\tif (gdb_running_type == 'c')\n\t\tretval = target_resume(target, 1, 0x0, 0, 0);\n\telse if (gdb_running_type == 's')\n\t\tretval = target_step(target, 1, 0x0, 0);\n\telse\n\t\tretval = ERROR_FAIL;\n\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic void gdb_log_callback(void *priv, const char *file, unsigned line,\n\t\tconst char *function, const char *string)\n{\n\tstruct connection *connection = priv;\n\tstruct gdb_connection *gdb_con = connection->priv;\n\n\tif (gdb_con->output_flag == GDB_OUTPUT_NO)\n\t\t/* No out allowed */\n\t\treturn;\n\n\tif (gdb_con->busy) {\n\t\t/* do not reply this using the O packet */\n\t\treturn;\n\t}\n\n\tgdb_output_con(connection, string);\n}\n\nstatic void gdb_sig_halted(struct connection *connection)\n{\n\tchar sig_reply[4];\n\tsnprintf(sig_reply, 4, \"T%2.2x\", 2);\n\tgdb_put_packet(connection, sig_reply, 3);\n}\n\nstatic int gdb_input_inner(struct connection *connection)\n{\n\t/* Do not allocate this on the stack */\n\tstatic char gdb_packet_buffer[GDB_BUFFER_SIZE + 1]; /* Extra byte for null-termination */\n\n\tstruct target *target;\n\tchar const *packet = gdb_packet_buffer;\n\tint packet_size;\n\tint retval;\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tstatic bool warn_use_ext;\n\n\ttarget = get_target_from_connection(connection);\n\n\t/* drain input buffer. If one of the packets fail, then an error\n\t * packet is replied, if applicable.\n\t *\n\t * This loop will terminate and the error code is returned.\n\t *\n\t * The calling fn will check if this error is something that\n\t * can be recovered from, or if the connection must be closed.\n\t *\n\t * If the error is recoverable, this fn is called again to\n\t * drain the rest of the buffer.\n\t */\n\tdo {\n\t\tpacket_size = GDB_BUFFER_SIZE;\n\t\tretval = gdb_get_packet(connection, gdb_packet_buffer, &packet_size);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* terminate with zero */\n\t\tgdb_packet_buffer[packet_size] = '\\0';\n\n\t\tif (packet_size > 0) {\n\n\t\t\tgdb_log_incoming_packet(connection, gdb_packet_buffer);\n\n\t\t\tretval = ERROR_OK;\n\t\t\tswitch (packet[0]) {\n\t\t\t\tcase 'T':\t/* Is thread alive? */\n\t\t\t\t\tgdb_thread_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'H':\t/* Set current thread ( 'c' for step and continue,\n\t\t\t\t\t\t\t * 'g' for all other operations ) */\n\t\t\t\t\tgdb_thread_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'q':\n\t\t\t\tcase 'Q':\n\t\t\t\t\tretval = gdb_thread_packet(connection, packet, packet_size);\n\t\t\t\t\tif (retval == GDB_THREAD_PACKET_NOT_CONSUMED)\n\t\t\t\t\t\tretval = gdb_query_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'g':\n\t\t\t\t\tretval = gdb_get_registers_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'G':\n\t\t\t\t\tretval = gdb_set_registers_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'p':\n\t\t\t\t\tretval = gdb_get_register_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'P':\n\t\t\t\t\tretval = gdb_set_register_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'm':\n\t\t\t\t\tretval = gdb_read_memory_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'M':\n\t\t\t\t\tretval = gdb_write_memory_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'z':\n\t\t\t\tcase 'Z':\n\t\t\t\t\tretval = gdb_breakpoint_watchpoint_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase '?':\n\t\t\t\t\tgdb_last_signal_packet(connection, packet, packet_size);\n\t\t\t\t\t/* '?' is sent after the eventual '!' */\n\t\t\t\t\tif (!warn_use_ext && !gdb_con->extended_protocol) {\n\t\t\t\t\t\twarn_use_ext = true;\n\t\t\t\t\t\tLOG_WARNING(\"Prefer GDB command \\\"target extended-remote :%s\\\" instead of \\\"target remote :%s\\\"\",\n\t\t\t\t\t\t\t\t\tconnection->service->port, connection->service->port);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'c':\n\t\t\t\tcase 's':\n\t\t\t\t{\n\t\t\t\t\tgdb_thread_packet(connection, packet, packet_size);\n\t\t\t\t\tgdb_con->output_flag = GDB_OUTPUT_ALL;\n\n\t\t\t\t\tif (gdb_con->mem_write_error) {\n\t\t\t\t\t\tLOG_ERROR(\"Memory write failure!\");\n\n\t\t\t\t\t\t/* now that we have reported the memory write error,\n\t\t\t\t\t\t * we can clear the condition */\n\t\t\t\t\t\tgdb_con->mem_write_error = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tbool nostep = false;\n\t\t\t\t\tbool already_running = false;\n\t\t\t\t\tif (target->state == TARGET_RUNNING) {\n\t\t\t\t\t\tLOG_WARNING(\"WARNING! The target is already running. \"\n\t\t\t\t\t\t\t\t\"All changes GDB did to registers will be discarded! \"\n\t\t\t\t\t\t\t\t\"Waiting for target to halt.\");\n\t\t\t\t\t\talready_running = true;\n\t\t\t\t\t} else if (target->state != TARGET_HALTED) {\n\t\t\t\t\t\tLOG_WARNING(\"The target is not in the halted nor running stated, \"\n\t\t\t\t\t\t\t\t\"stepi/continue ignored.\");\n\t\t\t\t\t\tnostep = true;\n\t\t\t\t\t} else if ((packet[0] == 's') && gdb_con->sync) {\n\t\t\t\t\t\t/* Hmm..... when you issue a continue in GDB, then a \"stepi\" is\n\t\t\t\t\t\t * sent by GDB first to OpenOCD, thus defeating the check to\n\t\t\t\t\t\t * make only the single stepping have the sync feature...\n\t\t\t\t\t\t */\n\t\t\t\t\t\tnostep = true;\n\t\t\t\t\t\tLOG_DEBUG(\"stepi ignored. GDB will now fetch the register state \"\n\t\t\t\t\t\t\t\t\"from the target.\");\n\t\t\t\t\t}\n\t\t\t\t\tgdb_con->sync = false;\n\n\t\t\t\t\tif (!already_running && nostep) {\n\t\t\t\t\t\t/* Either the target isn't in the halted state, then we can't\n\t\t\t\t\t\t * step/continue. This might be early setup, etc.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * Or we want to allow GDB to pick up a fresh set of\n\t\t\t\t\t\t * register values without modifying the target state.\n\t\t\t\t\t\t *\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgdb_sig_halted(connection);\n\n\t\t\t\t\t\t/* stop forwarding log packets! */\n\t\t\t\t\t\tgdb_con->output_flag = GDB_OUTPUT_NO;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* We're running/stepping, in which case we can\n\t\t\t\t\t\t * forward log output until the target is halted\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgdb_con->frontend_state = TARGET_RUNNING;\n\t\t\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_START);\n\n\t\t\t\t\t\tif (!already_running) {\n\t\t\t\t\t\t\t/* Here we don't want packet processing to stop even if this fails,\n\t\t\t\t\t\t\t * so we use a local variable instead of retval. */\n\t\t\t\t\t\t\tretval = gdb_step_continue_packet(connection, packet, packet_size);\n\t\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\t\t/* we'll never receive a halted\n\t\t\t\t\t\t\t\t * condition... issue a false one..\n\t\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\t\tgdb_frontend_halted(target, connection);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\tcase 'v':\n\t\t\t\t\tretval = gdb_v_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'D':\n\t\t\t\t\tretval = gdb_detach(connection);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'X':\n\t\t\t\t\tretval = gdb_write_memory_binary_packet(connection, packet, packet_size);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'k':\n\t\t\t\t\tif (gdb_con->extended_protocol) {\n\t\t\t\t\t\tgdb_con->attached = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t\t\tcase '!':\n\t\t\t\t\t/* handle extended remote protocol */\n\t\t\t\t\tgdb_con->extended_protocol = true;\n\t\t\t\t\tgdb_put_packet(connection, \"OK\", 2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'R':\n\t\t\t\t\t/* handle extended restart packet */\n\t\t\t\t\tgdb_restart_inferior(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'j':\n\t\t\t\t\t/* DEPRECATED */\n\t\t\t\t\t/* packet supported only by smp target i.e cortex_a.c*/\n\t\t\t\t\t/* handle smp packet replying coreid played to gbd */\n\t\t\t\t\tgdb_read_smp_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'J':\n\t\t\t\t\t/* DEPRECATED */\n\t\t\t\t\t/* packet supported only by smp target i.e cortex_a.c */\n\t\t\t\t\t/* handle smp packet setting coreid to be played at next\n\t\t\t\t\t * resume to gdb */\n\t\t\t\t\tgdb_write_smp_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 'F':\n\t\t\t\t\t/* File-I/O extension */\n\t\t\t\t\t/* After gdb uses host-side syscall to complete target file\n\t\t\t\t\t * I/O, gdb sends host-side syscall return value to target\n\t\t\t\t\t * by 'F' packet.\n\t\t\t\t\t * The format of 'F' response packet is\n\t\t\t\t\t * Fretcode,errno,Ctrl-C flag;call-specific attachment\n\t\t\t\t\t */\n\t\t\t\t\tgdb_con->frontend_state = TARGET_RUNNING;\n\t\t\t\t\tgdb_con->output_flag = GDB_OUTPUT_ALL;\n\t\t\t\t\tgdb_fileio_response_packet(connection, packet, packet_size);\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:\n\t\t\t\t\t/* ignore unknown packets */\n\t\t\t\t\tLOG_DEBUG(\"ignoring 0x%2.2x packet\", packet[0]);\n\t\t\t\t\tgdb_put_packet(connection, \"\", 0);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* if a packet handler returned an error, exit input loop */\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tif (gdb_con->ctrl_c) {\n\t\t\tif (target->state == TARGET_RUNNING) {\n\t\t\t\tstruct target *t = target;\n\t\t\t\tif (target->rtos)\n\t\t\t\t\ttarget->rtos->gdb_target_for_threadid(connection, target->rtos->current_threadid, &t);\n\t\t\t\tretval = target_halt(t);\n\t\t\t\tif (retval == ERROR_OK)\n\t\t\t\t\tretval = target_poll(t);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n\t\t\t\tgdb_con->ctrl_c = false;\n\t\t\t} else {\n\t\t\t\tLOG_INFO(\"The target is not running when halt was requested, stopping GDB.\");\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n\t\t\t}\n\t\t}\n\n\t} while (gdb_con->buf_cnt > 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int gdb_input(struct connection *connection)\n{\n\tint retval = gdb_input_inner(connection);\n\tstruct gdb_connection *gdb_con = connection->priv;\n\tif (retval == ERROR_SERVER_REMOTE_CLOSED)\n\t\treturn retval;\n\n\t/* logging does not propagate the error, yet can set the gdb_con->closed flag */\n\tif (gdb_con->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\t/* we'll recover from any other errors(e.g. temporary timeouts, etc.) */\n\treturn ERROR_OK;\n}\n\nstatic void gdb_keep_client_alive(struct connection *connection)\n{\n\tstruct gdb_connection *gdb_con = connection->priv;\n\n\tif (gdb_con->busy) {\n\t\t/* do not send packets, retry asap */\n\t\treturn;\n\t}\n\n\tswitch (gdb_con->output_flag) {\n\tcase GDB_OUTPUT_NO:\n\t\t/* no need for keep-alive */\n\t\tbreak;\n\tcase GDB_OUTPUT_ALL:\n\t\t/* send an empty O packet */\n\t\tgdb_output_con(connection, \"\");\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nstatic const struct service_driver gdb_service_driver = {\n\t.name = \"gdb\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = gdb_new_connection,\n\t.input_handler = gdb_input,\n\t.connection_closed_handler = gdb_connection_closed,\n\t.keep_client_alive_handler = gdb_keep_client_alive,\n};\n\nstatic int gdb_target_start(struct target *target, const char *port)\n{\n\tstruct gdb_service *gdb_service;\n\tint ret;\n\tgdb_service = malloc(sizeof(struct gdb_service));\n\n\tif (!gdb_service)\n\t\treturn -ENOMEM;\n\n\tLOG_INFO(\"starting gdb server for %s on %s\", target_name(target), port);\n\n\tgdb_service->target = target;\n\tgdb_service->core[0] = -1;\n\tgdb_service->core[1] = -1;\n\ttarget->gdb_service = gdb_service;\n\n\tret = add_service(&gdb_service_driver, port, target->gdb_max_connections, gdb_service);\n\t/* initialize all targets gdb service with the same pointer */\n\t{\n\t\tstruct target_list *head;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tif (curr != target)\n\t\t\t\tcurr->gdb_service = gdb_service;\n\t\t}\n\t}\n\treturn ret;\n}\n\nstatic int gdb_target_add_one(struct target *target)\n{\n\t/*  one gdb instance per smp list */\n\tif ((target->smp) && (target->gdb_service))\n\t\treturn ERROR_OK;\n\n\t/* skip targets that cannot handle a gdb connections (e.g. mem_ap) */\n\tif (!target_supports_gdb_connection(target)) {\n\t\tLOG_DEBUG(\"skip gdb server for target %s\", target_name(target));\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->gdb_port_override) {\n\t\tif (strcmp(target->gdb_port_override, \"disabled\") == 0) {\n\t\t\tLOG_INFO(\"gdb port disabled\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\treturn gdb_target_start(target, target->gdb_port_override);\n\t}\n\n\tif (strcmp(gdb_port, \"disabled\") == 0) {\n\t\tLOG_INFO(\"gdb port disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint retval = gdb_target_start(target, gdb_port_next);\n\tif (retval == ERROR_OK) {\n\t\t/* save the port number so can be queried with\n\t\t * $target_name cget -gdb-port\n\t\t */\n\t\ttarget->gdb_port_override = strdup(gdb_port_next);\n\n\t\tlong portnumber;\n\t\t/* If we can parse the port number\n\t\t * then we increment the port number for the next target.\n\t\t */\n\t\tchar *end;\n\t\tportnumber = strtol(gdb_port_next, &end, 0);\n\t\tif (!*end) {\n\t\t\tif (parse_long(gdb_port_next, &portnumber) == ERROR_OK) {\n\t\t\t\tfree(gdb_port_next);\n\t\t\t\tif (portnumber) {\n\t\t\t\t\tgdb_port_next = alloc_printf(\"%ld\", portnumber+1);\n\t\t\t\t} else {\n\t\t\t\t\t/* Don't increment if gdb_port is 0, since we're just\n\t\t\t\t\t * trying to allocate an unused port. */\n\t\t\t\t\tgdb_port_next = strdup(\"0\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn retval;\n}\n\nint gdb_target_add_all(struct target *target)\n{\n\tif (!target) {\n\t\tLOG_WARNING(\"gdb services need one or more targets defined\");\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (target) {\n\t\tint retval = gdb_target_add_one(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\ttarget = target->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_sync_command)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!current_gdb_connection) {\n\t\tcommand_print(CMD,\n\t\t\t\"gdb_sync command can only be run from within gdb using \\\"monitor gdb_sync\\\"\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcurrent_gdb_connection->sync = true;\n\n\treturn ERROR_OK;\n}\n\n/* daemon configuration command gdb_port */\nCOMMAND_HANDLER(handle_gdb_port_command)\n{\n\tint retval = CALL_COMMAND_HANDLER(server_pipe_command, &gdb_port);\n\tif (retval == ERROR_OK) {\n\t\tfree(gdb_port_next);\n\t\tgdb_port_next = strdup(gdb_port);\n\t}\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_gdb_memory_map_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_memory_map);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_flash_program_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_flash_program);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_report_data_abort_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_data_abort);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_report_register_access_error)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_report_register_access_error);\n\treturn ERROR_OK;\n}\n\n/* gdb_breakpoint_override */\nCOMMAND_HANDLER(handle_gdb_breakpoint_override_command)\n{\n\tif (CMD_ARGC == 0) {\n\t\t/* nothing */\n\t} else if (CMD_ARGC == 1) {\n\t\tgdb_breakpoint_override = 1;\n\t\tif (strcmp(CMD_ARGV[0], \"hard\") == 0)\n\t\t\tgdb_breakpoint_override_type = BKPT_HARD;\n\t\telse if (strcmp(CMD_ARGV[0], \"soft\") == 0)\n\t\t\tgdb_breakpoint_override_type = BKPT_SOFT;\n\t\telse if (strcmp(CMD_ARGV[0], \"disable\") == 0)\n\t\t\tgdb_breakpoint_override = 0;\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (gdb_breakpoint_override)\n\t\tLOG_USER(\"force %s breakpoints\",\n\t\t\t(gdb_breakpoint_override_type == BKPT_HARD) ? \"hard\" : \"soft\");\n\telse\n\t\tLOG_USER(\"breakpoint type is not overridden\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_target_description_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], gdb_use_target_description);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_gdb_save_tdesc_command)\n{\n\tchar *tdesc;\n\tuint32_t tdesc_length;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tint retval = gdb_generate_target_description(target, &tdesc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to Generate Target Description\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttdesc_length = strlen(tdesc);\n\n\tstruct fileio *fileio;\n\tsize_t size_written;\n\n\tchar *tdesc_filename = alloc_printf(\"%s.xml\", target_type_name(target));\n\tif (!tdesc_filename) {\n\t\tretval = ERROR_FAIL;\n\t\tgoto out;\n\t}\n\n\tretval = fileio_open(&fileio, tdesc_filename, FILEIO_WRITE, FILEIO_TEXT);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Can't open %s for writing\", tdesc_filename);\n\t\tgoto out;\n\t}\n\n\tretval = fileio_write(fileio, tdesc_length, tdesc, &size_written);\n\n\tfileio_close(fileio);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error while writing the tdesc file\");\n\nout:\n\tfree(tdesc_filename);\n\tfree(tdesc);\n\n\treturn retval;\n}\n\nstatic const struct command_registration gdb_command_handlers[] = {\n\t{\n\t\t.name = \"gdb_sync\",\n\t\t.handler = handle_gdb_sync_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"next stepi will return immediately allowing \"\n\t\t\t\"GDB to fetch register state without affecting \"\n\t\t\t\"target state\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"gdb_port\",\n\t\t.handler = handle_gdb_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Normally gdb listens to a TCP/IP port. Each subsequent GDB \"\n\t\t\t\"server listens for the next port number after the \"\n\t\t\t\"base port number specified. \"\n\t\t\t\"No arguments reports GDB port. \\\"pipe\\\" means listen to stdin \"\n\t\t\t\"output to stdout, an integer is base port number, \\\"disabled\\\" disables \"\n\t\t\t\"port. Any other string is are interpreted as named pipe to listen to. \"\n\t\t\t\"Output pipe is the same name as input pipe, but with 'o' appended.\",\n\t\t.usage = \"[port_num]\",\n\t},\n\t{\n\t\t.name = \"gdb_memory_map\",\n\t\t.handler = handle_gdb_memory_map_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable memory map\",\n\t\t.usage = \"('enable'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_flash_program\",\n\t\t.handler = handle_gdb_flash_program_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable flash program\",\n\t\t.usage = \"('enable'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_report_data_abort\",\n\t\t.handler = handle_gdb_report_data_abort_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable reporting data aborts\",\n\t\t.usage = \"('enable'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_report_register_access_error\",\n\t\t.handler = handle_gdb_report_register_access_error,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable reporting register access errors\",\n\t\t.usage = \"('enable'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_breakpoint_override\",\n\t\t.handler = handle_gdb_breakpoint_override_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or specify type of breakpoint \"\n\t\t\t\"to be used by gdb 'break' commands.\",\n\t\t.usage = \"('hard'|'soft'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_target_description\",\n\t\t.handler = handle_gdb_target_description_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable target description\",\n\t\t.usage = \"('enable'|'disable')\"\n\t},\n\t{\n\t\t.name = \"gdb_save_tdesc\",\n\t\t.handler = handle_gdb_save_tdesc_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Save the target description file\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint gdb_register_commands(struct command_context *cmd_ctx)\n{\n\tgdb_port = strdup(\"3333\");\n\tgdb_port_next = strdup(\"3333\");\n\treturn register_commands(cmd_ctx, NULL, gdb_command_handlers);\n}\n\nvoid gdb_service_free(void)\n{\n\tfree(gdb_port);\n\tfree(gdb_port_next);\n}\n\nint gdb_get_actual_connections(void)\n{\n\treturn gdb_actual_connections;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/gdb_server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2009 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_SERVER_GDB_SERVER_H\n#define OPENOCD_SERVER_GDB_SERVER_H\n\nstruct image;\nstruct reg;\n#include <target/target.h>\n#include <server/server.h>\n\n#define GDB_BUFFER_SIZE 16384\n\nint gdb_target_add_all(struct target *target);\nint gdb_register_commands(struct command_context *command_context);\nvoid gdb_service_free(void);\n\nint gdb_put_packet(struct connection *connection, char *buffer, int len);\n\nint gdb_get_actual_connections(void);\n\nstatic inline struct target *get_target_from_connection(struct connection *connection)\n{\n\tstruct gdb_service *gdb_service = connection->service->priv;\n\treturn gdb_service->target;\n}\n\n#define ERROR_GDB_BUFFER_TOO_SMALL (-800)\n#define ERROR_GDB_TIMEOUT (-801)\n\n#endif /* OPENOCD_SERVER_GDB_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/ipdbg.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/bits.h>\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include <server/server.h>\n#include <target/target.h>\n#include <pld/pld.h>\n\n#include \"ipdbg.h\"\n\n#define IPDBG_BUFFER_SIZE 16384\n#define IPDBG_MIN_NUM_OF_OPTIONS 2\n#define IPDBG_MAX_NUM_OF_OPTIONS 14\n#define IPDBG_MIN_DR_LENGTH 11\n#define IPDBG_MAX_DR_LENGTH 13\n#define IPDBG_TCP_PORT_STR_MAX_LENGTH 6\n\n/* private connection data for IPDBG */\nstruct ipdbg_fifo {\n\tsize_t count;\n\tsize_t rd_idx;\n\tchar buffer[IPDBG_BUFFER_SIZE];\n};\n\nstruct ipdbg_connection {\n\tstruct ipdbg_fifo dn_fifo;\n\tstruct ipdbg_fifo up_fifo;\n\tbool closed;\n};\n\nstruct ipdbg_service {\n\tstruct ipdbg_hub *hub;\n\tstruct ipdbg_service *next;\n\tuint16_t port;\n\tstruct ipdbg_connection connection;\n\tuint8_t tool;\n};\n\nstruct ipdbg_virtual_ir_info {\n\tuint32_t instruction;\n\tuint32_t length;\n\tuint32_t value;\n};\n\nstruct ipdbg_hub {\n\tuint32_t user_instruction;\n\tuint32_t max_tools;\n\tuint32_t active_connections;\n\tuint32_t active_services;\n\tuint32_t valid_mask;\n\tuint32_t xoff_mask;\n\tuint32_t tool_mask;\n\tuint32_t last_dn_tool;\n\tstruct ipdbg_hub *next;\n\tstruct jtag_tap *tap;\n\tstruct connection **connections;\n\tuint8_t data_register_length;\n\tuint8_t dn_xoff;\n\tstruct ipdbg_virtual_ir_info *virtual_ir;\n};\n\nstatic struct ipdbg_hub *ipdbg_first_hub;\n\nstatic struct ipdbg_service *ipdbg_first_service;\n\nstatic void ipdbg_init_fifo(struct ipdbg_fifo *fifo)\n{\n\tfifo->count = 0;\n\tfifo->rd_idx = 0;\n}\n\nstatic bool ipdbg_fifo_is_empty(struct ipdbg_fifo *fifo)\n{\n\treturn fifo->count == 0;\n}\n\nstatic bool ipdbg_fifo_is_full(struct ipdbg_fifo *fifo)\n{\n\treturn fifo->count == IPDBG_BUFFER_SIZE;\n}\n\nstatic void ipdbg_zero_rd_idx(struct ipdbg_fifo *fifo)\n{\n\tif (fifo->rd_idx == 0)\n\t\treturn;\n\n\tsize_t ri = fifo->rd_idx;\n\tfor (size_t idx = 0; idx < fifo->count; ++idx)\n\t\tfifo->buffer[idx] = fifo->buffer[ri++];\n\tfifo->rd_idx = 0;\n}\n\nstatic void ipdbg_append_to_fifo(struct ipdbg_fifo *fifo, char data)\n{\n\tif (ipdbg_fifo_is_full(fifo))\n\t\treturn;\n\n\tipdbg_zero_rd_idx(fifo);\n\tfifo->buffer[fifo->count++] = data;\n}\n\nstatic char ipdbg_get_from_fifo(struct ipdbg_fifo *fifo)\n{\n\tif (ipdbg_fifo_is_empty(fifo))\n\t\treturn 0;\n\n\tfifo->count--;\n\treturn fifo->buffer[fifo->rd_idx++];\n}\n\nstatic int ipdbg_move_buffer_to_connection(struct connection *conn, struct ipdbg_fifo *fifo)\n{\n\tif (ipdbg_fifo_is_empty(fifo))\n\t\treturn ERROR_OK;\n\n\tstruct ipdbg_connection *connection = conn->priv;\n\tif (connection->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\tipdbg_zero_rd_idx(fifo);\n\tsize_t bytes_written = connection_write(conn, fifo->buffer, fifo->count);\n\tif (bytes_written != fifo->count) {\n\t\tLOG_ERROR(\"error during write: %zu != %zu\", bytes_written, fifo->count);\n\t\tconnection->closed = true;\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tfifo->count -= bytes_written;\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_max_tools_from_data_register_length(uint8_t data_register_length)\n{\n\tint max_tools = 1;\n\tdata_register_length -= 10; /* 8 bit payload, 1 xoff-flag, 1 valid-flag; remaining bits used to select tool*/\n\twhile (data_register_length--)\n\t\tmax_tools *= 2;\n\n\t/* last tool is used to reset JtagCDC and transfer \"XON\" to host*/\n\treturn max_tools - 1;\n}\n\nstatic struct ipdbg_service *ipdbg_find_service(struct ipdbg_hub *hub, uint8_t tool)\n{\n\tstruct ipdbg_service *service;\n\tfor (service = ipdbg_first_service; service; service = service->next) {\n\t\tif (service->hub == hub && service->tool == tool)\n\t\t\tbreak;\n\t}\n\treturn service;\n}\n\nstatic void ipdbg_add_service(struct ipdbg_service *service)\n{\n\tstruct ipdbg_service *iservice;\n\tif (ipdbg_first_service) {\n\t\tfor (iservice = ipdbg_first_service; iservice->next; iservice = iservice->next)\n\t\t\t;\n\t\tiservice->next = service;\n\t} else\n\t\tipdbg_first_service = service;\n}\n\nstatic int ipdbg_create_service(struct ipdbg_hub *hub, uint8_t tool, struct ipdbg_service **service, uint16_t port)\n{\n\t*service = calloc(1, sizeof(struct ipdbg_service));\n\tif (!*service) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t(*service)->hub = hub;\n\t(*service)->tool = tool;\n\t(*service)->port = port;\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_remove_service(struct ipdbg_service *service)\n{\n\tif (!ipdbg_first_service)\n\t\treturn ERROR_FAIL;\n\n\tif (service == ipdbg_first_service) {\n\t\tipdbg_first_service = ipdbg_first_service->next;\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (struct ipdbg_service *iservice = ipdbg_first_service; iservice->next; iservice = iservice->next) {\n\t\tif (service == iservice->next) {\n\t\t\tiservice->next = service->next;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic struct ipdbg_hub *ipdbg_find_hub(struct jtag_tap *tap,\n\t\t\t\tuint32_t user_instruction, struct ipdbg_virtual_ir_info *virtual_ir)\n{\n\tstruct ipdbg_hub *hub = NULL;\n\tfor (hub = ipdbg_first_hub; hub; hub = hub->next) {\n\t\tif (hub->tap == tap && hub->user_instruction == user_instruction) {\n\t\t\tif ((!virtual_ir && !hub->virtual_ir) ||\n\t\t\t\t (virtual_ir && hub->virtual_ir &&\n\t\t\t\t  virtual_ir->instruction == hub->virtual_ir->instruction &&\n\t\t\t\t  virtual_ir->length == hub->virtual_ir->length &&\n\t\t\t\t  virtual_ir->value == hub->virtual_ir->value)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn hub;\n}\n\nstatic void ipdbg_add_hub(struct ipdbg_hub *hub)\n{\n\tstruct ipdbg_hub *ihub;\n\tif (ipdbg_first_hub) {\n\t\tfor (ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next)\n\t\t\t;\n\t\tihub->next = hub;\n\t} else\n\t\tipdbg_first_hub = hub;\n}\n\nstatic int ipdbg_create_hub(struct jtag_tap *tap, uint32_t user_instruction, uint8_t data_register_length,\n\t\t\t\t\t  struct ipdbg_virtual_ir_info *virtual_ir, struct ipdbg_hub **hub)\n{\n\t*hub = NULL;\n\tstruct ipdbg_hub *new_hub = calloc(1, sizeof(struct ipdbg_hub));\n\tif (!new_hub) {\n\t\tfree(virtual_ir);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tnew_hub->max_tools = ipdbg_max_tools_from_data_register_length(data_register_length);\n\tnew_hub->connections = calloc(new_hub->max_tools, sizeof(struct connection *));\n\tif (!new_hub->connections) {\n\t\tfree(virtual_ir);\n\t\tfree(new_hub);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tnew_hub->tap                  = tap;\n\tnew_hub->user_instruction     = user_instruction;\n\tnew_hub->data_register_length = data_register_length;\n\tnew_hub->valid_mask           = BIT(data_register_length - 1);\n\tnew_hub->xoff_mask            = BIT(data_register_length - 2);\n\tnew_hub->tool_mask            = (new_hub->xoff_mask - 1) >> 8;\n\tnew_hub->last_dn_tool         = new_hub->tool_mask;\n\tnew_hub->virtual_ir           = virtual_ir;\n\n\t*hub = new_hub;\n\n\treturn ERROR_OK;\n}\n\nstatic void ipdbg_free_hub(struct ipdbg_hub *hub)\n{\n\tif (!hub)\n\t\treturn;\n\tfree(hub->connections);\n\tfree(hub->virtual_ir);\n\tfree(hub);\n}\n\nstatic int ipdbg_remove_hub(struct ipdbg_hub *hub)\n{\n\tif (!ipdbg_first_hub)\n\t\treturn ERROR_FAIL;\n\tif (hub == ipdbg_first_hub) {\n\t\tipdbg_first_hub = ipdbg_first_hub->next;\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (struct ipdbg_hub *ihub = ipdbg_first_hub; ihub->next; ihub = ihub->next) {\n\t\tif (hub == ihub->next) {\n\t\t\tihub->next = hub->next;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nstatic void ipdbg_init_scan_field(struct scan_field *fields, uint8_t *in_value, int num_bits, const uint8_t *out_value)\n{\n\tfields->check_mask = NULL;\n\tfields->check_value = NULL;\n\tfields->in_value = in_value;\n\tfields->num_bits = num_bits;\n\tfields->out_value = out_value;\n}\n\nstatic int ipdbg_shift_instr(struct ipdbg_hub *hub, uint32_t instr)\n{\n\tif (!hub)\n\t\treturn ERROR_FAIL;\n\n\tstruct jtag_tap *tap = hub->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == instr) {\n\t\t/* there is already the requested instruction in the ir */\n\t\treturn ERROR_OK;\n\t}\n\n\tuint8_t *ir_out_val = calloc(DIV_ROUND_UP(tap->ir_length, 8), 1);\n\tif (!ir_out_val) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbuf_set_u32(ir_out_val, 0, tap->ir_length, instr);\n\n\tstruct scan_field fields;\n\tipdbg_init_scan_field(&fields, NULL, tap->ir_length, ir_out_val);\n\tjtag_add_ir_scan(tap, &fields, TAP_IDLE);\n\tint retval = jtag_execute_queue();\n\n\tfree(ir_out_val);\n\n\treturn retval;\n}\n\nstatic int ipdbg_shift_vir(struct ipdbg_hub *hub)\n{\n\tif (!hub)\n\t\treturn ERROR_FAIL;\n\n\tif (!hub->virtual_ir)\n\t\treturn ERROR_OK;\n\n\tint retval = ipdbg_shift_instr(hub, hub->virtual_ir->instruction);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct jtag_tap *tap = hub->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tuint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->virtual_ir->length, 8), 1);\n\tif (!dr_out_val) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbuf_set_u32(dr_out_val, 0, hub->virtual_ir->length, hub->virtual_ir->value);\n\n\tstruct scan_field fields;\n\tipdbg_init_scan_field(&fields, NULL, hub->virtual_ir->length, dr_out_val);\n\tjtag_add_dr_scan(tap, 1, &fields, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\n\tfree(dr_out_val);\n\n\treturn retval;\n}\n\nstatic int ipdbg_shift_data(struct ipdbg_hub *hub, uint32_t dn_data, uint32_t *up_data)\n{\n\tif (!hub)\n\t\treturn ERROR_FAIL;\n\n\tstruct jtag_tap *tap = hub->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tuint8_t *dr_out_val = calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1);\n\tif (!dr_out_val) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tbuf_set_u32(dr_out_val, 0, hub->data_register_length, dn_data);\n\n\tuint8_t *dr_in_val = NULL;\n\tif (up_data) {\n\t\tdr_in_val = calloc(DIV_ROUND_UP(hub->data_register_length, 8), 1);\n\t\tif (!dr_in_val) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tfree(dr_out_val);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tstruct scan_field fields;\n\tipdbg_init_scan_field(&fields, dr_in_val, hub->data_register_length, dr_out_val);\n\tjtag_add_dr_scan(tap, 1, &fields, TAP_IDLE);\n\tint retval = jtag_execute_queue();\n\n\tif (up_data && retval == ERROR_OK)\n\t\t*up_data = buf_get_u32(dr_in_val, 0, hub->data_register_length);\n\n\tfree(dr_out_val);\n\tfree(dr_in_val);\n\n\treturn retval;\n}\n\nstatic int ipdbg_distribute_data_from_hub(struct ipdbg_hub *hub, uint32_t up)\n{\n\tconst bool valid_up_data = up & hub->valid_mask;\n\tif (!valid_up_data)\n\t\treturn ERROR_OK;\n\n\tconst size_t tool = (up >> 8) & hub->tool_mask;\n\tif (tool == hub->tool_mask) {\n\t\tconst uint8_t xon_cmd = up & 0x00ff;\n\t\thub->dn_xoff &= ~xon_cmd;\n\t\tLOG_INFO(\"received xon cmd: %d\\n\", xon_cmd);\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct connection *conn = hub->connections[tool];\n\tif (conn) {\n\t\tstruct ipdbg_connection *connection = conn->priv;\n\t\tif (ipdbg_fifo_is_full(&connection->up_fifo)) {\n\t\t\tint retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tipdbg_append_to_fifo(&connection->up_fifo, up);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_jtag_transfer_byte(struct ipdbg_hub *hub, size_t tool, struct ipdbg_connection *connection)\n{\n\tuint32_t dn = hub->valid_mask | ((tool & hub->tool_mask) << 8) |\n\t\t\t\t(0x00fful & ipdbg_get_from_fifo(&connection->dn_fifo));\n\tuint32_t up = 0;\n\tint ret = ipdbg_shift_data(hub, dn, &up);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ipdbg_distribute_data_from_hub(hub, up);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif ((up & hub->xoff_mask) && (hub->last_dn_tool != hub->max_tools)) {\n\t\thub->dn_xoff |= BIT(hub->last_dn_tool);\n\t\tLOG_INFO(\"tool %d sent xoff\", hub->last_dn_tool);\n\t}\n\n\thub->last_dn_tool = tool;\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_polling_callback(void *priv)\n{\n\tstruct ipdbg_hub *hub = priv;\n\n\tint ret = ipdbg_shift_vir(hub);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ipdbg_shift_instr(hub, hub->user_instruction);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t/* transfer dn buffers to jtag-hub */\n\tunsigned int num_transfers = 0;\n\tfor (size_t tool = 0; tool < hub->max_tools; ++tool) {\n\t\tstruct connection *conn = hub->connections[tool];\n\t\tif (conn && conn->priv) {\n\t\t\tstruct ipdbg_connection *connection = conn->priv;\n\t\t\twhile (((hub->dn_xoff & BIT(tool)) == 0) && !ipdbg_fifo_is_empty(&connection->dn_fifo)) {\n\t\t\t\tret = ipdbg_jtag_transfer_byte(hub, tool, connection);\n\t\t\t\tif (ret != ERROR_OK)\n\t\t\t\t\treturn ret;\n\t\t\t\t++num_transfers;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* some transfers to get data from jtag-hub in case there is no dn data */\n\twhile (num_transfers++ < hub->max_tools) {\n\t\tuint32_t dn = 0;\n\t\tuint32_t up = 0;\n\n\t\tint retval = ipdbg_shift_data(hub, dn, &up);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tretval = ipdbg_distribute_data_from_hub(hub, up);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\t/* write from up fifos to sockets */\n\tfor (size_t tool = 0; tool < hub->max_tools; ++tool) {\n\t\tstruct connection *conn = hub->connections[tool];\n\t\tif (conn && conn->priv) {\n\t\t\tstruct ipdbg_connection *connection = conn->priv;\n\t\t\tint retval = ipdbg_move_buffer_to_connection(conn, &connection->up_fifo);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_start_polling(struct ipdbg_service *service, struct connection *connection)\n{\n\tstruct ipdbg_hub *hub = service->hub;\n\thub->connections[service->tool] = connection;\n\thub->active_connections++;\n\tif (hub->active_connections > 1) {\n\t\t/* hub is already initialized */\n\t\treturn ERROR_OK;\n\t}\n\n\tconst uint32_t reset_hub = hub->valid_mask | ((hub->max_tools) << 8);\n\n\tint ret = ipdbg_shift_vir(hub);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ipdbg_shift_instr(hub, hub->user_instruction);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = ipdbg_shift_data(hub, reset_hub, NULL);\n\thub->last_dn_tool = hub->tool_mask;\n\thub->dn_xoff = 0;\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_INFO(\"IPDBG start_polling\");\n\n\tconst int time_ms = 20;\n\tconst int periodic = 1;\n\treturn target_register_timer_callback(ipdbg_polling_callback, time_ms, periodic, hub);\n}\n\nstatic int ipdbg_stop_polling(struct ipdbg_service *service)\n{\n\tstruct ipdbg_hub *hub = service->hub;\n\thub->connections[service->tool] = NULL;\n\thub->active_connections--;\n\tif (hub->active_connections == 0) {\n\t\tLOG_INFO(\"IPDBG stop_polling\");\n\n\t\treturn target_unregister_timer_callback(ipdbg_polling_callback, hub);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_on_new_connection(struct connection *connection)\n{\n\tstruct ipdbg_service *service = connection->service->priv;\n\tconnection->priv = &service->connection;\n\t/* initialize ipdbg connection information */\n\tipdbg_init_fifo(&service->connection.up_fifo);\n\tipdbg_init_fifo(&service->connection.dn_fifo);\n\n\tint retval = ipdbg_start_polling(service, connection);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: ipdbg_start_polling failed\");\n\t\treturn retval;\n\t}\n\n\tstruct ipdbg_connection *conn = connection->priv;\n\tconn->closed = false;\n\n\tLOG_INFO(\"New IPDBG Connection\");\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_on_connection_input(struct connection *connection)\n{\n\tstruct ipdbg_connection *conn = connection->priv;\n\tstruct ipdbg_fifo *fifo = &conn->dn_fifo;\n\n\tif (ipdbg_fifo_is_full(fifo))\n\t\treturn ERROR_OK;\n\n\tipdbg_zero_rd_idx(fifo);\n\tint bytes_read = connection_read(connection, fifo->buffer + fifo->count, IPDBG_BUFFER_SIZE - fifo->count);\n\tif (bytes_read <= 0) {\n\t\tif (bytes_read < 0)\n\t\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tfifo->count += bytes_read;\n\n\treturn ERROR_OK;\n}\n\nstatic int ipdbg_on_connection_closed(struct connection *connection)\n{\n\tstruct ipdbg_connection *conn = connection->priv;\n\tconn->closed = true;\n\tLOG_INFO(\"Closed IPDBG Connection\");\n\n\treturn ipdbg_stop_polling(connection->service->priv);\n}\n\nstatic const struct service_driver ipdbg_service_driver = {\n\t.name = \"ipdbg\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = ipdbg_on_new_connection,\n\t.input_handler = ipdbg_on_connection_input,\n\t.connection_closed_handler = ipdbg_on_connection_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nstatic int ipdbg_start(uint16_t port, struct jtag_tap *tap, uint32_t user_instruction,\n\t\t\t\t\tuint8_t data_register_length, struct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)\n{\n\tLOG_INFO(\"starting ipdbg service on port %d for tool %d\", port, tool);\n\n\tstruct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir);\n\tif (hub) {\n\t\tfree(virtual_ir);\n\t\tif (hub->data_register_length != data_register_length) {\n\t\t\tLOG_DEBUG(\"hub must have the same data_register_length for all tools\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tint retval = ipdbg_create_hub(tap, user_instruction, data_register_length, virtual_ir, &hub);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tstruct ipdbg_service *service = NULL;\n\tint retval = ipdbg_create_service(hub, tool, &service, port);\n\n\tif (retval != ERROR_OK || !service) {\n\t\tif (hub->active_services == 0 && hub->active_connections == 0)\n\t\t\tipdbg_free_hub(hub);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchar port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];\n\tsnprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, \"%u\", port);\n\tretval = add_service(&ipdbg_service_driver, port_str_buffer, 1, service);\n\tif (retval == ERROR_OK) {\n\t\tipdbg_add_service(service);\n\t\tif (hub->active_services == 0 && hub->active_connections == 0)\n\t\t\tipdbg_add_hub(hub);\n\t\thub->active_services++;\n\t} else {\n\t\tif (hub->active_services == 0 && hub->active_connections == 0)\n\t\t\tipdbg_free_hub(hub);\n\t\tfree(service);\n\t}\n\n\treturn retval;\n}\n\nstatic int ipdbg_stop(struct jtag_tap *tap, uint32_t user_instruction,\n\t\t\tstruct ipdbg_virtual_ir_info *virtual_ir, uint8_t tool)\n{\n\tstruct ipdbg_hub *hub = ipdbg_find_hub(tap, user_instruction, virtual_ir);\n\tfree(virtual_ir);\n\tif (!hub)\n\t\treturn ERROR_FAIL;\n\n\tstruct ipdbg_service *service = ipdbg_find_service(hub, tool);\n\tif (!service)\n\t\treturn ERROR_FAIL;\n\n\tint retval = ipdbg_remove_service(service);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: ipdbg_remove_service failed\");\n\t\treturn retval;\n\t}\n\n\tchar port_str_buffer[IPDBG_TCP_PORT_STR_MAX_LENGTH];\n\tsnprintf(port_str_buffer, IPDBG_TCP_PORT_STR_MAX_LENGTH, \"%u\", service->port);\n\tretval = remove_service(\"ipdbg\", port_str_buffer);\n\t/* The ipdbg_service structure is freed by server.c:remove_service().\n\t   There the \"priv\" pointer is freed.*/\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: remove_service failed\");\n\t\treturn retval;\n\t}\n\thub->active_services--;\n\tif (hub->active_connections == 0 && hub->active_services == 0) {\n\t\tretval = ipdbg_remove_hub(hub);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"BUG: ipdbg_remove_hub failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tipdbg_free_hub(hub);\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_ipdbg_command)\n{\n\tstruct jtag_tap *tap = NULL;\n\tuint16_t port = 4242;\n\tuint8_t tool = 1;\n\tuint32_t user_instruction = 0x00;\n\tuint8_t data_register_length = IPDBG_MAX_DR_LENGTH;\n\tbool start = true;\n\tbool hub_configured = false;\n\tbool has_virtual_ir = false;\n\tuint32_t virtual_ir_instruction = 0x00e;\n\tuint32_t virtual_ir_length = 5;\n\tuint32_t virtual_ir_value = 0x11;\n\tstruct ipdbg_virtual_ir_info *virtual_ir = NULL;\n\tint user_num = 1;\n\n\tif ((CMD_ARGC < IPDBG_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > IPDBG_MAX_NUM_OF_OPTIONS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; ++i) {\n\t\tif (strcmp(CMD_ARGV[i], \"-tap\") == 0) {\n\t\t\tif (i + 1 >= CMD_ARGC || CMD_ARGV[i + 1][0] == '-') {\n\t\t\t\tcommand_print(CMD, \"no TAP given\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ttap = jtag_tap_by_string(CMD_ARGV[i + 1]);\n\t\t\tif (!tap) {\n\t\t\t\tcommand_print(CMD, \"Tap %s unknown\", CMD_ARGV[i + 1]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\t++i;\n\t\t} else if (strcmp(CMD_ARGV[i], \"-hub\") == 0) {\n\t\t\tCOMMAND_PARSE_ADDITIONAL_NUMBER(u32, i, user_instruction, \"ir_value to select hub\");\n\t\t\thub_configured = true;\n\t\t\tCOMMAND_PARSE_OPTIONAL_NUMBER(u8, i, data_register_length);\n\t\t\tif (data_register_length < IPDBG_MIN_DR_LENGTH ||\n\t\t\t\tdata_register_length > IPDBG_MAX_DR_LENGTH) {\n\t\t\t\tcommand_print(CMD, \"length of \\\"user\\\"-data register must be at least %d and at most %d.\",\n\t\t\t\t\t\t\tIPDBG_MIN_DR_LENGTH, IPDBG_MAX_DR_LENGTH);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t} else if (strcmp(CMD_ARGV[i], \"-pld\") == 0) {\n\t\t\t++i;\n\t\t\tif (i >= CMD_ARGC || CMD_ARGV[i][0] == '-')\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tstruct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[i]);\n\t\t\tif (!device || !device->driver) {\n\t\t\t\tcommand_print(CMD, \"pld device '#%s' is out of bounds or unknown\", CMD_ARGV[i]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tCOMMAND_PARSE_OPTIONAL_NUMBER(int, i, user_num);\n\t\t\tstruct pld_ipdbg_hub pld_hub;\n\t\t\tstruct pld_driver *driver = device->driver;\n\t\t\tif (!driver->get_ipdbg_hub) {\n\t\t\t\tcommand_print(CMD, \"pld driver has no ipdbg support\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (driver->get_ipdbg_hub(user_num, device, &pld_hub) != ERROR_OK) {\n\t\t\t\tcommand_print(CMD, \"unable to retrieve hub from pld driver\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (!pld_hub.tap) {\n\t\t\t\tcommand_print(CMD, \"no tap received from pld driver\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\thub_configured = true;\n\t\t\tuser_instruction = pld_hub.user_ir_code;\n\t\t\ttap = pld_hub.tap;\n\n\t\t} else if (strcmp(CMD_ARGV[i], \"-vir\") == 0) {\n\t\t\tCOMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_value);\n\t\t\tCOMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_length);\n\t\t\tCOMMAND_PARSE_OPTIONAL_NUMBER(u32, i, virtual_ir_instruction);\n\t\t\thas_virtual_ir = true;\n\t\t} else if (strcmp(CMD_ARGV[i], \"-port\") == 0) {\n\t\t\tCOMMAND_PARSE_ADDITIONAL_NUMBER(u16, i, port, \"port number\");\n\t\t} else if (strcmp(CMD_ARGV[i], \"-tool\") == 0) {\n\t\t\tCOMMAND_PARSE_ADDITIONAL_NUMBER(u8, i, tool, \"tool\");\n\t\t} else if (strcmp(CMD_ARGV[i], \"-stop\") == 0) {\n\t\t\tstart = false;\n\t\t} else if (strcmp(CMD_ARGV[i], \"-start\") == 0) {\n\t\t\tstart = true;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"Unknown argument: %s\", CMD_ARGV[i]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (!tap) {\n\t\tcommand_print(CMD, \"no valid tap selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!hub_configured) {\n\t\tcommand_print(CMD, \"hub not configured correctly\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (tool >= ipdbg_max_tools_from_data_register_length(data_register_length)) {\n\t\tcommand_print(CMD, \"Tool: %d is invalid\", tool);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (has_virtual_ir) {\n\t\tvirtual_ir = calloc(1, sizeof(struct ipdbg_virtual_ir_info));\n\t\tif (!virtual_ir) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tvirtual_ir->instruction = virtual_ir_instruction;\n\t\tvirtual_ir->length      = virtual_ir_length;\n\t\tvirtual_ir->value       = virtual_ir_value;\n\t}\n\n\tif (start)\n\t\treturn ipdbg_start(port, tap, user_instruction, data_register_length, virtual_ir, tool);\n\telse\n\t\treturn ipdbg_stop(tap, user_instruction, virtual_ir, tool);\n}\n\nstatic const struct command_registration ipdbg_command_handlers[] = {\n\t{\n\t\t.name = \"ipdbg\",\n\t\t.handler = handle_ipdbg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Starts or stops an IPDBG JTAG-Host server.\",\n\t\t.usage = \"[-start|-stop] -tap device.tap -hub ir_value [dr_length]\"\n\t\t\t\t \" [-port number] [-tool number] [-vir [vir_value [length [instr_code]]]]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint ipdbg_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, ipdbg_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/ipdbg.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/* Copyright (C) 2020 by Daniel Anselmi <danselmi@gmx.ch> */\n\n#ifndef OPENOCD_IPDBG_IPDBG_H\n#define OPENOCD_IPDBG_IPDBG_H\n\n#include <helper/command.h>\n\nint ipdbg_register_commands(struct command_context *cmd_ctx);\n\n#endif /* OPENOCD_IPDBG_IPDBG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/rtt_server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <rtt/rtt.h>\n\n#include \"server.h\"\n#include \"rtt_server.h\"\n\n/**\n * @file\n *\n * RTT server.\n *\n * This server allows access to Real Time Transfer (RTT) channels via TCP\n * connections.\n */\n\nstruct rtt_service {\n\tunsigned int channel;\n};\n\nstatic int read_callback(unsigned int channel, const uint8_t *buffer,\n\t\tsize_t length, void *user_data)\n{\n\tint ret;\n\tstruct connection *connection;\n\tsize_t offset;\n\n\tconnection = (struct connection *)user_data;\n\toffset = 0;\n\n\twhile (offset < length) {\n\t\tret = connection_write(connection, buffer + offset, length - offset);\n\n\t\tif (ret < 0) {\n\t\t\tLOG_ERROR(\"Failed to write data to socket.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\toffset += ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rtt_new_connection(struct connection *connection)\n{\n\tint ret;\n\tstruct rtt_service *service;\n\n\tservice = connection->service->priv;\n\n\tLOG_DEBUG(\"rtt: New connection for channel %u\", service->channel);\n\n\tret = rtt_register_sink(service->channel, &read_callback, connection);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn ERROR_OK;\n}\n\nstatic int rtt_connection_closed(struct connection *connection)\n{\n\tstruct rtt_service *service;\n\n\tservice = (struct rtt_service *)connection->service->priv;\n\trtt_unregister_sink(service->channel, &read_callback, connection);\n\n\tLOG_DEBUG(\"rtt: Connection for channel %u closed\", service->channel);\n\n\treturn ERROR_OK;\n}\n\nstatic int rtt_input(struct connection *connection)\n{\n\tint bytes_read;\n\tunsigned char buffer[1024];\n\tstruct rtt_service *service;\n\tsize_t length;\n\n\tservice = (struct rtt_service *)connection->service->priv;\n\tbytes_read = connection_read(connection, buffer, sizeof(buffer));\n\n\tif (!bytes_read)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\telse if (bytes_read < 0) {\n\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tlength = bytes_read;\n\trtt_write_channel(service->channel, buffer, &length);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct service_driver rtt_service_driver = {\n\t.name = \"rtt\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = rtt_new_connection,\n\t.input_handler = rtt_input,\n\t.connection_closed_handler = rtt_connection_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nCOMMAND_HANDLER(handle_rtt_start_command)\n{\n\tint ret;\n\tstruct rtt_service *service;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tservice = malloc(sizeof(struct rtt_service));\n\n\tif (!service)\n\t\treturn ERROR_FAIL;\n\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], service->channel);\n\n\tret = add_service(&rtt_service_driver, CMD_ARGV[0], CONNECTION_LIMIT_UNLIMITED, service);\n\n\tif (ret != ERROR_OK) {\n\t\tfree(service);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_rtt_stop_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tremove_service(\"rtt\", CMD_ARGV[0]);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration rtt_server_subcommand_handlers[] = {\n\t{\n\t\t.name = \"start\",\n\t\t.handler = handle_rtt_start_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Start a RTT server\",\n\t\t.usage = \"<port> <channel>\"\n\t},\n\t{\n\t\t.name = \"stop\",\n\t\t.handler = handle_rtt_stop_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Stop a RTT server\",\n\t\t.usage = \"<port>\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration rtt_server_command_handlers[] = {\n\t{\n\t\t.name = \"server\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"RTT server\",\n\t\t.usage = \"\",\n\t\t.chain = rtt_server_subcommand_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration rtt_command_handlers[] = {\n\t{\n\t\t.name = \"rtt\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"RTT\",\n\t\t.usage = \"\",\n\t\t.chain = rtt_server_command_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint rtt_server_register_commands(struct command_context *ctx)\n{\n\treturn register_commands(ctx, NULL, rtt_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/rtt_server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2016-2017 by Marc Schink <dev@zapb.de>\n */\n\n#ifndef OPENOCD_SERVER_RTT_SERVER_H\n#define OPENOCD_SERVER_RTT_SERVER_H\n\n#include <helper/command.h>\n\nint rtt_server_register_commands(struct command_context *ctx);\n\n#endif /* OPENOCD_SERVER_RTT_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"server.h\"\n#include <helper/time_support.h>\n#include <target/target.h>\n#include <target/target_request.h>\n#include <target/openrisc/jsp_server.h>\n#include \"openocd.h\"\n#include \"tcl_server.h\"\n#include \"telnet_server.h\"\n\n#include <signal.h>\n\n#ifdef HAVE_NETDB_H\n#include <netdb.h>\n#endif\n\n#ifndef _WIN32\n#include <netinet/tcp.h>\n#endif\n\nstatic struct service *services;\n\nenum shutdown_reason {\n\tCONTINUE_MAIN_LOOP,\t\t\t/* stay in main event loop */\n\tSHUTDOWN_REQUESTED,\t\t\t/* set by shutdown command; exit the event loop and quit the debugger */\n\tSHUTDOWN_WITH_ERROR_CODE,\t/* set by shutdown command; quit with non-zero return code */\n\tSHUTDOWN_WITH_SIGNAL_CODE\t/* set by sig_handler; exec shutdown then exit with signal as return code */\n};\nstatic enum shutdown_reason shutdown_openocd = CONTINUE_MAIN_LOOP;\n\n/* store received signal to exit application by killing ourselves */\nstatic int last_signal;\n\n/* set the polling period to 100ms */\nstatic int polling_period = 100;\n\n/* address by name on which to listen for incoming TCP/IP connections */\nstatic char *bindto_name;\n\nstatic int add_connection(struct service *service, struct command_context *cmd_ctx)\n{\n\tsocklen_t address_size;\n\tstruct connection *c, **p;\n\tint retval;\n\tint flag = 1;\n\n\tc = malloc(sizeof(struct connection));\n\tc->fd = -1;\n\tc->fd_out = -1;\n\tmemset(&c->sin, 0, sizeof(c->sin));\n\tc->cmd_ctx = copy_command_context(cmd_ctx);\n\tc->service = service;\n\tc->input_pending = false;\n\tc->priv = NULL;\n\tc->next = NULL;\n\n\tif (service->type == CONNECTION_TCP) {\n\t\taddress_size = sizeof(c->sin);\n\n\t\tc->fd = accept(service->fd, (struct sockaddr *)&service->sin, &address_size);\n\t\tc->fd_out = c->fd;\n\n\t\t/* This increases performance dramatically for e.g. GDB load which\n\t\t * does not have a sliding window protocol.\n\t\t *\n\t\t * Ignore errors from this fn as it probably just means less performance\n\t\t */\n\t\tsetsockopt(c->fd,\t/* socket affected */\n\t\t\tIPPROTO_TCP,\t\t\t/* set option at TCP level */\n\t\t\tTCP_NODELAY,\t\t\t/* name of option */\n\t\t\t(char *)&flag,\t\t\t/* the cast is historical cruft */\n\t\t\tsizeof(int));\t\t\t/* length of option value */\n\n\t\tLOG_INFO(\"accepting '%s' connection on tcp/%s\", service->name, service->port);\n\t\tretval = service->new_connection(c);\n\t\tif (retval != ERROR_OK) {\n\t\t\tclose_socket(c->fd);\n\t\t\tLOG_ERROR(\"attempted '%s' connection rejected\", service->name);\n\t\t\tcommand_done(c->cmd_ctx);\n\t\t\tfree(c);\n\t\t\treturn retval;\n\t\t}\n\t} else if (service->type == CONNECTION_STDINOUT) {\n\t\tc->fd = service->fd;\n\t\tc->fd_out = fileno(stdout);\n\n#ifdef _WIN32\n\t\t/* we are using stdin/out so ignore ctrl-c under windoze */\n\t\tSetConsoleCtrlHandler(NULL, TRUE);\n#endif\n\n\t\t/* do not check for new connections again on stdin */\n\t\tservice->fd = -1;\n\n\t\tLOG_INFO(\"accepting '%s' connection from pipe\", service->name);\n\t\tretval = service->new_connection(c);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"attempted '%s' connection rejected\", service->name);\n\t\t\tcommand_done(c->cmd_ctx);\n\t\t\tfree(c);\n\t\t\treturn retval;\n\t\t}\n\t} else if (service->type == CONNECTION_PIPE) {\n\t\tc->fd = service->fd;\n\t\t/* do not check for new connections again on stdin */\n\t\tservice->fd = -1;\n\n\t\tchar *out_file = alloc_printf(\"%so\", service->port);\n\t\tc->fd_out = open(out_file, O_WRONLY);\n\t\tfree(out_file);\n\t\tif (c->fd_out == -1) {\n\t\t\tLOG_ERROR(\"could not open %s\", service->port);\n\t\t\tcommand_done(c->cmd_ctx);\n\t\t\tfree(c);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_INFO(\"accepting '%s' connection from pipe %s\", service->name, service->port);\n\t\tretval = service->new_connection(c);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"attempted '%s' connection rejected\", service->name);\n\t\t\tcommand_done(c->cmd_ctx);\n\t\t\tfree(c);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* add to the end of linked list */\n\tfor (p = &service->connections; *p; p = &(*p)->next)\n\t\t;\n\t*p = c;\n\n\tif (service->max_connections != CONNECTION_LIMIT_UNLIMITED)\n\t\tservice->max_connections--;\n\n\treturn ERROR_OK;\n}\n\nstatic int remove_connection(struct service *service, struct connection *connection)\n{\n\tstruct connection **p = &service->connections;\n\tstruct connection *c;\n\n\t/* find connection */\n\twhile ((c = *p)) {\n\t\tif (c->fd == connection->fd) {\n\t\t\tservice->connection_closed(c);\n\t\t\tif (service->type == CONNECTION_TCP)\n\t\t\t\tclose_socket(c->fd);\n\t\t\telse if (service->type == CONNECTION_PIPE) {\n\t\t\t\t/* The service will listen to the pipe again */\n\t\t\t\tc->service->fd = c->fd;\n\t\t\t}\n\n\t\t\tcommand_done(c->cmd_ctx);\n\n\t\t\t/* delete connection */\n\t\t\t*p = c->next;\n\t\t\tfree(c);\n\n\t\t\tif (service->max_connections != CONNECTION_LIMIT_UNLIMITED)\n\t\t\t\tservice->max_connections++;\n\n\t\t\tbreak;\n\t\t}\n\n\t\t/* redirect p to next list pointer */\n\t\tp = &(*p)->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void free_service(struct service *c)\n{\n\tfree(c->name);\n\tfree(c->port);\n\tfree(c);\n}\n\nint add_service(const struct service_driver *driver, const char *port,\n\t\tint max_connections, void *priv)\n{\n\tstruct service *c, **p;\n\tstruct hostent *hp;\n\tint so_reuseaddr_option = 1;\n\n\tc = malloc(sizeof(struct service));\n\n\tc->name = strdup(driver->name);\n\tc->port = strdup(port);\n\tc->max_connections = 1;\t/* Only TCP/IP ports can support more than one connection */\n\tc->fd = -1;\n\tc->connections = NULL;\n\tc->new_connection_during_keep_alive = driver->new_connection_during_keep_alive_handler;\n\tc->new_connection = driver->new_connection_handler;\n\tc->input = driver->input_handler;\n\tc->connection_closed = driver->connection_closed_handler;\n\tc->keep_client_alive = driver->keep_client_alive_handler;\n\tc->priv = priv;\n\tc->next = NULL;\n\tlong portnumber;\n\tif (strcmp(c->port, \"pipe\") == 0)\n\t\tc->type = CONNECTION_STDINOUT;\n\telse {\n\t\tchar *end;\n\t\tportnumber = strtol(c->port, &end, 0);\n\t\tif (!*end && (parse_long(c->port, &portnumber) == ERROR_OK)) {\n\t\t\tc->portnumber = portnumber;\n\t\t\tc->type = CONNECTION_TCP;\n\t\t} else\n\t\t\tc->type = CONNECTION_PIPE;\n\t}\n\n\tif (c->type == CONNECTION_TCP) {\n\t\tc->max_connections = max_connections;\n\n\t\tc->fd = socket(AF_INET, SOCK_STREAM, 0);\n\t\tif (c->fd == -1) {\n\t\t\tLOG_ERROR(\"error creating socket: %s\", strerror(errno));\n\t\t\tfree_service(c);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tsetsockopt(c->fd,\n\t\t\tSOL_SOCKET,\n\t\t\tSO_REUSEADDR,\n\t\t\t(void *)&so_reuseaddr_option,\n\t\t\tsizeof(int));\n\n\t\tsocket_nonblock(c->fd);\n\n\t\tmemset(&c->sin, 0, sizeof(c->sin));\n\t\tc->sin.sin_family = AF_INET;\n\n\t\tif (!bindto_name)\n\t\t\tc->sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);\n\t\telse {\n\t\t\thp = gethostbyname(bindto_name);\n\t\t\tif (!hp) {\n\t\t\t\tLOG_ERROR(\"couldn't resolve bindto address: %s\", bindto_name);\n\t\t\t\tclose_socket(c->fd);\n\t\t\t\tfree_service(c);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tmemcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);\n\t\t}\n\t\tc->sin.sin_port = htons(c->portnumber);\n\n\t\tif (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {\n\t\t\tLOG_ERROR(\"couldn't bind %s to socket on port %d: %s\", c->name, c->portnumber, strerror(errno));\n\t\t\tclose_socket(c->fd);\n\t\t\tfree_service(c);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n#ifndef _WIN32\n\t\tint segsize = 65536;\n\t\tsetsockopt(c->fd, IPPROTO_TCP, TCP_MAXSEG,  &segsize, sizeof(int));\n#endif\n\t\tint window_size = 128 * 1024;\n\n\t\t/* These setsockopt()s must happen before the listen() */\n\n\t\tsetsockopt(c->fd, SOL_SOCKET, SO_SNDBUF,\n\t\t\t(char *)&window_size, sizeof(window_size));\n\t\tsetsockopt(c->fd, SOL_SOCKET, SO_RCVBUF,\n\t\t\t(char *)&window_size, sizeof(window_size));\n\n\t\tif (listen(c->fd, 1) == -1) {\n\t\t\tLOG_ERROR(\"couldn't listen on socket: %s\", strerror(errno));\n\t\t\tclose_socket(c->fd);\n\t\t\tfree_service(c);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tstruct sockaddr_in addr_in;\n\t\taddr_in.sin_port = 0;\n\t\tsocklen_t addr_in_size = sizeof(addr_in);\n\t\tif (getsockname(c->fd, (struct sockaddr *)&addr_in, &addr_in_size) == 0)\n\t\t\tLOG_INFO(\"Listening on port %hu for %s connections\",\n\t\t\t\t ntohs(addr_in.sin_port), c->name);\n\t} else if (c->type == CONNECTION_STDINOUT) {\n\t\tc->fd = fileno(stdin);\n\n#ifdef _WIN32\n\t\t/* for win32 set stdin/stdout to binary mode */\n\t\tif (_setmode(_fileno(stdout), _O_BINARY) < 0)\n\t\t\tLOG_WARNING(\"cannot change stdout mode to binary\");\n\t\tif (_setmode(_fileno(stdin), _O_BINARY) < 0)\n\t\t\tLOG_WARNING(\"cannot change stdin mode to binary\");\n\t\tif (_setmode(_fileno(stderr), _O_BINARY) < 0)\n\t\t\tLOG_WARNING(\"cannot change stderr mode to binary\");\n#else\n\t\tsocket_nonblock(c->fd);\n#endif\n\t} else if (c->type == CONNECTION_PIPE) {\n#ifdef _WIN32\n\t\t/* we currently do not support named pipes under win32\n\t\t * so exit openocd for now */\n\t\tLOG_ERROR(\"Named pipes currently not supported under this os\");\n\t\tfree_service(c);\n\t\treturn ERROR_FAIL;\n#else\n\t\t/* Pipe we're reading from */\n\t\tc->fd = open(c->port, O_RDONLY | O_NONBLOCK);\n\t\tif (c->fd == -1) {\n\t\t\tLOG_ERROR(\"could not open %s\", c->port);\n\t\t\tfree_service(c);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n#endif\n\t}\n\n\t/* add to the end of linked list */\n\tfor (p = &services; *p; p = &(*p)->next)\n\t\t;\n\t*p = c;\n\n\treturn ERROR_OK;\n}\n\nstatic void remove_connections(struct service *service)\n{\n\tstruct connection *connection;\n\n\tconnection = service->connections;\n\n\twhile (connection) {\n\t\tstruct connection *tmp;\n\n\t\ttmp = connection->next;\n\t\tremove_connection(service, connection);\n\t\tconnection = tmp;\n\t}\n}\n\nint remove_service(const char *name, const char *port)\n{\n\tstruct service *tmp;\n\tstruct service *prev;\n\n\tprev = services;\n\n\tfor (tmp = services; tmp; prev = tmp, tmp = tmp->next) {\n\t\tif (!strcmp(tmp->name, name) && !strcmp(tmp->port, port)) {\n\t\t\tremove_connections(tmp);\n\n\t\t\tif (tmp == services)\n\t\t\t\tservices = tmp->next;\n\t\t\telse\n\t\t\t\tprev->next = tmp->next;\n\n\t\t\tif (tmp->type != CONNECTION_STDINOUT)\n\t\t\t\tclose_socket(tmp->fd);\n\n\t\t\tfree(tmp->priv);\n\t\t\tfree_service(tmp);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int remove_services(void)\n{\n\tstruct service *c = services;\n\n\t/* loop service */\n\twhile (c) {\n\t\tstruct service *next = c->next;\n\n\t\tremove_connections(c);\n\n\t\tfree(c->name);\n\n\t\tif (c->type == CONNECTION_PIPE) {\n\t\t\tif (c->fd != -1)\n\t\t\t\tclose(c->fd);\n\t\t}\n\t\tfree(c->port);\n\t\tfree(c->priv);\n\t\t/* delete service */\n\t\tfree(c);\n\n\t\t/* remember the last service for unlinking */\n\t\tc = next;\n\t}\n\n\tservices = NULL;\n\n\treturn ERROR_OK;\n}\n\nvoid server_keep_clients_alive(void)\n{\n\tfor (struct service *s = services; s; s = s->next)\n\t\tif (s->keep_client_alive)\n\t\t\tfor (struct connection *c = s->connections; c; c = c->next)\n\t\t\t\ts->keep_client_alive(c);\n}\n\nint server_loop(struct command_context *command_context)\n{\n\tstruct service *service;\n\n\tbool poll_ok = true;\n\n\t/* used in select() */\n\tfd_set read_fds;\n\tint fd_max;\n\n\t/* used in accept() */\n\tint retval;\n\n\tint64_t next_event = timeval_ms() + polling_period;\n\n#ifndef _WIN32\n\tif (signal(SIGPIPE, SIG_IGN) == SIG_ERR)\n\t\tLOG_ERROR(\"couldn't set SIGPIPE to SIG_IGN\");\n#endif\n\n\twhile (shutdown_openocd == CONTINUE_MAIN_LOOP) {\n\t\t/* monitor sockets for activity */\n\t\tfd_max = 0;\n\t\tFD_ZERO(&read_fds);\n\n\t\t/* add service and connection fds to read_fds */\n\t\tfor (service = services; service; service = service->next) {\n\t\t\tif (service->fd != -1) {\n\t\t\t\t/* listen for new connections */\n\t\t\t\tFD_SET(service->fd, &read_fds);\n\n\t\t\t\tif (service->fd > fd_max)\n\t\t\t\t\tfd_max = service->fd;\n\t\t\t}\n\n\t\t\tif (service->connections) {\n\t\t\t\tstruct connection *c;\n\n\t\t\t\tfor (c = service->connections; c; c = c->next) {\n\t\t\t\t\t/* check for activity on the connection */\n\t\t\t\t\tFD_SET(c->fd, &read_fds);\n\t\t\t\t\tif (c->fd > fd_max)\n\t\t\t\t\t\tfd_max = c->fd;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tstruct timeval tv;\n\t\ttv.tv_sec = 0;\n\t\tif (poll_ok) {\n\t\t\t/* we're just polling this iteration, this is faster on embedded\n\t\t\t * hosts */\n\t\t\ttv.tv_usec = 0;\n\t\t\tretval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);\n\t\t} else {\n\t\t\t/* Timeout socket_select() when a target timer expires or every polling_period */\n\t\t\tint timeout_ms = next_event - timeval_ms();\n\t\t\tif (timeout_ms < 0)\n\t\t\t\ttimeout_ms = 0;\n\t\t\telse if (timeout_ms > polling_period)\n\t\t\t\ttimeout_ms = polling_period;\n\t\t\ttv.tv_usec = timeout_ms * 1000;\n\t\t\t/* Only while we're sleeping we'll let others run */\n\t\t\tretval = socket_select(fd_max + 1, &read_fds, NULL, NULL, &tv);\n\t\t}\n\n\t\tif (retval == -1) {\n#ifdef _WIN32\n\n\t\t\terrno = WSAGetLastError();\n\n\t\t\tif (errno == WSAEINTR)\n\t\t\t\tFD_ZERO(&read_fds);\n\t\t\telse {\n\t\t\t\tLOG_ERROR(\"error during select: %s\", strerror(errno));\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n#else\n\n\t\t\tif (errno == EINTR)\n\t\t\t\tFD_ZERO(&read_fds);\n\t\t\telse {\n\t\t\t\tLOG_ERROR(\"error during select: %s\", strerror(errno));\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n#endif\n\t\t}\n\n\t\tif (retval == 0) {\n\t\t\t/* Execute callbacks of expired timers when\n\t\t\t * - there was nothing to do if poll_ok was true\n\t\t\t * - socket_select() timed out if poll_ok was false, now one or more\n\t\t\t *   timers expired or the polling period elapsed\n\t\t\t */\n\t\t\ttarget_call_timer_callbacks();\n\t\t\tnext_event = target_timer_next_event();\n\t\t\tprocess_jim_events(command_context);\n\n\t\t\tFD_ZERO(&read_fds);\t/* eCos leaves read_fds unchanged in this case!  */\n\n\t\t\t/* We timed out/there was nothing to do, timeout rather than poll next time\n\t\t\t **/\n\t\t\tpoll_ok = false;\n\t\t} else {\n\t\t\t/* There was something to do, next time we'll just poll */\n\t\t\tpoll_ok = true;\n\t\t}\n\n\t\t/* This is a simple back-off algorithm where we immediately\n\t\t * re-poll if we did something this time around.\n\t\t *\n\t\t * This greatly improves performance of DCC.\n\t\t */\n\t\tpoll_ok = poll_ok || target_got_message();\n\n\t\tfor (service = services; service; service = service->next) {\n\t\t\t/* handle new connections on listeners */\n\t\t\tif ((service->fd != -1)\n\t\t\t\t&& (FD_ISSET(service->fd, &read_fds))) {\n\t\t\t\tif (service->max_connections != 0)\n\t\t\t\t\tadd_connection(service, command_context);\n\t\t\t\telse {\n\t\t\t\t\tif (service->type == CONNECTION_TCP) {\n\t\t\t\t\t\tstruct sockaddr_in sin;\n\t\t\t\t\t\tsocklen_t address_size = sizeof(sin);\n\t\t\t\t\t\tint tmp_fd;\n\t\t\t\t\t\ttmp_fd = accept(service->fd,\n\t\t\t\t\t\t\t\t(struct sockaddr *)&service->sin,\n\t\t\t\t\t\t\t\t&address_size);\n\t\t\t\t\t\tclose_socket(tmp_fd);\n\t\t\t\t\t}\n\t\t\t\t\tLOG_INFO(\n\t\t\t\t\t\t\"rejected '%s' connection, no more connections allowed\",\n\t\t\t\t\t\tservice->name);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* handle activity on connections */\n\t\t\tif (service->connections) {\n\t\t\t\tstruct connection *c;\n\n\t\t\t\tfor (c = service->connections; c; ) {\n\t\t\t\t\tif ((c->fd >= 0 && FD_ISSET(c->fd, &read_fds)) || c->input_pending) {\n\t\t\t\t\t\tretval = service->input(c);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tstruct connection *next = c->next;\n\t\t\t\t\t\t\tif (service->type == CONNECTION_PIPE ||\n\t\t\t\t\t\t\t\t\tservice->type == CONNECTION_STDINOUT) {\n\t\t\t\t\t\t\t\t/* if connection uses a pipe then\n\t\t\t\t\t\t\t\t * shutdown openocd on error */\n\t\t\t\t\t\t\t\tshutdown_openocd = SHUTDOWN_REQUESTED;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tremove_connection(service, c);\n\t\t\t\t\t\t\tLOG_INFO(\"dropped '%s' connection\",\n\t\t\t\t\t\t\t\tservice->name);\n\t\t\t\t\t\t\tc = next;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tc = c->next;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n#ifdef _WIN32\n\t\tMSG msg;\n\t\twhile (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\n\t\t\tif (msg.message == WM_QUIT)\n\t\t\t\tshutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;\n\t\t}\n#endif\n\t}\n\n\t/* when quit for signal or CTRL-C, run (eventually user implemented) \"shutdown\" */\n\tif (shutdown_openocd == SHUTDOWN_WITH_SIGNAL_CODE)\n\t\tcommand_run_line(command_context, \"shutdown\");\n\n\treturn shutdown_openocd == SHUTDOWN_WITH_ERROR_CODE ? ERROR_FAIL : ERROR_OK;\n}\n\nstatic void sig_handler(int sig)\n{\n\t/* store only first signal that hits us */\n\tif (shutdown_openocd == CONTINUE_MAIN_LOOP) {\n\t\tshutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;\n\t\tlast_signal = sig;\n\t\tLOG_DEBUG(\"Terminating on Signal %d\", sig);\n\t} else\n\t\tLOG_DEBUG(\"Ignored extra Signal %d\", sig);\n}\n\n\n#ifdef _WIN32\nBOOL WINAPI control_handler(DWORD ctrl_type)\n{\n\tshutdown_openocd = SHUTDOWN_WITH_SIGNAL_CODE;\n\treturn TRUE;\n}\n#else\nstatic void sigkey_handler(int sig)\n{\n\t/* ignore keystroke generated signals if not in foreground process group */\n\n\tif (tcgetpgrp(STDIN_FILENO) > 0)\n\t\tsig_handler(sig);\n\telse\n\t\tLOG_DEBUG(\"Ignored Signal %d\", sig);\n}\n#endif\n\n\nint server_host_os_entry(void)\n{\n\t/* this currently only calls WSAStartup on native win32 systems\n\t * before any socket operations are performed.\n\t * This is an issue if you call init in your config script */\n\n#ifdef _WIN32\n\tWORD version_requested;\n\tWSADATA wsadata;\n\n\tversion_requested = MAKEWORD(2, 2);\n\n\tif (WSAStartup(version_requested, &wsadata) != 0) {\n\t\tLOG_ERROR(\"Failed to Open Winsock\");\n\t\treturn ERROR_FAIL;\n\t}\n#endif\n\treturn ERROR_OK;\n}\n\nint server_host_os_close(void)\n{\n#ifdef _WIN32\n\tWSACleanup();\n#endif\n\treturn ERROR_OK;\n}\n\nint server_preinit(void)\n{\n#ifdef _WIN32\n\t/* register ctrl-c handler */\n\tSetConsoleCtrlHandler(control_handler, TRUE);\n\n\tsignal(SIGBREAK, sig_handler);\n\tsignal(SIGINT, sig_handler);\n#else\n\tsignal(SIGHUP, sig_handler);\n\tsignal(SIGPIPE, sig_handler);\n\tsignal(SIGQUIT, sigkey_handler);\n\tsignal(SIGINT, sigkey_handler);\n#endif\n\tsignal(SIGTERM, sig_handler);\n\tsignal(SIGABRT, sig_handler);\n\n\treturn ERROR_OK;\n}\n\nint server_init(struct command_context *cmd_ctx)\n{\n\tint ret = tcl_init();\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tret = telnet_init(\"Open On-Chip Debugger\");\n\n\tif (ret != ERROR_OK) {\n\t\tremove_services();\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint server_quit(void)\n{\n\tremove_services();\n\ttarget_quit();\n\n#ifdef _WIN32\n\tSetConsoleCtrlHandler(control_handler, FALSE);\n\n\treturn ERROR_OK;\n#endif\n\n\t/* return signal number so we can kill ourselves */\n\treturn last_signal;\n}\n\nvoid server_free(void)\n{\n\ttcl_service_free();\n\ttelnet_service_free();\n\tjsp_service_free();\n\n\tfree(bindto_name);\n}\n\nvoid exit_on_signal(int sig)\n{\n#ifndef _WIN32\n\t/* bring back default system handler and kill yourself */\n\tsignal(sig, SIG_DFL);\n\tkill(getpid(), sig);\n#endif\n}\n\nint connection_write(struct connection *connection, const void *data, int len)\n{\n\tif (len == 0) {\n\t\t/* successful no-op. Sockets and pipes behave differently here... */\n\t\treturn 0;\n\t}\n\tif (connection->service->type == CONNECTION_TCP)\n\t\treturn write_socket(connection->fd_out, data, len);\n\telse\n\t\treturn write(connection->fd_out, data, len);\n}\n\nint connection_read(struct connection *connection, void *data, int len)\n{\n\tif (connection->service->type == CONNECTION_TCP)\n\t\treturn read_socket(connection->fd, data, len);\n\telse\n\t\treturn read(connection->fd, data, len);\n}\n\nbool openocd_is_shutdown_pending(void)\n{\n\treturn shutdown_openocd != CONTINUE_MAIN_LOOP;\n}\n\n/* tell the server we want to shut down */\nCOMMAND_HANDLER(handle_shutdown_command)\n{\n\tLOG_USER(\"shutdown command invoked\");\n\n\tshutdown_openocd = SHUTDOWN_REQUESTED;\n\n\tcommand_run_line(CMD_CTX, \"_run_pre_shutdown_commands\");\n\n\tif (CMD_ARGC == 1) {\n\t\tif (!strcmp(CMD_ARGV[0], \"error\")) {\n\t\t\tshutdown_openocd = SHUTDOWN_WITH_ERROR_CODE;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_COMMAND_CLOSE_CONNECTION;\n}\n\nCOMMAND_HANDLER(handle_poll_period_command)\n{\n\tif (CMD_ARGC == 0)\n\t\tLOG_WARNING(\"You need to set a period value\");\n\telse\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], polling_period);\n\n\tLOG_INFO(\"set servers polling period to %ums\", polling_period);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_bindto_command)\n{\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tcommand_print(CMD, \"bindto name: %s\", bindto_name);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tfree(bindto_name);\n\t\t\tbindto_name = strdup(CMD_ARGV[0]);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration server_command_handlers[] = {\n\t{\n\t\t.name = \"shutdown\",\n\t\t.handler = &handle_shutdown_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"\",\n\t\t.help = \"shut the server down\",\n\t},\n\t{\n\t\t.name = \"poll_period\",\n\t\t.handler = &handle_poll_period_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"\",\n\t\t.help = \"set the servers polling period\",\n\t},\n\t{\n\t\t.name = \"bindto\",\n\t\t.handler = &handle_bindto_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"[name]\",\n\t\t.help = \"Specify address by name on which to listen for \"\n\t\t\t\"incoming TCP/IP connections\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint server_register_commands(struct command_context *cmd_ctx)\n{\n\tint retval = telnet_register_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = tcl_register_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jsp_register_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn register_commands(cmd_ctx, NULL, server_command_handlers);\n}\n\nCOMMAND_HELPER(server_port_command, unsigned short *out)\n{\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tcommand_print(CMD, \"%d\", *out);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t{\n\t\t\tuint16_t port;\n\t\t\tCOMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], port);\n\t\t\t*out = port;\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HELPER(server_pipe_command, char **out)\n{\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tcommand_print(CMD, \"%s\", *out);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t{\n\t\t\tif (CMD_CTX->mode == COMMAND_EXEC) {\n\t\t\t\tLOG_WARNING(\"unable to change server port after init\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\t\t\tfree(*out);\n\t\t\t*out = strdup(CMD_ARGV[0]);\n\t\t\tbreak;\n\t\t}\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_SERVER_SERVER_H\n#define OPENOCD_SERVER_SERVER_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/replacements.h>\n\n#ifdef HAVE_NETINET_IN_H\n#include <netinet/in.h>\n#endif\n\nenum connection_type {\n\tCONNECTION_TCP,\n\tCONNECTION_PIPE,\n\tCONNECTION_STDINOUT\n};\n\n#define CONNECTION_LIMIT_UNLIMITED\t\t(-1)\n\nstruct connection {\n\tint fd;\n\tint fd_out;\t/* When using pipes we're writing to a different fd */\n\tstruct sockaddr_in sin;\n\tstruct command_context *cmd_ctx;\n\tstruct service *service;\n\tbool input_pending;\n\tvoid *priv;\n\tstruct connection *next;\n};\n\nstruct service_driver {\n\t/** the name of the server */\n\tconst char *name;\n\t/** optional minimal setup to accept a connection during keep-alive */\n\tint (*new_connection_during_keep_alive_handler)(struct connection *connection);\n\t/**\n\t * complete code to accept a new connection.\n\t * If 'new_connection_during_keep_alive_handler' above is present, this can be\n\t * either called alone during the server_loop, or after the function above.\n\t * Check the implementation in gdb_server.\n\t * */\n\tint (*new_connection_handler)(struct connection *connection);\n\t/** callback to handle incoming data */\n\tint (*input_handler)(struct connection *connection);\n\t/** callback to tear down the connection */\n\tint (*connection_closed_handler)(struct connection *connection);\n\t/** called periodically to send keep-alive messages on the connection */\n\tvoid (*keep_client_alive_handler)(struct connection *connection);\n};\n\nstruct service {\n\tchar *name;\n\tenum connection_type type;\n\tchar *port;\n\tunsigned short portnumber;\n\tint fd;\n\tstruct sockaddr_in sin;\n\tint max_connections;\n\tstruct connection *connections;\n\tint (*new_connection_during_keep_alive)(struct connection *connection);\n\tint (*new_connection)(struct connection *connection);\n\tint (*input)(struct connection *connection);\n\tint (*connection_closed)(struct connection *connection);\n\tvoid (*keep_client_alive)(struct connection *connection);\n\tvoid *priv;\n\tstruct service *next;\n};\n\nint add_service(const struct service_driver *driver, const char *port,\n\t\tint max_connections, void *priv);\nint remove_service(const char *name, const char *port);\n\nint server_host_os_entry(void);\nint server_host_os_close(void);\n\nint server_preinit(void);\nint server_init(struct command_context *cmd_ctx);\nint server_quit(void);\nvoid server_free(void);\nvoid exit_on_signal(int sig);\n\nvoid server_keep_clients_alive(void);\n\nint server_loop(struct command_context *command_context);\n\nint server_register_commands(struct command_context *context);\n\nint connection_write(struct connection *connection, const void *data, int len);\nint connection_read(struct connection *connection, void *data, int len);\n\nbool openocd_is_shutdown_pending(void);\n\n/**\n * Defines an extended command handler function declaration to enable\n * access to (and manipulation of) the server port number.\n * Call server_port like a normal COMMAND_HANDLER with an extra @a out parameter\n * to receive the specified port number.\n */\nCOMMAND_HELPER(server_pipe_command, char **out);\n\nCOMMAND_HELPER(server_port_command, unsigned short *out);\n\n#define ERROR_SERVER_REMOTE_CLOSED\t\t(-400)\n#define ERROR_CONNECTION_REJECTED\t\t(-401)\n\n#endif /* OPENOCD_SERVER_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/startup.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Defines basic Tcl procs for OpenOCD server modules\n\n# Handle GDB 'R' packet. Can be overridden by configuration script,\n# but it's not something one would expect target scripts to do\n# normally\nproc ocd_gdb_restart {target_id} {\n\t# Fix!!! we're resetting all targets here! Really we should reset only\n\t# one target\n\treset halt\n}\n\nlappend _telnet_autocomplete_skip prevent_cps\nlappend _telnet_autocomplete_skip POST\nlappend _telnet_autocomplete_skip Host:\nproc prevent_cps {} {\n\techo \"Possible SECURITY ATTACK detected.\"\n\techo \"It looks like somebody is sending POST or Host: commands to OpenOCD.\"\n\techo \"This is likely due to an attacker attempting to use Cross Protocol Scripting\"\n\techo \"to compromise your OpenOCD instance. Connection aborted.\"\n\texit\n}\n\nproc POST {args} { prevent_cps }\nproc Host: {args} { prevent_cps }\n\n# list of commands we don't want to appear in autocomplete\nlappend _telnet_autocomplete_skip _telnet_autocomplete_helper\n\n# helper for telnet autocomplete\nproc _telnet_autocomplete_helper pattern {\n\tset cmds [info commands $pattern]\n\n\t# skip matches in variable '_telnet_autocomplete_skip'\n\tforeach skip $::_telnet_autocomplete_skip {\n\t\tforeach n [lsearch -all -regexp $cmds \"^$skip\\$\"] {\n\t\t\tset cmds [lreplace $cmds $n $n]\n\t\t}\n\t}\n\n\treturn [lsort $cmds]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/tcl_server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"tcl_server.h\"\n#include <target/target.h>\n#include <helper/binarybuffer.h>\n\n#define TCL_SERVER_VERSION\t\t\"TCL Server 0.1\"\n#define TCL_LINE_INITIAL\t\t(4*1024)\n#define TCL_LINE_MAX\t\t\t(4*1024*1024)\n\nstruct tcl_connection {\n\tint tc_linedrop;\n\tint tc_lineoffset;\n\tint tc_line_size;\n\tchar *tc_line;\n\tint tc_outerror;/* flag an output error */\n\tenum target_state tc_laststate;\n\tbool tc_notify;\n\tbool tc_trace;\n};\n\nstatic char *tcl_port;\n\n/* handlers */\nstatic int tcl_new_connection(struct connection *connection);\nstatic int tcl_input(struct connection *connection);\nstatic int tcl_output(struct connection *connection, const void *buf, ssize_t len);\nstatic int tcl_closed(struct connection *connection);\n\nstatic int tcl_target_callback_event_handler(struct target *target,\n\t\tenum target_event event, void *priv)\n{\n\tstruct connection *connection = priv;\n\tstruct tcl_connection *tclc;\n\tchar buf[256];\n\n\ttclc = connection->priv;\n\n\tif (tclc->tc_notify) {\n\t\tsnprintf(buf, sizeof(buf), \"type target_event event %s\\r\\n\\x1a\", target_event_name(event));\n\t\ttcl_output(connection, buf, strlen(buf));\n\t}\n\n\tif (tclc->tc_laststate != target->state) {\n\t\ttclc->tc_laststate = target->state;\n\t\tif (tclc->tc_notify) {\n\t\t\tsnprintf(buf, sizeof(buf), \"type target_state state %s\\r\\n\\x1a\", target_state_name(target));\n\t\t\ttcl_output(connection, buf, strlen(buf));\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int tcl_target_callback_reset_handler(struct target *target,\n\t\tenum target_reset_mode reset_mode, void *priv)\n{\n\tstruct connection *connection = priv;\n\tstruct tcl_connection *tclc;\n\tchar buf[256];\n\n\ttclc = connection->priv;\n\n\tif (tclc->tc_notify) {\n\t\tsnprintf(buf, sizeof(buf), \"type target_reset mode %s\\r\\n\\x1a\", target_reset_mode_name(reset_mode));\n\t\ttcl_output(connection, buf, strlen(buf));\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int tcl_target_callback_trace_handler(struct target *target,\n\t\tsize_t len, uint8_t *data, void *priv)\n{\n\tstruct connection *connection = priv;\n\tstruct tcl_connection *tclc;\n\tchar *header = \"type target_trace data \";\n\tchar *trailer = \"\\r\\n\\x1a\";\n\tsize_t hex_len = len * 2 + 1;\n\tsize_t max_len = hex_len + strlen(header) + strlen(trailer);\n\tchar *buf, *hex;\n\n\ttclc = connection->priv;\n\n\tif (tclc->tc_trace) {\n\t\thex = malloc(hex_len);\n\t\tbuf = malloc(max_len);\n\t\thexify(hex, data, len, hex_len);\n\t\tsnprintf(buf, max_len, \"%s%s%s\", header, hex, trailer);\n\t\ttcl_output(connection, buf, strlen(buf));\n\t\tfree(hex);\n\t\tfree(buf);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* write data out to a socket.\n *\n * this is a blocking write, so the return value must equal the length, if\n * that is not the case then flag the connection with an output error.\n */\nint tcl_output(struct connection *connection, const void *data, ssize_t len)\n{\n\tssize_t wlen;\n\tstruct tcl_connection *tclc;\n\n\ttclc = connection->priv;\n\tif (tclc->tc_outerror)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\twlen = connection_write(connection, data, len);\n\n\tif (wlen == len)\n\t\treturn ERROR_OK;\n\n\tLOG_ERROR(\"error during write: %d != %d\", (int)wlen, (int)len);\n\ttclc->tc_outerror = 1;\n\treturn ERROR_SERVER_REMOTE_CLOSED;\n}\n\n/* connections */\nstatic int tcl_new_connection(struct connection *connection)\n{\n\tstruct tcl_connection *tclc;\n\n\ttclc = calloc(1, sizeof(struct tcl_connection));\n\tif (!tclc)\n\t\treturn ERROR_CONNECTION_REJECTED;\n\n\ttclc->tc_line_size = TCL_LINE_INITIAL;\n\ttclc->tc_line = malloc(tclc->tc_line_size);\n\tif (!tclc->tc_line) {\n\t\tfree(tclc);\n\t\treturn ERROR_CONNECTION_REJECTED;\n\t}\n\n\tconnection->priv = tclc;\n\n\tstruct target *target = get_current_target_or_null(connection->cmd_ctx);\n\tif (target)\n\t\ttclc->tc_laststate = target->state;\n\n\t/* store the connection object on cmd_ctx so we can access it from command handlers */\n\tconnection->cmd_ctx->output_handler_priv = connection;\n\n\ttarget_register_event_callback(tcl_target_callback_event_handler, connection);\n\ttarget_register_reset_callback(tcl_target_callback_reset_handler, connection);\n\ttarget_register_trace_callback(tcl_target_callback_trace_handler, connection);\n\n\treturn ERROR_OK;\n}\n\nstatic int tcl_input(struct connection *connection)\n{\n\tJim_Interp *interp = (Jim_Interp *)connection->cmd_ctx->interp;\n\tint retval;\n\tint i;\n\tssize_t rlen;\n\tconst char *result;\n\tint reslen;\n\tstruct tcl_connection *tclc;\n\tunsigned char in[256];\n\tchar *tc_line_new;\n\tint tc_line_size_new;\n\n\trlen = connection_read(connection, &in, sizeof(in));\n\tif (rlen <= 0) {\n\t\tif (rlen < 0)\n\t\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\ttclc = connection->priv;\n\tif (!tclc)\n\t\treturn ERROR_CONNECTION_REJECTED;\n\n\t/* push as much data into the line as possible */\n\tfor (i = 0; i < rlen; i++) {\n\t\t/* buffer the data */\n\t\ttclc->tc_line[tclc->tc_lineoffset] = in[i];\n\t\tif (tclc->tc_lineoffset + 1 < tclc->tc_line_size) {\n\t\t\ttclc->tc_lineoffset++;\n\t\t} else if (tclc->tc_line_size >= TCL_LINE_MAX) {\n\t\t\t/* maximum line size reached, drop line */\n\t\t\ttclc->tc_linedrop = 1;\n\t\t} else {\n\t\t\t/* grow line buffer: exponential below 1 MB, linear above */\n\t\t\tif (tclc->tc_line_size <= 1*1024*1024)\n\t\t\t\ttc_line_size_new = tclc->tc_line_size * 2;\n\t\t\telse\n\t\t\t\ttc_line_size_new = tclc->tc_line_size + 1*1024*1024;\n\n\t\t\tif (tc_line_size_new > TCL_LINE_MAX)\n\t\t\t\ttc_line_size_new = TCL_LINE_MAX;\n\n\t\t\ttc_line_new = realloc(tclc->tc_line, tc_line_size_new);\n\t\t\tif (!tc_line_new) {\n\t\t\t\ttclc->tc_linedrop = 1;\n\t\t\t} else {\n\t\t\t\ttclc->tc_line = tc_line_new;\n\t\t\t\ttclc->tc_line_size = tc_line_size_new;\n\t\t\t\ttclc->tc_lineoffset++;\n\t\t\t}\n\n\t\t}\n\n\t\t/* ctrl-z is end of command. When testing from telnet, just\n\t\t * press ctrl-z a couple of times first to put telnet into the\n\t\t * mode where it will send 0x1a in response to pressing ctrl-z\n\t\t */\n\t\tif (in[i] != '\\x1a')\n\t\t\tcontinue;\n\n\t\t/* process the line */\n\t\tif (tclc->tc_linedrop) {\n#define ESTR \"line too long\\n\"\n\t\t\tretval = tcl_output(connection, ESTR, sizeof(ESTR));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n#undef ESTR\n\t\t} else {\n\t\t\ttclc->tc_line[tclc->tc_lineoffset-1] = '\\0';\n\t\t\tcommand_run_line(connection->cmd_ctx, tclc->tc_line);\n\t\t\tresult = Jim_GetString(Jim_GetResult(interp), &reslen);\n\t\t\tretval = tcl_output(connection, result, reslen);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* Always output ctrl-z as end of line to allow multiline results */\n\t\t\ttcl_output(connection, \"\\x1a\", 1);\n\t\t}\n\n\t\ttclc->tc_lineoffset = 0;\n\t\ttclc->tc_linedrop = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int tcl_closed(struct connection *connection)\n{\n\tstruct tcl_connection *tclc;\n\ttclc = connection->priv;\n\n\t/* cleanup connection context */\n\tif (tclc) {\n\t\tfree(tclc->tc_line);\n\t\tfree(tclc);\n\t\tconnection->priv = NULL;\n\t}\n\n\ttarget_unregister_event_callback(tcl_target_callback_event_handler, connection);\n\ttarget_unregister_reset_callback(tcl_target_callback_reset_handler, connection);\n\ttarget_unregister_trace_callback(tcl_target_callback_trace_handler, connection);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct service_driver tcl_service_driver = {\n\t.name = \"tcl\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = tcl_new_connection,\n\t.input_handler = tcl_input,\n\t.connection_closed_handler = tcl_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nint tcl_init(void)\n{\n\tif (strcmp(tcl_port, \"disabled\") == 0) {\n\t\tLOG_INFO(\"tcl server disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\treturn add_service(&tcl_service_driver, tcl_port, CONNECTION_LIMIT_UNLIMITED, NULL);\n}\n\nCOMMAND_HANDLER(handle_tcl_port_command)\n{\n\treturn CALL_COMMAND_HANDLER(server_pipe_command, &tcl_port);\n}\n\nCOMMAND_HANDLER(handle_tcl_notifications_command)\n{\n\tstruct connection *connection = NULL;\n\tstruct tcl_connection *tclc = NULL;\n\n\tif (CMD_CTX->output_handler_priv)\n\t\tconnection = CMD_CTX->output_handler_priv;\n\n\tif (connection && !strcmp(connection->service->name, \"tcl\")) {\n\t\ttclc = connection->priv;\n\t\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_notify, \"Target Notification output \");\n\t} else {\n\t\tLOG_ERROR(\"%s: can only be called from the tcl server\", CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n}\n\nCOMMAND_HANDLER(handle_tcl_trace_command)\n{\n\tstruct connection *connection = NULL;\n\tstruct tcl_connection *tclc = NULL;\n\n\tif (CMD_CTX->output_handler_priv)\n\t\tconnection = CMD_CTX->output_handler_priv;\n\n\tif (connection && !strcmp(connection->service->name, \"tcl\")) {\n\t\ttclc = connection->priv;\n\t\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool, &tclc->tc_trace, \"Target trace output \");\n\t} else {\n\t\tLOG_ERROR(\"%s: can only be called from the tcl server\", CMD_NAME);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n}\n\nstatic const struct command_registration tcl_command_handlers[] = {\n\t{\n\t\t.name = \"tcl_port\",\n\t\t.handler = handle_tcl_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Specify port on which to listen \"\n\t\t\t\"for incoming Tcl syntax.  \"\n\t\t\t\"Read help on 'gdb_port'.\",\n\t\t.usage = \"[port_num]\",\n\t},\n\t{\n\t\t.name = \"tcl_notifications\",\n\t\t.handler = handle_tcl_notifications_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Target Notification output\",\n\t\t.usage = \"[on|off]\",\n\t},\n\t{\n\t\t.name = \"tcl_trace\",\n\t\t.handler = handle_tcl_trace_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Target trace output\",\n\t\t.usage = \"[on|off]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint tcl_register_commands(struct command_context *cmd_ctx)\n{\n\ttcl_port = strdup(\"6666\");\n\treturn register_commands(cmd_ctx, NULL, tcl_command_handlers);\n}\n\nvoid tcl_service_free(void)\n{\n\tfree(tcl_port);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/tcl_server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008                                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_SERVER_TCL_SERVER_H\n#define OPENOCD_SERVER_TCL_SERVER_H\n\n#include <server/server.h>\n\nint tcl_init(void);\nint tcl_register_commands(struct command_context *cmd_ctx);\nvoid tcl_service_free(void);\n\n#endif /* OPENOCD_SERVER_TCL_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/telnet_server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"telnet_server.h\"\n#include <target/target_request.h>\n#include <helper/configuration.h>\n#include <helper/list.h>\n\nstatic char *telnet_port;\n\nstatic char *negotiate =\n\t\"\\xFF\\xFB\\x03\"\t\t\t/* IAC WILL Suppress Go Ahead */\n\t\"\\xFF\\xFB\\x01\"\t\t\t/* IAC WILL Echo */\n\t\"\\xFF\\xFD\\x03\"\t\t\t/* IAC DO Suppress Go Ahead */\n\t\"\\xFF\\xFE\\x01\";\t\t\t/* IAC DON'T Echo */\n\n#define CTRL(c) (c - '@')\n#define TELNET_HISTORY\t\".openocd_history\"\n\n/* The only way we can detect that the socket is closed is the first time\n * we write to it, we will fail. Subsequent write operations will\n * succeed. Shudder!\n */\nstatic int telnet_write(struct connection *connection, const void *data,\n\tint len)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tif (t_con->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\tif (connection_write(connection, data, len) == len)\n\t\treturn ERROR_OK;\n\tt_con->closed = true;\n\treturn ERROR_SERVER_REMOTE_CLOSED;\n}\n\n/* output an audible bell */\nstatic int telnet_bell(struct connection *connection)\n{\n\t/* (\"\\a\" does not work, at least on windows) */\n\treturn telnet_write(connection, \"\\x07\", 1);\n}\n\nstatic int telnet_prompt(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\treturn telnet_write(connection, t_con->prompt, strlen(t_con->prompt));\n}\n\nstatic int telnet_outputline(struct connection *connection, const char *line)\n{\n\tint len;\n\n\t/* process lines in buffer */\n\twhile (*line) {\n\t\tchar *line_end = strchr(line, '\\n');\n\n\t\tif (line_end)\n\t\t\tlen = line_end-line;\n\t\telse\n\t\t\tlen = strlen(line);\n\n\t\ttelnet_write(connection, line, len);\n\t\tif (line_end) {\n\t\t\ttelnet_write(connection, \"\\r\\n\", 2);\n\t\t\tline += len + 1;\n\t\t} else\n\t\t\tline += len;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int telnet_output(struct command_context *cmd_ctx, const char *line)\n{\n\tstruct connection *connection = cmd_ctx->output_handler_priv;\n\n\treturn telnet_outputline(connection, line);\n}\n\nstatic void telnet_log_callback(void *priv, const char *file, unsigned line,\n\tconst char *function, const char *string)\n{\n\tstruct connection *connection = priv;\n\tstruct telnet_connection *t_con = connection->priv;\n\tsize_t i;\n\tsize_t tmp;\n\n\t/* If the prompt is not visible, simply output the message. */\n\tif (!t_con->prompt_visible) {\n\t\ttelnet_outputline(connection, string);\n\t\treturn;\n\t}\n\n\t/* Clear the command line. */\n\ttmp = strlen(t_con->prompt) + t_con->line_size;\n\n\tfor (i = 0; i < tmp; i += 16)\n\t\ttelnet_write(connection, \"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\",\n\t\t\tMIN(tmp - i, 16));\n\n\tfor (i = 0; i < tmp; i += 16)\n\t\ttelnet_write(connection, \"                \", MIN(tmp - i, 16));\n\n\tfor (i = 0; i < tmp; i += 16)\n\t\ttelnet_write(connection, \"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\",\n\t\t\tMIN(tmp - i, 16));\n\n\ttelnet_outputline(connection, string);\n\n\t/* Put the command line to its previous state. */\n\ttelnet_prompt(connection);\n\ttelnet_write(connection, t_con->line, t_con->line_size);\n\n\tfor (i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\ttelnet_write(connection, \"\\b\", 1);\n}\n\nstatic void telnet_load_history(struct telnet_connection *t_con)\n{\n\tFILE *histfp;\n\tchar buffer[TELNET_BUFFER_SIZE];\n\tint i = 0;\n\n\tchar *history = get_home_dir(TELNET_HISTORY);\n\n\tif (!history) {\n\t\tLOG_INFO(\"unable to get user home directory, telnet history will be disabled\");\n\t\treturn;\n\t}\n\n\thistfp = fopen(history, \"rb\");\n\n\tif (histfp) {\n\n\t\twhile (fgets(buffer, sizeof(buffer), histfp)) {\n\n\t\t\tchar *p = strchr(buffer, '\\n');\n\t\t\tif (p)\n\t\t\t\t*p = '\\0';\n\t\t\tif (buffer[0] && i < TELNET_LINE_HISTORY_SIZE)\n\t\t\t\tt_con->history[i++] = strdup(buffer);\n\t\t}\n\n\t\tt_con->next_history = i;\n\t\tt_con->next_history %= TELNET_LINE_HISTORY_SIZE;\n\t\t/* try to set to last entry - 1, that way we skip over any exit/shutdown cmds */\n\t\tt_con->current_history = t_con->next_history > 0 ? i - 1 : 0;\n\t\tfclose(histfp);\n\t}\n\n\tfree(history);\n}\n\nstatic void telnet_save_history(struct telnet_connection *t_con)\n{\n\tFILE *histfp;\n\tint i;\n\tint num;\n\n\tchar *history = get_home_dir(TELNET_HISTORY);\n\n\tif (!history) {\n\t\tLOG_INFO(\"unable to get user home directory, telnet history will be disabled\");\n\t\treturn;\n\t}\n\n\thistfp = fopen(history, \"wb\");\n\n\tif (histfp) {\n\n\t\tnum = TELNET_LINE_HISTORY_SIZE;\n\t\ti = t_con->current_history + 1;\n\t\ti %= TELNET_LINE_HISTORY_SIZE;\n\n\t\twhile (!t_con->history[i] && num > 0) {\n\t\t\ti++;\n\t\t\ti %= TELNET_LINE_HISTORY_SIZE;\n\t\t\tnum--;\n\t\t}\n\n\t\tif (num > 0) {\n\t\t\tfor (; num > 0; num--) {\n\t\t\t\tfprintf(histfp, \"%s\\n\", t_con->history[i]);\n\t\t\t\ti++;\n\t\t\t\ti %= TELNET_LINE_HISTORY_SIZE;\n\t\t\t}\n\t\t}\n\t\tfclose(histfp);\n\t}\n\n\tfree(history);\n}\n\nstatic int telnet_new_connection(struct connection *connection)\n{\n\tstruct telnet_connection *telnet_connection;\n\tstruct telnet_service *telnet_service = connection->service->priv;\n\n\ttelnet_connection = calloc(1, sizeof(struct telnet_connection));\n\n\tif (!telnet_connection) {\n\t\tLOG_ERROR(\"Failed to allocate telnet connection.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tconnection->priv = telnet_connection;\n\n\t/* initialize telnet connection information */\n\ttelnet_connection->prompt = strdup(\"> \");\n\ttelnet_connection->prompt_visible = true;\n\ttelnet_connection->state = TELNET_STATE_DATA;\n\n\t/* output goes through telnet connection */\n\tcommand_set_output_handler(connection->cmd_ctx, telnet_output, connection);\n\n\t/* negotiate telnet options */\n\ttelnet_write(connection, negotiate, strlen(negotiate));\n\n\t/* print connection banner */\n\tif (telnet_service->banner) {\n\t\ttelnet_write(connection, telnet_service->banner, strlen(telnet_service->banner));\n\t\ttelnet_write(connection, \"\\r\\n\", 2);\n\t}\n\n\t/* the prompt is always placed at the line beginning */\n\ttelnet_write(connection, \"\\r\", 1);\n\ttelnet_prompt(connection);\n\n\ttelnet_load_history(telnet_connection);\n\n\tlog_add_callback(telnet_log_callback, connection);\n\n\treturn ERROR_OK;\n}\n\nstatic void telnet_clear_line(struct connection *connection,\n\tstruct telnet_connection *t_con)\n{\n\t/* move to end of line */\n\tif (t_con->line_cursor < t_con->line_size)\n\t\ttelnet_write(connection,\n\t\t\tt_con->line + t_con->line_cursor,\n\t\t\tt_con->line_size - t_con->line_cursor);\n\n\t/* backspace, overwrite with space, backspace */\n\twhile (t_con->line_size > 0) {\n\t\ttelnet_write(connection, \"\\b \\b\", 3);\n\t\tt_con->line_size--;\n\t}\n\tt_con->line_cursor = 0;\n}\n\nstatic void telnet_history_go(struct connection *connection, int idx)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tif (t_con->history[idx]) {\n\t\ttelnet_clear_line(connection, t_con);\n\t\tt_con->line_size = strlen(t_con->history[idx]);\n\t\tt_con->line_cursor = t_con->line_size;\n\t\tmemcpy(t_con->line, t_con->history[idx], t_con->line_size);\n\t\ttelnet_write(connection, t_con->line, t_con->line_size);\n\t\tt_con->current_history = idx;\n\t}\n\tt_con->state = TELNET_STATE_DATA;\n}\n\nstatic void telnet_history_up(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tsize_t last_history = (t_con->current_history > 0) ?\n\t\t\t\tt_con->current_history - 1 :\n\t\t\t\tTELNET_LINE_HISTORY_SIZE-1;\n\ttelnet_history_go(connection, last_history);\n}\n\nstatic void telnet_history_down(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tsize_t next_history;\n\n\tnext_history = (t_con->current_history + 1) % TELNET_LINE_HISTORY_SIZE;\n\ttelnet_history_go(connection, next_history);\n}\n\nstatic void telnet_history_add(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\t/* save only non-blank not repeating lines in the history */\n\tchar *prev_line = t_con->history[(t_con->current_history > 0) ?\n\t\t\tt_con->current_history - 1 : TELNET_LINE_HISTORY_SIZE-1];\n\n\tif (*t_con->line && (!prev_line || strcmp(t_con->line, prev_line))) {\n\t\t/* if the history slot is already taken, free it */\n\t\tfree(t_con->history[t_con->next_history]);\n\n\t\t/* add line to history */\n\t\tt_con->history[t_con->next_history] = strdup(t_con->line);\n\n\t\t/* wrap history at TELNET_LINE_HISTORY_SIZE */\n\t\tt_con->next_history = (t_con->next_history + 1) % TELNET_LINE_HISTORY_SIZE;\n\n\t\t/* current history line starts at the new entry */\n\t\tt_con->current_history = t_con->next_history;\n\n\t\tfree(t_con->history[t_con->current_history]);\n\t\tt_con->history[t_con->current_history] = strdup(\"\");\n\t}\n}\n\nstatic int telnet_history_print(struct connection *connection)\n{\n\tstruct telnet_connection *tc;\n\n\ttc = connection->priv;\n\n\tfor (size_t i = 1; i < TELNET_LINE_HISTORY_SIZE; i++) {\n\t\tchar *line;\n\n\t\t/*\n\t\t * The tc->next_history line contains empty string (unless NULL), thus\n\t\t * it is not printed.\n\t\t */\n\t\tline = tc->history[(tc->next_history + i) % TELNET_LINE_HISTORY_SIZE];\n\n\t\tif (line) {\n\t\t\ttelnet_write(connection, line, strlen(line));\n\t\t\ttelnet_write(connection, \"\\r\\n\\x00\", 3);\n\t\t}\n\t}\n\n\ttc->line_size = 0;\n\ttc->line_cursor = 0;\n\n\t/* The prompt is always placed at the line beginning. */\n\ttelnet_write(connection, \"\\r\", 1);\n\n\treturn telnet_prompt(connection);\n}\n\nstatic void telnet_move_cursor(struct connection *connection, size_t pos)\n{\n\tstruct telnet_connection *tc = connection->priv;\n\tsize_t tmp;\n\n\tif (pos == tc->line_cursor) /* nothing to do */\n\t\treturn;\n\n\tif (pos > tc->line_size) /* out of bounds */\n\t\treturn;\n\n\tif (pos < tc->line_cursor) {\n\t\ttmp = tc->line_cursor - pos;\n\n\t\tfor (size_t i = 0; i < tmp; i += 16)\n\t\t\ttelnet_write(connection, \"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\",\n\t\t\t\tMIN(tmp - i, 16));\n\t} else {\n\t\ttmp = pos - tc->line_cursor;\n\n\t\tfor (size_t i = 0; i < tmp; i += 16)\n\t\t\ttelnet_write(connection, tc->line + tc->line_cursor + i,\n\t\t\t\tMIN(tmp - i, 16));\n\t}\n\n\ttc->line_cursor = pos;\n}\n\n/* check buffer size leaving one spare character for string null termination */\nstatic inline bool telnet_can_insert(struct connection *connection, size_t len)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\treturn t_con->line_size + len < TELNET_LINE_MAX_SIZE;\n}\n\n/* write to telnet console, and update the telnet_connection members\n * this function is capable of inserting in the middle of a line\n * please ensure that data does not contain special characters (\\n, \\r, \\t, \\b ...)\n *\n * returns false when it fails to insert the requested data\n */\nstatic bool telnet_insert(struct connection *connection, const void *data, size_t len)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tif (!telnet_can_insert(connection, len)) {\n\t\ttelnet_bell(connection);\n\t\treturn false;\n\t}\n\n\tif (t_con->line_cursor < t_con->line_size) {\n\t\t/* we have some content after the cursor */\n\t\tmemmove(t_con->line + t_con->line_cursor + len,\n\t\t\t\tt_con->line + t_con->line_cursor,\n\t\t\t\tt_con->line_size - t_con->line_cursor);\n\t}\n\n\tstrncpy(t_con->line + t_con->line_cursor, data, len);\n\n\ttelnet_write(connection,\n\t\t\tt_con->line + t_con->line_cursor,\n\t\t\tt_con->line_size + len - t_con->line_cursor);\n\n\tt_con->line_size += len;\n\tt_con->line_cursor += len;\n\n\tfor (size_t i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\ttelnet_write(connection, \"\\b\", 1);\n\n\treturn true;\n}\n\nstatic void telnet_delete_character(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tif (t_con->line_cursor == 0)\n\t\treturn;\n\n\tif (t_con->line_cursor != t_con->line_size) {\n\t\tsize_t i;\n\t\ttelnet_write(connection, \"\\b\", 1);\n\t\tt_con->line_cursor--;\n\t\tt_con->line_size--;\n\t\tmemmove(t_con->line + t_con->line_cursor,\n\t\t\t\tt_con->line + t_con->line_cursor + 1,\n\t\t\t\tt_con->line_size -\n\t\t\t\tt_con->line_cursor);\n\n\t\ttelnet_write(connection,\n\t\t\t\tt_con->line + t_con->line_cursor,\n\t\t\t\tt_con->line_size -\n\t\t\t\tt_con->line_cursor);\n\t\ttelnet_write(connection, \" \\b\", 2);\n\t\tfor (i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\t\ttelnet_write(connection, \"\\b\", 1);\n\t} else {\n\t\tt_con->line_size--;\n\t\tt_con->line_cursor--;\n\t\t/* back space: move the 'printer' head one char\n\t\t * back, overwrite with space, move back again */\n\t\ttelnet_write(connection, \"\\b \\b\", 3);\n\t}\n}\n\nstatic void telnet_remove_character(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tif (t_con->line_cursor < t_con->line_size) {\n\t\tsize_t i;\n\t\tt_con->line_size--;\n\t\t/* remove char from line buffer */\n\t\tmemmove(t_con->line + t_con->line_cursor,\n\t\t\t\tt_con->line + t_con->line_cursor + 1,\n\t\t\t\tt_con->line_size - t_con->line_cursor);\n\n\t\t/* print remainder of buffer */\n\t\ttelnet_write(connection, t_con->line + t_con->line_cursor,\n\t\t\t\tt_con->line_size - t_con->line_cursor);\n\t\t/* overwrite last char with whitespace */\n\t\ttelnet_write(connection, \" \\b\", 2);\n\n\t\t/* move back to cursor position*/\n\t\tfor (i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\t\ttelnet_write(connection, \"\\b\", 1);\n\t}\n}\n\nstatic int telnet_exec_line(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tstruct command_context *command_context = connection->cmd_ctx;\n\tint retval;\n\n\ttelnet_write(connection, \"\\r\\n\\x00\", 3);\n\n\tif (strcmp(t_con->line, \"history\") == 0) {\n\t\tretval = telnet_history_print(connection);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\treturn ERROR_OK;\n\t}\n\n\ttelnet_history_add(connection);\n\n\tt_con->line_size = 0;\n\n\t/* to suppress prompt in log callback during command execution */\n\tt_con->prompt_visible = false;\n\n\tif (strcmp(t_con->line, \"shutdown\") == 0)\n\t\ttelnet_save_history(t_con);\n\n\tretval = command_run_line(command_context, t_con->line);\n\n\tt_con->line_cursor = 0;\n\tt_con->prompt_visible = true;\n\n\tif (retval == ERROR_COMMAND_CLOSE_CONNECTION)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\t/* the prompt is always placed at the line beginning */\n\ttelnet_write(connection, \"\\r\", 1);\n\n\tretval = telnet_prompt(connection);\n\tif (retval == ERROR_SERVER_REMOTE_CLOSED)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\treturn ERROR_OK;\n}\n\nstatic void telnet_cut_line_to_end(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\t/* FIXME: currently this function does not save to clipboard */\n\n\tif (t_con->line_cursor < t_con->line_size) {\n\t\t/* overwrite with space, until end of line, move back */\n\t\tfor (size_t i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\t\ttelnet_write(connection, \" \", 1);\n\t\tfor (size_t i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\t\ttelnet_write(connection, \"\\b\", 1);\n\t\tt_con->line[t_con->line_cursor] = '\\0';\n\t\tt_con->line_size = t_con->line_cursor;\n\t}\n}\n\nstatic void telnet_interrupt(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\n\t/* print '^C' at line end, and display a new command prompt */\n\ttelnet_move_cursor(connection, t_con->line_size);\n\ttelnet_write(connection, \"^C\\n\\r\", 4);\n\tt_con->line_cursor = 0;\n\tt_con->line_size = 0;\n\ttelnet_prompt(connection);\n}\n\nstatic void telnet_auto_complete(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tstruct command_context *command_context = connection->cmd_ctx;\n\n\tstruct cmd_match {\n\t\tchar *cmd;\n\t\tstruct list_head lh;\n\t};\n\n\tLIST_HEAD(matches);\n\n\t/* - user command sequence, either at line beginning\n\t *   or we start over after these characters ';', '[', '{'\n\t * - user variable sequence, start after the character '$'\n\t *   and do not contain white spaces */\n\tbool is_variable_auto_completion = false;\n\tbool have_spaces = false;\n\tsize_t seq_start = (t_con->line_cursor == 0) ? 0 : (t_con->line_cursor - 1);\n\twhile (1) {\n\t\tchar c = t_con->line[seq_start];\n\n\t\tif (c == ';' || c == '[' || c == '{') {\n\t\t\tseq_start++;\n\t\t\tbreak;\n\t\t} else if (c == ' ') {\n\t\t\thave_spaces = true;\n\t\t} else if (c == '$' && !have_spaces) {\n\t\t\tis_variable_auto_completion = true;\n\t\t\tseq_start++;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (seq_start == 0)\n\t\t\tbreak;\n\n\t\tseq_start--;\n\t}\n\n\t/* user command position in the line, ignore leading spaces */\n\tsize_t usr_cmd_pos = seq_start;\n\twhile ((usr_cmd_pos < t_con->line_cursor) && isspace(t_con->line[usr_cmd_pos]))\n\t\tusr_cmd_pos++;\n\n\t/* check user command length */\n\tif (t_con->line_cursor < usr_cmd_pos) {\n\t\ttelnet_bell(connection);\n\t\treturn;\n\t}\n\tsize_t usr_cmd_len = t_con->line_cursor - usr_cmd_pos;\n\n\t/* optimize multiple spaces in the user command,\n\t * because info commands does not tolerate multiple spaces */\n\tsize_t optimized_spaces = 0;\n\tchar query[usr_cmd_len + 1];\n\tfor (size_t i = 0; i < usr_cmd_len; i++) {\n\t\tif ((i < usr_cmd_len - 1) && isspace(t_con->line[usr_cmd_pos + i])\n\t\t\t\t&& isspace(t_con->line[usr_cmd_pos + i + 1])) {\n\t\t\toptimized_spaces++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tquery[i - optimized_spaces] = t_con->line[usr_cmd_pos + i];\n\t}\n\n\tusr_cmd_len -= optimized_spaces;\n\tquery[usr_cmd_len] = '\\0';\n\n\t/* filter commands */\n\tchar *query_cmd;\n\n\tif (is_variable_auto_completion)\n\t\tquery_cmd = alloc_printf(\"lsort [info vars {%s*}]\", query);\n\telse\n\t\tquery_cmd = alloc_printf(\"_telnet_autocomplete_helper {%s*}\", query);\n\n\tif (!query_cmd) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn;\n\t}\n\n\tint retval = Jim_EvalSource(command_context->interp, __FILE__, __LINE__, query_cmd);\n\tfree(query_cmd);\n\tif (retval != JIM_OK)\n\t\treturn;\n\n\tJim_Obj *list = Jim_GetResult(command_context->interp);\n\tJim_IncrRefCount(list);\n\n\t/* common prefix length of the matched commands */\n\tsize_t common_len = 0;\n\tchar *first_match = NULL; /* used to compute the common prefix length */\n\n\tint len = Jim_ListLength(command_context->interp, list);\n\tfor (int i = 0; i < len; i++) {\n\t\tJim_Obj *elem = Jim_ListGetIndex(command_context->interp, list, i);\n\t\tJim_IncrRefCount(elem);\n\n\t\tchar *name = (char *)Jim_GetString(elem, NULL);\n\n\t\t/* validate the command */\n\t\tbool ignore_cmd = false;\n\t\tif (!is_variable_auto_completion) {\n\t\t\tJim_Cmd *jim_cmd = Jim_GetCommand(command_context->interp, elem, JIM_NONE);\n\n\t\t\tif (!jim_cmd) {\n\t\t\t\t/* Why we are here? Let's ignore it! */\n\t\t\t\tignore_cmd = true;\n\t\t\t} else if (jimcmd_is_oocd_command(jim_cmd)) {\n\t\t\t\tstruct command *cmd = jimcmd_privdata(jim_cmd);\n\n\t\t\t\tif (cmd && !cmd->handler && !cmd->jim_handler) {\n\t\t\t\t\t/* Initial part of a multi-word command. Ignore it! */\n\t\t\t\t\tignore_cmd = true;\n\t\t\t\t} else if (cmd && cmd->mode == COMMAND_CONFIG) {\n\t\t\t\t\t/* Not executable after config phase. Ignore it! */\n\t\t\t\t\tignore_cmd = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* save the command in the prediction list */\n\t\tif (!ignore_cmd) {\n\t\t\tstruct cmd_match *match = calloc(1, sizeof(struct cmd_match));\n\t\t\tif (!match) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\tJim_DecrRefCount(command_context->interp, elem);\n\t\t\t\tbreak; /* break the for loop */\n\t\t\t}\n\n\t\t\tif (list_empty(&matches)) {\n\t\t\t\tcommon_len = strlen(name);\n\t\t\t\tfirst_match = name;\n\t\t\t} else {\n\t\t\t\tsize_t new_common_len = usr_cmd_len; /* save some loops */\n\n\t\t\t\twhile (new_common_len < common_len && first_match[new_common_len] == name[new_common_len])\n\t\t\t\t\tnew_common_len++;\n\n\t\t\t\tcommon_len = new_common_len;\n\t\t\t}\n\n\t\t\tmatch->cmd = name;\n\t\t\tlist_add_tail(&match->lh, &matches);\n\t\t}\n\n\t\tJim_DecrRefCount(command_context->interp, elem);\n\t}\n\t/* end of command filtering */\n\n\t/* proceed with auto-completion */\n\tif (list_empty(&matches))\n\t\ttelnet_bell(connection);\n\telse if (common_len == usr_cmd_len && list_is_singular(&matches) && t_con->line_cursor == t_con->line_size)\n\t\ttelnet_insert(connection, \" \", 1);\n\telse if (common_len > usr_cmd_len) {\n\t\tint completion_size = common_len - usr_cmd_len;\n\t\tif (telnet_insert(connection, first_match + usr_cmd_len, completion_size)) {\n\t\t\t/* in bash this extra space is only added when the cursor in at the end of line */\n\t\t\tif (list_is_singular(&matches) && t_con->line_cursor == t_con->line_size)\n\t\t\t\ttelnet_insert(connection, \" \", 1);\n\t\t}\n\t} else if (!list_is_singular(&matches)) {\n\t\ttelnet_write(connection, \"\\n\\r\", 2);\n\n\t\tstruct cmd_match *match;\n\t\tlist_for_each_entry(match, &matches, lh) {\n\t\t\ttelnet_write(connection, match->cmd, strlen(match->cmd));\n\t\t\ttelnet_write(connection, \"\\n\\r\", 2);\n\t\t}\n\n\t\ttelnet_prompt(connection);\n\t\ttelnet_write(connection, t_con->line, t_con->line_size);\n\n\t\t/* restore the terminal visible cursor location */\n\t\tfor (size_t i = t_con->line_cursor; i < t_con->line_size; i++)\n\t\t\ttelnet_write(connection, \"\\b\", 1);\n\t}\n\n\t/* destroy the command_list */\n\tstruct cmd_match *tmp, *match;\n\tlist_for_each_entry_safe(match, tmp, &matches, lh)\n\t\tfree(match);\n\n\tJim_DecrRefCount(command_context->interp, list);\n}\n\nstatic int telnet_input(struct connection *connection)\n{\n\tint bytes_read;\n\tunsigned char buffer[TELNET_BUFFER_SIZE];\n\tunsigned char *buf_p;\n\tstruct telnet_connection *t_con = connection->priv;\n\n\tbytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE);\n\n\tif (bytes_read == 0)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\telse if (bytes_read == -1) {\n\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tbuf_p = buffer;\n\twhile (bytes_read) {\n\t\tswitch (t_con->state) {\n\t\t\tcase TELNET_STATE_DATA:\n\t\t\t\tif (*buf_p == 0xff) {\n\t\t\t\t\tt_con->state = TELNET_STATE_IAC;\n\t\t\t\t} else {\n\t\t\t\t\tif (isprint(*buf_p)) {\t/* printable character */\n\t\t\t\t\t\ttelnet_insert(connection, buf_p, 1);\n\t\t\t\t\t} else { /* non-printable */\n\t\t\t\t\t\tif (*buf_p == 0x1b) {\t/* escape */\n\t\t\t\t\t\t\tt_con->state = TELNET_STATE_ESCAPE;\n\t\t\t\t\t\t\tt_con->last_escape = '\\x00';\n\t\t\t\t\t\t} else if ((*buf_p == 0xd) || (*buf_p == 0xa)) { /* CR/LF */\n\t\t\t\t\t\t\tint retval;\n\n\t\t\t\t\t\t\t/* skip over combinations with CR/LF and NUL characters */\n\t\t\t\t\t\t\tif ((bytes_read > 1) && ((*(buf_p + 1) == 0xa) ||\n\t\t\t\t\t\t\t\t\t(*(buf_p + 1) == 0xd))) {\n\t\t\t\t\t\t\t\tbuf_p++;\n\t\t\t\t\t\t\t\tbytes_read--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ((bytes_read > 1) && (*(buf_p + 1) == 0)) {\n\t\t\t\t\t\t\t\tbuf_p++;\n\t\t\t\t\t\t\t\tbytes_read--;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tt_con->line[t_con->line_size] = 0;\n\n\t\t\t\t\t\t\tretval = telnet_exec_line(connection);\n\t\t\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t} else if ((*buf_p == 0x7f) || (*buf_p == 0x8)) {\t/* delete character */\n\t\t\t\t\t\t\ttelnet_delete_character(connection);\n\t\t\t\t\t\t} else if (*buf_p == 0x15) {\t/* clear line */\n\t\t\t\t\t\t\ttelnet_clear_line(connection, t_con);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('B')) {\t/* cursor left */\n\t\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_cursor - 1);\n\t\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t\t} else if (*buf_p == CTRL('C')) {\t/* interrupt */\n\t\t\t\t\t\t\ttelnet_interrupt(connection);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('F')) {\t/* cursor right */\n\t\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_cursor + 1);\n\t\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t\t} else if (*buf_p == CTRL('P')) {\t/* cursor up */\n\t\t\t\t\t\t\ttelnet_history_up(connection);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('N')) {\t/* cursor down */\n\t\t\t\t\t\t\ttelnet_history_down(connection);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('A')) {\t/* move the cursor to the beginning of the line */\n\t\t\t\t\t\t\ttelnet_move_cursor(connection, 0);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('E')) {\t/* move the cursor to the end of the line */\n\t\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_size);\n\t\t\t\t\t\t} else if (*buf_p == CTRL('K')) {\t/* kill line to end */\n\t\t\t\t\t\t\ttelnet_cut_line_to_end(connection);\n\t\t\t\t\t\t} else if (*buf_p == '\\t') {\n\t\t\t\t\t\t\ttelnet_auto_complete(connection);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tLOG_DEBUG(\"unhandled nonprintable: %2.2x\", *buf_p);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_IAC:\n\t\t\t\tswitch (*buf_p) {\n\t\t\t\tcase 0xfe:\n\t\t\t\t\tt_con->state = TELNET_STATE_DONT;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfd:\n\t\t\t\t\tt_con->state = TELNET_STATE_DO;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfc:\n\t\t\t\t\tt_con->state = TELNET_STATE_WONT;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfb:\n\t\t\t\t\tt_con->state = TELNET_STATE_WILL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_SB:\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_SE:\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_WILL:\n\t\t\tcase TELNET_STATE_WONT:\n\t\t\tcase TELNET_STATE_DO:\n\t\t\tcase TELNET_STATE_DONT:\n\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_ESCAPE:\n\t\t\t\tif (t_con->last_escape == '[') {\n\t\t\t\t\tif (*buf_p == 'D') {\t/* cursor left */\n\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_cursor - 1);\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t} else if (*buf_p == 'C') {\t/* cursor right */\n\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_cursor + 1);\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t} else if (*buf_p == 'A') {\t/* cursor up */\n\t\t\t\t\t\ttelnet_history_up(connection);\n\t\t\t\t\t} else if (*buf_p == 'B') {\t/* cursor down */\n\t\t\t\t\t\ttelnet_history_down(connection);\n\t\t\t\t\t} else if (*buf_p == 'F') { /* end key */\n\t\t\t\t\t\ttelnet_move_cursor(connection, t_con->line_size);\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t} else if (*buf_p == 'H') { /* home key */\n\t\t\t\t\t\ttelnet_move_cursor(connection, 0);\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t} else if (*buf_p == '3') {\n\t\t\t\t\t\tt_con->last_escape = *buf_p;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t}\n\t\t\t\t} else if (t_con->last_escape == '3') {\n\t\t\t\t\t/* Remove character */\n\t\t\t\t\tif (*buf_p == '~') {\n\t\t\t\t\t\ttelnet_remove_character(connection);\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t\t} else\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t} else if (t_con->last_escape == '\\x00') {\n\t\t\t\t\tif (*buf_p == '[')\n\t\t\t\t\t\tt_con->last_escape = *buf_p;\n\t\t\t\t\telse\n\t\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"BUG: unexpected value in t_con->last_escape\");\n\t\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"unknown telnet state\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbytes_read--;\n\t\tbuf_p++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int telnet_connection_closed(struct connection *connection)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tint i;\n\n\tlog_remove_callback(telnet_log_callback, connection);\n\n\tfree(t_con->prompt);\n\tt_con->prompt = NULL;\n\n\t/* save telnet history */\n\ttelnet_save_history(t_con);\n\n\tfor (i = 0; i < TELNET_LINE_HISTORY_SIZE; i++) {\n\t\tfree(t_con->history[i]);\n\t\tt_con->history[i] = NULL;\n\t}\n\n\t/* if this connection registered a debug-message receiver delete it */\n\tdelete_debug_msg_receiver(connection->cmd_ctx, NULL);\n\n\tfree(connection->priv);\n\tconnection->priv = NULL;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct service_driver telnet_service_driver = {\n\t.name = \"telnet\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = telnet_new_connection,\n\t.input_handler = telnet_input,\n\t.connection_closed_handler = telnet_connection_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nint telnet_init(char *banner)\n{\n\tif (strcmp(telnet_port, \"disabled\") == 0) {\n\t\tLOG_INFO(\"telnet server disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct telnet_service *telnet_service =\n\t\tmalloc(sizeof(struct telnet_service));\n\n\tif (!telnet_service) {\n\t\tLOG_ERROR(\"Failed to allocate telnet service.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttelnet_service->banner = banner;\n\n\tint ret = add_service(&telnet_service_driver, telnet_port, CONNECTION_LIMIT_UNLIMITED,\n\t\ttelnet_service);\n\n\tif (ret != ERROR_OK) {\n\t\tfree(telnet_service);\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* daemon configuration command telnet_port */\nCOMMAND_HANDLER(handle_telnet_port_command)\n{\n\treturn CALL_COMMAND_HANDLER(server_pipe_command, &telnet_port);\n}\n\nCOMMAND_HANDLER(handle_exit_command)\n{\n\treturn ERROR_COMMAND_CLOSE_CONNECTION;\n}\n\nstatic const struct command_registration telnet_command_handlers[] = {\n\t{\n\t\t.name = \"exit\",\n\t\t.handler = handle_exit_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"exit telnet session\",\n\t},\n\t{\n\t\t.name = \"telnet_port\",\n\t\t.handler = handle_telnet_port_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Specify port on which to listen \"\n\t\t\t\"for incoming telnet connections.  \"\n\t\t\t\"Read help on 'gdb_port'.\",\n\t\t.usage = \"[port_num]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint telnet_register_commands(struct command_context *cmd_ctx)\n{\n\ttelnet_port = strdup(\"4444\");\n\treturn register_commands(cmd_ctx, NULL, telnet_command_handlers);\n}\n\nvoid telnet_service_free(void)\n{\n\tfree(telnet_port);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/server/telnet_server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_SERVER_TELNET_SERVER_H\n#define OPENOCD_SERVER_TELNET_SERVER_H\n\n#include <server/server.h>\n\n#define TELNET_BUFFER_SIZE (10*1024)\n\n#define TELNET_LINE_HISTORY_SIZE (128)\n#define TELNET_LINE_MAX_SIZE (10*256)\n\nenum telnet_states {\n\tTELNET_STATE_DATA,\n\tTELNET_STATE_IAC,\n\tTELNET_STATE_SB,\n\tTELNET_STATE_SE,\n\tTELNET_STATE_WILL,\n\tTELNET_STATE_WONT,\n\tTELNET_STATE_DO,\n\tTELNET_STATE_DONT,\n\tTELNET_STATE_ESCAPE,\n};\n\nstruct telnet_connection {\n\tchar *prompt;\n\tbool prompt_visible;\n\tenum telnet_states state;\n\tchar line[TELNET_LINE_MAX_SIZE];\n\tsize_t line_size;\n\tsize_t line_cursor;\n\tchar last_escape;\n\tchar *history[TELNET_LINE_HISTORY_SIZE];\n\tsize_t next_history;\n\tsize_t current_history;\n\tbool closed;\n};\n\nstruct telnet_service {\n\tchar *banner;\n};\n\nint telnet_init(char *banner);\nint telnet_register_commands(struct command_context *command_context);\nvoid telnet_service_free(void);\n\n#endif /* OPENOCD_SERVER_TELNET_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/svf/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libsvf.la\n%C%_libsvf_la_SOURCES = %D%/svf.c %D%/svf.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/svf/svf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *    Copyright (C) 2009 by Simon Qian                                     *\n *    SimonQian@SimonQian.com                                              *\n ***************************************************************************/\n\n/* The specification for SVF is available here:\n * http://www.asset-intertech.com/support/svf.pdf\n * Below, this document is referred to as the \"SVF spec\".\n *\n * The specification for XSVF is available here:\n * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf\n * Below, this document is referred to as the \"XSVF spec\".\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include \"svf.h\"\n#include \"helper/system.h\"\n#include <helper/time_support.h>\n#include <helper/nvp.h>\n#include <stdbool.h>\n\n/* SVF command */\nenum svf_command {\n\tENDDR,\n\tENDIR,\n\tFREQUENCY,\n\tHDR,\n\tHIR,\n\tPIO,\n\tPIOMAP,\n\tRUNTEST,\n\tSDR,\n\tSIR,\n\tSTATE,\n\tTDR,\n\tTIR,\n\tTRST,\n};\n\nstatic const char *svf_command_name[14] = {\n\t\"ENDDR\",\n\t\"ENDIR\",\n\t\"FREQUENCY\",\n\t\"HDR\",\n\t\"HIR\",\n\t\"PIO\",\n\t\"PIOMAP\",\n\t\"RUNTEST\",\n\t\"SDR\",\n\t\"SIR\",\n\t\"STATE\",\n\t\"TDR\",\n\t\"TIR\",\n\t\"TRST\"\n};\n\nenum trst_mode {\n\tTRST_ON,\n\tTRST_OFF,\n\tTRST_Z,\n\tTRST_ABSENT\n};\n\nstatic const char *svf_trst_mode_name[4] = {\n\t\"ON\",\n\t\"OFF\",\n\t\"Z\",\n\t\"ABSENT\"\n};\n\nstruct svf_statemove {\n\ttap_state_t from;\n\ttap_state_t to;\n\tuint32_t num_of_moves;\n\ttap_state_t paths[8];\n};\n\n/*\n * These paths are from the SVF specification for the STATE command, to be\n * used when the STATE command only includes the final state.  The first\n * element of the path is the \"from\" (current) state, and the last one is\n * the \"to\" (target) state.\n *\n * All specified paths are the shortest ones in the JTAG spec, and are thus\n * not (!!) exact matches for the paths used elsewhere in OpenOCD.  Note\n * that PAUSE-to-PAUSE transitions all go through UPDATE and then CAPTURE,\n * which has specific effects on the various registers; they are not NOPs.\n *\n * Paths to RESET are disabled here.  As elsewhere in OpenOCD, and in XSVF\n * and many SVF implementations, we don't want to risk missing that state.\n * To get to RESET, always we ignore the current state.\n */\nstatic const struct svf_statemove svf_statemoves[] = {\n\t/* from\t\t\tto\t\t\t\tnum_of_moves,\tpaths[8] */\n/*\t{TAP_RESET,\t\tTAP_RESET,\t\t1,\t\t\t\t{TAP_RESET}}, */\n\t{TAP_RESET,\t\tTAP_IDLE,\t\t2,\t\t\t\t{TAP_RESET, TAP_IDLE} },\n\t{TAP_RESET,\t\tTAP_DRPAUSE,\t6,\t\t\t\t{TAP_RESET, TAP_IDLE, TAP_DRSELECT,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE} },\n\t{TAP_RESET,\t\tTAP_IRPAUSE,\t7,\t\t\t\t{TAP_RESET, TAP_IDLE, TAP_DRSELECT,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IRSELECT, TAP_IRCAPTURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IREXIT1, TAP_IRPAUSE} },\n\n/*\t{TAP_IDLE,\t\tTAP_RESET,\t\t4,\t\t\t\t{TAP_IDLE,\n * TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */\n\t{TAP_IDLE,\t\tTAP_IDLE,\t\t1,\t\t\t\t{TAP_IDLE} },\n\t{TAP_IDLE,\t\tTAP_DRPAUSE,\t5,\t\t\t\t{TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DREXIT1, TAP_DRPAUSE} },\n\t{TAP_IDLE,\t\tTAP_IRPAUSE,\t6,\t\t\t\t{TAP_IDLE, TAP_DRSELECT, TAP_IRSELECT,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} },\n\n/*\t{TAP_DRPAUSE,\tTAP_RESET,\t\t6,\t\t\t\t{TAP_DRPAUSE,\n * TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */\n\t{TAP_DRPAUSE,\tTAP_IDLE,\t\t4,\t\t\t\t{TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IDLE} },\n\t{TAP_DRPAUSE,\tTAP_DRPAUSE,\t7,\t\t\t\t{TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DRSELECT, TAP_DRCAPTURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DREXIT1, TAP_DRPAUSE} },\n\t{TAP_DRPAUSE,\tTAP_IRPAUSE,\t8,\t\t\t\t{TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DRSELECT, TAP_IRSELECT,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} },\n\n/*\t{TAP_IRPAUSE,\tTAP_RESET,\t\t6,\t\t\t\t{TAP_IRPAUSE,\n * TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, */\n\t{TAP_IRPAUSE,\tTAP_IDLE,\t\t4,\t\t\t\t{TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IDLE} },\n\t{TAP_IRPAUSE,\tTAP_DRPAUSE,\t7,\t\t\t\t{TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DRSELECT, TAP_DRCAPTURE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DREXIT1, TAP_DRPAUSE} },\n\t{TAP_IRPAUSE,\tTAP_IRPAUSE,\t8,\t\t\t\t{TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_DRSELECT, TAP_IRSELECT,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tTAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE} }\n};\n\n#define XXR_TDI\t\t\t\t(1 << 0)\n#define XXR_TDO\t\t\t\t(1 << 1)\n#define XXR_MASK\t\t\t(1 << 2)\n#define XXR_SMASK\t\t\t(1 << 3)\n\n#define SVF_MAX_ADDCYCLES\t255\n\nstruct svf_xxr_para {\n\tint len;\n\tint data_mask;\n\tuint8_t *tdi;\n\tuint8_t *tdo;\n\tuint8_t *mask;\n\tuint8_t *smask;\n};\n\nstruct svf_para {\n\tfloat frequency;\n\ttap_state_t ir_end_state;\n\ttap_state_t dr_end_state;\n\ttap_state_t runtest_run_state;\n\ttap_state_t runtest_end_state;\n\tenum trst_mode trst_mode;\n\n\tstruct svf_xxr_para hir_para;\n\tstruct svf_xxr_para hdr_para;\n\tstruct svf_xxr_para tir_para;\n\tstruct svf_xxr_para tdr_para;\n\tstruct svf_xxr_para sir_para;\n\tstruct svf_xxr_para sdr_para;\n};\n\nstatic struct svf_para svf_para;\nstatic const struct svf_para svf_para_init = {\n/*\tfrequency, ir_end_state, dr_end_state, runtest_run_state, runtest_end_state, trst_mode */\n\t0,\t\t\tTAP_IDLE,\t\tTAP_IDLE,\tTAP_IDLE,\t\tTAP_IDLE,\t\tTRST_Z,\n/*\thir_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n/*\thdr_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n/*\ttir_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n/*\ttdr_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n/*\tsir_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n/*\tsdr_para */\n/*\t{len,\tdata_mask,\ttdi,\ttdo,\tmask,\tsmask}, */\n\t{0,\t\t\t0,\t\tNULL,\tNULL,\tNULL,\tNULL},\n};\n\nstruct svf_check_tdo_para {\n\tint line_num;\t\t/* used to record line number of the check operation */\n\t/* so more information could be printed */\n\tint enabled;\t\t/* check is enabled or not */\n\tint buffer_offset;\t/* buffer_offset to buffers */\n\tint bit_len;\t\t/* bit length to check */\n};\n\n#define SVF_CHECK_TDO_PARA_SIZE 1024\nstatic struct svf_check_tdo_para *svf_check_tdo_para;\nstatic int svf_check_tdo_para_index;\n\nstatic int svf_read_command_from_file(FILE *fd);\nstatic int svf_check_tdo(void);\nstatic int svf_add_check_para(uint8_t enabled, int buffer_offset, int bit_len);\nstatic int svf_run_command(struct command_context *cmd_ctx, char *cmd_str);\nstatic int svf_execute_tap(void);\n\nstatic FILE *svf_fd;\nstatic char *svf_read_line;\nstatic size_t svf_read_line_size;\nstatic char *svf_command_buffer;\nstatic size_t svf_command_buffer_size;\nstatic int svf_line_number;\nstatic int svf_getline(char **lineptr, size_t *n, FILE *stream);\n\n#define SVF_MAX_BUFFER_SIZE_TO_COMMIT   (1024 * 1024)\nstatic uint8_t *svf_tdi_buffer, *svf_tdo_buffer, *svf_mask_buffer;\nstatic int svf_buffer_index, svf_buffer_size;\nstatic int svf_quiet;\nstatic int svf_nil;\nstatic int svf_ignore_error;\nstatic bool svf_noreset;\nstatic int svf_addcycles;\n\n/* Targeting particular tap */\nstatic int svf_tap_is_specified;\nstatic int svf_set_padding(struct svf_xxr_para *para, int len, unsigned char tdi);\n\n/* Progress Indicator */\nstatic int svf_progress_enabled;\nstatic long svf_total_lines;\nstatic int svf_percentage;\nstatic int svf_last_printed_percentage = -1;\n\n/*\n * macro is used to print the svf hex buffer at desired debug level\n * DEBUG, INFO, ERROR, USER\n */\n#define SVF_BUF_LOG(_lvl, _buf, _nbits, _desc)\t\t\t\t\t\t\t\\\n\tsvf_hexbuf_print(LOG_LVL_##_lvl,  __FILE__, __LINE__, __func__, _buf, _nbits, _desc)\n\nstatic void svf_hexbuf_print(int dbg_lvl, const char *file, unsigned line,\n\t\t\t\t\t\t\t const char *function, const uint8_t *buf,\n\t\t\t\t\t\t\t int bit_len, const char *desc)\n{\n\tint j, len = 0;\n\tint byte_len = DIV_ROUND_UP(bit_len, 8);\n\tint msbits = bit_len % 8;\n\n\t/* allocate 2 bytes per hex digit */\n\tchar *prbuf = malloc((byte_len * 2) + 2 + 1);\n\tif (!prbuf)\n\t\treturn;\n\n\t/* print correct number of bytes, mask excess bits where applicable */\n\tuint8_t msb = buf[byte_len - 1] & (msbits ? (1 << msbits) - 1 : 0xff);\n\tlen = sprintf(prbuf, msbits <= 4 ? \"0x%01\"PRIx8 : \"0x%02\"PRIx8, msb);\n\tfor (j = byte_len - 2; j >= 0; j--)\n\t\tlen += sprintf(prbuf + len, \"%02\"PRIx8, buf[j]);\n\n\tlog_printf_lf(dbg_lvl, file, line, function, \"%8s = %s\", desc ? desc : \" \", prbuf);\n\n\tfree(prbuf);\n}\n\nstatic int svf_realloc_buffers(size_t len)\n{\n\tvoid *ptr;\n\n\tif (svf_execute_tap() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tptr = realloc(svf_tdi_buffer, len);\n\tif (!ptr)\n\t\treturn ERROR_FAIL;\n\tsvf_tdi_buffer = ptr;\n\n\tptr = realloc(svf_tdo_buffer, len);\n\tif (!ptr)\n\t\treturn ERROR_FAIL;\n\tsvf_tdo_buffer = ptr;\n\n\tptr = realloc(svf_mask_buffer, len);\n\tif (!ptr)\n\t\treturn ERROR_FAIL;\n\tsvf_mask_buffer = ptr;\n\n\tsvf_buffer_size = len;\n\n\treturn ERROR_OK;\n}\n\nstatic void svf_free_xxd_para(struct svf_xxr_para *para)\n{\n\tif (para) {\n\t\tfree(para->tdi);\n\t\tpara->tdi = NULL;\n\n\t\tfree(para->tdo);\n\t\tpara->tdo = NULL;\n\n\t\tfree(para->mask);\n\t\tpara->mask = NULL;\n\n\t\tfree(para->smask);\n\t\tpara->smask = NULL;\n\t}\n}\n\nint svf_add_statemove(tap_state_t state_to)\n{\n\ttap_state_t state_from = cmd_queue_cur_state;\n\tunsigned index_var;\n\n\t/* when resetting, be paranoid and ignore current state */\n\tif (state_to == TAP_RESET) {\n\t\tif (svf_nil)\n\t\t\treturn ERROR_OK;\n\n\t\tjtag_add_tlr();\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (index_var = 0; index_var < ARRAY_SIZE(svf_statemoves); index_var++) {\n\t\tif ((svf_statemoves[index_var].from == state_from)\n\t\t\t\t&& (svf_statemoves[index_var].to == state_to)) {\n\t\t\tif (svf_nil)\n\t\t\t\tcontinue;\n\t\t\t\t\t\t/* recorded path includes current state ... avoid\n\t\t\t\t\t\t *extra TCKs! */\n\t\t\tif (svf_statemoves[index_var].num_of_moves > 1)\n\t\t\t\tjtag_add_pathmove(svf_statemoves[index_var].num_of_moves - 1,\n\t\t\t\t\tsvf_statemoves[index_var].paths + 1);\n\t\t\telse\n\t\t\t\tjtag_add_pathmove(svf_statemoves[index_var].num_of_moves,\n\t\t\t\t\tsvf_statemoves[index_var].paths);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\tLOG_ERROR(\"SVF: can not move to %s\", tap_state_name(state_to));\n\treturn ERROR_FAIL;\n}\n\nenum svf_cmd_param {\n\tOPT_ADDCYCLES,\n\tOPT_IGNORE_ERROR,\n\tOPT_NIL,\n\tOPT_NORESET,\n\tOPT_PROGRESS,\n\tOPT_QUIET,\n\tOPT_TAP,\n\t/* DEPRECATED */\n\tDEPRECATED_OPT_IGNORE_ERROR,\n\tDEPRECATED_OPT_NIL,\n\tDEPRECATED_OPT_PROGRESS,\n\tDEPRECATED_OPT_QUIET,\n};\n\nstatic const struct nvp svf_cmd_opts[] = {\n\t{ .name = \"-addcycles\",    .value = OPT_ADDCYCLES },\n\t{ .name = \"-ignore_error\", .value = OPT_IGNORE_ERROR },\n\t{ .name = \"-nil\",          .value = OPT_NIL },\n\t{ .name = \"-noreset\",      .value = OPT_NORESET },\n\t{ .name = \"-progress\",     .value = OPT_PROGRESS },\n\t{ .name = \"-quiet\",        .value = OPT_QUIET },\n\t{ .name = \"-tap\",          .value = OPT_TAP },\n\t/* DEPRECATED */\n\t{ .name = \"ignore_error\",  .value = DEPRECATED_OPT_IGNORE_ERROR },\n\t{ .name = \"nil\",           .value = DEPRECATED_OPT_NIL },\n\t{ .name = \"progress\",      .value = DEPRECATED_OPT_PROGRESS },\n\t{ .name = \"quiet\",         .value = DEPRECATED_OPT_QUIET },\n\t{ .name = NULL,            .value = -1 }\n};\n\nCOMMAND_HANDLER(handle_svf_command)\n{\n#define SVF_MIN_NUM_OF_OPTIONS 1\n#define SVF_MAX_NUM_OF_OPTIONS 8\n\tint command_num = 0;\n\tint ret = ERROR_OK;\n\tint64_t time_measure_ms;\n\tint time_measure_s, time_measure_m;\n\n\t/*\n\t * use NULL to indicate a \"plain\" svf file which accounts for\n\t * any additional devices in the scan chain, otherwise the device\n\t * that should be affected\n\t */\n\tstruct jtag_tap *tap = NULL;\n\n\tif ((CMD_ARGC < SVF_MIN_NUM_OF_OPTIONS) || (CMD_ARGC > SVF_MAX_NUM_OF_OPTIONS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* parse command line */\n\tsvf_quiet = 0;\n\tsvf_nil = 0;\n\tsvf_progress_enabled = 0;\n\tsvf_ignore_error = 0;\n\tsvf_noreset = false;\n\tsvf_addcycles = 0;\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tconst struct nvp *n = nvp_name2value(svf_cmd_opts, CMD_ARGV[i]);\n\t\tswitch (n->value) {\n\t\tcase OPT_ADDCYCLES:\n\t\t\tsvf_addcycles = atoi(CMD_ARGV[i + 1]);\n\t\t\tif (svf_addcycles > SVF_MAX_ADDCYCLES) {\n\t\t\t\tcommand_print(CMD, \"addcycles: %s out of range\", CMD_ARGV[i + 1]);\n\t\t\t\tif (svf_fd)\n\t\t\t\t\tfclose(svf_fd);\n\t\t\t\tsvf_fd = NULL;\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\t\t\ti++;\n\t\t\tbreak;\n\n\t\tcase OPT_TAP:\n\t\t\ttap = jtag_tap_by_string(CMD_ARGV[i+1]);\n\t\t\tif (!tap) {\n\t\t\t\tcommand_print(CMD, \"Tap: %s unknown\", CMD_ARGV[i+1]);\n\t\t\t\tif (svf_fd)\n\t\t\t\t\tfclose(svf_fd);\n\t\t\t\tsvf_fd = NULL;\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\t\t\ti++;\n\t\t\tbreak;\n\n\t\tcase DEPRECATED_OPT_QUIET:\n\t\t\tLOG_INFO(\"DEPRECATED flag '%s'; use '-%s'\", CMD_ARGV[i], CMD_ARGV[i]);\n\t\t\t/* fallthrough */\n\t\tcase OPT_QUIET:\n\t\t\tsvf_quiet = 1;\n\t\t\tbreak;\n\n\t\tcase DEPRECATED_OPT_NIL:\n\t\t\tLOG_INFO(\"DEPRECATED flag '%s'; use '-%s'\", CMD_ARGV[i], CMD_ARGV[i]);\n\t\t\t/* fallthrough */\n\t\tcase OPT_NIL:\n\t\t\tsvf_nil = 1;\n\t\t\tbreak;\n\n\t\tcase DEPRECATED_OPT_PROGRESS:\n\t\t\tLOG_INFO(\"DEPRECATED flag '%s'; use '-%s'\", CMD_ARGV[i], CMD_ARGV[i]);\n\t\t\t/* fallthrough */\n\t\tcase OPT_PROGRESS:\n\t\t\tsvf_progress_enabled = 1;\n\t\t\tbreak;\n\n\t\tcase DEPRECATED_OPT_IGNORE_ERROR:\n\t\t\tLOG_INFO(\"DEPRECATED flag '%s'; use '-%s'\", CMD_ARGV[i], CMD_ARGV[i]);\n\t\t\t/* fallthrough */\n\t\tcase OPT_IGNORE_ERROR:\n\t\t\tsvf_ignore_error = 1;\n\t\t\tbreak;\n\n\t\tcase OPT_NORESET:\n\t\t\tsvf_noreset = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tsvf_fd = fopen(CMD_ARGV[i], \"r\");\n\t\t\tif (!svf_fd) {\n\t\t\t\tint err = errno;\n\t\t\t\tcommand_print(CMD, \"open(\\\"%s\\\"): %s\", CMD_ARGV[i], strerror(err));\n\t\t\t\t/* no need to free anything now */\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tLOG_USER(\"svf processing file: \\\"%s\\\"\", CMD_ARGV[i]);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!svf_fd)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* get time */\n\ttime_measure_ms = timeval_ms();\n\n\t/* init */\n\tsvf_line_number = 0;\n\tsvf_command_buffer_size = 0;\n\n\tsvf_check_tdo_para_index = 0;\n\tsvf_check_tdo_para = malloc(sizeof(struct svf_check_tdo_para) * SVF_CHECK_TDO_PARA_SIZE);\n\tif (!svf_check_tdo_para) {\n\t\tLOG_ERROR(\"not enough memory\");\n\t\tret = ERROR_FAIL;\n\t\tgoto free_all;\n\t}\n\n\tsvf_buffer_index = 0;\n\t/* double the buffer size */\n\t/* in case current command cannot be committed, and next command is a bit scan command */\n\t/* here is 32K bits for this big scan command, it should be enough */\n\t/* buffer will be reallocated if buffer size is not enough */\n\tif (svf_realloc_buffers(2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT) != ERROR_OK) {\n\t\tret = ERROR_FAIL;\n\t\tgoto free_all;\n\t}\n\n\tmemcpy(&svf_para, &svf_para_init, sizeof(svf_para));\n\n\tif (!svf_nil && !svf_noreset) {\n\t\t/* TAP_RESET */\n\t\tjtag_add_tlr();\n\t}\n\n\tif (tap) {\n\t\t/* Tap is specified, set header/trailer paddings */\n\t\tint header_ir_len = 0, header_dr_len = 0, trailer_ir_len = 0, trailer_dr_len = 0;\n\t\tstruct jtag_tap *check_tap;\n\n\t\tsvf_tap_is_specified = 1;\n\n\t\tfor (check_tap = jtag_all_taps(); check_tap; check_tap = check_tap->next_tap) {\n\t\t\tif (check_tap->abs_chain_position < tap->abs_chain_position) {\n\t\t\t\t/* Header */\n\t\t\t\theader_ir_len += check_tap->ir_length;\n\t\t\t\theader_dr_len++;\n\t\t\t} else if (check_tap->abs_chain_position > tap->abs_chain_position) {\n\t\t\t\t/* Trailer */\n\t\t\t\ttrailer_ir_len += check_tap->ir_length;\n\t\t\t\ttrailer_dr_len++;\n\t\t\t}\n\t\t}\n\n\t\t/* HDR %d TDI (0) */\n\t\tret = svf_set_padding(&svf_para.hdr_para, header_dr_len, 0);\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"failed to set data header\");\n\t\t\tgoto free_all;\n\t\t}\n\n\t\t/* HIR %d TDI (0xFF) */\n\t\tret = svf_set_padding(&svf_para.hir_para, header_ir_len, 0xFF);\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"failed to set instruction header\");\n\t\t\tgoto free_all;\n\t\t}\n\n\t\t/* TDR %d TDI (0) */\n\t\tret = svf_set_padding(&svf_para.tdr_para, trailer_dr_len, 0);\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"failed to set data trailer\");\n\t\t\tgoto free_all;\n\t\t}\n\n\t\t/* TIR %d TDI (0xFF) */\n\t\tret = svf_set_padding(&svf_para.tir_para, trailer_ir_len, 0xFF);\n\t\tif (ret != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"failed to set instruction trailer\");\n\t\t\tgoto free_all;\n\t\t}\n\t}\n\n\tif (svf_progress_enabled) {\n\t\t/* Count total lines in file. */\n\t\twhile (!feof(svf_fd)) {\n\t\t\tsvf_getline(&svf_command_buffer, &svf_command_buffer_size, svf_fd);\n\t\t\tsvf_total_lines++;\n\t\t}\n\t\trewind(svf_fd);\n\t}\n\twhile (svf_read_command_from_file(svf_fd) == ERROR_OK) {\n\t\t/* Log Output */\n\t\tif (svf_quiet) {\n\t\t\tif (svf_progress_enabled) {\n\t\t\t\tsvf_percentage = ((svf_line_number * 20) / svf_total_lines) * 5;\n\t\t\t\tif (svf_last_printed_percentage != svf_percentage) {\n\t\t\t\t\tLOG_USER_N(\"\\r%d%%    \", svf_percentage);\n\t\t\t\t\tsvf_last_printed_percentage = svf_percentage;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (svf_progress_enabled) {\n\t\t\t\tsvf_percentage = ((svf_line_number * 20) / svf_total_lines) * 5;\n\t\t\t\tLOG_USER_N(\"%3d%%  %s\", svf_percentage, svf_read_line);\n\t\t\t} else\n\t\t\t\tLOG_USER_N(\"%s\", svf_read_line);\n\t\t}\n\t\t/* Run Command */\n\t\tif (svf_run_command(CMD_CTX, svf_command_buffer) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"fail to run command at line %d\", svf_line_number);\n\t\t\tret = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\t\tcommand_num++;\n\t}\n\n\tif ((!svf_nil) && (jtag_execute_queue() != ERROR_OK))\n\t\tret = ERROR_FAIL;\n\telse if (svf_check_tdo() != ERROR_OK)\n\t\tret = ERROR_FAIL;\n\n\t/* print time */\n\ttime_measure_ms = timeval_ms() - time_measure_ms;\n\ttime_measure_s = time_measure_ms / 1000;\n\ttime_measure_ms %= 1000;\n\ttime_measure_m = time_measure_s / 60;\n\ttime_measure_s %= 60;\n\tif (time_measure_ms < 1000)\n\t\tcommand_print(CMD,\n\t\t\t\"\\r\\nTime used: %dm%ds%\" PRId64 \"ms \",\n\t\t\ttime_measure_m,\n\t\t\ttime_measure_s,\n\t\t\ttime_measure_ms);\n\nfree_all:\n\n\tfclose(svf_fd);\n\tsvf_fd = NULL;\n\n\t/* free buffers */\n\tfree(svf_command_buffer);\n\tsvf_command_buffer = NULL;\n\tsvf_command_buffer_size = 0;\n\n\tfree(svf_check_tdo_para);\n\tsvf_check_tdo_para = NULL;\n\tsvf_check_tdo_para_index = 0;\n\n\tfree(svf_tdi_buffer);\n\tsvf_tdi_buffer = NULL;\n\n\tfree(svf_tdo_buffer);\n\tsvf_tdo_buffer = NULL;\n\n\tfree(svf_mask_buffer);\n\tsvf_mask_buffer = NULL;\n\n\tsvf_buffer_index = 0;\n\tsvf_buffer_size = 0;\n\n\tsvf_free_xxd_para(&svf_para.hdr_para);\n\tsvf_free_xxd_para(&svf_para.hir_para);\n\tsvf_free_xxd_para(&svf_para.tdr_para);\n\tsvf_free_xxd_para(&svf_para.tir_para);\n\tsvf_free_xxd_para(&svf_para.sdr_para);\n\tsvf_free_xxd_para(&svf_para.sir_para);\n\n\tif (ret == ERROR_OK)\n\t\tcommand_print(CMD,\n\t\t\t      \"svf file programmed %s for %d commands with %d errors\",\n\t\t\t      (svf_ignore_error > 1) ? \"unsuccessfully\" : \"successfully\",\n\t\t\t      command_num,\n\t\t\t      (svf_ignore_error > 1) ? (svf_ignore_error - 1) : 0);\n\telse\n\t\tcommand_print(CMD, \"svf file programmed failed\");\n\n\tsvf_ignore_error = 0;\n\treturn ret;\n}\n\nstatic int svf_getline(char **lineptr, size_t *n, FILE *stream)\n{\n#define MIN_CHUNK 16\t/* Buffer is increased by this size each time as required */\n\tsize_t i = 0;\n\n\tif (!*lineptr) {\n\t\t*n = MIN_CHUNK;\n\t\t*lineptr = malloc(*n);\n\t\tif (!*lineptr)\n\t\t\treturn -1;\n\t}\n\n\t(*lineptr)[0] = fgetc(stream);\n\twhile ((*lineptr)[i] != '\\n') {\n\t\t(*lineptr)[++i] = fgetc(stream);\n\t\tif (feof(stream)) {\n\t\t\t(*lineptr)[0] = 0;\n\t\t\treturn -1;\n\t\t}\n\t\tif ((i + 2) > *n) {\n\t\t\t*n += MIN_CHUNK;\n\t\t\t*lineptr = realloc(*lineptr, *n);\n\t\t}\n\t}\n\n\t(*lineptr)[++i] = 0;\n\n\treturn sizeof(*lineptr);\n}\n\n#define SVFP_CMD_INC_CNT 1024\nstatic int svf_read_command_from_file(FILE *fd)\n{\n\tunsigned char ch;\n\tint i = 0;\n\tsize_t cmd_pos = 0;\n\tint cmd_ok = 0, slash = 0;\n\n\tif (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0)\n\t\treturn ERROR_FAIL;\n\tsvf_line_number++;\n\tch = svf_read_line[0];\n\twhile (!cmd_ok && (ch != 0)) {\n\t\tswitch (ch) {\n\t\t\tcase '!':\n\t\t\t\tslash = 0;\n\t\t\t\tif (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tsvf_line_number++;\n\t\t\t\ti = -1;\n\t\t\t\tbreak;\n\t\t\tcase '/':\n\t\t\t\tif (++slash == 2) {\n\t\t\t\t\tslash = 0;\n\t\t\t\t\tif (svf_getline(&svf_read_line, &svf_read_line_size,\n\t\t\t\t\t\tsvf_fd) <= 0)\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\tsvf_line_number++;\n\t\t\t\t\ti = -1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase ';':\n\t\t\t\tslash = 0;\n\t\t\t\tcmd_ok = 1;\n\t\t\t\tbreak;\n\t\t\tcase '\\n':\n\t\t\t\tsvf_line_number++;\n\t\t\t\tif (svf_getline(&svf_read_line, &svf_read_line_size, svf_fd) <= 0)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\ti = -1;\n\t\t\t\t/* fallthrough */\n\t\t\tcase '\\r':\n\t\t\t\tslash = 0;\n\t\t\t\t/* Don't save '\\r' and '\\n' if no data is parsed */\n\t\t\t\tif (!cmd_pos)\n\t\t\t\t\tbreak;\n\t\t\t\t/* fallthrough */\n\t\t\tdefault:\n\t\t\t\t/* The parsing code currently expects a space\n\t\t\t\t * before parentheses -- \"TDI (123)\".  Also a\n\t\t\t\t * space afterwards -- \"TDI (123) TDO(456)\".\n\t\t\t\t * But such spaces are optional... instead of\n\t\t\t\t * parser updates, cope with that by adding the\n\t\t\t\t * spaces as needed.\n\t\t\t\t *\n\t\t\t\t * Ensure there are 3 bytes available, for:\n\t\t\t\t *  - current character\n\t\t\t\t *  - added space.\n\t\t\t\t *  - terminating NUL ('\\0')\n\t\t\t\t */\n\t\t\t\tif (cmd_pos + 3 > svf_command_buffer_size) {\n\t\t\t\t\tsvf_command_buffer = realloc(svf_command_buffer, cmd_pos + 3);\n\t\t\t\t\tsvf_command_buffer_size = cmd_pos + 3;\n\t\t\t\t\tif (!svf_command_buffer) {\n\t\t\t\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* insert a space before '(' */\n\t\t\t\tif ('(' == ch)\n\t\t\t\t\tsvf_command_buffer[cmd_pos++] = ' ';\n\n\t\t\t\tsvf_command_buffer[cmd_pos++] = (char)toupper(ch);\n\n\t\t\t\t/* insert a space after ')' */\n\t\t\t\tif (')' == ch)\n\t\t\t\t\tsvf_command_buffer[cmd_pos++] = ' ';\n\t\t\t\tbreak;\n\t\t}\n\t\tch = svf_read_line[++i];\n\t}\n\n\tif (cmd_ok) {\n\t\tsvf_command_buffer[cmd_pos] = '\\0';\n\t\treturn ERROR_OK;\n\t} else\n\t\treturn ERROR_FAIL;\n}\n\nstatic int svf_parse_cmd_string(char *str, int len, char **argus, int *num_of_argu)\n{\n\tint pos = 0, num = 0, space_found = 1, in_bracket = 0;\n\n\twhile (pos < len) {\n\t\tswitch (str[pos]) {\n\t\t\tcase '!':\n\t\t\tcase '/':\n\t\t\t\tLOG_ERROR(\"fail to parse svf command\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tcase '(':\n\t\t\t\tin_bracket = 1;\n\t\t\t\tgoto parse_char;\n\t\t\tcase ')':\n\t\t\t\tin_bracket = 0;\n\t\t\t\tgoto parse_char;\n\t\t\tdefault:\nparse_char:\n\t\t\t\tif (!in_bracket && isspace((int) str[pos])) {\n\t\t\t\t\tspace_found = 1;\n\t\t\t\t\tstr[pos] = '\\0';\n\t\t\t\t} else if (space_found) {\n\t\t\t\t\targus[num++] = &str[pos];\n\t\t\t\t\tspace_found = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\tpos++;\n\t}\n\n\tif (num == 0)\n\t\treturn ERROR_FAIL;\n\n\t*num_of_argu = num;\n\n\treturn ERROR_OK;\n}\n\nbool svf_tap_state_is_stable(tap_state_t state)\n{\n\treturn (state == TAP_RESET) || (state == TAP_IDLE)\n\t\t\t|| (state == TAP_DRPAUSE) || (state == TAP_IRPAUSE);\n}\n\nstatic int svf_find_string_in_array(char *str, char **strs, int num_of_element)\n{\n\tint i;\n\n\tfor (i = 0; i < num_of_element; i++) {\n\t\tif (!strcmp(str, strs[i]))\n\t\t\treturn i;\n\t}\n\treturn 0xFF;\n}\n\nstatic int svf_adjust_array_length(uint8_t **arr, int orig_bit_len, int new_bit_len)\n{\n\tint new_byte_len = (new_bit_len + 7) >> 3;\n\n\tif ((!*arr) || (((orig_bit_len + 7) >> 3) < ((new_bit_len + 7) >> 3))) {\n\t\tfree(*arr);\n\t\t*arr = calloc(1, new_byte_len);\n\t\tif (!*arr) {\n\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int svf_set_padding(struct svf_xxr_para *para, int len, unsigned char tdi)\n{\n\tint error = ERROR_OK;\n\terror |= svf_adjust_array_length(&para->tdi, para->len, len);\n\tmemset(para->tdi, tdi, (len + 7) >> 3);\n\terror |= svf_adjust_array_length(&para->tdo, para->len, len);\n\terror |= svf_adjust_array_length(&para->mask, para->len, len);\n\tpara->len = len;\n\tpara->data_mask = XXR_TDI;\n\n\treturn error;\n}\n\nstatic int svf_copy_hexstring_to_binary(char *str, uint8_t **bin, int orig_bit_len, int bit_len)\n{\n\tint i, str_len = strlen(str), str_hbyte_len = (bit_len + 3) >> 2;\n\tuint8_t ch = 0;\n\n\tif (svf_adjust_array_length(bin, orig_bit_len, bit_len) != ERROR_OK) {\n\t\tLOG_ERROR(\"fail to adjust length of array\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* fill from LSB (end of str) to MSB (beginning of str) */\n\tfor (i = 0; i < str_hbyte_len; i++) {\n\t\tch = 0;\n\t\twhile (str_len > 0) {\n\t\t\tch = str[--str_len];\n\n\t\t\t/* Skip whitespace.  The SVF specification (rev E) is\n\t\t\t * deficient in terms of basic lexical issues like\n\t\t\t * where whitespace is allowed.  Long bitstrings may\n\t\t\t * require line ends for correctness, since there is\n\t\t\t * a hard limit on line length.\n\t\t\t */\n\t\t\tif (!isspace(ch)) {\n\t\t\t\tif ((ch >= '0') && (ch <= '9')) {\n\t\t\t\t\tch = ch - '0';\n\t\t\t\t\tbreak;\n\t\t\t\t} else if ((ch >= 'A') && (ch <= 'F')) {\n\t\t\t\t\tch = ch - 'A' + 10;\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"invalid hex string\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tch = 0;\n\t\t}\n\n\t\t/* write bin */\n\t\tif (i % 2) {\n\t\t\t/* MSB */\n\t\t\t(*bin)[i / 2] |= ch << 4;\n\t\t} else {\n\t\t\t/* LSB */\n\t\t\t(*bin)[i / 2] = 0;\n\t\t\t(*bin)[i / 2] |= ch;\n\t\t}\n\t}\n\n\t/* consume optional leading '0' MSBs or whitespace */\n\twhile (str_len > 0 && ((str[str_len - 1] == '0')\n\t\t\t|| isspace((int) str[str_len - 1])))\n\t\tstr_len--;\n\n\t/* check validity: we must have consumed everything */\n\tif (str_len > 0 || (ch & ~((2 << ((bit_len - 1) % 4)) - 1)) != 0) {\n\t\tLOG_ERROR(\"value exceeds length\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int svf_check_tdo(void)\n{\n\tint i, len, index_var;\n\n\tfor (i = 0; i < svf_check_tdo_para_index; i++) {\n\t\tindex_var = svf_check_tdo_para[i].buffer_offset;\n\t\tlen = svf_check_tdo_para[i].bit_len;\n\t\tif ((svf_check_tdo_para[i].enabled)\n\t\t\t\t&& buf_cmp_mask(&svf_tdi_buffer[index_var], &svf_tdo_buffer[index_var],\n\t\t\t\t&svf_mask_buffer[index_var], len)) {\n\t\t\tLOG_ERROR(\"tdo check error at line %d\",\n\t\t\t\tsvf_check_tdo_para[i].line_num);\n\t\t\tSVF_BUF_LOG(ERROR, &svf_tdi_buffer[index_var], len, \"READ\");\n\t\t\tSVF_BUF_LOG(ERROR, &svf_tdo_buffer[index_var], len, \"WANT\");\n\t\t\tSVF_BUF_LOG(ERROR, &svf_mask_buffer[index_var], len, \"MASK\");\n\n\t\t\tif (svf_ignore_error == 0)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\telse\n\t\t\t\tsvf_ignore_error++;\n\t\t}\n\t}\n\tsvf_check_tdo_para_index = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int svf_add_check_para(uint8_t enabled, int buffer_offset, int bit_len)\n{\n\tif (svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE) {\n\t\tLOG_ERROR(\"toooooo many operation undone\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsvf_check_tdo_para[svf_check_tdo_para_index].line_num = svf_line_number;\n\tsvf_check_tdo_para[svf_check_tdo_para_index].bit_len = bit_len;\n\tsvf_check_tdo_para[svf_check_tdo_para_index].enabled = enabled;\n\tsvf_check_tdo_para[svf_check_tdo_para_index].buffer_offset = buffer_offset;\n\tsvf_check_tdo_para_index++;\n\n\treturn ERROR_OK;\n}\n\nstatic int svf_execute_tap(void)\n{\n\tif ((!svf_nil) && (jtag_execute_queue() != ERROR_OK))\n\t\treturn ERROR_FAIL;\n\telse if (svf_check_tdo() != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tsvf_buffer_index = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)\n{\n\tchar *argus[256], command;\n\tint num_of_argu = 0, i;\n\n\t/* tmp variable */\n\tint i_tmp;\n\n\t/* for RUNTEST */\n\tint run_count;\n\tfloat min_time;\n\t/* for XXR */\n\tstruct svf_xxr_para *xxr_para_tmp;\n\tuint8_t **pbuffer_tmp;\n\tstruct scan_field field;\n\t/* for STATE */\n\ttap_state_t *path = NULL, state;\n\t/* flag padding commands skipped due to -tap command */\n\tint padding_command_skipped = 0;\n\n\tif (svf_parse_cmd_string(cmd_str, strlen(cmd_str), argus, &num_of_argu) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* NOTE: we're a bit loose here, because we ignore case in\n\t * TAP state names (instead of insisting on uppercase).\n\t */\n\n\tcommand = svf_find_string_in_array(argus[0],\n\t\t\t(char **)svf_command_name, ARRAY_SIZE(svf_command_name));\n\tswitch (command) {\n\t\tcase ENDDR:\n\t\tcase ENDIR:\n\t\t\tif (num_of_argu != 2) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\ti_tmp = tap_state_by_name(argus[1]);\n\n\t\t\tif (svf_tap_state_is_stable(i_tmp)) {\n\t\t\t\tif (command == ENDIR) {\n\t\t\t\t\tsvf_para.ir_end_state = i_tmp;\n\t\t\t\t\tLOG_DEBUG(\"\\tIR end_state = %s\",\n\t\t\t\t\t\t\ttap_state_name(i_tmp));\n\t\t\t\t} else {\n\t\t\t\t\tsvf_para.dr_end_state = i_tmp;\n\t\t\t\t\tLOG_DEBUG(\"\\tDR end_state = %s\",\n\t\t\t\t\t\t\ttap_state_name(i_tmp));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"%s: %s is not a stable state\",\n\t\t\t\t\t\targus[0], argus[1]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase FREQUENCY:\n\t\t\tif ((num_of_argu != 1) && (num_of_argu != 3)) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (num_of_argu == 1) {\n\t\t\t\t/* TODO: set jtag speed to full speed */\n\t\t\t\tsvf_para.frequency = 0;\n\t\t\t} else {\n\t\t\t\tif (strcmp(argus[2], \"HZ\")) {\n\t\t\t\t\tLOG_ERROR(\"HZ not found in FREQUENCY command\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tif (svf_execute_tap() != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tsvf_para.frequency = atof(argus[1]);\n\t\t\t\t/* TODO: set jtag speed to */\n\t\t\t\tif (svf_para.frequency > 0) {\n\t\t\t\t\tcommand_run_linef(cmd_ctx,\n\t\t\t\t\t\t\t\"adapter speed %d\",\n\t\t\t\t\t\t\t(int)svf_para.frequency / 1000);\n\t\t\t\t\tLOG_DEBUG(\"\\tfrequency = %f\", svf_para.frequency);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase HDR:\n\t\t\tif (svf_tap_is_specified) {\n\t\t\t\tpadding_command_skipped = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\txxr_para_tmp = &svf_para.hdr_para;\n\t\t\tgoto xxr_common;\n\t\tcase HIR:\n\t\t\tif (svf_tap_is_specified) {\n\t\t\t\tpadding_command_skipped = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\txxr_para_tmp = &svf_para.hir_para;\n\t\t\tgoto xxr_common;\n\t\tcase TDR:\n\t\t\tif (svf_tap_is_specified) {\n\t\t\t\tpadding_command_skipped = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\txxr_para_tmp = &svf_para.tdr_para;\n\t\t\tgoto xxr_common;\n\t\tcase TIR:\n\t\t\tif (svf_tap_is_specified) {\n\t\t\t\tpadding_command_skipped = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\txxr_para_tmp = &svf_para.tir_para;\n\t\t\tgoto xxr_common;\n\t\tcase SDR:\n\t\t\txxr_para_tmp = &svf_para.sdr_para;\n\t\t\tgoto xxr_common;\n\t\tcase SIR:\n\t\t\txxr_para_tmp = &svf_para.sir_para;\n\t\t\tgoto xxr_common;\nxxr_common:\n\t\t\t/* XXR length [TDI (tdi)] [TDO (tdo)][MASK (mask)] [SMASK (smask)] */\n\t\t\tif ((num_of_argu > 10) || (num_of_argu % 2)) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ti_tmp = xxr_para_tmp->len;\n\t\t\txxr_para_tmp->len = atoi(argus[1]);\n\t\t\t/* If we are to enlarge the buffers, all parts of xxr_para_tmp\n\t\t\t * need to be freed */\n\t\t\tif (i_tmp < xxr_para_tmp->len) {\n\t\t\t\tfree(xxr_para_tmp->tdi);\n\t\t\t\txxr_para_tmp->tdi = NULL;\n\t\t\t\tfree(xxr_para_tmp->tdo);\n\t\t\t\txxr_para_tmp->tdo = NULL;\n\t\t\t\tfree(xxr_para_tmp->mask);\n\t\t\t\txxr_para_tmp->mask = NULL;\n\t\t\t\tfree(xxr_para_tmp->smask);\n\t\t\t\txxr_para_tmp->smask = NULL;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"\\tlength = %d\", xxr_para_tmp->len);\n\t\t\txxr_para_tmp->data_mask = 0;\n\t\t\tfor (i = 2; i < num_of_argu; i += 2) {\n\t\t\t\tif ((strlen(argus[i + 1]) < 3) || (argus[i + 1][0] != '(') ||\n\t\t\t\t(argus[i + 1][strlen(argus[i + 1]) - 1] != ')')) {\n\t\t\t\t\tLOG_ERROR(\"data section error\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\targus[i + 1][strlen(argus[i + 1]) - 1] = '\\0';\n\t\t\t\t/* TDI, TDO, MASK, SMASK */\n\t\t\t\tif (!strcmp(argus[i], \"TDI\")) {\n\t\t\t\t\t/* TDI */\n\t\t\t\t\tpbuffer_tmp = &xxr_para_tmp->tdi;\n\t\t\t\t\txxr_para_tmp->data_mask |= XXR_TDI;\n\t\t\t\t} else if (!strcmp(argus[i], \"TDO\")) {\n\t\t\t\t\t/* TDO */\n\t\t\t\t\tpbuffer_tmp = &xxr_para_tmp->tdo;\n\t\t\t\t\txxr_para_tmp->data_mask |= XXR_TDO;\n\t\t\t\t} else if (!strcmp(argus[i], \"MASK\")) {\n\t\t\t\t\t/* MASK */\n\t\t\t\t\tpbuffer_tmp = &xxr_para_tmp->mask;\n\t\t\t\t\txxr_para_tmp->data_mask |= XXR_MASK;\n\t\t\t\t} else if (!strcmp(argus[i], \"SMASK\")) {\n\t\t\t\t\t/* SMASK */\n\t\t\t\t\tpbuffer_tmp = &xxr_para_tmp->smask;\n\t\t\t\t\txxr_para_tmp->data_mask |= XXR_SMASK;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"unknown parameter: %s\", argus[i]);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tif (ERROR_OK !=\n\t\t\t\tsvf_copy_hexstring_to_binary(&argus[i + 1][1], pbuffer_tmp, i_tmp,\n\t\t\t\t\txxr_para_tmp->len)) {\n\t\t\t\t\tLOG_ERROR(\"fail to parse hex value\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tSVF_BUF_LOG(DEBUG, *pbuffer_tmp, xxr_para_tmp->len, argus[i]);\n\t\t\t}\n\t\t\t/* If a command changes the length of the last scan of the same type and the\n\t\t\t * MASK parameter is absent, */\n\t\t\t/* the mask pattern used is all cares */\n\t\t\tif (!(xxr_para_tmp->data_mask & XXR_MASK) && (i_tmp != xxr_para_tmp->len)) {\n\t\t\t\t/* MASK not defined and length changed */\n\t\t\t\tif (ERROR_OK !=\n\t\t\t\tsvf_adjust_array_length(&xxr_para_tmp->mask, i_tmp,\n\t\t\t\t\txxr_para_tmp->len)) {\n\t\t\t\t\tLOG_ERROR(\"fail to adjust length of array\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tbuf_set_ones(xxr_para_tmp->mask, xxr_para_tmp->len);\n\t\t\t}\n\t\t\t/* If TDO is absent, no comparison is needed, set the mask to 0 */\n\t\t\tif (!(xxr_para_tmp->data_mask & XXR_TDO)) {\n\t\t\t\tif (!xxr_para_tmp->tdo) {\n\t\t\t\t\tif (ERROR_OK !=\n\t\t\t\t\tsvf_adjust_array_length(&xxr_para_tmp->tdo, i_tmp,\n\t\t\t\t\t\txxr_para_tmp->len)) {\n\t\t\t\t\t\tLOG_ERROR(\"fail to adjust length of array\");\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!xxr_para_tmp->mask) {\n\t\t\t\t\tif (ERROR_OK !=\n\t\t\t\t\tsvf_adjust_array_length(&xxr_para_tmp->mask, i_tmp,\n\t\t\t\t\t\txxr_para_tmp->len)) {\n\t\t\t\t\t\tLOG_ERROR(\"fail to adjust length of array\");\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmemset(xxr_para_tmp->mask, 0, (xxr_para_tmp->len + 7) >> 3);\n\t\t\t}\n\t\t\t/* do scan if necessary */\n\t\t\tif (command == SDR) {\n\t\t\t\t/* check buffer size first, reallocate if necessary */\n\t\t\t\ti = svf_para.hdr_para.len + svf_para.sdr_para.len +\n\t\t\t\t\t\tsvf_para.tdr_para.len;\n\t\t\t\tif ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) {\n\t\t\t\t\t/* reallocate buffer */\n\t\t\t\t\tif (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* assemble dr data */\n\t\t\t\ti = 0;\n\t\t\t\tbuf_set_buf(svf_para.hdr_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.hdr_para.len);\n\t\t\t\ti += svf_para.hdr_para.len;\n\t\t\t\tbuf_set_buf(svf_para.sdr_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.sdr_para.len);\n\t\t\t\ti += svf_para.sdr_para.len;\n\t\t\t\tbuf_set_buf(svf_para.tdr_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.tdr_para.len);\n\t\t\t\ti += svf_para.tdr_para.len;\n\n\t\t\t\t/* add check data */\n\t\t\t\tif (svf_para.sdr_para.data_mask & XXR_TDO) {\n\t\t\t\t\t/* assemble dr mask data */\n\t\t\t\t\ti = 0;\n\t\t\t\t\tbuf_set_buf(svf_para.hdr_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.hdr_para.len);\n\t\t\t\t\ti += svf_para.hdr_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.sdr_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.sdr_para.len);\n\t\t\t\t\ti += svf_para.sdr_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.tdr_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.tdr_para.len);\n\n\t\t\t\t\t/* assemble dr check data */\n\t\t\t\t\ti = 0;\n\t\t\t\t\tbuf_set_buf(svf_para.hdr_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.hdr_para.len);\n\t\t\t\t\ti += svf_para.hdr_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.sdr_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.sdr_para.len);\n\t\t\t\t\ti += svf_para.sdr_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.tdr_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.tdr_para.len);\n\t\t\t\t\ti += svf_para.tdr_para.len;\n\n\t\t\t\t\tsvf_add_check_para(1, svf_buffer_index, i);\n\t\t\t\t} else\n\t\t\t\t\tsvf_add_check_para(0, svf_buffer_index, i);\n\t\t\t\tfield.num_bits = i;\n\t\t\t\tfield.out_value = &svf_tdi_buffer[svf_buffer_index];\n\t\t\t\tfield.in_value = (xxr_para_tmp->data_mask & XXR_TDO) ? &svf_tdi_buffer[svf_buffer_index] : NULL;\n\t\t\t\tif (!svf_nil) {\n\t\t\t\t\t/* NOTE:  doesn't use SVF-specified state paths */\n\t\t\t\t\tjtag_add_plain_dr_scan(field.num_bits,\n\t\t\t\t\t\t\tfield.out_value,\n\t\t\t\t\t\t\tfield.in_value,\n\t\t\t\t\t\t\tsvf_para.dr_end_state);\n\t\t\t\t}\n\n\t\t\t\tif (svf_addcycles)\n\t\t\t\t\tjtag_add_clocks(svf_addcycles);\n\n\t\t\t\tsvf_buffer_index += (i + 7) >> 3;\n\t\t\t} else if (command == SIR) {\n\t\t\t\t/* check buffer size first, reallocate if necessary */\n\t\t\t\ti = svf_para.hir_para.len + svf_para.sir_para.len +\n\t\t\t\t\t\tsvf_para.tir_para.len;\n\t\t\t\tif ((svf_buffer_size - svf_buffer_index) < ((i + 7) >> 3)) {\n\t\t\t\t\tif (svf_realloc_buffers(svf_buffer_index + ((i + 7) >> 3)) != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* assemble ir data */\n\t\t\t\ti = 0;\n\t\t\t\tbuf_set_buf(svf_para.hir_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.hir_para.len);\n\t\t\t\ti += svf_para.hir_para.len;\n\t\t\t\tbuf_set_buf(svf_para.sir_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.sir_para.len);\n\t\t\t\ti += svf_para.sir_para.len;\n\t\t\t\tbuf_set_buf(svf_para.tir_para.tdi,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t&svf_tdi_buffer[svf_buffer_index],\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tsvf_para.tir_para.len);\n\t\t\t\ti += svf_para.tir_para.len;\n\n\t\t\t\t/* add check data */\n\t\t\t\tif (svf_para.sir_para.data_mask & XXR_TDO) {\n\t\t\t\t\t/* assemble dr mask data */\n\t\t\t\t\ti = 0;\n\t\t\t\t\tbuf_set_buf(svf_para.hir_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.hir_para.len);\n\t\t\t\t\ti += svf_para.hir_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.sir_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.sir_para.len);\n\t\t\t\t\ti += svf_para.sir_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.tir_para.mask,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_mask_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.tir_para.len);\n\n\t\t\t\t\t/* assemble dr check data */\n\t\t\t\t\ti = 0;\n\t\t\t\t\tbuf_set_buf(svf_para.hir_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.hir_para.len);\n\t\t\t\t\ti += svf_para.hir_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.sir_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.sir_para.len);\n\t\t\t\t\ti += svf_para.sir_para.len;\n\t\t\t\t\tbuf_set_buf(svf_para.tir_para.tdo,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t&svf_tdo_buffer[svf_buffer_index],\n\t\t\t\t\t\t\ti,\n\t\t\t\t\t\t\tsvf_para.tir_para.len);\n\t\t\t\t\ti += svf_para.tir_para.len;\n\n\t\t\t\t\tsvf_add_check_para(1, svf_buffer_index, i);\n\t\t\t\t} else\n\t\t\t\t\tsvf_add_check_para(0, svf_buffer_index, i);\n\t\t\t\tfield.num_bits = i;\n\t\t\t\tfield.out_value = &svf_tdi_buffer[svf_buffer_index];\n\t\t\t\tfield.in_value = (xxr_para_tmp->data_mask & XXR_TDO) ? &svf_tdi_buffer[svf_buffer_index] : NULL;\n\t\t\t\tif (!svf_nil) {\n\t\t\t\t\t/* NOTE:  doesn't use SVF-specified state paths */\n\t\t\t\t\tjtag_add_plain_ir_scan(field.num_bits,\n\t\t\t\t\t\t\tfield.out_value,\n\t\t\t\t\t\t\tfield.in_value,\n\t\t\t\t\t\t\tsvf_para.ir_end_state);\n\t\t\t\t}\n\n\t\t\t\tsvf_buffer_index += (i + 7) >> 3;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase PIO:\n\t\tcase PIOMAP:\n\t\t\tLOG_ERROR(\"PIO and PIOMAP are not supported\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase RUNTEST:\n\t\t\t/* RUNTEST [run_state] run_count run_clk [min_time SEC [MAXIMUM max_time\n\t\t\t * SEC]] [ENDSTATE end_state] */\n\t\t\t/* RUNTEST [run_state] min_time SEC [MAXIMUM max_time SEC] [ENDSTATE\n\t\t\t * end_state] */\n\t\t\tif ((num_of_argu < 3) || (num_of_argu > 11)) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\t/* init */\n\t\t\trun_count = 0;\n\t\t\tmin_time = 0;\n\t\t\ti = 1;\n\n\t\t\t/* run_state */\n\t\t\ti_tmp = tap_state_by_name(argus[i]);\n\t\t\tif (i_tmp != TAP_INVALID) {\n\t\t\t\tif (svf_tap_state_is_stable(i_tmp)) {\n\t\t\t\t\tsvf_para.runtest_run_state = i_tmp;\n\n\t\t\t\t\t/* When a run_state is specified, the new\n\t\t\t\t\t * run_state becomes the default end_state.\n\t\t\t\t\t */\n\t\t\t\t\tsvf_para.runtest_end_state = i_tmp;\n\t\t\t\t\tLOG_DEBUG(\"\\trun_state = %s\", tap_state_name(i_tmp));\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"%s: %s is not a stable state\", argus[0], tap_state_name(i_tmp));\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* run_count run_clk */\n\t\t\tif (((i + 2) <= num_of_argu) && strcmp(argus[i + 1], \"SEC\")) {\n\t\t\t\tif (!strcmp(argus[i + 1], \"TCK\")) {\n\t\t\t\t\t/* clock source is TCK */\n\t\t\t\t\trun_count = atoi(argus[i]);\n\t\t\t\t\tLOG_DEBUG(\"\\trun_count@TCK = %d\", run_count);\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"%s not supported for clock\", argus[i + 1]);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\ti += 2;\n\t\t\t}\n\t\t\t/* min_time SEC */\n\t\t\tif (((i + 2) <= num_of_argu) && !strcmp(argus[i + 1], \"SEC\")) {\n\t\t\t\tmin_time = atof(argus[i]);\n\t\t\t\tLOG_DEBUG(\"\\tmin_time = %fs\", min_time);\n\t\t\t\ti += 2;\n\t\t\t}\n\t\t\t/* MAXIMUM max_time SEC */\n\t\t\tif (((i + 3) <= num_of_argu) &&\n\t\t\t!strcmp(argus[i], \"MAXIMUM\") && !strcmp(argus[i + 2], \"SEC\")) {\n\t\t\t\tfloat max_time = 0;\n\t\t\t\tmax_time = atof(argus[i + 1]);\n\t\t\t\tLOG_DEBUG(\"\\tmax_time = %fs\", max_time);\n\t\t\t\ti += 3;\n\t\t\t}\n\t\t\t/* ENDSTATE end_state */\n\t\t\tif (((i + 2) <= num_of_argu) && !strcmp(argus[i], \"ENDSTATE\")) {\n\t\t\t\ti_tmp = tap_state_by_name(argus[i + 1]);\n\n\t\t\t\tif (svf_tap_state_is_stable(i_tmp)) {\n\t\t\t\t\tsvf_para.runtest_end_state = i_tmp;\n\t\t\t\t\tLOG_DEBUG(\"\\tend_state = %s\", tap_state_name(i_tmp));\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"%s: %s is not a stable state\", argus[0], tap_state_name(i_tmp));\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\ti += 2;\n\t\t\t}\n\n\t\t\t/* all parameter should be parsed */\n\t\t\tif (i == num_of_argu) {\n#if 1\n\t\t\t\t/* FIXME handle statemove failures */\n\t\t\t\tuint32_t min_usec = 1000000 * min_time;\n\n\t\t\t\t/* enter into run_state if necessary */\n\t\t\t\tif (cmd_queue_cur_state != svf_para.runtest_run_state)\n\t\t\t\t\tsvf_add_statemove(svf_para.runtest_run_state);\n\n\t\t\t\t/* add clocks and/or min wait */\n\t\t\t\tif (run_count > 0) {\n\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\tjtag_add_clocks(run_count);\n\t\t\t\t}\n\n\t\t\t\tif (min_usec > 0) {\n\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\tjtag_add_sleep(min_usec);\n\t\t\t\t}\n\n\t\t\t\t/* move to end_state if necessary */\n\t\t\t\tif (svf_para.runtest_end_state != svf_para.runtest_run_state)\n\t\t\t\t\tsvf_add_statemove(svf_para.runtest_end_state);\n\n#else\n\t\t\t\tif (svf_para.runtest_run_state != TAP_IDLE) {\n\t\t\t\t\tLOG_ERROR(\"cannot runtest in %s state\",\n\t\t\t\t\t\t\ttap_state_name(svf_para.runtest_run_state));\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\n\t\t\t\tif (!svf_nil)\n\t\t\t\t\tjtag_add_runtest(run_count, svf_para.runtest_end_state);\n#endif\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"fail to parse parameter of RUNTEST, %d out of %d is parsed\",\n\t\t\t\t\t\ti,\n\t\t\t\t\t\tnum_of_argu);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase STATE:\n\t\t\t/* STATE [pathstate1 [pathstate2 ...[pathstaten]]] stable_state */\n\t\t\tif (num_of_argu < 2) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (num_of_argu > 2) {\n\t\t\t\t/* STATE pathstate1 ... stable_state */\n\t\t\t\tpath = malloc((num_of_argu - 1) * sizeof(tap_state_t));\n\t\t\t\tif (!path) {\n\t\t\t\t\tLOG_ERROR(\"not enough memory\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tnum_of_argu--;\t/* num of path */\n\t\t\t\ti_tmp = 1;\t\t/* path is from parameter 1 */\n\t\t\t\tfor (i = 0; i < num_of_argu; i++, i_tmp++) {\n\t\t\t\t\tpath[i] = tap_state_by_name(argus[i_tmp]);\n\t\t\t\t\tif (path[i] == TAP_INVALID) {\n\t\t\t\t\t\tLOG_ERROR(\"%s: %s is not a valid state\", argus[0], argus[i_tmp]);\n\t\t\t\t\t\tfree(path);\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t\t/* OpenOCD refuses paths containing TAP_RESET */\n\t\t\t\t\tif (path[i] == TAP_RESET) {\n\t\t\t\t\t\t/* FIXME last state MUST be stable! */\n\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\t\t\tjtag_add_pathmove(i, path);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\t\tjtag_add_tlr();\n\t\t\t\t\t\tnum_of_argu -= i + 1;\n\t\t\t\t\t\ti = -1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (num_of_argu > 0) {\n\t\t\t\t\t/* execute last path if necessary */\n\t\t\t\t\tif (svf_tap_state_is_stable(path[num_of_argu - 1])) {\n\t\t\t\t\t\t/* last state MUST be stable state */\n\t\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\t\tjtag_add_pathmove(num_of_argu, path);\n\t\t\t\t\t\tLOG_DEBUG(\"\\tmove to %s by path_move\",\n\t\t\t\t\t\t\t\ttap_state_name(path[num_of_argu - 1]));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tLOG_ERROR(\"%s: %s is not a stable state\",\n\t\t\t\t\t\t\t\targus[0],\n\t\t\t\t\t\t\t\ttap_state_name(path[num_of_argu - 1]));\n\t\t\t\t\t\tfree(path);\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfree(path);\n\t\t\t\tpath = NULL;\n\t\t\t} else {\n\t\t\t\t/* STATE stable_state */\n\t\t\t\tstate = tap_state_by_name(argus[1]);\n\t\t\t\tif (svf_tap_state_is_stable(state)) {\n\t\t\t\t\tLOG_DEBUG(\"\\tmove to %s by svf_add_statemove\",\n\t\t\t\t\t\t\ttap_state_name(state));\n\t\t\t\t\t/* FIXME handle statemove failures */\n\t\t\t\t\tsvf_add_statemove(state);\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"%s: %s is not a stable state\",\n\t\t\t\t\t\t\targus[0], tap_state_name(state));\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase TRST:\n\t\t\t/* TRST trst_mode */\n\t\t\tif (num_of_argu != 2) {\n\t\t\t\tLOG_ERROR(\"invalid parameter of %s\", argus[0]);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (svf_para.trst_mode != TRST_ABSENT) {\n\t\t\t\tif (svf_execute_tap() != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\ti_tmp = svf_find_string_in_array(argus[1],\n\t\t\t\t\t\t(char **)svf_trst_mode_name,\n\t\t\t\t\t\tARRAY_SIZE(svf_trst_mode_name));\n\t\t\t\tswitch (i_tmp) {\n\t\t\t\tcase TRST_ON:\n\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\tjtag_add_reset(1, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TRST_Z:\n\t\t\t\tcase TRST_OFF:\n\t\t\t\t\tif (!svf_nil)\n\t\t\t\t\t\tjtag_add_reset(0, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase TRST_ABSENT:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"unknown TRST mode: %s\", argus[1]);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tsvf_para.trst_mode = i_tmp;\n\t\t\t\tLOG_DEBUG(\"\\ttrst_mode = %s\", svf_trst_mode_name[svf_para.trst_mode]);\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"can not accept TRST command if trst_mode is ABSENT\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"invalid svf command: %s\", argus[0]);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!svf_quiet) {\n\t\tif (padding_command_skipped)\n\t\t\tLOG_USER(\"(Above Padding command skipped, as per -tap argument)\");\n\t}\n\n\tif (debug_level >= LOG_LVL_DEBUG) {\n\t\t/* for convenient debugging, execute tap if possible */\n\t\tif ((svf_buffer_index > 0) &&\n\t\t\t\t(((command != STATE) && (command != RUNTEST)) ||\n\t\t\t\t\t\t((command == STATE) && (num_of_argu == 2)))) {\n\t\t\tif (svf_execute_tap() != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\n\t\t\t/* output debug info */\n\t\t\tif ((command == SIR) || (command == SDR))\n\t\t\t\tSVF_BUF_LOG(DEBUG, svf_tdi_buffer, svf_check_tdo_para[0].bit_len, \"TDO read\");\n\t\t}\n\t} else {\n\t\t/* for fast executing, execute tap if necessary */\n\t\t/* half of the buffer is for the next command */\n\t\tif (((svf_buffer_index >= SVF_MAX_BUFFER_SIZE_TO_COMMIT) ||\n\t\t\t\t(svf_check_tdo_para_index >= SVF_CHECK_TDO_PARA_SIZE / 2)) &&\n\t\t\t\t(((command != STATE) && (command != RUNTEST)) ||\n\t\t\t\t\t\t((command == STATE) && (num_of_argu == 2))))\n\t\t\treturn svf_execute_tap();\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration svf_command_handlers[] = {\n\t{\n\t\t.name = \"svf\",\n\t\t.handler = handle_svf_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Runs a SVF file.\",\n\t\t.usage = \"[-tap device.tap] [-quiet] [-nil] [-progress] [-ignore_error] [-noreset] [-addcycles numcycles] file\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint svf_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, svf_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/svf/svf.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian                                      *\n *   SimonQian@SimonQian.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_SVF_SVF_H\n#define OPENOCD_SVF_SVF_H\n\n#include <jtag/jtag.h>\n\nint svf_register_commands(struct command_context *cmd_ctx);\n\n/**\n * svf_add_statemove() moves from the current state to @a goal_state.\n *\n * @param goal_state The final TAP state.\n * @return ERROR_OK on success, or an error code on failure.\n *\n * The current and goal states must satisfy svf_tap_state_is_stable().\n * State transition paths used by this routine are those given in the\n * SVF specification for single-argument STATE commands (and also used\n * for various other state transitions).\n */\nint svf_add_statemove(tap_state_t goal_state);\n\n/**\n * svf_tap_state_is_stable() returns true for stable non-SHIFT states\n *\n * @param state The TAP state in question\n * @return true iff the state is stable and not a SHIFT state.\n */\nbool svf_tap_state_is_stable(tap_state_t state);\n\n#endif /* OPENOCD_SVF_SVF_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n%C%_libtarget_la_LIBADD = %D%/openrisc/libopenrisc.la \\\n\t%D%/riscv/libriscv.la \\\n\t%D%/xtensa/libxtensa.la \\\n\t%D%/espressif/libespressif.la\n\n%C%_libtarget_la_CPPFLAGS = $(AM_CPPFLAGS)\n\nSTARTUP_TCL_SRCS += %D%/startup.tcl\n\nnoinst_LTLIBRARIES += %D%/libtarget.la\n%C%_libtarget_la_SOURCES = \\\n\t$(TARGET_CORE_SRC) \\\n\t$(ARM_DEBUG_SRC) \\\n\t$(ARMV4_5_SRC) \\\n\t$(ARMV6_SRC) \\\n\t$(ARMV7_SRC) \\\n\t$(ARM_MISC_SRC) \\\n\t$(AVR32_SRC) \\\n\t$(MIPS32_SRC) \\\n\t$(STM8_SRC) \\\n\t$(INTEL_IA32_SRC) \\\n\t$(ESIRISC_SRC) \\\n        $(ARC_SRC) \\\n\t%D%/avrt.c \\\n\t%D%/dsp563xx.c \\\n\t%D%/dsp563xx_once.c \\\n\t%D%/dsp5680xx.c \\\n\t%D%/hla_target.c \\\n\t$(ARMV8_SRC) \\\n\t$(MIPS64_SRC)\n\nif HAVE_CAPSTONE\n%C%_libtarget_la_CPPFLAGS += $(CAPSTONE_CFLAGS)\n%C%_libtarget_la_LIBADD += $(CAPSTONE_LIBS)\nendif\n\nTARGET_CORE_SRC = \\\n\t%D%/algorithm.c \\\n\t%D%/register.c \\\n\t%D%/image.c \\\n\t%D%/breakpoints.c \\\n\t%D%/target.c \\\n\t%D%/target_request.c \\\n\t%D%/testee.c \\\n\t%D%/semihosting_common.c \\\n\t%D%/smp.c \\\n\t%D%/rtt.c\n\nARMV4_5_SRC = \\\n\t%D%/armv4_5.c \\\n\t%D%/armv4_5_mmu.c \\\n\t%D%/armv4_5_cache.c \\\n\t$(ARM7_9_SRC)\n\nARM7_9_SRC = \\\n\t%D%/arm7_9_common.c \\\n\t%D%/arm7tdmi.c \\\n\t%D%/arm720t.c \\\n\t%D%/arm9tdmi.c \\\n\t%D%/arm920t.c \\\n\t%D%/arm966e.c \\\n\t%D%/arm946e.c \\\n\t%D%/arm926ejs.c \\\n\t%D%/feroceon.c\n\nARM_MISC_SRC = \\\n\t%D%/fa526.c \\\n\t%D%/xscale.c\n\nARMV6_SRC = \\\n\t%D%/arm11.c \\\n\t%D%/arm11_dbgtap.c\n\nARMV7_SRC = \\\n\t%D%/armv7m.c \\\n\t%D%/armv7m_trace.c \\\n\t%D%/cortex_m.c \\\n\t%D%/armv7a.c \\\n\t%D%/armv7a_mmu.c \\\n\t%D%/cortex_a.c \\\n\t%D%/ls1_sap.c \\\n\t%D%/mem_ap.c\n\nARMV8_SRC = \\\n\t%D%/armv8_dpm.c \\\n\t%D%/armv8_opcodes.c \\\n\t%D%/aarch64.c \\\n\t%D%/a64_disassembler.c \\\n\t%D%/armv8.c \\\n\t%D%/armv8_cache.c\n\nARM_DEBUG_SRC = \\\n\t%D%/arm_dpm.c \\\n\t%D%/arm_jtag.c \\\n\t%D%/arm_disassembler.c \\\n\t%D%/arm_simulator.c \\\n\t%D%/arm_semihosting.c \\\n\t%D%/arm_adi_v5.c \\\n\t%D%/arm_dap.c \\\n\t%D%/armv7a_cache.c \\\n\t%D%/armv7a_cache_l2x.c \\\n\t%D%/adi_v5_dapdirect.c \\\n\t%D%/adi_v5_jtag.c \\\n\t%D%/adi_v5_swd.c \\\n\t%D%/embeddedice.c \\\n\t%D%/trace.c \\\n\t%D%/etb.c \\\n\t%D%/etm.c \\\n\t%D%/etm_dummy.c \\\n\t%D%/arm_tpiu_swo.c \\\n\t%D%/arm_cti.c\n\nAVR32_SRC = \\\n\t%D%/avr32_ap7k.c \\\n\t%D%/avr32_jtag.c \\\n\t%D%/avr32_mem.c \\\n\t%D%/avr32_regs.c\n\nMIPS32_SRC = \\\n\t%D%/mips32.c \\\n\t%D%/mips_m4k.c \\\n\t%D%/mips32_pracc.c \\\n\t%D%/mips32_dmaacc.c \\\n\t%D%/mips_ejtag.c\n\nMIPS64_SRC = \\\n\t%D%/mips64.c \\\n\t%D%/mips32_pracc.c \\\n\t%D%/mips64_pracc.c \\\n\t%D%/mips_mips64.c \\\n\t%D%/trace.c \\\n\t%D%/mips_ejtag.c\n\nSTM8_SRC = \\\n\t%D%/stm8.c\n\nINTEL_IA32_SRC = \\\n\t%D%/quark_x10xx.c \\\n\t%D%/quark_d20xx.c \\\n\t%D%/lakemont.c \\\n\t%D%/x86_32_common.c\n\nESIRISC_SRC = \\\n\t%D%/esirisc.c \\\n\t%D%/esirisc_jtag.c \\\n\t%D%/esirisc_trace.c\n\nARC_SRC = \\\n        %D%/arc.c \\\n        %D%/arc_cmd.c \\\n        %D%/arc_jtag.c \\\n        %D%/arc_mem.c\n\n%C%_libtarget_la_SOURCES += \\\n\t%D%/algorithm.h \\\n\t%D%/arm.h \\\n\t%D%/arm_coresight.h \\\n\t%D%/arm_dpm.h \\\n\t%D%/arm_jtag.h \\\n\t%D%/arm_adi_v5.h \\\n\t%D%/armv7a_cache.h \\\n\t%D%/armv7a_cache_l2x.h \\\n\t%D%/armv7a_mmu.h \\\n\t%D%/arm_disassembler.h \\\n\t%D%/a64_disassembler.h \\\n\t%D%/arm_opcodes.h \\\n\t%D%/arm_simulator.h \\\n\t%D%/arm_semihosting.h \\\n\t%D%/arm7_9_common.h \\\n\t%D%/arm7tdmi.h \\\n\t%D%/arm720t.h \\\n\t%D%/arm9tdmi.h \\\n\t%D%/arm920t.h \\\n\t%D%/arm926ejs.h \\\n\t%D%/arm966e.h \\\n\t%D%/arm946e.h \\\n\t%D%/arm11.h \\\n\t%D%/arm11_dbgtap.h \\\n\t%D%/armv4_5.h \\\n\t%D%/armv4_5_mmu.h \\\n\t%D%/armv4_5_cache.h \\\n\t%D%/armv7a.h \\\n\t%D%/armv7m.h \\\n\t%D%/armv7m_trace.h \\\n\t%D%/armv8.h \\\n\t%D%/armv8_dpm.h \\\n\t%D%/armv8_opcodes.h \\\n\t%D%/armv8_cache.h \\\n\t%D%/avrt.h \\\n\t%D%/dsp563xx.h \\\n\t%D%/dsp563xx_once.h \\\n\t%D%/dsp5680xx.h \\\n\t%D%/breakpoints.h \\\n\t%D%/cortex_m.h \\\n\t%D%/cortex_a.h \\\n\t%D%/aarch64.h \\\n\t%D%/embeddedice.h \\\n\t%D%/etb.h \\\n\t%D%/etm.h \\\n\t%D%/etm_dummy.h \\\n\t%D%/arm_tpiu_swo.h \\\n\t%D%/image.h \\\n\t%D%/mips32.h \\\n\t%D%/mips64.h \\\n\t%D%/mips_m4k.h \\\n\t%D%/mips_mips64.h \\\n\t%D%/mips_ejtag.h \\\n\t%D%/mips32_pracc.h \\\n\t%D%/mips32_dmaacc.h \\\n\t%D%/mips64_pracc.h \\\n\t%D%/register.h \\\n\t%D%/target.h \\\n\t%D%/target_type.h \\\n\t%D%/trace.h \\\n\t%D%/target_request.h \\\n\t%D%/trace.h \\\n\t%D%/xscale.h \\\n\t%D%/smp.h \\\n\t%D%/avr32_ap7k.h \\\n\t%D%/avr32_jtag.h \\\n\t%D%/avr32_mem.h \\\n\t%D%/avr32_regs.h \\\n\t%D%/semihosting_common.h \\\n\t%D%/stm8.h \\\n\t%D%/lakemont.h \\\n\t%D%/x86_32_common.h \\\n\t%D%/arm_cti.h \\\n\t%D%/esirisc.h \\\n\t%D%/esirisc_jtag.h \\\n\t%D%/esirisc_regs.h \\\n\t%D%/esirisc_trace.h \\\n\t%D%/arc.h \\\n\t%D%/arc_cmd.h \\\n\t%D%/arc_jtag.h \\\n\t%D%/arc_mem.h \\\n\t%D%/rtt.h\n\ninclude %D%/openrisc/Makefile.am\ninclude %D%/riscv/Makefile.am\ninclude %D%/xtensa/Makefile.am\ninclude %D%/espressif/Makefile.am\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/a64_disassembler.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2019 by Mete Balci                                      *\n *   metebalci@gmail.com                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include \"target.h\"\n#include \"a64_disassembler.h\"\n\n#if HAVE_CAPSTONE\n\n#include <capstone.h>\n\nstatic void print_opcode(struct command_invocation *cmd, const cs_insn *insn)\n{\n\tuint32_t opcode = 0;\n\n\tmemcpy(&opcode, insn->bytes, insn->size);\n\n\tif (insn->size == 4) {\n\n\t\tuint16_t opcode_high = opcode >> 16;\n\n\t\topcode = opcode & 0xffff;\n\n\t\tcommand_print(cmd,\n\t\t\t\t\"0x%08\" PRIx64\"  %04x %04x\\t%s\\t%s\",\n\t\t\t\tinsn->address,\n\t\t\t\topcode,\n\t\t\t\topcode_high,\n\t\t\t\tinsn->mnemonic,\n\t\t\t\tinsn->op_str);\n\n\t} else {\n\n\t\tcommand_print(\n\t\t\t\tcmd,\n\t\t\t\t\"0x%08\" PRIx64\"  %04x\\t%s\\t%s\",\n\t\t\t\tinsn->address,\n\t\t\t\topcode,\n\t\t\t\tinsn->mnemonic,\n\t\t\t\tinsn->op_str);\n\n\t}\n}\n\nint a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)\n{\n\tint ret;\n\tint csret;\n\tcsh handle;\n\n\tcsret = cs_open(CS_ARCH_ARM64, CS_MODE_LITTLE_ENDIAN, &handle);\n\n\tif (csret != CS_ERR_OK) {\n\n\t\tLOG_ERROR(\"cs_open() failed: %s\", cs_strerror(csret));\n\t\treturn ERROR_FAIL;\n\n\t}\n\n\tcsret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);\n\n\tif (csret != CS_ERR_OK) {\n\n\t\tLOG_ERROR(\"cs_option() failed: %s\", cs_strerror(csret));\n\t\tcs_close(&handle);\n\t\treturn ERROR_FAIL;\n\n\t}\n\n\tcs_insn *insn = cs_malloc(handle);\n\n\tif (csret != CS_ERR_OK) {\n\n\t\tLOG_ERROR(\"cs_malloc() failed: %s\", cs_strerror(csret));\n\t\tcs_close(&handle);\n\t\treturn ERROR_FAIL;\n\n\t}\n\n\twhile (count > 0) {\n\n\t\tuint8_t buffer[4];\n\n\t\tret = target_read_buffer(target, address, sizeof(buffer), buffer);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tcs_free(insn, 1);\n\t\t\tcs_close(&handle);\n\t\t\treturn ret;\n\t\t}\n\n\t\tsize_t size = sizeof(buffer);\n\t\tconst uint8_t *tmp = buffer;\n\n\t\tret = cs_disasm_iter(handle, &tmp, &size, &address, insn);\n\n\t\tif (!ret) {\n\n\t\t\tLOG_ERROR(\"cs_disasm_iter() failed: %s\", cs_strerror(cs_errno(handle)));\n\t\t\tcs_free(insn, 1);\n\t\t\tcs_close(&handle);\n\t\t\treturn ERROR_FAIL;\n\n\t\t}\n\n\t\tprint_opcode(cmd, insn);\n\t\tcount--;\n\n\t}\n\n\tcs_free(insn, 1);\n\tcs_close(&handle);\n\n\treturn ERROR_OK;\n}\n\n#else\n\nint a64_disassemble(struct command_invocation *cmd, struct target *target, target_addr_t address, size_t count)\n{\n\tcommand_print(cmd, \"capstone disassembly framework required\");\n\n\treturn ERROR_FAIL;\n}\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/a64_disassembler.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2019 by Mete Balci                                      *\n *   metebalci@gmail.com                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AARCH64_DISASSEMBLER_H\n#define OPENOCD_TARGET_AARCH64_DISASSEMBLER_H\n\n#include \"target.h\"\n\nint a64_disassemble(\n\t\tstruct command_invocation *cmd,\n\t\tstruct target *target,\n\t\ttarget_addr_t address,\n\t\tsize_t count);\n\n#endif /* OPENOCD_TARGET_AARCH64_DISASSEMBLER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/aarch64.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by David Ung                                       *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"aarch64.h\"\n#include \"a64_disassembler.h\"\n#include \"register.h\"\n#include \"target_request.h\"\n#include \"target_type.h\"\n#include \"armv8_opcodes.h\"\n#include \"armv8_cache.h\"\n#include \"arm_coresight.h\"\n#include \"arm_semihosting.h\"\n#include \"jtag/interface.h\"\n#include \"smp.h\"\n#include <helper/nvp.h>\n#include <helper/time_support.h>\n\nenum restart_mode {\n\tRESTART_LAZY,\n\tRESTART_SYNC,\n};\n\nenum halt_mode {\n\tHALT_LAZY,\n\tHALT_SYNC,\n};\n\nstruct aarch64_private_config {\n\tstruct adiv5_private_config adiv5_config;\n\tstruct arm_cti *cti;\n};\n\nstatic int aarch64_poll(struct target *target);\nstatic int aarch64_debug_entry(struct target *target);\nstatic int aarch64_restore_context(struct target *target, bool bpwp);\nstatic int aarch64_set_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode);\nstatic int aarch64_set_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode);\nstatic int aarch64_set_hybrid_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint);\nstatic int aarch64_unset_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint);\nstatic int aarch64_mmu(struct target *target, int *enabled);\nstatic int aarch64_virt2phys(struct target *target,\n\ttarget_addr_t virt, target_addr_t *phys);\nstatic int aarch64_read_cpu_memory(struct target *target,\n\tuint64_t address, uint32_t size, uint32_t count, uint8_t *buffer);\n\nstatic int aarch64_restore_system_control_reg(struct target *target)\n{\n\tenum arm_mode target_mode = ARM_MODE_ANY;\n\tint retval = ERROR_OK;\n\tuint32_t instr;\n\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\tif (aarch64->system_control_reg != aarch64->system_control_reg_curr) {\n\t\taarch64->system_control_reg_curr = aarch64->system_control_reg;\n\t\t/* LOG_INFO(\"cp15_control_reg: %8.8\" PRIx32, cortex_v8->cp15_control_reg); */\n\n\t\tswitch (armv8->arm.core_mode) {\n\t\tcase ARMV8_64_EL0T:\n\t\t\ttarget_mode = ARMV8_64_EL1H;\n\t\t\t/* fall through */\n\t\tcase ARMV8_64_EL1T:\n\t\tcase ARMV8_64_EL1H:\n\t\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL1, 0);\n\t\t\tbreak;\n\t\tcase ARMV8_64_EL2T:\n\t\tcase ARMV8_64_EL2H:\n\t\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL2, 0);\n\t\t\tbreak;\n\t\tcase ARMV8_64_EL3H:\n\t\tcase ARMV8_64_EL3T:\n\t\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);\n\t\t\tbreak;\n\n\t\tcase ARM_MODE_SVC:\n\t\tcase ARM_MODE_ABT:\n\t\tcase ARM_MODE_FIQ:\n\t\tcase ARM_MODE_IRQ:\n\t\tcase ARM_MODE_HYP:\n\t\tcase ARM_MODE_UND:\n\t\tcase ARM_MODE_SYS:\n\t\t\tinstr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0);\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"cannot read system control register in this mode: (%s : 0x%x)\",\n\t\t\t\t\tarmv8_mode_name(armv8->arm.core_mode), armv8->arm.core_mode);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (target_mode != ARM_MODE_ANY)\n\t\t\tarmv8_dpm_modeswitch(&armv8->dpm, target_mode);\n\n\t\tretval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr, aarch64->system_control_reg);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (target_mode != ARM_MODE_ANY)\n\t\t\tarmv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);\n\t}\n\n\treturn retval;\n}\n\n/*  modify system_control_reg in order to enable or disable mmu for :\n *  - virt2phys address conversion\n *  - read or write memory in phys or virt address */\nstatic int aarch64_mmu_modify(struct target *target, int enable)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tint retval = ERROR_OK;\n\tenum arm_mode target_mode = ARM_MODE_ANY;\n\tuint32_t instr = 0;\n\n\tif (enable) {\n\t\t/*\tif mmu enabled at target stop and mmu not enable */\n\t\tif (!(aarch64->system_control_reg & 0x1U)) {\n\t\t\tLOG_ERROR(\"trying to enable mmu on target stopped with mmu disable\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (!(aarch64->system_control_reg_curr & 0x1U))\n\t\t\taarch64->system_control_reg_curr |= 0x1U;\n\t} else {\n\t\tif (aarch64->system_control_reg_curr & 0x4U) {\n\t\t\t/*  data cache is active */\n\t\t\taarch64->system_control_reg_curr &= ~0x4U;\n\t\t\t/* flush data cache armv8 function to be called */\n\t\t\tif (armv8->armv8_mmu.armv8_cache.flush_all_data_cache)\n\t\t\t\tarmv8->armv8_mmu.armv8_cache.flush_all_data_cache(target);\n\t\t}\n\t\tif ((aarch64->system_control_reg_curr & 0x1U)) {\n\t\t\taarch64->system_control_reg_curr &= ~0x1U;\n\t\t}\n\t}\n\n\tswitch (armv8->arm.core_mode) {\n\tcase ARMV8_64_EL0T:\n\t\ttarget_mode = ARMV8_64_EL1H;\n\t\t/* fall through */\n\tcase ARMV8_64_EL1T:\n\tcase ARMV8_64_EL1H:\n\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL1, 0);\n\t\tbreak;\n\tcase ARMV8_64_EL2T:\n\tcase ARMV8_64_EL2H:\n\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL2, 0);\n\t\tbreak;\n\tcase ARMV8_64_EL3H:\n\tcase ARMV8_64_EL3T:\n\t\tinstr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);\n\t\tbreak;\n\n\tcase ARM_MODE_SVC:\n\tcase ARM_MODE_ABT:\n\tcase ARM_MODE_FIQ:\n\tcase ARM_MODE_IRQ:\n\tcase ARM_MODE_HYP:\n\tcase ARM_MODE_UND:\n\tcase ARM_MODE_SYS:\n\t\tinstr = ARMV4_5_MCR(15, 0, 0, 1, 0, 0);\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_DEBUG(\"unknown cpu state 0x%x\", armv8->arm.core_mode);\n\t\tbreak;\n\t}\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(&armv8->dpm, target_mode);\n\n\tretval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr,\n\t\t\t\taarch64->system_control_reg_curr);\n\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);\n\n\treturn retval;\n}\n\n/*\n * Basic debug access, very low level assumes state is saved\n */\nstatic int aarch64_init_debug_access(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tint retval;\n\tuint32_t dummy;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_OSLAR, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"oslock\");\n\t\treturn retval;\n\t}\n\n\t/* Clear Sticky Power Down status Bit in PRSR to enable access to\n\t   the registers in the Core Power Domain */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_PRSR, &dummy);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * Static CTI configuration:\n\t * Channel 0 -> trigger outputs HALT request to PE\n\t * Channel 1 -> trigger outputs Resume request to PE\n\t * Gate all channel trigger events from entering the CTM\n\t */\n\n\t/* Enable CTI */\n\tretval = arm_cti_enable(armv8->cti, true);\n\t/* By default, gate all channel events to and from the CTM */\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0);\n\t/* output halt requests to PE on channel 0 event */\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_write_reg(armv8->cti, CTI_OUTEN0, CTI_CHNL(0));\n\t/* output restart requests to PE on channel 1 event */\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_write_reg(armv8->cti, CTI_OUTEN1, CTI_CHNL(1));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Resync breakpoint registers */\n\n\treturn ERROR_OK;\n}\n\n/* Write to memory mapped registers directly with no cache or mmu handling */\nstatic int aarch64_dap_write_memap_register_u32(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t value)\n{\n\tint retval;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap, address, value);\n\n\treturn retval;\n}\n\nstatic int aarch64_dpm_setup(struct aarch64_common *a8, uint64_t debug)\n{\n\tstruct arm_dpm *dpm = &a8->armv8_common.dpm;\n\tint retval;\n\n\tdpm->arm = &a8->armv8_common.arm;\n\tdpm->didr = debug;\n\n\tretval = armv8_dpm_setup(dpm);\n\tif (retval == ERROR_OK)\n\t\tretval = armv8_dpm_initialize(dpm);\n\n\treturn retval;\n}\n\nstatic int aarch64_set_dscr_bits(struct target *target, unsigned long bit_mask, unsigned long value)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\treturn armv8_set_dbgreg_bits(armv8, CPUV8_DBG_DSCR, bit_mask, value);\n}\n\nstatic int aarch64_check_state_one(struct target *target,\n\t\tuint32_t mask, uint32_t val, int *p_result, uint32_t *p_prsr)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tuint32_t prsr;\n\tint retval;\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_PRSR, &prsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (p_prsr)\n\t\t*p_prsr = prsr;\n\n\tif (p_result)\n\t\t*p_result = (prsr & mask) == (val & mask);\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_wait_halt_one(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tuint32_t prsr;\n\n\tint64_t then = timeval_ms();\n\tfor (;;) {\n\t\tint halted;\n\n\t\tretval = aarch64_check_state_one(target, PRSR_HALT, PRSR_HALT, &halted, &prsr);\n\t\tif (retval != ERROR_OK || halted)\n\t\t\tbreak;\n\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\tLOG_DEBUG(\"target %s timeout, prsr=0x%08\"PRIx32, target_name(target), prsr);\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int aarch64_prepare_halt_smp(struct target *target, bool exc_target, struct target **p_first)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\tstruct target *first = NULL;\n\n\tLOG_DEBUG(\"target %s exc %i\", target_name(target), exc_target);\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tstruct armv8_common *armv8 = target_to_armv8(curr);\n\n\t\tif (exc_target && curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\tif (curr->state != TARGET_RUNNING)\n\t\t\tcontinue;\n\n\t\t/* HACK: mark this target as prepared for halting */\n\t\tcurr->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t/* open the gate for channel 0 to let HALT requests pass to the CTM */\n\t\tretval = arm_cti_ungate_channel(armv8->cti, 0);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = aarch64_set_dscr_bits(curr, DSCR_HDE, DSCR_HDE);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tLOG_DEBUG(\"target %s prepared\", target_name(curr));\n\n\t\tif (!first)\n\t\t\tfirst = curr;\n\t}\n\n\tif (p_first) {\n\t\tif (exc_target && first)\n\t\t\t*p_first = first;\n\t\telse\n\t\t\t*p_first = target;\n\t}\n\n\treturn retval;\n}\n\nstatic int aarch64_halt_one(struct target *target, enum halt_mode mode)\n{\n\tint retval = ERROR_OK;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\t/* allow Halting Debug Mode */\n\tretval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* trigger an event on channel 0, this outputs a halt request to the PE */\n\tretval = arm_cti_pulse_channel(armv8->cti, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mode == HALT_SYNC) {\n\t\tretval = aarch64_wait_halt_one(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tif (retval == ERROR_TARGET_TIMEOUT)\n\t\t\t\tLOG_ERROR(\"Timeout waiting for target %s halt\", target_name(target));\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_halt_smp(struct target *target, bool exc_target)\n{\n\tstruct target *next = target;\n\tint retval;\n\n\t/* prepare halt on all PEs of the group */\n\tretval = aarch64_prepare_halt_smp(target, exc_target, &next);\n\n\tif (exc_target && next == target)\n\t\treturn retval;\n\n\t/* halt the target PE */\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_halt_one(next, HALT_LAZY);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* wait for all PEs to halt */\n\tint64_t then = timeval_ms();\n\tfor (;;) {\n\t\tbool all_halted = true;\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tint halted;\n\n\t\t\tcurr = head->target;\n\n\t\t\tif (!target_was_examined(curr))\n\t\t\t\tcontinue;\n\n\t\t\tretval = aarch64_check_state_one(curr, PRSR_HALT, PRSR_HALT, &halted, NULL);\n\t\t\tif (retval != ERROR_OK || !halted) {\n\t\t\t\tall_halted = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (all_halted)\n\t\t\tbreak;\n\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t * HACK: on Hi6220 there are 8 cores organized in 2 clusters\n\t\t * and it looks like the CTI's are not connected by a common\n\t\t * trigger matrix. It seems that we need to halt one core in each\n\t\t * cluster explicitly. So if we find that a core has not halted\n\t\t * yet, we trigger an explicit halt for the second cluster.\n\t\t */\n\t\tretval = aarch64_halt_one(curr, HALT_LAZY);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int update_halt_gdb(struct target *target, enum target_debug_reason debug_reason)\n{\n\tstruct target *gdb_target = NULL;\n\tstruct target_list *head;\n\tstruct target *curr;\n\n\tif (debug_reason == DBG_REASON_NOTHALTED) {\n\t\tLOG_DEBUG(\"Halting remaining targets in SMP group\");\n\t\taarch64_halt_smp(target, true);\n\t}\n\n\t/* poll all targets in the group, but skip the target that serves GDB */\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tcurr = head->target;\n\t\t/* skip calling context */\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\t/* skip targets that were already halted */\n\t\tif (curr->state == TARGET_HALTED)\n\t\t\tcontinue;\n\t\t/* remember the gdb_service->target */\n\t\tif (curr->gdb_service)\n\t\t\tgdb_target = curr->gdb_service->target;\n\t\t/* skip it */\n\t\tif (curr == gdb_target)\n\t\t\tcontinue;\n\n\t\t/* avoid recursion in aarch64_poll() */\n\t\tcurr->smp = 0;\n\t\taarch64_poll(curr);\n\t\tcurr->smp = 1;\n\t}\n\n\t/* after all targets were updated, poll the gdb serving target */\n\tif (gdb_target && gdb_target != target)\n\t\taarch64_poll(gdb_target);\n\n\treturn ERROR_OK;\n}\n\n/*\n * Aarch64 Run control\n */\n\nstatic int aarch64_poll(struct target *target)\n{\n\tenum target_state prev_target_state;\n\tint retval = ERROR_OK;\n\tint halted;\n\n\tretval = aarch64_check_state_one(target,\n\t\t\t\tPRSR_HALT, PRSR_HALT, &halted, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (halted) {\n\t\tprev_target_state = target->state;\n\t\tif (prev_target_state != TARGET_HALTED) {\n\t\t\tenum target_debug_reason debug_reason = target->debug_reason;\n\n\t\t\t/* We have a halting debug event */\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tLOG_DEBUG(\"Target %s halted\", target_name(target));\n\t\t\tretval = aarch64_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (target->smp)\n\t\t\t\tupdate_halt_gdb(target, debug_reason);\n\n\t\t\tif (arm_semihosting(target, &retval) != 0)\n\t\t\t\treturn retval;\n\n\t\t\tswitch (prev_target_state) {\n\t\t\tcase TARGET_RUNNING:\n\t\t\tcase TARGET_UNKNOWN:\n\t\t\tcase TARGET_RESET:\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t\tbreak;\n\t\t\tcase TARGET_DEBUG_RUNNING:\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n\n\treturn retval;\n}\n\nstatic int aarch64_halt(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tarmv8->last_run_control_op = ARMV8_RUNCONTROL_HALT;\n\n\tif (target->smp)\n\t\treturn aarch64_halt_smp(target, false);\n\n\treturn aarch64_halt_one(target, HALT_SYNC);\n}\n\nstatic int aarch64_restore_one(struct target *target, int current,\n\tuint64_t *address, int handle_breakpoints, int debug_execution)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\tint retval;\n\tuint64_t resume_pc;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tresume_pc = buf_get_u64(arm->pc->value, 0, 64);\n\tif (!current)\n\t\tresume_pc = *address;\n\telse\n\t\t*address = resume_pc;\n\n\t/* Make sure that the Armv7 gdb thumb fixups does not\n\t * kill the return address\n\t */\n\tswitch (arm->core_state) {\n\t\tcase ARM_STATE_ARM:\n\t\t\tresume_pc &= 0xFFFFFFFC;\n\t\t\tbreak;\n\t\tcase ARM_STATE_AARCH64:\n\t\t\tresume_pc &= 0xFFFFFFFFFFFFFFFCULL;\n\t\t\tbreak;\n\t\tcase ARM_STATE_THUMB:\n\t\tcase ARM_STATE_THUMB_EE:\n\t\t\t/* When the return address is loaded into PC\n\t\t\t * bit 0 must be 1 to stay in Thumb state\n\t\t\t */\n\t\t\tresume_pc |= 0x1;\n\t\t\tbreak;\n\t\tcase ARM_STATE_JAZELLE:\n\t\t\tLOG_ERROR(\"How do I resume into Jazelle state??\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"resume pc = 0x%016\" PRIx64, resume_pc);\n\tbuf_set_u64(arm->pc->value, 0, 64, resume_pc);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\t/* called it now before restoring context because it uses cpu\n\t * register r0 for restoring system control register */\n\tretval = aarch64_restore_system_control_reg(target);\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_restore_context(target, handle_breakpoints);\n\n\treturn retval;\n}\n\n/**\n * prepare single target for restart\n *\n *\n */\nstatic int aarch64_prepare_restart_one(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tint retval;\n\tuint32_t dscr;\n\tuint32_t tmp;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((dscr & DSCR_ITE) == 0)\n\t\tLOG_ERROR(\"DSCR.ITE must be set before leaving debug!\");\n\tif ((dscr & DSCR_ERR) != 0)\n\t\tLOG_ERROR(\"DSCR.ERR must be cleared before leaving debug!\");\n\n\t/* acknowledge a pending CTI halt event */\n\tretval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT));\n\t/*\n\t * open the CTI gate for channel 1 so that the restart events\n\t * get passed along to all PEs. Also close gate for channel 0\n\t * to isolate the PE from halt events.\n\t */\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_ungate_channel(armv8->cti, 1);\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_gate_channel(armv8->cti, 0);\n\n\t/* make sure that DSCR.HDE is set */\n\tif (retval == ERROR_OK) {\n\t\tdscr |= DSCR_HDE;\n\t\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, dscr);\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\t/* clear sticky bits in PRSR, SDR is now 0 */\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_PRSR, &tmp);\n\t}\n\n\treturn retval;\n}\n\nstatic int aarch64_do_restart_one(struct target *target, enum restart_mode mode)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\t/* trigger an event on channel 1, generates a restart request to the PE */\n\tretval = arm_cti_pulse_channel(armv8->cti, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mode == RESTART_SYNC) {\n\t\tint64_t then = timeval_ms();\n\t\tfor (;;) {\n\t\t\tint resumed;\n\t\t\t/*\n\t\t\t * if PRSR.SDR is set now, the target did restart, even\n\t\t\t * if it's now already halted again (e.g. due to breakpoint)\n\t\t\t */\n\t\t\tretval = aarch64_check_state_one(target,\n\t\t\t\t\t\tPRSR_SDR, PRSR_SDR, &resumed, NULL);\n\t\t\tif (retval != ERROR_OK || resumed)\n\t\t\t\tbreak;\n\n\t\t\tif (timeval_ms() > then + 1000) {\n\t\t\t\tLOG_ERROR(\"%s: Timeout waiting for resume\"PRIx32, target_name(target));\n\t\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\ttarget->state = TARGET_RUNNING;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_restart_one(struct target *target, enum restart_mode mode)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tretval = aarch64_prepare_restart_one(target);\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_do_restart_one(target, mode);\n\n\treturn retval;\n}\n\n/*\n * prepare all but the current target for restart\n */\nstatic int aarch64_prep_restart_smp(struct target *target, int handle_breakpoints, struct target **p_first)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\tstruct target *first = NULL;\n\tuint64_t address;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\n\t\t/* skip calling target */\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\tif (curr->state != TARGET_HALTED)\n\t\t\tcontinue;\n\n\t\t/*  resume at current address, not in step mode */\n\t\tretval = aarch64_restore_one(curr, 1, &address, handle_breakpoints, 0);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = aarch64_prepare_restart_one(curr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to restore target %s\", target_name(curr));\n\t\t\tbreak;\n\t\t}\n\t\t/* remember the first valid target in the group */\n\t\tif (!first)\n\t\t\tfirst = curr;\n\t}\n\n\tif (p_first)\n\t\t*p_first = first;\n\n\treturn retval;\n}\n\n\nstatic int aarch64_step_restart_smp(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\tstruct target *first = NULL;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tretval = aarch64_prep_restart_smp(target, 0, &first);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (first)\n\t\tretval = aarch64_do_restart_one(first, RESTART_LAZY);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"error restarting target %s\", target_name(first));\n\t\treturn retval;\n\t}\n\n\tint64_t then = timeval_ms();\n\tfor (;;) {\n\t\tstruct target *curr = target;\n\t\tbool all_resumed = true;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tuint32_t prsr;\n\t\t\tint resumed;\n\n\t\t\tcurr = head->target;\n\n\t\t\tif (curr == target)\n\t\t\t\tcontinue;\n\n\t\t\tif (!target_was_examined(curr))\n\t\t\t\tcontinue;\n\n\t\t\tretval = aarch64_check_state_one(curr,\n\t\t\t\t\tPRSR_SDR, PRSR_SDR, &resumed, &prsr);\n\t\t\tif (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) {\n\t\t\t\tall_resumed = false;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (curr->state != TARGET_RUNNING) {\n\t\t\t\tcurr->state = TARGET_RUNNING;\n\t\t\t\tcurr->debug_reason = DBG_REASON_NOTHALTED;\n\t\t\t\ttarget_call_event_callbacks(curr, TARGET_EVENT_RESUMED);\n\t\t\t}\n\t\t}\n\n\t\tif (all_resumed)\n\t\t\tbreak;\n\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"%s: timeout waiting for target resume\", __func__);\n\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\tbreak;\n\t\t}\n\t\t/*\n\t\t * HACK: on Hi6220 there are 8 cores organized in 2 clusters\n\t\t * and it looks like the CTI's are not connected by a common\n\t\t * trigger matrix. It seems that we need to halt one core in each\n\t\t * cluster explicitly. So if we find that a core has not halted\n\t\t * yet, we trigger an explicit resume for the second cluster.\n\t\t */\n\t\tretval = aarch64_do_restart_one(curr, RESTART_LAZY);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n}\n\n\treturn retval;\n}\n\nstatic int aarch64_resume(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tint retval = 0;\n\tuint64_t addr = address;\n\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tarmv8->last_run_control_op = ARMV8_RUNCONTROL_RESUME;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/*\n\t * If this target is part of a SMP group, prepare the others\n\t * targets for resuming. This involves restoring the complete\n\t * target register context and setting up CTI gates to accept\n\t * resume events from the trigger matrix.\n\t */\n\tif (target->smp) {\n\t\tretval = aarch64_prep_restart_smp(target, handle_breakpoints, NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* all targets prepared, restore and restart the current target */\n\tretval = aarch64_restore_one(target, current, &addr, handle_breakpoints,\n\t\t\t\t debug_execution);\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_restart_one(target, RESTART_SYNC);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->smp) {\n\t\tint64_t then = timeval_ms();\n\t\tfor (;;) {\n\t\t\tstruct target *curr = target;\n\t\t\tstruct target_list *head;\n\t\t\tbool all_resumed = true;\n\n\t\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\t\tuint32_t prsr;\n\t\t\t\tint resumed;\n\n\t\t\t\tcurr = head->target;\n\t\t\t\tif (curr == target)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!target_was_examined(curr))\n\t\t\t\t\tcontinue;\n\n\t\t\t\tretval = aarch64_check_state_one(curr,\n\t\t\t\t\t\tPRSR_SDR, PRSR_SDR, &resumed, &prsr);\n\t\t\t\tif (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) {\n\t\t\t\t\tall_resumed = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (curr->state != TARGET_RUNNING) {\n\t\t\t\t\tcurr->state = TARGET_RUNNING;\n\t\t\t\t\tcurr->debug_reason = DBG_REASON_NOTHALTED;\n\t\t\t\t\ttarget_call_event_callbacks(curr, TARGET_EVENT_RESUMED);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (all_resumed)\n\t\t\t\tbreak;\n\n\t\t\tif (timeval_ms() > then + 1000) {\n\t\t\t\tLOG_ERROR(\"%s: timeout waiting for target %s to resume\", __func__, target_name(curr));\n\t\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * HACK: on Hi6220 there are 8 cores organized in 2 clusters\n\t\t\t * and it looks like the CTI's are not connected by a common\n\t\t\t * trigger matrix. It seems that we need to halt one core in each\n\t\t\t * cluster explicitly. So if we find that a core has not halted\n\t\t\t * yet, we trigger an explicit resume for the second cluster.\n\t\t\t */\n\t\t\tretval = aarch64_do_restart_one(curr, RESTART_LAZY);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"target resumed at 0x%\" PRIx64, addr);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"target debug resumed at 0x%\" PRIx64, addr);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_debug_entry(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tenum arm_state core_state;\n\tuint32_t dscr;\n\n\t/* make sure to clear all sticky errors */\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);\n\tif (retval == ERROR_OK)\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT));\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"%s dscr = 0x%08\" PRIx32, target_name(target), dscr);\n\n\tdpm->dscr = dscr;\n\tcore_state = armv8_dpm_get_core_state(dpm);\n\tarmv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);\n\tarmv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);\n\n\t/* close the CTI gate for all events */\n\tif (retval == ERROR_OK)\n\t\tretval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0);\n\t/* discard async exceptions */\n\tif (retval == ERROR_OK)\n\t\tretval = dpm->instr_cpsr_sync(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Examine debug reason */\n\tarmv8_dpm_report_dscr(dpm, dscr);\n\n\t/* save the memory address that triggered the watchpoint */\n\tif (target->debug_reason == DBG_REASON_WATCHPOINT) {\n\t\tuint32_t tmp;\n\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_EDWAR0, &tmp);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\ttarget_addr_t edwar = tmp;\n\n\t\t/* EDWAR[63:32] has unknown content in aarch32 state */\n\t\tif (core_state == ARM_STATE_AARCH64) {\n\t\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_EDWAR1, &tmp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tedwar |= ((target_addr_t)tmp) << 32;\n\t\t}\n\n\t\tarmv8->dpm.wp_addr = edwar;\n\t}\n\n\tretval = armv8_dpm_read_current_registers(&armv8->dpm);\n\n\tif (retval == ERROR_OK && armv8->post_debug_entry)\n\t\tretval = armv8->post_debug_entry(target);\n\n\treturn retval;\n}\n\nstatic int aarch64_post_debug_entry(struct target *target)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tint retval;\n\tenum arm_mode target_mode = ARM_MODE_ANY;\n\tuint32_t instr;\n\n\tswitch (armv8->arm.core_mode) {\n\tcase ARMV8_64_EL0T:\n\t\ttarget_mode = ARMV8_64_EL1H;\n\t\t/* fall through */\n\tcase ARMV8_64_EL1T:\n\tcase ARMV8_64_EL1H:\n\t\tinstr = ARMV8_MRS(SYSTEM_SCTLR_EL1, 0);\n\t\tbreak;\n\tcase ARMV8_64_EL2T:\n\tcase ARMV8_64_EL2H:\n\t\tinstr = ARMV8_MRS(SYSTEM_SCTLR_EL2, 0);\n\t\tbreak;\n\tcase ARMV8_64_EL3H:\n\tcase ARMV8_64_EL3T:\n\t\tinstr = ARMV8_MRS(SYSTEM_SCTLR_EL3, 0);\n\t\tbreak;\n\n\tcase ARM_MODE_SVC:\n\tcase ARM_MODE_ABT:\n\tcase ARM_MODE_FIQ:\n\tcase ARM_MODE_IRQ:\n\tcase ARM_MODE_HYP:\n\tcase ARM_MODE_UND:\n\tcase ARM_MODE_SYS:\n\t\tinstr = ARMV4_5_MRC(15, 0, 0, 1, 0, 0);\n\t\tbreak;\n\n\tdefault:\n\t\tLOG_ERROR(\"cannot read system control register in this mode: (%s : 0x%x)\",\n\t\t\t\tarmv8_mode_name(armv8->arm.core_mode), armv8->arm.core_mode);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(&armv8->dpm, target_mode);\n\n\tretval = armv8->dpm.instr_read_data_r0(&armv8->dpm, instr, &aarch64->system_control_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);\n\n\tLOG_DEBUG(\"System_register: %8.8\" PRIx32, aarch64->system_control_reg);\n\taarch64->system_control_reg_curr = aarch64->system_control_reg;\n\n\tif (armv8->armv8_mmu.armv8_cache.info == -1) {\n\t\tarmv8_identify_cache(armv8);\n\t\tarmv8_read_mpidr(armv8);\n\t}\n\tif (armv8->is_armv8r) {\n\t\tarmv8->armv8_mmu.mmu_enabled = 0;\n\t} else {\n\t\tarmv8->armv8_mmu.mmu_enabled =\n\t\t\t(aarch64->system_control_reg & 0x1U) ? 1 : 0;\n\t}\n\tarmv8->armv8_mmu.armv8_cache.d_u_cache_enabled =\n\t\t(aarch64->system_control_reg & 0x4U) ? 1 : 0;\n\tarmv8->armv8_mmu.armv8_cache.i_cache_enabled =\n\t\t(aarch64->system_control_reg & 0x1000U) ? 1 : 0;\n\treturn ERROR_OK;\n}\n\n/*\n * single-step a target\n */\nstatic int aarch64_step(struct target *target, int current, target_addr_t address,\n\tint handle_breakpoints)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tint saved_retval = ERROR_OK;\n\tint retval;\n\tuint32_t edecr;\n\n\tarmv8->last_run_control_op = ARMV8_RUNCONTROL_STEP;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_EDECR, &edecr);\n\t/* make sure EDECR.SS is not set when restoring the register */\n\n\tif (retval == ERROR_OK) {\n\t\tedecr &= ~0x4;\n\t\t/* set EDECR.SS to enter hardware step mode */\n\t\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_EDECR, (edecr|0x4));\n\t}\n\t/* disable interrupts while stepping */\n\tif (retval == ERROR_OK && aarch64->isrmasking_mode == AARCH64_ISRMASK_ON)\n\t\tretval = aarch64_set_dscr_bits(target, 0x3 << 22, 0x3 << 22);\n\t/* bail out if stepping setup has failed */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->smp && (current == 1)) {\n\t\t/*\n\t\t * isolate current target so that it doesn't get resumed\n\t\t * together with the others\n\t\t */\n\t\tretval = arm_cti_gate_channel(armv8->cti, 1);\n\t\t/* resume all other targets in the group */\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = aarch64_step_restart_smp(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to restart non-stepping targets in SMP group\");\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"Restarted all non-stepping targets in SMP group\");\n\t}\n\n\t/* all other targets running, restore and restart the current target */\n\tretval = aarch64_restore_one(target, current, &address, 0, 0);\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_restart_one(target, RESTART_LAZY);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"target step-resumed at 0x%\" PRIx64, address);\n\tif (!handle_breakpoints)\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\tint64_t then = timeval_ms();\n\tfor (;;) {\n\t\tint stepped;\n\t\tuint32_t prsr;\n\n\t\tretval = aarch64_check_state_one(target,\n\t\t\t\t\tPRSR_SDR|PRSR_HALT, PRSR_SDR|PRSR_HALT, &stepped, &prsr);\n\t\tif (retval != ERROR_OK || stepped)\n\t\t\tbreak;\n\n\t\tif (timeval_ms() > then + 100) {\n\t\t\tLOG_ERROR(\"timeout waiting for target %s halt after step\",\n\t\t\t\t\ttarget_name(target));\n\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/*\n\t * At least on one SoC (Renesas R8A7795) stepping over a WFI instruction\n\t * causes a timeout. The core takes the step but doesn't complete it and so\n\t * debug state is never entered. However, you can manually halt the core\n\t * as an external debug even is also a WFI wakeup event.\n\t */\n\tif (retval == ERROR_TARGET_TIMEOUT)\n\t\tsaved_retval = aarch64_halt_one(target, HALT_SYNC);\n\n\t/* restore EDECR */\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_EDECR, edecr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* restore interrupts */\n\tif (aarch64->isrmasking_mode == AARCH64_ISRMASK_ON) {\n\t\tretval = aarch64_set_dscr_bits(target, 0x3 << 22, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t}\n\n\tif (saved_retval != ERROR_OK)\n\t\treturn saved_retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_restore_context(struct target *target, bool bpwp)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", target_name(target));\n\n\tif (armv8->pre_restore_context)\n\t\tarmv8->pre_restore_context(target);\n\n\tretval = armv8_dpm_write_dirty_registers(&armv8->dpm, bpwp);\n\tif (retval == ERROR_OK) {\n\t\t/* registers are now invalid */\n\t\tregister_cache_invalidate(arm->core_cache);\n\t\tregister_cache_invalidate(arm->core_cache->next);\n\t}\n\n\treturn retval;\n}\n\n/*\n * Cortex-A8 Breakpoint and watchpoint functions\n */\n\n/* Setup hardware Breakpoint Register Pair */\nstatic int aarch64_set_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode)\n{\n\tint retval;\n\tint brp_i = 0;\n\tuint32_t control;\n\tuint8_t byte_addr_select = 0x0F;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *brp_list = aarch64->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tint64_t bpt_value;\n\t\twhile (brp_list[brp_i].used && (brp_i < aarch64->brp_num))\n\t\t\tbrp_i++;\n\t\tif (brp_i >= aarch64->brp_num) {\n\t\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint_hw_set(breakpoint, brp_i);\n\t\tif (breakpoint->length == 2)\n\t\t\tbyte_addr_select = (3 << (breakpoint->address & 0x02));\n\t\tcontrol = ((matchmode & 0x7) << 20)\n\t\t\t| (1 << 13)\n\t\t\t| (byte_addr_select << 5)\n\t\t\t| (3 << 1) | 1;\n\t\tbrp_list[brp_i].used = 1;\n\t\tbrp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;\n\t\tbrp_list[brp_i].control = control;\n\t\tbpt_value = brp_list[brp_i].value;\n\n\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\t(uint32_t)(bpt_value & 0xFFFFFFFF));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t+ CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,\n\t\t\t\t(uint32_t)(bpt_value >> 32));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\tbrp_list[brp_i].control);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"brp %i control 0x%0\" PRIx32 \" value 0x%\" TARGET_PRIxADDR, brp_i,\n\t\t\tbrp_list[brp_i].control,\n\t\t\tbrp_list[brp_i].value);\n\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tuint32_t opcode;\n\t\tuint8_t code[4];\n\n\t\tif (armv8_dpm_get_core_state(&armv8->dpm) == ARM_STATE_AARCH64) {\n\t\t\topcode = ARMV8_HLT(11);\n\n\t\t\tif (breakpoint->length != 4)\n\t\t\t\tLOG_ERROR(\"bug: breakpoint length should be 4 in AArch64 mode\");\n\t\t} else {\n\t\t\t/**\n\t\t\t * core_state is ARM_STATE_ARM\n\t\t\t * in that case the opcode depends on breakpoint length:\n\t\t\t *  - if length == 4 => A32 opcode\n\t\t\t *  - if length == 2 => T32 opcode\n\t\t\t *  - if length == 3 => T32 opcode (refer to gdb doc : ARM-Breakpoint-Kinds)\n\t\t\t *    in that case the length should be changed from 3 to 4 bytes\n\t\t\t **/\n\t\t\topcode = (breakpoint->length == 4) ? ARMV8_HLT_A1(11) :\n\t\t\t\t\t(uint32_t) (ARMV8_HLT_T1(11) | ARMV8_HLT_T1(11) << 16);\n\n\t\t\tif (breakpoint->length == 3)\n\t\t\t\tbreakpoint->length = 4;\n\t\t}\n\n\t\tbuf_set_u32(code, 0, 32, opcode);\n\n\t\tretval = target_read_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length, 1,\n\t\t\t\tbreakpoint->orig_instr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tarmv8_cache_d_inner_flush_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\n\t\tretval = target_write_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length, 1, code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tarmv8_cache_d_inner_flush_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\n\t\tarmv8_cache_i_inner_inval_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\n\t\tbreakpoint->is_set = true;\n\t}\n\n\t/* Ensure that halting debug mode is enable */\n\tretval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed to set DSCR.HDE\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_set_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode)\n{\n\tint retval = ERROR_FAIL;\n\tint brp_i = 0;\n\tuint32_t control;\n\tuint8_t byte_addr_select = 0x0F;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *brp_list = aarch64->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn retval;\n\t}\n\t/*check available context BRPs*/\n\twhile ((brp_list[brp_i].used ||\n\t\t(brp_list[brp_i].type != BRP_CONTEXT)) && (brp_i < aarch64->brp_num))\n\t\tbrp_i++;\n\n\tif (brp_i >= aarch64->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbreakpoint_hw_set(breakpoint, brp_i);\n\tcontrol = ((matchmode & 0x7) << 20)\n\t\t| (1 << 13)\n\t\t| (byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_i].used = 1;\n\tbrp_list[brp_i].value = (breakpoint->asid);\n\tbrp_list[brp_i].control = control;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\tbrp_list[brp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\tbrp_list[brp_i].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"brp %i control 0x%0\" PRIx32 \" value 0x%\" TARGET_PRIxADDR, brp_i,\n\t\tbrp_list[brp_i].control,\n\t\tbrp_list[brp_i].value);\n\treturn ERROR_OK;\n\n}\n\nstatic int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval = ERROR_FAIL;\n\tint brp_1 = 0;\t/* holds the contextID pair */\n\tint brp_2 = 0;\t/* holds the IVA pair */\n\tuint32_t control_ctx, control_iva;\n\tuint8_t ctx_byte_addr_select = 0x0F;\n\tuint8_t iva_byte_addr_select = 0x0F;\n\tuint8_t ctx_machmode = 0x03;\n\tuint8_t iva_machmode = 0x01;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *brp_list = aarch64->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn retval;\n\t}\n\t/*check available context BRPs*/\n\twhile ((brp_list[brp_1].used ||\n\t\t(brp_list[brp_1].type != BRP_CONTEXT)) && (brp_1 < aarch64->brp_num))\n\t\tbrp_1++;\n\n\tLOG_DEBUG(\"brp(CTX) found num: %d\", brp_1);\n\tif (brp_1 >= aarch64->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\twhile ((brp_list[brp_2].used ||\n\t\t(brp_list[brp_2].type != BRP_NORMAL)) && (brp_2 < aarch64->brp_num))\n\t\tbrp_2++;\n\n\tLOG_DEBUG(\"brp(IVA) found num: %d\", brp_2);\n\tif (brp_2 >= aarch64->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbreakpoint_hw_set(breakpoint, brp_1);\n\tbreakpoint->linked_brp = brp_2;\n\tcontrol_ctx = ((ctx_machmode & 0x7) << 20)\n\t\t| (brp_2 << 16)\n\t\t| (0 << 14)\n\t\t| (ctx_byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_1].used = 1;\n\tbrp_list[brp_1].value = (breakpoint->asid);\n\tbrp_list[brp_1].control = control_ctx;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_1].brpn,\n\t\t\tbrp_list[brp_1].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_1].brpn,\n\t\t\tbrp_list[brp_1].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcontrol_iva = ((iva_machmode & 0x7) << 20)\n\t\t| (brp_1 << 16)\n\t\t| (1 << 13)\n\t\t| (iva_byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_2].used = 1;\n\tbrp_list[brp_2].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;\n\tbrp_list[brp_2].control = control_iva;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_2].brpn,\n\t\t\tbrp_list[brp_2].value & 0xFFFFFFFF);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_2].brpn,\n\t\t\tbrp_list[brp_2].value >> 32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_2].brpn,\n\t\t\tbrp_list[brp_2].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *brp_list = aarch64->brp_list;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tif ((breakpoint->address != 0) && (breakpoint->asid != 0)) {\n\t\t\tint brp_i = breakpoint->number;\n\t\t\tint brp_j = breakpoint->linked_brp;\n\t\t\tif (brp_i >= aarch64->brp_num) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%\" TARGET_PRIxADDR, brp_i,\n\t\t\t\tbrp_list[brp_i].control, brp_list[brp_i].value);\n\t\t\tbrp_list[brp_i].used = 0;\n\t\t\tbrp_list[brp_i].value = 0;\n\t\t\tbrp_list[brp_i].control = 0;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\t(uint32_t)brp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\t(uint32_t)brp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif ((brp_j < 0) || (brp_j >= aarch64->brp_num)) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx64, brp_j,\n\t\t\t\tbrp_list[brp_j].control, brp_list[brp_j].value);\n\t\t\tbrp_list[brp_j].used = 0;\n\t\t\tbrp_list[brp_j].value = 0;\n\t\t\tbrp_list[brp_j].control = 0;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_j].brpn,\n\t\t\t\t\tbrp_list[brp_j].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_j].brpn,\n\t\t\t\t\t(uint32_t)brp_list[brp_j].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_j].brpn,\n\t\t\t\t\t(uint32_t)brp_list[brp_j].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tbreakpoint->linked_brp = 0;\n\t\t\tbreakpoint->is_set = false;\n\t\t\treturn ERROR_OK;\n\n\t\t} else {\n\t\t\tint brp_i = breakpoint->number;\n\t\t\tif (brp_i >= aarch64->brp_num) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx64, brp_i,\n\t\t\t\tbrp_list[brp_i].control, brp_list[brp_i].value);\n\t\t\tbrp_list[brp_i].used = 0;\n\t\t\tbrp_list[brp_i].value = 0;\n\t\t\tbrp_list[brp_i].control = 0;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BCR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t\t\t+ CPUV8_DBG_BVR_BASE + 4 + 16 * brp_list[brp_i].brpn,\n\t\t\t\t\t(uint32_t)brp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreakpoint->is_set = false;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\n\t\tarmv8_cache_d_inner_flush_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\n\t\tif (breakpoint->length == 4) {\n\t\t\tretval = target_write_memory(target,\n\t\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\t\t4, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tretval = target_write_memory(target,\n\t\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\t\t2, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tarmv8_cache_d_inner_flush_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\n\t\tarmv8_cache_i_inner_inval_virt(armv8,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFFFFFFFFFEULL,\n\t\t\t\tbreakpoint->length);\n\t}\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_add_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\taarch64->brp_num_available--;\n\n\treturn aarch64_set_breakpoint(target, breakpoint, 0x00);\t/* Exact match */\n}\n\nstatic int aarch64_add_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\taarch64->brp_num_available--;\n\n\treturn aarch64_set_context_breakpoint(target, breakpoint, 0x02);\t/* asid match */\n}\n\nstatic int aarch64_add_hybrid_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (aarch64->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\taarch64->brp_num_available--;\n\n\treturn aarch64_set_hybrid_breakpoint(target, breakpoint);\t/* ??? */\n}\n\nstatic int aarch64_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n#if 0\n/* It is perfectly possible to remove breakpoints while the target is running */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n#endif\n\n\tif (breakpoint->is_set) {\n\t\taarch64_unset_breakpoint(target, breakpoint);\n\t\tif (breakpoint->type == BKPT_HARD)\n\t\t\taarch64->brp_num_available++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Setup hardware Watchpoint Register Pair */\nstatic int aarch64_set_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tint retval;\n\tint wp_i = 0;\n\tuint32_t control, offset, length;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *wp_list = aarch64->wp_list;\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (wp_list[wp_i].used && (wp_i < aarch64->wp_num))\n\t\twp_i++;\n\tif (wp_i >= aarch64->wp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Watchpoint Register Pair\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tcontrol = (1 << 0)      /* enable */\n\t\t| (3 << 1)      /* both user and privileged access */\n\t\t| (1 << 13);    /* higher mode control */\n\n\tswitch (watchpoint->rw) {\n\tcase WPT_READ:\n\t\tcontrol |= 1 << 3;\n\t\tbreak;\n\tcase WPT_WRITE:\n\t\tcontrol |= 2 << 3;\n\t\tbreak;\n\tcase WPT_ACCESS:\n\t\tcontrol |= 3 << 3;\n\t\tbreak;\n\t}\n\n\t/* Match up to 8 bytes. */\n\toffset = watchpoint->address & 7;\n\tlength = watchpoint->length;\n\tif (offset + length > sizeof(uint64_t)) {\n\t\tlength = sizeof(uint64_t) - offset;\n\t\tLOG_WARNING(\"Adjust watchpoint match inside 8-byte boundary\");\n\t}\n\tfor (; length > 0; offset++, length--)\n\t\tcontrol |= (1 << offset) << 5;\n\n\twp_list[wp_i].value = watchpoint->address & 0xFFFFFFFFFFFFFFF8ULL;\n\twp_list[wp_i].control = control;\n\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WVR_BASE + 16 * wp_list[wp_i].brpn,\n\t\t\t(uint32_t)(wp_list[wp_i].value & 0xFFFFFFFF));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WVR_BASE + 4 + 16 * wp_list[wp_i].brpn,\n\t\t\t(uint32_t)(wp_list[wp_i].value >> 32));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WCR_BASE + 16 * wp_list[wp_i].brpn,\n\t\t\tcontrol);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"wp %i control 0x%0\" PRIx32 \" value 0x%\" TARGET_PRIxADDR, wp_i,\n\t\twp_list[wp_i].control, wp_list[wp_i].value);\n\n\t/* Ensure that halting debug mode is enable */\n\tretval = aarch64_set_dscr_bits(target, DSCR_HDE, DSCR_HDE);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed to set DSCR.HDE\");\n\t\treturn retval;\n\t}\n\n\twp_list[wp_i].used = 1;\n\twatchpoint_set(watchpoint, wp_i);\n\n\treturn ERROR_OK;\n}\n\n/* Clear hardware Watchpoint Register Pair */\nstatic int aarch64_unset_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tint retval;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct aarch64_brp *wp_list = aarch64->wp_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wp_i = watchpoint->number;\n\tif (wp_i >= aarch64->wp_num) {\n\t\tLOG_DEBUG(\"Invalid WP number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tLOG_DEBUG(\"rwp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx64, wp_i,\n\t\twp_list[wp_i].control, wp_list[wp_i].value);\n\twp_list[wp_i].used = 0;\n\twp_list[wp_i].value = 0;\n\twp_list[wp_i].control = 0;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WCR_BASE + 16 * wp_list[wp_i].brpn,\n\t\t\twp_list[wp_i].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WVR_BASE + 16 * wp_list[wp_i].brpn,\n\t\t\twp_list[wp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base\n\t\t\t+ CPUV8_DBG_WVR_BASE + 4 + 16 * wp_list[wp_i].brpn,\n\t\t\t(uint32_t)wp_list[wp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_add_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tint retval;\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif (aarch64->wp_num_available < 1) {\n\t\tLOG_INFO(\"no hardware watchpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = aarch64_set_watchpoint(target, watchpoint);\n\tif (retval == ERROR_OK)\n\t\taarch64->wp_num_available--;\n\n\treturn retval;\n}\n\nstatic int aarch64_remove_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif (watchpoint->is_set) {\n\t\taarch64_unset_watchpoint(target, watchpoint);\n\t\taarch64->wp_num_available++;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * find out which watchpoint hits\n * get exception address and compare the address to watchpoints\n */\nstatic int aarch64_hit_watchpoint(struct target *target,\n\tstruct watchpoint **hit_watchpoint)\n{\n\tif (target->debug_reason != DBG_REASON_WATCHPOINT)\n\t\treturn ERROR_FAIL;\n\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\ttarget_addr_t exception_address;\n\tstruct watchpoint *wp;\n\n\texception_address = armv8->dpm.wp_addr;\n\n\tif (exception_address == 0xFFFFFFFF)\n\t\treturn ERROR_FAIL;\n\n\tfor (wp = target->watchpoints; wp; wp = wp->next)\n\t\tif (exception_address >= wp->address && exception_address < (wp->address + wp->length)) {\n\t\t\t*hit_watchpoint = wp;\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\treturn ERROR_FAIL;\n}\n\n/*\n * Cortex-A8 Reset functions\n */\n\nstatic int aarch64_enable_reset_catch(struct target *target, bool enable)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tuint32_t edecr;\n\tint retval;\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_EDECR, &edecr);\n\tLOG_DEBUG(\"EDECR = 0x%08\" PRIx32 \", enable=%d\", edecr, enable);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (enable)\n\t\tedecr |= ECR_RCE;\n\telse\n\t\tedecr &= ~ECR_RCE;\n\n\treturn mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_EDECR, edecr);\n}\n\nstatic int aarch64_clear_reset_catch(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tuint32_t edesr;\n\tint retval;\n\tbool was_triggered;\n\n\t/* check if Reset Catch debug event triggered as expected */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\tarmv8->debug_base + CPUV8_DBG_EDESR, &edesr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\twas_triggered = !!(edesr & ESR_RC);\n\tLOG_DEBUG(\"Reset Catch debug event %s\",\n\t\t\twas_triggered ? \"triggered\" : \"NOT triggered!\");\n\n\tif (was_triggered) {\n\t\t/* clear pending Reset Catch debug event */\n\t\tedesr &= ~ESR_RC;\n\t\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_EDESR, edesr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_assert_reset(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tenum reset_types reset_config = jtag_get_reset_config();\n\tint retval;\n\n\tLOG_DEBUG(\" \");\n\n\t/* Issue some kind of warm reset. */\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\telse if (reset_config & RESET_HAS_SRST) {\n\t\tbool srst_asserted = false;\n\n\t\tif (target->reset_halt && !(reset_config & RESET_SRST_PULLS_TRST)) {\n\t\t\tif (target_was_examined(target)) {\n\n\t\t\t\tif (reset_config & RESET_SRST_NO_GATING) {\n\t\t\t\t\t/*\n\t\t\t\t\t * SRST needs to be asserted *before* Reset Catch\n\t\t\t\t\t * debug event can be set up.\n\t\t\t\t\t */\n\t\t\t\t\tadapter_assert_reset();\n\t\t\t\t\tsrst_asserted = true;\n\t\t\t\t}\n\n\t\t\t\t/* make sure to clear all sticky errors */\n\t\t\t\tmem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);\n\n\t\t\t\t/* set up Reset Catch debug event to halt the CPU after reset */\n\t\t\t\tretval = aarch64_enable_reset_catch(target, true);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tLOG_WARNING(\"%s: Error enabling Reset Catch debug event; the CPU will not halt immediately after reset!\",\n\t\t\t\t\t\t\ttarget_name(target));\n\t\t\t} else {\n\t\t\t\tLOG_WARNING(\"%s: Target not examined, will not halt immediately after reset!\",\n\t\t\t\t\t\ttarget_name(target));\n\t\t\t}\n\t\t}\n\n\t\t/* REVISIT handle \"pulls\" cases, if there's\n\t\t * hardware that needs them to work.\n\t\t */\n\t\tif (!srst_asserted)\n\t\t\tadapter_assert_reset();\n\t} else {\n\t\tLOG_ERROR(\"%s: how to reset?\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* registers are now invalid */\n\tif (target_was_examined(target)) {\n\t\tregister_cache_invalidate(armv8->arm.core_cache);\n\t\tregister_cache_invalidate(armv8->arm.core_cache->next);\n\t}\n\n\ttarget->state = TARGET_RESET;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_deassert_reset(struct target *target)\n{\n\tint retval;\n\n\tLOG_DEBUG(\" \");\n\n\t/* be certain SRST is off */\n\tadapter_deassert_reset();\n\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\n\tretval = aarch64_init_debug_access(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = aarch64_poll(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->reset_halt) {\n\t\t/* clear pending Reset Catch debug event */\n\t\tretval = aarch64_clear_reset_catch(target);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_WARNING(\"%s: Clearing Reset Catch debug event failed\",\n\t\t\t\t\ttarget_name(target));\n\n\t\t/* disable Reset Catch debug event */\n\t\tretval = aarch64_enable_reset_catch(target, false);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_WARNING(\"%s: Disabling Reset Catch debug event failed\",\n\t\t\t\t\ttarget_name(target));\n\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_WARNING(\"%s: ran after reset and before halt ...\",\n\t\t\t\ttarget_name(target));\n\t\t\tif (target_was_examined(target)) {\n\t\t\t\tretval = aarch64_halt_one(target, HALT_LAZY);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else {\n\t\t\t\ttarget->state = TARGET_UNKNOWN;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_write_cpu_memory_slow(struct target *target,\n\tuint32_t size, uint32_t count, const uint8_t *buffer, uint32_t *dscr)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct arm *arm = &armv8->arm;\n\tint retval;\n\n\tarmv8_reg_current(arm, 1)->dirty = true;\n\n\t/* change DCC to normal mode if necessary */\n\tif (*dscr & DSCR_MA) {\n\t\t*dscr &= ~DSCR_MA;\n\t\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\twhile (count) {\n\t\tuint32_t data, opcode;\n\n\t\t/* write the data to store into DTRRX */\n\t\tif (size == 1)\n\t\t\tdata = *buffer;\n\t\telse if (size == 2)\n\t\t\tdata = target_buffer_get_u16(target, buffer);\n\t\telse\n\t\t\tdata = target_buffer_get_u32(target, buffer);\n\t\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRRX, data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (arm->core_state == ARM_STATE_AARCH64)\n\t\t\tretval = dpm->instr_execute(dpm, ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 1));\n\t\telse\n\t\t\tretval = dpm->instr_execute(dpm, ARMV4_5_MRC(14, 0, 1, 0, 5, 0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (size == 1)\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_STRB_IP);\n\t\telse if (size == 2)\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_STRH_IP);\n\t\telse\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_STRW_IP);\n\t\tretval = dpm->instr_execute(dpm, opcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Advance */\n\t\tbuffer += size;\n\t\t--count;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_write_cpu_memory_fast(struct target *target,\n\tuint32_t count, const uint8_t *buffer, uint32_t *dscr)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\tint retval;\n\n\tarmv8_reg_current(arm, 1)->dirty = true;\n\n\t/* Step 1.d   - Change DCC to memory mode */\n\t*dscr |= DSCR_MA;\n\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\n\t/* Step 2.a   - Do the write */\n\tretval = mem_ap_write_buf_noincr(armv8->debug_ap,\n\t\t\t\t\tbuffer, 4, count, armv8->debug_base + CPUV8_DBG_DTRRX);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Step 3.a   - Switch DTR mode back to Normal mode */\n\t*dscr &= ~DSCR_MA;\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_write_cpu_memory(struct target *target,\n\tuint64_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\t/* write memory through APB-AP */\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct arm *arm = &armv8->arm;\n\tuint32_t dscr;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Mark register X0 as dirty, as it will be used\n\t * for transferring the data.\n\t * It will be restored automatically when exiting\n\t * debug mode\n\t */\n\tarmv8_reg_current(arm, 0)->dirty = true;\n\n\t/* This algorithm comes from DDI0487A.g, chapter J9.1 */\n\n\t/* Read DSCR */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Set Normal access mode  */\n\tdscr = (dscr & ~DSCR_MA);\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\t/* Write X0 with value 'address' using write procedure */\n\t\t/* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */\n\t\t/* Step 1.c   - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */\n\t\tretval = dpm->instr_write_data_dcc_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address);\n\t} else {\n\t\t/* Write R0 with value 'address' using write procedure */\n\t\t/* Step 1.a+b - Write the address for read access into DBGDTRRX */\n\t\t/* Step 1.c   - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 0, 0, 5, 0), address);\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 4 && (address % 4) == 0)\n\t\tretval = aarch64_write_cpu_memory_fast(target, count, buffer, &dscr);\n\telse\n\t\tretval = aarch64_write_cpu_memory_slow(target, size, count, buffer, &dscr);\n\n\tif (retval != ERROR_OK) {\n\t\t/* Unset DTR mode */\n\t\tmem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\t\tdscr &= ~DSCR_MA;\n\t\tmem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, dscr);\n\t}\n\n\t/* Check for sticky abort flags in the DSCR */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdpm->dscr = dscr;\n\tif (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {\n\t\t/* Abort occurred - clear it and exit */\n\t\tLOG_ERROR(\"abort occurred - dscr = 0x%08\" PRIx32, dscr);\n\t\tarmv8_dpm_handle_exception(dpm, true);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Done */\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_read_cpu_memory_slow(struct target *target,\n\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t *dscr)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct arm *arm = &armv8->arm;\n\tint retval;\n\n\tarmv8_reg_current(arm, 1)->dirty = true;\n\n\t/* change DCC to normal mode (if necessary) */\n\tif (*dscr & DSCR_MA) {\n\t\t*dscr &= DSCR_MA;\n\t\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\twhile (count) {\n\t\tuint32_t opcode, data;\n\n\t\tif (size == 1)\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_LDRB_IP);\n\t\telse if (size == 2)\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_LDRH_IP);\n\t\telse\n\t\t\topcode = armv8_opcode(armv8, ARMV8_OPC_LDRW_IP);\n\t\tretval = dpm->instr_execute(dpm, opcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (arm->core_state == ARM_STATE_AARCH64)\n\t\t\tretval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 1));\n\t\telse\n\t\t\tretval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 1, 0, 5, 0));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX, &data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (size == 1)\n\t\t\t*buffer = (uint8_t)data;\n\t\telse if (size == 2)\n\t\t\ttarget_buffer_set_u16(target, buffer, (uint16_t)data);\n\t\telse\n\t\t\ttarget_buffer_set_u32(target, buffer, data);\n\n\t\t/* Advance */\n\t\tbuffer += size;\n\t\t--count;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_read_cpu_memory_fast(struct target *target,\n\tuint32_t count, uint8_t *buffer, uint32_t *dscr)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct arm *arm = &armv8->arm;\n\tint retval;\n\tuint32_t value;\n\n\t/* Mark X1 as dirty */\n\tarmv8_reg_current(arm, 1)->dirty = true;\n\n\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\t/* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */\n\t\tretval = dpm->instr_execute(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0));\n\t} else {\n\t\t/* Step 1.d - Dummy operation to ensure EDSCR.Txfull == 1 */\n\t\tretval = dpm->instr_execute(dpm, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Step 1.e - Change DCC to memory mode */\n\t*dscr |= DSCR_MA;\n\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Step 1.f - read DBGDTRTX and discard the value */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcount--;\n\t/* Read the data - Each read of the DTRTX register causes the instruction to be reissued\n\t * Abort flags are sticky, so can be read at end of transactions\n\t *\n\t * This data is read in aligned to 32 bit boundary.\n\t */\n\n\tif (count) {\n\t\t/* Step 2.a - Loop n-1 times, each read of DBGDTRTX reads the data from [X0] and\n\t\t * increments X0 by 4. */\n\t\tretval = mem_ap_read_buf_noincr(armv8->debug_ap, buffer, 4, count,\n\t\t\t\t\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Step 3.a - set DTR access mode back to Normal mode\t*/\n\t*dscr &= ~DSCR_MA;\n\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, *dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Step 3.b - read DBGDTRTX for the final value */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget_buffer_set_u32(target, buffer + count * 4, value);\n\treturn retval;\n}\n\nstatic int aarch64_read_cpu_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\t/* read memory through APB-AP */\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct arm *arm = &armv8->arm;\n\tuint32_t dscr;\n\n\tLOG_DEBUG(\"Reading CPU memory address 0x%016\" PRIx64 \" size %\" PRIu32 \" count %\" PRIu32,\n\t\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Mark register X0 as dirty, as it will be used\n\t * for transferring the data.\n\t * It will be restored automatically when exiting\n\t * debug mode\n\t */\n\tarmv8_reg_current(arm, 0)->dirty = true;\n\n\t/* Read DSCR */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* This algorithm comes from DDI0487A.g, chapter J9.1 */\n\n\t/* Set Normal access mode  */\n\tdscr &= ~DSCR_MA;\n\tretval =  mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\t/* Write X0 with value 'address' using write procedure */\n\t\t/* Step 1.a+b - Write the address for read access into DBGDTR_EL0 */\n\t\t/* Step 1.c   - Copy value from DTR to R0 using instruction mrs DBGDTR_EL0, x0 */\n\t\tretval = dpm->instr_write_data_dcc_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), address);\n\t} else {\n\t\t/* Write R0 with value 'address' using write procedure */\n\t\t/* Step 1.a+b - Write the address for read access into DBGDTRRXint */\n\t\t/* Step 1.c   - Copy value from DTR to R0 using instruction mrc DBGDTRTXint, r0 */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 0, 0, 5, 0), address);\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 4 && (address % 4) == 0)\n\t\tretval = aarch64_read_cpu_memory_fast(target, count, buffer, &dscr);\n\telse\n\t\tretval = aarch64_read_cpu_memory_slow(target, size, count, buffer, &dscr);\n\n\tif (dscr & DSCR_MA) {\n\t\tdscr &= ~DSCR_MA;\n\t\tmem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, dscr);\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check for sticky abort flags in the DSCR */\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdpm->dscr = dscr;\n\n\tif (dscr & (DSCR_ERR | DSCR_SYS_ERROR_PEND)) {\n\t\t/* Abort occurred - clear it and exit */\n\t\tLOG_ERROR(\"abort occurred - dscr = 0x%08\" PRIx32, dscr);\n\t\tarmv8_dpm_handle_exception(dpm, true);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Done */\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_read_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (count && buffer) {\n\t\t/* read memory through APB-AP */\n\t\tretval = aarch64_mmu_modify(target, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = aarch64_read_cpu_memory(target, address, size, count, buffer);\n\t}\n\treturn retval;\n}\n\nstatic int aarch64_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint mmu_enabled = 0;\n\tint retval;\n\n\t/* determine if MMU was enabled on target stop */\n\tretval = aarch64_mmu(target, &mmu_enabled);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu_enabled) {\n\t\t/* enable MMU as we could have disabled it for phys access */\n\t\tretval = aarch64_mmu_modify(target, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn aarch64_read_cpu_memory(target, address, size, count, buffer);\n}\n\nstatic int aarch64_write_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (count && buffer) {\n\t\t/* write memory through APB-AP */\n\t\tretval = aarch64_mmu_modify(target, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\treturn aarch64_write_cpu_memory(target, address, size, count, buffer);\n\t}\n\n\treturn retval;\n}\n\nstatic int aarch64_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint mmu_enabled = 0;\n\tint retval;\n\n\t/* determine if MMU was enabled on target stop */\n\tretval = aarch64_mmu(target, &mmu_enabled);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu_enabled) {\n\t\t/* enable MMU as we could have disabled it for phys access */\n\t\tretval = aarch64_mmu_modify(target, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn aarch64_write_cpu_memory(target, address, size, count, buffer);\n}\n\nstatic int aarch64_handle_target_request(void *priv)\n{\n\tstruct target *target = priv;\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tint retval;\n\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\tif (!target->dbg_msg_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->state == TARGET_RUNNING) {\n\t\tuint32_t request;\n\t\tuint32_t dscr;\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\n\t\t/* check if we have data */\n\t\twhile ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {\n\t\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX, &request);\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\ttarget_request(target, request);\n\t\t\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_examine_first(struct target *target)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct adiv5_dap *swjdp = armv8->arm.dap;\n\tstruct aarch64_private_config *pc = target->private_config;\n\tint i;\n\tint retval = ERROR_OK;\n\tuint64_t debug, ttypr;\n\tuint32_t cpuid;\n\tuint32_t tmp0, tmp1, tmp2, tmp3;\n\tdebug = ttypr = cpuid = 0;\n\n\tif (!pc)\n\t\treturn ERROR_FAIL;\n\n\tif (!armv8->debug_ap) {\n\t\tif (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {\n\t\t\t/* Search for the APB-AB */\n\t\t\tretval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not find APB-AP for debug access\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tarmv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);\n\t\t\tif (!armv8->debug_ap) {\n\t\t\t\tLOG_ERROR(\"Cannot get AP\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = mem_ap_init(armv8->debug_ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not initialize the APB-AP\");\n\t\treturn retval;\n\t}\n\n\tarmv8->debug_ap->memaccess_tck = 10;\n\n\tif (!target->dbgbase_set) {\n\t\t/* Lookup Processor DAP */\n\t\tretval = dap_lookup_cs_component(armv8->debug_ap, ARM_CS_C9_DEVTYPE_CORE_DEBUG,\n\t\t\t\t&armv8->debug_base, target->coreid);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"Detected core %\" PRId32 \" dbgbase: \" TARGET_ADDR_FMT,\n\t\t\t\ttarget->coreid, armv8->debug_base);\n\t} else\n\t\tarmv8->debug_base = target->dbgbase;\n\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_OSLAR, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"oslock\");\n\t\treturn retval;\n\t}\n\n\tretval = mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_MAINID0, &cpuid);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"CPUID\");\n\t\treturn retval;\n\t}\n\n\tretval = mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_MEMFEATURE0, &tmp0);\n\tretval += mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_MEMFEATURE0 + 4, &tmp1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"Memory Model Type\");\n\t\treturn retval;\n\t}\n\tretval = mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DBGFEATURE0, &tmp2);\n\tretval += mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DBGFEATURE0 + 4, &tmp3);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"ID_AA64DFR0_EL1\");\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(armv8->debug_ap->dap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: examination failed\\n\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tttypr |= tmp1;\n\tttypr = (ttypr << 32) | tmp0;\n\tdebug |= tmp3;\n\tdebug = (debug << 32) | tmp2;\n\n\tLOG_DEBUG(\"cpuid = 0x%08\" PRIx32, cpuid);\n\tLOG_DEBUG(\"ttypr = 0x%08\" PRIx64, ttypr);\n\tLOG_DEBUG(\"debug = 0x%08\" PRIx64, debug);\n\n\tif (!pc->cti) {\n\t\tLOG_TARGET_ERROR(target, \"CTI not specified\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarmv8->cti = pc->cti;\n\n\tretval = aarch64_dpm_setup(aarch64, debug);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Setup Breakpoint Register Pairs */\n\taarch64->brp_num = (uint32_t)((debug >> 12) & 0x0F) + 1;\n\taarch64->brp_num_context = (uint32_t)((debug >> 28) & 0x0F) + 1;\n\taarch64->brp_num_available = aarch64->brp_num;\n\taarch64->brp_list = calloc(aarch64->brp_num, sizeof(struct aarch64_brp));\n\tfor (i = 0; i < aarch64->brp_num; i++) {\n\t\taarch64->brp_list[i].used = 0;\n\t\tif (i < (aarch64->brp_num-aarch64->brp_num_context))\n\t\t\taarch64->brp_list[i].type = BRP_NORMAL;\n\t\telse\n\t\t\taarch64->brp_list[i].type = BRP_CONTEXT;\n\t\taarch64->brp_list[i].value = 0;\n\t\taarch64->brp_list[i].control = 0;\n\t\taarch64->brp_list[i].brpn = i;\n\t}\n\n\t/* Setup Watchpoint Register Pairs */\n\taarch64->wp_num = (uint32_t)((debug >> 20) & 0x0F) + 1;\n\taarch64->wp_num_available = aarch64->wp_num;\n\taarch64->wp_list = calloc(aarch64->wp_num, sizeof(struct aarch64_brp));\n\tfor (i = 0; i < aarch64->wp_num; i++) {\n\t\taarch64->wp_list[i].used = 0;\n\t\taarch64->wp_list[i].type = BRP_NORMAL;\n\t\taarch64->wp_list[i].value = 0;\n\t\taarch64->wp_list[i].control = 0;\n\t\taarch64->wp_list[i].brpn = i;\n\t}\n\n\tLOG_DEBUG(\"Configured %i hw breakpoints, %i watchpoints\",\n\t\taarch64->brp_num, aarch64->wp_num);\n\n\ttarget->state = TARGET_UNKNOWN;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\taarch64->isrmasking_mode = AARCH64_ISRMASK_ON;\n\ttarget_set_examined(target);\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_examine(struct target *target)\n{\n\tint retval = ERROR_OK;\n\n\t/* don't re-probe hardware after each reset */\n\tif (!target_was_examined(target))\n\t\tretval = aarch64_examine_first(target);\n\n\t/* Configure core debug access */\n\tif (retval == ERROR_OK)\n\t\tretval = aarch64_init_debug_access(target);\n\n\treturn retval;\n}\n\n/*\n *\tCortex-A8 target creation and initialization\n */\n\nstatic int aarch64_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\t/* examine_first() does a bunch of this */\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_init_arch_info(struct target *target,\n\tstruct aarch64_common *aarch64, struct adiv5_dap *dap)\n{\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\n\t/* Setup struct aarch64_common */\n\taarch64->common_magic = AARCH64_COMMON_MAGIC;\n\tarmv8->arm.dap = dap;\n\n\t/* register arch-specific functions */\n\tarmv8->examine_debug_reason = NULL;\n\tarmv8->post_debug_entry = aarch64_post_debug_entry;\n\tarmv8->pre_restore_context = NULL;\n\tarmv8->armv8_mmu.read_physical_memory = aarch64_read_phys_memory;\n\n\tarmv8_init_arch_info(target, armv8);\n\ttarget_register_timer_callback(aarch64_handle_target_request, 1,\n\t\tTARGET_TIMER_TYPE_PERIODIC, target);\n\n\treturn ERROR_OK;\n}\n\nstatic int armv8r_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct aarch64_private_config *pc = target->private_config;\n\tstruct aarch64_common *aarch64;\n\n\tif (adiv5_verify_config(&pc->adiv5_config) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\taarch64 = calloc(1, sizeof(struct aarch64_common));\n\tif (!aarch64) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\taarch64->armv8_common.is_armv8r = true;\n\n\treturn aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);\n}\n\nstatic int aarch64_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct aarch64_private_config *pc = target->private_config;\n\tstruct aarch64_common *aarch64;\n\n\tif (adiv5_verify_config(&pc->adiv5_config) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\taarch64 = calloc(1, sizeof(struct aarch64_common));\n\tif (!aarch64) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\taarch64->armv8_common.is_armv8r = false;\n\n\treturn aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);\n}\n\nstatic void aarch64_deinit_target(struct target *target)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\n\tif (armv8->debug_ap)\n\t\tdap_put_ap(armv8->debug_ap);\n\n\tarmv8_free_reg_cache(target);\n\tfree(aarch64->brp_list);\n\tfree(dpm->dbp);\n\tfree(dpm->dwp);\n\tfree(target->private_config);\n\tfree(aarch64);\n}\n\nstatic int aarch64_mmu(struct target *target, int *enabled)\n{\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\tstruct armv8_common *armv8 = &aarch64->armv8_common;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target %s not halted\", __func__, target_name(target));\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\tif (armv8->is_armv8r)\n\t\t*enabled = 0;\n\telse\n\t\t*enabled = target_to_aarch64(target)->armv8_common.armv8_mmu.mmu_enabled;\n\treturn ERROR_OK;\n}\n\nstatic int aarch64_virt2phys(struct target *target, target_addr_t virt,\n\t\t\t     target_addr_t *phys)\n{\n\treturn armv8_mmu_translate_va_pa(target, virt, phys, 1);\n}\n\n/*\n * private target configuration items\n */\nenum aarch64_cfg_param {\n\tCFG_CTI,\n};\n\nstatic const struct jim_nvp nvp_config_opts[] = {\n\t{ .name = \"-cti\", .value = CFG_CTI },\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic int aarch64_jim_configure(struct target *target, struct jim_getopt_info *goi)\n{\n\tstruct aarch64_private_config *pc;\n\tstruct jim_nvp *n;\n\tint e;\n\n\tpc = (struct aarch64_private_config *)target->private_config;\n\tif (!pc) {\n\t\t\tpc = calloc(1, sizeof(struct aarch64_private_config));\n\t\t\tpc->adiv5_config.ap_num = DP_APSEL_INVALID;\n\t\t\ttarget->private_config = pc;\n\t}\n\n\t/*\n\t * Call adiv5_jim_configure() to parse the common DAP options\n\t * It will return JIM_CONTINUE if it didn't find any known\n\t * options, JIM_OK if it correctly parsed the topmost option\n\t * and JIM_ERR if an error occurred during parameter evaluation.\n\t * For JIM_CONTINUE, we check our own params.\n\t *\n\t * adiv5_jim_configure() assumes 'private_config' to point to\n\t * 'struct adiv5_private_config'. Override 'private_config'!\n\t */\n\ttarget->private_config = &pc->adiv5_config;\n\te = adiv5_jim_configure(target, goi);\n\ttarget->private_config = pc;\n\tif (e != JIM_CONTINUE)\n\t\treturn e;\n\n\t/* parse config or cget options ... */\n\tif (goi->argc > 0) {\n\t\tJim_SetEmptyResult(goi->interp);\n\n\t\t/* check first if topmost item is for us */\n\t\te = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,\n\t\t\t\tgoi->argv[0], &n);\n\t\tif (e != JIM_OK)\n\t\t\treturn JIM_CONTINUE;\n\n\t\te = jim_getopt_obj(goi, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tswitch (n->value) {\n\t\tcase CFG_CTI: {\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tJim_Obj *o_cti;\n\t\t\t\tstruct arm_cti *cti;\n\t\t\t\te = jim_getopt_obj(goi, &o_cti);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tcti = cti_instance_by_jim_obj(goi->interp, o_cti);\n\t\t\t\tif (!cti) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"CTI name invalid!\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t\tpc->cti = cti;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp,\n\t\t\t\t\t\t\tgoi->argc, goi->argv,\n\t\t\t\t\t\t\t\"NO PARAMS\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\n\t\t\t\tif (!pc || !pc->cti) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"CTI not configured\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t\tJim_SetResultString(goi->interp, arm_cti_name(pc->cti), -1);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn JIM_CONTINUE;\n\t\t}\n\t}\n\n\treturn JIM_OK;\n}\n\nCOMMAND_HANDLER(aarch64_handle_cache_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\treturn armv8_handle_cache_info_command(CMD,\n\t\t\t&armv8->armv8_mmu.armv8_cache);\n}\n\nCOMMAND_HANDLER(aarch64_handle_dbginit_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn aarch64_init_debug_access(target);\n}\n\nCOMMAND_HANDLER(aarch64_handle_disassemble_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tif (aarch64->common_magic != AARCH64_COMMON_MAGIC) {\n\t\tcommand_print(CMD, \"current target isn't an AArch64\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint count = 1;\n\ttarget_addr_t address;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 2:\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);\n\t\t/* FALL THROUGH */\n\t\tcase 1:\n\t\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn a64_disassemble(CMD, target, address, count);\n}\n\nCOMMAND_HANDLER(aarch64_mask_interrupts_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct aarch64_common *aarch64 = target_to_aarch64(target);\n\n\tstatic const struct nvp nvp_maskisr_modes[] = {\n\t\t{ .name = \"off\", .value = AARCH64_ISRMASK_OFF },\n\t\t{ .name = \"on\", .value = AARCH64_ISRMASK_ON },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\tconst struct nvp *n;\n\n\tif (CMD_ARGC > 0) {\n\t\tn = nvp_name2value(nvp_maskisr_modes, CMD_ARGV[0]);\n\t\tif (!n->name) {\n\t\t\tLOG_ERROR(\"Unknown parameter: %s - should be off or on\", CMD_ARGV[0]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\taarch64->isrmasking_mode = n->value;\n\t}\n\n\tn = nvp_value2name(nvp_maskisr_modes, aarch64->isrmasking_mode);\n\tcommand_print(CMD, \"aarch64 interrupt mask %s\", n->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(aarch64_mcrmrc_command)\n{\n\tbool is_mcr = false;\n\tunsigned int arg_cnt = 5;\n\n\tif (!strcmp(CMD_NAME, \"mcr\")) {\n\t\tis_mcr = true;\n\t\targ_cnt = 6;\n\t}\n\n\tif (arg_cnt != CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"no current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target_was_examined(target)) {\n\t\tcommand_print(CMD, \"%s: not yet examined\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tstruct arm *arm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"%s: not an ARM\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\tcommand_print(CMD, \"%s: not 32-bit arm target\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint cpnum;\n\tuint32_t op1;\n\tuint32_t op2;\n\tuint32_t crn;\n\tuint32_t crm;\n\tuint32_t value;\n\n\t/* NOTE:  parameter sequence matches ARM instruction set usage:\n\t *\tMCR\tpNUM, op1, rX, CRn, CRm, op2\t; write CP from rX\n\t *\tMRC\tpNUM, op1, rX, CRn, CRm, op2\t; read CP into rX\n\t * The \"rX\" is necessarily omitted; it uses Tcl mechanisms.\n\t */\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);\n\tif (cpnum & ~0xf) {\n\t\tcommand_print(CMD, \"coprocessor %d out of range\", cpnum);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);\n\tif (op1 & ~0x7) {\n\t\tcommand_print(CMD, \"op1 %d out of range\", op1);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);\n\tif (crn & ~0xf) {\n\t\tcommand_print(CMD, \"CRn %d out of range\", crn);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);\n\tif (crm & ~0xf) {\n\t\tcommand_print(CMD, \"CRm %d out of range\", crm);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);\n\tif (op2 & ~0x7) {\n\t\tcommand_print(CMD, \"op2 %d out of range\", op2);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (is_mcr) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);\n\n\t\t/* NOTE: parameters reordered! */\n\t\t/* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */\n\t\tint retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tvalue = 0;\n\t\t/* NOTE: parameters reordered! */\n\t\t/* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */\n\t\tint retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration aarch64_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cache_info\",\n\t\t.handler = aarch64_handle_cache_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display information about target caches\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"dbginit\",\n\t\t.handler = aarch64_handle_dbginit_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Initialize core debug\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"disassemble\",\n\t\t.handler = aarch64_handle_disassemble_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Disassemble instructions\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = aarch64_mask_interrupts_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mask aarch64 interrupts during single-step\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.name = \"mcr\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = aarch64_mcrmrc_command,\n\t\t.help = \"write coprocessor register\",\n\t\t.usage = \"cpnum op1 CRn CRm op2 value\",\n\t},\n\t{\n\t\t.name = \"mrc\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = aarch64_mcrmrc_command,\n\t\t.help = \"read coprocessor register\",\n\t\t.usage = \"cpnum op1 CRn CRm op2\",\n\t},\n\t{\n\t\t.chain = smp_command_handlers,\n\t},\n\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration aarch64_command_handlers[] = {\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = semihosting_common_handlers\n\t},\n\t{\n\t\t.chain = armv8_command_handlers,\n\t},\n\t{\n\t\t.name = \"aarch64\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Aarch64 command group\",\n\t\t.usage = \"\",\n\t\t.chain = aarch64_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type aarch64_target = {\n\t.name = \"aarch64\",\n\n\t.poll = aarch64_poll,\n\t.arch_state = armv8_arch_state,\n\n\t.halt = aarch64_halt,\n\t.resume = aarch64_resume,\n\t.step = aarch64_step,\n\n\t.assert_reset = aarch64_assert_reset,\n\t.deassert_reset = aarch64_deassert_reset,\n\n\t/* REVISIT allow exporting VFP3 registers ... */\n\t.get_gdb_arch = armv8_get_gdb_arch,\n\t.get_gdb_reg_list = armv8_get_gdb_reg_list,\n\n\t.read_memory = aarch64_read_memory,\n\t.write_memory = aarch64_write_memory,\n\n\t.add_breakpoint = aarch64_add_breakpoint,\n\t.add_context_breakpoint = aarch64_add_context_breakpoint,\n\t.add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,\n\t.remove_breakpoint = aarch64_remove_breakpoint,\n\t.add_watchpoint = aarch64_add_watchpoint,\n\t.remove_watchpoint = aarch64_remove_watchpoint,\n\t.hit_watchpoint = aarch64_hit_watchpoint,\n\n\t.commands = aarch64_command_handlers,\n\t.target_create = aarch64_target_create,\n\t.target_jim_configure = aarch64_jim_configure,\n\t.init_target = aarch64_init_target,\n\t.deinit_target = aarch64_deinit_target,\n\t.examine = aarch64_examine,\n\n\t.read_phys_memory = aarch64_read_phys_memory,\n\t.write_phys_memory = aarch64_write_phys_memory,\n\t.mmu = aarch64_mmu,\n\t.virt2phys = aarch64_virt2phys,\n};\n\nstruct target_type armv8r_target = {\n\t.name = \"armv8r\",\n\n\t.poll = aarch64_poll,\n\t.arch_state = armv8_arch_state,\n\n\t.halt = aarch64_halt,\n\t.resume = aarch64_resume,\n\t.step = aarch64_step,\n\n\t.assert_reset = aarch64_assert_reset,\n\t.deassert_reset = aarch64_deassert_reset,\n\n\t/* REVISIT allow exporting VFP3 registers ... */\n\t.get_gdb_arch = armv8_get_gdb_arch,\n\t.get_gdb_reg_list = armv8_get_gdb_reg_list,\n\n\t.read_memory = aarch64_read_phys_memory,\n\t.write_memory = aarch64_write_phys_memory,\n\n\t.add_breakpoint = aarch64_add_breakpoint,\n\t.add_context_breakpoint = aarch64_add_context_breakpoint,\n\t.add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,\n\t.remove_breakpoint = aarch64_remove_breakpoint,\n\t.add_watchpoint = aarch64_add_watchpoint,\n\t.remove_watchpoint = aarch64_remove_watchpoint,\n\t.hit_watchpoint = aarch64_hit_watchpoint,\n\n\t.commands = aarch64_command_handlers,\n\t.target_create = armv8r_target_create,\n\t.target_jim_configure = aarch64_jim_configure,\n\t.init_target = aarch64_init_target,\n\t.deinit_target = aarch64_deinit_target,\n\t.examine = aarch64_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/aarch64.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by David Ung                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AARCH64_H\n#define OPENOCD_TARGET_AARCH64_H\n\n#include \"armv8.h\"\n\n#define AARCH64_COMMON_MAGIC 0x41413634U\n\n#define CPUDBG_CPUID\t0xD00\n#define CPUDBG_CTYPR\t0xD04\n#define CPUDBG_TTYPR\t0xD0C\n#define ID_AA64PFR0_EL1\t0xD20\n#define ID_AA64DFR0_EL1\t0xD28\n#define CPUDBG_LOCKACCESS 0xFB0\n#define CPUDBG_LOCKSTATUS 0xFB4\n\n#define BRP_NORMAL 0\n#define BRP_CONTEXT 1\n\n#define AARCH64_PADDRDBG_CPU_SHIFT 13\n\nenum aarch64_isrmasking_mode {\n\tAARCH64_ISRMASK_OFF,\n\tAARCH64_ISRMASK_ON,\n};\n\nstruct aarch64_brp {\n\tint used;\n\tint type;\n\ttarget_addr_t value;\n\tuint32_t control;\n\tuint8_t brpn;\n};\n\nstruct aarch64_common {\n\tunsigned int common_magic;\n\n\tstruct armv8_common armv8_common;\n\n\t/* Context information */\n\tuint32_t system_control_reg;\n\tuint32_t system_control_reg_curr;\n\n\t/* Breakpoint register pairs */\n\tint brp_num_context;\n\tint brp_num;\n\tint brp_num_available;\n\tstruct aarch64_brp *brp_list;\n\n\t/* Watchpoint register pairs */\n\tint wp_num;\n\tint wp_num_available;\n\tstruct aarch64_brp *wp_list;\n\n\tenum aarch64_isrmasking_mode isrmasking_mode;\n};\n\nstatic inline struct aarch64_common *\ntarget_to_aarch64(struct target *target)\n{\n\treturn container_of(target->arch_info, struct aarch64_common, armv8_common.arm);\n}\n\n#endif /* OPENOCD_TARGET_AARCH64_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/adi_v5_dapdirect.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2019, STMicroelectronics - All Rights Reserved\n * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics\n */\n\n/**\n * @file\n * Utilities to support in-circuit debuggers that provide APIs to access\n * directly ARM DAP, hiding the access to the underlining transport used\n * for the physical connection (either JTAG or SWD).\n * E.g. STMicroelectronics ST-Link/V2 (from version V2J24) and STLINK-V3.\n *\n * Single-DAP support only.\n *\n * For details, see \"ARM IHI 0031A\"\n * ARM Debug Interface v5 Architecture Specification\n *\n * FIXME: in JTAG mode, trst is not managed\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/interface.h>\n#include <jtag/tcl.h>\n#include <transport/transport.h>\n\nCOMMAND_HANDLER(dapdirect_jtag_empty_command)\n{\n\tLOG_DEBUG(\"dapdirect_jtag_empty_command(\\\"%s\\\")\", CMD_NAME);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(dapdirect_jtag_reset_command)\n{\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t/*\n\t * in case the adapter has not already handled asserting srst\n\t * we will attempt it again\n\t */\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING) {\n\t\t\tadapter_assert_reset();\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t}\n\tadapter_deassert_reset();\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration dapdirect_jtag_subcommand_handlers[] = {\n\t{\n\t\t.name = \"newtap\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_jtag_newtap,\n\t\t.help = \"declare a new TAP\",\n\t\t.usage = \"basename tap_type '-irlen' count \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"arp_init\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"arp_init-reset\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_reset_command,\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"tapisenabled\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_tap_enabler,\n\t\t.help = \"Returns a Tcl boolean (0/1) indicating whether \"\n\t\t\t\"the TAP is enabled (1) or not (0).\",\n\t\t.usage = \"tap_name\",\n\t},\n\t{\n\t\t.name = \"tapenable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_jtag_tap_enabler,\n\t\t.help = \"Try to enable the specified TAP using the \"\n\t\t\t\"'tap-enable' TAP event.\",\n\t\t.usage = \"tap_name\",\n\t},\n\t{\n\t\t.name = \"tapdisable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"configure\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"cget\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = jim_jtag_configure,\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration dapdirect_jtag_handlers[] = {\n\t{\n\t\t.name = \"jtag\",\n\t\t.mode = COMMAND_ANY,\n\t\t.chain = dapdirect_jtag_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"jtag_ntrst_delay\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = dapdirect_jtag_empty_command,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration dapdirect_swd_subcommand_handlers[] = {\n\t{\n\t\t.name = \"newdap\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_jtag_newtap,\n\t\t.help = \"declare a new SWD DAP\",\n\t\t.usage = \"basename dap_type ['-irlen' count] \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration dapdirect_swd_handlers[] = {\n\t{\n\t\t.name = \"swd\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"SWD command group\",\n\t\t.usage = \"\",\n\t\t.chain = dapdirect_swd_subcommand_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int dapdirect_jtag_select(struct command_context *ctx)\n{\n\tLOG_DEBUG(\"dapdirect_jtag_select()\");\n\n\treturn register_commands(ctx, NULL, dapdirect_jtag_handlers);\n}\n\nstatic int dapdirect_swd_select(struct command_context *ctx)\n{\n\tLOG_DEBUG(\"dapdirect_swd_select()\");\n\n\treturn register_commands(ctx, NULL, dapdirect_swd_handlers);\n}\n\nstatic int dapdirect_init(struct command_context *ctx)\n{\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tLOG_DEBUG(\"dapdirect_init()\");\n\n\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\tadapter_assert_reset();\n\t\telse\n\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t} else\n\t\tadapter_deassert_reset();\n\n\treturn ERROR_OK;\n}\n\nstatic struct transport dapdirect_jtag_transport = {\n\t.name = \"dapdirect_jtag\",\n\t.select = dapdirect_jtag_select,\n\t.init = dapdirect_init,\n};\n\nstatic struct transport dapdirect_swd_transport = {\n\t.name = \"dapdirect_swd\",\n\t.select = dapdirect_swd_select,\n\t.init = dapdirect_init,\n};\n\nstatic void dapdirect_constructor(void) __attribute__((constructor));\nstatic void dapdirect_constructor(void)\n{\n\ttransport_register(&dapdirect_jtag_transport);\n\ttransport_register(&dapdirect_swd_transport);\n}\n\n/**\n * Returns true if the current debug session\n * is using JTAG as its transport.\n */\nbool transport_is_dapdirect_jtag(void)\n{\n\treturn get_current_transport() == &dapdirect_jtag_transport;\n}\n\n/**\n * Returns true if the current debug session\n * is using SWD as its transport.\n */\nbool transport_is_dapdirect_swd(void)\n{\n\treturn get_current_transport() == &dapdirect_swd_transport;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/adi_v5_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin\n *   lundin@mlu.mine.nu\n *\n *   Copyright (C) 2008 by Spencer Oliver\n *   spen@spen-soft.co.uk\n *\n *   Copyright (C) 2009 by Oyvind Harboe\n *   oyvind.harboe@zylin.com\n *\n *   Copyright (C) 2009-2010 by David Brownell\n *\n *   Copyright (C) 2020-2021, Ampere Computing LLC                              *\n ***************************************************************************/\n\n/**\n * @file\n * This file implements JTAG transport support for cores implementing\n the ARM Debug Interface version 5 (ADIv5) and version 6 (ADIv6).\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"arm_adi_v5.h\"\n#include <helper/time_support.h>\n#include <helper/list.h>\n#include <jtag/swd.h>\n\n/*#define DEBUG_WAIT*/\n\n/* JTAG instructions/registers for JTAG-DP and SWJ-DP */\n#define JTAG_DP_ABORT\t\t0xF8\n#define JTAG_DP_DPACC\t\t0xFA\n#define JTAG_DP_APACC\t\t0xFB\n#define JTAG_DP_IDCODE\t\t0xFE\n\n/* three-bit ACK values for DPACC and APACC reads */\n#define JTAG_ACK_WAIT       0x1     /* ADIv5 and ADIv6 */\n#define JTAG_ACK_OK_FAULT   0x2     /* ADIv5 */\n#define JTAG_ACK_FAULT      0x2     /* ADIv6 */\n#define JTAG_ACK_OK         0x4     /* ADIV6 */\n\nstatic int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack);\n\n#ifdef DEBUG_WAIT\nstatic const char *dap_reg_name(struct adiv5_dap *dap, uint8_t instr, uint16_t reg_addr)\n{\n\tchar *reg_name = \"UNK\";\n\n\tif (instr == JTAG_DP_DPACC) {\n\t\tswitch (reg_addr) {\n\t\tcase DP_ABORT:\n\t\t\treg_name =  \"ABORT\";\n\t\t\tbreak;\n\t\tcase DP_CTRL_STAT:\n\t\t\treg_name =  \"CTRL/STAT\";\n\t\t\tbreak;\n\t\tcase DP_SELECT:\n\t\t\treg_name = \"SELECT\";\n\t\t\tbreak;\n\t\tcase DP_RDBUFF:\n\t\t\treg_name =  \"RDBUFF\";\n\t\t\tbreak;\n\t\tcase DP_DLCR:\n\t\t\treg_name =  \"DLCR\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treg_name = \"UNK\";\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (instr == JTAG_DP_APACC) {\n\t\tif (reg_addr == MEM_AP_REG_CSW(dap))\n\t\t\treg_name = \"CSW\";\n\t\telse if (reg_addr == MEM_AP_REG_TAR(dap))\n\t\t\treg_name = \"TAR\";\n\t\telse if (reg_addr == MEM_AP_REG_TAR64(dap))\n\t\t\treg_name = \"TAR64\";\n\t\telse if (reg_addr == MEM_AP_REG_DRW(dap))\n\t\t\treg_name = \"DRW\";\n\t\telse if (reg_addr == MEM_AP_REG_BD0(dap))\n\t\t\treg_name = \"BD0\";\n\t\telse if (reg_addr == MEM_AP_REG_BD1(dap))\n\t\t\treg_name = \"BD1\";\n\t\telse if (reg_addr == MEM_AP_REG_BD2(dap))\n\t\t\treg_name = \"BD2\";\n\t\telse if (reg_addr == MEM_AP_REG_BD3(dap))\n\t\t\treg_name = \"BD3\";\n\t\telse if (reg_addr == MEM_AP_REG_CFG(dap))\n\t\t\treg_name = \"CFG\";\n\t\telse if (reg_addr == MEM_AP_REG_BASE(dap))\n\t\t\treg_name = \"BASE\";\n\t\telse if (reg_addr == MEM_AP_REG_BASE64(dap))\n\t\t\treg_name = \"BASE64\";\n\t\telse if (reg_addr == AP_REG_IDR(dap))\n\t\t\treg_name = \"IDR\";\n\t\telse\n\t\t\treg_name = \"UNK\";\n\t}\n\n\treturn reg_name;\n}\n#endif\n\nstruct dap_cmd {\n\tstruct list_head lh;\n\tuint8_t instr;\n\tuint16_t reg_addr;\n\tuint8_t rnw;\n\tuint8_t *invalue;\n\tuint8_t ack;\n\tuint32_t memaccess_tck;\n\tuint64_t dp_select;\n\n\tstruct scan_field fields[2];\n\tuint8_t out_addr_buf;\n\tuint8_t invalue_buf[4];\n\tuint8_t outvalue_buf[4];\n};\n\n#define MAX_DAP_COMMAND_NUM 65536\n\nstruct dap_cmd_pool {\n\tstruct list_head lh;\n\tstruct dap_cmd cmd;\n};\n\nstatic void log_dap_cmd(struct adiv5_dap *dap, const char *header, struct dap_cmd *el)\n{\n#ifdef DEBUG_WAIT\n\tconst char *ack;\n\tswitch (el->ack) {\n\tcase JTAG_ACK_WAIT:         /* ADIv5 and ADIv6 */\n\t\tack = \"WAIT\";\n\t\tbreak;\n\tcase JTAG_ACK_OK_FAULT:     /* ADIv5, same value as JTAG_ACK_FAULT */\n\t/* case JTAG_ACK_FAULT: */  /* ADIv6 */\n\t\tif (is_adiv6(dap))\n\t\t\tack = \"FAULT\";\n\t\telse\n\t\t\tack = \"OK\";\n\t\tbreak;\n\tcase JTAG_ACK_OK:           /* ADIv6 */\n\t\tif (is_adiv6(dap)) {\n\t\t\tack = \"OK\";\n\t\t\tbreak;\n\t\t}\n\t\t/* fall-through */\n\tdefault:\n\t\tack = \"INVAL\";\n\t\tbreak;\n\t}\n\tLOG_DEBUG(\"%s: %2s %6s %5s 0x%08x 0x%08x %2s\", header,\n\t\tel->instr == JTAG_DP_APACC ? \"AP\" : \"DP\",\n\t\tdap_reg_name(dap, el->instr, el->reg_addr),\n\t\tel->rnw == DPAP_READ ? \"READ\" : \"WRITE\",\n\t\tbuf_get_u32(el->outvalue_buf, 0, 32),\n\t\tbuf_get_u32(el->invalue, 0, 32),\n\t\tack);\n#endif\n}\n\nstatic int jtag_limit_queue_size(struct adiv5_dap *dap)\n{\n\tif (dap->cmd_pool_size < MAX_DAP_COMMAND_NUM)\n\t\treturn ERROR_OK;\n\n\treturn dap_run(dap);\n}\n\nstatic struct dap_cmd *dap_cmd_new(struct adiv5_dap *dap, uint8_t instr,\n\t\tuint16_t reg_addr, uint8_t rnw,\n\t\tuint8_t *outvalue, uint8_t *invalue,\n\t\tuint32_t memaccess_tck)\n{\n\n\tstruct dap_cmd_pool *pool = NULL;\n\n\tif (list_empty(&dap->cmd_pool)) {\n\t\tpool = calloc(1, sizeof(struct dap_cmd_pool));\n\t\tif (!pool)\n\t\t\treturn NULL;\n\t} else {\n\t\tpool = list_first_entry(&dap->cmd_pool, struct dap_cmd_pool, lh);\n\t\tlist_del(&pool->lh);\n\t}\n\n\tINIT_LIST_HEAD(&pool->lh);\n\tdap->cmd_pool_size++;\n\n\tstruct dap_cmd *cmd = &pool->cmd;\n\tINIT_LIST_HEAD(&cmd->lh);\n\tcmd->instr = instr;\n\tcmd->reg_addr = reg_addr;\n\tcmd->rnw = rnw;\n\tif (outvalue)\n\t\tmemcpy(cmd->outvalue_buf, outvalue, 4);\n\tcmd->invalue = (invalue) ? invalue : cmd->invalue_buf;\n\tcmd->memaccess_tck = memaccess_tck;\n\n\treturn cmd;\n}\n\nstatic void dap_cmd_release(struct adiv5_dap *dap, struct dap_cmd *cmd)\n{\n\tstruct dap_cmd_pool *pool = container_of(cmd, struct dap_cmd_pool, cmd);\n\tif (dap->cmd_pool_size > MAX_DAP_COMMAND_NUM)\n\t\tfree(pool);\n\telse\n\t\tlist_add(&pool->lh, &dap->cmd_pool);\n\n\tdap->cmd_pool_size--;\n}\n\nstatic void flush_journal(struct adiv5_dap *dap, struct list_head *lh)\n{\n\tstruct dap_cmd *el, *tmp;\n\n\tlist_for_each_entry_safe(el, tmp, lh, lh) {\n\t\tlist_del(&el->lh);\n\t\tdap_cmd_release(dap, el);\n\t}\n}\n\nstatic void jtag_quit(struct adiv5_dap *dap)\n{\n\tstruct dap_cmd_pool *el, *tmp;\n\tstruct list_head *lh = &dap->cmd_pool;\n\n\tlist_for_each_entry_safe(el, tmp, lh, lh) {\n\t\tlist_del(&el->lh);\n\t\tfree(el);\n\t}\n}\n\n/***************************************************************************\n *\n * DPACC and APACC scanchain access through JTAG-DP (or SWJ-DP)\n *\n***************************************************************************/\n\nstatic int adi_jtag_dp_scan_cmd(struct adiv5_dap *dap, struct dap_cmd *cmd, uint8_t *ack)\n{\n\tstruct jtag_tap *tap = dap->tap;\n\tint retval;\n\n\tretval = arm_jtag_set_instr(tap, cmd->instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Scan out a read or write operation using some DP or AP register.\n\t * For APACC access with any sticky error flag set, this is discarded.\n\t */\n\tcmd->fields[0].num_bits = 3;\n\tbuf_set_u32(&cmd->out_addr_buf, 0, 3, ((cmd->reg_addr >> 1) & 0x6) | (cmd->rnw & 0x1));\n\tcmd->fields[0].out_value = &cmd->out_addr_buf;\n\tcmd->fields[0].in_value = (ack) ? ack : &cmd->ack;\n\n\t/* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not\n\t * complete; data we write is discarded, data we read is unpredictable.\n\t * When overrun detect is active, STICKYORUN is set.\n\t */\n\n\tcmd->fields[1].num_bits = 32;\n\tcmd->fields[1].out_value = cmd->outvalue_buf;\n\tcmd->fields[1].in_value = cmd->invalue;\n\n\tjtag_add_dr_scan(tap, 2, cmd->fields, TAP_IDLE);\n\n\t/* Add specified number of tck clocks after starting AP register\n\t * access or memory bus access, giving the hardware time to complete\n\t * the access.\n\t * They provide more time for the (MEM) AP to complete the read ...\n\t * See \"Minimum Response Time\" for JTAG-DP, in the ADIv5/ADIv6 spec.\n\t */\n\tif (cmd->instr == JTAG_DP_APACC && cmd->memaccess_tck != 0)\n\t\tjtag_add_runtest(cmd->memaccess_tck, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nstatic int adi_jtag_dp_scan_cmd_sync(struct adiv5_dap *dap, struct dap_cmd *cmd, uint8_t *ack)\n{\n\tint retval;\n\n\tretval = adi_jtag_dp_scan_cmd(dap, cmd, ack);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Scan DPACC or APACC using target ordered uint8_t buffers.  No endianness\n * conversions are performed.  See section 4.4.3 of the ADIv5/ADIv6 spec, which\n * discusses operations which access these registers.\n *\n * Note that only one scan is performed.  If rnw is set, a separate scan\n * will be needed to collect the data which was read; the \"invalue\" collects\n * the posted result of a preceding operation, not the current one.\n *\n * @param dap the DAP\n * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access)\n * @param reg_addr two significant bits; A[3:2]; for APACC access, the\n *\tSELECT register has more addressing bits.\n * @param rnw false iff outvalue will be written to the DP or AP\n * @param outvalue points to a 32-bit (little-endian) integer\n * @param invalue NULL, or points to a 32-bit (little-endian) integer\n * @param ack points to where the three bit JTAG_ACK_* code will be stored\n * @param memaccess_tck number of idle cycles to add after AP access\n */\n\nstatic int adi_jtag_dp_scan(struct adiv5_dap *dap,\n\t\tuint8_t instr, uint16_t reg_addr, uint8_t rnw,\n\t\tuint8_t *outvalue, uint8_t *invalue,\n\t\tuint32_t memaccess_tck, uint8_t *ack)\n{\n\tstruct dap_cmd *cmd;\n\tint retval;\n\n\tcmd = dap_cmd_new(dap, instr, reg_addr, rnw, outvalue, invalue, memaccess_tck);\n\tif (cmd)\n\t\tcmd->dp_select = dap->select;\n\telse\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\n\tretval = adi_jtag_dp_scan_cmd(dap, cmd, ack);\n\tif (retval == ERROR_OK)\n\t\tlist_add_tail(&cmd->lh,\t&dap->cmd_journal);\n\n\treturn retval;\n}\n\n/**\n * Scan DPACC or APACC out and in from host ordered uint32_t buffers.\n * This is exactly like adi_jtag_dp_scan(), except that endianness\n * conversions are performed (so the types of invalue and outvalue\n * must be different).\n */\nstatic int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,\n\t\tuint8_t instr, uint16_t reg_addr, uint8_t rnw,\n\t\tuint32_t outvalue, uint32_t *invalue,\n\t\tuint32_t memaccess_tck, uint8_t *ack)\n{\n\tuint8_t out_value_buf[4];\n\tint retval;\n\tuint64_t sel = (reg_addr >> 4) & 0xf;\n\n\t/* No need to change SELECT or RDBUFF as they are not banked */\n\tif (instr == JTAG_DP_DPACC && reg_addr != DP_SELECT && reg_addr != DP_RDBUFF &&\n\t\t\tsel != (dap->select & 0xf)) {\n\t\tif (dap->select != DP_SELECT_INVALID)\n\t\t\tsel |= dap->select & ~0xfull;\n\t\tdap->select = sel;\n\t\tLOG_DEBUG(\"DP BANKSEL: %x\", (uint32_t)sel);\n\t\tbuf_set_u32(out_value_buf, 0, 32, (uint32_t)sel);\n\t\tretval = adi_jtag_dp_scan(dap, JTAG_DP_DPACC,\n\t\t\t\tDP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0, NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tbuf_set_u32(out_value_buf, 0, 32, outvalue);\n\n\tretval = adi_jtag_dp_scan(dap, instr, reg_addr, rnw,\n\t\t\tout_value_buf, (uint8_t *)invalue, memaccess_tck, ack);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (invalue)\n\t\tjtag_add_callback(arm_le_to_h_u32,\n\t\t\t\t(jtag_callback_data_t) invalue);\n\n\treturn retval;\n}\n\nstatic int adi_jtag_finish_read(struct adiv5_dap *dap)\n{\n\tint retval = ERROR_OK;\n\n\tif (dap->last_read) {\n\t\tretval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,\n\t\t\t\tDP_RDBUFF, DPAP_READ, 0, dap->last_read, 0, NULL);\n\t\tdap->last_read = NULL;\n\t}\n\n\treturn retval;\n}\n\nstatic int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,\n\t\tuint8_t instr, uint16_t reg_addr, uint8_t rnw,\n\t\tuint32_t outvalue, uint32_t *invalue, uint32_t memaccess_tck)\n{\n\tint retval;\n\n\t/* Issue the read or write */\n\tretval = adi_jtag_dp_scan_u32(dap, instr, reg_addr,\n\t\t\trnw, outvalue, NULL, memaccess_tck, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* For reads,  collect posted value; RDBUFF has no other effect.\n\t * Assumes read gets acked with OK/FAULT, and CTRL_STAT says \"OK\".\n\t */\n\tif ((rnw == DPAP_READ) && (invalue)) {\n\t\tretval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,\n\t\t\t\tDP_RDBUFF, DPAP_READ, 0, invalue, 0, NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn jtag_execute_queue();\n}\n\nstatic int jtagdp_overrun_check(struct adiv5_dap *dap)\n{\n\tint retval;\n\tstruct dap_cmd *el, *tmp, *prev = NULL;\n\tint found_wait = 0;\n\tint64_t time_now;\n\tLIST_HEAD(replay_list);\n\n\t/* make sure all queued transactions are complete */\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* skip all completed transactions up to the first WAIT */\n\tlist_for_each_entry(el, &dap->cmd_journal, lh) {\n\t\t/*\n\t\t * JTAG_ACK_OK_FAULT (ADIv5) and JTAG_ACK_FAULT (ADIv6) are equal so\n\t\t * the following statement is checking to see if an acknowledgment of\n\t\t * OK or FAULT is generated for ADIv5 or ADIv6\n\t\t */\n\t\tif (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) {\n\t\t\tlog_dap_cmd(dap, \"LOG\", el);\n\t\t} else if (el->ack == JTAG_ACK_WAIT) {\n\t\t\tfound_wait = 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tLOG_ERROR(\"Invalid ACK (%1x) in DAP response\", el->ack);\n\t\t\tlog_dap_cmd(dap, \"ERR\", el);\n\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\tgoto done;\n\t\t}\n\t}\n\n\t/*\n\t * If we found a stalled transaction and a previous transaction\n\t * exists, check if it's a READ access.\n\t */\n\tif (found_wait && el != list_first_entry(&dap->cmd_journal, struct dap_cmd, lh)) {\n\t\tprev = list_entry(el->lh.prev, struct dap_cmd, lh);\n\t\tif (prev->rnw == DPAP_READ) {\n\t\t\tlog_dap_cmd(dap, \"PND\", prev);\n\t\t\t/* search for the next OK transaction, it contains\n\t\t\t * the result of the previous READ */\n\t\t\ttmp = el;\n\t\t\tlist_for_each_entry_from(tmp, &dap->cmd_journal, lh) {\n\t\t\t\t/* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */\n\t\t\t\tif (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) {\n\t\t\t\t\t/* recover the read value */\n\t\t\t\t\tlog_dap_cmd(dap, \"FND\", tmp);\n\t\t\t\t\tif (el->invalue != el->invalue_buf) {\n\t\t\t\t\t\tuint32_t invalue = le_to_h_u32(tmp->invalue);\n\t\t\t\t\t\tmemcpy(el->invalue, &invalue, sizeof(uint32_t));\n\t\t\t\t\t}\n\t\t\t\t\tprev = NULL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (prev) {\n\t\t\t\tlog_dap_cmd(dap, \"LST\", el);\n\n\t\t\t\t/*\n\t\t\t\t* At this point we're sure that no previous\n\t\t\t\t* transaction completed and the DAP/AP is still\n\t\t\t\t* in busy state. We know that the next \"OK\" scan\n\t\t\t\t* will return the READ result we need to recover.\n\t\t\t\t* To complete the READ, we just keep polling RDBUFF\n\t\t\t\t* until the WAIT condition clears\n\t\t\t\t*/\n\t\t\t\ttmp = dap_cmd_new(dap, JTAG_DP_DPACC,\n\t\t\t\t\t\tDP_RDBUFF, DPAP_READ, NULL, NULL, 0);\n\t\t\t\tif (!tmp) {\n\t\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\tgoto done;\n\t\t\t\t}\n\t\t\t\t/* synchronously retry the command until it succeeds */\n\t\t\t\ttime_now = timeval_ms();\n\t\t\t\tdo {\n\t\t\t\t\tretval = adi_jtag_dp_scan_cmd_sync(dap, tmp, NULL);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t/* The following check covers OK and FAULT ACKs for both ADIv5 and ADIv6 */\n\t\t\t\t\tif (tmp->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && tmp->ack == JTAG_ACK_OK)) {\n\t\t\t\t\t\tlog_dap_cmd(dap, \"FND\", tmp);\n\t\t\t\t\t\tif (el->invalue != el->invalue_buf) {\n\t\t\t\t\t\t\tuint32_t invalue = le_to_h_u32(tmp->invalue);\n\t\t\t\t\t\t\tmemcpy(el->invalue, &invalue, sizeof(uint32_t));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (tmp->ack != JTAG_ACK_WAIT) {\n\t\t\t\t\t\tLOG_ERROR(\"Invalid ACK (%1x) in DAP response\", tmp->ack);\n\t\t\t\t\t\tlog_dap_cmd(dap, \"ERR\", tmp);\n\t\t\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t} while (timeval_ms() - time_now < 1000);\n\n\t\t\t\tif (retval == ERROR_OK) {\n\t\t\t\t\t/* timeout happened */\n\t\t\t\t\tif (tmp->ack == JTAG_ACK_WAIT) {\n\t\t\t\t\t\tLOG_ERROR(\"Timeout during WAIT recovery\");\n\t\t\t\t\t\tdap->select = DP_SELECT_INVALID;\n\t\t\t\t\t\tjtag_ap_q_abort(dap, NULL);\n\t\t\t\t\t\t/* clear the sticky overrun condition */\n\t\t\t\t\t\tadi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\t\t\t\t\tDP_CTRL_STAT, DPAP_WRITE,\n\t\t\t\t\t\t\tdap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);\n\t\t\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* we're done with this command, release it */\n\t\t\t\tdap_cmd_release(dap, tmp);\n\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto done;\n\n\t\t\t}\n\t\t\t/* make el->invalue point to the default invalue\n\t\t\t* so that we can safely retry it without clobbering\n\t\t\t* the result we just recovered */\n\t\t\tel->invalue = el->invalue_buf;\n\t\t}\n\t}\n\n\t/* move all remaining transactions over to the replay list */\n\tlist_for_each_entry_safe_from(el, tmp, &dap->cmd_journal, lh) {\n\t\tlog_dap_cmd(dap, \"REP\", el);\n\t\tlist_move_tail(&el->lh, &replay_list);\n\t}\n\n\t/* we're done with the journal, flush it */\n\tflush_journal(dap, &dap->cmd_journal);\n\n\t/* check for overrun condition in the last batch of transactions */\n\tif (found_wait) {\n\t\tLOG_INFO(\"DAP transaction stalled (WAIT) - slowing down and resending\");\n\t\t/* clear the sticky overrun condition */\n\t\tretval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\t\tDP_CTRL_STAT, DPAP_WRITE,\n\t\t\t\tdap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\t/* restore SELECT register first */\n\t\tif (!list_empty(&replay_list)) {\n\t\t\tel = list_first_entry(&replay_list, struct dap_cmd, lh);\n\n\t\t\tuint8_t out_value_buf[4];\n\t\t\tbuf_set_u32(out_value_buf, 0, 32, (uint32_t)(el->dp_select));\n\n\t\t\ttmp = dap_cmd_new(dap, JTAG_DP_DPACC,\n\t\t\t\t\t  DP_SELECT, DPAP_WRITE, out_value_buf, NULL, 0);\n\t\t\tif (!tmp) {\n\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tlist_add(&tmp->lh, &replay_list);\n\n\t\t\t/* TODO: ADIv6 DP SELECT1 handling */\n\n\t\t\tdap->select = DP_SELECT_INVALID;\n\t\t}\n\n\t\tlist_for_each_entry_safe(el, tmp, &replay_list, lh) {\n\t\t\ttime_now = timeval_ms();\n\t\t\tdo {\n\t\t\t\tretval = adi_jtag_dp_scan_cmd_sync(dap, el, NULL);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t\tlog_dap_cmd(dap, \"REC\", el);\n\t\t\t\tif (el->ack == JTAG_ACK_OK_FAULT || (is_adiv6(dap) && el->ack == JTAG_ACK_OK)) {\n\t\t\t\t\tif (el->invalue != el->invalue_buf) {\n\t\t\t\t\t\tuint32_t invalue = le_to_h_u32(el->invalue);\n\t\t\t\t\t\tmemcpy(el->invalue, &invalue, sizeof(uint32_t));\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (el->ack != JTAG_ACK_WAIT) {\n\t\t\t\t\tLOG_ERROR(\"Invalid ACK (%1x) in DAP response\", el->ack);\n\t\t\t\t\tlog_dap_cmd(dap, \"ERR\", el);\n\t\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tLOG_DEBUG(\"DAP transaction stalled during replay (WAIT) - resending\");\n\t\t\t\t/* clear the sticky overrun condition */\n\t\t\t\tretval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\t\t\t\tDP_CTRL_STAT, DPAP_WRITE,\n\t\t\t\t\t\tdap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t} while (timeval_ms() - time_now < 1000);\n\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tif (el->ack == JTAG_ACK_WAIT) {\n\t\t\t\t\tLOG_ERROR(\"Timeout during WAIT recovery\");\n\t\t\t\t\tdap->select = DP_SELECT_INVALID;\n\t\t\t\t\tjtag_ap_q_abort(dap, NULL);\n\t\t\t\t\t/* clear the sticky overrun condition */\n\t\t\t\t\tadi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\t\t\t\tDP_CTRL_STAT, DPAP_WRITE,\n\t\t\t\t\t\tdap->dp_ctrl_stat | SSTICKYORUN, NULL, 0);\n\t\t\t\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n done:\n\tflush_journal(dap, &replay_list);\n\tflush_journal(dap, &dap->cmd_journal);\n\treturn retval;\n}\n\nstatic int jtagdp_transaction_endcheck(struct adiv5_dap *dap)\n{\n\tint retval;\n\tuint32_t ctrlstat, pwrmask;\n\n\t/* too expensive to call keep_alive() here */\n\n\t/* Post CTRL/STAT read; discard any previous posted read value\n\t * but collect its ACK status.\n\t */\n\tretval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\tDP_CTRL_STAT, DPAP_READ, 0, &ctrlstat, 0);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */\n\n\t/* Check for STICKYERR */\n\tif (ctrlstat & SSTICKYERR) {\n\t\tLOG_DEBUG(\"jtag-dp: CTRL/STAT 0x%\" PRIx32, ctrlstat);\n\t\t/* Check power to debug regions */\n\t\tpwrmask = CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ;\n\t\tif (!dap->ignore_syspwrupack)\n\t\t\tpwrmask |= CSYSPWRUPACK;\n\t\tif ((ctrlstat & pwrmask) != pwrmask) {\n\t\t\tLOG_ERROR(\"Debug regions are unpowered, an unexpected reset might have happened\");\n\t\t\tdap->do_reconnect = true;\n\t\t}\n\n\t\tif (ctrlstat & SSTICKYERR)\n\t\t\tLOG_ERROR(\"JTAG-DP STICKY ERROR\");\n\t\tif (ctrlstat & SSTICKYORUN)\n\t\t\tLOG_DEBUG(\"JTAG-DP STICKY OVERRUN\");\n\n\t\t/* Clear Sticky Error and Sticky Overrun Bits */\n\t\tretval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,\n\t\t\t\tDP_CTRL_STAT, DPAP_WRITE,\n\t\t\t\tdap->dp_ctrl_stat | SSTICKYERR | SSTICKYORUN, NULL, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tretval = ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n done:\n\tflush_journal(dap, &dap->cmd_journal);\n\treturn retval;\n}\n\n/*--------------------------------------------------------------------------*/\n\nstatic int jtag_connect(struct adiv5_dap *dap)\n{\n\tdap->do_reconnect = false;\n\treturn dap_dp_init(dap);\n}\n\nstatic int jtag_check_reconnect(struct adiv5_dap *dap)\n{\n\tif (dap->do_reconnect)\n\t\treturn jtag_connect(dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)\n{\n\tint retval;\n\n\tswitch (seq) {\n\tcase JTAG_TO_SWD:\n\t\tretval =  jtag_add_tms_seq(swd_seq_jtag_to_swd_len,\n\t\t\t\tswd_seq_jtag_to_swd, TAP_INVALID);\n\t\tbreak;\n\tcase SWD_TO_JTAG:\n\t\tretval = jtag_add_tms_seq(swd_seq_swd_to_jtag_len,\n\t\t\t\tswd_seq_swd_to_jtag, TAP_RESET);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Sequence %d not supported\", seq);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (retval == ERROR_OK)\n\t\tretval = jtag_execute_queue();\n\treturn retval;\n}\n\nstatic int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,\n\t\tuint32_t *data)\n{\n\tint retval = jtag_limit_queue_size(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval =  adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC, reg,\n\t\t\tDPAP_READ, 0, dap->last_read, 0, NULL);\n\tdap->last_read = data;\n\treturn retval;\n}\n\nstatic int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,\n\t\tuint32_t data)\n{\n\tint retval = jtag_limit_queue_size(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval =  adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,\n\t\t\treg, DPAP_WRITE, data, dap->last_read, 0, NULL);\n\tdap->last_read = NULL;\n\treturn retval;\n}\n\n/** Select the AP register bank matching bits 7:4 of reg. */\nstatic int jtag_ap_q_bankselect(struct adiv5_ap *ap, unsigned reg)\n{\n\tint retval;\n\tstruct adiv5_dap *dap = ap->dap;\n\tuint64_t sel;\n\n\tif (is_adiv6(dap)) {\n\t\tsel = ap->ap_num | (reg & 0x00000FF0);\n\t\tif (sel == (dap->select & ~0xfull))\n\t\t\treturn ERROR_OK;\n\n\t\tif (dap->select != DP_SELECT_INVALID)\n\t\t\tsel |= dap->select & 0xf;\n\t\tdap->select = sel;\n\t\tLOG_DEBUG(\"AP BANKSEL: %\" PRIx64, sel);\n\n\t\tretval = jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (dap->asize > 32)\n\t\t\treturn jtag_dp_q_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));\n\t\treturn ERROR_OK;\n\t}\n\n\t/* ADIv5 */\n\tsel = (ap->ap_num << 24) | (reg & 0x000000F0);\n\n\tif (sel == dap->select)\n\t\treturn ERROR_OK;\n\n\tdap->select = sel;\n\n\treturn jtag_dp_q_write(dap, DP_SELECT, (uint32_t)sel);\n}\n\nstatic int jtag_ap_q_read(struct adiv5_ap *ap, unsigned reg,\n\t\tuint32_t *data)\n{\n\tint retval = jtag_limit_queue_size(ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_check_reconnect(ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_ap_q_bankselect(ap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval =  adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg,\n\t\t\tDPAP_READ, 0, ap->dap->last_read, ap->memaccess_tck, NULL);\n\tap->dap->last_read = data;\n\n\treturn retval;\n}\n\nstatic int jtag_ap_q_write(struct adiv5_ap *ap, unsigned reg,\n\t\tuint32_t data)\n{\n\tint retval = jtag_limit_queue_size(ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_check_reconnect(ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_ap_q_bankselect(ap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval =  adi_jtag_dp_scan_u32(ap->dap, JTAG_DP_APACC, reg,\n\t\t\tDPAP_WRITE, data, ap->dap->last_read, ap->memaccess_tck, NULL);\n\tap->dap->last_read = NULL;\n\treturn retval;\n}\n\nstatic int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\t/* for JTAG, this is the only valid ABORT register operation */\n\tint retval =  adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT,\n\t\t\t0, DPAP_WRITE, 1, NULL, 0, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn jtag_execute_queue();\n}\n\nstatic int jtag_dp_run(struct adiv5_dap *dap)\n{\n\tint retval;\n\tint retval2 = ERROR_OK;\n\n\tretval = adi_jtag_finish_read(dap);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\tretval2 = jtagdp_overrun_check(dap);\n\tretval = jtagdp_transaction_endcheck(dap);\n\n done:\n\treturn (retval2 != ERROR_OK) ? retval2 : retval;\n}\n\nstatic int jtag_dp_sync(struct adiv5_dap *dap)\n{\n\treturn jtagdp_overrun_check(dap);\n}\n\n/* FIXME don't export ... just initialize as\n * part of DAP setup\n*/\nconst struct dap_ops jtag_dp_ops = {\n\t.connect             = jtag_connect,\n\t.send_sequence       = jtag_send_sequence,\n\t.queue_dp_read       = jtag_dp_q_read,\n\t.queue_dp_write      = jtag_dp_q_write,\n\t.queue_ap_read       = jtag_ap_q_read,\n\t.queue_ap_write      = jtag_ap_q_write,\n\t.queue_ap_abort      = jtag_ap_q_abort,\n\t.run                 = jtag_dp_run,\n\t.sync                = jtag_dp_sync,\n\t.quit                = jtag_quit,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/adi_v5_swd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *\n *   Copyright (C) 2010 by David Brownell\n ***************************************************************************/\n\n/**\n * @file\n * Utilities to support ARM \"Serial Wire Debug\" (SWD), a low pin-count debug\n * link protocol used in cases where JTAG is not wanted.  This is coupled to\n * recent versions of ARM's \"CoreSight\" debug framework.  This specific code\n * is a transport level interface, with \"target/arm_adi_v5.[hc]\" code\n * understanding operation semantics, shared with the JTAG transport.\n *\n * Single DAP and multidrop-SWD support.\n *\n * for details, see \"ARM IHI 0031A\"\n * ARM Debug Interface v5 Architecture Specification\n * especially section 5.3 for SWD protocol\n * and \"ARM IHI 0074C\" ARM Debug Interface Architecture Specification ADIv6.0\n *\n * On many chips (most current Cortex-M3 parts) SWD is a run-time alternative\n * to JTAG.  Boards may support one or both.  There are also SWD-only chips,\n * (using SW-DP not SWJ-DP).\n *\n * Even boards that also support JTAG can benefit from SWD support, because\n * usually there's no way to access the SWO trace view mechanism in JTAG mode.\n * That is, trace access may require SWD support.\n *\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"arm_adi_v5.h\"\n#include <helper/time_support.h>\n\n#include <transport/transport.h>\n#include <jtag/interface.h>\n\n#include <jtag/swd.h>\n\n/* for debug, set do_sync to true to force synchronous transfers */\nstatic bool do_sync;\n\nstatic struct adiv5_dap *swd_multidrop_selected_dap;\n\n\nstatic int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,\n\t\tuint32_t data);\n\n\nstatic int swd_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\treturn swd->switch_seq(seq);\n}\n\nstatic void swd_finish_read(struct adiv5_dap *dap)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tif (dap->last_read) {\n\t\tswd->read_reg(swd_cmd(true, false, DP_RDBUFF), dap->last_read, 0);\n\t\tdap->last_read = NULL;\n\t}\n}\n\nstatic void swd_clear_sticky_errors(struct adiv5_dap *dap)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tswd->write_reg(swd_cmd(false, false, DP_ABORT),\n\t\tSTKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);\n}\n\nstatic int swd_run_inner(struct adiv5_dap *dap)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tint retval;\n\n\tretval = swd->run();\n\n\tif (retval != ERROR_OK) {\n\t\t/* fault response */\n\t\tdap->do_reconnect = true;\n\t}\n\n\treturn retval;\n}\n\nstatic inline int check_sync(struct adiv5_dap *dap)\n{\n\treturn do_sync ? swd_run_inner(dap) : ERROR_OK;\n}\n\n/** Select the DP register bank matching bits 7:4 of reg. */\nstatic int swd_queue_dp_bankselect(struct adiv5_dap *dap, unsigned int reg)\n{\n\t/* Only register address 0 and 4 are banked. */\n\tif ((reg & 0xf) > 4)\n\t\treturn ERROR_OK;\n\n\tuint64_t sel = (reg & 0x000000F0) >> 4;\n\tif (dap->select != DP_SELECT_INVALID)\n\t\tsel |= dap->select & ~0xfULL;\n\n\tif (sel == dap->select)\n\t\treturn ERROR_OK;\n\n\tdap->select = sel;\n\n\tint retval = swd_queue_dp_write_inner(dap, DP_SELECT, (uint32_t)sel);\n\tif (retval != ERROR_OK)\n\t\tdap->select = DP_SELECT_INVALID;\n\n\treturn retval;\n}\n\nstatic int swd_queue_dp_read_inner(struct adiv5_dap *dap, unsigned int reg,\n\t\tuint32_t *data)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tint retval = swd_queue_dp_bankselect(dap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd->read_reg(swd_cmd(true, false, reg), data, 0);\n\n\treturn check_sync(dap);\n}\n\nstatic int swd_queue_dp_write_inner(struct adiv5_dap *dap, unsigned int reg,\n\t\tuint32_t data)\n{\n\tint retval;\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tswd_finish_read(dap);\n\n\tif (reg == DP_SELECT) {\n\t\tdap->select = data & (DP_SELECT_APSEL | DP_SELECT_APBANK | DP_SELECT_DPBANK);\n\n\t\tswd->write_reg(swd_cmd(false, false, reg), data, 0);\n\n\t\tretval = check_sync(dap);\n\t\tif (retval != ERROR_OK)\n\t\t\tdap->select = DP_SELECT_INVALID;\n\n\t\treturn retval;\n\t}\n\n\tretval = swd_queue_dp_bankselect(dap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd->write_reg(swd_cmd(false, false, reg), data, 0);\n\n\treturn check_sync(dap);\n}\n\n\nstatic int swd_multidrop_select_inner(struct adiv5_dap *dap, uint32_t *dpidr_ptr,\n\t\tuint32_t *dlpidr_ptr, bool clear_sticky)\n{\n\tint retval;\n\tuint32_t dpidr, dlpidr;\n\n\tassert(dap_is_multidrop(dap));\n\n\tswd_send_sequence(dap, LINE_RESET);\n\t/* From ARM IHI 0074C ADIv6.0, chapter B4.3.3 \"Connection and line reset\n\t * sequence\":\n\t * - line reset sets DP_SELECT_DPBANK to zero;\n\t * - read of DP_DPIDR takes the connection out of reset;\n\t * - write of DP_TARGETSEL keeps the connection in reset;\n\t * - other accesses return protocol error (SWDIO not driven by target).\n\t *\n\t * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to\n\t * skip the write to DP_SELECT, avoiding the protocol error. Set again\n\t * dap->select to DP_SELECT_INVALID because the rest of the register is\n\t * unknown after line reset.\n\t */\n\tdap->select = 0;\n\n\tretval = swd_queue_dp_write_inner(dap, DP_TARGETSEL, dap->multidrop_targetsel);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (clear_sticky) {\n\t\t/* Clear all sticky errors (including ORUN) */\n\t\tswd_clear_sticky_errors(dap);\n\t} else {\n\t\t/* Ideally just clear ORUN flag which is set by reset */\n\t\tretval = swd_queue_dp_write_inner(dap, DP_ABORT, ORUNERRCLR);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tdap->select = DP_SELECT_INVALID;\n\n\tretval = swd_queue_dp_read_inner(dap, DP_DLPIDR, &dlpidr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_run_inner(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((dpidr & DP_DPIDR_VERSION_MASK) < (2UL << DP_DPIDR_VERSION_SHIFT)) {\n\t\tLOG_INFO(\"Read DPIDR 0x%08\" PRIx32\n\t\t\t\t \" has version < 2. A non multidrop capable device connected?\",\n\t\t\t\t dpidr);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* TODO: check TARGETID if DLIPDR is same for more than one DP */\n\tuint32_t expected_dlpidr = DP_DLPIDR_PROTVSN |\n\t\t\t(dap->multidrop_targetsel & DP_TARGETSEL_INSTANCEID_MASK);\n\tif (dlpidr != expected_dlpidr) {\n\t\tLOG_INFO(\"Read incorrect DLPIDR 0x%08\" PRIx32\n\t\t\t\t \" (possibly CTRL/STAT value)\",\n\t\t\t\t dlpidr);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG_IO(\"Selected DP_TARGETSEL 0x%08\" PRIx32, dap->multidrop_targetsel);\n\tswd_multidrop_selected_dap = dap;\n\n\tif (dpidr_ptr)\n\t\t*dpidr_ptr = dpidr;\n\n\tif (dlpidr_ptr)\n\t\t*dlpidr_ptr = dlpidr;\n\n\treturn retval;\n}\n\nstatic int swd_multidrop_select(struct adiv5_dap *dap)\n{\n\tif (!dap_is_multidrop(dap))\n\t\treturn ERROR_OK;\n\n\tif (swd_multidrop_selected_dap == dap)\n\t\treturn ERROR_OK;\n\n\tint retval = ERROR_OK;\n\tfor (unsigned int retry = 0; ; retry++) {\n\t\tbool clear_sticky = retry > 0;\n\n\t\tretval = swd_multidrop_select_inner(dap, NULL, NULL, clear_sticky);\n\t\tif (retval == ERROR_OK)\n\t\t\tbreak;\n\n\t\tswd_multidrop_selected_dap = NULL;\n\t\tif (retry > 3) {\n\t\t\tLOG_ERROR(\"Failed to select multidrop %s\", adiv5_dap_name(dap));\n\t\t\treturn retval;\n\t\t}\n\n\t\tLOG_DEBUG(\"Failed to select multidrop %s, retrying...\",\n\t\t\t\t  adiv5_dap_name(dap));\n\t\t/* we going to retry localy, do not ask for full reconnect */\n\t\tdap->do_reconnect = false;\n\t}\n\n\treturn retval;\n}\n\nstatic int swd_connect_multidrop(struct adiv5_dap *dap)\n{\n\tint retval;\n\tuint32_t dpidr = 0xdeadbeef;\n\tuint32_t dlpidr = 0xdeadbeef;\n\tint64_t timeout = timeval_ms() + 500;\n\n\tdo {\n\t\tswd_send_sequence(dap, JTAG_TO_DORMANT);\n\t\tswd_send_sequence(dap, DORMANT_TO_SWD);\n\n\t\t/* Clear link state, including the SELECT cache. */\n\t\tdap->do_reconnect = false;\n\t\tdap_invalidate_cache(dap);\n\t\tswd_multidrop_selected_dap = NULL;\n\n\t\tretval = swd_multidrop_select_inner(dap, &dpidr, &dlpidr, true);\n\t\tif (retval == ERROR_OK)\n\t\t\tbreak;\n\n\t\talive_sleep(1);\n\n\t} while (timeval_ms() < timeout);\n\n\tif (retval != ERROR_OK) {\n\t\tswd_multidrop_selected_dap = NULL;\n\t\tLOG_ERROR(\"Failed to connect multidrop %s\", adiv5_dap_name(dap));\n\t\treturn retval;\n\t}\n\n\tLOG_INFO(\"SWD DPIDR 0x%08\" PRIx32 \", DLPIDR 0x%08\" PRIx32,\n\t\t\t  dpidr, dlpidr);\n\n\treturn retval;\n}\n\nstatic int swd_connect_single(struct adiv5_dap *dap)\n{\n\tint retval;\n\tuint32_t dpidr = 0xdeadbeef;\n\tint64_t timeout = timeval_ms() + 500;\n\n\tdo {\n\t\tif (dap->switch_through_dormant) {\n\t\t\tswd_send_sequence(dap, JTAG_TO_DORMANT);\n\t\t\tswd_send_sequence(dap, DORMANT_TO_SWD);\n\t\t} else {\n\t\t\tswd_send_sequence(dap, JTAG_TO_SWD);\n\t\t}\n\n\t\t/* Clear link state, including the SELECT cache. */\n\t\tdap->do_reconnect = false;\n\t\tdap_invalidate_cache(dap);\n\n\t\t/* The sequences to enter in SWD (JTAG_TO_SWD and DORMANT_TO_SWD) end\n\t\t * with a SWD line reset sequence (50 clk with SWDIO high).\n\t\t * From ARM IHI 0074C ADIv6.0, chapter B4.3.3 \"Connection and line reset\n\t\t * sequence\":\n\t\t * - line reset sets DP_SELECT_DPBANK to zero;\n\t\t * - read of DP_DPIDR takes the connection out of reset;\n\t\t * - write of DP_TARGETSEL keeps the connection in reset;\n\t\t * - other accesses return protocol error (SWDIO not driven by target).\n\t\t *\n\t\t * Read DP_DPIDR to get out of reset. Initialize dap->select to zero to\n\t\t * skip the write to DP_SELECT, avoiding the protocol error. Set again\n\t\t * dap->select to DP_SELECT_INVALID because the rest of the register is\n\t\t * unknown after line reset.\n\t\t */\n\t\tdap->select = 0;\n\t\tretval = swd_queue_dp_read_inner(dap, DP_DPIDR, &dpidr);\n\t\tif (retval == ERROR_OK) {\n\t\t\tretval = swd_run_inner(dap);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tbreak;\n\t\t}\n\n\t\talive_sleep(1);\n\n\t\tdap->switch_through_dormant = !dap->switch_through_dormant;\n\t} while (timeval_ms() < timeout);\n\n\tdap->select = DP_SELECT_INVALID;\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error connecting DP: cannot read IDR\");\n\t\treturn retval;\n\t}\n\n\tLOG_INFO(\"SWD DPIDR 0x%08\" PRIx32, dpidr);\n\n\tdo {\n\t\tdap->do_reconnect = false;\n\n\t\t/* force clear all sticky faults */\n\t\tswd_clear_sticky_errors(dap);\n\n\t\tretval = swd_run_inner(dap);\n\t\tif (retval != ERROR_WAIT)\n\t\t\tbreak;\n\n\t\talive_sleep(10);\n\n\t} while (timeval_ms() < timeout);\n\n\treturn retval;\n}\n\nstatic int swd_connect(struct adiv5_dap *dap)\n{\n\tint status;\n\n\t/* FIXME validate transport config ... is the\n\t * configured DAP present (check IDCODE)?\n\t */\n\n\t/* Check if we should reset srst already when connecting, but not if reconnecting. */\n\tif (!dap->do_reconnect) {\n\t\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\t\tadapter_assert_reset();\n\t\t\telse\n\t\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t\t}\n\t}\n\n\tif (dap_is_multidrop(dap))\n\t\tstatus = swd_connect_multidrop(dap);\n\telse\n\t\tstatus = swd_connect_single(dap);\n\n\t/* IHI 0031E B4.3.2:\n\t * \"A WAIT response must not be issued to the ...\n\t * ... writes to the ABORT register\"\n\t * swd_clear_sticky_errors() writes to the ABORT register only.\n\t *\n\t * Unfortunately at least Microchip SAMD51/E53/E54 returns WAIT\n\t * in a corner case. Just try if ABORT resolves the problem.\n\t */\n\tif (status == ERROR_WAIT) {\n\t\tLOG_WARNING(\"Connecting DP: stalled AP operation, issuing ABORT\");\n\n\t\tdap->do_reconnect = false;\n\n\t\tstatus = swd_queue_dp_write_inner(dap, DP_ABORT,\n\t\t\tDAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR);\n\n\t\tif (status == ERROR_OK)\n\t\t\tstatus = swd_run_inner(dap);\n\t}\n\n\tif (status == ERROR_OK)\n\t\tstatus = dap_dp_init(dap);\n\n\treturn status;\n}\n\nstatic int swd_check_reconnect(struct adiv5_dap *dap)\n{\n\tif (dap->do_reconnect)\n\t\treturn swd_connect(dap);\n\n\treturn ERROR_OK;\n}\n\nstatic int swd_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\t/* TODO: Send DAPABORT in swd_multidrop_select_inner()\n\t * in the case the multidrop dap is not selected?\n\t * swd_queue_ap_abort() is not currently used anyway...\n\t */\n\tint retval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd->write_reg(swd_cmd(false, false, DP_ABORT),\n\t\tDAPABORT | STKCMPCLR | STKERRCLR | WDERRCLR | ORUNERRCLR, 0);\n\treturn check_sync(dap);\n}\n\nstatic int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,\n\t\tuint32_t *data)\n{\n\tint retval = swd_check_reconnect(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn swd_queue_dp_read_inner(dap, reg, data);\n}\n\nstatic int swd_queue_dp_write(struct adiv5_dap *dap, unsigned reg,\n\t\tuint32_t data)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tint retval = swd_check_reconnect(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn swd_queue_dp_write_inner(dap, reg, data);\n}\n\n/** Select the AP register bank matching bits 7:4 of reg. */\nstatic int swd_queue_ap_bankselect(struct adiv5_ap *ap, unsigned reg)\n{\n\tint retval;\n\tstruct adiv5_dap *dap = ap->dap;\n\tuint64_t sel;\n\n\tif (is_adiv6(dap)) {\n\t\tsel = ap->ap_num | (reg & 0x00000FF0);\n\t\tif (sel == (dap->select & ~0xfULL))\n\t\t\treturn ERROR_OK;\n\n\t\tif (dap->select != DP_SELECT_INVALID)\n\t\t\tsel |= dap->select & 0xf;\n\t\tdap->select = sel;\n\t\tLOG_DEBUG(\"AP BANKSEL: %\" PRIx64, sel);\n\n\t\tretval = swd_queue_dp_write(dap, DP_SELECT, (uint32_t)sel);\n\n\t\tif (retval == ERROR_OK && dap->asize > 32)\n\t\t\tretval = swd_queue_dp_write(dap, DP_SELECT1, (uint32_t)(sel >> 32));\n\n\t\tif (retval != ERROR_OK)\n\t\t\tdap->select = DP_SELECT_INVALID;\n\n\t\treturn retval;\n\t}\n\n\t/* ADIv5 */\n\tsel = (ap->ap_num << 24) | (reg & 0x000000F0);\n\tif (dap->select != DP_SELECT_INVALID)\n\t\tsel |= dap->select & DP_SELECT_DPBANK;\n\n\tif (sel == dap->select)\n\t\treturn ERROR_OK;\n\n\tdap->select = sel;\n\n\tretval = swd_queue_dp_write_inner(dap, DP_SELECT, sel);\n\tif (retval != ERROR_OK)\n\t\tdap->select = DP_SELECT_INVALID;\n\n\treturn retval;\n}\n\nstatic int swd_queue_ap_read(struct adiv5_ap *ap, unsigned reg,\n\t\tuint32_t *data)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tint retval = swd_check_reconnect(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_queue_ap_bankselect(ap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd->read_reg(swd_cmd(true, true, reg), dap->last_read, ap->memaccess_tck);\n\tdap->last_read = data;\n\n\treturn check_sync(dap);\n}\n\nstatic int swd_queue_ap_write(struct adiv5_ap *ap, unsigned reg,\n\t\tuint32_t data)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tassert(swd);\n\n\tint retval = swd_check_reconnect(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd_finish_read(dap);\n\n\tretval = swd_queue_ap_bankselect(ap, reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd->write_reg(swd_cmd(false, true, reg), data, ap->memaccess_tck);\n\n\treturn check_sync(dap);\n}\n\n/** Executes all queued DAP operations. */\nstatic int swd_run(struct adiv5_dap *dap)\n{\n\tint retval = swd_multidrop_select(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswd_finish_read(dap);\n\n\treturn swd_run_inner(dap);\n}\n\n/** Put the SWJ-DP back to JTAG mode */\nstatic void swd_quit(struct adiv5_dap *dap)\n{\n\tconst struct swd_driver *swd = adiv5_dap_swd_driver(dap);\n\tstatic bool done;\n\n\t/* There is no difference if the sequence is sent at the last\n\t * or the first swd_quit() call, send it just once */\n\tif (done)\n\t\treturn;\n\n\tdone = true;\n\tif (dap_is_multidrop(dap)) {\n\t\tswd->switch_seq(SWD_TO_DORMANT);\n\t\t/* Revisit!\n\t\t * Leaving DPs in dormant state was tested and offers some safety\n\t\t * against DPs mismatch in case of unintentional use of non-multidrop SWD.\n\t\t * To put SWJ-DPs to power-on state issue\n\t\t * swd->switch_seq(DORMANT_TO_JTAG);\n\t\t */\n\t} else {\n\t\tif (dap->switch_through_dormant) {\n\t\t\tswd->switch_seq(SWD_TO_DORMANT);\n\t\t\tswd->switch_seq(DORMANT_TO_JTAG);\n\t\t} else {\n\t\t\tswd->switch_seq(SWD_TO_JTAG);\n\t\t}\n\t}\n\n\t/* flush the queue to shift out the sequence before exit */\n\tswd->run();\n}\n\nconst struct dap_ops swd_dap_ops = {\n\t.connect = swd_connect,\n\t.send_sequence = swd_send_sequence,\n\t.queue_dp_read = swd_queue_dp_read,\n\t.queue_dp_write = swd_queue_dp_write,\n\t.queue_ap_read = swd_queue_ap_read,\n\t.queue_ap_write = swd_queue_ap_write,\n\t.queue_ap_abort = swd_queue_ap_abort,\n\t.run = swd_run,\n\t.quit = swd_quit,\n};\n\nstatic const struct command_registration swd_commands[] = {\n\t{\n\t\t/*\n\t\t * Set up SWD and JTAG targets identically, unless/until\n\t\t * infrastructure improves ...  meanwhile, ignore all\n\t\t * JTAG-specific stuff like IR length for SWD.\n\t\t *\n\t\t * REVISIT can we verify \"just one SWD DAP\" here/early?\n\t\t */\n\t\t.name = \"newdap\",\n\t\t.handler = handle_jtag_newtap,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"declare a new SWD DAP\",\n\t\t.usage = \"basename dap_type ['-irlen' count] \"\n\t\t\t\"['-enable'|'-disable'] \"\n\t\t\t\"['-expected_id' number] \"\n\t\t\t\"['-ignore-version'] \"\n\t\t\t\"['-ignore-bypass'] \"\n\t\t\t\"['-ircapture' number] \"\n\t\t\t\"['-mask' number]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration swd_handlers[] = {\n\t{\n\t\t.name = \"swd\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"SWD command group\",\n\t\t.chain = swd_commands,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int swd_select(struct command_context *ctx)\n{\n\t/* FIXME: only place where global 'adapter_driver' is still needed */\n\textern struct adapter_driver *adapter_driver;\n\tconst struct swd_driver *swd = adapter_driver->swd_ops;\n\tint retval;\n\n\tretval = register_commands(ctx, NULL, swd_handlers);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t /* be sure driver is in SWD mode; start\n\t  * with hardware default TRN (1), it can be changed later\n\t  */\n\tif (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {\n\t\tLOG_DEBUG(\"no SWD driver?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = swd->init();\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"can't init SWD driver\");\n\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int swd_init(struct command_context *ctx)\n{\n\t/* nothing done here, SWD is initialized\n\t * together with the DAP */\n\treturn ERROR_OK;\n}\n\nstatic struct transport swd_transport = {\n\t.name = \"swd\",\n\t.select = swd_select,\n\t.init = swd_init,\n};\n\nstatic void swd_constructor(void) __attribute__((constructor));\nstatic void swd_constructor(void)\n{\n\ttransport_register(&swd_transport);\n}\n\n/** Returns true if the current debug session\n * is using SWD as its transport.\n */\nbool transport_is_swd(void)\n{\n\treturn get_current_transport() == &swd_transport;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/algorithm.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"algorithm.h\"\n#include <helper/binarybuffer.h>\n\nvoid init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction)\n{\n\tparam->address = address;\n\tparam->size = size;\n\tparam->value = malloc(size);\n\tparam->direction = direction;\n}\n\nvoid destroy_mem_param(struct mem_param *param)\n{\n\tfree(param->value);\n\tparam->value = NULL;\n}\n\nvoid init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)\n{\n\tparam->reg_name = reg_name;\n\tparam->size = size;\n\tparam->value = malloc(DIV_ROUND_UP(size, 8));\n\tparam->direction = direction;\n}\n\nvoid destroy_reg_param(struct reg_param *param)\n{\n\tfree(param->value);\n\tparam->value = NULL;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/algorithm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ALGORITHM_H\n#define OPENOCD_TARGET_ALGORITHM_H\n\n#include \"helper/types.h\"\n#include \"helper/replacements.h\"\n\nenum param_direction {\n\tPARAM_IN,\n\tPARAM_OUT,\n\tPARAM_IN_OUT\n};\n\nstruct mem_param {\n\ttarget_addr_t address;\n\tuint32_t size;\n\tuint8_t *value;\n\tenum param_direction direction;\n};\n\nstruct reg_param {\n\tconst char *reg_name;\n\tuint32_t size;\n\tuint8_t *value;\n\tenum param_direction direction;\n};\n\nvoid init_mem_param(struct mem_param *param,\n\t\tuint32_t address, uint32_t size, enum param_direction dir);\nvoid destroy_mem_param(struct mem_param *param);\n\nvoid init_reg_param(struct reg_param *param,\n\t\tchar *reg_name, uint32_t size, enum param_direction dir);\nvoid destroy_reg_param(struct reg_param *param);\n\n#endif /* OPENOCD_TARGET_ALGORITHM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2015,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arc.h\"\n\n\n\n/*\n * ARC architecture specific details.\n *\n * ARC has two types of registers:\n *  1) core registers(e.g. r0,r1..) [is_core = true]\n *  2) Auxiliary registers [is_core = false]..\n *\n * Auxiliary registers at the same time can be divided into\n * read-only BCR(build configuration regs, e.g. isa_config, mpu_build) and\n * R/RW non-BCR (\"control\" register, e.g. pc, status32_t, debug).\n *\n * The way of accessing to Core and AUX registers differs on Jtag level.\n * BCR/non-BCR describes if the register is immutable and that reading\n * unexisting register is safe RAZ, rather then an error.\n * Note, core registers cannot be BCR.\n *\n * In arc/cpu/ tcl files all registers are defined as core, non-BCR aux\n * and BCR aux, in \"add-reg\" command they are passed to three lists\n * respectively:  core_reg_descriptions, aux_reg_descriptions,\n * bcr_reg_descriptions.\n *\n * Due to the specifics of accessing to BCR/non-BCR registers there are two\n * register caches:\n *  1) core_and_aux_cache - includes registers described in\n *     core_reg_descriptions and aux_reg_descriptions lists.\n *     Used during save/restore context step.\n *  2) bcr_cache - includes registers described bcr_reg_descriptions.\n *     Currently used internally during configure step.\n */\n\n\nstatic int arc_remove_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint);\n\nvoid arc_reg_data_type_add(struct target *target,\n\t\tstruct arc_reg_data_type *data_type)\n{\n\tLOG_DEBUG(\"Adding %s reg_data_type\", data_type->data_type.id);\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\tlist_add_tail(&data_type->list, &arc->reg_data_types);\n}\n\n/**\n * Private implementation of register_get_by_name() for ARC that\n * doesn't skip not [yet] existing registers. Used in many places\n * for iteration through registers and even for marking required registers as\n * existing.\n */\nstruct reg *arc_reg_get_by_name(struct reg_cache *first,\n\t\tconst char *name, bool search_all)\n{\n\tunsigned int i;\n\tstruct reg_cache *cache = first;\n\n\twhile (cache) {\n\t\tfor (i = 0; i < cache->num_regs; i++) {\n\t\t\tif (!strcmp(cache->reg_list[i].name, name))\n\t\t\t\treturn &(cache->reg_list[i]);\n\t\t}\n\n\t\tif (search_all)\n\t\t\tcache = cache->next;\n\t\telse\n\t\t\tbreak;\n\t}\n\n\treturn NULL;\n}\n\n/**\n * Reset internal states of caches. Must be called when entering debugging.\n *\n * @param target Target for which to reset caches states.\n */\nstatic int arc_reset_caches_states(struct target *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tLOG_DEBUG(\"Resetting internal variables of caches states\");\n\n\t/* Reset caches states. */\n\tarc->dcache_flushed = false;\n\tarc->l2cache_flushed = false;\n\tarc->icache_invalidated = false;\n\tarc->dcache_invalidated = false;\n\tarc->l2cache_invalidated = false;\n\n\treturn ERROR_OK;\n}\n\n/* Initialize arc_common structure, which passes to openocd target instance */\nstatic int arc_init_arch_info(struct target *target, struct arc_common *arc,\n\tstruct jtag_tap *tap)\n{\n\tarc->common_magic = ARC_COMMON_MAGIC;\n\ttarget->arch_info = arc;\n\n\tarc->jtag_info.tap = tap;\n\n\t/* The only allowed ir_length is 4 for ARC jtag. */\n\tif (tap->ir_length != 4) {\n\t\tLOG_ERROR(\"ARC jtag instruction length should be equal to 4\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* On most ARC targets there is a dcache, so we enable its flushing\n\t * by default. If there no dcache, there will be no error, just a slight\n\t * performance penalty from unnecessary JTAG operations. */\n\tarc->has_dcache = true;\n\tarc->has_icache = true;\n\t/* L2$ is not available in a target by default. */\n\tarc->has_l2cache = false;\n\tarc_reset_caches_states(target);\n\n\t/* Add standard GDB data types */\n\tINIT_LIST_HEAD(&arc->reg_data_types);\n\tstruct arc_reg_data_type *std_types = calloc(ARRAY_SIZE(standard_gdb_types),\n\t\tsizeof(*std_types));\n\n\tif (!std_types) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(standard_gdb_types); i++) {\n\t\tstd_types[i].data_type.type = standard_gdb_types[i].type;\n\t\tstd_types[i].data_type.id = standard_gdb_types[i].id;\n\t\tarc_reg_data_type_add(target, &(std_types[i]));\n\t}\n\n\t/* Fields related to target descriptions */\n\tINIT_LIST_HEAD(&arc->core_reg_descriptions);\n\tINIT_LIST_HEAD(&arc->aux_reg_descriptions);\n\tINIT_LIST_HEAD(&arc->bcr_reg_descriptions);\n\tarc->num_regs = 0;\n\tarc->num_core_regs = 0;\n\tarc->num_aux_regs = 0;\n\tarc->num_bcr_regs = 0;\n\tarc->last_general_reg = ULONG_MAX;\n\tarc->pc_index_in_cache = ULONG_MAX;\n\tarc->debug_index_in_cache = ULONG_MAX;\n\n\treturn ERROR_OK;\n}\n\nint arc_reg_add(struct target *target, struct arc_reg_desc *arc_reg,\n\t\tconst char * const type_name, const size_t type_name_len)\n{\n\tassert(target);\n\tassert(arc_reg);\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\t/* Find register type */\n\t{\n\t\tstruct arc_reg_data_type *type;\n\t\tlist_for_each_entry(type, &arc->reg_data_types, list)\n\t\t\tif (!strncmp(type->data_type.id, type_name, type_name_len)) {\n\t\t\t\tarc_reg->data_type = &(type->data_type);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\tif (!arc_reg->data_type)\n\t\t\treturn ERROR_ARC_REGTYPE_NOT_FOUND;\n\t}\n\n\tif (arc_reg->is_core) {\n\t\tlist_add_tail(&arc_reg->list, &arc->core_reg_descriptions);\n\t\tarc->num_core_regs += 1;\n\t} else if (arc_reg->is_bcr) {\n\t\tlist_add_tail(&arc_reg->list, &arc->bcr_reg_descriptions);\n\t\tarc->num_bcr_regs += 1;\n\t} else {\n\t\tlist_add_tail(&arc_reg->list, &arc->aux_reg_descriptions);\n\t\tarc->num_aux_regs += 1;\n\t}\n\tarc->num_regs += 1;\n\n\tLOG_DEBUG(\n\t\t\t\"added register {name=%s, num=0x%\" PRIx32 \", type=%s%s%s%s}\",\n\t\t\tarc_reg->name, arc_reg->arch_num, arc_reg->data_type->id,\n\t\t\tarc_reg->is_core ? \", core\" : \"\",  arc_reg->is_bcr ? \", bcr\" : \"\",\n\t\t\tarc_reg->is_general ? \", general\" : \"\"\n\t\t);\n\n\treturn ERROR_OK;\n}\n\n/* Reading core or aux register */\nstatic int arc_get_register(struct reg *reg)\n{\n\tassert(reg);\n\n\tstruct arc_reg_desc *desc = reg->arch_info;\n\tstruct target *target = desc->target;\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tuint32_t value;\n\n\tif (reg->valid) {\n\t\tLOG_DEBUG(\"Get register (cached) gdb_num=%\" PRIu32 \", name=%s, value=0x%\" PRIx32,\n\t\t\t\treg->number, desc->name, target_buffer_get_u32(target, reg->value));\n\t\treturn ERROR_OK;\n\t}\n\n\tif (desc->is_core) {\n\t\t/* Accessing to R61/R62 registers causes Jtag hang */\n\t\tif (desc->arch_num == ARC_R61 || desc->arch_num == ARC_R62) {\n\t\t\tLOG_ERROR(\"It is forbidden to read core registers 61 and 62.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tCHECK_RETVAL(arc_jtag_read_core_reg_one(&arc->jtag_info, desc->arch_num,\n\t\t\t\t\t&value));\n\t} else {\n\t\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, desc->arch_num,\n\t\t\t&value));\n\t}\n\n\ttarget_buffer_set_u32(target, reg->value, value);\n\n\t/* If target is unhalted all register reads should be uncached. */\n\tif (target->state == TARGET_HALTED)\n\t\treg->valid = true;\n\telse\n\t\treg->valid = false;\n\n\treg->dirty = false;\n\n\tLOG_DEBUG(\"Get register gdb_num=%\" PRIu32 \", name=%s, value=0x%\" PRIx32,\n\t\t\treg->number, desc->name, value);\n\n\n\treturn ERROR_OK;\n}\n\n/* Writing core or aux register */\nstatic int arc_set_register(struct reg *reg, uint8_t *buf)\n{\n\tstruct arc_reg_desc *desc = reg->arch_info;\n\tstruct target *target = desc->target;\n\tuint32_t value = target_buffer_get_u32(target, buf);\n\t/* Unlike \"get\" function \"set\" is supported only if target\n\t* is in halt mode. Async writes are not supported yet. */\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/* Accessing to R61/R62 registers causes Jtag hang */\n\tif (desc->is_core && (desc->arch_num == ARC_R61 ||\n\t\t\tdesc->arch_num == ARC_R62)) {\n\t\tLOG_ERROR(\"It is forbidden to write core registers 61 and 62.\");\n\t\treturn ERROR_FAIL;\n\t}\n\ttarget_buffer_set_u32(target, reg->value, value);\n\n\tLOG_DEBUG(\"Set register gdb_num=%\" PRIu32 \", name=%s, value=0x%08\" PRIx32,\n\t\t\treg->number, desc->name, value);\n\n\treg->valid = true;\n\treg->dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type arc_reg_type = {\n\t.get = arc_get_register,\n\t.set = arc_set_register,\n};\n\n/* GDB register groups. For now we support only general and \"empty\" */\nstatic const char * const reg_group_general = \"general\";\nstatic const char * const reg_group_other = \"\";\n\n/* Common code to initialize `struct reg` for different registers: core, aux, bcr. */\nstatic int arc_init_reg(struct target *target, struct reg *reg,\n\t\t\tstruct arc_reg_desc *reg_desc, unsigned long number)\n{\n\tassert(target);\n\tassert(reg);\n\tassert(reg_desc);\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* Initialize struct reg */\n\treg->name = reg_desc->name;\n\treg->size = 32; /* All register in ARC are 32-bit */\n\treg->value = reg_desc->reg_value;\n\treg->type = &arc_reg_type;\n\treg->arch_info = reg_desc;\n\treg->caller_save = true; /* @todo should be configurable. */\n\treg->reg_data_type = reg_desc->data_type;\n\treg->feature = &reg_desc->feature;\n\n\treg->feature->name = reg_desc->gdb_xml_feature;\n\n\t/* reg->number is used by OpenOCD as value for @regnum. Thus when setting\n\t * value of a register GDB will use it as a number of register in\n\t * P-packet. OpenOCD gdbserver will then use number of register in\n\t * P-packet as an array index in the reg_list returned by\n\t * arc_regs_get_gdb_reg_list. So to ensure that registers are assigned\n\t * correctly it would be required to either sort registers in\n\t * arc_regs_get_gdb_reg_list or to assign numbers sequentially here and\n\t * according to how registers will be sorted in\n\t * arc_regs_get_gdb_reg_list. Second options is much more simpler. */\n\treg->number = number;\n\n\tif (reg_desc->is_general) {\n\t\tarc->last_general_reg = reg->number;\n\t\treg->group = reg_group_general;\n\t} else {\n\t\treg->group = reg_group_other;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Building aux/core reg_cache */\nstatic int arc_build_reg_cache(struct target *target)\n{\n\tunsigned long i = 0;\n\tstruct arc_reg_desc *reg_desc;\n\t/* get pointers to arch-specific information */\n\tstruct arc_common *arc = target_to_arc(target);\n\tconst unsigned long num_regs = arc->num_core_regs + arc->num_aux_regs;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = calloc(1, sizeof(*cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(*reg_list));\n\n\tif (!cache || !reg_list)  {\n\t\tLOG_ERROR(\"Not enough memory\");\n\t\tgoto fail;\n\t}\n\n\t/* Build the process context cache */\n\tcache->name = \"arc registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\tarc->core_and_aux_cache = cache;\n\t(*cache_p) = cache;\n\n\tif (list_empty(&arc->core_reg_descriptions)) {\n\t\tLOG_ERROR(\"No core registers were defined\");\n\t\tgoto fail;\n\t}\n\n\tlist_for_each_entry(reg_desc, &arc->core_reg_descriptions, list) {\n\t\tCHECK_RETVAL(arc_init_reg(target, &reg_list[i], reg_desc, i));\n\n\t\tLOG_DEBUG(\"reg n=%3li name=%3s group=%s feature=%s\", i,\n\t\t\treg_list[i].name, reg_list[i].group,\n\t\t\treg_list[i].feature->name);\n\n\t\ti += 1;\n\t}\n\n\tif (list_empty(&arc->aux_reg_descriptions)) {\n\t\tLOG_ERROR(\"No aux registers were defined\");\n\t\tgoto fail;\n\t}\n\n\tlist_for_each_entry(reg_desc, &arc->aux_reg_descriptions, list) {\n\t\t CHECK_RETVAL(arc_init_reg(target, &reg_list[i],  reg_desc, i));\n\n\t\tLOG_DEBUG(\"reg n=%3li name=%3s group=%s feature=%s\", i,\n\t\t\treg_list[i].name, reg_list[i].group,\n\t\t\treg_list[i].feature->name);\n\n\t\t/* PC and DEBUG are essential so we search for them. */\n\t\tif (!strcmp(\"pc\", reg_desc->name)) {\n\t\t\tif (arc->pc_index_in_cache != ULONG_MAX) {\n\t\t\t\tLOG_ERROR(\"Double definition of PC in configuration\");\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tarc->pc_index_in_cache = i;\n\t\t} else if (!strcmp(\"debug\", reg_desc->name)) {\n\t\t\tif (arc->debug_index_in_cache != ULONG_MAX) {\n\t\t\t\tLOG_ERROR(\"Double definition of DEBUG in configuration\");\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tarc->debug_index_in_cache = i;\n\t\t}\n\t\ti += 1;\n\t}\n\n\tif (arc->pc_index_in_cache == ULONG_MAX\n\t\t\t|| arc->debug_index_in_cache == ULONG_MAX) {\n\t\tLOG_ERROR(\"`pc' and `debug' registers must be present in target description.\");\n\t\tgoto fail;\n\t}\n\n\tassert(i == (arc->num_core_regs + arc->num_aux_regs));\n\n\tarc->core_aux_cache_built = true;\n\n\treturn ERROR_OK;\n\nfail:\n\tfree(cache);\n\tfree(reg_list);\n\n\treturn ERROR_FAIL;\n}\n\n/* Build bcr reg_cache.\n * This function must be called only after arc_build_reg_cache */\nstatic int arc_build_bcr_reg_cache(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct arc_common *arc = target_to_arc(target);\n\tconst unsigned long num_regs = arc->num_bcr_regs;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(*cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(*reg_list));\n\n\tstruct arc_reg_desc *reg_desc;\n\tunsigned long i = 0;\n\tunsigned long gdb_regnum = arc->core_and_aux_cache->num_regs;\n\n\tif (!cache || !reg_list)  {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\tgoto fail;\n\t}\n\n\t/* Build the process context cache */\n\tcache->name = \"arc.bcr\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\tarc->bcr_cache = cache;\n\t(*cache_p) = cache;\n\n\tif (list_empty(&arc->bcr_reg_descriptions)) {\n\t\tLOG_ERROR(\"No BCR registers are defined\");\n\t\tgoto fail;\n\t}\n\n\tlist_for_each_entry(reg_desc, &arc->bcr_reg_descriptions, list) {\n\t\t CHECK_RETVAL(arc_init_reg(target, &reg_list[i], reg_desc, gdb_regnum));\n\t\t/* BCRs always semantically, they are just read-as-zero, if there is\n\t\t * not real register. */\n\t\treg_list[i].exist = true;\n\n\t\tLOG_DEBUG(\"reg n=%3li name=%3s group=%s feature=%s\", i,\n\t\t\treg_list[i].name, reg_list[i].group,\n\t\t\treg_list[i].feature->name);\n\t\ti += 1;\n\t\tgdb_regnum += 1;\n\t}\n\n\tassert(i == arc->num_bcr_regs);\n\n\tarc->bcr_cache_built = true;\n\n\n\treturn ERROR_OK;\nfail:\n\tfree(cache);\n\tfree(reg_list);\n\n\treturn ERROR_FAIL;\n}\n\n\nstatic int arc_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\tint *reg_list_size, enum target_register_class reg_class)\n{\n\tassert(target->reg_cache);\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* get pointers to arch-specific information storage */\n\t*reg_list_size = arc->num_regs;\n\t*reg_list = calloc(*reg_list_size, sizeof(struct reg *));\n\n\tif (!*reg_list) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* OpenOCD gdb_server API seems to be inconsistent here: when it generates\n\t * XML tdesc it filters out !exist registers, however when creating a\n\t * g-packet it doesn't do so. REG_CLASS_ALL is used in first case, and\n\t * REG_CLASS_GENERAL used in the latter one. Due to this we had to filter\n\t * out !exist register for \"general\", but not for \"all\". Attempts to filter out\n\t * !exist for \"all\" as well will cause a failed check in OpenOCD GDB\n\t * server. */\n\tif (reg_class == REG_CLASS_ALL) {\n\t\tunsigned long i = 0;\n\t\tstruct reg_cache *reg_cache = target->reg_cache;\n\t\twhile (reg_cache) {\n\t\t\tfor (unsigned j = 0; j < reg_cache->num_regs; j++, i++)\n\t\t\t\t(*reg_list)[i] =  &reg_cache->reg_list[j];\n\t\t\treg_cache = reg_cache->next;\n\t\t}\n\t\tassert(i == arc->num_regs);\n\t\tLOG_DEBUG(\"REG_CLASS_ALL: number of regs=%i\", *reg_list_size);\n\t} else {\n\t\tunsigned long i = 0;\n\t\tunsigned long gdb_reg_number = 0;\n\t\tstruct reg_cache *reg_cache = target->reg_cache;\n\t\twhile (reg_cache) {\n\t\t\tfor (unsigned j = 0;\n\t\t\t\t j < reg_cache->num_regs && gdb_reg_number <= arc->last_general_reg;\n\t\t\t\t j++) {\n\t\t\t\tif (reg_cache->reg_list[j].exist) {\n\t\t\t\t\t(*reg_list)[i] =  &reg_cache->reg_list[j];\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\tgdb_reg_number += 1;\n\t\t\t}\n\t\t\treg_cache = reg_cache->next;\n\t\t}\n\t\t*reg_list_size = i;\n\t\tLOG_DEBUG(\"REG_CLASS_GENERAL: number of regs=%i\", *reg_list_size);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Reading field of struct_type register */\nint arc_reg_get_field(struct target *target, const char *reg_name,\n\t\tconst char *field_name, uint32_t *value_ptr)\n{\n\tstruct reg_data_type_struct_field *field;\n\n\tLOG_DEBUG(\"getting register field (reg_name=%s, field_name=%s)\", reg_name, field_name);\n\n\t/* Get register */\n\tstruct reg *reg = arc_reg_get_by_name(target->reg_cache, reg_name, true);\n\n\tif (!reg) {\n\t\tLOG_ERROR(\"Requested register `%s' doesn't exist.\", reg_name);\n\t\treturn ERROR_ARC_REGISTER_NOT_FOUND;\n\t}\n\n\tif (reg->reg_data_type->type != REG_TYPE_ARCH_DEFINED\n\t    || reg->reg_data_type->type_class != REG_TYPE_CLASS_STRUCT)\n\t\treturn ERROR_ARC_REGISTER_IS_NOT_STRUCT;\n\n\t/* Get field in a register */\n\tstruct reg_data_type_struct *reg_struct =\n\t\treg->reg_data_type->reg_type_struct;\n\tfor (field = reg_struct->fields;\n\t     field;\n\t     field = field->next) {\n\t\tif (!strcmp(field->name, field_name))\n\t\t\tbreak;\n\t}\n\n\tif (!field)\n\t\treturn ERROR_ARC_REGISTER_FIELD_NOT_FOUND;\n\n\tif (!field->use_bitfields)\n\t\treturn ERROR_ARC_FIELD_IS_NOT_BITFIELD;\n\n\tif (!reg->valid)\n\t\tCHECK_RETVAL(reg->type->get(reg));\n\n\t/* First do endianness-safe read of register value\n\t * then convert it to binary buffer for further\n\t * field extraction */\n\n\t*value_ptr = buf_get_u32(reg->value, field->bitfield->start,\n\t\tfield->bitfield->end - field->bitfield->start + 1);\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_get_register_value(struct target *target, const char *reg_name,\n\t\tuint32_t *value_ptr)\n{\n\tLOG_DEBUG(\"reg_name=%s\", reg_name);\n\n\tstruct reg *reg = arc_reg_get_by_name(target->reg_cache, reg_name, true);\n\n\tif (!reg)\n\t\treturn ERROR_ARC_REGISTER_NOT_FOUND;\n\n\tif (!reg->valid)\n\t\tCHECK_RETVAL(reg->type->get(reg));\n\n\t*value_ptr = target_buffer_get_u32(target, reg->value);\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_set_register_value(struct target *target, const char *reg_name,\n\t\tuint32_t value)\n{\n\tLOG_DEBUG(\"reg_name=%s value=0x%08\" PRIx32, reg_name, value);\n\n\tif (!(target && reg_name)) {\n\t\tLOG_ERROR(\"Arguments cannot be NULL.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct reg *reg = arc_reg_get_by_name(target->reg_cache, reg_name, true);\n\n\tif (!reg)\n\t\treturn ERROR_ARC_REGISTER_NOT_FOUND;\n\n\tuint8_t value_buf[4];\n\tbuf_set_u32(value_buf, 0, 32, value);\n\tCHECK_RETVAL(reg->type->set(reg, value_buf));\n\n\treturn ERROR_OK;\n}\n\n/* Configure DCCM's */\nstatic int arc_configure_dccm(struct target  *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tuint32_t dccm_build_version, dccm_build_size0, dccm_build_size1;\n\tCHECK_RETVAL(arc_reg_get_field(target, \"dccm_build\", \"version\",\n\t\t&dccm_build_version));\n\tCHECK_RETVAL(arc_reg_get_field(target, \"dccm_build\", \"size0\",\n\t\t&dccm_build_size0));\n\tCHECK_RETVAL(arc_reg_get_field(target, \"dccm_build\", \"size1\",\n\t\t&dccm_build_size1));\n\t/* There is no yet support of configurable number of cycles,\n\t * So there is no difference between v3 and v4 */\n\tif ((dccm_build_version == 3 || dccm_build_version == 4) && dccm_build_size0 > 0) {\n\t\tCHECK_RETVAL(arc_get_register_value(target, \"aux_dccm\", &(arc->dccm_start)));\n\t\tuint32_t dccm_size = 0x100;\n\t\tdccm_size <<= dccm_build_size0;\n\t\tif (dccm_build_size0 == 0xF)\n\t\t\tdccm_size <<= dccm_build_size1;\n\t\tarc->dccm_end = arc->dccm_start + dccm_size;\n\t\tLOG_DEBUG(\"DCCM detected start=0x%\" PRIx32 \" end=0x%\" PRIx32,\n\t\t\t\tarc->dccm_start, arc->dccm_end);\n\n\t}\n\treturn ERROR_OK;\n}\n\n\n/* Configure ICCM's */\n\nstatic int arc_configure_iccm(struct target  *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* ICCM0 */\n\tuint32_t iccm_build_version, iccm_build_size00, iccm_build_size01;\n\tuint32_t aux_iccm = 0;\n\tCHECK_RETVAL(arc_reg_get_field(target, \"iccm_build\", \"version\",\n\t\t&iccm_build_version));\n\tCHECK_RETVAL(arc_reg_get_field(target, \"iccm_build\", \"iccm0_size0\",\n\t\t&iccm_build_size00));\n\tCHECK_RETVAL(arc_reg_get_field(target, \"iccm_build\", \"iccm0_size1\",\n\t\t&iccm_build_size01));\n\tif (iccm_build_version == 4 && iccm_build_size00 > 0) {\n\t\tCHECK_RETVAL(arc_get_register_value(target, \"aux_iccm\", &aux_iccm));\n\t\tuint32_t iccm0_size = 0x100;\n\t\ticcm0_size <<= iccm_build_size00;\n\t\tif (iccm_build_size00 == 0xF)\n\t\t\ticcm0_size <<= iccm_build_size01;\n\t\t/* iccm0 start is located in highest 4 bits of aux_iccm */\n\t\tarc->iccm0_start = aux_iccm & 0xF0000000;\n\t\tarc->iccm0_end = arc->iccm0_start + iccm0_size;\n\t\tLOG_DEBUG(\"ICCM0 detected start=0x%\" PRIx32 \" end=0x%\" PRIx32,\n\t\t\t\tarc->iccm0_start, arc->iccm0_end);\n\t}\n\n\t/* ICCM1 */\n\tuint32_t iccm_build_size10, iccm_build_size11;\n\tCHECK_RETVAL(arc_reg_get_field(target, \"iccm_build\", \"iccm1_size0\",\n\t\t&iccm_build_size10));\n\tCHECK_RETVAL(arc_reg_get_field(target, \"iccm_build\", \"iccm1_size1\",\n\t\t&iccm_build_size11));\n\tif (iccm_build_version == 4 && iccm_build_size10 > 0) {\n\t\t/* Use value read for ICCM0 */\n\t\tif (!aux_iccm)\n\t\t\tCHECK_RETVAL(arc_get_register_value(target, \"aux_iccm\", &aux_iccm));\n\t\tuint32_t iccm1_size = 0x100;\n\t\ticcm1_size <<= iccm_build_size10;\n\t\tif (iccm_build_size10 == 0xF)\n\t\t\ticcm1_size <<= iccm_build_size11;\n\t\tarc->iccm1_start = aux_iccm & 0x0F000000;\n\t\tarc->iccm1_end = arc->iccm1_start + iccm1_size;\n\t\tLOG_DEBUG(\"ICCM1 detected start=0x%\" PRIx32 \" end=0x%\" PRIx32,\n\t\t\t\tarc->iccm1_start, arc->iccm1_end);\n\t}\n\treturn ERROR_OK;\n}\n\n/* Configure some core features, depending on BCRs. */\nstatic int arc_configure(struct target *target)\n{\n\tLOG_DEBUG(\"Configuring ARC ICCM and DCCM\");\n\n\t/* Configuring DCCM if DCCM_BUILD and AUX_DCCM are known registers. */\n\tif (arc_reg_get_by_name(target->reg_cache, \"dccm_build\", true) &&\n\t    arc_reg_get_by_name(target->reg_cache, \"aux_dccm\", true))\n\t\t\t\tCHECK_RETVAL(arc_configure_dccm(target));\n\n\t/* Configuring ICCM if ICCM_BUILD and AUX_ICCM are known registers. */\n\tif (arc_reg_get_by_name(target->reg_cache, \"iccm_build\", true) &&\n\t    arc_reg_get_by_name(target->reg_cache, \"aux_iccm\", true))\n\t\t\t\tCHECK_RETVAL(arc_configure_iccm(target));\n\n\treturn ERROR_OK;\n}\n\n/* arc_examine is function, which is used for all arc targets*/\nstatic int arc_examine(struct target *target)\n{\n\tuint32_t status;\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tCHECK_RETVAL(arc_jtag_startup(&arc->jtag_info));\n\n\tif (!target_was_examined(target)) {\n\t\tCHECK_RETVAL(arc_jtag_status(&arc->jtag_info, &status));\n\t\tif (status & ARC_JTAG_STAT_RU)\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\telse\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t/* Read BCRs and configure optional registers. */\n\t\tCHECK_RETVAL(arc_configure(target));\n\n\t\ttarget_set_examined(target);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_halt(struct target *target)\n{\n\tuint32_t value, irq_state;\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {\n\t\t\tLOG_ERROR(\"can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t}\n\t}\n\n\t/* Break (stop) processor.\n\t * Do read-modify-write sequence, or DEBUG.UB will be reset unintentionally.\n\t * We do not use here arc_get/set_core_reg functions here because they imply\n\t * that the processor is already halted. */\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, &value));\n\tvalue |= SET_CORE_FORCE_HALT; /* set the HALT bit */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG, value));\n\talive_sleep(1);\n\n\t/* Save current IRQ state */\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &irq_state));\n\n\tif (irq_state & AUX_STATUS32_REG_IE_BIT)\n\t\tarc->irq_state = 1;\n\telse\n\t\tarc->irq_state = 0;\n\n\t/* update state and notify gdb*/\n\ttarget->state = TARGET_HALTED;\n\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));\n\n\t/* some more debug information */\n\tif (debug_level >= LOG_LVL_DEBUG) {\n\t\tLOG_DEBUG(\"core stopped (halted) DEGUB-REG: 0x%08\" PRIx32, value);\n\t\tCHECK_RETVAL(arc_get_register_value(target, \"status32\", &value));\n\t\tLOG_DEBUG(\"core STATUS32: 0x%08\" PRIx32, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Read registers that are used in GDB g-packet. We don't read them one-by-one,\n * but do that in one batch operation to improve speed. Calls to JTAG layer are\n * expensive so it is better to make one big call that reads all necessary\n * registers, instead of many calls, one for one register.\n */\nstatic int arc_save_context(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tunsigned int i;\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct reg *reg_list = arc->core_and_aux_cache->reg_list;\n\n\tLOG_DEBUG(\"Saving aux and core registers values\");\n\tassert(reg_list);\n\n\t/* It is assumed that there is at least one AUX register in the list, for\n\t * example PC. */\n\tconst uint32_t core_regs_size = arc->num_core_regs * sizeof(uint32_t);\n\t/* last_general_reg is inclusive number. To get count of registers it is\n\t * required to do +1. */\n\tconst uint32_t regs_to_scan =\n\t\tMIN(arc->last_general_reg + 1, arc->num_regs);\n\tconst uint32_t aux_regs_size = arc->num_aux_regs * sizeof(uint32_t);\n\tuint32_t *core_values = malloc(core_regs_size);\n\tuint32_t *aux_values = malloc(aux_regs_size);\n\tuint32_t *core_addrs = malloc(core_regs_size);\n\tuint32_t *aux_addrs = malloc(aux_regs_size);\n\tunsigned int core_cnt = 0;\n\tunsigned int aux_cnt = 0;\n\n\tif (!core_values || !core_addrs || !aux_values || !aux_addrs)  {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto exit;\n\t}\n\n\tmemset(core_values, 0xff, core_regs_size);\n\tmemset(core_addrs, 0xff, core_regs_size);\n\tmemset(aux_values, 0xff, aux_regs_size);\n\tmemset(aux_addrs, 0xff, aux_regs_size);\n\n\tfor (i = 0; i < MIN(arc->num_core_regs, regs_to_scan); i++) {\n\t\tstruct reg *reg = &(reg_list[i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (!reg->valid && reg->exist) {\n\t\t\tcore_addrs[core_cnt] = arc_reg->arch_num;\n\t\t\tcore_cnt += 1;\n\t\t}\n\t}\n\n\tfor (i = arc->num_core_regs; i < regs_to_scan; i++) {\n\t\tstruct reg *reg = &(reg_list[i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (!reg->valid && reg->exist) {\n\t\t\taux_addrs[aux_cnt] = arc_reg->arch_num;\n\t\t\taux_cnt += 1;\n\t\t}\n\t}\n\n\t/* Read data from target. */\n\tif (core_cnt > 0) {\n\t\tretval = arc_jtag_read_core_reg(&arc->jtag_info, core_addrs, core_cnt, core_values);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Attempt to read core registers failed.\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\tif (aux_cnt > 0) {\n\t\tretval = arc_jtag_read_aux_reg(&arc->jtag_info, aux_addrs, aux_cnt, aux_values);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Attempt to read aux registers failed.\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\n\t/* Parse core regs */\n\tcore_cnt = 0;\n\tfor (i = 0; i < MIN(arc->num_core_regs, regs_to_scan); i++) {\n\t\tstruct reg *reg = &(reg_list[i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (!reg->valid && reg->exist) {\n\t\t\ttarget_buffer_set_u32(target, reg->value, core_values[core_cnt]);\n\t\t\tcore_cnt += 1;\n\t\t\treg->valid = true;\n\t\t\treg->dirty = false;\n\t\t\tLOG_DEBUG(\"Get core register regnum=%u, name=%s, value=0x%08\" PRIx32,\n\t\t\t\ti, arc_reg->name, core_values[core_cnt]);\n\t\t}\n\t}\n\n\t/* Parse aux regs */\n\taux_cnt = 0;\n\tfor (i = arc->num_core_regs; i < regs_to_scan; i++) {\n\t\tstruct reg *reg = &(reg_list[i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (!reg->valid && reg->exist) {\n\t\t\ttarget_buffer_set_u32(target, reg->value, aux_values[aux_cnt]);\n\t\t\taux_cnt += 1;\n\t\t\treg->valid = true;\n\t\t\treg->dirty = false;\n\t\t\tLOG_DEBUG(\"Get aux register regnum=%u, name=%s, value=0x%08\" PRIx32,\n\t\t\t\ti, arc_reg->name, aux_values[aux_cnt]);\n\t\t}\n\t}\n\nexit:\n\tfree(core_values);\n\tfree(core_addrs);\n\tfree(aux_values);\n\tfree(aux_addrs);\n\n\treturn retval;\n}\n\n/**\n * Finds an actionpoint that triggered last actionpoint event, as specified by\n * DEBUG.ASR.\n *\n * @param target\n * @param actionpoint Pointer to be set to last active actionpoint. Pointer\n *                    will be set to NULL if DEBUG.AH is 0.\n */\nstatic int get_current_actionpoint(struct target *target,\n\t\tstruct arc_actionpoint **actionpoint)\n{\n\tassert(target);\n\tassert(actionpoint);\n\n\tuint32_t debug_ah;\n\t/* Check if actionpoint caused halt */\n\tCHECK_RETVAL(arc_reg_get_field(target, \"debug\", \"ah\",\n\t\t\t\t&debug_ah));\n\n\tif (debug_ah) {\n\t\tstruct arc_common *arc = target_to_arc(target);\n\t\tunsigned int ap;\n\t\tuint32_t debug_asr;\n\t\tCHECK_RETVAL(arc_reg_get_field(target, \"debug\",\n\t\t\t\t\t\"asr\", &debug_asr));\n\n\t\tfor (ap = 0; debug_asr > 1; debug_asr >>= 1)\n\t\t\tap += 1;\n\n\t\tassert(ap < arc->actionpoints_num);\n\n\t\t*actionpoint = &(arc->actionpoints_list[ap]);\n\t} else {\n\t\t*actionpoint = NULL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_examine_debug_reason(struct target *target)\n{\n\tuint32_t debug_bh;\n\n\t/* Only check for reason if don't know it already. */\n\t/* BTW After singlestep at this point core is not marked as halted, so\n\t * reading from memory to get current instruction wouldn't work anyway.  */\n\tif (target->debug_reason == DBG_REASON_DBGRQ ||\n\t    target->debug_reason == DBG_REASON_SINGLESTEP) {\n\t\treturn ERROR_OK;\n\t}\n\n\tCHECK_RETVAL(arc_reg_get_field(target, \"debug\", \"bh\",\n\t\t\t\t&debug_bh));\n\n\tif (debug_bh) {\n\t\t/* DEBUG.BH is set if core halted due to BRK instruction.  */\n\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t} else {\n\t\tstruct arc_actionpoint *actionpoint = NULL;\n\t\tCHECK_RETVAL(get_current_actionpoint(target, &actionpoint));\n\n\t\tif (actionpoint) {\n\t\t\tif (!actionpoint->used)\n\t\t\t\tLOG_WARNING(\"Target halted by an unused actionpoint.\");\n\n\t\t\tif (actionpoint->type == ARC_AP_BREAKPOINT)\n\t\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\telse if (actionpoint->type == ARC_AP_WATCHPOINT)\n\t\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\telse\n\t\t\t\tLOG_WARNING(\"Unknown type of actionpoint.\");\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_debug_entry(struct target *target)\n{\n\tCHECK_RETVAL(arc_save_context(target));\n\n\t/* TODO: reset internal indicators of caches states, otherwise D$/I$\n\t * will not be flushed/invalidated when required. */\n\tCHECK_RETVAL(arc_reset_caches_states(target));\n\tCHECK_RETVAL(arc_examine_debug_reason(target));\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_poll(struct target *target)\n{\n\tuint32_t status, value;\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* gdb calls continuously through this arc_poll() function  */\n\tCHECK_RETVAL(arc_jtag_status(&arc->jtag_info, &status));\n\n\t/* check for processor halted */\n\tif (status & ARC_JTAG_STAT_RU) {\n\t\tif (target->state != TARGET_RUNNING) {\n\t\t\tLOG_WARNING(\"target is still running!\");\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\t/* In some cases JTAG status register indicates that\n\t *  processor is in halt mode, but processor is still running.\n\t *  We check halt bit of AUX STATUS32 register for setting correct state. */\n\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {\n\t\tCHECK_RETVAL(arc_get_register_value(target, \"status32\", &value));\n\t\tif (value & AUX_STATUS32_REG_HALT_BIT) {\n\t\t\tLOG_DEBUG(\"ARC core in halt or reset state.\");\n\t\t\t/* Save context if target was not in reset state */\n\t\t\tif (target->state == TARGET_RUNNING)\n\t\t\t\tCHECK_RETVAL(arc_debug_entry(target));\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));\n\t\t} else {\n\t\tLOG_DEBUG(\"Discrepancy of STATUS32[0] HALT bit and ARC_JTAG_STAT_RU, \"\n\t\t\t\t\t\t\"target is still running\");\n\t\t}\n\n\t} else if (target->state == TARGET_DEBUG_RUNNING) {\n\n\t\ttarget->state = TARGET_HALTED;\n\t\tLOG_DEBUG(\"ARC core is in debug running mode\");\n\n\t\tCHECK_RETVAL(arc_debug_entry(target));\n\n\t\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED));\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_assert_reset(struct target *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tbool srst_asserted = false;\n\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {\n\t\t/* allow scripts to override the reset event */\n\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\t\tregister_cache_invalidate(arc->core_and_aux_cache);\n\t\t /* An ARC target might be in halt state after reset, so\n\t\t * if script requested processor to resume, then it must\n\t\t * be manually started to ensure that this request\n\t\t * is satisfied. */\n\t\tif (target->state == TARGET_HALTED && !target->reset_halt) {\n\t\t\t/* Resume the target and continue from the current\n\t\t\t * PC register value. */\n\t\t\tLOG_DEBUG(\"Starting CPU execution after reset\");\n\t\t\tCHECK_RETVAL(target_resume(target, 1, 0, 0, 0));\n\t\t}\n\t\ttarget->state = TARGET_RESET;\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* some cores support connecting while srst is asserted\n\t * use that mode if it has been configured */\n\tif (!(jtag_reset_config & RESET_SRST_PULLS_TRST) &&\n\t\t\t(jtag_reset_config & RESET_SRST_NO_GATING)) {\n\t\tjtag_add_reset(0, 1);\n\t\tsrst_asserted = true;\n\t}\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\t/* should issue a srst only, but we may have to assert trst as well */\n\t\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\tjtag_add_reset(1, 1);\n\t\telse if (!srst_asserted)\n\t\t\tjtag_add_reset(0, 1);\n\t}\n\n\ttarget->state = TARGET_RESET;\n\tjtag_add_sleep(50000);\n\n\tregister_cache_invalidate(arc->core_and_aux_cache);\n\n\tif (target->reset_halt)\n\t\tCHECK_RETVAL(target_halt(target));\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_deassert_reset(struct target *target)\n{\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\t/* deassert reset lines */\n\tjtag_add_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_arch_state(struct target *target)\n{\n\tuint32_t pc_value;\n\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn ERROR_OK;\n\n\tCHECK_RETVAL(arc_get_register_value(target, \"pc\", &pc_value));\n\n\tLOG_DEBUG(\"target state: %s;  PC at: 0x%08\" PRIx32,\n\t\ttarget_state_name(target),\n\t\tpc_value);\n\n\treturn ERROR_OK;\n}\n\n/**\n * See arc_save_context() for reason why we want to dump all regs at once.\n * This however means that if there are dependencies between registers they\n * will not be observable until target will be resumed.\n */\nstatic int arc_restore_context(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tunsigned int i;\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct reg *reg_list = arc->core_and_aux_cache->reg_list;\n\n\tLOG_DEBUG(\"Restoring registers values\");\n\tassert(reg_list);\n\n\tconst uint32_t core_regs_size = arc->num_core_regs  * sizeof(uint32_t);\n\tconst uint32_t aux_regs_size =  arc->num_aux_regs * sizeof(uint32_t);\n\tuint32_t *core_values = malloc(core_regs_size);\n\tuint32_t *aux_values = malloc(aux_regs_size);\n\tuint32_t *core_addrs = malloc(core_regs_size);\n\tuint32_t *aux_addrs = malloc(aux_regs_size);\n\tunsigned int core_cnt = 0;\n\tunsigned int aux_cnt = 0;\n\n\tif (!core_values || !core_addrs || !aux_values || !aux_addrs)  {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto exit;\n\t}\n\n\tmemset(core_values, 0xff, core_regs_size);\n\tmemset(core_addrs, 0xff, core_regs_size);\n\tmemset(aux_values, 0xff, aux_regs_size);\n\tmemset(aux_addrs, 0xff, aux_regs_size);\n\n\tfor (i = 0; i < arc->num_core_regs; i++) {\n\t\tstruct reg *reg = &(reg_list[i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (reg->valid && reg->exist && reg->dirty) {\n\t\t\tLOG_DEBUG(\"Will write regnum=%u\", i);\n\t\t\tcore_addrs[core_cnt] = arc_reg->arch_num;\n\t\t\tcore_values[core_cnt] = target_buffer_get_u32(target, reg->value);\n\t\t\tcore_cnt += 1;\n\t\t}\n\t}\n\n\tfor (i = 0; i < arc->num_aux_regs; i++) {\n\t\tstruct reg *reg = &(reg_list[arc->num_core_regs + i]);\n\t\tstruct arc_reg_desc *arc_reg = reg->arch_info;\n\t\tif (reg->valid && reg->exist && reg->dirty) {\n\t\t\tLOG_DEBUG(\"Will write regnum=%lu\", arc->num_core_regs + i);\n\t\t\taux_addrs[aux_cnt] = arc_reg->arch_num;\n\t\t\taux_values[aux_cnt] = target_buffer_get_u32(target, reg->value);\n\t\t\taux_cnt += 1;\n\t\t}\n\t}\n\n\t/* Write data to target.\n\t * Check before write, if aux and core count is greater than 0. */\n\tif (core_cnt > 0) {\n\t\tretval = arc_jtag_write_core_reg(&arc->jtag_info, core_addrs, core_cnt, core_values);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Attempt to write to core registers failed.\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\n\tif (aux_cnt > 0) {\n\t\tretval = arc_jtag_write_aux_reg(&arc->jtag_info, aux_addrs, aux_cnt, aux_values);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Attempt to write to aux registers failed.\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t}\n\nexit:\n\tfree(core_values);\n\tfree(core_addrs);\n\tfree(aux_values);\n\tfree(aux_addrs);\n\n\treturn retval;\n}\n\nstatic int arc_enable_interrupts(struct target *target, int enable)\n{\n\tuint32_t value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value));\n\n\tif (enable) {\n\t\t/* enable interrupts */\n\t\tvalue |= SET_CORE_ENABLE_INTERRUPTS;\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value));\n\t\tLOG_DEBUG(\"interrupts enabled\");\n\t} else {\n\t\t/* disable interrupts */\n\t\tvalue &= ~SET_CORE_ENABLE_INTERRUPTS;\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value));\n\t\tLOG_DEBUG(\"interrupts disabled\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_resume(struct target *target, int current, target_addr_t address,\n\tint handle_breakpoints, int debug_execution)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\tuint32_t resume_pc = 0;\n\tuint32_t value;\n\tstruct reg *pc = &arc->core_and_aux_cache->reg_list[arc->pc_index_in_cache];\n\n\tLOG_DEBUG(\"current:%i, address:0x%08\" TARGET_PRIxADDR \", handle_breakpoints(not supported yet):%i,\"\n\t\t\" debug_execution:%i\", current, address, handle_breakpoints, debug_execution);\n\n\t/* We need to reset ARC cache variables so caches\n\t * would be invalidated and actual data\n\t * would be fetched from memory. */\n\tCHECK_RETVAL(arc_reset_caches_states(target));\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current PC, otherwise continue at <address> */\n\tif (!current) {\n\t\ttarget_buffer_set_u32(target, pc->value, address);\n\t\tpc->dirty = 1;\n\t\tpc->valid = 1;\n\t\tLOG_DEBUG(\"Changing the value of current PC to 0x%08\" TARGET_PRIxADDR, address);\n\t}\n\n\tif (!current)\n\t\tresume_pc = address;\n\telse\n\t\tresume_pc = target_buffer_get_u32(target, pc->value);\n\n\tCHECK_RETVAL(arc_restore_context(target));\n\n\tLOG_DEBUG(\"Target resumes from PC=0x%\" PRIx32 \", pc.dirty=%i, pc.valid=%i\",\n\t\tresume_pc, pc->dirty, pc->valid);\n\n\t/* check if GDB tells to set our PC where to continue from */\n\tif ((pc->valid == 1) && (resume_pc == target_buffer_get_u32(target, pc->value))) {\n\t\tvalue = target_buffer_get_u32(target, pc->value);\n\t\tLOG_DEBUG(\"resume Core (when start-core) with PC @:0x%08\" PRIx32, value);\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_PC_REG, value));\n\t}\n\n\t/* Restore IRQ state if not in debug_execution*/\n\tif (!debug_execution)\n\t\tCHECK_RETVAL(arc_enable_interrupts(target, arc->irq_state));\n\telse\n\t\tCHECK_RETVAL(arc_enable_interrupts(target, !debug_execution));\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* ready to get us going again */\n\ttarget->state = TARGET_RUNNING;\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, &value));\n\tvalue &= ~SET_CORE_HALT_BIT;        /* clear the HALT bit */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG, value));\n\tLOG_DEBUG(\"Core started to run\");\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arc->core_and_aux_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));\n\t\tLOG_DEBUG(\"target resumed at 0x%08\" PRIx32, resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED));\n\t\tLOG_DEBUG(\"target debug resumed at 0x%08\" PRIx32, resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tCHECK_RETVAL(arc_build_reg_cache(target));\n\tCHECK_RETVAL(arc_build_bcr_reg_cache(target));\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\treturn ERROR_OK;\n}\n\nstatic void arc_free_reg_cache(struct reg_cache *cache)\n{\n\tfree(cache->reg_list);\n\tfree(cache);\n}\n\nstatic void arc_deinit_target(struct target *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tLOG_DEBUG(\"deinitialization of target\");\n\tif (arc->core_aux_cache_built)\n\t\tarc_free_reg_cache(arc->core_and_aux_cache);\n\tif (arc->bcr_cache_built)\n\t\tarc_free_reg_cache(arc->bcr_cache);\n\n\tstruct arc_reg_data_type *type, *n;\n\tstruct arc_reg_desc *desc, *k;\n\n\t/* Free arc-specific reg_data_types allocations*/\n\tlist_for_each_entry_safe_reverse(type, n, &arc->reg_data_types, list) {\n\t\tif (type->data_type.type_class == REG_TYPE_CLASS_STRUCT) {\n\t\t\tfree(type->reg_type_struct_field);\n\t\t\tfree(type->bitfields);\n\t\t\tfree(type);\n\t\t}\telse if (type->data_type.type_class == REG_TYPE_CLASS_FLAGS) {\n\t\t\tfree(type->reg_type_flags_field);\n\t\t\tfree(type->bitfields);\n\t\t\tfree(type);\n\t\t}\n\t}\n\n\t/* Free standard_gdb_types reg_data_types allocations */\n\ttype = list_first_entry(&arc->reg_data_types, struct arc_reg_data_type, list);\n\tfree(type);\n\n\tlist_for_each_entry_safe(desc, k, &arc->aux_reg_descriptions, list)\n\t\tfree_reg_desc(desc);\n\n\tlist_for_each_entry_safe(desc, k, &arc->core_reg_descriptions, list)\n\t\tfree_reg_desc(desc);\n\n\tlist_for_each_entry_safe(desc, k, &arc->bcr_reg_descriptions, list)\n\t\tfree_reg_desc(desc);\n\n\tfree(arc->actionpoints_list);\n\tfree(arc);\n}\n\n\nstatic int arc_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arc_common *arc = calloc(1, sizeof(*arc));\n\n\tif (!arc) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Entering\");\n\tCHECK_RETVAL(arc_init_arch_info(target, arc, target->tap));\n\n\treturn ERROR_OK;\n}\n\n/**\n * Write 4-byte instruction to memory. This is like target_write_u32, however\n * in case of little endian ARC instructions are in middle endian format, not\n * little endian, so different type of conversion should be done.\n * Middle endian: instruction \"aabbccdd\", stored as \"bbaaddcc\"\n */\nstatic int arc_write_instruction_u32(struct target *target, uint32_t address,\n\tuint32_t instr)\n{\n\tuint8_t value_buf[4];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"Address: 0x%08\" PRIx32 \", value: 0x%08\" PRIx32, address,\n\t\tinstr);\n\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\tarc_h_u32_to_me(value_buf, instr);\n\telse\n\t\th_u32_to_be(value_buf, instr);\n\n\tCHECK_RETVAL(target_write_buffer(target, address, 4, value_buf));\n\n\treturn ERROR_OK;\n}\n\n/**\n * Read 32-bit instruction from memory. It is like target_read_u32, however in\n * case of little endian ARC instructions are in middle endian format, so\n * different type of conversion should be done.\n */\nstatic int arc_read_instruction_u32(struct target *target, uint32_t address,\n\t\tuint32_t *value)\n{\n\tuint8_t value_buf[4];\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*value = 0;\n\tCHECK_RETVAL(target_read_buffer(target, address, 4, value_buf));\n\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\t*value = arc_me_to_h_u32(value_buf);\n\telse\n\t\t*value = be_to_h_u32(value_buf);\n\n\tLOG_DEBUG(\"Address: 0x%08\" PRIx32 \", value: 0x%08\" PRIx32, address,\n\t\t*value);\n\n\treturn ERROR_OK;\n}\n\n/* Actionpoint mechanism allows to setup HW breakpoints\n * and watchpoints. Each actionpoint is controlled by\n * 3 aux registers: Actionpoint(AP) match mask(AP_AMM), AP match value(AP_AMV)\n * and AP control(AC).\n * This function is for setting/unsetting actionpoints:\n * at - actionpoint target: trigger on mem/reg access\n * tt - transaction type : trigger on r/w. */\nstatic int arc_configure_actionpoint(struct target *target, uint32_t ap_num,\n\tuint32_t match_value, uint32_t control_tt, uint32_t control_at)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tif (control_tt != AP_AC_TT_DISABLE) {\n\n\t\tif (arc->actionpoints_num_avail < 1) {\n\t\t\tLOG_ERROR(\"No free actionpoints, maximum amount is %u\",\n\t\t\t\t\tarc->actionpoints_num);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\t/* Names of register to set - 24 chars should be enough. Looks a little\n\t\t * bit out-of-place for C code, but makes it aligned to the bigger\n\t\t * concept of \"ARC registers are defined in TCL\" as far as possible.\n\t\t */\n\t\tchar ap_amv_reg_name[24], ap_amm_reg_name[24], ap_ac_reg_name[24];\n\t\tsnprintf(ap_amv_reg_name, 24, \"ap_amv%\" PRIu32, ap_num);\n\t\tsnprintf(ap_amm_reg_name, 24, \"ap_amm%\" PRIu32, ap_num);\n\t\tsnprintf(ap_ac_reg_name, 24, \"ap_ac%\" PRIu32, ap_num);\n\t\tCHECK_RETVAL(arc_set_register_value(target, ap_amv_reg_name,\n\t\t\t\t\t match_value));\n\t\tCHECK_RETVAL(arc_set_register_value(target, ap_amm_reg_name, 0));\n\t\tCHECK_RETVAL(arc_set_register_value(target, ap_ac_reg_name,\n\t\t\t\t\t control_tt | control_at));\n\t\tarc->actionpoints_num_avail--;\n\t} else {\n\t\tchar ap_ac_reg_name[24];\n\t\tsnprintf(ap_ac_reg_name, 24, \"ap_ac%\" PRIu32, ap_num);\n\t\tCHECK_RETVAL(arc_set_register_value(target, ap_ac_reg_name,\n\t\t\t\t\t AP_AC_TT_DISABLE));\n\t\tarc->actionpoints_num_avail++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_set_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\n\t\tif (breakpoint->length == 4) {\n\t\t\tuint32_t verify = 0xffffffff;\n\n\t\t\tCHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length,\n\t\t\t\t\tbreakpoint->orig_instr));\n\n\t\t\tCHECK_RETVAL(arc_write_instruction_u32(target, breakpoint->address,\n\t\t\t\t\tARC_SDBBP_32));\n\n\t\t\tCHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, &verify));\n\n\t\t\tif (verify != ARC_SDBBP_32) {\n\t\t\t\tLOG_ERROR(\"Unable to set 32bit breakpoint at address @0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t} else if (breakpoint->length == 2) {\n\t\t\tuint16_t verify = 0xffff;\n\n\t\t\tCHECK_RETVAL(target_read_buffer(target, breakpoint->address, breakpoint->length,\n\t\t\t\t\tbreakpoint->orig_instr));\n\t\t\tCHECK_RETVAL(target_write_u16(target, breakpoint->address, ARC_SDBBP_16));\n\n\t\t\tCHECK_RETVAL(target_read_u16(target, breakpoint->address, &verify));\n\t\t\tif (verify != ARC_SDBBP_16) {\n\t\t\t\tLOG_ERROR(\"Unable to set 16bit breakpoint at address @0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"Invalid breakpoint length: target supports only 2 or 4\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\n\t\tbreakpoint->is_set = true;\n\t} else if (breakpoint->type == BKPT_HARD) {\n\t\tstruct arc_common *arc = target_to_arc(target);\n\t\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\t\tunsigned int bp_num;\n\n\t\tfor (bp_num = 0; bp_num < arc->actionpoints_num; bp_num++) {\n\t\t\tif (!ap_list[bp_num].used)\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif (bp_num >= arc->actionpoints_num) {\n\t\t\tLOG_ERROR(\"No free actionpoints, maximum amount is %u\",\n\t\t\t\t\tarc->actionpoints_num);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tint retval = arc_configure_actionpoint(target, bp_num,\n\t\t\t\tbreakpoint->address, AP_AC_TT_READWRITE, AP_AC_AT_INST_ADDR);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tbreakpoint_hw_set(breakpoint, bp_num);\n\t\t\tap_list[bp_num].used = 1;\n\t\t\tap_list[bp_num].bp_value = breakpoint->address;\n\t\t\tap_list[bp_num].type = ARC_AP_BREAKPOINT;\n\n\t\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \", bp_num %u bp_value 0x%\" PRIx32,\n\t\t\t\t\tbreakpoint->unique_id, bp_num, ap_list[bp_num].bp_value);\n\t\t}\n\n\t} else {\n\t\tLOG_DEBUG(\"ERROR: setting unknown breakpoint type\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* core instruction cache is now invalid. */\n\tCHECK_RETVAL(arc_cache_invalidate(target));\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tint retval = ERROR_OK;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\t\tif (breakpoint->length == 4) {\n\t\t\tuint32_t current_instr;\n\n\t\t\t/* check that user program has not modified breakpoint instruction */\n\t\t\tCHECK_RETVAL(arc_read_instruction_u32(target, breakpoint->address, &current_instr));\n\n\t\t\tif (current_instr == ARC_SDBBP_32) {\n\t\t\t\tretval = target_write_buffer(target, breakpoint->address,\n\t\t\t\t\tbreakpoint->length, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else {\n\t\t\t\tLOG_WARNING(\"Software breakpoint @0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" has been overwritten outside of debugger.\"\n\t\t\t\t\t\"Expected: @0x%x, got: @0x%\" PRIx32,\n\t\t\t\t\tbreakpoint->address, ARC_SDBBP_32, current_instr);\n\t\t\t}\n\t\t} else if (breakpoint->length == 2) {\n\t\t\tuint16_t current_instr;\n\n\t\t\t/* check that user program has not modified breakpoint instruction */\n\t\t\tCHECK_RETVAL(target_read_u16(target, breakpoint->address, &current_instr));\n\t\t\tif (current_instr == ARC_SDBBP_16) {\n\t\t\t\tretval = target_write_buffer(target, breakpoint->address,\n\t\t\t\t\tbreakpoint->length, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else {\n\t\t\t\tLOG_WARNING(\"Software breakpoint @0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" has been overwritten outside of debugger. \"\n\t\t\t\t\t\"Expected: 0x%04x, got: 0x%04\" PRIx16,\n\t\t\t\t\tbreakpoint->address, ARC_SDBBP_16, current_instr);\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"Invalid breakpoint length: target supports only 2 or 4\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tbreakpoint->is_set = false;\n\n\t}\telse if (breakpoint->type == BKPT_HARD) {\n\t\tstruct arc_common *arc = target_to_arc(target);\n\t\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\t\tunsigned int bp_num = breakpoint->number;\n\n\t\tif (bp_num >= arc->actionpoints_num) {\n\t\t\tLOG_DEBUG(\"Invalid actionpoint ID: %u in breakpoint: %\" PRIu32,\n\t\t\t\t\t  bp_num, breakpoint->unique_id);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tretval = arc_configure_actionpoint(target, bp_num,\n\t\t\t\t\t\tbreakpoint->address, AP_AC_TT_DISABLE, AP_AC_AT_INST_ADDR);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tbreakpoint->is_set = false;\n\t\t\tap_list[bp_num].used = 0;\n\t\t\tap_list[bp_num].bp_value = 0;\n\n\t\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \" - released actionpoint ID: %u\",\n\t\t\t\t\tbreakpoint->unique_id, bp_num);\n\t\t}\n\t} else {\n\t\t\tLOG_DEBUG(\"ERROR: unsetting unknown breakpoint type\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* core instruction cache is now invalid. */\n\tCHECK_RETVAL(arc_cache_invalidate(target));\n\n\treturn retval;\n}\n\n\nstatic int arc_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tif (target->state == TARGET_HALTED) {\n\t\treturn arc_set_breakpoint(target, breakpoint);\n\n\t} else {\n\t\tLOG_WARNING(\" > core was not halted, please try again.\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n}\n\nstatic int arc_remove_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tif (target->state == TARGET_HALTED) {\n\t\tif (breakpoint->is_set)\n\t\t\tCHECK_RETVAL(arc_unset_breakpoint(target, breakpoint));\n\t} else {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void arc_reset_actionpoints(struct target *target)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\tstruct breakpoint *next_b;\n\tstruct watchpoint *next_w;\n\n\twhile (target->breakpoints) {\n\t\tnext_b = target->breakpoints->next;\n\t\tarc_remove_breakpoint(target, target->breakpoints);\n\t\tfree(target->breakpoints->orig_instr);\n\t\tfree(target->breakpoints);\n\t\ttarget->breakpoints = next_b;\n\t}\n\twhile (target->watchpoints) {\n\t\tnext_w = target->watchpoints->next;\n\t\tarc_remove_watchpoint(target, target->watchpoints);\n\t\tfree(target->watchpoints);\n\t\ttarget->watchpoints = next_w;\n\t}\n\tfor (unsigned int i = 0; i < arc->actionpoints_num; i++) {\n\t\tif ((ap_list[i].used) && (ap_list[i].reg_address))\n\t\t\tarc_remove_auxreg_actionpoint(target, ap_list[i].reg_address);\n\t}\n}\n\nint arc_set_actionpoints_num(struct target *target, uint32_t ap_num)\n{\n\tLOG_DEBUG(\"target=%s actionpoints=%\" PRIu32, target_name(target), ap_num);\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* Make sure that there are no enabled actionpoints in target. */\n\tarc_reset_actionpoints(target);\n\n\t/* Assume that all points have been removed from target.  */\n\tfree(arc->actionpoints_list);\n\n\tarc->actionpoints_num_avail = ap_num;\n\tarc->actionpoints_num = ap_num;\n\t/* calloc can be safely called when ncount == 0.  */\n\tarc->actionpoints_list = calloc(ap_num, sizeof(struct arc_actionpoint));\n\n\tif (!arc->actionpoints_list) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\n\nint arc_add_auxreg_actionpoint(struct target *target,\n\tuint32_t auxreg_addr, uint32_t transaction)\n{\n\tunsigned int ap_num = 0;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\n\twhile (ap_list[ap_num].used)\n\t\tap_num++;\n\n\tif (ap_num >= arc->actionpoints_num) {\n\t\tLOG_ERROR(\"No actionpoint free, maximum amount is %u\",\n\t\t\t\tarc->actionpoints_num);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval =  arc_configure_actionpoint(target, ap_num,\n\t\t\tauxreg_addr, transaction, AP_AC_AT_AUXREG_ADDR);\n\n\tif (retval == ERROR_OK) {\n\t\tap_list[ap_num].used = 1;\n\t\tap_list[ap_num].reg_address = auxreg_addr;\n\t}\n\n\treturn retval;\n}\n\nint arc_remove_auxreg_actionpoint(struct target *target, uint32_t auxreg_addr)\n{\n\tint retval = ERROR_OK;\n\tbool ap_found = false;\n\tunsigned int ap_num = 0;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\n\twhile ((ap_list[ap_num].used) && (ap_num < arc->actionpoints_num)) {\n\t\tif (ap_list[ap_num].reg_address == auxreg_addr) {\n\t\t\tap_found = true;\n\t\t\tbreak;\n\t\t}\n\t\tap_num++;\n\t}\n\n\tif (ap_found) {\n\t\tretval =  arc_configure_actionpoint(target, ap_num,\n\t\t\t\tauxreg_addr, AP_AC_TT_DISABLE, AP_AC_AT_AUXREG_ADDR);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tap_list[ap_num].used = 0;\n\t\t\tap_list[ap_num].bp_value = 0;\n\t\t}\n\t} else {\n\t\tLOG_ERROR(\"Register actionpoint not found\");\n\t}\n\treturn retval;\n}\n\n\nstatic int arc_set_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tunsigned int wp_num;\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (wp_num = 0; wp_num < arc->actionpoints_num; wp_num++) {\n\t\tif (!ap_list[wp_num].used)\n\t\t\tbreak;\n\t}\n\n\tif (wp_num >= arc->actionpoints_num) {\n\t\tLOG_ERROR(\"No free actionpoints, maximum amount is %u\",\n\t\t\t\tarc->actionpoints_num);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (watchpoint->length != 4) {\n\t\tLOG_ERROR(\"Only watchpoints of length 4 are supported\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tint enable = AP_AC_TT_DISABLE;\n\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tenable = AP_AC_TT_READ;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tenable = AP_AC_TT_WRITE;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tenable = AP_AC_TT_READWRITE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: watchpoint->rw neither read, write nor access\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval =  arc_configure_actionpoint(target, wp_num,\n\t\t\t\t\twatchpoint->address, enable, AP_AC_AT_MEMORY_ADDR);\n\n\tif (retval == ERROR_OK) {\n\t\twatchpoint_set(watchpoint, wp_num);\n\t\tap_list[wp_num].used = 1;\n\t\tap_list[wp_num].bp_value = watchpoint->address;\n\t\tap_list[wp_num].type = ARC_AP_WATCHPOINT;\n\n\t\tLOG_DEBUG(\"wpid: %\" PRIu32 \", wp_num %u wp_value 0x%\" PRIx32,\n\t\t\t\twatchpoint->unique_id, wp_num, ap_list[wp_num].bp_value);\n\t}\n\n\treturn retval;\n}\n\nstatic int arc_unset_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct arc_actionpoint *ap_list = arc->actionpoints_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tunsigned int wp_num = watchpoint->number;\n\tif (wp_num >= arc->actionpoints_num) {\n\t\tLOG_DEBUG(\"Invalid actionpoint ID: %u in watchpoint: %\" PRIu32,\n\t\t\t\twp_num, watchpoint->unique_id);\n\t\treturn ERROR_OK;\n\t}\n\n\tint retval =  arc_configure_actionpoint(target, wp_num,\n\t\t\t\twatchpoint->address, AP_AC_TT_DISABLE, AP_AC_AT_MEMORY_ADDR);\n\n\tif (retval == ERROR_OK) {\n\t\twatchpoint->is_set = false;\n\t\tap_list[wp_num].used = 0;\n\t\tap_list[wp_num].bp_value = 0;\n\n\t\tLOG_DEBUG(\"wpid: %\" PRIu32 \" - releasing actionpoint ID: %u\",\n\t\t\t\twatchpoint->unique_id, wp_num);\n\t}\n\n\treturn retval;\n}\n\nstatic int arc_add_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tCHECK_RETVAL(arc_set_watchpoint(target, watchpoint));\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_remove_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\tCHECK_RETVAL(arc_unset_watchpoint(target, watchpoint));\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)\n{\n\tassert(target);\n\tassert(hit_watchpoint);\n\n\tstruct arc_actionpoint *actionpoint = NULL;\n\tCHECK_RETVAL(get_current_actionpoint(target, &actionpoint));\n\n\tif (actionpoint) {\n\t\tif (!actionpoint->used)\n\t\t\tLOG_WARNING(\"Target halted by unused actionpoint.\");\n\n\t\t/* If this check fails - that is some sort of an error in OpenOCD. */\n\t\tif (actionpoint->type != ARC_AP_WATCHPOINT)\n\t\t\tLOG_WARNING(\"Target halted by breakpoint, but is treated as a watchpoint.\");\n\n\t\tfor (struct watchpoint *watchpoint = target->watchpoints;\n\t\t\t\twatchpoint;\n\t\t\t\twatchpoint = watchpoint->next) {\n\t\t\tif (actionpoint->bp_value == watchpoint->address) {\n\t\t\t\t*hit_watchpoint = watchpoint;\n\t\t\t\tLOG_DEBUG(\"Hit watchpoint, wpid: %\" PRIu32 \", watchpoint num: %u\",\n\t\t\t\t\t\t\twatchpoint->unique_id, watchpoint->number);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\n/* Helper function which switches core to single_step mode by\n * doing aux r/w operations.  */\nstatic int arc_config_step(struct target *target, int enable_step)\n{\n\tuint32_t value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* enable core debug step mode */\n\tif (enable_step) {\n\t\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG,\n\t\t\t&value));\n\t\tvalue &= ~SET_CORE_AE_BIT; /* clear the AE bit */\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_STATUS32_REG,\n\t\t\tvalue));\n\t\tLOG_DEBUG(\" [status32:0x%08\" PRIx32 \"]\", value);\n\n\t\t/* Doing read-modify-write, because DEBUG might contain manually set\n\t\t * bits like UB or ED, which should be preserved.  */\n\t\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info,\n\t\t\t\t\tAUX_DEBUG_REG, &value));\n\t\tvalue |= SET_CORE_SINGLE_INSTR_STEP; /* set the IS bit */\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,\n\t\t\tvalue));\n\t\tLOG_DEBUG(\"core debug step mode enabled [debug-reg:0x%08\" PRIx32 \"]\", value);\n\n\t} else {\t/* disable core debug step mode */\n\t\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,\n\t\t\t&value));\n\t\tvalue &= ~SET_CORE_SINGLE_INSTR_STEP; /* clear the IS bit */\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DEBUG_REG,\n\t\t\tvalue));\n\t\tLOG_DEBUG(\"core debug step mode disabled\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arc_step(struct target *target, int current, target_addr_t address,\n\tint handle_breakpoints)\n{\n\t/* get pointers to arch-specific information */\n\tstruct arc_common *arc = target_to_arc(target);\n\tstruct breakpoint *breakpoint = NULL;\n\tstruct reg *pc = &(arc->core_and_aux_cache->reg_list[arc->pc_index_in_cache]);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tbuf_set_u32(pc->value, 0, 32, address);\n\t\tpc->dirty = 1;\n\t\tpc->valid = 1;\n\t}\n\n\tLOG_DEBUG(\"Target steps one instruction from PC=0x%\" PRIx32,\n\t\tbuf_get_u32(pc->value, 0, 32));\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target, buf_get_u32(pc->value, 0, 32));\n\t\tif (breakpoint)\n\t\t\tCHECK_RETVAL(arc_unset_breakpoint(target, breakpoint));\n\t}\n\n\t/* restore context */\n\tCHECK_RETVAL(arc_restore_context(target));\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));\n\n\t/* disable interrupts while stepping */\n\tCHECK_RETVAL(arc_enable_interrupts(target, 0));\n\n\t/* do a single step */\n\tCHECK_RETVAL(arc_config_step(target, 1));\n\n\t/* make sure we done our step */\n\talive_sleep(1);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arc->core_and_aux_cache);\n\n\tif (breakpoint)\n\t\tCHECK_RETVAL(arc_set_breakpoint(target, breakpoint));\n\n\tLOG_DEBUG(\"target stepped \");\n\n\ttarget->state = TARGET_HALTED;\n\n\t/* Saving context */\n\tCHECK_RETVAL(arc_debug_entry(target));\n\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));\n\n\treturn ERROR_OK;\n}\n\n\n/* This function invalidates icache. */\nstatic int arc_icache_invalidate(struct target *target)\n{\n\tuint32_t value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* Don't waste time if already done. */\n\tif (!arc->has_icache || arc->icache_invalidated)\n\t    return ERROR_OK;\n\n\tLOG_DEBUG(\"Invalidating I$.\");\n\n\tvalue = IC_IVIC_INVALIDATE;\t/* invalidate I$ */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_IC_IVIC_REG, value));\n\n\tarc->icache_invalidated = true;\n\n\treturn ERROR_OK;\n}\n\n/* This function invalidates dcache */\nstatic int arc_dcache_invalidate(struct target *target)\n{\n\tuint32_t value, dc_ctrl_value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tif (!arc->has_dcache || arc->dcache_invalidated)\n\t    return ERROR_OK;\n\n\tLOG_DEBUG(\"Invalidating D$.\");\n\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, &value));\n\tdc_ctrl_value = value;\n\tvalue &= ~DC_CTRL_IM;\n\n\t/* set DC_CTRL invalidate mode to invalidate-only (no flushing!!) */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, value));\n\tvalue = DC_IVDC_INVALIDATE;\t/* invalidate D$ */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_IVDC_REG, value));\n\n\t/* restore DC_CTRL invalidate mode */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, dc_ctrl_value));\n\n\tarc->dcache_invalidated = true;\n\n\treturn ERROR_OK;\n}\n\n/* This function invalidates l2 cache. */\nstatic int arc_l2cache_invalidate(struct target *target)\n{\n\tuint32_t value, slc_ctrl_value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tif (!arc->has_l2cache || arc->l2cache_invalidated)\n\t    return ERROR_OK;\n\n\tLOG_DEBUG(\"Invalidating L2$.\");\n\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_CTRL, &value));\n\tslc_ctrl_value = value;\n\tvalue &= ~L2_CTRL_IM;\n\n\t/* set L2_CTRL invalidate mode to invalidate-only (no flushing!!) */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_CTRL, value));\n\t/* invalidate L2$ */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_INV, L2_INV_IV));\n\n\t/* Wait until invalidate operation ends */\n\tdo {\n\t    LOG_DEBUG(\"Waiting for invalidation end.\");\n\t    CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_CTRL, &value));\n\t} while (value & L2_CTRL_BS);\n\n\t/* restore L2_CTRL invalidate mode */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_CTRL, slc_ctrl_value));\n\n\tarc->l2cache_invalidated = true;\n\n\treturn ERROR_OK;\n}\n\n\nint arc_cache_invalidate(struct target *target)\n{\n\tCHECK_RETVAL(arc_icache_invalidate(target));\n\tCHECK_RETVAL(arc_dcache_invalidate(target));\n\tCHECK_RETVAL(arc_l2cache_invalidate(target));\n\n\treturn ERROR_OK;\n}\n\n/* Flush data cache. This function is cheap to call and return quickly if D$\n * already has been flushed since target had been halted. JTAG debugger reads\n * values directly from memory, bypassing cache, so if there are unflushed\n * lines debugger will read invalid values, which will cause a lot of troubles.\n * */\nstatic int arc_dcache_flush(struct target *target)\n{\n\tuint32_t value, dc_ctrl_value;\n\tbool has_to_set_dc_ctrl_im;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* Don't waste time if already done. */\n\tif (!arc->has_dcache || arc->dcache_flushed)\n\t    return ERROR_OK;\n\n\tLOG_DEBUG(\"Flushing D$.\");\n\n\t/* Store current value of DC_CTRL */\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, &dc_ctrl_value));\n\n\t/* Set DC_CTRL invalidate mode to flush (if not already set) */\n\thas_to_set_dc_ctrl_im = (dc_ctrl_value & DC_CTRL_IM) == 0;\n\tif (has_to_set_dc_ctrl_im) {\n\t\tvalue = dc_ctrl_value | DC_CTRL_IM;\n\t\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, value));\n\t}\n\n\t/* Flush D$ */\n\tvalue = DC_IVDC_INVALIDATE;\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_IVDC_REG, value));\n\n\t/* Restore DC_CTRL invalidate mode (even of flush failed) */\n\tif (has_to_set_dc_ctrl_im)\n\t    CHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, AUX_DC_CTRL_REG, dc_ctrl_value));\n\n\tarc->dcache_flushed = true;\n\n\treturn ERROR_OK;\n}\n\n/* This function flushes l2cache. */\nstatic int arc_l2cache_flush(struct target *target)\n{\n\tuint32_t value;\n\n\tstruct arc_common *arc = target_to_arc(target);\n\n\t/* Don't waste time if already done. */\n\tif (!arc->has_l2cache || arc->l2cache_flushed)\n\t    return ERROR_OK;\n\n\tLOG_DEBUG(\"Flushing L2$.\");\n\n\t/* Flush L2 cache */\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_FLUSH, L2_FLUSH_FL));\n\n\t/* Wait until flush operation ends */\n\tdo {\n\t    LOG_DEBUG(\"Waiting for flushing end.\");\n\t    CHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, SLC_AUX_CACHE_CTRL, &value));\n\t} while (value & L2_CTRL_BS);\n\n\tarc->l2cache_flushed = true;\n\n\treturn ERROR_OK;\n}\n\nint arc_cache_flush(struct target *target)\n{\n\tCHECK_RETVAL(arc_dcache_flush(target));\n\tCHECK_RETVAL(arc_l2cache_flush(target));\n\n\treturn ERROR_OK;\n}\n\n/* ARC v2 target */\nstruct target_type arcv2_target = {\n\t.name = \"arcv2\",\n\n\t.poll =\tarc_poll,\n\n\t.arch_state = arc_arch_state,\n\n\t/* TODO That seems like something similar to metaware hostlink, so perhaps\n\t * we can exploit this in the future. */\n\t.target_request_data = NULL,\n\n\t.halt = arc_halt,\n\t.resume = arc_resume,\n\t.step = arc_step,\n\n\t.assert_reset = arc_assert_reset,\n\t.deassert_reset = arc_deassert_reset,\n\n\t/* TODO Implement soft_reset_halt */\n\t.soft_reset_halt = NULL,\n\n\t.get_gdb_reg_list = arc_get_gdb_reg_list,\n\n\t.read_memory = arc_mem_read,\n\t.write_memory = arc_mem_write,\n\t.checksum_memory = NULL,\n\t.blank_check_memory = NULL,\n\n\t.add_breakpoint = arc_add_breakpoint,\n\t.add_context_breakpoint = NULL,\n\t.add_hybrid_breakpoint = NULL,\n\t.remove_breakpoint = arc_remove_breakpoint,\n\t.add_watchpoint = arc_add_watchpoint,\n\t.remove_watchpoint = arc_remove_watchpoint,\n\t.hit_watchpoint = arc_hit_watchpoint,\n\n\t.run_algorithm = NULL,\n\t.start_algorithm = NULL,\n\t.wait_algorithm = NULL,\n\n\t.commands = arc_monitor_command_handlers,\n\n\t.target_create = arc_target_create,\n\t.init_target = arc_init_target,\n\t.deinit_target = arc_deinit_target,\n\t.examine = arc_examine,\n\n\t.virt2phys = NULL,\n\t.read_phys_memory = NULL,\n\t.write_phys_memory = NULL,\n\t.mmu = NULL,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013-2015,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARC_H\n#define OPENOCD_TARGET_ARC_H\n\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n\n#include \"algorithm.h\"\n#include \"breakpoints.h\"\n#include \"jtag/interface.h\"\n#include \"register.h\"\n#include \"target.h\"\n#include \"target_request.h\"\n#include \"target_type.h\"\n#include \"helper/bits.h\"\n\n#include \"arc_jtag.h\"\n#include \"arc_cmd.h\"\n#include \"arc_mem.h\"\n\n#define ARC_COMMON_MAGIC\t0xB32EB324U  /* just a unique number */\n\n#define AUX_DEBUG_REG                   0x5\n#define AUX_PC_REG                      0x6\n#define AUX_STATUS32_REG                0xA\n\n\n#define SET_CORE_FORCE_HALT             BIT(1)\n#define SET_CORE_HALT_BIT               BIT(0)      /* STATUS32[0] = H field */\n#define SET_CORE_ENABLE_INTERRUPTS      BIT(31)\n/* STATUS32[5] or AE bit indicates if the processor is in exception state */\n#define SET_CORE_AE_BIT                 BIT(5)\n/* Single instruction step bit in Debug register */\n#define SET_CORE_SINGLE_INSTR_STEP      BIT(11)\n\n#define AUX_STATUS32_REG_HALT_BIT       BIT(0)\n#define AUX_STATUS32_REG_IE_BIT         BIT(31)    /* STATUS32[31] = IE field */\n\n/* ARC register numbers */\nenum {\n\tARC_R0,\n\tARC_R1,\n\tARC_R2,\n\tARC_R3,\n\tARC_R4,\n\tARC_R5,\n\tARC_R6,\n\tARC_R7,\n\tARC_R8,\n\tARC_R9,\n\tARC_R10,\n\tARC_R11,\n\tARC_R12,\n\tARC_R13,\n\tARC_R14,\n\tARC_R15,\n\tARC_R16,\n\tARC_R17,\n\tARC_R18,\n\tARC_R19,\n\tARC_R20,\n\tARC_R21,\n\tARC_R22,\n\tARC_R23,\n\tARC_R24,\n\tARC_R25,\n\tARC_GP\t\t= 26,\n\tARC_FP\t\t= 27,\n\tARC_SP\t\t= 28,\n\tARC_ILINK\t= 29,\n\tARC_R30,\n\tARC_BLINK\t= 31,\n\tARC_LP_COUNT\t= 60,\n\n\t/* Reserved registers */\n\tARC_R61\t\t= 61,\n\tARC_R62\t\t= 62,\n\n\tARC_PCL\t\t= 63,\n\tARC_PC\t\t= 64,\n\tARC_LP_START\t= 65,\n\tARC_LP_END\t= 66,\n\tARC_STATUS32\t= 67,\n};\n\n#define CORE_REG_MAX_NUMBER\t\t(63)\n\n/* Limit reg_type/reg_type_field  name to 20 symbols */\n#define REG_TYPE_MAX_NAME_LENGTH\t20\n\n/* ARC 32bits opcodes */\n#define ARC_SDBBP_32 0x256F003FU  /* BRK */\n\n/* ARC 16bits opcodes */\n#define ARC_SDBBP_16 0x7FFF      /* BRK_S */\n\n/* Cache registers */\n#define AUX_IC_IVIC_REG\t\t\t0X10\n#define IC_IVIC_INVALIDATE\t\t0XFFFFFFFF\n\n#define AUX_DC_IVDC_REG\t\t\t0X47\n#define DC_IVDC_INVALIDATE\t\tBIT(0)\n#define AUX_DC_CTRL_REG\t\t\t0X48\n#define DC_CTRL_IM\t\t\tBIT(6)\n\n/* L2 cache registers */\n#define SLC_AUX_CACHE_CTRL\t\t0x903\n#define L2_CTRL_IM\t\t\tBIT(6)\n#define L2_CTRL_BS\t\t\tBIT(8)\t\t/* Busy flag */\n#define SLC_AUX_CACHE_FLUSH\t\t0x904\n#define L2_FLUSH_FL\t\t\tBIT(0)\n#define SLC_AUX_CACHE_INV\t\t0x905\n#define L2_INV_IV\t\t\tBIT(0)\n\n /* Action Point */\n#define AP_AC_AT_INST_ADDR\t\t0x0\n#define AP_AC_AT_MEMORY_ADDR\t0x2\n#define AP_AC_AT_AUXREG_ADDR\t0x4\n\n#define AP_AC_TT_DISABLE\t\t0x00\n#define AP_AC_TT_WRITE\t\t\t0x10\n#define AP_AC_TT_READ\t\t\t0x20\n#define AP_AC_TT_READWRITE\t\t0x30\n\nstruct arc_reg_bitfield {\n\tstruct reg_data_type_bitfield bitfield;\n\tchar name[REG_TYPE_MAX_NAME_LENGTH];\n};\n/* Register data type */\nstruct arc_reg_data_type {\n\tstruct list_head list;\n\tstruct reg_data_type data_type;\n\tstruct reg_data_type_flags data_type_flags;\n\tstruct reg_data_type_struct data_type_struct;\n\tchar data_type_id[REG_TYPE_MAX_NAME_LENGTH];\n\tstruct arc_reg_bitfield *bitfields;\n\tunion {\n\t\tstruct reg_data_type_struct_field *reg_type_struct_field;\n\t\tstruct reg_data_type_flags_field *reg_type_flags_field;\n\t};\n};\n\n/* Standard GDB register types */\nstatic const struct reg_data_type standard_gdb_types[] = {\n\t{ .type = REG_TYPE_INT,         .id = \"int\" },\n\t{ .type = REG_TYPE_INT8,        .id = \"int8\" },\n\t{ .type = REG_TYPE_INT16,       .id = \"int16\" },\n\t{ .type = REG_TYPE_INT32,       .id = \"int32\" },\n\t{ .type = REG_TYPE_INT64,       .id = \"int64\" },\n\t{ .type = REG_TYPE_INT128,      .id = \"int128\" },\n\t{ .type = REG_TYPE_UINT8,       .id = \"uint8\" },\n\t{ .type = REG_TYPE_UINT16,      .id = \"uint16\" },\n\t{ .type = REG_TYPE_UINT32,      .id = \"uint32\" },\n\t{ .type = REG_TYPE_UINT64,      .id = \"uint64\" },\n\t{ .type = REG_TYPE_UINT128,     .id = \"uint128\" },\n\t{ .type = REG_TYPE_CODE_PTR,    .id = \"code_ptr\" },\n\t{ .type = REG_TYPE_DATA_PTR,    .id = \"data_ptr\" },\n\t{ .type = REG_TYPE_FLOAT,       .id = \"float\" },\n\t{ .type = REG_TYPE_IEEE_SINGLE, .id = \"ieee_single\" },\n\t{ .type = REG_TYPE_IEEE_DOUBLE, .id = \"ieee_double\" },\n};\n\nenum arc_actionpointype {\n\tARC_AP_BREAKPOINT,\n\tARC_AP_WATCHPOINT,\n};\n\n/* Actionpoint related fields  */\nstruct arc_actionpoint {\n\tint used;\n\tuint32_t bp_value;\n\tuint32_t reg_address;\n\tenum arc_actionpointype type;\n};\n\nstruct arc_common {\n\tunsigned int common_magic;\n\n\tstruct arc_jtag jtag_info;\n\n\tstruct reg_cache *core_and_aux_cache;\n\tstruct reg_cache *bcr_cache;\n\n\t/* Cache control */\n\tbool has_dcache;\n\tbool has_icache;\n\tbool has_l2cache;\n\t/* If true, then D$ has been already flushed since core has been\n\t * halted. */\n\tbool dcache_flushed;\n\t/* If true, then L2 has been already flushed since core has been\n\t * halted. */\n\tbool l2cache_flushed;\n\t/* If true, then caches have been already flushed since core has been\n\t * halted. */\n\tbool icache_invalidated;\n\tbool dcache_invalidated;\n\tbool l2cache_invalidated;\n\n\t/* Indicate if cache was built (for deinit function) */\n\tbool core_aux_cache_built;\n\tbool bcr_cache_built;\n\t/* Closely Coupled memory(CCM) regions for performance-critical\n\t * code (optional). */\n\tuint32_t iccm0_start;\n\tuint32_t iccm0_end;\n\tuint32_t iccm1_start;\n\tuint32_t iccm1_end;\n\tuint32_t dccm_start;\n\tuint32_t dccm_end;\n\n\tint irq_state;\n\n\t/* Register descriptions */\n\tstruct list_head reg_data_types;\n\tstruct list_head core_reg_descriptions;\n\tstruct list_head aux_reg_descriptions;\n\tstruct list_head bcr_reg_descriptions;\n\tunsigned long num_regs;\n\tunsigned long num_core_regs;\n\tunsigned long num_aux_regs;\n\tunsigned long num_bcr_regs;\n\tunsigned long last_general_reg;\n\n\t/* PC register location in register cache. */\n\tunsigned long pc_index_in_cache;\n\t/* DEBUG register location in register cache. */\n\tunsigned long debug_index_in_cache;\n\n\t/* Actionpoints */\n\tunsigned int actionpoints_num;\n\tunsigned int actionpoints_num_avail;\n\tstruct arc_actionpoint *actionpoints_list;\n};\n\n/* Borrowed from nds32.h */\n#define CHECK_RETVAL(action)\t\t\t\\\n\tdo {\t\t\t\t\t\\\n\t\tint __retval = (action);\t\\\n\t\tif (__retval != ERROR_OK) {\t\\\n\t\t\tLOG_DEBUG(\"error while calling \\\"%s\\\"\",\t\\\n\t\t\t\t# action);     \\\n\t\t\treturn __retval;\t\\\n\t\t}\t\t\t\t\\\n\t} while (0)\n\nstatic inline struct arc_common *target_to_arc(struct target *target)\n{\n\treturn target->arch_info;\n}\n\n/* ----- Inlined functions ------------------------------------------------- */\n\n/**\n * Convert data in host endianness to the middle endian. This is required to\n * write 4-byte instructions.\n */\nstatic inline void arc_h_u32_to_me(uint8_t *buf, int val)\n{\n\tbuf[1] = (uint8_t) (val >> 24);\n\tbuf[0] = (uint8_t) (val >> 16);\n\tbuf[3] = (uint8_t) (val >> 8);\n\tbuf[2] = (uint8_t) (val >> 0);\n}\n\n/**\n * Convert data in middle endian to host endian. This is required to read 32-bit\n * instruction from little endian ARCs.\n */\nstatic inline uint32_t arc_me_to_h_u32(const uint8_t *buf)\n{\n\treturn (uint32_t)(buf[2] | buf[3] << 8 | buf[0] << 16 | buf[1] << 24);\n}\n\n\n/* ARC Register description */\nstruct arc_reg_desc {\n\n\tstruct target *target;\n\n\t/* Register name */\n\tchar *name;\n\n\t/* Actual place of storing reg_value */\n\tuint8_t reg_value[4];\n\n\t/* Actual place of storing register feature */\n\tstruct reg_feature feature;\n\n\t/* GDB XML feature */\n\tchar *gdb_xml_feature;\n\n\t/* Is this a register in g/G-packet? */\n\tbool is_general;\n\n\t/* Architectural number: core reg num or AUX reg num */\n\tuint32_t arch_num;\n\n\t/* Core or AUX register? */\n\tbool is_core;\n\n\t/* Build configuration register? */\n\tbool is_bcr;\n\n\t/* Data type */\n\tstruct reg_data_type *data_type;\n\n\tstruct list_head list;\n};\n\n/* Error codes */\n#define ERROR_ARC_REGISTER_NOT_FOUND       (-700)\n#define ERROR_ARC_REGISTER_FIELD_NOT_FOUND (-701)\n#define ERROR_ARC_REGISTER_IS_NOT_STRUCT   (-702)\n#define ERROR_ARC_FIELD_IS_NOT_BITFIELD    (-703)\n#define ERROR_ARC_REGTYPE_NOT_FOUND        (-704)\n\nvoid free_reg_desc(struct arc_reg_desc *r);\n\n\nvoid arc_reg_data_type_add(struct target *target,\n\t\tstruct arc_reg_data_type *data_type);\n\nint arc_reg_add(struct target *target, struct arc_reg_desc *arc_reg,\n\t\tconst char * const type_name, const size_t type_name_len);\n\nstruct reg *arc_reg_get_by_name(struct reg_cache *first,\n\t\t\t\t\tconst char *name, bool search_all);\n\nint arc_reg_get_field(struct target *target, const char *reg_name,\n\t\tconst char *field_name, uint32_t *value_ptr);\n\nint arc_cache_flush(struct target *target);\nint arc_cache_invalidate(struct target *target);\n\nint arc_add_auxreg_actionpoint(struct target *target,\n\tuint32_t auxreg_addr, uint32_t transaction);\nint arc_remove_auxreg_actionpoint(struct target *target, uint32_t auxreg_addr);\nint arc_set_actionpoints_num(struct target *target, uint32_t ap_num);\n\n#endif /* OPENOCD_TARGET_ARC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_cmd.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2015,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arc.h\"\n#include <helper/nvp.h>\n\n/* --------------------------------------------------------------------------\n *\n *   ARC targets expose command interface.\n *   It can be accessed via GDB through the (gdb) monitor command.\n *\n * ------------------------------------------------------------------------- */\n\n\nenum add_reg_types {\n\tCFG_ADD_REG_TYPE_FLAG,\n\tCFG_ADD_REG_TYPE_STRUCT,\n};\n/* Add flags register data type */\nenum add_reg_type_flags {\n\tCFG_ADD_REG_TYPE_FLAGS_NAME,\n\tCFG_ADD_REG_TYPE_FLAGS_FLAG,\n};\n\nstatic const struct nvp nvp_add_reg_type_flags_opts[] = {\n\t{ .name = \"-name\",  .value = CFG_ADD_REG_TYPE_FLAGS_NAME },\n\t{ .name = \"-flag\",  .value = CFG_ADD_REG_TYPE_FLAGS_FLAG },\n\t{ .name = NULL,     .value = -1 }\n};\n\n/* Helper function to check if all field required for register\n * are set up */\nstatic const char *validate_register(const struct arc_reg_desc * const reg, bool arch_num_set)\n{\n\t/* Check that required fields are set */\n\tif (!reg->name)\n\t\treturn \"-name option is required\";\n\tif (!reg->gdb_xml_feature)\n\t\treturn \"-feature option is required\";\n\tif (!arch_num_set)\n\t\treturn \"-num option is required\";\n\tif (reg->is_bcr && reg->is_core)\n\t\treturn \"Register cannot be both -core and -bcr.\";\n\treturn NULL;\n}\n\nstatic COMMAND_HELPER(arc_handle_add_reg_type_flags_ops, struct arc_reg_data_type *type)\n{\n\tstruct reg_data_type_flags_field *fields = type->reg_type_flags_field;\n\tstruct arc_reg_bitfield *bitfields = type->bitfields;\n\tstruct reg_data_type_flags *flags = &type->data_type_flags;\n\tunsigned int cur_field = 0;\n\n\twhile (CMD_ARGC) {\n\t\tconst struct nvp *n = nvp_name2value(nvp_add_reg_type_flags_opts, CMD_ARGV[0]);\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tswitch (n->value) {\n\t\tcase CFG_ADD_REG_TYPE_FLAGS_NAME:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tconst char *name = CMD_ARGV[0];\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\n\t\t\tif (strlen(name) >= REG_TYPE_MAX_NAME_LENGTH) {\n\t\t\t\tcommand_print(CMD, \"Reg type name is too big.\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\n\t\t\tstrcpy((void *)type->data_type.id, name);\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_TYPE_FLAGS_FLAG:\n\t\t\tif (CMD_ARGC < 2)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tuint32_t val;\n\t\t\tconst char *field_name = CMD_ARGV[0];\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], val);\n\t\t\tCMD_ARGC -= 2;\n\t\t\tCMD_ARGV += 2;\n\t\t\tbitfields[cur_field].bitfield.start = val;\n\t\t\tbitfields[cur_field].bitfield.end = val;\n\n\t\t\tif (strlen(field_name) >= REG_TYPE_MAX_NAME_LENGTH) {\n\t\t\t\tcommand_print(CMD, \"Reg type field_name is too big.\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\n\t\t\tfields[cur_field].name = bitfields[cur_field].name;\n\t\t\tstrcpy(bitfields[cur_field].name, field_name);\n\n\t\t\tfields[cur_field].bitfield = &bitfields[cur_field].bitfield;\n\t\t\tif (cur_field > 0)\n\t\t\t\tfields[cur_field - 1].next = &fields[cur_field];\n\t\t\telse\n\t\t\t\tflags->fields = fields;\n\n\t\t\tcur_field += 1;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tnvp_unknown_command_print(CMD, nvp_add_reg_type_flags_opts, NULL, CMD_ARGV[-1]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (!type->data_type.id) {\n\t\tcommand_print(CMD, \"-name is a required option\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_add_reg_type_flags)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check if the amount of arguments is not zero */\n\tif (CMD_ARGC == 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Estimate number of registers as (argc - 2)/3 as each -flag option has 2\n\t * arguments while -name is required. */\n\tunsigned int fields_sz = (CMD_ARGC - 2) / 3;\n\n\t/* The maximum amount of bitfields is 32 */\n\tif (fields_sz > 32) {\n\t\tcommand_print(CMD, \"The amount of bitfields exceed 32\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tstruct arc_reg_data_type *type = calloc(1, sizeof(*type));\n\tstruct reg_data_type_flags_field *fields = calloc(fields_sz, sizeof(*fields));\n\tstruct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields));\n\tif (!type || !fields || !bitfields) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto fail;\n\t}\n\tstruct reg_data_type_flags *flags = &type->data_type_flags;\n\ttype->reg_type_flags_field = fields;\n\n\t/* Initialize type */\n\ttype->bitfields = bitfields;\n\ttype->data_type.id = type->data_type_id;\n\ttype->data_type.type = REG_TYPE_ARCH_DEFINED;\n\ttype->data_type.type_class = REG_TYPE_CLASS_FLAGS;\n\ttype->data_type.reg_type_flags = flags;\n\tflags->size = 4; /* For now ARC has only 32-bit registers */\n\n\tretval = CALL_COMMAND_HANDLER(arc_handle_add_reg_type_flags_ops, type);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\n\tarc_reg_data_type_add(target, type);\n\n\tLOG_DEBUG(\"added flags type {name=%s}\", type->data_type.id);\n\n\treturn ERROR_OK;\n\nfail:\n\tfree(type);\n\tfree(fields);\n\tfree(bitfields);\n\n\treturn retval;\n}\n\n/* Add struct register data type */\nenum add_reg_type_struct {\n\tCFG_ADD_REG_TYPE_STRUCT_NAME,\n\tCFG_ADD_REG_TYPE_STRUCT_BITFIELD,\n};\n\nstatic const struct nvp nvp_add_reg_type_struct_opts[] = {\n\t{ .name = \"-name\",     .value = CFG_ADD_REG_TYPE_STRUCT_NAME },\n\t{ .name = \"-bitfield\", .value = CFG_ADD_REG_TYPE_STRUCT_BITFIELD },\n\t{ .name = NULL,     .value = -1 }\n};\n\nCOMMAND_HANDLER(arc_handle_set_aux_reg)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Register number */\n\tuint32_t regnum;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum);\n\n\t/* Register value */\n\tuint32_t value;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\tCHECK_RETVAL(arc_jtag_write_aux_reg_one(&arc->jtag_info, regnum, value));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_get_aux_reg)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Register number */\n\tuint32_t regnum;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum);\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\tuint32_t value;\n\tCHECK_RETVAL(arc_jtag_read_aux_reg_one(&arc->jtag_info, regnum, &value));\n\n\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_get_core_reg)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Register number */\n\tuint32_t regnum;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum);\n\tif (regnum > CORE_REG_MAX_NUMBER || regnum == ARC_R61 || regnum == ARC_R62) {\n\t\tcommand_print(CMD, \"Core register number %i \"\n\t\t\t\"is invalid. Must less then 64 and not 61 and 62.\", regnum);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\t/* Read value */\n\tuint32_t value;\n\tCHECK_RETVAL(arc_jtag_read_core_reg_one(&arc->jtag_info, regnum, &value));\n\n\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_set_core_reg)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Register number */\n\tuint32_t regnum;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], regnum);\n\tif (regnum > CORE_REG_MAX_NUMBER || regnum == ARC_R61 || regnum == ARC_R62) {\n\t\tcommand_print(CMD, \"Core register number %i \"\n\t\t\t\"is invalid. Must less then 64 and not 61 and 62.\", regnum);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* Register value */\n\tuint32_t value;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\tstruct arc_common *arc = target_to_arc(target);\n\tassert(arc);\n\n\tCHECK_RETVAL(arc_jtag_write_core_reg_one(&arc->jtag_info, regnum, value));\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arc_jtag_command_group[] = {\n\t{\n\t\t.name = \"get-aux-reg\",\n\t\t.handler = arc_handle_get_aux_reg,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Get AUX register by number. This command does a \"\n\t\t\t\"raw JTAG request that bypasses OpenOCD register cache \"\n\t\t\t\"and thus is unsafe and can have unexpected consequences. \"\n\t\t\t\"Use at your own risk.\",\n\t\t.usage = \"<regnum>\"\n\t},\n\t{\n\t\t.name = \"set-aux-reg\",\n\t\t.handler = arc_handle_set_aux_reg,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Set AUX register by number. This command does a \"\n\t\t\t\"raw JTAG request that bypasses OpenOCD register cache \"\n\t\t\t\"and thus is unsafe and can have unexpected consequences. \"\n\t\t\t\"Use at your own risk.\",\n\t\t.usage = \"<regnum> <value>\"\n\t},\n\t{\n\t\t.name = \"get-core-reg\",\n\t\t.handler = arc_handle_get_core_reg,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Get/Set core register by number. This command does a \"\n\t\t\t\"raw JTAG request that bypasses OpenOCD register cache \"\n\t\t\t\"and thus is unsafe and can have unexpected consequences. \"\n\t\t\t\"Use at your own risk.\",\n\t\t.usage = \"<regnum> [<value>]\"\n\t},\n\t{\n\t\t.name = \"set-core-reg\",\n\t\t.handler = arc_handle_set_core_reg,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Get/Set core register by number. This command does a \"\n\t\t\t\"raw JTAG request that bypasses OpenOCD register cache \"\n\t\t\t\"and thus is unsafe and can have unexpected consequences. \"\n\t\t\t\"Use at your own risk.\",\n\t\t.usage = \"<regnum> [<value>]\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\n/* This function supports only bitfields. */\nstatic COMMAND_HELPER(arc_handle_add_reg_type_struct_opts, struct arc_reg_data_type *type)\n{\n\tstruct reg_data_type_struct_field *fields = type->reg_type_struct_field;\n\tstruct arc_reg_bitfield *bitfields = type->bitfields;\n\tstruct reg_data_type_struct *struct_type = &type->data_type_struct;\n\tunsigned int cur_field = 0;\n\n\twhile (CMD_ARGC) {\n\t\tconst struct nvp *n = nvp_name2value(nvp_add_reg_type_struct_opts, CMD_ARGV[0]);\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tswitch (n->value) {\n\t\tcase CFG_ADD_REG_TYPE_STRUCT_NAME:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tconst char *name = CMD_ARGV[0];\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\n\t\t\tif (strlen(name) >= REG_TYPE_MAX_NAME_LENGTH) {\n\t\t\t\tcommand_print(CMD, \"Reg type name is too big.\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\n\t\t\tstrcpy((void *)type->data_type.id, name);\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_TYPE_STRUCT_BITFIELD:\n\t\t\tif (CMD_ARGC < 3)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tuint32_t start_pos, end_pos;\n\t\t\tconst char *field_name = CMD_ARGV[0];\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], start_pos);\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], end_pos);\n\t\t\tCMD_ARGC -= 3;\n\t\t\tCMD_ARGV += 3;\n\t\t\tbitfields[cur_field].bitfield.start = start_pos;\n\t\t\tbitfields[cur_field].bitfield.end = end_pos;\n\t\t\tbitfields[cur_field].bitfield.type = REG_TYPE_INT;\n\n\t\t\tif (strlen(field_name) >= REG_TYPE_MAX_NAME_LENGTH) {\n\t\t\t\tcommand_print(CMD, \"Reg type field_name is too big.\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\n\t\t\tfields[cur_field].name = bitfields[cur_field].name;\n\t\t\tstrcpy(bitfields[cur_field].name, field_name);\n\n\t\t\tfields[cur_field].bitfield = &bitfields[cur_field].bitfield;\n\t\t\tfields[cur_field].use_bitfields = true;\n\t\t\tif (cur_field > 0)\n\t\t\t\tfields[cur_field - 1].next = &fields[cur_field];\n\t\t\telse\n\t\t\t\tstruct_type->fields = fields;\n\n\t\t\tcur_field += 1;\n\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tnvp_unknown_command_print(CMD, nvp_add_reg_type_struct_opts, NULL, CMD_ARGV[-1]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (!type->data_type.id) {\n\t\tcommand_print(CMD, \"-name is a required option\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_add_reg_type_struct)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Check if the amount of arguments is not zero */\n\tif (CMD_ARGC == 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Estimate number of registers as (argc - 2)/4 as each -bitfield option has 3\n\t * arguments while -name is required. */\n\tunsigned int fields_sz = (CMD_ARGC - 2) / 4;\n\n\t/* The maximum amount of bitfields is 32 */\n\tif (fields_sz > 32) {\n\t\tcommand_print(CMD, \"The amount of bitfields exceed 32\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tstruct arc_reg_data_type *type = calloc(1, sizeof(*type));\n\tstruct reg_data_type_struct_field *fields = calloc(fields_sz, sizeof(*fields));\n\tstruct arc_reg_bitfield *bitfields = calloc(fields_sz, sizeof(*bitfields));\n\tif (!type || !fields || !bitfields) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tretval = ERROR_FAIL;\n\t\tgoto fail;\n\t}\n\tstruct reg_data_type_struct *struct_type = &type->data_type_struct;\n\ttype->reg_type_struct_field = fields;\n\n\t/* Initialize type */\n\ttype->data_type.id = type->data_type_id;\n\ttype->bitfields = bitfields;\n\ttype->data_type.type = REG_TYPE_ARCH_DEFINED;\n\ttype->data_type.type_class = REG_TYPE_CLASS_STRUCT;\n\ttype->data_type.reg_type_struct = struct_type;\n\tstruct_type->size = 4; /* For now ARC has only 32-bit registers */\n\n\tretval = CALL_COMMAND_HANDLER(arc_handle_add_reg_type_struct_opts, type);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\n\tarc_reg_data_type_add(target, type);\n\n\tLOG_DEBUG(\"added struct type {name=%s}\", type->data_type.id);\n\n\treturn ERROR_OK;\n\nfail:\n\tfree(type);\n\tfree(fields);\n\tfree(bitfields);\n\n\treturn retval;\n}\n\n/* Add register */\nenum opts_add_reg {\n\tCFG_ADD_REG_NAME,\n\tCFG_ADD_REG_ARCH_NUM,\n\tCFG_ADD_REG_IS_CORE,\n\tCFG_ADD_REG_IS_BCR,\n\tCFG_ADD_REG_GDB_FEATURE,\n\tCFG_ADD_REG_TYPE,\n\tCFG_ADD_REG_GENERAL,\n};\n\nstatic const struct nvp opts_nvp_add_reg[] = {\n\t{ .name = \"-name\",    .value = CFG_ADD_REG_NAME },\n\t{ .name = \"-num\",     .value = CFG_ADD_REG_ARCH_NUM },\n\t{ .name = \"-core\",    .value = CFG_ADD_REG_IS_CORE },\n\t{ .name = \"-bcr\",     .value = CFG_ADD_REG_IS_BCR },\n\t{ .name = \"-feature\", .value = CFG_ADD_REG_GDB_FEATURE },\n\t{ .name = \"-type\",    .value = CFG_ADD_REG_TYPE },\n\t{ .name = \"-g\",       .value = CFG_ADD_REG_GENERAL },\n\t{ .name = NULL,       .value = -1 }\n};\n\nvoid free_reg_desc(struct arc_reg_desc *r)\n{\n\tfree(r->name);\n\tfree(r->gdb_xml_feature);\n\tfree(r);\n}\n\nstatic COMMAND_HELPER(arc_handle_add_reg_do, struct arc_reg_desc *reg)\n{\n\t/* There is no architecture number that we could treat as invalid, so\n\t * separate variable required to ensure that arch num has been set. */\n\tbool arch_num_set = false;\n\tconst char *type_name = \"int\"; /* Default type */\n\n\t/* At least we need to specify 4 parameters: name, number and gdb_feature,\n\t * which means there should be 6 arguments. Also there can be additional parameters\n\t * \"-type <type>\", \"-g\" and  \"-core\" or \"-bcr\" which makes maximum 10 parameters. */\n\tif (CMD_ARGC < 6 || CMD_ARGC > 10)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Parse options. */\n\twhile (CMD_ARGC) {\n\t\tconst struct nvp *n = nvp_name2value(opts_nvp_add_reg, CMD_ARGV[0]);\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tswitch (n->value) {\n\t\tcase CFG_ADD_REG_NAME:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\treg->name = strdup(CMD_ARGV[0]);\n\t\t\tif (!reg->name) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_IS_CORE:\n\t\t\treg->is_core = true;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_IS_BCR:\n\t\t\treg->is_bcr = true;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_ARCH_NUM:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg->arch_num);\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\n\t\t\tarch_num_set = true;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_GDB_FEATURE:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\treg->gdb_xml_feature = strdup(CMD_ARGV[0]);\n\t\t\tif (!reg->gdb_xml_feature) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_TYPE:\n\t\t\tif (!CMD_ARGC)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\t\ttype_name = CMD_ARGV[0];\n\t\t\tCMD_ARGC--;\n\t\t\tCMD_ARGV++;\n\t\t\tbreak;\n\n\t\tcase CFG_ADD_REG_GENERAL:\n\t\t\treg->is_general = true;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tnvp_unknown_command_print(CMD, opts_nvp_add_reg, NULL, CMD_ARGV[-1]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\t/* Check that required fields are set */\n\tconst char * const errmsg = validate_register(reg, arch_num_set);\n\tif (errmsg) {\n\t\tcommand_print(CMD, \"%s\", errmsg);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* Add new register */\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treg->target = target;\n\n\tint retval = arc_reg_add(target, reg, type_name, strlen(type_name));\n\tif (retval == ERROR_ARC_REGTYPE_NOT_FOUND) {\n\t\tcommand_print(CMD,\n\t\t\t\"Cannot find type `%s' for register `%s'.\",\n\t\t\ttype_name, reg->name);\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_handle_add_reg)\n{\n\tstruct arc_reg_desc *reg = calloc(1, sizeof(*reg));\n\tif (!reg) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = CALL_COMMAND_HANDLER(arc_handle_add_reg_do, reg);\n\tif (retval != ERROR_OK) {\n\t\tfree_reg_desc(reg);\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* arc set-reg-exists ($reg_name)+\n * Accepts any amount of register names - will set them as existing in a loop.*/\nCOMMAND_HANDLER(arc_set_reg_exists)\n{\n\tstruct target * const target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"Unable to get current target.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!CMD_ARGC) {\n\t\tcommand_print(CMD, \"At least one register name must be specified.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tconst char * const reg_name = CMD_ARGV[i];\n\t\tstruct reg * const r = arc_reg_get_by_name(target->reg_cache, reg_name, true);\n\n\t\tif (!r) {\n\t\t\tcommand_print(CMD, \"Register `%s' is not found.\", reg_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\n\t\tr->exist = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* arc reg-field  ($reg_name) ($reg_field)\n * Reads struct type register field */\nCOMMAND_HANDLER(arc_handle_get_reg_field)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tconst char *reg_name = CMD_ARGV[0];\n\tconst char *field_name = CMD_ARGV[1];\n\tuint32_t value;\n\tint retval = arc_reg_get_field(target, reg_name, field_name, &value);\n\n\tswitch (retval) {\n\t\tcase ERROR_OK:\n\t\t\tbreak;\n\t\tcase ERROR_ARC_REGISTER_NOT_FOUND:\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Register `%s' has not been found.\", reg_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tcase ERROR_ARC_REGISTER_IS_NOT_STRUCT:\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Register `%s' must have 'struct' type.\", reg_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tcase ERROR_ARC_REGISTER_FIELD_NOT_FOUND:\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Field `%s' has not been found in register `%s'.\",\n\t\t\t\tfield_name, reg_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tcase ERROR_ARC_FIELD_IS_NOT_BITFIELD:\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Field `%s' is not a 'bitfield' field in a structure.\",\n\t\t\t\tfield_name);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tdefault:\n\t\t\t/* Pass through other errors. */\n\t\t\treturn retval;\n\t}\n\n\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arc_l1_cache_disable_auto_cmd)\n{\n\tbool value;\n\tint retval = 0;\n\tstruct arc_common *arc = target_to_arc(get_current_target(CMD_CTX));\n\tretval = CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t&value, \"target has caches enabled\");\n\tarc->has_l2cache = value;\n\tarc->has_dcache = value;\n\tarc->has_icache = value;\n\treturn retval;\n}\n\nCOMMAND_HANDLER(arc_l2_cache_disable_auto_cmd)\n{\n\tstruct arc_common *arc = target_to_arc(get_current_target(CMD_CTX));\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t&arc->has_l2cache, \"target has l2 cache enabled\");\n}\n\nCOMMAND_HANDLER(arc_handle_actionpoints_num)\n{\n\tLOG_DEBUG(\"-\");\n\n\tif (CMD_ARGC >= 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"No current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct arc_common *arc = target_to_arc(target);\n\t/* It is not possible to pass &arc->actionpoints_num directly to\n\t * handle_command_parse_uint, because this value should be valid during\n\t * \"actionpoint reset, initiated by arc_set_actionpoints_num.  */\n\tuint32_t ap_num = arc->actionpoints_num;\n\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ap_num);\n\t\tint e = arc_set_actionpoints_num(target, ap_num);\n\t\tif (e != ERROR_OK) {\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Failed to set number of actionpoints\");\n\t\t\treturn e;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"%\" PRIu32, ap_num);\n\n\treturn ERROR_OK;\n}\n\n/* ----- Exported target commands ------------------------------------------ */\n\nstatic const struct command_registration arc_l2_cache_group_handlers[] = {\n\t{\n\t\t.name = \"auto\",\n\t\t.handler = arc_l2_cache_disable_auto_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"(1|0)\",\n\t\t.help = \"Disable or enable L2\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arc_cache_group_handlers[] = {\n\t{\n\t\t.name = \"auto\",\n\t\t.handler = arc_l1_cache_disable_auto_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Disable or enable L1\",\n\t\t.usage = \"(1|0)\",\n\t},\n\t{\n\t\t.name = \"l2\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"L2 cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arc_l2_cache_group_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\nstatic const struct command_registration arc_core_command_handlers[] = {\n\t{\n\t\t.name = \"add-reg-type-flags\",\n\t\t.handler = arc_handle_add_reg_type_flags,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"-name <string> -flag <name> <position> \"\n\t\t\t\"[-flag <name> <position>]...\",\n\t\t.help = \"Add new 'flags' register data type. Only single bit flags \"\n\t\t\t\"are supported. Type name is global. Bitsize of register is fixed \"\n\t\t\t\"at 32 bits.\",\n\t},\n\t{\n\t\t.name = \"add-reg-type-struct\",\n\t\t.handler = arc_handle_add_reg_type_struct,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"-name <string> -bitfield <name> <start> <end> \"\n\t\t\t\"[-bitfield <name> <start> <end>]...\",\n\t\t.help = \"Add new 'struct' register data type. Only bit-fields are \"\n\t\t\t\"supported so far, which means that for each bitfield start and end \"\n\t\t\t\"position bits must be specified. GDB also support type-fields, \"\n\t\t\t\"where common type can be used instead. Type name is global. Bitsize of \"\n\t\t\t\"register is fixed at 32 bits.\",\n\t},\n\t{\n\t\t.name = \"add-reg\",\n\t\t.handler = arc_handle_add_reg,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"-name <string> -num <int> -feature <string> [-gdbnum <int>] \"\n\t\t\t\"[-core|-bcr] [-type <type_name>] [-g]\",\n\t\t.help = \"Add new register. Name, architectural number and feature name \"\n\t\t\t\"are required options. GDB regnum will default to previous register \"\n\t\t\t\"(gdbnum + 1) and shouldn't be specified in most cases. Type \"\n\t\t\t\"defaults to default GDB 'int'.\",\n\t},\n\t{\n\t\t.name = \"set-reg-exists\",\n\t\t.handler = arc_set_reg_exists,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"<register-name> [<register-name>]...\",\n\t\t.help = \"Set that register exists. Accepts multiple register names as \"\n\t\t\t\"arguments.\",\n\t},\n\t{\n\t\t.name = \"get-reg-field\",\n\t\t.handler = arc_handle_get_reg_field,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"<regname> <field_name>\",\n\t\t.help = \"Returns value of field in a register with 'struct' type.\",\n\t},\n\t{\n\t\t.name = \"jtag\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARC JTAG specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = arc_jtag_command_group,\n\t},\n\t{\n\t\t.name = \"cache\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arc_cache_group_handlers,\n\t},\n\t{\n\t\t.name = \"num-actionpoints\",\n\t\t.handler = arc_handle_actionpoints_num,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[<unsigned integer>]\",\n\t\t.help = \"Prints or sets amount of actionpoints in the processor.\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arc_monitor_command_handlers[] = {\n\t{\n\t\t.name = \"arc\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARC monitor command group\",\n\t\t.usage = \"\",\n\t\t.chain = arc_core_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_cmd.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARC_CMD_H\n#define OPENOCD_TARGET_ARC_CMD_H\n\nextern const struct command_registration arc_monitor_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARC_CMD_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arc.h\"\n\n/*\n * This functions sets instruction register in TAP. TAP end state is always\n * IRPAUSE.\n *\n * @param jtag_info\n * @param new_instr\tInstruction to write to instruction register.\n */\nstatic void arc_jtag_enque_write_ir(struct arc_jtag *jtag_info, uint32_t\n\t\tnew_instr)\n{\n\tuint32_t current_instr;\n\tstruct jtag_tap *tap;\n\tuint8_t instr_buffer[sizeof(uint32_t)] = {0};\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\ttap = jtag_info->tap;\n\n\t/* Do not set instruction if it is the same as current. */\n\tcurrent_instr = buf_get_u32(tap->cur_instr, 0, tap->ir_length);\n\tif (current_instr == new_instr)\n\t\treturn;\n\n\tstruct scan_field field = {\n\t\t.num_bits = tap->ir_length,\n\t\t.out_value = instr_buffer\n\t};\n\tbuf_set_u32(instr_buffer, 0, field.num_bits, new_instr);\n\n\t/* From code in src/jtag/drivers/driver.c it look like that fields are\n\t * copied so it is OK that field in this function is allocated in stack and\n\t * thus this memory will be repurposed before jtag_execute_queue() will be\n\t * invoked. */\n\tjtag_add_ir_scan(tap, &field, TAP_IRPAUSE);\n}\n\n/**\n * Read 4-byte word from data register.\n *\n * Unlike arc_jtag_write_data, this function returns byte-buffer, caller must\n * convert this data to required format himself. This is done, because it is\n * impossible to convert data before jtag_execute_queue() is invoked, so it\n * cannot be done inside this function, so it has to operate with\n * byte-buffers. Write function on the other hand can \"write-and-forget\", data\n * is converted to byte-buffer before jtag_execute_queue().\n *\n * @param jtag_info\n * @param data\t\tArray of bytes to read into.\n * @param end_state\tEnd state after reading.\n */\nstatic void arc_jtag_enque_read_dr(struct arc_jtag *jtag_info, uint8_t *data,\n\t\ttap_state_t end_state)\n{\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\tstruct scan_field field = {\n\t\t.num_bits = 32,\n\t\t.in_value = data\n\t};\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, end_state);\n}\n\n/**\n * Write 4-byte word to data register.\n *\n * @param jtag_info\n * @param data\t\t4-byte word to write into data register.\n * @param end_state\tEnd state after writing.\n */\nstatic void arc_jtag_enque_write_dr(struct arc_jtag *jtag_info, uint32_t data,\n\t\ttap_state_t end_state)\n{\n\tuint8_t out_value[sizeof(uint32_t)] = {0};\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\tbuf_set_u32(out_value, 0, 32, data);\n\n\tstruct scan_field field = {\n\t\t.num_bits = 32,\n\t\t.out_value = out_value\n\t};\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, end_state);\n}\n\n\n/**\n * Set transaction in command register. This function sets instruction register\n * and then transaction register, there is no need to invoke write_ir before\n * invoking this function.\n *\n * @param jtag_info\n * @param new_trans\tTransaction to write to transaction command register.\n * @param end_state\tEnd state after writing.\n */\nstatic void arc_jtag_enque_set_transaction(struct arc_jtag *jtag_info,\n\t\tuint32_t new_trans, tap_state_t end_state)\n{\n\tuint8_t out_value[sizeof(uint32_t)] = {0};\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\t/* No need to do anything. */\n\tif (jtag_info->cur_trans == new_trans)\n\t\treturn;\n\n\t/* Set instruction. We used to call write_ir at upper levels, however\n\t * write_ir-write_transaction were constantly in pair, so to avoid code\n\t * duplication this function does it self. For this reasons it is \"set\"\n\t * instead of \"write\". */\n\tarc_jtag_enque_write_ir(jtag_info, ARC_TRANSACTION_CMD_REG);\n\tbuf_set_u32(out_value, 0, ARC_TRANSACTION_CMD_REG_LENGTH, new_trans);\n\tstruct scan_field field = {\n\t\t.num_bits = ARC_TRANSACTION_CMD_REG_LENGTH,\n\t\t.out_value = out_value\n\t};\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, end_state);\n\tjtag_info->cur_trans = new_trans;\n}\n\n/**\n * Run reset through transaction set. None of the previous\n * settings/commands/etc. are used anymore (or no influence).\n */\nstatic void arc_jtag_enque_reset_transaction(struct arc_jtag *jtag_info)\n{\n\tarc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_CMD_NOP, TAP_IDLE);\n}\n\nstatic void arc_jtag_enque_status_read(struct arc_jtag * const jtag_info,\n\tuint8_t * const buffer)\n{\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\tassert(buffer);\n\n\t/* first writing code(0x8) of jtag status register in IR */\n\tarc_jtag_enque_write_ir(jtag_info, ARC_JTAG_STATUS_REG);\n\t/* Now reading dr performs jtag status register read */\n\tarc_jtag_enque_read_dr(jtag_info, buffer, TAP_IDLE);\n}\n\n/* ----- Exported JTAG functions ------------------------------------------- */\n\nint arc_jtag_startup(struct arc_jtag *jtag_info)\n{\n\tassert(jtag_info);\n\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\treturn jtag_execute_queue();\n}\n\n/** Read STATUS register. */\nint arc_jtag_status(struct arc_jtag * const jtag_info, uint32_t * const value)\n{\n\tuint8_t buffer[sizeof(uint32_t)];\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\t/* Fill command queue. */\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\tarc_jtag_enque_status_read(jtag_info, buffer);\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\t/* Execute queue. */\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\t/* Parse output. */\n\t*value = buf_get_u32(buffer, 0, 32);\n\n\treturn ERROR_OK;\n}\n/* Helper function: Adding read/write register operation to queue */\nstatic void arc_jtag_enque_register_rw(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint8_t *read_buffer, const uint32_t *write_buffer, uint32_t count)\n{\n\tuint32_t i;\n\n\tfor (i = 0; i < count; i++) {\n\t\t/* ARC jtag has optimization which is to increment ADDRESS_REG performing\n\t\t * each transaction. Making sequential reads/writes we can set address for\n\t\t * only first register in sequence, and than do read/write in cycle. */\n\t\tif (i == 0 || (addr[i] != addr[i-1] + 1)) {\n\t\t\tarc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG);\n\t\t\t/* Going to TAP_IDLE state we initiate jtag transaction.\n\t\t\t * Reading data we must go to TAP_IDLE, because further\n\t\t\t * the data would be read. In case of write we go to TAP_DRPAUSE,\n\t\t\t * because we need to write data to Data register first. */\n\t\t\tif (write_buffer)\n\t\t\t\tarc_jtag_enque_write_dr(jtag_info, addr[i], TAP_DRPAUSE);\n\t\t\telse\n\t\t\t\tarc_jtag_enque_write_dr(jtag_info, addr[i], TAP_IDLE);\n\t\t\tarc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG);\n\t\t}\n\t\tif (write_buffer)\n\t\t\tarc_jtag_enque_write_dr(jtag_info, *(write_buffer + i), TAP_IDLE);\n\t\telse\n\t\t\tarc_jtag_enque_read_dr(jtag_info, read_buffer + i * 4, TAP_IDLE);\n\t}\n\t/* To prevent pollution of next register due to optimization it is necessary *\n\t * to reset transaction */\n\tarc_jtag_enque_reset_transaction(jtag_info);\n}\n\n/**\n * Write registers. addr is an array of addresses, and those addresses can be\n * in any order, though it is recommended that they are in sequential order\n * where possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param type\t\tType of registers to write: core or aux.\n * @param addr\t\tArray of registers numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nstatic int arc_jtag_write_registers(struct arc_jtag *jtag_info, uint32_t type,\n\tuint32_t *addr, uint32_t count, const uint32_t *buffer)\n{\n\tLOG_DEBUG(\"Writing to %s registers: addr[0]=0x%\" PRIx32 \";count=%\" PRIu32\n\t\t\t  \";buffer[0]=0x%08\" PRIx32,\n\t\t(type == ARC_JTAG_CORE_REG ? \"core\" : \"aux\"), *addr, count, *buffer);\n\n\tif (!count) {\n\t\tLOG_ERROR(\"Trying to write 0 registers\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\t/* What registers are we writing to? */\n\tconst uint32_t transaction = (type == ARC_JTAG_CORE_REG ?\n\t\t\tARC_JTAG_WRITE_TO_CORE_REG : ARC_JTAG_WRITE_TO_AUX_REG);\n\tarc_jtag_enque_set_transaction(jtag_info, transaction, TAP_DRPAUSE);\n\n\tarc_jtag_enque_register_rw(jtag_info, addr, NULL, buffer, count);\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Read registers. addr is an array of addresses, and those addresses can be in\n * any order, though it is recommended that they are in sequential order where\n * possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param type\t\tType of registers to read: core or aux.\n * @param addr\t\tArray of registers numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nstatic int arc_jtag_read_registers(struct arc_jtag *jtag_info, uint32_t type,\n\t\tuint32_t *addr, uint32_t count, uint32_t *buffer)\n{\n\tint retval;\n\tuint32_t i;\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\tLOG_DEBUG(\"Reading %s registers: addr[0]=0x%\" PRIx32 \";count=%\" PRIu32,\n\t\t(type == ARC_JTAG_CORE_REG ? \"core\" : \"aux\"), *addr, count);\n\n\tif (!count) {\n\t\tLOG_ERROR(\"Trying to read 0 registers\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\t/* What type of registers we are reading? */\n\tconst uint32_t transaction = (type == ARC_JTAG_CORE_REG ?\n\t\t\tARC_JTAG_READ_FROM_CORE_REG : ARC_JTAG_READ_FROM_AUX_REG);\n\tarc_jtag_enque_set_transaction(jtag_info, transaction, TAP_DRPAUSE);\n\n\tuint8_t *data_buf = calloc(sizeof(uint8_t), count * 4);\n\n\tarc_jtag_enque_register_rw(jtag_info, addr, data_buf, NULL, count);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to execute jtag queue: %d\", retval);\n\t\tretval = ERROR_FAIL;\n\t\tgoto exit;\n\t}\n\n\t/* Convert byte-buffers to host /presentation. */\n\tfor (i = 0; i < count; i++)\n\t\tbuffer[i] = buf_get_u32(data_buf + 4 * i, 0, 32);\n\n\tLOG_DEBUG(\"Read from register: buf[0]=0x%\" PRIx32, buffer[0]);\n\nexit:\n\tfree(data_buf);\n\n\treturn retval;\n}\n\n\n/** Wrapper function to ease writing of one core register. */\nint arc_jtag_write_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t value)\n{\n\treturn arc_jtag_write_core_reg(jtag_info, &addr, 1, &value);\n}\n\n/**\n * Write core registers. addr is an array of addresses, and those addresses can\n * be in any order, though it is recommended that they are in sequential order\n * where possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param addr\t\tArray of registers numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nint arc_jtag_write_core_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, const uint32_t *buffer)\n{\n\treturn arc_jtag_write_registers(jtag_info, ARC_JTAG_CORE_REG, addr, count,\n\t\t\tbuffer);\n}\n\n/** Wrapper function to ease reading of one core register. */\nint arc_jtag_read_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t *value)\n{\n\treturn arc_jtag_read_core_reg(jtag_info, &addr, 1, value);\n}\n\n/**\n * Read core registers. addr is an array of addresses, and those addresses can\n * be in any order, though it is recommended that they are in sequential order\n * where possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param addr\t\tArray of core register numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nint arc_jtag_read_core_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, uint32_t *buffer)\n{\n\treturn arc_jtag_read_registers(jtag_info, ARC_JTAG_CORE_REG, addr, count,\n\t\t\tbuffer);\n}\n\n/** Wrapper function to ease writing of one AUX register. */\nint arc_jtag_write_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t value)\n{\n\treturn arc_jtag_write_aux_reg(jtag_info, &addr, 1, &value);\n}\n\n/**\n * Write AUX registers. addr is an array of addresses, and those addresses can\n * be in any order, though it is recommended that they are in sequential order\n * where possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param addr\t\tArray of registers numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nint arc_jtag_write_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, const uint32_t *buffer)\n{\n\treturn arc_jtag_write_registers(jtag_info, ARC_JTAG_AUX_REG, addr, count,\n\t\t\tbuffer);\n}\n\n/** Wrapper function to ease reading of one AUX register. */\nint arc_jtag_read_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t *value)\n{\n\treturn arc_jtag_read_aux_reg(jtag_info, &addr, 1, value);\n}\n\n/**\n * Read AUX registers. addr is an array of addresses, and those addresses can\n * be in any order, though it is recommended that they are in sequential order\n * where possible, as this reduces number of JTAG commands to transfer.\n *\n * @param jtag_info\n * @param addr\t\tArray of AUX register numbers.\n * @param count\t\tAmount of registers in arrays.\n * @param buffer\tArray of register values.\n */\nint arc_jtag_read_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, uint32_t *buffer)\n{\n\treturn arc_jtag_read_registers(jtag_info, ARC_JTAG_AUX_REG, addr, count,\n\t\t\tbuffer);\n}\n\n/**\n * Write a sequence of 4-byte words into target memory.\n *\n * We can write only 4byte words via JTAG, so any non-word writes should be\n * handled at higher levels by read-modify-write.\n *\n * This function writes directly to the memory, leaving any caches (if there\n * are any) in inconsistent state. It is responsibility of upper level to\n * resolve this.\n *\n * @param jtag_info\n * @param addr\t\tAddress of first word to write into.\n * @param count\t\tAmount of word to write.\n * @param buffer\tArray to write into memory.\n */\nint arc_jtag_write_memory(struct arc_jtag *jtag_info, uint32_t addr,\n\t\tuint32_t count, const uint32_t *buffer)\n{\n\tassert(jtag_info);\n\tassert(buffer);\n\n\tLOG_DEBUG(\"Writing to memory: addr=0x%08\" PRIx32 \";count=%\" PRIu32 \";buffer[0]=0x%08\" PRIx32,\n\t\taddr, count, *buffer);\n\n\t/* No need to waste time on useless operations. */\n\tif (!count)\n\t\treturn ERROR_OK;\n\n\t/* We do not know where we come from. */\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\t/* We want to write to memory. */\n\tarc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_WRITE_TO_MEMORY, TAP_DRPAUSE);\n\n\t/* Set target memory address of the first word. */\n\tarc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG);\n\tarc_jtag_enque_write_dr(jtag_info, addr, TAP_DRPAUSE);\n\n\t/* Start sending words. Address is auto-incremented on 4bytes by HW. */\n\tarc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG);\n\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\tarc_jtag_enque_write_dr(jtag_info, *(buffer + i), TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Read a sequence of 4-byte words from target memory.\n *\n * We can read only 4byte words via JTAG.\n *\n * This function read directly from the memory, so it can read invalid data if\n * data cache hasn't been flushed before hand. It is responsibility of upper\n * level to resolve this.\n *\n * @param jtag_info\n * @param addr\t\tAddress of first word to read from.\n * @param count\t\tAmount of words to read.\n * @param buffer\tArray of words to read into.\n * @param slow_memory\tWhether this is a slow memory (DDR) or fast (CCM).\n */\nint arc_jtag_read_memory(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t count, uint32_t *buffer, bool slow_memory)\n{\n\tuint8_t *data_buf;\n\tuint32_t i;\n\tint retval = ERROR_OK;\n\n\n\tassert(jtag_info);\n\tassert(jtag_info->tap);\n\n\tLOG_DEBUG(\"Reading memory: addr=0x%\" PRIx32 \";count=%\" PRIu32 \";slow=%c\",\n\t\taddr, count, slow_memory ? 'Y' : 'N');\n\n\tif (!count)\n\t\treturn ERROR_OK;\n\n\tdata_buf = calloc(sizeof(uint8_t), count * 4);\n\tarc_jtag_enque_reset_transaction(jtag_info);\n\n\t/* We are reading from memory. */\n\tarc_jtag_enque_set_transaction(jtag_info, ARC_JTAG_READ_FROM_MEMORY, TAP_DRPAUSE);\n\n\t/* Read data */\n\tfor (i = 0; i < count; i++) {\n\t\t/* When several words are read at consequent addresses we can\n\t\t * rely on ARC JTAG auto-incrementing address. That means that\n\t\t * address can be set only once, for a first word. However it\n\t\t * has been noted that at least in some cases when reading from\n\t\t * DDR, JTAG returns 0 instead of a real value. To workaround\n\t\t * this issue we need to do totally non-required address\n\t\t * writes, which however resolve a problem by introducing\n\t\t * delay. See STAR 9000832538... */\n\t\tif (slow_memory || i == 0) {\n\t\t    /* Set address */\n\t\t    arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_ADDRESS_REG);\n\t\t    arc_jtag_enque_write_dr(jtag_info, addr + i * 4, TAP_IDLE);\n\n\t\t    arc_jtag_enque_write_ir(jtag_info, ARC_JTAG_DATA_REG);\n\t\t}\n\t\tarc_jtag_enque_read_dr(jtag_info, data_buf + i * 4, TAP_IDLE);\n\t}\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to execute jtag queue: %d\", retval);\n\t\tretval = ERROR_FAIL;\n\t\tgoto exit;\n\t}\n\n\t/* Convert byte-buffers to host presentation. */\n\tfor (i = 0; i < count; i++)\n\t\tbuffer[i] = buf_get_u32(data_buf + 4*i, 0, 32);\n\nexit:\n\tfree(data_buf);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARC_JTAG_H\n#define OPENOCD_TARGET_ARC_JTAG_H\n\n#define ARC_TRANSACTION_CMD_REG\t\t0x9 /* Command to perform */\n#define ARC_TRANSACTION_CMD_REG_LENGTH\t4\n\n/* Jtag status register, value is placed in IR to read jtag status register */\n#define ARC_JTAG_STATUS_REG\t\t0x8\n#define ARC_JTAG_ADDRESS_REG\t\t0xA /* SoC address to access */\n#define ARC_JTAG_DATA_REG\t\t0xB /* Data read/written from SoC */\n\n/* Jtag status register field */\n#define ARC_JTAG_STAT_RU\t\t0x10\n\n/* ARC Jtag transactions */\n#define ARC_JTAG_WRITE_TO_MEMORY\t0x0\n#define ARC_JTAG_WRITE_TO_CORE_REG\t0x1\n#define ARC_JTAG_WRITE_TO_AUX_REG\t0x2\n#define ARC_JTAG_CMD_NOP\t\t0x3\n#define ARC_JTAG_READ_FROM_MEMORY\t0x4\n#define ARC_JTAG_READ_FROM_CORE_REG\t0x5\n#define ARC_JTAG_READ_FROM_AUX_REG\t0x6\n\n#define ARC_JTAG_CORE_REG\t\t0x0\n#define ARC_JTAG_AUX_REG\t\t0x1\n\n\nstruct arc_jtag {\n\tstruct jtag_tap *tap;\n\tuint32_t cur_trans;\n};\n\n/* ----- Exported JTAG functions ------------------------------------------- */\n\nint arc_jtag_startup(struct arc_jtag *jtag_info);\nint arc_jtag_status(struct arc_jtag *const jtag_info, uint32_t *const value);\n\nint arc_jtag_write_core_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, const uint32_t *buffer);\nint arc_jtag_read_core_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, uint32_t *buffer);\nint arc_jtag_write_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tconst uint32_t buffer);\nint arc_jtag_read_core_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t *buffer);\n\nint arc_jtag_write_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, const uint32_t *buffer);\nint arc_jtag_write_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t value);\nint arc_jtag_read_aux_reg(struct arc_jtag *jtag_info, uint32_t *addr,\n\tuint32_t count, uint32_t *buffer);\nint arc_jtag_read_aux_reg_one(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t *value);\n\nint arc_jtag_write_memory(struct arc_jtag *jtag_info, uint32_t addr,\n\t\tuint32_t count, const uint32_t *buffer);\nint arc_jtag_read_memory(struct arc_jtag *jtag_info, uint32_t addr,\n\tuint32_t count, uint32_t *buffer, bool slow_memory);\n#endif /* OPENOCD_TARGET_ARC_JTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_mem.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Mischa Jonker <mischa.jonker@synopsys.com>                            *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arc.h\"\n\n/* ----- Supporting functions ---------------------------------------------- */\nstatic bool arc_mem_is_slow_memory(struct arc_common *arc, uint32_t addr,\n\tuint32_t size, uint32_t count)\n{\n\tuint32_t addr_end = addr + size * count;\n\t/* `_end` field can overflow - it points to the first byte after the end,\n\t * therefore if DCCM is right at the end of memory address space, then\n\t * dccm_end will be 0. */\n\tassert(addr_end >= addr || addr_end == 0);\n\n\treturn !((addr >= arc->dccm_start && addr_end <= arc->dccm_end) ||\n\t\t(addr >= arc->iccm0_start && addr_end <= arc->iccm0_end) ||\n\t\t(addr >= arc->iccm1_start && addr_end <= arc->iccm1_end));\n}\n\n/* Write word at word-aligned address */\nstatic int arc_mem_write_block32(struct target *target, uint32_t addr,\n\tuint32_t count, void *buf)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tLOG_DEBUG(\"Write 4-byte memory block: addr=0x%08\" PRIx32 \", count=%\" PRIu32,\n\t\t\taddr, count);\n\n\t/* Check arguments */\n\tassert(!(addr & 3));\n\n\t/* We need to flush the cache since it might contain dirty\n\t * lines, so the cache invalidation may cause data inconsistency. */\n\tCHECK_RETVAL(arc_cache_flush(target));\n\n\n\t/* No need to flush cache, because we don't read values from memory. */\n\tCHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, addr, count,\n\t\t\t\t(uint32_t *)buf));\n\n\t/* Invalidate caches. */\n\tCHECK_RETVAL(arc_cache_invalidate(target));\n\n\treturn ERROR_OK;\n}\n\n/* Write half-word at half-word-aligned address */\nstatic int arc_mem_write_block16(struct target *target, uint32_t addr,\n\tuint32_t count, void *buf)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\tuint32_t i;\n\tuint32_t buffer_he;\n\tuint8_t buffer_te[sizeof(uint32_t)];\n\tuint8_t halfword_te[sizeof(uint16_t)];\n\n\tLOG_DEBUG(\"Write 2-byte memory block: addr=0x%08\" PRIx32 \", count=%\" PRIu32,\n\t\t\taddr, count);\n\n\t/* Check arguments */\n\tassert(!(addr & 1));\n\n\t/* We will read data from memory, so we need to flush the cache. */\n\tCHECK_RETVAL(arc_cache_flush(target));\n\n\t/* non-word writes are less common than 4-byte writes, so I suppose we can\n\t * allow ourselves to write this in a cycle, instead of calling arc_jtag\n\t * with count > 1. */\n\tfor (i = 0; i < count; i++) {\n\t\t/* We can read only word at word-aligned address. Also *jtag_read_memory\n\t\t * functions return data in host endianness, so host endianness !=\n\t\t * target endianness we have to convert data back to target endianness,\n\t\t * or bytes will be at the wrong places.So:\n\t\t *   1) read word\n\t\t *   2) convert to target endianness\n\t\t *   3) make changes\n\t\t *   4) convert back to host endianness\n\t\t *   5) write word back to target.\n\t\t */\n\t\tbool is_slow_memory = arc_mem_is_slow_memory(arc,\n\t\t\t(addr + i * sizeof(uint16_t)) & ~3u, 4, 1);\n\t\tCHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info,\n\t\t\t\t(addr + i * sizeof(uint16_t)) & ~3u, 1, &buffer_he,\n\t\t\t\tis_slow_memory));\n\t\ttarget_buffer_set_u32(target, buffer_te, buffer_he);\n\n\t\t/* buf is in host endianness, convert to target */\n\t\ttarget_buffer_set_u16(target, halfword_te, ((uint16_t *)buf)[i]);\n\n\t\tmemcpy(buffer_te  + ((addr + i * sizeof(uint16_t)) & 3u),\n\t\t\thalfword_te, sizeof(uint16_t));\n\n\t\tbuffer_he = target_buffer_get_u32(target, buffer_te);\n\n\t\tCHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info,\n\t\t\t(addr + i * sizeof(uint16_t)) & ~3u, 1, &buffer_he));\n\t}\n\n\t/* Invalidate caches. */\n\tCHECK_RETVAL(arc_cache_invalidate(target));\n\n\treturn ERROR_OK;\n}\n\n/* Write byte at address */\nstatic int arc_mem_write_block8(struct target *target, uint32_t addr,\n\tuint32_t count, void *buf)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\tuint32_t i;\n\tuint32_t buffer_he;\n\tuint8_t buffer_te[sizeof(uint32_t)];\n\n\n\tLOG_DEBUG(\"Write 1-byte memory block: addr=0x%08\" PRIx32 \", count=%\" PRIu32,\n\t\t\taddr, count);\n\n\t/* We will read data from memory, so we need to flush the cache. */\n\tCHECK_RETVAL(arc_cache_flush(target));\n\n\t/* non-word writes are less common than 4-byte writes, so I suppose we can\n\t * allow ourselves to write this in a cycle, instead of calling arc_jtag\n\t * with count > 1. */\n\tfor (i = 0; i < count; i++) {\n\t\t/* See comment in arc_mem_write_block16 for details. Since it is a byte\n\t\t * there is not need to convert write buffer to target endianness, but\n\t\t * we still have to convert read buffer. */\n\t\tCHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, (addr + i) & ~3, 1, &buffer_he,\n\t\t\t    arc_mem_is_slow_memory(arc, (addr + i) & ~3, 4, 1)));\n\t\ttarget_buffer_set_u32(target, buffer_te, buffer_he);\n\t\tmemcpy(buffer_te  + ((addr + i) & 3), (uint8_t *)buf + i, 1);\n\t\tbuffer_he = target_buffer_get_u32(target, buffer_te);\n\t\tCHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, (addr + i) & ~3, 1, &buffer_he));\n\t}\n\n\t/* Invalidate caches. */\n\tCHECK_RETVAL(arc_cache_invalidate(target));\n\n\treturn ERROR_OK;\n}\n\n/* ----- Exported functions ------------------------------------------------ */\nint arc_mem_write(struct target *target, target_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tvoid *tunnel = NULL;\n\n\tLOG_DEBUG(\"address: 0x%08\" TARGET_PRIxADDR \", size: %\" PRIu32 \", count: %\" PRIu32,\n\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* correct endianness if we have word or hword access */\n\tif (size > 1) {\n\t\t/*\n\t\t * arc_..._write_mem with size 4/2 requires uint32_t/uint16_t\n\t\t * in host endianness, but byte array represents target endianness.\n\t\t */\n\t\ttunnel = calloc(1, count * size * sizeof(uint8_t));\n\n\t\tif (!tunnel) {\n\t\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\ttarget_buffer_get_u32_array(target, buffer, count,\n\t\t\t\t(uint32_t *)tunnel);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_get_u16_array(target, buffer, count,\n\t\t\t\t(uint16_t *)tunnel);\n\t\t\tbreak;\n\t\t}\n\t\tbuffer = tunnel;\n\t}\n\n\tif (size == 4) {\n\t\tretval = arc_mem_write_block32(target, address, count, (void *)buffer);\n\t} else if (size == 2) {\n\t\t/* We convert buffer from host endianness to target. But then in\n\t\t * write_block16, we do the reverse. Is there a way to avoid this without\n\t\t * breaking other cases? */\n\t\tretval = arc_mem_write_block16(target, address, count, (void *)buffer);\n\t} else {\n\t\tretval = arc_mem_write_block8(target, address, count, (void *)buffer);\n\t}\n\n\tfree(tunnel);\n\n\treturn retval;\n}\n\nstatic int arc_mem_read_block(struct target *target, target_addr_t addr,\n\tuint32_t size, uint32_t count, void *buf)\n{\n\tstruct arc_common *arc = target_to_arc(target);\n\n\tLOG_DEBUG(\"Read memory: addr=0x%08\" TARGET_PRIxADDR \", size=%\" PRIu32\n\t\t\t\", count=%\" PRIu32, addr, size, count);\n\tassert(!(addr & 3));\n\tassert(size == 4);\n\n\t/* Flush cache before memory access */\n\tCHECK_RETVAL(arc_cache_flush(target));\n\n\tCHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, addr, count, buf,\n\t\t    arc_mem_is_slow_memory(arc, addr, size, count)));\n\n\treturn ERROR_OK;\n}\n\nint arc_mem_read(struct target *target, target_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tvoid *tunnel_he;\n\tuint8_t *tunnel_te;\n\tuint32_t words_to_read, bytes_to_read;\n\n\n\tLOG_DEBUG(\"Read memory: addr=0x%08\" TARGET_PRIxADDR \", size=%\" PRIu32\n\t\t\t\", count=%\" PRIu32, address, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || !(count) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t    return ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* Reads are word-aligned, so padding might be required if count > 1.\n\t * NB: +3 is a padding for the last word (in case it's not aligned;\n\t * addr&3 is a padding for the first word (since address can be\n\t * unaligned as well).  */\n\tbytes_to_read = (count * size + 3 + (address & 3u)) & ~3u;\n\twords_to_read = bytes_to_read >> 2;\n\ttunnel_he = calloc(1, bytes_to_read);\n\ttunnel_te = calloc(1, bytes_to_read);\n\n\tif (!tunnel_he || !tunnel_te) {\n\t\tLOG_ERROR(\"Unable to allocate memory\");\n\t\tfree(tunnel_he);\n\t\tfree(tunnel_te);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* We can read only word-aligned words. */\n\tretval = arc_mem_read_block(target, address & ~3u, sizeof(uint32_t),\n\t\twords_to_read, tunnel_he);\n\n\t/* arc_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */\n\t/* endianness, but byte array should represent target endianness      */\n\n\tif (retval == ERROR_OK) {\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\ttarget_buffer_set_u32_array(target, buffer, count,\n\t\t\t\ttunnel_he);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_set_u32_array(target, tunnel_te,\n\t\t\t\twords_to_read, tunnel_he);\n\t\t\t/* Will that work properly with count > 1 and big endian? */\n\t\t\tmemcpy(buffer, tunnel_te + (address & 3u),\n\t\t\t\tcount * sizeof(uint16_t));\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\ttarget_buffer_set_u32_array(target, tunnel_te,\n\t\t\t\twords_to_read, tunnel_he);\n\t\t\t/* Will that work properly with count > 1 and big endian? */\n\t\t\tmemcpy(buffer, tunnel_te + (address & 3u), count);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tfree(tunnel_he);\n\tfree(tunnel_te);\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arc_mem.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *\n *   Frank Dols <frank.dols@synopsys.com>                                  *\n *   Anton Kolesov <anton.kolesov@synopsys.com>                            *\n *   Evgeniy Didin <didin@synopsys.com>                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARC_MEM_H\n#define OPENOCD_TARGET_ARC_MEM_H\n\n/* ----- Exported functions ------------------------------------------------ */\n\nint arc_mem_read(struct target *target, target_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer);\nint arc_mem_write(struct target *target, target_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer);\n\n\n#endif /* OPENOCD_TARGET_ARC_MEM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2005 by Dominic Rath\n * Dominic.Rath@gmx.de\n *\n * Copyright (C) 2008 by Spencer Oliver\n * spen@spen-soft.co.uk\n *\n * Copyright (C) 2009 by Øyvind Harboe\n * oyvind.harboe@zylin.com\n *\n * Copyright (C) 2018 by Liviu Ionescu\n *   <ilg@livius.net>\n */\n\n#ifndef OPENOCD_TARGET_ARM_H\n#define OPENOCD_TARGET_ARM_H\n\n#include <helper/command.h>\n#include \"target.h\"\n\n/**\n * @file\n * Holds the interface to ARM cores.\n *\n * At this writing, only \"classic ARM\" cores built on the ARMv4 register\n * and mode model are supported.  The Thumb2-only microcontroller profile\n * support has not yet been integrated, affecting Cortex-M parts.\n */\n\n/**\n * Indicates what registers are in the ARM state core register set.\n *\n * - ARM_CORE_TYPE_STD indicates the standard set of 37 registers, seen\n *   on for example ARM7TDMI cores.\n * - ARM_CORE_TYPE_SEC_EXT indicates core has security extensions, thus\n *   three more registers are shadowed for \"Secure Monitor\" mode.\n * - ARM_CORE_TYPE_VIRT_EXT indicates core has virtualization extensions\n *   and also security extensions. Additional shadowed registers for\n *   \"Secure Monitor\" and \"Hypervisor\" modes.\n * - ARM_CORE_TYPE_M_PROFILE indicates a microcontroller profile core,\n *   which only shadows SP.\n */\nenum arm_core_type {\n\tARM_CORE_TYPE_STD = -1,\n\tARM_CORE_TYPE_SEC_EXT = 1,\n\tARM_CORE_TYPE_VIRT_EXT,\n\tARM_CORE_TYPE_M_PROFILE,\n};\n\n/** ARM Architecture specifying the version and the profile */\nenum arm_arch {\n\tARM_ARCH_UNKNOWN,\n\tARM_ARCH_V4,\n\tARM_ARCH_V6M,\n\tARM_ARCH_V7M,\n\tARM_ARCH_V8M,\n};\n\n/**\n * Represent state of an ARM core.\n *\n * Most numbers match the five low bits of the *PSR registers on\n * \"classic ARM\" processors, which build on the ARMv4 processor\n * modes and register set.\n *\n * ARM_MODE_ANY is a magic value, often used as a wildcard.\n *\n * Only the microcontroller cores (ARMv6-M, ARMv7-M) support ARM_MODE_THREAD,\n * ARM_MODE_USER_THREAD, and ARM_MODE_HANDLER.  Those are the only modes\n * they support.\n */\nenum arm_mode {\n\tARM_MODE_USR = 16,\n\tARM_MODE_FIQ = 17,\n\tARM_MODE_IRQ = 18,\n\tARM_MODE_SVC = 19,\n\tARM_MODE_MON = 22,\n\tARM_MODE_ABT = 23,\n\tARM_MODE_HYP = 26,\n\tARM_MODE_UND = 27,\n\tARM_MODE_1176_MON = 28,\n\tARM_MODE_SYS = 31,\n\n\tARM_MODE_THREAD = 0,\n\tARM_MODE_USER_THREAD = 1,\n\tARM_MODE_HANDLER = 2,\n\n\tARMV8_64_EL0T = 0x0,\n\tARMV8_64_EL1T = 0x4,\n\tARMV8_64_EL1H = 0x5,\n\tARMV8_64_EL2T = 0x8,\n\tARMV8_64_EL2H = 0x9,\n\tARMV8_64_EL3T = 0xC,\n\tARMV8_64_EL3H = 0xD,\n\n\tARM_MODE_ANY = -1\n};\n\n/* VFPv3 internal register numbers mapping to d0:31 */\nenum {\n\tARM_VFP_V3_D0 = 51,\n\tARM_VFP_V3_D1,\n\tARM_VFP_V3_D2,\n\tARM_VFP_V3_D3,\n\tARM_VFP_V3_D4,\n\tARM_VFP_V3_D5,\n\tARM_VFP_V3_D6,\n\tARM_VFP_V3_D7,\n\tARM_VFP_V3_D8,\n\tARM_VFP_V3_D9,\n\tARM_VFP_V3_D10,\n\tARM_VFP_V3_D11,\n\tARM_VFP_V3_D12,\n\tARM_VFP_V3_D13,\n\tARM_VFP_V3_D14,\n\tARM_VFP_V3_D15,\n\tARM_VFP_V3_D16,\n\tARM_VFP_V3_D17,\n\tARM_VFP_V3_D18,\n\tARM_VFP_V3_D19,\n\tARM_VFP_V3_D20,\n\tARM_VFP_V3_D21,\n\tARM_VFP_V3_D22,\n\tARM_VFP_V3_D23,\n\tARM_VFP_V3_D24,\n\tARM_VFP_V3_D25,\n\tARM_VFP_V3_D26,\n\tARM_VFP_V3_D27,\n\tARM_VFP_V3_D28,\n\tARM_VFP_V3_D29,\n\tARM_VFP_V3_D30,\n\tARM_VFP_V3_D31,\n\tARM_VFP_V3_FPSCR,\n};\n\nconst char *arm_mode_name(unsigned psr_mode);\nbool is_arm_mode(unsigned psr_mode);\n\n/** The PSR \"T\" and \"J\" bits define the mode of \"classic ARM\" cores. */\nenum arm_state {\n\tARM_STATE_ARM,\n\tARM_STATE_THUMB,\n\tARM_STATE_JAZELLE,\n\tARM_STATE_THUMB_EE,\n\tARM_STATE_AARCH64,\n};\n\n/** ARM vector floating point enabled, if yes which version. */\nenum arm_vfp_version {\n\tARM_VFP_DISABLED,\n\tARM_VFP_V1,\n\tARM_VFP_V2,\n\tARM_VFP_V3,\n};\n\n#define ARM_COMMON_MAGIC 0x0A450A45U\n\n/**\n * Represents a generic ARM core, with standard application registers.\n *\n * There are sixteen application registers (including PC, SP, LR) and a PSR.\n * Cortex-M series cores do not support as many core states or shadowed\n * registers as traditional ARM cores, and only support Thumb2 instructions.\n */\nstruct arm {\n\tunsigned int common_magic;\n\n\tstruct reg_cache *core_cache;\n\n\t/** Handle to the PC; valid in all core modes. */\n\tstruct reg *pc;\n\n\t/** Handle to the CPSR/xPSR; valid in all core modes. */\n\tstruct reg *cpsr;\n\n\t/** Handle to the SPSR; valid only in core modes with an SPSR. */\n\tstruct reg *spsr;\n\n\t/** Support for arm_reg_current() */\n\tconst int *map;\n\n\t/** Indicates what registers are in the ARM state core register set. */\n\tenum arm_core_type core_type;\n\n\t/** Record the current core mode: SVC, USR, or some other mode. */\n\tenum arm_mode core_mode;\n\n\t/** Record the current core state: ARM, Thumb, or otherwise. */\n\tenum arm_state core_state;\n\n\t/** ARM architecture version */\n\tenum arm_arch arch;\n\n\t/** Floating point or VFP version, 0 if disabled. */\n\tint arm_vfp_version;\n\n\tint (*setup_semihosting)(struct target *target, int enable);\n\n\t/** Backpointer to the target. */\n\tstruct target *target;\n\n\t/** Handle for the debug module, if one is present. */\n\tstruct arm_dpm *dpm;\n\n\t/** Handle for the Embedded Trace Module, if one is present. */\n\tstruct etm_context *etm;\n\n\t/* FIXME all these methods should take \"struct arm *\" not target */\n\n\t/** Retrieve all core registers, for display. */\n\tint (*full_context)(struct target *target);\n\n\t/** Retrieve a single core register. */\n\tint (*read_core_reg)(struct target *target, struct reg *reg,\n\t\t\tint num, enum arm_mode mode);\n\tint (*write_core_reg)(struct target *target, struct reg *reg,\n\t\t\tint num, enum arm_mode mode, uint8_t *value);\n\n\t/** Read coprocessor register.  */\n\tint (*mrc)(struct target *target, int cpnum,\n\t\t\tuint32_t op1, uint32_t op2,\n\t\t\tuint32_t crn, uint32_t crm,\n\t\t\tuint32_t *value);\n\n\t/** Write coprocessor register.  */\n\tint (*mcr)(struct target *target, int cpnum,\n\t\t\tuint32_t op1, uint32_t op2,\n\t\t\tuint32_t crn, uint32_t crm,\n\t\t\tuint32_t value);\n\n\tvoid *arch_info;\n\n\t/** For targets conforming to ARM Debug Interface v5,\n\t * this handle references the Debug Access Port (DAP)\n\t * used to make requests to the target.\n\t */\n\tstruct adiv5_dap *dap;\n};\n\n/** Convert target handle to generic ARM target state handle. */\nstatic inline struct arm *target_to_arm(struct target *target)\n{\n\tassert(target);\n\treturn target->arch_info;\n}\n\nstatic inline bool is_arm(struct arm *arm)\n{\n\tassert(arm);\n\treturn arm->common_magic == ARM_COMMON_MAGIC;\n}\n\nstruct arm_algorithm {\n\tunsigned int common_magic;\n\n\tenum arm_mode core_mode;\n\tenum arm_state core_state;\n};\n\nstruct arm_reg {\n\tint num;\n\tenum arm_mode mode;\n\tstruct target *target;\n\tstruct arm *arm;\n\tuint8_t value[16];\n};\n\nstruct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm);\nvoid arm_free_reg_cache(struct arm *arm);\n\nstruct reg_cache *armv8_build_reg_cache(struct target *target);\n\nextern const struct command_registration arm_command_handlers[];\nextern const struct command_registration arm_all_profiles_command_handlers[];\n\nint arm_arch_state(struct target *target);\nconst char *arm_get_gdb_arch(struct target *target);\nint arm_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\nconst char *armv8_get_gdb_arch(struct target *target);\nint armv8_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\n\nint arm_init_arch_info(struct target *target, struct arm *arm);\n\n/* REVISIT rename this once it's usable by ARMv7-M */\nint armv4_5_run_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info);\nint armv4_5_run_algorithm_inner(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\tuint32_t entry_point, uint32_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info,\n\t\tint (*run_it)(struct target *target, uint32_t exit_point,\n\t\t\t\tunsigned int timeout_ms, void *arch_info));\n\nint arm_checksum_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t count, uint32_t *checksum);\nint arm_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);\n\nvoid arm_set_cpsr(struct arm *arm, uint32_t cpsr);\nstruct reg *arm_reg_current(struct arm *arm, unsigned regnum);\nstruct reg *armv8_reg_current(struct arm *arm, unsigned regnum);\n\n#endif /* OPENOCD_TARGET_ARM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm11.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 digenius technology GmbH.                          *\n *   Michael Bruck                                                         *\n *                                                                         *\n *   Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com         *\n *                                                                         *\n *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *\n *                                                                         *\n *   Copyright (C) 2009 David Brownell                                     *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"etm.h\"\n#include \"breakpoints.h\"\n#include \"arm11_dbgtap.h\"\n#include \"arm_simulator.h\"\n#include <helper/time_support.h>\n#include \"target_type.h\"\n#include \"algorithm.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\n\nstatic int arm11_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints);\n\n\n/** Check and if necessary take control of the system\n *\n * \\param arm11\t\tTarget state variable.\n */\nstatic int arm11_check_init(struct arm11_common *arm11)\n{\n\tCHECK_RETVAL(arm11_read_dscr(arm11));\n\n\tif (!(arm11->dscr & DSCR_HALT_DBG_MODE)) {\n\t\tLOG_DEBUG(\"DSCR %08x\", (unsigned) arm11->dscr);\n\t\tLOG_DEBUG(\"Bringing target into debug mode\");\n\n\t\tarm11->dscr |= DSCR_HALT_DBG_MODE;\n\t\tCHECK_RETVAL(arm11_write_dscr(arm11, arm11->dscr));\n\n\t\t/* add further reset initialization here */\n\n\t\tarm11->simulate_reset_on_next_halt = true;\n\n\t\tif (arm11->dscr & DSCR_CORE_HALTED) {\n\t\t\t/** \\todo TODO: this needs further scrutiny because\n\t\t\t  * arm11_debug_entry() never gets called.  (WHY NOT?)\n\t\t\t  * As a result we don't read the actual register states from\n\t\t\t  * the target.\n\t\t\t  */\n\n\t\t\tarm11->arm.target->state = TARGET_HALTED;\n\t\t\tarm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);\n\t\t} else {\n\t\t\tarm11->arm.target->state = TARGET_RUNNING;\n\t\t\tarm11->arm.target->debug_reason = DBG_REASON_NOTHALTED;\n\t\t}\n\n\t\tCHECK_RETVAL(arm11_sc7_clear_vbw(arm11));\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Save processor state.  This is called after a HALT instruction\n * succeeds, and on other occasions the processor enters debug mode\n * (breakpoint, watchpoint, etc).  Caller has updated arm11->dscr.\n */\nstatic int arm11_debug_entry(struct arm11_common *arm11)\n{\n\tint retval;\n\n\tarm11->arm.target->state = TARGET_HALTED;\n\tarm_dpm_report_dscr(arm11->arm.dpm, arm11->dscr);\n\n\t/* REVISIT entire cache should already be invalid !!! */\n\tregister_cache_invalidate(arm11->arm.core_cache);\n\n\t/* See e.g. ARM1136 TRM, \"14.8.4 Entering Debug state\" */\n\n\t/* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */\n\tarm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL);\n\tif (arm11->is_wdtr_saved) {\n\t\tarm11_add_debug_scan_n(arm11, 0x05, ARM11_TAP_DEFAULT);\n\n\t\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\t\tstruct scan_field chain5_fields[3];\n\n\t\tarm11_setup_field(arm11, 32, NULL,\n\t\t\t&arm11->saved_wdtr, chain5_fields + 0);\n\t\tarm11_setup_field(arm11,  1, NULL, NULL, chain5_fields + 1);\n\t\tarm11_setup_field(arm11,  1, NULL, NULL, chain5_fields + 2);\n\n\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\t\tchain5_fields), chain5_fields, TAP_DRPAUSE);\n\n\t}\n\n\t/* DSCR: set the Execute ARM instruction enable bit.\n\t *\n\t * ARM1176 spec says this is needed only for wDTR/rDTR's \"ITR mode\",\n\t * but not to issue ITRs(?).  The ARMv7 arch spec says it's required\n\t * for executing instructions via ITR.\n\t */\n\tCHECK_RETVAL(arm11_write_dscr(arm11, DSCR_ITR_EN | arm11->dscr));\n\n\n\t/* From the spec:\n\t   Before executing any instruction in debug state you have to drain the write buffer.\n\t   This ensures that no imprecise Data Aborts can return at a later point:*/\n\n\t/** \\todo TODO: Test drain write buffer. */\n\n#if 0\n\twhile (1) {\n\t\t/* MRC p14,0,R0,c5,c10,0 */\n\t\t/*\tarm11_run_instr_no_data1(arm11, / *0xee150e1a* /0xe320f000); */\n\n\t\t/* mcr\t   15, 0, r0, cr7, cr10, {4} */\n\t\tarm11_run_instr_no_data1(arm11, 0xee070f9a);\n\n\t\tuint32_t dscr = arm11_read_dscr(arm11);\n\n\t\tLOG_DEBUG(\"DRAIN, DSCR %08x\", dscr);\n\n\t\tif (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) {\n\t\t\tarm11_run_instr_no_data1(arm11, 0xe320f000);\n\n\t\t\tdscr = arm11_read_dscr(arm11);\n\n\t\t\tLOG_DEBUG(\"DRAIN, DSCR %08x (DONE)\", dscr);\n\n\t\t\tbreak;\n\t\t}\n\t}\n#endif\n\n\t/* Save registers.\n\t *\n\t * NOTE:  ARM1136 TRM suggests saving just R0 here now, then\n\t * CPSR and PC after the rDTR stuff.  We do it all at once.\n\t */\n\tretval = arm_dpm_read_current_registers(&arm11->dpm);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"DPM REG READ -- fail\");\n\n\tretval = arm11_run_instr_data_prepare(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* maybe save rDTR (pending DCC read from debug SW, e.g. libdcc) */\n\tarm11->is_rdtr_saved = !!(arm11->dscr & DSCR_DTR_RX_FULL);\n\tif (arm11->is_rdtr_saved) {\n\t\t/* MRC p14,0,R0,c0,c5,0 (move rDTR -> r0 (-> wDTR -> local var)) */\n\t\tretval = arm11_run_instr_data_from_core_via_r0(arm11,\n\t\t\t\t0xEE100E15, &arm11->saved_rdtr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* REVISIT Now that we've saved core state, there's may also\n\t * be MMU and cache state to care about ...\n\t */\n\n\tif (arm11->simulate_reset_on_next_halt) {\n\t\tarm11->simulate_reset_on_next_halt = false;\n\n\t\tLOG_DEBUG(\"Reset c1 Control Register\");\n\n\t\t/* Write 0 (reset value) to Control register 0 to disable MMU/Cache etc. */\n\n\t\t/* MCR p15,0,R0,c1,c0,0 */\n\t\tretval = arm11_run_instr_data_to_core_via_r0(arm11, 0xee010f10, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t}\n\n\tif (arm11->arm.target->debug_reason == DBG_REASON_WATCHPOINT) {\n\t\tuint32_t wfar;\n\n\t\t/* MRC p15, 0, <Rd>, c6, c0, 1 ; Read WFAR */\n\t\tretval = arm11_run_instr_data_from_core_via_r0(arm11,\n\t\t\t\tARMV4_5_MRC(15, 0, 0, 6, 0, 1),\n\t\t\t\t&wfar);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarm_dpm_report_wfar(arm11->arm.dpm, wfar);\n\t}\n\n\n\tretval = arm11_run_instr_data_finish(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Restore processor state.  This is called in preparation for\n * the RESTART function.\n */\nstatic int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp)\n{\n\tint retval;\n\n\t/* See e.g. ARM1136 TRM, \"14.8.5 Leaving Debug state\" */\n\n\t/* NOTE:  the ARM1136 TRM suggests restoring all registers\n\t * except R0/PC/CPSR right now.  Instead, we do them all\n\t * at once, just a bit later on.\n\t */\n\n\t/* REVISIT once we start caring about MMU and cache state,\n\t * address it here ...\n\t */\n\n\t/* spec says clear wDTR and rDTR; we assume they are clear as\n\t   otherwise our programming would be sloppy */\n\t{\n\t\tCHECK_RETVAL(arm11_read_dscr(arm11));\n\n\t\tif (arm11->dscr & (DSCR_DTR_RX_FULL | DSCR_DTR_TX_FULL)) {\n\t\t\t/*\n\t\t\tThe wDTR/rDTR two registers that are used to send/receive data to/from\n\t\t\tthe core in tandem with corresponding instruction codes that are\n\t\t\twritten into the core. The RDTR FULL/WDTR FULL flag indicates that the\n\t\t\tregisters hold data that was written by one side (CPU or JTAG) and not\n\t\t\tread out by the other side.\n\t\t\t*/\n\t\t\tLOG_ERROR(\"wDTR/rDTR inconsistent (DSCR %08x)\",\n\t\t\t\t(unsigned) arm11->dscr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* maybe restore original wDTR */\n\tif (arm11->is_wdtr_saved) {\n\t\tretval = arm11_run_instr_data_prepare(arm11);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* MCR p14,0,R0,c0,c5,0 */\n\t\tretval = arm11_run_instr_data_to_core_via_r0(arm11,\n\t\t\t\t0xee000e15, arm11->saved_wdtr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = arm11_run_instr_data_finish(arm11);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* restore CPSR, PC, and R0 ... after flushing any modified\n\t * registers.\n\t */\n\tCHECK_RETVAL(arm_dpm_write_dirty_registers(&arm11->dpm, bpwp));\n\n\tCHECK_RETVAL(arm11_bpwp_flush(arm11));\n\n\tregister_cache_invalidate(arm11->arm.core_cache);\n\n\t/* restore DSCR */\n\tCHECK_RETVAL(arm11_write_dscr(arm11, arm11->dscr));\n\n\t/* maybe restore rDTR */\n\tif (arm11->is_rdtr_saved) {\n\t\tarm11_add_debug_scan_n(arm11, 0x05, ARM11_TAP_DEFAULT);\n\n\t\tarm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);\n\n\t\tstruct scan_field chain5_fields[3];\n\n\t\tuint8_t ready           = 0;\t\t\t/* ignored */\n\t\tuint8_t valid           = 0;\t\t\t/* ignored */\n\n\t\tarm11_setup_field(arm11, 32, &arm11->saved_rdtr,\n\t\t\tNULL, chain5_fields + 0);\n\t\tarm11_setup_field(arm11,  1, &ready,    NULL, chain5_fields + 1);\n\t\tarm11_setup_field(arm11,  1, &valid,    NULL, chain5_fields + 2);\n\n\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\t\tchain5_fields), chain5_fields, TAP_DRPAUSE);\n\t}\n\n\t/* now processor is ready to RESTART */\n\n\treturn ERROR_OK;\n}\n\n/* poll current target status */\nstatic int arm11_poll(struct target *target)\n{\n\tint retval;\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tCHECK_RETVAL(arm11_check_init(arm11));\n\n\tif (arm11->dscr & DSCR_CORE_HALTED) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tenum target_state old_state = target->state;\n\n\t\t\tLOG_DEBUG(\"enter TARGET_HALTED\");\n\t\t\tretval = arm11_debug_entry(arm11);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target,\n\t\t\t\t(old_state == TARGET_DEBUG_RUNNING)\n\t\t\t\t? TARGET_EVENT_DEBUG_HALTED\n\t\t\t\t: TARGET_EVENT_HALTED);\n\t\t}\n\t} else {\n\t\tif (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) {\n\t\t\tLOG_DEBUG(\"enter TARGET_RUNNING\");\n\t\t\ttarget->state                   = TARGET_RUNNING;\n\t\t\ttarget->debug_reason    = DBG_REASON_NOTHALTED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n/* architecture specific status reply */\nstatic int arm11_arch_state(struct target *target)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\tint retval;\n\n\tretval = arm_arch_state(target);\n\n\t/* REVISIT also display ARM11-specific MMU and cache status ... */\n\n\tif (target->debug_reason == DBG_REASON_WATCHPOINT)\n\t\tLOG_USER(\"Watchpoint triggered at PC \" TARGET_ADDR_FMT, arm11->dpm.wp_addr);\n\n\treturn retval;\n}\n\n/* target execution control */\nstatic int arm11_halt(struct target *target)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tarm11->simulate_reset_on_next_halt = true;\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tarm11_add_ir(arm11, ARM11_HALT, TAP_IDLE);\n\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\tint i = 0;\n\n\twhile (1) {\n\t\tCHECK_RETVAL(arm11_read_dscr(arm11));\n\n\t\tif (arm11->dscr & DSCR_CORE_HALTED)\n\t\t\tbreak;\n\n\n\t\tint64_t then = 0;\n\t\tif (i == 1000)\n\t\t\tthen = timeval_ms();\n\t\tif (i >= 1000) {\n\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\tLOG_WARNING(\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\n\tenum target_state old_state     = target->state;\n\n\tCHECK_RETVAL(arm11_debug_entry(arm11));\n\n\tCHECK_RETVAL(\n\t\ttarget_call_event_callbacks(target,\n\t\t\told_state ==\n\t\t\tTARGET_DEBUG_RUNNING ? TARGET_EVENT_DEBUG_HALTED : TARGET_EVENT_HALTED));\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t address)\n{\n\tvoid *value = arm11->arm.pc->value;\n\n\t/* use the current program counter */\n\tif (current)\n\t\taddress = buf_get_u32(value, 0, 32);\n\n\t/* Make sure that the gdb thumb fixup does not\n\t * kill the return address\n\t */\n\tswitch (arm11->arm.core_state) {\n\t\tcase ARM_STATE_ARM:\n\t\t\taddress &= 0xFFFFFFFC;\n\t\t\tbreak;\n\t\tcase ARM_STATE_THUMB:\n\t\t\t/* When the return address is loaded into PC\n\t\t\t * bit 0 must be 1 to stay in Thumb state\n\t\t\t */\n\t\t\taddress |= 0x1;\n\t\t\tbreak;\n\n\t\t/* catch-all for JAZELLE and THUMB_EE */\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\tbuf_set_u32(value, 0, 32, address);\n\tarm11->arm.pc->dirty = true;\n\tarm11->arm.pc->valid = true;\n\n\treturn address;\n}\n\nstatic int arm11_resume(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\t/*\t  LOG_DEBUG(\"current %d  address %08x  handle_breakpoints %d  debug_execution %d\", */\n\t/*\tcurrent, address, handle_breakpoints, debug_execution); */\n\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\taddress = arm11_nextpc(arm11, current, address);\n\n\tLOG_DEBUG(\"RESUME PC %08\" TARGET_PRIxADDR \"%s\", address, !current ? \"!\" : \"\");\n\n\t/* clear breakpoints/watchpoints and VCR*/\n\tCHECK_RETVAL(arm11_sc7_clear_vbw(arm11));\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n\t/* Should we skip over breakpoints matching the PC? */\n\tif (handle_breakpoints) {\n\t\tstruct breakpoint *bp;\n\n\t\tfor (bp = target->breakpoints; bp; bp = bp->next) {\n\t\t\tif (bp->address == address) {\n\t\t\t\tLOG_DEBUG(\"must step over %08\" TARGET_PRIxADDR \"\", bp->address);\n\t\t\t\tarm11_step(target, 1, 0, 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* activate all breakpoints */\n\tif (true) {\n\t\tstruct breakpoint *bp;\n\t\tunsigned brp_num = 0;\n\n\t\tfor (bp = target->breakpoints; bp; bp = bp->next) {\n\t\t\tstruct arm11_sc7_action brp[2];\n\n\t\t\tbrp[0].write    = 1;\n\t\t\tbrp[0].address  = ARM11_SC7_BVR0 + brp_num;\n\t\t\tbrp[0].value    = bp->address;\n\t\t\tbrp[1].write    = 1;\n\t\t\tbrp[1].address  = ARM11_SC7_BCR0 + brp_num;\n\t\t\tbrp[1].value    = 0x1 |\n\t\t\t\t(3 <<\n\t\t\t\t 1) | (0x0F << 5) | (0 << 14) | (0 << 16) | (0 << 20) | (0 << 21);\n\n\t\t\tCHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));\n\n\t\t\tLOG_DEBUG(\"Add BP %d at %08\" TARGET_PRIxADDR, brp_num,\n\t\t\t\tbp->address);\n\n\t\t\tbrp_num++;\n\t\t}\n\n\t\tif (arm11->vcr)\n\t\t\tCHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr));\n\t}\n\n\t/* activate all watchpoints and breakpoints */\n\tCHECK_RETVAL(arm11_leave_debug_state(arm11, true));\n\n\tarm11_add_ir(arm11, ARM11_RESTART, TAP_IDLE);\n\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\tint i = 0;\n\twhile (1) {\n\t\tCHECK_RETVAL(arm11_read_dscr(arm11));\n\n\t\tLOG_DEBUG(\"DSCR %08x\", (unsigned) arm11->dscr);\n\n\t\tif (arm11->dscr & DSCR_CORE_RESTARTED)\n\t\t\tbreak;\n\n\n\t\tint64_t then = 0;\n\t\tif (i == 1000)\n\t\t\tthen = timeval_ms();\n\t\tif (i >= 1000) {\n\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\tLOG_WARNING(\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\ti++;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\tif (!debug_execution)\n\t\ttarget->state = TARGET_RUNNING;\n\telse\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_RESUMED));\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_step(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints)\n{\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target was not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\taddress = arm11_nextpc(arm11, current, address);\n\n\tLOG_DEBUG(\"STEP PC %08\" TARGET_PRIxADDR \"%s\", address, !current ? \"!\" : \"\");\n\n\n\t/** \\todo TODO: Thumb not supported here */\n\n\tuint32_t next_instruction;\n\n\tCHECK_RETVAL(arm11_read_memory_word(arm11, address, &next_instruction));\n\n\t/* skip over BKPT */\n\tif ((next_instruction & 0xFFF00070) == 0xe1200070) {\n\t\taddress = arm11_nextpc(arm11, 0, address + 4);\n\t\tLOG_DEBUG(\"Skipping BKPT %08\" TARGET_PRIxADDR, address);\n\t}\n\t/* skip over Wait for interrupt / Standby\n\t * mcr\t15, 0, r?, cr7, cr0, {4} */\n\telse if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) {\n\t\taddress = arm11_nextpc(arm11, 0, address + 4);\n\t\tLOG_DEBUG(\"Skipping WFI %08\" TARGET_PRIxADDR, address);\n\t}\n\t/* ignore B to self */\n\telse if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)\n\t\tLOG_DEBUG(\"Not stepping jump to self\");\n\telse {\n\t\t/** \\todo TODO: check if break-/watchpoints make any sense at all in combination\n\t\t* with this. */\n\n\t\t/** \\todo TODO: check if disabling IRQs might be a good idea here. Alternatively\n\t\t* the VCR might be something worth looking into. */\n\n\n\t\t/* Set up breakpoint for stepping */\n\n\t\tstruct arm11_sc7_action brp[2];\n\n\t\tbrp[0].write    = 1;\n\t\tbrp[0].address  = ARM11_SC7_BVR0;\n\t\tbrp[1].write    = 1;\n\t\tbrp[1].address  = ARM11_SC7_BCR0;\n\n\t\tif (arm11->hardware_step) {\n\t\t\t/* Hardware single stepping (\"instruction address\n\t\t\t * mismatch\") is used if enabled.  It's not quite\n\t\t\t * exactly \"run one instruction\"; \"branch to here\"\n\t\t\t * loops won't break, neither will some other cases,\n\t\t\t * but it's probably the best default.\n\t\t\t *\n\t\t\t * Hardware single stepping isn't supported on v6\n\t\t\t * debug modules.  ARM1176 and v7 can support it...\n\t\t\t *\n\t\t\t * FIXME Thumb stepping likely needs to use 0x03\n\t\t\t * or 0xc0 byte masks, not 0x0f.\n\t\t\t */\n\t\t\tbrp[0].value   = address;\n\t\t\tbrp[1].value   = 0x1 | (3 << 1) | (0x0F << 5)\n\t\t\t\t| (0 << 14) | (0 << 16) | (0 << 20)\n\t\t\t\t| (2 << 21);\n\t\t} else {\n\t\t\t/* Sets a breakpoint on the next PC, as calculated\n\t\t\t * by instruction set simulation.\n\t\t\t *\n\t\t\t * REVISIT stepping Thumb on ARM1156 requires Thumb2\n\t\t\t * support from the simulator.\n\t\t\t */\n\t\t\tuint32_t next_pc;\n\t\t\tint retval;\n\n\t\t\tretval = arm_simulate_step(target, &next_pc);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tbrp[0].value    = next_pc;\n\t\t\tbrp[1].value    = 0x1 | (3 << 1) | (0x0F << 5)\n\t\t\t\t| (0 << 14) | (0 << 16) | (0 << 20)\n\t\t\t\t| (0 << 21);\n\t\t}\n\n\t\tCHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));\n\n\t\t/* resume */\n\n\n\t\tif (arm11->step_irq_enable)\n\t\t\t/* this disable should be redundant ... */\n\t\t\tarm11->dscr &= ~DSCR_INT_DIS;\n\t\telse\n\t\t\tarm11->dscr |= DSCR_INT_DIS;\n\n\n\t\tCHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints));\n\n\t\tarm11_add_ir(arm11, ARM11_RESTART, TAP_IDLE);\n\n\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\t/* wait for halt */\n\t\tint i = 0;\n\n\t\twhile (1) {\n\t\t\tconst uint32_t mask = DSCR_CORE_RESTARTED\n\t\t\t\t| DSCR_CORE_HALTED;\n\n\t\t\tCHECK_RETVAL(arm11_read_dscr(arm11));\n\t\t\tLOG_DEBUG(\"DSCR %08x e\", (unsigned) arm11->dscr);\n\n\t\t\tif ((arm11->dscr & mask) == mask)\n\t\t\t\tbreak;\n\n\t\t\tlong long then = 0;\n\t\t\tif (i == 1000)\n\t\t\t\tthen = timeval_ms();\n\t\t\tif (i >= 1000) {\n\t\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t\ti++;\n\t\t}\n\n\t\t/* clear breakpoint */\n\t\tCHECK_RETVAL(arm11_sc7_clear_vbw(arm11));\n\n\t\t/* save state */\n\t\tCHECK_RETVAL(arm11_debug_entry(arm11));\n\n\t\t/* restore default state */\n\t\tarm11->dscr &= ~DSCR_INT_DIS;\n\n\t}\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tCHECK_RETVAL(target_call_event_callbacks(target, TARGET_EVENT_HALTED));\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_assert_reset(struct target *target)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tif (!(target_was_examined(target))) {\n\t\tif (jtag_get_reset_config() & RESET_HAS_SRST)\n\t\t\tjtag_add_reset(0, 1);\n\t\telse {\n\t\t\tLOG_WARNING(\"Reset is not asserted because the target is not examined.\");\n\t\t\tLOG_WARNING(\"Use a reset button or power cycle the target.\");\n\t\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t\t}\n\t} else {\n\n\t\t/* optionally catch reset vector */\n\t\tif (target->reset_halt && !(arm11->vcr & 1))\n\t\t\tCHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));\n\n\t\t/* Issue some kind of warm reset. */\n\t\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))\n\t\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\t\telse if (jtag_get_reset_config() & RESET_HAS_SRST) {\n\t\t\t/* REVISIT handle \"pulls\" cases, if there's\n\t\t\t * hardware that needs them to work.\n\t\t\t */\n\t\t\tjtag_add_reset(0, 1);\n\t\t} else {\n\t\t\tLOG_ERROR(\"%s: how to reset?\", target_name(target));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arm11->arm.core_cache);\n\n\ttarget->state = TARGET_RESET;\n\n\treturn ERROR_OK;\n}\n\n/*\n * - There is another bug in the arm11 core.  (iMX31 specific again?)\n *   When you generate an access to external logic (for example DDR\n *   controller via AHB bus) and that block is not configured (perhaps\n *   it is still held in reset), that transaction will never complete.\n *   This will hang arm11 core but it will also hang JTAG controller.\n *   Nothing short of srst assertion will bring it out of this.\n */\n\nstatic int arm11_deassert_reset(struct target *target)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\tint retval;\n\n\t/* be certain SRST is off */\n\tjtag_add_reset(0, 0);\n\n\t/* WORKAROUND i.MX31 problems:  SRST goofs the TAP, and resets\n\t * at least DSCR.  OMAP24xx doesn't show that problem, though\n\t * SRST-only reset seems to be problematic for other reasons.\n\t * (Secure boot sequences being one likelihood!)\n\t */\n\tjtag_add_tlr();\n\n\tCHECK_RETVAL(arm11_poll(target));\n\n\tif (target->reset_halt) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_WARNING(\"%s: ran after reset and before halt ...\",\n\t\t\t\ttarget_name(target));\n\t\t\tretval = target_halt(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* maybe restore vector catch config */\n\tif (target->reset_halt && !(arm11->vcr & 1))\n\t\tCHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr));\n\n\treturn ERROR_OK;\n}\n\n/* target memory access\n * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)\n * count: number of items of <size>\n *\n * arm11_config_memrw_no_increment - in the future we may want to be able\n * to read/write a range of data to a \"port\". a \"port\" is an action on\n * read memory address for some peripheral.\n */\nstatic int arm11_read_memory_inner(struct target *target,\n\tuint32_t address, uint32_t size, uint32_t count, uint8_t *buffer,\n\tbool arm11_config_memrw_no_increment)\n{\n\t/** \\todo TODO: check if buffer cast to uint32_t* and uint16_t* might cause alignment\n\t *problems */\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target was not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"ADDR %08\" PRIx32 \"  SIZE %08\" PRIx32 \"  COUNT %08\" PRIx32 \"\",\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tretval = arm11_run_instr_data_prepare(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* MRC p14,0,r0,c0,c5,0 */\n\tretval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswitch (size) {\n\t\tcase 1:\n\t\t\tarm11->arm.core_cache->reg_list[1].dirty = true;\n\n\t\t\tfor (size_t i = 0; i < count; i++) {\n\t\t\t\t/* ldrb    r1, [r0], #1 */\n\t\t\t\t/* ldrb    r1, [r0] */\n\t\t\t\tCHECK_RETVAL(arm11_run_instr_no_data1(arm11,\n\t\t\t\t\t\t!arm11_config_memrw_no_increment ? 0xe4d01001 : 0xe5d01000));\n\n\t\t\t\tuint32_t res;\n\t\t\t\t/* MCR p14,0,R1,c0,c5,0 */\n\t\t\t\tCHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1));\n\n\t\t\t\t*buffer++ = res;\n\t\t\t}\n\n\t\t\tbreak;\n\n\t\tcase 2:\n\t\t{\n\t\t\tarm11->arm.core_cache->reg_list[1].dirty = true;\n\n\t\t\tfor (size_t i = 0; i < count; i++) {\n\t\t\t\t/* ldrh    r1, [r0], #2 */\n\t\t\t\tCHECK_RETVAL(arm11_run_instr_no_data1(arm11,\n\t\t\t\t\t\t!arm11_config_memrw_no_increment ? 0xe0d010b2 : 0xe1d010b0));\n\n\t\t\t\tuint32_t res;\n\n\t\t\t\t/* MCR p14,0,R1,c0,c5,0 */\n\t\t\t\tCHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xEE001E15, &res, 1));\n\n\t\t\t\tuint16_t svalue = res;\n\t\t\t\tmemcpy(buffer + i * sizeof(uint16_t), &svalue, sizeof(uint16_t));\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 4:\n\t\t{\n\t\t\tuint32_t instr = !arm11_config_memrw_no_increment ? 0xecb05e01 : 0xed905e00;\n\t\t\t/** \\todo TODO: buffer cast to uint32_t* causes alignment warnings */\n\t\t\tuint32_t *words = (uint32_t *)(void *)buffer;\n\n\t\t\t/* LDC p14,c5,[R0],#4 */\n\t\t\t/* LDC p14,c5,[R0] */\n\t\t\tCHECK_RETVAL(arm11_run_instr_data_from_core(arm11, instr, words, count));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn arm11_run_instr_data_finish(arm11);\n}\n\nstatic int arm11_read_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tuint8_t *buffer)\n{\n\treturn arm11_read_memory_inner(target, address, size, count, buffer, false);\n}\n\n/*\n* no_increment - in the future we may want to be able\n* to read/write a range of data to a \"port\". a \"port\" is an action on\n* read memory address for some peripheral.\n*/\nstatic int arm11_write_memory_inner(struct target *target,\n\tuint32_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer,\n\tbool no_increment)\n{\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target was not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tLOG_DEBUG(\"ADDR %08\" PRIx32 \"  SIZE %08\" PRIx32 \"  COUNT %08\" PRIx32 \"\",\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tretval = arm11_run_instr_data_prepare(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* load r0 with buffer address\n\t * MRC p14,0,r0,c0,c5,0 */\n\tretval = arm11_run_instr_data_to_core1(arm11, 0xee100e15, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* burst writes are not used for single words as those may well be\n\t * reset init script writes.\n\t *\n\t * The other advantage is that as burst writes are default, we'll\n\t * now exercise both burst and non-burst code paths with the\n\t * default settings, increasing code coverage.\n\t */\n\tbool burst = arm11->memwrite_burst && (count > 1);\n\n\tswitch (size) {\n\t\tcase 1:\n\t\t{\n\t\t\tarm11->arm.core_cache->reg_list[1].dirty = true;\n\n\t\t\tfor (size_t i = 0; i < count; i++) {\n\t\t\t\t/* load r1 from DCC with byte data */\n\t\t\t\t/* MRC p14,0,r1,c0,c5,0 */\n\t\t\t\tretval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, *buffer++);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\t/* write r1 to memory */\n\t\t\t\t/* strb    r1, [r0], #1 */\n\t\t\t\t/* strb    r1, [r0] */\n\t\t\t\tretval = arm11_run_instr_no_data1(arm11,\n\t\t\t\t\t\t!no_increment ? 0xe4c01001 : 0xe5c01000);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 2:\n\t\t{\n\t\t\tarm11->arm.core_cache->reg_list[1].dirty = true;\n\n\t\t\tfor (size_t i = 0; i < count; i++) {\n\t\t\t\tuint16_t value;\n\t\t\t\tmemcpy(&value, buffer + i * sizeof(uint16_t), sizeof(uint16_t));\n\n\t\t\t\t/* load r1 from DCC with halfword data */\n\t\t\t\t/* MRC p14,0,r1,c0,c5,0 */\n\t\t\t\tretval = arm11_run_instr_data_to_core1(arm11, 0xee101e15, value);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\t/* write r1 to memory */\n\t\t\t\t/* strh    r1, [r0], #2 */\n\t\t\t\t/* strh    r1, [r0] */\n\t\t\t\tretval = arm11_run_instr_no_data1(arm11,\n\t\t\t\t\t\t!no_increment ? 0xe0c010b2 : 0xe1c010b0);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 4: {\n\t\t\t/* stream word data through DCC directly to memory */\n\t\t\t/* increment:\t\tSTC p14,c5,[R0],#4 */\n\t\t\t/* no increment:\tSTC p14,c5,[R0]*/\n\t\t\tuint32_t instr = !no_increment ? 0xeca05e01 : 0xed805e00;\n\n\t\t\t/** \\todo TODO: buffer cast to uint32_t* causes alignment warnings */\n\t\t\tuint32_t *words = (uint32_t *)(void *)buffer;\n\n\t\t\t/* \"burst\" here just means trusting each instruction executes\n\t\t\t * fully before we run the next one:  per-word roundtrips, to\n\t\t\t * check the Ready flag, are not used.\n\t\t\t */\n\t\t\tif (!burst)\n\t\t\t\tretval = arm11_run_instr_data_to_core(arm11,\n\t\t\t\t\t\tinstr, words, count);\n\t\t\telse\n\t\t\t\tretval = arm11_run_instr_data_to_core_noack(arm11,\n\t\t\t\t\t\tinstr, words, count);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* r0 verification */\n\tif (!no_increment) {\n\t\tuint32_t r0;\n\n\t\t/* MCR p14,0,R0,c0,c5,0 */\n\t\tretval = arm11_run_instr_data_from_core(arm11, 0xEE000E15, &r0, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (address + size * count != r0) {\n\t\t\tLOG_ERROR(\"Data transfer failed. Expected end \"\n\t\t\t\t\"address 0x%08x, got 0x%08x\",\n\t\t\t\t(unsigned) (address + size * count),\n\t\t\t\t(unsigned) r0);\n\n\t\t\tif (burst)\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"use 'arm11 memwrite burst disable' to disable fast burst mode\");\n\n\n\t\t\tif (arm11->memwrite_error_fatal)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn arm11_run_instr_data_finish(arm11);\n}\n\nstatic int arm11_write_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\t/* pointer increment matters only for multi-unit writes ...\n\t * not e.g. to a \"reset the chip\" controller.\n\t */\n\treturn arm11_write_memory_inner(target, address, size,\n\t\tcount, buffer, count == 1);\n}\n\n/* target break-/watchpoint control\n* rw: 0 = write, 1 = read, 2 = access\n*/\nstatic int arm11_add_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n#if 0\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\tLOG_INFO(\"sw breakpoint requested, but software breakpoints not enabled\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n#endif\n\n\tif (!arm11->free_brps) {\n\t\tLOG_DEBUG(\"no breakpoint unit available for hardware breakpoint\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->length != 4) {\n\t\tLOG_DEBUG(\"only breakpoints of four bytes length supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tarm11->free_brps--;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_remove_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tarm11->free_brps++;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm11_common *arm11;\n\n\tif (!target->tap)\n\t\treturn ERROR_FAIL;\n\n\tif (target->tap->ir_length != 5) {\n\t\tLOG_ERROR(\"'target arm11' expects IR LENGTH = 5\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tarm11 = calloc(1, sizeof(*arm11));\n\tif (!arm11)\n\t\treturn ERROR_FAIL;\n\n\tarm11->arm.core_type = ARM_CORE_TYPE_STD;\n\tarm_init_arch_info(target, &arm11->arm);\n\n\tarm11->jtag_info.tap = target->tap;\n\tarm11->jtag_info.scann_size = 5;\n\tarm11->jtag_info.scann_instr = ARM11_SCAN_N;\n\tarm11->jtag_info.cur_scan_chain = ~0;\t/* invalid/unknown */\n\tarm11->jtag_info.intest_instr = ARM11_INTEST;\n\n\tarm11->memwrite_burst = true;\n\tarm11->memwrite_error_fatal = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\t/* Initialize anything we can set up without talking to the target */\n\treturn ERROR_OK;\n}\n\nstatic void arm11_deinit_target(struct target *target)\n{\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tarm11_dpm_deinit(arm11);\n\tfree(arm11);\n}\n\n/* talk to the target and set things up */\nstatic int arm11_examine(struct target *target)\n{\n\tint retval;\n\tchar *type;\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\tuint32_t didr, device_id;\n\tuint8_t implementor;\n\n\t/* FIXME split into do-first-time and do-every-time logic ... */\n\n\t/* check IDCODE */\n\n\tarm11_add_ir(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field idcode_field;\n\n\tarm11_setup_field(arm11, 32, NULL, &device_id, &idcode_field);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &idcode_field, TAP_DRPAUSE);\n\n\t/* check DIDR */\n\n\tarm11_add_debug_scan_n(arm11, 0x00, ARM11_TAP_DEFAULT);\n\n\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain0_fields[2];\n\n\tarm11_setup_field(arm11, 32, NULL, &didr, chain0_fields + 0);\n\tarm11_setup_field(arm11,  8, NULL, &implementor, chain0_fields + 1);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\tchain0_fields), chain0_fields, TAP_IDLE);\n\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\t/* assume the manufacturer id is ok; check the part # */\n\tswitch ((device_id >> 12) & 0xFFFF) {\n\t\tcase 0x7B36:\n\t\t\ttype = \"ARM1136\";\n\t\t\tbreak;\n\t\tcase 0x7B37:\n\t\t\ttype = \"ARM11 MPCore\";\n\t\t\tbreak;\n\t\tcase 0x7B56:\n\t\t\ttype = \"ARM1156\";\n\t\t\tbreak;\n\t\tcase 0x7B76:\n\t\t\tarm11->arm.core_type = ARM_CORE_TYPE_SEC_EXT;\n\t\t\t/* NOTE: could default arm11->hardware_step to true */\n\t\t\ttype = \"ARM1176\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unexpected ARM11 ID code\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\tLOG_INFO(\"found %s\", type);\n\n\t/* unlikely this could ever fail, but ... */\n\tswitch ((didr >> 16) & 0x0F) {\n\t\tcase ARM11_DEBUG_V6:\n\t\tcase ARM11_DEBUG_V61:\t/* supports security extensions */\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Only ARM v6 and v6.1 debug supported.\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tarm11->brp = ((didr >> 24) & 0x0F) + 1;\n\n\t/** \\todo TODO: reserve one brp slot if we allow breakpoints during step */\n\tarm11->free_brps = arm11->brp;\n\n\tLOG_DEBUG(\"IDCODE %08\" PRIx32 \" IMPLEMENTOR %02x DIDR %08\" PRIx32,\n\t\tdevice_id, implementor, didr);\n\n\t/* Build register cache \"late\", after target_init(), since we\n\t * want to know if this core supports Secure Monitor mode.\n\t */\n\tif (!target_was_examined(target))\n\t\tCHECK_RETVAL(arm11_dpm_init(arm11, didr));\n\n\t/* as a side-effect this reads DSCR and thus\n\t * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag\n\t * as suggested by the spec.\n\t */\n\n\tretval = arm11_check_init(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* ETM on ARM11 still uses original scanchain 6 access mode */\n\tif (arm11->arm.etm && !target_was_examined(target)) {\n\t\t*register_get_last_cache_p(&target->reg_cache) =\n\t\t\tetm_build_reg_cache(target, &arm11->jtag_info,\n\t\t\t\tarm11->arm.etm);\n\t\tCHECK_RETVAL(etm_setup(target));\n\t}\n\n\ttarget_set_examined(target);\n\n\treturn ERROR_OK;\n}\n\n#define ARM11_BOOL_WRAPPER(name, print_name)\t\\\n\tCOMMAND_HANDLER(arm11_handle_bool_ ## name) \\\n\t{ \\\n\t\tstruct target *target = get_current_target(CMD_CTX); \\\n\t\tstruct arm11_common *arm11 = target_to_arm11(target); \\\n\t\t\\\n\t\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool, \\\n\t\t\t&arm11->name, print_name); \\\n\t}\n\nARM11_BOOL_WRAPPER(memwrite_burst, \"memory write burst mode\")\nARM11_BOOL_WRAPPER(memwrite_error_fatal, \"fatal error mode for memory writes\")\nARM11_BOOL_WRAPPER(step_irq_enable, \"IRQs while stepping\")\nARM11_BOOL_WRAPPER(hardware_step, \"hardware single step\")\n\n/* REVISIT handle the VCR bits like other ARMs:  use symbols for\n * input and output values.\n */\n\nCOMMAND_HANDLER(arm11_handle_vcr)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm11_common *arm11 = target_to_arm11(target);\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], arm11->vcr);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tLOG_INFO(\"VCR 0x%08\" PRIx32 \"\", arm11->vcr);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm11_mw_command_handlers[] = {\n\t{\n\t\t.name = \"burst\",\n\t\t.handler = arm11_handle_bool_memwrite_burst,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or modify flag controlling potentially \"\n\t\t\t\"risky fast burst mode (default: enabled)\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"error_fatal\",\n\t\t.handler = arm11_handle_bool_memwrite_error_fatal,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or modify flag controlling transfer \"\n\t\t\t\"termination on transfer errors\"\n\t\t\t\" (default: enabled)\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration arm11_any_command_handlers[] = {\n\t{\n\t\t/* \"hardware_step\" is only here to check if the default\n\t\t * simulate + breakpoint implementation is broken.\n\t\t * TEMPORARY! NOT DOCUMENTED! */\n\t\t.name = \"hardware_step\",\n\t\t.handler = arm11_handle_bool_hardware_step,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"DEBUG ONLY - Hardware single stepping\"\n\t\t\t\" (default: disabled)\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"memwrite\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"memwrite command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm11_mw_command_handlers,\n\t},\n\t{\n\t\t.name = \"step_irq_enable\",\n\t\t.handler = arm11_handle_bool_step_irq_enable,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or modify flag controlling interrupt \"\n\t\t\t\"enable while stepping (default: disabled)\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"vcr\",\n\t\t.handler = arm11_handle_vcr,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Display or modify Vector Catch Register\",\n\t\t.usage = \"[value]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm11_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.chain = etm_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm11\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM11 command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm11_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM11xx targets. */\nstruct target_type arm11_target = {\n\t.name = \"arm11\",\n\n\t.poll = arm11_poll,\n\t.arch_state = arm11_arch_state,\n\n\t.halt = arm11_halt,\n\t.resume = arm11_resume,\n\t.step = arm11_step,\n\n\t.assert_reset = arm11_assert_reset,\n\t.deassert_reset = arm11_deassert_reset,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm11_read_memory,\n\t.write_memory = arm11_write_memory,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.add_breakpoint = arm11_add_breakpoint,\n\t.remove_breakpoint = arm11_remove_breakpoint,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.commands = arm11_command_handlers,\n\t.target_create = arm11_target_create,\n\t.init_target = arm11_init_target,\n\t.deinit_target = arm11_deinit_target,\n\t.examine = arm11_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm11.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 digenius technology GmbH.                          *\n *   Michael Bruck                                                         *\n *                                                                         *\n *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM11_H\n#define OPENOCD_TARGET_ARM11_H\n\n#include \"arm.h\"\n#include \"arm_dpm.h\"\n\n#define ARM11_TAP_DEFAULT                       TAP_INVALID\n\n#define CHECK_RETVAL(action)\t\t\t\\\n\tdo {\t\t\t\t\t\\\n\t\tint __retval = (action);\t\\\n\t\tif (__retval != ERROR_OK) {\t\\\n\t\t\tLOG_DEBUG(\"error while calling \\\"%s\\\"\",\t\\\n\t\t\t\t# action);     \\\n\t\t\treturn __retval;\t\\\n\t\t}\t\t\t\t\\\n\t} while (0)\n\n/* bits from ARMv7 DIDR */\nenum arm11_debug_version {\n\tARM11_DEBUG_V6                  = 0x01,\n\tARM11_DEBUG_V61                 = 0x02,\n\tARM11_DEBUG_V7                  = 0x03,\n\tARM11_DEBUG_V7_CP14             = 0x04,\n};\n\nstruct arm11_common {\n\tstruct arm arm;\n\n\t/** Debug module state. */\n\tstruct arm_dpm dpm;\n\tstruct arm11_sc7_action *bpwp_actions;\n\tunsigned bpwp_n;\n\n\tsize_t brp;\t\t\t/**< Number of Breakpoint Register Pairs from DIDR\t*/\n\tsize_t free_brps;\t\t/**< Number of breakpoints allocated */\n\n\tuint32_t dscr;\t\t\t/**< Last retrieved DSCR value. */\n\n\tuint32_t saved_rdtr;\n\tuint32_t saved_wdtr;\n\n\tbool is_rdtr_saved;\n\tbool is_wdtr_saved;\n\n\tbool simulate_reset_on_next_halt;\t/**< Perform cleanups of the ARM state on next halt **/\n\n\t/* Per-core configurable options.\n\t * NOTE that several of these boolean options should not exist\n\t * once the relevant code is known to work correctly.\n\t */\n\tbool memwrite_burst;\n\tbool memwrite_error_fatal;\n\tbool step_irq_enable;\n\tbool hardware_step;\n\n\t/** Configured Vector Catch Register settings. */\n\tuint32_t vcr;\n\n\tstruct arm_jtag jtag_info;\n};\n\nstatic inline struct arm11_common *target_to_arm11(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm11_common, arm);\n}\n\n/**\n * ARM11 DBGTAP instructions\n *\n * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html\n */\nenum arm11_instructions {\n\tARM11_EXTEST    = 0x00,\n\tARM11_SCAN_N    = 0x02,\n\tARM11_RESTART   = 0x04,\n\tARM11_HALT          = 0x08,\n\tARM11_INTEST    = 0x0C,\n\tARM11_ITRSEL    = 0x1D,\n\tARM11_IDCODE    = 0x1E,\n\tARM11_BYPASS    = 0x1F,\n};\n\nenum arm11_sc7 {\n\tARM11_SC7_NULL                          = 0,\n\tARM11_SC7_VCR                           = 7,\n\tARM11_SC7_PC                            = 8,\n\tARM11_SC7_BVR0                          = 64,\n\tARM11_SC7_BCR0                          = 80,\n\tARM11_SC7_WVR0                          = 96,\n\tARM11_SC7_WCR0                          = 112,\n};\n\n#endif /* OPENOCD_TARGET_ARM11_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm11_dbgtap.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 digenius technology GmbH.                          *\n *   Michael Bruck                                                         *\n *                                                                         *\n *   Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm_jtag.h\"\n#include \"arm11_dbgtap.h\"\n\n#include <helper/time_support.h>\n\n#if 0\n#define JTAG_DEBUG(expr ...)    do { if (1) \\\n\t\t\t\t\t     LOG_DEBUG(expr); } while (0)\n#else\n#define JTAG_DEBUG(expr ...)    do { if (0) \\\n\t\t\t\t\t     LOG_DEBUG(expr); } while (0)\n#endif\n\n/*\nThis pathmove goes from Pause-IR to Shift-IR while avoiding RTI. The\nbehavior of the FTDI driver IIRC was to go via RTI.\n\nConversely there may be other places in this code where the ARM11 code relies\non the driver to hit through RTI when coming from Update-?R.\n*/\nstatic const tap_state_t arm11_move_pi_to_si_via_ci[] = {\n\tTAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IRSHIFT\n};\n\n/* REVISIT no error handling here! */\nstatic void arm11_add_ir_scan_vc(struct jtag_tap *tap, struct scan_field *fields,\n\ttap_state_t state)\n{\n\tif (cmd_queue_cur_state == TAP_IRPAUSE)\n\t\tjtag_add_pathmove(ARRAY_SIZE(arm11_move_pi_to_si_via_ci),\n\t\t\tarm11_move_pi_to_si_via_ci);\n\n\tjtag_add_ir_scan(tap, fields, state);\n}\n\nstatic const tap_state_t arm11_move_pd_to_sd_via_cd[] = {\n\tTAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DRSHIFT\n};\n\n/* REVISIT no error handling here! */\nvoid arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields,\n\ttap_state_t state)\n{\n\tif (cmd_queue_cur_state == TAP_DRPAUSE)\n\t\tjtag_add_pathmove(ARRAY_SIZE(arm11_move_pd_to_sd_via_cd),\n\t\t\tarm11_move_pd_to_sd_via_cd);\n\n\tjtag_add_dr_scan(tap, num_fields, fields, state);\n}\n\n\n/** Code de-clutter: Construct struct scan_field to write out a value\n *\n * \\param arm11\t\t\tTarget state variable.\n * \\param num_bits\t\tLength of the data field\n * \\param out_data\t\tpointer to the data that will be sent out\n *\t\t\t\t\t\t<em > (data is read when it is added to the JTAG queue)</em>\n * \\param in_data\t\tpointer to the memory that will receive data that was clocked in\n *\t\t\t\t\t\t<em > (data is written when the JTAG queue is executed)</em>\n * \\param field\t\t\ttarget data structure that will be initialized\n */\nvoid arm11_setup_field(struct arm11_common *arm11, int num_bits,\n\tvoid *out_data, void *in_data, struct scan_field *field)\n{\n\tfield->num_bits                 = num_bits;\n\tfield->out_value                = out_data;\n\tfield->in_value                 = in_data;\n}\n\nstatic const char *arm11_ir_to_string(uint8_t ir)\n{\n\tconst char *s = \"unknown\";\n\n\tswitch (ir) {\n\t\tcase ARM11_EXTEST:\n\t\t\ts = \"EXTEST\";\n\t\t\tbreak;\n\t\tcase ARM11_SCAN_N:\n\t\t\ts = \"SCAN_N\";\n\t\t\tbreak;\n\t\tcase ARM11_RESTART:\n\t\t\ts = \"RESTART\";\n\t\t\tbreak;\n\t\tcase ARM11_HALT:\n\t\t\ts = \"HALT\";\n\t\t\tbreak;\n\t\tcase ARM11_INTEST:\n\t\t\ts = \"INTEST\";\n\t\t\tbreak;\n\t\tcase ARM11_ITRSEL:\n\t\t\ts = \"ITRSEL\";\n\t\t\tbreak;\n\t\tcase ARM11_IDCODE:\n\t\t\ts = \"IDCODE\";\n\t\t\tbreak;\n\t\tcase ARM11_BYPASS:\n\t\t\ts = \"BYPASS\";\n\t\t\tbreak;\n\t}\n\treturn s;\n}\n\n/** Write JTAG instruction register\n *\n * \\param arm11\t\tTarget state variable.\n * \\param instr\t\tAn ARM11 DBGTAP instruction. Use enum #arm11_instructions.\n * \\param state\t\tPass the final TAP state or ARM11_TAP_DEFAULT for the default value (Pause-IR).\n *\n * \\remarks\t\t\tThis adds to the JTAG command queue but does \\em not execute it.\n */\nvoid arm11_add_ir(struct arm11_common *arm11, uint8_t instr, tap_state_t state)\n{\n\tstruct jtag_tap *tap = arm11->arm.target->tap;\n\n\tif (buf_get_u32(tap->cur_instr, 0, 5) == instr) {\n\t\tJTAG_DEBUG(\"IR <= 0x%02x SKIPPED\", instr);\n\t\treturn;\n\t}\n\n\tJTAG_DEBUG(\"IR <= %s (0x%02x)\", arm11_ir_to_string(instr), instr);\n\n\tstruct scan_field field;\n\n\tarm11_setup_field(arm11, 5, &instr, NULL, &field);\n\n\tarm11_add_ir_scan_vc(arm11->arm.target->tap,\n\t\t&field,\n\t\tstate == ARM11_TAP_DEFAULT ? TAP_IRPAUSE : state);\n}\n\n/** Verify data shifted out from Scan Chain Register (SCREG). */\nstatic void arm11_in_handler_scan_n(uint8_t *in_value)\n{\n\t/* Don't expect JTAG layer to modify bits we didn't ask it to read */\n\tuint8_t v = *in_value & 0x1F;\n\n\tif (v != 0x10) {\n\t\tLOG_ERROR(\"'arm11 target' JTAG error SCREG OUT 0x%02x\", v);\n\t\tjtag_set_error(ERROR_FAIL);\n\t}\n}\n\n/** Select and write to Scan Chain Register (SCREG)\n *\n * This function sets the instruction register to SCAN_N and writes\n * the data register with the selected chain number.\n *\n * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/Cacbjhfg.html\n *\n * \\param arm11\t    Target state variable.\n * \\param chain\t    Scan chain that will be selected.\n * \\param state\t    Pass the final TAP state or ARM11_TAP_DEFAULT for the default\n *\t\t\t\t\tvalue (Pause-DR).\n *\n * Changes the current scan chain if needed, transitions to the specified\n * TAP state, and leaves the IR undefined.\n *\n * The chain takes effect when Update-DR is passed (usually when subsequently\n * the INTEXT/EXTEST instructions are written).\n *\n * \\warning\t\t\t(Obsolete) Using this twice in a row will \\em fail. The first\n *\t\t\t\t\tcall will end in Pause-DR. The second call, due to the IR\n *\t\t\t\t\tcaching, will not go through Capture-DR when shifting in the\n *\t\t\t\t\tnew scan chain number. As a result the verification in\n *\t\t\t\t\tarm11_in_handler_scan_n() must fail.\n *\n * \\remarks\t\t\tThis adds to the JTAG command queue but does \\em not execute it.\n */\n\nint arm11_add_debug_scan_n(struct arm11_common *arm11,\n\tuint8_t chain, tap_state_t state)\n{\n\t/* Don't needlessly switch the scan chain.\n\t * NOTE:  the ITRSEL instruction fakes SCREG changing;\n\t * but leaves its actual value unchanged.\n\t */\n#if 0\n\t/* FIX!!! the optimization below is broken because we do not */\n\t/* invalidate the cur_scan_chain upon a TRST/TMS. See arm_jtag.c */\n\t/* for example on how to invalidate cur_scan_chain. Tested patches gladly */\n\t/* accepted! */\n\tif (arm11->jtag_info.cur_scan_chain == chain) {\n\t\tJTAG_DEBUG(\"SCREG <= %d SKIPPED\", chain);\n\t\treturn jtag_add_statemove((state == ARM11_TAP_DEFAULT)\n\t\t\t? TAP_DRPAUSE : state);\n\t}\n#endif\n\tJTAG_DEBUG(\"SCREG <= %d\", chain);\n\n\tarm11_add_ir(arm11, ARM11_SCAN_N, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field field;\n\n\tuint8_t tmp[1];\n\tarm11_setup_field(arm11, 5, &chain, &tmp, &field);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap,\n\t\t1,\n\t\t&field,\n\t\tstate == ARM11_TAP_DEFAULT ? TAP_DRPAUSE : state);\n\n\tjtag_execute_queue_noclear();\n\n\tarm11_in_handler_scan_n(tmp);\n\n\tarm11->jtag_info.cur_scan_chain = chain;\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Queue a DR scan of the ITR register.  Caller must have selected\n * scan chain 4 (ITR), possibly using ITRSEL.\n *\n * \\param arm11\t\tTarget state variable.\n * \\param inst\t\tAn ARM11 processor instruction/opcode.\n * \\param flag\t\tOptional parameter to retrieve the Ready flag;\n *\tthis address will be written when the JTAG chain is scanned.\n * \\param state\t\tThe TAP state to enter after the DR scan.\n *\n * Going through the TAP_DRUPDATE state writes ITR only if Ready was\n * previously set.  Only the Ready flag is readable by the scan.\n *\n * An instruction loaded into ITR is executed when going through the\n * TAP_IDLE state only if Ready was previously set and the debug state\n * is properly set up.  Depending on the instruction, you may also need\n * to ensure that the rDTR is ready before that Run-Test/Idle state.\n */\nstatic void arm11_add_debug_inst(struct arm11_common *arm11,\n\tuint32_t inst, uint8_t *flag, tap_state_t state)\n{\n\tJTAG_DEBUG(\"INST <= 0x%08x\", (unsigned) inst);\n\n\tstruct scan_field itr[2];\n\n\tarm11_setup_field(arm11, 32, &inst, NULL, itr + 0);\n\tarm11_setup_field(arm11, 1, NULL, flag, itr + 1);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(itr), itr, state);\n}\n\n/**\n * Read and save the Debug Status and Control Register (DSCR).\n *\n * \\param arm11\t\tTarget state variable.\n * \\return Error status; arm11->dscr is updated on success.\n *\n * \\remarks This is a stand-alone function that executes the JTAG\n * command queue.  It does not require the ARM11 debug TAP to be\n * in any particular state.\n */\nint arm11_read_dscr(struct arm11_common *arm11)\n{\n\tint retval;\n\n\tretval = arm11_add_debug_scan_n(arm11, 0x01, ARM11_TAP_DEFAULT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\tuint32_t dscr;\n\tstruct scan_field chain1_field;\n\n\tarm11_setup_field(arm11, 32, NULL, &dscr, &chain1_field);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &chain1_field, TAP_DRPAUSE);\n\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\tif (arm11->dscr != dscr)\n\t\tJTAG_DEBUG(\"DSCR  = %08x (OLD %08x)\",\n\t\t\t(unsigned) dscr,\n\t\t\t(unsigned) arm11->dscr);\n\n\tarm11->dscr = dscr;\n\n\treturn ERROR_OK;\n}\n\n/** Write the Debug Status and Control Register (DSCR)\n *\n * same as CP14 c1\n *\n * \\param arm11\t\tTarget state variable.\n * \\param dscr\t\tDSCR content\n *\n * \\remarks\t\t\tThis is a stand-alone function that executes the JTAG command queue.\n */\nint arm11_write_dscr(struct arm11_common *arm11, uint32_t dscr)\n{\n\tint retval;\n\tretval = arm11_add_debug_scan_n(arm11, 0x01, ARM11_TAP_DEFAULT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain1_field;\n\n\tarm11_setup_field(arm11, 32, &dscr, NULL, &chain1_field);\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, 1, &chain1_field, TAP_DRPAUSE);\n\n\tCHECK_RETVAL(jtag_execute_queue());\n\n\tJTAG_DEBUG(\"DSCR <= %08x (OLD %08x)\",\n\t\t(unsigned) dscr,\n\t\t(unsigned) arm11->dscr);\n\n\tarm11->dscr = dscr;\n\n\treturn ERROR_OK;\n}\n\n/** Prepare the stage for ITR/DTR operations\n * from the arm11_run_instr... group of functions.\n *\n * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()\n * around a block of arm11_run_instr_... calls.\n *\n * Select scan chain 5 to allow quick access to DTR. When scan\n * chain 4 is needed to put in a register the ITRSel instruction\n * shortcut is used instead of actually changing the Scan_N\n * register.\n *\n * \\param arm11\t\tTarget state variable.\n *\n */\nint arm11_run_instr_data_prepare(struct arm11_common *arm11)\n{\n\treturn arm11_add_debug_scan_n(arm11, 0x05, ARM11_TAP_DEFAULT);\n}\n\n/** Cleanup after ITR/DTR operations\n * from the arm11_run_instr... group of functions\n *\n * Put arm11_run_instr_data_prepare() and arm11_run_instr_data_finish()\n * around a block of arm11_run_instr_... calls.\n *\n * Any IDLE can lead to an instruction execution when\n * scan chains 4 or 5 are selected and the IR holds\n * INTEST or EXTEST. So we must disable that before\n * any following activities lead to an IDLE.\n *\n * \\param arm11\t\tTarget state variable.\n *\n */\nint arm11_run_instr_data_finish(struct arm11_common *arm11)\n{\n\treturn arm11_add_debug_scan_n(arm11, 0x00, ARM11_TAP_DEFAULT);\n}\n\n/**\n * Execute one or more instructions via ITR.\n * Caller guarantees that processor is in debug state, that DSCR_ITR_EN\n * is set, the ITR Ready flag is set (as seen on the previous entry to\n * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tPointer to sequence of ARM opcodes\n * \\param count\t\tNumber of opcodes to execute\n *\n */\nstatic\nint arm11_run_instr_no_data(struct arm11_common *arm11,\n\tuint32_t *opcode, size_t count)\n{\n\tarm11_add_ir(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);\n\n\twhile (count--) {\n\t\tarm11_add_debug_inst(arm11, *opcode++, NULL, TAP_IDLE);\n\n\t\tint i = 0;\n\t\twhile (1) {\n\t\t\tuint8_t flag;\n\n\t\t\tarm11_add_debug_inst(arm11, 0, &flag, count ? TAP_IDLE : TAP_DRPAUSE);\n\n\t\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\t\tif (flag)\n\t\t\t\tbreak;\n\n\t\t\tint64_t then = 0;\n\n\t\t\tif (i == 1000)\n\t\t\t\tthen = timeval_ms();\n\t\t\tif (i >= 1000) {\n\t\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti++;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** Execute one instruction via ITR\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode\n *\n */\nint arm11_run_instr_no_data1(struct arm11_common *arm11, uint32_t opcode)\n{\n\treturn arm11_run_instr_no_data(arm11, &opcode, 1);\n}\n\n\n/** Execute one instruction via ITR repeatedly while\n *  passing data to the core via DTR on each execution.\n *\n * Caller guarantees that processor is in debug state, that DSCR_ITR_EN\n * is set, the ITR Ready flag is set (as seen on the previous entry to\n * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.\n *\n *  The executed instruction \\em must read data from DTR.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode\n * \\param data\t\tPointer to the data words to be passed to the core\n * \\param count\t\tNumber of data words and instruction repetitions\n *\n */\nint arm11_run_instr_data_to_core(struct arm11_common *arm11,\n\tuint32_t opcode,\n\tuint32_t *data,\n\tsize_t count)\n{\n\tarm11_add_ir(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);\n\n\tarm11_add_debug_inst(arm11, opcode, NULL, TAP_DRPAUSE);\n\n\tarm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain5_fields[3];\n\n\tuint32_t _data;\n\tuint8_t ready;\n\tuint8_t n_retry;\n\n\tarm11_setup_field(arm11, 32,    &_data, NULL,           chain5_fields + 0);\n\tarm11_setup_field(arm11,  1,    NULL,   &ready,         chain5_fields + 1);\n\tarm11_setup_field(arm11,  1,    NULL,   &n_retry,       chain5_fields + 2);\n\n\twhile (count--) {\n\t\tint i = 0;\n\t\tdo {\n\t\t\t_data        = *data;\n\n\t\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\t\t\tchain5_fields), chain5_fields, TAP_IDLE);\n\n\t\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\t\tJTAG_DEBUG(\"DTR  ready %d  n_retry %d\", ready, n_retry);\n\n\t\t\tint64_t then = 0;\n\n\t\t\tif (i == 1000)\n\t\t\t\tthen = timeval_ms();\n\t\t\tif (i >= 1000) {\n\t\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti++;\n\t\t} while (!ready);\n\n\t\tdata++;\n\t}\n\n\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\tint i = 0;\n\tdo {\n\t\t_data        = 0;\n\n\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\t\tchain5_fields), chain5_fields, TAP_DRPAUSE);\n\n\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\tJTAG_DEBUG(\"DTR  _data %08x  ready %d  n_retry %d\",\n\t\t\t(unsigned) _data, ready, n_retry);\n\n\t\tint64_t then = 0;\n\n\t\tif (i == 1000)\n\t\t\tthen = timeval_ms();\n\t\tif (i >= 1000) {\n\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\tLOG_WARNING(\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\ti++;\n\t} while (!ready);\n\n\treturn ERROR_OK;\n}\n\n/** JTAG path for arm11_run_instr_data_to_core_noack\n *\n *  The repeated TAP_IDLE's do not cause a repeated execution\n *  if passed without leaving the state.\n *\n *  Since this is more than 7 bits (adjustable via adding more\n *  TAP_IDLE's) it produces an artificial delay in the lower\n *  layer (FT2232) that is long enough to finish execution on\n *  the core but still shorter than any manually inducible delays.\n *\n *  To disable this code, try \"memwrite burst false\"\n *\n *  FIX!!! should we use multiple TAP_IDLE here or not???\n *\n *  https://lists.berlios.de/pipermail/openocd-development/2009-July/009698.html\n *  https://lists.berlios.de/pipermail/openocd-development/2009-August/009865.html\n */\nstatic const tap_state_t arm11_move_drpause_idle_drpause_with_delay[] = {\n\tTAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE, TAP_IDLE, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE,\n\tTAP_DRSHIFT\n};\n\nstatic int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap *tap,\n\tuint32_t opcode,\n\tuint32_t *data,\n\tsize_t count)\n{\n\tstruct scan_field chain5_fields[3];\n\n\tchain5_fields[0].num_bits               = 32;\n\tchain5_fields[0].out_value              = NULL;\t/*&Data*/\n\tchain5_fields[0].in_value               = NULL;\n\n\tchain5_fields[1].num_bits               = 1;\n\tchain5_fields[1].out_value              = NULL;\n\tchain5_fields[1].in_value               = NULL;\t/*&Ready*/\n\n\tchain5_fields[2].num_bits               = 1;\n\tchain5_fields[2].out_value              = NULL;\n\tchain5_fields[2].in_value               = NULL;\n\n\tuint8_t *readies;\n\tunsigned readies_num = count;\n\tunsigned bytes = sizeof(*readies)*readies_num;\n\n\treadies = malloc(bytes);\n\tif (!readies) {\n\t\tLOG_ERROR(\"Out of memory allocating %u bytes\", bytes);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t *ready_pos                      = readies;\n\twhile (count--) {\n\t\tchain5_fields[0].out_value      = (uint8_t *)(data++);\n\t\tchain5_fields[1].in_value       = ready_pos++;\n\n\t\tif (count > 0) {\n\t\t\tjtag_add_dr_scan(tap, ARRAY_SIZE(chain5_fields), chain5_fields,\n\t\t\t\tTAP_DRPAUSE);\n\t\t\tjtag_add_pathmove(ARRAY_SIZE(arm11_move_drpause_idle_drpause_with_delay),\n\t\t\t\tarm11_move_drpause_idle_drpause_with_delay);\n\t\t} else\n\t\t\tjtag_add_dr_scan(tap, ARRAY_SIZE(chain5_fields), chain5_fields, TAP_IDLE);\n\t}\n\n\tint retval = jtag_execute_queue();\n\tif (retval == ERROR_OK) {\n\t\tunsigned error_count = 0;\n\n\t\tfor (size_t i = 0; i < readies_num; i++) {\n\t\t\tif (readies[i] != 1)\n\t\t\t\terror_count++;\n\t\t}\n\n\t\tif (error_count > 0) {\n\t\t\tLOG_ERROR(\"%u words out of %u not transferred\",\n\t\t\t\terror_count, readies_num);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\tfree(readies);\n\n\treturn retval;\n}\n\n/** Execute one instruction via ITR repeatedly while\n *  passing data to the core via DTR on each execution.\n *\n * Caller guarantees that processor is in debug state, that DSCR_ITR_EN\n * is set, the ITR Ready flag is set (as seen on the previous entry to\n * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.\n *\n *  No Ready check during transmission.\n *\n *  The executed instruction \\em must read data from DTR.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode\n * \\param data\t\tPointer to the data words to be passed to the core\n * \\param count\t\tNumber of data words and instruction repetitions\n *\n */\nint arm11_run_instr_data_to_core_noack(struct arm11_common *arm11,\n\tuint32_t opcode,\n\tuint32_t *data,\n\tsize_t count)\n{\n\tarm11_add_ir(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);\n\n\tarm11_add_debug_inst(arm11, opcode, NULL, TAP_DRPAUSE);\n\n\tarm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);\n\n\tint retval = arm11_run_instr_data_to_core_noack_inner(arm11->arm.target->tap,\n\t\t\topcode,\n\t\t\tdata,\n\t\t\tcount);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain5_fields[3];\n\n\tarm11_setup_field(arm11,\n\t\t32,\n\t\tNULL /*&Data*/,\n\t\tNULL,\n\t\tchain5_fields + 0);\n\tarm11_setup_field(arm11,\n\t\t1,\n\t\tNULL,\n\t\tNULL /*&Ready*/,\n\t\tchain5_fields + 1);\n\tarm11_setup_field(arm11,\n\t\t1,\n\t\tNULL,\n\t\tNULL,\n\t\tchain5_fields + 2);\n\n\tuint8_t ready_flag;\n\tchain5_fields[1].in_value   = &ready_flag;\n\n\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\tchain5_fields), chain5_fields, TAP_DRPAUSE);\n\n\tretval = jtag_execute_queue();\n\tif (retval == ERROR_OK) {\n\t\tif (ready_flag != 1) {\n\t\t\tLOG_ERROR(\"last word not transferred\");\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\n\n/** Execute an instruction via ITR while handing data into the core via DTR.\n *\n *  The executed instruction \\em must read data from DTR.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode\n * \\param data\t\tData word to be passed to the core via DTR\n *\n */\nint arm11_run_instr_data_to_core1(struct arm11_common *arm11, uint32_t opcode, uint32_t data)\n{\n\treturn arm11_run_instr_data_to_core(arm11, opcode, &data, 1);\n}\n\n\n/** Execute one instruction via ITR repeatedly while\n *  reading data from the core via DTR on each execution.\n *\n * Caller guarantees that processor is in debug state, that DSCR_ITR_EN\n * is set, the ITR Ready flag is set (as seen on the previous entry to\n * TAP_DRCAPTURE), and the DSCR sticky abort flag is clear.\n *\n *  The executed instruction \\em must write data to DTR.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode\n * \\param data\t\tPointer to an array that receives the data words from the core\n * \\param count\t\tNumber of data words and instruction repetitions\n *\n */\nint arm11_run_instr_data_from_core(struct arm11_common *arm11,\n\tuint32_t opcode,\n\tuint32_t *data,\n\tsize_t count)\n{\n\tarm11_add_ir(arm11, ARM11_ITRSEL, ARM11_TAP_DEFAULT);\n\n\tarm11_add_debug_inst(arm11, opcode, NULL, TAP_IDLE);\n\n\tarm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain5_fields[3];\n\n\tuint32_t _data;\n\tuint8_t ready;\n\tuint8_t n_retry;\n\n\tarm11_setup_field(arm11, 32,    NULL,   &_data,     chain5_fields + 0);\n\tarm11_setup_field(arm11,  1,    NULL,   &ready,     chain5_fields + 1);\n\tarm11_setup_field(arm11,  1,    NULL,   &n_retry,   chain5_fields + 2);\n\n\twhile (count--) {\n\t\tint i = 0;\n\t\tdo {\n\t\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(\n\t\t\t\t\tchain5_fields), chain5_fields,\n\t\t\t\tcount ? TAP_IDLE : TAP_DRPAUSE);\n\n\t\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\t\tJTAG_DEBUG(\"DTR  _data %08x  ready %d  n_retry %d\",\n\t\t\t\t(unsigned) _data, ready, n_retry);\n\n\t\t\tint64_t then = 0;\n\n\t\t\tif (i == 1000)\n\t\t\t\tthen = timeval_ms();\n\t\t\tif (i >= 1000) {\n\t\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti++;\n\t\t} while (!ready);\n\n\t\t*data++ = _data;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** Execute one instruction via ITR\n *  then load r0 into DTR and read DTR from core.\n *\n *  The first executed instruction (\\p opcode) should write data to r0.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode to write r0 with the value of interest\n * \\param data\t\tPointer to a data word that receives the value from r0 after \\p opcode was executed.\n *\n */\nint arm11_run_instr_data_from_core_via_r0(struct arm11_common *arm11,\n\tuint32_t opcode,\n\tuint32_t *data)\n{\n\tint retval;\n\tretval = arm11_run_instr_no_data1(arm11, opcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* MCR p14,0,R0,c0,c5,0 (move r0 -> wDTR -> local var) */\n\tarm11_run_instr_data_from_core(arm11, 0xEE000E15, data, 1);\n\n\treturn ERROR_OK;\n}\n\n/** Load data into core via DTR then move it to r0 then\n *  execute one instruction via ITR\n *\n *  The final executed instruction (\\p opcode) should read data from r0.\n *\n * \\pre arm11_run_instr_data_prepare() /  arm11_run_instr_data_finish() block\n *\n * \\param arm11\t\tTarget state variable.\n * \\param opcode\tARM opcode to read r0 act upon it\n * \\param data\t\tData word that will be written to r0 before \\p opcode is executed\n *\n */\nint arm11_run_instr_data_to_core_via_r0(struct arm11_common *arm11, uint32_t opcode, uint32_t data)\n{\n\tint retval;\n\t/* MRC p14,0,r0,c0,c5,0 */\n\tretval = arm11_run_instr_data_to_core1(arm11, 0xEE100E15, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm11_run_instr_no_data1(arm11, opcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n/** Apply reads and writes to scan chain 7\n *\n * \\see struct arm11_sc7_action\n *\n * \\param arm11\t\tTarget state variable.\n * \\param actions\tA list of read and/or write instructions\n * \\param count\t\tNumber of instructions in the list.\n *\n */\nint arm11_sc7_run(struct arm11_common *arm11, struct arm11_sc7_action *actions, size_t count)\n{\n\tint retval;\n\n\tretval = arm11_add_debug_scan_n(arm11, 0x07, ARM11_TAP_DEFAULT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);\n\n\tstruct scan_field chain7_fields[3];\n\n\tuint8_t n_rw;\n\tuint32_t data_out;\n\tuint8_t address_out;\n\tuint8_t ready;\n\tuint32_t data_in;\n\tuint8_t address_in;\n\n\tarm11_setup_field(arm11,  1, &n_rw,              &ready,          chain7_fields + 0);\n\tarm11_setup_field(arm11, 32, &data_out,          &data_in,        chain7_fields + 1);\n\tarm11_setup_field(arm11,  7, &address_out,       &address_in,     chain7_fields + 2);\n\n\tfor (size_t i = 0; i < count + 1; i++) {\n\t\tif (i < count) {\n\t\t\tn_rw             = actions[i].write ? 1 : 0;\n\t\t\tdata_out         = actions[i].value;\n\t\t\taddress_out      = actions[i].address;\n\t\t} else {\n\t\t\tn_rw             = 1;\n\t\t\tdata_out         = 0;\n\t\t\taddress_out      = 0;\n\t\t}\n\n\t\t/* Timeout here so we don't get stuck. */\n\t\tint i_n = 0;\n\t\twhile (1) {\n\t\t\tJTAG_DEBUG(\"SC7 <= c%-3d Data %08x %s\",\n\t\t\t\t(unsigned) address_out,\n\t\t\t\t(unsigned) data_out,\n\t\t\t\tn_rw ? \"write\" : \"read\");\n\n\t\t\tarm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(chain7_fields),\n\t\t\t\tchain7_fields, TAP_DRPAUSE);\n\n\t\t\tCHECK_RETVAL(jtag_execute_queue());\n\n\t\t\t/* 'n_rw' is 'ready' on read out */\n\t\t\tif (ready)\n\t\t\t\tbreak;\n\n\t\t\tint64_t then = 0;\n\n\t\t\tif (i_n == 1000)\n\t\t\t\tthen = timeval_ms();\n\t\t\tif (i_n >= 1000) {\n\t\t\t\tif ((timeval_ms()-then) > 1000) {\n\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\"Timeout (1000ms) waiting for instructions to complete\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti_n++;\n\t\t}\n\n\t\tif (!n_rw)\n\t\t\tJTAG_DEBUG(\"SC7 => Data %08x\", (unsigned) data_in);\n\n\t\tif (i > 0) {\n\t\t\tif (actions[i - 1].address != address_in)\n\t\t\t\tLOG_WARNING(\"Scan chain 7 shifted out unexpected address\");\n\n\t\t\tif (!actions[i - 1].write)\n\t\t\t\tactions[i - 1].value = data_in;\n\t\t\telse {\n\t\t\t\tif (actions[i - 1].value != data_in)\n\t\t\t\t\tLOG_WARNING(\"Scan chain 7 shifted out unexpected data\");\n\t\t\t}\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/** Clear VCR and all breakpoints and watchpoints via scan chain 7\n *\n * \\param arm11\t\tTarget state variable.\n *\n */\nint arm11_sc7_clear_vbw(struct arm11_common *arm11)\n{\n\tsize_t clear_bw_size = arm11->brp + 1;\n\tstruct arm11_sc7_action *clear_bw = malloc(sizeof(struct arm11_sc7_action) * clear_bw_size);\n\tstruct arm11_sc7_action *pos = clear_bw;\n\n\tfor (size_t i = 0; i < clear_bw_size; i++) {\n\t\tclear_bw[i].write       = true;\n\t\tclear_bw[i].value       = 0;\n\t}\n\n\tfor (size_t i = 0; i < arm11->brp; i++)\n\t\t(pos++)->address = ARM11_SC7_BCR0 + i;\n\n\t(pos++)->address = ARM11_SC7_VCR;\n\n\tint retval;\n\tretval = arm11_sc7_run(arm11, clear_bw, clear_bw_size);\n\n\tfree(clear_bw);\n\n\treturn retval;\n}\n\n/** Write VCR register\n *\n * \\param arm11\t\tTarget state variable.\n * \\param value\t\tValue to be written\n */\nint arm11_sc7_set_vcr(struct arm11_common *arm11, uint32_t value)\n{\n\tstruct arm11_sc7_action set_vcr;\n\n\tset_vcr.write           = true;\n\tset_vcr.address         = ARM11_SC7_VCR;\n\tset_vcr.value           = value;\n\n\treturn arm11_sc7_run(arm11, &set_vcr, 1);\n}\n\n/** Read word from address\n *\n * \\param arm11\t\tTarget state variable.\n * \\param address\tMemory address to be read\n * \\param result\tPointer where to store result\n *\n */\nint arm11_read_memory_word(struct arm11_common *arm11, uint32_t address, uint32_t *result)\n{\n\tint retval;\n\tretval = arm11_run_instr_data_prepare(arm11);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* MRC p14,0,r0,c0,c5,0 (r0 = address) */\n\tCHECK_RETVAL(arm11_run_instr_data_to_core1(arm11, 0xee100e15, address));\n\n\t/* LDC p14,c5,[R0],#4 (DTR = [r0]) */\n\tCHECK_RETVAL(arm11_run_instr_data_from_core(arm11, 0xecb05e01, result, 1));\n\n\treturn arm11_run_instr_data_finish(arm11);\n}\n\n/************************************************************************/\n\n/*\n * ARM11 provider for the OpenOCD implementation of the standard\n * architectural ARM v6/v7 \"Debug Programmer's Model\" (DPM).\n */\n\nstatic inline struct arm11_common *dpm_to_arm11(struct arm_dpm *dpm)\n{\n\treturn container_of(dpm, struct arm11_common, dpm);\n}\n\nstatic int arm11_dpm_prepare(struct arm_dpm *dpm)\n{\n\treturn arm11_run_instr_data_prepare(dpm_to_arm11(dpm));\n}\n\nstatic int arm11_dpm_finish(struct arm_dpm *dpm)\n{\n\treturn arm11_run_instr_data_finish(dpm_to_arm11(dpm));\n}\n\nstatic int arm11_dpm_instr_write_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\treturn arm11_run_instr_data_to_core(dpm_to_arm11(dpm),\n\t\topcode, &data, 1);\n}\n\nstatic int arm11_dpm_instr_write_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\treturn arm11_run_instr_data_to_core_via_r0(dpm_to_arm11(dpm),\n\t\topcode, data);\n}\n\nstatic int arm11_dpm_instr_read_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\treturn arm11_run_instr_data_from_core(dpm_to_arm11(dpm),\n\t\topcode, data, 1);\n}\n\nstatic int arm11_dpm_instr_read_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\treturn arm11_run_instr_data_from_core_via_r0(dpm_to_arm11(dpm),\n\t\topcode, data);\n}\n\n/* Because arm11_sc7_run() takes a vector of actions, we batch breakpoint\n * and watchpoint operations instead of running them right away.  Since we\n * pre-allocated our vector, we don't need to worry about space.\n */\nstatic int arm11_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,\n\tuint32_t addr, uint32_t control)\n{\n\tstruct arm11_common *arm11 = dpm_to_arm11(dpm);\n\tstruct arm11_sc7_action *action;\n\n\taction = arm11->bpwp_actions + arm11->bpwp_n;\n\n\t/* Invariant:  this bp/wp is disabled.\n\t * It also happens that the core is halted here, but for\n\t * DPM-based cores we don't actually care about that.\n\t */\n\n\taction[0].write = action[1].write = true;\n\n\taction[0].value = addr;\n\taction[1].value = control;\n\n\tswitch (index_t) {\n\t    case 0 ... 15:\n\t\t    action[0].address = ARM11_SC7_BVR0 + index_t;\n\t\t    action[1].address = ARM11_SC7_BCR0 + index_t;\n\t\t    break;\n\t    case 16 ... 32:\n\t\t    index_t -= 16;\n\t\t    action[0].address = ARM11_SC7_WVR0 + index_t;\n\t\t    action[1].address = ARM11_SC7_WCR0 + index_t;\n\t\t    break;\n\t    default:\n\t\t    return ERROR_FAIL;\n\t}\n\n\tarm11->bpwp_n += 2;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm11_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)\n{\n\tstruct arm11_common *arm11 = dpm_to_arm11(dpm);\n\tstruct arm11_sc7_action *action;\n\n\taction = arm11->bpwp_actions + arm11->bpwp_n;\n\n\taction[0].write = true;\n\taction[0].value = 0;\n\n\tswitch (index_t) {\n\t    case 0 ... 15:\n\t\t    action[0].address = ARM11_SC7_BCR0 + index_t;\n\t\t    break;\n\t    case 16 ... 32:\n\t\t    index_t -= 16;\n\t\t    action[0].address = ARM11_SC7_WCR0 + index_t;\n\t\t    break;\n\t    default:\n\t\t    return ERROR_FAIL;\n\t}\n\n\tarm11->bpwp_n += 1;\n\n\treturn ERROR_OK;\n}\n\n/** Flush any pending breakpoint and watchpoint updates. */\nint arm11_bpwp_flush(struct arm11_common *arm11)\n{\n\tint retval;\n\n\tif (!arm11->bpwp_n)\n\t\treturn ERROR_OK;\n\n\tretval = arm11_sc7_run(arm11, arm11->bpwp_actions, arm11->bpwp_n);\n\tarm11->bpwp_n = 0;\n\n\treturn retval;\n}\n\n/** Set up high-level debug module utilities */\nint arm11_dpm_init(struct arm11_common *arm11, uint32_t didr)\n{\n\tstruct arm_dpm *dpm = &arm11->dpm;\n\tint retval;\n\n\tdpm->arm = &arm11->arm;\n\n\tdpm->didr = didr;\n\n\tdpm->prepare = arm11_dpm_prepare;\n\tdpm->finish = arm11_dpm_finish;\n\n\tdpm->instr_write_data_dcc = arm11_dpm_instr_write_data_dcc;\n\tdpm->instr_write_data_r0 = arm11_dpm_instr_write_data_r0;\n\n\tdpm->instr_read_data_dcc = arm11_dpm_instr_read_data_dcc;\n\tdpm->instr_read_data_r0 = arm11_dpm_instr_read_data_r0;\n\n\tdpm->bpwp_enable = arm11_bpwp_enable;\n\tdpm->bpwp_disable = arm11_bpwp_disable;\n\n\tretval = arm_dpm_setup(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* alloc enough to enable all breakpoints and watchpoints at once */\n\tarm11->bpwp_actions = calloc(2 * (dpm->nbp + dpm->nwp),\n\t\t\tsizeof(*arm11->bpwp_actions));\n\tif (!arm11->bpwp_actions)\n\t\treturn ERROR_FAIL;\n\n\tretval = arm_dpm_initialize(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn arm11_bpwp_flush(arm11);\n}\n\nvoid arm11_dpm_deinit(struct arm11_common *arm11)\n{\n\tstruct arm_dpm *dpm = &arm11->dpm;\n\n\tfree(arm11->bpwp_actions);\n\tarm_free_reg_cache(dpm->arm);\n\tfree(dpm->dbp);\n\tfree(dpm->dwp);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm11_dbgtap.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 digenius technology GmbH.                          *\n *   Michael Bruck                                                         *\n *                                                                         *\n *   Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM11_DBGTAP_H\n#define OPENOCD_TARGET_ARM11_DBGTAP_H\n\n#include \"arm11.h\"\n\n/* ARM11 internals */\n\nvoid arm11_setup_field(struct arm11_common *arm11, int num_bits,\n\t\tvoid *in_data, void *out_data, struct scan_field *field);\nvoid arm11_add_ir(struct arm11_common *arm11,\n\t\tuint8_t instr, tap_state_t state);\nint arm11_add_debug_scan_n(struct arm11_common *arm11,\n\t\tuint8_t chain, tap_state_t state);\nint arm11_read_dscr(struct arm11_common *arm11);\nint arm11_write_dscr(struct arm11_common *arm11, uint32_t dscr);\n\nint arm11_run_instr_data_prepare(struct arm11_common *arm11);\nint arm11_run_instr_data_finish(struct arm11_common *arm11);\nint arm11_run_instr_no_data1(struct arm11_common *arm11, uint32_t opcode);\nint arm11_run_instr_data_to_core(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t *data, size_t count);\nint arm11_run_instr_data_to_core_noack(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t *data, size_t count);\nint arm11_run_instr_data_to_core1(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t data);\nint arm11_run_instr_data_from_core(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t *data, size_t count);\nint arm11_run_instr_data_from_core_via_r0(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t *data);\nint arm11_run_instr_data_to_core_via_r0(struct arm11_common *arm11,\n\t\tuint32_t opcode, uint32_t data);\n\nvoid arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_field *fields,\n\t\ttap_state_t state);\n\n/**\n * Used with arm11_sc7_run to make a list of read/write commands for\n * scan chain 7\n */\nstruct arm11_sc7_action {\n\tbool write;\t/**< Access mode: true for write, false for read. */\n\tuint8_t address;/**< Register address mode. Use enum #arm11_sc7 */\n\t/**\n\t * If write then set this to value to be written.  In read mode\n\t * this receives the read value when the function returns.\n\t */\n\tuint32_t value;\n};\n\nint arm11_sc7_run(struct arm11_common *arm11,\n\t\tstruct arm11_sc7_action *actions, size_t count);\n\n/* Mid-level helper functions */\nint arm11_sc7_clear_vbw(struct arm11_common *arm11);\nint arm11_sc7_set_vcr(struct arm11_common *arm11, uint32_t value);\n\nint arm11_read_memory_word(struct arm11_common *arm11,\n\t\tuint32_t address, uint32_t *result);\n\nint arm11_dpm_init(struct arm11_common *arm11, uint32_t didr);\nvoid arm11_dpm_deinit(struct arm11_common *arm11);\nint arm11_bpwp_flush(struct arm11_common *arm11);\n\n#endif /* OPENOCD_TARGET_ARM11_DBGTAP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm720t.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2009 by Øyvind Harboe                                   *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm720t.h\"\n#include <helper/time_support.h>\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n\n\n/*\n * ARM720 is an ARM7TDMI-S with MMU and ETM7.  For information, see\n * ARM DDI 0229C especially Chapter 9 about debug support.\n */\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\nstatic int arm720t_scan_cp15(struct target *target,\n\t\tuint32_t out, uint32_t *in, int instruction, int clock_arg)\n{\n\tint retval;\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\tstruct arm_jtag *jtag_info;\n\tstruct scan_field fields[2];\n\tuint8_t out_buf[4];\n\tuint8_t instruction_buf = instruction;\n\n\tjtag_info = &arm720t->arm7_9_common.jtag_info;\n\n\tbuf_set_u32(out_buf, 0, 32, flip_u32(out, 32));\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = &instruction_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = out_buf;\n\tfields[1].in_value = NULL;\n\n\tif (in) {\n\t\tfields[1].in_value = (uint8_t *)in;\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);\n\t\tjtag_add_callback(arm7flip32, (jtag_callback_data_t)in);\n\t} else\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);\n\n\tif (clock_arg)\n\t\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (in)\n\t\tLOG_DEBUG(\"out: %8.8x, in: %8.8x, instruction: %i, clock: %i\", out, *in, instruction, clock);\n\telse\n\t\tLOG_DEBUG(\"out: %8.8x, instruction: %i, clock: %i\", out, instruction, clock_arg);\n#else\n\t\tLOG_DEBUG(\"out: %8.8\" PRIx32 \", instruction: %i, clock: %i\", out, instruction, clock_arg);\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_read_cp15(struct target *target, uint32_t opcode, uint32_t *value)\n{\n\t/* fetch CP15 opcode */\n\tarm720t_scan_cp15(target, opcode, NULL, 1, 1);\n\t/* \"DECODE\" stage */\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);\n\t/* \"EXECUTE\" stage (1) */\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0);\n\tarm720t_scan_cp15(target, 0x0, NULL, 0, 1);\n\t/* \"EXECUTE\" stage (2) */\n\tarm720t_scan_cp15(target, 0x0, NULL, 0, 1);\n\t/* \"EXECUTE\" stage (3), CDATA is read */\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, value, 1, 1);\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_write_cp15(struct target *target, uint32_t opcode, uint32_t value)\n{\n\t/* fetch CP15 opcode */\n\tarm720t_scan_cp15(target, opcode, NULL, 1, 1);\n\t/* \"DECODE\" stage */\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);\n\t/* \"EXECUTE\" stage (1) */\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 0);\n\tarm720t_scan_cp15(target, 0x0, NULL, 0, 1);\n\t/* \"EXECUTE\" stage (2) */\n\tarm720t_scan_cp15(target, value, NULL, 0, 1);\n\tarm720t_scan_cp15(target, ARMV4_5_NOP, NULL, 1, 1);\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_get_ttb(struct target *target, uint32_t *result)\n{\n\tuint32_t ttb = 0x0;\n\n\tint retval;\n\n\tretval = arm720t_read_cp15(target, 0xee120f10, &ttb);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tttb &= 0xffffc000;\n\n\t*result = ttb;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_disable_mmu_caches(struct target *target,\n\t\tint mmu, int d_u_cache, int i_cache)\n{\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm720t_read_cp15(target, 0xee110f10, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu)\n\t\tcp15_control &= ~0x1U;\n\n\tif (d_u_cache || i_cache)\n\t\tcp15_control &= ~0x4U;\n\n\tretval = arm720t_write_cp15(target, 0xee010f10, cp15_control);\n\treturn retval;\n}\n\nstatic int arm720t_enable_mmu_caches(struct target *target,\n\t\tint mmu, int d_u_cache, int i_cache)\n{\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm720t_read_cp15(target, 0xee110f10, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu)\n\t\tcp15_control |= 0x1U;\n\n\tif (d_u_cache || i_cache)\n\t\tcp15_control |= 0x4U;\n\n\tretval = arm720t_write_cp15(target, 0xee010f10, cp15_control);\n\treturn retval;\n}\n\nstatic int arm720t_post_debug_entry(struct target *target)\n{\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\tint retval;\n\n\t/* examine cp15 control reg */\n\tretval = arm720t_read_cp15(target, 0xee110f10, &arm720t->cp15_control_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"cp15_control_reg: %8.8\" PRIx32 \"\", arm720t->cp15_control_reg);\n\n\tarm720t->armv4_5_mmu.mmu_enabled = (arm720t->cp15_control_reg & 0x1U) ? 1 : 0;\n\tarm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm720t->cp15_control_reg & 0x4U) ? 1 : 0;\n\tarm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;\n\n\t/* save i/d fault status and address register */\n\tretval = arm720t_read_cp15(target, 0xee150f10, &arm720t->fsr_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm720t_read_cp15(target, 0xee160f10, &arm720t->far_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\treturn retval;\n}\n\nstatic void arm720t_pre_restore_context(struct target *target)\n{\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\t/* restore i/d fault status and address register */\n\tarm720t_write_cp15(target, 0xee050f10, arm720t->fsr_reg);\n\tarm720t_write_cp15(target, 0xee060f10, arm720t->far_reg);\n}\n\nstatic int arm720t_arch_state(struct target *target)\n{\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\tstatic const char *state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tarm_arch_state(target);\n\tLOG_USER(\"MMU: %s, Cache: %s\",\n\t\t\t state[arm720t->armv4_5_mmu.mmu_enabled],\n\t\t\t state[arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled]);\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720_mmu(struct target *target, int *enabled)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\t*enabled = target_to_arm720(target)->armv4_5_mmu.mmu_enabled;\n\treturn ERROR_OK;\n}\n\nstatic int arm720_virt2phys(struct target *target,\n\t\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tuint32_t cb;\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\tuint32_t ret;\n\tint retval = armv4_5_mmu_translate_va(target,\n\t\t\t&arm720t->armv4_5_mmu, virtual, &cb, &ret);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t*physical = ret;\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_read_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\t/* disable cache, but leave MMU enabled */\n\tif (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {\n\t\tretval = arm720t_disable_mmu_caches(target, 0, 1, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = arm7_9_read_memory(target, address, size, count, buffer);\n\n\tif (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {\n\t\tretval = arm720t_enable_mmu_caches(target, 0, 1, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int arm720t_read_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\treturn armv4_5_mmu_read_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer);\n}\n\nstatic int arm720t_write_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\n\treturn armv4_5_mmu_write_physical(target, &arm720t->armv4_5_mmu, address, size, count, buffer);\n}\n\nstatic int arm720t_soft_reset_halt(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct arm720t_common *arm720t = target_to_arm720(target);\n\tstruct reg *dbg_stat = &arm720t->arm7_9_common\n\t\t\t.eice_cache->reg_list[EICE_DBG_STAT];\n\tstruct arm *arm = &arm720t->arm7_9_common.arm;\n\n\tretval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms();\n\tint timeout;\n\twhile (!(timeout = ((timeval_ms()-then) > 1000))) {\n\t\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {\n\t\t\tembeddedice_read_reg(dbg_stat);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else\n\t\t\tbreak;\n\t\tif (debug_level >= 3)\n\t\t\talive_sleep(100);\n\t\telse\n\t\t\tkeep_alive();\n\t}\n\tif (timeout) {\n\t\tLOG_ERROR(\"Failed to halt CPU after 1 sec\");\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\ttarget->state = TARGET_HALTED;\n\n\t/* SVC, ARM state, IRQ and FIQ disabled */\n\tuint32_t cpsr;\n\n\tcpsr = buf_get_u32(arm->cpsr->value, 0, 32);\n\tcpsr &= ~0xff;\n\tcpsr |= 0xd3;\n\tarm_set_cpsr(arm, cpsr);\n\tarm->cpsr->dirty = true;\n\n\t/* start fetching from 0x0 */\n\tbuf_set_u32(arm->pc->value, 0, 32, 0x0);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\tretval = arm720t_disable_mmu_caches(target, 1, 1, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tarm720t->armv4_5_mmu.mmu_enabled = 0;\n\tarm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;\n\tarm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;\n\n\tretval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\treturn arm7tdmi_init_target(cmd_ctx, target);\n}\n\nstatic void arm720t_deinit_target(struct target *target)\n{\n\tarm7tdmi_deinit_target(target);\n}\n\n/* FIXME remove forward decls */\nstatic int arm720t_mrc(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t *value);\nstatic int arm720t_mcr(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t value);\n\nstatic int arm720t_init_arch_info(struct target *target,\n\t\tstruct arm720t_common *arm720t, struct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm720t->arm7_9_common;\n\n\tarm7_9->arm.mrc = arm720t_mrc;\n\tarm7_9->arm.mcr = arm720t_mcr;\n\n\tarm7tdmi_init_arch_info(target, arm7_9, tap);\n\n\tarm720t->common_magic = ARM720T_COMMON_MAGIC;\n\n\tarm7_9->post_debug_entry = arm720t_post_debug_entry;\n\tarm7_9->pre_restore_context = arm720t_pre_restore_context;\n\n\tarm720t->armv4_5_mmu.armv4_5_cache.ctype = -1;\n\tarm720t->armv4_5_mmu.get_ttb = arm720t_get_ttb;\n\tarm720t->armv4_5_mmu.read_memory = arm7_9_read_memory;\n\tarm720t->armv4_5_mmu.write_memory = arm7_9_write_memory;\n\tarm720t->armv4_5_mmu.disable_mmu_caches = arm720t_disable_mmu_caches;\n\tarm720t->armv4_5_mmu.enable_mmu_caches = arm720t_enable_mmu_caches;\n\tarm720t->armv4_5_mmu.has_tiny_pages = 0;\n\tarm720t->armv4_5_mmu.mmu_enabled = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm720t_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm720t_common *arm720t = calloc(1, sizeof(*arm720t));\n\n\tarm720t->arm7_9_common.arm.arch = ARM_ARCH_V4;\n\treturn arm720t_init_arch_info(target, arm720t, target->tap);\n}\n\nstatic int arm720t_mrc(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t *value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* read \"to\" r0 */\n\treturn arm720t_read_cp15(target,\n\t\t\tARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n\n}\n\nstatic int arm720t_mcr(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* write \"from\" r0 */\n\treturn arm720t_write_cp15(target,\n\t\t\tARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n}\n\nstatic const struct command_registration arm720t_command_handlers[] = {\n\t{\n\t\t.chain = arm7_9_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM720 targets. */\nstruct target_type arm720t_target = {\n\t.name = \"arm720t\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm720t_arch_state,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm720t_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm720t_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\t.read_phys_memory = arm720t_read_phys_memory,\n\t.write_phys_memory = arm720t_write_phys_memory,\n\t.mmu = arm720_mmu,\n\t.virt2phys = arm720_virt2phys,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm720t_command_handlers,\n\t.target_create = arm720t_target_create,\n\t.init_target = arm720t_init_target,\n\t.deinit_target = arm720t_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm720t.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM720T_H\n#define OPENOCD_TARGET_ARM720T_H\n\n#include \"arm7tdmi.h\"\n#include \"armv4_5_mmu.h\"\n\n#define\tARM720T_COMMON_MAGIC 0xa720a720U\n\nstruct arm720t_common {\n\tunsigned int common_magic;\n\n\tstruct arm7_9_common arm7_9_common;\n\tstruct armv4_5_mmu_common armv4_5_mmu;\n\tuint32_t cp15_control_reg;\n\tuint32_t fsr_reg;\n\tuint32_t far_reg;\n};\n\nstatic inline struct arm720t_common *target_to_arm720(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm720t_common, arm7_9_common.arm);\n}\n\n#endif /* OPENOCD_TARGET_ARM720T_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm7_9_common.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by Hongtao Zheng                                   *\n *   hontor@126.com                                                        *\n *                                                                         *\n *   Copyright (C) 2009 by David Brownell                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"embeddedice.h\"\n#include \"target_request.h\"\n#include \"etm.h\"\n#include <helper/time_support.h>\n#include \"arm_simulator.h\"\n#include \"arm_semihosting.h\"\n#include \"algorithm.h\"\n#include \"register.h\"\n#include \"armv4_5.h\"\n\n/**\n * @file\n * Hold common code supporting the ARM7 and ARM9 core generations.\n *\n * While the ARM core implementations evolved substantially during these\n * two generations, they look quite similar from the JTAG perspective.\n * Both have similar debug facilities, based on the same two scan chains\n * providing access to the core and to an EmbeddedICE module.  Both can\n * support similar ETM and ETB modules, for tracing.  And both expose\n * what could be viewed as \"ARM Classic\", with multiple processor modes,\n * shadowed registers, and support for the Thumb instruction set.\n *\n * Processor differences include things like presence or absence of MMU\n * and cache, pipeline sizes, use of a modified Harvard Architecture\n * (with separate instruction and data buses from the CPU), support\n * for cpu clock gating during idle, and more.\n */\n\nstatic int arm7_9_debug_entry(struct target *target);\n\n/**\n * Clear watchpoints for an ARM7/9 target.\n *\n * @param arm7_9 Pointer to the common struct for an ARM7/9 target\n * @return JTAG error status after executing queue\n */\nstatic int arm7_9_clear_watchpoints(struct arm7_9_common *arm7_9)\n{\n\tLOG_DEBUG(\"-\");\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);\n\tarm7_9->sw_breakpoint_count = 0;\n\tarm7_9->sw_breakpoints_added = 0;\n\tarm7_9->wp0_used = 0;\n\tarm7_9->wp1_used = arm7_9->wp1_used_default;\n\tarm7_9->wp_available = arm7_9->wp_available_max;\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Assign a watchpoint to one of the two available hardware comparators in an\n * ARM7 or ARM9 target.\n *\n * @param arm7_9 Pointer to the common struct for an ARM7/9 target\n * @param breakpoint Pointer to the breakpoint to be used as a watchpoint\n */\nstatic void arm7_9_assign_wp(struct arm7_9_common *arm7_9, struct breakpoint *breakpoint)\n{\n\tif (!arm7_9->wp0_used) {\n\t\tarm7_9->wp0_used = 1;\n\t\tbreakpoint_hw_set(breakpoint, 0);\n\t\tarm7_9->wp_available--;\n\t} else if (!arm7_9->wp1_used) {\n\t\tarm7_9->wp1_used = 1;\n\t\tbreakpoint_hw_set(breakpoint, 1);\n\t\tarm7_9->wp_available--;\n\t} else {\n\t\tLOG_ERROR(\"BUG: no hardware comparator available\");\n\t}\n\n\tLOG_DEBUG(\"BPID: %\" PRIu32 \" (0x%08\" TARGET_PRIxADDR \") using hw wp: %u\",\n\t\t\tbreakpoint->unique_id,\n\t\t\tbreakpoint->address,\n\t\t\tbreakpoint->number);\n}\n\n/**\n * Setup an ARM7/9 target's embedded ICE registers for software breakpoints.\n *\n * @param arm7_9 Pointer to common struct for ARM7/9 targets\n * @return Error codes if there is a problem finding a watchpoint or the result\n * of executing the JTAG queue\n */\nstatic int arm7_9_set_software_breakpoints(struct arm7_9_common *arm7_9)\n{\n\tif (arm7_9->sw_breakpoints_added)\n\t\treturn ERROR_OK;\n\tif (arm7_9->wp_available < 1) {\n\t\tLOG_WARNING(\"can't enable sw breakpoints with no watchpoint unit available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tarm7_9->wp_available--;\n\n\t/* pick a breakpoint unit */\n\tif (!arm7_9->wp0_used) {\n\t\tarm7_9->sw_breakpoints_added = 1;\n\t\tarm7_9->wp0_used = 3;\n\t} else if (!arm7_9->wp1_used) {\n\t\tarm7_9->sw_breakpoints_added = 2;\n\t\tarm7_9->wp1_used = 3;\n\t} else {\n\t\tLOG_ERROR(\"BUG: both watchpoints used, but wp_available >= 1\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (arm7_9->sw_breakpoints_added == 1) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE], arm7_9->arm_bkpt);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0x0);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffffu);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);\n\t} else if (arm7_9->sw_breakpoints_added == 2) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE], arm7_9->arm_bkpt);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0x0);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0xffffffffu);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);\n\t} else {\n\t\tLOG_ERROR(\"BUG: both watchpoints used, but wp_available >= 1\");\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"SW BP using hw wp: %d\",\n\t\tarm7_9->sw_breakpoints_added);\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Setup the common pieces for an ARM7/9 target after reset or on startup.\n *\n * @param target Pointer to an ARM7/9 target to setup\n * @return Result of clearing the watchpoints on the target\n */\nstatic int arm7_9_setup(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\treturn arm7_9_clear_watchpoints(arm7_9);\n}\n\n/**\n * Set either a hardware or software breakpoint on an ARM7/9 target.  The\n * breakpoint is set up even if it is already set.  Some actions, e.g. reset,\n * might have erased the values in Embedded ICE.\n *\n * @param target Pointer to the target device to set the breakpoints on\n * @param breakpoint Pointer to the breakpoint to be set\n * @return For hardware breakpoints, this is the result of executing the JTAG\n * queue.  For software breakpoints, this will be the status of the\n * required memory reads and writes\n */\nstatic int arm7_9_set_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"BPID: %\" PRIu32 \", Address: 0x%08\" TARGET_PRIxADDR \", Type: %d\",\n\t\tbreakpoint->unique_id,\n\t\tbreakpoint->address,\n\t\tbreakpoint->type);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\t/* either an ARM (4 byte) or Thumb (2 byte) breakpoint */\n\t\tuint32_t mask = (breakpoint->length == 4) ? 0x3u : 0x1u;\n\n\t\t/* reassign a hw breakpoint */\n\t\tif (!breakpoint->is_set)\n\t\t\tarm7_9_assign_wp(arm7_9, breakpoint);\n\n\t\tif (breakpoint->number == 0) {\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], breakpoint->address);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffffu);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);\n\t\t} else if (breakpoint->number == 1) {\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], breakpoint->address);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffffu);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], EICE_W_CTRL_ENABLE);\n\t\t} else {\n\t\t\tLOG_ERROR(\"BUG: no hardware comparator available\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tretval = jtag_execute_queue();\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\t/* did we already set this breakpoint? */\n\t\tif (breakpoint->is_set)\n\t\t\treturn ERROR_OK;\n\n\t\tif (breakpoint->length == 4) {\n\t\t\tuint32_t verify = 0xffffffff;\n\t\t\t/* keep the original instruction in target endianness */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* write the breakpoint instruction in target\n\t\t\t * endianness (arm7_9->arm_bkpt is host endian) */\n\t\t\tretval = target_write_u32(target, breakpoint->address, arm7_9->arm_bkpt);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_read_u32(target, breakpoint->address, &verify);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (verify != arm7_9->arm_bkpt) {\n\t\t\t\tLOG_ERROR(\"Unable to set 32 bit software breakpoint at address %08\" TARGET_PRIxADDR\n\t\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t} else {\n\t\t\tuint16_t verify = 0xffff;\n\t\t\t/* keep the original instruction in target endianness */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* write the breakpoint instruction in target\n\t\t\t * endianness (arm7_9->thumb_bkpt is host endian) */\n\t\t\tretval = target_write_u16(target, breakpoint->address, arm7_9->thumb_bkpt);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_read_u16(target, breakpoint->address, &verify);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (verify != arm7_9->thumb_bkpt) {\n\t\t\t\tLOG_ERROR(\"Unable to set thumb software breakpoint at address %08\" TARGET_PRIxADDR\n\t\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\n\t\tretval = arm7_9_set_software_breakpoints(arm7_9);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tarm7_9->sw_breakpoint_count++;\n\n\t\tbreakpoint->is_set = true;\n\t}\n\n\treturn retval;\n}\n\n/**\n * Unsets an existing breakpoint on an ARM7/9 target.  If it is a hardware\n * breakpoint, the watchpoint used will be freed and the Embedded ICE registers\n * will be updated.  Otherwise, the software breakpoint will be restored to its\n * original instruction if it hasn't already been modified.\n *\n * @param target Pointer to ARM7/9 target to unset the breakpoint from\n * @param breakpoint Pointer to breakpoint to be unset\n * @return For hardware breakpoints, this is the result of executing the JTAG\n * queue.  For software breakpoints, this will be the status of the\n * required memory reads and writes\n */\nstatic int arm7_9_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tLOG_DEBUG(\"BPID: %\" PRIu32 \", Address: 0x%08\" TARGET_PRIxADDR,\n\t\tbreakpoint->unique_id,\n\t\tbreakpoint->address);\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tLOG_DEBUG(\"BPID: %\" PRIu32 \" Releasing hw wp: %d\",\n\t\t\tbreakpoint->unique_id,\n\t\t\tbreakpoint->is_set);\n\t\tif (breakpoint->number == 0) {\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);\n\t\t\tarm7_9->wp0_used = 0;\n\t\t\tarm7_9->wp_available++;\n\t\t} else if (breakpoint->number == 1) {\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);\n\t\t\tarm7_9->wp1_used = 0;\n\t\t\tarm7_9->wp_available++;\n\t\t}\n\t\tretval = jtag_execute_queue();\n\t\tbreakpoint->is_set = false;\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tif (breakpoint->length == 4) {\n\t\t\tuint32_t current_instr;\n\t\t\t/* check that user program as not modified breakpoint instruction */\n\t\t\tretval = target_read_memory(target,\n\t\t\t\t\tbreakpoint->address, 4, 1, (uint8_t *)&current_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tcurrent_instr = target_buffer_get_u32(target, (uint8_t *)&current_instr);\n\t\t\tif (current_instr == arm7_9->arm_bkpt) {\n\t\t\t\tretval = target_write_memory(target,\n\t\t\t\t\t\tbreakpoint->address, 4, 1, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t} else {\n\t\t\tuint16_t current_instr;\n\t\t\t/* check that user program as not modified breakpoint instruction */\n\t\t\tretval = target_read_memory(target,\n\t\t\t\t\tbreakpoint->address, 2, 1, (uint8_t *)&current_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tcurrent_instr = target_buffer_get_u16(target, (uint8_t *)&current_instr);\n\t\t\tif (current_instr == arm7_9->thumb_bkpt) {\n\t\t\t\tretval = target_write_memory(target,\n\t\t\t\t\t\tbreakpoint->address, 2, 1, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\tif (--arm7_9->sw_breakpoint_count == 0) {\n\t\t\t/* We have removed the last sw breakpoint, clear the hw breakpoint we used\n\t\t\t *to implement it */\n\t\t\tif (arm7_9->sw_breakpoints_added == 1)\n\t\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\tEICE_W0_CONTROL_VALUE], 0);\n\t\t\telse if (arm7_9->sw_breakpoints_added == 2)\n\t\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\tEICE_W1_CONTROL_VALUE], 0);\n\t\t}\n\n\t\tbreakpoint->is_set = false;\n\t}\n\n\treturn retval;\n}\n\n/**\n * Add a breakpoint to an ARM7/9 target.  This makes sure that there are no\n * dangling breakpoints and that the desired breakpoint can be added.\n *\n * @param target Pointer to the target ARM7/9 device to add a breakpoint to\n * @param breakpoint Pointer to the breakpoint to be added\n * @return An error status if there is a problem adding the breakpoint or the\n * result of setting the breakpoint\n */\nint arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (arm7_9->breakpoint_count == 0) {\n\t\t/* make sure we don't have any dangling breakpoints. This is vital upon\n\t\t * GDB connect/disconnect\n\t\t */\n\t\tarm7_9_clear_watchpoints(arm7_9);\n\t}\n\n\tif ((breakpoint->type == BKPT_HARD) && (arm7_9->wp_available < 1)) {\n\t\tLOG_INFO(\"no watchpoint unit available for hardware breakpoint\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif ((breakpoint->length != 2) && (breakpoint->length != 4)) {\n\t\tLOG_INFO(\"only breakpoints of two (Thumb) or four (ARM) bytes length supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tarm7_9_assign_wp(arm7_9, breakpoint);\n\n\tarm7_9->breakpoint_count++;\n\n\treturn arm7_9_set_breakpoint(target, breakpoint);\n}\n\n/**\n * Removes a breakpoint from an ARM7/9 target.  This will make sure there are no\n * dangling breakpoints and updates available watchpoints if it is a hardware\n * breakpoint.\n *\n * @param target Pointer to the target to have a breakpoint removed\n * @param breakpoint Pointer to the breakpoint to be removed\n * @return Error status if there was a problem unsetting the breakpoint or the\n * watchpoints could not be cleared\n */\nint arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tretval = arm7_9_unset_breakpoint(target, breakpoint);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tarm7_9->wp_available++;\n\n\tarm7_9->breakpoint_count--;\n\tif (arm7_9->breakpoint_count == 0) {\n\t\t/* make sure we don't have any dangling breakpoints */\n\t\tretval = arm7_9_clear_watchpoints(arm7_9);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sets a watchpoint for an ARM7/9 target in one of the watchpoint units.  It is\n * considered a bug to call this function when there are no available watchpoint\n * units.\n *\n * @param target Pointer to an ARM7/9 target to set a watchpoint on\n * @param watchpoint Pointer to the watchpoint to be set\n * @return Error status if watchpoint set fails or the result of executing the\n * JTAG queue\n */\nstatic int arm7_9_set_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tint rw_mask = 1;\n\tuint32_t mask;\n\n\tmask = watchpoint->length - 1;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->rw == WPT_ACCESS)\n\t\trw_mask = 0;\n\telse\n\t\trw_mask = 1;\n\n\tif (!arm7_9->wp0_used) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE],\n\t\t\twatchpoint->address);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], mask);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK],\n\t\t\twatchpoint->mask);\n\t\tif (watchpoint->mask != 0xffffffffu)\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_VALUE],\n\t\t\t\twatchpoint->value);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK],\n\t\t\t0xff & ~EICE_W_CTRL_NOPC & ~rw_mask);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE],\n\t\t\tEICE_W_CTRL_ENABLE | EICE_W_CTRL_NOPC | (watchpoint->rw & 1));\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twatchpoint_set(watchpoint, 1);\n\t\tarm7_9->wp0_used = 2;\n\t} else if (!arm7_9->wp1_used) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE],\n\t\t\twatchpoint->address);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], mask);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK],\n\t\t\twatchpoint->mask);\n\t\tif (watchpoint->mask != 0xffffffffu)\n\t\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_VALUE],\n\t\t\t\twatchpoint->value);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK],\n\t\t\t0xff & ~EICE_W_CTRL_NOPC & ~rw_mask);\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE],\n\t\t\tEICE_W_CTRL_ENABLE | EICE_W_CTRL_NOPC | (watchpoint->rw & 1));\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twatchpoint_set(watchpoint, 2);\n\t\tarm7_9->wp1_used = 2;\n\t} else {\n\t\tLOG_ERROR(\"BUG: no hardware comparator available\");\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Unset an existing watchpoint and clear the used watchpoint unit.\n *\n * @param target Pointer to the target to have the watchpoint removed\n * @param watchpoint Pointer to the watchpoint to be removed\n * @return Error status while trying to unset the watchpoint or the result of\n *         executing the JTAG queue\n */\nstatic int arm7_9_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (watchpoint->number == 1) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarm7_9->wp0_used = 0;\n\t} else if (watchpoint->number == 2) {\n\t\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarm7_9->wp1_used = 0;\n\t}\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Add a watchpoint to an ARM7/9 target.  If there are no watchpoint units\n * available, an error response is returned.\n *\n * @param target Pointer to the ARM7/9 target to add a watchpoint to\n * @param watchpoint Pointer to the watchpoint to be added\n * @return Error status while trying to add the watchpoint\n */\nint arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (arm7_9->wp_available < 1)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tarm7_9->wp_available--;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Remove a watchpoint from an ARM7/9 target.  The watchpoint will be unset and\n * the used watchpoint unit will be reopened.\n *\n * @param target Pointer to the target to remove a watchpoint from\n * @param watchpoint Pointer to the watchpoint to be removed\n * @return Result of trying to unset the watchpoint\n */\nint arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (watchpoint->is_set) {\n\t\tretval = arm7_9_unset_watchpoint(target, watchpoint);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tarm7_9->wp_available++;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Restarts the target by sending a RESTART instruction and moving the JTAG\n * state to IDLE.  This includes a timeout waiting for DBGACK and SYSCOMP to be\n * asserted by the processor.\n *\n * @param target Pointer to target to issue commands to\n * @return Error status if there is a timeout or a problem while executing the\n * JTAG queue\n */\nint arm7_9_execute_sys_speed(struct target *target)\n{\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\t/* set RESTART instruction */\n\tif (arm7_9->need_bypass_before_restart) {\n\t\tarm7_9->need_bypass_before_restart = 0;\n\t\tretval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms();\n\tbool timeout;\n\twhile (!(timeout = ((timeval_ms()-then) > 1000))) {\n\t\t/* read debug status register */\n\t\tembeddedice_read_reg(dbg_stat);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif ((buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1))\n\t\t\t\t&& (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_SYSCOMP, 1)))\n\t\t\tbreak;\n\t\tif (debug_level >= 3)\n\t\t\talive_sleep(100);\n\t\telse\n\t\t\tkeep_alive();\n\t}\n\tif (timeout) {\n\t\tLOG_ERROR(\"timeout waiting for SYSCOMP & DBGACK, last DBG_STATUS: %\" PRIx32 \"\",\n\t\t\tbuf_get_u32(dbg_stat->value, 0, dbg_stat->size));\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Restarts the target by sending a RESTART instruction and moving the JTAG\n * state to IDLE.  This validates that DBGACK and SYSCOMP are set without\n * waiting until they are.\n *\n * @param target Pointer to the target to issue commands to\n * @return Always ERROR_OK\n */\nstatic int arm7_9_execute_fast_sys_speed(struct target *target)\n{\n\tstatic int set;\n\tstatic uint8_t check_value[4], check_mask[4];\n\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\tint retval;\n\n\t/* set RESTART instruction */\n\tif (arm7_9->need_bypass_before_restart) {\n\t\tarm7_9->need_bypass_before_restart = 0;\n\t\tretval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!set) {\n\t\t/* check for DBGACK and SYSCOMP set (others don't care) */\n\n\t\t/* NB! These are constants that must be available until after next jtag_execute() and\n\t\t * we evaluate the values upon first execution in lieu of setting up these constants\n\t\t * during early setup.\n\t\t * */\n\t\tbuf_set_u32(check_value, 0, 32, 0x9);\n\t\tbuf_set_u32(check_mask, 0, 32, 0x9);\n\t\tset = 1;\n\t}\n\n\t/* read debug status register */\n\tembeddedice_read_reg_w_check(dbg_stat, check_value, check_mask);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Get some data from the ARM7/9 target.\n *\n * @param target Pointer to the ARM7/9 target to read data from\n * @param size The number of 32bit words to be read\n * @param buffer Pointer to the buffer that will hold the data\n * @return The result of receiving data from the Embedded ICE unit\n */\nint arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tuint32_t *data;\n\tint retval = ERROR_OK;\n\tuint32_t i;\n\n\tdata = malloc(size * (sizeof(uint32_t)));\n\n\tretval = embeddedice_receive(jtag_info, data, size);\n\n\t/* return the 32-bit ints in the 8-bit array */\n\tfor (i = 0; i < size; i++)\n\t\th_u32_to_le(buffer + (i * 4), data[i]);\n\n\tfree(data);\n\n\treturn retval;\n}\n\n/**\n * Handles requests to an ARM7/9 target.  If debug messaging is enabled, the\n * target is running and the DCC control register has the W bit high, this will\n * execute the request on the target.\n *\n * @param priv Void pointer expected to be a struct target pointer\n * @return ERROR_OK unless there are issues with the JTAG queue or when reading\n * from the Embedded ICE unit\n */\nstatic int arm7_9_handle_target_request(void *priv)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target = priv;\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct reg *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];\n\n\tif (!target->dbg_msg_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->state == TARGET_RUNNING) {\n\t\t/* read DCC control register */\n\t\tembeddedice_read_reg(dcc_control);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* check W bit */\n\t\tif (buf_get_u32(dcc_control->value, 1, 1) == 1) {\n\t\t\tuint32_t request;\n\n\t\t\tretval = embeddedice_receive(jtag_info, &request, 1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_request(target, request);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Polls an ARM7/9 target for its current status.  If DBGACK is set, the target\n * is manipulated to the right halted state based on its current state.  This is\n * what happens:\n *\n * <table>\n *   <tr><th > State</th><th > Action</th></tr>\n *   <tr><td > TARGET_RUNNING | TARGET_RESET</td>\n *     <td > Enters debug mode.  If TARGET_RESET, pc may be checked</td></tr>\n *   <tr><td > TARGET_UNKNOWN</td><td > Warning is logged</td></tr>\n *   <tr><td > TARGET_DEBUG_RUNNING</td><td > Enters debug mode</td></tr>\n *   <tr><td > TARGET_HALTED</td><td > Nothing</td></tr>\n * </table>\n *\n * If the target does not end up in the halted state, a warning is produced.  If\n * DBGACK is cleared, then the target is expected to either be running or\n * running in debug.\n *\n * @param target Pointer to the ARM7/9 target to poll\n * @return ERROR_OK or an error status if a command fails\n */\nint arm7_9_poll(struct target *target)\n{\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\t/* read debug status register */\n\tembeddedice_read_reg(dbg_stat);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1)) {\n\t\t/* LOG_DEBUG(\"DBGACK set, dbg_state->value: 0x%x\", buf_get_u32(dbg_stat->value, 0, *32));*/\n\t\tif (target->state == TARGET_UNKNOWN) {\n\t\t\t/* Starting OpenOCD with target in debug-halt */\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\tLOG_DEBUG(\"DBGACK already set during server startup.\");\n\t\t}\n\t\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = arm7_9_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (arm_semihosting(target, &retval) != 0)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tif (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tretval = arm7_9_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tif (target->state != TARGET_HALTED)\n\t\t\tLOG_WARNING(\n\t\t\t\t\"DBGACK set, but the target did not end up in the halted state %d\",\n\t\t\t\ttarget->state);\n\t} else {\n\t\tif (target->state != TARGET_DEBUG_RUNNING)\n\t\t\ttarget->state = TARGET_RUNNING;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Asserts the reset (SRST) on an ARM7/9 target.  Some -S targets (ARM966E-S in\n * the STR912 isn't affected, ARM926EJ-S in the LPC3180 and AT91SAM9260 is\n * affected) completely stop the JTAG clock while the core is held in reset\n * (SRST).  It isn't possible to program the halt condition once reset is\n * asserted, hence a hook that allows the target to set up its reset-halt\n * condition is setup prior to asserting reset.\n *\n * @param target Pointer to an ARM7/9 target to assert reset on\n * @return ERROR_FAIL if the JTAG device does not have SRST, otherwise ERROR_OK\n */\nint arm7_9_assert_reset(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tbool use_event = false;\n\n\t/* TODO: apply hw reset signal in not examined state */\n\tif (!(target_was_examined(target))) {\n\t\tLOG_WARNING(\"Reset is not asserted because the target is not examined.\");\n\t\tLOG_WARNING(\"Use a reset button or power cycle the target.\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))\n\t\tuse_event = true;\n\telse if (!(jtag_reset_config & RESET_HAS_SRST)) {\n\t\tLOG_ERROR(\"%s: how to reset?\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* At this point trst has been asserted/deasserted once. We would\n\t * like to program EmbeddedICE while SRST is asserted, instead of\n\t * depending on SRST to leave that module alone.  However, many CPUs\n\t * gate the JTAG clock while SRST is asserted; or JTAG may need\n\t * clock stability guarantees (adaptive clocking might help).\n\t *\n\t * So we assume JTAG access during SRST is off the menu unless it's\n\t * been specifically enabled.\n\t */\n\tbool srst_asserted = false;\n\n\tif (!use_event && !(jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\t&& (jtag_reset_config & RESET_SRST_NO_GATING)) {\n\t\tjtag_add_reset(0, 1);\n\t\tsrst_asserted = true;\n\t}\n\n\tif (target->reset_halt) {\n\t\t/*\n\t\t * For targets that don't support communication while SRST is\n\t\t * asserted, we need to set up the reset vector catch first.\n\t\t *\n\t\t * When we use TRST+SRST and that's equivalent to a power-up\n\t\t * reset, these settings may well be reset anyway; so setting\n\t\t * them here won't matter.\n\t\t */\n\t\tif (arm7_9->has_vector_catch) {\n\t\t\t/* program vector catch register to catch reset */\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0x1);\n\n\t\t\t/* extra runtest added as issues were found with\n\t\t\t * certain ARM9 cores (maybe more) - AT91SAM9260\n\t\t\t * and STR9\n\t\t\t */\n\t\t\tjtag_add_runtest(1, TAP_IDLE);\n\t\t} else {\n\t\t\t/* program watchpoint unit to match on reset vector\n\t\t\t * address\n\t\t\t */\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], 0x0);\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0x3);\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], EICE_W_CTRL_ENABLE);\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], ~EICE_W_CTRL_NOPC & 0xff);\n\t\t}\n\t}\n\n\tif (use_event)\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\telse {\n\t\t/* If we use SRST ... we'd like to issue just SRST, but the\n\t\t * board or chip may be set up so we have to assert TRST as\n\t\t * well.  On some chips that combination is equivalent to a\n\t\t * power-up reset, and generally clobbers EICE state.\n\t\t */\n\t\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\tjtag_add_reset(1, 1);\n\t\telse if (!srst_asserted)\n\t\t\tjtag_add_reset(0, 1);\n\t\tjtag_add_sleep(50000);\n\t}\n\n\ttarget->state = TARGET_RESET;\n\tregister_cache_invalidate(arm7_9->arm.core_cache);\n\n\t/* REVISIT why isn't standard debug entry logic sufficient?? */\n\tif (target->reset_halt && (!(jtag_reset_config & RESET_SRST_PULLS_TRST) || use_event)) {\n\t\t/* debug entry was prepared above */\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Deassert the reset (SRST) signal on an ARM7/9 target.  If SRST pulls TRST\n * and the target is being reset into a halt, a warning will be triggered\n * because it is not possible to reset into a halted mode in this case.  The\n * target is halted using the target's functions.\n *\n * @param target Pointer to the target to have the reset deasserted\n * @return ERROR_OK or an error from polling or halting the target\n */\nint arm7_9_deassert_reset(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\t/* deassert reset lines */\n\tjtag_add_reset(0, 0);\n\n\t/* In case polling is disabled, we need to examine the\n\t * target and poll here for this target to work correctly.\n\t *\n\t * Otherwise, e.g. halt will fail afterwards with bogus\n\t * error messages as halt will believe that reset is\n\t * still in effect.\n\t */\n\tretval = target_examine_one(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_poll(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tif (target->reset_halt && (jtag_reset_config & RESET_SRST_PULLS_TRST) != 0) {\n\t\tLOG_WARNING(\n\t\t\t\"srst pulls trst - can not reset into halted mode. Issuing halt after reset.\");\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\n/**\n * Clears the halt condition for an ARM7/9 target.  If it isn't coming out of\n * reset and if DBGRQ is used, it is programmed to be deasserted.  If the reset\n * vector catch was used, it is restored.  Otherwise, the control value is\n * restored and the watchpoint unit is restored if it was in use.\n *\n * @param target Pointer to the ARM7/9 target to have halt cleared\n * @return Always ERROR_OK\n */\nstatic int arm7_9_clear_halt(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n\t/* we used DBGRQ only if we didn't come out of reset */\n\tif (!arm7_9->debug_entry_from_reset && arm7_9->use_dbgrq) {\n\t\t/* program EmbeddedICE Debug Control Register to deassert DBGRQ\n\t\t */\n\t\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);\n\t\tembeddedice_store_reg(dbg_ctrl);\n\t} else {\n\t\tif (arm7_9->debug_entry_from_reset && arm7_9->has_vector_catch) {\n\t\t\t/* if we came out of reset, and vector catch is supported, we used\n\t\t\t * vector catch to enter debug state\n\t\t\t * restore the register in that case\n\t\t\t */\n\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH]);\n\t\t} else {\n\t\t\t/* restore registers if watchpoint unit 0 was in use\n\t\t\t */\n\t\t\tif (arm7_9->wp0_used) {\n\t\t\t\tif (arm7_9->debug_entry_from_reset)\n\t\t\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\t\tEICE_W0_ADDR_VALUE]);\n\t\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\tEICE_W0_ADDR_MASK]);\n\t\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\tEICE_W0_DATA_MASK]);\n\t\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[\n\t\t\t\t\t\tEICE_W0_CONTROL_MASK]);\n\t\t\t}\n\t\t\t/* control value always has to be restored, as it was either disabled,\n\t\t\t * or enabled with possibly different bits\n\t\t\t */\n\t\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Issue a software reset and halt to an ARM7/9 target.  The target is halted\n * and then there is a wait until the processor shows the halt.  This wait can\n * timeout and results in an error being returned.  The software reset involves\n * clearing the halt, updating the debug control register, changing to ARM mode,\n * reset of the program counter, and reset of all of the registers.\n *\n * @param target Pointer to the ARM7/9 target to be reset and halted by software\n * @return Error status if any of the commands fail, otherwise ERROR_OK\n */\nint arm7_9_soft_reset_halt(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\tint i;\n\tint retval;\n\n\t/* FIX!!! replace some of this code with tcl commands\n\t *\n\t * halt # the halt command is synchronous\n\t * armv4_5 core_state arm\n\t *\n\t */\n\n\tretval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tlong long then = timeval_ms();\n\tint timeout;\n\twhile (!(timeout = ((timeval_ms()-then) > 1000))) {\n\t\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) != 0)\n\t\t\tbreak;\n\t\tembeddedice_read_reg(dbg_stat);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (debug_level >= 3)\n\t\t\talive_sleep(100);\n\t\telse\n\t\t\tkeep_alive();\n\t}\n\tif (timeout) {\n\t\tLOG_ERROR(\"Failed to halt CPU after 1 sec\");\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\ttarget->state = TARGET_HALTED;\n\n\t/* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS\n\t * ensure that DBGRQ is cleared\n\t */\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);\n\tembeddedice_store_reg(dbg_ctrl);\n\n\tretval = arm7_9_clear_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* if the target is in Thumb state, change to ARM state */\n\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1)) {\n\t\tuint32_t r0_thumb, pc_thumb;\n\t\tLOG_DEBUG(\"target entered debug from Thumb state, changing to ARM\");\n\t\t/* Entered debug from Thumb mode */\n\t\tarm->core_state = ARM_STATE_THUMB;\n\t\tarm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);\n\t}\n\n\t/* REVISIT likewise for bit 5 -- switch Jazelle-to-ARM */\n\n\t/* all register content is now invalid */\n\tregister_cache_invalidate(arm->core_cache);\n\n\t/* SVC, ARM state, IRQ and FIQ disabled */\n\tuint32_t cpsr;\n\n\tcpsr = buf_get_u32(arm->cpsr->value, 0, 32);\n\tcpsr &= ~0xff;\n\tcpsr |= 0xd3;\n\tarm_set_cpsr(arm, cpsr);\n\tarm->cpsr->dirty = true;\n\n\t/* start fetching from 0x0 */\n\tbuf_set_u32(arm->pc->value, 0, 32, 0x0);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\t/* reset registers */\n\tfor (i = 0; i <= 14; i++) {\n\t\tstruct reg *r = arm_reg_current(arm, i);\n\n\t\tbuf_set_u32(r->value, 0, 32, 0xffffffff);\n\t\tr->dirty = true;\n\t\tr->valid = true;\n\t}\n\n\tretval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Halt an ARM7/9 target.  This is accomplished by either asserting the DBGRQ\n * line or by programming a watchpoint to trigger on any address.  It is\n * considered a bug to call this function while the target is in the\n * TARGET_RESET state.\n *\n * @param target Pointer to the ARM7/9 target to be halted\n * @return Always ERROR_OK\n */\nint arm7_9_halt(struct target *target)\n{\n\tif (target->state == TARGET_RESET) {\n\t\tLOG_ERROR(\n\t\t\t\"BUG: arm7/9 does not support halt during reset. This is handled in arm7_9_assert_reset()\");\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (arm7_9->use_dbgrq) {\n\t\t/* program EmbeddedICE Debug Control Register to assert DBGRQ\n\t\t */\n\t\tif (arm7_9->set_special_dbgrq)\n\t\t\tarm7_9->set_special_dbgrq(target);\n\t\telse {\n\t\t\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 1);\n\t\t\tembeddedice_store_reg(dbg_ctrl);\n\t\t}\n\t} else {\n\t\t/* program watchpoint unit to match on any address\n\t\t */\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE],\n\t\t\tEICE_W_CTRL_ENABLE);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK],\n\t\t\t~EICE_W_CTRL_NOPC & 0xff);\n\t}\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Handle an ARM7/9 target's entry into debug mode.  The halt is cleared on the\n * ARM.  The JTAG queue is then executed and the reason for debug entry is\n * examined.  Once done, the target is verified to be halted and the processor\n * is forced into ARM mode.  The core registers are saved for the current core\n * mode and the program counter (register 15) is updated as needed.  The core\n * registers and CPSR and SPSR are saved for restoration later.\n *\n * @param target Pointer to target that is entering debug mode\n * @return Error code if anything fails, otherwise ERROR_OK\n */\nstatic int arm7_9_debug_entry(struct target *target)\n{\n\tint i;\n\tuint32_t context[16];\n\tuint32_t *context_p[16];\n\tuint32_t r0_thumb, pc_thumb;\n\tuint32_t cpsr, cpsr_mask = 0;\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n#ifdef _DEBUG_ARM7_9_\n\tLOG_DEBUG(\"-\");\n#endif\n\n\t/* program EmbeddedICE Debug Control Register to assert DBGACK and INTDIS\n\t * ensure that DBGRQ is cleared\n\t */\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGRQ, 1, 0);\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 1);\n\tembeddedice_store_reg(dbg_ctrl);\n\n\tretval = arm7_9_clear_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm7_9->examine_debug_reason(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* if the target is in Thumb state, change to ARM state */\n\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_ITBIT, 1)) {\n\t\tLOG_DEBUG(\"target entered debug from Thumb state\");\n\t\t/* Entered debug from Thumb mode */\n\t\tarm->core_state = ARM_STATE_THUMB;\n\t\tcpsr_mask = 1 << 5;\n\t\tarm7_9->change_to_arm(target, &r0_thumb, &pc_thumb);\n\t\tLOG_DEBUG(\"r0_thumb: 0x%8.8\" PRIx32\n\t\t\t\", pc_thumb: 0x%8.8\" PRIx32, r0_thumb, pc_thumb);\n\t} else if (buf_get_u32(dbg_stat->value, 5, 1)) {\n\t\t/* \\todo Get some vaguely correct handling of Jazelle, if\n\t\t * anyone ever uses it and full info becomes available.\n\t\t * See ARM9EJS TRM B.7.1 for how to switch J->ARM; and\n\t\t * B.7.3 for the reverse.  That'd be the bare minimum...\n\t\t */\n\t\tLOG_DEBUG(\"target entered debug from Jazelle state\");\n\t\tarm->core_state = ARM_STATE_JAZELLE;\n\t\tcpsr_mask = 1 << 24;\n\t\tLOG_ERROR(\"Jazelle debug entry -- BROKEN!\");\n\t} else {\n\t\tLOG_DEBUG(\"target entered debug from ARM state\");\n\t\t/* Entered debug from ARM mode */\n\t\tarm->core_state = ARM_STATE_ARM;\n\t}\n\n\tfor (i = 0; i < 16; i++)\n\t\tcontext_p[i] = &context[i];\n\t/* save core registers (r0 - r15 of current core mode) */\n\tarm7_9->read_core_regs(target, 0xffff, context_p);\n\n\tarm7_9->read_xpsr(target, &cpsr, 0);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Sync our CPSR copy with J or T bits EICE reported, but\n\t * which we then erased by putting the core into ARM mode.\n\t */\n\tarm_set_cpsr(arm, cpsr | cpsr_mask);\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\tLOG_ERROR(\"cpsr contains invalid mode value - communication failure\");\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\tLOG_DEBUG(\"target entered debug state in %s mode\",\n\t\tarm_mode_name(arm->core_mode));\n\n\tif (arm->core_state == ARM_STATE_THUMB) {\n\t\tLOG_DEBUG(\"thumb state, applying fixups\");\n\t\tcontext[0] = r0_thumb;\n\t\tcontext[15] = pc_thumb;\n\t} else if (arm->core_state == ARM_STATE_ARM) {\n\t\t/* adjust value stored by STM */\n\t\tcontext[15] -= 3 * 4;\n\t}\n\n\tif ((target->debug_reason != DBG_REASON_DBGRQ) || (!arm7_9->use_dbgrq))\n\t\tcontext[15] -= 3 * ((arm->core_state == ARM_STATE_ARM) ? 4 : 2);\n\telse\n\t\tcontext[15] -= arm7_9->dbgreq_adjust_pc *\n\t\t\t((arm->core_state == ARM_STATE_ARM) ? 4 : 2);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tstruct reg *r = arm_reg_current(arm, i);\n\n\t\tLOG_DEBUG(\"r%i: 0x%8.8\" PRIx32 \"\", i, context[i]);\n\n\t\tbuf_set_u32(r->value, 0, 32, context[i]);\n\t\t/* r0 and r15 (pc) have to be restored later */\n\t\tr->dirty = (i == 0) || (i == 15);\n\t\tr->valid = true;\n\t}\n\n\tLOG_DEBUG(\"entered debug state at PC 0x%\" PRIx32 \"\", context[15]);\n\n\t/* exceptions other than USR & SYS have a saved program status register */\n\tif (arm->spsr) {\n\t\tuint32_t spsr;\n\t\tarm7_9->read_xpsr(target, &spsr, 1);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbuf_set_u32(arm->spsr->value, 0, 32, spsr);\n\t\tarm->spsr->dirty = false;\n\t\tarm->spsr->valid = true;\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (arm7_9->post_debug_entry) {\n\t\tretval = arm7_9->post_debug_entry(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Validate the full context for an ARM7/9 target in all processor modes.  If\n * there are any invalid registers for the target, they will all be read.  This\n * includes the PSR.\n *\n * @param target Pointer to the ARM7/9 target to capture the full context from\n * @return Error if the target is not halted, has an invalid core mode, or if\n *         the JTAG queue fails to execute\n */\nstatic int arm7_9_full_context(struct target *target)\n{\n\tint i;\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct {\n\t\tuint32_t value;\n\t\tuint8_t *reg_p;\n\t} read_cache[6 * (16 + 1)];\n\tint read_cache_idx = 0;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)\n\t * SYS shares registers with User, so we don't touch SYS\n\t */\n\tfor (i = 0; i < 6; i++) {\n\t\tuint32_t mask = 0;\n\t\tuint32_t *reg_p[16];\n\t\tint j;\n\t\tbool valid = true;\n\n\t\t/* check if there are invalid registers in the current mode\n\t\t */\n\t\tfor (j = 0; j <= 16; j++) {\n\t\t\tif (!ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), j).valid)\n\t\t\t\tvalid = false;\n\t\t}\n\n\t\tif (!valid) {\n\t\t\tuint32_t tmp_cpsr;\n\n\t\t\t/* change processor mode (and mask T bit) */\n\t\t\ttmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8)\n\t\t\t\t& 0xe0;\n\t\t\ttmp_cpsr |= armv4_5_number_to_mode(i);\n\t\t\ttmp_cpsr &= ~0x20;\n\t\t\tarm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);\n\n\t\t\tfor (j = 0; j < 15; j++) {\n\t\t\t\tif (!ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\t\tarmv4_5_number_to_mode(i), j).valid) {\n\t\t\t\t\tread_cache[read_cache_idx].reg_p = ARMV4_5_CORE_REG_MODE(\n\t\t\t\t\t\t\tarm->core_cache,\n\t\t\t\t\t\t\tarmv4_5_number_to_mode(i),\n\t\t\t\t\t\t\tj).value;\n\t\t\t\t\treg_p[j] = &read_cache[read_cache_idx].value;\n\t\t\t\t\tread_cache_idx++;\n\t\t\t\t\tmask |= 1 << j;\n\t\t\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\t\tarmv4_5_number_to_mode(i),\n\t\t\t\t\t\tj).valid = true;\n\t\t\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\t\tarmv4_5_number_to_mode(i),\n\t\t\t\t\t\tj).dirty = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* if only the PSR is invalid, mask is all zeroes */\n\t\t\tif (mask)\n\t\t\t\tarm7_9->read_core_regs(target, mask, reg_p);\n\n\t\t\t/* check if the PSR has to be read */\n\t\t\tif (!ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i),\n\t\t\t\t\t16).valid) {\n\t\t\t\tread_cache[read_cache_idx].reg_p = ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\tarmv4_5_number_to_mode(i), 16).value;\n\t\t\t\tarm7_9->read_xpsr(target, &read_cache[read_cache_idx].value, 1);\n\t\t\t\tread_cache_idx++;\n\t\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i),\n\t\t\t\t\t16).valid = true;\n\t\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i),\n\t\t\t\t\t16).dirty = false;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* restore processor mode (mask T bit) */\n\tarm7_9->write_xpsr_im8(target,\n\t\tbuf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/*\n\t * FIXME: regs in cache should be tagged as 'valid' only now,\n\t * not before the jtag_execute_queue()\n\t */\n\twhile (read_cache_idx) {\n\t\tread_cache_idx--;\n\t\tbuf_set_u32(read_cache[read_cache_idx].reg_p, 0, 32, read_cache[read_cache_idx].value);\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * Restore the processor context on an ARM7/9 target.  The full processor\n * context is analyzed to see if any of the registers are dirty on this end, but\n * have a valid new value.  If this is the case, the processor is changed to the\n * appropriate mode and the new register values are written out to the\n * processor.  If there happens to be a dirty register with an invalid value, an\n * error will be logged.\n *\n * @param target Pointer to the ARM7/9 target to have its context restored\n * @return Error status if the target is not halted or the core mode in the\n * armv4_5 struct is invalid.\n */\nstatic int arm7_9_restore_context(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *reg;\n\tenum arm_mode current_mode = arm->core_mode;\n\tint i, j;\n\tbool dirty;\n\tint mode_change;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (arm7_9->pre_restore_context)\n\t\tarm7_9->pre_restore_context(target);\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* iterate through processor modes (User, FIQ, IRQ, SVC, ABT, UND)\n\t * SYS shares registers with User, so we don't touch SYS\n\t */\n\tfor (i = 0; i < 6; i++) {\n\t\tLOG_DEBUG(\"examining %s mode\",\n\t\t\tarm_mode_name(arm->core_mode));\n\t\tdirty = false;\n\t\tmode_change = 0;\n\t\t/* check if there are dirty registers in the current mode\n\t\t*/\n\t\tfor (j = 0; j <= 16; j++) {\n\t\t\treg = &ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(i), j);\n\t\t\tif (reg->dirty) {\n\t\t\t\tif (reg->valid) {\n\t\t\t\t\tdirty = true;\n\t\t\t\t\tLOG_DEBUG(\"examining dirty reg: %s\", reg->name);\n\t\t\t\t\tstruct arm_reg *reg_arch_info;\n\t\t\t\t\treg_arch_info = reg->arch_info;\n\t\t\t\t\tif ((reg_arch_info->mode != ARM_MODE_ANY)\n\t\t\t\t\t\t\t&& (reg_arch_info->mode != current_mode)\n\t\t\t\t\t\t\t&& !((reg_arch_info->mode == ARM_MODE_USR)\n\t\t\t\t\t\t\t&& (arm->core_mode == ARM_MODE_SYS))\n\t\t\t\t\t\t\t&& !((reg_arch_info->mode == ARM_MODE_SYS)\n\t\t\t\t\t\t\t&& (arm->core_mode == ARM_MODE_USR))) {\n\t\t\t\t\t\tmode_change = 1;\n\t\t\t\t\t\tLOG_DEBUG(\"require mode change\");\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t\tLOG_ERROR(\"BUG: dirty register '%s', but no valid data\",\n\t\t\t\t\t\treg->name);\n\t\t\t}\n\t\t}\n\n\t\tif (dirty) {\n\t\t\tuint32_t mask = 0x0;\n\t\t\tuint32_t regs[16];\n\n\t\t\tif (mode_change) {\n\t\t\t\tuint32_t tmp_cpsr;\n\n\t\t\t\t/* change processor mode (mask T bit) */\n\t\t\t\ttmp_cpsr = buf_get_u32(arm->cpsr->value,\n\t\t\t\t\t\t0, 8) & 0xe0;\n\t\t\t\ttmp_cpsr |= armv4_5_number_to_mode(i);\n\t\t\t\ttmp_cpsr &= ~0x20;\n\t\t\t\tarm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);\n\t\t\t\tcurrent_mode = armv4_5_number_to_mode(i);\n\t\t\t}\n\n\t\t\tfor (j = 0; j <= 14; j++) {\n\t\t\t\treg = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\t\tarmv4_5_number_to_mode(i),\n\t\t\t\t\t\tj);\n\n\t\t\t\tif (reg->dirty) {\n\t\t\t\t\tregs[j] = buf_get_u32(reg->value, 0, 32);\n\t\t\t\t\tmask |= 1 << j;\n\t\t\t\t\treg->dirty = false;\n\t\t\t\t\treg->valid = true;\n\t\t\t\t\tLOG_DEBUG(\"writing register %i mode %s \"\n\t\t\t\t\t\t\"with value 0x%8.8\" PRIx32, j,\n\t\t\t\t\t\tarm_mode_name(arm->core_mode),\n\t\t\t\t\t\tregs[j]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (mask)\n\t\t\t\tarm7_9->write_core_regs(target, mask, regs);\n\n\t\t\treg =\n\t\t\t\t&ARMV4_5_CORE_REG_MODE(arm->core_cache, armv4_5_number_to_mode(\n\t\t\t\t\t\ti), 16);\n\t\t\tstruct arm_reg *reg_arch_info;\n\t\t\treg_arch_info = reg->arch_info;\n\t\t\tif ((reg->dirty) && (reg_arch_info->mode != ARM_MODE_ANY)) {\n\t\t\t\tLOG_DEBUG(\"writing SPSR of mode %i with value 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\ti,\n\t\t\t\t\tbuf_get_u32(reg->value, 0, 32));\n\t\t\t\tarm7_9->write_xpsr(target, buf_get_u32(reg->value, 0, 32), 1);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!arm->cpsr->dirty && (arm->core_mode != current_mode)) {\n\t\t/* restore processor mode (mask T bit) */\n\t\tuint32_t tmp_cpsr;\n\n\t\ttmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0;\n\t\ttmp_cpsr |= armv4_5_number_to_mode(i);\n\t\ttmp_cpsr &= ~0x20;\n\t\tLOG_DEBUG(\"writing lower 8 bit of cpsr with value 0x%2.2x\", (unsigned)(tmp_cpsr));\n\t\tarm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);\n\n\t} else if (arm->cpsr->dirty) {\n\t\t/* CPSR has been changed, full restore necessary (mask T bit) */\n\t\tLOG_DEBUG(\"writing cpsr with value 0x%8.8\" PRIx32,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\t\tarm7_9->write_xpsr(target,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 32)\n\t\t\t& ~0x20, 0);\n\t\tarm->cpsr->dirty = false;\n\t\tarm->cpsr->valid = true;\n\t}\n\n\t/* restore PC */\n\tLOG_DEBUG(\"writing PC with value 0x%8.8\" PRIx32,\n\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\tarm7_9->write_pc(target, buf_get_u32(arm->pc->value, 0, 32));\n\tarm->pc->dirty = false;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Restart the core of an ARM7/9 target.  A RESTART command is sent to the\n * instruction register and the JTAG state is set to TAP_IDLE causing a core\n * restart.\n *\n * @param target Pointer to the ARM7/9 target to be restarted\n * @return Result of executing the JTAG queue\n */\nstatic int arm7_9_restart_core(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint retval;\n\n\t/* set RESTART instruction */\n\tif (arm7_9->need_bypass_before_restart) {\n\t\tarm7_9->need_bypass_before_restart = 0;\n\n\t\tretval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = arm_jtag_set_instr(jtag_info->tap, 0x4, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tjtag_add_runtest(1, TAP_IDLE);\n\treturn jtag_execute_queue();\n}\n\n/**\n * Enable the watchpoints on an ARM7/9 target.  The target's watchpoints are\n * iterated through and are set on the target if they aren't already set.\n *\n * @param target Pointer to the ARM7/9 target to enable watchpoints on\n */\nstatic void arm7_9_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\tarm7_9_set_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n}\n\n/**\n * Enable the breakpoints on an ARM7/9 target.  The target's breakpoints are\n * iterated through and are set on the target.\n *\n * @param target Pointer to the ARM7/9 target to enable breakpoints on\n */\nstatic void arm7_9_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\t/* set any pending breakpoints */\n\twhile (breakpoint) {\n\t\tarm7_9_set_breakpoint(target, breakpoint);\n\t\tbreakpoint = breakpoint->next;\n\t}\n}\n\nint arm7_9_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\tint err, retval = ERROR_OK;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current)\n\t\tbuf_set_u32(arm->pc->value, 0, 32, address);\n\n\tuint32_t current_pc;\n\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tstruct breakpoint *breakpoint;\n\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at 0x%8.8\" TARGET_PRIxADDR \" (id: %\" PRIu32,\n\t\t\t\tbreakpoint->address,\n\t\t\t\tbreakpoint->unique_id);\n\t\t\tretval = arm7_9_unset_breakpoint(target, breakpoint);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* calculate PC of next instruction */\n\t\t\tuint32_t next_pc;\n\t\t\tretval = arm_simulate_step(target, &next_pc);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tuint32_t current_opcode;\n\t\t\t\ttarget_read_u32(target, current_pc, &current_opcode);\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Couldn't calculate PC of next instruction, current opcode was 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\tcurrent_opcode);\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"enable single-step\");\n\t\t\tarm7_9->enable_single_step(target, next_pc);\n\n\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\t\t\tretval = arm7_9_restore_context(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (arm->core_state == ARM_STATE_ARM)\n\t\t\t\tarm7_9->branch_resume(target);\n\t\t\telse if (arm->core_state == ARM_STATE_THUMB)\n\t\t\t\tarm7_9->branch_resume_thumb(target);\n\t\t\telse {\n\t\t\t\tLOG_ERROR(\"unhandled core state\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);\n\t\t\tembeddedice_write_reg(dbg_ctrl,\n\t\t\t\tbuf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));\n\t\t\terr = arm7_9_execute_sys_speed(target);\n\n\t\t\tLOG_DEBUG(\"disable single-step\");\n\t\t\tarm7_9->disable_single_step(target);\n\n\t\t\tif (err != ERROR_OK) {\n\t\t\t\tretval = arm7_9_set_breakpoint(target, breakpoint);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\ttarget->state = TARGET_UNKNOWN;\n\t\t\t\treturn err;\n\t\t\t}\n\n\t\t\tretval = arm7_9_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tLOG_DEBUG(\"new PC after step: 0x%8.8\" PRIx32,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\n\t\t\tLOG_DEBUG(\"set breakpoint at 0x%8.8\" TARGET_PRIxADDR \"\", breakpoint->address);\n\t\t\tretval = arm7_9_set_breakpoint(target, breakpoint);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* enable any pending breakpoints and watchpoints */\n\tarm7_9_enable_breakpoints(target);\n\tarm7_9_enable_watchpoints(target);\n\n\tretval = arm7_9_restore_context(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (arm->core_state == ARM_STATE_ARM)\n\t\tarm7_9->branch_resume(target);\n\telse if (arm->core_state == ARM_STATE_THUMB)\n\t\tarm7_9->branch_resume_thumb(target);\n\telse {\n\t\tLOG_ERROR(\"unhandled core state\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* deassert DBGACK and INTDIS */\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);\n\t/* INTDIS only when we really resume, not during debug execution */\n\tif (!debug_execution)\n\t\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_INTDIS, 1, 0);\n\tembeddedice_write_reg(dbg_ctrl, buf_get_u32(dbg_ctrl->value, 0, dbg_ctrl->size));\n\n\tretval = arm7_9_restart_core(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\tif (!debug_execution) {\n\t\t/* registers are now invalid */\n\t\tregister_cache_invalidate(arm->core_cache);\n\t\ttarget->state = TARGET_RUNNING;\n\t\tretval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\tretval = target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"target resumed\");\n\n\treturn ERROR_OK;\n}\n\nvoid arm7_9_enable_eice_step(struct target *target, uint32_t next_pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tuint32_t current_pc;\n\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\tif (next_pc != current_pc) {\n\t\t/* setup an inverse breakpoint on the current PC\n\t\t* - comparator 1 matches the current address\n\t\t* - rangeout from comparator 1 is connected to comparator 0 rangein\n\t\t* - comparator 0 matches any address, as long as rangein is low */\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE],\n\t\t\tEICE_W_CTRL_ENABLE);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK],\n\t\t\t~(EICE_W_CTRL_RANGE | EICE_W_CTRL_NOPC) & 0xff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE],\n\t\t\tcurrent_pc);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE], 0x0);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK],\n\t\t\t~EICE_W_CTRL_NOPC & 0xff);\n\t} else {\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x0);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE], next_pc);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK], 0);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK], 0xffffffff);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE],\n\t\t\tEICE_W_CTRL_ENABLE);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK],\n\t\t\t~EICE_W_CTRL_NOPC & 0xff);\n\t}\n}\n\nvoid arm7_9_disable_eice_step(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_VALUE]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_ADDR_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_DATA_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W1_CONTROL_VALUE]);\n}\n\nint arm7_9_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct breakpoint *breakpoint = NULL;\n\tint err, retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current)\n\t\tbuf_set_u32(arm->pc->value, 0, 32, address);\n\n\tuint32_t current_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints)\n\t\tbreakpoint = breakpoint_find(target, current_pc);\n\tif (breakpoint) {\n\t\tretval = arm7_9_unset_breakpoint(target, breakpoint);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\t/* calculate PC of next instruction */\n\tuint32_t next_pc;\n\tretval = arm_simulate_step(target, &next_pc);\n\tif (retval != ERROR_OK) {\n\t\tuint32_t current_opcode;\n\t\ttarget_read_u32(target, current_pc, &current_opcode);\n\t\tLOG_ERROR(\n\t\t\t\"Couldn't calculate PC of next instruction, current opcode was 0x%8.8\" PRIx32 \"\",\n\t\t\tcurrent_opcode);\n\t\treturn retval;\n\t}\n\n\tretval = arm7_9_restore_context(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm7_9->enable_single_step(target, next_pc);\n\n\tif (arm->core_state == ARM_STATE_ARM)\n\t\tarm7_9->branch_resume(target);\n\telse if (arm->core_state == ARM_STATE_THUMB)\n\t\tarm7_9->branch_resume_thumb(target);\n\telse {\n\t\tLOG_ERROR(\"unhandled core state\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\terr = arm7_9_execute_sys_speed(target);\n\tarm7_9->disable_single_step(target);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arm->core_cache);\n\n\tif (err != ERROR_OK)\n\t\ttarget->state = TARGET_UNKNOWN;\n\telse {\n\t\tretval = arm7_9_debug_entry(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"target stepped\");\n\t}\n\n\tif (breakpoint) {\n\t\tretval = arm7_9_set_breakpoint(target, breakpoint);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn err;\n}\n\nstatic int arm7_9_read_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode)\n{\n\tuint32_t *reg_p[16];\n\tint retval;\n\tstruct arm_reg *areg = r->arch_info;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\n\tif (!is_arm_mode(arm->core_mode))\n\t\treturn ERROR_FAIL;\n\tif ((num < 0) || (num > 16))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif ((mode != ARM_MODE_ANY) && (mode != arm->core_mode)\n\t\t\t&& (areg->mode != ARM_MODE_ANY)) {\n\t\tuint32_t tmp_cpsr;\n\n\t\t/* change processor mode (mask T bit) */\n\t\ttmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0;\n\t\ttmp_cpsr |= mode;\n\t\ttmp_cpsr &= ~0x20;\n\t\tarm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);\n\t}\n\n\tuint32_t value = 0;\n\tif ((num >= 0) && (num <= 15)) {\n\t\t/* read a normal core register */\n\t\treg_p[num] = &value;\n\n\t\tarm7_9->read_core_regs(target, 1 << num, reg_p);\n\t} else {\n\t\t/* read a program status register\n\t\t * if the register mode is MODE_ANY, we read the cpsr, otherwise a spsr\n\t\t */\n\t\tarm7_9->read_xpsr(target, &value, areg->mode != ARM_MODE_ANY);\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tr->valid = true;\n\tr->dirty = false;\n\tbuf_set_u32(r->value, 0, 32, value);\n\n\tif ((mode != ARM_MODE_ANY) && (mode != arm->core_mode)\n\t\t\t&& (areg->mode != ARM_MODE_ANY)) {\n\t\t/* restore processor mode (mask T bit) */\n\t\tarm7_9->write_xpsr_im8(target,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm7_9_write_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode, uint8_t *value)\n{\n\tuint32_t reg[16];\n\tstruct arm_reg *areg = r->arch_info;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\n\tif (!is_arm_mode(arm->core_mode))\n\t\treturn ERROR_FAIL;\n\tif ((num < 0) || (num > 16))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif ((mode != ARM_MODE_ANY) && (mode != arm->core_mode)\n\t\t\t&& (areg->mode != ARM_MODE_ANY)) {\n\t\tuint32_t tmp_cpsr;\n\n\t\t/* change processor mode (mask T bit) */\n\t\ttmp_cpsr = buf_get_u32(arm->cpsr->value, 0, 8) & 0xE0;\n\t\ttmp_cpsr |= mode;\n\t\ttmp_cpsr &= ~0x20;\n\t\tarm7_9->write_xpsr_im8(target, tmp_cpsr & 0xff, 0, 0);\n\t}\n\n\tif ((num >= 0) && (num <= 15)) {\n\t\t/* write a normal core register */\n\t\treg[num] = buf_get_u32(value, 0, 32);\n\n\t\tarm7_9->write_core_regs(target, 1 << num, reg);\n\t} else {\n\t\t/* write a program status register\n\t\t* if the register mode is MODE_ANY, we write the cpsr, otherwise a spsr\n\t\t*/\n\t\tint spsr = (areg->mode != ARM_MODE_ANY);\n\n\t\tuint32_t t = buf_get_u32(value, 0, 32);\n\t\t/* if we're writing the CPSR, mask the T bit */\n\t\tif (!spsr)\n\t\t\tt &= ~0x20;\n\n\t\tarm7_9->write_xpsr(target, t, spsr);\n\t}\n\n\tr->valid = true;\n\tr->dirty = false;\n\n\tif ((mode != ARM_MODE_ANY) && (mode != arm->core_mode)\n\t\t\t&& (areg->mode != ARM_MODE_ANY)) {\n\t\t/* restore processor mode (mask T bit) */\n\t\tarm7_9->write_xpsr_im8(target,\n\t\t\t\tbuf_get_u32(arm->cpsr->value, 0, 8) & ~0x20, 0, 0);\n\t}\n\n\treturn jtag_execute_queue();\n}\n\nint arm7_9_read_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tuint8_t *buffer)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tuint32_t reg[16];\n\tuint32_t num_accesses = 0;\n\tint thisrun_accesses;\n\tint i;\n\tuint32_t cpsr;\n\tint retval;\n\tint last_reg = 0;\n\n\tLOG_DEBUG(\"address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* load the base register with the address of the first word */\n\treg[0] = address;\n\tarm7_9->write_core_regs(target, 0x1, reg);\n\n\tint j = 0;\n\n\tswitch (size) {\n\t\tcase 4:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tif (last_reg <= thisrun_accesses)\n\t\t\t\t\tlast_reg = thisrun_accesses;\n\n\t\t\t\tarm7_9->load_word_regs(target, reg_list);\n\n\t\t\t\t/* fast memory reads are only safe when the target is running\n\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t */\n\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\telse\n\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tarm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 4);\n\n\t\t\t\t/* advance buffer, count number of accesses */\n\t\t\t\tbuffer += thisrun_accesses * 4;\n\t\t\t\tnum_accesses += thisrun_accesses;\n\n\t\t\t\tif ((j++%1024) == 0)\n\t\t\t\t\tkeep_alive();\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tif (i > last_reg)\n\t\t\t\t\t    last_reg = i;\n\t\t\t\t\tarm7_9->load_hword_reg(target, i);\n\t\t\t\t\t/* fast memory reads are only safe when the target is running\n\t\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t\t */\n\t\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\t\telse\n\t\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\n\t\t\t\t}\n\n\t\t\t\tarm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 2);\n\n\t\t\t\t/* advance buffer, count number of accesses */\n\t\t\t\tbuffer += thisrun_accesses * 2;\n\t\t\t\tnum_accesses += thisrun_accesses;\n\n\t\t\t\tif ((j++%1024) == 0)\n\t\t\t\t\tkeep_alive();\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tif (i > last_reg)\n\t\t\t\t\t\tlast_reg = i;\n\t\t\t\t\tarm7_9->load_byte_reg(target, i);\n\t\t\t\t\t/* fast memory reads are only safe when the target is running\n\t\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t\t */\n\t\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\t\telse\n\t\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\n\t\t\t\tarm7_9->read_core_regs_target_buffer(target, reg_list, buffer, 1);\n\n\t\t\t\t/* advance buffer, count number of accesses */\n\t\t\t\tbuffer += thisrun_accesses * 1;\n\t\t\t\tnum_accesses += thisrun_accesses;\n\n\t\t\t\tif ((j++%1024) == 0)\n\t\t\t\t\tkeep_alive();\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\tif (!is_arm_mode(arm->core_mode))\n\t\treturn ERROR_FAIL;\n\n\tfor (i = 0; i <= last_reg; i++) {\n\t\tstruct reg *r = arm_reg_current(arm, i);\n\t\tr->dirty = r->valid;\n\t}\n\n\tarm7_9->read_xpsr(target, &cpsr, 0);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while reading cpsr\");\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\tif (((cpsr & 0x1f) == ARM_MODE_ABT) && (arm->core_mode != ARM_MODE_ABT)) {\n\t\tLOG_WARNING(\n\t\t\t\"memory read caused data abort \"\n\t\t\t\"(address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%\" PRIx32 \", count: 0x%\" PRIx32 \")\",\n\t\t\taddress,\n\t\t\tsize,\n\t\t\tcount);\n\n\t\tarm7_9->write_xpsr_im8(target,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 8)\n\t\t\t& ~0x20, 0, 0);\n\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint arm7_9_write_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n\tuint32_t reg[16];\n\tuint32_t num_accesses = 0;\n\tint thisrun_accesses;\n\tint i;\n\tuint32_t cpsr;\n\tint retval;\n\tint last_reg = 0;\n\n#ifdef _DEBUG_ARM7_9_\n\tLOG_DEBUG(\"address: 0x%8.8x, size: 0x%8.8x, count: 0x%8.8x\", address, size, count);\n#endif\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* load the base register with the address of the first word */\n\treg[0] = address;\n\tarm7_9->write_core_regs(target, 0x1, reg);\n\n\t/* Clear DBGACK, to make sure memory fetches work as expected */\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 0);\n\tembeddedice_store_reg(dbg_ctrl);\n\n\tswitch (size) {\n\t\tcase 4:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tif (i > last_reg)\n\t\t\t\t\t\tlast_reg = i;\n\t\t\t\t\treg[i] = target_buffer_get_u32(target, buffer);\n\t\t\t\t\tbuffer += 4;\n\t\t\t\t}\n\n\t\t\t\tarm7_9->write_core_regs(target, reg_list, reg);\n\n\t\t\t\tarm7_9->store_word_regs(target, reg_list);\n\n\t\t\t\t/* fast memory writes are only safe when the target is running\n\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t */\n\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\telse {\n\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\n\t\t\t\t\t/*\n\t\t\t\t\t * if memory writes are made when the clock is running slow\n\t\t\t\t\t * (i.e. 32 kHz) which is necessary in some scripts to reconfigure\n\t\t\t\t\t * processor operations after a \"reset halt\" or \"reset init\",\n\t\t\t\t\t * need to immediately stroke the keep alive or will end up with\n\t\t\t\t\t * gdb \"keep alive not sent error message\" problem.\n\t\t\t\t\t */\n\n\t\t\t\t\tkeep_alive();\n\t\t\t\t}\n\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tnum_accesses += thisrun_accesses;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tif (i > last_reg)\n\t\t\t\t\t\tlast_reg = i;\n\t\t\t\t\treg[i] = target_buffer_get_u16(target, buffer) & 0xffff;\n\t\t\t\t\tbuffer += 2;\n\t\t\t\t}\n\n\t\t\t\tarm7_9->write_core_regs(target, reg_list, reg);\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tarm7_9->store_hword_reg(target, i);\n\n\t\t\t\t\t/* fast memory writes are only safe when the target is running\n\t\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t\t */\n\t\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\t\telse {\n\t\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * if memory writes are made when the clock is running slow\n\t\t\t\t\t\t * (i.e. 32 kHz) which is necessary in some scripts to reconfigure\n\t\t\t\t\t\t * processor operations after a \"reset halt\" or \"reset init\",\n\t\t\t\t\t\t * need to immediately stroke the keep alive or will end up with\n\t\t\t\t\t\t * gdb \"keep alive not sent error message\" problem.\n\t\t\t\t\t\t */\n\n\t\t\t\t\t\tkeep_alive();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\n\t\t\t\tnum_accesses += thisrun_accesses;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\twhile (num_accesses < count) {\n\t\t\t\tuint32_t reg_list;\n\t\t\t\tthisrun_accesses =\n\t\t\t\t\t\t((count - num_accesses) >= 14) ? 14 : (count - num_accesses);\n\t\t\t\treg_list = (0xffff >> (15 - thisrun_accesses)) & 0xfffe;\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tif (i > last_reg)\n\t\t\t\t\t\tlast_reg = i;\n\t\t\t\t\treg[i] = *buffer++ & 0xff;\n\t\t\t\t}\n\n\t\t\t\tarm7_9->write_core_regs(target, reg_list, reg);\n\n\t\t\t\tfor (i = 1; i <= thisrun_accesses; i++) {\n\t\t\t\t\tarm7_9->store_byte_reg(target, i);\n\t\t\t\t\t/* fast memory writes are only safe when the target is running\n\t\t\t\t\t * from a sufficiently high clock (32 kHz is usually too slow)\n\t\t\t\t\t */\n\t\t\t\t\tif (arm7_9->fast_memory_access)\n\t\t\t\t\t\tretval = arm7_9_execute_fast_sys_speed(target);\n\t\t\t\t\telse {\n\t\t\t\t\t\tretval = arm7_9_execute_sys_speed(target);\n\n\t\t\t\t\t\t/*\n\t\t\t\t\t\t * if memory writes are made when the clock is running slow\n\t\t\t\t\t\t * (i.e. 32 kHz) which is necessary in some scripts to reconfigure\n\t\t\t\t\t\t * processor operations after a \"reset halt\" or \"reset init\",\n\t\t\t\t\t\t * need to immediately stroke the keep alive or will end up with\n\t\t\t\t\t\t * gdb \"keep alive not sent error message\" problem.\n\t\t\t\t\t\t */\n\n\t\t\t\t\t\tkeep_alive();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\n\t\t\t\t}\n\n\t\t\t\tnum_accesses += thisrun_accesses;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\t/* Re-Set DBGACK */\n\tbuf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_DBGACK, 1, 1);\n\tembeddedice_store_reg(dbg_ctrl);\n\n\tif (!is_arm_mode(arm->core_mode))\n\t\treturn ERROR_FAIL;\n\n\tfor (i = 0; i <= last_reg; i++) {\n\t\tstruct reg *r = arm_reg_current(arm, i);\n\t\tr->dirty = r->valid;\n\t}\n\n\tarm7_9->read_xpsr(target, &cpsr, 0);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while reading cpsr\");\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\tif (((cpsr & 0x1f) == ARM_MODE_ABT) && (arm->core_mode != ARM_MODE_ABT)) {\n\t\tLOG_WARNING(\n\t\t\t\"memory write caused data abort \"\n\t\t\t\"(address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%\" PRIx32 \", count: 0x%\" PRIx32 \")\",\n\t\t\taddress,\n\t\t\tsize,\n\t\t\tcount);\n\n\t\tarm7_9->write_xpsr_im8(target,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 8)\n\t\t\t& ~0x20, 0, 0);\n\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint arm7_9_write_memory_opt(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tint retval;\n\n\tif (size == 4 && count > 32 && arm7_9->bulk_write_memory) {\n\t\t/* Attempt to do a bulk write */\n\t\tretval = arm7_9->bulk_write_memory(target, address, count, buffer);\n\n\t\tif (retval == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn arm7_9->write_memory(target, address, size, count, buffer);\n}\n\nint arm7_9_write_memory_no_opt(struct target *target,\n\tuint32_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\treturn arm7_9->write_memory(target, address, size, count, buffer);\n}\n\nstatic int dcc_count;\nstatic const uint8_t *dcc_buffer;\n\nstatic int arm7_9_dcc_completion(struct target *target,\n\tuint32_t exit_point,\n\tunsigned int timeout_ms,\n\tvoid *arch_info)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tretval = target_wait_state(target, TARGET_DEBUG_RUNNING, 500);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint little = target->endianness == TARGET_LITTLE_ENDIAN;\n\tint count = dcc_count;\n\tconst uint8_t *buffer = dcc_buffer;\n\tif (count > 2) {\n\t\t/* Handle first & last using standard embeddedice_write_reg and the middle ones w/the\n\t\t * core function repeated. */\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA],\n\t\t\tfast_target_buffer_get_u32(buffer, little));\n\t\tbuffer += 4;\n\n\t\tstruct embeddedice_reg *ice_reg =\n\t\t\tarm7_9->eice_cache->reg_list[EICE_COMMS_DATA].arch_info;\n\t\tuint8_t reg_addr = ice_reg->addr & 0x1f;\n\t\tstruct jtag_tap *tap;\n\t\ttap = ice_reg->jtag_info->tap;\n\n\t\tembeddedice_write_dcc(tap, reg_addr, buffer, little, count-2);\n\t\tbuffer += (count-2)*4;\n\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA],\n\t\t\tfast_target_buffer_get_u32(buffer, little));\n\t} else {\n\t\tint i;\n\t\tfor (i = 0; i < count; i++) {\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA],\n\t\t\t\tfast_target_buffer_get_u32(buffer, little));\n\t\t\tbuffer += 4;\n\t\t}\n\t}\n\n\tretval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn target_wait_state(target, TARGET_HALTED, 500);\n}\n\nstatic const uint32_t dcc_code[] = {\n\t/* r0 == input, points to memory buffer\n\t * r1 == scratch\n\t */\n\n\t/* spin until DCC control (c0) reports data arrived */\n\t0xee101e10,\t/* w: mrc p14, #0, r1, c0, c0 */\n\t0xe3110001,\t/*    tst r1, #1              */\n\t0x0afffffc,\t/*    bne w                   */\n\n\t/* read word from DCC (c1), write to memory */\n\t0xee111e10,\t/*    mrc p14, #0, r1, c1, c0 */\n\t0xe4801004,\t/*    str r1, [r0], #4        */\n\n\t/* repeat */\n\t0xeafffff9\t/*    b   w                   */\n};\n\nint arm7_9_bulk_write_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (address % 4 != 0)\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (!arm7_9->dcc_downloads)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* regrab previously allocated working_area, or allocate a new one */\n\tif (!arm7_9->dcc_working_area) {\n\t\tuint8_t dcc_code_buf[6 * 4];\n\n\t\t/* make sure we have a working area */\n\t\tif (target_alloc_working_area(target, 24, &arm7_9->dcc_working_area) != ERROR_OK) {\n\t\t\tLOG_INFO(\"no working area available, falling back to memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\t/* copy target instructions to target endianness */\n\t\ttarget_buffer_set_u32_array(target, dcc_code_buf, ARRAY_SIZE(dcc_code), dcc_code);\n\n\t\t/* write DCC code to working area, using the non-optimized\n\t\t * memory write to avoid ending up here again */\n\t\tretval = arm7_9_write_memory_no_opt(target,\n\t\t\t\tarm7_9->dcc_working_area->address, 4, 6, dcc_code_buf);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tstruct arm_algorithm arm_algo;\n\tstruct reg_param reg_params[1];\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\n\tdcc_count = count;\n\tdcc_buffer = buffer;\n\tretval = armv4_5_run_algorithm_inner(target, 0, NULL, 1, reg_params,\n\t\t\tarm7_9->dcc_working_area->address,\n\t\t\tarm7_9->dcc_working_area->address + 6*4,\n\t\t\t20*1000, &arm_algo, arm7_9_dcc_completion);\n\n\tif (retval == ERROR_OK) {\n\t\tuint32_t endaddress = buf_get_u32(reg_params[0].value, 0, 32);\n\t\tif (endaddress != (address + count*4)) {\n\t\t\tLOG_ERROR(\n\t\t\t\t\"DCC write failed, expected end address 0x%08\" TARGET_PRIxADDR \" got 0x%0\" PRIx32 \"\",\n\t\t\t\t(address + count*4),\n\t\t\t\tendaddress);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\tdestroy_reg_param(&reg_params[0]);\n\n\treturn retval;\n}\n\n/**\n * Perform per-target setup that requires JTAG access.\n */\nint arm7_9_examine(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tint retval;\n\n\tif (!target_was_examined(target)) {\n\t\tstruct reg_cache *t, **cache_p;\n\n\t\tt = embeddedice_build_reg_cache(target, arm7_9);\n\t\tif (!t)\n\t\t\treturn ERROR_FAIL;\n\n\t\tcache_p = register_get_last_cache_p(&target->reg_cache);\n\t\t(*cache_p) = t;\n\t\tarm7_9->eice_cache = (*cache_p);\n\n\t\tif (arm7_9->arm.etm)\n\t\t\t(*cache_p)->next = etm_build_reg_cache(target,\n\t\t\t\t\t&arm7_9->jtag_info,\n\t\t\t\t\tarm7_9->arm.etm);\n\n\t\ttarget_set_examined(target);\n\t}\n\n\tretval = embeddedice_setup(target);\n\tif (retval == ERROR_OK)\n\t\tretval = arm7_9_setup(target);\n\tif (retval == ERROR_OK && arm7_9->arm.etm)\n\t\tretval = etm_setup(target);\n\treturn retval;\n}\n\nvoid arm7_9_deinit(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (target_was_examined(target))\n\t\tembeddedice_free_reg_cache(arm7_9->eice_cache);\n\n\tarm_jtag_close_connection(&arm7_9->jtag_info);\n}\n\nint arm7_9_check_reset(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (get_target_reset_nag() && !arm7_9->dcc_downloads)\n\t\tLOG_WARNING(\n\t\t\t\"NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.\");\n\n\tif (get_target_reset_nag() && (target->working_area_size == 0))\n\t\tLOG_WARNING(\"NOTE! Severe performance degradation without working memory enabled.\");\n\n\tif (get_target_reset_nag() && !arm7_9->fast_memory_access)\n\t\tLOG_WARNING(\n\t\t\t\"NOTE! Severe performance degradation without fast memory access enabled. Type 'help fast'.\");\n\n\treturn ERROR_OK;\n}\n\nint arm7_9_endianness_callback(jtag_callback_data_t pu8_in,\n\t\tjtag_callback_data_t i_size, jtag_callback_data_t i_be,\n\t\tjtag_callback_data_t i_flip)\n{\n\tuint8_t *in = (uint8_t *)pu8_in;\n\tint size = (int)i_size;\n\tint be = (int)i_be;\n\tint flip = (int)i_flip;\n\tuint32_t readback;\n\n\tswitch (size) {\n\tcase 4:\n\t\treadback = le_to_h_u32(in);\n\t\tif (flip)\n\t\t\treadback = flip_u32(readback, 32);\n\t\tif (be)\n\t\t\th_u32_to_be(in, readback);\n\t\telse\n\t\t\th_u32_to_le(in, readback);\n\t\tbreak;\n\tcase 2:\n\t\treadback = le_to_h_u16(in);\n\t\tif (flip)\n\t\t\treadback = flip_u32(readback, 16);\n\t\tif (be)\n\t\t\th_u16_to_be(in, readback & 0xffff);\n\t\telse\n\t\t\th_u16_to_le(in, readback & 0xffff);\n\t\tbreak;\n\tcase 1:\n\t\treadback = *in;\n\t\tif (flip)\n\t\t\treadback = flip_u32(readback, 8);\n\t\t*in = readback & 0xff;\n\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_arm7_9_dbgrq_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (!is_arm7_9(arm7_9)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM7/ARM9 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->use_dbgrq);\n\n\tcommand_print(CMD,\n\t\t\"use of EmbeddedICE dbgrq instead of breakpoint for target halt %s\",\n\t\t(arm7_9->use_dbgrq) ? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_arm7_9_fast_memory_access_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (!is_arm7_9(arm7_9)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM7/ARM9 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->fast_memory_access);\n\n\tcommand_print(CMD,\n\t\t\"fast memory access is %s\",\n\t\t(arm7_9->fast_memory_access) ? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_arm7_9_dcc_downloads_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (!is_arm7_9(arm7_9)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM7/ARM9 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], arm7_9->dcc_downloads);\n\n\tcommand_print(CMD,\n\t\t\"dcc downloads are %s\",\n\t\t(arm7_9->dcc_downloads) ? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nstatic int arm7_9_setup_semihosting(struct target *target, int enable)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (!is_arm7_9(arm7_9)) {\n\t\tLOG_USER(\"current target isn't an ARM7/ARM9 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (arm7_9->has_vector_catch) {\n\t\tstruct reg *vector_catch = &arm7_9->eice_cache\n\t\t\t->reg_list[EICE_VEC_CATCH];\n\n\t\tif (!vector_catch->valid)\n\t\t\tembeddedice_read_reg(vector_catch);\n\t\tbuf_set_u32(vector_catch->value, 2, 1, enable);\n\t\tembeddedice_store_reg(vector_catch);\n\t} else {\n\t\t/* TODO: allow optional high vectors and/or BKPT_HARD */\n\t\tif (enable)\n\t\t\tbreakpoint_add(target, 8, 4, BKPT_SOFT);\n\t\telse\n\t\t\tbreakpoint_remove(target, 8);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9)\n{\n\tint retval = ERROR_OK;\n\tstruct arm *arm = &arm7_9->arm;\n\n\tarm7_9->common_magic = ARM7_9_COMMON_MAGIC;\n\n\tretval = arm_jtag_setup_connection(&arm7_9->jtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* caller must have allocated via calloc(), so everything's zeroed */\n\n\tarm7_9->wp_available_max = 2;\n\n\tarm7_9->fast_memory_access = false;\n\tarm7_9->dcc_downloads = false;\n\n\tarm->arch_info = arm7_9;\n\tarm->core_type = ARM_CORE_TYPE_STD;\n\tarm->read_core_reg = arm7_9_read_core_reg;\n\tarm->write_core_reg = arm7_9_write_core_reg;\n\tarm->full_context = arm7_9_full_context;\n\tarm->setup_semihosting = arm7_9_setup_semihosting;\n\n\tretval = arm_init_arch_info(target, arm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_register_timer_callback(arm7_9_handle_target_request,\n\t\t1, TARGET_TIMER_TYPE_PERIODIC, target);\n}\n\nstatic const struct command_registration arm7_9_any_command_handlers[] = {\n\t{\n\t\t.name = \"dbgrq\",\n\t\t.handler = handle_arm7_9_dbgrq_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"use EmbeddedICE dbgrq instead of breakpoint \"\n\t\t\t\"for target halt requests\",\n\t},\n\t{\n\t\t.name = \"fast_memory_access\",\n\t\t.handler = handle_arm7_9_fast_memory_access_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"use fast memory accesses instead of slower \"\n\t\t\t\"but potentially safer accesses\",\n\t},\n\t{\n\t\t.name = \"dcc_downloads\",\n\t\t.handler = handle_arm7_9_dcc_downloads_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"use DCC downloads for larger memory writes\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nconst struct command_registration arm7_9_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.chain = etm_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm7_9\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm7/9 specific commands\",\n\t\t.usage = \"\",\n\t\t.chain = arm7_9_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm7_9_common.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by Hongtao Zheng                                   *\n *   hontor@126.com                                                        *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM7_9_COMMON_H\n#define OPENOCD_TARGET_ARM7_9_COMMON_H\n\n#include \"arm.h\"\n#include \"arm_jtag.h\"\n\n#define\tARM7_9_COMMON_MAGIC 0x0a790a79U /**< */\n\n/**\n * Structure for items that are common between both ARM7 and ARM9 targets.\n */\nstruct arm7_9_common {\n\tunsigned int common_magic;\n\n\tstruct arm arm;\n\n\tstruct arm_jtag jtag_info; /**< JTAG information for target */\n\tstruct reg_cache *eice_cache; /**< Embedded ICE register cache */\n\n\tuint32_t arm_bkpt; /**< ARM breakpoint instruction */\n\tuint16_t thumb_bkpt; /**< Thumb breakpoint instruction */\n\n\tint sw_breakpoints_added; /**< Specifies which watchpoint software breakpoints are setup on */\n\tint sw_breakpoint_count; /**< keep track of number of software breakpoints we have set */\n\tint breakpoint_count; /**< Current number of set breakpoints */\n\tint wp_available; /**< Current number of available watchpoint units */\n\tint wp_available_max; /**< Maximum number of available watchpoint units */\n\tint wp0_used; /**< Specifies if and how watchpoint unit 0 is used */\n\tint wp1_used; /**< Specifies if and how watchpoint unit 1 is used */\n\tint wp1_used_default; /**< Specifies if and how watchpoint unit 1 is used by default */\n\tint dbgreq_adjust_pc; /**< Amount of PC adjustment caused by a DBGREQ */\n\tbool use_dbgrq; /**< Specifies if DBGRQ should be used to halt the target */\n\tbool need_bypass_before_restart; /**< Specifies if there should be a bypass before a JTAG restart */\n\n\tbool has_single_step;\n\tbool has_monitor_mode;\n\tbool has_vector_catch; /**< Specifies if the target has a reset vector catch */\n\n\tbool debug_entry_from_reset; /**< Specifies if debug entry was from a reset */\n\n\tbool fast_memory_access;\n\tbool dcc_downloads;\n\n\tstruct working_area *dcc_working_area;\n\n\tint (*examine_debug_reason)(struct target *target);\n\t/**< Function for determining why debug state was entered */\n\n\tvoid (*change_to_arm)(struct target *target, uint32_t *r0, uint32_t *pc);\n\t/**< Function for changing from Thumb to ARM mode */\n\n\tvoid (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]);\n\t/**< Function for reading the core registers */\n\n\tvoid (*read_core_regs_target_buffer)(struct target *target, uint32_t mask,\n\t\t\tvoid *buffer, int size);\n\tvoid (*read_xpsr)(struct target *target, uint32_t *xpsr, int spsr);\n\t/**< Function for reading CPSR or SPSR */\n\n\tvoid (*write_xpsr)(struct target *target, uint32_t xpsr, int spsr);\n\t/**< Function for writing to CPSR or SPSR */\n\n\tvoid (*write_xpsr_im8)(struct target *target, uint8_t xpsr_im, int rot, int spsr);\n\t/**< Function for writing an immediate value to CPSR or SPSR */\n\n\tvoid (*write_core_regs)(struct target *target, uint32_t mask, uint32_t core_regs[16]);\n\n\tvoid (*load_word_regs)(struct target *target, uint32_t mask);\n\tvoid (*load_hword_reg)(struct target *target, int num);\n\tvoid (*load_byte_reg)(struct target *target, int num);\n\n\tvoid (*store_word_regs)(struct target *target, uint32_t mask);\n\tvoid (*store_hword_reg)(struct target *target, int num);\n\tvoid (*store_byte_reg)(struct target *target, int num);\n\n\tvoid (*write_pc)(struct target *target, uint32_t pc);\n\t/**< Function for writing to the program counter */\n\n\tvoid (*branch_resume)(struct target *target);\n\tvoid (*branch_resume_thumb)(struct target *target);\n\n\tvoid (*enable_single_step)(struct target *target, uint32_t next_pc);\n\tvoid (*disable_single_step)(struct target *target);\n\n\tvoid (*set_special_dbgrq)(struct target *target);\n\t/**< Function for setting DBGRQ if the normal way won't work */\n\n\tint (*post_debug_entry)(struct target *target);\n\t/**< Callback function called after entering debug mode */\n\n\tvoid (*pre_restore_context)(struct target *target);\n\t/**< Callback function called before restoring the processor context */\n\n\t/**\n\t * Variant specific memory write function that does not dispatch to bulk_write_memory.\n\t * Used as a fallback when bulk writes are unavailable, or for writing data needed to\n\t * do the bulk writes.\n\t */\n\tint (*write_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\n\t/**\n\t * Write target memory in multiples of 4 bytes, optimized for\n\t * writing large quantities of data.\n\t */\n\tint (*bulk_write_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t count, const uint8_t *buffer);\n};\n\nstatic inline struct arm7_9_common *target_to_arm7_9(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm7_9_common, arm);\n}\n\nstatic inline bool is_arm7_9(struct arm7_9_common *arm7_9)\n{\n\treturn arm7_9->common_magic == ARM7_9_COMMON_MAGIC;\n}\n\nextern const struct command_registration arm7_9_command_handlers[];\n\nint arm7_9_poll(struct target *target);\n\nint arm7_9_target_request_data(struct target *target, uint32_t size, uint8_t *buffer);\n\nint arm7_9_assert_reset(struct target *target);\nint arm7_9_deassert_reset(struct target *target);\nint arm7_9_reset_request_halt(struct target *target);\nint arm7_9_early_halt(struct target *target);\nint arm7_9_soft_reset_halt(struct target *target);\n\nint arm7_9_halt(struct target *target);\nint arm7_9_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution);\nint arm7_9_step(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints);\nint arm7_9_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer);\nint arm7_9_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\nint arm7_9_write_memory_opt(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\nint arm7_9_write_memory_no_opt(struct target *target, uint32_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\nint arm7_9_bulk_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, const uint8_t *buffer);\n\nint arm7_9_run_algorithm(struct target *target, int num_mem_params,\n\t\tstruct mem_param *mem_params, int num_reg_prams,\n\t\tstruct reg_param *reg_param, uint32_t entry_point, void *arch_info);\n\nint arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint arm7_9_add_watchpoint(struct target *target, struct watchpoint *watchpoint);\nint arm7_9_remove_watchpoint(struct target *target, struct watchpoint *watchpoint);\n\nvoid arm7_9_enable_eice_step(struct target *target, uint32_t next_pc);\nvoid arm7_9_disable_eice_step(struct target *target);\n\nint arm7_9_execute_sys_speed(struct target *target);\n\nint arm7_9_init_arch_info(struct target *target, struct arm7_9_common *arm7_9);\nint arm7_9_examine(struct target *target);\nvoid arm7_9_deinit(struct target *target);\nint arm7_9_check_reset(struct target *target);\n\nint arm7_9_endianness_callback(jtag_callback_data_t pu8_in,\n\t\tjtag_callback_data_t i_size, jtag_callback_data_t i_be,\n\t\tjtag_callback_data_t i_flip);\n\n#endif /* OPENOCD_TARGET_ARM7_9_COMMON_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm7tdmi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm7tdmi.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n#include \"arm_semihosting.h\"\n\n/*\n * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)\n * or ARM DDI 0029G (r3).  \"Debug In Depth\", Appendix B,\n * covers JTAG support.\n */\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\nstatic int arm7tdmi_examine_debug_reason(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\t/* only check the debug reason if we don't know it already */\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\t\tstruct scan_field fields[2];\n\t\tuint8_t databus[4];\n\t\tuint8_t breakpoint;\n\n\t\tfields[0].num_bits = 1;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = &breakpoint;\n\n\t\tfields[1].num_bits = 32;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = databus;\n\n\t\tretval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tjtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfields[0].in_value = NULL;\n\t\tfields[0].out_value = &breakpoint;\n\t\tfields[1].in_value = NULL;\n\t\tfields[1].out_value = databus;\n\n\t\tjtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);\n\n\t\tif (breakpoint & 1)\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\telse\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const int arm7tdmi_num_bits[] = {1, 32};\n\nstatic inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)\n{\n\tuint8_t bp = breakpoint ? 1 : 0;\n\tuint8_t out_value[4];\n\tbuf_set_u32(out_value, 0, 32, flip_u32(out, 32));\n\n\tstruct scan_field fields[2] = {\n\t\t\t{ .num_bits = arm7tdmi_num_bits[0], .out_value = &bp },\n\t\t\t{ .num_bits = arm7tdmi_num_bits[1], .out_value = out_value },\n\t};\n\n\tjtag_add_dr_scan(jtag_info->tap,\n\t\t\t2,\n\t\t\tfields,\n\t\t\tTAP_DRPAUSE);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n\treturn ERROR_OK;\n}\n\n/* put an instruction in the ARM7TDMI pipeline or write the data bus,\n * and optionally read data\n */\nstatic inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info,\n\t\tuint32_t out, int breakpoint)\n{\n\tint retval;\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);\n}\n\n/* clock the target, reading the databus */\nstatic int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)\n{\n\tint retval = ERROR_OK;\n\tstruct scan_field fields[2];\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = NULL;\n\tfields[1].in_value = (uint8_t *)in;\n\n\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);\n\n\tjtag_add_callback(arm7flip32, (jtag_callback_data_t)in);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (in)\n\t\tLOG_DEBUG(\"in: 0x%8.8x\", *in);\n\telse\n\t\tLOG_ERROR(\"BUG: called with in == NULL\");\n#endif\n\n\treturn ERROR_OK;\n}\n\n/* clock the target, and read the databus\n * the *in pointer points to a buffer where elements of 'size' bytes\n * are stored in big (be == 1) or little (be == 0) endianness\n */\nstatic int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,\n\t\tvoid *in, int size, int be)\n{\n\tint retval = ERROR_OK;\n\tstruct scan_field fields[3];\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tif (size == 4) {\n\t\tfields[1].num_bits = 32;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = in;\n\t} else {\n\t\t/* Discard irrelevant bits of the scan, making sure we don't write more\n\t\t * than size bytes to in */\n\t\tfields[1].num_bits = 32 - size * 8;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = NULL;\n\n\t\tfields[2].num_bits = size * 8;\n\t\tfields[2].out_value = NULL;\n\t\tfields[2].in_value = in;\n\t}\n\n\tjtag_add_dr_scan(jtag_info->tap, size == 4 ? 2 : 3, fields, TAP_DRPAUSE);\n\n\tjtag_add_callback4(arm7_9_endianness_callback,\n\t\t(jtag_callback_data_t)in,\n\t\t(jtag_callback_data_t)size,\n\t\t(jtag_callback_data_t)be,\n\t\t(jtag_callback_data_t)1);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n{\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (in)\n\t\t\tLOG_DEBUG(\"in: 0x%8.8x\", *(uint32_t *)in);\n\t\telse\n\t\t\tLOG_ERROR(\"BUG: called with in == NULL\");\n}\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic void arm7tdmi_change_to_arm(struct target *target,\n\t\tuint32_t *r0, uint32_t *pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* save r0 before using it and put system in ARM state\n\t * to allow common handling of ARM and THUMB debugging */\n\n\t/* fetch STR r0, [r0] */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* nothing fetched, STR r0, [r0] in Execute (2) */\n\tarm7tdmi_clock_data_in(jtag_info, r0);\n\n\t/* MOV r0, r15 fetched, STR in Decode */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* nothing fetched, STR r0, [r0] in Execute (2) */\n\tarm7tdmi_clock_data_in(jtag_info, pc);\n\n\t/* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* nothing fetched, data for LDR r0, [PC, #0] */\n\tarm7tdmi_clock_out(jtag_info, 0x0, 0);\n\t/* nothing fetched, data from previous cycle is written to register */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\n\t/* fetch BX */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0);\n\t/* NOP fetched, BX in Decode, MOV in Execute */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* NOP fetched, BX in Execute (1) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\n\tjtag_execute_queue();\n\n\t/* fix program counter:\n\t * MOV r0, r15 was the 4th instruction (+6)\n\t * reading PC in Thumb state gives address of instruction + 4\n\t */\n\t*pc -= 0xa;\n}\n\n/* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many\n * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?\n *\n * The solution is to arrange for a large out/in scan in this loop and\n * and convert data afterwards.\n */\nstatic void arm7tdmi_read_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t *core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, STM still in EXECUTE (1 + i cycle) */\n\t\t\tarm7tdmi_clock_data_in(jtag_info, core_regs[i]);\n\t}\n}\n\nstatic void arm7tdmi_read_core_regs_target_buffer(struct target *target,\n\t\tuint32_t mask, void *buffer, int size)\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;\n\tuint32_t *buf_u32 = buffer;\n\tuint16_t *buf_u16 = buffer;\n\tuint8_t *buf_u8 = buffer;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\t/* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */\n\t\tif (mask & (1 << i)) {\n\t\t\tswitch (size) {\n\t\t\t\tcase 4:\n\t\t\t\t\tarm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tarm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tarm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void arm7tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* MRS r0, cpsr */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0);\n\n\t/* STR r0, [r15] */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0);\n\t/* fetch NOP, STR in DECODE stage */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, STR in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, STR still in EXECUTE (2nd cycle) */\n\tarm7tdmi_clock_data_in(jtag_info, xpsr);\n}\n\nstatic void arm7tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr: %8.8\" PRIx32 \", spsr: %i\", xpsr, spsr);\n\n\t/* MSR1 fetched */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0);\n\t/* MSR2 fetched, MSR1 in DECODE */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0);\n\t/* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0);\n\t/* nothing fetched, MSR1 in EXECUTE (2) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0);\n\t/* nothing fetched, MSR2 in EXECUTE (2) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, MSR3 in EXECUTE (2) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* NOP fetched, MSR4 in EXECUTE (1) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, MSR4 in EXECUTE (2) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n}\n\nstatic void arm7tdmi_write_xpsr_im8(struct target *target,\n\t\tuint8_t xpsr_im, int rot, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr_im: %2.2x, rot: %i, spsr: %i\", xpsr_im, rot, spsr);\n\n\t/* MSR fetched */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0);\n\t/* NOP fetched, MSR in DECODE */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* NOP fetched, MSR in EXECUTE (1) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, MSR in EXECUTE (2) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n}\n\nstatic void arm7tdmi_write_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t* register values will start to appear on 4th DCLK\n\t*/\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */\n\t\t\tarm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);\n\t}\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n}\n\nstatic void arm7tdmi_load_word_regs(struct target *target, uint32_t mask)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load-multiple into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0);\n}\n\nstatic void arm7tdmi_load_hword_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load half-word into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0);\n}\n\nstatic void arm7tdmi_load_byte_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load byte into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0);\n}\n\nstatic void arm7tdmi_store_word_regs(struct target *target, uint32_t mask)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store-multiple into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0);\n}\n\nstatic void arm7tdmi_store_hword_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store half-word into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0);\n}\n\nstatic void arm7tdmi_store_byte_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store byte into the pipeline */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0);\n}\n\nstatic void arm7tdmi_write_pc(struct target *target, uint32_t pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0);\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */\n\tarm7tdmi_clock_out_inner(jtag_info, pc, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (4th cycle) */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (5th cycle) */\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);\n}\n\nstatic void arm7tdmi_branch_resume(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 1);\n\tarm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);\n}\n\nstatic void arm7tdmi_branch_resume_thumb(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\tLOG_DEBUG(\"-\");\n\n\t/* LDMIA r0, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */\n\tarm7tdmi_clock_out(jtag_info, buf_get_u32(arm->pc->value, 0, 32) | 1, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\n\t/* Branch and eXchange */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0);\n\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* fetch NOP, BX in DECODE stage */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\n\t/* target is now in Thumb state */\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* fetch NOP, BX in EXECUTE stage (1st cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0);\n\n\t/* target is now in Thumb state */\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* load r0 value */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0);\n\t/* fetch NOP, LDR in Decode */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* fetch NOP, LDR in Execute */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\t/* nothing fetched, LDR in EXECUTE stage (2nd cycle) */\n\tarm7tdmi_clock_out(jtag_info, buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), 0);\n\t/* nothing fetched, LDR in EXECUTE stage (3rd cycle) */\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0);\n\n\tembeddedice_read_reg(dbg_stat);\n\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 1);\n\tarm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), 0);\n}\n\nstatic void arm7tdmi_build_reg_cache(struct target *target)\n{\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct arm *arm = target_to_arm(target);\n\n\t(*cache_p) = arm_build_reg_cache(target, arm);\n}\n\nstatic void arm7tdmi_free_reg_cache(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tarm_free_reg_cache(arm);\n}\n\nint arm7tdmi_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tarm7tdmi_build_reg_cache(target);\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nvoid arm7tdmi_deinit_target(struct target *target)\n{\n\tarm7tdmi_free_reg_cache(target);\n}\n\nint arm7tdmi_init_arch_info(struct target *target,\n\t\tstruct arm7_9_common *arm7_9, struct jtag_tap *tap)\n{\n\t/* prepare JTAG information for the new target */\n\tarm7_9->jtag_info.tap = tap;\n\tarm7_9->jtag_info.scann_size = 4;\n\n\t/* register arch-specific functions */\n\tarm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;\n\tarm7_9->change_to_arm = arm7tdmi_change_to_arm;\n\tarm7_9->read_core_regs = arm7tdmi_read_core_regs;\n\tarm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;\n\tarm7_9->read_xpsr = arm7tdmi_read_xpsr;\n\n\tarm7_9->write_xpsr = arm7tdmi_write_xpsr;\n\tarm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;\n\tarm7_9->write_core_regs = arm7tdmi_write_core_regs;\n\n\tarm7_9->load_word_regs = arm7tdmi_load_word_regs;\n\tarm7_9->load_hword_reg = arm7tdmi_load_hword_reg;\n\tarm7_9->load_byte_reg = arm7tdmi_load_byte_reg;\n\n\tarm7_9->store_word_regs = arm7tdmi_store_word_regs;\n\tarm7_9->store_hword_reg = arm7tdmi_store_hword_reg;\n\tarm7_9->store_byte_reg = arm7tdmi_store_byte_reg;\n\n\tarm7_9->write_pc = arm7tdmi_write_pc;\n\tarm7_9->branch_resume = arm7tdmi_branch_resume;\n\tarm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;\n\n\tarm7_9->enable_single_step = arm7_9_enable_eice_step;\n\tarm7_9->disable_single_step = arm7_9_disable_eice_step;\n\n\tarm7_9->write_memory = arm7_9_write_memory;\n\tarm7_9->bulk_write_memory = arm7_9_bulk_write_memory;\n\n\tarm7_9->post_debug_entry = NULL;\n\n\tarm7_9->pre_restore_context = NULL;\n\n\t/* initialize arch-specific breakpoint handling */\n\tarm7_9->arm_bkpt = 0xdeeedeee;\n\tarm7_9->thumb_bkpt = 0xdeee;\n\n\tarm7_9->dbgreq_adjust_pc = 2;\n\n\tarm7_9_init_arch_info(target, arm7_9);\n\n\treturn ERROR_OK;\n}\n\nstatic int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm7_9_common *arm7_9;\n\n\tarm7_9 = calloc(1, sizeof(struct arm7_9_common));\n\tarm7tdmi_init_arch_info(target, arm7_9, target->tap);\n\tarm7_9->arm.arch = ARM_ARCH_V4;\n\n\treturn ERROR_OK;\n}\n\n/** Holds methods for ARM7TDMI targets. */\nstruct target_type arm7tdmi_target = {\n\t.name = \"arm7tdmi\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm7_9_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands  = arm7_9_command_handlers,\n\t.target_create  = arm7tdmi_target_create,\n\t.init_target = arm7tdmi_init_target,\n\t.deinit_target = arm7tdmi_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm7tdmi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM7TDMI_H\n#define OPENOCD_TARGET_ARM7TDMI_H\n\n#include \"embeddedice.h\"\n\nint arm7tdmi_init_arch_info(struct target *target,\n\t\tstruct arm7_9_common *arm7_9, struct jtag_tap *tap);\nint arm7tdmi_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target);\nvoid arm7tdmi_deinit_target(struct target *target);\n\n#endif /* OPENOCD_TARGET_ARM7TDMI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm920t.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm920t.h\"\n#include <helper/time_support.h>\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n\n/*\n * For information about the ARM920T, see ARM DDI 0151C especially\n * Chapter 9 about debug support, which shows how to manipulate each\n * of the different scan chains:\n *\n *   0 ... ARM920 signals, e.g. to rest of SOC (unused here)\n *   1 ... debugging; watchpoint and breakpoint status, etc; also\n *\tMMU and cache access in conjunction with scan chain 15\n *   2 ... EmbeddedICE\n *   3 ... external boundary scan (SoC-specific, unused here)\n *   4 ... access to cache tag RAM\n *   6 ... ETM9\n *   15 ... access coprocessor 15, \"physical\" or \"interpreted\" modes\n *\t\"interpreted\" works with a few actual MRC/MCR instructions\n *\t\"physical\" provides register-like behaviors.  Section 9.6.7\n *\tcovers these details.\n *\n * The ARM922T is similar, but with smaller caches (8K each, vs 16K).\n */\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\n/* Table 9-8 shows scan chain 15 format during physical access mode, using a\n * dedicated 6-bit address space (encoded in bits 33:38).  Writes use one\n * JTAG scan, while reads use two.\n *\n * Table 9-9 lists the thirteen registers which support physical access.\n * ARM920T_CP15_PHYS_ADDR() constructs the 6-bit reg_addr parameter passed\n * to arm920t_read_cp15_physical() and arm920t_write_cp15_physical().\n *\n *  x == bit[38]\n *  y == bits[37:34]\n *  z == bit[33]\n */\n#define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))\n\n/* Registers supporting physical Read access (from table 9-9) */\n#define CP15PHYS_CACHETYPE      ARM920T_CP15_PHYS_ADDR(0, 0x0, 1)\n#define CP15PHYS_ICACHE_IDX     ARM920T_CP15_PHYS_ADDR(1, 0xd, 1)\n#define CP15PHYS_DCACHE_IDX     ARM920T_CP15_PHYS_ADDR(1, 0xe, 1)\n/* NOTE: several more registers support only physical read access */\n\n/* Registers supporting physical Read/Write access (from table 9-9) */\n#define CP15PHYS_CTRL           ARM920T_CP15_PHYS_ADDR(0, 0x1, 0)\n#define CP15PHYS_PID            ARM920T_CP15_PHYS_ADDR(0, 0xd, 0)\n#define CP15PHYS_TESTSTATE      ARM920T_CP15_PHYS_ADDR(0, 0xf, 0)\n#define CP15PHYS_ICACHE         ARM920T_CP15_PHYS_ADDR(1, 0x1, 1)\n#define CP15PHYS_DCACHE         ARM920T_CP15_PHYS_ADDR(1, 0x2, 1)\n\nstatic int arm920t_read_cp15_physical(struct target *target,\n\tint reg_addr, uint32_t *value)\n{\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm_jtag *jtag_info;\n\tstruct scan_field fields[4];\n\tuint8_t access_type_buf = 1;\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 0;\n\tint retval;\n\n\tjtag_info = &arm920t->arm7_9_common.jtag_info;\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = &access_type_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = NULL;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 6;\n\tfields[2].out_value = &reg_addr_buf;\n\tfields[2].in_value = NULL;\n\n\tfields[3].num_bits = 1;\n\tfields[3].out_value = &nr_w_buf;\n\tfields[3].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\tfields[1].in_value = (uint8_t *)value;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tjtag_execute_queue();\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, *value);\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic int arm920t_write_cp15_physical(struct target *target,\n\tint reg_addr, uint32_t value)\n{\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm_jtag *jtag_info;\n\tstruct scan_field fields[4];\n\tuint8_t access_type_buf = 1;\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 1;\n\tuint8_t value_buf[4];\n\tint retval;\n\n\tjtag_info = &arm920t->arm7_9_common.jtag_info;\n\n\tbuf_set_u32(value_buf, 0, 32, value);\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = &access_type_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = value_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 6;\n\tfields[2].out_value = &reg_addr_buf;\n\tfields[2].in_value = NULL;\n\n\tfields[3].num_bits = 1;\n\tfields[3].out_value = &nr_w_buf;\n\tfields[3].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, value);\n#endif\n\n\treturn ERROR_OK;\n}\n\n/* See table 9-10 for scan chain 15 format during interpreted access mode.\n * If the TESTSTATE register is set for interpreted access, certain CP15\n * MRC and MCR instructions may be executed through scan chain 15.\n *\n * Tables 9-11, 9-12, and 9-13 show which MRC and MCR instructions can be\n * executed using scan chain 15 interpreted mode.\n */\nstatic int arm920t_execute_cp15(struct target *target, uint32_t cp15_opcode,\n\tuint32_t arm_opcode)\n{\n\tint retval;\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm_jtag *jtag_info;\n\tstruct scan_field fields[4];\n\tuint8_t access_type_buf = 0;\t\t/* interpreted access */\n\tuint8_t reg_addr_buf = 0x0;\n\tuint8_t nr_w_buf = 0;\n\tuint8_t cp15_opcode_buf[4];\n\n\tjtag_info = &arm920t->arm7_9_common.jtag_info;\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tbuf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);\n\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = &access_type_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = cp15_opcode_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 6;\n\tfields[2].out_value = &reg_addr_buf;\n\tfields[2].in_value = NULL;\n\n\tfields[3].num_bits = 1;\n\tfields[3].out_value = &nr_w_buf;\n\tfields[3].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\tarm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n\tretval = arm7_9_execute_sys_speed(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed executing JTAG queue\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm920t_read_cp15_interpreted(struct target *target,\n\tuint32_t cp15_opcode, uint32_t address, uint32_t *value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tuint32_t *regs_p[16];\n\tuint32_t regs[16];\n\tuint32_t cp15c15 = 0x0;\n\tstruct reg *r = arm->core_cache->reg_list;\n\n\t/* load address into R1 */\n\tregs[1] = address;\n\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t/* read-modify-write CP15 test state register\n\t* to enable interpreted access mode */\n\tarm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);\n\tjtag_execute_queue();\n\tcp15c15 |= 1;\t/* set interpret mode */\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* execute CP15 instruction and ARM load (reading from coprocessor) */\n\tarm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));\n\n\t/* disable interpreted access mode */\n\tcp15c15 &= ~1U;\t/* clear interpret mode */\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* retrieve value from R0 */\n\tregs_p[0] = value;\n\tarm9tdmi_read_core_regs(target, 0x1, regs_p);\n\tjtag_execute_queue();\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"cp15_opcode: %8.8x, address: %8.8x, value: %8.8x\",\n\t\tcp15_opcode, address, *value);\n#endif\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr[0].dirty = true;\n\tr[1].dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic\nint arm920t_write_cp15_interpreted(struct target *target,\n\tuint32_t cp15_opcode, uint32_t value, uint32_t address)\n{\n\tuint32_t cp15c15 = 0x0;\n\tstruct arm *arm = target_to_arm(target);\n\tuint32_t regs[16];\n\tstruct reg *r = arm->core_cache->reg_list;\n\n\t/* load value, address into R0, R1 */\n\tregs[0] = value;\n\tregs[1] = address;\n\tarm9tdmi_write_core_regs(target, 0x3, regs);\n\n\t/* read-modify-write CP15 test state register\n\t* to enable interpreted access mode */\n\tarm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);\n\tjtag_execute_queue();\n\tcp15c15 |= 1;\t/* set interpret mode */\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* execute CP15 instruction and ARM store (writing to coprocessor) */\n\tarm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));\n\n\t/* disable interpreted access mode */\n\tcp15c15 &= ~1U;\t/* set interpret mode */\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"cp15_opcode: %8.8x, value: %8.8x, address: %8.8x\",\n\t\tcp15_opcode, value, address);\n#endif\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tr[0].dirty = true;\n\tr[1].dirty = true;\n\n\treturn ERROR_OK;\n}\n\n/* EXPORTED to FA256 */\nint arm920t_get_ttb(struct target *target, uint32_t *result)\n{\n\tint retval;\n\tuint32_t ttb = 0x0;\n\n\tretval = arm920t_read_cp15_interpreted(target,\n\t\t\t/* FIXME use opcode macro */\n\t\t\t0xeebf0f51, 0x0, &ttb);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*result = ttb;\n\treturn ERROR_OK;\n}\n\n/* EXPORTED to FA256 */\nint arm920t_disable_mmu_caches(struct target *target, int mmu,\n\tint d_u_cache, int i_cache)\n{\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu)\n\t\tcp15_control &= ~0x1U;\n\n\tif (d_u_cache)\n\t\tcp15_control &= ~0x4U;\n\n\tif (i_cache)\n\t\tcp15_control &= ~0x1000U;\n\n\tretval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);\n\treturn retval;\n}\n\n/* EXPORTED to FA256 */\nint arm920t_enable_mmu_caches(struct target *target, int mmu,\n\tint d_u_cache, int i_cache)\n{\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu)\n\t\tcp15_control |= 0x1U;\n\n\tif (d_u_cache)\n\t\tcp15_control |= 0x4U;\n\n\tif (i_cache)\n\t\tcp15_control |= 0x1000U;\n\n\tretval = arm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_control);\n\treturn retval;\n}\n\n/* EXPORTED to FA256 */\nint arm920t_post_debug_entry(struct target *target)\n{\n\tuint32_t cp15c15;\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tint retval;\n\n\t/* examine cp15 control reg */\n\tretval = arm920t_read_cp15_physical(target,\n\t\t\tCP15PHYS_CTRL, &arm920t->cp15_control_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"cp15_control_reg: %8.8\" PRIx32, arm920t->cp15_control_reg);\n\n\tif (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1) {\n\t\tuint32_t cache_type_reg;\n\t\t/* identify caches */\n\t\tretval = arm920t_read_cp15_physical(target,\n\t\t\t\tCP15PHYS_CACHETYPE, &cache_type_reg);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarmv4_5_identify_cache(cache_type_reg,\n\t\t\t&arm920t->armv4_5_mmu.armv4_5_cache);\n\t}\n\n\tarm920t->armv4_5_mmu.mmu_enabled =\n\t\t(arm920t->cp15_control_reg & 0x1U) ? 1 : 0;\n\tarm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =\n\t\t(arm920t->cp15_control_reg & 0x4U) ? 1 : 0;\n\tarm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled =\n\t\t(arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;\n\n\t/* save i/d fault status and address register\n\t * FIXME use opcode macros */\n\tretval = arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"D FSR: 0x%8.8\" PRIx32 \", D FAR: 0x%8.8\" PRIx32\n\t\t\", I FSR: 0x%8.8\" PRIx32 \", I FAR: 0x%8.8\" PRIx32,\n\t\tarm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);\n\n\tif (arm920t->preserve_cache) {\n\t\t/* read-modify-write CP15 test state register\n\t\t * to disable I/D-cache linefills */\n\t\tretval = arm920t_read_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, &cp15c15);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcp15c15 |= 0x600;\n\t\tretval = arm920t_write_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n\n/* EXPORTED to FA256 */\nvoid arm920t_pre_restore_context(struct target *target)\n{\n\tuint32_t cp15c15 = 0;\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\t/* restore i/d fault status and address register */\n\tarm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);\n\tarm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);\n\tarm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);\n\tarm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);\n\n\t/* read-modify-write CP15 test state register\n\t* to reenable I/D-cache linefills */\n\tif (arm920t->preserve_cache) {\n\t\tarm920t_read_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, &cp15c15);\n\t\tjtag_execute_queue();\n\t\tcp15c15 &= ~0x600U;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\t}\n}\n\nstatic const char arm920_not[] = \"target is not an ARM920\";\n\nstatic int arm920t_verify_pointer(struct command_invocation *cmd,\n\tstruct arm920t_common *arm920t)\n{\n\tif (arm920t->common_magic != ARM920T_COMMON_MAGIC) {\n\t\tcommand_print(cmd, arm920_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** Logs summary of ARM920 state for a halted target. */\nint arm920t_arch_state(struct target *target)\n{\n\tstatic const char *state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tif (arm920t->common_magic != ARM920T_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: %s\", arm920_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tarm_arch_state(target);\n\tLOG_USER(\"MMU: %s, D-Cache: %s, I-Cache: %s\",\n\t\tstate[arm920t->armv4_5_mmu.mmu_enabled],\n\t\tstate[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],\n\t\tstate[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);\n\n\treturn ERROR_OK;\n}\n\nstatic int arm920_mmu(struct target *target, int *enabled)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\t*enabled = target_to_arm920(target)->armv4_5_mmu.mmu_enabled;\n\treturn ERROR_OK;\n}\n\nstatic int arm920_virt2phys(struct target *target,\n\ttarget_addr_t virt, target_addr_t *phys)\n{\n\tuint32_t cb;\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tuint32_t ret;\n\tint retval = armv4_5_mmu_translate_va(target,\n\t\t\t&arm920t->armv4_5_mmu, virt, &cb, &ret);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t*phys = ret;\n\treturn ERROR_OK;\n}\n\n/** Reads a buffer, in the specified word size, with current MMU settings. */\nint arm920t_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\n\tretval = arm7_9_read_memory(target, address, size, count, buffer);\n\n\treturn retval;\n}\n\n\nstatic int arm920t_read_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\treturn armv4_5_mmu_read_physical(target, &arm920t->armv4_5_mmu,\n\t\taddress, size, count, buffer);\n}\n\nstatic int arm920t_write_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\treturn armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu,\n\t\taddress, size, count, buffer);\n}\n\n/** Writes a buffer, in the specified word size, with current MMU settings. */\nint arm920t_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\tconst uint32_t cache_mask = ~0x1f;\t/* cache line size : 32 byte */\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\t/* FIX!!!! this should be cleaned up and made much more general. The\n\t * plan is to write up and test on arm920t specifically and\n\t * then generalize and clean up afterwards.\n\t *\n\t * Also it should be moved to the callbacks that handle breakpoints\n\t * specifically and not the generic memory write fn's. See XScale code.\n\t */\n\tif (arm920t->armv4_5_mmu.mmu_enabled && (count == 1) &&\n\t\t\t((size == 2) || (size == 4))) {\n\t\t/* special case the handling of single word writes to\n\t\t * bypass MMU, to allow implementation of breakpoints\n\t\t * in memory marked read only\n\t\t * by MMU\n\t\t */\n\t\tuint32_t cb;\n\t\tuint32_t pa;\n\n\t\t/*\n\t\t * We need physical address and cb\n\t\t */\n\t\tretval = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu,\n\t\t\t\taddress, &cb, &pa);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {\n\t\t\tif (cb & 0x1) {\n\t\t\t\tLOG_DEBUG(\"D-Cache buffered, \"\n\t\t\t\t\t\"drain write buffer\");\n\t\t\t\t/*\n\t\t\t\t * Buffered ?\n\t\t\t\t * Drain write buffer - MCR p15,0,Rd,c7,c10,4\n\t\t\t\t */\n\n\t\t\t\tretval = arm920t_write_cp15_interpreted(target,\n\t\t\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 10, 4),\n\t\t\t\t\t\t0x0, 0);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tif (cb == 0x3) {\n\t\t\t\t/*\n\t\t\t\t * Write back memory ? -> clean cache\n\t\t\t\t *\n\t\t\t\t * There is no way to clean cache lines using\n\t\t\t\t * cp15 scan chain, so copy the full cache\n\t\t\t\t * line from cache to physical memory.\n\t\t\t\t */\n\t\t\t\tuint8_t data[32];\n\n\t\t\t\tLOG_DEBUG(\"D-Cache in 'write back' mode, \"\n\t\t\t\t\t\"flush cache line\");\n\n\t\t\t\tretval = target_read_memory(target,\n\t\t\t\t\t\taddress & cache_mask, 1,\n\t\t\t\t\t\tsizeof(data), &data[0]);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tretval = armv4_5_mmu_write_physical(target,\n\t\t\t\t\t\t&arm920t->armv4_5_mmu,\n\t\t\t\t\t\tpa & cache_mask, 1,\n\t\t\t\t\t\tsizeof(data), &data[0]);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Cached ? */\n\t\t\tif (cb & 0x2) {\n\t\t\t\t/*\n\t\t\t\t * Cached ? -> Invalidate data cache using MVA\n\t\t\t\t *\n\t\t\t\t * MCR p15,0,Rd,c7,c6,1\n\t\t\t\t */\n\t\t\t\tLOG_DEBUG(\"D-Cache enabled, \"\n\t\t\t\t\t\"invalidate cache line\");\n\n\t\t\t\tretval = arm920t_write_cp15_interpreted(target,\n\t\t\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 6, 1), 0x0,\n\t\t\t\t\t\taddress & cache_mask);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\t/* write directly to physical memory,\n\t\t * bypassing any read only MMU bits, etc.\n\t\t */\n\t\tretval = armv4_5_mmu_write_physical(target,\n\t\t\t\t&arm920t->armv4_5_mmu, pa, size,\n\t\t\t\tcount, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tretval = arm7_9_write_memory(target, address, size, count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* If ICache is enabled, we have to invalidate affected ICache lines\n\t * the DCache is forced to write-through,\n\t * so we don't have to clean it here\n\t */\n\tif (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {\n\t\tif (count <= 1) {\n\t\t\t/* invalidate ICache single entry with MVA\n\t\t\t *   mcr\t15, 0, r0, cr7, cr5, {1}\n\t\t\t */\n\t\t\tLOG_DEBUG(\"I-Cache enabled, \"\n\t\t\t\t\"invalidating affected I-Cache line\");\n\t\t\tretval = arm920t_write_cp15_interpreted(target,\n\t\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 1),\n\t\t\t\t\t0x0, address & cache_mask);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* invalidate ICache\n\t\t\t *  mcr\t15, 0, r0, cr7, cr5, {0}\n\t\t\t */\n\t\t\tretval = arm920t_write_cp15_interpreted(target,\n\t\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 0),\n\t\t\t\t\t0x0, 0x0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* EXPORTED to FA256 */\nint arm920t_soft_reset_halt(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\tretval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms();\n\tbool timeout;\n\twhile (!(timeout = ((timeval_ms()-then) > 1000))) {\n\t\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {\n\t\t\tembeddedice_read_reg(dbg_stat);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else\n\t\t\tbreak;\n\t\tif (debug_level >= 3) {\n\t\t\t/* do not eat all CPU, time out after 1 se*/\n\t\t\talive_sleep(100);\n\t\t} else\n\t\t\tkeep_alive();\n\t}\n\tif (timeout) {\n\t\tLOG_ERROR(\"Failed to halt CPU after 1 sec\");\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\ttarget->state = TARGET_HALTED;\n\n\t/* SVC, ARM state, IRQ and FIQ disabled */\n\tuint32_t cpsr;\n\n\tcpsr = buf_get_u32(arm->cpsr->value, 0, 32);\n\tcpsr &= ~0xff;\n\tcpsr |= 0xd3;\n\tarm_set_cpsr(arm, cpsr);\n\tarm->cpsr->dirty = true;\n\n\t/* start fetching from 0x0 */\n\tbuf_set_u32(arm->pc->value, 0, 32, 0x0);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\tarm920t_disable_mmu_caches(target, 1, 1, 1);\n\tarm920t->armv4_5_mmu.mmu_enabled = 0;\n\tarm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;\n\tarm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;\n\n\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n}\n\n/* FIXME remove forward decls */\nstatic int arm920t_mrc(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t *value);\nstatic int arm920t_mcr(struct target *target, int cpnum,\n\t\tuint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm,\n\t\tuint32_t value);\n\nstatic int arm920t_init_arch_info(struct target *target,\n\tstruct arm920t_common *arm920t, struct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;\n\n\tarm7_9->arm.mrc = arm920t_mrc;\n\tarm7_9->arm.mcr = arm920t_mcr;\n\n\t/* initialize arm7/arm9 specific info (including armv4_5) */\n\tarm9tdmi_init_arch_info(target, arm7_9, tap);\n\n\tarm920t->common_magic = ARM920T_COMMON_MAGIC;\n\n\tarm7_9->post_debug_entry = arm920t_post_debug_entry;\n\tarm7_9->pre_restore_context = arm920t_pre_restore_context;\n\tarm7_9->write_memory = arm920t_write_memory;\n\n\tarm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;\n\tarm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;\n\tarm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;\n\tarm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;\n\tarm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;\n\tarm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;\n\tarm920t->armv4_5_mmu.has_tiny_pages = 1;\n\tarm920t->armv4_5_mmu.mmu_enabled = 0;\n\n\t/* disabling linefills leads to lockups, so keep them enabled for now\n\t * this doesn't affect correctness, but might affect timing issues, if\n\t * important data is evicted from the cache during the debug session\n\t * */\n\tarm920t->preserve_cache = 0;\n\n\t/* override hw single-step capability from ARM9TDMI */\n\tarm7_9->has_single_step = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm920t_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm920t_common *arm920t;\n\n\tarm920t = calloc(1, sizeof(struct arm920t_common));\n\treturn arm920t_init_arch_info(target, arm920t, target->tap);\n}\n\nstatic void arm920t_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm920t);\n}\n\nCOMMAND_HANDLER(arm920t_handle_read_cache_command)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tuint32_t cp15c15;\n\tuint32_t cp15_ctrl, cp15_ctrl_saved;\n\tuint32_t regs[16];\n\tuint32_t *regs_p[16];\n\tuint32_t c15_c_d_ind, c15_c_i_ind;\n\tint i;\n\tFILE *output;\n\tint segment, index_t;\n\tstruct reg *r;\n\n\tretval = arm920t_verify_pointer(CMD, arm920t);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\toutput = fopen(CMD_ARGV[0], \"w\");\n\tif (!output) {\n\t\tLOG_DEBUG(\"error opening cache content file\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (i = 0; i < 16; i++)\n\t\tregs_p[i] = &regs[i];\n\n\t/* disable MMU and Caches */\n\tarm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcp15_ctrl_saved = cp15_ctrl;\n\tcp15_ctrl &= ~(ARMV4_5_MMU_ENABLED\n\t\t\t| ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);\n\tarm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);\n\n\t/* read CP15 test state register */\n\tarm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);\n\tjtag_execute_queue();\n\n\t/* read DCache content */\n\tfprintf(output, \"DCache:\\n\");\n\n\t/* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */\n\tfor (segment = 0;\n\t\t\tsegment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;\n\t\t\tsegment++) {\n\t\tfprintf(output, \"\\nsegment: %i\\n----------\", segment);\n\n\t\t/* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */\n\t\tregs[0] = 0x0 | (segment << 5);\n\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* D CAM Read, loads current victim into C15.C.D.Ind */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 2, 0, 15, 6, 2), ARMV4_5_LDR(1, 0));\n\n\t\t/* read current victim */\n\t\tarm920t_read_cp15_physical(target,\n\t\t\tCP15PHYS_DCACHE_IDX, &c15_c_d_ind);\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\tfor (index_t = 0; index_t < 64; index_t++) {\n\t\t\t/* Ra:\n\t\t\t * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)\n\t\t\t */\n\t\t\tregs[0] = 0x0 | (segment << 5) | (index_t << 26);\n\t\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t\t/* set interpret mode */\n\t\t\tcp15c15 |= 0x1;\n\t\t\tarm920t_write_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t\t/* Write DCache victim */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));\n\n\t\t\t/* Read D RAM */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 2, 0, 15, 10, 2),\n\t\t\t\tARMV4_5_LDMIA(0, 0x1fe, 0, 0));\n\n\t\t\t/* Read D CAM */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 2, 0, 15, 6, 2),\n\t\t\t\tARMV4_5_LDR(9, 0));\n\n\t\t\t/* clear interpret mode */\n\t\t\tcp15c15 &= ~0x1;\n\t\t\tarm920t_write_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t\t/* read D RAM and CAM content */\n\t\t\tarm9tdmi_read_core_regs(target, 0x3fe, regs_p);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* mask LFSR[6] */\n\t\t\tregs[9] &= 0xfffffffe;\n\t\t\tfprintf(output, \"\\nsegment: %i, index: %i, CAM: 0x%8.8\"\n\t\t\t\tPRIx32 \", content (%s):\\n\",\n\t\t\t\tsegment, index_t, regs[9],\n\t\t\t\t(regs[9] & 0x10) ? \"valid\" : \"invalid\");\n\n\t\t\tfor (i = 1; i < 9; i++) {\n\t\t\t\tfprintf(output, \"%i: 0x%8.8\" PRIx32 \"\\n\",\n\t\t\t\t\ti-1, regs[i]);\n\t\t\t}\n\n\t\t}\n\n\t\t/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */\n\t\tregs[0] = 0x0 | (segment << 5) | (c15_c_d_ind << 26);\n\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write DCache victim */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 9, 1, 0), ARMV4_5_LDR(1, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\t}\n\n\t/* read ICache content */\n\tfprintf(output, \"ICache:\\n\");\n\n\t/* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */\n\tfor (segment = 0;\n\t\t\tsegment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets;\n\t\t\tsegment++) {\n\t\tfprintf(output, \"segment: %i\\n----------\", segment);\n\n\t\t/* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */\n\t\tregs[0] = 0x0 | (segment << 5);\n\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* I CAM Read, loads current victim into C15.C.I.Ind */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 2, 0, 15, 5, 2), ARMV4_5_LDR(1, 0));\n\n\t\t/* read current victim */\n\t\tarm920t_read_cp15_physical(target, CP15PHYS_ICACHE_IDX,\n\t\t\t&c15_c_i_ind);\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\tfor (index_t = 0; index_t < 64; index_t++) {\n\t\t\t/* Ra:\n\t\t\t * r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0)\n\t\t\t */\n\t\t\tregs[0] = 0x0 | (segment << 5) | (index_t << 26);\n\t\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t\t/* set interpret mode */\n\t\t\tcp15c15 |= 0x1;\n\t\t\tarm920t_write_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t\t/* Write ICache victim */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));\n\n\t\t\t/* Read I RAM */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 2, 0, 15, 9, 2),\n\t\t\t\tARMV4_5_LDMIA(0, 0x1fe, 0, 0));\n\n\t\t\t/* Read I CAM */\n\t\t\tarm920t_execute_cp15(target,\n\t\t\t\tARMV4_5_MCR(15, 2, 0, 15, 5, 2),\n\t\t\t\tARMV4_5_LDR(9, 0));\n\n\t\t\t/* clear interpret mode */\n\t\t\tcp15c15 &= ~0x1;\n\t\t\tarm920t_write_cp15_physical(target,\n\t\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t\t/* read I RAM and CAM content */\n\t\t\tarm9tdmi_read_core_regs(target, 0x3fe, regs_p);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* mask LFSR[6] */\n\t\t\tregs[9] &= 0xfffffffe;\n\t\t\tfprintf(output, \"\\nsegment: %i, index: %i, \"\n\t\t\t\t\"CAM: 0x%8.8\" PRIx32 \", content (%s):\\n\",\n\t\t\t\tsegment, index_t, regs[9],\n\t\t\t\t(regs[9] & 0x10) ? \"valid\" : \"invalid\");\n\n\t\t\tfor (i = 1; i < 9; i++) {\n\t\t\t\tfprintf(output, \"%i: 0x%8.8\" PRIx32 \"\\n\",\n\t\t\t\t\ti-1, regs[i]);\n\t\t\t}\n\t\t}\n\n\t\t/* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */\n\t\tregs[0] = 0x0 | (segment << 5) | (c15_c_d_ind << 26);\n\t\tarm9tdmi_write_core_regs(target, 0x1, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write ICache victim */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 9, 1, 1), ARMV4_5_LDR(1, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\t}\n\n\t/* restore CP15 MMU and Cache settings */\n\tarm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);\n\n\tcommand_print(CMD, \"cache content successfully output to %s\",\n\t\tCMD_ARGV[0]);\n\n\tfclose(output);\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* force writeback of the valid data */\n\tr = arm->core_cache->reg_list;\n\tr[0].dirty = r[0].valid;\n\tr[1].dirty = r[1].valid;\n\tr[2].dirty = r[2].valid;\n\tr[3].dirty = r[3].valid;\n\tr[4].dirty = r[4].valid;\n\tr[5].dirty = r[5].valid;\n\tr[6].dirty = r[6].valid;\n\tr[7].dirty = r[7].valid;\n\n\tr = arm_reg_current(arm, 8);\n\tr->dirty = r->valid;\n\n\tr = arm_reg_current(arm, 9);\n\tr->dirty = r->valid;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm920t_handle_read_mmu_command)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tuint32_t cp15c15;\n\tuint32_t cp15_ctrl, cp15_ctrl_saved;\n\tuint32_t regs[16];\n\tuint32_t *regs_p[16];\n\tint i;\n\tFILE *output;\n\tuint32_t d_lockdown, i_lockdown;\n\tstruct arm920t_tlb_entry d_tlb[64], i_tlb[64];\n\tint victim;\n\tstruct reg *r;\n\n\tretval = arm920t_verify_pointer(CMD, arm920t);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\toutput = fopen(CMD_ARGV[0], \"w\");\n\tif (!output) {\n\t\tLOG_DEBUG(\"error opening mmu content file\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (i = 0; i < 16; i++)\n\t\tregs_p[i] = &regs[i];\n\n\t/* disable MMU and Caches */\n\tarm920t_read_cp15_physical(target, CP15PHYS_CTRL, &cp15_ctrl);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcp15_ctrl_saved = cp15_ctrl;\n\tcp15_ctrl &= ~(ARMV4_5_MMU_ENABLED\n\t\t\t| ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);\n\tarm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl);\n\n\t/* read CP15 test state register */\n\tarm920t_read_cp15_physical(target, CP15PHYS_TESTSTATE, &cp15c15);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* prepare reading D TLB content\n\t * */\n\n\t/* set interpret mode */\n\tcp15c15 |= 0x1;\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* Read D TLB lockdown */\n\tarm920t_execute_cp15(target,\n\t\tARMV4_5_MRC(15, 0, 0, 10, 0, 0), ARMV4_5_LDR(1, 0));\n\n\t/* clear interpret mode */\n\tcp15c15 &= ~0x1;\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* read D TLB lockdown stored to r1 */\n\tarm9tdmi_read_core_regs(target, 0x2, regs_p);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\td_lockdown = regs[1];\n\n\tfor (victim = 0; victim < 64; victim += 8) {\n\t\t/* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]\n\t\t * base remains unchanged, victim goes through entries 0 to 63\n\t\t */\n\t\tregs[1] = (d_lockdown & 0xfc000000) | (victim << 20);\n\t\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write D TLB lockdown */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 0),\n\t\t\tARMV4_5_STR(1, 0));\n\n\t\t/* Read D TLB CAM */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 6, 4),\n\t\t\tARMV4_5_LDMIA(0, 0x3fc, 0, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* read D TLB CAM content stored to r2-r9 */\n\t\tarm9tdmi_read_core_regs(target, 0x3fc, regs_p);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (i = 0; i < 8; i++)\n\t\t\td_tlb[victim + i].cam = regs[i + 2];\n\t}\n\n\tfor (victim = 0; victim < 64; victim++) {\n\t\t/* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]\n\t\t * base remains unchanged, victim goes through entries 0 to 63\n\t\t */\n\t\tregs[1] = (d_lockdown & 0xfc000000) | (victim << 20);\n\t\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write D TLB lockdown */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0));\n\n\t\t/* Read D TLB RAM1 */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 10, 4), ARMV4_5_LDR(2, 0));\n\n\t\t/* Read D TLB RAM2 */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 2, 5), ARMV4_5_LDR(3, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* read D TLB RAM content stored to r2 and r3 */\n\t\tarm9tdmi_read_core_regs(target, 0xc, regs_p);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\td_tlb[victim].ram1 = regs[2];\n\t\td_tlb[victim].ram2 = regs[3];\n\t}\n\n\t/* restore D TLB lockdown */\n\tregs[1] = d_lockdown;\n\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t/* Write D TLB lockdown */\n\tarm920t_execute_cp15(target,\n\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 0), ARMV4_5_STR(1, 0));\n\n\t/* prepare reading I TLB content\n\t * */\n\n\t/* set interpret mode */\n\tcp15c15 |= 0x1;\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* Read I TLB lockdown */\n\tarm920t_execute_cp15(target,\n\t\tARMV4_5_MRC(15, 0, 0, 10, 0, 1), ARMV4_5_LDR(1, 0));\n\n\t/* clear interpret mode */\n\tcp15c15 &= ~0x1;\n\tarm920t_write_cp15_physical(target, CP15PHYS_TESTSTATE, cp15c15);\n\n\t/* read I TLB lockdown stored to r1 */\n\tarm9tdmi_read_core_regs(target, 0x2, regs_p);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ti_lockdown = regs[1];\n\n\tfor (victim = 0; victim < 64; victim += 8) {\n\t\t/* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]\n\t\t * base remains unchanged, victim goes through entries 0 to 63\n\t\t */\n\t\tregs[1] = (i_lockdown & 0xfc000000) | (victim << 20);\n\t\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write I TLB lockdown */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 1),\n\t\t\tARMV4_5_STR(1, 0));\n\n\t\t/* Read I TLB CAM */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 5, 4),\n\t\t\tARMV4_5_LDMIA(0, 0x3fc, 0, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* read I TLB CAM content stored to r2-r9 */\n\t\tarm9tdmi_read_core_regs(target, 0x3fc, regs_p);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (i = 0; i < 8; i++)\n\t\t\ti_tlb[i + victim].cam = regs[i + 2];\n\t}\n\n\tfor (victim = 0; victim < 64; victim++) {\n\t\t/* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]\n\t\t * base remains unchanged, victim goes through entries 0 to 63\n\t\t */\n\t\tregs[1] = (d_lockdown & 0xfc000000) | (victim << 20);\n\t\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t\t/* set interpret mode */\n\t\tcp15c15 |= 0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* Write I TLB lockdown */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));\n\n\t\t/* Read I TLB RAM1 */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 9, 4), ARMV4_5_LDR(2, 0));\n\n\t\t/* Read I TLB RAM2 */\n\t\tarm920t_execute_cp15(target,\n\t\t\tARMV4_5_MCR(15, 4, 0, 15, 1, 5), ARMV4_5_LDR(3, 0));\n\n\t\t/* clear interpret mode */\n\t\tcp15c15 &= ~0x1;\n\t\tarm920t_write_cp15_physical(target,\n\t\t\tCP15PHYS_TESTSTATE, cp15c15);\n\n\t\t/* read I TLB RAM content stored to r2 and r3 */\n\t\tarm9tdmi_read_core_regs(target, 0xc, regs_p);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\ti_tlb[victim].ram1 = regs[2];\n\t\ti_tlb[victim].ram2 = regs[3];\n\t}\n\n\t/* restore I TLB lockdown */\n\tregs[1] = i_lockdown;\n\tarm9tdmi_write_core_regs(target, 0x2, regs);\n\n\t/* Write I TLB lockdown */\n\tarm920t_execute_cp15(target,\n\t\tARMV4_5_MCR(15, 0, 0, 10, 0, 1), ARMV4_5_STR(1, 0));\n\n\t/* restore CP15 MMU and Cache settings */\n\tarm920t_write_cp15_physical(target, CP15PHYS_CTRL, cp15_ctrl_saved);\n\n\t/* output data to file */\n\tfprintf(output, \"D TLB content:\\n\");\n\tfor (i = 0; i < 64; i++) {\n\t\tfprintf(output, \"%i: 0x%8.8\" PRIx32 \" 0x%8.8\" PRIx32\n\t\t\t\" 0x%8.8\" PRIx32 \" %s\\n\",\n\t\t\ti, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2,\n\t\t\t(d_tlb[i].cam & 0x20) ? \"(valid)\" : \"(invalid)\");\n\t}\n\n\tfprintf(output, \"\\n\\nI TLB content:\\n\");\n\tfor (i = 0; i < 64; i++) {\n\t\tfprintf(output, \"%i: 0x%8.8\" PRIx32 \" 0x%8.8\" PRIx32\n\t\t\t\" 0x%8.8\" PRIx32 \" %s\\n\",\n\t\t\ti, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2,\n\t\t\t(i_tlb[i].cam & 0x20) ? \"(valid)\" : \"(invalid)\");\n\t}\n\n\tcommand_print(CMD, \"mmu content successfully output to %s\",\n\t\tCMD_ARGV[0]);\n\n\tfclose(output);\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* force writeback of the valid data */\n\tr = arm->core_cache->reg_list;\n\tr[0].dirty = r[0].valid;\n\tr[1].dirty = r[1].valid;\n\tr[2].dirty = r[2].valid;\n\tr[3].dirty = r[3].valid;\n\tr[4].dirty = r[4].valid;\n\tr[5].dirty = r[5].valid;\n\tr[6].dirty = r[6].valid;\n\tr[7].dirty = r[7].valid;\n\n\tr = arm_reg_current(arm, 8);\n\tr->dirty = r->valid;\n\n\tr = arm_reg_current(arm, 9);\n\tr->dirty = r->valid;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm920t_handle_cp15_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tretval = arm920t_verify_pointer(CMD, arm920t);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \"\n\t\t\t\"\\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* one argument, read a register.\n\t * two arguments, write it.\n\t */\n\tif (CMD_ARGC >= 1) {\n\t\tint address;\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], address);\n\n\t\tif (CMD_ARGC == 1) {\n\t\t\tuint32_t value;\n\t\t\tretval = arm920t_read_cp15_physical(target, address, &value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"couldn't access reg %i\", address);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tcommand_print(CMD, \"%i: %8.8\" PRIx32,\n\t\t\t\taddress, value);\n\t\t} else if (CMD_ARGC == 2)   {\n\t\t\tuint32_t value;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\t\t\tretval = arm920t_write_cp15_physical(target,\n\t\t\t\t\taddress, value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"couldn't access reg %i\", address);\n\t\t\t\t/* REVISIT why lie? \"return retval\"? */\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"%i: %8.8\" PRIx32,\n\t\t\t\taddress, value);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm920t_handle_cache_info_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tretval = arm920t_verify_pointer(CMD, arm920t);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn armv4_5_handle_cache_info_command(CMD,\n\t\t&arm920t->armv4_5_mmu.armv4_5_cache);\n}\n\n\nstatic int arm920t_mrc(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2,\n\tuint32_t crn, uint32_t crm,\n\tuint32_t *value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* read \"to\" r0 */\n\treturn arm920t_read_cp15_interpreted(target,\n\t\tARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),\n\t\t0, value);\n}\n\nstatic int arm920t_mcr(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2,\n\tuint32_t crn, uint32_t crm,\n\tuint32_t value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* write \"from\" r0 */\n\treturn arm920t_write_cp15_interpreted(target,\n\t\tARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),\n\t\t0, value);\n}\n\nstatic const struct command_registration arm920t_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cp15\",\n\t\t.handler = arm920t_handle_cp15_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display/modify cp15 register\",\n\t\t.usage = \"regnum [value]\",\n\t},\n\t{\n\t\t.name = \"cache_info\",\n\t\t.handler = arm920t_handle_cache_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"display information about target caches\",\n\t},\n\t{\n\t\t.name = \"read_cache\",\n\t\t.handler = arm920t_handle_read_cache_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"dump I/D cache content to file\",\n\t\t.usage = \"filename\",\n\t},\n\t{\n\t\t.name = \"read_mmu\",\n\t\t.handler = arm920t_handle_read_mmu_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"dump I/D mmu content to file\",\n\t\t.usage = \"filename\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nconst struct command_registration arm920t_command_handlers[] = {\n\t{\n\t\t.chain = arm9tdmi_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm920t\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm920t command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm920t_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM920 targets. */\nstruct target_type arm920t_target = {\n\t.name = \"arm920t\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm920t_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm920t_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm920t_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\t.read_phys_memory = arm920t_read_phys_memory,\n\t.write_phys_memory = arm920t_write_phys_memory,\n\t.mmu = arm920_mmu,\n\t.virt2phys = arm920_virt2phys,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm920t_command_handlers,\n\t.target_create = arm920t_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = arm920t_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm920t.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM920T_H\n#define OPENOCD_TARGET_ARM920T_H\n\n#include \"arm9tdmi.h\"\n#include \"armv4_5_mmu.h\"\n\n#define\tARM920T_COMMON_MAGIC 0xa920a920U\n\nstruct arm920t_common {\n\tunsigned int common_magic;\n\n\tstruct arm7_9_common arm7_9_common;\n\tstruct armv4_5_mmu_common armv4_5_mmu;\n\tuint32_t cp15_control_reg;\n\tuint32_t d_fsr;\n\tuint32_t i_fsr;\n\tuint32_t d_far;\n\tuint32_t i_far;\n\tint preserve_cache;\n};\n\nstatic inline struct arm920t_common *target_to_arm920(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm920t_common, arm7_9_common.arm);\n}\n\nstruct arm920t_cache_line {\n\tuint32_t cam;\n\tuint32_t data[8];\n};\n\nstruct arm920t_tlb_entry {\n\tuint32_t cam;\n\tuint32_t ram1;\n\tuint32_t ram2;\n};\n\nint arm920t_arch_state(struct target *target);\nint arm920t_soft_reset_halt(struct target *target);\nint arm920t_read_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);\nint arm920t_write_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\nint arm920t_post_debug_entry(struct target *target);\nvoid arm920t_pre_restore_context(struct target *target);\nint arm920t_get_ttb(struct target *target, uint32_t *result);\nint arm920t_disable_mmu_caches(struct target *target,\n\tint mmu, int d_u_cache, int i_cache);\nint arm920t_enable_mmu_caches(struct target *target,\n\tint mmu, int d_u_cache, int i_cache);\n\nextern const struct command_registration arm920t_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARM920T_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm926ejs.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008,2009 by Øyvind Harboe                         *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm926ejs.h\"\n#include <helper/time_support.h>\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n\n\n/*\n * The ARM926 is built around the ARM9EJ-S core, and most JTAG docs\n * are in the ARM9EJ-S Technical Reference Manual (ARM DDI 0222B) not\n * the ARM926 manual (ARM DDI 0198E).  The scan chains are:\n *\n *   1 ... core debugging\n *   2 ... EmbeddedICE\n *   3 ... external boundary scan (SoC-specific, unused here)\n *   6 ... ETM\n *   15 ... coprocessor 15\n */\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\n#define ARM926EJS_CP15_ADDR(opcode_1, opcode_2, crn, crm) ((opcode_1 << 11) | (opcode_2 << 8) | (crn << 4) | (crm << 0))\n\nstatic int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm, uint32_t *value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tuint32_t address = ARM926EJS_CP15_ADDR(op1, op2, crn, crm);\n\tstruct scan_field fields[4];\n\tuint8_t address_buf[2] = {0, 0};\n\tuint8_t nr_w_buf = 0;\n\tuint8_t access_t = 1;\n\n\tbuf_set_u32(address_buf, 0, 14, address);\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = (uint8_t *)value;\n\n\tfields[1].num_bits = 1;\n\tfields[1].out_value = &access_t;\n\tfields[1].in_value = &access_t;\n\n\tfields[2].num_bits = 14;\n\tfields[2].out_value = address_buf;\n\tfields[2].in_value = NULL;\n\n\tfields[3].num_bits = 1;\n\tfields[3].out_value = &nr_w_buf;\n\tfields[3].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\tint64_t then = timeval_ms();\n\n\tfor (;;) {\n\t\t/* rescan with NOP, to wait for the access to complete */\n\t\taccess_t = 0;\n\t\tnr_w_buf = 0;\n\t\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\t\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (buf_get_u32(&access_t, 0, 1) == 1)\n\t\t\tbreak;\n\n\t\t/* 10ms timeout */\n\t\tif ((timeval_ms()-then) > 10) {\n\t\t\tLOG_ERROR(\"cp15 read operation timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", address, *value);\n#endif\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, 0xc, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_mrc(struct target *target, int cpnum, uint32_t op1,\n\t\tuint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn arm926ejs_cp15_read(target, op1, op2, crn, crm, value);\n}\n\nstatic int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op2,\n\t\tuint32_t crn, uint32_t crm, uint32_t value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tuint32_t address = ARM926EJS_CP15_ADDR(op1, op2, crn, crm);\n\tstruct scan_field fields[4];\n\tuint8_t value_buf[4];\n\tuint8_t address_buf[2] = {0, 0};\n\tuint8_t nr_w_buf = 1;\n\tuint8_t access_t = 1;\n\n\tbuf_set_u32(address_buf, 0, 14, address);\n\tbuf_set_u32(value_buf, 0, 32, value);\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = value_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 1;\n\tfields[1].out_value = &access_t;\n\tfields[1].in_value = &access_t;\n\n\tfields[2].num_bits = 14;\n\tfields[2].out_value = address_buf;\n\tfields[2].in_value = NULL;\n\n\tfields[3].num_bits = 1;\n\tfields[3].out_value = &nr_w_buf;\n\tfields[3].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\n\tint64_t then = timeval_ms();\n\n\tfor (;;) {\n\t\t/* rescan with NOP, to wait for the access to complete */\n\t\taccess_t = 0;\n\t\tnr_w_buf = 0;\n\t\tjtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (buf_get_u32(&access_t, 0, 1) == 1)\n\t\t\tbreak;\n\n\t\t/* 10ms timeout */\n\t\tif ((timeval_ms()-then) > 10) {\n\t\t\tLOG_ERROR(\"cp15 write operation timed out\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", address, value);\n#endif\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, 0xf, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_mcr(struct target *target, int cpnum, uint32_t op1,\n\t\tuint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)\n{\n\tif (cpnum != 15) {\n\t\tLOG_ERROR(\"Only cp15 is supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn arm926ejs_cp15_write(target, op1, op2, crn, crm, value);\n}\n\nstatic int arm926ejs_examine_debug_reason(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\tint debug_reason;\n\tint retval;\n\n\tembeddedice_read_reg(dbg_stat);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Method-Of-Entry (MOE) field */\n\tdebug_reason = buf_get_u32(dbg_stat->value, 6, 4);\n\n\tswitch (debug_reason) {\n\t\tcase 0:\n\t\t\tLOG_DEBUG(\"no *NEW* debug entry (?missed one?)\");\n\t\t\t/* ... since last restart or debug reset ... */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tLOG_DEBUG(\"breakpoint from EICE unit 0\");\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tLOG_DEBUG(\"breakpoint from EICE unit 1\");\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tLOG_DEBUG(\"soft breakpoint (BKPT instruction)\");\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tLOG_DEBUG(\"vector catch breakpoint\");\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tLOG_DEBUG(\"external breakpoint\");\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tLOG_DEBUG(\"watchpoint from EICE unit 0\");\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tLOG_DEBUG(\"watchpoint from EICE unit 1\");\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tLOG_DEBUG(\"external watchpoint\");\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tLOG_DEBUG(\"internal debug request\");\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase 10:\n\t\t\tLOG_DEBUG(\"external debug request\");\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase 11:\n\t\t\tLOG_DEBUG(\"debug re-entry from system speed access\");\n\t\t\t/* This is normal when connecting to something that's\n\t\t\t * already halted, or in some related code paths, but\n\t\t\t * otherwise is surprising (and presumably wrong).\n\t\t\t */\n\t\t\tswitch (target->debug_reason) {\n\t\t\tcase DBG_REASON_DBGRQ:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"unexpected -- debug re-entry\");\n\t\t\t\t/* FALLTHROUGH */\n\t\t\tcase DBG_REASON_UNDEFINED:\n\t\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 12:\n\t\t\t/* FIX!!!! here be dragons!!! We need to fail here so\n\t\t\t * the target will interpreted as halted but we won't\n\t\t\t * try to talk to it right now... a resume + halt seems\n\t\t\t * to sync things up again. Please send an email to\n\t\t\t * openocd development mailing list if you have hardware\n\t\t\t * to donate to look into this problem....\n\t\t\t */\n\t\t\tLOG_WARNING(\"WARNING: mystery debug reason MOE = 0xc. Try issuing a resume + halt.\");\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_WARNING(\"WARNING: unknown debug reason: 0x%x\", debug_reason);\n\t\t\t/* Oh agony! should we interpret this as a halt request or\n\t\t\t * that the target stopped on it's own accord?\n\t\t\t */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\t/* if we fail here, we won't talk to the target and it will\n\t\t\t * be reported to be in the halted state */\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_get_ttb(struct target *target, uint32_t *result)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\tint retval;\n\tuint32_t ttb = 0x0;\n\n\tretval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*result = ttb;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_disable_mmu_caches(struct target *target, int mmu,\n\t\tint d_u_cache, int i_cache)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu) {\n\t\t/* invalidate TLB */\n\t\tretval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcp15_control &= ~0x1U;\n\t}\n\n\tif (d_u_cache) {\n\t\tuint32_t debug_override;\n\t\t/* read-modify-write CP15 debug override register\n\t\t * to enable \"test and clean all\" */\n\t\tretval = arm926ejs->read_cp15(target, 0, 0, 15, 0, &debug_override);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tdebug_override |= 0x80000;\n\t\tretval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* clean and invalidate DCache */\n\t\tretval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* write CP15 debug override register\n\t\t * to disable \"test and clean all\" */\n\t\tdebug_override &= ~0x80000;\n\t\tretval = arm926ejs->write_cp15(target, 0, 0, 15, 0, debug_override);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcp15_control &= ~0x4U;\n\t}\n\n\tif (i_cache) {\n\t\t/* invalidate ICache */\n\t\tretval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcp15_control &= ~0x1000U;\n\t}\n\n\tretval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);\n\treturn retval;\n}\n\nstatic int arm926ejs_enable_mmu_caches(struct target *target, int mmu,\n\t\tint d_u_cache, int i_cache)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mmu)\n\t\tcp15_control |= 0x1U;\n\n\tif (d_u_cache)\n\t\tcp15_control |= 0x4U;\n\n\tif (i_cache)\n\t\tcp15_control |= 0x1000U;\n\n\tretval = arm926ejs->write_cp15(target, 0, 0, 1, 0, cp15_control);\n\treturn retval;\n}\n\nstatic int arm926ejs_post_debug_entry(struct target *target)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\tint retval;\n\n\t/* examine cp15 control reg */\n\tretval = arm926ejs->read_cp15(target, 0, 0, 1, 0, &arm926ejs->cp15_control_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"cp15_control_reg: %8.8\" PRIx32 \"\", arm926ejs->cp15_control_reg);\n\n\tif (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1) {\n\t\tuint32_t cache_type_reg;\n\t\t/* identify caches */\n\t\tretval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarmv4_5_identify_cache(cache_type_reg, &arm926ejs->armv4_5_mmu.armv4_5_cache);\n\t}\n\n\tarm926ejs->armv4_5_mmu.mmu_enabled = (arm926ejs->cp15_control_reg & 0x1U) ? 1 : 0;\n\tarm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm926ejs->cp15_control_reg & 0x4U) ? 1 : 0;\n\tarm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm926ejs->cp15_control_reg & 0x1000U) ? 1 : 0;\n\n\t/* save i/d fault status and address register */\n\tretval = arm926ejs->read_cp15(target, 0, 0, 5, 0, &arm926ejs->d_fsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm926ejs->read_cp15(target, 0, 1, 5, 0, &arm926ejs->i_fsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm926ejs->read_cp15(target, 0, 0, 6, 0, &arm926ejs->d_far);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"D FSR: 0x%8.8\" PRIx32 \", D FAR: 0x%8.8\" PRIx32 \", I FSR: 0x%8.8\" PRIx32 \"\",\n\t\tarm926ejs->d_fsr, arm926ejs->d_far, arm926ejs->i_fsr);\n\n\tuint32_t cache_dbg_ctrl;\n\n\t/* read-modify-write CP15 cache debug control register\n\t * to disable I/D-cache linefills and force WT */\n\tretval = arm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcache_dbg_ctrl |= 0x7;\n\tretval = arm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);\n\treturn retval;\n}\n\nstatic void arm926ejs_pre_restore_context(struct target *target)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\t/* restore i/d fault status and address register */\n\tarm926ejs->write_cp15(target, 0, 0, 5, 0, arm926ejs->d_fsr);\n\tarm926ejs->write_cp15(target, 0, 1, 5, 0, arm926ejs->i_fsr);\n\tarm926ejs->write_cp15(target, 0, 0, 6, 0, arm926ejs->d_far);\n\n\tuint32_t cache_dbg_ctrl;\n\n\t/* read-modify-write CP15 cache debug control register\n\t * to reenable I/D-cache linefills and disable WT */\n\tarm926ejs->read_cp15(target, 7, 0, 15, 0, &cache_dbg_ctrl);\n\tcache_dbg_ctrl &= ~0x7;\n\tarm926ejs->write_cp15(target, 7, 0, 15, 0, cache_dbg_ctrl);\n}\n\nstatic const char arm926_not[] = \"target is not an ARM926\";\n\nstatic int arm926ejs_verify_pointer(struct command_invocation *cmd,\n\t\tstruct arm926ejs_common *arm926)\n{\n\tif (arm926->common_magic != ARM926EJS_COMMON_MAGIC) {\n\t\tcommand_print(cmd, arm926_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\n/** Logs summary of ARM926 state for a halted target. */\nint arm926ejs_arch_state(struct target *target)\n{\n\tstatic const char *state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\tif (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: %s\", arm926_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tarm_arch_state(target);\n\tLOG_USER(\"MMU: %s, D-Cache: %s, I-Cache: %s\",\n\t\t\t state[arm926ejs->armv4_5_mmu.mmu_enabled],\n\t\t\t state[arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],\n\t\t\t state[arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);\n\n\treturn ERROR_OK;\n}\n\nint arm926ejs_soft_reset_halt(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\tretval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms();\n\tint timeout;\n\twhile (!(timeout = ((timeval_ms()-then) > 1000))) {\n\t\tif (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {\n\t\t\tembeddedice_read_reg(dbg_stat);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else\n\t\t\tbreak;\n\t\tif (debug_level >= 1) {\n\t\t\t/* do not eat all CPU, time out after 1 se*/\n\t\t\talive_sleep(100);\n\t\t} else\n\t\t\tkeep_alive();\n\t}\n\tif (timeout) {\n\t\tLOG_ERROR(\"Failed to halt CPU after 1 sec\");\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\ttarget->state = TARGET_HALTED;\n\n\t/* SVC, ARM state, IRQ and FIQ disabled */\n\tuint32_t cpsr;\n\n\tcpsr = buf_get_u32(arm->cpsr->value, 0, 32);\n\tcpsr &= ~0xff;\n\tcpsr |= 0xd3;\n\tarm_set_cpsr(arm, cpsr);\n\tarm->cpsr->dirty = true;\n\n\t/* start fetching from 0x0 */\n\tbuf_set_u32(arm->pc->value, 0, 32, 0x0);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\tretval = arm926ejs_disable_mmu_caches(target, 1, 1, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tarm926ejs->armv4_5_mmu.mmu_enabled = 0;\n\tarm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;\n\tarm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;\n\n\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n}\n\n/** Writes a buffer, in the specified word size, with current MMU settings. */\nint arm926ejs_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\t/* FIX!!!! this should be cleaned up and made much more general. The\n\t * plan is to write up and test on arm926ejs specifically and\n\t * then generalize and clean up afterwards.\n\t *\n\t *\n\t * Also it should be moved to the callbacks that handle breakpoints\n\t * specifically and not the generic memory write fn's. See XScale code.\n\t **/\n\tif (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size == 2) || (size == 4))) {\n\t\t/* special case the handling of single word writes to bypass MMU\n\t\t * to allow implementation of breakpoints in memory marked read only\n\t\t * by MMU */\n\t\tif (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {\n\t\t\t/* flush and invalidate data cache\n\t\t\t *\n\t\t\t * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address\n\t\t\t *\n\t\t\t */\n\t\t\tretval = arm926ejs->write_cp15(target, 0, 1, 7, 10, address&~0x3);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\ttarget_addr_t pa;\n\t\tretval = target->type->virt2phys(target, address, &pa);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* write directly to physical memory bypassing any read only MMU bits, etc. */\n\t\tretval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tretval = arm7_9_write_memory(target, address, size, count, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* If ICache is enabled, we have to invalidate affected ICache lines\n\t * the DCache is forced to write-through, so we don't have to clean it here\n\t */\n\tif (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {\n\t\tif (count <= 1) {\n\t\t\t/* invalidate ICache single entry with MVA */\n\t\t\tarm926ejs->write_cp15(target, 0, 1, 7, 5, address);\n\t\t} else {\n\t\t\t/* invalidate ICache */\n\t\t\tarm926ejs->write_cp15(target, 0, 0, 7, 5, address);\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int arm926ejs_write_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size,\n\t\tuint32_t count, const uint8_t *buffer)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\treturn armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu,\n\t\t\taddress, size, count, buffer);\n}\n\nstatic int arm926ejs_read_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size,\n\t\tuint32_t count, uint8_t *buffer)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\treturn armv4_5_mmu_read_physical(target, &arm926ejs->armv4_5_mmu,\n\t\t\taddress, size, count, buffer);\n}\n\nint arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm926ejs,\n\t\tstruct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm926ejs->arm7_9_common;\n\n\tarm7_9->arm.mrc = arm926ejs_mrc;\n\tarm7_9->arm.mcr = arm926ejs_mcr;\n\n\t/* initialize arm7/arm9 specific info (including armv4_5) */\n\tarm9tdmi_init_arch_info(target, arm7_9, tap);\n\n\tarm926ejs->common_magic = ARM926EJS_COMMON_MAGIC;\n\n\tarm7_9->post_debug_entry = arm926ejs_post_debug_entry;\n\tarm7_9->pre_restore_context = arm926ejs_pre_restore_context;\n\tarm7_9->write_memory = arm926ejs_write_memory;\n\n\tarm926ejs->read_cp15 = arm926ejs_cp15_read;\n\tarm926ejs->write_cp15 = arm926ejs_cp15_write;\n\tarm926ejs->armv4_5_mmu.armv4_5_cache.ctype = -1;\n\tarm926ejs->armv4_5_mmu.get_ttb = arm926ejs_get_ttb;\n\tarm926ejs->armv4_5_mmu.read_memory = arm7_9_read_memory;\n\tarm926ejs->armv4_5_mmu.write_memory = arm7_9_write_memory;\n\tarm926ejs->armv4_5_mmu.disable_mmu_caches = arm926ejs_disable_mmu_caches;\n\tarm926ejs->armv4_5_mmu.enable_mmu_caches = arm926ejs_enable_mmu_caches;\n\tarm926ejs->armv4_5_mmu.has_tiny_pages = 1;\n\tarm926ejs->armv4_5_mmu.mmu_enabled = 0;\n\n\tarm7_9->examine_debug_reason = arm926ejs_examine_debug_reason;\n\n\t/* The ARM926EJ-S implements the ARMv5TE architecture which\n\t * has the BKPT instruction, so we don't have to use a watchpoint comparator\n\t */\n\tarm7_9->arm_bkpt = ARMV5_BKPT(0x0);\n\tarm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common));\n\n\t/* ARM9EJ-S core always reports 0x1 in Capture-IR */\n\ttarget->tap->ir_capture_mask = 0x0f;\n\n\treturn arm926ejs_init_arch_info(target, arm926ejs, target->tap);\n}\n\nstatic void arm926ejs_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm926ejs);\n}\n\nCOMMAND_HANDLER(arm926ejs_handle_cache_info_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\tretval = arm926ejs_verify_pointer(CMD, arm926ejs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn armv4_5_handle_cache_info_command(CMD, &arm926ejs->armv4_5_mmu.armv4_5_cache);\n}\n\nstatic int arm926ejs_virt2phys(struct target *target, target_addr_t virtual, target_addr_t *physical)\n{\n\tuint32_t cb;\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\tuint32_t ret;\n\tint retval = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu,\n\t\t\tvirtual, &cb, &ret);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t*physical = ret;\n\treturn ERROR_OK;\n}\n\nstatic int arm926ejs_mmu(struct target *target, int *enabled)\n{\n\tstruct arm926ejs_common *arm926ejs = target_to_arm926(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\t*enabled = arm926ejs->armv4_5_mmu.mmu_enabled;\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm926ejs_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cache_info\",\n\t\t.handler = arm926ejs_handle_cache_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"display information about target caches\",\n\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nconst struct command_registration arm926ejs_command_handlers[] = {\n\t{\n\t\t.chain = arm9tdmi_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm926ejs\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm926ejs command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm926ejs_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM926 targets. */\nstruct target_type arm926ejs_target = {\n\t.name = \"arm926ejs\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm926ejs_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm926ejs_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm926ejs_command_handlers,\n\t.target_create = arm926ejs_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = arm926ejs_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n\t.virt2phys = arm926ejs_virt2phys,\n\t.mmu = arm926ejs_mmu,\n\n\t.read_phys_memory = arm926ejs_read_phys_memory,\n\t.write_phys_memory = arm926ejs_write_phys_memory,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm926ejs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM926EJS_H\n#define OPENOCD_TARGET_ARM926EJS_H\n\n#include \"arm9tdmi.h\"\n#include \"armv4_5_mmu.h\"\n\n#define\tARM926EJS_COMMON_MAGIC 0xa926a926U\n\nstruct arm926ejs_common {\n\tunsigned int common_magic;\n\n\tstruct arm7_9_common arm7_9_common;\n\tstruct armv4_5_mmu_common armv4_5_mmu;\n\tint (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2,\n\t\t\tuint32_t crn, uint32_t crm, uint32_t *value);\n\tint (*write_cp15)(struct target *target, uint32_t op1, uint32_t op2,\n\t\t\tuint32_t crn, uint32_t crm, uint32_t value);\n\tuint32_t cp15_control_reg;\n\tuint32_t d_fsr;\n\tuint32_t i_fsr;\n\tuint32_t d_far;\n};\n\nstatic inline struct arm926ejs_common *target_to_arm926(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm926ejs_common, arm7_9_common.arm);\n}\n\nint arm926ejs_init_arch_info(struct target *target,\n\t\tstruct arm926ejs_common *arm926ejs, struct jtag_tap *tap);\nint arm926ejs_arch_state(struct target *target);\nint arm926ejs_write_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\nint arm926ejs_soft_reset_halt(struct target *target);\n\nextern const struct command_registration arm926ejs_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARM926EJS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm946e.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2010 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm946e.h\"\n#include \"target_type.h\"\n#include \"arm_opcodes.h\"\n\n#include \"breakpoints.h\"\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\n#define NB_CACHE_WAYS 4\n\n#define CP15_CTL\t\t0x02\n#define CP15_CTL_DCACHE (1<<2)\n#define CP15_CTL_ICACHE (1<<12)\n\n/**\n * flag to give info about cache manipulation during debug :\n * \"0\"\t-\tcache lines are invalidated \"on the fly\", for affected addresses.\n *\t\t\tThis is preferred from performance point of view.\n * \"1\"\t-\tcache is invalidated and switched off on debug_entry, and switched back on on restore.\n *\t\t\tIt is kept off during debugging.\n */\nstatic uint8_t arm946e_preserve_cache;\n\nstatic int arm946e_post_debug_entry(struct target *target);\nstatic void arm946e_pre_restore_context(struct target *target);\nstatic int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value);\n\nstatic int arm946e_init_arch_info(struct target *target,\n\tstruct arm946e_common *arm946e,\n\tstruct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm946e->arm7_9_common;\n\n\t/* initialize arm7/arm9 specific info (including armv4_5) */\n\tarm9tdmi_init_arch_info(target, arm7_9, tap);\n\n\tarm946e->common_magic = ARM946E_COMMON_MAGIC;\n\n\t/**\n\t * The ARM946E-S implements the ARMv5TE architecture which\n\t * has the BKPT instruction, so we don't have to use a watchpoint comparator\n\t */\n\tarm7_9->arm_bkpt = ARMV5_BKPT(0x0);\n\tarm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;\n\n\n\tarm7_9->post_debug_entry = arm946e_post_debug_entry;\n\tarm7_9->pre_restore_context = arm946e_pre_restore_context;\n\n\t/**\n\t * disabling linefills leads to lockups, so keep them enabled for now\n\t * this doesn't affect correctness, but might affect timing issues, if\n\t * important data is evicted from the cache during the debug session\n\t */\n\tarm946e_preserve_cache = 0;\n\n\t/* override hw single-step capability from ARM9TDMI */\n\t/* arm7_9->has_single_step = 1; */\n\n\treturn ERROR_OK;\n}\n\nstatic int arm946e_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm946e_common *arm946e = calloc(1, sizeof(struct arm946e_common));\n\n\tarm946e_init_arch_info(target, arm946e, target->tap);\n\n\treturn ERROR_OK;\n}\n\nstatic void arm946e_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm946e);\n}\n\nstatic int arm946e_verify_pointer(struct command_invocation *cmd,\n\tstruct arm946e_common *arm946e)\n{\n\tif (arm946e->common_magic != ARM946E_COMMON_MAGIC) {\n\t\tcommand_print(cmd, \"target is not an ARM946\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * Update cp15_control_reg, saved on debug_entry.\n */\nstatic void arm946e_update_cp15_caches(struct target *target, uint32_t value)\n{\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\tarm946e->cp15_control_reg = (arm946e->cp15_control_reg & ~(CP15_CTL_DCACHE|CP15_CTL_ICACHE))\n\t\t| (value & (CP15_CTL_DCACHE|CP15_CTL_ICACHE));\n}\n\n/*\n * REVISIT:  The \"read_cp15\" and \"write_cp15\" commands could hook up\n * to eventual mrc() and mcr() routines ... the reg_addr values being\n * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.\n * See section 7.3 of the ARM946E-S TRM.\n */\nstatic int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct scan_field fields[3];\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 0;\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\t/* REVISIT: table 7-2 shows that bits 31-31 need to be\n\t * specified for accessing BIST registers ...\n\t */\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 6;\n\tfields[1].out_value = &reg_addr_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &nr_w_buf;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\tfields[0].in_value = (uint8_t *)value;\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, *value);\n#endif\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct scan_field fields[3];\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 1;\n\tuint8_t value_buf[4];\n\n\tbuf_set_u32(value_buf, 0, 32, value);\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = value_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 6;\n\tfields[1].out_value = &reg_addr_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &nr_w_buf;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, value);\n#endif\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\n#define GET_ICACHE_SIZE  6\n#define GET_DCACHE_SIZE 18\n\n/*\n * \\param target struct target pointer\n * \\param idsel  select GET_ICACHE_SIZE or GET_DCACHE_SIZE\n * \\returns      cache size, given in bytes\n */\nstatic uint32_t arm946e_cp15_get_csize(struct target *target, int idsel)\n{\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\tuint32_t csize = arm946e->cp15_cache_info;\n\tif (csize == 0) {\n\t\tif (arm946e_read_cp15(target, 0x01, &csize) == ERROR_OK)\n\t\t\tarm946e->cp15_cache_info = csize;\n\t}\n\tif (csize & (1<<(idsel-4)))\t/* cache absent */\n\t\treturn 0;\n\tcsize = (csize >> idsel) & 0x0F;\n\treturn csize ? 1 << (12 + (csize-3)) : 0;\n}\n\nstatic uint32_t arm946e_invalidate_whole_dcache(struct target *target)\n{\n\tuint32_t csize = arm946e_cp15_get_csize(target, GET_DCACHE_SIZE);\n\tif (csize == 0)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* One line (index) is 32 bytes (8 words) long, 4-way assoc\n\t * ARM DDI 0201D, Section 3.3.5\n\t */\n\tint nb_idx = (csize / (4*8*NB_CACHE_WAYS));\t/* gives nb of lines (indexes) in the cache */\n\n\t/* Loop for all segments (i.e. ways) */\n\tuint32_t seg;\n\tfor (seg = 0; seg < NB_CACHE_WAYS; seg++) {\n\t\t/* Loop for all indexes */\n\t\tint idx;\n\t\tfor (idx = 0; idx < nb_idx; idx++) {\n\t\t\t/* Form and write cp15 index (segment + line idx) */\n\t\t\tuint32_t cp15_idx = seg << 30 | idx << 5;\n\t\t\tint retval = arm946e_write_cp15(target, 0x3a, cp15_idx);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR writing index\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Read dtag */\n\t\t\tuint32_t dtag;\n\t\t\tretval = arm946e_read_cp15(target, 0x16, &dtag);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR reading dtag\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Check cache line VALID bit */\n\t\t\tif (!(dtag >> 4 & 0x1))\n\t\t\t\tcontinue;\n\n\t\t\t/* Clean data cache line */\n\t\t\tretval = arm946e_write_cp15(target, 0x35, 0x1);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR cleaning cache line\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Flush data cache line */\n\t\t\tretval = arm946e_write_cp15(target, 0x1a, 0x1);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR flushing cache line\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t arm946e_invalidate_whole_icache(struct target *target)\n{\n\t/* Check cache presence before flushing - avoid undefined behavior */\n\tuint32_t csize = arm946e_cp15_get_csize(target, GET_ICACHE_SIZE);\n\tif (csize == 0)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tLOG_DEBUG(\"FLUSHING I$\");\n\t/**\n\t *  Invalidate (flush) I$\n\t *  mcr\t15, 0, r0, cr7, cr5, {0}\n\t */\n\tint retval = arm946e_write_cp15(target, 0x0f, 0x1);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"ERROR flushing I$\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm946e_post_debug_entry(struct target *target)\n{\n\tuint32_t ctr_reg = 0x0;\n\tuint32_t retval = ERROR_OK;\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\n\t/* See if CACHES are enabled, and save that info\n\t * in the context bits, so that arm946e_pre_restore_context() can use them */\n\tarm946e_read_cp15(target, CP15_CTL, &ctr_reg);\n\n\t/* Save control reg in the context */\n\tarm946e->cp15_control_reg = ctr_reg;\n\n\tif (arm946e_preserve_cache) {\n\t\tif (ctr_reg & CP15_CTL_DCACHE) {\n\t\t\t/* Clean and flush D$ */\n\t\t\tarm946e_invalidate_whole_dcache(target);\n\n\t\t\t/* Disable D$ */\n\t\t\tctr_reg &= ~CP15_CTL_DCACHE;\n\t\t}\n\n\t\tif (ctr_reg & CP15_CTL_ICACHE) {\n\t\t\t/* Flush I$ */\n\t\t\tarm946e_invalidate_whole_icache(target);\n\n\t\t\t/* Disable I$ */\n\t\t\tctr_reg &= ~CP15_CTL_ICACHE;\n\t\t}\n\n\t\t/* Write the new configuration */\n\t\tretval = arm946e_write_cp15(target, CP15_CTL, ctr_reg);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"ERROR disabling cache\");\n\t\t\treturn retval;\n\t\t}\n\t}\t/* if preserve_cache */\n\n\treturn ERROR_OK;\n}\n\nstatic void arm946e_pre_restore_context(struct target *target)\n{\n\tuint32_t ctr_reg = 0x0;\n\tuint32_t retval;\n\n\tif (arm946e_preserve_cache) {\n\t\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\t\t/* Get the contents of the CTR reg */\n\t\tarm946e_read_cp15(target, CP15_CTL, &ctr_reg);\n\n\t\t/**\n\t\t * Read-modify-write CP15 control\n\t\t * to reenable I/D-cache operation\n\t\t * NOTE: It is not possible to disable cache by CP15.\n\t\t * if arm946e_preserve_cache debugging flag enabled.\n\t\t */\n\t\tctr_reg |= arm946e->cp15_control_reg & (CP15_CTL_DCACHE|CP15_CTL_ICACHE);\n\n\t\t/* Write the new configuration */\n\t\tretval = arm946e_write_cp15(target, CP15_CTL, ctr_reg);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_DEBUG(\"ERROR enabling cache\");\n\t}\t/* if preserve_cache */\n}\n\nstatic uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,\n\tuint32_t size, uint32_t count)\n{\n\tuint32_t cur_addr = 0x0;\n\tuint32_t cp15_idx, set, way, dtag;\n\tuint32_t i = 0;\n\tint retval;\n\n\tfor (i = 0; i < count*size; i++) {\n\t\tcur_addr = address + i;\n\n\n\t\tset = (cur_addr >> 5) & 0xff;\t/* set field is 8 bits long */\n\n\t\tfor (way = 0; way < NB_CACHE_WAYS; way++) {\n\t\t\t/**\n\t\t\t * Find if the affected address is kept in the cache.\n\t\t\t * Because JTAG Scan Chain 15 offers limited approach,\n\t\t\t * we have to loop through all cache ways (segments) and\n\t\t\t * read cache tags, then compare them with with address.\n\t\t\t */\n\n\t\t\t/* Form and write cp15 index (segment + line idx) */\n\t\t\tcp15_idx = way << 30 | set << 5;\n\t\t\tretval = arm946e_write_cp15(target, 0x3a, cp15_idx);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR writing index\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Read dtag */\n\t\t\tretval = arm946e_read_cp15(target, 0x16, &dtag);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR reading dtag\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Check cache line VALID bit */\n\t\t\tif (!(dtag >> 4 & 0x1))\n\t\t\t\tcontinue;\n\n\t\t\t/* If line is valid and corresponds to affected address - invalidate it */\n\t\t\tif (dtag >> 5 == cur_addr >> 5) {\n\t\t\t\t/* Clean data cache line */\n\t\t\t\tretval = arm946e_write_cp15(target, 0x35, 0x1);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tLOG_DEBUG(\"ERROR cleaning cache line\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\n\t\t\t\t/* Flush data cache line */\n\t\t\t\tretval = arm946e_write_cp15(target, 0x1c, 0x1);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tLOG_DEBUG(\"ERROR flushing cache line\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\t/* loop through all 4 ways */\n\t}\t/* loop through all addresses */\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address,\n\tuint32_t size, uint32_t count)\n{\n\tuint32_t cur_addr = 0x0;\n\tuint32_t cp15_idx, set, way, itag;\n\tuint32_t i = 0;\n\tint retval;\n\n\tfor (i = 0; i < count*size; i++) {\n\t\tcur_addr = address + i;\n\n\t\tset = (cur_addr >> 5) & 0xff;\t/* set field is 8 bits long */\n\n\t\tfor (way = 0; way < NB_CACHE_WAYS; way++) {\n\t\t\t/* Form and write cp15 index (segment + line idx) */\n\t\t\tcp15_idx = way << 30 | set << 5;\n\t\t\tretval = arm946e_write_cp15(target, 0x3a, cp15_idx);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR writing index\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Read itag */\n\t\t\tretval = arm946e_read_cp15(target, 0x17, &itag);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"ERROR reading itag\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Check cache line VALID bit */\n\t\t\tif (!(itag >> 4 & 0x1))\n\t\t\t\tcontinue;\n\n\t\t\t/* If line is valid and corresponds to affected address - invalidate it */\n\t\t\tif (itag >> 5 == cur_addr >> 5) {\n\t\t\t\t/* Flush I$ line */\n\t\t\t\tretval = arm946e_write_cp15(target, 0x1d, 0x0);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tLOG_DEBUG(\"ERROR flushing cache line\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\t/* way loop */\n\t}\t/* addr loop */\n\n\treturn ERROR_OK;\n}\n\n/** Writes a buffer, in the specified word size, with current MMU settings. */\nstatic int arm946e_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\t/* Invalidate D$ if it is ON */\n\tif (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_DCACHE))\n\t\tarm946e_invalidate_dcache(target, address, size, count);\n\n\t/**\n\t * Write memory\n\t */\n\tretval = arm7_9_write_memory_opt(target, address, size, count, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* *\n\t * Invalidate I$ if it is ON.\n\t *\n\t * D$ has been cleaned and flushed before mem write thus forcing it to behave like write-through,\n\t * because arm7_9_write_memory() has seen non-valid bit in D$\n\t * and wrote data into physical RAM (without touching or allocating the cache line).\n\t * From ARM946ES Technical Reference Manual we can see that it uses \"allocate on read-miss\"\n\t * policy for both I$ and D$ (Chapter 3.2 and 3.3)\n\t *\n\t * Explanation :\n\t * \"ARM system developer's guide: designing and optimizing system software\" by\n\t * Andrew N. Sloss, Dominic Symes and Chris Wright,\n\t * Chapter 12.3.3 Allocating Policy on a Cache Miss :\n\t * A read allocate on cache miss policy allocates a cache line only during a read from main memory.\n\t * If the victim cache line contains valid data, then it is written to main memory before the cache line\n\t * is filled with new data.\n\t * Under this strategy, a write of new data to memory does not update the contents of the cache memory\n\t * unless a cache line was allocated on a previous read from main memory.\n\t * If the cache line contains valid data, then the write updates the cache and may update the main memory if\n\t * the cache write policy is write-through.\n\t * If the data is not in the cache, the controller writes to main memory only.\n\t */\n\tif (!arm946e_preserve_cache && (arm946e->cp15_control_reg & CP15_CTL_ICACHE))\n\t\tarm946e_invalidate_icache(target, address, size, count);\n\n\treturn ERROR_OK;\n\n}\n\nstatic int arm946e_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = arm7_9_read_memory(target, address, size, count, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm946e_handle_cp15)\n{\n\t/* one or two arguments, access a single register (write if second argument is given) */\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\tint retval = arm946e_verify_pointer(CMD, arm946e);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tuint32_t address;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\n\tif (CMD_ARGC == 1) {\n\t\tuint32_t value;\n\t\tretval = arm946e_read_cp15(target, address, &value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"%s cp15 reg %\" PRIu32 \" access failed\", target_name(target), address);\n\t\t\treturn retval;\n\t\t}\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Return value in hex format */\n\t\tcommand_print(CMD, \"0x%08\" PRIx32, value);\n\t} else if (CMD_ARGC == 2) {\n\t\tuint32_t value;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\t\tretval = arm946e_write_cp15(target, address, value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"%s cp15 reg %\" PRIu32 \" access failed\", target_name(target), address);\n\t\t\treturn retval;\n\t\t}\n\t\tif (address == CP15_CTL)\n\t\t\tarm946e_update_cp15_caches(target, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm946e_handle_idcache)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm946e_common *arm946e = target_to_arm946(target);\n\n\tretval = arm946e_verify_pointer(CMD, arm946e);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tbool icache = (strcmp(CMD_NAME, \"icache\") == 0);\n\tuint32_t csize = arm946e_cp15_get_csize(target, icache ? GET_ICACHE_SIZE : GET_DCACHE_SIZE) / 1024;\n\tif (CMD_ARGC == 0) {\n\t\tbool  bena = ((arm946e->cp15_control_reg & (icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE)) != 0)\n\t\t\t  && (arm946e->cp15_control_reg & 0x1);\n\t\tif (csize == 0)\n\t\t\tcommand_print(CMD, \"%s-cache absent\", icache ? \"I\" : \"D\");\n\t\telse\n\t\t\tcommand_print(CMD, \"%s-cache size: %\" PRIu32 \"K, %s\",\n\t\t\t\t      icache ? \"I\" : \"D\", csize, bena ? \"enabled\" : \"disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\tbool flush = false;\n\tbool enable = false;\n\tretval = command_parse_bool_arg(CMD_ARGV[0], &enable);\n\tif (retval == ERROR_COMMAND_SYNTAX_ERROR) {\n\t\tif (strcmp(CMD_ARGV[0], \"flush\") == 0) {\n\t\t\tflush = true;\n\t\t\tretval = ERROR_OK;\n\t\t} else\n\t\t\treturn retval;\n\t}\n\n\t/* Do not invalidate or change state, if cache is absent */\n\tif (csize == 0) {\n\t\tcommand_print(CMD, \"%s-cache absent, '%s' operation undefined\", icache ? \"I\" : \"D\", CMD_ARGV[0]);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* NOTE: flushing entire cache will not preserve lock-down cache regions */\n\tif (icache) {\n\t\tif ((arm946e->cp15_control_reg & CP15_CTL_ICACHE) && !enable)\n\t\t\tretval = arm946e_invalidate_whole_icache(target);\n\t} else {\n\t\tif ((arm946e->cp15_control_reg & CP15_CTL_DCACHE) && !enable)\n\t\t\tretval = arm946e_invalidate_whole_dcache(target);\n\t}\n\n\tif (retval != ERROR_OK || flush)\n\t\treturn retval;\n\n\tuint32_t value;\n\tretval = arm946e_read_cp15(target, CP15_CTL, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t vnew = value;\n\tuint32_t cmask = icache ? CP15_CTL_ICACHE : CP15_CTL_DCACHE;\n\tif (enable) {\n\t\tif ((value & 0x1) == 0)\n\t\t\tLOG_WARNING(\"arm946e: MPU must be enabled for cache to operate\");\n\t\tvnew |= cmask;\n\t} else\n\t\tvnew &= ~cmask;\n\n\tif (vnew == value)\n\t\treturn ERROR_OK;\n\n\tretval = arm946e_write_cp15(target, CP15_CTL, vnew);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm946e_update_cp15_caches(target, vnew);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm946e_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cp15\",\n\t\t.handler = arm946e_handle_cp15,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"regnum [value]\",\n\t\t.help = \"read/modify cp15 register\",\n\t},\n\t{\n\t\t.name = \"icache\",\n\t\t.handler = arm946e_handle_idcache,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['enable'|'disable'|'flush']\",\n\t\t.help = \"I-cache info and operations\",\n\t},\n\t{\n\t\t.name = \"dcache\",\n\t\t.handler = arm946e_handle_idcache,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['enable'|'disable'|'flush']\",\n\t\t.help = \"D-cache info and operations\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm946e_command_handlers[] = {\n\t{\n\t\t.chain = arm9tdmi_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm946e\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm946e command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm946e_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM946 targets. */\nstruct target_type arm946e_target = {\n\t.name = \"arm946e\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm7_9_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t/* .read_memory = arm7_9_read_memory, */\n\t/* .write_memory = arm7_9_write_memory, */\n\t.read_memory = arm946e_read_memory,\n\t.write_memory = arm946e_write_memory,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t/* .add_breakpoint = arm946e_add_breakpoint, */\n\t/* .remove_breakpoint = arm946e_remove_breakpoint, */\n\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm946e_command_handlers,\n\t.target_create = arm946e_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = arm946e_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm946e.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2010 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM946E_H\n#define OPENOCD_TARGET_ARM946E_H\n\n#include \"arm9tdmi.h\"\n\n#define ARM946E_COMMON_MAGIC 0x20f920f9U\n\nstruct arm946e_common {\n\tunsigned int common_magic;\n\n\tstruct arm7_9_common arm7_9_common;\n\tuint32_t cp15_control_reg;\n\tuint32_t cp15_cache_info;\n};\n\nstatic inline struct arm946e_common *target_to_arm946(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm946e_common,\n\t\t\tarm7_9_common.arm);\n}\n\n#endif /* OPENOCD_TARGET_ARM946E_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm966e.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm966e.h\"\n#include \"target_type.h\"\n#include \"arm_opcodes.h\"\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\nint arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm966e->arm7_9_common;\n\n\t/* initialize arm7/arm9 specific info (including armv4_5) */\n\tarm9tdmi_init_arch_info(target, arm7_9, tap);\n\n\tarm966e->common_magic = ARM966E_COMMON_MAGIC;\n\n\t/* The ARM966E-S implements the ARMv5TE architecture which\n\t * has the BKPT instruction, so we don't have to use a watchpoint comparator\n\t */\n\tarm7_9->arm_bkpt = ARMV5_BKPT(0x0);\n\tarm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm966e_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));\n\n\treturn arm966e_init_arch_info(target, arm966e, target->tap);\n}\n\nstatic void arm966e_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm966e_common *arm966e = target_to_arm966(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm966e);\n}\n\nstatic int arm966e_verify_pointer(struct command_invocation *cmd,\n\t\tstruct arm966e_common *arm966e)\n{\n\tif (arm966e->common_magic != ARM966E_COMMON_MAGIC) {\n\t\tcommand_print(cmd, \"target is not an ARM966\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * REVISIT:  The \"read_cp15\" and \"write_cp15\" commands could hook up\n * to eventual mrc() and mcr() routines ... the reg_addr values being\n * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.\n * See section 7.3 of the ARM966E-S TRM.\n */\n\nstatic int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct scan_field fields[3];\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 0;\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\t/* REVISIT: table 7-2 shows that bits 31-31 need to be\n\t * specified for accessing BIST registers ...\n\t */\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 6;\n\tfields[1].out_value = &reg_addr_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &nr_w_buf;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\tfields[1].in_value = (uint8_t *)value;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);\n\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, *value);\n#endif\n\n\treturn ERROR_OK;\n}\n\n/* EXPORTED to str9x (flash) */\nint arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct scan_field fields[3];\n\tuint8_t reg_addr_buf = reg_addr & 0x3f;\n\tuint8_t nr_w_buf = 1;\n\tuint8_t value_buf[4];\n\n\tbuf_set_u32(value_buf, 0, 32, value);\n\n\tretval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = value_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 6;\n\tfields[1].out_value = &reg_addr_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &nr_w_buf;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\tLOG_DEBUG(\"addr: 0x%x value: %8.8x\", reg_addr, value);\n#endif\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm966e_handle_cp15_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm966e_common *arm966e = target_to_arm966(target);\n\n\tretval = arm966e_verify_pointer(CMD, arm966e);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* one or more argument, access a single register (write if second argument is given */\n\tif (CMD_ARGC >= 1) {\n\t\tuint32_t address;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\n\t\tif (CMD_ARGC == 1) {\n\t\t\tuint32_t value;\n\t\t\tretval = arm966e_read_cp15(target, address, &value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access reg %\" PRIu32,\n\t\t\t\t\t\taddress);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tcommand_print(CMD, \"%\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\taddress, value);\n\t\t} else if (CMD_ARGC == 2) {\n\t\t\tuint32_t value;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\t\t\tretval = arm966e_write_cp15(target, address, value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access reg %\" PRIu32,\n\t\t\t\t\t\taddress);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"%\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\taddress, value);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm966e_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cp15\",\n\t\t.handler = arm966e_handle_cp15_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"regnum [value]\",\n\t\t.help = \"display/modify cp15 register\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm966e_command_handlers[] = {\n\t{\n\t\t.chain = arm9tdmi_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm966e\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm966e command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm966e_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM966 targets. */\nstruct target_type arm966e_target = {\n\t.name = \"arm966e\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm7_9_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm966e_command_handlers,\n\t.target_create = arm966e_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = arm966e_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm966e.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM966E_H\n#define OPENOCD_TARGET_ARM966E_H\n\n#include \"arm9tdmi.h\"\n\n#define\tARM966E_COMMON_MAGIC 0x20f920f9U\n\nstruct arm966e_common {\n\tunsigned int common_magic;\n\n\tstruct arm7_9_common arm7_9_common;\n\tuint32_t cp15_control_reg;\n};\n\nstatic inline struct arm966e_common *\ntarget_to_arm966(struct target *target)\n{\n\treturn container_of(target->arch_info, struct arm966e_common,\n\t\t\tarm7_9_common.arm);\n}\n\nint arm966e_init_arch_info(struct target *target,\n\t\tstruct arm966e_common *arm966e, struct jtag_tap *tap);\nint arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value);\n\nextern const struct command_registration arm966e_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARM966E_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm9tdmi.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by Hongtao Zheng                                   *\n *   hontor@126.com                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm9tdmi.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n#include \"arm_semihosting.h\"\n\n/*\n * NOTE:  this holds code that's used with multiple ARM9 processors:\n *  - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores\n *  - ARM9E-S (ARMv5TE) ... in ARM946, ARM966, and ARM968 cores\n *  - ARM9EJS (ARMv5TEJ) ... in ARM926 core\n *\n * In short, the file name is a misnomer ... it is NOT specific to\n * that first generation ARM9 processor, or cores using it.\n */\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\nenum arm9tdmi_vector_bit {\n\tARM9TDMI_RESET_VECTOR = 0x01,\n\tARM9TDMI_UNDEF_VECTOR = 0x02,\n\tARM9TDMI_SWI_VECTOR = 0x04,\n\tARM9TDMI_PABT_VECTOR = 0x08,\n\tARM9TDMI_DABT_VECTOR = 0x10,\n\t/* BIT(5) reserved -- must be zero */\n\tARM9TDMI_IRQ_VECTOR = 0x40,\n\tARM9TDMI_FIQ_VECTOR = 0x80,\n};\n\nstatic const struct arm9tdmi_vector {\n\tconst char *name;\n\tuint32_t value;\n} arm9tdmi_vectors[] = {\n\t{\"reset\", ARM9TDMI_RESET_VECTOR},\n\t{\"undef\", ARM9TDMI_UNDEF_VECTOR},\n\t{\"swi\", ARM9TDMI_SWI_VECTOR},\n\t{\"pabt\", ARM9TDMI_PABT_VECTOR},\n\t{\"dabt\", ARM9TDMI_DABT_VECTOR},\n\t{\"irq\", ARM9TDMI_IRQ_VECTOR},\n\t{\"fiq\", ARM9TDMI_FIQ_VECTOR},\n\t{NULL, 0},\n};\n\nint arm9tdmi_examine_debug_reason(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\t/* only check the debug reason if we don't know it already */\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\t\tstruct scan_field fields[3];\n\t\tuint8_t databus[4];\n\t\tuint8_t instructionbus[4];\n\t\tuint8_t debug_reason;\n\n\t\tfields[0].num_bits = 32;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = databus;\n\n\t\tfields[1].num_bits = 3;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = &debug_reason;\n\n\t\tfields[2].num_bits = 32;\n\t\tfields[2].out_value = NULL;\n\t\tfields[2].in_value = instructionbus;\n\n\t\tretval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = arm_jtag_set_instr(arm7_9->jtag_info.tap, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tjtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfields[0].in_value = NULL;\n\t\tfields[0].out_value = databus;\n\t\tfields[1].in_value = NULL;\n\t\tfields[1].out_value = &debug_reason;\n\t\tfields[2].in_value = NULL;\n\t\tfields[2].out_value = instructionbus;\n\n\t\tjtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);\n\n\t\tif (debug_reason & 0x4)\n\t\t\tif (debug_reason & 0x2)\n\t\t\t\ttarget->debug_reason = DBG_REASON_WPTANDBKPT;\n\t\telse\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\telse\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* put an instruction in the ARM9TDMI pipeline or write the data bus,\n * and optionally read data\n */\nint arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,\n\t\tuint32_t out, uint32_t *in, int sysspeed)\n{\n\tint retval = ERROR_OK;\n\tstruct scan_field fields[3];\n\tuint8_t out_buf[4];\n\tuint8_t instr_buf[4];\n\tuint8_t sysspeed_buf = 0x0;\n\n\t/* prepare buffer */\n\tbuf_set_u32(out_buf, 0, 32, out);\n\n\tbuf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));\n\n\tif (sysspeed)\n\t\tbuf_set_u32(&sysspeed_buf, 2, 1, 1);\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = out_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 3;\n\tfields[1].out_value = &sysspeed_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 32;\n\tfields[2].out_value = instr_buf;\n\tfields[2].in_value = NULL;\n\n\tif (in) {\n\t\tfields[0].in_value = (uint8_t *)in;\n\t\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);\n\n\t\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);\n\t} else\n\t\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\t{\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (in)\n\t\t\tLOG_DEBUG(\"instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x\", instr, out, *in);\n\t\telse\n\t\t\tLOG_DEBUG(\"instr: 0x%8.8x, out: 0x%8.8x\", instr, out);\n\t}\n#endif\n\n\treturn ERROR_OK;\n}\n\n/* just read data (instruction and data-out = don't care) */\nint arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)\n{\n\tint retval = ERROR_OK;\n\tstruct scan_field fields[3];\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = (uint8_t *)in;\n\n\tfields[1].num_bits = 3;\n\tfields[1].out_value = NULL;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 32;\n\tfields[2].out_value = NULL;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);\n\n\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\t{\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (in)\n\t\t\tLOG_DEBUG(\"in: 0x%8.8x\", *in);\n\t\telse\n\t\t\tLOG_ERROR(\"BUG: called with in == NULL\");\n\t}\n#endif\n\n\treturn ERROR_OK;\n}\n\n/* clock the target, and read the databus\n * the *in pointer points to a buffer where elements of 'size' bytes\n * are stored in big (be == 1) or little (be == 0) endianness\n */\nint arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,\n\t\tvoid *in, int size, int be)\n{\n\tint retval = ERROR_OK;\n\tstruct scan_field fields[2];\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 4) {\n\t\tfields[0].num_bits = 32;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = in;\n\n\t\tfields[1].num_bits = 3 + 32;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = NULL;\n\t} else {\n\t\t/* Discard irrelevant bits of the scan, making sure we don't write more\n\t\t * than size bytes to in */\n\t\tfields[0].num_bits = size * 8;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = in;\n\n\t\tfields[1].num_bits = 3 + 32 + 32 - size * 8;\n\t\tfields[1].out_value = NULL;\n\t\tfields[1].in_value = NULL;\n\t}\n\n\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);\n\n\tjtag_add_callback4(arm7_9_endianness_callback,\n\t\t(jtag_callback_data_t)in,\n\t\t(jtag_callback_data_t)size,\n\t\t(jtag_callback_data_t)be,\n\t\t(jtag_callback_data_t)0);\n\n\tjtag_add_runtest(0, TAP_DRPAUSE);\n\n#ifdef _DEBUG_INSTRUCTION_EXECUTION_\n\t{\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (in)\n\t\t\tLOG_DEBUG(\"in: 0x%8.8x\", *(uint32_t *)in);\n\t\telse\n\t\t\tLOG_ERROR(\"BUG: called with in == NULL\");\n\t}\n#endif\n\n\treturn ERROR_OK;\n}\n\nstatic void arm9tdmi_change_to_arm(struct target *target,\n\t\tuint32_t *r0, uint32_t *pc)\n{\n\tint retval = ERROR_OK;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* save r0 before using it and put system in ARM state\n\t * to allow common handling of ARM and THUMB debugging */\n\n\t/* fetch STR r0, [r0] */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* STR r0, [r0] in Memory */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);\n\n\t/* MOV r0, r15 fetched, STR in Decode */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* nothing fetched, STR r0, [r0] in Memory */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);\n\n\t/* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);\n\t/* LDR in Decode */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* LDR in Execute */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* LDR in Memory (to account for interlock) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\t/* fetch BX */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);\n\t/* NOP fetched, BX in Decode, MOV in Execute */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* NOP fetched, BX in Execute (1) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn;\n\n\t/* fix program counter:\n\t * MOV r0, r15 was the 5th instruction (+8)\n\t * reading PC in Thumb state gives address of instruction + 4\n\t */\n\t*pc -= 0xc;\n}\n\nvoid arm9tdmi_read_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t *core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, STM in MEMORY (i'th cycle) */\n\t\t\tarm9tdmi_clock_data_in(jtag_info, core_regs[i]);\n\t}\n}\n\nstatic void arm9tdmi_read_core_regs_target_buffer(struct target *target,\n\t\tuint32_t mask, void *buffer, int size)\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;\n\tuint32_t *buf_u32 = buffer;\n\tuint16_t *buf_u16 = buffer;\n\tuint8_t *buf_u8 = buffer;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, STM in MEMORY (i'th cycle) */\n\t\t\tswitch (size) {\n\t\t\t\tcase 4:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t}\n}\n\nstatic void arm9tdmi_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* MRS r0, cpsr */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* STR r0, [r15] */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);\n\t/* fetch NOP, STR in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STR in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, STR in MEMORY */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);\n}\n\nstatic void arm9tdmi_write_xpsr(struct target *target, uint32_t xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr: %8.8\" PRIx32 \", spsr: %i\", xpsr, spsr);\n\n\t/* MSR1 fetched */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);\n\t/* MSR2 fetched, MSR1 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);\n\t/* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);\n\t/* nothing fetched, MSR1 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR1 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);\n\t/* nothing fetched, MSR2 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR2 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR3 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR3 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR4 in EXECUTE (1) */\n\t/* last MSR writes flags, which takes only one cycle */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void arm9tdmi_write_xpsr_im8(struct target *target,\n\t\tuint8_t xpsr_im, int rot, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr_im: %2.2x, rot: %i, spsr: %i\", xpsr_im, rot, spsr);\n\n\t/* MSR fetched */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);\n\t/* NOP fetched, MSR in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR in EXECUTE (1) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* rot == 4 writes flags, which takes only one cycle */\n\tif (rot != 4) {\n\t\t/* nothing fetched, MSR in EXECUTE (2) */\n\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t\t/* nothing fetched, MSR in EXECUTE (3) */\n\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t}\n}\n\nvoid arm9tdmi_write_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t* register values will start to appear on 4th DCLK\n\t*/\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */\n\t\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);\n\t}\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nvoid arm9tdmi_load_word_regs(struct target *target, uint32_t mask)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load-multiple into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nvoid arm9tdmi_load_hword_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load half-word into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nvoid arm9tdmi_load_byte_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed load byte into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nvoid arm9tdmi_store_word_regs(struct target *target, uint32_t mask)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store-multiple into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nvoid arm9tdmi_store_hword_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store half-word into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nvoid arm9tdmi_store_byte_reg(struct target *target, int num)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* put system-speed store byte into the pipeline */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nstatic void arm9tdmi_write_pc(struct target *target, uint32_t pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (4th cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (5th cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nvoid arm9tdmi_branch_resume(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n}\n\nstatic void arm9tdmi_branch_resume_thumb(struct target *target)\n{\n\tLOG_DEBUG(\"-\");\n\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm *arm = &arm7_9->arm;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tstruct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t* register values will start to appear on 4th DCLK\n\t*/\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (2nd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP,\n\t\t\tbuf_get_u32(arm->pc->value, 0, 32) | 1, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* Branch and eXchange */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);\n\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* fetch NOP, BX in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* fetch NOP, BX in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* target is now in Thumb state */\n\tembeddedice_read_reg(dbg_stat);\n\n\t/* load r0 value, MOV_IM in Decode*/\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);\n\t/* fetch NOP, LDR in Decode, MOV_IM in Execute */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDR in Execute */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\t/* nothing fetched, LDR in EXECUTE stage (2nd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP,\n\t\t\tbuf_get_u32(arm->core_cache->reg_list[0].value, 0, 32), NULL, 0);\n\t/* nothing fetched, LDR in EXECUTE stage (3rd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tembeddedice_read_reg(dbg_stat);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n}\n\nvoid arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (arm7_9->has_single_step) {\n\t\tbuf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);\n\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);\n\t} else\n\t\tarm7_9_enable_eice_step(target, next_pc);\n}\n\nvoid arm9tdmi_disable_single_step(struct target *target)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tif (arm7_9->has_single_step) {\n\t\tbuf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);\n\t\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);\n\t} else\n\t\tarm7_9_disable_eice_step(target);\n}\n\nstatic void arm9tdmi_build_reg_cache(struct target *target)\n{\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct arm *arm = target_to_arm(target);\n\n\t(*cache_p) = arm_build_reg_cache(target, arm);\n}\n\nint arm9tdmi_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tarm9tdmi_build_reg_cache(target);\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nint arm9tdmi_init_arch_info(struct target *target,\n\t\tstruct arm7_9_common *arm7_9, struct jtag_tap *tap)\n{\n\t/* prepare JTAG information for the new target */\n\tarm7_9->jtag_info.tap = tap;\n\tarm7_9->jtag_info.scann_size = 5;\n\n\t/* register arch-specific functions */\n\tarm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;\n\tarm7_9->change_to_arm = arm9tdmi_change_to_arm;\n\tarm7_9->read_core_regs = arm9tdmi_read_core_regs;\n\tarm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;\n\tarm7_9->read_xpsr = arm9tdmi_read_xpsr;\n\n\tarm7_9->write_xpsr = arm9tdmi_write_xpsr;\n\tarm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;\n\tarm7_9->write_core_regs = arm9tdmi_write_core_regs;\n\n\tarm7_9->load_word_regs = arm9tdmi_load_word_regs;\n\tarm7_9->load_hword_reg = arm9tdmi_load_hword_reg;\n\tarm7_9->load_byte_reg = arm9tdmi_load_byte_reg;\n\n\tarm7_9->store_word_regs = arm9tdmi_store_word_regs;\n\tarm7_9->store_hword_reg = arm9tdmi_store_hword_reg;\n\tarm7_9->store_byte_reg = arm9tdmi_store_byte_reg;\n\n\tarm7_9->write_pc = arm9tdmi_write_pc;\n\tarm7_9->branch_resume = arm9tdmi_branch_resume;\n\tarm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;\n\n\tarm7_9->enable_single_step = arm9tdmi_enable_single_step;\n\tarm7_9->disable_single_step = arm9tdmi_disable_single_step;\n\n\tarm7_9->write_memory = arm7_9_write_memory;\n\tarm7_9->bulk_write_memory = arm7_9_bulk_write_memory;\n\n\tarm7_9->post_debug_entry = NULL;\n\n\tarm7_9->pre_restore_context = NULL;\n\n\t/* initialize arch-specific breakpoint handling */\n\tarm7_9->arm_bkpt = 0xdeeedeee;\n\tarm7_9->thumb_bkpt = 0xdeee;\n\n\tarm7_9->dbgreq_adjust_pc = 3;\n\n\tarm7_9_init_arch_info(target, arm7_9);\n\n\t/* override use of DBGRQ, this is safe on ARM9TDMI */\n\tarm7_9->use_dbgrq = 1;\n\n\t/* all ARM9s have the vector catch register */\n\tarm7_9->has_vector_catch = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int arm9tdmi_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common));\n\n\tarm9tdmi_init_arch_info(target, arm7_9, target->tap);\n\tarm7_9->arm.arch = ARM_ARCH_V4;\n\n\treturn ERROR_OK;\n}\n\nvoid arm9tdmi_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm7_9);\n}\n\nCOMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct reg *vector_catch;\n\tuint32_t vector_catch_value;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* it's uncommon, but some ARM7 chips can support this */\n\tif (arm7_9->common_magic != ARM7_9_COMMON_MAGIC\n\t\t\t|| !arm7_9->has_vector_catch) {\n\t\tcommand_print(CMD, \"target doesn't have EmbeddedICE \"\n\t\t\t\t\"with vector_catch\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tvector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];\n\n\t/* read the vector catch register if necessary */\n\tif (!vector_catch->valid)\n\t\tembeddedice_read_reg(vector_catch);\n\n\t/* get the current setting */\n\tvector_catch_value = buf_get_u32(vector_catch->value, 0, 8);\n\n\tif (CMD_ARGC > 0) {\n\t\tvector_catch_value = 0x0;\n\t\tif (strcmp(CMD_ARGV[0], \"all\") == 0)\n\t\t\tvector_catch_value = 0xdf;\n\t\telse if (strcmp(CMD_ARGV[0], \"none\") == 0) {\n\t\t\t/* do nothing */\n\t\t} else {\n\t\t\tfor (unsigned i = 0; i < CMD_ARGC; i++) {\n\t\t\t\t/* go through list of vectors */\n\t\t\t\tunsigned j;\n\t\t\t\tfor (j = 0; arm9tdmi_vectors[j].name; j++) {\n\t\t\t\t\tif (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) {\n\t\t\t\t\t\tvector_catch_value |= arm9tdmi_vectors[j].value;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* complain if vector wasn't found */\n\t\t\t\tif (!arm9tdmi_vectors[j].name) {\n\t\t\t\t\tcommand_print(CMD, \"vector '%s' not found, leaving current setting unchanged\", CMD_ARGV[i]);\n\n\t\t\t\t\t/* reread current setting */\n\t\t\t\t\tvector_catch_value = buf_get_u32(\n\t\t\t\t\t\t\tvector_catch->value,\n\t\t\t\t\t\t\t0, 8);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* store new settings */\n\t\tbuf_set_u32(vector_catch->value, 0, 8, vector_catch_value);\n\t\tembeddedice_store_reg(vector_catch);\n\t}\n\n\t/* output current settings */\n\tfor (unsigned i = 0; arm9tdmi_vectors[i].name; i++) {\n\t\tcommand_print(CMD, \"%s: %s\", arm9tdmi_vectors[i].name,\n\t\t\t(vector_catch_value & arm9tdmi_vectors[i].value)\n\t\t\t\t? \"catch\" : \"don't catch\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm9tdmi_exec_command_handlers[] = {\n\t{\n\t\t.name = \"vector_catch\",\n\t\t.handler = handle_arm9tdmi_catch_vectors_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Display, after optionally updating, configuration \"\n\t\t\t\"of vector catch unit.\",\n\t\t.usage = \"[all|none|(reset|undef|swi|pabt|dabt|irq|fiq)*]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nconst struct command_registration arm9tdmi_command_handlers[] = {\n\t{\n\t\t.chain = arm7_9_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm9\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"arm9 command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm9tdmi_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for ARM9TDMI targets. */\nstruct target_type arm9tdmi_target = {\n\t.name = \"arm9tdmi\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm7_9_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm9tdmi_command_handlers,\n\t.target_create = arm9tdmi_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = arm9tdmi_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm9tdmi.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM9TDMI_H\n#define OPENOCD_TARGET_ARM9TDMI_H\n\n#include \"embeddedice.h\"\n\nint arm9tdmi_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target);\nvoid arm9tdmi_deinit_target(struct target *target);\nint arm9tdmi_init_arch_info(struct target *target,\n\t\tstruct arm7_9_common *arm7_9, struct jtag_tap *tap);\nextern const struct command_registration arm9tdmi_command_handlers[];\n\nint arm9tdmi_clock_out(struct arm_jtag *jtag_info,\n\t\tuint32_t instr, uint32_t out, uint32_t *in, int sysspeed);\nint arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in);\nint arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,\n\t\tvoid *in, int size, int be);\nvoid arm9tdmi_read_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t *core_regs[16]);\nvoid arm9tdmi_write_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t core_regs[16]);\n\nint arm9tdmi_examine_debug_reason(struct target *target);\n\nvoid arm9tdmi_load_word_regs(struct target *target, uint32_t mask);\nvoid arm9tdmi_load_hword_reg(struct target *target, int num);\nvoid arm9tdmi_load_byte_reg(struct target *target, int num);\nvoid arm9tdmi_store_word_regs(struct target *target, uint32_t mask);\nvoid arm9tdmi_store_hword_reg(struct target *target, int num);\nvoid arm9tdmi_store_byte_reg(struct target *target, int num);\n\nvoid arm9tdmi_branch_resume(struct target *target);\nvoid arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc);\nvoid arm9tdmi_disable_single_step(struct target *target);\n\n#endif /* OPENOCD_TARGET_ARM9TDMI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_adi_v5.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2009-2010 by Oyvind Harboe                              *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009-2010 by David Brownell                             *\n *                                                                         *\n *   Copyright (C) 2013 by Andreas Fritiofson                              *\n *   andreas.fritiofson@gmail.com                                          *\n *                                                                         *\n *   Copyright (C) 2019-2021, Ampere Computing LLC                         *\n ***************************************************************************/\n\n/**\n * @file\n * This file implements support for the ARM Debug Interface version 5 (ADIv5)\n * debugging architecture.  Compared with previous versions, this includes\n * a low pin-count Serial Wire Debug (SWD) alternative to JTAG for message\n * transport, and focuses on memory mapped resources as defined by the\n * CoreSight architecture.\n *\n * A key concept in ADIv5 is the Debug Access Port, or DAP.  A DAP has two\n * basic components:  a Debug Port (DP) transporting messages to and from a\n * debugger, and an Access Port (AP) accessing resources.  Three types of DP\n * are defined.  One uses only JTAG for communication, and is called JTAG-DP.\n * One uses only SWD for communication, and is called SW-DP.  The third can\n * use either SWD or JTAG, and is called SWJ-DP.  The most common type of AP\n * is used to access memory mapped resources and is called a MEM-AP.  Also a\n * JTAG-AP is also defined, bridging to JTAG resources; those are uncommon.\n *\n * This programming interface allows DAP pipelined operations through a\n * transaction queue.  This primarily affects AP operations (such as using\n * a MEM-AP to access memory or registers).  If the current transaction has\n * not finished by the time the next one must begin, and the ORUNDETECT bit\n * is set in the DP_CTRL_STAT register, the SSTICKYORUN status is set and\n * further AP operations will fail.  There are two basic methods to avoid\n * such overrun errors.  One involves polling for status instead of using\n * transaction pipelining.  The other involves adding delays to ensure the\n * AP has enough time to complete one operation before starting the next\n * one.  (For JTAG these delays are controlled by memaccess_tck.)\n */\n\n/*\n * Relevant specifications from ARM include:\n *\n * ARM(tm) Debug Interface v5 Architecture Specification    ARM IHI 0031E\n * CoreSight(tm) v1.0 Architecture Specification            ARM IHI 0029B\n *\n * CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D\n * Cortex-M3(tm) TRM, ARM DDI 0337G\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"arm.h\"\n#include \"arm_adi_v5.h\"\n#include \"arm_coresight.h\"\n#include \"jtag/swd.h\"\n#include \"transport/transport.h\"\n#include <helper/align.h>\n#include <helper/jep106.h>\n#include <helper/time_support.h>\n#include <helper/list.h>\n#include <helper/jim-nvp.h>\n\n/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement  */\n\n/*\n\tuint32_t tar_block_size(uint32_t address)\n\tReturn the largest block starting at address that does not cross a tar block size alignment boundary\n*/\nstatic uint32_t max_tar_block_size(uint32_t tar_autoincr_block, target_addr_t address)\n{\n\treturn tar_autoincr_block - ((tar_autoincr_block - 1) & address);\n}\n\n/***************************************************************************\n *                                                                         *\n * DP and MEM-AP  register access  through APACC and DPACC                 *\n *                                                                         *\n***************************************************************************/\n\nstatic int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw)\n{\n\tcsw |= ap->csw_default;\n\n\tif (csw != ap->csw_value) {\n\t\t/* LOG_DEBUG(\"DAP: Set CSW %x\",csw); */\n\t\tint retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW(ap->dap), csw);\n\t\tif (retval != ERROR_OK) {\n\t\t\tap->csw_value = 0;\n\t\t\treturn retval;\n\t\t}\n\t\tap->csw_value = csw;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_setup_tar(struct adiv5_ap *ap, target_addr_t tar)\n{\n\tif (!ap->tar_valid || tar != ap->tar_value) {\n\t\t/* LOG_DEBUG(\"DAP: Set TAR %x\",tar); */\n\t\tint retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR(ap->dap), (uint32_t)(tar & 0xffffffffUL));\n\t\tif (retval == ERROR_OK && is_64bit_ap(ap)) {\n\t\t\t/* See if bits 63:32 of tar is different from last setting */\n\t\t\tif (!ap->tar_valid || (ap->tar_value >> 32) != (tar >> 32))\n\t\t\t\tretval = dap_queue_ap_write(ap, MEM_AP_REG_TAR64(ap->dap), (uint32_t)(tar >> 32));\n\t\t}\n\t\tif (retval != ERROR_OK) {\n\t\t\tap->tar_valid = false;\n\t\t\treturn retval;\n\t\t}\n\t\tap->tar_value = tar;\n\t\tap->tar_valid = true;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_read_tar(struct adiv5_ap *ap, target_addr_t *tar)\n{\n\tuint32_t lower;\n\tuint32_t upper = 0;\n\n\tint retval = dap_queue_ap_read(ap, MEM_AP_REG_TAR(ap->dap), &lower);\n\tif (retval == ERROR_OK && is_64bit_ap(ap))\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_TAR64(ap->dap), &upper);\n\n\tif (retval != ERROR_OK) {\n\t\tap->tar_valid = false;\n\t\treturn retval;\n\t}\n\n\tretval = dap_run(ap->dap);\n\tif (retval != ERROR_OK) {\n\t\tap->tar_valid = false;\n\t\treturn retval;\n\t}\n\n\t*tar = (((target_addr_t)upper) << 32) | (target_addr_t)lower;\n\n\tap->tar_value = *tar;\n\tap->tar_valid = true;\n\treturn ERROR_OK;\n}\n\nstatic uint32_t mem_ap_get_tar_increment(struct adiv5_ap *ap)\n{\n\tswitch (ap->csw_value & CSW_ADDRINC_MASK) {\n\tcase CSW_ADDRINC_SINGLE:\n\t\tswitch (ap->csw_value & CSW_SIZE_MASK) {\n\t\tcase CSW_8BIT:\n\t\t\treturn 1;\n\t\tcase CSW_16BIT:\n\t\t\treturn 2;\n\t\tcase CSW_32BIT:\n\t\t\treturn 4;\n\t\tdefault:\n\t\t\treturn 0;\n\t\t}\n\tcase CSW_ADDRINC_PACKED:\n\t\treturn 4;\n\t}\n\treturn 0;\n}\n\n/* mem_ap_update_tar_cache is called after an access to MEM_AP_REG_DRW\n */\nstatic void mem_ap_update_tar_cache(struct adiv5_ap *ap)\n{\n\tif (!ap->tar_valid)\n\t\treturn;\n\n\tuint32_t inc = mem_ap_get_tar_increment(ap);\n\tif (inc >= max_tar_block_size(ap->tar_autoincr_block, ap->tar_value))\n\t\tap->tar_valid = false;\n\telse\n\t\tap->tar_value += inc;\n}\n\n/**\n * Queue transactions setting up transfer parameters for the\n * currently selected MEM-AP.\n *\n * Subsequent transfers using registers like MEM_AP_REG_DRW or MEM_AP_REG_BD2\n * initiate data reads or writes using memory or peripheral addresses.\n * If the CSW is configured for it, the TAR may be automatically\n * incremented after each transfer.\n *\n * @param ap The MEM-AP.\n * @param csw MEM-AP Control/Status Word (CSW) register to assign.  If this\n *\tmatches the cached value, the register is not changed.\n * @param tar MEM-AP Transfer Address Register (TAR) to assign.  If this\n *\tmatches the cached address, the register is not changed.\n *\n * @return ERROR_OK if the transaction was properly queued, else a fault code.\n */\nstatic int mem_ap_setup_transfer(struct adiv5_ap *ap, uint32_t csw, target_addr_t tar)\n{\n\tint retval;\n\tretval = mem_ap_setup_csw(ap, csw);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mem_ap_setup_tar(ap, tar);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn ERROR_OK;\n}\n\n/**\n * Asynchronous (queued) read of a word from memory or a system register.\n *\n * @param ap The MEM-AP to access.\n * @param address Address of the 32-bit word to read; it must be\n *\treadable by the currently selected MEM-AP.\n * @param value points to where the word will be stored when the\n *\ttransaction queue is flushed (assuming no errors).\n *\n * @return ERROR_OK for success.  Otherwise a fault code.\n */\nint mem_ap_read_u32(struct adiv5_ap *ap, target_addr_t address,\n\t\tuint32_t *value)\n{\n\tint retval;\n\n\t/* Use banked addressing (REG_BDx) to avoid some link traffic\n\t * (updating TAR) when reading several consecutive addresses.\n\t */\n\tretval = mem_ap_setup_transfer(ap,\n\t\t\tCSW_32BIT | (ap->csw_value & CSW_ADDRINC_MASK),\n\t\t\taddress & 0xFFFFFFFFFFFFFFF0ull);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dap_queue_ap_read(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC), value);\n}\n\n/**\n * Synchronous read of a word from memory or a system register.\n * As a side effect, this flushes any queued transactions.\n *\n * @param ap The MEM-AP to access.\n * @param address Address of the 32-bit word to read; it must be\n *\treadable by the currently selected MEM-AP.\n * @param value points to where the result will be stored.\n *\n * @return ERROR_OK for success; *value holds the result.\n * Otherwise a fault code.\n */\nint mem_ap_read_atomic_u32(struct adiv5_ap *ap, target_addr_t address,\n\t\tuint32_t *value)\n{\n\tint retval;\n\n\tretval = mem_ap_read_u32(ap, address, value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dap_run(ap->dap);\n}\n\n/**\n * Asynchronous (queued) write of a word to memory or a system register.\n *\n * @param ap The MEM-AP to access.\n * @param address Address to be written; it must be writable by\n *\tthe currently selected MEM-AP.\n * @param value Word that will be written to the address when transaction\n *\tqueue is flushed (assuming no errors).\n *\n * @return ERROR_OK for success.  Otherwise a fault code.\n */\nint mem_ap_write_u32(struct adiv5_ap *ap, target_addr_t address,\n\t\tuint32_t value)\n{\n\tint retval;\n\n\t/* Use banked addressing (REG_BDx) to avoid some link traffic\n\t * (updating TAR) when writing several consecutive addresses.\n\t */\n\tretval = mem_ap_setup_transfer(ap,\n\t\t\tCSW_32BIT | (ap->csw_value & CSW_ADDRINC_MASK),\n\t\t\taddress & 0xFFFFFFFFFFFFFFF0ull);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dap_queue_ap_write(ap, MEM_AP_REG_BD0(ap->dap) | (address & 0xC),\n\t\t\tvalue);\n}\n\n/**\n * Synchronous write of a word to memory or a system register.\n * As a side effect, this flushes any queued transactions.\n *\n * @param ap The MEM-AP to access.\n * @param address Address to be written; it must be writable by\n *\tthe currently selected MEM-AP.\n * @param value Word that will be written.\n *\n * @return ERROR_OK for success; the data was written.  Otherwise a fault code.\n */\nint mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address,\n\t\tuint32_t value)\n{\n\tint retval = mem_ap_write_u32(ap, address, value);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dap_run(ap->dap);\n}\n\n/**\n * Synchronous write of a block of memory, using a specific access size.\n *\n * @param ap The MEM-AP to access.\n * @param buffer The data buffer to write. No particular alignment is assumed.\n * @param size Which access size to use, in bytes. 1, 2 or 4.\n * @param count The number of writes to do (in size units, not bytes).\n * @param address Address to be written; it must be writable by the currently selected MEM-AP.\n * @param addrinc Whether the target address should be increased for each write or not. This\n *  should normally be true, except when writing to e.g. a FIFO.\n * @return ERROR_OK on success, otherwise an error code.\n */\nstatic int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t size, uint32_t count,\n\t\ttarget_addr_t address, bool addrinc)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tsize_t nbytes = size * count;\n\tconst uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;\n\tuint32_t csw_size;\n\ttarget_addr_t addr_xor;\n\tint retval = ERROR_OK;\n\n\t/* TI BE-32 Quirks mode:\n\t * Writes on big-endian TMS570 behave very strangely. Observed behavior:\n\t *   size   write address   bytes written in order\n\t *   4      TAR ^ 0         (val >> 24), (val >> 16), (val >> 8), (val)\n\t *   2      TAR ^ 2         (val >> 8), (val)\n\t *   1      TAR ^ 3         (val)\n\t * For example, if you attempt to write a single byte to address 0, the processor\n\t * will actually write a byte to address 3.\n\t *\n\t * To make writes of size < 4 work as expected, we xor a value with the address before\n\t * setting the TAP, and we set the TAP after every transfer rather then relying on\n\t * address increment. */\n\n\tif (size == 4) {\n\t\tcsw_size = CSW_32BIT;\n\t\taddr_xor = 0;\n\t} else if (size == 2) {\n\t\tcsw_size = CSW_16BIT;\n\t\taddr_xor = dap->ti_be_32_quirks ? 2 : 0;\n\t} else if (size == 1) {\n\t\tcsw_size = CSW_8BIT;\n\t\taddr_xor = dap->ti_be_32_quirks ? 3 : 0;\n\t} else {\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tif (ap->unaligned_access_bad && (address % size != 0))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\twhile (nbytes > 0) {\n\t\tuint32_t this_size = size;\n\n\t\t/* Select packed transfer if possible */\n\t\tif (addrinc && ap->packed_transfers && nbytes >= 4\n\t\t\t\t&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {\n\t\t\tthis_size = 4;\n\t\t\tretval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);\n\t\t} else {\n\t\t\tretval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = mem_ap_setup_tar(ap, address ^ addr_xor);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* How many source bytes each transfer will consume, and their location in the DRW,\n\t\t * depends on the type of transfer and alignment. See ARM document IHI0031C. */\n\t\tuint32_t outvalue = 0;\n\t\tuint32_t drw_byte_idx = address;\n\t\tif (dap->ti_be_32_quirks) {\n\t\t\tswitch (this_size) {\n\t\t\tcase 4:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx++ & 3) ^ addr_xor);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (drw_byte_idx & 3) ^ addr_xor);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx++ & 3) ^ addr_xor);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (drw_byte_idx & 3) ^ addr_xor);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else if (dap->nu_npcx_quirks) {\n\t\t\tswitch (this_size) {\n\t\t\tcase 4:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\toutvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*(buffer+1) << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\toutvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);\n\t\t\t}\n\t\t} else {\n\t\t\tswitch (this_size) {\n\t\t\tcase 4:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\t/* fallthrough */\n\t\t\tcase 2:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);\n\t\t\t\t/* fallthrough */\n\t\t\tcase 1:\n\t\t\t\toutvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);\n\t\t\t}\n\t\t}\n\n\t\tnbytes -= this_size;\n\n\t\tretval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tmem_ap_update_tar_cache(ap);\n\t\tif (addrinc)\n\t\t\taddress += this_size;\n\t}\n\n\t/* REVISIT: Might want to have a queued version of this function that does not run. */\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(dap);\n\n\tif (retval != ERROR_OK) {\n\t\ttarget_addr_t tar;\n\t\tif (mem_ap_read_tar(ap, &tar) == ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to write memory at \" TARGET_ADDR_FMT, tar);\n\t\telse\n\t\t\tLOG_ERROR(\"Failed to write memory and, additionally, failed to find out where\");\n\t}\n\n\treturn retval;\n}\n\n/**\n * Synchronous read of a block of memory, using a specific access size.\n *\n * @param ap The MEM-AP to access.\n * @param buffer The data buffer to receive the data. No particular alignment is assumed.\n * @param size Which access size to use, in bytes. 1, 2 or 4.\n * @param count The number of reads to do (in size units, not bytes).\n * @param adr Address to be read; it must be readable by the currently selected MEM-AP.\n * @param addrinc Whether the target address should be increased after each read or not. This\n *  should normally be true, except when reading from e.g. a FIFO.\n * @return ERROR_OK on success, otherwise an error code.\n */\nstatic int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint32_t count,\n\t\ttarget_addr_t adr, bool addrinc)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tsize_t nbytes = size * count;\n\tconst uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;\n\tuint32_t csw_size;\n\ttarget_addr_t address = adr;\n\tint retval = ERROR_OK;\n\n\t/* TI BE-32 Quirks mode:\n\t * Reads on big-endian TMS570 behave strangely differently than writes.\n\t * They read from the physical address requested, but with DRW byte-reversed.\n\t * For example, a byte read from address 0 will place the result in the high bytes of DRW.\n\t * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,\n\t * so avoid them. */\n\n\tif (size == 4)\n\t\tcsw_size = CSW_32BIT;\n\telse if (size == 2)\n\t\tcsw_size = CSW_16BIT;\n\telse if (size == 1)\n\t\tcsw_size = CSW_8BIT;\n\telse\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (ap->unaligned_access_bad && (adr % size != 0))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant\n\t * over-allocation if packed transfers are going to be used, but determining the real need at\n\t * this point would be messy. */\n\tuint32_t *read_buf = calloc(count, sizeof(uint32_t));\n\t/* Multiplication count * sizeof(uint32_t) may overflow, calloc() is safe */\n\tuint32_t *read_ptr = read_buf;\n\tif (!read_buf) {\n\t\tLOG_ERROR(\"Failed to allocate read buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many\n\t * useful bytes it contains, and their location in the word, depends on the type of transfer\n\t * and alignment. */\n\twhile (nbytes > 0) {\n\t\tuint32_t this_size = size;\n\n\t\t/* Select packed transfer if possible */\n\t\tif (addrinc && ap->packed_transfers && nbytes >= 4\n\t\t\t\t&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {\n\t\t\tthis_size = 4;\n\t\t\tretval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);\n\t\t} else {\n\t\t\tretval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = mem_ap_setup_tar(ap, address);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tnbytes -= this_size;\n\t\tif (addrinc)\n\t\t\taddress += this_size;\n\n\t\tmem_ap_update_tar_cache(ap);\n\t}\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(dap);\n\n\t/* Restore state */\n\taddress = adr;\n\tnbytes = size * count;\n\tread_ptr = read_buf;\n\n\t/* If something failed, read TAR to find out how much data was successfully read, so we can\n\t * at least give the caller what we have. */\n\tif (retval != ERROR_OK) {\n\t\ttarget_addr_t tar;\n\t\tif (mem_ap_read_tar(ap, &tar) == ERROR_OK) {\n\t\t\t/* TAR is incremented after failed transfer on some devices (eg Cortex-M4) */\n\t\t\tLOG_ERROR(\"Failed to read memory at \" TARGET_ADDR_FMT, tar);\n\t\t\tif (nbytes > tar - address)\n\t\t\t\tnbytes = tar - address;\n\t\t} else {\n\t\t\tLOG_ERROR(\"Failed to read memory and, additionally, failed to find out where\");\n\t\t\tnbytes = 0;\n\t\t}\n\t}\n\n\t/* Replay loop to populate caller's buffer from the correct word and byte lane */\n\twhile (nbytes > 0) {\n\t\tuint32_t this_size = size;\n\n\t\tif (addrinc && ap->packed_transfers && nbytes >= 4\n\t\t\t\t&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {\n\t\t\tthis_size = 4;\n\t\t}\n\n\t\tif (dap->ti_be_32_quirks) {\n\t\t\tswitch (this_size) {\n\t\t\tcase 4:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));\n\t\t\t\t/* fallthrough */\n\t\t\tcase 2:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));\n\t\t\t\t/* fallthrough */\n\t\t\tcase 1:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));\n\t\t\t}\n\t\t} else {\n\t\t\tswitch (this_size) {\n\t\t\tcase 4:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (address++ & 3);\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (address++ & 3);\n\t\t\t\t/* fallthrough */\n\t\t\tcase 2:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (address++ & 3);\n\t\t\t\t/* fallthrough */\n\t\t\tcase 1:\n\t\t\t\t*buffer++ = *read_ptr >> 8 * (address++ & 3);\n\t\t\t}\n\t\t}\n\n\t\tread_ptr++;\n\t\tnbytes -= this_size;\n\t}\n\n\tfree(read_buf);\n\treturn retval;\n}\n\nint mem_ap_read_buf(struct adiv5_ap *ap,\n\t\tuint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)\n{\n\treturn mem_ap_read(ap, buffer, size, count, address, true);\n}\n\nint mem_ap_write_buf(struct adiv5_ap *ap,\n\t\tconst uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)\n{\n\treturn mem_ap_write(ap, buffer, size, count, address, true);\n}\n\nint mem_ap_read_buf_noincr(struct adiv5_ap *ap,\n\t\tuint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)\n{\n\treturn mem_ap_read(ap, buffer, size, count, address, false);\n}\n\nint mem_ap_write_buf_noincr(struct adiv5_ap *ap,\n\t\tconst uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address)\n{\n\treturn mem_ap_write(ap, buffer, size, count, address, false);\n}\n\n/*--------------------------------------------------------------------------*/\n\n\n#define DAP_POWER_DOMAIN_TIMEOUT (10)\n\n/*--------------------------------------------------------------------------*/\n\n/**\n * Invalidate cached DP select and cached TAR and CSW of all APs\n */\nvoid dap_invalidate_cache(struct adiv5_dap *dap)\n{\n\tdap->select = DP_SELECT_INVALID;\n\tdap->last_read = NULL;\n\n\tint i;\n\tfor (i = 0; i <= DP_APSEL_MAX; i++) {\n\t\t/* force csw and tar write on the next mem-ap access */\n\t\tdap->ap[i].tar_valid = false;\n\t\tdap->ap[i].csw_value = 0;\n\t}\n}\n\n/**\n * Initialize a DAP.  This sets up the power domains, prepares the DP\n * for further use and activates overrun checking.\n *\n * @param dap The DAP being initialized.\n */\nint dap_dp_init(struct adiv5_dap *dap)\n{\n\tint retval;\n\n\tLOG_DEBUG(\"%s\", adiv5_dap_name(dap));\n\n\tdap->do_reconnect = false;\n\tdap_invalidate_cache(dap);\n\n\t/*\n\t * Early initialize dap->dp_ctrl_stat.\n\t * In jtag mode only, if the following queue run (in dap_dp_poll_register)\n\t * fails and sets the sticky error, it will trigger the clearing\n\t * of the sticky. Without this initialization system and debug power\n\t * would be disabled while clearing the sticky error bit.\n\t */\n\tdap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;\n\n\t/*\n\t * This write operation clears the sticky error bit in jtag mode only and\n\t * is ignored in swd mode. It also powers-up system and debug domains in\n\t * both jtag and swd modes, if not done before.\n\t */\n\tretval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat | SSTICKYERR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check that we have debug power domains activated */\n\tLOG_DEBUG(\"DAP: wait CDBGPWRUPACK\");\n\tretval = dap_dp_poll_register(dap, DP_CTRL_STAT,\n\t\t\t\t      CDBGPWRUPACK, CDBGPWRUPACK,\n\t\t\t\t      DAP_POWER_DOMAIN_TIMEOUT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!dap->ignore_syspwrupack) {\n\t\tLOG_DEBUG(\"DAP: wait CSYSPWRUPACK\");\n\t\tretval = dap_dp_poll_register(dap, DP_CTRL_STAT,\n\t\t\t\t\t      CSYSPWRUPACK, CSYSPWRUPACK,\n\t\t\t\t\t      DAP_POWER_DOMAIN_TIMEOUT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* With debug power on we can activate OVERRUN checking */\n\tdap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ | CORUNDETECT;\n\tretval = dap_queue_dp_write(dap, DP_CTRL_STAT, dap->dp_ctrl_stat);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_run(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\n/**\n * Initialize a DAP or do reconnect if DAP is not accessible.\n *\n * @param dap The DAP being initialized.\n */\nint dap_dp_init_or_reconnect(struct adiv5_dap *dap)\n{\n\tLOG_DEBUG(\"%s\", adiv5_dap_name(dap));\n\n\t/*\n\t * Early initialize dap->dp_ctrl_stat.\n\t * In jtag mode only, if the following atomic reads fail and set the\n\t * sticky error, it will trigger the clearing of the sticky. Without this\n\t * initialization system and debug power would be disabled while clearing\n\t * the sticky error bit.\n\t */\n\tdap->dp_ctrl_stat = CDBGPWRUPREQ | CSYSPWRUPREQ;\n\n\tdap->do_reconnect = false;\n\n\tdap_dp_read_atomic(dap, DP_CTRL_STAT, NULL);\n\tif (dap->do_reconnect) {\n\t\t/* dap connect calls dap_dp_init() after transport dependent initialization */\n\t\treturn dap->ops->connect(dap);\n\t} else {\n\t\treturn dap_dp_init(dap);\n\t}\n}\n\n/**\n * Initialize a DAP.  This sets up the power domains, prepares the DP\n * for further use, and arranges to use AP #0 for all AP operations\n * until dap_ap-select() changes that policy.\n *\n * @param ap The MEM-AP being initialized.\n */\nint mem_ap_init(struct adiv5_ap *ap)\n{\n\t/* check that we support packed transfers */\n\tuint32_t csw, cfg;\n\tint retval;\n\tstruct adiv5_dap *dap = ap->dap;\n\n\t/* Set ap->cfg_reg before calling mem_ap_setup_transfer(). */\n\t/* mem_ap_setup_transfer() needs to know if the MEM_AP supports LPAE. */\n\tretval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &cfg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_run(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tap->cfg_reg = cfg;\n\tap->tar_valid = false;\n\tap->csw_value = 0;      /* force csw and tar write */\n\tretval = mem_ap_setup_transfer(ap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_queue_ap_read(ap, MEM_AP_REG_CSW(dap), &csw);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_run(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (csw & CSW_ADDRINC_PACKED)\n\t\tap->packed_transfers = true;\n\telse\n\t\tap->packed_transfers = false;\n\n\t/* Packed transfers on TI BE-32 processors do not work correctly in\n\t * many cases. */\n\tif (dap->ti_be_32_quirks)\n\t\tap->packed_transfers = false;\n\n\tLOG_DEBUG(\"MEM_AP Packed Transfers: %s\",\n\t\t\tap->packed_transfers ? \"enabled\" : \"disabled\");\n\n\t/* The ARM ADI spec leaves implementation-defined whether unaligned\n\t * memory accesses work, only work partially, or cause a sticky error.\n\t * On TI BE-32 processors, reads seem to return garbage in some bytes\n\t * and unaligned writes seem to cause a sticky error.\n\t * TODO: it would be nice to have a way to detect whether unaligned\n\t * operations are supported on other processors. */\n\tap->unaligned_access_bad = dap->ti_be_32_quirks;\n\n\tLOG_DEBUG(\"MEM_AP CFG: large data %d, long address %d, big-endian %d\",\n\t\t\t!!(cfg & MEM_AP_REG_CFG_LD), !!(cfg & MEM_AP_REG_CFG_LA), !!(cfg & MEM_AP_REG_CFG_BE));\n\n\treturn ERROR_OK;\n}\n\n/**\n * Put the debug link into SWD mode, if the target supports it.\n * The link's initial mode may be either JTAG (for example,\n * with SWJ-DP after reset) or SWD.\n *\n * Note that targets using the JTAG-DP do not support SWD, and that\n * some targets which could otherwise support it may have been\n * configured to disable SWD signaling\n *\n * @param dap The DAP used\n * @return ERROR_OK or else a fault code.\n */\nint dap_to_swd(struct adiv5_dap *dap)\n{\n\tLOG_DEBUG(\"Enter SWD mode\");\n\n\treturn dap_send_sequence(dap, JTAG_TO_SWD);\n}\n\n/**\n * Put the debug link into JTAG mode, if the target supports it.\n * The link's initial mode may be either SWD or JTAG.\n *\n * Note that targets implemented with SW-DP do not support JTAG, and\n * that some targets which could otherwise support it may have been\n * configured to disable JTAG signaling\n *\n * @param dap The DAP used\n * @return ERROR_OK or else a fault code.\n */\nint dap_to_jtag(struct adiv5_dap *dap)\n{\n\tLOG_DEBUG(\"Enter JTAG mode\");\n\n\treturn dap_send_sequence(dap, SWD_TO_JTAG);\n}\n\n/* CID interpretation -- see ARM IHI 0029E table B2-7\n * and ARM IHI 0031E table D1-2.\n *\n * From 2009/11/25 commit 21378f58b604:\n *   \"OptimoDE DESS\" is ARM's semicustom DSPish stuff.\n * Let's keep it as is, for the time being\n */\nstatic const char *class_description[16] = {\n\t[0x0] = \"Generic verification component\",\n\t[0x1] = \"ROM table\",\n\t[0x2] = \"Reserved\",\n\t[0x3] = \"Reserved\",\n\t[0x4] = \"Reserved\",\n\t[0x5] = \"Reserved\",\n\t[0x6] = \"Reserved\",\n\t[0x7] = \"Reserved\",\n\t[0x8] = \"Reserved\",\n\t[0x9] = \"CoreSight component\",\n\t[0xA] = \"Reserved\",\n\t[0xB] = \"Peripheral Test Block\",\n\t[0xC] = \"Reserved\",\n\t[0xD] = \"OptimoDE DESS\", /* see above */\n\t[0xE] = \"Generic IP component\",\n\t[0xF] = \"CoreLink, PrimeCell or System component\",\n};\n\n#define ARCH_ID(architect, archid) ( \\\n\t(((architect) << ARM_CS_C9_DEVARCH_ARCHITECT_SHIFT) & ARM_CS_C9_DEVARCH_ARCHITECT_MASK) | \\\n\t(((archid) << ARM_CS_C9_DEVARCH_ARCHID_SHIFT) & ARM_CS_C9_DEVARCH_ARCHID_MASK) \\\n)\n\nstatic const struct {\n\tuint32_t arch_id;\n\tconst char *description;\n} class0x9_devarch[] = {\n\t/* keep same unsorted order as in ARM IHI0029E */\n\t{ ARCH_ID(ARM_ID, 0x0A00), \"RAS architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x1A01), \"Instrumentation Trace Macrocell (ITM) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x1A02), \"DWT architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x1A03), \"Flash Patch and Breakpoint unit (FPB) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x2A04), \"Processor debug architecture (ARMv8-M)\" },\n\t{ ARCH_ID(ARM_ID, 0x6A05), \"Processor debug architecture (ARMv8-R)\" },\n\t{ ARCH_ID(ARM_ID, 0x0A10), \"PC sample-based profiling\" },\n\t{ ARCH_ID(ARM_ID, 0x4A13), \"Embedded Trace Macrocell (ETM) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x1A14), \"Cross Trigger Interface (CTI) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x6A15), \"Processor debug architecture (v8.0-A)\" },\n\t{ ARCH_ID(ARM_ID, 0x7A15), \"Processor debug architecture (v8.1-A)\" },\n\t{ ARCH_ID(ARM_ID, 0x8A15), \"Processor debug architecture (v8.2-A)\" },\n\t{ ARCH_ID(ARM_ID, 0x2A16), \"Processor Performance Monitor (PMU) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A17), \"Memory Access Port v2 architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A27), \"JTAG Access Port v2 architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A31), \"Basic trace router\" },\n\t{ ARCH_ID(ARM_ID, 0x0A37), \"Power requestor\" },\n\t{ ARCH_ID(ARM_ID, 0x0A47), \"Unknown Access Port v2 architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A50), \"HSSTP architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A63), \"System Trace Macrocell (STM) architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0A75), \"CoreSight ELA architecture\" },\n\t{ ARCH_ID(ARM_ID, 0x0AF7), \"CoreSight ROM architecture\" },\n};\n\n#define DEVARCH_ID_MASK         (ARM_CS_C9_DEVARCH_ARCHITECT_MASK | ARM_CS_C9_DEVARCH_ARCHID_MASK)\n#define DEVARCH_MEM_AP          ARCH_ID(ARM_ID, 0x0A17)\n#define DEVARCH_ROM_C_0X9       ARCH_ID(ARM_ID, 0x0AF7)\n#define DEVARCH_UNKNOWN_V2      ARCH_ID(ARM_ID, 0x0A47)\n\nstatic const char *class0x9_devarch_description(uint32_t devarch)\n{\n\tif (!(devarch & ARM_CS_C9_DEVARCH_PRESENT))\n\t\treturn \"not present\";\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(class0x9_devarch); i++)\n\t\tif ((devarch & DEVARCH_ID_MASK) == class0x9_devarch[i].arch_id)\n\t\t\treturn class0x9_devarch[i].description;\n\n\treturn \"unknown\";\n}\n\nstatic const struct {\n\tenum ap_type type;\n\tconst char *description;\n} ap_types[] = {\n\t{ AP_TYPE_JTAG_AP,  \"JTAG-AP\" },\n\t{ AP_TYPE_COM_AP,   \"COM-AP\" },\n\t{ AP_TYPE_AHB3_AP,  \"MEM-AP AHB3\" },\n\t{ AP_TYPE_APB_AP,   \"MEM-AP APB2 or APB3\" },\n\t{ AP_TYPE_AXI_AP,   \"MEM-AP AXI3 or AXI4\" },\n\t{ AP_TYPE_AHB5_AP,  \"MEM-AP AHB5\" },\n\t{ AP_TYPE_APB4_AP,  \"MEM-AP APB4\" },\n\t{ AP_TYPE_AXI5_AP,  \"MEM-AP AXI5\" },\n\t{ AP_TYPE_AHB5H_AP, \"MEM-AP AHB5 with enhanced HPROT\" },\n};\n\nstatic const char *ap_type_to_description(enum ap_type type)\n{\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(ap_types); i++)\n\t\tif (type == ap_types[i].type)\n\t\t\treturn ap_types[i].description;\n\n\treturn \"Unknown\";\n}\n\nbool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num)\n{\n\tif (!dap)\n\t\treturn false;\n\n\t/* no autodetection, by now, so uninitialized is equivalent to ADIv5 for\n\t * backward compatibility */\n\tif (!is_adiv6(dap)) {\n\t\tif (ap_num > DP_APSEL_MAX)\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\tif (is_adiv6(dap)) {\n\t\tif (ap_num & 0x0fffULL)\n\t\t\treturn false;\n\t\tif (dap->asize != 0)\n\t\t\tif (ap_num & ((~0ULL) << dap->asize))\n\t\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/*\n * This function checks the ID for each access port to find the requested Access Port type\n * It also calls dap_get_ap() to increment the AP refcount\n */\nint dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out)\n{\n\tif (is_adiv6(dap)) {\n\t\t/* TODO: scan the ROM table and detect the AP available */\n\t\tLOG_DEBUG(\"On ADIv6 we cannot scan all the possible AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Maximum AP number is 255 since the SELECT register is 8 bits */\n\tfor (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) {\n\t\tstruct adiv5_ap *ap = dap_get_ap(dap, ap_num);\n\t\tif (!ap)\n\t\t\tcontinue;\n\n\t\t/* read the IDR register of the Access Port */\n\t\tuint32_t id_val = 0;\n\n\t\tint retval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &id_val);\n\t\tif (retval != ERROR_OK) {\n\t\t\tdap_put_ap(ap);\n\t\t\treturn retval;\n\t\t}\n\n\t\tretval = dap_run(dap);\n\n\t\t/* Reading register for a non-existent AP should not cause an error,\n\t\t * but just to be sure, try to continue searching if an error does happen.\n\t\t */\n\t\tif (retval == ERROR_OK && (id_val & AP_TYPE_MASK) == type_to_find) {\n\t\t\tLOG_DEBUG(\"Found %s at AP index: %d (IDR=0x%08\" PRIX32 \")\",\n\t\t\t\t\t\tap_type_to_description(type_to_find),\n\t\t\t\t\t\tap_num, id_val);\n\n\t\t\t*ap_out = ap;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tdap_put_ap(ap);\n\t}\n\n\tLOG_DEBUG(\"No %s found\", ap_type_to_description(type_to_find));\n\treturn ERROR_FAIL;\n}\n\nstatic inline bool is_ap_in_use(struct adiv5_ap *ap)\n{\n\treturn ap->refcount > 0 || ap->config_ap_never_release;\n}\n\nstatic struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)\n{\n\tif (!is_ap_num_valid(dap, ap_num)) {\n\t\tLOG_ERROR(\"Invalid AP#0x%\" PRIx64, ap_num);\n\t\treturn NULL;\n\t}\n\tif (is_adiv6(dap)) {\n\t\tfor (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {\n\t\t\tstruct adiv5_ap *ap = &dap->ap[i];\n\t\t\tif (is_ap_in_use(ap) && ap->ap_num == ap_num) {\n\t\t\t\t++ap->refcount;\n\t\t\t\treturn ap;\n\t\t\t}\n\t\t}\n\t\tfor (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {\n\t\t\tstruct adiv5_ap *ap = &dap->ap[i];\n\t\t\tif (!is_ap_in_use(ap)) {\n\t\t\t\tap->ap_num = ap_num;\n\t\t\t\t++ap->refcount;\n\t\t\t\treturn ap;\n\t\t\t}\n\t\t}\n\t\tLOG_ERROR(\"No more AP available!\");\n\t\treturn NULL;\n\t}\n\n\t/* ADIv5 */\n\tstruct adiv5_ap *ap = &dap->ap[ap_num];\n\tap->ap_num = ap_num;\n\t++ap->refcount;\n\treturn ap;\n}\n\n/* Return AP with specified ap_num. Increment AP refcount */\nstruct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num)\n{\n\tstruct adiv5_ap *ap = _dap_get_ap(dap, ap_num);\n\tif (ap)\n\t\tLOG_DEBUG(\"refcount AP#0x%\" PRIx64 \" get %u\", ap_num, ap->refcount);\n\treturn ap;\n}\n\n/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */\nstruct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num)\n{\n\tstruct adiv5_ap *ap = _dap_get_ap(dap, ap_num);\n\tif (ap) {\n\t\tap->config_ap_never_release = true;\n\t\tLOG_DEBUG(\"refcount AP#0x%\" PRIx64 \" get_config %u\", ap_num, ap->refcount);\n\t}\n\treturn ap;\n}\n\n/* Decrement AP refcount and release the AP when refcount reaches zero */\nint dap_put_ap(struct adiv5_ap *ap)\n{\n\tif (ap->refcount == 0) {\n\t\tLOG_ERROR(\"BUG: refcount AP#0x%\" PRIx64 \" put underflow\", ap->ap_num);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t--ap->refcount;\n\n\tLOG_DEBUG(\"refcount AP#0x%\" PRIx64 \" put %u\", ap->ap_num, ap->refcount);\n\tif (!is_ap_in_use(ap)) {\n\t\t/* defaults from dap_instance_init() */\n\t\tap->ap_num = DP_APSEL_INVALID;\n\t\tap->memaccess_tck = 255;\n\t\tap->tar_autoincr_block = (1 << 10);\n\t\tap->csw_default = CSW_AHB_DEFAULT;\n\t\tap->cfg_reg = MEM_AP_REG_CFG_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int dap_get_debugbase(struct adiv5_ap *ap,\n\t\t\ttarget_addr_t *dbgbase, uint32_t *apid)\n{\n\tstruct adiv5_dap *dap = ap->dap;\n\tint retval;\n\tuint32_t baseptr_upper, baseptr_lower;\n\n\tif (ap->cfg_reg == MEM_AP_REG_CFG_INVALID) {\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseptr_lower);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = dap_queue_ap_read(ap, AP_REG_IDR(dap), apid);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */\n\tif (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap)) {\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseptr_upper);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = dap_run(dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!is_64bit_ap(ap))\n\t\tbaseptr_upper = 0;\n\t*dbgbase = (((target_addr_t)baseptr_upper) << 32) | baseptr_lower;\n\n\treturn ERROR_OK;\n}\n\nint adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, uint64_t *baseptr)\n{\n\tuint32_t baseptr_lower, baseptr_upper = 0;\n\tint retval;\n\n\tif (dap->asize > 32) {\n\t\tretval = dap_queue_dp_read(dap, DP_BASEPTR1, &baseptr_upper);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = dap_dp_read_atomic(dap, DP_BASEPTR0, &baseptr_lower);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((baseptr_lower & DP_BASEPTR0_VALID) != DP_BASEPTR0_VALID) {\n\t\tcommand_print(cmd, \"System root table not present\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbaseptr_lower &= ~0x0fff;\n\t*baseptr = (((uint64_t)baseptr_upper) << 32) | baseptr_lower;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Method to access the CoreSight component.\n * On ADIv5, CoreSight components are on the bus behind a MEM-AP.\n * On ADIv6, CoreSight components can either be on the bus behind a MEM-AP\n * or directly in the AP.\n */\nenum coresight_access_mode {\n\tCS_ACCESS_AP,\n\tCS_ACCESS_MEM_AP,\n};\n\n/** Holds registers and coordinates of a CoreSight component */\nstruct cs_component_vals {\n\tstruct adiv5_ap *ap;\n\ttarget_addr_t component_base;\n\tuint64_t pid;\n\tuint32_t cid;\n\tuint32_t devarch;\n\tuint32_t devid;\n\tuint32_t devtype_memtype;\n\tenum coresight_access_mode mode;\n};\n\n/**\n * Helper to read CoreSight component's registers, either on the bus\n * behind a MEM-AP or directly in the AP.\n *\n * @param mode           Method to access the component (AP or MEM-AP).\n * @param ap             Pointer to AP containing the component.\n * @param component_base On MEM-AP access method, base address of the component.\n * @param reg            Offset of the component's register to read.\n * @param value          Pointer to the store the read value.\n *\n * @return ERROR_OK on success, else a fault code.\n */\nstatic int dap_queue_read_reg(enum coresight_access_mode mode, struct adiv5_ap *ap,\n\t\tuint64_t component_base, unsigned int reg, uint32_t *value)\n{\n\tif (mode == CS_ACCESS_AP)\n\t\treturn dap_queue_ap_read(ap, reg, value);\n\n\t/* mode == CS_ACCESS_MEM_AP */\n\treturn mem_ap_read_u32(ap, component_base + reg, value);\n}\n\n/**\n * Read the CoreSight registers needed during ROM Table Parsing (RTP).\n *\n * @param mode           Method to access the component (AP or MEM-AP).\n * @param ap             Pointer to AP containing the component.\n * @param component_base On MEM-AP access method, base address of the component.\n * @param v              Pointer to the struct holding the value of registers.\n *\n * @return ERROR_OK on success, else a fault code.\n */\nstatic int rtp_read_cs_regs(enum coresight_access_mode mode, struct adiv5_ap *ap,\n\t\ttarget_addr_t component_base, struct cs_component_vals *v)\n{\n\tassert(IS_ALIGNED(component_base, ARM_CS_ALIGN));\n\tassert(ap && v);\n\n\tuint32_t cid0, cid1, cid2, cid3;\n\tuint32_t pid0, pid1, pid2, pid3, pid4;\n\tint retval = ERROR_OK;\n\n\tv->ap = ap;\n\tv->component_base = component_base;\n\tv->mode = mode;\n\n\t/* sort by offset to gain speed */\n\n\t/*\n\t * Registers DEVARCH, DEVID and DEVTYPE are valid on Class 0x9 devices\n\t * only, but are at offset above 0xf00, so can be read on any device\n\t * without triggering error. Read them for eventual use on Class 0x9.\n\t */\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVARCH, &v->devarch);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVID, &v->devid);\n\n\t/* Same address as ARM_CS_C1_MEMTYPE */\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_C9_DEVTYPE, &v->devtype_memtype);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR4, &pid4);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR0, &pid0);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR1, &pid1);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR2, &pid2);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_PIDR3, &pid3);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR0, &cid0);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR1, &cid1);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR2, &cid2);\n\tif (retval == ERROR_OK)\n\t\tretval = dap_queue_read_reg(mode, ap, component_base, ARM_CS_CIDR3, &cid3);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(ap->dap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Failed read CoreSight registers\");\n\t\treturn retval;\n\t}\n\n\tv->cid = (cid3 & 0xff) << 24\n\t\t\t| (cid2 & 0xff) << 16\n\t\t\t| (cid1 & 0xff) << 8\n\t\t\t| (cid0 & 0xff);\n\tv->pid = (uint64_t)(pid4 & 0xff) << 32\n\t\t\t| (pid3 & 0xff) << 24\n\t\t\t| (pid2 & 0xff) << 16\n\t\t\t| (pid1 & 0xff) << 8\n\t\t\t| (pid0 & 0xff);\n\n\treturn ERROR_OK;\n}\n\n/* Part number interpretations are from Cortex\n * core specs, the CoreSight components TRM\n * (ARM DDI 0314H), CoreSight System Design\n * Guide (ARM DGI 0012D) and ETM specs; also\n * from chip observation (e.g. TI SDTI).\n */\n\nstatic const struct dap_part_nums {\n\tuint16_t designer_id;\n\tuint16_t part_num;\n\tconst char *type;\n\tconst char *full;\n} dap_part_nums[] = {\n\t{ ARM_ID, 0x000, \"Cortex-M3 SCS\",              \"(System Control Space)\", },\n\t{ ARM_ID, 0x001, \"Cortex-M3 ITM\",              \"(Instrumentation Trace Module)\", },\n\t{ ARM_ID, 0x002, \"Cortex-M3 DWT\",              \"(Data Watchpoint and Trace)\", },\n\t{ ARM_ID, 0x003, \"Cortex-M3 FPB\",              \"(Flash Patch and Breakpoint)\", },\n\t{ ARM_ID, 0x008, \"Cortex-M0 SCS\",              \"(System Control Space)\", },\n\t{ ARM_ID, 0x00a, \"Cortex-M0 DWT\",              \"(Data Watchpoint and Trace)\", },\n\t{ ARM_ID, 0x00b, \"Cortex-M0 BPU\",              \"(Breakpoint Unit)\", },\n\t{ ARM_ID, 0x00c, \"Cortex-M4 SCS\",              \"(System Control Space)\", },\n\t{ ARM_ID, 0x00d, \"CoreSight ETM11\",            \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x00e, \"Cortex-M7 FPB\",              \"(Flash Patch and Breakpoint)\", },\n\t{ ARM_ID, 0x193, \"SoC-600 TSGEN\",              \"(Timestamp Generator)\", },\n\t{ ARM_ID, 0x470, \"Cortex-M1 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x471, \"Cortex-M0 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x490, \"Cortex-A15 GIC\",             \"(Generic Interrupt Controller)\", },\n\t{ ARM_ID, 0x492, \"Cortex-R52 GICD\",            \"(Distributor)\", },\n\t{ ARM_ID, 0x493, \"Cortex-R52 GICR\",            \"(Redistributor)\", },\n\t{ ARM_ID, 0x4a1, \"Cortex-A53 ROM\",             \"(v8 Memory Map ROM Table)\", },\n\t{ ARM_ID, 0x4a2, \"Cortex-A57 ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x4a3, \"Cortex-A53 ROM\",             \"(v7 Memory Map ROM Table)\", },\n\t{ ARM_ID, 0x4a4, \"Cortex-A72 ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x4a9, \"Cortex-A9 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x4aa, \"Cortex-A35 ROM\",             \"(v8 Memory Map ROM Table)\", },\n\t{ ARM_ID, 0x4af, \"Cortex-A15 ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x4b5, \"Cortex-R5 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x4b8, \"Cortex-R52 ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x4c0, \"Cortex-M0+ ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x4c3, \"Cortex-M3 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x4c4, \"Cortex-M4 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x4c7, \"Cortex-M7 PPB ROM\",          \"(Private Peripheral Bus ROM Table)\", },\n\t{ ARM_ID, 0x4c8, \"Cortex-M7 ROM\",              \"(ROM Table)\", },\n\t{ ARM_ID, 0x4e0, \"Cortex-A35 ROM\",             \"(v7 Memory Map ROM Table)\", },\n\t{ ARM_ID, 0x4e4, \"Cortex-A76 ROM\",             \"(ROM Table)\", },\n\t{ ARM_ID, 0x906, \"CoreSight CTI\",              \"(Cross Trigger)\", },\n\t{ ARM_ID, 0x907, \"CoreSight ETB\",              \"(Trace Buffer)\", },\n\t{ ARM_ID, 0x908, \"CoreSight CSTF\",             \"(Trace Funnel)\", },\n\t{ ARM_ID, 0x909, \"CoreSight ATBR\",             \"(Advanced Trace Bus Replicator)\", },\n\t{ ARM_ID, 0x910, \"CoreSight ETM9\",             \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x912, \"CoreSight TPIU\",             \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x913, \"CoreSight ITM\",              \"(Instrumentation Trace Macrocell)\", },\n\t{ ARM_ID, 0x914, \"CoreSight SWO\",              \"(Single Wire Output)\", },\n\t{ ARM_ID, 0x917, \"CoreSight HTM\",              \"(AHB Trace Macrocell)\", },\n\t{ ARM_ID, 0x920, \"CoreSight ETM11\",            \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x921, \"Cortex-A8 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x922, \"Cortex-A8 CTI\",              \"(Cross Trigger)\", },\n\t{ ARM_ID, 0x923, \"Cortex-M3 TPIU\",             \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x924, \"Cortex-M3 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x925, \"Cortex-M4 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x930, \"Cortex-R4 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x931, \"Cortex-R5 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x932, \"CoreSight MTB-M0+\",          \"(Micro Trace Buffer)\", },\n\t{ ARM_ID, 0x941, \"CoreSight TPIU-Lite\",        \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x950, \"Cortex-A9 PTM\",              \"(Program Trace Macrocell)\", },\n\t{ ARM_ID, 0x955, \"Cortex-A5 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x95a, \"Cortex-A72 ETM\",             \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x95b, \"Cortex-A17 PTM\",             \"(Program Trace Macrocell)\", },\n\t{ ARM_ID, 0x95d, \"Cortex-A53 ETM\",             \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x95e, \"Cortex-A57 ETM\",             \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x95f, \"Cortex-A15 PTM\",             \"(Program Trace Macrocell)\", },\n\t{ ARM_ID, 0x961, \"CoreSight TMC\",              \"(Trace Memory Controller)\", },\n\t{ ARM_ID, 0x962, \"CoreSight STM\",              \"(System Trace Macrocell)\", },\n\t{ ARM_ID, 0x975, \"Cortex-M7 ETM\",              \"(Embedded Trace)\", },\n\t{ ARM_ID, 0x9a0, \"CoreSight PMU\",              \"(Performance Monitoring Unit)\", },\n\t{ ARM_ID, 0x9a1, \"Cortex-M4 TPIU\",             \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x9a4, \"CoreSight GPR\",              \"(Granular Power Requester)\", },\n\t{ ARM_ID, 0x9a5, \"Cortex-A5 PMU\",              \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9a7, \"Cortex-A7 PMU\",              \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9a8, \"Cortex-A53 CTI\",             \"(Cross Trigger)\", },\n\t{ ARM_ID, 0x9a9, \"Cortex-M7 TPIU\",             \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x9ae, \"Cortex-A17 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9af, \"Cortex-A15 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9b6, \"Cortex-R52 PMU/CTI/ETM\",     \"(Performance Monitor Unit/Cross Trigger/ETM)\", },\n\t{ ARM_ID, 0x9b7, \"Cortex-R7 PMU\",              \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9d3, \"Cortex-A53 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9d7, \"Cortex-A57 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9d8, \"Cortex-A72 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ ARM_ID, 0x9da, \"Cortex-A35 PMU/CTI/ETM\",     \"(Performance Monitor Unit/Cross Trigger/ETM)\", },\n\t{ ARM_ID, 0x9e2, \"SoC-600 APB-AP\",             \"(APB4 Memory Access Port)\", },\n\t{ ARM_ID, 0x9e3, \"SoC-600 AHB-AP\",             \"(AHB5 Memory Access Port)\", },\n\t{ ARM_ID, 0x9e4, \"SoC-600 AXI-AP\",             \"(AXI Memory Access Port)\", },\n\t{ ARM_ID, 0x9e5, \"SoC-600 APv1 Adapter\",       \"(Access Port v1 Adapter)\", },\n\t{ ARM_ID, 0x9e6, \"SoC-600 JTAG-AP\",            \"(JTAG Access Port)\", },\n\t{ ARM_ID, 0x9e7, \"SoC-600 TPIU\",               \"(Trace Port Interface Unit)\", },\n\t{ ARM_ID, 0x9e8, \"SoC-600 TMC ETR/ETS\",        \"(Embedded Trace Router/Streamer)\", },\n\t{ ARM_ID, 0x9e9, \"SoC-600 TMC ETB\",            \"(Embedded Trace Buffer)\", },\n\t{ ARM_ID, 0x9ea, \"SoC-600 TMC ETF\",            \"(Embedded Trace FIFO)\", },\n\t{ ARM_ID, 0x9eb, \"SoC-600 ATB Funnel\",         \"(Trace Funnel)\", },\n\t{ ARM_ID, 0x9ec, \"SoC-600 ATB Replicator\",     \"(Trace Replicator)\", },\n\t{ ARM_ID, 0x9ed, \"SoC-600 CTI\",                \"(Cross Trigger)\", },\n\t{ ARM_ID, 0x9ee, \"SoC-600 CATU\",               \"(Address Translation Unit)\", },\n\t{ ARM_ID, 0xc05, \"Cortex-A5 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc07, \"Cortex-A7 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc08, \"Cortex-A8 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc09, \"Cortex-A9 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc0e, \"Cortex-A17 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc0f, \"Cortex-A15 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc14, \"Cortex-R4 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc15, \"Cortex-R5 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xc17, \"Cortex-R7 Debug\",            \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd03, \"Cortex-A53 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd04, \"Cortex-A35 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd07, \"Cortex-A57 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd08, \"Cortex-A72 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd0b, \"Cortex-A76 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd0c, \"Neoverse N1\",                \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd13, \"Cortex-R52 Debug\",           \"(Debug Unit)\", },\n\t{ ARM_ID, 0xd49, \"Neoverse N2\",                \"(Debug Unit)\", },\n\t{ 0x017,  0x120, \"TI SDTI\",                    \"(System Debug Trace Interface)\", }, /* from OMAP3 memmap */\n\t{ 0x017,  0x343, \"TI DAPCTL\",                  \"\", }, /* from OMAP3 memmap */\n\t{ 0x017,  0x9af, \"MSP432 ROM\",                 \"(ROM Table)\" },\n\t{ 0x01f,  0xcd0, \"Atmel CPU with DSU\",         \"(CPU)\" },\n\t{ 0x041,  0x1db, \"XMC4500 ROM\",                \"(ROM Table)\" },\n\t{ 0x041,  0x1df, \"XMC4700/4800 ROM\",           \"(ROM Table)\" },\n\t{ 0x041,  0x1ed, \"XMC1000 ROM\",                \"(ROM Table)\" },\n\t{ 0x065,  0x000, \"SHARC+/Blackfin+\",           \"\", },\n\t{ 0x070,  0x440, \"Qualcomm QDSS Component v1\", \"(Qualcomm Designed CoreSight Component v1)\", },\n\t{ 0x0bf,  0x100, \"Brahma-B53 Debug\",           \"(Debug Unit)\", },\n\t{ 0x0bf,  0x9d3, \"Brahma-B53 PMU\",             \"(Performance Monitor Unit)\", },\n\t{ 0x0bf,  0x4a1, \"Brahma-B53 ROM\",             \"(ROM Table)\", },\n\t{ 0x0bf,  0x721, \"Brahma-B53 ROM\",             \"(ROM Table)\", },\n\t{ 0x1eb,  0x181, \"Tegra 186 ROM\",              \"(ROM Table)\", },\n\t{ 0x1eb,  0x202, \"Denver ETM\",                 \"(Denver Embedded Trace)\", },\n\t{ 0x1eb,  0x211, \"Tegra 210 ROM\",              \"(ROM Table)\", },\n\t{ 0x1eb,  0x302, \"Denver Debug\",               \"(Debug Unit)\", },\n\t{ 0x1eb,  0x402, \"Denver PMU\",                 \"(Performance Monitor Unit)\", },\n};\n\nstatic const struct dap_part_nums *pidr_to_part_num(unsigned int designer_id, unsigned int part_num)\n{\n\tstatic const struct dap_part_nums unknown = {\n\t\t.type = \"Unrecognized\",\n\t\t.full = \"\",\n\t};\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(dap_part_nums); i++)\n\t\tif (dap_part_nums[i].designer_id == designer_id && dap_part_nums[i].part_num == part_num)\n\t\t\treturn &dap_part_nums[i];\n\n\treturn &unknown;\n}\n\nstatic int dap_devtype_display(struct command_invocation *cmd, uint32_t devtype)\n{\n\tconst char *major = \"Reserved\", *subtype = \"Reserved\";\n\tconst unsigned int minor = (devtype & ARM_CS_C9_DEVTYPE_SUB_MASK) >> ARM_CS_C9_DEVTYPE_SUB_SHIFT;\n\tconst unsigned int devtype_major = (devtype & ARM_CS_C9_DEVTYPE_MAJOR_MASK) >> ARM_CS_C9_DEVTYPE_MAJOR_SHIFT;\n\tswitch (devtype_major) {\n\tcase 0:\n\t\tmajor = \"Miscellaneous\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tsubtype = \"Validation component\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 1:\n\t\tmajor = \"Trace Sink\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Port\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"Buffer\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"Router\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 2:\n\t\tmajor = \"Trace Link\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Funnel, router\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"Filter\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"FIFO, buffer\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 3:\n\t\tmajor = \"Trace Source\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Processor\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"DSP\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"Engine/Coprocessor\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tsubtype = \"Bus\";\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tsubtype = \"Software\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 4:\n\t\tmajor = \"Debug Control\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Trigger Matrix\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"Debug Auth\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"Power Requestor\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 5:\n\t\tmajor = \"Debug Logic\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Processor\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"DSP\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"Engine/Coprocessor\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tsubtype = \"Bus\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tsubtype = \"Memory\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\tcase 6:\n\t\tmajor = \"Performance Monitor\";\n\t\tswitch (minor) {\n\t\tcase 0:\n\t\t\tsubtype = \"other\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsubtype = \"Processor\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsubtype = \"DSP\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsubtype = \"Engine/Coprocessor\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tsubtype = \"Bus\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tsubtype = \"Memory\";\n\t\t\tbreak;\n\t\t}\n\t\tbreak;\n\t}\n\tcommand_print(cmd, \"\\t\\tType is 0x%02x, %s, %s\",\n\t\t\tdevtype & ARM_CS_C9_DEVTYPE_MASK,\n\t\t\tmajor, subtype);\n\treturn ERROR_OK;\n}\n\n/**\n * Actions/operations to be executed while parsing ROM tables.\n */\nstruct rtp_ops {\n\t/**\n\t * Executed at the start of a new AP, typically to print the AP header.\n\t * @param ap        Pointer to AP.\n\t * @param depth     The current depth level of ROM table.\n\t * @param priv      Pointer to private data.\n\t * @return          ERROR_OK on success, else a fault code.\n\t */\n\tint (*ap_header)(struct adiv5_ap *ap, int depth, void *priv);\n\t/**\n\t * Executed at the start of a new MEM-AP, typically to print the MEM-AP header.\n\t * @param retval    Error encountered while reading AP.\n\t * @param ap        Pointer to AP.\n\t * @param dbgbase   Value of MEM-AP Debug Base Address register.\n\t * @param apid      Value of MEM-AP IDR Identification Register.\n\t * @param depth     The current depth level of ROM table.\n\t * @param priv      Pointer to private data.\n\t * @return          ERROR_OK on success, else a fault code.\n\t */\n\tint (*mem_ap_header)(int retval, struct adiv5_ap *ap, uint64_t dbgbase,\n\t\t\tuint32_t apid, int depth, void *priv);\n\t/**\n\t * Executed when a CoreSight component is parsed, typically to print\n\t * information on the component.\n\t * @param retval    Error encountered while reading component's registers.\n\t * @param v         Pointer to a container of the component's registers.\n\t * @param depth     The current depth level of ROM table.\n\t * @param priv      Pointer to private data.\n\t * @return          ERROR_OK on success, else a fault code.\n\t */\n\tint (*cs_component)(int retval, struct cs_component_vals *v, int depth, void *priv);\n\t/**\n\t * Executed for each entry of a ROM table, typically to print the entry\n\t * and information about validity or end-of-table mark.\n\t * @param retval    Error encountered while reading the ROM table entry.\n\t * @param depth     The current depth level of ROM table.\n\t * @param offset    The offset of the entry in the ROM table.\n\t * @param romentry  The value of the ROM table entry.\n\t * @param priv      Pointer to private data.\n\t * @return          ERROR_OK on success, else a fault code.\n\t */\n\tint (*rom_table_entry)(int retval, int depth, unsigned int offset, uint64_t romentry,\n\t\t\tvoid *priv);\n\t/**\n\t * Private data\n\t */\n\tvoid *priv;\n};\n\n/**\n * Wrapper around struct rtp_ops::ap_header.\n */\nstatic int rtp_ops_ap_header(const struct rtp_ops *ops,\n\t\tstruct adiv5_ap *ap, int depth)\n{\n\tif (ops->ap_header)\n\t\treturn ops->ap_header(ap, depth, ops->priv);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Wrapper around struct rtp_ops::mem_ap_header.\n * Input parameter @a retval is propagated.\n */\nstatic int rtp_ops_mem_ap_header(const struct rtp_ops *ops,\n\t\tint retval, struct adiv5_ap *ap, uint64_t dbgbase, uint32_t apid, int depth)\n{\n\tif (!ops->mem_ap_header)\n\t\treturn retval;\n\n\tint retval1 = ops->mem_ap_header(retval, ap, dbgbase, apid, depth, ops->priv);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn retval1;\n}\n\n/**\n * Wrapper around struct rtp_ops::cs_component.\n * Input parameter @a retval is propagated.\n */\nstatic int rtp_ops_cs_component(const struct rtp_ops *ops,\n\t\tint retval, struct cs_component_vals *v, int depth)\n{\n\tif (!ops->cs_component)\n\t\treturn retval;\n\n\tint retval1 = ops->cs_component(retval, v, depth, ops->priv);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn retval1;\n}\n\n/**\n * Wrapper around struct rtp_ops::rom_table_entry.\n * Input parameter @a retval is propagated.\n */\nstatic int rtp_ops_rom_table_entry(const struct rtp_ops *ops,\n\t\tint retval, int depth, unsigned int offset, uint64_t romentry)\n{\n\tif (!ops->rom_table_entry)\n\t\treturn retval;\n\n\tint retval1 = ops->rom_table_entry(retval, depth, offset, romentry, ops->priv);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn retval1;\n}\n\n/* Broken ROM tables can have circular references. Stop after a while */\n#define ROM_TABLE_MAX_DEPTH (16)\n\n/**\n * Value used only during lookup of a CoreSight component in ROM table.\n * Return CORESIGHT_COMPONENT_FOUND when component is found.\n * Return ERROR_OK when component is not found yet.\n * Return any other ERROR_* in case of error.\n */\n#define CORESIGHT_COMPONENT_FOUND (1)\n\nstatic int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth);\nstatic int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops,\n\t\tstruct adiv5_ap *ap, target_addr_t dbgbase, bool *is_mem_ap, int depth);\n\nstatic int rtp_rom_loop(enum coresight_access_mode mode, const struct rtp_ops *ops,\n\t\tstruct adiv5_ap *ap, target_addr_t base_address, int depth,\n\t\tunsigned int width, unsigned int max_entries)\n{\n\t/* ADIv6 AP ROM table provide offset from current AP */\n\tif (mode == CS_ACCESS_AP)\n\t\tbase_address = ap->ap_num;\n\n\tassert(IS_ALIGNED(base_address, ARM_CS_ALIGN));\n\n\tunsigned int offset = 0;\n\twhile (max_entries--) {\n\t\tuint64_t romentry;\n\t\tuint32_t romentry_low, romentry_high;\n\t\ttarget_addr_t component_base;\n\t\tunsigned int saved_offset = offset;\n\n\t\tint retval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_low);\n\t\toffset += 4;\n\t\tif (retval == ERROR_OK && width == 64) {\n\t\t\tretval = dap_queue_read_reg(mode, ap, base_address, offset, &romentry_high);\n\t\t\toffset += 4;\n\t\t}\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = dap_run(ap->dap);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Failed read ROM table entry\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (width == 64) {\n\t\t\tromentry = (((uint64_t)romentry_high) << 32) | romentry_low;\n\t\t\tcomponent_base = base_address +\n\t\t\t\t((((uint64_t)romentry_high) << 32) | (romentry_low & ARM_CS_ROMENTRY_OFFSET_MASK));\n\t\t} else {\n\t\t\tromentry = romentry_low;\n\t\t\t/* \"romentry\" is signed */\n\t\t\tcomponent_base = base_address + (int32_t)(romentry_low & ARM_CS_ROMENTRY_OFFSET_MASK);\n\t\t\tif (!is_64bit_ap(ap))\n\t\t\t\tcomponent_base = (uint32_t)component_base;\n\t\t}\n\t\tretval = rtp_ops_rom_table_entry(ops, retval, depth, saved_offset, romentry);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (romentry == 0) {\n\t\t\t/* End of ROM table */\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!(romentry & ARM_CS_ROMENTRY_PRESENT))\n\t\t\tcontinue;\n\n\t\t/* Recurse */\n\t\tif (mode == CS_ACCESS_AP) {\n\t\t\tstruct adiv5_ap *next_ap = dap_get_ap(ap->dap, component_base);\n\t\t\tif (!next_ap) {\n\t\t\t\tLOG_DEBUG(\"Wrong AP # 0x%\" PRIx64, component_base);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tretval = rtp_ap(ops, next_ap, depth + 1);\n\t\t\tdap_put_ap(next_ap);\n\t\t} else {\n\t\t\t/* mode == CS_ACCESS_MEM_AP */\n\t\t\tretval = rtp_cs_component(mode, ops, ap, component_base, NULL, depth + 1);\n\t\t}\n\t\tif (retval == CORESIGHT_COMPONENT_FOUND)\n\t\t\treturn CORESIGHT_COMPONENT_FOUND;\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* TODO: do we need to send an ABORT before continuing? */\n\t\t\tLOG_DEBUG(\"Ignore error parsing CoreSight component\");\n\t\t\tcontinue;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int rtp_cs_component(enum coresight_access_mode mode, const struct rtp_ops *ops,\n\t\tstruct adiv5_ap *ap, target_addr_t base_address, bool *is_mem_ap, int depth)\n{\n\tstruct cs_component_vals v;\n\tint retval;\n\n\tassert(IS_ALIGNED(base_address, ARM_CS_ALIGN));\n\n\tif (is_mem_ap)\n\t\t*is_mem_ap = false;\n\n\tif (depth > ROM_TABLE_MAX_DEPTH)\n\t\tretval = ERROR_FAIL;\n\telse\n\t\tretval = rtp_read_cs_regs(mode, ap, base_address, &v);\n\n\tretval = rtp_ops_cs_component(ops, retval, &v, depth);\n\tif (retval == CORESIGHT_COMPONENT_FOUND)\n\t\treturn CORESIGHT_COMPONENT_FOUND;\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_OK; /* Don't abort recursion */\n\n\tif (!is_valid_arm_cs_cidr(v.cid))\n\t\treturn ERROR_OK; /* Don't abort recursion */\n\n\tconst unsigned int class = ARM_CS_CIDR_CLASS(v.cid);\n\n\tif (class == ARM_CS_CLASS_0X1_ROM_TABLE)\n\t\treturn rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 960);\n\n\tif (class == ARM_CS_CLASS_0X9_CS_COMPONENT) {\n\t\tif ((v.devarch & ARM_CS_C9_DEVARCH_PRESENT) == 0)\n\t\t\treturn ERROR_OK;\n\n\t\tif (is_mem_ap) {\n\t\t\tif ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_MEM_AP)\n\t\t\t\t*is_mem_ap = true;\n\n\t\t\t/* SoC-600 APv1 Adapter */\n\t\t\tif ((v.devarch & DEVARCH_ID_MASK) == DEVARCH_UNKNOWN_V2 &&\n\t\t\t\t\tARM_CS_PIDR_DESIGNER(v.pid) == ARM_ID &&\n\t\t\t\t\tARM_CS_PIDR_PART(v.pid) == 0x9e5)\n\t\t\t\t*is_mem_ap = true;\n\t\t}\n\n\t\t/* quit if not ROM table */\n\t\tif ((v.devarch & DEVARCH_ID_MASK) != DEVARCH_ROM_C_0X9)\n\t\t\treturn ERROR_OK;\n\n\t\tif ((v.devid & ARM_CS_C9_DEVID_FORMAT_MASK) == ARM_CS_C9_DEVID_FORMAT_64BIT)\n\t\t\treturn rtp_rom_loop(mode, ops, ap, base_address, depth, 64, 256);\n\t\telse\n\t\t\treturn rtp_rom_loop(mode, ops, ap, base_address, depth, 32, 512);\n\t}\n\n\t/* Class other than 0x1 and 0x9 */\n\treturn ERROR_OK;\n}\n\nstatic int rtp_ap(const struct rtp_ops *ops, struct adiv5_ap *ap, int depth)\n{\n\tuint32_t apid;\n\ttarget_addr_t dbgbase, invalid_entry;\n\n\tint retval = rtp_ops_ap_header(ops, ap, depth);\n\tif (retval != ERROR_OK || depth > ROM_TABLE_MAX_DEPTH)\n\t\treturn ERROR_OK; /* Don't abort recursion */\n\n\tif (is_adiv6(ap->dap)) {\n\t\tbool is_mem_ap;\n\t\tretval = rtp_cs_component(CS_ACCESS_AP, ops, ap, 0, &is_mem_ap, depth);\n\t\tif (retval == CORESIGHT_COMPONENT_FOUND)\n\t\t\treturn CORESIGHT_COMPONENT_FOUND;\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_OK; /* Don't abort recursion */\n\n\t\tif (!is_mem_ap)\n\t\t\treturn ERROR_OK;\n\t\t/* Continue for an ADIv6 MEM-AP or SoC-600 APv1 Adapter */\n\t}\n\n\t/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec  */\n\tretval = dap_get_debugbase(ap, &dbgbase, &apid);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = rtp_ops_mem_ap_header(ops, retval, ap, dbgbase, apid, depth);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (apid == 0)\n\t\treturn ERROR_FAIL;\n\n\t/* NOTE: a MEM-AP may have a single CoreSight component that's\n\t * not a ROM table ... or have no such components at all.\n\t */\n\tconst unsigned int class = (apid & AP_REG_IDR_CLASS_MASK) >> AP_REG_IDR_CLASS_SHIFT;\n\n\tif (class == AP_REG_IDR_CLASS_MEM_AP) {\n\t\tif (is_64bit_ap(ap))\n\t\t\tinvalid_entry = 0xFFFFFFFFFFFFFFFFull;\n\t\telse\n\t\t\tinvalid_entry = 0xFFFFFFFFul;\n\n\t\tif (dbgbase != invalid_entry && (dbgbase & 0x3) != 0x2) {\n\t\t\tretval = rtp_cs_component(CS_ACCESS_MEM_AP, ops, ap,\n\t\t\t\t\tdbgbase & 0xFFFFFFFFFFFFF000ull, NULL, depth);\n\t\t\tif (retval == CORESIGHT_COMPONENT_FOUND)\n\t\t\t\treturn CORESIGHT_COMPONENT_FOUND;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Actions for command \"dap info\" */\n\nstatic int dap_info_ap_header(struct adiv5_ap *ap, int depth, void *priv)\n{\n\tstruct command_invocation *cmd = priv;\n\n\tif (depth > ROM_TABLE_MAX_DEPTH) {\n\t\tcommand_print(cmd, \"\\tTables too deep\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(cmd, \"%sAP # 0x%\" PRIx64, (depth) ? \"\\t\\t\" : \"\", ap->ap_num);\n\treturn ERROR_OK;\n}\n\nstatic int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap,\n\t\ttarget_addr_t dbgbase, uint32_t apid, int depth, void *priv)\n{\n\tstruct command_invocation *cmd = priv;\n\ttarget_addr_t invalid_entry;\n\tchar tabs[17] = \"\";\n\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(cmd, \"\\t\\tCan't read MEM-AP, the corresponding core might be turned off\");\n\t\treturn retval;\n\t}\n\n\tif (depth > ROM_TABLE_MAX_DEPTH) {\n\t\tcommand_print(cmd, \"\\tTables too deep\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (depth)\n\t\tsnprintf(tabs, sizeof(tabs), \"\\t[L%02d] \", depth);\n\n\tcommand_print(cmd, \"\\t\\tAP ID register 0x%8.8\" PRIx32, apid);\n\tif (apid == 0) {\n\t\tcommand_print(cmd, \"\\t\\tNo AP found at this AP#0x%\" PRIx64, ap->ap_num);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(cmd, \"\\t\\tType is %s\", ap_type_to_description(apid & AP_TYPE_MASK));\n\n\t/* NOTE: a MEM-AP may have a single CoreSight component that's\n\t * not a ROM table ... or have no such components at all.\n\t */\n\tconst unsigned int class = (apid & AP_REG_IDR_CLASS_MASK) >> AP_REG_IDR_CLASS_SHIFT;\n\n\tif (class == AP_REG_IDR_CLASS_MEM_AP) {\n\t\tif (is_64bit_ap(ap))\n\t\t\tinvalid_entry = 0xFFFFFFFFFFFFFFFFull;\n\t\telse\n\t\t\tinvalid_entry = 0xFFFFFFFFul;\n\n\t\tcommand_print(cmd, \"%sMEM-AP BASE \" TARGET_ADDR_FMT, tabs, dbgbase);\n\n\t\tif (dbgbase == invalid_entry || (dbgbase & 0x3) == 0x2) {\n\t\t\tcommand_print(cmd, \"\\t\\tNo ROM table present\");\n\t\t} else {\n\t\t\tif (dbgbase & 0x01)\n\t\t\t\tcommand_print(cmd, \"\\t\\tValid ROM table present\");\n\t\t\telse\n\t\t\t\tcommand_print(cmd, \"\\t\\tROM table in legacy format\");\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dap_info_cs_component(int retval, struct cs_component_vals *v, int depth, void *priv)\n{\n\tstruct command_invocation *cmd = priv;\n\n\tif (depth > ROM_TABLE_MAX_DEPTH) {\n\t\tcommand_print(cmd, \"\\tTables too deep\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (v->mode == CS_ACCESS_MEM_AP)\n\t\tcommand_print(cmd, \"\\t\\tComponent base address \" TARGET_ADDR_FMT, v->component_base);\n\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(cmd, \"\\t\\tCan't read component, the corresponding core might be turned off\");\n\t\treturn retval;\n\t}\n\n\tif (!is_valid_arm_cs_cidr(v->cid)) {\n\t\tcommand_print(cmd, \"\\t\\tInvalid CID 0x%08\" PRIx32, v->cid);\n\t\treturn ERROR_OK; /* Don't abort recursion */\n\t}\n\n\t/* component may take multiple 4K pages */\n\tuint32_t size = ARM_CS_PIDR_SIZE(v->pid);\n\tif (size > 0)\n\t\tcommand_print(cmd, \"\\t\\tStart address \" TARGET_ADDR_FMT, v->component_base - 0x1000 * size);\n\n\tcommand_print(cmd, \"\\t\\tPeripheral ID 0x%010\" PRIx64, v->pid);\n\n\tconst unsigned int part_num = ARM_CS_PIDR_PART(v->pid);\n\tunsigned int designer_id = ARM_CS_PIDR_DESIGNER(v->pid);\n\n\tif (v->pid & ARM_CS_PIDR_JEDEC) {\n\t\t/* JEP106 code */\n\t\tcommand_print(cmd, \"\\t\\tDesigner is 0x%03x, %s\",\n\t\t\t\tdesigner_id, jep106_manufacturer(designer_id));\n\t} else {\n\t\t/* Legacy ASCII ID, clear invalid bits */\n\t\tdesigner_id &= 0x7f;\n\t\tcommand_print(cmd, \"\\t\\tDesigner ASCII code 0x%02x, %s\",\n\t\t\t\tdesigner_id, designer_id == 0x41 ? \"ARM\" : \"<unknown>\");\n\t}\n\n\tconst struct dap_part_nums *partnum = pidr_to_part_num(designer_id, part_num);\n\tcommand_print(cmd, \"\\t\\tPart is 0x%03x, %s %s\", part_num, partnum->type, partnum->full);\n\n\tconst unsigned int class = ARM_CS_CIDR_CLASS(v->cid);\n\tcommand_print(cmd, \"\\t\\tComponent class is 0x%x, %s\", class, class_description[class]);\n\n\tif (class == ARM_CS_CLASS_0X1_ROM_TABLE) {\n\t\tif (v->devtype_memtype & ARM_CS_C1_MEMTYPE_SYSMEM_MASK)\n\t\t\tcommand_print(cmd, \"\\t\\tMEMTYPE system memory present on bus\");\n\t\telse\n\t\t\tcommand_print(cmd, \"\\t\\tMEMTYPE system memory not present: dedicated debug bus\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (class == ARM_CS_CLASS_0X9_CS_COMPONENT) {\n\t\tdap_devtype_display(cmd, v->devtype_memtype);\n\n\t\t/* REVISIT also show ARM_CS_C9_DEVID */\n\n\t\tif ((v->devarch & ARM_CS_C9_DEVARCH_PRESENT) == 0)\n\t\t\treturn ERROR_OK;\n\n\t\tunsigned int architect_id = ARM_CS_C9_DEVARCH_ARCHITECT(v->devarch);\n\t\tunsigned int revision = ARM_CS_C9_DEVARCH_REVISION(v->devarch);\n\t\tcommand_print(cmd, \"\\t\\tDev Arch is 0x%08\" PRIx32 \", %s \\\"%s\\\" rev.%u\", v->devarch,\n\t\t\t\tjep106_manufacturer(architect_id), class0x9_devarch_description(v->devarch),\n\t\t\t\trevision);\n\n\t\tif ((v->devarch & DEVARCH_ID_MASK) == DEVARCH_ROM_C_0X9) {\n\t\t\tcommand_print(cmd, \"\\t\\tType is ROM table\");\n\n\t\t\tif (v->devid & ARM_CS_C9_DEVID_SYSMEM_MASK)\n\t\t\t\tcommand_print(cmd, \"\\t\\tMEMTYPE system memory present on bus\");\n\t\t\telse\n\t\t\t\tcommand_print(cmd, \"\\t\\tMEMTYPE system memory not present: dedicated debug bus\");\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Class other than 0x1 and 0x9 */\n\treturn ERROR_OK;\n}\n\nstatic int dap_info_rom_table_entry(int retval, int depth,\n\t\tunsigned int offset, uint64_t romentry, void *priv)\n{\n\tstruct command_invocation *cmd = priv;\n\tchar tabs[16] = \"\";\n\n\tif (depth)\n\t\tsnprintf(tabs, sizeof(tabs), \"[L%02d] \", depth);\n\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(cmd, \"\\t%sROMTABLE[0x%x] Read error\", tabs, offset);\n\t\tcommand_print(cmd, \"\\t\\tUnable to continue\");\n\t\tcommand_print(cmd, \"\\t%s\\tStop parsing of ROM table\", tabs);\n\t\treturn retval;\n\t}\n\n\tcommand_print(cmd, \"\\t%sROMTABLE[0x%x] = 0x%08\" PRIx64,\n\t\t\ttabs, offset, romentry);\n\n\tif (romentry == 0) {\n\t\tcommand_print(cmd, \"\\t%s\\tEnd of ROM table\", tabs);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!(romentry & ARM_CS_ROMENTRY_PRESENT)) {\n\t\tcommand_print(cmd, \"\\t\\tComponent not present\");\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint dap_info_command(struct command_invocation *cmd, struct adiv5_ap *ap)\n{\n\tstruct rtp_ops dap_info_ops = {\n\t\t.ap_header       = dap_info_ap_header,\n\t\t.mem_ap_header   = dap_info_mem_ap_header,\n\t\t.cs_component    = dap_info_cs_component,\n\t\t.rom_table_entry = dap_info_rom_table_entry,\n\t\t.priv            = cmd,\n\t};\n\n\treturn rtp_ap(&dap_info_ops, ap, 0);\n}\n\n/* Actions for dap_lookup_cs_component() */\n\nstruct dap_lookup_data {\n\t/* input */\n\tunsigned int idx;\n\tunsigned int type;\n\t/* output */\n\tuint64_t component_base;\n\tuint64_t ap_num;\n};\n\nstatic int dap_lookup_cs_component_cs_component(int retval,\n\t\tstruct cs_component_vals *v, int depth, void *priv)\n{\n\tstruct dap_lookup_data *lookup = priv;\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!is_valid_arm_cs_cidr(v->cid))\n\t\treturn ERROR_OK;\n\n\tconst unsigned int class = ARM_CS_CIDR_CLASS(v->cid);\n\tif (class != ARM_CS_CLASS_0X9_CS_COMPONENT)\n\t\treturn ERROR_OK;\n\n\tif ((v->devtype_memtype & ARM_CS_C9_DEVTYPE_MASK) != lookup->type)\n\t\treturn ERROR_OK;\n\n\tif (lookup->idx) {\n\t\t/* search for next one */\n\t\t--lookup->idx;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Found! */\n\tlookup->component_base = v->component_base;\n\tlookup->ap_num = v->ap->ap_num;\n\treturn CORESIGHT_COMPONENT_FOUND;\n}\n\nint dap_lookup_cs_component(struct adiv5_ap *ap, uint8_t type,\n\t\ttarget_addr_t *addr, int32_t core_id)\n{\n\tstruct dap_lookup_data lookup = {\n\t\t.type = type,\n\t\t.idx  = core_id,\n\t};\n\tstruct rtp_ops dap_lookup_cs_component_ops = {\n\t\t.ap_header       = NULL,\n\t\t.mem_ap_header   = NULL,\n\t\t.cs_component    = dap_lookup_cs_component_cs_component,\n\t\t.rom_table_entry = NULL,\n\t\t.priv            = &lookup,\n\t};\n\n\tint retval = rtp_ap(&dap_lookup_cs_component_ops, ap, 0);\n\tif (retval == CORESIGHT_COMPONENT_FOUND) {\n\t\tif (lookup.ap_num != ap->ap_num) {\n\t\t\t/* TODO: handle search from root ROM table */\n\t\t\tLOG_DEBUG(\"CS lookup ended in AP # 0x%\" PRIx64 \". Ignore it\", lookup.ap_num);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tLOG_DEBUG(\"CS lookup found at 0x%\" PRIx64, lookup.component_base);\n\t\t*addr = lookup.component_base;\n\t\treturn ERROR_OK;\n\t}\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"CS lookup error %d\", retval);\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\"CS lookup not found\");\n\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n}\n\nenum adiv5_cfg_param {\n\tCFG_DAP,\n\tCFG_AP_NUM,\n\tCFG_BASEADDR,\n\tCFG_CTIBASE, /* DEPRECATED */\n};\n\nstatic const struct jim_nvp nvp_config_opts[] = {\n\t{ .name = \"-dap\",       .value = CFG_DAP },\n\t{ .name = \"-ap-num\",    .value = CFG_AP_NUM },\n\t{ .name = \"-baseaddr\",  .value = CFG_BASEADDR },\n\t{ .name = \"-ctibase\",   .value = CFG_CTIBASE }, /* DEPRECATED */\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic int adiv5_jim_spot_configure(struct jim_getopt_info *goi,\n\t\tstruct adiv5_dap **dap_p, uint64_t *ap_num_p, uint32_t *base_p)\n{\n\tassert(dap_p && ap_num_p);\n\n\tif (!goi->argc)\n\t\treturn JIM_OK;\n\n\tJim_SetEmptyResult(goi->interp);\n\n\tstruct jim_nvp *n;\n\tint e = jim_nvp_name2value_obj(goi->interp, nvp_config_opts,\n\t\t\t\tgoi->argv[0], &n);\n\tif (e != JIM_OK)\n\t\treturn JIM_CONTINUE;\n\n\t/* base_p can be NULL, then '-baseaddr' option is treated as unknown */\n\tif (!base_p && (n->value == CFG_BASEADDR || n->value == CFG_CTIBASE))\n\t\treturn JIM_CONTINUE;\n\n\te = jim_getopt_obj(goi, NULL);\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\tswitch (n->value) {\n\tcase CFG_DAP:\n\t\tif (goi->isconfigure) {\n\t\t\tJim_Obj *o_t;\n\t\t\tstruct adiv5_dap *dap;\n\t\t\te = jim_getopt_obj(goi, &o_t);\n\t\t\tif (e != JIM_OK)\n\t\t\t\treturn e;\n\t\t\tdap = dap_instance_by_jim_obj(goi->interp, o_t);\n\t\t\tif (!dap) {\n\t\t\t\tJim_SetResultString(goi->interp, \"DAP name invalid!\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tif (*dap_p && *dap_p != dap) {\n\t\t\t\tJim_SetResultString(goi->interp,\n\t\t\t\t\t\"DAP assignment cannot be changed!\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\t*dap_p = dap;\n\t\t} else {\n\t\t\tif (goi->argc)\n\t\t\t\tgoto err_no_param;\n\t\t\tif (!*dap_p) {\n\t\t\t\tJim_SetResultString(goi->interp, \"DAP not configured\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tJim_SetResultString(goi->interp, adiv5_dap_name(*dap_p), -1);\n\t\t}\n\t\tbreak;\n\n\tcase CFG_AP_NUM:\n\t\tif (goi->isconfigure) {\n\t\t\t/* jim_wide is a signed 64 bits int, ap_num is unsigned with max 52 bits */\n\t\t\tjim_wide ap_num;\n\t\t\te = jim_getopt_wide(goi, &ap_num);\n\t\t\tif (e != JIM_OK)\n\t\t\t\treturn e;\n\t\t\t/* we still don't know dap->adi_version */\n\t\t\tif (ap_num < 0 || (ap_num > DP_APSEL_MAX && (ap_num & 0xfff))) {\n\t\t\t\tJim_SetResultString(goi->interp, \"Invalid AP number!\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\t*ap_num_p = ap_num;\n\t\t} else {\n\t\t\tif (goi->argc)\n\t\t\t\tgoto err_no_param;\n\t\t\tif (*ap_num_p == DP_APSEL_INVALID) {\n\t\t\t\tJim_SetResultString(goi->interp, \"AP number not configured\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, *ap_num_p));\n\t\t}\n\t\tbreak;\n\n\tcase CFG_CTIBASE:\n\t\tLOG_WARNING(\"DEPRECATED! use \\'-baseaddr' not \\'-ctibase\\'\");\n\t\t/* fall through */\n\tcase CFG_BASEADDR:\n\t\tif (goi->isconfigure) {\n\t\t\tjim_wide base;\n\t\t\te = jim_getopt_wide(goi, &base);\n\t\t\tif (e != JIM_OK)\n\t\t\t\treturn e;\n\t\t\t*base_p = (uint32_t)base;\n\t\t} else {\n\t\t\tif (goi->argc)\n\t\t\t\tgoto err_no_param;\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, *base_p));\n\t\t}\n\t\tbreak;\n\t};\n\n\treturn JIM_OK;\n\nerr_no_param:\n\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"NO PARAMS\");\n\treturn JIM_ERR;\n}\n\nint adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi)\n{\n\tstruct adiv5_private_config *pc;\n\tint e;\n\n\tpc = (struct adiv5_private_config *)target->private_config;\n\tif (!pc) {\n\t\tpc = calloc(1, sizeof(struct adiv5_private_config));\n\t\tif (!pc) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\t\tpc->ap_num = DP_APSEL_INVALID;\n\t\ttarget->private_config = pc;\n\t}\n\n\ttarget->has_dap = true;\n\n\te = adiv5_jim_spot_configure(goi, &pc->dap, &pc->ap_num, NULL);\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\tif (pc->dap && !target->dap_configured) {\n\t\tif (target->tap_configured) {\n\t\t\tpc->dap = NULL;\n\t\t\tJim_SetResultString(goi->interp,\n\t\t\t\t\"-chain-position and -dap configparams are mutually exclusive!\", -1);\n\t\t\treturn JIM_ERR;\n\t\t}\n\t\ttarget->tap = pc->dap->tap;\n\t\ttarget->dap_configured = true;\n\t}\n\n\treturn JIM_OK;\n}\n\nint adiv5_verify_config(struct adiv5_private_config *pc)\n{\n\tif (!pc)\n\t\treturn ERROR_FAIL;\n\n\tif (!pc->dap)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nint adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg,\n\t\tstruct jim_getopt_info *goi)\n{\n\treturn adiv5_jim_spot_configure(goi, &cfg->dap, &cfg->ap_num, &cfg->base);\n}\n\nint adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p)\n{\n\tp->dap = NULL;\n\tp->ap_num = DP_APSEL_INVALID;\n\tp->base = 0;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_dap_info_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint64_t apsel;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tapsel = dap->apsel;\n\t\tbreak;\n\tcase 1:\n\t\tif (!strcmp(CMD_ARGV[0], \"root\")) {\n\t\t\tif (!is_adiv6(dap)) {\n\t\t\t\tcommand_print(CMD, \"Option \\\"root\\\" not allowed with ADIv5 DAP\");\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t}\n\t\t\tint retval = adiv6_dap_read_baseptr(CMD, dap, &apsel);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD, \"Failed reading DAP baseptr\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\t\tif (!is_ap_num_valid(dap, apsel)) {\n\t\t\tcommand_print(CMD, \"Invalid AP number\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, apsel);\n\tif (!ap) {\n\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = dap_info_command(CMD, ap);\n\tdap_put_ap(ap);\n\treturn retval;\n}\n\nCOMMAND_HANDLER(dap_baseaddr_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint64_t apsel;\n\tuint32_t baseaddr_lower, baseaddr_upper;\n\tstruct adiv5_ap *ap;\n\ttarget_addr_t baseaddr;\n\tint retval;\n\n\tbaseaddr_upper = 0;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tapsel = dap->apsel;\n\t\tbreak;\n\tcase 1:\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\t\tif (!is_ap_num_valid(dap, apsel)) {\n\t\t\tcommand_print(CMD, \"Invalid AP number\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* NOTE:  assumes we're talking to a MEM-AP, which\n\t * has a base address.  There are other kinds of AP,\n\t * though they're not common for now.  This should\n\t * use the ID register to verify it's a MEM-AP.\n\t */\n\n\tap = dap_get_ap(dap, apsel);\n\tif (!ap) {\n\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = dap_queue_ap_read(ap, MEM_AP_REG_BASE(dap), &baseaddr_lower);\n\n\tif (retval == ERROR_OK && ap->cfg_reg == MEM_AP_REG_CFG_INVALID)\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_CFG(dap), &ap->cfg_reg);\n\n\tif (retval == ERROR_OK && (ap->cfg_reg == MEM_AP_REG_CFG_INVALID || is_64bit_ap(ap))) {\n\t\t/* MEM_AP_REG_BASE64 is defined as 'RES0'; can be read and then ignored on 32 bits AP */\n\t\tretval = dap_queue_ap_read(ap, MEM_AP_REG_BASE64(dap), &baseaddr_upper);\n\t}\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (is_64bit_ap(ap)) {\n\t\tbaseaddr = (((target_addr_t)baseaddr_upper) << 32) | baseaddr_lower;\n\t\tcommand_print(CMD, \"0x%016\" PRIx64, baseaddr);\n\t} else\n\t\tcommand_print(CMD, \"0x%08\" PRIx32, baseaddr_lower);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(dap_memaccess_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tstruct adiv5_ap *ap;\n\tuint32_t memaccess_tck;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tap = dap_get_ap(dap, dap->apsel);\n\t\tif (!ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tmemaccess_tck = ap->memaccess_tck;\n\t\tbreak;\n\tcase 1:\n\t\tap = dap_get_config_ap(dap, dap->apsel);\n\t\tif (!ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], memaccess_tck);\n\t\tap->memaccess_tck = memaccess_tck;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tdap_put_ap(ap);\n\n\tcommand_print(CMD, \"memory bus access delay set to %\" PRIu32 \" tck\",\n\t\t\tmemaccess_tck);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(dap_apsel_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint64_t apsel;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tcommand_print(CMD, \"0x%\" PRIx64, dap->apsel);\n\t\treturn ERROR_OK;\n\tcase 1:\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\t\tif (!is_ap_num_valid(dap, apsel)) {\n\t\t\tcommand_print(CMD, \"Invalid AP number\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tdap->apsel = apsel;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(dap_apcsw_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tstruct adiv5_ap *ap;\n\tuint32_t csw_val, csw_mask;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tap = dap_get_ap(dap, dap->apsel);\n\t\tif (!ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tcommand_print(CMD, \"AP#0x%\" PRIx64 \" selected, csw 0x%8.8\" PRIx32,\n\t\t\tdap->apsel, ap->csw_default);\n\t\tbreak;\n\tcase 1:\n\t\tif (strcmp(CMD_ARGV[0], \"default\") == 0)\n\t\t\tcsw_val = CSW_AHB_DEFAULT;\n\t\telse\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val);\n\n\t\tif (csw_val & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) {\n\t\t\tLOG_ERROR(\"CSW value cannot include 'Size' and 'AddrInc' bit-fields\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tap = dap_get_config_ap(dap, dap->apsel);\n\t\tif (!ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tap->csw_default = csw_val;\n\t\tbreak;\n\tcase 2:\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], csw_val);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], csw_mask);\n\t\tif (csw_mask & (CSW_SIZE_MASK | CSW_ADDRINC_MASK)) {\n\t\t\tLOG_ERROR(\"CSW mask cannot include 'Size' and 'AddrInc' bit-fields\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tap = dap_get_config_ap(dap, dap->apsel);\n\t\tif (!ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tap->csw_default = (ap->csw_default & ~csw_mask) | (csw_val & csw_mask);\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tdap_put_ap(ap);\n\n\treturn ERROR_OK;\n}\n\n\n\nCOMMAND_HANDLER(dap_apid_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint64_t apsel;\n\tuint32_t apid;\n\tint retval;\n\n\tswitch (CMD_ARGC) {\n\tcase 0:\n\t\tapsel = dap->apsel;\n\t\tbreak;\n\tcase 1:\n\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\t\tif (!is_ap_num_valid(dap, apsel)) {\n\t\t\tcommand_print(CMD, \"Invalid AP number\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, apsel);\n\tif (!ap) {\n\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\tretval = dap_queue_ap_read(ap, AP_REG_IDR(dap), &apid);\n\tif (retval != ERROR_OK) {\n\t\tdap_put_ap(ap);\n\t\treturn retval;\n\t}\n\tretval = dap_run(dap);\n\tdap_put_ap(ap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"0x%8.8\" PRIx32, apid);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(dap_apreg_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint64_t apsel;\n\tuint32_t reg, value;\n\tint retval;\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\tif (!is_ap_num_valid(dap, apsel)) {\n\t\tcommand_print(CMD, \"Invalid AP number\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg);\n\tif (is_adiv6(dap)) {\n\t\tif (reg >= 4096 || (reg & 3)) {\n\t\t\tcommand_print(CMD, \"Invalid reg value (should be less than 4096 and 4 bytes aligned)\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t} else {\t/* ADI version 5 */\n\t\tif (reg >= 256 || (reg & 3)) {\n\t\t\tcommand_print(CMD, \"Invalid reg value (should be less than 256 and 4 bytes aligned)\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, apsel);\n\tif (!ap) {\n\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC == 3) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);\n\t\t/* see if user supplied register address is a match for the CSW or TAR register */\n\t\tif (reg == MEM_AP_REG_CSW(dap)) {\n\t\t\tap->csw_value = 0;  /* invalid, in case write fails */\n\t\t\tretval = dap_queue_ap_write(ap, reg, value);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tap->csw_value = value;\n\t\t} else if (reg == MEM_AP_REG_TAR(dap)) {\n\t\t\tretval = dap_queue_ap_write(ap, reg, value);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tap->tar_value = (ap->tar_value & ~0xFFFFFFFFull) | value;\n\t\t\telse {\n\t\t\t\t/* To track independent writes to TAR and TAR64, two tar_valid flags */\n\t\t\t\t/* should be used. To keep it simple, tar_valid is only invalidated on a */\n\t\t\t\t/* write fail. This approach causes a later re-write of the TAR and TAR64 */\n\t\t\t\t/* if tar_valid is false. */\n\t\t\t\tap->tar_valid = false;\n\t\t\t}\n\t\t} else if (reg == MEM_AP_REG_TAR64(dap)) {\n\t\t\tretval = dap_queue_ap_write(ap, reg, value);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tap->tar_value = (ap->tar_value & 0xFFFFFFFFull) | (((target_addr_t)value) << 32);\n\t\t\telse {\n\t\t\t\t/* See above comment for the MEM_AP_REG_TAR failed write case */\n\t\t\t\tap->tar_valid = false;\n\t\t\t}\n\t\t} else {\n\t\t\tretval = dap_queue_ap_write(ap, reg, value);\n\t\t}\n\t} else {\n\t\tretval = dap_queue_ap_read(ap, reg, &value);\n\t}\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(dap);\n\n\tdap_put_ap(ap);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC == 2)\n\t\tcommand_print(CMD, \"0x%08\" PRIx32, value);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(dap_dpreg_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\tuint32_t reg, value;\n\tint retval;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg);\n\tif (reg >= 256 || (reg & 3)) {\n\t\tcommand_print(CMD, \"Invalid reg value (should be less than 256 and 4 bytes aligned)\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\t\tretval = dap_queue_dp_write(dap, reg, value);\n\t} else {\n\t\tretval = dap_queue_dp_read(dap, reg, &value);\n\t}\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(dap);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC == 1)\n\t\tcommand_print(CMD, \"0x%08\" PRIx32, value);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(dap_ti_be_32_quirks_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->ti_be_32_quirks,\n\t\t\"TI BE-32 quirks mode\");\n}\n\nCOMMAND_HANDLER(dap_nu_npcx_quirks_command)\n{\n\tstruct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->nu_npcx_quirks,\n\t\t\t\t\t\t\t\t\"Nuvoton NPCX quirks mode\");\n}\n\nconst struct command_registration dap_instance_commands[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_dap_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display ROM table for specified MEM-AP (default currently selected AP) \"\n\t\t\t\"or the ADIv6 root ROM table\",\n\t\t.usage = \"[ap_num | 'root']\",\n\t},\n\t{\n\t\t.name = \"apsel\",\n\t\t.handler = dap_apsel_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Set the currently selected AP (default 0) \"\n\t\t\t\"and display the result\",\n\t\t.usage = \"[ap_num]\",\n\t},\n\t{\n\t\t.name = \"apcsw\",\n\t\t.handler = dap_apcsw_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Set CSW default bits\",\n\t\t.usage = \"[value [mask]]\",\n\t},\n\n\t{\n\t\t.name = \"apid\",\n\t\t.handler = dap_apid_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"return ID register from AP \"\n\t\t\t\"(default currently selected AP)\",\n\t\t.usage = \"[ap_num]\",\n\t},\n\t{\n\t\t.name = \"apreg\",\n\t\t.handler = dap_apreg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read/write a register from AP \"\n\t\t\t\"(reg is byte address of a word register, like 0 4 8...)\",\n\t\t.usage = \"ap_num reg [value]\",\n\t},\n\t{\n\t\t.name = \"dpreg\",\n\t\t.handler = dap_dpreg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"read/write a register from DP \"\n\t\t\t\"(reg is byte address (bank << 4 | reg) of a word register, like 0 4 8...)\",\n\t\t.usage = \"reg [value]\",\n\t},\n\t{\n\t\t.name = \"baseaddr\",\n\t\t.handler = dap_baseaddr_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"return debug base address from MEM-AP \"\n\t\t\t\"(default currently selected AP)\",\n\t\t.usage = \"[ap_num]\",\n\t},\n\t{\n\t\t.name = \"memaccess\",\n\t\t.handler = dap_memaccess_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set/get number of extra tck for MEM-AP memory \"\n\t\t\t\"bus access [0-255]\",\n\t\t.usage = \"[cycles]\",\n\t},\n\t{\n\t\t.name = \"ti_be_32_quirks\",\n\t\t.handler = dap_ti_be_32_quirks_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set/get quirks mode for TI TMS450/TMS570 processors\",\n\t\t.usage = \"[enable]\",\n\t},\n\t{\n\t\t.name = \"nu_npcx_quirks\",\n\t\t.handler = dap_nu_npcx_quirks_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"set/get quirks mode for Nuvoton NPCX controllers\",\n\t\t.usage = \"[enable]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_adi_v5.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2019-2021, Ampere Computing LLC                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_ADI_V5_H\n#define OPENOCD_TARGET_ARM_ADI_V5_H\n\n/**\n * @file\n * This defines formats and data structures used to talk to ADIv5 entities.\n * Those include a DAP, different types of Debug Port (DP), and memory mapped\n * resources accessed through a MEM-AP.\n */\n\n#include <helper/list.h>\n#include \"arm_jtag.h\"\n#include \"helper/bits.h\"\n\n/* JEP106 ID for ARM */\n#define ARM_ID 0x23B\n\n/* three-bit ACK values for SWD access (sent LSB first) */\n#define SWD_ACK_OK    0x1\n#define SWD_ACK_WAIT  0x2\n#define SWD_ACK_FAULT 0x4\n\n#define DPAP_WRITE\t\t0\n#define DPAP_READ\t\t1\n\n#define BANK_REG(bank, reg)\t(((bank) << 4) | (reg))\n\n/* A[3:0] for DP registers; A[1:0] are always zero.\n * - JTAG accesses all of these via JTAG_DP_DPACC, except for\n *   IDCODE (JTAG_DP_IDCODE) and ABORT (JTAG_DP_ABORT).\n * - SWD accesses these directly, sometimes needing SELECT.DPBANKSEL\n */\n#define DP_DPIDR        BANK_REG(0x0, 0x0) /* DPv1+: ro */\n#define DP_ABORT        BANK_REG(0x0, 0x0) /* DPv1+: SWD: wo */\n#define DP_DPIDR1       BANK_REG(0x1, 0x0) /* DPv3: ro */\n#define DP_BASEPTR0     BANK_REG(0x2, 0x0) /* DPv3: ro */\n#define DP_BASEPTR1     BANK_REG(0x3, 0x0) /* DPv3: ro */\n#define DP_CTRL_STAT    BANK_REG(0x0, 0x4) /* DPv0+: rw */\n#define DP_DLCR         BANK_REG(0x1, 0x4) /* DPv1+: SWD: rw */\n#define DP_TARGETID     BANK_REG(0x2, 0x4) /* DPv2: ro */\n#define DP_DLPIDR       BANK_REG(0x3, 0x4) /* DPv2: ro */\n#define DP_EVENTSTAT    BANK_REG(0x4, 0x4) /* DPv2: ro */\n#define DP_SELECT1      BANK_REG(0x5, 0x4) /* DPv3: ro */\n#define DP_RESEND       BANK_REG(0x0, 0x8) /* DPv1+: SWD: ro */\n#define DP_SELECT       BANK_REG(0x0, 0x8) /* DPv0+: JTAG: rw; SWD: wo */\n#define DP_RDBUFF       BANK_REG(0x0, 0xC) /* DPv0+: ro */\n#define DP_TARGETSEL    BANK_REG(0x0, 0xC) /* DPv2: SWD: wo */\n\n#define DLCR_TO_TRN(dlcr) ((uint32_t)(1 + ((3 & (dlcr)) >> 8))) /* 1..4 clocks */\n\n/* Fields of DP_DPIDR register */\n#define DP_DPIDR_VERSION_SHIFT\t12\n#define DP_DPIDR_VERSION_MASK\t(0xFUL << DP_DPIDR_VERSION_SHIFT)\n\n/* Fields of the DP's AP ABORT register */\n#define DAPABORT        (1UL << 0)\n#define STKCMPCLR       (1UL << 1) /* SWD-only */\n#define STKERRCLR       (1UL << 2) /* SWD-only */\n#define WDERRCLR        (1UL << 3) /* SWD-only */\n#define ORUNERRCLR      (1UL << 4) /* SWD-only */\n\n/* Fields of register DP_DPIDR1 */\n#define DP_DPIDR1_ASIZE_MASK    (0x7F)\n#define DP_DPIDR1_ERRMODE       BIT(7)\n\n/* Fields of register DP_BASEPTR0 */\n#define DP_BASEPTR0_VALID       BIT(0)\n\n/* Fields of the DP's CTRL/STAT register */\n#define CORUNDETECT     (1UL << 0)\n#define SSTICKYORUN     (1UL << 1)\n/* 3:2 - transaction mode (e.g. pushed compare) */\n#define SSTICKYCMP      (1UL << 4)\n#define SSTICKYERR      (1UL << 5)\n#define READOK          (1UL << 6) /* SWD-only */\n#define WDATAERR        (1UL << 7) /* SWD-only */\n/* 11:8 - mask lanes for pushed compare or verify ops */\n/* 21:12 - transaction counter */\n#define CDBGRSTREQ      (1UL << 26)\n#define CDBGRSTACK      (1UL << 27)\n#define CDBGPWRUPREQ    (1UL << 28)\n#define CDBGPWRUPACK    (1UL << 29)\n#define CSYSPWRUPREQ    (1UL << 30)\n#define CSYSPWRUPACK    (1UL << 31)\n\n#define DP_DLPIDR_PROTVSN\t1u\n\n#define DP_SELECT_APSEL 0xFF000000\n#define DP_SELECT_APBANK 0x000000F0\n#define DP_SELECT_DPBANK 0x0000000F\n#define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */\n\n#define DP_APSEL_MAX        (255) /* for ADIv5 only */\n#define DP_APSEL_INVALID    0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */\n\n#define DP_TARGETSEL_INVALID 0xFFFFFFFFU\n#define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU\n#define DP_TARGETSEL_INSTANCEID_MASK 0xF0000000U\n#define DP_TARGETSEL_INSTANCEID_SHIFT 28\n\n\n/* MEM-AP register addresses */\n#define ADIV5_MEM_AP_REG_CSW    (0x00)\n#define ADIV5_MEM_AP_REG_TAR    (0x04)\n#define ADIV5_MEM_AP_REG_TAR64  (0x08)\t\t/* RW: Large Physical Address Extension */\n#define ADIV5_MEM_AP_REG_DRW    (0x0C)\t\t/* RW: Data Read/Write register */\n#define ADIV5_MEM_AP_REG_BD0    (0x10)\t\t/* RW: Banked Data register 0-3 */\n#define ADIV5_MEM_AP_REG_BD1    (0x14)\n#define ADIV5_MEM_AP_REG_BD2    (0x18)\n#define ADIV5_MEM_AP_REG_BD3    (0x1C)\n#define ADIV5_MEM_AP_REG_MBT    (0x20)\t\t/* --: Memory Barrier Transfer register */\n#define ADIV5_MEM_AP_REG_BASE64 (0xF0)\t\t/* RO: Debug Base Address (LA) register */\n#define ADIV5_MEM_AP_REG_CFG    (0xF4)\t\t/* RO: Configuration register */\n#define ADIV5_MEM_AP_REG_BASE   (0xF8)\t\t/* RO: Debug Base Address register */\n\n#define ADIV6_MEM_AP_REG_CSW    (0xD00 + ADIV5_MEM_AP_REG_CSW)\n#define ADIV6_MEM_AP_REG_TAR    (0xD00 + ADIV5_MEM_AP_REG_TAR)\n#define ADIV6_MEM_AP_REG_TAR64  (0xD00 + ADIV5_MEM_AP_REG_TAR64)\n#define ADIV6_MEM_AP_REG_DRW    (0xD00 + ADIV5_MEM_AP_REG_DRW)\n#define ADIV6_MEM_AP_REG_BD0    (0xD00 + ADIV5_MEM_AP_REG_BD0)\n#define ADIV6_MEM_AP_REG_BD1    (0xD00 + ADIV5_MEM_AP_REG_BD1)\n#define ADIV6_MEM_AP_REG_BD2    (0xD00 + ADIV5_MEM_AP_REG_BD2)\n#define ADIV6_MEM_AP_REG_BD3    (0xD00 + ADIV5_MEM_AP_REG_BD3)\n#define ADIV6_MEM_AP_REG_MBT    (0xD00 + ADIV5_MEM_AP_REG_MBT)\n#define ADIV6_MEM_AP_REG_BASE64 (0xD00 + ADIV5_MEM_AP_REG_BASE64)\n#define ADIV6_MEM_AP_REG_CFG    (0xD00 + ADIV5_MEM_AP_REG_CFG)\n#define ADIV6_MEM_AP_REG_BASE   (0xD00 + ADIV5_MEM_AP_REG_BASE)\n\n#define MEM_AP_REG_CSW(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CSW    : ADIV5_MEM_AP_REG_CSW)\n#define MEM_AP_REG_TAR(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR    : ADIV5_MEM_AP_REG_TAR)\n#define MEM_AP_REG_TAR64(dap)   (is_adiv6(dap) ? ADIV6_MEM_AP_REG_TAR64  : ADIV5_MEM_AP_REG_TAR64)\n#define MEM_AP_REG_DRW(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_DRW    : ADIV5_MEM_AP_REG_DRW)\n#define MEM_AP_REG_BD0(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD0    : ADIV5_MEM_AP_REG_BD0)\n#define MEM_AP_REG_BD1(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD1    : ADIV5_MEM_AP_REG_BD1)\n#define MEM_AP_REG_BD2(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD2    : ADIV5_MEM_AP_REG_BD2)\n#define MEM_AP_REG_BD3(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BD3    : ADIV5_MEM_AP_REG_BD3)\n#define MEM_AP_REG_MBT(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_MBT    : ADIV5_MEM_AP_REG_MBT)\n#define MEM_AP_REG_BASE64(dap)  (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE64 : ADIV5_MEM_AP_REG_BASE64)\n#define MEM_AP_REG_CFG(dap)     (is_adiv6(dap) ? ADIV6_MEM_AP_REG_CFG    : ADIV5_MEM_AP_REG_CFG)\n#define MEM_AP_REG_BASE(dap)    (is_adiv6(dap) ? ADIV6_MEM_AP_REG_BASE   : ADIV5_MEM_AP_REG_BASE)\n\n/* Generic AP register address */\n#define ADIV5_AP_REG_IDR        (0xFC)\t\t/* RO: Identification Register */\n#define ADIV6_AP_REG_IDR        (0xD00 + ADIV5_AP_REG_IDR)\n#define AP_REG_IDR(dap)         (is_adiv6(dap) ? ADIV6_AP_REG_IDR : ADIV5_AP_REG_IDR)\n\n/* Fields of the MEM-AP's CSW register */\n#define CSW_SIZE_MASK\t\t7\n#define CSW_8BIT\t\t0\n#define CSW_16BIT\t\t1\n#define CSW_32BIT\t\t2\n#define CSW_ADDRINC_MASK    (3UL << 4)\n#define CSW_ADDRINC_OFF     0UL\n#define CSW_ADDRINC_SINGLE  (1UL << 4)\n#define CSW_ADDRINC_PACKED  (2UL << 4)\n#define CSW_DEVICE_EN       (1UL << 6)\n#define CSW_TRIN_PROG       (1UL << 7)\n\n/* All fields in bits 12 and above are implementation-defined\n * Defaults for AHB/AXI in \"Standard Memory Access Port Definitions\" from ADI\n * Some bits are shared between buses\n */\n#define CSW_SPIDEN          (1UL << 23)\n#define CSW_DBGSWENABLE     (1UL << 31)\n\n/* AHB: Privileged */\n#define CSW_AHB_HPROT1          (1UL << 25)\n/* AHB: set HMASTER signals to AHB-AP ID */\n#define CSW_AHB_MASTER_DEBUG    (1UL << 29)\n/* AHB5: non-secure access via HNONSEC\n * AHB3: SBO, UNPREDICTABLE if zero */\n#define CSW_AHB_SPROT           (1UL << 30)\n/* AHB: initial value of csw_default */\n#define CSW_AHB_DEFAULT         (CSW_AHB_HPROT1 | CSW_AHB_MASTER_DEBUG | CSW_DBGSWENABLE)\n\n/* AXI: Privileged */\n#define CSW_AXI_ARPROT0_PRIV    (1UL << 28)\n/* AXI: Non-secure */\n#define CSW_AXI_ARPROT1_NONSEC  (1UL << 29)\n/* AXI: initial value of csw_default */\n#define CSW_AXI_DEFAULT         (CSW_AXI_ARPROT0_PRIV | CSW_AXI_ARPROT1_NONSEC | CSW_DBGSWENABLE)\n\n/* APB: initial value of csw_default */\n#define CSW_APB_DEFAULT         (CSW_DBGSWENABLE)\n\n/* Fields of the MEM-AP's CFG register */\n#define MEM_AP_REG_CFG_BE       BIT(0)\n#define MEM_AP_REG_CFG_LA       BIT(1)\n#define MEM_AP_REG_CFG_LD       BIT(2)\n#define MEM_AP_REG_CFG_INVALID  0xFFFFFFF8\n\n/* Fields of the MEM-AP's IDR register */\n#define AP_REG_IDR_REVISION_MASK        (0xF0000000)\n#define AP_REG_IDR_REVISION_SHIFT       (28)\n#define AP_REG_IDR_DESIGNER_MASK        (0x0FFE0000)\n#define AP_REG_IDR_DESIGNER_SHIFT       (17)\n#define AP_REG_IDR_CLASS_MASK           (0x0001E000)\n#define AP_REG_IDR_CLASS_SHIFT          (13)\n#define AP_REG_IDR_VARIANT_MASK         (0x000000F0)\n#define AP_REG_IDR_VARIANT_SHIFT        (4)\n#define AP_REG_IDR_TYPE_MASK            (0x0000000F)\n#define AP_REG_IDR_TYPE_SHIFT           (0)\n\n#define AP_REG_IDR_CLASS_NONE           (0x0)\n#define AP_REG_IDR_CLASS_COM            (0x1)\n#define AP_REG_IDR_CLASS_MEM_AP         (0x8)\n\n#define AP_REG_IDR_VALUE(d, c, t) (\\\n\t(((d) << AP_REG_IDR_DESIGNER_SHIFT) & AP_REG_IDR_DESIGNER_MASK) | \\\n\t(((c) << AP_REG_IDR_CLASS_SHIFT) & AP_REG_IDR_CLASS_MASK) | \\\n\t(((t) << AP_REG_IDR_TYPE_SHIFT) & AP_REG_IDR_TYPE_MASK) \\\n)\n\n#define AP_TYPE_MASK (AP_REG_IDR_DESIGNER_MASK | AP_REG_IDR_CLASS_MASK | AP_REG_IDR_TYPE_MASK)\n\n/* FIXME: not SWD specific; should be renamed, e.g. adiv5_special_seq */\nenum swd_special_seq {\n\tLINE_RESET,\n\tJTAG_TO_SWD,\n\tJTAG_TO_DORMANT,\n\tSWD_TO_JTAG,\n\tSWD_TO_DORMANT,\n\tDORMANT_TO_SWD,\n\tDORMANT_TO_JTAG,\n};\n\n/**\n * This represents an ARM Debug Interface (v5) Access Port (AP).\n * Most common is a MEM-AP, for memory access.\n */\nstruct adiv5_ap {\n\t/**\n\t * DAP this AP belongs to.\n\t */\n\tstruct adiv5_dap *dap;\n\n\t/**\n\t * ADIv5: Number of this AP (0~255)\n\t * ADIv6: Base address of this AP (4k aligned)\n\t * TODO: to be more coherent, it should be renamed apsel\n\t */\n\tuint64_t ap_num;\n\n\t/**\n\t * Default value for (MEM-AP) AP_REG_CSW register.\n\t */\n\tuint32_t csw_default;\n\n\t/**\n\t * Cache for (MEM-AP) AP_REG_CSW register value.  This is written to\n\t * configure an access mode, such as autoincrementing AP_REG_TAR during\n\t * word access.  \"-1\" indicates no cached value.\n\t */\n\tuint32_t csw_value;\n\n\t/**\n\t * Cache for (MEM-AP) AP_REG_TAR register value This is written to\n\t * configure the address being read or written\n\t * \"-1\" indicates no cached value.\n\t */\n\ttarget_addr_t tar_value;\n\n\t/**\n\t * Configures how many extra tck clocks are added after starting a\n\t * MEM-AP access before we try to read its status (and/or result).\n\t */\n\tuint32_t memaccess_tck;\n\n\t/* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */\n\tuint32_t tar_autoincr_block;\n\n\t/* true if packed transfers are supported by the MEM-AP */\n\tbool packed_transfers;\n\n\t/* true if unaligned memory access is not supported by the MEM-AP */\n\tbool unaligned_access_bad;\n\n\t/* true if tar_value is in sync with TAR register */\n\tbool tar_valid;\n\n\t/* MEM AP configuration register indicating LPAE support */\n\tuint32_t cfg_reg;\n\n\t/* references counter */\n\tunsigned int refcount;\n\n\t/* AP referenced during config. Never put it, even when refcount reaches zero */\n\tbool config_ap_never_release;\n};\n\n\n/**\n * This represents an ARM Debug Interface (v5) Debug Access Port (DAP).\n * A DAP has two types of component:  one Debug Port (DP), which is a\n * transport agent; and at least one Access Port (AP), controlling\n * resource access.\n *\n * There are two basic DP transports: JTAG, and ARM's low pin-count SWD.\n * Accordingly, this interface is responsible for hiding the transport\n * differences so upper layer code can largely ignore them.\n *\n * When the chip is implemented with JTAG-DP or SW-DP, the transport is\n * fixed as JTAG or SWD, respectively.  Chips incorporating SWJ-DP permit\n * a choice made at board design time (by only using the SWD pins), or\n * as part of setting up a debug session (if all the dual-role JTAG/SWD\n * signals are available).\n */\nstruct adiv5_dap {\n\tconst struct dap_ops *ops;\n\n\t/* dap transaction list for WAIT support */\n\tstruct list_head cmd_journal;\n\n\t/* pool for dap_cmd objects */\n\tstruct list_head cmd_pool;\n\n\t/* number of dap_cmd objects in the pool */\n\tsize_t cmd_pool_size;\n\n\tstruct jtag_tap *tap;\n\t/* Control config */\n\tuint32_t dp_ctrl_stat;\n\n\tstruct adiv5_ap ap[DP_APSEL_MAX + 1];\n\n\t/* The current manually selected AP by the \"dap apsel\" command */\n\tuint64_t apsel;\n\n\t/**\n\t * Cache for DP_SELECT register. A value of DP_SELECT_INVALID\n\t * indicates no cached value and forces rewrite of the register.\n\t */\n\tuint64_t select;\n\n\t/* information about current pending SWjDP-AHBAP transaction */\n\tuint8_t  ack;\n\n\t/**\n\t * Holds the pointer to the destination word for the last queued read,\n\t * for use with posted AP read sequence optimization.\n\t */\n\tuint32_t *last_read;\n\n\t/* The TI TMS470 and TMS570 series processors use a BE-32 memory ordering\n\t * despite lack of support in the ARMv7 architecture. Memory access through\n\t * the AHB-AP has strange byte ordering these processors, and we need to\n\t * swizzle appropriately. */\n\tbool ti_be_32_quirks;\n\n\t/* The Nuvoton NPCX M4 has an issue with writing to non-4-byte-aligned mmios.\n\t * The work around is to repeat the data in all 4 bytes of DRW */\n\tbool nu_npcx_quirks;\n\n\t/**\n\t * STLINK adapter need to know if last AP operation was read or write, and\n\t * in case of write has to flush it with a dummy read from DP_RDBUFF\n\t */\n\tbool stlink_flush_ap_write;\n\n\t/**\n\t * Signals that an attempt to reestablish communication afresh\n\t * should be performed before the next access.\n\t */\n\tbool do_reconnect;\n\n\t/** Flag saying whether to ignore the syspwrupack flag in DAP. Some devices\n\t *  do not set this bit until later in the bringup sequence */\n\tbool ignore_syspwrupack;\n\n\t/** Value to select DP in SWD multidrop mode or DP_TARGETSEL_INVALID */\n\tuint32_t multidrop_targetsel;\n\t/** TPARTNO and TDESIGNER fields of multidrop_targetsel have been configured */\n\tbool multidrop_dp_id_valid;\n\t/** TINSTANCE field of multidrop_targetsel has been configured */\n\tbool multidrop_instance_id_valid;\n\n\t/**\n\t * Record if enter in SWD required passing through DORMANT\n\t */\n\tbool switch_through_dormant;\n\n\t/** Indicates ADI version (5, 6 or 0 for unknown) being used */\n\tunsigned int adi_version;\n\n\t/* ADIv6 only field indicating ROM Table address size */\n\tunsigned int asize;\n};\n\n/**\n * Transport-neutral representation of queued DAP transactions, supporting\n * both JTAG and SWD transports.  All submitted transactions are logically\n * queued, until the queue is executed by run().  Some implementations might\n * execute transactions as soon as they're submitted, but no status is made\n * available until run().\n */\nstruct dap_ops {\n\t/** connect operation for SWD */\n\tint (*connect)(struct adiv5_dap *dap);\n\n\t/** send a sequence to the DAP */\n\tint (*send_sequence)(struct adiv5_dap *dap, enum swd_special_seq seq);\n\n\t/** DP register read. */\n\tint (*queue_dp_read)(struct adiv5_dap *dap, unsigned reg,\n\t\t\tuint32_t *data);\n\t/** DP register write. */\n\tint (*queue_dp_write)(struct adiv5_dap *dap, unsigned reg,\n\t\t\tuint32_t data);\n\n\t/** AP register read. */\n\tint (*queue_ap_read)(struct adiv5_ap *ap, unsigned reg,\n\t\t\tuint32_t *data);\n\t/** AP register write. */\n\tint (*queue_ap_write)(struct adiv5_ap *ap, unsigned reg,\n\t\t\tuint32_t data);\n\n\t/** AP operation abort. */\n\tint (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack);\n\n\t/** Executes all queued DAP operations. */\n\tint (*run)(struct adiv5_dap *dap);\n\n\t/** Executes all queued DAP operations but doesn't check\n\t * sticky error conditions */\n\tint (*sync)(struct adiv5_dap *dap);\n\n\t/** Optional; called at OpenOCD exit */\n\tvoid (*quit)(struct adiv5_dap *dap);\n};\n\n/*\n * Access Port types\n */\nenum ap_type {\n\tAP_TYPE_JTAG_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_NONE,   0),  /* JTAG-AP */\n\tAP_TYPE_COM_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_COM,    0),  /* COM-AP */\n\tAP_TYPE_AHB3_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 1),  /* AHB3 Memory-AP */\n\tAP_TYPE_APB_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 2),  /* APB2 or APB3 Memory-AP */\n\tAP_TYPE_AXI_AP   = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 4),  /* AXI3 or AXI4 Memory-AP */\n\tAP_TYPE_AHB5_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 5),  /* AHB5 Memory-AP */\n\tAP_TYPE_APB4_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 6),  /* APB4 Memory-AP */\n\tAP_TYPE_AXI5_AP  = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 7),  /* AXI5 Memory-AP */\n\tAP_TYPE_AHB5H_AP = AP_REG_IDR_VALUE(ARM_ID, AP_REG_IDR_CLASS_MEM_AP, 8),  /* AHB5 with enhanced HPROT Memory-AP */\n};\n\nextern const struct dap_ops jtag_dp_ops;\nextern const struct dap_ops swd_dap_ops;\n\n/* Check the ap->cfg_reg Long Address field (bit 1)\n *\n * 0b0: The AP only supports physical addresses 32 bits or smaller\n * 0b1: The AP supports physical addresses larger than 32 bits\n *\n * @param ap The AP used for reading.\n *\n * @return true for 64 bit, false for 32 bit\n */\nstatic inline bool is_64bit_ap(struct adiv5_ap *ap)\n{\n\treturn (ap->cfg_reg & MEM_AP_REG_CFG_LA) != 0;\n}\n\n/**\n * Check if DAP is ADIv6\n *\n * @param dap The DAP to test\n *\n * @return true for ADIv6, false for either ADIv5 or unknown version\n */\nstatic inline bool is_adiv6(const struct adiv5_dap *dap)\n{\n\treturn dap->adi_version == 6;\n}\n\n/**\n * Send an adi-v5 sequence to the DAP.\n *\n * @param dap The DAP used for reading.\n * @param seq The sequence to send.\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_send_sequence(struct adiv5_dap *dap,\n\t\tenum swd_special_seq seq)\n{\n\tassert(dap->ops);\n\treturn dap->ops->send_sequence(dap, seq);\n}\n\n/**\n * Queue a DP register read.\n * Note that not all DP registers are readable; also, that JTAG and SWD\n * have slight differences in DP register support.\n *\n * @param dap The DAP used for reading.\n * @param reg The two-bit number of the DP register being read.\n * @param data Pointer saying where to store the register's value\n * (in host endianness).\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_queue_dp_read(struct adiv5_dap *dap,\n\t\tunsigned reg, uint32_t *data)\n{\n\tassert(dap->ops);\n\treturn dap->ops->queue_dp_read(dap, reg, data);\n}\n\n/**\n * Queue a DP register write.\n * Note that not all DP registers are writable; also, that JTAG and SWD\n * have slight differences in DP register support.\n *\n * @param dap The DAP used for writing.\n * @param reg The two-bit number of the DP register being written.\n * @param data Value being written (host endianness)\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_queue_dp_write(struct adiv5_dap *dap,\n\t\tunsigned reg, uint32_t data)\n{\n\tassert(dap->ops);\n\treturn dap->ops->queue_dp_write(dap, reg, data);\n}\n\n/**\n * Queue an AP register read.\n *\n * @param ap The AP used for reading.\n * @param reg The number of the AP register being read.\n * @param data Pointer saying where to store the register's value\n * (in host endianness).\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_queue_ap_read(struct adiv5_ap *ap,\n\t\tunsigned reg, uint32_t *data)\n{\n\tassert(ap->dap->ops);\n\tif (ap->refcount == 0) {\n\t\tap->refcount = 1;\n\t\tLOG_ERROR(\"BUG: refcount AP#0x%\" PRIx64 \" used without get\", ap->ap_num);\n\t}\n\treturn ap->dap->ops->queue_ap_read(ap, reg, data);\n}\n\n/**\n * Queue an AP register write.\n *\n * @param ap The AP used for writing.\n * @param reg The number of the AP register being written.\n * @param data Value being written (host endianness)\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_queue_ap_write(struct adiv5_ap *ap,\n\t\tunsigned reg, uint32_t data)\n{\n\tassert(ap->dap->ops);\n\tif (ap->refcount == 0) {\n\t\tap->refcount = 1;\n\t\tLOG_ERROR(\"BUG: refcount AP#0x%\" PRIx64 \" used without get\", ap->ap_num);\n\t}\n\treturn ap->dap->ops->queue_ap_write(ap, reg, data);\n}\n\n/**\n * Queue an AP abort operation.  The current AP transaction is aborted,\n * including any update of the transaction counter.  The AP is left in\n * an unknown state (so it must be re-initialized).  For use only after\n * the AP has reported WAIT status for an extended period.\n *\n * @param dap The DAP used for writing.\n * @param ack Pointer to where transaction status will be stored.\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)\n{\n\tassert(dap->ops);\n\treturn dap->ops->queue_ap_abort(dap, ack);\n}\n\n/**\n * Perform all queued DAP operations, and clear any errors posted in the\n * CTRL_STAT register when they are done.  Note that if more than one AP\n * operation will be queued, one of the first operations in the queue\n * should probably enable CORUNDETECT in the CTRL/STAT register.\n *\n * @param dap The DAP used.\n *\n * @return ERROR_OK for success, else a fault code.\n */\nstatic inline int dap_run(struct adiv5_dap *dap)\n{\n\tassert(dap->ops);\n\treturn dap->ops->run(dap);\n}\n\nstatic inline int dap_sync(struct adiv5_dap *dap)\n{\n\tassert(dap->ops);\n\tif (dap->ops->sync)\n\t\treturn dap->ops->sync(dap);\n\treturn ERROR_OK;\n}\n\nstatic inline int dap_dp_read_atomic(struct adiv5_dap *dap, unsigned reg,\n\t\t\t\t     uint32_t *value)\n{\n\tint retval;\n\n\tretval = dap_queue_dp_read(dap, reg, value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dap_run(dap);\n}\n\nstatic inline int dap_dp_poll_register(struct adiv5_dap *dap, unsigned reg,\n\t\t\t\t       uint32_t mask, uint32_t value, int timeout)\n{\n\tassert(timeout > 0);\n\tassert((value & mask) == value);\n\n\tint ret;\n\tuint32_t regval;\n\tLOG_DEBUG(\"DAP: poll %x, mask 0x%08\" PRIx32 \", value 0x%08\" PRIx32,\n\t\t  reg, mask, value);\n\tdo {\n\t\tret = dap_dp_read_atomic(dap, reg, &regval);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif ((regval & mask) == value)\n\t\t\tbreak;\n\n\t\talive_sleep(10);\n\t} while (--timeout);\n\n\tif (!timeout) {\n\t\tLOG_DEBUG(\"DAP: poll %x timeout\", reg);\n\t\treturn ERROR_WAIT;\n\t} else {\n\t\treturn ERROR_OK;\n\t}\n}\n\n/* Queued MEM-AP memory mapped single word transfers. */\nint mem_ap_read_u32(struct adiv5_ap *ap,\n\t\ttarget_addr_t address, uint32_t *value);\nint mem_ap_write_u32(struct adiv5_ap *ap,\n\t\ttarget_addr_t address, uint32_t value);\n\n/* Synchronous MEM-AP memory mapped single word transfers. */\nint mem_ap_read_atomic_u32(struct adiv5_ap *ap,\n\t\ttarget_addr_t address, uint32_t *value);\nint mem_ap_write_atomic_u32(struct adiv5_ap *ap,\n\t\ttarget_addr_t address, uint32_t value);\n\n/* Synchronous MEM-AP memory mapped bus block transfers. */\nint mem_ap_read_buf(struct adiv5_ap *ap,\n\t\tuint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address);\nint mem_ap_write_buf(struct adiv5_ap *ap,\n\t\tconst uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address);\n\n/* Synchronous, non-incrementing buffer functions for accessing fifos. */\nint mem_ap_read_buf_noincr(struct adiv5_ap *ap,\n\t\tuint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address);\nint mem_ap_write_buf_noincr(struct adiv5_ap *ap,\n\t\tconst uint8_t *buffer, uint32_t size, uint32_t count, target_addr_t address);\n\n/* Initialisation of the debug system, power domains and registers */\nint dap_dp_init(struct adiv5_dap *dap);\nint dap_dp_init_or_reconnect(struct adiv5_dap *dap);\nint mem_ap_init(struct adiv5_ap *ap);\n\n/* Invalidate cached DP select and cached TAR and CSW of all APs */\nvoid dap_invalidate_cache(struct adiv5_dap *dap);\n\n/* read ADIv6 baseptr register */\nint adiv6_dap_read_baseptr(struct command_invocation *cmd, struct adiv5_dap *dap, target_addr_t *baseptr);\n\n/* test if ap_num is valid, based on current knowledge of dap */\nbool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num);\n\n/* Probe Access Ports to find a particular type. Increment AP refcount */\nint dap_find_get_ap(struct adiv5_dap *dap,\n\t\t\tenum ap_type type_to_find,\n\t\t\tstruct adiv5_ap **ap_out);\n\n/* Return AP with specified ap_num. Increment AP refcount */\nstruct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num);\n\n/* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */\nstruct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num);\n\n/* Decrement AP refcount and release the AP when refcount reaches zero */\nint dap_put_ap(struct adiv5_ap *ap);\n\n/** Check if SWD multidrop configuration is valid */\nstatic inline bool dap_is_multidrop(struct adiv5_dap *dap)\n{\n\treturn dap->multidrop_dp_id_valid && dap->multidrop_instance_id_valid;\n}\n\n/* Lookup CoreSight component */\nint dap_lookup_cs_component(struct adiv5_ap *ap,\n\t\t\tuint8_t type, target_addr_t *addr, int32_t idx);\n\nstruct target;\n\n/* Put debug link into SWD mode */\nint dap_to_swd(struct adiv5_dap *dap);\n\n/* Put debug link into JTAG mode */\nint dap_to_jtag(struct adiv5_dap *dap);\n\nextern const struct command_registration dap_instance_commands[];\n\nstruct arm_dap_object;\nextern struct adiv5_dap *dap_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o);\nextern struct adiv5_dap *adiv5_get_dap(struct arm_dap_object *obj);\nextern int dap_info_command(struct command_invocation *cmd,\n\t\t\t\t\t struct adiv5_ap *ap);\nextern int dap_register_commands(struct command_context *cmd_ctx);\nextern const char *adiv5_dap_name(struct adiv5_dap *self);\nextern const struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self);\nextern int dap_cleanup_all(void);\n\nstruct adiv5_private_config {\n\tuint64_t ap_num;\n\tstruct adiv5_dap *dap;\n};\n\nextern int adiv5_verify_config(struct adiv5_private_config *pc);\nextern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *goi);\n\nstruct adiv5_mem_ap_spot {\n\tstruct adiv5_dap *dap;\n\tuint64_t ap_num;\n\tuint32_t base;\n};\n\nextern int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p);\nextern int adiv5_jim_mem_ap_spot_configure(struct adiv5_mem_ap_spot *cfg,\n\t\tstruct jim_getopt_info *goi);\n\n#endif /* OPENOCD_TARGET_ARM_ADI_V5_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_coresight.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * General info from:\n * ARM CoreSight Architecture Specification v3.0 IHI0029E\n */\n\n#ifndef OPENOCD_TARGET_ARM_CORESIGHT_H\n#define OPENOCD_TARGET_ARM_CORESIGHT_H\n\n#include <stdbool.h>\n#include <stdint.h>\n\n#include <helper/bits.h>\n\n#define ARM_CS_ALIGN                            (0x1000)\n\n/* mandatory registers */\n#define ARM_CS_PIDR0                            (0xFE0)\n#define ARM_CS_PIDR1                            (0xFE4)\n#define ARM_CS_PIDR2                            (0xFE8)\n#define ARM_CS_PIDR3                            (0xFEC)\n#define ARM_CS_PIDR4                            (0xFD0)\n#define ARM_CS_PIDR5                            (0xFD4)\n#define ARM_CS_PIDR6                            (0xFD8)\n#define ARM_CS_PIDR7                            (0xFDC)\n\n/*\n * When PIDR bit JEDEC is zero, only the lowers 7 bits of DESIGNER are valid\n * and represent a legacy ASCII Identity Code.\n */\n#define ARM_CS_PIDR_PART(pidr)                  ((pidr) & 0x0FFF)\n#define ARM_CS_PIDR_DESIGNER(pidr)              \\\n({                                              \\\n\ttypeof(pidr) _x = (pidr);                   \\\n\t((_x >> 25) & 0x780) | ((_x >> 12) & 0x7F); \\\n})\n#define ARM_CS_PIDR_JEDEC                       BIT(19)\n#define ARM_CS_PIDR_SIZE(pidr)                  (((pidr) >> 36) & 0x000F)\n\n#define ARM_CS_CIDR0                            (0xFF0)\n#define ARM_CS_CIDR1                            (0xFF4)\n#define ARM_CS_CIDR2                            (0xFF8)\n#define ARM_CS_CIDR3                            (0xFFC)\n\n#define ARM_CS_CIDR_CLASS_MASK                  (0x0000F000)\n#define ARM_CS_CIDR_CLASS(cidr)                 (((cidr) >> 12) & 0x000F)\n#define ARM_CS_CLASS_0X1_ROM_TABLE              (0x1)\n#define ARM_CS_CLASS_0X9_CS_COMPONENT           (0x9)\n\nstatic inline bool is_valid_arm_cs_cidr(uint32_t cidr)\n{\n\treturn (cidr & ~ARM_CS_CIDR_CLASS_MASK) == 0xB105000D;\n}\n\n/* Class 0x9 only registers */\n#define ARM_CS_C9_DEVARCH                       (0xFBC)\n\n#define ARM_CS_C9_DEVARCH_ARCHID_MASK           (0x0000FFFF)\n#define ARM_CS_C9_DEVARCH_ARCHID_SHIFT          (0)\n#define ARM_CS_C9_DEVARCH_REVISION_MASK         (0x000F0000)\n#define ARM_CS_C9_DEVARCH_REVISION_SHIFT        (16)\n#define ARM_CS_C9_DEVARCH_PRESENT               BIT(20)\n#define ARM_CS_C9_DEVARCH_ARCHITECT_MASK        (0xFFE00000)\n#define ARM_CS_C9_DEVARCH_ARCHITECT_SHIFT       (21)\n#define ARM_CS_C9_DEVARCH_REVISION(devarch)     \\\n\t(((devarch) & ARM_CS_C9_DEVARCH_REVISION_MASK) >> ARM_CS_C9_DEVARCH_REVISION_SHIFT)\n#define ARM_CS_C9_DEVARCH_ARCHITECT(devarch)    \\\n\t(((devarch) & ARM_CS_C9_DEVARCH_ARCHITECT_MASK) >> ARM_CS_C9_DEVARCH_ARCHITECT_SHIFT)\n\n#define ARM_CS_C9_DEVID                         (0xFC8)\n\n#define ARM_CS_C9_DEVID_FORMAT_MASK             (0x0000000F)\n#define ARM_CS_C9_DEVID_FORMAT_32BIT            (0)\n#define ARM_CS_C9_DEVID_FORMAT_64BIT            (1)\n#define ARM_CS_C9_DEVID_SYSMEM_MASK             BIT(4)\n#define ARM_CS_C9_DEVID_PRR_MASK                BIT(5)\n#define ARM_CS_C9_DEVID_CP_MASK                 BIT(5)\n\n#define ARM_CS_C9_DEVTYPE                       (0xFCC)\n\n#define ARM_CS_C9_DEVTYPE_MAJOR_MASK            (0x0000000F)\n#define ARM_CS_C9_DEVTYPE_MAJOR_SHIFT           (0)\n#define ARM_CS_C9_DEVTYPE_SUB_MASK              (0x000000F0)\n#define ARM_CS_C9_DEVTYPE_SUB_SHIFT             (4)\n\n#define ARM_CS_C9_DEVTYPE_MASK                  (0x000000FF)\n#define ARM_CS_C9_DEVTYPE_CORE_DEBUG            (0x00000015)\n\n/* Class 0x1 only registers */\n#define ARM_CS_C1_MEMTYPE                       ARM_CS_C9_DEVTYPE\n\n#define ARM_CS_C1_MEMTYPE_SYSMEM_MASK           BIT(0)\n\n/* The coding of ROM entry present differs between Class 0x9 and Class 0x1,\n * but we can simplify the whole management */\n#define ARM_CS_ROMENTRY_PRESENT                 BIT(0)\n#define ARM_CS_ROMENTRY_OFFSET_MASK             (0xFFFFF000U)\n\n#endif /* OPENOCD_TARGET_ARM_CORESIGHT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_cti.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <stdint.h>\n#include \"target/arm_adi_v5.h\"\n#include \"target/arm_cti.h\"\n#include \"target/target.h\"\n#include \"helper/time_support.h\"\n#include \"helper/list.h\"\n#include \"helper/command.h\"\n\nstruct arm_cti {\n\tstruct list_head lh;\n\tchar *name;\n\tstruct adiv5_mem_ap_spot spot;\n\tstruct adiv5_ap *ap;\n};\n\nstatic LIST_HEAD(all_cti);\n\nconst char *arm_cti_name(struct arm_cti *self)\n{\n\treturn self->name;\n}\n\nstruct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)\n{\n\tstruct arm_cti *obj = NULL;\n\tconst char *name;\n\tbool found = false;\n\n\tname = Jim_GetString(o, NULL);\n\n\tlist_for_each_entry(obj, &all_cti, lh) {\n\t\tif (!strcmp(name, obj->name)) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (found)\n\t\treturn obj;\n\treturn NULL;\n}\n\nstatic int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)\n{\n\tstruct adiv5_ap *ap = self->ap;\n\tuint32_t tmp;\n\n\t/* Read register */\n\tint retval = mem_ap_read_atomic_u32(ap, self->spot.base + reg, &tmp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* clear bitfield */\n\ttmp &= ~mask;\n\t/* put new value */\n\ttmp |= value & mask;\n\n\t/* write new value */\n\treturn mem_ap_write_atomic_u32(ap, self->spot.base + reg, tmp);\n}\n\nint arm_cti_enable(struct arm_cti *self, bool enable)\n{\n\tuint32_t val = enable ? 1 : 0;\n\n\treturn mem_ap_write_atomic_u32(self->ap, self->spot.base + CTI_CTR, val);\n}\n\nint arm_cti_ack_events(struct arm_cti *self, uint32_t event)\n{\n\tstruct adiv5_ap *ap = self->ap;\n\tint retval;\n\tuint32_t tmp;\n\n\tretval = mem_ap_write_atomic_u32(ap, self->spot.base + CTI_INACK, event);\n\tif (retval == ERROR_OK) {\n\t\tint64_t then = timeval_ms();\n\t\tfor (;;) {\n\t\t\tretval = mem_ap_read_atomic_u32(ap, self->spot.base + CTI_TROUT_STATUS, &tmp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\t\t\tif ((tmp & event) == 0)\n\t\t\t\tbreak;\n\t\t\tif (timeval_ms() > then + 1000) {\n\t\t\t\tLOG_ERROR(\"timeout waiting for target\");\n\t\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint arm_cti_gate_channel(struct arm_cti *self, uint32_t channel)\n{\n\tif (channel > 31)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn arm_cti_mod_reg_bits(self, CTI_GATE, CTI_CHNL(channel), 0);\n}\n\nint arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel)\n{\n\tif (channel > 31)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn arm_cti_mod_reg_bits(self, CTI_GATE, CTI_CHNL(channel), 0xFFFFFFFF);\n}\n\nint arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value)\n{\n\treturn mem_ap_write_atomic_u32(self->ap, self->spot.base + reg, value);\n}\n\nint arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)\n{\n\tif (!p_value)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn mem_ap_read_atomic_u32(self->ap, self->spot.base + reg, p_value);\n}\n\nint arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)\n{\n\tif (channel > 31)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn arm_cti_write_reg(self, CTI_APPPULSE, CTI_CHNL(channel));\n}\n\nint arm_cti_set_channel(struct arm_cti *self, uint32_t channel)\n{\n\tif (channel > 31)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn arm_cti_write_reg(self, CTI_APPSET, CTI_CHNL(channel));\n}\n\nint arm_cti_clear_channel(struct arm_cti *self, uint32_t channel)\n{\n\tif (channel > 31)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treturn arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel));\n}\n\nstatic uint32_t cti_regs[28];\n\nstatic const struct {\n\tuint32_t offset;\n\tconst char *label;\n\tuint32_t *p_val;\n} cti_names[] = {\n\t{ CTI_CTR,\t\t\"CTR\",\t\t&cti_regs[0] },\n\t{ CTI_GATE,\t\t\"GATE\",\t\t&cti_regs[1] },\n\t{ CTI_INEN0,\t\"INEN0\",\t&cti_regs[2] },\n\t{ CTI_INEN1,\t\"INEN1\",\t&cti_regs[3] },\n\t{ CTI_INEN2,\t\"INEN2\",\t&cti_regs[4] },\n\t{ CTI_INEN3,\t\"INEN3\",\t&cti_regs[5] },\n\t{ CTI_INEN4,\t\"INEN4\",\t&cti_regs[6] },\n\t{ CTI_INEN5,\t\"INEN5\",\t&cti_regs[7] },\n\t{ CTI_INEN6,\t\"INEN6\",\t&cti_regs[8] },\n\t{ CTI_INEN7,\t\"INEN7\",\t&cti_regs[9] },\n\t{ CTI_INEN8,\t\"INEN8\",\t&cti_regs[10] },\n\t{ CTI_OUTEN0,\t\"OUTEN0\",\t&cti_regs[11] },\n\t{ CTI_OUTEN1,\t\"OUTEN1\",\t&cti_regs[12] },\n\t{ CTI_OUTEN2,\t\"OUTEN2\",\t&cti_regs[13] },\n\t{ CTI_OUTEN3,\t\"OUTEN3\",\t&cti_regs[14] },\n\t{ CTI_OUTEN4,\t\"OUTEN4\",\t&cti_regs[15] },\n\t{ CTI_OUTEN5,\t\"OUTEN5\",\t&cti_regs[16] },\n\t{ CTI_OUTEN6,\t\"OUTEN6\",\t&cti_regs[17] },\n\t{ CTI_OUTEN7,\t\"OUTEN7\",\t&cti_regs[18] },\n\t{ CTI_OUTEN8,\t\"OUTEN8\",\t&cti_regs[19] },\n\t{ CTI_TRIN_STATUS,\t\"TRIN\",\t&cti_regs[20] },\n\t{ CTI_TROUT_STATUS,\t\"TROUT\", &cti_regs[21] },\n\t{ CTI_CHIN_STATUS,\t\"CHIN\",\t&cti_regs[22] },\n\t{ CTI_CHOU_STATUS,\t\"CHOUT\", &cti_regs[23] },\n\t{ CTI_APPSET,\t\"APPSET\",\t&cti_regs[24] },\n\t{ CTI_APPCLEAR,\t\"APPCLR\",\t&cti_regs[25] },\n\t{ CTI_APPPULSE,\t\"APPPULSE\",\t&cti_regs[26] },\n\t{ CTI_INACK,\t\"INACK\",\t&cti_regs[27] },\n};\n\nstatic int cti_find_reg_offset(const char *name)\n{\n\tunsigned int i;\n\n\tfor (i = 0; i < ARRAY_SIZE(cti_names); i++) {\n\t\tif (!strcmp(name, cti_names[i].label))\n\t\t\treturn cti_names[i].offset;\n\t}\n\n\tLOG_ERROR(\"unknown CTI register %s\", name);\n\treturn -1;\n}\n\nint arm_cti_cleanup_all(void)\n{\n\tstruct arm_cti *obj, *tmp;\n\n\tlist_for_each_entry_safe(obj, tmp, &all_cti, lh) {\n\t\tif (obj->ap)\n\t\t\tdap_put_ap(obj->ap);\n\t\tfree(obj->name);\n\t\tfree(obj);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cti_dump)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tstruct adiv5_ap *ap = cti->ap;\n\tint retval = ERROR_OK;\n\n\tfor (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)\n\t\tretval = mem_ap_read_u32(ap,\n\t\t\t\tcti->spot.base + cti_names[i].offset, cti_names[i].p_val);\n\n\tif (retval == ERROR_OK)\n\t\tretval = dap_run(ap->dap);\n\n\tif (retval != ERROR_OK)\n\t\treturn JIM_ERR;\n\n\tfor (int i = 0; i < (int)ARRAY_SIZE(cti_names); i++)\n\t\tcommand_print(CMD, \"%8.8s (0x%04\"PRIx32\") 0x%08\"PRIx32,\n\t\t\t\tcti_names[i].label, cti_names[i].offset, *cti_names[i].p_val);\n\n\treturn JIM_OK;\n}\n\nCOMMAND_HANDLER(handle_cti_enable)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tbool on_off;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);\n\n\treturn arm_cti_enable(cti, on_off);\n}\n\nCOMMAND_HANDLER(handle_cti_testmode)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tbool on_off;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);\n\n\treturn arm_cti_write_reg(cti, 0xf00, on_off ? 0x1 : 0x0);\n}\n\nCOMMAND_HANDLER(handle_cti_write)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tint offset;\n\tuint32_t value;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\toffset = cti_find_reg_offset(CMD_ARGV[0]);\n\tif (offset < 0)\n\t\treturn ERROR_FAIL;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\treturn arm_cti_write_reg(cti, offset, value);\n}\n\nCOMMAND_HANDLER(handle_cti_read)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tint offset;\n\tint retval;\n\tuint32_t value;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\toffset = cti_find_reg_offset(CMD_ARGV[0]);\n\tif (offset < 0)\n\t\treturn ERROR_FAIL;\n\n\tretval = arm_cti_read_reg(cti, offset, &value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"0x%08\"PRIx32, value);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cti_ack)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tuint32_t event;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], event);\n\n\tint retval = arm_cti_ack_events(cti, 1 << event);\n\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cti_channel)\n{\n\tstruct arm_cti *cti = CMD_DATA;\n\tint retval = ERROR_OK;\n\tuint32_t ch_num;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ch_num);\n\n\tif (!strcmp(CMD_ARGV[1], \"gate\"))\n\t\tretval = arm_cti_gate_channel(cti, ch_num);\n\telse if (!strcmp(CMD_ARGV[1], \"ungate\"))\n\t\tretval = arm_cti_ungate_channel(cti, ch_num);\n\telse if (!strcmp(CMD_ARGV[1], \"pulse\"))\n\t\tretval = arm_cti_pulse_channel(cti, ch_num);\n\telse if (!strcmp(CMD_ARGV[1], \"set\"))\n\t\tretval = arm_cti_set_channel(cti, ch_num);\n\telse if (!strcmp(CMD_ARGV[1], \"clear\"))\n\t\tretval = arm_cti_clear_channel(cti, ch_num);\n\telse {\n\t\tcommand_print(CMD, \"Possible channel operations: gate|ungate|set|clear|pulse\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration cti_instance_command_handlers[] = {\n\t{\n\t\t.name  = \"dump\",\n\t\t.mode  = COMMAND_EXEC,\n\t\t.handler = handle_cti_dump,\n\t\t.help  = \"dump CTI registers\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"enable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_enable,\n\t\t.help = \"enable or disable the CTI\",\n\t\t.usage = \"'on'|'off'\",\n\t},\n\t{\n\t\t.name = \"testmode\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_testmode,\n\t\t.help = \"enable or disable integration test mode\",\n\t\t.usage = \"'on'|'off'\",\n\t},\n\t{\n\t\t.name = \"write\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_write,\n\t\t.help = \"write to a CTI register\",\n\t\t.usage = \"register_name value\",\n\t},\n\t{\n\t\t.name = \"read\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_read,\n\t\t.help = \"read a CTI register\",\n\t\t.usage = \"register_name\",\n\t},\n\t{\n\t\t.name = \"ack\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_ack,\n\t\t.help = \"acknowledge a CTI event\",\n\t\t.usage = \"event\",\n\t},\n\t{\n\t\t.name = \"channel\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_cti_channel,\n\t\t.help = \"do an operation on one CTI channel, possible operations: \"\n\t\t\t\t\"gate, ungate, set, clear and pulse\",\n\t\t.usage = \"channel_number operation\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int cti_configure(struct jim_getopt_info *goi, struct arm_cti *cti)\n{\n\t/* parse config or cget options ... */\n\twhile (goi->argc > 0) {\n\t\tint e = adiv5_jim_mem_ap_spot_configure(&cti->spot, goi);\n\n\t\tif (e == JIM_CONTINUE)\n\t\t\tJim_SetResultFormatted(goi->interp, \"unknown option '%s'\",\n\t\t\t\tJim_String(goi->argv[0]));\n\n\t\tif (e != JIM_OK)\n\t\t\treturn JIM_ERR;\n\t}\n\n\tif (!cti->spot.dap) {\n\t\tJim_SetResultString(goi->interp, \"-dap required when creating CTI\", -1);\n\t\treturn JIM_ERR;\n\t}\n\n\treturn JIM_OK;\n}\nstatic int cti_create(struct jim_getopt_info *goi)\n{\n\tstruct command_context *cmd_ctx;\n\tstatic struct arm_cti *cti;\n\tJim_Obj *new_cmd;\n\tJim_Cmd *cmd;\n\tconst char *cp;\n\tint e;\n\n\tcmd_ctx = current_command_context(goi->interp);\n\tassert(cmd_ctx);\n\n\tif (goi->argc < 3) {\n\t\tJim_WrongNumArgs(goi->interp, 1, goi->argv, \"?name? ..options...\");\n\t\treturn JIM_ERR;\n\t}\n\t/* COMMAND */\n\tjim_getopt_obj(goi, &new_cmd);\n\t/* does this command exist? */\n\tcmd = Jim_GetCommand(goi->interp, new_cmd, JIM_NONE);\n\tif (cmd) {\n\t\tcp = Jim_GetString(new_cmd, NULL);\n\t\tJim_SetResultFormatted(goi->interp, \"Command: %s Exists\", cp);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Create it */\n\tcti = calloc(1, sizeof(*cti));\n\tif (!cti)\n\t\treturn JIM_ERR;\n\n\tadiv5_mem_ap_spot_init(&cti->spot);\n\n\t/* Do the rest as \"configure\" options */\n\tgoi->isconfigure = 1;\n\te = cti_configure(goi, cti);\n\tif (e != JIM_OK) {\n\t\tfree(cti);\n\t\treturn e;\n\t}\n\n\tcp = Jim_GetString(new_cmd, NULL);\n\tcti->name = strdup(cp);\n\n\t/* now - create the new cti name command */\n\tconst struct command_registration cti_subcommands[] = {\n\t\t{\n\t\t\t.chain = cti_instance_command_handlers,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\tconst struct command_registration cti_commands[] = {\n\t\t{\n\t\t\t.name = cp,\n\t\t\t.mode = COMMAND_ANY,\n\t\t\t.help = \"cti instance command group\",\n\t\t\t.usage = \"\",\n\t\t\t.chain = cti_subcommands,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\te = register_commands_with_data(cmd_ctx, NULL, cti_commands, cti);\n\tif (e != ERROR_OK)\n\t\treturn JIM_ERR;\n\n\tlist_add_tail(&cti->lh, &all_cti);\n\n\tcti->ap = dap_get_ap(cti->spot.dap, cti->spot.ap_num);\n\tif (!cti->ap) {\n\t\tJim_SetResultString(goi->interp, \"Cannot get AP\", -1);\n\t\treturn JIM_ERR;\n\t}\n\n\treturn JIM_OK;\n}\n\nstatic int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tif (goi.argc < 2) {\n\t\tJim_WrongNumArgs(goi.interp, goi.argc, goi.argv,\n\t\t\t\"<name> [<cti_options> ...]\");\n\t\treturn JIM_ERR;\n\t}\n\treturn cti_create(&goi);\n}\n\nCOMMAND_HANDLER(cti_handle_names)\n{\n\tstruct arm_cti *obj;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(obj, &all_cti, lh)\n\t\tcommand_print(CMD, \"%s\", obj->name);\n\n\treturn ERROR_OK;\n}\n\n\nstatic const struct command_registration cti_subcommand_handlers[] = {\n\t{\n\t\t.name = \"create\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_cti_create,\n\t\t.usage = \"name '-chain-position' name [options ...]\",\n\t\t.help = \"Creates a new CTI object\",\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = cti_handle_names,\n\t\t.usage = \"\",\n\t\t.help = \"Lists all registered CTI objects by name\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration cti_command_handlers[] = {\n\t{\n\t\t.name = \"cti\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"CTI commands\",\n\t\t.chain = cti_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint cti_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, cti_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_cti.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *                                                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_CTI_H\n#define OPENOCD_TARGET_ARM_CTI_H\n\n/*define CTI(cross trigger interface)*/\n#define CTI_CTR\t\t\t\t0x0\n#define CTI_INACK\t\t\t0x10\n#define CTI_APPSET\t\t\t0x14\n#define CTI_APPCLEAR\t\t0x18\n#define CTI_APPPULSE\t\t0x1C\n#define CTI_INEN0\t\t\t0x20\n#define CTI_INEN1\t\t\t0x24\n#define CTI_INEN2\t\t\t0x28\n#define CTI_INEN3\t\t\t0x2C\n#define CTI_INEN4\t\t\t0x30\n#define CTI_INEN5\t\t\t0x34\n#define CTI_INEN6\t\t\t0x38\n#define CTI_INEN7\t\t\t0x3C\n#define CTI_INEN8\t\t\t0x40\n#define CTI_INEN(n)\t\t\t(0x20 + 4 * n)\n#define CTI_OUTEN0\t\t\t0xA0\n#define CTI_OUTEN1\t\t\t0xA4\n#define CTI_OUTEN2\t\t\t0xA8\n#define CTI_OUTEN3\t\t\t0xAC\n#define CTI_OUTEN4\t\t\t0xB0\n#define CTI_OUTEN5\t\t\t0xB4\n#define CTI_OUTEN6\t\t\t0xB8\n#define CTI_OUTEN7\t\t\t0xBC\n#define CTI_OUTEN8\t\t\t0xC0\n#define CTI_OUTEN(n)\t\t(0xA0 + 4 * n)\n#define CTI_TRIN_STATUS\t\t0x130\n#define CTI_TROUT_STATUS\t0x134\n#define CTI_CHIN_STATUS\t\t0x138\n#define CTI_CHOU_STATUS\t\t0x13C\n#define CTI_GATE\t\t\t0x140\n#define CTI_UNLOCK\t\t\t0xFB0\n\n#define CTI_CHNL(x)\t\t\t(1 << x)\n#define CTI_TRIG_HALT\t\t0\n#define CTI_TRIG_RESUME\t\t1\n#define CTI_TRIG(n)\t\t\t(1 << CTI_TRIG_##n)\n\n/* forward-declare arm_cti struct */\nstruct arm_cti;\nstruct adiv5_ap;\n\nextern const char *arm_cti_name(struct arm_cti *self);\nextern struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o);\nextern int arm_cti_enable(struct arm_cti *self, bool enable);\nextern int arm_cti_ack_events(struct arm_cti *self, uint32_t event);\nextern int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel);\nextern int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel);\nextern int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value);\nextern int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *value);\nextern int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel);\nextern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel);\nextern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel);\nextern int arm_cti_cleanup_all(void);\nextern int cti_register_commands(struct command_context *cmd_ctx);\n\n#endif /* OPENOCD_TARGET_ARM_CTI_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_dap.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <stdint.h>\n#include \"target/arm_adi_v5.h\"\n#include \"target/arm.h\"\n#include \"helper/list.h\"\n#include \"helper/command.h\"\n#include \"transport/transport.h\"\n#include \"jtag/interface.h\"\n\nstatic LIST_HEAD(all_dap);\n\nextern struct adapter_driver *adapter_driver;\n\n/* DAP command support */\nstruct arm_dap_object {\n\tstruct list_head lh;\n\tstruct adiv5_dap dap;\n\tchar *name;\n\tconst struct swd_driver *swd;\n};\n\nstatic void dap_instance_init(struct adiv5_dap *dap)\n{\n\tint i;\n\t/* Set up with safe defaults */\n\tfor (i = 0; i <= DP_APSEL_MAX; i++) {\n\t\tdap->ap[i].dap = dap;\n\t\tdap->ap[i].ap_num = DP_APSEL_INVALID;\n\t\t/* memaccess_tck max is 255 */\n\t\tdap->ap[i].memaccess_tck = 255;\n\t\t/* Number of bits for tar autoincrement, impl. dep. at least 10 */\n\t\tdap->ap[i].tar_autoincr_block = (1<<10);\n\t\t/* default CSW value */\n\t\tdap->ap[i].csw_default = CSW_AHB_DEFAULT;\n\t\tdap->ap[i].cfg_reg = MEM_AP_REG_CFG_INVALID; /* mem_ap configuration reg (large physical addr, etc.) */\n\t\tdap->ap[i].refcount = 0;\n\t\tdap->ap[i].config_ap_never_release = false;\n\t}\n\tINIT_LIST_HEAD(&dap->cmd_journal);\n\tINIT_LIST_HEAD(&dap->cmd_pool);\n}\n\nconst char *adiv5_dap_name(struct adiv5_dap *self)\n{\n\tstruct arm_dap_object *obj = container_of(self, struct arm_dap_object, dap);\n\treturn obj->name;\n}\n\nconst struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self)\n{\n\tstruct arm_dap_object *obj = container_of(self, struct arm_dap_object, dap);\n\treturn obj->swd;\n}\n\nstruct adiv5_dap *adiv5_get_dap(struct arm_dap_object *obj)\n{\n\treturn &obj->dap;\n}\nstruct adiv5_dap *dap_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)\n{\n\tstruct arm_dap_object *obj = NULL;\n\tconst char *name;\n\tbool found = false;\n\n\tname = Jim_GetString(o, NULL);\n\n\tlist_for_each_entry(obj, &all_dap, lh) {\n\t\tif (!strcmp(name, obj->name)) {\n\t\t\tfound = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (found)\n\t\treturn &obj->dap;\n\treturn NULL;\n}\n\nstatic int dap_init_all(void)\n{\n\tstruct arm_dap_object *obj;\n\tint retval;\n\n\tLOG_DEBUG(\"Initializing all DAPs ...\");\n\n\tlist_for_each_entry(obj, &all_dap, lh) {\n\t\tstruct adiv5_dap *dap = &obj->dap;\n\n\t\t/* with hla, dap is just a dummy */\n\t\tif (transport_is_hla())\n\t\t\tcontinue;\n\n\t\t/* skip taps that are disabled */\n\t\tif (!dap->tap->enabled)\n\t\t\tcontinue;\n\n\t\tif (transport_is_swd()) {\n\t\t\tdap->ops = &swd_dap_ops;\n\t\t\tobj->swd = adapter_driver->swd_ops;\n\t\t} else if (transport_is_dapdirect_swd()) {\n\t\t\tdap->ops = adapter_driver->dap_swd_ops;\n\t\t} else if (transport_is_dapdirect_jtag()) {\n\t\t\tdap->ops = adapter_driver->dap_jtag_ops;\n\t\t} else\n\t\t\tdap->ops = &jtag_dp_ops;\n\n\t\tif (dap->adi_version == 0) {\n\t\t\tLOG_DEBUG(\"DAP %s configured by default to use ADIv5 protocol\", jtag_tap_name(dap->tap));\n\t\t\tdap->adi_version = 5;\n\t\t} else {\n\t\t\tLOG_DEBUG(\"DAP %s configured to use %s protocol by user cfg file\", jtag_tap_name(dap->tap),\n\t\t\t\tis_adiv6(dap) ? \"ADIv6\" : \"ADIv5\");\n\t\t}\n\n\t\tretval = dap->ops->connect(dap);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* see if address size of ROM Table is greater than 32-bits */\n\t\tif (is_adiv6(dap)) {\n\t\t\tuint32_t dpidr1;\n\n\t\t\tretval = dap->ops->queue_dp_read(dap, DP_DPIDR1, &dpidr1);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"DAP read of DPIDR1 failed...\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tretval = dap_run(dap);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"DAP read of DPIDR1 failed...\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tdap->asize = dpidr1 & DP_DPIDR1_ASIZE_MASK;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint dap_cleanup_all(void)\n{\n\tstruct arm_dap_object *obj, *tmp;\n\tstruct adiv5_dap *dap;\n\n\tlist_for_each_entry_safe(obj, tmp, &all_dap, lh) {\n\t\tdap = &obj->dap;\n\t\tfor (unsigned int i = 0; i <= DP_APSEL_MAX; i++) {\n\t\t\tif (dap->ap[i].refcount != 0)\n\t\t\t\tLOG_ERROR(\"BUG: refcount AP#%u still %u at exit\", i, dap->ap[i].refcount);\n\t\t}\n\t\tif (dap->ops && dap->ops->quit)\n\t\t\tdap->ops->quit(dap);\n\n\t\tfree(obj->name);\n\t\tfree(obj);\n\t}\n\n\treturn ERROR_OK;\n}\n\nenum dap_cfg_param {\n\tCFG_CHAIN_POSITION,\n\tCFG_IGNORE_SYSPWRUPACK,\n\tCFG_DP_ID,\n\tCFG_INSTANCE_ID,\n\tCFG_ADIV6,\n\tCFG_ADIV5,\n};\n\nstatic const struct jim_nvp nvp_config_opts[] = {\n\t{ .name = \"-chain-position\",     .value = CFG_CHAIN_POSITION },\n\t{ .name = \"-ignore-syspwrupack\", .value = CFG_IGNORE_SYSPWRUPACK },\n\t{ .name = \"-dp-id\",              .value = CFG_DP_ID },\n\t{ .name = \"-instance-id\",        .value = CFG_INSTANCE_ID },\n\t{ .name = \"-adiv6\",              .value = CFG_ADIV6 },\n\t{ .name = \"-adiv5\",              .value = CFG_ADIV5 },\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap)\n{\n\tstruct jim_nvp *n;\n\tint e;\n\n\t/* parse config ... */\n\twhile (goi->argc > 0) {\n\t\tJim_SetEmptyResult(goi->interp);\n\n\t\te = jim_getopt_nvp(goi, nvp_config_opts, &n);\n\t\tif (e != JIM_OK) {\n\t\t\tjim_getopt_nvp_unknown(goi, nvp_config_opts, 0);\n\t\t\treturn e;\n\t\t}\n\t\tswitch (n->value) {\n\t\tcase CFG_CHAIN_POSITION: {\n\t\t\tJim_Obj *o_t;\n\t\t\te = jim_getopt_obj(goi, &o_t);\n\t\t\tif (e != JIM_OK)\n\t\t\t\treturn e;\n\n\t\t\tstruct jtag_tap *tap;\n\t\t\ttap = jtag_tap_by_jim_obj(goi->interp, o_t);\n\t\t\tif (!tap) {\n\t\t\t\tJim_SetResultString(goi->interp, \"-chain-position is invalid\", -1);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tdap->dap.tap = tap;\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\t\t}\n\t\tcase CFG_IGNORE_SYSPWRUPACK:\n\t\t\tdap->dap.ignore_syspwrupack = true;\n\t\t\tbreak;\n\t\tcase CFG_DP_ID: {\n\t\t\tjim_wide w;\n\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\tif (e != JIM_OK) {\n\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\"create %s: bad parameter %s\",\n\t\t\t\t\t\tdap->name, n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tif (w < 0 || w > DP_TARGETSEL_DPID_MASK) {\n\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\"create %s: %s out of range\",\n\t\t\t\t\t\tdap->name, n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tdap->dap.multidrop_targetsel =\n\t\t\t\t(dap->dap.multidrop_targetsel & DP_TARGETSEL_INSTANCEID_MASK)\n\t\t\t\t| (w & DP_TARGETSEL_DPID_MASK);\n\t\t\tdap->dap.multidrop_dp_id_valid = true;\n\t\t\tbreak;\n\t\t}\n\t\tcase CFG_INSTANCE_ID: {\n\t\t\tjim_wide w;\n\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\tif (e != JIM_OK) {\n\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\"create %s: bad parameter %s\",\n\t\t\t\t\t\tdap->name, n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tif (w < 0 || w > 15) {\n\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\"create %s: %s out of range\",\n\t\t\t\t\t\tdap->name, n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tdap->dap.multidrop_targetsel =\n\t\t\t\t(dap->dap.multidrop_targetsel & DP_TARGETSEL_DPID_MASK)\n\t\t\t\t| ((w << DP_TARGETSEL_INSTANCEID_SHIFT) & DP_TARGETSEL_INSTANCEID_MASK);\n\t\t\tdap->dap.multidrop_instance_id_valid = true;\n\t\t\tbreak;\n\t\t}\n\t\tcase CFG_ADIV6:\n\t\t\tdap->dap.adi_version = 6;\n\t\t\tbreak;\n\t\tcase CFG_ADIV5:\n\t\t\tdap->dap.adi_version = 5;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn JIM_OK;\n}\n\nstatic int dap_check_config(struct adiv5_dap *dap)\n{\n\tif (transport_is_jtag() || transport_is_dapdirect_jtag() || transport_is_hla())\n\t\treturn ERROR_OK;\n\n\tstruct arm_dap_object *obj;\n\tbool new_multidrop = dap_is_multidrop(dap);\n\tbool had_multidrop = new_multidrop;\n\tuint32_t targetsel = dap->multidrop_targetsel;\n\tunsigned int non_multidrop_count = had_multidrop ? 0 : 1;\n\n\tlist_for_each_entry(obj, &all_dap, lh) {\n\t\tstruct adiv5_dap *dap_it = &obj->dap;\n\n\t\tif (transport_is_swd()) {\n\t\t\tif (dap_is_multidrop(dap_it)) {\n\t\t\t\thad_multidrop = true;\n\t\t\t\tif (new_multidrop && dap_it->multidrop_targetsel == targetsel) {\n\t\t\t\t\tuint32_t dp_id = targetsel & DP_TARGETSEL_DPID_MASK;\n\t\t\t\t\tuint32_t instance_id = targetsel >> DP_TARGETSEL_INSTANCEID_SHIFT;\n\t\t\t\t\tLOG_ERROR(\"%s and %s have the same multidrop selectors -dp-id 0x%08\"\n\t\t\t\t\t\t\t  PRIx32 \" and -instance-id 0x%\" PRIx32,\n\t\t\t\t\t\t\t  obj->name, adiv5_dap_name(dap),\n\t\t\t\t\t\t\t  dp_id, instance_id);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnon_multidrop_count++;\n\t\t\t}\n\t\t} else if (transport_is_dapdirect_swd()) {\n\t\t\tnon_multidrop_count++;\n\t\t}\n\t}\n\n\tif (non_multidrop_count > 1) {\n\t\tLOG_ERROR(\"Two or more SWD non multidrop DAPs are not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (had_multidrop && non_multidrop_count) {\n\t\tLOG_ERROR(\"Mixing of SWD multidrop DAPs and non multidrop DAPs is not supported\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dap_create(struct jim_getopt_info *goi)\n{\n\tstruct command_context *cmd_ctx;\n\tstatic struct arm_dap_object *dap;\n\tJim_Obj *new_cmd;\n\tJim_Cmd *cmd;\n\tconst char *cp;\n\tint e;\n\n\tcmd_ctx = current_command_context(goi->interp);\n\tassert(cmd_ctx);\n\n\tif (goi->argc < 3) {\n\t\tJim_WrongNumArgs(goi->interp, 1, goi->argv, \"?name? ..options...\");\n\t\treturn JIM_ERR;\n\t}\n\t/* COMMAND */\n\tjim_getopt_obj(goi, &new_cmd);\n\t/* does this command exist? */\n\tcmd = Jim_GetCommand(goi->interp, new_cmd, JIM_NONE);\n\tif (cmd) {\n\t\tcp = Jim_GetString(new_cmd, NULL);\n\t\tJim_SetResultFormatted(goi->interp, \"Command: %s Exists\", cp);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Create it */\n\tdap = calloc(1, sizeof(struct arm_dap_object));\n\tif (!dap)\n\t\treturn JIM_ERR;\n\n\tdap_instance_init(&dap->dap);\n\n\tcp = Jim_GetString(new_cmd, NULL);\n\tdap->name = strdup(cp);\n\n\te = dap_configure(goi, dap);\n\tif (e != JIM_OK)\n\t\tgoto err;\n\n\tif (!dap->dap.tap) {\n\t\tJim_SetResultString(goi->interp, \"-chain-position required when creating DAP\", -1);\n\t\te = JIM_ERR;\n\t\tgoto err;\n\t}\n\n\te = dap_check_config(&dap->dap);\n\tif (e != ERROR_OK) {\n\t\te = JIM_ERR;\n\t\tgoto err;\n\t}\n\n\tstruct command_registration dap_create_commands[] = {\n\t\t{\n\t\t\t.name = cp,\n\t\t\t.mode = COMMAND_ANY,\n\t\t\t.help = \"dap instance command group\",\n\t\t\t.usage = \"\",\n\t\t\t.chain = dap_instance_commands,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\n\t/* don't expose the instance commands when using hla */\n\tif (transport_is_hla())\n\t\tdap_create_commands[0].chain = NULL;\n\n\te = register_commands_with_data(cmd_ctx, NULL, dap_create_commands, dap);\n\tif (e != ERROR_OK) {\n\t\te = JIM_ERR;\n\t\tgoto err;\n\t}\n\n\tlist_add_tail(&dap->lh, &all_dap);\n\n\treturn JIM_OK;\n\nerr:\n\tfree(dap->name);\n\tfree(dap);\n\treturn e;\n}\n\nstatic int jim_dap_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tif (goi.argc < 2) {\n\t\tJim_WrongNumArgs(goi.interp, goi.argc, goi.argv,\n\t\t\t\"<name> [<dap_options> ...]\");\n\t\treturn JIM_ERR;\n\t}\n\treturn dap_create(&goi);\n}\n\nCOMMAND_HANDLER(handle_dap_names)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct arm_dap_object *obj;\n\tlist_for_each_entry(obj, &all_dap, lh)\n\t\tcommand_print(CMD, \"%s\", obj->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_dap_init)\n{\n\treturn dap_init_all();\n}\n\nCOMMAND_HANDLER(handle_dap_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm *arm = target_to_arm(target);\n\tstruct adiv5_dap *dap = arm->dap;\n\tuint64_t apsel;\n\n\tif (!dap) {\n\t\tLOG_ERROR(\"DAP instance not available. Probably a HLA target...\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tapsel = dap->apsel;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tif (!strcmp(CMD_ARGV[0], \"root\")) {\n\t\t\t\tif (!is_adiv6(dap)) {\n\t\t\t\t\tcommand_print(CMD, \"Option \\\"root\\\" not allowed with ADIv5 DAP\");\n\t\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\t\t}\n\t\t\t\tint retval = adiv6_dap_read_baseptr(CMD, dap, &apsel);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tcommand_print(CMD, \"Failed reading DAP baseptr\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel);\n\t\t\tif (!is_ap_num_valid(dap, apsel))\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct adiv5_ap *ap = dap_get_ap(dap, apsel);\n\tif (!ap) {\n\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint retval = dap_info_command(CMD, ap);\n\tdap_put_ap(ap);\n\treturn retval;\n}\n\nstatic const struct command_registration dap_subcommand_handlers[] = {\n\t{\n\t\t.name = \"create\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_dap_create,\n\t\t.usage = \"name '-chain-position' name\",\n\t\t.help = \"Creates a new DAP instance\",\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_dap_names,\n\t\t.usage = \"\",\n\t\t.help = \"Lists all registered DAP instances by name\",\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_dap_init,\n\t\t.usage = \"\",\n\t\t.help = \"Initialize all registered DAP instances\"\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_dap_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display ROM table for specified MEM-AP (default MEM-AP of current target) \"\n\t\t\t\"or the ADIv6 root ROM table of current target's DAP\",\n\t\t.usage = \"[ap_num | 'root']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration dap_commands[] = {\n\t{\n\t\t.name = \"dap\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"DAP commands\",\n\t\t.chain = dap_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint dap_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, dap_commands);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_disassembler.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2009 by David Brownell                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"arm_disassembler.h\"\n#include <helper/log.h>\n\n#if HAVE_CAPSTONE\n#include <capstone.h>\n#endif\n\n/*\n * This disassembler supports two main functions for OpenOCD:\n *\n *  - Various \"disassemble\" commands.  OpenOCD can serve as a\n *    machine-language debugger, without help from GDB.\n *\n *  - Single stepping.  Not all ARM cores support hardware single\n *    stepping.  To work without that support, the debugger must\n *    be able to decode instructions to find out where to put a\n *    \"next instruction\" breakpoint.\n *\n * In addition, interpretation of ETM trace data needs some of the\n * decoding mechanisms.\n *\n * At this writing (September 2009) neither function is complete.\n *\n *  - ARM decoding\n *     * Old-style syntax (not UAL) is generally used\n *     * VFP instructions are not understood (ARMv5 and later)\n *       except as coprocessor 10/11 operations\n *     * Most ARM instructions through ARMv6 are decoded, but some\n *       of the post-ARMv4 opcodes may not be handled yet\n *\t\tCPS, SDIV, UDIV, LDREX*, STREX*, QASX, ...\n *     * NEON instructions are not understood (ARMv7-A)\n *\n *  - Thumb/Thumb2 decoding\n *     * UAL syntax should be consistently used\n *     * Any Thumb2 instructions used in Cortex-M3 (ARMv7-M) should\n *       be handled properly.  Accordingly, so should the subset\n *       used in Cortex-M0/M1; and \"original\" 16-bit Thumb from\n *       ARMv4T and ARMv5T.\n *     * Conditional effects of Thumb2 \"IT\" (if-then) instructions\n *       are not handled:  the affected instructions are not shown\n *       with their now-conditional suffixes.\n *     * Some ARMv6 and ARMv7-M Thumb2 instructions may not be\n *       handled (minimally for coprocessor access).\n *     * SIMD instructions, and some other Thumb2 instructions\n *       from ARMv7-A, are not understood.\n *\n *  - ThumbEE decoding\n *     * As a Thumb2 variant, the Thumb2 comments (above) apply.\n *     * Opcodes changed by ThumbEE mode are not handled; these\n *       instructions wrongly decode as LDM and STM.\n *\n *  - Jazelle decoding ...  no support whatsoever for Jazelle mode\n *    or decoding.  ARM encourages use of the more generic ThumbEE\n *    mode, instead of Jazelle mode, in current chips.\n *\n *  - Single-step/emulation ... spotty support, which is only weakly\n *    tested.  Thumb2 is not supported.  (Arguably a full simulator\n *    is not needed to support just single stepping.  Recognizing\n *    branch vs non-branch instructions suffices, except when the\n *    instruction faults and triggers a synchronous exception which\n *    can be intercepted using other means.)\n *\n * ARM DDI 0406B \"ARM Architecture Reference Manual, ARM v7-A and\n * ARM v7-R edition\" gives the most complete coverage of the various\n * generations of ARM instructions.  At this writing it is publicly\n * accessible to anyone willing to create an account at the ARM\n * web site; see http://www.arm.com/documentation/ for information.\n *\n * ARM DDI 0403C \"ARMv7-M Architecture Reference Manual\" provides\n * more details relevant to the Thumb2-only processors (such as\n * the Cortex-M implementations).\n */\n\n/* textual representation of the condition field\n * ALways (default) is omitted (empty string) */\nstatic const char *arm_condition_strings[] = {\n\t\"EQ\", \"NE\", \"CS\", \"CC\", \"MI\", \"PL\", \"VS\", \"VC\", \"HI\", \"LS\", \"GE\", \"LT\", \"GT\", \"LE\", \"\", \"NV\"\n};\n\n/* make up for C's missing ROR */\nstatic uint32_t ror(uint32_t value, int places)\n{\n\treturn (value >> places) | (value << (32 - places));\n}\n\nstatic int evaluate_unknown(uint32_t opcode,\n\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32\n\t\t\t\"\\tUNDEFINED INSTRUCTION\", address, opcode);\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_pld(uint32_t opcode,\n\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\t/* PLD */\n\tif ((opcode & 0x0d30f000) == 0x0510f000) {\n\t\tuint8_t rn;\n\t\tuint8_t u;\n\t\tunsigned offset;\n\n\t\tinstruction->type = ARM_PLD;\n\t\trn = (opcode & 0xf0000) >> 16;\n\t\tu = (opcode & 0x00800000) >> 23;\n\t\tif (rn == 0xf) {\n\t\t\t/* literal */\n\t\t\toffset = opcode & 0x0fff;\n\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD %s%d\",\n\t\t\t\t address, opcode, u ? \"\" : \"-\", offset);\n\t\t} else {\n\t\t\tuint8_t i, r;\n\n\t\t\ti = (opcode & 0x02000000) >> 25;\n\t\t\tr = (opcode & 0x00400000) >> 22;\n\n\t\t\tif (i) {\n\t\t\t\t/* register PLD{W} [<Rn>,+/-<Rm>{, <shift>}] */\n\t\t\t\toffset = (opcode & 0x0F80) >> 7;\n\t\t\t\tuint8_t rm;\n\t\t\t\trm = opcode & 0xf;\n\n\t\t\t\tif (offset == 0) {\n\t\t\t\t\t/* No shift */\n\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, %sr%d]\",\n\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", rm);\n\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t shift;\n\t\t\t\t\tshift = (opcode & 0x60) >> 5;\n\n\t\t\t\t\tif (shift == 0x0) {\n\t\t\t\t\t\t/* LSL */\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, %sr%d, LSL #0x%x)\",\n\t\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", rm, offset);\n\t\t\t\t\t} else if (shift == 0x1) {\n\t\t\t\t\t\t/* LSR */\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, %sr%d, LSR #0x%x)\",\n\t\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", rm, offset);\n\t\t\t\t\t} else if (shift == 0x2) {\n\t\t\t\t\t\t/* ASR */\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, %sr%d, ASR #0x%x)\",\n\t\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", rm, offset);\n\t\t\t\t\t} else if (shift == 0x3) {\n\t\t\t\t\t\t/* ROR */\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, %sr%d, ROR #0x%x)\",\n\t\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", rm, offset);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* immediate PLD{W} [<Rn>, #+/-<imm12>] */\n\t\t\t\toffset = opcode & 0x0fff;\n\t\t\t\tif (offset == 0) {\n\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d]\",\n\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn);\n\t\t\t\t} else {\n\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tPLD%s [r%d, #%s%d]\",\n\t\t\t\t\t\t address, opcode, r ? \"\" : \"W\", rn, u ? \"\" : \"-\", offset);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\t/* DSB */\n\tif ((opcode & 0x07f000f0) == 0x05700040) {\n\t\tinstruction->type = ARM_DSB;\n\n\t\tchar *opt;\n\t\tswitch (opcode & 0x0000000f) {\n\t\tcase 0xf:\n\t\t\topt = \"SY\";\n\t\t\tbreak;\n\t\tcase 0xe:\n\t\t\topt = \"ST\";\n\t\t\tbreak;\n\t\tcase 0xb:\n\t\t\topt = \"ISH\";\n\t\t\tbreak;\n\t\tcase 0xa:\n\t\t\topt = \"ISHST\";\n\t\t\tbreak;\n\t\tcase 0x7:\n\t\t\topt = \"NSH\";\n\t\t\tbreak;\n\t\tcase 0x6:\n\t\t\topt = \"NSHST\";\n\t\t\tbreak;\n\t\tcase 0x3:\n\t\t\topt = \"OSH\";\n\t\t\tbreak;\n\t\tcase 0x2:\n\t\t\topt = \"OSHST\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\topt = \"UNK\";\n\t\t}\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tDSB %s\",\n\t\t\t\taddress, opcode, opt);\n\n\t\treturn ERROR_OK;\n\t}\n\t/* ISB */\n\tif ((opcode & 0x07f000f0) == 0x05700060) {\n\t\tinstruction->type = ARM_ISB;\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tISB %s\",\n\t\t\t\taddress, opcode,\n\t\t\t\t((opcode & 0x0000000f) == 0xf) ? \"SY\" : \"UNK\");\n\n\t\treturn ERROR_OK;\n\t}\n\treturn evaluate_unknown(opcode, address, instruction);\n}\n\nstatic int evaluate_srs(uint32_t opcode,\n\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\tconst char *wback = (opcode & (1 << 21)) ? \"!\" : \"\";\n\tconst char *mode = \"\";\n\n\tswitch ((opcode >> 23) & 0x3) {\n\t\tcase 0:\n\t\t\tmode = \"DA\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t/* \"IA\" is default */\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tmode = \"DB\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tmode = \"IB\";\n\t\t\tbreak;\n\t}\n\n\tswitch (opcode & 0x0e500000) {\n\t\tcase 0x08400000:\n\t\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32\n\t\t\t\t\"\\t0x%8.8\" PRIx32\n\t\t\t\t\"\\tSRS%s\\tSP%s, #%d\",\n\t\t\t\taddress, opcode,\n\t\t\t\tmode, wback,\n\t\t\t\t(unsigned)(opcode & 0x1f));\n\t\t\tbreak;\n\t\tcase 0x08100000:\n\t\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32\n\t\t\t\t\"\\t0x%8.8\" PRIx32\n\t\t\t\t\"\\tRFE%s\\tr%d%s\",\n\t\t\t\taddress, opcode,\n\t\t\t\tmode,\n\t\t\t\t(unsigned)((opcode >> 16) & 0xf), wback);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn evaluate_unknown(opcode, address, instruction);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_swi(uint32_t opcode,\n\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\tinstruction->type = ARM_SWI;\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSVC %#6.6\" PRIx32,\n\t\t\taddress, opcode, (opcode & 0xffffff));\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_blx_imm(uint32_t opcode,\n\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tint offset;\n\tuint32_t immediate;\n\tuint32_t target_address;\n\n\tinstruction->type = ARM_BLX;\n\timmediate = opcode & 0x00ffffff;\n\n\t/* sign extend 24-bit immediate */\n\tif (immediate & 0x00800000)\n\t\toffset = 0xff000000 | immediate;\n\telse\n\t\toffset = immediate;\n\n\t/* shift two bits left */\n\toffset <<= 2;\n\n\t/* odd/event halfword */\n\tif (opcode & 0x01000000)\n\t\toffset |= 0x2;\n\n\ttarget_address = address + 8 + offset;\n\n\tsnprintf(instruction->text,\n\t\t\t128,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tBLX 0x%8.8\" PRIx32 \"\",\n\t\t\taddress,\n\t\t\topcode,\n\t\t\ttarget_address);\n\n\tinstruction->info.b_bl_bx_blx.reg_operand = -1;\n\tinstruction->info.b_bl_bx_blx.target_address = target_address;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_b_bl(uint32_t opcode,\n\t\t\t uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t l;\n\tuint32_t immediate;\n\tint offset;\n\tuint32_t target_address;\n\n\timmediate = opcode & 0x00ffffff;\n\tl = (opcode & 0x01000000) >> 24;\n\n\t/* sign extend 24-bit immediate */\n\tif (immediate & 0x00800000)\n\t\toffset = 0xff000000 | immediate;\n\telse\n\t\toffset = immediate;\n\n\t/* shift two bits left */\n\toffset <<= 2;\n\n\ttarget_address = address + 8 + offset;\n\n\tif (l)\n\t\tinstruction->type = ARM_BL;\n\telse\n\t\tinstruction->type = ARM_B;\n\n\tsnprintf(instruction->text,\n\t\t\t128,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tB%s%s 0x%8.8\" PRIx32,\n\t\t\taddress,\n\t\t\topcode,\n\t\t\t(l) ? \"L\" : \"\",\n\t\t\tCOND(opcode),\n\t\t\ttarget_address);\n\n\tinstruction->info.b_bl_bx_blx.reg_operand = -1;\n\tinstruction->info.b_bl_bx_blx.target_address = target_address;\n\n\treturn ERROR_OK;\n}\n\n/* Coprocessor load/store and double register transfers\n * both normal and extended instruction space (condition field b1111) */\nstatic int evaluate_ldc_stc_mcrr_mrrc(uint32_t opcode,\n\t\t\t\t      uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t cp_num = (opcode & 0xf00) >> 8;\n\n\t/* MCRR or MRRC */\n\tif (((opcode & 0x0ff00000) == 0x0c400000) || ((opcode & 0x0ff00000) == 0x0c500000)) {\n\t\tuint8_t cp_opcode, rd, rn, crm;\n\t\tchar *mnemonic;\n\n\t\tcp_opcode = (opcode & 0xf0) >> 4;\n\t\trd = (opcode & 0xf000) >> 12;\n\t\trn = (opcode & 0xf0000) >> 16;\n\t\tcrm = (opcode & 0xf);\n\n\t\t/* MCRR */\n\t\tif ((opcode & 0x0ff00000) == 0x0c400000) {\n\t\t\tinstruction->type = ARM_MCRR;\n\t\t\tmnemonic = \"MCRR\";\n\t\t} else if ((opcode & 0x0ff00000) == 0x0c500000) {\n\t\t\t/* MRRC */\n\t\t\tinstruction->type = ARM_MRRC;\n\t\t\tmnemonic = \"MRRC\";\n\t\t} else {\n\t\t\tLOG_ERROR(\"Unknown instruction\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32\n\t\t\t\t\"\\t%s%s%s p%i, %x, r%i, r%i, c%i\",\n\t\t\t\taddress, opcode, mnemonic,\n\t\t\t\t((opcode & 0xf0000000) == 0xf0000000)\n\t\t\t\t? \"2\" : COND(opcode),\n\t\t\t\tCOND(opcode), cp_num, cp_opcode, rd, rn, crm);\n\t} else {/* LDC or STC */\n\t\tuint8_t crd, rn, offset;\n\t\tuint8_t u;\n\t\tchar *mnemonic;\n\t\tchar addressing_mode[32];\n\n\t\tcrd = (opcode & 0xf000) >> 12;\n\t\trn = (opcode & 0xf0000) >> 16;\n\t\toffset = (opcode & 0xff) << 2;\n\n\t\t/* load/store */\n\t\tif (opcode & 0x00100000) {\n\t\t\tinstruction->type = ARM_LDC;\n\t\t\tmnemonic = \"LDC\";\n\t\t} else {\n\t\t\tinstruction->type = ARM_STC;\n\t\t\tmnemonic = \"STC\";\n\t\t}\n\n\t\tu = (opcode & 0x00800000) >> 23;\n\n\t\t/* addressing modes */\n\t\tif ((opcode & 0x01200000) == 0x01000000)/* offset */\n\t\t\tsnprintf(addressing_mode, 32, \"[r%i, #%s%d]\",\n\t\t\t\t\trn, u ? \"\" : \"-\", offset);\n\t\telse if ((opcode & 0x01200000) == 0x01200000)\t/* pre-indexed */\n\t\t\tsnprintf(addressing_mode, 32, \"[r%i, #%s%d]!\",\n\t\t\t\t\trn, u ? \"\" : \"-\", offset);\n\t\telse if ((opcode & 0x01200000) == 0x00200000)\t/* post-indexed */\n\t\t\tsnprintf(addressing_mode, 32, \"[r%i], #%s%d\",\n\t\t\t\t\trn, u ? \"\" : \"-\", offset);\n\t\telse if ((opcode & 0x01200000) == 0x00000000)\t/* unindexed */\n\t\t\tsnprintf(addressing_mode, 32, \"[r%i], {%d}\",\n\t\t\t\t\trn, offset >> 2);\n\n\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32\n\t\t\t\t\"\\t0x%8.8\" PRIx32\n\t\t\t\t\"\\t%s%s%s p%i, c%i, %s\",\n\t\t\t\taddress, opcode, mnemonic,\n\t\t\t\t((opcode & 0xf0000000) == 0xf0000000)\n\t\t\t\t? \"2\" : COND(opcode),\n\t\t\t\t(opcode & (1 << 22)) ? \"L\" : \"\",\n\t\t\t\tcp_num, crd, addressing_mode);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Coprocessor data processing instructions\n * Coprocessor register transfer instructions\n * both normal and extended instruction space (condition field b1111) */\nstatic int evaluate_cdp_mcr_mrc(uint32_t opcode,\n\t\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\tconst char *cond;\n\tchar *mnemonic;\n\tuint8_t cp_num, opcode_1, crd_rd, crn, crm, opcode_2;\n\n\tcond = ((opcode & 0xf0000000) == 0xf0000000) ? \"2\" : COND(opcode);\n\tcp_num = (opcode & 0xf00) >> 8;\n\tcrd_rd = (opcode & 0xf000) >> 12;\n\tcrn = (opcode & 0xf0000) >> 16;\n\tcrm = (opcode & 0xf);\n\topcode_2 = (opcode & 0xe0) >> 5;\n\n\t/* CDP or MRC/MCR */\n\tif (opcode & 0x00000010) {\t/* bit 4 set -> MRC/MCR */\n\t\tif (opcode & 0x00100000) {\t/* bit 20 set -> MRC */\n\t\t\tinstruction->type = ARM_MRC;\n\t\t\tmnemonic = \"MRC\";\n\t\t} else {/* bit 20 not set -> MCR */\n\t\t\tinstruction->type = ARM_MCR;\n\t\t\tmnemonic = \"MCR\";\n\t\t}\n\n\t\topcode_1 = (opcode & 0x00e00000) >> 21;\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s p%i, 0x%2.2x, r%i, c%i, c%i, 0x%2.2x\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tmnemonic,\n\t\t\t\tcond,\n\t\t\t\tcp_num,\n\t\t\t\topcode_1,\n\t\t\t\tcrd_rd,\n\t\t\t\tcrn,\n\t\t\t\tcrm,\n\t\t\t\topcode_2);\n\t} else {/* bit 4 not set -> CDP */\n\t\tinstruction->type = ARM_CDP;\n\t\tmnemonic = \"CDP\";\n\n\t\topcode_1 = (opcode & 0x00f00000) >> 20;\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s p%i, 0x%2.2x, c%i, c%i, c%i, 0x%2.2x\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tmnemonic,\n\t\t\t\tcond,\n\t\t\t\tcp_num,\n\t\t\t\topcode_1,\n\t\t\t\tcrd_rd,\n\t\t\t\tcrn,\n\t\t\t\tcrm,\n\t\t\t\topcode_2);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Load/store instructions */\nstatic int evaluate_load_store(uint32_t opcode,\n\t\t\t       uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t i, p, u, b, w, l;\n\tuint8_t rn, rd;\n\tchar *operation;/* \"LDR\" or \"STR\" */\n\tchar *suffix;\t/* \"\", \"B\", \"T\", \"BT\" */\n\tchar offset[32];\n\n\t/* examine flags */\n\ti = (opcode & 0x02000000) >> 25;\n\tp = (opcode & 0x01000000) >> 24;\n\tu = (opcode & 0x00800000) >> 23;\n\tb = (opcode & 0x00400000) >> 22;\n\tw = (opcode & 0x00200000) >> 21;\n\tl = (opcode & 0x00100000) >> 20;\n\n\t/* target register */\n\trd = (opcode & 0xf000) >> 12;\n\n\t/* base register */\n\trn = (opcode & 0xf0000) >> 16;\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = rn;\n\tinstruction->info.load_store.u = u;\n\n\t/* determine operation */\n\tif (l)\n\t\toperation = \"LDR\";\n\telse\n\t\toperation = \"STR\";\n\n\t/* determine instruction type and suffix */\n\tif (b) {\n\t\tif ((p == 0) && (w == 1)) {\n\t\t\tif (l)\n\t\t\t\tinstruction->type = ARM_LDRBT;\n\t\t\telse\n\t\t\t\tinstruction->type = ARM_STRBT;\n\t\t\tsuffix = \"BT\";\n\t\t} else {\n\t\t\tif (l)\n\t\t\t\tinstruction->type = ARM_LDRB;\n\t\t\telse\n\t\t\t\tinstruction->type = ARM_STRB;\n\t\t\tsuffix = \"B\";\n\t\t}\n\t} else {\n\t\tif ((p == 0) && (w == 1)) {\n\t\t\tif (l)\n\t\t\t\tinstruction->type = ARM_LDRT;\n\t\t\telse\n\t\t\t\tinstruction->type = ARM_STRT;\n\t\t\tsuffix = \"T\";\n\t\t} else {\n\t\t\tif (l)\n\t\t\t\tinstruction->type = ARM_LDR;\n\t\t\telse\n\t\t\t\tinstruction->type = ARM_STR;\n\t\t\tsuffix = \"\";\n\t\t}\n\t}\n\n\tif (!i) {\t/* #+-<offset_12> */\n\t\tuint32_t offset_12 = (opcode & 0xfff);\n\t\tif (offset_12)\n\t\t\tsnprintf(offset, 32, \", #%s0x%\" PRIx32 \"\", (u) ? \"\" : \"-\", offset_12);\n\t\telse\n\t\t\tsnprintf(offset, 32, \"%s\", \"\");\n\n\t\tinstruction->info.load_store.offset_mode = 0;\n\t\tinstruction->info.load_store.offset.offset = offset_12;\n\t} else {/* either +-<Rm> or +-<Rm>, <shift>, #<shift_imm> */\n\t\tuint8_t shift_imm, shift;\n\t\tuint8_t rm;\n\n\t\tshift_imm = (opcode & 0xf80) >> 7;\n\t\tshift = (opcode & 0x60) >> 5;\n\t\trm = (opcode & 0xf);\n\n\t\t/* LSR encodes a shift by 32 bit as 0x0 */\n\t\tif ((shift == 0x1) && (shift_imm == 0x0))\n\t\t\tshift_imm = 0x20;\n\n\t\t/* ASR encodes a shift by 32 bit as 0x0 */\n\t\tif ((shift == 0x2) && (shift_imm == 0x0))\n\t\t\tshift_imm = 0x20;\n\n\t\t/* ROR by 32 bit is actually a RRX */\n\t\tif ((shift == 0x3) && (shift_imm == 0x0))\n\t\t\tshift = 0x4;\n\n\t\tinstruction->info.load_store.offset_mode = 1;\n\t\tinstruction->info.load_store.offset.reg.rm = rm;\n\t\tinstruction->info.load_store.offset.reg.shift = shift;\n\t\tinstruction->info.load_store.offset.reg.shift_imm = shift_imm;\n\n\t\tif ((shift_imm == 0x0) && (shift == 0x0))\t/* +-<Rm> */\n\t\t\tsnprintf(offset, 32, \", %sr%i\", (u) ? \"\" : \"-\", rm);\n\t\telse {\t/* +-<Rm>, <Shift>, #<shift_imm> */\n\t\t\tswitch (shift) {\n\t\t\t\tcase 0x0:\t\t/* LSL */\n\t\t\t\t\tsnprintf(offset, 32, \", %sr%i, LSL #0x%x\", (u) ? \"\" : \"-\", rm, shift_imm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1:\t\t/* LSR */\n\t\t\t\t\tsnprintf(offset, 32, \", %sr%i, LSR #0x%x\", (u) ? \"\" : \"-\", rm, shift_imm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2:\t\t/* ASR */\n\t\t\t\t\tsnprintf(offset, 32, \", %sr%i, ASR #0x%x\", (u) ? \"\" : \"-\", rm, shift_imm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x3:\t\t/* ROR */\n\t\t\t\t\tsnprintf(offset, 32, \", %sr%i, ROR #0x%x\", (u) ? \"\" : \"-\", rm, shift_imm);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x4:\t\t/* RRX */\n\t\t\t\t\tsnprintf(offset, 32, \", %sr%i, RRX\", (u) ? \"\" : \"-\", rm);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (p == 1) {\n\t\tif (w == 0) {\t/* offset */\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i%s]\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\toperation,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tsuffix,\n\t\t\t\t\trd,\n\t\t\t\t\trn,\n\t\t\t\t\toffset);\n\n\t\t\tinstruction->info.load_store.index_mode = 0;\n\t\t} else {/* pre-indexed */\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i%s]!\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\toperation,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tsuffix,\n\t\t\t\t\trd,\n\t\t\t\t\trn,\n\t\t\t\t\toffset);\n\n\t\t\tinstruction->info.load_store.index_mode = 1;\n\t\t}\n\t} else {/* post-indexed */\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i]%s\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\toperation,\n\t\t\t\tCOND(opcode),\n\t\t\t\tsuffix,\n\t\t\t\trd,\n\t\t\t\trn,\n\t\t\t\toffset);\n\n\t\tinstruction->info.load_store.index_mode = 2;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_extend(uint32_t opcode, uint32_t address, char *cp)\n{\n\tunsigned rm = (opcode >> 0) & 0xf;\n\tunsigned rd = (opcode >> 12) & 0xf;\n\tunsigned rn = (opcode >> 16) & 0xf;\n\tchar *type, *rot;\n\n\tswitch ((opcode >> 24) & 0x3) {\n\t\tcase 0:\n\t\t\ttype = \"B16\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsprintf(cp, \"UNDEFINED\");\n\t\t\treturn ARM_UNDEFINED_INSTRUCTION;\n\t\tcase 2:\n\t\t\ttype = \"B\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttype = \"H\";\n\t\t\tbreak;\n\t}\n\n\tswitch ((opcode >> 10) & 0x3) {\n\t\tcase 0:\n\t\t\trot = \"\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\trot = \", ROR #8\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\trot = \", ROR #16\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\trot = \", ROR #24\";\n\t\t\tbreak;\n\t}\n\n\tif (rn == 0xf) {\n\t\tsprintf(cp, \"%cXT%s%s\\tr%d, r%d%s\",\n\t\t\t\t(opcode & (1 << 22)) ? 'U' : 'S',\n\t\t\t\ttype, COND(opcode),\n\t\t\t\trd, rm, rot);\n\t\treturn ARM_MOV;\n\t} else {\n\t\tsprintf(cp, \"%cXTA%s%s\\tr%d, r%d, r%d%s\",\n\t\t\t\t(opcode & (1 << 22)) ? 'U' : 'S',\n\t\t\t\ttype, COND(opcode),\n\t\t\t\trd, rn, rm, rot);\n\t\treturn ARM_ADD;\n\t}\n}\n\nstatic int evaluate_p_add_sub(uint32_t opcode, uint32_t address, char *cp)\n{\n\tchar *prefix;\n\tchar *op;\n\tint type;\n\n\tswitch ((opcode >> 20) & 0x7) {\n\t\tcase 1:\n\t\t\tprefix = \"S\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tprefix = \"Q\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tprefix = \"SH\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tprefix = \"U\";\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tprefix = \"UQ\";\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tprefix = \"UH\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto undef;\n\t}\n\n\tswitch ((opcode >> 5) & 0x7) {\n\t\tcase 0:\n\t\t\top = \"ADD16\";\n\t\t\ttype = ARM_ADD;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\top = \"ADDSUBX\";\n\t\t\ttype = ARM_ADD;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\top = \"SUBADDX\";\n\t\t\ttype = ARM_SUB;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\top = \"SUB16\";\n\t\t\ttype = ARM_SUB;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\top = \"ADD8\";\n\t\t\ttype = ARM_ADD;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\top = \"SUB8\";\n\t\t\ttype = ARM_SUB;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tgoto undef;\n\t}\n\n\tsprintf(cp, \"%s%s%s\\tr%d, r%d, r%d\", prefix, op, COND(opcode),\n\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t(int) (opcode >> 0) & 0xf);\n\treturn type;\n\nundef:\n\t/* these opcodes might be used someday */\n\tsprintf(cp, \"UNDEFINED\");\n\treturn ARM_UNDEFINED_INSTRUCTION;\n}\n\n/* ARMv6 and later support \"media\" instructions (includes SIMD) */\nstatic int evaluate_media(uint32_t opcode, uint32_t address,\n\t\t\t  struct arm_instruction *instruction)\n{\n\tchar *cp = instruction->text;\n\tchar *mnemonic = NULL;\n\n\tsprintf(cp,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t\",\n\t\t\taddress, opcode);\n\tcp = strchr(cp, 0);\n\n\t/* parallel add/subtract */\n\tif ((opcode & 0x01800000) == 0x00000000) {\n\t\tinstruction->type = evaluate_p_add_sub(opcode, address, cp);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* halfword pack */\n\tif ((opcode & 0x01f00020) == 0x00800000) {\n\t\tchar *type, *shift;\n\t\tunsigned imm = (unsigned) (opcode >> 7) & 0x1f;\n\n\t\tif (opcode & (1 << 6)) {\n\t\t\ttype = \"TB\";\n\t\t\tshift = \"ASR\";\n\t\t\tif (imm == 0)\n\t\t\t\timm = 32;\n\t\t} else {\n\t\t\ttype = \"BT\";\n\t\t\tshift = \"LSL\";\n\t\t}\n\t\tsprintf(cp, \"PKH%s%s\\tr%d, r%d, r%d, %s #%d\",\n\t\t\t\ttype, COND(opcode),\n\t\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\tshift, imm);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* word saturate */\n\tif ((opcode & 0x01a00020) == 0x00a00000) {\n\t\tchar *shift;\n\t\tunsigned imm = (unsigned) (opcode >> 7) & 0x1f;\n\n\t\tif (opcode & (1 << 6)) {\n\t\t\tshift = \"ASR\";\n\t\t\tif (imm == 0)\n\t\t\t\timm = 32;\n\t\t} else\n\t\t\tshift = \"LSL\";\n\n\t\tsprintf(cp, \"%cSAT%s\\tr%d, #%d, r%d, %s #%d\",\n\t\t\t\t(opcode & (1 << 22)) ? 'U' : 'S',\n\t\t\t\tCOND(opcode),\n\t\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t\t(int) (opcode >> 16) & 0x1f,\n\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\tshift, imm);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* sign extension */\n\tif ((opcode & 0x018000f0) == 0x00800070) {\n\t\tinstruction->type = evaluate_extend(opcode, address, cp);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* multiplies */\n\tif ((opcode & 0x01f00080) == 0x01000000) {\n\t\tunsigned rn = (opcode >> 12) & 0xf;\n\n\t\tif (rn != 0xf)\n\t\t\tsprintf(cp, \"SML%cD%s%s\\tr%d, r%d, r%d, r%d\",\n\t\t\t\t\t(opcode & (1 << 6)) ? 'S' : 'A',\n\t\t\t\t\t(opcode & (1 << 5)) ? \"X\" : \"\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t(int) (opcode >> 8) & 0xf,\n\t\t\t\t\trn);\n\t\telse\n\t\t\tsprintf(cp, \"SMU%cD%s%s\\tr%d, r%d, r%d\",\n\t\t\t\t\t(opcode & (1 << 6)) ? 'S' : 'A',\n\t\t\t\t\t(opcode & (1 << 5)) ? \"X\" : \"\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t(int) (opcode >> 8) & 0xf);\n\t\treturn ERROR_OK;\n\t}\n\tif ((opcode & 0x01f00000) == 0x01400000) {\n\t\tsprintf(cp, \"SML%cLD%s%s\\tr%d, r%d, r%d, r%d\",\n\t\t\t\t(opcode & (1 << 6)) ? 'S' : 'A',\n\t\t\t\t(opcode & (1 << 5)) ? \"X\" : \"\",\n\t\t\t\tCOND(opcode),\n\t\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t(int) (opcode >> 8) & 0xf);\n\t\treturn ERROR_OK;\n\t}\n\tif ((opcode & 0x01f00000) == 0x01500000) {\n\t\tunsigned rn = (opcode >> 12) & 0xf;\n\n\t\tswitch (opcode & 0xc0) {\n\t\t\tcase 3:\n\t\t\t\tif (rn == 0xf)\n\t\t\t\t\tgoto undef;\n\t\t\t/* FALL THROUGH */\n\t\t\tcase 0:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tgoto undef;\n\t\t}\n\n\t\tif (rn != 0xf)\n\t\t\tsprintf(cp, \"SMML%c%s%s\\tr%d, r%d, r%d, r%d\",\n\t\t\t\t\t(opcode & (1 << 6)) ? 'S' : 'A',\n\t\t\t\t\t(opcode & (1 << 5)) ? \"R\" : \"\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t(int) (opcode >> 8) & 0xf,\n\t\t\t\t\trn);\n\t\telse\n\t\t\tsprintf(cp, \"SMMUL%s%s\\tr%d, r%d, r%d\",\n\t\t\t\t\t(opcode & (1 << 5)) ? \"R\" : \"\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t(int) (opcode >> 8) & 0xf);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* simple matches against the remaining decode bits */\n\tswitch (opcode & 0x01f000f0) {\n\t\tcase 0x00a00030:\n\t\tcase 0x00e00030:\n\t\t\t/* parallel halfword saturate */\n\t\t\tsprintf(cp, \"%cSAT16%s\\tr%d, #%d, r%d\",\n\t\t\t\t(opcode & (1 << 22)) ? 'U' : 'S',\n\t\t\t\tCOND(opcode),\n\t\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t(int) (opcode >> 0) & 0xf);\n\t\t\treturn ERROR_OK;\n\t\tcase 0x00b00030:\n\t\t\tmnemonic = \"REV\";\n\t\t\tbreak;\n\t\tcase 0x00b000b0:\n\t\t\tmnemonic = \"REV16\";\n\t\t\tbreak;\n\t\tcase 0x00f000b0:\n\t\t\tmnemonic = \"REVSH\";\n\t\t\tbreak;\n\t\tcase 0x008000b0:\n\t\t\t/* select bytes */\n\t\t\tsprintf(cp, \"SEL%s\\tr%d, r%d, r%d\", COND(opcode),\n\t\t\t\t(int) (opcode >> 12) & 0xf,\n\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t(int) (opcode >> 0) & 0xf);\n\t\t\treturn ERROR_OK;\n\t\tcase 0x01800010:\n\t\t\t/* unsigned sum of absolute differences */\n\t\t\tif (((opcode >> 12) & 0xf) == 0xf)\n\t\t\t\tsprintf(cp, \"USAD8%s\\tr%d, r%d, r%d\", COND(opcode),\n\t\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t\t(int) (opcode >> 8) & 0xf);\n\t\t\telse\n\t\t\t\tsprintf(cp, \"USADA8%s\\tr%d, r%d, r%d, r%d\", COND(opcode),\n\t\t\t\t\t\t(int) (opcode >> 16) & 0xf,\n\t\t\t\t\t\t(int) (opcode >> 0) & 0xf,\n\t\t\t\t\t\t(int) (opcode >> 8) & 0xf,\n\t\t\t\t\t\t(int) (opcode >> 12) & 0xf);\n\t\t\treturn ERROR_OK;\n\t}\n\tif (mnemonic) {\n\t\tunsigned rm = (opcode >> 0) & 0xf;\n\t\tunsigned rd = (opcode >> 12) & 0xf;\n\n\t\tsprintf(cp, \"%s%s\\tr%d, r%d\", mnemonic, COND(opcode), rm, rd);\n\t\treturn ERROR_OK;\n\t}\n\nundef:\n\t/* these opcodes might be used someday */\n\tsprintf(cp, \"UNDEFINED\");\n\treturn ERROR_OK;\n}\n\n/* Miscellaneous load/store instructions */\nstatic int evaluate_misc_load_store(uint32_t opcode,\n\t\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t p, u, i, w, l, s, h;\n\tuint8_t rn, rd;\n\tchar *operation;/* \"LDR\" or \"STR\" */\n\tchar *suffix;\t/* \"H\", \"SB\", \"SH\", \"D\" */\n\tchar offset[32];\n\n\t/* examine flags */\n\tp = (opcode & 0x01000000) >> 24;\n\tu = (opcode & 0x00800000) >> 23;\n\ti = (opcode & 0x00400000) >> 22;\n\tw = (opcode & 0x00200000) >> 21;\n\tl = (opcode & 0x00100000) >> 20;\n\ts = (opcode & 0x00000040) >> 6;\n\th = (opcode & 0x00000020) >> 5;\n\n\t/* target register */\n\trd = (opcode & 0xf000) >> 12;\n\n\t/* base register */\n\trn = (opcode & 0xf0000) >> 16;\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = rn;\n\tinstruction->info.load_store.u = u;\n\n\t/* determine instruction type and suffix */\n\tif (s) {/* signed */\n\t\tif (l) {/* load */\n\t\t\tif (h) {\n\t\t\t\toperation = \"LDR\";\n\t\t\t\tinstruction->type = ARM_LDRSH;\n\t\t\t\tsuffix = \"SH\";\n\t\t\t} else {\n\t\t\t\toperation = \"LDR\";\n\t\t\t\tinstruction->type = ARM_LDRSB;\n\t\t\t\tsuffix = \"SB\";\n\t\t\t}\n\t\t} else {/* there are no signed stores, so this is used to encode double-register\n\t\t\t *load/stores */\n\t\t\tsuffix = \"D\";\n\t\t\tif (h) {\n\t\t\t\toperation = \"STR\";\n\t\t\t\tinstruction->type = ARM_STRD;\n\t\t\t} else {\n\t\t\t\toperation = \"LDR\";\n\t\t\t\tinstruction->type = ARM_LDRD;\n\t\t\t}\n\t\t}\n\t} else {/* unsigned */\n\t\tsuffix = \"H\";\n\t\tif (l) {/* load */\n\t\t\toperation = \"LDR\";\n\t\t\tinstruction->type = ARM_LDRH;\n\t\t} else {/* store */\n\t\t\toperation = \"STR\";\n\t\t\tinstruction->type = ARM_STRH;\n\t\t}\n\t}\n\n\tif (i) {/* Immediate offset/index (#+-<offset_8>)*/\n\t\tuint32_t offset_8 = ((opcode & 0xf00) >> 4) | (opcode & 0xf);\n\t\tsnprintf(offset, 32, \"#%s0x%\" PRIx32 \"\", (u) ? \"\" : \"-\", offset_8);\n\n\t\tinstruction->info.load_store.offset_mode = 0;\n\t\tinstruction->info.load_store.offset.offset = offset_8;\n\t} else {/* Register offset/index (+-<Rm>) */\n\t\tuint8_t rm;\n\t\trm = (opcode & 0xf);\n\t\tsnprintf(offset, 32, \"%sr%i\", (u) ? \"\" : \"-\", rm);\n\n\t\tinstruction->info.load_store.offset_mode = 1;\n\t\tinstruction->info.load_store.offset.reg.rm = rm;\n\t\tinstruction->info.load_store.offset.reg.shift = 0x0;\n\t\tinstruction->info.load_store.offset.reg.shift_imm = 0x0;\n\t}\n\n\tif (p == 1) {\n\t\tif (w == 0) {\t/* offset */\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i, %s]\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\toperation,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tsuffix,\n\t\t\t\t\trd,\n\t\t\t\t\trn,\n\t\t\t\t\toffset);\n\n\t\t\tinstruction->info.load_store.index_mode = 0;\n\t\t} else {/* pre-indexed */\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i, %s]!\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\toperation,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tsuffix,\n\t\t\t\t\trd,\n\t\t\t\t\trn,\n\t\t\t\t\toffset);\n\n\t\t\tinstruction->info.load_store.index_mode = 1;\n\t\t}\n\t} else {/* post-indexed */\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, [r%i], %s\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\toperation,\n\t\t\t\tCOND(opcode),\n\t\t\t\tsuffix,\n\t\t\t\trd,\n\t\t\t\trn,\n\t\t\t\toffset);\n\n\t\tinstruction->info.load_store.index_mode = 2;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Load/store multiples instructions */\nstatic int evaluate_ldm_stm(uint32_t opcode,\n\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t p, u, s, w, l, rn;\n\tuint32_t register_list;\n\tchar *addressing_mode;\n\tchar *mnemonic;\n\tchar reg_list[69];\n\tchar *reg_list_p;\n\tint i;\n\tint first_reg = 1;\n\n\tp = (opcode & 0x01000000) >> 24;\n\tu = (opcode & 0x00800000) >> 23;\n\ts = (opcode & 0x00400000) >> 22;\n\tw = (opcode & 0x00200000) >> 21;\n\tl = (opcode & 0x00100000) >> 20;\n\tregister_list = (opcode & 0xffff);\n\trn = (opcode & 0xf0000) >> 16;\n\n\tinstruction->info.load_store_multiple.rn = rn;\n\tinstruction->info.load_store_multiple.register_list = register_list;\n\tinstruction->info.load_store_multiple.s = s;\n\tinstruction->info.load_store_multiple.w = w;\n\n\tif (l) {\n\t\tinstruction->type = ARM_LDM;\n\t\tmnemonic = \"LDM\";\n\t} else {\n\t\tinstruction->type = ARM_STM;\n\t\tmnemonic = \"STM\";\n\t}\n\n\tif (p) {\n\t\tif (u) {\n\t\t\tinstruction->info.load_store_multiple.addressing_mode = 1;\n\t\t\taddressing_mode = \"IB\";\n\t\t} else {\n\t\t\tinstruction->info.load_store_multiple.addressing_mode = 3;\n\t\t\taddressing_mode = \"DB\";\n\t\t}\n\t} else {\n\t\tif (u) {\n\t\t\tinstruction->info.load_store_multiple.addressing_mode = 0;\n\t\t\t/* \"IA\" is the default in UAL syntax */\n\t\t\taddressing_mode = \"\";\n\t\t} else {\n\t\t\tinstruction->info.load_store_multiple.addressing_mode = 2;\n\t\t\taddressing_mode = \"DA\";\n\t\t}\n\t}\n\n\treg_list_p = reg_list;\n\tfor (i = 0; i <= 15; i++) {\n\t\tif ((register_list >> i) & 1) {\n\t\t\tif (first_reg) {\n\t\t\t\tfirst_reg = 0;\n\t\t\t\treg_list_p += snprintf(reg_list_p,\n\t\t\t\t\t\t\t(reg_list + 69 - reg_list_p),\n\t\t\t\t\t\t\t\"r%i\",\n\t\t\t\t\t\t\ti);\n\t\t\t} else\n\t\t\t\treg_list_p += snprintf(reg_list_p,\n\t\t\t\t\t\t\t(reg_list + 69 - reg_list_p),\n\t\t\t\t\t\t\t\", r%i\",\n\t\t\t\t\t\t\ti);\n\t\t}\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32\n\t\t\t\"\\t%s%s%s r%i%s, {%s}%s\",\n\t\t\taddress, opcode,\n\t\t\tmnemonic, addressing_mode, COND(opcode),\n\t\t\trn, (w) ? \"!\" : \"\", reg_list, (s) ? \"^\" : \"\");\n\n\treturn ERROR_OK;\n}\n\n/* Multiplies, extra load/stores */\nstatic int evaluate_mul_and_extra_ld_st(uint32_t opcode,\n\t\t\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\t/* Multiply (accumulate) (long) and Swap/swap byte */\n\tif ((opcode & 0x000000f0) == 0x00000090) {\n\t\t/* Multiply (accumulate) */\n\t\tif ((opcode & 0x0f800000) == 0x00000000) {\n\t\t\tuint8_t rm, rs, rn, rd, s;\n\t\t\trm = opcode & 0xf;\n\t\t\trs = (opcode & 0xf00) >> 8;\n\t\t\trn = (opcode & 0xf000) >> 12;\n\t\t\trd = (opcode & 0xf0000) >> 16;\n\t\t\ts = (opcode & 0x00100000) >> 20;\n\n\t\t\t/* examine A bit (accumulate) */\n\t\t\tif (opcode & 0x00200000) {\n\t\t\t\tinstruction->type = ARM_MLA;\n\t\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t\t128,\n\t\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMLA%s%s r%i, r%i, r%i, r%i\",\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\topcode,\n\t\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t\t(s) ? \"S\" : \"\",\n\t\t\t\t\t\trd,\n\t\t\t\t\t\trm,\n\t\t\t\t\t\trs,\n\t\t\t\t\t\trn);\n\t\t\t} else {\n\t\t\t\tinstruction->type = ARM_MUL;\n\t\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t\t128,\n\t\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMUL%s%s r%i, r%i, r%i\",\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\topcode,\n\t\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t\t(s) ? \"S\" : \"\",\n\t\t\t\t\t\trd,\n\t\t\t\t\t\trm,\n\t\t\t\t\t\trs);\n\t\t\t}\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Multiply (accumulate) long */\n\t\tif ((opcode & 0x0f800000) == 0x00800000) {\n\t\t\tchar *mnemonic = NULL;\n\t\t\tuint8_t rm, rs, rd_hi, rd_low, s;\n\t\t\trm = opcode & 0xf;\n\t\t\trs = (opcode & 0xf00) >> 8;\n\t\t\trd_hi = (opcode & 0xf000) >> 12;\n\t\t\trd_low = (opcode & 0xf0000) >> 16;\n\t\t\ts = (opcode & 0x00100000) >> 20;\n\n\t\t\tswitch ((opcode & 0x00600000) >> 21) {\n\t\t\t\tcase 0x0:\n\t\t\t\t\tinstruction->type = ARM_UMULL;\n\t\t\t\t\tmnemonic = \"UMULL\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1:\n\t\t\t\t\tinstruction->type = ARM_UMLAL;\n\t\t\t\t\tmnemonic = \"UMLAL\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2:\n\t\t\t\t\tinstruction->type = ARM_SMULL;\n\t\t\t\t\tmnemonic = \"SMULL\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x3:\n\t\t\t\t\tinstruction->type = ARM_SMLAL;\n\t\t\t\t\tmnemonic = \"SMLAL\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\tmnemonic,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(s) ? \"S\" : \"\",\n\t\t\t\t\trd_low,\n\t\t\t\t\trd_hi,\n\t\t\t\t\trm,\n\t\t\t\t\trs);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Swap/swap byte */\n\t\tif ((opcode & 0x0f800000) == 0x01000000) {\n\t\t\tuint8_t rm, rd, rn;\n\t\t\trm = opcode & 0xf;\n\t\t\trd = (opcode & 0xf000) >> 12;\n\t\t\trn = (opcode & 0xf0000) >> 16;\n\n\t\t\t/* examine B flag */\n\t\t\tinstruction->type = (opcode & 0x00400000) ? ARM_SWPB : ARM_SWP;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s r%i, r%i, [r%i]\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(opcode & 0x00400000) ? \"SWPB\" : \"SWP\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd,\n\t\t\t\t\trm,\n\t\t\t\t\trn);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t}\n\n\treturn evaluate_misc_load_store(opcode, address, instruction);\n}\n\nstatic int evaluate_mrs_msr(uint32_t opcode,\n\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tint r = (opcode & 0x00400000) >> 22;\n\tchar *PSR = (r) ? \"SPSR\" : \"CPSR\";\n\n\t/* Move register to status register (MSR) */\n\tif (opcode & 0x00200000) {\n\t\tinstruction->type = ARM_MSR;\n\n\t\t/* immediate variant */\n\t\tif (opcode & 0x02000000) {\n\t\t\tuint8_t immediate = (opcode & 0xff);\n\t\t\tuint8_t rotate = (opcode & 0xf00);\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMSR%s %s_%s%s%s%s, 0x%8.8\" PRIx32,\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tPSR,\n\t\t\t\t\t(opcode & 0x10000) ? \"c\" : \"\",\n\t\t\t\t\t(opcode & 0x20000) ? \"x\" : \"\",\n\t\t\t\t\t(opcode & 0x40000) ? \"s\" : \"\",\n\t\t\t\t\t(opcode & 0x80000) ? \"f\" : \"\",\n\t\t\t\t\tror(immediate, (rotate * 2))\n\t\t\t\t\t);\n\t\t} else {/* register variant */\n\t\t\tuint8_t rm = opcode & 0xf;\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMSR%s %s_%s%s%s%s, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\tPSR,\n\t\t\t\t\t(opcode & 0x10000) ? \"c\" : \"\",\n\t\t\t\t\t(opcode & 0x20000) ? \"x\" : \"\",\n\t\t\t\t\t(opcode & 0x40000) ? \"s\" : \"\",\n\t\t\t\t\t(opcode & 0x80000) ? \"f\" : \"\",\n\t\t\t\t\trm\n\t\t\t\t\t);\n\t\t}\n\n\t} else {/* Move status register to register (MRS) */\n\t\tuint8_t rd;\n\n\t\tinstruction->type = ARM_MRS;\n\t\trd = (opcode & 0x0000f000) >> 12;\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMRS%s r%i, %s\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tCOND(opcode),\n\t\t\t\trd,\n\t\t\t\tPSR);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Miscellaneous instructions */\nstatic int evaluate_misc_instr(uint32_t opcode,\n\t\t\t       uint32_t address, struct arm_instruction *instruction)\n{\n\t/* MRS/MSR */\n\tif ((opcode & 0x000000f0) == 0x00000000)\n\t\tevaluate_mrs_msr(opcode, address, instruction);\n\n\t/* BX */\n\tif ((opcode & 0x006000f0) == 0x00200010) {\n\t\tuint8_t rm;\n\t\tinstruction->type = ARM_BX;\n\t\trm = opcode & 0xf;\n\n\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tBX%s r%i\",\n\t\t\t\taddress, opcode, COND(opcode), rm);\n\n\t\tinstruction->info.b_bl_bx_blx.reg_operand = rm;\n\t\tinstruction->info.b_bl_bx_blx.target_address = -1;\n\t}\n\n\t/* BXJ - \"Jazelle\" support (ARMv5-J) */\n\tif ((opcode & 0x006000f0) == 0x00200020) {\n\t\tuint8_t rm;\n\t\tinstruction->type = ARM_BX;\n\t\trm = opcode & 0xf;\n\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tBXJ%s r%i\",\n\t\t\t\taddress, opcode, COND(opcode), rm);\n\n\t\tinstruction->info.b_bl_bx_blx.reg_operand = rm;\n\t\tinstruction->info.b_bl_bx_blx.target_address = -1;\n\t}\n\n\t/* CLZ */\n\tif ((opcode & 0x006000f0) == 0x00600010) {\n\t\tuint8_t rm, rd;\n\t\tinstruction->type = ARM_CLZ;\n\t\trm = opcode & 0xf;\n\t\trd = (opcode & 0xf000) >> 12;\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tCLZ%s r%i, r%i\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tCOND(opcode),\n\t\t\t\trd,\n\t\t\t\trm);\n\t}\n\n\t/* BLX(2) */\n\tif ((opcode & 0x006000f0) == 0x00200030) {\n\t\tuint8_t rm;\n\t\tinstruction->type = ARM_BLX;\n\t\trm = opcode & 0xf;\n\n\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tBLX%s r%i\",\n\t\t\t\taddress, opcode, COND(opcode), rm);\n\n\t\tinstruction->info.b_bl_bx_blx.reg_operand = rm;\n\t\tinstruction->info.b_bl_bx_blx.target_address = -1;\n\t}\n\n\t/* Enhanced DSP add/subtracts */\n\tif ((opcode & 0x0000000f0) == 0x00000050) {\n\t\tuint8_t rm, rd, rn;\n\t\tchar *mnemonic = NULL;\n\t\trm = opcode & 0xf;\n\t\trd = (opcode & 0xf000) >> 12;\n\t\trn = (opcode & 0xf0000) >> 16;\n\n\t\tswitch ((opcode & 0x00600000) >> 21) {\n\t\t\tcase 0x0:\n\t\t\t\tinstruction->type = ARM_QADD;\n\t\t\t\tmnemonic = \"QADD\";\n\t\t\t\tbreak;\n\t\t\tcase 0x1:\n\t\t\t\tinstruction->type = ARM_QSUB;\n\t\t\t\tmnemonic = \"QSUB\";\n\t\t\t\tbreak;\n\t\t\tcase 0x2:\n\t\t\t\tinstruction->type = ARM_QDADD;\n\t\t\t\tmnemonic = \"QDADD\";\n\t\t\t\tbreak;\n\t\t\tcase 0x3:\n\t\t\t\tinstruction->type = ARM_QDSUB;\n\t\t\t\tmnemonic = \"QDSUB\";\n\t\t\t\tbreak;\n\t\t}\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s r%i, r%i, r%i\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tmnemonic,\n\t\t\t\tCOND(opcode),\n\t\t\t\trd,\n\t\t\t\trm,\n\t\t\t\trn);\n\t}\n\n\t/* exception return */\n\tif ((opcode & 0x0000000f0) == 0x00000060) {\n\t\tif (((opcode & 0x600000) >> 21) == 3)\n\t\t\tinstruction->type = ARM_ERET;\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tERET\",\n\t\t\t\taddress,\n\t\t\t\topcode);\n\t}\n\n\t/* exception generate instructions */\n\tif ((opcode & 0x0000000f0) == 0x00000070) {\n\t\tuint32_t immediate = 0;\n\t\tchar *mnemonic = NULL;\n\n\t\tswitch ((opcode & 0x600000) >> 21) {\n\t\t\tcase 0x1:\n\t\t\t\tinstruction->type = ARM_BKPT;\n\t\t\t\tmnemonic = \"BRKT\";\n\t\t\t\timmediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);\n\t\t\t\tbreak;\n\t\t\tcase 0x2:\n\t\t\t\tinstruction->type = ARM_HVC;\n\t\t\t\tmnemonic = \"HVC\";\n\t\t\t\timmediate = ((opcode & 0x000fff00) >> 4) | (opcode & 0xf);\n\t\t\t\tbreak;\n\t\t\tcase 0x3:\n\t\t\t\tinstruction->type = ARM_SMC;\n\t\t\t\tmnemonic = \"SMC\";\n\t\t\t\timmediate = (opcode & 0xf);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s 0x%4.4\" PRIx32 \"\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tmnemonic,\n\t\t\t\timmediate);\n\t}\n\n\t/* Enhanced DSP multiplies */\n\tif ((opcode & 0x000000090) == 0x00000080) {\n\t\tint x = (opcode & 0x20) >> 5;\n\t\tint y = (opcode & 0x40) >> 6;\n\n\t\t/* SMLA < x><y> */\n\t\tif ((opcode & 0x00600000) == 0x00000000) {\n\t\t\tuint8_t rd, rm, rs, rn;\n\t\t\tinstruction->type = ARM_SMLAXY;\n\t\t\trd = (opcode & 0xf0000) >> 16;\n\t\t\trm = (opcode & 0xf);\n\t\t\trs = (opcode & 0xf00) >> 8;\n\t\t\trn = (opcode & 0xf000) >> 12;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSMLA%s%s%s r%i, r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(x) ? \"T\" : \"B\",\n\t\t\t\t\t(y) ? \"T\" : \"B\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd,\n\t\t\t\t\trm,\n\t\t\t\t\trs,\n\t\t\t\t\trn);\n\t\t}\n\n\t\t/* SMLAL < x><y> */\n\t\tif ((opcode & 0x00600000) == 0x00400000) {\n\t\t\tuint8_t rd_low, rd_hi, rm, rs;\n\t\t\tinstruction->type = ARM_SMLAXY;\n\t\t\trd_hi = (opcode & 0xf0000) >> 16;\n\t\t\trd_low = (opcode & 0xf000) >> 12;\n\t\t\trm = (opcode & 0xf);\n\t\t\trs = (opcode & 0xf00) >> 8;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSMLA%s%s%s r%i, r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(x) ? \"T\" : \"B\",\n\t\t\t\t\t(y) ? \"T\" : \"B\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd_low,\n\t\t\t\t\trd_hi,\n\t\t\t\t\trm,\n\t\t\t\t\trs);\n\t\t}\n\n\t\t/* SMLAW < y> */\n\t\tif (((opcode & 0x00600000) == 0x00200000) && (x == 0)) {\n\t\t\tuint8_t rd, rm, rs, rn;\n\t\t\tinstruction->type = ARM_SMLAWY;\n\t\t\trd = (opcode & 0xf0000) >> 16;\n\t\t\trm = (opcode & 0xf);\n\t\t\trs = (opcode & 0xf00) >> 8;\n\t\t\trn = (opcode & 0xf000) >> 12;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSMLAW%s%s r%i, r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(y) ? \"T\" : \"B\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd,\n\t\t\t\t\trm,\n\t\t\t\t\trs,\n\t\t\t\t\trn);\n\t\t}\n\n\t\t/* SMUL < x><y> */\n\t\tif ((opcode & 0x00600000) == 0x00600000) {\n\t\t\tuint8_t rd, rm, rs;\n\t\t\tinstruction->type = ARM_SMULXY;\n\t\t\trd = (opcode & 0xf0000) >> 16;\n\t\t\trm = (opcode & 0xf);\n\t\t\trs = (opcode & 0xf00) >> 8;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSMULW%s%s%s r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(x) ? \"T\" : \"B\",\n\t\t\t\t\t(y) ? \"T\" : \"B\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd,\n\t\t\t\t\trm,\n\t\t\t\t\trs);\n\t\t}\n\n\t\t/* SMULW < y> */\n\t\tif (((opcode & 0x00600000) == 0x00200000) && (x == 1)) {\n\t\t\tuint8_t rd, rm, rs;\n\t\t\tinstruction->type = ARM_SMULWY;\n\t\t\trd = (opcode & 0xf0000) >> 16;\n\t\t\trm = (opcode & 0xf);\n\t\t\trs = (opcode & 0xf00) >> 8;\n\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tSMULW%s%s r%i, r%i, r%i\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\t(y) ? \"T\" : \"B\",\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\trd,\n\t\t\t\t\trm,\n\t\t\t\t\trs);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_mov_imm(uint32_t opcode,\n\t\t\t      uint32_t address, struct arm_instruction *instruction)\n{\n\tuint16_t immediate;\n\tuint8_t rd;\n\tbool t;\n\n\trd = (opcode & 0xf000) >> 12;\n\tt = opcode & 0x00400000;\n\timmediate = (opcode & 0xf0000) >> 4 | (opcode & 0xfff);\n\n\tinstruction->type = ARM_MOV;\n\tinstruction->info.data_proc.rd = rd;\n\n\tsnprintf(instruction->text,\n\t\t 128,\n\t\t \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tMOV%s%s r%i, #0x%\" PRIx16,\n\t\t address,\n\t\t opcode,\n\t\t t ? \"T\" : \"W\",\n\t\t COND(opcode),\n\t\t rd,\n\t\t immediate);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_data_proc(uint32_t opcode,\n\t\t\t      uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t i, op, s, rn, rd;\n\tchar *mnemonic = NULL;\n\tchar shifter_operand[32];\n\n\ti = (opcode & 0x02000000) >> 25;\n\top = (opcode & 0x01e00000) >> 21;\n\ts = (opcode & 0x00100000) >> 20;\n\n\trd = (opcode & 0xf000) >> 12;\n\trn = (opcode & 0xf0000) >> 16;\n\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = rn;\n\tinstruction->info.data_proc.s = s;\n\n\tswitch (op) {\n\t\tcase 0x0:\n\t\t\tinstruction->type = ARM_AND;\n\t\t\tmnemonic = \"AND\";\n\t\t\tbreak;\n\t\tcase 0x1:\n\t\t\tinstruction->type = ARM_EOR;\n\t\t\tmnemonic = \"EOR\";\n\t\t\tbreak;\n\t\tcase 0x2:\n\t\t\tinstruction->type = ARM_SUB;\n\t\t\tmnemonic = \"SUB\";\n\t\t\tbreak;\n\t\tcase 0x3:\n\t\t\tinstruction->type = ARM_RSB;\n\t\t\tmnemonic = \"RSB\";\n\t\t\tbreak;\n\t\tcase 0x4:\n\t\t\tinstruction->type = ARM_ADD;\n\t\t\tmnemonic = \"ADD\";\n\t\t\tbreak;\n\t\tcase 0x5:\n\t\t\tinstruction->type = ARM_ADC;\n\t\t\tmnemonic = \"ADC\";\n\t\t\tbreak;\n\t\tcase 0x6:\n\t\t\tinstruction->type = ARM_SBC;\n\t\t\tmnemonic = \"SBC\";\n\t\t\tbreak;\n\t\tcase 0x7:\n\t\t\tinstruction->type = ARM_RSC;\n\t\t\tmnemonic = \"RSC\";\n\t\t\tbreak;\n\t\tcase 0x8:\n\t\t\tinstruction->type = ARM_TST;\n\t\t\tmnemonic = \"TST\";\n\t\t\tbreak;\n\t\tcase 0x9:\n\t\t\tinstruction->type = ARM_TEQ;\n\t\t\tmnemonic = \"TEQ\";\n\t\t\tbreak;\n\t\tcase 0xa:\n\t\t\tinstruction->type = ARM_CMP;\n\t\t\tmnemonic = \"CMP\";\n\t\t\tbreak;\n\t\tcase 0xb:\n\t\t\tinstruction->type = ARM_CMN;\n\t\t\tmnemonic = \"CMN\";\n\t\t\tbreak;\n\t\tcase 0xc:\n\t\t\tinstruction->type = ARM_ORR;\n\t\t\tmnemonic = \"ORR\";\n\t\t\tbreak;\n\t\tcase 0xd:\n\t\t\tinstruction->type = ARM_MOV;\n\t\t\tmnemonic = \"MOV\";\n\t\t\tbreak;\n\t\tcase 0xe:\n\t\t\tinstruction->type = ARM_BIC;\n\t\t\tmnemonic = \"BIC\";\n\t\t\tbreak;\n\t\tcase 0xf:\n\t\t\tinstruction->type = ARM_MVN;\n\t\t\tmnemonic = \"MVN\";\n\t\t\tbreak;\n\t}\n\n\tif (i) {/* immediate shifter operand (#<immediate>)*/\n\t\tuint8_t immed_8 = opcode & 0xff;\n\t\tuint8_t rotate_imm = (opcode & 0xf00) >> 8;\n\t\tuint32_t immediate;\n\n\t\timmediate = ror(immed_8, rotate_imm * 2);\n\n\t\tsnprintf(shifter_operand, 32, \"#0x%\" PRIx32 \"\", immediate);\n\n\t\tinstruction->info.data_proc.variant = 0;\n\t\tinstruction->info.data_proc.shifter_operand.immediate.immediate = immediate;\n\t} else {/* register-based shifter operand */\n\t\tuint8_t shift, rm;\n\t\tshift = (opcode & 0x60) >> 5;\n\t\trm = (opcode & 0xf);\n\n\t\tif ((opcode & 0x10) != 0x10) {\t/* Immediate shifts (\"<Rm>\" or \"<Rm>, <shift>\n\t\t\t\t\t\t *#<shift_immediate>\") */\n\t\t\tuint8_t shift_imm;\n\t\t\tshift_imm = (opcode & 0xf80) >> 7;\n\n\t\t\tinstruction->info.data_proc.variant = 1;\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.rm = rm;\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift_imm =\n\t\t\t\tshift_imm;\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift = shift;\n\n\t\t\t/* LSR encodes a shift by 32 bit as 0x0 */\n\t\t\tif ((shift == 0x1) && (shift_imm == 0x0))\n\t\t\t\tshift_imm = 0x20;\n\n\t\t\t/* ASR encodes a shift by 32 bit as 0x0 */\n\t\t\tif ((shift == 0x2) && (shift_imm == 0x0))\n\t\t\t\tshift_imm = 0x20;\n\n\t\t\t/* ROR by 32 bit is actually a RRX */\n\t\t\tif ((shift == 0x3) && (shift_imm == 0x0))\n\t\t\t\tshift = 0x4;\n\n\t\t\tif ((shift_imm == 0x0) && (shift == 0x0))\n\t\t\t\tsnprintf(shifter_operand, 32, \"r%i\", rm);\n\t\t\telse {\n\t\t\t\tif (shift == 0x0)\t/* LSL */\n\t\t\t\t\tsnprintf(shifter_operand,\n\t\t\t\t\t\t\t32,\n\t\t\t\t\t\t\t\"r%i, LSL #0x%x\",\n\t\t\t\t\t\t\trm,\n\t\t\t\t\t\t\tshift_imm);\n\t\t\t\telse if (shift == 0x1)\t/* LSR */\n\t\t\t\t\tsnprintf(shifter_operand,\n\t\t\t\t\t\t\t32,\n\t\t\t\t\t\t\t\"r%i, LSR #0x%x\",\n\t\t\t\t\t\t\trm,\n\t\t\t\t\t\t\tshift_imm);\n\t\t\t\telse if (shift == 0x2)\t/* ASR */\n\t\t\t\t\tsnprintf(shifter_operand,\n\t\t\t\t\t\t\t32,\n\t\t\t\t\t\t\t\"r%i, ASR #0x%x\",\n\t\t\t\t\t\t\trm,\n\t\t\t\t\t\t\tshift_imm);\n\t\t\t\telse if (shift == 0x3)\t/* ROR */\n\t\t\t\t\tsnprintf(shifter_operand,\n\t\t\t\t\t\t\t32,\n\t\t\t\t\t\t\t\"r%i, ROR #0x%x\",\n\t\t\t\t\t\t\trm,\n\t\t\t\t\t\t\tshift_imm);\n\t\t\t\telse if (shift == 0x4)\t/* RRX */\n\t\t\t\t\tsnprintf(shifter_operand, 32, \"r%i, RRX\", rm);\n\t\t\t}\n\t\t} else {/* Register shifts (\"<Rm>, <shift> <Rs>\") */\n\t\t\tuint8_t rs = (opcode & 0xf00) >> 8;\n\n\t\t\tinstruction->info.data_proc.variant = 2;\n\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rm = rm;\n\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rs = rs;\n\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.shift = shift;\n\n\t\t\tif (shift == 0x0)\t/* LSL */\n\t\t\t\tsnprintf(shifter_operand, 32, \"r%i, LSL r%i\", rm, rs);\n\t\t\telse if (shift == 0x1)\t/* LSR */\n\t\t\t\tsnprintf(shifter_operand, 32, \"r%i, LSR r%i\", rm, rs);\n\t\t\telse if (shift == 0x2)\t/* ASR */\n\t\t\t\tsnprintf(shifter_operand, 32, \"r%i, ASR r%i\", rm, rs);\n\t\t\telse if (shift == 0x3)\t/* ROR */\n\t\t\t\tsnprintf(shifter_operand, 32, \"r%i, ROR r%i\", rm, rs);\n\t\t}\n\t}\n\n\tif ((op < 0x8) || (op == 0xc) || (op == 0xe)) {\t/* <opcode3>{<cond>}{S} <Rd>, <Rn>,\n\t\t\t\t\t\t\t *<shifter_operand> */\n\t\tsnprintf(instruction->text,\n\t\t\t\t128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, r%i, %s\",\n\t\t\t\taddress,\n\t\t\t\topcode,\n\t\t\t\tmnemonic,\n\t\t\t\tCOND(opcode),\n\t\t\t\t(s) ? \"S\" : \"\",\n\t\t\t\trd,\n\t\t\t\trn,\n\t\t\t\tshifter_operand);\n\t} else if ((op == 0xd) || (op == 0xf)) {\t/* <opcode1>{<cond>}{S} <Rd>,\n\t\t\t\t\t\t\t *<shifter_operand> */\n\t\tif (opcode == 0xe1a00000)\t/* print MOV r0,r0 as NOP */\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tNOP\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode);\n\t\telse\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s%s r%i, %s\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode,\n\t\t\t\t\tmnemonic,\n\t\t\t\t\tCOND(opcode),\n\t\t\t\t\t(s) ? \"S\" : \"\",\n\t\t\t\t\trd,\n\t\t\t\t\tshifter_operand);\n\t} else {/* <opcode2>{<cond>} <Rn>, <shifter_operand> */\n\t\tsnprintf(instruction->text, 128, \"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\t%s%s r%i, %s\",\n\t\t\t\taddress, opcode, mnemonic, COND(opcode),\n\t\t\t\trn, shifter_operand);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint arm_evaluate_opcode(uint32_t opcode, uint32_t address,\n\t\t\tstruct arm_instruction *instruction)\n{\n\t/* clear fields, to avoid confusion */\n\tmemset(instruction, 0, sizeof(struct arm_instruction));\n\tinstruction->opcode = opcode;\n\tinstruction->instruction_size = 4;\n\n\t/* catch opcodes with condition field [31:28] = b1111 */\n\tif ((opcode & 0xf0000000) == 0xf0000000) {\n\t\t/* Undefined instruction (or ARMv5E cache preload PLD) */\n\t\tif ((opcode & 0x08000000) == 0x00000000)\n\t\t\treturn evaluate_pld(opcode, address, instruction);\n\n\t\t/* Undefined instruction (or ARMv6+ SRS/RFE) */\n\t\tif ((opcode & 0x0e000000) == 0x08000000)\n\t\t\treturn evaluate_srs(opcode, address, instruction);\n\n\t\t/* Branch and branch with link and change to Thumb */\n\t\tif ((opcode & 0x0e000000) == 0x0a000000)\n\t\t\treturn evaluate_blx_imm(opcode, address, instruction);\n\n\t\t/* Extended coprocessor opcode space (ARMv5 and higher)\n\t\t * Coprocessor load/store and double register transfers */\n\t\tif ((opcode & 0x0e000000) == 0x0c000000)\n\t\t\treturn evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);\n\n\t\t/* Coprocessor data processing */\n\t\tif ((opcode & 0x0f000100) == 0x0c000000)\n\t\t\treturn evaluate_cdp_mcr_mrc(opcode, address, instruction);\n\n\t\t/* Coprocessor register transfers */\n\t\tif ((opcode & 0x0f000010) == 0x0c000010)\n\t\t\treturn evaluate_cdp_mcr_mrc(opcode, address, instruction);\n\n\t\t/* Undefined instruction */\n\t\tif ((opcode & 0x0f000000) == 0x0f000000) {\n\t\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\t\tsnprintf(instruction->text,\n\t\t\t\t\t128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tUNDEFINED INSTRUCTION\",\n\t\t\t\t\taddress,\n\t\t\t\t\topcode);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* catch opcodes with [27:25] = b000 */\n\tif ((opcode & 0x0e000000) == 0x00000000) {\n\t\t/* Multiplies, extra load/stores */\n\t\tif ((opcode & 0x00000090) == 0x00000090)\n\t\t\treturn evaluate_mul_and_extra_ld_st(opcode, address, instruction);\n\n\t\t/* Miscellaneous instructions */\n\t\tif ((opcode & 0x0f900000) == 0x01000000)\n\t\t\treturn evaluate_misc_instr(opcode, address, instruction);\n\n\t\treturn evaluate_data_proc(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b001 */\n\tif ((opcode & 0x0e000000) == 0x02000000) {\n\t\t/* 16-bit immediate load */\n\t\tif ((opcode & 0x0fb00000) == 0x03000000)\n\t\t\treturn evaluate_mov_imm(opcode, address, instruction);\n\n\t\t/* Move immediate to status register */\n\t\tif ((opcode & 0x0fb00000) == 0x03200000)\n\t\t\treturn evaluate_mrs_msr(opcode, address, instruction);\n\n\t\treturn evaluate_data_proc(opcode, address, instruction);\n\n\t}\n\n\t/* catch opcodes with [27:25] = b010 */\n\tif ((opcode & 0x0e000000) == 0x04000000) {\n\t\t/* Load/store immediate offset */\n\t\treturn evaluate_load_store(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b011 */\n\tif ((opcode & 0x0e000000) == 0x06000000) {\n\t\t/* Load/store register offset */\n\t\tif ((opcode & 0x00000010) == 0x00000000)\n\t\t\treturn evaluate_load_store(opcode, address, instruction);\n\n\t\t/* Architecturally Undefined instruction\n\t\t * ... don't expect these to ever be used\n\t\t */\n\t\tif ((opcode & 0x07f000f0) == 0x07f000f0) {\n\t\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"\\t0x%8.8\" PRIx32 \"\\tUNDEF\",\n\t\t\t\t\taddress, opcode);\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* \"media\" instructions */\n\t\treturn evaluate_media(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b100 */\n\tif ((opcode & 0x0e000000) == 0x08000000) {\n\t\t/* Load/store multiple */\n\t\treturn evaluate_ldm_stm(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b101 */\n\tif ((opcode & 0x0e000000) == 0x0a000000) {\n\t\t/* Branch and branch with link */\n\t\treturn evaluate_b_bl(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b110 */\n\tif ((opcode & 0x0e000000) == 0x0c000000) {\n\t\t/* Coprocessor load/store and double register transfers */\n\t\treturn evaluate_ldc_stc_mcrr_mrrc(opcode, address, instruction);\n\t}\n\n\t/* catch opcodes with [27:25] = b111 */\n\tif ((opcode & 0x0e000000) == 0x0e000000) {\n\t\t/* Software interrupt */\n\t\tif ((opcode & 0x0f000000) == 0x0f000000)\n\t\t\treturn evaluate_swi(opcode, address, instruction);\n\n\t\t/* Coprocessor data processing */\n\t\tif ((opcode & 0x0f000010) == 0x0e000000)\n\t\t\treturn evaluate_cdp_mcr_mrc(opcode, address, instruction);\n\n\t\t/* Coprocessor register transfers */\n\t\tif ((opcode & 0x0f000010) == 0x0e000010)\n\t\t\treturn evaluate_cdp_mcr_mrc(opcode, address, instruction);\n\t}\n\n\tLOG_ERROR(\"ARM: should never reach this point (opcode=%08x)\",\n\t\t\t(unsigned) opcode);\n\treturn -1;\n}\n\nstatic int evaluate_b_bl_blx_thumb(uint16_t opcode,\n\t\t\t\t   uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t offset = opcode & 0x7ff;\n\tuint32_t opc = (opcode >> 11) & 0x3;\n\tuint32_t target_address;\n\tchar *mnemonic = NULL;\n\n\t/* sign extend 11-bit offset */\n\tif (((opc == 0) || (opc == 2)) && (offset & 0x00000400))\n\t\toffset = 0xfffff800 | offset;\n\n\ttarget_address = address + 4 + (offset << 1);\n\n\tswitch (opc) {\n\t\t/* unconditional branch */\n\t\tcase 0:\n\t\t\tinstruction->type = ARM_B;\n\t\t\tmnemonic = \"B\";\n\t\t\tbreak;\n\t\t/* BLX suffix */\n\t\tcase 1:\n\t\t\tinstruction->type = ARM_BLX;\n\t\t\tmnemonic = \"BLX\";\n\t\t\ttarget_address &= 0xfffffffc;\n\t\t\tbreak;\n\t\t/* BL/BLX prefix */\n\t\tcase 2:\n\t\t\tinstruction->type = ARM_UNKNOWN_INSTRUCTION;\n\t\t\tmnemonic = \"prefix\";\n\t\t\ttarget_address = offset << 12;\n\t\t\tbreak;\n\t\t/* BL suffix */\n\t\tcase 3:\n\t\t\tinstruction->type = ARM_BL;\n\t\t\tmnemonic = \"BL\";\n\t\t\tbreak;\n\t}\n\n\t/* TODO: deal correctly with dual opcode (prefixed) BL/BLX;\n\t * these are effectively 32-bit instructions even in Thumb1.  For\n\t * disassembly, it's simplest to always use the Thumb2 decoder.\n\t *\n\t * But some cores will evidently handle them as two instructions,\n\t * where exceptions may occur between the two.  The ETMv3.2+ ID\n\t * register has a bit which exposes this behavior.\n\t */\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\t%#8.8\" PRIx32,\n\t\t\taddress, opcode, mnemonic, target_address);\n\n\tinstruction->info.b_bl_bx_blx.reg_operand = -1;\n\tinstruction->info.b_bl_bx_blx.target_address = target_address;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_add_sub_thumb(uint16_t opcode,\n\t\t\t\t  uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t rd = (opcode >> 0) & 0x7;\n\tuint8_t rn = (opcode >> 3) & 0x7;\n\tuint8_t rm_imm = (opcode >> 6) & 0x7;\n\tuint32_t opc = opcode & (1 << 9);\n\tuint32_t reg_imm  = opcode & (1 << 10);\n\tchar *mnemonic;\n\n\tif (opc) {\n\t\tinstruction->type = ARM_SUB;\n\t\tmnemonic = \"SUBS\";\n\t} else {\n\t\t/* REVISIT:  if reg_imm == 0, display as \"MOVS\" */\n\t\tinstruction->type = ARM_ADD;\n\t\tmnemonic = \"ADDS\";\n\t}\n\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = rn;\n\tinstruction->info.data_proc.s = 1;\n\n\tif (reg_imm) {\n\t\tinstruction->info.data_proc.variant = 0;/*immediate*/\n\t\tinstruction->info.data_proc.shifter_operand.immediate.immediate = rm_imm;\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, r%i, #%d\",\n\t\t\t\taddress, opcode, mnemonic, rd, rn, rm_imm);\n\t} else {\n\t\tinstruction->info.data_proc.variant = 1;/*immediate shift*/\n\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.rm = rm_imm;\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, r%i, r%i\",\n\t\t\t\taddress, opcode, mnemonic, rd, rn, rm_imm);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_shift_imm_thumb(uint16_t opcode,\n\t\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t rd = (opcode >> 0) & 0x7;\n\tuint8_t rm = (opcode >> 3) & 0x7;\n\tuint8_t imm = (opcode >> 6) & 0x1f;\n\tuint8_t opc = (opcode >> 11) & 0x3;\n\tchar *mnemonic = NULL;\n\n\tswitch (opc) {\n\t\tcase 0:\n\t\t\tinstruction->type = ARM_MOV;\n\t\t\tmnemonic = \"LSLS\";\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift = 0;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tinstruction->type = ARM_MOV;\n\t\t\tmnemonic = \"LSRS\";\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift = 1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tinstruction->type = ARM_MOV;\n\t\t\tmnemonic = \"ASRS\";\n\t\t\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift = 2;\n\t\t\tbreak;\n\t}\n\n\tif ((imm == 0) && (opc != 0))\n\t\timm = 32;\n\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = -1;\n\tinstruction->info.data_proc.s = 1;\n\n\tinstruction->info.data_proc.variant = 1;/*immediate_shift*/\n\tinstruction->info.data_proc.shifter_operand.immediate_shift.rm = rm;\n\tinstruction->info.data_proc.shifter_operand.immediate_shift.shift_imm = imm;\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, r%i, #%#2.2x\",\n\t\t\taddress, opcode, mnemonic, rd, rm, imm);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_data_proc_imm_thumb(uint16_t opcode,\n\t\t\t\t\tuint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t imm = opcode & 0xff;\n\tuint8_t rd = (opcode >> 8) & 0x7;\n\tuint32_t opc = (opcode >> 11) & 0x3;\n\tchar *mnemonic = NULL;\n\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = rd;\n\tinstruction->info.data_proc.s = 1;\n\tinstruction->info.data_proc.variant = 0;/*immediate*/\n\tinstruction->info.data_proc.shifter_operand.immediate.immediate = imm;\n\n\tswitch (opc) {\n\t\tcase 0:\n\t\t\tinstruction->type = ARM_MOV;\n\t\t\tmnemonic = \"MOVS\";\n\t\t\tinstruction->info.data_proc.rn = -1;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tinstruction->type = ARM_CMP;\n\t\t\tmnemonic = \"CMP\";\n\t\t\tinstruction->info.data_proc.rd = -1;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tinstruction->type = ARM_ADD;\n\t\t\tmnemonic = \"ADDS\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tinstruction->type = ARM_SUB;\n\t\t\tmnemonic = \"SUBS\";\n\t\t\tbreak;\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, #%#2.2x\",\n\t\t\taddress, opcode, mnemonic, rd, imm);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_data_proc_thumb(uint16_t opcode,\n\t\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t high_reg, op, rm, rd, h1, h2;\n\tchar *mnemonic = NULL;\n\tbool nop = false;\n\n\thigh_reg = (opcode & 0x0400) >> 10;\n\top = (opcode & 0x03C0) >> 6;\n\n\trd = (opcode & 0x0007);\n\trm = (opcode & 0x0038) >> 3;\n\th1 = (opcode & 0x0080) >> 7;\n\th2 = (opcode & 0x0040) >> 6;\n\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = rd;\n\tinstruction->info.data_proc.s = (!high_reg || (instruction->type == ARM_CMP));\n\tinstruction->info.data_proc.variant = 1\t/*immediate shift*/;\n\tinstruction->info.data_proc.shifter_operand.immediate_shift.rm = rm;\n\n\tif (high_reg) {\n\t\trd |= h1 << 3;\n\t\trm |= h2 << 3;\n\t\top >>= 2;\n\n\t\tswitch (op) {\n\t\t\tcase 0x0:\n\t\t\t\tinstruction->type = ARM_ADD;\n\t\t\t\tmnemonic = \"ADD\";\n\t\t\t\tbreak;\n\t\t\tcase 0x1:\n\t\t\t\tinstruction->type = ARM_CMP;\n\t\t\t\tmnemonic = \"CMP\";\n\t\t\t\tbreak;\n\t\t\tcase 0x2:\n\t\t\t\tinstruction->type = ARM_MOV;\n\t\t\t\tmnemonic = \"MOV\";\n\t\t\t\tif (rd == rm)\n\t\t\t\t\tnop = true;\n\t\t\t\tbreak;\n\t\t\tcase 0x3:\n\t\t\t\tif ((opcode & 0x7) == 0x0) {\n\t\t\t\t\tinstruction->info.b_bl_bx_blx.reg_operand = rm;\n\t\t\t\t\tif (h1) {\n\t\t\t\t\t\tinstruction->type = ARM_BLX;\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t\t\"0x%8.8\" PRIx32\n\t\t\t\t\t\t\t\t\"  0x%4.4x    \\tBLX\\tr%i\",\n\t\t\t\t\t\t\t\taddress, opcode, rm);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tinstruction->type = ARM_BX;\n\t\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t\t\"0x%8.8\" PRIx32\n\t\t\t\t\t\t\t\t\"  0x%4.4x    \\tBX\\tr%i\",\n\t\t\t\t\t\t\t\taddress, opcode, rm);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\t\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\t\t\"0x%8.8\" PRIx32\n\t\t\t\t\t\t\t\"  0x%4.4x    \\t\"\n\t\t\t\t\t\t\t\"UNDEFINED INSTRUCTION\",\n\t\t\t\t\t\t\taddress, opcode);\n\t\t\t\t}\n\t\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\tswitch (op) {\n\t\t\tcase 0x0:\n\t\t\t\tinstruction->type = ARM_AND;\n\t\t\t\tmnemonic = \"ANDS\";\n\t\t\t\tbreak;\n\t\t\tcase 0x1:\n\t\t\t\tinstruction->type = ARM_EOR;\n\t\t\t\tmnemonic = \"EORS\";\n\t\t\t\tbreak;\n\t\t\tcase 0x2:\n\t\t\t\tinstruction->type = ARM_MOV;\n\t\t\t\tmnemonic = \"LSLS\";\n\t\t\t\tinstruction->info.data_proc.variant = 2\t/*register shift*/;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.shift = 0;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rm = rd;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rs = rm;\n\t\t\t\tbreak;\n\t\t\tcase 0x3:\n\t\t\t\tinstruction->type = ARM_MOV;\n\t\t\t\tmnemonic = \"LSRS\";\n\t\t\t\tinstruction->info.data_proc.variant = 2\t/*register shift*/;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.shift = 1;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rm = rd;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rs = rm;\n\t\t\t\tbreak;\n\t\t\tcase 0x4:\n\t\t\t\tinstruction->type = ARM_MOV;\n\t\t\t\tmnemonic = \"ASRS\";\n\t\t\t\tinstruction->info.data_proc.variant = 2\t/*register shift*/;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.shift = 2;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rm = rd;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rs = rm;\n\t\t\t\tbreak;\n\t\t\tcase 0x5:\n\t\t\t\tinstruction->type = ARM_ADC;\n\t\t\t\tmnemonic = \"ADCS\";\n\t\t\t\tbreak;\n\t\t\tcase 0x6:\n\t\t\t\tinstruction->type = ARM_SBC;\n\t\t\t\tmnemonic = \"SBCS\";\n\t\t\t\tbreak;\n\t\t\tcase 0x7:\n\t\t\t\tinstruction->type = ARM_MOV;\n\t\t\t\tmnemonic = \"RORS\";\n\t\t\t\tinstruction->info.data_proc.variant = 2\t/*register shift*/;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.shift = 3;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rm = rd;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.register_shift.rs = rm;\n\t\t\t\tbreak;\n\t\t\tcase 0x8:\n\t\t\t\tinstruction->type = ARM_TST;\n\t\t\t\tmnemonic = \"TST\";\n\t\t\t\tbreak;\n\t\t\tcase 0x9:\n\t\t\t\tinstruction->type = ARM_RSB;\n\t\t\t\tmnemonic = \"RSBS\";\n\t\t\t\tinstruction->info.data_proc.variant = 0\t/*immediate*/;\n\t\t\t\tinstruction->info.data_proc.shifter_operand.immediate.immediate = 0;\n\t\t\t\tinstruction->info.data_proc.rn = rm;\n\t\t\t\tbreak;\n\t\t\tcase 0xA:\n\t\t\t\tinstruction->type = ARM_CMP;\n\t\t\t\tmnemonic = \"CMP\";\n\t\t\t\tbreak;\n\t\t\tcase 0xB:\n\t\t\t\tinstruction->type = ARM_CMN;\n\t\t\t\tmnemonic = \"CMN\";\n\t\t\t\tbreak;\n\t\t\tcase 0xC:\n\t\t\t\tinstruction->type = ARM_ORR;\n\t\t\t\tmnemonic = \"ORRS\";\n\t\t\t\tbreak;\n\t\t\tcase 0xD:\n\t\t\t\tinstruction->type = ARM_MUL;\n\t\t\t\tmnemonic = \"MULS\";\n\t\t\t\tbreak;\n\t\t\tcase 0xE:\n\t\t\t\tinstruction->type = ARM_BIC;\n\t\t\t\tmnemonic = \"BICS\";\n\t\t\t\tbreak;\n\t\t\tcase 0xF:\n\t\t\t\tinstruction->type = ARM_MVN;\n\t\t\t\tmnemonic = \"MVNS\";\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (nop)\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tNOP\\t\\t\\t\"\n\t\t\t\t\"; (%s r%i, r%i)\",\n\t\t\t\taddress, opcode, mnemonic, rd, rm);\n\telse\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, r%i\",\n\t\t\t\taddress, opcode, mnemonic, rd, rm);\n\n\treturn ERROR_OK;\n}\n\n/* PC-relative data addressing is word-aligned even with Thumb */\nstatic inline uint32_t thumb_alignpc4(uint32_t addr)\n{\n\treturn (addr + 4) & ~3;\n}\n\nstatic int evaluate_load_literal_thumb(uint16_t opcode,\n\t\t\t\t       uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t immediate;\n\tuint8_t rd = (opcode >> 8) & 0x7;\n\n\tinstruction->type = ARM_LDR;\n\timmediate = opcode & 0x000000ff;\n\timmediate *= 4;\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = 15 /*PC*/;\n\tinstruction->info.load_store.index_mode = 0;\t/*offset*/\n\tinstruction->info.load_store.offset_mode = 0;\t/*immediate*/\n\tinstruction->info.load_store.offset.offset = immediate;\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t\"\n\t\t\t\"LDR\\tr%i, [pc, #%#\" PRIx32 \"]\\t; %#8.8\" PRIx32,\n\t\t\taddress, opcode, rd, immediate,\n\t\t\tthumb_alignpc4(address) + immediate);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_load_store_reg_thumb(uint16_t opcode,\n\t\t\t\t\t uint32_t address, struct arm_instruction *instruction)\n{\n\tuint8_t rd = (opcode >> 0) & 0x7;\n\tuint8_t rn = (opcode >> 3) & 0x7;\n\tuint8_t rm = (opcode >> 6) & 0x7;\n\tuint8_t opc = (opcode >> 9) & 0x7;\n\tchar *mnemonic = NULL;\n\n\tswitch (opc) {\n\t\tcase 0:\n\t\t\tinstruction->type = ARM_STR;\n\t\t\tmnemonic = \"STR\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tinstruction->type = ARM_STRH;\n\t\t\tmnemonic = \"STRH\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tinstruction->type = ARM_STRB;\n\t\t\tmnemonic = \"STRB\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tinstruction->type = ARM_LDRSB;\n\t\t\tmnemonic = \"LDRSB\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tinstruction->type = ARM_LDR;\n\t\t\tmnemonic = \"LDR\";\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tinstruction->type = ARM_LDRH;\n\t\t\tmnemonic = \"LDRH\";\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tinstruction->type = ARM_LDRB;\n\t\t\tmnemonic = \"LDRB\";\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tinstruction->type = ARM_LDRSH;\n\t\t\tmnemonic = \"LDRSH\";\n\t\t\tbreak;\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, [r%i, r%i]\",\n\t\t\taddress, opcode, mnemonic, rd, rn, rm);\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = rn;\n\tinstruction->info.load_store.index_mode = 0;\t/*offset*/\n\tinstruction->info.load_store.offset_mode = 1;\t/*register*/\n\tinstruction->info.load_store.offset.reg.rm = rm;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_load_store_imm_thumb(uint16_t opcode,\n\t\t\t\t\t uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t offset = (opcode >> 6) & 0x1f;\n\tuint8_t rd = (opcode >> 0) & 0x7;\n\tuint8_t rn = (opcode >> 3) & 0x7;\n\tuint32_t l = opcode & (1 << 11);\n\tuint32_t b = opcode & (1 << 12);\n\tchar *mnemonic;\n\tchar suffix = ' ';\n\tuint32_t shift = 2;\n\n\tif (l) {\n\t\tinstruction->type = ARM_LDR;\n\t\tmnemonic = \"LDR\";\n\t} else {\n\t\tinstruction->type = ARM_STR;\n\t\tmnemonic = \"STR\";\n\t}\n\n\tif ((opcode&0xF000) == 0x8000) {\n\t\tsuffix = 'H';\n\t\tshift = 1;\n\t} else if (b) {\n\t\tsuffix = 'B';\n\t\tshift = 0;\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s%c\\tr%i, [r%i, #%#\" PRIx32 \"]\",\n\t\t\taddress, opcode, mnemonic, suffix, rd, rn, offset << shift);\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = rn;\n\tinstruction->info.load_store.index_mode = 0;\t/*offset*/\n\tinstruction->info.load_store.offset_mode = 0;\t/*immediate*/\n\tinstruction->info.load_store.offset.offset = offset << shift;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_load_store_stack_thumb(uint16_t opcode,\n\t\t\t\t\t   uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t offset = opcode  & 0xff;\n\tuint8_t rd = (opcode >> 8) & 0x7;\n\tuint32_t l = opcode & (1 << 11);\n\tchar *mnemonic;\n\n\tif (l) {\n\t\tinstruction->type = ARM_LDR;\n\t\tmnemonic = \"LDR\";\n\t} else {\n\t\tinstruction->type = ARM_STR;\n\t\tmnemonic = \"STR\";\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tr%i, [SP, #%#\" PRIx32 \"]\",\n\t\t\taddress, opcode, mnemonic, rd, offset*4);\n\n\tinstruction->info.load_store.rd = rd;\n\tinstruction->info.load_store.rn = 13 /*SP*/;\n\tinstruction->info.load_store.index_mode = 0;\t/*offset*/\n\tinstruction->info.load_store.offset_mode = 0;\t/*immediate*/\n\tinstruction->info.load_store.offset.offset = offset*4;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_add_sp_pc_thumb(uint16_t opcode,\n\t\t\t\t    uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t imm = opcode  & 0xff;\n\tuint8_t rd = (opcode >> 8) & 0x7;\n\tuint8_t rn;\n\tuint32_t sp = opcode & (1 << 11);\n\tconst char *reg_name;\n\n\tinstruction->type = ARM_ADD;\n\n\tif (sp) {\n\t\treg_name = \"SP\";\n\t\trn = 13;\n\t} else {\n\t\treg_name = \"PC\";\n\t\trn = 15;\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x  \\tADD\\tr%i, %s, #%#\" PRIx32,\n\t\t\taddress, opcode, rd, reg_name, imm * 4);\n\n\tinstruction->info.data_proc.variant = 0\t/* immediate */;\n\tinstruction->info.data_proc.rd = rd;\n\tinstruction->info.data_proc.rn = rn;\n\tinstruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_adjust_stack_thumb(uint16_t opcode,\n\t\t\t\t       uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t imm = opcode  & 0x7f;\n\tuint8_t opc = opcode & (1 << 7);\n\tchar *mnemonic;\n\n\n\tif (opc) {\n\t\tinstruction->type = ARM_SUB;\n\t\tmnemonic = \"SUB\";\n\t} else {\n\t\tinstruction->type = ARM_ADD;\n\t\tmnemonic = \"ADD\";\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\\tSP, #%#\" PRIx32,\n\t\t\taddress, opcode, mnemonic, imm*4);\n\n\tinstruction->info.data_proc.variant = 0\t/* immediate */;\n\tinstruction->info.data_proc.rd = 13 /*SP*/;\n\tinstruction->info.data_proc.rn = 13 /*SP*/;\n\tinstruction->info.data_proc.shifter_operand.immediate.immediate = imm*4;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_breakpoint_thumb(uint16_t opcode,\n\t\t\t\t     uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t imm = opcode  & 0xff;\n\n\tinstruction->type = ARM_BKPT;\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x  \\tBKPT\\t%#2.2\" PRIx32 \"\",\n\t\t\taddress, opcode, imm);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_load_store_multiple_thumb(uint16_t opcode,\n\t\t\t\t\t      uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t reg_list = opcode  & 0xff;\n\tuint32_t l = opcode & (1 << 11);\n\tuint32_t r = opcode & (1 << 8);\n\tuint8_t rn = (opcode >> 8) & 7;\n\tuint8_t addr_mode = 0 /* IA */;\n\tchar reg_names[40];\n\tchar *reg_names_p;\n\tchar *mnemonic;\n\tchar ptr_name[7] = \"\";\n\tint i;\n\n\t/* REVISIT:  in ThumbEE mode, there are no LDM or STM instructions.\n\t * The STMIA and LDMIA opcodes are used for other instructions.\n\t */\n\n\tif ((opcode & 0xf000) == 0xc000) {\t/* generic load/store multiple */\n\t\tchar *wback = \"!\";\n\n\t\tif (l) {\n\t\t\tinstruction->type = ARM_LDM;\n\t\t\tmnemonic = \"LDM\";\n\t\t\tif (opcode & (1 << rn))\n\t\t\t\twback = \"\";\n\t\t} else {\n\t\t\tinstruction->type = ARM_STM;\n\t\t\tmnemonic = \"STM\";\n\t\t}\n\t\tsnprintf(ptr_name, sizeof(ptr_name), \"r%i%s, \", rn, wback);\n\t} else {/* push/pop */\n\t\trn = 13;/* SP */\n\t\tif (l) {\n\t\t\tinstruction->type = ARM_LDM;\n\t\t\tmnemonic = \"POP\";\n\t\t\tif (r)\n\t\t\t\treg_list |= (1 << 15) /*PC*/;\n\t\t} else {\n\t\t\tinstruction->type = ARM_STM;\n\t\t\tmnemonic = \"PUSH\";\n\t\t\taddr_mode = 3;\t/*DB*/\n\t\t\tif (r)\n\t\t\t\treg_list |= (1 << 14) /*LR*/;\n\t\t}\n\t}\n\n\treg_names_p = reg_names;\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (reg_list & (1 << i))\n\t\t\treg_names_p += snprintf(reg_names_p,\n\t\t\t\t\t\t(reg_names + 40 - reg_names_p),\n\t\t\t\t\t\t\"r%i, \",\n\t\t\t\t\t\ti);\n\t}\n\tif (reg_names_p > reg_names)\n\t\treg_names_p[-2] = '\\0';\n\telse\t/* invalid op : no registers */\n\t\treg_names[0] = '\\0';\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x  \\t%s\\t%s{%s}\",\n\t\t\taddress, opcode, mnemonic, ptr_name, reg_names);\n\n\tinstruction->info.load_store_multiple.register_list = reg_list;\n\tinstruction->info.load_store_multiple.rn = rn;\n\tinstruction->info.load_store_multiple.addressing_mode = addr_mode;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_cond_branch_thumb(uint16_t opcode,\n\t\t\t\t      uint32_t address, struct arm_instruction *instruction)\n{\n\tuint32_t offset = opcode  & 0xff;\n\tuint8_t cond = (opcode >> 8) & 0xf;\n\tuint32_t target_address;\n\n\tif (cond == 0xf) {\n\t\tinstruction->type = ARM_SWI;\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tSVC\\t%#2.2\" PRIx32,\n\t\t\t\taddress, opcode, offset);\n\t\treturn ERROR_OK;\n\t} else if (cond == 0xe) {\n\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tUNDEFINED INSTRUCTION\",\n\t\t\t\taddress, opcode);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* sign extend 8-bit offset */\n\tif (offset & 0x00000080)\n\t\toffset = 0xffffff00 | offset;\n\n\ttarget_address = address + 4 + (offset << 1);\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tB%s\\t%#8.8\" PRIx32,\n\t\t\taddress, opcode,\n\t\t\tarm_condition_strings[cond], target_address);\n\n\tinstruction->type = ARM_B;\n\tinstruction->info.b_bl_bx_blx.reg_operand = -1;\n\tinstruction->info.b_bl_bx_blx.target_address = target_address;\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_cb_thumb(uint16_t opcode, uint32_t address,\n\t\t\t     struct arm_instruction *instruction)\n{\n\tunsigned offset;\n\n\t/* added in Thumb2 */\n\toffset = (opcode >> 3) & 0x1f;\n\toffset |= (opcode & 0x0200) >> 4;\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tCB%sZ\\tr%d, %#8.8\" PRIx32,\n\t\t\taddress, opcode,\n\t\t\t(opcode & 0x0800) ? \"N\" : \"\",\n\t\t\topcode & 0x7, address + 4 + (offset << 1));\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_extend_thumb(uint16_t opcode, uint32_t address,\n\t\t\t\t struct arm_instruction *instruction)\n{\n\t/* added in ARMv6 */\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%cXT%c\\tr%d, r%d\",\n\t\t\taddress, opcode,\n\t\t\t(opcode & 0x0080) ? 'U' : 'S',\n\t\t\t(opcode & 0x0040) ? 'B' : 'H',\n\t\t\topcode & 0x7, (opcode >> 3) & 0x7);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_cps_thumb(uint16_t opcode, uint32_t address,\n\t\t\t      struct arm_instruction *instruction)\n{\n\t/* added in ARMv6 */\n\tif ((opcode & 0x0ff0) == 0x0650)\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tSETEND %s\",\n\t\t\t\taddress, opcode,\n\t\t\t\t(opcode & 0x80) ? \"BE\" : \"LE\");\n\telse\t/* ASSUME (opcode & 0x0fe0) == 0x0660 */\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tCPSI%c\\t%s%s%s\",\n\t\t\t\taddress, opcode,\n\t\t\t\t(opcode & 0x0010) ? 'D' : 'E',\n\t\t\t\t(opcode & 0x0004) ? \"A\" : \"\",\n\t\t\t\t(opcode & 0x0002) ? \"I\" : \"\",\n\t\t\t\t(opcode & 0x0001) ? \"F\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_byterev_thumb(uint16_t opcode, uint32_t address,\n\t\t\t\t  struct arm_instruction *instruction)\n{\n\tchar *suffix;\n\n\t/* added in ARMv6 */\n\tswitch ((opcode >> 6) & 3) {\n\t\tcase 0:\n\t\t\tsuffix = \"\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tsuffix = \"16\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tsuffix = \"SH\";\n\t\t\tbreak;\n\t}\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tREV%s\\tr%d, r%d\",\n\t\t\taddress, opcode, suffix,\n\t\t\topcode & 0x7, (opcode >> 3) & 0x7);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_hint_thumb(uint16_t opcode, uint32_t address,\n\t\t\t       struct arm_instruction *instruction)\n{\n\tchar *hint;\n\n\tswitch ((opcode >> 4) & 0x0f) {\n\t\tcase 0:\n\t\t\thint = \"NOP\";\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\thint = \"YIELD\";\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\thint = \"WFE\";\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\thint = \"WFI\";\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\thint = \"SEV\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\thint = \"HINT (UNRECOGNIZED)\";\n\t\t\tbreak;\n\t}\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\t%s\",\n\t\t\taddress, opcode, hint);\n\n\treturn ERROR_OK;\n}\n\nstatic int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,\n\t\t\t\t struct arm_instruction *instruction)\n{\n\tunsigned cond = (opcode >> 4) & 0x0f;\n\tchar *x = \"\", *y = \"\", *z = \"\";\n\n\tif (opcode & 0x01)\n\t\tz = (opcode & 0x02) ? \"T\" : \"E\";\n\tif (opcode & 0x03)\n\t\ty = (opcode & 0x04) ? \"T\" : \"E\";\n\tif (opcode & 0x07)\n\t\tx = (opcode & 0x08) ? \"T\" : \"E\";\n\n\tsnprintf(instruction->text, 128,\n\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tIT%s%s%s\\t%s\",\n\t\t\taddress, opcode,\n\t\t\tx, y, z, arm_condition_strings[cond]);\n\n\t/* NOTE:  strictly speaking, the next 1-4 instructions should\n\t * now be displayed with the relevant conditional suffix...\n\t */\n\n\treturn ERROR_OK;\n}\n\nint thumb_evaluate_opcode(uint16_t opcode, uint32_t address, struct arm_instruction *instruction)\n{\n\t/* clear fields, to avoid confusion */\n\tmemset(instruction, 0, sizeof(struct arm_instruction));\n\tinstruction->opcode = opcode;\n\tinstruction->instruction_size = 2;\n\n\tif ((opcode & 0xe000) == 0x0000) {\n\t\t/* add/subtract register or immediate */\n\t\tif ((opcode & 0x1800) == 0x1800)\n\t\t\treturn evaluate_add_sub_thumb(opcode, address, instruction);\n\t\t/* shift by immediate */\n\t\telse\n\t\t\treturn evaluate_shift_imm_thumb(opcode, address, instruction);\n\t}\n\n\t/* Add/subtract/compare/move immediate */\n\tif ((opcode & 0xe000) == 0x2000)\n\t\treturn evaluate_data_proc_imm_thumb(opcode, address, instruction);\n\n\t/* Data processing instructions */\n\tif ((opcode & 0xf800) == 0x4000)\n\t\treturn evaluate_data_proc_thumb(opcode, address, instruction);\n\n\t/* Load from literal pool */\n\tif ((opcode & 0xf800) == 0x4800)\n\t\treturn evaluate_load_literal_thumb(opcode, address, instruction);\n\n\t/* Load/Store register offset */\n\tif ((opcode & 0xf000) == 0x5000)\n\t\treturn evaluate_load_store_reg_thumb(opcode, address, instruction);\n\n\t/* Load/Store immediate offset */\n\tif (((opcode & 0xe000) == 0x6000)\n\t\t\t|| ((opcode & 0xf000) == 0x8000))\n\t\treturn evaluate_load_store_imm_thumb(opcode, address, instruction);\n\n\t/* Load/Store from/to stack */\n\tif ((opcode & 0xf000) == 0x9000)\n\t\treturn evaluate_load_store_stack_thumb(opcode, address, instruction);\n\n\t/* Add to SP/PC */\n\tif ((opcode & 0xf000) == 0xa000)\n\t\treturn evaluate_add_sp_pc_thumb(opcode, address, instruction);\n\n\t/* Misc */\n\tif ((opcode & 0xf000) == 0xb000) {\n\t\tswitch ((opcode >> 8) & 0x0f) {\n\t\t\tcase 0x0:\n\t\t\t\treturn evaluate_adjust_stack_thumb(opcode, address, instruction);\n\t\t\tcase 0x1:\n\t\t\tcase 0x3:\n\t\t\tcase 0x9:\n\t\t\tcase 0xb:\n\t\t\t\treturn evaluate_cb_thumb(opcode, address, instruction);\n\t\t\tcase 0x2:\n\t\t\t\treturn evaluate_extend_thumb(opcode, address, instruction);\n\t\t\tcase 0x4:\n\t\t\tcase 0x5:\n\t\t\tcase 0xc:\n\t\t\tcase 0xd:\n\t\t\t\treturn evaluate_load_store_multiple_thumb(opcode, address,\n\t\t\t\t\tinstruction);\n\t\t\tcase 0x6:\n\t\t\t\treturn evaluate_cps_thumb(opcode, address, instruction);\n\t\t\tcase 0xa:\n\t\t\t\tif ((opcode & 0x00c0) == 0x0080)\n\t\t\t\t\tbreak;\n\t\t\t\treturn evaluate_byterev_thumb(opcode, address, instruction);\n\t\t\tcase 0xe:\n\t\t\t\treturn evaluate_breakpoint_thumb(opcode, address, instruction);\n\t\t\tcase 0xf:\n\t\t\t\tif (opcode & 0x000f)\n\t\t\t\t\treturn evaluate_ifthen_thumb(opcode, address,\n\t\t\t\t\t\t\tinstruction);\n\t\t\t\telse\n\t\t\t\t\treturn evaluate_hint_thumb(opcode, address,\n\t\t\t\t\t\t\tinstruction);\n\t\t}\n\n\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%4.4x    \\tUNDEFINED INSTRUCTION\",\n\t\t\t\taddress, opcode);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Load/Store multiple */\n\tif ((opcode & 0xf000) == 0xc000)\n\t\treturn evaluate_load_store_multiple_thumb(opcode, address, instruction);\n\n\t/* Conditional branch + SWI */\n\tif ((opcode & 0xf000) == 0xd000)\n\t\treturn evaluate_cond_branch_thumb(opcode, address, instruction);\n\n\tif ((opcode & 0xe000) == 0xe000) {\n\t\t/* Undefined instructions */\n\t\tif ((opcode & 0xf801) == 0xe801) {\n\t\t\tinstruction->type = ARM_UNDEFINED_INSTRUCTION;\n\t\t\tsnprintf(instruction->text, 128,\n\t\t\t\t\t\"0x%8.8\" PRIx32 \"  0x%8.8x\\t\"\n\t\t\t\t\t\"UNDEFINED INSTRUCTION\",\n\t\t\t\t\taddress, opcode);\n\t\t\treturn ERROR_OK;\n\t\t} else\t/* Branch to offset */\n\t\t\treturn evaluate_b_bl_blx_thumb(opcode, address, instruction);\n\t}\n\n\tLOG_ERROR(\"Thumb: should never reach this point (opcode=%04x)\", opcode);\n\treturn -1;\n}\n\nint arm_access_size(struct arm_instruction *instruction)\n{\n\tif ((instruction->type == ARM_LDRB)\n\t    || (instruction->type == ARM_LDRBT)\n\t    || (instruction->type == ARM_LDRSB)\n\t    || (instruction->type == ARM_STRB)\n\t    || (instruction->type == ARM_STRBT))\n\t\treturn 1;\n\telse if ((instruction->type == ARM_LDRH)\n\t\t || (instruction->type == ARM_LDRSH)\n\t\t || (instruction->type == ARM_STRH))\n\t\treturn 2;\n\telse if ((instruction->type == ARM_LDR)\n\t\t || (instruction->type == ARM_LDRT)\n\t\t || (instruction->type == ARM_STR)\n\t\t || (instruction->type == ARM_STRT))\n\t\treturn 4;\n\telse if ((instruction->type == ARM_LDRD)\n\t\t || (instruction->type == ARM_STRD))\n\t\treturn 8;\n\telse {\n\t\tLOG_ERROR(\"BUG: instruction type %i isn't a load/store instruction\",\n\t\t\t\tinstruction->type);\n\t\treturn 0;\n\t}\n}\n\n#if HAVE_CAPSTONE\nstatic void print_opcode(struct command_invocation *cmd, const cs_insn *insn)\n{\n\tuint32_t opcode = 0;\n\n\tmemcpy(&opcode, insn->bytes, insn->size);\n\n\tif (insn->size == 4) {\n\t\tuint16_t opcode_high = opcode >> 16;\n\t\topcode = opcode & 0xffff;\n\n\t\tcommand_print(cmd, \"0x%08\" PRIx64\"  %04x %04x\\t%s%s%s\",\n\t\t\tinsn->address, opcode, opcode_high, insn->mnemonic,\n\t\t\tinsn->op_str[0] ? \"\\t\" : \"\", insn->op_str);\n\t} else {\n\t\tcommand_print(cmd, \"0x%08\" PRIx64\"  %04x\\t%s%s%s\",\n\t\t\tinsn->address, opcode, insn->mnemonic,\n\t\t\tinsn->op_str[0] ? \"\\t\" : \"\", insn->op_str);\n\t}\n}\n\nint arm_disassemble(struct command_invocation *cmd, struct target *target,\n\t\ttarget_addr_t address, size_t count, bool thumb_mode)\n{\n\tcsh handle;\n\tint ret;\n\tcs_insn *insn;\n\tcs_mode mode;\n\n\tif (!cs_support(CS_ARCH_ARM)) {\n\t\tLOG_ERROR(\"ARM architecture not supported by capstone\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmode = CS_MODE_LITTLE_ENDIAN;\n\n\tif (thumb_mode)\n\t\tmode |= CS_MODE_THUMB;\n\n\tret = cs_open(CS_ARCH_ARM, mode, &handle);\n\n\tif (ret != CS_ERR_OK) {\n\t\tLOG_ERROR(\"cs_open() failed: %s\", cs_strerror(ret));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tret = cs_option(handle, CS_OPT_SKIPDATA, CS_OPT_ON);\n\n\tif (ret != CS_ERR_OK) {\n\t\tLOG_ERROR(\"cs_option() failed: %s\", cs_strerror(ret));\n\t\tcs_close(&handle);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tinsn = cs_malloc(handle);\n\n\tif (!insn) {\n\t\tLOG_ERROR(\"cs_malloc() failed\\n\");\n\t\tcs_close(&handle);\n\t\treturn ERROR_FAIL;\n\t}\n\n\twhile (count > 0) {\n\t    uint8_t buffer[4];\n\n\t\tret = target_read_buffer(target, address, sizeof(buffer), buffer);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tcs_free(insn, 1);\n\t\t\tcs_close(&handle);\n\t\t\treturn ret;\n\t\t}\n\n\t\tsize_t size = sizeof(buffer);\n\t\tconst uint8_t *tmp = buffer;\n\n\t\tret = cs_disasm_iter(handle, &tmp, &size, &address, insn);\n\n\t\tif (!ret) {\n\t\t\tLOG_ERROR(\"cs_disasm_iter() failed: %s\",\n\t\t\t\tcs_strerror(cs_errno(handle)));\n\t\t\tcs_free(insn, 1);\n\t\t\tcs_close(&handle);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tprint_opcode(cmd, insn);\n\t\tcount--;\n\t}\n\n\tcs_free(insn, 1);\n\tcs_close(&handle);\n\n\treturn ERROR_OK;\n}\n#endif /* HAVE_CAPSTONE */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_disassembler.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_DISASSEMBLER_H\n#define OPENOCD_TARGET_ARM_DISASSEMBLER_H\n\nenum arm_instruction_type {\n\tARM_UNKNOWN_INSTRUCTION,\n\n\t/* Branch instructions */\n\tARM_B,\n\tARM_BL,\n\tARM_BX,\n\tARM_BLX,\n\n\t/* Data processing instructions */\n\tARM_AND,\n\tARM_EOR,\n\tARM_SUB,\n\tARM_RSB,\n\tARM_ADD,\n\tARM_ADC,\n\tARM_SBC,\n\tARM_RSC,\n\tARM_TST,\n\tARM_TEQ,\n\tARM_CMP,\n\tARM_CMN,\n\tARM_ORR,\n\tARM_MOV,\n\tARM_BIC,\n\tARM_MVN,\n\n\t/* Load/store instructions */\n\tARM_LDR,\n\tARM_LDRB,\n\tARM_LDRT,\n\tARM_LDRBT,\n\n\tARM_LDRH,\n\tARM_LDRSB,\n\tARM_LDRSH,\n\n\tARM_LDM,\n\n\tARM_STR,\n\tARM_STRB,\n\tARM_STRT,\n\tARM_STRBT,\n\n\tARM_STRH,\n\n\tARM_STM,\n\n\t/* Status register access instructions */\n\tARM_MRS,\n\tARM_MSR,\n\n\t/* Multiply instructions */\n\tARM_MUL,\n\tARM_MLA,\n\tARM_SMULL,\n\tARM_SMLAL,\n\tARM_UMULL,\n\tARM_UMLAL,\n\n\t/* Miscellaneous instructions */\n\tARM_CLZ,\n\n\t/* Exception return instructions */\n\tARM_ERET,\n\n\t/* Exception generating instructions */\n\tARM_BKPT,\n\tARM_SWI,\n\tARM_HVC,\n\tARM_SMC,\n\n\t/* Coprocessor instructions */\n\tARM_CDP,\n\tARM_LDC,\n\tARM_STC,\n\tARM_MCR,\n\tARM_MRC,\n\n\t/* Semaphore instructions */\n\tARM_SWP,\n\tARM_SWPB,\n\n\t/* Enhanced DSP extensions */\n\tARM_MCRR,\n\tARM_MRRC,\n\tARM_PLD,\n\tARM_DSB,\n\tARM_ISB,\n\tARM_QADD,\n\tARM_QDADD,\n\tARM_QSUB,\n\tARM_QDSUB,\n\tARM_SMLAXY,\n\tARM_SMLALXY,\n\tARM_SMLAWY,\n\tARM_SMULXY,\n\tARM_SMULWY,\n\tARM_LDRD,\n\tARM_STRD,\n\n\tARM_UNDEFINED_INSTRUCTION = 0xffffffff,\n};\n\nstruct arm_b_bl_bx_blx_instr {\n\tint reg_operand;\n\tuint32_t target_address;\n};\n\nunion arm_shifter_operand {\n\tstruct {\n\t\tuint32_t immediate;\n\t} immediate;\n\tstruct {\n\t\tuint8_t rm;\n\t\tuint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */\n\t\tuint8_t shift_imm;\n\t} immediate_shift;\n\tstruct {\n\t\tuint8_t rm;\n\t\tuint8_t shift;\n\t\tuint8_t rs;\n\t} register_shift;\n};\n\nstruct arm_data_proc_instr {\n\tint variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */\n\tuint8_t s;\n\tuint8_t rn;\n\tuint8_t rd;\n\tunion arm_shifter_operand shifter_operand;\n};\n\nstruct arm_load_store_instr {\n\tuint8_t rd;\n\tuint8_t rn;\n\tuint8_t u;\n\tint index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */\n\tint offset_mode; /* 0: immediate, 1: (scaled) register */\n\tunion {\n\t\tuint32_t offset;\n\t\tstruct {\n\t\t\tuint8_t rm;\n\t\t\tuint8_t shift; /* 0: LSL, 1: LSR, 2: ASR, 3: ROR, 4: RRX */\n\t\t\tuint8_t shift_imm;\n\t\t} reg;\n\t} offset;\n};\n\nstruct arm_load_store_multiple_instr {\n\tuint8_t rn;\n\tuint32_t register_list;\n\tuint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */\n\tuint8_t s;\n\tuint8_t w;\n};\n\nstruct arm_instruction {\n\tenum arm_instruction_type type;\n\tchar text[128];\n\tuint32_t opcode;\n\n\t/* return value ... Thumb-2 sizes vary */\n\tunsigned instruction_size;\n\n\tunion {\n\t\tstruct arm_b_bl_bx_blx_instr b_bl_bx_blx;\n\t\tstruct arm_data_proc_instr data_proc;\n\t\tstruct arm_load_store_instr load_store;\n\t\tstruct arm_load_store_multiple_instr load_store_multiple;\n\t} info;\n\n};\n\nint arm_evaluate_opcode(uint32_t opcode, uint32_t address,\n\t\tstruct arm_instruction *instruction);\nint thumb_evaluate_opcode(uint16_t opcode, uint32_t address,\n\t\tstruct arm_instruction *instruction);\nint arm_access_size(struct arm_instruction *instruction);\n#if HAVE_CAPSTONE\nint arm_disassemble(struct command_invocation *cmd, struct target *target,\n\t\ttarget_addr_t address, size_t count, bool thumb_mode);\n#endif\n\n#define COND(opcode) (arm_condition_strings[(opcode & 0xf0000000) >> 28])\n\n#endif /* OPENOCD_TARGET_ARM_DISASSEMBLER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_dpm.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2009 by David Brownell\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"arm_dpm.h\"\n#include \"armv8_dpm.h\"\n#include <jtag/jtag.h>\n#include \"register.h\"\n#include \"breakpoints.h\"\n#include \"target_type.h\"\n#include \"arm_opcodes.h\"\n\n\n/**\n * @file\n * Implements various ARM DPM operations using architectural debug registers.\n * These routines layer over core-specific communication methods to cope with\n * implementation differences between cores like ARM1136 and Cortex-A8.\n *\n * The \"Debug Programmers' Model\" (DPM) for ARMv6 and ARMv7 is defined by\n * Part C (Debug Architecture) of the ARM Architecture Reference Manual,\n * ARMv7-A and ARMv7-R edition (ARM DDI 0406B).  In OpenOCD, DPM operations\n * are abstracted through internal programming interfaces to share code and\n * to minimize needless differences in debug behavior between cores.\n */\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Coprocessor support\n */\n\n/* Read coprocessor */\nstatic int dpm_mrc(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,\n\tuint32_t *value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"MRC p%d, %d, r0, c%d, c%d, %d\", cpnum,\n\t\t(int) op1, (int) crn,\n\t\t(int) crm, (int) op2);\n\n\t/* read coprocessor register into R0; return via DCC */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int dpm_mcr(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,\n\tuint32_t value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"MCR p%d, %d, r0, c%d, c%d, %d\", cpnum,\n\t\t(int) op1, (int) crn,\n\t\t(int) crm, (int) op2);\n\n\t/* read DCC into r0; then write coprocessor register from R0 */\n\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Register access utilities\n */\n\n/* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.\n * Routines *must* restore the original mode before returning!!\n */\nint arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)\n{\n\tint retval;\n\tuint32_t cpsr;\n\n\t/* restore previous mode */\n\tif (mode == ARM_MODE_ANY)\n\t\tcpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);\n\n\t/* else force to the specified mode */\n\telse\n\t\tcpsr = mode;\n\n\tretval = dpm->instr_write_data_r0(dpm, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dpm->instr_cpsr_sync)\n\t\tretval = dpm->instr_cpsr_sync(dpm);\n\n\treturn retval;\n}\n\n/* Read 64bit VFP registers */\nstatic int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tint retval = ERROR_FAIL;\n\tuint32_t value_r0, value_r1;\n\n\tswitch (regnum) {\n\t\tcase ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:\n\t\t\t/* move from double word register to r0:r1: \"vmov r0, r1, vm\"\n\t\t\t * then read r0 via dcc\n\t\t\t */\n\t\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_VMOV(1, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4),\n\t\t\t\t((regnum - ARM_VFP_V3_D0) & 0xf)), &value_r0);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\t/* read r1 via dcc */\n\t\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, 1, 0, 5, 0),\n\t\t\t\t&value_r1);\n\t\t\tbreak;\n\t\tdefault:\n\n\t\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\tbuf_set_u32(r->value, 0, 32, value_r0);\n\t\tbuf_set_u32(r->value + 4, 0, 32, value_r1);\n\t\tr->valid = true;\n\t\tr->dirty = false;\n\t\tLOG_DEBUG(\"READ: %s, %8.8x, %8.8x\", r->name,\n\t\t\t\t(unsigned) value_r0, (unsigned) value_r1);\n\t}\n\n\treturn retval;\n}\n\n/* just read the register -- rely on the core mode being right */\nint arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tuint32_t value;\n\tint retval;\n\n\tswitch (regnum) {\n\t\tcase 0 ... 14:\n\t\t\t/* return via DCC:  \"MCR p14, 0, Rnum, c0, c5, 0\" */\n\t\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, regnum, 0, 5, 0),\n\t\t\t\t&value);\n\t\t\tbreak;\n\t\tcase 15:/* PC\n\t\t\t * \"MOV r0, pc\"; then return via DCC */\n\t\t\tretval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value);\n\n\t\t\t/* NOTE: this seems like a slightly awkward place to update\n\t\t\t * this value ... but if the PC gets written (the only way\n\t\t\t * to change what we compute), the arch spec says subsequent\n\t\t\t * reads return values which are \"unpredictable\".  So this\n\t\t\t * is always right except in those broken-by-intent cases.\n\t\t\t */\n\t\t\tswitch (dpm->arm->core_state) {\n\t\t\t\tcase ARM_STATE_ARM:\n\t\t\t\t\tvalue -= 8;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ARM_STATE_THUMB:\n\t\t\t\tcase ARM_STATE_THUMB_EE:\n\t\t\t\t\tvalue -= 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase ARM_STATE_JAZELLE:\n\t\t\t\t\t/* core-specific ... ? */\n\t\t\t\t\tLOG_WARNING(\"Jazelle PC adjustment unknown\");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_WARNING(\"unknown core state\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:\n\t\t\treturn dpm_read_reg_u64(dpm, r, regnum);\n\t\tcase ARM_VFP_V3_FPSCR:\n\t\t\t/* \"VMRS r0, FPSCR\"; then return via DCC */\n\t\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_VMRS(0), &value);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* 16: \"MRS r0, CPSR\"; then return via DCC\n\t\t\t * 17: \"MRS r0, SPSR\"; then return via DCC\n\t\t\t */\n\t\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_MRS(0, regnum & 1),\n\t\t\t\t&value);\n\t\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\tbuf_set_u32(r->value, 0, 32, value);\n\t\tr->valid = true;\n\t\tr->dirty = false;\n\t\tLOG_DEBUG(\"READ: %s, %8.8x\", r->name, (unsigned) value);\n\t}\n\n\treturn retval;\n}\n\n/* Write 64bit VFP registers */\nstatic int dpm_write_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tint retval = ERROR_FAIL;\n\tuint32_t value_r0 = buf_get_u32(r->value, 0, 32);\n\tuint32_t value_r1 = buf_get_u32(r->value + 4, 0, 32);\n\n\tswitch (regnum) {\n\t\tcase ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:\n\t\t\t/* write value_r1 to r1 via dcc */\n\t\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 1, 0, 5, 0),\n\t\t\t\tvalue_r1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tbreak;\n\n\t\t\t/* write value_r0 to r0 via dcc then,\n\t\t\t * move to double word register from r0:r1: \"vmov vm, r0, r1\"\n\t\t\t */\n\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_VMOV(0, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4),\n\t\t\t\t((regnum - ARM_VFP_V3_D0) & 0xf)), value_r0);\n\t\t\tbreak;\n\t\tdefault:\n\n\t\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\tr->dirty = false;\n\t\tLOG_DEBUG(\"WRITE: %s, %8.8x, %8.8x\", r->name,\n\t\t\t\t(unsigned) value_r0, (unsigned) value_r1);\n\t}\n\n\treturn retval;\n}\n\n/* just write the register -- rely on the core mode being right */\nstatic int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tint retval;\n\tuint32_t value = buf_get_u32(r->value, 0, 32);\n\n\tswitch (regnum) {\n\t\tcase 0 ... 14:\n\t\t\t/* load register from DCC:  \"MRC p14, 0, Rnum, c0, c5, 0\" */\n\t\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, regnum, 0, 5, 0),\n\t\t\t\tvalue);\n\t\t\tbreak;\n\t\tcase 15:/* PC\n\t\t\t * read r0 from DCC; then \"MOV pc, r0\" */\n\t\t\tretval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value);\n\t\t\tbreak;\n\t\tcase ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:\n\t\t\treturn dpm_write_reg_u64(dpm, r, regnum);\n\t\tcase ARM_VFP_V3_FPSCR:\n\t\t\t/* move to r0 from DCC, then \"VMSR FPSCR, r0\" */\n\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_VMSR(0), value);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* 16: read r0 from DCC, then \"MSR r0, CPSR_cxsf\"\n\t\t\t * 17: read r0 from DCC, then \"MSR r0, SPSR_cxsf\"\n\t\t\t */\n\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MSR_GP(0, 0xf, regnum & 1),\n\t\t\t\tvalue);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (regnum == 16 && dpm->instr_cpsr_sync)\n\t\t\t\tretval = dpm->instr_cpsr_sync(dpm);\n\n\t\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\tr->dirty = false;\n\t\tLOG_DEBUG(\"WRITE: %s, %8.8x\", r->name, (unsigned) value);\n\t}\n\n\treturn retval;\n}\n\n/**\n * Write to program counter and switch the core state (arm/thumb) according to\n * the address.\n */\nstatic int dpm_write_pc_core_state(struct arm_dpm *dpm, struct reg *r)\n{\n\tuint32_t value = buf_get_u32(r->value, 0, 32);\n\n\t/* read r0 from DCC; then \"BX r0\" */\n\treturn dpm->instr_write_data_r0(dpm, ARMV4_5_BX(0), value);\n}\n\n/**\n * Read basic registers of the current context:  R0 to R15, and CPSR;\n * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).\n * In normal operation this is called on entry to halting debug state,\n * possibly after some other operations supporting restore of debug state\n * or making sure the CPU is fully idle (drain write buffer, etc).\n */\nint arm_dpm_read_current_registers(struct arm_dpm *dpm)\n{\n\tstruct arm *arm = dpm->arm;\n\tuint32_t cpsr;\n\tint retval;\n\tstruct reg *r;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* read R0 and R1 first (it's used for scratch), then CPSR */\n\tfor (unsigned i = 0; i < 2; i++) {\n\t\tr = arm->core_cache->reg_list + i;\n\t\tif (!r->valid) {\n\t\t\tretval = arm_dpm_read_reg(dpm, r, i);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto fail;\n\t\t}\n\t\tr->dirty = true;\n\t}\n\n\tretval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRS(0, 0), &cpsr);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\n\t/* update core mode and state, plus shadow mapping for R8..R14 */\n\tarm_set_cpsr(arm, cpsr);\n\n\t/* REVISIT we can probably avoid reading R1..R14, saving time... */\n\tfor (unsigned i = 2; i < 16; i++) {\n\t\tr = arm_reg_current(arm, i);\n\t\tif (r->valid)\n\t\t\tcontinue;\n\n\t\tretval = arm_dpm_read_reg(dpm, r, i);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\t}\n\n\t/* NOTE: SPSR ignored (if it's even relevant). */\n\n\t/* REVISIT the debugger can trigger various exceptions.  See the\n\t * ARMv7A architecture spec, section C5.7, for more info about\n\t * what defenses are needed; v6 debug has the most issues.\n\t */\n\nfail:\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\n/* Avoid needless I/O ... leave breakpoints and watchpoints alone\n * unless they're removed, or need updating because of single-stepping\n * or running debugger code.\n */\nstatic int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,\n\tstruct dpm_bpwp *xp, bool *set_p)\n{\n\tint retval = ERROR_OK;\n\tbool disable;\n\n\tif (!set_p) {\n\t\tif (!xp->dirty)\n\t\t\tgoto done;\n\t\txp->dirty = false;\n\t\t/* removed or startup; we must disable it */\n\t\tdisable = true;\n\t} else if (bpwp) {\n\t\tif (!xp->dirty)\n\t\t\tgoto done;\n\t\t/* disabled, but we must set it */\n\t\txp->dirty = disable = false;\n\t\t*set_p = true;\n\t} else {\n\t\tif (!*set_p)\n\t\t\tgoto done;\n\t\t/* set, but we must temporarily disable it */\n\t\txp->dirty = disable = true;\n\t\t*set_p = false;\n\t}\n\n\tif (disable)\n\t\tretval = dpm->bpwp_disable(dpm, xp->number);\n\telse\n\t\tretval = dpm->bpwp_enable(dpm, xp->number,\n\t\t\t\txp->address, xp->control);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"%s: can't %s HW %spoint %d\",\n\t\t\tdisable ? \"disable\" : \"enable\",\n\t\t\ttarget_name(dpm->arm->target),\n\t\t\t(xp->number < 16) ? \"break\" : \"watch\",\n\t\t\txp->number & 0xf);\ndone:\n\treturn retval;\n}\n\nstatic int dpm_add_breakpoint(struct target *target, struct breakpoint *bp);\n\n/**\n * Writes all modified core registers for all processor modes.  In normal\n * operation this is called on exit from halting debug state.\n *\n * @param dpm: represents the processor\n * @param bpwp: true ensures breakpoints and watchpoints are set,\n *\tfalse ensures they are cleared\n */\nint arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)\n{\n\tstruct arm *arm = dpm->arm;\n\tstruct reg_cache *cache = arm->core_cache;\n\tint retval;\n\tbool did_write;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* If we're managing hardware breakpoints for this core, enable\n\t * or disable them as requested.\n\t *\n\t * REVISIT We don't yet manage them for ANY cores.  Eventually\n\t * we should be able to assume we handle them; but until then,\n\t * cope with the hand-crafted breakpoint code.\n\t */\n\tif (arm->target->type->add_breakpoint == dpm_add_breakpoint) {\n\t\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\t\tstruct dpm_bp *dbp = dpm->dbp + i;\n\t\t\tstruct breakpoint *bp = dbp->bp;\n\n\t\t\tretval = dpm_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,\n\t\t\t\t\tbp ? &bp->is_set : NULL);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t}\n\t}\n\n\t/* enable/disable watchpoints */\n\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\tstruct dpm_wp *dwp = dpm->dwp + i;\n\t\tstruct watchpoint *wp = dwp->wp;\n\n\t\tretval = dpm_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,\n\t\t\t\twp ? &wp->is_set : NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\n\t/* NOTE:  writes to breakpoint and watchpoint registers might\n\t * be queued, and need (efficient/batched) flushing later.\n\t */\n\n\t/* Scan the registers until we find one that's both dirty and\n\t * eligible for flushing.  Flush that and everything else that\n\t * shares the same core mode setting.  Typically this won't\n\t * actually find anything to do...\n\t */\n\tdo {\n\t\tenum arm_mode mode = ARM_MODE_ANY;\n\n\t\tdid_write = false;\n\n\t\t/* check everything except our scratch registers R0 and R1 */\n\t\tfor (unsigned i = 2; i < cache->num_regs; i++) {\n\t\t\tstruct arm_reg *r;\n\t\t\tunsigned regnum;\n\n\t\t\t/* also skip PC, CPSR, and non-dirty */\n\t\t\tif (i == 15)\n\t\t\t\tcontinue;\n\t\t\tif (arm->cpsr == cache->reg_list + i)\n\t\t\t\tcontinue;\n\t\t\tif (!cache->reg_list[i].exist || !cache->reg_list[i].dirty)\n\t\t\t\tcontinue;\n\n\t\t\tr = cache->reg_list[i].arch_info;\n\t\t\tregnum = r->num;\n\n\t\t\t/* may need to pick and set a mode */\n\t\t\tif (!did_write) {\n\t\t\t\tenum arm_mode tmode;\n\n\t\t\t\tdid_write = true;\n\t\t\t\tmode = tmode = r->mode;\n\n\t\t\t\t/* cope with special cases */\n\t\t\t\tswitch (regnum) {\n\t\t\t\tcase 8 ... 12:\n\t\t\t\t\t/* r8..r12 \"anything but FIQ\" case;\n\t\t\t\t\t * we \"know\" core mode is accurate\n\t\t\t\t\t * since we haven't changed it yet\n\t\t\t\t\t */\n\t\t\t\t\tif (arm->core_mode == ARM_MODE_FIQ\n\t\t\t\t\t    && ARM_MODE_ANY\n\t\t\t\t\t    != mode)\n\t\t\t\t\t\ttmode = ARM_MODE_USR;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 16:\n\t\t\t\t\t/* SPSR */\n\t\t\t\t\tregnum++;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* REVISIT error checks */\n\t\t\t\tif (tmode != ARM_MODE_ANY) {\n\t\t\t\t\tretval = arm_dpm_modeswitch(dpm, tmode);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\tgoto done;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (r->mode != mode)\n\t\t\t\tcontinue;\n\n\t\t\tretval = dpm_write_reg(dpm,\n\t\t\t\t\t       &cache->reg_list[i],\n\t\t\t\t\t       regnum);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t}\n\n\t} while (did_write);\n\n\t/* Restore original CPSR ... assuming either that we changed it,\n\t * or it's dirty.  Must write PC to ensure the return address is\n\t * defined, and must not write it before CPSR.\n\t */\n\tretval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\tarm->cpsr->dirty = false;\n\n\t/* restore the PC, make sure to also switch the core state\n\t * to whatever it was set to with \"arm core_state\" command.\n\t * target code will have set PC to an appropriate resume address.\n\t */\n\tretval = dpm_write_pc_core_state(dpm, arm->pc);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\t/* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction\n\t * executed in debug state doesn't appear to set the PC,\n\t * explicitly set it with a \"MOV pc, r0\". This doesn't influence\n\t * CPSR on Cortex-A9 so it should be OK. Maybe due to different\n\t * debug version?\n\t */\n\tretval = dpm_write_reg(dpm, arm->pc, 15);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\tarm->pc->dirty = false;\n\n\t/* flush R0 and R1 (our scratch registers) */\n\tfor (unsigned i = 0; i < 2; i++) {\n\t\tretval = dpm_write_reg(dpm, &cache->reg_list[i], i);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tcache->reg_list[i].dirty = false;\n\t}\n\n\t/* (void) */ dpm->finish(dpm);\ndone:\n\treturn retval;\n}\n\n/* Returns ARM_MODE_ANY or temporary mode to use while reading the\n * specified register ... works around flakiness from ARM core calls.\n * Caller already filtered out SPSR access; mode is never MODE_SYS\n * or MODE_ANY.\n */\nstatic enum arm_mode dpm_mapmode(struct arm *arm,\n\tunsigned num, enum arm_mode mode)\n{\n\tenum arm_mode amode = arm->core_mode;\n\n\t/* don't switch if the mode is already correct */\n\tif (amode == ARM_MODE_SYS)\n\t\tamode = ARM_MODE_USR;\n\tif (mode == amode)\n\t\treturn ARM_MODE_ANY;\n\n\tswitch (num) {\n\t\t/* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */\n\t\tcase 0 ... 7:\n\t\tcase 15:\n\t\tcase 16:\n\t\t\tbreak;\n\t\t/* r8..r12 aren't shadowed for anything except FIQ */\n\t\tcase 8 ... 12:\n\t\t\tif (mode == ARM_MODE_FIQ)\n\t\t\t\treturn mode;\n\t\t\tbreak;\n\t\t/* r13/sp, and r14/lr are always shadowed */\n\t\tcase 13:\n\t\tcase 14:\n\t\tcase ARM_VFP_V3_D0 ... ARM_VFP_V3_FPSCR:\n\t\t\treturn mode;\n\t\tdefault:\n\t\t\tLOG_WARNING(\"invalid register #%u\", num);\n\t\t\tbreak;\n\t}\n\treturn ARM_MODE_ANY;\n}\n\n\n/*\n * Standard ARM register accessors ... there are three methods\n * in \"struct arm\", to support individual read/write and bulk read\n * of registers.\n */\n\nstatic int arm_dpm_read_core_reg(struct target *target, struct reg *r,\n\tint regnum, enum arm_mode mode)\n{\n\tstruct arm_dpm *dpm = target_to_arm(target)->dpm;\n\tint retval;\n\n\tif (regnum < 0 || (regnum > 16 && regnum < ARM_VFP_V3_D0) ||\n\t\t(regnum > ARM_VFP_V3_FPSCR))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (regnum == 16) {\n\t\tif (mode != ARM_MODE_ANY)\n\t\t\tregnum = 17;\n\t} else\n\t\tmode = dpm_mapmode(dpm->arm, regnum, mode);\n\n\t/* REVISIT what happens if we try to read SPSR in a core mode\n\t * which has no such register?\n\t */\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mode != ARM_MODE_ANY) {\n\t\tretval = arm_dpm_modeswitch(dpm, mode);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\t}\n\n\tretval = arm_dpm_read_reg(dpm, r, regnum);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\t/* always clean up, regardless of error */\n\n\tif (mode != ARM_MODE_ANY)\n\t\t/* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\nfail:\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int arm_dpm_write_core_reg(struct target *target, struct reg *r,\n\tint regnum, enum arm_mode mode, uint8_t *value)\n{\n\tstruct arm_dpm *dpm = target_to_arm(target)->dpm;\n\tint retval;\n\n\n\tif (regnum < 0 || (regnum > 16 && regnum < ARM_VFP_V3_D0) ||\n\t\t\t(regnum > ARM_VFP_V3_FPSCR))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (regnum == 16) {\n\t\tif (mode != ARM_MODE_ANY)\n\t\t\tregnum = 17;\n\t} else\n\t\tmode = dpm_mapmode(dpm->arm, regnum, mode);\n\n\t/* REVISIT what happens if we try to write SPSR in a core mode\n\t * which has no such register?\n\t */\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (mode != ARM_MODE_ANY) {\n\t\tretval = arm_dpm_modeswitch(dpm, mode);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\t}\n\n\tretval = dpm_write_reg(dpm, r, regnum);\n\t/* always clean up, regardless of error */\n\n\tif (mode != ARM_MODE_ANY)\n\t\t/* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\nfail:\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int arm_dpm_full_context(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tstruct reg_cache *cache = arm->core_cache;\n\tint retval;\n\tbool did_read;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tdo {\n\t\tenum arm_mode mode = ARM_MODE_ANY;\n\n\t\tdid_read = false;\n\n\t\t/* We \"know\" arm_dpm_read_current_registers() was called so\n\t\t * the unmapped registers (R0..R7, PC, AND CPSR) and some\n\t\t * view of R8..R14 are current.  We also \"know\" oddities of\n\t\t * register mapping: special cases for R8..R12 and SPSR.\n\t\t *\n\t\t * Pick some mode with unread registers and read them all.\n\t\t * Repeat until done.\n\t\t */\n\t\tfor (unsigned i = 0; i < cache->num_regs; i++) {\n\t\t\tstruct arm_reg *r;\n\n\t\t\tif (!cache->reg_list[i].exist || cache->reg_list[i].valid)\n\t\t\t\tcontinue;\n\t\t\tr = cache->reg_list[i].arch_info;\n\n\t\t\t/* may need to pick a mode and set CPSR */\n\t\t\tif (!did_read) {\n\t\t\t\tdid_read = true;\n\t\t\t\tmode = r->mode;\n\n\t\t\t\t/* For regular (ARM_MODE_ANY) R8..R12\n\t\t\t\t * in case we've entered debug state\n\t\t\t\t * in FIQ mode we need to patch mode.\n\t\t\t\t */\n\t\t\t\tif (mode != ARM_MODE_ANY)\n\t\t\t\t\tretval = arm_dpm_modeswitch(dpm, mode);\n\t\t\t\telse\n\t\t\t\t\tretval = arm_dpm_modeswitch(dpm, ARM_MODE_USR);\n\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tif (r->mode != mode)\n\t\t\t\tcontinue;\n\n\t\t\t/* CPSR was read, so \"R16\" must mean SPSR */\n\t\t\tretval = arm_dpm_read_reg(dpm,\n\t\t\t\t\t&cache->reg_list[i],\n\t\t\t\t\t(r->num == 16) ? 17 : r->num);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t}\n\n\t} while (did_read);\n\n\tretval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\t/* (void) */ dpm->finish(dpm);\ndone:\n\treturn retval;\n}\n\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Breakpoint and Watchpoint support.\n *\n * Hardware {break,watch}points are usually left active, to minimize\n * debug entry/exit costs.  When they are set or cleared, it's done in\n * batches.  Also, DPM-conformant hardware can update debug registers\n * regardless of whether the CPU is running or halted ... though that\n * fact isn't currently leveraged.\n */\n\nstatic int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,\n\tuint32_t addr, uint32_t length)\n{\n\tuint32_t control;\n\n\tcontrol = (1 << 0)\t/* enable */\n\t\t| (3 << 1);\t/* both user and privileged access */\n\n\t/* Match 1, 2, or all 4 byte addresses in this word.\n\t *\n\t * FIXME:  v7 hardware allows lengths up to 2 GB for BP and WP.\n\t * Support larger length, when addr is suitably aligned.  In\n\t * particular, allow watchpoints on 8 byte \"double\" values.\n\t *\n\t * REVISIT allow watchpoints on unaligned 2-bit values; and on\n\t * v7 hardware, unaligned 4-byte ones too.\n\t */\n\tswitch (length) {\n\t\tcase 1:\n\t\t\tcontrol |= (1 << (addr & 3)) << 5;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t/* require 2-byte alignment */\n\t\t\tif (!(addr & 1)) {\n\t\t\t\tcontrol |= (3 << (addr & 2)) << 5;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t/* FALL THROUGH */\n\t\tcase 4:\n\t\t\t/* require 4-byte alignment */\n\t\t\tif (!(addr & 3)) {\n\t\t\t\tcontrol |= 0xf << 5;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t/* FALL THROUGH */\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unsupported {break,watch}point length/alignment\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* other shared control bits:\n\t * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)\n\t * bit 20 == 0 ... not linked to a context ID\n\t * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)\n\t */\n\n\txp->address = addr & ~3;\n\txp->control = control;\n\txp->dirty = true;\n\n\tLOG_DEBUG(\"BPWP: addr %8.8\" PRIx32 \", control %\" PRIx32 \", number %d\",\n\t\txp->address, control, xp->number);\n\n\t/* hardware is updated in write_dirty_registers() */\n\treturn ERROR_OK;\n}\n\nstatic int dpm_add_breakpoint(struct target *target, struct breakpoint *bp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (bp->length < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (!dpm->bpwp_enable)\n\t\treturn retval;\n\n\t/* FIXME we need a generic solution for software breakpoints. */\n\tif (bp->type == BKPT_SOFT)\n\t\tLOG_DEBUG(\"using HW bkpt, not SW...\");\n\n\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\tif (!dpm->dbp[i].bp) {\n\t\t\tretval = dpm_bpwp_setup(dpm, &dpm->dbp[i].bpwp,\n\t\t\t\t\tbp->address, bp->length);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tdpm->dbp[i].bp = bp;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpm_remove_breakpoint(struct target *target, struct breakpoint *bp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\tif (dpm->dbp[i].bp == bp) {\n\t\t\tdpm->dbp[i].bp = NULL;\n\t\t\tdpm->dbp[i].bpwp.dirty = true;\n\n\t\t\t/* hardware is updated in write_dirty_registers() */\n\t\t\tretval = ERROR_OK;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,\n\tstruct watchpoint *wp)\n{\n\tint retval;\n\tstruct dpm_wp *dwp = dpm->dwp + index_t;\n\tuint32_t control;\n\n\t/* this hardware doesn't support data value matching or masking */\n\tif (wp->value || wp->mask != ~(uint32_t)0) {\n\t\tLOG_DEBUG(\"watchpoint values and masking not supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = dpm_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcontrol = dwp->bpwp.control;\n\tswitch (wp->rw) {\n\t\tcase WPT_READ:\n\t\t\tcontrol |= 1 << 3;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tcontrol |= 2 << 3;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tcontrol |= 3 << 3;\n\t\t\tbreak;\n\t}\n\tdwp->bpwp.control = control;\n\n\tdpm->dwp[index_t].wp = wp;\n\n\treturn retval;\n}\n\nstatic int dpm_add_watchpoint(struct target *target, struct watchpoint *wp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (dpm->bpwp_enable) {\n\t\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\t\tif (!dpm->dwp[i].wp) {\n\t\t\t\tretval = dpm_watchpoint_setup(dpm, i, wp);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\tif (dpm->dwp[i].wp == wp) {\n\t\t\tdpm->dwp[i].wp = NULL;\n\t\t\tdpm->dwp[i].bpwp.dirty = true;\n\n\t\t\t/* hardware is updated in write_dirty_registers() */\n\t\t\tretval = ERROR_OK;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nvoid arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)\n{\n\tswitch (dpm->arm->core_state) {\n\t\tcase ARM_STATE_ARM:\n\t\t\taddr -= 8;\n\t\t\tbreak;\n\t\tcase ARM_STATE_THUMB:\n\t\tcase ARM_STATE_THUMB_EE:\n\t\t\taddr -= 4;\n\t\t\tbreak;\n\t\tcase ARM_STATE_JAZELLE:\n\t\tcase ARM_STATE_AARCH64:\n\t\t\t/* ?? */\n\t\t\tbreak;\n\t}\n\tdpm->wp_addr = addr;\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Other debug and support utilities\n */\n\nvoid arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)\n{\n\tstruct target *target = dpm->arm->target;\n\n\tdpm->dscr = dscr;\n\n\t/* Examine debug reason */\n\tswitch (DSCR_ENTRY(dscr)) {\n\t\tcase DSCR_ENTRY_HALT_REQ:\t/* HALT request from debugger */\n\t\tcase DSCR_ENTRY_EXT_DBG_REQ:\t/* EDBGRQ */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase DSCR_ENTRY_BREAKPOINT:\t/* HW breakpoint */\n\t\tcase DSCR_ENTRY_BKPT_INSTR:\t/* vector catch */\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase DSCR_ENTRY_IMPRECISE_WATCHPT:\t/* asynch watchpoint */\n\t\tcase DSCR_ENTRY_PRECISE_WATCHPT:/* precise watchpoint */\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\t\t\tbreak;\n\t}\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Setup and management support.\n */\n\n/**\n * Hooks up this DPM to its associated target; call only once.\n * Initially this only covers the register cache.\n *\n * Oh, and watchpoints.  Yeah.\n */\nint arm_dpm_setup(struct arm_dpm *dpm)\n{\n\tstruct arm *arm = dpm->arm;\n\tstruct target *target = arm->target;\n\tstruct reg_cache *cache = NULL;\n\n\tarm->dpm = dpm;\n\n\t/* register access setup */\n\tarm->full_context = arm_dpm_full_context;\n\tarm->read_core_reg = arm_dpm_read_core_reg;\n\tarm->write_core_reg = arm_dpm_write_core_reg;\n\n\tif (!arm->core_cache) {\n\t\tcache = arm_build_reg_cache(target, arm);\n\t\tif (!cache)\n\t\t\treturn ERROR_FAIL;\n\n\t\t*register_get_last_cache_p(&target->reg_cache) = cache;\n\t}\n\n\t/* coprocessor access setup */\n\tarm->mrc = dpm_mrc;\n\tarm->mcr = dpm_mcr;\n\n\t/* breakpoint setup -- optional until it works everywhere */\n\tif (!target->type->add_breakpoint) {\n\t\ttarget->type->add_breakpoint = dpm_add_breakpoint;\n\t\ttarget->type->remove_breakpoint = dpm_remove_breakpoint;\n\t}\n\n\t/* watchpoint setup -- optional until it works everywhere */\n\tif (!target->type->add_watchpoint) {\n\t\ttarget->type->add_watchpoint = dpm_add_watchpoint;\n\t\ttarget->type->remove_watchpoint = dpm_remove_watchpoint;\n\t}\n\n\t/* FIXME add vector catch support */\n\n\tdpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);\n\tdpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);\n\tdpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));\n\tdpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));\n\n\tif (!dpm->dbp || !dpm->dwp) {\n\t\tarm_free_reg_cache(arm);\n\t\tfree(dpm->dbp);\n\t\tfree(dpm->dwp);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"%s: hardware has %d breakpoints, %d watchpoints\",\n\t\ttarget_name(target), dpm->nbp, dpm->nwp);\n\n\t/* REVISIT ... and some of those breakpoints could match\n\t * execution context IDs...\n\t */\n\n\treturn ERROR_OK;\n}\n\n/**\n * Reinitializes DPM state at the beginning of a new debug session\n * or after a reset which may have affected the debug module.\n */\nint arm_dpm_initialize(struct arm_dpm *dpm)\n{\n\t/* Disable all breakpoints and watchpoints at startup. */\n\tif (dpm->bpwp_disable) {\n\t\tunsigned i;\n\n\t\tfor (i = 0; i < dpm->nbp; i++) {\n\t\t\tdpm->dbp[i].bpwp.number = i;\n\t\t\t(void) dpm->bpwp_disable(dpm, i);\n\t\t}\n\t\tfor (i = 0; i < dpm->nwp; i++) {\n\t\t\tdpm->dwp[i].bpwp.number = 16 + i;\n\t\t\t(void) dpm->bpwp_disable(dpm, 16 + i);\n\t\t}\n\t} else\n\t\tLOG_WARNING(\"%s: can't disable breakpoints and watchpoints\",\n\t\t\ttarget_name(dpm->arm->target));\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_dpm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2009 by David Brownell\n */\n\n#ifndef OPENOCD_TARGET_ARM_DPM_H\n#define OPENOCD_TARGET_ARM_DPM_H\n\n/**\n * @file\n * This is the interface to the Debug Programmers Model for ARMv6 and\n * ARMv7 processors.  ARMv6 processors (such as ARM11xx implementations)\n * introduced a model which became part of the ARMv7-AR architecture\n * which is most familiar through the Cortex-A series parts.  While\n * specific details differ (like how to write the instruction register),\n * the high level models easily support shared code because those\n * registers are compatible.\n */\n\nstruct dpm_bpwp {\n\tunsigned number;\n\tuint32_t address;\n\tuint32_t control;\n\t/* true if hardware state needs flushing */\n\tbool dirty;\n};\n\nstruct dpm_bp {\n\tstruct breakpoint *bp;\n\tstruct dpm_bpwp bpwp;\n};\n\nstruct dpm_wp {\n\tstruct watchpoint *wp;\n\tstruct dpm_bpwp bpwp;\n};\n\n/**\n * This wraps an implementation of DPM primitives.  Each interface\n * provider supplies a structure like this, which is the glue between\n * upper level code and the lower level hardware access.\n *\n * It is a PRELIMINARY AND INCOMPLETE set of primitives, starting with\n * support for CPU register access.\n */\nstruct arm_dpm {\n\tstruct arm *arm;\n\n\t/** Cache of DIDR */\n\tuint64_t didr;\n\n\t/** Invoke before a series of instruction operations */\n\tint (*prepare)(struct arm_dpm *dpm);\n\n\t/** Invoke after a series of instruction operations */\n\tint (*finish)(struct arm_dpm *dpm);\n\n\t/** Runs one instruction. */\n\tint (*instr_execute)(struct arm_dpm *dpm, uint32_t opcode);\n\n\t/* WRITE TO CPU */\n\n\t/** Runs one instruction, writing data to DCC before execution. */\n\tint (*instr_write_data_dcc)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint32_t data);\n\n\tint (*instr_write_data_dcc_64)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint64_t data);\n\n\t/** Runs one instruction, writing data to R0 before execution. */\n\tint (*instr_write_data_r0)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint32_t data);\n\n\t/** Runs one instruction, writing data to R0 before execution. */\n\tint (*instr_write_data_r0_64)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint64_t data);\n\n\t/** Optional core-specific operation invoked after CPSR writes. */\n\tint (*instr_cpsr_sync)(struct arm_dpm *dpm);\n\n\t/* READ FROM CPU */\n\n\t/** Runs one instruction, reading data from dcc after execution. */\n\tint (*instr_read_data_dcc)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint32_t *data);\n\n\tint (*instr_read_data_dcc_64)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint64_t *data);\n\n\t/** Runs one instruction, reading data from r0 after execution. */\n\tint (*instr_read_data_r0)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint32_t *data);\n\n\tint (*instr_read_data_r0_64)(struct arm_dpm *dpm,\n\t\t\tuint32_t opcode, uint64_t *data);\n\n\tstruct reg *(*arm_reg_current)(struct arm *arm,\n\t\t\tunsigned regnum);\n\n\t/* BREAKPOINT/WATCHPOINT SUPPORT */\n\n\t/**\n\t * Enables one breakpoint or watchpoint by writing to the\n\t * hardware registers.  The specified breakpoint/watchpoint\n\t * must currently be disabled.  Indices 0..15 are used for\n\t * breakpoints; indices 16..31 are for watchpoints.\n\t */\n\tint (*bpwp_enable)(struct arm_dpm *dpm, unsigned index_value,\n\t\t\tuint32_t addr, uint32_t control);\n\n\t/**\n\t * Disables one breakpoint or watchpoint by clearing its\n\t * hardware control registers.  Indices are the same ones\n\t * accepted by bpwp_enable().\n\t */\n\tint (*bpwp_disable)(struct arm_dpm *dpm, unsigned index_value);\n\n\t/* The breakpoint and watchpoint arrays are private to the\n\t * DPM infrastructure.  There are nbp indices in the dbp\n\t * array.  There are nwp indices in the dwp array.\n\t */\n\n\tunsigned nbp;\n\tunsigned nwp;\n\tstruct dpm_bp *dbp;\n\tstruct dpm_wp *dwp;\n\n\t/**\n\t * Target dependent watchpoint address.\n\t * Either the address of the instruction which triggered a watchpoint\n\t * or the memory address whose access triggered a watchpoint.\n\t */\n\ttarget_addr_t wp_addr;\n\n\t/** Recent value of DSCR. */\n\tuint32_t dscr;\n\n\t/** Recent exception level on armv8 */\n\tunsigned int last_el;\n\n\t/* FIXME -- read/write DCSR methods and symbols */\n};\n\nint arm_dpm_setup(struct arm_dpm *dpm);\nint arm_dpm_initialize(struct arm_dpm *dpm);\n\nint arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum);\nint arm_dpm_read_current_registers(struct arm_dpm *dpm);\nint arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);\n\nint arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp);\n\nvoid arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t wfar);\n\n/* DSCR bits; see ARMv7a arch spec section C10.3.1.\n * Not all v7 bits are valid in v6.\n */\n#define DSCR_CORE_HALTED            (0x1 <<  0)\n#define DSCR_CORE_RESTARTED         (0x1 <<  1)\n#define DSCR_ENTRY_MASK             (0xF <<  2)\n#define DSCR_STICKY_ABORT_PRECISE   (0x1 <<  6)\n#define DSCR_STICKY_ABORT_IMPRECISE (0x1 <<  7)\n#define DSCR_STICKY_UNDEFINED       (0x1 <<  8)\n#define DSCR_DBG_NOPWRDWN           (0x1 <<  9) /* v6 only */\n#define DSCR_DBG_ACK                (0x1 << 10)\n#define DSCR_INT_DIS                (0x1 << 11)\n#define DSCR_CP14_USR_COMMS         (0x1 << 12)\n#define DSCR_ITR_EN                 (0x1 << 13)\n#define DSCR_HALT_DBG_MODE          (0x1 << 14)\n#define DSCR_MON_DBG_MODE           (0x1 << 15)\n#define DSCR_SEC_PRIV_INVASV_DIS    (0x1 << 16)\n#define DSCR_SEC_PRIV_NINVASV_DIS   (0x1 << 17)\n#define DSCR_NON_SECURE             (0x1 << 18)\n#define DSCR_DSCRD_IMPRECISE_ABORT  (0x1 << 19)\n#define DSCR_EXT_DCC_MASK           (0x3 << 20) /* DTR mode */  /* bits 22, 23 are reserved */\n#define DSCR_INSTR_COMP             (0x1 << 24)\n#define DSCR_PIPE_ADVANCE           (0x1 << 25)\n#define DSCR_DTRTX_FULL_LATCHED     (0x1 << 26)\n#define DSCR_DTRRX_FULL_LATCHED     (0x1 << 27) /* bit 28 is reserved */\n#define DSCR_DTR_TX_FULL            (0x1 << 29)\n#define DSCR_DTR_RX_FULL            (0x1 << 30) /* bit 31 is reserved */\n\n#define DSCR_ENTRY(dscr)            ((dscr) & 0x3f)\n#define DSCR_RUN_MODE(dscr)         ((dscr) & 0x03)\n\n\n/* Methods of entry into debug mode */\n#define DSCR_ENTRY_HALT_REQ           (0x03)\n#define DSCR_ENTRY_BREAKPOINT         (0x07)\n#define DSCR_ENTRY_IMPRECISE_WATCHPT  (0x0B)\n#define DSCR_ENTRY_BKPT_INSTR         (0x0F)\n#define DSCR_ENTRY_EXT_DBG_REQ        (0x13)\n#define DSCR_ENTRY_VECT_CATCH         (0x17)\n#define DSCR_ENTRY_D_SIDE_ABORT       (0x1B)  /* v6 only */\n#define DSCR_ENTRY_I_SIDE_ABORT       (0x1F)  /* v6 only */\n#define DSCR_ENTRY_OS_UNLOCK          (0x23)\n#define DSCR_ENTRY_PRECISE_WATCHPT    (0x2B)\n\n/* DTR modes */\n#define DSCR_EXT_DCC_NON_BLOCKING     (0x0 << 20)\n#define DSCR_EXT_DCC_STALL_MODE       (0x1 << 20)\n#define DSCR_EXT_DCC_FAST_MODE        (0x2 << 20)  /* bits 22, 23 are reserved */\n\n\n\n\n\n/* DRCR (debug run control register) bits */\n#define DRCR_HALT\t\t\t\t(1 << 0)\n#define DRCR_RESTART\t\t\t(1 << 1)\n#define DRCR_CLEAR_EXCEPTIONS\t(1 << 2)\n\nvoid arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr);\n\n/* PRCR (Device Power-down and Reset Control Register) bits */\n#define PRCR_DEBUG_NO_POWER_DOWN         (1 << 0)\n#define PRCR_WARM_RESET                  (1 << 1)\n#define PRCR_HOLD_NON_DEBUG_RESET        (1 << 2)\n\n/* PRSR (Device Power-down and Reset Status Register) bits */\n#define PRSR_POWERUP_STATUS              (1 << 0)\n#define PRSR_STICKY_POWERDOWN_STATUS     (1 << 1)\n#define PRSR_RESET_STATUS                (1 << 2)\n#define PRSR_STICKY_RESET_STATUS         (1 << 3)\n#define PRSR_HALTED                      (1 << 4)  /* v7.1 Debug only */\n#define PRSR_OSLK                        (1 << 5)  /* v7.1 Debug only */\n#define PRSR_DLK                         (1 << 6)  /* v7.1 Debug only */\n\n/* OSLSR (OS Lock Status Register) bits */\n#define OSLSR_OSLM0                      (1 << 0)\n#define OSLSR_OSLK                       (1 << 1)\n#define OSLSR_NTT                        (1 << 2)\n#define OSLSR_OSLM1                      (1 << 3)\n#define OSLSR_OSLM                       (OSLSR_OSLM0|OSLSR_OSLM1)\n\n#endif /* OPENOCD_TARGET_ARM_DPM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm_jtag.h\"\n\n#if 0\n#define _ARM_JTAG_SCAN_N_CHECK_\n#endif\n\nint arm_jtag_set_instr_inner(struct jtag_tap *tap,\n\t\tuint32_t new_instr, void *no_verify_capture, tap_state_t end_state)\n{\n\tstruct scan_field field;\n\tuint8_t t[4] = { 0 };\n\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\n\tif (!no_verify_capture)\n\t\tjtag_add_ir_scan(tap, &field, end_state);\n\telse {\n\t\t/* FIX!!!! this is a kludge!!! arm926ejs.c should reimplement this arm_jtag_set_instr to\n\t\t * have special verification code.\n\t\t */\n\t\tjtag_add_ir_scan_noverify(tap, &field, end_state);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)\n{\n\tint retval = ERROR_OK;\n\n\tuint8_t out_value[4] = { 0 };\n\tbuf_set_u32(out_value, 0, jtag_info->scann_size, new_scan_chain);\n\tstruct scan_field field = { .num_bits = jtag_info->scann_size, .out_value = out_value, };\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->scann_instr, NULL, end_state);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tjtag_add_dr_scan(jtag_info->tap,\n\t\t\t1,\n\t\t\t&field,\n\t\t\tend_state);\n\n\tjtag_info->cur_scan_chain = new_scan_chain;\n\n\treturn retval;\n}\n\nstatic int arm_jtag_reset_callback(enum jtag_event event, void *priv)\n{\n\tstruct arm_jtag *jtag_info = priv;\n\n\tif (event == JTAG_TRST_ASSERTED)\n\t\tjtag_info->cur_scan_chain = 0;\n\n\treturn ERROR_OK;\n}\n\nint arm_jtag_setup_connection(struct arm_jtag *jtag_info)\n{\n\tjtag_info->scann_instr = 0x2;\n\tjtag_info->cur_scan_chain = 0;\n\tjtag_info->intest_instr = 0xc;\n\n\treturn jtag_register_event_callback(arm_jtag_reset_callback, jtag_info);\n}\n\nint arm_jtag_close_connection(struct arm_jtag *jtag_info)\n{\n\treturn jtag_unregister_event_callback(arm_jtag_reset_callback, jtag_info);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_JTAG_H\n#define OPENOCD_TARGET_ARM_JTAG_H\n\n#include <jtag/jtag.h>\n#include <helper/bits.h>\n\nstruct arm_jtag {\n\tstruct jtag_tap *tap;\n\n\tuint32_t scann_size;\n\tuint32_t scann_instr;\n\tuint32_t cur_scan_chain;\n\n\tuint32_t intest_instr;\n};\n\nint arm_jtag_set_instr_inner(struct jtag_tap *tap, uint32_t new_instr,\n\t\tvoid *no_verify_capture,\n\t\ttap_state_t end_state);\n\nstatic inline int arm_jtag_set_instr(struct jtag_tap *tap,\n\t\tuint32_t new_instr, void *no_verify_capture, tap_state_t end_state)\n{\n\t/* inline most common code path */\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (new_instr & (BIT(tap->ir_length) - 1)))\n\t\treturn arm_jtag_set_instr_inner(tap, new_instr, no_verify_capture, end_state);\n\n\treturn ERROR_OK;\n\n}\n\nint arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state);\nstatic inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)\n{\n\t/* inline most common code path */\n\tint retval = ERROR_OK;\n\tif (jtag_info->cur_scan_chain != new_scan_chain)\n\t\treturn arm_jtag_scann_inner(jtag_info, new_scan_chain, end_state);\n\n\treturn retval;\n}\n\nint arm_jtag_setup_connection(struct arm_jtag *jtag_info);\nint arm_jtag_close_connection(struct arm_jtag *jtag_info);\n\n/* use this as a static so we can inline it in -O3 and refer to it via a pointer  */\nstatic inline void arm7flip32(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32);\n}\n\nstatic inline void arm_le_to_h_u32(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint32_t *)arg) = le_to_h_u32(in);\n}\n\n#endif /* OPENOCD_TARGET_ARM_JTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_opcodes.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2005 by Dominic Rath\n * Dominic.Rath@gmx.de\n *\n * Copyright (C) 2006 by Magnus Lundin\n * lundin@mlu.mine.nu\n *\n * Copyright (C) 2008 by Spencer Oliver\n * spen@spen-soft.co.uk\n *\n * Copyright (C) 2009 by Øyvind Harboe\n * oyvind.harboe@zylin.com\n */\n\n#ifndef OPENOCD_TARGET_ARM_OPCODES_H\n#define OPENOCD_TARGET_ARM_OPCODES_H\n\n/**\n * @file\n * Macros used to generate various ARM or Thumb opcodes.\n */\n\n/* ARM mode instructions */\n\n/* Store multiple increment after\n * rn: base register\n * list: for each bit in list: store register\n * s: in privileged mode: store user-mode registers\n * w = 1: update the base register. w = 0: leave the base register untouched\n */\n#define ARMV4_5_STMIA(rn, list, s, w) \\\n\t(0xe8800000 | ((s) << 22) | ((w) << 21) | ((rn) << 16) | (list))\n\n/* Load multiple increment after\n * rn: base register\n * list: for each bit in list: store register\n * s: in privileged mode: store user-mode registers\n * w = 1: update the base register. w = 0: leave the base register untouched\n */\n#define ARMV4_5_LDMIA(rn, list, s, w) \\\n\t(0xe8900000 | ((s) << 22) | ((w) << 21) | ((rn) << 16) | (list))\n\n/* MOV r8, r8 */\n#define ARMV4_5_NOP\t\t\t\t\t(0xe1a08008)\n\n/* Move PSR to general purpose register\n * r = 1: SPSR r = 0: CPSR\n * rn: target register\n */\n#define ARMV4_5_MRS(rn, r)\t(0xe10f0000 | ((r) << 22) | ((rn) << 12))\n\n/* Store register\n * rd: register to store\n * rn: base register\n */\n#define ARMV4_5_STR(rd, rn)\t(0xe5800000 | ((rd) << 12) | ((rn) << 16))\n\n/* Load register\n * rd: register to load\n * rn: base register\n */\n#define ARMV4_5_LDR(rd, rn)\t(0xe5900000 | ((rd) << 12) | ((rn) << 16))\n\n/* Move general purpose register to PSR\n * r = 1: SPSR r = 0: CPSR\n * field: Field mask\n * 1: control field 2: extension field 4: status field 8: flags field\n * rm: source register\n */\n#define ARMV4_5_MSR_GP(rm, field, r) \\\n\t(0xe120f000 | (rm) | ((field) << 16) | ((r) << 22))\n#define ARMV4_5_MSR_IM(im, rotate, field, r) \\\n\t(0xe320f000 | (im)  | ((rotate) << 8) | ((field) << 16) | ((r) << 22))\n\n/* Load Register Word Immediate Post-Index\n * rd: register to load\n * rn: base register\n */\n#define ARMV4_5_LDRW_IP(rd, rn)\t(0xe4900004 | ((rd) << 12) | ((rn) << 16))\n\n/* Load Register Halfword Immediate Post-Index\n * rd: register to load\n * rn: base register\n */\n#define ARMV4_5_LDRH_IP(rd, rn)\t(0xe0d000b2 | ((rd) << 12) | ((rn) << 16))\n\n/* Load Register Byte Immediate Post-Index\n * rd: register to load\n * rn: base register\n */\n#define ARMV4_5_LDRB_IP(rd, rn)\t(0xe4d00001 | ((rd) << 12) | ((rn) << 16))\n\n/* Store register Word Immediate Post-Index\n * rd: register to store\n * rn: base register\n */\n#define ARMV4_5_STRW_IP(rd, rn)\t(0xe4800004 | ((rd) << 12) | ((rn) << 16))\n\n/* Store register Halfword Immediate Post-Index\n * rd: register to store\n * rn: base register\n */\n#define ARMV4_5_STRH_IP(rd, rn)\t(0xe0c000b2 | ((rd) << 12) | ((rn) << 16))\n\n/* Store register Byte Immediate Post-Index\n * rd: register to store\n * rn: base register\n */\n#define ARMV4_5_STRB_IP(rd, rn)\t(0xe4c00001 | ((rd) << 12) | ((rn) << 16))\n\n/* Branch (and Link)\n * im: Branch target (left-shifted by 2 bits, added to PC)\n * l: 1: branch and link 0: branch only\n */\n#define ARMV4_5_B(im, l) (0xea000000 | (im) | ((l) << 24))\n\n/* Branch and exchange (ARM state)\n * rm: register holding branch target address\n */\n#define ARMV4_5_BX(rm) (0xe12fff10 | (rm))\n\n/* Copies two words from two ARM core registers\n * into a doubleword extension register, or\n * from a doubleword extension register to two ARM core registers.\n * See Armv7-A arch reference manual section A8.8.345\n * rt:   Arm core register 1\n * rt2:  Arm core register 2\n * vm:   The doubleword extension register\n * m:    m = UInt(m:vm);\n * op:   to_arm_registers = (op == ‘1’);\n */\n#define ARMV4_5_VMOV(op, rt2, rt, m, vm) \\\n\t(0xec400b10 | ((op) << 20) | ((rt2) << 16) | \\\n\t((rt) << 12) | ((m) << 5) | (vm))\n\n/* Moves the value of the FPSCR to an ARM core register\n * rt: Arm core register\n */\n#define ARMV4_5_VMRS(rt) (0xeef10a10 | ((rt) << 12))\n\n/* Moves the value of an ARM core register to the FPSCR.\n * rt: Arm core register\n */\n#define ARMV4_5_VMSR(rt) (0xeee10a10 | ((rt) << 12))\n\n/* Store data from coprocessor to consecutive memory\n * See Armv7-A arch doc section A8.6.187\n * p:    1=index mode (offset from rn)\n * u:    1=add, 0=subtract  rn address with imm\n * d:    Opcode D encoding\n * w:    write back the offset start address to the rn register\n * cp:   Coprocessor number (4 bits)\n * crd:  Coprocessor source register (4 bits)\n * rn:   Base register for memory address (4 bits)\n * imm:  Immediate value (0 - 1020, must be divisible by 4)\n */\n#define ARMV4_5_STC(p, u, d, w, cp, crd, rn, imm) \\\n\t(0xec000000 | ((p) << 24) | ((u) << 23) | ((d) << 22) | \\\n\t((w) << 21) | ((rn) << 16) | ((crd) << 12) | ((cp) << 8) | ((imm)>>2))\n\n/* Loads data from consecutive memory to coprocessor\n * See Armv7-A arch doc section A8.6.51\n * p:    1=index mode (offset from rn)\n * u:    1=add, 0=subtract  rn address with imm\n * d:    Opcode D encoding\n * w:    write back the offset start address to the rn register\n * cp:   Coprocessor number (4 bits)\n * crd:  Coprocessor dest register (4 bits)\n * rn:   Base register for memory address (4 bits)\n * imm:  Immediate value (0 - 1020, must be divisible by 4)\n */\n#define ARMV4_5_LDC(p, u, d, w, cp, crd, rn, imm) \\\n\t(0xec100000 | ((p) << 24) | ((u) << 23) | ((d) << 22) | \\\n\t((w) << 21) | ((rn) << 16) | ((crd) << 12) | ((cp) << 8) | ((imm) >> 2))\n\n/* Move to ARM register from coprocessor\n * cp: Coprocessor number\n * op1: Coprocessor opcode\n * rd: destination register\n * crn: first coprocessor operand\n * crm: second coprocessor operand\n * op2: Second coprocessor opcode\n */\n#define ARMV4_5_MRC(cp, op1, rd, crn, crm, op2) \\\n\t(0xee100010 | (crm) | ((op2) << 5) | ((cp) << 8) \\\n\t| ((rd) << 12) | ((crn) << 16) | ((op1) << 21))\n\n/* Move to coprocessor from ARM register\n * cp: Coprocessor number\n * op1: Coprocessor opcode\n * rd: destination register\n * crn: first coprocessor operand\n * crm: second coprocessor operand\n * op2: Second coprocessor opcode\n */\n#define ARMV4_5_MCR(cp, op1, rd, crn, crm, op2) \\\n\t(0xee000010 | (crm) | ((op2) << 5) | ((cp) << 8) \\\n\t| ((rd) << 12) | ((crn) << 16) | ((op1) << 21))\n\n/* Breakpoint instruction (ARMv5)\n * im: 16-bit immediate\n */\n#define ARMV5_BKPT(im) (0xe1200070 | ((im & 0xfff0) << 4) | (im & 0xf))\n\n\n/* Thumb mode instructions\n *\n * NOTE: these 16-bit opcodes fill both halves of a word with the same\n * value.  The reason for this is that when we need to execute Thumb\n * opcodes on ARM7/ARM9 cores (to switch to ARM state on debug entry),\n * we must shift 32 bits to the bus using scan chain 1 ... if we write\n * both halves, we don't need to track which half matters.  On ARMv6 and\n * ARMv7 we don't execute Thumb instructions in debug mode; the ITR\n * register does not accept Thumb (or Thumb2) opcodes.\n */\n\n/* Store register (Thumb mode)\n * rd: source register\n * rn: base register\n */\n#define ARMV4_5_T_STR(rd, rn) \\\n\t((0x6000 | (rd) | ((rn) << 3)) | \\\n\t((0x6000 | (rd) | ((rn) << 3)) << 16))\n\n/* Load register (Thumb state)\n * rd: destination register\n * rn: base register\n */\n#define ARMV4_5_T_LDR(rd, rn) \\\n\t((0x6800 | ((rn) << 3) | (rd)) \\\n\t| ((0x6800 | ((rn) << 3) | (rd)) << 16))\n\n/* Load multiple (Thumb state)\n * rn: base register\n * list: for each bit in list: store register\n */\n#define ARMV4_5_T_LDMIA(rn, list) \\\n\t((0xc800 | ((rn) << 8) | (list)) \\\n\t| ((0xc800 | ((rn) << 8) | (list)) << 16))\n\n/* Load register with PC relative addressing\n * rd: register to load\n */\n#define ARMV4_5_T_LDR_PCREL(rd) \\\n\t((0x4800 | ((rd) << 8)) \\\n\t| ((0x4800 | ((rd) << 8)) << 16))\n\n/* Move hi register (Thumb mode)\n * rd: destination register\n * rm: source register\n */\n#define ARMV4_5_T_MOV(rd, rm) \\\n\t((0x4600 | ((rd) & 0x7) | (((rd) & 0x8) << 4) | \\\n\t\t(((rm) & 0x7) << 3) | (((rm) & 0x8) << 3)) \\\n\t| ((0x4600 | ((rd) & 0x7) | (((rd) & 0x8) << 4) | \\\n\t\t(((rm) & 0x7) << 3) | (((rm) & 0x8) << 3)) << 16))\n\n/* No operation (Thumb mode)\n * NOTE:  this is \"MOV r8, r8\" ... Thumb2 adds two\n * architected NOPs, 16-bit and 32-bit.\n */\n#define ARMV4_5_T_NOP\t(0x46c0 | (0x46c0 << 16))\n\n/* Move immediate to register (Thumb state)\n * rd: destination register\n * im: 8-bit immediate value\n */\n#define ARMV4_5_T_MOV_IM(rd, im) \\\n\t((0x2000 | ((rd) << 8) | (im)) \\\n\t| ((0x2000 | ((rd) << 8) | (im)) << 16))\n\n/* Branch and Exchange\n * rm: register containing branch target\n */\n#define ARMV4_5_T_BX(rm) \\\n\t((0x4700 | ((rm) << 3)) \\\n\t| ((0x4700 | ((rm) << 3)) << 16))\n\n/* Branch (Thumb state)\n * imm: Branch target\n */\n#define ARMV4_5_T_B(imm) \\\n\t((0xe000 | (imm)) \\\n\t| ((0xe000 | (imm)) << 16))\n\n/* Breakpoint instruction (ARMv5) (Thumb state)\n * Im: 8-bit immediate\n */\n#define ARMV5_T_BKPT(im) \\\n\t((0xbe00 | (im)) \\\n\t| ((0xbe00 | (im)) << 16))\n\n/* Move to Register from Special Register\n *\t32 bit Thumb2 instruction\n * rd: destination register\n * sysm: source special register\n */\n#define ARM_T2_MRS(rd, sysm) \\\n\t((0xF3EF) | ((0x8000 | (rd << 8) | sysm) << 16))\n\n/* Move from Register from Special Register\n *\t32 bit Thumb2 instruction\n * rd: source register\n * sysm: destination special register\n */\n#define ARM_T2_MSR(sysm, rn) \\\n\t((0xF380 | (rn << 8)) | ((0x8800 | sysm) << 16))\n\n/* Change Processor State.\n *\t16 bit Thumb2 instruction\n * rd: source register\n * IF: A_FLAG and/or I_FLAG and/or F_FLAG\n */\n#define A_FLAG 4\n#define I_FLAG 2\n#define F_FLAG 1\n#define ARM_T2_CPSID(_if) \\\n\t((0xB660 | (1 << 8) | ((_if)&0x3)) \\\n\t| ((0xB660 | (1 << 8) | ((_if)&0x3)) << 16))\n#define ARM_T2_CPSIE(_if) \\\n\t((0xB660 | (0 << 8) | ((_if)&0x3)) \\\n\t| ((0xB660 | (0 << 8) | ((_if)&0x3)) << 16))\n\n#endif /* OPENOCD_TARGET_ARM_OPCODES_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_semihosting.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Marvell Technology Group Ltd.                   *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n *                                                                         *\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *                                                                         *\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n ***************************************************************************/\n\n/**\n * @file\n * Hold ARM semihosting support.\n *\n * Semihosting enables code running on an ARM target to use the I/O\n * facilities on the host computer. The target application must be linked\n * against a library that forwards operation requests by using the SVC\n * instruction trapped at the Supervisor Call vector by the debugger.\n * Details can be found in chapter 8 of DUI0203I_rvct_developer_guide.pdf\n * from ARM Ltd.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"armv4_5.h\"\n#include \"arm7_9_common.h\"\n#include \"armv7m.h\"\n#include \"armv7a.h\"\n#include \"armv8.h\"\n#include \"cortex_m.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n#include \"target_type.h\"\n#include \"arm_semihosting.h\"\n#include <helper/binarybuffer.h>\n#include <helper/log.h>\n#include <sys/stat.h>\n\nstatic int arm_semihosting_resume(struct target *target, int *retval)\n{\n\tif (is_armv8(target_to_armv8(target))) {\n\t\tstruct armv8_common *armv8 = target_to_armv8(target);\n\t\tif (armv8->last_run_control_op == ARMV8_RUNCONTROL_RESUME) {\n\t\t\t*retval = target_resume(target, 1, 0, 0, 0);\n\t\t\tif (*retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to resume target\");\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else if (armv8->last_run_control_op == ARMV8_RUNCONTROL_STEP)\n\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t} else {\n\t\t*retval = target_resume(target, 1, 0, 0, 0);\n\t\tif (*retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to resume target\");\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 1;\n}\n\nstatic int post_result(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tif (!target->semihosting)\n\t\treturn ERROR_FAIL;\n\n\t/* REVISIT this looks wrong ... ARM11 and Cortex-A8\n\t * should work this way at least sometimes.\n\t */\n\tif (is_arm7_9(target_to_arm7_9(target)) ||\n\t    is_armv7a(target_to_armv7a(target))) {\n\t\tuint32_t spsr;\n\n\t\t/* return value in R0 */\n\t\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, target->semihosting->result);\n\t\tarm->core_cache->reg_list[0].dirty = true;\n\n\t\t/* LR --> PC */\n\t\tbuf_set_u32(arm->core_cache->reg_list[15].value, 0, 32,\n\t\t\tbuf_get_u32(arm_reg_current(arm, 14)->value, 0, 32));\n\t\tarm->core_cache->reg_list[15].dirty = true;\n\n\t\t/* saved PSR --> current PSR */\n\t\tspsr = buf_get_u32(arm->spsr->value, 0, 32);\n\n\t\t/* REVISIT should this be arm_set_cpsr(arm, spsr)\n\t\t * instead of a partially unrolled version?\n\t\t */\n\n\t\tbuf_set_u32(arm->cpsr->value, 0, 32, spsr);\n\t\tarm->cpsr->dirty = true;\n\t\tarm->core_mode = spsr & 0x1f;\n\t\tif (spsr & 0x20)\n\t\t\tarm->core_state = ARM_STATE_THUMB;\n\n\t} else if (is_armv8(target_to_armv8(target))) {\n\t\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\t\t/* return value in R0 */\n\t\t\tbuf_set_u64(arm->core_cache->reg_list[0].value, 0, 64, target->semihosting->result);\n\t\t\tarm->core_cache->reg_list[0].dirty = true;\n\n\t\t\tuint64_t pc = buf_get_u64(arm->core_cache->reg_list[32].value, 0, 64);\n\t\t\tbuf_set_u64(arm->pc->value, 0, 64, pc + 4);\n\t\t\tarm->pc->dirty = true;\n\t\t}  else if (arm->core_state == ARM_STATE_ARM) {\n\t\t\t/* return value in R0 */\n\t\t\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, target->semihosting->result);\n\t\t\tarm->core_cache->reg_list[0].dirty = true;\n\n\t\t\tuint32_t pc = buf_get_u32(arm->core_cache->reg_list[32].value, 0, 32);\n\t\t\tbuf_set_u32(arm->pc->value, 0, 32, pc + 4);\n\t\t\tarm->pc->dirty = true;\n\t\t} else if (arm->core_state == ARM_STATE_THUMB) {\n\t\t\t/* return value in R0 */\n\t\t\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, target->semihosting->result);\n\t\t\tarm->core_cache->reg_list[0].dirty = true;\n\n\t\t\tuint32_t pc = buf_get_u32(arm->core_cache->reg_list[32].value, 0, 32);\n\t\t\tbuf_set_u32(arm->pc->value, 0, 32, pc + 2);\n\t\t\tarm->pc->dirty = true;\n\t\t}\n\t} else {\n\t\t/* resume execution, this will be pc+2 to skip over the\n\t\t * bkpt instruction */\n\n\t\t/* return result in R0 */\n\t\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, target->semihosting->result);\n\t\tarm->core_cache->reg_list[0].dirty = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Initialize ARM semihosting support.\n *\n * @param target Pointer to the ARM target to initialize.\n * @return An error status if there is a problem during initialization.\n */\nint arm_semihosting_init(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tassert(arm->setup_semihosting);\n\tsemihosting_common_init(target, arm->setup_semihosting, post_result);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Checks for and processes an ARM semihosting request.  This is meant\n * to be called when the target is stopped due to a debug mode entry.\n * If the value 0 is returned then there was nothing to process. A non-zero\n * return value signifies that a request was processed and the target resumed,\n * or an error was encountered, in which case the caller must return\n * immediately.\n *\n * @param target Pointer to the ARM target to process.  This target must\n *\tnot represent an ARMv6-M or ARMv7-M processor.\n * @param retval Pointer to a location where the return code will be stored\n * @return non-zero value if a request was processed or an error encountered\n */\nint arm_semihosting(struct target *target, int *retval)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tuint32_t pc, lr, spsr;\n\tstruct reg *r;\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting)\n\t\treturn 0;\n\n\tif (!semihosting->is_active)\n\t\treturn 0;\n\n\tif (is_arm7_9(target_to_arm7_9(target)) ||\n\t    is_armv7a(armv7a)) {\n\t\tuint32_t vbar = 0x00000000;\n\n\t\tif (arm->core_mode != ARM_MODE_SVC)\n\t\t\treturn 0;\n\n\t\tif (is_armv7a(armv7a)) {\n\t\t\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\n\t\t\t*retval = dpm->prepare(dpm);\n\t\t\tif (*retval == ERROR_OK) {\n\t\t\t\t*retval = dpm->instr_read_data_r0(dpm,\n\t\t\t\t\t\t\t\t ARMV4_5_MRC(15, 0, 0, 12, 0, 0),\n\t\t\t\t\t\t\t\t &vbar);\n\n\t\t\t\tdpm->finish(dpm);\n\n\t\t\t\tif (*retval != ERROR_OK)\n\t\t\t\t\treturn 1;\n\t\t\t} else {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\t/* Check for PC == 0x00000008 or 0xffff0008: Supervisor Call vector. */\n\t\tr = arm->pc;\n\t\tpc = buf_get_u32(r->value, 0, 32);\n\t\tif (pc != (vbar + 0x00000008) && pc != 0xffff0008)\n\t\t\treturn 0;\n\n\t\tr = arm_reg_current(arm, 14);\n\t\tlr = buf_get_u32(r->value, 0, 32);\n\n\t\t/* Core-specific code should make sure SPSR is retrieved\n\t\t * when the above checks pass...\n\t\t */\n\t\tif (!arm->spsr->valid) {\n\t\t\tLOG_ERROR(\"SPSR not valid!\");\n\t\t\t*retval = ERROR_FAIL;\n\t\t\treturn 1;\n\t\t}\n\n\t\tspsr = buf_get_u32(arm->spsr->value, 0, 32);\n\n\t\t/* check instruction that triggered this trap */\n\t\tif (spsr & (1 << 5)) {\n\t\t\t/* was in Thumb (or ThumbEE) mode */\n\t\t\tuint8_t insn_buf[2];\n\t\t\tuint16_t insn;\n\n\t\t\t*retval = target_read_memory(target, lr-2, 2, 1, insn_buf);\n\t\t\tif (*retval != ERROR_OK)\n\t\t\t\treturn 1;\n\t\t\tinsn = target_buffer_get_u16(target, insn_buf);\n\n\t\t\t/* SVC 0xab */\n\t\t\tif (insn != 0xDFAB)\n\t\t\t\treturn 0;\n\t\t} else if (spsr & (1 << 24)) {\n\t\t\t/* was in Jazelle mode */\n\t\t\treturn 0;\n\t\t} else {\n\t\t\t/* was in ARM mode */\n\t\t\tuint8_t insn_buf[4];\n\t\t\tuint32_t insn;\n\n\t\t\t*retval = target_read_memory(target, lr-4, 4, 1, insn_buf);\n\t\t\tif (*retval != ERROR_OK)\n\t\t\t\treturn 1;\n\t\t\tinsn = target_buffer_get_u32(target, insn_buf);\n\n\t\t\t/* SVC 0x123456 */\n\t\t\tif (insn != 0xEF123456)\n\t\t\t\treturn 0;\n\t\t}\n\t} else if (is_armv7m(target_to_armv7m(target))) {\n\t\tuint16_t insn;\n\n\t\tif (target->debug_reason != DBG_REASON_BREAKPOINT)\n\t\t\treturn 0;\n\n\t\tr = arm->pc;\n\t\tpc = buf_get_u32(r->value, 0, 32);\n\n\t\tpc &= ~1;\n\t\t*retval = target_read_u16(target, pc, &insn);\n\t\tif (*retval != ERROR_OK)\n\t\t\treturn 1;\n\n\t\t/* bkpt 0xAB */\n\t\tif (insn != 0xBEAB)\n\t\t\treturn 0;\n\t} else if (is_armv8(target_to_armv8(target))) {\n\t\tif (target->debug_reason != DBG_REASON_BREAKPOINT)\n\t\t\treturn 0;\n\n\t\t/* According to ARM Semihosting for AArch32 and AArch64:\n\t\t * The HLT encodings are new in version 2.0 of the semihosting specification.\n\t\t * Where possible, have semihosting callers continue to use the previously\n\t\t * existing trap instructions to ensure compatibility with legacy semihosting\n\t\t * implementations.\n\t\t * These trap instructions are HLT for A64, SVC on A+R profile A32 or T32,\n\t\t * and BKPT on M profile.\n\t\t * However, it is necessary to change from SVC to HLT instructions to support\n\t\t * AArch32 semihosting properly in a mixed AArch32/AArch64 system. */\n\n\t\tif (arm->core_state == ARM_STATE_AARCH64) {\n\t\t\tuint32_t insn = 0;\n\t\t\tr = arm->pc;\n\t\t\tuint64_t pc64 = buf_get_u64(r->value, 0, 64);\n\t\t\t*retval = target_read_u32(target, pc64, &insn);\n\n\t\t\tif (*retval != ERROR_OK)\n\t\t\t\treturn 1;\n\n\t\t\t/* HLT 0xF000 */\n\t\t\tif (insn != 0xD45E0000)\n\t\t\t\treturn 0;\n\t\t} else if (arm->core_state == ARM_STATE_ARM) {\n\t\t\tr = arm->pc;\n\t\t\tpc = buf_get_u32(r->value, 0, 32);\n\n\t\t\t/* A32 instruction => check for HLT 0xF000 (0xE10F0070) */\n\t\t\tuint32_t insn = 0;\n\n\t\t\t*retval = target_read_u32(target, pc, &insn);\n\n\t\t\tif (*retval != ERROR_OK)\n\t\t\t\treturn 1;\n\n\t\t\t/* HLT 0xF000*/\n\t\t\tif (insn != 0xE10F0070)\n\t\t\t\treturn 0;\n\t\t} else if (arm->core_state == ARM_STATE_THUMB) {\n\t\t\tr = arm->pc;\n\t\t\tpc = buf_get_u32(r->value, 0, 32);\n\n\t\t\t/* T32 instruction => check for HLT 0x3C (0xBABC) */\n\t\t\tuint16_t insn = 0;\n\t\t\t*retval = target_read_u16(target, pc, &insn);\n\n\t\t\tif (*retval != ERROR_OK)\n\t\t\t\treturn 1;\n\n\t\t\t/* HLT 0x3C*/\n\t\t\tif (insn != 0xBABC)\n\t\t\t\treturn 0;\n\t\t} else\n\t\t\treturn 1;\n\t} else {\n\t\tLOG_ERROR(\"Unsupported semi-hosting Target\");\n\t\treturn 0;\n\t}\n\n\t/* Perform semihosting if we are not waiting on a fileio\n\t * operation to complete.\n\t */\n\tif (!semihosting->hit_fileio) {\n\t\tif (is_armv8(target_to_armv8(target)) &&\n\t\t\t\tarm->core_state == ARM_STATE_AARCH64) {\n\t\t\t/* Read op and param from register x0 and x1 respectively. */\n\t\t\tsemihosting->op = buf_get_u64(arm->core_cache->reg_list[0].value, 0, 64);\n\t\t\tsemihosting->param = buf_get_u64(arm->core_cache->reg_list[1].value, 0, 64);\n\t\t\tsemihosting->word_size_bytes = 8;\n\t\t} else {\n\t\t\t/* Read op and param from register r0 and r1 respectively. */\n\t\t\tsemihosting->op = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);\n\t\t\tsemihosting->param = buf_get_u32(arm->core_cache->reg_list[1].value, 0, 32);\n\t\t\tsemihosting->word_size_bytes = 4;\n\t\t}\n\n\t\t/* Check for ARM operation numbers. */\n\t\tif ((semihosting->op >= 0 && semihosting->op <= 0x31) ||\n\t\t\t(semihosting->op >= 0x100 && semihosting->op <= 0x107)) {\n\n\t\t\t*retval = semihosting_common(target);\n\t\t\tif (*retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed semihosting operation (0x%02X)\",\n\t\t\t\t\t\tsemihosting->op);\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Unknown operation number, not a semihosting call. */\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* Resume if target it is resumable and we are not waiting on a fileio\n\t * operation to complete:\n\t */\n\tif (semihosting->is_resumable && !semihosting->hit_fileio)\n\t\treturn arm_semihosting_resume(target, retval);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_semihosting.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Marvell Technology Group Ltd.                   *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_SEMIHOSTING_H\n#define OPENOCD_TARGET_ARM_SEMIHOSTING_H\n\n#include \"semihosting_common.h\"\n\nint arm_semihosting_init(struct target *target);\nint arm_semihosting(struct target *target, int *retval);\n\n#endif /* OPENOCD_TARGET_ARM_SEMIHOSTING_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_simulator.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Hongtao Zheng                                   *\n *   hontor@126.com                                                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"armv4_5.h\"\n#include \"arm_disassembler.h\"\n#include \"arm_simulator.h\"\n#include <helper/binarybuffer.h>\n#include \"register.h\"\n#include <helper/log.h>\n\nstatic uint32_t arm_shift(uint8_t shift, uint32_t rm,\n\tuint32_t shift_amount, uint8_t *carry)\n{\n\tuint32_t return_value = 0;\n\tshift_amount &= 0xff;\n\n\tif (shift == 0x0) {\t/* LSL */\n\t\tif ((shift_amount > 0) && (shift_amount <= 32)) {\n\t\t\treturn_value = rm << shift_amount;\n\t\t\t*carry = rm >> (32 - shift_amount);\n\t\t} else if (shift_amount > 32) {\n\t\t\treturn_value = 0x0;\n\t\t\t*carry = 0x0;\n\t\t} else /* (shift_amount == 0) */\n\t\t\treturn_value = rm;\n\t} else if (shift == 0x1) {\t/* LSR */\n\t\tif ((shift_amount > 0) && (shift_amount <= 32)) {\n\t\t\treturn_value = rm >> shift_amount;\n\t\t\t*carry = (rm >> (shift_amount - 1)) & 1;\n\t\t} else if (shift_amount > 32) {\n\t\t\treturn_value = 0x0;\n\t\t\t*carry = 0x0;\n\t\t} else /* (shift_amount == 0) */\n\t\t\treturn_value = rm;\n\t} else if (shift == 0x2) {\t/* ASR */\n\t\tif ((shift_amount > 0) && (shift_amount <= 32)) {\n\t\t\t/* C right shifts of unsigned values are guaranteed to\n\t\t\t * be logical (shift in zeroes); simulate an arithmetic\n\t\t\t * shift (shift in signed-bit) by adding the sign bit\n\t\t\t * manually\n\t\t\t */\n\t\t\treturn_value = rm >> shift_amount;\n\t\t\tif (rm & 0x80000000)\n\t\t\t\treturn_value |= 0xffffffff << (32 - shift_amount);\n\t\t} else if (shift_amount > 32) {\n\t\t\tif (rm & 0x80000000) {\n\t\t\t\treturn_value = 0xffffffff;\n\t\t\t\t*carry = 0x1;\n\t\t\t} else {\n\t\t\t\treturn_value = 0x0;\n\t\t\t\t*carry = 0x0;\n\t\t\t}\n\t\t} else /* (shift_amount == 0) */\n\t\t\treturn_value = rm;\n\t} else if (shift == 0x3) {\t/* ROR */\n\t\tif (shift_amount == 0)\n\t\t\treturn_value = rm;\n\t\telse {\n\t\t\tshift_amount = shift_amount % 32;\n\t\t\treturn_value = (rm >> shift_amount) | (rm << (32 - shift_amount));\n\t\t\t*carry = (return_value >> 31) & 0x1;\n\t\t}\n\t} else if (shift == 0x4) {\t/* RRX */\n\t\treturn_value = rm >> 1;\n\t\tif (*carry)\n\t\t\trm |= 0x80000000;\n\t\t*carry = rm & 0x1;\n\t}\n\n\treturn return_value;\n}\n\n\nstatic uint32_t arm_shifter_operand(struct arm_sim_interface *sim,\n\tint variant, union arm_shifter_operand shifter_operand,\n\tuint8_t *shifter_carry_out)\n{\n\tuint32_t return_value;\n\tint instruction_size;\n\n\tif (sim->get_state(sim) == ARM_STATE_ARM)\n\t\tinstruction_size = 4;\n\telse\n\t\tinstruction_size = 2;\n\n\t*shifter_carry_out = sim->get_cpsr(sim, 29, 1);\n\n\tif (variant == 0) /* 32-bit immediate */\n\t\treturn_value = shifter_operand.immediate.immediate;\n\telse if (variant == 1) {/* immediate shift */\n\t\tuint32_t rm = sim->get_reg_mode(sim, shifter_operand.immediate_shift.rm);\n\n\t\t/* adjust RM in case the PC is being read */\n\t\tif (shifter_operand.immediate_shift.rm == 15)\n\t\t\trm += 2 * instruction_size;\n\n\t\treturn_value = arm_shift(shifter_operand.immediate_shift.shift,\n\t\t\t\trm, shifter_operand.immediate_shift.shift_imm,\n\t\t\t\tshifter_carry_out);\n\t} else if (variant == 2) {\t/* register shift */\n\t\tuint32_t rm = sim->get_reg_mode(sim, shifter_operand.register_shift.rm);\n\t\tuint32_t rs = sim->get_reg_mode(sim, shifter_operand.register_shift.rs);\n\n\t\t/* adjust RM in case the PC is being read */\n\t\tif (shifter_operand.register_shift.rm == 15)\n\t\t\trm += 2 * instruction_size;\n\n\t\treturn_value = arm_shift(shifter_operand.immediate_shift.shift,\n\t\t\t\trm, rs, shifter_carry_out);\n\t} else {\n\t\tLOG_ERROR(\"BUG: shifter_operand.variant not 0, 1 or 2\");\n\t\treturn_value = 0xffffffff;\n\t}\n\n\treturn return_value;\n}\n\nstatic int pass_condition(uint32_t cpsr, uint32_t opcode)\n{\n\tswitch ((opcode & 0xf0000000) >> 28) {\n\t\tcase 0x0:\t/* EQ */\n\t\t\tif (cpsr & 0x40000000)\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x1:\t/* NE */\n\t\t\tif (!(cpsr & 0x40000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x2:\t/* CS */\n\t\t\tif (cpsr & 0x20000000)\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x3:\t/* CC */\n\t\t\tif (!(cpsr & 0x20000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x4:\t/* MI */\n\t\t\tif (cpsr & 0x80000000)\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x5:\t/* PL */\n\t\t\tif (!(cpsr & 0x80000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x6:\t/* VS */\n\t\t\tif (cpsr & 0x10000000)\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x7:\t/* VC */\n\t\t\tif (!(cpsr & 0x10000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x8:\t/* HI */\n\t\t\tif ((cpsr & 0x20000000) && !(cpsr & 0x40000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0x9:\t/* LS */\n\t\t\tif (!(cpsr & 0x20000000) || (cpsr & 0x40000000))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0xa:\t/* GE */\n\t\t\tif (((cpsr & 0x80000000) && (cpsr & 0x10000000))\n\t\t\t\t|| (!(cpsr & 0x80000000) && !(cpsr & 0x10000000)))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0xb:\t/* LT */\n\t\t\tif (((cpsr & 0x80000000) && !(cpsr & 0x10000000))\n\t\t\t\t|| (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0xc:\t/* GT */\n\t\t\tif (!(cpsr & 0x40000000) &&\n\t\t\t\t(((cpsr & 0x80000000) && (cpsr & 0x10000000))\n\t\t\t\t|| (!(cpsr & 0x80000000) && !(cpsr & 0x10000000))))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0xd:\t/* LE */\n\t\t\tif ((cpsr & 0x40000000) ||\n\t\t\t\t((cpsr & 0x80000000) && !(cpsr & 0x10000000))\n\t\t\t\t|| (!(cpsr & 0x80000000) && (cpsr & 0x10000000)))\n\t\t\t\treturn 1;\n\t\t\telse\n\t\t\t\treturn 0;\n\t\tcase 0xe:\n\t\tcase 0xf:\n\t\t\treturn 1;\n\n\t}\n\n\tLOG_ERROR(\"BUG: should never get here\");\n\treturn 0;\n}\n\nstatic int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode)\n{\n\treturn pass_condition(cpsr, (opcode & 0x0f00) << 20);\n}\n\n/* simulate a single step (if possible)\n * if the dry_run_pc argument is provided, no state is changed,\n * but the new pc is stored in the variable pointed at by the argument\n */\nstatic int arm_simulate_step_core(struct target *target,\n\tuint32_t *dry_run_pc, struct arm_sim_interface *sim)\n{\n\tuint32_t current_pc = sim->get_reg(sim, 15);\n\tstruct arm_instruction instruction;\n\tint instruction_size;\n\tint retval = ERROR_OK;\n\n\tif (sim->get_state(sim) == ARM_STATE_ARM) {\n\t\tuint32_t opcode;\n\n\t\t/* get current instruction, and identify it */\n\t\tretval = target_read_u32(target, current_pc, &opcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = arm_evaluate_opcode(opcode, current_pc, &instruction);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tinstruction_size = 4;\n\n\t\t/* check condition code (for all instructions) */\n\t\tif (!pass_condition(sim->get_cpsr(sim, 0, 32), opcode)) {\n\t\t\tif (dry_run_pc)\n\t\t\t\t*dry_run_pc = current_pc + instruction_size;\n\t\t\telse\n\t\t\t\tsim->set_reg(sim, 15, current_pc + instruction_size);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\tuint16_t opcode;\n\n\t\tretval = target_read_u16(target, current_pc, &opcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = thumb_evaluate_opcode(opcode, current_pc, &instruction);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tinstruction_size = 2;\n\n\t\t/* check condition code (only for branch (1) instructions) */\n\t\tif ((opcode & 0xf000) == 0xd000\n\t\t\t&& !thumb_pass_branch_condition(\n\t\t\tsim->get_cpsr(sim, 0, 32), opcode)) {\n\t\t\tif (dry_run_pc)\n\t\t\t\t*dry_run_pc = current_pc + instruction_size;\n\t\t\telse\n\t\t\t\tsim->set_reg(sim, 15, current_pc + instruction_size);\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\t/* Deal with 32-bit BL/BLX */\n\t\tif ((opcode & 0xf800) == 0xf000) {\n\t\t\tuint32_t high = instruction.info.b_bl_bx_blx.target_address;\n\t\t\tretval = target_read_u16(target, current_pc+2, &opcode);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = thumb_evaluate_opcode(opcode, current_pc, &instruction);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tinstruction.info.b_bl_bx_blx.target_address += high;\n\t\t}\n\t}\n\n\t/* examine instruction type */\n\n\t/* branch instructions */\n\tif ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) {\n\t\tuint32_t target_address;\n\n\t\tif (instruction.info.b_bl_bx_blx.reg_operand == -1)\n\t\t\ttarget_address = instruction.info.b_bl_bx_blx.target_address;\n\t\telse {\n\t\t\ttarget_address = sim->get_reg_mode(sim,\n\t\t\t\t\tinstruction.info.b_bl_bx_blx.reg_operand);\n\t\t\tif (instruction.info.b_bl_bx_blx.reg_operand == 15)\n\t\t\t\ttarget_address += 2 * instruction_size;\n\t\t}\n\n\t\tif (dry_run_pc) {\n\t\t\t*dry_run_pc = target_address & ~1;\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tif (instruction.type == ARM_B)\n\t\t\t\tsim->set_reg(sim, 15, target_address);\n\t\t\telse if (instruction.type == ARM_BL) {\n\t\t\t\tuint32_t old_pc = sim->get_reg(sim, 15);\n\t\t\t\tint t = (sim->get_state(sim) == ARM_STATE_THUMB);\n\t\t\t\tsim->set_reg_mode(sim, 14, old_pc + 4 + t);\n\t\t\t\tsim->set_reg(sim, 15, target_address);\n\t\t\t} else if (instruction.type == ARM_BX) {\n\t\t\t\tif (target_address & 0x1)\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_THUMB);\n\t\t\t\telse\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_ARM);\n\t\t\t\tsim->set_reg(sim, 15, target_address & 0xfffffffe);\n\t\t\t} else if (instruction.type == ARM_BLX) {\n\t\t\t\tuint32_t old_pc = sim->get_reg(sim, 15);\n\t\t\t\tint t = (sim->get_state(sim) == ARM_STATE_THUMB);\n\t\t\t\tsim->set_reg_mode(sim, 14, old_pc + 4 + t);\n\n\t\t\t\tif (target_address & 0x1)\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_THUMB);\n\t\t\t\telse\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_ARM);\n\t\t\t\tsim->set_reg(sim, 15, target_address & 0xfffffffe);\n\t\t\t}\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\t/* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */\n\telse if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))\n\t\t|| ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN))) {\n\t\tuint32_t rd, rn, shifter_operand;\n\t\tuint8_t c = sim->get_cpsr(sim, 29, 1);\n\t\tuint8_t carry_out;\n\n\t\trd = 0x0;\n\t\t/* ARM_MOV and ARM_MVN does not use Rn */\n\t\tif ((instruction.type != ARM_MOV) && (instruction.type != ARM_MVN))\n\t\t\trn = sim->get_reg_mode(sim, instruction.info.data_proc.rn);\n\t\telse\n\t\t\trn = 0;\n\n\t\tshifter_operand = arm_shifter_operand(sim,\n\t\t\t\tinstruction.info.data_proc.variant,\n\t\t\t\tinstruction.info.data_proc.shifter_operand,\n\t\t\t\t&carry_out);\n\n\t\t/* adjust Rn in case the PC is being read */\n\t\tif (instruction.info.data_proc.rn == 15)\n\t\t\trn += 2 * instruction_size;\n\n\t\tif (instruction.type == ARM_AND)\n\t\t\trd = rn & shifter_operand;\n\t\telse if (instruction.type == ARM_EOR)\n\t\t\trd = rn ^ shifter_operand;\n\t\telse if (instruction.type == ARM_SUB)\n\t\t\trd = rn - shifter_operand;\n\t\telse if (instruction.type == ARM_RSB)\n\t\t\trd = shifter_operand - rn;\n\t\telse if (instruction.type == ARM_ADD)\n\t\t\trd = rn + shifter_operand;\n\t\telse if (instruction.type == ARM_ADC)\n\t\t\trd = rn + shifter_operand + (c & 1);\n\t\telse if (instruction.type == ARM_SBC)\n\t\t\trd = rn - shifter_operand - (c & 1) ? 0 : 1;\n\t\telse if (instruction.type == ARM_RSC)\n\t\t\trd = shifter_operand - rn - (c & 1) ? 0 : 1;\n\t\telse if (instruction.type == ARM_ORR)\n\t\t\trd = rn | shifter_operand;\n\t\telse if (instruction.type == ARM_BIC)\n\t\t\trd = rn & ~(shifter_operand);\n\t\telse if (instruction.type == ARM_MOV)\n\t\t\trd = shifter_operand;\n\t\telse if (instruction.type == ARM_MVN)\n\t\t\trd = ~shifter_operand;\n\t\telse\n\t\t\tLOG_WARNING(\"unhandled instruction type\");\n\n\t\tif (dry_run_pc) {\n\t\t\tif (instruction.info.data_proc.rd == 15)\n\t\t\t\t*dry_run_pc = rd & ~1;\n\t\t\telse\n\t\t\t\t*dry_run_pc = current_pc + instruction_size;\n\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tif (instruction.info.data_proc.rd == 15) {\n\t\t\t\tsim->set_reg_mode(sim, 15, rd & ~1);\n\t\t\t\tif (rd & 1)\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_THUMB);\n\t\t\t\telse\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_ARM);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tsim->set_reg_mode(sim, instruction.info.data_proc.rd, rd);\n\t\t\tLOG_WARNING(\"no updating of flags yet\");\n\t\t}\n\t}\n\t/* compare instructions (CMP, CMN, TST, TEQ) */\n\telse if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) {\n\t\tif (dry_run_pc) {\n\t\t\t*dry_run_pc = current_pc + instruction_size;\n\t\t\treturn ERROR_OK;\n\t\t} else\n\t\t\tLOG_WARNING(\"no updating of flags yet\");\n\t}\n\t/* load register instructions */\n\telse if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH)) {\n\t\tuint32_t load_address = 0, modified_address = 0, load_value = 0;\n\t\tuint32_t rn = sim->get_reg_mode(sim, instruction.info.load_store.rn);\n\n\t\t/* adjust Rn in case the PC is being read */\n\t\tif (instruction.info.load_store.rn == 15)\n\t\t\trn += 2 * instruction_size;\n\n\t\tif (instruction.info.load_store.offset_mode == 0) {\n\t\t\tif (instruction.info.load_store.u)\n\t\t\t\tmodified_address = rn + instruction.info.load_store.offset.offset;\n\t\t\telse\n\t\t\t\tmodified_address = rn - instruction.info.load_store.offset.offset;\n\t\t} else if (instruction.info.load_store.offset_mode == 1) {\n\t\t\tuint32_t offset;\n\t\t\tuint32_t rm = sim->get_reg_mode(sim,\n\t\t\t\t\tinstruction.info.load_store.offset.reg.rm);\n\t\t\tuint8_t shift = instruction.info.load_store.offset.reg.shift;\n\t\t\tuint8_t shift_imm = instruction.info.load_store.offset.reg.shift_imm;\n\t\t\tuint8_t carry = sim->get_cpsr(sim, 29, 1);\n\n\t\t\toffset = arm_shift(shift, rm, shift_imm, &carry);\n\n\t\t\tif (instruction.info.load_store.u)\n\t\t\t\tmodified_address = rn + offset;\n\t\t\telse\n\t\t\t\tmodified_address = rn - offset;\n\t\t} else\n\t\t\tLOG_ERROR(\"BUG: offset_mode neither 0 (offset) nor 1 (scaled register)\");\n\n\t\tif (instruction.info.load_store.index_mode == 0) {\n\t\t\t/* offset mode\n\t\t\t * we load from the modified address, but don't change\n\t\t\t * the base address register\n\t\t\t */\n\t\t\tload_address = modified_address;\n\t\t\tmodified_address = rn;\n\t\t} else if (instruction.info.load_store.index_mode == 1) {\n\t\t\t/* pre-indexed mode\n\t\t\t * we load from the modified address, and write it\n\t\t\t * back to the base address register\n\t\t\t */\n\t\t\tload_address = modified_address;\n\t\t} else if (instruction.info.load_store.index_mode == 2) {\n\t\t\t/* post-indexed mode\n\t\t\t * we load from the unmodified address, and write the\n\t\t\t * modified address back\n\t\t\t */\n\t\t\tload_address = rn;\n\t\t}\n\n\t\tif ((!dry_run_pc) || (instruction.info.load_store.rd == 15)) {\n\t\t\tretval = target_read_u32(target, load_address, &load_value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\tif (dry_run_pc) {\n\t\t\tif (instruction.info.load_store.rd == 15)\n\t\t\t\t*dry_run_pc = load_value & ~1;\n\t\t\telse\n\t\t\t\t*dry_run_pc = current_pc + instruction_size;\n\t\t\treturn ERROR_OK;\n\t\t} else {\n\t\t\tif ((instruction.info.load_store.index_mode == 1) ||\n\t\t\t\t(instruction.info.load_store.index_mode == 2))\n\t\t\t\tsim->set_reg_mode(sim,\n\t\t\t\t\tinstruction.info.load_store.rn,\n\t\t\t\t\tmodified_address);\n\n\t\t\tif (instruction.info.load_store.rd == 15) {\n\t\t\t\tsim->set_reg_mode(sim, 15, load_value & ~1);\n\t\t\t\tif (load_value & 1)\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_THUMB);\n\t\t\t\telse\n\t\t\t\t\tsim->set_state(sim, ARM_STATE_ARM);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tsim->set_reg_mode(sim, instruction.info.load_store.rd, load_value);\n\t\t}\n\t}\n\t/* load multiple instruction */\n\telse if (instruction.type == ARM_LDM) {\n\t\tint i;\n\t\tuint32_t rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.rn);\n\t\tuint32_t load_values[16];\n\t\tint bits_set = 0;\n\n\t\tfor (i = 0; i < 16; i++) {\n\t\t\tif (instruction.info.load_store_multiple.register_list & (1 << i))\n\t\t\t\tbits_set++;\n\t\t}\n\n\t\tswitch (instruction.info.load_store_multiple.addressing_mode) {\n\t\t\tcase 0:\t/* Increment after */\n\t\t\t\t/* rn = rn; */\n\t\t\t\tbreak;\n\t\t\tcase 1:\t/* Increment before */\n\t\t\t\trn = rn + 4;\n\t\t\t\tbreak;\n\t\t\tcase 2:\t/* Decrement after */\n\t\t\t\trn = rn - (bits_set * 4) + 4;\n\t\t\t\tbreak;\n\t\t\tcase 3:\t/* Decrement before */\n\t\t\t\trn = rn - (bits_set * 4);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tfor (i = 0; i < 16; i++) {\n\t\t\tif (instruction.info.load_store_multiple.register_list & (1 << i)) {\n\t\t\t\tif ((!dry_run_pc) || (i == 15))\n\t\t\t\t\ttarget_read_u32(target, rn, &load_values[i]);\n\t\t\t\trn += 4;\n\t\t\t}\n\t\t}\n\n\t\tif (dry_run_pc) {\n\t\t\tif (instruction.info.load_store_multiple.register_list & 0x8000) {\n\t\t\t\t*dry_run_pc = load_values[15] & ~1;\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t} else {\n\t\t\tint update_cpsr = 0;\n\n\t\t\tif (instruction.info.load_store_multiple.s) {\n\t\t\t\tif (instruction.info.load_store_multiple.register_list & 0x8000)\n\t\t\t\t\tupdate_cpsr = 1;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\tif (instruction.info.load_store_multiple.register_list & (1 << i)) {\n\t\t\t\t\tif (i == 15) {\n\t\t\t\t\t\tuint32_t val = load_values[i];\n\t\t\t\t\t\tsim->set_reg_mode(sim, i, val & ~1);\n\t\t\t\t\t\tif (val & 1)\n\t\t\t\t\t\t\tsim->set_state(sim, ARM_STATE_THUMB);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsim->set_state(sim, ARM_STATE_ARM);\n\t\t\t\t\t} else\n\t\t\t\t\t\tsim->set_reg_mode(sim, i, load_values[i]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (update_cpsr) {\n\t\t\t\tuint32_t spsr = sim->get_reg_mode(sim, 16);\n\t\t\t\tsim->set_reg(sim, ARMV4_5_CPSR, spsr);\n\t\t\t}\n\n\t\t\t/* base register writeback */\n\t\t\tif (instruction.info.load_store_multiple.w)\n\t\t\t\tsim->set_reg_mode(sim, instruction.info.load_store_multiple.rn, rn);\n\n\n\t\t\tif (instruction.info.load_store_multiple.register_list & 0x8000)\n\t\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\t/* store multiple instruction */\n\telse if (instruction.type == ARM_STM) {\n\t\tint i;\n\n\t\tif (dry_run_pc) {\n\t\t\t/* STM wont affect PC (advance by instruction size */\n\t\t} else {\n\t\t\tuint32_t rn = sim->get_reg_mode(sim,\n\t\t\t\t\tinstruction.info.load_store_multiple.rn);\n\t\t\tint bits_set = 0;\n\n\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\tif (instruction.info.load_store_multiple.register_list & (1 << i))\n\t\t\t\t\tbits_set++;\n\t\t\t}\n\n\t\t\tswitch (instruction.info.load_store_multiple.addressing_mode) {\n\t\t\t\tcase 0:\t/* Increment after */\n\t\t\t\t\t/* rn = rn; */\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\t/* Increment before */\n\t\t\t\t\trn = rn + 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\t/* Decrement after */\n\t\t\t\t\trn = rn - (bits_set * 4) + 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\t/* Decrement before */\n\t\t\t\t\trn = rn - (bits_set * 4);\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\tif (instruction.info.load_store_multiple.register_list & (1 << i)) {\n\t\t\t\t\ttarget_write_u32(target, rn, sim->get_reg_mode(sim, i));\n\t\t\t\t\trn += 4;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* base register writeback */\n\t\t\tif (instruction.info.load_store_multiple.w)\n\t\t\t\tsim->set_reg_mode(sim,\n\t\t\t\t\tinstruction.info.load_store_multiple.rn, rn);\n\n\t\t}\n\t} else if (!dry_run_pc) {\n\t\t/* the instruction wasn't handled, but we're supposed to simulate it\n\t\t */\n\t\tLOG_ERROR(\"Unimplemented instruction, could not simulate it.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (dry_run_pc) {\n\t\t*dry_run_pc = current_pc + instruction_size;\n\t\treturn ERROR_OK;\n\t} else {\n\t\tsim->set_reg(sim, 15, current_pc + instruction_size);\n\t\treturn ERROR_OK;\n\t}\n\n}\n\nstatic uint32_t armv4_5_get_reg(struct arm_sim_interface *sim, int reg)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\treturn buf_get_u32(arm->core_cache->reg_list[reg].value, 0, 32);\n}\n\nstatic void armv4_5_set_reg(struct arm_sim_interface *sim, int reg, uint32_t value)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\tbuf_set_u32(arm->core_cache->reg_list[reg].value, 0, 32, value);\n}\n\nstatic uint32_t armv4_5_get_reg_mode(struct arm_sim_interface *sim, int reg)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\treturn buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\tarm->core_mode, reg).value, 0, 32);\n}\n\nstatic void armv4_5_set_reg_mode(struct arm_sim_interface *sim, int reg, uint32_t value)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\tbuf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\tarm->core_mode, reg).value, 0, 32, value);\n}\n\nstatic uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\treturn buf_get_u32(arm->cpsr->value, pos, bits);\n}\n\nstatic enum arm_state armv4_5_get_state(struct arm_sim_interface *sim)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\treturn arm->core_state;\n}\n\nstatic void armv4_5_set_state(struct arm_sim_interface *sim, enum arm_state mode)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\tarm->core_state = mode;\n}\n\nstatic enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim)\n{\n\tstruct arm *arm = (struct arm *)sim->user_data;\n\n\treturn arm->core_mode;\n}\n\nint arm_simulate_step(struct target *target, uint32_t *dry_run_pc)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_sim_interface sim;\n\n\tsim.user_data = arm;\n\tsim.get_reg = &armv4_5_get_reg;\n\tsim.set_reg = &armv4_5_set_reg;\n\tsim.get_reg_mode = &armv4_5_get_reg_mode;\n\tsim.set_reg_mode = &armv4_5_set_reg_mode;\n\tsim.get_cpsr = &armv4_5_get_cpsr;\n\tsim.get_mode = &armv4_5_get_mode;\n\tsim.get_state = &armv4_5_get_state;\n\tsim.set_state = &armv4_5_set_state;\n\n\treturn arm_simulate_step_core(target, dry_run_pc, &sim);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_simulator.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2006 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM_SIMULATOR_H\n#define OPENOCD_TARGET_ARM_SIMULATOR_H\n\nstruct target;\n\nstruct arm_sim_interface {\n\tvoid *user_data;\n\tuint32_t (*get_reg)(struct arm_sim_interface *sim, int reg);\n\tvoid (*set_reg)(struct arm_sim_interface *sim, int reg, uint32_t value);\n\tuint32_t (*get_reg_mode)(struct arm_sim_interface *sim, int reg);\n\tvoid (*set_reg_mode)(struct arm_sim_interface *sim, int reg, uint32_t value);\n\tuint32_t (*get_cpsr)(struct arm_sim_interface *sim, int pos, int bits);\n\tenum arm_state (*get_state)(struct arm_sim_interface *sim);\n\tvoid (*set_state)(struct arm_sim_interface *sim, enum arm_state mode);\n\tenum arm_mode (*get_mode)(struct arm_sim_interface *sim);\n};\n\n/* armv4_5 version */\nint arm_simulate_step(struct target *target, uint32_t *dry_run_pc);\n\n#endif /* OPENOCD_TARGET_ARM_SIMULATOR_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_tpiu_swo.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/**\n * @file\n * This file implements support for the ARM CoreSight components Trace Port\n * Interface Unit (TPIU) and Serial Wire Output (SWO). It also supports the\n * CoreSight TPIU-Lite and the special TPIU version present with Cortex-M3\n * and Cortex-M4 (that includes SWO).\n */\n\n/*\n * Relevant specifications from ARM include:\n *\n * CoreSight(tm) Components Technical Reference Manual           ARM DDI 0314H\n * CoreSight(tm) TPIU-Lite Technical Reference Manual            ARM DDI 0317A\n * Cortex(tm)-M3 Technical Reference Manual                      ARM DDI 0337G\n * Cortex(tm)-M4 Technical Reference Manual                      ARM DDI 0439B\n * CoreSight(tm) SoC-400 Technical Reference Manual              ARM DDI 0480F\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <jim.h>\n\n#include <helper/bits.h>\n#include <helper/command.h>\n#include <helper/jim-nvp.h>\n#include <helper/list.h>\n#include <helper/log.h>\n#include <helper/types.h>\n#include <jtag/interface.h>\n#include <server/server.h>\n#include <target/arm_adi_v5.h>\n#include <target/target.h>\n#include <transport/transport.h>\n#include \"arm_tpiu_swo.h\"\n\n/* START_DEPRECATED_TPIU */\n#include <target/cortex_m.h>\n#include <target/target_type.h>\n#define MSG \"DEPRECATED \\'tpiu config\\' command: \"\n/* END_DEPRECATED_TPIU */\n\n#define TCP_SERVICE_NAME                \"tpiu_swo_trace\"\n\n/* default for Cortex-M3 and Cortex-M4 specific TPIU */\n#define TPIU_SWO_DEFAULT_BASE           0xE0040000\n\n#define TPIU_SSPSR_OFFSET               0x000\n#define TPIU_CSPSR_OFFSET               0x004\n#define TPIU_ACPR_OFFSET                0x010\n#define TPIU_SPPR_OFFSET                0x0F0\n#define TPIU_FFSR_OFFSET                0x300\n#define TPIU_FFCR_OFFSET                0x304\n#define TPIU_FSCR_OFFSET                0x308\n#define TPIU_DEVID_OFFSET               0xfc8\n\n#define TPIU_ACPR_MAX_PRESCALER         0x1fff\n#define TPIU_SPPR_PROTOCOL_SYNC         (TPIU_PIN_PROTOCOL_SYNC)\n#define TPIU_SPPR_PROTOCOL_MANCHESTER   (TPIU_PIN_PROTOCOL_ASYNC_MANCHESTER)\n#define TPIU_SPPR_PROTOCOL_UART         (TPIU_PIN_PROTOCOL_ASYNC_UART)\n#define TPIU_DEVID_NOSUPPORT_SYNC       BIT(9)\n#define TPIU_DEVID_SUPPORT_MANCHESTER   BIT(10)\n#define TPIU_DEVID_SUPPORT_UART         BIT(11)\n\nenum arm_tpiu_swo_event {\n\tTPIU_SWO_EVENT_PRE_ENABLE,\n\tTPIU_SWO_EVENT_POST_ENABLE,\n\tTPIU_SWO_EVENT_PRE_DISABLE,\n\tTPIU_SWO_EVENT_POST_DISABLE,\n};\n\nstatic const struct jim_nvp nvp_arm_tpiu_swo_event[] = {\n\t{ .value = TPIU_SWO_EVENT_PRE_ENABLE,   .name = \"pre-enable\" },\n\t{ .value = TPIU_SWO_EVENT_POST_ENABLE,  .name = \"post-enable\" },\n\t{ .value = TPIU_SWO_EVENT_PRE_DISABLE,  .name = \"pre-disable\" },\n\t{ .value = TPIU_SWO_EVENT_POST_DISABLE, .name = \"post-disable\" },\n};\n\nstruct arm_tpiu_swo_event_action {\n\tenum arm_tpiu_swo_event event;\n\tJim_Interp *interp;\n\tJim_Obj *body;\n\tstruct arm_tpiu_swo_event_action *next;\n};\n\nstruct arm_tpiu_swo_object {\n\tstruct list_head lh;\n\tstruct adiv5_mem_ap_spot spot;\n\tstruct adiv5_ap *ap;\n\tchar *name;\n\tstruct arm_tpiu_swo_event_action *event_action;\n\t/* record enable before init */\n\tbool deferred_enable;\n\tbool enabled;\n\tbool en_capture;\n\t/** Handle to output trace data in INTERNAL capture mode */\n\t/** Synchronous output port width */\n\tuint32_t port_width;\n\tFILE *file;\n\t/** output mode */\n\tunsigned int pin_protocol;\n\t/** Enable formatter */\n\tbool en_formatter;\n\t/** frequency of TRACECLKIN (usually matches HCLK) */\n\tunsigned int traceclkin_freq;\n\t/** SWO pin frequency */\n\tunsigned int swo_pin_freq;\n\t/** where to dump the captured output trace data */\n\tchar *out_filename;\n\t/** track TCP connections */\n\tstruct list_head connections;\n\t/* START_DEPRECATED_TPIU */\n\tbool recheck_ap_cur_target;\n\t/* END_DEPRECATED_TPIU */\n};\n\nstruct arm_tpiu_swo_connection {\n\tstruct list_head lh;\n\tstruct connection *connection;\n};\n\nstruct arm_tpiu_swo_priv_connection {\n\tstruct arm_tpiu_swo_object *obj;\n};\n\nstatic LIST_HEAD(all_tpiu_swo);\n\n#define ARM_TPIU_SWO_TRACE_BUF_SIZE\t4096\n\nstatic int arm_tpiu_swo_poll_trace(void *priv)\n{\n\tstruct arm_tpiu_swo_object *obj = priv;\n\tuint8_t buf[ARM_TPIU_SWO_TRACE_BUF_SIZE];\n\tsize_t size = sizeof(buf);\n\tstruct arm_tpiu_swo_connection *c;\n\n\tint retval = adapter_poll_trace(buf, &size);\n\tif (retval != ERROR_OK || !size)\n\t\treturn retval;\n\n\ttarget_call_trace_callbacks(/*target*/NULL, size, buf);\n\n\tif (obj->file) {\n\t\tif (fwrite(buf, 1, size, obj->file) == size) {\n\t\t\tfflush(obj->file);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Error writing to the SWO trace destination file\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (obj->out_filename && obj->out_filename[0] == ':')\n\t\tlist_for_each_entry(c, &obj->connections, lh)\n\t\t\tif (connection_write(c->connection, buf, size) != (int)size)\n\t\t\t\tLOG_ERROR(\"Error writing to connection\"); /* FIXME: which connection? */\n\n\treturn ERROR_OK;\n}\n\nstatic void arm_tpiu_swo_handle_event(struct arm_tpiu_swo_object *obj, enum arm_tpiu_swo_event event)\n{\n\tfor (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {\n\t\tif (ea->event != event)\n\t\t\tcontinue;\n\n\t\tLOG_DEBUG(\"TPIU/SWO: %s event: %s (%d) action : %s\",\n\t\t\tobj->name,\n\t\t\tjim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,\n\t\t\tevent,\n\t\t\tJim_GetString(ea->body, NULL));\n\n\t\t/* prevent event execution to change current target */\n\t\tstruct command_context *cmd_ctx = current_command_context(ea->interp);\n\t\tstruct target *saved_target = cmd_ctx->current_target;\n\t\tint retval = Jim_EvalObj(ea->interp, ea->body);\n\t\tcmd_ctx->current_target = saved_target;\n\n\t\tif (retval == JIM_RETURN)\n\t\t\tretval = ea->interp->returnCode;\n\t\tif (retval == JIM_OK || retval == ERROR_COMMAND_CLOSE_CONNECTION)\n\t\t\treturn;\n\n\t\tJim_MakeErrorMessage(ea->interp);\n\t\tLOG_USER(\"Error executing event %s on TPIU/SWO %s:\\n%s\",\n\t\t\tjim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, event)->name,\n\t\t\tobj->name,\n\t\t\tJim_GetString(Jim_GetResult(ea->interp), NULL));\n\t\t/* clean both error code and stacktrace before return */\n\t\tJim_Eval(ea->interp, \"error \\\"\\\" \\\"\\\"\");\n\t\treturn;\n\t}\n}\n\nstatic void arm_tpiu_swo_close_output(struct arm_tpiu_swo_object *obj)\n{\n\tif (obj->file) {\n\t\tfclose(obj->file);\n\t\tobj->file = NULL;\n\t}\n\tif (obj->out_filename && obj->out_filename[0] == ':')\n\t\tremove_service(TCP_SERVICE_NAME, &obj->out_filename[1]);\n}\n\nint arm_tpiu_swo_cleanup_all(void)\n{\n\tstruct arm_tpiu_swo_object *obj, *tmp;\n\n\tlist_for_each_entry_safe(obj, tmp, &all_tpiu_swo, lh) {\n\t\tif (obj->enabled)\n\t\t\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE);\n\n\t\tarm_tpiu_swo_close_output(obj);\n\n\t\tif (obj->en_capture) {\n\t\t\ttarget_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);\n\n\t\t\tint retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"Failed to stop adapter's trace\");\n\t\t}\n\n\t\tif (obj->enabled)\n\t\t\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);\n\n\t\tstruct arm_tpiu_swo_event_action *ea = obj->event_action;\n\t\twhile (ea) {\n\t\t\tstruct arm_tpiu_swo_event_action *next = ea->next;\n\t\t\tJim_DecrRefCount(ea->interp, ea->body);\n\t\t\tfree(ea);\n\t\t\tea = next;\n\t\t}\n\n\t\tif (obj->ap)\n\t\t\tdap_put_ap(obj->ap);\n\n\t\tfree(obj->name);\n\t\tfree(obj->out_filename);\n\t\tfree(obj);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm_tpiu_swo_service_new_connection(struct connection *connection)\n{\n\tstruct arm_tpiu_swo_priv_connection *priv = connection->service->priv;\n\tstruct arm_tpiu_swo_object *obj = priv->obj;\n\tstruct arm_tpiu_swo_connection *c = malloc(sizeof(*c));\n\tif (!c) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tc->connection = connection;\n\tlist_add(&c->lh, &obj->connections);\n\treturn ERROR_OK;\n}\n\nstatic int arm_tpiu_swo_service_input(struct connection *connection)\n{\n\t/* read a dummy buffer to check if the connection is still active */\n\tlong dummy;\n\tint bytes_read = connection_read(connection, &dummy, sizeof(dummy));\n\n\tif (bytes_read == 0) {\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t} else if (bytes_read == -1) {\n\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int arm_tpiu_swo_service_connection_closed(struct connection *connection)\n{\n\tstruct arm_tpiu_swo_priv_connection *priv = connection->service->priv;\n\tstruct arm_tpiu_swo_object *obj = priv->obj;\n\tstruct arm_tpiu_swo_connection *c, *tmp;\n\n\tlist_for_each_entry_safe(c, tmp, &obj->connections, lh)\n\t\tif (c->connection == connection) {\n\t\t\tlist_del(&c->lh);\n\t\t\tfree(c);\n\t\t\treturn ERROR_OK;\n\t\t}\n\tLOG_ERROR(\"Failed to find connection to close!\");\n\treturn ERROR_FAIL;\n}\n\nCOMMAND_HANDLER(handle_arm_tpiu_swo_event_list)\n{\n\tstruct arm_tpiu_swo_object *obj = CMD_DATA;\n\n\tcommand_print(CMD, \"Event actions for TPIU/SWO %s\\n\", obj->name);\n\tcommand_print(CMD, \"%-25s | Body\", \"Event\");\n\tcommand_print(CMD, \"------------------------- | \"\n\t\t\t\"----------------------------------------\");\n\n\tfor (struct arm_tpiu_swo_event_action *ea = obj->event_action; ea; ea = ea->next) {\n\t\tstruct jim_nvp *opt = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_event, ea->event);\n\t\tcommand_print(CMD, \"%-25s | %s\",\n\t\t\t\topt->name, Jim_GetString(ea->body, NULL));\n\t}\n\tcommand_print(CMD, \"***END***\");\n\treturn ERROR_OK;\n}\n\nenum arm_tpiu_swo_cfg_param {\n\tCFG_PORT_WIDTH,\n\tCFG_PROTOCOL,\n\tCFG_FORMATTER,\n\tCFG_TRACECLKIN,\n\tCFG_BITRATE,\n\tCFG_OUTFILE,\n\tCFG_EVENT,\n};\n\nstatic const struct jim_nvp nvp_arm_tpiu_swo_config_opts[] = {\n\t{ .name = \"-port-width\",    .value = CFG_PORT_WIDTH },\n\t{ .name = \"-protocol\",      .value = CFG_PROTOCOL },\n\t{ .name = \"-formatter\",     .value = CFG_FORMATTER },\n\t{ .name = \"-traceclk\",      .value = CFG_TRACECLKIN },\n\t{ .name = \"-pin-freq\",      .value = CFG_BITRATE },\n\t{ .name = \"-output\",        .value = CFG_OUTFILE },\n\t{ .name = \"-event\",         .value = CFG_EVENT },\n\t/* handled by mem_ap_spot, added for jim_getopt_nvp_unknown() */\n\t{ .name = \"-dap\",           .value = -1 },\n\t{ .name = \"-ap-num\",        .value = -1 },\n\t{ .name = \"-baseaddr\",      .value = -1 },\n\t{ .name = NULL,             .value = -1 },\n};\n\nstatic const struct jim_nvp nvp_arm_tpiu_swo_protocol_opts[] = {\n\t{ .name = \"sync\",           .value = TPIU_SPPR_PROTOCOL_SYNC },\n\t{ .name = \"uart\",           .value = TPIU_SPPR_PROTOCOL_UART },\n\t{ .name = \"manchester\",     .value = TPIU_SPPR_PROTOCOL_MANCHESTER },\n\t{ .name = NULL,             .value = -1 },\n};\n\nstatic const struct jim_nvp nvp_arm_tpiu_swo_bool_opts[] = {\n\t{ .name = \"on\",             .value = 1 },\n\t{ .name = \"yes\",            .value = 1 },\n\t{ .name = \"1\",              .value = 1 },\n\t{ .name = \"true\",           .value = 1 },\n\t{ .name = \"off\",            .value = 0 },\n\t{ .name = \"no\",             .value = 0 },\n\t{ .name = \"0\",              .value = 0 },\n\t{ .name = \"false\",          .value = 0 },\n\t{ .name = NULL,             .value = -1 },\n};\n\nstatic int arm_tpiu_swo_configure(struct jim_getopt_info *goi, struct arm_tpiu_swo_object *obj)\n{\n\tassert(obj);\n\n\tif (goi->isconfigure && obj->enabled) {\n\t\tJim_SetResultFormatted(goi->interp, \"Cannot configure TPIU/SWO; %s is enabled!\", obj->name);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* parse config or cget options ... */\n\twhile (goi->argc > 0) {\n\t\tJim_SetEmptyResult(goi->interp);\n\n\t\tint e = adiv5_jim_mem_ap_spot_configure(&obj->spot, goi);\n\t\tif (e == JIM_OK)\n\t\t\tcontinue;\n\t\tif (e == JIM_ERR)\n\t\t\treturn e;\n\n\t\tstruct jim_nvp *n;\n\t\te = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_config_opts, &n);\n\t\tif (e != JIM_OK) {\n\t\t\tjim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_config_opts, 0);\n\t\t\treturn e;\n\t\t}\n\n\t\tswitch (n->value) {\n\t\tcase CFG_PORT_WIDTH:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tjim_wide port_width;\n\t\t\t\te = jim_getopt_wide(goi, &port_width);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tif (port_width < 1 || port_width > 32) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"Invalid port width!\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t\tobj->port_width = (uint32_t)port_width;\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->port_width));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_PROTOCOL:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tstruct jim_nvp *p;\n\t\t\t\te = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_protocol_opts, &p);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tobj->pin_protocol = p->value;\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tstruct jim_nvp *p;\n\t\t\t\te = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);\n\t\t\t\tif (e != JIM_OK) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"protocol error\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, p->name, -1));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_FORMATTER:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tstruct jim_nvp *p;\n\t\t\t\te = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_bool_opts, &p);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tobj->en_formatter = p->value;\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tstruct jim_nvp *p;\n\t\t\t\te = jim_nvp_value2name(goi->interp, nvp_arm_tpiu_swo_bool_opts, obj->en_formatter, &p);\n\t\t\t\tif (e != JIM_OK) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"formatter error\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, p->name, -1));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_TRACECLKIN:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tjim_wide clk;\n\t\t\t\te = jim_getopt_wide(goi, &clk);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tobj->traceclkin_freq = clk;\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->traceclkin_freq));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_BITRATE:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tjim_wide clk;\n\t\t\t\te = jim_getopt_wide(goi, &clk);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tobj->swo_pin_freq = clk;\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, obj->swo_pin_freq));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_OUTFILE:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tconst char *s;\n\t\t\t\te = jim_getopt_string(goi, &s, NULL);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tif (s[0] == ':') {\n\t\t\t\t\tchar *end;\n\t\t\t\t\tlong port = strtol(s + 1, &end, 0);\n\t\t\t\t\tif (port <= 0 || port > UINT16_MAX || *end != '\\0') {\n\t\t\t\t\t\tJim_SetResultFormatted(goi->interp, \"Invalid TCP port \\'%s\\'\", s + 1);\n\t\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfree(obj->out_filename);\n\t\t\t\tobj->out_filename = strdup(s);\n\t\t\t\tif (!obj->out_filename) {\n\t\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (goi->argc)\n\t\t\t\t\tgoto err_no_params;\n\t\t\t\tif (obj->out_filename)\n\t\t\t\t\tJim_SetResult(goi->interp, Jim_NewStringObj(goi->interp, obj->out_filename, -1));\n\t\t\t}\n\t\t\tbreak;\n\t\tcase CFG_EVENT:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tif (goi->argc < 2) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event ?event-name? ?EVENT-BODY?\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 1) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event ?event-name?\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tstruct jim_nvp *p;\n\t\t\t\tJim_Obj *o;\n\t\t\t\tstruct arm_tpiu_swo_event_action *ea = obj->event_action;\n\n\t\t\t\te = jim_getopt_nvp(goi, nvp_arm_tpiu_swo_event, &p);\n\t\t\t\tif (e != JIM_OK) {\n\t\t\t\t\tjim_getopt_nvp_unknown(goi, nvp_arm_tpiu_swo_event, 1);\n\t\t\t\t\treturn e;\n\t\t\t\t}\n\n\t\t\t\twhile (ea) {\n\t\t\t\t\t/* replace existing? */\n\t\t\t\t\tif (ea->event == (enum arm_tpiu_swo_event)p->value)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tea = ea->next;\n\t\t\t\t}\n\n\t\t\t\tif (goi->isconfigure) {\n\t\t\t\t\tif (!ea) {\n\t\t\t\t\t\tea = calloc(1, sizeof(*ea));\n\t\t\t\t\t\tif (!ea) {\n\t\t\t\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tea->next = obj->event_action;\n\t\t\t\t\t\tobj->event_action = ea;\n\t\t\t\t\t}\n\t\t\t\t\tif (ea->body)\n\t\t\t\t\t\tJim_DecrRefCount(ea->interp, ea->body);\n\t\t\t\t\tea->event = p->value;\n\t\t\t\t\tea->interp = goi->interp;\n\t\t\t\t\tjim_getopt_obj(goi, &o);\n\t\t\t\t\tea->body = Jim_DuplicateObj(goi->interp, o);\n\t\t\t\t\tJim_IncrRefCount(ea->body);\n\t\t\t\t} else {\n\t\t\t\t\tif (ea)\n\t\t\t\t\t\tJim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, ea->body));\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn JIM_OK;\n\nerr_no_params:\n\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"NO PARAMS\");\n\treturn JIM_ERR;\n}\n\nstatic int jim_arm_tpiu_swo_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)\n{\n\tstruct command *c = jim_to_command(interp);\n\tstruct jim_getopt_info goi;\n\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tgoi.isconfigure = !strcmp(c->name, \"configure\");\n\tif (goi.argc < 1) {\n\t\tJim_WrongNumArgs(goi.interp, goi.argc, goi.argv,\n\t\t\t\"missing: -option ...\");\n\t\treturn JIM_ERR;\n\t}\n\tstruct arm_tpiu_swo_object *obj = c->jim_handler_data;\n\treturn arm_tpiu_swo_configure(&goi, obj);\n}\n\nstatic int wrap_write_u32(struct target *target, struct adiv5_ap *tpiu_ap,\n\t\ttarget_addr_t address, uint32_t value)\n{\n\tif (transport_is_hla())\n\t\treturn target_write_u32(target, address, value);\n\telse\n\t\treturn mem_ap_write_atomic_u32(tpiu_ap, address, value);\n}\n\nstatic int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,\n\t\ttarget_addr_t address, uint32_t *value)\n{\n\tif (transport_is_hla())\n\t\treturn target_read_u32(target, address, value);\n\telse\n\t\treturn mem_ap_read_atomic_u32(tpiu_ap, address, value);\n}\n\nstatic const struct service_driver arm_tpiu_swo_service_driver = {\n\t.name = \"tpiu_swo_trace\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = arm_tpiu_swo_service_new_connection,\n\t.input_handler = arm_tpiu_swo_service_input,\n\t.connection_closed_handler = arm_tpiu_swo_service_connection_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nCOMMAND_HANDLER(handle_arm_tpiu_swo_enable)\n{\n\tstruct arm_tpiu_swo_object *obj = CMD_DATA;\n\tuint32_t value;\n\tint retval;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_CTX->mode == COMMAND_CONFIG) {\n\t\tLOG_DEBUG(\"%s: enable deferred\", obj->name);\n\t\tobj->deferred_enable = true;\n\t\treturn ERROR_OK;\n\t}\n\n\tif (obj->enabled)\n\t\treturn ERROR_OK;\n\n\tif (transport_is_hla() && obj->spot.ap_num != 0) {\n\t\tcommand_print(CMD,\n\t\t\t\"Invalid access port 0x%\" PRIx64 \". Only AP#0 allowed with hla transport\",\n\t\t\tobj->spot.ap_num);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!obj->traceclkin_freq) {\n\t\tcommand_print(CMD, \"Trace clock-in frequency not set\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)\n\t\tif (!obj->swo_pin_freq)\n\t\t\tLOG_DEBUG(\"SWO pin frequency not set, will be autodetected by the adapter\");\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\t/* START_DEPRECATED_TPIU */\n\tif (obj->recheck_ap_cur_target) {\n\t\tif (strcmp(target->type->name, \"cortex_m\") &&\n\t\t\tstrcmp(target->type->name, \"hla_target\")) {\n\t\t\tLOG_ERROR(MSG \"Current target is not a Cortex-M nor a HLA\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (!target_was_examined(target)) {\n\t\t\tLOG_ERROR(MSG \"Current target not examined yet\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tstruct cortex_m_common *cm = target_to_cm(target);\n\t\tobj->recheck_ap_cur_target = false;\n\t\tobj->spot.ap_num = cm->armv7m.debug_ap->ap_num;\n\t\tif (obj->spot.ap_num == 0)\n\t\t\tLOG_INFO(MSG \"Confirmed TPIU %s is on AP 0\", obj->name);\n\t\telse\n\t\t\tLOG_INFO(MSG \"Target %s is on AP#0x%\" PRIx64 \". Revised command is \"\n\t\t\t\t\"\\'tpiu create %s -dap %s -ap-num 0x%\" PRIx64 \"\\'\",\n\t\t\t\ttarget_name(target), obj->spot.ap_num,\n\t\t\t\tobj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num);\n\t}\n\t/* END_DEPRECATED_TPIU */\n\n\tif (!obj->ap) {\n\t\tobj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);\n\t\tif (!obj->ap) {\n\t\t\tcommand_print(CMD, \"Cannot get AP\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* trigger the event before any attempt to R/W in the TPIU/SWO */\n\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);\n\n\tretval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD, \"Unable to read %s\", obj->name);\n\t\treturn retval;\n\t}\n\tswitch (obj->pin_protocol) {\n\tcase TPIU_SPPR_PROTOCOL_SYNC:\n\t\tvalue = !(value & TPIU_DEVID_NOSUPPORT_SYNC);\n\t\tbreak;\n\tcase TPIU_SPPR_PROTOCOL_UART:\n\t\tvalue &= TPIU_DEVID_SUPPORT_UART;\n\t\tbreak;\n\tcase TPIU_SPPR_PROTOCOL_MANCHESTER:\n\t\tvalue &= TPIU_DEVID_SUPPORT_MANCHESTER;\n\t\tbreak;\n\tdefault:\n\t\tvalue = 0;\n\t}\n\tif (!value) {\n\t\tstruct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol);\n\t\tcommand_print(CMD, \"%s does not support protocol %s\", obj->name, p->name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {\n\t\tretval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"Cannot read TPIU register SSPSR\");\n\t\t\treturn retval;\n\t\t}\n\t\tif (!(value & BIT(obj->port_width - 1))) {\n\t\t\tcommand_print(CMD, \"TPIU does not support port-width of %d bits\", obj->port_width);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tuint16_t prescaler = 1; /* dummy value */\n\tunsigned int swo_pin_freq = obj->swo_pin_freq; /* could be replaced */\n\n\tif (obj->out_filename && strcmp(obj->out_filename, \"external\") && obj->out_filename[0]) {\n\t\tif (obj->out_filename[0] == ':') {\n\t\t\tstruct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv));\n\t\t\tif (!priv) {\n\t\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tpriv->obj = obj;\n\t\t\tLOG_INFO(\"starting trace server for %s on %s\", obj->name, &obj->out_filename[1]);\n\t\t\tretval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],\n\t\t\t\tCONNECTION_LIMIT_UNLIMITED, priv);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD, \"Can't configure trace TCP port %s\", &obj->out_filename[1]);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else if (strcmp(obj->out_filename, \"-\")) {\n\t\t\tobj->file = fopen(obj->out_filename, \"ab\");\n\t\t\tif (!obj->file) {\n\t\t\t\tcommand_print(CMD, \"Can't open trace destination file \\\"%s\\\"\", obj->out_filename);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tretval = adapter_config_trace(true, obj->pin_protocol, obj->port_width,\n\t\t\t&swo_pin_freq, obj->traceclkin_freq, &prescaler);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"Failed to start adapter's trace\");\n\t\t\tarm_tpiu_swo_close_output(obj);\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)\n\t\t\tif (!swo_pin_freq) {\n\t\t\t\tif (obj->swo_pin_freq)\n\t\t\t\t\tcommand_print(CMD, \"Adapter rejected SWO pin frequency %d Hz\", obj->swo_pin_freq);\n\t\t\t\telse\n\t\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"Adapter does not support auto-detection of SWO pin frequency nor a default value\");\n\n\t\t\t\tarm_tpiu_swo_close_output(obj);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\tif (obj->swo_pin_freq != swo_pin_freq)\n\t\t\tLOG_INFO(\"SWO pin data rate adjusted by adapter to %d Hz\", swo_pin_freq);\n\t\tobj->swo_pin_freq = swo_pin_freq;\n\n\t\ttarget_register_timer_callback(arm_tpiu_swo_poll_trace, 1,\n\t\t\tTARGET_TIMER_TYPE_PERIODIC, obj);\n\n\t\tobj->en_capture = true;\n\t} else if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART) {\n\t\tprescaler = (obj->traceclkin_freq + obj->swo_pin_freq / 2) / obj->swo_pin_freq;\n\t\tif (prescaler > TPIU_ACPR_MAX_PRESCALER)\n\t\t\tprescaler = TPIU_ACPR_MAX_PRESCALER;\n\t\tswo_pin_freq = obj->traceclkin_freq / prescaler;\n\n\t\tif (obj->swo_pin_freq != swo_pin_freq)\n\t\t\tLOG_INFO(\"SWO pin data rate adjusted to %d Hz\", swo_pin_freq);\n\t\tobj->swo_pin_freq = swo_pin_freq;\n\t}\n\n\tretval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));\n\tif (retval != ERROR_OK)\n\t\tgoto error_exit;\n\n\tretval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);\n\tif (retval != ERROR_OK)\n\t\tgoto error_exit;\n\n\tretval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);\n\tif (retval != ERROR_OK)\n\t\tgoto error_exit;\n\n\tretval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);\n\tif (retval != ERROR_OK)\n\t\tgoto error_exit;\n\tif (obj->en_formatter)\n\t\tvalue |= BIT(1);\n\telse\n\t\tvalue &= ~BIT(1);\n\tretval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value);\n\tif (retval != ERROR_OK)\n\t\tgoto error_exit;\n\n\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_ENABLE);\n\n\t/* START_DEPRECATED_TPIU */\n\ttarget_handle_event(target, TARGET_EVENT_TRACE_CONFIG);\n\t/* END_DEPRECATED_TPIU */\n\n\tobj->enabled = true;\n\treturn ERROR_OK;\n\nerror_exit:\n\tcommand_print(CMD, \"Error!\");\n\n\tif (obj->en_capture) {\n\t\tobj->en_capture = false;\n\n\t\tarm_tpiu_swo_close_output(obj);\n\n\t\ttarget_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);\n\n\t\tint retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL);\n\t\tif (retval1 != ERROR_OK)\n\t\t\tcommand_print(CMD, \"Failed to stop adapter's trace\");\n\t}\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_arm_tpiu_swo_disable)\n{\n\tstruct arm_tpiu_swo_object *obj = CMD_DATA;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!obj->enabled)\n\t\treturn ERROR_OK;\n\tobj->enabled = false;\n\n\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE);\n\n\tif (obj->en_capture) {\n\t\tobj->en_capture = false;\n\n\t\tarm_tpiu_swo_close_output(obj);\n\n\t\ttarget_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);\n\n\t\tint retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);\n\t\tif (retval != ERROR_OK) {\n\t\t\tcommand_print(CMD, \"Failed to stop adapter's trace\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tarm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);\n\n\t/* START_DEPRECATED_TPIU */\n\tstruct target *target = get_current_target(CMD_CTX);\n\ttarget_handle_event(target, TARGET_EVENT_TRACE_CONFIG);\n\t/* END_DEPRECATED_TPIU */\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm_tpiu_swo_instance_command_handlers[] = {\n\t{\n\t\t.name = \"configure\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_arm_tpiu_swo_configure,\n\t\t.help  = \"configure a new TPIU/SWO for use\",\n\t\t.usage = \"[attribute value ...]\",\n\t},\n\t{\n\t\t.name = \"cget\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_arm_tpiu_swo_configure,\n\t\t.help  = \"returns the specified TPIU/SWO attribute\",\n\t\t.usage = \"attribute\",\n\t},\n\t{\n\t\t.name = \"eventlist\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_arm_tpiu_swo_event_list,\n\t\t.help = \"displays a table of events defined for this TPIU/SWO\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"enable\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_arm_tpiu_swo_enable,\n\t\t.usage = \"\",\n\t\t.help = \"Enables the TPIU/SWO output\",\n\t},\n\t{\n\t\t.name = \"disable\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_arm_tpiu_swo_disable,\n\t\t.usage = \"\",\n\t\t.help = \"Disables the TPIU/SWO output\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int arm_tpiu_swo_create(Jim_Interp *interp, struct arm_tpiu_swo_object *obj)\n{\n\tstruct command_context *cmd_ctx;\n\tJim_Cmd *cmd;\n\tint e;\n\n\tcmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\n\t/* does this command exist? */\n\tcmd = Jim_GetCommand(interp, Jim_NewStringObj(interp, obj->name, -1), JIM_NONE);\n\tif (cmd) {\n\t\tJim_SetResultFormatted(interp, \"cannot create TPIU object because a command with name '%s' already exists\",\n\t\t\tobj->name);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* now - create the new tpiu/swo name command */\n\tconst struct command_registration obj_commands[] = {\n\t\t{\n\t\t\t.name = obj->name,\n\t\t\t.mode = COMMAND_ANY,\n\t\t\t.help = \"tpiu/swo instance command group\",\n\t\t\t.usage = \"\",\n\t\t\t.chain = arm_tpiu_swo_instance_command_handlers,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\te = register_commands_with_data(cmd_ctx, NULL, obj_commands, obj);\n\tif (e != ERROR_OK)\n\t\treturn JIM_ERR;\n\n\tlist_add_tail(&obj->lh, &all_tpiu_swo);\n\n\treturn JIM_OK;\n}\n\nstatic int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tif (goi.argc < 1) {\n\t\tJim_WrongNumArgs(interp, 1, argv, \"name ?option option ...?\");\n\t\treturn JIM_ERR;\n\t}\n\n\tstruct arm_tpiu_swo_object *obj = calloc(1, sizeof(struct arm_tpiu_swo_object));\n\tif (!obj) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn JIM_ERR;\n\t}\n\tINIT_LIST_HEAD(&obj->connections);\n\tadiv5_mem_ap_spot_init(&obj->spot);\n\tobj->spot.base = TPIU_SWO_DEFAULT_BASE;\n\tobj->port_width = 1;\n\n\tJim_Obj *n;\n\tjim_getopt_obj(&goi, &n);\n\tobj->name = strdup(Jim_GetString(n, NULL));\n\tif (!obj->name) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(obj);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Do the rest as \"configure\" options */\n\tgoi.isconfigure = 1;\n\tint e = arm_tpiu_swo_configure(&goi, obj);\n\tif (e != JIM_OK)\n\t\tgoto err_exit;\n\n\tif (!obj->spot.dap || obj->spot.ap_num == DP_APSEL_INVALID) {\n\t\tJim_SetResultString(goi.interp, \"-dap and -ap-num required when creating TPIU\", -1);\n\t\tgoto err_exit;\n\t}\n\n\te = arm_tpiu_swo_create(goi.interp, obj);\n\tif (e != JIM_OK)\n\t\tgoto err_exit;\n\n\treturn JIM_OK;\n\nerr_exit:\n\tfree(obj->name);\n\tfree(obj->out_filename);\n\tfree(obj);\n\treturn JIM_ERR;\n}\n\nCOMMAND_HANDLER(handle_arm_tpiu_swo_names)\n{\n\tstruct arm_tpiu_swo_object *obj;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(obj, &all_tpiu_swo, lh)\n\t\tcommand_print(CMD, \"%s\", obj->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_arm_tpiu_swo_init)\n{\n\tstruct arm_tpiu_swo_object *obj;\n\tint retval = ERROR_OK;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(obj, &all_tpiu_swo, lh) {\n\t\tif (!obj->deferred_enable)\n\t\t\tcontinue;\n\t\tLOG_DEBUG(\"%s: running enable during init\", obj->name);\n\t\tint retval2 = command_run_linef(CMD_CTX, \"%s enable\", obj->name);\n\t\tif (retval2 != ERROR_OK)\n\t\t\tretval = retval2;\n\t}\n\treturn retval;\n}\n\n/* START_DEPRECATED_TPIU */\n/* DEPRECATED: emulation of old command 'tpiu config' */\nCOMMAND_HANDLER(handle_tpiu_deprecated_config_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm_tpiu_swo_object *obj = NULL;\n\tint retval;\n\n\tif (strcmp(target->type->name, \"cortex_m\") &&\n\t\tstrcmp(target->type->name, \"hla_target\")) {\n\t\tLOG_ERROR(MSG \"Current target is not a Cortex-M nor a HLA\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!list_empty(&all_tpiu_swo)) {\n\t\tobj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);\n\t\tLOG_INFO(MSG \"Using %s\", obj->name);\n\t} else {\n\t\tstruct cortex_m_common *cm = target_to_cm(target);\n\t\tstruct adiv5_private_config *pc = target->private_config;\n\t\tstruct adiv5_dap *dap = pc->dap;\n\t\tuint64_t ap_num = pc->ap_num;\n\t\tbool set_recheck_ap_cur_target = false;\n\n\t\tLOG_INFO(MSG \"Adding a TPIU \\'%s.tpiu\\' in the configuration\", target_name(target));\n\n\t\tif (ap_num == DP_APSEL_INVALID && transport_is_hla())\n\t\t\tap_num = 0; /* HLA should only support AP 0 */\n\n\t\tif (ap_num == DP_APSEL_INVALID && target_was_examined(target))\n\t\t\tap_num = cm->armv7m.debug_ap->ap_num;\n\n\t\tif (ap_num == DP_APSEL_INVALID) {\n\t\t\tLOG_INFO(MSG \"Target %s uses AP autodetection. Adding TPIU on AP 0; can be revised later\",\n\t\t\t\ttarget_name(target));\n\t\t\tap_num = 0;\n\t\t\tset_recheck_ap_cur_target = true;\n\t\t}\n\n\t\tLOG_INFO(MSG \"Running: \\'tpiu create %s.tpiu -dap %s -ap-num 0x%\" PRIx64 \"\\'\",\n\t\t\ttarget_name(target), adiv5_dap_name(dap), ap_num);\n\n\t\tretval = command_run_linef(CMD_CTX, \"tpiu create %s.tpiu -dap %s -ap-num 0x%\" PRIx64,\n\t\t\ttarget_name(target), adiv5_dap_name(dap), ap_num);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tobj = list_first_entry(&all_tpiu_swo, typeof(*obj), lh);\n\t\tif (set_recheck_ap_cur_target)\n\t\t\tobj->recheck_ap_cur_target = true;\n\t}\n\n\tunsigned int cmd_idx = 0;\n\tif (cmd_idx == CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!strcmp(CMD_ARGV[cmd_idx], \"disable\")) {\n\t\tif (CMD_ARGC != cmd_idx + 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tLOG_INFO(MSG \"Running: \\'%s disable\\'\", obj->name);\n\t\treturn command_run_linef(CMD_CTX, \"%s disable\", obj->name);\n\t}\n\n\tconst char *output = NULL;\n\tconst char *protocol;\n\tconst char *formatter = NULL;\n\tconst char *port_width = NULL;\n\tconst char *trace_clk;\n\tconst char *pin_clk = NULL;\n\tif (!strcmp(CMD_ARGV[cmd_idx], \"internal\")) {\n\t\tcmd_idx++;\n\t\tif (cmd_idx == CMD_ARGC)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\toutput = CMD_ARGV[cmd_idx];\n\t} else if (strcmp(CMD_ARGV[cmd_idx], \"external\"))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tcmd_idx++;\n\tif (cmd_idx == CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (!strcmp(CMD_ARGV[cmd_idx], \"sync\")) {\n\t\tprotocol = CMD_ARGV[cmd_idx];\n\t\tcmd_idx++;\n\t\tif (cmd_idx == CMD_ARGC)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tport_width = CMD_ARGV[cmd_idx];\n\t} else {\n\t\tif (strcmp(CMD_ARGV[cmd_idx], \"manchester\") && strcmp(CMD_ARGV[cmd_idx], \"uart\"))\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tprotocol = CMD_ARGV[cmd_idx];\n\t\tcmd_idx++;\n\t\tif (cmd_idx == CMD_ARGC)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tformatter = CMD_ARGV[cmd_idx];\n\t}\n\tcmd_idx++;\n\tif (cmd_idx == CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\ttrace_clk = CMD_ARGV[cmd_idx];\n\tcmd_idx++;\n\tif (cmd_idx != CMD_ARGC) {\n\t\tpin_clk = CMD_ARGV[cmd_idx];\n\t\tcmd_idx++;\n\t}\n\tif (cmd_idx != CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_INFO(MSG \"Running: \\'%s configure -protocol %s -traceclk %s\" \"%s%s\" \"%s%s\" \"%s%s\" \"%s%s\\'\",\n\t\tobj->name, protocol, trace_clk,\n\t\tpin_clk    ? \" -pin-freq \"   : \"\", pin_clk    ? pin_clk    : \"\",\n\t\toutput     ? \" -output \"     : \"\", output     ? output     : \"\",\n\t\tformatter  ? \" -formatter \"  : \"\", formatter  ? formatter  : \"\",\n\t\tport_width ? \" -port-width \" : \"\", port_width ? port_width : \"\");\n\n\tretval = command_run_linef(CMD_CTX,\n\t\t\"%s configure -protocol %s -traceclk %s\" \"%s%s\" \"%s%s\" \"%s%s\" \"%s%s\",\n\t\tobj->name, protocol, trace_clk,\n\t\tpin_clk    ? \" -pin-freq \"   : \"\", pin_clk    ? pin_clk    : \"\",\n\t\toutput     ? \" -output \"     : \"\", output     ? output     : \"\",\n\t\tformatter  ? \" -formatter \"  : \"\", formatter  ? formatter  : \"\",\n\t\tport_width ? \" -port-width \" : \"\", port_width ? port_width : \"\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_INFO(MSG \"Running: \\'%s enable\\'\", obj->name);\n\tretval = command_run_linef(CMD_CTX, \"%s enable\", obj->name);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm_tpiu_deprecated_subcommand_handlers[] = {\n\t{\n\t\t.name = \"config\",\n\t\t.handler = handle_tpiu_deprecated_config_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Configure TPIU features, DEPRECATED, use \\'tpiu create\\'\",\n\t\t.usage = \"(disable | \"\n\t\t\"((external | internal (<filename> | <:port> | -)) \"\n\t\t\"(sync <port width> | ((manchester | uart) <formatter enable>)) \"\n\t\t\"<TRACECLKIN freq> [<trace freq>]))\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm_tpiu_deprecated_command_handlers[] = {\n\t{\n\t\t.name = \"tpiu\",\n\t\t.chain = arm_tpiu_deprecated_subcommand_handlers,\n\t\t.usage = \"\",\n\t\t.help = \"tpiu command group\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n/* END_DEPRECATED_TPIU */\n\nstatic const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {\n\t{\n\t\t.name = \"create\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_arm_tpiu_swo_create,\n\t\t.usage = \"name [-dap dap] [-ap-num num] [-baseaddr baseaddr]\",\n\t\t.help = \"Creates a new TPIU or SWO object\",\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_arm_tpiu_swo_names,\n\t\t.usage = \"\",\n\t\t.help = \"Lists all registered TPIU and SWO objects by name\",\n\t},\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_arm_tpiu_swo_init,\n\t\t.usage = \"\",\n\t\t.help = \"Initialize TPIU and SWO\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm_tpiu_swo_command_handlers[] = {\n\t{\n\t\t.name = \"tpiu\",\n\t\t.chain = arm_tpiu_swo_subcommand_handlers,\n\t\t.usage = \"\",\n\t\t.help = \"tpiu command group\",\n\t},\n\t{\n\t\t.name = \"swo\",\n\t\t.chain = arm_tpiu_swo_subcommand_handlers,\n\t\t.usage = \"\",\n\t\t.help = \"swo command group\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint arm_tpiu_swo_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, arm_tpiu_swo_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/arm_tpiu_swo.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_TARGET_ARM_TPIU_SWO_H\n#define OPENOCD_TARGET_ARM_TPIU_SWO_H\n\n/* Values should match TPIU_SPPR_PROTOCOL_xxx */\nenum tpiu_pin_protocol {\n\tTPIU_PIN_PROTOCOL_SYNC = 0,                 /**< synchronous trace output */\n\tTPIU_PIN_PROTOCOL_ASYNC_MANCHESTER = 1,     /**< asynchronous output with Manchester coding */\n\tTPIU_PIN_PROTOCOL_ASYNC_UART = 2,           /**< asynchronous output with NRZ coding */\n};\n\n/* START_DEPRECATED_TPIU */\n/* DEPRECATED: emulation of old command 'tpiu config' */\nextern const struct command_registration arm_tpiu_deprecated_command_handlers[];\n/* END_DEPRECATED_TPIU */\n\nint arm_tpiu_swo_register_commands(struct command_context *cmd_ctx);\nint arm_tpiu_swo_cleanup_all(void);\n\n#endif /* OPENOCD_TARGET_ARM_TPIU_SWO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by Oyvind Harboe                                   *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"armv4_5.h\"\n#include \"arm_jtag.h\"\n#include \"breakpoints.h\"\n#include \"arm_disassembler.h\"\n#include <helper/binarybuffer.h>\n#include \"algorithm.h\"\n#include \"register.h\"\n#include \"semihosting_common.h\"\n\n/* offsets into armv4_5 core register cache */\nenum {\n/*\tARMV4_5_CPSR = 31, */\n\tARMV4_5_SPSR_FIQ = 32,\n\tARMV4_5_SPSR_IRQ = 33,\n\tARMV4_5_SPSR_SVC = 34,\n\tARMV4_5_SPSR_ABT = 35,\n\tARMV4_5_SPSR_UND = 36,\n\tARM_SPSR_MON = 41,\n\tARM_SPSR_HYP = 43,\n};\n\nstatic const uint8_t arm_usr_indices[17] = {\n\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR,\n};\n\nstatic const uint8_t arm_fiq_indices[8] = {\n\t16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ,\n};\n\nstatic const uint8_t arm_irq_indices[3] = {\n\t23, 24, ARMV4_5_SPSR_IRQ,\n};\n\nstatic const uint8_t arm_svc_indices[3] = {\n\t25, 26, ARMV4_5_SPSR_SVC,\n};\n\nstatic const uint8_t arm_abt_indices[3] = {\n\t27, 28, ARMV4_5_SPSR_ABT,\n};\n\nstatic const uint8_t arm_und_indices[3] = {\n\t29, 30, ARMV4_5_SPSR_UND,\n};\n\nstatic const uint8_t arm_mon_indices[3] = {\n\t39, 40, ARM_SPSR_MON,\n};\n\nstatic const uint8_t arm_hyp_indices[2] = {\n\t42, ARM_SPSR_HYP,\n};\n\nstatic const struct {\n\tconst char *name;\n\tunsigned short psr;\n\t/* For user and system modes, these list indices for all registers.\n\t * otherwise they're just indices for the shadow registers and SPSR.\n\t */\n\tunsigned short n_indices;\n\tconst uint8_t *indices;\n} arm_mode_data[] = {\n\t/* Seven modes are standard from ARM7 on. \"System\" and \"User\" share\n\t * the same registers; other modes shadow from 3 to 8 registers.\n\t */\n\t{\n\t\t.name = \"User\",\n\t\t.psr = ARM_MODE_USR,\n\t\t.n_indices = ARRAY_SIZE(arm_usr_indices),\n\t\t.indices = arm_usr_indices,\n\t},\n\t{\n\t\t.name = \"FIQ\",\n\t\t.psr = ARM_MODE_FIQ,\n\t\t.n_indices = ARRAY_SIZE(arm_fiq_indices),\n\t\t.indices = arm_fiq_indices,\n\t},\n\t{\n\t\t.name = \"Supervisor\",\n\t\t.psr = ARM_MODE_SVC,\n\t\t.n_indices = ARRAY_SIZE(arm_svc_indices),\n\t\t.indices = arm_svc_indices,\n\t},\n\t{\n\t\t.name = \"Abort\",\n\t\t.psr = ARM_MODE_ABT,\n\t\t.n_indices = ARRAY_SIZE(arm_abt_indices),\n\t\t.indices = arm_abt_indices,\n\t},\n\t{\n\t\t.name = \"IRQ\",\n\t\t.psr = ARM_MODE_IRQ,\n\t\t.n_indices = ARRAY_SIZE(arm_irq_indices),\n\t\t.indices = arm_irq_indices,\n\t},\n\t{\n\t\t.name = \"Undefined instruction\",\n\t\t.psr = ARM_MODE_UND,\n\t\t.n_indices = ARRAY_SIZE(arm_und_indices),\n\t\t.indices = arm_und_indices,\n\t},\n\t{\n\t\t.name = \"System\",\n\t\t.psr = ARM_MODE_SYS,\n\t\t.n_indices = ARRAY_SIZE(arm_usr_indices),\n\t\t.indices = arm_usr_indices,\n\t},\n\t/* TrustZone \"Security Extensions\" add a secure monitor mode.\n\t * This is distinct from a \"debug monitor\" which can support\n\t * non-halting debug, in conjunction with some debuggers.\n\t */\n\t{\n\t\t.name = \"Secure Monitor\",\n\t\t.psr = ARM_MODE_MON,\n\t\t.n_indices = ARRAY_SIZE(arm_mon_indices),\n\t\t.indices = arm_mon_indices,\n\t},\n\t{\n\t\t.name = \"Secure Monitor ARM1176JZF-S\",\n\t\t.psr = ARM_MODE_1176_MON,\n\t\t.n_indices = ARRAY_SIZE(arm_mon_indices),\n\t\t.indices = arm_mon_indices,\n\t},\n\n\t/* These special modes are currently only supported\n\t * by ARMv6M and ARMv7M profiles */\n\t{\n\t\t.name = \"Thread\",\n\t\t.psr = ARM_MODE_THREAD,\n\t},\n\t{\n\t\t.name = \"Thread (User)\",\n\t\t.psr = ARM_MODE_USER_THREAD,\n\t},\n\t{\n\t\t.name = \"Handler\",\n\t\t.psr = ARM_MODE_HANDLER,\n\t},\n\n\t/* armv7-a with virtualization extension */\n\t{\n\t\t.name = \"Hypervisor\",\n\t\t.psr = ARM_MODE_HYP,\n\t\t.n_indices = ARRAY_SIZE(arm_hyp_indices),\n\t\t.indices = arm_hyp_indices,\n\t},\n};\n\n/** Map PSR mode bits to the name of an ARM processor operating mode. */\nconst char *arm_mode_name(unsigned psr_mode)\n{\n\tfor (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {\n\t\tif (arm_mode_data[i].psr == psr_mode)\n\t\t\treturn arm_mode_data[i].name;\n\t}\n\tLOG_ERROR(\"unrecognized psr mode: %#02x\", psr_mode);\n\treturn \"UNRECOGNIZED\";\n}\n\n/** Return true iff the parameter denotes a valid ARM processor mode. */\nbool is_arm_mode(unsigned psr_mode)\n{\n\tfor (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {\n\t\tif (arm_mode_data[i].psr == psr_mode)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\n/** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */\nint arm_mode_to_number(enum arm_mode mode)\n{\n\tswitch (mode) {\n\t\tcase ARM_MODE_ANY:\n\t\t/* map MODE_ANY to user mode */\n\t\tcase ARM_MODE_USR:\n\t\t\treturn 0;\n\t\tcase ARM_MODE_FIQ:\n\t\t\treturn 1;\n\t\tcase ARM_MODE_IRQ:\n\t\t\treturn 2;\n\t\tcase ARM_MODE_SVC:\n\t\t\treturn 3;\n\t\tcase ARM_MODE_ABT:\n\t\t\treturn 4;\n\t\tcase ARM_MODE_UND:\n\t\t\treturn 5;\n\t\tcase ARM_MODE_SYS:\n\t\t\treturn 6;\n\t\tcase ARM_MODE_MON:\n\t\tcase ARM_MODE_1176_MON:\n\t\t\treturn 7;\n\t\tcase ARM_MODE_HYP:\n\t\t\treturn 8;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"invalid mode value encountered %d\", mode);\n\t\t\treturn -1;\n\t}\n}\n\n/** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */\nenum arm_mode armv4_5_number_to_mode(int number)\n{\n\tswitch (number) {\n\t\tcase 0:\n\t\t\treturn ARM_MODE_USR;\n\t\tcase 1:\n\t\t\treturn ARM_MODE_FIQ;\n\t\tcase 2:\n\t\t\treturn ARM_MODE_IRQ;\n\t\tcase 3:\n\t\t\treturn ARM_MODE_SVC;\n\t\tcase 4:\n\t\t\treturn ARM_MODE_ABT;\n\t\tcase 5:\n\t\t\treturn ARM_MODE_UND;\n\t\tcase 6:\n\t\t\treturn ARM_MODE_SYS;\n\t\tcase 7:\n\t\t\treturn ARM_MODE_MON;\n\t\tcase 8:\n\t\t\treturn ARM_MODE_HYP;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"mode index out of bounds %d\", number);\n\t\t\treturn ARM_MODE_ANY;\n\t}\n}\n\nstatic const char *arm_state_strings[] = {\n\t\"ARM\", \"Thumb\", \"Jazelle\", \"ThumbEE\",\n};\n\n/* Templates for ARM core registers.\n *\n * NOTE:  offsets in this table are coupled to the arm_mode_data\n * table above, the armv4_5_core_reg_map array below, and also to\n * the ARMV4_5_CPSR symbol (which should vanish after ARM11 updates).\n */\nstatic const struct {\n\t/* The name is used for e.g. the \"regs\" command. */\n\tconst char *name;\n\n\t/* The {cookie, mode} tuple uniquely identifies one register.\n\t * In a given mode, cookies 0..15 map to registers R0..R15,\n\t * with R13..R15 usually called SP, LR, PC.\n\t *\n\t * MODE_ANY is used as *input* to the mapping, and indicates\n\t * various special cases (sigh) and errors.\n\t *\n\t * Cookie 16 is (currently) confusing, since it indicates\n\t * CPSR -or- SPSR depending on whether 'mode' is MODE_ANY.\n\t * (Exception modes have both CPSR and SPSR registers ...)\n\t */\n\tunsigned cookie;\n\tunsigned gdb_index;\n\tenum arm_mode mode;\n} arm_core_regs[] = {\n\t/* IMPORTANT:  we guarantee that the first eight cached registers\n\t * correspond to r0..r7, and the fifteenth to PC, so that callers\n\t * don't need to map them.\n\t */\n\t[0] = { .name = \"r0\", .cookie = 0, .mode = ARM_MODE_ANY, .gdb_index = 0, },\n\t[1] = { .name = \"r1\", .cookie = 1, .mode = ARM_MODE_ANY, .gdb_index = 1, },\n\t[2] = { .name = \"r2\", .cookie = 2, .mode = ARM_MODE_ANY, .gdb_index = 2, },\n\t[3] = { .name = \"r3\", .cookie = 3, .mode = ARM_MODE_ANY, .gdb_index = 3, },\n\t[4] = { .name = \"r4\", .cookie = 4, .mode = ARM_MODE_ANY, .gdb_index = 4, },\n\t[5] = { .name = \"r5\", .cookie = 5, .mode = ARM_MODE_ANY, .gdb_index = 5, },\n\t[6] = { .name = \"r6\", .cookie = 6, .mode = ARM_MODE_ANY, .gdb_index = 6, },\n\t[7] = { .name = \"r7\", .cookie = 7, .mode = ARM_MODE_ANY, .gdb_index = 7, },\n\n\t/* NOTE: regs 8..12 might be shadowed by FIQ ... flagging\n\t * them as MODE_ANY creates special cases.  (ANY means\n\t * \"not mapped\" elsewhere; here it's \"everything but FIQ\".)\n\t */\n\t[8] = { .name = \"r8\", .cookie = 8, .mode = ARM_MODE_ANY, .gdb_index = 8, },\n\t[9] = { .name = \"r9\", .cookie = 9, .mode = ARM_MODE_ANY, .gdb_index = 9, },\n\t[10] = { .name = \"r10\", .cookie = 10, .mode = ARM_MODE_ANY, .gdb_index = 10, },\n\t[11] = { .name = \"r11\", .cookie = 11, .mode = ARM_MODE_ANY, .gdb_index = 11, },\n\t[12] = { .name = \"r12\", .cookie = 12, .mode = ARM_MODE_ANY, .gdb_index = 12, },\n\n\t/* Historical GDB mapping of indices:\n\t *  - 13-14 are sp and lr, but banked counterparts are used\n\t *  - 16-24 are left for deprecated 8 FPA + 1 FPS\n\t *  - 25 is the cpsr\n\t */\n\n\t/* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */\n\t[13] = { .name = \"sp_usr\", .cookie = 13, .mode = ARM_MODE_USR, .gdb_index = 26, },\n\t[14] = { .name = \"lr_usr\", .cookie = 14, .mode = ARM_MODE_USR, .gdb_index = 27, },\n\n\t/* guaranteed to be at index 15 */\n\t[15] = { .name = \"pc\", .cookie = 15, .mode = ARM_MODE_ANY, .gdb_index = 15, },\n\t[16] = { .name = \"r8_fiq\", .cookie = 8, .mode = ARM_MODE_FIQ, .gdb_index = 28, },\n\t[17] = { .name = \"r9_fiq\", .cookie = 9, .mode = ARM_MODE_FIQ, .gdb_index = 29, },\n\t[18] = { .name = \"r10_fiq\", .cookie = 10, .mode = ARM_MODE_FIQ, .gdb_index = 30, },\n\t[19] = { .name = \"r11_fiq\", .cookie = 11, .mode = ARM_MODE_FIQ, .gdb_index = 31, },\n\t[20] = { .name = \"r12_fiq\", .cookie = 12, .mode = ARM_MODE_FIQ, .gdb_index = 32, },\n\n\t[21] = { .name = \"sp_fiq\", .cookie = 13, .mode = ARM_MODE_FIQ, .gdb_index = 33, },\n\t[22] = { .name = \"lr_fiq\", .cookie = 14, .mode = ARM_MODE_FIQ, .gdb_index = 34, },\n\n\t[23] = { .name = \"sp_irq\", .cookie = 13, .mode = ARM_MODE_IRQ, .gdb_index = 35, },\n\t[24] = { .name = \"lr_irq\", .cookie = 14, .mode = ARM_MODE_IRQ, .gdb_index = 36, },\n\n\t[25] = { .name = \"sp_svc\", .cookie = 13, .mode = ARM_MODE_SVC, .gdb_index = 37, },\n\t[26] = { .name = \"lr_svc\", .cookie = 14, .mode = ARM_MODE_SVC, .gdb_index = 38, },\n\n\t[27] = { .name = \"sp_abt\", .cookie = 13, .mode = ARM_MODE_ABT, .gdb_index = 39, },\n\t[28] = { .name = \"lr_abt\", .cookie = 14, .mode = ARM_MODE_ABT, .gdb_index = 40, },\n\n\t[29] = { .name = \"sp_und\", .cookie = 13, .mode = ARM_MODE_UND, .gdb_index = 41, },\n\t[30] = { .name = \"lr_und\", .cookie = 14, .mode = ARM_MODE_UND, .gdb_index = 42, },\n\n\t[31] = { .name = \"cpsr\", .cookie = 16, .mode = ARM_MODE_ANY, .gdb_index = 25, },\n\t[32] = { .name = \"spsr_fiq\", .cookie = 16, .mode = ARM_MODE_FIQ, .gdb_index = 43, },\n\t[33] = { .name = \"spsr_irq\", .cookie = 16, .mode = ARM_MODE_IRQ, .gdb_index = 44, },\n\t[34] = { .name = \"spsr_svc\", .cookie = 16, .mode = ARM_MODE_SVC, .gdb_index = 45, },\n\t[35] = { .name = \"spsr_abt\", .cookie = 16, .mode = ARM_MODE_ABT, .gdb_index = 46, },\n\t[36] = { .name = \"spsr_und\", .cookie = 16, .mode = ARM_MODE_UND, .gdb_index = 47, },\n\n\t/* These are only used for GDB target description, banked registers are accessed instead */\n\t[37] = { .name = \"sp\", .cookie = 13, .mode = ARM_MODE_ANY, .gdb_index = 13, },\n\t[38] = { .name = \"lr\", .cookie = 14, .mode = ARM_MODE_ANY, .gdb_index = 14, },\n\n\t/* These exist only when the Security Extension (TrustZone) is present */\n\t[39] = { .name = \"sp_mon\", .cookie = 13, .mode = ARM_MODE_MON, .gdb_index = 48, },\n\t[40] = { .name = \"lr_mon\", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, },\n\t[41] = { .name = \"spsr_mon\", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, },\n\n\t/* These exist only when the Virtualization Extensions is present */\n\t[42] = { .name = \"sp_hyp\", .cookie = 13, .mode = ARM_MODE_HYP, .gdb_index = 51, },\n\t[43] = { .name = \"spsr_hyp\", .cookie = 16, .mode = ARM_MODE_HYP, .gdb_index = 52, },\n};\n\nstatic const struct {\n\tunsigned int id;\n\tconst char *name;\n\tuint32_t bits;\n\tenum arm_mode mode;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n} arm_vfp_v3_regs[] = {\n\t{ ARM_VFP_V3_D0,  \"d0\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D1,  \"d1\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D2,  \"d2\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D3,  \"d3\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D4,  \"d4\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D5,  \"d5\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D6,  \"d6\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D7,  \"d7\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D8,  \"d8\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D9,  \"d9\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D10, \"d10\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D11, \"d11\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D12, \"d12\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D13, \"d13\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D14, \"d14\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D15, \"d15\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D16, \"d16\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D17, \"d17\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D18, \"d18\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D19, \"d19\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D20, \"d20\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D21, \"d21\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D22, \"d22\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D23, \"d23\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D24, \"d24\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D25, \"d25\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D26, \"d26\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D27, \"d27\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D28, \"d28\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D29, \"d29\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D30, \"d30\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_D31, \"d31\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARM_VFP_V3_FPSCR, \"fpscr\", 32, ARM_MODE_ANY, REG_TYPE_INT, \"float\", \"org.gnu.gdb.arm.vfp\"},\n};\n\n/* map core mode (USR, FIQ, ...) and register number to\n * indices into the register cache\n */\nconst int armv4_5_core_reg_map[9][17] = {\n\t{\t/* USR */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31\n\t},\n\t{\t/* FIQ (8 shadows of USR, vs normal 3) */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32\n\t},\n\t{\t/* IRQ */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33\n\t},\n\t{\t/* SVC */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34\n\t},\n\t{\t/* ABT */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35\n\t},\n\t{\t/* UND */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36\n\t},\n\t{\t/* SYS (same registers as USR) */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31\n\t},\n\t{\t/* MON */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 39, 40, 15, 41,\n\t},\n\t{\t/* HYP */\n\t\t0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 42, 14, 15, 43,\n\t}\n};\n\n/**\n * Configures host-side ARM records to reflect the specified CPSR.\n * Later, code can use arm_reg_current() to map register numbers\n * according to how they are exposed by this mode.\n */\nvoid arm_set_cpsr(struct arm *arm, uint32_t cpsr)\n{\n\tenum arm_mode mode = cpsr & 0x1f;\n\tint num;\n\n\t/* NOTE:  this may be called very early, before the register\n\t * cache is set up.  We can't defend against many errors, in\n\t * particular against CPSRs that aren't valid *here* ...\n\t */\n\tif (arm->cpsr) {\n\t\tbuf_set_u32(arm->cpsr->value, 0, 32, cpsr);\n\t\tarm->cpsr->valid = true;\n\t\tarm->cpsr->dirty = false;\n\t}\n\n\tarm->core_mode = mode;\n\n\t/* mode_to_number() warned; set up a somewhat-sane mapping */\n\tnum = arm_mode_to_number(mode);\n\tif (num < 0) {\n\t\tmode = ARM_MODE_USR;\n\t\tnum = 0;\n\t}\n\n\tarm->map = &armv4_5_core_reg_map[num][0];\n\tarm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS)\n\t\t? NULL\n\t\t: arm->core_cache->reg_list + arm->map[16];\n\n\t/* Older ARMs won't have the J bit */\n\tenum arm_state state;\n\n\tif (cpsr & (1 << 5)) {\t/* T */\n\t\tif (cpsr & (1 << 24)) {\t/* J */\n\t\t\tLOG_WARNING(\"ThumbEE -- incomplete support\");\n\t\t\tstate = ARM_STATE_THUMB_EE;\n\t\t} else\n\t\t\tstate = ARM_STATE_THUMB;\n\t} else {\n\t\tif (cpsr & (1 << 24)) {\t/* J */\n\t\t\tLOG_ERROR(\"Jazelle state handling is BROKEN!\");\n\t\t\tstate = ARM_STATE_JAZELLE;\n\t\t} else\n\t\t\tstate = ARM_STATE_ARM;\n\t}\n\tarm->core_state = state;\n\n\tLOG_DEBUG(\"set CPSR %#8.8x: %s mode, %s state\", (unsigned) cpsr,\n\t\tarm_mode_name(mode),\n\t\tarm_state_strings[arm->core_state]);\n}\n\n/**\n * Returns handle to the register currently mapped to a given number.\n * Someone must have called arm_set_cpsr() before.\n *\n * \\param arm This core's state and registers are used.\n * \\param regnum From 0..15 corresponding to R0..R14 and PC.\n *\tNote that R0..R7 don't require mapping; you may access those\n *\tas the first eight entries in the register cache.  Likewise\n *\tR15 (PC) doesn't need mapping; you may also access it directly.\n *\tHowever, R8..R14, and SPSR (arm->spsr) *must* be mapped.\n *\tCPSR (arm->cpsr) is also not mapped.\n */\nstruct reg *arm_reg_current(struct arm *arm, unsigned regnum)\n{\n\tstruct reg *r;\n\n\tif (regnum > 16)\n\t\treturn NULL;\n\n\tif (!arm->map) {\n\t\tLOG_ERROR(\"Register map is not available yet, the target is not fully initialised\");\n\t\tr = arm->core_cache->reg_list + regnum;\n\t} else\n\t\tr = arm->core_cache->reg_list + arm->map[regnum];\n\n\t/* e.g. invalid CPSR said \"secure monitor\" mode on a core\n\t * that doesn't support it...\n\t */\n\tif (!r) {\n\t\tLOG_ERROR(\"Invalid CPSR mode\");\n\t\tr = arm->core_cache->reg_list + regnum;\n\t}\n\n\treturn r;\n}\n\nstatic const uint8_t arm_gdb_dummy_fp_value[12];\n\nstatic struct reg_feature arm_gdb_dummy_fp_features = {\n\t.name = \"net.sourceforge.openocd.fake_fpa\"\n};\n\n/**\n * Dummy FPA registers are required to support GDB on ARM.\n * Register packets require eight obsolete FPA register values.\n * Modern ARM cores use Vector Floating Point (VFP), if they\n * have any floating point support.  VFP is not FPA-compatible.\n */\nstatic struct reg arm_gdb_dummy_fp_reg = {\n\t.name = \"GDB dummy FPA register\",\n\t.value = (uint8_t *) arm_gdb_dummy_fp_value,\n\t.valid = true,\n\t.size = 96,\n\t.exist = false,\n\t.number = 16,\n\t.feature = &arm_gdb_dummy_fp_features,\n\t.group = \"fake_fpa\",\n};\n\nstatic const uint8_t arm_gdb_dummy_fps_value[4];\n\n/**\n * Dummy FPA status registers are required to support GDB on ARM.\n * Register packets require an obsolete FPA status register.\n */\nstatic struct reg arm_gdb_dummy_fps_reg = {\n\t.name = \"GDB dummy FPA status register\",\n\t.value = (uint8_t *) arm_gdb_dummy_fps_value,\n\t.valid = true,\n\t.size = 32,\n\t.exist = false,\n\t.number = 24,\n\t.feature = &arm_gdb_dummy_fp_features,\n\t.group = \"fake_fpa\",\n};\n\nstatic void arm_gdb_dummy_init(void) __attribute__ ((constructor));\n\nstatic void arm_gdb_dummy_init(void)\n{\n\tregister_init_dummy(&arm_gdb_dummy_fp_reg);\n\tregister_init_dummy(&arm_gdb_dummy_fps_reg);\n}\n\nstatic int armv4_5_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct arm_reg *reg_arch_info = reg->arch_info;\n\tstruct target *target = reg_arch_info->target;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = reg_arch_info->arm->read_core_reg(target, reg,\n\t\t\treg_arch_info->num, reg_arch_info->mode);\n\tif (retval == ERROR_OK) {\n\t\treg->valid = true;\n\t\treg->dirty = false;\n\t}\n\n\treturn retval;\n}\n\nstatic int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct arm_reg *reg_arch_info = reg->arch_info;\n\tstruct target *target = reg_arch_info->target;\n\tstruct arm *armv4_5_target = target_to_arm(target);\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Except for CPSR, the \"reg\" command exposes a writeback model\n\t * for the register cache.\n\t */\n\tif (reg == armv4_5_target->cpsr) {\n\t\tarm_set_cpsr(armv4_5_target, value);\n\n\t\t/* Older cores need help to be in ARM mode during halt\n\t\t * mode debug, so we clear the J and T bits if we flush.\n\t\t * For newer cores (v6/v7a/v7r) we don't need that, but\n\t\t * it won't hurt since CPSR is always flushed anyway.\n\t\t */\n\t\tif (armv4_5_target->core_mode !=\n\t\t\t(enum arm_mode)(value & 0x1f)) {\n\t\t\tLOG_DEBUG(\"changing ARM core mode to '%s'\",\n\t\t\t\tarm_mode_name(value & 0x1f));\n\t\t\tvalue &= ~((1 << 24) | (1 << 5));\n\t\t\tuint8_t t[4];\n\t\t\tbuf_set_u32(t, 0, 32, value);\n\t\t\tarmv4_5_target->write_core_reg(target, reg,\n\t\t\t\t16, ARM_MODE_ANY, t);\n\t\t}\n\t} else {\n\t\tbuf_set_u32(reg->value, 0, 32, value);\n\t\tif (reg->size == 64) {\n\t\t\tvalue = buf_get_u32(buf + 4, 0, 32);\n\t\t\tbuf_set_u32(reg->value + 4, 0, 32, value);\n\t\t}\n\t\treg->valid = true;\n\t}\n\treg->dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type arm_reg_type = {\n\t.get = armv4_5_get_core_reg,\n\t.set = armv4_5_set_core_reg,\n};\n\nstruct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)\n{\n\tint num_regs = ARRAY_SIZE(arm_core_regs);\n\tint num_core_regs = num_regs;\n\tif (arm->arm_vfp_version == ARM_VFP_V3)\n\t\tnum_regs += ARRAY_SIZE(arm_vfp_v3_regs);\n\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct arm_reg *reg_arch_info = calloc(num_regs, sizeof(struct arm_reg));\n\tint i;\n\n\tif (!cache || !reg_list || !reg_arch_info) {\n\t\tfree(cache);\n\t\tfree(reg_list);\n\t\tfree(reg_arch_info);\n\t\treturn NULL;\n\t}\n\n\tcache->name = \"ARM registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = 0;\n\n\tfor (i = 0; i < num_core_regs; i++) {\n\t\t/* Skip registers this core doesn't expose */\n\t\tif (arm_core_regs[i].mode == ARM_MODE_MON\n\t\t\t&& arm->core_type != ARM_CORE_TYPE_SEC_EXT\n\t\t\t&& arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\tcontinue;\n\t\tif (arm_core_regs[i].mode == ARM_MODE_HYP\n\t\t\t&& arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\tcontinue;\n\n\t\t/* REVISIT handle Cortex-M, which only shadows R13/SP */\n\n\t\treg_arch_info[i].num = arm_core_regs[i].cookie;\n\t\treg_arch_info[i].mode = arm_core_regs[i].mode;\n\t\treg_arch_info[i].target = target;\n\t\treg_arch_info[i].arm = arm;\n\n\t\treg_list[i].name = arm_core_regs[i].name;\n\t\treg_list[i].number = arm_core_regs[i].gdb_index;\n\t\treg_list[i].size = 32;\n\t\treg_list[i].value = reg_arch_info[i].value;\n\t\treg_list[i].type = &arm_reg_type;\n\t\treg_list[i].arch_info = &reg_arch_info[i];\n\t\treg_list[i].exist = true;\n\n\t\t/* This really depends on the calling convention in use */\n\t\treg_list[i].caller_save = false;\n\n\t\t/* Registers data type, as used by GDB target description */\n\t\treg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type));\n\t\tswitch (arm_core_regs[i].cookie) {\n\t\tcase 13:\n\t\t\treg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR;\n\t\t\tbreak;\n\t\tcase 14:\n\t\tcase 15:\n\t\t\treg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR;\n\t\t    break;\n\t\tdefault:\n\t\t\treg_list[i].reg_data_type->type = REG_TYPE_UINT32;\n\t\t    break;\n\t\t}\n\n\t\t/* let GDB shows banked registers only in \"info all-reg\" */\n\t\treg_list[i].feature = malloc(sizeof(struct reg_feature));\n\t\tif (reg_list[i].number <= 15 || reg_list[i].number == 25) {\n\t\t\treg_list[i].feature->name = \"org.gnu.gdb.arm.core\";\n\t\t\treg_list[i].group = \"general\";\n\t\t} else {\n\t\t\treg_list[i].feature->name = \"net.sourceforge.openocd.banked\";\n\t\t\treg_list[i].group = \"banked\";\n\t\t}\n\n\t\tcache->num_regs++;\n\t}\n\n\tint j;\n\tfor (i = num_core_regs, j = 0; i < num_regs; i++, j++) {\n\t\treg_arch_info[i].num = arm_vfp_v3_regs[j].id;\n\t\treg_arch_info[i].mode = arm_vfp_v3_regs[j].mode;\n\t\treg_arch_info[i].target = target;\n\t\treg_arch_info[i].arm = arm;\n\n\t\treg_list[i].name = arm_vfp_v3_regs[j].name;\n\t\treg_list[i].number = arm_vfp_v3_regs[j].id;\n\t\treg_list[i].size = arm_vfp_v3_regs[j].bits;\n\t\treg_list[i].value = reg_arch_info[i].value;\n\t\treg_list[i].type = &arm_reg_type;\n\t\treg_list[i].arch_info = &reg_arch_info[i];\n\t\treg_list[i].exist = true;\n\n\t\treg_list[i].caller_save = false;\n\n\t\treg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type));\n\t\treg_list[i].reg_data_type->type = arm_vfp_v3_regs[j].type;\n\n\t\treg_list[i].feature = malloc(sizeof(struct reg_feature));\n\t\treg_list[i].feature->name = arm_vfp_v3_regs[j].feature;\n\n\t\treg_list[i].group = arm_vfp_v3_regs[j].group;\n\n\t\tcache->num_regs++;\n\t}\n\n\tarm->pc = reg_list + 15;\n\tarm->cpsr = reg_list + ARMV4_5_CPSR;\n\tarm->core_cache = cache;\n\n\treturn cache;\n}\n\nvoid arm_free_reg_cache(struct arm *arm)\n{\n\tif (!arm || !arm->core_cache)\n\t\treturn;\n\n\tstruct reg_cache *cache = arm->core_cache;\n\n\tfor (unsigned int i = 0; i < cache->num_regs; i++) {\n\t\tstruct reg *reg = &cache->reg_list[i];\n\n\t\tfree(reg->feature);\n\t\tfree(reg->reg_data_type);\n\t}\n\n\tfree(cache->reg_list[0].arch_info);\n\tfree(cache->reg_list);\n\tfree(cache);\n\n\tarm->core_cache = NULL;\n}\n\nint arm_arch_state(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tif (arm->common_magic != ARM_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-ARM target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* avoid filling log waiting for fileio reply */\n\tif (target->semihosting && target->semihosting->hit_fileio)\n\t\treturn ERROR_OK;\n\n\tLOG_USER(\"target halted in %s state due to %s, current mode: %s\\n\"\n\t\t\"cpsr: 0x%8.8\" PRIx32 \" pc: 0x%8.8\" PRIx32 \"%s%s\",\n\t\tarm_state_strings[arm->core_state],\n\t\tdebug_reason_name(target),\n\t\tarm_mode_name(arm->core_mode),\n\t\tbuf_get_u32(arm->cpsr->value, 0, 32),\n\t\tbuf_get_u32(arm->pc->value, 0, 32),\n\t\t(target->semihosting && target->semihosting->is_active) ? \", semihosting\" : \"\",\n\t\t(target->semihosting && target->semihosting->is_fileio) ? \" fileio\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_armv4_5_reg_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm *arm = target_to_arm(target);\n\tstruct reg *regs;\n\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"error: target must be halted for register accesses\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (arm->core_type != ARM_CORE_TYPE_STD) {\n\t\tcommand_print(CMD,\n\t\t\t\"Microcontroller Profile not supported - use standard reg cmd\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!arm->full_context) {\n\t\tcommand_print(CMD, \"error: target doesn't support %s\",\n\t\t\tCMD_NAME);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tregs = arm->core_cache->reg_list;\n\n\tfor (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) {\n\t\tconst char *name;\n\t\tchar *sep = \"\\n\";\n\t\tchar *shadow = \"\";\n\n\t\tif (!arm_mode_data[mode].n_indices)\n\t\t\tcontinue;\n\n\t\t/* label this bank of registers (or shadows) */\n\t\tswitch (arm_mode_data[mode].psr) {\n\t\t\tcase ARM_MODE_SYS:\n\t\t\t\tcontinue;\n\t\t\tcase ARM_MODE_USR:\n\t\t\t\tname = \"System and User\";\n\t\t\t\tsep = \"\";\n\t\t\t\tbreak;\n\t\t\tcase ARM_MODE_HYP:\n\t\t\t\tif (arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\t\t\tcontinue;\n\t\t\t/* FALLTHROUGH */\n\t\t\tcase ARM_MODE_MON:\n\t\t\tcase ARM_MODE_1176_MON:\n\t\t\t\tif (arm->core_type != ARM_CORE_TYPE_SEC_EXT\n\t\t\t\t\t&& arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\t\t\tcontinue;\n\t\t\t/* FALLTHROUGH */\n\t\t\tdefault:\n\t\t\t\tname = arm_mode_data[mode].name;\n\t\t\t\tshadow = \"shadow \";\n\t\t\t\tbreak;\n\t\t}\n\t\tcommand_print(CMD, \"%s%s mode %sregisters\",\n\t\t\tsep, name, shadow);\n\n\t\t/* display N rows of up to 4 registers each */\n\t\tfor (unsigned i = 0; i < arm_mode_data[mode].n_indices; ) {\n\t\t\tchar output[80];\n\t\t\tint output_len = 0;\n\n\t\t\tfor (unsigned j = 0; j < 4; j++, i++) {\n\t\t\t\tuint32_t value;\n\t\t\t\tstruct reg *reg = regs;\n\n\t\t\t\tif (i >= arm_mode_data[mode].n_indices)\n\t\t\t\t\tbreak;\n\n\t\t\t\treg += arm_mode_data[mode].indices[i];\n\n\t\t\t\t/* REVISIT be smarter about faults... */\n\t\t\t\tif (!reg->valid)\n\t\t\t\t\tarm->full_context(target);\n\n\t\t\t\tvalue = buf_get_u32(reg->value, 0, 32);\n\t\t\t\toutput_len += snprintf(output + output_len,\n\t\t\t\t\t\tsizeof(output) - output_len,\n\t\t\t\t\t\t\"%8s: %8.8\" PRIx32 \" \",\n\t\t\t\t\t\treg->name, value);\n\t\t\t}\n\t\t\tcommand_print(CMD, \"%s\", output);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_arm_core_state_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm *arm = target_to_arm(target);\n\tint ret = ERROR_OK;\n\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC > 0) {\n\t\tif (strcmp(CMD_ARGV[0], \"arm\") == 0) {\n\t\t\tif (arm->core_type == ARM_CORE_TYPE_M_PROFILE) {\n\t\t\t\tcommand_print(CMD, \"arm mode not supported on Cortex-M\");\n\t\t\t\tret = ERROR_FAIL;\n\t\t\t} else {\n\t\t\t\tarm->core_state = ARM_STATE_ARM;\n\t\t\t}\n\t\t}\n\t\tif (strcmp(CMD_ARGV[0], \"thumb\") == 0)\n\t\t\tarm->core_state = ARM_STATE_THUMB;\n\t}\n\n\tcommand_print(CMD, \"core state: %s\", arm_state_strings[arm->core_state]);\n\n\treturn ret;\n}\n\nCOMMAND_HANDLER(handle_arm_disassemble_command)\n{\n#if HAVE_CAPSTONE\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct arm *arm = target_to_arm(target);\n\ttarget_addr_t address;\n\tunsigned int count = 1;\n\tbool thumb = false;\n\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (arm->core_type == ARM_CORE_TYPE_M_PROFILE) {\n\t\t/* armv7m is always thumb mode */\n\t\tthumb = true;\n\t}\n\n\tswitch (CMD_ARGC) {\n\t\tcase 3:\n\t\t\tif (strcmp(CMD_ARGV[2], \"thumb\") != 0)\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\tthumb = true;\n\t\t/* FALL THROUGH */\n\t\tcase 2:\n\t\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], count);\n\t\t/* FALL THROUGH */\n\t\tcase 1:\n\t\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\t\t\tif (address & 0x01) {\n\t\t\t\tif (!thumb) {\n\t\t\t\t\tcommand_print(CMD, \"Disassemble as Thumb\");\n\t\t\t\t\tthumb = true;\n\t\t\t\t}\n\t\t\t\taddress &= ~1;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn arm_disassemble(CMD, target, address, count, thumb);\n#else\n\tcommand_print(CMD, \"capstone disassembly framework required\");\n\treturn ERROR_FAIL;\n#endif\n}\n\nCOMMAND_HANDLER(handle_armv4_5_mcrmrc)\n{\n\tbool is_mcr = false;\n\tunsigned int arg_cnt = 5;\n\n\tif (!strcmp(CMD_NAME, \"mcr\")) {\n\t\tis_mcr = true;\n\t\targ_cnt = 6;\n\t}\n\n\tif (arg_cnt != CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tcommand_print(CMD, \"no current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target_was_examined(target)) {\n\t\tcommand_print(CMD, \"%s: not yet examined\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tstruct arm *arm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"%s: not an ARM\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tint cpnum;\n\tuint32_t op1;\n\tuint32_t op2;\n\tuint32_t crn;\n\tuint32_t crm;\n\tuint32_t value;\n\n\t/* NOTE:  parameter sequence matches ARM instruction set usage:\n\t *\tMCR\tpNUM, op1, rX, CRn, CRm, op2\t; write CP from rX\n\t *\tMRC\tpNUM, op1, rX, CRn, CRm, op2\t; read CP into rX\n\t * The \"rX\" is necessarily omitted; it uses Tcl mechanisms.\n\t */\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);\n\tif (cpnum & ~0xf) {\n\t\tcommand_print(CMD, \"coprocessor %d out of range\", cpnum);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);\n\tif (op1 & ~0x7) {\n\t\tcommand_print(CMD, \"op1 %d out of range\", op1);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);\n\tif (crn & ~0xf) {\n\t\tcommand_print(CMD, \"CRn %d out of range\", crn);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);\n\tif (crm & ~0xf) {\n\t\tcommand_print(CMD, \"CRm %d out of range\", crm);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);\n\tif (op2 & ~0x7) {\n\t\tcommand_print(CMD, \"op2 %d out of range\", op2);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/*\n\t * FIXME change the call syntax here ... simplest to just pass\n\t * the MRC() or MCR() instruction to be executed.  That will also\n\t * let us support the \"mrc2\" and \"mcr2\" opcodes (toggling one bit)\n\t * if that's ever needed.\n\t */\n\tif (is_mcr) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);\n\n\t\t/* NOTE: parameters reordered! */\n\t\t/* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */\n\t\tint retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tvalue = 0;\n\t\t/* NOTE: parameters reordered! */\n\t\t/* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */\n\t\tint retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration arm_exec_command_handlers[] = {\n\t{\n\t\t.name = \"reg\",\n\t\t.handler = handle_armv4_5_reg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display ARM core registers\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"mcr\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_armv4_5_mcrmrc,\n\t\t.help = \"write coprocessor register\",\n\t\t.usage = \"cpnum op1 CRn CRm op2 value\",\n\t},\n\t{\n\t\t.name = \"mrc\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_armv4_5_mcrmrc,\n\t\t.help = \"read coprocessor register\",\n\t\t.usage = \"cpnum op1 CRn CRm op2\",\n\t},\n\t{\n\t\t.chain = arm_all_profiles_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm_all_profiles_command_handlers[] = {\n\t{\n\t\t.name = \"core_state\",\n\t\t.handler = handle_arm_core_state_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['arm'|'thumb']\",\n\t\t.help = \"display/change ARM core state\",\n\t},\n\t{\n\t\t.name = \"disassemble\",\n\t\t.handler = handle_arm_disassemble_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"address [count ['thumb']]\",\n\t\t.help = \"disassemble instructions\",\n\t},\n\t{\n\t\t.chain = semihosting_common_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm_command_handlers[] = {\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/*\n * gdb for arm targets (e.g. arm-none-eabi-gdb) supports several variants\n * of arm architecture. You can list them using the autocompletion of gdb\n * command prompt by typing \"set architecture \" and then press TAB key.\n * The default, selected automatically, is \"arm\".\n * Let's use the default value, here, to make gdb-multiarch behave in the\n * same way as a gdb for arm. This can be changed later on. User can still\n * set the specific architecture variant with the gdb command.\n */\nconst char *arm_get_gdb_arch(struct target *target)\n{\n\treturn \"arm\";\n}\n\nint arm_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[], int *reg_list_size,\n\tenum target_register_class reg_class)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tunsigned int i;\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tswitch (reg_class) {\n\tcase REG_CLASS_GENERAL:\n\t\t*reg_list_size = 26;\n\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\tfor (i = 0; i < 16; i++)\n\t\t\t\t(*reg_list)[i] = arm_reg_current(arm, i);\n\n\t\t/* For GDB compatibility, take FPA registers size into account and zero-fill it*/\n\t\tfor (i = 16; i < 24; i++)\n\t\t\t\t(*reg_list)[i] = &arm_gdb_dummy_fp_reg;\n\t\t(*reg_list)[24] = &arm_gdb_dummy_fps_reg;\n\n\t\t(*reg_list)[25] = arm->cpsr;\n\n\t\treturn ERROR_OK;\n\n\tcase REG_CLASS_ALL:\n\t\tswitch (arm->core_type) {\n\t\t\tcase ARM_CORE_TYPE_SEC_EXT:\n\t\t\t\t*reg_list_size = 51;\n\t\t\t\tbreak;\n\t\t\tcase ARM_CORE_TYPE_VIRT_EXT:\n\t\t\t\t*reg_list_size = 53;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t*reg_list_size = 48;\n\t\t}\n\t\tunsigned int list_size_core = *reg_list_size;\n\t\tif (arm->arm_vfp_version == ARM_VFP_V3)\n\t\t\t*reg_list_size += 33;\n\n\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\tfor (i = 0; i < 16; i++)\n\t\t\t\t(*reg_list)[i] = arm_reg_current(arm, i);\n\n\t\tfor (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) {\n\t\t\t\tint reg_index = arm->core_cache->reg_list[i].number;\n\n\t\t\t\tif (arm_core_regs[i].mode == ARM_MODE_MON\n\t\t\t\t\t&& arm->core_type != ARM_CORE_TYPE_SEC_EXT\n\t\t\t\t\t&& arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (arm_core_regs[i].mode == ARM_MODE_HYP\n\t\t\t\t\t&& arm->core_type != ARM_CORE_TYPE_VIRT_EXT)\n\t\t\t\t\tcontinue;\n\t\t\t\t(*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]);\n\t\t}\n\n\t\t/* When we supply the target description, there is no need for fake FPA */\n\t\tfor (i = 16; i < 24; i++) {\n\t\t\t\t(*reg_list)[i] = &arm_gdb_dummy_fp_reg;\n\t\t\t\t(*reg_list)[i]->size = 0;\n\t\t}\n\t\t(*reg_list)[24] = &arm_gdb_dummy_fps_reg;\n\t\t(*reg_list)[24]->size = 0;\n\n\t\tif (arm->arm_vfp_version == ARM_VFP_V3) {\n\t\t\tunsigned int num_core_regs = ARRAY_SIZE(arm_core_regs);\n\t\t\tfor (i = 0; i < 33; i++)\n\t\t\t\t(*reg_list)[list_size_core + i] = &(arm->core_cache->reg_list[num_core_regs + i]);\n\t\t}\n\n\t\treturn ERROR_OK;\n\n\tdefault:\n\t\tLOG_ERROR(\"not a valid register class type in query.\");\n\t\treturn ERROR_FAIL;\n\t}\n}\n\n/* wait for execution to complete and check exit point */\nstatic int armv4_5_run_algorithm_completion(struct target *target,\n\tuint32_t exit_point,\n\tunsigned int timeout_ms,\n\tvoid *arch_info)\n{\n\tint retval;\n\tstruct arm *arm = target_to_arm(target);\n\n\tretval = target_wait_state(target, TARGET_HALTED, timeout_ms);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (target->state != TARGET_HALTED) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_wait_state(target, TARGET_HALTED, 500);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\t/* fast exit: ARMv5+ code can use BKPT */\n\tif (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) {\n\t\tLOG_WARNING(\n\t\t\t\"target reentered debug state, but not at the desired exit point: 0x%4.4\" PRIx32 \"\",\n\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint armv4_5_run_algorithm_inner(struct target *target,\n\tint num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\tuint32_t entry_point, uint32_t exit_point,\n\tunsigned int timeout_ms, void *arch_info,\n\tint (*run_it)(struct target *target, uint32_t exit_point,\n\tunsigned int timeout_ms, void *arch_info))\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_algorithm *arm_algorithm_info = arch_info;\n\tenum arm_state core_state = arm->core_state;\n\tuint32_t context[17];\n\tuint32_t cpsr;\n\tint exit_breakpoint_size = 0;\n\tint i;\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"Running algorithm\");\n\n\tif (arm_algorithm_info->common_magic != ARM_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"current target isn't an ARMV4/5 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\tLOG_ERROR(\"not a valid arm core mode - communication failure?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* armv5 and later can terminate with BKPT instruction; less overhead */\n\tif (!exit_point && arm->arch == ARM_ARCH_V4) {\n\t\tLOG_ERROR(\"ARMv4 target needs HW breakpoint location\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure;\n\t * they'll be restored later.\n\t */\n\tfor (i = 0; i <= 16; i++) {\n\t\tstruct reg *r;\n\n\t\tr = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tarm_algorithm_info->core_mode, i);\n\t\tif (!r->valid)\n\t\t\tarm->read_core_reg(target, r, i,\n\t\t\t\tarm_algorithm_info->core_mode);\n\t\tcontext[i] = buf_get_u32(r->value, 0, 32);\n\t}\n\tcpsr = buf_get_u32(arm->cpsr->value, 0, 32);\n\n\tfor (i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\t\tretval = target_write_buffer(target, mem_params[i].address, mem_params[i].size,\n\t\t\t\tmem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\n\t\tstruct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, false);\n\t\tif (!reg) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (reg->size != reg_params[i].size) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\treg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tretval = armv4_5_set_core_reg(reg, reg_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tarm->core_state = arm_algorithm_info->core_state;\n\tif (arm->core_state == ARM_STATE_ARM)\n\t\texit_breakpoint_size = 4;\n\telse if (arm->core_state == ARM_STATE_THUMB)\n\t\texit_breakpoint_size = 2;\n\telse {\n\t\tLOG_ERROR(\"BUG: can't execute algorithms when not in ARM or Thumb state\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (arm_algorithm_info->core_mode != ARM_MODE_ANY) {\n\t\tLOG_DEBUG(\"setting core_mode: 0x%2.2x\",\n\t\t\tarm_algorithm_info->core_mode);\n\t\tbuf_set_u32(arm->cpsr->value, 0, 5,\n\t\t\tarm_algorithm_info->core_mode);\n\t\tarm->cpsr->dirty = true;\n\t\tarm->cpsr->valid = true;\n\t}\n\n\t/* terminate using a hardware or (ARMv5+) software breakpoint */\n\tif (exit_point) {\n\t\tretval = breakpoint_add(target, exit_point,\n\t\t\t\texit_breakpoint_size, BKPT_HARD);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"can't add HW breakpoint to terminate algorithm\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t}\n\t}\n\n\tretval = target_resume(target, 0, entry_point, 1, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = run_it(target, exit_point, timeout_ms, arch_info);\n\n\tif (exit_point)\n\t\tbreakpoint_remove(target, exit_point);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction != PARAM_OUT) {\n\t\t\tint retvaltemp = target_read_buffer(target, mem_params[i].address,\n\t\t\t\t\tmem_params[i].size,\n\t\t\t\t\tmem_params[i].value);\n\t\t\tif (retvaltemp != ERROR_OK)\n\t\t\t\tretval = retvaltemp;\n\t\t}\n\t}\n\n\tfor (i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction != PARAM_OUT) {\n\n\t\t\tstruct reg *reg = register_get_by_name(arm->core_cache,\n\t\t\t\t\treg_params[i].reg_name,\n\t\t\t\t\tfalse);\n\t\t\tif (!reg) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\t\tretval = ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (reg->size != reg_params[i].size) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\tretval = ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tbuf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));\n\t\t}\n\t}\n\n\t/* restore everything we saved before (17 or 18 registers) */\n\tfor (i = 0; i <= 16; i++) {\n\t\tuint32_t regvalue;\n\t\tregvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tarm_algorithm_info->core_mode, i).value, 0, 32);\n\t\tif (regvalue != context[i]) {\n\t\t\tLOG_DEBUG(\"restoring register %s with value 0x%8.8\" PRIx32 \"\",\n\t\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tarm_algorithm_info->core_mode, i).name, context[i]);\n\t\t\tbuf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tarm_algorithm_info->core_mode, i).value, 0, 32, context[i]);\n\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,\n\t\t\t\ti).valid = true;\n\t\t\tARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,\n\t\t\t\ti).dirty = true;\n\t\t}\n\t}\n\n\tarm_set_cpsr(arm, cpsr);\n\tarm->cpsr->dirty = true;\n\n\tarm->core_state = core_state;\n\n\treturn retval;\n}\n\nint armv4_5_run_algorithm(struct target *target,\n\tint num_mem_params,\n\tstruct mem_param *mem_params,\n\tint num_reg_params,\n\tstruct reg_param *reg_params,\n\ttarget_addr_t entry_point,\n\ttarget_addr_t exit_point,\n\tunsigned int timeout_ms,\n\tvoid *arch_info)\n{\n\treturn armv4_5_run_algorithm_inner(target,\n\t\t\tnum_mem_params,\n\t\t\tmem_params,\n\t\t\tnum_reg_params,\n\t\t\treg_params,\n\t\t\t(uint32_t)entry_point,\n\t\t\t(uint32_t)exit_point,\n\t\t\ttimeout_ms,\n\t\t\tarch_info,\n\t\t\tarmv4_5_run_algorithm_completion);\n}\n\n/**\n * Runs ARM code in the target to calculate a CRC32 checksum.\n *\n */\nint arm_checksum_memory(struct target *target,\n\ttarget_addr_t address, uint32_t count, uint32_t *checksum)\n{\n\tstruct working_area *crc_algorithm;\n\tstruct arm_algorithm arm_algo;\n\tstruct arm *arm = target_to_arm(target);\n\tstruct reg_param reg_params[2];\n\tint retval;\n\tuint32_t i;\n\tuint32_t exit_var = 0;\n\n\tstatic const uint8_t arm_crc_code_le[] = {\n#include \"../../contrib/loaders/checksum/armv4_5_crc.inc\"\n\t};\n\n\tassert(sizeof(arm_crc_code_le) % 4 == 0);\n\n\tretval = target_alloc_working_area(target,\n\t\t\tsizeof(arm_crc_code_le), &crc_algorithm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* convert code into a buffer in target endianness */\n\tfor (i = 0; i < ARRAY_SIZE(arm_crc_code_le) / 4; i++) {\n\t\tretval = target_write_u32(target,\n\t\t\t\tcrc_algorithm->address + i * sizeof(uint32_t),\n\t\t\t\tle_to_h_u32(&arm_crc_code_le[i * 4]));\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup;\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\n\t/* 20 second timeout/megabyte */\n\tunsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));\n\n\t/* armv4 must exit using a hardware breakpoint */\n\tif (arm->arch == ARM_ARCH_V4)\n\t\texit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8;\n\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params,\n\t\t\tcrc_algorithm->address,\n\t\t\texit_var,\n\t\t\ttimeout, &arm_algo);\n\n\tif (retval == ERROR_OK)\n\t\t*checksum = buf_get_u32(reg_params[0].value, 0, 32);\n\telse\n\t\tLOG_ERROR(\"error executing ARM crc algorithm\");\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\ncleanup:\n\ttarget_free_working_area(target, crc_algorithm);\n\n\treturn retval;\n}\n\n/**\n * Runs ARM code in the target to check whether a memory block holds\n * all ones.  NOR flash which has been erased, and thus may be written,\n * holds all ones.\n *\n */\nint arm_blank_check_memory(struct target *target,\n\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)\n{\n\tstruct working_area *check_algorithm;\n\tstruct reg_param reg_params[3];\n\tstruct arm_algorithm arm_algo;\n\tstruct arm *arm = target_to_arm(target);\n\tint retval;\n\tuint32_t i;\n\tuint32_t exit_var = 0;\n\n\tstatic const uint8_t check_code_le[] = {\n#include \"../../contrib/loaders/erase_check/armv4_5_erase_check.inc\"\n\t};\n\n\tassert(sizeof(check_code_le) % 4 == 0);\n\n\tif (erased_value != 0xff) {\n\t\tLOG_ERROR(\"Erase value 0x%02\" PRIx8 \" not yet supported for ARMv4/v5 targets\",\n\t\t\terased_value);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* make sure we have a working area */\n\tretval = target_alloc_working_area(target,\n\t\t\tsizeof(check_code_le), &check_algorithm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* convert code into a buffer in target endianness */\n\tfor (i = 0; i < ARRAY_SIZE(check_code_le) / 4; i++) {\n\t\tretval = target_write_u32(target,\n\t\t\t\tcheck_algorithm->address\n\t\t\t\t+ i * sizeof(uint32_t),\n\t\t\t\tle_to_h_u32(&check_code_le[i * 4]));\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto cleanup;\n\t}\n\n\tarm_algo.common_magic = ARM_COMMON_MAGIC;\n\tarm_algo.core_mode = ARM_MODE_SVC;\n\tarm_algo.core_state = ARM_STATE_ARM;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);\n\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);\n\n\tinit_reg_param(&reg_params[2], \"r2\", 32, PARAM_IN_OUT);\n\tbuf_set_u32(reg_params[2].value, 0, 32, erased_value);\n\n\t/* armv4 must exit using a hardware breakpoint */\n\tif (arm->arch == ARM_ARCH_V4)\n\t\texit_var = check_algorithm->address + sizeof(check_code_le) - 4;\n\n\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params,\n\t\t\tcheck_algorithm->address,\n\t\t\texit_var,\n\t\t\t10000, &arm_algo);\n\n\tif (retval == ERROR_OK)\n\t\tblocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\ncleanup:\n\ttarget_free_working_area(target, check_algorithm);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn 1;       /* only one block has been checked */\n}\n\nstatic int arm_full_context(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tunsigned num_regs = arm->core_cache->num_regs;\n\tstruct reg *reg = arm->core_cache->reg_list;\n\tint retval = ERROR_OK;\n\n\tfor (; num_regs && retval == ERROR_OK; num_regs--, reg++) {\n\t\tif (!reg->exist || reg->valid)\n\t\t\tcontinue;\n\t\tretval = armv4_5_get_core_reg(reg);\n\t}\n\treturn retval;\n}\n\nstatic int arm_default_mrc(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2,\n\tuint32_t crn, uint32_t crm,\n\tuint32_t *value)\n{\n\tLOG_ERROR(\"%s doesn't implement MRC\", target_type_name(target));\n\treturn ERROR_FAIL;\n}\n\nstatic int arm_default_mcr(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2,\n\tuint32_t crn, uint32_t crm,\n\tuint32_t value)\n{\n\tLOG_ERROR(\"%s doesn't implement MCR\", target_type_name(target));\n\treturn ERROR_FAIL;\n}\n\nint arm_init_arch_info(struct target *target, struct arm *arm)\n{\n\ttarget->arch_info = arm;\n\tarm->target = target;\n\n\tarm->common_magic = ARM_COMMON_MAGIC;\n\n\t/* core_type may be overridden by subtype logic */\n\tif (arm->core_type != ARM_CORE_TYPE_M_PROFILE) {\n\t\tarm->core_type = ARM_CORE_TYPE_STD;\n\t\tarm_set_cpsr(arm, ARM_MODE_USR);\n\t}\n\n\t/* default full_context() has no core-specific optimizations */\n\tif (!arm->full_context && arm->read_core_reg)\n\t\tarm->full_context = arm_full_context;\n\n\tif (!arm->mrc)\n\t\tarm->mrc = arm_default_mrc;\n\tif (!arm->mcr)\n\t\tarm->mcr = arm_default_mcr;\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2009 by Øyvind Harboe                                   *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV4_5_H\n#define OPENOCD_TARGET_ARMV4_5_H\n\n/* This stuff \"knows\" that its callers aren't talking\n * to microcontroller profile (current Cortex-M) parts.\n * We want to phase it out so core code can be shared.\n */\n\n/* OBSOLETE, DO NOT USE IN NEW CODE!  The \"number\" of an arm_mode is an\n * index into the armv4_5_core_reg_map array.  Its remaining users are\n * remnants which could as easily walk * the register cache directly as\n * use the expensive ARMV4_5_CORE_REG_MODE() macro.\n */\nint arm_mode_to_number(enum arm_mode mode);\nenum arm_mode armv4_5_number_to_mode(int number);\n\nextern const int armv4_5_core_reg_map[9][17];\n\n#define ARMV4_5_CORE_REG_MODE(cache, mode, num) \\\n\t\t(cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]])\n\n/* offset into armv4_5 core register cache -- OBSOLETE, DO NOT USE! */\nenum { ARMV4_5_CPSR = 31, };\n\n#endif /* OPENOCD_TARGET_ARMV4_5_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5_cache.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"armv4_5_cache.h\"\n#include <helper/log.h>\n\nint armv4_5_identify_cache(uint32_t cache_type_reg, struct armv4_5_cache_common *cache)\n{\n\tint size, assoc, M, len, multiplier;\n\n\tcache->ctype = (cache_type_reg & 0x1e000000U) >> 25;\n\tcache->separate = (cache_type_reg & 0x01000000U) >> 24;\n\n\tsize = (cache_type_reg & 0x1c0000) >> 18;\n\tassoc = (cache_type_reg & 0x38000) >> 15;\n\tM = (cache_type_reg & 0x4000) >> 14;\n\tlen = (cache_type_reg & 0x3000) >> 12;\n\tmultiplier = 2 + M;\n\n\tif ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ {\n\t\t/* cache is present */\n\t\tcache->d_u_size.linelen = 1 << (len + 3);\n\t\tcache->d_u_size.associativity = multiplier << (assoc - 1);\n\t\tcache->d_u_size.nsets = 1 << (size + 6 - assoc - len);\n\t\tcache->d_u_size.cachesize = multiplier << (size + 8);\n\t} else {\n\t\t/* cache is absent */\n\t\tcache->d_u_size.linelen = -1;\n\t\tcache->d_u_size.associativity = -1;\n\t\tcache->d_u_size.nsets = -1;\n\t\tcache->d_u_size.cachesize = -1;\n\t}\n\n\tif (cache->separate) {\n\t\tsize = (cache_type_reg & 0x1c0) >> 6;\n\t\tassoc = (cache_type_reg & 0x38) >> 3;\n\t\tM = (cache_type_reg & 0x4) >> 2;\n\t\tlen = (cache_type_reg & 0x3);\n\t\tmultiplier = 2 + M;\n\n\t\tif ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ {\n\t\t\t/* cache is present */\n\t\t\tcache->i_size.linelen = 1 << (len + 3);\n\t\t\tcache->i_size.associativity = multiplier << (assoc - 1);\n\t\t\tcache->i_size.nsets = 1 << (size + 6 - assoc - len);\n\t\t\tcache->i_size.cachesize = multiplier << (size + 8);\n\t\t} else {\n\t\t\t/* cache is absent */\n\t\t\tcache->i_size.linelen = -1;\n\t\t\tcache->i_size.associativity = -1;\n\t\t\tcache->i_size.nsets = -1;\n\t\t\tcache->i_size.cachesize = -1;\n\t\t}\n\t} else\n\t\tcache->i_size = cache->d_u_size;\n\n\treturn ERROR_OK;\n}\n\nint armv4_5_handle_cache_info_command(struct command_invocation *cmd, struct armv4_5_cache_common *armv4_5_cache)\n{\n\tif (armv4_5_cache->ctype == -1) {\n\t\tcommand_print(cmd, \"cache not yet identified\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(cmd, \"cache type: 0x%1.1x, %s\", armv4_5_cache->ctype,\n\t\t(armv4_5_cache->separate) ? \"separate caches\" : \"unified cache\");\n\n\tcommand_print(cmd, \"D-Cache: linelen %i, associativity %i, nsets %i, cachesize 0x%x\",\n\t\tarmv4_5_cache->d_u_size.linelen,\n\t\tarmv4_5_cache->d_u_size.associativity,\n\t\tarmv4_5_cache->d_u_size.nsets,\n\t\tarmv4_5_cache->d_u_size.cachesize);\n\n\tcommand_print(cmd, \"I-Cache: linelen %i, associativity %i, nsets %i, cachesize 0x%x\",\n\t\tarmv4_5_cache->i_size.linelen,\n\t\tarmv4_5_cache->i_size.associativity,\n\t\tarmv4_5_cache->i_size.nsets,\n\t\tarmv4_5_cache->i_size.cachesize);\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5_cache.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV4_5_CACHE_H\n#define OPENOCD_TARGET_ARMV4_5_CACHE_H\n\n#include \"helper/types.h\"\n\nstruct command_invocation;\n\nstruct armv4_5_cachesize {\n\tint linelen;\n\tint associativity;\n\tint nsets;\n\tint cachesize;\n};\n\nstruct armv4_5_cache_common {\n\tint ctype;\t/* specify supported cache operations */\n\tint separate;\t/* separate caches or unified cache */\n\tstruct armv4_5_cachesize d_u_size;\t/* data cache */\n\tstruct armv4_5_cachesize i_size; /* instruction cache */\n\tint i_cache_enabled;\n\tint d_u_cache_enabled;\n};\n\nint armv4_5_identify_cache(uint32_t cache_type_reg,\n\t\tstruct armv4_5_cache_common *cache);\nint armv4_5_cache_state(uint32_t cp15_control_reg,\n\t\tstruct armv4_5_cache_common *cache);\n\nint armv4_5_handle_cache_info_command(struct command_invocation *cmd,\n\t\tstruct armv4_5_cache_common *armv4_5_cache);\n\nenum {\n\tARMV4_5_D_U_CACHE_ENABLED = 0x4,\n\tARMV4_5_I_CACHE_ENABLED = 0x1000,\n\tARMV4_5_WRITE_BUFFER_ENABLED = 0x8,\n\tARMV4_5_CACHE_RR_BIT = 0x5000,\n};\n\n#endif /* OPENOCD_TARGET_ARMV4_5_CACHE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5_mmu.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include \"target.h\"\n#include \"armv4_5_mmu.h\"\n\nint armv4_5_mmu_translate_va(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu, uint32_t va, uint32_t *cb, uint32_t *val)\n{\n\tuint32_t first_lvl_descriptor = 0x0;\n\tuint32_t second_lvl_descriptor = 0x0;\n\tuint32_t ttb;\n\tint retval;\n\tretval = armv4_5_mmu->get_ttb(target, &ttb);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = armv4_5_mmu_read_physical(target, armv4_5_mmu,\n\t\t(ttb & 0xffffc000) | ((va & 0xfff00000) >> 18),\n\t\t4, 1, (uint8_t *)&first_lvl_descriptor);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tfirst_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&first_lvl_descriptor);\n\n\tLOG_DEBUG(\"1st lvl desc: %8.8\" PRIx32 \"\", first_lvl_descriptor);\n\n\tif ((first_lvl_descriptor & 0x3) == 0) {\n\t\tLOG_ERROR(\"Address translation failure\");\n\t\treturn ERROR_TARGET_TRANSLATION_FAULT;\n\t}\n\n\tif (!armv4_5_mmu->has_tiny_pages && ((first_lvl_descriptor & 0x3) == 3)) {\n\t\tLOG_ERROR(\"Address translation failure\");\n\t\treturn ERROR_TARGET_TRANSLATION_FAULT;\n\t}\n\n\tif ((first_lvl_descriptor & 0x3) == 2) {\n\t\t/* section descriptor */\n\t\t*cb = (first_lvl_descriptor & 0xc) >> 2;\n\t\t*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff);\n\t\treturn ERROR_OK;\n\t}\n\n\tif ((first_lvl_descriptor & 0x3) == 1) {\n\t\t/* coarse page table */\n\t\tretval = armv4_5_mmu_read_physical(target, armv4_5_mmu,\n\t\t\t(first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),\n\t\t\t4, 1, (uint8_t *)&second_lvl_descriptor);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else if ((first_lvl_descriptor & 0x3) == 3) {\n\t\t/* fine page table */\n\t\tretval = armv4_5_mmu_read_physical(target, armv4_5_mmu,\n\t\t\t(first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8),\n\t\t\t4, 1, (uint8_t *)&second_lvl_descriptor);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tsecond_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&second_lvl_descriptor);\n\n\tLOG_DEBUG(\"2nd lvl desc: %8.8\" PRIx32 \"\", second_lvl_descriptor);\n\n\tif ((second_lvl_descriptor & 0x3) == 0) {\n\t\tLOG_ERROR(\"Address translation failure\");\n\t\treturn ERROR_TARGET_TRANSLATION_FAULT;\n\t}\n\n\t/* cacheable/bufferable is always specified in bits 3-2 */\n\t*cb = (second_lvl_descriptor & 0xc) >> 2;\n\n\tif ((second_lvl_descriptor & 0x3) == 1) {\n\t\t/* large page descriptor */\n\t\t*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff);\n\t\treturn ERROR_OK;\n\t}\n\n\tif ((second_lvl_descriptor & 0x3) == 2) {\n\t\t/* small page descriptor */\n\t\t*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff);\n\t\treturn ERROR_OK;\n\t}\n\n\tif ((second_lvl_descriptor & 0x3) == 3) {\n\t\t/* tiny page descriptor */\n\t\t*val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* should not happen */\n\tLOG_ERROR(\"Address translation failure\");\n\treturn ERROR_TARGET_TRANSLATION_FAULT;\n}\n\nint armv4_5_mmu_read_physical(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu, uint32_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/* disable MMU and data (or unified) cache */\n\tretval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = armv4_5_mmu->read_memory(target, address, size, count, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* reenable MMU / cache */\n\tretval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled,\n\t\tarmv4_5_mmu->armv4_5_cache.d_u_cache_enabled,\n\t\tarmv4_5_mmu->armv4_5_cache.i_cache_enabled);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nint armv4_5_mmu_write_physical(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu, uint32_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/* disable MMU and data (or unified) cache */\n\tretval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = armv4_5_mmu->write_memory(target, address, size, count, buffer);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* reenable MMU / cache */\n\tretval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled,\n\t\tarmv4_5_mmu->armv4_5_cache.d_u_cache_enabled,\n\t\tarmv4_5_mmu->armv4_5_cache.i_cache_enabled);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv4_5_mmu.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV4_5_MMU_H\n#define OPENOCD_TARGET_ARMV4_5_MMU_H\n\n#include \"armv4_5_cache.h\"\n\nstruct target;\n\nstruct armv4_5_mmu_common {\n\tint (*get_ttb)(struct target *target, uint32_t *result);\n\tint (*read_memory)(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);\n\tint (*write_memory)(struct target *target, target_addr_t address,\n\t\t\t    uint32_t size, uint32_t count, const uint8_t *buffer);\n\tint (*disable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache);\n\tint (*enable_mmu_caches)(struct target *target, int mmu, int d_u_cache, int i_cache);\n\tstruct armv4_5_cache_common armv4_5_cache;\n\tint has_tiny_pages;\n\tint mmu_enabled;\n};\n\nint armv4_5_mmu_translate_va(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu, uint32_t va,\n\t\tuint32_t *cb, uint32_t *val);\n\nint armv4_5_mmu_read_physical(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu,\n\t\tuint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);\n\nint armv4_5_mmu_write_physical(struct target *target,\n\t\tstruct armv4_5_mmu_common *armv4_5_mmu,\n\t\tuint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\n\nenum {\n\tARMV4_5_MMU_ENABLED = 0x1,\n\tARMV4_5_ALIGNMENT_CHECK = 0x2,\n\tARMV4_5_MMU_S_BIT = 0x100,\n\tARMV4_5_MMU_R_BIT = 0x200\n};\n\n#endif /* OPENOCD_TARGET_ARMV4_5_MMU_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *    Copyright (C) 2009 by David Brownell                                 *\n *                                                                         *\n *    Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/replacements.h>\n\n#include \"armv7a.h\"\n#include \"armv7a_mmu.h\"\n#include \"arm_disassembler.h\"\n\n#include \"register.h\"\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"arm_opcodes.h\"\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"smp.h\"\n\nstatic void armv7a_show_fault_registers(struct target *target)\n{\n\tuint32_t dfsr, ifsr, dfar, ifar;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn;\n\n\t/* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */\n\n\t/* c5/c0 - {data, instruction} fault status registers */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 5, 0, 0),\n\t\t\t&dfsr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 5, 0, 1),\n\t\t\t&ifsr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* c6/c0 - {data, instruction} fault address registers */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 6, 0, 0),\n\t\t\t&dfar);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 6, 0, 2),\n\t\t\t&ifar);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tLOG_USER(\"Data fault registers        DFSR: %8.8\" PRIx32\n\t\t\", DFAR: %8.8\" PRIx32, dfsr, dfar);\n\tLOG_USER(\"Instruction fault registers IFSR: %8.8\" PRIx32\n\t\t\", IFAR: %8.8\" PRIx32, ifsr, ifar);\n\ndone:\n\t/* (void) */ dpm->finish(dpm);\n}\n\n\n/*  retrieve main id register  */\nstatic int armv7a_read_midr(struct target *target)\n{\n\tint retval = ERROR_FAIL;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tuint32_t midr;\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\t/* MRC p15,0,<Rd>,c0,c0,0; read main id register*/\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 0, 0, 0),\n\t\t\t&midr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tarmv7a->rev = (midr & 0xf);\n\tarmv7a->partnum = (midr >> 4) & 0xfff;\n\tarmv7a->arch = (midr >> 16) & 0xf;\n\tarmv7a->variant = (midr >> 20) & 0xf;\n\tarmv7a->implementor = (midr >> 24) & 0xff;\n\tLOG_DEBUG(\"%s rev %\" PRIx32 \", partnum %\" PRIx32 \", arch %\" PRIx32\n\t\t\t \", variant %\" PRIx32 \", implementor %\" PRIx32,\n\t\t target->cmd_name,\n\t\t armv7a->rev,\n\t\t armv7a->partnum,\n\t\t armv7a->arch,\n\t\t armv7a->variant,\n\t\t armv7a->implementor);\n\ndone:\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\nint armv7a_read_ttbcr(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tuint32_t ttbcr, ttbcr_n;\n\tint ttbidx;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/*  MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 2, 0, 2),\n\t\t\t&ttbcr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tLOG_DEBUG(\"ttbcr %\" PRIx32, ttbcr);\n\n\tttbcr_n = ttbcr & 0x7;\n\tarmv7a->armv7a_mmu.ttbcr = ttbcr;\n\tarmv7a->armv7a_mmu.cached = 1;\n\n\tfor (ttbidx = 0; ttbidx < 2; ttbidx++) {\n\t\t/*  MRC p15,0,<Rt>,c2,c0,ttbidx */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_MRC(15, 0, 0, 2, 0, ttbidx),\n\t\t\t\t&armv7a->armv7a_mmu.ttbr[ttbidx]);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\n\t/*\n\t * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),\n\t * document # ARM DDI 0406C\n\t */\n\tarmv7a->armv7a_mmu.ttbr_range[0]  = 0xffffffff >> ttbcr_n;\n\tarmv7a->armv7a_mmu.ttbr_range[1] = 0xffffffff;\n\tarmv7a->armv7a_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);\n\tarmv7a->armv7a_mmu.ttbr_mask[1] = 0xffffffff << 14;\n\tarmv7a->armv7a_mmu.cached = 1;\n\n\tretval = armv7a_read_midr(target);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* FIXME: why this special case based on part number? */\n\tif ((armv7a->partnum & 0xf) == 0) {\n\t\t/*  ARM DDI 0344H , ARM DDI 0407F */\n\t\tarmv7a->armv7a_mmu.ttbr_mask[0]  = 7 << (32 - ttbcr_n);\n\t}\n\n\tLOG_DEBUG(\"ttbr1 %s, ttbr0_mask %\" PRIx32 \" ttbr1_mask %\" PRIx32,\n\t\t  (ttbcr_n != 0) ? \"used\" : \"not used\",\n\t\t  armv7a->armv7a_mmu.ttbr_mask[0],\n\t\t  armv7a->armv7a_mmu.ttbr_mask[1]);\n\ndone:\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\n/* FIXME: remove it */\nstatic int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)\n{\n\tstruct armv7a_l2x_cache *l2x_cache;\n\tstruct target_list *head;\n\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tl2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache));\n\tl2x_cache->base = base;\n\tl2x_cache->way = way;\n\t/*LOG_INFO(\"cache l2 initialized base %x  way %d\",\n\tl2x_cache->base,l2x_cache->way);*/\n\tif (armv7a->armv7a_mmu.armv7a_cache.outer_cache)\n\t\tLOG_INFO(\"outer cache already initialized\\n\");\n\tarmv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;\n\t/*  initialize all target in this cluster (smp target)\n\t *  l2 cache must be configured after smp declaration */\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (curr != target) {\n\t\t\tarmv7a = target_to_armv7a(curr);\n\t\t\tif (armv7a->armv7a_mmu.armv7a_cache.outer_cache)\n\t\t\t\tLOG_ERROR(\"smp target : outer cache already initialized\\n\");\n\t\t\tarmv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;\n\t\t}\n\t}\n\treturn JIM_OK;\n}\n\n/* FIXME: remove it */\nCOMMAND_HANDLER(handle_cache_l2x)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t base, way;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* command_print(CMD, \"%s %s\", CMD_ARGV[0], CMD_ARGV[1]); */\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way);\n\n\t/* AP address is in bits 31:24 of DP_SELECT */\n\tarmv7a_l2x_cache_init(target, base, way);\n\n\treturn ERROR_OK;\n}\n\nint armv7a_handle_cache_info_command(struct command_invocation *cmd,\n\tstruct armv7a_cache_common *armv7a_cache)\n{\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a_cache->outer_cache);\n\n\tint cl;\n\n\tif (armv7a_cache->info == -1) {\n\t\tcommand_print(cmd, \"cache not yet identified\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (cl = 0; cl < armv7a_cache->loc; cl++) {\n\t\tstruct armv7a_arch_cache *arch = &(armv7a_cache->arch[cl]);\n\n\t\tif (arch->ctype & 1) {\n\t\t\tcommand_print(cmd,\n\t\t\t\t\"L%d I-Cache: linelen %\" PRIu32\n\t\t\t\t\", associativity %\" PRIu32\n\t\t\t\t\", nsets %\" PRIu32\n\t\t\t\t\", cachesize %\" PRIu32 \" KBytes\",\n\t\t\t\tcl+1,\n\t\t\t\tarch->i_size.linelen,\n\t\t\t\tarch->i_size.associativity,\n\t\t\t\tarch->i_size.nsets,\n\t\t\t\tarch->i_size.cachesize);\n\t\t}\n\n\t\tif (arch->ctype >= 2) {\n\t\t\tcommand_print(cmd,\n\t\t\t\t\"L%d D-Cache: linelen %\" PRIu32\n\t\t\t\t\", associativity %\" PRIu32\n\t\t\t\t\", nsets %\" PRIu32\n\t\t\t\t\", cachesize %\" PRIu32 \" KBytes\",\n\t\t\t\tcl+1,\n\t\t\t\tarch->d_u_size.linelen,\n\t\t\t\tarch->d_u_size.associativity,\n\t\t\t\tarch->d_u_size.nsets,\n\t\t\t\tarch->d_u_size.cachesize);\n\t\t}\n\t}\n\n\tif (l2x_cache)\n\t\tcommand_print(cmd, \"Outer unified cache Base Address 0x%\" PRIx32 \", %\" PRIu32 \" ways\",\n\t\t\tl2x_cache->base, l2x_cache->way);\n\n\treturn ERROR_OK;\n}\n\n/*  retrieve core id cluster id  */\nstatic int armv7a_read_mpidr(struct target *target)\n{\n\tint retval = ERROR_FAIL;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tuint32_t mpidr;\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\t/* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 0, 0, 5),\n\t\t\t&mpidr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* Is register in Multiprocessing Extensions register format? */\n\tif (mpidr & MPIDR_MP_EXT) {\n\t\tLOG_DEBUG(\"%s: MPIDR 0x%\" PRIx32, target_name(target), mpidr);\n\t\tarmv7a->multi_processor_system = (mpidr >> 30) & 1;\n\t\tarmv7a->multi_threading_processor = (mpidr >> 24) & 1;\n\t\tarmv7a->level2_id = (mpidr >> 16) & 0xf;\n\t\tarmv7a->cluster_id = (mpidr >> 8) & 0xf;\n\t\tarmv7a->cpu_id = mpidr & 0xf;\n\t\tLOG_INFO(\"%s: MPIDR level2 %x, cluster %x, core %x, %s, %s\",\n\t\t\ttarget_name(target),\n\t\t\tarmv7a->level2_id,\n\t\t\tarmv7a->cluster_id,\n\t\t\tarmv7a->cpu_id,\n\t\t\tarmv7a->multi_processor_system == 0 ? \"multi core\" : \"mono core\",\n\t\t\tarmv7a->multi_threading_processor == 1 ? \"SMT\" : \"no SMT\");\n\n\t} else\n\t\tLOG_ERROR(\"MPIDR not in multiprocessor format\");\n\ndone:\n\tdpm->finish(dpm);\n\treturn retval;\n\n\n}\n\nstatic int get_cache_info(struct arm_dpm *dpm, int cl, int ct, uint32_t *cache_reg)\n{\n\tint retval = ERROR_OK;\n\n\t/*  select cache level */\n\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_MCR(15, 2, 0, 0, 0, 0),\n\t\t\t(cl << 1) | (ct == 1 ? 1 : 0));\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 1, 0, 0, 0, 0),\n\t\t\tcache_reg);\n done:\n\treturn retval;\n}\n\nstatic struct armv7a_cachesize decode_cache_reg(uint32_t cache_reg)\n{\n\tstruct armv7a_cachesize size;\n\tint i = 0;\n\n\tsize.linelen = 16 << (cache_reg & 0x7);\n\tsize.associativity = ((cache_reg >> 3) & 0x3ff) + 1;\n\tsize.nsets = ((cache_reg >> 13) & 0x7fff) + 1;\n\tsize.cachesize = size.linelen * size.associativity * size.nsets / 1024;\n\n\t/*  compute info for set way operation on cache */\n\tsize.index_shift = (cache_reg & 0x7) + 4;\n\tsize.index = (cache_reg >> 13) & 0x7fff;\n\tsize.way = ((cache_reg >> 3) & 0x3ff);\n\n\twhile (((size.way << i) & 0x80000000) == 0)\n\t\ti++;\n\tsize.way_shift = i;\n\n\treturn size;\n}\n\nint armv7a_identify_cache(struct target *target)\n{\n\t/*  read cache descriptor */\n\tint retval = ERROR_FAIL;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tuint32_t csselr, clidr, ctr;\n\tuint32_t cache_reg;\n\tint cl, ctype;\n\tstruct armv7a_cache_common *cache =\n\t\t&(armv7a->armv7a_mmu.armv7a_cache);\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* retrieve CTR\n\t * mrc p15, 0, r0, c0, c0, 1\t\t@ read ctr */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 0, 0, 1),\n\t\t\t&ctr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tcache->iminline = 4UL << (ctr & 0xf);\n\tcache->dminline = 4UL << ((ctr & 0xf0000) >> 16);\n\tLOG_DEBUG(\"ctr %\" PRIx32 \" ctr.iminline %\" PRIu32 \" ctr.dminline %\" PRIu32,\n\t\t ctr, cache->iminline, cache->dminline);\n\n\t/*  retrieve CLIDR\n\t *  mrc\tp15, 1, r0, c0, c0, 1\t\t@ read clidr */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 1, 0, 0, 0, 1),\n\t\t\t&clidr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tcache->loc = (clidr & 0x7000000) >> 24;\n\tLOG_DEBUG(\"Number of cache levels to PoC %\" PRId32, cache->loc);\n\n\t/*  retrieve selected cache for later restore\n\t *  MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 2, 0, 0, 0, 0),\n\t\t\t&csselr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* retrieve all available inner caches */\n\tfor (cl = 0; cl < cache->loc; clidr >>= 3, cl++) {\n\n\t\t/* isolate cache type at current level */\n\t\tctype = clidr & 7;\n\n\t\t/* skip reserved values */\n\t\tif (ctype > CACHE_LEVEL_HAS_UNIFIED_CACHE)\n\t\t\tcontinue;\n\n\t\t/* separate d or unified d/i cache at this level ? */\n\t\tif (ctype & (CACHE_LEVEL_HAS_UNIFIED_CACHE | CACHE_LEVEL_HAS_D_CACHE)) {\n\t\t\t/* retrieve d-cache info */\n\t\t\tretval = get_cache_info(dpm, cl, 0, &cache_reg);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tcache->arch[cl].d_u_size = decode_cache_reg(cache_reg);\n\n\t\t\tLOG_DEBUG(\"data/unified cache index %\" PRIu32 \" << %\" PRIu32 \", way %\" PRIu32 \" << %\" PRIu32,\n\t\t\t\t\tcache->arch[cl].d_u_size.index,\n\t\t\t\t\tcache->arch[cl].d_u_size.index_shift,\n\t\t\t\t\tcache->arch[cl].d_u_size.way,\n\t\t\t\t\tcache->arch[cl].d_u_size.way_shift);\n\n\t\t\tLOG_DEBUG(\"cacheline %\" PRIu32 \" bytes %\" PRIu32 \" KBytes asso %\" PRIu32 \" ways\",\n\t\t\t\t\tcache->arch[cl].d_u_size.linelen,\n\t\t\t\t\tcache->arch[cl].d_u_size.cachesize,\n\t\t\t\t\tcache->arch[cl].d_u_size.associativity);\n\t\t}\n\n\t\t/* separate i-cache at this level ? */\n\t\tif (ctype & CACHE_LEVEL_HAS_I_CACHE) {\n\t\t\t/* retrieve i-cache info */\n\t\t\tretval = get_cache_info(dpm, cl, 1, &cache_reg);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tcache->arch[cl].i_size = decode_cache_reg(cache_reg);\n\n\t\t\tLOG_DEBUG(\"instruction cache index %\" PRIu32 \" << %\" PRIu32 \", way %\" PRIu32 \" << %\" PRIu32,\n\t\t\t\t\tcache->arch[cl].i_size.index,\n\t\t\t\t\tcache->arch[cl].i_size.index_shift,\n\t\t\t\t\tcache->arch[cl].i_size.way,\n\t\t\t\t\tcache->arch[cl].i_size.way_shift);\n\n\t\t\tLOG_DEBUG(\"cacheline %\" PRIu32 \" bytes %\" PRIu32 \" KBytes asso %\" PRIu32 \" ways\",\n\t\t\t\t\tcache->arch[cl].i_size.linelen,\n\t\t\t\t\tcache->arch[cl].i_size.cachesize,\n\t\t\t\t\tcache->arch[cl].i_size.associativity);\n\t\t}\n\n\t\tcache->arch[cl].ctype = ctype;\n\t}\n\n\t/*  restore selected cache  */\n\tdpm->instr_write_data_r0(dpm,\n\t\tARMV4_5_MRC(15, 2, 0, 0, 0, 0),\n\t\tcsselr);\n\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/*  if no l2 cache initialize l1 data cache flush function function */\n\tif (!armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache) {\n\t\tarmv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =\n\t\t\tarmv7a_cache_auto_flush_all_data;\n\t}\n\n\tarmv7a->armv7a_mmu.armv7a_cache.info = 1;\ndone:\n\tdpm->finish(dpm);\n\tarmv7a_read_mpidr(target);\n\treturn retval;\n\n}\n\nstatic int armv7a_setup_semihosting(struct target *target, int enable)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tuint32_t vcr;\n\tint ret;\n\n\tret = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t armv7a->debug_base + CPUDBG_VCR,\n\t\t\t\t\t &vcr);\n\tif (ret < 0) {\n\t\tLOG_ERROR(\"Failed to read VCR register\\n\");\n\t\treturn ret;\n\t}\n\n\tif (enable)\n\t\tvcr |= DBG_VCR_SVC_MASK;\n\telse\n\t\tvcr &= ~DBG_VCR_SVC_MASK;\n\n\tret = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t  armv7a->debug_base + CPUDBG_VCR,\n\t\t\t\t\t  vcr);\n\tif (ret < 0)\n\t\tLOG_ERROR(\"Failed to write VCR register\\n\");\n\n\treturn ret;\n}\n\nint armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)\n{\n\tstruct arm *arm = &armv7a->arm;\n\tarm->arch_info = armv7a;\n\ttarget->arch_info = &armv7a->arm;\n\tarm->setup_semihosting = armv7a_setup_semihosting;\n\t/*  target is useful in all function arm v4 5 compatible */\n\tarmv7a->arm.target = target;\n\tarmv7a->arm.common_magic = ARM_COMMON_MAGIC;\n\tarmv7a->common_magic = ARMV7_COMMON_MAGIC;\n\tarmv7a->armv7a_mmu.armv7a_cache.info = -1;\n\tarmv7a->armv7a_mmu.armv7a_cache.outer_cache = NULL;\n\tarmv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL;\n\tarmv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = 1;\n\treturn ERROR_OK;\n}\n\nint armv7a_arch_state(struct target *target)\n{\n\tstatic const char *state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\n\tif (armv7a->common_magic != ARMV7_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-ARMv7A target\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tarm_arch_state(target);\n\n\tif (armv7a->is_armv7r) {\n\t\tLOG_USER(\"D-Cache: %s, I-Cache: %s\",\n\t\t\tstate[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],\n\t\t\tstate[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);\n\t} else {\n\t\tLOG_USER(\"MMU: %s, D-Cache: %s, I-Cache: %s\",\n\t\t\tstate[armv7a->armv7a_mmu.mmu_enabled],\n\t\t\tstate[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],\n\t\t\tstate[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);\n\t}\n\n\tif (arm->core_mode == ARM_MODE_ABT)\n\t\tarmv7a_show_fault_registers(target);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration l2_cache_commands[] = {\n\t{\n\t\t.name = \"l2x\",\n\t\t.handler = handle_cache_l2x,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure l2x cache\",\n\t\t.usage = \"[base_addr] [number_of_way]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n\n};\n\nstatic const struct command_registration l2x_cache_command_handlers[] = {\n\t{\n\t\t.name = \"cache_config\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"cache configuration for a target\",\n\t\t.usage = \"\",\n\t\t.chain = l2_cache_commands,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration armv7a_command_handlers[] = {\n\t{\n\t\t.chain = l2x_cache_command_handlers,\n\t},\n\t{\n\t\t.chain = arm7a_cache_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *    Copyright (C) 2009 by David Brownell                                 *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV7A_H\n#define OPENOCD_TARGET_ARMV7A_H\n\n#include \"arm_adi_v5.h\"\n#include \"armv7a_cache.h\"\n#include \"arm.h\"\n#include \"armv4_5_mmu.h\"\n#include \"armv4_5_cache.h\"\n#include \"arm_dpm.h\"\n\nenum {\n\tARM_PC  = 15,\n\tARM_CPSR = 16\n};\n\n#define ARMV7_COMMON_MAGIC 0x0A450999U\n\n/* VA to PA translation operations opc2 values*/\n#define V2PCWPR  0\n#define V2PCWPW  1\n#define V2PCWUR  2\n#define V2PCWUW  3\n#define V2POWPR  4\n#define V2POWPW  5\n#define V2POWUR  6\n#define V2POWUW  7\n/*   L210/L220 cache controller support */\nstruct armv7a_l2x_cache {\n\tuint32_t base;\n\tuint32_t way;\n};\n\nstruct armv7a_cachesize {\n\t/*  cache dimensioning */\n\tuint32_t linelen;\n\tuint32_t associativity;\n\tuint32_t nsets;\n\tuint32_t cachesize;\n\t/* info for set way operation on cache */\n\tuint32_t index;\n\tuint32_t index_shift;\n\tuint32_t way;\n\tuint32_t way_shift;\n};\n\n/* information about one architecture cache at any level */\nstruct armv7a_arch_cache {\n\tint ctype;\t\t\t\t/* cache type, CLIDR encoding */\n\tstruct armv7a_cachesize d_u_size;\t/* data cache */\n\tstruct armv7a_cachesize i_size;\t\t/* instruction cache */\n};\n\n/* common cache information */\nstruct armv7a_cache_common {\n\tint info;\t\t\t\t/* -1 invalid, else valid */\n\tint loc;\t\t\t\t/* level of coherency */\n\tuint32_t dminline;\t\t\t/* minimum d-cache linelen */\n\tuint32_t iminline;\t\t\t/* minimum i-cache linelen */\n\tstruct armv7a_arch_cache arch[6];\t/* cache info, L1 - L7 */\n\tint i_cache_enabled;\n\tint d_u_cache_enabled;\n\tint auto_cache_enabled;\t\t\t/* openocd automatic\n\t\t\t\t\t\t * cache handling */\n\t/* outer unified cache if some */\n\tvoid *outer_cache;\n\tint (*flush_all_data_cache)(struct target *target);\n};\n\nstruct armv7a_mmu_common {\n\t/* following field mmu working way */\n\tint32_t cached;     /* 0: not initialized, 1: initialized */\n\tuint32_t ttbcr;     /* cache for ttbcr register */\n\tuint32_t ttbr[2];\n\tuint32_t ttbr_mask[2];\n\tuint32_t ttbr_range[2];\n\n\tint (*read_physical_memory)(struct target *target, target_addr_t address, uint32_t size,\n\t\t\tuint32_t count, uint8_t *buffer);\n\tstruct armv7a_cache_common armv7a_cache;\n\tuint32_t mmu_enabled;\n};\n\nstruct armv7a_common {\n\tunsigned int common_magic;\n\n\tstruct arm arm;\n\tstruct reg_cache *core_cache;\n\n\t/* Core Debug Unit */\n\tstruct arm_dpm dpm;\n\ttarget_addr_t debug_base;\n\tstruct adiv5_ap *debug_ap;\n\t/* mdir */\n\tuint8_t multi_processor_system;\n\tuint8_t multi_threading_processor;\n\tuint8_t level2_id;\n\tuint8_t cluster_id;\n\tuint8_t cpu_id;\n\tbool is_armv7r;\n\tuint32_t rev;\n\tuint32_t partnum;\n\tuint32_t arch;\n\tuint32_t variant;\n\tuint32_t implementor;\n\n\t/* cache specific to V7 Memory Management Unit compatible with v4_5*/\n\tstruct armv7a_mmu_common armv7a_mmu;\n\n\tint (*examine_debug_reason)(struct target *target);\n\tint (*post_debug_entry)(struct target *target);\n\n\tvoid (*pre_restore_context)(struct target *target);\n};\n\nstatic inline struct armv7a_common *\ntarget_to_armv7a(struct target *target)\n{\n\treturn container_of(target->arch_info, struct armv7a_common, arm);\n}\n\nstatic inline bool is_armv7a(struct armv7a_common *armv7a)\n{\n\treturn armv7a->common_magic == ARMV7_COMMON_MAGIC;\n}\n\n\n/* register offsets from armv7a.debug_base */\n\n/* See ARMv7a arch spec section C10.2 */\n#define CPUDBG_DIDR\t\t0x000\n\n/* See ARMv7a arch spec section C10.3 */\n#define CPUDBG_WFAR\t\t0x018\n/* PCSR at 0x084 -or- 0x0a0 -or- both ... based on flags in DIDR */\n#define CPUDBG_DSCR\t\t0x088\n#define CPUDBG_DRCR\t\t0x090\n#define CPUDBG_PRCR\t\t0x310\n#define CPUDBG_PRSR\t\t0x314\n\n/* See ARMv7a arch spec section C10.4 */\n#define CPUDBG_DTRRX\t\t0x080\n#define CPUDBG_ITR\t\t0x084\n#define CPUDBG_DTRTX\t\t0x08c\n\n/* See ARMv7a arch spec section C10.5 */\n#define CPUDBG_BVR_BASE\t\t0x100\n#define CPUDBG_BCR_BASE\t\t0x140\n#define CPUDBG_WVR_BASE\t\t0x180\n#define CPUDBG_WCR_BASE\t\t0x1C0\n#define CPUDBG_VCR\t\t0x01C\n\n/* See ARMv7a arch spec section C10.6 */\n#define CPUDBG_OSLAR\t\t0x300\n#define CPUDBG_OSLSR\t\t0x304\n#define CPUDBG_OSSRR\t\t0x308\n#define CPUDBG_ECR\t\t0x024\n\n/* See ARMv7a arch spec section C10.7 */\n#define CPUDBG_DSCCR\t\t0x028\n#define CPUDBG_DSMCR\t\t0x02C\n\n/* See ARMv7a arch spec section C10.8 */\n#define CPUDBG_AUTHSTATUS\t0xFB8\n\n/* See ARMv7a arch spec DDI 0406C C11.10 */\n#define CPUDBG_ID_PFR1\t\t0xD24\n\n/* Masks for Vector Catch register */\n#define DBG_VCR_FIQ_MASK\t((1 << 31) | (1 << 7))\n#define DBG_VCR_IRQ_MASK\t((1 << 30) | (1 << 6))\n#define DBG_VCR_DATA_ABORT_MASK\t((1 << 28) | (1 << 4))\n#define DBG_VCR_PREF_ABORT_MASK\t((1 << 27) | (1 << 3))\n#define DBG_VCR_SVC_MASK\t((1 << 26) | (1 << 2))\n\n/* Masks for Multiprocessor Affinity Register */\n#define MPIDR_MP_EXT\t\t(1UL << 31)\n\nint armv7a_arch_state(struct target *target);\nint armv7a_identify_cache(struct target *target);\nint armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a);\n\nint armv7a_handle_cache_info_command(struct command_invocation *cmd,\n\t\tstruct armv7a_cache_common *armv7a_cache);\nint armv7a_read_ttbcr(struct target *target);\n\nextern const struct command_registration armv7a_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARMV7A_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_cache.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Oleksij Rempel                                  *\n *   linux@rempel-privat.de                                                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"arm.h\"\n#include \"armv7a.h\"\n#include \"armv7a_cache.h\"\n#include <helper/time_support.h>\n#include \"arm_opcodes.h\"\n#include \"smp.h\"\n\nstatic int armv7a_l1_d_cache_sanity_check(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/*  check that cache data is on at target halt */\n\tif (!armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {\n\t\tLOG_DEBUG(\"data cache is not enabled\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int armv7a_l1_i_cache_sanity_check(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/*  check that cache data is on at target halt */\n\tif (!armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled) {\n\t\tLOG_DEBUG(\"instruction cache is not enabled\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int armv7a_l1_d_cache_flush_level(struct arm_dpm *dpm, struct armv7a_cachesize *size, int cl)\n{\n\tint retval = ERROR_OK;\n\tint32_t c_way, c_index = size->index;\n\n\tLOG_DEBUG(\"cl %\" PRId32, cl);\n\tdo {\n\t\tkeep_alive();\n\t\tc_way = size->way;\n\t\tdo {\n\t\t\tuint32_t value = (c_index << size->index_shift)\n\t\t\t\t| (c_way << size->way_shift) | (cl << 1);\n\t\t\t/*\n\t\t\t * DCCISW - Clean and invalidate data cache\n\t\t\t * line by Set/Way.\n\t\t\t */\n\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 14, 2),\n\t\t\t\t\tvalue);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tc_way -= 1;\n\t\t} while (c_way >= 0);\n\t\tc_index -= 1;\n\t} while (c_index >= 0);\n\n done:\n\tkeep_alive();\n\treturn retval;\n}\n\nstatic int armv7a_l1_d_cache_clean_inval_all(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tint cl;\n\tint retval;\n\n\tretval = armv7a_l1_d_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tfor (cl = 0; cl < cache->loc; cl++) {\n\t\t/* skip i-only caches */\n\t\tif (cache->arch[cl].ctype < CACHE_LEVEL_HAS_D_CACHE)\n\t\t\tcontinue;\n\n\t\tarmv7a_l1_d_cache_flush_level(dpm, &cache->arch[cl].d_u_size, cl);\n\t}\n\n\tretval = dpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"clean invalidate failed\");\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_cache_auto_flush_all_data(struct target *target)\n{\n\tint retval = ERROR_FAIL;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tif (curr->state == TARGET_HALTED)\n\t\t\t\tretval = armv7a_l1_d_cache_clean_inval_all(curr);\n\t\t}\n\t} else\n\t\tretval = armv7a_l1_d_cache_clean_inval_all(target);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* do outer cache flushing after inner caches have been flushed */\n\treturn arm7a_l2x_flush_all_data(target);\n}\n\n\nint armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tstruct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;\n\tuint32_t linelen = armv7a_cache->dminline;\n\tuint32_t va_line, va_end;\n\tint retval, i = 0;\n\n\tretval = armv7a_l1_d_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = virt & (-linelen);\n\tva_end = virt + size;\n\n\t/* handle unaligned start */\n\tif (virt != va_line) {\n\t\t/* DCCIMVAC */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\t/* handle unaligned end */\n\tif ((va_end & (linelen-1)) != 0) {\n\t\tva_end &= (-linelen);\n\t\t/* DCCIMVAC */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_end);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\n\twhile (va_line < va_end) {\n\t\tif ((i++ & 0x3f) == 0)\n\t\t\tkeep_alive();\n\t\t/* DCIMVAC - Invalidate data cache line by VA to PoC. */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 6, 1), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\tkeep_alive();\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\tkeep_alive();\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tunsigned int size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tstruct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;\n\tuint32_t linelen = armv7a_cache->dminline;\n\tuint32_t va_line, va_end;\n\tint retval, i = 0;\n\n\tretval = armv7a_l1_d_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = virt & (-linelen);\n\tva_end = virt + size;\n\n\twhile (va_line < va_end) {\n\t\tif ((i++ & 0x3f) == 0)\n\t\t\tkeep_alive();\n\t\t/* DCCMVAC - Data Cache Clean by MVA to PoC */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 10, 1), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\tkeep_alive();\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\tkeep_alive();\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tunsigned int size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tstruct armv7a_cache_common *armv7a_cache = &armv7a->armv7a_mmu.armv7a_cache;\n\tuint32_t linelen = armv7a_cache->dminline;\n\tuint32_t va_line, va_end;\n\tint retval, i = 0;\n\n\tretval = armv7a_l1_d_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = virt & (-linelen);\n\tva_end = virt + size;\n\n\twhile (va_line < va_end) {\n\t\tif ((i++ & 0x3f) == 0)\n\t\t\tkeep_alive();\n\t\t/* DCCIMVAC */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 14, 1), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\tkeep_alive();\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\tkeep_alive();\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_l1_i_cache_inval_all(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tint retval;\n\n\tretval = armv7a_l1_i_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tif (target->smp) {\n\t\t/* ICIALLUIS */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 1, 0), 0);\n\t} else {\n\t\t/* ICIALLU */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 0), 0);\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"i-cache invalidate failed\");\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tstruct armv7a_cache_common *armv7a_cache =\n\t\t\t\t&armv7a->armv7a_mmu.armv7a_cache;\n\tuint32_t linelen = armv7a_cache->iminline;\n\tuint32_t va_line, va_end;\n\tint retval, i = 0;\n\n\tretval = armv7a_l1_i_cache_sanity_check(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = virt & (-linelen);\n\tva_end = virt + size;\n\n\twhile (va_line < va_end) {\n\t\tif ((i++ & 0x3f) == 0)\n\t\t\tkeep_alive();\n\t\t/* ICIMVAU - Invalidate instruction cache by VA to PoU. */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 1), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\t/* BPIMVA */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 7), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\tkeep_alive();\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"i-cache invalidate failed\");\n\tkeep_alive();\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv7a_cache_flush_virt(struct target *target, uint32_t virt,\n\t\t\t\tuint32_t size)\n{\n\tarmv7a_l1_d_cache_flush_virt(target, virt, size);\n\tarmv7a_l2x_cache_flush_virt(target, virt, size);\n\n\treturn ERROR_OK;\n}\n\n/*\n * We assume that target core was chosen correctly. It means if same data\n * was handled by two cores, other core will loose the changes. Since it\n * is impossible to know (FIXME) which core has correct data, keep in mind\n * that some kind of data lost or corruption is possible.\n * Possible scenario:\n *  - core1 loaded and changed data on 0x12345678\n *  - we halted target and modified same data on core0\n *  - data on core1 will be lost.\n */\nint armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled)\n\t\treturn ERROR_OK;\n\n\treturn armv7a_cache_flush_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(arm7a_l1_cache_info_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\treturn armv7a_handle_cache_info_command(CMD,\n\t\t\t&armv7a->armv7a_mmu.armv7a_cache);\n}\n\nCOMMAND_HANDLER(armv7a_l1_d_cache_clean_inval_all_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tarmv7a_l1_d_cache_clean_inval_all(target);\n\n\treturn 0;\n}\n\nCOMMAND_HANDLER(arm7a_l1_d_cache_inval_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t virt, size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);\n\n\treturn armv7a_l1_d_cache_inval_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(arm7a_l1_d_cache_clean_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t virt, size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);\n\n\treturn armv7a_l1_d_cache_clean_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(armv7a_i_cache_clean_inval_all_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tarmv7a_l1_i_cache_inval_all(target);\n\n\treturn 0;\n}\n\nCOMMAND_HANDLER(arm7a_l1_i_cache_inval_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t virt, size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], virt);\n\n\treturn armv7a_l1_i_cache_inval_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(arm7a_cache_disable_auto_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (CMD_ARGC == 0) {\n\t\tcommand_print(CMD, \"auto cache is %s\",\n\t\t\tarmv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled ? \"enabled\" : \"disabled\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC == 1) {\n\t\tuint32_t set;\n\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], set);\n\t\tarmv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled = !!set;\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nstatic const struct command_registration arm7a_l1_d_cache_commands[] = {\n\t{\n\t\t.name = \"flush_all\",\n\t\t.handler = armv7a_l1_d_cache_clean_inval_all_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"flush (clean and invalidate) complete l1 d-cache\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"inval\",\n\t\t.handler = arm7a_l1_d_cache_inval_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"invalidate l1 d-cache by virtual address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\t{\n\t\t.name = \"clean\",\n\t\t.handler = arm7a_l1_d_cache_clean_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"clean l1 d-cache by virtual address address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm7a_l1_i_cache_commands[] = {\n\t{\n\t\t.name = \"inval_all\",\n\t\t.handler = armv7a_i_cache_clean_inval_all_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"invalidate complete l1 i-cache\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"inval\",\n\t\t.handler = arm7a_l1_i_cache_inval_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"invalidate l1 i-cache by virtual address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm7a_l1_di_cache_group_handlers[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = arm7a_l1_cache_info_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"print cache related information\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"d\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"l1 d-cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm7a_l1_d_cache_commands,\n\t},\n\t{\n\t\t.name = \"i\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"l1 i-cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm7a_l1_i_cache_commands,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration arm7a_cache_group_handlers[] = {\n\t{\n\t\t.name = \"auto\",\n\t\t.handler = arm7a_cache_disable_auto_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"disable or enable automatic cache handling.\",\n\t\t.usage = \"(1|0)\",\n\t},\n\t{\n\t\t.name = \"l1\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"l1 cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm7a_l1_di_cache_group_handlers,\n\t},\n\t{\n\t\t.chain = arm7a_l2x_cache_command_handler,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm7a_cache_command_handlers[] = {\n\t{\n\t\t.name = \"cache\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm7a_cache_group_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_cache.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 Oleksij Rempel                                     *\n *   linux@rempel-privat.de                                                *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM7A_CACHE_H\n#define OPENOCD_TARGET_ARM7A_CACHE_H\n\n#include \"arm_jtag.h\"\n#include \"armv7a_cache_l2x.h\"\n\nint armv7a_l1_d_cache_clean_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tunsigned int size);\nint armv7a_l1_d_cache_inval_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size);\nint armv7a_l1_d_cache_flush_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tunsigned int size);\nint armv7a_l1_i_cache_inval_all(struct target *target);\nint armv7a_l1_i_cache_inval_virt(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size);\nint armv7a_cache_auto_flush_on_write(struct target *target, uint32_t virt,\n\t\t\t\t\tuint32_t size);\nint armv7a_cache_auto_flush_all_data(struct target *target);\nint armv7a_cache_flush_virt(struct target *target, uint32_t virt,\n\t\t\t\tuint32_t size);\nextern const struct command_registration arm7a_cache_command_handlers[];\n\n/* CLIDR cache types */\n#define CACHE_LEVEL_HAS_UNIFIED_CACHE\t0x4\n#define CACHE_LEVEL_HAS_D_CACHE\t\t0x2\n#define CACHE_LEVEL_HAS_I_CACHE\t\t0x1\n\n#endif /* OPENOCD_TARGET_ARM7A_CACHE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_cache_l2x.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by Oleksij Rempel                                  *\n *   linux@rempel-privat.de                                                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"arm.h\"\n#include \"armv7a.h\"\n#include \"armv7a_cache.h\"\n#include <helper/time_support.h>\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"smp.h\"\n\nstatic int arm7a_l2x_sanity_check(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a->armv7a_mmu.armv7a_cache.outer_cache);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!l2x_cache || !l2x_cache->base) {\n\t\tLOG_DEBUG(\"l2x is not configured!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n/*\n * clean and invalidate complete l2x cache\n */\nint arm7a_l2x_flush_all_data(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a->armv7a_mmu.armv7a_cache.outer_cache);\n\tuint32_t l2_way_val;\n\tint retval;\n\n\tretval = arm7a_l2x_sanity_check(target);\n\tif (retval)\n\t\treturn retval;\n\n\tl2_way_val = (1 << l2x_cache->way) - 1;\n\n\treturn target_write_phys_u32(target,\n\t\t\tl2x_cache->base + L2X0_CLEAN_INV_WAY,\n\t\t\tl2_way_val);\n}\n\nint armv7a_l2x_cache_flush_virt(struct target *target, target_addr_t virt,\n\t\t\t\t\tuint32_t size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a->armv7a_mmu.armv7a_cache.outer_cache);\n\t/* FIXME: different controllers have different linelen? */\n\tuint32_t i, linelen = 32;\n\tint retval;\n\n\tretval = arm7a_l2x_sanity_check(target);\n\tif (retval)\n\t\treturn retval;\n\n\tfor (i = 0; i < size; i += linelen) {\n\t\ttarget_addr_t pa, offs = virt + i;\n\n\t\t/* FIXME: use less verbose virt2phys? */\n\t\tretval = target->type->virt2phys(target, offs, &pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tretval = target_write_phys_u32(target,\n\t\t\t\tl2x_cache->base + L2X0_CLEAN_INV_LINE_PA, pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\n\treturn retval;\n}\n\nstatic int armv7a_l2x_cache_inval_virt(struct target *target, target_addr_t virt,\n\t\t\t\t\tuint32_t size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a->armv7a_mmu.armv7a_cache.outer_cache);\n\t/* FIXME: different controllers have different linelen */\n\tuint32_t i, linelen = 32;\n\tint retval;\n\n\tretval = arm7a_l2x_sanity_check(target);\n\tif (retval)\n\t\treturn retval;\n\n\tfor (i = 0; i < size; i += linelen) {\n\t\ttarget_addr_t pa, offs = virt + i;\n\n\t\t/* FIXME: use less verbose virt2phys? */\n\t\tretval = target->type->virt2phys(target, offs, &pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tretval = target_write_phys_u32(target,\n\t\t\t\tl2x_cache->base + L2X0_INV_LINE_PA, pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\n\treturn retval;\n}\n\nstatic int armv7a_l2x_cache_clean_virt(struct target *target, target_addr_t virt,\n\t\t\t\t\tunsigned int size)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a->armv7a_mmu.armv7a_cache.outer_cache);\n\t/* FIXME: different controllers have different linelen */\n\tuint32_t i, linelen = 32;\n\tint retval;\n\n\tretval = arm7a_l2x_sanity_check(target);\n\tif (retval)\n\t\treturn retval;\n\n\tfor (i = 0; i < size; i += linelen) {\n\t\ttarget_addr_t pa, offs = virt + i;\n\n\t\t/* FIXME: use less verbose virt2phys? */\n\t\tretval = target->type->virt2phys(target, offs, &pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\n\t\tretval = target_write_phys_u32(target,\n\t\t\t\tl2x_cache->base + L2X0_CLEAN_LINE_PA, pa);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\n\treturn retval;\n}\n\nstatic int arm7a_handle_l2x_cache_info_command(struct command_invocation *cmd,\n\tstruct armv7a_cache_common *armv7a_cache)\n{\n\tstruct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)\n\t\t(armv7a_cache->outer_cache);\n\n\tif (armv7a_cache->info == -1) {\n\t\tcommand_print(cmd, \"cache not yet identified\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcommand_print(cmd,\n\t\t      \"L2 unified cache Base Address 0x%\" PRIx32 \", %\" PRIu32 \" ways\",\n\t\t      l2x_cache->base, l2x_cache->way);\n\n\treturn ERROR_OK;\n}\n\nstatic int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t way)\n{\n\tstruct armv7a_l2x_cache *l2x_cache;\n\tstruct target_list *head;\n\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tif (armv7a->armv7a_mmu.armv7a_cache.outer_cache) {\n\t\tLOG_ERROR(\"L2 cache was already initialised\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tl2x_cache = calloc(1, sizeof(struct armv7a_l2x_cache));\n\tl2x_cache->base = base;\n\tl2x_cache->way = way;\n\tarmv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;\n\n\t/*  initialize all targets in this cluster (smp target)\n\t *  l2 cache must be configured after smp declaration */\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (curr != target) {\n\t\t\tarmv7a = target_to_armv7a(curr);\n\t\t\tif (armv7a->armv7a_mmu.armv7a_cache.outer_cache) {\n\t\t\t\tLOG_ERROR(\"smp target : cache l2 already initialized\\n\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tarmv7a->armv7a_mmu.armv7a_cache.outer_cache = l2x_cache;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(arm7a_l2x_cache_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval;\n\n\tretval = arm7a_l2x_sanity_check(target);\n\tif (retval)\n\t\treturn retval;\n\n\treturn arm7a_handle_l2x_cache_info_command(CMD,\n\t\t\t&armv7a->armv7a_mmu.armv7a_cache);\n}\n\nCOMMAND_HANDLER(arm7a_l2x_cache_flush_all_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\treturn arm7a_l2x_flush_all_data(target);\n}\n\nCOMMAND_HANDLER(arm7a_l2x_cache_flush_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\ttarget_addr_t virt;\n\tuint32_t size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);\n\n\treturn armv7a_l2x_cache_flush_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(arm7a_l2x_cache_inval_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\ttarget_addr_t virt;\n\tuint32_t size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);\n\n\treturn armv7a_l2x_cache_inval_virt(target, virt, size);\n}\n\nCOMMAND_HANDLER(arm7a_l2x_cache_clean_virt_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\ttarget_addr_t virt;\n\tuint32_t size;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\telse\n\t\tsize = 1;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], virt);\n\n\treturn armv7a_l2x_cache_clean_virt(target, virt, size);\n}\n\n/* FIXME: should we configure way size? or controller type? */\nCOMMAND_HANDLER(armv7a_l2x_cache_conf_cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t base, way;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* command_print(CMD, \"%s %s\", CMD_ARGV[0], CMD_ARGV[1]); */\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way);\n\n\t/* AP address is in bits 31:24 of DP_SELECT */\n\treturn armv7a_l2x_cache_init(target, base, way);\n}\n\nstatic const struct command_registration arm7a_l2x_cache_commands[] = {\n\t{\n\t\t.name = \"conf\",\n\t\t.handler = armv7a_l2x_cache_conf_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure l2x cache\",\n\t\t.usage = \"<base_addr> <number_of_way>\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = arm7a_l2x_cache_info_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"print cache related information\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"flush_all\",\n\t\t.handler = arm7a_l2x_cache_flush_all_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"flush complete l2x cache\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"flush\",\n\t\t.handler = arm7a_l2x_cache_flush_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"flush (clean and invalidate) l2x cache by virtual address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\t{\n\t\t.name = \"inval\",\n\t\t.handler = arm7a_l2x_cache_inval_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"invalidate l2x cache by virtual address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\t{\n\t\t.name = \"clean\",\n\t\t.handler = arm7a_l2x_cache_clean_virt_cmd,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"clean l2x cache by virtual address address offset and range size\",\n\t\t.usage = \"<virt_addr> [size]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration arm7a_l2x_cache_command_handler[] = {\n\t{\n\t\t.name = \"l2x\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"l2x cache command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm7a_l2x_cache_commands,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_cache_l2x.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 Oleksij Rempel                                     *\n *   linux@rempel-privat.de                                                *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARM7A_CACHE_L2X_H\n#define OPENOCD_TARGET_ARM7A_CACHE_L2X_H\n\n#define L2X0_CACHE_LINE_SIZE\t\t32\n\n/* source: linux/arch/arm/include/asm/hardware/cache-l2x0.h */\n#define L2X0_CACHE_ID\t\t\t0x000\n#define L2X0_CACHE_TYPE\t\t\t0x004\n#define L2X0_CTRL\t\t\t0x100\n#define L2X0_AUX_CTRL\t\t\t0x104\n#define L2X0_TAG_LATENCY_CTRL\t\t0x108\n#define L2X0_DATA_LATENCY_CTRL\t\t0x10C\n#define L2X0_EVENT_CNT_CTRL\t\t0x200\n#define L2X0_EVENT_CNT1_CFG\t\t0x204\n#define L2X0_EVENT_CNT0_CFG\t\t0x208\n#define L2X0_EVENT_CNT1_VAL\t\t0x20C\n#define L2X0_EVENT_CNT0_VAL\t\t0x210\n#define L2X0_INTR_MASK\t\t\t0x214\n#define L2X0_MASKED_INTR_STAT\t\t0x218\n#define L2X0_RAW_INTR_STAT\t\t0x21C\n#define L2X0_INTR_CLEAR\t\t\t0x220\n#define L2X0_CACHE_SYNC\t\t\t0x730\n#define L2X0_DUMMY_REG\t\t\t0x740\n#define L2X0_INV_LINE_PA\t\t0x770\n#define L2X0_INV_WAY\t\t\t0x77C\n#define L2X0_CLEAN_LINE_PA\t\t0x7B0\n#define L2X0_CLEAN_LINE_IDX\t\t0x7B8\n#define L2X0_CLEAN_WAY\t\t\t0x7BC\n#define L2X0_CLEAN_INV_LINE_PA\t\t0x7F0\n#define L2X0_CLEAN_INV_LINE_IDX\t\t0x7F8\n#define L2X0_CLEAN_INV_WAY\t\t0x7FC\n/*\n * The lockdown registers repeat 8 times for L310, the L210 has only one\n * D and one I lockdown register at 0x0900 and 0x0904.\n */\n#define L2X0_LOCKDOWN_WAY_D_BASE\t0x900\n#define L2X0_LOCKDOWN_WAY_I_BASE\t0x904\n#define L2X0_LOCKDOWN_STRIDE\t\t0x08\n#define L2X0_ADDR_FILTER_START\t\t0xC00\n#define L2X0_ADDR_FILTER_END\t\t0xC04\n#define L2X0_TEST_OPERATION\t\t0xF00\n#define L2X0_LINE_DATA\t\t\t0xF10\n#define L2X0_LINE_TAG\t\t\t0xF30\n#define L2X0_DEBUG_CTRL\t\t\t0xF40\n#define L2X0_PREFETCH_CTRL\t\t0xF60\n#define L2X0_POWER_CTRL\t\t\t0xF80\n#define   L2X0_DYNAMIC_CLK_GATING_EN\t(1 << 1)\n#define   L2X0_STNDBY_MODE_EN\t\t(1 << 0)\n\n/* Registers shifts and masks */\n#define L2X0_CACHE_ID_PART_MASK\t\t(0xf << 6)\n#define L2X0_CACHE_ID_PART_L210\t\t(1 << 6)\n#define L2X0_CACHE_ID_PART_L310\t\t(3 << 6)\n#define L2X0_CACHE_ID_RTL_MASK\t\t0x3f\n#define L2X0_CACHE_ID_RTL_R0P0\t\t0x0\n#define L2X0_CACHE_ID_RTL_R1P0\t\t0x2\n#define L2X0_CACHE_ID_RTL_R2P0\t\t0x4\n#define L2X0_CACHE_ID_RTL_R3P0\t\t0x5\n#define L2X0_CACHE_ID_RTL_R3P1\t\t0x6\n#define L2X0_CACHE_ID_RTL_R3P2\t\t0x8\n\n#define L2X0_AUX_CTRL_MASK\t\t\t0xc0000fff\n#define L2X0_AUX_CTRL_DATA_RD_LATENCY_SHIFT\t0\n#define L2X0_AUX_CTRL_DATA_RD_LATENCY_MASK\t0x7\n#define L2X0_AUX_CTRL_DATA_WR_LATENCY_SHIFT\t3\n#define L2X0_AUX_CTRL_DATA_WR_LATENCY_MASK\t(0x7 << 3)\n#define L2X0_AUX_CTRL_TAG_LATENCY_SHIFT\t\t6\n#define L2X0_AUX_CTRL_TAG_LATENCY_MASK\t\t(0x7 << 6)\n#define L2X0_AUX_CTRL_DIRTY_LATENCY_SHIFT\t9\n#define L2X0_AUX_CTRL_DIRTY_LATENCY_MASK\t(0x7 << 9)\n#define L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT\t16\n#define L2X0_AUX_CTRL_WAY_SIZE_SHIFT\t\t17\n#define L2X0_AUX_CTRL_WAY_SIZE_MASK\t\t(0x7 << 17)\n#define L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT\t22\n#define L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT\t\t26\n#define L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT\t\t27\n#define L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT\t28\n#define L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT\t29\n#define L2X0_AUX_CTRL_EARLY_BRESP_SHIFT\t\t30\n\n#define L2X0_LATENCY_CTRL_SETUP_SHIFT\t0\n#define L2X0_LATENCY_CTRL_RD_SHIFT\t4\n#define L2X0_LATENCY_CTRL_WR_SHIFT\t8\n\n#define L2X0_ADDR_FILTER_EN\t\t1\n\n#define L2X0_CTRL_EN\t\t\t1\n\n#define L2X0_WAY_SIZE_SHIFT\t\t3\n\nstruct l2x0_regs {\n\tunsigned long phy_base;\n\tunsigned long aux_ctrl;\n\t/*\n\t * Whether the following registers need to be saved/restored\n\t * depends on platform\n\t */\n\tunsigned long tag_latency;\n\tunsigned long data_latency;\n\tunsigned long filter_start;\n\tunsigned long filter_end;\n\tunsigned long prefetch_ctrl;\n\tunsigned long pwr_ctrl;\n\tunsigned long ctrl;\n\tunsigned long aux2_ctrl;\n};\n\nstruct outer_cache_fns {\n\tvoid (*inv_range)(unsigned long, unsigned long);\n\tvoid (*clean_range)(unsigned long, unsigned long);\n\tvoid (*flush_range)(unsigned long, unsigned long);\n\tvoid (*flush_all)(void);\n\tvoid (*disable)(void);\n\n\tvoid (*resume)(void);\n\n\t/* This is an ARM L2C thing */\n\tvoid (*write_sec)(unsigned long, unsigned);\n\tvoid (*configure)(const struct l2x0_regs *);\n};\n\nstruct l2c_init_data {\n\tconst char *type;\n\tunsigned way_size_0;\n\tunsigned num_lock;\n\n\tvoid (*enable)(uint32_t, uint32_t, unsigned);\n\tvoid (*fixup)(uint32_t, uint32_t, struct outer_cache_fns *);\n\tvoid (*save)(uint32_t);\n\tvoid (*configure)(uint32_t);\n\tstruct outer_cache_fns outer_cache;\n};\n\nextern const struct command_registration arm7a_l2x_cache_command_handler[];\n\nint armv7a_l2x_cache_flush_virt(struct target *target, target_addr_t virt,\n\t\t\t\t\tuint32_t size);\nint arm7a_l2x_flush_all_data(struct target *target);\n\n#endif /* OPENOCD_TARGET_ARM7A_CACHE_L2X_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_mmu.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *   matthias.welwarsky@sysgo.com                                          *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011 michel.jaouen@stericsson.com        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n\n#include \"jtag/interface.h\"\n#include \"arm.h\"\n#include \"armv7a.h\"\n#include \"armv7a_mmu.h\"\n#include \"arm_opcodes.h\"\n#include \"cortex_a.h\"\n\n#define SCTLR_BIT_AFE (1 << 29)\n\n/*  V7 method VA TO PA  */\nint armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,\n\ttarget_addr_t *val, int meminfo)\n{\n\tint retval = ERROR_FAIL;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm_dpm *dpm = armv7a->arm.dpm;\n\tuint32_t virt = va & ~0xfff, value;\n\tuint32_t NOS, NS, INNER, OUTER, SS;\n\t*val = 0xdeadbeef;\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\t/*  mmu must be enable in order to get a correct translation\n\t *  use VA to PA CP15 register for conversion */\n\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_MCR(15, 0, 0, 7, 8, 0),\n\t\t\tvirt);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 7, 4, 0),\n\t\t\t&value);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* decode memory attribute */\n\tSS = (value >> 1) & 1;\n\tNOS = (value >> 10) & 1;\t/*  Not Outer shareable */\n\tNS = (value >> 9) & 1;\t/* Non secure */\n\tINNER = (value >> 4) &  0x7;\n\tOUTER = (value >> 2) & 0x3;\n\n\tif (SS) {\n\t\t/* PAR[31:24] contains PA[31:24] */\n\t\t*val = value & 0xff000000;\n\t\t/* PAR [23:16] contains PA[39:32] */\n\t\t*val |= (target_addr_t)(value & 0x00ff0000) << 16;\n\t\t/* PA[23:12] is the same as VA[23:12] */\n\t\t*val |= (va & 0xffffff);\n\t} else {\n\t\t*val = (value & ~0xfff)  +  (va & 0xfff);\n\t}\n\tif (meminfo) {\n\t\tLOG_INFO(\"%\" PRIx32 \" : %\" TARGET_PRIxADDR \" %s outer shareable %s secured %s super section\",\n\t\t\tva, *val,\n\t\t\tNOS == 1 ? \"not\" : \" \",\n\t\t\tNS == 1 ? \"not\" : \"\",\n\t\t\tSS == 0 ? \"not\" : \"\");\n\t\tswitch (OUTER) {\n\t\t\tcase 0:\n\t\t\t\tLOG_INFO(\"outer: Non-Cacheable\");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tLOG_INFO(\"outer: Write-Back, Write-Allocate\");\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tLOG_INFO(\"outer: Write-Through, No Write-Allocate\");\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tLOG_INFO(\"outer: Write-Back, no Write-Allocate\");\n\t\t\t\tbreak;\n\t\t}\n\t\tswitch (INNER) {\n\t\t\tcase 0:\n\t\t\t\tLOG_INFO(\"inner: Non-Cacheable\");\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tLOG_INFO(\"inner: Strongly-ordered\");\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\tLOG_INFO(\"inner: Device\");\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\tLOG_INFO(\"inner: Write-Back, Write-Allocate\");\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tLOG_INFO(\"inner:  Write-Through\");\n\t\t\t\tbreak;\n\t\t\tcase 7:\n\t\t\t\tLOG_INFO(\"inner: Write-Back, no Write-Allocate\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_INFO(\"inner: %\" PRIx32 \" ???\", INNER);\n\t\t}\n\t}\n\ndone:\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nstatic const char *desc_bits_to_string(bool c_bit, bool b_bit, bool s_bit, bool ap2, int ap10, bool afe)\n{\n\tstatic char bits_string[64];\n\tunsigned int len;\n\n\tif (afe) {\n\t\tbool acc_r = true;\n\t\tbool acc_w = !ap2;\n\t\tbool priv = !(ap10 & 2);\n\t\tlen = snprintf(bits_string, sizeof(bits_string), \"%s%s%s access%s: %s%s\",\n\t\t\t\t\t   s_bit ? \"S \" : \"\", c_bit ? \"C \" : \"\", b_bit ? \"B \" : \"\",\n\t\t\t\t priv ? \"(priv)\" : \"\", acc_r ? \"R\" : \"N\", acc_w ? \"W \" : \"O \");\n\t} else {\n\t\tbool priv_acc_w = !ap2;\n\t\tbool priv_acc_r = true;\n\t\tbool unpriv_acc_w = priv_acc_w;\n\t\tbool unpriv_acc_r = priv_acc_r;\n\n\t\tswitch (ap10) {\n\t\tcase 0:\n\t\t\tpriv_acc_r = priv_acc_w = false;\n\t\t\tunpriv_acc_r = unpriv_acc_w = false;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tunpriv_acc_r = unpriv_acc_w = false;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tunpriv_acc_w = false;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\n\t\tlen = snprintf(bits_string, sizeof(bits_string), \"%s%s%s access(priv): %s%s access(unpriv): %s%s\",\n\t\t\t\ts_bit ? \"S \" : \"\", c_bit ? \"C \" : \"\", b_bit ? \"B \" : \"\", priv_acc_r ? \"R\" : \"N\", priv_acc_w ? \"W\" : \"O\",\n\t\t\t\tunpriv_acc_r ? \"R\" : \"N\", unpriv_acc_w ? \"W\" : \"O\");\n\t}\n\n\tif (len >= sizeof(bits_string))\n\t\tbits_string[63] = 0;\n\n\treturn bits_string;\n}\n\nstatic const char *l2_desc_bits_to_string(uint32_t l2_desc, bool afe)\n{\n\tbool c_bit = !!(l2_desc & (1 << 3));\n\tbool b_bit = !!(l2_desc & (1 << 2));\n\tbool s_bit = !!(l2_desc & (1 << 10));\n\tbool ap2 = !!(l2_desc & (1 << 9));\n\tint ap10 = (l2_desc >> 4) & 3;\n\n\treturn desc_bits_to_string(c_bit, b_bit, s_bit, ap2, ap10, afe);\n}\n\nstatic const char *l1_desc_bits_to_string(uint32_t l1_desc, bool afe)\n{\n\tbool c_bit = !!(l1_desc & (1 << 3));\n\tbool b_bit = !!(l1_desc & (1 << 2));\n\tbool s_bit = !!(l1_desc & (1 << 16));\n\tbool ap2 = !!(l1_desc & (1 << 15));\n\tint ap10 = (l1_desc >> 10) & 3;\n\n\treturn desc_bits_to_string(c_bit, b_bit, s_bit, ap2, ap10, afe);\n}\n\nCOMMAND_HANDLER(armv7a_mmu_dump_table)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct armv7a_mmu_common *mmu = &armv7a->armv7a_mmu;\n\tstruct armv7a_cache_common *cache = &mmu->armv7a_cache;\n\tuint32_t *first_lvl_ptbl;\n\ttarget_addr_t ttb;\n\tint ttbidx = 0;\n\tint retval;\n\tint pt_idx;\n\tint max_pt_idx = 4095;\n\tbool afe;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!strcmp(CMD_ARGV[0], \"addr\")) {\n\t\tif (CMD_ARGC < 2)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tCOMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[1], ttb);\n\n\t\tif (CMD_ARGC > 2) {\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[2], max_pt_idx);\n\n\t\t\tif (max_pt_idx < 1 || max_pt_idx > 4096)\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t\tmax_pt_idx -= 1;\n\t\t}\n\t} else {\n\t\tif (mmu->cached != 1) {\n\t\t\tLOG_ERROR(\"TTB not cached!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], ttbidx);\n\t\tif (ttbidx < 0 || ttbidx > 1)\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\t\tttb = mmu->ttbr[ttbidx] & mmu->ttbr_mask[ttbidx];\n\n\t\tif (ttbidx == 0) {\n\t\t\tint ttbcr_n = mmu->ttbcr & 0x7;\n\t\t\tmax_pt_idx = 0x0fff >> ttbcr_n;\n\t\t}\n\t}\n\n\tLOG_USER(\"Page Directory at (phys): %8.8\" TARGET_PRIxADDR, ttb);\n\n\tfirst_lvl_ptbl = malloc(sizeof(uint32_t)*(max_pt_idx+1));\n\tif (!first_lvl_ptbl)\n\t\treturn ERROR_FAIL;\n\n\t/*\n\t * this may or may not be necessary depending on whether\n\t * the table walker is configured to use the cache or not.\n\t */\n\tcache->flush_all_data_cache(target);\n\n\tretval = mmu->read_physical_memory(target, ttb, 4, max_pt_idx+1, (uint8_t *)first_lvl_ptbl);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read first-level page table!\");\n\t\treturn retval;\n\t}\n\n\tafe = !!(cortex_a->cp15_control_reg & SCTLR_BIT_AFE);\n\n\tfor (pt_idx = 0; pt_idx <= max_pt_idx;) {\n\t\tuint32_t first_lvl_descriptor = target_buffer_get_u32(target,\n\t\t\t\t\t\t(uint8_t *)&first_lvl_ptbl[pt_idx]);\n\n\t\tLOG_DEBUG(\"L1 desc[%8.8x]: %8.8\"PRIx32, pt_idx << 20, first_lvl_descriptor);\n\n\t\t/* skip empty entries in the first level table */\n\t\tif ((first_lvl_descriptor & 3) == 0) {\n\t\t\tpt_idx++;\n\t\t} else\n\t\tif ((first_lvl_descriptor & 0x40002) == 2) {\n\t\t\t/* section descriptor */\n\t\t\tuint32_t va_range = 1024*1024-1; /* 1MB range */\n\t\t\tuint32_t va_start = pt_idx << 20;\n\t\t\tuint32_t va_end = va_start + va_range;\n\n\t\t\tuint32_t pa_start = (first_lvl_descriptor & 0xfff00000);\n\t\t\tuint32_t pa_end = pa_start + va_range;\n\n\t\t\tLOG_USER(\"SECT: VA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"]: PA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"] %s\",\n\t\t\t\tva_start, va_end, pa_start, pa_end, l1_desc_bits_to_string(first_lvl_descriptor, afe));\n\t\t\tpt_idx++;\n\t\t} else\n\t\tif ((first_lvl_descriptor & 0x40002) == 0x40002) {\n\t\t\t/* supersection descriptor */\n\t\t\tuint32_t va_range = 16*1024*1024-1; /* 16MB range */\n\t\t\tuint32_t va_start = pt_idx << 20;\n\t\t\tuint32_t va_end = va_start + va_range;\n\n\t\t\tuint32_t pa_start = (first_lvl_descriptor & 0xff000000);\n\t\t\tuint32_t pa_end = pa_start + va_range;\n\n\t\t\tLOG_USER(\"SSCT: VA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"]: PA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"] %s\",\n\t\t\t\tva_start, va_end, pa_start, pa_end, l1_desc_bits_to_string(first_lvl_descriptor, afe));\n\n\t\t\t/* skip next 15 entries, they're duplicating the first entry */\n\t\t\tpt_idx += 16;\n\t\t} else {\n\t\t\ttarget_addr_t second_lvl_ptbl = first_lvl_descriptor & 0xfffffc00;\n\t\t\tuint32_t second_lvl_descriptor;\n\t\t\tuint32_t *pt2;\n\t\t\tint pt2_idx;\n\n\t\t\t/* page table, always 1KB long */\n\t\t\tpt2 = malloc(1024);\n\t\t\tretval = mmu->read_physical_memory(target, second_lvl_ptbl,\n\t\t\t\t\t\t  4, 256, (uint8_t *)pt2);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to read second-level page table!\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tfor (pt2_idx = 0; pt2_idx < 256; ) {\n\t\t\t\tsecond_lvl_descriptor = target_buffer_get_u32(target,\n\t\t\t\t\t\t(uint8_t *)&pt2[pt2_idx]);\n\n\t\t\t\tif ((second_lvl_descriptor & 3) == 0) {\n\t\t\t\t\t/* skip entry */\n\t\t\t\t\tpt2_idx++;\n\t\t\t\t} else\n\t\t\t\tif ((second_lvl_descriptor & 3) == 1) {\n\t\t\t\t\t/* large page */\n\t\t\t\t\tuint32_t va_range = 64*1024-1; /* 64KB range */\n\t\t\t\t\tuint32_t va_start = (pt_idx << 20) + (pt2_idx << 12);\n\t\t\t\t\tuint32_t va_end = va_start + va_range;\n\n\t\t\t\t\tuint32_t pa_start = (second_lvl_descriptor & 0xffff0000);\n\t\t\t\t\tuint32_t pa_end = pa_start + va_range;\n\n\t\t\t\t\tLOG_USER(\"LPGE: VA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"]: PA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"] %s\",\n\t\t\t\t\t\tva_start, va_end, pa_start, pa_end, l2_desc_bits_to_string(second_lvl_descriptor, afe));\n\n\t\t\t\t\tpt2_idx += 16;\n\t\t\t\t} else {\n\t\t\t\t\t/* small page */\n\t\t\t\t\tuint32_t va_range = 4*1024-1; /* 4KB range */\n\t\t\t\t\tuint32_t va_start = (pt_idx << 20) + (pt2_idx << 12);\n\t\t\t\t\tuint32_t va_end = va_start + va_range;\n\n\t\t\t\t\tuint32_t pa_start = (second_lvl_descriptor & 0xfffff000);\n\t\t\t\t\tuint32_t pa_end = pa_start + va_range;\n\n\t\t\t\t\tLOG_USER(\"SPGE: VA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"]: PA[%8.8\"PRIx32\" -- %8.8\"PRIx32\"] %s\",\n\t\t\t\t\t\tva_start, va_end, pa_start, pa_end, l2_desc_bits_to_string(second_lvl_descriptor, afe));\n\n\t\t\t\t\tpt2_idx++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfree(pt2);\n\t\t\tpt_idx++;\n\t\t}\n\t}\n\n\tfree(first_lvl_ptbl);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration armv7a_mmu_group_handlers[] = {\n\t{\n\t\t.name = \"dump\",\n\t\t.handler = armv7a_mmu_dump_table,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"dump translation table 0, 1 or from <address>\",\n\t\t.usage = \"(0|1|addr <address> [num_entries])\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration armv7a_mmu_command_handlers[] = {\n\t{\n\t\t.name = \"mmu\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mmu command group\",\n\t\t.usage = \"\",\n\t\t.chain = armv7a_mmu_group_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7a_mmu.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *   matthias.welwarsky@sysgo.com                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV7A_MMU_H\n#define OPENOCD_TARGET_ARMV7A_MMU_H\n\nextern int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,\n\ttarget_addr_t *val, int meminfo);\n\nextern const struct command_registration armv7a_mmu_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARMV7A_MMU_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7m.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n *                                                                         *\n *   Copyright (C) 2019 by Tomas Vanek                                     *\n *   vanekt@fbl.cz                                                         *\n *                                                                         *\n *   ARMv7-M Architecture, Application Level Reference Manual              *\n *              ARM DDI 0405C (September 2008)                             *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"armv7m.h\"\n#include \"algorithm.h\"\n#include \"register.h\"\n#include \"semihosting_common.h\"\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n\n#if 0\n#define _DEBUG_INSTRUCTION_EXECUTION_\n#endif\n\nstatic const char * const armv7m_exception_strings[] = {\n\t\"\", \"Reset\", \"NMI\", \"HardFault\",\n\t\"MemManage\", \"BusFault\", \"UsageFault\", \"SecureFault\",\n\t\"RESERVED\", \"RESERVED\", \"RESERVED\", \"SVCall\",\n\t\"DebugMonitor\", \"RESERVED\", \"PendSV\", \"SysTick\"\n};\n\n/* PSP is used in some thread modes */\nconst int armv7m_psp_reg_map[ARMV7M_NUM_CORE_REGS] = {\n\tARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3,\n\tARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,\n\tARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,\n\tARMV7M_R12, ARMV7M_PSP, ARMV7M_R14, ARMV7M_PC,\n\tARMV7M_XPSR,\n};\n\n/* MSP is used in handler and some thread modes */\nconst int armv7m_msp_reg_map[ARMV7M_NUM_CORE_REGS] = {\n\tARMV7M_R0, ARMV7M_R1, ARMV7M_R2, ARMV7M_R3,\n\tARMV7M_R4, ARMV7M_R5, ARMV7M_R6, ARMV7M_R7,\n\tARMV7M_R8, ARMV7M_R9, ARMV7M_R10, ARMV7M_R11,\n\tARMV7M_R12, ARMV7M_MSP, ARMV7M_R14, ARMV7M_PC,\n\tARMV7M_XPSR,\n};\n\n/*\n * These registers are not memory-mapped.  The ARMv7-M profile includes\n * memory mapped registers too, such as for the NVIC (interrupt controller)\n * and SysTick (timer) modules; those can mostly be treated as peripherals.\n *\n * The ARMv6-M profile is almost identical in this respect, except that it\n * doesn't include basepri or faultmask registers.\n */\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tunsigned bits;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n} armv7m_regs[] = {\n\t{ ARMV7M_R0, \"r0\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R1, \"r1\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R2, \"r2\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R3, \"r3\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R4, \"r4\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R5, \"r5\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R6, \"r6\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R7, \"r7\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R8, \"r8\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R9, \"r9\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R10, \"r10\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R11, \"r11\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R12, \"r12\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R13, \"sp\", 32, REG_TYPE_DATA_PTR, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_R14, \"lr\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_PC, \"pc\", 32, REG_TYPE_CODE_PTR, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\t{ ARMV7M_XPSR, \"xpsr\", 32, REG_TYPE_INT, \"general\", \"org.gnu.gdb.arm.m-profile\" },\n\n\t{ ARMV7M_MSP, \"msp\", 32, REG_TYPE_DATA_PTR, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\t{ ARMV7M_PSP, \"psp\", 32, REG_TYPE_DATA_PTR, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\n\t/* A working register for packing/unpacking special regs, hidden from gdb */\n\t{ ARMV7M_PMSK_BPRI_FLTMSK_CTRL, \"pmsk_bpri_fltmsk_ctrl\", 32, REG_TYPE_INT, NULL, NULL },\n\n\t/* WARNING: If you use armv7m_write_core_reg() on one of 4 following\n\t * special registers, the new data go to ARMV7M_PMSK_BPRI_FLTMSK_CTRL\n\t * cache only and are not flushed to CPU HW register.\n\t * To trigger write to CPU HW register, add\n\t *\t\tarmv7m_write_core_reg(,,ARMV7M_PMSK_BPRI_FLTMSK_CTRL,);\n\t */\n\t{ ARMV7M_PRIMASK, \"primask\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\t{ ARMV7M_BASEPRI, \"basepri\", 8, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\t{ ARMV7M_FAULTMASK, \"faultmask\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\t{ ARMV7M_CONTROL, \"control\", 3, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.m-system\" },\n\n\t/* ARMv8-M security extension (TrustZone) specific registers */\n\t{ ARMV8M_MSP_NS, \"msp_ns\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_PSP_NS, \"psp_ns\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_MSP_S, \"msp_s\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_PSP_S, \"psp_s\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_MSPLIM_S, \"msplim_s\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_PSPLIM_S, \"psplim_s\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_MSPLIM_NS, \"msplim_ns\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_PSPLIM_NS, \"psplim_ns\", 32, REG_TYPE_DATA_PTR, \"stack\", \"org.gnu.gdb.arm.secext\" },\n\n\t{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S, \"pmsk_bpri_fltmsk_ctrl_s\", 32, REG_TYPE_INT, NULL, NULL },\n\t{ ARMV8M_PRIMASK_S, \"primask_s\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_BASEPRI_S, \"basepri_s\", 8, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_FAULTMASK_S, \"faultmask_s\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_CONTROL_S, \"control_s\", 3, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\n\t{ ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS, \"pmsk_bpri_fltmsk_ctrl_ns\", 32, REG_TYPE_INT, NULL, NULL },\n\t{ ARMV8M_PRIMASK_NS, \"primask_ns\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_BASEPRI_NS, \"basepri_ns\", 8, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_FAULTMASK_NS, \"faultmask_ns\", 1, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\t{ ARMV8M_CONTROL_NS, \"control_ns\", 3, REG_TYPE_INT8, \"system\", \"org.gnu.gdb.arm.secext\" },\n\n\t/* FPU registers */\n\t{ ARMV7M_D0, \"d0\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D1, \"d1\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D2, \"d2\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D3, \"d3\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D4, \"d4\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D5, \"d5\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D6, \"d6\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D7, \"d7\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D8, \"d8\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D9, \"d9\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D10, \"d10\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D11, \"d11\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D12, \"d12\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D13, \"d13\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D14, \"d14\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\t{ ARMV7M_D15, \"d15\", 64, REG_TYPE_IEEE_DOUBLE, \"float\", \"org.gnu.gdb.arm.vfp\" },\n\n\t{ ARMV7M_FPSCR, \"fpscr\", 32, REG_TYPE_INT, \"float\", \"org.gnu.gdb.arm.vfp\" },\n};\n\n#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)\n\n/**\n * Restores target context using the cache of core registers set up\n * by armv7m_build_reg_cache(), calling optional core-specific hooks.\n */\nint armv7m_restore_context(struct target *target)\n{\n\tint i;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct reg_cache *cache = armv7m->arm.core_cache;\n\n\tLOG_DEBUG(\" \");\n\n\tif (armv7m->pre_restore_context)\n\t\tarmv7m->pre_restore_context(target);\n\n\t/* The descending order of register writes is crucial for correct\n\t * packing of ARMV7M_PMSK_BPRI_FLTMSK_CTRL!\n\t * See also comments in the register table above */\n\tfor (i = cache->num_regs - 1; i >= 0; i--) {\n\t\tstruct reg *r = &cache->reg_list[i];\n\n\t\tif (r->exist && r->dirty) {\n\t\t\tint retval = armv7m->arm.write_core_reg(target, r, i, ARM_MODE_ANY, r->value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Core state functions */\n\n/**\n * Maps ISR number (from xPSR) to name.\n * Note that while names and meanings for the first sixteen are standardized\n * (with zero not a true exception), external interrupts are only numbered.\n * They are assigned by vendors, which generally assign different numbers to\n * peripherals (such as UART0 or a USB peripheral controller).\n */\nconst char *armv7m_exception_string(int number)\n{\n\tstatic char enamebuf[32];\n\n\tif ((number < 0) | (number > 511))\n\t\treturn \"Invalid exception\";\n\tif (number < 16)\n\t\treturn armv7m_exception_strings[number];\n\tsprintf(enamebuf, \"External Interrupt(%i)\", number - 16);\n\treturn enamebuf;\n}\n\nstatic int armv7m_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct arm_reg *armv7m_reg = reg->arch_info;\n\tstruct target *target = armv7m_reg->target;\n\tstruct arm *arm = target_to_arm(target);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = arm->read_core_reg(target, reg, reg->number, arm->core_mode);\n\n\treturn retval;\n}\n\nstatic int armv7m_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct arm_reg *armv7m_reg = reg->arch_info;\n\tstruct target *target = armv7m_reg->target;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_cpy(buf, reg->value, reg->size);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nuint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id)\n{\n\tswitch (arm_reg_id) {\n\tcase ARMV7M_R0 ... ARMV7M_R14:\n\tcase ARMV7M_PC:\n\tcase ARMV7M_XPSR:\n\tcase ARMV7M_MSP:\n\tcase ARMV7M_PSP:\n\t\t/* NOTE:  we \"know\" here that the register identifiers\n\t\t * match the Cortex-M DCRSR.REGSEL selectors values\n\t\t * for R0..R14, PC, xPSR, MSP, and PSP.\n\t\t */\n\t\treturn arm_reg_id;\n\n\tcase ARMV7M_PMSK_BPRI_FLTMSK_CTRL:\n\t\treturn ARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL;\n\n\tcase ARMV8M_MSP_NS...ARMV8M_PSPLIM_NS:\n\t\treturn arm_reg_id - ARMV8M_MSP_NS + ARMV8M_REGSEL_MSP_NS;\n\n\tcase ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S:\n\t\treturn ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S;\n\n\tcase ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS:\n\t\treturn ARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS;\n\n\tcase ARMV7M_FPSCR:\n\t\treturn ARMV7M_REGSEL_FPSCR;\n\n\tcase ARMV7M_D0 ... ARMV7M_D15:\n\t\treturn ARMV7M_REGSEL_S0 + 2 * (arm_reg_id - ARMV7M_D0);\n\n\tdefault:\n\t\tLOG_ERROR(\"Bad register ID %u\", arm_reg_id);\n\t\treturn arm_reg_id;\n\t}\n}\n\nbool armv7m_map_reg_packing(unsigned int arm_reg_id,\n\t\t\t\t\tunsigned int *reg32_id, uint32_t *offset)\n{\n\n\tswitch (arm_reg_id) {\n\n\tcase ARMV7M_PRIMASK...ARMV7M_CONTROL:\n\t\t*reg32_id = ARMV7M_PMSK_BPRI_FLTMSK_CTRL;\n\t\t*offset = arm_reg_id - ARMV7M_PRIMASK;\n\t\treturn true;\n\tcase ARMV8M_PRIMASK_S...ARMV8M_CONTROL_S:\n\t\t*reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S;\n\t\t*offset = arm_reg_id - ARMV8M_PRIMASK_S;\n\t\treturn true;\n\tcase ARMV8M_PRIMASK_NS...ARMV8M_CONTROL_NS:\n\t\t*reg32_id = ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS;\n\t\t*offset = arm_reg_id - ARMV8M_PRIMASK_NS;\n\t\treturn true;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n}\n\nstatic int armv7m_read_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode)\n{\n\tuint32_t reg_value;\n\tint retval;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tassert(num < (int)armv7m->arm.core_cache->num_regs);\n\tassert(num == (int)r->number);\n\n\t/* If a code calls read_reg, it expects the cache is no more dirty.\n\t * Clear the dirty flag regardless of the later read succeeds or not\n\t * to prevent unwanted cache flush after a read error */\n\tr->dirty = false;\n\n\tif (r->size <= 8) {\n\t\t/* any 8-bit or shorter register is packed */\n\t\tuint32_t offset;\n\t\tunsigned int reg32_id;\n\n\t\tbool is_packed = armv7m_map_reg_packing(num, &reg32_id, &offset);\n\t\tif (!is_packed) {\n\t\t\t/* We should not get here as all 8-bit or shorter registers\n\t\t\t * are packed */\n\t\t\tassert(false);\n\t\t\t/* assert() does nothing if NDEBUG is defined */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tstruct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];\n\n\t\t/* Read 32-bit container register if not cached */\n\t\tif (!r32->valid) {\n\t\t\tretval = armv7m_read_core_reg(target, r32, reg32_id, mode);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\t/* Copy required bits of 32-bit container register */\n\t\tbuf_cpy(r32->value + offset, r->value, r->size);\n\n\t} else {\n\t\tassert(r->size == 32 || r->size == 64);\n\n\t\tstruct arm_reg *armv7m_core_reg = r->arch_info;\n\t\tuint32_t regsel = armv7m_map_id_to_regsel(armv7m_core_reg->num);\n\n\t\tretval = armv7m->load_core_reg_u32(target, regsel, &reg_value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbuf_set_u32(r->value, 0, 32, reg_value);\n\n\t\tif (r->size == 64) {\n\t\t\tretval = armv7m->load_core_reg_u32(target, regsel + 1, &reg_value);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tr->valid = false;\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tbuf_set_u32(r->value + 4, 0, 32, reg_value);\n\n\t\t\tuint64_t q = buf_get_u64(r->value, 0, 64);\n\t\t\tLOG_DEBUG(\"read %s value 0x%016\" PRIx64, r->name, q);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"read %s value 0x%08\" PRIx32, r->name, reg_value);\n\t\t}\n\t}\n\n\tr->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int armv7m_write_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode, uint8_t *value)\n{\n\tint retval;\n\tuint32_t t;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tassert(num < (int)armv7m->arm.core_cache->num_regs);\n\tassert(num == (int)r->number);\n\n\tif (value != r->value) {\n\t\t/* If we are not flushing the cache, store the new value to the cache */\n\t\tbuf_cpy(value, r->value, r->size);\n\t}\n\n\tif (r->size <= 8) {\n\t\t/* any 8-bit or shorter register is packed */\n\t\tuint32_t offset;\n\t\tunsigned int reg32_id;\n\n\t\tbool is_packed = armv7m_map_reg_packing(num, &reg32_id, &offset);\n\t\tif (!is_packed) {\n\t\t\t/* We should not get here as all 8-bit or shorter registers\n\t\t\t * are packed */\n\t\t\tassert(false);\n\t\t\t/* assert() does nothing if NDEBUG is defined */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tstruct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];\n\n\t\tif (!r32->valid) {\n\t\t\t/* Before merging with other parts ensure the 32-bit register is valid */\n\t\t\tretval = armv7m_read_core_reg(target, r32, reg32_id, mode);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\t/* Write a part to the 32-bit container register */\n\t\tbuf_cpy(value, r32->value + offset, r->size);\n\t\tr32->dirty = true;\n\n\t} else {\n\t\tassert(r->size == 32 || r->size == 64);\n\n\t\tstruct arm_reg *armv7m_core_reg = r->arch_info;\n\t\tuint32_t regsel = armv7m_map_id_to_regsel(armv7m_core_reg->num);\n\n\t\tt = buf_get_u32(value, 0, 32);\n\t\tretval = armv7m->store_core_reg_u32(target, regsel, t);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto out_error;\n\n\t\tif (r->size == 64) {\n\t\t\tt = buf_get_u32(value + 4, 0, 32);\n\t\t\tretval = armv7m->store_core_reg_u32(target, regsel + 1, t);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto out_error;\n\n\t\t\tuint64_t q = buf_get_u64(value, 0, 64);\n\t\t\tLOG_DEBUG(\"write %s value 0x%016\" PRIx64, r->name, q);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"write %s value 0x%08\" PRIx32, r->name, t);\n\t\t}\n\t}\n\n\tr->valid = true;\n\tr->dirty = false;\n\n\treturn ERROR_OK;\n\nout_error:\n\tr->dirty = true;\n\tLOG_ERROR(\"Error setting register %s\", r->name);\n\treturn retval;\n}\n\n/**\n * Returns generic ARM userspace registers to GDB.\n */\nint armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint i, size;\n\n\tif (reg_class == REG_CLASS_ALL)\n\t\tsize = armv7m->arm.core_cache->num_regs;\n\telse\n\t\tsize = ARMV7M_NUM_CORE_REGS;\n\n\t*reg_list = malloc(sizeof(struct reg *) * size);\n\tif (!*reg_list)\n\t\treturn ERROR_FAIL;\n\n\tfor (i = 0; i < size; i++)\n\t\t(*reg_list)[i] = &armv7m->arm.core_cache->reg_list[i];\n\n\t*reg_list_size = size;\n\n\treturn ERROR_OK;\n}\n\n/** Runs a Thumb algorithm in the target. */\nint armv7m_run_algorithm(struct target *target,\n\tint num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\ttarget_addr_t entry_point, target_addr_t exit_point,\n\tunsigned int timeout_ms, void *arch_info)\n{\n\tint retval;\n\n\tretval = armv7m_start_algorithm(target,\n\t\t\tnum_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\tentry_point, exit_point,\n\t\t\tarch_info);\n\n\tif (retval == ERROR_OK)\n\t\tretval = armv7m_wait_algorithm(target,\n\t\t\t\tnum_mem_params, mem_params,\n\t\t\t\tnum_reg_params, reg_params,\n\t\t\t\texit_point, timeout_ms,\n\t\t\t\tarch_info);\n\n\treturn retval;\n}\n\n/** Starts a Thumb algorithm in the target. */\nint armv7m_start_algorithm(struct target *target,\n\tint num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\ttarget_addr_t entry_point, target_addr_t exit_point,\n\tvoid *arch_info)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct armv7m_algorithm *armv7m_algorithm_info = arch_info;\n\tenum arm_mode core_mode = armv7m->arm.core_mode;\n\tint retval = ERROR_OK;\n\n\t/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint\n\t * at the exit point */\n\n\tif (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"current target isn't an ARMV7M target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Store all non-debug execution registers to armv7m_algorithm_info context */\n\tfor (unsigned i = 0; i < armv7m->arm.core_cache->num_regs; i++) {\n\t\tstruct reg *reg = &armv7m->arm.core_cache->reg_list[i];\n\t\tif (!reg->exist)\n\t\t\tcontinue;\n\n\t\tif (!reg->valid)\n\t\t\tarmv7m_get_core_reg(reg);\n\n\t\tif (!reg->valid)\n\t\t\tLOG_TARGET_WARNING(target, \"Storing invalid register %s\", reg->name);\n\n\t\tarmv7m_algorithm_info->context[i] = buf_get_u32(reg->value, 0, 32);\n\t}\n\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\t\tretval = target_write_buffer(target, mem_params[i].address,\n\t\t\t\tmem_params[i].size,\n\t\t\t\tmem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\n\t\tstruct reg *reg =\n\t\t\tregister_get_by_name(armv7m->arm.core_cache, reg_params[i].reg_name, false);\n/*\t\tuint32_t regvalue; */\n\n\t\tif (!reg) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (reg->size != reg_params[i].size) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\treg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n/*\t\tregvalue = buf_get_u32(reg_params[i].value, 0, 32); */\n\t\tarmv7m_set_core_reg(reg, reg_params[i].value);\n\t}\n\n\t{\n\t\t/*\n\t\t * Ensure xPSR.T is set to avoid trying to run things in arm\n\t\t * (non-thumb) mode, which armv7m does not support.\n\t\t *\n\t\t * We do this by setting the entirety of xPSR, which should\n\t\t * remove all the unknowns about xPSR state.\n\t\t *\n\t\t * Because xPSR.T is populated on reset from the vector table,\n\t\t * it might be 0 if the vector table has \"bad\" data in it.\n\t\t */\n\t\tstruct reg *reg = &armv7m->arm.core_cache->reg_list[ARMV7M_XPSR];\n\t\tbuf_set_u32(reg->value, 0, 32, 0x01000000);\n\t\treg->valid = true;\n\t\treg->dirty = true;\n\t}\n\n\tif (armv7m_algorithm_info->core_mode != ARM_MODE_ANY &&\n\t\t\tarmv7m_algorithm_info->core_mode != core_mode) {\n\n\t\t/* we cannot set ARM_MODE_HANDLER, so use ARM_MODE_THREAD instead */\n\t\tif (armv7m_algorithm_info->core_mode == ARM_MODE_HANDLER) {\n\t\t\tarmv7m_algorithm_info->core_mode = ARM_MODE_THREAD;\n\t\t\tLOG_INFO(\"ARM_MODE_HANDLER not currently supported, using ARM_MODE_THREAD instead\");\n\t\t}\n\n\t\tLOG_DEBUG(\"setting core_mode: 0x%2.2x\", armv7m_algorithm_info->core_mode);\n\t\tbuf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value,\n\t\t\t0, 1, armv7m_algorithm_info->core_mode);\n\t\tarmv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = true;\n\t\tarmv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = true;\n\t}\n\n\t/* save previous core mode */\n\tarmv7m_algorithm_info->core_mode = core_mode;\n\n\tretval = target_resume(target, 0, entry_point, 1, 1);\n\n\treturn retval;\n}\n\n/** Waits for an algorithm in the target. */\nint armv7m_wait_algorithm(struct target *target,\n\tint num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\ttarget_addr_t exit_point, unsigned int timeout_ms,\n\tvoid *arch_info)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct armv7m_algorithm *armv7m_algorithm_info = arch_info;\n\tint retval = ERROR_OK;\n\n\t/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint\n\t * at the exit point */\n\n\tif (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"current target isn't an ARMV7M target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tretval = target_wait_state(target, TARGET_HALTED, timeout_ms);\n\t/* If the target fails to halt due to the breakpoint, force a halt */\n\tif (retval != ERROR_OK || target->state != TARGET_HALTED) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_wait_state(target, TARGET_HALTED, 500);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\tif (exit_point) {\n\t\t/* PC value has been cached in cortex_m_debug_entry() */\n\t\tuint32_t pc = buf_get_u32(armv7m->arm.pc->value, 0, 32);\n\t\tif (pc != exit_point) {\n\t\t\tLOG_DEBUG(\"failed algorithm halted at 0x%\" PRIx32 \", expected 0x%\" TARGET_PRIxADDR,\n\t\t\t\t\t  pc, exit_point);\n\t\t\treturn ERROR_TARGET_ALGO_EXIT;\n\t\t}\n\t}\n\n\t/* Read memory values to mem_params[] */\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction != PARAM_OUT) {\n\t\t\tretval = target_read_buffer(target, mem_params[i].address,\n\t\t\t\t\tmem_params[i].size,\n\t\t\t\t\tmem_params[i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Copy core register values to reg_params[] */\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction != PARAM_OUT) {\n\t\t\tstruct reg *reg = register_get_by_name(armv7m->arm.core_cache,\n\t\t\t\t\treg_params[i].reg_name,\n\t\t\t\t\tfalse);\n\n\t\t\tif (!reg) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tif (reg->size != reg_params[i].size) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tbuf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));\n\t\t}\n\t}\n\n\tfor (int i = armv7m->arm.core_cache->num_regs - 1; i >= 0; i--) {\n\t\tstruct reg *reg = &armv7m->arm.core_cache->reg_list[i];\n\t\tif (!reg->exist)\n\t\t\tcontinue;\n\n\t\tuint32_t regvalue;\n\t\tregvalue = buf_get_u32(reg->value, 0, 32);\n\t\tif (regvalue != armv7m_algorithm_info->context[i]) {\n\t\t\tLOG_DEBUG(\"restoring register %s with value 0x%8.8\" PRIx32,\n\t\t\t\t\t  reg->name, armv7m_algorithm_info->context[i]);\n\t\t\tbuf_set_u32(reg->value,\n\t\t\t\t0, 32, armv7m_algorithm_info->context[i]);\n\t\t\treg->valid = true;\n\t\t\treg->dirty = true;\n\t\t}\n\t}\n\n\t/* restore previous core mode */\n\tif (armv7m_algorithm_info->core_mode != armv7m->arm.core_mode) {\n\t\tLOG_DEBUG(\"restoring core_mode: 0x%2.2x\", armv7m_algorithm_info->core_mode);\n\t\tbuf_set_u32(armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].value,\n\t\t\t0, 1, armv7m_algorithm_info->core_mode);\n\t\tarmv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].dirty = true;\n\t\tarmv7m->arm.core_cache->reg_list[ARMV7M_CONTROL].valid = true;\n\t}\n\n\tarmv7m->arm.core_mode = armv7m_algorithm_info->core_mode;\n\n\treturn retval;\n}\n\n/** Logs summary of ARMv7-M state for a halted target. */\nint armv7m_arch_state(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct arm *arm = &armv7m->arm;\n\tuint32_t ctrl, sp;\n\n\t/* avoid filling log waiting for fileio reply */\n\tif (target->semihosting && target->semihosting->hit_fileio)\n\t\treturn ERROR_OK;\n\n\tctrl = buf_get_u32(arm->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 32);\n\tsp = buf_get_u32(arm->core_cache->reg_list[ARMV7M_R13].value, 0, 32);\n\n\tLOG_USER(\"[%s] halted due to %s, current mode: %s %s\\n\"\n\t\t\"xPSR: %#8.8\" PRIx32 \" pc: %#8.8\" PRIx32 \" %csp: %#8.8\" PRIx32 \"%s%s\",\n\t\ttarget_name(target),\n\t\tdebug_reason_name(target),\n\t\tarm_mode_name(arm->core_mode),\n\t\tarmv7m_exception_string(armv7m->exception_number),\n\t\tbuf_get_u32(arm->cpsr->value, 0, 32),\n\t\tbuf_get_u32(arm->pc->value, 0, 32),\n\t\t(ctrl & 0x02) ? 'p' : 'm',\n\t\tsp,\n\t\t(target->semihosting && target->semihosting->is_active) ? \", semihosting\" : \"\",\n\t\t(target->semihosting && target->semihosting->is_fileio) ? \" fileio\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type armv7m_reg_type = {\n\t.get = armv7m_get_core_reg,\n\t.set = armv7m_set_core_reg,\n};\n\n/** Builds cache of architecturally defined registers.  */\nstruct reg_cache *armv7m_build_reg_cache(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct arm *arm = &armv7m->arm;\n\tint num_regs = ARMV7M_NUM_REGS;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));\n\tstruct reg_feature *feature;\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"arm v7m registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\t(*cache_p) = cache;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i].num = armv7m_regs[i].id;\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].arm = arm;\n\n\t\treg_list[i].name = armv7m_regs[i].name;\n\t\treg_list[i].size = armv7m_regs[i].bits;\n\t\treg_list[i].value = arch_info[i].value;\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].hidden = (i == ARMV7M_PMSK_BPRI_FLTMSK_CTRL ||\n\t\t\t\ti == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS || i == ARMV8M_PMSK_BPRI_FLTMSK_CTRL_S);\n\t\treg_list[i].type = &armv7m_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\n\t\treg_list[i].group = armv7m_regs[i].group;\n\t\treg_list[i].number = i;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].caller_save = true;\t/* gdb defaults to true */\n\n\t\tif (reg_list[i].hidden)\n\t\t\tcontinue;\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = armv7m_regs[i].feature;\n\t\t\treg_list[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate feature list\");\n\n\t\treg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\tif (reg_list[i].reg_data_type)\n\t\t\treg_list[i].reg_data_type->type = armv7m_regs[i].type;\n\t\telse\n\t\t\tLOG_ERROR(\"unable to allocate reg type list\");\n\t}\n\n\tarm->cpsr = reg_list + ARMV7M_XPSR;\n\tarm->pc = reg_list + ARMV7M_PC;\n\tarm->core_cache = cache;\n\n\treturn cache;\n}\n\nvoid armv7m_free_reg_cache(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct arm *arm = &armv7m->arm;\n\tstruct reg_cache *cache;\n\tstruct reg *reg;\n\tunsigned int i;\n\n\tcache = arm->core_cache;\n\n\tif (!cache)\n\t\treturn;\n\n\tfor (i = 0; i < cache->num_regs; i++) {\n\t\treg = &cache->reg_list[i];\n\n\t\tfree(reg->feature);\n\t\tfree(reg->reg_data_type);\n\t}\n\n\tfree(cache->reg_list[0].arch_info);\n\tfree(cache->reg_list);\n\tfree(cache);\n\n\tarm->core_cache = NULL;\n}\n\nstatic int armv7m_setup_semihosting(struct target *target, int enable)\n{\n\t/* nothing todo for armv7m */\n\treturn ERROR_OK;\n}\n\n/** Sets up target as a generic ARMv7-M core */\nint armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m)\n{\n\tstruct arm *arm = &armv7m->arm;\n\n\tarmv7m->common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m->fp_feature = FP_NONE;\n\tarmv7m->trace_config.trace_bus_id = 1;\n\t/* Enable stimulus port #0 by default */\n\tarmv7m->trace_config.itm_ter[0] = 1;\n\n\tarm->core_state = ARM_STATE_THUMB;\n\tarm->core_type = ARM_CORE_TYPE_M_PROFILE;\n\tarm->arch_info = armv7m;\n\tarm->setup_semihosting = armv7m_setup_semihosting;\n\n\tarm->read_core_reg = armv7m_read_core_reg;\n\tarm->write_core_reg = armv7m_write_core_reg;\n\n\treturn arm_init_arch_info(target, arm);\n}\n\n/** Generates a CRC32 checksum of a memory region. */\nint armv7m_checksum_memory(struct target *target,\n\ttarget_addr_t address, uint32_t count, uint32_t *checksum)\n{\n\tstruct working_area *crc_algorithm;\n\tstruct armv7m_algorithm armv7m_info;\n\tstruct reg_param reg_params[2];\n\tint retval;\n\n\tstatic const uint8_t cortex_m_crc_code[] = {\n#include \"../../contrib/loaders/checksum/armv7m_crc.inc\"\n\t};\n\n\tretval = target_alloc_working_area(target, sizeof(cortex_m_crc_code), &crc_algorithm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_buffer(target, crc_algorithm->address,\n\t\t\tsizeof(cortex_m_crc_code), (uint8_t *)cortex_m_crc_code);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup;\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\n\tunsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));\n\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,\n\t\t\tcrc_algorithm->address + (sizeof(cortex_m_crc_code) - 6),\n\t\t\ttimeout, &armv7m_info);\n\n\tif (retval == ERROR_OK)\n\t\t*checksum = buf_get_u32(reg_params[0].value, 0, 32);\n\telse\n\t\tLOG_ERROR(\"error executing cortex_m crc algorithm\");\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\ncleanup:\n\ttarget_free_working_area(target, crc_algorithm);\n\n\treturn retval;\n}\n\n/** Checks an array of memory regions whether they are erased. */\nint armv7m_blank_check_memory(struct target *target,\n\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)\n{\n\tstruct working_area *erase_check_algorithm;\n\tstruct working_area *erase_check_params;\n\tstruct reg_param reg_params[2];\n\tstruct armv7m_algorithm armv7m_info;\n\tint retval;\n\n\tstatic bool timed_out;\n\n\tstatic const uint8_t erase_check_code[] = {\n#include \"../../contrib/loaders/erase_check/armv7m_erase_check.inc\"\n\t};\n\n\tconst uint32_t code_size = sizeof(erase_check_code);\n\n\t/* make sure we have a working area */\n\tif (target_alloc_working_area(target, code_size,\n\t\t&erase_check_algorithm) != ERROR_OK)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tretval = target_write_buffer(target, erase_check_algorithm->address,\n\t\t\tcode_size, erase_check_code);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup1;\n\n\t/* prepare blocks array for algo */\n\tstruct algo_block {\n\t\tunion {\n\t\t\tuint32_t size;\n\t\t\tuint32_t result;\n\t\t};\n\t\tuint32_t address;\n\t};\n\n\tuint32_t avail = target_get_working_area_avail(target);\n\tint blocks_to_check = avail / sizeof(struct algo_block) - 1;\n\tif (num_blocks < blocks_to_check)\n\t\tblocks_to_check = num_blocks;\n\n\tstruct algo_block *params = malloc((blocks_to_check+1)*sizeof(struct algo_block));\n\tif (!params) {\n\t\tretval = ERROR_FAIL;\n\t\tgoto cleanup1;\n\t}\n\n\tint i;\n\tuint32_t total_size = 0;\n\tfor (i = 0; i < blocks_to_check; i++) {\n\t\ttotal_size += blocks[i].size;\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&(params[i].size),\n\t\t\t\t\t\tblocks[i].size / sizeof(uint32_t));\n\t\ttarget_buffer_set_u32(target, (uint8_t *)&(params[i].address),\n\t\t\t\t\t\tblocks[i].address);\n\t}\n\ttarget_buffer_set_u32(target, (uint8_t *)&(params[blocks_to_check].size), 0);\n\n\tuint32_t param_size = (blocks_to_check + 1) * sizeof(struct algo_block);\n\tif (target_alloc_working_area(target, param_size,\n\t\t\t&erase_check_params) != ERROR_OK) {\n\t\tretval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\tgoto cleanup2;\n\t}\n\n\tretval = target_write_buffer(target, erase_check_params->address,\n\t\t\t\tparam_size, (uint8_t *)params);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup3;\n\n\tuint32_t erased_word = erased_value | (erased_value << 8)\n\t\t\t       | (erased_value << 16) | (erased_value << 24);\n\n\tLOG_DEBUG(\"Starting erase check of %d blocks, parameters@\"\n\t\t TARGET_ADDR_FMT, blocks_to_check, erase_check_params->address);\n\n\tarmv7m_info.common_magic = ARMV7M_COMMON_MAGIC;\n\tarmv7m_info.core_mode = ARM_MODE_THREAD;\n\n\tinit_reg_param(&reg_params[0], \"r0\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, erase_check_params->address);\n\n\tinit_reg_param(&reg_params[1], \"r1\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, erased_word);\n\n\t/* assume CPU clk at least 1 MHz */\n\tunsigned int timeout = (timed_out ? 30000 : 2000) + total_size * 3 / 1000;\n\n\tretval = target_run_algorithm(target,\n\t\t\t\t0, NULL,\n\t\t\t\tARRAY_SIZE(reg_params), reg_params,\n\t\t\t\terase_check_algorithm->address,\n\t\t\t\terase_check_algorithm->address + (code_size - 2),\n\t\t\t\ttimeout,\n\t\t\t\t&armv7m_info);\n\n\ttimed_out = retval == ERROR_TARGET_TIMEOUT;\n\tif (retval != ERROR_OK && !timed_out)\n\t\tgoto cleanup4;\n\n\tretval = target_read_buffer(target, erase_check_params->address,\n\t\t\t\tparam_size, (uint8_t *)params);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup4;\n\n\tfor (i = 0; i < blocks_to_check; i++) {\n\t\tuint32_t result = target_buffer_get_u32(target,\n\t\t\t\t\t(uint8_t *)&(params[i].result));\n\t\tif (result != 0 && result != 1)\n\t\t\tbreak;\n\n\t\tblocks[i].result = result;\n\t}\n\tif (i && timed_out)\n\t\tLOG_INFO(\"Slow CPU clock: %d blocks checked, %d remain. Continuing...\", i, num_blocks-i);\n\n\tretval = i;\t\t/* return number of blocks really checked */\n\ncleanup4:\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\ncleanup3:\n\ttarget_free_working_area(target, erase_check_params);\ncleanup2:\n\tfree(params);\ncleanup1:\n\ttarget_free_working_area(target, erase_check_algorithm);\n\n\treturn retval;\n}\n\nint armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct reg *r = armv7m->arm.pc;\n\tbool result = false;\n\n\n\t/* if we halted last time due to a bkpt instruction\n\t * then we have to manually step over it, otherwise\n\t * the core will break again */\n\n\tif (target->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\tuint16_t op;\n\t\tuint32_t pc = buf_get_u32(r->value, 0, 32);\n\n\t\tpc &= ~1;\n\t\tif (target_read_u16(target, pc, &op) == ERROR_OK) {\n\t\t\tif ((op & 0xFF00) == 0xBE00) {\n\t\t\t\tpc = buf_get_u32(r->value, 0, 32) + 2;\n\t\t\t\tbuf_set_u32(r->value, 0, 32, pc);\n\t\t\t\tr->dirty = true;\n\t\t\t\tr->valid = true;\n\t\t\t\tresult = true;\n\t\t\t\tLOG_DEBUG(\"Skipping over BKPT instruction\");\n\t\t\t}\n\t\t}\n\t}\n\n\tif (inst_found)\n\t\t*inst_found = result;\n\n\treturn ERROR_OK;\n}\n\nconst struct command_registration armv7m_command_handlers[] = {\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM command group\",\n\t\t.usage = \"\",\n\t\t.chain = arm_all_profiles_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7m.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV7M_H\n#define OPENOCD_TARGET_ARMV7M_H\n\n#include \"arm.h\"\n#include \"armv7m_trace.h\"\n\nstruct adiv5_ap;\n\nextern const int armv7m_psp_reg_map[];\nextern const int armv7m_msp_reg_map[];\n\nconst char *armv7m_exception_string(int number);\n\n/* Cortex-M DCRSR.REGSEL selectors */\nenum {\n\tARMV7M_REGSEL_R0,\n\tARMV7M_REGSEL_R1,\n\tARMV7M_REGSEL_R2,\n\tARMV7M_REGSEL_R3,\n\n\tARMV7M_REGSEL_R4,\n\tARMV7M_REGSEL_R5,\n\tARMV7M_REGSEL_R6,\n\tARMV7M_REGSEL_R7,\n\n\tARMV7M_REGSEL_R8,\n\tARMV7M_REGSEL_R9,\n\tARMV7M_REGSEL_R10,\n\tARMV7M_REGSEL_R11,\n\n\tARMV7M_REGSEL_R12,\n\tARMV7M_REGSEL_R13,\n\tARMV7M_REGSEL_R14,\n\tARMV7M_REGSEL_PC = 15,\n\n\tARMV7M_REGSEL_XPSR = 16,\n\tARMV7M_REGSEL_MSP,\n\tARMV7M_REGSEL_PSP,\n\n\tARMV8M_REGSEL_MSP_NS = 0x18,\n\tARMV8M_REGSEL_PSP_NS,\n\tARMV8M_REGSEL_MSP_S,\n\tARMV8M_REGSEL_PSP_S,\n\tARMV8M_REGSEL_MSPLIM_S,\n\tARMV8M_REGSEL_PSPLIM_S,\n\tARMV8M_REGSEL_MSPLIM_NS,\n\tARMV8M_REGSEL_PSPLIM_NS,\n\n\tARMV7M_REGSEL_PMSK_BPRI_FLTMSK_CTRL = 0x14,\n\tARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_S = 0x22,\n\tARMV8M_REGSEL_PMSK_BPRI_FLTMSK_CTRL_NS = 0x23,\n\tARMV7M_REGSEL_FPSCR = 0x21,\n\n\t/* 32bit Floating-point registers */\n\tARMV7M_REGSEL_S0 = 0x40,\n\tARMV7M_REGSEL_S1,\n\tARMV7M_REGSEL_S2,\n\tARMV7M_REGSEL_S3,\n\tARMV7M_REGSEL_S4,\n\tARMV7M_REGSEL_S5,\n\tARMV7M_REGSEL_S6,\n\tARMV7M_REGSEL_S7,\n\tARMV7M_REGSEL_S8,\n\tARMV7M_REGSEL_S9,\n\tARMV7M_REGSEL_S10,\n\tARMV7M_REGSEL_S11,\n\tARMV7M_REGSEL_S12,\n\tARMV7M_REGSEL_S13,\n\tARMV7M_REGSEL_S14,\n\tARMV7M_REGSEL_S15,\n\tARMV7M_REGSEL_S16,\n\tARMV7M_REGSEL_S17,\n\tARMV7M_REGSEL_S18,\n\tARMV7M_REGSEL_S19,\n\tARMV7M_REGSEL_S20,\n\tARMV7M_REGSEL_S21,\n\tARMV7M_REGSEL_S22,\n\tARMV7M_REGSEL_S23,\n\tARMV7M_REGSEL_S24,\n\tARMV7M_REGSEL_S25,\n\tARMV7M_REGSEL_S26,\n\tARMV7M_REGSEL_S27,\n\tARMV7M_REGSEL_S28,\n\tARMV7M_REGSEL_S29,\n\tARMV7M_REGSEL_S30,\n\tARMV7M_REGSEL_S31,\n};\n\n/* offsets into armv7m core register cache */\nenum {\n\t/* for convenience, the first set of indices match\n\t * the Cortex-M DCRSR.REGSEL selectors\n\t */\n\tARMV7M_R0 = ARMV7M_REGSEL_R0,\n\tARMV7M_R1 = ARMV7M_REGSEL_R1,\n\tARMV7M_R2 = ARMV7M_REGSEL_R2,\n\tARMV7M_R3 = ARMV7M_REGSEL_R3,\n\n\tARMV7M_R4 = ARMV7M_REGSEL_R4,\n\tARMV7M_R5 = ARMV7M_REGSEL_R5,\n\tARMV7M_R6 = ARMV7M_REGSEL_R6,\n\tARMV7M_R7 = ARMV7M_REGSEL_R7,\n\n\tARMV7M_R8 = ARMV7M_REGSEL_R8,\n\tARMV7M_R9 = ARMV7M_REGSEL_R9,\n\tARMV7M_R10 = ARMV7M_REGSEL_R10,\n\tARMV7M_R11 = ARMV7M_REGSEL_R11,\n\n\tARMV7M_R12 = ARMV7M_REGSEL_R12,\n\tARMV7M_R13 = ARMV7M_REGSEL_R13,\n\tARMV7M_R14 = ARMV7M_REGSEL_R14,\n\tARMV7M_PC = ARMV7M_REGSEL_PC,\n\n\tARMV7M_XPSR = ARMV7M_REGSEL_XPSR,\n\tARMV7M_MSP = ARMV7M_REGSEL_MSP,\n\tARMV7M_PSP = ARMV7M_REGSEL_PSP,\n\n\t/* following indices are arbitrary, do not match DCRSR.REGSEL selectors */\n\n\t/* A block of container and contained registers follows:\n\t * THE ORDER IS IMPORTANT to the end of the block ! */\n\t/* working register for packing/unpacking special regs, hidden from gdb */\n\tARMV7M_PMSK_BPRI_FLTMSK_CTRL,\n\n\t/* WARNING: If you use armv7m_write_core_reg() on one of 4 following\n\t * special registers, the new data go to ARMV7M_PMSK_BPRI_FLTMSK_CTRL\n\t * cache only and are not flushed to CPU HW register.\n\t * To trigger write to CPU HW register, add\n\t *\t\tarmv7m_write_core_reg(,,ARMV7M_PMSK_BPRI_FLTMSK_CTRL,);\n\t */\n\tARMV7M_PRIMASK,\n\tARMV7M_BASEPRI,\n\tARMV7M_FAULTMASK,\n\tARMV7M_CONTROL,\n\t/* The end of block of container and contained registers */\n\n\t/* ARMv8-M specific registers */\n\tARMV8M_MSP_NS,\n\tARMV8M_PSP_NS,\n\tARMV8M_MSP_S,\n\tARMV8M_PSP_S,\n\tARMV8M_MSPLIM_S,\n\tARMV8M_PSPLIM_S,\n\tARMV8M_MSPLIM_NS,\n\tARMV8M_PSPLIM_NS,\n\n\t/* A block of container and contained registers follows:\n\t * THE ORDER IS IMPORTANT to the end of the block ! */\n\tARMV8M_PMSK_BPRI_FLTMSK_CTRL_S,\n\tARMV8M_PRIMASK_S,\n\tARMV8M_BASEPRI_S,\n\tARMV8M_FAULTMASK_S,\n\tARMV8M_CONTROL_S,\n\t/* The end of block of container and contained registers */\n\n\t/* A block of container and contained registers follows:\n\t * THE ORDER IS IMPORTANT to the end of the block ! */\n\tARMV8M_PMSK_BPRI_FLTMSK_CTRL_NS,\n\tARMV8M_PRIMASK_NS,\n\tARMV8M_BASEPRI_NS,\n\tARMV8M_FAULTMASK_NS,\n\tARMV8M_CONTROL_NS,\n\t/* The end of block of container and contained registers */\n\n\t/* 64bit Floating-point registers */\n\tARMV7M_D0,\n\tARMV7M_D1,\n\tARMV7M_D2,\n\tARMV7M_D3,\n\tARMV7M_D4,\n\tARMV7M_D5,\n\tARMV7M_D6,\n\tARMV7M_D7,\n\tARMV7M_D8,\n\tARMV7M_D9,\n\tARMV7M_D10,\n\tARMV7M_D11,\n\tARMV7M_D12,\n\tARMV7M_D13,\n\tARMV7M_D14,\n\tARMV7M_D15,\n\n\t/* Floating-point status register */\n\tARMV7M_FPSCR,\n\n\t/* for convenience add registers' block delimiters */\n\tARMV7M_LAST_REG,\n\tARMV7M_CORE_FIRST_REG = ARMV7M_R0,\n\tARMV7M_CORE_LAST_REG = ARMV7M_XPSR,\n\tARMV7M_FPU_FIRST_REG = ARMV7M_D0,\n\tARMV7M_FPU_LAST_REG = ARMV7M_FPSCR,\n\tARMV8M_FIRST_REG = ARMV8M_MSP_NS,\n\tARMV8M_LAST_REG = ARMV8M_CONTROL_NS,\n};\n\nenum {\n\tFP_NONE = 0,\n\tFPV4_SP,\n\tFPV5_SP,\n\tFPV5_DP,\n};\n\n#define ARMV7M_NUM_CORE_REGS (ARMV7M_CORE_LAST_REG - ARMV7M_CORE_FIRST_REG + 1)\n\n#define ARMV7M_COMMON_MAGIC 0x2A452A45U\n\nstruct armv7m_common {\n\tunsigned int common_magic;\n\n\tstruct arm arm;\n\n\tint exception_number;\n\n\t/* AP this processor is connected to in the DAP */\n\tstruct adiv5_ap *debug_ap;\n\n\tint fp_feature;\n\tuint32_t demcr;\n\n\t/* hla_target uses a high level adapter that does not support all functions */\n\tbool is_hla_target;\n\n\tstruct armv7m_trace_config trace_config;\n\n\t/* Direct processor core register read and writes */\n\tint (*load_core_reg_u32)(struct target *target, uint32_t regsel, uint32_t *value);\n\tint (*store_core_reg_u32)(struct target *target, uint32_t regsel, uint32_t value);\n\n\tint (*examine_debug_reason)(struct target *target);\n\tint (*post_debug_entry)(struct target *target);\n\n\tvoid (*pre_restore_context)(struct target *target);\n};\n\nstatic inline bool is_armv7m(const struct armv7m_common *armv7m)\n{\n\treturn armv7m->common_magic == ARMV7M_COMMON_MAGIC;\n}\n\n/**\n * @returns the pointer to the target specific struct\n * without matching a magic number.\n * Use in target specific service routines, where the correct\n * type of arch_info is certain.\n */\nstatic inline struct armv7m_common *\ntarget_to_armv7m(struct target *target)\n{\n\treturn container_of(target->arch_info, struct armv7m_common, arm);\n}\n\n/**\n * @returns the pointer to the target specific struct\n * or NULL if the magic number does not match.\n * Use in a flash driver or any place where mismatch of the arch_info\n * type can happen.\n */\nstatic inline struct armv7m_common *\ntarget_to_armv7m_safe(struct target *target)\n{\n\tif (!target)\n\t\treturn NULL;\n\n\tif (!target->arch_info)\n\t\treturn NULL;\n\n\t/* Check the parent type first to prevent peeking memory too far\n\t * from arch_info pointer */\n\tif (!is_arm(target_to_arm(target)))\n\t\treturn NULL;\n\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tif (!is_armv7m(armv7m))\n\t\treturn NULL;\n\n\treturn armv7m;\n}\n\nstruct armv7m_algorithm {\n\tunsigned int common_magic;\n\n\tenum arm_mode core_mode;\n\n\tuint32_t context[ARMV7M_LAST_REG]; /* ARMV7M_NUM_REGS */\n};\n\nstruct reg_cache *armv7m_build_reg_cache(struct target *target);\nvoid armv7m_free_reg_cache(struct target *target);\n\nenum armv7m_mode armv7m_number_to_mode(int number);\nint armv7m_mode_to_number(enum armv7m_mode mode);\n\nint armv7m_arch_state(struct target *target);\nint armv7m_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\n\nint armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m);\n\nint armv7m_run_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info);\n\nint armv7m_start_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tvoid *arch_info);\n\nint armv7m_wait_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms,\n\t\tvoid *arch_info);\n\nint armv7m_invalidate_core_regs(struct target *target);\n\nint armv7m_restore_context(struct target *target);\n\nuint32_t armv7m_map_id_to_regsel(unsigned int arm_reg_id);\n\nbool armv7m_map_reg_packing(unsigned int arm_reg_id,\n\t\tunsigned int *reg32_id, uint32_t *offset);\n\nint armv7m_checksum_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t count, uint32_t *checksum);\nint armv7m_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);\n\nint armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found);\n\nextern const struct command_registration armv7m_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARMV7M_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7m_trace.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015  Paul Fertser <fercerpav@gmail.com>                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <target/target.h>\n#include <target/armv7m.h>\n#include <target/cortex_m.h>\n#include <target/armv7m_trace.h>\n#include <jtag/interface.h>\n#include <helper/time_support.h>\n\nint armv7m_trace_itm_config(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct armv7m_trace_config *trace_config = &armv7m->trace_config;\n\tint retval;\n\n\tretval = target_write_u32(target, ITM_LAR, ITM_LAR_KEY);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* pg315 of CoreSight Components\n\t * It is recommended that the ITMEn bit is cleared and waits for the\n\t * ITMBusy bit to be cleared, before changing any fields in the\n\t * Control Register, otherwise the behavior can be unpredictable.\n\t */\n\tuint32_t itm_tcr;\n\tretval = target_read_u32(target, ITM_TCR, &itm_tcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target,\n\t\t\tITM_TCR,\n\t\t\titm_tcr & ~ITM_TCR_ITMENA_BIT\n\t\t\t);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms() + 1000;\n\tdo {\n\t\tretval = target_read_u32(target, ITM_TCR, &itm_tcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeval_ms() > then) {\n\t\t\tLOG_ERROR(\"timeout waiting for ITM_TCR_BUSY_BIT\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while (itm_tcr & ITM_TCR_BUSY_BIT);\n\n\t/* Enable ITM, TXENA, set TraceBusID and other parameters */\n\tretval = target_write_u32(target, ITM_TCR, (1 << 0) | (1 << 3) |\n\t\t\t\t  (trace_config->itm_diff_timestamps << 1) |\n\t\t\t\t  (trace_config->itm_synchro_packets << 2) |\n\t\t\t\t  (trace_config->itm_async_timestamps << 4) |\n\t\t\t\t  (trace_config->itm_ts_prescale << 8) |\n\t\t\t\t  (trace_config->trace_bus_id << 16));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned int i = 0; i < 8; i++) {\n\t\tretval = target_write_u32(target, ITM_TER0 + i * 4,\n\t\t\t\t\t  trace_config->itm_ter[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_itm_port_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tunsigned int reg_idx;\n\tuint8_t port;\n\tbool enable;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], port);\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);\n\treg_idx = port / 32;\n\tport = port % 32;\n\tif (enable)\n\t\tarmv7m->trace_config.itm_ter[reg_idx] |= (1 << port);\n\telse\n\t\tarmv7m->trace_config.itm_ter[reg_idx] &= ~(1 << port);\n\n\tif (CMD_CTX->mode == COMMAND_EXEC)\n\t\treturn armv7m_trace_itm_config(target);\n\n\tarmv7m->trace_config.itm_deferred_config = true;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_itm_ports_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tbool enable;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);\n\tmemset(armv7m->trace_config.itm_ter, enable ? 0xff : 0,\n\t       sizeof(armv7m->trace_config.itm_ter));\n\n\tif (CMD_CTX->mode == COMMAND_EXEC)\n\t\treturn armv7m_trace_itm_config(target);\n\n\tarmv7m->trace_config.itm_deferred_config = true;\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration itm_command_handlers[] = {\n\t{\n\t\t.name = \"port\",\n\t\t.handler = handle_itm_port_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Enable or disable ITM stimulus port\",\n\t\t.usage = \"<port> (0|1|on|off)\",\n\t},\n\t{\n\t\t.name = \"ports\",\n\t\t.handler = handle_itm_ports_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Enable or disable all ITM stimulus ports\",\n\t\t.usage = \"(0|1|on|off)\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration armv7m_trace_command_handlers[] = {\n\t{\n\t\t.name = \"itm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"itm command group\",\n\t\t.usage = \"\",\n\t\t.chain = itm_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv7m_trace.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015  Paul Fertser <fercerpav@gmail.com>                *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV7M_TRACE_H\n#define OPENOCD_TARGET_ARMV7M_TRACE_H\n\n#include <helper/command.h>\n#include <target/target.h>\n\n/**\n * @file\n * Holds the interface to ITM and DWT configuration functions.\n */\n\nenum itm_ts_prescaler {\n\tITM_TS_PRESCALE1,\t/**< no prescaling for the timestamp counter */\n\tITM_TS_PRESCALE4,\t/**< refclock divided by 4 for the timestamp counter */\n\tITM_TS_PRESCALE16,\t/**< refclock divided by 16 for the timestamp counter */\n\tITM_TS_PRESCALE64,\t/**< refclock divided by 64 for the timestamp counter */\n};\n\nstruct armv7m_trace_config {\n\t/** Bitmask of currently enabled ITM stimuli */\n\tuint32_t itm_ter[8];\n\t/** Identifier for multi-source trace stream formatting */\n\tunsigned int trace_bus_id;\n\t/** Prescaler for the timestamp counter */\n\tenum itm_ts_prescaler itm_ts_prescale;\n\t/** Enable differential timestamps */\n\tbool itm_diff_timestamps;\n\t/** Enable async timestamps model */\n\tbool itm_async_timestamps;\n\t/** Enable synchronisation packet transmission (for sync port only) */\n\tbool itm_synchro_packets;\n\t/** Config ITM after target examine */\n\tbool itm_deferred_config;\n};\n\nextern const struct command_registration armv7m_trace_command_handlers[];\n\n/**\n * Configure hardware accordingly to the current ITM target settings\n */\nint armv7m_trace_itm_config(struct target *target);\n\n#endif /* OPENOCD_TARGET_ARMV7M_TRACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2015 by David Ung                                       *\n *                                                                         *\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/replacements.h>\n\n#include \"armv8.h\"\n#include \"arm_disassembler.h\"\n\n#include \"register.h\"\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <helper/nvp.h>\n\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"armv8_opcodes.h\"\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"semihosting_common.h\"\n\nstatic const char * const armv8_state_strings[] = {\n\t\"AArch32\", \"Thumb\", \"Jazelle\", \"ThumbEE\", \"AArch64\",\n};\n\nstatic const struct {\n\tconst char *name;\n\tunsigned psr;\n} armv8_mode_data[] = {\n\t{\n\t\t.name = \"USR\",\n\t\t.psr = ARM_MODE_USR,\n\t},\n\t{\n\t\t.name = \"FIQ\",\n\t\t.psr = ARM_MODE_FIQ,\n\t},\n\t{\n\t\t.name = \"IRQ\",\n\t\t.psr = ARM_MODE_IRQ,\n\t},\n\t{\n\t\t.name = \"SVC\",\n\t\t.psr = ARM_MODE_SVC,\n\t},\n\t{\n\t\t.name = \"MON\",\n\t\t.psr = ARM_MODE_MON,\n\t},\n\t{\n\t\t.name = \"ABT\",\n\t\t.psr = ARM_MODE_ABT,\n\t},\n\t{\n\t\t.name = \"HYP\",\n\t\t.psr = ARM_MODE_HYP,\n\t},\n\t{\n\t\t.name = \"UND\",\n\t\t.psr = ARM_MODE_UND,\n\t},\n\t{\n\t\t.name = \"SYS\",\n\t\t.psr = ARM_MODE_SYS,\n\t},\n\t{\n\t\t.name = \"EL0T\",\n\t\t.psr = ARMV8_64_EL0T,\n\t},\n\t{\n\t\t.name = \"EL1T\",\n\t\t.psr = ARMV8_64_EL1T,\n\t},\n\t{\n\t\t.name = \"EL1H\",\n\t\t.psr = ARMV8_64_EL1H,\n\t},\n\t{\n\t\t.name = \"EL2T\",\n\t\t.psr = ARMV8_64_EL2T,\n\t},\n\t{\n\t\t.name = \"EL2H\",\n\t\t.psr = ARMV8_64_EL2H,\n\t},\n\t{\n\t\t.name = \"EL3T\",\n\t\t.psr = ARMV8_64_EL3T,\n\t},\n\t{\n\t\t.name = \"EL3H\",\n\t\t.psr = ARMV8_64_EL3H,\n\t},\n};\n\n/** Map PSR mode bits to the name of an ARM processor operating mode. */\nconst char *armv8_mode_name(unsigned psr_mode)\n{\n\tfor (unsigned i = 0; i < ARRAY_SIZE(armv8_mode_data); i++) {\n\t\tif (armv8_mode_data[i].psr == psr_mode)\n\t\t\treturn armv8_mode_data[i].name;\n\t}\n\tLOG_ERROR(\"unrecognized psr mode: %#02x\", psr_mode);\n\treturn \"UNRECOGNIZED\";\n}\n\nstatic uint8_t armv8_pa_size(uint32_t ps)\n{\n\tuint8_t ret = 0;\n\tswitch (ps) {\n\t\tcase 0:\n\t\t\tret = 32;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tret = 36;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tret = 40;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tret = 42;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tret = 44;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tret = 48;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_INFO(\"Unknown physical address size\");\n\t\t\tbreak;\n\t}\n\treturn ret;\n}\n\nstatic __attribute__((unused)) int armv8_read_ttbcr32(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tuint32_t ttbcr, ttbcr_n;\n\tint retval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\t/*  MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 2, 0, 2),\n\t\t\t&ttbcr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tLOG_DEBUG(\"ttbcr %\" PRIx32, ttbcr);\n\n\tttbcr_n = ttbcr & 0x7;\n\tarmv8->armv8_mmu.ttbcr = ttbcr;\n\n\t/*\n\t * ARM Architecture Reference Manual (ARMv7-A and ARMv7-R edition),\n\t * document # ARM DDI 0406C\n\t */\n\tarmv8->armv8_mmu.ttbr_range[0]  = 0xffffffff >> ttbcr_n;\n\tarmv8->armv8_mmu.ttbr_range[1] = 0xffffffff;\n\tarmv8->armv8_mmu.ttbr_mask[0] = 0xffffffff << (14 - ttbcr_n);\n\tarmv8->armv8_mmu.ttbr_mask[1] = 0xffffffff << 14;\n\n\tLOG_DEBUG(\"ttbr1 %s, ttbr0_mask %\" PRIx32 \" ttbr1_mask %\" PRIx32,\n\t\t  (ttbcr_n != 0) ? \"used\" : \"not used\",\n\t\t  armv8->armv8_mmu.ttbr_mask[0],\n\t\t  armv8->armv8_mmu.ttbr_mask[1]);\n\ndone:\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int armv8_read_ttbcr(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tstruct arm *arm = &armv8->arm;\n\tuint32_t ttbcr;\n\tuint64_t ttbcr_64;\n\n\tint retval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* clear ttrr1_used and ttbr0_mask */\n\tmemset(&armv8->armv8_mmu.ttbr1_used, 0, sizeof(armv8->armv8_mmu.ttbr1_used));\n\tmemset(&armv8->armv8_mmu.ttbr0_mask, 0, sizeof(armv8->armv8_mmu.ttbr0_mask));\n\n\tswitch (armv8_curel_from_core_mode(arm->core_mode)) {\n\tcase SYSTEM_CUREL_EL3:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TCR_EL3, 0),\n\t\t\t\t&ttbcr);\n\t\tretval += dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TTBR0_EL3, 0),\n\t\t\t\t&armv8->ttbr_base);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tarmv8->va_size = 64 - (ttbcr & 0x3F);\n\t\tarmv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);\n\t\tarmv8->page_size = (ttbcr >> 14) & 3;\n\t\tbreak;\n\tcase SYSTEM_CUREL_EL2:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TCR_EL2, 0),\n\t\t\t\t&ttbcr);\n\t\tretval += dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TTBR0_EL2, 0),\n\t\t\t\t&armv8->ttbr_base);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tarmv8->va_size = 64 - (ttbcr & 0x3F);\n\t\tarmv8->pa_size = armv8_pa_size((ttbcr >> 16) & 7);\n\t\tarmv8->page_size = (ttbcr >> 14) & 3;\n\t\tbreak;\n\tcase SYSTEM_CUREL_EL0:\n\t\tarmv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);\n\t\t/* fall through */\n\tcase SYSTEM_CUREL_EL1:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TCR_EL1, 0),\n\t\t\t\t&ttbcr_64);\n\t\tarmv8->va_size = 64 - (ttbcr_64 & 0x3F);\n\t\tarmv8->pa_size = armv8_pa_size((ttbcr_64 >> 32) & 7);\n\t\tarmv8->page_size = (ttbcr_64 >> 14) & 3;\n\t\tarmv8->armv8_mmu.ttbr1_used = (((ttbcr_64 >> 16) & 0x3F) != 0) ? 1 : 0;\n\t\tarmv8->armv8_mmu.ttbr0_mask  = 0x0000FFFFFFFFFFFFULL;\n\t\tretval += dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_TTBR0_EL1 | (armv8->armv8_mmu.ttbr1_used), 0),\n\t\t\t\t&armv8->ttbr_base);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"unknown core state\");\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tif (armv8->armv8_mmu.ttbr1_used == 1)\n\t\tLOG_INFO(\"TTBR0 access above %\" PRIx64, (uint64_t)(armv8->armv8_mmu.ttbr0_mask));\n\ndone:\n\tarmv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int armv8_get_pauth_mask(struct armv8_common *armv8, uint64_t *mask)\n{\n\tstruct arm *arm = &armv8->arm;\n\tint retval = ERROR_OK;\n\tif (armv8->va_size == 0)\n\t\tretval = armv8_read_ttbcr(arm->target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*mask = ~(((uint64_t)1 << armv8->va_size) - 1);\n\n\treturn retval;\n}\n\nstatic int armv8_read_reg(struct armv8_common *armv8, int regnum, uint64_t *regval)\n{\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tint retval;\n\tuint32_t value;\n\tuint64_t value_64;\n\n\tswitch (regnum) {\n\tcase 0 ... 30:\n\t\tretval = dpm->instr_read_data_dcc_64(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, regnum), &value_64);\n\t\tbreak;\n\tcase ARMV8_SP:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MOVFSP_64(0), &value_64);\n\t\tbreak;\n\tcase ARMV8_PC:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS_DLR(0), &value_64);\n\t\tbreak;\n\tcase ARMV8_XPSR:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_DSPSR(0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_FPSR:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_FPSR(0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_FPCR:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_FPCR(0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_ELR_EL1:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ELR_EL1, 0), &value_64);\n\t\tbreak;\n\tcase ARMV8_ELR_EL2:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ELR_EL2, 0), &value_64);\n\t\tbreak;\n\tcase ARMV8_ELR_EL3:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ELR_EL3, 0), &value_64);\n\t\tbreak;\n\tcase ARMV8_ESR_EL1:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ESR_EL1, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_ESR_EL2:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ESR_EL2, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_ESR_EL3:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_ESR_EL3, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_SPSR_EL1:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_SPSR_EL1, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_SPSR_EL2:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_SPSR_EL2, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_SPSR_EL3:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS(SYSTEM_SPSR_EL3, 0), &value);\n\t\tvalue_64 = value;\n\t\tbreak;\n\tcase ARMV8_PAUTH_CMASK:\n\tcase ARMV8_PAUTH_DMASK:\n\t\tretval = armv8_get_pauth_mask(armv8, &value_64);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK && regval)\n\t\t*regval = value_64;\n\telse\n\t\tretval = ERROR_FAIL;\n\n\treturn retval;\n}\n\nstatic int armv8_read_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, uint64_t *lvalue, uint64_t *hvalue)\n{\n\tint retval = ERROR_FAIL;\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\n\tswitch (regnum) {\n\tcase ARMV8_V0 ... ARMV8_V31:\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MOV_GPR_VFP(0, (regnum - ARMV8_V0), 1), hvalue);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = dpm->instr_read_data_r0_64(dpm,\n\t\t\t\tARMV8_MOV_GPR_VFP(0, (regnum - ARMV8_V0), 0), lvalue);\n\t\tbreak;\n\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int armv8_write_reg(struct armv8_common *armv8, int regnum, uint64_t value_64)\n{\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tint retval;\n\tuint32_t value;\n\n\tswitch (regnum) {\n\tcase 0 ... 30:\n\t\tretval = dpm->instr_write_data_dcc_64(dpm,\n\t\t\tARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, regnum),\n\t\t\tvalue_64);\n\t\tbreak;\n\tcase ARMV8_SP:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\tARMV8_MOVTSP_64(0),\n\t\t\tvalue_64);\n\t\tbreak;\n\tcase ARMV8_PC:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\tARMV8_MSR_DLR(0),\n\t\t\tvalue_64);\n\t\tbreak;\n\tcase ARMV8_XPSR:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV8_MSR_DSPSR(0),\n\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_FPSR:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV8_MSR_FPSR(0),\n\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_FPCR:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV8_MSR_FPCR(0),\n\t\t\tvalue);\n\t\tbreak;\n\t/* registers clobbered by taking exception in debug state */\n\tcase ARMV8_ELR_EL1:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ELR_EL1, 0), value_64);\n\t\tbreak;\n\tcase ARMV8_ELR_EL2:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ELR_EL2, 0), value_64);\n\t\tbreak;\n\tcase ARMV8_ELR_EL3:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ELR_EL3, 0), value_64);\n\t\tbreak;\n\tcase ARMV8_ESR_EL1:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ESR_EL1, 0), value);\n\t\tbreak;\n\tcase ARMV8_ESR_EL2:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ESR_EL2, 0), value);\n\t\tbreak;\n\tcase ARMV8_ESR_EL3:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_ESR_EL3, 0), value);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL1:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_SPSR_EL1, 0), value);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL2:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_SPSR_EL2, 0), value);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL3:\n\t\tvalue = value_64;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP(SYSTEM_SPSR_EL3, 0), value);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int armv8_write_reg_simdfp_aarch64(struct armv8_common *armv8, int regnum, uint64_t lvalue, uint64_t hvalue)\n{\n\tint retval = ERROR_FAIL;\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\n\tswitch (regnum) {\n\tcase ARMV8_V0 ... ARMV8_V31:\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tARMV8_MOV_VFP_GPR((regnum - ARMV8_V0), 0, 1), hvalue);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tARMV8_MOV_VFP_GPR((regnum - ARMV8_V0), 0, 0), lvalue);\n\t\tbreak;\n\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int armv8_read_reg32(struct armv8_common *armv8, int regnum, uint64_t *regval)\n{\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tuint32_t value = 0;\n\tint retval;\n\n\tswitch (regnum) {\n\tcase ARMV8_R0 ... ARMV8_R14:\n\t\t/* return via DCC:  \"MCR p14, 0, Rnum, c0, c5, 0\" */\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\tARMV4_5_MCR(14, 0, regnum, 0, 5, 0),\n\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_SP:\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\tARMV4_5_MCR(14, 0, 13, 0, 5, 0),\n\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_PC:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV8_MRC_DLR(0),\n\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_XPSR:\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV8_MRC_DSPSR(0),\n\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ELR_EL1: /* mapped to LR_svc */\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, 14, 0, 5, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ELR_EL2: /* mapped to ELR_hyp */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_T1(0, 14, 0, 1),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ELR_EL3: /* mapped to LR_mon */\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, 14, 0, 5, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ESR_EL1: /* mapped to DFSR */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_MRC(15, 0, 0, 5, 0, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ESR_EL2: /* mapped to HSR */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_MRC(15, 4, 0, 5, 2, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\tcase ARMV8_SPSR_EL1: /* mapped to SPSR_svc */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_XPSR_T1(1, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_XPSR_T1(1, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL3: /* mapped to SPSR_mon */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV8_MRS_XPSR_T1(1, 0),\n\t\t\t\t&value);\n\t\tbreak;\n\tcase ARMV8_FPSR:\n\t\t/* \"VMRS r0, FPSCR\"; then return via DCC */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_VMRS(0), &value);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\tif (retval == ERROR_OK && regval)\n\t\t*regval = value;\n\n\treturn retval;\n}\n\nstatic int armv8_read_reg_simdfp_aarch32(struct armv8_common *armv8, int regnum, uint64_t *lvalue, uint64_t *hvalue)\n{\n\tint retval = ERROR_FAIL;\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct reg *reg_r1 = dpm->arm->core_cache->reg_list + ARMV8_R1;\n\tuint32_t value_r0 = 0, value_r1 = 0;\n\tunsigned num = (regnum - ARMV8_V0) << 1;\n\n\tswitch (regnum) {\n\tcase ARMV8_V0 ... ARMV8_V15:\n\t\t/* we are going to write R1, mark it dirty */\n\t\treg_r1->dirty = true;\n\t\t/* move from double word register to r0:r1: \"vmov r0, r1, vm\"\n\t\t * then read r0 via dcc\n\t\t */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_VMOV(1, 1, 0, (num >> 4), (num & 0xf)),\n\t\t\t\t&value_r0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* read r1 via dcc */\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, 1, 0, 5, 0),\n\t\t\t\t&value_r1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t*lvalue = value_r1;\n\t\t*lvalue = ((*lvalue) << 32) | value_r0;\n\n\t\tnum++;\n\t\t/* repeat above steps for high 64 bits of V register */\n\t\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\t\tARMV4_5_VMOV(1, 1, 0, (num >> 4), (num & 0xf)),\n\t\t\t\t&value_r0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = dpm->instr_read_data_dcc(dpm,\n\t\t\t\tARMV4_5_MCR(14, 0, 1, 0, 5, 0),\n\t\t\t\t&value_r1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t*hvalue = value_r1;\n\t\t*hvalue = ((*hvalue) << 32) | value_r0;\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nstatic int armv8_write_reg32(struct armv8_common *armv8, int regnum, uint64_t value)\n{\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tint retval;\n\n\tswitch (regnum) {\n\tcase ARMV8_R0 ... ARMV8_R14:\n\t\t/* load register from DCC:  \"MRC p14, 0, Rnum, c0, c5, 0\" */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, regnum, 0, 5, 0), value);\n\t\tbreak;\n\tcase ARMV8_SP:\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 13, 0, 5, 0), value);\n\t\t\tbreak;\n\tcase ARMV8_PC:/* PC\n\t\t * read r0 from DCC; then \"MOV pc, r0\" */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MCR_DLR(0), value);\n\t\tbreak;\n\tcase ARMV8_XPSR: /* CPSR */\n\t\t/* read r0 from DCC, then \"MCR r0, DSPSR\" */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MCR_DSPSR(0), value);\n\t\tbreak;\n\tcase ARMV8_ELR_EL1: /* mapped to LR_svc */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 14, 0, 5, 0),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_ELR_EL2: /* mapped to ELR_hyp */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP_T1(0, 14, 0, 1),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_ELR_EL3: /* mapped to LR_mon */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\t\tARMV4_5_MRC(14, 0, 14, 0, 5, 0),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_ESR_EL1: /* mapped to DFSR */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 0, 0, 5, 0, 0),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_ESR_EL2: /* mapped to HSR */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV4_5_MCR(15, 4, 0, 5, 2, 0),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_ESR_EL3: /* FIXME: no equivalent in aarch32? */\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\tcase ARMV8_SPSR_EL1: /* mapped to SPSR_svc */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP_XPSR_T1(1, 0, 15),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL2: /* mapped to SPSR_hyp */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP_XPSR_T1(1, 0, 15),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_SPSR_EL3: /* mapped to SPSR_mon */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\tARMV8_MSR_GP_XPSR_T1(1, 0, 15),\n\t\t\t\tvalue);\n\t\tbreak;\n\tcase ARMV8_FPSR:\n\t\t/* move to r0 from DCC, then \"VMSR FPSCR, r0\" */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_VMSR(0), value);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n\n}\n\nstatic int armv8_write_reg_simdfp_aarch32(struct armv8_common *armv8, int regnum, uint64_t lvalue, uint64_t hvalue)\n{\n\tint retval = ERROR_FAIL;\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tstruct reg *reg_r1 = dpm->arm->core_cache->reg_list + ARMV8_R1;\n\tuint32_t value_r0 = 0, value_r1 = 0;\n\tunsigned num = (regnum - ARMV8_V0) << 1;\n\n\tswitch (regnum) {\n\tcase ARMV8_V0 ... ARMV8_V15:\n\t\t/* we are going to write R1, mark it dirty */\n\t\treg_r1->dirty = true;\n\t\tvalue_r1 = lvalue >> 32;\n\t\tvalue_r0 = lvalue & 0xFFFFFFFF;\n\t\t/* write value_r1 to r1 via dcc */\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\tARMV4_5_MRC(14, 0, 1, 0, 5, 0),\n\t\t\tvalue_r1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\t/* write value_r0 to r0 via dcc then,\n\t\t * move to double word register from r0:r1: \"vmov vm, r0, r1\"\n\t\t */\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_VMOV(0, 1, 0, (num >> 4), (num & 0xf)),\n\t\t\tvalue_r0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tnum++;\n\t\t/* repeat above steps for high 64 bits of V register */\n\t\tvalue_r1 = hvalue >> 32;\n\t\tvalue_r0 = hvalue & 0xFFFFFFFF;\n\t\tretval = dpm->instr_write_data_dcc(dpm,\n\t\t\tARMV4_5_MRC(14, 0, 1, 0, 5, 0),\n\t\t\tvalue_r1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_VMOV(0, 1, 0, (num >> 4), (num & 0xf)),\n\t\t\tvalue_r0);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nvoid armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64)\n{\n\tif (is_aarch64) {\n\t\tarmv8->read_reg_u64 = armv8_read_reg;\n\t\tarmv8->write_reg_u64 = armv8_write_reg;\n\t\tarmv8->read_reg_u128 = armv8_read_reg_simdfp_aarch64;\n\t\tarmv8->write_reg_u128 = armv8_write_reg_simdfp_aarch64;\n\n\t} else {\n\t\tarmv8->read_reg_u64 = armv8_read_reg32;\n\t\tarmv8->write_reg_u64 = armv8_write_reg32;\n\t\tarmv8->read_reg_u128 = armv8_read_reg_simdfp_aarch32;\n\t\tarmv8->write_reg_u128 = armv8_write_reg_simdfp_aarch32;\n\t}\n}\n\n/*  retrieve core id cluster id  */\nint armv8_read_mpidr(struct armv8_common *armv8)\n{\n\tint retval = ERROR_FAIL;\n\tstruct arm *arm = &armv8->arm;\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tuint32_t mpidr;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* check if we're in an unprivileged mode */\n\tif (armv8_curel_from_core_mode(arm->core_mode) < SYSTEM_CUREL_EL1) {\n\t\tretval = armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\tif (mpidr & 1U<<31) {\n\t\tarmv8->multi_processor_system = (mpidr >> 30) & 1;\n\t\tarmv8->cluster_id = (mpidr >> 8) & 0xf;\n\t\tarmv8->cpu_id = mpidr & 0x3;\n\t\tLOG_INFO(\"%s cluster %x core %x %s\", target_name(armv8->arm.target),\n\t\t\tarmv8->cluster_id,\n\t\t\tarmv8->cpu_id,\n\t\t\tarmv8->multi_processor_system == 0 ? \"multi core\" : \"single core\");\n\t} else\n\t\tLOG_ERROR(\"mpidr not in multiprocessor format\");\n\ndone:\n\tarmv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\n/**\n * Configures host-side ARM records to reflect the specified CPSR.\n * Later, code can use arm_reg_current() to map register numbers\n * according to how they are exposed by this mode.\n */\nvoid armv8_set_cpsr(struct arm *arm, uint32_t cpsr)\n{\n\tuint32_t mode = cpsr & 0x1F;\n\n\t/* NOTE:  this may be called very early, before the register\n\t * cache is set up.  We can't defend against many errors, in\n\t * particular against CPSRs that aren't valid *here* ...\n\t */\n\tif (arm->cpsr) {\n\t\tbuf_set_u32(arm->cpsr->value, 0, 32, cpsr);\n\t\tarm->cpsr->valid = true;\n\t\tarm->cpsr->dirty = false;\n\t}\n\n\t/* Older ARMs won't have the J bit */\n\tenum arm_state state = 0xFF;\n\n\tif ((cpsr & 0x10) != 0) {\n\t\t/* Aarch32 state */\n\t\tif (cpsr & (1 << 5)) {\t/* T */\n\t\t\tif (cpsr & (1 << 24)) { /* J */\n\t\t\t\tLOG_WARNING(\"ThumbEE -- incomplete support\");\n\t\t\t\tstate = ARM_STATE_THUMB_EE;\n\t\t\t} else\n\t\t\t\tstate = ARM_STATE_THUMB;\n\t\t} else {\n\t\t\tif (cpsr & (1 << 24)) { /* J */\n\t\t\t\tLOG_ERROR(\"Jazelle state handling is BROKEN!\");\n\t\t\t\tstate = ARM_STATE_JAZELLE;\n\t\t\t} else\n\t\t\t\tstate = ARM_STATE_ARM;\n\t\t}\n\t} else {\n\t\t/* Aarch64 state */\n\t\tstate = ARM_STATE_AARCH64;\n\t}\n\n\tarm->core_state = state;\n\tarm->core_mode = mode;\n\n\tLOG_DEBUG(\"set CPSR %#8.8x: %s mode, %s state\", (unsigned) cpsr,\n\t\tarmv8_mode_name(arm->core_mode),\n\t\tarmv8_state_strings[arm->core_state]);\n}\n\nstatic void armv8_show_fault_registers32(struct armv8_common *armv8)\n{\n\tuint32_t dfsr, ifsr, dfar, ifar;\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn;\n\n\t/* ARMV4_5_MRC(cpnum, op1, r0, crn, crm, op2) */\n\n\t/* c5/c0 - {data, instruction} fault status registers */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 5, 0, 0),\n\t\t\t&dfsr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 5, 0, 1),\n\t\t\t&ifsr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* c6/c0 - {data, instruction} fault address registers */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 6, 0, 0),\n\t\t\t&dfar);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(15, 0, 0, 6, 0, 2),\n\t\t\t&ifar);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tLOG_USER(\"Data fault registers        DFSR: %8.8\" PRIx32\n\t\t\", DFAR: %8.8\" PRIx32, dfsr, dfar);\n\tLOG_USER(\"Instruction fault registers IFSR: %8.8\" PRIx32\n\t\t\", IFAR: %8.8\" PRIx32, ifsr, ifar);\n\ndone:\n\t/* (void) */ dpm->finish(dpm);\n}\n\nstatic __attribute__((unused)) void armv8_show_fault_registers(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\n\tif (armv8->arm.core_state != ARM_STATE_AARCH64)\n\t\tarmv8_show_fault_registers32(armv8);\n}\n\n/*  method adapted to cortex A : reused arm v4 v5 method*/\nint armv8_mmu_translate_va(struct target *target,  target_addr_t va, target_addr_t *val)\n{\n\treturn ERROR_OK;\n}\n\n/*  V8 method VA TO PA  */\nint armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,\n\ttarget_addr_t *val, int meminfo)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = &armv8->dpm;\n\tenum arm_mode target_mode = ARM_MODE_ANY;\n\tuint32_t retval;\n\tuint32_t instr = 0;\n\tuint64_t par;\n\n\tstatic const char * const shared_name[] = {\n\t\t\t\"Non-\", \"UNDEFINED \", \"Outer \", \"Inner \"\n\t};\n\n\tstatic const char * const secure_name[] = {\n\t\t\t\"Secure\", \"Not Secure\"\n\t};\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s not halted\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tswitch (armv8_curel_from_core_mode(arm->core_mode)) {\n\tcase SYSTEM_CUREL_EL0:\n\t\tinstr = ARMV8_SYS(SYSTEM_ATS12E0R, 0);\n\t\t/* can only execute instruction at EL2 */\n\t\ttarget_mode = ARMV8_64_EL2H;\n\t\tbreak;\n\tcase SYSTEM_CUREL_EL1:\n\t\tinstr = ARMV8_SYS(SYSTEM_ATS12E1R, 0);\n\t\t/* can only execute instruction at EL2 */\n\t\ttarget_mode = ARMV8_64_EL2H;\n\t\tbreak;\n\tcase SYSTEM_CUREL_EL2:\n\t\tinstr = ARMV8_SYS(SYSTEM_ATS1E2R, 0);\n\t\tbreak;\n\tcase SYSTEM_CUREL_EL3:\n\t\tinstr = ARMV8_SYS(SYSTEM_ATS1E3R, 0);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t};\n\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(dpm, target_mode);\n\n\t/* write VA to R0 and execute translation instruction */\n\tretval = dpm->instr_write_data_r0_64(dpm, instr, (uint64_t)va);\n\t/* read result from PAR_EL1 */\n\tif (retval == ERROR_OK)\n\t\tretval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_PAR_EL1, 0), &par);\n\n\t/* switch back to saved PE mode */\n\tif (target_mode != ARM_MODE_ANY)\n\t\tarmv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\n\tdpm->finish(dpm);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (par & 1) {\n\t\tLOG_ERROR(\"Address translation failed at stage %i, FST=%x, PTW=%i\",\n\t\t\t\t((int)(par >> 9) & 1)+1, (int)(par >> 1) & 0x3f, (int)(par >> 8) & 1);\n\n\t\t*val = 0;\n\t\tretval = ERROR_FAIL;\n\t} else {\n\t\t*val = (par & 0xFFFFFFFFF000UL) | (va & 0xFFF);\n\t\tif (meminfo) {\n\t\t\tint SH = (par >> 7) & 3;\n\t\t\tint NS = (par >> 9) & 1;\n\t\t\tint ATTR = (par >> 56) & 0xFF;\n\n\t\t\tchar *memtype = (ATTR & 0xF0) == 0 ? \"Device Memory\" : \"Normal Memory\";\n\n\t\t\tLOG_USER(\"%sshareable, %s\",\n\t\t\t\t\tshared_name[SH], secure_name[NS]);\n\t\t\tLOG_USER(\"%s\", memtype);\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(armv8_handle_exception_catch_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tuint32_t edeccr = 0;\n\tunsigned int argp = 0;\n\tint retval;\n\n\tstatic const struct nvp nvp_ecatch_modes[] = {\n\t\t{ .name = \"off\",       .value = 0 },\n\t\t{ .name = \"nsec_el1\",  .value = (1 << 5) },\n\t\t{ .name = \"nsec_el2\",  .value = (2 << 5) },\n\t\t{ .name = \"nsec_el12\", .value = (3 << 5) },\n\t\t{ .name = \"sec_el1\",   .value = (1 << 1) },\n\t\t{ .name = \"sec_el3\",   .value = (4 << 1) },\n\t\t{ .name = \"sec_el13\",  .value = (5 << 1) },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\tconst struct nvp *n;\n\n\tif (CMD_ARGC == 0) {\n\t\tconst char *sec = NULL, *nsec = NULL;\n\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\tarmv8->debug_base + CPUV8_DBG_ECCR, &edeccr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tn = nvp_value2name(nvp_ecatch_modes, edeccr & 0x0f);\n\t\tif (n->name)\n\t\t\tsec = n->name;\n\n\t\tn = nvp_value2name(nvp_ecatch_modes, edeccr & 0xf0);\n\t\tif (n->name)\n\t\t\tnsec = n->name;\n\n\t\tif (!sec || !nsec) {\n\t\t\tLOG_WARNING(\"Exception Catch: unknown exception catch configuration: EDECCR = %02\" PRIx32, edeccr & 0xff);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tcommand_print(CMD, \"Exception Catch: Secure: %s, Non-Secure: %s\", sec, nsec);\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (argp < CMD_ARGC) {\n\t\tn = nvp_name2value(nvp_ecatch_modes, CMD_ARGV[argp]);\n\t\tif (!n->name) {\n\t\t\tLOG_ERROR(\"Unknown option: %s\", CMD_ARGV[argp]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tLOG_DEBUG(\"found: %s\", n->name);\n\n\t\tedeccr |= n->value;\n\t\targp++;\n\t}\n\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_ECCR, edeccr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(armv8_pauth_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t\t\t    &armv8->enable_pauth,\n\t\t\t\t    \"pauth feature\");\n}\n\nint armv8_handle_cache_info_command(struct command_invocation *cmd,\n\tstruct armv8_cache_common *armv8_cache)\n{\n\tif (armv8_cache->info == -1) {\n\t\tcommand_print(cmd, \"cache not yet identified\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (armv8_cache->display_cache_info)\n\t\tarmv8_cache->display_cache_info(cmd, armv8_cache);\n\treturn ERROR_OK;\n}\n\nstatic int armv8_setup_semihosting(struct target *target, int enable)\n{\n\treturn ERROR_OK;\n}\n\nint armv8_init_arch_info(struct target *target, struct armv8_common *armv8)\n{\n\tstruct arm *arm = &armv8->arm;\n\tarm->arch_info = armv8;\n\ttarget->arch_info = &armv8->arm;\n\tarm->setup_semihosting = armv8_setup_semihosting;\n\t/*  target is useful in all function arm v4 5 compatible */\n\tarmv8->arm.target = target;\n\tarmv8->arm.common_magic = ARM_COMMON_MAGIC;\n\tarmv8->common_magic = ARMV8_COMMON_MAGIC;\n\n\tarmv8->armv8_mmu.armv8_cache.l2_cache = NULL;\n\tarmv8->armv8_mmu.armv8_cache.info = -1;\n\tarmv8->armv8_mmu.armv8_cache.flush_all_data_cache = NULL;\n\tarmv8->armv8_mmu.armv8_cache.display_cache_info = NULL;\n\treturn ERROR_OK;\n}\n\nstatic int armv8_aarch64_state(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tif (arm->common_magic != ARM_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-ARM target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_USER(\"%s halted in %s state due to %s, current mode: %s\\n\"\n\t\t\"cpsr: 0x%8.8\" PRIx32 \" pc: 0x%\" PRIx64 \"%s\",\n\t\ttarget_name(target),\n\t\tarmv8_state_strings[arm->core_state],\n\t\tdebug_reason_name(target),\n\t\tarmv8_mode_name(arm->core_mode),\n\t\tbuf_get_u32(arm->cpsr->value, 0, 32),\n\t\tbuf_get_u64(arm->pc->value, 0, 64),\n\t\t(target->semihosting && target->semihosting->is_active) ? \", semihosting\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nint armv8_arch_state(struct target *target)\n{\n\tstatic const char * const state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\n\tif (armv8->common_magic != ARMV8_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-Armv8 target\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (arm->core_state == ARM_STATE_AARCH64)\n\t\tarmv8_aarch64_state(target);\n\telse\n\t\tarm_arch_state(target);\n\n\tLOG_USER(\"MMU: %s, D-Cache: %s, I-Cache: %s\",\n\t\tstate[armv8->armv8_mmu.mmu_enabled],\n\t\tstate[armv8->armv8_mmu.armv8_cache.d_u_cache_enabled],\n\t\tstate[armv8->armv8_mmu.armv8_cache.i_cache_enabled]);\n\n\tif (arm->core_mode == ARM_MODE_ABT)\n\t\tarmv8_show_fault_registers(target);\n\n\tif (target->debug_reason == DBG_REASON_WATCHPOINT)\n\t\tLOG_USER(\"Watchpoint triggered at \" TARGET_ADDR_FMT, armv8->dpm.wp_addr);\n\n\treturn ERROR_OK;\n}\n\nstatic struct reg_data_type aarch64_vector_base_types[] = {\n\t{REG_TYPE_IEEE_DOUBLE, \"ieee_double\", 0, {NULL} },\n\t{REG_TYPE_UINT64, \"uint64\", 0, {NULL} },\n\t{REG_TYPE_INT64, \"int64\", 0, {NULL} },\n\t{REG_TYPE_IEEE_SINGLE, \"ieee_single\", 0, {NULL} },\n\t{REG_TYPE_UINT32, \"uint32\", 0, {NULL} },\n\t{REG_TYPE_INT32, \"int32\", 0, {NULL} },\n\t{REG_TYPE_UINT16, \"uint16\", 0, {NULL} },\n\t{REG_TYPE_INT16, \"int16\", 0, {NULL} },\n\t{REG_TYPE_UINT8, \"uint8\", 0, {NULL} },\n\t{REG_TYPE_INT8, \"int8\", 0, {NULL} },\n\t{REG_TYPE_UINT128, \"uint128\", 0, {NULL} },\n\t{REG_TYPE_INT128, \"int128\", 0, {NULL} }\n};\n\nstatic struct reg_data_type_vector aarch64_vector_types[] = {\n\t{aarch64_vector_base_types + 0, 2},\n\t{aarch64_vector_base_types + 1, 2},\n\t{aarch64_vector_base_types + 2, 2},\n\t{aarch64_vector_base_types + 3, 4},\n\t{aarch64_vector_base_types + 4, 4},\n\t{aarch64_vector_base_types + 5, 4},\n\t{aarch64_vector_base_types + 6, 8},\n\t{aarch64_vector_base_types + 7, 8},\n\t{aarch64_vector_base_types + 8, 16},\n\t{aarch64_vector_base_types + 9, 16},\n\t{aarch64_vector_base_types + 10, 01},\n\t{aarch64_vector_base_types + 11, 01},\n};\n\nstatic struct reg_data_type aarch64_fpu_vector[] = {\n\t{REG_TYPE_ARCH_DEFINED, \"v2d\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 0} },\n\t{REG_TYPE_ARCH_DEFINED, \"v2u\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 1} },\n\t{REG_TYPE_ARCH_DEFINED, \"v2i\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 2} },\n\t{REG_TYPE_ARCH_DEFINED, \"v4f\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 3} },\n\t{REG_TYPE_ARCH_DEFINED, \"v4u\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 4} },\n\t{REG_TYPE_ARCH_DEFINED, \"v4i\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 5} },\n\t{REG_TYPE_ARCH_DEFINED, \"v8u\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 6} },\n\t{REG_TYPE_ARCH_DEFINED, \"v8i\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 7} },\n\t{REG_TYPE_ARCH_DEFINED, \"v16u\", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 8} },\n\t{REG_TYPE_ARCH_DEFINED, \"v16i\", REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 9} },\n\t{REG_TYPE_ARCH_DEFINED, \"v1u\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 10} },\n\t{REG_TYPE_ARCH_DEFINED, \"v1i\",  REG_TYPE_CLASS_VECTOR, {aarch64_vector_types + 11} },\n};\n\nstatic struct reg_data_type_union_field aarch64_union_fields_vnd[] = {\n\t{\"f\", aarch64_fpu_vector + 0, aarch64_union_fields_vnd + 1},\n\t{\"u\", aarch64_fpu_vector + 1, aarch64_union_fields_vnd + 2},\n\t{\"s\", aarch64_fpu_vector + 2, NULL},\n};\n\nstatic struct reg_data_type_union_field aarch64_union_fields_vns[] = {\n\t{\"f\", aarch64_fpu_vector + 3, aarch64_union_fields_vns + 1},\n\t{\"u\", aarch64_fpu_vector + 4, aarch64_union_fields_vns + 2},\n\t{\"s\", aarch64_fpu_vector + 5, NULL},\n};\n\nstatic struct reg_data_type_union_field aarch64_union_fields_vnh[] = {\n\t{\"u\", aarch64_fpu_vector + 6, aarch64_union_fields_vnh + 1},\n\t{\"s\", aarch64_fpu_vector + 7, NULL},\n};\n\nstatic struct reg_data_type_union_field aarch64_union_fields_vnb[] = {\n\t{\"u\", aarch64_fpu_vector + 8, aarch64_union_fields_vnb + 1},\n\t{\"s\", aarch64_fpu_vector + 9, NULL},\n};\n\nstatic struct reg_data_type_union_field aarch64_union_fields_vnq[] = {\n\t{\"u\", aarch64_fpu_vector + 10, aarch64_union_fields_vnq + 1},\n\t{\"s\", aarch64_fpu_vector + 11, NULL},\n};\n\nstatic struct reg_data_type_union aarch64_union_types[] = {\n\t{aarch64_union_fields_vnd},\n\t{aarch64_union_fields_vns},\n\t{aarch64_union_fields_vnh},\n\t{aarch64_union_fields_vnb},\n\t{aarch64_union_fields_vnq},\n};\n\nstatic struct reg_data_type aarch64_fpu_union[] = {\n\t{REG_TYPE_ARCH_DEFINED, \"vnd\", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 0} },\n\t{REG_TYPE_ARCH_DEFINED, \"vns\", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 1} },\n\t{REG_TYPE_ARCH_DEFINED, \"vnh\", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 2} },\n\t{REG_TYPE_ARCH_DEFINED, \"vnb\", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 3} },\n\t{REG_TYPE_ARCH_DEFINED, \"vnq\", REG_TYPE_CLASS_UNION, {.reg_type_union = aarch64_union_types + 4} },\n};\n\nstatic struct reg_data_type_union_field aarch64v_union_fields[] = {\n\t{\"d\", aarch64_fpu_union + 0, aarch64v_union_fields + 1},\n\t{\"s\", aarch64_fpu_union + 1, aarch64v_union_fields + 2},\n\t{\"h\", aarch64_fpu_union + 2, aarch64v_union_fields + 3},\n\t{\"b\", aarch64_fpu_union + 3, aarch64v_union_fields + 4},\n\t{\"q\", aarch64_fpu_union + 4, NULL},\n};\n\nstatic struct reg_data_type_union aarch64v_union[] = {\n\t{aarch64v_union_fields}\n};\n\nstatic struct reg_data_type aarch64v[] = {\n\t{REG_TYPE_ARCH_DEFINED, \"aarch64v\", REG_TYPE_CLASS_UNION,\n\t\t{.reg_type_union = aarch64v_union} },\n};\n\nstatic struct reg_data_type_bitfield aarch64_cpsr_bits[] = {\n\t{  0,  0, REG_TYPE_UINT8 },\n\t{  2,  3, REG_TYPE_UINT8 },\n\t{  4,  4, REG_TYPE_UINT8 },\n\t{  6,  6, REG_TYPE_BOOL },\n\t{  7,  7, REG_TYPE_BOOL },\n\t{  8,  8, REG_TYPE_BOOL },\n\t{  9,  9, REG_TYPE_BOOL },\n\t{ 20, 20, REG_TYPE_BOOL },\n\t{ 21, 21, REG_TYPE_BOOL },\n\t{ 28, 28, REG_TYPE_BOOL },\n\t{ 29, 29, REG_TYPE_BOOL },\n\t{ 30, 30, REG_TYPE_BOOL },\n\t{ 31, 31, REG_TYPE_BOOL },\n};\n\nstatic struct reg_data_type_flags_field aarch64_cpsr_fields[] = {\n\t{ \"SP\",  aarch64_cpsr_bits + 0,  aarch64_cpsr_fields + 1 },\n\t{ \"EL\",  aarch64_cpsr_bits + 1,  aarch64_cpsr_fields + 2 },\n\t{ \"nRW\", aarch64_cpsr_bits + 2,  aarch64_cpsr_fields + 3 },\n\t{ \"F\",   aarch64_cpsr_bits + 3,  aarch64_cpsr_fields + 4 },\n\t{ \"I\",   aarch64_cpsr_bits + 4,  aarch64_cpsr_fields + 5 },\n\t{ \"A\",   aarch64_cpsr_bits + 5,  aarch64_cpsr_fields + 6 },\n\t{ \"D\",   aarch64_cpsr_bits + 6,  aarch64_cpsr_fields + 7 },\n\t{ \"IL\",  aarch64_cpsr_bits + 7,  aarch64_cpsr_fields + 8 },\n\t{ \"SS\",  aarch64_cpsr_bits + 8,  aarch64_cpsr_fields + 9 },\n\t{ \"V\",   aarch64_cpsr_bits + 9,  aarch64_cpsr_fields + 10 },\n\t{ \"C\",   aarch64_cpsr_bits + 10, aarch64_cpsr_fields + 11 },\n\t{ \"Z\",   aarch64_cpsr_bits + 11, aarch64_cpsr_fields + 12 },\n\t{ \"N\",   aarch64_cpsr_bits + 12, NULL }\n};\n\nstatic struct reg_data_type_flags aarch64_cpsr_flags[] = {\n\t{ 4, aarch64_cpsr_fields }\n};\n\nstatic struct reg_data_type aarch64_flags_cpsr[] = {\n\t{REG_TYPE_ARCH_DEFINED, \"cpsr_flags\", REG_TYPE_CLASS_FLAGS,\n\t\t{.reg_type_flags = aarch64_cpsr_flags} },\n};\n\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tunsigned bits;\n\tenum arm_mode mode;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n\tstruct reg_data_type *data_type;\n} armv8_regs[] = {\n\t{ ARMV8_R0,  \"x0\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R1,  \"x1\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R2,  \"x2\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R3,  \"x3\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R4,  \"x4\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R5,  \"x5\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R6,  \"x6\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R7,  \"x7\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R8,  \"x8\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R9,  \"x9\",  64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R10, \"x10\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R11, \"x11\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R12, \"x12\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R13, \"x13\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R14, \"x14\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R15, \"x15\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R16, \"x16\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R17, \"x17\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R18, \"x18\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R19, \"x19\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R20, \"x20\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R21, \"x21\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R22, \"x22\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R23, \"x23\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R24, \"x24\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R25, \"x25\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R26, \"x26\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R27, \"x27\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R28, \"x28\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R29, \"x29\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_R30, \"x30\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\n\t{ ARMV8_SP, \"sp\", 64, ARM_MODE_ANY, REG_TYPE_DATA_PTR, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_PC, \"pc\", 64, ARM_MODE_ANY, REG_TYPE_CODE_PTR, \"general\", \"org.gnu.gdb.aarch64.core\", NULL},\n\t{ ARMV8_XPSR, \"cpsr\", 32, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED,\n\t\t\"general\", \"org.gnu.gdb.aarch64.core\", aarch64_flags_cpsr},\n\t{ ARMV8_V0,  \"v0\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V1,  \"v1\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V2,  \"v2\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V3,  \"v3\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V4,  \"v4\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V5,  \"v5\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V6,  \"v6\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V7,  \"v7\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V8,  \"v8\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V9,  \"v9\",  128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V10, \"v10\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V11, \"v11\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V12, \"v12\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V13, \"v13\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V14, \"v14\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V15, \"v15\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V16, \"v16\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V17, \"v17\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V18, \"v18\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V19, \"v19\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V20, \"v20\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V21, \"v21\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V22, \"v22\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V23, \"v23\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V24, \"v24\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V25, \"v25\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V26, \"v26\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V27, \"v27\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V28, \"v28\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V29, \"v29\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V30, \"v30\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_V31, \"v31\", 128, ARM_MODE_ANY, REG_TYPE_ARCH_DEFINED, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", aarch64v},\n\t{ ARMV8_FPSR, \"fpsr\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", NULL},\n\t{ ARMV8_FPCR, \"fpcr\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"simdfp\", \"org.gnu.gdb.aarch64.fpu\", NULL},\n\n\t{ ARMV8_ELR_EL1, \"ELR_EL1\", 64, ARMV8_64_EL1H, REG_TYPE_CODE_PTR, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_ESR_EL1, \"ESR_EL1\", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_SPSR_EL1, \"SPSR_EL1\", 32, ARMV8_64_EL1H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\n\t{ ARMV8_ELR_EL2, \"ELR_EL2\", 64, ARMV8_64_EL2H, REG_TYPE_CODE_PTR, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_ESR_EL2, \"ESR_EL2\", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_SPSR_EL2, \"SPSR_EL2\", 32, ARMV8_64_EL2H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\n\t{ ARMV8_ELR_EL3, \"ELR_EL3\", 64, ARMV8_64_EL3H, REG_TYPE_CODE_PTR, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_ESR_EL3, \"ESR_EL3\", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_SPSR_EL3, \"SPSR_EL3\", 32, ARMV8_64_EL3H, REG_TYPE_UINT32, \"banked\", \"net.sourceforge.openocd.banked\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNULL},\n\t{ ARMV8_PAUTH_DMASK, \"pauth_dmask\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, \"org.gnu.gdb.aarch64.pauth\", NULL},\n\t{ ARMV8_PAUTH_CMASK, \"pauth_cmask\", 64, ARM_MODE_ANY, REG_TYPE_UINT64, NULL, \"org.gnu.gdb.aarch64.pauth\", NULL},\n};\n\nstatic const struct {\n\tunsigned id;\n\tunsigned mapping;\n\tconst char *name;\n\tunsigned bits;\n\tenum arm_mode mode;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n} armv8_regs32[] = {\n\t{ ARMV8_R0, 0,  \"r0\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R1, 0,  \"r1\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R2, 0,  \"r2\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R3, 0,  \"r3\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R4, 0,  \"r4\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R5, 0,  \"r5\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R6, 0,  \"r6\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R7, 0,  \"r7\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R8, 0,  \"r8\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R9, 0,  \"r9\",  32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R10, 0, \"r10\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R11, 0, \"r11\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R12, 0, \"r12\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R13, 0, \"sp\", 32, ARM_MODE_ANY, REG_TYPE_DATA_PTR, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_R14, 0, \"lr\",  32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_PC, 0, \"pc\",   32, ARM_MODE_ANY, REG_TYPE_CODE_PTR, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_XPSR, 0, \"cpsr\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.arm.core\" },\n\t{ ARMV8_V0, 0, \"d0\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V0, 8, \"d1\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V1, 0, \"d2\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V1, 8, \"d3\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V2, 0, \"d4\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V2, 8, \"d5\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V3, 0, \"d6\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V3, 8, \"d7\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V4, 0, \"d8\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V4, 8, \"d9\",  64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V5, 0, \"d10\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V5, 8, \"d11\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V6, 0, \"d12\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V6, 8, \"d13\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V7, 0, \"d14\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V7, 8, \"d15\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V8, 0, \"d16\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V8, 8, \"d17\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V9, 0, \"d18\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V9, 8, \"d19\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V10, 0, \"d20\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V10, 8, \"d21\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V11, 0, \"d22\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V11, 8, \"d23\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V12, 0, \"d24\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V12, 8, \"d25\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V13, 0, \"d26\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V13, 8, \"d27\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V14, 0, \"d28\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V14, 8, \"d29\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V15, 0, \"d30\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_V15, 8, \"d31\", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, \"org.gnu.gdb.arm.vfp\"},\n\t{ ARMV8_FPSR, 0, \"fpscr\", 32, ARM_MODE_ANY, REG_TYPE_UINT32, \"float\", \"org.gnu.gdb.arm.vfp\"},\n};\n\n#define ARMV8_NUM_REGS ARRAY_SIZE(armv8_regs)\n#define ARMV8_NUM_REGS32 ARRAY_SIZE(armv8_regs32)\n\nstatic int armv8_get_core_reg(struct reg *reg)\n{\n\tstruct arm_reg *armv8_reg = reg->arch_info;\n\tstruct target *target = armv8_reg->target;\n\tstruct arm *arm = target_to_arm(target);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\treturn arm->read_core_reg(target, reg, armv8_reg->num, arm->core_mode);\n}\n\nstatic int armv8_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct arm_reg *armv8_reg = reg->arch_info;\n\tstruct target *target = armv8_reg->target;\n\tstruct arm *arm = target_to_arm(target);\n\tuint64_t value = buf_get_u64(buf, 0, reg->size);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (reg->size <= 64) {\n\t\tif (reg == arm->cpsr)\n\t\t\tarmv8_set_cpsr(arm, (uint32_t)value);\n\t\telse {\n\t\t\tbuf_set_u64(reg->value, 0, reg->size, value);\n\t\t\treg->valid = true;\n\t\t}\n\t} else if (reg->size <= 128) {\n\t\tuint64_t hvalue = buf_get_u64(buf + 8, 0, reg->size - 64);\n\n\t\tbuf_set_u64(reg->value, 0, 64, value);\n\t\tbuf_set_u64(reg->value + 8, 0, reg->size - 64, hvalue);\n\t\treg->valid = true;\n\t}\n\n\treg->dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type armv8_reg_type = {\n\t.get = armv8_get_core_reg,\n\t.set = armv8_set_core_reg,\n};\n\nstatic int armv8_get_core_reg32(struct reg *reg)\n{\n\tstruct arm_reg *armv8_reg = reg->arch_info;\n\tstruct target *target = armv8_reg->target;\n\tstruct arm *arm = target_to_arm(target);\n\tstruct reg_cache *cache = arm->core_cache;\n\tstruct reg *reg64;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/* get the corresponding Aarch64 register */\n\treg64 = cache->reg_list + armv8_reg->num;\n\tif (reg64->valid) {\n\t\treg->valid = true;\n\t\treturn ERROR_OK;\n\t}\n\n\tretval = arm->read_core_reg(target, reg64, armv8_reg->num, arm->core_mode);\n\tif (retval == ERROR_OK)\n\t\treg->valid = reg64->valid;\n\n\treturn retval;\n}\n\nstatic int armv8_set_core_reg32(struct reg *reg, uint8_t *buf)\n{\n\tstruct arm_reg *armv8_reg = reg->arch_info;\n\tstruct target *target = armv8_reg->target;\n\tstruct arm *arm = target_to_arm(target);\n\tstruct reg_cache *cache = arm->core_cache;\n\tstruct reg *reg64 = cache->reg_list + armv8_reg->num;\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (reg64 == arm->cpsr) {\n\t\tarmv8_set_cpsr(arm, value);\n\t} else {\n\t\tif (reg->size <= 32)\n\t\t\tbuf_set_u32(reg->value, 0, 32, value);\n\t\telse if (reg->size <= 64) {\n\t\t\tuint64_t value64 = buf_get_u64(buf, 0, 64);\n\t\t\tbuf_set_u64(reg->value, 0, 64, value64);\n\t\t}\n\t\treg->valid = true;\n\t\treg64->valid = true;\n\t}\n\n\treg64->dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type armv8_reg32_type = {\n\t.get = armv8_get_core_reg32,\n\t.set = armv8_set_core_reg32,\n};\n\n/** Builds cache of architecturally defined registers.  */\nstruct reg_cache *armv8_build_reg_cache(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\tint num_regs = ARMV8_NUM_REGS;\n\tint num_regs32 = ARMV8_NUM_REGS32;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg_cache *cache32 = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct reg *reg_list32 = calloc(num_regs32, sizeof(struct reg));\n\tstruct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));\n\tstruct reg_feature *feature;\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"Aarch64 registers\";\n\tcache->next = cache32;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i].num = armv8_regs[i].id;\n\t\tarch_info[i].mode = armv8_regs[i].mode;\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].arm = arm;\n\n\t\treg_list[i].name = armv8_regs[i].name;\n\t\treg_list[i].size = armv8_regs[i].bits;\n\t\treg_list[i].value = &arch_info[i].value[0];\n\t\treg_list[i].type = &armv8_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\n\t\treg_list[i].group = armv8_regs[i].group;\n\t\treg_list[i].number = i;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].caller_save = true;\t/* gdb defaults to true */\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = armv8_regs[i].feature;\n\t\t\treg_list[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate feature list\");\n\n\t\treg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\tif (reg_list[i].reg_data_type) {\n\t\t\tif (!armv8_regs[i].data_type)\n\t\t\t\treg_list[i].reg_data_type->type = armv8_regs[i].type;\n\t\t\telse\n\t\t\t\t*reg_list[i].reg_data_type = *armv8_regs[i].data_type;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate reg type list\");\n\n\t\tif (i == ARMV8_PAUTH_CMASK || i == ARMV8_PAUTH_DMASK)\n\t\t\treg_list[i].exist = armv8->enable_pauth;\n\t}\n\n\tarm->cpsr = reg_list + ARMV8_XPSR;\n\tarm->pc = reg_list + ARMV8_PC;\n\tarm->core_cache = cache;\n\n\t/* shadow cache for ARM mode registers */\n\tcache32->name = \"Aarch32 registers\";\n\tcache32->next = NULL;\n\tcache32->reg_list = reg_list32;\n\tcache32->num_regs = num_regs32;\n\n\tfor (i = 0; i < num_regs32; i++) {\n\t\treg_list32[i].name = armv8_regs32[i].name;\n\t\treg_list32[i].size = armv8_regs32[i].bits;\n\t\treg_list32[i].value = &arch_info[armv8_regs32[i].id].value[armv8_regs32[i].mapping];\n\t\treg_list32[i].type = &armv8_reg32_type;\n\t\treg_list32[i].arch_info = &arch_info[armv8_regs32[i].id];\n\t\treg_list32[i].group = armv8_regs32[i].group;\n\t\treg_list32[i].number = i;\n\t\treg_list32[i].exist = true;\n\t\treg_list32[i].caller_save = true;\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = armv8_regs32[i].feature;\n\t\t\treg_list32[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate feature list\");\n\n\t\treg_list32[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\tif (reg_list32[i].reg_data_type)\n\t\t\treg_list32[i].reg_data_type->type = armv8_regs32[i].type;\n\t\telse\n\t\t\tLOG_ERROR(\"unable to allocate reg type list\");\n\t}\n\n\t(*cache_p) = cache;\n\treturn cache;\n}\n\nstruct reg *armv8_reg_current(struct arm *arm, unsigned regnum)\n{\n\tstruct reg *r;\n\n\tif (regnum > (ARMV8_LAST_REG - 1))\n\t\treturn NULL;\n\n\tr = arm->core_cache->reg_list + regnum;\n\treturn r;\n}\n\nstatic void armv8_free_cache(struct reg_cache *cache, bool regs32)\n{\n\tstruct reg *reg;\n\tunsigned int i;\n\n\tif (!cache)\n\t\treturn;\n\n\tfor (i = 0; i < cache->num_regs; i++) {\n\t\treg = &cache->reg_list[i];\n\n\t\tfree(reg->feature);\n\t\tfree(reg->reg_data_type);\n\t}\n\n\tif (!regs32)\n\t\tfree(cache->reg_list[0].arch_info);\n\tfree(cache->reg_list);\n\tfree(cache);\n}\n\nvoid armv8_free_reg_cache(struct target *target)\n{\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tstruct arm *arm = &armv8->arm;\n\tstruct reg_cache *cache = NULL, *cache32 = NULL;\n\n\tcache = arm->core_cache;\n\tif (cache)\n\t\tcache32 = cache->next;\n\tarmv8_free_cache(cache32, true);\n\tarmv8_free_cache(cache, false);\n\tarm->core_cache = NULL;\n}\n\nconst struct command_registration armv8_command_handlers[] = {\n\t{\n\t\t.name = \"catch_exc\",\n\t\t.handler = armv8_handle_exception_catch_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure exception catch\",\n\t\t.usage = \"[(nsec_el1,nsec_el2,sec_el1,sec_el3)+,off]\",\n\t},\n\t{\n\t\t.name = \"pauth\",\n\t\t.handler = armv8_pauth_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"enable or disable providing GDB with an 8-bytes mask to \"\n\t\t\t\"remove signature bits added by pointer authentication.\"\n\t\t\t\"Pointer authentication feature is broken until gdb 12.1, going to be fixed. \"\n\t\t\t\"Consider using a newer version of gdb if you want enable \"\n\t\t\t\"pauth feature.\",\n\t\t.usage = \"[on|off]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst char *armv8_get_gdb_arch(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\treturn arm->core_state == ARM_STATE_AARCH64 ? \"aarch64\" : \"arm\";\n}\n\nint armv8_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[], int *reg_list_size,\n\tenum target_register_class reg_class)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tint i;\n\n\tif (arm->core_state == ARM_STATE_AARCH64) {\n\n\t\tLOG_DEBUG(\"Creating Aarch64 register list for target %s\", target_name(target));\n\n\t\tswitch (reg_class) {\n\t\tcase REG_CLASS_GENERAL:\n\t\t\t*reg_list_size = ARMV8_V0;\n\t\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\t\tfor (i = 0; i < *reg_list_size; i++)\n\t\t\t\t\t(*reg_list)[i] = armv8_reg_current(arm, i);\n\t\t\treturn ERROR_OK;\n\n\t\tcase REG_CLASS_ALL:\n\t\t\t*reg_list_size = ARMV8_LAST_REG;\n\t\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\t\tfor (i = 0; i < *reg_list_size; i++)\n\t\t\t\t\t(*reg_list)[i] = armv8_reg_current(arm, i);\n\n\t\t\treturn ERROR_OK;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"not a valid register class type in query.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tstruct reg_cache *cache32 = arm->core_cache->next;\n\n\t\tLOG_DEBUG(\"Creating Aarch32 register list for target %s\", target_name(target));\n\n\t\tswitch (reg_class) {\n\t\tcase REG_CLASS_GENERAL:\n\t\t\t*reg_list_size = ARMV8_R14 + 3;\n\t\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\t\tfor (i = 0; i < *reg_list_size; i++)\n\t\t\t\t(*reg_list)[i] = cache32->reg_list + i;\n\n\t\t\treturn ERROR_OK;\n\t\tcase REG_CLASS_ALL:\n\t\t\t*reg_list_size = cache32->num_regs;\n\t\t\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\t\t\tfor (i = 0; i < *reg_list_size; i++)\n\t\t\t\t(*reg_list)[i] = cache32->reg_list + i;\n\n\t\t\treturn ERROR_OK;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"not a valid register class type in query.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n}\n\nint armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value)\n{\n\tuint32_t tmp;\n\n\t/* Read register */\n\tint retval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + reg, &tmp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* clear bitfield */\n\ttmp &= ~mask;\n\t/* put new value */\n\ttmp |= value & mask;\n\n\t/* write new value */\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + reg, tmp);\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2015 by David Ung                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ARMV8_H\n#define OPENOCD_TARGET_ARMV8_H\n\n#include \"arm_adi_v5.h\"\n#include \"arm.h\"\n#include \"armv4_5_mmu.h\"\n#include \"armv4_5_cache.h\"\n#include \"armv8_dpm.h\"\n#include \"arm_cti.h\"\n\nenum {\n\tARMV8_R0 = 0,\n\tARMV8_R1,\n\tARMV8_R2,\n\tARMV8_R3,\n\tARMV8_R4,\n\tARMV8_R5,\n\tARMV8_R6,\n\tARMV8_R7,\n\tARMV8_R8,\n\tARMV8_R9,\n\tARMV8_R10,\n\tARMV8_R11,\n\tARMV8_R12,\n\tARMV8_R13,\n\tARMV8_R14,\n\tARMV8_R15,\n\tARMV8_R16,\n\tARMV8_R17,\n\tARMV8_R18,\n\tARMV8_R19,\n\tARMV8_R20,\n\tARMV8_R21,\n\tARMV8_R22,\n\tARMV8_R23,\n\tARMV8_R24,\n\tARMV8_R25,\n\tARMV8_R26,\n\tARMV8_R27,\n\tARMV8_R28,\n\tARMV8_R29,\n\tARMV8_R30,\n\n\tARMV8_SP = 31,\n\tARMV8_PC = 32,\n\tARMV8_XPSR = 33,\n\n\tARMV8_V0 = 34,\n\tARMV8_V1,\n\tARMV8_V2,\n\tARMV8_V3,\n\tARMV8_V4,\n\tARMV8_V5,\n\tARMV8_V6,\n\tARMV8_V7,\n\tARMV8_V8,\n\tARMV8_V9,\n\tARMV8_V10,\n\tARMV8_V11,\n\tARMV8_V12,\n\tARMV8_V13,\n\tARMV8_V14,\n\tARMV8_V15,\n\tARMV8_V16,\n\tARMV8_V17,\n\tARMV8_V18,\n\tARMV8_V19,\n\tARMV8_V20,\n\tARMV8_V21,\n\tARMV8_V22,\n\tARMV8_V23,\n\tARMV8_V24,\n\tARMV8_V25,\n\tARMV8_V26,\n\tARMV8_V27,\n\tARMV8_V28,\n\tARMV8_V29,\n\tARMV8_V30,\n\tARMV8_V31,\n\tARMV8_FPSR,\n\tARMV8_FPCR,\n\n\tARMV8_ELR_EL1 = 68,\n\tARMV8_ESR_EL1 = 69,\n\tARMV8_SPSR_EL1 = 70,\n\n\tARMV8_ELR_EL2 = 71,\n\tARMV8_ESR_EL2 = 72,\n\tARMV8_SPSR_EL2 = 73,\n\n\tARMV8_ELR_EL3 = 74,\n\tARMV8_ESR_EL3 = 75,\n\tARMV8_SPSR_EL3 = 76,\n\n\t/* Pseudo registers defined by GDB to remove the pauth signature. */\n\tARMV8_PAUTH_DMASK = 77,\n\tARMV8_PAUTH_CMASK = 78,\n\n\tARMV8_LAST_REG,\n};\n\nenum run_control_op {\n\tARMV8_RUNCONTROL_UNKNOWN = 0,\n\tARMV8_RUNCONTROL_RESUME = 1,\n\tARMV8_RUNCONTROL_HALT = 2,\n\tARMV8_RUNCONTROL_STEP = 3,\n};\n\n#define ARMV8_COMMON_MAGIC 0x0A450AAAU\n\n/* VA to PA translation operations opc2 values*/\n#define V2PCWPR  0\n#define V2PCWPW  1\n#define V2PCWUR  2\n#define V2PCWUW  3\n#define V2POWPR  4\n#define V2POWPW  5\n#define V2POWUR  6\n#define V2POWUW  7\n/*   L210/L220 cache controller support */\nstruct armv8_l2x_cache {\n\tuint32_t base;\n\tuint32_t way;\n};\n\nstruct armv8_cachesize {\n\tuint32_t level_num;\n\t/*  cache dimensioning */\n\tuint32_t linelen;\n\tuint32_t associativity;\n\tuint32_t nsets;\n\tuint32_t cachesize;\n\t/* info for set way operation on cache */\n\tuint32_t index;\n\tuint32_t index_shift;\n\tuint32_t way;\n\tuint32_t way_shift;\n};\n\n/* information about one architecture cache at any level */\nstruct armv8_arch_cache {\n\tint ctype;\t\t\t\t/* cache type, CLIDR encoding */\n\tstruct armv8_cachesize d_u_size;\t/* data cache */\n\tstruct armv8_cachesize i_size;\t\t/* instruction cache */\n};\n\nstruct armv8_cache_common {\n\tint info;\n\tint loc;\n\tuint32_t iminline;\n\tuint32_t dminline;\n\tstruct armv8_arch_cache arch[6];\t/* cache info, L1 - L7 */\n\tint i_cache_enabled;\n\tint d_u_cache_enabled;\n\n\t/* l2 external unified cache if some */\n\tvoid *l2_cache;\n\tint (*flush_all_data_cache)(struct target *target);\n\tint (*display_cache_info)(struct command_invocation *cmd,\n\t\t\tstruct armv8_cache_common *armv8_cache);\n};\n\nstruct armv8_mmu_common {\n\t/* following field mmu working way */\n\tint32_t ttbr1_used; /*  -1 not initialized, 0 no ttbr1 1 ttbr1 used and  */\n\tuint64_t ttbr0_mask;/*  masked to be used  */\n\n\tuint32_t ttbcr;     /* cache for ttbcr register */\n\tuint32_t ttbr_mask[2];\n\tuint32_t ttbr_range[2];\n\n\tint (*read_physical_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer);\n\tstruct armv8_cache_common armv8_cache;\n\tuint32_t mmu_enabled;\n};\n\nstruct armv8_common {\n\tunsigned int common_magic;\n\n\tstruct arm arm;\n\tstruct reg_cache *core_cache;\n\n\t/* Core Debug Unit */\n\tstruct arm_dpm dpm;\n\ttarget_addr_t debug_base;\n\tstruct adiv5_ap *debug_ap;\n\n\tconst uint32_t *opcodes;\n\n\t/* mdir */\n\tuint8_t multi_processor_system;\n\tuint8_t cluster_id;\n\tuint8_t cpu_id;\n\n\t/* armv8 aarch64 need below information for page translation */\n\tuint8_t va_size;\n\tuint8_t pa_size;\n\tuint32_t page_size;\n\tuint64_t ttbr_base;\n\tbool is_armv8r;\n\n\tstruct armv8_mmu_common armv8_mmu;\n\n\tstruct arm_cti *cti;\n\n\t/* True if OpenOCD provides pointer auth related info to GDB */\n\tbool enable_pauth;\n\n\t/* last run-control command issued to this target (resume, halt, step) */\n\tenum run_control_op last_run_control_op;\n\n\t/* Direct processor core register read and writes */\n\tint (*read_reg_u64)(struct armv8_common *armv8, int num, uint64_t *value);\n\tint (*write_reg_u64)(struct armv8_common *armv8, int num, uint64_t value);\n\n\t/* SIMD/FPU registers read/write interface */\n\tint (*read_reg_u128)(struct armv8_common *armv8, int num,\n\t\t\tuint64_t *lvalue, uint64_t *hvalue);\n\tint (*write_reg_u128)(struct armv8_common *armv8, int num,\n\t\t\tuint64_t lvalue, uint64_t hvalue);\n\n\tint (*examine_debug_reason)(struct target *target);\n\tint (*post_debug_entry)(struct target *target);\n\n\tvoid (*pre_restore_context)(struct target *target);\n};\n\nstatic inline struct armv8_common *\ntarget_to_armv8(struct target *target)\n{\n\treturn container_of(target->arch_info, struct armv8_common, arm);\n}\n\nstatic inline bool is_armv8(struct armv8_common *armv8)\n{\n\treturn armv8->common_magic == ARMV8_COMMON_MAGIC;\n}\n\n/* register offsets from armv8.debug_base */\n#define CPUV8_DBG_MAINID0\t\t0xD00\n#define CPUV8_DBG_CPUFEATURE0\t0xD20\n#define CPUV8_DBG_DBGFEATURE0\t0xD28\n#define CPUV8_DBG_MEMFEATURE0\t0xD38\n\n#define CPUV8_DBG_LOCKACCESS 0xFB0\n#define CPUV8_DBG_LOCKSTATUS 0xFB4\n\n#define CPUV8_DBG_EDESR\t\t0x20\n#define CPUV8_DBG_EDECR\t\t0x24\n#define CPUV8_DBG_EDWAR0\t0x30\n#define CPUV8_DBG_EDWAR1\t0x34\n#define CPUV8_DBG_DSCR\t\t0x088\n#define CPUV8_DBG_DRCR\t\t0x090\n#define CPUV8_DBG_ECCR\t\t0x098\n#define CPUV8_DBG_PRCR\t\t0x310\n#define CPUV8_DBG_PRSR\t\t0x314\n\n#define CPUV8_DBG_DTRRX\t\t0x080\n#define CPUV8_DBG_ITR\t\t0x084\n#define CPUV8_DBG_SCR\t\t0x088\n#define CPUV8_DBG_DTRTX\t\t0x08c\n\n#define CPUV8_DBG_BVR_BASE\t0x400\n#define CPUV8_DBG_BCR_BASE\t0x408\n#define CPUV8_DBG_WVR_BASE\t0x800\n#define CPUV8_DBG_WCR_BASE\t0x808\n#define CPUV8_DBG_VCR\t\t0x01C\n\n#define CPUV8_DBG_OSLAR\t\t0x300\n\n#define CPUV8_DBG_AUTHSTATUS\t0xFB8\n\n#define PAGE_SIZE_4KB\t\t\t\t0x1000\n#define PAGE_SIZE_4KB_LEVEL0_BITS\t39\n#define PAGE_SIZE_4KB_LEVEL1_BITS\t30\n#define PAGE_SIZE_4KB_LEVEL2_BITS\t21\n#define PAGE_SIZE_4KB_LEVEL3_BITS\t12\n\n#define PAGE_SIZE_4KB_LEVEL0_MASK\t((0x1FFULL) << PAGE_SIZE_4KB_LEVEL0_BITS)\n#define PAGE_SIZE_4KB_LEVEL1_MASK\t((0x1FFULL) << PAGE_SIZE_4KB_LEVEL1_BITS)\n#define PAGE_SIZE_4KB_LEVEL2_MASK\t((0x1FFULL) << PAGE_SIZE_4KB_LEVEL2_BITS)\n#define PAGE_SIZE_4KB_LEVEL3_MASK\t((0x1FFULL) << PAGE_SIZE_4KB_LEVEL3_BITS)\n\n#define PAGE_SIZE_4KB_TRBBASE_MASK\t0xFFFFFFFFF000\n\nint armv8_arch_state(struct target *target);\nint armv8_read_mpidr(struct armv8_common *armv8);\nint armv8_identify_cache(struct armv8_common *armv8);\nint armv8_init_arch_info(struct target *target, struct armv8_common *armv8);\nint armv8_mmu_translate_va_pa(struct target *target, target_addr_t va,\n\t\ttarget_addr_t *val, int meminfo);\nint armv8_mmu_translate_va(struct target *target,  target_addr_t va, target_addr_t *val);\n\nint armv8_handle_cache_info_command(struct command_invocation *cmd,\n\t\tstruct armv8_cache_common *armv8_cache);\n\nvoid armv8_set_cpsr(struct arm *arm, uint32_t cpsr);\n\nstatic inline unsigned int armv8_curel_from_core_mode(enum arm_mode core_mode)\n{\n\tswitch (core_mode) {\n\t/* Aarch32 modes */\n\tcase ARM_MODE_USR:\n\t\treturn 0;\n\tcase ARM_MODE_SVC:\n\tcase ARM_MODE_ABT: /* FIXME: EL3? */\n\tcase ARM_MODE_IRQ: /* FIXME: EL3? */\n\tcase ARM_MODE_FIQ: /* FIXME: EL3? */\n\tcase ARM_MODE_UND: /* FIXME: EL3? */\n\tcase ARM_MODE_SYS: /* FIXME: EL3? */\n\t\treturn 1;\n\t/* case ARM_MODE_HYP:\n\t *     return 2;\n\t */\n\tcase ARM_MODE_MON:\n\t\treturn 3;\n\t/* all Aarch64 modes */\n\tdefault:\n\t\treturn (core_mode >> 2) & 3;\n\t}\n}\n\nconst char *armv8_mode_name(unsigned psr_mode);\nvoid armv8_select_reg_access(struct armv8_common *armv8, bool is_aarch64);\nint armv8_set_dbgreg_bits(struct armv8_common *armv8, unsigned int reg, unsigned long mask, unsigned long value);\n\nextern void armv8_free_reg_cache(struct target *target);\n\nextern const struct command_registration armv8_command_handlers[];\n\n#endif /* OPENOCD_TARGET_ARMV8_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_cache.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *   matthias.welwarsky@sysgo.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"armv8_cache.h\"\n#include \"armv8_dpm.h\"\n#include \"armv8_opcodes.h\"\n#include \"smp.h\"\n\n/* CLIDR cache types */\n#define CACHE_LEVEL_HAS_UNIFIED_CACHE\t0x4\n#define CACHE_LEVEL_HAS_D_CACHE\t\t0x2\n#define CACHE_LEVEL_HAS_I_CACHE\t\t0x1\n\nstatic int armv8_d_cache_sanity_check(struct armv8_common *armv8)\n{\n\tstruct armv8_cache_common *armv8_cache = &armv8->armv8_mmu.armv8_cache;\n\n\tif (armv8_cache->d_u_cache_enabled)\n\t\treturn ERROR_OK;\n\n\treturn ERROR_TARGET_INVALID;\n}\n\nstatic int armv8_i_cache_sanity_check(struct armv8_common *armv8)\n{\n\tstruct armv8_cache_common *armv8_cache = &armv8->armv8_mmu.armv8_cache;\n\n\tif (armv8_cache->i_cache_enabled)\n\t\treturn ERROR_OK;\n\n\treturn ERROR_TARGET_INVALID;\n}\n\nstatic int armv8_cache_d_inner_flush_level(struct armv8_common *armv8, struct armv8_cachesize *size, int cl)\n{\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tint retval = ERROR_OK;\n\tint32_t c_way, c_index = size->index;\n\n\tLOG_DEBUG(\"cl %\" PRId32, cl);\n\tdo {\n\t\tc_way = size->way;\n\t\tdo {\n\t\t\tuint32_t value = (c_index << size->index_shift)\n\t\t\t\t| (c_way << size->way_shift) | (cl << 1);\n\t\t\t/*\n\t\t\t * DC CISW - Clean and invalidate data cache\n\t\t\t * line by Set/Way.\n\t\t\t */\n\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\t\tarmv8_opcode(armv8, ARMV8_OPC_DCCISW), value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tc_way -= 1;\n\t\t} while (c_way >= 0);\n\t\tc_index -= 1;\n\t} while (c_index >= 0);\n\n done:\n\treturn retval;\n}\n\nstatic int armv8_cache_d_inner_clean_inval_all(struct armv8_common *armv8)\n{\n\tstruct armv8_cache_common *cache = &(armv8->armv8_mmu.armv8_cache);\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tint cl;\n\tint retval;\n\n\tretval = armv8_d_cache_sanity_check(armv8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tfor (cl = 0; cl < cache->loc; cl++) {\n\t\t/* skip i-only caches */\n\t\tif (cache->arch[cl].ctype < CACHE_LEVEL_HAS_D_CACHE)\n\t\t\tcontinue;\n\n\t\tarmv8_cache_d_inner_flush_level(armv8, &cache->arch[cl].d_u_size, cl);\n\t}\n\n\tretval = dpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"clean invalidate failed\");\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv8_cache_d_inner_flush_virt(struct armv8_common *armv8, target_addr_t va, size_t size)\n{\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tstruct armv8_cache_common *armv8_cache = &armv8->armv8_mmu.armv8_cache;\n\tuint64_t linelen = armv8_cache->dminline;\n\ttarget_addr_t va_line, va_end;\n\tint retval;\n\n\tretval = armv8_d_cache_sanity_check(armv8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = va & (-linelen);\n\tva_end = va + size;\n\n\twhile (va_line < va_end) {\n\t\t/* DC CIVAC */\n\t\t/* Aarch32: DCCIMVAC: ARMV4_5_MCR(15, 0, 0, 7, 14, 1) */\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tarmv8_opcode(armv8, ARMV8_OPC_DCCIVAC), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nint armv8_cache_i_inner_inval_virt(struct armv8_common *armv8, target_addr_t va, size_t size)\n{\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tstruct armv8_cache_common *armv8_cache = &armv8->armv8_mmu.armv8_cache;\n\tuint64_t linelen = armv8_cache->iminline;\n\ttarget_addr_t va_line, va_end;\n\tint retval;\n\n\tretval = armv8_i_cache_sanity_check(armv8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tva_line = va & (-linelen);\n\tva_end = va + size;\n\n\twhile (va_line < va_end) {\n\t\t/* IC IVAU - Invalidate instruction cache by VA to PoU. */\n\t\tretval = dpm->instr_write_data_r0_64(dpm,\n\t\t\t\tarmv8_opcode(armv8, ARMV8_OPC_ICIVAU), va_line);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t\tva_line += linelen;\n\t}\n\n\tdpm->finish(dpm);\n\treturn retval;\n\ndone:\n\tLOG_ERROR(\"d-cache invalidate failed\");\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nstatic int armv8_handle_inner_cache_info_command(struct command_invocation *cmd,\n\tstruct armv8_cache_common *armv8_cache)\n{\n\tint cl;\n\n\tif (armv8_cache->info == -1) {\n\t\tcommand_print(cmd, \"cache not yet identified\");\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (cl = 0; cl < armv8_cache->loc; cl++) {\n\t\tstruct armv8_arch_cache *arch = &(armv8_cache->arch[cl]);\n\n\t\tif (arch->ctype & 1) {\n\t\t\tcommand_print(cmd,\n\t\t\t\t\"L%d I-Cache: linelen %\" PRIu32\n\t\t\t\t\", associativity %\" PRIu32\n\t\t\t\t\", nsets %\" PRIu32\n\t\t\t\t\", cachesize %\" PRIu32 \" KBytes\",\n\t\t\t\tcl+1,\n\t\t\t\tarch->i_size.linelen,\n\t\t\t\tarch->i_size.associativity,\n\t\t\t\tarch->i_size.nsets,\n\t\t\t\tarch->i_size.cachesize);\n\t\t}\n\n\t\tif (arch->ctype >= 2) {\n\t\t\tcommand_print(cmd,\n\t\t\t\t\"L%d D-Cache: linelen %\" PRIu32\n\t\t\t\t\", associativity %\" PRIu32\n\t\t\t\t\", nsets %\" PRIu32\n\t\t\t\t\", cachesize %\" PRIu32 \" KBytes\",\n\t\t\t\tcl+1,\n\t\t\t\tarch->d_u_size.linelen,\n\t\t\t\tarch->d_u_size.associativity,\n\t\t\t\tarch->d_u_size.nsets,\n\t\t\t\tarch->d_u_size.cachesize);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int _armv8_flush_all_data(struct target *target)\n{\n\treturn armv8_cache_d_inner_clean_inval_all(target_to_armv8(target));\n}\n\nstatic int  armv8_flush_all_data(struct target *target)\n{\n\tint retval = ERROR_FAIL;\n\t/*  check that armv8_cache is correctly identify */\n\tstruct armv8_common *armv8 = target_to_armv8(target);\n\tif (armv8->armv8_mmu.armv8_cache.info == -1) {\n\t\tLOG_ERROR(\"trying to flush un-identified cache\");\n\t\treturn retval;\n\t}\n\n\tif (target->smp) {\n\t\t/*  look if all the other target have been flushed in order to flush level\n\t\t *  2 */\n\t\tstruct target_list *head;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tif (curr->state == TARGET_HALTED) {\n\t\t\t\tLOG_INFO(\"Wait flushing data l1 on core %\" PRId32, curr->coreid);\n\t\t\t\tretval = _armv8_flush_all_data(curr);\n\t\t\t}\n\t\t}\n\t} else\n\t\tretval = _armv8_flush_all_data(target);\n\treturn retval;\n}\n\nstatic int get_cache_info(struct arm_dpm *dpm, int cl, int ct, uint32_t *cache_reg)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval = ERROR_OK;\n\n\t/*  select cache level */\n\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, WRITE_REG_CSSELR),\n\t\t\t(cl << 1) | (ct == 1 ? 1 : 0));\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, READ_REG_CCSIDR),\n\t\t\tcache_reg);\n done:\n\treturn retval;\n}\n\nstatic struct armv8_cachesize decode_cache_reg(uint32_t cache_reg)\n{\n\tstruct armv8_cachesize size;\n\tint i = 0;\n\n\tsize.linelen = 16 << (cache_reg & 0x7);\n\tsize.associativity = ((cache_reg >> 3) & 0x3ff) + 1;\n\tsize.nsets = ((cache_reg >> 13) & 0x7fff) + 1;\n\tsize.cachesize = size.linelen * size.associativity * size.nsets / 1024;\n\n\t/*  compute info for set way operation on cache */\n\tsize.index_shift = (cache_reg & 0x7) + 4;\n\tsize.index = (cache_reg >> 13) & 0x7fff;\n\tsize.way = ((cache_reg >> 3) & 0x3ff);\n\n\twhile (((size.way << i) & 0x80000000) == 0)\n\t\ti++;\n\tsize.way_shift = i;\n\n\treturn size;\n}\n\nint armv8_identify_cache(struct armv8_common *armv8)\n{\n\t/*  read cache descriptor */\n\tint retval = ERROR_FAIL;\n\tstruct arm *arm = &armv8->arm;\n\tstruct arm_dpm *dpm = armv8->arm.dpm;\n\tuint32_t csselr, clidr, ctr;\n\tuint32_t cache_reg;\n\tint cl, ctype;\n\tstruct armv8_cache_common *cache = &(armv8->armv8_mmu.armv8_cache);\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* check if we're in an unprivileged mode */\n\tif (armv8_curel_from_core_mode(arm->core_mode) < SYSTEM_CUREL_EL1) {\n\t\tretval = armv8_dpm_modeswitch(dpm, ARMV8_64_EL1H);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* retrieve CTR */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, READ_REG_CTR), &ctr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tcache->iminline = 4UL << (ctr & 0xf);\n\tcache->dminline = 4UL << ((ctr & 0xf0000) >> 16);\n\tLOG_DEBUG(\"ctr %\" PRIx32 \" ctr.iminline %\" PRIu32 \" ctr.dminline %\" PRIu32,\n\t\t ctr, cache->iminline, cache->dminline);\n\n\t/*  retrieve CLIDR */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, READ_REG_CLIDR), &clidr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tcache->loc = (clidr & 0x7000000) >> 24;\n\tLOG_DEBUG(\"Number of cache levels to PoC %\" PRId32, cache->loc);\n\n\t/*  retrieve selected cache for later restore\n\t *  MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, READ_REG_CSSELR), &csselr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* retrieve all available inner caches */\n\tfor (cl = 0; cl < cache->loc; clidr >>= 3, cl++) {\n\n\t\t/* isolate cache type at current level */\n\t\tctype = clidr & 7;\n\n\t\t/* skip reserved values */\n\t\tif (ctype > CACHE_LEVEL_HAS_UNIFIED_CACHE)\n\t\t\tcontinue;\n\n\t\t/* separate d or unified d/i cache at this level ? */\n\t\tif (ctype & (CACHE_LEVEL_HAS_UNIFIED_CACHE | CACHE_LEVEL_HAS_D_CACHE)) {\n\t\t\t/* retrieve d-cache info */\n\t\t\tretval = get_cache_info(dpm, cl, 0, &cache_reg);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tcache->arch[cl].d_u_size = decode_cache_reg(cache_reg);\n\n\t\t\tLOG_DEBUG(\"data/unified cache index %\" PRIu32 \" << %\" PRIu32 \", way %\" PRIu32 \" << %\" PRIu32,\n\t\t\t\t\tcache->arch[cl].d_u_size.index,\n\t\t\t\t\tcache->arch[cl].d_u_size.index_shift,\n\t\t\t\t\tcache->arch[cl].d_u_size.way,\n\t\t\t\t\tcache->arch[cl].d_u_size.way_shift);\n\n\t\t\tLOG_DEBUG(\"cacheline %\" PRIu32 \" bytes %\" PRIu32 \" KBytes asso %\" PRIu32 \" ways\",\n\t\t\t\t\tcache->arch[cl].d_u_size.linelen,\n\t\t\t\t\tcache->arch[cl].d_u_size.cachesize,\n\t\t\t\t\tcache->arch[cl].d_u_size.associativity);\n\t\t}\n\n\t\t/* separate i-cache at this level ? */\n\t\tif (ctype & CACHE_LEVEL_HAS_I_CACHE) {\n\t\t\t/* retrieve i-cache info */\n\t\t\tretval = get_cache_info(dpm, cl, 1, &cache_reg);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t\tcache->arch[cl].i_size = decode_cache_reg(cache_reg);\n\n\t\t\tLOG_DEBUG(\"instruction cache index %\" PRIu32 \" << %\" PRIu32 \", way %\" PRIu32 \" << %\" PRIu32,\n\t\t\t\t\tcache->arch[cl].i_size.index,\n\t\t\t\t\tcache->arch[cl].i_size.index_shift,\n\t\t\t\t\tcache->arch[cl].i_size.way,\n\t\t\t\t\tcache->arch[cl].i_size.way_shift);\n\n\t\t\tLOG_DEBUG(\"cacheline %\" PRIu32 \" bytes %\" PRIu32 \" KBytes asso %\" PRIu32 \" ways\",\n\t\t\t\t\tcache->arch[cl].i_size.linelen,\n\t\t\t\t\tcache->arch[cl].i_size.cachesize,\n\t\t\t\t\tcache->arch[cl].i_size.associativity);\n\t\t}\n\n\t\tcache->arch[cl].ctype = ctype;\n\t}\n\n\t/*  restore selected cache  */\n\tdpm->instr_write_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, WRITE_REG_CSSELR), csselr);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tarmv8->armv8_mmu.armv8_cache.info = 1;\n\n\t/*  if no l2 cache initialize l1 data cache flush function function */\n\tif (!armv8->armv8_mmu.armv8_cache.flush_all_data_cache) {\n\t\tarmv8->armv8_mmu.armv8_cache.display_cache_info =\n\t\t\tarmv8_handle_inner_cache_info_command;\n\t\tarmv8->armv8_mmu.armv8_cache.flush_all_data_cache =\n\t\t\tarmv8_flush_all_data;\n\t}\n\ndone:\n\tarmv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\tdpm->finish(dpm);\n\treturn retval;\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_cache.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2016 by Matthias Welwarsky                              *\n *   matthias.welwarsky@sysgo.com                                          *\n ***************************************************************************/\n#ifndef OPENOCD_TARGET_ARMV8_CACHE_H_\n#define OPENOCD_TARGET_ARMV8_CACHE_H_\n\n#include \"armv8.h\"\n\nextern int armv8_cache_d_inner_flush_virt(struct armv8_common *armv8, target_addr_t va, size_t size);\nextern int armv8_cache_i_inner_inval_virt(struct armv8_common *armv8, target_addr_t va, size_t size);\n\n#endif /* OPENOCD_TARGET_ARMV8_CACHE_H_ */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_dpm.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2009 by David Brownell\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"armv8.h\"\n#include \"armv8_dpm.h\"\n#include <jtag/jtag.h>\n#include \"register.h\"\n#include \"breakpoints.h\"\n#include \"target_type.h\"\n#include \"armv8_opcodes.h\"\n\n#include \"helper/time_support.h\"\n\n/* T32 ITR format */\n#define T32_FMTITR(instr) (((instr & 0x0000FFFF) << 16) | ((instr & 0xFFFF0000) >> 16))\n\n/**\n * @file\n * Implements various ARM DPM operations using architectural debug registers.\n * These routines layer over core-specific communication methods to cope with\n * implementation differences between cores like ARM1136 and Cortex-A8.\n *\n * The \"Debug Programmers' Model\" (DPM) for ARMv6 and ARMv7 is defined by\n * Part C (Debug Architecture) of the ARM Architecture Reference Manual,\n * ARMv7-A and ARMv7-R edition (ARM DDI 0406B).  In OpenOCD, DPM operations\n * are abstracted through internal programming interfaces to share code and\n * to minimize needless differences in debug behavior between cores.\n */\n\n/**\n * Get core state from EDSCR, without necessity to retrieve CPSR\n */\nenum arm_state armv8_dpm_get_core_state(struct arm_dpm *dpm)\n{\n\tint el = (dpm->dscr >> 8) & 0x3;\n\tint rw = (dpm->dscr >> 10) & 0xF;\n\n\tdpm->last_el = el;\n\n\t/* In Debug state, each bit gives the current Execution state of each EL */\n\tif ((rw >> el) & 0b1)\n\t\treturn ARM_STATE_AARCH64;\n\n\treturn ARM_STATE_ARM;\n}\n\n/*----------------------------------------------------------------------*/\n\nstatic int dpmv8_write_dcc(struct armv8_common *armv8, uint32_t data)\n{\n\treturn mem_ap_write_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRRX, data);\n}\n\nstatic int dpmv8_write_dcc_64(struct armv8_common *armv8, uint64_t data)\n{\n\tint ret;\n\tret = mem_ap_write_u32(armv8->debug_ap,\n\t\t\t       armv8->debug_base + CPUV8_DBG_DTRRX, data);\n\tif (ret == ERROR_OK)\n\t\tret = mem_ap_write_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DTRTX, data >> 32);\n\treturn ret;\n}\n\nstatic int dpmv8_read_dcc(struct armv8_common *armv8, uint32_t *data,\n\tuint32_t *dscr_p)\n{\n\tuint32_t dscr = DSCR_ITE;\n\tint retval;\n\n\tif (dscr_p)\n\t\tdscr = *dscr_p;\n\n\t/* Wait for DTRRXfull */\n\tlong long then = timeval_ms();\n\twhile ((dscr & DSCR_DTR_TX_FULL) == 0) {\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR,\n\t\t\t\t&dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"Timeout waiting for read dcc\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\t    armv8->debug_base + CPUV8_DBG_DTRTX,\n\t\t\t\t\t    data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dscr_p)\n\t\t*dscr_p = dscr;\n\n\treturn retval;\n}\n\nstatic int dpmv8_read_dcc_64(struct armv8_common *armv8, uint64_t *data,\n\tuint32_t *dscr_p)\n{\n\tuint32_t dscr = DSCR_ITE;\n\tuint32_t higher;\n\tint retval;\n\n\tif (dscr_p)\n\t\tdscr = *dscr_p;\n\n\t/* Wait for DTRRXfull */\n\tlong long then = timeval_ms();\n\twhile ((dscr & DSCR_DTR_TX_FULL) == 0) {\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR,\n\t\t\t\t&dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"Timeout waiting for DTR_TX_FULL, dscr = 0x%08\" PRIx32, dscr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\t    armv8->debug_base + CPUV8_DBG_DTRTX,\n\t\t\t\t\t    (uint32_t *)data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\t\t    armv8->debug_base + CPUV8_DBG_DTRRX,\n\t\t\t\t\t    &higher);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = *(uint32_t *)data | (uint64_t)higher << 32;\n\n\tif (dscr_p)\n\t\t*dscr_p = dscr;\n\n\treturn retval;\n}\n\nstatic int dpmv8_dpm_prepare(struct arm_dpm *dpm)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tuint32_t dscr;\n\tint retval;\n\n\t/* set up invariant:  ITE is set after ever DPM operation */\n\tlong long then = timeval_ms();\n\tfor (;; ) {\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR,\n\t\t\t\t&dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif ((dscr & DSCR_ITE) != 0)\n\t\t\tbreak;\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"Timeout waiting for dpm prepare\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* update the stored copy of dscr */\n\tdpm->dscr = dscr;\n\n\t/* this \"should never happen\" ... */\n\tif (dscr & DSCR_DTR_RX_FULL) {\n\t\tLOG_ERROR(\"DSCR_DTR_RX_FULL, dscr 0x%08\" PRIx32, dscr);\n\t\t/* Clear DCCRX */\n\t\tretval = mem_ap_read_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_DTRRX, &dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int dpmv8_dpm_finish(struct arm_dpm *dpm)\n{\n\t/* REVISIT what could be done here? */\n\treturn ERROR_OK;\n}\n\nstatic int dpmv8_exec_opcode(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *p_dscr)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tuint32_t dscr = dpm->dscr;\n\tint retval;\n\n\tif (p_dscr)\n\t\tdscr = *p_dscr;\n\n\t/* Wait for InstrCompl bit to be set */\n\tlong long then = timeval_ms();\n\twhile ((dscr & DSCR_ITE) == 0) {\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DSCR register, opcode = 0x%08\" PRIx32, opcode);\n\t\t\treturn retval;\n\t\t}\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"Timeout waiting for aarch64_exec_opcode\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64)\n\t\topcode = T32_FMTITR(opcode);\n\n\tretval = mem_ap_write_u32(armv8->debug_ap,\n\t\t\tarmv8->debug_base + CPUV8_DBG_ITR, opcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tthen = timeval_ms();\n\tdo {\n\t\tretval = mem_ap_read_atomic_u32(armv8->debug_ap,\n\t\t\t\tarmv8->debug_base + CPUV8_DBG_DSCR, &dscr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DSCR register\");\n\t\t\treturn retval;\n\t\t}\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"Timeout waiting for aarch64_exec_opcode\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} while ((dscr & DSCR_ITE) == 0);\t/* Wait for InstrCompl bit to be set */\n\n\t/* update dscr and el after each command execution */\n\tdpm->dscr = dscr;\n\tif (dpm->last_el != ((dscr >> 8) & 3))\n\t\tLOG_DEBUG(\"EL %i -> %\" PRIu32, dpm->last_el, (dscr >> 8) & 3);\n\tdpm->last_el = (dscr >> 8) & 3;\n\n\tif (dscr & DSCR_ERR) {\n\t\tLOG_ERROR(\"Opcode 0x%08\" PRIx32 \", DSCR.ERR=1, DSCR.EL=%i\", opcode, dpm->last_el);\n\t\tarmv8_dpm_handle_exception(dpm, true);\n\t\tretval = ERROR_FAIL;\n\t}\n\n\tif (p_dscr)\n\t\t*p_dscr = dscr;\n\n\treturn retval;\n}\n\nstatic int dpmv8_instr_execute(struct arm_dpm *dpm, uint32_t opcode)\n{\n\treturn dpmv8_exec_opcode(dpm, opcode, NULL);\n}\n\nstatic int dpmv8_instr_write_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\tretval = dpmv8_write_dcc(armv8, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_exec_opcode(dpm, opcode, NULL);\n}\n\nstatic int dpmv8_instr_write_data_dcc_64(struct arm_dpm *dpm,\n\tuint32_t opcode, uint64_t data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\tretval = dpmv8_write_dcc_64(armv8, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_exec_opcode(dpm, opcode, NULL);\n}\n\nstatic int dpmv8_instr_write_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tuint32_t dscr = DSCR_ITE;\n\tint retval;\n\n\tretval = dpmv8_write_dcc(armv8, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, READ_REG_DTRRX), &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* then the opcode, taking data from R0 */\n\treturn dpmv8_exec_opcode(dpm, opcode, &dscr);\n}\n\nstatic int dpmv8_instr_write_data_r0_64(struct arm_dpm *dpm,\n\tuint32_t opcode, uint64_t data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\tif (dpm->arm->core_state != ARM_STATE_AARCH64)\n\t\treturn dpmv8_instr_write_data_r0(dpm, opcode, data);\n\n\t/* transfer data from DCC to R0 */\n\tretval = dpmv8_write_dcc_64(armv8, data);\n\tif (retval == ERROR_OK)\n\t\tretval = dpmv8_exec_opcode(dpm, ARMV8_MRS(SYSTEM_DBG_DBGDTR_EL0, 0), &dpm->dscr);\n\n\t/* then the opcode, taking data from R0 */\n\tif (retval == ERROR_OK)\n\t\tretval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);\n\n\treturn retval;\n}\n\nstatic int dpmv8_instr_cpsr_sync(struct arm_dpm *dpm)\n{\n\tint retval;\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\n\t/* \"Prefetch flush\" after modifying execution status in CPSR */\n\tretval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, ARMV8_OPC_DSB_SY), &dpm->dscr);\n\tif (retval == ERROR_OK)\n\t\tdpmv8_exec_opcode(dpm, armv8_opcode(armv8, ARMV8_OPC_ISB_SY), &dpm->dscr);\n\treturn retval;\n}\n\nstatic int dpmv8_instr_read_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\t/* the opcode, writing data to DCC */\n\tretval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_read_dcc(armv8, data, &dpm->dscr);\n}\n\nstatic int dpmv8_instr_read_data_dcc_64(struct arm_dpm *dpm,\n\tuint32_t opcode, uint64_t *data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\t/* the opcode, writing data to DCC */\n\tretval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_read_dcc_64(armv8, data, &dpm->dscr);\n}\n\nstatic int dpmv8_instr_read_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\t/* the opcode, writing data to R0 */\n\tretval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write R0 to DCC */\n\tretval = dpmv8_exec_opcode(dpm, armv8_opcode(armv8, WRITE_REG_DTRTX), &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_read_dcc(armv8, data, &dpm->dscr);\n}\n\nstatic int dpmv8_instr_read_data_r0_64(struct arm_dpm *dpm,\n\tuint32_t opcode, uint64_t *data)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval;\n\n\tif (dpm->arm->core_state != ARM_STATE_AARCH64) {\n\t\tuint32_t tmp;\n\t\tretval = dpmv8_instr_read_data_r0(dpm, opcode, &tmp);\n\t\tif (retval == ERROR_OK)\n\t\t\t*data = tmp;\n\t\treturn retval;\n\t}\n\n\t/* the opcode, writing data to R0 */\n\tretval = dpmv8_exec_opcode(dpm, opcode, &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write R0 to DCC */\n\tretval = dpmv8_exec_opcode(dpm, ARMV8_MSR_GP(SYSTEM_DBG_DBGDTR_EL0, 0), &dpm->dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn dpmv8_read_dcc_64(armv8, data, &dpm->dscr);\n}\n\n#if 0\nstatic int dpmv8_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,\n\ttarget_addr_t addr, uint32_t control)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tuint32_t vr = armv8->debug_base;\n\tuint32_t cr = armv8->debug_base;\n\tint retval;\n\n\tswitch (index_t) {\n\t\tcase 0 ... 15:\t/* breakpoints */\n\t\t\tvr += CPUV8_DBG_BVR_BASE;\n\t\t\tcr += CPUV8_DBG_BCR_BASE;\n\t\t\tbreak;\n\t\tcase 16 ... 31:\t/* watchpoints */\n\t\t\tvr += CPUV8_DBG_WVR_BASE;\n\t\t\tcr += CPUV8_DBG_WCR_BASE;\n\t\t\tindex_t -= 16;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\tvr += 16 * index_t;\n\tcr += 16 * index_t;\n\n\tLOG_DEBUG(\"A8: bpwp enable, vr %08x cr %08x\",\n\t\t(unsigned) vr, (unsigned) cr);\n\n\tretval = mem_ap_write_atomic_u32(armv8->debug_ap, vr, addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn mem_ap_write_atomic_u32(armv8->debug_ap, cr, control);\n}\n#endif\n\nstatic int dpmv8_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tuint32_t cr;\n\n\tswitch (index_t) {\n\t\tcase 0 ... 15:\n\t\t\tcr = armv8->debug_base + CPUV8_DBG_BCR_BASE;\n\t\t\tbreak;\n\t\tcase 16 ... 31:\n\t\t\tcr = armv8->debug_base + CPUV8_DBG_WCR_BASE;\n\t\t\tindex_t -= 16;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\tcr += 16 * index_t;\n\n\tLOG_DEBUG(\"A: bpwp disable, cr %08x\", (unsigned) cr);\n\n\t/* clear control register */\n\treturn mem_ap_write_atomic_u32(armv8->debug_ap, cr, 0);\n}\n\n/*\n * Coprocessor support\n */\n\n/* Read coprocessor */\nstatic int dpmv8_mrc(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,\n\tuint32_t *value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"MRC p%d, %d, r0, c%d, c%d, %d\", cpnum,\n\t\t(int) op1, (int) crn,\n\t\t(int) crm, (int) op2);\n\n\t/* read coprocessor register into R0; return via DCC */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int dpmv8_mcr(struct target *target, int cpnum,\n\tuint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,\n\tuint32_t value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"MCR p%d, %d, r0, c%d, c%d, %d\", cpnum,\n\t\t(int) op1, (int) crn,\n\t\t(int) crm, (int) op2);\n\n\t/* read DCC into r0; then write coprocessor register from R0 */\n\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\tARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),\n\t\t\tvalue);\n\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Register access utilities\n */\n\nint armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)\n{\n\tstruct armv8_common *armv8 = (struct armv8_common *)dpm->arm->arch_info;\n\tint retval = ERROR_OK;\n\tunsigned int target_el;\n\tenum arm_state core_state;\n\tuint32_t cpsr;\n\n\t/* restore previous mode */\n\tif (mode == ARM_MODE_ANY) {\n\t\tcpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);\n\n\t\tLOG_DEBUG(\"restoring mode, cpsr = 0x%08\"PRIx32, cpsr);\n\n\t} else {\n\t\tLOG_DEBUG(\"setting mode 0x%x\", mode);\n\t\tcpsr = mode;\n\t}\n\n\tswitch (cpsr & 0x1f) {\n\t/* aarch32 modes */\n\tcase ARM_MODE_USR:\n\t\ttarget_el = 0;\n\t\tbreak;\n\tcase ARM_MODE_SVC:\n\tcase ARM_MODE_ABT:\n\tcase ARM_MODE_IRQ:\n\tcase ARM_MODE_FIQ:\n\tcase ARM_MODE_SYS:\n\t\ttarget_el = 1;\n\t\tbreak;\n\t/*\n\t * TODO: handle ARM_MODE_HYP\n\t * case ARM_MODE_HYP:\n\t *      target_el = 2;\n\t *      break;\n\t */\n\tcase ARM_MODE_MON:\n\t\ttarget_el = 3;\n\t\tbreak;\n\t/* aarch64 modes */\n\tdefault:\n\t\ttarget_el = (cpsr >> 2) & 3;\n\t}\n\n\tif (target_el > SYSTEM_CUREL_EL3) {\n\t\tLOG_ERROR(\"%s: Invalid target exception level %i\", __func__, target_el);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"target_el = %i, last_el = %i\", target_el, dpm->last_el);\n\tif (dpm->last_el == target_el)\n\t\treturn ERROR_OK; /* nothing to do */\n\n\tif (target_el > dpm->last_el) {\n\t\tretval = dpm->instr_execute(dpm,\n\t\t\t\tarmv8_opcode(armv8, ARMV8_OPC_DCPS) | target_el);\n\n\t\t/* DCPS clobbers registers just like an exception taken */\n\t\tarmv8_dpm_handle_exception(dpm, false);\n\t} else {\n\t\tcore_state = armv8_dpm_get_core_state(dpm);\n\t\tif (core_state != ARM_STATE_AARCH64) {\n\t\t\t/* cannot do DRPS/ERET when already in EL0 */\n\t\t\tif (dpm->last_el != 0) {\n\t\t\t\t/* load SPSR with the desired mode and execute DRPS */\n\t\t\t\tLOG_DEBUG(\"SPSR = 0x%08\"PRIx32, cpsr);\n\t\t\t\tretval = dpm->instr_write_data_r0(dpm,\n\t\t\t\t\t\tARMV8_MSR_GP_XPSR_T1(1, 0, 15), cpsr);\n\t\t\t\tif (retval == ERROR_OK)\n\t\t\t\t\tretval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t * need to execute multiple DRPS instructions until target_el\n\t\t\t * is reached\n\t\t\t */\n\t\t\twhile (retval == ERROR_OK && dpm->last_el != target_el) {\n\t\t\t\tunsigned int cur_el = dpm->last_el;\n\t\t\t\tretval = dpm->instr_execute(dpm, armv8_opcode(armv8, ARMV8_OPC_DRPS));\n\t\t\t\tif (cur_el == dpm->last_el) {\n\t\t\t\t\tLOG_INFO(\"Cannot reach EL %i, SPSR corrupted?\", target_el);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* On executing DRPS, DSPSR and DLR become UNKNOWN, mark them as dirty */\n\t\tdpm->arm->cpsr->dirty = true;\n\t\tdpm->arm->pc->dirty = true;\n\n\t\t/*\n\t\t * re-evaluate the core state, we might be in Aarch32 state now\n\t\t * we rely on dpm->dscr being up-to-date\n\t\t */\n\t\tcore_state = armv8_dpm_get_core_state(dpm);\n\t\tarmv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);\n\t\tarmv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);\n\t}\n\n\treturn retval;\n}\n\n/*\n * Common register read, relies on armv8_select_reg_access() having been called.\n */\nstatic int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval = ERROR_FAIL;\n\n\tif (r->size <= 64) {\n\t\tuint64_t value_64;\n\t\tretval = armv8->read_reg_u64(armv8, regnum, &value_64);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tr->valid = true;\n\t\t\tr->dirty = false;\n\t\t\tbuf_set_u64(r->value, 0, r->size, value_64);\n\t\t\tif (r->size == 64)\n\t\t\t\tLOG_DEBUG(\"READ: %s, %16.8llx\", r->name, (unsigned long long) value_64);\n\t\t\telse\n\t\t\t\tLOG_DEBUG(\"READ: %s, %8.8x\", r->name, (unsigned int) value_64);\n\t\t}\n\t} else if (r->size <= 128) {\n\t\tuint64_t lvalue = 0, hvalue = 0;\n\t\tretval = armv8->read_reg_u128(armv8, regnum, &lvalue, &hvalue);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tr->valid = true;\n\t\t\tr->dirty = false;\n\n\t\t\tbuf_set_u64(r->value, 0, 64, lvalue);\n\t\t\tbuf_set_u64(r->value + 8, 0, r->size - 64, hvalue);\n\n\t\t\tLOG_DEBUG(\"READ: %s, lvalue=%16.8llx\", r->name, (unsigned long long) lvalue);\n\t\t\tLOG_DEBUG(\"READ: %s, hvalue=%16.8llx\", r->name, (unsigned long long) hvalue);\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to read %s register\", r->name);\n\n\treturn retval;\n}\n\n/*\n * Common register write, relies on armv8_select_reg_access() having been called.\n */\nstatic int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tint retval = ERROR_FAIL;\n\n\tif (r->size <= 64) {\n\t\tuint64_t value_64;\n\n\t\tvalue_64 = buf_get_u64(r->value, 0, r->size);\n\t\tretval = armv8->write_reg_u64(armv8, regnum, value_64);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tr->dirty = false;\n\t\t\tif (r->size == 64)\n\t\t\t\tLOG_DEBUG(\"WRITE: %s, %16.8llx\", r->name, (unsigned long long)value_64);\n\t\t\telse\n\t\t\t\tLOG_DEBUG(\"WRITE: %s, %8.8x\", r->name, (unsigned int)value_64);\n\t\t}\n\t} else if (r->size <= 128) {\n\t\tuint64_t lvalue, hvalue;\n\n\t\tlvalue = buf_get_u64(r->value, 0, 64);\n\t\thvalue = buf_get_u64(r->value + 8, 0, r->size - 64);\n\t\tretval = armv8->write_reg_u128(armv8, regnum, lvalue, hvalue);\n\n\t\tif (retval == ERROR_OK) {\n\t\t\tr->dirty = false;\n\n\t\t\tLOG_DEBUG(\"WRITE: %s, lvalue=%16.8llx\", r->name, (unsigned long long) lvalue);\n\t\t\tLOG_DEBUG(\"WRITE: %s, hvalue=%16.8llx\", r->name, (unsigned long long) hvalue);\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to write %s register\", r->name);\n\n\treturn retval;\n}\n\n/**\n * Read basic registers of the current context:  R0 to R15, and CPSR;\n * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).\n * In normal operation this is called on entry to halting debug state,\n * possibly after some other operations supporting restore of debug state\n * or making sure the CPU is fully idle (drain write buffer, etc).\n */\nint armv8_dpm_read_current_registers(struct arm_dpm *dpm)\n{\n\tstruct arm *arm = dpm->arm;\n\tstruct armv8_common *armv8 = (struct armv8_common *)arm->arch_info;\n\tstruct reg_cache *cache;\n\tstruct reg *r;\n\tuint32_t cpsr;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcache = arm->core_cache;\n\n\t/* read R0 first (it's used for scratch), then CPSR */\n\tr = cache->reg_list + ARMV8_R0;\n\tif (!r->valid) {\n\t\tretval = dpmv8_read_reg(dpm, r, ARMV8_R0);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\t}\n\tr->dirty = true;\n\n\t/* read R1, too, it will be clobbered during memory access */\n\tr = cache->reg_list + ARMV8_R1;\n\tif (!r->valid) {\n\t\tretval = dpmv8_read_reg(dpm, r, ARMV8_R1);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\t}\n\n\t/* read cpsr to r0 and get it back */\n\tretval = dpm->instr_read_data_r0(dpm,\n\t\t\tarmv8_opcode(armv8, READ_REG_DSPSR), &cpsr);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\n\t/* update core mode and state */\n\tarmv8_set_cpsr(arm, cpsr);\n\n\tfor (unsigned int i = ARMV8_PC; i < cache->num_regs ; i++) {\n\t\tstruct arm_reg *arm_reg;\n\n\t\tr = armv8_reg_current(arm, i);\n\t\tif (!r->exist || r->valid)\n\t\t\tcontinue;\n\n\t\t/* Skip reading FP-SIMD registers */\n\t\tif (r->number >= ARMV8_V0 && r->number <= ARMV8_FPCR)\n\t\t\tcontinue;\n\n\t\t/*\n\t\t * Only read registers that are available from the\n\t\t * current EL (or core mode).\n\t\t */\n\t\tarm_reg = r->arch_info;\n\t\tif (arm_reg->mode != ARM_MODE_ANY &&\n\t\t\t\tdpm->last_el != armv8_curel_from_core_mode(arm_reg->mode))\n\t\t\tcontinue;\n\n\t\t/* Special case: ARM_MODE_SYS has no SPSR at EL1 */\n\t\tif (r->number == ARMV8_SPSR_EL1 && arm->core_mode == ARM_MODE_SYS)\n\t\t\tcontinue;\n\n\t\tretval = dpmv8_read_reg(dpm, r, i);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\n\t}\n\nfail:\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\n/* Avoid needless I/O ... leave breakpoints and watchpoints alone\n * unless they're removed, or need updating because of single-stepping\n * or running debugger code.\n */\nstatic int dpmv8_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,\n\tstruct dpm_bpwp *xp, bool *set_p)\n{\n\tint retval = ERROR_OK;\n\tbool disable;\n\n\tif (!set_p) {\n\t\tif (!xp->dirty)\n\t\t\tgoto done;\n\t\txp->dirty = false;\n\t\t/* removed or startup; we must disable it */\n\t\tdisable = true;\n\t} else if (bpwp) {\n\t\tif (!xp->dirty)\n\t\t\tgoto done;\n\t\t/* disabled, but we must set it */\n\t\txp->dirty = disable = false;\n\t\t*set_p = true;\n\t} else {\n\t\tif (!*set_p)\n\t\t\tgoto done;\n\t\t/* set, but we must temporarily disable it */\n\t\txp->dirty = disable = true;\n\t\t*set_p = false;\n\t}\n\n\tif (disable)\n\t\tretval = dpm->bpwp_disable(dpm, xp->number);\n\telse\n\t\tretval = dpm->bpwp_enable(dpm, xp->number,\n\t\t\t\txp->address, xp->control);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"%s: can't %s HW %spoint %d\",\n\t\t\tdisable ? \"disable\" : \"enable\",\n\t\t\ttarget_name(dpm->arm->target),\n\t\t\t(xp->number < 16) ? \"break\" : \"watch\",\n\t\t\txp->number & 0xf);\ndone:\n\treturn retval;\n}\n\nstatic int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp);\n\n/**\n * Writes all modified core registers for all processor modes.  In normal\n * operation this is called on exit from halting debug state.\n *\n * @param dpm: represents the processor\n * @param bpwp: true ensures breakpoints and watchpoints are set,\n *\tfalse ensures they are cleared\n */\nint armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)\n{\n\tstruct arm *arm = dpm->arm;\n\tstruct reg_cache *cache = arm->core_cache;\n\tint retval;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* If we're managing hardware breakpoints for this core, enable\n\t * or disable them as requested.\n\t *\n\t * REVISIT We don't yet manage them for ANY cores.  Eventually\n\t * we should be able to assume we handle them; but until then,\n\t * cope with the hand-crafted breakpoint code.\n\t */\n\tif (arm->target->type->add_breakpoint == dpmv8_add_breakpoint) {\n\t\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\t\tstruct dpm_bp *dbp = dpm->dbp + i;\n\t\t\tstruct breakpoint *bp = dbp->bp;\n\n\t\t\tretval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,\n\t\t\t\t\tbp ? &bp->is_set : NULL);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t}\n\t}\n\n\t/* enable/disable watchpoints */\n\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\tstruct dpm_wp *dwp = dpm->dwp + i;\n\t\tstruct watchpoint *wp = dwp->wp;\n\n\t\tretval = dpmv8_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,\n\t\t\t\twp ? &wp->is_set : NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto done;\n\t}\n\n\t/* NOTE:  writes to breakpoint and watchpoint registers might\n\t * be queued, and need (efficient/batched) flushing later.\n\t */\n\n\t/* Restore original core mode and state */\n\tretval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\t/* check everything except our scratch register R0 */\n\tfor (unsigned i = 1; i < cache->num_regs; i++) {\n\t\tstruct arm_reg *r;\n\n\t\t/* skip non-existent */\n\t\tif (!cache->reg_list[i].exist)\n\t\t\tcontinue;\n\t\t/* skip PC and CPSR */\n\t\tif (i == ARMV8_PC || i == ARMV8_XPSR)\n\t\t\tcontinue;\n\t\t/* skip invalid */\n\t\tif (!cache->reg_list[i].valid)\n\t\t\tcontinue;\n\t\t/* skip non-dirty */\n\t\tif (!cache->reg_list[i].dirty)\n\t\t\tcontinue;\n\n\t\t/* skip all registers not on the current EL */\n\t\tr = cache->reg_list[i].arch_info;\n\t\tif (r->mode != ARM_MODE_ANY &&\n\t\t\t\tdpm->last_el != armv8_curel_from_core_mode(r->mode))\n\t\t\tcontinue;\n\n\t\tretval = dpmv8_write_reg(dpm, &cache->reg_list[i], i);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\t/* flush CPSR and PC */\n\tif (retval == ERROR_OK)\n\t\tretval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_XPSR], ARMV8_XPSR);\n\tif (retval == ERROR_OK)\n\t\tretval = dpmv8_write_reg(dpm, &cache->reg_list[ARMV8_PC], ARMV8_PC);\n\t/* flush R0 -- it's *very* dirty by now */\n\tif (retval == ERROR_OK)\n\t\tretval = dpmv8_write_reg(dpm, &cache->reg_list[0], 0);\n\tif (retval == ERROR_OK)\n\t\tdpm->instr_cpsr_sync(dpm);\ndone:\n\tdpm->finish(dpm);\n\treturn retval;\n}\n\n/*\n * Standard ARM register accessors ... there are three methods\n * in \"struct arm\", to support individual read/write and bulk read\n * of registers.\n */\n\nstatic int armv8_dpm_read_core_reg(struct target *target, struct reg *r,\n\tint regnum, enum arm_mode mode)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = target_to_arm(target)->dpm;\n\tint retval;\n\tint max = arm->core_cache->num_regs;\n\n\tif (regnum < 0 || regnum >= max)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/*\n\t * REVISIT what happens if we try to read SPSR in a core mode\n\t * which has no such register?\n\t */\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpmv8_read_reg(dpm, r, regnum);\n\tif (retval != ERROR_OK)\n\t\tgoto fail;\n\nfail:\n\t/* (void) */ dpm->finish(dpm);\n\treturn retval;\n}\n\nstatic int armv8_dpm_write_core_reg(struct target *target, struct reg *r,\n\tint regnum, enum arm_mode mode, uint8_t *value)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = target_to_arm(target)->dpm;\n\tint retval;\n\tint max = arm->core_cache->num_regs;\n\n\tif (regnum < 0 || regnum > max)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* REVISIT what happens if we try to write SPSR in a core mode\n\t * which has no such register?\n\t */\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dpmv8_write_reg(dpm, r, regnum);\n\n\t/* always clean up, regardless of error */\n\tdpm->finish(dpm);\n\n\treturn retval;\n}\n\nstatic int armv8_dpm_full_context(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tstruct reg_cache *cache = arm->core_cache;\n\tint retval;\n\tbool did_read;\n\n\tretval = dpm->prepare(dpm);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tdo {\n\t\tenum arm_mode mode = ARM_MODE_ANY;\n\n\t\tdid_read = false;\n\n\t\t/* We \"know\" arm_dpm_read_current_registers() was called so\n\t\t * the unmapped registers (R0..R7, PC, AND CPSR) and some\n\t\t * view of R8..R14 are current.  We also \"know\" oddities of\n\t\t * register mapping: special cases for R8..R12 and SPSR.\n\t\t *\n\t\t * Pick some mode with unread registers and read them all.\n\t\t * Repeat until done.\n\t\t */\n\t\tfor (unsigned i = 0; i < cache->num_regs; i++) {\n\t\t\tstruct arm_reg *r;\n\n\t\t\tif (!cache->reg_list[i].exist || cache->reg_list[i].valid)\n\t\t\t\tcontinue;\n\t\t\tr = cache->reg_list[i].arch_info;\n\n\t\t\t/* may need to pick a mode and set CPSR */\n\t\t\tif (!did_read) {\n\t\t\t\tdid_read = true;\n\t\t\t\tmode = r->mode;\n\n\t\t\t\t/* For regular (ARM_MODE_ANY) R8..R12\n\t\t\t\t * in case we've entered debug state\n\t\t\t\t * in FIQ mode we need to patch mode.\n\t\t\t\t */\n\t\t\t\tif (mode != ARM_MODE_ANY)\n\t\t\t\t\tretval = armv8_dpm_modeswitch(dpm, mode);\n\t\t\t\telse\n\t\t\t\t\tretval = armv8_dpm_modeswitch(dpm, ARM_MODE_USR);\n\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tif (r->mode != mode)\n\t\t\t\tcontinue;\n\n\t\t\t/* CPSR was read, so \"R16\" must mean SPSR */\n\t\t\tretval = dpmv8_read_reg(dpm,\n\t\t\t\t\t&cache->reg_list[i],\n\t\t\t\t\t(r->num == 16) ? 17 : r->num);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto done;\n\t\t}\n\n\t} while (did_read);\n\n\tretval = armv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n\t/* (void) */ dpm->finish(dpm);\ndone:\n\treturn retval;\n}\n\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Breakpoint and Watchpoint support.\n *\n * Hardware {break,watch}points are usually left active, to minimize\n * debug entry/exit costs.  When they are set or cleared, it's done in\n * batches.  Also, DPM-conformant hardware can update debug registers\n * regardless of whether the CPU is running or halted ... though that\n * fact isn't currently leveraged.\n */\n\nstatic int dpmv8_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,\n\tuint32_t addr, uint32_t length)\n{\n\tuint32_t control;\n\n\tcontrol = (1 << 0)\t/* enable */\n\t\t| (3 << 1);\t/* both user and privileged access */\n\n\t/* Match 1, 2, or all 4 byte addresses in this word.\n\t *\n\t * FIXME:  v7 hardware allows lengths up to 2 GB for BP and WP.\n\t * Support larger length, when addr is suitably aligned.  In\n\t * particular, allow watchpoints on 8 byte \"double\" values.\n\t *\n\t * REVISIT allow watchpoints on unaligned 2-bit values; and on\n\t * v7 hardware, unaligned 4-byte ones too.\n\t */\n\tswitch (length) {\n\t\tcase 1:\n\t\t\tcontrol |= (1 << (addr & 3)) << 5;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t/* require 2-byte alignment */\n\t\t\tif (!(addr & 1)) {\n\t\t\t\tcontrol |= (3 << (addr & 2)) << 5;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t/* FALL THROUGH */\n\t\tcase 4:\n\t\t\t/* require 4-byte alignment */\n\t\t\tif (!(addr & 3)) {\n\t\t\t\tcontrol |= 0xf << 5;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t/* FALL THROUGH */\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unsupported {break,watch}point length/alignment\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* other shared control bits:\n\t * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)\n\t * bit 20 == 0 ... not linked to a context ID\n\t * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)\n\t */\n\n\txp->address = addr & ~3;\n\txp->control = control;\n\txp->dirty = true;\n\n\tLOG_DEBUG(\"BPWP: addr %8.8\" PRIx32 \", control %\" PRIx32 \", number %d\",\n\t\txp->address, control, xp->number);\n\n\t/* hardware is updated in write_dirty_registers() */\n\treturn ERROR_OK;\n}\n\nstatic int dpmv8_add_breakpoint(struct target *target, struct breakpoint *bp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (bp->length < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (!dpm->bpwp_enable)\n\t\treturn retval;\n\n\t/* FIXME we need a generic solution for software breakpoints. */\n\tif (bp->type == BKPT_SOFT)\n\t\tLOG_DEBUG(\"using HW bkpt, not SW...\");\n\n\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\tif (!dpm->dbp[i].bp) {\n\t\t\tretval = dpmv8_bpwp_setup(dpm, &dpm->dbp[i].bpwp,\n\t\t\t\t\tbp->address, bp->length);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tdpm->dbp[i].bp = bp;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpmv8_remove_breakpoint(struct target *target, struct breakpoint *bp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned i = 0; i < dpm->nbp; i++) {\n\t\tif (dpm->dbp[i].bp == bp) {\n\t\t\tdpm->dbp[i].bp = NULL;\n\t\t\tdpm->dbp[i].bpwp.dirty = true;\n\n\t\t\t/* hardware is updated in write_dirty_registers() */\n\t\t\tretval = ERROR_OK;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpmv8_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,\n\tstruct watchpoint *wp)\n{\n\tint retval;\n\tstruct dpm_wp *dwp = dpm->dwp + index_t;\n\tuint32_t control;\n\n\t/* this hardware doesn't support data value matching or masking */\n\tif (wp->value || wp->mask != ~(uint32_t)0) {\n\t\tLOG_DEBUG(\"watchpoint values and masking not supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tretval = dpmv8_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcontrol = dwp->bpwp.control;\n\tswitch (wp->rw) {\n\t\tcase WPT_READ:\n\t\t\tcontrol |= 1 << 3;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tcontrol |= 2 << 3;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tcontrol |= 3 << 3;\n\t\t\tbreak;\n\t}\n\tdwp->bpwp.control = control;\n\n\tdpm->dwp[index_t].wp = wp;\n\n\treturn retval;\n}\n\nstatic int dpmv8_add_watchpoint(struct target *target, struct watchpoint *wp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (dpm->bpwp_enable) {\n\t\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\t\tif (!dpm->dwp[i].wp) {\n\t\t\t\tretval = dpmv8_watchpoint_setup(dpm, i, wp);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic int dpmv8_remove_watchpoint(struct target *target, struct watchpoint *wp)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm_dpm *dpm = arm->dpm;\n\tint retval = ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned i = 0; i < dpm->nwp; i++) {\n\t\tif (dpm->dwp[i].wp == wp) {\n\t\t\tdpm->dwp[i].wp = NULL;\n\t\t\tdpm->dwp[i].bpwp.dirty = true;\n\n\t\t\t/* hardware is updated in write_dirty_registers() */\n\t\t\tretval = ERROR_OK;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\n/*\n * Handle exceptions taken in debug state. This happens mostly for memory\n * accesses that violated a MMU policy. Taking an exception while in debug\n * state clobbers certain state registers on the target exception level.\n * Just mark those registers dirty so that they get restored on resume.\n * This works both for Aarch32 and Aarch64 states.\n *\n * This function must not perform any actions that trigger another exception\n * or a recursion will happen.\n */\nvoid armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore)\n{\n\tstruct armv8_common *armv8 = dpm->arm->arch_info;\n\tstruct reg_cache *cache = dpm->arm->core_cache;\n\tenum arm_state core_state;\n\tuint64_t dlr;\n\tuint32_t dspsr;\n\tunsigned int el;\n\n\tstatic const int clobbered_regs_by_el[3][5] = {\n\t\t{ ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL1, ARMV8_ESR_EL1, ARMV8_SPSR_EL1 },\n\t\t{ ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL2, ARMV8_ESR_EL2, ARMV8_SPSR_EL2 },\n\t\t{ ARMV8_PC, ARMV8_XPSR, ARMV8_ELR_EL3, ARMV8_ESR_EL3, ARMV8_SPSR_EL3 },\n\t};\n\n\tel = (dpm->dscr >> 8) & 3;\n\n\t/* safety check, must not happen since EL0 cannot be a target for an exception */\n\tif (el < SYSTEM_CUREL_EL1 || el > SYSTEM_CUREL_EL3) {\n\t\tLOG_ERROR(\"%s: EL %i is invalid, DSCR corrupted?\", __func__, el);\n\t\treturn;\n\t}\n\n\t/* Clear sticky error */\n\tmem_ap_write_u32(armv8->debug_ap,\n\t\tarmv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);\n\n\tarmv8->read_reg_u64(armv8, ARMV8_XPSR, &dlr);\n\tdspsr = dlr;\n\tarmv8->read_reg_u64(armv8, ARMV8_PC, &dlr);\n\n\tLOG_DEBUG(\"Exception taken to EL %i, DLR=0x%016\"PRIx64\" DSPSR=0x%08\"PRIx32,\n\t\t\tel, dlr, dspsr);\n\n\t/* mark all clobbered registers as dirty */\n\tfor (int i = 0; i < 5; i++)\n\t\tcache->reg_list[clobbered_regs_by_el[el-1][i]].dirty = true;\n\n\t/*\n\t * re-evaluate the core state, we might be in Aarch64 state now\n\t * we rely on dpm->dscr being up-to-date\n\t */\n\tcore_state = armv8_dpm_get_core_state(dpm);\n\tarmv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64);\n\tarmv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64);\n\n\tif (do_restore)\n\t\tarmv8_dpm_modeswitch(dpm, ARM_MODE_ANY);\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Other debug and support utilities\n */\n\nvoid armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)\n{\n\tstruct target *target = dpm->arm->target;\n\n\tdpm->dscr = dscr;\n\tdpm->last_el = (dscr >> 8) & 3;\n\n\t/* Examine debug reason */\n\tswitch (DSCR_ENTRY(dscr)) {\n\t\t/* FALL THROUGH -- assume a v6 core in abort mode */\n\t\tcase DSCRV8_ENTRY_EXT_DEBUG:\t/* EDBGRQ */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase DSCRV8_ENTRY_HALT_STEP_EXECLU:\t/* HALT step */\n\t\tcase DSCRV8_ENTRY_HALT_STEP_NORMAL: /* Halt step*/\n\t\tcase DSCRV8_ENTRY_HALT_STEP:\n\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t\t\tbreak;\n\t\tcase DSCRV8_ENTRY_HLT:\t/* HLT instruction (software breakpoint) */\n\t\tcase DSCRV8_ENTRY_BKPT:\t/* SW BKPT (?) */\n\t\tcase DSCRV8_ENTRY_RESET_CATCH:\t/* Reset catch */\n\t\tcase DSCRV8_ENTRY_OS_UNLOCK:  /*OS unlock catch*/\n\t\tcase DSCRV8_ENTRY_SW_ACCESS_DBG: /*SW access dbg register*/\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase DSCRV8_ENTRY_WATCHPOINT:\t/* asynch watchpoint */\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase DSCRV8_ENTRY_EXCEPTION_CATCH:  /*exception catch*/\n\t\t\ttarget->debug_reason = DBG_REASON_EXC_CATCH;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\t\t\tbreak;\n\t}\n\n}\n\n/*----------------------------------------------------------------------*/\n\n/*\n * Setup and management support.\n */\n\n/**\n * Hooks up this DPM to its associated target; call only once.\n * Initially this only covers the register cache.\n *\n * Oh, and watchpoints.  Yeah.\n */\nint armv8_dpm_setup(struct arm_dpm *dpm)\n{\n\tstruct arm *arm = dpm->arm;\n\tstruct target *target = arm->target;\n\tstruct reg_cache *cache;\n\tarm->dpm = dpm;\n\n\t/* register access setup */\n\tarm->full_context = armv8_dpm_full_context;\n\tarm->read_core_reg = armv8_dpm_read_core_reg;\n\tarm->write_core_reg = armv8_dpm_write_core_reg;\n\n\tif (!arm->core_cache) {\n\t\tcache = armv8_build_reg_cache(target);\n\t\tif (!cache)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* coprocessor access setup */\n\tarm->mrc = dpmv8_mrc;\n\tarm->mcr = dpmv8_mcr;\n\n\tdpm->prepare = dpmv8_dpm_prepare;\n\tdpm->finish = dpmv8_dpm_finish;\n\n\tdpm->instr_execute = dpmv8_instr_execute;\n\tdpm->instr_write_data_dcc = dpmv8_instr_write_data_dcc;\n\tdpm->instr_write_data_dcc_64 = dpmv8_instr_write_data_dcc_64;\n\tdpm->instr_write_data_r0 = dpmv8_instr_write_data_r0;\n\tdpm->instr_write_data_r0_64 = dpmv8_instr_write_data_r0_64;\n\tdpm->instr_cpsr_sync = dpmv8_instr_cpsr_sync;\n\n\tdpm->instr_read_data_dcc = dpmv8_instr_read_data_dcc;\n\tdpm->instr_read_data_dcc_64 = dpmv8_instr_read_data_dcc_64;\n\tdpm->instr_read_data_r0 = dpmv8_instr_read_data_r0;\n\tdpm->instr_read_data_r0_64 = dpmv8_instr_read_data_r0_64;\n\n\tdpm->arm_reg_current = armv8_reg_current;\n\n/*\tdpm->bpwp_enable = dpmv8_bpwp_enable; */\n\tdpm->bpwp_disable = dpmv8_bpwp_disable;\n\n\t/* breakpoint setup -- optional until it works everywhere */\n\tif (!target->type->add_breakpoint) {\n\t\ttarget->type->add_breakpoint = dpmv8_add_breakpoint;\n\t\ttarget->type->remove_breakpoint = dpmv8_remove_breakpoint;\n\t}\n\n\t/* watchpoint setup */\n\tif (!target->type->add_watchpoint) {\n\t\ttarget->type->add_watchpoint = dpmv8_add_watchpoint;\n\t\ttarget->type->remove_watchpoint = dpmv8_remove_watchpoint;\n\t}\n\n\t/* FIXME add vector catch support */\n\n\tdpm->nbp = 1 + ((dpm->didr >> 12) & 0xf);\n\tdpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));\n\n\tdpm->nwp = 1 + ((dpm->didr >> 20) & 0xf);\n\tdpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));\n\n\tif (!dpm->dbp || !dpm->dwp) {\n\t\tfree(dpm->dbp);\n\t\tfree(dpm->dwp);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"%s: hardware has %d breakpoints, %d watchpoints\",\n\t\ttarget_name(target), dpm->nbp, dpm->nwp);\n\n\t/* REVISIT ... and some of those breakpoints could match\n\t * execution context IDs...\n\t */\n\n\treturn ERROR_OK;\n}\n\n/**\n * Reinitializes DPM state at the beginning of a new debug session\n * or after a reset which may have affected the debug module.\n */\nint armv8_dpm_initialize(struct arm_dpm *dpm)\n{\n\t/* Disable all breakpoints and watchpoints at startup. */\n\tif (dpm->bpwp_disable) {\n\t\tunsigned i;\n\n\t\tfor (i = 0; i < dpm->nbp; i++) {\n\t\t\tdpm->dbp[i].bpwp.number = i;\n\t\t\t(void) dpm->bpwp_disable(dpm, i);\n\t\t}\n\t\tfor (i = 0; i < dpm->nwp; i++) {\n\t\t\tdpm->dwp[i].bpwp.number = 16 + i;\n\t\t\t(void) dpm->bpwp_disable(dpm, 16 + i);\n\t\t}\n\t} else\n\t\tLOG_WARNING(\"%s: can't disable breakpoints and watchpoints\",\n\t\t\ttarget_name(dpm->arm->target));\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_dpm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2009 by David Brownell\n */\n\n#ifndef OPENOCD_TARGET_ARMV8_DPM_H\n#define OPENOCD_TARGET_ARMV8_DPM_H\n\n#include \"arm_dpm.h\"\n#include \"helper/bits.h\"\n\n/* forward-declare struct armv8_common */\nstruct armv8_common;\n\n/**\n * This wraps an implementation of DPM primitives.  Each interface\n * provider supplies a structure like this, which is the glue between\n * upper level code and the lower level hardware access.\n *\n * It is a PRELIMINARY AND INCOMPLETE set of primitives, starting with\n * support for CPU register access.\n */\nint armv8_dpm_setup(struct arm_dpm *dpm);\nint armv8_dpm_initialize(struct arm_dpm *dpm);\n\nint armv8_dpm_read_current_registers(struct arm_dpm *dpm);\nint armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode);\n\n\nint armv8_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp);\n\n/* DSCR bits; see ARMv7a arch spec section C10.3.1.\n * Not all v7 bits are valid in v6.\n */\n#define DSCR_DEBUG_STATUS_MASK\t\t(0x1F <<  0)\n#define DSCR_ERR\t\t\t\t\t(0x1 <<  6)\n#define DSCR_SYS_ERROR_PEND\t\t\t(0x1 <<  7)\n#define DSCR_CUR_EL\t\t\t\t\t(0x3 <<  8)\n#define DSCR_EL_STATUS_MASK\t\t\t(0xF << 10)\n#define DSCR_HDE\t\t\t\t\t(0x1 << 14)\n#define DSCR_SDD\t\t\t\t\t(0x1 << 16)\n#define DSCR_NON_SECURE             (0x1 << 18)\n#define DSCR_MA\t\t\t\t\t\t(0x1 << 20)\n#define DSCR_TDA\t\t\t\t\t(0x1 << 21)\n#define DSCR_INTDIS_MASK\t\t\t(0x3 << 22)\n#define DSCR_ITE\t\t\t\t\t(0x1 << 24)\n#define DSCR_PIPE_ADVANCE           (0x1 << 25)\n#define DSCR_TXU\t\t\t\t\t(0x1 << 26)\n#define DSCR_RTO\t\t\t\t\t(0x1 << 27) /* bit 28 is reserved */\n#define DSCR_ITO\t\t\t\t\t(0x1 << 28)\n#define DSCR_DTR_TX_FULL            (0x1 << 29)\n#define DSCR_DTR_RX_FULL            (0x1 << 30) /* bit 31 is reserved */\n\n\n\n/* Methods of entry into debug mode */\n#define DSCRV8_ENTRY_NON_DEBUG\t\t\t(0x2)\n#define DSCRV8_ENTRY_RESTARTING\t\t\t(0x1)\n#define DSCRV8_ENTRY_BKPT\t\t\t\t(0x7)\n#define DSCRV8_ENTRY_EXT_DEBUG\t\t\t(0x13)\n#define DSCRV8_ENTRY_HALT_STEP_NORMAL\t(0x1B)\n#define DSCRV8_ENTRY_HALT_STEP_EXECLU\t(0x1F)\n#define DSCRV8_ENTRY_OS_UNLOCK\t\t\t(0x23)\n#define DSCRV8_ENTRY_RESET_CATCH\t\t(0x27)\n#define DSCRV8_ENTRY_WATCHPOINT\t\t\t(0x2B)\n#define DSCRV8_ENTRY_HLT\t\t\t\t(0x2F)\n#define DSCRV8_ENTRY_SW_ACCESS_DBG\t\t(0x33)\n#define DSCRV8_ENTRY_EXCEPTION_CATCH\t(0x37)\n#define DSCRV8_ENTRY_HALT_STEP\t\t\t(0x3B)\n#define DSCRV8_HALT_MASK\t\t\t(0x3C)\n\n/*DRCR registers*/\n#define DRCR_CSE\t\t\t\t(1 << 2)\n#define DRCR_CSPA\t\t\t\t(1 << 3)\n#define DRCR_CBRRQ\t\t\t\t(1 << 4)\n\n\n/* DTR modes */\n#define DSCR_EXT_DCC_NON_BLOCKING     (0x0 << 20)\n#define DSCR_EXT_DCC_STALL_MODE       (0x1 << 20)\n#define DSCR_EXT_DCC_FAST_MODE        (0x2 << 20)  /* bits 22, 23 are reserved */\n\n\n/* DRCR (debug run control register) bits */\n#define DRCR_HALT\t\t\t\t(1 << 0)\n#define DRCR_RESTART\t\t\t(1 << 1)\n#define DRCR_CLEAR_EXCEPTIONS\t(1 << 2)\n\n/* ECR (Execution Control Register) bits */\n#define ECR_RCE         BIT(1)\n\n/* ESR (Event Status Register) bits */\n#define ESR_RC          BIT(1)\n\n/* PRSR (processor debug status register) bits */\n#define PRSR_PU\t\t\t\t\t(1 << 0)\n#define PRSR_SPD\t\t\t\t(1 << 1)\n#define PRSR_RESET\t\t\t\t(1 << 2)\n#define PRSR_SR\t\t\t\t\t(1 << 3)\n#define PRSR_HALT\t\t\t\t(1 << 4)\n#define PRSR_OSLK\t\t\t\t(1 << 5)\n#define PRSR_DLK\t\t\t\t(1 << 6)\n#define PRSR_EDAD\t\t\t\t(1 << 7)\n#define PRSR_SDAD\t\t\t\t(1 << 8)\n#define PRSR_EPMAD\t\t\t\t(1 << 9)\n#define PRSR_SPMAD\t\t\t\t(1 << 10)\n#define PRSR_SDR\t\t\t\t(1 << 11)\n\n/* PRCR (processor debug control register) bits */\n#define PRCR_CORENPDRQ\t\t\t(1 << 0)\n#define PRCR_CWRR\t\t\t\t(1 << 2)\n#define PRCR_COREPURQ\t\t\t(1 << 3)\n\nvoid armv8_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dcsr);\nvoid armv8_dpm_handle_exception(struct arm_dpm *dpm, bool do_restore);\nenum arm_state armv8_dpm_get_core_state(struct arm_dpm *dpm);\n\n#endif /* OPENOCD_TARGET_ARM_DPM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_opcodes.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2015 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#include \"armv8.h\"\n#include \"armv8_opcodes.h\"\n\nstatic const uint32_t a64_opcodes[ARMV8_OPC_NUM] = {\n\t\t[READ_REG_CTR]\t\t= ARMV8_MRS(SYSTEM_CTR, 0),\n\t\t[READ_REG_CLIDR]\t= ARMV8_MRS(SYSTEM_CLIDR, 0),\n\t\t[READ_REG_CSSELR]\t= ARMV8_MRS(SYSTEM_CSSELR, 0),\n\t\t[READ_REG_CCSIDR]\t= ARMV8_MRS(SYSTEM_CCSIDR, 0),\n\t\t[WRITE_REG_CSSELR]\t= ARMV8_MSR_GP(SYSTEM_CSSELR, 0),\n\t\t[READ_REG_MPIDR]\t= ARMV8_MRS(SYSTEM_MPIDR, 0),\n\t\t[READ_REG_DTRRX]\t= ARMV8_MRS(SYSTEM_DBG_DTRRX_EL0, 0),\n\t\t[WRITE_REG_DTRTX]\t= ARMV8_MSR_GP(SYSTEM_DBG_DTRTX_EL0, 0),\n\t\t[WRITE_REG_DSPSR]\t= ARMV8_MSR_DSPSR(0),\n\t\t[READ_REG_DSPSR]\t= ARMV8_MRS_DSPSR(0),\n\t\t[ARMV8_OPC_DSB_SY]\t= ARMV8_DSB_SY,\n\t\t[ARMV8_OPC_DCPS]\t= ARMV8_DCPS(0, 11),\n\t\t[ARMV8_OPC_DRPS]\t= ARMV8_DRPS,\n\t\t[ARMV8_OPC_ISB_SY]\t= ARMV8_ISB,\n\t\t[ARMV8_OPC_DCCISW]\t= ARMV8_SYS(SYSTEM_DCCISW, 0),\n\t\t[ARMV8_OPC_DCCIVAC]\t= ARMV8_SYS(SYSTEM_DCCIVAC, 0),\n\t\t[ARMV8_OPC_ICIVAU]\t= ARMV8_SYS(SYSTEM_ICIVAU, 0),\n\t\t[ARMV8_OPC_HLT]\t\t= ARMV8_HLT(11),\n\t\t[ARMV8_OPC_LDRB_IP]\t= ARMV8_LDRB_IP(1, 0),\n\t\t[ARMV8_OPC_LDRH_IP]\t= ARMV8_LDRH_IP(1, 0),\n\t\t[ARMV8_OPC_LDRW_IP]\t= ARMV8_LDRW_IP(1, 0),\n\t\t[ARMV8_OPC_STRB_IP]\t= ARMV8_STRB_IP(1, 0),\n\t\t[ARMV8_OPC_STRH_IP]\t= ARMV8_STRH_IP(1, 0),\n\t\t[ARMV8_OPC_STRW_IP]\t= ARMV8_STRW_IP(1, 0),\n};\n\nstatic const uint32_t t32_opcodes[ARMV8_OPC_NUM] = {\n\t\t[READ_REG_CTR]\t\t= ARMV4_5_MRC(15, 0, 0, 0, 0, 1),\n\t\t[READ_REG_CLIDR]\t= ARMV4_5_MRC(15, 1, 0, 0, 0, 1),\n\t\t[READ_REG_CSSELR]\t= ARMV4_5_MRC(15, 2, 0, 0, 0, 0),\n\t\t[READ_REG_CCSIDR]\t= ARMV4_5_MRC(15, 1, 0, 0, 0, 0),\n\t\t[WRITE_REG_CSSELR]\t= ARMV4_5_MCR(15, 2, 0, 0, 0, 0),\n\t\t[READ_REG_MPIDR]\t= ARMV4_5_MRC(15, 0, 0, 0, 0, 5),\n\t\t[READ_REG_DTRRX]\t= ARMV4_5_MRC(14, 0, 0, 0, 5, 0),\n\t\t[WRITE_REG_DTRTX]\t= ARMV4_5_MCR(14, 0, 0, 0, 5, 0),\n\t\t[WRITE_REG_DSPSR]\t= ARMV8_MCR_DSPSR(0),\n\t\t[READ_REG_DSPSR]\t= ARMV8_MRC_DSPSR(0),\n\t\t[ARMV8_OPC_DSB_SY]\t= ARMV8_DSB_SY_T1,\n\t\t[ARMV8_OPC_DCPS]\t= ARMV8_DCPS_T1(0),\n\t\t[ARMV8_OPC_DRPS]\t= ARMV8_ERET_T1,\n\t\t[ARMV8_OPC_ISB_SY]\t= ARMV8_ISB_SY_T1,\n\t\t[ARMV8_OPC_DCCISW]\t= ARMV4_5_MCR(15, 0, 0, 7, 14, 2),\n\t\t[ARMV8_OPC_DCCIVAC]\t= ARMV4_5_MCR(15, 0, 0, 7, 14, 1),\n\t\t[ARMV8_OPC_ICIVAU]\t= ARMV4_5_MCR(15, 0, 0, 7, 5, 1),\n\t\t[ARMV8_OPC_HLT]\t\t= ARMV8_HLT_T1(11),\n\t\t[ARMV8_OPC_LDRB_IP]\t= ARMV8_LDRB_IP_T3(1, 0),\n\t\t[ARMV8_OPC_LDRH_IP]\t= ARMV8_LDRH_IP_T3(1, 0),\n\t\t[ARMV8_OPC_LDRW_IP]\t= ARMV8_LDRW_IP_T3(1, 0),\n\t\t[ARMV8_OPC_STRB_IP]\t= ARMV8_STRB_IP_T3(1, 0),\n\t\t[ARMV8_OPC_STRH_IP]\t= ARMV8_STRH_IP_T3(1, 0),\n\t\t[ARMV8_OPC_STRW_IP]\t= ARMV8_STRW_IP_T3(1, 0),\n};\n\nvoid armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64)\n{\n\tif (state_is_aarch64)\n\t\tarmv8->opcodes = &a64_opcodes[0];\n\telse\n\t\tarmv8->opcodes = &t32_opcodes[0];\n}\n\nuint32_t armv8_opcode(struct armv8_common *armv8, enum armv8_opcode code)\n{\n\tif ((int)code >= ARMV8_OPC_NUM)\n\t\treturn -1;\n\n\treturn *(armv8->opcodes + code);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/armv8_opcodes.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2015 by pierrr kuo <vichy.kuo@gmail.com>\n */\n\n#ifndef OPENOCD_TARGET_ARMV8_OPCODES_H\n#define OPENOCD_TARGET_ARMV8_OPCODES_H\n\n#include \"arm_opcodes.h\"\n\n#define SYSTEM_CUREL_MASK\t\t0xC0\n#define SYSTEM_CUREL_SHIFT\t\t6\n#define SYSTEM_CUREL_EL0\t\t0x0\n#define SYSTEM_CUREL_EL1\t\t0x1\n#define SYSTEM_CUREL_EL2\t\t0x2\n#define SYSTEM_CUREL_EL3\t\t0x3\n#define SYSTEM_CUREL_NONCH\t\t0xF\n#define SYSTEM_AARCH64\t\t\t0x1\n\n#define SYSTEM_AAR64_MODE_EL0T\t0x0\n#define SYSTEM_AAR64_MODE_EL1T\t0x4\n#define SYSTEM_AAR64_MODE_EL1H\t0x5\n#define SYSTEM_AAR64_MODE_EL2T\t0x8\n#define SYSTEM_AAR64_MODE_EL2H\t0x9\n#define SYSTEM_AAR64_MODE_EL3T\t0xC\n#define SYSTEM_AAR64_MODE_EL3H\t0xd\n\n#define SYSTEM_DAIF\t\t\t0b1101101000010001\n#define SYSTEM_DAIF_MASK\t\t0x3C0\n#define SYSTEM_DAIF_SHIFT\t\t6\n\n#define SYSTEM_ELR_EL1\t\t\t0b1100001000000001\n#define SYSTEM_ELR_EL2\t\t\t0b1110001000000001\n#define SYSTEM_ELR_EL3\t\t\t0b1111001000000001\n\n#define SYSTEM_SCTLR_EL1\t0b1100000010000000\n#define SYSTEM_SCTLR_EL2\t0b1110000010000000\n#define SYSTEM_SCTLR_EL3\t0b1111000010000000\n\n#define SYSTEM_FPCR\t\t\t0b1101101000100000\n#define SYSTEM_FPSR\t\t\t0b1101101000100001\n#define SYSTEM_DAIF\t\t\t0b1101101000010001\n#define SYSTEM_NZCV\t\t\t0b1101101000010000\n#define SYSTEM_SP_EL0\t\t\t0b1100001000001000\n#define SYSTEM_SP_EL1\t\t\t0b1110001000001000\n#define SYSTEM_SP_EL2\t\t\t0b1111001000001000\n#define SYSTEM_SP_SEL\t\t\t0b1100001000010000\n#define SYSTEM_SPSR_ABT\t\t\t0b1110001000011001\n#define SYSTEM_SPSR_FIQ\t\t\t0b1110001000011011\n#define SYSTEM_SPSR_IRQ\t\t\t0b1110001000011000\n#define SYSTEM_SPSR_UND\t\t\t0b1110001000011010\n\n#define SYSTEM_SPSR_EL1\t\t\t0b1100001000000000\n#define SYSTEM_SPSR_EL2\t\t\t0b1110001000000000\n#define SYSTEM_SPSR_EL3\t\t\t0b1111001000000000\n\n#define SYSTEM_ISR_EL1\t\t\t0b1100011000001000\n\n#define SYSTEM_DBG_DSPSR_EL0    0b1101101000101000\n#define SYSTEM_DBG_DLR_EL0\t\t0b1101101000101001\n#define SYSTEM_DBG_DTRRX_EL0\t0b1001100000101000\n#define SYSTEM_DBG_DTRTX_EL0\t0b1001100000101000\n#define SYSTEM_DBG_DBGDTR_EL0\t0b1001100000100000\n\n#define SYSTEM_CCSIDR\t\t\t0b1100100000000000\n#define SYSTEM_CLIDR\t\t\t0b1100100000000001\n#define SYSTEM_CSSELR\t\t\t0b1101000000000000\n#define SYSTEM_CTYPE\t\t\t0b1101100000000001\n#define SYSTEM_CTR\t\t\t\t0b1101100000000001\n\n#define SYSTEM_DCCISW\t\t\t0b0100001111110010\n#define SYSTEM_DCCSW\t\t\t0b0100001111010010\n#define SYSTEM_ICIVAU\t\t\t0b0101101110101001\n#define SYSTEM_DCCVAU\t\t\t0b0101101111011001\n#define SYSTEM_DCCIVAC\t\t\t0b0101101111110001\n\n#define SYSTEM_MPIDR\t\t\t0b1100000000000101\n\n#define SYSTEM_TCR_EL1\t\t\t0b1100000100000010\n#define SYSTEM_TCR_EL2\t\t\t0b1110000100000010\n#define SYSTEM_TCR_EL3\t\t\t0b1111000100000010\n\n#define SYSTEM_TTBR0_EL1\t\t0b1100000100000000\n#define SYSTEM_TTBR0_EL2\t\t0b1110000100000000\n#define SYSTEM_TTBR0_EL3\t\t0b1111000100000000\n#define SYSTEM_TTBR1_EL1\t\t0b1100000100000001\n\n/* ARMv8 address translation */\n#define SYSTEM_PAR_EL1\t\t\t0b1100001110100000\n#define SYSTEM_ATS12E0R\t\t\t0b0110001111000110\n#define SYSTEM_ATS12E1R\t\t\t0b0110001111000100\n#define SYSTEM_ATS1E2R\t\t\t0b0110001111000000\n#define SYSTEM_ATS1E3R\t\t\t0b0111001111000000\n\n/* fault status and fault address */\n#define SYSTEM_FAR_EL1\t\t\t0b1100001100000000\n#define SYSTEM_FAR_EL2\t\t\t0b1110001100000000\n#define SYSTEM_FAR_EL3\t\t\t0b1111001100000000\n#define SYSTEM_ESR_EL1\t\t\t0b1100001010010000\n#define SYSTEM_ESR_EL2\t\t\t0b1110001010010000\n#define SYSTEM_ESR_EL3\t\t\t0b1111001010010000\n\n#define ARMV8_MRS_DSPSR(rt)\t(0xd53b4500 | (rt))\n#define ARMV8_MSR_DSPSR(rt)\t(0xd51b4500 | (rt))\n#define ARMV8_MRS_DLR(rt)\t(0xd53b4520 | (rt))\n#define ARMV8_MSR_DLR(rt)\t(0xd51b4520 | (rt))\n\n/* T32 instruction to access coprocessor registers */\n#define ARMV8_MCR_T1(cp, crn, opc1, crm, opc2, rt) ARMV4_5_MCR(cp, opc1, rt, crn, crm, opc2)\n#define ARMV8_MRC_T1(cp, crn, opc1, crm, opc2, rt) ARMV4_5_MRC(cp, opc1, rt, crn, crm, opc2)\n\n/* T32 instructions to access DSPSR and DLR */\n#define ARMV8_MRC_DSPSR(rt) ARMV8_MRC_T1(15, 4, 3, 5, 0, rt)\n#define ARMV8_MCR_DSPSR(rt) ARMV8_MCR_T1(15, 4, 3, 5, 0, rt)\n#define ARMV8_MRC_DLR(rt)\tARMV8_MRC_T1(15, 4, 3, 5, 1, rt)\n#define ARMV8_MCR_DLR(rt)\tARMV8_MCR_T1(15, 4, 3, 5, 1, rt)\n\n#define ARMV8_DCPS1(im)\t\t(0xd4a00001 | (((im) & 0xFFFF) << 5))\n#define ARMV8_DCPS2(im)\t\t(0xd4a00002 | (((im) & 0xFFFF) << 5))\n#define ARMV8_DCPS3(im)\t\t(0xd4a00003 | (((im) & 0xFFFF) << 5))\n#define ARMV8_DCPS(el, im)\t(0xd4a00000 | (((im) & 0xFFFF) << 5) | el)\n#define ARMV8_DCPS_T1(el)\t(0xf78f8000 | el)\n#define ARMV8_DRPS\t\t0xd6bf03e0\n#define ARMV8_ERET_T1\t\t0xf3de8f00\n\n#define ARMV8_DSB_SY\t\t\t\t0xd5033F9F\n#define ARMV8_DSB_SY_T1\t\t\t\t0xf3bf8f4f\n#define ARMV8_ISB\t\t\t\t0xd5033fdf\n#define ARMV8_ISB_SY_T1\t\t\t\t0xf3bf8f6f\n\n#define ARMV8_MRS(system, rt)\t(0xd5300000 | ((system) << 5) | (rt))\n/* ARM V8 Move to system register. */\n#define ARMV8_MSR_GP(system, rt) \\\n\t(0xd5100000 | ((system) << 5) | (rt))\n/* ARM V8 Move immediate to process state field. */\n#define ARMV8_MSR_IM(op1, crm, op2) \\\n\t(0xd500401f | ((op1) << 16)  | ((crm) << 8) | ((op2) << 5))\n\n#define ARMV8_MRS_T1(r, m1, rd, m) (0xF3E08020 | (r << 20) | (m1 << 16) | (rd << 8) | (m << 4))\n#define ARMV8_MRS_XPSR_T1(r, rd) (0xF3EF8000 | (r << 20) | (rd << 8))\n#define ARMV8_MSR_GP_T1(r, m1, rd, m) (0xF3808020 | (r << 20) | (m1 << 8) | (rd << 16) | (m << 4))\n#define ARMV8_MSR_GP_XPSR_T1(r, rn, mask) (0xF3808000 | (r << 20) | (rn << 16) | (mask << 8))\n\n#define ARMV8_BKPT(im) (0xD4200000 | ((im & 0xffff) << 5))\n#define ARMV8_HLT(im) (0x0D4400000 | ((im & 0xffff) << 5))\n#define ARMV8_HLT_A1(im) (0xE1000070 | ((im & 0xFFF0) << 4) | (im & 0xF))\n#define ARMV8_HLT_T1(im) (0xba80 | (im & 0x3f))\n\n#define ARMV8_MOVFSP_64(rt) ((1 << 31) | 0x11000000 | (0x1f << 5) | (rt))\n#define ARMV8_MOVTSP_64(rt) ((1 << 31) | 0x11000000 | (rt << 5) | (0x1F))\n#define ARMV8_MOVFSP_32(rt) (0x11000000 | (0x1f << 5) | (rt))\n#define ARMV8_MOVTSP_32(rt) (0x11000000 | (rt << 5) | (0x1F))\n\n#define ARMV8_LDRB_IP(rd, rn) (0x38401400 | (rn << 5) | rd)\n#define ARMV8_LDRH_IP(rd, rn) (0x78402400 | (rn << 5) | rd)\n#define ARMV8_LDRW_IP(rd, rn) (0xb8404400 | (rn << 5) | rd)\n\n#define ARMV8_LDRB_IP_T3(rd, rn) (0xf8100b01 | (rn << 16) | (rd << 12))\n#define ARMV8_LDRH_IP_T3(rd, rn) (0xf8300b02 | (rn << 16) | (rd << 12))\n#define ARMV8_LDRW_IP_T3(rd, rn) (0xf8500b04 | (rn << 16) | (rd << 12))\n\n#define ARMV8_STRB_IP(rd, rn) (0x38001400 | (rn << 5) | rd)\n#define ARMV8_STRH_IP(rd, rn) (0x78002400 | (rn << 5) | rd)\n#define ARMV8_STRW_IP(rd, rn) (0xb8004400 | (rn << 5) | rd)\n\n#define ARMV8_STRB_IP_T3(rd, rn) (0xf8000b01 | (rn << 16) | (rd << 12))\n#define ARMV8_STRH_IP_T3(rd, rn) (0xf8200b02 | (rn << 16) | (rd << 12))\n#define ARMV8_STRW_IP_T3(rd, rn) (0xf8400b04 | (rn << 16) | (rd << 12))\n\n#define ARMV8_MOV_GPR_VFP(rd, rn, index) (0x4e083c00 | (index << 20) | (rn << 5) | rd)\n#define ARMV8_MOV_VFP_GPR(rd, rn, index) (0x4e081c00 | (index << 20) | (rn << 5) | rd)\n\n#define ARMV8_MRS_FPCR(rt)\t(0xd53b4400 | (rt))\n#define ARMV8_MRS_FPSR(rt)\t(0xd53b4420 | (rt))\n#define ARMV8_MSR_FPCR(rt)\t(0xd51b4400 | (rt))\n#define ARMV8_MSR_FPSR(rt)\t(0xd51b4420 | (rt))\n\n#define ARMV8_SYS(system, rt) (0xD5080000 | ((system) << 5) | rt)\n\nenum armv8_opcode {\n\tREAD_REG_CTR,\n\tREAD_REG_CLIDR,\n\tREAD_REG_CSSELR,\n\tREAD_REG_CCSIDR,\n\tWRITE_REG_CSSELR,\n\tREAD_REG_MPIDR,\n\tREAD_REG_DTRRX,\n\tWRITE_REG_DTRTX,\n\tWRITE_REG_DSPSR,\n\tREAD_REG_DSPSR,\n\tARMV8_OPC_DSB_SY,\n\tARMV8_OPC_DCPS,\n\tARMV8_OPC_DRPS,\n\tARMV8_OPC_ISB_SY,\n\tARMV8_OPC_DCCISW,\n\tARMV8_OPC_DCCIVAC,\n\tARMV8_OPC_ICIVAU,\n\tARMV8_OPC_HLT,\n\tARMV8_OPC_STRB_IP,\n\tARMV8_OPC_STRH_IP,\n\tARMV8_OPC_STRW_IP,\n\tARMV8_OPC_LDRB_IP,\n\tARMV8_OPC_LDRH_IP,\n\tARMV8_OPC_LDRW_IP,\n\tARMV8_OPC_NUM,\n};\n\nextern uint32_t armv8_opcode(struct armv8_common *armv8, enum armv8_opcode);\nextern void armv8_select_opcodes(struct armv8_common *armv8, bool state_is_aarch64);\n\n#endif /* OPENOCD_TARGET_ARMV8_OPCODES_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_ap7k.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n *   Based on mips_m4k code:                                               *\n *       Copyright (C) 2008 by Spencer Oliver <spen@spen-soft.co.uk>       *\n *       Copyright (C) 2008 by David T.L. Wong                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/jtag.h\"\n#include \"register.h\"\n#include \"algorithm.h\"\n#include \"target.h\"\n#include \"breakpoints.h\"\n#include \"target_type.h\"\n#include \"avr32_jtag.h\"\n#include \"avr32_mem.h\"\n#include \"avr32_regs.h\"\n#include \"avr32_ap7k.h\"\n\nstatic const char * const avr32_core_reg_list[] = {\n\t\"r0\", \"r1\", \"r2\", \"r3\", \"r4\", \"r5\", \"r6\", \"r7\", \"r8\",\n\t\"r9\", \"r10\", \"r11\", \"r12\", \"sp\", \"lr\", \"pc\", \"sr\"\n};\n\nstatic const struct avr32_core_reg\n\tavr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = {\n\t{0, NULL, NULL},\n\t{1, NULL, NULL},\n\t{2, NULL, NULL},\n\t{3, NULL, NULL},\n\t{4, NULL, NULL},\n\t{5, NULL, NULL},\n\t{6, NULL, NULL},\n\t{7, NULL, NULL},\n\t{8, NULL, NULL},\n\t{9, NULL, NULL},\n\t{10, NULL, NULL},\n\t{11, NULL, NULL},\n\t{12, NULL, NULL},\n\t{13, NULL, NULL},\n\t{14, NULL, NULL},\n\t{15, NULL, NULL},\n\t{16, NULL, NULL},\n};\n\n\nstatic int avr32_read_core_reg(struct target *target, int num);\nstatic int avr32_write_core_reg(struct target *target, int num);\n\nstatic int avr32_ap7k_save_context(struct target *target)\n{\n\tint retval, i;\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tretval = avr32_jtag_read_regs(&ap7k->jtag, ap7k->core_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < AVR32NUMCOREREGS; i++) {\n\t\tif (!ap7k->core_cache->reg_list[i].valid)\n\t\t\tavr32_read_core_reg(target, i);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_restore_context(struct target *target)\n{\n\tint i;\n\n\t/* get pointers to arch-specific information */\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tfor (i = 0; i < AVR32NUMCOREREGS; i++) {\n\t\tif (ap7k->core_cache->reg_list[i].dirty)\n\t\t\tavr32_write_core_reg(target, i);\n\t}\n\n\t/* write core regs */\n\tavr32_jtag_write_regs(&ap7k->jtag, ap7k->core_regs);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_read_core_reg(struct target *target, int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tif ((num < 0) || (num >= AVR32NUMCOREREGS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = ap7k->core_regs[num];\n\tbuf_set_u32(ap7k->core_cache->reg_list[num].value, 0, 32, reg_value);\n\tap7k->core_cache->reg_list[num].valid = true;\n\tap7k->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_write_core_reg(struct target *target, int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tif ((num < 0) || (num >= AVR32NUMCOREREGS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32);\n\tap7k->core_regs[num] = reg_value;\n\tLOG_DEBUG(\"write core reg %i value 0x%\" PRIx32 \"\", num, reg_value);\n\tap7k->core_cache->reg_list[num].valid = true;\n\tap7k->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct avr32_core_reg *avr32_reg = reg->arch_info;\n\tstruct target *target = avr32_reg->target;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = avr32_read_core_reg(target, avr32_reg->num);\n\n\treturn retval;\n}\n\nstatic int avr32_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct avr32_core_reg *avr32_reg = reg->arch_info;\n\tstruct target *target = avr32_reg->target;\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u32(reg->value, 0, 32, value);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type avr32_reg_type = {\n\t.get = avr32_get_core_reg,\n\t.set = avr32_set_core_reg,\n};\n\nstatic struct reg_cache *avr32_build_reg_cache(struct target *target)\n{\n\tint num_regs = AVR32NUMCOREREGS;\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct avr32_core_reg *arch_info =\n\t\tmalloc(sizeof(struct avr32_core_reg) * num_regs);\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"avr32 registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\t(*cache_p) = cache;\n\tap7k->core_cache = cache;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i] = avr32_core_reg_list_arch_info[i];\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].avr32_common = ap7k;\n\t\treg_list[i].name = avr32_core_reg_list[i];\n\t\treg_list[i].size = 32;\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].type = &avr32_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\t}\n\n\treturn cache;\n}\n\nstatic int avr32_ap7k_debug_entry(struct target *target)\n{\n\n\tuint32_t dpc, dinst;\n\tint retval;\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tretval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DPC, &dpc);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DINST, &dinst);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tap7k->jtag.dpc = dpc;\n\n\tavr32_ap7k_save_context(target);\n\n\treturn ERROR_OK;\n}\n\n\nstatic int avr32_ap7k_poll(struct target *target)\n{\n\tuint32_t ds;\n\tint retval;\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tretval = avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check for processor halted */\n\tif (ds & OCDREG_DS_DBA) {\n\t\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = avr32_ap7k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t} else if (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = avr32_ap7k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_halt(struct target *target)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {\n\t\t\tLOG_ERROR(\"can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\n\tavr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBR);\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_assert_reset(struct target *target)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_deassert_reset(struct target *target)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_resume(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\tstruct breakpoint *breakpoint = NULL;\n\tuint32_t resume_pc;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\t/*\n\t\tavr32_ap7k_enable_breakpoints(target);\n\t\tavr32_ap7k_enable_watchpoints(target);\n\t\t*/\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n#if 0\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n#endif\n\t}\n\n\tresume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);\n\tavr32_ap7k_restore_context(target);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at 0x%8.8\" TARGET_PRIxADDR \"\", breakpoint->address);\n#if 0\n\t\t\tavr32_ap7k_unset_breakpoint(target, breakpoint);\n\t\t\tavr32_ap7k_single_step_core(target);\n\t\t\tavr32_ap7k_set_breakpoint(target, breakpoint);\n#endif\n\t\t}\n\t}\n\n#if 0\n\t/* enable interrupts if we are running */\n\tavr32_ap7k_enable_interrupts(target, !debug_execution);\n\n\t/* exit debug mode */\n\tmips_ejtag_exit_debug(ejtag_info);\n#endif\n\n\n\tretval = avr32_ocd_clearbits(&ap7k->jtag, AVR32_OCDREG_DC,\n\t\t\tOCDREG_DC_DBR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = avr32_jtag_exec(&ap7k->jtag, RETD);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(ap7k->core_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"target resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"target debug resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_step(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_remove_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_remove_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tLOG_DEBUG(\"address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tswitch (size) {\n\t\tcase 4:\n\t\t\treturn avr32_jtag_read_memory32(&ap7k->jtag, address, count,\n\t\t\t\t(uint32_t *)(void *)buffer);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\treturn avr32_jtag_read_memory16(&ap7k->jtag, address, count,\n\t\t\t\t(uint16_t *)(void *)buffer);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\treturn avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer);\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tLOG_DEBUG(\"address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tswitch (size) {\n\t\tcase 4:\n\t\t\treturn avr32_jtag_write_memory32(&ap7k->jtag, address, count,\n\t\t\t\t(uint32_t *)(void *)buffer);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\treturn avr32_jtag_write_memory16(&ap7k->jtag, address, count,\n\t\t\t\t(uint16_t *)(void *)buffer);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\treturn avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer);\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tap7k->jtag.tap = target->tap;\n\tavr32_build_reg_cache(target);\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct\n\t\t\tavr32_ap7k_common));\n\n\tap7k->common_magic = AP7K_COMMON_MAGIC;\n\ttarget->arch_info = ap7k;\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_examine(struct target *target)\n{\n\tuint32_t devid, ds;\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tif (!target_was_examined(target)) {\n\t\ttarget_set_examined(target);\n\t\tavr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid);\n\t\tLOG_INFO(\"device id: %08\" PRIx32, devid);\n\t\tavr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBE);\n\t\tavr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);\n\n\t\t/* check for processor halted */\n\t\tif (ds & OCDREG_DS_DBA) {\n\t\t\tLOG_INFO(\"target is halted\");\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t} else\n\t\t\ttarget->state = TARGET_RUNNING;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_arch_state(struct target *target)\n{\n\tstruct avr32_ap7k_common *ap7k = target_to_ap7k(target);\n\n\tLOG_USER(\"target halted due to %s, pc: 0x%8.8\" PRIx32 \"\",\n\t\tdebug_reason_name(target), ap7k->jtag.dpc);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n#if 0\n\t/* get pointers to arch-specific information */\n\tint i;\n\n\t/* include floating point registers */\n\t*reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS;\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\tfor (i = 0; i < AVR32NUMCOREREGS; i++)\n\t\t(*reg_list)[i] = &mips32->core_cache->reg_list[i];\n\n\t/* add dummy floating points regs */\n\tfor (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++)\n\t\t(*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg;\n\n#endif\n\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\treturn ERROR_FAIL;\n}\n\nstruct target_type avr32_ap7k_target = {\n\t.name = \"avr32_ap7k\",\n\n\t.poll = avr32_ap7k_poll,\n\t.arch_state = avr32_ap7k_arch_state,\n\n\t.halt = avr32_ap7k_halt,\n\t.resume = avr32_ap7k_resume,\n\t.step = avr32_ap7k_step,\n\n\t.assert_reset = avr32_ap7k_assert_reset,\n\t.deassert_reset = avr32_ap7k_deassert_reset,\n\n\t.get_gdb_reg_list = avr32_ap7k_get_gdb_reg_list,\n\n\t.read_memory = avr32_ap7k_read_memory,\n\t.write_memory = avr32_ap7k_write_memory,\n\t/* .checksum_memory = avr32_ap7k_checksum_memory, */\n\t/* .blank_check_memory = avr32_ap7k_blank_check_memory, */\n\n\t/* .run_algorithm = avr32_ap7k_run_algorithm, */\n\n\t.add_breakpoint = avr32_ap7k_add_breakpoint,\n\t.remove_breakpoint = avr32_ap7k_remove_breakpoint,\n\t.add_watchpoint = avr32_ap7k_add_watchpoint,\n\t.remove_watchpoint = avr32_ap7k_remove_watchpoint,\n\n\t.target_create = avr32_ap7k_target_create,\n\t.init_target = avr32_ap7k_init_target,\n\t.examine = avr32_ap7k_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_ap7k.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AVR32_AP7K_H\n#define OPENOCD_TARGET_AVR32_AP7K_H\n\nstruct target;\n\n#define AP7K_COMMON_MAGIC\t0x4150374bU\n\nstruct avr32_ap7k_common {\n\tunsigned int common_magic;\n\n\tstruct avr32_jtag jtag;\n\tstruct reg_cache *core_cache;\n\tuint32_t core_regs[AVR32NUMCOREREGS];\n};\n\nstatic inline struct avr32_ap7k_common *\ntarget_to_ap7k(struct target *target)\n{\n\treturn (struct avr32_ap7k_common *)target->arch_info;\n}\n\nstruct avr32_core_reg {\n\tuint32_t num;\n\tstruct target *target;\n\tstruct avr32_ap7k_common *avr32_common;\n};\n\n#endif /* OPENOCD_TARGET_AVR32_AP7K_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"jtag/jtag.h\"\n#include \"avr32_jtag.h\"\n\nstatic int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr)\n{\n\tstruct jtag_tap *tap;\n\tint busy = 0;\n\n\ttap = jtag_info->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {\n\t\tdo {\n\t\t\tstruct scan_field field;\n\t\t\tuint8_t t[4] = { 0 };\n\t\t\tuint8_t ret[4];\n\n\t\t\tfield.num_bits = tap->ir_length;\n\t\t\tfield.out_value = t;\n\t\t\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\t\t\tfield.in_value = ret;\n\n\t\t\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\t\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s: setting address failed\", __func__);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbusy = buf_get_u32(ret, 2, 1);\n\t\t} while (busy); /* check for busy bit */\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int mode)\n{\n\tstruct scan_field fields[2];\n\tuint8_t addr_buf[4];\n\tuint8_t busy_buf[4];\n\tint busy;\n\n\tmemset(fields, 0, sizeof(fields));\n\n\tdo {\n\t\tmemset(addr_buf, 0, sizeof(addr_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\n\t\tbuf_set_u32(addr_buf, 0, 1, mode);\n\t\tbuf_set_u32(addr_buf, 1, 7, addr);\n\n\t\tfields[0].num_bits = 26;\n\t\tfields[0].in_value = NULL;\n\t\tfields[0].out_value = NULL;\n\n\t\tfields[1].num_bits = 8;\n\t\tfields[1].in_value = busy_buf;\n\t\tfields[1].out_value = addr_buf;\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: setting address failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbusy = buf_get_u32(busy_buf, 6, 1);\n\t} while (busy);\n\n\treturn ERROR_OK;\n}\n\n\nstatic int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info,\n\tuint32_t *pdata)\n{\n\n\tstruct scan_field fields[2];\n\tuint8_t data_buf[4];\n\tuint8_t busy_buf[4];\n\tint busy;\n\n\tdo {\n\t\tmemset(data_buf, 0, sizeof(data_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\n\t\tfields[0].num_bits = 32;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = data_buf;\n\n\n\t\tfields[1].num_bits = 2;\n\t\tfields[1].in_value = busy_buf;\n\t\tfields[1].out_value = NULL;\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: reading data  failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbusy = buf_get_u32(busy_buf, 0, 1);\n\t} while (busy);\n\n\t*pdata = buf_get_u32(data_buf, 0, 32);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,\n\t\tuint32_t data)\n{\n\n\tstruct scan_field fields[2];\n\tuint8_t data_buf[4];\n\tuint8_t busy_buf[4];\n\tuint8_t dummy_buf[4];\n\tint busy;\n\n\tdo {\n\t\tmemset(data_buf, 0, sizeof(data_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\t\tmemset(dummy_buf, 0, sizeof(dummy_buf));\n\n\t\tfields[0].num_bits = 2;\n\t\tfields[0].in_value = busy_buf;\n\t\tfields[0].out_value = dummy_buf;\n\n\n\t\tbuf_set_u32(data_buf, 0, 32, data);\n\t\tfields[1].num_bits = 32;\n\t\tfields[1].in_value = NULL;\n\t\tfields[1].out_value = data_buf;\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: reading data  failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbusy = buf_get_u32(busy_buf, 0, 0);\n\t} while (busy);\n\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_nexus_read(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, uint32_t *value)\n{\n\tavr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS);\n\tavr32_jtag_nexus_set_address(jtag_info, addr, MODE_READ);\n\treturn avr32_jtag_nexus_read_data(jtag_info, value);\n}\n\nint avr32_jtag_nexus_write(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, uint32_t value)\n{\n\tavr32_jtag_set_instr(jtag_info, AVR32_INST_NEXUS_ACCESS);\n\tavr32_jtag_nexus_set_address(jtag_info, addr, MODE_WRITE);\n\treturn avr32_jtag_nexus_write_data(jtag_info, value);\n}\n\nstatic int avr32_jtag_mwa_set_address(struct avr32_jtag *jtag_info, int slave,\n\t\tuint32_t addr, int mode)\n{\n\tstruct scan_field fields[2];\n\tuint8_t addr_buf[4];\n\tuint8_t slave_buf[4];\n\tuint8_t busy_buf[4];\n\tint busy;\n\n\tmemset(fields, 0, sizeof(fields));\n\n\tdo {\n\t\tmemset(addr_buf, 0, sizeof(addr_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\t\tmemset(slave_buf, 0, sizeof(slave_buf));\n\n\t\tbuf_set_u32(slave_buf, 0, 4, slave);\n\t\tbuf_set_u32(addr_buf, 0, 1, mode);\n\t\tbuf_set_u32(addr_buf, 1, 30, addr >> 2);\n\n\t\tfields[0].num_bits = 31;\n\t\tfields[0].in_value = NULL;\n\t\tfields[0].out_value = addr_buf;\n\n\t\tfields[1].num_bits = 4;\n\t\tfields[1].in_value = busy_buf;\n\t\tfields[1].out_value = slave_buf;\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: setting address failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tbusy = buf_get_u32(busy_buf, 1, 1);\n\t} while (busy);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info,\n\tuint32_t *pdata)\n{\n\n\tstruct scan_field fields[2];\n\tuint8_t data_buf[4];\n\tuint8_t busy_buf[4];\n\tint busy;\n\n\tdo {\n\t\tmemset(data_buf, 0, sizeof(data_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\n\t\tfields[0].num_bits = 32;\n\t\tfields[0].out_value = NULL;\n\t\tfields[0].in_value = data_buf;\n\n\n\t\tfields[1].num_bits = 3;\n\t\tfields[1].in_value = busy_buf;\n\t\tfields[1].out_value = NULL;\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: reading data  failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbusy = buf_get_u32(busy_buf, 0, 1);\n\t} while (busy);\n\n\t*pdata = buf_get_u32(data_buf, 0, 32);\n\n\treturn ERROR_OK;\n}\n\nstatic int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info,\n\tuint32_t data)\n{\n\n\tstruct scan_field fields[2];\n\tuint8_t data_buf[4];\n\tuint8_t busy_buf[4];\n\tuint8_t zero_buf[4];\n\tint busy;\n\n\tdo {\n\t\tmemset(data_buf, 0, sizeof(data_buf));\n\t\tmemset(busy_buf, 0, sizeof(busy_buf));\n\t\tmemset(zero_buf, 0, sizeof(zero_buf));\n\n\t\tbuf_set_u32(data_buf, 0, 32, data);\n\t\tfields[0].num_bits = 3;\n\t\tfields[0].in_value = busy_buf;\n\t\tfields[0].out_value = zero_buf;\n\n\t\tfields[1].num_bits = 32;\n\t\tfields[1].out_value = data_buf;\n\t\tfields[1].in_value = NULL;\n\n\n\t\tjtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);\n\n\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: reading data  failed\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tbusy = buf_get_u32(busy_buf, 0, 1);\n\t} while (busy);\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave,\n\t\tuint32_t addr, uint32_t *value)\n{\n\tavr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS);\n\tavr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_READ);\n\tavr32_jtag_mwa_read_data(jtag_info, value);\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave,\n\t\tuint32_t addr, uint32_t value)\n{\n\tavr32_jtag_set_instr(jtag_info, AVR32_INST_MW_ACCESS);\n\tavr32_jtag_mwa_set_address(jtag_info, slave, addr, MODE_WRITE);\n\tavr32_jtag_mwa_write_data(jtag_info, value);\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst)\n{\n\tint retval;\n\tuint32_t ds;\n\n\tretval = avr32_jtag_nexus_write(jtag_info, AVR32_OCDREG_DINST, inst);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdo {\n\t\tretval = avr32_jtag_nexus_read(jtag_info, AVR32_OCDREG_DS, &ds);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} while ((ds & OCDREG_DS_DBA) && !(ds & OCDREG_DS_INC));\n\n\treturn ERROR_OK;\n}\n\nint avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits)\n{\n\tuint32_t value;\n\tint res;\n\n\tres = avr32_jtag_nexus_read(jtag, reg, &value);\n\tif (res)\n\t\treturn res;\n\n\tvalue |= bits;\n\tres = avr32_jtag_nexus_write(jtag, reg, value);\n\tif (res)\n\t\treturn res;\n\n\treturn ERROR_OK;\n}\n\nint avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits)\n{\n\tuint32_t value;\n\tint res;\n\n\tres = avr32_jtag_nexus_read(jtag, reg, &value);\n\tif (res)\n\t\treturn res;\n\n\tvalue &= ~bits;\n\tres = avr32_jtag_nexus_write(jtag, reg, value);\n\tif (res)\n\t\treturn res;\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AVR32_JTAG_H\n#define OPENOCD_TARGET_AVR32_JTAG_H\n\n#define\tAVR32NUMCOREREGS\t17\n\n/* tap instructions */\n#define AVR32_INST_IDCODE\t\t0x01\n#define AVR32_INST_NEXUS_ACCESS\t0x10\n#define AVR32_INST_MW_ACCESS\t0x11\n#define AVR32_INST_MB_ACCESS\t0x12\n\n#define\tSLAVE_OCD\t\t\t\t0x01\n#define\tSLAVE_HSB_CACHED\t\t0x04\n#define\tSLAVE_HSB_UNCACHED\t\t0x05\n\n/*\n * Registers\n */\n\n#define AVR32_OCDREG_DID\t\t0x00\n#define AVR32_OCDREG_DC\t\t\t0x02\n#define\t\tOCDREG_DC_SS\t\t\t(1 <<  8)\n#define\t\tOCDREG_DC_DBR\t\t\t(1 << 12)\n#define\t\tOCDREG_DC_DBE\t\t\t(1 << 13)\n#define\t\tOCDREG_DC_SQA\t\t\t(1 << 22)\n#define\t\tOCDREG_DC_RES\t\t\t(1 << 30)\n#define\t\tOCDREG_DC_ABORT\t\t\t(1 << 31)\n#define AVR32_OCDREG_DS\t\t\t0x04\n#define\t\tOCDREG_DS_SSS\t\t\t(1 <<  0)\n#define\t\tOCDREG_DS_SWB\t\t\t(1 <<  1)\n#define\t\tOCDREG_DS_HWB\t\t\t(1 <<  2)\n#define\t\tOCDREG_DS_STP\t\t\t(1 <<  4)\n#define\t\tOCDREG_DS_DBS\t\t\t(1 <<  5)\n#define\t\tOCDREG_DS_BP_SHIFT\t\t8\n#define\t\tOCDREG_DS_BP_MASK\t\t0xff\n#define\t\tOCDREG_DS_INC\t\t\t(1 << 24)\n#define\t\tOCDREG_DS_BOZ\t\t\t(1 << 25)\n#define\t\tOCDREG_DS_DBA\t\t\t(1 << 26)\n#define\t\tOCDREG_DS_EXB\t\t\t(1 << 27)\n#define\t\tOCDREG_DS_NTBF\t\t\t(1 << 28)\n\n#define AVR32_OCDREG_DINST\t\t0x41\n#define AVR32_OCDREG_DPC\t\t0x42\n#define AVR32_OCDREG_DCCPU\t\t0x44\n#define AVR32_OCDREG_DCEMU\t\t0x45\n#define AVR32_OCDREG_DCSR\t\t0x46\n#define\t\tOCDREG_DCSR_CPUD\t\t(1 <<  0)\n#define\t\tOCDREG_DCSR_EMUD\t\t(1 <<  1)\n\n/*\n * Direction bit\n */\n#define\tMODE_WRITE\t\t\t\t0x00\n#define\tMODE_READ\t\t\t\t0x01\n\n/*\n * Some instructions\n */\n\n#define\tRETD\t\t\t\t\t0xd703d623\n#define\tMTDR(dreg, reg)\t\t\t(0xe7b00044 | ((reg) << 16) | dreg)\n#define\tMFDR(reg, dreg)\t\t\t(0xe5b00044 | ((reg) << 16) | dreg)\n#define\tMTSR(sysreg, reg)\t\t(0xe3b00002 | ((reg) << 16) | sysreg)\n#define\tMFSR(reg, sysreg)\t\t(0xe1b00002 | ((reg) << 16) | sysreg)\n\nstruct avr32_jtag {\n\tstruct jtag_tap *tap;\n\tuint32_t dpc; /* Debug PC value */\n};\n\nint avr32_jtag_nexus_read(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, uint32_t *value);\nint avr32_jtag_nexus_write(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, uint32_t value);\n\nint avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave,\n\t\tuint32_t addr, uint32_t *value);\nint avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave,\n\t\tuint32_t addr, uint32_t value);\n\nint avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits);\nint avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits);\n\nint avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst);\n\n#endif /* OPENOCD_TARGET_AVR32_JTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_mem.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"jtag/jtag.h\"\n#include \"avr32_jtag.h\"\n#include \"avr32_mem.h\"\n\nint avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, uint32_t *buffer)\n{\n\tint i, retval;\n\tuint32_t data;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*4, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* XXX: Assume AVR32 is BE */\n\t\tbuffer[i] = be_to_h_u32((uint8_t *)&data);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, uint16_t *buffer)\n{\n\tint i, retval;\n\tuint32_t data;\n\n\ti = 0;\n\n\t/* any unaligned half-words? */\n\tif (addr & 3) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* XXX: Assume AVR32 is BE */\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tbuffer[i] = (data >> 16) & 0xffff;\n\t\ti++;\n\t}\n\n\t/* read all complete words */\n\tfor (; i < (count & ~1); i += 2) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* XXX: Assume AVR32 is BE */\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tbuffer[i] = data & 0xffff;\n\t\tbuffer[i+1] = (data >> 16) & 0xffff;\n\t}\n\n\t/* last halfword */\n\tif (i < count) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* XXX: Assume AVR32 is BE */\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tbuffer[i] = data & 0xffff;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_read_memory8(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, uint8_t *buffer)\n{\n\tint i, j, retval;\n\tuint8_t data[4];\n\ti = 0;\n\n\t/* Do we have non-aligned bytes? */\n\tif (addr & 3) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i, (uint32_t *)(void *)data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (j = addr & 3; (j < 4) && (i < count); j++, i++)\n\t\t\tbuffer[i] = data[3-j];\n\t}\n\n\t/* read all complete words */\n\tfor (; i < (count & ~3); i += 4) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i, (uint32_t *)(void *)data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (j = 0; j < 4; j++)\n\t\t\tbuffer[i+j] = data[3-j];\n\t}\n\n\t/* remaining bytes */\n\tif (i < count) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i, (uint32_t *)(void *)data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tfor (j = 0; i + j < count; j++)\n\t\t\tbuffer[i+j] = data[3-j];\n\t}\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_write_memory32(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, const uint32_t *buffer)\n{\n\tint i, retval;\n\tuint32_t data;\n\n\tfor (i = 0; i < count; i++) {\n\t\t/* XXX: Assume AVR32 is BE */\n\t\th_u32_to_be((uint8_t *)&data, buffer[i]);\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*4, data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t}\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, const uint16_t *buffer)\n{\n\tint i, retval;\n\tuint32_t data;\n\tuint32_t data_out;\n\n\ti = 0;\n\n\t/*\n\t * Do we have any non-aligned half-words?\n\t */\n\tif (addr & 3) {\n\t\t/*\n\t\t * mwa_read will read whole world, no need to fiddle\n\t\t * with address. It will be truncated in set_addr\n\t\t */\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tdata = (buffer[i] << 16) | (data & 0xffff);\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\ti++;\n\t}\n\n\t/* write all complete words */\n\tfor (; i < (count & ~1); i += 2) {\n\t\t/* XXX: Assume AVR32 is BE */\n\t\tdata = (buffer[i+1] << 16) | buffer[i];\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* last halfword */\n\tif (i < count) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tdata &= ~0xffff;\n\t\tdata |= buffer[i];\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i*2, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,\n\tuint32_t addr, int count, const uint8_t *buffer)\n{\n\tint i, j, retval;\n\tuint32_t data;\n\tuint32_t data_out;\n\n\ti = 0;\n\n\t/*\n\t * Do we have any non-aligned bytes?\n\t */\n\tif (addr & 3) {\n\t\t/*\n\t\t * mwa_read will read whole world, no need to fiddle\n\t\t * with address. It will be truncated in set_addr\n\t\t */\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tfor (j = addr & 3; (j < 4) && (i < count); j++, i++) {\n\t\t\tdata &= ~(0xff << j*8);\n\t\t\tdata |= (buffer[i] << j*8);\n\t\t}\n\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\n\t/* write all complete words */\n\tfor (; i < (count & ~3); i += 4) {\n\t\tdata = 0;\n\n\t\tfor (j = 0; j < 4; j++)\n\t\t\tdata |= (buffer[j+i] << j*8);\n\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/*\n\t * Write trailing bytes\n\t */\n\tif (i < count) {\n\t\tretval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr + i, &data);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tdata = be_to_h_u32((uint8_t *)&data);\n\t\tfor (j = 0; i < count; j++, i++) {\n\t\t\tdata &= ~(0xff << j*8);\n\t\t\tdata |= (buffer[j+i] << j*8);\n\t\t}\n\n\t\th_u32_to_be((uint8_t *)&data_out, data);\n\n\t\tretval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,\n\t\t\t\taddr+i, data_out);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_mem.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AVR32_MEM_H\n#define OPENOCD_TARGET_AVR32_MEM_H\n\nint avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, uint32_t *buffer);\nint avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, uint16_t *buffer);\nint avr32_jtag_read_memory8(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, uint8_t *buffer);\n\nint avr32_jtag_write_memory32(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, const uint32_t *buffer);\nint avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, const uint16_t *buffer);\nint avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,\n\t\tuint32_t addr, int count, const uint8_t *buffer);\n\n#endif /* OPENOCD_TARGET_AVR32_MEM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_regs.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"jtag/jtag.h\"\n#include \"avr32_jtag.h\"\n#include \"avr32_regs.h\"\n\nstatic int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg,\n\t\tuint32_t *val)\n{\n\tint retval;\n\tuint32_t dcsr;\n\n\tretval = avr32_jtag_exec(jtag_info, MTDR(AVR32_OCDREG_DCCPU, reg));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdo {\n\t\tretval = avr32_jtag_nexus_read(jtag_info,\n\t\t\tAVR32_OCDREG_DCSR, &dcsr);\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} while (!(dcsr & OCDREG_DCSR_CPUD));\n\n\tretval = avr32_jtag_nexus_read(jtag_info,\n\t\t\tAVR32_OCDREG_DCCPU, val);\n\n\treturn retval;\n}\n\nstatic int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg,\n\t\tuint32_t val)\n{\n\tint retval;\n\tuint32_t dcsr;\n\n\t/* Restore Status reg */\n\tretval = avr32_jtag_nexus_write(jtag_info,\n\t\t\t\tAVR32_OCDREG_DCEMU, val);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = avr32_jtag_exec(jtag_info, MFDR(reg, AVR32_OCDREG_DCEMU));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tdo {\n\t\tretval = avr32_jtag_nexus_read(jtag_info,\n\t\t\tAVR32_OCDREG_DCSR, &dcsr);\n\t} while (!(dcsr & OCDREG_DCSR_EMUD) && (retval == ERROR_OK));\n\n\treturn retval;\n}\n\n\n\nint avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs)\n{\n\tint i, retval;\n\n\t/* read core registers */\n\tfor (i = 0; i < AVR32NUMCOREREGS - 1; i++)\n\t\tavr32_jtag_read_reg(jtag_info, i, regs + i);\n\n\t/* read status register */\n\tretval = avr32_jtag_exec(jtag_info, MFSR(0, 0));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = avr32_jtag_read_reg(jtag_info, 0, regs + AVR32_REG_SR);\n\n\treturn retval;\n}\n\nint avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs)\n{\n\tint i, retval;\n\n\tretval = avr32_jtag_write_reg(jtag_info, 0, regs[AVR32_REG_SR]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Restore Status reg */\n\tretval = avr32_jtag_exec(jtag_info, MTSR(0, 0));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/*\n\t * And now the rest of registers\n\t */\n\tfor (i = 0; i < AVR32NUMCOREREGS - 1; i++)\n\t\tavr32_jtag_write_reg(jtag_info, i, regs[i]);\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avr32_regs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2010 by Oleksandr Tymoshenko <gonzo@bluezbox.com>       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AVR32_REGS_H\n#define OPENOCD_TARGET_AVR32_REGS_H\n\nenum avr32_reg_nums {\n\tAVR32_REG_R0 = 0,\n\tAVR32_REG_R1,\n\tAVR32_REG_R2,\n\tAVR32_REG_R3,\n\tAVR32_REG_R4,\n\tAVR32_REG_R5,\n\tAVR32_REG_R6,\n\tAVR32_REG_R7,\n\tAVR32_REG_R8,\n\tAVR32_REG_R9,\n\tAVR32_REG_R10,\n\tAVR32_REG_R11,\n\tAVR32_REG_R12,\n\tAVR32_REG_SP,\n\tAVR32_REG_LR,\n\tAVR32_REG_PC,\n\tAVR32_REG_SR,\n};\n\nint avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs);\nint avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs);\n\n#endif /* OPENOCD_TARGET_AVR32_REGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avrt.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian                                      *\n *   SimonQian@SimonQian.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"avrt.h\"\n#include \"target.h\"\n#include \"target_type.h\"\n\n#define AVR_JTAG_INS_LEN\t4\n\n/* forward declarations */\nstatic int avr_target_create(struct target *target, Jim_Interp *interp);\nstatic int avr_init_target(struct command_context *cmd_ctx, struct target *target);\n\nstatic int avr_arch_state(struct target *target);\nstatic int avr_poll(struct target *target);\nstatic int avr_halt(struct target *target);\nstatic int avr_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution);\nstatic int avr_step(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints);\n\nstatic int avr_assert_reset(struct target *target);\nstatic int avr_deassert_reset(struct target *target);\n\n/* IR and DR functions */\nstatic int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti);\nstatic int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti);\nstatic int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);\nstatic int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);\n\nstruct target_type avr_target = {\n\t.name = \"avr\",\n\n\t.poll = avr_poll,\n\t.arch_state = avr_arch_state,\n\n\t.halt = avr_halt,\n\t.resume = avr_resume,\n\t.step = avr_step,\n\n\t.assert_reset = avr_assert_reset,\n\t.deassert_reset = avr_deassert_reset,\n/*\n\t.get_gdb_reg_list = avr_get_gdb_reg_list,\n\n\t.read_memory = avr_read_memory,\n\t.write_memory = avr_write_memory,\n\t.bulk_write_memory = avr_bulk_write_memory,\n\t.checksum_memory = avr_checksum_memory,\n\t.blank_check_memory = avr_blank_check_memory,\n\n\t.run_algorithm = avr_run_algorithm,\n\n\t.add_breakpoint = avr_add_breakpoint,\n\t.remove_breakpoint = avr_remove_breakpoint,\n\t.add_watchpoint = avr_add_watchpoint,\n\t.remove_watchpoint = avr_remove_watchpoint,\n*/\n\t.target_create = avr_target_create,\n\t.init_target = avr_init_target,\n};\n\nstatic int avr_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct avr_common *avr = calloc(1, sizeof(struct avr_common));\n\n\tavr->jtag_info.tap = target->tap;\n\ttarget->arch_info = avr;\n\n\treturn ERROR_OK;\n}\n\nstatic int avr_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_arch_state(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_poll(struct target *target)\n{\n\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))\n\t\ttarget->state = TARGET_HALTED;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_halt(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_assert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RESET;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int avr_deassert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RUNNING;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nint avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out,\n\t\tint len)\n{\n\treturn mcu_write_dr_u32(tap, dr_in, dr_out, len, 1);\n}\n\nint avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out)\n{\n\treturn mcu_write_ir_u8(tap, ir_in, ir_out, AVR_JTAG_INS_LEN, 1);\n}\n\n/* IR and DR functions */\nstatic int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,\n\t\tint ir_len, int rti)\n{\n\tif (!tap) {\n\t\tLOG_ERROR(\"invalid tap\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (ir_len != tap->ir_length) {\n\t\tLOG_ERROR(\"invalid ir_len\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t{\n\t\tjtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,\n\t\tint dr_len, int rti)\n{\n\tif (!tap) {\n\t\tLOG_ERROR(\"invalid tap\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t{\n\t\tjtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in,\n\t\tuint8_t ir_out, int ir_len, int rti)\n{\n\tif (ir_len > 8) {\n\t\tLOG_ERROR(\"ir_len overflow, maximum is 8\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmcu_write_ir(tap, ir_in, &ir_out, ir_len, rti);\n\n\treturn ERROR_OK;\n}\n\nstatic int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in,\n\t\tuint32_t dr_out, int dr_len, int rti)\n{\n\tif (dr_len > 32) {\n\t\tLOG_ERROR(\"dr_len overflow, maximum is 32\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len, rti);\n\n\treturn ERROR_OK;\n}\n\nint mcu_execute_queue(void)\n{\n\treturn jtag_execute_queue();\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/avrt.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Simon Qian                                      *\n *   SimonQian@SimonQian.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_AVRT_H\n#define OPENOCD_TARGET_AVRT_H\n\n#include <jtag/jtag.h>\n\nstruct mcu_jtag {\n\tstruct jtag_tap *tap;\n};\n\nstruct avr_common {\n\tstruct mcu_jtag jtag_info;\n};\n\nint mcu_execute_queue(void);\nint avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out);\nint avr_jtag_senddat(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out,\n\t\tint len);\n\n#endif /* OPENOCD_TARGET_AVRT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/breakpoints.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011                                     *\n *   michel.jaouen@stericsson.com : smp minimum support                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include <helper/log.h>\n#include \"breakpoints.h\"\n#include \"smp.h\"\n\nstatic const char * const breakpoint_type_strings[] = {\n\t\"hardware\",\n\t\"software\"\n};\n\nstatic const char * const watchpoint_rw_strings[] = {\n\t\"read\",\n\t\"write\",\n\t\"access\"\n};\n\n/* monotonic counter/id-number for breakpoints and watch points */\nstatic int bpwp_unique_id;\n\nstatic int breakpoint_add_internal(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\tstruct breakpoint **breakpoint_p = &target->breakpoints;\n\tconst char *reason;\n\tint retval;\n\n\twhile (breakpoint) {\n\t\tif (breakpoint->address == address) {\n\t\t\t/* FIXME don't assume \"same address\" means \"same\n\t\t\t * breakpoint\" ... check all the parameters before\n\t\t\t * succeeding.\n\t\t\t */\n\t\t\tLOG_ERROR(\"Duplicate Breakpoint address: \" TARGET_ADDR_FMT \" (BP %\" PRIu32 \")\",\n\t\t\t\taddress, breakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_DUPLICATE_BREAKPOINT;\n\t\t}\n\t\tbreakpoint_p = &breakpoint->next;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\t(*breakpoint_p) = malloc(sizeof(struct breakpoint));\n\t(*breakpoint_p)->address = address;\n\t(*breakpoint_p)->asid = 0;\n\t(*breakpoint_p)->length = length;\n\t(*breakpoint_p)->type = type;\n\t(*breakpoint_p)->is_set = false;\n\t(*breakpoint_p)->orig_instr = malloc(length);\n\t(*breakpoint_p)->next = NULL;\n\t(*breakpoint_p)->unique_id = bpwp_unique_id++;\n\n\tretval = target_add_breakpoint(target, *breakpoint_p);\n\tswitch (retval) {\n\t\tcase ERROR_OK:\n\t\t\tbreak;\n\t\tcase ERROR_TARGET_RESOURCE_NOT_AVAILABLE:\n\t\t\treason = \"resource not available\";\n\t\t\tgoto fail;\n\t\tcase ERROR_TARGET_NOT_HALTED:\n\t\t\treason = \"target running\";\n\t\t\tgoto fail;\n\t\tdefault:\n\t\t\treason = \"unknown reason\";\nfail:\n\t\t\tLOG_ERROR(\"can't add breakpoint: %s\", reason);\n\t\t\tfree((*breakpoint_p)->orig_instr);\n\t\t\tfree(*breakpoint_p);\n\t\t\t*breakpoint_p = NULL;\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"[%d] added %s breakpoint at \" TARGET_ADDR_FMT\n\t\t\t\" of length 0x%8.8x, (BPID: %\" PRIu32 \")\",\n\t\ttarget->coreid,\n\t\tbreakpoint_type_strings[(*breakpoint_p)->type],\n\t\t(*breakpoint_p)->address, (*breakpoint_p)->length,\n\t\t(*breakpoint_p)->unique_id);\n\n\treturn ERROR_OK;\n}\n\nstatic int context_breakpoint_add_internal(struct target *target,\n\tuint32_t asid,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\tstruct breakpoint **breakpoint_p = &target->breakpoints;\n\tint retval;\n\n\twhile (breakpoint) {\n\t\tif (breakpoint->asid == asid) {\n\t\t\t/* FIXME don't assume \"same address\" means \"same\n\t\t\t * breakpoint\" ... check all the parameters before\n\t\t\t * succeeding.\n\t\t\t */\n\t\t\tLOG_ERROR(\"Duplicate Breakpoint asid: 0x%08\" PRIx32 \" (BP %\" PRIu32 \")\",\n\t\t\t\tasid, breakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_DUPLICATE_BREAKPOINT;\n\t\t}\n\t\tbreakpoint_p = &breakpoint->next;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\t(*breakpoint_p) = malloc(sizeof(struct breakpoint));\n\t(*breakpoint_p)->address = 0;\n\t(*breakpoint_p)->asid = asid;\n\t(*breakpoint_p)->length = length;\n\t(*breakpoint_p)->type = type;\n\t(*breakpoint_p)->is_set = false;\n\t(*breakpoint_p)->orig_instr = malloc(length);\n\t(*breakpoint_p)->next = NULL;\n\t(*breakpoint_p)->unique_id = bpwp_unique_id++;\n\tretval = target_add_context_breakpoint(target, *breakpoint_p);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not add breakpoint\");\n\t\tfree((*breakpoint_p)->orig_instr);\n\t\tfree(*breakpoint_p);\n\t\t*breakpoint_p = NULL;\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"added %s Context breakpoint at 0x%8.8\" PRIx32 \" of length 0x%8.8x, (BPID: %\" PRIu32 \")\",\n\t\tbreakpoint_type_strings[(*breakpoint_p)->type],\n\t\t(*breakpoint_p)->asid, (*breakpoint_p)->length,\n\t\t(*breakpoint_p)->unique_id);\n\n\treturn ERROR_OK;\n}\n\nstatic int hybrid_breakpoint_add_internal(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t asid,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\tstruct breakpoint **breakpoint_p = &target->breakpoints;\n\tint retval;\n\n\twhile (breakpoint) {\n\t\tif ((breakpoint->asid == asid) && (breakpoint->address == address)) {\n\t\t\t/* FIXME don't assume \"same address\" means \"same\n\t\t\t * breakpoint\" ... check all the parameters before\n\t\t\t * succeeding.\n\t\t\t */\n\t\t\tLOG_ERROR(\"Duplicate Hybrid Breakpoint asid: 0x%08\" PRIx32 \" (BP %\" PRIu32 \")\",\n\t\t\t\tasid, breakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_DUPLICATE_BREAKPOINT;\n\t\t} else if ((breakpoint->address == address) && (breakpoint->asid == 0)) {\n\t\t\tLOG_ERROR(\"Duplicate Breakpoint IVA: \" TARGET_ADDR_FMT \" (BP %\" PRIu32 \")\",\n\t\t\t\taddress, breakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_DUPLICATE_BREAKPOINT;\n\n\t\t}\n\t\tbreakpoint_p = &breakpoint->next;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\t(*breakpoint_p) = malloc(sizeof(struct breakpoint));\n\t(*breakpoint_p)->address = address;\n\t(*breakpoint_p)->asid = asid;\n\t(*breakpoint_p)->length = length;\n\t(*breakpoint_p)->type = type;\n\t(*breakpoint_p)->is_set = false;\n\t(*breakpoint_p)->orig_instr = malloc(length);\n\t(*breakpoint_p)->next = NULL;\n\t(*breakpoint_p)->unique_id = bpwp_unique_id++;\n\n\n\tretval = target_add_hybrid_breakpoint(target, *breakpoint_p);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not add breakpoint\");\n\t\tfree((*breakpoint_p)->orig_instr);\n\t\tfree(*breakpoint_p);\n\t\t*breakpoint_p = NULL;\n\t\treturn retval;\n\t}\n\tLOG_DEBUG(\n\t\t\"added %s Hybrid breakpoint at address \" TARGET_ADDR_FMT \" of length 0x%8.8x, (BPID: %\" PRIu32 \")\",\n\t\tbreakpoint_type_strings[(*breakpoint_p)->type],\n\t\t(*breakpoint_p)->address,\n\t\t(*breakpoint_p)->length,\n\t\t(*breakpoint_p)->unique_id);\n\n\treturn ERROR_OK;\n}\n\nint breakpoint_add(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tif (type == BKPT_SOFT) {\n\t\t\thead = list_first_entry(target->smp_targets, struct target_list, lh);\n\t\t\treturn breakpoint_add_internal(head->target, address, length, type);\n\t\t}\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tint retval = breakpoint_add_internal(curr, address, length, type);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t} else {\n\t\treturn breakpoint_add_internal(target, address, length, type);\n\t}\n}\n\nint context_breakpoint_add(struct target *target,\n\tuint32_t asid,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tint retval = context_breakpoint_add_internal(curr, asid, length, type);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t} else {\n\t\treturn context_breakpoint_add_internal(target, asid, length, type);\n\t}\n}\n\nint hybrid_breakpoint_add(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t asid,\n\tuint32_t length,\n\tenum breakpoint_type type)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tint retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t} else\n\t\treturn hybrid_breakpoint_add_internal(target, address, asid, length, type);\n}\n\n/* free up a breakpoint */\nstatic void breakpoint_free(struct target *target, struct breakpoint *breakpoint_to_remove)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\tstruct breakpoint **breakpoint_p = &target->breakpoints;\n\tint retval;\n\n\twhile (breakpoint) {\n\t\tif (breakpoint == breakpoint_to_remove)\n\t\t\tbreak;\n\t\tbreakpoint_p = &breakpoint->next;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\tif (!breakpoint)\n\t\treturn;\n\n\tretval = target_remove_breakpoint(target, breakpoint);\n\n\tLOG_DEBUG(\"free BPID: %\" PRIu32 \" --> %d\", breakpoint->unique_id, retval);\n\t(*breakpoint_p) = breakpoint->next;\n\tfree(breakpoint->orig_instr);\n\tfree(breakpoint);\n}\n\nstatic int breakpoint_remove_internal(struct target *target, target_addr_t address)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\twhile (breakpoint) {\n\t\tif ((breakpoint->address == address) ||\n\t\t    (breakpoint->address == 0 && breakpoint->asid == address))\n\t\t\tbreak;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\tif (breakpoint) {\n\t\tbreakpoint_free(target, breakpoint);\n\t\treturn 1;\n\t} else {\n\t\tif (!target->smp)\n\t\t\tLOG_ERROR(\"no breakpoint at address \" TARGET_ADDR_FMT \" found\", address);\n\t\treturn 0;\n\t}\n}\n\nstatic void breakpoint_remove_all_internal(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\twhile (breakpoint) {\n\t\tstruct breakpoint *tmp = breakpoint;\n\t\tbreakpoint = breakpoint->next;\n\t\tbreakpoint_free(target, tmp);\n\t}\n}\n\nvoid breakpoint_remove(struct target *target, target_addr_t address)\n{\n\tif (target->smp) {\n\t\tunsigned int num_breakpoints = 0;\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tnum_breakpoints += breakpoint_remove_internal(curr, address);\n\t\t}\n\t\tif (!num_breakpoints)\n\t\t\tLOG_ERROR(\"no breakpoint at address \" TARGET_ADDR_FMT \" found\", address);\n\t} else {\n\t\tbreakpoint_remove_internal(target, address);\n\t}\n}\n\nvoid breakpoint_remove_all(struct target *target)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tbreakpoint_remove_all_internal(curr);\n\t\t}\n\t} else {\n\t\tbreakpoint_remove_all_internal(target);\n\t}\n}\n\nstatic void breakpoint_clear_target_internal(struct target *target)\n{\n\tLOG_DEBUG(\"Delete all breakpoints for target: %s\",\n\t\ttarget_name(target));\n\twhile (target->breakpoints)\n\t\tbreakpoint_free(target, target->breakpoints);\n}\n\nvoid breakpoint_clear_target(struct target *target)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tbreakpoint_clear_target_internal(curr);\n\t\t}\n\t} else {\n\t\tbreakpoint_clear_target_internal(target);\n\t}\n}\n\nstruct breakpoint *breakpoint_find(struct target *target, target_addr_t address)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\twhile (breakpoint) {\n\t\tif (breakpoint->address == address)\n\t\t\treturn breakpoint;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\treturn NULL;\n}\n\nstatic int watchpoint_add_internal(struct target *target, target_addr_t address,\n\t\tuint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\tstruct watchpoint **watchpoint_p = &target->watchpoints;\n\tint retval;\n\tconst char *reason;\n\n\twhile (watchpoint) {\n\t\tif (watchpoint->address == address) {\n\t\t\tif (watchpoint->length != length\n\t\t\t\t|| watchpoint->value != value\n\t\t\t\t|| watchpoint->mask != mask\n\t\t\t\t|| watchpoint->rw != rw) {\n\t\t\t\tLOG_ERROR(\"address \" TARGET_ADDR_FMT\n\t\t\t\t\t\" already has watchpoint %d\",\n\t\t\t\t\taddress, watchpoint->unique_id);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* ignore duplicate watchpoint */\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\twatchpoint_p = &watchpoint->next;\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\t(*watchpoint_p) = calloc(1, sizeof(struct watchpoint));\n\t(*watchpoint_p)->address = address;\n\t(*watchpoint_p)->length = length;\n\t(*watchpoint_p)->value = value;\n\t(*watchpoint_p)->mask = mask;\n\t(*watchpoint_p)->rw = rw;\n\t(*watchpoint_p)->unique_id = bpwp_unique_id++;\n\n\tretval = target_add_watchpoint(target, *watchpoint_p);\n\tswitch (retval) {\n\t\tcase ERROR_OK:\n\t\t\tbreak;\n\t\tcase ERROR_TARGET_RESOURCE_NOT_AVAILABLE:\n\t\t\treason = \"resource not available\";\n\t\t\tgoto bye;\n\t\tcase ERROR_TARGET_NOT_HALTED:\n\t\t\treason = \"target running\";\n\t\t\tgoto bye;\n\t\tdefault:\n\t\t\treason = \"unrecognized error\";\nbye:\n\t\t\tLOG_ERROR(\"can't add %s watchpoint at \" TARGET_ADDR_FMT \", %s\",\n\t\t\t\twatchpoint_rw_strings[(*watchpoint_p)->rw],\n\t\t\t\taddress, reason);\n\t\t\tfree(*watchpoint_p);\n\t\t\t*watchpoint_p = NULL;\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"[%d] added %s watchpoint at \" TARGET_ADDR_FMT\n\t\t\t\" of length 0x%8.8\" PRIx32 \" (WPID: %d)\",\n\t\ttarget->coreid,\n\t\twatchpoint_rw_strings[(*watchpoint_p)->rw],\n\t\t(*watchpoint_p)->address,\n\t\t(*watchpoint_p)->length,\n\t\t(*watchpoint_p)->unique_id);\n\n\treturn ERROR_OK;\n}\n\nint watchpoint_add(struct target *target, target_addr_t address,\n\t\tuint32_t length, enum watchpoint_rw rw, uint32_t value, uint32_t mask)\n{\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tint retval = watchpoint_add_internal(curr, address, length, rw, value, mask);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t} else {\n\t\treturn watchpoint_add_internal(target, address, length, rw, value,\n\t\t\t\tmask);\n\t}\n}\n\nstatic void watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\tstruct watchpoint **watchpoint_p = &target->watchpoints;\n\tint retval;\n\n\twhile (watchpoint) {\n\t\tif (watchpoint == watchpoint_to_remove)\n\t\t\tbreak;\n\t\twatchpoint_p = &watchpoint->next;\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\tif (!watchpoint)\n\t\treturn;\n\tretval = target_remove_watchpoint(target, watchpoint);\n\tLOG_DEBUG(\"free WPID: %d --> %d\", watchpoint->unique_id, retval);\n\t(*watchpoint_p) = watchpoint->next;\n\tfree(watchpoint);\n}\n\nstatic int watchpoint_remove_internal(struct target *target, target_addr_t address)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\twhile (watchpoint) {\n\t\tif (watchpoint->address == address)\n\t\t\tbreak;\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\tif (watchpoint) {\n\t\twatchpoint_free(target, watchpoint);\n\t\treturn 1;\n\t} else {\n\t\tif (!target->smp)\n\t\t\tLOG_ERROR(\"no watchpoint at address \" TARGET_ADDR_FMT \" found\", address);\n\t\treturn 0;\n\t}\n}\n\nvoid watchpoint_remove(struct target *target, target_addr_t address)\n{\n\tif (target->smp) {\n\t\tunsigned int num_watchpoints = 0;\n\t\tstruct target_list *head;\n\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tnum_watchpoints += watchpoint_remove_internal(curr, address);\n\t\t}\n\t\tif (num_watchpoints == 0)\n\t\t\tLOG_ERROR(\"no watchpoint at address \" TARGET_ADDR_FMT \" num_watchpoints\", address);\n\t} else {\n\t\twatchpoint_remove_internal(target, address);\n\t}\n}\n\nvoid watchpoint_clear_target(struct target *target)\n{\n\tLOG_DEBUG(\"Delete all watchpoints for target: %s\",\n\t\ttarget_name(target));\n\twhile (target->watchpoints)\n\t\twatchpoint_free(target, target->watchpoints);\n}\n\nint watchpoint_hit(struct target *target, enum watchpoint_rw *rw,\n\t\t   target_addr_t *address)\n{\n\tint retval;\n\tstruct watchpoint *hit_watchpoint;\n\n\tretval = target_hit_watchpoint(target, &hit_watchpoint);\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t*rw = hit_watchpoint->rw;\n\t*address = hit_watchpoint->address;\n\n\tLOG_DEBUG(\"Found hit watchpoint at \" TARGET_ADDR_FMT \" (WPID: %d)\",\n\t\thit_watchpoint->address,\n\t\thit_watchpoint->unique_id);\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/breakpoints.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_BREAKPOINTS_H\n#define OPENOCD_TARGET_BREAKPOINTS_H\n\n#include <stdint.h>\n\n#include \"helper/types.h\"\n\nstruct target;\n\nenum breakpoint_type {\n\tBKPT_HARD,\n\tBKPT_SOFT,\n};\n\nenum watchpoint_rw {\n\tWPT_READ = 0, WPT_WRITE = 1, WPT_ACCESS = 2\n};\n\nstruct breakpoint {\n\ttarget_addr_t address;\n\tuint32_t asid;\n\tint length;\n\tenum breakpoint_type type;\n\tbool is_set;\n\tunsigned int number;\n\tuint8_t *orig_instr;\n\tstruct breakpoint *next;\n\tuint32_t unique_id;\n\tint linked_brp;\n};\n\nstruct watchpoint {\n\ttarget_addr_t address;\n\tuint32_t length;\n\tuint32_t mask;\n\tuint32_t value;\n\tenum watchpoint_rw rw;\n\tbool is_set;\n\tunsigned int number;\n\tstruct watchpoint *next;\n\tint unique_id;\n};\n\nvoid breakpoint_clear_target(struct target *target);\nint breakpoint_add(struct target *target,\n\t\ttarget_addr_t address, uint32_t length, enum breakpoint_type type);\nint context_breakpoint_add(struct target *target,\n\t\tuint32_t asid, uint32_t length, enum breakpoint_type type);\nint hybrid_breakpoint_add(struct target *target,\n\t\ttarget_addr_t address, uint32_t asid, uint32_t length, enum breakpoint_type type);\nvoid breakpoint_remove(struct target *target, target_addr_t address);\nvoid breakpoint_remove_all(struct target *target);\n\nstruct breakpoint *breakpoint_find(struct target *target, target_addr_t address);\n\nstatic inline void breakpoint_hw_set(struct breakpoint *breakpoint, unsigned int hw_number)\n{\n\tbreakpoint->is_set = true;\n\tbreakpoint->number = hw_number;\n}\n\nvoid watchpoint_clear_target(struct target *target);\nint watchpoint_add(struct target *target,\n\t\ttarget_addr_t address, uint32_t length,\n\t\tenum watchpoint_rw rw, uint32_t value, uint32_t mask);\nvoid watchpoint_remove(struct target *target, target_addr_t address);\n\n/* report type and address of just hit watchpoint */\nint watchpoint_hit(struct target *target, enum watchpoint_rw *rw,\n\t\ttarget_addr_t *address);\n\nstatic inline void watchpoint_set(struct watchpoint *watchpoint, unsigned int number)\n{\n\twatchpoint->is_set = true;\n\twatchpoint->number = number;\n}\n\n#endif /* OPENOCD_TARGET_BREAKPOINTS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/cortex_a.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2009 by Dirk Behme                                      *\n *   dirk.behme@gmail.com - copy from cortex_m3                            *\n *                                                                         *\n *   Copyright (C) 2010 Øyvind Harboe                                      *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011                                     *\n *   michel.jaouen@stericsson.com : smp minimum support                    *\n *                                                                         *\n *   Copyright (C) Broadcom 2012                                           *\n *   ehunter@broadcom.com : Cortex-R4 support                              *\n *                                                                         *\n *   Copyright (C) 2013 Kamal Dasu                                         *\n *   kdasu.kdev@gmail.com                                                  *\n *                                                                         *\n *   Copyright (C) 2016 Chengyu Zheng                                      *\n *   chengyu.zheng@polimi.it : watchpoint support                          *\n *                                                                         *\n *   Cortex-A8(tm) TRM, ARM DDI 0344H                                      *\n *   Cortex-A9(tm) TRM, ARM DDI 0407F                                      *\n *   Cortex-A4(tm) TRM, ARM DDI 0363E                                      *\n *   Cortex-A15(tm)TRM, ARM DDI 0438C                                      *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"cortex_a.h\"\n#include \"register.h\"\n#include \"armv7a_mmu.h\"\n#include \"target_request.h\"\n#include \"target_type.h\"\n#include \"arm_coresight.h\"\n#include \"arm_opcodes.h\"\n#include \"arm_semihosting.h\"\n#include \"jtag/interface.h\"\n#include \"transport/transport.h\"\n#include \"smp.h\"\n#include <helper/bits.h>\n#include <helper/nvp.h>\n#include <helper/time_support.h>\n\nstatic int cortex_a_poll(struct target *target);\nstatic int cortex_a_debug_entry(struct target *target);\nstatic int cortex_a_restore_context(struct target *target, bool bpwp);\nstatic int cortex_a_set_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode);\nstatic int cortex_a_set_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode);\nstatic int cortex_a_set_hybrid_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint);\nstatic int cortex_a_unset_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint);\nstatic int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask,\n\tuint32_t value, uint32_t *dscr);\nstatic int cortex_a_mmu(struct target *target, int *enabled);\nstatic int cortex_a_mmu_modify(struct target *target, int enable);\nstatic int cortex_a_virt2phys(struct target *target,\n\ttarget_addr_t virt, target_addr_t *phys);\nstatic int cortex_a_read_cpu_memory(struct target *target,\n\tuint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);\n\nstatic unsigned int ilog2(unsigned int x)\n{\n\tunsigned int y = 0;\n\tx /= 2;\n\twhile (x) {\n\t\t++y;\n\t\tx /= 2;\n\t\t}\n\treturn y;\n}\n\n/*  restore cp15_control_reg at resume */\nstatic int cortex_a_restore_cp15_control_reg(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (cortex_a->cp15_control_reg != cortex_a->cp15_control_reg_curr) {\n\t\tcortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg;\n\t\t/* LOG_INFO(\"cp15_control_reg: %8.8\" PRIx32, cortex_a->cp15_control_reg); */\n\t\tretval = armv7a->arm.mcr(target, 15,\n\t\t\t\t0, 0,\t/* op1, op2 */\n\t\t\t\t1, 0,\t/* CRn, CRm */\n\t\t\t\tcortex_a->cp15_control_reg);\n\t}\n\treturn retval;\n}\n\n/*\n * Set up ARM core for memory access.\n * If !phys_access, switch to SVC mode and make sure MMU is on\n * If phys_access, switch off mmu\n */\nstatic int cortex_a_prep_memaccess(struct target *target, int phys_access)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tint mmu_enabled = 0;\n\n\tif (phys_access == 0) {\n\t\tarm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);\n\t\tcortex_a_mmu(target, &mmu_enabled);\n\t\tif (mmu_enabled)\n\t\t\tcortex_a_mmu_modify(target, 1);\n\t\tif (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {\n\t\t\t/* overwrite DACR to all-manager */\n\t\t\tarmv7a->arm.mcr(target, 15,\n\t\t\t\t\t0, 0, 3, 0,\n\t\t\t\t\t0xFFFFFFFF);\n\t\t}\n\t} else {\n\t\tcortex_a_mmu(target, &mmu_enabled);\n\t\tif (mmu_enabled)\n\t\t\tcortex_a_mmu_modify(target, 0);\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * Restore ARM core after memory access.\n * If !phys_access, switch to previous mode\n * If phys_access, restore MMU setting\n */\nstatic int cortex_a_post_memaccess(struct target *target, int phys_access)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif (phys_access == 0) {\n\t\tif (cortex_a->dacrfixup_mode == CORTEX_A_DACRFIXUP_ON) {\n\t\t\t/* restore */\n\t\t\tarmv7a->arm.mcr(target, 15,\n\t\t\t\t\t0, 0, 3, 0,\n\t\t\t\t\tcortex_a->cp15_dacr_reg);\n\t\t}\n\t\tarm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);\n\t} else {\n\t\tint mmu_enabled = 0;\n\t\tcortex_a_mmu(target, &mmu_enabled);\n\t\tif (mmu_enabled)\n\t\t\tcortex_a_mmu_modify(target, 1);\n\t}\n\treturn ERROR_OK;\n}\n\n\n/*  modify cp15_control_reg in order to enable or disable mmu for :\n *  - virt2phys address conversion\n *  - read or write memory in phys or virt address */\nstatic int cortex_a_mmu_modify(struct target *target, int enable)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval = ERROR_OK;\n\tint need_write = 0;\n\n\tif (enable) {\n\t\t/*  if mmu enabled at target stop and mmu not enable */\n\t\tif (!(cortex_a->cp15_control_reg & 0x1U)) {\n\t\t\tLOG_ERROR(\"trying to enable mmu on target stopped with mmu disable\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif ((cortex_a->cp15_control_reg_curr & 0x1U) == 0) {\n\t\t\tcortex_a->cp15_control_reg_curr |= 0x1U;\n\t\t\tneed_write = 1;\n\t\t}\n\t} else {\n\t\tif ((cortex_a->cp15_control_reg_curr & 0x1U) == 0x1U) {\n\t\t\tcortex_a->cp15_control_reg_curr &= ~0x1U;\n\t\t\tneed_write = 1;\n\t\t}\n\t}\n\n\tif (need_write) {\n\t\tLOG_DEBUG(\"%s, writing cp15 ctrl: %\" PRIx32,\n\t\t\tenable ? \"enable mmu\" : \"disable mmu\",\n\t\t\tcortex_a->cp15_control_reg_curr);\n\n\t\tretval = armv7a->arm.mcr(target, 15,\n\t\t\t\t0, 0,\t/* op1, op2 */\n\t\t\t\t1, 0,\t/* CRn, CRm */\n\t\t\t\tcortex_a->cp15_control_reg_curr);\n\t}\n\treturn retval;\n}\n\n/*\n * Cortex-A Basic debug access, very low level assumes state is saved\n */\nstatic int cortex_a_init_debug_access(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tuint32_t dscr;\n\tint retval;\n\n\t/* lock memory-mapped access to debug registers to prevent\n\t * software interference */\n\tretval = mem_ap_write_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_LOCKACCESS, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Disable cacheline fills and force cache write-through in debug state */\n\tretval = mem_ap_write_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCCR, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Disable TLB lookup and refill/eviction in debug state */\n\tretval = mem_ap_write_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSMCR, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = dap_run(armv7a->debug_ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enabling of instruction execution in debug mode is done in debug_entry code */\n\n\t/* Resync breakpoint registers */\n\n\t/* Enable halt for breakpoint, watchpoint and vector catch */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr | DSCR_HALT_DBG_MODE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Since this is likely called from init or reset, update target state information*/\n\treturn cortex_a_poll(target);\n}\n\nstatic int cortex_a_wait_instrcmpl(struct target *target, uint32_t *dscr, bool force)\n{\n\t/* Waits until InstrCmpl_l becomes 1, indicating instruction is done.\n\t * Writes final value of DSCR into *dscr. Pass force to force always\n\t * reading DSCR at least once. */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval;\n\n\tif (force) {\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DSCR register\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_INSTR_COMP, DSCR_INSTR_COMP, dscr);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Error waiting for InstrCompl=1\");\n\treturn retval;\n}\n\n/* To reduce needless round-trips, pass in a pointer to the current\n * DSCR value.  Initialize it to zero if you just need to know the\n * value on return from this function; or DSCR_INSTR_COMP if you\n * happen to know that no instruction is pending.\n */\nstatic int cortex_a_exec_opcode(struct target *target,\n\tuint32_t opcode, uint32_t *dscr_p)\n{\n\tuint32_t dscr;\n\tint retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tdscr = dscr_p ? *dscr_p : 0;\n\n\tLOG_DEBUG(\"exec opcode 0x%08\" PRIx32, opcode);\n\n\t/* Wait for InstrCompl bit to be set */\n\tretval = cortex_a_wait_instrcmpl(target, dscr_p, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mem_ap_write_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_ITR, opcode);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait for InstrCompl bit to be set */\n\tretval = cortex_a_wait_instrcmpl(target, &dscr, true);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error waiting for cortex_a_exec_opcode\");\n\t\treturn retval;\n\t}\n\n\tif (dscr_p)\n\t\t*dscr_p = dscr;\n\n\treturn retval;\n}\n\n/* Write to memory mapped registers directly with no cache or mmu handling */\nstatic int cortex_a_dap_write_memap_register_u32(struct target *target,\n\tuint32_t address,\n\tuint32_t value)\n{\n\tint retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap, address, value);\n\n\treturn retval;\n}\n\n/*\n * Cortex-A implementation of Debug Programmer's Model\n *\n * NOTE the invariant:  these routines return with DSCR_INSTR_COMP set,\n * so there's no need to poll for it before executing an instruction.\n *\n * NOTE that in several of these cases the \"stall\" mode might be useful.\n * It'd let us queue a few operations together... prepare/finish might\n * be the places to enable/disable that mode.\n */\n\nstatic inline struct cortex_a_common *dpm_to_a(struct arm_dpm *dpm)\n{\n\treturn container_of(dpm, struct cortex_a_common, armv7a_common.dpm);\n}\n\nstatic int cortex_a_write_dcc(struct cortex_a_common *a, uint32_t data)\n{\n\tLOG_DEBUG(\"write DCC 0x%08\" PRIx32, data);\n\treturn mem_ap_write_u32(a->armv7a_common.debug_ap,\n\t\t\ta->armv7a_common.debug_base + CPUDBG_DTRRX, data);\n}\n\nstatic int cortex_a_read_dcc(struct cortex_a_common *a, uint32_t *data,\n\tuint32_t *dscr_p)\n{\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\tint retval;\n\n\tif (dscr_p)\n\t\tdscr = *dscr_p;\n\n\t/* Wait for DTRRXfull */\n\tretval = cortex_a_wait_dscr_bits(a->armv7a_common.arm.target,\n\t\t\tDSCR_DTR_TX_FULL, DSCR_DTR_TX_FULL, &dscr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error waiting for read dcc\");\n\t\treturn retval;\n\t}\n\n\tretval = mem_ap_read_atomic_u32(a->armv7a_common.debug_ap,\n\t\t\ta->armv7a_common.debug_base + CPUDBG_DTRTX, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t/* LOG_DEBUG(\"read DCC 0x%08\" PRIx32, *data); */\n\n\tif (dscr_p)\n\t\t*dscr_p = dscr;\n\n\treturn retval;\n}\n\nstatic int cortex_a_dpm_prepare(struct arm_dpm *dpm)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t dscr;\n\tint retval;\n\n\t/* set up invariant:  INSTR_COMP is set after ever DPM operation */\n\tretval = cortex_a_wait_instrcmpl(dpm->arm->target, &dscr, true);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error waiting for dpm prepare\");\n\t\treturn retval;\n\t}\n\n\t/* this \"should never happen\" ... */\n\tif (dscr & DSCR_DTR_RX_FULL) {\n\t\tLOG_ERROR(\"DSCR_DTR_RX_FULL, dscr 0x%08\" PRIx32, dscr);\n\t\t/* Clear DCCRX */\n\t\tretval = cortex_a_exec_opcode(\n\t\t\t\ta->armv7a_common.arm.target,\n\t\t\t\tARMV4_5_MRC(14, 0, 0, 0, 5, 0),\n\t\t\t\t&dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int cortex_a_dpm_finish(struct arm_dpm *dpm)\n{\n\t/* REVISIT what could be done here? */\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_instr_write_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tint retval;\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\n\tretval = cortex_a_write_dcc(a, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\topcode,\n\t\t\t&dscr);\n}\n\nstatic int cortex_a_instr_write_data_rt_dcc(struct arm_dpm *dpm,\n\tuint8_t rt, uint32_t data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\tint retval;\n\n\tif (rt > 15)\n\t\treturn ERROR_TARGET_INVALID;\n\n\tretval = cortex_a_write_dcc(a, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* DCCRX to Rt, \"MCR p14, 0, R0, c0, c5, 0\", 0xEE000E15 */\n\treturn cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\tARMV4_5_MRC(14, 0, rt, 0, 5, 0),\n\t\t\t&dscr);\n}\n\nstatic int cortex_a_instr_write_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\tint retval;\n\n\tretval = cortex_a_instr_write_data_rt_dcc(dpm, 0, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* then the opcode, taking data from R0 */\n\tretval = cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\topcode,\n\t\t\t&dscr);\n\n\treturn retval;\n}\n\nstatic int cortex_a_instr_cpsr_sync(struct arm_dpm *dpm)\n{\n\tstruct target *target = dpm->arm->target;\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\n\t/* \"Prefetch flush\" after modifying execution status in CPSR */\n\treturn cortex_a_exec_opcode(target,\n\t\t\tARMV4_5_MCR(15, 0, 0, 7, 5, 4),\n\t\t\t&dscr);\n}\n\nstatic int cortex_a_instr_read_data_dcc(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tint retval;\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\n\t/* the opcode, writing data to DCC */\n\tretval = cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\topcode,\n\t\t\t&dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn cortex_a_read_dcc(a, data, &dscr);\n}\n\nstatic int cortex_a_instr_read_data_rt_dcc(struct arm_dpm *dpm,\n\tuint8_t rt, uint32_t *data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\tint retval;\n\n\tif (rt > 15)\n\t\treturn ERROR_TARGET_INVALID;\n\n\tretval = cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\tARMV4_5_MCR(14, 0, rt, 0, 5, 0),\n\t\t\t&dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn cortex_a_read_dcc(a, data, &dscr);\n}\n\nstatic int cortex_a_instr_read_data_r0(struct arm_dpm *dpm,\n\tuint32_t opcode, uint32_t *data)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t dscr = DSCR_INSTR_COMP;\n\tint retval;\n\n\t/* the opcode, writing data to R0 */\n\tretval = cortex_a_exec_opcode(\n\t\t\ta->armv7a_common.arm.target,\n\t\t\topcode,\n\t\t\t&dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* write R0 to DCC */\n\treturn cortex_a_instr_read_data_rt_dcc(dpm, 0, data);\n}\n\nstatic int cortex_a_bpwp_enable(struct arm_dpm *dpm, unsigned index_t,\n\tuint32_t addr, uint32_t control)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t vr = a->armv7a_common.debug_base;\n\tuint32_t cr = a->armv7a_common.debug_base;\n\tint retval;\n\n\tswitch (index_t) {\n\t\tcase 0 ... 15:\t/* breakpoints */\n\t\t\tvr += CPUDBG_BVR_BASE;\n\t\t\tcr += CPUDBG_BCR_BASE;\n\t\t\tbreak;\n\t\tcase 16 ... 31:\t/* watchpoints */\n\t\t\tvr += CPUDBG_WVR_BASE;\n\t\t\tcr += CPUDBG_WCR_BASE;\n\t\t\tindex_t -= 16;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\tvr += 4 * index_t;\n\tcr += 4 * index_t;\n\n\tLOG_DEBUG(\"A: bpwp enable, vr %08x cr %08x\",\n\t\t(unsigned) vr, (unsigned) cr);\n\n\tretval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,\n\t\t\tvr, addr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_dap_write_memap_register_u32(dpm->arm->target,\n\t\t\tcr, control);\n\treturn retval;\n}\n\nstatic int cortex_a_bpwp_disable(struct arm_dpm *dpm, unsigned index_t)\n{\n\tstruct cortex_a_common *a = dpm_to_a(dpm);\n\tuint32_t cr;\n\n\tswitch (index_t) {\n\t\tcase 0 ... 15:\n\t\t\tcr = a->armv7a_common.debug_base + CPUDBG_BCR_BASE;\n\t\t\tbreak;\n\t\tcase 16 ... 31:\n\t\t\tcr = a->armv7a_common.debug_base + CPUDBG_WCR_BASE;\n\t\t\tindex_t -= 16;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_FAIL;\n\t}\n\tcr += 4 * index_t;\n\n\tLOG_DEBUG(\"A: bpwp disable, cr %08x\", (unsigned) cr);\n\n\t/* clear control register */\n\treturn cortex_a_dap_write_memap_register_u32(dpm->arm->target, cr, 0);\n}\n\nstatic int cortex_a_dpm_setup(struct cortex_a_common *a, uint32_t didr)\n{\n\tstruct arm_dpm *dpm = &a->armv7a_common.dpm;\n\tint retval;\n\n\tdpm->arm = &a->armv7a_common.arm;\n\tdpm->didr = didr;\n\n\tdpm->prepare = cortex_a_dpm_prepare;\n\tdpm->finish = cortex_a_dpm_finish;\n\n\tdpm->instr_write_data_dcc = cortex_a_instr_write_data_dcc;\n\tdpm->instr_write_data_r0 = cortex_a_instr_write_data_r0;\n\tdpm->instr_cpsr_sync = cortex_a_instr_cpsr_sync;\n\n\tdpm->instr_read_data_dcc = cortex_a_instr_read_data_dcc;\n\tdpm->instr_read_data_r0 = cortex_a_instr_read_data_r0;\n\n\tdpm->bpwp_enable = cortex_a_bpwp_enable;\n\tdpm->bpwp_disable = cortex_a_bpwp_disable;\n\n\tretval = arm_dpm_setup(dpm);\n\tif (retval == ERROR_OK)\n\t\tretval = arm_dpm_initialize(dpm);\n\n\treturn retval;\n}\nstatic struct target *get_cortex_a(struct target *target, int32_t coreid)\n{\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))\n\t\t\treturn curr;\n\t}\n\treturn target;\n}\nstatic int cortex_a_halt(struct target *target);\n\nstatic int cortex_a_halt_smp(struct target *target)\n{\n\tint retval = 0;\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif ((curr != target) && (curr->state != TARGET_HALTED)\n\t\t\t&& target_was_examined(curr))\n\t\t\tretval += cortex_a_halt(curr);\n\t}\n\treturn retval;\n}\n\nstatic int update_halt_gdb(struct target *target)\n{\n\tstruct target *gdb_target = NULL;\n\tstruct target_list *head;\n\tstruct target *curr;\n\tint retval = 0;\n\n\tif (target->gdb_service && target->gdb_service->core[0] == -1) {\n\t\ttarget->gdb_service->target = target;\n\t\ttarget->gdb_service->core[0] = target->coreid;\n\t\tretval += cortex_a_halt_smp(target);\n\t}\n\n\tif (target->gdb_service)\n\t\tgdb_target = target->gdb_service->target;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tcurr = head->target;\n\t\t/* skip calling context */\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\t/* skip targets that were already halted */\n\t\tif (curr->state == TARGET_HALTED)\n\t\t\tcontinue;\n\t\t/* Skip gdb_target; it alerts GDB so has to be polled as last one */\n\t\tif (curr == gdb_target)\n\t\t\tcontinue;\n\n\t\t/* avoid recursion in cortex_a_poll() */\n\t\tcurr->smp = 0;\n\t\tcortex_a_poll(curr);\n\t\tcurr->smp = 1;\n\t}\n\n\t/* after all targets were updated, poll the gdb serving target */\n\tif (gdb_target && gdb_target != target)\n\t\tcortex_a_poll(gdb_target);\n\treturn retval;\n}\n\n/*\n * Cortex-A Run control\n */\n\nstatic int cortex_a_poll(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tuint32_t dscr;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tenum target_state prev_target_state = target->state;\n\t/*  toggle to another core is done by gdb as follow */\n\t/*  maint packet J core_id */\n\t/*  continue */\n\t/*  the next polling trigger an halt event sent to gdb */\n\tif ((target->state == TARGET_HALTED) && (target->smp) &&\n\t\t(target->gdb_service) &&\n\t\t(!target->gdb_service->target)) {\n\t\ttarget->gdb_service->target =\n\t\t\tget_cortex_a(target, target->gdb_service->core[1]);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\treturn retval;\n\t}\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcortex_a->cpudbg_dscr = dscr;\n\n\tif (DSCR_RUN_MODE(dscr) == (DSCR_CORE_HALTED | DSCR_CORE_RESTARTED)) {\n\t\tif (prev_target_state != TARGET_HALTED) {\n\t\t\t/* We have a halting debug event */\n\t\t\tLOG_DEBUG(\"Target halted\");\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = cortex_a_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (target->smp) {\n\t\t\t\tretval = update_halt_gdb(target);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tif (prev_target_state == TARGET_DEBUG_RUNNING) {\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t\t} else { /* prev_target_state is RUNNING, UNKNOWN or RESET */\n\t\t\t\tif (arm_semihosting(target, &retval) != 0)\n\t\t\t\t\treturn retval;\n\n\t\t\t\ttarget_call_event_callbacks(target,\n\t\t\t\t\tTARGET_EVENT_HALTED);\n\t\t\t}\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n\n\treturn retval;\n}\n\nstatic int cortex_a_halt(struct target *target)\n{\n\tint retval;\n\tuint32_t dscr;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\t/*\n\t * Tell the core to be halted by writing DRCR with 0x1\n\t * and then wait for the core to be halted.\n\t */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_HALT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdscr = 0; /* force read of dscr */\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_CORE_HALTED,\n\t\t\tDSCR_CORE_HALTED, &dscr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error waiting for halt\");\n\t\treturn retval;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_internal_restore(struct target *target, int current,\n\ttarget_addr_t *address, int handle_breakpoints, int debug_execution)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tint retval;\n\tuint32_t resume_pc;\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n#if 0\n\tif (debug_execution) {\n\t\t/* Disable interrupts */\n\t\t/* We disable interrupts in the PRIMASK register instead of\n\t\t * masking with C_MASKINTS,\n\t\t * This is probably the same issue as Cortex-M3 Errata 377493:\n\t\t * C_MASKINTS in parallel with disabled interrupts can cause\n\t\t * local faults to not be taken. */\n\t\tbuf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);\n\t\tarmv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = true;\n\t\tarmv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = true;\n\n\t\t/* Make sure we are in Thumb mode */\n\t\tbuf_set_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0, 32,\n\t\t\tbuf_get_u32(armv7m->core_cache->reg_list[ARMV7M_XPSR].value, 0,\n\t\t\t32) | (1 << 24));\n\t\tarmv7m->core_cache->reg_list[ARMV7M_XPSR].dirty = true;\n\t\tarmv7m->core_cache->reg_list[ARMV7M_XPSR].valid = true;\n\t}\n#endif\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tresume_pc = buf_get_u32(arm->pc->value, 0, 32);\n\tif (!current)\n\t\tresume_pc = *address;\n\telse\n\t\t*address = resume_pc;\n\n\t/* Make sure that the Armv7 gdb thumb fixups does not\n\t * kill the return address\n\t */\n\tswitch (arm->core_state) {\n\t\tcase ARM_STATE_ARM:\n\t\t\tresume_pc &= 0xFFFFFFFC;\n\t\t\tbreak;\n\t\tcase ARM_STATE_THUMB:\n\t\tcase ARM_STATE_THUMB_EE:\n\t\t\t/* When the return address is loaded into PC\n\t\t\t * bit 0 must be 1 to stay in Thumb state\n\t\t\t */\n\t\t\tresume_pc |= 0x1;\n\t\t\tbreak;\n\t\tcase ARM_STATE_JAZELLE:\n\t\t\tLOG_ERROR(\"How do I resume into Jazelle state??\");\n\t\t\treturn ERROR_FAIL;\n\t\tcase ARM_STATE_AARCH64:\n\t\t\tLOG_ERROR(\"Shouldn't be in AARCH64 state\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"resume pc = 0x%08\" PRIx32, resume_pc);\n\tbuf_set_u32(arm->pc->value, 0, 32, resume_pc);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\n\t/* restore dpm_mode at system halt */\n\tarm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);\n\t/* called it now before restoring context because it uses cpu\n\t * register r0 for restoring cp15 control register */\n\tretval = cortex_a_restore_cp15_control_reg(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_restore_context(target, handle_breakpoints);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\ttarget->state = TARGET_RUNNING;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arm->core_cache);\n\n#if 0\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at 0x%8.8x\", breakpoint->address);\n\t\t\tcortex_m3_unset_breakpoint(target, breakpoint);\n\t\t\tcortex_m3_single_step_core(target);\n\t\t\tcortex_m3_set_breakpoint(target, breakpoint);\n\t\t}\n\t}\n\n#endif\n\treturn retval;\n}\n\nstatic int cortex_a_internal_restart(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tint retval;\n\tuint32_t dscr;\n\t/*\n\t * * Restart core and wait for it to be started.  Clear ITRen and sticky\n\t * * exception flags: see ARMv7 ARM, C5.9.\n\t *\n\t * REVISIT: for single stepping, we probably want to\n\t * disable IRQs by default, with optional override...\n\t */\n\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif ((dscr & DSCR_INSTR_COMP) == 0)\n\t\tLOG_ERROR(\"DSCR InstrCompl must be set before leaving debug!\");\n\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr & ~DSCR_ITR_EN);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_RESTART |\n\t\t\tDRCR_CLEAR_EXCEPTIONS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdscr = 0; /* force read of dscr */\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_CORE_RESTARTED,\n\t\t\tDSCR_CORE_RESTARTED, &dscr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error waiting for resume\");\n\t\treturn retval;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\ttarget->state = TARGET_RUNNING;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arm->core_cache);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_restore_smp(struct target *target, int handle_breakpoints)\n{\n\tint retval = 0;\n\tstruct target_list *head;\n\ttarget_addr_t address;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif ((curr != target) && (curr->state != TARGET_RUNNING)\n\t\t\t&& target_was_examined(curr)) {\n\t\t\t/*  resume current address , not in step mode */\n\t\t\tretval += cortex_a_internal_restore(curr, 1, &address,\n\t\t\t\t\thandle_breakpoints, 0);\n\t\t\tretval += cortex_a_internal_restart(curr);\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int cortex_a_resume(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tint retval = 0;\n\t/* dummy resume for smp toggle in order to reduce gdb impact  */\n\tif ((target->smp) && (target->gdb_service->core[1] != -1)) {\n\t\t/*   simulate a start and halt of target */\n\t\ttarget->gdb_service->target = NULL;\n\t\ttarget->gdb_service->core[0] = target->gdb_service->core[1];\n\t\t/*  fake resume at next poll we play the  target core[1], see poll*/\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\treturn 0;\n\t}\n\tcortex_a_internal_restore(target, current, &address, handle_breakpoints, debug_execution);\n\tif (target->smp) {\n\t\ttarget->gdb_service->core[0] = -1;\n\t\tretval = cortex_a_restore_smp(target, handle_breakpoints);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tcortex_a_internal_restart(target);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"target resumed at \" TARGET_ADDR_FMT, address);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"target debug resumed at \" TARGET_ADDR_FMT, address);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_debug_entry(struct target *target)\n{\n\tuint32_t dscr;\n\tint retval = ERROR_OK;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\n\tLOG_DEBUG(\"dscr = 0x%08\" PRIx32, cortex_a->cpudbg_dscr);\n\n\t/* REVISIT surely we should not re-read DSCR !! */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* REVISIT see A TRM 12.11.4 steps 2..3 -- make sure that any\n\t * imprecise data aborts get discarded by issuing a Data\n\t * Synchronization Barrier:  ARMV4_5_MCR(15, 0, 0, 7, 10, 4).\n\t */\n\n\t/* Enable the ITR execution once we are in debug mode */\n\tdscr |= DSCR_ITR_EN;\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Examine debug reason */\n\tarm_dpm_report_dscr(&armv7a->dpm, cortex_a->cpudbg_dscr);\n\n\t/* save address of instruction that triggered the watchpoint? */\n\tif (target->debug_reason == DBG_REASON_WATCHPOINT) {\n\t\tuint32_t wfar;\n\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_WFAR,\n\t\t\t\t&wfar);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tarm_dpm_report_wfar(&armv7a->dpm, wfar);\n\t}\n\n\t/* First load register accessible through core debug port */\n\tretval = arm_dpm_read_current_registers(&armv7a->dpm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (arm->spsr) {\n\t\t/* read SPSR */\n\t\tretval = arm_dpm_read_reg(&armv7a->dpm, arm->spsr, 17);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n#if 0\n/* TODO, Move this */\n\tuint32_t cp15_control_register, cp15_cacr, cp15_nacr;\n\tcortex_a_read_cp(target, &cp15_control_register, 15, 0, 1, 0, 0);\n\tLOG_DEBUG(\"cp15_control_register = 0x%08x\", cp15_control_register);\n\n\tcortex_a_read_cp(target, &cp15_cacr, 15, 0, 1, 0, 2);\n\tLOG_DEBUG(\"cp15 Coprocessor Access Control Register = 0x%08x\", cp15_cacr);\n\n\tcortex_a_read_cp(target, &cp15_nacr, 15, 0, 1, 1, 2);\n\tLOG_DEBUG(\"cp15 Nonsecure Access Control Register = 0x%08x\", cp15_nacr);\n#endif\n\n\t/* Are we in an exception handler */\n/*\tarmv4_5->exception_number = 0; */\n\tif (armv7a->post_debug_entry) {\n\t\tretval = armv7a->post_debug_entry(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn retval;\n}\n\nstatic int cortex_a_post_debug_entry(struct target *target)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tint retval;\n\n\t/* MRC p15,0,<Rt>,c1,c0,0 ; Read CP15 System Control Register */\n\tretval = armv7a->arm.mrc(target, 15,\n\t\t\t0, 0,\t/* op1, op2 */\n\t\t\t1, 0,\t/* CRn, CRm */\n\t\t\t&cortex_a->cp15_control_reg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"cp15_control_reg: %8.8\" PRIx32, cortex_a->cp15_control_reg);\n\tcortex_a->cp15_control_reg_curr = cortex_a->cp15_control_reg;\n\n\tif (!armv7a->is_armv7r)\n\t\tarmv7a_read_ttbcr(target);\n\n\tif (armv7a->armv7a_mmu.armv7a_cache.info == -1)\n\t\tarmv7a_identify_cache(target);\n\n\tif (armv7a->is_armv7r) {\n\t\tarmv7a->armv7a_mmu.mmu_enabled = 0;\n\t} else {\n\t\tarmv7a->armv7a_mmu.mmu_enabled =\n\t\t\t(cortex_a->cp15_control_reg & 0x1U) ? 1 : 0;\n\t}\n\tarmv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled =\n\t\t(cortex_a->cp15_control_reg & 0x4U) ? 1 : 0;\n\tarmv7a->armv7a_mmu.armv7a_cache.i_cache_enabled =\n\t\t(cortex_a->cp15_control_reg & 0x1000U) ? 1 : 0;\n\tcortex_a->curr_mode = armv7a->arm.core_mode;\n\n\t/* switch to SVC mode to read DACR */\n\tarm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_SVC);\n\tarmv7a->arm.mrc(target, 15,\n\t\t\t0, 0, 3, 0,\n\t\t\t&cortex_a->cp15_dacr_reg);\n\n\tLOG_DEBUG(\"cp15_dacr_reg: %8.8\" PRIx32,\n\t\t\tcortex_a->cp15_dacr_reg);\n\n\tarm_dpm_modeswitch(&armv7a->dpm, ARM_MODE_ANY);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_set_dscr_bits(struct target *target,\n\t\tunsigned long bit_mask, unsigned long value)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tuint32_t dscr;\n\n\t/* Read DSCR */\n\tint retval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* clear bitfield */\n\tdscr &= ~bit_mask;\n\t/* put new value */\n\tdscr |= value & bit_mask;\n\n\t/* write new DSCR */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr);\n\treturn retval;\n}\n\nstatic int cortex_a_step(struct target *target, int current, target_addr_t address,\n\tint handle_breakpoints)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tstruct breakpoint *breakpoint = NULL;\n\tstruct breakpoint stepbreakpoint;\n\tstruct reg *r;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tr = arm->pc;\n\tif (!current)\n\t\tbuf_set_u32(r->value, 0, 32, address);\n\telse\n\t\taddress = buf_get_u32(r->value, 0, 32);\n\n\t/* The front-end may request us not to handle breakpoints.\n\t * But since Cortex-A uses breakpoint for single step,\n\t * we MUST handle breakpoints.\n\t */\n\thandle_breakpoints = 1;\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target, address);\n\t\tif (breakpoint)\n\t\t\tcortex_a_unset_breakpoint(target, breakpoint);\n\t}\n\n\t/* Setup single step breakpoint */\n\tstepbreakpoint.address = address;\n\tstepbreakpoint.asid = 0;\n\tstepbreakpoint.length = (arm->core_state == ARM_STATE_THUMB)\n\t\t? 2 : 4;\n\tstepbreakpoint.type = BKPT_HARD;\n\tstepbreakpoint.is_set = false;\n\n\t/* Disable interrupts during single step if requested */\n\tif (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {\n\t\tretval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, DSCR_INT_DIS);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Break on IVA mismatch */\n\tcortex_a_set_breakpoint(target, &stepbreakpoint, 0x04);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tretval = cortex_a_resume(target, 1, address, 0, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint64_t then = timeval_ms();\n\twhile (target->state != TARGET_HALTED) {\n\t\tretval = cortex_a_poll(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (target->state == TARGET_HALTED)\n\t\t\tbreak;\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"timeout waiting for target halt\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcortex_a_unset_breakpoint(target, &stepbreakpoint);\n\n\t/* Re-enable interrupts if they were disabled */\n\tif (cortex_a->isrmasking_mode == CORTEX_A_ISRMASK_ON) {\n\t\tretval = cortex_a_set_dscr_bits(target, DSCR_INT_DIS, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\n\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\n\tif (breakpoint)\n\t\tcortex_a_set_breakpoint(target, breakpoint, 0);\n\n\tif (target->state != TARGET_HALTED)\n\t\tLOG_DEBUG(\"target stepped\");\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_restore_context(struct target *target, bool bpwp)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tLOG_DEBUG(\" \");\n\n\tif (armv7a->pre_restore_context)\n\t\tarmv7a->pre_restore_context(target);\n\n\treturn arm_dpm_write_dirty_registers(&armv7a->dpm, bpwp);\n}\n\n/*\n * Cortex-A Breakpoint and watchpoint functions\n */\n\n/* Setup hardware Breakpoint Register Pair */\nstatic int cortex_a_set_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode)\n{\n\tint retval;\n\tint brp_i = 0;\n\tuint32_t control;\n\tuint8_t byte_addr_select = 0x0F;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_brp *brp_list = cortex_a->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\twhile (brp_list[brp_i].used && (brp_i < cortex_a->brp_num))\n\t\t\tbrp_i++;\n\t\tif (brp_i >= cortex_a->brp_num) {\n\t\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint_hw_set(breakpoint, brp_i);\n\t\tif (breakpoint->length == 2)\n\t\t\tbyte_addr_select = (3 << (breakpoint->address & 0x02));\n\t\tcontrol = ((matchmode & 0x7) << 20)\n\t\t\t| (byte_addr_select << 5)\n\t\t\t| (3 << 1) | 1;\n\t\tbrp_list[brp_i].used = true;\n\t\tbrp_list[brp_i].value = (breakpoint->address & 0xFFFFFFFC);\n\t\tbrp_list[brp_i].control = control;\n\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\tbrp_list[brp_i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\tbrp_list[brp_i].control);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"brp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, brp_i,\n\t\t\tbrp_list[brp_i].control,\n\t\t\tbrp_list[brp_i].value);\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tuint8_t code[4];\n\t\t/* length == 2: Thumb breakpoint */\n\t\tif (breakpoint->length == 2)\n\t\t\tbuf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));\n\t\telse\n\t\t/* length == 3: Thumb-2 breakpoint, actual encoding is\n\t\t * a regular Thumb BKPT instruction but we replace a\n\t\t * 32bit Thumb-2 instruction, so fix-up the breakpoint\n\t\t * length\n\t\t */\n\t\tif (breakpoint->length == 3) {\n\t\t\tbuf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));\n\t\t\tbreakpoint->length = 4;\n\t\t} else\n\t\t\t/* length == 4, normal ARM breakpoint */\n\t\t\tbuf_set_u32(code, 0, 32, ARMV5_BKPT(0x11));\n\n\t\tretval = target_read_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\tbreakpoint->length, 1,\n\t\t\t\tbreakpoint->orig_instr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* make sure data cache is cleaned & invalidated down to PoC */\n\t\tif (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {\n\t\t\tarmv7a_cache_flush_virt(target, breakpoint->address,\n\t\t\t\t\t\tbreakpoint->length);\n\t\t}\n\n\t\tretval = target_write_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\tbreakpoint->length, 1, code);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* update i-cache at breakpoint location */\n\t\tarmv7a_l1_d_cache_inval_virt(target, breakpoint->address,\n\t\t\t\t\tbreakpoint->length);\n\t\tarmv7a_l1_i_cache_inval_virt(target, breakpoint->address,\n\t\t\t\t\t\t breakpoint->length);\n\n\t\tbreakpoint->is_set = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_set_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint, uint8_t matchmode)\n{\n\tint retval = ERROR_FAIL;\n\tint brp_i = 0;\n\tuint32_t control;\n\tuint8_t byte_addr_select = 0x0F;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_brp *brp_list = cortex_a->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn retval;\n\t}\n\t/*check available context BRPs*/\n\twhile ((brp_list[brp_i].used ||\n\t\t(brp_list[brp_i].type != BRP_CONTEXT)) && (brp_i < cortex_a->brp_num))\n\t\tbrp_i++;\n\n\tif (brp_i >= cortex_a->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbreakpoint_hw_set(breakpoint, brp_i);\n\tcontrol = ((matchmode & 0x7) << 20)\n\t\t| (byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_i].used = true;\n\tbrp_list[brp_i].value = (breakpoint->asid);\n\tbrp_list[brp_i].control = control;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\tbrp_list[brp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\tbrp_list[brp_i].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"brp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, brp_i,\n\t\tbrp_list[brp_i].control,\n\t\tbrp_list[brp_i].value);\n\treturn ERROR_OK;\n\n}\n\nstatic int cortex_a_set_hybrid_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval = ERROR_FAIL;\n\tint brp_1 = 0;\t/* holds the contextID pair */\n\tint brp_2 = 0;\t/* holds the IVA pair */\n\tuint32_t control_ctx, control_iva;\n\tuint8_t ctx_byte_addr_select = 0x0F;\n\tuint8_t iva_byte_addr_select = 0x0F;\n\tuint8_t ctx_machmode = 0x03;\n\tuint8_t iva_machmode = 0x01;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_brp *brp_list = cortex_a->brp_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn retval;\n\t}\n\t/*check available context BRPs*/\n\twhile ((brp_list[brp_1].used ||\n\t\t(brp_list[brp_1].type != BRP_CONTEXT)) && (brp_1 < cortex_a->brp_num))\n\t\tbrp_1++;\n\n\tLOG_DEBUG(\"brp(CTX) found num: %d\", brp_1);\n\tif (brp_1 >= cortex_a->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\twhile ((brp_list[brp_2].used ||\n\t\t(brp_list[brp_2].type != BRP_NORMAL)) && (brp_2 < cortex_a->brp_num))\n\t\tbrp_2++;\n\n\tLOG_DEBUG(\"brp(IVA) found num: %d\", brp_2);\n\tif (brp_2 >= cortex_a->brp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Breakpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tbreakpoint_hw_set(breakpoint, brp_1);\n\tbreakpoint->linked_brp = brp_2;\n\tcontrol_ctx = ((ctx_machmode & 0x7) << 20)\n\t\t| (brp_2 << 16)\n\t\t| (0 << 14)\n\t\t| (ctx_byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_1].used = true;\n\tbrp_list[brp_1].value = (breakpoint->asid);\n\tbrp_list[brp_1].control = control_ctx;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_1].brpn,\n\t\t\tbrp_list[brp_1].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_1].brpn,\n\t\t\tbrp_list[brp_1].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcontrol_iva = ((iva_machmode & 0x7) << 20)\n\t\t| (brp_1 << 16)\n\t\t| (iva_byte_addr_select << 5)\n\t\t| (3 << 1) | 1;\n\tbrp_list[brp_2].used = true;\n\tbrp_list[brp_2].value = (breakpoint->address & 0xFFFFFFFC);\n\tbrp_list[brp_2].control = control_iva;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_2].brpn,\n\t\t\tbrp_list[brp_2].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_2].brpn,\n\t\t\tbrp_list[brp_2].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_brp *brp_list = cortex_a->brp_list;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tif ((breakpoint->address != 0) && (breakpoint->asid != 0)) {\n\t\t\tint brp_i = breakpoint->number;\n\t\t\tint brp_j = breakpoint->linked_brp;\n\t\t\tif (brp_i >= cortex_a->brp_num) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, brp_i,\n\t\t\t\tbrp_list[brp_i].control, brp_list[brp_i].value);\n\t\t\tbrp_list[brp_i].used = false;\n\t\t\tbrp_list[brp_i].value = 0;\n\t\t\tbrp_list[brp_i].control = 0;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif ((brp_j < 0) || (brp_j >= cortex_a->brp_num)) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, brp_j,\n\t\t\t\tbrp_list[brp_j].control, brp_list[brp_j].value);\n\t\t\tbrp_list[brp_j].used = false;\n\t\t\tbrp_list[brp_j].value = 0;\n\t\t\tbrp_list[brp_j].control = 0;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_j].brpn,\n\t\t\t\t\tbrp_list[brp_j].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_j].brpn,\n\t\t\t\t\tbrp_list[brp_j].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreakpoint->linked_brp = 0;\n\t\t\tbreakpoint->is_set = false;\n\t\t\treturn ERROR_OK;\n\n\t\t} else {\n\t\t\tint brp_i = breakpoint->number;\n\t\t\tif (brp_i >= cortex_a->brp_num) {\n\t\t\t\tLOG_DEBUG(\"Invalid BRP number in breakpoint\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"rbp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, brp_i,\n\t\t\t\tbrp_list[brp_i].control, brp_list[brp_i].value);\n\t\t\tbrp_list[brp_i].used = false;\n\t\t\tbrp_list[brp_i].value = 0;\n\t\t\tbrp_list[brp_i].control = 0;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BCR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].control);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t\t\t+ CPUDBG_BVR_BASE + 4 * brp_list[brp_i].brpn,\n\t\t\t\t\tbrp_list[brp_i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreakpoint->is_set = false;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\n\t\t/* make sure data cache is cleaned & invalidated down to PoC */\n\t\tif (!armv7a->armv7a_mmu.armv7a_cache.auto_cache_enabled) {\n\t\t\tarmv7a_cache_flush_virt(target, breakpoint->address,\n\t\t\t\t\t\tbreakpoint->length);\n\t\t}\n\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tif (breakpoint->length == 4) {\n\t\t\tretval = target_write_memory(target,\n\t\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\t\t4, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tretval = target_write_memory(target,\n\t\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\t\t2, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\n\t\t/* update i-cache at breakpoint location */\n\t\tarmv7a_l1_d_cache_inval_virt(target, breakpoint->address,\n\t\t\t\t\t\t breakpoint->length);\n\t\tarmv7a_l1_i_cache_inval_virt(target, breakpoint->address,\n\t\t\t\t\t\t breakpoint->length);\n\t}\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_add_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tcortex_a->brp_num_available--;\n\n\treturn cortex_a_set_breakpoint(target, breakpoint, 0x00);\t/* Exact match */\n}\n\nstatic int cortex_a_add_context_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tcortex_a->brp_num_available--;\n\n\treturn cortex_a_set_context_breakpoint(target, breakpoint, 0x02);\t/* asid match */\n}\n\nstatic int cortex_a_add_hybrid_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (cortex_a->brp_num_available < 1)) {\n\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tcortex_a->brp_num_available--;\n\n\treturn cortex_a_set_hybrid_breakpoint(target, breakpoint);\t/* ??? */\n}\n\n\nstatic int cortex_a_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n#if 0\n/* It is perfectly possible to remove breakpoints while the target is running */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n#endif\n\n\tif (breakpoint->is_set) {\n\t\tcortex_a_unset_breakpoint(target, breakpoint);\n\t\tif (breakpoint->type == BKPT_HARD)\n\t\t\tcortex_a->brp_num_available++;\n\t}\n\n\n\treturn ERROR_OK;\n}\n\n/**\n * Sets a watchpoint for an Cortex-A target in one of the watchpoint units.  It is\n * considered a bug to call this function when there are no available watchpoint\n * units.\n *\n * @param target Pointer to an Cortex-A target to set a watchpoint on\n * @param watchpoint Pointer to the watchpoint to be set\n * @return Error status if watchpoint set fails or the result of executing the\n * JTAG queue\n */\nstatic int cortex_a_set_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tint retval = ERROR_OK;\n\tint wrp_i = 0;\n\tuint32_t control;\n\tuint32_t address;\n\tuint8_t address_mask;\n\tuint8_t byte_address_select;\n\tuint8_t load_store_access_control = 0x3;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_wrp *wrp_list = cortex_a->wrp_list;\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn retval;\n\t}\n\n\t/* check available context WRPs */\n\twhile (wrp_list[wrp_i].used && (wrp_i < cortex_a->wrp_num))\n\t\twrp_i++;\n\n\tif (wrp_i >= cortex_a->wrp_num) {\n\t\tLOG_ERROR(\"ERROR Can not find free Watchpoint Register Pair\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (watchpoint->length == 0 || watchpoint->length > 0x80000000U ||\n\t\t\t(watchpoint->length & (watchpoint->length - 1))) {\n\t\tLOG_WARNING(\"watchpoint length must be a power of 2\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (watchpoint->address & (watchpoint->length - 1)) {\n\t\tLOG_WARNING(\"watchpoint address must be aligned at length\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* FIXME: ARM DDI 0406C: address_mask is optional. What to do if it's missing?  */\n\t/* handle wp length 1 and 2 through byte select */\n\tswitch (watchpoint->length) {\n\tcase 1:\n\t\tbyte_address_select = BIT(watchpoint->address & 0x3);\n\t\taddress = watchpoint->address & ~0x3;\n\t\taddress_mask = 0;\n\t\tbreak;\n\n\tcase 2:\n\t\tbyte_address_select = 0x03 << (watchpoint->address & 0x2);\n\t\taddress = watchpoint->address & ~0x3;\n\t\taddress_mask = 0;\n\t\tbreak;\n\n\tcase 4:\n\t\tbyte_address_select = 0x0f;\n\t\taddress = watchpoint->address;\n\t\taddress_mask = 0;\n\t\tbreak;\n\n\tdefault:\n\t\tbyte_address_select = 0xff;\n\t\taddress = watchpoint->address;\n\t\taddress_mask = ilog2(watchpoint->length);\n\t\tbreak;\n\t}\n\n\twatchpoint_set(watchpoint, wrp_i);\n\tcontrol = (address_mask << 24) |\n\t\t(byte_address_select << 5) |\n\t\t(load_store_access_control << 3) |\n\t\t(0x3 << 1) | 1;\n\twrp_list[wrp_i].used = true;\n\twrp_list[wrp_i].value = address;\n\twrp_list[wrp_i].control = control;\n\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,\n\t\t\twrp_list[wrp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,\n\t\t\twrp_list[wrp_i].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"wp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, wrp_i,\n\t\t\twrp_list[wrp_i].control,\n\t\t\twrp_list[wrp_i].value);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Unset an existing watchpoint and clear the used watchpoint unit.\n *\n * @param target Pointer to the target to have the watchpoint removed\n * @param watchpoint Pointer to the watchpoint to be removed\n * @return Error status while trying to unset the watchpoint or the result of\n *         executing the JTAG queue\n */\nstatic int cortex_a_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tint retval;\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct cortex_a_wrp *wrp_list = cortex_a->wrp_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wrp_i = watchpoint->number;\n\tif (wrp_i >= cortex_a->wrp_num) {\n\t\tLOG_DEBUG(\"Invalid WRP number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tLOG_DEBUG(\"wrp %i control 0x%0\" PRIx32 \" value 0x%0\" PRIx32, wrp_i,\n\t\t\twrp_list[wrp_i].control, wrp_list[wrp_i].value);\n\twrp_list[wrp_i].used = false;\n\twrp_list[wrp_i].value = 0;\n\twrp_list[wrp_i].control = 0;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_WCR_BASE + 4 * wrp_list[wrp_i].wrpn,\n\t\t\twrp_list[wrp_i].control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_dap_write_memap_register_u32(target, armv7a->debug_base\n\t\t\t+ CPUDBG_WVR_BASE + 4 * wrp_list[wrp_i].wrpn,\n\t\t\twrp_list[wrp_i].value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Add a watchpoint to an Cortex-A target.  If there are no watchpoint units\n * available, an error response is returned.\n *\n * @param target Pointer to the Cortex-A target to add a watchpoint to\n * @param watchpoint Pointer to the watchpoint to be added\n * @return Error status while trying to add the watchpoint\n */\nstatic int cortex_a_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif (cortex_a->wrp_num_available < 1) {\n\t\tLOG_INFO(\"no hardware watchpoint available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tint retval = cortex_a_set_watchpoint(target, watchpoint);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcortex_a->wrp_num_available--;\n\treturn ERROR_OK;\n}\n\n/**\n * Remove a watchpoint from an Cortex-A target.  The watchpoint will be unset and\n * the used watchpoint unit will be reopened.\n *\n * @param target Pointer to the target to remove a watchpoint from\n * @param watchpoint Pointer to the watchpoint to be removed\n * @return Result of trying to unset the watchpoint\n */\nstatic int cortex_a_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tif (watchpoint->is_set) {\n\t\tcortex_a->wrp_num_available++;\n\t\tcortex_a_unset_watchpoint(target, watchpoint);\n\t}\n\treturn ERROR_OK;\n}\n\n\n/*\n * Cortex-A Reset functions\n */\n\nstatic int cortex_a_assert_reset(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tLOG_DEBUG(\" \");\n\n\t/* FIXME when halt is requested, make it work somehow... */\n\n\t/* This function can be called in \"target not examined\" state */\n\n\t/* Issue some kind of warm reset. */\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\telse if (jtag_get_reset_config() & RESET_HAS_SRST) {\n\t\t/* REVISIT handle \"pulls\" cases, if there's\n\t\t * hardware that needs them to work.\n\t\t */\n\n\t\t/*\n\t\t * FIXME: fix reset when transport is not JTAG. This is a temporary\n\t\t * work-around for release v0.10 that is not intended to stay!\n\t\t */\n\t\tif (!transport_is_jtag() ||\n\t\t\t\t(target->reset_halt && (jtag_get_reset_config() & RESET_SRST_NO_GATING)))\n\t\t\tadapter_assert_reset();\n\n\t} else {\n\t\tLOG_ERROR(\"%s: how to reset?\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* registers are now invalid */\n\tif (target_was_examined(target))\n\t\tregister_cache_invalidate(armv7a->arm.core_cache);\n\n\ttarget->state = TARGET_RESET;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_deassert_reset(struct target *target)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval;\n\n\tLOG_DEBUG(\" \");\n\n\t/* be certain SRST is off */\n\tadapter_deassert_reset();\n\n\tif (target_was_examined(target)) {\n\t\tretval = cortex_a_poll(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (target->reset_halt) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tLOG_WARNING(\"%s: ran after reset and before halt ...\",\n\t\t\t\ttarget_name(target));\n\t\t\tif (target_was_examined(target)) {\n\t\t\t\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_HALT);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else\n\t\t\t\ttarget->state = TARGET_UNKNOWN;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_set_dcc_mode(struct target *target, uint32_t mode, uint32_t *dscr)\n{\n\t/* Changes the mode of the DCC between non-blocking, stall, and fast mode.\n\t * New desired mode must be in mode. Current value of DSCR must be in\n\t * *dscr, which is updated with new value.\n\t *\n\t * This function elides actually sending the mode-change over the debug\n\t * interface if the mode is already set as desired.\n\t */\n\tuint32_t new_dscr = (*dscr & ~DSCR_EXT_DCC_MASK) | mode;\n\tif (new_dscr != *dscr) {\n\t\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\t\tint retval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, new_dscr);\n\t\tif (retval == ERROR_OK)\n\t\t\t*dscr = new_dscr;\n\t\treturn retval;\n\t} else {\n\t\treturn ERROR_OK;\n\t}\n}\n\nstatic int cortex_a_wait_dscr_bits(struct target *target, uint32_t mask,\n\tuint32_t value, uint32_t *dscr)\n{\n\t/* Waits until the specified bit(s) of DSCR take on a specified value. */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint64_t then;\n\tint retval;\n\n\tif ((*dscr & mask) == value)\n\t\treturn ERROR_OK;\n\n\tthen = timeval_ms();\n\twhile (1) {\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, dscr);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not read DSCR register\");\n\t\t\treturn retval;\n\t\t}\n\t\tif ((*dscr & mask) == value)\n\t\t\tbreak;\n\t\tif (timeval_ms() > then + 1000) {\n\t\t\tLOG_ERROR(\"timeout waiting for DSCR bit change\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_read_copro(struct target *target, uint32_t opcode,\n\tuint32_t *data, uint32_t *dscr)\n{\n\tint retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\t/* Move from coprocessor to R0. */\n\tretval = cortex_a_exec_opcode(target, opcode, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Move from R0 to DTRTX. */\n\tretval = cortex_a_exec_opcode(target, ARMV4_5_MCR(14, 0, 0, 0, 5, 0), dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait until DTRTX is full (according to ARMv7-A/-R architecture\n\t * manual section C8.4.3, checking InstrCmpl_l is not sufficient; one\n\t * must also check TXfull_l). Most of the time this will be free\n\t * because TXfull_l will be set immediately and cached in dscr. */\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED,\n\t\t\tDSCR_DTRTX_FULL_LATCHED, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read the value transferred to DTRTX. */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_read_dfar_dfsr(struct target *target, uint32_t *dfar,\n\tuint32_t *dfsr, uint32_t *dscr)\n{\n\tint retval;\n\n\tif (dfar) {\n\t\tretval = cortex_a_read_copro(target, ARMV4_5_MRC(15, 0, 0, 6, 0, 0), dfar, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (dfsr) {\n\t\tretval = cortex_a_read_copro(target, ARMV4_5_MRC(15, 0, 0, 5, 0, 0), dfsr, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_write_copro(struct target *target, uint32_t opcode,\n\tuint32_t data, uint32_t *dscr)\n{\n\tint retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\t/* Write the value into DTRRX. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DTRRX, data);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Move from DTRRX to R0. */\n\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Move from R0 to coprocessor. */\n\tretval = cortex_a_exec_opcode(target, opcode, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Wait until DTRRX is empty (according to ARMv7-A/-R architecture manual\n\t * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also\n\t * check RXfull_l). Most of the time this will be free because RXfull_l\n\t * will be cleared immediately and cached in dscr. */\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_write_dfar_dfsr(struct target *target, uint32_t dfar,\n\tuint32_t dfsr, uint32_t *dscr)\n{\n\tint retval;\n\n\tretval = cortex_a_write_copro(target, ARMV4_5_MCR(15, 0, 0, 6, 0, 0), dfar, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cortex_a_write_copro(target, ARMV4_5_MCR(15, 0, 0, 5, 0, 0), dfsr, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_dfsr_to_error_code(uint32_t dfsr)\n{\n\tuint32_t status, upper4;\n\n\tif (dfsr & (1 << 9)) {\n\t\t/* LPAE format. */\n\t\tstatus = dfsr & 0x3f;\n\t\tupper4 = status >> 2;\n\t\tif (upper4 == 1 || upper4 == 2 || upper4 == 3 || upper4 == 15)\n\t\t\treturn ERROR_TARGET_TRANSLATION_FAULT;\n\t\telse if (status == 33)\n\t\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t\telse\n\t\t\treturn ERROR_TARGET_DATA_ABORT;\n\t} else {\n\t\t/* Normal format. */\n\t\tstatus = ((dfsr >> 6) & 0x10) | (dfsr & 0xf);\n\t\tif (status == 1)\n\t\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t\telse if (status == 5 || status == 7 || status == 3 || status == 6 ||\n\t\t\t\tstatus == 9 || status == 11 || status == 13 || status == 15)\n\t\t\treturn ERROR_TARGET_TRANSLATION_FAULT;\n\t\telse\n\t\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n}\n\nstatic int cortex_a_write_cpu_memory_slow(struct target *target,\n\tuint32_t size, uint32_t count, const uint8_t *buffer, uint32_t *dscr)\n{\n\t/* Writes count objects of size size from *buffer. Old value of DSCR must\n\t * be in *dscr; updated to new value. This is slow because it works for\n\t * non-word-sized objects. Avoid unaligned accesses as they do not work\n\t * on memory address space without \"Normal\" attribute. If size == 4 and\n\t * the address is aligned, cortex_a_write_cpu_memory_fast should be\n\t * preferred.\n\t * Preconditions:\n\t * - Address is in R0.\n\t * - R0 is marked dirty.\n\t */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tint retval;\n\n\t/* Mark register R1 as dirty, to use for transferring data. */\n\tarm_reg_current(arm, 1)->dirty = true;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Go through the objects. */\n\twhile (count) {\n\t\t/* Write the value to store into DTRRX. */\n\t\tuint32_t data, opcode;\n\t\tif (size == 1)\n\t\t\tdata = *buffer;\n\t\telse if (size == 2)\n\t\t\tdata = target_buffer_get_u16(target, buffer);\n\t\telse\n\t\t\tdata = target_buffer_get_u32(target, buffer);\n\t\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DTRRX, data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Transfer the value from DTRRX to R1. */\n\t\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Write the value transferred to R1 into memory. */\n\t\tif (size == 1)\n\t\t\topcode = ARMV4_5_STRB_IP(1, 0);\n\t\telse if (size == 2)\n\t\t\topcode = ARMV4_5_STRH_IP(1, 0);\n\t\telse\n\t\t\topcode = ARMV4_5_STRW_IP(1, 0);\n\t\tretval = cortex_a_exec_opcode(target, opcode, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Check for faults and return early. */\n\t\tif (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE))\n\t\t\treturn ERROR_OK; /* A data fault is not considered a system failure. */\n\n\t\t/* Wait until DTRRX is empty (according to ARMv7-A/-R architecture\n\t\t * manual section C8.4.3, checking InstrCmpl_l is not sufficient; one\n\t\t * must also check RXfull_l). Most of the time this will be free\n\t\t * because RXfull_l will be cleared immediately and cached in dscr. */\n\t\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Advance. */\n\t\tbuffer += size;\n\t\t--count;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_write_cpu_memory_fast(struct target *target,\n\tuint32_t count, const uint8_t *buffer, uint32_t *dscr)\n{\n\t/* Writes count objects of size 4 from *buffer. Old value of DSCR must be\n\t * in *dscr; updated to new value. This is fast but only works for\n\t * word-sized objects at aligned addresses.\n\t * Preconditions:\n\t * - Address is in R0 and must be a multiple of 4.\n\t * - R0 is marked dirty.\n\t */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval;\n\n\t/* Switch to fast mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_FAST_MODE, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Latch STC instruction. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_ITR, ARMV4_5_STC(0, 1, 0, 1, 14, 5, 0, 4));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Transfer all the data and issue all the instructions. */\n\treturn mem_ap_write_buf_noincr(armv7a->debug_ap, buffer,\n\t\t\t4, count, armv7a->debug_base + CPUDBG_DTRRX);\n}\n\nstatic int cortex_a_write_cpu_memory(struct target *target,\n\tuint32_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\t/* Write memory through the CPU. */\n\tint retval, final_retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tuint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;\n\n\tLOG_DEBUG(\"Writing CPU memory address 0x%\" PRIx32 \" size %\"  PRIu32 \" count %\"  PRIu32,\n\t\t\t  address, size, count);\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!count)\n\t\treturn ERROR_OK;\n\n\t/* Clear any abort. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read DSCR. */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Mark R0 as dirty. */\n\tarm_reg_current(arm, 0)->dirty = true;\n\n\t/* Read DFAR and DFSR, as they will be modified in the event of a fault. */\n\tretval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Get the memory address into R0. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DTRRX, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 4 && (address % 4) == 0) {\n\t\t/* We are doing a word-aligned transfer, so use fast mode. */\n\t\tretval = cortex_a_write_cpu_memory_fast(target, count, buffer, &dscr);\n\t} else {\n\t\t/* Use slow path. Adjust size for aligned accesses */\n\t\tswitch (address % 4) {\n\t\t\tcase 1:\n\t\t\tcase 3:\n\t\t\t\tcount *= size;\n\t\t\t\tsize = 1;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (size == 4) {\n\t\t\t\t\tcount *= 2;\n\t\t\t\t\tsize = 2;\n\t\t\t\t}\n\t\t\tcase 0:\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\tretval = cortex_a_write_cpu_memory_slow(target, size, count, buffer, &dscr);\n\t}\n\n\tfinal_retval = retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);\n\tif (final_retval == ERROR_OK)\n\t\tfinal_retval = retval;\n\n\t/* Wait for last issued instruction to complete. */\n\tretval = cortex_a_wait_instrcmpl(target, &dscr, true);\n\tif (final_retval == ERROR_OK)\n\t\tfinal_retval = retval;\n\n\t/* Wait until DTRRX is empty (according to ARMv7-A/-R architecture manual\n\t * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also\n\t * check RXfull_l). Most of the time this will be free because RXfull_l\n\t * will be cleared immediately and cached in dscr. However, don't do this\n\t * if there is fault, because then the instruction might not have completed\n\t * successfully. */\n\tif (!(dscr & DSCR_STICKY_ABORT_PRECISE)) {\n\t\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRRX_FULL_LATCHED, 0, &dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* If there were any sticky abort flags, clear them. */\n\tif (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {\n\t\tfault_dscr = dscr;\n\t\tmem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);\n\t\tdscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE);\n\t} else {\n\t\tfault_dscr = 0;\n\t}\n\n\t/* Handle synchronous data faults. */\n\tif (fault_dscr & DSCR_STICKY_ABORT_PRECISE) {\n\t\tif (final_retval == ERROR_OK) {\n\t\t\t/* Final return value will reflect cause of fault. */\n\t\t\tretval = cortex_a_read_dfar_dfsr(target, &fault_dfar, &fault_dfsr, &dscr);\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"data abort at 0x%08\" PRIx32 \", dfsr = 0x%08\" PRIx32, fault_dfar, fault_dfsr);\n\t\t\t\tfinal_retval = cortex_a_dfsr_to_error_code(fault_dfsr);\n\t\t\t} else\n\t\t\t\tfinal_retval = retval;\n\t\t}\n\t\t/* Fault destroyed DFAR/DFSR; restore them. */\n\t\tretval = cortex_a_write_dfar_dfsr(target, orig_dfar, orig_dfsr, &dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"error restoring dfar/dfsr - dscr = 0x%08\" PRIx32, dscr);\n\t}\n\n\t/* Handle asynchronous data faults. */\n\tif (fault_dscr & DSCR_STICKY_ABORT_IMPRECISE) {\n\t\tif (final_retval == ERROR_OK)\n\t\t\t/* No other error has been recorded so far, so keep this one. */\n\t\t\tfinal_retval = ERROR_TARGET_DATA_ABORT;\n\t}\n\n\t/* If the DCC is nonempty, clear it. */\n\tif (dscr & DSCR_DTRTX_FULL_LATCHED) {\n\t\tuint32_t dummy;\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, &dummy);\n\t\tif (final_retval == ERROR_OK)\n\t\t\tfinal_retval = retval;\n\t}\n\tif (dscr & DSCR_DTRRX_FULL_LATCHED) {\n\t\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), &dscr);\n\t\tif (final_retval == ERROR_OK)\n\t\t\tfinal_retval = retval;\n\t}\n\n\t/* Done. */\n\treturn final_retval;\n}\n\nstatic int cortex_a_read_cpu_memory_slow(struct target *target,\n\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t *dscr)\n{\n\t/* Reads count objects of size size into *buffer. Old value of DSCR must be\n\t * in *dscr; updated to new value. This is slow because it works for\n\t * non-word-sized objects. Avoid unaligned accesses as they do not work\n\t * on memory address space without \"Normal\" attribute. If size == 4 and\n\t * the address is aligned, cortex_a_read_cpu_memory_fast should be\n\t * preferred.\n\t * Preconditions:\n\t * - Address is in R0.\n\t * - R0 is marked dirty.\n\t */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tint retval;\n\n\t/* Mark register R1 as dirty, to use for transferring data. */\n\tarm_reg_current(arm, 1)->dirty = true;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Go through the objects. */\n\twhile (count) {\n\t\t/* Issue a load of the appropriate size to R1. */\n\t\tuint32_t opcode, data;\n\t\tif (size == 1)\n\t\t\topcode = ARMV4_5_LDRB_IP(1, 0);\n\t\telse if (size == 2)\n\t\t\topcode = ARMV4_5_LDRH_IP(1, 0);\n\t\telse\n\t\t\topcode = ARMV4_5_LDRW_IP(1, 0);\n\t\tretval = cortex_a_exec_opcode(target, opcode, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Issue a write of R1 to DTRTX. */\n\t\tretval = cortex_a_exec_opcode(target, ARMV4_5_MCR(14, 0, 1, 0, 5, 0), dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Check for faults and return early. */\n\t\tif (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE))\n\t\t\treturn ERROR_OK; /* A data fault is not considered a system failure. */\n\n\t\t/* Wait until DTRTX is full (according to ARMv7-A/-R architecture\n\t\t * manual section C8.4.3, checking InstrCmpl_l is not sufficient; one\n\t\t * must also check TXfull_l). Most of the time this will be free\n\t\t * because TXfull_l will be set immediately and cached in dscr. */\n\t\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED,\n\t\t\t\tDSCR_DTRTX_FULL_LATCHED, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Read the value transferred to DTRTX into the buffer. */\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, &data);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (size == 1)\n\t\t\t*buffer = (uint8_t) data;\n\t\telse if (size == 2)\n\t\t\ttarget_buffer_set_u16(target, buffer, (uint16_t) data);\n\t\telse\n\t\t\ttarget_buffer_set_u32(target, buffer, data);\n\n\t\t/* Advance. */\n\t\tbuffer += size;\n\t\t--count;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_read_cpu_memory_fast(struct target *target,\n\tuint32_t count, uint8_t *buffer, uint32_t *dscr)\n{\n\t/* Reads count objects of size 4 into *buffer. Old value of DSCR must be in\n\t * *dscr; updated to new value. This is fast but only works for word-sized\n\t * objects at aligned addresses.\n\t * Preconditions:\n\t * - Address is in R0 and must be a multiple of 4.\n\t * - R0 is marked dirty.\n\t */\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tuint32_t u32;\n\tint retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Issue the LDC instruction via a write to ITR. */\n\tretval = cortex_a_exec_opcode(target, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4), dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcount--;\n\n\tif (count > 0) {\n\t\t/* Switch to fast mode if not already in that mode. */\n\t\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_FAST_MODE, dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Latch LDC instruction. */\n\t\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_ITR, ARMV4_5_LDC(0, 1, 0, 1, 14, 5, 0, 4));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Read the value transferred to DTRTX into the buffer. Due to fast\n\t\t * mode rules, this blocks until the instruction finishes executing and\n\t\t * then reissues the read instruction to read the next word from\n\t\t * memory. The last read of DTRTX in this call reads the second-to-last\n\t\t * word from memory and issues the read instruction for the last word.\n\t\t */\n\t\tretval = mem_ap_read_buf_noincr(armv7a->debug_ap, buffer,\n\t\t\t\t4, count, armv7a->debug_base + CPUDBG_DTRTX);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Advance. */\n\t\tbuffer += count * 4;\n\t}\n\n\t/* Wait for last issued instruction to complete. */\n\tretval = cortex_a_wait_instrcmpl(target, dscr, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Check for faults and return early. */\n\tif (*dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE))\n\t\treturn ERROR_OK; /* A data fault is not considered a system failure. */\n\n\t/* Wait until DTRTX is full (according to ARMv7-A/-R architecture manual\n\t * section C8.4.3, checking InstrCmpl_l is not sufficient; one must also\n\t * check TXfull_l). Most of the time this will be free because TXfull_l\n\t * will be set immediately and cached in dscr. */\n\tretval = cortex_a_wait_dscr_bits(target, DSCR_DTRTX_FULL_LATCHED,\n\t\t\tDSCR_DTRTX_FULL_LATCHED, dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read the value transferred to DTRTX into the buffer. This is the last\n\t * word. */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, &u32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget_buffer_set_u32(target, buffer, u32);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_read_cpu_memory(struct target *target,\n\tuint32_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\t/* Read memory through the CPU. */\n\tint retval, final_retval;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tstruct arm *arm = &armv7a->arm;\n\tuint32_t dscr, orig_dfar, orig_dfsr, fault_dscr, fault_dfar, fault_dfsr;\n\n\tLOG_DEBUG(\"Reading CPU memory address 0x%\" PRIx32 \" size %\"  PRIu32 \" count %\"  PRIu32,\n\t\t\t  address, size, count);\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!count)\n\t\treturn ERROR_OK;\n\n\t/* Clear any abort. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Read DSCR */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Mark R0 as dirty. */\n\tarm_reg_current(arm, 0)->dirty = true;\n\n\t/* Read DFAR and DFSR, as they will be modified in the event of a fault. */\n\tretval = cortex_a_read_dfar_dfsr(target, &orig_dfar, &orig_dfsr, &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Get the memory address into R0. */\n\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DTRRX, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 0, 0, 5, 0), &dscr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (size == 4 && (address % 4) == 0) {\n\t\t/* We are doing a word-aligned transfer, so use fast mode. */\n\t\tretval = cortex_a_read_cpu_memory_fast(target, count, buffer, &dscr);\n\t} else {\n\t\t/* Use slow path. Adjust size for aligned accesses */\n\t\tswitch (address % 4) {\n\t\t\tcase 1:\n\t\t\tcase 3:\n\t\t\t\tcount *= size;\n\t\t\t\tsize = 1;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (size == 4) {\n\t\t\t\t\tcount *= 2;\n\t\t\t\t\tsize = 2;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t\tretval = cortex_a_read_cpu_memory_slow(target, size, count, buffer, &dscr);\n\t}\n\n\tfinal_retval = retval;\n\n\t/* Switch to non-blocking mode if not already in that mode. */\n\tretval = cortex_a_set_dcc_mode(target, DSCR_EXT_DCC_NON_BLOCKING, &dscr);\n\tif (final_retval == ERROR_OK)\n\t\tfinal_retval = retval;\n\n\t/* Wait for last issued instruction to complete. */\n\tretval = cortex_a_wait_instrcmpl(target, &dscr, true);\n\tif (final_retval == ERROR_OK)\n\t\tfinal_retval = retval;\n\n\t/* If there were any sticky abort flags, clear them. */\n\tif (dscr & (DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE)) {\n\t\tfault_dscr = dscr;\n\t\tmem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DRCR, DRCR_CLEAR_EXCEPTIONS);\n\t\tdscr &= ~(DSCR_STICKY_ABORT_PRECISE | DSCR_STICKY_ABORT_IMPRECISE);\n\t} else {\n\t\tfault_dscr = 0;\n\t}\n\n\t/* Handle synchronous data faults. */\n\tif (fault_dscr & DSCR_STICKY_ABORT_PRECISE) {\n\t\tif (final_retval == ERROR_OK) {\n\t\t\t/* Final return value will reflect cause of fault. */\n\t\t\tretval = cortex_a_read_dfar_dfsr(target, &fault_dfar, &fault_dfsr, &dscr);\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"data abort at 0x%08\" PRIx32 \", dfsr = 0x%08\" PRIx32, fault_dfar, fault_dfsr);\n\t\t\t\tfinal_retval = cortex_a_dfsr_to_error_code(fault_dfsr);\n\t\t\t} else\n\t\t\t\tfinal_retval = retval;\n\t\t}\n\t\t/* Fault destroyed DFAR/DFSR; restore them. */\n\t\tretval = cortex_a_write_dfar_dfsr(target, orig_dfar, orig_dfsr, &dscr);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"error restoring dfar/dfsr - dscr = 0x%08\" PRIx32, dscr);\n\t}\n\n\t/* Handle asynchronous data faults. */\n\tif (fault_dscr & DSCR_STICKY_ABORT_IMPRECISE) {\n\t\tif (final_retval == ERROR_OK)\n\t\t\t/* No other error has been recorded so far, so keep this one. */\n\t\t\tfinal_retval = ERROR_TARGET_DATA_ABORT;\n\t}\n\n\t/* If the DCC is nonempty, clear it. */\n\tif (dscr & DSCR_DTRTX_FULL_LATCHED) {\n\t\tuint32_t dummy;\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, &dummy);\n\t\tif (final_retval == ERROR_OK)\n\t\t\tfinal_retval = retval;\n\t}\n\tif (dscr & DSCR_DTRRX_FULL_LATCHED) {\n\t\tretval = cortex_a_exec_opcode(target, ARMV4_5_MRC(14, 0, 1, 0, 5, 0), &dscr);\n\t\tif (final_retval == ERROR_OK)\n\t\t\tfinal_retval = retval;\n\t}\n\n\t/* Done. */\n\treturn final_retval;\n}\n\n\n/*\n * Cortex-A Memory access\n *\n * This is same Cortex-M3 but we must also use the correct\n * ap number for every access.\n */\n\nstatic int cortex_a_read_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\n\tif (!count || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"Reading memory at real address \" TARGET_ADDR_FMT \"; size %\" PRIu32 \"; count %\" PRIu32,\n\t\taddress, size, count);\n\n\t/* read memory through the CPU */\n\tcortex_a_prep_memaccess(target, 1);\n\tretval = cortex_a_read_cpu_memory(target, address, size, count, buffer);\n\tcortex_a_post_memaccess(target, 1);\n\n\treturn retval;\n}\n\nstatic int cortex_a_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval;\n\n\t/* cortex_a handles unaligned memory access */\n\tLOG_DEBUG(\"Reading memory at address \" TARGET_ADDR_FMT \"; size %\" PRIu32 \"; count %\" PRIu32,\n\t\taddress, size, count);\n\n\tcortex_a_prep_memaccess(target, 0);\n\tretval = cortex_a_read_cpu_memory(target, address, size, count, buffer);\n\tcortex_a_post_memaccess(target, 0);\n\n\treturn retval;\n}\n\nstatic int cortex_a_write_phys_memory(struct target *target,\n\ttarget_addr_t address, uint32_t size,\n\tuint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\n\tif (!count || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"Writing memory to real address \" TARGET_ADDR_FMT \"; size %\" PRIu32 \"; count %\" PRIu32,\n\t\taddress, size, count);\n\n\t/* write memory through the CPU */\n\tcortex_a_prep_memaccess(target, 1);\n\tretval = cortex_a_write_cpu_memory(target, address, size, count, buffer);\n\tcortex_a_post_memaccess(target, 1);\n\n\treturn retval;\n}\n\nstatic int cortex_a_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\n\t/* cortex_a handles unaligned memory access */\n\tLOG_DEBUG(\"Writing memory at address \" TARGET_ADDR_FMT \"; size %\" PRIu32 \"; count %\" PRIu32,\n\t\taddress, size, count);\n\n\t/* memory writes bypass the caches, must flush before writing */\n\tarmv7a_cache_auto_flush_on_write(target, address, size * count);\n\n\tcortex_a_prep_memaccess(target, 0);\n\tretval = cortex_a_write_cpu_memory(target, address, size, count, buffer);\n\tcortex_a_post_memaccess(target, 0);\n\treturn retval;\n}\n\nstatic int cortex_a_read_buffer(struct target *target, target_addr_t address,\n\t\t\t\tuint32_t count, uint8_t *buffer)\n{\n\tuint32_t size;\n\n\t/* Align up to maximum 4 bytes. The loop condition makes sure the next pass\n\t * will have something to do with the size we leave to it. */\n\tfor (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {\n\t\tif (address & size) {\n\t\t\tint retval = target_read_memory(target, address, size, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += size;\n\t\t\tcount -= size;\n\t\t\tbuffer += size;\n\t\t}\n\t}\n\n\t/* Read the data with as large access size as possible. */\n\tfor (; size > 0; size /= 2) {\n\t\tuint32_t aligned = count - count % size;\n\t\tif (aligned > 0) {\n\t\t\tint retval = target_read_memory(target, address, size, aligned / size, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += aligned;\n\t\t\tcount -= aligned;\n\t\t\tbuffer += aligned;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_write_buffer(struct target *target, target_addr_t address,\n\t\t\t\t uint32_t count, const uint8_t *buffer)\n{\n\tuint32_t size;\n\n\t/* Align up to maximum 4 bytes. The loop condition makes sure the next pass\n\t * will have something to do with the size we leave to it. */\n\tfor (size = 1; size < 4 && count >= size * 2 + (address & size); size *= 2) {\n\t\tif (address & size) {\n\t\t\tint retval = target_write_memory(target, address, size, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += size;\n\t\t\tcount -= size;\n\t\t\tbuffer += size;\n\t\t}\n\t}\n\n\t/* Write the data with as large access size as possible. */\n\tfor (; size > 0; size /= 2) {\n\t\tuint32_t aligned = count - count % size;\n\t\tif (aligned > 0) {\n\t\t\tint retval = target_write_memory(target, address, size, aligned / size, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += aligned;\n\t\t\tcount -= aligned;\n\t\t\tbuffer += aligned;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_handle_target_request(void *priv)\n{\n\tstruct target *target = priv;\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\tint retval;\n\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\tif (!target->dbg_msg_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->state == TARGET_RUNNING) {\n\t\tuint32_t request;\n\t\tuint32_t dscr;\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\n\t\t/* check if we have data */\n\t\tint64_t then = timeval_ms();\n\t\twhile ((dscr & DSCR_DTR_TX_FULL) && (retval == ERROR_OK)) {\n\t\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\tarmv7a->debug_base + CPUDBG_DTRTX, &request);\n\t\t\tif (retval == ERROR_OK) {\n\t\t\t\ttarget_request(target, request);\n\t\t\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\t\t\t}\n\t\t\tif (timeval_ms() > then + 1000) {\n\t\t\t\tLOG_ERROR(\"Timeout waiting for dtr tx full\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n * Cortex-A target information and configuration\n */\n\nstatic int cortex_a_examine_first(struct target *target)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct adiv5_dap *swjdp = armv7a->arm.dap;\n\tstruct adiv5_private_config *pc = target->private_config;\n\n\tint i;\n\tint retval = ERROR_OK;\n\tuint32_t didr, cpuid, dbg_osreg, dbg_idpfr1;\n\n\tif (!armv7a->debug_ap) {\n\t\tif (pc->ap_num == DP_APSEL_INVALID) {\n\t\t\t/* Search for the APB-AP - it is needed for access to debug registers */\n\t\t\tretval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv7a->debug_ap);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not find APB-AP for debug access\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tarmv7a->debug_ap = dap_get_ap(swjdp, pc->ap_num);\n\t\t\tif (!armv7a->debug_ap) {\n\t\t\t\tLOG_ERROR(\"Cannot get AP\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = mem_ap_init(armv7a->debug_ap);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Could not initialize the APB-AP\");\n\t\treturn retval;\n\t}\n\n\tarmv7a->debug_ap->memaccess_tck = 80;\n\n\tif (!target->dbgbase_set) {\n\t\tLOG_DEBUG(\"%s's dbgbase is not set, trying to detect using the ROM table\",\n\t\t\t  target->cmd_name);\n\t\t/* Lookup Processor DAP */\n\t\tretval = dap_lookup_cs_component(armv7a->debug_ap, ARM_CS_C9_DEVTYPE_CORE_DEBUG,\n\t\t\t\t&armv7a->debug_base, target->coreid);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Can't detect %s's dbgbase from the ROM table; you need to specify it explicitly.\",\n\t\t\t\t  target->cmd_name);\n\t\t\treturn retval;\n\t\t}\n\t\tLOG_DEBUG(\"Detected core %\" PRId32 \" dbgbase: \" TARGET_ADDR_FMT,\n\t\t\t  target->coreid, armv7a->debug_base);\n\t} else\n\t\tarmv7a->debug_base = target->dbgbase;\n\n\tif ((armv7a->debug_base & (1UL<<31)) == 0)\n\t\tLOG_WARNING(\"Debug base address for target %s has bit 31 set to 0. Access to debug registers will likely fail!\\n\"\n\t\t\t    \"Please fix the target configuration.\", target_name(target));\n\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_DIDR, &didr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"DIDR\");\n\t\treturn retval;\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\tarmv7a->debug_base + CPUDBG_CPUID, &cpuid);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"Examine %s failed\", \"CPUID\");\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"didr = 0x%08\" PRIx32, didr);\n\tLOG_DEBUG(\"cpuid = 0x%08\" PRIx32, cpuid);\n\n\tcortex_a->didr = didr;\n\tcortex_a->cpuid = cpuid;\n\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t    armv7a->debug_base + CPUDBG_PRSR, &dbg_osreg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"target->coreid %\" PRId32 \" DBGPRSR  0x%\" PRIx32, target->coreid, dbg_osreg);\n\n\tif ((dbg_osreg & PRSR_POWERUP_STATUS) == 0) {\n\t\tLOG_ERROR(\"target->coreid %\" PRId32 \" powered down!\", target->coreid);\n\t\ttarget->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */\n\t\treturn ERROR_TARGET_INIT_FAILED;\n\t}\n\n\tif (dbg_osreg & PRSR_STICKY_RESET_STATUS)\n\t\tLOG_DEBUG(\"target->coreid %\" PRId32 \" was reset!\", target->coreid);\n\n\t/* Read DBGOSLSR and check if OSLK is implemented */\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"target->coreid %\" PRId32 \" DBGOSLSR 0x%\" PRIx32, target->coreid, dbg_osreg);\n\n\t/* check if OS Lock is implemented */\n\tif ((dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM0 || (dbg_osreg & OSLSR_OSLM) == OSLSR_OSLM1) {\n\t\t/* check if OS Lock is set */\n\t\tif (dbg_osreg & OSLSR_OSLK) {\n\t\t\tLOG_DEBUG(\"target->coreid %\" PRId32 \" OSLock set! Trying to unlock\", target->coreid);\n\n\t\t\tretval = mem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t\t\tarmv7a->debug_base + CPUDBG_OSLAR,\n\t\t\t\t\t\t\t0);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\t\t\tarmv7a->debug_base + CPUDBG_OSLSR, &dbg_osreg);\n\n\t\t\t/* if we fail to access the register or cannot reset the OSLK bit, bail out */\n\t\t\tif (retval != ERROR_OK || (dbg_osreg & OSLSR_OSLK) != 0) {\n\t\t\t\tLOG_ERROR(\"target->coreid %\" PRId32 \" OSLock sticky, core not powered?\",\n\t\t\t\t\t\ttarget->coreid);\n\t\t\t\ttarget->state = TARGET_UNKNOWN; /* TARGET_NO_POWER? */\n\t\t\t\treturn ERROR_TARGET_INIT_FAILED;\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\t armv7a->debug_base + CPUDBG_ID_PFR1, &dbg_idpfr1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dbg_idpfr1 & 0x000000f0) {\n\t\tLOG_DEBUG(\"target->coreid %\" PRId32 \" has security extensions\",\n\t\t\t\ttarget->coreid);\n\t\tarmv7a->arm.core_type = ARM_CORE_TYPE_SEC_EXT;\n\t}\n\tif (dbg_idpfr1 & 0x0000f000) {\n\t\tLOG_DEBUG(\"target->coreid %\" PRId32 \" has virtualization extensions\",\n\t\t\t\ttarget->coreid);\n\t\t/*\n\t\t * overwrite and simplify the checks.\n\t\t * virtualization extensions require implementation of security extension\n\t\t */\n\t\tarmv7a->arm.core_type = ARM_CORE_TYPE_VIRT_EXT;\n\t}\n\n\t/* Avoid recreating the registers cache */\n\tif (!target_was_examined(target)) {\n\t\tretval = cortex_a_dpm_setup(cortex_a, didr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Setup Breakpoint Register Pairs */\n\tcortex_a->brp_num = ((didr >> 24) & 0x0F) + 1;\n\tcortex_a->brp_num_context = ((didr >> 20) & 0x0F) + 1;\n\tcortex_a->brp_num_available = cortex_a->brp_num;\n\tfree(cortex_a->brp_list);\n\tcortex_a->brp_list = calloc(cortex_a->brp_num, sizeof(struct cortex_a_brp));\n/*\tcortex_a->brb_enabled = ????; */\n\tfor (i = 0; i < cortex_a->brp_num; i++) {\n\t\tcortex_a->brp_list[i].used = false;\n\t\tif (i < (cortex_a->brp_num-cortex_a->brp_num_context))\n\t\t\tcortex_a->brp_list[i].type = BRP_NORMAL;\n\t\telse\n\t\t\tcortex_a->brp_list[i].type = BRP_CONTEXT;\n\t\tcortex_a->brp_list[i].value = 0;\n\t\tcortex_a->brp_list[i].control = 0;\n\t\tcortex_a->brp_list[i].brpn = i;\n\t}\n\n\tLOG_DEBUG(\"Configured %i hw breakpoints\", cortex_a->brp_num);\n\n\t/* Setup Watchpoint Register Pairs */\n\tcortex_a->wrp_num = ((didr >> 28) & 0x0F) + 1;\n\tcortex_a->wrp_num_available = cortex_a->wrp_num;\n\tfree(cortex_a->wrp_list);\n\tcortex_a->wrp_list = calloc(cortex_a->wrp_num, sizeof(struct cortex_a_wrp));\n\tfor (i = 0; i < cortex_a->wrp_num; i++) {\n\t\tcortex_a->wrp_list[i].used = false;\n\t\tcortex_a->wrp_list[i].value = 0;\n\t\tcortex_a->wrp_list[i].control = 0;\n\t\tcortex_a->wrp_list[i].wrpn = i;\n\t}\n\n\tLOG_DEBUG(\"Configured %i hw watchpoints\", cortex_a->wrp_num);\n\n\t/* select debug_ap as default */\n\tswjdp->apsel = armv7a->debug_ap->ap_num;\n\n\ttarget_set_examined(target);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_examine(struct target *target)\n{\n\tint retval = ERROR_OK;\n\n\t/* Reestablish communication after target reset */\n\tretval = cortex_a_examine_first(target);\n\n\t/* Configure core debug access */\n\tif (retval == ERROR_OK)\n\t\tretval = cortex_a_init_debug_access(target);\n\n\treturn retval;\n}\n\n/*\n *\tCortex-A target creation and initialization\n */\n\nstatic int cortex_a_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\t/* examine_first() does a bunch of this */\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_init_arch_info(struct target *target,\n\tstruct cortex_a_common *cortex_a, struct adiv5_dap *dap)\n{\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\n\t/* Setup struct cortex_a_common */\n\tcortex_a->common_magic = CORTEX_A_COMMON_MAGIC;\n\tarmv7a->arm.dap = dap;\n\n\t/* register arch-specific functions */\n\tarmv7a->examine_debug_reason = NULL;\n\n\tarmv7a->post_debug_entry = cortex_a_post_debug_entry;\n\n\tarmv7a->pre_restore_context = NULL;\n\n\tarmv7a->armv7a_mmu.read_physical_memory = cortex_a_read_phys_memory;\n\n\n/*\tarm7_9->handle_target_request = cortex_a_handle_target_request; */\n\n\t/* REVISIT v7a setup should be in a v7a-specific routine */\n\tarmv7a_init_arch_info(target, armv7a);\n\ttarget_register_timer_callback(cortex_a_handle_target_request, 1,\n\t\tTARGET_TIMER_TYPE_PERIODIC, target);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct cortex_a_common *cortex_a;\n\tstruct adiv5_private_config *pc;\n\n\tif (!target->private_config)\n\t\treturn ERROR_FAIL;\n\n\tpc = (struct adiv5_private_config *)target->private_config;\n\n\tcortex_a = calloc(1, sizeof(struct cortex_a_common));\n\tif (!cortex_a) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tcortex_a->common_magic = CORTEX_A_COMMON_MAGIC;\n\tcortex_a->armv7a_common.is_armv7r = false;\n\tcortex_a->armv7a_common.arm.arm_vfp_version = ARM_VFP_V3;\n\n\treturn cortex_a_init_arch_info(target, cortex_a, pc->dap);\n}\n\nstatic int cortex_r4_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct cortex_a_common *cortex_a;\n\tstruct adiv5_private_config *pc;\n\n\tpc = (struct adiv5_private_config *)target->private_config;\n\tif (adiv5_verify_config(pc) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tcortex_a = calloc(1, sizeof(struct cortex_a_common));\n\tif (!cortex_a) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tcortex_a->common_magic = CORTEX_A_COMMON_MAGIC;\n\tcortex_a->armv7a_common.is_armv7r = true;\n\n\treturn cortex_a_init_arch_info(target, cortex_a, pc->dap);\n}\n\nstatic void cortex_a_deinit_target(struct target *target)\n{\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\tstruct armv7a_common *armv7a = &cortex_a->armv7a_common;\n\tstruct arm_dpm *dpm = &armv7a->dpm;\n\tuint32_t dscr;\n\tint retval;\n\n\tif (target_was_examined(target)) {\n\t\t/* Disable halt for breakpoint, watchpoint and vector catch */\n\t\tretval = mem_ap_read_atomic_u32(armv7a->debug_ap,\n\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR, &dscr);\n\t\tif (retval == ERROR_OK)\n\t\t\tmem_ap_write_atomic_u32(armv7a->debug_ap,\n\t\t\t\t\tarmv7a->debug_base + CPUDBG_DSCR,\n\t\t\t\t\tdscr & ~DSCR_HALT_DBG_MODE);\n\t}\n\n\tif (armv7a->debug_ap)\n\t\tdap_put_ap(armv7a->debug_ap);\n\n\tfree(cortex_a->wrp_list);\n\tfree(cortex_a->brp_list);\n\tarm_free_reg_cache(dpm->arm);\n\tfree(dpm->dbp);\n\tfree(dpm->dwp);\n\tfree(target->private_config);\n\tfree(cortex_a);\n}\n\nstatic int cortex_a_mmu(struct target *target, int *enabled)\n{\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"%s: target not halted\", __func__);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (armv7a->is_armv7r)\n\t\t*enabled = 0;\n\telse\n\t\t*enabled = target_to_cortex_a(target)->armv7a_common.armv7a_mmu.mmu_enabled;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_a_virt2phys(struct target *target,\n\ttarget_addr_t virt, target_addr_t *phys)\n{\n\tint retval;\n\tint mmu_enabled = 0;\n\n\t/*\n\t * If the MMU was not enabled at debug entry, there is no\n\t * way of knowing if there was ever a valid configuration\n\t * for it and thus it's not safe to enable it. In this case,\n\t * just return the virtual address as physical.\n\t */\n\tcortex_a_mmu(target, &mmu_enabled);\n\tif (!mmu_enabled) {\n\t\t*phys = virt;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* mmu must be enable in order to get a correct translation */\n\tretval = cortex_a_mmu_modify(target, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn armv7a_mmu_translate_va_pa(target, (uint32_t)virt,\n\t\t\t\t\t\t    phys, 1);\n}\n\nCOMMAND_HANDLER(cortex_a_handle_cache_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct armv7a_common *armv7a = target_to_armv7a(target);\n\n\treturn armv7a_handle_cache_info_command(CMD,\n\t\t\t&armv7a->armv7a_mmu.armv7a_cache);\n}\n\n\nCOMMAND_HANDLER(cortex_a_handle_dbginit_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn cortex_a_init_debug_access(target);\n}\n\nCOMMAND_HANDLER(handle_cortex_a_mask_interrupts_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tstatic const struct nvp nvp_maskisr_modes[] = {\n\t\t{ .name = \"off\", .value = CORTEX_A_ISRMASK_OFF },\n\t\t{ .name = \"on\", .value = CORTEX_A_ISRMASK_ON },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\tconst struct nvp *n;\n\n\tif (CMD_ARGC > 0) {\n\t\tn = nvp_name2value(nvp_maskisr_modes, CMD_ARGV[0]);\n\t\tif (!n->name) {\n\t\t\tLOG_ERROR(\"Unknown parameter: %s - should be off or on\", CMD_ARGV[0]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tcortex_a->isrmasking_mode = n->value;\n\t}\n\n\tn = nvp_value2name(nvp_maskisr_modes, cortex_a->isrmasking_mode);\n\tcommand_print(CMD, \"cortex_a interrupt mask %s\", n->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cortex_a_dacrfixup_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_a_common *cortex_a = target_to_cortex_a(target);\n\n\tstatic const struct nvp nvp_dacrfixup_modes[] = {\n\t\t{ .name = \"off\", .value = CORTEX_A_DACRFIXUP_OFF },\n\t\t{ .name = \"on\", .value = CORTEX_A_DACRFIXUP_ON },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\tconst struct nvp *n;\n\n\tif (CMD_ARGC > 0) {\n\t\tn = nvp_name2value(nvp_dacrfixup_modes, CMD_ARGV[0]);\n\t\tif (!n->name)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tcortex_a->dacrfixup_mode = n->value;\n\n\t}\n\n\tn = nvp_value2name(nvp_dacrfixup_modes, cortex_a->dacrfixup_mode);\n\tcommand_print(CMD, \"cortex_a domain access control fixup %s\", n->name);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration cortex_a_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cache_info\",\n\t\t.handler = cortex_a_handle_cache_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display information about target caches\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"dbginit\",\n\t\t.handler = cortex_a_handle_dbginit_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Initialize core debug\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = handle_cortex_a_mask_interrupts_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mask cortex_a interrupts\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.name = \"dacrfixup\",\n\t\t.handler = handle_cortex_a_dacrfixup_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"set domain access control (DACR) to all-manager \"\n\t\t\t\"on memory access\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.chain = armv7a_mmu_command_handlers,\n\t},\n\t{\n\t\t.chain = smp_command_handlers,\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration cortex_a_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.chain = armv7a_command_handlers,\n\t},\n\t{\n\t\t.name = \"cortex_a\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Cortex-A command group\",\n\t\t.usage = \"\",\n\t\t.chain = cortex_a_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type cortexa_target = {\n\t.name = \"cortex_a\",\n\n\t.poll = cortex_a_poll,\n\t.arch_state = armv7a_arch_state,\n\n\t.halt = cortex_a_halt,\n\t.resume = cortex_a_resume,\n\t.step = cortex_a_step,\n\n\t.assert_reset = cortex_a_assert_reset,\n\t.deassert_reset = cortex_a_deassert_reset,\n\n\t/* REVISIT allow exporting VFP3 registers ... */\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = cortex_a_read_memory,\n\t.write_memory = cortex_a_write_memory,\n\n\t.read_buffer = cortex_a_read_buffer,\n\t.write_buffer = cortex_a_write_buffer,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = cortex_a_add_breakpoint,\n\t.add_context_breakpoint = cortex_a_add_context_breakpoint,\n\t.add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint,\n\t.remove_breakpoint = cortex_a_remove_breakpoint,\n\t.add_watchpoint = cortex_a_add_watchpoint,\n\t.remove_watchpoint = cortex_a_remove_watchpoint,\n\n\t.commands = cortex_a_command_handlers,\n\t.target_create = cortex_a_target_create,\n\t.target_jim_configure = adiv5_jim_configure,\n\t.init_target = cortex_a_init_target,\n\t.examine = cortex_a_examine,\n\t.deinit_target = cortex_a_deinit_target,\n\n\t.read_phys_memory = cortex_a_read_phys_memory,\n\t.write_phys_memory = cortex_a_write_phys_memory,\n\t.mmu = cortex_a_mmu,\n\t.virt2phys = cortex_a_virt2phys,\n};\n\nstatic const struct command_registration cortex_r4_exec_command_handlers[] = {\n\t{\n\t\t.name = \"dbginit\",\n\t\t.handler = cortex_a_handle_dbginit_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Initialize core debug\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = handle_cortex_a_mask_interrupts_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"mask cortex_r4 interrupts\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration cortex_r4_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.name = \"cortex_r4\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Cortex-R4 command group\",\n\t\t.usage = \"\",\n\t\t.chain = cortex_r4_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type cortexr4_target = {\n\t.name = \"cortex_r4\",\n\n\t.poll = cortex_a_poll,\n\t.arch_state = armv7a_arch_state,\n\n\t.halt = cortex_a_halt,\n\t.resume = cortex_a_resume,\n\t.step = cortex_a_step,\n\n\t.assert_reset = cortex_a_assert_reset,\n\t.deassert_reset = cortex_a_deassert_reset,\n\n\t/* REVISIT allow exporting VFP3 registers ... */\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = cortex_a_read_phys_memory,\n\t.write_memory = cortex_a_write_phys_memory,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = cortex_a_add_breakpoint,\n\t.add_context_breakpoint = cortex_a_add_context_breakpoint,\n\t.add_hybrid_breakpoint = cortex_a_add_hybrid_breakpoint,\n\t.remove_breakpoint = cortex_a_remove_breakpoint,\n\t.add_watchpoint = cortex_a_add_watchpoint,\n\t.remove_watchpoint = cortex_a_remove_watchpoint,\n\n\t.commands = cortex_r4_command_handlers,\n\t.target_create = cortex_r4_target_create,\n\t.target_jim_configure = adiv5_jim_configure,\n\t.init_target = cortex_a_init_target,\n\t.examine = cortex_a_examine,\n\t.deinit_target = cortex_a_deinit_target,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/cortex_a.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2009 by Dirk Behme                                      *\n *   dirk.behme@gmail.com - copy from cortex_m3                            *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_CORTEX_A_H\n#define OPENOCD_TARGET_CORTEX_A_H\n\n#include \"armv7a.h\"\n\n#define CORTEX_A_COMMON_MAGIC 0x411fc082U\n\n#define CORTEX_A5_PARTNUM 0xc05\n#define CORTEX_A7_PARTNUM 0xc07\n#define CORTEX_A8_PARTNUM 0xc08\n#define CORTEX_A9_PARTNUM 0xc09\n#define CORTEX_A15_PARTNUM 0xc0f\n#define CORTEX_A_MIDR_PARTNUM_MASK 0x0000fff0\n#define CORTEX_A_MIDR_PARTNUM_SHIFT 4\n\n#define CPUDBG_CPUID\t0xD00\n#define CPUDBG_CTYPR\t0xD04\n#define CPUDBG_TTYPR\t0xD0C\n#define CPUDBG_LOCKACCESS 0xFB0\n#define CPUDBG_LOCKSTATUS 0xFB4\n#define CPUDBG_OSLAR_LK_MASK (1 << 1)\n\n#define BRP_NORMAL 0\n#define BRP_CONTEXT 1\n\n#define CORTEX_A_PADDRDBG_CPU_SHIFT 13\n\nenum cortex_a_isrmasking_mode {\n\tCORTEX_A_ISRMASK_OFF,\n\tCORTEX_A_ISRMASK_ON,\n};\n\nenum cortex_a_dacrfixup_mode {\n\tCORTEX_A_DACRFIXUP_OFF,\n\tCORTEX_A_DACRFIXUP_ON\n};\n\nstruct cortex_a_brp {\n\tbool used;\n\tint type;\n\tuint32_t value;\n\tuint32_t control;\n\tuint8_t brpn;\n};\n\nstruct cortex_a_wrp {\n\tbool used;\n\tuint32_t value;\n\tuint32_t control;\n\tuint8_t wrpn;\n};\n\nstruct cortex_a_common {\n\tunsigned int common_magic;\n\n\tstruct armv7a_common armv7a_common;\n\n\t/* Context information */\n\tuint32_t cpudbg_dscr;\n\n\t/* Saved cp15 registers */\n\tuint32_t cp15_control_reg;\n\t/* latest cp15 register value written and cpsr processor mode */\n\tuint32_t cp15_control_reg_curr;\n\t/* auxiliary control reg */\n\tuint32_t cp15_aux_control_reg;\n\t/* DACR */\n\tuint32_t cp15_dacr_reg;\n\tenum arm_mode curr_mode;\n\n\t/* Breakpoint register pairs */\n\tint brp_num_context;\n\tint brp_num;\n\tint brp_num_available;\n\tstruct cortex_a_brp *brp_list;\n\tint wrp_num;\n\tint wrp_num_available;\n\tstruct cortex_a_wrp *wrp_list;\n\n\tuint32_t cpuid;\n\tuint32_t didr;\n\n\tenum cortex_a_isrmasking_mode isrmasking_mode;\n\tenum cortex_a_dacrfixup_mode dacrfixup_mode;\n};\n\nstatic inline struct cortex_a_common *\ntarget_to_cortex_a(struct target *target)\n{\n\treturn container_of(target->arch_info, struct cortex_a_common, armv7a_common.arm);\n}\n\n#endif /* OPENOCD_TARGET_CORTEX_A_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/cortex_m.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *                                                                         *\n *   Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0)              *\n *                                                                         *\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"breakpoints.h\"\n#include \"cortex_m.h\"\n#include \"target_request.h\"\n#include \"target_type.h\"\n#include \"arm_adi_v5.h\"\n#include \"arm_disassembler.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n#include \"arm_semihosting.h\"\n#include \"smp.h\"\n#include <helper/nvp.h>\n#include <helper/time_support.h>\n#include <rtt/rtt.h>\n\n/* NOTE:  most of this should work fine for the Cortex-M1 and\n * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.\n * Some differences:  M0/M1 doesn't have FPB remapping or the\n * DWT tracing/profiling support.  (So the cycle counter will\n * not be usable; the other stuff isn't currently used here.)\n *\n * Although there are some workarounds for errata seen only in r0p0\n * silicon, such old parts are hard to find and thus not much tested\n * any longer.\n */\n\n/* Timeout for register r/w */\n#define DHCSR_S_REGRDY_TIMEOUT (500)\n\n/* Supported Cortex-M Cores */\nstatic const struct cortex_m_part_info cortex_m_parts[] = {\n\t{\n\t\t.partno = CORTEX_M0_PARTNO,\n\t\t.name = \"Cortex-M0\",\n\t\t.arch = ARM_ARCH_V6M,\n\t},\n\t{\n\t\t.partno = CORTEX_M0P_PARTNO,\n\t\t.name = \"Cortex-M0+\",\n\t\t.arch = ARM_ARCH_V6M,\n\t},\n\t{\n\t\t.partno = CORTEX_M1_PARTNO,\n\t\t.name = \"Cortex-M1\",\n\t\t.arch = ARM_ARCH_V6M,\n\t},\n\t{\n\t\t.partno = CORTEX_M3_PARTNO,\n\t\t.name = \"Cortex-M3\",\n\t\t.arch = ARM_ARCH_V7M,\n\t\t.flags = CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,\n\t},\n\t{\n\t\t.partno = CORTEX_M4_PARTNO,\n\t\t.name = \"Cortex-M4\",\n\t\t.arch = ARM_ARCH_V7M,\n\t\t.flags = CORTEX_M_F_HAS_FPV4 | CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,\n\t},\n\t{\n\t\t.partno = CORTEX_M7_PARTNO,\n\t\t.name = \"Cortex-M7\",\n\t\t.arch = ARM_ARCH_V7M,\n\t\t.flags = CORTEX_M_F_HAS_FPV5,\n\t},\n\t{\n\t\t.partno = CORTEX_M23_PARTNO,\n\t\t.name = \"Cortex-M23\",\n\t\t.arch = ARM_ARCH_V8M,\n\t},\n\t{\n\t\t.partno = CORTEX_M33_PARTNO,\n\t\t.name = \"Cortex-M33\",\n\t\t.arch = ARM_ARCH_V8M,\n\t\t.flags = CORTEX_M_F_HAS_FPV5,\n\t},\n\t{\n\t\t.partno = CORTEX_M35P_PARTNO,\n\t\t.name = \"Cortex-M35P\",\n\t\t.arch = ARM_ARCH_V8M,\n\t\t.flags = CORTEX_M_F_HAS_FPV5,\n\t},\n\t{\n\t\t.partno = CORTEX_M55_PARTNO,\n\t\t.name = \"Cortex-M55\",\n\t\t.arch = ARM_ARCH_V8M,\n\t\t.flags = CORTEX_M_F_HAS_FPV5,\n\t},\n\t{\n\t\t.partno = STAR_MC1_PARTNO,\n\t\t.name = \"STAR-MC1\",\n\t\t.arch = ARM_ARCH_V8M,\n\t\t.flags = CORTEX_M_F_HAS_FPV5,\n\t},\n};\n\n/* forward declarations */\nstatic int cortex_m_store_core_reg_u32(struct target *target,\n\t\tuint32_t num, uint32_t value);\nstatic void cortex_m_dwt_free(struct target *target);\n\n/** DCB DHCSR register contains S_RETIRE_ST and S_RESET_ST bits cleared\n *  on a read. Call this helper function each time DHCSR is read\n *  to preserve S_RESET_ST state in case of a reset event was detected.\n */\nstatic inline void cortex_m_cumulate_dhcsr_sticky(struct cortex_m_common *cortex_m,\n\t\tuint32_t dhcsr)\n{\n\tcortex_m->dcb_dhcsr_cumulated_sticky |= dhcsr;\n}\n\n/** Read DCB DHCSR register to cortex_m->dcb_dhcsr and cumulate\n * sticky bits in cortex_m->dcb_dhcsr_cumulated_sticky\n */\nstatic int cortex_m_read_dhcsr_atomic_sticky(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tint retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR,\n\t\t\t\t&cortex_m->dcb_dhcsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_load_core_reg_u32(struct target *target,\n\t\tuint32_t regsel, uint32_t *value)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint retval;\n\tuint32_t dcrdr, tmp_value;\n\tint64_t then;\n\n\t/* because the DCB_DCRDR is used for the emulated dcc channel\n\t * we have to save/restore the DCB_DCRDR when used */\n\tif (target->dbg_msg_enabled) {\n\t\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check if value from register is ready and pre-read it */\n\tthen = timeval_ms();\n\twhile (1) {\n\t\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DHCSR,\n\t\t\t\t\t\t\t\t &cortex_m->dcb_dhcsr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR,\n\t\t\t\t\t\t\t\t\t\t&tmp_value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);\n\t\tif (cortex_m->dcb_dhcsr & S_REGRDY)\n\t\t\tbreak;\n\t\tcortex_m->slow_register_read = true; /* Polling (still) needed. */\n\t\tif (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {\n\t\t\tLOG_TARGET_ERROR(target, \"Timeout waiting for DCRDR transfer ready\");\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t}\n\t\tkeep_alive();\n\t}\n\n\t*value = tmp_value;\n\n\tif (target->dbg_msg_enabled) {\n\t\t/* restore DCB_DCRDR - this needs to be in a separate\n\t\t * transaction otherwise the emulated DCC channel breaks */\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);\n\t}\n\n\treturn retval;\n}\n\nstatic int cortex_m_slow_read_all_regs(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tconst unsigned int num_regs = armv7m->arm.core_cache->num_regs;\n\n\t/* Opportunistically restore fast read, it'll revert to slow\n\t * if any register needed polling in cortex_m_load_core_reg_u32(). */\n\tcortex_m->slow_register_read = false;\n\n\tfor (unsigned int reg_id = 0; reg_id < num_regs; reg_id++) {\n\t\tstruct reg *r = &armv7m->arm.core_cache->reg_list[reg_id];\n\t\tif (r->exist) {\n\t\t\tint retval = armv7m->arm.read_core_reg(target, r, reg_id, ARM_MODE_ANY);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\tif (!cortex_m->slow_register_read)\n\t\tLOG_TARGET_DEBUG(target, \"Switching back to fast register reads\");\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_queue_reg_read(struct target *target, uint32_t regsel,\n\t\tuint32_t *reg_value, uint32_t *dhcsr)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint retval;\n\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DHCSR, dhcsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, reg_value);\n}\n\nstatic int cortex_m_fast_read_all_regs(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint retval;\n\tuint32_t dcrdr;\n\n\t/* because the DCB_DCRDR is used for the emulated dcc channel\n\t * we have to save/restore the DCB_DCRDR when used */\n\tif (target->dbg_msg_enabled) {\n\t\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tconst unsigned int num_regs = armv7m->arm.core_cache->num_regs;\n\tconst unsigned int n_r32 = ARMV7M_LAST_REG - ARMV7M_CORE_FIRST_REG + 1\n\t\t\t\t\t\t\t   + ARMV7M_FPU_LAST_REG - ARMV7M_FPU_FIRST_REG + 1;\n\t/* we need one 32-bit word for each register except FP D0..D15, which\n\t * need two words */\n\tuint32_t r_vals[n_r32];\n\tuint32_t dhcsr[n_r32];\n\n\tunsigned int wi = 0; /* write index to r_vals and dhcsr arrays */\n\tunsigned int reg_id; /* register index in the reg_list, ARMV7M_R0... */\n\tfor (reg_id = 0; reg_id < num_regs; reg_id++) {\n\t\tstruct reg *r = &armv7m->arm.core_cache->reg_list[reg_id];\n\t\tif (!r->exist)\n\t\t\tcontinue;\t/* skip non existent registers */\n\n\t\tif (r->size <= 8) {\n\t\t\t/* Any 8-bit or shorter register is unpacked from a 32-bit\n\t\t\t * container register. Skip it now. */\n\t\t\tcontinue;\n\t\t}\n\n\t\tuint32_t regsel = armv7m_map_id_to_regsel(reg_id);\n\t\tretval = cortex_m_queue_reg_read(target, regsel, &r_vals[wi],\n\t\t\t\t\t\t\t\t\t\t &dhcsr[wi]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twi++;\n\n\t\tassert(r->size == 32 || r->size == 64);\n\t\tif (r->size == 32)\n\t\t\tcontinue;\t/* done with 32-bit register */\n\n\t\tassert(reg_id >= ARMV7M_FPU_FIRST_REG && reg_id <= ARMV7M_FPU_LAST_REG);\n\t\t/* the odd part of FP register (S1, S3...) */\n\t\tretval = cortex_m_queue_reg_read(target, regsel + 1, &r_vals[wi],\n\t\t\t\t\t\t\t\t\t\t\t &dhcsr[wi]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\twi++;\n\t}\n\n\tassert(wi <= n_r32);\n\n\tretval = dap_run(armv7m->debug_ap->dap);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->dbg_msg_enabled) {\n\t\t/* restore DCB_DCRDR - this needs to be in a separate\n\t\t * transaction otherwise the emulated DCC channel breaks */\n\t\tretval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tbool not_ready = false;\n\tfor (unsigned int i = 0; i < wi; i++) {\n\t\tif ((dhcsr[i] & S_REGRDY) == 0) {\n\t\t\tnot_ready = true;\n\t\t\tLOG_TARGET_DEBUG(target, \"Register %u was not ready during fast read\", i);\n\t\t}\n\t\tcortex_m_cumulate_dhcsr_sticky(cortex_m, dhcsr[i]);\n\t}\n\n\tif (not_ready) {\n\t\t/* Any register was not ready,\n\t\t * fall back to slow read with S_REGRDY polling */\n\t\treturn ERROR_TIMEOUT_REACHED;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"read %u 32-bit registers\", wi);\n\n\tunsigned int ri = 0; /* read index from r_vals array */\n\tfor (reg_id = 0; reg_id < num_regs; reg_id++) {\n\t\tstruct reg *r = &armv7m->arm.core_cache->reg_list[reg_id];\n\t\tif (!r->exist)\n\t\t\tcontinue;\t/* skip non existent registers */\n\n\t\tr->dirty = false;\n\n\t\tunsigned int reg32_id;\n\t\tuint32_t offset;\n\t\tif (armv7m_map_reg_packing(reg_id, &reg32_id, &offset)) {\n\t\t\t/* Unpack a partial register from 32-bit container register */\n\t\t\tstruct reg *r32 = &armv7m->arm.core_cache->reg_list[reg32_id];\n\n\t\t\t/* The container register ought to precede all regs unpacked\n\t\t\t * from it in the reg_list. So the value should be ready\n\t\t\t * to unpack */\n\t\t\tassert(r32->valid);\n\t\t\tbuf_cpy(r32->value + offset, r->value, r->size);\n\n\t\t} else {\n\t\t\tassert(r->size == 32 || r->size == 64);\n\t\t\tbuf_set_u32(r->value, 0, 32, r_vals[ri++]);\n\n\t\t\tif (r->size == 64) {\n\t\t\t\tassert(reg_id >= ARMV7M_FPU_FIRST_REG && reg_id <= ARMV7M_FPU_LAST_REG);\n\t\t\t\t/* the odd part of FP register (S1, S3...) */\n\t\t\t\tbuf_set_u32(r->value + 4, 0, 32, r_vals[ri++]);\n\t\t\t}\n\t\t}\n\t\tr->valid = true;\n\t}\n\tassert(ri == wi);\n\n\treturn retval;\n}\n\nstatic int cortex_m_store_core_reg_u32(struct target *target,\n\t\tuint32_t regsel, uint32_t value)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint retval;\n\tuint32_t dcrdr;\n\tint64_t then;\n\n\t/* because the DCB_DCRDR is used for the emulated dcc channel\n\t * we have to save/restore the DCB_DCRDR when used */\n\tif (target->dbg_msg_enabled) {\n\t\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WNR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check if value is written into register */\n\tthen = timeval_ms();\n\twhile (1) {\n\t\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (cortex_m->dcb_dhcsr & S_REGRDY)\n\t\t\tbreak;\n\t\tif (timeval_ms() > then + DHCSR_S_REGRDY_TIMEOUT) {\n\t\t\tLOG_TARGET_ERROR(target, \"Timeout waiting for DCRDR transfer ready\");\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t}\n\t\tkeep_alive();\n\t}\n\n\tif (target->dbg_msg_enabled) {\n\t\t/* restore DCB_DCRDR - this needs to be in a separate\n\t\t * transaction otherwise the emulated DCC channel breaks */\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);\n\t}\n\n\treturn retval;\n}\n\nstatic int cortex_m_write_debug_halt_mask(struct target *target,\n\tuint32_t mask_on, uint32_t mask_off)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\n\t/* mask off status bits */\n\tcortex_m->dcb_dhcsr &= ~((0xFFFFul << 16) | mask_off);\n\t/* create new register mask */\n\tcortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;\n\n\treturn mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, cortex_m->dcb_dhcsr);\n}\n\nstatic int cortex_m_set_maskints(struct target *target, bool mask)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tif (!!(cortex_m->dcb_dhcsr & C_MASKINTS) != mask)\n\t\treturn cortex_m_write_debug_halt_mask(target, mask ? C_MASKINTS : 0, mask ? 0 : C_MASKINTS);\n\telse\n\t\treturn ERROR_OK;\n}\n\nstatic int cortex_m_set_maskints_for_halt(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tswitch (cortex_m->isrmasking_mode) {\n\t\tcase CORTEX_M_ISRMASK_AUTO:\n\t\t\t/* interrupts taken at resume, whether for step or run -> no mask */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\n\t\tcase CORTEX_M_ISRMASK_OFF:\n\t\t\t/* interrupts never masked */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\n\t\tcase CORTEX_M_ISRMASK_ON:\n\t\t\t/* interrupts always masked */\n\t\t\treturn cortex_m_set_maskints(target, true);\n\n\t\tcase CORTEX_M_ISRMASK_STEPONLY:\n\t\t\t/* interrupts masked for single step only -> mask now if MASKINTS\n\t\t\t * erratum, otherwise only mask before stepping */\n\t\t\treturn cortex_m_set_maskints(target, cortex_m->maskints_erratum);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_set_maskints_for_run(struct target *target)\n{\n\tswitch (target_to_cm(target)->isrmasking_mode) {\n\t\tcase CORTEX_M_ISRMASK_AUTO:\n\t\t\t/* interrupts taken at resume, whether for step or run -> no mask */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\n\t\tcase CORTEX_M_ISRMASK_OFF:\n\t\t\t/* interrupts never masked */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\n\t\tcase CORTEX_M_ISRMASK_ON:\n\t\t\t/* interrupts always masked */\n\t\t\treturn cortex_m_set_maskints(target, true);\n\n\t\tcase CORTEX_M_ISRMASK_STEPONLY:\n\t\t\t/* interrupts masked for single step only -> no mask */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_set_maskints_for_step(struct target *target)\n{\n\tswitch (target_to_cm(target)->isrmasking_mode) {\n\t\tcase CORTEX_M_ISRMASK_AUTO:\n\t\t\t/* the auto-interrupt should already be done -> mask */\n\t\t\treturn cortex_m_set_maskints(target, true);\n\n\t\tcase CORTEX_M_ISRMASK_OFF:\n\t\t\t/* interrupts never masked */\n\t\t\treturn cortex_m_set_maskints(target, false);\n\n\t\tcase CORTEX_M_ISRMASK_ON:\n\t\t\t/* interrupts always masked */\n\t\t\treturn cortex_m_set_maskints(target, true);\n\n\t\tcase CORTEX_M_ISRMASK_STEPONLY:\n\t\t\t/* interrupts masked for single step only -> mask */\n\t\t\treturn cortex_m_set_maskints(target, true);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_clear_halt(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tint retval;\n\n\t/* clear step if any */\n\tcortex_m_write_debug_halt_mask(target, C_HALT, C_STEP);\n\n\t/* Read Debug Fault Status Register */\n\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Clear Debug Fault Status */\n\tretval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_DFSR, cortex_m->nvic_dfsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_TARGET_DEBUG(target, \"NVIC_DFSR 0x%\" PRIx32 \"\", cortex_m->nvic_dfsr);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_single_step_core(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tint retval;\n\n\t/* Mask interrupts before clearing halt, if not done already.  This avoids\n\t * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing\n\t * HALT can put the core into an unknown state.\n\t */\n\tif (!(cortex_m->dcb_dhcsr & C_MASKINTS)) {\n\t\tretval = cortex_m_write_debug_halt_mask(target, C_MASKINTS, 0);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_TARGET_DEBUG(target, \"single step\");\n\n\t/* restore dhcsr reg */\n\tcortex_m_clear_halt(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_enable_fpb(struct target *target)\n{\n\tint retval = target_write_u32(target, FP_CTRL, 3);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check the fpb is actually enabled */\n\tuint32_t fpctrl;\n\tretval = target_read_u32(target, FP_CTRL, &fpctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (fpctrl & 1)\n\t\treturn ERROR_OK;\n\n\treturn ERROR_FAIL;\n}\n\nstatic int cortex_m_endreset_event(struct target *target)\n{\n\tint retval;\n\tuint32_t dcb_demcr;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tstruct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;\n\tstruct cortex_m_fp_comparator *fp_list = cortex_m->fp_comparator_list;\n\tstruct cortex_m_dwt_comparator *dwt_list = cortex_m->dwt_comparator_list;\n\n\t/* REVISIT The four debug monitor bits are currently ignored... */\n\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &dcb_demcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_TARGET_DEBUG(target, \"DCB_DEMCR = 0x%8.8\" PRIx32 \"\", dcb_demcr);\n\n\t/* this register is used for emulated dcc channel */\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {\n\t\t/* Enable debug requests */\n\t\tretval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Restore proper interrupt masking setting for running CPU. */\n\tcortex_m_set_maskints_for_run(target);\n\n\t/* Enable features controlled by ITM and DWT blocks, and catch only\n\t * the vectors we were told to pay attention to.\n\t *\n\t * Target firmware is responsible for all fault handling policy\n\t * choices *EXCEPT* explicitly scripted overrides like \"vector_catch\"\n\t * or manual updates to the NVIC SHCSR and CCR registers.\n\t */\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, TRCENA | armv7m->demcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Paranoia: evidently some (early?) chips don't preserve all the\n\t * debug state (including FPB, DWT, etc) across reset...\n\t */\n\n\t/* Enable FPB */\n\tretval = cortex_m_enable_fpb(target);\n\tif (retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to enable the FPB\");\n\t\treturn retval;\n\t}\n\n\tcortex_m->fpb_enabled = true;\n\n\t/* Restore FPB registers */\n\tfor (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {\n\t\tretval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Restore DWT registers */\n\tfor (unsigned int i = 0; i < cortex_m->dwt_num_comp; i++) {\n\t\tretval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,\n\t\t\t\tdwt_list[i].comp);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 4,\n\t\t\t\tdwt_list[i].mask);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,\n\t\t\t\tdwt_list[i].function);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tretval = dap_run(swjdp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\t/* TODO: invalidate also working areas (needed in the case of detected reset).\n\t * Doing so will require flash drivers to test if working area\n\t * is still valid in all target algo calling loops.\n\t */\n\n\t/* make sure we have latest dhcsr flags */\n\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn retval;\n}\n\nstatic int cortex_m_examine_debug_reason(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\t/* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason\n\t * only check the debug reason if we don't know it already */\n\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\t\tif (cortex_m->nvic_dfsr & DFSR_BKPT) {\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tif (cortex_m->nvic_dfsr & DFSR_DWTTRAP)\n\t\t\t\ttarget->debug_reason = DBG_REASON_WPTANDBKPT;\n\t\t} else if (cortex_m->nvic_dfsr & DFSR_DWTTRAP)\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\telse if (cortex_m->nvic_dfsr & DFSR_VCATCH)\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\telse if (cortex_m->nvic_dfsr & DFSR_EXTERNAL)\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\telse\t/* HALTED */\n\t\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_examine_exception_reason(struct target *target)\n{\n\tuint32_t shcsr = 0, except_sr = 0, cfsr = -1, except_ar = -1;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct adiv5_dap *swjdp = armv7m->arm.dap;\n\tint retval;\n\n\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SHCSR, &shcsr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tswitch (armv7m->exception_number) {\n\t\tcase 2:\t/* NMI */\n\t\t\tbreak;\n\t\tcase 3:\t/* Hard Fault */\n\t\t\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_HFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (except_sr & 0x40000000) {\n\t\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &cfsr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 4:\t/* Memory Management */\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_MMFAR, &except_ar);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\tcase 5:\t/* Bus Fault */\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_BFAR, &except_ar);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\tcase 6:\t/* Usage Fault */\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\tcase 7:\t/* Secure Fault */\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFAR, &except_ar);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\tcase 11:\t/* SVCall */\n\t\t\tbreak;\n\t\tcase 12:\t/* Debug Monitor */\n\t\t\tretval = mem_ap_read_u32(armv7m->debug_ap, NVIC_DFSR, &except_sr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tbreak;\n\t\tcase 14:\t/* PendSV */\n\t\t\tbreak;\n\t\tcase 15:\t/* SysTick */\n\t\t\tbreak;\n\t\tdefault:\n\t\t\texcept_sr = 0;\n\t\t\tbreak;\n\t}\n\tretval = dap_run(swjdp);\n\tif (retval == ERROR_OK)\n\t\tLOG_TARGET_DEBUG(target, \"%s SHCSR 0x%\" PRIx32 \", SR 0x%\" PRIx32\n\t\t\t\", CFSR 0x%\" PRIx32 \", AR 0x%\" PRIx32,\n\t\t\tarmv7m_exception_string(armv7m->exception_number),\n\t\t\tshcsr, except_sr, cfsr, except_ar);\n\treturn retval;\n}\n\nstatic int cortex_m_debug_entry(struct target *target)\n{\n\tuint32_t xpsr;\n\tint retval;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tstruct arm *arm = &armv7m->arm;\n\tstruct reg *r;\n\n\tLOG_TARGET_DEBUG(target, \" \");\n\n\t/* Do this really early to minimize the window where the MASKINTS erratum\n\t * can pile up pending interrupts. */\n\tcortex_m_set_maskints_for_halt(target);\n\n\tcortex_m_clear_halt(target);\n\n\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = armv7m->examine_debug_reason(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* examine PE security state */\n\tuint32_t dscsr = 0;\n\tif (armv7m->arm.arch == ARM_ARCH_V8M) {\n\t\tretval = mem_ap_read_u32(armv7m->debug_ap, DCB_DSCSR, &dscsr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* Load all registers to arm.core_cache */\n\tif (!cortex_m->slow_register_read) {\n\t\tretval = cortex_m_fast_read_all_regs(target);\n\t\tif (retval == ERROR_TIMEOUT_REACHED) {\n\t\t\tcortex_m->slow_register_read = true;\n\t\t\tLOG_TARGET_DEBUG(target, \"Switched to slow register read\");\n\t\t}\n\t}\n\n\tif (cortex_m->slow_register_read)\n\t\tretval = cortex_m_slow_read_all_regs(target);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tr = arm->cpsr;\n\txpsr = buf_get_u32(r->value, 0, 32);\n\n\t/* Are we in an exception handler */\n\tif (xpsr & 0x1FF) {\n\t\tarmv7m->exception_number = (xpsr & 0x1FF);\n\n\t\tarm->core_mode = ARM_MODE_HANDLER;\n\t\tarm->map = armv7m_msp_reg_map;\n\t} else {\n\t\tunsigned control = buf_get_u32(arm->core_cache\n\t\t\t\t->reg_list[ARMV7M_CONTROL].value, 0, 3);\n\n\t\t/* is this thread privileged? */\n\t\tarm->core_mode = control & 1\n\t\t\t? ARM_MODE_USER_THREAD\n\t\t\t: ARM_MODE_THREAD;\n\n\t\t/* which stack is it using? */\n\t\tif (control & 2)\n\t\t\tarm->map = armv7m_psp_reg_map;\n\t\telse\n\t\t\tarm->map = armv7m_msp_reg_map;\n\n\t\tarmv7m->exception_number = 0;\n\t}\n\n\tif (armv7m->exception_number)\n\t\tcortex_m_examine_exception_reason(target);\n\n\tbool secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS;\n\tLOG_TARGET_DEBUG(target, \"entered debug state in core mode: %s at PC 0x%\" PRIx32\n\t\t\t\", cpu in %s state, target->state: %s\",\n\t\tarm_mode_name(arm->core_mode),\n\t\tbuf_get_u32(arm->pc->value, 0, 32),\n\t\tsecure_state ? \"Secure\" : \"Non-Secure\",\n\t\ttarget_state_name(target));\n\n\tif (armv7m->post_debug_entry) {\n\t\tretval = armv7m->post_debug_entry(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_poll_one(struct target *target)\n{\n\tint detected_failure = ERROR_OK;\n\tint retval = ERROR_OK;\n\tenum target_state prev_target_state = target->state;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\n\t/* Read from Debug Halting Control and Status Register */\n\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\tif (retval != ERROR_OK) {\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\treturn retval;\n\t}\n\n\t/* Recover from lockup.  See ARMv7-M architecture spec,\n\t * section B1.5.15 \"Unrecoverable exception cases\".\n\t */\n\tif (cortex_m->dcb_dhcsr & S_LOCKUP) {\n\t\tLOG_TARGET_ERROR(target, \"clearing lockup after double fault\");\n\t\tcortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t/* We have to execute the rest (the \"finally\" equivalent, but\n\t\t * still throw this exception again).\n\t\t */\n\t\tdetected_failure = ERROR_FAIL;\n\n\t\t/* refresh status bits */\n\t\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (cortex_m->dcb_dhcsr_cumulated_sticky & S_RESET_ST) {\n\t\tcortex_m->dcb_dhcsr_cumulated_sticky &= ~S_RESET_ST;\n\t\tif (target->state != TARGET_RESET) {\n\t\t\ttarget->state = TARGET_RESET;\n\t\t\tLOG_TARGET_INFO(target, \"external reset detected\");\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_RESET) {\n\t\t/* Cannot switch context while running so endreset is\n\t\t * called with target->state == TARGET_RESET\n\t\t */\n\t\tLOG_TARGET_DEBUG(target, \"Exit from reset with dcb_dhcsr 0x%\" PRIx32,\n\t\t\tcortex_m->dcb_dhcsr);\n\t\tretval = cortex_m_endreset_event(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\ttarget->state = TARGET_UNKNOWN;\n\t\t\treturn retval;\n\t\t}\n\t\ttarget->state = TARGET_RUNNING;\n\t\tprev_target_state = TARGET_RUNNING;\n\t}\n\n\tif (cortex_m->dcb_dhcsr & S_HALT) {\n\t\ttarget->state = TARGET_HALTED;\n\n\t\tif ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {\n\t\t\tretval = cortex_m_debug_entry(target);\n\n\t\t\t/* arm_semihosting needs to know registers, don't run if debug entry returned error */\n\t\t\tif (retval == ERROR_OK && arm_semihosting(target, &retval) != 0)\n\t\t\t\treturn retval;\n\n\t\t\tif (target->smp) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"postpone target event 'halted'\");\n\t\t\t\ttarget->smp_halt_event_postponed = true;\n\t\t\t} else {\n\t\t\t\t/* regardless of errors returned in previous code update state */\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t}\n\t\t}\n\t\tif (prev_target_state == TARGET_DEBUG_RUNNING) {\n\t\t\tretval = cortex_m_debug_entry(target);\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN) {\n\t\t/* Check if processor is retiring instructions or sleeping.\n\t\t * Unlike S_RESET_ST here we test if the target *is* running now,\n\t\t * not if it has been running (possibly in the past). Instructions are\n\t\t * typically processed much faster than OpenOCD polls DHCSR so S_RETIRE_ST\n\t\t * is read always 1. That's the reason not to use dcb_dhcsr_cumulated_sticky.\n\t\t */\n\t\tif (cortex_m->dcb_dhcsr & S_RETIRE_ST || cortex_m->dcb_dhcsr & S_SLEEP) {\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\tretval = ERROR_OK;\n\t\t}\n\t}\n\n\t/* Check that target is truly halted, since the target could be resumed externally */\n\tif ((prev_target_state == TARGET_HALTED) && !(cortex_m->dcb_dhcsr & S_HALT)) {\n\t\t/* registers are now invalid */\n\t\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\t\ttarget->state = TARGET_RUNNING;\n\t\tLOG_TARGET_WARNING(target, \"external resume detected\");\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tretval = ERROR_OK;\n\t}\n\n\t/* Did we detect a failure condition that we cleared? */\n\tif (detected_failure != ERROR_OK)\n\t\tretval = detected_failure;\n\treturn retval;\n}\n\nstatic int cortex_m_halt_one(struct target *target);\n\nstatic int cortex_m_smp_halt_all(struct list_head *smp_targets)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\tif (curr->state == TARGET_HALTED)\n\t\t\tcontinue;\n\n\t\tint ret2 = cortex_m_halt_one(curr);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ret2;\t/* store the first error code ignore others */\n\t}\n\treturn retval;\n}\n\nstatic int cortex_m_smp_post_halt_poll(struct list_head *smp_targets)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\t/* skip targets that were already halted */\n\t\tif (curr->state == TARGET_HALTED)\n\t\t\tcontinue;\n\n\t\tint ret2 = cortex_m_poll_one(curr);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ret2;\t/* store the first error code ignore others */\n\t}\n\treturn retval;\n}\n\nstatic int cortex_m_poll_smp(struct list_head *smp_targets)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\tbool halted = false;\n\n\tforeach_smp_target(head, smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (curr->smp_halt_event_postponed) {\n\t\t\thalted = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (halted) {\n\t\tretval = cortex_m_smp_halt_all(smp_targets);\n\n\t\tint ret2 = cortex_m_smp_post_halt_poll(smp_targets);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = ret2;\t/* store the first error code ignore others */\n\n\t\tforeach_smp_target(head, smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tif (!curr->smp_halt_event_postponed)\n\t\t\t\tcontinue;\n\n\t\t\tcurr->smp_halt_event_postponed = false;\n\t\t\tif (curr->state == TARGET_HALTED) {\n\t\t\t\tLOG_TARGET_DEBUG(curr, \"sending postponed target event 'halted'\");\n\t\t\t\ttarget_call_event_callbacks(curr, TARGET_EVENT_HALTED);\n\t\t\t}\n\t\t}\n\t\t/* There is no need to set gdb_service->target\n\t\t * as hwthread_update_threads() selects an interesting thread\n\t\t * by its own\n\t\t */\n\t}\n\treturn retval;\n}\n\nstatic int cortex_m_poll(struct target *target)\n{\n\tint retval = cortex_m_poll_one(target);\n\n\tif (target->smp) {\n\t\tstruct target_list *last;\n\t\tlast = list_last_entry(target->smp_targets, struct target_list, lh);\n\t\tif (target == last->target)\n\t\t\t/* After the last target in SMP group has been polled\n\t\t\t * check for postponed halted events and eventually halt and re-poll\n\t\t\t * other targets */\n\t\t\tcortex_m_poll_smp(target->smp_targets);\n\t}\n\treturn retval;\n}\n\nstatic int cortex_m_halt_one(struct target *target)\n{\n\tLOG_TARGET_DEBUG(target, \"target->state: %s\", target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_TARGET_DEBUG(target, \"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_TARGET_WARNING(target, \"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {\n\t\t\tLOG_TARGET_ERROR(target, \"can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\t/* we came here in a reset_halt or reset_init sequence\n\t\t\t * debug entry was already prepared in cortex_m3_assert_reset()\n\t\t\t */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* Write to Debug Halting Control and Status Register */\n\tcortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\n\t/* Do this really early to minimize the window where the MASKINTS erratum\n\t * can pile up pending interrupts. */\n\tcortex_m_set_maskints_for_halt(target);\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_halt(struct target *target)\n{\n\tif (target->smp)\n\t\treturn cortex_m_smp_halt_all(target->smp_targets);\n\telse\n\t\treturn cortex_m_halt_one(target);\n}\n\nstatic int cortex_m_soft_reset_halt(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tint retval, timeout = 0;\n\n\t/* on single cortex_m MCU soft_reset_halt should be avoided as same functionality\n\t * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.\n\t * As this reset only uses VC_CORERESET it would only ever reset the cortex_m\n\t * core, not the peripherals */\n\tLOG_TARGET_DEBUG(target, \"soft_reset_halt is discouraged, please use 'reset halt' instead.\");\n\n\tif (!cortex_m->vectreset_supported) {\n\t\tLOG_TARGET_ERROR(target, \"VECTRESET is not supported on this Cortex-M core\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Set C_DEBUGEN */\n\tretval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Enter debug state on reset; restore DEMCR in endreset_event() */\n\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,\n\t\t\tTRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Request a core-only reset */\n\tretval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,\n\t\t\tAIRCR_VECTKEY | AIRCR_VECTRESET);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget->state = TARGET_RESET;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(cortex_m->armv7m.arm.core_cache);\n\n\twhile (timeout < 100) {\n\t\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\t\tif (retval == ERROR_OK) {\n\t\t\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR,\n\t\t\t\t\t&cortex_m->nvic_dfsr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif ((cortex_m->dcb_dhcsr & S_HALT)\n\t\t\t\t&& (cortex_m->nvic_dfsr & DFSR_VCATCH)) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"system reset-halted, DHCSR 0x%08\" PRIx32 \", DFSR 0x%08\" PRIx32,\n\t\t\t\t\t\tcortex_m->dcb_dhcsr, cortex_m->nvic_dfsr);\n\t\t\t\tcortex_m_poll(target);\n\t\t\t\t/* FIXME restore user's vector catch config */\n\t\t\t\treturn ERROR_OK;\n\t\t\t} else {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"waiting for system reset-halt, \"\n\t\t\t\t\t\"DHCSR 0x%08\" PRIx32 \", %d ms\",\n\t\t\t\t\tcortex_m->dcb_dhcsr, timeout);\n\t\t\t}\n\t\t}\n\t\ttimeout++;\n\t\talive_sleep(1);\n\t}\n\n\treturn ERROR_OK;\n}\n\nvoid cortex_m_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\t/* set any pending breakpoints */\n\twhile (breakpoint) {\n\t\tif (!breakpoint->is_set)\n\t\t\tcortex_m_set_breakpoint(target, breakpoint);\n\t\tbreakpoint = breakpoint->next;\n\t}\n}\n\nstatic int cortex_m_restore_one(struct target *target, bool current,\n\ttarget_addr_t *address, bool handle_breakpoints, bool debug_execution)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct breakpoint *breakpoint = NULL;\n\tuint32_t resume_pc;\n\tstruct reg *r;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_ERROR(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tcortex_m_enable_breakpoints(target);\n\t\tcortex_m_enable_watchpoints(target);\n\t}\n\n\tif (debug_execution) {\n\t\tr = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK;\n\n\t\t/* Disable interrupts */\n\t\t/* We disable interrupts in the PRIMASK register instead of\n\t\t * masking with C_MASKINTS.  This is probably the same issue\n\t\t * as Cortex-M3 Erratum 377493 (fixed in r1p0):  C_MASKINTS\n\t\t * in parallel with disabled interrupts can cause local faults\n\t\t * to not be taken.\n\t\t *\n\t\t * This breaks non-debug (application) execution if not\n\t\t * called from armv7m_start_algorithm() which saves registers.\n\t\t */\n\t\tbuf_set_u32(r->value, 0, 1, 1);\n\t\tr->dirty = true;\n\t\tr->valid = true;\n\n\t\t/* Make sure we are in Thumb mode, set xPSR.T bit */\n\t\t/* armv7m_start_algorithm() initializes entire xPSR register.\n\t\t * This duplicity handles the case when cortex_m_resume()\n\t\t * is used with the debug_execution flag directly,\n\t\t * not called through armv7m_start_algorithm().\n\t\t */\n\t\tr = armv7m->arm.cpsr;\n\t\tbuf_set_u32(r->value, 24, 1, 1);\n\t\tr->dirty = true;\n\t\tr->valid = true;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tr = armv7m->arm.pc;\n\tif (!current) {\n\t\tbuf_set_u32(r->value, 0, 32, *address);\n\t\tr->dirty = true;\n\t\tr->valid = true;\n\t}\n\n\t/* if we halted last time due to a bkpt instruction\n\t * then we have to manually step over it, otherwise\n\t * the core will break again */\n\n\tif (!breakpoint_find(target, buf_get_u32(r->value, 0, 32))\n\t\t&& !debug_execution)\n\t\tarmv7m_maybe_skip_bkpt_inst(target, NULL);\n\n\tresume_pc = buf_get_u32(r->value, 0, 32);\n\tif (current)\n\t\t*address = resume_pc;\n\n\tint retval = armv7m_restore_context(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_TARGET_DEBUG(target, \"unset breakpoint at \" TARGET_ADDR_FMT \" (ID: %\" PRIu32 \")\",\n\t\t\t\tbreakpoint->address,\n\t\t\t\tbreakpoint->unique_id);\n\t\t\tretval = cortex_m_unset_breakpoint(target, breakpoint);\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tretval = cortex_m_single_step_core(target);\n\t\t\tint ret2 = cortex_m_set_breakpoint(target, breakpoint);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (ret2 != ERROR_OK)\n\t\t\t\treturn ret2;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_restart_one(struct target *target, bool debug_execution)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\t/* Restart core */\n\tcortex_m_set_maskints_for_run(target);\n\tcortex_m_write_debug_halt_mask(target, 0, C_HALT);\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t/* registers are now invalid */\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_restore_smp(struct target *target, bool handle_breakpoints)\n{\n\tstruct target_list *head;\n\ttarget_addr_t address;\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\t/* skip calling target */\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr))\n\t\t\tcontinue;\n\t\t/* skip running targets */\n\t\tif (curr->state == TARGET_RUNNING)\n\t\t\tcontinue;\n\n\t\tint retval = cortex_m_restore_one(curr, true, &address,\n\t\t\t\t\t\t\t\t\t\thandle_breakpoints, false);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = cortex_m_restart_one(curr, false);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_TARGET_DEBUG(curr, \"SMP resumed at \" TARGET_ADDR_FMT, address);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_resume(struct target *target, int current,\n\t\t\t\t\t\t   target_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tint retval = cortex_m_restore_one(target, !!current, &address, !!handle_breakpoints, !!debug_execution);\n\tif (retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"context restore failed, aborting resume\");\n\t\treturn retval;\n\t}\n\n\tif (target->smp && !debug_execution) {\n\t\tretval = cortex_m_restore_smp(target, !!handle_breakpoints);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_WARNING(\"resume of a SMP target failed, trying to resume current one\");\n\t}\n\n\tcortex_m_restart_one(target, !!debug_execution);\n\tif (retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"resume failed\");\n\t\treturn retval;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"%sresumed at \" TARGET_ADDR_FMT,\n\t\t\t\t\tdebug_execution ? \"debug \" : \"\", address);\n\n\treturn ERROR_OK;\n}\n\n/* int irqstepcount = 0; */\nstatic int cortex_m_step(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tstruct breakpoint *breakpoint = NULL;\n\tstruct reg *pc = armv7m->arm.pc;\n\tbool bkpt_inst_found = false;\n\tint retval;\n\tbool isr_timed_out = false;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Just one of SMP cores will step. Set the gdb control\n\t * target to current one or gdb miss gdb-end event */\n\tif (target->smp && target->gdb_service)\n\t\ttarget->gdb_service->target = target;\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tbuf_set_u32(pc->value, 0, 32, address);\n\t\tpc->dirty = true;\n\t\tpc->valid = true;\n\t}\n\n\tuint32_t pc_value = buf_get_u32(pc->value, 0, 32);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target, pc_value);\n\t\tif (breakpoint)\n\t\t\tcortex_m_unset_breakpoint(target, breakpoint);\n\t}\n\n\tarmv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tarmv7m_restore_context(target);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\t/* if no bkpt instruction is found at pc then we can perform\n\t * a normal step, otherwise we have to manually step over the bkpt\n\t * instruction - as such simulate a step */\n\tif (bkpt_inst_found == false) {\n\t\tif (cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO) {\n\t\t\t/* Automatic ISR masking mode off: Just step over the next\n\t\t\t * instruction, with interrupts on or off as appropriate. */\n\t\t\tcortex_m_set_maskints_for_step(target);\n\t\t\tcortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);\n\t\t} else {\n\t\t\t/* Process interrupts during stepping in a way they don't interfere\n\t\t\t * debugging.\n\t\t\t *\n\t\t\t * Principle:\n\t\t\t *\n\t\t\t * Set a temporary break point at the current pc and let the core run\n\t\t\t * with interrupts enabled. Pending interrupts get served and we run\n\t\t\t * into the breakpoint again afterwards. Then we step over the next\n\t\t\t * instruction with interrupts disabled.\n\t\t\t *\n\t\t\t * If the pending interrupts don't complete within time, we leave the\n\t\t\t * core running. This may happen if the interrupts trigger faster\n\t\t\t * than the core can process them or the handler doesn't return.\n\t\t\t *\n\t\t\t * If no more breakpoints are available we simply do a step with\n\t\t\t * interrupts enabled.\n\t\t\t *\n\t\t\t */\n\n\t\t\t/* 2012-09-29 ph\n\t\t\t *\n\t\t\t * If a break point is already set on the lower half word then a break point on\n\t\t\t * the upper half word will not break again when the core is restarted. So we\n\t\t\t * just step over the instruction with interrupts disabled.\n\t\t\t *\n\t\t\t * The documentation has no information about this, it was found by observation\n\t\t\t * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to\n\t\t\t * suffer from this problem.\n\t\t\t *\n\t\t\t * To add some confusion: pc_value has bit 0 always set, while the breakpoint\n\t\t\t * address has it always cleared. The former is done to indicate thumb mode\n\t\t\t * to gdb.\n\t\t\t *\n\t\t\t */\n\t\t\tif ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"Stepping over next instruction with interrupts disabled\");\n\t\t\t\tcortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);\n\t\t\t\tcortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);\n\t\t\t\t/* Re-enable interrupts if appropriate */\n\t\t\t\tcortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\t\t\t\tcortex_m_set_maskints_for_halt(target);\n\t\t\t} else {\n\n\t\t\t\t/* Set a temporary break point */\n\t\t\t\tif (breakpoint) {\n\t\t\t\t\tretval = cortex_m_set_breakpoint(target, breakpoint);\n\t\t\t\t} else {\n\t\t\t\t\tenum breakpoint_type type = BKPT_HARD;\n\t\t\t\t\tif (cortex_m->fp_rev == 0 && pc_value > 0x1FFFFFFF) {\n\t\t\t\t\t\t/* FPB rev.1 cannot handle such addr, try BKPT instr */\n\t\t\t\t\t\ttype = BKPT_SOFT;\n\t\t\t\t\t}\n\t\t\t\t\tretval = breakpoint_add(target, pc_value, 2, type);\n\t\t\t\t}\n\n\t\t\t\tbool tmp_bp_set = (retval == ERROR_OK);\n\n\t\t\t\t/* No more breakpoints left, just do a step */\n\t\t\t\tif (!tmp_bp_set) {\n\t\t\t\t\tcortex_m_set_maskints_for_step(target);\n\t\t\t\t\tcortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);\n\t\t\t\t\t/* Re-enable interrupts if appropriate */\n\t\t\t\t\tcortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\t\t\t\t\tcortex_m_set_maskints_for_halt(target);\n\t\t\t\t} else {\n\t\t\t\t\t/* Start the core */\n\t\t\t\t\tLOG_TARGET_DEBUG(target, \"Starting core to serve pending interrupts\");\n\t\t\t\t\tint64_t t_start = timeval_ms();\n\t\t\t\t\tcortex_m_set_maskints_for_run(target);\n\t\t\t\t\tcortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP);\n\n\t\t\t\t\t/* Wait for pending handlers to complete or timeout */\n\t\t\t\t\tdo {\n\t\t\t\t\t\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\ttarget->state = TARGET_UNKNOWN;\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tisr_timed_out = ((timeval_ms() - t_start) > 500);\n\t\t\t\t\t} while (!((cortex_m->dcb_dhcsr & S_HALT) || isr_timed_out));\n\n\t\t\t\t\t/* only remove breakpoint if we created it */\n\t\t\t\t\tif (breakpoint)\n\t\t\t\t\t\tcortex_m_unset_breakpoint(target, breakpoint);\n\t\t\t\t\telse {\n\t\t\t\t\t\t/* Remove the temporary breakpoint */\n\t\t\t\t\t\tbreakpoint_remove(target, pc_value);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isr_timed_out) {\n\t\t\t\t\t\tLOG_TARGET_DEBUG(target, \"Interrupt handlers didn't complete within time, \"\n\t\t\t\t\t\t\t\"leaving target running\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Step over next instruction with interrupts disabled */\n\t\t\t\t\t\tcortex_m_set_maskints_for_step(target);\n\t\t\t\t\t\tcortex_m_write_debug_halt_mask(target,\n\t\t\t\t\t\t\tC_HALT | C_MASKINTS,\n\t\t\t\t\t\t\t0);\n\t\t\t\t\t\tcortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);\n\t\t\t\t\t\t/* Re-enable interrupts if appropriate */\n\t\t\t\t\t\tcortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\t\t\t\t\t\tcortex_m_set_maskints_for_halt(target);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tretval = cortex_m_read_dhcsr_atomic_sticky(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\tif (breakpoint)\n\t\tcortex_m_set_breakpoint(target, breakpoint);\n\n\tif (isr_timed_out) {\n\t\t/* Leave the core running. The user has to stop execution manually. */\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t\ttarget->state = TARGET_RUNNING;\n\t\treturn ERROR_OK;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"target stepped dcb_dhcsr = 0x%\" PRIx32\n\t\t\" nvic_icsr = 0x%\" PRIx32,\n\t\tcortex_m->dcb_dhcsr, cortex_m->nvic_icsr);\n\n\tretval = cortex_m_debug_entry(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\tLOG_TARGET_DEBUG(target, \"target stepped dcb_dhcsr = 0x%\" PRIx32\n\t\t\" nvic_icsr = 0x%\" PRIx32,\n\t\tcortex_m->dcb_dhcsr, cortex_m->nvic_icsr);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_assert_reset(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tenum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;\n\n\tLOG_TARGET_DEBUG(target, \"target->state: %s,%s examined\",\n\t\ttarget_state_name(target),\n\t\ttarget_was_examined(target) ? \"\" : \" not\");\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {\n\t\t/* allow scripts to override the reset event */\n\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\t\tregister_cache_invalidate(cortex_m->armv7m.arm.core_cache);\n\t\ttarget->state = TARGET_RESET;\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* some cores support connecting while srst is asserted\n\t * use that mode is it has been configured */\n\n\tbool srst_asserted = false;\n\n\tif ((jtag_reset_config & RESET_HAS_SRST) &&\n\t\t((jtag_reset_config & RESET_SRST_NO_GATING) || !armv7m->debug_ap)) {\n\t\t/* If we have no debug_ap, asserting SRST is the only thing\n\t\t * we can do now */\n\t\tadapter_assert_reset();\n\t\tsrst_asserted = true;\n\t}\n\n\t/* TODO: replace the hack calling target_examine_one()\n\t * as soon as a better reset framework is available */\n\tif (!target_was_examined(target) && !target->defer_examine\n\t\t&& srst_asserted && (jtag_reset_config & RESET_SRST_NO_GATING)) {\n\t\tLOG_TARGET_DEBUG(target, \"Trying to re-examine under reset\");\n\t\ttarget_examine_one(target);\n\t}\n\n\t/* We need at least debug_ap to go further.\n\t * Inform user and bail out if we don't have one. */\n\tif (!armv7m->debug_ap) {\n\t\tif (srst_asserted) {\n\t\t\tif (target->reset_halt)\n\t\t\t\tLOG_TARGET_ERROR(target, \"Debug AP not available, will not halt after reset!\");\n\n\t\t\t/* Do not propagate error: reset was asserted, proceed to deassert! */\n\t\t\ttarget->state = TARGET_RESET;\n\t\t\tregister_cache_invalidate(cortex_m->armv7m.arm.core_cache);\n\t\t\treturn ERROR_OK;\n\n\t\t} else {\n\t\t\tLOG_TARGET_ERROR(target, \"Debug AP not available, reset NOT asserted!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* Enable debug requests */\n\tint retval = cortex_m_read_dhcsr_atomic_sticky(target);\n\n\t/* Store important errors instead of failing and proceed to reset assert */\n\n\tif (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))\n\t\tretval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);\n\n\t/* If the processor is sleeping in a WFI or WFE instruction, the\n\t * C_HALT bit must be asserted to regain control */\n\tif (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))\n\t\tretval = cortex_m_write_debug_halt_mask(target, C_HALT, 0);\n\n\tmem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);\n\t/* Ignore less important errors */\n\n\tif (!target->reset_halt) {\n\t\t/* Set/Clear C_MASKINTS in a separate operation */\n\t\tcortex_m_set_maskints_for_run(target);\n\n\t\t/* clear any debug flags before resuming */\n\t\tcortex_m_clear_halt(target);\n\n\t\t/* clear C_HALT in dhcsr reg */\n\t\tcortex_m_write_debug_halt_mask(target, 0, C_HALT);\n\t} else {\n\t\t/* Halt in debug on reset; endreset_event() restores DEMCR.\n\t\t *\n\t\t * REVISIT catching BUSERR presumably helps to defend against\n\t\t * bad vector table entries.  Should this include MMERR or\n\t\t * other flags too?\n\t\t */\n\t\tint retval2;\n\t\tretval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,\n\t\t\t\tTRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);\n\t\tif (retval != ERROR_OK || retval2 != ERROR_OK)\n\t\t\tLOG_TARGET_INFO(target, \"AP write error, reset will not halt\");\n\t}\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\t/* default to asserting srst */\n\t\tif (!srst_asserted)\n\t\t\tadapter_assert_reset();\n\n\t\t/* srst is asserted, ignore AP access errors */\n\t\tretval = ERROR_OK;\n\t} else {\n\t\t/* Use a standard Cortex-M3 software reset mechanism.\n\t\t * We default to using VECTRESET as it is supported on all current cores\n\t\t * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)\n\t\t * This has the disadvantage of not resetting the peripherals, so a\n\t\t * reset-init event handler is needed to perform any peripheral resets.\n\t\t */\n\t\tif (!cortex_m->vectreset_supported\n\t\t\t\t&& reset_config == CORTEX_M_RESET_VECTRESET) {\n\t\t\treset_config = CORTEX_M_RESET_SYSRESETREQ;\n\t\t\tLOG_TARGET_WARNING(target, \"VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.\");\n\t\t\tLOG_TARGET_WARNING(target, \"Set 'cortex_m reset_config sysresetreq'.\");\n\t\t}\n\n\t\tLOG_TARGET_DEBUG(target, \"Using Cortex-M %s\", (reset_config == CORTEX_M_RESET_SYSRESETREQ)\n\t\t\t? \"SYSRESETREQ\" : \"VECTRESET\");\n\n\t\tif (reset_config == CORTEX_M_RESET_VECTRESET) {\n\t\t\tLOG_TARGET_WARNING(target, \"Only resetting the Cortex-M core, use a reset-init event \"\n\t\t\t\t\"handler to reset any peripherals or configure hardware srst support.\");\n\t\t}\n\n\t\tint retval3;\n\t\tretval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,\n\t\t\t\tAIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)\n\t\t\t\t? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));\n\t\tif (retval3 != ERROR_OK)\n\t\t\tLOG_TARGET_DEBUG(target, \"Ignoring AP write error right after reset\");\n\n\t\tretval3 = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);\n\t\tif (retval3 != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"DP initialisation failed\");\n\t\t\t/* The error return value must not be propagated in this case.\n\t\t\t * SYSRESETREQ or VECTRESET have been possibly triggered\n\t\t\t * so reset processing should continue */\n\t\t} else {\n\t\t\t/* I do not know why this is necessary, but it\n\t\t\t * fixes strange effects (step/resume cause NMI\n\t\t\t * after reset) on LM3S6918 -- Michael Schwingen\n\t\t\t */\n\t\t\tuint32_t tmp;\n\t\t\tmem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);\n\t\t}\n\t}\n\n\ttarget->state = TARGET_RESET;\n\tjtag_sleep(50000);\n\n\tregister_cache_invalidate(cortex_m->armv7m.arm.core_cache);\n\n\t/* now return stored error code if any */\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->reset_halt && target_was_examined(target)) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_deassert_reset(struct target *target)\n{\n\tstruct armv7m_common *armv7m = &target_to_cm(target)->armv7m;\n\n\tLOG_TARGET_DEBUG(target, \"target->state: %s,%s examined\",\n\t\ttarget_state_name(target),\n\t\ttarget_was_examined(target) ? \"\" : \" not\");\n\n\t/* deassert reset lines */\n\tadapter_deassert_reset();\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif ((jtag_reset_config & RESET_HAS_SRST) &&\n\t\t!(jtag_reset_config & RESET_SRST_NO_GATING) &&\n\t\tarmv7m->debug_ap) {\n\n\t\tint retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"DP initialisation failed\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval;\n\tunsigned int fp_num = 0;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_TARGET_WARNING(target, \"breakpoint (BPID: %\" PRIu32 \") already set\", breakpoint->unique_id);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tuint32_t fpcr_value;\n\t\twhile (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))\n\t\t\tfp_num++;\n\t\tif (fp_num >= cortex_m->fp_num_code) {\n\t\t\tLOG_TARGET_ERROR(target, \"Can not find free FPB Comparator!\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint_hw_set(breakpoint, fp_num);\n\t\tfpcr_value = breakpoint->address | 1;\n\t\tif (cortex_m->fp_rev == 0) {\n\t\t\tif (breakpoint->address > 0x1FFFFFFF) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"Cortex-M Flash Patch Breakpoint rev.1 \"\n\t\t\t\t\t\t\"cannot handle HW breakpoint above address 0x1FFFFFFE\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tuint32_t hilo;\n\t\t\thilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;\n\t\t\tfpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1;\n\t\t} else if (cortex_m->fp_rev > 1) {\n\t\t\tLOG_TARGET_ERROR(target, \"Unhandled Cortex-M Flash Patch Breakpoint architecture revision\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tcomparator_list[fp_num].used = true;\n\t\tcomparator_list[fp_num].fpcr_value = fpcr_value;\n\t\ttarget_write_u32(target, comparator_list[fp_num].fpcr_address,\n\t\t\tcomparator_list[fp_num].fpcr_value);\n\t\tLOG_TARGET_DEBUG(target, \"fpc_num %i fpcr_value 0x%\" PRIx32 \"\",\n\t\t\tfp_num,\n\t\t\tcomparator_list[fp_num].fpcr_value);\n\t\tif (!cortex_m->fpb_enabled) {\n\t\t\tLOG_TARGET_DEBUG(target, \"FPB wasn't enabled, do it now\");\n\t\t\tretval = cortex_m_enable_fpb(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"Failed to enable the FPB\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tcortex_m->fpb_enabled = true;\n\t\t}\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tuint8_t code[4];\n\n\t\t/* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for\n\t\t * semihosting; don't use that.  Otherwise the BKPT\n\t\t * parameter is arbitrary.\n\t\t */\n\t\tbuf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));\n\t\tretval = target_read_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\tbreakpoint->length, 1,\n\t\t\t\tbreakpoint->orig_instr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_write_memory(target,\n\t\t\t\tbreakpoint->address & 0xFFFFFFFE,\n\t\t\t\tbreakpoint->length, 1,\n\t\t\t\tcode);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbreakpoint->is_set = true;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"BPID: %\" PRIu32 \", Type: %d, Address: \" TARGET_ADDR_FMT \" Length: %d (n=%u)\",\n\t\tbreakpoint->unique_id,\n\t\t(int)(breakpoint->type),\n\t\tbreakpoint->address,\n\t\tbreakpoint->length,\n\t\t(breakpoint->type == BKPT_SOFT) ? 0 : breakpoint->number);\n\n\treturn ERROR_OK;\n}\n\nint cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tint retval;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_TARGET_WARNING(target, \"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"BPID: %\" PRIu32 \", Type: %d, Address: \" TARGET_ADDR_FMT \" Length: %d (n=%u)\",\n\t\tbreakpoint->unique_id,\n\t\t(int)(breakpoint->type),\n\t\tbreakpoint->address,\n\t\tbreakpoint->length,\n\t\t(breakpoint->type == BKPT_SOFT) ? 0 : breakpoint->number);\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tunsigned int fp_num = breakpoint->number;\n\t\tif (fp_num >= cortex_m->fp_num_code) {\n\t\t\tLOG_TARGET_DEBUG(target, \"Invalid FP Comparator number in breakpoint\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tcomparator_list[fp_num].used = false;\n\t\tcomparator_list[fp_num].fpcr_value = 0;\n\t\ttarget_write_u32(target, comparator_list[fp_num].fpcr_address,\n\t\t\tcomparator_list[fp_num].fpcr_value);\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tretval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE,\n\t\t\t\t\tbreakpoint->length, 1,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nint cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tif (breakpoint->length == 3) {\n\t\tLOG_TARGET_DEBUG(target, \"Using a two byte breakpoint for 32bit Thumb-2 request\");\n\t\tbreakpoint->length = 2;\n\t}\n\n\tif ((breakpoint->length != 2)) {\n\t\tLOG_TARGET_INFO(target, \"only breakpoints of two bytes length supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\treturn cortex_m_set_breakpoint(target, breakpoint);\n}\n\nint cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tif (!breakpoint->is_set)\n\t\treturn ERROR_OK;\n\n\treturn cortex_m_unset_breakpoint(target, breakpoint);\n}\n\nstatic int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tunsigned int dwt_num = 0;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\t/* REVISIT Don't fully trust these \"not used\" records ... users\n\t * may set up breakpoints by hand, e.g. dual-address data value\n\t * watchpoint using comparator #1; comparator #0 matching cycle\n\t * count; send data trace info through ITM and TPIU; etc\n\t */\n\tstruct cortex_m_dwt_comparator *comparator;\n\n\tfor (comparator = cortex_m->dwt_comparator_list;\n\t\tcomparator->used && dwt_num < cortex_m->dwt_num_comp;\n\t\tcomparator++, dwt_num++)\n\t\tcontinue;\n\tif (dwt_num >= cortex_m->dwt_num_comp) {\n\t\tLOG_TARGET_ERROR(target, \"Can not find free DWT Comparator\");\n\t\treturn ERROR_FAIL;\n\t}\n\tcomparator->used = true;\n\twatchpoint_set(watchpoint, dwt_num);\n\n\tcomparator->comp = watchpoint->address;\n\ttarget_write_u32(target, comparator->dwt_comparator_address + 0,\n\t\tcomparator->comp);\n\n\tif ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) {\n\t\tuint32_t mask = 0, temp;\n\n\t\t/* watchpoint params were validated earlier */\n\t\ttemp = watchpoint->length;\n\t\twhile (temp) {\n\t\t\ttemp >>= 1;\n\t\t\tmask++;\n\t\t}\n\t\tmask--;\n\n\t\tcomparator->mask = mask;\n\t\ttarget_write_u32(target, comparator->dwt_comparator_address + 4,\n\t\t\tcomparator->mask);\n\n\t\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tcomparator->function = 5;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tcomparator->function = 6;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tcomparator->function = 7;\n\t\t\tbreak;\n\t\t}\n\t} else {\n\t\tuint32_t data_size = watchpoint->length >> 1;\n\t\tcomparator->mask = (watchpoint->length >> 1) | 1;\n\n\t\tswitch (watchpoint->rw) {\n\t\tcase WPT_ACCESS:\n\t\t\tcomparator->function = 4;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tcomparator->function = 5;\n\t\t\tbreak;\n\t\tcase WPT_READ:\n\t\t\tcomparator->function = 6;\n\t\t\tbreak;\n\t\t}\n\t\tcomparator->function = comparator->function | (1 << 4) |\n\t\t\t\t(data_size << 10);\n\t}\n\n\ttarget_write_u32(target, comparator->dwt_comparator_address + 8,\n\t\tcomparator->function);\n\n\tLOG_TARGET_DEBUG(target, \"Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x\",\n\t\twatchpoint->unique_id, dwt_num,\n\t\t(unsigned) comparator->comp,\n\t\t(unsigned) comparator->mask,\n\t\t(unsigned) comparator->function);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct cortex_m_dwt_comparator *comparator;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_TARGET_WARNING(target, \"watchpoint (wpid: %d) not set\",\n\t\t\twatchpoint->unique_id);\n\t\treturn ERROR_OK;\n\t}\n\n\tunsigned int dwt_num = watchpoint->number;\n\n\tLOG_TARGET_DEBUG(target, \"Watchpoint (ID %d) DWT%u address: 0x%08x clear\",\n\t\twatchpoint->unique_id, dwt_num,\n\t\t(unsigned) watchpoint->address);\n\n\tif (dwt_num >= cortex_m->dwt_num_comp) {\n\t\tLOG_TARGET_DEBUG(target, \"Invalid DWT Comparator number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\n\tcomparator = cortex_m->dwt_comparator_list + dwt_num;\n\tcomparator->used = false;\n\tcomparator->function = 0;\n\ttarget_write_u32(target, comparator->dwt_comparator_address + 8,\n\t\tcomparator->function);\n\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nint cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\tif (cortex_m->dwt_comp_available < 1) {\n\t\tLOG_TARGET_DEBUG(target, \"no comparators?\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* hardware doesn't support data value masking */\n\tif (watchpoint->mask != ~(uint32_t)0) {\n\t\tLOG_TARGET_DEBUG(target, \"watchpoint value masks not supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* hardware allows address masks of up to 32K */\n\tunsigned mask;\n\n\tfor (mask = 0; mask < 16; mask++) {\n\t\tif ((1u << mask) == watchpoint->length)\n\t\t\tbreak;\n\t}\n\tif (mask == 16) {\n\t\tLOG_TARGET_DEBUG(target, \"unsupported watchpoint length\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tif (watchpoint->address & ((1 << mask) - 1)) {\n\t\tLOG_TARGET_DEBUG(target, \"watchpoint address is unaligned\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Caller doesn't seem to be able to describe watching for data\n\t * values of zero; that flags \"no value\".\n\t *\n\t * REVISIT This DWT may well be able to watch for specific data\n\t * values.  Requires comparator #1 to set DATAVMATCH and match\n\t * the data, and another comparator (DATAVADDR0) matching addr.\n\t */\n\tif (watchpoint->value) {\n\t\tLOG_TARGET_DEBUG(target, \"data value watchpoint not YET supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tcortex_m->dwt_comp_available--;\n\tLOG_TARGET_DEBUG(target, \"dwt_comp_available: %d\", cortex_m->dwt_comp_available);\n\n\treturn ERROR_OK;\n}\n\nint cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\t/* REVISIT why check? DWT can be updated with core running ... */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\tcortex_m_unset_watchpoint(target, watchpoint);\n\n\tcortex_m->dwt_comp_available++;\n\tLOG_TARGET_DEBUG(target, \"dwt_comp_available: %d\", cortex_m->dwt_comp_available);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)\n{\n\tif (target->debug_reason != DBG_REASON_WATCHPOINT)\n\t\treturn ERROR_FAIL;\n\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\n\tfor (struct watchpoint *wp = target->watchpoints; wp; wp = wp->next) {\n\t\tif (!wp->is_set)\n\t\t\tcontinue;\n\n\t\tunsigned int dwt_num = wp->number;\n\t\tstruct cortex_m_dwt_comparator *comparator = cortex_m->dwt_comparator_list + dwt_num;\n\n\t\tuint32_t dwt_function;\n\t\tint retval = target_read_u32(target, comparator->dwt_comparator_address + 8, &dwt_function);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* check the MATCHED bit */\n\t\tif (dwt_function & BIT(24)) {\n\t\t\t*hit_watchpoint = wp;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nvoid cortex_m_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\t/* set any pending watchpoints */\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\tcortex_m_set_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n}\n\nstatic int cortex_m_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tif (armv7m->arm.arch == ARM_ARCH_V6M) {\n\t\t/* armv6m does not handle unaligned memory access */\n\t\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\treturn mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address);\n}\n\nstatic int cortex_m_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tif (armv7m->arm.arch == ARM_ARCH_V6M) {\n\t\t/* armv6m does not handle unaligned memory access */\n\t\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\treturn mem_ap_write_buf(armv7m->debug_ap, buffer, size, count, address);\n}\n\nstatic int cortex_m_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\tarmv7m_build_reg_cache(target);\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nvoid cortex_m_deinit_target(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\tif (!armv7m->is_hla_target && armv7m->debug_ap)\n\t\tdap_put_ap(armv7m->debug_ap);\n\n\tfree(cortex_m->fp_comparator_list);\n\n\tcortex_m_dwt_free(target);\n\tarmv7m_free_reg_cache(target);\n\n\tfree(target->private_config);\n\tfree(cortex_m);\n}\n\nint cortex_m_profiling(struct target *target, uint32_t *samples,\n\t\t\t      uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)\n{\n\tstruct timeval timeout, now;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tuint32_t reg_value;\n\tint retval;\n\n\tretval = target_read_u32(target, DWT_PCSR, &reg_value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Error while reading PCSR\");\n\t\treturn retval;\n\t}\n\tif (reg_value == 0) {\n\t\tLOG_TARGET_INFO(target, \"PCSR sampling not supported on this processor.\");\n\t\treturn target_profiling_default(target, samples, max_num_samples, num_samples, seconds);\n\t}\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, seconds, 0);\n\n\tLOG_TARGET_INFO(target, \"Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...\");\n\n\t/* Make sure the target is running */\n\ttarget_poll(target);\n\tif (target->state == TARGET_HALTED)\n\t\tretval = target_resume(target, 1, 0, 0, 0);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Error while resuming target\");\n\t\treturn retval;\n\t}\n\n\tuint32_t sample_count = 0;\n\n\tfor (;;) {\n\t\tif (armv7m && armv7m->debug_ap) {\n\t\t\tuint32_t read_count = max_num_samples - sample_count;\n\t\t\tif (read_count > 1024)\n\t\t\t\tread_count = 1024;\n\n\t\t\tretval = mem_ap_read_buf_noincr(armv7m->debug_ap,\n\t\t\t\t\t\t(void *)&samples[sample_count],\n\t\t\t\t\t\t4, read_count, DWT_PCSR);\n\t\t\tsample_count += read_count;\n\t\t} else {\n\t\t\ttarget_read_u32(target, DWT_PCSR, &samples[sample_count++]);\n\t\t}\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Error while reading PCSR\");\n\t\t\treturn retval;\n\t\t}\n\n\n\t\tgettimeofday(&now, NULL);\n\t\tif (sample_count >= max_num_samples || timeval_compare(&now, &timeout) > 0) {\n\t\t\tLOG_TARGET_INFO(target, \"Profiling completed. %\" PRIu32 \" samples.\", sample_count);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t*num_samples = sample_count;\n\treturn retval;\n}\n\n\n/* REVISIT cache valid/dirty bits are unmaintained.  We could set \"valid\"\n * on r/w if the core is not running, and clear on resume or reset ... or\n * at least, in a post_restore_context() method.\n */\n\nstruct dwt_reg_state {\n\tstruct target *target;\n\tuint32_t addr;\n\tuint8_t value[4];\t\t/* scratch/cache */\n};\n\nstatic int cortex_m_dwt_get_reg(struct reg *reg)\n{\n\tstruct dwt_reg_state *state = reg->arch_info;\n\n\tuint32_t tmp;\n\tint retval = target_read_u32(state->target, state->addr, &tmp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tbuf_set_u32(state->value, 0, 32, tmp);\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_dwt_set_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct dwt_reg_state *state = reg->arch_info;\n\n\treturn target_write_u32(state->target, state->addr,\n\t\t\tbuf_get_u32(buf, 0, reg->size));\n}\n\nstruct dwt_reg {\n\tuint32_t addr;\n\tconst char *name;\n\tunsigned size;\n};\n\nstatic const struct dwt_reg dwt_base_regs[] = {\n\t{ DWT_CTRL, \"dwt_ctrl\", 32, },\n\t/* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT:  it wrongly\n\t * increments while the core is asleep.\n\t */\n\t{ DWT_CYCCNT, \"dwt_cyccnt\", 32, },\n\t/* plus some 8 bit counters, useful for profiling with TPIU */\n};\n\nstatic const struct dwt_reg dwt_comp[] = {\n#define DWT_COMPARATOR(i) \\\n\t\t{ DWT_COMP0 + 0x10 * (i), \"dwt_\" #i \"_comp\", 32, }, \\\n\t\t{ DWT_MASK0 + 0x10 * (i), \"dwt_\" #i \"_mask\", 4, }, \\\n\t\t{ DWT_FUNCTION0 + 0x10 * (i), \"dwt_\" #i \"_function\", 32, }\n\tDWT_COMPARATOR(0),\n\tDWT_COMPARATOR(1),\n\tDWT_COMPARATOR(2),\n\tDWT_COMPARATOR(3),\n\tDWT_COMPARATOR(4),\n\tDWT_COMPARATOR(5),\n\tDWT_COMPARATOR(6),\n\tDWT_COMPARATOR(7),\n\tDWT_COMPARATOR(8),\n\tDWT_COMPARATOR(9),\n\tDWT_COMPARATOR(10),\n\tDWT_COMPARATOR(11),\n\tDWT_COMPARATOR(12),\n\tDWT_COMPARATOR(13),\n\tDWT_COMPARATOR(14),\n\tDWT_COMPARATOR(15),\n#undef DWT_COMPARATOR\n};\n\nstatic const struct reg_arch_type dwt_reg_type = {\n\t.get = cortex_m_dwt_get_reg,\n\t.set = cortex_m_dwt_set_reg,\n};\n\nstatic void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dwt_reg *d)\n{\n\tstruct dwt_reg_state *state;\n\n\tstate = calloc(1, sizeof(*state));\n\tif (!state)\n\t\treturn;\n\tstate->addr = d->addr;\n\tstate->target = t;\n\n\tr->name = d->name;\n\tr->size = d->size;\n\tr->value = state->value;\n\tr->arch_info = state;\n\tr->type = &dwt_reg_type;\n}\n\nstatic void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)\n{\n\tuint32_t dwtcr;\n\tstruct reg_cache *cache;\n\tstruct cortex_m_dwt_comparator *comparator;\n\tint reg;\n\n\ttarget_read_u32(target, DWT_CTRL, &dwtcr);\n\tLOG_TARGET_DEBUG(target, \"DWT_CTRL: 0x%\" PRIx32, dwtcr);\n\tif (!dwtcr) {\n\t\tLOG_TARGET_DEBUG(target, \"no DWT\");\n\t\treturn;\n\t}\n\n\ttarget_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch);\n\tLOG_TARGET_DEBUG(target, \"DWT_DEVARCH: 0x%\" PRIx32, cm->dwt_devarch);\n\n\tcm->dwt_num_comp = (dwtcr >> 28) & 0xF;\n\tcm->dwt_comp_available = cm->dwt_num_comp;\n\tcm->dwt_comparator_list = calloc(cm->dwt_num_comp,\n\t\t\tsizeof(struct cortex_m_dwt_comparator));\n\tif (!cm->dwt_comparator_list) {\nfail0:\n\t\tcm->dwt_num_comp = 0;\n\t\tLOG_TARGET_ERROR(target, \"out of mem\");\n\t\treturn;\n\t}\n\n\tcache = calloc(1, sizeof(*cache));\n\tif (!cache) {\nfail1:\n\t\tfree(cm->dwt_comparator_list);\n\t\tgoto fail0;\n\t}\n\tcache->name = \"Cortex-M DWT registers\";\n\tcache->num_regs = 2 + cm->dwt_num_comp * 3;\n\tcache->reg_list = calloc(cache->num_regs, sizeof(*cache->reg_list));\n\tif (!cache->reg_list) {\n\t\tfree(cache);\n\t\tgoto fail1;\n\t}\n\n\tfor (reg = 0; reg < 2; reg++)\n\t\tcortex_m_dwt_addreg(target, cache->reg_list + reg,\n\t\t\tdwt_base_regs + reg);\n\n\tcomparator = cm->dwt_comparator_list;\n\tfor (unsigned int i = 0; i < cm->dwt_num_comp; i++, comparator++) {\n\t\tint j;\n\n\t\tcomparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i;\n\t\tfor (j = 0; j < 3; j++, reg++)\n\t\t\tcortex_m_dwt_addreg(target, cache->reg_list + reg,\n\t\t\t\tdwt_comp + 3 * i + j);\n\n\t\t/* make sure we clear any watchpoints enabled on the target */\n\t\ttarget_write_u32(target, comparator->dwt_comparator_address + 8, 0);\n\t}\n\n\t*register_get_last_cache_p(&target->reg_cache) = cache;\n\tcm->dwt_cache = cache;\n\n\tLOG_TARGET_DEBUG(target, \"DWT dwtcr 0x%\" PRIx32 \", comp %d, watch%s\",\n\t\tdwtcr, cm->dwt_num_comp,\n\t\t(dwtcr & (0xf << 24)) ? \" only\" : \"/trigger\");\n\n\t/* REVISIT:  if num_comp > 1, check whether comparator #1 can\n\t * implement single-address data value watchpoints ... so we\n\t * won't need to check it later, when asked to set one up.\n\t */\n}\n\nstatic void cortex_m_dwt_free(struct target *target)\n{\n\tstruct cortex_m_common *cm = target_to_cm(target);\n\tstruct reg_cache *cache = cm->dwt_cache;\n\n\tfree(cm->dwt_comparator_list);\n\tcm->dwt_comparator_list = NULL;\n\tcm->dwt_num_comp = 0;\n\n\tif (cache) {\n\t\tregister_unlink_cache(&target->reg_cache, cache);\n\n\t\tif (cache->reg_list) {\n\t\t\tfor (size_t i = 0; i < cache->num_regs; i++)\n\t\t\t\tfree(cache->reg_list[i].arch_info);\n\t\t\tfree(cache->reg_list);\n\t\t}\n\t\tfree(cache);\n\t}\n\tcm->dwt_cache = NULL;\n}\n\nstatic bool cortex_m_has_tz(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tuint32_t dauthstatus;\n\n\tif (armv7m->arm.arch != ARM_ARCH_V8M)\n\t\treturn false;\n\n\tint retval = target_read_u32(target, DAUTHSTATUS, &dauthstatus);\n\tif (retval != ERROR_OK) {\n\t\tLOG_WARNING(\"Error reading DAUTHSTATUS register\");\n\t\treturn false;\n\t}\n\treturn (dauthstatus & DAUTHSTATUS_SID_MASK) != 0;\n}\n\n#define MVFR0 0xe000ef40\n#define MVFR1 0xe000ef44\n\n#define MVFR0_DEFAULT_M4 0x10110021\n#define MVFR1_DEFAULT_M4 0x11000011\n\n#define MVFR0_DEFAULT_M7_SP 0x10110021\n#define MVFR0_DEFAULT_M7_DP 0x10110221\n#define MVFR1_DEFAULT_M7_SP 0x11000011\n#define MVFR1_DEFAULT_M7_DP 0x12000011\n\nstatic int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,\n\t\tstruct adiv5_ap **debug_ap)\n{\n\tif (dap_find_get_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)\n\t\treturn ERROR_OK;\n\n\treturn dap_find_get_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);\n}\n\nint cortex_m_examine(struct target *target)\n{\n\tint retval;\n\tuint32_t cpuid, fpcr, mvfr0, mvfr1;\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\n\t/* hla_target shares the examine handler but does not support\n\t * all its calls */\n\tif (!armv7m->is_hla_target) {\n\t\tif (!armv7m->debug_ap) {\n\t\t\tif (cortex_m->apsel == DP_APSEL_INVALID) {\n\t\t\t\t/* Search for the MEM-AP */\n\t\t\t\tretval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tLOG_TARGET_ERROR(target, \"Could not find MEM-AP to control the core\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tarmv7m->debug_ap = dap_get_ap(swjdp, cortex_m->apsel);\n\t\t\t\tif (!armv7m->debug_ap) {\n\t\t\t\t\tLOG_ERROR(\"Cannot get AP\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tarmv7m->debug_ap->memaccess_tck = 8;\n\n\t\tretval = mem_ap_init(armv7m->debug_ap);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (!target_was_examined(target)) {\n\t\ttarget_set_examined(target);\n\n\t\t/* Read from Device Identification Registers */\n\t\tretval = target_read_u32(target, CPUID, &cpuid);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Get ARCH and CPU types */\n\t\tconst enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS;\n\n\t\tfor (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {\n\t\t\tif (core_partno == cortex_m_parts[n].partno) {\n\t\t\t\tcortex_m->core_info = &cortex_m_parts[n];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!cortex_m->core_info) {\n\t\t\tLOG_TARGET_ERROR(target, \"Cortex-M PARTNO 0x%x is unrecognized\", core_partno);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tarmv7m->arm.arch = cortex_m->core_info->arch;\n\n\t\tLOG_TARGET_INFO(target, \"%s r%\" PRId8 \"p%\" PRId8 \" processor detected\",\n\t\t\t\tcortex_m->core_info->name,\n\t\t\t\t(uint8_t)((cpuid >> 20) & 0xf),\n\t\t\t\t(uint8_t)((cpuid >> 0) & 0xf));\n\n\t\tcortex_m->maskints_erratum = false;\n\t\tif (core_partno == CORTEX_M7_PARTNO) {\n\t\t\tuint8_t rev, patch;\n\t\t\trev = (cpuid >> 20) & 0xf;\n\t\t\tpatch = (cpuid >> 0) & 0xf;\n\t\t\tif ((rev == 0) && (patch < 2)) {\n\t\t\t\tLOG_TARGET_WARNING(target, \"Silicon bug: single stepping may enter pending exception handler!\");\n\t\t\t\tcortex_m->maskints_erratum = true;\n\t\t\t}\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"cpuid: 0x%8.8\" PRIx32 \"\", cpuid);\n\n\t\tif (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {\n\t\t\ttarget_read_u32(target, MVFR0, &mvfr0);\n\t\t\ttarget_read_u32(target, MVFR1, &mvfr1);\n\n\t\t\t/* test for floating point feature on Cortex-M4 */\n\t\t\tif ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"%s floating point feature FPv4_SP found\", cortex_m->core_info->name);\n\t\t\t\tarmv7m->fp_feature = FPV4_SP;\n\t\t\t}\n\t\t} else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {\n\t\t\ttarget_read_u32(target, MVFR0, &mvfr0);\n\t\t\ttarget_read_u32(target, MVFR1, &mvfr1);\n\n\t\t\t/* test for floating point features on Cortex-M7 */\n\t\t\tif ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"%s floating point feature FPv5_SP found\", cortex_m->core_info->name);\n\t\t\t\tarmv7m->fp_feature = FPV5_SP;\n\t\t\t} else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"%s floating point feature FPv5_DP found\", cortex_m->core_info->name);\n\t\t\t\tarmv7m->fp_feature = FPV5_DP;\n\t\t\t}\n\t\t}\n\n\t\t/* VECTRESET is supported only on ARMv7-M cores */\n\t\tcortex_m->vectreset_supported = armv7m->arm.arch == ARM_ARCH_V7M;\n\n\t\t/* Check for FPU, otherwise mark FPU register as non-existent */\n\t\tif (armv7m->fp_feature == FP_NONE)\n\t\t\tfor (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++)\n\t\t\t\tarmv7m->arm.core_cache->reg_list[idx].exist = false;\n\n\t\tif (!cortex_m_has_tz(target))\n\t\t\tfor (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)\n\t\t\t\tarmv7m->arm.core_cache->reg_list[idx].exist = false;\n\n\t\tif (!armv7m->is_hla_target) {\n\t\t\tif (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K)\n\t\t\t\t/* Cortex-M3/M4 have 4096 bytes autoincrement range,\n\t\t\t\t * s. ARM IHI 0031C: MEM-AP 7.2.2 */\n\t\t\t\tarmv7m->debug_ap->tar_autoincr_block = (1 << 12);\n\t\t}\n\n\t\tretval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/*  Don't cumulate sticky S_RESET_ST at the very first read of DHCSR\n\t\t *  as S_RESET_ST may indicate a reset that happened long time ago\n\t\t *  (most probably the power-on reset before OpenOCD was started).\n\t\t *  As we are just initializing the debug system we do not need\n\t\t *  to call cortex_m_endreset_event() in the following poll.\n\t\t */\n\t\tif (!cortex_m->dcb_dhcsr_sticky_is_recent) {\n\t\t\tcortex_m->dcb_dhcsr_sticky_is_recent = true;\n\t\t\tif (cortex_m->dcb_dhcsr & S_RESET_ST) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"reset happened some time ago, ignore\");\n\t\t\t\tcortex_m->dcb_dhcsr &= ~S_RESET_ST;\n\t\t\t}\n\t\t}\n\t\tcortex_m_cumulate_dhcsr_sticky(cortex_m, cortex_m->dcb_dhcsr);\n\n\t\tif (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {\n\t\t\t/* Enable debug requests */\n\t\t\tuint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS);\n\n\t\t\tretval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tcortex_m->dcb_dhcsr = dhcsr;\n\t\t}\n\n\t\t/* Configure trace modules */\n\t\tretval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (armv7m->trace_config.itm_deferred_config)\n\t\t\tarmv7m_trace_itm_config(target);\n\n\t\t/* NOTE: FPB and DWT are both optional. */\n\n\t\t/* Setup FPB */\n\t\ttarget_read_u32(target, FP_CTRL, &fpcr);\n\t\t/* bits [14:12] and [7:4] */\n\t\tcortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);\n\t\tcortex_m->fp_num_lit = (fpcr >> 8) & 0xF;\n\t\t/* Detect flash patch revision, see RM DDI 0403E.b page C1-817.\n\t\t   Revision is zero base, fp_rev == 1 means Rev.2 ! */\n\t\tcortex_m->fp_rev = (fpcr >> 28) & 0xf;\n\t\tfree(cortex_m->fp_comparator_list);\n\t\tcortex_m->fp_comparator_list = calloc(\n\t\t\t\tcortex_m->fp_num_code + cortex_m->fp_num_lit,\n\t\t\t\tsizeof(struct cortex_m_fp_comparator));\n\t\tcortex_m->fpb_enabled = fpcr & 1;\n\t\tfor (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {\n\t\t\tcortex_m->fp_comparator_list[i].type =\n\t\t\t\t(i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;\n\t\t\tcortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;\n\n\t\t\t/* make sure we clear any breakpoints enabled on the target */\n\t\t\ttarget_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0);\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"FPB fpcr 0x%\" PRIx32 \", numcode %i, numlit %i\",\n\t\t\tfpcr,\n\t\t\tcortex_m->fp_num_code,\n\t\t\tcortex_m->fp_num_lit);\n\n\t\t/* Setup DWT */\n\t\tcortex_m_dwt_free(target);\n\t\tcortex_m_dwt_setup(cortex_m, target);\n\n\t\t/* These hardware breakpoints only work for code in flash! */\n\t\tLOG_TARGET_INFO(target, \"target has %d breakpoints, %d watchpoints\",\n\t\t\tcortex_m->fp_num_code,\n\t\t\tcortex_m->dwt_num_comp);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tuint16_t dcrdr;\n\tuint8_t buf[2];\n\tint retval;\n\n\tretval = mem_ap_read_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tdcrdr = target_buffer_get_u16(target, buf);\n\t*ctrl = (uint8_t)dcrdr;\n\t*value = (uint8_t)(dcrdr >> 8);\n\n\tLOG_TARGET_DEBUG(target, \"data 0x%x ctrl 0x%x\", *value, *ctrl);\n\n\t/* write ack back to software dcc register\n\t * signify we have read data */\n\tif (dcrdr & (1 << 0)) {\n\t\ttarget_buffer_set_u16(target, buf, 0);\n\t\tretval = mem_ap_write_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_target_request_data(struct target *target,\n\tuint32_t size, uint8_t *buffer)\n{\n\tuint8_t data;\n\tuint8_t ctrl;\n\tuint32_t i;\n\n\tfor (i = 0; i < (size * 4); i++) {\n\t\tint retval = cortex_m_dcc_read(target, &data, &ctrl);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbuffer[i] = data;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_handle_target_request(void *priv)\n{\n\tstruct target *target = priv;\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\n\tif (!target->dbg_msg_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->state == TARGET_RUNNING) {\n\t\tuint8_t data;\n\t\tuint8_t ctrl;\n\t\tint retval;\n\n\t\tretval = cortex_m_dcc_read(target, &data, &ctrl);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* check if we have data */\n\t\tif (ctrl & (1 << 0)) {\n\t\t\tuint32_t request;\n\n\t\t\t/* we assume target is quick enough */\n\t\t\trequest = data;\n\t\t\tfor (int i = 1; i <= 3; i++) {\n\t\t\t\tretval = cortex_m_dcc_read(target, &data, &ctrl);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\trequest |= ((uint32_t)data << (i * 8));\n\t\t\t}\n\t\t\ttarget_request(target, request);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_init_arch_info(struct target *target,\n\tstruct cortex_m_common *cortex_m, struct adiv5_dap *dap)\n{\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\n\tarmv7m_init_arch_info(target, armv7m);\n\n\t/* default reset mode is to use srst if fitted\n\t * if not it will use CORTEX_M3_RESET_VECTRESET */\n\tcortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;\n\n\tarmv7m->arm.dap = dap;\n\n\t/* register arch-specific functions */\n\tarmv7m->examine_debug_reason = cortex_m_examine_debug_reason;\n\n\tarmv7m->post_debug_entry = NULL;\n\n\tarmv7m->pre_restore_context = NULL;\n\n\tarmv7m->load_core_reg_u32 = cortex_m_load_core_reg_u32;\n\tarmv7m->store_core_reg_u32 = cortex_m_store_core_reg_u32;\n\n\ttarget_register_timer_callback(cortex_m_handle_target_request, 1,\n\t\tTARGET_TIMER_TYPE_PERIODIC, target);\n\n\treturn ERROR_OK;\n}\n\nstatic int cortex_m_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct adiv5_private_config *pc;\n\n\tpc = (struct adiv5_private_config *)target->private_config;\n\tif (adiv5_verify_config(pc) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tstruct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));\n\tif (!cortex_m) {\n\t\tLOG_TARGET_ERROR(target, \"No memory creating target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcortex_m->common_magic = CORTEX_M_COMMON_MAGIC;\n\tcortex_m->apsel = pc->ap_num;\n\n\tcortex_m_init_arch_info(target, cortex_m, pc->dap);\n\n\treturn ERROR_OK;\n}\n\n/*--------------------------------------------------------------------------*/\n\nstatic int cortex_m_verify_pointer(struct command_invocation *cmd,\n\tstruct cortex_m_common *cm)\n{\n\tif (!is_cortex_m_with_dap_access(cm)) {\n\t\tcommand_print(cmd, \"target is not a Cortex-M\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * Only stuff below this line should need to verify that its target\n * is a Cortex-M3.  Everything else should have indirected through the\n * cortexm3_target structure, which is only used with CM3 targets.\n */\n\nCOMMAND_HANDLER(handle_cortex_m_vector_catch_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tstruct armv7m_common *armv7m = &cortex_m->armv7m;\n\tuint32_t demcr = 0;\n\tint retval;\n\n\tstatic const struct {\n\t\tchar name[10];\n\t\tunsigned mask;\n\t} vec_ids[] = {\n\t\t{ \"hard_err\",   VC_HARDERR, },\n\t\t{ \"int_err\",    VC_INTERR, },\n\t\t{ \"bus_err\",    VC_BUSERR, },\n\t\t{ \"state_err\",  VC_STATERR, },\n\t\t{ \"chk_err\",    VC_CHKERR, },\n\t\t{ \"nocp_err\",   VC_NOCPERR, },\n\t\t{ \"mm_err\",     VC_MMERR, },\n\t\t{ \"reset\",      VC_CORERESET, },\n\t};\n\n\tretval = cortex_m_verify_pointer(CMD, cortex_m);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_TARGET_ERROR(target, \"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC > 0) {\n\t\tunsigned catch = 0;\n\n\t\tif (CMD_ARGC == 1) {\n\t\t\tif (strcmp(CMD_ARGV[0], \"all\") == 0) {\n\t\t\t\tcatch = VC_HARDERR | VC_INTERR | VC_BUSERR\n\t\t\t\t\t| VC_STATERR | VC_CHKERR | VC_NOCPERR\n\t\t\t\t\t| VC_MMERR | VC_CORERESET;\n\t\t\t\tgoto write;\n\t\t\t} else if (strcmp(CMD_ARGV[0], \"none\") == 0)\n\t\t\t\tgoto write;\n\t\t}\n\t\twhile (CMD_ARGC-- > 0) {\n\t\t\tunsigned i;\n\t\t\tfor (i = 0; i < ARRAY_SIZE(vec_ids); i++) {\n\t\t\t\tif (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0)\n\t\t\t\t\tcontinue;\n\t\t\t\tcatch |= vec_ids[i].mask;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i == ARRAY_SIZE(vec_ids)) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"No CM3 vector '%s'\", CMD_ARGV[CMD_ARGC]);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\nwrite:\n\t\t/* For now, armv7m->demcr only stores vector catch flags. */\n\t\tarmv7m->demcr = catch;\n\n\t\tdemcr &= ~0xffff;\n\t\tdemcr |= catch;\n\n\t\t/* write, but don't assume it stuck (why not??) */\n\t\tretval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, demcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* FIXME be sure to clear DEMCR on clean server shutdown.\n\t\t * Otherwise the vector catch hardware could fire when there's\n\t\t * no debugger hooked up, causing much confusion...\n\t\t */\n\t}\n\n\tfor (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {\n\t\tcommand_print(CMD, \"%9s: %s\", vec_ids[i].name,\n\t\t\t(demcr & vec_ids[i].mask) ? \"catch\" : \"ignore\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tint retval;\n\n\tstatic const struct nvp nvp_maskisr_modes[] = {\n\t\t{ .name = \"auto\", .value = CORTEX_M_ISRMASK_AUTO },\n\t\t{ .name = \"off\", .value = CORTEX_M_ISRMASK_OFF },\n\t\t{ .name = \"on\", .value = CORTEX_M_ISRMASK_ON },\n\t\t{ .name = \"steponly\", .value = CORTEX_M_ISRMASK_STEPONLY },\n\t\t{ .name = NULL, .value = -1 },\n\t};\n\tconst struct nvp *n;\n\n\n\tretval = cortex_m_verify_pointer(CMD, cortex_m);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC > 0) {\n\t\tn = nvp_name2value(nvp_maskisr_modes, CMD_ARGV[0]);\n\t\tif (!n->name)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tcortex_m->isrmasking_mode = n->value;\n\t\tcortex_m_set_maskints_for_halt(target);\n\t}\n\n\tn = nvp_value2name(nvp_maskisr_modes, cortex_m->isrmasking_mode);\n\tcommand_print(CMD, \"cortex_m interrupt mask %s\", n->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_cortex_m_reset_config_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tint retval;\n\tchar *reset_config;\n\n\tretval = cortex_m_verify_pointer(CMD, cortex_m);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC > 0) {\n\t\tif (strcmp(*CMD_ARGV, \"sysresetreq\") == 0)\n\t\t\tcortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ;\n\n\t\telse if (strcmp(*CMD_ARGV, \"vectreset\") == 0) {\n\t\t\tif (target_was_examined(target)\n\t\t\t\t\t&& !cortex_m->vectreset_supported)\n\t\t\t\tLOG_TARGET_WARNING(target, \"VECTRESET is not supported on your Cortex-M core!\");\n\t\t\telse\n\t\t\t\tcortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;\n\n\t\t} else\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tswitch (cortex_m->soft_reset_config) {\n\t\tcase CORTEX_M_RESET_SYSRESETREQ:\n\t\t\treset_config = \"sysresetreq\";\n\t\t\tbreak;\n\n\t\tcase CORTEX_M_RESET_VECTRESET:\n\t\t\treset_config = \"vectreset\";\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\treset_config = \"unknown\";\n\t\t\tbreak;\n\t}\n\n\tcommand_print(CMD, \"cortex_m reset_config %s\", reset_config);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration cortex_m_exec_command_handlers[] = {\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = handle_cortex_m_mask_interrupts_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"mask cortex_m interrupts\",\n\t\t.usage = \"['auto'|'on'|'off'|'steponly']\",\n\t},\n\t{\n\t\t.name = \"vector_catch\",\n\t\t.handler = handle_cortex_m_vector_catch_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure hardware vectors to trigger debug entry\",\n\t\t.usage = \"['all'|'none'|('bus_err'|'chk_err'|...)*]\",\n\t},\n\t{\n\t\t.name = \"reset_config\",\n\t\t.handler = handle_cortex_m_reset_config_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure software reset handling\",\n\t\t.usage = \"['sysresetreq'|'vectreset']\",\n\t},\n\t{\n\t\t.chain = smp_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration cortex_m_command_handlers[] = {\n\t{\n\t\t.chain = armv7m_command_handlers,\n\t},\n\t{\n\t\t.chain = armv7m_trace_command_handlers,\n\t},\n\t/* START_DEPRECATED_TPIU */\n\t{\n\t\t.chain = arm_tpiu_deprecated_command_handlers,\n\t},\n\t/* END_DEPRECATED_TPIU */\n\t{\n\t\t.name = \"cortex_m\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Cortex-M command group\",\n\t\t.usage = \"\",\n\t\t.chain = cortex_m_exec_command_handlers,\n\t},\n\t{\n\t\t.chain = rtt_target_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type cortexm_target = {\n\t.name = \"cortex_m\",\n\n\t.poll = cortex_m_poll,\n\t.arch_state = armv7m_arch_state,\n\n\t.target_request_data = cortex_m_target_request_data,\n\n\t.halt = cortex_m_halt,\n\t.resume = cortex_m_resume,\n\t.step = cortex_m_step,\n\n\t.assert_reset = cortex_m_assert_reset,\n\t.deassert_reset = cortex_m_deassert_reset,\n\t.soft_reset_halt = cortex_m_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = armv7m_get_gdb_reg_list,\n\n\t.read_memory = cortex_m_read_memory,\n\t.write_memory = cortex_m_write_memory,\n\t.checksum_memory = armv7m_checksum_memory,\n\t.blank_check_memory = armv7m_blank_check_memory,\n\n\t.run_algorithm = armv7m_run_algorithm,\n\t.start_algorithm = armv7m_start_algorithm,\n\t.wait_algorithm = armv7m_wait_algorithm,\n\n\t.add_breakpoint = cortex_m_add_breakpoint,\n\t.remove_breakpoint = cortex_m_remove_breakpoint,\n\t.add_watchpoint = cortex_m_add_watchpoint,\n\t.remove_watchpoint = cortex_m_remove_watchpoint,\n\t.hit_watchpoint = cortex_m_hit_watchpoint,\n\n\t.commands = cortex_m_command_handlers,\n\t.target_create = cortex_m_target_create,\n\t.target_jim_configure = adiv5_jim_configure,\n\t.init_target = cortex_m_init_target,\n\t.examine = cortex_m_examine,\n\t.deinit_target = cortex_m_deinit_target,\n\n\t.profiling = cortex_m_profiling,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/cortex_m.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2006 by Magnus Lundin                                   *\n *   lundin@mlu.mine.nu                                                    *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_CORTEX_M_H\n#define OPENOCD_TARGET_CORTEX_M_H\n\n#include \"armv7m.h\"\n#include \"helper/bits.h\"\n\n#define CORTEX_M_COMMON_MAGIC 0x1A451A45U\n\n#define SYSTEM_CONTROL_BASE 0x400FE000\n\n#define ITM_TER0\t0xE0000E00\n#define ITM_TPR\t\t0xE0000E40\n#define ITM_TCR\t\t0xE0000E80\n#define ITM_TCR_ITMENA_BIT\tBIT(0)\n#define ITM_TCR_BUSY_BIT\tBIT(23)\n#define ITM_LAR\t\t0xE0000FB0\n#define ITM_LAR_KEY\t0xC5ACCE55\n\n#define CPUID\t\t0xE000ED00\n\n#define ARM_CPUID_PARTNO_POS    4\n#define ARM_CPUID_PARTNO_MASK\t(0xFFF << ARM_CPUID_PARTNO_POS)\n\nenum cortex_m_partno {\n\tCORTEX_M_PARTNO_INVALID,\n\tSTAR_MC1_PARTNO    = 0x132,\n\tCORTEX_M0_PARTNO   = 0xC20,\n\tCORTEX_M1_PARTNO   = 0xC21,\n\tCORTEX_M3_PARTNO   = 0xC23,\n\tCORTEX_M4_PARTNO   = 0xC24,\n\tCORTEX_M7_PARTNO   = 0xC27,\n\tCORTEX_M0P_PARTNO  = 0xC60,\n\tCORTEX_M23_PARTNO  = 0xD20,\n\tCORTEX_M33_PARTNO  = 0xD21,\n\tCORTEX_M35P_PARTNO = 0xD31,\n\tCORTEX_M55_PARTNO  = 0xD22,\n};\n\n/* Relevant Cortex-M flags, used in struct cortex_m_part_info.flags */\n#define CORTEX_M_F_HAS_FPV4               BIT(0)\n#define CORTEX_M_F_HAS_FPV5               BIT(1)\n#define CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K  BIT(2)\n\nstruct cortex_m_part_info {\n\tenum cortex_m_partno partno;\n\tconst char *name;\n\tenum arm_arch arch;\n\tuint32_t flags;\n};\n\n/* Debug Control Block */\n#define DCB_DHCSR\t0xE000EDF0\n#define DCB_DCRSR\t0xE000EDF4\n#define DCB_DCRDR\t0xE000EDF8\n#define DCB_DEMCR\t0xE000EDFC\n#define DCB_DSCSR\t0xE000EE08\n\n#define DAUTHSTATUS\t0xE000EFB8\n#define DAUTHSTATUS_SID_MASK\t0x00000030\n\n#define DCRSR_WNR\tBIT(16)\n\n#define DWT_CTRL\t0xE0001000\n#define DWT_CYCCNT\t0xE0001004\n#define DWT_PCSR\t0xE000101C\n#define DWT_COMP0\t0xE0001020\n#define DWT_MASK0\t0xE0001024\n#define DWT_FUNCTION0\t0xE0001028\n#define DWT_DEVARCH\t\t0xE0001FBC\n\n#define DWT_DEVARCH_ARMV8M\t0x101A02\n\n#define FP_CTRL\t\t0xE0002000\n#define FP_REMAP\t0xE0002004\n#define FP_COMP0\t0xE0002008\n#define FP_COMP1\t0xE000200C\n#define FP_COMP2\t0xE0002010\n#define FP_COMP3\t0xE0002014\n#define FP_COMP4\t0xE0002018\n#define FP_COMP5\t0xE000201C\n#define FP_COMP6\t0xE0002020\n#define FP_COMP7\t0xE0002024\n\n#define FPU_CPACR\t0xE000ED88\n#define FPU_FPCCR\t0xE000EF34\n#define FPU_FPCAR\t0xE000EF38\n#define FPU_FPDSCR\t0xE000EF3C\n\n#define TPIU_SSPSR\t0xE0040000\n#define TPIU_CSPSR\t0xE0040004\n#define TPIU_ACPR\t0xE0040010\n#define TPIU_SPPR\t0xE00400F0\n#define TPIU_FFSR\t0xE0040300\n#define TPIU_FFCR\t0xE0040304\n#define TPIU_FSCR\t0xE0040308\n\n/* Maximum SWO prescaler value. */\n#define TPIU_ACPR_MAX_SWOSCALER\t0x1fff\n\n/* DCB_DHCSR bit and field definitions */\n#define DBGKEY\t\t(0xA05Ful << 16)\n#define C_DEBUGEN\tBIT(0)\n#define C_HALT\t\tBIT(1)\n#define C_STEP\t\tBIT(2)\n#define C_MASKINTS\tBIT(3)\n#define S_REGRDY\tBIT(16)\n#define S_HALT\t\tBIT(17)\n#define S_SLEEP\t\tBIT(18)\n#define S_LOCKUP\tBIT(19)\n#define S_RETIRE_ST\tBIT(24)\n#define S_RESET_ST\tBIT(25)\n\n/* DCB_DEMCR bit and field definitions */\n#define TRCENA\t\t\tBIT(24)\n#define VC_HARDERR\t\tBIT(10)\n#define VC_INTERR\t\tBIT(9)\n#define VC_BUSERR\t\tBIT(8)\n#define VC_STATERR\t\tBIT(7)\n#define VC_CHKERR\t\tBIT(6)\n#define VC_NOCPERR\t\tBIT(5)\n#define VC_MMERR\t\tBIT(4)\n#define VC_CORERESET\tBIT(0)\n\n/* DCB_DSCSR bit and field definitions */\n#define DSCSR_CDS\t\tBIT(16)\n\n/* NVIC registers */\n#define NVIC_ICTR\t\t0xE000E004\n#define NVIC_ISE0\t\t0xE000E100\n#define NVIC_ICSR\t\t0xE000ED04\n#define NVIC_AIRCR\t\t0xE000ED0C\n#define NVIC_SHCSR\t\t0xE000ED24\n#define NVIC_CFSR\t\t0xE000ED28\n#define NVIC_MMFSRB\t\t0xE000ED28\n#define NVIC_BFSRB\t\t0xE000ED29\n#define NVIC_USFSRH\t\t0xE000ED2A\n#define NVIC_HFSR\t\t0xE000ED2C\n#define NVIC_DFSR\t\t0xE000ED30\n#define NVIC_MMFAR\t\t0xE000ED34\n#define NVIC_BFAR\t\t0xE000ED38\n#define NVIC_SFSR\t\t0xE000EDE4\n#define NVIC_SFAR\t\t0xE000EDE8\n\n/* NVIC_AIRCR bits */\n#define AIRCR_VECTKEY\t\t(0x5FAul << 16)\n#define AIRCR_SYSRESETREQ\tBIT(2)\n#define AIRCR_VECTCLRACTIVE\tBIT(1)\n#define AIRCR_VECTRESET\t\tBIT(0)\n/* NVIC_SHCSR bits */\n#define SHCSR_BUSFAULTENA\tBIT(17)\n/* NVIC_DFSR bits */\n#define DFSR_HALTED\t\t\t1\n#define DFSR_BKPT\t\t\t2\n#define DFSR_DWTTRAP\t\t4\n#define DFSR_VCATCH\t\t\t8\n#define DFSR_EXTERNAL\t\t16\n\n#define FPCR_CODE 0\n#define FPCR_LITERAL 1\n#define FPCR_REPLACE_REMAP  (0ul << 30)\n#define FPCR_REPLACE_BKPT_LOW  (1ul << 30)\n#define FPCR_REPLACE_BKPT_HIGH  (2ul << 30)\n#define FPCR_REPLACE_BKPT_BOTH  (3ul << 30)\n\nstruct cortex_m_fp_comparator {\n\tbool used;\n\tint type;\n\tuint32_t fpcr_value;\n\tuint32_t fpcr_address;\n};\n\nstruct cortex_m_dwt_comparator {\n\tbool used;\n\tuint32_t comp;\n\tuint32_t mask;\n\tuint32_t function;\n\tuint32_t dwt_comparator_address;\n};\n\nenum cortex_m_soft_reset_config {\n\tCORTEX_M_RESET_SYSRESETREQ,\n\tCORTEX_M_RESET_VECTRESET,\n};\n\nenum cortex_m_isrmasking_mode {\n\tCORTEX_M_ISRMASK_AUTO,\n\tCORTEX_M_ISRMASK_OFF,\n\tCORTEX_M_ISRMASK_ON,\n\tCORTEX_M_ISRMASK_STEPONLY,\n};\n\nstruct cortex_m_common {\n\tunsigned int common_magic;\n\n\tstruct armv7m_common armv7m;\n\n\t/* Context information */\n\tuint32_t dcb_dhcsr;\n\tuint32_t dcb_dhcsr_cumulated_sticky;\n\t/* DCB DHCSR has been at least once read, so the sticky bits have been reset */\n\tbool dcb_dhcsr_sticky_is_recent;\n\tuint32_t nvic_dfsr;  /* Debug Fault Status Register - shows reason for debug halt */\n\tuint32_t nvic_icsr;  /* Interrupt Control State Register - shows active and pending IRQ */\n\n\t/* Flash Patch and Breakpoint (FPB) */\n\tunsigned int fp_num_lit;\n\tunsigned int fp_num_code;\n\tint fp_rev;\n\tbool fpb_enabled;\n\tstruct cortex_m_fp_comparator *fp_comparator_list;\n\n\t/* Data Watchpoint and Trace (DWT) */\n\tunsigned int dwt_num_comp;\n\tunsigned int dwt_comp_available;\n\tuint32_t dwt_devarch;\n\tstruct cortex_m_dwt_comparator *dwt_comparator_list;\n\tstruct reg_cache *dwt_cache;\n\n\tenum cortex_m_soft_reset_config soft_reset_config;\n\tbool vectreset_supported;\n\tenum cortex_m_isrmasking_mode isrmasking_mode;\n\n\tconst struct cortex_m_part_info *core_info;\n\n\tbool slow_register_read;\t/* A register has not been ready, poll S_REGRDY */\n\n\tuint64_t apsel;\n\n\t/* Whether this target has the erratum that makes C_MASKINTS not apply to\n\t * already pending interrupts */\n\tbool maskints_erratum;\n};\n\nstatic inline bool is_cortex_m_or_hla(const struct cortex_m_common *cortex_m)\n{\n\treturn cortex_m->common_magic == CORTEX_M_COMMON_MAGIC;\n}\n\nstatic inline bool is_cortex_m_with_dap_access(const struct cortex_m_common *cortex_m)\n{\n\tif (!is_cortex_m_or_hla(cortex_m))\n\t\treturn false;\n\n\treturn !cortex_m->armv7m.is_hla_target;\n}\n\n/**\n * @returns the pointer to the target specific struct\n * without matching a magic number.\n * Use in target specific service routines, where the correct\n * type of arch_info is certain.\n */\nstatic inline struct cortex_m_common *\ntarget_to_cm(struct target *target)\n{\n\treturn container_of(target->arch_info,\n\t\t\tstruct cortex_m_common, armv7m.arm);\n}\n\n/**\n * @returns the pointer to the target specific struct\n * or NULL if the magic number does not match.\n * Use in a flash driver or any place where mismatch of the arch_info\n * type can happen.\n */\nstatic inline struct cortex_m_common *\ntarget_to_cortex_m_safe(struct target *target)\n{\n\t/* Check the parent types first to prevent peeking memory too far\n\t * from arch_info pointer */\n\tif (!target_to_armv7m_safe(target))\n\t\treturn NULL;\n\n\tstruct cortex_m_common *cortex_m = target_to_cm(target);\n\tif (!is_cortex_m_or_hla(cortex_m))\n\t\treturn NULL;\n\n\treturn cortex_m;\n}\n\n/**\n * @returns cached value of Cortex-M part number\n * or CORTEX_M_PARTNO_INVALID if the magic number does not match\n * or core_info is not initialised.\n */\nstatic inline enum cortex_m_partno cortex_m_get_partno_safe(struct target *target)\n{\n\tstruct cortex_m_common *cortex_m = target_to_cortex_m_safe(target);\n\tif (!cortex_m)\n\t\treturn CORTEX_M_PARTNO_INVALID;\n\n\tif (!cortex_m->core_info)\n\t\treturn CORTEX_M_PARTNO_INVALID;\n\n\treturn cortex_m->core_info->partno;\n}\n\nint cortex_m_examine(struct target *target);\nint cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint);\nint cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint);\nint cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint);\nvoid cortex_m_enable_breakpoints(struct target *target);\nvoid cortex_m_enable_watchpoints(struct target *target);\nvoid cortex_m_deinit_target(struct target *target);\nint cortex_m_profiling(struct target *target, uint32_t *samples,\n\tuint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);\n\n#endif /* OPENOCD_TARGET_CORTEX_M_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp563xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009-2011 by Mathias Kuester                            *\n *   mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jim.h>\n\n#include \"target.h\"\n#include \"breakpoints.h\"\n#include \"target_type.h\"\n#include \"algorithm.h\"\n#include \"register.h\"\n#include \"dsp563xx.h\"\n#include \"dsp563xx_once.h\"\n\n#define ASM_REG_W_R0    0x60F400\n#define ASM_REG_W_R1    0x61F400\n#define ASM_REG_W_R2    0x62F400\n#define ASM_REG_W_R3    0x63F400\n#define ASM_REG_W_R4    0x64F400\n#define ASM_REG_W_R5    0x65F400\n#define ASM_REG_W_R6    0x66F400\n#define ASM_REG_W_R7    0x67F400\n\n#define ASM_REG_W_N0    0x70F400\n#define ASM_REG_W_N1    0x71F400\n#define ASM_REG_W_N2    0x72F400\n#define ASM_REG_W_N3    0x73F400\n#define ASM_REG_W_N4    0x74F400\n#define ASM_REG_W_N5    0x75F400\n#define ASM_REG_W_N6    0x76F400\n#define ASM_REG_W_N7    0x77F400\n\n#define ASM_REG_W_M0    0x05F420\n#define ASM_REG_W_M1    0x05F421\n#define ASM_REG_W_M2    0x05F422\n#define ASM_REG_W_M3    0x05F423\n#define ASM_REG_W_M4    0x05F424\n#define ASM_REG_W_M5    0x05F425\n#define ASM_REG_W_M6    0x05F426\n#define ASM_REG_W_M7    0x05F427\n\n#define ASM_REG_W_X0    0x44F400\n#define ASM_REG_W_X1    0x45F400\n\n#define ASM_REG_W_Y0    0x46F400\n#define ASM_REG_W_Y1    0x47F400\n\n#define ASM_REG_W_A0    0x50F400\n#define ASM_REG_W_A1    0x54F400\n#define ASM_REG_W_A2    0x52F400\n\n#define ASM_REG_W_B0    0x51F400\n#define ASM_REG_W_B1    0x55F400\n#define ASM_REG_W_B2    0x53F400\n\n#define ASM_REG_W_VBA   0x05F430\n#define ASM_REG_W_OMR   0x05F43A\n#define ASM_REG_W_EP    0x05F42A\n#define ASM_REG_W_SC    0x05F431\n#define ASM_REG_W_SZ    0x05F438\n#define ASM_REG_W_SR    0x05F439\n#define ASM_REG_W_SP    0x05F43B\n#define ASM_REG_W_SSH   0x05F43C\n#define ASM_REG_W_SSL   0x05F43D\n#define ASM_REG_W_LA    0x05F43E\n#define ASM_REG_W_LC    0x05F43F\n#define ASM_REG_W_PC    0x000000\n#define ASM_REG_W_IPRC  0xFFFFFF\n#define ASM_REG_W_IPRP  0xFFFFFE\n\n#define ASM_REG_W_BCR   0xFFFFFB\n#define ASM_REG_W_DCR   0xFFFFFA\n#define ASM_REG_W_AAR0  0xFFFFF9\n#define ASM_REG_W_AAR1  0xFFFFF8\n#define ASM_REG_W_AAR2  0xFFFFF7\n#define ASM_REG_W_AAR3  0xFFFFF6\n\n/*\n * OBCR Register bit definitions\n */\n#define OBCR_B0_AND_B1            ((0x0) << 10)\n#define OBCR_B0_OR_B1             ((0x1) << 10)\n#define OBCR_B1_AFTER_B0          ((0x2) << 10)\n#define OBCR_B0_AFTER_B1          ((0x3) << 10)\n\n#define OBCR_BP_DISABLED          (0x0)\n#define OBCR_BP_MEM_P             (0x1)\n#define OBCR_BP_MEM_X             (0x2)\n#define OBCR_BP_MEM_Y             (0x3)\n#define OBCR_BP_ON_READ           ((0x2) << 0)\n#define OBCR_BP_ON_WRITE          ((0x1) << 0)\n#define OBCR_BP_CC_NOT_EQUAL      ((0x0) << 2)\n#define OBCR_BP_CC_EQUAL          ((0x1) << 2)\n#define OBCR_BP_CC_LESS_THAN      ((0x2) << 2)\n#define OBCR_BP_CC_GREATER_THAN   ((0x3) << 2)\n\n#define OBCR_BP_0(x)              ((x)<<2)\n#define OBCR_BP_1(x)              ((x)<<6)\n\n\nenum once_reg_idx {\n\tONCE_REG_IDX_OSCR = 0,\n\tONCE_REG_IDX_OMBC = 1,\n\tONCE_REG_IDX_OBCR = 2,\n\tONCE_REG_IDX_OMLR0 = 3,\n\tONCE_REG_IDX_OMLR1 = 4,\n\tONCE_REG_IDX_OGDBR = 5,\n\tONCE_REG_IDX_OPDBR = 6,\n\tONCE_REG_IDX_OPILR = 7,\n\tONCE_REG_IDX_PDB = 8,\n\tONCE_REG_IDX_OTC = 9,\n\tONCE_REG_IDX_OPABFR = 10,\n\tONCE_REG_IDX_OPABDR = 11,\n\tONCE_REG_IDX_OPABEX = 12,\n\tONCE_REG_IDX_OPABF0 = 13,\n\tONCE_REG_IDX_OPABF1 = 14,\n\tONCE_REG_IDX_OPABF2 = 15,\n\tONCE_REG_IDX_OPABF3 = 16,\n\tONCE_REG_IDX_OPABF4 = 17,\n\tONCE_REG_IDX_OPABF5 = 18,\n\tONCE_REG_IDX_OPABF6 = 19,\n\tONCE_REG_IDX_OPABF7 = 20,\n\tONCE_REG_IDX_OPABF8 = 21,\n\tONCE_REG_IDX_OPABF9 = 22,\n\tONCE_REG_IDX_OPABF10 = 23,\n\tONCE_REG_IDX_OPABF11 = 24,\n};\n\nstatic struct once_reg once_regs[] = {\n\t{ONCE_REG_IDX_OSCR,    DSP563XX_ONCE_OSCR,    24, \"OSCR\",    0},\n\t{ONCE_REG_IDX_OMBC,    DSP563XX_ONCE_OMBC,    24, \"OMBC\",    0},\n\t{ONCE_REG_IDX_OBCR,    DSP563XX_ONCE_OBCR,    24, \"OBCR\",    0},\n\t{ONCE_REG_IDX_OMLR0,   DSP563XX_ONCE_OMLR0,   24, \"OMLR0\",   0},\n\t{ONCE_REG_IDX_OMLR1,   DSP563XX_ONCE_OMLR1,   24, \"OMLR1\",   0},\n\t{ONCE_REG_IDX_OGDBR,   DSP563XX_ONCE_OGDBR,   24, \"OGDBR\",   0},\n\t{ONCE_REG_IDX_OPDBR,   DSP563XX_ONCE_OPDBR,   24, \"OPDBR\",   0},\n\t{ONCE_REG_IDX_OPILR,   DSP563XX_ONCE_OPILR,   24, \"OPILR\",   0},\n\t{ONCE_REG_IDX_PDB,     DSP563XX_ONCE_PDBGOTO, 24, \"PDB\",     0},\n\t{ONCE_REG_IDX_OTC,     DSP563XX_ONCE_OTC,     24, \"OTC\",     0},\n\t{ONCE_REG_IDX_OPABFR,  DSP563XX_ONCE_OPABFR,  24, \"OPABFR\",  0},\n\t{ONCE_REG_IDX_OPABDR,  DSP563XX_ONCE_OPABDR,  24, \"OPABDR\",  0},\n\t{ONCE_REG_IDX_OPABEX,  DSP563XX_ONCE_OPABEX,  24, \"OPABEX\",  0},\n\t{ONCE_REG_IDX_OPABF0,  DSP563XX_ONCE_OPABF11, 25, \"OPABF0\",  0},\n\t{ONCE_REG_IDX_OPABF1,  DSP563XX_ONCE_OPABF11, 25, \"OPABF1\",  0},\n\t{ONCE_REG_IDX_OPABF2,  DSP563XX_ONCE_OPABF11, 25, \"OPABF2\",  0},\n\t{ONCE_REG_IDX_OPABF3,  DSP563XX_ONCE_OPABF11, 25, \"OPABF3\",  0},\n\t{ONCE_REG_IDX_OPABF4,  DSP563XX_ONCE_OPABF11, 25, \"OPABF4\",  0},\n\t{ONCE_REG_IDX_OPABF5,  DSP563XX_ONCE_OPABF11, 25, \"OPABF5\",  0},\n\t{ONCE_REG_IDX_OPABF6,  DSP563XX_ONCE_OPABF11, 25, \"OPABF6\",  0},\n\t{ONCE_REG_IDX_OPABF7,  DSP563XX_ONCE_OPABF11, 25, \"OPABF7\",  0},\n\t{ONCE_REG_IDX_OPABF8,  DSP563XX_ONCE_OPABF11, 25, \"OPABF8\",  0},\n\t{ONCE_REG_IDX_OPABF9,  DSP563XX_ONCE_OPABF11, 25, \"OPABF9\",  0},\n\t{ONCE_REG_IDX_OPABF10, DSP563XX_ONCE_OPABF11, 25, \"OPABF10\", 0},\n\t{ONCE_REG_IDX_OPABF11, DSP563XX_ONCE_OPABF11, 25, \"OPABF11\", 0},\n/*      {25,0x1f,24,\"NRSEL\",0}, */\n};\n\nenum dsp563xx_reg_idx {\n\tDSP563XX_REG_IDX_R0 = 0,\n\tDSP563XX_REG_IDX_R1 = 1,\n\tDSP563XX_REG_IDX_R2 = 2,\n\tDSP563XX_REG_IDX_R3 = 3,\n\tDSP563XX_REG_IDX_R4 = 4,\n\tDSP563XX_REG_IDX_R5 = 5,\n\tDSP563XX_REG_IDX_R6 = 6,\n\tDSP563XX_REG_IDX_R7 = 7,\n\tDSP563XX_REG_IDX_N0 = 8,\n\tDSP563XX_REG_IDX_N1 = 9,\n\tDSP563XX_REG_IDX_N2 = 10,\n\tDSP563XX_REG_IDX_N3 = 11,\n\tDSP563XX_REG_IDX_N4 = 12,\n\tDSP563XX_REG_IDX_N5 = 13,\n\tDSP563XX_REG_IDX_N6 = 14,\n\tDSP563XX_REG_IDX_N7 = 15,\n\tDSP563XX_REG_IDX_M0 = 16,\n\tDSP563XX_REG_IDX_M1 = 17,\n\tDSP563XX_REG_IDX_M2 = 18,\n\tDSP563XX_REG_IDX_M3 = 19,\n\tDSP563XX_REG_IDX_M4 = 20,\n\tDSP563XX_REG_IDX_M5 = 21,\n\tDSP563XX_REG_IDX_M6 = 22,\n\tDSP563XX_REG_IDX_M7 = 23,\n\tDSP563XX_REG_IDX_X0 = 24,\n\tDSP563XX_REG_IDX_X1 = 25,\n\tDSP563XX_REG_IDX_Y0 = 26,\n\tDSP563XX_REG_IDX_Y1 = 27,\n\tDSP563XX_REG_IDX_A0 = 28,\n\tDSP563XX_REG_IDX_A1 = 29,\n\tDSP563XX_REG_IDX_A2 = 30,\n\tDSP563XX_REG_IDX_B0 = 31,\n\tDSP563XX_REG_IDX_B1 = 32,\n\tDSP563XX_REG_IDX_B2 = 33,\n\tDSP563XX_REG_IDX_SSH = 34,\n\tDSP563XX_REG_IDX_SSL = 35,\n\tDSP563XX_REG_IDX_SP = 36,\n\tDSP563XX_REG_IDX_EP = 37,\n\tDSP563XX_REG_IDX_SZ = 38,\n\tDSP563XX_REG_IDX_SC = 39,\n\tDSP563XX_REG_IDX_PC = 40,\n\tDSP563XX_REG_IDX_SR = 41,\n\tDSP563XX_REG_IDX_OMR = 42,\n\tDSP563XX_REG_IDX_LA = 43,\n\tDSP563XX_REG_IDX_LC = 44,\n\tDSP563XX_REG_IDX_VBA = 45,\n\tDSP563XX_REG_IDX_IPRC = 46,\n\tDSP563XX_REG_IDX_IPRP = 47,\n\tDSP563XX_REG_IDX_BCR = 48,\n\tDSP563XX_REG_IDX_DCR = 49,\n\tDSP563XX_REG_IDX_AAR0 = 50,\n\tDSP563XX_REG_IDX_AAR1 = 51,\n\tDSP563XX_REG_IDX_AAR2 = 52,\n\tDSP563XX_REG_IDX_AAR3 = 53,\n};\n\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tunsigned bits;\n\t/* effective addressing mode encoding */\n\tuint8_t eame;\n\tuint32_t instr_mask;\n} dsp563xx_regs[] = {\n\t/* *INDENT-OFF* */\n\t/* address registers */\n\t{DSP563XX_REG_IDX_R0, \"r0\", 24, 0x10, ASM_REG_W_R0},\n\t{DSP563XX_REG_IDX_R1, \"r1\", 24, 0x11, ASM_REG_W_R1},\n\t{DSP563XX_REG_IDX_R2, \"r2\", 24, 0x12, ASM_REG_W_R2},\n\t{DSP563XX_REG_IDX_R3, \"r3\", 24, 0x13, ASM_REG_W_R3},\n\t{DSP563XX_REG_IDX_R4, \"r4\", 24, 0x14, ASM_REG_W_R4},\n\t{DSP563XX_REG_IDX_R5, \"r5\", 24, 0x15, ASM_REG_W_R5},\n\t{DSP563XX_REG_IDX_R6, \"r6\", 24, 0x16, ASM_REG_W_R6},\n\t{DSP563XX_REG_IDX_R7, \"r7\", 24, 0x17, ASM_REG_W_R7},\n\t/* offset registers */\n\t{DSP563XX_REG_IDX_N0, \"n0\", 24, 0x18, ASM_REG_W_N0},\n\t{DSP563XX_REG_IDX_N1, \"n1\", 24, 0x19, ASM_REG_W_N1},\n\t{DSP563XX_REG_IDX_N2, \"n2\", 24, 0x1a, ASM_REG_W_N2},\n\t{DSP563XX_REG_IDX_N3, \"n3\", 24, 0x1b, ASM_REG_W_N3},\n\t{DSP563XX_REG_IDX_N4, \"n4\", 24, 0x1c, ASM_REG_W_N4},\n\t{DSP563XX_REG_IDX_N5, \"n5\", 24, 0x1d, ASM_REG_W_N5},\n\t{DSP563XX_REG_IDX_N6, \"n6\", 24, 0x1e, ASM_REG_W_N6},\n\t{DSP563XX_REG_IDX_N7, \"n7\", 24, 0x1f, ASM_REG_W_N7},\n\t/* modifier registers */\n\t{DSP563XX_REG_IDX_M0, \"m0\", 24, 0x20, ASM_REG_W_M0},\n\t{DSP563XX_REG_IDX_M1, \"m1\", 24, 0x21, ASM_REG_W_M1},\n\t{DSP563XX_REG_IDX_M2, \"m2\", 24, 0x22, ASM_REG_W_M2},\n\t{DSP563XX_REG_IDX_M3, \"m3\", 24, 0x23, ASM_REG_W_M3},\n\t{DSP563XX_REG_IDX_M4, \"m4\", 24, 0x24, ASM_REG_W_M4},\n\t{DSP563XX_REG_IDX_M5, \"m5\", 24, 0x25, ASM_REG_W_M5},\n\t{DSP563XX_REG_IDX_M6, \"m6\", 24, 0x26, ASM_REG_W_M6},\n\t{DSP563XX_REG_IDX_M7, \"m7\", 24, 0x27, ASM_REG_W_M7},\n\t/* data alu input register */\n\t{DSP563XX_REG_IDX_X0, \"x0\", 24, 0x04, ASM_REG_W_X0},\n\t{DSP563XX_REG_IDX_X1, \"x1\", 24, 0x05, ASM_REG_W_X1},\n\t{DSP563XX_REG_IDX_Y0, \"y0\", 24, 0x06, ASM_REG_W_Y0},\n\t{DSP563XX_REG_IDX_Y1, \"y1\", 24, 0x07, ASM_REG_W_Y1},\n\t/* data alu accumulator register */\n\t{DSP563XX_REG_IDX_A0, \"a0\", 24, 0x08, ASM_REG_W_A0},\n\t{DSP563XX_REG_IDX_A1, \"a1\", 24, 0x0c, ASM_REG_W_A1},\n\t{DSP563XX_REG_IDX_A2, \"a2\", 8, 0x0a, ASM_REG_W_A2},\n\t{DSP563XX_REG_IDX_B0, \"b0\", 24, 0x09, ASM_REG_W_B0},\n\t{DSP563XX_REG_IDX_B1, \"b1\", 24, 0x0d, ASM_REG_W_B1},\n\t{DSP563XX_REG_IDX_B2, \"b2\", 8, 0x0b, ASM_REG_W_B2},\n\t/* stack */\n\t{DSP563XX_REG_IDX_SSH, \"ssh\", 24, 0x3c, ASM_REG_W_SSH},\n\t{DSP563XX_REG_IDX_SSL, \"ssl\", 24, 0x3d, ASM_REG_W_SSL},\n\t{DSP563XX_REG_IDX_SP, \"sp\", 24, 0x3b, ASM_REG_W_SP},\n\t{DSP563XX_REG_IDX_EP, \"ep\", 24, 0x2a, ASM_REG_W_EP},\n\t{DSP563XX_REG_IDX_SZ, \"sz\", 24, 0x38, ASM_REG_W_SZ},\n\t{DSP563XX_REG_IDX_SC, \"sc\", 24, 0x31, ASM_REG_W_SC},\n\t/* system */\n\t{DSP563XX_REG_IDX_PC, \"pc\", 24, 0x00, ASM_REG_W_PC},\n\t{DSP563XX_REG_IDX_SR, \"sr\", 24, 0x39, ASM_REG_W_SR},\n\t{DSP563XX_REG_IDX_OMR, \"omr\", 24, 0x3a, ASM_REG_W_OMR},\n\t{DSP563XX_REG_IDX_LA, \"la\", 24, 0x3e, ASM_REG_W_LA},\n\t{DSP563XX_REG_IDX_LC, \"lc\", 24, 0x3f, ASM_REG_W_LC},\n\t/* interrupt */\n\t{DSP563XX_REG_IDX_VBA, \"vba\", 24, 0x30, ASM_REG_W_VBA},\n\t{DSP563XX_REG_IDX_IPRC, \"iprc\", 24, 0x00, ASM_REG_W_IPRC},\n\t{DSP563XX_REG_IDX_IPRP, \"iprp\", 24, 0x00, ASM_REG_W_IPRP},\n\t/* port a */\n\t{DSP563XX_REG_IDX_BCR, \"bcr\", 24, 0x00, ASM_REG_W_BCR},\n\t{DSP563XX_REG_IDX_DCR, \"dcr\", 24, 0x00, ASM_REG_W_DCR},\n\t{DSP563XX_REG_IDX_AAR0, \"aar0\", 24, 0x00, ASM_REG_W_AAR0},\n\t{DSP563XX_REG_IDX_AAR1, \"aar1\", 24, 0x00, ASM_REG_W_AAR1},\n\t{DSP563XX_REG_IDX_AAR2, \"aar2\", 24, 0x00, ASM_REG_W_AAR2},\n\t{DSP563XX_REG_IDX_AAR3, \"aar3\", 24, 0x00, ASM_REG_W_AAR3},\n\t/* *INDENT-ON* */\n};\n\nenum memory_type {\n\tMEM_X = 0,\n\tMEM_Y = 1,\n\tMEM_P = 2,\n\tMEM_L = 3,\n};\n\nenum watchpoint_condition {\n\tEQUAL,\n\tNOT_EQUAL,\n\tGREATER,\n\tLESS_THAN\n};\n\n#define INSTR_JUMP      0x0AF080\n/* Effective Addressing Mode Encoding */\n#define EAME_R0         0x10\n/* instruction encoder */\n/* movep\n * s - peripheral space X/Y (X=0,Y=1)\n * w - write/read\n * d - source/destination register\n * p - IO short address\n */\n#define INSTR_MOVEP_REG_HIO(s, w, d, p) (0x084000 | \\\n\t((s & 1) << 16) | ((w & 1) << 15) | ((d & 0x3f) << 8) | (p & 0x3f))\n\n/* the gdb register list is send in this order */\nstatic const uint8_t gdb_reg_list_idx[] = {\n\tDSP563XX_REG_IDX_X1, DSP563XX_REG_IDX_X0, DSP563XX_REG_IDX_Y1, DSP563XX_REG_IDX_Y0,\n\tDSP563XX_REG_IDX_A2, DSP563XX_REG_IDX_A1, DSP563XX_REG_IDX_A0, DSP563XX_REG_IDX_B2,\n\tDSP563XX_REG_IDX_B1, DSP563XX_REG_IDX_B0, DSP563XX_REG_IDX_PC, DSP563XX_REG_IDX_SR,\n\tDSP563XX_REG_IDX_OMR, DSP563XX_REG_IDX_LA, DSP563XX_REG_IDX_LC, DSP563XX_REG_IDX_SSH,\n\tDSP563XX_REG_IDX_SSL, DSP563XX_REG_IDX_SP, DSP563XX_REG_IDX_EP, DSP563XX_REG_IDX_SZ,\n\tDSP563XX_REG_IDX_SC, DSP563XX_REG_IDX_VBA, DSP563XX_REG_IDX_IPRC, DSP563XX_REG_IDX_IPRP,\n\tDSP563XX_REG_IDX_BCR, DSP563XX_REG_IDX_DCR, DSP563XX_REG_IDX_AAR0, DSP563XX_REG_IDX_AAR1,\n\tDSP563XX_REG_IDX_AAR2, DSP563XX_REG_IDX_AAR3, DSP563XX_REG_IDX_R0, DSP563XX_REG_IDX_R1,\n\tDSP563XX_REG_IDX_R2, DSP563XX_REG_IDX_R3, DSP563XX_REG_IDX_R4, DSP563XX_REG_IDX_R5,\n\tDSP563XX_REG_IDX_R6, DSP563XX_REG_IDX_R7, DSP563XX_REG_IDX_N0, DSP563XX_REG_IDX_N1,\n\tDSP563XX_REG_IDX_N2, DSP563XX_REG_IDX_N3, DSP563XX_REG_IDX_N4, DSP563XX_REG_IDX_N5,\n\tDSP563XX_REG_IDX_N6, DSP563XX_REG_IDX_N7, DSP563XX_REG_IDX_M0, DSP563XX_REG_IDX_M1,\n\tDSP563XX_REG_IDX_M2, DSP563XX_REG_IDX_M3, DSP563XX_REG_IDX_M4, DSP563XX_REG_IDX_M5,\n\tDSP563XX_REG_IDX_M6, DSP563XX_REG_IDX_M7,\n};\n\nstatic int dsp563xx_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[],\n\tint *reg_list_size,\n\tenum target_register_class reg_class)\n{\n\tint i;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t*reg_list_size = DSP563XX_NUMCOREREGS;\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\tif (!*reg_list)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (i = 0; i < DSP563XX_NUMCOREREGS; i++)\n\t\t(*reg_list)[i] = &dsp563xx->core_cache->reg_list[gdb_reg_list_idx[i]];\n\n\treturn ERROR_OK;\n\n}\n\nstatic int dsp563xx_read_core_reg(struct target *target, int num)\n{\n\tuint32_t reg_value;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif ((num < 0) || (num >= DSP563XX_NUMCOREREGS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = dsp563xx->core_regs[num];\n\tbuf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value);\n\tdsp563xx->core_cache->reg_list[num].valid = true;\n\tdsp563xx->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_write_core_reg(struct target *target, int num)\n{\n\tuint32_t reg_value;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif ((num < 0) || (num >= DSP563XX_NUMCOREREGS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32);\n\tdsp563xx->core_regs[num] = reg_value;\n\tdsp563xx->core_cache->reg_list[num].valid = true;\n\tdsp563xx->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_get_core_reg(struct reg *reg)\n{\n\tstruct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;\n\tstruct target *target = dsp563xx_reg->target;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\treturn dsp563xx->read_core_reg(target, dsp563xx_reg->num);\n}\n\nstatic int dsp563xx_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tstruct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;\n\tstruct target *target = dsp563xx_reg->target;\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u32(reg->value, 0, reg->size, value);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type dsp563xx_reg_type = {\n\t.get = dsp563xx_get_core_reg,\n\t.set = dsp563xx_set_core_reg,\n};\n\nstatic void dsp563xx_build_reg_cache(struct target *target)\n{\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(DSP563XX_NUMCOREREGS, sizeof(struct reg));\n\tstruct dsp563xx_core_reg *arch_info = malloc(\n\t\t\tsizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"dsp563xx registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = DSP563XX_NUMCOREREGS;\n\t(*cache_p) = cache;\n\tdsp563xx->core_cache = cache;\n\n\tfor (i = 0; i < DSP563XX_NUMCOREREGS; i++) {\n\t\tarch_info[i].num = dsp563xx_regs[i].id;\n\t\tarch_info[i].name = dsp563xx_regs[i].name;\n\t\tarch_info[i].size = dsp563xx_regs[i].bits;\n\t\tarch_info[i].eame = dsp563xx_regs[i].eame;\n\t\tarch_info[i].instr_mask = dsp563xx_regs[i].instr_mask;\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].dsp563xx_common = dsp563xx;\n\t\treg_list[i].name = dsp563xx_regs[i].name;\n\t\treg_list[i].size = 32;\t/* dsp563xx_regs[i].bits; */\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].type = &dsp563xx_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\t}\n}\n\nstatic int dsp563xx_read_register(struct target *target, int num, int force);\nstatic int dsp563xx_write_register(struct target *target, int num, int force);\n\nstatic int dsp563xx_reg_read_high_io(struct target *target, uint32_t instr_mask, uint32_t *data)\n{\n\tint err;\n\tuint32_t instr;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\t/* we use r0 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);\n\n\t/* move source memory to r0 */\n\tinstr = INSTR_MOVEP_REG_HIO(MEM_X, 0, EAME_R0, instr_mask);\n\terr = dsp563xx_once_execute_sw_ir(target->tap, 0, instr);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* move r0 to debug register */\n\tinstr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, 0xfffffc);\n\terr = dsp563xx_once_execute_sw_ir(target->tap, 1, instr);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* read debug register */\n\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* r0 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_reg_write_high_io(struct target *target, uint32_t instr_mask, uint32_t data)\n{\n\tint err;\n\tuint32_t instr;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\t/* we use r0 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);\n\n\t/* move data to r0 */\n\terr = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x60F400, data);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* move r0 to destination memory */\n\tinstr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, instr_mask);\n\terr = dsp563xx_once_execute_sw_ir(target->tap, 1, instr);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\t/* r0 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_reg_read(struct target *target, uint32_t eame, uint32_t *data)\n{\n\tint err;\n\tuint32_t instr;\n\n\tinstr = INSTR_MOVEP_REG_HIO(MEM_X, 1, eame, 0xfffffc);\n\terr = dsp563xx_once_execute_sw_ir(target->tap, 0, instr);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* nop */\n\terr = dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* read debug register */\n\treturn dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data);\n}\n\nstatic int dsp563xx_reg_write(struct target *target, uint32_t instr_mask, uint32_t data)\n{\n\tint err;\n\n\terr = dsp563xx_once_execute_dw_ir(target->tap, 0, instr_mask, data);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* nop */\n\treturn dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000);\n}\n\nstatic int dsp563xx_reg_pc_read(struct target *target)\n{\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\t/* pc was changed, nothing todo */\n\tif (dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty)\n\t\treturn ERROR_OK;\n\n\t/* conditional branch check */\n\tif (once_regs[ONCE_REG_IDX_OPABDR].reg == once_regs[ONCE_REG_IDX_OPABEX].reg) {\n\t\tif ((once_regs[ONCE_REG_IDX_OPABF11].reg & 1) == 0) {\n\t\t\tLOG_DEBUG(\"%s conditional branch not supported yet (0x%\" PRIx32 \" 0x%\" PRIx32 \" 0x%\" PRIx32 \")\",\n\t\t\t\t__func__,\n\t\t\t\t(once_regs[ONCE_REG_IDX_OPABF11].reg >> 1),\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPABDR].reg,\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPABEX].reg);\n\n\t\t\t/* TODO: use disassembly to set correct pc offset\n\t\t\t * read 2 words from OPABF11 and disasm the instruction\n\t\t\t */\n\t\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_PC] =\n\t\t\t\t(once_regs[ONCE_REG_IDX_OPABF11].reg >> 1) & 0x00FFFFFF;\n\t\t} else {\n\t\t\tif (once_regs[ONCE_REG_IDX_OPABEX].reg ==\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPABFR].reg)\n\t\t\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_PC] =\n\t\t\t\t\tonce_regs[ONCE_REG_IDX_OPABEX].reg;\n\t\t\telse\n\t\t\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_PC] =\n\t\t\t\t\tonce_regs[ONCE_REG_IDX_OPABEX].reg - 1;\n\t\t}\n\t} else\n\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg;\n\n\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_PC);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_reg_ssh_read(struct target *target)\n{\n\tint err;\n\tuint32_t sp;\n\tstruct dsp563xx_core_reg *arch_info;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info;\n\n\t/* get a valid stack pointer */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tsp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];\n\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\t/* get a valid stack count */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SC, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\t/* get a valid extended pointer */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_EP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (!sp)\n\t\tsp = 0x00FFFFFF;\n\telse {\n\t\terr = dsp563xx_reg_read(target, arch_info->eame, &sp);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\tdsp563xx->core_regs[DSP563XX_REG_IDX_SSH] = sp;\n\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSH);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_reg_ssh_write(struct target *target)\n{\n\tint err;\n\tuint32_t sp;\n\tstruct dsp563xx_core_reg *arch_info;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].arch_info;\n\n\t/* get a valid stack pointer */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tsp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];\n\n\tif (sp) {\n\t\tsp--;\n\t\t/* write new stackpointer */\n\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_SP] = sp;\n\t\terr = dsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SP);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_write_register(target, DSP563XX_REG_IDX_SP, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = dsp563xx_reg_write(target, arch_info->instr_mask,\n\t\t\t\tdsp563xx->core_regs[DSP563XX_REG_IDX_SSH]);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SSH, 1);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_reg_ssl_read(struct target *target)\n{\n\tint err;\n\tuint32_t sp;\n\tstruct dsp563xx_core_reg *arch_info;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].arch_info;\n\n\t/* get a valid stack pointer */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SP, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tsp = dsp563xx->core_regs[DSP563XX_REG_IDX_SP];\n\n\tif (!sp)\n\t\tsp = 0x00FFFFFF;\n\telse {\n\t\terr = dsp563xx_reg_read(target, arch_info->eame, &sp);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\tdsp563xx->core_regs[DSP563XX_REG_IDX_SSL] = sp;\n\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_SSL);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_read_register(struct target *target, int num, int force)\n{\n\tint err = ERROR_OK;\n\tuint32_t data = 0;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tstruct dsp563xx_core_reg *arch_info;\n\n\tif (force)\n\t\tdsp563xx->core_cache->reg_list[num].valid = false;\n\n\tif (!dsp563xx->core_cache->reg_list[num].valid) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[num].arch_info;\n\n\t\tswitch (arch_info->num) {\n\t\t\tcase DSP563XX_REG_IDX_SSH:\n\t\t\t\terr = dsp563xx_reg_ssh_read(target);\n\t\t\t\tbreak;\n\t\t\tcase DSP563XX_REG_IDX_SSL:\n\t\t\t\terr = dsp563xx_reg_ssl_read(target);\n\t\t\t\tbreak;\n\t\t\tcase DSP563XX_REG_IDX_PC:\n\t\t\t\terr = dsp563xx_reg_pc_read(target);\n\t\t\t\tbreak;\n\t\t\tcase DSP563XX_REG_IDX_IPRC:\n\t\t\tcase DSP563XX_REG_IDX_IPRP:\n\t\t\tcase DSP563XX_REG_IDX_BCR:\n\t\t\tcase DSP563XX_REG_IDX_DCR:\n\t\t\tcase DSP563XX_REG_IDX_AAR0:\n\t\t\tcase DSP563XX_REG_IDX_AAR1:\n\t\t\tcase DSP563XX_REG_IDX_AAR2:\n\t\t\tcase DSP563XX_REG_IDX_AAR3:\n\t\t\t\terr = dsp563xx_reg_read_high_io(target,\n\t\t\t\t\t\tarch_info->instr_mask, &data);\n\t\t\t\tif (err == ERROR_OK) {\n\t\t\t\t\tdsp563xx->core_regs[num] = data;\n\t\t\t\t\tdsp563xx->read_core_reg(target, num);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\terr = dsp563xx_reg_read(target, arch_info->eame, &data);\n\t\t\t\tif (err == ERROR_OK) {\n\t\t\t\t\tdsp563xx->core_regs[num] = data;\n\t\t\t\t\tdsp563xx->read_core_reg(target, num);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn err;\n}\n\nstatic int dsp563xx_write_register(struct target *target, int num, int force)\n{\n\tint err = ERROR_OK;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tstruct dsp563xx_core_reg *arch_info;\n\n\tif (force)\n\t\tdsp563xx->core_cache->reg_list[num].dirty = true;\n\n\tif (dsp563xx->core_cache->reg_list[num].dirty) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[num].arch_info;\n\n\t\tdsp563xx->write_core_reg(target, num);\n\n\t\tswitch (arch_info->num) {\n\t\t\tcase DSP563XX_REG_IDX_SSH:\n\t\t\t\terr = dsp563xx_reg_ssh_write(target);\n\t\t\t\tbreak;\n\t\t\tcase DSP563XX_REG_IDX_PC:\n\t\t\t\t/* pc is updated on resume, no need to write it here */\n\t\t\t\tbreak;\n\t\t\tcase DSP563XX_REG_IDX_IPRC:\n\t\t\tcase DSP563XX_REG_IDX_IPRP:\n\t\t\tcase DSP563XX_REG_IDX_BCR:\n\t\t\tcase DSP563XX_REG_IDX_DCR:\n\t\t\tcase DSP563XX_REG_IDX_AAR0:\n\t\t\tcase DSP563XX_REG_IDX_AAR1:\n\t\t\tcase DSP563XX_REG_IDX_AAR2:\n\t\t\tcase DSP563XX_REG_IDX_AAR3:\n\t\t\t\terr = dsp563xx_reg_write_high_io(target,\n\t\t\t\t\tarch_info->instr_mask,\n\t\t\t\t\tdsp563xx->core_regs[num]);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\terr = dsp563xx_reg_write(target,\n\t\t\t\t\tarch_info->instr_mask,\n\t\t\t\t\tdsp563xx->core_regs[num]);\n\n\t\t\t\tif ((err == ERROR_OK) && (arch_info->num == DSP563XX_REG_IDX_SP)) {\n\t\t\t\t\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSH].valid =\n\t\t\t\t\t\t0;\n\t\t\t\t\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SSL].valid =\n\t\t\t\t\t\t0;\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn err;\n}\n\nstatic int dsp563xx_save_context(struct target *target)\n{\n\tint i, err = ERROR_OK;\n\n\tfor (i = 0; i < DSP563XX_NUMCOREREGS; i++) {\n\t\terr = dsp563xx_read_register(target, i, 0);\n\t\tif (err != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn err;\n}\n\nstatic int dsp563xx_restore_context(struct target *target)\n{\n\tint i, err = ERROR_OK;\n\n\tfor (i = 0; i < DSP563XX_NUMCOREREGS; i++) {\n\t\terr = dsp563xx_write_register(target, i, 0);\n\t\tif (err != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn err;\n}\n\nstatic void dsp563xx_invalidate_x_context(struct target *target,\n\tuint32_t addr_start,\n\tuint32_t addr_end)\n{\n\tint i;\n\tstruct dsp563xx_core_reg *arch_info;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (addr_start > ASM_REG_W_IPRC)\n\t\treturn;\n\tif (addr_start < ASM_REG_W_AAR3)\n\t\treturn;\n\n\tfor (i = DSP563XX_REG_IDX_IPRC; i < DSP563XX_NUMCOREREGS; i++) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[i].arch_info;\n\n\t\tif ((arch_info->instr_mask >= addr_start) &&\n\t\t\t(arch_info->instr_mask <= addr_end)) {\n\t\t\tdsp563xx->core_cache->reg_list[i].valid = false;\n\t\t\tdsp563xx->core_cache->reg_list[i].dirty = false;\n\t\t}\n\t}\n}\n\nstatic int dsp563xx_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common));\n\n\tif (!dsp563xx)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tdsp563xx->jtag_info.tap = target->tap;\n\ttarget->arch_info = dsp563xx;\n\tdsp563xx->read_core_reg = dsp563xx_read_core_reg;\n\tdsp563xx->write_core_reg = dsp563xx_write_core_reg;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tdsp563xx_build_reg_cache(target);\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tdsp563xx->hardware_breakpoints_cleared = false;\n\tdsp563xx->hardware_breakpoint[0].used = BPU_NONE;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_examine(struct target *target)\n{\n\tuint32_t chip;\n\n\tif (target->tap->hasidcode == false) {\n\t\tLOG_ERROR(\"no IDCODE present on device\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (!target_was_examined(target)) {\n\t\ttarget_set_examined(target);\n\n\t\t/* examine core and chip derivate number */\n\t\tchip = (target->tap->idcode>>12) & 0x3ff;\n\t\t/* core number 0 means DSP563XX */\n\t\tif (((chip>>5)&0x1f) == 0)\n\t\t\tchip += 300;\n\n\t\tLOG_INFO(\"DSP56%03\" PRIu32 \" device found\", chip);\n\n\t\t/* Clear all breakpoints */\n\t\tdsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_arch_state(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\n#define DSP563XX_SR_SA (1<<17)\n#define DSP563XX_SR_SC (1<<13)\n\nstatic int dsp563xx_debug_once_init(struct target *target)\n{\n\treturn dsp563xx_once_read_register(target->tap, 1, once_regs, DSP563XX_NUMONCEREGS);\n}\n\nstatic int dsp563xx_debug_init(struct target *target)\n{\n\tint err;\n\tuint32_t sr;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tstruct dsp563xx_core_reg *arch_info;\n\n\terr = dsp563xx_debug_once_init(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].arch_info;\n\n\t/* check 24bit mode */\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_SR, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tsr = dsp563xx->core_regs[DSP563XX_REG_IDX_SR];\n\n\tif (sr & (DSP563XX_SR_SA | DSP563XX_SR_SC)) {\n\t\tsr &= ~(DSP563XX_SR_SA | DSP563XX_SR_SC);\n\n\t\terr = dsp563xx_once_execute_dw_ir(target->tap, 1, arch_info->instr_mask, sr);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_SR].dirty = true;\n\t}\n\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_N0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_N1, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_M0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_read_register(target, DSP563XX_REG_IDX_M1, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (dsp563xx->core_regs[DSP563XX_REG_IDX_N0] != 0x000000) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].arch_info;\n\t\terr = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N0].dirty = true;\n\n\tif (dsp563xx->core_regs[DSP563XX_REG_IDX_N1] != 0x000000) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].arch_info;\n\t\terr = dsp563xx_reg_write(target, arch_info->instr_mask, 0x000000);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_N1].dirty = true;\n\n\tif (dsp563xx->core_regs[DSP563XX_REG_IDX_M0] != 0xffffff) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].arch_info;\n\t\terr = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M0].dirty = true;\n\n\tif (dsp563xx->core_regs[DSP563XX_REG_IDX_M1] != 0xffffff) {\n\t\tarch_info = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].arch_info;\n\t\terr = dsp563xx_reg_write(target, arch_info->instr_mask, 0xffffff);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_M1].dirty = true;\n\n\terr = dsp563xx_save_context(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_jtag_debug_request(struct target *target)\n{\n\treturn dsp563xx_once_request_debug(target->tap, target->state == TARGET_RESET);\n}\n\nstatic int dsp563xx_poll(struct target *target)\n{\n\tint err;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tuint32_t once_status = 0;\n\tint state;\n\n\tstate = dsp563xx_once_target_status(target->tap);\n\n\tif (state == TARGET_UNKNOWN) {\n\t\ttarget->state = state;\n\t\tLOG_ERROR(\"jtag status contains invalid mode value - communication failure\");\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\terr = dsp563xx_debug_init(target);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\tif (once_status & (DSP563XX_ONCE_OSCR_MBO|DSP563XX_ONCE_OSCR_SWO))\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t\telse\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\t\t\tLOG_DEBUG(\"target->state: %s (%\" PRIx32 \")\", target_state_name(target), once_status);\n\t\t\tLOG_INFO(\"halted: PC: 0x%\" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]);\n\t\t}\n\t}\n\n\tif (!dsp563xx->hardware_breakpoints_cleared) {\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, 0);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tdsp563xx->hardware_breakpoints_cleared = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_halt(struct target *target)\n{\n\tint err;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\terr = dsp563xx_jtag_debug_request(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tint err;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\t/* check if pc was changed and resume want to execute the next address\n\t * if pc was changed from gdb or other interface we will\n\t * jump to this address and don't execute the next address\n\t * this will not affect the resume command with an address argument\n\t * because current is set to zero then\n\t */\n\tif (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {\n\t\tdsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);\n\t\taddress = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];\n\t\tcurrent = 0;\n\t}\n\n\tLOG_DEBUG(\"%s %08X %08X\", __func__, current, (unsigned) address);\n\n\terr = dsp563xx_restore_context(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tregister_cache_invalidate(dsp563xx->core_cache);\n\n\tif (current) {\n\t\t/* restore pipeline registers and go */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPILR].reg);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |\n\t\t\t\tDSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPDBR].reg);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t} else {\n\t\t/* set to go register and jump */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,\tINSTR_JUMP);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |\n\t\t\t\tDSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\ttarget->state = TARGET_RUNNING;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_step_ex(struct target *target,\n\tint current,\n\tuint32_t address,\n\tint handle_breakpoints,\n\tint steps)\n{\n\tint err;\n\tuint32_t once_status;\n\tuint32_t dr_in, cnt;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was not halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* check if pc was changed and step want to execute the next address\n\t * if pc was changed from gdb or other interface we will\n\t * jump to this address and don't execute the next address\n\t * this will not affect the step command with an address argument\n\t * because current is set to zero then\n\t */\n\tif (current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty) {\n\t\tdsp563xx_write_core_reg(target, DSP563XX_REG_IDX_PC);\n\t\taddress = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];\n\t\tcurrent = 0;\n\t}\n\n\tLOG_DEBUG(\"%s %08X %08X\", __func__, current, (unsigned) address);\n\n\terr = dsp563xx_jtag_debug_request(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_restore_context(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\t/* reset trace mode */\n\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\t/* enable trace mode */\n\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tcnt = steps;\n\n\t/* on JUMP we need one extra cycle */\n\tif (!current)\n\t\tcnt++;\n\n\t/* load step counter with N-1 */\n\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, cnt);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (current) {\n\t\t/* restore pipeline registers and go */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR,\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPILR].reg);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR |\n\t\t\t\tDSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,\n\t\t\t\tonce_regs[ONCE_REG_IDX_OPDBR].reg);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t} else {\n\t\t/* set to go register and jump */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO |\n\t\t\t\tDSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,\n\t\t\t\taddress);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\twhile (1) {\n\t\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tif (once_status & DSP563XX_ONCE_OSCR_TO) {\n\t\t\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABFR, &dr_in);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\t\t\tLOG_DEBUG(\"fetch: %08X\", (unsigned) dr_in&0x00ffffff);\n\t\t\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABDR, &dr_in);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\t\t\tLOG_DEBUG(\"decode: %08X\", (unsigned) dr_in&0x00ffffff);\n\t\t\terr = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABEX, &dr_in);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\t\t\tLOG_DEBUG(\"execute: %08X\", (unsigned) dr_in&0x00ffffff);\n\n\t\t\t/* reset trace mode */\n\t\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\tregister_cache_invalidate(dsp563xx->core_cache);\n\t\t\terr = dsp563xx_debug_init(target);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_step(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints)\n{\n\tint err;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\terr = dsp563xx_step_ex(target, current, address, handle_breakpoints, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\tLOG_INFO(\"halted: PC: 0x%\" PRIx32, dsp563xx->core_regs[DSP563XX_REG_IDX_PC]);\n\n\treturn err;\n}\n\nstatic int dsp563xx_assert_reset(struct target *target)\n{\n\tint retval = 0;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\t/* default to asserting srst */\n\t\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\tjtag_add_reset(1, 1);\n\t\telse\n\t\t\tjtag_add_reset(0, 1);\n\t}\n\n\ttarget->state = TARGET_RESET;\n\tjtag_add_sleep(5000);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(dsp563xx->core_cache);\n\n\tif (target->reset_halt) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_deassert_reset(struct target *target)\n{\n\tint err;\n\n\t/* deassert reset lines */\n\tjtag_add_reset(0, 0);\n\n\terr = dsp563xx_poll(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tif (target->reset_halt) {\n\t\tif (target->state == TARGET_HALTED) {\n\t\t\t/* after a reset the cpu jmp to the\n\t\t\t * reset vector and need 2 cycles to fill\n\t\t\t * the cache (fetch,decode,execute)\n\t\t\t */\n\t\t\terr = dsp563xx_step_ex(target, 1, 0, 1, 1);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_run_algorithm(struct target *target,\n\tint num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\ttarget_addr_t entry_point, target_addr_t exit_point,\n\tunsigned int timeout_ms, void *arch_info)\n{\n\tint i;\n\tint retval = ERROR_OK;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tfor (i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\t\tretval = target_write_buffer(target, mem_params[i].address,\n\t\t\t\tmem_params[i].size, mem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\n\t\tstruct reg *reg = register_get_by_name(dsp563xx->core_cache,\n\t\t\t\treg_params[i].reg_name,\n\t\t\t\tfalse);\n\n\t\tif (!reg) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (reg->size != reg_params[i].size) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\treg_params[i].reg_name);\n\t\t\tcontinue;\n\t\t}\n\n\t\tretval = dsp563xx_set_core_reg(reg, reg_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* exec */\n\tretval = target_resume(target, 0, entry_point, 1, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_wait_state(target, TARGET_HALTED, timeout_ms);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction != PARAM_OUT)\n\t\t\tretval = target_read_buffer(target,\n\t\t\t\t\tmem_params[i].address,\n\t\t\t\t\tmem_params[i].size,\n\t\t\t\t\tmem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction != PARAM_OUT) {\n\n\t\t\tstruct reg *reg = register_get_by_name(dsp563xx->core_cache,\n\t\t\t\t\treg_params[i].reg_name,\n\t\t\t\t\tfalse);\n\t\t\tif (!reg) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (reg->size != reg_params[i].size) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tbuf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* global command context from openocd.c */\nextern struct command_context *global_cmd_ctx;\n\nstatic int dsp563xx_get_default_memory(void)\n{\n\tJim_Interp *interp;\n\tJim_Obj *memspace;\n\tchar *c;\n\n\tif (!global_cmd_ctx)\n\t\treturn MEM_P;\n\n\tinterp = global_cmd_ctx->interp;\n\n\tif (!interp)\n\t\treturn MEM_P;\n\n\tmemspace = Jim_GetGlobalVariableStr(interp, \"memspace\", JIM_NONE);\n\n\tif (!memspace)\n\t\treturn MEM_P;\n\n\tc = (char *)Jim_GetString(memspace, NULL);\n\n\tif (!c)\n\t\treturn MEM_P;\n\n\tswitch (c[0]) {\n\t\tcase '1':\n\t\t\treturn MEM_X;\n\t\tcase '2':\n\t\t\treturn MEM_Y;\n\t\tcase '3':\n\t\t\treturn MEM_L;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\treturn MEM_P;\n}\n\nstatic int dsp563xx_read_memory_core(struct target *target,\n\tint mem_type,\n\tuint32_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tuint8_t *buffer)\n{\n\tint err;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tuint32_t i, x;\n\tuint32_t data, move_cmd = 0;\n\tuint8_t *b;\n\n\tLOG_DEBUG(\n\t\t\"memtype: %d address: 0x%8.8\" PRIx32 \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\tmem_type,\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (mem_type) {\n\t\tcase MEM_X:\n\t\t\t/* TODO: mark effected queued registers */\n\t\t\tmove_cmd = 0x61d800;\n\t\t\tbreak;\n\t\tcase MEM_Y:\n\t\t\tmove_cmd = 0x69d800;\n\t\t\tbreak;\n\t\tcase MEM_P:\n\t\t\tmove_cmd = 0x07d891;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* we use r0 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);\n\t/* we use r1 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);\n\n\t/* r0 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;\n\t/* r1 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;\n\n\tx = count;\n\tb = buffer;\n\n\terr = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tfor (i = 0; i < x; i++) {\n\t\terr = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_reg_read(target->tap, 0,\n\t\t\t\tDSP563XX_ONCE_OGDBR, (uint32_t *)(void *)b);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tb += 4;\n\t}\n\n\t/* flush the jtag queue */\n\terr = jtag_execute_queue();\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\t/* walk over the buffer and fix target endianness */\n\tb = buffer;\n\n\tfor (i = 0; i < x; i++) {\n\t\tdata = buf_get_u32(b, 0, 32) & 0x00FFFFFF;\n/*\t\tLOG_DEBUG(\"R: %08X\", *((uint32_t*)b)); */\n\t\ttarget_buffer_set_u32(target, b, data);\n\t\tb += 4;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_read_memory(struct target *target,\n\tint mem_type,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tuint8_t *buffer)\n{\n\tint err;\n\tuint32_t i, i1;\n\tuint8_t *buffer_y, *buffer_x;\n\n\t/* if size equals zero we are called from target read memory\n\t * and have to handle the parameter here */\n\tif ((size == 0) && (count != 0)) {\n\t\tsize = count % 4;\n\n\t\tif (size)\n\t\t\tLOG_DEBUG(\"size is not aligned to 4 byte\");\n\n\t\tcount = (count - size) / 4;\n\t\tsize = 4;\n\t}\n\n\t/* we only support 4 byte aligned data */\n\tif ((size != 4) || (!count))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (mem_type != MEM_L)\n\t\treturn dsp563xx_read_memory_core(target, mem_type, address, size, count, buffer);\n\n\tbuffer_y = malloc(size * count);\n\tif (!buffer_y)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tbuffer_x = malloc(size * count);\n\tif (!buffer_x) {\n\t\tfree(buffer_y);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\terr = dsp563xx_read_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);\n\n\tif (err != ERROR_OK) {\n\t\tfree(buffer_y);\n\t\tfree(buffer_x);\n\t\treturn err;\n\t}\n\n\terr = dsp563xx_read_memory_core(target, MEM_X, address, size, count / 2, buffer_x);\n\n\tif (err != ERROR_OK) {\n\t\tfree(buffer_y);\n\t\tfree(buffer_x);\n\t\treturn err;\n\t}\n\n\tfor (i = 0, i1 = 0; i < count; i += 2, i1++) {\n\t\tbuf_set_u32(buffer + i*sizeof(uint32_t), 0, 32,\n\t\t\tbuf_get_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32));\n\t\t\tbuf_set_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32,\n\t\t\tbuf_get_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32));\n\t}\n\n\tfree(buffer_y);\n\tfree(buffer_x);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_read_memory_default(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tuint8_t *buffer)\n{\n\n\treturn dsp563xx_read_memory(target,\n\t\t\tdsp563xx_get_default_memory(), address, size, count, buffer);\n}\n\nstatic int dsp563xx_read_buffer_default(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint8_t *buffer)\n{\n\n\treturn dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0,\n\t\t\tbuffer);\n}\n\nstatic int dsp563xx_write_memory_core(struct target *target,\n\tint mem_type,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tint err;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\tuint32_t i, x;\n\tuint32_t data, move_cmd = 0;\n\tconst uint8_t *b;\n\n\tLOG_DEBUG(\n\t\t\"memtype: %d address: 0x%8.8\" TARGET_PRIxADDR \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\tmem_type,\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (mem_type) {\n\t\tcase MEM_X:\n\t\t\t/* invalidate affected x registers */\n\t\t\tdsp563xx_invalidate_x_context(target, address, address + count - 1);\n\t\t\tmove_cmd = 0x615800;\n\t\t\tbreak;\n\t\tcase MEM_Y:\n\t\t\tmove_cmd = 0x695800;\n\t\t\tbreak;\n\t\tcase MEM_P:\n\t\t\tmove_cmd = 0x075891;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* we use r0 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R0);\n\t/* we use r1 to store temporary data */\n\tif (!dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].valid)\n\t\tdsp563xx->read_core_reg(target, DSP563XX_REG_IDX_R1);\n\n\t/* r0 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R0].dirty = true;\n\t/* r1 is no longer valid on target */\n\tdsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_R1].dirty = true;\n\n\tx = count;\n\tb = buffer;\n\n\terr = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tfor (i = 0; i < x; i++) {\n\t\tdata = target_buffer_get_u32(target, b);\n\n/*\t\tLOG_DEBUG(\"W: %08X\", data); */\n\n\t\tdata &= 0x00ffffff;\n\n\t\terr = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\tb += 4;\n\t}\n\n\t/* flush the jtag queue */\n\terr = jtag_execute_queue();\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_write_memory(struct target *target,\n\tint mem_type,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\tint err;\n\tuint32_t i, i1;\n\tuint8_t *buffer_y, *buffer_x;\n\n\t/* if size equals zero we are called from target write memory\n\t * and have to handle the parameter here */\n\tif ((size == 0) && (count != 0)) {\n\t\tsize = count % 4;\n\n\t\tif (size)\n\t\t\tLOG_DEBUG(\"size is not aligned to 4 byte\");\n\n\t\tcount = (count - size) / 4;\n\t\tsize = 4;\n\t}\n\n\t/* we only support 4 byte aligned data */\n\tif ((size != 4) || (!count))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (mem_type != MEM_L)\n\t\treturn dsp563xx_write_memory_core(target, mem_type, address, size, count, buffer);\n\n\tbuffer_y = malloc(size * count);\n\tif (!buffer_y)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tbuffer_x = malloc(size * count);\n\tif (!buffer_x) {\n\t\tfree(buffer_y);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tfor (i = 0, i1 = 0; i < count; i += 2, i1++) {\n\t\tbuf_set_u32(buffer_y + i1 * sizeof(uint32_t), 0, 32,\n\t\tbuf_get_u32(buffer + i * sizeof(uint32_t), 0, 32));\n\t\tbuf_set_u32(buffer_x + i1 * sizeof(uint32_t), 0, 32,\n\t\tbuf_get_u32(buffer + (i + 1) * sizeof(uint32_t), 0, 32));\n\t}\n\n\terr = dsp563xx_write_memory_core(target, MEM_Y, address, size, count / 2, buffer_y);\n\n\tif (err != ERROR_OK) {\n\t\tfree(buffer_y);\n\t\tfree(buffer_x);\n\t\treturn err;\n\t}\n\n\terr = dsp563xx_write_memory_core(target, MEM_X, address, size, count / 2, buffer_x);\n\n\tif (err != ERROR_OK) {\n\t\tfree(buffer_y);\n\t\tfree(buffer_x);\n\t\treturn err;\n\t}\n\n\tfree(buffer_y);\n\tfree(buffer_x);\n\n\treturn ERROR_OK;\n}\n\nstatic int dsp563xx_write_memory_default(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\treturn dsp563xx_write_memory(target,\n\t\t\tdsp563xx_get_default_memory(), address, size, count, buffer);\n}\n\nstatic int dsp563xx_write_buffer_default(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tconst uint8_t *buffer)\n{\n\treturn dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0,\n\t\t\tbuffer);\n}\n\n/*\n * Exit with error here, because we support watchpoints over a custom command.\n * This is because the DSP has separate X,Y,P memspace which is not compatible to the\n * traditional watchpoint logic.\n */\nstatic int dsp563xx_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n}\n\n/*\n * @see dsp563xx_add_watchpoint\n */\nstatic int dsp563xx_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n}\n\nstatic int dsp563xx_add_custom_watchpoint(struct target *target, uint32_t address, uint32_t mem_type,\n\t\tenum watchpoint_rw rw, enum watchpoint_condition cond)\n{\n\tint err = ERROR_OK;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tbool was_running = false;\n\t/* Only set breakpoint when halted */\n\tif (target->state != TARGET_HALTED) {\n\t\tdsp563xx_halt(target);\n\t\twas_running = true;\n\t}\n\n\tif (dsp563xx->hardware_breakpoint[0].used) {\n\t\tLOG_ERROR(\"Cannot add watchpoint. Hardware resource already used.\");\n\t\terr = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tuint32_t obcr_value = 0;\n\tif\t(err == ERROR_OK) {\n\t\tobcr_value |= OBCR_B0_OR_B1;\n\t\tswitch (mem_type) {\n\t\t\tcase MEM_X:\n\t\t\t\tobcr_value |= OBCR_BP_MEM_X;\n\t\t\t\tbreak;\n\t\t\tcase MEM_Y:\n\t\t\t\tobcr_value |= OBCR_BP_MEM_Y;\n\t\t\t\tbreak;\n\t\t\tcase MEM_P:\n\t\t\t\tobcr_value |= OBCR_BP_MEM_P;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unknown mem_type parameter (%\" PRIu32 \")\", mem_type);\n\t\t\t\terr = ERROR_TARGET_INVALID;\n\t\t}\n\t}\n\n\tif (err == ERROR_OK) {\n\t\tswitch (rw) {\n\t\t\tcase WPT_READ:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_ON_READ);\n\t\t\t\tbreak;\n\t\t\tcase WPT_WRITE:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_ON_WRITE);\n\t\t\t\tbreak;\n\t\t\tcase WPT_ACCESS:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_ON_READ|OBCR_BP_ON_WRITE);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported write mode (%d)\", rw);\n\t\t\t\terr = ERROR_TARGET_INVALID;\n\t\t}\n\t}\n\n\tif (err == ERROR_OK) {\n\t\tswitch (cond) {\n\t\t\tcase EQUAL:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_CC_EQUAL);\n\t\t\t\tbreak;\n\t\t\tcase NOT_EQUAL:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_CC_NOT_EQUAL);\n\t\t\t\tbreak;\n\t\t\tcase LESS_THAN:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_CC_LESS_THAN);\n\t\t\t\tbreak;\n\t\t\tcase GREATER:\n\t\t\t\tobcr_value |= OBCR_BP_0(OBCR_BP_CC_GREATER_THAN);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Unsupported condition code (%d)\", cond);\n\t\t\t\terr = ERROR_TARGET_INVALID;\n\t\t}\n\t}\n\n\tif (err == ERROR_OK)\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR0, address);\n\n\tif (err == ERROR_OK)\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMLR1, 0x0);\n\n\tif (err == ERROR_OK)\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, obcr_value);\n\n\tif (err == ERROR_OK) {\n\t\t/* You should write the memory breakpoint counter to 0 */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OMBC, 0);\n\t}\n\n\tif (err == ERROR_OK) {\n\t\t/* You should write the memory breakpoint counter to 0 */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, 0);\n\t}\n\n\tif (err == ERROR_OK)\n\t\tdsp563xx->hardware_breakpoint[0].used = BPU_WATCHPOINT;\n\n\tif (err == ERROR_OK && was_running) {\n\t\t/* Resume from current PC */\n\t\terr = dsp563xx_resume(target, 1, 0x0, 0, 0);\n\t}\n\n\treturn err;\n}\n\nstatic int dsp563xx_remove_custom_watchpoint(struct target *target)\n{\n\tint err = ERROR_OK;\n\tstruct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);\n\n\tif (dsp563xx->hardware_breakpoint[0].used != BPU_WATCHPOINT) {\n\t\tLOG_ERROR(\"Cannot remove watchpoint, as no watchpoint is currently configured!\");\n\t\terr = ERROR_TARGET_INVALID;\n\t}\n\n\tif (err == ERROR_OK) {\n\t\t/* Clear watchpoint by clearing OBCR. */\n\t\terr = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OBCR, 0);\n\t}\n\n\tif (err == ERROR_OK)\n\t\tdsp563xx->hardware_breakpoint[0].used = BPU_NONE;\n\n\treturn err;\n}\n\nCOMMAND_HANDLER(dsp563xx_add_watchpoint_command)\n{\n\tint err = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tuint32_t mem_type = 0;\n\tswitch (CMD_NAME[2]) {\n\t\tcase 'x':\n\t\t\tmem_type = MEM_X;\n\t\t\tbreak;\n\t\tcase 'y':\n\t\t\tmem_type = MEM_Y;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tmem_type = MEM_P;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t address = 0;\n\tif (CMD_ARGC > 2)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);\n\n\tenum watchpoint_condition cond;\n\tswitch (CMD_ARGV[0][0]) {\n\t\tcase '>':\n\t\t\tcond = GREATER;\n\t\t\tbreak;\n\t\tcase '<':\n\t\t\tcond = LESS_THAN;\n\t\t\tbreak;\n\t\tcase '=':\n\t\t\tcond = EQUAL;\n\t\t\tbreak;\n\t\tcase '!':\n\t\t\tcond = NOT_EQUAL;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tenum watchpoint_rw rw;\n\tswitch (CMD_ARGV[1][0]) {\n\t\tcase 'r':\n\t\t\trw = WPT_READ;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\trw = WPT_WRITE;\n\t\t\tbreak;\n\t\tcase 'a':\n\t\t\trw = WPT_ACCESS;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\terr = dsp563xx_add_custom_watchpoint(target, address, mem_type, rw, cond);\n\n\treturn err;\n}\n\n/* Adding a breakpoint using the once breakpoint logic.\n * Note that this mechanism is a true hw breakpoint and is share between the watchpoint logic.\n * This means, you can only have one breakpoint/watchpoint at any time.\n */\nstatic int dsp563xx_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\treturn dsp563xx_add_custom_watchpoint(target, breakpoint->address, MEM_P, WPT_READ, EQUAL);\n}\n\nstatic int dsp563xx_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\treturn dsp563xx_remove_custom_watchpoint(target);\n}\n\nCOMMAND_HANDLER(dsp563xx_remove_watchpoint_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\treturn dsp563xx_remove_custom_watchpoint(target);\n}\n\nCOMMAND_HANDLER(dsp563xx_mem_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint err = ERROR_OK;\n\tint read_mem;\n\tuint32_t address = 0;\n\tuint32_t count = 1, i;\n\tuint32_t pattern = 0;\n\tuint32_t mem_type;\n\tuint8_t *buffer, *b;\n\n\tswitch (CMD_NAME[1]) {\n\t\tcase 'w':\n\t\t\tread_mem = 0;\n\t\t\tbreak;\n\t\tcase 'd':\n\t\t\tread_mem = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tswitch (CMD_NAME[3]) {\n\t\tcase 'x':\n\t\t\tmem_type = MEM_X;\n\t\t\tbreak;\n\t\tcase 'y':\n\t\t\tmem_type = MEM_Y;\n\t\t\tbreak;\n\t\tcase 'p':\n\t\t\tmem_type = MEM_P;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\n\tif (read_mem == 0) {\n\t\tif (CMD_ARGC < 2)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tif (CMD_ARGC > 1)\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);\n\t\tif (CMD_ARGC > 2)\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);\n\t}\n\n\tif (read_mem == 1) {\n\t\tif (CMD_ARGC < 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tif (CMD_ARGC > 1)\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);\n\t}\n\n\tbuffer = calloc(count, 4);\n\n\tif (read_mem == 1) {\n\t\terr = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t),\n\t\t\t\tcount, buffer);\n\t\tif (err == ERROR_OK)\n\t\t\ttarget_handle_md_output(CMD, target, address, sizeof(uint32_t), count, buffer);\n\n\t} else {\n\t\tb = buffer;\n\n\t\tfor (i = 0; i < count; i++) {\n\t\t\ttarget_buffer_set_u32(target, b, pattern);\n\t\t\tb += 4;\n\t\t}\n\n\t\terr = dsp563xx_write_memory(target,\n\t\t\t\tmem_type,\n\t\t\t\taddress,\n\t\t\t\tsizeof(uint32_t),\n\t\t\t\tcount,\n\t\t\t\tbuffer);\n\t}\n\n\tfree(buffer);\n\n\treturn err;\n}\n\nstatic const struct command_registration dsp563xx_command_handlers[] = {\n\t{\n\t\t.name = \"mwwx\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write x memory words\",\n\t\t.usage = \"address value [count]\",\n\t},\n\t{\n\t\t.name = \"mwwy\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write y memory words\",\n\t\t.usage = \"address value [count]\",\n\t},\n\t{\n\t\t.name = \"mwwp\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write p memory words\",\n\t\t.usage = \"address value [count]\",\n\t},\n\t{\n\t\t.name = \"mdwx\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display x memory words\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"mdwy\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display y memory words\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"mdwp\",\n\t\t.handler = dsp563xx_mem_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display p memory words\",\n\t\t.usage = \"address [count]\",\n\t},\n  /*\n   * Watchpoint commands\n   */\n\t{\n\t\t.name = \"wpp\",\n\t\t.handler = dsp563xx_add_watchpoint_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Create p memspace watchpoint\",\n\t\t.usage = \"(>|<|=|!) (r|w|a) address\",\n\t},\n\t{\n\t\t.name = \"wpx\",\n\t\t.handler = dsp563xx_add_watchpoint_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Create x memspace watchpoint\",\n\t\t.usage = \"(>|<|=|!) (r|w|a) address\",\n\t},\n\t{\n\t\t.name = \"wpy\",\n\t\t.handler = dsp563xx_add_watchpoint_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Create y memspace watchpoint\",\n\t\t.usage = \"(>|<|=|!) (r|w|a) address\",\n\t},\n\t{\n\t\t.name = \"rwpc\",\n\t\t.handler = dsp563xx_remove_watchpoint_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"remove watchpoint custom\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for DSP563XX targets. */\nstruct target_type dsp563xx_target = {\n\t.name = \"dsp563xx\",\n\n\t.poll = dsp563xx_poll,\n\t.arch_state = dsp563xx_arch_state,\n\n\t.get_gdb_reg_list = dsp563xx_get_gdb_reg_list,\n\n\t.halt = dsp563xx_halt,\n\t.resume = dsp563xx_resume,\n\t.step = dsp563xx_step,\n\n\t.assert_reset = dsp563xx_assert_reset,\n\t.deassert_reset = dsp563xx_deassert_reset,\n\n\t.read_memory = dsp563xx_read_memory_default,\n\t.write_memory = dsp563xx_write_memory_default,\n\n\t.read_buffer = dsp563xx_read_buffer_default,\n\t.write_buffer = dsp563xx_write_buffer_default,\n\n\t.run_algorithm = dsp563xx_run_algorithm,\n\n\t.add_breakpoint = dsp563xx_add_breakpoint,\n\t.remove_breakpoint = dsp563xx_remove_breakpoint,\n\t.add_watchpoint = dsp563xx_add_watchpoint,\n\t.remove_watchpoint = dsp563xx_remove_watchpoint,\n\n\t.commands = dsp563xx_command_handlers,\n\t.target_create = dsp563xx_target_create,\n\t.init_target = dsp563xx_init_target,\n\t.examine = dsp563xx_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp563xx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009-2011 by Mathias Kuester                            *\n *   mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_DSP563XX_H\n#define OPENOCD_TARGET_DSP563XX_H\n\n#include <jtag/jtag.h>\n#include <target/dsp563xx_once.h>\n\n#define DSP563XX_NUMCOREREGS\t54\n#define DSP563XX_NUMONCEREGS\t25\n\nstruct mcu_jtag {\n\tstruct jtag_tap *tap;\n};\n\nenum breakpoint_usage {\n\tBPU_NONE = 0,\n\tBPU_BREAKPOINT,\n\tBPU_WATCHPOINT\n};\n\nstruct hardware_breakpoint {\n\tenum breakpoint_usage used;\n};\n\nstruct dsp563xx_common {\n\tstruct mcu_jtag jtag_info;\n\tstruct reg_cache *core_cache;\n\tuint32_t core_regs[DSP563XX_NUMCOREREGS];\n\tstruct once_reg once_regs[DSP563XX_NUMONCEREGS];\n\n\t/* register cache to processor synchronization */\n\tint (*read_core_reg)(struct target *target, int num);\n\tint (*write_core_reg)(struct target *target, int num);\n\n\tstruct hardware_breakpoint hardware_breakpoint[1];\n\n\t/*Were the hardware breakpoints cleared on startup?*/\n\tbool hardware_breakpoints_cleared;\n};\n\nstruct dsp563xx_core_reg {\n\tuint32_t num;\n\tconst char *name;\n\tuint32_t size;\n\tuint8_t eame;\n\tuint32_t instr_mask;\n\tstruct target *target;\n\tstruct dsp563xx_common *dsp563xx_common;\n};\n\nstatic inline struct dsp563xx_common *target_to_dsp563xx(struct target *target)\n{\n\treturn target->arch_info;\n}\n\n#endif /* OPENOCD_TARGET_DSP563XX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp563xx_once.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Mathias Kuester                                 *\n *   mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jim.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"dsp563xx.h\"\n#include \"dsp563xx_once.h\"\n\n#define JTAG_STATUS_STATIC_MASK\t\t0x03\n#define JTAG_STATUS_STATIC_VALUE\t0x01\n\n#define JTAG_STATUS_NORMAL\t\t0x01\n#define JTAG_STATUS_STOPWAIT\t\t0x05\n#define JTAG_STATUS_BUSY\t\t0x09\n#define JTAG_STATUS_DEBUG\t\t0x0d\n\n#define JTAG_INSTR_EXTEST\t\t0x00\n#define JTAG_INSTR_SAMPLE_PRELOAD\t0x01\n#define JTAG_INSTR_IDCODE\t\t0x02\n#define JTAG_INSTR_HIZ\t\t\t0x04\n#define JTAG_INSTR_CLAMP\t\t0x05\n#define JTAG_INSTR_ENABLE_ONCE\t\t0x06\n#define JTAG_INSTR_DEBUG_REQUEST\t0x07\n#define JTAG_INSTR_BYPASS\t\t0x0F\n\n/** */\nstatic inline int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, int dr_len, int rti)\n{\n\tjtag_add_plain_dr_scan(dr_len, dr_out, dr_in, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\n/** */\nstatic inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t *dr_in, uint8_t dr_out, int dr_len, int rti)\n{\n\treturn dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);\n}\n\n/** */\nstatic inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in, uint32_t dr_out, int dr_len, int rti)\n{\n\treturn dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti);\n}\n\n/** single word instruction */\nstatic inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t instr,\n\t\t\t\t\t\t\t\t\t\tuint8_t rw, uint8_t go, uint8_t ex)\n{\n\tint err;\n\n\terr = dsp563xx_write_dr_u8(tap, NULL, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\treturn err;\n}\n\n/* IR and DR functions */\nstatic inline int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, int ir_len, int rti)\n{\n\tjtag_add_plain_ir_scan(tap->ir_length, ir_out, ir_in, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nstatic inline int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti)\n{\n\treturn dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);\n}\n\nstatic inline int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out)\n{\n\treturn dsp563xx_write_ir_u8(tap, ir_in, ir_out, tap->ir_length, 1);\n}\n\n/** */\nint dsp563xx_once_target_status(struct jtag_tap *tap)\n{\n\tint err;\n\tuint8_t jtag_status;\n\n\terr = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE);\n\tif (err != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\terr = jtag_execute_queue();\n\tif (err != ERROR_OK)\n\t\treturn TARGET_UNKNOWN;\n\n\t/* verify correct static status pattern */\n\tif ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE)\n\t\treturn TARGET_UNKNOWN;\n\n\tif (jtag_status != JTAG_STATUS_DEBUG)\n\t\treturn TARGET_RUNNING;\n\n\treturn TARGET_HALTED;\n}\n\n/** */\nint dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)\n{\n\tint err;\n\tuint8_t ir_in = 0, pattern = 0;\n\tuint32_t retry = 0;\n\n\t/* in reset state we only get a ACK\n\t * from the interface */\n\tif (reset_state)\n\t\tpattern = 1;\n\telse\n\t\tpattern = JTAG_STATUS_DEBUG;\n\n\t/* wait until we get the ack */\n\twhile (ir_in != pattern) {\n\t\terr = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = jtag_execute_queue();\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tLOG_DEBUG(\"debug request: %02X\", ir_in);\n\n\t\tif (retry++ == 100)\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\t/* we cant enable the once in reset state */\n\tif (pattern == 1)\n\t\treturn ERROR_OK;\n\n\t/* try to enable once */\n\tretry = 0;\n\tir_in = 0;\n\twhile (ir_in != pattern) {\n\t\terr = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t\terr = jtag_execute_queue();\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tLOG_DEBUG(\"enable once: %02X\", ir_in);\n\n\t\tif (retry++ == 100) {\n\t\t\tLOG_DEBUG(\"error\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t}\n\t}\n\n\tif (ir_in != JTAG_STATUS_DEBUG)\n\t\treturn ERROR_TARGET_FAILURE;\n\n\treturn ERROR_OK;\n}\n\n/** once read registers */\nint dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len)\n{\n\tint i;\n\tint err = ERROR_OK;\n\n\tfor (i = 0; i < len; i++) {\n\t\terr = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\treturn err;\n}\n\n/** once read register with register len */\nint dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t *data)\n{\n\tint err;\n\n\terr = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\n\treturn err;\n}\n\n/** once read register */\nint dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t *data)\n{\n\tint err;\n\n\terr = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\n\treturn err;\n}\n\n/** once write register */\nint dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data)\n{\n\tint err;\n\n\terr = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, NULL, data, 24, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\treturn err;\n}\n\n/** single word instruction */\nint dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode)\n{\n\tint err;\n\n\terr = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, NULL, opcode, 24, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush)\n\t\terr = jtag_execute_queue();\n\treturn err;\n}\n\n/** double word instruction */\nint dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand)\n{\n\tint err;\n\n\terr = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, NULL, opcode, 24, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush) {\n\t\terr = jtag_execute_queue();\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\terr = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\terr = dsp563xx_write_dr_u32(tap, NULL, operand, 24, 0);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\tif (flush) {\n\t\terr = jtag_execute_queue();\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp563xx_once.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2009 by Mathias Kuester                                 *\n *   mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_DSP563XX_ONCE_H\n#define OPENOCD_TARGET_DSP563XX_ONCE_H\n\n#include <jtag/jtag.h>\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define DSP563XX_ONCE_OCR_EX\t(1<<5)\n#define DSP563XX_ONCE_OCR_GO\t(1<<6)\n#define DSP563XX_ONCE_OCR_RW\t(1<<7)\n\n#define DSP563XX_ONCE_OSCR_OS1\t(1<<7)\n#define DSP563XX_ONCE_OSCR_OS0\t(1<<6)\n#define DSP563XX_ONCE_OSCR_HIT\t(1<<5)\n#define DSP563XX_ONCE_OSCR_TO\t(1<<4)\n#define DSP563XX_ONCE_OSCR_MBO\t(1<<3)\n#define DSP563XX_ONCE_OSCR_SWO\t(1<<2)\n#define DSP563XX_ONCE_OSCR_IME\t(1<<1)\n#define DSP563XX_ONCE_OSCR_TME\t(1<<0)\n\n#define DSP563XX_ONCE_OSCR_NORMAL_M\t(0)\n#define DSP563XX_ONCE_OSCR_STOPWAIT_M\t(DSP563XX_ONCE_OSCR_OS0)\n#define DSP563XX_ONCE_OSCR_BUSY_M\t(DSP563XX_ONCE_OSCR_OS1)\n#define DSP563XX_ONCE_OSCR_DEBUG_M\t(DSP563XX_ONCE_OSCR_OS0|DSP563XX_ONCE_OSCR_OS1)\n\n#define DSP563XX_ONCE_OSCR\t0x000\t/* status/ctrl reg. */\n#define DSP563XX_ONCE_OMBC\t0x001\t/* memory breakp. reg. */\n#define DSP563XX_ONCE_OBCR\t0x002\t/* breakp. ctrl reg */\n#define DSP563XX_ONCE_OMLR0\t0x005\t/* memory limit reg */\n#define DSP563XX_ONCE_OMLR1\t0x006\t/* memory limit reg */\n#define DSP563XX_ONCE_OGDBR\t0x009\t/* gdb reg */\n#define DSP563XX_ONCE_OPDBR\t0x00A\t/* pdb reg */\n#define DSP563XX_ONCE_OPILR\t0x00B\t/* pil reg */\n#define DSP563XX_ONCE_PDBGOTO\t0x00C\t/* pdb to go reg */\n#define DSP563XX_ONCE_OTC\t0x00D\t/* trace cnt */\n#define DSP563XX_ONCE_TAGB\t0x00E\t/* tags buffer */\n#define DSP563XX_ONCE_OPABFR\t0x00F\t/* pab fetch reg */\n#define DSP563XX_ONCE_OPABDR\t0x010\t/* pab decode reg */\n#define DSP563XX_ONCE_OPABEX\t0x011\t/* pab exec reg */\n#define DSP563XX_ONCE_OPABF11\t0x012\t/* trace buffer/inc ptr */\n#define DSP563XX_ONCE_NOREG\t0x01F\t/* no register selected */\n\nstruct once_reg {\n\tconst uint8_t num;\n\tconst uint8_t addr;\n\tconst uint8_t len;\n\tconst char *name;\n\tuint32_t reg;\n};\n\n/** */\nint dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state);\n/** */\nint dsp563xx_once_target_status(struct jtag_tap *tap);\n\n/** once read registers */\nint dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg *regs, int len);\n/** once read register */\nint dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint8_t len, uint32_t *data);\n/** once read register */\nint dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t *data);\n/** once write register */\nint dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32_t data);\n/** single word instruction */\nint dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode);\n/** double word instruction */\nint dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode, uint32_t operand);\n\n#endif /* OPENOCD_TARGET_DSP563XX_ONCE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp5680xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *  Copyright (C) 2011 by Rodrigo L. Rosa                                 *\n *  rodrigorosa.LG@gmail.com                                              *\n *                                                                        *\n *  Based on dsp563xx_once.h written by Mathias Kuester                   *\n *  mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"dsp5680xx.h\"\n\nstatic struct dsp5680xx_common dsp5680xx_context;\n\n#define _E \"DSP5680XX_ERROR:%d\\nAt:%s:%d:%s\"\n#define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; }\n#define err_check_propagate(retval) if (retval != ERROR_OK) return retval;\n#define DEBUG_MSG \"Debug mode be enabled to read mem.\"\n#define DEBUG_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IN_DEBUG, DEBUG_MSG) }\n#define CHECK_DBG if (!dsp5680xx_context.debug_mode_enabled) DEBUG_FAIL\n#define HALT_MSG \"Target must be halted.\"\n#define HALT_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_TARGET_RUNNING, HALT_MSG) }\n#define CHECK_HALT(target) if (target->state != TARGET_HALTED) HALT_FAIL\n#define check_halt_and_debug(target) { CHECK_HALT(target); CHECK_DBG; }\n\nstatic int dsp5680xx_execute_queue(void)\n{\n\tint retval;\n\n\tretval = jtag_execute_queue();\n\treturn retval;\n}\n\n/**\n * Reset state machine\n */\nstatic int reset_jtag(void)\n{\n\tint retval;\n\n\ttap_state_t states[2];\n\n\tconst char *cp = \"RESET\";\n\n\tstates[0] = tap_state_by_name(cp);\n\tretval = jtag_add_statemove(states[0]);\n\terr_check_propagate(retval);\n\tretval = jtag_execute_queue();\n\terr_check_propagate(retval);\n\tjtag_add_pathmove(0, states + 1);\n\tretval = jtag_execute_queue();\n\treturn retval;\n}\n\nstatic int dsp5680xx_drscan(struct target *target, uint8_t *d_in,\n\t\t\t    uint8_t *d_out, int len)\n{\n\t/* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n\t *\n\t *Inputs:\n\t *    - d_in: This is the data that will be shifted into the JTAG DR reg.\n\t *    - d_out: The data that will be shifted out of the JTAG DR reg will stored here\n\t *    - len: Length of the data to be shifted to JTAG DR.\n\t *\n\t *Note:  If  d_out   ==  NULL, discard incoming bits.\n\t *\n\t *-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --\n\t */\n\tint retval = ERROR_OK;\n\n\tif (!target->tap) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP,\n\t\t\t  \"Invalid tap\");\n\t}\n\tif (len > 32) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW,\n\t\t\t  \"dr_len overflow, maximum is 32\");\n\t}\n\t/* TODO what values of len are valid for jtag_add_plain_dr_scan? */\n\t/* can i send as many bits as i want? */\n\t/* is the casting necessary? */\n\tjtag_add_plain_dr_scan(len, d_in, d_out, TAP_IDLE);\n\tif (dsp5680xx_context.flush) {\n\t\tretval = dsp5680xx_execute_queue();\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_DRSCAN,\n\t\t\t  \"drscan failed!\");\n\t}\n\tif (d_out)\n\t\tLOG_DEBUG(\"Data read (%d bits): 0x%04X\", len, *d_out);\n\telse\n\t\tLOG_DEBUG(\"Data read was discarded.\");\n\treturn retval;\n}\n\n/**\n * Test func\n *\n * @param target\n * @param d_in This is the data that will be shifted into the JTAG IR reg.\n * @param d_out The data that will be shifted out of the JTAG IR reg will be stored here.\n * @param ir_len Length of the data to be shifted to JTAG IR.\n *\n */\nstatic int dsp5680xx_irscan(struct target *target, uint32_t *d_in,\n\t\t\t    uint32_t *d_out, uint8_t ir_len)\n{\n\tint retval = ERROR_OK;\n\n\tuint16_t tap_ir_len = DSP5680XX_JTAG_MASTER_TAP_IRLEN;\n\n\tif (!target->tap) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP,\n\t\t\t  \"Invalid tap\");\n\t}\n\tif (ir_len != target->tap->ir_length) {\n\t\tif (target->tap->enabled) {\n\t\t\tretval = ERROR_FAIL;\n\t\t\terr_check(retval, DSP5680XX_ERROR_INVALID_IR_LEN,\n\t\t\t\t  \"Invalid irlen\");\n\t\t} else {\n\t\t\tstruct jtag_tap *t =\n\t\t\t\tjtag_tap_by_string(\"dsp568013.chp\");\n\t\t\tif ((!t)\n\t\t\t    || ((t->enabled) && (ir_len != tap_ir_len))) {\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\terr_check(retval,\n\t\t\t\t\t  DSP5680XX_ERROR_INVALID_IR_LEN,\n\t\t\t\t\t  \"Invalid irlen\");\n\t\t\t}\n\t\t}\n\t}\n\tjtag_add_plain_ir_scan(ir_len, (uint8_t *) d_in, (uint8_t *) d_out,\n\t\t\t       TAP_IDLE);\n\tif (dsp5680xx_context.flush) {\n\t\tretval = dsp5680xx_execute_queue();\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_IRSCAN,\n\t\t\t  \"irscan failed!\");\n\t}\n\treturn retval;\n}\n\nstatic int dsp5680xx_jtag_status(struct target *target, uint8_t *status)\n{\n\tuint32_t read_from_ir;\n\n\tuint32_t instr;\n\n\tint retval;\n\n\tinstr = JTAG_INSTR_ENABLE_ONCE;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &read_from_ir,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tif (status)\n\t\t*status = (uint8_t) read_from_ir;\n\treturn ERROR_OK;\n}\n\nstatic int jtag_data_read(struct target *target, uint8_t *data_read,\n\t\t\t  int num_bits)\n{\n\tuint32_t bogus_instr = 0;\n\n\tint retval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &bogus_instr, data_read,\n\t\t\t\t num_bits);\n\tLOG_DEBUG(\"Data read (%d bits): 0x%04X\", num_bits, *data_read);\n\t/** TODO remove this or move to jtagio? */\n\treturn retval;\n}\n\n#define jtag_data_read8(target, data_read)  jtag_data_read(target, data_read, 8)\n#define jtag_data_read16(target, data_read) jtag_data_read(target, data_read, 16)\n#define jtag_data_read32(target, data_read) jtag_data_read(target, data_read, 32)\n\nstatic uint32_t data_read_dummy;\n\nstatic int jtag_data_write(struct target *target, uint32_t instr, int num_bits,\n\t\t\t   uint32_t *data_read)\n{\n\tint retval;\n\n\tretval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr,\n\t\t\t\t (uint8_t *) &data_read_dummy, num_bits);\n\terr_check_propagate(retval);\n\tif (data_read)\n\t\t*data_read = data_read_dummy;\n\treturn retval;\n}\n\n#define jtag_data_write8(target, instr, data_read)  jtag_data_write(target, instr, 8, data_read)\n#define jtag_data_write16(target, instr, data_read) jtag_data_write(target, instr, 16, data_read)\n#define jtag_data_write24(target, instr, data_read) jtag_data_write(target, instr, 24, data_read)\n#define jtag_data_write32(target, instr, data_read) jtag_data_write(target, instr, 32, data_read)\n\n/**\n * Executes EOnCE instruction.\n *\n * @param target\n * @param instr Instruction to execute.\n * @param rw\n * @param go\n * @param ex\n * @param eonce_status Value read from the EOnCE status register.\n *\n * @return\n */\nstatic int eonce_instruction_exec_single(struct target *target, uint8_t instr,\n\t\t\t\t\t uint8_t rw, uint8_t go, uint8_t ex,\n\t\t\t\t\t uint8_t *eonce_status)\n{\n\tint retval;\n\n\tuint32_t dr_out_tmp;\n\n\tuint8_t instr_with_flags = instr | (rw << 7) | (go << 6) | (ex << 5);\n\n\tretval = jtag_data_write(target, instr_with_flags, 8, &dr_out_tmp);\n\terr_check_propagate(retval);\n\tif (eonce_status)\n\t\t*eonce_status = (uint8_t) dr_out_tmp;\n\treturn retval;\n}\n\n/* wrappers for multi opcode instructions */\n#define dsp5680xx_exe_1(target, oc1, oc2, oc3)\t dsp5680xx_exe1(target, oc1)\n#define dsp5680xx_exe_2(target, oc1, oc2, oc3)\t dsp5680xx_exe2(target, oc1, oc2)\n#define dsp5680xx_exe_3(target, oc1, oc2, oc3)\t dsp5680xx_exe3(target, oc1, oc2, oc3)\n#define dsp5680xx_exe_generic(t, words, oc1, oc2, oc3) dsp5680xx_exe_##words(t, oc1, oc2, oc3)\n\n/* Executes one word DSP instruction */\nstatic int dsp5680xx_exe1(struct target *target, uint16_t opcode)\n{\n\tint retval;\n\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode, NULL);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/* Executes two word DSP instruction */\nstatic int dsp5680xx_exe2(struct target *target, uint16_t opcode1,\n\t\t\t  uint16_t opcode2)\n{\n\tint retval;\n\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode1, NULL);\n\terr_check_propagate(retval);\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode2, NULL);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/* Executes three word DSP instruction */\nstatic int dsp5680xx_exe3(struct target *target, uint16_t opcode1,\n\t\t\t  uint16_t opcode2, uint16_t opcode3)\n{\n\tint retval;\n\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode1, NULL);\n\terr_check_propagate(retval);\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode2, NULL);\n\terr_check_propagate(retval);\n\tretval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, opcode3, NULL);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/*\n *--------------- Real-time data exchange ---------------\n * The EOnCE Transmit (OTX) and Receive (ORX) registers are data memory mapped, each with an upper\n * and lower 16 bit word.\n * Transmit and receive directions are defined from the core’s perspective.\n * The core writes to the Transmit register and reads the Receive register, and the host through\n * JTAG writes to the Receive register and reads the Transmit register.\n * Both registers have a combined data memory mapped OTXRXSR which provides indication when\n * each may be accessed.\n * ref: eonce_rev.1.0_0208081.pdf@36\n */\n\n/* writes data into upper ORx register of the target */\nstatic int core_tx_upper_data(struct target *target, uint16_t data,\n\t\t\t      uint32_t *eonce_status_low)\n{\n\tint retval;\n\n\tretval =\n\t\teonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX1, 0, 0, 0,\n\t\t\t\t\t      NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_write16(target, data, eonce_status_low);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/* writes data into lower ORx register of the target */\n#define CMD1 eonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX, 0, 0, 0, NULL);\n#define CMD2 jtag_data_write16((t, data)\n#define core_tx_lower_data(t, data) PT1\\ PT2\n\n/**\n *\n * @param target\n * @param data_read: Returns the data read from the upper OTX register via JTAG.\n * @return: Returns an error code (see error code documentation)\n */\nstatic int core_rx_upper_data(struct target *target, uint8_t *data_read)\n{\n\tint retval;\n\n\tretval =\n\t\teonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX1, 1, 0, 0,\n\t\t\t\t\t      NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_read16(target, data_read);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/**\n *\n * @param target\n * @param data_read: Returns the data read from the lower OTX register via JTAG.\n * @return: Returns an error code (see error code documentation)\n */\nstatic int core_rx_lower_data(struct target *target, uint8_t *data_read)\n{\n\tint retval;\n\n\tretval =\n\t\teonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX, 1, 0, 0,\n\t\t\t\t\t      NULL);\n\terr_check_propagate(retval);\n\tretval = jtag_data_read16(target, data_read);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/*\n *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- --\n *-- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- --\n *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- --\n */\n\n#define exe(a, b, c, d, e) dsp5680xx_exe_generic(a, b, c, d, e)\n\n/* move.l #value, r0 */\n#define core_move_long_to_r0(target, value)\texe(target, 3, 0xe418, value&0xffff, value>>16)\n\n/* move.l #value, n */\n#define core_move_long_to_n(target, value)\texe(target, 3, 0xe41e, value&0xffff, value>>16)\n\n/* move x:(r0), y0 */\n#define core_move_at_r0_to_y0(target)\texe(target, 1, 0xF514, 0, 0)\n\n/* move x:(r0), y1 */\n#define core_move_at_r0_to_y1(target)\texe(target, 1, 0xF714, 0, 0)\n\n/* move.l x:(r0), y */\n#define core_move_long_at_r0_y(target) exe(target, 1, 0xF734, 0, 0)\n\n/* move y0, x:(r0) */\n#define core_move_y0_at_r0(target)\texe(target, 1, 0xd514, 0, 0)\n\n/* bfclr #value, x:(r0) */\n#define eonce_bfclr_at_r0(target, value)\texe(target, 2, 0x8040, value, 0)\n\n/* move #value, y0 */\n#define core_move_value_to_y0(target, value)\texe(target, 2, 0x8745, value, 0)\n\n/* move.w y0, x:(r0)+ */\n#define core_move_y0_at_r0_inc(target)\texe(target, 1, 0xd500, 0, 0)\n\n/* move.w y0, p:(r0)+ */\n#define core_move_y0_at_pr0_inc(target)\texe(target, 1, 0x8560, 0, 0)\n\n/* move.w p:(r0)+, y0 */\n#define core_move_at_pr0_inc_to_y0(target)\texe(target, 1, 0x8568, 0, 0)\n\n/* move.w p:(r0)+, y1 */\n#define core_move_at_pr0_inc_to_y1(target)\texe(target, 1, 0x8768, 0, 0)\n\n/* move.l #value, r2 */\n#define core_move_long_to_r2(target, value)\texe(target, 3, 0xe41A, value&0xffff, value>>16)\n\n/* move y0, x:(r2) */\n#define core_move_y0_at_r2(target)\t     exe(target, 1, 0xd516, 0, 0)\n\n/* move.w #<value>, x:(r2) */\n#define core_move_value_at_r2(target, value)\texe(target, 2, 0x8642, value, 0)\n\n/* move.w #<value>, x:(r0) */\n#define core_move_value_at_r0(target, value)\texe(target, 2, 0x8640, value, 0)\n\n/* move.w #<value>, x:(R2+<disp>) */\n#define core_move_value_at_r2_disp(target, value, disp)\texe(target, 3, 0x8646, value, disp)\n\n/* move.w x:(r2), Y0 */\n#define core_move_at_r2_to_y0(target)\texe(target, 1, 0xF516, 0, 0)\n\n/* move.w p:(r2)+, y0 */\n#define core_move_at_pr2_inc_to_y0(target)\texe(target, 1, 0x856A, 0, 0)\n\n/* move.l #value, r3 */\n#define core_move_long_to_r1(target, value)\texe(target, 3, 0xE419, value&0xffff, value>>16)\n\n/* move.l #value, r3 */\n#define core_move_long_to_r3(target, value)\texe(target, 3, 0xE41B, value&0xffff, value>>16)\n\n/* move.w y0, p:(r3)+ */\n#define core_move_y0_at_pr3_inc(target)\texe(target, 1, 0x8563, 0, 0)\n\n/* move.w y0, x:(r3) */\n#define core_move_y0_at_r3(target)\texe(target, 1, 0xD503, 0, 0)\n\n/* move.l #value, r4 */\n#define core_move_long_to_r4(target, value)\texe(target, 3, 0xE41C, value&0xffff, value>>16)\n\n/* move pc, r4 */\n#define core_move_pc_to_r4(target)\texe(target, 1, 0xE716, 0, 0)\n\n/* move.l r4, y */\n#define core_move_r4_to_y(target)\texe(target, 1, 0xe764, 0, 0)\n\n/* move.w p:(r0)+, y0 */\n#define core_move_at_pr0_inc_to_y0(target)\texe(target, 1, 0x8568, 0, 0)\n\n/* move.w x:(r0)+, y0 */\n#define core_move_at_r0_inc_to_y0(target)\texe(target, 1, 0xf500, 0, 0)\n\n/* move x:(r0), y0 */\n#define core_move_at_r0_y0(target)\texe(target, 1, 0xF514, 0, 0)\n\n/* nop */\n#define eonce_nop(target)\texe(target, 1, 0xe700, 0, 0)\n\n/* move.w x:(R2+<disp>), Y0 */\n#define core_move_at_r2_disp_to_y0(target, disp) exe(target, 2, 0xF542, disp, 0)\n\n/* move.w y1, x:(r2) */\n#define core_move_y1_at_r2(target) exe(target, 1, 0xd716, 0, 0)\n\n/* move.w y1, x:(r0) */\n#define core_move_y1_at_r0(target) exe(target, 1, 0xd714, 0, 0)\n\n/* move.bp y0, x:(r0)+ */\n#define core_move_byte_y0_at_r0(target) exe(target, 1, 0xd5a0, 0, 0)\n\n/* move.w y1, p:(r0)+ */\n#define core_move_y1_at_pr0_inc(target) exe(target, 1, 0x8760, 0, 0)\n\n/* move.w y1, x:(r0)+ */\n#define core_move_y1_at_r0_inc(target) exe(target, 1, 0xD700, 0, 0)\n\n/* move.l #value, y */\n#define core_move_long_to_y(target, value) exe(target, 3, 0xe417, value&0xffff, value>>16)\n\nstatic int core_move_value_to_pc(struct target *target, uint32_t value)\n{\n\tcheck_halt_and_debug(target);\n\tint retval;\n\n\tretval =\n\t\tdsp5680xx_exe_generic(target, 3, 0xE71E, value & 0xffff,\n\t\t\t\t      value >> 16);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\nstatic int eonce_load_tx_rx_to_r0(struct target *target)\n{\n\tint retval;\n\n\tretval =\n\t\tcore_move_long_to_r0(target,\n\t\t\t\t     ((MC568013_EONCE_TX_RX_ADDR) +\n\t\t\t\t      (MC568013_EONCE_OBASE_ADDR << 16)));\n\treturn retval;\n}\n\nstatic int core_load_tx_rx_high_addr_to_r0(struct target *target)\n{\n\tint retval = 0;\n\n\tretval =\n\t\tcore_move_long_to_r0(target,\n\t\t\t\t     ((MC568013_EONCE_TX1_RX1_HIGH_ADDR) +\n\t\t\t\t      (MC568013_EONCE_OBASE_ADDR << 16)));\n\treturn retval;\n}\n\nstatic int dsp5680xx_read_core_reg(struct target *target, uint8_t reg_addr,\n\t\t\t\t   uint16_t *data_read)\n{\n\t/* TODO implement a general version of this which matches what openocd uses. */\n\tint retval;\n\n\tuint32_t dummy_data_to_shift_into_dr;\n\n\tretval = eonce_instruction_exec_single(target, reg_addr, 1, 0, 0, NULL);\n\terr_check_propagate(retval);\n\tretval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &dummy_data_to_shift_into_dr,\n\t\t\t\t (uint8_t *) data_read, 8);\n\terr_check_propagate(retval);\n\tLOG_DEBUG(\"Reg. data: 0x%02X.\", *data_read);\n\treturn retval;\n}\n\nstatic int eonce_read_status_reg(struct target *target, uint16_t *data)\n{\n\tint retval;\n\n\tretval = dsp5680xx_read_core_reg(target, DSP5680XX_ONCE_OSR, data);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/**\n * Takes the core out of debug mode.\n *\n * @param target\n * @param eonce_status Data read from the EOnCE status register.\n *\n * @return\n */\nstatic int eonce_exit_debug_mode(struct target *target, uint8_t *eonce_status)\n{\n\tint retval;\n\n\tretval =\n\t\teonce_instruction_exec_single(target, 0x1F, 0, 0, 1, eonce_status);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\nstatic int switch_tap(struct target *target, struct jtag_tap *master_tap,\n\t\t      struct jtag_tap *core_tap)\n{\n\tint retval = ERROR_OK;\n\n\tuint32_t instr;\n\n\tuint32_t ir_out;\t/* not used, just to make jtag happy. */\n\n\tif (!master_tap) {\n\t\tmaster_tap = jtag_tap_by_string(\"dsp568013.chp\");\n\t\tif (!master_tap) {\n\t\t\tretval = ERROR_FAIL;\n\t\t\tconst char *msg = \"Failed to get master tap.\";\n\n\t\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER,\n\t\t\t\t  msg);\n\t\t}\n\t}\n\tif (!core_tap) {\n\t\tcore_tap = jtag_tap_by_string(\"dsp568013.cpu\");\n\t\tif (!core_tap) {\n\t\t\tretval = ERROR_FAIL;\n\t\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE,\n\t\t\t\t  \"Failed to get core tap.\");\n\t\t}\n\t}\n\n\tif (!(((int)master_tap->enabled) ^ ((int)core_tap->enabled))) {\n\t\tLOG_WARNING\n\t\t\t(\"Master:%d\\nCore:%d\\nOnly 1 should be enabled.\\n\",\n\t\t\t (int)master_tap->enabled, (int)core_tap->enabled);\n\t}\n\n\tif (master_tap->enabled) {\n\t\tinstr = 0x5;\n\t\tretval =\n\t\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t\t DSP5680XX_JTAG_MASTER_TAP_IRLEN);\n\t\terr_check_propagate(retval);\n\t\tinstr = 0x2;\n\t\tretval =\n\t\t\tdsp5680xx_drscan(target, (uint8_t *) &instr,\n\t\t\t\t\t (uint8_t *) &ir_out, 4);\n\t\terr_check_propagate(retval);\n\t\tcore_tap->enabled = true;\n\t\tmaster_tap->enabled = false;\n\t} else {\n\t\tinstr = 0x08;\n\t\tretval =\n\t\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\t\terr_check_propagate(retval);\n\t\tinstr = 0x1;\n\t\tretval =\n\t\t\tdsp5680xx_drscan(target, (uint8_t *) &instr,\n\t\t\t\t\t (uint8_t *) &ir_out, 4);\n\t\terr_check_propagate(retval);\n\t\tcore_tap->enabled = false;\n\t\tmaster_tap->enabled = true;\n\t}\n\treturn retval;\n}\n\n/**\n * Puts the core into debug mode, enabling the EOnCE module.\n * This will not always work, eonce_enter_debug_mode executes much\n * more complicated routine, which is guaranteed to work, but requires\n * a reset. This will complicate comm with the flash module, since\n * after a reset clock divisors must be set again.\n * This implementation works most of the time, and is not accessible to the\n * user.\n *\n * @param target\n * @param eonce_status Data read from the EOnCE status register.\n *\n * @return\n */\nstatic int eonce_enter_debug_mode_without_reset(struct target *target,\n\t\t\t\t\t\tuint16_t *eonce_status)\n{\n\tint retval;\n\n\tuint32_t instr = JTAG_INSTR_DEBUG_REQUEST;\n\n\tuint32_t ir_out;\t/* not used, just to make jtag happy.*/\n\n\t/* Debug request #1 */\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\n\t/* Enable EOnCE module */\n\tinstr = JTAG_INSTR_ENABLE_ONCE;\n\t/* Two rounds of jtag 0x6  (enable eonce) to enable EOnCE. */\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tif ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG)\n\t\ttarget->state = TARGET_HALTED;\n\telse {\n\t\tretval = ERROR_FAIL;\n\t\terr_check_propagate(retval);\n\t}\n\t/* Verify that debug mode is enabled */\n\tuint16_t data_read_from_dr;\n\n\tretval = eonce_read_status_reg(target, &data_read_from_dr);\n\terr_check_propagate(retval);\n\tif ((data_read_from_dr & 0x30) == 0x30) {\n\t\tLOG_DEBUG(\"EOnCE successfully entered debug mode.\");\n\t\tdsp5680xx_context.debug_mode_enabled = true;\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tdsp5680xx_context.debug_mode_enabled = false;\n\t\tretval = ERROR_TARGET_FAILURE;\n\t\t/**\n\t\t *No error msg here, since there is still hope with full halting sequence\n\t\t */\n\t\terr_check_propagate(retval);\n\t}\n\tif (eonce_status)\n\t\t*eonce_status = data_read_from_dr;\n\treturn retval;\n}\n\n/**\n * Puts the core into debug mode, enabling the EOnCE module.\n *\n * @param target\n * @param eonce_status Data read from the EOnCE status register.\n *\n * @return\n */\nstatic int eonce_enter_debug_mode(struct target *target,\n\t\t\t\t  uint16_t *eonce_status)\n{\n\tint retval = ERROR_OK;\n\n\tuint32_t instr = JTAG_INSTR_DEBUG_REQUEST;\n\n\tuint32_t ir_out;\t/* not used, just to make jtag happy. */\n\n\tuint16_t instr_16;\n\n\tuint16_t read_16;\n\n\t/* First try the easy way */\n\tretval = eonce_enter_debug_mode_without_reset(target, eonce_status);\n\tif (retval == ERROR_OK)\n\t\treturn retval;\n\n\tstruct jtag_tap *tap_chp;\n\n\tstruct jtag_tap *tap_cpu;\n\n\ttap_chp = jtag_tap_by_string(\"dsp568013.chp\");\n\tif (!tap_chp) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\ttap_cpu = jtag_tap_by_string(\"dsp568013.cpu\");\n\tif (!tap_cpu) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\t/* Enable master tap */\n\ttap_chp->enabled = true;\n\ttap_cpu->enabled = false;\n\n\tinstr = MASTER_TAP_CMD_IDCODE;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_MASTER_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000);\n\n\t/* Enable EOnCE module */\n\tjtag_add_reset(0, 1);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000);\n\tinstr = 0x0606ffff;     /* This was selected experimentally. */\n\tretval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out,\n\t\t\t\t 32);\n\terr_check_propagate(retval);\n\t/* ir_out now hold tap idcode */\n\n\t/* Enable core tap */\n\ttap_chp->enabled = true;\n\tretval = switch_tap(target, tap_chp, tap_cpu);\n\terr_check_propagate(retval);\n\n\tinstr = JTAG_INSTR_ENABLE_ONCE;\n\t/* Two rounds of jtag 0x6  (enable eonce) to enable EOnCE. */\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tinstr = JTAG_INSTR_DEBUG_REQUEST;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tinstr_16 = 0x1;\n\tretval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr_16,\n\t\t\t\t (uint8_t *) &read_16, 8);\n\terr_check_propagate(retval);\n\tinstr_16 = 0x20;\n\tretval =\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr_16,\n\t\t\t\t (uint8_t *) &read_16, 8);\n\terr_check_propagate(retval);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000);\n\tjtag_add_reset(0, 0);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000);\n\n\tinstr = JTAG_INSTR_ENABLE_ONCE;\n\t/* Two rounds of jtag 0x6  (enable eonce) to enable EOnCE. */\n\tfor (int i = 0; i < 3; i++) {\n\t\tretval =\n\t\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\t\terr_check_propagate(retval);\n\t}\n\tif ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG)\n\t\ttarget->state = TARGET_HALTED;\n\telse {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_HALT,\n\t\t\t  \"Failed to halt target.\");\n\t}\n\n\tfor (int i = 0; i < 3; i++) {\n\t\tinstr_16 = 0x86;\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr_16,\n\t\t\t\t (uint8_t *) &read_16, 16);\n\t\tinstr_16 = 0xff;\n\t\tdsp5680xx_drscan(target, (uint8_t *) &instr_16,\n\t\t\t\t (uint8_t *) &read_16, 16);\n\t}\n\n\t/* Verify that debug mode is enabled */\n\tuint16_t data_read_from_dr;\n\n\tretval = eonce_read_status_reg(target, &data_read_from_dr);\n\terr_check_propagate(retval);\n\tif ((data_read_from_dr & 0x30) == 0x30) {\n\t\tLOG_DEBUG(\"EOnCE successfully entered debug mode.\");\n\t\tdsp5680xx_context.debug_mode_enabled = true;\n\t\tretval = ERROR_OK;\n\t} else {\n\t\tconst char *msg = \"Failed to set EOnCE module to debug mode\";\n\n\t\tretval = ERROR_TARGET_FAILURE;\n\t\terr_check(retval, DSP5680XX_ERROR_ENTER_DEBUG_MODE, msg);\n\t}\n\tif (eonce_status)\n\t\t*eonce_status = data_read_from_dr;\n\treturn retval;\n}\n\n/**\n * Reads the current value of the program counter and stores it.\n *\n * @param target\n *\n * @return\n */\nstatic int eonce_pc_store(struct target *target)\n{\n\tuint8_t tmp[2];\n\n\tint retval;\n\n\tretval = core_move_pc_to_r4(target);\n\terr_check_propagate(retval);\n\tretval = core_move_r4_to_y(target);\n\terr_check_propagate(retval);\n\tretval = eonce_load_tx_rx_to_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_y0_at_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_rx_lower_data(target, tmp);\n\terr_check_propagate(retval);\n\tLOG_USER(\"PC value: 0x%X%X\\n\", tmp[1], tmp[0]);\n\tdsp5680xx_context.stored_pc = (tmp[0] | (tmp[1] << 8));\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct dsp5680xx_common *dsp5680xx =\n\t\tcalloc(1, sizeof(struct dsp5680xx_common));\n\ttarget->arch_info = dsp5680xx;\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_init_target(struct command_context *cmd_ctx,\n\t\t\t\t struct target *target)\n{\n\tdsp5680xx_context.stored_pc = 0;\n\tdsp5680xx_context.flush = 1;\n\tdsp5680xx_context.debug_mode_enabled = false;\n\tLOG_DEBUG(\"target initiated!\");\n\t/* TODO core tap must be enabled before running these commands, currently\n\t * this is done in the .cfg tcl script. */\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_arch_state(struct target *target)\n{\n\tLOG_USER(\"%s not implemented yet.\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_assert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RESET;\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_deassert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RUNNING;\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_halt(struct target *target)\n{\n\tint retval;\n\n\tuint16_t eonce_status = 0xbeef;\n\n\tif ((target->state == TARGET_HALTED)\n\t    && (dsp5680xx_context.debug_mode_enabled)) {\n\t\tLOG_USER(\"Target already halted and in debug mode.\");\n\t\treturn ERROR_OK;\n\t} else {\n\t\tif (target->state == TARGET_HALTED)\n\t\t\tLOG_USER\n\t\t\t\t(\"Target already halted, re attempting to enter debug mode.\");\n\t}\n\tretval = eonce_enter_debug_mode(target, &eonce_status);\n\terr_check_propagate(retval);\n\tretval = eonce_pc_store(target);\n\terr_check_propagate(retval);\n\tif (dsp5680xx_context.debug_mode_enabled) {\n\t\tretval = eonce_pc_store(target);\n\t\terr_check_propagate(retval);\n\t}\n\treturn retval;\n}\n\nstatic int dsp5680xx_poll(struct target *target)\n{\n\tint retval;\n\n\tuint8_t jtag_status;\n\n\tuint8_t eonce_status;\n\n\tuint16_t read_tmp;\n\n\tretval = dsp5680xx_jtag_status(target, &jtag_status);\n\terr_check_propagate(retval);\n\tif (jtag_status == JTAG_STATUS_DEBUG)\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tretval = eonce_enter_debug_mode(target, &read_tmp);\n\t\t\terr_check_propagate(retval);\n\t\t\teonce_status = (uint8_t) read_tmp;\n\t\t\tif ((eonce_status & EONCE_STAT_MASK) !=\n\t\t\t    DSP5680XX_ONCE_OSCR_DEBUG_M) {\n\t\t\t\tconst char *msg =\n\t\t\t\t\t\"%s: Failed to put EOnCE in debug mode.Flash locked?...\";\n\t\t\t\tLOG_WARNING(msg, __func__);\n\t\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t\t} else {\n\t\t\t\ttarget->state = TARGET_HALTED;\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\tif (jtag_status == JTAG_STATUS_NORMAL) {\n\t\tif (target->state == TARGET_RESET) {\n\t\t\tretval = dsp5680xx_halt(target);\n\t\t\terr_check_propagate(retval);\n\t\t\tretval = eonce_exit_debug_mode(target, &eonce_status);\n\t\t\terr_check_propagate(retval);\n\t\t\tif ((eonce_status & EONCE_STAT_MASK) !=\n\t\t\t    DSP5680XX_ONCE_OSCR_NORMAL_M) {\n\t\t\t\tconst char *msg =\n\t\t\t\t\t\"%s: JTAG running, but EOnCE run failed.Try resetting..\";\n\t\t\t\tLOG_WARNING(msg, __func__);\n\t\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t\t} else {\n\t\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t\tif (target->state != TARGET_RUNNING) {\n\t\t\tretval = eonce_read_status_reg(target, &read_tmp);\n\t\t\terr_check_propagate(retval);\n\t\t\teonce_status = (uint8_t) read_tmp;\n\t\t\tif ((eonce_status & EONCE_STAT_MASK) !=\n\t\t\t    DSP5680XX_ONCE_OSCR_NORMAL_M) {\n\t\t\t\tLOG_WARNING\n\t\t\t\t\t(\"Inconsistent target status. Restart!\");\n\t\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t\t}\n\t\t}\n\t\ttarget->state = TARGET_RUNNING;\n\t\treturn ERROR_OK;\n\t}\n\tif (jtag_status == JTAG_STATUS_DEAD) {\n\t\tLOG_ERROR\n\t\t\t(\"%s: Cannot communicate with JTAG. Check connection...\",\n\t\t\t __func__);\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\tif (target->state == TARGET_UNKNOWN) {\n\t\tLOG_ERROR(\"%s: Target status invalid - communication failure\",\n\t\t\t  __func__);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_resume(struct target *target, int current,\n\t\t\t    target_addr_t address, int hb, int d)\n{\n\tif (target->state == TARGET_RUNNING) {\n\t\tLOG_USER(\"Target already running.\");\n\t\treturn ERROR_OK;\n\t}\n\tint retval;\n\n\tuint8_t eonce_status;\n\n\tuint8_t jtag_status;\n\n\tif (dsp5680xx_context.debug_mode_enabled) {\n\t\tif (!current) {\n\t\t\tretval = core_move_value_to_pc(target, address);\n\t\t\terr_check_propagate(retval);\n\t\t}\n\n\t\tint retry = 20;\n\n\t\twhile (retry-- > 1) {\n\t\t\tretval = eonce_exit_debug_mode(target, &eonce_status);\n\t\t\terr_check_propagate(retval);\n\t\t\tif (eonce_status == DSP5680XX_ONCE_OSCR_NORMAL_M)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (retry == 0) {\n\t\t\tretval = ERROR_TARGET_FAILURE;\n\t\t\terr_check(retval, DSP5680XX_ERROR_EXIT_DEBUG_MODE,\n\t\t\t\t  \"Failed to exit debug mode...\");\n\t\t} else {\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\tdsp5680xx_context.debug_mode_enabled = false;\n\t\t}\n\t\tLOG_DEBUG(\"EOnCE status: 0x%02X.\", eonce_status);\n\t} else {\n\t\t/*\n\t\t * If debug mode was not enabled but target was halted, then it is most likely that\n\t\t * access to eonce registers is locked.\n\t\t * Reset target to make it run again.\n\t\t */\n\t\tjtag_add_reset(0, 1);\n\t\tjtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000);\n\n\t\tretval = reset_jtag();\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_RESET,\n\t\t\t  \"Failed to reset JTAG state machine\");\n\t\tjtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000);\n\t\tjtag_add_reset(0, 0);\n\t\tjtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000);\n\t\tretval = dsp5680xx_jtag_status(target, &jtag_status);\n\t\terr_check_propagate(retval);\n\t\tif ((jtag_status & JTAG_STATUS_MASK) == JTAG_STATUS_NORMAL) {\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\tdsp5680xx_context.debug_mode_enabled = false;\n\t\t} else {\n\t\t\tretval = ERROR_TARGET_FAILURE;\n\t\t\terr_check(retval, DSP5680XX_ERROR_RESUME,\n\t\t\t\t  \"Failed to resume target\");\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * The value of @a address determines if it corresponds to P: (program) or X: (dat) memory.\n * If the address is over 0x200000 then it is considered X: memory, and @a pmem = 0.\n * The special case of 0xFFXXXX is not modified, since it allows to read out the\n * memory mapped EOnCE registers.\n *\n * @param address\n * @param pmem\n *\n * @return\n */\nstatic int dsp5680xx_convert_address(uint32_t *address, int *pmem)\n{\n\t/*\n\t * Distinguish data memory (x) from program memory (p) by the address.\n\t * Addresses over S_FILE_DATA_OFFSET are considered (x) memory.\n\t */\n\tif (*address >= S_FILE_DATA_OFFSET) {\n\t\t*pmem = 0;\n\t\tif (((*address) & 0xff0000) != 0xff0000)\n\t\t\t*address -= S_FILE_DATA_OFFSET;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int dsp5680xx_read_16_single(struct target *t, uint32_t a,\n\t\t\t\t    uint8_t *data_read, int r_pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tint retval;\n\n\tretval = core_move_long_to_r0(target, address);\n\terr_check_propagate(retval);\n\tif (r_pmem)\n\t\tretval = core_move_at_pr0_inc_to_y0(target);\n\telse\n\t\tretval = core_move_at_r0_to_y0(target);\n\terr_check_propagate(retval);\n\tretval = eonce_load_tx_rx_to_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_y0_at_r0(target);\n\terr_check_propagate(retval);\n\t/* at this point the data i want is at the reg eonce can read */\n\tretval = core_rx_lower_data(target, data_read);\n\terr_check_propagate(retval);\n\tLOG_DEBUG(\"%s:Data read from 0x%06\" PRIX32 \": 0x%02X%02X\", __func__, address,\n\t\t  data_read[1], data_read[0]);\n\treturn retval;\n}\n\nstatic int dsp5680xx_read_32_single(struct target *t, uint32_t a,\n\t\t\t\t    uint8_t *data_read, int r_pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tint retval;\n\n\taddress = (address & 0xFFFFF);\n\t/* Get data to an intermediate register */\n\tretval = core_move_long_to_r0(target, address);\n\terr_check_propagate(retval);\n\tif (r_pmem) {\n\t\tretval = core_move_at_pr0_inc_to_y0(target);\n\t\terr_check_propagate(retval);\n\t\tretval = core_move_at_pr0_inc_to_y1(target);\n\t\terr_check_propagate(retval);\n\t} else {\n\t\tretval = core_move_at_r0_inc_to_y0(target);\n\t\terr_check_propagate(retval);\n\t\tretval = core_move_at_r0_to_y1(target);\n\t\terr_check_propagate(retval);\n\t}\n\t/* Get lower part of data to TX/RX */\n\tretval = eonce_load_tx_rx_to_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_y0_at_r0_inc(target);    /* This also load TX/RX high to r0 */\n\terr_check_propagate(retval);\n\t/* Get upper part of data to TX/RX */\n\tretval = core_move_y1_at_r0(target);\n\terr_check_propagate(retval);\n\t/* at this point the data i want is at the reg eonce can read */\n\tretval = core_rx_lower_data(target, data_read);\n\terr_check_propagate(retval);\n\tretval = core_rx_upper_data(target, data_read + 2);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\nstatic int dsp5680xx_read(struct target *t, target_addr_t a, uint32_t size,\n\t\t\t  uint32_t count, uint8_t *buf)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tuint8_t *buffer = buf;\n\n\tcheck_halt_and_debug(target);\n\n\tint retval = ERROR_OK;\n\n\tint pmem = 1;\n\n\tretval = dsp5680xx_convert_address(&address, &pmem);\n\terr_check_propagate(retval);\n\n\tdsp5680xx_context.flush = 0;\n\tint counter = FLUSH_COUNT_READ_WRITE;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tif (--counter == 0) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\tcounter = FLUSH_COUNT_READ_WRITE;\n\t\t}\n\t\tswitch (size) {\n\t\tcase 1:\n\t\t\tif (!(i % 2))\n\t\t\t\tretval =\n\t\t\t\t\tdsp5680xx_read_16_single(target,\n\t\t\t\t\t\t\t\t address + i / 2,\n\t\t\t\t\t\t\t\t buffer + i, pmem);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tretval =\n\t\t\t\tdsp5680xx_read_16_single(target, address + i,\n\t\t\t\t\t\t\t buffer + 2 * i, pmem);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tretval =\n\t\t\t\tdsp5680xx_read_32_single(target, address + 2 * i,\n\t\t\t\t\t\t\t buffer + 4 * i, pmem);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_USER(\"%s: Invalid read size.\", __func__);\n\t\t\tbreak;\n\t\t}\n\t\terr_check_propagate(retval);\n\t\tdsp5680xx_context.flush = 0;\n\t}\n\n\tdsp5680xx_context.flush = 1;\n\tretval = dsp5680xx_execute_queue();\n\terr_check_propagate(retval);\n\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_16_single(struct target *t, uint32_t a,\n\t\t\t\t     uint16_t data, uint8_t w_pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tint retval = 0;\n\n\tretval = core_move_long_to_r0(target, address);\n\terr_check_propagate(retval);\n\tif (w_pmem) {\n\t\tretval = core_move_value_to_y0(target, data);\n\t\terr_check_propagate(retval);\n\t\tretval = core_move_y0_at_pr0_inc(target);\n\t\terr_check_propagate(retval);\n\t} else {\n\t\tretval = core_move_value_at_r0(target, data);\n\t\terr_check_propagate(retval);\n\t}\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_32_single(struct target *t, uint32_t a,\n\t\t\t\t     uint32_t data, int w_pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tint retval = ERROR_OK;\n\n\tretval = core_move_long_to_r0(target, address);\n\terr_check_propagate(retval);\n\tretval = core_move_long_to_y(target, data);\n\terr_check_propagate(retval);\n\tif (w_pmem)\n\t\tretval = core_move_y0_at_pr0_inc(target);\n\telse\n\t\tretval = core_move_y0_at_r0_inc(target);\n\terr_check_propagate(retval);\n\tif (w_pmem)\n\t\tretval = core_move_y1_at_pr0_inc(target);\n\telse\n\t\tretval = core_move_y1_at_r0_inc(target);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c,\n\t\t\t     const uint8_t *d, int pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tuint32_t count = c;\n\n\tconst uint8_t *data = d;\n\n\tint retval = 0;\n\n\tuint16_t data_16;\n\n\tuint32_t iter;\n\n\tint counter = FLUSH_COUNT_READ_WRITE;\n\n\tfor (iter = 0; iter < count / 2; iter++) {\n\t\tif (--counter == 0) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\tcounter = FLUSH_COUNT_READ_WRITE;\n\t\t}\n\t\tdata_16 = (data[2 * iter] | (data[2 * iter + 1] << 8));\n\t\tretval =\n\t\t\tdsp5680xx_write_16_single(target, address + iter, data_16,\n\t\t\t\t\t\t  pmem);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: Could not write to p:0x%04\" PRIX32, __func__,\n\t\t\t\t  address);\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\treturn retval;\n\t\t}\n\t\tdsp5680xx_context.flush = 0;\n\t}\n\tdsp5680xx_context.flush = 1;\n\n\t/* Only one byte left, let's not overwrite the other byte (mem is 16bit) */\n\t/* Need to retrieve the part we do not want to overwrite. */\n\tuint16_t data_old;\n\n\tif ((count == 1) || (count % 2)) {\n\t\tretval =\n\t\t\tdsp5680xx_read(target, address + iter, 1, 1,\n\t\t\t\t       (uint8_t *) &data_old);\n\t\terr_check_propagate(retval);\n\t\tif (count == 1)\n\t\t\tdata_old = (((data_old & 0xff) << 8) | data[0]); /* preserve upper byte */\n\t\telse\n\t\t\tdata_old =\n\t\t\t\t(((data_old & 0xff) << 8) | data[2 * iter + 1]);\n\t\tretval =\n\t\t\tdsp5680xx_write_16_single(target, address + iter, data_old,\n\t\t\t\t\t\t  pmem);\n\t\terr_check_propagate(retval);\n\t}\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_16(struct target *t, uint32_t a, uint32_t c,\n\t\t\t      const uint8_t *d, int pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tuint32_t count = c;\n\n\tconst uint8_t *data = d;\n\n\tint retval = ERROR_OK;\n\n\tuint32_t iter;\n\n\tint counter = FLUSH_COUNT_READ_WRITE;\n\n\tfor (iter = 0; iter < count; iter++) {\n\t\tif (--counter == 0) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\tcounter = FLUSH_COUNT_READ_WRITE;\n\t\t}\n\t\tretval =\n\t\t\tdsp5680xx_write_16_single(target, address + iter,\n\t\t\t\t\t\t  data[iter], pmem);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: Could not write to p:0x%04\" PRIX32, __func__,\n\t\t\t\t  address);\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\treturn retval;\n\t\t}\n\t\tdsp5680xx_context.flush = 0;\n\t}\n\tdsp5680xx_context.flush = 1;\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c,\n\t\t\t      const uint8_t *d, int pmem)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tuint32_t count = c;\n\n\tconst uint8_t *data = d;\n\n\tint retval = ERROR_OK;\n\n\tuint32_t iter;\n\n\tint counter = FLUSH_COUNT_READ_WRITE;\n\n\tfor (iter = 0; iter < count; iter++) {\n\t\tif (--counter == 0) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\tcounter = FLUSH_COUNT_READ_WRITE;\n\t\t}\n\t\tretval =\n\t\t\tdsp5680xx_write_32_single(target, address + (iter << 1),\n\t\t\t\t\t\t  data[iter], pmem);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: Could not write to p:0x%04\" PRIX32, __func__,\n\t\t\t\t  address);\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\treturn retval;\n\t\t}\n\t\tdsp5680xx_context.flush = 0;\n\t}\n\tdsp5680xx_context.flush = 1;\n\treturn retval;\n}\n\n/**\n * Writes @a buffer to memory.\n * The parameter @a address determines whether @a buffer should be written to\n * P: (program) memory or X: (dat) memory.\n *\n * @param target\n * @param a address\n * @param size Bytes (1), Half words (2), Words (4).\n * @param count In bytes.\n * @param b buffer\n *\n * @return\n */\nstatic int dsp5680xx_write(struct target *target, target_addr_t a, uint32_t size, uint32_t count,\n\t\t\t   const uint8_t *b)\n{\n\t/* TODO Cannot write 32bit to odd address, will write 0x12345678  as 0x5678 0x0012 */\n\tuint32_t address = a;\n\n\tuint8_t const *buffer = b;\n\n\tcheck_halt_and_debug(target);\n\n\tint retval = 0;\n\n\tint p_mem = 1;\n\n\tretval = dsp5680xx_convert_address(&address, &p_mem);\n\terr_check_propagate(retval);\n\n\tswitch (size) {\n\tcase 1:\n\t\tretval =\n\t\t\tdsp5680xx_write_8(target, address, count, buffer, p_mem);\n\t\tbreak;\n\tcase 2:\n\t\tretval =\n\t\t\tdsp5680xx_write_16(target, address, count, buffer, p_mem);\n\t\tbreak;\n\tcase 4:\n\t\tretval =\n\t\t\tdsp5680xx_write_32(target, address, count, buffer, p_mem);\n\t\tbreak;\n\tdefault:\n\t\tretval = ERROR_TARGET_DATA_ABORT;\n\t\terr_check(retval, DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT,\n\t\t\t  \"Invalid data size.\");\n\t\tbreak;\n\t}\n\treturn retval;\n}\n\nstatic int dsp5680xx_write_buffer(struct target *t, target_addr_t a, uint32_t size,\n\t\t\t\t  const uint8_t *b)\n{\n\tcheck_halt_and_debug(t);\n\treturn dsp5680xx_write(t, a, 1, size, b);\n}\n\n/**\n * This function is called by verify_image, it is used to read data from memory.\n *\n * @param target\n * @param address Word addressing.\n * @param size In bytes.\n * @param buffer\n *\n * @return\n */\nstatic int dsp5680xx_read_buffer(struct target *target, target_addr_t address, uint32_t size,\n\t\t\t\t uint8_t *buffer)\n{\n\tcheck_halt_and_debug(target);\n\t/* The \"/2\" solves the byte/word addressing issue.*/\n\treturn dsp5680xx_read(target, address, 2, size / 2, buffer);\n}\n\n/**\n * This function is not implemented.\n * It returns an error in order to get OpenOCD to do read out the data\n * and calculate the CRC, or try a binary comparison.\n *\n * @param target\n * @param address Start address of the image.\n * @param size In bytes.\n * @param checksum\n *\n * @return\n */\nstatic int dsp5680xx_checksum_memory(struct target *target, target_addr_t address, uint32_t size,\n\t\t\t\t     uint32_t *checksum)\n{\n\treturn ERROR_FAIL;\n}\n\n/**\n * Calculates a signature over @a word_count words in the data from @a buff8.\n * The algorithm used is the same the FM uses, so the @a return may be used to compare\n * with the one generated by the FM module, and check if flashing was successful.\n * This algorithm is based on the perl script available from the Freescale website at FAQ 25630.\n *\n * @param buff8\n * @param word_count\n *\n * @return\n */\nstatic int perl_crc(const uint8_t *buff8, uint32_t word_count)\n{\n\tuint16_t checksum = 0xffff;\n\n\tuint16_t data, fbmisr;\n\n\tuint32_t i;\n\n\tfor (i = 0; i < word_count; i++) {\n\t\tdata = (buff8[2 * i] | (buff8[2 * i + 1] << 8));\n\t\tfbmisr =\n\t\t\t(checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16)\n\t\t\t\t>> 4 ^ (checksum & 0x8000) >> 15;\n\t\tchecksum = (data ^ ((checksum << 1) | fbmisr));\n\t}\n\ti--;\n\tfor (; !(i & 0x80000000); i--) {\n\t\tdata = (buff8[2 * i] | (buff8[2 * i + 1] << 8));\n\t\tfbmisr =\n\t\t\t(checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16)\n\t\t\t\t       >> 4 ^ (checksum & 0x8000) >> 15;\n\t\tchecksum = (data ^ ((checksum << 1) | fbmisr));\n\t}\n\treturn checksum;\n}\n\n/**\n * Resets the SIM. (System Integration Modul).\n *\n * @param target\n *\n * @return\n */\nstatic int dsp5680xx_f_sim_reset(struct target *target)\n{\n\tint retval = ERROR_OK;\n\n\tuint16_t sim_cmd = SIM_CMD_RESET;\n\n\tuint32_t sim_addr;\n\n\tif (strcmp(target->tap->chip, \"dsp568013\") == 0) {\n\t\tsim_addr = MC568013_SIM_BASE_ADDR + S_FILE_DATA_OFFSET;\n\t\tretval =\n\t\t\tdsp5680xx_write(target, sim_addr, 1, 2,\n\t\t\t\t\t(const uint8_t *)&sim_cmd);\n\t\terr_check_propagate(retval);\n\t}\n\treturn retval;\n}\n\n/**\n * Halts the core and resets the SIM. (System Integration Modul).\n *\n * @param target\n *\n * @return\n */\nstatic int dsp5680xx_soft_reset_halt(struct target *target)\n{\n\t/* TODO is this what this function is expected to do...? */\n\tint retval;\n\n\tretval = dsp5680xx_halt(target);\n\terr_check_propagate(retval);\n\tretval = dsp5680xx_f_sim_reset(target);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\nint dsp5680xx_f_protect_check(struct target *target, uint16_t *protected)\n{\n\tint retval;\n\n\tcheck_halt_and_debug(target);\n\tif (!protected) {\n\t\tconst char *msg = \"NULL pointer not valid.\";\n\n\t\terr_check(ERROR_FAIL,\n\t\t\t  DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg);\n\t}\n\tretval =\n\t\tdsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_PROT,\n\t\t\t\t\t (uint8_t *) protected, 0);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/**\n * Executes a command on the FM module.\n * Some commands use the parameters @a address and @a data, others ignore them.\n *\n * @param target\n * @param c Command to execute.\n * @param address Command parameter.\n * @param data Command parameter.\n * @param hfm_ustat FM status register.\n * @param pmem Address is P: (program) memory (@a pmem == 1) or X: (dat) memory (@a pmem == 0)\n *\n * @return\n */\nstatic int dsp5680xx_f_ex(struct target *target, uint16_t c, uint32_t address, uint32_t data,\n\t\t\t  uint16_t *hfm_ustat, int pmem)\n{\n\tuint32_t command = c;\n\tint retval;\n\n\tretval = core_load_tx_rx_high_addr_to_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_long_to_r2(target, HFM_BASE_ADDR);\n\terr_check_propagate(retval);\n\tuint8_t i[2];\n\n\tint watchdog = 100;\n\n\tdo {\n\t\tretval = core_move_at_r2_disp_to_y0(target, HFM_USTAT); /* read HMF_USTAT */\n\t\terr_check_propagate(retval);\n\t\tretval = core_move_y0_at_r0(target);\n\t\terr_check_propagate(retval);\n\t\tretval = core_rx_upper_data(target, i);\n\t\terr_check_propagate(retval);\n\t\tif ((watchdog--) == 1) {\n\t\t\tretval = ERROR_TARGET_FAILURE;\n\t\t\tconst char *msg =\n\t\t\t\t\"Timed out waiting for FM to finish old command.\";\n\t\t\terr_check(retval, DSP5680XX_ERROR_FM_BUSY, msg);\n\t\t}\n\t} while (!(i[0] & 0x40)); /* wait until current command is complete */\n\n\tdsp5680xx_context.flush = 0;\n\n\t/* write to HFM_CNFG (lock=0,select bank) - flash_desc.bank&0x03, 0x01 == 0x00, 0x01 ??? */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG);\n\terr_check_propagate(retval);\n\t/* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */\n\tretval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT);\n\terr_check_propagate(retval);\n\t/* clear only one bit at a time */\n\tretval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT);\n\terr_check_propagate(retval);\n\tretval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT);\n\terr_check_propagate(retval);\n\t/* write to HMF_PROT, clear protection */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT);\n\terr_check_propagate(retval);\n\t/* write to HMF_PROTB, clear protection */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB);\n\terr_check_propagate(retval);\n\tretval = core_move_value_to_y0(target, data);\n\terr_check_propagate(retval);\n\t/* write to the flash block */\n\tretval = core_move_long_to_r3(target, address);\n\terr_check_propagate(retval);\n\tif (pmem) {\n\t\tretval = core_move_y0_at_pr3_inc(target);\n\t\terr_check_propagate(retval);\n\t} else {\n\t\tretval = core_move_y0_at_r3(target);\n\t\terr_check_propagate(retval);\n\t}\n\t/* write command to the HFM_CMD reg */\n\tretval = core_move_value_at_r2_disp(target, command, HFM_CMD);\n\terr_check_propagate(retval);\n\t/* start the command */\n\tretval = core_move_value_at_r2_disp(target, 0x80, HFM_USTAT);\n\terr_check_propagate(retval);\n\n\tdsp5680xx_context.flush = 1;\n\tretval = dsp5680xx_execute_queue();\n\terr_check_propagate(retval);\n\n\twatchdog = 100;\n\tdo {\n\t\t/* read HMF_USTAT */\n\t\tretval = core_move_at_r2_disp_to_y0(target, HFM_USTAT);\n\t\terr_check_propagate(retval);\n\t\tretval = core_move_y0_at_r0(target);\n\t\terr_check_propagate(retval);\n\t\tretval = core_rx_upper_data(target, i);\n\t\terr_check_propagate(retval);\n\t\tif ((watchdog--) == 1) {\n\t\t\tretval = ERROR_TARGET_FAILURE;\n\t\t\terr_check(retval, DSP5680XX_ERROR_FM_CMD_TIMED_OUT,\n\t\t\t\t  \"FM execution did not finish.\");\n\t\t}\n\t} while (!(i[0] & 0x40)); /* wait until the command is complete */\n\t*hfm_ustat = ((i[0] << 8) | (i[1]));\n\tif (i[0] & HFM_USTAT_MASK_PVIOL_ACCER) {\n\t\tretval = ERROR_TARGET_FAILURE;\n\t\tconst char *msg =\n\t\t\t\"pviol and/or accer bits set. HFM command execution error\";\n\t\terr_check(retval, DSP5680XX_ERROR_FM_EXEC, msg);\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * Prior to the execution of any Flash module command, the Flash module Clock\n * Divider (CLKDIV) register must be initialized. The values of this register\n * determine the speed of the internal Flash Clock (FCLK). FCLK must be in the\n * range of 150kHz ≤ FCLK ≤ 200kHz for proper operation of the Flash module.\n * (Running FCLK too slowly wears out the module, while running it too fast\n * under programs Flash leading to bit errors.)\n *\n * @param target\n *\n * @return\n */\nstatic int set_fm_ck_div(struct target *target)\n{\n\tuint8_t i[2];\n\n\tint retval;\n\n\tretval = core_move_long_to_r2(target, HFM_BASE_ADDR);\n\terr_check_propagate(retval);\n\tretval = core_load_tx_rx_high_addr_to_r0(target);\n\terr_check_propagate(retval);\n\t/* read HFM_CLKD */\n\tretval = core_move_at_r2_to_y0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_y0_at_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_rx_upper_data(target, i);\n\terr_check_propagate(retval);\n\tunsigned int hfm_at_wrong_value = 0;\n\n\tif ((i[0] & 0x7f) != HFM_CLK_DEFAULT) {\n\t\tLOG_DEBUG(\"HFM CLK divisor contained incorrect value (0x%02X).\",\n\t\t\t  i[0] & 0x7f);\n\t\thfm_at_wrong_value = 1;\n\t} else {\n\t\tLOG_DEBUG\n\t\t\t(\"HFM CLK divisor was already set to correct value (0x%02X).\",\n\t\t\t i[0] & 0x7f);\n\t\treturn ERROR_OK;\n\t}\n\t/* write HFM_CLKD */\n\tretval = core_move_value_at_r2(target, HFM_CLK_DEFAULT);\n\terr_check_propagate(retval);\n\t/* verify HFM_CLKD */\n\tretval = core_move_at_r2_to_y0(target);\n\terr_check_propagate(retval);\n\tretval = core_move_y0_at_r0(target);\n\terr_check_propagate(retval);\n\tretval = core_rx_upper_data(target, i);\n\terr_check_propagate(retval);\n\tif (i[0] != (0x80 | (HFM_CLK_DEFAULT & 0x7f))) {\n\t\tretval = ERROR_TARGET_FAILURE;\n\t\terr_check(retval, DSP5680XX_ERROR_FM_SET_CLK,\n\t\t\t  \"Unable to set HFM CLK divisor.\");\n\t}\n\tif (hfm_at_wrong_value)\n\t\tLOG_DEBUG(\"HFM CLK divisor set to 0x%02x.\", i[0] & 0x7f);\n\treturn ERROR_OK;\n}\n\n/**\n * Executes the FM calculate signature command. The FM will calculate over the\n * data from @a address to @a address + @a words -1. The result is written to a\n * register, then read out by this function and returned in @a signature. The\n * value @a signature may be compared to the one returned by perl_crc to\n * verify the flash was written correctly.\n *\n * @param target\n * @param address Start of flash array where the signature should be calculated.\n * @param words Number of words over which the signature should be calculated.\n * @param signature Value calculated by the FM.\n *\n * @return\n */\nstatic int dsp5680xx_f_signature(struct target *target, uint32_t address, uint32_t words,\n\t\t\t\t uint16_t *signature)\n{\n\tint retval;\n\n\tuint16_t hfm_ustat;\n\n\tif (!dsp5680xx_context.debug_mode_enabled) {\n\t\tretval = eonce_enter_debug_mode_without_reset(target, NULL);\n\t\t/*\n\t\t * Generate error here, since it is not done in eonce_enter_debug_mode_without_reset\n\t\t */\n\t\terr_check(retval, DSP5680XX_ERROR_HALT,\n\t\t\t  \"Failed to halt target.\");\n\t}\n\tretval =\n\t\tdsp5680xx_f_ex(target, HFM_CALCULATE_DATA_SIGNATURE, address, words,\n\t\t\t       &hfm_ustat, 1);\n\terr_check_propagate(retval);\n\tretval =\n\t\tdsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_DATA,\n\t\t\t\t\t (uint8_t *) signature, 0);\n\treturn retval;\n}\n\nint dsp5680xx_f_erase_check(struct target *target, uint8_t *erased,\n\t\t\t    uint32_t sector)\n{\n\tint retval;\n\n\tuint16_t hfm_ustat;\n\n\tuint32_t tmp;\n\n\tif (!dsp5680xx_context.debug_mode_enabled) {\n\t\tretval = dsp5680xx_halt(target);\n\t\terr_check_propagate(retval);\n\t}\n\tretval = set_fm_ck_div(target);\n\terr_check_propagate(retval);\n\t/*\n\t * Check if chip is already erased.\n\t */\n\ttmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2;\n\tretval =\n\t\tdsp5680xx_f_ex(target, HFM_ERASE_VERIFY, tmp, 0, &hfm_ustat, 1);\n\terr_check_propagate(retval);\n\tif (erased)\n\t\t*erased = (uint8_t) (hfm_ustat & HFM_USTAT_MASK_BLANK);\n\treturn retval;\n}\n\n/**\n * Executes the FM page erase command.\n *\n * @param target\n * @param sector Page to erase.\n * @param hfm_ustat FM module status register.\n *\n * @return\n */\nstatic int erase_sector(struct target *target, int sector, uint16_t *hfm_ustat)\n{\n\tint retval;\n\n\tuint32_t tmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2;\n\n\tretval = dsp5680xx_f_ex(target, HFM_PAGE_ERASE, tmp, 0, hfm_ustat, 1);\n\terr_check_propagate(retval);\n\treturn retval;\n}\n\n/**\n * Executes the FM mass erase command. Erases the flash array completely.\n *\n * @param target\n * @param hfm_ustat FM module status register.\n *\n * @return\n */\nstatic int mass_erase(struct target *target, uint16_t *hfm_ustat)\n{\n\tint retval;\n\n\tretval = dsp5680xx_f_ex(target, HFM_MASS_ERASE, 0, 0, hfm_ustat, 1);\n\treturn retval;\n}\n\nint dsp5680xx_f_erase(struct target *target, int first, int last)\n{\n\tint retval;\n\n\tif (!dsp5680xx_context.debug_mode_enabled) {\n\t\tretval = dsp5680xx_halt(target);\n\t\terr_check_propagate(retval);\n\t}\n\t/*\n\t * Reset SIM\n\t *\n\t */\n\tretval = dsp5680xx_f_sim_reset(target);\n\terr_check_propagate(retval);\n\t/*\n\t * Set hfmdiv\n\t *\n\t */\n\tretval = set_fm_ck_div(target);\n\terr_check_propagate(retval);\n\n\tuint16_t hfm_ustat;\n\n\tint do_mass_erase = ((!(first | last))\n\t\t\t     || ((first == 0)\n\t\t\t\t && (last == (HFM_SECTOR_COUNT - 1))));\n\tif (do_mass_erase) {\n\t\t/* Mass erase */\n\t\tretval = mass_erase(target, &hfm_ustat);\n\t\terr_check_propagate(retval);\n\t} else {\n\t\tfor (int i = first; i <= last; i++) {\n\t\t\tretval = erase_sector(target, i, &hfm_ustat);\n\t\t\terr_check_propagate(retval);\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/*\n * Algorithm for programming normal p: flash\n * Follow state machine from \"56F801x Peripheral Reference Manual\"@163.\n * Registers to set up before calling:\n * r0: TX/RX high address.\n * r2: FM module base address.\n * r3: Destination address in flash.\n *\n *\t\thfm_wait:\t\t\t\t\t   // wait for buffer empty\n *\t\t\tbrclr\t#0x80, x:(r2+0x13), hfm_wait\n *\t\trx_check:\t\t\t\t\t    // wait for input buffer full\n *\t\t\tbrclr\t#0x01, x:(r0-2), rx_check\n *\t\t\tmove.w\tx:(r0), y0\t\t\t    // read from Rx buffer\n *\t\t\tmove.w\ty0, p:(r3)+\n *\t\t\tmove.w\t#0x20, x:(r2+0x14)\t\t    // write PGM command\n *\t\t\tmove.w\t#0x80, x:(r2+0x13)\t\t    // start the command\n *\t\t\tmove.w  X:(R2+0x13), A\t\t\t    // Read USTAT register\n *\t\t      brclr       #0x20, A, accerr_check\t     // protection violation check\n *\t\t      bfset       #0x20, X:(R2+0x13)\t\t// clear pviol\n *\t\t      bra\t hfm_wait\n *\t      accerr_check:\n *\t\t      brclr       #0x10, A, hfm_wait\t\t // access error check\n *\t\t      bfset       #0x10, X:(R2+0x13)\t\t// clear accerr\n *\t\t\tbra\t    hfm_wait\t\t\t    // loop\n * 0x00000000  0x8A460013807D\t brclr       #0x80, X:(R2+0x13),*+0\n * 0x00000003  0xE700\t\t nop\n * 0x00000004  0xE700\t\t nop\n * 0x00000005  0x8A44FFFE017B\t brclr       #1, X:(R0-2),*-2\n * 0x00000008  0xE700\t\t nop\n * 0x00000009  0xF514\t\t move.w      X:(R0), Y0\n * 0x0000000A  0x8563\t\t move.w      Y0, P:(R3)+\n * 0x0000000B  0x864600200014\t move.w      #32, X:(R2+0x14)\n * 0x0000000E  0x864600800013\t move.w      #128, X:(R2+0x13)\n * 0x00000011  0xF0420013\t     move.w      X:(R2+0x13), A\n * 0x00000013  0x8B402004\t     brclr       #0x20, A,*+6\n * 0x00000015  0x824600130020\t bfset       #0x20, X:(R2+0x13)\n * 0x00000018  0xA967\t\t bra\t *-24\n * 0x00000019  0x8B401065\t     brclr       #0x10, A,*-25\n * 0x0000001B  0x824600130010\t bfset       #0x10, X:(R2+0x13)\n * 0x0000001E  0xA961\t\t bra\t *-30\n */\n\nstatic const uint16_t pgm_write_pflash[] = {\n\t\t0x8A46, 0x0013, 0x807D, 0xE700,\n\t\t0xE700, 0x8A44, 0xFFFE, 0x017B,\n\t\t0xE700, 0xF514, 0x8563, 0x8646,\n\t\t0x0020, 0x0014, 0x8646, 0x0080,\n\t\t0x0013, 0xF042, 0x0013, 0x8B40,\n\t\t0x2004, 0x8246, 0x0013, 0x0020,\n\t\t0xA967, 0x8B40, 0x1065, 0x8246,\n\t\t0x0013, 0x0010, 0xA961\n};\n\nstatic const uint32_t pgm_write_pflash_length = 31;\n\nint dsp5680xx_f_wr(struct target *t, const uint8_t *b, uint32_t a, uint32_t count,\n\t\t   int is_flash_lock)\n{\n\tstruct target *target = t;\n\n\tuint32_t address = a;\n\n\tconst uint8_t *buffer = b;\n\n\tint retval = ERROR_OK;\n\n\tif (!dsp5680xx_context.debug_mode_enabled) {\n\t\tretval = eonce_enter_debug_mode(target, NULL);\n\t\terr_check_propagate(retval);\n\t}\n\t/*\n\t * Download the pgm that flashes.\n\t *\n\t */\n\tconst uint32_t len = pgm_write_pflash_length;\n\n\tuint32_t ram_addr = 0x8700;\n\n\t/*\n\t * This seems to be a safe address.\n\t * This one is the one used by codewarrior in 56801x_flash.cfg\n\t */\n\tif (!is_flash_lock) {\n\t\tretval =\n\t\t\tdsp5680xx_write(target, ram_addr, 1, len * 2,\n\t\t\t\t\t(uint8_t *) pgm_write_pflash);\n\t\terr_check_propagate(retval);\n\t\tretval = dsp5680xx_execute_queue();\n\t\terr_check_propagate(retval);\n\t}\n\t/*\n\t * Set hfmdiv\n\t *\n\t */\n\tretval = set_fm_ck_div(target);\n\terr_check_propagate(retval);\n\t/*\n\t * Setup registers needed by pgm_write_pflash\n\t *\n\t */\n\n\tdsp5680xx_context.flush = 0;\n\n\tretval = core_move_long_to_r3(target, address); /* Destination address to r3 */\n\terr_check_propagate(retval);\n\tcore_load_tx_rx_high_addr_to_r0(target); /* TX/RX reg address to r0 */\n\terr_check_propagate(retval);\n\tretval = core_move_long_to_r2(target, HFM_BASE_ADDR); /* FM base address to r2 */\n\terr_check_propagate(retval);\n\t/*\n\t * Run flashing program.\n\t *\n\t */\n\t/* write to HFM_CNFG (lock=0, select bank) */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG);\n\terr_check_propagate(retval);\n\t/* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */\n\tretval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT);\n\terr_check_propagate(retval);\n\t/* clear only one bit at a time */\n\tretval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT);\n\terr_check_propagate(retval);\n\tretval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT);\n\terr_check_propagate(retval);\n\t/* write to HMF_PROT, clear protection */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT);\n\terr_check_propagate(retval);\n\t/* write to HMF_PROTB, clear protection */\n\tretval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB);\n\terr_check_propagate(retval);\n\tif (count % 2) {\n\t\t/* TODO implement handling of odd number of words. */\n\t\tretval = ERROR_FAIL;\n\t\tconst char *msg = \"Cannot handle odd number of words.\";\n\n\t\terr_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT,\n\t\t\t  msg);\n\t}\n\n\tdsp5680xx_context.flush = 1;\n\tretval = dsp5680xx_execute_queue();\n\terr_check_propagate(retval);\n\n\tuint32_t drscan_data;\n\n\tuint16_t tmp = (buffer[0] | (buffer[1] << 8));\n\n\tretval = core_tx_upper_data(target, tmp, &drscan_data);\n\terr_check_propagate(retval);\n\n\tretval = dsp5680xx_resume(target, 0, ram_addr, 0, 0);\n\terr_check_propagate(retval);\n\n\tint counter = FLUSH_COUNT_FLASH;\n\n\tdsp5680xx_context.flush = 0;\n\tuint32_t i;\n\n\tfor (i = 1; (i < count / 2) && (i < HFM_SIZE_WORDS); i++) {\n\t\tif (--counter == 0) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\tcounter = FLUSH_COUNT_FLASH;\n\t\t}\n\t\ttmp = (buffer[2 * i] | (buffer[2 * i + 1] << 8));\n\t\tretval = core_tx_upper_data(target, tmp, &drscan_data);\n\t\tif (retval != ERROR_OK) {\n\t\t\tdsp5680xx_context.flush = 1;\n\t\t\terr_check_propagate(retval);\n\t\t}\n\t\tdsp5680xx_context.flush = 0;\n\t}\n\tdsp5680xx_context.flush = 1;\n\tif (!is_flash_lock) {\n\t\t/*\n\t\t *Verify flash (skip when exec lock sequence)\n\t\t *\n\t\t */\n\t\tuint16_t signature;\n\n\t\tuint16_t pc_crc;\n\n\t\tretval = dsp5680xx_f_signature(target, address, i, &signature);\n\t\terr_check_propagate(retval);\n\t\tpc_crc = perl_crc(buffer, i);\n\t\tif (pc_crc != signature) {\n\t\t\tretval = ERROR_FAIL;\n\t\t\tconst char *msg =\n\t\t\t\t\"Flashed data failed CRC check, flash again!\";\n\t\t\terr_check(retval, DSP5680XX_ERROR_FLASHING_CRC, msg);\n\t\t}\n\t}\n\treturn retval;\n}\n\nint dsp5680xx_f_unlock(struct target *target)\n{\n\tint retval = ERROR_OK;\n\n\tuint16_t eonce_status;\n\n\tuint32_t instr;\n\n\tuint32_t ir_out;\n\n\tstruct jtag_tap *tap_chp;\n\n\tstruct jtag_tap *tap_cpu;\n\n\ttap_chp = jtag_tap_by_string(\"dsp568013.chp\");\n\tif (!tap_chp) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\ttap_cpu = jtag_tap_by_string(\"dsp568013.cpu\");\n\tif (!tap_cpu) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\n\tretval = eonce_enter_debug_mode_without_reset(target, &eonce_status);\n\tif (retval == ERROR_OK)\n\t\tLOG_WARNING(\"Memory was not locked.\");\n\n\tjtag_add_reset(0, 1);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000);\n\n\tretval = reset_jtag();\n\terr_check(retval, DSP5680XX_ERROR_JTAG_RESET,\n\t\t  \"Failed to reset JTAG state machine\");\n\tjtag_add_sleep(150);\n\n\t/* Enable core tap */\n\ttap_chp->enabled = true;\n\tretval = switch_tap(target, tap_chp, tap_cpu);\n\terr_check_propagate(retval);\n\n\tinstr = JTAG_INSTR_DEBUG_REQUEST;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_CORE_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000);\n\tjtag_add_reset(0, 0);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000);\n\n\t/* Enable master tap */\n\ttap_chp->enabled = false;\n\tretval = switch_tap(target, tap_chp, tap_cpu);\n\terr_check_propagate(retval);\n\n\t/* Execute mass erase to unlock */\n\tinstr = MASTER_TAP_CMD_FLASH_ERASE;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_MASTER_TAP_IRLEN);\n\terr_check_propagate(retval);\n\n\tinstr = HFM_CLK_DEFAULT;\n\tretval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, 16);\n\terr_check_propagate(retval);\n\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 150 * 1000);\n\tjtag_add_reset(0, 1);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000);\n\n\tretval = reset_jtag();\n\terr_check(retval, DSP5680XX_ERROR_JTAG_RESET,\n\t\t  \"Failed to reset JTAG state machine\");\n\tjtag_add_sleep(150);\n\n\tinstr = 0x0606ffff;\n\tretval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out,\n\t\t\t\t 32);\n\terr_check_propagate(retval);\n\n\t/* enable core tap */\n\tinstr = 0x5;\n\tretval =\n\t\tdsp5680xx_irscan(target, &instr, &ir_out,\n\t\t\t\t DSP5680XX_JTAG_MASTER_TAP_IRLEN);\n\terr_check_propagate(retval);\n\tinstr = 0x2;\n\tretval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out,\n\t\t\t\t 4);\n\terr_check_propagate(retval);\n\n\ttap_cpu->enabled = true;\n\ttap_chp->enabled = false;\n\ttarget->state = TARGET_RUNNING;\n\tdsp5680xx_context.debug_mode_enabled = false;\n\treturn retval;\n}\n\nint dsp5680xx_f_lock(struct target *target)\n{\n\tint retval;\n\n\tstruct jtag_tap *tap_chp;\n\n\tstruct jtag_tap *tap_cpu;\n\tuint16_t lock_word = HFM_LOCK_FLASH;\n\tretval = dsp5680xx_f_wr(target, (uint8_t *)&lock_word, HFM_LOCK_ADDR_L, 2, 1);\n\terr_check_propagate(retval);\n\n\tjtag_add_reset(0, 1);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000);\n\n\tretval = reset_jtag();\n\terr_check(retval, DSP5680XX_ERROR_JTAG_RESET,\n\t\t  \"Failed to reset JTAG state machine\");\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000);\n\tjtag_add_reset(0, 0);\n\tjtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000);\n\n\ttap_chp = jtag_tap_by_string(\"dsp568013.chp\");\n\tif (!tap_chp) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\ttap_cpu = jtag_tap_by_string(\"dsp568013.cpu\");\n\tif (!tap_cpu) {\n\t\tretval = ERROR_FAIL;\n\t\terr_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE,\n\t\t\t  \"Failed to get master tap.\");\n\t}\n\ttarget->state = TARGET_RUNNING;\n\tdsp5680xx_context.debug_mode_enabled = false;\n\ttap_cpu->enabled = false;\n\ttap_chp->enabled = true;\n\tretval = switch_tap(target, tap_chp, tap_cpu);\n\treturn retval;\n}\n\nstatic int dsp5680xx_step(struct target *target, int current, target_addr_t address,\n\t\t\t  int handle_breakpoints)\n{\n\terr_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP,\n\t\t  \"Not implemented yet.\");\n}\n\n/** Holds methods for dsp5680xx targets. */\nstruct target_type dsp5680xx_target = {\n\t.name = \"dsp5680xx\",\n\n\t.poll = dsp5680xx_poll,\n\t.arch_state = dsp5680xx_arch_state,\n\n\t.halt = dsp5680xx_halt,\n\t.resume = dsp5680xx_resume,\n\t.step = dsp5680xx_step,\n\n\t.write_buffer = dsp5680xx_write_buffer,\n\t.read_buffer = dsp5680xx_read_buffer,\n\n\t.assert_reset = dsp5680xx_assert_reset,\n\t.deassert_reset = dsp5680xx_deassert_reset,\n\t.soft_reset_halt = dsp5680xx_soft_reset_halt,\n\n\t.read_memory = dsp5680xx_read,\n\t.write_memory = dsp5680xx_write,\n\n\t.checksum_memory = dsp5680xx_checksum_memory,\n\n\t.target_create = dsp5680xx_target_create,\n\t.init_target = dsp5680xx_init_target,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/dsp5680xx.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Rodrigo L. Rosa                                 *\n *   rodrigorosa.LG@gmail.com                                              *\n *                                                                         *\n *   Based on dsp563xx_once.h written by Mathias Kuester                   *\n *   mkdorg@users.sourceforge.net                                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_DSP5680XX_H\n#define OPENOCD_TARGET_DSP5680XX_H\n\n#include <jtag/jtag.h>\n\n/**\n * @file   dsp5680xx.h\n * @author Rodrigo Rosa <rodrigorosa.LG@gmail.com>\n * @date   Thu Jun  9 18:54:38 2011\n *\n * @brief  Basic support for the 5680xx DSP from Freescale.\n * The chip has two taps in the JTAG chain, the Master tap and the Core tap.\n * In this code the Master tap is only used to unlock the flash memory by executing a JTAG instruction.\n *\n */\n\n#define S_FILE_DATA_OFFSET 0x200000\n#define TIME_DIV_FREESCALE 0.3\n\n/** ----------------------------------------------------------------\n * JTAG\n *----------------------------------------------------------------\n */\n#define DSP5680XX_JTAG_CORE_TAP_IRLEN\t4\n#define DSP5680XX_JTAG_MASTER_TAP_IRLEN\t8\n\n#define JTAG_STATUS_MASK\t\t0x0F\n\n#define JTAG_STATUS_NORMAL\t\t0x01\n#define JTAG_STATUS_STOPWAIT\t\t0x05\n#define JTAG_STATUS_BUSY\t\t0x09\n#define JTAG_STATUS_DEBUG\t\t0x0D\n#define JTAG_STATUS_DEAD\t\t0x0f\n\n#define JTAG_INSTR_EXTEST\t\t0x0\n#define JTAG_INSTR_SAMPLE_PRELOAD\t0x1\n#define JTAG_INSTR_IDCODE\t\t0x2\n#define JTAG_INSTR_EXTEST_PULLUP\t0x3\n#define JTAG_INSTR_HIGHZ\t\t0x4\n#define JTAG_INSTR_CLAMP\t\t0x5\n#define JTAG_INSTR_ENABLE_ONCE\t\t0x6\n#define JTAG_INSTR_DEBUG_REQUEST\t0x7\n#define JTAG_INSTR_BYPASS\t\t0xF\n /**\n * ----------------------------------------------------------------\n */\n\n/** ----------------------------------------------------------------\n * Master TAP instructions from MC56F8000RM.pdf\n * ----------------------------------------------------------------\n */\n#define MASTER_TAP_CMD_BYPASS      0xF\n#define MASTER_TAP_CMD_IDCODE      0x2\n#define MASTER_TAP_CMD_TLM_SEL     0x5\n#define MASTER_TAP_CMD_FLASH_ERASE 0x8\n /**\n * ----------------------------------------------------------------\n */\n\n /** ----------------------------------------------------------------\n * EOnCE control register info\n * ----------------------------------------------------------------\n */\n#define DSP5680XX_ONCE_OCR_EX\t(1<<5)\n/* EX Bit Definition\n   0 Remain in the Debug Processing State\n   1 Leave the Debug Processing State */\n#define DSP5680XX_ONCE_OCR_GO\t(1<<6)\n/* GO Bit Definition\n   0 Inactive—No Action Taken\n   1 Execute Controller Instruction */\n#define DSP5680XX_ONCE_OCR_RW\t(1<<7)\n/** RW Bit Definition\n * 0 Write To the Register Specified by the RS[4:0] Bits\n * 1 ReadFrom the Register Specified by the RS[4:0] Bits\n * ----------------------------------------------------------------\n */\n\n /** ----------------------------------------------------------------\n * EOnCE Status Register\n * ----------------------------------------------------------------\n */\n#define DSP5680XX_ONCE_OSCR_OS1\t (1<<5)\n#define DSP5680XX_ONCE_OSCR_OS0\t (1<<4)\n /**\n * ----------------------------------------------------------------\n */\n\n /** ----------------------------------------------------------------\n * EOnCE Core Status - Describes the operating status of the core controller\n * ----------------------------------------------------------------\n */\n#define DSP5680XX_ONCE_OSCR_NORMAL_M\t(0)\n/* 00  -   Normal      -   Controller Core Executing Instructions or in Reset */\n#define DSP5680XX_ONCE_OSCR_STOPWAIT_M\t(DSP5680XX_ONCE_OSCR_OS0)\n/* 01  -   Stop/Wait   -   Controller Core in Stop or Wait Mode */\n#define DSP5680XX_ONCE_OSCR_BUSY_M\t(DSP5680XX_ONCE_OSCR_OS1)\n/* 10  -   Busy\t-   Controller is Performing External or Peripheral Access (Wait States) */\n#define DSP5680XX_ONCE_OSCR_DEBUG_M\t(DSP5680XX_ONCE_OSCR_OS0|DSP5680XX_ONCE_OSCR_OS1)\n/* 11  -   Debug       -   Controller Core Halted and in Debug Mode */\n#define EONCE_STAT_MASK 0x30\n /**\n * ----------------------------------------------------------------\n */\n\n /** ----------------------------------------------------------------\n * Register Select Encoding (eonce_rev.1.0_0208081.pdf:14)\n * ----------------------------------------------------------------\n */\n#define DSP5680XX_ONCE_NOREG    0x00    /* No register selected */\n#define DSP5680XX_ONCE_OCR      0x01    /* OnCE Debug Control Register */\n#define DSP5680XX_ONCE_OCNTR    0x02    /* OnCE Breakpoint and Trace Counter */\n#define DSP5680XX_ONCE_OSR      0x03    /* EOnCE status register */\n#define DSP5680XX_ONCE_OBAR     0x04    /* OnCE Breakpoint Address Register */\n#define DSP5680XX_ONCE_OBASE    0x05    /* EOnCE Peripheral Base Address register */\n#define DSP5680XX_ONCE_OTXRXSR  0x06    /* EOnCE TXRX Status and Control Register (OTXRXSR)  */\n#define DSP5680XX_ONCE_OTX      0x07    /* EOnCE Transmit register (OTX)  */\n#define DSP5680XX_ONCE_OPDBR    0x08    /* EOnCE Program Data Bus Register (OPDBR) */\n#define DSP5680XX_ONCE_OTX1     0x09    /* EOnCE Upper Transmit register (OTX1) */\n#define DSP5680XX_ONCE_OPABFR   0x0A    /* OnCE Program Address Register—Fetch cycle */\n#define DSP5680XX_ONCE_ORX      0x0B    /* EOnCE Receive register (ORX) */\n#define DSP5680XX_ONCE_OCNTR_C  0x0C    /* Clear OCNTR */\n#define DSP5680XX_ONCE_ORX1     0x0D    /* EOnCE Upper Receive register (ORX1) */\n#define DSP5680XX_ONCE_OTBCR    0x0E    /* EOnCE Trace Buffer Control Reg (OTBCR) */\n#define DSP5680XX_ONCE_OPABER   0x10    /* OnCE Program Address Register—Execute cycle */\n#define DSP5680XX_ONCE_OPFIFO   0x11    /* OnCE Program address FIFO */\n#define DSP5680XX_ONCE_OBAR1    0x12    /* EOnCE Breakpoint 1 Unit 0 Address Reg.(OBAR1) */\n#define DSP5680XX_ONCE_OPABDR   0x13    /* OnCE Program Address Register—Decode cycle (OPABDR) */\n /**\n * ----------------------------------------------------------------\n */\n\n#define FLUSH_COUNT_READ_WRITE 8192 /* This value works, higher values (and lower...) may work as well. */\n#define FLUSH_COUNT_FLASH 8192\n/** ----------------------------------------------------------------\n * HFM (flash module) Commands (ref:MC56F801xRM.pdf:159)\n * ----------------------------------------------------------------\n */\n#define HFM_ERASE_VERIFY\t\t  0x05\n#define HFM_CALCULATE_DATA_SIGNATURE      0x06\n#define HFM_WORD_PROGRAM\t\t  0x20\n#define HFM_PAGE_ERASE\t\t    0x40\n#define HFM_MASS_ERASE\t\t    0x41\n#define HFM_CALCULATE_IFR_BLOCK_SIGNATURE 0x66\n /**\n * ----------------------------------------------------------------\n */\n\n/** ----------------------------------------------------------------\n * Flashing (ref:MC56F801xRM.pdf:159)\n * ----------------------------------------------------------------\n */\n#define HFM_BASE_ADDR     0x0F400   /** In x: mem. (write to S_FILE_DATA_OFFSET+HFM_BASE_ADDR\n\t\t\t\t     * to get data into x: mem.)\n\t\t\t\t     */\n/**\n * The following are register addresses, not memory\n * addresses (though all registers are memory mapped)\n */\n#define HFM_CLK_DIV       0x00  /* r/w */\n#define HFM_CNFG\t  0x01  /* r/w */\n#define HFM_SECHI\t 0x03  /* r */\n#define HFM_SECLO\t 0x04  /* r */\n#define HFM_PROT\t  0x10  /* r/w */\n#define HFM_PROTB\t 0x11  /* r/w */\n#define HFM_USTAT\t 0x13  /* r/w */\n#define HFM_CMD\t   0x14  /* r/w */\n#define HFM_DATA\t  0x18  /* r */\n#define HFM_OPT1\t  0x1B  /* r */\n#define HFM_TSTSIG\t0x1D  /* r */\n\n#define HFM_EXEC_COMPLETE  0x40\n\n/* User status register (USTAT) masks (MC56F80XXRM.pdf:6.7.5) */\n#define HFM_USTAT_MASK_BLANK 0x4\n#define HFM_USTAT_MASK_PVIOL_ACCER 0x30\n\n/**\n * The value used on for the FM clock is important to prevent flashing errors and to prevent deterioration of the FM.\n * This value was calculated using a spreadsheet tool available on the Freescale website under FAQ 25464.\n *\n */\n#define HFM_CLK_DEFAULT\t0x27\n/* 0x27 according to freescale cfg, but 0x40 according to freescale spreadsheet... */\n#define HFM_FLASH_BASE_ADDR 0x0\n#define HFM_SIZE_BYTES 0x4000   /* bytes */\n#define HFM_SIZE_WORDS 0x2000   /* words */\n#define HFM_SECTOR_SIZE 0x200   /* Size in bytes */\n#define HFM_SECTOR_COUNT 0x20\n/* A 16K block in pages of 256 words. */\n\n/**\n * Writing HFM_LOCK_FLASH to HFM_LOCK_ADDR_L and HFM_LOCK_ADDR_H will enable security on flash after the next reset.\n */\n#define HFM_LOCK_FLASH 0xE70A\n#define HFM_LOCK_ADDR_L 0x1FF7\n#define HFM_LOCK_ADDR_H 0x1FF8\n /**\n * ----------------------------------------------------------------\n */\n\n/** ----------------------------------------------------------------\n * Register Memory Map (eonce_rev.1.0_0208081.pdf:16)\n * ----------------------------------------------------------------\n */\n#define MC568013_EONCE_OBASE_ADDR 0xFF\n/* The following are relative to EONCE_OBASE_ADDR (EONCE_OBASE_ADDR<<16 + ...) */\n#define MC568013_EONCE_TX_RX_ADDR    0xFFFE\n#define MC568013_EONCE_TX1_RX1_HIGH_ADDR  0xFFFF /* Relative to EONCE_OBASE_ADDR */\n#define MC568013_EONCE_OCR 0xFFA0   /* Relative to EONCE_OBASE_ADDR */\n /**\n * ----------------------------------------------------------------\n */\n\n/** ----------------------------------------------------------------\n * SIM addresses & commands (MC56F80xx.h from freescale)\n * ----------------------------------------------------------------\n */\n#define MC568013_SIM_BASE_ADDR 0xF140\n#define MC56803X_2X_SIM_BASE_ADDR 0xF100\n\n#define SIM_CMD_RESET 0x10\n /**\n * ----------------------------------------------------------------\n */\n\n/**\n * ----------------------------------------------------------------\n * ERROR codes - enable automatic parsing of output\n * ----------------------------------------------------------------\n */\n#define DSP5680XX_ERROR_UNKNOWN_OR_ERROR_OPENOCD -100\n#define DSP5680XX_ERROR_JTAG_COMM -1\n#define DSP5680XX_ERROR_JTAG_RESET -2\n#define DSP5680XX_ERROR_JTAG_INVALID_TAP -3\n#define DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW -4\n#define DSP5680XX_ERROR_INVALID_IR_LEN -5\n#define DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER -6\n#define DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE -7\n#define DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER -8\n#define DSP5680XX_ERROR_JTAG_TAP_FIND_CORE -9\n#define DSP5680XX_ERROR_JTAG_DRSCAN -10\n#define DSP5680XX_ERROR_JTAG_IRSCAN -11\n#define DSP5680XX_ERROR_ENTER_DEBUG_MODE -12\n#define DSP5680XX_ERROR_RESUME -13\n#define DSP5680XX_ERROR_WRITE_WITH_TARGET_RUNNING -14\n#define DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT -15\n#define DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS -16\n#define DSP5680XX_ERROR_FM_BUSY -17\n#define DSP5680XX_ERROR_FM_CMD_TIMED_OUT -18\n#define DSP5680XX_ERROR_FM_EXEC -19\n#define DSP5680XX_ERROR_FM_SET_CLK -20\n#define DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT -21\n#define DSP5680XX_ERROR_FLASHING_CRC -22\n#define DSP5680XX_ERROR_FLASHING -23\n#define DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP -24\n#define DSP5680XX_ERROR_HALT -25\n#define DSP5680XX_ERROR_EXIT_DEBUG_MODE -26\n#define DSP5680XX_ERROR_TARGET_RUNNING -27\n#define DSP5680XX_ERROR_NOT_IN_DEBUG -28\n/**\n * ----------------------------------------------------------------\n */\n\nstruct dsp5680xx_common {\n\tuint32_t stored_pc;\n\tint flush;\n\tbool debug_mode_enabled;\n};\n\nstatic inline struct dsp5680xx_common *target_to_dsp5680xx(struct target\n\t\t\t\t\t\t\t   *target)\n{\n\treturn target->arch_info;\n}\n\n/**\n * Writes to flash memory.\n * Does not check if flash is erased, it's up to the user to erase the flash before running\n * this function.\n * The flashing algorithm runs from RAM, reading from a register to which this function\n * writes to. The algorithm is open loop, there is no control to verify that the FM read\n * the register before writing the next data. A closed loop approach was much slower,\n * and the current implementation does not fail, and if it did the crc check would detect it,\n * allowing to flash again.\n *\n * @param target\n * @param buffer\n * @param address Word addressing.\n * @param count In bytes.\n * @param is_flash_lock\n *\n * @return\n */\nint dsp5680xx_f_wr(struct target *target, const uint8_t *buffer, uint32_t address,\n\t\tuint32_t count, int is_flash_lock);\n\n/**\n * The FM has the functionality of checking if the flash array is erased. This function\n * executes it. It does not support individual sector analysis.\n *\n * @param target\n * @param erased\n * @param sector This parameter is ignored because the FM does not support checking if\n * individual sectors are erased.\n *\n * @return\n */\nint dsp5680xx_f_erase_check(struct target *target, uint8_t *erased,\n\t\tuint32_t sector);\n\n/**\n * Erases either a sector or the complete flash array. If either the range first-last covers\n * the complete array or if first == 0 and last == 0 then a mass erase command is executed\n * on the FM. If not, then individual sectors are erased.\n *\n * @param target\n * @param first\n * @param last\n *\n * @return\n */\nint dsp5680xx_f_erase(struct target *target, int first, int last);\n\n/**\n * Reads the memory mapped protection register. A 1 implies the sector is protected,\n * a 0 implies the sector is not protected.\n *\n * @param target\n * @param protected Data read from the protection register.\n *\n * @return\n */\nint dsp5680xx_f_protect_check(struct target *target, uint16_t *protected);\n\n/**\n * Writes the flash security words with a specific value. The chip's security will be\n * enabled after the first reset following the execution of this function.\n *\n * @param target\n *\n * @return\n */\nint dsp5680xx_f_lock(struct target *target);\n\n/**\n * Executes a mass erase command. The must be done from the Master tap.\n * It is up to the user to select the master tap (jtag tapenable dsp5680xx.chp)\n * before running this function.\n * The flash array will be unsecured (and erased) after the first reset following\n * the execution of this function.\n *\n * @param target\n *\n * @return\n */\nint dsp5680xx_f_unlock(struct target *target);\n\n#endif /* OPENOCD_TARGET_DSP5680XX_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/embeddedice.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"embeddedice.h\"\n#include \"register.h\"\n#include <helper/time_support.h>\n\n/**\n * @file\n *\n * This provides lowlevel glue to the EmbeddedICE (or EmbeddedICE-RT)\n * module found on scan chain 2 in ARM7, ARM9, and some other families\n * of ARM cores.  The module is called \"EmbeddedICE-RT\" if it has\n * monitor mode support.\n *\n * EmbeddedICE provides basic watchpoint/breakpoint hardware and a Debug\n * Communications Channel (DCC) used to read or write 32-bit words to\n * OpenOCD-aware code running on the target CPU.\n * Newer modules also include vector catch hardware.  Some versions\n * support hardware single-stepping, \"monitor mode\" debug (which is not\n * currently supported by OpenOCD), or extended reporting on why the\n * core entered debug mode.\n */\n\nstatic int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf);\n\n/*\n * From:  ARM9E-S TRM, DDI 0165, table C-4 (and similar, for other cores)\n */\nstatic const struct {\n\tconst char     *name;\n\tunsigned short addr;\n\tunsigned short width;\n} eice_regs[] = {\n\t[EICE_DBG_CTRL] = {\n\t\t.name =\t\t\"debug_ctrl\",\n\t\t.addr =\t\t0,\n\t\t/* width is assigned based on EICE version */\n\t},\n\t[EICE_DBG_STAT] = {\n\t\t.name =\t\t\"debug_status\",\n\t\t.addr =\t\t1,\n\t\t/* width is assigned based on EICE version */\n\t},\n\t[EICE_COMMS_CTRL] = {\n\t\t.name =\t\t\"comms_ctrl\",\n\t\t.addr =\t\t4,\n\t\t.width =\t6,\n\t},\n\t[EICE_COMMS_DATA] = {\n\t\t.name =\t\t\"comms_data\",\n\t\t.addr =\t\t5,\n\t\t.width =\t32,\n\t},\n\t[EICE_W0_ADDR_VALUE] = {\n\t\t.name =\t\t\"watch_0_addr_value\",\n\t\t.addr =\t\t8,\n\t\t.width =\t32,\n\t},\n\t[EICE_W0_ADDR_MASK] = {\n\t\t.name =\t\t\"watch_0_addr_mask\",\n\t\t.addr =\t\t9,\n\t\t.width =\t32,\n\t},\n\t[EICE_W0_DATA_VALUE] = {\n\t\t.name =\t\t\"watch_0_data_value\",\n\t\t.addr =\t\t10,\n\t\t.width =\t32,\n\t},\n\t[EICE_W0_DATA_MASK] = {\n\t\t.name =\t\t\"watch_0_data_mask\",\n\t\t.addr =\t\t11,\n\t\t.width =\t32,\n\t},\n\t[EICE_W0_CONTROL_VALUE] = {\n\t\t.name =\t\t\"watch_0_control_value\",\n\t\t.addr =\t\t12,\n\t\t.width =\t9,\n\t},\n\t[EICE_W0_CONTROL_MASK] = {\n\t\t.name =\t\t\"watch_0_control_mask\",\n\t\t.addr =\t\t13,\n\t\t.width =\t8,\n\t},\n\t[EICE_W1_ADDR_VALUE] = {\n\t\t.name =\t\t\"watch_1_addr_value\",\n\t\t.addr =\t\t16,\n\t\t.width =\t32,\n\t},\n\t[EICE_W1_ADDR_MASK] = {\n\t\t.name =\t\t\"watch_1_addr_mask\",\n\t\t.addr =\t\t17,\n\t\t.width =\t32,\n\t},\n\t[EICE_W1_DATA_VALUE] = {\n\t\t.name =\t\t\"watch_1_data_value\",\n\t\t.addr =\t\t18,\n\t\t.width =\t32,\n\t},\n\t[EICE_W1_DATA_MASK] = {\n\t\t.name =\t\t\"watch_1_data_mask\",\n\t\t.addr =\t\t19,\n\t\t.width =\t32,\n\t},\n\t[EICE_W1_CONTROL_VALUE] = {\n\t\t.name =\t\t\"watch_1_control_value\",\n\t\t.addr =\t\t20,\n\t\t.width =\t9,\n\t},\n\t[EICE_W1_CONTROL_MASK] = {\n\t\t.name =\t\t\"watch_1_control_mask\",\n\t\t.addr =\t\t21,\n\t\t.width =\t8,\n\t},\n\t/* vector_catch isn't always present */\n\t[EICE_VEC_CATCH] = {\n\t\t.name =\t\t\"vector_catch\",\n\t\t.addr =\t\t2,\n\t\t.width =\t8,\n\t},\n};\n\nstatic int embeddedice_get_reg(struct reg *reg)\n{\n\tint retval = embeddedice_read_reg(reg);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"error queueing EmbeddedICE register read\");\n\t\treturn retval;\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"EmbeddedICE register read failed\");\n\n\treturn retval;\n}\n\nstatic const struct reg_arch_type eice_reg_type = {\n\t.get = embeddedice_get_reg,\n\t.set = embeddedice_set_reg_w_exec,\n};\n\n/**\n * Probe EmbeddedICE module and set up local records of its registers.\n * Different versions of the modules have different capabilities, such as\n * hardware support for vector_catch, single stepping, and monitor mode.\n */\nstruct reg_cache *embeddedice_build_reg_cache(struct target *target,\n\t\tstruct arm7_9_common *arm7_9)\n{\n\tint retval;\n\tstruct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = NULL;\n\tstruct embeddedice_reg *arch_info = NULL;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint num_regs = ARRAY_SIZE(eice_regs);\n\tint i;\n\tint eice_version = 0;\n\n\t/* vector_catch isn't always present */\n\tif (!arm7_9->has_vector_catch)\n\t\tnum_regs--;\n\n\t/* the actual registers are kept in two arrays */\n\treg_list = calloc(num_regs, sizeof(struct reg));\n\tarch_info = calloc(num_regs, sizeof(struct embeddedice_reg));\n\n\t/* fill in values for the reg cache */\n\treg_cache->name = \"EmbeddedICE registers\";\n\treg_cache->next = NULL;\n\treg_cache->reg_list = reg_list;\n\treg_cache->num_regs = num_regs;\n\n\t/* FIXME the second watchpoint unit on Feroceon and Dragonite\n\t * seems not to work ... we should have a way to not set up\n\t * its four registers here!\n\t */\n\n\t/* set up registers */\n\tfor (i = 0; i < num_regs; i++) {\n\t\treg_list[i].name = eice_regs[i].name;\n\t\treg_list[i].size = eice_regs[i].width;\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].arch_info = &arch_info[i];\n\t\treg_list[i].type = &eice_reg_type;\n\t\tarch_info[i].addr = eice_regs[i].addr;\n\t\tarch_info[i].jtag_info = jtag_info;\n\t}\n\n\t/* identify EmbeddedICE version by reading DCC control register */\n\tembeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tfor (i = 0; i < num_regs; i++)\n\t\t\tfree(reg_list[i].value);\n\t\tfree(reg_list);\n\t\tfree(reg_cache);\n\t\tfree(arch_info);\n\t\treturn NULL;\n\t}\n\n\teice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4);\n\tLOG_INFO(\"Embedded ICE version %d\", eice_version);\n\n\tswitch (eice_version) {\n\t\tcase 1:\n\t\t\t/* ARM7TDMI r3, ARM7TDMI-S r3\n\t\t\t *\n\t\t\t * REVISIT docs say ARM7TDMI-S r4 uses version 1 but\n\t\t\t * that it has 6-bit CTRL and 5-bit STAT... doc bug?\n\t\t\t * ARM7TDMI r4 docs say EICE v4.\n\t\t\t */\n\t\t\treg_list[EICE_DBG_CTRL].size = 3;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t/* ARM9TDMI */\n\t\t\treg_list[EICE_DBG_CTRL].size = 4;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tarm7_9->has_single_step = 1;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tLOG_ERROR(\"EmbeddedICE v%d handling might be broken\",\n\t\t\t\t\teice_version);\n\t\t\treg_list[EICE_DBG_CTRL].size = 6;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tarm7_9->has_single_step = 1;\n\t\t\tarm7_9->has_monitor_mode = 1;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\t/* ARM7TDMI r4 */\n\t\t\treg_list[EICE_DBG_CTRL].size = 6;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tarm7_9->has_monitor_mode = 1;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\t/* ARM9E-S rev 1 */\n\t\t\treg_list[EICE_DBG_CTRL].size = 6;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tarm7_9->has_single_step = 1;\n\t\t\tarm7_9->has_monitor_mode = 1;\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\t/* ARM7EJ-S, ARM9E-S rev 2, ARM9EJ-S */\n\t\t\treg_list[EICE_DBG_CTRL].size = 6;\n\t\t\treg_list[EICE_DBG_STAT].size = 10;\n\t\t\t/* DBG_STAT has MOE bits */\n\t\t\tarm7_9->has_monitor_mode = 1;\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tLOG_ERROR(\"EmbeddedICE v%d handling might be broken\",\n\t\t\t\t\teice_version);\n\t\t\treg_list[EICE_DBG_CTRL].size = 6;\n\t\t\treg_list[EICE_DBG_STAT].size = 5;\n\t\t\tarm7_9->has_monitor_mode = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/*\n\t\t\t * The Feroceon implementation has the version number\n\t\t\t * in some unusual bits.  Let feroceon.c validate it\n\t\t\t * and do the appropriate setup itself.\n\t\t\t */\n\t\t\tif (strcmp(target_type_name(target), \"feroceon\") == 0 ||\n\t\t\t\t\tstrcmp(target_type_name(target), \"dragonite\") == 0)\n\t\t\t\tbreak;\n\t\t\tLOG_ERROR(\"unknown EmbeddedICE version \"\n\t\t\t\t\"(comms ctrl: 0x%8.8\" PRIx32 \")\",\n\t\t\t\tbuf_get_u32(reg_list[EICE_COMMS_CTRL].value, 0, 32));\n\t}\n\n\t/* On Feroceon and Dragonite the second unit is seemingly missing. */\n\tLOG_INFO(\"%s: hardware has %d breakpoint/watchpoint unit%s\",\n\t\t\ttarget_name(target), arm7_9->wp_available_max,\n\t\t\t(arm7_9->wp_available_max != 1) ? \"s\" : \"\");\n\n\treturn reg_cache;\n}\n\n/**\n * Free all memory allocated for EmbeddedICE register cache\n */\nvoid embeddedice_free_reg_cache(struct reg_cache *reg_cache)\n{\n\tif (!reg_cache)\n\t\treturn;\n\n\tfor (unsigned int i = 0; i < reg_cache->num_regs; i++)\n\t\tfree(reg_cache->reg_list[i].value);\n\n\tfree(reg_cache->reg_list[0].arch_info);\n\tfree(reg_cache->reg_list);\n\tfree(reg_cache);\n}\n\n/**\n * Initialize EmbeddedICE module, if needed.\n */\nint embeddedice_setup(struct target *target)\n{\n\tint retval;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\n\t/* Explicitly disable monitor mode.  For now we only support halting\n\t * debug ... we don't know how to talk with a resident debug monitor\n\t * that manages break requests.  ARM's \"Angel Debug Monitor\" is one\n\t * common example of such code.\n\t */\n\tif (arm7_9->has_monitor_mode) {\n\t\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n\t\tembeddedice_read_reg(dbg_ctrl);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tbuf_set_u32(dbg_ctrl->value, 4, 1, 0);\n\t\tembeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value);\n\t}\n\treturn jtag_execute_queue();\n}\n\n/**\n * Queue a read for an EmbeddedICE register into the register cache,\n * optionally checking the value read.\n * Note that at this level, all registers are 32 bits wide.\n */\nint embeddedice_read_reg_w_check(struct reg *reg,\n\t\tuint8_t *check_value, uint8_t *check_mask)\n{\n\tstruct embeddedice_reg *ice_reg = reg->arch_info;\n\tuint8_t reg_addr = ice_reg->addr & 0x1f;\n\tstruct scan_field fields[3];\n\tuint8_t field1_out[1];\n\tuint8_t field2_out[1];\n\tint retval;\n\n\tretval = arm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm_jtag_set_instr(ice_reg->jtag_info->tap,\n\t\t\tice_reg->jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* bits 31:0 -- data (ignored here) */\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = reg->value;\n\tfields[0].in_value = NULL;\n\tfields[0].check_value = NULL;\n\tfields[0].check_mask = NULL;\n\n\t/* bits 36:32 -- register */\n\tfields[1].num_bits = 5;\n\tfields[1].out_value = field1_out;\n\tfield1_out[0] = reg_addr;\n\tfields[1].in_value = NULL;\n\tfields[1].check_value = NULL;\n\tfields[1].check_mask = NULL;\n\n\t/* bit 37 -- 0/read */\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = field2_out;\n\tfield2_out[0] = 0;\n\tfields[2].in_value = NULL;\n\tfields[2].check_value = NULL;\n\tfields[2].check_mask = NULL;\n\n\t/* traverse Update-DR, setting address for the next read */\n\tjtag_add_dr_scan(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);\n\n\t/* bits 31:0 -- the data we're reading (and maybe checking) */\n\tfields[0].in_value = reg->value;\n\tfields[0].check_value = check_value;\n\tfields[0].check_mask = check_mask;\n\n\t/* when reading the DCC data register, leaving the address field set to\n\t * EICE_COMMS_DATA would read the register twice\n\t * reading the control register is safe\n\t */\n\tfield1_out[0] = eice_regs[EICE_COMMS_CTRL].addr;\n\n\t/* traverse Update-DR, reading but with no other side effects */\n\tjtag_add_dr_scan_check(ice_reg->jtag_info->tap, 3, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Receive a block of size 32-bit words from the DCC.\n * We assume the target is always going to be fast enough (relative to\n * the JTAG clock) that the debugger won't need to poll the handshake\n * bit.  The JTAG clock is usually at least six times slower than the\n * functional clock, so the 50+ JTAG clocks needed to receive the word\n * allow hundreds of instruction cycles (per word) in the target.\n */\nint embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)\n{\n\tstruct scan_field fields[3];\n\tuint8_t field1_out[1];\n\tuint8_t field2_out[1];\n\tint retval;\n\n\tretval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 5;\n\tfields[1].out_value = field1_out;\n\tfield1_out[0] = eice_regs[EICE_COMMS_DATA].addr;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = field2_out;\n\tfield2_out[0] = 0;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\twhile (size > 0) {\n\t\t/* when reading the last item, set the register address to the DCC control reg,\n\t\t * to avoid reading additional data from the DCC data reg\n\t\t */\n\t\tif (size == 1)\n\t\t\tfield1_out[0] = eice_regs[EICE_COMMS_CTRL].addr;\n\n\t\tfields[0].in_value = (uint8_t *)data;\n\t\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\t\tjtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)data);\n\n\t\tdata++;\n\t\tsize--;\n\t}\n\n\treturn jtag_execute_queue();\n}\n\n/**\n * Queue a read for an EmbeddedICE register into the register cache,\n * not checking the value read.\n */\nint embeddedice_read_reg(struct reg *reg)\n{\n\treturn embeddedice_read_reg_w_check(reg, NULL, NULL);\n}\n\n/**\n * Queue a write for an EmbeddedICE register, updating the register cache.\n * Uses embeddedice_write_reg().\n */\nvoid embeddedice_set_reg(struct reg *reg, uint32_t value)\n{\n\tembeddedice_write_reg(reg, value);\n\n\tbuf_set_u32(reg->value, 0, reg->size, value);\n\treg->valid = true;\n\treg->dirty = false;\n\n}\n\n/**\n * Write an EmbeddedICE register, updating the register cache.\n * Uses embeddedice_set_reg(); not queued.\n */\nstatic int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf)\n{\n\tint retval;\n\n\tembeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size));\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"register write failed\");\n\treturn retval;\n}\n\n/**\n * Queue a write for an EmbeddedICE register, bypassing the register cache.\n */\nvoid embeddedice_write_reg(struct reg *reg, uint32_t value)\n{\n\tstruct embeddedice_reg *ice_reg = reg->arch_info;\n\n\tLOG_DEBUG(\"%i: 0x%8.8\" PRIx32 \"\", ice_reg->addr, value);\n\n\tarm_jtag_scann(ice_reg->jtag_info, 0x2, TAP_IDLE);\n\n\tarm_jtag_set_instr(ice_reg->jtag_info->tap, ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE);\n\n\tuint8_t reg_addr = ice_reg->addr & 0x1f;\n\tembeddedice_write_reg_inner(ice_reg->jtag_info->tap, reg_addr, value);\n}\n\n/**\n * Queue a write for an EmbeddedICE register, using cached value.\n * Uses embeddedice_write_reg().\n */\nvoid embeddedice_store_reg(struct reg *reg)\n{\n\tembeddedice_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));\n}\n\n/**\n * Send a block of size 32-bit words to the DCC.\n * We assume the target is always going to be fast enough (relative to\n * the JTAG clock) that the debugger won't need to poll the handshake\n * bit.  The JTAG clock is usually at least six times slower than the\n * functional clock, so the 50+ JTAG clocks needed to receive the word\n * allow hundreds of instruction cycles (per word) in the target.\n */\nint embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)\n{\n\tstruct scan_field fields[3];\n\tuint8_t field0_out[4];\n\tuint8_t field1_out[1];\n\tuint8_t field2_out[1];\n\tint retval;\n\n\tretval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = field0_out;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 5;\n\tfields[1].out_value = field1_out;\n\tfield1_out[0] = eice_regs[EICE_COMMS_DATA].addr;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = field2_out;\n\tfield2_out[0] = 1;\n\n\tfields[2].in_value = NULL;\n\n\twhile (size > 0) {\n\t\tbuf_set_u32(field0_out, 0, 32, *data);\n\t\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\n\t\tdata++;\n\t\tsize--;\n\t}\n\n\t/* call to jtag_execute_queue() intentionally omitted */\n\treturn ERROR_OK;\n}\n\n/**\n * Poll DCC control register until read or write handshake completes.\n */\nint embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout)\n{\n\tstruct scan_field fields[3];\n\tuint8_t field0_in[4];\n\tuint8_t field1_out[1];\n\tuint8_t field2_out[1];\n\tint retval;\n\tuint32_t hsact;\n\tstruct timeval now;\n\tstruct timeval timeout_end;\n\n\tif (hsbit == EICE_COMM_CTRL_WBIT)\n\t\thsact = 1;\n\telse if (hsbit == EICE_COMM_CTRL_RBIT)\n\t\thsact = 0;\n\telse {\n\t\tLOG_ERROR(\"Invalid arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tretval = arm_jtag_scann(jtag_info, 0x2, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = field0_in;\n\n\tfields[1].num_bits = 5;\n\tfields[1].out_value = field1_out;\n\tfield1_out[0] = eice_regs[EICE_COMMS_DATA].addr;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = field2_out;\n\tfield2_out[0] = 0;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\tgettimeofday(&timeout_end, NULL);\n\ttimeval_add_time(&timeout_end, 0, timeout * 1000);\n\tdo {\n\t\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (buf_get_u32(field0_in, hsbit, 1) == hsact)\n\t\t\treturn ERROR_OK;\n\n\t\tgettimeofday(&now, NULL);\n\t} while (timeval_compare(&now, &timeout_end) <= 0);\n\n\tLOG_ERROR(\"embeddedice handshake timeout\");\n\treturn ERROR_TARGET_TIMEOUT;\n}\n\n/**\n * This is an inner loop of the open loop DCC write of data to target\n */\nvoid embeddedice_write_dcc(struct jtag_tap *tap,\n\t\tint reg_addr, const uint8_t *buffer, int little, int count)\n{\n\tint i;\n\n\tfor (i = 0; i < count; i++) {\n\t\tembeddedice_write_reg_inner(tap, reg_addr,\n\t\t\t\tfast_target_buffer_get_u32(buffer, little));\n\t\tbuffer += 4;\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/embeddedice.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2006 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_EMBEDDEDICE_H\n#define OPENOCD_TARGET_EMBEDDEDICE_H\n\n#include \"arm7_9_common.h\"\n\nenum {\n\tEICE_DBG_CTRL = 0,\n\tEICE_DBG_STAT = 1,\n\tEICE_COMMS_CTRL = 2,\n\tEICE_COMMS_DATA = 3,\n\tEICE_W0_ADDR_VALUE = 4,\n\tEICE_W0_ADDR_MASK = 5,\n\tEICE_W0_DATA_VALUE  = 6,\n\tEICE_W0_DATA_MASK = 7,\n\tEICE_W0_CONTROL_VALUE = 8,\n\tEICE_W0_CONTROL_MASK = 9,\n\tEICE_W1_ADDR_VALUE = 10,\n\tEICE_W1_ADDR_MASK = 11,\n\tEICE_W1_DATA_VALUE = 12,\n\tEICE_W1_DATA_MASK = 13,\n\tEICE_W1_CONTROL_VALUE = 14,\n\tEICE_W1_CONTROL_MASK = 15,\n\tEICE_VEC_CATCH = 16\n};\n\nenum {\n\tEICE_DBG_CONTROL_ICEDIS = 5,\n\tEICE_DBG_CONTROL_MONEN = 4,\n\tEICE_DBG_CONTROL_INTDIS = 2,\n\tEICE_DBG_CONTROL_DBGRQ = 1,\n\tEICE_DBG_CONTROL_DBGACK = 0,\n};\n\nenum {\n\tEICE_DBG_STATUS_IJBIT = 5,\n\tEICE_DBG_STATUS_ITBIT = 4,\n\tEICE_DBG_STATUS_SYSCOMP = 3,\n\tEICE_DBG_STATUS_IFEN = 2,\n\tEICE_DBG_STATUS_DBGRQ = 1,\n\tEICE_DBG_STATUS_DBGACK = 0\n};\n\nenum {\n\tEICE_W_CTRL_ENABLE = 0x100,\n\tEICE_W_CTRL_RANGE = 0x80,\n\tEICE_W_CTRL_CHAIN = 0x40,\n\tEICE_W_CTRL_EXTERN = 0x20,\n\tEICE_W_CTRL_NTRANS = 0x10,\n\tEICE_W_CTRL_NOPC = 0x8,\n\tEICE_W_CTRL_MAS = 0x6,\n\tEICE_W_CTRL_ITBIT = 0x2,\n\tEICE_W_CTRL_NRW = 0x1\n};\n\nenum {\n\tEICE_COMM_CTRL_WBIT = 1,\n\tEICE_COMM_CTRL_RBIT = 0\n};\n\nstruct embeddedice_reg {\n\tint addr;\n\tstruct arm_jtag *jtag_info;\n};\n\nstruct reg_cache *embeddedice_build_reg_cache(struct target *target,\n\t\tstruct arm7_9_common *arm7_9);\nvoid embeddedice_free_reg_cache(struct reg_cache *reg_cache);\n\nint embeddedice_setup(struct target *target);\n\nint embeddedice_read_reg(struct reg *reg);\nint embeddedice_read_reg_w_check(struct reg *reg,\n\t\tuint8_t *check_value, uint8_t *check_mask);\n\nvoid embeddedice_write_reg(struct reg *reg, uint32_t value);\nvoid embeddedice_store_reg(struct reg *reg);\n\nvoid embeddedice_set_reg(struct reg *reg, uint32_t value);\n\nint embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size);\nint embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size);\n\nint embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout);\n\n/* If many embeddedice_write_reg() follow each other, then the >1 invocations can be\n * this faster version of embeddedice_write_reg\n */\nstatic inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value)\n{\n\tuint8_t out_reg_addr = (1 << 5) | reg_addr;\n\tuint8_t out_value[4];\n\tbuf_set_u32(out_value, 0, 32, value);\n\n\tstruct scan_field fields[2] = {\n\t\t\t{ .num_bits = 32, .out_value = out_value },\n\t\t\t{ .num_bits = 6, .out_value = &out_reg_addr },\n\t};\n\n\tjtag_add_dr_scan(tap, 2, fields, TAP_IDLE);\n}\n\nvoid embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer,\n\t\tint little, int count);\n\n#endif /* OPENOCD_TARGET_EMBEDDEDICE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <helper/log.h>\n#include <helper/time_support.h>\n#include <helper/types.h>\n#include <jtag/interface.h>\n#include <target/breakpoints.h>\n#include <target/register.h>\n#include <target/target.h>\n#include <target/target_type.h>\n\n#include \"esirisc.h\"\n\n#define RESET_TIMEOUT\t\t\t5000\t/* 5s */\n#define STEP_TIMEOUT\t\t\t1000\t/* 1s */\n\n/*\n * eSi-RISC targets support a configurable number of interrupts;\n * up to 32 interrupts are supported.\n */\nstatic const char * const esirisc_exception_strings[] = {\n\t[EID_RESET]\t\t\t\t\t= \"Reset\",\n\t[EID_HARDWARE_FAILURE]\t\t= \"HardwareFailure\",\n\t[EID_NMI]\t\t\t\t\t= \"NMI\",\n\t[EID_INST_BREAKPOINT]\t\t= \"InstBreakpoint\",\n\t[EID_DATA_BREAKPOINT]\t\t= \"DataBreakpoint\",\n\t[EID_UNSUPPORTED]\t\t\t= \"Unsupported\",\n\t[EID_PRIVILEGE_VIOLATION]\t= \"PrivilegeViolation\",\n\t[EID_INST_BUS_ERROR]\t\t= \"InstBusError\",\n\t[EID_DATA_BUS_ERROR]\t\t= \"DataBusError\",\n\t[EID_ALIGNMENT_ERROR]\t\t= \"AlignmentError\",\n\t[EID_ARITHMETIC_ERROR]\t\t= \"ArithmeticError\",\n\t[EID_SYSTEM_CALL]\t\t\t= \"SystemCall\",\n\t[EID_MEMORY_MANAGEMENT]\t\t= \"MemoryManagement\",\n\t[EID_UNRECOVERABLE]\t\t\t= \"Unrecoverable\",\n\t[EID_INTERRUPT_N+0]\t\t\t= \"Interrupt0\",\n\t[EID_INTERRUPT_N+1]\t\t\t= \"Interrupt1\",\n\t[EID_INTERRUPT_N+2]\t\t\t= \"Interrupt2\",\n\t[EID_INTERRUPT_N+3]\t\t\t= \"Interrupt3\",\n\t[EID_INTERRUPT_N+4]\t\t\t= \"Interrupt4\",\n\t[EID_INTERRUPT_N+5]\t\t\t= \"Interrupt5\",\n\t[EID_INTERRUPT_N+6]\t\t\t= \"Interrupt6\",\n\t[EID_INTERRUPT_N+7]\t\t\t= \"Interrupt7\",\n\t[EID_INTERRUPT_N+8]\t\t\t= \"Interrupt8\",\n\t[EID_INTERRUPT_N+9]\t\t\t= \"Interrupt9\",\n\t[EID_INTERRUPT_N+10]\t\t\t= \"Interrupt10\",\n\t[EID_INTERRUPT_N+11]\t\t\t= \"Interrupt11\",\n\t[EID_INTERRUPT_N+12]\t\t\t= \"Interrupt12\",\n\t[EID_INTERRUPT_N+13]\t\t\t= \"Interrupt13\",\n\t[EID_INTERRUPT_N+14]\t\t\t= \"Interrupt14\",\n\t[EID_INTERRUPT_N+15]\t\t\t= \"Interrupt15\",\n\t[EID_INTERRUPT_N+16]\t\t\t= \"Interrupt16\",\n\t[EID_INTERRUPT_N+17]\t\t\t= \"Interrupt17\",\n\t[EID_INTERRUPT_N+18]\t\t\t= \"Interrupt18\",\n\t[EID_INTERRUPT_N+19]\t\t\t= \"Interrupt19\",\n\t[EID_INTERRUPT_N+20]\t\t\t= \"Interrupt20\",\n\t[EID_INTERRUPT_N+21]\t\t\t= \"Interrupt21\",\n\t[EID_INTERRUPT_N+22]\t\t\t= \"Interrupt22\",\n\t[EID_INTERRUPT_N+23]\t\t\t= \"Interrupt23\",\n\t[EID_INTERRUPT_N+24]\t\t\t= \"Interrupt24\",\n\t[EID_INTERRUPT_N+25]\t\t\t= \"Interrupt25\",\n\t[EID_INTERRUPT_N+26]\t\t\t= \"Interrupt26\",\n\t[EID_INTERRUPT_N+27]\t\t\t= \"Interrupt27\",\n\t[EID_INTERRUPT_N+28]\t\t\t= \"Interrupt28\",\n\t[EID_INTERRUPT_N+29]\t\t\t= \"Interrupt29\",\n\t[EID_INTERRUPT_N+30]\t\t\t= \"Interrupt30\",\n\t[EID_INTERRUPT_N+31]\t\t\t= \"Interrupt31\",\n};\n\n/*\n * eSi-RISC targets support a configurable number of general purpose\n * registers; 8, 16, and 32 registers are supported.\n */\nstatic const struct {\n\tenum esirisc_reg_num number;\n\tconst char *name;\n\tenum reg_type type;\n\tconst char *group;\n} esirisc_regs[] = {\n\t{ ESIRISC_SP, \"sp\", REG_TYPE_DATA_PTR, \"general\" },\n\t{ ESIRISC_RA, \"ra\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R2, \"r2\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R3, \"r3\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R4, \"r4\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R5, \"r5\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R6, \"r6\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R7, \"r7\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R8, \"r8\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R9, \"r9\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R10, \"r10\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R11, \"r11\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R12, \"r12\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R13, \"r13\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R14, \"r14\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R15, \"r15\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R16, \"r16\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R17, \"r17\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R18, \"r18\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R19, \"r19\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R20, \"r20\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R21, \"r21\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R22, \"r22\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R23, \"r23\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R24, \"r24\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R25, \"r25\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R26, \"r26\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R27, \"r27\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R28, \"r28\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R29, \"r29\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R30, \"r30\", REG_TYPE_INT, \"general\" },\n\t{ ESIRISC_R31, \"r31\", REG_TYPE_INT, \"general\" },\n};\n\n/*\n * Control and Status Registers (CSRs) are largely defined as belonging\n * to the system register group. The exception to this rule are the PC\n * and CAS registers, which belong to the general group. While debug is\n * active, EPC, ECAS, and ETC must be used to read and write the PC,\n * CAS, and TC CSRs, respectively.\n */\nstatic const struct {\n\tenum esirisc_reg_num number;\n\tuint8_t bank;\n\tuint8_t csr;\n\tconst char *name;\n\tenum reg_type type;\n\tconst char *group;\n} esirisc_csrs[] = {\n\t{ ESIRISC_PC, CSR_THREAD, CSR_THREAD_EPC, \"PC\", REG_TYPE_CODE_PTR, \"general\" },\t/*  PC -> EPC  */\n\t{ ESIRISC_CAS, CSR_THREAD, CSR_THREAD_ECAS, \"CAS\", REG_TYPE_INT, \"general\" },\t/* CAS -> ECAS */\n\t{ ESIRISC_TC, CSR_THREAD, CSR_THREAD_ETC, \"TC\", REG_TYPE_INT, \"system\" },\t\t/*  TC -> ETC  */\n\t{ ESIRISC_ETA, CSR_THREAD, CSR_THREAD_ETA, \"ETA\", REG_TYPE_INT, \"system\" },\n\t{ ESIRISC_ETC, CSR_THREAD, CSR_THREAD_ETC, \"ETC\", REG_TYPE_INT, \"system\" },\n\t{ ESIRISC_EPC, CSR_THREAD, CSR_THREAD_EPC, \"EPC\", REG_TYPE_CODE_PTR, \"system\" },\n\t{ ESIRISC_ECAS, CSR_THREAD, CSR_THREAD_ECAS, \"ECAS\", REG_TYPE_INT, \"system\" },\n\t{ ESIRISC_EID, CSR_THREAD, CSR_THREAD_EID, \"EID\", REG_TYPE_INT, \"system\" },\n\t{ ESIRISC_ED, CSR_THREAD, CSR_THREAD_ED, \"ED\", REG_TYPE_INT, \"system\" },\n\t{ ESIRISC_IP, CSR_INTERRUPT, CSR_INTERRUPT_IP, \"IP\", REG_TYPE_INT, \"system\"},\n\t{ ESIRISC_IM, CSR_INTERRUPT, CSR_INTERRUPT_IM, \"IM\", REG_TYPE_INT, \"system\"},\n\t{ ESIRISC_IS, CSR_INTERRUPT, CSR_INTERRUPT_IS, \"IS\", REG_TYPE_INT, \"system\"},\n\t{ ESIRISC_IT, CSR_INTERRUPT, CSR_INTERRUPT_IT, \"IT\", REG_TYPE_INT, \"system\"},\n};\n\nstatic int esirisc_disable_interrupts(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t etc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC, &etc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tetc &= ~(1<<0);\t\t/* TC.I */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC, etc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n#if 0\nstatic int esirisc_enable_interrupts(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t etc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC, &etc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tetc |= (1<<0);\t\t/* TC.I */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC, etc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n#endif\n\nstatic int esirisc_save_interrupts(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_read_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC,\n\t\t\t&esirisc->etc_save);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_restore_interrupts(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_write_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETC,\n\t\t\tesirisc->etc_save);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Thread CSR: ETC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n#if 0\nstatic int esirisc_save_hwdc(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_HWDC,\n\t\t\t&esirisc->hwdc_save);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Thread CSR: HWDC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n#endif\n\nstatic int esirisc_restore_hwdc(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_HWDC,\n\t\t\tesirisc->hwdc_save);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: HWDC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_save_context(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (unsigned i = 0; i < esirisc->reg_cache->num_regs; ++i) {\n\t\tstruct reg *reg = esirisc->reg_cache->reg_list + i;\n\t\tstruct esirisc_reg *reg_info = reg->arch_info;\n\n\t\tif (reg->exist && !reg->valid)\n\t\t\treg_info->read(reg);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_restore_context(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (unsigned i = 0; i < esirisc->reg_cache->num_regs; ++i) {\n\t\tstruct reg *reg = esirisc->reg_cache->reg_list + i;\n\t\tstruct esirisc_reg *reg_info = reg->arch_info;\n\n\t\tif (reg->exist && reg->dirty)\n\t\t\treg_info->write(reg);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_flush_caches(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tint retval = esirisc_jtag_flush_caches(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to flush caches\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_wait_debug_active(struct esirisc_common *esirisc, int ms)\n{\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint64_t t;\n\n\tLOG_DEBUG(\"-\");\n\n\tt = timeval_ms();\n\tfor (;;) {\n\t\tint retval = esirisc_jtag_enable_debug(jtag_info);\n\t\tif (retval == ERROR_OK && esirisc_jtag_is_debug_active(jtag_info))\n\t\t\treturn retval;\n\n\t\tif ((timeval_ms() - t) > ms)\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\n\t\talive_sleep(100);\n\t}\n}\n\nstatic int esirisc_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tint num_bits = 8 * size;\n\tfor (uint32_t i = 0; i < count; ++i) {\n\t\tunion esirisc_memory value;\n\t\tvoid *value_p;\n\n\t\tswitch (size) {\n\t\t\tcase sizeof(value.word):\n\t\t\t\tvalue_p = &value.word;\n\t\t\t\tretval = esirisc_jtag_read_word(jtag_info, address, value_p);\n\t\t\t\tbreak;\n\n\t\t\tcase sizeof(value.hword):\n\t\t\t\tvalue_p = &value.hword;\n\t\t\t\tretval = esirisc_jtag_read_hword(jtag_info, address, value_p);\n\t\t\t\tbreak;\n\n\t\t\tcase sizeof(value.byte):\n\t\t\t\tvalue_p = &value.byte;\n\t\t\t\tretval = esirisc_jtag_read_byte(jtag_info, address, value_p);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"%s: unsupported size: %\" PRIu32, target_name(target), size);\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to read address: 0x%\" TARGET_PRIxADDR, target_name(target),\n\t\t\t\t\taddress);\n\t\t\treturn retval;\n\t\t}\n\n\t\tbuf_cpy(value_p, buffer, num_bits);\n\t\taddress += size;\n\t\tbuffer += size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tint num_bits = 8 * size;\n\tfor (uint32_t i = 0; i < count; ++i) {\n\t\tunion esirisc_memory value;\n\n\t\tswitch (size) {\n\t\t\tcase sizeof(value.word):\n\t\t\t\tvalue.word = buf_get_u32(buffer, 0, num_bits);\n\t\t\t\tretval = esirisc_jtag_write_word(jtag_info, address, value.word);\n\t\t\t\tbreak;\n\n\t\t\tcase sizeof(value.hword):\n\t\t\t\tvalue.hword = buf_get_u32(buffer, 0, num_bits);\n\t\t\t\tretval = esirisc_jtag_write_hword(jtag_info, address, value.hword);\n\t\t\t\tbreak;\n\n\t\t\tcase sizeof(value.byte):\n\t\t\t\tvalue.byte = buf_get_u32(buffer, 0, num_bits);\n\t\t\t\tretval = esirisc_jtag_write_byte(jtag_info, address, value.byte);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"%s: unsupported size: %\" PRIu32, target_name(target), size);\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to write address: 0x%\" TARGET_PRIxADDR, target_name(target),\n\t\t\t\t\taddress);\n\t\t\treturn retval;\n\t\t}\n\n\t\taddress += size;\n\t\tbuffer += size;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_checksum_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint32_t *checksum)\n{\n\treturn ERROR_FAIL;\t/* not supported */\n}\n\nstatic int esirisc_next_breakpoint(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct breakpoint **breakpoints_p = esirisc->breakpoints_p;\n\tstruct breakpoint **breakpoints_e = breakpoints_p + esirisc->num_breakpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (int bp_index = 0; breakpoints_p < breakpoints_e; ++breakpoints_p, ++bp_index)\n\t\tif (!*breakpoints_p)\n\t\t\treturn bp_index;\n\n\treturn -1;\n}\n\nstatic int esirisc_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint bp_index;\n\tuint32_t ibc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\t/*\n\t * The default linker scripts provided by the eSi-RISC toolchain do\n\t * not specify attributes on memory regions, which results in\n\t * incorrect application of software breakpoints by GDB. Targets\n\t * must be configured with `gdb_breakpoint_override hard` as\n\t * software breakpoints are not supported.\n\t */\n\tif (breakpoint->type != BKPT_HARD)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tbp_index = esirisc_next_breakpoint(target);\n\tif (bp_index < 0) {\n\t\tLOG_ERROR(\"%s: out of hardware breakpoints\", target_name(target));\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tbreakpoint_hw_set(breakpoint, bp_index);\n\tesirisc->breakpoints_p[bp_index] = breakpoint;\n\n\t/* specify instruction breakpoint address */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBA_N + bp_index,\n\t\t\tbreakpoint->address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: IBA\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* enable instruction breakpoint */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBC, &ibc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: IBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tibc |= (1 << bp_index);\t\t/* IBC.In */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBC, ibc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: IBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_add_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\twhile (breakpoint) {\n\t\tif (!breakpoint->is_set)\n\t\t\tesirisc_add_breakpoint(target, breakpoint);\n\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tunsigned int bp_index = breakpoint->number;\n\tuint32_t ibc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* disable instruction breakpoint */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBC, &ibc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: IBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tibc &= ~(1 << bp_index);\t/* IBC.In */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBC, ibc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: IBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->breakpoints_p[bp_index] = NULL;\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_remove_breakpoints(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* clear instruction breakpoints */\n\tint retval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_IBC, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: IBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tmemset(esirisc->breakpoints_p, 0, sizeof(esirisc->breakpoints_p));\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_next_watchpoint(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct watchpoint **watchpoints_p = esirisc->watchpoints_p;\n\tstruct watchpoint **watchpoints_e = watchpoints_p + esirisc->num_watchpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (int wp_index = 0; watchpoints_p < watchpoints_e; ++watchpoints_p, ++wp_index)\n\t\tif (!*watchpoints_p)\n\t\t\treturn wp_index;\n\n\treturn -1;\n}\n\nstatic int esirisc_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint wp_index;\n\tuint32_t dbs, dbc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\twp_index = esirisc_next_watchpoint(target);\n\tif (wp_index < 0) {\n\t\tLOG_ERROR(\"%s: out of hardware watchpoints\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\twatchpoint_set(watchpoint, wp_index);\n\tesirisc->watchpoints_p[wp_index] = watchpoint;\n\n\t/* specify data breakpoint address */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBA_N + wp_index,\n\t\t\twatchpoint->address);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DBA\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* specify data breakpoint size */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBS, &dbs);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: DBS\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tuint32_t sn;\n\tswitch (watchpoint->length) {\n\t\tcase sizeof(uint64_t):\n\t\t\tsn = 0x3;\n\t\t\tbreak;\n\t\tcase sizeof(uint32_t):\n\t\t\tsn = 0x2;\n\t\t\tbreak;\n\n\t\tcase sizeof(uint16_t):\n\t\t\tsn = 0x1;\n\t\t\tbreak;\n\n\t\tcase sizeof(uint8_t):\n\t\t\tsn = 0x0;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s: unsupported length: %\" PRIu32, target_name(target),\n\t\t\t\t\twatchpoint->length);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tdbs |= (sn << (2 * wp_index));\t\t/* DBS.Sn */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBS, dbs);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DBS\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* enable data breakpoint */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBC, &dbc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: DBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tuint32_t dn;\n\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tdn = 0x1;\n\t\t\tbreak;\n\n\t\tcase WPT_WRITE:\n\t\t\tdn = 0x2;\n\t\t\tbreak;\n\n\t\tcase WPT_ACCESS:\n\t\t\tdn = 0x3;\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s: unsupported rw: %\" PRId32, target_name(target),\n\t\t\t\t\twatchpoint->rw);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tdbc |= (dn << (2 * wp_index));\t\t/* DBC.Dn */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBC, dbc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_add_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\tesirisc_add_watchpoint(target, watchpoint);\n\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tunsigned int wp_index = watchpoint->number;\n\tuint32_t dbc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* disable data breakpoint */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBC, &dbc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: DBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tdbc &= ~(0x3 << (2 * wp_index));\t/* DBC.Dn */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBC, dbc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->watchpoints_p[wp_index] = NULL;\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_remove_watchpoints(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* clear data breakpoints */\n\tint retval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DBC, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DBC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tmemset(esirisc->watchpoints_p, 0, sizeof(esirisc->watchpoints_p));\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_halt(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state == TARGET_HALTED)\n\t\treturn ERROR_OK;\n\n\tint retval = esirisc_jtag_break(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to halt target\", target_name(target));\n\t\treturn retval;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_disable_step(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t dc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DC, &dc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: DC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tdc &= ~(1<<0);\t/* DC.S */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DC, dc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_enable_step(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t dc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DC, &dc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Debug CSR: DC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tdc |= (1<<0);\t/* DC.S */\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_DEBUG, CSR_DEBUG_DC, dc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Debug CSR: DC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_resume_or_step(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution, bool step)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct breakpoint *breakpoint = NULL;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tesirisc_add_breakpoints(target);\n\t\tesirisc_add_watchpoints(target);\n\t}\n\n\tif (current)\n\t\taddress = buf_get_u32(esirisc->epc->value, 0, esirisc->epc->size);\n\telse {\n\t\tbuf_set_u32(esirisc->epc->value, 0, esirisc->epc->size, address);\n\t\tesirisc->epc->dirty = true;\n\t\tesirisc->epc->valid = true;\n\t}\n\n\tesirisc_restore_context(target);\n\n\tif (esirisc_has_cache(esirisc))\n\t\tesirisc_flush_caches(target);\n\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target, address);\n\t\tif (breakpoint)\n\t\t\tesirisc_remove_breakpoint(target, breakpoint);\n\t}\n\n\tif (step) {\n\t\tesirisc_disable_interrupts(target);\n\t\tesirisc_enable_step(target);\n\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t} else {\n\t\tesirisc_disable_step(target);\n\t\tesirisc_restore_interrupts(target);\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t}\n\n\tesirisc_restore_hwdc(target);\n\n\tretval = esirisc_jtag_continue(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to resume target\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tregister_cache_invalidate(esirisc->reg_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\tLOG_DEBUG(\"-\");\n\n\treturn esirisc_resume_or_step(target, current, address,\n\t\t\thandle_breakpoints, debug_execution, false);\n}\n\nstatic int esirisc_step(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints)\n{\n\tLOG_DEBUG(\"-\");\n\n\treturn esirisc_resume_or_step(target, current, address,\n\t\t\thandle_breakpoints, 0, true);\n}\n\nstatic int esirisc_debug_step(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tesirisc_disable_interrupts(target);\n\tesirisc_enable_step(target);\n\n\tretval = esirisc_jtag_continue(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to resume target\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_wait_debug_active(esirisc, STEP_TIMEOUT);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: step timed out\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc_disable_step(target);\n\tesirisc_restore_interrupts(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_debug_reset(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_assert_reset(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to assert reset\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_jtag_deassert_reset(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to deassert reset\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_wait_debug_active(esirisc, RESET_TIMEOUT);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: reset timed out\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_debug_enable(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_enable_debug(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to enable debug mode\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/*\n\t * The debug clock is inactive until the first command is sent.\n\t * If the target is stopped, we must first issue a reset before\n\t * attempting further communication. This also handles unpowered\n\t * targets, which will respond with all ones and appear active.\n\t */\n\tif (esirisc_jtag_is_stopped(jtag_info)) {\n\t\tLOG_INFO(\"%s: debug clock inactive; attempting debug reset\", target_name(target));\n\t\tretval = esirisc_debug_reset(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (esirisc_jtag_is_stopped(jtag_info)) {\n\t\t\tLOG_ERROR(\"%s: target unresponsive; giving up\", target_name(target));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_debug_entry(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct breakpoint *breakpoint;\n\n\tLOG_DEBUG(\"-\");\n\n\tesirisc_save_context(target);\n\n\tif (esirisc_has_cache(esirisc))\n\t\tesirisc_flush_caches(target);\n\n\tif (target->debug_reason != DBG_REASON_SINGLESTEP) {\n\t\tesirisc_save_interrupts(target);\n\n\t\tuint32_t eid = buf_get_u32(esirisc->eid->value, 0, esirisc->eid->size);\n\t\tswitch (eid) {\n\t\t\t/*\n\t\t\t * InstBreakpoint exceptions are also raised when a core is\n\t\t\t * halted for debugging. The following is required to\n\t\t\t * determine if a breakpoint was encountered.\n\t\t\t */\n\t\t\tcase EID_INST_BREAKPOINT:\n\t\t\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\t\t\tbuf_get_u32(esirisc->epc->value, 0, esirisc->epc->size));\n\t\t\t\ttarget->debug_reason = (breakpoint) ?\n\t\t\t\t\t\tDBG_REASON_BREAKPOINT : DBG_REASON_DBGRQ;\n\t\t\t\tbreak;\n\n\t\t\t/*\n\t\t\t * eSi-RISC treats watchpoints similarly to breakpoints,\n\t\t\t * however GDB will not request to step over the current\n\t\t\t * instruction when a watchpoint fires. The following is\n\t\t\t * required to resume the target.\n\t\t\t */\n\t\t\tcase EID_DATA_BREAKPOINT:\n\t\t\t\tesirisc_remove_watchpoints(target);\n\t\t\t\tesirisc_debug_step(target);\n\t\t\t\tesirisc_add_watchpoints(target);\n\t\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_poll(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tretval = esirisc_jtag_enable_debug(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to poll target\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tif (esirisc_jtag_is_stopped(jtag_info)) {\n\t\tLOG_ERROR(\"%s: target has stopped; reset required\", target_name(target));\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\tif (esirisc_jtag_is_debug_active(jtag_info)) {\n\t\tif (target->state == TARGET_RUNNING || target->state == TARGET_RESET) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = esirisc_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t}\n\n\t} else if (target->state == TARGET_HALTED || target->state == TARGET_RESET) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_assert_reset(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (jtag_get_reset_config() & RESET_HAS_SRST) {\n\t\tjtag_add_reset(1, 1);\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) == 0)\n\t\t\tjtag_add_reset(0, 1);\n\t} else {\n\t\tesirisc_remove_breakpoints(target);\n\t\tesirisc_remove_watchpoints(target);\n\n\t\tretval = esirisc_jtag_assert_reset(jtag_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to assert reset\", target_name(target));\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\ttarget->state = TARGET_RESET;\n\n\tregister_cache_invalidate(esirisc->reg_cache);\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_reset_entry(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t eta, epc;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* read exception table address */\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_THREAD, CSR_THREAD_ETA, &eta);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Thread CSR: ETA\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* read reset entry point */\n\tretval = esirisc_jtag_read_word(jtag_info, eta + ENTRY_RESET, &epc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read address: 0x%\" TARGET_PRIxADDR, target_name(target),\n\t\t\t\t(target_addr_t)epc);\n\t\treturn retval;\n\t}\n\n\t/* write reset entry point */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_THREAD, CSR_THREAD_EPC, epc);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Thread CSR: EPC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_deassert_reset(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (jtag_get_reset_config() & RESET_HAS_SRST) {\n\t\tjtag_add_reset(0, 0);\n\n\t\tretval = esirisc_debug_enable(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = esirisc_debug_reset(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t} else {\n\t\tretval = esirisc_jtag_deassert_reset(jtag_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to deassert reset\", target_name(target));\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = esirisc_wait_debug_active(esirisc, RESET_TIMEOUT);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: reset timed out\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_reset_entry(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tesirisc_add_breakpoints(target);\n\tesirisc_add_watchpoints(target);\n\n\tesirisc_restore_hwdc(target);\n\n\tif (!target->reset_halt) {\n\t\tretval = esirisc_jtag_continue(jtag_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to resume target\", target_name(target));\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_arch_state(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tuint32_t epc = buf_get_u32(esirisc->epc->value, 0, esirisc->epc->size);\n\tuint32_t ecas = buf_get_u32(esirisc->ecas->value, 0, esirisc->ecas->size);\n\tuint32_t eid = buf_get_u32(esirisc->eid->value, 0, esirisc->eid->size);\n\tuint32_t ed = buf_get_u32(esirisc->ed->value, 0, esirisc->ed->size);\n\n\tLOG_USER(\"target halted due to %s, exception: %s\\n\"\n\t\t\t\"EPC: 0x%\" PRIx32 \", ECAS: 0x%\" PRIx32 \", EID: 0x%\" PRIx32 \", ED: 0x%\" PRIx32,\n\t\t\tdebug_reason_name(target), esirisc_exception_strings[eid], epc, ecas, eid, ed);\n\n\treturn ERROR_OK;\n}\n\nstatic const char *esirisc_get_gdb_arch(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tLOG_DEBUG(\"-\");\n\n\t/*\n\t * Targets with the UNIFIED_ADDRESS_SPACE option disabled employ a\n\t * Harvard architecture. This option is not exposed in a CSR, which\n\t * requires additional configuration to properly interact with these\n\t * targets in GDB (also see: `esirisc cache_arch`).\n\t */\n\tif (!esirisc->gdb_arch && target_was_examined(target))\n\t\tesirisc->gdb_arch = alloc_printf(\"esirisc:%d_bit_%d_reg_%s\",\n\t\t\t\tesirisc->num_bits, esirisc->num_regs, esirisc_cache_arch_name(esirisc));\n\n\treturn esirisc->gdb_arch;\n}\n\nstatic int esirisc_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tLOG_DEBUG(\"-\");\n\n\t*reg_list_size = ESIRISC_NUM_REGS;\n\n\t*reg_list = calloc(*reg_list_size, sizeof(struct reg *));\n\tif (!*reg_list)\n\t\treturn ERROR_FAIL;\n\n\tif (reg_class == REG_CLASS_ALL)\n\t\tfor (int i = 0; i < *reg_list_size; ++i)\n\t\t\t(*reg_list)[i] = esirisc->reg_cache->reg_list + i;\n\telse {\n\t\tfor (int i = 0; i < esirisc->num_regs; ++i)\n\t\t\t(*reg_list)[i] = esirisc->reg_cache->reg_list + i;\n\n\t\t(*reg_list)[ESIRISC_PC] = esirisc->reg_cache->reg_list + ESIRISC_PC;\n\t\t(*reg_list)[ESIRISC_CAS] = esirisc->reg_cache->reg_list + ESIRISC_CAS;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_read_reg(struct reg *reg)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct target *target = esirisc->target;\n\tuint32_t data;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_read_reg(jtag_info, reg->number, &data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read register: %s\", target_name(target), reg->name);\n\t\treturn retval;\n\t}\n\n\tbuf_set_u32(reg->value, 0, reg->size, data);\n\treg->dirty = false;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_write_reg(struct reg *reg)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct target *target = esirisc->target;\n\tuint32_t data = buf_get_u32(reg->value, 0, reg->size);\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_write_reg(jtag_info, reg->number, data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write register: %s\", target_name(target), reg->name);\n\t\treturn retval;\n\t}\n\n\treg->dirty = false;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_read_csr(struct reg *reg)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct target *target = esirisc->target;\n\tuint32_t data;\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_read_csr(jtag_info, reg_info->bank, reg_info->csr, &data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read CSR: %s\", target_name(target), reg->name);\n\t\treturn retval;\n\t}\n\n\tbuf_set_u32(reg->value, 0, reg->size, data);\n\treg->dirty = false;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_write_csr(struct reg *reg)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct target *target = esirisc->target;\n\tuint32_t data = buf_get_u32(reg->value, 0, reg->size);\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = esirisc_jtag_write_csr(jtag_info, reg_info->bank, reg_info->csr, data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write CSR: %s\", target_name(target), reg->name);\n\t\treturn retval;\n\t}\n\n\treg->dirty = false;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_get_reg(struct reg *reg)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct target *target = esirisc->target;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\treturn reg_info->read(reg);\n}\n\nstatic int esirisc_set_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct esirisc_reg *reg_info = reg->arch_info;\n\tstruct esirisc_common *esirisc = reg_info->esirisc;\n\tstruct target *target = esirisc->target;\n\tuint32_t value = buf_get_u32(buf, 0, reg->size);\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u32(reg->value, 0, reg->size, value);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type esirisc_reg_type = {\n\t.get = esirisc_get_reg,\n\t.set = esirisc_set_reg,\n};\n\nstatic struct reg_cache *esirisc_build_reg_cache(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(ESIRISC_NUM_REGS, sizeof(struct reg));\n\n\tLOG_DEBUG(\"-\");\n\n\tcache->name = \"eSi-RISC registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = ESIRISC_NUM_REGS;\n\t(*cache_p) = cache;\n\n\tesirisc->reg_cache = cache;\n\tesirisc->epc = reg_list + ESIRISC_EPC;\n\tesirisc->ecas = reg_list + ESIRISC_ECAS;\n\tesirisc->eid = reg_list + ESIRISC_EID;\n\tesirisc->ed = reg_list + ESIRISC_ED;\n\n\tfor (int i = 0; i < esirisc->num_regs; ++i) {\n\t\tstruct reg *reg = reg_list + esirisc_regs[i].number;\n\t\tstruct esirisc_reg *reg_info = calloc(1, sizeof(struct esirisc_reg));\n\n\t\treg->name = esirisc_regs[i].name;\n\t\treg->number = esirisc_regs[i].number;\n\t\treg->value = calloc(1, DIV_ROUND_UP(esirisc->num_bits, 8));\n\t\treg->size = esirisc->num_bits;\n\t\treg->reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\treg->reg_data_type->type = esirisc_regs[i].type;\n\t\treg->group = esirisc_regs[i].group;\n\t\treg_info->esirisc = esirisc;\n\t\treg_info->read = esirisc_read_reg;\n\t\treg_info->write = esirisc_write_reg;\n\t\treg->arch_info = reg_info;\n\t\treg->type = &esirisc_reg_type;\n\t\treg->exist = true;\n\t}\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(esirisc_csrs); ++i) {\n\t\tstruct reg *reg = reg_list + esirisc_csrs[i].number;\n\t\tstruct esirisc_reg *reg_info = calloc(1, sizeof(struct esirisc_reg));\n\n\t\treg->name = esirisc_csrs[i].name;\n\t\treg->number = esirisc_csrs[i].number;\n\t\treg->value = calloc(1, DIV_ROUND_UP(esirisc->num_bits, 8));\n\t\treg->size = esirisc->num_bits;\n\t\treg->reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\treg->reg_data_type->type = esirisc_csrs[i].type;\n\t\treg->group = esirisc_csrs[i].group;\n\t\treg_info->esirisc = esirisc;\n\t\treg_info->bank = esirisc_csrs[i].bank;\n\t\treg_info->csr = esirisc_csrs[i].csr;\n\t\treg_info->read = esirisc_read_csr;\n\t\treg_info->write = esirisc_write_csr;\n\t\treg->arch_info = reg_info;\n\t\treg->type = &esirisc_reg_type;\n\t\treg->exist = true;\n\t}\n\n\treturn cache;\n}\n\nstatic int esirisc_identify(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t csr;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_ARCH0, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: ARCH0\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->num_bits = (csr >> 0) & 0x3f;\t\t\t/* ARCH0.B */\n\tesirisc->num_regs = (csr >> 10) & 0x3f;\t\t\t/* ARCH0.R */\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_MEM, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: MEM\", target_name(target));\n\t\treturn retval;\n\t}\n\n\ttarget->endianness = (csr & 1<<0) ?\t\t\t\t/* MEM.E */\n\t\t\tTARGET_BIG_ENDIAN : TARGET_LITTLE_ENDIAN;\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_IC, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: IC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->has_icache = !!(csr & 1<<0);\t\t\t/* IC.E */\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_DC, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: DC\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->has_dcache = !!(csr & 1<<0);\t\t\t/* DC.E */\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_DBG, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: DBG\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->num_breakpoints = (csr >> 7) & 0xf;\t/* DBG.BP */\n\tesirisc->num_watchpoints = (csr >> 12) & 0xf;\t/* DBG.WP */\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_CONFIG, CSR_CONFIG_TRACE, &csr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Configuration CSR: TRACE\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tesirisc->has_trace = !!(csr & 1<<0);\t\t\t/* TRACE.T */\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct jtag_tap *tap = target->tap;\n\tstruct esirisc_common *esirisc;\n\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (tap->ir_length != INSTR_LENGTH) {\n\t\tLOG_ERROR(\"%s: invalid IR length; expected %d\", target_name(target),\n\t\t\t\tINSTR_LENGTH);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tesirisc = calloc(1, sizeof(struct esirisc_common));\n\tif (!esirisc)\n\t\treturn ERROR_FAIL;\n\n\tesirisc->target = target;\n\tesirisc->jtag_info.tap = tap;\n\ttarget->arch_info = esirisc;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\t/* trap reset, error, and debug exceptions */\n\tesirisc->hwdc_save = HWDC_R | HWDC_E | HWDC_D;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_examine(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (!target_was_examined(target)) {\n\t\tretval = esirisc_debug_enable(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/*\n\t\t * In order to identify the target we must first halt the core.\n\t\t * We quietly resume once identification has completed for those\n\t\t * targets that were running when target_examine was called.\n\t\t */\n\t\tif (esirisc_jtag_is_debug_active(jtag_info)) {\n\t\t\tif (target->state == TARGET_UNKNOWN)\n\t\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t} else {\n\t\t\tretval = esirisc_jtag_break(jtag_info);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s: failed to halt target\", target_name(target));\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t}\n\n\t\tretval = esirisc_identify(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s: failed to identify target\", target_name(target));\n\t\t\treturn retval;\n\t\t}\n\n\t\tesirisc_build_reg_cache(target);\n\n\t\tesirisc_remove_breakpoints(target);\n\t\tesirisc_remove_watchpoints(target);\n\n\t\tesirisc_disable_step(target);\n\t\tesirisc_restore_hwdc(target);\n\n\t\tif (target->state == TARGET_HALTED)\n\t\t\tesirisc_save_interrupts(target);\n\t\telse {\n\t\t\tretval = esirisc_jtag_continue(jtag_info);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s: failed to resume target\", target_name(target));\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\ttarget_set_examined(target);\n\n\t\tLOG_INFO(\"%s: %d bit, %d registers, %s%s%s\", target_name(target),\n\t\t\t\tesirisc->num_bits, esirisc->num_regs,\n\t\t\t\ttarget_endianness(target),\n\t\t\t\tesirisc->has_icache ? \", icache\" : \"\",\n\t\t\t\tesirisc->has_dcache ? \", dcache\" : \"\");\n\n\t\tLOG_INFO(\"%s: hardware has %d breakpoints, %d watchpoints%s\", target_name(target),\n\t\t\t\tesirisc->num_breakpoints, esirisc->num_watchpoints,\n\t\t\t\tesirisc->has_trace ? \", trace\" : \"\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_cache_arch_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tif (CMD_ARGC > 0) {\n\t\tif (strcmp(*CMD_ARGV, \"harvard\") == 0)\n\t\t\tesirisc->cache_arch = ESIRISC_CACHE_HARVARD;\n\t\telse if (strcmp(*CMD_ARGV, \"von_neumann\") == 0)\n\t\t\tesirisc->cache_arch = ESIRISC_CACHE_VON_NEUMANN;\n\t\telse {\n\t\t\tLOG_ERROR(\"invalid cache_arch: %s\", *CMD_ARGV);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"esirisc cache_arch %s\", esirisc_cache_arch_name(esirisc));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_flush_caches_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tint retval;\n\n\tif (!esirisc_has_cache(esirisc)) {\n\t\tLOG_ERROR(\"target does not support caching\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_flush_caches(target);\n\n\tcommand_print(CMD, \"cache flush %s\",\n\t\t\t(retval == ERROR_OK) ? \"successful\" : \"failed\");\n\n\treturn retval;\n}\n\nstatic const struct {\n\tconst char *name;\n\tint mask;\n} esirisc_hwdc_masks[] = {\n\t{ \"reset\",\t\tHWDC_R },\n\t{ \"interrupt\",\tHWDC_I },\n\t{ \"syscall\",\tHWDC_S },\n\t{ \"error\",\t\tHWDC_E },\n\t{ \"debug\",\t\tHWDC_D },\n};\n\nstatic int esirisc_find_hwdc_mask(const char *name)\n{\n\tfor (size_t i = 0; i < ARRAY_SIZE(esirisc_hwdc_masks); ++i)\n\t\tif (strcmp(esirisc_hwdc_masks[i].name, name) == 0)\n\t\t\treturn esirisc_hwdc_masks[i].mask;\n\n\treturn -1;\n}\n\nCOMMAND_HANDLER(handle_esirisc_hwdc_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tif (CMD_ARGC > 0) {\n\t\tif (strcmp(CMD_ARGV[0], \"all\") == 0)\n\t\t\tesirisc->hwdc_save = HWDC_R | HWDC_I | HWDC_S | HWDC_E | HWDC_D;\n\t\telse {\n\t\t\tesirisc->hwdc_save = 0;\n\t\t\tif (strcmp(CMD_ARGV[0], \"none\") != 0) {\n\t\t\t\twhile (CMD_ARGC-- > 0) {\n\t\t\t\t\tint mask = esirisc_find_hwdc_mask(CMD_ARGV[CMD_ARGC]);\n\t\t\t\t\tif (mask < 0) {\n\t\t\t\t\t\tLOG_ERROR(\"invalid mask: %s\", CMD_ARGV[CMD_ARGC]);\n\t\t\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\t\t}\n\t\t\t\t\tesirisc->hwdc_save |= mask;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (size_t i = 0; i < ARRAY_SIZE(esirisc_hwdc_masks); ++i)\n\t\tcommand_print(CMD, \"%9s: %s\", esirisc_hwdc_masks[i].name,\n\t\t\t\t(esirisc->hwdc_save & esirisc_hwdc_masks[i].mask) ? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration esirisc_exec_command_handlers[] = {\n\t{\n\t\t.name = \"flush_caches\",\n\t\t.handler = handle_esirisc_flush_caches_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"flush instruction and data caches\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esirisc_any_command_handlers[] = {\n\t{\n\t\t.name = \"cache_arch\",\n\t\t.handler = handle_esirisc_cache_arch_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure cache architecture\",\n\t\t.usage = \"['harvard'|'von_neumann']\",\n\t},\n\t{\n\t\t.name = \"hwdc\",\n\t\t.handler = handle_esirisc_hwdc_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure hardware debug control\",\n\t\t.usage = \"['all'|'none'|mask ...]\",\n\t},\n\t{\n\t\t.chain = esirisc_exec_command_handlers\n\t},\n\t{\n\t\t.chain = esirisc_trace_command_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esirisc_command_handlers[] = {\n\t{\n\t\t.name = \"esirisc\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"eSi-RISC command group\",\n\t\t.usage = \"\",\n\t\t.chain = esirisc_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type esirisc_target = {\n\t.name = \"esirisc\",\n\n\t.poll = esirisc_poll,\n\t.arch_state = esirisc_arch_state,\n\n\t.halt = esirisc_halt,\n\t.resume = esirisc_resume,\n\t.step = esirisc_step,\n\n\t.assert_reset = esirisc_assert_reset,\n\t.deassert_reset = esirisc_deassert_reset,\n\n\t.get_gdb_arch = esirisc_get_gdb_arch,\n\t.get_gdb_reg_list = esirisc_get_gdb_reg_list,\n\n\t.read_memory = esirisc_read_memory,\n\t.write_memory = esirisc_write_memory,\n\t.checksum_memory = esirisc_checksum_memory,\n\n\t.add_breakpoint = esirisc_add_breakpoint,\n\t.remove_breakpoint = esirisc_remove_breakpoint,\n\t.add_watchpoint = esirisc_add_watchpoint,\n\t.remove_watchpoint = esirisc_remove_watchpoint,\n\n\t.commands = esirisc_command_handlers,\n\n\t.target_create = esirisc_target_create,\n\t.init_target = esirisc_init_target,\n\t.examine = esirisc_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESIRISC_H\n#define OPENOCD_TARGET_ESIRISC_H\n\n#include <helper/types.h>\n#include <target/breakpoints.h>\n#include <target/register.h>\n#include <target/target.h>\n\n#include \"esirisc_jtag.h\"\n#include \"esirisc_regs.h\"\n#include \"esirisc_trace.h\"\n\n#define MAX_BREAKPOINTS\t\t\t8\n#define MAX_WATCHPOINTS\t\t\t8\n\n/* Exception IDs */\n#define EID_RESET\t\t\t\t0x00\n#define EID_HARDWARE_FAILURE\t0x01\n#define EID_NMI\t\t\t\t\t0x02\n#define EID_INST_BREAKPOINT\t\t0x03\n#define EID_DATA_BREAKPOINT\t\t0x04\n#define EID_UNSUPPORTED\t\t\t0x05\n#define EID_PRIVILEGE_VIOLATION\t0x06\n#define EID_INST_BUS_ERROR\t\t0x07\n#define EID_DATA_BUS_ERROR\t\t0x08\n#define EID_ALIGNMENT_ERROR\t\t0x09\n#define EID_ARITHMETIC_ERROR\t0x0a\n#define EID_SYSTEM_CALL\t\t\t0x0b\n#define EID_MEMORY_MANAGEMENT\t0x0c\n#define EID_UNRECOVERABLE\t\t0x0d\n#define EID_INTERRUPT_N\t\t\t0x20\n\n/* Exception Entry Points */\n#define ENTRY_RESET\t\t\t\t0x00\n#define ENTRY_UNRECOVERABLE\t\t0x01\n#define ENTRY_HARDWARE_FAILURE\t0x02\n#define ENTRY_RUNTIME\t\t\t0x03\n#define ENTRY_MEMORY\t\t\t0x04\n#define ENTRY_SYSCALL\t\t\t0x05\n#define ENTRY_DEBUG\t\t\t\t0x06\n#define ENTRY_NMI\t\t\t\t0x07\n#define ENTRY_INTERRUPT_N\t\t0x08\n\n/* Hardware Debug Control */\n#define HWDC_R\t\t\t\t\t(1<<4)\t/* Reset & Hardware Failure */\n#define HWDC_I\t\t\t\t\t(1<<3)\t/* Interrupts */\n#define HWDC_S\t\t\t\t\t(1<<2)\t/* System Calls */\n#define HWDC_E\t\t\t\t\t(1<<1)\t/* Program Errors */\n#define HWDC_D\t\t\t\t\t(1<<0)\t/* Debug Exceptions */\n\nenum esirisc_cache {\n\tESIRISC_CACHE_VON_NEUMANN,\n\tESIRISC_CACHE_HARVARD,\n};\n\nstruct esirisc_common {\n\tstruct target *target;\n\tstruct esirisc_jtag jtag_info;\n\tenum esirisc_cache cache_arch;\n\tchar *gdb_arch;\n\n\tstruct reg_cache *reg_cache;\n\tstruct reg *epc;\n\tstruct reg *ecas;\n\tstruct reg *eid;\n\tstruct reg *ed;\n\tuint32_t etc_save;\n\tuint32_t hwdc_save;\n\n\tint num_bits;\n\tint num_regs;\n\tbool has_icache;\n\tbool has_dcache;\n\tbool has_trace;\n\n\tint num_breakpoints;\n\tstruct breakpoint *breakpoints_p[MAX_BREAKPOINTS];\n\n\tint num_watchpoints;\n\tstruct watchpoint *watchpoints_p[MAX_WATCHPOINTS];\n\n\tstruct esirisc_trace trace_info;\n};\n\nunion esirisc_memory {\n\tuint32_t word;\n\tuint16_t hword;\n\tuint8_t byte;\n};\n\nstruct esirisc_reg {\n\tstruct esirisc_common *esirisc;\n\n\tuint8_t bank;\n\tuint8_t csr;\n\n\tint (*read)(struct reg *reg);\n\tint (*write)(struct reg *reg);\n};\n\nstatic inline struct esirisc_common *target_to_esirisc(struct target *target)\n{\n\treturn (struct esirisc_common *)target->arch_info;\n}\n\nstatic inline char *esirisc_cache_arch_name(struct esirisc_common *esirisc)\n{\n\treturn esirisc->cache_arch == ESIRISC_CACHE_HARVARD ? \"harvard\" : \"von_neumann\";\n}\n\nstatic inline bool esirisc_has_cache(struct esirisc_common *esirisc)\n{\n\treturn esirisc->has_icache || esirisc->has_dcache;\n}\n\n#endif /* OPENOCD_TARGET_ESIRISC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc_jtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/binarybuffer.h>\n#include <helper/log.h>\n#include <helper/types.h>\n#include <jtag/jtag.h>\n#include <jtag/commands.h>\n#include <jtag/interface.h>\n\n#include \"esirisc_jtag.h\"\n\nstatic void esirisc_jtag_set_instr(struct esirisc_jtag *jtag_info, uint32_t new_instr)\n{\n\tstruct jtag_tap *tap = jtag_info->tap;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\t\tstruct scan_field field;\n\t\tuint8_t t[4] = { 0 };\n\n\t\tfield.num_bits = tap->ir_length;\n\t\tfield.out_value = t;\n\t\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\t}\n}\n\n/*\n * The data register is latched every 8 bits while in the Shift-DR state\n * (Update-DR is not supported). This necessitates prepending padding\n * bits to ensure data is aligned when multiple TAPs are present.\n */\nstatic int esirisc_jtag_get_padding(void)\n{\n\tint padding = 0;\n\tint bypass_devices = 0;\n\n\tfor (struct jtag_tap *tap = jtag_tap_next_enabled(NULL); tap;\n\t\t\ttap = jtag_tap_next_enabled(tap))\n\t\tif (tap->bypass)\n\t\t\tbypass_devices++;\n\n\tint num_bits = bypass_devices % 8;\n\tif (num_bits > 0)\n\t\tpadding = 8 - num_bits;\n\n\treturn padding;\n}\n\nstatic int esirisc_jtag_count_bits(int num_fields, struct scan_field *fields)\n{\n\tint bit_count = 0;\n\n\tfor (int i = 0; i < num_fields; ++i)\n\t\tbit_count += fields[i].num_bits;\n\n\treturn bit_count;\n}\n\n/*\n * Data received from the target will be byte-stuffed if it contains\n * either the pad byte (0xAA) or stuffing marker (0x55). Buffers should\n * be sized twice the expected length to account for stuffing overhead.\n */\nstatic void esirisc_jtag_unstuff(uint8_t *data, size_t len)\n{\n\tuint8_t *r, *w;\n\tuint8_t *end;\n\n\tr = w = data;\n\tend = data + len;\n\twhile (r < end) {\n\t\tif (*r == STUFF_MARKER) {\n\t\t\tr++; /* skip stuffing marker */\n\t\t\tassert(r < end);\n\t\t\t*w++ = *r++ ^ STUFF_MARKER;\n\t\t} else\n\t\t\t*w++ = *r++;\n\t}\n}\n\n/*\n * The eSi-Debug protocol defines a byte-oriented command/response\n * channel that operates over serial or JTAG. While not strictly\n * required, separate DR scans are used for sending and receiving data.\n * This allows the TAP to recover gracefully if the byte stream is\n * corrupted at the expense of sending additional padding bits.\n */\n\nstatic int esirisc_jtag_send(struct esirisc_jtag *jtag_info, uint8_t command,\n\t\tint num_out_fields, struct scan_field *out_fields)\n{\n\tint num_fields = 2 + num_out_fields;\n\tstruct scan_field *fields = cmd_queue_alloc(num_fields * sizeof(struct scan_field));\n\n\tesirisc_jtag_set_instr(jtag_info, INSTR_DEBUG);\n\n\tfields[0].num_bits = esirisc_jtag_get_padding();\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 8;\n\tfields[1].out_value = &command;\n\tfields[1].in_value = NULL;\n\n\t/* append command data */\n\tfor (int i = 0; i < num_out_fields; ++i)\n\t\tjtag_scan_field_clone(&fields[2+i], &out_fields[i]);\n\n\tjtag_add_dr_scan(jtag_info->tap, num_fields, fields, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int esirisc_jtag_recv(struct esirisc_jtag *jtag_info,\n\t\tint num_in_fields, struct scan_field *in_fields)\n{\n\tint num_in_bits = esirisc_jtag_count_bits(num_in_fields, in_fields);\n\tint num_in_bytes = DIV_ROUND_UP(num_in_bits, 8);\n\n\tstruct scan_field fields[3];\n\t/* prevent zero-size variable length array */\n\tint r_size = num_in_bytes ? num_in_bytes * 2 : 1;\n\tuint8_t r[r_size];\n\n\tesirisc_jtag_set_instr(jtag_info, INSTR_DEBUG);\n\n\tfields[0].num_bits = esirisc_jtag_get_padding() + 1;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 8;\n\tfields[1].out_value = NULL;\n\tfields[1].in_value = &jtag_info->status;\n\n\tfields[2].num_bits = num_in_bits * 2;\n\tfields[2].out_value = NULL;\n\tfields[2].in_value = r;\n\n\tjtag_add_dr_scan(jtag_info->tap, ARRAY_SIZE(fields), fields, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* unstuff response data and write back to caller */\n\tif (num_in_fields > 0) {\n\t\tesirisc_jtag_unstuff(r, ARRAY_SIZE(r));\n\n\t\tint bit_count = 0;\n\t\tfor (int i = 0; i < num_in_fields; ++i) {\n\t\t\tbuf_set_buf(r, bit_count, in_fields[i].in_value, 0, in_fields[i].num_bits);\n\t\t\tbit_count += in_fields[i].num_bits;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_jtag_check_status(struct esirisc_jtag *jtag_info)\n{\n\tuint8_t eid = esirisc_jtag_get_eid(jtag_info);\n\tif (eid != EID_NONE) {\n\t\tLOG_ERROR(\"esirisc_jtag: bad status: 0x%02\" PRIx8 \" (DA: %\" PRId32 \", \"\n\t\t\t\t\"S: %\" PRId32 \", EID: 0x%02\" PRIx8 \")\",\n\t\t\t\tjtag_info->status, esirisc_jtag_is_debug_active(jtag_info),\n\t\t\t\tesirisc_jtag_is_stopped(jtag_info), eid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_jtag_send_and_recv(struct esirisc_jtag *jtag_info, uint8_t command,\n\t\tint num_out_fields, struct scan_field *out_fields,\n\t\tint num_in_fields, struct scan_field *in_fields)\n{\n\tint retval;\n\n\tjtag_info->status = 0;\t/* clear status */\n\n\tretval = esirisc_jtag_send(jtag_info, command, num_out_fields, out_fields);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"esirisc_jtag: send failed (command: 0x%02\" PRIx8 \")\", command);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_jtag_recv(jtag_info, num_in_fields, in_fields);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"esirisc_jtag: recv failed (command: 0x%02\" PRIx8 \")\", command);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn esirisc_jtag_check_status(jtag_info);\n}\n\n/*\n * Status is automatically updated after each command completes;\n * these functions make each field available to the caller.\n */\n\nbool esirisc_jtag_is_debug_active(struct esirisc_jtag *jtag_info)\n{\n\treturn !!(jtag_info->status & 1<<7);\t/* DA */\n}\n\nbool esirisc_jtag_is_stopped(struct esirisc_jtag *jtag_info)\n{\n\treturn !!(jtag_info->status & 1<<6);\t/* S */\n}\n\nuint8_t esirisc_jtag_get_eid(struct esirisc_jtag *jtag_info)\n{\n\treturn jtag_info->status & 0x3f;\t\t/* EID */\n}\n\n/*\n * Most commands manipulate target data (eg. memory and registers); each\n * command returns a status byte that indicates success. Commands must\n * transmit multibyte values in big-endian order, however response\n * values are in little-endian order. Target endianness does not have an\n * effect on this ordering.\n */\n\nint esirisc_jtag_read_byte(struct esirisc_jtag *jtag_info, uint32_t address, uint8_t *data)\n{\n\tstruct scan_field out_fields[1];\n\tuint8_t a[4];\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tstruct scan_field in_fields[1];\n\tuint8_t d[1];\n\n\tin_fields[0].num_bits = 8;\n\tin_fields[0].out_value = NULL;\n\tin_fields[0].in_value = d;\n\n\tint retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_BYTE,\n\t\t\tARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = *d;\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx8, address, *data);\n\n\treturn ERROR_OK;\n}\n\nint esirisc_jtag_read_hword(struct esirisc_jtag *jtag_info, uint32_t address, uint16_t *data)\n{\n\tstruct scan_field out_fields[1];\n\tuint8_t a[4];\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tstruct scan_field in_fields[1];\n\tuint8_t d[2];\n\n\tin_fields[0].num_bits = 16;\n\tin_fields[0].out_value = NULL;\n\tin_fields[0].in_value = d;\n\n\tint retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_HWORD,\n\t\t\tARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = le_to_h_u16(d);\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx16, address, *data);\n\n\treturn ERROR_OK;\n}\n\nint esirisc_jtag_read_word(struct esirisc_jtag *jtag_info, uint32_t address, uint32_t *data)\n{\n\tstruct scan_field out_fields[1];\n\tuint8_t a[4];\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tstruct scan_field in_fields[1];\n\tuint8_t d[4];\n\n\tin_fields[0].num_bits = 32;\n\tin_fields[0].out_value = NULL;\n\tin_fields[0].in_value = d;\n\n\tint retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_WORD,\n\t\t\tARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = le_to_h_u32(d);\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx32, address, *data);\n\n\treturn ERROR_OK;\n}\n\nint esirisc_jtag_write_byte(struct esirisc_jtag *jtag_info, uint32_t address, uint8_t data)\n{\n\tstruct scan_field out_fields[2];\n\tuint8_t a[4];\n\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx8, address, data);\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tout_fields[1].num_bits = 8;\n\tout_fields[1].out_value = &data;\n\tout_fields[1].in_value = NULL;\n\n\treturn esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_BYTE,\n\t\t\tARRAY_SIZE(out_fields), out_fields, 0, NULL);\n}\n\nint esirisc_jtag_write_hword(struct esirisc_jtag *jtag_info, uint32_t address, uint16_t data)\n{\n\tstruct scan_field out_fields[2];\n\tuint8_t a[4], d[2];\n\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx16, address, data);\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tout_fields[1].num_bits = 16;\n\tout_fields[1].out_value = d;\n\th_u16_to_be(d, data);\n\tout_fields[1].in_value = NULL;\n\n\treturn esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_HWORD,\n\t\t\tARRAY_SIZE(out_fields), out_fields, 0, NULL);\n}\n\nint esirisc_jtag_write_word(struct esirisc_jtag *jtag_info, uint32_t address, uint32_t data)\n{\n\tstruct scan_field out_fields[2];\n\tuint8_t a[4], d[4];\n\n\tLOG_DEBUG(\"address: 0x%\" PRIx32 \", data: 0x%\" PRIx32, address, data);\n\n\tout_fields[0].num_bits = 32;\n\tout_fields[0].out_value = a;\n\th_u32_to_be(a, address);\n\tout_fields[0].in_value = NULL;\n\n\tout_fields[1].num_bits = 32;\n\tout_fields[1].out_value = d;\n\th_u32_to_be(d, data);\n\tout_fields[1].in_value = NULL;\n\n\treturn esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_WORD,\n\t\t\tARRAY_SIZE(out_fields), out_fields, 0, NULL);\n}\n\nint esirisc_jtag_read_reg(struct esirisc_jtag *jtag_info, uint8_t reg, uint32_t *data)\n{\n\tstruct scan_field out_fields[1];\n\n\tout_fields[0].num_bits = 8;\n\tout_fields[0].out_value = &reg;\n\tout_fields[0].in_value = NULL;\n\n\tstruct scan_field in_fields[1];\n\tuint8_t d[4];\n\n\tin_fields[0].num_bits = 32;\n\tin_fields[0].out_value = NULL;\n\tin_fields[0].in_value = d;\n\n\tint retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_REG,\n\t\t\tARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = le_to_h_u32(d);\n\tLOG_DEBUG(\"register: 0x%\" PRIx8 \", data: 0x%\" PRIx32, reg, *data);\n\n\treturn ERROR_OK;\n}\n\nint esirisc_jtag_write_reg(struct esirisc_jtag *jtag_info, uint8_t reg, uint32_t data)\n{\n\tstruct scan_field out_fields[2];\n\tuint8_t d[4];\n\n\tLOG_DEBUG(\"register: 0x%\" PRIx8 \", data: 0x%\" PRIx32, reg, data);\n\n\tout_fields[0].num_bits = 8;\n\tout_fields[0].out_value = &reg;\n\tout_fields[0].in_value = NULL;\n\n\tout_fields[1].num_bits = 32;\n\tout_fields[1].out_value = d;\n\th_u32_to_be(d, data);\n\tout_fields[1].in_value = NULL;\n\n\treturn esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_REG,\n\t\t\tARRAY_SIZE(out_fields), out_fields, 0, NULL);\n}\n\nint esirisc_jtag_read_csr(struct esirisc_jtag *jtag_info, uint8_t bank, uint8_t csr, uint32_t *data)\n{\n\tstruct scan_field out_fields[1];\n\tuint8_t c[2];\n\n\tout_fields[0].num_bits = 16;\n\tout_fields[0].out_value = c;\n\th_u16_to_be(c, (csr << 5) | bank);\n\tout_fields[0].in_value = NULL;\n\n\tstruct scan_field in_fields[1];\n\tuint8_t d[4];\n\n\tin_fields[0].num_bits = 32;\n\tin_fields[0].out_value = NULL;\n\tin_fields[0].in_value = d;\n\n\tint retval = esirisc_jtag_send_and_recv(jtag_info, DEBUG_READ_CSR,\n\t\t\tARRAY_SIZE(out_fields), out_fields, ARRAY_SIZE(in_fields), in_fields);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*data = le_to_h_u32(d);\n\tLOG_DEBUG(\"bank: 0x%\" PRIx8 \", csr: 0x%\" PRIx8 \", data: 0x%\" PRIx32, bank, csr, *data);\n\n\treturn ERROR_OK;\n}\n\nint esirisc_jtag_write_csr(struct esirisc_jtag *jtag_info, uint8_t bank, uint8_t csr, uint32_t data)\n{\n\tstruct scan_field out_fields[2];\n\tuint8_t c[2], d[4];\n\n\tLOG_DEBUG(\"bank: 0x%\" PRIx8 \", csr: 0x%\" PRIx8 \", data: 0x%\" PRIx32, bank, csr, data);\n\n\tout_fields[0].num_bits = 16;\n\tout_fields[0].out_value = c;\n\th_u16_to_be(c, (csr << 5) | bank);\n\tout_fields[0].in_value = NULL;\n\n\tout_fields[1].num_bits = 32;\n\tout_fields[1].out_value = d;\n\th_u32_to_be(d, data);\n\tout_fields[1].in_value = NULL;\n\n\treturn esirisc_jtag_send_and_recv(jtag_info, DEBUG_WRITE_CSR,\n\t\t\tARRAY_SIZE(out_fields), out_fields, 0, NULL);\n}\n\n/*\n * Control commands affect CPU operation; these commands send no data\n * and return a status byte.\n */\n\nstatic inline int esirisc_jtag_send_ctrl(struct esirisc_jtag *jtag_info, uint8_t command)\n{\n\treturn esirisc_jtag_send_and_recv(jtag_info, command, 0, NULL, 0, NULL);\n}\n\nint esirisc_jtag_enable_debug(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_ENABLE_DEBUG);\n}\n\nint esirisc_jtag_disable_debug(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_DISABLE_DEBUG);\n}\n\nint esirisc_jtag_assert_reset(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_ASSERT_RESET);\n}\n\nint esirisc_jtag_deassert_reset(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_DEASSERT_RESET);\n}\n\nint esirisc_jtag_break(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_BREAK);\n}\n\nint esirisc_jtag_continue(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_CONTINUE);\n}\n\nint esirisc_jtag_flush_caches(struct esirisc_jtag *jtag_info)\n{\n\treturn esirisc_jtag_send_ctrl(jtag_info, DEBUG_FLUSH_CACHES);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc_jtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESIRISC_JTAG_H\n#define OPENOCD_TARGET_ESIRISC_JTAG_H\n\n#include <helper/types.h>\n#include <jtag/jtag.h>\n\n/* TAP Instructions */\n#define INSTR_IDCODE\t\t\t0x8\n#define INSTR_DEBUG\t\t\t\t0x9\n#define INSTR_BYPASS\t\t\t0xf\n#define INSTR_LENGTH\t\t\t4\n\n/* eSi-Debug Commands */\n#define DEBUG_NOP\t\t\t\t0x00\n#define DEBUG_READ_BYTE\t\t\t0x10\n#define DEBUG_READ_HWORD\t\t0x20\n#define DEBUG_READ_WORD\t\t\t0x30\n#define DEBUG_WRITE_BYTE\t\t0x60\n#define DEBUG_WRITE_HWORD\t\t0x70\n#define DEBUG_WRITE_WORD\t\t0x80\n#define DEBUG_READ_REG\t\t\t0xb0\n#define DEBUG_WRITE_REG\t\t\t0xc0\n#define DEBUG_READ_CSR\t\t\t0xd0\n#define DEBUG_WRITE_CSR\t\t\t0xe0\n#define DEBUG_ENABLE_DEBUG\t\t0xf0\n#define DEBUG_DISABLE_DEBUG\t\t0xf2\n#define DEBUG_ASSERT_RESET\t\t0xf4\n#define DEBUG_DEASSERT_RESET\t0xf6\n#define DEBUG_BREAK\t\t\t\t0xf8\n#define DEBUG_CONTINUE\t\t\t0xfa\n#define DEBUG_FLUSH_CACHES\t\t0xfc\n\n/* Exception IDs */\n#define EID_OVERFLOW\t\t\t0x3d\n#define EID_CANT_DEBUG\t\t\t0x3e\n#define EID_NONE\t\t\t\t0x3f\n\n/* Byte Stuffing */\n#define STUFF_MARKER\t\t\t0x55\n#define PAD_BYTE\t\t\t\t0xaa\n\nstruct esirisc_jtag {\n\tstruct jtag_tap *tap;\n\tuint8_t status;\n};\n\nbool esirisc_jtag_is_debug_active(struct esirisc_jtag *jtag_info);\nbool esirisc_jtag_is_stopped(struct esirisc_jtag *jtag_info);\nuint8_t esirisc_jtag_get_eid(struct esirisc_jtag *jtag_info);\n\nint esirisc_jtag_read_byte(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint8_t *data);\nint esirisc_jtag_read_hword(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint16_t *data);\nint esirisc_jtag_read_word(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint32_t *data);\n\nint esirisc_jtag_write_byte(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint8_t data);\nint esirisc_jtag_write_hword(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint16_t data);\nint esirisc_jtag_write_word(struct esirisc_jtag *jtag_info,\n\t\tuint32_t address, uint32_t data);\n\nint esirisc_jtag_read_reg(struct esirisc_jtag *jtag_info,\n\t\tuint8_t reg, uint32_t *data);\nint esirisc_jtag_write_reg(struct esirisc_jtag *jtag_info,\n\t\tuint8_t reg, uint32_t data);\n\nint esirisc_jtag_read_csr(struct esirisc_jtag *jtag_info,\n\t\tuint8_t bank, uint8_t csr, uint32_t *data);\nint esirisc_jtag_write_csr(struct esirisc_jtag *jtag_info,\n\t\tuint8_t bank, uint8_t csr, uint32_t data);\n\nint esirisc_jtag_enable_debug(struct esirisc_jtag *jtag_info);\nint esirisc_jtag_disable_debug(struct esirisc_jtag *jtag_info);\n\nint esirisc_jtag_assert_reset(struct esirisc_jtag *jtag_info);\nint esirisc_jtag_deassert_reset(struct esirisc_jtag *jtag_info);\n\nint esirisc_jtag_break(struct esirisc_jtag *jtag_info);\nint esirisc_jtag_continue(struct esirisc_jtag *jtag_info);\n\nint esirisc_jtag_flush_caches(struct esirisc_jtag *jtag_info);\n\n#endif /* OPENOCD_TARGET_ESIRISC_JTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc_regs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n *   James Zhao <hjz@squareup.com>                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESIRISC_REGS_H\n#define OPENOCD_TARGET_ESIRISC_REGS_H\n\nenum esirisc_reg_num {\n\tESIRISC_SP,\n\tESIRISC_RA,\n\tESIRISC_R2,\n\tESIRISC_R3,\n\tESIRISC_R4,\n\tESIRISC_R5,\n\tESIRISC_R6,\n\tESIRISC_R7,\n\tESIRISC_R8,\n\tESIRISC_R9,\n\tESIRISC_R10,\n\tESIRISC_R11,\n\tESIRISC_R12,\n\tESIRISC_R13,\n\tESIRISC_R14,\n\tESIRISC_R15,\n\tESIRISC_R16,\n\tESIRISC_R17,\n\tESIRISC_R18,\n\tESIRISC_R19,\n\tESIRISC_R20,\n\tESIRISC_R21,\n\tESIRISC_R22,\n\tESIRISC_R23,\n\tESIRISC_R24,\n\tESIRISC_R25,\n\tESIRISC_R26,\n\tESIRISC_R27,\n\tESIRISC_R28,\n\tESIRISC_R29,\n\tESIRISC_R30,\n\tESIRISC_R31,\n\n\tESIRISC_V0,\n\tESIRISC_V1,\n\tESIRISC_V2,\n\tESIRISC_V3,\n\tESIRISC_V4,\n\tESIRISC_V5,\n\tESIRISC_V6,\n\tESIRISC_V7,\n\tESIRISC_V8,\n\tESIRISC_V9,\n\tESIRISC_V10,\n\tESIRISC_V11,\n\tESIRISC_V12,\n\tESIRISC_V13,\n\tESIRISC_V14,\n\tESIRISC_V15,\n\tESIRISC_V16,\n\tESIRISC_V17,\n\tESIRISC_V18,\n\tESIRISC_V19,\n\tESIRISC_V20,\n\tESIRISC_V21,\n\tESIRISC_V22,\n\tESIRISC_V23,\n\tESIRISC_V24,\n\tESIRISC_V25,\n\tESIRISC_V26,\n\tESIRISC_V27,\n\tESIRISC_V28,\n\tESIRISC_V29,\n\tESIRISC_V30,\n\tESIRISC_V31,\n\n\tESIRISC_A0,\n\tESIRISC_A1,\n\tESIRISC_A2,\n\tESIRISC_A3,\n\tESIRISC_A4,\n\tESIRISC_A5,\n\tESIRISC_A6,\n\tESIRISC_A7,\n\n\tESIRISC_PC,\n\tESIRISC_CAS,\n\tESIRISC_TC,\n\tESIRISC_ETA,\n\tESIRISC_ETC,\n\tESIRISC_EPC,\n\tESIRISC_ECAS,\n\tESIRISC_EID,\n\tESIRISC_ED,\n\tESIRISC_IP,\n\tESIRISC_IM,\n\tESIRISC_IS,\n\tESIRISC_IT,\n\n\tESIRISC_NUM_REGS,\n};\n\n/* CSR Banks */\n#define CSR_THREAD\t\t\t\t\t0x00\n#define CSR_INTERRUPT\t\t\t\t0x01\n#define CSR_DEBUG\t\t\t\t\t0x04\n#define CSR_CONFIG\t\t\t\t\t0x05\n#define CSR_TRACE\t\t\t\t\t0x09\n\n/* Thread CSRs */\n#define CSR_THREAD_TC\t\t\t\t0x00\t/* Thread Control */\n#define CSR_THREAD_PC\t\t\t\t0x01\t/* Program Counter */\n#define CSR_THREAD_CAS\t\t\t\t0x02\t/* Comparison & Arithmetic Status */\n#define CSR_THREAD_AC\t\t\t\t0x03\t/* Arithmetic Control */\n#define CSR_THREAD_LF\t\t\t\t0x04\t/* Locked Flag */\n#define CSR_THREAD_LA\t\t\t\t0x05\t/* Locked Address */\n#define CSR_THREAD_ETA\t\t\t\t0x07\t/* Exception Table Address */\n#define CSR_THREAD_ETC\t\t\t\t0x08\t/* Exception TC */\n#define CSR_THREAD_EPC\t\t\t\t0x09\t/* Exception PC */\n#define CSR_THREAD_ECAS\t\t\t\t0x0a\t/* Exception CAS */\n#define CSR_THREAD_EID\t\t\t\t0x0b\t/* Exception ID */\n#define CSR_THREAD_ED\t\t\t\t0x0c\t/* Exception Data */\n\n/* Interrupt CSRs */\n#define CSR_INTERRUPT_IP\t\t\t0x00\t/* Interrupt Pending */\n#define CSR_INTERRUPT_IA\t\t\t0x01\t/* Interrupt Acknowledge */\n#define CSR_INTERRUPT_IM\t\t\t0x02\t/* Interrupt Mask */\n#define CSR_INTERRUPT_IS\t\t\t0x03\t/* Interrupt Sense */\n#define CSR_INTERRUPT_IT\t\t\t0x04\t/* Interrupt Trigger */\n\n/* Debug CSRs */\n#define CSR_DEBUG_DC\t\t\t\t0x00\t/* Debug Control */\n#define CSR_DEBUG_IBC\t\t\t\t0x01\t/* Instruction Breakpoint Control */\n#define CSR_DEBUG_DBC\t\t\t\t0x02\t/* Data Breakpoint Control */\n#define CSR_DEBUG_HWDC\t\t\t\t0x03\t/* Hardware Debug Control */\n#define CSR_DEBUG_DBS\t\t\t\t0x04\t/* Data Breakpoint Size */\n#define CSR_DEBUG_DBR\t\t\t\t0x05\t/* Data Breakpoint Range */\n#define CSR_DEBUG_IBA_N\t\t\t\t0x08\t/* Instruction Breakpoint Address [0..7] */\n#define CSR_DEBUG_DBA_N\t\t\t\t0x10\t/* Data Breakpoint Address [0..7] */\n\n/* Configuration CSRs */\n#define CSR_CONFIG_ARCH0\t\t\t0x00\t/* Architectural Configuration 0 */\n#define CSR_CONFIG_ARCH1\t\t\t0x01\t/* Architectural Configuration 1 */\n#define CSR_CONFIG_ARCH2\t\t\t0x02\t/* Architectural Configuration 2 */\n#define CSR_CONFIG_ARCH3\t\t\t0x03\t/* Architectural Configuration 3 */\n#define CSR_CONFIG_MEM\t\t\t\t0x04\t/* Memory Configuration */\n#define CSR_CONFIG_IC\t\t\t\t0x05\t/* Instruction Cache Configuration */\n#define CSR_CONFIG_DC\t\t\t\t0x06\t/* Data Cache Configuration */\n#define CSR_CONFIG_INT\t\t\t\t0x07\t/* Interrupt Configuration */\n#define\tCSR_CONFIG_ISA_N\t\t\t0x08\t/* Instruction Set Configuration [0..6] */\n#define CSR_CONFIG_DBG\t\t\t\t0x0f\t/* Debug Configuration */\n#define CSR_CONFIG_MID\t\t\t\t0x10\t/* Manufacturer ID */\n#define CSR_CONFIG_REV\t\t\t\t0x11\t/* Revision Number */\n#define CSR_CONFIG_MPID\t\t\t\t0x12\t/* Multiprocessor ID */\n#define CSR_CONFIG_FREQ_N\t\t\t0x13\t/* Frequency [0..2] */\n#define CSR_CONFIG_TRACE\t\t\t0x16\t/* Trace Configuration */\n\n/* Trace CSRs */\n#define CSR_TRACE_CONTROL\t\t\t0x00\n#define CSR_TRACE_STATUS\t\t\t0x01\n#define CSR_TRACE_BUFFER_START\t\t0x02\n#define CSR_TRACE_BUFFER_END\t\t0x03\n#define CSR_TRACE_BUFFER_CUR\t\t0x04\n#define CSR_TRACE_TRIGGER\t\t\t0x05\n#define CSR_TRACE_START_DATA\t\t0x06\n#define CSR_TRACE_START_MASK\t\t0x07\n#define CSR_TRACE_STOP_DATA\t\t\t0x08\n#define CSR_TRACE_STOP_MASK\t\t\t0x09\n#define CSR_TRACE_DELAY\t\t\t\t0x0a\n\n#endif /* OPENOCD_TARGET_ESIRISC_REGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc_trace.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <helper/fileio.h>\n#include <helper/log.h>\n#include <helper/types.h>\n#include <target/target.h>\n\n#include \"esirisc.h\"\n\n#define BIT_MASK(x)\t\t\t((1 << (x)) - 1)\n\n/* Control Fields */\n#define CONTROL_ST\t\t\t(1<<0)\t\t\t\t\t/* Start */\n#define CONTROL_SP\t\t\t(1<<1)\t\t\t\t\t/* Stop */\n#define CONTROL_W\t\t\t(1<<2)\t\t\t\t\t/* Wrap */\n#define CONTROL_FC\t\t\t(1<<3)\t\t\t\t\t/* Flow Control */\n#define CONTROL_FMT(x)\t\t(((x) <<  4) & 0x30)\t/* Format */\n#define CONTROL_PCB(x)\t\t(((x) << 10) & 0x7c00)\t/* PC Bits */\n\n/* Status Fields */\n#define STATUS_T\t\t\t(1<<0)\t/* Trace Started */\n#define STATUS_TD\t\t\t(1<<1)\t/* Trace Disabled */\n#define\tSTATUS_W\t\t\t(1<<2)\t/* Wrapped */\n#define STATUS_O\t\t\t(1<<3)\t/* Overflow */\n\n/* Trigger Fields */\n#define TRIGGER_TST(x)\t\t(((x) << 0) & 0xf)\t\t/* Trigger Start */\n#define TRIGGER_DST\t\t\t(1<<7)\t\t\t\t\t/* Delay Start */\n#define TRIGGER_TSP(x)\t\t(((x) << 8) & 0xf00)\t/* Trigger Stop */\n#define TRIGGER_DSP\t\t\t(1<<15)\t\t\t\t\t/* Delay Start */\n\nstatic const char * const esirisc_trace_delay_strings[] = {\n\t\"none\", \"start\", \"stop\", \"both\",\n};\n\nstatic const char * const esirisc_trace_format_strings[] = {\n\t\"full\", \"branch\", \"icache\",\n};\n\nstatic const char * const esirisc_trace_id_strings[] = {\n\t\"sequential instruction\",\n\t\"pipeline stall\",\n\t\"direct branch\",\n\t\"extended ID\",\n};\n\nstatic const char * const esirisc_trace_ext_id_strings[] = {\n\t\"\",\t/* unused */\n\t\"exception\",\n\t\"eret\",\n\t\"stop instruction\",\n\t\"wait instruction\",\n\t\"multicycle instruction\",\n\t\"count\",\n\t\"initial\",\n\t\"indirect branch\",\n\t\"end of trace\",\n\t\"final\",\n};\n\nstatic const char * const esirisc_trace_trigger_strings[] = {\n\t\"none\", \"pc\", \"load\", \"store\", \"exception\", \"eret\", \"wait\", \"stop\",\n\t\"high\", \"low\",\t/* start only */\n};\n\nstatic int esirisc_trace_clear_status(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_STATUS, ~0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Status\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_get_status(struct target *target, uint32_t *status)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tint retval = esirisc_jtag_read_csr(jtag_info, CSR_TRACE, CSR_TRACE_STATUS, status);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Trace CSR: Status\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_start(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t control;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_TRACE, CSR_TRACE_CONTROL, &control);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Trace CSR: Control\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tcontrol |= CONTROL_ST;\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_CONTROL, control);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Control\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_stop(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tuint32_t control;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_TRACE, CSR_TRACE_CONTROL, &control);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Trace CSR: Control\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tcontrol |= CONTROL_SP;\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_CONTROL, control);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Control\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_init(struct target *target)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tuint32_t control, trigger;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\t/* stop if running and clear status */\n\tretval = esirisc_trace_stop(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = esirisc_trace_clear_status(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* initialize Control CSR */\n\tcontrol = CONTROL_FMT(trace_info->format)\n\t\t\t| CONTROL_PCB(trace_info->pc_bits);\n\n\tif (trace_info->buffer_wrap)\n\t\tcontrol |= CONTROL_W;\n\n\tif (trace_info->flow_control)\n\t\tcontrol |= CONTROL_FC;\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_CONTROL, control);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Control\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* initialize buffer CSRs */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_BUFFER_START,\n\t\t\ttrace_info->buffer_start);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: BufferStart\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_BUFFER_END,\n\t\t\ttrace_info->buffer_end);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: BufferEnd\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/*\n\t * The BufferCurrent CSR must be initialized to the same value as\n\t * BufferStart before tracing can be enabled:\n\t */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_BUFFER_CUR,\n\t\t\ttrace_info->buffer_start);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: BufferCurrent\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* initialize Trigger CSR */\n\ttrigger = TRIGGER_TST(trace_info->start_trigger)\n\t\t\t| TRIGGER_TSP(trace_info->stop_trigger);\n\n\tif (trace_info->delay == ESIRISC_TRACE_DELAY_START\n\t\t|| trace_info->delay == ESIRISC_TRACE_DELAY_BOTH) {\n\t\ttrigger |= TRIGGER_DST;\n\t}\n\n\tif (trace_info->delay == ESIRISC_TRACE_DELAY_STOP\n\t\t|| trace_info->delay == ESIRISC_TRACE_DELAY_BOTH) {\n\t\ttrigger |= TRIGGER_DSP;\n\t}\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_TRIGGER, trigger);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Trigger\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* initialize StartData/StartMask CSRs */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_START_DATA,\n\t\t\ttrace_info->start_data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: StartData\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_START_MASK,\n\t\t\ttrace_info->start_mask);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: StartMask\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* initialize StopData/StopMask CSRs */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_STOP_DATA,\n\t\t\ttrace_info->stop_data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: StopData\", target_name(target));\n\t\treturn retval;\n\t}\n\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_STOP_MASK,\n\t\t\ttrace_info->stop_mask);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: StopMask\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* initialize Delay CSR */\n\tretval = esirisc_jtag_write_csr(jtag_info, CSR_TRACE, CSR_TRACE_DELAY,\n\t\t\ttrace_info->delay_cycles);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to write Trace CSR: Delay\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_buf_get_u32(uint8_t *buffer, uint32_t size,\n\t\tunsigned *pos, unsigned count, uint32_t *value)\n{\n\tconst unsigned num_bits = size * 8;\n\n\tif (*pos+count > num_bits)\n\t\treturn ERROR_FAIL;\n\n\t*value = buf_get_u32(buffer, *pos, count);\n\t*pos += count;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_buf_get_pc(struct target *target, uint8_t *buffer, uint32_t size,\n\t\tunsigned *pos, uint32_t *value)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tint retval;\n\n\tretval = esirisc_trace_buf_get_u32(buffer, size, pos, trace_info->pc_bits, value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t*value <<= esirisc->num_bits - trace_info->pc_bits;\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_read_memory(struct target *target, target_addr_t address, uint32_t size,\n\t\tuint8_t *buffer)\n{\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = target_read_memory(target, address, 1, size, buffer);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read trace data\", target_name(target));\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esirisc_trace_read_buffer(struct target *target, uint8_t *buffer)\n{\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_jtag *jtag_info = &esirisc->jtag_info;\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tuint32_t buffer_cur, status;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = esirisc_jtag_read_csr(jtag_info, CSR_TRACE, CSR_TRACE_BUFFER_CUR, &buffer_cur);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: failed to read Trace CSR: BufferCurrent\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/*\n\t * If the buffer has wrapped, the BufferCurrent CSR indicates the\n\t * next address to be written (ie. the start address). These bytes\n\t * must be dumped first to maintain coherency when analyzing\n\t * captured data.\n\t */\n\tretval = esirisc_trace_get_status(target, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (status & STATUS_W) {\n\t\tuint32_t size = trace_info->buffer_end - buffer_cur;\n\n\t\tretval = esirisc_trace_read_memory(target, buffer_cur, size, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tbuffer += size;\n\t}\n\n\treturn esirisc_trace_read_memory(target, trace_info->buffer_start,\n\t\t\tbuffer_cur - trace_info->buffer_start, buffer);\n}\n\nstatic int esirisc_trace_analyze_full(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tconst uint32_t num_bits = size * 8;\n\tint retval;\n\n\tunsigned pos = 0;\n\twhile (pos < num_bits) {\n\t\tuint32_t id;\n\n\t\tretval = esirisc_trace_buf_get_u32(buffer, size, &pos, 2, &id);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto fail;\n\n\t\tswitch (id) {\n\t\t\tcase ESIRISC_TRACE_ID_EXECUTE:\n\t\t\tcase ESIRISC_TRACE_ID_STALL:\n\t\t\tcase ESIRISC_TRACE_ID_BRANCH:\n\t\t\t\tcommand_print(cmd, \"%s\", esirisc_trace_id_strings[id]);\n\t\t\t\tbreak;\n\n\t\t\tcase ESIRISC_TRACE_ID_EXTENDED: {\n\t\t\t\tuint32_t ext_id;\n\n\t\t\t\tretval = esirisc_trace_buf_get_u32(buffer, size, &pos, 4, &ext_id);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\tgoto fail;\n\n\t\t\t\tswitch (ext_id) {\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_STOP:\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_WAIT:\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_MULTICYCLE:\n\t\t\t\t\t\tcommand_print(cmd, \"%s\", esirisc_trace_ext_id_strings[ext_id]);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_ERET:\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_PC:\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_INDIRECT:\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_END_PC: {\n\t\t\t\t\t\tuint32_t pc;\n\n\t\t\t\t\t\tretval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);\n\t\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\t\tgoto fail;\n\n\t\t\t\t\t\tcommand_print(cmd, \"%s PC: 0x%\" PRIx32,\n\t\t\t\t\t\t\t\tesirisc_trace_ext_id_strings[ext_id], pc);\n\n\t\t\t\t\t\tif (ext_id == ESIRISC_TRACE_EXT_ID_END_PC) {\n\t\t\t\t\t\t\tcommand_print(cmd, \"--- end of trace ---\");\n\t\t\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_EXCEPTION: {\n\t\t\t\t\t\tuint32_t eid, epc;\n\n\t\t\t\t\t\tretval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &eid);\n\t\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\t\tgoto fail;\n\n\t\t\t\t\t\tretval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &epc);\n\t\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\t\tgoto fail;\n\n\t\t\t\t\t\tcommand_print(cmd, \"%s EID: 0x%\" PRIx32 \", EPC: 0x%\" PRIx32,\n\t\t\t\t\t\t\t\tesirisc_trace_ext_id_strings[ext_id], eid, epc);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_COUNT: {\n\t\t\t\t\t\tuint32_t count;\n\n\t\t\t\t\t\tretval = esirisc_trace_buf_get_u32(buffer, size, &pos, 6, &count);\n\t\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\t\tgoto fail;\n\n\t\t\t\t\t\tcommand_print(cmd, \"repeats %\" PRIu32 \" %s\", count,\n\t\t\t\t\t\t\t\t(count == 1) ? \"time\" : \"times\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase ESIRISC_TRACE_EXT_ID_END:\n\t\t\t\t\t\tcommand_print(cmd, \"--- end of trace ---\");\n\t\t\t\t\t\treturn ERROR_OK;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcommand_print(cmd, \"invalid extended trace ID: %\" PRIu32, ext_id);\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tcommand_print(cmd, \"invalid trace ID: %\" PRIu32, id);\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\nfail:\n\tcommand_print(cmd, \"trace buffer too small\");\n\treturn ERROR_BUF_TOO_SMALL;\n}\n\nstatic int esirisc_trace_analyze_simple(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tconst uint32_t end_of_trace = BIT_MASK(trace_info->pc_bits) << 1;\n\tconst uint32_t num_bits = size * 8;\n\tint retval;\n\n\tunsigned pos = 0;\n\twhile (pos < num_bits) {\n\t\tuint32_t pc;\n\n\t\tretval = esirisc_trace_buf_get_pc(target, buffer, size, &pos, &pc);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tif (pc == end_of_trace) {\n\t\t\tcommand_print(cmd, \"--- end of trace ---\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tcommand_print(cmd, \"PC: 0x%\" PRIx32, pc);\n\t}\n\n\tcommand_print(cmd, \"trace buffer too small\");\n\treturn ERROR_BUF_TOO_SMALL;\n}\n\nstatic int esirisc_trace_analyze(struct command_invocation *cmd, uint8_t *buffer, uint32_t size)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tswitch (trace_info->format) {\n\t\tcase ESIRISC_TRACE_FORMAT_FULL:\n\t\t\tcommand_print(cmd, \"--- full pipeline ---\");\n\t\t\treturn esirisc_trace_analyze_full(cmd, buffer, size);\n\n\t\tcase ESIRISC_TRACE_FORMAT_BRANCH:\n\t\t\tcommand_print(cmd, \"--- branches taken ---\");\n\t\t\treturn esirisc_trace_analyze_full(cmd, buffer, size);\n\n\t\tcase ESIRISC_TRACE_FORMAT_ICACHE:\n\t\t\tcommand_print(cmd, \"--- icache misses ---\");\n\t\t\treturn esirisc_trace_analyze_simple(cmd, buffer, size);\n\n\t\tdefault:\n\t\t\tcommand_print(cmd, \"invalid trace format: %i\", trace_info->format);\n\t\t\treturn ERROR_FAIL;\n\t}\n}\n\nstatic int esirisc_trace_analyze_buffer(struct command_invocation *cmd)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tuint8_t *buffer;\n\tuint32_t size;\n\tint retval;\n\n\tsize = esirisc_trace_buffer_size(trace_info);\n\tbuffer = calloc(1, size);\n\tif (!buffer) {\n\t\tcommand_print(cmd, \"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_trace_read_buffer(target, buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = esirisc_trace_analyze(cmd, buffer, size);\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int esirisc_trace_analyze_memory(struct command_invocation *cmd,\n\t\ttarget_addr_t address, uint32_t size)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tuint8_t *buffer;\n\tint retval;\n\n\tbuffer = calloc(1, size);\n\tif (!buffer) {\n\t\tcommand_print(cmd, \"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_trace_read_memory(target, address, size, buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = esirisc_trace_analyze(cmd, buffer, size);\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int esirisc_trace_dump(struct command_invocation *cmd, const char *filename,\n\t\tuint8_t *buffer, uint32_t size)\n{\n\tstruct fileio *fileio;\n\tsize_t size_written;\n\tint retval;\n\n\tretval = fileio_open(&fileio, filename, FILEIO_WRITE, FILEIO_BINARY);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(cmd, \"could not open dump file: %s\", filename);\n\t\treturn retval;\n\t}\n\n\tretval = fileio_write(fileio, size, buffer, &size_written);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(cmd, \"trace data dumped to: %s\", filename);\n\telse\n\t\tcommand_print(cmd, \"could not write dump file: %s\", filename);\n\n\tfileio_close(fileio);\n\n\treturn retval;\n}\n\nstatic int esirisc_trace_dump_buffer(struct command_invocation *cmd, const char *filename)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tuint8_t *buffer;\n\tuint32_t size;\n\tint retval;\n\n\tsize = esirisc_trace_buffer_size(trace_info);\n\tbuffer = calloc(1, size);\n\tif (!buffer) {\n\t\tcommand_print(cmd, \"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_trace_read_buffer(target, buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = esirisc_trace_dump(cmd, filename, buffer, size);\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nstatic int esirisc_trace_dump_memory(struct command_invocation *cmd, const char *filename,\n\t\ttarget_addr_t address, uint32_t size)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tuint8_t *buffer;\n\tint retval;\n\n\tbuffer = calloc(1, size);\n\tif (!buffer) {\n\t\tcommand_print(cmd, \"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = esirisc_trace_read_memory(target, address, size, buffer);\n\tif (retval != ERROR_OK)\n\t\tgoto done;\n\n\tretval = esirisc_trace_dump(cmd, filename, buffer, size);\n\ndone:\n\tfree(buffer);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_init_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = esirisc_trace_init(target);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"trace initialized\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (esirisc_trace_is_fifo(trace_info))\n\t\tcommand_print(CMD, \"trace FIFO address: 0x%\" TARGET_PRIxADDR,\n\t\t\t\ttrace_info->buffer_start);\n\telse {\n\t\tcommand_print(CMD, \"trace buffer start: 0x%\" TARGET_PRIxADDR,\n\t\t\t\ttrace_info->buffer_start);\n\t\tcommand_print(CMD, \"trace buffer end: 0x%\" TARGET_PRIxADDR,\n\t\t\t\ttrace_info->buffer_end);\n\t\tcommand_print(CMD, \"trace buffer will %swrap\",\n\t\t\t\ttrace_info->buffer_wrap ? \"\" : \"not \");\n\t}\n\n\tcommand_print(CMD, \"flow control: %s\",\n\t\t\ttrace_info->flow_control ? \"enabled\" : \"disabled\");\n\n\tcommand_print(CMD, \"trace format: %s\",\n\t\t\tesirisc_trace_format_strings[trace_info->format]);\n\tcommand_print(CMD, \"number of PC bits: %i\", trace_info->pc_bits);\n\n\tcommand_print(CMD, \"start trigger: %s\",\n\t\t\tesirisc_trace_trigger_strings[trace_info->start_trigger]);\n\tcommand_print(CMD, \"start data: 0x%\" PRIx32, trace_info->start_data);\n\tcommand_print(CMD, \"start mask: 0x%\" PRIx32, trace_info->start_mask);\n\n\tcommand_print(CMD, \"stop trigger: %s\",\n\t\t\tesirisc_trace_trigger_strings[trace_info->stop_trigger]);\n\tcommand_print(CMD, \"stop data: 0x%\" PRIx32, trace_info->stop_data);\n\tcommand_print(CMD, \"stop mask: 0x%\" PRIx32, trace_info->stop_mask);\n\n\tcommand_print(CMD, \"trigger delay: %s\",\n\t\t\tesirisc_trace_delay_strings[trace_info->delay]);\n\tcommand_print(CMD, \"trigger delay cycles: %\" PRIu32, trace_info->delay_cycles);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_status_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tuint32_t status;\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = esirisc_trace_get_status(target, &status);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tcommand_print(CMD, \"trace is %s%s%s%s\",\n\t\t\t(status & STATUS_T)  ? \"started\" : \"stopped\",\n\t\t\t(status & STATUS_TD) ? \", disabled\"   : \"\",\n\t\t\t(status & STATUS_W)  ? \", wrapped\"    : \"\",\n\t\t\t(status & STATUS_O)  ? \", overflowed\" : \"\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_start_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = esirisc_trace_start(target);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"trace started\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_stop_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = esirisc_trace_stop(target);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"trace stopped\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_analyze_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\ttarget_addr_t address;\n\tuint32_t size;\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC != 0 && CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 0) {\n\t\t/*\n\t\t * Use of the Trace FIFO typically involves DMA to a peripheral\n\t\t * (eg. SPI) or a separately managed buffer in memory, neither\n\t\t * of which may be under our control. If the destination address\n\t\t * and size are known in the latter case, they may be specified\n\t\t * as arguments as a workaround.\n\t\t */\n\t\tif (esirisc_trace_is_fifo(trace_info)) {\n\t\t\tcommand_print(CMD, \"analyze from FIFO not supported\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\treturn esirisc_trace_analyze_buffer(CMD);\n\t} else {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\n\t\treturn esirisc_trace_analyze_memory(CMD, address, size);\n\t}\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_dump_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\ttarget_addr_t address;\n\tuint32_t size;\n\n\tif (!esirisc->has_trace) {\n\t\tcommand_print(CMD, \"target does not support trace\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC != 1 && CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\t/* also see: handle_esirisc_trace_analyze_command() */\n\t\tif (esirisc_trace_is_fifo(trace_info)) {\n\t\t\tcommand_print(CMD, \"dump from FIFO not supported\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\treturn esirisc_trace_dump_buffer(CMD, CMD_ARGV[0]);\n\t} else {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\n\t\treturn esirisc_trace_dump_memory(CMD, CMD_ARGV[2], address, size);\n\t}\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_buffer_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tuint32_t size;\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], trace_info->buffer_start);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);\n\n\ttrace_info->buffer_end = trace_info->buffer_start + size;\n\n\tif (CMD_ARGC == 3) {\n\t\tif (strcmp(\"wrap\", CMD_ARGV[2]) == 0)\n\t\t\ttrace_info->buffer_wrap = true;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_fifo_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], trace_info->buffer_start);\n\n\t/* FIFOs have the same start and end address */\n\ttrace_info->buffer_end = trace_info->buffer_start;\n\ttrace_info->buffer_wrap = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_flow_control_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"enable\") == 0)\n\t\ttrace_info->flow_control = true;\n\telse if (strcmp(CMD_ARGV[0], \"disable\") == 0)\n\t\ttrace_info->flow_control = false;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_format_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\tint pc_bits;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"full\") == 0)\n\t\ttrace_info->format = ESIRISC_TRACE_FORMAT_FULL;\n\telse if (strcmp(CMD_ARGV[0], \"branch\") == 0)\n\t\ttrace_info->format = ESIRISC_TRACE_FORMAT_BRANCH;\n\telse if (strcmp(CMD_ARGV[0], \"icache\") == 0)\n\t\ttrace_info->format = ESIRISC_TRACE_FORMAT_ICACHE;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], pc_bits);\n\n\tif (pc_bits < 1 || pc_bits > 31) {\n\t\tcommand_print(CMD, \"invalid pc_bits: %i; must be 1..31\", pc_bits);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\ttrace_info->pc_bits = pc_bits;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_trigger_start_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (CMD_ARGC != 1 && CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"none\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_NONE;\n\telse if (strcmp(CMD_ARGV[0], \"pc\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_PC;\n\telse if (strcmp(CMD_ARGV[0], \"load\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_LOAD;\n\telse if (strcmp(CMD_ARGV[0], \"store\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_STORE;\n\telse if (strcmp(CMD_ARGV[0], \"exception\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_EXCEPTION;\n\telse if (strcmp(CMD_ARGV[0], \"eret\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_ERET;\n\telse if (strcmp(CMD_ARGV[0], \"wait\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_WAIT;\n\telse if (strcmp(CMD_ARGV[0], \"stop\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_STOP;\n\telse if (strcmp(CMD_ARGV[0], \"high\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_HIGH;\n\telse if (strcmp(CMD_ARGV[0], \"low\") == 0)\n\t\ttrace_info->start_trigger = ESIRISC_TRACE_TRIGGER_LOW;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 3) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->start_data);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], trace_info->start_mask);\n\t} else {\n\t\ttrace_info->start_data = 0;\n\t\ttrace_info->start_mask = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_trigger_stop_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (CMD_ARGC != 1 && CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"none\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_NONE;\n\telse if (strcmp(CMD_ARGV[0], \"pc\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_PC;\n\telse if (strcmp(CMD_ARGV[0], \"load\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_LOAD;\n\telse if (strcmp(CMD_ARGV[0], \"store\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_STORE;\n\telse if (strcmp(CMD_ARGV[0], \"exception\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_EXCEPTION;\n\telse if (strcmp(CMD_ARGV[0], \"eret\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_ERET;\n\telse if (strcmp(CMD_ARGV[0], \"wait\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_WAIT;\n\telse if (strcmp(CMD_ARGV[0], \"stop\") == 0)\n\t\ttrace_info->stop_trigger = ESIRISC_TRACE_TRIGGER_STOP;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 3) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->stop_data);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], trace_info->stop_mask);\n\t} else {\n\t\ttrace_info->stop_data = 0;\n\t\ttrace_info->stop_mask = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_esirisc_trace_trigger_delay_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct esirisc_common *esirisc = target_to_esirisc(target);\n\tstruct esirisc_trace *trace_info = &esirisc->trace_info;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"none\") == 0)\n\t\ttrace_info->delay = ESIRISC_TRACE_DELAY_NONE;\n\telse if (strcmp(CMD_ARGV[0], \"start\") == 0)\n\t\ttrace_info->delay = ESIRISC_TRACE_DELAY_START;\n\telse if (strcmp(CMD_ARGV[0], \"stop\") == 0)\n\t\ttrace_info->delay = ESIRISC_TRACE_DELAY_STOP;\n\telse if (strcmp(CMD_ARGV[0], \"both\") == 0)\n\t\ttrace_info->delay = ESIRISC_TRACE_DELAY_BOTH;\n\telse\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (trace_info->delay == ESIRISC_TRACE_DELAY_NONE)\n\t\ttrace_info->delay_cycles = 0;\n\telse {\n\t\tif (CMD_ARGC != 2)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], trace_info->delay_cycles);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration esirisc_trace_exec_command_handlers[] = {\n\t{\n\t\t.name = \"init\",\n\t\t.handler = handle_esirisc_trace_init_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"initialize trace collection\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_esirisc_trace_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display trace configuration\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"status\",\n\t\t.handler = handle_esirisc_trace_status_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display trace collection status\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"start\",\n\t\t.handler = handle_esirisc_trace_start_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"start trace collection\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"stop\",\n\t\t.handler = handle_esirisc_trace_stop_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"stop trace collection\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"analyze\",\n\t\t.handler = handle_esirisc_trace_analyze_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[address size]\",\n\t\t.help = \"analyze collected trace data\",\n\t},\n\t{\n\t\t.name = \"dump\",\n\t\t.handler = handle_esirisc_trace_dump_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"dump collected trace data to file\",\n\t\t.usage = \"[address size] filename\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esirisc_trace_trigger_any_command_handlers[] = {\n\t{\n\t\t.name = \"start\",\n\t\t.handler = handle_esirisc_trace_trigger_start_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trigger start condition\",\n\t\t.usage = \"('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop'|'high'|'low')\"\n\t\t\t\t \" [start_data start_mask]\",\n\t},\n\t{\n\t\t.name = \"stop\",\n\t\t.handler = handle_esirisc_trace_trigger_stop_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trigger stop condition\",\n\t\t.usage = \"('none'|'pc'|'load'|'store'|'exception'|'eret'|'wait'|'stop')\"\n\t\t\t\t \" [stop_data stop_mask]\",\n\t},\n\t{\n\t\t.name = \"delay\",\n\t\t.handler = handle_esirisc_trace_trigger_delay_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trigger start/stop delay in clock cycles\",\n\t\t.usage = \"('none'|'start'|'stop'|'both') [cycles]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esirisc_trace_any_command_handlers[] = {\n\t{\n\t\t.name = \"buffer\",\n\t\t.handler = handle_esirisc_trace_buffer_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trace buffer\",\n\t\t.usage = \"address size ['wrap']\",\n\t},\n\t{\n\t\t.name = \"fifo\",\n\t\t.handler = handle_esirisc_trace_fifo_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trace FIFO\",\n\t\t.usage = \"address\",\n\t},\n\t{\n\t\t.name = \"flow_control\",\n\t\t.handler = handle_esirisc_trace_flow_control_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"enable or disable stalling CPU to collect trace data\",\n\t\t.usage = \"('enable'|'disable')\",\n\t},\n\t{\n\t\t.name = \"format\",\n\t\t.handler = handle_esirisc_trace_format_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"configure trace format\",\n\t\t.usage = \"('full'|'branch'|'icache') pc_bits\",\n\t},\n\t{\n\t\t.name = \"trigger\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"eSi-Trace trigger command group\",\n\t\t.usage = \"\",\n\t\t.chain = esirisc_trace_trigger_any_command_handlers,\n\t},\n\t{\n\t\t.chain = esirisc_trace_exec_command_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration esirisc_trace_command_handlers[] = {\n\t{\n\t\t.name = \"trace\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"eSi-Trace command group\",\n\t\t.usage = \"\",\n\t\t.chain = esirisc_trace_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/esirisc_trace.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESIRISC_TRACE_H\n#define OPENOCD_TARGET_ESIRISC_TRACE_H\n\n#include <helper/command.h>\n#include <helper/types.h>\n#include <target/target.h>\n\nenum esirisc_trace_delay {\n\tESIRISC_TRACE_DELAY_NONE,\n\tESIRISC_TRACE_DELAY_START,\n\tESIRISC_TRACE_DELAY_STOP,\n\tESIRISC_TRACE_DELAY_BOTH,\n};\n\nenum esirisc_trace_format {\n\tESIRISC_TRACE_FORMAT_FULL,\n\tESIRISC_TRACE_FORMAT_BRANCH,\n\tESIRISC_TRACE_FORMAT_ICACHE,\n};\n\nenum esirisc_trace_id {\n\tESIRISC_TRACE_ID_EXECUTE,\n\tESIRISC_TRACE_ID_STALL,\n\tESIRISC_TRACE_ID_BRANCH,\n\tESIRISC_TRACE_ID_EXTENDED,\n};\n\nenum esirisc_trace_ext_id {\n\tESIRISC_TRACE_EXT_ID_EXCEPTION = 1,\n\tESIRISC_TRACE_EXT_ID_ERET,\n\tESIRISC_TRACE_EXT_ID_STOP,\n\tESIRISC_TRACE_EXT_ID_WAIT,\n\tESIRISC_TRACE_EXT_ID_MULTICYCLE,\n\tESIRISC_TRACE_EXT_ID_COUNT,\n\tESIRISC_TRACE_EXT_ID_PC,\n\tESIRISC_TRACE_EXT_ID_INDIRECT,\n\tESIRISC_TRACE_EXT_ID_END,\n\tESIRISC_TRACE_EXT_ID_END_PC,\n};\n\nenum esirisc_trace_trigger {\n\tESIRISC_TRACE_TRIGGER_NONE,\n\tESIRISC_TRACE_TRIGGER_PC,\n\tESIRISC_TRACE_TRIGGER_LOAD,\n\tESIRISC_TRACE_TRIGGER_STORE,\n\tESIRISC_TRACE_TRIGGER_EXCEPTION,\n\tESIRISC_TRACE_TRIGGER_ERET,\n\tESIRISC_TRACE_TRIGGER_WAIT,\n\tESIRISC_TRACE_TRIGGER_STOP,\n\tESIRISC_TRACE_TRIGGER_HIGH,\n\tESIRISC_TRACE_TRIGGER_LOW,\n};\n\nstruct esirisc_trace {\n\ttarget_addr_t buffer_start;\n\ttarget_addr_t buffer_end;\n\tbool buffer_wrap;\n\tbool flow_control;\n\n\tenum esirisc_trace_format format;\n\tint pc_bits;\n\n\tenum esirisc_trace_trigger start_trigger;\n\tuint32_t start_data;\n\tuint32_t start_mask;\n\n\tenum esirisc_trace_trigger stop_trigger;\n\tuint32_t stop_data;\n\tuint32_t stop_mask;\n\n\tenum esirisc_trace_delay delay;\n\tuint32_t delay_cycles;\n};\n\nextern const struct command_registration esirisc_trace_command_handlers[];\n\nstatic inline uint32_t esirisc_trace_buffer_size(struct esirisc_trace *trace_info)\n{\n\treturn trace_info->buffer_end - trace_info->buffer_start;\n}\n\nstatic inline bool esirisc_trace_is_fifo(struct esirisc_trace *trace_info)\n{\n\treturn trace_info->buffer_start == trace_info->buffer_end;\n}\n\n#endif /* OPENOCD_TARGET_ESIRISC_TRACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libespressif.la\n%C%_libespressif_la_SOURCES = \\\n\t%D%/esp_xtensa.c \\\n\t%D%/esp_xtensa.h \\\n\t%D%/esp_xtensa_smp.c \\\n\t%D%/esp_xtensa_smp.h \\\n\t%D%/esp_xtensa_semihosting.c \\\n\t%D%/esp_xtensa_semihosting.h \\\n\t%D%/esp_xtensa_apptrace.c \\\n\t%D%/esp_xtensa_apptrace.h \\\n\t%D%/esp32_apptrace.c \\\n\t%D%/esp32_apptrace.h \\\n\t%D%/esp32.c \\\n\t%D%/esp32s2.c \\\n\t%D%/esp32s3.c \\\n\t%D%/esp.c \\\n\t%D%/esp.h \\\n\t%D%/esp32_sysview.c \\\n\t%D%/esp32_sysview.h \\\n\t%D%/segger_sysview.h \\\n\t%D%/esp_semihosting.c \\\n\t%D%/esp_semihosting.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Espressif chips common target API for OpenOCD                         *\n *   Copyright (C) 2021 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n#include \"target/target.h\"\n#include \"esp.h\"\n\nint esp_dbgstubs_table_read(struct target *target, struct esp_dbg_stubs *dbg_stubs)\n{\n\tuint32_t table_size, table_start_id, desc_entry_id, gcov_entry_id;\n\tuint32_t entries[ESP_DBG_STUB_ENTRY_MAX] = {0};\n\tuint8_t entry_buff[sizeof(entries)] = {0}; /* to avoid endiannes issues */\n\n\tLOG_TARGET_DEBUG(target, \"Read debug stubs info %\" PRIx32 \" / %d\", dbg_stubs->base, dbg_stubs->entries_count);\n\n\t/* First of, read 2 entries to get magic num and table size */\n\tint res = target_read_buffer(target, dbg_stubs->base, sizeof(uint32_t) * 2, entry_buff);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to read first debug stub entry!\", target_name(target));\n\t\treturn res;\n\t}\n\tentries[0] = target_buffer_get_u32(target, entry_buff);\n\tentries[1] = target_buffer_get_u32(target, entry_buff + sizeof(uint32_t));\n\n\tif (entries[0] != ESP_DBG_STUB_MAGIC_NUM_VAL) {\n\t\t/* idf with the old table entry structure */\n\t\ttable_size = 2;\n\t\ttable_start_id = 0;\n\t\tdesc_entry_id = 0;\n\t\tgcov_entry_id = 1;\n\t} else {\n\t\ttable_size = entries[1];\n\t\ttable_start_id = ESP_DBG_STUB_TABLE_START;\n\t\tdesc_entry_id = ESP_DBG_STUB_TABLE_START;\n\t\tgcov_entry_id = ESP_DBG_STUB_ENTRY_FIRST;\n\n\t\t/* discard unsupported entries */\n\t\tif (table_size > ESP_DBG_STUB_ENTRY_MAX)\n\t\t\ttable_size = ESP_DBG_STUB_ENTRY_MAX;\n\n\t\t/* now read the remaining entries */\n\t\tres = target_read_buffer(target, dbg_stubs->base + 2 * sizeof(uint32_t), sizeof(uint32_t) * table_size - 2,\n\t\t\tentry_buff + sizeof(uint32_t) * 2);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to read debug stubs info!\");\n\t\t\treturn res;\n\t\t}\n\t\tfor (unsigned int i = 2; i < table_size; ++i)\n\t\t\tentries[i] = target_buffer_get_u32(target, entry_buff + sizeof(uint32_t) * i);\n\n\t\tdbg_stubs->entries[ESP_DBG_STUB_CAPABILITIES] = entries[ESP_DBG_STUB_CAPABILITIES];\n\t}\n\n\tdbg_stubs->entries[ESP_DBG_STUB_DESC] = entries[desc_entry_id];\n\tdbg_stubs->entries[ESP_DBG_STUB_ENTRY_GCOV] = entries[gcov_entry_id];\n\n\tfor (enum esp_dbg_stub_id i = ESP_DBG_STUB_DESC; i < ESP_DBG_STUB_ENTRY_MAX; i++) {\n\t\tLOG_DEBUG(\"Check dbg stub %d - %x\", i, dbg_stubs->entries[i]);\n\t\tif (dbg_stubs->entries[i]) {\n\t\t\tLOG_DEBUG(\"New dbg stub %d at %x\", dbg_stubs->entries_count, dbg_stubs->entries[i]);\n\t\t\tdbg_stubs->entries_count++;\n\t\t}\n\t}\n\tif (dbg_stubs->entries_count < table_size - table_start_id)\n\t\tLOG_WARNING(\"Not full dbg stub table %d of %d\", dbg_stubs->entries_count, table_size - table_start_id);\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Espressif chips common target API for OpenOCD                         *\n *   Copyright (C) 2021 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP_H\n#define OPENOCD_TARGET_ESP_H\n\n#include <stdint.h>\n#include <helper/bits.h>\n\n/* must be in sync with ESP-IDF version */\n/** Size of the pre-compiled target buffer for stub trampoline.\n * @note Must be in sync with ESP-IDF version */\n#define ESP_DBG_STUBS_CODE_BUF_SIZE         32\t/* TODO: move this info to esp_dbg_stubs_desc */\n/** Size of the pre-compiled target buffer for stack.\n * @note Must be in sync with ESP-IDF version */\n#define ESP_DBG_STUBS_STACK_MIN_SIZE        2048/* TODO: move this info to esp_dbg_stubs_desc */\n\n/**\n * Debug stubs table entries IDs\n *\n * @note Must be in sync with ESP-IDF version\n */\nenum esp_dbg_stub_id {\n\tESP_DBG_STUB_ENTRY_MAGIC_NUM,\n\tESP_DBG_STUB_TABLE_SIZE,\n\tESP_DBG_STUB_TABLE_START,\n\tESP_DBG_STUB_DESC = ESP_DBG_STUB_TABLE_START,\t/*< Stubs descriptor ID */\n\tESP_DBG_STUB_ENTRY_FIRST,\n\tESP_DBG_STUB_ENTRY_GCOV = ESP_DBG_STUB_ENTRY_FIRST,\t/*< GCOV stub ID */\n\tESP_DBG_STUB_CAPABILITIES,\n\t/* add new stub entries here */\n\tESP_DBG_STUB_ENTRY_MAX,\n};\n\n#define ESP_DBG_STUB_MAGIC_NUM_VAL      0xFEEDBEEF\n#define ESP_DBG_STUB_CAP_GCOV_THREAD    BIT(0)\n\n/**\n * Debug stubs descriptor. ID: ESP_DBG_STUB_DESC\n *\n * @note Must be in sync with ESP-IDF version\n */\nstruct esp_dbg_stubs_desc {\n\t/** Address of pre-compiled target buffer for stub trampoline.\n\t * Size of the buffer is ESP_DBG_STUBS_CODE_BUF_SIZE\n\t */\n\tuint32_t tramp_addr;\n\t/** Pre-compiled target buffer's addr for stack. The size of the buffer is ESP_DBG_STUBS_STACK_MIN_SIZE.\n\t * Target has the buffer which is used for the stack of onboard algorithms.\n\t * If stack size required by algorithm exceeds ESP_DBG_STUBS_STACK_MIN_SIZE,\n\t * it should be allocated using onboard function pointed by 'data_alloc' and\n\t * freed by 'data_free'. They fit to the minimal stack. See below.\n\t */\n\tuint32_t min_stack_addr;\n\t/** Address of malloc-like function to allocate buffer on target. */\n\tuint32_t data_alloc;\n\t/** Address of free-like function to free buffer allocated with data_alloc. */\n\tuint32_t data_free;\n};\n\n/**\n * Debug stubs info.\n */\nstruct esp_dbg_stubs {\n\t/** Address. */\n\tuint32_t base;\n\t/** Table contents. */\n\tuint32_t entries[ESP_DBG_STUB_ENTRY_MAX];\n\t/** Number of table entries. */\n\tuint32_t entries_count;\n\t/** Debug stubs decsriptor. */\n\tstruct esp_dbg_stubs_desc desc;\n};\n\nstruct esp_common {\n\tstruct esp_dbg_stubs dbg_stubs;\n};\n\nint esp_dbgstubs_table_read(struct target *target, struct esp_dbg_stubs *dbg_stubs);\n\n#endif\t/* OPENOCD_TARGET_ESP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP32 target API for OpenOCD                                          *\n *   Copyright (C) 2016-2019 Espressif Systems Ltd.                        *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/smp.h>\n#include <target/semihosting_common.h>\n#include \"assert.h\"\n#include \"esp_xtensa_smp.h\"\n\n/*\nThis is a JTAG driver for the ESP32, the are two Tensilica cores inside\nthe ESP32 chip. For more information please have a look into ESP32 target\nimplementation.\n*/\n\n/* ESP32 memory map */\n#define ESP32_RTC_DATA_LOW        0x50000000\n#define ESP32_RTC_DATA_HIGH       0x50002000\n#define ESP32_DR_REG_LOW          0x3ff00000\n#define ESP32_DR_REG_HIGH         0x3ff71000\n#define ESP32_SYS_RAM_LOW         0x60000000UL\n#define ESP32_SYS_RAM_HIGH        (ESP32_SYS_RAM_LOW + 0x20000000UL)\n#define ESP32_RTC_SLOW_MEM_BASE   ESP32_RTC_DATA_LOW\n\n/* ESP32 WDT */\n#define ESP32_WDT_WKEY_VALUE       0x50d83aa1\n#define ESP32_TIMG0_BASE           0x3ff5f000\n#define ESP32_TIMG1_BASE           0x3ff60000\n#define ESP32_TIMGWDT_CFG0_OFF     0x48\n#define ESP32_TIMGWDT_PROTECT_OFF  0x64\n#define ESP32_TIMG0WDT_CFG0        (ESP32_TIMG0_BASE + ESP32_TIMGWDT_CFG0_OFF)\n#define ESP32_TIMG1WDT_CFG0        (ESP32_TIMG1_BASE + ESP32_TIMGWDT_CFG0_OFF)\n#define ESP32_TIMG0WDT_PROTECT     (ESP32_TIMG0_BASE + ESP32_TIMGWDT_PROTECT_OFF)\n#define ESP32_TIMG1WDT_PROTECT     (ESP32_TIMG1_BASE + ESP32_TIMGWDT_PROTECT_OFF)\n#define ESP32_RTCCNTL_BASE         0x3ff48000\n#define ESP32_RTCWDT_CFG_OFF       0x8C\n#define ESP32_RTCWDT_PROTECT_OFF   0xA4\n#define ESP32_RTCWDT_CFG           (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_CFG_OFF)\n#define ESP32_RTCWDT_PROTECT       (ESP32_RTCCNTL_BASE + ESP32_RTCWDT_PROTECT_OFF)\n\n#define ESP32_TRACEMEM_BLOCK_SZ    0x4000\n\n/* ESP32 dport regs */\n#define ESP32_DR_REG_DPORT_BASE         ESP32_DR_REG_LOW\n#define ESP32_DPORT_APPCPU_CTRL_B_REG   (ESP32_DR_REG_DPORT_BASE + 0x030)\n#define ESP32_DPORT_APPCPU_CLKGATE_EN   BIT(0)\n/* ESP32 RTC regs */\n#define ESP32_RTC_CNTL_SW_CPU_STALL_REG (ESP32_RTCCNTL_BASE + 0xac)\n#define ESP32_RTC_CNTL_SW_CPU_STALL_DEF 0x0\n\n/* 0 - don't care, 1 - TMS low, 2 - TMS high */\nenum esp32_flash_bootstrap {\n\tFBS_DONTCARE = 0,\n\tFBS_TMSLOW,\n\tFBS_TMSHIGH,\n};\n\nstruct esp32_common {\n\tstruct esp_xtensa_smp_common esp_xtensa_smp;\n\tenum esp32_flash_bootstrap flash_bootstrap;\n};\n\nstatic inline struct esp32_common *target_to_esp32(struct target *target)\n{\n\treturn container_of(target->arch_info, struct esp32_common, esp_xtensa_smp);\n}\n\n/* Reset ESP32 peripherals.\n * Postconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted,\n * APP CPU is in reset\n * How this works:\n * 0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt\n * 1. set CPU initial PC to 0x50000000 (ESP32_SMP_RTC_DATA_LOW) by clearing RTC_CNTL_{PRO,APP}CPU_STAT_VECTOR_SEL\n * 2. load stub code into ESP32_SMP_RTC_DATA_LOW; once executed, stub code will disable watchdogs and\n * make CPU spin in an idle loop.\n * 3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit\n * 4. wait for the OCD to be reset\n * 5. halt the target and wait for it to be halted (at this point CPU is in the idle loop)\n * 6. restore initial PC and the contents of ESP32_SMP_RTC_DATA_LOW\n * TODO: some state of RTC_CNTL is not reset during SW_SYS_RST. Need to reset that manually. */\n\nstatic const uint8_t esp32_reset_stub_code[] = {\n#include \"../../../contrib/loaders/reset/espressif/esp32/cpu_reset_handler_code.inc\"\n};\n\nstatic int esp32_soc_reset(struct target *target)\n{\n\tint res;\n\tstruct target_list *head;\n\tstruct xtensa *xtensa;\n\n\tLOG_DEBUG(\"start\");\n\t/* In order to write to peripheral registers, target must be halted first */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"Target not halted before SoC reset, trying to halt it first\");\n\t\txtensa_halt(target);\n\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Couldn't halt target before SoC reset, trying to do reset-halt\");\n\t\t\tres = xtensa_assert_reset(target);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\tbool reset_halt_save = target->reset_halt;\n\t\t\ttarget->reset_halt = true;\n\t\t\tres = xtensa_deassert_reset(target);\n\t\t\ttarget->reset_halt = reset_halt_save;\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\txtensa_halt(target);\n\t\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Couldn't halt target before SoC reset\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (target->smp) {\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\txtensa = target_to_xtensa(head->target);\n\t\t\t/* if any of the cores is stalled unstall them */\n\t\t\tif (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {\n\t\t\t\tLOG_TARGET_DEBUG(head->target, \"Unstall CPUs before SW reset!\");\n\t\t\t\tres = target_write_u32(target,\n\t\t\t\t\tESP32_RTC_CNTL_SW_CPU_STALL_REG,\n\t\t\t\t\tESP32_RTC_CNTL_SW_CPU_STALL_DEF);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_TARGET_ERROR(head->target, \"Failed to unstall CPUs before SW reset!\");\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\tbreak;\t/* both cores are unstalled now, so exit the loop */\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"Loading stub code into RTC RAM\");\n\tuint8_t slow_mem_save[sizeof(esp32_reset_stub_code)];\n\n\t/* Save contents of RTC_SLOW_MEM which we are about to overwrite */\n\tres = target_read_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to save contents of RTC_SLOW_MEM (%d)!\", res);\n\t\treturn res;\n\t}\n\n\t/* Write stub code into RTC_SLOW_MEM */\n\tres = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(esp32_reset_stub_code), esp32_reset_stub_code);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write stub (%d)!\", res);\n\t\treturn res;\n\t}\n\n\tLOG_DEBUG(\"Resuming the target\");\n\txtensa = target_to_xtensa(target);\n\txtensa->suppress_dsr_errors = true;\n\tres = xtensa_resume(target, 0, ESP32_RTC_SLOW_MEM_BASE + 4, 0, 0);\n\txtensa->suppress_dsr_errors = false;\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to run stub (%d)!\", res);\n\t\treturn res;\n\t}\n\tLOG_DEBUG(\"resume done, waiting for the target to come alive\");\n\n\t/* Wait for SoC to reset */\n\talive_sleep(100);\n\tint64_t timeout = timeval_ms() + 100;\n\tbool get_timeout = false;\n\twhile (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {\n\t\talive_sleep(10);\n\t\txtensa_poll(target);\n\t\tif (timeval_ms() >= timeout) {\n\t\t\tLOG_TARGET_ERROR(target, \"Timed out waiting for CPU to be reset, target state=%d\",\n\t\t\t\ttarget->state);\n\t\t\tget_timeout = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Halt the CPU again */\n\tLOG_DEBUG(\"halting the target\");\n\txtensa_halt(target);\n\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\tif (res == ERROR_OK) {\n\t\tLOG_DEBUG(\"restoring RTC_SLOW_MEM\");\n\t\tres = target_write_buffer(target, ESP32_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);\n\t\tif (res != ERROR_OK)\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to restore contents of RTC_SLOW_MEM (%d)!\", res);\n\t} else {\n\t\tLOG_TARGET_ERROR(target, \"Timed out waiting for CPU to be halted after SoC reset\");\n\t}\n\n\treturn get_timeout ? ERROR_TARGET_TIMEOUT : res;\n}\n\nstatic int esp32_disable_wdts(struct target *target)\n{\n\t/* TIMG1 WDT */\n\tint res = target_write_u32(target, ESP32_TIMG0WDT_PROTECT, ESP32_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_TIMG0WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_TIMG0WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_TIMG0WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* TIMG2 WDT */\n\tres = target_write_u32(target, ESP32_TIMG1WDT_PROTECT, ESP32_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_TIMG1WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_TIMG1WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_TIMG1WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* RTC WDT */\n\tres = target_write_u32(target, ESP32_RTCWDT_PROTECT, ESP32_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_RTCWDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_RTCWDT_CFG, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_RTCWDT_CFG (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_on_halt(struct target *target)\n{\n\tint ret = esp32_disable_wdts(target);\n\tif (ret == ERROR_OK)\n\t\tret = esp_xtensa_smp_on_halt(target);\n\treturn ret;\n}\n\nstatic int esp32_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int esp32_virt2phys(struct target *target,\n\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tif (physical) {\n\t\t*physical = virtual;\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_FAIL;\n}\n\n/* The TDI pin is also used as a flash Vcc bootstrap pin. If we reset the CPU externally, the last state of the TDI pin\n * can allow the power to an 1.8V flash chip to be raised to 3.3V, or the other way around. Users can use the\n * esp32 flashbootstrap command to set a level, and this routine will make sure the tdi line will return to\n * that when the jtag port is idle. */\n\nstatic void esp32_queue_tdi_idle(struct target *target)\n{\n\tstruct esp32_common *esp32 = target_to_esp32(target);\n\tstatic uint32_t value;\n\tuint8_t t[4] = { 0, 0, 0, 0 };\n\n\tif (esp32->flash_bootstrap == FBS_TMSLOW)\n\t\t/* Make sure tdi is 0 at the exit of queue execution */\n\t\tvalue = 0;\n\telse if (esp32->flash_bootstrap == FBS_TMSHIGH)\n\t\t/* Make sure tdi is 1 at the exit of queue execution */\n\t\tvalue = 1;\n\telse\n\t\treturn;\n\n\t/* Scan out 1 bit, do not move from IRPAUSE after we're done. */\n\tbuf_set_u32(t, 0, 1, value);\n\tjtag_add_plain_ir_scan(1, t, NULL, TAP_IRPAUSE);\n}\n\nstatic int esp32_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\treturn esp_xtensa_smp_target_init(cmd_ctx, target);\n}\n\nstatic const struct xtensa_debug_ops esp32_dbg_ops = {\n\t.queue_enable = xtensa_dm_queue_enable,\n\t.queue_reg_read = xtensa_dm_queue_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_reg_write\n};\n\nstatic const struct xtensa_power_ops esp32_pwr_ops = {\n\t.queue_reg_read = xtensa_dm_queue_pwr_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_pwr_reg_write\n};\n\nstatic const struct esp_xtensa_smp_chip_ops esp32_chip_ops = {\n\t.reset = esp32_soc_reset,\n\t.on_halt = esp32_on_halt\n};\n\nstatic const struct esp_semihost_ops esp32_semihost_ops = {\n\t.prepare = esp32_disable_wdts\n};\n\nstatic int esp32_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct xtensa_debug_module_config esp32_dm_cfg = {\n\t\t.dbg_ops = &esp32_dbg_ops,\n\t\t.pwr_ops = &esp32_pwr_ops,\n\t\t.tap = target->tap,\n\t\t.queue_tdi_idle = esp32_queue_tdi_idle,\n\t\t.queue_tdi_idle_arg = target\n\t};\n\n\tstruct esp32_common *esp32 = calloc(1, sizeof(struct esp32_common));\n\tif (!esp32) {\n\t\tLOG_ERROR(\"Failed to alloc memory for arch info!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = esp_xtensa_smp_init_arch_info(target, &esp32->esp_xtensa_smp,\n\t\t&esp32_dm_cfg, &esp32_chip_ops, &esp32_semihost_ops);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to init arch info!\");\n\t\tfree(esp32);\n\t\treturn ret;\n\t}\n\tesp32->flash_bootstrap = FBS_DONTCARE;\n\n\t/* Assume running target. If different, the first poll will fix this. */\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nstatic COMMAND_HELPER(esp32_cmd_flashbootstrap_do, struct esp32_common *esp32)\n{\n\tint state = -1;\n\n\tif (CMD_ARGC < 1) {\n\t\tconst char *st;\n\t\tstate = esp32->flash_bootstrap;\n\t\tif (state == FBS_DONTCARE)\n\t\t\tst = \"Don't care\";\n\t\telse if (state == FBS_TMSLOW)\n\t\t\tst = \"Low (3.3V)\";\n\t\telse if (state == FBS_TMSHIGH)\n\t\t\tst = \"High (1.8V)\";\n\t\telse\n\t\t\tst = \"None\";\n\t\tcommand_print(CMD, \"Current idle tms state: %s\", st);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!strcasecmp(CMD_ARGV[0], \"none\"))\n\t\tstate = FBS_DONTCARE;\n\telse if (!strcasecmp(CMD_ARGV[0], \"1.8\"))\n\t\tstate = FBS_TMSHIGH;\n\telse if (!strcasecmp(CMD_ARGV[0], \"3.3\"))\n\t\tstate = FBS_TMSLOW;\n\telse if (!strcasecmp(CMD_ARGV[0], \"high\"))\n\t\tstate = FBS_TMSHIGH;\n\telse if (!strcasecmp(CMD_ARGV[0], \"low\"))\n\t\tstate = FBS_TMSLOW;\n\n\tif (state == -1) {\n\t\tcommand_print(CMD,\n\t\t\t\"Argument unknown. Please pick one of none, high, low, 1.8 or 3.3\");\n\t\treturn ERROR_FAIL;\n\t}\n\tesp32->flash_bootstrap = state;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp32_cmd_flashbootstrap)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,\n\t\t\t\ttarget_to_esp32(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(esp32_cmd_flashbootstrap_do,\n\t\ttarget_to_esp32(target));\n}\n\nstatic const struct command_registration esp32_any_command_handlers[] = {\n\t{\n\t\t.name = \"flashbootstrap\",\n\t\t.handler = esp32_cmd_flashbootstrap,\n\t\t.mode = COMMAND_ANY,\n\t\t.help =\n\t\t\t\"Set the idle state of the TMS pin, which at reset also is the voltage selector for the flash chip.\",\n\t\t.usage = \"none|1.8|3.3|high|low\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration esp32_command_handlers[] = {\n\t{\n\t\t.chain = esp_xtensa_smp_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp\",\n\t\t.usage = \"\",\n\t\t.chain = esp32_apptrace_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp32\",\n\t\t.usage = \"\",\n\t\t.chain = smp_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp32\",\n\t\t.usage = \"\",\n\t\t.chain = esp32_any_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = semihosting_common_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for Xtensa targets. */\nstruct target_type esp32_target = {\n\t.name = \"esp32\",\n\n\t.poll = esp_xtensa_smp_poll,\n\t.arch_state = esp32_arch_state,\n\n\t.halt = xtensa_halt,\n\t.resume = esp_xtensa_smp_resume,\n\t.step = esp_xtensa_smp_step,\n\n\t.assert_reset = esp_xtensa_smp_assert_reset,\n\t.deassert_reset = esp_xtensa_smp_deassert_reset,\n\t.soft_reset_halt = esp_xtensa_smp_soft_reset_halt,\n\n\t.virt2phys = esp32_virt2phys,\n\t.mmu = xtensa_mmu_is_enabled,\n\t.read_memory = xtensa_read_memory,\n\t.write_memory = xtensa_write_memory,\n\n\t.read_buffer = xtensa_read_buffer,\n\t.write_buffer = xtensa_write_buffer,\n\n\t.checksum_memory = xtensa_checksum_memory,\n\n\t.get_gdb_arch = xtensa_get_gdb_arch,\n\t.get_gdb_reg_list = xtensa_get_gdb_reg_list,\n\n\t.add_breakpoint = esp_xtensa_breakpoint_add,\n\t.remove_breakpoint = esp_xtensa_breakpoint_remove,\n\n\t.add_watchpoint = esp_xtensa_smp_watchpoint_add,\n\t.remove_watchpoint = esp_xtensa_smp_watchpoint_remove,\n\n\t.target_create = esp32_target_create,\n\t.init_target = esp32_target_init,\n\t.examine = xtensa_examine,\n\t.deinit_target = esp_xtensa_target_deinit,\n\n\t.commands = esp32_command_handlers,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32_apptrace.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP32xx application tracing module for OpenOCD                        *\n *   Copyright (C) 2017 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#ifdef HAVE_ARPA_INET_H\n#include <arpa/inet.h>\n#endif\n\n#ifdef HAVE_NETDB_H\n#include <netdb.h>\n#endif\n\n#ifndef _WIN32\n#include <netinet/tcp.h>\n#include <sys/ioctl.h>\n#endif\n\n#include <helper/list.h>\n#include <helper/time_support.h>\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/smp.h>\n#include <server/server.h>\n#include \"esp_xtensa.h\"\n#include \"esp_xtensa_smp.h\"\n#include \"esp_xtensa_apptrace.h\"\n#include \"esp32_apptrace.h\"\n#include \"esp32_sysview.h\"\n#include \"segger_sysview.h\"\n\n#define ESP32_APPTRACE_USER_BLOCK_CORE(_v_)     ((_v_) >> 15)\n#define ESP32_APPTRACE_USER_BLOCK_LEN(_v_)      ((_v_) & ~BIT(15))\n\n#define ESP32_APPTRACE_USER_BLOCK_HDR_SZ        4\n\n#define ESP_APPTRACE_CMD_MODE_GEN               0\n#define ESP_APPTRACE_CMD_MODE_SYSVIEW           1\n#define ESP_APPTRACE_CMD_MODE_SYSVIEW_MCORE     2\n#define ESP_APPTRACE_CMD_MODE_SYNC              3\n\n#define ESP32_APPTRACE_TGT_STATE_TMO            5000\n#define ESP_APPTRACE_BLOCKS_POOL_SZ             10\n\nstruct esp32_apptrace_dest_file_data {\n\tint fout;\n};\n\nstruct esp32_apptrace_dest_tcp_data {\n\tint sockfd;\n};\n\nstruct esp32_apptrace_target_state {\n\tint running;\n\tuint32_t block_id;\n\tuint32_t data_len;\n};\n\nstruct esp_apptrace_target2host_hdr {\n\tuint16_t block_sz;\n\tuint16_t wr_sz;\n};\n#define APPTRACE_BLOCK_SIZE_OFFSET      0\n#define APPTRACE_WR_SIZE_OFFSET         2\n\nstruct esp32_apptrace_block {\n\tstruct list_head node;\n\tuint8_t *data;\n\tuint32_t data_len;\n};\n\nstatic int esp32_apptrace_data_processor(void *priv);\nstatic int esp32_apptrace_get_data_info(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_target_state *target_state,\n\tuint32_t *fired_target_num);\nstatic int esp32_apptrace_safe_halt_targets(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_target_state *targets);\nstatic struct esp32_apptrace_block *esp32_apptrace_free_block_get(struct esp32_apptrace_cmd_ctx *ctx);\nstatic int esp32_apptrace_handle_trace_block(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_block *block);\nstatic int esp32_sysview_start(struct esp32_apptrace_cmd_ctx *ctx);\nstatic int esp32_sysview_stop(struct esp32_apptrace_cmd_ctx *ctx);\n\nstatic const bool s_time_stats_enable = true;\n\n/*********************************************************************\n*                       Trace destination API\n**********************************************************************/\n\nstatic int esp32_apptrace_file_dest_write(void *priv, uint8_t *data, int size)\n{\n\tstruct esp32_apptrace_dest_file_data *dest_data = (struct esp32_apptrace_dest_file_data *)priv;\n\n\tint wr_sz = write(dest_data->fout, data, size);\n\tif (wr_sz != size) {\n\t\tLOG_ERROR(\"Failed to write %d bytes to out file (%d)! Written %d.\", size, errno, wr_sz);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_file_dest_cleanup(void *priv)\n{\n\tstruct esp32_apptrace_dest_file_data *dest_data = (struct esp32_apptrace_dest_file_data *)priv;\n\n\tif (dest_data->fout > 0)\n\t\tclose(dest_data->fout);\n\tfree(dest_data);\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_file_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name)\n{\n\tstruct esp32_apptrace_dest_file_data *dest_data = calloc(1, sizeof(*dest_data));\n\tif (!dest_data) {\n\t\tLOG_ERROR(\"Failed to alloc mem for file dest!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_INFO(\"Open file %s\", dest_name);\n\tdest_data->fout = open(dest_name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);\n\tif (dest_data->fout <= 0) {\n\t\tLOG_ERROR(\"Failed to open file %s\", dest_name);\n\t\tfree(dest_data);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdest->priv = dest_data;\n\tdest->write = esp32_apptrace_file_dest_write;\n\tdest->clean = esp32_apptrace_file_dest_cleanup;\n\tdest->log_progress = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_console_dest_write(void *priv, uint8_t *data, int size)\n{\n\tLOG_USER_N(\"%.*s\", size, data);\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_console_dest_cleanup(void *priv)\n{\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_console_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name)\n{\n\tdest->priv = NULL;\n\tdest->write = esp32_apptrace_console_dest_write;\n\tdest->clean = esp32_apptrace_console_dest_cleanup;\n\tdest->log_progress = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_tcp_dest_write(void *priv, uint8_t *data, int size)\n{\n\tstruct esp32_apptrace_dest_tcp_data *dest_data = (struct esp32_apptrace_dest_tcp_data *)priv;\n\tint wr_sz = write_socket(dest_data->sockfd, data, size);\n\tif (wr_sz != size) {\n\t\tLOG_ERROR(\"Failed to write %u bytes to out socket (%d)! Written %d.\", size, errno, wr_sz);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_tcp_dest_cleanup(void *priv)\n{\n\tstruct esp32_apptrace_dest_tcp_data *dest_data = (struct esp32_apptrace_dest_tcp_data *)priv;\n\n\tif (dest_data->sockfd > 0)\n\t\tclose_socket(dest_data->sockfd);\n\tfree(dest_data);\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_tcp_dest_init(struct esp32_apptrace_dest *dest, const char *dest_name)\n{\n\tconst char *port_sep = strchr(dest_name, ':');\n\t/* separator not found, or was the first or the last character */\n\tif (!port_sep || port_sep == dest_name || port_sep == dest_name + strlen(dest_name) - 1) {\n\t\tLOG_ERROR(\"apptrace: Invalid connection URI, format should be tcp://host:port\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tsize_t hostname_len = port_sep - dest_name;\n\n\tchar hostname[64] = { 0 };\n\tif (hostname_len >= sizeof(hostname)) {\n\t\tLOG_ERROR(\"apptrace: Hostname too long\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tmemcpy(hostname, dest_name, hostname_len);\n\n\tconst char *port_str = port_sep + 1;\n\tstruct addrinfo *ai;\n\tint flags = 0;\n#ifdef AI_NUMERICSERV\n\tflags |= AI_NUMERICSERV;\n#endif\t/* AI_NUMERICSERV */\n\tstruct addrinfo hint = {\n\t\t.ai_family = AF_UNSPEC,\n\t\t.ai_socktype = SOCK_STREAM,\n\t\t.ai_protocol = 0,\n\t\t.ai_flags = flags\n\t};\n\tint res = getaddrinfo(hostname, port_str, &hint, &ai);\n\tif (res != 0) {\n\t\tLOG_ERROR(\"apptrace: Failed to resolve host name: %s\", hostname);\n\t\treturn ERROR_FAIL;\n\t}\n\tint sockfd = -1;\n\tfor (struct addrinfo *ai_it = ai; ai_it; ai_it = ai_it->ai_next) {\n\t\tsockfd = socket(ai_it->ai_family, ai_it->ai_socktype, ai_it->ai_protocol);\n\t\tif (sockfd < 0) {\n\t\t\tLOG_DEBUG(\"apptrace: Failed to create socket (%d, %d, %d) (%s)\",\n\t\t\t\tai_it->ai_family,\n\t\t\t\tai_it->ai_socktype,\n\t\t\t\tai_it->ai_protocol,\n\t\t\t\tstrerror(errno));\n\t\t\tcontinue;\n\t\t}\n\n\t\tchar cur_hostname[NI_MAXHOST];\n\t\tchar cur_portname[NI_MAXSERV];\n\t\tres =\n\t\t\tgetnameinfo(ai_it->ai_addr, ai_it->ai_addrlen, cur_hostname,\n\t\t\tsizeof(cur_hostname),\n\t\t\tcur_portname, sizeof(cur_portname),\n\t\t\tNI_NUMERICHOST | NI_NUMERICSERV);\n\t\tif (res != 0)\n\t\t\tcontinue;\n\n\t\tLOG_INFO(\"apptrace: Trying to connect to %s:%s\", cur_hostname, cur_portname);\n\t\tif (connect(sockfd, ai_it->ai_addr, ai_it->ai_addrlen) < 0) {\n\t\t\tclose_socket(sockfd);\n\t\t\tsockfd = -1;\n\t\t\tLOG_WARNING(\"apptrace: Connection failed (%s)\", strerror(errno));\n\t\t\tcontinue;\n\t\t}\n\t\tbreak;\n\t}\n\tfreeaddrinfo(ai);\n\tif (sockfd < 0) {\n\t\tLOG_ERROR(\"apptrace: Could not connect to %s:%s\", hostname, port_str);\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_INFO(\"apptrace: Connected!\");\n\n\tstruct esp32_apptrace_dest_tcp_data *dest_data = calloc(1, sizeof(struct esp32_apptrace_dest_tcp_data));\n\tif (!dest_data) {\n\t\tLOG_ERROR(\"apptrace: Failed to alloc mem for tcp dest!\");\n\t\tclose_socket(sockfd);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdest_data->sockfd = sockfd;\n\tdest->priv = dest_data;\n\tdest->write = esp32_apptrace_tcp_dest_write;\n\tdest->clean = esp32_apptrace_tcp_dest_cleanup;\n\tdest->log_progress = true;\n\n\treturn ERROR_OK;\n}\n\nint esp32_apptrace_dest_init(struct esp32_apptrace_dest dest[], const char *dest_paths[], unsigned int max_dests)\n{\n\tint res;\n\tunsigned int i;\n\n\tfor (i = 0; i < max_dests; i++) {\n\t\tif (strncmp(dest_paths[i], \"file://\", 7) == 0)\n\t\t\tres = esp32_apptrace_file_dest_init(&dest[i], &dest_paths[i][7]);\n\t\telse if (strncmp(dest_paths[i], \"con:\", 4) == 0)\n\t\t\tres = esp32_apptrace_console_dest_init(&dest[i], NULL);\n\t\telse if (strncmp(dest_paths[i], \"tcp://\", 6) == 0)\n\t\t\tres = esp32_apptrace_tcp_dest_init(&dest[i], &dest_paths[i][6]);\n\t\telse\n\t\t\tbreak;\n\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"apptrace: Failed to init trace data destination '%s'!\", dest_paths[i]);\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn i;\n}\n\nint esp32_apptrace_dest_cleanup(struct esp32_apptrace_dest dest[], unsigned int max_dests)\n{\n\tfor (unsigned int i = 0; i < max_dests; i++) {\n\t\tif (dest[i].clean && dest[i].priv) {\n\t\t\tint res = dest[i].clean(dest[i].priv);\n\t\t\tdest[i].priv = NULL;\n\t\t\treturn res;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\n/*********************************************************************\n*                 Trace data blocks management API\n**********************************************************************/\nstatic void esp32_apptrace_blocks_pool_cleanup(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tstruct esp32_apptrace_block *cur;\n\tstruct list_head *head = &ctx->free_trace_blocks;\n\tstruct list_head *tmp, *pos;\n\n\tlist_for_each_safe(pos, tmp, head) {\n\t\tcur = list_entry(pos, struct esp32_apptrace_block, node);\n\t\tif (cur) {\n\t\t\tlist_del(&cur->node);\n\t\t\tfree(cur->data);\n\t\t\tfree(cur);\n\t\t}\n\t}\n\n\thead = &ctx->ready_trace_blocks;\n\n\tlist_for_each_safe(pos, tmp, head) {\n\t\tcur = list_entry(pos, struct esp32_apptrace_block, node);\n\t\tif (cur) {\n\t\t\tlist_del(&cur->node);\n\t\t\tfree(cur->data);\n\t\t\tfree(cur);\n\t\t}\n\t}\n}\n\nstruct esp32_apptrace_block *esp32_apptrace_free_block_get(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tstruct esp32_apptrace_block *block = NULL;\n\n\tif (!list_empty(&ctx->free_trace_blocks)) {\n\t\t/*get first */\n\t\tblock = list_first_entry(&ctx->free_trace_blocks, struct esp32_apptrace_block, node);\n\t\tlist_del(&block->node);\n\t}\n\n\treturn block;\n}\n\nstatic int esp32_apptrace_ready_block_put(struct esp32_apptrace_cmd_ctx *ctx, struct esp32_apptrace_block *block)\n{\n\tLOG_DEBUG(\"esp32_apptrace_ready_block_put\");\n\t/* add to ready blocks list */\n\tINIT_LIST_HEAD(&block->node);\n\tlist_add(&block->node, &ctx->ready_trace_blocks);\n\n\treturn ERROR_OK;\n}\n\nstatic struct esp32_apptrace_block *esp32_apptrace_ready_block_get(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tif (list_empty(&ctx->ready_trace_blocks))\n\t\treturn NULL;\n\n\tstruct esp32_apptrace_block *block =\n\t\tlist_last_entry(&ctx->ready_trace_blocks, struct esp32_apptrace_block, node);\n\n\t/* remove it from ready list */\n\tlist_del(&block->node);\n\n\treturn block;\n}\n\nstatic int esp32_apptrace_block_free(struct esp32_apptrace_cmd_ctx *ctx, struct esp32_apptrace_block *block)\n{\n\t/* add to free blocks list */\n\tINIT_LIST_HEAD(&block->node);\n\tlist_add(&block->node, &ctx->free_trace_blocks);\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_wait_tracing_finished(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tint64_t timeout = timeval_ms() + (LOG_LEVEL_IS(LOG_LVL_DEBUG) ? 70000 : 5000);\n\twhile (!list_empty(&ctx->ready_trace_blocks)) {\n\t\talive_sleep(100);\n\t\tif (timeval_ms() >= timeout) {\n\t\t\tLOG_ERROR(\"Failed to wait for pended trace blocks!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\t/* signal timer callback to stop */\n\tctx->running = 0;\n\ttarget_unregister_timer_callback(esp32_apptrace_data_processor, ctx);\n\treturn ERROR_OK;\n}\n\n/*********************************************************************\n*                          Trace commands\n**********************************************************************/\n\nint esp32_apptrace_cmd_ctx_init(struct esp32_apptrace_cmd_ctx *cmd_ctx, struct command_invocation *cmd, int mode)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tmemset(cmd_ctx, 0, sizeof(struct esp32_apptrace_cmd_ctx));\n\tcmd_ctx->target = target;\n\tcmd_ctx->mode = mode;\n\tcmd_ctx->target_state = target->state;\n\tcmd_ctx->cmd = cmd;\n\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tunsigned int i = 0;\n\t\tcmd_ctx->cores_num = 0;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tif (i == ESP32_APPTRACE_MAX_CORES_NUM) {\n\t\t\t\tcommand_print(cmd, \"Too many cores configured! Max %d cores are supported.\",\n\t\t\t\t\tESP32_APPTRACE_MAX_CORES_NUM);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (!target_was_examined(curr))\n\t\t\t\tcontinue;\n\t\t\tcmd_ctx->cores_num++;\n\t\t\tcmd_ctx->cpus[i++] = curr;\n\t\t}\n\t} else {\n\t\tcmd_ctx->cores_num = 1;\n\t\tcmd_ctx->cpus[0] = target;\n\t}\n\t/* some relies on ESP32_APPTRACE_MAX_CORES_NUM\n\t * TODO: remove that dependency */\n\tassert(cmd_ctx->cores_num <= ESP32_APPTRACE_MAX_CORES_NUM && \"Too many cores number!\");\n\n\tstruct xtensa *xtensa = target->arch_info;\n\tif (xtensa->common_magic == XTENSA_COMMON_MAGIC) {\n\t\tcmd_ctx->hw = target_to_esp_xtensa(target)->apptrace.hw;\n\t} else { /* TODO: riscv is not supported yet */\n\t\tcommand_print(cmd, \"Unsupported target arch 0x%X\", xtensa->common_magic);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcmd_ctx->max_trace_block_sz = cmd_ctx->hw->max_block_size_get(cmd_ctx->cpus[0]);\n\tif (cmd_ctx->max_trace_block_sz == 0) {\n\t\tcommand_print(cmd, \"Failed to get max trace block size!\");\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_INFO(\"Total trace memory: %\" PRIu32 \" bytes\", cmd_ctx->max_trace_block_sz);\n\n\tINIT_LIST_HEAD(&cmd_ctx->ready_trace_blocks);\n\tINIT_LIST_HEAD(&cmd_ctx->free_trace_blocks);\n\tfor (unsigned int i = 0; i < ESP_APPTRACE_BLOCKS_POOL_SZ; i++) {\n\t\tstruct esp32_apptrace_block *block = calloc(1, sizeof(struct esp32_apptrace_block));\n\t\tif (!block) {\n\t\t\tcommand_print(cmd, \"Failed to alloc trace buffer entry!\");\n\t\t\tesp32_apptrace_blocks_pool_cleanup(cmd_ctx);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tblock->data = malloc(cmd_ctx->max_trace_block_sz);\n\t\tif (!block->data) {\n\t\t\tfree(block);\n\t\t\tcommand_print(cmd, \"Failed to alloc trace buffer %\" PRIu32 \" bytes!\", cmd_ctx->max_trace_block_sz);\n\t\t\tesp32_apptrace_blocks_pool_cleanup(cmd_ctx);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tINIT_LIST_HEAD(&block->node);\n\t\tlist_add(&block->node, &cmd_ctx->free_trace_blocks);\n\t}\n\n\tcmd_ctx->running = 1;\n\tif (cmd_ctx->mode != ESP_APPTRACE_CMD_MODE_SYNC) {\n\t\tint res = target_register_timer_callback(esp32_apptrace_data_processor,\n\t\t\t0,\n\t\t\tTARGET_TIMER_TYPE_PERIODIC,\n\t\t\tcmd_ctx);\n\t\tif (res != ERROR_OK) {\n\t\t\tcommand_print(cmd, \"Failed to start trace data timer callback (%d)!\", res);\n\t\t\tesp32_apptrace_blocks_pool_cleanup(cmd_ctx);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (s_time_stats_enable) {\n\t\tcmd_ctx->stats.min_blk_read_time = 1000000.0;\n\t\tcmd_ctx->stats.min_blk_proc_time = 1000000.0;\n\t}\n\tif (duration_start(&cmd_ctx->idle_time) != 0) {\n\t\tcommand_print(cmd, \"Failed to start idle time measurement!\");\n\t\tesp32_apptrace_cmd_ctx_cleanup(cmd_ctx);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint esp32_apptrace_cmd_ctx_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx)\n{\n\tesp32_apptrace_blocks_pool_cleanup(cmd_ctx);\n\treturn ERROR_OK;\n}\n\n#define ESP32_APPTRACE_CMD_NUM_ARG_CHECK(_cmd_, _arg_, _start_, _end_)\t   \\\n\tdo { \\\n\t\tif ((_arg_) == 0 && (_start_) == (_end_)) { \\\n\t\t\tcommand_print(_cmd_, \"Invalid '\" # _arg_ \"' arg!\"); \\\n\t\t\treturn;\t\\\n\t\t} \\\n\t} while (0)\n\nvoid esp32_apptrace_cmd_args_parse(struct esp32_apptrace_cmd_ctx *cmd_ctx,\n\tstruct esp32_apptrace_cmd_data *cmd_data,\n\tconst char **argv,\n\tint argc)\n{\n\tchar *end;\n\n\tcmd_data->poll_period = strtoul(argv[0], &end, 10);\n\tESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->poll_period, argv[0], end);\n\tif (argc > 1) {\n\t\tcmd_data->max_len = strtoul(argv[1], &end, 10);\n\t\tESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->max_len, argv[1], end);\n\t\tif (argc > 2) {\n\t\t\tint32_t tmo = strtol(argv[2], &end, 10);\n\t\t\tESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, tmo, argv[2], end);\n\t\t\tcmd_ctx->stop_tmo = 1.0 * tmo;\n\t\t\tif (argc > 3) {\n\t\t\t\tcmd_data->wait4halt = strtoul(argv[3], &end, 10);\n\t\t\t\tESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->wait4halt, argv[3], end);\n\t\t\t\tif (argc > 4) {\n\t\t\t\t\tcmd_data->skip_len = strtoul(argv[4], &end, 10);\n\t\t\t\t\tESP32_APPTRACE_CMD_NUM_ARG_CHECK(cmd_ctx->cmd, cmd_data->skip_len, argv[4], end);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic int esp32_apptrace_core_id_get(struct target *target, uint8_t *hdr_buf)\n{\n\treturn ESP32_APPTRACE_USER_BLOCK_CORE(target_buffer_get_u16(target, hdr_buf + APPTRACE_BLOCK_SIZE_OFFSET));\n}\n\nstatic uint32_t esp32_apptrace_usr_block_len_get(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len)\n{\n\t*wr_len = ESP32_APPTRACE_USER_BLOCK_LEN(target_buffer_get_u16(target, hdr_buf + APPTRACE_WR_SIZE_OFFSET));\n\treturn ESP32_APPTRACE_USER_BLOCK_LEN(target_buffer_get_u16(target, hdr_buf + APPTRACE_BLOCK_SIZE_OFFSET));\n}\n\nstatic int esp32_apptrace_cmd_init(struct esp32_apptrace_cmd_ctx *cmd_ctx,\n\tstruct command_invocation *cmd,\n\tint mode,\n\tconst char **argv,\n\tint argc)\n{\n\tstruct esp32_apptrace_cmd_data *cmd_data;\n\n\tif (argc < 1) {\n\t\tcommand_print(cmd, \"Not enough args! Need trace data destination!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint res = esp32_apptrace_cmd_ctx_init(cmd_ctx, cmd, mode);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tcmd_data = calloc(1, sizeof(*cmd_data));\n\tassert(cmd_data && \"No memory for command data!\");\n\tcmd_ctx->cmd_priv = cmd_data;\n\n\t/*outfile1 [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]] */\n\tres = esp32_apptrace_dest_init(&cmd_data->data_dest, argv, 1);\n\tif (res != 1) {\t/* only one destination needs to be initialized */\n\t\tcommand_print(cmd, \"Wrong args! Needs a trace data destination!\");\n\t\tfree(cmd_data);\n\t\tgoto on_error;\n\t}\n\tcmd_ctx->stop_tmo = -1.0;\t/* infinite */\n\tcmd_data->max_len = UINT32_MAX;\n\tcmd_data->poll_period = 0 /*ms*/;\n\tif (argc > 1)\n\t\t/* parse remaining args */\n\t\tesp32_apptrace_cmd_args_parse(cmd_ctx, cmd_data, &argv[1], argc - 1);\n\n\tLOG_USER(\"App trace params: from %d cores, size %\" PRId32 \" bytes, stop_tmo %g s, poll period %\" PRId32\n\t\t\" ms, wait_rst %d, skip %\" PRId32 \" bytes\", cmd_ctx->cores_num,\n\t\tcmd_data->max_len,\n\t\tcmd_ctx->stop_tmo,\n\t\tcmd_data->poll_period,\n\t\tcmd_data->wait4halt,\n\t\tcmd_data->skip_len);\n\n\tcmd_ctx->trace_format.hdr_sz = ESP32_APPTRACE_USER_BLOCK_HDR_SZ;\n\tcmd_ctx->trace_format.core_id_get = esp32_apptrace_core_id_get;\n\tcmd_ctx->trace_format.usr_block_len_get = esp32_apptrace_usr_block_len_get;\n\treturn ERROR_OK;\non_error:\n\tcommand_print(cmd, \"Not enough args! Need %d trace data destinations!\", cmd_ctx->cores_num);\n\tcmd_ctx->running = 0;\n\tesp32_apptrace_cmd_ctx_cleanup(cmd_ctx);\n\treturn res;\n}\n\nstatic int esp32_apptrace_cmd_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx)\n{\n\tstruct esp32_apptrace_cmd_data *cmd_data = cmd_ctx->cmd_priv;\n\n\tesp32_apptrace_dest_cleanup(&cmd_data->data_dest, 1);\n\tfree(cmd_data);\n\tcmd_ctx->cmd_priv = NULL;\n\tesp32_apptrace_cmd_ctx_cleanup(cmd_ctx);\n\treturn ERROR_OK;\n}\n\nstatic void esp32_apptrace_print_stats(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tstruct esp32_apptrace_cmd_data *cmd_data = ctx->cmd_priv;\n\tuint32_t trace_sz = 0;\n\n\tif (cmd_data)\n\t\ttrace_sz = ctx->tot_len > cmd_data->skip_len ? ctx->tot_len - cmd_data->skip_len : 0;\n\tLOG_USER(\"Tracing is %s. Size is %\" PRId32 \" of %\" PRId32 \" @ %f (%f) KiB/s\",\n\t\t!ctx->running ? \"STOPPED\" : \"RUNNING\",\n\t\ttrace_sz,\n\t\tcmd_data ? cmd_data->max_len : 0,\n\t\tduration_kbps(&ctx->read_time, ctx->tot_len),\n\t\tduration_kbps(&ctx->read_time, ctx->raw_tot_len));\n\tLOG_USER(\"Data: blocks incomplete %\" PRId32 \", lost bytes: %\" PRId32,\n\t\tctx->stats.incompl_blocks,\n\t\tctx->stats.lost_bytes);\n\tif (s_time_stats_enable) {\n\t\tLOG_USER(\"Block read time [%f..%f] ms\",\n\t\t\t1000 * ctx->stats.min_blk_read_time,\n\t\t\t1000 * ctx->stats.max_blk_read_time);\n\t\tLOG_USER(\"Block proc time [%f..%f] ms\",\n\t\t\t1000 * ctx->stats.min_blk_proc_time,\n\t\t\t1000 * ctx->stats.max_blk_proc_time);\n\t}\n}\n\nstatic int esp32_apptrace_wait4halt(struct esp32_apptrace_cmd_ctx *ctx, struct target *target)\n{\n\tLOG_USER(\"Wait for halt...\");\n\twhile (!openocd_is_shutdown_pending()) {\n\t\tint res = target_poll(target);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\tif (target->state == TARGET_HALTED) {\n\t\t\tLOG_USER(\"%s: HALTED\", target->cmd_name);\n\t\t\tbreak;\n\t\t}\n\t\talive_sleep(500);\n\t}\n\treturn ERROR_OK;\n}\n\nint esp32_apptrace_safe_halt_targets(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_target_state *targets)\n{\n\tint res = ERROR_OK;\n\n\tmemset(targets, 0, ctx->cores_num * sizeof(struct esp32_apptrace_target_state));\n\t/* halt all CPUs */\n\tLOG_DEBUG(\"Halt all targets!\");\n\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\tif (!target_was_examined(ctx->cpus[k]))\n\t\t\tcontinue;\n\t\tif (ctx->cpus[k]->state == TARGET_HALTED)\n\t\t\tcontinue;\n\t\tres = target_halt(ctx->cpus[k]);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to halt target (%d)!\", res);\n\t\t\treturn res;\n\t\t}\n\t\tres = target_wait_state(ctx->cpus[k], TARGET_HALTED, ESP32_APPTRACE_TGT_STATE_TMO);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to wait halt target %s / %d (%d)!\",\n\t\t\t\ttarget_name(ctx->cpus[k]),\n\t\t\t\tctx->cpus[k]->state,\n\t\t\t\tres);\n\t\t\treturn res;\n\t\t}\n\t}\n\t/* read current block statuses from CPUs */\n\tLOG_DEBUG(\"Read current block statuses\");\n\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\tuint32_t stat;\n\t\tres = ctx->hw->status_reg_read(ctx->cpus[k], &stat);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read trace status (%d)!\", res);\n\t\t\treturn res;\n\t\t}\n\t\t/* check if some CPU stopped inside tracing regs update critical section */\n\t\tif (stat) {\n\t\t\tif (ctx->hw->leave_trace_crit_section_start) {\n\t\t\t\tres = ctx->hw->leave_trace_crit_section_start(ctx->cpus[k]);\n\t\t\t\tif (res != ERROR_OK)\n\t\t\t\t\treturn res;\n\t\t\t}\n\t\t\tuint32_t bp_addr = stat;\n\t\t\tres = breakpoint_add(ctx->cpus[k], bp_addr, 1, BKPT_HARD);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to set breakpoint (%d)!\", res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\twhile (stat) {\n\t\t\t\t/* allow this CPU to leave ERI write critical section */\n\t\t\t\tres = target_resume(ctx->cpus[k], 1, 0, 1, 0);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Failed to resume target (%d)!\", res);\n\t\t\t\t\tbreakpoint_remove(ctx->cpus[k], bp_addr);\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\t/* wait for CPU to be halted on BP */\n\t\t\t\tenum target_debug_reason debug_reason = DBG_REASON_UNDEFINED;\n\t\t\t\twhile (debug_reason != DBG_REASON_BREAKPOINT) {\n\t\t\t\t\tres = target_wait_state(ctx->cpus[k], TARGET_HALTED,\n\t\t\t\t\t\tESP32_APPTRACE_TGT_STATE_TMO);\n\t\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"Failed to wait halt on bp (%d)!\", res);\n\t\t\t\t\t\tbreakpoint_remove(ctx->cpus[k], bp_addr);\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t}\n\t\t\t\t\tdebug_reason = ctx->cpus[k]->debug_reason;\n\t\t\t\t}\n\t\t\t\tres = ctx->hw->status_reg_read(ctx->cpus[k], &stat);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Failed to read trace status (%d)!\", res);\n\t\t\t\t\tbreakpoint_remove(ctx->cpus[k], bp_addr);\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreakpoint_remove(ctx->cpus[k], bp_addr);\n\t\t\tif (ctx->hw->leave_trace_crit_section_stop) {\n\t\t\t\tres = ctx->hw->leave_trace_crit_section_stop(ctx->cpus[k]);\n\t\t\t\tif (res != ERROR_OK)\n\t\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t\tres = ctx->hw->data_len_read(ctx->cpus[k], &targets[k].block_id, &targets[k].data_len);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read trace status (%d)!\", res);\n\t\t\treturn res;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_connect_targets(struct esp32_apptrace_cmd_ctx *ctx,\n\tbool conn,\n\tbool resume_target)\n{\n\tstruct esp32_apptrace_target_state target_to_connect[ESP32_APPTRACE_MAX_CORES_NUM];\n\n\tif (conn)\n\t\tLOG_USER(\"Connect targets...\");\n\telse\n\t\tLOG_USER(\"Disconnect targets...\");\n\n\tint res = esp32_apptrace_safe_halt_targets(ctx, target_to_connect);\n\tif (res != ERROR_OK) {\n\t\tcommand_print(ctx->cmd, \"Failed to halt targets (%d)!\", res);\n\t\treturn res;\n\t}\n\tif (ctx->cores_num > 1) {\n\t\t/* set block ids to the highest value */\n\t\tuint32_t max_id = 0;\n\t\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\t\tif (target_to_connect[k].block_id > max_id)\n\t\t\t\tmax_id = target_to_connect[k].block_id;\n\t\t}\n\t\tfor (unsigned int k = 0; k < ctx->cores_num; k++)\n\t\t\ttarget_to_connect[k].block_id = max_id;\n\t}\n\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\t/* update host connected status */\n\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[k],\n\t\t\ttarget_to_connect[k].block_id,\n\t\t\t0 /*ack target data*/,\n\t\t\tconn,\n\t\t\tfalse /*no host data*/);\n\t\tif (res != ERROR_OK) {\n\t\t\tcommand_print(ctx->cmd, \"Failed to read trace status (%d)!\", res);\n\t\t\treturn res;\n\t\t}\n\t}\n\tif (resume_target) {\n\t\tLOG_DEBUG(\"Resume targets\");\n\t\tbool smp_resumed = false;\n\t\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\t\tif (smp_resumed && ctx->cpus[k]->smp) {\n\t\t\t\t/* in SMP mode we need to call target_resume for one core only */\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tres = target_resume(ctx->cpus[k], 1, 0, 1, 0);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tcommand_print(ctx->cmd, \"Failed to resume target (%d)!\", res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tif (ctx->cpus[k]->smp)\n\t\t\t\tsmp_resumed = true;\n\t\t}\n\t}\n\tif (conn)\n\t\tLOG_INFO(\"Targets connected.\");\n\telse\n\t\tLOG_INFO(\"Targets disconnected.\");\n\treturn ERROR_OK;\n}\n\nint esp_apptrace_usr_block_write(const struct esp32_apptrace_hw *hw, struct target *target,\n\tuint32_t block_id,\n\tconst uint8_t *data,\n\tuint32_t size)\n{\n\tstruct esp_apptrace_host2target_hdr hdr = { .block_sz = size };\n\tuint32_t buf_sz[2] = { sizeof(hdr), size };\n\tconst uint8_t *bufs[2] = { (const uint8_t *)&hdr, data };\n\n\tif (size > hw->usr_block_max_size_get(target)) {\n\t\tLOG_ERROR(\"Too large user block %\" PRId32, size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn hw->buffs_write(target,\n\t\tARRAY_SIZE(buf_sz),\n\t\tbuf_sz,\n\t\tbufs,\n\t\tblock_id,\n\t\ttrue /*ack target data*/,\n\t\ttrue /*host data*/);\n}\n\nstatic uint32_t esp32_apptrace_usr_block_check(struct esp32_apptrace_cmd_ctx *ctx, uint8_t *hdr_buf)\n{\n\tuint32_t wr_len = 0;\n\tuint32_t usr_len = ctx->trace_format.usr_block_len_get(ctx->target, hdr_buf, &wr_len);\n\tif (usr_len != wr_len) {\n\t\tLOG_ERROR(\"Incomplete block sz %\" PRId32 \", wr %\" PRId32, usr_len, wr_len);\n\t\tctx->stats.incompl_blocks++;\n\t\tctx->stats.lost_bytes += usr_len - wr_len;\n\t}\n\treturn usr_len;\n}\n\nint esp32_apptrace_get_data_info(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_target_state *target_state,\n\tuint32_t *fired_target_num)\n{\n\tif (fired_target_num)\n\t\t*fired_target_num = UINT32_MAX;\n\n\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\tint res = ctx->hw->data_len_read(ctx->cpus[i], &target_state[i].block_id, &target_state[i].data_len);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read data len on (%s)!\", target_name(ctx->cpus[i]));\n\t\t\treturn res;\n\t\t}\n\t\tif (target_state[i].data_len) {\n\t\t\tLOG_TARGET_DEBUG(ctx->cpus[i], \"Block %\" PRId32 \", len %\" PRId32 \" bytes on fired\",\n\t\t\t\ttarget_state[i].block_id, target_state[i].data_len);\n\t\t\tif (fired_target_num)\n\t\t\t\t*fired_target_num = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_process_data(struct esp32_apptrace_cmd_ctx *ctx,\n\tunsigned int core_id,\n\tuint8_t *data,\n\tuint32_t data_len)\n{\n\tstruct esp32_apptrace_cmd_data *cmd_data = ctx->cmd_priv;\n\n\tLOG_DEBUG(\"Got block %\" PRId32 \" bytes [%x %x...%x %x]\", data_len, data[12], data[13],\n\t\tdata[data_len - 2], data[data_len - 1]);\n\tif (ctx->tot_len + data_len > cmd_data->skip_len) {\n\t\tuint32_t wr_idx = 0, wr_chunk_len = data_len;\n\t\tif (ctx->tot_len < cmd_data->skip_len) {\n\t\t\twr_chunk_len = (ctx->tot_len + wr_chunk_len) - cmd_data->skip_len;\n\t\t\twr_idx = cmd_data->skip_len - ctx->tot_len;\n\t\t}\n\t\tif (ctx->tot_len + wr_chunk_len > cmd_data->max_len)\n\t\t\twr_chunk_len -= (ctx->tot_len + wr_chunk_len - cmd_data->skip_len) - cmd_data->max_len;\n\t\tif (wr_chunk_len > 0) {\n\t\t\tint res = cmd_data->data_dest.write(cmd_data->data_dest.priv, data + wr_idx, wr_chunk_len);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to write %\" PRId32 \" bytes to dest 0!\", data_len);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t\tctx->tot_len += wr_chunk_len;\n\t} else {\n\t\tctx->tot_len += data_len;\n\t}\n\n\tif (cmd_data->data_dest.log_progress)\n\t\tLOG_USER(\"%\" PRId32 \" \", ctx->tot_len);\n\t/* check for stop condition */\n\tif (ctx->tot_len > cmd_data->skip_len && (ctx->tot_len - cmd_data->skip_len >= cmd_data->max_len)) {\n\t\tctx->running = 0;\n\t\tif (duration_measure(&ctx->read_time) != 0) {\n\t\t\tLOG_ERROR(\"Failed to stop trace read time measure!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_handle_trace_block(struct esp32_apptrace_cmd_ctx *ctx,\n\tstruct esp32_apptrace_block *block)\n{\n\tuint32_t processed = 0;\n\tuint32_t hdr_sz = ctx->trace_format.hdr_sz;\n\n\tLOG_DEBUG(\"Got block %\" PRId32 \" bytes\", block->data_len);\n\t/* process user blocks one by one */\n\twhile (processed < block->data_len) {\n\t\tLOG_DEBUG(\"Process usr block %\" PRId32 \"/%\" PRId32, processed, block->data_len);\n\t\t/* process user block */\n\t\tuint32_t usr_len = esp32_apptrace_usr_block_check(ctx, block->data + processed);\n\t\tint core_id = ctx->trace_format.core_id_get(ctx->target, block->data + processed);\n\t\t/* process user data */\n\t\tint res = ctx->process_data(ctx, core_id, block->data + processed + hdr_sz, usr_len);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to process %\" PRId32 \" bytes!\", usr_len);\n\t\t\treturn res;\n\t\t}\n\t\tprocessed += usr_len + hdr_sz;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_data_processor(void *priv)\n{\n\tstruct esp32_apptrace_cmd_ctx *ctx = (struct esp32_apptrace_cmd_ctx *)priv;\n\n\tif (!ctx->running)\n\t\treturn ERROR_OK;\n\n\tstruct esp32_apptrace_block *block = esp32_apptrace_ready_block_get(ctx);\n\tif (!block)\n\t\treturn ERROR_OK;\n\n\tint res = esp32_apptrace_handle_trace_block(ctx, block);\n\tif (res != ERROR_OK) {\n\t\tctx->running = 0;\n\t\tLOG_ERROR(\"Failed to process trace block %\" PRId32 \" bytes!\", block->data_len);\n\t\treturn res;\n\t}\n\tres = esp32_apptrace_block_free(ctx, block);\n\tif (res != ERROR_OK) {\n\t\tctx->running = 0;\n\t\tLOG_ERROR(\"Failed to free ready block!\");\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_check_connection(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tif (!ctx)\n\t\treturn ERROR_FAIL;\n\n\tunsigned int busy_target_num = 0;\n\n\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\tbool conn = true;\n\t\tint res = ctx->hw->ctrl_reg_read(ctx->cpus[i], NULL, NULL, &conn);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read apptrace control reg for cpu(%d) res(%d)!\", i, res);\n\t\t\treturn res;\n\t\t}\n\t\tif (!conn) {\n\t\t\tuint32_t stat = 0;\n\t\t\tLOG_TARGET_WARNING(ctx->cpus[i], \"apptrace connection is lost. Re-connect.\");\n\t\t\tres = ctx->hw->status_reg_read(ctx->cpus[i], &stat);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to read trace status (%d)!\", res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tif (stat) {\n\t\t\t\tLOG_TARGET_WARNING(ctx->cpus[i], \"in critical state. Retry in next poll\");\n\t\t\t\tif (++busy_target_num == ctx->cores_num) {\n\t\t\t\t\tLOG_WARNING(\"No available core\");\n\t\t\t\t\treturn ERROR_WAIT;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[i],\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\ttrue /*host connected*/,\n\t\t\t\tfalse /*no host data*/);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to write apptrace control reg for cpu(%d) res(%d)!\", i, res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tif (ctx->stop_tmo != -1.0) {\n\t\t\t\t/* re-start idle time measurement */\n\t\t\t\tif (duration_start(&ctx->idle_time) != 0) {\n\t\t\t\t\tLOG_ERROR(\"Failed to re-start idle time measure!\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32_apptrace_poll(void *priv)\n{\n\tstruct esp32_apptrace_cmd_ctx *ctx = (struct esp32_apptrace_cmd_ctx *)priv;\n\tint res;\n\tuint32_t fired_target_num = 0;\n\tstruct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM];\n\tstruct duration blk_proc_time;\n\n\tif (!ctx->running) {\n\t\tif (ctx->auto_clean)\n\t\t\tctx->auto_clean(ctx);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/*  Check for connection is alive.For some reason target and therefore host_connected flag\n\t *  might have been reset */\n\tres = esp32_apptrace_check_connection(ctx);\n\tif (res != ERROR_OK) {\n\t\tif (res != ERROR_WAIT)\n\t\t\tctx->running = 0;\n\t\treturn res;\n\t}\n\n\t/* check for data from target */\n\tres = esp32_apptrace_get_data_info(ctx, target_state, &fired_target_num);\n\tif (res != ERROR_OK) {\n\t\tctx->running = 0;\n\t\tLOG_ERROR(\"Failed to read data len!\");\n\t\treturn res;\n\t}\n\t/* LOG_DEBUG(\"Block %d (%d bytes) on target (%s)!\", target_state[0].block_id,\n\t * target_state[0].data_len, target_name(ctx->cpus[0])); */\n\tif (fired_target_num == UINT32_MAX) {\n\t\t/* no data has been received, but block could be switched due to the data transferred\n\t\t * from host to target */\n\t\tif (ctx->cores_num > 1) {\n\t\t\tuint32_t max_block_id = 0, min_block_id = ctx->hw->max_block_id;\n\t\t\t/* find maximum block ID and set the same ID in control reg for both cores\n\t\t\t * */\n\t\t\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\t\t\tif (max_block_id < target_state[i].block_id)\n\t\t\t\t\tmax_block_id = target_state[i].block_id;\n\t\t\t\tif (min_block_id > target_state[i].block_id)\n\t\t\t\t\tmin_block_id = target_state[i].block_id;\n\t\t\t}\n\t\t\t/* handle block ID overflow */\n\t\t\tif (max_block_id == ctx->hw->max_block_id && min_block_id == 0)\n\t\t\t\tmax_block_id = 0;\n\t\t\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\t\t\tif (max_block_id != target_state[i].block_id) {\n\t\t\t\t\tLOG_TARGET_DEBUG(ctx->cpus[i], \"Ack empty block %\" PRId32 \"!\", max_block_id);\n\t\t\t\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[i],\n\t\t\t\t\t\tmax_block_id,\n\t\t\t\t\t\t0 /*all read*/,\n\t\t\t\t\t\ttrue /*host connected*/,\n\t\t\t\t\t\tfalse /*no host data*/);\n\t\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\t\tctx->running = 0;\n\t\t\t\t\t\tLOG_TARGET_ERROR(ctx->cpus[i], \"Failed to ack empty data block!\");\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tctx->last_blk_id = max_block_id;\n\t\t}\n\t\tif (ctx->stop_tmo != -1.0) {\n\t\t\tif (duration_measure(&ctx->idle_time) != 0) {\n\t\t\t\tctx->running = 0;\n\t\t\t\tLOG_ERROR(\"Failed to measure idle time!\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (duration_elapsed(&ctx->idle_time) >= ctx->stop_tmo) {\n\t\t\t\tctx->running = 0;\n\t\t\t\tLOG_ERROR(\"Data timeout!\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\treturn ERROR_OK;/* no data */\n\t}\n\t/* sanity check */\n\tif (target_state[fired_target_num].data_len > ctx->max_trace_block_sz) {\n\t\tctx->running = 0;\n\t\tLOG_ERROR(\"Too large block size %\" PRId32 \"!\", target_state[fired_target_num].data_len);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (ctx->tot_len == 0) {\n\t\tif (duration_start(&ctx->read_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to start trace read time measurement!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\tstruct esp32_apptrace_block *block = esp32_apptrace_free_block_get(ctx);\n\tif (!block) {\n\t\tctx->running = 0;\n\t\tLOG_TARGET_ERROR(ctx->cpus[fired_target_num], \"Failed to get free block for data!\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (s_time_stats_enable) {\n\t\t/* read block */\n\t\tif (duration_start(&blk_proc_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to start block read time measurement!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\tres = ctx->hw->data_read(ctx->cpus[fired_target_num], target_state[fired_target_num].data_len, block->data,\n\t\ttarget_state[fired_target_num].block_id,\n\t\t/* do not ack target data in sync mode,\n\t\t   esp32_apptrace_handle_trace_block() can write response data and will do ack thereafter */\n\t\tctx->mode != ESP_APPTRACE_CMD_MODE_SYNC);\n\tif (res != ERROR_OK) {\n\t\tctx->running = 0;\n\t\tLOG_TARGET_ERROR(ctx->cpus[fired_target_num], \"Failed to read data!\");\n\t\treturn res;\n\t}\n\tctx->last_blk_id = target_state[fired_target_num].block_id;\n\tblock->data_len = target_state[fired_target_num].data_len;\n\tctx->raw_tot_len += block->data_len;\n\tif (s_time_stats_enable) {\n\t\tif (duration_measure(&blk_proc_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to measure block read time!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\t/* update stats */\n\t\tfloat brt = duration_elapsed(&blk_proc_time);\n\t\tif (brt > ctx->stats.max_blk_read_time)\n\t\t\tctx->stats.max_blk_read_time = brt;\n\t\tif (brt < ctx->stats.min_blk_read_time)\n\t\t\tctx->stats.min_blk_read_time = brt;\n\n\t\tif (duration_start(&blk_proc_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to start block proc time measurement!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\t/* in sync mode do not ack target data on other cores, esp32_apptrace_handle_trace_block() can write response\n\t * data and will do ack thereafter */\n\tif (ctx->mode != ESP_APPTRACE_CMD_MODE_SYNC) {\n\t\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\t\tif (i == fired_target_num)\n\t\t\t\tcontinue;\n\t\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[i],\n\t\t\t\tctx->last_blk_id,\n\t\t\t\t0 /*all read*/,\n\t\t\t\ttrue /*host connected*/,\n\t\t\t\tfalse /*no host data*/);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tctx->running = 0;\n\t\t\t\tLOG_TARGET_ERROR(ctx->cpus[i], \"Failed to ack data!\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tLOG_TARGET_DEBUG(ctx->cpus[i], \"Ack block %\" PRId32, ctx->last_blk_id);\n\t\t}\n\t\tres = esp32_apptrace_ready_block_put(ctx, block);\n\t\tif (res != ERROR_OK) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_TARGET_ERROR(ctx->cpus[fired_target_num], \"Failed to put ready block of data!\");\n\t\t\treturn res;\n\t\t}\n\t} else {\n\t\tres = esp32_apptrace_handle_trace_block(ctx, block);\n\t\tif (res != ERROR_OK) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to process trace block %\" PRId32 \" bytes!\", block->data_len);\n\t\t\treturn res;\n\t\t}\n\t\tres = esp32_apptrace_block_free(ctx, block);\n\t\tif (res != ERROR_OK) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to free ready block!\");\n\t\t\treturn res;\n\t\t}\n\t}\n\tif (ctx->stop_tmo != -1.0) {\n\t\t/* start idle time measurement */\n\t\tif (duration_start(&ctx->idle_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to start idle time measure!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\tif (s_time_stats_enable) {\n\t\tif (duration_measure(&blk_proc_time) != 0) {\n\t\t\tctx->running = 0;\n\t\t\tLOG_ERROR(\"Failed to stop block proc time measure!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\t/* update stats */\n\t\tfloat bt = duration_elapsed(&blk_proc_time);\n\t\tif (bt > ctx->stats.max_blk_proc_time)\n\t\t\tctx->stats.max_blk_proc_time = bt;\n\t\tif (bt < ctx->stats.min_blk_proc_time)\n\t\t\tctx->stats.min_blk_proc_time = bt;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic inline bool is_sysview_mode(int mode)\n{\n\treturn mode == ESP_APPTRACE_CMD_MODE_SYSVIEW || mode ==\tESP_APPTRACE_CMD_MODE_SYSVIEW_MCORE;\n}\n\nstatic void esp32_apptrace_cmd_stop(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tif (duration_measure(&ctx->read_time) != 0)\n\t\tLOG_ERROR(\"Failed to stop trace read time measurement!\");\n\tint res = target_unregister_timer_callback(esp32_apptrace_poll, ctx);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to unregister target timer handler (%d)!\", res);\n\tif (is_sysview_mode(ctx->mode)) {\n\t\t/* stop tracing */\n\t\tres = esp32_sysview_stop(ctx);\n\t\tif (res != ERROR_OK)\n\t\t\tLOG_ERROR(\"sysview: Failed to stop tracing!\");\n\t}\n\t/* data processor is alive, so wait for all received blocks to be processed */\n\tres = esp32_apptrace_wait_tracing_finished(ctx);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to wait for pended blocks (%d)!\", res);\n\tres = esp32_apptrace_connect_targets(ctx, false, ctx->target_state == TARGET_RUNNING);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to disconnect targets (%d)!\", res);\n\tesp32_apptrace_print_stats(ctx);\n\tres = esp32_apptrace_cmd_cleanup(ctx);\n\tif (res != ERROR_OK)\n\t\tLOG_ERROR(\"Failed to cleanup cmd ctx (%d)!\", res);\n}\n\n/* this function must be called after connecting to targets */\nstatic int esp32_sysview_start(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tuint8_t cmds[] = { SEGGER_SYSVIEW_COMMAND_ID_START };\n\tuint32_t fired_target_num = 0;\n\tstruct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM] = {{0}};\n\tstruct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv;\n\n\t/* get current block id */\n\tint res = esp32_apptrace_get_data_info(ctx, target_state, &fired_target_num);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"sysview: Failed to read target data info!\");\n\t\treturn res;\n\t}\n\tif (fired_target_num == UINT32_MAX) {\n\t\t/* it can happen that there is no pending target data, but block was switched\n\t\t * in this case block_ids on both CPUs are equal, so select the first one */\n\t\tfired_target_num = 0;\n\t}\n\t/* start tracing */\n\tres = esp_apptrace_usr_block_write(ctx->hw, ctx->cpus[fired_target_num], target_state[fired_target_num].block_id,\n\t\tcmds, sizeof(cmds));\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"sysview: Failed to start tracing!\");\n\t\treturn res;\n\t}\n\tcmd_data->sv_trace_running = 1;\n\treturn res;\n}\n\nstatic int esp32_sysview_stop(struct esp32_apptrace_cmd_ctx *ctx)\n{\n\tuint32_t old_block_id, fired_target_num = 0, empty_target_num = 0;\n\tstruct esp32_apptrace_target_state target_state[ESP32_APPTRACE_MAX_CORES_NUM];\n\tstruct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv;\n\tuint8_t cmds[] = { SEGGER_SYSVIEW_COMMAND_ID_STOP };\n\tstruct duration wait_time;\n\n\tstruct esp32_apptrace_block *block = esp32_apptrace_free_block_get(ctx);\n\tif (!block) {\n\t\tLOG_ERROR(\"Failed to get free block for data on (%s)!\", target_name(ctx->cpus[fired_target_num]));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* halt all CPUs (not only one), otherwise it can happen that there is no target data and\n\t * while we are queueing commands another CPU switches tracing block */\n\tint res = esp32_apptrace_safe_halt_targets(ctx, target_state);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"sysview: Failed to halt targets (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* it can happen that there is no pending target data\n\t * in this case block_ids on both CPUs are equal, so the first one will be selected */\n\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\tif (target_state[k].data_len) {\n\t\t\tfired_target_num = k;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (target_state[fired_target_num].data_len) {\n\t\t/* read pending data without ack, they will be acked when stop command is queued */\n\t\tres = ctx->hw->data_read(ctx->cpus[fired_target_num], target_state[fired_target_num].data_len, block->data,\n\t\t\ttarget_state[fired_target_num].block_id,\n\t\t\tfalse /*no ack target data*/);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to read data on (%s)!\", target_name(ctx->cpus[fired_target_num]));\n\t\t\treturn res;\n\t\t}\n\t\t/* process data */\n\t\tblock->data_len = target_state[fired_target_num].data_len;\n\t\tres = esp32_apptrace_handle_trace_block(ctx, block);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to process trace block %\" PRId32 \" bytes!\", block->data_len);\n\t\t\treturn res;\n\t\t}\n\t}\n\t/* stop tracing and ack target data */\n\tres = esp_apptrace_usr_block_write(ctx->hw, ctx->cpus[fired_target_num], target_state[fired_target_num].block_id,\n\t\tcmds,\n\t\tsizeof(cmds));\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"sysview: Failed to stop tracing!\");\n\t\treturn res;\n\t}\n\tif (ctx->cores_num > 1) {\n\t\tempty_target_num = fired_target_num ? 0 : 1;\n\t\t/* ack target data on another CPU */\n\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[empty_target_num], target_state[fired_target_num].block_id,\n\t\t\t0 /*target data ack*/,\n\t\t\ttrue /*host connected*/,\n\t\t\tfalse /*no host data*/);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to ack data on target '%s' (%d)!\",\n\t\t\t\ttarget_name(ctx->cpus[empty_target_num]), res);\n\t\t\treturn res;\n\t\t}\n\t}\n\t/* resume targets to allow command processing */\n\tLOG_INFO(\"Resume targets\");\n\tbool smp_resumed = false;\n\tfor (unsigned int k = 0; k < ctx->cores_num; k++) {\n\t\tif (smp_resumed && ctx->cpus[k]->smp) {\n\t\t\t/* in SMP mode we need to call target_resume for one core only */\n\t\t\tcontinue;\n\t\t}\n\t\tres = target_resume(ctx->cpus[k], 1, 0, 1, 0);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to resume target '%s' (%d)!\", target_name(ctx->cpus[k]), res);\n\t\t\treturn res;\n\t\t}\n\t\tif (ctx->cpus[k]->smp)\n\t\t\tsmp_resumed = true;\n\t}\n\t/* wait for block switch (command sent), so we can disconnect from targets */\n\told_block_id = target_state[fired_target_num].block_id;\n\tif (duration_start(&wait_time) != 0) {\n\t\tLOG_ERROR(\"Failed to start trace stop timeout measurement!\");\n\t\treturn ERROR_FAIL;\n\t}\n\t/* we are waiting for the last data from tracing block and also there can be data in the pended\n\t * data buffer */\n\t/* so we are expecting two TRX block switches at most or stopping due to timeout */\n\twhile (cmd_data->sv_trace_running) {\n\t\tres = esp32_apptrace_get_data_info(ctx, target_state, &fired_target_num);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to read targets data info!\");\n\t\t\treturn res;\n\t\t}\n\t\tif (fired_target_num == UINT32_MAX) {\n\t\t\t/* it can happen that there is no pending (last) target data, but block was\n\t\t\t * switched */\n\t\t\t/* in this case block_ids on both CPUs are equal, so select the first one */\n\t\t\tfired_target_num = 0;\n\t\t}\n\t\tif (target_state[fired_target_num].block_id != old_block_id) {\n\t\t\tif (target_state[fired_target_num].data_len) {\n\t\t\t\t/* read last data and ack them */\n\t\t\t\tres = ctx->hw->data_read(ctx->cpus[fired_target_num],\n\t\t\t\t\ttarget_state[fired_target_num].data_len,\n\t\t\t\t\tblock->data,\n\t\t\t\t\ttarget_state[fired_target_num].block_id,\n\t\t\t\t\ttrue /*ack target data*/);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"sysview: Failed to read last data on (%s)!\", target_name(ctx->cpus[fired_target_num]));\n\t\t\t\t} else {\n\t\t\t\t\tif (ctx->cores_num > 1) {\n\t\t\t\t\t\t/* ack target data on another CPU */\n\t\t\t\t\t\tempty_target_num = fired_target_num ? 0 : 1;\n\t\t\t\t\t\tres = ctx->hw->ctrl_reg_write(ctx->cpus[empty_target_num],\n\t\t\t\t\t\t\ttarget_state[fired_target_num].block_id,\n\t\t\t\t\t\t\t0 /*all read*/,\n\t\t\t\t\t\t\ttrue /*host connected*/,\n\t\t\t\t\t\t\tfalse /*no host data*/);\n\t\t\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\t\t\tLOG_ERROR(\"sysview: Failed to ack data on target '%s' (%d)!\",\n\t\t\t\t\t\t\t\ttarget_name(ctx->cpus[empty_target_num]), res);\n\t\t\t\t\t\t\treturn res;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t/* process data */\n\t\t\t\t\tblock->data_len = target_state[fired_target_num].data_len;\n\t\t\t\t\tres = esp32_apptrace_handle_trace_block(ctx, block);\n\t\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"Failed to process trace block %\" PRId32 \" bytes!\",\n\t\t\t\t\t\t\tblock->data_len);\n\t\t\t\t\t\treturn res;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\told_block_id = target_state[fired_target_num].block_id;\n\t\t\t}\n\t\t}\n\t\tif (duration_measure(&wait_time) != 0) {\n\t\t\tLOG_ERROR(\"Failed to start trace stop timeout measurement!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tconst float stop_tmo = LOG_LEVEL_IS(LOG_LVL_DEBUG) ? 30.0 : 0.5;\n\t\tif (duration_elapsed(&wait_time) >= stop_tmo) {\n\t\t\tLOG_INFO(\"Stop waiting for the last data due to timeout.\");\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn res;\n}\n\nstatic int esp32_cmd_apptrace_generic(struct command_invocation *cmd, int mode, const char **argv, int argc)\n{\n\tstatic struct esp32_apptrace_cmd_ctx s_at_cmd_ctx;\n\tstruct esp32_apptrace_cmd_data *cmd_data;\n\tint res = ERROR_FAIL;\n\tenum target_state old_state;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (argc < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* command can be invoked on unexamined core, if so find examined one */\n\tif (target->smp && !target_was_examined(target)) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tLOG_WARNING(\"Current target '%s' was not examined!\", target_name(target));\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tif (target_was_examined(curr)) {\n\t\t\t\ttarget = curr;\n\t\t\t\tLOG_WARNING(\"Run command on target '%s'\", target_name(target));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\told_state = target->state;\n\n\tif (strcmp(argv[0], \"start\") == 0) {\n\t\tif (is_sysview_mode(mode)) {\n\t\t\t/* init cmd context */\n\t\t\tres = esp32_sysview_cmd_init(&s_at_cmd_ctx,\n\t\t\t\tcmd,\n\t\t\t\tmode,\n\t\t\t\tmode == ESP_APPTRACE_CMD_MODE_SYSVIEW_MCORE,\n\t\t\t\t&argv[1],\n\t\t\t\targc - 1);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tcommand_print(cmd, \"Failed to init cmd ctx (%d)!\", res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tcmd_data = s_at_cmd_ctx.cmd_priv;\n\t\t\tif (cmd_data->skip_len != 0) {\n\t\t\t\ts_at_cmd_ctx.running = 0;\n\t\t\t\tesp32_sysview_cmd_cleanup(&s_at_cmd_ctx);\n\t\t\t\tcommand_print(cmd, \"Data skipping not supported!\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ts_at_cmd_ctx.process_data = esp32_sysview_process_data;\n\t\t} else {\n\t\t\tres = esp32_apptrace_cmd_init(&s_at_cmd_ctx,\n\t\t\t\tcmd,\n\t\t\t\tmode,\n\t\t\t\t&argv[1],\n\t\t\t\targc - 1);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tcommand_print(cmd, \"Failed to init cmd ctx (%d)!\", res);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tcmd_data = s_at_cmd_ctx.cmd_priv;\n\t\t\ts_at_cmd_ctx.process_data = esp32_apptrace_process_data;\n\t\t}\n\t\ts_at_cmd_ctx.auto_clean = esp32_apptrace_cmd_stop;\n\t\tif (cmd_data->wait4halt) {\n\t\t\tres = esp32_apptrace_wait4halt(&s_at_cmd_ctx, target);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tcommand_print(cmd, \"Failed to wait for halt target (%d)!\", res);\n\t\t\t\tgoto _on_start_error;\n\t\t\t}\n\t\t}\n\t\tres = esp32_apptrace_connect_targets(&s_at_cmd_ctx, true, old_state == TARGET_RUNNING);\n\t\tif (res != ERROR_OK) {\n\t\t\tcommand_print(cmd, \"Failed to connect to targets (%d)!\", res);\n\t\t\tgoto _on_start_error;\n\t\t}\n\t\tif (is_sysview_mode(mode)) {\n\t\t\t/* start tracing */\n\t\t\tres = esp32_sysview_start(&s_at_cmd_ctx);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tesp32_apptrace_connect_targets(&s_at_cmd_ctx, false, old_state == TARGET_RUNNING);\n\t\t\t\ts_at_cmd_ctx.running = 0;\n\t\t\t\tesp32_apptrace_cmd_cleanup(&s_at_cmd_ctx);\n\t\t\t\tcommand_print(cmd, \"sysview: Failed to start tracing!\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t\tres = target_register_timer_callback(esp32_apptrace_poll,\n\t\t\tcmd_data->poll_period,\n\t\t\tTARGET_TIMER_TYPE_PERIODIC,\n\t\t\t&s_at_cmd_ctx);\n\t\tif (res != ERROR_OK) {\n\t\t\tcommand_print(cmd, \"Failed to register target timer handler (%d)!\", res);\n\t\t\tgoto _on_start_error;\n\t\t}\n\t} else if (strcmp(argv[0], \"stop\") == 0) {\n\t\tif (!s_at_cmd_ctx.running) {\n\t\t\tcommand_print(cmd, \"Tracing is not running!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tesp32_apptrace_cmd_stop(&s_at_cmd_ctx);\n\t\treturn ERROR_OK;\n\t} else if (strcmp(argv[0], \"status\") == 0) {\n\t\tif (s_at_cmd_ctx.running && duration_measure(&s_at_cmd_ctx.read_time) != 0)\n\t\t\tLOG_ERROR(\"Failed to measure trace read time!\");\n\t\tesp32_apptrace_print_stats(&s_at_cmd_ctx);\n\t\treturn ERROR_OK;\n\t} else if (strcmp(argv[0], \"dump\") == 0) {\n\t\tif (is_sysview_mode(mode)) {\n\t\t\tcommand_print(cmd, \"Not supported!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\t/* [dump outfile] - post-mortem dump without connection to targets */\n\t\tres = esp32_apptrace_cmd_init(&s_at_cmd_ctx,\n\t\t\tcmd,\n\t\t\tmode,\n\t\t\t&argv[1],\n\t\t\targc - 1);\n\t\tif (res != ERROR_OK) {\n\t\t\tcommand_print(cmd, \"Failed to init cmd ctx (%d)!\", res);\n\t\t\treturn res;\n\t\t}\n\t\ts_at_cmd_ctx.stop_tmo = 0.01;\t/* use small stop tmo */\n\t\ts_at_cmd_ctx.process_data = esp32_apptrace_process_data;\n\t\t/* check for exit signal and command completion */\n\t\twhile (!openocd_is_shutdown_pending() && s_at_cmd_ctx.running) {\n\t\t\tres = esp32_apptrace_poll(&s_at_cmd_ctx);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to poll target for trace data (%d)!\", res);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* let registered timer callbacks to run */\n\t\t\ttarget_call_timer_callbacks();\n\t\t}\n\t\tif (s_at_cmd_ctx.running) {\n\t\t\t/* data processor is alive, so wait for all received blocks to be processed */\n\t\t\tres = esp32_apptrace_wait_tracing_finished(&s_at_cmd_ctx);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tLOG_ERROR(\"Failed to wait for pended blocks (%d)!\", res);\n\t\t}\n\t\tesp32_apptrace_print_stats(&s_at_cmd_ctx);\n\t\tres = esp32_apptrace_cmd_cleanup(&s_at_cmd_ctx);\n\t\tif (res != ERROR_OK)\n\t\t\tcommand_print(cmd, \"Failed to cleanup cmd ctx (%d)!\", res);\n\t} else {\n\t\tcommand_print(cmd, \"Invalid action '%s'!\", argv[0]);\n\t}\n\n\treturn res;\n\n_on_start_error:\n\ts_at_cmd_ctx.running = 0;\n\tif (is_sysview_mode(mode))\n\t\tesp32_sysview_cmd_cleanup(&s_at_cmd_ctx);\n\telse\n\t\tesp32_apptrace_cmd_cleanup(&s_at_cmd_ctx);\n\treturn res;\n}\n\nCOMMAND_HANDLER(esp32_cmd_apptrace)\n{\n\treturn esp32_cmd_apptrace_generic(CMD, ESP_APPTRACE_CMD_MODE_GEN, CMD_ARGV, CMD_ARGC);\n}\n\nCOMMAND_HANDLER(esp32_cmd_sysview)\n{\n\treturn esp32_cmd_apptrace_generic(CMD, ESP_APPTRACE_CMD_MODE_SYSVIEW, CMD_ARGV, CMD_ARGC);\n}\n\nCOMMAND_HANDLER(esp32_cmd_sysview_mcore)\n{\n\treturn esp32_cmd_apptrace_generic(CMD, ESP_APPTRACE_CMD_MODE_SYSVIEW_MCORE, CMD_ARGV, CMD_ARGC);\n}\n\nconst struct command_registration esp32_apptrace_command_handlers[] = {\n\t{\n\t\t.name = \"apptrace\",\n\t\t.handler = esp32_cmd_apptrace,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"App Tracing: application level trace control. Starts, stops or queries tracing process status.\",\n\t\t.usage =\n\t\t\t\"(start <destination> [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]) | (stop) | (status) | (dump <destination>)\",\n\t},\n\t{\n\t\t.name = \"sysview\",\n\t\t.handler = esp32_cmd_sysview,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"App Tracing: SEGGER SystemView compatible trace control. Starts, stops or queries tracing process status.\",\n\t\t.usage =\n\t\t\t\"(start file://<outfile1> [file://<outfile2>] [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]) | (stop) | (status)\",\n\t},\n\t{\n\t\t.name = \"sysview_mcore\",\n\t\t.handler = esp32_cmd_sysview_mcore,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"App Tracing: Espressif multi-core SystemView trace control. Starts, stops or queries tracing process status.\",\n\t\t.usage =\n\t\t\t\"(start file://<outfile> [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]) | (stop) | (status)\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32_apptrace.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   ESP32 application trace module                                        *\n *   Copyright (C) 2017-2019 Espressif Systems Ltd.                        *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP32_APPTRACE_H\n#define OPENOCD_TARGET_ESP32_APPTRACE_H\n\n#include <helper/command.h>\n#include <helper/time_support.h>\n#include <target/target.h>\n\n#define ESP32_APPTRACE_MAX_CORES_NUM 2\n\nstruct esp32_apptrace_hw {\n\tuint32_t max_block_id;\n\tuint32_t (*max_block_size_get)(struct target *target);\n\tint (*status_reg_read)(struct target *target, uint32_t *stat);\n\tint (*ctrl_reg_write)(struct target *target,\n\t\tuint32_t block_id,\n\t\tuint32_t len,\n\t\tbool conn,\n\t\tbool data);\n\tint (*ctrl_reg_read)(struct target *target,\n\t\tuint32_t *block_id,\n\t\tuint32_t *len,\n\t\tbool *conn);\n\tint (*data_len_read)(struct target *target,\n\t\tuint32_t *block_id,\n\t\tuint32_t *len);\n\tint (*data_read)(struct target *target,\n\t\tuint32_t size,\n\t\tuint8_t *buffer,\n\t\tuint32_t block_id,\n\t\tbool ack);\n\tuint32_t (*usr_block_max_size_get)(struct target *target);\n\tint (*buffs_write)(struct target *target,\n\t\tuint32_t bufs_num,\n\t\tuint32_t buf_sz[],\n\t\tconst uint8_t *bufs[],\n\t\tuint32_t block_id,\n\t\tbool ack,\n\t\tbool data);\n\tint (*leave_trace_crit_section_start)(struct target *target);\n\tint (*leave_trace_crit_section_stop)(struct target *target);\n};\n\nstruct esp_apptrace_host2target_hdr {\n\tuint16_t block_sz;\n};\n\nstruct esp32_apptrace_dest {\n\tvoid *priv;\n\tint (*write)(void *priv, uint8_t *data, int size);\n\tint (*clean)(void *priv);\n\tbool log_progress;\n};\n\nstruct esp32_apptrace_format {\n\tuint32_t hdr_sz;\n\tint (*core_id_get)(struct target *target, uint8_t *hdr_buf);\n\tuint32_t (*usr_block_len_get)(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len);\n};\n\nstruct esp32_apptrace_cmd_stats {\n\tuint32_t incompl_blocks;\n\tuint32_t lost_bytes;\n\tfloat min_blk_read_time;\n\tfloat max_blk_read_time;\n\tfloat min_blk_proc_time;\n\tfloat max_blk_proc_time;\n};\n\nstruct esp32_apptrace_cmd_ctx {\n\tvolatile int running;\n\tint mode;\n\t/* TODO: use subtargets from target arch info */\n\tstruct target *cpus[ESP32_APPTRACE_MAX_CORES_NUM];\n\t/* TODO: use cores num from target */\n\tunsigned int cores_num;\n\tconst struct esp32_apptrace_hw *hw;\n\tenum target_state target_state;\n\tuint32_t last_blk_id;\n\tstruct list_head free_trace_blocks;\n\tstruct list_head ready_trace_blocks;\n\tuint32_t max_trace_block_sz;\n\tstruct esp32_apptrace_format trace_format;\n\tint (*process_data)(struct esp32_apptrace_cmd_ctx *ctx, unsigned int core_id, uint8_t *data, uint32_t data_len);\n\tvoid (*auto_clean)(struct esp32_apptrace_cmd_ctx *ctx);\n\tuint32_t tot_len;\n\tuint32_t raw_tot_len;\n\tfloat stop_tmo;\n\tstruct esp32_apptrace_cmd_stats stats;\n\tstruct duration read_time;\n\tstruct duration idle_time;\n\tvoid *cmd_priv;\n\tstruct target *target;\n\tstruct command_invocation *cmd;\n};\n\nstruct esp32_apptrace_cmd_data {\n\tstruct esp32_apptrace_dest data_dest;\n\tuint32_t poll_period;\n\tuint32_t max_len;\n\tuint32_t skip_len;\n\tbool wait4halt;\n};\n\nint esp32_apptrace_cmd_ctx_init(struct esp32_apptrace_cmd_ctx *cmd_ctx, struct command_invocation *cmd, int mode);\nint esp32_apptrace_cmd_ctx_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx);\nvoid esp32_apptrace_cmd_args_parse(struct esp32_apptrace_cmd_ctx *cmd_ctx,\n\tstruct esp32_apptrace_cmd_data *cmd_data,\n\tconst char **argv,\n\tint argc);\nint esp32_apptrace_dest_init(struct esp32_apptrace_dest dest[], const char *dest_paths[], unsigned int max_dests);\nint esp32_apptrace_dest_cleanup(struct esp32_apptrace_dest dest[], unsigned int max_dests);\nint esp_apptrace_usr_block_write(const struct esp32_apptrace_hw *hw, struct target *target,\n\tuint32_t block_id,\n\tconst uint8_t *data,\n\tuint32_t size);\n\nextern const struct command_registration esp32_apptrace_command_handlers[];\n\n#endif\t/* OPENOCD_TARGET_ESP32_APPTRACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32_sysview.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP32 sysview tracing module                                          *\n *   Copyright (C) 2020 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include \"esp32_apptrace.h\"\n#include \"esp32_sysview.h\"\n#include \"segger_sysview.h\"\n\n/* in SystemView mode core ID is passed in event ID field */\n#define ESP32_SYSVIEW_USER_BLOCK_CORE(_v_)  (0)\t/* not used */\n#define ESP32_SYSVIEW_USER_BLOCK_LEN(_v_)   (_v_)\n#define ESP32_SYSVIEW_USER_BLOCK_HDR_SZ     2\n\nstruct esp_sysview_target2host_hdr {\n\tuint8_t block_sz;\n\tuint8_t wr_sz;\n};\n#define SYSVIEW_BLOCK_SIZE_OFFSET       0\n#define SYSVIEW_WR_SIZE_OFFSET          1\n\nstatic int esp_sysview_trace_header_write(struct esp32_apptrace_cmd_ctx *ctx, bool mcore_format);\nstatic int esp32_sysview_core_id_get(struct target *target, uint8_t *hdr_buf);\nstatic uint32_t esp32_sysview_usr_block_len_get(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len);\n\nint esp32_sysview_cmd_init(struct esp32_apptrace_cmd_ctx *cmd_ctx,\n\tstruct command_invocation *cmd,\n\tint mode,\n\tbool mcore_format,\n\tconst char **argv,\n\tint argc)\n{\n\tstruct esp32_sysview_cmd_data *cmd_data;\n\n\tif (argc < 1) {\n\t\tcommand_print(cmd, \"Not enough args! Need trace data destination!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint res = esp32_apptrace_cmd_ctx_init(cmd_ctx, cmd, mode);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tint core_num = cmd_ctx->cores_num;\n\n\tif (!mcore_format && argc < core_num) {\n\t\tcommand_print(cmd, \"Not enough args! Need %d trace data destinations!\", core_num);\n\t\tres = ERROR_FAIL;\n\t\tgoto on_error;\n\t}\n\n\tcmd_data = calloc(1, sizeof(*cmd_data));\n\tif (!cmd_data) {\n\t\tcommand_print(cmd, \"No memory for command data!\");\n\t\tres = ERROR_FAIL;\n\t\tgoto on_error;\n\t}\n\tcmd_ctx->cmd_priv = cmd_data;\n\tcmd_data->mcore_format = mcore_format;\n\n\t/*outfile1 [outfile2] [poll_period [trace_size [stop_tmo [wait4halt [skip_size]]]]] */\n\tint dests_num = esp32_apptrace_dest_init(cmd_data->data_dests, argv, !mcore_format ? core_num : 1);\n\tif (!mcore_format && dests_num < core_num) {\n\t\tcommand_print(cmd, \"Not enough args! Need %d trace data destinations!\", core_num);\n\t\tfree(cmd_data);\n\t\tres = ERROR_FAIL;\n\t\tgoto on_error;\n\t}\n\tcmd_data->apptrace.max_len = UINT32_MAX;\n\tcmd_data->apptrace.poll_period = 0 /*ms*/;\n\tcmd_ctx->stop_tmo = -1.0;\t/* infinite */\n\tif (argc > dests_num) {\n\t\t/* parse remaining args */\n\t\tesp32_apptrace_cmd_args_parse(cmd_ctx,\n\t\t\t&cmd_data->apptrace,\n\t\t\t&argv[dests_num],\n\t\t\targc - dests_num);\n\t}\n\tLOG_USER(\"App trace params: from %d cores, size %u bytes, stop_tmo %g s, \"\n\t\t\"poll period %u ms, wait_rst %d, skip %u bytes\",\n\t\tcmd_ctx->cores_num,\n\t\tcmd_data->apptrace.max_len,\n\t\tcmd_ctx->stop_tmo,\n\t\tcmd_data->apptrace.poll_period,\n\t\tcmd_data->apptrace.wait4halt,\n\t\tcmd_data->apptrace.skip_len);\n\n\tcmd_ctx->trace_format.hdr_sz = ESP32_SYSVIEW_USER_BLOCK_HDR_SZ;\n\tcmd_ctx->trace_format.core_id_get = esp32_sysview_core_id_get;\n\tcmd_ctx->trace_format.usr_block_len_get = esp32_sysview_usr_block_len_get;\n\n\tres = esp_sysview_trace_header_write(cmd_ctx, mcore_format);\n\tif (res != ERROR_OK) {\n\t\tcommand_print(cmd, \"Failed to write trace header (%d)!\", res);\n\t\tesp32_apptrace_dest_cleanup(cmd_data->data_dests, core_num);\n\t\tfree(cmd_data);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\non_error:\n\tcmd_ctx->running = 0;\n\tesp32_apptrace_cmd_ctx_cleanup(cmd_ctx);\n\treturn res;\n}\n\nint esp32_sysview_cmd_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx)\n{\n\tstruct esp32_sysview_cmd_data *cmd_data = cmd_ctx->cmd_priv;\n\n\tesp32_apptrace_dest_cleanup(cmd_data->data_dests, cmd_ctx->cores_num);\n\tfree(cmd_data);\n\tcmd_ctx->cmd_priv = NULL;\n\tesp32_apptrace_cmd_ctx_cleanup(cmd_ctx);\n\treturn ERROR_OK;\n}\n\nstatic int esp32_sysview_core_id_get(struct target *target, uint8_t *hdr_buf)\n{\n\t/* for sysview compressed apptrace header is used, so core id is encoded in sysview packet */\n\treturn 0;\n}\n\nstatic uint32_t esp32_sysview_usr_block_len_get(struct target *target, uint8_t *hdr_buf, uint32_t *wr_len)\n{\n\t*wr_len = ESP32_SYSVIEW_USER_BLOCK_LEN(hdr_buf[SYSVIEW_WR_SIZE_OFFSET]);\n\treturn ESP32_SYSVIEW_USER_BLOCK_LEN(hdr_buf[SYSVIEW_BLOCK_SIZE_OFFSET]);\n}\n\nstatic int esp_sysview_trace_header_write(struct esp32_apptrace_cmd_ctx *ctx, bool mcore_format)\n{\n\tstruct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv;\n\tchar *hdr_str;\n\tint dests_num;\n\n\tif (!mcore_format) {\n\t\thdr_str = \";\\n\"\n\t\t\t\"; Version     \" SYSVIEW_MIN_VER_STRING \"\\n\"\n\t\t\t\"; Author      Espressif Inc\\n\"\n\t\t\t\";\\n\";\n\t\tdests_num = ctx->cores_num;\n\t} else {\n\t\thdr_str = \";\\n\"\n\t\t\t\"; Version     \" SYSVIEW_MIN_VER_STRING \"\\n\"\n\t\t\t\"; Author      Espressif Inc\\n\"\n\t\t\t\"; ESP_Extension\\n\"\n\t\t\t\";\\n\";\n\t\tdests_num = 1;\n\t}\n\n\tint hdr_len = strlen(hdr_str);\n\tfor (int i = 0; i < dests_num; i++) {\n\t\tint res = cmd_data->data_dests[i].write(cmd_data->data_dests[i].priv,\n\t\t\t(uint8_t *)hdr_str,\n\t\t\thdr_len);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to write %u bytes to dest %d!\", hdr_len, i);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic void sysview_encode_u32(uint8_t **dest, uint32_t val)\n{\n\tuint8_t *sv_ptr = *dest;\n\twhile (val > 0x7F) {\n\t\t*sv_ptr++ = (uint8_t)(val | 0x80);\n\t\tval >>= 7;\n\t}\n\t*sv_ptr++ = (uint8_t)val;\n\t*dest = sv_ptr;\n}\n\nstatic uint32_t esp_sysview_decode_u32(uint8_t **ptr)\n{\n\tuint32_t val = 0;\n\tfor (int k = 0;; k++, (*ptr)++) {\n\t\tif (**ptr & 0x80) {\n\t\t\tval |= (uint32_t)(**ptr & ~0x80) << 7 * k;\n\t\t} else {\n\t\t\tval |= (uint32_t)**ptr << 7 * k;\n\t\t\t(*ptr)++;\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn val;\n}\n\nstatic uint16_t esp_sysview_decode_plen(uint8_t **ptr)\n{\n\tuint16_t payload_len = 0;\n\tuint8_t *p = *ptr;\n\t/* here pkt points to encoded payload length */\n\tif (*p & 0x80) {\n\t\tpayload_len = *(p + 1);\t/* higher part */\n\t\tpayload_len = (payload_len << 7) | (*p & ~0x80);/* lower 7 bits */\n\t\tp += 2;\t/* payload len (2 bytes) */\n\t} else {\n\t\tpayload_len = *p;\n\t\tp++;\t/* payload len (1 byte) */\n\t}\n\t*ptr = p;\n\n\treturn payload_len;\n}\n\nstatic uint16_t esp_sysview_get_predef_payload_len(uint16_t id, uint8_t *pkt)\n{\n\tuint16_t len;\n\tuint8_t *ptr = pkt;\n\n\tswitch (id) {\n\tcase SYSVIEW_EVTID_OVERFLOW:\n\tcase SYSVIEW_EVTID_ISR_ENTER:\n\tcase SYSVIEW_EVTID_TASK_START_EXEC:\n\tcase SYSVIEW_EVTID_TASK_START_READY:\n\tcase SYSVIEW_EVTID_TASK_CREATE:\n\tcase SYSVIEW_EVTID_SYSTIME_CYCLES:\n\tcase SYSVIEW_EVTID_USER_START:\n\tcase SYSVIEW_EVTID_USER_STOP:\n\tcase SYSVIEW_EVTID_TIMER_ENTER:\n\t\t/*ENCODE_U32 */\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tlen = ptr - pkt;\n\t\tbreak;\n\tcase SYSVIEW_EVTID_TASK_STOP_READY:\n\tcase SYSVIEW_EVTID_SYSTIME_US:\n\t\t/*2*ENCODE_U32 */\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tlen = ptr - pkt;\n\t\tbreak;\n\tcase SYSVIEW_EVTID_SYSDESC:\n\t\t/*str(128 + 1) */\n\t\tlen = *ptr + 1;\n\t\tbreak;\n\tcase SYSVIEW_EVTID_TASK_INFO:\n\tcase SYSVIEW_EVTID_MODULEDESC:\n\t\t/*2*ENCODE_U32 + str */\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tesp_sysview_decode_u32(&ptr);\n\t\t/* TODO: add support for strings longer then 255 bytes */\n\t\tlen = ptr - pkt + *ptr + 1;\n\t\tbreak;\n\tcase SYSVIEW_EVTID_STACK_INFO:\n\t\t/*4*ENCODE_U32 */\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tesp_sysview_decode_u32(&ptr);\n\t\tlen = ptr - pkt;\n\t\tbreak;\n\tcase SYSVIEW_EVTID_ISR_EXIT:\n\tcase SYSVIEW_EVTID_TASK_STOP_EXEC:\n\tcase SYSVIEW_EVTID_TRACE_START:\n\tcase SYSVIEW_EVTID_TRACE_STOP:\n\tcase SYSVIEW_EVTID_IDLE:\n\tcase SYSVIEW_EVTID_ISR_TO_SCHEDULER:\n\tcase SYSVIEW_EVTID_TIMER_EXIT:\n\t\tlen = 0;\n\t\tbreak;\n\n\t/*case SYSVIEW_EVTID_NOP: */\n\tdefault:\n\t\tLOG_ERROR(\"sysview: Unsupported predef event %d!\", id);\n\t\tlen = 0;\n\t}\n\treturn len;\n}\n\nstatic uint16_t esp_sysview_parse_packet(uint8_t *pkt_buf,\n\tuint32_t *pkt_len,\n\tunsigned int *pkt_core_id,\n\tuint32_t *delta,\n\tuint32_t *delta_len,\n\tbool clear_core_bit)\n{\n\tuint8_t *pkt = pkt_buf;\n\tuint16_t event_id = 0, payload_len = 0;\n\n\t*pkt_core_id = 0;\n\t*pkt_len = 0;\n\t/* 1-2 byte of message type, 0-2  byte of payload length, payload, 1-5 bytes of timestamp. */\n\tif (*pkt & 0x80) {\n\t\tif (*(pkt + 1) & (1 << 6)) {\n\t\t\tif (clear_core_bit)\n\t\t\t\t*(pkt + 1) &= ~(1 << 6);\t/* clear core_id bit */\n\t\t\t*pkt_core_id = 1;\n\t\t}\n\t\tevent_id = *(pkt + 1) & ~(1 << 6);\t/* higher part */\n\t\tevent_id = (event_id << 7) | (*pkt & ~0x80);\t/* lower 7 bits */\n\t\tpkt += 2;\t/* event_id (2 bytes) */\n\t\t/* here pkt points to encoded payload length */\n\t\tpayload_len = esp_sysview_decode_plen(&pkt);\n\t} else {\n\t\tif (*pkt & (1 << 6)) {\n\t\t\tif (clear_core_bit)\n\t\t\t\t*pkt &= ~(1 << 6);\t/* clear core_id bit */\n\t\t\t*pkt_core_id = 1;\n\t\t}\n\t\t/* event_id (1 byte) */\n\t\tevent_id = *pkt & ~(1 << 6);\n\t\tpkt++;\n\t\tif (event_id < 24)\n\t\t\tpayload_len = esp_sysview_get_predef_payload_len(event_id, pkt);\n\t\telse\n\t\t\tpayload_len = esp_sysview_decode_plen(&pkt);\n\t}\n\tpkt += payload_len;\n\tuint8_t *delta_start = pkt;\n\t*delta = esp_sysview_decode_u32(&pkt);\n\t*delta_len = pkt - delta_start;\n\t*pkt_len = pkt - pkt_buf;\n\tLOG_DEBUG(\"sysview: evt %d len %d plen %d dlen %d\",\n\t\tevent_id,\n\t\t*pkt_len,\n\t\tpayload_len,\n\t\t*delta_len);\n\treturn event_id;\n}\n\nstatic int esp32_sysview_write_packet(struct esp32_sysview_cmd_data *cmd_data,\n\tint pkt_core_id, uint32_t pkt_len, uint8_t *pkt_buf, uint32_t delta_len, uint8_t *delta_buf)\n{\n\tif (!cmd_data->data_dests[pkt_core_id].write)\n\t\treturn ERROR_FAIL;\n\n\tint res = cmd_data->data_dests[pkt_core_id].write(cmd_data->data_dests[pkt_core_id].priv, pkt_buf, pkt_len);\n\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"sysview: Failed to write %u bytes to dest %d!\", pkt_len, pkt_core_id);\n\t\treturn res;\n\t}\n\tif (delta_len) {\n\t\t/* write packet with modified delta */\n\t\tres = cmd_data->data_dests[pkt_core_id].write(cmd_data->data_dests[pkt_core_id].priv, delta_buf, delta_len);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to write %u bytes of delta to dest %d!\", delta_len, pkt_core_id);\n\t\t\treturn res;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32_sysview_process_packet(struct esp32_apptrace_cmd_ctx *ctx,\n\tunsigned int pkt_core_id, uint16_t event_id, uint32_t delta, uint32_t delta_len,\n\tuint32_t pkt_len, uint8_t *pkt_buf)\n{\n\tstruct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv;\n\tint pkt_core_changed = 0;\n\tuint32_t new_delta_len = 0;\n\tuint8_t new_delta_buf[10];\n\tuint32_t wr_len = pkt_len;\n\n\tif (ctx->cores_num > 1) {\n\t\tif (cmd_data->sv_last_core_id == pkt_core_id) {\n\t\t\t/* if this packet is for the same core as the prev one acc delta and write packet unmodified */\n\t\t\tcmd_data->sv_acc_time_delta += delta;\n\t\t} else {\n\t\t\t/* if this packet is for another core then prev one set acc delta to the packet's delta */\n\t\t\tuint8_t *delta_ptr = new_delta_buf;\n\t\t\tsysview_encode_u32(&delta_ptr, delta + cmd_data->sv_acc_time_delta);\n\t\t\tcmd_data->sv_acc_time_delta = delta;\n\t\t\twr_len -= delta_len;\n\t\t\tnew_delta_len = delta_ptr - new_delta_buf;\n\t\t\tpkt_core_changed = 1;\n\t\t}\n\t\tcmd_data->sv_last_core_id = pkt_core_id;\n\t}\n\tif (pkt_core_id >= ctx->cores_num) {\n\t\tLOG_WARNING(\"sysview: invalid core ID in packet %d, must be less then %d! Event id %d\",\n\t\t\tpkt_core_id,\n\t\t\tctx->cores_num,\n\t\t\tevent_id);\n\t\treturn ERROR_FAIL;\n\t}\n\tint res = esp32_sysview_write_packet(cmd_data,\n\t\tpkt_core_id,\n\t\twr_len,\n\t\tpkt_buf,\n\t\tnew_delta_len,\n\t\tnew_delta_buf);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\tif (pkt_core_id == i)\n\t\t\tcontinue;\n\t\tswitch (event_id) {\n\t\t/* messages below should be sent to trace destinations for all cores */\n\t\tcase SYSVIEW_EVTID_TRACE_START:\n\t\tcase SYSVIEW_EVTID_TRACE_STOP:\n\t\tcase SYSVIEW_EVTID_SYSTIME_CYCLES:\n\t\tcase SYSVIEW_EVTID_SYSTIME_US:\n\t\tcase SYSVIEW_EVTID_SYSDESC:\n\t\tcase SYSVIEW_EVTID_TASK_INFO:\n\t\tcase SYSVIEW_EVTID_STACK_INFO:\n\t\tcase SYSVIEW_EVTID_MODULEDESC:\n\t\tcase SYSVIEW_EVTID_INIT:\n\t\tcase SYSVIEW_EVTID_NUMMODULES:\n\t\tcase SYSVIEW_EVTID_OVERFLOW:\n\t\tcase SYSVIEW_EVTID_TASK_START_READY:\n\t\t\t/* if packet's source core has changed */\n\t\t\twr_len = pkt_len;\n\t\t\tif (pkt_core_changed) {\n\t\t\t\t/* clone packet with unmodified delta */\n\t\t\t\tnew_delta_len = 0;\n\t\t\t} else {\n\t\t\t\t/* clone packet with modified delta */\n\t\t\t\tuint8_t *delta_ptr = new_delta_buf;\n\t\t\t\tsysview_encode_u32(&delta_ptr, cmd_data->sv_acc_time_delta /*delta has been accumulated above*/);\n\t\t\t\twr_len -= delta_len;\n\t\t\t\tnew_delta_len = delta_ptr - new_delta_buf;\n\t\t\t}\n\t\t\tLOG_DEBUG(\"sysview: Redirect %d bytes of event %d to dest %d\", wr_len, event_id, i);\n\t\t\tres = esp32_sysview_write_packet(cmd_data,\n\t\t\t\ti,\n\t\t\t\twr_len,\n\t\t\t\tpkt_buf,\n\t\t\t\tnew_delta_len,\n\t\t\t\tnew_delta_buf);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\t/* messages above are cloned to trace files for both cores,\n\t\t\t* so reset acc time delta, both files have actual delta\n\t\t\t* info */\n\t\t\tcmd_data->sv_acc_time_delta = 0;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nint esp32_sysview_process_data(struct esp32_apptrace_cmd_ctx *ctx,\n\tunsigned int core_id,\n\tuint8_t *data,\n\tuint32_t data_len)\n{\n\tstruct esp32_sysview_cmd_data *cmd_data = ctx->cmd_priv;\n\n\tLOG_DEBUG(\"sysview: Read from target %d bytes [%x %x %x %x]\",\n\t\tdata_len,\n\t\tdata[0],\n\t\tdata[1],\n\t\tdata[2],\n\t\tdata[3]);\n\tint res;\n\tuint32_t processed = 0;\n\tif (core_id >= ctx->cores_num) {\n\t\tLOG_ERROR(\"sysview: Invalid core id %d in user block!\", core_id);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (cmd_data->mcore_format)\n\t\tcore_id = 0;\n\tif (ctx->tot_len == 0) {\n\t\t/* handle sync seq */\n\t\tif (data_len < SYSVIEW_SYNC_LEN) {\n\t\t\tLOG_ERROR(\"sysview: Invalid init seq len %d!\", data_len);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tLOG_DEBUG(\"sysview: Process %d sync bytes\", SYSVIEW_SYNC_LEN);\n\t\tuint8_t sync_seq[SYSVIEW_SYNC_LEN] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };\n\t\tif (memcmp(data, sync_seq, SYSVIEW_SYNC_LEN) != 0) {\n\t\t\tLOG_ERROR(\"sysview: Invalid init seq [%x %x %x %x %x %x %x %x %x %x]\",\n\t\t\t\tdata[0], data[1], data[2], data[3], data[4], data[5], data[6],\n\t\t\t\tdata[7], data[8], data[9]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tres = cmd_data->data_dests[core_id].write(cmd_data->data_dests[core_id].priv,\n\t\t\tdata,\n\t\t\tSYSVIEW_SYNC_LEN);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"sysview: Failed to write %u sync bytes to dest %d!\",\n\t\t\t\tSYSVIEW_SYNC_LEN,\n\t\t\t\tcore_id);\n\t\t\treturn res;\n\t\t}\n\t\tif (!cmd_data->mcore_format) {\n\t\t\tfor (unsigned int i = 0; i < ctx->cores_num; i++) {\n\t\t\t\tif (core_id == i)\n\t\t\t\t\tcontinue;\n\t\t\t\tres =\n\t\t\t\t\tcmd_data->data_dests[i].write(cmd_data->data_dests[i].priv,\n\t\t\t\t\tdata,\n\t\t\t\t\tSYSVIEW_SYNC_LEN);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"sysview: Failed to write %u sync bytes to dest %d!\", SYSVIEW_SYNC_LEN, core_id ? 0 : 1);\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tctx->tot_len += SYSVIEW_SYNC_LEN;\n\t\tprocessed += SYSVIEW_SYNC_LEN;\n\t}\n\twhile (processed < data_len) {\n\t\tunsigned int pkt_core_id;\n\t\tuint32_t delta_len = 0;\n\t\tuint32_t pkt_len = 0, delta = 0;\n\t\tuint16_t event_id = esp_sysview_parse_packet(data + processed,\n\t\t\t&pkt_len,\n\t\t\t&pkt_core_id,\n\t\t\t&delta,\n\t\t\t&delta_len,\n\t\t\t!cmd_data->mcore_format);\n\t\tLOG_DEBUG(\"sysview: Process packet: core %d, %d id, %d bytes [%x %x %x %x]\",\n\t\t\tpkt_core_id,\n\t\t\tevent_id,\n\t\t\tpkt_len,\n\t\t\tdata[processed + 0],\n\t\t\tdata[processed + 1],\n\t\t\tdata[processed + 2],\n\t\t\tdata[processed + 3]);\n\t\tif (!cmd_data->mcore_format) {\n\t\t\tres = esp32_sysview_process_packet(ctx,\n\t\t\t\tpkt_core_id,\n\t\t\t\tevent_id,\n\t\t\t\tdelta,\n\t\t\t\tdelta_len,\n\t\t\t\tpkt_len,\n\t\t\t\tdata + processed);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t} else {\n\t\t\tres = cmd_data->data_dests[0].write(cmd_data->data_dests[0].priv, data + processed, pkt_len);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"sysview: Failed to write %u bytes to dest %d!\", pkt_len, 0);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t\tif (event_id == SYSVIEW_EVTID_TRACE_STOP)\n\t\t\tcmd_data->sv_trace_running = 0;\n\t\tctx->tot_len += pkt_len;\n\t\tprocessed += pkt_len;\n\t}\n\tLOG_USER(\"%u \", ctx->tot_len);\n\t/* check for stop condition */\n\tif (ctx->tot_len > cmd_data->apptrace.skip_len &&\n\t\t(ctx->tot_len - cmd_data->apptrace.skip_len >= cmd_data->apptrace.max_len)) {\n\t\tctx->running = 0;\n\t\tif (duration_measure(&ctx->read_time) != 0) {\n\t\t\tLOG_ERROR(\"Failed to stop trace read time measure!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32_sysview.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   ESP32 sysview tracing module                                          *\n *   Copyright (C) 2020 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP32_SYSVIEW_H\n#define OPENOCD_TARGET_ESP32_SYSVIEW_H\n\n#include <stdint.h>\n#include \"esp32_apptrace.h\"\n\nstruct esp32_sysview_cmd_data {\n\t/* Should be the first field. Generic apptrace command handling code accesses it */\n\tstruct esp32_apptrace_cmd_data apptrace;\n\tstruct esp32_apptrace_dest data_dests[ESP32_APPTRACE_MAX_CORES_NUM];\n\tbool mcore_format;\n\tuint32_t sv_acc_time_delta;\n\tunsigned int sv_last_core_id;\n\tint sv_trace_running;\n};\n\nstruct esp32_apptrace_cmd_ctx;\n\nint esp32_sysview_cmd_init(struct esp32_apptrace_cmd_ctx *cmd_ctx,\n\tstruct command_invocation *cmd,\n\tint mode,\n\tbool mcore_format,\n\tconst char **argv,\n\tint argc);\nint esp32_sysview_cmd_cleanup(struct esp32_apptrace_cmd_ctx *cmd_ctx);\nint esp32_sysview_process_data(struct esp32_apptrace_cmd_ctx *ctx,\n\tunsigned int core_id,\n\tuint8_t *data,\n\tuint32_t data_len);\n\n#endif\t/* OPENOCD_TARGET_ESP32_SYSVIEW_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32s2.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP32-S2 target for OpenOCD                                           *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include \"assert.h\"\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/semihosting_common.h>\n#include \"esp_xtensa.h\"\n#include \"esp_xtensa_semihosting.h\"\n\n#define ESP32_S2_RTC_DATA_LOW           0x50000000\n#define ESP32_S2_RTC_DATA_HIGH          0x50002000\n#define ESP32_S2_DR_REG_LOW             0x3f400000\n#define ESP32_S2_DR_REG_HIGH            0x3f4d3FFC\n#define ESP32_S2_SYS_RAM_LOW            0x60000000UL\n#define ESP32_S2_SYS_RAM_HIGH           (ESP32_S2_SYS_RAM_LOW + 0x20000000UL)\n\n/* ESP32 WDT */\n#define ESP32_S2_WDT_WKEY_VALUE         0x50d83aa1\n#define ESP32_S2_TIMG0_BASE             0x3f41F000\n#define ESP32_S2_TIMG1_BASE             0x3f420000\n#define ESP32_S2_TIMGWDT_CFG0_OFF       0x48\n#define ESP32_S2_TIMGWDT_PROTECT_OFF    0x64\n#define ESP32_S2_TIMG0WDT_CFG0          (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)\n#define ESP32_S2_TIMG1WDT_CFG0          (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_CFG0_OFF)\n#define ESP32_S2_TIMG0WDT_PROTECT       (ESP32_S2_TIMG0_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)\n#define ESP32_S2_TIMG1WDT_PROTECT       (ESP32_S2_TIMG1_BASE + ESP32_S2_TIMGWDT_PROTECT_OFF)\n#define ESP32_S2_RTCCNTL_BASE           0x3f408000\n#define ESP32_S2_RTCWDT_CFG_OFF         0x94\n#define ESP32_S2_RTCWDT_PROTECT_OFF     0xAC\n#define ESP32_S2_SWD_CONF_OFF           0xB0\n#define ESP32_S2_SWD_WPROTECT_OFF       0xB4\n#define ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF      0x8C\n#define ESP32_S2_RTC_CNTL_DIG_PWC_REG   (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTC_CNTL_DIG_PWC_REG_OFF)\n#define ESP32_S2_RTCWDT_CFG             (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_CFG_OFF)\n#define ESP32_S2_RTCWDT_PROTECT         (ESP32_S2_RTCCNTL_BASE + ESP32_S2_RTCWDT_PROTECT_OFF)\n#define ESP32_S2_SWD_CONF_REG           (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_CONF_OFF)\n#define ESP32_S2_SWD_WPROTECT_REG       (ESP32_S2_RTCCNTL_BASE + ESP32_S2_SWD_WPROTECT_OFF)\n#define ESP32_S2_SWD_AUTO_FEED_EN_M     BIT(31)\n#define ESP32_S2_SWD_WKEY_VALUE         0x8F1D312AU\n#define ESP32_S2_OPTIONS0               (ESP32_S2_RTCCNTL_BASE + 0x0000)\n#define ESP32_S2_SW_SYS_RST_M           0x80000000\n#define ESP32_S2_SW_SYS_RST_V           0x1\n#define ESP32_S2_SW_SYS_RST_S           31\n#define ESP32_S2_SW_STALL_PROCPU_C0_M   ((ESP32_S2_SW_STALL_PROCPU_C0_V) << (ESP32_S2_SW_STALL_PROCPU_C0_S))\n#define ESP32_S2_SW_STALL_PROCPU_C0_V   0x3\n#define ESP32_S2_SW_STALL_PROCPU_C0_S   2\n#define ESP32_S2_SW_CPU_STALL           (ESP32_S2_RTCCNTL_BASE + 0x00B8)\n#define ESP32_S2_SW_STALL_PROCPU_C1_M   ((ESP32_S2_SW_STALL_PROCPU_C1_V) << (ESP32_S2_SW_STALL_PROCPU_C1_S))\n#define ESP32_S2_SW_STALL_PROCPU_C1_V   0x3FU\n#define ESP32_S2_SW_STALL_PROCPU_C1_S   26\n#define ESP32_S2_CLK_CONF               (ESP32_S2_RTCCNTL_BASE + 0x0074)\n#define ESP32_S2_CLK_CONF_DEF           0x1583218\n#define ESP32_S2_STORE4                 (ESP32_S2_RTCCNTL_BASE + 0x00BC)\n#define ESP32_S2_STORE5                 (ESP32_S2_RTCCNTL_BASE + 0x00C0)\n#define ESP32_S2_DPORT_PMS_OCCUPY_3     0x3F4C10E0\n\n#define ESP32_S2_TRACEMEM_BLOCK_SZ      0x4000\n\n#define ESP32_S2_DR_REG_UART_BASE       0x3f400000\n#define ESP32_S2_REG_UART_BASE(i)       (ESP32_S2_DR_REG_UART_BASE + (i) * 0x10000)\n#define ESP32_S2_UART_DATE_REG(i)       (ESP32_S2_REG_UART_BASE(i) + 0x74)\nstruct esp32s2_common {\n\tstruct esp_xtensa_common esp_xtensa;\n};\n\nstatic int esp32s2_soc_reset(struct target *target);\nstatic int esp32s2_disable_wdts(struct target *target);\n\nstatic int esp32s2_assert_reset(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_deassert_reset(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\n\tint res = xtensa_deassert_reset(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* restore configured value\n\t   esp32s2_soc_reset() modified it, but can not restore just after SW reset for some reason (???) */\n\tres = xtensa_smpbreak_write(xtensa, xtensa->smp_break);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to restore smpbreak (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_soft_reset_halt(struct target *target)\n{\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\n\t/* Reset the SoC first */\n\tint res = esp32s2_soc_reset(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn xtensa_soft_reset_halt(target);\n}\n\nstatic int esp32s2_set_peri_reg_mask(struct target *target,\n\ttarget_addr_t addr,\n\tuint32_t mask,\n\tuint32_t val)\n{\n\tuint32_t reg_val;\n\tint res = target_read_u32(target, addr, &reg_val);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treg_val = (reg_val & (~mask)) | val;\n\tres = target_write_u32(target, addr, reg_val);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_stall_set(struct target *target, bool stall)\n{\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\n\tint res = esp32s2_set_peri_reg_mask(target,\n\t\tESP32_S2_SW_CPU_STALL,\n\t\tESP32_S2_SW_STALL_PROCPU_C1_M,\n\t\tstall ? 0x21U << ESP32_S2_SW_STALL_PROCPU_C1_S : 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_SW_CPU_STALL (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = esp32s2_set_peri_reg_mask(target,\n\t\tESP32_S2_OPTIONS0,\n\t\tESP32_S2_SW_STALL_PROCPU_C0_M,\n\t\tstall ? 0x2 << ESP32_S2_SW_STALL_PROCPU_C0_S : 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_OPTIONS0 (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic inline int esp32s2_stall(struct target *target)\n{\n\treturn esp32s2_stall_set(target, true);\n}\n\nstatic inline int esp32s2_unstall(struct target *target)\n{\n\treturn esp32s2_stall_set(target, false);\n}\n\n/* Reset ESP32-S2's peripherals.\nPostconditions: all peripherals except RTC_CNTL are reset, CPU's PC is undefined, PRO CPU is halted, APP CPU is in reset\nHow this works:\n0. make sure target is halted; if not, try to halt it; if that fails, try to reset it (via OCD) and then halt\n1. Resets clock related registers\n2. Stalls CPU\n3. trigger SoC reset using RTC_CNTL_SW_SYS_RST bit\n4. CPU is reset and stalled at the first reset vector instruction\n5. wait for the OCD to be reset\n6. halt the target\n7. Unstalls CPU\n8. Disables WDTs and trace memory mapping\n*/\nstatic int esp32s2_soc_reset(struct target *target)\n{\n\tint res;\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_DEBUG(\"start\");\n\n\t/* In order to write to peripheral registers, target must be halted first */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_DEBUG(target, \"Target not halted before SoC reset, trying to halt it first\");\n\t\txtensa_halt(target);\n\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_TARGET_DEBUG(target, \"Couldn't halt target before SoC reset, trying to do reset-halt\");\n\t\t\tres = xtensa_assert_reset(target);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(\n\t\t\t\t\ttarget,\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\tint reset_halt_save = target->reset_halt;\n\t\t\ttarget->reset_halt = 1;\n\t\t\tres = xtensa_deassert_reset(target);\n\t\t\ttarget->reset_halt = reset_halt_save;\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(\n\t\t\t\t\ttarget,\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\txtensa_halt(target);\n\t\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"Couldn't halt target before SoC reset\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t}\n\n\tassert(target->state == TARGET_HALTED);\n\n\t/* Set some clock-related RTC registers to the default values */\n\tres = target_write_u32(target, ESP32_S2_STORE4, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_STORE4 (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_STORE5, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_STORE5 (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_RTC_CNTL_DIG_PWC_REG, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_RTC_CNTL_DIG_PWC_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_CLK_CONF, ESP32_S2_CLK_CONF_DEF);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_CLK_CONF (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* Stall CPU */\n\tres = esp32s2_stall(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\t/* enable stall */\n\tres = xtensa_smpbreak_write(xtensa, OCDDCR_RUNSTALLINEN);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to set smpbreak (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* Reset CPU */\n\txtensa->suppress_dsr_errors = true;\n\tres = esp32s2_set_peri_reg_mask(target,\n\t\tESP32_S2_OPTIONS0,\n\t\tESP32_S2_SW_SYS_RST_M,\n\t\tBIT(ESP32_S2_SW_SYS_RST_S));\n\txtensa->suppress_dsr_errors = false;\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_OPTIONS0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* Wait for SoC to reset */\n\talive_sleep(100);\n\tint64_t timeout = timeval_ms() + 100;\n\twhile (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {\n\t\talive_sleep(10);\n\t\txtensa_poll(target);\n\t\tif (timeval_ms() >= timeout) {\n\t\t\tLOG_TARGET_ERROR(target, \"Timed out waiting for CPU to be reset, target state=%d\",\n\t\t\t\ttarget->state);\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t}\n\n\txtensa_halt(target);\n\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Couldn't halt target before SoC reset\");\n\t\treturn res;\n\t}\n\t/* Unstall CPU */\n\tres = esp32s2_unstall(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\t/* Disable WDTs */\n\tres = esp32s2_disable_wdts(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\t/* Disable trace memory mapping */\n\tres = target_write_u32(target, ESP32_S2_DPORT_PMS_OCCUPY_3, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_DPORT_PMS_OCCUPY_3 (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_disable_wdts(struct target *target)\n{\n\t/* TIMG1 WDT */\n\tint res = target_write_u32(target, ESP32_S2_TIMG0WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_TIMG0WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_TIMG0WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_TIMG0WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* TIMG2 WDT */\n\tres = target_write_u32(target, ESP32_S2_TIMG1WDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_TIMG1WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_TIMG1WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_TIMG1WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* RTC WDT */\n\tres = target_write_u32(target, ESP32_S2_RTCWDT_PROTECT, ESP32_S2_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_RTCWDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S2_RTCWDT_CFG, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_RTCWDT_CFG (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* Enable SWD auto-feed */\n\tres = target_write_u32(target, ESP32_S2_SWD_WPROTECT_REG, ESP32_S2_SWD_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_SWD_WPROTECT_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\tuint32_t swd_conf_reg = 0;\n\tres = target_read_u32(target, ESP32_S2_SWD_CONF_REG, &swd_conf_reg);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read ESP32_S2_SWD_CONF_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\tswd_conf_reg |= ESP32_S2_SWD_AUTO_FEED_EN_M;\n\tres = target_write_u32(target, ESP32_S2_SWD_CONF_REG, swd_conf_reg);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S2_SWD_CONF_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_on_halt(struct target *target)\n{\n\tint ret = esp32s2_disable_wdts(target);\n\tif (ret == ERROR_OK)\n\t\tret = esp_xtensa_on_halt(target);\n\treturn ret;\n}\n\nstatic int esp32s2_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)\n{\n\tint ret = xtensa_step(target, current, address, handle_breakpoints);\n\tif (ret == ERROR_OK) {\n\t\tesp32s2_on_halt(target);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t}\n\treturn ret;\n}\n\nstatic int esp32s2_poll(struct target *target)\n{\n\tenum target_state old_state = target->state;\n\tint ret = esp_xtensa_poll(target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {\n\t\t/* Call any event callbacks that are applicable */\n\t\tif (old_state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t} else {\n\t\t\tif (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) {\n\t\t\t\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\t\t\t\tif (ret == ERROR_OK && esp_xtensa->semihost.need_resume) {\n\t\t\t\t\tesp_xtensa->semihost.need_resume = false;\n\t\t\t\t\t/* Resume xtensa_resume will handle BREAK instruction. */\n\t\t\t\t\tret = target_resume(target, 1, 0, 1, 0);\n\t\t\t\t\tif (ret != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"Failed to resume target\");\n\t\t\t\t\t\treturn ret;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\tesp32s2_on_halt(target);\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nstatic int esp32s2_virt2phys(struct target *target,\n\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\t*physical = virtual;\n\treturn ERROR_OK;\n}\n\nstatic int esp32s2_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\tint ret = esp_xtensa_target_init(cmd_ctx, target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn esp_xtensa_semihosting_init(target);\n}\n\nstatic const struct xtensa_debug_ops esp32s2_dbg_ops = {\n\t.queue_enable = xtensa_dm_queue_enable,\n\t.queue_reg_read = xtensa_dm_queue_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_reg_write\n};\n\nstatic const struct xtensa_power_ops esp32s2_pwr_ops = {\n\t.queue_reg_read = xtensa_dm_queue_pwr_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_pwr_reg_write\n};\n\nstatic const struct esp_semihost_ops esp32s2_semihost_ops = {\n\t.prepare = esp32s2_disable_wdts\n};\n\nstatic int esp32s2_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct xtensa_debug_module_config esp32s2_dm_cfg = {\n\t\t.dbg_ops = &esp32s2_dbg_ops,\n\t\t.pwr_ops = &esp32s2_pwr_ops,\n\t\t.tap = target->tap,\n\t\t.queue_tdi_idle = NULL,\n\t\t.queue_tdi_idle_arg = NULL\n\t};\n\n\t/* creates xtensa object */\n\tstruct esp32s2_common *esp32 = calloc(1, sizeof(*esp32));\n\tif (!esp32) {\n\t\tLOG_ERROR(\"Failed to alloc memory for arch info!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = esp_xtensa_init_arch_info(target, &esp32->esp_xtensa, &esp32s2_dm_cfg, &esp32s2_semihost_ops);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to init arch info!\");\n\t\tfree(esp32);\n\t\treturn ret;\n\t}\n\n\t/* Assume running target. If different, the first poll will fix this */\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration esp32s2_command_handlers[] = {\n\t{\n\t\t.chain = xtensa_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp\",\n\t\t.usage = \"\",\n\t\t.chain = esp32_apptrace_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = semihosting_common_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/* Holds methods for Xtensa targets. */\nstruct target_type esp32s2_target = {\n\t.name = \"esp32s2\",\n\n\t.poll = esp32s2_poll,\n\t.arch_state = esp32s2_arch_state,\n\n\t.halt = xtensa_halt,\n\t.resume = xtensa_resume,\n\t.step = esp32s2_step,\n\n\t.assert_reset = esp32s2_assert_reset,\n\t.deassert_reset = esp32s2_deassert_reset,\n\t.soft_reset_halt = esp32s2_soft_reset_halt,\n\n\t.virt2phys = esp32s2_virt2phys,\n\t.mmu = xtensa_mmu_is_enabled,\n\t.read_memory = xtensa_read_memory,\n\t.write_memory = xtensa_write_memory,\n\n\t.read_buffer = xtensa_read_buffer,\n\t.write_buffer = xtensa_write_buffer,\n\n\t.checksum_memory = xtensa_checksum_memory,\n\n\t.get_gdb_arch = xtensa_get_gdb_arch,\n\t.get_gdb_reg_list = xtensa_get_gdb_reg_list,\n\n\t.add_breakpoint = esp_xtensa_breakpoint_add,\n\t.remove_breakpoint = esp_xtensa_breakpoint_remove,\n\n\t.add_watchpoint = xtensa_watchpoint_add,\n\t.remove_watchpoint = xtensa_watchpoint_remove,\n\n\t.target_create = esp32s2_target_create,\n\t.init_target = esp32s2_target_init,\n\t.examine = xtensa_examine,\n\t.deinit_target = esp_xtensa_target_deinit,\n\n\t.commands = esp32s2_command_handlers,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp32s3.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP32-S3 target API for OpenOCD                                       *\n *   Copyright (C) 2020 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/time_support.h>\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/smp.h>\n#include <target/semihosting_common.h>\n#include \"assert.h\"\n#include \"esp_xtensa_smp.h\"\n\n/*\nThis is a JTAG driver for the ESP32_S3, the are two Tensilica cores inside\nthe ESP32_S3 chip. For more information please have a look into ESP32_S3 target\nimplementation.\n*/\n\n/* ESP32_S3 memory map */\n#define ESP32_S3_RTC_DATA_LOW           0x50000000\n#define ESP32_S3_RTC_DATA_HIGH          0x50002000\n#define ESP32_S3_EXTRAM_DATA_LOW        0x3D000000\n#define ESP32_S3_EXTRAM_DATA_HIGH       0x3E000000\n#define ESP32_S3_SYS_RAM_LOW            0x60000000UL\n#define ESP32_S3_SYS_RAM_HIGH           (ESP32_S3_SYS_RAM_LOW + 0x10000000UL)\n#define ESP32_S3_RTC_SLOW_MEM_BASE      ESP32_S3_RTC_DATA_LOW\n\n/* ESP32_S3 WDT */\n#define ESP32_S3_WDT_WKEY_VALUE       0x50D83AA1\n#define ESP32_S3_TIMG0_BASE           0x6001F000\n#define ESP32_S3_TIMG1_BASE           0x60020000\n#define ESP32_S3_TIMGWDT_CFG0_OFF     0x48\n#define ESP32_S3_TIMGWDT_PROTECT_OFF  0x64\n#define ESP32_S3_TIMG0WDT_CFG0        (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)\n#define ESP32_S3_TIMG1WDT_CFG0        (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_CFG0_OFF)\n#define ESP32_S3_TIMG0WDT_PROTECT     (ESP32_S3_TIMG0_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)\n#define ESP32_S3_TIMG1WDT_PROTECT     (ESP32_S3_TIMG1_BASE + ESP32_S3_TIMGWDT_PROTECT_OFF)\n#define ESP32_S3_RTCCNTL_BASE         0x60008000\n#define ESP32_S3_RTCWDT_CFG_OFF       0x98\n#define ESP32_S3_RTCWDT_PROTECT_OFF   0xB0\n#define ESP32_S3_SWD_CONF_OFF         0xB0\n#define ESP32_S3_SWD_WPROTECT_OFF     0xB4\n#define ESP32_S3_RTCWDT_CFG           (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_CFG_OFF)\n#define ESP32_S3_RTCWDT_PROTECT       (ESP32_S3_RTCCNTL_BASE + ESP32_S3_RTCWDT_PROTECT_OFF)\n#define ESP32_S3_SWD_CONF_REG         (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_CONF_OFF)\n#define ESP32_S3_SWD_WPROTECT_REG     (ESP32_S3_RTCCNTL_BASE + ESP32_S3_SWD_WPROTECT_OFF)\n#define ESP32_S3_SWD_AUTO_FEED_EN_M   BIT(31)\n#define ESP32_S3_SWD_WKEY_VALUE       0x8F1D312AU\n\n#define ESP32_S3_TRACEMEM_BLOCK_SZ    0x4000\n\n/* ESP32_S3 dport regs */\n#define ESP32_S3_DR_REG_SYSTEM_BASE                0x600c0000\n#define ESP32_S3_SYSTEM_CORE_1_CONTROL_0_REG       (ESP32_S3_DR_REG_SYSTEM_BASE + 0x014)\n#define ESP32_S3_SYSTEM_CONTROL_CORE_1_CLKGATE_EN  BIT(1)\n\n/* ESP32_S3 RTC regs */\n#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_REG (ESP32_S3_RTCCNTL_BASE + 0xBC)\n#define ESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF 0x0\n\nstruct esp32s3_common {\n\tstruct esp_xtensa_smp_common esp_xtensa_smp;\n};\n\n/* Reset ESP32-S3's peripherals.\n * 1. OpenOCD makes sure the target is halted; if not, tries to halt it.\n *    If that fails, tries to reset it (via OCD) and then halt.\n * 2. OpenOCD loads the stub code into RTC_SLOW_MEM.\n * 3. Executes the stub code from address 0x50000004.\n * 4. The stub code changes the reset vector to 0x50000000, and triggers\n *    a system reset using RTC_CNTL_SW_SYS_RST bit.\n * 5. Once the PRO CPU is out of reset, it executes the stub code from address 0x50000000.\n *    The stub code disables the watchdog, re-enables JTAG and the APP CPU,\n *    restores the reset vector, and enters an infinite loop.\n * 6. OpenOCD waits until it can talk to the OCD module again, then halts the target.\n * 7. OpenOCD restores the contents of RTC_SLOW_MEM.\n *\n * End result: all the peripherals except RTC_CNTL are reset, CPU's PC is undefined,\n * PRO CPU is halted, APP CPU is in reset.\n */\n\nstatic const uint8_t esp32s3_reset_stub_code[] = {\n#include \"../../../contrib/loaders/reset/espressif/esp32s3/cpu_reset_handler_code.inc\"\n};\n\nstatic int esp32s3_soc_reset(struct target *target)\n{\n\tint res;\n\tstruct target_list *head;\n\tstruct xtensa *xtensa;\n\n\tLOG_DEBUG(\"start\");\n\t/* In order to write to peripheral registers, target must be halted first */\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"Target not halted before SoC reset, trying to halt it first\");\n\t\txtensa_halt(target);\n\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"Couldn't halt target before SoC reset, trying to do reset-halt\");\n\t\t\tres = xtensa_assert_reset(target);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_assert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\tbool reset_halt_save = target->reset_halt;\n\t\t\ttarget->reset_halt = true;\n\t\t\tres = xtensa_deassert_reset(target);\n\t\t\ttarget->reset_halt = reset_halt_save;\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Couldn't halt target before SoC reset! (xtensa_deassert_reset returned %d)\",\n\t\t\t\t\tres);\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\talive_sleep(10);\n\t\t\txtensa_poll(target);\n\t\t\txtensa_halt(target);\n\t\t\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Couldn't halt target before SoC reset\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (target->smp) {\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\txtensa = target_to_xtensa(head->target);\n\t\t\t/* if any of the cores is stalled unstall them */\n\t\t\tif (xtensa_dm_core_is_stalled(&xtensa->dbg_mod)) {\n\t\t\t\tLOG_TARGET_DEBUG(head->target, \"Unstall CPUs before SW reset!\");\n\t\t\t\tres = target_write_u32(target,\n\t\t\t\t\tESP32_S3_RTC_CNTL_SW_CPU_STALL_REG,\n\t\t\t\t\tESP32_S3_RTC_CNTL_SW_CPU_STALL_DEF);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_TARGET_ERROR(head->target, \"Failed to unstall CPUs before SW reset!\");\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\tbreak;\t/* both cores are unstalled now, so exit the loop */\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"Loading stub code into RTC RAM\");\n\tuint8_t slow_mem_save[sizeof(esp32s3_reset_stub_code)];\n\n\t/* Save contents of RTC_SLOW_MEM which we are about to overwrite */\n\tres = target_read_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to save contents of RTC_SLOW_MEM (%d)!\", res);\n\t\treturn res;\n\t}\n\n\t/* Write stub code into RTC_SLOW_MEM */\n\tres = target_write_buffer(target,\n\t\tESP32_S3_RTC_SLOW_MEM_BASE,\n\t\tsizeof(esp32s3_reset_stub_code),\n\t\tesp32s3_reset_stub_code);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write stub (%d)!\", res);\n\t\treturn res;\n\t}\n\n\tLOG_DEBUG(\"Resuming the target\");\n\txtensa = target_to_xtensa(target);\n\txtensa->suppress_dsr_errors = true;\n\tres = xtensa_resume(target, 0, ESP32_S3_RTC_SLOW_MEM_BASE + 4, 0, 0);\n\txtensa->suppress_dsr_errors = false;\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to run stub (%d)!\", res);\n\t\treturn res;\n\t}\n\tLOG_DEBUG(\"resume done, waiting for the target to come alive\");\n\n\t/* Wait for SoC to reset */\n\talive_sleep(100);\n\tint64_t timeout = timeval_ms() + 100;\n\tbool get_timeout = false;\n\twhile (target->state != TARGET_RESET && target->state != TARGET_RUNNING) {\n\t\talive_sleep(10);\n\t\txtensa_poll(target);\n\t\tif (timeval_ms() >= timeout) {\n\t\t\tLOG_TARGET_ERROR(target,\n\t\t\t\t\"Timed out waiting for CPU to be reset, target state=%d\",\n\t\t\t\ttarget->state);\n\t\t\tget_timeout = true;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Halt the CPU again */\n\tLOG_DEBUG(\"halting the target\");\n\txtensa_halt(target);\n\tres = target_wait_state(target, TARGET_HALTED, 1000);\n\tif (res == ERROR_OK) {\n\t\tLOG_DEBUG(\"restoring RTC_SLOW_MEM\");\n\t\tres = target_write_buffer(target, ESP32_S3_RTC_SLOW_MEM_BASE, sizeof(slow_mem_save), slow_mem_save);\n\t\tif (res != ERROR_OK)\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to restore contents of RTC_SLOW_MEM (%d)!\", res);\n\t} else {\n\t\tLOG_TARGET_ERROR(target, \"Timed out waiting for CPU to be halted after SoC reset\");\n\t}\n\n\treturn get_timeout ? ERROR_TARGET_TIMEOUT : res;\n}\n\nstatic int esp32s3_disable_wdts(struct target *target)\n{\n\t/* TIMG1 WDT */\n\tint res = target_write_u32(target, ESP32_S3_TIMG0WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_TIMG0WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S3_TIMG0WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_TIMG0WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* TIMG2 WDT */\n\tres = target_write_u32(target, ESP32_S3_TIMG1WDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_TIMG1WDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S3_TIMG1WDT_CFG0, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_TIMG1WDT_CFG0 (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* RTC WDT */\n\tres = target_write_u32(target, ESP32_S3_RTCWDT_PROTECT, ESP32_S3_WDT_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_RTCWDT_PROTECT (%d)!\", res);\n\t\treturn res;\n\t}\n\tres = target_write_u32(target, ESP32_S3_RTCWDT_CFG, 0);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_RTCWDT_CFG (%d)!\", res);\n\t\treturn res;\n\t}\n\t/* Enable SWD auto-feed */\n\tres = target_write_u32(target, ESP32_S3_SWD_WPROTECT_REG, ESP32_S3_SWD_WKEY_VALUE);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_SWD_WPROTECT_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\tuint32_t swd_conf_reg = 0;\n\tres = target_read_u32(target, ESP32_S3_SWD_CONF_REG, &swd_conf_reg);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read ESP32_S3_SWD_CONF_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\tswd_conf_reg |= ESP32_S3_SWD_AUTO_FEED_EN_M;\n\tres = target_write_u32(target, ESP32_S3_SWD_CONF_REG, swd_conf_reg);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write ESP32_S3_SWD_CONF_REG (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp32s3_on_halt(struct target *target)\n{\n\tint ret = esp32s3_disable_wdts(target);\n\tif (ret == ERROR_OK)\n\t\tret = esp_xtensa_smp_on_halt(target);\n\treturn ret;\n}\n\nstatic int esp32s3_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int esp32s3_virt2phys(struct target *target,\n\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tif (physical) {\n\t\t*physical = virtual;\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic int esp32s3_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\treturn esp_xtensa_smp_target_init(cmd_ctx, target);\n}\n\nstatic const struct xtensa_debug_ops esp32s3_dbg_ops = {\n\t.queue_enable = xtensa_dm_queue_enable,\n\t.queue_reg_read = xtensa_dm_queue_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_reg_write\n};\n\nstatic const struct xtensa_power_ops esp32s3_pwr_ops = {\n\t.queue_reg_read = xtensa_dm_queue_pwr_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_pwr_reg_write\n};\n\nstatic const struct esp_xtensa_smp_chip_ops esp32s3_chip_ops = {\n\t.reset = esp32s3_soc_reset,\n\t.on_halt = esp32s3_on_halt\n};\n\nstatic const struct esp_semihost_ops esp32s3_semihost_ops = {\n\t.prepare = esp32s3_disable_wdts\n};\n\nstatic int esp32s3_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct xtensa_debug_module_config esp32s3_dm_cfg = {\n\t\t.dbg_ops = &esp32s3_dbg_ops,\n\t\t.pwr_ops = &esp32s3_pwr_ops,\n\t\t.tap = target->tap,\n\t\t.queue_tdi_idle = NULL,\n\t\t.queue_tdi_idle_arg = NULL\n\t};\n\n\tstruct esp32s3_common *esp32s3 = calloc(1, sizeof(struct esp32s3_common));\n\tif (!esp32s3) {\n\t\tLOG_ERROR(\"Failed to alloc memory for arch info!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = esp_xtensa_smp_init_arch_info(target,\n\t\t&esp32s3->esp_xtensa_smp,\n\t\t&esp32s3_dm_cfg,\n\t\t&esp32s3_chip_ops,\n\t\t&esp32s3_semihost_ops);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to init arch info!\");\n\t\tfree(esp32s3);\n\t\treturn ret;\n\t}\n\n\t/* Assume running target. If different, the first poll will fix this. */\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration esp32s3_command_handlers[] = {\n\t{\n\t\t.usage = \"\",\n\t\t.chain = esp_xtensa_smp_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp\",\n\t\t.usage = \"\",\n\t\t.chain = esp32_apptrace_command_handlers,\n\t},\n\t{\n\t\t.name = \"esp32\",\n\t\t.usage = \"\",\n\t\t.chain = smp_command_handlers,\n\t},\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = semihosting_common_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/** Holds methods for Xtensa targets. */\nstruct target_type esp32s3_target = {\n\t.name = \"esp32s3\",\n\n\t.poll = esp_xtensa_smp_poll,\n\t.arch_state = esp32s3_arch_state,\n\n\t.halt = xtensa_halt,\n\t.resume = esp_xtensa_smp_resume,\n\t.step = esp_xtensa_smp_step,\n\n\t.assert_reset = esp_xtensa_smp_assert_reset,\n\t.deassert_reset = esp_xtensa_smp_deassert_reset,\n\t.soft_reset_halt = esp_xtensa_smp_soft_reset_halt,\n\n\t.virt2phys = esp32s3_virt2phys,\n\t.mmu = xtensa_mmu_is_enabled,\n\t.read_memory = xtensa_read_memory,\n\t.write_memory = xtensa_write_memory,\n\n\t.read_buffer = xtensa_read_buffer,\n\t.write_buffer = xtensa_write_buffer,\n\n\t.checksum_memory = xtensa_checksum_memory,\n\n\t.get_gdb_arch = xtensa_get_gdb_arch,\n\t.get_gdb_reg_list = xtensa_get_gdb_reg_list,\n\n\t.add_breakpoint = esp_xtensa_breakpoint_add,\n\t.remove_breakpoint = esp_xtensa_breakpoint_remove,\n\n\t.add_watchpoint = esp_xtensa_smp_watchpoint_add,\n\t.remove_watchpoint = esp_xtensa_smp_watchpoint_remove,\n\n\t.target_create = esp32s3_target_create,\n\t.init_target = esp32s3_target_init,\n\t.examine = xtensa_examine,\n\t.deinit_target = esp_xtensa_target_deinit,\n\n\t.commands = esp32s3_command_handlers,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_semihosting.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Semihosting API for Espressif chips                                   *\n *   Copyright (C) 2022 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <target/target.h>\n#include <target/semihosting_common.h>\n#include \"esp_semihosting.h\"\n#include \"esp_xtensa.h\"\n\nstatic struct esp_semihost_data __attribute__((unused)) *target_to_esp_semihost_data(struct target *target)\n{\n\tstruct xtensa *xtensa = target->arch_info;\n\tif (xtensa->common_magic == XTENSA_COMMON_MAGIC)\n\t\treturn &target_to_esp_xtensa(target)->semihost;\n\t/* TODO: add riscv */\n\tLOG_ERROR(\"Unknown target arch!\");\n\treturn NULL;\n}\n\nstatic int esp_semihosting_sys_seek(struct target *target, uint64_t fd, uint32_t pos, size_t whence)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\n\tsemihosting->result = lseek(fd, pos, whence);\n\tsemihosting->sys_errno = errno;\n\tLOG_TARGET_DEBUG(target, \"lseek(%\" PRIx64 \", %\" PRIu32 \" %\" PRId64 \")=%d\", fd, pos, semihosting->result, errno);\n\treturn ERROR_OK;\n}\n\nint esp_semihosting_common(struct target *target)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting)\n\t\t/* Silently ignore if the semihosting field was not set. */\n\t\treturn ERROR_OK;\n\n\tint retval = ERROR_NOT_IMPLEMENTED;\n\n\t/* Enough space to hold 4 long words. */\n\tuint8_t fields[4 * 8];\n\n\t/*\n\t * By default return an error.\n\t * The actual result must be set by each function\n\t */\n\tsemihosting->result = -1;\n\tsemihosting->sys_errno = EIO;\n\n\tLOG_TARGET_DEBUG(target, \"op=0x%x, param=0x%\" PRIx64, semihosting->op, semihosting->param);\n\n\tswitch (semihosting->op) {\n\tcase ESP_SEMIHOSTING_SYS_DRV_INFO:\n\t\t/* Return success to make esp-idf application happy */\n\t\tretval = ERROR_OK;\n\t\tsemihosting->result = 0;\n\t\tsemihosting->sys_errno = 0;\n\t\tbreak;\n\n\tcase ESP_SEMIHOSTING_SYS_SEEK:\n\t\tretval = semihosting_read_fields(target, 3, fields);\n\t\tif (retval == ERROR_OK) {\n\t\t\tuint64_t fd = semihosting_get_field(target, 0, fields);\n\t\t\tuint32_t pos = semihosting_get_field(target, 1, fields);\n\t\t\tsize_t whence = semihosting_get_field(target, 2, fields);\n\t\t\tretval = esp_semihosting_sys_seek(target, fd, pos, whence);\n\t\t}\n\t\tbreak;\n\n\tcase ESP_SEMIHOSTING_SYS_APPTRACE_INIT:\n\tcase ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT:\n\tcase ESP_SEMIHOSTING_SYS_BREAKPOINT_SET:\n\tcase ESP_SEMIHOSTING_SYS_WATCHPOINT_SET:\n\t\t/* For the time being only riscv chips support these commands\n\t\t * TODO: invoke riscv custom command handler */\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nint esp_semihosting_basedir_command(struct command_invocation *cmd)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tif (semihosting->setup(target, true) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to Configure semihosting\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tsemihosting->is_active = true;\n\t}\n\n\tif (CMD_ARGC > 0) {\n\t\tfree(semihosting->basedir);\n\t\tsemihosting->basedir = strdup(CMD_ARGV[0]);\n\t\tif (!semihosting->basedir) {\n\t\t\tcommand_print(CMD, \"semihosting failed to allocate memory for basedir!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"DEPRECATED! semihosting base dir: %s\",\n\t\tsemihosting->basedir ? semihosting->basedir : \"\");\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_semihosting.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Semihosting API for Espressif chips                                   *\n *   Copyright (C) 2022 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP_SEMIHOSTING_H\n#define OPENOCD_TARGET_ESP_SEMIHOSTING_H\n\n/* Legacy syscalls */\n#define ESP_SYS_DRV_INFO_LEGACY                     0xE0\n\n/* syscalls compatible to ARM standard */\n#define ESP_SEMIHOSTING_SYS_DRV_INFO                0x100\n#define ESP_SEMIHOSTING_SYS_APPTRACE_INIT           0x101\n#define ESP_SEMIHOSTING_SYS_DEBUG_STUBS_INIT        0x102\n#define ESP_SEMIHOSTING_SYS_BREAKPOINT_SET          0x103\n#define ESP_SEMIHOSTING_SYS_WATCHPOINT_SET          0x104\n#define ESP_SEMIHOSTING_SYS_SEEK                    0x105\t/* custom lseek with whence */\n/* not implemented yet */\n#define ESP_SEMIHOSTING_SYS_MKDIR                   0x106\n#define ESP_SEMIHOSTING_SYS_OPENDIR                 0x107\n#define ESP_SEMIHOSTING_SYS_READDIR                 0x108\n#define ESP_SEMIHOSTING_SYS_READDIR_R               0x109\n#define ESP_SEMIHOSTING_SYS_SEEKDIR                 0x10A\n#define ESP_SEMIHOSTING_SYS_TELLDIR                 0x10B\n#define ESP_SEMIHOSTING_SYS_CLOSEDIR                0x10C\n#define ESP_SEMIHOSTING_SYS_RMDIR                   0x10D\n#define ESP_SEMIHOSTING_SYS_ACCESS                  0x10E\n#define ESP_SEMIHOSTING_SYS_TRUNCATE                0x10F\n#define ESP_SEMIHOSTING_SYS_UTIME                   0x110\n#define ESP_SEMIHOSTING_SYS_FSTAT                   0x111\n#define ESP_SEMIHOSTING_SYS_STAT                    0x112\n#define ESP_SEMIHOSTING_SYS_FSYNC                   0x113\n#define ESP_SEMIHOSTING_SYS_LINK                    0x114\n#define ESP_SEMIHOSTING_SYS_UNLINK                  0x115\n\n/**\n * Semihost calls handling operations.\n */\nstruct esp_semihost_ops {\n\t/** Callback called before handling semihost call */\n\tint (*prepare)(struct target *target);\n};\n\nstruct esp_semihost_data {\n\tbool need_resume;\n\tstruct esp_semihost_ops *ops;\n};\n\nint esp_semihosting_common(struct target *target);\nint esp_semihosting_basedir_command(struct command_invocation *cmd);\n\n#endif\t/* OPENOCD_TARGET_ESP_SEMIHOSTING_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Espressif Xtensa target API for OpenOCD                               *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <target/smp.h>\n#include \"esp_xtensa_apptrace.h\"\n#include <target/register.h>\n#include \"esp_xtensa.h\"\n#include \"esp_semihosting.h\"\n\n#define ESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(_e_) \\\n\tdo { \\\n\t\tuint32_t __internal_val = (_e_); \\\n\t\tif (!xtensa_data_addr_valid(target, __internal_val)) { \\\n\t\t\tLOG_ERROR(\"No valid stub data entry found (0x%\" PRIx32 \")!\", __internal_val); \\\n\t\t\treturn;\t\\\n\t\t} \\\n\t} while (0)\n\n#define ESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(_e_) \\\n\tdo { \\\n\t\tuint32_t __internal_val = (_e_); \\\n\t\tif (__internal_val == 0) { \\\n\t\t\tLOG_ERROR(\"No valid stub code entry found (0x%\" PRIx32 \")!\", __internal_val); \\\n\t\t\treturn;\t\\\n\t\t} \\\n\t} while (0)\n\nstatic void esp_xtensa_dbgstubs_info_update(struct target *target);\nstatic void esp_xtensa_dbgstubs_addr_check(struct target *target);\n\nstatic int esp_xtensa_dbgstubs_restore(struct target *target)\n{\n\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\n\tif (esp_xtensa->esp.dbg_stubs.base == 0)\n\t\treturn ERROR_OK;\n\n\tLOG_TARGET_INFO(target, \"Restore debug stubs address %\" PRIx32, esp_xtensa->esp.dbg_stubs.base);\n\tint res = esp_xtensa_apptrace_status_reg_write(target, esp_xtensa->esp.dbg_stubs.base);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write trace status (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\nint esp_xtensa_on_halt(struct target *target)\n{\n\t/* debug stubs can be used in HALTED state only, so it is OK to get info about them here */\n\tesp_xtensa_dbgstubs_info_update(target);\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_init_arch_info(struct target *target,\n\tstruct esp_xtensa_common *esp_xtensa,\n\tstruct xtensa_debug_module_config *dm_cfg,\n\tconst struct esp_semihost_ops *semihost_ops)\n{\n\tint ret = xtensa_init_arch_info(target, &esp_xtensa->xtensa, dm_cfg);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tesp_xtensa->semihost.ops = (struct esp_semihost_ops *)semihost_ops;\n\tesp_xtensa->apptrace.hw = &esp_xtensa_apptrace_hw;\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\treturn xtensa_target_init(cmd_ctx, target);\n}\n\nvoid esp_xtensa_target_deinit(struct target *target)\n{\n\tLOG_DEBUG(\"start\");\n\n\tif (target_was_examined(target)) {\n\t\tint ret = esp_xtensa_dbgstubs_restore(target);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn;\n\t}\n\txtensa_target_deinit(target);\n\tfree(target_to_esp_xtensa(target));\t/* same as free(xtensa) */\n}\n\nint esp_xtensa_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_poll(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct esp_xtensa_common *esp_xtensa_common = target_to_esp_xtensa(target);\n\n\tint ret = xtensa_poll(target);\n\n\tif (xtensa_dm_power_status_get(&xtensa->dbg_mod) & PWRSTAT_COREWASRESET(xtensa)) {\n\t\tLOG_TARGET_DEBUG(target, \"Clear debug stubs info\");\n\t\tmemset(&esp_xtensa_common->esp.dbg_stubs, 0, sizeof(esp_xtensa_common->esp.dbg_stubs));\n\t}\n\tif (target->state != TARGET_DEBUG_RUNNING)\n\t\tesp_xtensa_dbgstubs_addr_check(target);\n\treturn ret;\n}\n\nstatic void esp_xtensa_dbgstubs_addr_check(struct target *target)\n{\n\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\tuint32_t vec_addr = 0;\n\n\tif (esp_xtensa->esp.dbg_stubs.base != 0)\n\t\treturn;\n\n\tint res = esp_xtensa_apptrace_status_reg_read(target, &vec_addr);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read debug stubs address location (%d)!\", res);\n\t\treturn;\n\t}\n\tif (xtensa_data_addr_valid(target, vec_addr)) {\n\t\tLOG_TARGET_INFO(target, \"Detected debug stubs @ %\" PRIx32, vec_addr);\n\t\tres = esp_xtensa_apptrace_status_reg_write(target, 0);\n\t\tif (res != ERROR_OK)\n\t\t\tLOG_ERROR(\"Failed to clear debug stubs address location (%d)!\", res);\n\t\tesp_xtensa->esp.dbg_stubs.base = vec_addr;\n\t}\n}\n\nstatic void esp_xtensa_dbgstubs_info_update(struct target *target)\n{\n\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\n\tif (esp_xtensa->esp.dbg_stubs.base == 0 || esp_xtensa->esp.dbg_stubs.entries_count != 0)\n\t\treturn;\n\n\tint res = esp_dbgstubs_table_read(target, &esp_xtensa->esp.dbg_stubs);\n\tif (res != ERROR_OK)\n\t\treturn;\n\tif (esp_xtensa->esp.dbg_stubs.entries_count == 0)\n\t\treturn;\n\n\t/* read debug stubs descriptor */\n\tESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(esp_xtensa->esp.dbg_stubs.entries[ESP_DBG_STUB_DESC]);\n\tres = target_read_buffer(target, esp_xtensa->esp.dbg_stubs.entries[ESP_DBG_STUB_DESC],\n\t\tsizeof(struct esp_dbg_stubs_desc),\n\t\t(uint8_t *)&esp_xtensa->esp.dbg_stubs.desc);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read debug stubs descriptor (%d)!\", res);\n\t\treturn;\n\t}\n\tESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(esp_xtensa->esp.dbg_stubs.desc.tramp_addr);\n\tESP_XTENSA_DBGSTUBS_UPDATE_DATA_ENTRY(esp_xtensa->esp.dbg_stubs.desc.min_stack_addr);\n\tESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(esp_xtensa->esp.dbg_stubs.desc.data_alloc);\n\tESP_XTENSA_DBGSTUBS_UPDATE_CODE_ENTRY(esp_xtensa->esp.dbg_stubs.desc.data_free);\n}\n\nint esp_xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)\n{\n\treturn xtensa_breakpoint_add(target, breakpoint);\n\t/* flash breakpoints will be handled in another patch */\n}\n\nint esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)\n{\n\treturn xtensa_breakpoint_remove(target, breakpoint);\n\t/* flash breakpoints will be handled in another patch */\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Generic ESP xtensa target implementation for OpenOCD                  *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP_XTENSA_H\n#define OPENOCD_TARGET_ESP_XTENSA_H\n\n#include <target/target.h>\n#include <target/xtensa/xtensa.h>\n#include \"esp_semihosting.h\"\n#include \"esp.h\"\n#include \"esp_xtensa_apptrace.h\"\n\nstruct esp_xtensa_common {\n\tstruct xtensa xtensa;\t/* must be the first element */\n\tstruct esp_common esp;\n\tstruct esp_semihost_data semihost;\n\tstruct esp_xtensa_apptrace_info apptrace;\n};\n\nstatic inline struct esp_xtensa_common *target_to_esp_xtensa(struct target *target)\n{\n\treturn container_of(target->arch_info, struct esp_xtensa_common, xtensa);\n}\n\nint esp_xtensa_init_arch_info(struct target *target,\n\tstruct esp_xtensa_common *esp_xtensa,\n\tstruct xtensa_debug_module_config *dm_cfg,\n\tconst struct esp_semihost_ops *semihost_ops);\nint esp_xtensa_target_init(struct command_context *cmd_ctx, struct target *target);\nvoid esp_xtensa_target_deinit(struct target *target);\nint esp_xtensa_arch_state(struct target *target);\nvoid esp_xtensa_queue_tdi_idle(struct target *target);\nint esp_xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);\nint esp_xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);\nint esp_xtensa_poll(struct target *target);\nint esp_xtensa_on_halt(struct target *target);\n\n#endif\t/* OPENOCD_TARGET_ESP_XTENSA_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_apptrace.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Xtensa application tracing module for OpenOCD                         *\n *   Copyright (C) 2017 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n/*\n    How it works?\n    https://github.com/espressif/esp-idf/blob/master/components/app_trace/port/xtensa/port.c#L8\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/align.h>\n#include <target/xtensa/xtensa.h>\n#include <target/xtensa/xtensa_debug_module.h>\n#include \"esp_xtensa_apptrace.h\"\n\n/* TRAX is disabled, so we use its registers for our own purposes\n * | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 |\n */\n#define XTENSA_APPTRACE_CTRL_REG                XDMREG_DELAYCNT\n#define XTENSA_APPTRACE_BLOCK_ID_MSK            0x7FUL\n#define XTENSA_APPTRACE_BLOCK_ID_MAX            XTENSA_APPTRACE_BLOCK_ID_MSK\n/* if non-zero then apptrace code entered the critical section and the value is an address of the\n * critical section's exit point */\n#define XTENSA_APPTRACE_STAT_REG                XDMREG_TRIGGERPC\n\n#define XTENSA_APPTRACE_BLOCK_LEN_MSK           0x7FFFUL\n#define XTENSA_APPTRACE_BLOCK_LEN(_l_)          ((_l_) & XTENSA_APPTRACE_BLOCK_LEN_MSK)\n#define XTENSA_APPTRACE_BLOCK_LEN_GET(_v_)      ((_v_) & XTENSA_APPTRACE_BLOCK_LEN_MSK)\n#define XTENSA_APPTRACE_BLOCK_ID(_id_)          (((_id_) & XTENSA_APPTRACE_BLOCK_ID_MSK) << 15)\n#define XTENSA_APPTRACE_BLOCK_ID_GET(_v_)       (((_v_) >> 15) & XTENSA_APPTRACE_BLOCK_ID_MSK)\n#define XTENSA_APPTRACE_HOST_DATA               BIT(22)\n#define XTENSA_APPTRACE_HOST_CONNECT            BIT(23)\n\nstatic int esp_xtensa_apptrace_leave_crit_section_start(struct target *target);\nstatic int esp_xtensa_apptrace_leave_crit_section_stop(struct target *target);\nstatic int esp_xtensa_apptrace_buffs_write(struct target *target,\n\tuint32_t bufs_num,\n\tuint32_t buf_sz[],\n\tconst uint8_t *bufs[],\n\tuint32_t block_id,\n\tbool ack,\n\tbool data);\n\nstruct esp32_apptrace_hw esp_xtensa_apptrace_hw = {\n\t.max_block_id = XTENSA_APPTRACE_BLOCK_ID_MAX,\n\t.max_block_size_get = esp_xtensa_apptrace_block_max_size_get,\n\t.status_reg_read = esp_xtensa_apptrace_status_reg_read,\n\t.ctrl_reg_write = esp_xtensa_apptrace_ctrl_reg_write,\n\t.ctrl_reg_read = esp_xtensa_apptrace_ctrl_reg_read,\n\t.data_len_read = esp_xtensa_apptrace_data_len_read,\n\t.data_read = esp_xtensa_apptrace_data_read,\n\t.usr_block_max_size_get = esp_xtensa_apptrace_usr_block_max_size_get,\n\t.buffs_write = esp_xtensa_apptrace_buffs_write,\n\t.leave_trace_crit_section_start = esp_xtensa_apptrace_leave_crit_section_start,\n\t.leave_trace_crit_section_stop = esp_xtensa_apptrace_leave_crit_section_stop,\n};\n\nuint32_t esp_xtensa_apptrace_block_max_size_get(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct xtensa_trace_status trace_status;\n\tstruct xtensa_trace_config trace_config;\n\tuint32_t max_trace_block_sz;\n\n\tint res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read TRAX status (%d)!\", res);\n\t\treturn 0;\n\t}\n\n\tmax_trace_block_sz = BIT(((trace_status.stat >> 8) & 0x1f) - 2) * 4;\n\tres = xtensa_dm_trace_config_read(&xtensa->dbg_mod, &trace_config);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read TRAX config (%d)!\", res);\n\t\treturn 0;\n\t}\n\tLOG_DEBUG(\"ctrl=0x%\" PRIx32 \" memadrstart=0x%\" PRIx32 \" memadrend=0x%\" PRIx32 \" traxadr=0x%\" PRIx32,\n\t\ttrace_config.ctrl,\n\t\ttrace_config.memaddr_start,\n\t\ttrace_config.memaddr_end,\n\t\ttrace_config.addr);\n\n\treturn max_trace_block_sz;\n}\n\nuint32_t esp_xtensa_apptrace_usr_block_max_size_get(struct target *target)\n{\n\treturn esp_xtensa_apptrace_block_max_size_get(target) - sizeof(struct esp_apptrace_host2target_hdr);\n}\n\nint esp_xtensa_apptrace_data_len_read(struct target *target,\n\tuint32_t *block_id,\n\tuint32_t *len)\n{\n\treturn esp_xtensa_apptrace_ctrl_reg_read(target, block_id, len, NULL);\n}\n\nint esp_xtensa_apptrace_usr_block_write(struct target *target,\n\tuint32_t block_id,\n\tconst uint8_t *data,\n\tuint32_t size)\n{\n\treturn esp_apptrace_usr_block_write(&esp_xtensa_apptrace_hw, target, block_id, data, size);\n}\n\nstatic int esp_xtensa_apptrace_data_reverse_read(struct xtensa *xtensa,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tuint8_t *unal_bytes)\n{\n\tint res = 0;\n\tuint32_t rd_sz = ALIGN_UP(size, 4);\n\n\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, (xtensa->core_config->trace.mem_sz - rd_sz) / 4);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (!IS_ALIGNED(size, 4)) {\n\t\tres = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, unal_bytes);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\tfor (unsigned int i = size / 4; i != 0; i--) {\n\t\tres = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, &buffer[(i - 1) * 4]);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_data_normal_read(struct xtensa *xtensa,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tuint8_t *unal_bytes)\n{\n\tint res = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, 0);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tfor (unsigned int i = 0; i < size / 4; i++) {\n\t\tres = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, &buffer[i * 4]);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\tif (!IS_ALIGNED(size, 4)) {\n\t\tres = xtensa_queue_dbg_reg_read(xtensa, XDMREG_TRAXDATA, unal_bytes);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_apptrace_data_read(struct target *target,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tuint32_t block_id,\n\tbool ack)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res;\n\tuint32_t tmp = XTENSA_APPTRACE_HOST_CONNECT | XTENSA_APPTRACE_BLOCK_ID(block_id) |\n\t\tXTENSA_APPTRACE_BLOCK_LEN(0);\n\tuint8_t unal_bytes[4];\n\n\tLOG_DEBUG(\"Read data on target (%s)\", target_name(target));\n\tif (xtensa->core_config->trace.reversed_mem_access)\n\t\tres = esp_xtensa_apptrace_data_reverse_read(xtensa, size, buffer, unal_bytes);\n\telse\n\t\tres = esp_xtensa_apptrace_data_normal_read(xtensa, size, buffer, unal_bytes);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (ack) {\n\t\tLOG_DEBUG(\"Ack block %\" PRIu32 \" target (%s)!\", block_id, target_name(target));\n\t\tres = xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exec JTAG queue!\");\n\t\treturn res;\n\t}\n\tif (!IS_ALIGNED(size, 4)) {\n\t\t/* copy the last unaligned bytes */\n\t\tmemcpy(buffer + ALIGN_DOWN(size, 4), unal_bytes, size & 0x3UL);\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_apptrace_ctrl_reg_write(struct target *target,\n\tuint32_t block_id,\n\tuint32_t len,\n\tbool conn,\n\tbool data)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint32_t tmp = (conn ? XTENSA_APPTRACE_HOST_CONNECT : 0) |\n\t\t(data ? XTENSA_APPTRACE_HOST_DATA : 0) | XTENSA_APPTRACE_BLOCK_ID(block_id) |\n\t\tXTENSA_APPTRACE_BLOCK_LEN(len);\n\n\txtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exec JTAG queue!\");\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_apptrace_ctrl_reg_read(struct target *target,\n\tuint32_t *block_id,\n\tuint32_t *len,\n\tbool *conn)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint8_t tmp[4];\n\n\txtensa_queue_dbg_reg_read(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tuint32_t val = target_buffer_get_u32(target, tmp);\n\tif (block_id)\n\t\t*block_id = XTENSA_APPTRACE_BLOCK_ID_GET(val);\n\tif (len)\n\t\t*len = XTENSA_APPTRACE_BLOCK_LEN_GET(val);\n\tif (conn)\n\t\t*conn = val & XTENSA_APPTRACE_HOST_CONNECT;\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_apptrace_status_reg_read(struct target *target, uint32_t *stat)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint8_t tmp[4];\n\n\tint res = xtensa_queue_dbg_reg_read(xtensa, XTENSA_APPTRACE_STAT_REG, tmp);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exec JTAG queue!\");\n\t\treturn res;\n\t}\n\t*stat = buf_get_u32(tmp, 0, 32);\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_apptrace_status_reg_write(struct target *target, uint32_t stat)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\txtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_STAT_REG, stat);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exec JTAG queue!\");\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_swdbg_activate(struct target *target, int enab)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\txtensa_queue_dbg_reg_write(xtensa, enab ? XDMREG_DCRSET : XDMREG_DCRCLR, OCDDCR_DEBUGSWACTIVE);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: writing DCR failed!\", target->cmd_name);\n\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_leave_crit_section_start(struct target *target)\n{\n\t/* TODO: not sure that we need this, but it seems that we fail to leave tracing critical\n\t *section w/o this */\n\tint res = esp_xtensa_swdbg_activate(target, 1 /*enable*/);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to activate SW debug (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_leave_crit_section_stop(struct target *target)\n{\n\tint res = esp_xtensa_swdbg_activate(target, 0 /*disable*/);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to activate SW debug (%d)!\", res);\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_queue_reverse_write(struct target *target, uint32_t bufs_num,\n\tuint32_t buf_sz[], const uint8_t *bufs[])\n{\n\tint res = ERROR_OK;\n\tuint32_t cached_bytes = 0, total_sz = 0;\n\tuint8_t cached_data8[sizeof(uint32_t)] = { 0 };\n\tuint32_t cached_data32 = 0;\n\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tfor (uint32_t i = 0; i < bufs_num; i++)\n\t\ttotal_sz += buf_sz[i];\n\tif (!IS_ALIGNED(total_sz, 4)) {\n\t\tcached_bytes = sizeof(uint32_t) - (total_sz & 0x3UL);\n\t\ttotal_sz = ALIGN_UP(total_sz, 4);\n\t}\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, (xtensa->core_config->trace.mem_sz - total_sz) / 4);\n\tfor (uint32_t i = bufs_num; i > 0; i--) {\n\t\tuint32_t bsz = buf_sz[i - 1];\n\t\tconst uint8_t *cur_buf = &bufs[i - 1][bsz];\n\t\tuint32_t bytes_to_cache;\n\t\t/* if there are cached bytes from the previous buffer, combine them with the last\n\t\t * from the current buffer */\n\t\tif (cached_bytes) {\n\t\t\tif ((cached_bytes + bsz) < sizeof(uint32_t))\n\t\t\t\tbytes_to_cache = bsz;\n\t\t\telse\n\t\t\t\tbytes_to_cache = sizeof(uint32_t) - cached_bytes;\n\t\t\tmemcpy(&cached_data8[sizeof(uint32_t) - cached_bytes - bytes_to_cache],\n\t\t\t\tcur_buf - bytes_to_cache,\n\t\t\t\tbytes_to_cache);\n\t\t\tcached_data32 = target_buffer_get_u32(target, cached_data8);\n\t\t\tcached_bytes += bytes_to_cache;\n\t\t\tif (cached_bytes < sizeof(uint32_t))\n\t\t\t\tcontinue;\n\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\tbsz -= bytes_to_cache;\n\t\t\tcur_buf -= bytes_to_cache;\n\t\t\tmemset(cached_data8, 0x00, sizeof(cached_data8));\n\t\t\tcached_bytes = 0;\n\t\t}\n\t\t/* write full dwords */\n\t\tfor (unsigned int k = bsz; k >= sizeof(uint32_t); k -= sizeof(uint32_t)) {\n\t\t\tuint32_t temp = target_buffer_get_u32(target, cur_buf - sizeof(uint32_t));\n\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, temp);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\tcur_buf -= sizeof(uint32_t);\n\t\t}\n\t\t/* if there are bytes to be cached (1..3) */\n\t\tbytes_to_cache = bsz & 0x3UL;\n\t\tif (bytes_to_cache > 0) {\n\t\t\tif (bytes_to_cache + cached_bytes >= sizeof(uint32_t)) {\n\t\t\t\t/* filling the cache buffer from the end to beginning */\n\t\t\t\tuint32_t to_copy = sizeof(uint32_t) - cached_bytes;\n\t\t\t\tmemcpy(&cached_data8[0], cur_buf - to_copy, to_copy);\n\t\t\t\tcached_data32 = target_buffer_get_u32(target, cached_data8);\n\t\t\t\t/* write full word of cached bytes */\n\t\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32);\n\t\t\t\tif (res != ERROR_OK)\n\t\t\t\t\treturn res;\n\t\t\t\t/* cache remaining bytes */\n\t\t\t\tmemset(cached_data8, 0x00, sizeof(cached_data8));\n\t\t\t\tcur_buf -= to_copy;\n\t\t\t\tto_copy = bytes_to_cache + cached_bytes - sizeof(uint32_t);\n\t\t\t\tmemcpy(&cached_data8[sizeof(uint32_t) - to_copy], cur_buf - to_copy, to_copy);\n\t\t\t\tcached_bytes = to_copy;\n\t\t\t} else {\n\t\t\t\t/* filling the cache buffer from the end to beginning */\n\t\t\t\tmemcpy(&cached_data8[sizeof(uint32_t) - cached_bytes - bytes_to_cache],\n\t\t\t\t\tcur_buf - bytes_to_cache,\n\t\t\t\t\tbytes_to_cache);\n\t\t\t\tcached_bytes += bytes_to_cache;\n\t\t\t}\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_queue_normal_write(struct target *target, uint32_t bufs_num,\n\tuint32_t buf_sz[], const uint8_t *bufs[])\n{\n\tint res = ERROR_OK;\n\tuint32_t cached_bytes = 0;\n\tuint8_t cached_data8[4] = { 0 };\n\tuint32_t cached_data32 = 0;\n\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\t/* | 1 |   2   | 1 | 2     |       4       |.......|\n\t * |       4       |       4       |       4       | */\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXADDR, 0);\n\tfor (unsigned int i = 0; i < bufs_num; i++) {\n\t\tuint32_t bsz = buf_sz[i];\n\t\tconst uint8_t *cur_buf = bufs[i];\n\t\tuint32_t bytes_to_cache;\n\t\t/* if there are cached bytes from the previous buffer, combine them with the last\n\t\t * from the current buffer */\n\t\tif (cached_bytes) {\n\t\t\tif ((cached_bytes + bsz) < sizeof(uint32_t))\n\t\t\t\tbytes_to_cache = bsz;\n\t\t\telse\n\t\t\t\tbytes_to_cache = sizeof(uint32_t) - cached_bytes;\n\t\t\tmemcpy(&cached_data8[cached_bytes], cur_buf, bytes_to_cache);\n\t\t\tcached_bytes += bytes_to_cache;\n\t\t\tif (cached_bytes < sizeof(uint32_t))\n\t\t\t\tcontinue;\n\t\t\tcached_data32 = target_buffer_get_u32(target, cached_data8);\n\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\tbsz -= bytes_to_cache;\n\t\t\tcur_buf += bytes_to_cache;\n\t\t\tmemset(cached_data8, 0x00, sizeof(cached_data8));\n\t\t\tcached_bytes = 0;\n\t\t}\n\t\t/* write full dwords */\n\t\tfor (unsigned int k = 0; (k + sizeof(uint32_t)) <= bsz; k += sizeof(uint32_t)) {\n\t\t\tuint32_t temp = target_buffer_get_u32(target, cur_buf);\n\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, temp);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t\tcur_buf += sizeof(uint32_t);\n\t\t}\n\t\t/* if there are bytes to be cached (1..3) */\n\t\tbytes_to_cache = bsz & 0x3UL;\n\t\tif (bytes_to_cache > 0) {\n\t\t\tif (bytes_to_cache + cached_bytes >= sizeof(uint32_t)) {\n\t\t\t\tmemcpy(&cached_data8[0], cur_buf, sizeof(uint32_t) - cached_bytes);\n\t\t\t\tcached_data32 = target_buffer_get_u32(target, cached_data8);\n\t\t\t\t/* write full word of cached bytes */\n\t\t\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32);\n\t\t\t\tif (res != ERROR_OK)\n\t\t\t\t\treturn res;\n\t\t\t\t/* cache remaining bytes */\n\t\t\t\tmemset(cached_data8, 0x00, sizeof(cached_data8));\n\t\t\t\tcur_buf += sizeof(uint32_t) - cached_bytes;\n\t\t\t\tcached_bytes = bytes_to_cache + cached_bytes - sizeof(uint32_t);\n\t\t\t\tmemcpy(&cached_data8[0], cur_buf, cached_bytes);\n\t\t\t} else {\n\t\t\t\tmemcpy(&cached_data8[cached_bytes], cur_buf, bytes_to_cache);\n\t\t\t\tcached_bytes += bytes_to_cache;\n\t\t\t}\n\t\t}\n\t}\n\tif (cached_bytes) {\n\t\t/* write remaining cached bytes */\n\t\tcached_data32 = target_buffer_get_u32(target, cached_data8);\n\t\tres = xtensa_queue_dbg_reg_write(xtensa, XDMREG_TRAXDATA, cached_data32);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_apptrace_buffs_write(struct target *target,\n\tuint32_t bufs_num,\n\tuint32_t buf_sz[],\n\tconst uint8_t *bufs[],\n\tuint32_t block_id,\n\tbool ack,\n\tbool data)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res = ERROR_OK;\n\tuint32_t tmp = XTENSA_APPTRACE_HOST_CONNECT |\n\t\t(data ? XTENSA_APPTRACE_HOST_DATA : 0) | XTENSA_APPTRACE_BLOCK_ID(block_id) |\n\t\tXTENSA_APPTRACE_BLOCK_LEN(0);\n\n\tif (xtensa->core_config->trace.reversed_mem_access)\n\t\tres = esp_xtensa_apptrace_queue_reverse_write(target, bufs_num, buf_sz, bufs);\n\telse\n\t\tres = esp_xtensa_apptrace_queue_normal_write(target, bufs_num, buf_sz, bufs);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (ack) {\n\t\tLOG_DEBUG(\"Ack block %\" PRId32 \" on target (%s)!\", block_id, target_name(target));\n\t\tres = xtensa_queue_dbg_reg_write(xtensa, XTENSA_APPTRACE_CTRL_REG, tmp);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to exec JTAG queue!\");\n\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_apptrace.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Xtensa application tracing module for OpenOCD                         *\n *   Copyright (C) 2017 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H\n#define OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H\n\n#include \"esp32_apptrace.h\"\n\nstruct esp_xtensa_apptrace_info {\n\tconst struct esp32_apptrace_hw *hw;\n};\n\nextern struct esp32_apptrace_hw esp_xtensa_apptrace_hw;\n\nint esp_xtensa_apptrace_data_len_read(struct target *target, uint32_t *block_id, uint32_t *len);\nint esp_xtensa_apptrace_data_read(struct target *target,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tuint32_t block_id,\n\tbool ack);\nint esp_xtensa_apptrace_ctrl_reg_read(struct target *target, uint32_t *block_id, uint32_t *len, bool *conn);\nint esp_xtensa_apptrace_ctrl_reg_write(struct target *target,\n\tuint32_t block_id,\n\tuint32_t len,\n\tbool conn,\n\tbool data);\nint esp_xtensa_apptrace_status_reg_write(struct target *target, uint32_t stat);\nint esp_xtensa_apptrace_status_reg_read(struct target *target, uint32_t *stat);\nuint32_t esp_xtensa_apptrace_block_max_size_get(struct target *target);\nuint32_t esp_xtensa_apptrace_usr_block_max_size_get(struct target *target);\nint esp_xtensa_apptrace_usr_block_write(struct target *target, uint32_t block_id, const uint8_t *data, uint32_t size);\n\n#endif\t/* OPENOCD_TARGET_ESP_XTENSA_APPTRACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_semihosting.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd.              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <target/semihosting_common.h>\n#include <target/xtensa/xtensa_regs.h>\n#include <target/xtensa/xtensa.h>\n#include \"esp_xtensa.h\"\n#include \"esp_xtensa_semihosting.h\"\n\n#define ESP_XTENSA_SYSCALL              0x41E0\t/* XT_INS_BREAK(1, 14) */\n#define ESP_XTENSA_SYSCALL_SZ           3\n\n#define XTENSA_SYSCALL_OP_REG           XT_REG_IDX_A2\n#define XTENSA_SYSCALL_RETVAL_REG       XT_REG_IDX_A2\n#define XTENSA_SYSCALL_ERRNO_REG        XT_REG_IDX_A3\n\nstatic int esp_xtensa_semihosting_setup(struct target *target, int enable)\n{\n\tLOG_TARGET_DEBUG(target, \"semihosting enable=%d\", enable);\n\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_semihosting_post_result(struct target *target)\n{\n\t/* Even with the v2 and later, errno will not retrieved from A3 reg, it is safe to set */\n\txtensa_reg_set(target, XTENSA_SYSCALL_RETVAL_REG, target->semihosting->result);\n\txtensa_reg_set(target, XTENSA_SYSCALL_ERRNO_REG, target->semihosting->sys_errno);\n\treturn ERROR_OK;\n}\n\n/**\n * Checks and processes an ESP Xtensa semihosting request. This is meant\n * to be called when the target is stopped due to a debug mode entry.\n * If the value 0 is returned then there was nothing to process. A non-zero\n * return value signifies that a request was processed and the target resumed,\n * or an error was encountered, in which case the caller must return immediately.\n *\n * @param target Pointer to the ESP Xtensa target to process.\n * @param retval Pointer to a location where the return code will be stored\n * @return SEMIHOSTING_HANDLED if a request was processed or SEMIHOSTING_NONE with the proper retval\n */\nint esp_xtensa_semihosting(struct target *target, int *retval)\n{\n\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\n\txtensa_reg_val_t dbg_cause = xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);\n\tif ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0)\n\t\treturn SEMIHOSTING_NONE;\n\n\tuint8_t brk_insn_buf[sizeof(uint32_t)] = { 0 };\n\txtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);\n\t*retval = target_read_memory(target, pc, ESP_XTENSA_SYSCALL_SZ, 1, brk_insn_buf);\n\tif (*retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to read break instruction!\");\n\t\treturn SEMIHOSTING_NONE;\n\t}\n\n\tuint32_t syscall_ins = buf_get_u32(brk_insn_buf, 0, 32);\n\tif (syscall_ins != ESP_XTENSA_SYSCALL) {\n\t\t*retval = ERROR_OK;\n\t\treturn SEMIHOSTING_NONE;\n\t}\n\n\tif (esp_xtensa->semihost.ops && esp_xtensa->semihost.ops->prepare)\n\t\tesp_xtensa->semihost.ops->prepare(target);\n\n\txtensa_reg_val_t a2 = xtensa_reg_get(target, XT_REG_IDX_A2);\n\txtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);\n\tLOG_TARGET_DEBUG(target, \"Semihosting call 0x%\" PRIx32 \" 0x%\" PRIx32 \" Base dir '%s'\",\n\t\ta2,\n\t\ta3,\n\t\ttarget->semihosting->basedir ? target->semihosting->basedir : \"\");\n\n\ttarget->semihosting->op = a2;\n\ttarget->semihosting->param = a3;\n\n\t*retval = semihosting_common(target);\n\n\t/* Most operations are resumable, except the two exit calls. */\n\tif (*retval != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Semihosting operation (op: 0x%x) error! Code: %d\",\n\t\t\ttarget->semihosting->op,\n\t\t\t*retval);\n\t}\n\n\t/* Resume if target it is resumable and we are not waiting on a fileio operation to complete. */\n\tif (target->semihosting->is_resumable && !target->semihosting->hit_fileio)\n\t\ttarget_to_esp_xtensa(target)->semihost.need_resume = true;\n\n\treturn SEMIHOSTING_HANDLED;\n}\n\nstatic int xtensa_semihosting_init(struct target *target)\n{\n\treturn semihosting_common_init(target, esp_xtensa_semihosting_setup, esp_xtensa_semihosting_post_result);\n}\n\nint esp_xtensa_semihosting_init(struct target *target)\n{\n\tint retval = xtensa_semihosting_init(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget->semihosting->word_size_bytes = 4;\t\t\t/* 32 bits */\n\ttarget->semihosting->user_command_extension = esp_semihosting_common;\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_semihosting.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (c) 2020 Espressif Systems (Shanghai) Co. Ltd.              *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H\n#define OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H\n\n#include <target/target.h>\n\nint esp_xtensa_semihosting_init(struct target *target);\nint esp_xtensa_semihosting(struct target *target, int *retval);\n\n#endif\t/* OPENOCD_TARGET_ESP_XTENSA_SEMIHOSTING_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_smp.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   ESP Xtensa SMP target API for OpenOCD                                 *\n *   Copyright (C) 2020 Espressif Systems Ltd. Co                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"assert.h\"\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/smp.h>\n#include <target/semihosting_common.h>\n#include \"esp_xtensa_smp.h\"\n#include \"esp_xtensa_semihosting.h\"\n\n/*\nMultiprocessor stuff common:\n\nThe ESP Xtensa chip can have several cores in it, which can run in SMP-mode if an\nSMP-capable OS is running. The hardware has a few features which makes\nSMP debugging much easier.\n\nFirst of all, there's something called a 'break network', consisting of a\nBreakIn input  and a BreakOut output on each CPU. The idea is that as soon\nas a CPU goes into debug mode for whatever reason, it'll signal that using\nits DebugOut pin. This signal is connected to the other CPU's DebugIn\ninput, causing this CPU also to go into debugging mode. To resume execution\nwhen using only this break network, we will need to manually resume both\nCPUs.\n\nAn alternative to this is the XOCDMode output and the RunStall (or DebugStall)\ninput. When these are cross-connected, a CPU that goes into debug mode will\nhalt execution entirely on the other CPU. Execution on the other CPU can be\nresumed by either the first CPU going out of debug mode, or the second CPU\ngoing into debug mode: the stall is temporarily lifted as long as the stalled\nCPU is in debug mode.\n\nA third, separate, signal is CrossTrigger. This is connected in the same way\nas the breakIn/breakOut network, but is for the TRAX (trace memory) feature;\nit does not affect OCD in any way.\n*/\n\n/*\nMultiprocessor stuff:\n\nThe ESP Xtensa chip has several Xtensa cores inside, but represent themself to the OCD\nas one chip that works in multithreading mode under FreeRTOS OS.\nThe core that initiate the stop condition will be defined as an active cpu.\nWhen one core stops, then other core will be stopped automatically by smpbreak.\nThe core that initiates stop condition will be defined as an active core, and\nregisters of this core will be transferred.\n*/\n\n#define ESP_XTENSA_SMP_EXAMINE_OTHER_CORES      5\n\nstatic int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume);\n\nstatic inline struct esp_xtensa_smp_common *target_to_esp_xtensa_smp(struct target *target)\n{\n\treturn container_of(target->arch_info, struct esp_xtensa_smp_common, esp_xtensa);\n}\n\nint esp_xtensa_smp_assert_reset(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_deassert_reset(struct target *target)\n{\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\n\tint ret = xtensa_deassert_reset(target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\t/* in SMP mode when chip was running single-core app the other core can be left un-examined,\n\t   because examination is done before SOC reset. But after SOC reset it is functional and should be handled.\n\t   So try to examine un-examined core just after SOC reset */\n\tif (target->smp && !target_was_examined(target))\n\t\tret = xtensa_examine(target);\n\treturn ret;\n}\n\nint esp_xtensa_smp_soft_reset_halt(struct target *target)\n{\n\tint res;\n\tstruct target_list *head;\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);\n\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\t/* in SMP mode we need to ensure that at first we reset SOC on PRO-CPU\n\t   and then call xtensa_assert_reset() for all cores */\n\tif (target->smp && target->coreid != 0)\n\t\treturn ERROR_OK;\n\t/* Reset the SoC first */\n\tif (esp_xtensa_smp->chip_ops->reset) {\n\t\tres = esp_xtensa_smp->chip_ops->reset(target);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\tif (!target->smp)\n\t\treturn xtensa_assert_reset(target);\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tres = xtensa_assert_reset(head->target);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_on_halt(struct target *target)\n{\n\tstruct target_list *head;\n\n\tif (!target->smp)\n\t\treturn esp_xtensa_on_halt(target);\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tint res = esp_xtensa_on_halt(head->target);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic struct target *get_halted_esp_xtensa_smp(struct target *target, int32_t coreid)\n{\n\tstruct target_list *head;\n\tstruct target *curr;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tcurr = head->target;\n\t\tif ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))\n\t\t\treturn curr;\n\t}\n\n\treturn target;\n}\n\nint esp_xtensa_smp_poll(struct target *target)\n{\n\tenum target_state old_state = target->state;\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);\n\tstruct esp_xtensa_common *esp_xtensa = target_to_esp_xtensa(target);\n\tuint32_t old_dbg_stubs_base = esp_xtensa->esp.dbg_stubs.base;\n\tstruct target_list *head;\n\tstruct target *curr;\n\tbool other_core_resume_req = false;\n\n\tif (target->state == TARGET_HALTED && target->smp && target->gdb_service && !target->gdb_service->target) {\n\t\ttarget->gdb_service->target = get_halted_esp_xtensa_smp(target, target->gdb_service->core[1]);\n\t\tLOG_INFO(\"Switch GDB target to '%s'\", target_name(target->gdb_service->target));\n\t\tif (esp_xtensa_smp->chip_ops->on_halt)\n\t\t\tesp_xtensa_smp->chip_ops->on_halt(target);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\treturn ERROR_OK;\n\t}\n\n\tint ret = esp_xtensa_poll(target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (esp_xtensa->esp.dbg_stubs.base && old_dbg_stubs_base != esp_xtensa->esp.dbg_stubs.base) {\n\t\t/* debug stubs base is set only in PRO-CPU TRAX register, so sync this info */\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tif (curr == target)\n\t\t\t\tcontinue;\n\t\t\ttarget_to_esp_xtensa(curr)->esp.dbg_stubs.base = esp_xtensa->esp.dbg_stubs.base;\n\t\t}\n\t}\n\n\tif (target->smp) {\n\t\tif (target->state == TARGET_RESET) {\n\t\t\tesp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES;\n\t\t} else if (esp_xtensa_smp->examine_other_cores > 0 &&\n\t\t\t(target->state == TARGET_RUNNING || target->state == TARGET_HALTED)) {\n\t\t\tLOG_TARGET_DEBUG(target, \"Check for unexamined cores after reset\");\n\t\t\tbool all_examined = true;\n\t\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\t\tcurr = head->target;\n\t\t\t\tif (curr == target)\n\t\t\t\t\tcontinue;\n\t\t\t\tif (!target_was_examined(curr)) {\n\t\t\t\t\tif (target_examine_one(curr) != ERROR_OK) {\n\t\t\t\t\t\tLOG_DEBUG(\"Failed to examine!\");\n\t\t\t\t\t\tall_examined = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (all_examined)\n\t\t\t\tesp_xtensa_smp->examine_other_cores = 0;\n\t\t\telse\n\t\t\t\tesp_xtensa_smp->examine_other_cores--;\n\t\t}\n\t}\n\n\tif (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {\n\t\tif (target->smp) {\n\t\t\tret = esp_xtensa_smp_update_halt_gdb(target, &other_core_resume_req);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\t/* Call any event callbacks that are applicable */\n\t\tif (old_state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t} else {\n\t\t\tif (esp_xtensa_semihosting(target, &ret) == SEMIHOSTING_HANDLED) {\n\t\t\t\tif (ret == ERROR_OK && esp_xtensa->semihost.need_resume &&\n\t\t\t\t\t!esp_xtensa_smp->other_core_does_resume) {\n\t\t\t\t\tesp_xtensa->semihost.need_resume = false;\n\t\t\t\t\t/* Resume xtensa_resume will handle BREAK instruction. */\n\t\t\t\t\tret = target_resume(target, 1, 0, 1, 0);\n\t\t\t\t\tif (ret != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"Failed to resume target\");\n\t\t\t\t\t\treturn ret;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\t/* check whether any core polled by esp_xtensa_smp_update_halt_gdb() requested resume */\n\t\t\tif (target->smp && other_core_resume_req) {\n\t\t\t\t/* Resume xtensa_resume will handle BREAK instruction. */\n\t\t\t\tret = target_resume(target, 1, 0, 1, 0);\n\t\t\t\tif (ret != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Failed to resume target\");\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tif (esp_xtensa_smp->chip_ops->on_halt)\n\t\t\t\tesp_xtensa_smp->chip_ops->on_halt(target);\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int esp_xtensa_smp_update_halt_gdb(struct target *target, bool *need_resume)\n{\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp;\n\tstruct target *gdb_target = NULL;\n\tstruct target_list *head;\n\tstruct target *curr;\n\tint ret = ERROR_OK;\n\n\t*need_resume = false;\n\n\tif (target->gdb_service && target->gdb_service->target)\n\t\tLOG_DEBUG(\"GDB target '%s'\", target_name(target->gdb_service->target));\n\n\tif (target->gdb_service && target->gdb_service->core[0] == -1) {\n\t\ttarget->gdb_service->target = target;\n\t\ttarget->gdb_service->core[0] = target->coreid;\n\t\tLOG_INFO(\"Set GDB target to '%s'\", target_name(target));\n\t}\n\n\tif (target->gdb_service)\n\t\tgdb_target = target->gdb_service->target;\n\n\t/* due to smpbreak config other cores can also go to HALTED state */\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tcurr = head->target;\n\t\tLOG_DEBUG(\"Check target '%s'\", target_name(curr));\n\t\t/* skip calling context */\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\tif (!target_was_examined(curr)) {\n\t\t\tcurr->state = TARGET_HALTED;\n\t\t\tcontinue;\n\t\t}\n\t\t/* skip targets that were already halted */\n\t\tif (curr->state == TARGET_HALTED)\n\t\t\tcontinue;\n\t\t/* Skip gdb_target; it alerts GDB so has to be polled as last one */\n\t\tif (curr == gdb_target)\n\t\t\tcontinue;\n\t\tLOG_DEBUG(\"Poll target '%s'\", target_name(curr));\n\n\t\tesp_xtensa_smp = target_to_esp_xtensa_smp(curr);\n\t\t/* avoid auto-resume after syscall, it will be done later */\n\t\tesp_xtensa_smp->other_core_does_resume = true;\n\t\t/* avoid recursion in esp_xtensa_smp_poll() */\n\t\tcurr->smp = 0;\n\t\tif (esp_xtensa_smp->chip_ops->poll)\n\t\t\tret = esp_xtensa_smp->chip_ops->poll(curr);\n\t\telse\n\t\t\tret = esp_xtensa_smp_poll(curr);\n\t\tcurr->smp = 1;\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t\tesp_xtensa_smp->other_core_does_resume = false;\n\t\tstruct esp_xtensa_common *curr_esp_xtensa = target_to_esp_xtensa(curr);\n\t\tif (curr_esp_xtensa->semihost.need_resume) {\n\t\t\tcurr_esp_xtensa->semihost.need_resume = false;\n\t\t\t*need_resume = true;\n\t\t}\n\t}\n\n\t/* after all targets were updated, poll the gdb serving target */\n\tif (gdb_target && gdb_target != target) {\n\t\tesp_xtensa_smp = target_to_esp_xtensa_smp(gdb_target);\n\t\tif (esp_xtensa_smp->chip_ops->poll)\n\t\t\tret = esp_xtensa_smp->chip_ops->poll(gdb_target);\n\t\telse\n\t\t\tret = esp_xtensa_smp_poll(gdb_target);\n\t}\n\n\tLOG_DEBUG(\"exit\");\n\n\treturn ret;\n}\n\nstatic inline int esp_xtensa_smp_smpbreak_disable(struct target *target, uint32_t *smp_break)\n{\n\tint res = xtensa_smpbreak_get(target, smp_break);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\treturn xtensa_smpbreak_set(target, 0);\n}\n\nstatic inline int esp_xtensa_smp_smpbreak_restore(struct target *target, uint32_t smp_break)\n{\n\treturn xtensa_smpbreak_set(target, smp_break);\n}\n\nstatic int esp_xtensa_smp_resume_cores(struct target *target,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tstruct target_list *head;\n\tstruct target *curr;\n\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tcurr = head->target;\n\t\t/* in single-core mode disabled core cannot be examined, but need to be resumed too*/\n\t\tif ((curr != target) && (curr->state != TARGET_RUNNING) && target_was_examined(curr)) {\n\t\t\t/*  resume current address, not in SMP mode */\n\t\t\tcurr->smp = 0;\n\t\t\tint res = esp_xtensa_smp_resume(curr, 1, 0, handle_breakpoints, debug_execution);\n\t\t\tcurr->smp = 1;\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tint res;\n\tuint32_t smp_break;\n\n\txtensa_smpbreak_get(target, &smp_break);\n\tLOG_TARGET_DEBUG(target, \"smp_break=0x%\" PRIx32, smp_break);\n\n\t/* dummy resume for smp toggle in order to reduce gdb impact  */\n\tif ((target->smp) && (target->gdb_service) && (target->gdb_service->core[1] != -1)) {\n\t\t/* simulate a start and halt of target */\n\t\ttarget->gdb_service->target = NULL;\n\t\ttarget->gdb_service->core[0] = target->gdb_service->core[1];\n\t\t/* fake resume at next poll we play the  target core[1], see poll*/\n\t\tLOG_TARGET_DEBUG(target, \"Fake resume\");\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* xtensa_prepare_resume() can step over breakpoint/watchpoint and generate signals on BreakInOut circuit for\n\t * other cores. So disconnect this core from BreakInOut circuit and do xtensa_prepare_resume(). */\n\tres = esp_xtensa_smp_smpbreak_disable(target, &smp_break);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tres = xtensa_prepare_resume(target, current, address, handle_breakpoints, debug_execution);\n\t/* restore configured BreakInOut signals config */\n\tint ret = esp_xtensa_smp_smpbreak_restore(target, smp_break);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to prepare for resume!\");\n\t\treturn res;\n\t}\n\n\tif (target->smp) {\n\t\tif (target->gdb_service)\n\t\t\ttarget->gdb_service->core[0] = -1;\n\t\tres = esp_xtensa_smp_resume_cores(target, handle_breakpoints, debug_execution);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\tres = xtensa_do_resume(target);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to resume!\");\n\t\treturn res;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\tif (!debug_execution)\n\t\ttarget->state = TARGET_RUNNING;\n\telse\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_step(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints)\n{\n\tint res;\n\tuint32_t smp_break = 0;\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp = target_to_esp_xtensa_smp(target);\n\n\tif (target->smp) {\n\t\tres = esp_xtensa_smp_smpbreak_disable(target, &smp_break);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\tres = xtensa_step(target, current, address, handle_breakpoints);\n\n\tif (res == ERROR_OK) {\n\t\tif (esp_xtensa_smp->chip_ops->on_halt)\n\t\t\tesp_xtensa_smp->chip_ops->on_halt(target);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t}\n\n\tif (target->smp) {\n\t\tint ret = esp_xtensa_smp_smpbreak_restore(target, smp_break);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\treturn res;\n}\n\nint esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint)\n{\n\tint res = xtensa_watchpoint_add(target, watchpoint);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (!target->smp)\n\t\treturn ERROR_OK;\n\n\tstruct target_list *head;\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (curr == target || !target_was_examined(curr))\n\t\t\tcontinue;\n\t\t/* Need to use high level API here because every target for core contains list of watchpoints.\n\t\t * GDB works with active core only, so we need to duplicate every watchpoint on other cores,\n\t\t * otherwise watchpoint_free() on active core can fail if WP has been initially added on another core. */\n\t\tcurr->smp = 0;\n\t\tres = watchpoint_add(curr, watchpoint->address, watchpoint->length,\n\t\t\twatchpoint->rw, watchpoint->value, watchpoint->mask);\n\t\tcurr->smp = 1;\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)\n{\n\tint res = xtensa_watchpoint_remove(target, watchpoint);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (!target->smp)\n\t\treturn ERROR_OK;\n\n\tstruct target_list *head;\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif (curr == target)\n\t\t\tcontinue;\n\t\t/* see big comment in esp_xtensa_smp_watchpoint_add() */\n\t\tcurr->smp = 0;\n\t\twatchpoint_remove(curr, watchpoint->address);\n\t\tcurr->smp = 1;\n\t}\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_init_arch_info(struct target *target,\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp,\n\tstruct xtensa_debug_module_config *dm_cfg,\n\tconst struct esp_xtensa_smp_chip_ops *chip_ops,\n\tconst struct esp_semihost_ops *semihost_ops)\n{\n\tint ret = esp_xtensa_init_arch_info(target, &esp_xtensa_smp->esp_xtensa, dm_cfg, semihost_ops);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tesp_xtensa_smp->chip_ops = chip_ops;\n\tesp_xtensa_smp->examine_other_cores = ESP_XTENSA_SMP_EXAMINE_OTHER_CORES;\n\treturn ERROR_OK;\n}\n\nint esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\tint ret = esp_xtensa_target_init(cmd_ctx, target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tstruct target *curr = head->target;\n\t\t\tret = esp_xtensa_semihosting_init(curr);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t} else {\n\t\tret = esp_xtensa_semihosting_init(target);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtdef)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtopt)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtmem)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtmpu)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtmmu)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtreg)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_xtregfmt)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_permissive_mode)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_smpbreak)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, curr);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do, target);\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_mask_interrupts)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_enable)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp && CMD_ARGC > 0) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_perfmon_dump)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tLOG_INFO(\"CPU%d:\", curr->coreid);\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_tracestart)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_tracestop)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,\n\t\t\t\ttarget_to_xtensa(curr));\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,\n\t\ttarget_to_xtensa(target));\n}\n\nCOMMAND_HANDLER(esp_xtensa_smp_cmd_tracedump)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (target->smp) {\n\t\tstruct target_list *head;\n\t\tstruct target *curr;\n\t\tint32_t cores_max_id = 0;\n\t\t/* assume that core IDs are assigned to SMP targets sequentially: 0,1,2... */\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tif (cores_max_id < curr->coreid)\n\t\t\t\tcores_max_id = curr->coreid;\n\t\t}\n\t\tif (CMD_ARGC < ((uint32_t)cores_max_id + 1)) {\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"Need %d filenames to dump to as output!\",\n\t\t\t\tcores_max_id + 1);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tforeach_smp_target(head, target->smp_targets) {\n\t\t\tcurr = head->target;\n\t\t\tint ret = CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,\n\t\t\t\ttarget_to_xtensa(curr), CMD_ARGV[curr->coreid]);\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\treturn ret;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,\n\t\ttarget_to_xtensa(target), CMD_ARGV[0]);\n}\n\nconst struct command_registration esp_xtensa_smp_xtensa_command_handlers[] = {\n\t{\n\t\t.name = \"xtdef\",\n\t\t.handler = esp_xtensa_smp_cmd_xtdef,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa core type\",\n\t\t.usage = \"<type>\",\n\t},\n\t{\n\t\t.name = \"xtopt\",\n\t\t.handler = esp_xtensa_smp_cmd_xtopt,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa core option\",\n\t\t.usage = \"<name> <value>\",\n\t},\n\t{\n\t\t.name = \"xtmem\",\n\t\t.handler = esp_xtensa_smp_cmd_xtmem,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa memory/cache option\",\n\t\t.usage = \"<type> [parameters]\",\n\t},\n\t{\n\t\t.name = \"xtmmu\",\n\t\t.handler = esp_xtensa_smp_cmd_xtmmu,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa MMU option\",\n\t\t.usage = \"<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>\",\n\t},\n\t{\n\t\t.name = \"xtmpu\",\n\t\t.handler = esp_xtensa_smp_cmd_xtmpu,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa MPU option\",\n\t\t.usage = \"<num FG seg> <min seg size> <lockable> <executeonly>\",\n\t},\n\t{\n\t\t.name = \"xtreg\",\n\t\t.handler = esp_xtensa_smp_cmd_xtreg,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa register\",\n\t\t.usage = \"<regname> <regnum>\",\n\t},\n\t{\n\t\t.name = \"xtregs\",\n\t\t.handler = esp_xtensa_smp_cmd_xtreg,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure number of Xtensa registers\",\n\t\t.usage = \"<numregs>\",\n\t},\n\t{\n\t\t.name = \"xtregfmt\",\n\t\t.handler = esp_xtensa_smp_cmd_xtregfmt,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure format of Xtensa register map\",\n\t\t.usage = \"<numgregs>\",\n\t},\n\t{\n\t\t.name = \"set_permissive\",\n\t\t.handler = esp_xtensa_smp_cmd_permissive_mode,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"When set to 1, enable Xtensa permissive mode (less client-side checks)\",\n\t\t.usage = \"[0|1]\",\n\t},\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = esp_xtensa_smp_cmd_mask_interrupts,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mask Xtensa interrupts at step\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.name = \"smpbreak\",\n\t\t.handler = esp_xtensa_smp_cmd_smpbreak,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Set the way the CPU chains OCD breaks\",\n\t\t.usage =\n\t\t\t\"[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]\",\n\t},\n\t{\n\t\t.name = \"perfmon_enable\",\n\t\t.handler = esp_xtensa_smp_cmd_perfmon_enable,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Enable and start performance counter\",\n\t\t.usage = \"<counter_id> <select> [mask] [kernelcnt] [tracelevel]\",\n\t},\n\t{\n\t\t.name = \"perfmon_dump\",\n\t\t.handler = esp_xtensa_smp_cmd_perfmon_dump,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"Dump performance counter value. If no argument specified, dumps all counters.\",\n\t\t.usage = \"[counter_id]\",\n\t},\n\t{\n\t\t.name = \"tracestart\",\n\t\t.handler = esp_xtensa_smp_cmd_tracestart,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.\",\n\t\t.usage = \"[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]\",\n\t},\n\t{\n\t\t.name = \"tracestop\",\n\t\t.handler = esp_xtensa_smp_cmd_tracestop,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Tracing: Stop current trace as started by the tracestart command\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"tracedump\",\n\t\t.handler = esp_xtensa_smp_cmd_tracedump,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Tracing: Dump trace memory to a files. One file per core.\",\n\t\t.usage = \"<outfile1> <outfile2>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration esp_xtensa_smp_command_handlers[] = {\n\t{\n\t\t.name = \"xtensa\",\n\t\t.usage = \"\",\n\t\t.chain = esp_xtensa_smp_xtensa_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/esp_xtensa_smp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   ESP Xtensa SMP target for OpenOCD                                     *\n *   Copyright (C) 2020 Espressif Systems Ltd. Co                          *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_ESP_SMP_H\n#define OPENOCD_TARGET_XTENSA_ESP_SMP_H\n\n#include \"esp_xtensa.h\"\n\nstruct esp_xtensa_smp_chip_ops {\n\tint (*poll)(struct target *target);\n\tint (*reset)(struct target *target);\n\tint (*on_halt)(struct target *target);\n};\n\nstruct esp_xtensa_smp_common {\n\tstruct esp_xtensa_common esp_xtensa;\n\tconst struct esp_xtensa_smp_chip_ops *chip_ops;\n\tbool other_core_does_resume;\n\t/* number of attempts to examine other SMP cores, attempts are made after reset on target poll */\n\tint examine_other_cores;\n};\n\nint esp_xtensa_smp_poll(struct target *target);\nint esp_xtensa_smp_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution);\nint esp_xtensa_smp_step(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints);\nint esp_xtensa_smp_assert_reset(struct target *target);\nint esp_xtensa_smp_deassert_reset(struct target *target);\nint esp_xtensa_smp_soft_reset_halt(struct target *target);\nint esp_xtensa_smp_on_halt(struct target *target);\nint esp_xtensa_smp_watchpoint_add(struct target *target, struct watchpoint *watchpoint);\nint esp_xtensa_smp_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);\nint esp_xtensa_smp_handle_target_event(struct target *target, enum target_event event, void *priv);\nint esp_xtensa_smp_target_init(struct command_context *cmd_ctx, struct target *target);\nint esp_xtensa_smp_init_arch_info(struct target *target,\n\tstruct esp_xtensa_smp_common *esp_xtensa_smp,\n\tstruct xtensa_debug_module_config *dm_cfg,\n\tconst struct esp_xtensa_smp_chip_ops *chip_ops,\n\tconst struct esp_semihost_ops *semihost_ops);\n\nextern const struct command_registration esp_xtensa_smp_command_handlers[];\nextern const struct command_registration esp_xtensa_smp_xtensa_command_handlers[];\nextern const struct command_registration esp_xtensa_smp_esp_command_handlers[];\n\n#endif\t/* OPENOCD_TARGET_XTENSA_ESP_SMP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/espressif/segger_sysview.h",
    "content": "/* SPDX-License-Identifier: BSD-1-Clause */\n/* SPDX-FileCopyrightText: (c) 1995-2021 SEGGER Microcontroller GmbH. All rights reserved. */\n/* SPDX-FileContributor: 2023 Espressif Systems (Shanghai) CO LTD */\n\n/*\n* The contend below is extracted from files SEGGER_SYSVIEW.h and SEGGER_SYSVIEW_Int.h in:\n* https://www.segger.com/downloads/systemview/systemview_target_src\n* SystemView version: 3.42\n*/\n\n#ifndef OPENOCD_TARGET_SEGGER_SYSVIEW_H\n#define OPENOCD_TARGET_SEGGER_SYSVIEW_H\n\n#define SYSVIEW_EVTID_NOP                 0\t/* Dummy packet. */\n#define SYSVIEW_EVTID_OVERFLOW            1\n#define SYSVIEW_EVTID_ISR_ENTER           2\n#define SYSVIEW_EVTID_ISR_EXIT            3\n#define SYSVIEW_EVTID_TASK_START_EXEC     4\n#define SYSVIEW_EVTID_TASK_STOP_EXEC      5\n#define SYSVIEW_EVTID_TASK_START_READY    6\n#define SYSVIEW_EVTID_TASK_STOP_READY     7\n#define SYSVIEW_EVTID_TASK_CREATE         8\n#define SYSVIEW_EVTID_TASK_INFO           9\n#define SYSVIEW_EVTID_TRACE_START         10\n#define SYSVIEW_EVTID_TRACE_STOP          11\n#define SYSVIEW_EVTID_SYSTIME_CYCLES      12\n#define SYSVIEW_EVTID_SYSTIME_US          13\n#define SYSVIEW_EVTID_SYSDESC             14\n#define SYSVIEW_EVTID_USER_START          15\n#define SYSVIEW_EVTID_USER_STOP           16\n#define SYSVIEW_EVTID_IDLE                17\n#define SYSVIEW_EVTID_ISR_TO_SCHEDULER    18\n#define SYSVIEW_EVTID_TIMER_ENTER         19\n#define SYSVIEW_EVTID_TIMER_EXIT          20\n#define SYSVIEW_EVTID_STACK_INFO          21\n#define SYSVIEW_EVTID_MODULEDESC          22\n\n#define SYSVIEW_EVTID_INIT                24\n#define SYSVIEW_EVTID_NAME_RESOURCE       25\n#define SYSVIEW_EVTID_PRINT_FORMATTED     26\n#define SYSVIEW_EVTID_NUMMODULES          27\n#define SYSVIEW_EVTID_END_CALL            28\n#define SYSVIEW_EVTID_TASK_TERMINATE      29\n\n#define SYSVIEW_EVTID_EX                  31\n//\n// SystemView extended events. Sent with ID 31.\n//\n#define SYSVIEW_EVTID_EX_MARK             0\n#define SYSVIEW_EVTID_EX_NAME_MARKER      1\n#define SYSVIEW_EVTID_EX_HEAP_DEFINE      2\n#define SYSVIEW_EVTID_EX_HEAP_ALLOC       3\n#define SYSVIEW_EVTID_EX_HEAP_ALLOC_EX    4\n#define SYSVIEW_EVTID_EX_HEAP_FREE        5\n\n#define SYSVIEW_SYNC_LEN                  10\n\n#define SYSVIEW_EVENT_ID_MAX             (200)\n\n//\n// Commands that Host can send to target\n//\nenum {\n\tSEGGER_SYSVIEW_COMMAND_ID_START = 1,\n\tSEGGER_SYSVIEW_COMMAND_ID_STOP,\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_SYSTIME,\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_TASKLIST,\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_SYSDESC,\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_NUMMODULES,\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_MODULEDESC,\n\tSEGGER_SYSVIEW_COMMAND_ID_HEARTBEAT = 127,\n\t// Extended commands: Commands >= 128 have a second parameter\n\tSEGGER_SYSVIEW_COMMAND_ID_GET_MODULE = 128\n};\n\n/* Minimum compatible SEGGER SystemView tool version */\n#define SYSVIEW_MIN_VER_STRING\t\t\t\"SEGGER SystemViewer V2.42\"\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etb.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"etm.h\"\n#include \"etb.h\"\n#include \"register.h\"\n\nstatic const char * const etb_reg_list[] = {\n\t\"ETB_identification\",\n\t\"ETB_ram_depth\",\n\t\"ETB_ram_width\",\n\t\"ETB_status\",\n\t\"ETB_ram_data\",\n\t\"ETB_ram_read_pointer\",\n\t\"ETB_ram_write_pointer\",\n\t\"ETB_trigger_counter\",\n\t\"ETB_control\",\n};\n\nstatic int etb_get_reg(struct reg *reg);\n\nstatic int etb_set_instr(struct etb *etb, uint32_t new_instr)\n{\n\tstruct jtag_tap *tap;\n\n\ttap = etb->tap;\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\t\tstruct scan_field field;\n\n\t\tfield.num_bits = tap->ir_length;\n\t\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\t\tfield.out_value = t;\n\t\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\t\tfree(t);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_scann(struct etb *etb, uint32_t new_scan_chain)\n{\n\tif (etb->cur_scan_chain != new_scan_chain) {\n\t\tstruct scan_field field;\n\n\t\tfield.num_bits = 5;\n\t\tvoid *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\t\tfield.out_value = t;\n\t\tbuf_set_u32(t, 0, field.num_bits, new_scan_chain);\n\n\t\tfield.in_value = NULL;\n\n\t\t/* select INTEST instruction */\n\t\tetb_set_instr(etb, 0x2);\n\t\tjtag_add_dr_scan(etb->tap, 1, &field, TAP_IDLE);\n\n\t\tetb->cur_scan_chain = new_scan_chain;\n\n\t\tfree(t);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_read_reg_w_check(struct reg *, uint8_t *, uint8_t *);\nstatic int etb_set_reg_w_exec(struct reg *, uint8_t *);\n\nstatic int etb_read_reg(struct reg *reg)\n{\n\treturn etb_read_reg_w_check(reg, NULL, NULL);\n}\n\nstatic int etb_get_reg(struct reg *reg)\n{\n\tint retval;\n\n\tretval = etb_read_reg(reg);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: error scheduling ETB register read\");\n\t\treturn retval;\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"ETB register read failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type etb_reg_type = {\n\t.get = etb_get_reg,\n\t.set = etb_set_reg_w_exec,\n};\n\nstruct reg_cache *etb_build_reg_cache(struct etb *etb)\n{\n\tstruct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = NULL;\n\tstruct etb_reg *arch_info = NULL;\n\tint num_regs = 9;\n\tint i;\n\n\t/* the actual registers are kept in two arrays */\n\treg_list = calloc(num_regs, sizeof(struct reg));\n\tarch_info = calloc(num_regs, sizeof(struct etb_reg));\n\n\t/* fill in values for the reg cache */\n\treg_cache->name = \"etb registers\";\n\treg_cache->next = NULL;\n\treg_cache->reg_list = reg_list;\n\treg_cache->num_regs = num_regs;\n\n\t/* set up registers */\n\tfor (i = 0; i < num_regs; i++) {\n\t\treg_list[i].name = etb_reg_list[i];\n\t\treg_list[i].size = 32;\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].arch_info = &arch_info[i];\n\t\treg_list[i].type = &etb_reg_type;\n\t\treg_list[i].size = 32;\n\t\tarch_info[i].addr = i;\n\t\tarch_info[i].etb = etb;\n\t}\n\n\treturn reg_cache;\n}\n\nstatic void etb_getbuf(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\n\t*((uint32_t *)arg) = buf_get_u32(in, 0, 32);\n}\n\nstatic int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames)\n{\n\tstruct scan_field fields[3];\n\tint i;\n\n\tetb_scann(etb, 0x0);\n\tetb_set_instr(etb, 0xc);\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = NULL;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 7;\n\tuint8_t temp1 = 0;\n\tfields[1].out_value = &temp1;\n\tbuf_set_u32(&temp1, 0, 7, 4);\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tuint8_t temp2 = 0;\n\tfields[2].out_value = &temp2;\n\tbuf_set_u32(&temp2, 0, 1, 0);\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE);\n\n\tfor (i = 0; i < num_frames; i++) {\n\t\t/* ensure nR/W remains set to read */\n\t\tbuf_set_u32(&temp2, 0, 1, 0);\n\n\t\t/* address remains set to 0x4 (RAM data) until we read the last frame */\n\t\tif (i < num_frames - 1)\n\t\t\tbuf_set_u32(&temp1, 0, 7, 4);\n\t\telse\n\t\t\tbuf_set_u32(&temp1, 0, 7, 0);\n\n\t\tfields[0].in_value = (uint8_t *)(data + i);\n\t\tjtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE);\n\n\t\tjtag_add_callback(etb_getbuf, (jtag_callback_data_t)(data + i));\n\t}\n\n\tjtag_execute_queue();\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_read_reg_w_check(struct reg *reg,\n\tuint8_t *check_value, uint8_t *check_mask)\n{\n\tstruct etb_reg *etb_reg = reg->arch_info;\n\tuint8_t reg_addr = etb_reg->addr & 0x7f;\n\tstruct scan_field fields[3];\n\n\tLOG_DEBUG(\"%i\", (int)(etb_reg->addr));\n\n\tetb_scann(etb_reg->etb, 0x0);\n\tetb_set_instr(etb_reg->etb, 0xc);\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = reg->value;\n\tfields[0].in_value = NULL;\n\tfields[0].check_value = NULL;\n\tfields[0].check_mask = NULL;\n\n\tfields[1].num_bits = 7;\n\tuint8_t temp1 = 0;\n\tfields[1].out_value = &temp1;\n\tbuf_set_u32(&temp1, 0, 7, reg_addr);\n\tfields[1].in_value = NULL;\n\tfields[1].check_value = NULL;\n\tfields[1].check_mask = NULL;\n\n\tfields[2].num_bits = 1;\n\tuint8_t temp2 = 0;\n\tfields[2].out_value = &temp2;\n\tbuf_set_u32(&temp2, 0, 1, 0);\n\tfields[2].in_value = NULL;\n\tfields[2].check_value = NULL;\n\tfields[2].check_mask = NULL;\n\n\tjtag_add_dr_scan(etb_reg->etb->tap, 3, fields, TAP_IDLE);\n\n\t/* read the identification register in the second run, to make sure we\n\t * don't read the ETB data register twice, skipping every second entry\n\t */\n\tbuf_set_u32(&temp1, 0, 7, 0x0);\n\tfields[0].in_value = reg->value;\n\tfields[0].check_value = check_value;\n\tfields[0].check_mask = check_mask;\n\n\tjtag_add_dr_scan_check(etb_reg->etb->tap, 3, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_write_reg(struct reg *, uint32_t);\n\nstatic int etb_set_reg(struct reg *reg, uint32_t value)\n{\n\tint retval;\n\n\tretval = etb_write_reg(reg, value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: error scheduling ETB register write\");\n\t\treturn retval;\n\t}\n\n\tbuf_set_u32(reg->value, 0, reg->size, value);\n\treg->valid = true;\n\treg->dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_set_reg_w_exec(struct reg *reg, uint8_t *buf)\n{\n\tint retval;\n\n\tetb_set_reg(reg, buf_get_u32(buf, 0, reg->size));\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"ETB: register write failed\");\n\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int etb_write_reg(struct reg *reg, uint32_t value)\n{\n\tstruct etb_reg *etb_reg = reg->arch_info;\n\tuint8_t reg_addr = etb_reg->addr & 0x7f;\n\tstruct scan_field fields[3];\n\n\tLOG_DEBUG(\"%i: 0x%8.8\" PRIx32 \"\", (int)(etb_reg->addr), value);\n\n\tetb_scann(etb_reg->etb, 0x0);\n\tetb_set_instr(etb_reg->etb, 0xc);\n\n\tfields[0].num_bits = 32;\n\tuint8_t temp0[4];\n\tfields[0].out_value = temp0;\n\tbuf_set_u32(temp0, 0, 32, value);\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 7;\n\tuint8_t temp1 = 0;\n\tfields[1].out_value = &temp1;\n\tbuf_set_u32(&temp1, 0, 7, reg_addr);\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tuint8_t temp2 = 0;\n\tfields[2].out_value = &temp2;\n\tbuf_set_u32(&temp2, 0, 1, 1);\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(etb_reg->etb->tap, 3, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etb_config_command)\n{\n\tstruct target *target;\n\tstruct jtag_tap *tap;\n\tstruct arm *arm;\n\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_target(CMD_ARGV[0]);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"ETB: target '%s' not defined\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETB: '%s' isn't an ARM\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttap = jtag_tap_by_string(CMD_ARGV[1]);\n\tif (!tap) {\n\t\tcommand_print(CMD, \"ETB: TAP %s does not exist\", CMD_ARGV[1]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (arm->etm) {\n\t\tstruct etb *etb = malloc(sizeof(struct etb));\n\n\t\tarm->etm->capture_driver_priv = etb;\n\n\t\tetb->tap  = tap;\n\t\tetb->cur_scan_chain = 0xffffffff;\n\t\tetb->reg_cache = NULL;\n\t\tetb->ram_width = 0;\n\t\tetb->ram_depth = 0;\n\t} else {\n\t\tLOG_ERROR(\"ETM: target has no ETM defined, ETB left unconfigured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etb_trigger_percent_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm;\n\tstruct etb *etb;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETB: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm = arm->etm;\n\tif (!etm) {\n\t\tcommand_print(CMD, \"ETB: target has no ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (etm->capture_driver != &etb_capture_driver) {\n\t\tcommand_print(CMD, \"ETB: target not using ETB\");\n\t\treturn ERROR_FAIL;\n\t}\n\tetb = arm->etm->capture_driver_priv;\n\n\tif (CMD_ARGC > 0) {\n\t\tuint32_t new_value;\n\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], new_value);\n\t\tif ((new_value < 2) || (new_value > 100))\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"valid percentages are 2%% to 100%%\");\n\t\telse\n\t\t\tetb->trigger_percent = (unsigned) new_value;\n\t}\n\n\tcommand_print(CMD, \"%d percent of tracebuffer fills after trigger\",\n\t\tetb->trigger_percent);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration etb_config_command_handlers[] = {\n\t{\n\t\t/* NOTE:  with ADIv5, ETBs are accessed using DAP operations,\n\t\t * possibly over SWD, not through separate TAPs...\n\t\t */\n\t\t.name = \"config\",\n\t\t.handler = handle_etb_config_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Associate ETB with target and JTAG TAP.\",\n\t\t.usage = \"target tap\",\n\t},\n\t{\n\t\t.name = \"trigger_percent\",\n\t\t.handler = handle_etb_trigger_percent_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Set percent of trace buffer to be filled \"\n\t\t\t\"after the trigger occurs (2..100).\",\n\t\t.usage = \"[percent]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration etb_command_handlers[] = {\n\t{\n\t\t.name = \"etb\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Embedded Trace Buffer command group\",\n\t\t.chain = etb_config_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int etb_init(struct etm_context *etm_ctx)\n{\n\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\n\tetb->etm_ctx = etm_ctx;\n\n\t/* identify ETB RAM depth and width */\n\tetb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_DEPTH]);\n\tetb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_WIDTH]);\n\tjtag_execute_queue();\n\n\tetb->ram_depth = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_DEPTH].value, 0, 32);\n\tetb->ram_width = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WIDTH].value, 0, 32);\n\n\tetb->trigger_percent = 50;\n\n\treturn ERROR_OK;\n}\n\nstatic trace_status_t etb_status(struct etm_context *etm_ctx)\n{\n\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\tstruct reg *control = &etb->reg_cache->reg_list[ETB_CTRL];\n\tstruct reg *status = &etb->reg_cache->reg_list[ETB_STATUS];\n\ttrace_status_t retval = 0;\n\tint etb_timeout = 100;\n\n\tetb->etm_ctx = etm_ctx;\n\n\t/* read control and status registers */\n\tetb_read_reg(control);\n\tetb_read_reg(status);\n\tjtag_execute_queue();\n\n\t/* See if it's (still) active */\n\tretval = buf_get_u32(control->value, 0, 1) ? TRACE_RUNNING : TRACE_IDLE;\n\n\t/* check Full bit to identify wraparound/overflow */\n\tif (buf_get_u32(status->value, 0, 1) == 1)\n\t\tretval |= TRACE_OVERFLOWED;\n\n\t/* check Triggered bit to identify trigger condition */\n\tif (buf_get_u32(status->value, 1, 1) == 1)\n\t\tretval |= TRACE_TRIGGERED;\n\n\t/* check AcqComp to see if trigger counter dropped to zero */\n\tif (buf_get_u32(status->value, 2, 1) == 1) {\n\t\t/* wait for DFEmpty */\n\t\twhile (etb_timeout-- && buf_get_u32(status->value, 3, 1) == 0)\n\t\t\tetb_get_reg(status);\n\n\t\tif (etb_timeout == 0)\n\t\t\tLOG_ERROR(\"ETB:  DFEmpty won't go high, status 0x%02x\",\n\t\t\t\t(unsigned) buf_get_u32(status->value, 0, 4));\n\n\t\tif (!(etm_ctx->capture_status & TRACE_TRIGGERED))\n\t\t\tLOG_WARNING(\"ETB: trace complete without triggering?\");\n\n\t\tretval |= TRACE_COMPLETED;\n\t}\n\n\t/* NOTE: using a trigger is optional; and at least ETB11 has a mode\n\t * where it can ignore the trigger counter.\n\t */\n\n\t/* update recorded state */\n\tetm_ctx->capture_status = retval;\n\n\treturn retval;\n}\n\nstatic int etb_read_trace(struct etm_context *etm_ctx)\n{\n\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\tint first_frame = 0;\n\tint num_frames = etb->ram_depth;\n\tuint32_t *trace_data = NULL;\n\tint i, j;\n\n\tetb_read_reg(&etb->reg_cache->reg_list[ETB_STATUS]);\n\tetb_read_reg(&etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER]);\n\tjtag_execute_queue();\n\n\t/* check if we overflowed, and adjust first frame of the trace accordingly\n\t * if we didn't overflow, read only up to the frame that would be written next,\n\t * i.e. don't read invalid entries\n\t */\n\tif (buf_get_u32(etb->reg_cache->reg_list[ETB_STATUS].value, 0, 1))\n\t\tfirst_frame = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value,\n\t\t\t\t0,\n\t\t\t\t32);\n\telse\n\t\tnum_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value,\n\t\t\t\t0,\n\t\t\t\t32);\n\n\tetb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame);\n\n\t/* read data into temporary array for unpacking */\n\ttrace_data = malloc(sizeof(uint32_t) * num_frames);\n\tetb_read_ram(etb, trace_data, num_frames);\n\n\tif (etm_ctx->trace_depth > 0)\n\t\tfree(etm_ctx->trace_data);\n\n\tif ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT)\n\t\tetm_ctx->trace_depth = num_frames * 3;\n\telse if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT)\n\t\tetm_ctx->trace_depth = num_frames * 2;\n\telse\n\t\tetm_ctx->trace_depth = num_frames;\n\n\tetm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth);\n\n\tfor (i = 0, j = 0; i < num_frames; i++) {\n\t\tif ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) {\n\t\t\t/* trace word j */\n\t\t\tetm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;\n\t\t\tetm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3;\n\t\t\tetm_ctx->trace_data[j].flags = 0;\n\t\t\tif ((trace_data[i] & 0x80) >> 7)\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &\n\t\t\t\t\t0x7;\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\t/* trace word j + 1 */\n\t\t\tetm_ctx->trace_data[j + 1].pipestat = (trace_data[i] & 0x100) >> 8;\n\t\t\tetm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7800) >> 11;\n\t\t\tetm_ctx->trace_data[j + 1].flags = 0;\n\t\t\tif ((trace_data[i] & 0x8000) >> 15)\n\t\t\t\tetm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j +\n\t\t\t\t1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;\n\t\t\t\tetm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\t/* trace word j + 2 */\n\t\t\tetm_ctx->trace_data[j + 2].pipestat = (trace_data[i] & 0x10000) >> 16;\n\t\t\tetm_ctx->trace_data[j + 2].packet = (trace_data[i] & 0x780000) >> 19;\n\t\t\tetm_ctx->trace_data[j + 2].flags = 0;\n\t\t\tif ((trace_data[i] & 0x800000) >> 23)\n\t\t\t\tetm_ctx->trace_data[j + 2].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j + 2].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j +\n\t\t\t\t2].pipestat = etm_ctx->trace_data[j + 2].packet & 0x7;\n\t\t\t\tetm_ctx->trace_data[j + 2].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\tj += 3;\n\t\t} else if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) {\n\t\t\t/* trace word j */\n\t\t\tetm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;\n\t\t\tetm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3;\n\t\t\tetm_ctx->trace_data[j].flags = 0;\n\t\t\tif ((trace_data[i] & 0x800) >> 11)\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &\n\t\t\t\t\t0x7;\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\t/* trace word j + 1 */\n\t\t\tetm_ctx->trace_data[j + 1].pipestat = (trace_data[i] & 0x7000) >> 12;\n\t\t\tetm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7f8000) >> 15;\n\t\t\tetm_ctx->trace_data[j + 1].flags = 0;\n\t\t\tif ((trace_data[i] & 0x800000) >> 23)\n\t\t\t\tetm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j +\n\t\t\t\t1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;\n\t\t\t\tetm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\tj += 2;\n\t\t} else {\n\t\t\t/* trace word j */\n\t\t\tetm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;\n\t\t\tetm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3;\n\t\t\tetm_ctx->trace_data[j].flags = 0;\n\t\t\tif ((trace_data[i] & 0x80000) >> 19)\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;\n\t\t\tif (etm_ctx->trace_data[j].pipestat == STAT_TR) {\n\t\t\t\tetm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &\n\t\t\t\t\t0x7;\n\t\t\t\tetm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;\n\t\t\t}\n\n\t\t\tj += 1;\n\t\t}\n\t}\n\n\tfree(trace_data);\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_start_capture(struct etm_context *etm_ctx)\n{\n\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\tuint32_t etb_ctrl_value = 0x1;\n\tuint32_t trigger_count;\n\n\tif ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) {\n\t\tif ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT) {\n\t\t\tLOG_ERROR(\"ETB can't run in demultiplexed mode with a 4 or 16 bit port\");\n\t\t\treturn ERROR_ETM_PORTMODE_NOT_SUPPORTED;\n\t\t}\n\t\tetb_ctrl_value |= 0x2;\n\t}\n\n\tif ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_MUXED) {\n\t\tLOG_ERROR(\"ETB: can't run in multiplexed mode\");\n\t\treturn ERROR_ETM_PORTMODE_NOT_SUPPORTED;\n\t}\n\n\ttrigger_count = (etb->ram_depth * etb->trigger_percent) / 100;\n\n\tetb_write_reg(&etb->reg_cache->reg_list[ETB_TRIGGER_COUNTER], trigger_count);\n\tetb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER], 0x0);\n\tetb_write_reg(&etb->reg_cache->reg_list[ETB_CTRL], etb_ctrl_value);\n\tjtag_execute_queue();\n\n\t/* we're starting a new trace, initialize capture status */\n\tetm_ctx->capture_status = TRACE_RUNNING;\n\n\treturn ERROR_OK;\n}\n\nstatic int etb_stop_capture(struct etm_context *etm_ctx)\n{\n\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\tstruct reg *etb_ctrl_reg = &etb->reg_cache->reg_list[ETB_CTRL];\n\n\tetb_write_reg(etb_ctrl_reg, 0x0);\n\tjtag_execute_queue();\n\n\t/* trace stopped, just clear running flag, but preserve others */\n\tetm_ctx->capture_status &= ~TRACE_RUNNING;\n\n\treturn ERROR_OK;\n}\n\nstruct etm_capture_driver etb_capture_driver = {\n\t.name = \"etb\",\n\t.commands = etb_command_handlers,\n\t.init = etb_init,\n\t.status = etb_status,\n\t.start_capture = etb_start_capture,\n\t.stop_capture = etb_stop_capture,\n\t.read_trace = etb_read_trace,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etb.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ETB_H\n#define OPENOCD_TARGET_ETB_H\n\n/* ETB registers */\nenum {\n\tETB_ID = 0x00,\n\tETB_RAM_DEPTH = 0x01,\n\tETB_RAM_WIDTH = 0x02,\n\tETB_STATUS = 0x03,\n\tETB_RAM_DATA = 0x04,\n\tETB_RAM_READ_POINTER = 0x05,\n\tETB_RAM_WRITE_POINTER = 0x06,\n\tETB_TRIGGER_COUNTER = 0x07,\n\tETB_CTRL = 0x08,\n};\n\nstruct etb {\n\tstruct etm_context *etm_ctx;\n\tstruct jtag_tap *tap;\n\tuint32_t cur_scan_chain;\n\tstruct reg_cache *reg_cache;\n\n\t/* ETB parameters */\n\tuint32_t ram_depth;\n\tuint32_t ram_width;\n\n\t/** how much trace buffer to fill after trigger */\n\tunsigned trigger_percent;\n};\n\nstruct etb_reg {\n\tuint32_t addr;\n\tstruct etb *etb;\n};\n\nextern struct etm_capture_driver etb_capture_driver;\n\nstruct reg_cache *etb_build_reg_cache(struct etb *etb);\n\n#endif /* OPENOCD_TARGET_ETB_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etm.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"etm.h\"\n#include \"etb.h\"\n#include \"image.h\"\n#include \"arm_disassembler.h\"\n#include \"register.h\"\n#include \"etm_dummy.h\"\n\n/*\n * ARM \"Embedded Trace Macrocell\" (ETM) support -- direct JTAG access.\n *\n * ETM modules collect instruction and/or data trace information, compress\n * it, and transfer it to a debugging host through either a (buffered) trace\n * port (often a 38-pin Mictor connector) or an Embedded Trace Buffer (ETB).\n *\n * There are several generations of these modules.  Original versions have\n * JTAG access through a dedicated scan chain.  Recent versions have added\n * access via coprocessor instructions, memory addressing, and the ARM Debug\n * Interface v5 (ADIv5); and phased out direct JTAG access.\n *\n * This code supports up to the ETMv1.3 architecture, as seen in ETM9 and\n * most common ARM9 systems.  Note: \"CoreSight ETM9\" implements ETMv3.2,\n * implying non-JTAG connectivity options.\n *\n * Relevant documentation includes:\n *  ARM DDI 0157G ... ETM9 (r2p2) Technical Reference Manual\n *  ARM DDI 0315B ... CoreSight ETM9 (r0p1) Technical Reference Manual\n *  ARM IHI 0014O ... Embedded Trace Macrocell, Architecture Specification\n */\n\nenum {\n\tRO,\t\t\t\t/* read/only */\n\tWO,\t\t\t\t/* write/only */\n\tRW,\t\t\t\t/* read/write */\n};\n\nstruct etm_reg_info {\n\tuint8_t addr;\n\tuint8_t size;\t\t\t/* low-N of 32 bits */\n\tuint8_t mode;\t\t\t/* RO, WO, RW */\n\tuint8_t bcd_vers;\t\t/* 1.0, 2.0, etc */\n\tconst char *name;\n};\n\n/*\n * Registers 0..0x7f are JTAG-addressable using scanchain 6.\n * (Or on some processors, through coprocessor operations.)\n * Newer versions of ETM make some W/O registers R/W, and\n * provide definitions for some previously-unused bits.\n */\n\n/* core registers used to version/configure the ETM */\nstatic const struct etm_reg_info etm_core[] = {\n\t/* NOTE: we \"know\" the order here ... */\n\t{ ETM_CONFIG, 32, RO, 0x10, \"ETM_config\", },\n\t{ ETM_ID, 32, RO, 0x20, \"ETM_id\", },\n};\n\n/* basic registers that are always there given the right ETM version */\nstatic const struct etm_reg_info etm_basic[] = {\n\t/* ETM Trace Registers */\n\t{ ETM_CTRL, 32, RW, 0x10, \"ETM_ctrl\", },\n\t{ ETM_TRIG_EVENT, 17, WO, 0x10, \"ETM_trig_event\", },\n\t{ ETM_ASIC_CTRL,  8, WO, 0x10, \"ETM_asic_ctrl\", },\n\t{ ETM_STATUS,  3, RO, 0x11, \"ETM_status\", },\n\t{ ETM_SYS_CONFIG,  9, RO, 0x12, \"ETM_sys_config\", },\n\n\t/* TraceEnable configuration */\n\t{ ETM_TRACE_RESOURCE_CTRL, 32, WO, 0x12, \"ETM_trace_resource_ctrl\", },\n\t{ ETM_TRACE_EN_CTRL2, 16, WO, 0x12, \"ETM_trace_en_ctrl2\", },\n\t{ ETM_TRACE_EN_EVENT, 17, WO, 0x10, \"ETM_trace_en_event\", },\n\t{ ETM_TRACE_EN_CTRL1, 26, WO, 0x10, \"ETM_trace_en_ctrl1\", },\n\n\t/* ViewData configuration (data trace) */\n\t{ ETM_VIEWDATA_EVENT, 17, WO, 0x10, \"ETM_viewdata_event\", },\n\t{ ETM_VIEWDATA_CTRL1, 32, WO, 0x10, \"ETM_viewdata_ctrl1\", },\n\t{ ETM_VIEWDATA_CTRL2, 32, WO, 0x10, \"ETM_viewdata_ctrl2\", },\n\t{ ETM_VIEWDATA_CTRL3, 17, WO, 0x10, \"ETM_viewdata_ctrl3\", },\n\n\t/* REVISIT exclude VIEWDATA_CTRL2 when it's not there */\n\n\t{ 0x78, 12, WO, 0x20, \"ETM_sync_freq\", },\n\t{ 0x7a, 22, RO, 0x31, \"ETM_config_code_ext\", },\n\t{ 0x7b, 32, WO, 0x31, \"ETM_ext_input_select\", },\n\t{ 0x7c, 32, WO, 0x34, \"ETM_trace_start_stop\", },\n\t{ 0x7d, 8, WO, 0x34, \"ETM_behavior_control\", },\n};\n\nstatic const struct etm_reg_info etm_fifofull[] = {\n\t/* FIFOFULL configuration */\n\t{ ETM_FIFOFULL_REGION, 25, WO, 0x10, \"ETM_fifofull_region\", },\n\t{ ETM_FIFOFULL_LEVEL,  8, WO, 0x10, \"ETM_fifofull_level\", },\n};\n\nstatic const struct etm_reg_info etm_addr_comp[] = {\n\t/* Address comparator register pairs */\n#define ADDR_COMPARATOR(i) \\\n\t\t{ ETM_ADDR_COMPARATOR_VALUE + (i) - 1, 32, WO, 0x10, \\\n\t\t\t\t\"ETM_addr_\" #i \"_comparator_value\", }, \\\n\t\t{ ETM_ADDR_ACCESS_TYPE + (i) - 1,  7, WO, 0x10, \\\n\t\t\t\t\"ETM_addr_\" #i \"_access_type\", }\n\tADDR_COMPARATOR(1),\n\tADDR_COMPARATOR(2),\n\tADDR_COMPARATOR(3),\n\tADDR_COMPARATOR(4),\n\tADDR_COMPARATOR(5),\n\tADDR_COMPARATOR(6),\n\tADDR_COMPARATOR(7),\n\tADDR_COMPARATOR(8),\n\n\tADDR_COMPARATOR(9),\n\tADDR_COMPARATOR(10),\n\tADDR_COMPARATOR(11),\n\tADDR_COMPARATOR(12),\n\tADDR_COMPARATOR(13),\n\tADDR_COMPARATOR(14),\n\tADDR_COMPARATOR(15),\n\tADDR_COMPARATOR(16),\n\t{ 0, 0, 0, 0, NULL }\n#undef ADDR_COMPARATOR\n};\n\nstatic const struct etm_reg_info etm_data_comp[] = {\n\t/* Data Value Comparators (NOTE: odd addresses are reserved) */\n#define DATA_COMPARATOR(i) \\\n\t\t{ ETM_DATA_COMPARATOR_VALUE + 2*(i) - 1, 32, WO, 0x10, \\\n\t\t\t\t\"ETM_data_\" #i \"_comparator_value\", }, \\\n\t\t{ ETM_DATA_COMPARATOR_MASK + 2*(i) - 1, 32, WO, 0x10, \\\n\t\t\t\t\"ETM_data_\" #i \"_comparator_mask\", }\n\tDATA_COMPARATOR(1),\n\tDATA_COMPARATOR(2),\n\tDATA_COMPARATOR(3),\n\tDATA_COMPARATOR(4),\n\tDATA_COMPARATOR(5),\n\tDATA_COMPARATOR(6),\n\tDATA_COMPARATOR(7),\n\tDATA_COMPARATOR(8),\n\t{ 0, 0, 0, 0, NULL }\n#undef DATA_COMPARATOR\n};\n\nstatic const struct etm_reg_info etm_counters[] = {\n#define ETM_COUNTER(i) \\\n\t\t{ ETM_COUNTER_RELOAD_VALUE + (i) - 1, 16, WO, 0x10, \\\n\t\t\t\t\"ETM_counter_\" #i \"_reload_value\", }, \\\n\t\t{ ETM_COUNTER_ENABLE + (i) - 1, 18, WO, 0x10, \\\n\t\t\t\t\"ETM_counter_\" #i \"_enable\", }, \\\n\t\t{ ETM_COUNTER_RELOAD_EVENT + (i) - 1, 17, WO, 0x10, \\\n\t\t\t\t\"ETM_counter_\" #i \"_reload_event\", }, \\\n\t\t{ ETM_COUNTER_VALUE + (i) - 1, 16, RO, 0x10, \\\n\t\t\t\t\"ETM_counter_\" #i \"_value\", }\n\tETM_COUNTER(1),\n\tETM_COUNTER(2),\n\tETM_COUNTER(3),\n\tETM_COUNTER(4),\n\t{ 0, 0, 0, 0, NULL }\n#undef ETM_COUNTER\n};\n\nstatic const struct etm_reg_info etm_sequencer[] = {\n#define ETM_SEQ(i) \\\n\t\t{ ETM_SEQUENCER_EVENT + (i), 17, WO, 0x10, \\\n\t\t\t\t\"ETM_sequencer_event\" #i, }\n\tETM_SEQ(0),\t\t\t\t/* 1->2 */\n\tETM_SEQ(1),\t\t\t\t/* 2->1 */\n\tETM_SEQ(2),\t\t\t\t/* 2->3 */\n\tETM_SEQ(3),\t\t\t\t/* 3->1 */\n\tETM_SEQ(4),\t\t\t\t/* 3->2 */\n\tETM_SEQ(5),\t\t\t\t/* 1->3 */\n#undef ETM_SEQ\n\t/* 0x66 reserved */\n\t{ ETM_SEQUENCER_STATE,  2, RO, 0x10, \"ETM_sequencer_state\", },\n};\n\nstatic const struct etm_reg_info etm_outputs[] = {\n#define ETM_OUTPUT(i) \\\n\t\t{ ETM_EXTERNAL_OUTPUT + (i) - 1, 17, WO, 0x10, \\\n\t\t\t\t\"ETM_external_output\" #i, }\n\n\tETM_OUTPUT(1),\n\tETM_OUTPUT(2),\n\tETM_OUTPUT(3),\n\tETM_OUTPUT(4),\n\t{ 0, 0, 0, 0, NULL }\n#undef ETM_OUTPUT\n};\n\n#if 0\n\t/* registers from 0x6c..0x7f were added after ETMv1.3 */\n\n\t/* Context ID Comparators */\n\t{ 0x6c, 32, RO, 0x20, \"ETM_contextid_comparator_value1\", }\n\t{ 0x6d, 32, RO, 0x20, \"ETM_contextid_comparator_value2\", }\n\t{ 0x6e, 32, RO, 0x20, \"ETM_contextid_comparator_value3\", }\n\t{ 0x6f, 32, RO, 0x20, \"ETM_contextid_comparator_mask\", }\n#endif\n\nstatic int etm_get_reg(struct reg *reg);\nstatic int etm_read_reg_w_check(struct reg *reg,\n\tuint8_t *check_value, uint8_t *check_mask);\nstatic int etm_register_user_commands(struct command_context *cmd_ctx);\nstatic int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf);\nstatic int etm_write_reg(struct reg *reg, uint32_t value);\n\nstatic const struct reg_arch_type etm_scan6_type = {\n\t.get = etm_get_reg,\n\t.set = etm_set_reg_w_exec,\n};\n\n/* Look up register by ID ... most ETM instances only\n * support a subset of the possible registers.\n */\nstatic struct reg *etm_reg_lookup(struct etm_context *etm_ctx, unsigned id)\n{\n\tstruct reg_cache *cache = etm_ctx->reg_cache;\n\tunsigned i;\n\n\tfor (i = 0; i < cache->num_regs; i++) {\n\t\tstruct etm_reg *reg = cache->reg_list[i].arch_info;\n\n\t\tif (reg->reg_info->addr == id)\n\t\t\treturn &cache->reg_list[i];\n\t}\n\n\t/* caller asking for nonexistent register is a bug!\n\t * REVISIT say which of the N targets was involved */\n\tLOG_ERROR(\"ETM: register 0x%02x not available\", id);\n\treturn NULL;\n}\n\nstatic void etm_reg_add(unsigned bcd_vers, struct arm_jtag *jtag_info,\n\tstruct reg_cache *cache, struct etm_reg *ereg,\n\tconst struct etm_reg_info *r, unsigned nreg)\n{\n\tstruct reg *reg = cache->reg_list;\n\n\treg += cache->num_regs;\n\tereg += cache->num_regs;\n\n\t/* add up to \"nreg\" registers from \"r\", if supported by this\n\t * version of the ETM, to the specified cache.\n\t */\n\tfor (; nreg--; r++) {\n\t\t/* No more registers to add */\n\t\tif (!r->size) {\n\t\t\tLOG_ERROR(\"etm_reg_add is requested to add non-existing registers, ETM config might be bogus\");\n\t\t\treturn;\n\t\t}\n\n\t\t/* this ETM may be too old to have some registers */\n\t\tif (r->bcd_vers > bcd_vers)\n\t\t\tcontinue;\n\n\t\treg->name = r->name;\n\t\treg->size = r->size;\n\t\treg->value = ereg->value;\n\t\treg->arch_info = ereg;\n\t\treg->type = &etm_scan6_type;\n\t\treg++;\n\t\tcache->num_regs++;\n\n\t\tereg->reg_info = r;\n\t\tereg->jtag_info = jtag_info;\n\t\tereg++;\n\t}\n}\n\nstruct reg_cache *etm_build_reg_cache(struct target *target,\n\tstruct arm_jtag *jtag_info, struct etm_context *etm_ctx)\n{\n\tstruct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = NULL;\n\tstruct etm_reg *arch_info = NULL;\n\tunsigned bcd_vers, config;\n\n\t/* the actual registers are kept in two arrays */\n\treg_list = calloc(128, sizeof(struct reg));\n\tarch_info = calloc(128, sizeof(struct etm_reg));\n\n\tif (!reg_cache || !reg_list || !arch_info) {\n\t\tLOG_ERROR(\"No memory\");\n\t\tgoto fail;\n\t}\n\n\t/* fill in values for the reg cache */\n\treg_cache->name = \"etm registers\";\n\treg_cache->next = NULL;\n\treg_cache->reg_list = reg_list;\n\treg_cache->num_regs = 0;\n\n\t/* add ETM_CONFIG, then parse its values to see\n\t * which other registers exist in this ETM\n\t */\n\tetm_reg_add(0x10, jtag_info, reg_cache, arch_info,\n\t\tetm_core, 1);\n\n\tetm_get_reg(reg_list);\n\tetm_ctx->config = buf_get_u32(arch_info->value, 0, 32);\n\tconfig = etm_ctx->config;\n\n\t/* figure ETM version then add base registers */\n\tif (config & (1 << 31)) {\n\t\tLOG_WARNING(\"ETMv2+ support is incomplete\");\n\n\t\t/* REVISIT more registers may exist; they may now be\n\t\t * readable; more register bits have defined meanings;\n\t\t * don't presume trace start/stop support is present;\n\t\t * and include any context ID comparator registers.\n\t\t */\n\t\tetm_reg_add(0x20, jtag_info, reg_cache, arch_info,\n\t\t\tetm_core + 1, 1);\n\t\tetm_get_reg(reg_list + 1);\n\t\tetm_ctx->id = buf_get_u32(\n\t\t\t\tarch_info[1].value, 0, 32);\n\t\tLOG_DEBUG(\"ETM ID: %08x\", (unsigned) etm_ctx->id);\n\t\tbcd_vers = 0x10 + (((etm_ctx->id) >> 4) & 0xff);\n\n\t} else {\n\t\tswitch (config >> 28) {\n\t\t\tcase 7:\n\t\t\tcase 5:\n\t\t\tcase 3:\n\t\t\t\tbcd_vers = 0x13;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\tcase 2:\n\t\t\t\tbcd_vers = 0x12;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tbcd_vers = 0x11;\n\t\t\t\tbreak;\n\t\t\tcase 0:\n\t\t\t\tbcd_vers = 0x10;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_WARNING(\"Bad ETMv1 protocol %d\", config >> 28);\n\t\t\t\tgoto fail;\n\t\t}\n\t}\n\tetm_ctx->bcd_vers = bcd_vers;\n\tLOG_INFO(\"ETM v%d.%d\", bcd_vers >> 4, bcd_vers & 0xf);\n\n\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\tetm_basic, ARRAY_SIZE(etm_basic));\n\n\t/* address and data comparators; counters; outputs */\n\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\tetm_addr_comp, 4 * (0x0f & (config >> 0)));\n\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\tetm_data_comp, 2 * (0x0f & (config >> 4)));\n\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\tetm_counters, 4 * (0x07 & (config >> 13)));\n\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\tetm_outputs, (0x07 & (config >> 20)));\n\n\t/* FIFOFULL presence is optional\n\t * REVISIT for ETMv1.2 and later, don't bother adding this\n\t * unless ETM_SYS_CONFIG says it's also *supported* ...\n\t */\n\tif (config & (1 << 23))\n\t\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\t\tetm_fifofull, ARRAY_SIZE(etm_fifofull));\n\n\t/* sequencer is optional (for state-dependant triggering) */\n\tif (config & (1 << 16))\n\t\tetm_reg_add(bcd_vers, jtag_info, reg_cache, arch_info,\n\t\t\tetm_sequencer, ARRAY_SIZE(etm_sequencer));\n\n\t/* REVISIT could realloc and likely save half the memory\n\t * in the two chunks we allocated...\n\t */\n\n\t/* the ETM might have an ETB connected */\n\tif (strcmp(etm_ctx->capture_driver->name, \"etb\") == 0) {\n\t\tstruct etb *etb = etm_ctx->capture_driver_priv;\n\n\t\tif (!etb) {\n\t\t\tLOG_ERROR(\"etb selected as etm capture driver, but no ETB configured\");\n\t\t\tgoto fail;\n\t\t}\n\n\t\treg_cache->next = etb_build_reg_cache(etb);\n\n\t\tetb->reg_cache = reg_cache->next;\n\t}\n\n\tetm_ctx->reg_cache = reg_cache;\n\treturn reg_cache;\n\nfail:\n\tfree(reg_cache);\n\tfree(reg_list);\n\tfree(arch_info);\n\treturn NULL;\n}\n\nstatic int etm_read_reg(struct reg *reg)\n{\n\treturn etm_read_reg_w_check(reg, NULL, NULL);\n}\n\nstatic int etm_store_reg(struct reg *reg)\n{\n\treturn etm_write_reg(reg, buf_get_u32(reg->value, 0, reg->size));\n}\n\nint etm_setup(struct target *target)\n{\n\tint retval;\n\tuint32_t etm_ctrl_value;\n\tstruct arm *arm = target_to_arm(target);\n\tstruct etm_context *etm_ctx = arm->etm;\n\tstruct reg *etm_ctrl_reg;\n\n\tetm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);\n\tif (!etm_ctrl_reg)\n\t\treturn ERROR_OK;\n\n\t/* initialize some ETM control register settings */\n\tetm_get_reg(etm_ctrl_reg);\n\tetm_ctrl_value = buf_get_u32(etm_ctrl_reg->value, 0, 32);\n\n\t/* clear the ETM powerdown bit (0) */\n\tetm_ctrl_value &= ~ETM_CTRL_POWERDOWN;\n\n\t/* configure port width (21,6:4), mode (13,17:16) and\n\t * for older modules clocking (13)\n\t */\n\tetm_ctrl_value = (etm_ctrl_value\n\t\t& ~ETM_PORT_WIDTH_MASK\n\t\t& ~ETM_PORT_MODE_MASK\n\t\t& ~ETM_CTRL_DBGRQ\n\t\t& ~ETM_PORT_CLOCK_MASK)\n\t\t| etm_ctx->control;\n\n\tbuf_set_u32(etm_ctrl_reg->value, 0, 32, etm_ctrl_value);\n\tetm_store_reg(etm_ctrl_reg);\n\n\tetm_ctx->control = etm_ctrl_value;\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* REVISIT for ETMv3.0 and later, read ETM_sys_config to\n\t * verify that those width and mode settings are OK ...\n\t */\n\n\tretval = etm_ctx->capture_driver->init(etm_ctx);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"ETM capture driver initialization failed\");\n\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int etm_get_reg(struct reg *reg)\n{\n\tint retval;\n\n\tretval = etm_read_reg(reg);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: error scheduling etm register read\");\n\t\treturn retval;\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"register read failed\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int etm_read_reg_w_check(struct reg *reg,\n\tuint8_t *check_value, uint8_t *check_mask)\n{\n\tstruct etm_reg *etm_reg = reg->arch_info;\n\tassert(etm_reg);\n\tconst struct etm_reg_info *r = etm_reg->reg_info;\n\tuint8_t reg_addr = r->addr & 0x7f;\n\tstruct scan_field fields[3];\n\tint retval;\n\n\tif (etm_reg->reg_info->mode == WO) {\n\t\tLOG_ERROR(\"BUG: can't read write-only register %s\", r->name);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tLOG_DEBUG(\"%s (%u)\", r->name, reg_addr);\n\n\tretval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(etm_reg->jtag_info->tap,\n\t\t\tetm_reg->jtag_info->intest_instr,\n\t\t\tNULL,\n\t\t\tTAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = reg->value;\n\tfields[0].in_value = NULL;\n\tfields[0].check_value = NULL;\n\tfields[0].check_mask = NULL;\n\n\tfields[1].num_bits = 7;\n\tuint8_t temp1 = 0;\n\tfields[1].out_value = &temp1;\n\tbuf_set_u32(&temp1, 0, 7, reg_addr);\n\tfields[1].in_value = NULL;\n\tfields[1].check_value = NULL;\n\tfields[1].check_mask = NULL;\n\n\tfields[2].num_bits = 1;\n\tuint8_t temp2 = 0;\n\tfields[2].out_value = &temp2;\n\tbuf_set_u32(&temp2, 0, 1, 0);\n\tfields[2].in_value = NULL;\n\tfields[2].check_value = NULL;\n\tfields[2].check_mask = NULL;\n\n\tjtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);\n\n\tfields[0].in_value = reg->value;\n\tfields[0].check_value = check_value;\n\tfields[0].check_mask = check_mask;\n\n\tjtag_add_dr_scan_check(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nstatic int etm_set_reg(struct reg *reg, uint32_t value)\n{\n\tint retval = etm_write_reg(reg, value);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"BUG: error scheduling etm register write\");\n\t\treturn retval;\n\t}\n\n\tbuf_set_u32(reg->value, 0, reg->size, value);\n\treg->valid = 1;\n\treg->dirty = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int etm_set_reg_w_exec(struct reg *reg, uint8_t *buf)\n{\n\tint retval;\n\n\tetm_set_reg(reg, buf_get_u32(buf, 0, reg->size));\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"register write failed\");\n\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int etm_write_reg(struct reg *reg, uint32_t value)\n{\n\tstruct etm_reg *etm_reg = reg->arch_info;\n\tconst struct etm_reg_info *r = etm_reg->reg_info;\n\tuint8_t reg_addr = r->addr & 0x7f;\n\tstruct scan_field fields[3];\n\tint retval;\n\n\tif (etm_reg->reg_info->mode == RO) {\n\t\tLOG_ERROR(\"BUG: can't write read--only register %s\", r->name);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tLOG_DEBUG(\"%s (%u): 0x%8.8\" PRIx32 \"\", r->name, reg_addr, value);\n\n\tretval = arm_jtag_scann(etm_reg->jtag_info, 0x6, TAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = arm_jtag_set_instr(etm_reg->jtag_info->tap,\n\t\t\tetm_reg->jtag_info->intest_instr,\n\t\t\tNULL,\n\t\t\tTAP_IDLE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tuint8_t tmp1[4];\n\tfields[0].out_value = tmp1;\n\tbuf_set_u32(tmp1, 0, 32, value);\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 7;\n\tuint8_t tmp2 = 0;\n\tfields[1].out_value = &tmp2;\n\tbuf_set_u32(&tmp2, 0, 7, reg_addr);\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 1;\n\tuint8_t tmp3 = 0;\n\tfields[2].out_value = &tmp3;\n\tbuf_set_u32(&tmp3, 0, 1, 1);\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(etm_reg->jtag_info->tap, 3, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\n\n/* ETM trace analysis functionality */\n\nstatic struct etm_capture_driver *etm_capture_drivers[] = {\n\t&etb_capture_driver,\n\t&etm_dummy_capture_driver,\n\tNULL\n};\n\nstatic int etm_read_instruction(struct etm_context *ctx, struct arm_instruction *instruction)\n{\n\tint section = -1;\n\tsize_t size_read;\n\tuint32_t opcode;\n\tint retval;\n\n\tif (!ctx->image)\n\t\treturn ERROR_TRACE_IMAGE_UNAVAILABLE;\n\n\t/* search for the section the current instruction belongs to */\n\tfor (unsigned int i = 0; i < ctx->image->num_sections; i++) {\n\t\tif ((ctx->image->sections[i].base_address <= ctx->current_pc) &&\n\t\t\t(ctx->image->sections[i].base_address + ctx->image->sections[i].size >\n\t\t\tctx->current_pc)) {\n\t\t\tsection = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (section == -1) {\n\t\t/* current instruction couldn't be found in the image */\n\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t}\n\n\tif (ctx->core_state == ARM_STATE_ARM) {\n\t\tuint8_t buf[4];\n\t\tretval = image_read_section(ctx->image, section,\n\t\t\t\tctx->current_pc -\n\t\t\t\tctx->image->sections[section].base_address,\n\t\t\t\t4, buf, &size_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error while reading instruction\");\n\t\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t\t}\n\t\topcode = target_buffer_get_u32(ctx->target, buf);\n\t\tarm_evaluate_opcode(opcode, ctx->current_pc, instruction);\n\t} else if (ctx->core_state == ARM_STATE_THUMB) {\n\t\tuint8_t buf[2];\n\t\tretval = image_read_section(ctx->image, section,\n\t\t\t\tctx->current_pc -\n\t\t\t\tctx->image->sections[section].base_address,\n\t\t\t\t2, buf, &size_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error while reading instruction\");\n\t\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t\t}\n\t\topcode = target_buffer_get_u16(ctx->target, buf);\n\t\tthumb_evaluate_opcode(opcode, ctx->current_pc, instruction);\n\t} else if (ctx->core_state == ARM_STATE_JAZELLE) {\n\t\tLOG_ERROR(\"BUG: tracing of jazelle code not supported\");\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_ERROR(\"BUG: unknown core state encountered\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int etmv1_next_packet(struct etm_context *ctx, uint8_t *packet, int apo)\n{\n\twhile (ctx->data_index < ctx->trace_depth) {\n\t\t/* if the caller specified an address packet offset, skip until the\n\t\t * we reach the n-th cycle marked with tracesync */\n\t\tif (apo > 0) {\n\t\t\tif (ctx->trace_data[ctx->data_index].flags & ETMV1_TRACESYNC_CYCLE)\n\t\t\t\tapo--;\n\n\t\t\tif (apo > 0) {\n\t\t\t\tctx->data_index++;\n\t\t\t\tctx->data_half = 0;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* no tracedata output during a TD cycle\n\t\t * or in a trigger cycle */\n\t\tif ((ctx->trace_data[ctx->data_index].pipestat == STAT_TD)\n\t\t\t|| (ctx->trace_data[ctx->data_index].flags & ETMV1_TRIGGER_CYCLE)) {\n\t\t\tctx->data_index++;\n\t\t\tctx->data_half = 0;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* FIXME there are more port widths than these... */\n\t\tif ((ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_16BIT) {\n\t\t\tif (ctx->data_half == 0) {\n\t\t\t\t*packet = ctx->trace_data[ctx->data_index].packet & 0xff;\n\t\t\t\tctx->data_half = 1;\n\t\t\t} else {\n\t\t\t\t*packet = (ctx->trace_data[ctx->data_index].packet & 0xff00) >> 8;\n\t\t\t\tctx->data_half = 0;\n\t\t\t\tctx->data_index++;\n\t\t\t}\n\t\t} else if ((ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) {\n\t\t\t*packet = ctx->trace_data[ctx->data_index].packet & 0xff;\n\t\t\tctx->data_index++;\n\t\t} else {\n\t\t\t/* on a 4-bit port, a packet will be output during two consecutive cycles */\n\t\t\tif (ctx->data_index > (ctx->trace_depth - 2))\n\t\t\t\treturn -1;\n\n\t\t\t*packet = ctx->trace_data[ctx->data_index].packet & 0xf;\n\t\t\t*packet |= (ctx->trace_data[ctx->data_index + 1].packet & 0xf) << 4;\n\t\t\tctx->data_index += 2;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\treturn -1;\n}\n\nstatic int etmv1_branch_address(struct etm_context *ctx)\n{\n\tint retval;\n\tuint8_t packet;\n\tint shift = 0;\n\tint apo;\n\tuint32_t i;\n\n\t/* quit analysis if less than two cycles are left in the trace\n\t * because we can't extract the APO */\n\tif (ctx->data_index > (ctx->trace_depth - 2))\n\t\treturn -1;\n\n\t/* a BE could be output during an APO cycle, skip the current\n\t * and continue with the new one */\n\tif (ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x4)\n\t\treturn 1;\n\tif (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x4)\n\t\treturn 2;\n\n\t/* address packet offset encoded in the next two cycles' pipestat bits */\n\tapo = ctx->trace_data[ctx->pipe_index + 1].pipestat & 0x3;\n\tapo |= (ctx->trace_data[ctx->pipe_index + 2].pipestat & 0x3) << 2;\n\n\t/* count number of tracesync cycles between current pipe_index and data_index\n\t * i.e. the number of tracesyncs that data_index already passed by\n\t * to subtract them from the APO */\n\tfor (i = ctx->pipe_index; i < ctx->data_index; i++) {\n\t\tif (ctx->trace_data[ctx->pipe_index + 1].pipestat & ETMV1_TRACESYNC_CYCLE)\n\t\t\tapo--;\n\t}\n\n\t/* extract up to four 7-bit packets */\n\tdo {\n\t\tretval = etmv1_next_packet(ctx, &packet, (shift == 0) ? apo + 1 : 0);\n\t\tif (retval != 0)\n\t\t\treturn -1;\n\t\tctx->last_branch &= ~(0x7f << shift);\n\t\tctx->last_branch |= (packet & 0x7f) << shift;\n\t\tshift += 7;\n\t} while ((packet & 0x80) && (shift < 28));\n\n\t/* one last packet holding 4 bits of the address, plus the branch reason code */\n\tif ((shift == 28) && (packet & 0x80)) {\n\t\tretval = etmv1_next_packet(ctx, &packet, 0);\n\t\tif (retval != 0)\n\t\t\treturn -1;\n\t\tctx->last_branch &= 0x0fffffff;\n\t\tctx->last_branch |= (packet & 0x0f) << 28;\n\t\tctx->last_branch_reason = (packet & 0x70) >> 4;\n\t\tshift += 4;\n\t} else\n\t\tctx->last_branch_reason = 0;\n\n\tif (shift == 32)\n\t\tctx->pc_ok = 1;\n\n\t/* if a full address was output, we might have branched into Jazelle state */\n\tif ((shift == 32) && (packet & 0x80))\n\t\tctx->core_state = ARM_STATE_JAZELLE;\n\telse {\n\t\t/* if we didn't branch into Jazelle state, the current processor state is\n\t\t * encoded in bit 0 of the branch target address */\n\t\tif (ctx->last_branch & 0x1) {\n\t\t\tctx->core_state = ARM_STATE_THUMB;\n\t\t\tctx->last_branch &= ~0x1;\n\t\t} else {\n\t\t\tctx->core_state = ARM_STATE_ARM;\n\t\t\tctx->last_branch &= ~0x3;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nstatic int etmv1_data(struct etm_context *ctx, int size, uint32_t *data)\n{\n\tint j;\n\tuint8_t buf[4];\n\tint retval;\n\n\tfor (j = 0; j < size; j++) {\n\t\tretval = etmv1_next_packet(ctx, &buf[j], 0);\n\t\tif (retval != 0)\n\t\t\treturn -1;\n\t}\n\n\tif (size == 8) {\n\t\tLOG_ERROR(\"TODO: add support for 64-bit values\");\n\t\treturn -1;\n\t} else if (size == 4)\n\t\t*data = target_buffer_get_u32(ctx->target, buf);\n\telse if (size == 2)\n\t\t*data = target_buffer_get_u16(ctx->target, buf);\n\telse if (size == 1)\n\t\t*data = buf[0];\n\telse\n\t\treturn -1;\n\n\treturn 0;\n}\n\nstatic int etmv1_analyze_trace(struct etm_context *ctx, struct command_invocation *cmd)\n{\n\tint retval;\n\tstruct arm_instruction instruction;\n\n\t/* read the trace data if it wasn't read already */\n\tif (ctx->trace_depth == 0)\n\t\tctx->capture_driver->read_trace(ctx);\n\n\tif (ctx->trace_depth == 0) {\n\t\tcommand_print(cmd, \"Trace is empty.\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* start at the beginning of the captured trace */\n\tctx->pipe_index = 0;\n\tctx->data_index = 0;\n\tctx->data_half = 0;\n\n\t/* neither the PC nor the data pointer are valid */\n\tctx->pc_ok = 0;\n\tctx->ptr_ok = 0;\n\n\twhile (ctx->pipe_index < ctx->trace_depth) {\n\t\tuint8_t pipestat = ctx->trace_data[ctx->pipe_index].pipestat;\n\t\tuint32_t next_pc = ctx->current_pc;\n\t\tuint32_t old_data_index = ctx->data_index;\n\t\tuint32_t old_data_half = ctx->data_half;\n\t\tuint32_t old_index = ctx->pipe_index;\n\t\tuint32_t last_instruction = ctx->last_instruction;\n\t\tuint32_t cycles = 0;\n\t\tint current_pc_ok = ctx->pc_ok;\n\n\t\tif (ctx->trace_data[ctx->pipe_index].flags & ETMV1_TRIGGER_CYCLE)\n\t\t\tcommand_print(cmd, \"--- trigger ---\");\n\n\t\t/* instructions execute in IE/D or BE/D cycles */\n\t\tif ((pipestat == STAT_IE) || (pipestat == STAT_ID))\n\t\t\tctx->last_instruction = ctx->pipe_index;\n\n\t\t/* if we don't have a valid pc skip until we reach an indirect branch */\n\t\tif ((!ctx->pc_ok) && (pipestat != STAT_BE)) {\n\t\t\tctx->pipe_index++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* any indirect branch could have interrupted instruction flow\n\t\t * - the branch reason code could indicate a trace discontinuity\n\t\t * - a branch to the exception vectors indicates an exception\n\t\t */\n\t\tif ((pipestat == STAT_BE) || (pipestat == STAT_BD)) {\n\t\t\t/* backup current data index, to be able to consume the branch address\n\t\t\t * before examining data address and values\n\t\t\t */\n\t\t\told_data_index = ctx->data_index;\n\t\t\told_data_half = ctx->data_half;\n\n\t\t\tctx->last_instruction = ctx->pipe_index;\n\n\t\t\tretval = etmv1_branch_address(ctx);\n\t\t\tif (retval != 0) {\n\t\t\t\t/* negative return value from etmv1_branch_address means we ran out of packets,\n\t\t\t\t * quit analysing the trace */\n\t\t\t\tif (retval < 0)\n\t\t\t\t\tbreak;\n\n\t\t\t\t/* a positive return values means the current branch was abandoned,\n\t\t\t\t * and a new branch was encountered in cycle ctx->pipe_index + retval;\n\t\t\t\t */\n\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\"abandoned branch encountered, correctness of analysis uncertain\");\n\t\t\t\tctx->pipe_index += retval;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* skip over APO cycles */\n\t\t\tctx->pipe_index += 2;\n\n\t\t\tswitch (ctx->last_branch_reason) {\n\t\t\t\tcase 0x0:\t/* normal PC change */\n\t\t\t\t\tnext_pc = ctx->last_branch;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x1:\t/* tracing enabled */\n\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\"--- tracing enabled at 0x%8.8\" PRIx32 \" ---\",\n\t\t\t\t\t\tctx->last_branch);\n\t\t\t\t\tctx->current_pc = ctx->last_branch;\n\t\t\t\t\tctx->pipe_index++;\n\t\t\t\t\tcontinue;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x2:\t/* trace restarted after FIFO overflow */\n\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\"--- trace restarted after FIFO overflow at 0x%8.8\" PRIx32 \" ---\",\n\t\t\t\t\t\tctx->last_branch);\n\t\t\t\t\tctx->current_pc = ctx->last_branch;\n\t\t\t\t\tctx->pipe_index++;\n\t\t\t\t\tcontinue;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x3:\t/* exit from debug state */\n\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\"--- exit from debug state at 0x%8.8\" PRIx32 \" ---\",\n\t\t\t\t\t\tctx->last_branch);\n\t\t\t\t\tctx->current_pc = ctx->last_branch;\n\t\t\t\t\tctx->pipe_index++;\n\t\t\t\t\tcontinue;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0x4:\t/* periodic synchronization point */\n\t\t\t\t\tnext_pc = ctx->last_branch;\n\t\t\t\t\t/* if we had no valid PC prior to this synchronization point,\n\t\t\t\t\t * we have to move on with the next trace cycle\n\t\t\t\t\t */\n\t\t\t\t\tif (!current_pc_ok) {\n\t\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\t\"--- periodic synchronization point at 0x%8.8\" PRIx32 \" ---\",\n\t\t\t\t\t\t\tnext_pc);\n\t\t\t\t\t\tctx->current_pc = next_pc;\n\t\t\t\t\t\tctx->pipe_index++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\t/* reserved */\n\t\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\t\"BUG: branch reason code 0x%\" PRIx32 \" is reserved\",\n\t\t\t\t\t\tctx->last_branch_reason);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* if we got here the branch was a normal PC change\n\t\t\t * (or a periodic synchronization point, which means the same for that matter)\n\t\t\t * if we didn't acquire a complete PC continue with the next cycle\n\t\t\t */\n\t\t\tif (!ctx->pc_ok)\n\t\t\t\tcontinue;\n\n\t\t\t/* indirect branch to the exception vector means an exception occurred */\n\t\t\tif ((ctx->last_branch <= 0x20)\n\t\t\t\t|| ((ctx->last_branch >= 0xffff0000) &&\n\t\t\t\t(ctx->last_branch <= 0xffff0020))) {\n\t\t\t\tif ((ctx->last_branch & 0xff) == 0x10)\n\t\t\t\t\tcommand_print(cmd, \"data abort\");\n\t\t\t\telse {\n\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\"exception vector 0x%2.2\" PRIx32 \"\",\n\t\t\t\t\t\tctx->last_branch);\n\t\t\t\t\tctx->current_pc = ctx->last_branch;\n\t\t\t\t\tctx->pipe_index++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* an instruction was executed (or not, depending on the condition flags)\n\t\t * retrieve it from the image for displaying */\n\t\tif (ctx->pc_ok && (pipestat != STAT_WT) && (pipestat != STAT_TD) &&\n\t\t\t!(((pipestat == STAT_BE) || (pipestat == STAT_BD)) &&\n\t\t\t((ctx->last_branch_reason != 0x0) && (ctx->last_branch_reason != 0x4)))) {\n\t\t\tretval = etm_read_instruction(ctx, &instruction);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t/* can't continue tracing with no image available */\n\t\t\t\tif (retval == ERROR_TRACE_IMAGE_UNAVAILABLE)\n\t\t\t\t\treturn retval;\n\t\t\t\telse if (retval == ERROR_TRACE_INSTRUCTION_UNAVAILABLE) {\n\t\t\t\t\t/* TODO: handle incomplete images\n\t\t\t\t\t * for now we just quit the analysis*/\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcycles = old_index - last_instruction;\n\t\t}\n\n\t\tif ((pipestat == STAT_ID) || (pipestat == STAT_BD)) {\n\t\t\tuint32_t new_data_index = ctx->data_index;\n\t\t\tuint32_t new_data_half = ctx->data_half;\n\n\t\t\t/* in case of a branch with data, the branch target address was consumed before\n\t\t\t * we temporarily go back to the saved data index */\n\t\t\tif (pipestat == STAT_BD) {\n\t\t\t\tctx->data_index = old_data_index;\n\t\t\t\tctx->data_half = old_data_half;\n\t\t\t}\n\n\t\t\tif (ctx->control & ETM_CTRL_TRACE_ADDR) {\n\t\t\t\tuint8_t packet;\n\t\t\t\tint shift = 0;\n\n\t\t\t\tdo {\n\t\t\t\t\tretval = etmv1_next_packet(ctx, &packet, 0);\n\t\t\t\t\tif (retval != 0)\n\t\t\t\t\t\treturn ERROR_ETM_ANALYSIS_FAILED;\n\t\t\t\t\tctx->last_ptr &= ~(0x7f << shift);\n\t\t\t\t\tctx->last_ptr |= (packet & 0x7f) << shift;\n\t\t\t\t\tshift += 7;\n\t\t\t\t} while ((packet & 0x80) && (shift < 32));\n\n\t\t\t\tif (shift >= 32)\n\t\t\t\t\tctx->ptr_ok = 1;\n\n\t\t\t\tif (ctx->ptr_ok)\n\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\"address: 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\t\tctx->last_ptr);\n\t\t\t}\n\n\t\t\tif (ctx->control & ETM_CTRL_TRACE_DATA) {\n\t\t\t\tif ((instruction.type == ARM_LDM) ||\n\t\t\t\t\t(instruction.type == ARM_STM)) {\n\t\t\t\t\tint i;\n\t\t\t\t\tfor (i = 0; i < 16; i++) {\n\t\t\t\t\t\tif (instruction.info.load_store_multiple.register_list\n\t\t\t\t\t\t\t& (1 << i)) {\n\t\t\t\t\t\t\tuint32_t data;\n\t\t\t\t\t\t\tif (etmv1_data(ctx, 4, &data) != 0)\n\t\t\t\t\t\t\t\treturn ERROR_ETM_ANALYSIS_FAILED;\n\t\t\t\t\t\t\tcommand_print(cmd,\n\t\t\t\t\t\t\t\t\"data: 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\t\t\t\tdata);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if ((instruction.type >= ARM_LDR) &&\n\t\t\t\t\t(instruction.type <= ARM_STRH)) {\n\t\t\t\t\tuint32_t data;\n\t\t\t\t\tif (etmv1_data(ctx, arm_access_size(&instruction),\n\t\t\t\t\t\t&data) != 0)\n\t\t\t\t\t\treturn ERROR_ETM_ANALYSIS_FAILED;\n\t\t\t\t\tcommand_print(cmd, \"data: 0x%8.8\" PRIx32 \"\", data);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* restore data index after consuming BD address and data */\n\t\t\tif (pipestat == STAT_BD) {\n\t\t\t\tctx->data_index = new_data_index;\n\t\t\t\tctx->data_half = new_data_half;\n\t\t\t}\n\t\t}\n\n\t\t/* adjust PC */\n\t\tif ((pipestat == STAT_IE) || (pipestat == STAT_ID)) {\n\t\t\tif (((instruction.type == ARM_B) ||\n\t\t\t\t(instruction.type == ARM_BL) ||\n\t\t\t\t(instruction.type == ARM_BLX)) &&\n\t\t\t\t(instruction.info.b_bl_bx_blx.target_address != 0xffffffff))\n\t\t\t\tnext_pc = instruction.info.b_bl_bx_blx.target_address;\n\t\t\telse\n\t\t\t\tnext_pc += (ctx->core_state == ARM_STATE_ARM) ? 4 : 2;\n\t\t} else if (pipestat == STAT_IN)\n\t\t\tnext_pc += (ctx->core_state == ARM_STATE_ARM) ? 4 : 2;\n\n\t\tif ((pipestat != STAT_TD) && (pipestat != STAT_WT)) {\n\t\t\tchar cycles_text[32] = \"\";\n\n\t\t\t/* if the trace was captured with cycle accurate tracing enabled,\n\t\t\t * output the number of cycles since the last executed instruction\n\t\t\t */\n\t\t\tif (ctx->control & ETM_CTRL_CYCLE_ACCURATE) {\n\t\t\t\tsnprintf(cycles_text, 32, \" (%i %s)\",\n\t\t\t\t\t(int)cycles,\n\t\t\t\t\t(cycles == 1) ? \"cycle\" : \"cycles\");\n\t\t\t}\n\n\t\t\tcommand_print(cmd, \"%s%s%s\",\n\t\t\t\tinstruction.text,\n\t\t\t\t(pipestat == STAT_IN) ? \" (not executed)\" : \"\",\n\t\t\t\tcycles_text);\n\n\t\t\tctx->current_pc = next_pc;\n\n\t\t\t/* packets for an instruction don't start on or before the preceding\n\t\t\t * functional pipestat (i.e. other than WT or TD)\n\t\t\t */\n\t\t\tif (ctx->data_index <= ctx->pipe_index) {\n\t\t\t\tctx->data_index = ctx->pipe_index + 1;\n\t\t\t\tctx->data_half = 0;\n\t\t\t}\n\t\t}\n\n\t\tctx->pipe_index += 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic COMMAND_HELPER(handle_etm_tracemode_command_update,\n\tuint32_t *mode)\n{\n\tuint32_t tracemode;\n\n\t/* what parts of data access are traced? */\n\tif (strcmp(CMD_ARGV[0], \"none\") == 0)\n\t\ttracemode = 0;\n\telse if (strcmp(CMD_ARGV[0], \"data\") == 0)\n\t\ttracemode = ETM_CTRL_TRACE_DATA;\n\telse if (strcmp(CMD_ARGV[0], \"address\") == 0)\n\t\ttracemode = ETM_CTRL_TRACE_ADDR;\n\telse if (strcmp(CMD_ARGV[0], \"all\") == 0)\n\t\ttracemode = ETM_CTRL_TRACE_DATA | ETM_CTRL_TRACE_ADDR;\n\telse {\n\t\tcommand_print(CMD, \"invalid option '%s'\", CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tuint8_t context_id;\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], context_id);\n\tswitch (context_id) {\n\t\tcase 0:\n\t\t\ttracemode |= ETM_CTRL_CONTEXTID_NONE;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\ttracemode |= ETM_CTRL_CONTEXTID_8;\n\t\t\tbreak;\n\t\tcase 16:\n\t\t\ttracemode |= ETM_CTRL_CONTEXTID_16;\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\ttracemode |= ETM_CTRL_CONTEXTID_32;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcommand_print(CMD, \"invalid option '%s'\", CMD_ARGV[1]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tbool etmv1_cycle_accurate;\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[2], etmv1_cycle_accurate);\n\tif (etmv1_cycle_accurate)\n\t\ttracemode |= ETM_CTRL_CYCLE_ACCURATE;\n\n\tbool etmv1_branch_output;\n\tCOMMAND_PARSE_ENABLE(CMD_ARGV[3], etmv1_branch_output);\n\tif (etmv1_branch_output)\n\t\ttracemode |= ETM_CTRL_BRANCH_OUTPUT;\n\n\t/* IGNORED:\n\t *  - CPRT tracing (coprocessor register transfers)\n\t *  - debug request (causes debug entry on trigger)\n\t *  - stall on FIFOFULL (preventing tracedata loss)\n\t */\n\t*mode = tracemode;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_tracemode_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct arm *arm = target_to_arm(target);\n\tstruct etm_context *etm;\n\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm = arm->etm;\n\tif (!etm) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t tracemode = etm->control;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tCALL_COMMAND_HANDLER(handle_etm_tracemode_command_update,\n\t\t\t\t&tracemode);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/**\n\t * todo: fail if parameters were invalid for this hardware,\n\t * or couldn't be written; display actual hardware state...\n\t */\n\n\tcommand_print(CMD, \"current tracemode configuration:\");\n\n\tswitch (tracemode & ETM_CTRL_TRACE_MASK) {\n\t\tdefault:\n\t\t\tcommand_print(CMD, \"data tracing: none\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_TRACE_DATA:\n\t\t\tcommand_print(CMD, \"data tracing: data only\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_TRACE_ADDR:\n\t\t\tcommand_print(CMD, \"data tracing: address only\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_TRACE_DATA | ETM_CTRL_TRACE_ADDR:\n\t\t\tcommand_print(CMD, \"data tracing: address and data\");\n\t\t\tbreak;\n\t}\n\n\tswitch (tracemode & ETM_CTRL_CONTEXTID_MASK) {\n\t\tcase ETM_CTRL_CONTEXTID_NONE:\n\t\t\tcommand_print(CMD, \"contextid tracing: none\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_CONTEXTID_8:\n\t\t\tcommand_print(CMD, \"contextid tracing: 8 bit\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_CONTEXTID_16:\n\t\t\tcommand_print(CMD, \"contextid tracing: 16 bit\");\n\t\t\tbreak;\n\t\tcase ETM_CTRL_CONTEXTID_32:\n\t\t\tcommand_print(CMD, \"contextid tracing: 32 bit\");\n\t\t\tbreak;\n\t}\n\n\tif (tracemode & ETM_CTRL_CYCLE_ACCURATE)\n\t\tcommand_print(CMD, \"cycle-accurate tracing enabled\");\n\telse\n\t\tcommand_print(CMD, \"cycle-accurate tracing disabled\");\n\n\tif (tracemode & ETM_CTRL_BRANCH_OUTPUT)\n\t\tcommand_print(CMD, \"full branch address output enabled\");\n\telse\n\t\tcommand_print(CMD, \"full branch address output disabled\");\n\n#define TRACEMODE_MASK ( \\\n\t\tETM_CTRL_CONTEXTID_MASK\t\\\n\t\t| ETM_CTRL_BRANCH_OUTPUT \\\n\t\t| ETM_CTRL_CYCLE_ACCURATE \\\n\t\t| ETM_CTRL_TRACE_MASK \\\n\t\t)\n\n\t/* only update ETM_CTRL register if tracemode changed */\n\tif ((etm->control & TRACEMODE_MASK) != tracemode) {\n\t\tstruct reg *etm_ctrl_reg;\n\n\t\tetm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL);\n\t\tif (!etm_ctrl_reg)\n\t\t\treturn ERROR_FAIL;\n\n\t\tetm->control &= ~TRACEMODE_MASK;\n\t\tetm->control |= tracemode & TRACEMODE_MASK;\n\n\t\tbuf_set_u32(etm_ctrl_reg->value, 0, 32, etm->control);\n\t\tetm_store_reg(etm_ctrl_reg);\n\n\t\t/* invalidate old trace data */\n\t\tetm->capture_status = TRACE_IDLE;\n\t\tif (etm->trace_depth > 0) {\n\t\t\tfree(etm->trace_data);\n\t\t\tetm->trace_data = NULL;\n\t\t}\n\t\tetm->trace_depth = 0;\n\t}\n\n#undef TRACEMODE_MASK\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_config_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tuint32_t portmode = 0x0;\n\tstruct etm_context *etm_ctx;\n\tint i;\n\n\tif (CMD_ARGC != 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_target(CMD_ARGV[0]);\n\tif (!target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"target '%s' is '%s'; not an ARM\",\n\t\t\ttarget_name(target),\n\t\t\ttarget_type_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* FIXME for ETMv3.0 and above -- and we don't yet know what ETM\n\t * version we'll be using!! -- so we can't know how to validate\n\t * params yet.  \"etm config\" should likely be *AFTER* hookup...\n\t *\n\t *  - Many more widths might be supported ... and we can easily\n\t *    check whether our setting \"took\".\n\t *\n\t *  - The \"clock\" and \"mode\" bits are interpreted differently.\n\t *    See ARM IHI 0014O table 2-17 for the old behaviour, and\n\t *    table 2-18 for the new.  With ETB it's best to specify\n\t *    \"normal full\" ...\n\t */\n\tuint8_t port_width;\n\tCOMMAND_PARSE_NUMBER(u8, CMD_ARGV[1], port_width);\n\tswitch (port_width) {\n\t\t/* before ETMv3.0 */\n\t\tcase 4:\n\t\t\tportmode |= ETM_PORT_4BIT;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tportmode |= ETM_PORT_8BIT;\n\t\t\tbreak;\n\t\tcase 16:\n\t\t\tportmode |= ETM_PORT_16BIT;\n\t\t\tbreak;\n\t\t/* ETMv3.0 and later*/\n\t\tcase 24:\n\t\t\tportmode |= ETM_PORT_24BIT;\n\t\t\tbreak;\n\t\tcase 32:\n\t\t\tportmode |= ETM_PORT_32BIT;\n\t\t\tbreak;\n\t\tcase 48:\n\t\t\tportmode |= ETM_PORT_48BIT;\n\t\t\tbreak;\n\t\tcase 64:\n\t\t\tportmode |= ETM_PORT_64BIT;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tportmode |= ETM_PORT_1BIT;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tportmode |= ETM_PORT_2BIT;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tcommand_print(CMD,\n\t\t\t\t\"unsupported ETM port width '%s'\", CMD_ARGV[1]);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (strcmp(\"normal\", CMD_ARGV[2]) == 0)\n\t\tportmode |= ETM_PORT_NORMAL;\n\telse if (strcmp(\"multiplexed\", CMD_ARGV[2]) == 0)\n\t\tportmode |= ETM_PORT_MUXED;\n\telse if (strcmp(\"demultiplexed\", CMD_ARGV[2]) == 0)\n\t\tportmode |= ETM_PORT_DEMUXED;\n\telse {\n\t\tcommand_print(CMD,\n\t\t\t\"unsupported ETM port mode '%s', must be 'normal', 'multiplexed' or 'demultiplexed'\",\n\t\t\tCMD_ARGV[2]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (strcmp(\"half\", CMD_ARGV[3]) == 0)\n\t\tportmode |= ETM_PORT_HALF_CLOCK;\n\telse if (strcmp(\"full\", CMD_ARGV[3]) == 0)\n\t\tportmode |= ETM_PORT_FULL_CLOCK;\n\telse {\n\t\tcommand_print(CMD,\n\t\t\t\"unsupported ETM port clocking '%s', must be 'full' or 'half'\",\n\t\t\tCMD_ARGV[3]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = calloc(1, sizeof(struct etm_context));\n\tif (!etm_ctx) {\n\t\tLOG_DEBUG(\"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = 0; etm_capture_drivers[i]; i++) {\n\t\tif (strcmp(CMD_ARGV[4], etm_capture_drivers[i]->name) == 0) {\n\t\t\tint retval = register_commands(CMD_CTX, NULL, etm_capture_drivers[i]->commands);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tfree(etm_ctx);\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tetm_ctx->capture_driver = etm_capture_drivers[i];\n\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!etm_capture_drivers[i]) {\n\t\t/* no supported capture driver found, don't register an ETM */\n\t\tfree(etm_ctx);\n\t\tLOG_ERROR(\"trace capture driver '%s' not found\", CMD_ARGV[4]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx->target = target;\n\tetm_ctx->trace_data = NULL;\n\tetm_ctx->control = portmode;\n\tetm_ctx->core_state = ARM_STATE_ARM;\n\n\tarm->etm = etm_ctx;\n\n\treturn etm_register_user_commands(CMD_CTX);\n}\n\nCOMMAND_HANDLER(handle_etm_info_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm;\n\tstruct reg *etm_sys_config_reg;\n\tint max_port_size;\n\tuint32_t config;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm = arm->etm;\n\tif (!etm) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print(CMD, \"ETM v%d.%d\",\n\t\tetm->bcd_vers >> 4, etm->bcd_vers & 0xf);\n\tcommand_print(CMD, \"pairs of address comparators: %i\",\n\t\t(int) (etm->config >> 0) & 0x0f);\n\tcommand_print(CMD, \"data comparators: %i\",\n\t\t(int) (etm->config >> 4) & 0x0f);\n\tcommand_print(CMD, \"memory map decoders: %i\",\n\t\t(int) (etm->config >> 8) & 0x1f);\n\tcommand_print(CMD, \"number of counters: %i\",\n\t\t(int) (etm->config >> 13) & 0x07);\n\tcommand_print(CMD, \"sequencer %spresent\",\n\t\t(int) (etm->config & (1 << 16)) ? \"\" : \"not \");\n\tcommand_print(CMD, \"number of ext. inputs: %i\",\n\t\t(int) (etm->config >> 17) & 0x07);\n\tcommand_print(CMD, \"number of ext. outputs: %i\",\n\t\t(int) (etm->config >> 20) & 0x07);\n\tcommand_print(CMD, \"FIFO full %spresent\",\n\t\t(int) (etm->config & (1 << 23)) ? \"\" : \"not \");\n\tif (etm->bcd_vers < 0x20)\n\t\tcommand_print(CMD, \"protocol version: %i\",\n\t\t\t(int) (etm->config >> 28) & 0x07);\n\telse {\n\t\tcommand_print(CMD,\n\t\t\t\"coprocessor and memory access %ssupported\",\n\t\t\t(etm->config & (1 << 26)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"trace start/stop %spresent\",\n\t\t\t(etm->config & (1 << 26)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"number of context comparators: %i\",\n\t\t\t(int) (etm->config >> 24) & 0x03);\n\t}\n\n\t/* SYS_CONFIG isn't present before ETMv1.2 */\n\tetm_sys_config_reg = etm_reg_lookup(etm, ETM_SYS_CONFIG);\n\tif (!etm_sys_config_reg)\n\t\treturn ERROR_OK;\n\n\tetm_get_reg(etm_sys_config_reg);\n\tconfig = buf_get_u32(etm_sys_config_reg->value, 0, 32);\n\n\tLOG_DEBUG(\"ETM SYS CONFIG %08x\", (unsigned) config);\n\n\tmax_port_size = config & 0x7;\n\tif (etm->bcd_vers >= 0x30)\n\t\tmax_port_size |= (config >> 6) & 0x08;\n\tswitch (max_port_size) {\n\t\t/* before ETMv3.0 */\n\t\tcase 0:\n\t\t\tmax_port_size = 4;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tmax_port_size = 8;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tmax_port_size = 16;\n\t\t\tbreak;\n\t\t/* ETMv3.0 and later*/\n\t\tcase 3:\n\t\t\tmax_port_size = 24;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tmax_port_size = 32;\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tmax_port_size = 48;\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tmax_port_size = 64;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tmax_port_size = 1;\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tmax_port_size = 2;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Illegal max_port_size\");\n\t\t\treturn ERROR_FAIL;\n\t}\n\tcommand_print(CMD, \"max. port size: %i\", max_port_size);\n\n\tif (etm->bcd_vers < 0x30) {\n\t\tcommand_print(CMD, \"half-rate clocking %ssupported\",\n\t\t\t(config & (1 << 3)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"full-rate clocking %ssupported\",\n\t\t\t(config & (1 << 4)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"normal trace format %ssupported\",\n\t\t\t(config & (1 << 5)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"multiplex trace format %ssupported\",\n\t\t\t(config & (1 << 6)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"demultiplex trace format %ssupported\",\n\t\t\t(config & (1 << 7)) ? \"\" : \"not \");\n\t} else {\n\t\t/* REVISIT show which size and format are selected ... */\n\t\tcommand_print(CMD, \"current port size %ssupported\",\n\t\t\t(config & (1 << 10)) ? \"\" : \"not \");\n\t\tcommand_print(CMD, \"current trace format %ssupported\",\n\t\t\t(config & (1 << 11)) ? \"\" : \"not \");\n\t}\n\tif (etm->bcd_vers >= 0x21)\n\t\tcommand_print(CMD, \"fetch comparisons %ssupported\",\n\t\t\t(config & (1 << 17)) ? \"not \" : \"\");\n\tcommand_print(CMD, \"FIFO full %ssupported\",\n\t\t(config & (1 << 8)) ? \"\" : \"not \");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_status_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm;\n\ttrace_status_t trace_status;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm = arm->etm;\n\tif (!etm) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* ETM status */\n\tif (etm->bcd_vers >= 0x11) {\n\t\tstruct reg *reg;\n\n\t\treg = etm_reg_lookup(etm, ETM_STATUS);\n\t\tif (!reg)\n\t\t\treturn ERROR_FAIL;\n\t\tif (etm_get_reg(reg) == ERROR_OK) {\n\t\t\tunsigned s = buf_get_u32(reg->value, 0, reg->size);\n\n\t\t\tcommand_print(CMD, \"etm: %s%s%s%s\",\n\t\t\t\t/* bit(1) == progbit */\n\t\t\t\t(etm->bcd_vers >= 0x12)\n\t\t\t\t? ((s & (1 << 1))\n\t\t\t\t? \"disabled\" : \"enabled\")\n\t\t\t\t: \"?\",\n\t\t\t\t((s & (1 << 3)) && etm->bcd_vers >= 0x31)\n\t\t\t\t? \" triggered\" : \"\",\n\t\t\t\t((s & (1 << 2)) && etm->bcd_vers >= 0x12)\n\t\t\t\t? \" start/stop\" : \"\",\n\t\t\t\t((s & (1 << 0)) && etm->bcd_vers >= 0x11)\n\t\t\t\t? \" untraced-overflow\" : \"\");\n\t\t}\t/* else ignore and try showing trace port status */\n\t}\n\n\t/* Trace Port Driver status */\n\ttrace_status = etm->capture_driver->status(etm);\n\tif (trace_status == TRACE_IDLE)\n\t\tcommand_print(CMD, \"%s: idle\", etm->capture_driver->name);\n\telse {\n\t\tstatic char *completed = \" completed\";\n\t\tstatic char *running = \" is running\";\n\t\tstatic char *overflowed = \", overflowed\";\n\t\tstatic char *triggered = \", triggered\";\n\n\t\tcommand_print(CMD, \"%s: trace collection%s%s%s\",\n\t\t\tetm->capture_driver->name,\n\t\t\t(trace_status & TRACE_RUNNING) ? running : completed,\n\t\t\t(trace_status & TRACE_OVERFLOWED) ? overflowed : \"\",\n\t\t\t(trace_status & TRACE_TRIGGERED) ? triggered : \"\");\n\n\t\tif (etm->trace_depth > 0) {\n\t\t\tcommand_print(CMD, \"%i frames of trace data read\",\n\t\t\t\t(int)(etm->trace_depth));\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_image_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (etm_ctx->image) {\n\t\timage_close(etm_ctx->image);\n\t\tfree(etm_ctx->image);\n\t\tcommand_print(CMD, \"previously loaded image found and closed\");\n\t}\n\n\tetm_ctx->image = malloc(sizeof(struct image));\n\tetm_ctx->image->base_address_set = false;\n\tetm_ctx->image->start_address_set = false;\n\n\t/* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */\n\tif (CMD_ARGC >= 2) {\n\t\tetm_ctx->image->base_address_set = true;\n\t\tCOMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], etm_ctx->image->base_address);\n\t} else\n\t\tetm_ctx->image->base_address_set = false;\n\n\tif (image_open(etm_ctx->image, CMD_ARGV[0],\n\t\t(CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) {\n\t\tfree(etm_ctx->image);\n\t\tetm_ctx->image = NULL;\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_dump_command)\n{\n\tstruct fileio *file;\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\tuint32_t i;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (etm_ctx->capture_driver->status(etm_ctx) == TRACE_IDLE) {\n\t\tcommand_print(CMD, \"trace capture wasn't enabled, no trace data captured\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) {\n\t\t/* TODO: if on-the-fly capture is to be supported, this needs to be changed */\n\t\tcommand_print(CMD, \"trace capture not completed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* read the trace data if it wasn't read already */\n\tif (etm_ctx->trace_depth == 0)\n\t\tetm_ctx->capture_driver->read_trace(etm_ctx);\n\n\tif (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tfileio_write_u32(file, etm_ctx->capture_status);\n\tfileio_write_u32(file, etm_ctx->control);\n\tfileio_write_u32(file, etm_ctx->trace_depth);\n\n\tfor (i = 0; i < etm_ctx->trace_depth; i++) {\n\t\tfileio_write_u32(file, etm_ctx->trace_data[i].pipestat);\n\t\tfileio_write_u32(file, etm_ctx->trace_data[i].packet);\n\t\tfileio_write_u32(file, etm_ctx->trace_data[i].flags);\n\t}\n\n\tfileio_close(file);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_load_command)\n{\n\tstruct fileio *file;\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\tuint32_t i;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (etm_ctx->capture_driver->status(etm_ctx) & TRACE_RUNNING) {\n\t\tcommand_print(CMD, \"trace capture running, stop first\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (fileio_open(&file, CMD_ARGV[0], FILEIO_READ, FILEIO_BINARY) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tsize_t filesize;\n\tint retval = fileio_size(file, &filesize);\n\tif (retval != ERROR_OK) {\n\t\tfileio_close(file);\n\t\treturn retval;\n\t}\n\n\tif (filesize % 4) {\n\t\tcommand_print(CMD, \"size isn't a multiple of 4, no valid trace data\");\n\t\tfileio_close(file);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (etm_ctx->trace_depth > 0) {\n\t\tfree(etm_ctx->trace_data);\n\t\tetm_ctx->trace_data = NULL;\n\t}\n\n\t{\n\t\tuint32_t tmp;\n\t\tfileio_read_u32(file, &tmp); etm_ctx->capture_status = tmp;\n\t\tfileio_read_u32(file, &tmp); etm_ctx->control = tmp;\n\t\tfileio_read_u32(file, &etm_ctx->trace_depth);\n\t}\n\tetm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth);\n\tif (!etm_ctx->trace_data) {\n\t\tcommand_print(CMD, \"not enough memory to perform operation\");\n\t\tfileio_close(file);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = 0; i < etm_ctx->trace_depth; i++) {\n\t\tuint32_t pipestat, packet, flags;\n\t\tfileio_read_u32(file, &pipestat);\n\t\tfileio_read_u32(file, &packet);\n\t\tfileio_read_u32(file, &flags);\n\t\tetm_ctx->trace_data[i].pipestat = pipestat & 0xff;\n\t\tetm_ctx->trace_data[i].packet = packet & 0xffff;\n\t\tetm_ctx->trace_data[i].flags = flags;\n\t}\n\n\tfileio_close(file);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_start_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\tstruct reg *etm_ctrl_reg;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* invalidate old tracing data */\n\tetm_ctx->capture_status = TRACE_IDLE;\n\tif (etm_ctx->trace_depth > 0) {\n\t\tfree(etm_ctx->trace_data);\n\t\tetm_ctx->trace_data = NULL;\n\t}\n\tetm_ctx->trace_depth = 0;\n\n\tetm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);\n\tif (!etm_ctrl_reg)\n\t\treturn ERROR_FAIL;\n\n\tetm_get_reg(etm_ctrl_reg);\n\n\t/* Clear programming bit (10), set port selection bit (11) */\n\tbuf_set_u32(etm_ctrl_reg->value, 10, 2, 0x2);\n\n\tetm_store_reg(etm_ctrl_reg);\n\tjtag_execute_queue();\n\n\tetm_ctx->capture_driver->start_capture(etm_ctx);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_stop_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\tstruct reg *etm_ctrl_reg;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctrl_reg = etm_reg_lookup(etm_ctx, ETM_CTRL);\n\tif (!etm_ctrl_reg)\n\t\treturn ERROR_FAIL;\n\n\tetm_get_reg(etm_ctrl_reg);\n\n\t/* Set programming bit (10), clear port selection bit (11) */\n\tbuf_set_u32(etm_ctrl_reg->value, 10, 2, 0x1);\n\n\tetm_store_reg(etm_ctrl_reg);\n\tjtag_execute_queue();\n\n\tetm_ctx->capture_driver->stop_capture(etm_ctx);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_trigger_debug_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: %s isn't an ARM\",\n\t\t\ttarget_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm = arm->etm;\n\tif (!etm) {\n\t\tcommand_print(CMD, \"ETM: no ETM configured for %s\",\n\t\t\ttarget_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC == 1) {\n\t\tstruct reg *etm_ctrl_reg;\n\t\tbool dbgrq;\n\n\t\tetm_ctrl_reg = etm_reg_lookup(etm, ETM_CTRL);\n\t\tif (!etm_ctrl_reg)\n\t\t\treturn ERROR_FAIL;\n\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], dbgrq);\n\t\tif (dbgrq)\n\t\t\tetm->control |= ETM_CTRL_DBGRQ;\n\t\telse\n\t\t\tetm->control &= ~ETM_CTRL_DBGRQ;\n\n\t\t/* etm->control will be written to hardware\n\t\t * the next time an \"etm start\" is issued.\n\t\t */\n\t\tbuf_set_u32(etm_ctrl_reg->value, 0, 32, etm->control);\n\t}\n\n\tcommand_print(CMD, \"ETM: %s debug halt\",\n\t\t(etm->control & ETM_CTRL_DBGRQ)\n\t\t? \"triggers\"\n\t\t: \"does not trigger\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_etm_analyze_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\tstruct etm_context *etm_ctx;\n\tint retval;\n\n\ttarget = get_current_target(CMD_CTX);\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"ETM: current target isn't an ARM\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tetm_ctx = arm->etm;\n\tif (!etm_ctx) {\n\t\tcommand_print(CMD, \"current target doesn't have an ETM configured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = etmv1_analyze_trace(etm_ctx, CMD);\n\tif (retval != ERROR_OK) {\n\t\t/* FIX! error should be reported inside etmv1_analyze_trace() */\n\t\tswitch (retval) {\n\t\t\tcase ERROR_ETM_ANALYSIS_FAILED:\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"further analysis failed (corrupted trace data or just end of data\");\n\t\t\t\tbreak;\n\t\t\tcase ERROR_TRACE_INSTRUCTION_UNAVAILABLE:\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"no instruction for current address available, analysis aborted\");\n\t\t\t\tbreak;\n\t\t\tcase ERROR_TRACE_IMAGE_UNAVAILABLE:\n\t\t\t\tcommand_print(CMD, \"no image available for trace analysis\");\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcommand_print(CMD, \"unknown error\");\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nstatic const struct command_registration etm_config_command_handlers[] = {\n\t{\n\t\t/* NOTE:  with ADIv5, ETMs are accessed by DAP operations,\n\t\t * possibly over SWD, not JTAG scanchain 6 of 'target'.\n\t\t *\n\t\t * Also, these parameters don't match ETM v3+ modules...\n\t\t */\n\t\t.name = \"config\",\n\t\t.handler = handle_etm_config_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Set up ETM output port.\",\n\t\t.usage = \"target port_width port_mode clocking capture_driver\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nconst struct command_registration etm_command_handlers[] = {\n\t{\n\t\t.name = \"etm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Embedded Trace Macrocell command group\",\n\t\t.usage = \"\",\n\t\t.chain = etm_config_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration etm_exec_command_handlers[] = {\n\t{\n\t\t.name = \"tracemode\",\n\t\t.handler = handle_etm_tracemode_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"configure/display trace mode\",\n\t\t.usage = \"('none'|'data'|'address'|'all') \"\n\t\t\t\"context_id_bits \"\n\t\t\t\"['enable'|'disable'] \"\n\t\t\t\"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_etm_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"display info about the current target's ETM\",\n\t},\n\t{\n\t\t.name = \"status\",\n\t\t.handler = handle_etm_status_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"display current target's ETM status\",\n\t},\n\t{\n\t\t.name = \"start\",\n\t\t.handler = handle_etm_start_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"start ETM trace collection\",\n\t},\n\t{\n\t\t.name = \"stop\",\n\t\t.handler = handle_etm_stop_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"stop ETM trace collection\",\n\t},\n\t{\n\t\t.name = \"trigger_debug\",\n\t\t.handler = handle_etm_trigger_debug_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"enable/disable debug entry on trigger\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"analyze\",\n\t\t.handler = handle_etm_analyze_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"analyze collected ETM trace\",\n\t},\n\t{\n\t\t.name = \"image\",\n\t\t.handler = handle_etm_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"load image from file with optional offset\",\n\t\t.usage = \"<file> [base address] [type]\",\n\t},\n\t{\n\t\t.name = \"dump\",\n\t\t.handler = handle_etm_dump_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"dump captured trace data to file\",\n\t\t.usage = \"filename\",\n\t},\n\t{\n\t\t.name = \"load\",\n\t\t.handler = handle_etm_load_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"load trace data for analysis <file>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int etm_register_user_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, \"etm\", etm_exec_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007 by Vincent Palatin                                 *\n *   vincent.palatin_openocd@m4x.org                                       *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ETM_H\n#define OPENOCD_TARGET_ETM_H\n\n#include \"trace.h\"\n#include \"arm_jtag.h\"\n\nstruct image;\n\n/* ETM registers (JTAG protocol) */\nenum {\n\tETM_CTRL = 0x00,\n\tETM_CONFIG = 0x01,\n\tETM_TRIG_EVENT = 0x02,\n\tETM_ASIC_CTRL = 0x03,\n\tETM_STATUS = 0x04,\n\tETM_SYS_CONFIG = 0x05,\n\tETM_TRACE_RESOURCE_CTRL = 0x06,\n\tETM_TRACE_EN_CTRL2 = 0x07,\n\tETM_TRACE_EN_EVENT = 0x08,\n\tETM_TRACE_EN_CTRL1 = 0x09,\n\t/* optional FIFOFULL */\n\tETM_FIFOFULL_REGION = 0x0a,\n\tETM_FIFOFULL_LEVEL = 0x0b,\n\t/* viewdata support */\n\tETM_VIEWDATA_EVENT = 0x0c,\n\tETM_VIEWDATA_CTRL1 = 0x0d,\n\tETM_VIEWDATA_CTRL2 = 0x0e,\t/* optional */\n\tETM_VIEWDATA_CTRL3 = 0x0f,\n\t/* N pairs of ADDR_{COMPARATOR,ACCESS} registers */\n\tETM_ADDR_COMPARATOR_VALUE = 0x10,\n\tETM_ADDR_ACCESS_TYPE = 0x20,\n\t/* N pairs of DATA_COMPARATOR_{VALUE,MASK} registers */\n\tETM_DATA_COMPARATOR_VALUE = 0x30,\n\tETM_DATA_COMPARATOR_MASK = 0x40,\n\t/* N quads of COUNTER_{RELOAD_{VALUE,EVENT},ENABLE,VALUE} registers */\n\tETM_COUNTER_RELOAD_VALUE = 0x50,\n\tETM_COUNTER_ENABLE = 0x54,\n\tETM_COUNTER_RELOAD_EVENT = 0x58,\n\tETM_COUNTER_VALUE = 0x5c,\n\t/* 6 sequencer event transitions */\n\tETM_SEQUENCER_EVENT = 0x60,\n\tETM_SEQUENCER_STATE = 0x67,\n\t/* N triggered outputs */\n\tETM_EXTERNAL_OUTPUT = 0x68,\n\t/* N task contexts */\n\tETM_CONTEXTID_COMPARATOR_VALUE = 0x6c,\n\tETM_CONTEXTID_COMPARATOR_MASK = 0x6f,\n\tETM_ID = 0x79,\n};\n\nstruct etm_reg {\n\tuint8_t value[4];\n\tconst struct etm_reg_info *reg_info;\n\tstruct arm_jtag *jtag_info;\n};\n\n/* Subset of ETM_CTRL bit assignments.  Many of these\n * control the configuration of trace output, which\n * hooks up either to ETB or to an external device.\n *\n * NOTE that these have evolved since the ~v1.3 defns ...\n */\nenum {\n\tETM_CTRL_POWERDOWN\t= (1 << 0),\n\tETM_CTRL_MONITOR_CPRT\t= (1 << 1),\n\n\t/* bits 3:2 == trace type */\n\tETM_CTRL_TRACE_DATA\t= (1 << 2),\n\tETM_CTRL_TRACE_ADDR\t= (2 << 2),\n\tETM_CTRL_TRACE_MASK\t= (3 << 2),\n\n\t/* Port width (bits 21 and 6:4) */\n\tETM_PORT_4BIT\t\t= 0x00,\n\tETM_PORT_8BIT\t\t= 0x10,\n\tETM_PORT_16BIT\t\t= 0x20,\n\tETM_PORT_24BIT\t\t= 0x30,\n\tETM_PORT_32BIT\t\t= 0x40,\n\tETM_PORT_48BIT\t\t= 0x50,\n\tETM_PORT_64BIT\t\t= 0x60,\n\tETM_PORT_1BIT\t\t= 0x00 | (1 << 21),\n\tETM_PORT_2BIT\t\t= 0x10 | (1 << 21),\n\tETM_PORT_WIDTH_MASK\t= 0x70 | (1 << 21),\n\n\tETM_CTRL_FIFOFULL_STALL\t= (1 << 7),\n\tETM_CTRL_BRANCH_OUTPUT\t= (1 << 8),\n\tETM_CTRL_DBGRQ\t\t= (1 << 9),\n\tETM_CTRL_ETM_PROG\t= (1 << 10),\n\tETM_CTRL_ETMEN\t\t= (1 << 11),\n\tETM_CTRL_CYCLE_ACCURATE\t= (1 << 12),\n\n\t/* Clocking modes -- up to v2.1, bit 13 */\n\tETM_PORT_FULL_CLOCK\t= (0 << 13),\n\tETM_PORT_HALF_CLOCK\t= (1 << 13),\n\tETM_PORT_CLOCK_MASK\t= (1 << 13),\n\n\t/* bits 15:14 == context ID size used in tracing */\n\tETM_CTRL_CONTEXTID_NONE\t= (0 << 14),\n\tETM_CTRL_CONTEXTID_8\t= (1 << 14),\n\tETM_CTRL_CONTEXTID_16\t= (2 << 14),\n\tETM_CTRL_CONTEXTID_32\t= (3 << 14),\n\tETM_CTRL_CONTEXTID_MASK\t= (3 << 14),\n\n\t/* Port modes -- bits 17:16, tied to clocking mode */\n\tETM_PORT_NORMAL\t\t= (0 << 16),\n\tETM_PORT_MUXED\t\t= (1 << 16),\n\tETM_PORT_DEMUXED\t= (2 << 16),\n\tETM_PORT_MODE_MASK\t= (3 << 16),\n\n\t/* bits 31:18 defined in v3.0 and later (e.g. ARM11+) */\n};\n\n/* forward-declare ETM context */\nstruct etm_context;\n\nstruct etm_capture_driver {\n\tconst char *name;\n\tconst struct command_registration *commands;\n\tint (*init)(struct etm_context *etm_ctx);\n\ttrace_status_t (*status)(struct etm_context *etm_ctx);\n\tint (*read_trace)(struct etm_context *etm_ctx);\n\tint (*start_capture)(struct etm_context *etm_ctx);\n\tint (*stop_capture)(struct etm_context *etm_ctx);\n};\n\nenum {\n\tETMV1_TRACESYNC_CYCLE = 0x1,\n\tETMV1_TRIGGER_CYCLE = 0x2,\n};\n\nstruct etmv1_trace_data {\n\tuint8_t pipestat;\t/* bits 0-2 pipeline status */\n\tuint16_t packet;\t\t/* packet data (4, 8 or 16 bit) */\n\tint flags;\t\t/* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */\n};\n\n/* describe a trace context\n * if support for ETMv2 or ETMv3 is to be implemented,\n * this will have to be split into version independent elements\n * and a version specific part\n */\nstruct etm_context {\n\tstruct target *target;\t\t/* target this ETM is connected to */\n\tstruct reg_cache *reg_cache;\t\t/* ETM register cache */\n\tstruct etm_capture_driver *capture_driver;\t/* driver used to access ETM data */\n\tvoid *capture_driver_priv;\t/* capture driver private data */\n\ttrace_status_t capture_status;\t/* current state of capture run */\n\tstruct etmv1_trace_data *trace_data;\t/* trace data */\n\tuint32_t trace_depth;\t\t/* number of cycles to be analyzed, 0 if no data available */\n\tuint32_t control;\t/* shadow of ETM_CTRL */\n\tint /*arm_state*/ core_state;\t/* current core state */\n\tstruct image *image;\t\t/* source for target opcodes */\n\tuint32_t pipe_index;\t\t/* current trace cycle */\n\tuint32_t data_index;\t\t/* cycle holding next data packet */\n\tbool data_half;\t\t\t/* port half on a 16 bit port */\n\tbool pc_ok;\t\t\t/* full PC has been acquired */\n\tbool ptr_ok;\t\t\t/* whether last_ptr is valid */\n\tuint8_t bcd_vers;\t\t/* e.g. 0x13 == ETMv1.3 */\n\tuint32_t config;\t\t/* cache of ETM_CONFIG value */\n\tuint32_t id;\t\t\t/* cache of ETM_ID value, or 0 */\n\tuint32_t current_pc;\t\t/* current program counter */\n\tuint32_t last_branch;\t\t/* last branch address output */\n\tuint32_t last_branch_reason;\t/* type of last branch encountered */\n\tuint32_t last_ptr;\t\t/* address of the last data access */\n\tuint32_t last_instruction;\t/* index of last executed (to calc timings) */\n};\n\n/* PIPESTAT values */\ntypedef enum {\n\tSTAT_IE = 0x0,\n\tSTAT_ID = 0x1,\n\tSTAT_IN = 0x2,\n\tSTAT_WT = 0x3,\n\tSTAT_BE = 0x4,\n\tSTAT_BD = 0x5,\n\tSTAT_TR = 0x6,\n\tSTAT_TD = 0x7\n} etmv1_pipestat_t;\n\n/* branch reason values */\ntypedef enum {\n\tBR_NORMAL  = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */\n\tBR_ENABLE  = 0x1, /* Trace has been enabled */\n\tBR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */\n\tBR_NODEBUG = 0x3, /* ARM has exited for debug state */\n\tBR_PERIOD  = 0x4, /* Periodic synchronization point (ETM >= v1.2)*/\n\tBR_RSVD5   = 0x5, /* reserved */\n\tBR_RSVD6   = 0x6, /* reserved */\n\tBR_RSVD7   = 0x7, /* reserved */\n} etmv1_branch_reason_t;\n\nstruct reg_cache *etm_build_reg_cache(struct target *target,\n\t\tstruct arm_jtag *jtag_info, struct etm_context *etm_ctx);\n\nint etm_setup(struct target *target);\n\nextern const struct command_registration etm_command_handlers[];\n\n#define ERROR_ETM_INVALID_DRIVER\t(-1300)\n#define ERROR_ETM_PORTMODE_NOT_SUPPORTED\t(-1301)\n#define ERROR_ETM_CAPTURE_INIT_FAILED\t(-1302)\n#define ERROR_ETM_ANALYSIS_FAILED\t(-1303)\n\n#endif /* OPENOCD_TARGET_ETM_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etm_dummy.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm.h\"\n#include \"etm_dummy.h\"\n\nCOMMAND_HANDLER(handle_etm_dummy_config_command)\n{\n\tstruct target *target;\n\tstruct arm *arm;\n\n\ttarget = get_target(CMD_ARGV[0]);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tarm = target_to_arm(target);\n\tif (!is_arm(arm)) {\n\t\tcommand_print(CMD, \"target '%s' isn't an ARM\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (arm->etm)\n\t\tarm->etm->capture_driver_priv = NULL;\n\telse {\n\t\tLOG_ERROR(\"target has no ETM defined, ETM dummy left unconfigured\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration etm_dummy_config_command_handlers[] = {\n\t{\n\t\t.name = \"config\",\n\t\t.handler = handle_etm_dummy_config_command,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"target\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration etm_dummy_command_handlers[] = {\n\t{\n\t\t.name = \"etm_dummy\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Dummy ETM capture driver command group\",\n\t\t.chain = etm_dummy_config_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int etm_dummy_init(struct etm_context *etm_ctx)\n{\n\treturn ERROR_OK;\n}\n\nstatic trace_status_t etm_dummy_status(struct etm_context *etm_ctx)\n{\n\treturn TRACE_IDLE;\n}\n\nstatic int etm_dummy_read_trace(struct etm_context *etm_ctx)\n{\n\treturn ERROR_OK;\n}\n\nstatic int etm_dummy_start_capture(struct etm_context *etm_ctx)\n{\n\treturn ERROR_ETM_PORTMODE_NOT_SUPPORTED;\n}\n\nstatic int etm_dummy_stop_capture(struct etm_context *etm_ctx)\n{\n\treturn ERROR_OK;\n}\n\nstruct etm_capture_driver etm_dummy_capture_driver = {\n\t.name = \"dummy\",\n\t.commands = etm_dummy_command_handlers,\n\t.init = etm_dummy_init,\n\t.status = etm_dummy_status,\n\t.start_capture = etm_dummy_start_capture,\n\t.stop_capture = etm_dummy_stop_capture,\n\t.read_trace = etm_dummy_read_trace,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/etm_dummy.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_ETM_DUMMY_H\n#define OPENOCD_TARGET_ETM_DUMMY_H\n\n#include \"etm.h\"\n\nextern struct etm_capture_driver etm_dummy_capture_driver;\n\n#endif /* OPENOCD_TARGET_ETM_DUMMY_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/fa526.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 by Paulius Zaleckas                                *\n *   paulius.zaleckas@gmail.com                                            *\n ***************************************************************************/\n\n/*\n * FA526 is very similar to ARM920T with following differences:\n *\n * - execution pipeline is 6 steps\n * - Unified TLB\n * - has Branch Target Buffer\n * - does not support reading of I/D cache contents\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm920t.h\"\n#include \"target_type.h\"\n#include \"arm_opcodes.h\"\n\nstatic void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *pc)\n{\n\tLOG_ERROR(\"%s: there is no Thumb state on FA526\", __func__);\n}\n\nstatic void fa526_read_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t *core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in SHIFT stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, STM in MEMORY (i'th cycle) */\n\t\t\tarm9tdmi_clock_data_in(jtag_info, core_regs[i]);\n\t}\n}\n\nstatic void fa526_read_core_regs_target_buffer(struct target *target,\n\t\tuint32_t mask, void *buffer, int size)\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;\n\tuint32_t *buf_u32 = buffer;\n\tuint16_t *buf_u16 = buffer;\n\tuint8_t *buf_u8 = buffer;\n\n\t/* STMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, STM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in SHIFT stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, STM in MEMORY (i'th cycle) */\n\t\t\tswitch (size) {\n\t\t\t\tcase 4:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t}\n}\n\nstatic void fa526_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* MRS r0, cpsr */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* STR r0, [r15] */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);\n\t/* fetch NOP, STR in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STR in SHIFT stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, STR in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, STR in MEMORY */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);\n}\n\nstatic void fa526_write_xpsr(struct target *target, uint32_t xpsr, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr: %8.8\" PRIx32 \", spsr: %i\", xpsr, spsr);\n\n\t/* MSR1 fetched */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);\n\t/* MSR2 fetched, MSR1 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);\n\t/* MSR3 fetched, MSR1 in SHIFT, MSR2 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);\n\t/* MSR4 fetched, MSR1 in EXECUTE (1), MSR2 in SHIFT, MSR3 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);\n\t/* nothing fetched, MSR1 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR1 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR2 in EXECUTE (1), MSR3 in SHIFT, MSR4 in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR2 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR2 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR3 in EXECUTE (1), MSR4 in SHIFT */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR3 in EXECUTE (2) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, MSR3 in EXECUTE (3) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR4 in EXECUTE (1) */\n\t/* last MSR writes flags, which takes only one cycle */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void fa526_write_xpsr_im8(struct target *target,\n\t\tuint8_t xpsr_im, int rot, int spsr)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr_im: %2.2x, rot: %i, spsr: %i\", xpsr_im, rot, spsr);\n\n\t/* MSR fetched */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);\n\t/* NOP fetched, MSR in DECODE */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR in SHIFT */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* NOP fetched, MSR in EXECUTE (1) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\t/* rot == 4 writes flags, which takes only one cycle */\n\tif (rot != 4) {\n\t\t/* nothing fetched, MSR in EXECUTE (2) */\n\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t\t/* nothing fetched, MSR in EXECUTE (3) */\n\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t}\n}\n\nstatic void fa526_write_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t core_regs[16])\n{\n\tint i;\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t* register values will start to appear on 4th DCLK\n\t*/\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in SHIFT stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i))\n\t\t\t/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */\n\t\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);\n\t}\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void fa526_write_pc(struct target *target, uint32_t pc)\n{\n\tstruct arm7_9_common *arm7_9 = target_to_arm7_9(target);\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/* LDMIA r0-15, [r0] at debug speed\n\t * register values will start to appear on 4th DCLK\n\t */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);\n\n\t/* fetch NOP, LDM in DECODE stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in SHIFT stage */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (1st cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);\n\t/* nothing fetched, LDM in EXECUTE stage (3rd cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (4th cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\t/* fetch NOP, LDM in EXECUTE stage (5th cycle) */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void fa526_branch_resume_thumb(struct target *target)\n{\n\tLOG_ERROR(\"%s: there is no Thumb state on FA526\", __func__);\n}\n\nstatic int fa526_init_arch_info_2(struct target *target,\n\t\tstruct arm7_9_common *arm7_9, struct jtag_tap *tap)\n{\n\t/* prepare JTAG information for the new target */\n\tarm7_9->jtag_info.tap = tap;\n\tarm7_9->jtag_info.scann_size = 5;\n\n\t/* register arch-specific functions */\n\tarm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;\n\tarm7_9->change_to_arm = fa526_change_to_arm;\n\tarm7_9->read_core_regs = fa526_read_core_regs;\n\tarm7_9->read_core_regs_target_buffer = fa526_read_core_regs_target_buffer;\n\tarm7_9->read_xpsr = fa526_read_xpsr;\n\n\tarm7_9->write_xpsr = fa526_write_xpsr;\n\tarm7_9->write_xpsr_im8 = fa526_write_xpsr_im8;\n\tarm7_9->write_core_regs = fa526_write_core_regs;\n\n\tarm7_9->load_word_regs = arm9tdmi_load_word_regs;\n\tarm7_9->load_hword_reg = arm9tdmi_load_hword_reg;\n\tarm7_9->load_byte_reg = arm9tdmi_load_byte_reg;\n\n\tarm7_9->store_word_regs = arm9tdmi_store_word_regs;\n\tarm7_9->store_hword_reg = arm9tdmi_store_hword_reg;\n\tarm7_9->store_byte_reg = arm9tdmi_store_byte_reg;\n\n\tarm7_9->write_pc = fa526_write_pc;\n\tarm7_9->branch_resume = arm9tdmi_branch_resume;\n\tarm7_9->branch_resume_thumb = fa526_branch_resume_thumb;\n\n\tarm7_9->enable_single_step = arm9tdmi_enable_single_step;\n\tarm7_9->disable_single_step = arm9tdmi_disable_single_step;\n\n\tarm7_9->write_memory = arm920t_write_memory;\n\tarm7_9->bulk_write_memory = arm7_9_bulk_write_memory;\n\n\tarm7_9->post_debug_entry = NULL;\n\n\tarm7_9->pre_restore_context = NULL;\n\n\t/* initialize arch-specific breakpoint handling */\n\tarm7_9->arm_bkpt = 0xdeeedeee;\n\tarm7_9->thumb_bkpt = 0xdeee;\n\n\tarm7_9->dbgreq_adjust_pc = 3;\n\n\tarm7_9_init_arch_info(target, arm7_9);\n\n\t/* override use of DBGRQ, this is safe on ARM9TDMI */\n\tarm7_9->use_dbgrq = 1;\n\n\t/* all ARM9s have the vector catch register */\n\tarm7_9->has_vector_catch = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int fa526_init_arch_info(struct target *target,\n\t\tstruct arm920t_common *arm920t, struct jtag_tap *tap)\n{\n\tstruct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;\n\n\t/* initialize arm7/arm9 specific info (including armv4_5) */\n\tfa526_init_arch_info_2(target, arm7_9, tap);\n\n\tarm920t->common_magic = ARM920T_COMMON_MAGIC;\n\n\tarm7_9->post_debug_entry = arm920t_post_debug_entry;\n\tarm7_9->pre_restore_context = arm920t_pre_restore_context;\n\n\tarm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;\n\tarm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;\n\tarm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;\n\tarm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;\n\tarm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;\n\tarm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;\n\tarm920t->armv4_5_mmu.has_tiny_pages = 1;\n\tarm920t->armv4_5_mmu.mmu_enabled = 0;\n\n\t/* disabling linefills leads to lockups, so keep them enabled for now\n\t * this doesn't affect correctness, but might affect timing issues, if\n\t * important data is evicted from the cache during the debug session\n\t * */\n\tarm920t->preserve_cache = 0;\n\n\t/* override hw single-step capability from ARM9TDMI */\n\tarm7_9->has_single_step = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int fa526_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm920t_common *arm920t = calloc(1, sizeof(struct arm920t_common));\n\n\treturn fa526_init_arch_info(target, arm920t, target->tap);\n}\n\nstatic void fa526_deinit_target(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct arm920t_common *arm920t = target_to_arm920(target);\n\n\tarm7_9_deinit(target);\n\tarm_free_reg_cache(arm);\n\tfree(arm920t);\n}\n\n/** Holds methods for FA526 targets. */\nstruct target_type fa526_target = {\n\t.name = \"fa526\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm920t_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = arm7_9_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm920t_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm920t_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm920t_command_handlers,\n\t.target_create = fa526_target_create,\n\t.init_target = arm9tdmi_init_target,\n\t.deinit_target = fa526_deinit_target,\n\t.examine = arm7_9_examine,\n\t.check_reset = arm7_9_check_reset,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/feroceon.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008-2009 by Marvell Semiconductors, Inc.                    *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n *                                                                         *\n *   Copyright (C) 2008 by Hongtao Zheng                                   *\n *   hontor@126.com                                                        *\n ***************************************************************************/\n\n/*\n * Marvell Feroceon/Dragonite support.\n *\n * The Feroceon core, as found in the Orion and Kirkwood SoCs amongst others,\n * mimics the ARM926 ICE interface with the following differences:\n *\n * - the MOE (method of entry) reporting is not implemented\n *\n * - breakpoint/watchpoint comparator #1 is seemingly not implemented\n *\n * - due to a different pipeline implementation, some injected debug\n *   instruction sequences have to be somewhat different\n *\n * Other issues:\n *\n * - asserting DBGRQ doesn't work if target is looping on the undef vector\n *\n * - the EICE version signature in the COMMS_CTL reg is next to the flow bits\n *   not at the top, and rather meaningless due to existing discrepancies\n *\n * - the DCC channel is half duplex (only one FIFO for both directions) with\n *   seemingly no proper flow control.\n *\n * The Dragonite core is the non-mmu version based on the ARM966 model, and\n * it shares the above issues as well.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"arm926ejs.h\"\n#include \"arm966e.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"arm_opcodes.h\"\n\nstatic int feroceon_assert_reset(struct target *target)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tint ud = arm7_9->use_dbgrq;\n\n\t/* TODO: apply hw reset signal in not examined state */\n\tif (!(target_was_examined(target))) {\n\t\tLOG_WARNING(\"Reset is not asserted because the target is not examined.\");\n\t\tLOG_WARNING(\"Use a reset button or power cycle the target.\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tarm7_9->use_dbgrq = 0;\n\tif (target->reset_halt)\n\t\tarm7_9_halt(target);\n\tarm7_9->use_dbgrq = ud;\n\treturn arm7_9_assert_reset(target);\n}\n\nstatic int feroceon_dummy_clock_out(struct arm_jtag *jtag_info, uint32_t instr)\n{\n\tstruct scan_field fields[3];\n\tuint8_t out_buf[4];\n\tuint8_t instr_buf[4];\n\tuint8_t sysspeed_buf = 0x0;\n\tint retval;\n\n\t/* prepare buffer */\n\tbuf_set_u32(out_buf, 0, 32, 0);\n\n\tbuf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));\n\n\tretval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_DRPAUSE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = out_buf;\n\tfields[0].in_value = NULL;\n\n\tfields[1].num_bits = 3;\n\tfields[1].out_value = &sysspeed_buf;\n\tfields[1].in_value = NULL;\n\n\tfields[2].num_bits = 32;\n\tfields[2].out_value = instr_buf;\n\tfields[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);\n\n\t/* no jtag_add_runtest(0, TAP_DRPAUSE) here */\n\n\treturn ERROR_OK;\n}\n\nstatic void feroceon_change_to_arm(struct target *target, uint32_t *r0,\n\t\tuint32_t *pc)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\t/*\n\t * save r0 before using it and put system in ARM state\n\t * to allow common handling of ARM and THUMB debugging\n\t */\n\n\tferoceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);\n\tferoceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);\n\tferoceon_dummy_clock_out(jtag_info, ARMV4_5_T_NOP);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(15), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tjtag_execute_queue();\n\n\t/*\n\t * fix program counter:\n\t * MOV R0, PC was the 7th instruction (+12)\n\t * reading PC in Thumb state gives address of instruction + 4\n\t */\n\t*pc -= (12 + 4);\n}\n\nstatic void feroceon_read_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t *core_regs[16])\n{\n\tint i;\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++)\n\t\tif (mask & (1 << i))\n\t\t\tarm9tdmi_clock_data_in(jtag_info, core_regs[i]);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_read_core_regs_target_buffer(struct target *target,\n\t\tuint32_t mask, void *buffer, int size)\n{\n\tint i;\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;\n\tuint32_t *buf_u32 = buffer;\n\tuint16_t *buf_u16 = buffer;\n\tuint8_t *buf_u8 = buffer;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++) {\n\t\tif (mask & (1 << i)) {\n\t\t\tswitch (size) {\n\t\t\t\tcase 4:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tarm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_write_xpsr(struct target *target, uint32_t xpsr, int spsr)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr: %8.8\" PRIx32 \", spsr: %i\", xpsr, spsr);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_write_xpsr_im8(struct target *target,\n\t\tuint8_t xpsr_im, int rot, int spsr)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tLOG_DEBUG(\"xpsr_im: %2.2x, rot: %i, spsr: %i\", xpsr_im, rot, spsr);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_write_core_regs(struct target *target,\n\t\tuint32_t mask, uint32_t core_regs[16])\n{\n\tint i;\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tfor (i = 0; i <= 15; i++)\n\t\tif (mask & (1 << i))\n\t\t\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n}\n\nstatic void feroceon_branch_resume(struct target *target)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffff9, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n\n\tarm7_9->need_bypass_before_restart = 1;\n}\n\nstatic void feroceon_branch_resume_thumb(struct target *target)\n{\n\tLOG_DEBUG(\"-\");\n\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tuint32_t r0 = buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);\n\tuint32_t pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, 0xE28F0001, 0, NULL, 0); /* add r0,pc,#1 */\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDMIA(0, 0x1), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, r0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);\n\n\tpc = (pc & 2) >> 1;\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7e9 + pc), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 1);\n\n\tarm7_9->need_bypass_before_restart = 1;\n}\n\nstatic int feroceon_read_cp15(struct target *target, uint32_t op1,\n\t\tuint32_t op2, uint32_t crn, uint32_t crm, uint32_t *value)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\tint err;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MRC(15, op1, 0, crn, crm, op2), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n\terr = arm7_9_execute_sys_speed(target);\n\tif (err != ERROR_OK)\n\t\treturn err;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, 1, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, value, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\treturn jtag_execute_queue();\n}\n\nstatic int feroceon_write_cp15(struct target *target, uint32_t op1,\n\t\tuint32_t op2, uint32_t crn, uint32_t crm, uint32_t value)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct arm_jtag *jtag_info = &arm7_9->jtag_info;\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 1, 0, 0), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, value, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);\n\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_MCR(15, op1, 0, crn, crm, op2), 0, NULL, 0);\n\tarm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);\n\treturn arm7_9_execute_sys_speed(target);\n}\n\nstatic void feroceon_set_dbgrq(struct target *target)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tstruct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];\n\n\tbuf_set_u32(dbg_ctrl->value, 0, 8, 2);\n\tembeddedice_store_reg(dbg_ctrl);\n}\n\nstatic void feroceon_enable_single_step(struct target *target, uint32_t next_pc)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\n\t/* set a breakpoint there */\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE], next_pc);\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK], 0);\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK], 0xffffffff);\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE], 0x100);\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK], 0xf7);\n}\n\nstatic void feroceon_disable_single_step(struct target *target)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_VALUE]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_ADDR_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_DATA_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_MASK]);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_W0_CONTROL_VALUE]);\n}\n\nstatic int feroceon_examine_debug_reason(struct target *target)\n{\n\t/* the MOE is not implemented */\n\tif (target->debug_reason != DBG_REASON_SINGLESTEP)\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int feroceon_bulk_write_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t count, const uint8_t *buffer)\n{\n\tint retval;\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tenum arm_state core_state = arm->core_state;\n\tuint32_t x, flip, shift, save[7];\n\tuint32_t i;\n\n\t/*\n\t * We can't use the dcc flow control bits, so let's transfer data\n\t * with 31 bits and flip the MSB each time a new data word is sent.\n\t */\n\tstatic uint32_t dcc_code[] = {\n\t\t0xee115e10,\t/* 3:\tmrc\tp14, 0, r5, c1, c0, 0\t*/\n\t\t0xe3a0301e,\t/* 1:\tmov\tr3, #30\t\t\t*/\n\t\t0xe3a04002,\t/*\tmov\tr4, #2\t\t\t*/\n\t\t0xee111e10,\t/* 2:\tmrc\tp14, 0, r1, c1, c0, 0\t*/\n\t\t0xe1310005,\t/*\tteq\tr1, r5\t\t\t*/\n\t\t0x0afffffc,\t/*\tbeq\t1b\t\t\t*/\n\t\t0xe1a05001,\t/*\tmov\tr5, r1\t\t\t*/\n\t\t0xe1a01081,\t/*\tmov\tr1, r1, lsl #1\t\t*/\n\t\t0xee112e10,\t/* 3:\tmrc\tp14, 0, r2, c1, c0, 0\t*/\n\t\t0xe1320005,\t/*\tteq\tr2, r5\t\t\t*/\n\t\t0x0afffffc,\t/*\tbeq\t3b\t\t\t*/\n\t\t0xe1a05002,\t/*\tmov\tr5, r2\t\t\t*/\n\t\t0xe3c22102,\t/*\tbic\tr2, r2, #0x80000000\t*/\n\t\t0xe1811332,\t/*\torr\tr1, r1, r2, lsr r3\t*/\n\t\t0xe2533001,\t/*\tsubs\tr3, r3, #1\t\t*/\n\t\t0xe4801004,\t/*\tstr\tr1, [r0], #4\t\t*/\n\t\t0xe1a01412,\t/*\tmov\tr1, r2, lsl r4\t\t*/\n\t\t0xe2844001,\t/*\tadd\tr4, r4, #1\t\t*/\n\t\t0x4affffed,\t/*\tbmi\t1b\t\t\t*/\n\t\t0xeafffff3,\t/*\tb\t3b\t\t\t*/\n\t};\n\n\tuint32_t dcc_size = sizeof(dcc_code);\n\n\tif (address % 4 != 0)\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (!arm7_9->dcc_downloads)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* regrab previously allocated working_area, or allocate a new one */\n\tif (!arm7_9->dcc_working_area) {\n\t\tuint8_t dcc_code_buf[dcc_size];\n\n\t\t/* make sure we have a working area */\n\t\tif (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK) {\n\t\t\tLOG_INFO(\"no working area available, falling back to memory writes\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\t/* copy target instructions to target endianness */\n\t\ttarget_buffer_set_u32_array(target, dcc_code_buf, ARRAY_SIZE(dcc_code), dcc_code);\n\n\t\t/* write DCC code to working area, using the non-optimized\n\t\t * memory write to avoid ending up here again */\n\t\tretval = arm7_9_write_memory_no_opt(target,\n\t\t\t\tarm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* backup clobbered processor state */\n\tfor (i = 0; i <= 5; i++)\n\t\tsave[i] = buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32);\n\tsave[i] = buf_get_u32(arm->pc->value, 0, 32);\n\n\t/* set up target address in r0 */\n\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, address);\n\tarm->core_cache->reg_list[0].valid = true;\n\tarm->core_cache->reg_list[0].dirty = true;\n\tarm->core_state = ARM_STATE_ARM;\n\n\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], 0);\n\tarm7_9_resume(target, 0, arm7_9->dcc_working_area->address, 1, 1);\n\n\t/* send data over */\n\tx = 0;\n\tflip = 0;\n\tshift = 1;\n\tfor (i = 0; i < count; i++) {\n\t\tuint32_t y = target_buffer_get_u32(target, buffer);\n\t\tuint32_t z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000);\n\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);\n\t\tx = y << (32 - shift);\n\t\tif (++shift >= 32 || i + 1 >= count) {\n\t\t\tz = (x >> 1) | (flip ^= 0x80000000);\n\t\t\tembeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);\n\t\t\tx = 0;\n\t\t\tshift = 1;\n\t\t}\n\t\tbuffer += 4;\n\t}\n\n\tretval = target_halt(target);\n\tif (retval == ERROR_OK)\n\t\tretval = target_wait_state(target, TARGET_HALTED, 500);\n\tif (retval == ERROR_OK) {\n\t\tuint32_t endaddress =\n\t\t\tbuf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);\n\t\tif (endaddress != address + count*4) {\n\t\t\tLOG_ERROR(\"DCC write failed,\"\n\t\t\t\t\" expected end address 0x%08\" TARGET_PRIxADDR\n\t\t\t\t\" got 0x%0\" PRIx32 \"\",\n\t\t\t\taddress + count*4, endaddress);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* restore target state */\n\tfor (i = 0; i <= 5; i++) {\n\t\tbuf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, save[i]);\n\t\tarm->core_cache->reg_list[i].valid = true;\n\t\tarm->core_cache->reg_list[i].dirty = true;\n\t}\n\tbuf_set_u32(arm->pc->value, 0, 32, save[i]);\n\tarm->pc->valid = true;\n\tarm->pc->dirty = true;\n\tarm->core_state = core_state;\n\n\treturn retval;\n}\n\nstatic int feroceon_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tarm9tdmi_init_target(cmd_ctx, target);\n\treturn ERROR_OK;\n}\n\nstatic void feroceon_deinit_target(struct target *target)\n{\n\tarm9tdmi_deinit_target(target);\n}\n\nstatic void feroceon_common_setup(struct target *target)\n{\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\n\t/* override some insn sequence functions */\n\tarm7_9->change_to_arm = feroceon_change_to_arm;\n\tarm7_9->read_core_regs = feroceon_read_core_regs;\n\tarm7_9->read_core_regs_target_buffer = feroceon_read_core_regs_target_buffer;\n\tarm7_9->read_xpsr = feroceon_read_xpsr;\n\tarm7_9->write_xpsr = feroceon_write_xpsr;\n\tarm7_9->write_xpsr_im8 = feroceon_write_xpsr_im8;\n\tarm7_9->write_core_regs = feroceon_write_core_regs;\n\tarm7_9->branch_resume = feroceon_branch_resume;\n\tarm7_9->branch_resume_thumb = feroceon_branch_resume_thumb;\n\n\t/* must be implemented with only one comparator */\n\tarm7_9->enable_single_step = feroceon_enable_single_step;\n\tarm7_9->disable_single_step = feroceon_disable_single_step;\n\n\tarm7_9->bulk_write_memory = feroceon_bulk_write_memory;\n\n\t/* MOE is not implemented */\n\tarm7_9->examine_debug_reason = feroceon_examine_debug_reason;\n\n\t/* Note: asserting DBGRQ might not win over the undef exception.\n\t   If that happens then just use \"arm7_9 dbgrq disable\". */\n\tarm7_9->use_dbgrq = 1;\n\tarm7_9->set_special_dbgrq = feroceon_set_dbgrq;\n\n\t/* only one working comparator */\n\tarm7_9->wp_available_max = 1;\n\tarm7_9->wp1_used_default = -1;\n}\n\nstatic int feroceon_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common));\n\n\tarm926ejs_init_arch_info(target, arm926ejs, target->tap);\n\tferoceon_common_setup(target);\n\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tarm7_9->write_memory = arm926ejs_write_memory;\n\n\t/* the standard ARM926 methods don't always work (don't ask...) */\n\tarm926ejs->read_cp15 = feroceon_read_cp15;\n\tarm926ejs->write_cp15 = feroceon_write_cp15;\n\n\treturn ERROR_OK;\n}\n\nstatic int dragonite_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));\n\n\tarm966e_init_arch_info(target, arm966e, target->tap);\n\tferoceon_common_setup(target);\n\n\tstruct arm *arm = target->arch_info;\n\tstruct arm7_9_common *arm7_9 = arm->arch_info;\n\tarm7_9->write_memory = arm7_9_write_memory;\n\n\treturn ERROR_OK;\n}\n\nstatic int feroceon_examine(struct target *target)\n{\n\tstruct arm *arm;\n\tstruct arm7_9_common *arm7_9;\n\tint retval;\n\n\tretval = arm7_9_examine(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tarm = target->arch_info;\n\tarm7_9 = arm->arch_info;\n\n\t/* the COMMS_CTRL bits are all contiguous */\n\tif (buf_get_u32(arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL].value, 2, 4) != 6)\n\t\tLOG_ERROR(\"unexpected Feroceon EICE version signature\");\n\n\tarm7_9->eice_cache->reg_list[EICE_DBG_CTRL].size = 6;\n\tarm7_9->eice_cache->reg_list[EICE_DBG_STAT].size = 5;\n\tarm7_9->has_monitor_mode = 1;\n\n\t/* vector catch reg is not initialized on reset */\n\tembeddedice_set_reg(&arm7_9->eice_cache->reg_list[EICE_VEC_CATCH], 0);\n\n\t/* clear monitor mode, enable comparators */\n\tembeddedice_read_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);\n\tjtag_execute_queue();\n\tbuf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 4, 1, 0);\n\tbuf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 5, 1, 0);\n\tembeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);\n\n\treturn ERROR_OK;\n}\n\nstruct target_type feroceon_target = {\n\t.name = \"feroceon\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm926ejs_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = feroceon_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm926ejs_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm926ejs_command_handlers,\n\t.target_create = feroceon_target_create,\n\t.init_target = feroceon_init_target,\n\t.deinit_target = feroceon_deinit_target,\n\t.examine = feroceon_examine,\n};\n\nstruct target_type dragonite_target = {\n\t.name = \"dragonite\",\n\n\t.poll = arm7_9_poll,\n\t.arch_state = arm_arch_state,\n\n\t.target_request_data = arm7_9_target_request_data,\n\n\t.halt = arm7_9_halt,\n\t.resume = arm7_9_resume,\n\t.step = arm7_9_step,\n\n\t.assert_reset = feroceon_assert_reset,\n\t.deassert_reset = arm7_9_deassert_reset,\n\t.soft_reset_halt = arm7_9_soft_reset_halt,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = arm7_9_read_memory,\n\t.write_memory = arm7_9_write_memory_opt,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = arm7_9_add_breakpoint,\n\t.remove_breakpoint = arm7_9_remove_breakpoint,\n\t.add_watchpoint = arm7_9_add_watchpoint,\n\t.remove_watchpoint = arm7_9_remove_watchpoint,\n\n\t.commands = arm966e_command_handlers,\n\t.target_create = dragonite_target_create,\n\t.init_target = feroceon_init_target,\n\t.examine = feroceon_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/hla_target.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Mathias Kuester                                 *\n *   Mathias Kuester <kesmtp@freenet.de>                                   *\n *                                                                         *\n *   Copyright (C) 2011 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   revised:  4/25/13 by brent@mbari.org [DCC target request support]\t   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"jtag/interface.h\"\n#include \"jtag/jtag.h\"\n#include \"jtag/hla/hla_transport.h\"\n#include \"jtag/hla/hla_interface.h\"\n#include \"jtag/hla/hla_layout.h\"\n#include \"register.h\"\n#include \"algorithm.h\"\n#include \"target.h\"\n#include \"breakpoints.h\"\n#include \"target_type.h\"\n#include \"armv7m.h\"\n#include \"cortex_m.h\"\n#include \"arm_adi_v5.h\"\n#include \"arm_semihosting.h\"\n#include \"target_request.h\"\n#include <rtt/rtt.h>\n\n#define SAVED_DCRDR  dbgbase  /* FIXME: using target->dbgbase to preserve DCRDR */\n\n#define ARMV7M_SCS_DCRSR\tDCB_DCRSR\n#define ARMV7M_SCS_DCRDR\tDCB_DCRDR\n\nstatic inline struct hl_interface_s *target_to_adapter(struct target *target)\n{\n\treturn target->tap->priv;\n}\n\nstatic int adapter_load_core_reg_u32(struct target *target,\n\t\tuint32_t regsel, uint32_t *value)\n{\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\treturn adapter->layout->api->read_reg(adapter->handle, regsel, value);\n}\n\nstatic int adapter_store_core_reg_u32(struct target *target,\n\t\tuint32_t regsel, uint32_t value)\n{\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\treturn adapter->layout->api->write_reg(adapter->handle, regsel, value);\n}\n\nstatic int adapter_examine_debug_reason(struct target *target)\n{\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_dcc_read(struct hl_interface_s *hl_if, uint8_t *value, uint8_t *ctrl)\n{\n\tuint16_t dcrdr;\n\tint retval = hl_if->layout->api->read_mem(hl_if->handle,\n\t\t\tDCB_DCRDR, 1, sizeof(dcrdr), (uint8_t *)&dcrdr);\n\tif (retval == ERROR_OK) {\n\t    *ctrl = (uint8_t)dcrdr;\n\t    *value = (uint8_t)(dcrdr >> 8);\n\n\t    LOG_DEBUG(\"data 0x%x ctrl 0x%x\", *value, *ctrl);\n\n\t    if (dcrdr & 1) {\n\t\t\t/* write ack back to software dcc register\n\t\t\t * to signify we have read data */\n\t\t\t/* atomically clear just the byte containing the busy bit */\n\t\t\tstatic const uint8_t zero;\n\t\t\tretval = hl_if->layout->api->write_mem(hl_if->handle, DCB_DCRDR, 1, 1, &zero);\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int hl_target_request_data(struct target *target,\n\tuint32_t size, uint8_t *buffer)\n{\n\tstruct hl_interface_s *hl_if = target_to_adapter(target);\n\tuint8_t data;\n\tuint8_t ctrl;\n\tuint32_t i;\n\n\tfor (i = 0; i < (size * 4); i++) {\n\t\tint err = hl_dcc_read(hl_if, &data, &ctrl);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\tbuffer[i] = data;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_handle_target_request(void *priv)\n{\n\tstruct target *target = priv;\n\tint err;\n\n\tif (!target_was_examined(target))\n\t\treturn ERROR_OK;\n\tstruct hl_interface_s *hl_if = target_to_adapter(target);\n\n\tif (!target->dbg_msg_enabled)\n\t\treturn ERROR_OK;\n\n\tif (target->state == TARGET_RUNNING) {\n\t\tuint8_t data;\n\t\tuint8_t ctrl;\n\n\t\terr = hl_dcc_read(hl_if, &data, &ctrl);\n\t\tif (err != ERROR_OK)\n\t\t\treturn err;\n\n\t\t/* check if we have data */\n\t\tif (ctrl & (1 << 0)) {\n\t\t\tuint32_t request;\n\n\t\t\t/* we assume target is quick enough */\n\t\t\trequest = data;\n\t\t\terr = hl_dcc_read(hl_if, &data, &ctrl);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\trequest |= (data << 8);\n\t\t\terr = hl_dcc_read(hl_if, &data, &ctrl);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\trequest |= (data << 16);\n\t\t\terr = hl_dcc_read(hl_if, &data, &ctrl);\n\t\t\tif (err != ERROR_OK)\n\t\t\t\treturn err;\n\n\t\t\trequest |= (data << 24);\n\t\t\ttarget_request(target, request);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_init_arch_info(struct target *target,\n\t\t\t\t       struct cortex_m_common *cortex_m,\n\t\t\t\t       struct jtag_tap *tap)\n{\n\tstruct armv7m_common *armv7m;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tarmv7m = &cortex_m->armv7m;\n\tarmv7m_init_arch_info(target, armv7m);\n\n\tarmv7m->load_core_reg_u32 = adapter_load_core_reg_u32;\n\tarmv7m->store_core_reg_u32 = adapter_store_core_reg_u32;\n\n\tarmv7m->examine_debug_reason = adapter_examine_debug_reason;\n\tarmv7m->is_hla_target = true;\n\n\ttarget_register_timer_callback(hl_handle_target_request, 1,\n\t\tTARGET_TIMER_TYPE_PERIODIC, target);\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_init_target(struct command_context *cmd_ctx,\n\t\t\t\t    struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tarmv7m_build_reg_cache(target);\n\tarm_semihosting_init(target);\n\treturn ERROR_OK;\n}\n\nstatic int adapter_target_create(struct target *target,\n\t\tJim_Interp *interp)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\tstruct adiv5_private_config *pc = target->private_config;\n\tif (pc && pc->ap_num != DP_APSEL_INVALID && pc->ap_num != 0) {\n\t\tLOG_ERROR(\"hla_target: invalid parameter -ap-num (> 0)\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));\n\tif (!cortex_m) {\n\t\tLOG_ERROR(\"No memory creating target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcortex_m->common_magic = CORTEX_M_COMMON_MAGIC;\n\n\tadapter_init_arch_info(target, cortex_m, target->tap);\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_load_context(struct target *target)\n{\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tint num_regs = armv7m->arm.core_cache->num_regs;\n\n\tfor (int i = 0; i < num_regs; i++) {\n\n\t\tstruct reg *r = &armv7m->arm.core_cache->reg_list[i];\n\t\tif (r->exist && !r->valid)\n\t\t\tarmv7m->arm.read_core_reg(target, r, i, ARM_MODE_ANY);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_debug_entry(struct target *target)\n{\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct arm *arm = &armv7m->arm;\n\tstruct reg *r;\n\tuint32_t xpsr;\n\tint retval;\n\n\t/* preserve the DCRDR across halts */\n\tretval = target_read_u32(target, DCB_DCRDR, &target->SAVED_DCRDR);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = armv7m->examine_debug_reason(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tadapter_load_context(target);\n\n\t/* make sure we clear the vector catch bit */\n\tadapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);\n\n\tr = arm->cpsr;\n\txpsr = buf_get_u32(r->value, 0, 32);\n\n\t/* Are we in an exception handler */\n\tif (xpsr & 0x1FF) {\n\t\tarmv7m->exception_number = (xpsr & 0x1FF);\n\n\t\tarm->core_mode = ARM_MODE_HANDLER;\n\t\tarm->map = armv7m_msp_reg_map;\n\t} else {\n\t\tunsigned control = buf_get_u32(arm->core_cache\n\t\t\t\t->reg_list[ARMV7M_CONTROL].value, 0, 3);\n\n\t\t/* is this thread privileged? */\n\t\tarm->core_mode = control & 1\n\t\t\t\t? ARM_MODE_USER_THREAD\n\t\t\t\t: ARM_MODE_THREAD;\n\n\t\t/* which stack is it using? */\n\t\tif (control & 2)\n\t\t\tarm->map = armv7m_psp_reg_map;\n\t\telse\n\t\t\tarm->map = armv7m_msp_reg_map;\n\n\t\tarmv7m->exception_number = 0;\n\t}\n\n\tLOG_DEBUG(\"entered debug state in core mode: %s at PC 0x%08\" PRIx32 \", target->state: %s\",\n\t\tarm_mode_name(arm->core_mode),\n\t\tbuf_get_u32(arm->pc->value, 0, 32),\n\t\ttarget_state_name(target));\n\n\treturn retval;\n}\n\nstatic int adapter_poll(struct target *target)\n{\n\tenum target_state state;\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tenum target_state prev_target_state = target->state;\n\n\tstate = adapter->layout->api->state(adapter->handle);\n\n\tif (state == TARGET_UNKNOWN) {\n\t\tLOG_ERROR(\"jtag status contains invalid mode value - communication failure\");\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\n\tif (prev_target_state == state)\n\t\treturn ERROR_OK;\n\n\tif (prev_target_state == TARGET_DEBUG_RUNNING && state == TARGET_RUNNING)\n\t\treturn ERROR_OK;\n\n\ttarget->state = state;\n\n\tif (state == TARGET_HALTED) {\n\n\t\tint retval = adapter_debug_entry(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (prev_target_state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t} else {\n\t\t\tif (arm_semihosting(target, &retval) != 0)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t}\n\n\t\tLOG_DEBUG(\"halted: PC: 0x%08\" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_assert_reset(struct target *target)\n{\n\tint res = ERROR_OK;\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tbool use_srst_fallback = true;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tbool srst_asserted = false;\n\n\tif ((jtag_reset_config & RESET_HAS_SRST) &&\n\t    (jtag_reset_config & RESET_SRST_NO_GATING)) {\n\t\tres = adapter_assert_reset();\n\t\tsrst_asserted = true;\n\t}\n\n\tadapter->layout->api->write_debug_reg(adapter->handle, DCB_DHCSR, DBGKEY|C_DEBUGEN);\n\n\tif (!target_was_examined(target) && !target->defer_examine\n\t\t&& srst_asserted && res == ERROR_OK) {\n\t\t/* If the target is not examined, now under reset it is good time to retry examination */\n\t\tLOG_TARGET_DEBUG(target, \"Trying to re-examine under reset\");\n\t\ttarget_examine_one(target);\n\t}\n\n\t/* only set vector catch if halt is requested */\n\tif (target->reset_halt)\n\t\tadapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA|VC_CORERESET);\n\telse\n\t\tadapter->layout->api->write_debug_reg(adapter->handle, DCB_DEMCR, TRCENA);\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\tif (!srst_asserted) {\n\t\t\tres = adapter_assert_reset();\n\t\t}\n\t\tif (res == ERROR_COMMAND_NOTFOUND)\n\t\t\tLOG_ERROR(\"Hardware srst not supported, falling back to software reset\");\n\t\telse if (res == ERROR_OK) {\n\t\t\t/* hardware srst supported */\n\t\t\tuse_srst_fallback = false;\n\t\t}\n\t}\n\n\tif (use_srst_fallback) {\n\t\t/* stlink v1 api does not support hardware srst, so we use a software reset fallback */\n\t\tadapter->layout->api->write_debug_reg(adapter->handle, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);\n\t}\n\n\tres = adapter->layout->api->reset(adapter->handle);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\tif (target->reset_halt) {\n\t\ttarget->state = TARGET_RESET;\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t} else {\n\t\ttarget->state = TARGET_HALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int hl_deassert_reset(struct target *target)\n{\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (jtag_reset_config & RESET_HAS_SRST)\n\t\tadapter_deassert_reset();\n\n\ttarget->SAVED_DCRDR = 0;  /* clear both DCC busy bits on initial resume */\n\n\treturn target->reset_halt ? ERROR_OK : target_resume(target, 1, 0, 0, 0);\n}\n\nstatic int adapter_halt(struct target *target)\n{\n\tint res;\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tres = adapter->layout->api->halt(adapter->handle);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_resume(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints,\n\t\tint debug_execution)\n{\n\tint res;\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tuint32_t resume_pc;\n\tstruct breakpoint *breakpoint = NULL;\n\tstruct reg *pc;\n\n\tLOG_DEBUG(\"%s %d \" TARGET_ADDR_FMT \" %d %d\", __func__, current,\n\t\t\taddress, handle_breakpoints, debug_execution);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tcortex_m_enable_breakpoints(target);\n\t\tcortex_m_enable_watchpoints(target);\n\t}\n\n\tpc = armv7m->arm.pc;\n\tif (!current) {\n\t\tbuf_set_u32(pc->value, 0, 32, address);\n\t\tpc->dirty = true;\n\t\tpc->valid = true;\n\t}\n\n\tif (!breakpoint_find(target, buf_get_u32(pc->value, 0, 32))\n\t\t\t&& !debug_execution) {\n\t\tarmv7m_maybe_skip_bkpt_inst(target, NULL);\n\t}\n\n\tresume_pc = buf_get_u32(pc->value, 0, 32);\n\n\t/* write any user vector flags */\n\tres = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tarmv7m_restore_context(target);\n\n\t/* restore SAVED_DCRDR */\n\tres = target_write_u32(target, DCB_DCRDR, target->SAVED_DCRDR);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at \" TARGET_ADDR_FMT \" (ID: %\" PRIu32 \")\",\n\t\t\t\t\tbreakpoint->address,\n\t\t\t\t\tbreakpoint->unique_id);\n\t\t\tcortex_m_unset_breakpoint(target, breakpoint);\n\n\t\t\tres = adapter->layout->api->step(adapter->handle);\n\n\t\t\tif (res != ERROR_OK)\n\t\t\t\treturn res;\n\n\t\t\tcortex_m_set_breakpoint(target, breakpoint);\n\t\t}\n\t}\n\n\tres = adapter->layout->api->run(adapter->handle);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\tint res;\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\tstruct armv7m_common *armv7m = target_to_armv7m(target);\n\tstruct breakpoint *breakpoint = NULL;\n\tstruct reg *pc = armv7m->arm.pc;\n\tbool bkpt_inst_found = false;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!current) {\n\t\tbuf_set_u32(pc->value, 0, 32, address);\n\t\tpc->dirty = true;\n\t\tpc->valid = true;\n\t}\n\n\tuint32_t pc_value = buf_get_u32(pc->value, 0, 32);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target, pc_value);\n\t\tif (breakpoint)\n\t\t\tcortex_m_unset_breakpoint(target, breakpoint);\n\t}\n\n\tarmv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tarmv7m_restore_context(target);\n\n\t/* restore SAVED_DCRDR */\n\tres = target_write_u32(target, DCB_DCRDR, target->SAVED_DCRDR);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\tres = adapter->layout->api->step(adapter->handle);\n\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(armv7m->arm.core_cache);\n\n\tif (breakpoint)\n\t\tcortex_m_set_breakpoint(target, breakpoint);\n\n\tadapter_debug_entry(target);\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\tLOG_INFO(\"halted: PC: 0x%08\" PRIx32, buf_get_u32(armv7m->arm.pc->value, 0, 32));\n\n\treturn ERROR_OK;\n}\n\nstatic int adapter_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count,\n\t\tuint8_t *buffer)\n{\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\n\tif (!count || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"%s \" TARGET_ADDR_FMT \" %\" PRIu32 \" %\" PRIu32,\n\t\t\t  __func__, address, size, count);\n\n\treturn adapter->layout->api->read_mem(adapter->handle, address, size, count, buffer);\n}\n\nstatic int adapter_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count,\n\t\tconst uint8_t *buffer)\n{\n\tstruct hl_interface_s *adapter = target_to_adapter(target);\n\n\tif (!count || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"%s \" TARGET_ADDR_FMT \" %\" PRIu32 \" %\" PRIu32,\n\t\t\t  __func__, address, size, count);\n\n\treturn adapter->layout->api->write_mem(adapter->handle, address, size, count, buffer);\n}\n\nstatic const struct command_registration hla_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.chain = armv7m_trace_command_handlers,\n\t},\n\t{\n\t\t.chain = rtt_target_command_handlers,\n\t},\n\t/* START_DEPRECATED_TPIU */\n\t{\n\t\t.chain = arm_tpiu_deprecated_command_handlers,\n\t},\n\t/* END_DEPRECATED_TPIU */\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type hla_target = {\n\t.name = \"hla_target\",\n\n\t.init_target = adapter_init_target,\n\t.deinit_target = cortex_m_deinit_target,\n\t.target_create = adapter_target_create,\n\t.target_jim_configure = adiv5_jim_configure,\n\t.examine = cortex_m_examine,\n\t.commands = hla_command_handlers,\n\n\t.poll = adapter_poll,\n\t.arch_state = armv7m_arch_state,\n\n\t.target_request_data = hl_target_request_data,\n\t.assert_reset = hl_assert_reset,\n\t.deassert_reset = hl_deassert_reset,\n\n\t.halt = adapter_halt,\n\t.resume = adapter_resume,\n\t.step = adapter_step,\n\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = armv7m_get_gdb_reg_list,\n\n\t.read_memory = adapter_read_memory,\n\t.write_memory = adapter_write_memory,\n\t.checksum_memory = armv7m_checksum_memory,\n\t.blank_check_memory = armv7m_blank_check_memory,\n\n\t.run_algorithm = armv7m_run_algorithm,\n\t.start_algorithm = armv7m_start_algorithm,\n\t.wait_algorithm = armv7m_wait_algorithm,\n\n\t.add_breakpoint = cortex_m_add_breakpoint,\n\t.remove_breakpoint = cortex_m_remove_breakpoint,\n\t.add_watchpoint = cortex_m_add_watchpoint,\n\t.remove_watchpoint = cortex_m_remove_watchpoint,\n\t.profiling = cortex_m_profiling,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/image.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2009 by Franck Hereson                                  *\n *   franck.hereson@secad.fr                                               *\n *                                                                         *\n *   Copyright (C) 2018 by Advantest                                       *\n *   florian.meister@advantest.com                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"image.h\"\n#include \"target.h\"\n#include <helper/log.h>\n\n/* convert ELF header field to host endianness */\n#define field16(elf, field) \\\n\t((elf->endianness == ELFDATA2LSB) ? \\\n\tle_to_h_u16((uint8_t *)&field) : be_to_h_u16((uint8_t *)&field))\n\n#define field32(elf, field) \\\n\t((elf->endianness == ELFDATA2LSB) ? \\\n\tle_to_h_u32((uint8_t *)&field) : be_to_h_u32((uint8_t *)&field))\n\n#define field64(elf, field) \\\n\t((elf->endianness == ELFDATA2LSB) ? \\\n\tle_to_h_u64((uint8_t *)&field) : be_to_h_u64((uint8_t *)&field))\n\nstatic int autodetect_image_type(struct image *image, const char *url)\n{\n\tint retval;\n\tstruct fileio *fileio;\n\tsize_t read_bytes;\n\tuint8_t buffer[9];\n\n\t/* read the first 9 bytes of image */\n\tretval = fileio_open(&fileio, url, FILEIO_READ, FILEIO_BINARY);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = fileio_read(fileio, 9, buffer, &read_bytes);\n\n\tif (retval == ERROR_OK) {\n\t\tif (read_bytes != 9)\n\t\t\tretval = ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\tfileio_close(fileio);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* check header against known signatures */\n\tif (strncmp((char *)buffer, ELFMAG, SELFMAG) == 0) {\n\t\tLOG_DEBUG(\"ELF image detected.\");\n\t\timage->type = IMAGE_ELF;\n\t} else if ((buffer[0] == ':')\t/* record start byte */\n\t\t&& (isxdigit(buffer[1]))\n\t\t&& (isxdigit(buffer[2]))\n\t\t&& (isxdigit(buffer[3]))\n\t\t&& (isxdigit(buffer[4]))\n\t\t&& (isxdigit(buffer[5]))\n\t\t&& (isxdigit(buffer[6]))\n\t\t&& (buffer[7] == '0')\t/* record type : 00 -> 05 */\n\t\t&& (buffer[8] >= '0') && (buffer[8] < '6')) {\n\t\tLOG_DEBUG(\"IHEX image detected.\");\n\t\timage->type = IMAGE_IHEX;\n\t} else if ((buffer[0] == 'S')\t/* record start byte */\n\t\t&& (isxdigit(buffer[1]))\n\t\t&& (isxdigit(buffer[2]))\n\t\t&& (isxdigit(buffer[3]))\n\t\t&& (buffer[1] >= '0') && (buffer[1] < '9')) {\n\t\tLOG_DEBUG(\"S19 image detected.\");\n\t\timage->type = IMAGE_SRECORD;\n\t} else\n\t\timage->type = IMAGE_BINARY;\n\n\treturn ERROR_OK;\n}\n\nstatic int identify_image_type(struct image *image, const char *type_string, const char *url)\n{\n\tif (type_string) {\n\t\tif (!strcmp(type_string, \"bin\"))\n\t\t\timage->type = IMAGE_BINARY;\n\t\telse if (!strcmp(type_string, \"ihex\"))\n\t\t\timage->type = IMAGE_IHEX;\n\t\telse if (!strcmp(type_string, \"elf\"))\n\t\t\timage->type = IMAGE_ELF;\n\t\telse if (!strcmp(type_string, \"mem\"))\n\t\t\timage->type = IMAGE_MEMORY;\n\t\telse if (!strcmp(type_string, \"s19\"))\n\t\t\timage->type = IMAGE_SRECORD;\n\t\telse if (!strcmp(type_string, \"build\"))\n\t\t\timage->type = IMAGE_BUILDER;\n\t\telse\n\t\t\treturn ERROR_IMAGE_TYPE_UNKNOWN;\n\t} else\n\t\treturn autodetect_image_type(image, url);\n\n\treturn ERROR_OK;\n}\n\nstatic int image_ihex_buffer_complete_inner(struct image *image,\n\tchar *lpsz_line,\n\tstruct imagesection *section)\n{\n\tstruct image_ihex *ihex = image->type_private;\n\tstruct fileio *fileio = ihex->fileio;\n\tuint32_t full_address;\n\tuint32_t cooked_bytes;\n\tbool end_rec = false;\n\n\t/* we can't determine the number of sections that we'll have to create ahead of time,\n\t * so we locally hold them until parsing is finished */\n\n\tsize_t filesize;\n\tint retval;\n\tretval = fileio_size(fileio, &filesize);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tihex->buffer = malloc(filesize >> 1);\n\tcooked_bytes = 0x0;\n\timage->num_sections = 0;\n\n\twhile (!fileio_feof(fileio)) {\n\t\tfull_address = 0x0;\n\t\tsection[image->num_sections].private = &ihex->buffer[cooked_bytes];\n\t\tsection[image->num_sections].base_address = 0x0;\n\t\tsection[image->num_sections].size = 0x0;\n\t\tsection[image->num_sections].flags = 0;\n\n\t\twhile (fileio_fgets(fileio, 1023, lpsz_line) == ERROR_OK) {\n\t\t\tuint32_t count;\n\t\t\tuint32_t address;\n\t\t\tuint32_t record_type;\n\t\t\tuint32_t checksum;\n\t\t\tuint8_t cal_checksum = 0;\n\t\t\tsize_t bytes_read = 0;\n\n\t\t\t/* skip comments and blank lines */\n\t\t\tif ((lpsz_line[0] == '#') || (strlen(lpsz_line + strspn(lpsz_line, \"\\n\\t\\r \")) == 0))\n\t\t\t\tcontinue;\n\n\t\t\tif (sscanf(&lpsz_line[bytes_read], \":%2\" SCNx32 \"%4\" SCNx32 \"%2\" SCNx32, &count,\n\t\t\t\t&address, &record_type) != 3)\n\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\tbytes_read += 9;\n\n\t\t\tcal_checksum += (uint8_t)count;\n\t\t\tcal_checksum += (uint8_t)(address >> 8);\n\t\t\tcal_checksum += (uint8_t)address;\n\t\t\tcal_checksum += (uint8_t)record_type;\n\n\t\t\tif (record_type == 0) {\t/* Data Record */\n\t\t\t\tif ((full_address & 0xffff) != address) {\n\t\t\t\t\t/* we encountered a nonconsecutive location, create a new section,\n\t\t\t\t\t * unless the current section has zero size, in which case this specifies\n\t\t\t\t\t * the current section's base address\n\t\t\t\t\t */\n\t\t\t\t\tif (section[image->num_sections].size != 0) {\n\t\t\t\t\t\timage->num_sections++;\n\t\t\t\t\t\tif (image->num_sections >= IMAGE_MAX_SECTIONS) {\n\t\t\t\t\t\t\t/* too many sections */\n\t\t\t\t\t\t\tLOG_ERROR(\"Too many sections found in IHEX file\");\n\t\t\t\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsection[image->num_sections].size = 0x0;\n\t\t\t\t\t\tsection[image->num_sections].flags = 0;\n\t\t\t\t\t\tsection[image->num_sections].private =\n\t\t\t\t\t\t\t&ihex->buffer[cooked_bytes];\n\t\t\t\t\t}\n\t\t\t\t\tsection[image->num_sections].base_address =\n\t\t\t\t\t\t(full_address & 0xffff0000) | address;\n\t\t\t\t\tfull_address = (full_address & 0xffff0000) | address;\n\t\t\t\t}\n\n\t\t\t\twhile (count-- > 0) {\n\t\t\t\t\tunsigned value;\n\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%2x\", &value);\n\t\t\t\t\tihex->buffer[cooked_bytes] = (uint8_t)value;\n\t\t\t\t\tcal_checksum += (uint8_t)ihex->buffer[cooked_bytes];\n\t\t\t\t\tbytes_read += 2;\n\t\t\t\t\tcooked_bytes += 1;\n\t\t\t\t\tsection[image->num_sections].size += 1;\n\t\t\t\t\tfull_address++;\n\t\t\t\t}\n\t\t\t} else if (record_type == 1) {\t/* End of File Record */\n\t\t\t\t/* finish the current section */\n\t\t\t\timage->num_sections++;\n\n\t\t\t\t/* copy section information */\n\t\t\t\timage->sections = malloc(sizeof(struct imagesection) * image->num_sections);\n\t\t\t\tfor (unsigned int i = 0; i < image->num_sections; i++) {\n\t\t\t\t\timage->sections[i].private = section[i].private;\n\t\t\t\t\timage->sections[i].base_address = section[i].base_address;\n\t\t\t\t\timage->sections[i].size = section[i].size;\n\t\t\t\t\timage->sections[i].flags = section[i].flags;\n\t\t\t\t}\n\n\t\t\t\tend_rec = true;\n\t\t\t\tbreak;\n\t\t\t} else if (record_type == 2) {\t/* Linear Address Record */\n\t\t\t\tuint16_t upper_address;\n\n\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%4hx\", &upper_address);\n\t\t\t\tcal_checksum += (uint8_t)(upper_address >> 8);\n\t\t\t\tcal_checksum += (uint8_t)upper_address;\n\t\t\t\tbytes_read += 4;\n\n\t\t\t\tif ((full_address >> 4) != upper_address) {\n\t\t\t\t\t/* we encountered a nonconsecutive location, create a new section,\n\t\t\t\t\t * unless the current section has zero size, in which case this specifies\n\t\t\t\t\t * the current section's base address\n\t\t\t\t\t */\n\t\t\t\t\tif (section[image->num_sections].size != 0) {\n\t\t\t\t\t\timage->num_sections++;\n\t\t\t\t\t\tif (image->num_sections >= IMAGE_MAX_SECTIONS) {\n\t\t\t\t\t\t\t/* too many sections */\n\t\t\t\t\t\t\tLOG_ERROR(\"Too many sections found in IHEX file\");\n\t\t\t\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsection[image->num_sections].size = 0x0;\n\t\t\t\t\t\tsection[image->num_sections].flags = 0;\n\t\t\t\t\t\tsection[image->num_sections].private =\n\t\t\t\t\t\t\t&ihex->buffer[cooked_bytes];\n\t\t\t\t\t}\n\t\t\t\t\tsection[image->num_sections].base_address =\n\t\t\t\t\t\t(full_address & 0xffff) | (upper_address << 4);\n\t\t\t\t\tfull_address = (full_address & 0xffff) | (upper_address << 4);\n\t\t\t\t}\n\t\t\t} else if (record_type == 3) {\t/* Start Segment Address Record */\n\t\t\t\tuint32_t dummy;\n\n\t\t\t\t/* \"Start Segment Address Record\" will not be supported\n\t\t\t\t * but we must consume it, and do not create an error.  */\n\t\t\t\twhile (count-- > 0) {\n\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%2\" SCNx32, &dummy);\n\t\t\t\t\tcal_checksum += (uint8_t)dummy;\n\t\t\t\t\tbytes_read += 2;\n\t\t\t\t}\n\t\t\t} else if (record_type == 4) {\t/* Extended Linear Address Record */\n\t\t\t\tuint16_t upper_address;\n\n\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%4hx\", &upper_address);\n\t\t\t\tcal_checksum += (uint8_t)(upper_address >> 8);\n\t\t\t\tcal_checksum += (uint8_t)upper_address;\n\t\t\t\tbytes_read += 4;\n\n\t\t\t\tif ((full_address >> 16) != upper_address) {\n\t\t\t\t\t/* we encountered a nonconsecutive location, create a new section,\n\t\t\t\t\t * unless the current section has zero size, in which case this specifies\n\t\t\t\t\t * the current section's base address\n\t\t\t\t\t */\n\t\t\t\t\tif (section[image->num_sections].size != 0) {\n\t\t\t\t\t\timage->num_sections++;\n\t\t\t\t\t\tif (image->num_sections >= IMAGE_MAX_SECTIONS) {\n\t\t\t\t\t\t\t/* too many sections */\n\t\t\t\t\t\t\tLOG_ERROR(\"Too many sections found in IHEX file\");\n\t\t\t\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsection[image->num_sections].size = 0x0;\n\t\t\t\t\t\tsection[image->num_sections].flags = 0;\n\t\t\t\t\t\tsection[image->num_sections].private =\n\t\t\t\t\t\t\t&ihex->buffer[cooked_bytes];\n\t\t\t\t\t}\n\t\t\t\t\tsection[image->num_sections].base_address =\n\t\t\t\t\t\t(full_address & 0xffff) | (upper_address << 16);\n\t\t\t\t\tfull_address = (full_address & 0xffff) | (upper_address << 16);\n\t\t\t\t}\n\t\t\t} else if (record_type == 5) {\t/* Start Linear Address Record */\n\t\t\t\tuint32_t start_address;\n\n\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%8\" SCNx32, &start_address);\n\t\t\t\tcal_checksum += (uint8_t)(start_address >> 24);\n\t\t\t\tcal_checksum += (uint8_t)(start_address >> 16);\n\t\t\t\tcal_checksum += (uint8_t)(start_address >> 8);\n\t\t\t\tcal_checksum += (uint8_t)start_address;\n\t\t\t\tbytes_read += 8;\n\n\t\t\t\timage->start_address_set = true;\n\t\t\t\timage->start_address = be_to_h_u32((uint8_t *)&start_address);\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"unhandled IHEX record type: %i\", (int)record_type);\n\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\t}\n\n\t\t\tsscanf(&lpsz_line[bytes_read], \"%2\" SCNx32, &checksum);\n\n\t\t\tif ((uint8_t)checksum != (uint8_t)(~cal_checksum + 1)) {\n\t\t\t\t/* checksum failed */\n\t\t\t\tLOG_ERROR(\"incorrect record checksum found in IHEX file\");\n\t\t\t\treturn ERROR_IMAGE_CHECKSUM;\n\t\t\t}\n\n\t\t\tif (end_rec) {\n\t\t\t\tend_rec = false;\n\t\t\t\tLOG_WARNING(\"continuing after end-of-file record: %.40s\", lpsz_line);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (end_rec)\n\t\treturn ERROR_OK;\n\telse {\n\t\tLOG_ERROR(\"premature end of IHEX file, no matching end-of-file record found\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n}\n\n/**\n * Allocate memory dynamically instead of on the stack. This\n * is important w/embedded hosts.\n */\nstatic int image_ihex_buffer_complete(struct image *image)\n{\n\tchar *lpsz_line = malloc(1023);\n\tif (!lpsz_line) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tstruct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);\n\tif (!section) {\n\t\tfree(lpsz_line);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint retval;\n\n\tretval = image_ihex_buffer_complete_inner(image, lpsz_line, section);\n\n\tfree(section);\n\tfree(lpsz_line);\n\n\treturn retval;\n}\n\nstatic int image_elf32_read_headers(struct image *image)\n{\n\tstruct image_elf *elf = image->type_private;\n\tsize_t read_bytes;\n\tuint32_t i, j;\n\tint retval;\n\tuint32_t nload;\n\tbool load_to_vaddr = false;\n\n\tretval = fileio_seek(elf->fileio, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot seek to ELF file header, read failed\");\n\t\treturn retval;\n\t}\n\n\telf->header32 = malloc(sizeof(Elf32_Ehdr));\n\n\tif (!elf->header32) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tretval = fileio_read(elf->fileio, sizeof(Elf32_Ehdr), (uint8_t *)elf->header32, &read_bytes);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot read ELF file header, read failed\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\tif (read_bytes != sizeof(Elf32_Ehdr)) {\n\t\tLOG_ERROR(\"cannot read ELF file header, only partially read\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\telf->segment_count = field16(elf, elf->header32->e_phnum);\n\tif (elf->segment_count == 0) {\n\t\tLOG_ERROR(\"invalid ELF file, no program headers\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\tretval = fileio_seek(elf->fileio, field32(elf, elf->header32->e_phoff));\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot seek to ELF program header table, read failed\");\n\t\treturn retval;\n\t}\n\n\telf->segments32 = malloc(elf->segment_count*sizeof(Elf32_Phdr));\n\tif (!elf->segments32) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tretval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf32_Phdr),\n\t\t\t(uint8_t *)elf->segments32, &read_bytes);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot read ELF segment headers, read failed\");\n\t\treturn retval;\n\t}\n\tif (read_bytes != elf->segment_count*sizeof(Elf32_Phdr)) {\n\t\tLOG_ERROR(\"cannot read ELF segment headers, only partially read\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\t/* count useful segments (loadable), ignore BSS section */\n\timage->num_sections = 0;\n\tfor (i = 0; i < elf->segment_count; i++)\n\t\tif ((field32(elf,\n\t\t\telf->segments32[i].p_type) == PT_LOAD) &&\n\t\t\t(field32(elf, elf->segments32[i].p_filesz) != 0))\n\t\t\timage->num_sections++;\n\n\tif (image->num_sections == 0) {\n\t\tLOG_ERROR(\"invalid ELF file, no loadable segments\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\t/**\n\t * some ELF linkers produce binaries with *all* the program header\n\t * p_paddr fields zero (there can be however one loadable segment\n\t * that has valid physical address 0x0).\n\t * If we have such a binary with more than\n\t * one PT_LOAD header, then use p_vaddr instead of p_paddr\n\t * (ARM ELF standard demands p_paddr = 0 anyway, and BFD\n\t * library uses this approach to workaround zero-initialized p_paddrs\n\t * when obtaining lma - look at elf.c of BDF)\n\t */\n\tfor (nload = 0, i = 0; i < elf->segment_count; i++)\n\t\tif (elf->segments32[i].p_paddr != 0)\n\t\t\tbreak;\n\t\telse if ((field32(elf,\n\t\t\telf->segments32[i].p_type) == PT_LOAD) &&\n\t\t\t(field32(elf, elf->segments32[i].p_memsz) != 0))\n\t\t\t++nload;\n\n\tif (i >= elf->segment_count && nload > 1)\n\t\tload_to_vaddr = true;\n\n\t/* alloc and fill sections array with loadable segments */\n\timage->sections = malloc(image->num_sections * sizeof(struct imagesection));\n\tif (!image->sections) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tfor (i = 0, j = 0; i < elf->segment_count; i++) {\n\t\tif ((field32(elf,\n\t\t\telf->segments32[i].p_type) == PT_LOAD) &&\n\t\t\t(field32(elf, elf->segments32[i].p_filesz) != 0)) {\n\t\t\timage->sections[j].size = field32(elf, elf->segments32[i].p_filesz);\n\t\t\tif (load_to_vaddr)\n\t\t\t\timage->sections[j].base_address = field32(elf,\n\t\t\t\t\t\telf->segments32[i].p_vaddr);\n\t\t\telse\n\t\t\t\timage->sections[j].base_address = field32(elf,\n\t\t\t\t\t\telf->segments32[i].p_paddr);\n\t\t\timage->sections[j].private = &elf->segments32[i];\n\t\t\timage->sections[j].flags = field32(elf, elf->segments32[i].p_flags);\n\t\t\tj++;\n\t\t}\n\t}\n\n\timage->start_address_set = true;\n\timage->start_address = field32(elf, elf->header32->e_entry);\n\n\treturn ERROR_OK;\n}\n\nstatic int image_elf64_read_headers(struct image *image)\n{\n\tstruct image_elf *elf = image->type_private;\n\tsize_t read_bytes;\n\tuint32_t i, j;\n\tint retval;\n\tuint32_t nload;\n\tbool load_to_vaddr = false;\n\n\tretval = fileio_seek(elf->fileio, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot seek to ELF file header, read failed\");\n\t\treturn retval;\n\t}\n\n\telf->header64 = malloc(sizeof(Elf64_Ehdr));\n\n\tif (!elf->header64) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tretval = fileio_read(elf->fileio, sizeof(Elf64_Ehdr), (uint8_t *)elf->header64, &read_bytes);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot read ELF file header, read failed\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\tif (read_bytes != sizeof(Elf64_Ehdr)) {\n\t\tLOG_ERROR(\"cannot read ELF file header, only partially read\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\telf->segment_count = field16(elf, elf->header64->e_phnum);\n\tif (elf->segment_count == 0) {\n\t\tLOG_ERROR(\"invalid ELF file, no program headers\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\tretval = fileio_seek(elf->fileio, field64(elf, elf->header64->e_phoff));\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot seek to ELF program header table, read failed\");\n\t\treturn retval;\n\t}\n\n\telf->segments64 = malloc(elf->segment_count*sizeof(Elf64_Phdr));\n\tif (!elf->segments64) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tretval = fileio_read(elf->fileio, elf->segment_count*sizeof(Elf64_Phdr),\n\t\t\t(uint8_t *)elf->segments64, &read_bytes);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot read ELF segment headers, read failed\");\n\t\treturn retval;\n\t}\n\tif (read_bytes != elf->segment_count*sizeof(Elf64_Phdr)) {\n\t\tLOG_ERROR(\"cannot read ELF segment headers, only partially read\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\t/* count useful segments (loadable), ignore BSS section */\n\timage->num_sections = 0;\n\tfor (i = 0; i < elf->segment_count; i++)\n\t\tif ((field32(elf,\n\t\t\telf->segments64[i].p_type) == PT_LOAD) &&\n\t\t\t(field64(elf, elf->segments64[i].p_filesz) != 0))\n\t\t\timage->num_sections++;\n\n\tif (image->num_sections == 0) {\n\t\tLOG_ERROR(\"invalid ELF file, no loadable segments\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\t/**\n\t * some ELF linkers produce binaries with *all* the program header\n\t * p_paddr fields zero (there can be however one loadable segment\n\t * that has valid physical address 0x0).\n\t * If we have such a binary with more than\n\t * one PT_LOAD header, then use p_vaddr instead of p_paddr\n\t * (ARM ELF standard demands p_paddr = 0 anyway, and BFD\n\t * library uses this approach to workaround zero-initialized p_paddrs\n\t * when obtaining lma - look at elf.c of BDF)\n\t */\n\tfor (nload = 0, i = 0; i < elf->segment_count; i++)\n\t\tif (elf->segments64[i].p_paddr != 0)\n\t\t\tbreak;\n\t\telse if ((field32(elf,\n\t\t\telf->segments64[i].p_type) == PT_LOAD) &&\n\t\t\t(field64(elf, elf->segments64[i].p_memsz) != 0))\n\t\t\t++nload;\n\n\tif (i >= elf->segment_count && nload > 1)\n\t\tload_to_vaddr = true;\n\n\t/* alloc and fill sections array with loadable segments */\n\timage->sections = malloc(image->num_sections * sizeof(struct imagesection));\n\tif (!image->sections) {\n\t\tLOG_ERROR(\"insufficient memory to perform operation\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tfor (i = 0, j = 0; i < elf->segment_count; i++) {\n\t\tif ((field32(elf,\n\t\t\telf->segments64[i].p_type) == PT_LOAD) &&\n\t\t\t(field64(elf, elf->segments64[i].p_filesz) != 0)) {\n\t\t\timage->sections[j].size = field64(elf, elf->segments64[i].p_filesz);\n\t\t\tif (load_to_vaddr)\n\t\t\t\timage->sections[j].base_address = field64(elf,\n\t\t\t\t\t\telf->segments64[i].p_vaddr);\n\t\t\telse\n\t\t\t\timage->sections[j].base_address = field64(elf,\n\t\t\t\t\t\telf->segments64[i].p_paddr);\n\t\t\timage->sections[j].private = &elf->segments64[i];\n\t\t\timage->sections[j].flags = field64(elf, elf->segments64[i].p_flags);\n\t\t\tj++;\n\t\t}\n\t}\n\n\timage->start_address_set = true;\n\timage->start_address = field64(elf, elf->header64->e_entry);\n\n\treturn ERROR_OK;\n}\n\nstatic int image_elf_read_headers(struct image *image)\n{\n\tstruct image_elf *elf = image->type_private;\n\tsize_t read_bytes;\n\tunsigned char e_ident[EI_NIDENT];\n\tint retval;\n\n\tretval = fileio_read(elf->fileio, EI_NIDENT, e_ident, &read_bytes);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"cannot read ELF file header, read failed\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\tif (read_bytes != EI_NIDENT) {\n\t\tLOG_ERROR(\"cannot read ELF file header, only partially read\");\n\t\treturn ERROR_FILEIO_OPERATION_FAILED;\n\t}\n\n\tif (strncmp((char *)e_ident, ELFMAG, SELFMAG) != 0) {\n\t\tLOG_ERROR(\"invalid ELF file, bad magic number\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\telf->endianness = e_ident[EI_DATA];\n\tif ((elf->endianness != ELFDATA2LSB)\n\t\t&& (elf->endianness != ELFDATA2MSB)) {\n\t\tLOG_ERROR(\"invalid ELF file, unknown endianness setting\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n\n\tswitch (e_ident[EI_CLASS]) {\n\tcase ELFCLASS32:\n\t\tLOG_DEBUG(\"ELF32 image detected.\");\n\t\telf->is_64_bit = false;\n\t\treturn image_elf32_read_headers(image);\n\n\tcase ELFCLASS64:\n\t\tLOG_DEBUG(\"ELF64 image detected.\");\n\t\telf->is_64_bit = true;\n\t\treturn image_elf64_read_headers(image);\n\n\tdefault:\n\t\tLOG_ERROR(\"invalid ELF file, only 32/64 bit ELF files are supported\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n}\n\nstatic int image_elf32_read_section(struct image *image,\n\tint section,\n\ttarget_addr_t offset,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tsize_t *size_read)\n{\n\tstruct image_elf *elf = image->type_private;\n\tElf32_Phdr *segment = (Elf32_Phdr *)image->sections[section].private;\n\tsize_t read_size, really_read;\n\tint retval;\n\n\t*size_read = 0;\n\n\tLOG_DEBUG(\"load segment %d at 0x%\" TARGET_PRIxADDR \" (sz = 0x%\" PRIx32 \")\", section, offset, size);\n\n\t/* read initialized data in current segment if any */\n\tif (offset < field32(elf, segment->p_filesz)) {\n\t\t/* maximal size present in file for the current segment */\n\t\tread_size = MIN(size, field32(elf, segment->p_filesz) - offset);\n\t\tLOG_DEBUG(\"read elf: size = 0x%zx at 0x%\" TARGET_PRIxADDR \"\", read_size,\n\t\t\tfield32(elf, segment->p_offset) + offset);\n\t\t/* read initialized area of the segment */\n\t\tretval = fileio_seek(elf->fileio, field32(elf, segment->p_offset) + offset);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"cannot find ELF segment content, seek failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tretval = fileio_read(elf->fileio, read_size, buffer, &really_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"cannot read ELF segment content, read failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tsize -= read_size;\n\t\t*size_read += read_size;\n\t\t/* need more data ? */\n\t\tif (!size)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int image_elf64_read_section(struct image *image,\n\tint section,\n\ttarget_addr_t offset,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tsize_t *size_read)\n{\n\tstruct image_elf *elf = image->type_private;\n\tElf64_Phdr *segment = (Elf64_Phdr *)image->sections[section].private;\n\tsize_t read_size, really_read;\n\tint retval;\n\n\t*size_read = 0;\n\n\tLOG_DEBUG(\"load segment %d at 0x%\" TARGET_PRIxADDR \" (sz = 0x%\" PRIx32 \")\", section, offset, size);\n\n\t/* read initialized data in current segment if any */\n\tif (offset < field64(elf, segment->p_filesz)) {\n\t\t/* maximal size present in file for the current segment */\n\t\tread_size = MIN(size, field64(elf, segment->p_filesz) - offset);\n\t\tLOG_DEBUG(\"read elf: size = 0x%zx at 0x%\" TARGET_PRIxADDR \"\", read_size,\n\t\t\tfield64(elf, segment->p_offset) + offset);\n\t\t/* read initialized area of the segment */\n\t\tretval = fileio_seek(elf->fileio, field64(elf, segment->p_offset) + offset);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"cannot find ELF segment content, seek failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tretval = fileio_read(elf->fileio, read_size, buffer, &really_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"cannot read ELF segment content, read failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tsize -= read_size;\n\t\t*size_read += read_size;\n\t\t/* need more data ? */\n\t\tif (!size)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int image_elf_read_section(struct image *image,\n\tint section,\n\ttarget_addr_t offset,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tsize_t *size_read)\n{\n\tstruct image_elf *elf = image->type_private;\n\n\tif (elf->is_64_bit)\n\t\treturn image_elf64_read_section(image, section, offset, size, buffer, size_read);\n\telse\n\t\treturn image_elf32_read_section(image, section, offset, size, buffer, size_read);\n}\n\nstatic int image_mot_buffer_complete_inner(struct image *image,\n\tchar *lpsz_line,\n\tstruct imagesection *section)\n{\n\tstruct image_mot *mot = image->type_private;\n\tstruct fileio *fileio = mot->fileio;\n\tuint32_t full_address;\n\tuint32_t cooked_bytes;\n\tbool end_rec = false;\n\n\t/* we can't determine the number of sections that we'll have to create ahead of time,\n\t * so we locally hold them until parsing is finished */\n\n\tint retval;\n\tsize_t filesize;\n\tretval = fileio_size(fileio, &filesize);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmot->buffer = malloc(filesize >> 1);\n\tcooked_bytes = 0x0;\n\timage->num_sections = 0;\n\n\twhile (!fileio_feof(fileio)) {\n\t\tfull_address = 0x0;\n\t\tsection[image->num_sections].private = &mot->buffer[cooked_bytes];\n\t\tsection[image->num_sections].base_address = 0x0;\n\t\tsection[image->num_sections].size = 0x0;\n\t\tsection[image->num_sections].flags = 0;\n\n\t\twhile (fileio_fgets(fileio, 1023, lpsz_line) == ERROR_OK) {\n\t\t\tuint32_t count;\n\t\t\tuint32_t address;\n\t\t\tuint32_t record_type;\n\t\t\tuint32_t checksum;\n\t\t\tuint8_t cal_checksum = 0;\n\t\t\tuint32_t bytes_read = 0;\n\n\t\t\t/* skip comments and blank lines */\n\t\t\tif ((lpsz_line[0] == '#') || (strlen(lpsz_line + strspn(lpsz_line, \"\\n\\t\\r \")) == 0))\n\t\t\t\tcontinue;\n\n\t\t\t/* get record type and record length */\n\t\t\tif (sscanf(&lpsz_line[bytes_read], \"S%1\" SCNx32 \"%2\" SCNx32, &record_type,\n\t\t\t\t&count) != 2)\n\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\n\t\t\tbytes_read += 4;\n\t\t\tcal_checksum += (uint8_t)count;\n\n\t\t\t/* skip checksum byte */\n\t\t\tcount -= 1;\n\n\t\t\tif (record_type == 0) {\n\t\t\t\t/* S0 - starting record (optional) */\n\t\t\t\tint value;\n\n\t\t\t\twhile (count-- > 0) {\n\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%2x\", &value);\n\t\t\t\t\tcal_checksum += (uint8_t)value;\n\t\t\t\t\tbytes_read += 2;\n\t\t\t\t}\n\t\t\t} else if (record_type >= 1 && record_type <= 3) {\n\t\t\t\tswitch (record_type) {\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t/* S1 - 16 bit address data record */\n\t\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%4\" SCNx32, &address);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 8);\n\t\t\t\t\t\tcal_checksum += (uint8_t)address;\n\t\t\t\t\t\tbytes_read += 4;\n\t\t\t\t\t\tcount -= 2;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\t/* S2 - 24 bit address data record */\n\t\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%6\" SCNx32, &address);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 16);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 8);\n\t\t\t\t\t\tcal_checksum += (uint8_t)address;\n\t\t\t\t\t\tbytes_read += 6;\n\t\t\t\t\t\tcount -= 3;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t/* S3 - 32 bit address data record */\n\t\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%8\" SCNx32, &address);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 24);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 16);\n\t\t\t\t\t\tcal_checksum += (uint8_t)(address >> 8);\n\t\t\t\t\t\tcal_checksum += (uint8_t)address;\n\t\t\t\t\t\tbytes_read += 8;\n\t\t\t\t\t\tcount -= 4;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\n\t\t\t\tif (full_address != address) {\n\t\t\t\t\t/* we encountered a nonconsecutive location, create a new section,\n\t\t\t\t\t * unless the current section has zero size, in which case this specifies\n\t\t\t\t\t * the current section's base address\n\t\t\t\t\t */\n\t\t\t\t\tif (section[image->num_sections].size != 0) {\n\t\t\t\t\t\timage->num_sections++;\n\t\t\t\t\t\tsection[image->num_sections].size = 0x0;\n\t\t\t\t\t\tsection[image->num_sections].flags = 0;\n\t\t\t\t\t\tsection[image->num_sections].private =\n\t\t\t\t\t\t\t&mot->buffer[cooked_bytes];\n\t\t\t\t\t}\n\t\t\t\t\tsection[image->num_sections].base_address = address;\n\t\t\t\t\tfull_address = address;\n\t\t\t\t}\n\n\t\t\t\twhile (count-- > 0) {\n\t\t\t\t\tunsigned value;\n\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%2x\", &value);\n\t\t\t\t\tmot->buffer[cooked_bytes] = (uint8_t)value;\n\t\t\t\t\tcal_checksum += (uint8_t)mot->buffer[cooked_bytes];\n\t\t\t\t\tbytes_read += 2;\n\t\t\t\t\tcooked_bytes += 1;\n\t\t\t\t\tsection[image->num_sections].size += 1;\n\t\t\t\t\tfull_address++;\n\t\t\t\t}\n\t\t\t} else if (record_type == 5 || record_type == 6) {\n\t\t\t\t/* S5 and S6 are the data count records, we ignore them */\n\t\t\t\tuint32_t dummy;\n\n\t\t\t\twhile (count-- > 0) {\n\t\t\t\t\tsscanf(&lpsz_line[bytes_read], \"%2\" SCNx32, &dummy);\n\t\t\t\t\tcal_checksum += (uint8_t)dummy;\n\t\t\t\t\tbytes_read += 2;\n\t\t\t\t}\n\t\t\t} else if (record_type >= 7 && record_type <= 9) {\n\t\t\t\t/* S7, S8, S9 - ending records for 32, 24 and 16bit */\n\t\t\t\timage->num_sections++;\n\n\t\t\t\t/* copy section information */\n\t\t\t\timage->sections = malloc(sizeof(struct imagesection) * image->num_sections);\n\t\t\t\tfor (unsigned int i = 0; i < image->num_sections; i++) {\n\t\t\t\t\timage->sections[i].private = section[i].private;\n\t\t\t\t\timage->sections[i].base_address = section[i].base_address;\n\t\t\t\t\timage->sections[i].size = section[i].size;\n\t\t\t\t\timage->sections[i].flags = section[i].flags;\n\t\t\t\t}\n\n\t\t\t\tend_rec = true;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"unhandled S19 record type: %i\", (int)(record_type));\n\t\t\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t\t\t}\n\n\t\t\t/* account for checksum, will always be 0xFF */\n\t\t\tsscanf(&lpsz_line[bytes_read], \"%2\" SCNx32, &checksum);\n\t\t\tcal_checksum += (uint8_t)checksum;\n\n\t\t\tif (cal_checksum != 0xFF) {\n\t\t\t\t/* checksum failed */\n\t\t\t\tLOG_ERROR(\"incorrect record checksum found in S19 file\");\n\t\t\t\treturn ERROR_IMAGE_CHECKSUM;\n\t\t\t}\n\n\t\t\tif (end_rec) {\n\t\t\t\tend_rec = false;\n\t\t\t\tLOG_WARNING(\"continuing after end-of-file record: %.40s\", lpsz_line);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (end_rec)\n\t\treturn ERROR_OK;\n\telse {\n\t\tLOG_ERROR(\"premature end of S19 file, no matching end-of-file record found\");\n\t\treturn ERROR_IMAGE_FORMAT_ERROR;\n\t}\n}\n\n/**\n * Allocate memory dynamically instead of on the stack. This\n * is important w/embedded hosts.\n */\nstatic int image_mot_buffer_complete(struct image *image)\n{\n\tchar *lpsz_line = malloc(1023);\n\tif (!lpsz_line) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tstruct imagesection *section = malloc(sizeof(struct imagesection) * IMAGE_MAX_SECTIONS);\n\tif (!section) {\n\t\tfree(lpsz_line);\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint retval;\n\n\tretval = image_mot_buffer_complete_inner(image, lpsz_line, section);\n\n\tfree(section);\n\tfree(lpsz_line);\n\n\treturn retval;\n}\n\nint image_open(struct image *image, const char *url, const char *type_string)\n{\n\tint retval = ERROR_OK;\n\n\tretval = identify_image_type(image, type_string, url);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (image->type == IMAGE_BINARY) {\n\t\tstruct image_binary *image_binary;\n\n\t\timage_binary = image->type_private = malloc(sizeof(struct image_binary));\n\n\t\tretval = fileio_open(&image_binary->fileio, url, FILEIO_READ, FILEIO_BINARY);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tsize_t filesize;\n\t\tretval = fileio_size(image_binary->fileio, &filesize);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfileio_close(image_binary->fileio);\n\t\t\treturn retval;\n\t\t}\n\n\t\timage->num_sections = 1;\n\t\timage->sections = malloc(sizeof(struct imagesection));\n\t\timage->sections[0].base_address = 0x0;\n\t\timage->sections[0].size = filesize;\n\t\timage->sections[0].flags = 0;\n\t} else if (image->type == IMAGE_IHEX) {\n\t\tstruct image_ihex *image_ihex;\n\n\t\timage_ihex = image->type_private = malloc(sizeof(struct image_ihex));\n\n\t\tretval = fileio_open(&image_ihex->fileio, url, FILEIO_READ, FILEIO_TEXT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = image_ihex_buffer_complete(image);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\n\t\t\t\t\"failed buffering IHEX image, check server output for additional information\");\n\t\t\tfileio_close(image_ihex->fileio);\n\t\t\treturn retval;\n\t\t}\n\t} else if (image->type == IMAGE_ELF) {\n\t\tstruct image_elf *image_elf;\n\n\t\timage_elf = image->type_private = malloc(sizeof(struct image_elf));\n\n\t\tretval = fileio_open(&image_elf->fileio, url, FILEIO_READ, FILEIO_BINARY);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = image_elf_read_headers(image);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfileio_close(image_elf->fileio);\n\t\t\treturn retval;\n\t\t}\n\t} else if (image->type == IMAGE_MEMORY) {\n\t\tstruct target *target = get_target(url);\n\n\t\tif (!target) {\n\t\t\tLOG_ERROR(\"target '%s' not defined\", url);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tstruct image_memory *image_memory;\n\n\t\timage->num_sections = 1;\n\t\timage->sections = malloc(sizeof(struct imagesection));\n\t\timage->sections[0].base_address = 0x0;\n\t\timage->sections[0].size = 0xffffffff;\n\t\timage->sections[0].flags = 0;\n\n\t\timage_memory = image->type_private = malloc(sizeof(struct image_memory));\n\n\t\timage_memory->target = target;\n\t\timage_memory->cache = NULL;\n\t\timage_memory->cache_address = 0x0;\n\t} else if (image->type == IMAGE_SRECORD) {\n\t\tstruct image_mot *image_mot;\n\n\t\timage_mot = image->type_private = malloc(sizeof(struct image_mot));\n\n\t\tretval = fileio_open(&image_mot->fileio, url, FILEIO_READ, FILEIO_TEXT);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = image_mot_buffer_complete(image);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\n\t\t\t\t\"failed buffering S19 image, check server output for additional information\");\n\t\t\tfileio_close(image_mot->fileio);\n\t\t\treturn retval;\n\t\t}\n\t} else if (image->type == IMAGE_BUILDER) {\n\t\timage->num_sections = 0;\n\t\timage->base_address_set = false;\n\t\timage->sections = NULL;\n\t\timage->type_private = NULL;\n\t}\n\n\tif (image->base_address_set) {\n\t\t/* relocate */\n\t\tfor (unsigned int section = 0; section < image->num_sections; section++)\n\t\t\timage->sections[section].base_address += image->base_address;\n\t\t\t\t\t\t\t\t\t\t\t/* we're done relocating. The two statements below are mainly\n\t\t\t\t\t\t\t\t\t\t\t* for documentation purposes: stop anyone from empirically\n\t\t\t\t\t\t\t\t\t\t\t* thinking they should use these values henceforth. */\n\t\timage->base_address = 0;\n\t\timage->base_address_set = false;\n\t}\n\n\treturn retval;\n};\n\nint image_read_section(struct image *image,\n\tint section,\n\ttarget_addr_t offset,\n\tuint32_t size,\n\tuint8_t *buffer,\n\tsize_t *size_read)\n{\n\tint retval;\n\n\t/* don't read past the end of a section */\n\tif (offset + size > image->sections[section].size) {\n\t\tLOG_DEBUG(\n\t\t\t\"read past end of section: 0x%8.8\" TARGET_PRIxADDR \" + 0x%8.8\" PRIx32 \" > 0x%8.8\" PRIx32 \"\",\n\t\t\toffset,\n\t\t\tsize,\n\t\t\timage->sections[section].size);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (image->type == IMAGE_BINARY) {\n\t\tstruct image_binary *image_binary = image->type_private;\n\n\t\t/* only one section in a plain binary */\n\t\tif (section != 0)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\t/* seek to offset */\n\t\tretval = fileio_seek(image_binary->fileio, offset);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* return requested bytes */\n\t\tretval = fileio_read(image_binary->fileio, size, buffer, size_read);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else if (image->type == IMAGE_IHEX) {\n\t\tmemcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);\n\t\t*size_read = size;\n\n\t\treturn ERROR_OK;\n\t} else if (image->type == IMAGE_ELF) {\n\t\treturn image_elf_read_section(image, section, offset, size, buffer, size_read);\n\t} else if (image->type == IMAGE_MEMORY) {\n\t\tstruct image_memory *image_memory = image->type_private;\n\t\tuint32_t address = image->sections[section].base_address + offset;\n\n\t\t*size_read = 0;\n\n\t\twhile ((size - *size_read) > 0) {\n\t\t\tuint32_t size_in_cache;\n\n\t\t\tif (!image_memory->cache\n\t\t\t\t|| (address < image_memory->cache_address)\n\t\t\t\t|| (address >=\n\t\t\t\t(image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE))) {\n\t\t\t\tif (!image_memory->cache)\n\t\t\t\t\timage_memory->cache = malloc(IMAGE_MEMORY_CACHE_SIZE);\n\n\t\t\t\tif (target_read_buffer(image_memory->target, address &\n\t\t\t\t\t~(IMAGE_MEMORY_CACHE_SIZE - 1),\n\t\t\t\t\tIMAGE_MEMORY_CACHE_SIZE, image_memory->cache) != ERROR_OK) {\n\t\t\t\t\tfree(image_memory->cache);\n\t\t\t\t\timage_memory->cache = NULL;\n\t\t\t\t\treturn ERROR_IMAGE_TEMPORARILY_UNAVAILABLE;\n\t\t\t\t}\n\t\t\t\timage_memory->cache_address = address &\n\t\t\t\t\t~(IMAGE_MEMORY_CACHE_SIZE - 1);\n\t\t\t}\n\n\t\t\tsize_in_cache =\n\t\t\t\t(image_memory->cache_address + IMAGE_MEMORY_CACHE_SIZE) - address;\n\n\t\t\tmemcpy(buffer + *size_read,\n\t\t\t\timage_memory->cache + (address - image_memory->cache_address),\n\t\t\t\t(size_in_cache > size) ? size : size_in_cache\n\t\t\t\t);\n\n\t\t\t*size_read += (size_in_cache > size) ? size : size_in_cache;\n\t\t\taddress += (size_in_cache > size) ? size : size_in_cache;\n\t\t}\n\t} else if (image->type == IMAGE_SRECORD) {\n\t\tmemcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);\n\t\t*size_read = size;\n\n\t\treturn ERROR_OK;\n\t} else if (image->type == IMAGE_BUILDER) {\n\t\tmemcpy(buffer, (uint8_t *)image->sections[section].private + offset, size);\n\t\t*size_read = size;\n\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint image_add_section(struct image *image, target_addr_t base, uint32_t size, uint64_t flags, uint8_t const *data)\n{\n\tstruct imagesection *section;\n\n\t/* only image builder supports adding sections */\n\tif (image->type != IMAGE_BUILDER)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* see if there's a previous section */\n\tif (image->num_sections) {\n\t\tsection = &image->sections[image->num_sections - 1];\n\n\t\t/* see if it's enough to extend the last section,\n\t\t * adding data to previous sections or merging is not supported */\n\t\tif (((section->base_address + section->size) == base) &&\n\t\t\t(section->flags == flags)) {\n\t\t\tsection->private = realloc(section->private, section->size + size);\n\t\t\tmemcpy((uint8_t *)section->private + section->size, data, size);\n\t\t\tsection->size += size;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* allocate new section */\n\timage->num_sections++;\n\timage->sections =\n\t\trealloc(image->sections, sizeof(struct imagesection) * image->num_sections);\n\tsection = &image->sections[image->num_sections - 1];\n\tsection->base_address = base;\n\tsection->size = size;\n\tsection->flags = flags;\n\tsection->private = malloc(sizeof(uint8_t) * size);\n\tmemcpy((uint8_t *)section->private, data, size);\n\n\treturn ERROR_OK;\n}\n\nvoid image_close(struct image *image)\n{\n\tif (image->type == IMAGE_BINARY) {\n\t\tstruct image_binary *image_binary = image->type_private;\n\n\t\tfileio_close(image_binary->fileio);\n\t} else if (image->type == IMAGE_IHEX) {\n\t\tstruct image_ihex *image_ihex = image->type_private;\n\n\t\tfileio_close(image_ihex->fileio);\n\n\t\tfree(image_ihex->buffer);\n\t\timage_ihex->buffer = NULL;\n\t} else if (image->type == IMAGE_ELF) {\n\t\tstruct image_elf *image_elf = image->type_private;\n\n\t\tfileio_close(image_elf->fileio);\n\n\t\tif (image_elf->is_64_bit) {\n\t\t\tfree(image_elf->header64);\n\t\t\timage_elf->header64 = NULL;\n\n\t\t\tfree(image_elf->segments64);\n\t\t\timage_elf->segments64 = NULL;\n\t\t} else {\n\t\t\tfree(image_elf->header32);\n\t\t\timage_elf->header32 = NULL;\n\n\t\t\tfree(image_elf->segments32);\n\t\t\timage_elf->segments32 = NULL;\n\t\t}\n\t} else if (image->type == IMAGE_MEMORY) {\n\t\tstruct image_memory *image_memory = image->type_private;\n\n\t\tfree(image_memory->cache);\n\t\timage_memory->cache = NULL;\n\t} else if (image->type == IMAGE_SRECORD) {\n\t\tstruct image_mot *image_mot = image->type_private;\n\n\t\tfileio_close(image_mot->fileio);\n\n\t\tfree(image_mot->buffer);\n\t\timage_mot->buffer = NULL;\n\t} else if (image->type == IMAGE_BUILDER) {\n\t\tfor (unsigned int i = 0; i < image->num_sections; i++) {\n\t\t\tfree(image->sections[i].private);\n\t\t\timage->sections[i].private = NULL;\n\t\t}\n\t}\n\n\tfree(image->type_private);\n\timage->type_private = NULL;\n\n\tfree(image->sections);\n\timage->sections = NULL;\n}\n\nint image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes, uint32_t *checksum)\n{\n\tuint32_t crc = 0xffffffff;\n\tLOG_DEBUG(\"Calculating checksum\");\n\n\tstatic uint32_t crc32_table[256];\n\n\tstatic bool first_init;\n\tif (!first_init) {\n\t\t/* Initialize the CRC table and the decoding table.  */\n\t\tunsigned int i, j, c;\n\t\tfor (i = 0; i < 256; i++) {\n\t\t\t/* as per gdb */\n\t\t\tfor (c = i << 24, j = 8; j > 0; --j)\n\t\t\t\tc = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);\n\t\t\tcrc32_table[i] = c;\n\t\t}\n\n\t\tfirst_init = true;\n\t}\n\n\twhile (nbytes > 0) {\n\t\tint run = nbytes;\n\t\tif (run > 32768)\n\t\t\trun = 32768;\n\t\tnbytes -= run;\n\t\twhile (run--) {\n\t\t\t/* as per gdb */\n\t\t\tcrc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buffer++) & 255];\n\t\t}\n\t\tkeep_alive();\n\t}\n\n\tLOG_DEBUG(\"Calculating checksum done; checksum=0x%\" PRIx32, crc);\n\n\t*checksum = crc;\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/image.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2018 by Advantest                                       *\n *   florian.meister@advantest.com                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_IMAGE_H\n#define OPENOCD_TARGET_IMAGE_H\n\n#include <helper/fileio.h>\n#include <helper/replacements.h>\n\n#ifdef HAVE_ELF_H\n#include <elf.h>\n#endif\n\n#define IMAGE_MAX_ERROR_STRING\t\t(256)\n#define IMAGE_MAX_SECTIONS\t\t\t(512)\n\n#define IMAGE_MEMORY_CACHE_SIZE\t\t(2048)\n\nenum image_type {\n\tIMAGE_BINARY,\t/* plain binary */\n\tIMAGE_IHEX,\t\t/* intel hex-record format */\n\tIMAGE_MEMORY,\t/* target-memory pseudo-image */\n\tIMAGE_ELF,\t\t/* ELF binary */\n\tIMAGE_SRECORD,\t/* motorola s19 */\n\tIMAGE_BUILDER,\t/* when building a new image */\n};\n\nstruct imagesection {\n\ttarget_addr_t base_address;\n\tuint32_t size;\n\tuint64_t flags;\n\tvoid *private;\t\t/* private data */\n};\n\nstruct image {\n\tenum image_type type;\t\t/* image type (plain, ihex, ...) */\n\tvoid *type_private;\t\t/* type private data */\n\tunsigned int num_sections;\t\t/* number of sections contained in the image */\n\tstruct imagesection *sections;\t/* array of sections */\n\tbool base_address_set;\t/* whether the image has a base address set (for relocation purposes) */\n\tlong long base_address;\t\t/* base address, if one is set */\n\tbool start_address_set;\t/* whether the image has a start address (entry point) associated */\n\tuint32_t start_address;\t\t/* start address, if one is set */\n};\n\nstruct image_binary {\n\tstruct fileio *fileio;\n};\n\nstruct image_ihex {\n\tstruct fileio *fileio;\n\tuint8_t *buffer;\n};\n\nstruct image_memory {\n\tstruct target *target;\n\tuint8_t *cache;\n\tuint32_t cache_address;\n};\n\nstruct image_elf {\n\tstruct fileio *fileio;\n\tbool is_64_bit;\n\tunion {\n\t\tElf32_Ehdr *header32;\n\t\tElf64_Ehdr *header64;\n\t};\n\tunion {\n\t\tElf32_Phdr *segments32;\n\t\tElf64_Phdr *segments64;\n\t};\n\tuint32_t segment_count;\n\tuint8_t endianness;\n};\n\nstruct image_mot {\n\tstruct fileio *fileio;\n\tuint8_t *buffer;\n};\n\nint image_open(struct image *image, const char *url, const char *type_string);\nint image_read_section(struct image *image, int section, target_addr_t offset,\n\t\tuint32_t size, uint8_t *buffer, size_t *size_read);\nvoid image_close(struct image *image);\n\nint image_add_section(struct image *image, target_addr_t base, uint32_t size,\n\t\tuint64_t flags, uint8_t const *data);\n\nint image_calculate_checksum(const uint8_t *buffer, uint32_t nbytes,\n\t\tuint32_t *checksum);\n\n#define ERROR_IMAGE_FORMAT_ERROR\t(-1400)\n#define ERROR_IMAGE_TYPE_UNKNOWN\t(-1401)\n#define ERROR_IMAGE_TEMPORARILY_UNAVAILABLE\t\t(-1402)\n#define ERROR_IMAGE_CHECKSUM\t\t(-1403)\n\n#endif /* OPENOCD_TARGET_IMAGE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/lakemont.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright(c) 2013-2016 Intel Corporation.\n *\n * Adrian Burns (adrian.burns@intel.com)\n * Thomas Faust (thomas.faust@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n * Julien Carreno (julien.carreno@intel.com)\n * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)\n * Jessica Gomez (jessica.gomez.hernandez@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * This implements the probemode operations for Lakemont 1 (LMT1).\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"lakemont.h\"\n#include \"register.h\"\n#include \"breakpoints.h\"\n#include \"x86_32_common.h\"\n\nstatic int irscan(struct target *t, uint8_t *out,\n\t\t\tuint8_t *in, uint8_t ir_len);\nstatic int drscan(struct target *t, uint8_t *out, uint8_t *in, uint8_t len);\nstatic int save_context(struct target *target);\nstatic int restore_context(struct target *target);\nstatic uint32_t get_tapstatus(struct target *t);\nstatic int enter_probemode(struct target *t);\nstatic int exit_probemode(struct target *t);\nstatic int halt_prep(struct target *t);\nstatic int do_halt(struct target *t);\nstatic int do_resume(struct target *t);\nstatic int read_all_core_hw_regs(struct target *t);\nstatic int write_all_core_hw_regs(struct target *t);\nstatic int read_hw_reg(struct target *t,\n\t\t\tint reg, uint32_t *regval, uint8_t cache);\nstatic int write_hw_reg(struct target *t,\n\t\t\tint reg, uint32_t regval, uint8_t cache);\nstatic struct reg_cache *lakemont_build_reg_cache\n\t\t\t(struct target *target);\nstatic int submit_reg_pir(struct target *t, int num);\nstatic int submit_instruction_pir(struct target *t, int num);\nstatic int submit_pir(struct target *t, uint64_t op);\nstatic int lakemont_get_core_reg(struct reg *reg);\nstatic int lakemont_set_core_reg(struct reg *reg, uint8_t *buf);\n\nstatic struct scan_blk scan;\n\n/* registers and opcodes for register access, pm_idx is used to identify the\n * registers that are modified for lakemont probemode specific operations\n */\nstatic const struct {\n\tuint8_t id;\n\tconst char *name;\n\tuint64_t op;\n\tuint8_t pm_idx;\n\tunsigned bits;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n} regs[] = {\n\t/* general purpose registers */\n\t{ EAX, \"eax\", 0x000000D01D660000ULL, 0, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ECX, \"ecx\", 0x000000501D660000ULL, 1, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ EDX, \"edx\", 0x000000901D660000ULL, 2, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ EBX, \"ebx\", 0x000000101D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ESP, \"esp\", 0x000000E01D660000ULL, NOT_PMREG, 32, REG_TYPE_DATA_PTR, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ EBP, \"ebp\", 0x000000601D660000ULL, NOT_PMREG, 32, REG_TYPE_DATA_PTR, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ESI, \"esi\", 0x000000A01D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ EDI, \"edi\", 0x000000201D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\n\t/* instruction pointer & flags */\n\t{ EIP, \"eip\", 0x000000C01D660000ULL, 3, 32, REG_TYPE_CODE_PTR, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ EFLAGS, \"eflags\", 0x000000401D660000ULL, 4, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\n\t/* segment registers */\n\t{ CS, \"cs\", 0x000000281D660000ULL, 5, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ SS, \"ss\", 0x000000C81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ DS, \"ds\", 0x000000481D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ES, \"es\", 0x000000A81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FS, \"fs\", 0x000000881D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ GS, \"gs\", 0x000000081D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\n\t/* floating point unit registers - not accessible via JTAG - here to satisfy GDB */\n\t{ ST0, \"st0\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST1, \"st1\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST2, \"st2\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST3, \"st3\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST4, \"st4\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST5, \"st5\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST6, \"st6\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ ST7, \"st7\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FCTRL, \"fctrl\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FSTAT, \"fstat\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FTAG, \"ftag\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FISEG, \"fiseg\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FIOFF, \"fioff\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FOSEG, \"foseg\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FOOFF, \"fooff\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\t{ FOP, \"fop\", 0x0, NOT_AVAIL_REG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.core\" },\n\n\t/* control registers */\n\t{ CR0, \"cr0\", 0x000000001D660000ULL, 6, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ CR2, \"cr2\", 0x000000BC1D660000ULL, 7, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ CR3, \"cr3\", 0x000000801D660000ULL, 8, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ CR4, \"cr4\", 0x0000002C1D660000ULL, 9, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\n\t/* debug registers */\n\t{ DR0, \"dr0\", 0x0000007C1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DR1, \"dr1\", 0x000000FC1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DR2, \"dr2\", 0x000000021D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DR3, \"dr3\", 0x000000821D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DR6, \"dr6\", 0x000000301D660000ULL, 10, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DR7, \"dr7\", 0x000000B01D660000ULL, 11, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\n\t/* descriptor tables */\n\t{ IDTB, \"idtbase\", 0x000000581D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ IDTL, \"idtlimit\", 0x000000D81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ IDTAR, \"idtar\", 0x000000981D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GDTB, \"gdtbase\", 0x000000B81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GDTL, \"gdtlimit\", 0x000000781D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GDTAR, \"gdtar\", 0x000000381D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ TR, \"tr\", 0x000000701D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ LDTR, \"ldtr\", 0x000000F01D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ LDTB, \"ldbase\", 0x000000041D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ LDTL, \"ldlimit\", 0x000000841D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ LDTAR, \"ldtar\", 0x000000F81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\n\t/* segment registers */\n\t{ CSB, \"csbase\", 0x000000F41D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ CSL, \"cslimit\", 0x0000000C1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ CSAR, \"csar\", 0x000000741D660000ULL, 12, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DSB, \"dsbase\", 0x000000941D660000ULL, 13, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DSL, \"dslimit\", 0x000000541D660000ULL, 14, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ DSAR, \"dsar\", 0x000000141D660000ULL, 15, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ ESB, \"esbase\", 0x0000004C1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ ESL, \"eslimit\", 0x000000CC1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ ESAR, \"esar\", 0x0000008C1D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ FSB, \"fsbase\", 0x000000641D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ FSL, \"fslimit\", 0x000000E41D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ FSAR, \"fsar\", 0x000000A41D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GSB, \"gsbase\", 0x000000C41D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GSL, \"gslimit\", 0x000000241D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ GSAR, \"gsar\", 0x000000441D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ SSB, \"ssbase\", 0x000000341D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ SSL, \"sslimit\", 0x000000B41D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ SSAR, \"ssar\", 0x000000D41D660000ULL, 16, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ TSSB, \"tssbase\", 0x000000E81D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ TSSL, \"tsslimit\", 0x000000181D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t{ TSSAR, \"tssar\", 0x000000681D660000ULL, NOT_PMREG, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n\t/* probemode control register */\n\t{ PMCR, \"pmcr\", 0x000000421D660000ULL, 17, 32, REG_TYPE_INT32, \"general\", \"org.gnu.gdb.i386.sys\" },\n};\n\nstatic const struct {\n\tuint8_t id;\n\tconst char *name;\n\tuint64_t op;\n} instructions[] = {\n\t/* memory read/write */\n\t{ MEMRDB32, \"MEMRDB32\", 0x0909090909090851ULL },\n\t{ MEMRDB16, \"MEMRDB16\", 0x09090909090851E6ULL },\n\t{ MEMRDH32, \"MEMRDH32\", 0x090909090908D166ULL },\n\t{ MEMRDH16, \"MEMRDH16\", 0x090909090908D1E6ULL },\n\t{ MEMRDW32, \"MEMRDW32\", 0x09090909090908D1ULL },\n\t{ MEMRDW16, \"MEMRDW16\", 0x0909090908D1E666ULL },\n\t{ MEMWRB32, \"MEMWRB32\", 0x0909090909090811ULL },\n\t{ MEMWRB16, \"MEMWRB16\", 0x09090909090811E6ULL },\n\t{ MEMWRH32, \"MEMWRH32\", 0x0909090909089166ULL },\n\t{ MEMWRH16, \"MEMWRH16\", 0x09090909090891E6ULL },\n\t{ MEMWRW32, \"MEMWRW32\", 0x0909090909090891ULL },\n\t{ MEMWRW16, \"MEMWRW16\", 0x090909090891E666ULL },\n\t/* IO read/write */\n\t{ IORDB32, \"IORDB32\", 0x0909090909090937ULL },\n\t{ IORDB16, \"IORDB16\", 0x09090909090937E6ULL },\n\t{ IORDH32, \"IORDH32\", 0x090909090909B766ULL },\n\t{ IORDH16, \"IORDH16\", 0x090909090909B7E6ULL },\n\t{ IORDW32, \"IORDW32\", 0x09090909090909B7ULL },\n\t{ IORDW16, \"IORDW16\", 0x0909090909B7E666ULL },\n\t{ IOWRB32, \"IOWRB32\", 0x0909090909090977ULL },\n\t{ IOWRB16, \"IOWRB16\", 0x09090909090977E6ULL },\n\t{ IOWRH32, \"IOWRH32\", 0x090909090909F766ULL },\n\t{ IOWRH16, \"IOWRH16\", 0x090909090909F7E6ULL },\n\t{ IOWRW32, \"IOWRW32\", 0x09090909090909F7ULL },\n\t{ IOWRW16, \"IOWRW16\", 0x0909090909F7E666ULL },\n\t/* lakemont1 core shadow ram access opcodes */\n\t{ SRAMACCESS, \"SRAMACCESS\", 0x0000000E9D660000ULL },\n\t{ SRAM2PDR, \"SRAM2PDR\", 0x4CF0000000000000ULL },\n\t{ PDR2SRAM, \"PDR2SRAM\", 0x0CF0000000000000ULL },\n\t{ WBINVD, \"WBINVD\", 0x09090909090990F0ULL },\n};\n\nbool check_not_halted(const struct target *t)\n{\n\tbool halted = t->state == TARGET_HALTED;\n\tif (!halted)\n\t\tLOG_ERROR(\"target running, halt it first\");\n\treturn !halted;\n}\n\nstatic int irscan(struct target *t, uint8_t *out,\n\t\t\tuint8_t *in, uint8_t ir_len)\n{\n\tint retval = ERROR_OK;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tif (!t->tap) {\n\t\tretval = ERROR_FAIL;\n\t\tLOG_ERROR(\"%s invalid target tap\", __func__);\n\t\treturn retval;\n\t}\n\tif (ir_len != t->tap->ir_length) {\n\t\tretval = ERROR_FAIL;\n\t\tif (t->tap->enabled)\n\t\t\tLOG_ERROR(\"%s tap enabled but tap irlen=%d\",\n\t\t\t\t\t__func__, t->tap->ir_length);\n\t\telse\n\t\t\tLOG_ERROR(\"%s tap not enabled and irlen=%d\",\n\t\t\t\t\t__func__, t->tap->ir_length);\n\t\treturn retval;\n\t}\n\tstruct scan_field *fields = &scan.field;\n\tfields->num_bits = ir_len;\n\tfields->out_value = out;\n\tfields->in_value = in;\n\tjtag_add_ir_scan(x86_32->curr_tap, fields, TAP_IDLE);\n\tif (x86_32->flush) {\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"%s failed to execute queue\", __func__);\n\t}\n\treturn retval;\n}\n\nstatic int drscan(struct target *t, uint8_t *out, uint8_t *in, uint8_t len)\n{\n\tint retval = ERROR_OK;\n\tuint64_t data = 0;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tif (!t->tap) {\n\t\tretval = ERROR_FAIL;\n\t\tLOG_ERROR(\"%s invalid target tap\", __func__);\n\t\treturn retval;\n\t}\n\tif (len > MAX_SCAN_SIZE || 0 == len) {\n\t\tretval = ERROR_FAIL;\n\t\tLOG_ERROR(\"%s data len is %d bits, max is %d bits\",\n\t\t\t\t__func__, len, MAX_SCAN_SIZE);\n\t\treturn retval;\n\t}\n\tstruct scan_field *fields = &scan.field;\n\tfields->out_value = out;\n\tfields->in_value = in;\n\tfields->num_bits = len;\n\tjtag_add_dr_scan(x86_32->curr_tap, 1, fields, TAP_IDLE);\n\tif (x86_32->flush) {\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s drscan failed to execute queue\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t}\n\tif (in) {\n\t\tif (len >= 8) {\n\t\t\tfor (int n = (len / 8) - 1 ; n >= 0; n--)\n\t\t\t\tdata = (data << 8) + *(in+n);\n\t\t} else\n\t\t\tLOG_DEBUG(\"dr in 0x%02\" PRIx8, *in);\n\t} else {\n\t\tLOG_ERROR(\"%s no drscan data\", __func__);\n\t\tretval = ERROR_FAIL;\n\t}\n\treturn retval;\n}\n\nstatic int save_context(struct target *t)\n{\n\tint err;\n\t/* read core registers from lakemont sram */\n\terr = read_all_core_hw_regs(t);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error reading regs\", __func__);\n\t\treturn err;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int restore_context(struct target *t)\n{\n\tint err = ERROR_OK;\n\tuint32_t i;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\t/* write core regs into the core PM SRAM from the reg_cache */\n\terr = write_all_core_hw_regs(t);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error writing regs\", __func__);\n\t\treturn err;\n\t}\n\n\tfor (i = 0; i < (x86_32->cache->num_regs); i++) {\n\t\tx86_32->cache->reg_list[i].dirty = false;\n\t\tx86_32->cache->reg_list[i].valid = false;\n\t}\n\treturn err;\n}\n\n/*\n * we keep reg_cache in sync with hardware at halt/resume time, we avoid\n * writing to real hardware here because pm_regs reflects the hardware\n * while we are halted then reg_cache syncs with hw on resume\n * TODO - in order for \"reg eip force\" to work it assume get/set reads\n * and writes from hardware, may be other reasons also because generally\n * other openocd targets read/write from hardware in get/set - watch this!\n */\nstatic int lakemont_get_core_reg(struct reg *reg)\n{\n\tint retval = ERROR_OK;\n\tstruct lakemont_core_reg *lakemont_reg = reg->arch_info;\n\tstruct target *t = lakemont_reg->target;\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tLOG_DEBUG(\"reg=%s, value=0x%08\" PRIx32, reg->name,\n\t\t\tbuf_get_u32(reg->value, 0, 32));\n\treturn retval;\n}\n\nstatic int lakemont_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct lakemont_core_reg *lakemont_reg = reg->arch_info;\n\tstruct target *t = lakemont_reg->target;\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\tLOG_DEBUG(\"reg=%s, newval=0x%08\" PRIx32, reg->name, value);\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tbuf_set_u32(reg->value, 0, 32, value);\n\treg->dirty = true;\n\treg->valid = true;\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type lakemont_reg_type = {\n\t/* these get called if reg_cache doesn't have a \"valid\" value\n\t * of an individual reg eg \"reg eip\" but not for \"reg\" block\n\t */\n\t.get = lakemont_get_core_reg,\n\t.set = lakemont_set_core_reg,\n};\n\nstruct reg_cache *lakemont_build_reg_cache(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tint num_regs = ARRAY_SIZE(regs);\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&t->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct lakemont_core_reg *arch_info = malloc(sizeof(struct lakemont_core_reg) * num_regs);\n\tstruct reg_feature *feature;\n\tint i;\n\n\tif (!cache || !reg_list || !arch_info) {\n\t\tfree(cache);\n\t\tfree(reg_list);\n\t\tfree(arch_info);\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn NULL;\n\t}\n\n\t/* Build the process context cache */\n\tcache->name = \"lakemont registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\t(*cache_p) = cache;\n\tx86_32->cache = cache;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i].target = t;\n\t\tarch_info[i].x86_32_common = x86_32;\n\t\tarch_info[i].op = regs[i].op;\n\t\tarch_info[i].pm_idx = regs[i].pm_idx;\n\t\treg_list[i].name = regs[i].name;\n\t\treg_list[i].size = 32;\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].type = &lakemont_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\n\t\treg_list[i].group = regs[i].group;\n\t\treg_list[i].number = i;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].caller_save = true;\t/* gdb defaults to true */\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = regs[i].feature;\n\t\t\treg_list[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"%s unable to allocate feature list\", __func__);\n\n\t\treg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\tif (reg_list[i].reg_data_type)\n\t\t\treg_list[i].reg_data_type->type = regs[i].type;\n\t\telse\n\t\t\tLOG_ERROR(\"%s unable to allocate reg type list\", __func__);\n\t}\n\treturn cache;\n}\n\nstatic uint32_t get_tapstatus(struct target *t)\n{\n\tscan.out[0] = TAPSTATUS;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn 0;\n\tif (drscan(t, NULL, scan.out, TS_SIZE) != ERROR_OK)\n\t\treturn 0;\n\treturn buf_get_u32(scan.out, 0, 32);\n}\n\nstatic int enter_probemode(struct target *t)\n{\n\tuint32_t tapstatus = 0;\n\tint retries = 100;\n\n\ttapstatus = get_tapstatus(t);\n\tLOG_DEBUG(\"TS before PM enter = 0x%08\" PRIx32, tapstatus);\n\tif (tapstatus & TS_PM_BIT) {\n\t\tLOG_DEBUG(\"core already in probemode\");\n\t\treturn ERROR_OK;\n\t}\n\tscan.out[0] = PROBEMODE;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tscan.out[0] = 1;\n\tif (drscan(t, scan.out, scan.in, 1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\twhile (retries--) {\n\t\ttapstatus = get_tapstatus(t);\n\t\tLOG_DEBUG(\"TS after PM enter = 0x%08\" PRIx32, tapstatus);\n\t\tif ((tapstatus & TS_PM_BIT) && (!(tapstatus & TS_EN_PM_BIT)))\n\t\t\treturn ERROR_OK;\n\t}\n\n\tLOG_ERROR(\"%s PM enter error, tapstatus = 0x%08\" PRIx32\n\t\t\t, __func__, tapstatus);\n\treturn ERROR_FAIL;\n}\n\nstatic int exit_probemode(struct target *t)\n{\n\tuint32_t tapstatus = get_tapstatus(t);\n\tLOG_DEBUG(\"TS before PM exit = 0x%08\" PRIx32, tapstatus);\n\n\tif (!(tapstatus & TS_PM_BIT)) {\n\t\tLOG_USER(\"core not in PM\");\n\t\treturn ERROR_OK;\n\t}\n\tscan.out[0] = PROBEMODE;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tscan.out[0] = 0;\n\tif (drscan(t, scan.out, scan.in, 1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\n/* do whats needed to properly enter probemode for debug on lakemont */\nstatic int halt_prep(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tif (write_hw_reg(t, DSB, PM_DSB, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write %s 0x%08\" PRIx32, regs[DSB].name, PM_DSB);\n\tif (write_hw_reg(t, DSL, PM_DSL, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write %s 0x%08\" PRIx32, regs[DSL].name, PM_DSL);\n\tif (write_hw_reg(t, DSAR, PM_DSAR, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write DSAR 0x%08\" PRIx32, PM_DSAR);\n\tif (write_hw_reg(t, CSB, PM_DSB, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write %s 0x%08\" PRIx32, regs[CSB].name, PM_DSB);\n\tif (write_hw_reg(t, CSL, PM_DSL, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write %s 0x%08\" PRIx32, regs[CSL].name, PM_DSL);\n\tif (write_hw_reg(t, DR7, PM_DR7, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"write DR7 0x%08\" PRIx32, PM_DR7);\n\n\tuint32_t eflags = buf_get_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32);\n\tuint32_t csar = buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32);\n\tuint32_t ssar = buf_get_u32(x86_32->cache->reg_list[SSAR].value, 0, 32);\n\tuint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32);\n\n\t/* clear VM86 and IF bits if they are set */\n\tLOG_DEBUG(\"EFLAGS = 0x%08\" PRIx32 \", VM86 = %d, IF = %d\", eflags,\n\t\t\teflags & EFLAGS_VM86 ? 1 : 0,\n\t\t\teflags & EFLAGS_IF ? 1 : 0);\n\tif ((eflags & EFLAGS_VM86) || (eflags & EFLAGS_IF)) {\n\t\tx86_32->pm_regs[I(EFLAGS)] = eflags & ~(EFLAGS_VM86 | EFLAGS_IF);\n\t\tif (write_hw_reg(t, EFLAGS, x86_32->pm_regs[I(EFLAGS)], 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tLOG_DEBUG(\"EFLAGS now = 0x%08\" PRIx32 \", VM86 = %d, IF = %d\",\n\t\t\t\tx86_32->pm_regs[I(EFLAGS)],\n\t\t\t\tx86_32->pm_regs[I(EFLAGS)] & EFLAGS_VM86 ? 1 : 0,\n\t\t\t\tx86_32->pm_regs[I(EFLAGS)] & EFLAGS_IF ? 1 : 0);\n\t}\n\n\t/* set CPL to 0 for memory access */\n\tif (csar & CSAR_DPL) {\n\t\tx86_32->pm_regs[I(CSAR)] = csar & ~CSAR_DPL;\n\t\tif (write_hw_reg(t, CSAR, x86_32->pm_regs[I(CSAR)], 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tLOG_DEBUG(\"write CSAR_CPL to 0 0x%08\" PRIx32, x86_32->pm_regs[I(CSAR)]);\n\t}\n\tif (ssar & SSAR_DPL) {\n\t\tx86_32->pm_regs[I(SSAR)] = ssar & ~SSAR_DPL;\n\t\tif (write_hw_reg(t, SSAR, x86_32->pm_regs[I(SSAR)], 0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tLOG_DEBUG(\"write SSAR_CPL to 0 0x%08\" PRIx32, x86_32->pm_regs[I(SSAR)]);\n\t}\n\n\t/* if cache's are enabled, disable and flush, depending on the core version */\n\tif (!(x86_32->core_type == LMT3_5) && !(cr0 & CR0_CD)) {\n\t\tLOG_DEBUG(\"caching enabled CR0 = 0x%08\" PRIx32, cr0);\n\t\tif (cr0 & CR0_PG) {\n\t\t\tx86_32->pm_regs[I(CR0)] = cr0 & ~CR0_PG;\n\t\t\tif (write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tLOG_DEBUG(\"cleared paging CR0_PG = 0x%08\" PRIx32, x86_32->pm_regs[I(CR0)]);\n\t\t\t/* submit wbinvd to flush cache */\n\t\t\tif (submit_reg_pir(t, WBINVD) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tx86_32->pm_regs[I(CR0)] =\n\t\t\t\tx86_32->pm_regs[I(CR0)] | (CR0_CD | CR0_NW | CR0_PG);\n\t\t\tif (write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tLOG_DEBUG(\"set CD, NW and PG, CR0 = 0x%08\" PRIx32, x86_32->pm_regs[I(CR0)]);\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int do_halt(struct target *t)\n{\n\t/* needs proper handling later if doing a halt errors out */\n\tt->state = TARGET_DEBUG_RUNNING;\n\tif (enter_probemode(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn lakemont_update_after_probemode_entry(t);\n}\n\n/* we need to expose the update to be able to complete the reset at SoC level */\nint lakemont_update_after_probemode_entry(struct target *t)\n{\n\tif (save_context(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (halt_prep(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tt->state = TARGET_HALTED;\n\n\treturn target_call_event_callbacks(t, TARGET_EVENT_HALTED);\n}\n\nstatic int do_resume(struct target *t)\n{\n\t/* needs proper handling later */\n\tt->state = TARGET_DEBUG_RUNNING;\n\tif (restore_context(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (exit_probemode(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tt->state = TARGET_RUNNING;\n\n\tt->debug_reason = DBG_REASON_NOTHALTED;\n\tLOG_USER(\"target running\");\n\n\treturn target_call_event_callbacks(t, TARGET_EVENT_RESUMED);\n}\n\nstatic int read_all_core_hw_regs(struct target *t)\n{\n\tint err;\n\tuint32_t regval;\n\tunsigned i;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tfor (i = 0; i < (x86_32->cache->num_regs); i++) {\n\t\tif (regs[i].pm_idx == NOT_AVAIL_REG)\n\t\t\tcontinue;\n\t\terr = read_hw_reg(t, regs[i].id, &regval, 1);\n\t\tif (err != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s error saving reg %s\",\n\t\t\t\t\t__func__, x86_32->cache->reg_list[i].name);\n\t\t\treturn err;\n\t\t}\n\t}\n\tLOG_DEBUG(\"read_all_core_hw_regs read %u registers ok\", i);\n\treturn ERROR_OK;\n}\n\nstatic int write_all_core_hw_regs(struct target *t)\n{\n\tint err;\n\tunsigned i;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tfor (i = 0; i < (x86_32->cache->num_regs); i++) {\n\t\tif (regs[i].pm_idx == NOT_AVAIL_REG)\n\t\t\tcontinue;\n\t\terr = write_hw_reg(t, i, 0, 1);\n\t\tif (err != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s error restoring reg %s\",\n\t\t\t\t\t__func__, x86_32->cache->reg_list[i].name);\n\t\t\treturn err;\n\t\t}\n\t}\n\tLOG_DEBUG(\"write_all_core_hw_regs wrote %u registers ok\", i);\n\treturn ERROR_OK;\n}\n\n/* read reg from lakemont core shadow ram, update reg cache if needed */\nstatic int read_hw_reg(struct target *t, int reg, uint32_t *regval, uint8_t cache)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct lakemont_core_reg *arch_info;\n\tarch_info = x86_32->cache->reg_list[reg].arch_info;\n\tx86_32->flush = 0; /* don't flush scans till we have a batch */\n\tif (submit_reg_pir(t, reg) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (submit_instruction_pir(t, SRAMACCESS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (submit_instruction_pir(t, SRAM2PDR) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tx86_32->flush = 1;\n\tscan.out[0] = RDWRPDR;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (drscan(t, NULL, scan.out, PDR_SIZE) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tjtag_add_sleep(DELAY_SUBMITPIR);\n\t*regval = buf_get_u32(scan.out, 0, 32);\n\tif (cache) {\n\t\tbuf_set_u32(x86_32->cache->reg_list[reg].value, 0, 32, *regval);\n\t\tx86_32->cache->reg_list[reg].valid = true;\n\t\tx86_32->cache->reg_list[reg].dirty = false;\n\t}\n\tLOG_DEBUG(\"reg=%s, op=0x%016\" PRIx64 \", val=0x%08\" PRIx32,\n\t\t\tx86_32->cache->reg_list[reg].name,\n\t\t\tarch_info->op,\n\t\t\t*regval);\n\treturn ERROR_OK;\n}\n\n/* write lakemont core shadow ram reg, update reg cache if needed */\nstatic int write_hw_reg(struct target *t, int reg, uint32_t regval, uint8_t cache)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct lakemont_core_reg *arch_info;\n\tarch_info = x86_32->cache->reg_list[reg].arch_info;\n\n\tuint8_t reg_buf[4];\n\tif (cache)\n\t\tregval = buf_get_u32(x86_32->cache->reg_list[reg].value, 0, 32);\n\tbuf_set_u32(reg_buf, 0, 32, regval);\n\tLOG_DEBUG(\"reg=%s, op=0x%016\" PRIx64 \", val=0x%08\" PRIx32,\n\t\t\tx86_32->cache->reg_list[reg].name,\n\t\t\tarch_info->op,\n\t\t\tregval);\n\n\tx86_32->flush = 0; /* don't flush scans till we have a batch */\n\tif (submit_reg_pir(t, reg) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (submit_instruction_pir(t, SRAMACCESS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tscan.out[0] = RDWRPDR;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (drscan(t, reg_buf, scan.out, PDR_SIZE) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tx86_32->flush = 1;\n\tif (submit_instruction_pir(t, PDR2SRAM) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* we are writing from the cache so ensure we reset flags */\n\tif (cache) {\n\t\tx86_32->cache->reg_list[reg].dirty = false;\n\t\tx86_32->cache->reg_list[reg].valid = false;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic bool is_paging_enabled(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tif (x86_32->pm_regs[I(CR0)] & CR0_PG)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic uint8_t get_num_user_regs(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\treturn x86_32->cache->num_regs;\n}\n/* value of the CR0.PG (paging enabled) bit influences memory reads/writes */\nstatic int disable_paging(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tx86_32->pm_regs[I(CR0)] = x86_32->pm_regs[I(CR0)] & ~CR0_PG;\n\tint err = x86_32->write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error disabling paging\", __func__);\n\t\treturn err;\n\t}\n\treturn err;\n}\n\nstatic int enable_paging(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tx86_32->pm_regs[I(CR0)] = (x86_32->pm_regs[I(CR0)] | CR0_PG);\n\tint err = x86_32->write_hw_reg(t, CR0, x86_32->pm_regs[I(CR0)], 0);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error enabling paging\", __func__);\n\t\treturn err;\n\t}\n\treturn err;\n}\n\nstatic bool sw_bpts_supported(struct target *t)\n{\n\tuint32_t tapstatus = get_tapstatus(t);\n\tif (tapstatus & TS_SBP_BIT)\n\t\treturn true;\n\telse\n\t\treturn false;\n}\n\nstatic int transaction_status(struct target *t)\n{\n\tuint32_t tapstatus = get_tapstatus(t);\n\tif ((TS_EN_PM_BIT | TS_PRDY_BIT) & tapstatus) {\n\t\tLOG_ERROR(\"%s transaction error tapstatus = 0x%08\" PRIx32\n\t\t\t\t, __func__, tapstatus);\n\t\treturn ERROR_FAIL;\n\t} else {\n\t\treturn ERROR_OK;\n\t}\n}\n\nstatic int submit_instruction(struct target *t, int num)\n{\n\tint err = submit_instruction_pir(t, num);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error submitting pir\", __func__);\n\t\treturn err;\n\t}\n\treturn err;\n}\n\nstatic int submit_reg_pir(struct target *t, int num)\n{\n\tLOG_DEBUG(\"reg %s op=0x%016\" PRIx64, regs[num].name, regs[num].op);\n\tint err = submit_pir(t, regs[num].op);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error submitting pir\", __func__);\n\t\treturn err;\n\t}\n\treturn err;\n}\n\nstatic int submit_instruction_pir(struct target *t, int num)\n{\n\tLOG_DEBUG(\"%s op=0x%016\" PRIx64, instructions[num].name,\n\t\t\tinstructions[num].op);\n\tint err = submit_pir(t, instructions[num].op);\n\tif (err != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error submitting pir\", __func__);\n\t\treturn err;\n\t}\n\treturn err;\n}\n\n/*\n * PIR (Probe Mode Instruction Register), SUBMITPIR is an \"IR only\" TAP\n * command; there is no corresponding data register\n */\nstatic int submit_pir(struct target *t, uint64_t op)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tuint8_t op_buf[8];\n\tbuf_set_u64(op_buf, 0, 64, op);\n\tint flush = x86_32->flush;\n\tx86_32->flush = 0;\n\tscan.out[0] = WRPIR;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (drscan(t, op_buf, scan.out, PIR_SIZE) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tscan.out[0] = SUBMITPIR;\n\tx86_32->flush = flush;\n\tif (irscan(t, scan.out, NULL, LMT_IRLEN) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tjtag_add_sleep(DELAY_SUBMITPIR);\n\treturn ERROR_OK;\n}\n\nint lakemont_init_target(struct command_context *cmd_ctx, struct target *t)\n{\n\tlakemont_build_reg_cache(t);\n\tt->state = TARGET_RUNNING;\n\tt->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nint lakemont_init_arch_info(struct target *t, struct x86_32_common *x86_32)\n{\n\tx86_32->submit_instruction = submit_instruction;\n\tx86_32->transaction_status = transaction_status;\n\tx86_32->read_hw_reg = read_hw_reg;\n\tx86_32->write_hw_reg = write_hw_reg;\n\tx86_32->sw_bpts_supported = sw_bpts_supported;\n\tx86_32->get_num_user_regs = get_num_user_regs;\n\tx86_32->is_paging_enabled = is_paging_enabled;\n\tx86_32->disable_paging = disable_paging;\n\tx86_32->enable_paging = enable_paging;\n\treturn ERROR_OK;\n}\n\nint lakemont_poll(struct target *t)\n{\n\t/* LMT1 PMCR register currently allows code breakpoints, data breakpoints,\n\t * single stepping and shutdowns to be redirected to PM but does not allow\n\t * redirecting into PM as a result of SMM enter and SMM exit\n\t */\n\tuint32_t ts = get_tapstatus(t);\n\n\tif (ts == 0xFFFFFFFF && t->state != TARGET_DEBUG_RUNNING) {\n\t\t/* something is wrong here */\n\t\tLOG_ERROR(\"tapstatus invalid - scan_chain serialization or locked JTAG access issues\");\n\t\t/* TODO: Give a hint that unlocking is wrong or maybe a\n\t\t * 'jtag arp_init' helps\n\t\t */\n\t\tt->state = TARGET_DEBUG_RUNNING;\n\t\treturn ERROR_OK;\n\t}\n\n\tif (t->state == TARGET_HALTED && (!(ts & TS_PM_BIT))) {\n\t\tLOG_INFO(\"target running for unknown reason\");\n\t\tt->state = TARGET_RUNNING;\n\t}\n\n\tif (t->state == TARGET_RUNNING &&\n\t\tt->state != TARGET_DEBUG_RUNNING) {\n\n\t\tif ((ts & TS_PM_BIT) && (ts & TS_PMCR_BIT)) {\n\n\t\t\tLOG_DEBUG(\"redirect to PM, tapstatus=0x%08\" PRIx32, get_tapstatus(t));\n\n\t\t\tt->state = TARGET_DEBUG_RUNNING;\n\t\t\tif (save_context(t) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tif (halt_prep(t) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tt->state = TARGET_HALTED;\n\t\t\tt->debug_reason = DBG_REASON_UNDEFINED;\n\n\t\t\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\t\t\tuint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);\n\t\t\tuint32_t dr6 = buf_get_u32(x86_32->cache->reg_list[DR6].value, 0, 32);\n\t\t\tuint32_t hwbreakpoint = (uint32_t)-1;\n\n\t\t\tif (dr6 & DR6_BRKDETECT_0)\n\t\t\t\thwbreakpoint = 0;\n\t\t\tif (dr6 & DR6_BRKDETECT_1)\n\t\t\t\thwbreakpoint = 1;\n\t\t\tif (dr6 & DR6_BRKDETECT_2)\n\t\t\t\thwbreakpoint = 2;\n\t\t\tif (dr6 & DR6_BRKDETECT_3)\n\t\t\t\thwbreakpoint = 3;\n\n\t\t\tif (hwbreakpoint != (uint32_t)-1) {\n\t\t\t\tuint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32);\n\t\t\t\tuint32_t type = dr7 & (0x03 << (DR7_RW_SHIFT + hwbreakpoint*DR7_RW_LEN_SIZE));\n\t\t\t\tif (type == DR7_BP_EXECUTE) {\n\t\t\t\t\tLOG_USER(\"hit hardware breakpoint (hwreg=%\" PRIu32 \") at 0x%08\" PRIx32, hwbreakpoint, eip);\n\t\t\t\t} else {\n\t\t\t\t\tuint32_t address = 0;\n\t\t\t\t\tswitch (hwbreakpoint) {\n\t\t\t\t\tdefault:\n\t\t\t\t\tcase 0:\n\t\t\t\t\t\taddress = buf_get_u32(x86_32->cache->reg_list[DR0].value, 0, 32);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\taddress = buf_get_u32(x86_32->cache->reg_list[DR1].value, 0, 32);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\taddress = buf_get_u32(x86_32->cache->reg_list[DR2].value, 0, 32);\n\t\t\t\t\tbreak;\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\taddress = buf_get_u32(x86_32->cache->reg_list[DR3].value, 0, 32);\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tLOG_USER(\"hit '%s' watchpoint for 0x%08\" PRIx32 \" (hwreg=%\" PRIu32 \") at 0x%08\" PRIx32,\n\t\t\t\t\t\t\t\ttype == DR7_BP_WRITE ? \"write\" : \"access\", address,\n\t\t\t\t\t\t\t\thwbreakpoint, eip);\n\t\t\t\t}\n\t\t\t\tt->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\t} else {\n\t\t\t\t/* Check if the target hit a software breakpoint.\n\t\t\t\t * ! Watch out: EIP is currently pointing after the breakpoint opcode\n\t\t\t\t */\n\t\t\t\tstruct breakpoint *bp = NULL;\n\t\t\t\tbp = breakpoint_find(t, eip-1);\n\t\t\t\tif (bp) {\n\t\t\t\t\tt->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\t\t\tif (bp->type == BKPT_SOFT) {\n\t\t\t\t\t\t/* The EIP is now pointing the next byte after the\n\t\t\t\t\t\t * breakpoint instruction. This needs to be corrected.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tbuf_set_u32(x86_32->cache->reg_list[EIP].value, 0, 32, eip-1);\n\t\t\t\t\t\tx86_32->cache->reg_list[EIP].dirty = true;\n\t\t\t\t\t\tx86_32->cache->reg_list[EIP].valid = true;\n\t\t\t\t\t\tLOG_USER(\"hit software breakpoint at 0x%08\" PRIx32, eip-1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* it's not a hardware breakpoint (checked already in DR6 state)\n\t\t\t\t\t\t * and it's also not a software breakpoint ...\n\t\t\t\t\t\t */\n\t\t\t\t\t\tLOG_USER(\"hit unknown breakpoint at 0x%08\" PRIx32, eip);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\n\t\t\t\t\t/* There is also the case that we hit an breakpoint instruction,\n\t\t\t\t\t * which was not set by us. This needs to be handled be the\n\t\t\t\t\t * application that introduced the breakpoint.\n\t\t\t\t\t */\n\n\t\t\t\t\tLOG_USER(\"unknown break reason at 0x%08\" PRIx32, eip);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn target_call_event_callbacks(t, TARGET_EVENT_HALTED);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint lakemont_arch_state(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tLOG_USER(\"target halted due to %s at 0x%08\" PRIx32 \" in %s mode\",\n\t\t\tdebug_reason_name(t),\n\t\t\tbuf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32),\n\t\t\t(buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32) & CR0_PE) ? \"protected\" : \"real\");\n\n\treturn ERROR_OK;\n}\n\nint lakemont_halt(struct target *t)\n{\n\tif (t->state == TARGET_RUNNING) {\n\t\tt->debug_reason = DBG_REASON_DBGRQ;\n\t\tif (do_halt(t) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\treturn ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"%s target not running\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nint lakemont_resume(struct target *t, int current, target_addr_t address,\n\t\t\tint handle_breakpoints, int debug_execution)\n{\n\tstruct breakpoint *bp = NULL;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t/* TODO lakemont_enable_breakpoints(t); */\n\tif (t->state == TARGET_HALTED) {\n\n\t\t/* running away for a software breakpoint needs some special handling */\n\t\tuint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);\n\t\tbp = breakpoint_find(t, eip);\n\t\tif (bp /*&& bp->type == BKPT_SOFT*/) {\n\t\t\t/* the step will step over the breakpoint */\n\t\t\tif (lakemont_step(t, 0, 0, 1) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s stepping over a software breakpoint at 0x%08\" PRIx32 \" \"\n\t\t\t\t\t\t\"failed to resume the target\", __func__, eip);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\t/* if breakpoints are enabled, we need to redirect these into probe mode */\n\t\tstruct breakpoint *activeswbp = t->breakpoints;\n\t\twhile (activeswbp && !activeswbp->is_set)\n\t\t\tactiveswbp = activeswbp->next;\n\t\tstruct watchpoint *activehwbp = t->watchpoints;\n\t\twhile (activehwbp && !activehwbp->is_set)\n\t\t\tactivehwbp = activehwbp->next;\n\t\tif (activeswbp || activehwbp)\n\t\t\tbuf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1);\n\t\tif (do_resume(t) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_USER(\"target not halted\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nint lakemont_step(struct target *t, int current,\n\t\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tuint32_t eflags = buf_get_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32);\n\tuint32_t eip = buf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32);\n\tuint32_t pmcr = buf_get_u32(x86_32->cache->reg_list[PMCR].value, 0, 32);\n\tstruct breakpoint *bp = NULL;\n\tint retval = ERROR_OK;\n\tuint32_t tapstatus = 0;\n\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tbp = breakpoint_find(t, eip);\n\tif (retval == ERROR_OK && bp/*&& bp->type == BKPT_SOFT*/) {\n\t\t/* TODO: This should only be done for software breakpoints.\n\t\t * Stepping from hardware breakpoints should be possible with the resume flag\n\t\t * Needs testing.\n\t\t */\n\t\tretval = x86_32_common_remove_breakpoint(t, bp);\n\t}\n\n\t/* Set EFLAGS[TF] and PMCR[IR], exit pm and wait for PRDY# */\n\tLOG_DEBUG(\"modifying PMCR = 0x%08\" PRIx32 \" and EFLAGS = 0x%08\" PRIx32, pmcr, eflags);\n\teflags = eflags | (EFLAGS_TF | EFLAGS_RF);\n\tbuf_set_u32(x86_32->cache->reg_list[EFLAGS].value, 0, 32, eflags);\n\tbuf_set_u32(x86_32->cache->reg_list[PMCR].value, 0, 32, 1);\n\tLOG_DEBUG(\"EFLAGS [TF] [RF] bits set=0x%08\" PRIx32 \", PMCR=0x%08\" PRIx32 \", EIP=0x%08\" PRIx32,\n\t\t\teflags, pmcr, eip);\n\n\t/* Returned value unused. Can this line be removed? */\n\tget_tapstatus(t);\n\n\tt->debug_reason = DBG_REASON_SINGLESTEP;\n\tt->state = TARGET_DEBUG_RUNNING;\n\tif (restore_context(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (exit_probemode(t) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttarget_call_event_callbacks(t, TARGET_EVENT_RESUMED);\n\n\ttapstatus = get_tapstatus(t);\n\tif (tapstatus & (TS_PM_BIT | TS_EN_PM_BIT | TS_PRDY_BIT | TS_PMCR_BIT)) {\n\t\t/* target has stopped */\n\t\tif (save_context(t) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (halt_prep(t) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tt->state = TARGET_HALTED;\n\n\t\tLOG_USER(\"step done from EIP 0x%08\" PRIx32 \" to 0x%08\" PRIx32, eip,\n\t\t\t\tbuf_get_u32(x86_32->cache->reg_list[EIP].value, 0, 32));\n\t\ttarget_call_event_callbacks(t, TARGET_EVENT_HALTED);\n\t} else {\n\t\t/* target didn't stop\n\t\t * I hope the poll() will catch it, but the deleted breakpoint is gone\n\t\t */\n\t\tLOG_ERROR(\"%s target didn't stop after executing a single step\", __func__);\n\t\tt->state = TARGET_RUNNING;\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* try to re-apply the breakpoint, even of step failed\n\t * TODO: When a bp was set, we should try to stop the target - fix the return above\n\t */\n\tif (bp/*&& bp->type == BKPT_SOFT*/) {\n\t\t/* TODO: This should only be done for software breakpoints.\n\t\t * Stepping from hardware breakpoints should be possible with the resume flag\n\t\t * Needs testing.\n\t\t */\n\t\tretval = x86_32_common_add_breakpoint(t, bp);\n\t}\n\n\treturn retval;\n}\n\nstatic int lakemont_reset_break(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct jtag_tap *saved_tap = x86_32->curr_tap;\n\tstruct scan_field *fields = &scan.field;\n\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"issuing port 0xcf9 reset\");\n\n\t/* prepare resetbreak setting the proper bits in CLTAPC_CPU_VPREQ */\n\tx86_32->curr_tap = jtag_tap_by_position(1);\n\tif (!x86_32->curr_tap) {\n\t\tx86_32->curr_tap = saved_tap;\n\t\tLOG_ERROR(\"%s could not select quark_x10xx.cltap\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfields->in_value  = NULL;\n\tfields->num_bits  = 8;\n\n\t/* select CLTAPC_CPU_VPREQ instruction*/\n\tscan.out[0] = 0x51;\n\tfields->out_value = ((uint8_t *)scan.out);\n\tjtag_add_ir_scan(x86_32->curr_tap, fields, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tx86_32->curr_tap = saved_tap;\n\t\tLOG_ERROR(\"%s irscan failed to execute queue\", __func__);\n\t\treturn retval;\n\t}\n\n\t/* set enable_preq_on_reset & enable_preq_on_reset2 bits*/\n\tscan.out[0] = 0x06;\n\tfields->out_value  = ((uint8_t *)scan.out);\n\tjtag_add_dr_scan(x86_32->curr_tap, 1, fields, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s drscan failed to execute queue\", __func__);\n\t\tx86_32->curr_tap = saved_tap;\n\t\treturn retval;\n\t}\n\n\t/* restore current tap */\n\tx86_32->curr_tap = saved_tap;\n\n\treturn ERROR_OK;\n}\n\n/*\n * If we ever get an adapter with support for PREQ# and PRDY#, we should\n * update this function to add support for using those two signals.\n *\n * Meanwhile, we're assuming that we only support reset break.\n */\nint lakemont_reset_assert(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\t/* write 0x6 to I/O port 0xcf9 to cause the reset */\n\tuint8_t cf9_reset_val = 0x6;\n\tint retval;\n\n\tLOG_DEBUG(\" \");\n\n\tif (t->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target must be halted first\");\n\t\tretval = lakemont_halt(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not halt target\");\n\t\t\treturn retval;\n\t\t}\n\t\tx86_32->forced_halt_for_reset = true;\n\t}\n\n\tif (t->reset_halt) {\n\t\tretval = lakemont_reset_break(t);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = x86_32_common_write_io(t, 0xcf9, BYTE, &cf9_reset_val);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"could not write to port 0xcf9\");\n\t\treturn retval;\n\t}\n\n\tif (!t->reset_halt && x86_32->forced_halt_for_reset) {\n\t\tx86_32->forced_halt_for_reset = false;\n\t\tretval = lakemont_resume(t, true, 0x00, false, true);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* remove breakpoints and watchpoints */\n\tx86_32_common_reset_breakpoints_watchpoints(t);\n\n\treturn ERROR_OK;\n}\n\nint lakemont_reset_deassert(struct target *t)\n{\n\tint retval;\n\n\tLOG_DEBUG(\" \");\n\n\tif (target_was_examined(t)) {\n\t\tretval = lakemont_poll(t);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (t->reset_halt) {\n\t\t/* entered PM after reset, update the state */\n\t\tretval = lakemont_update_after_probemode_entry(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"could not update state after probemode entry\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tif (t->state != TARGET_HALTED) {\n\t\t\tLOG_WARNING(\"%s: ran after reset and before halt ...\",\n\t\t\t\ttarget_name(t));\n\t\t\tif (target_was_examined(t)) {\n\t\t\t\tretval = target_halt(t);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else {\n\t\t\t\tt->state = TARGET_UNKNOWN;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/lakemont.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright(c) 2013-2016 Intel Corporation.\n *\n * Adrian Burns (adrian.burns@intel.com)\n * Thomas Faust (thomas.faust@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n * Julien Carreno (julien.carreno@intel.com)\n * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * This is the interface to the probemode operations for Lakemont 1 (LMT1).\n */\n\n#ifndef OPENOCD_TARGET_LAKEMONT_H\n#define OPENOCD_TARGET_LAKEMONT_H\n\n#include <jtag/jtag.h>\n#include <helper/types.h>\n\n/* The Intel Quark SoC X1000 Core is codenamed lakemont */\n\n#define LMT_IRLEN\t\t8\n\n/* lakemont tap instruction opcodes */\n#define IDCODE\t\t\t2\n#define SUBMITPIR\t\t3\n#define PROBEMODE\t\t4\n#define WRPIR\t\t\t6\n#define RDWRPDR\t\t\t8\n#define TAPSTATUS\t\t11\n#define BYPASS\t\t\t255\n#define NOT_NULL\t\t2\n\n/* DR sizes */\n#define ID_SIZE\t\t\t32\n#define PM_SIZE\t\t\t1\n#define PIR_SIZE\t\t64\n#define PDR_SIZE\t\t32\n#define TS_SIZE\t\t\t32\n#define BP_SIZE\t\t\t1\n#define MAX_SCAN_SIZE\tPIR_SIZE\n\n/* needed during lakemont probemode */\n#define NOT_PMREG\t\t0xfe\n#define NOT_AVAIL_REG\t\t0xff\n#define PM_DSB\t\t\t((uint32_t)0x00000000)\n#define PM_DSL\t\t\t((uint32_t)0xFFFFFFFF)\n#define PM_DSAR\t\t\t((uint32_t)0x004F9300)\n#define PM_DR7\t\t\t((uint32_t)0x00000400)\n#define DELAY_SUBMITPIR\t\t0 /* for now 0 is working */\n\n/* lakemont tapstatus bits */\n#define TS_PRDY_BIT\t\t((uint32_t)0x00000001)\n#define TS_EN_PM_BIT\t\t((uint32_t)0x00000002)\n#define TS_PM_BIT\t\t((uint32_t)0x00000004)\n#define TS_PMCR_BIT\t\t((uint32_t)0x00000008)\n#define TS_SBP_BIT\t\t((uint32_t)0x00000010)\n\nstruct lakemont_core_reg {\n\tuint32_t num;\n\tstruct target *target;\n\tstruct x86_32_common *x86_32_common;\n\tuint64_t op;\n\tuint8_t pm_idx;\n};\n\nstruct scan_blk {\n\tuint8_t out[MAX_SCAN_SIZE]; /* scanned out to the tap */\n\tuint8_t in[MAX_SCAN_SIZE]; /* in to our capture buf */\n\tstruct scan_field field;\n};\n\n#define I(name) (((struct lakemont_core_reg *)x86_32->cache->reg_list[name].arch_info)->pm_idx)\n\nint lakemont_init_target(struct command_context *cmd_ctx, struct target *t);\nint lakemont_init_arch_info(struct target *t, struct x86_32_common *x86_32);\nint lakemont_poll(struct target *t);\nint lakemont_arch_state(struct target *t);\nint lakemont_halt(struct target *t);\nint lakemont_resume(struct target *t, int current, target_addr_t address,\n\t\t\tint handle_breakpoints, int debug_execution);\nint lakemont_step(struct target *t, int current,\n\t\t\ttarget_addr_t address, int handle_breakpoints);\nint lakemont_reset_assert(struct target *t);\nint lakemont_reset_deassert(struct target *t);\nint lakemont_update_after_probemode_entry(struct target *t);\n\n#endif /* OPENOCD_TARGET_LAKEMONT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/ls1_sap.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2015 by Esben Haabendal <eha@deif.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"target_type.h\"\n\n#include <jtag/jtag.h>\n\nstruct ls1_sap {\n\tstruct jtag_tap *tap;\n};\n\nstatic int ls1_sap_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct ls1_sap *ls1_sap = calloc(1, sizeof(struct ls1_sap));\n\n\tls1_sap->tap = target->tap;\n\ttarget->arch_info = ls1_sap;\n\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_arch_state(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_poll(struct target *target)\n{\n\tif ((target->state == TARGET_UNKNOWN) ||\n\t    (target->state == TARGET_RUNNING) ||\n\t    (target->state == TARGET_DEBUG_RUNNING))\n\t\ttarget->state = TARGET_HALTED;\n\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_halt(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_step(struct target *target, int current, target_addr_t address,\n\t\t\t\tint handle_breakpoints)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_assert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RESET;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int ls1_sap_deassert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RUNNING;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic void ls1_sap_set_instr(struct jtag_tap *tap, uint32_t new_instr)\n{\n\tstruct scan_field field;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) == new_instr)\n\t\treturn;\n\n\tfield.num_bits = tap->ir_length;\n\tuint8_t *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\tfree(t);\n}\n\nstatic void ls1_sap_set_addr_high(struct jtag_tap *tap, uint16_t addr_high)\n{\n\tstruct scan_field field;\n\tuint8_t buf[2] = { 0 };\n\n\tls1_sap_set_instr(tap, 0x21);\n\n\tfield.num_bits = 16;\n\tfield.out_value = buf;\n\tbuf_set_u32(buf, 0, 16, addr_high);\n\tfield.in_value = NULL;\n\tfield.check_value = NULL;\n\tfield.check_mask = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n}\n\nstatic void ls1_sap_memory_cmd(struct jtag_tap *tap, uint32_t address,\n\t\t\t       int32_t size, bool rnw)\n{\n\tstruct scan_field field;\n\tuint8_t cmd[8] = { 0 };\n\n\tls1_sap_set_instr(tap, 0x24);\n\n\tfield.num_bits = 64;\n\tfield.out_value = cmd;\n\tbuf_set_u64(cmd, 0, 9, 0);\n\tbuf_set_u64(cmd, 9, 3, size);\n\tbuf_set_u64(cmd, 12, 1, rnw);\n\tbuf_set_u64(cmd, 13, 3, 0);\n\tbuf_set_u64(cmd, 16, 32, address);\n\tbuf_set_u64(cmd, 48, 16, 0);\n\tfield.in_value = NULL;\n\tfield.check_value = NULL;\n\tfield.check_mask = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n}\n\nstatic void ls1_sap_memory_read(struct jtag_tap *tap, uint32_t size,\n\t\t\t\tuint8_t *value)\n{\n\tstruct scan_field field;\n\n\tls1_sap_set_instr(tap, 0x25);\n\n\tfield.num_bits = 8 * size;\n\tfield.out_value = NULL;\n\tfield.in_value = value;\n\tfield.check_value = NULL;\n\tfield.check_mask = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n}\n\nstatic void ls1_sap_memory_write(struct jtag_tap *tap, uint32_t size,\n\t\t\t\t const uint8_t *value)\n{\n\tstruct scan_field field;\n\n\tls1_sap_set_instr(tap, 0x25);\n\n\tfield.num_bits = 8 * size;\n\tfield.out_value = value;\n\tfield.in_value = NULL;\n\tfield.check_value = NULL;\n\tfield.check_mask = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n}\n\nstatic int ls1_sap_read_memory(struct target *target, target_addr_t address,\n\t\t\t       uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tLOG_DEBUG(\"Reading memory at physical address 0x%\" TARGET_PRIxADDR\n\t\t  \"; size %\" PRIu32 \"; count %\" PRIu32, address, size, count);\n\n\tif (count == 0 || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tls1_sap_set_addr_high(target->tap, 0);\n\n\twhile (count--) {\n\t\tls1_sap_memory_cmd(target->tap, address, size, true);\n\t\tls1_sap_memory_read(target->tap, size, buffer);\n\t\taddress += size;\n\t\tbuffer += size;\n\t}\n\n\treturn jtag_execute_queue();\n}\n\nstatic int ls1_sap_write_memory(struct target *target, target_addr_t address,\n\t\t\t\tuint32_t size, uint32_t count,\n\t\t\t\tconst uint8_t *buffer)\n{\n\tLOG_DEBUG(\"Writing memory at physical address 0x%\" TARGET_PRIxADDR\n\t\t  \"; size %\" PRIu32 \"; count %\" PRIu32, address, size, count);\n\n\n\tif (count == 0 || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tls1_sap_set_addr_high(target->tap, 0);\n\n\twhile (count--) {\n\t\tls1_sap_memory_cmd(target->tap, address, size, false);\n\t\tls1_sap_memory_write(target->tap, size, buffer);\n\t\taddress += size;\n\t\tbuffer += size;\n\t}\n\n\treturn jtag_execute_queue();\n}\n\nstruct target_type ls1_sap_target = {\n\t.name = \"ls1_sap\",\n\n\t.target_create = ls1_sap_target_create,\n\t.init_target = ls1_sap_init_target,\n\n\t.poll = ls1_sap_poll,\n\t.arch_state = ls1_sap_arch_state,\n\n\t.halt = ls1_sap_halt,\n\t.resume = ls1_sap_resume,\n\t.step = ls1_sap_step,\n\n\t.assert_reset = ls1_sap_assert_reset,\n\t.deassert_reset = ls1_sap_deassert_reset,\n\n\t.read_memory = ls1_sap_read_memory,\n\t.write_memory = ls1_sap_write_memory,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mem_ap.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2016 by Matthias Welwarsky <matthias.welwarsky@sysgo.com>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"arm_adi_v5.h\"\n#include \"register.h\"\n\n#include <jtag/jtag.h>\n\n#define MEM_AP_COMMON_MAGIC 0x4DE4DA50\n\nstruct mem_ap {\n\tint common_magic;\n\tstruct adiv5_dap *dap;\n\tstruct adiv5_ap *ap;\n\tuint64_t ap_num;\n};\n\nstatic int mem_ap_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct mem_ap *mem_ap;\n\tstruct adiv5_private_config *pc;\n\n\tpc = (struct adiv5_private_config *)target->private_config;\n\tif (!pc)\n\t\treturn ERROR_FAIL;\n\n\tif (pc->ap_num == DP_APSEL_INVALID) {\n\t\tLOG_ERROR(\"AP number not specified\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmem_ap = calloc(1, sizeof(struct mem_ap));\n\tif (!mem_ap) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmem_ap->ap_num = pc->ap_num;\n\tmem_ap->common_magic = MEM_AP_COMMON_MAGIC;\n\tmem_ap->dap = pc->dap;\n\n\ttarget->arch_info = mem_ap;\n\n\tif (!target->gdb_port_override)\n\t\ttarget->gdb_port_override = strdup(\"disabled\");\n\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_init_target(struct command_context *cmd_ctx, struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\ttarget->state = TARGET_UNKNOWN;\n\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\treturn ERROR_OK;\n}\n\nstatic void mem_ap_deinit_target(struct target *target)\n{\n\tstruct mem_ap *mem_ap = target->arch_info;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\n\tif (mem_ap->ap)\n\t\tdap_put_ap(mem_ap->ap);\n\n\tfree(target->private_config);\n\tfree(target->arch_info);\n\treturn;\n}\n\nstatic int mem_ap_arch_state(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_poll(struct target *target)\n{\n\tif (target->state == TARGET_UNKNOWN) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_halt(struct target *target)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\ttarget->state = TARGET_HALTED;\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_step(struct target *target, int current, target_addr_t address,\n\t\t\t\tint handle_breakpoints)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\ttarget->state = TARGET_HALTED;\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_assert_reset(struct target *target)\n{\n\ttarget->state = TARGET_RESET;\n\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_examine(struct target *target)\n{\n\tstruct mem_ap *mem_ap = target->arch_info;\n\n\tif (!target_was_examined(target)) {\n\t\tif (!mem_ap->ap) {\n\t\t\tmem_ap->ap = dap_get_ap(mem_ap->dap, mem_ap->ap_num);\n\t\t\tif (!mem_ap->ap) {\n\t\t\t\tLOG_ERROR(\"Cannot get AP\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\ttarget_set_examined(target);\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\t\treturn mem_ap_init(mem_ap->ap);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_deassert_reset(struct target *target)\n{\n\tif (target->reset_halt) {\n\t\ttarget->state = TARGET_HALTED;\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t} else {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t}\n\n\tLOG_DEBUG(\"%s\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_reg_get(struct reg *reg)\n{\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_reg_set(struct reg *reg, uint8_t *buf)\n{\n\treturn ERROR_OK;\n}\n\nstatic struct reg_arch_type mem_ap_reg_arch_type = {\n\t.get = mem_ap_reg_get,\n\t.set = mem_ap_reg_set,\n};\n\nstatic const char *mem_ap_get_gdb_arch(struct target *target)\n{\n\treturn \"arm\";\n}\n\n/*\n * Dummy ARM register emulation:\n * reg[0..15]:  32 bits, r0~r12, sp, lr, pc\n * reg[16..23]: 96 bits, f0~f7\n * reg[24]:     32 bits, fps\n * reg[25]:     32 bits, cpsr\n *\n * Set 'exist' only to reg[0..15], so initial response to GDB is correct\n */\n#define NUM_REGS     26\n#define MAX_REG_SIZE 96\n#define REG_EXIST(n) ((n) < 16)\n#define REG_SIZE(n)  ((((n) >= 16) && ((n) < 24)) ? 96 : 32)\n\nstruct mem_ap_alloc_reg_list {\n\t/* reg_list must be the first field */\n\tstruct reg *reg_list[NUM_REGS];\n\tstruct reg regs[NUM_REGS];\n\tuint8_t regs_value[MAX_REG_SIZE / 8];\n};\n\nstatic int mem_ap_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\t\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n\tstruct mem_ap_alloc_reg_list *mem_ap_alloc = calloc(1, sizeof(struct mem_ap_alloc_reg_list));\n\tif (!mem_ap_alloc) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*reg_list = mem_ap_alloc->reg_list;\n\t*reg_list_size = NUM_REGS;\n\tstruct reg *regs = mem_ap_alloc->regs;\n\n\tfor (int i = 0; i < NUM_REGS; i++) {\n\t\tregs[i].number = i;\n\t\tregs[i].value = mem_ap_alloc->regs_value;\n\t\tregs[i].size = REG_SIZE(i);\n\t\tregs[i].exist = REG_EXIST(i);\n\t\tregs[i].type = &mem_ap_reg_arch_type;\n\t\t(*reg_list)[i] = &regs[i];\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mem_ap_read_memory(struct target *target, target_addr_t address,\n\t\t\t       uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct mem_ap *mem_ap = target->arch_info;\n\n\tLOG_DEBUG(\"Reading memory at physical address \" TARGET_ADDR_FMT\n\t\t  \"; size %\" PRIu32 \"; count %\" PRIu32, address, size, count);\n\n\tif (count == 0 || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn mem_ap_read_buf(mem_ap->ap, buffer, size, count, address);\n}\n\nstatic int mem_ap_write_memory(struct target *target, target_addr_t address,\n\t\t\t\tuint32_t size, uint32_t count,\n\t\t\t\tconst uint8_t *buffer)\n{\n\tstruct mem_ap *mem_ap = target->arch_info;\n\n\tLOG_DEBUG(\"Writing memory at physical address \" TARGET_ADDR_FMT\n\t\t  \"; size %\" PRIu32 \"; count %\" PRIu32, address, size, count);\n\n\tif (count == 0 || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn mem_ap_write_buf(mem_ap->ap, buffer, size, count, address);\n}\n\nstruct target_type mem_ap_target = {\n\t.name = \"mem_ap\",\n\n\t.target_create = mem_ap_target_create,\n\t.init_target = mem_ap_init_target,\n\t.deinit_target = mem_ap_deinit_target,\n\t.examine = mem_ap_examine,\n\t.target_jim_configure = adiv5_jim_configure,\n\n\t.poll = mem_ap_poll,\n\t.arch_state = mem_ap_arch_state,\n\n\t.halt = mem_ap_halt,\n\t.resume = mem_ap_resume,\n\t.step = mem_ap_step,\n\n\t.assert_reset = mem_ap_assert_reset,\n\t.deassert_reset = mem_ap_deassert_reset,\n\n\t.get_gdb_arch = mem_ap_get_gdb_arch,\n\t.get_gdb_reg_list = mem_ap_get_gdb_reg_list,\n\n\t.read_memory = mem_ap_read_memory,\n\t.write_memory = mem_ap_write_memory,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mips32.h\"\n#include \"breakpoints.h\"\n#include \"algorithm.h\"\n#include \"register.h\"\n\nstatic const char *mips_isa_strings[] = {\n\t\"MIPS32\", \"MIPS16\", \"\", \"MICRO MIPS32\",\n};\n\n#define MIPS32_GDB_DUMMY_FP_REG 1\n\n/*\n * GDB registers\n * based on gdb-7.6.2/gdb/features/mips-{fpu,cp0,cpu}.xml\n */\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n\tint flag;\n} mips32_regs[] = {\n\t{  0,  \"r0\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  1,  \"r1\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  2,  \"r2\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  3,  \"r3\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  4,  \"r4\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  5,  \"r5\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  6,  \"r6\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  7,  \"r7\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  8,  \"r8\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  9,  \"r9\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 10, \"r10\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 11, \"r11\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 12, \"r12\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 13, \"r13\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 14, \"r14\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 15, \"r15\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 16, \"r16\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 17, \"r17\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 18, \"r18\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 19, \"r19\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 20, \"r20\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 21, \"r21\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 22, \"r22\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 23, \"r23\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 24, \"r24\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 25, \"r25\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 26, \"r26\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 27, \"r27\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 28, \"r28\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 29, \"r29\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 30, \"r30\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 31, \"r31\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 32, \"status\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cp0\", 0 },\n\t{ 33, \"lo\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 34, \"hi\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 35, \"badvaddr\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cp0\", 0 },\n\t{ 36, \"cause\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cp0\", 0 },\n\t{ 37, \"pc\", REG_TYPE_INT, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\n\t{ 38,  \"f0\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 39,  \"f1\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 40,  \"f2\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 41,  \"f3\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 42,  \"f4\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 43,  \"f5\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 44,  \"f6\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 45,  \"f7\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 46,  \"f8\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 47,  \"f9\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 48, \"f10\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 49, \"f11\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 50, \"f12\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 51, \"f13\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 52, \"f14\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 53, \"f15\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 54, \"f16\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 55, \"f17\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 56, \"f18\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 57, \"f19\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 58, \"f20\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 59, \"f21\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 60, \"f22\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 61, \"f23\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 62, \"f24\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 63, \"f25\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 64, \"f26\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 65, \"f27\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 66, \"f28\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 67, \"f29\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 68, \"f30\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 69, \"f31\", REG_TYPE_IEEE_SINGLE, NULL,\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 70, \"fcsr\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n\t{ 71, \"fir\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", MIPS32_GDB_DUMMY_FP_REG },\n};\n\n\n#define MIPS32_NUM_REGS ARRAY_SIZE(mips32_regs)\n\nstatic uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};\n\nstatic int mips32_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct mips32_core_reg *mips32_reg = reg->arch_info;\n\tstruct target *target = mips32_reg->target;\n\tstruct mips32_common *mips32_target = target_to_mips32(target);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = mips32_target->read_core_reg(target, mips32_reg->num);\n\n\treturn retval;\n}\n\nstatic int mips32_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct mips32_core_reg *mips32_reg = reg->arch_info;\n\tstruct target *target = mips32_reg->target;\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u32(reg->value, 0, 32, value);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_read_core_reg(struct target *target, unsigned int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (num >= MIPS32_NUM_REGS)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = mips32->core_regs[num];\n\tbuf_set_u32(mips32->core_cache->reg_list[num].value, 0, 32, reg_value);\n\tmips32->core_cache->reg_list[num].valid = true;\n\tmips32->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_write_core_reg(struct target *target, unsigned int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (num >= MIPS32_NUM_REGS)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = buf_get_u32(mips32->core_cache->reg_list[num].value, 0, 32);\n\tmips32->core_regs[num] = reg_value;\n\tLOG_DEBUG(\"write core reg %i value 0x%\" PRIx32 \"\", num, reg_value);\n\tmips32->core_cache->reg_list[num].valid = true;\n\tmips32->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nint mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tunsigned int i;\n\n\t/* include floating point registers */\n\t*reg_list_size = MIPS32_NUM_REGS;\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\tfor (i = 0; i < MIPS32_NUM_REGS; i++)\n\t\t(*reg_list)[i] = &mips32->core_cache->reg_list[i];\n\n\treturn ERROR_OK;\n}\n\nint mips32_save_context(struct target *target)\n{\n\tunsigned int i;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\t/* read core registers */\n\tmips32_pracc_read_regs(ejtag_info, mips32->core_regs);\n\n\tfor (i = 0; i < MIPS32_NUM_REGS; i++) {\n\t\tif (!mips32->core_cache->reg_list[i].valid)\n\t\t\tmips32->read_core_reg(target, i);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint mips32_restore_context(struct target *target)\n{\n\tunsigned int i;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tfor (i = 0; i < MIPS32_NUM_REGS; i++) {\n\t\tif (mips32->core_cache->reg_list[i].dirty)\n\t\t\tmips32->write_core_reg(target, i);\n\t}\n\n\t/* write core regs */\n\tmips32_pracc_write_regs(ejtag_info, mips32->core_regs);\n\n\treturn ERROR_OK;\n}\n\nint mips32_arch_state(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tLOG_USER(\"target halted in %s mode due to %s, pc: 0x%8.8\" PRIx32 \"\",\n\t\tmips_isa_strings[mips32->isa_mode],\n\t\tdebug_reason_name(target),\n\t\tbuf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type mips32_reg_type = {\n\t.get = mips32_get_core_reg,\n\t.set = mips32_set_core_reg,\n};\n\nstruct reg_cache *mips32_build_reg_cache(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tint num_regs = MIPS32_NUM_REGS;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct mips32_core_reg *arch_info = malloc(sizeof(struct mips32_core_reg) * num_regs);\n\tstruct reg_feature *feature;\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"mips32 registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\t(*cache_p) = cache;\n\tmips32->core_cache = cache;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i].num = mips32_regs[i].id;\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].mips32_common = mips32;\n\n\t\treg_list[i].name = mips32_regs[i].name;\n\t\treg_list[i].size = 32;\n\n\t\tif (mips32_regs[i].flag == MIPS32_GDB_DUMMY_FP_REG) {\n\t\t\treg_list[i].value = mips32_gdb_dummy_fp_value;\n\t\t\treg_list[i].valid = true;\n\t\t\treg_list[i].arch_info = NULL;\n\t\t\tregister_init_dummy(&reg_list[i]);\n\t\t} else {\n\t\t\treg_list[i].value = calloc(1, 4);\n\t\t\treg_list[i].valid = false;\n\t\t\treg_list[i].type = &mips32_reg_type;\n\t\t\treg_list[i].arch_info = &arch_info[i];\n\n\t\t\treg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\t\tif (reg_list[i].reg_data_type)\n\t\t\t\treg_list[i].reg_data_type->type = mips32_regs[i].type;\n\t\t\telse\n\t\t\t\tLOG_ERROR(\"unable to allocate reg type list\");\n\t\t}\n\n\t\treg_list[i].dirty = false;\n\n\t\treg_list[i].group = mips32_regs[i].group;\n\t\treg_list[i].number = i;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].caller_save = true;\t/* gdb defaults to true */\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = mips32_regs[i].feature;\n\t\t\treg_list[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate feature list\");\n\t}\n\n\treturn cache;\n}\n\nint mips32_init_arch_info(struct target *target, struct mips32_common *mips32, struct jtag_tap *tap)\n{\n\ttarget->arch_info = mips32;\n\tmips32->common_magic = MIPS32_COMMON_MAGIC;\n\tmips32->fast_data_area = NULL;\n\tmips32->isa_imp = MIPS32_ONLY;\t/* default */\n\n\t/* has breakpoint/watchpoint unit been scanned */\n\tmips32->bp_scanned = 0;\n\tmips32->data_break_list = NULL;\n\n\tmips32->ejtag_info.tap = tap;\n\tmips32->read_core_reg = mips32_read_core_reg;\n\tmips32->write_core_reg = mips32_write_core_reg;\n\t/* if unknown endianness defaults to little endian, 1 */\n\tmips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1;\n\tmips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE;\n\tmips32->ejtag_info.mode = 0;\t\t\t/* Initial default value */\n\tmips32->ejtag_info.isa = 0;\t/* isa on debug mips32, updated by poll function */\n\tmips32->ejtag_info.config_regs = 0;\t/* no config register read */\n\treturn ERROR_OK;\n}\n\n/* run to exit point. return error if exit point was not reached. */\nstatic int mips32_run_and_wait(struct target *target, target_addr_t entry_point,\n\t\tunsigned int timeout_ms, target_addr_t exit_point, struct mips32_common *mips32)\n{\n\tuint32_t pc;\n\tint retval;\n\t/* This code relies on the target specific  resume() and  poll()->debug_entry()\n\t * sequence to write register values to the processor and the read them back */\n\tretval = target_resume(target, 0, entry_point, 0, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_wait_state(target, TARGET_HALTED, timeout_ms);\n\t/* If the target fails to halt due to the breakpoint, force a halt */\n\tif (retval != ERROR_OK || target->state != TARGET_HALTED) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_wait_state(target, TARGET_HALTED, 500);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\tpc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);\n\tif (exit_point && (pc != exit_point)) {\n\t\tLOG_DEBUG(\"failed algorithm halted at 0x%\" PRIx32 \" \", pc);\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint mips32_run_algorithm(struct target *target, int num_mem_params,\n\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\tstruct reg_param *reg_params, target_addr_t entry_point,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms, void *arch_info)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips32_algorithm *mips32_algorithm_info = arch_info;\n\tenum mips32_isa_mode isa_mode = mips32->isa_mode;\n\n\tuint32_t context[MIPS32_NUM_REGS];\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"Running algorithm\");\n\n\t/* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint\n\t * at the exit point */\n\n\tif (mips32->common_magic != MIPS32_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"current target isn't a MIPS32 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* refresh core register cache */\n\tfor (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {\n\t\tif (!mips32->core_cache->reg_list[i].valid)\n\t\t\tmips32->read_core_reg(target, i);\n\t\tcontext[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);\n\t}\n\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\t\tretval = target_write_buffer(target, mem_params[i].address,\n\t\t\t\tmem_params[i].size, mem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\n\t\tstruct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);\n\n\t\tif (!reg) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (reg->size != reg_params[i].size) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\treg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tmips32_set_core_reg(reg, reg_params[i].value);\n\t}\n\n\tmips32->isa_mode = mips32_algorithm_info->isa_mode;\n\n\tretval = mips32_run_and_wait(target, entry_point, timeout_ms, exit_point, mips32);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction != PARAM_OUT) {\n\t\t\tretval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,\n\t\t\t\t\tmem_params[i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction != PARAM_OUT) {\n\t\t\tstruct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, false);\n\t\t\tif (!reg) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tif (reg->size != reg_params[i].size) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tbuf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));\n\t\t}\n\t}\n\n\t/* restore everything we saved before */\n\tfor (unsigned int i = 0; i < MIPS32_NUM_REGS; i++) {\n\t\tuint32_t regvalue;\n\t\tregvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);\n\t\tif (regvalue != context[i]) {\n\t\t\tLOG_DEBUG(\"restoring register %s with value 0x%8.8\" PRIx32,\n\t\t\t\tmips32->core_cache->reg_list[i].name, context[i]);\n\t\t\tbuf_set_u32(mips32->core_cache->reg_list[i].value,\n\t\t\t\t\t0, 32, context[i]);\n\t\t\tmips32->core_cache->reg_list[i].valid = true;\n\t\t\tmips32->core_cache->reg_list[i].dirty = true;\n\t\t}\n\t}\n\n\tmips32->isa_mode = isa_mode;\n\n\treturn ERROR_OK;\n}\n\nint mips32_examine(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (!target_was_examined(target)) {\n\t\ttarget_set_examined(target);\n\n\t\t/* we will configure later */\n\t\tmips32->bp_scanned = 0;\n\t\tmips32->num_inst_bpoints = 0;\n\t\tmips32->num_data_bpoints = 0;\n\t\tmips32->num_inst_bpoints_avail = 0;\n\t\tmips32->num_data_bpoints_avail = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_configure_ibs(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tint retval, i;\n\tuint32_t bpinfo;\n\n\t/* get number of inst breakpoints */\n\tretval = target_read_u32(target, ejtag_info->ejtag_ibs_addr, &bpinfo);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;\n\tmips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;\n\tmips32->inst_break_list = calloc(mips32->num_inst_bpoints,\n\t\tsizeof(struct mips32_comparator));\n\n\tfor (i = 0; i < mips32->num_inst_bpoints; i++)\n\t\tmips32->inst_break_list[i].reg_address =\n\t\t\tejtag_info->ejtag_iba0_addr +\n\t\t\t(ejtag_info->ejtag_iba_step_size * i);\n\n\t/* clear IBIS reg */\n\tretval = target_write_u32(target, ejtag_info->ejtag_ibs_addr, 0);\n\treturn retval;\n}\n\nstatic int mips32_configure_dbs(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tint retval, i;\n\tuint32_t bpinfo;\n\n\t/* get number of data breakpoints */\n\tretval = target_read_u32(target, ejtag_info->ejtag_dbs_addr, &bpinfo);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;\n\tmips32->num_data_bpoints_avail = mips32->num_data_bpoints;\n\tmips32->data_break_list = calloc(mips32->num_data_bpoints,\n\t\tsizeof(struct mips32_comparator));\n\n\tfor (i = 0; i < mips32->num_data_bpoints; i++)\n\t\tmips32->data_break_list[i].reg_address =\n\t\t\tejtag_info->ejtag_dba0_addr +\n\t\t\t(ejtag_info->ejtag_dba_step_size * i);\n\n\t/* clear DBIS reg */\n\tretval = target_write_u32(target, ejtag_info->ejtag_dbs_addr, 0);\n\treturn retval;\n}\n\nint mips32_configure_break_unit(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tint retval;\n\tuint32_t dcr;\n\n\tif (mips32->bp_scanned)\n\t\treturn ERROR_OK;\n\n\t/* get info about breakpoint support */\n\tretval = target_read_u32(target, EJTAG_DCR, &dcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* EJTAG 2.0 defines IB and DB bits in IMP instead of DCR. */\n\tif (ejtag_info->ejtag_version == EJTAG_VERSION_20) {\n\t\tejtag_info->debug_caps = dcr & EJTAG_DCR_ENM;\n\t\tif (!(ejtag_info->impcode & EJTAG_V20_IMP_NOIB))\n\t\t\tejtag_info->debug_caps |= EJTAG_DCR_IB;\n\t\tif (!(ejtag_info->impcode & EJTAG_V20_IMP_NODB))\n\t\t\tejtag_info->debug_caps |= EJTAG_DCR_DB;\n\t} else\n\t\t/* keep  debug caps for later use */\n\t\tejtag_info->debug_caps = dcr & (EJTAG_DCR_ENM\n\t\t\t\t| EJTAG_DCR_IB | EJTAG_DCR_DB);\n\n\n\tif (ejtag_info->debug_caps & EJTAG_DCR_IB) {\n\t\tretval = mips32_configure_ibs(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (ejtag_info->debug_caps & EJTAG_DCR_DB) {\n\t\tretval = mips32_configure_dbs(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* check if target endianness settings matches debug control register */\n\tif (((ejtag_info->debug_caps & EJTAG_DCR_ENM)\n\t\t\t&& (target->endianness == TARGET_LITTLE_ENDIAN)) ||\n\t\t\t(!(ejtag_info->debug_caps & EJTAG_DCR_ENM)\n\t\t\t && (target->endianness == TARGET_BIG_ENDIAN)))\n\t\tLOG_WARNING(\"DCR endianness settings does not match target settings\");\n\n\tLOG_DEBUG(\"DCR 0x%\" PRIx32 \" numinst %i numdata %i\", dcr, mips32->num_inst_bpoints,\n\t\t\tmips32->num_data_bpoints);\n\n\tmips32->bp_scanned = 1;\n\n\treturn ERROR_OK;\n}\n\nint mips32_enable_interrupts(struct target *target, int enable)\n{\n\tint retval;\n\tint update = 0;\n\tuint32_t dcr;\n\n\t/* read debug control register */\n\tretval = target_read_u32(target, EJTAG_DCR, &dcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (enable) {\n\t\tif (!(dcr & EJTAG_DCR_INTE)) {\n\t\t\t/* enable interrupts */\n\t\t\tdcr |= EJTAG_DCR_INTE;\n\t\t\tupdate = 1;\n\t\t}\n\t} else {\n\t\tif (dcr & EJTAG_DCR_INTE) {\n\t\t\t/* disable interrupts */\n\t\t\tdcr &= ~EJTAG_DCR_INTE;\n\t\t\tupdate = 1;\n\t\t}\n\t}\n\n\tif (update) {\n\t\tretval = target_write_u32(target, EJTAG_DCR, dcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* read config to config3 cp0 registers and log isa implementation */\nint mips32_read_config_regs(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tif (ejtag_info->config_regs == 0)\n\t\tfor (int i = 0; i != 4; i++) {\n\t\t\tint retval = mips32_cp0_read(ejtag_info, &ejtag_info->config[i], 16, i);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"isa info not available, failed to read cp0 config register: %\" PRId32, i);\n\t\t\t\tejtag_info->config_regs = 0;\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t\tejtag_info->config_regs = i + 1;\n\t\t\tif ((ejtag_info->config[i] & (1 << 31)) == 0)\n\t\t\t\tbreak;\t/* no more config registers implemented */\n\t\t}\n\telse\n\t\treturn ERROR_OK;\t/* already successfully read */\n\n\tLOG_DEBUG(\"read  %\"PRIu32\" config registers\", ejtag_info->config_regs);\n\n\tif (ejtag_info->impcode & EJTAG_IMP_MIPS16) {\n\t\tmips32->isa_imp = MIPS32_MIPS16;\n\t\tLOG_USER(\"MIPS32 with MIPS16 support implemented\");\n\n\t} else if (ejtag_info->config_regs >= 4) {\t/* config3 implemented */\n\t\tunsigned isa_imp = (ejtag_info->config[3] & MIPS32_CONFIG3_ISA_MASK) >> MIPS32_CONFIG3_ISA_SHIFT;\n\t\tif (isa_imp == 1) {\n\t\t\tmips32->isa_imp = MMIPS32_ONLY;\n\t\t\tLOG_USER(\"MICRO MIPS32 only implemented\");\n\n\t\t} else if (isa_imp != 0) {\n\t\t\tmips32->isa_imp = MIPS32_MMIPS32;\n\t\t\tLOG_USER(\"MIPS32 and MICRO MIPS32 implemented\");\n\t\t}\n\t}\n\n\tif (mips32->isa_imp == MIPS32_ONLY)\t/* initial default value */\n\t\tLOG_USER(\"MIPS32 only implemented\");\n\n\treturn ERROR_OK;\n}\nint mips32_checksum_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint32_t *checksum)\n{\n\tstruct working_area *crc_algorithm;\n\tstruct reg_param reg_params[2];\n\tstruct mips32_algorithm mips32_info;\n\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\t/* see contrib/loaders/checksum/mips32.s for src */\n\tuint32_t isa = ejtag_info->isa ? 1 : 0;\n\n\tuint32_t mips_crc_code[] = {\n\t\tMIPS32_ADDIU(isa, 12, 4, 0),\t\t\t/* addiu\t$t4, $a0, 0 */\n\t\tMIPS32_ADDIU(isa, 10, 5, 0),\t\t\t/* addiu\t$t2, $a1, 0 */\n\t\tMIPS32_ADDIU(isa, 4, 0, 0xFFFF),\t\t/* addiu\t$a0, $zero, 0xffff */\n\t\tMIPS32_BEQ(isa, 0, 0, 0x10 << isa),\t\t/* beq\t\t$zero, $zero, ncomp */\n\t\tMIPS32_ADDIU(isa, 11, 0, 0),\t\t\t/* addiu\t$t3, $zero, 0 */\n\t\t\t\t\t\t/* nbyte: */\n\t\tMIPS32_LB(isa, 5, 0, 12),\t\t\t/* lb\t\t$a1, ($t4) */\n\t\tMIPS32_ADDI(isa, 12, 12, 1),\t\t\t/* addi\t\t$t4, $t4, 1 */\n\t\tMIPS32_SLL(isa, 5, 5, 24),\t\t\t/* sll\t\t$a1, $a1, 24 */\n\t\tMIPS32_LUI(isa, 2, 0x04c1),\t\t\t/* lui\t\t$v0, 0x04c1 */\n\t\tMIPS32_XOR(isa, 4, 4, 5),\t\t\t/* xor\t\t$a0, $a0, $a1 */\n\t\tMIPS32_ORI(isa, 7, 2, 0x1db7),\t\t\t/* ori\t\t$a3, $v0, 0x1db7 */\n\t\tMIPS32_ADDU(isa, 6, 0, 0),\t\t\t/* addu\t\t$a2, $zero, $zero */\n\t\t\t\t\t\t/* loop */\n\t\tMIPS32_SLL(isa, 8, 4, 1),\t\t\t/* sll\t\t$t0, $a0, 1 */\n\t\tMIPS32_ADDIU(isa, 6, 6, 1),\t\t\t/* addiu\t$a2, $a2, 1 */\n\t\tMIPS32_SLTI(isa, 4, 4, 0),\t\t\t/* slti\t\t$a0, $a0, 0 */\n\t\tMIPS32_XOR(isa, 9, 8, 7),\t\t\t/* xor\t\t$t1, $t0, $a3 */\n\t\tMIPS32_MOVN(isa, 8, 9, 4),\t\t\t/* movn\t\t$t0, $t1, $a0 */\n\t\tMIPS32_SLTI(isa, 3, 6, 8),\t\t\t/* slti\t\t$v1, $a2, 8 */\n\t\tMIPS32_BNE(isa, 3, 0, NEG16(7 << isa)),\t\t/* bne\t\t$v1, $zero, loop */\n\t\tMIPS32_ADDU(isa, 4, 8, 0),\t\t\t/* addu\t\t$a0, $t0, $zero */\n\t\t\t\t\t\t/* ncomp */\n\t\tMIPS32_BNE(isa, 10, 11, NEG16(16 << isa)),\t/* bne\t\t$t2, $t3, nbyte */\n\t\tMIPS32_ADDIU(isa, 11, 11, 1),\t\t\t/* addiu\t$t3, $t3, 1 */\n\t\tMIPS32_SDBBP(isa),\n\t};\n\n\t/* make sure we have a working area */\n\tif (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tpracc_swap16_array(ejtag_info, mips_crc_code, ARRAY_SIZE(mips_crc_code));\n\n\t/* convert mips crc code into a buffer in target endianness */\n\tuint8_t mips_crc_code_8[sizeof(mips_crc_code)];\n\ttarget_buffer_set_u32_array(target, mips_crc_code_8,\n\t\t\t\t\tARRAY_SIZE(mips_crc_code), mips_crc_code);\n\n\tint retval = target_write_buffer(target, crc_algorithm->address, sizeof(mips_crc_code), mips_crc_code_8);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips32_info.common_magic = MIPS32_COMMON_MAGIC;\n\tmips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;\t/* run isa as in debug mode */\n\n\tinit_reg_param(&reg_params[0], \"r4\", 32, PARAM_IN_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, address);\n\n\tinit_reg_param(&reg_params[1], \"r5\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, count);\n\n\tunsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));\n\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,\n\t\t\t\t      crc_algorithm->address + (sizeof(mips_crc_code) - 4), timeout, &mips32_info);\n\n\tif (retval == ERROR_OK)\n\t\t*checksum = buf_get_u32(reg_params[0].value, 0, 32);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\ttarget_free_working_area(target, crc_algorithm);\n\n\treturn retval;\n}\n\n/** Checks whether a memory region is erased. */\nint mips32_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks,\n\t\tuint8_t erased_value)\n{\n\tstruct working_area *erase_check_algorithm;\n\tstruct reg_param reg_params[3];\n\tstruct mips32_algorithm mips32_info;\n\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tif (erased_value != 0xff) {\n\t\tLOG_ERROR(\"Erase value 0x%02\" PRIx8 \" not yet supported for MIPS32\",\n\t\t\terased_value);\n\t\treturn ERROR_FAIL;\n\t}\n\tuint32_t isa = ejtag_info->isa ? 1 : 0;\n\tuint32_t erase_check_code[] = {\n\t\t\t\t\t\t/* nbyte: */\n\t\tMIPS32_LB(isa, 8, 0, 4),\t\t\t/* lb\t\t$t0, ($a0) */\n\t\tMIPS32_AND(isa, 6, 6, 8),\t\t\t/* and\t\t$a2, $a2, $t0 */\n\t\tMIPS32_ADDIU(isa, 5, 5, NEG16(1)),\t\t/* addiu\t$a1, $a1, -1 */\n\t\tMIPS32_BNE(isa, 5, 0, NEG16(4 << isa)),\t\t/* bne\t\t$a1, $zero, nbyte */\n\t\tMIPS32_ADDIU(isa, 4, 4, 1),\t\t\t/* addiu\t$a0, $a0, 1 */\n\t\tMIPS32_SDBBP(isa)\t\t\t\t/* sdbbp */\n\t};\n\n\t/* make sure we have a working area */\n\tif (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tpracc_swap16_array(ejtag_info, erase_check_code, ARRAY_SIZE(erase_check_code));\n\n\t/* convert erase check code into a buffer in target endianness */\n\tuint8_t erase_check_code_8[sizeof(erase_check_code)];\n\ttarget_buffer_set_u32_array(target, erase_check_code_8,\n\t\t\t\t\tARRAY_SIZE(erase_check_code), erase_check_code);\n\n\tint retval = target_write_buffer(target, erase_check_algorithm->address,\n\t\t\t\t\t\tsizeof(erase_check_code), erase_check_code_8);\n\tif (retval != ERROR_OK)\n\t\tgoto cleanup;\n\n\tmips32_info.common_magic = MIPS32_COMMON_MAGIC;\n\tmips32_info.isa_mode = isa ? MIPS32_ISA_MMIPS32 : MIPS32_ISA_MIPS32;\n\n\tinit_reg_param(&reg_params[0], \"r4\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);\n\n\tinit_reg_param(&reg_params[1], \"r5\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);\n\n\tinit_reg_param(&reg_params[2], \"r6\", 32, PARAM_IN_OUT);\n\tbuf_set_u32(reg_params[2].value, 0, 32, erased_value);\n\n\tretval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address,\n\t\t\terase_check_algorithm->address + (sizeof(erase_check_code) - 4), 10000, &mips32_info);\n\n\tif (retval == ERROR_OK)\n\t\tblocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\tdestroy_reg_param(&reg_params[2]);\n\ncleanup:\n\ttarget_free_working_area(target, erase_check_algorithm);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn 1;       /* only one block has been checked */\n}\n\nstatic int mips32_verify_pointer(struct command_invocation *cmd,\n\t\tstruct mips32_common *mips32)\n{\n\tif (mips32->common_magic != MIPS32_COMMON_MAGIC) {\n\t\tcommand_print(cmd, \"target is not an MIPS32\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * MIPS32 targets expose command interface\n * to manipulate CP0 registers\n */\nCOMMAND_HANDLER(mips32_handle_cp0_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\n\tretval = mips32_verify_pointer(CMD, mips32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* two or more argument, access a single register/select (write if third argument is given) */\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse {\n\t\tuint32_t cp0_reg, cp0_sel;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);\n\n\t\tif (CMD_ARGC == 2) {\n\t\t\tuint32_t value;\n\n\t\t\tretval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access reg %\" PRIu32,\n\t\t\t\t\t\tcp0_reg);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"cp0 reg %\" PRIu32 \", select %\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\tcp0_reg, cp0_sel, value);\n\n\t\t} else if (CMD_ARGC == 3) {\n\t\t\tuint32_t value;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);\n\t\t\tretval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access cp0 reg %\" PRIu32 \", select %\" PRIu32,\n\t\t\t\t\t\tcp0_reg,  cp0_sel);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"cp0 reg %\" PRIu32 \", select %\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\tcp0_reg, cp0_sel, value);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(mips32_handle_scan_delay_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);\n\telse if (CMD_ARGC > 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"scan delay: %d nsec\", ejtag_info->scan_delay);\n\tif (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {\n\t\tejtag_info->mode = 0;\n\t\tcommand_print(CMD, \"running in legacy mode\");\n\t} else {\n\t\tejtag_info->mode = 1;\n\t\tcommand_print(CMD, \"running in fast queued mode\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration mips32_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cp0\",\n\t\t.handler = mips32_handle_cp0_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"regnum select [value]\",\n\t\t.help = \"display/modify cp0 register\",\n\t},\n\t\t{\n\t\t.name = \"scan_delay\",\n\t\t.handler = mips32_handle_scan_delay_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"display/set scan delay in nano seconds\",\n\t\t.usage = \"[value]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration mips32_command_handlers[] = {\n\t{\n\t\t.name = \"mips32\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mips32 command group\",\n\t\t.usage = \"\",\n\t\t.chain = mips32_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_MIPS32_H\n#define OPENOCD_TARGET_MIPS32_H\n\n#include \"target.h\"\n#include \"mips32_pracc.h\"\n\n#define MIPS32_COMMON_MAGIC\t\t0xB320B320U\n\n/**\n * Memory segments (32bit kernel mode addresses)\n * These are the traditional names used in the 32-bit universe.\n */\n#define KUSEG\t\t\t0x00000000\n#define KSEG0\t\t\t0x80000000\n#define KSEG1\t\t\t0xa0000000\n#define KSEG2\t\t\t0xc0000000\n#define KSEG3\t\t\t0xe0000000\n\n/** Returns the kernel segment base of a given address */\n#define KSEGX(a)\t\t((a) & 0xe0000000)\n\n/** CP0 CONFIG register fields */\n#define MIPS32_CONFIG0_KU_SHIFT 25\n#define MIPS32_CONFIG0_KU_MASK (0x7 << MIPS32_CONFIG0_KU_SHIFT)\n\n#define MIPS32_CONFIG0_K0_SHIFT 0\n#define MIPS32_CONFIG0_K0_MASK (0x7 << MIPS32_CONFIG0_K0_SHIFT)\n\n#define MIPS32_CONFIG0_K23_SHIFT 28\n#define MIPS32_CONFIG0_K23_MASK (0x7 << MIPS32_CONFIG0_K23_SHIFT)\n\n#define MIPS32_CONFIG0_AR_SHIFT 10\n#define MIPS32_CONFIG0_AR_MASK (0x7 << MIPS32_CONFIG0_AR_SHIFT)\n\n#define MIPS32_CONFIG1_DL_SHIFT 10\n#define MIPS32_CONFIG1_DL_MASK (0x7 << MIPS32_CONFIG1_DL_SHIFT)\n\n#define MIPS32_CONFIG3_ISA_SHIFT\t14\n#define MIPS32_CONFIG3_ISA_MASK\t\t(3 << MIPS32_CONFIG3_ISA_SHIFT)\n\n#define MIPS32_ARCH_REL1 0x0\n#define MIPS32_ARCH_REL2 0x1\n\n#define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000\n\n/* offsets into mips32 core register cache */\nenum {\n\tMIPS32_PC = 37,\n\tMIPS32_FIR = 71,\n\tMIPS32NUMCOREREGS\n};\n\nenum mips32_isa_mode {\n\tMIPS32_ISA_MIPS32 = 0,\n\tMIPS32_ISA_MIPS16E = 1,\n\tMIPS32_ISA_MMIPS32 = 3,\n};\n\nenum mips32_isa_imp {\n\tMIPS32_ONLY = 0,\n\tMMIPS32_ONLY = 1,\n\tMIPS32_MIPS16 = 2,\n\tMIPS32_MMIPS32 = 3,\n};\n\nstruct mips32_comparator {\n\tint used;\n\tuint32_t bp_value;\n\tuint32_t reg_address;\n};\n\nstruct mips32_common {\n\tunsigned int common_magic;\n\n\tvoid *arch_info;\n\tstruct reg_cache *core_cache;\n\tstruct mips_ejtag ejtag_info;\n\tuint32_t core_regs[MIPS32NUMCOREREGS];\n\tenum mips32_isa_mode isa_mode;\n\tenum mips32_isa_imp isa_imp;\n\n\t/* working area for fastdata access */\n\tstruct working_area *fast_data_area;\n\n\tint bp_scanned;\n\tint num_inst_bpoints;\n\tint num_data_bpoints;\n\tint num_inst_bpoints_avail;\n\tint num_data_bpoints_avail;\n\tstruct mips32_comparator *inst_break_list;\n\tstruct mips32_comparator *data_break_list;\n\n\t/* register cache to processor synchronization */\n\tint (*read_core_reg)(struct target *target, unsigned int num);\n\tint (*write_core_reg)(struct target *target, unsigned int num);\n};\n\nstatic inline struct mips32_common *\ntarget_to_mips32(struct target *target)\n{\n\treturn target->arch_info;\n}\n\nstruct mips32_core_reg {\n\tuint32_t num;\n\tstruct target *target;\n\tstruct mips32_common *mips32_common;\n};\n\nstruct mips32_algorithm {\n\tunsigned int common_magic;\n\tenum mips32_isa_mode isa_mode;\n};\n\n#define MIPS32_OP_ADDU\t0x21u\n#define MIPS32_OP_ADDIU\t0x09u\n#define MIPS32_OP_ANDI\t0x0Cu\n#define MIPS32_OP_BEQ\t0x04u\n#define MIPS32_OP_BGTZ\t0x07u\n#define MIPS32_OP_BNE\t0x05u\n#define MIPS32_OP_ADDI\t0x08u\n#define MIPS32_OP_AND\t0x24u\n#define MIPS32_OP_CACHE\t0x2Fu\n#define MIPS32_OP_COP0\t0x10u\n#define MIPS32_OP_J\t0x02u\n#define MIPS32_OP_JR\t0x08u\n#define MIPS32_OP_LUI\t0x0Fu\n#define MIPS32_OP_LW\t0x23u\n#define MIPS32_OP_LB\t0x20u\n#define MIPS32_OP_LBU\t0x24u\n#define MIPS32_OP_LHU\t0x25u\n#define MIPS32_OP_MFHI\t0x10u\n#define MIPS32_OP_MTHI\t0x11u\n#define MIPS32_OP_MFLO\t0x12u\n#define MIPS32_OP_MTLO\t0x13u\n#define MIPS32_OP_RDHWR\t0x3Bu\n#define MIPS32_OP_SB\t0x28u\n#define MIPS32_OP_SH\t0x29u\n#define MIPS32_OP_SW\t0x2Bu\n#define MIPS32_OP_ORI\t0x0Du\n#define MIPS32_OP_XORI\t0x0Eu\n#define MIPS32_OP_XOR\t0x26u\n#define MIPS32_OP_SLTU\t0x2Bu\n#define MIPS32_OP_SRL\t0x03u\n#define MIPS32_OP_SYNCI\t0x1Fu\n#define MIPS32_OP_SLL\t0x00u\n#define MIPS32_OP_SLTI\t0x0Au\n#define MIPS32_OP_MOVN\t0x0Bu\n\n#define MIPS32_OP_REGIMM\t0x01u\n#define MIPS32_OP_SDBBP\t0x3Fu\n#define MIPS32_OP_SPECIAL\t0x00u\n#define MIPS32_OP_SPECIAL2\t0x07u\n#define MIPS32_OP_SPECIAL3\t0x1Fu\n\n#define MIPS32_COP0_MF\t0x00u\n#define MIPS32_COP0_MT\t0x04u\n\n#define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) \\\n\t(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))\n#define MIPS32_I_INST(opcode, rs, rt, immd) \\\n\t(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))\n#define MIPS32_J_INST(opcode, addr)\t(((opcode) << 26) | (addr))\n\n#define MIPS32_ISA_NOP\t\t\t\t0\n#define MIPS32_ISA_ADDI(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val)\n#define MIPS32_ISA_ADDIU(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_ADDIU, src, tar, val)\n#define MIPS32_ISA_ADDU(dst, src, tar)\t\tMIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_ADDU)\n#define MIPS32_ISA_AND(dst, src, tar)\t\tMIPS32_R_INST(0, src, tar, dst, 0, MIPS32_OP_AND)\n#define MIPS32_ISA_ANDI(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_ANDI, src, tar, val)\n\n#define MIPS32_ISA_B(off)\t\t\tMIPS32_ISA_BEQ(0, 0, off)\n#define MIPS32_ISA_BEQ(src, tar, off)\t\tMIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off)\n#define MIPS32_ISA_BGTZ(reg, off)\t\tMIPS32_I_INST(MIPS32_OP_BGTZ, reg, 0, off)\n#define MIPS32_ISA_BNE(src, tar, off)\t\tMIPS32_I_INST(MIPS32_OP_BNE, src, tar, off)\n#define MIPS32_ISA_CACHE(op, off, base)\t\tMIPS32_I_INST(MIPS32_OP_CACHE, base, op, off)\n#define MIPS32_ISA_J(tar)\t\t\tMIPS32_J_INST(MIPS32_OP_J, (0x0FFFFFFFu & (tar)) >> 2)\n#define MIPS32_ISA_JR(reg)\t\t\tMIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_JR)\n\n#define MIPS32_ISA_LB(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_LB, base, reg, off)\n#define MIPS32_ISA_LBU(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_LBU, base, reg, off)\n#define MIPS32_ISA_LHU(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_LHU, base, reg, off)\n#define MIPS32_ISA_LUI(reg, val)\t\tMIPS32_I_INST(MIPS32_OP_LUI, 0, reg, val)\n#define MIPS32_ISA_LW(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_LW, base, reg, off)\n\n#define MIPS32_ISA_MFC0(gpr, cpr, sel)\t\tMIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel)\n#define MIPS32_ISA_MTC0(gpr, cpr, sel)\t\tMIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MT, gpr, cpr, 0, sel)\n#define MIPS32_ISA_MFLO(reg)\t\t\tMIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFLO)\n#define MIPS32_ISA_MFHI(reg)\t\t\tMIPS32_R_INST(0, 0, 0, reg, 0, MIPS32_OP_MFHI)\n#define MIPS32_ISA_MTLO(reg)\t\t\tMIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTLO)\n#define MIPS32_ISA_MTHI(reg)\t\t\tMIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_MTHI)\n\n#define MIPS32_ISA_MOVN(dst, src, tar)\t\tMIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_MOVN)\n#define MIPS32_ISA_ORI(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_ORI, src, tar, val)\n#define MIPS32_ISA_RDHWR(tar, dst)\t\tMIPS32_R_INST(MIPS32_OP_SPECIAL3, 0, tar, dst, 0, MIPS32_OP_RDHWR)\n#define MIPS32_ISA_SB(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_SB, base, reg, off)\n#define MIPS32_ISA_SH(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_SH, base, reg, off)\n#define MIPS32_ISA_SW(reg, off, base)\t\tMIPS32_I_INST(MIPS32_OP_SW, base, reg, off)\n\n#define MIPS32_ISA_SLL(dst, src, sa)\t\tMIPS32_R_INST(MIPS32_OP_SPECIAL, 0, src, dst, sa, MIPS32_OP_SLL)\n#define MIPS32_ISA_SLTI(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_SLTI, src, tar, val)\n#define MIPS32_ISA_SLTU(dst, src, tar)\t\tMIPS32_R_INST(MIPS32_OP_SPECIAL, src, tar, dst, 0, MIPS32_OP_SLTU)\n#define MIPS32_ISA_SRL(reg, src, off)\t\tMIPS32_R_INST(0, 0, src, reg, off, MIPS32_OP_SRL)\n#define MIPS32_ISA_SYNC\t\t\t\t0xFu\n#define MIPS32_ISA_SYNCI(off, base)\t\tMIPS32_I_INST(MIPS32_OP_REGIMM, base, MIPS32_OP_SYNCI, off)\n\n#define MIPS32_ISA_XOR(reg, val1, val2)\t\tMIPS32_R_INST(0, val1, val2, reg, 0, MIPS32_OP_XOR)\n#define MIPS32_ISA_XORI(tar, src, val)\t\tMIPS32_I_INST(MIPS32_OP_XORI, src, tar, val)\n\n#define MIPS32_ISA_SYNCI_STEP\t\t0x1\t/* reg num od address step size to be used with synci instruction */\n\n/**\n * Cache operations definitions\n * Operation field is 5 bits long :\n * 1) bits 1..0 hold cache type\n * 2) bits 4..2 hold operation code\n */\n#define MIPS32_CACHE_D_HIT_WRITEBACK ((0x1 << 0) | (0x6 << 2))\n#define MIPS32_CACHE_I_HIT_INVALIDATE ((0x0 << 0) | (0x4 << 2))\n\n/* ejtag specific instructions */\n#define MIPS32_ISA_DRET\t\t\t\t0x4200001Fu\n/* MIPS32_ISA_J_INST(MIPS32_ISA_OP_SPECIAL2, MIPS32_ISA_OP_SDBBP) */\n#define MIPS32_ISA_SDBBP\t\t\t0x7000003Fu\n#define MIPS16_ISA_SDBBP\t\t\t0xE801u\n\n/*MICRO MIPS INSTRUCTIONS, see doc MD00582 */\n#define POOL32A\t\t\t\t\t0X00u\n#define POOL32AXF\t\t\t\t0x3Cu\n#define POOL32B\t\t\t\t\t0x08u\n#define POOL32I\t\t\t\t\t0x10u\n#define MMIPS32_OP_ADDI\t\t\t0x04u\n#define MMIPS32_OP_ADDIU\t\t0x0Cu\n#define MMIPS32_OP_ADDU\t\t\t0x150u\n#define MMIPS32_OP_AND\t\t\t0x250u\n#define MMIPS32_OP_ANDI\t\t\t0x34u\n#define MMIPS32_OP_BEQ\t\t\t0x25u\n#define MMIPS32_OP_BGTZ\t\t\t0x06u\n#define MMIPS32_OP_BNE\t\t\t0x2Du\n#define MMIPS32_OP_CACHE\t\t0x06u\n#define MMIPS32_OP_J\t\t\t0x35u\n#define MMIPS32_OP_JALR\t\t\t0x03Cu\n#define MMIPS32_OP_LB\t\t\t0x07u\n#define MMIPS32_OP_LBU\t\t\t0x05u\n#define MMIPS32_OP_LHU\t\t\t0x0Du\n#define MMIPS32_OP_LUI\t\t\t0x0Du\n#define MMIPS32_OP_LW\t\t\t0x3Fu\n#define MMIPS32_OP_MFC0\t\t\t0x03u\n#define MMIPS32_OP_MTC0\t\t\t0x0Bu\n#define MMIPS32_OP_MFLO\t\t\t0x075u\n#define MMIPS32_OP_MFHI\t\t\t0x035u\n#define MMIPS32_OP_MTLO\t\t\t0x0F5u\n#define MMIPS32_OP_MTHI\t\t\t0x0B5u\n#define MMIPS32_OP_MOVN\t\t\t0x018u\n#define MMIPS32_OP_ORI\t\t\t0x14u\n#define MMIPS32_OP_RDHWR\t\t0x1ACu\n#define MMIPS32_OP_SB\t\t\t0x06u\n#define MMIPS32_OP_SH\t\t\t0x0Eu\n#define MMIPS32_OP_SW\t\t\t0x3Eu\n#define MMIPS32_OP_SLTU\t\t\t0x390u\n#define MMIPS32_OP_SLL\t\t\t0x000u\n#define MMIPS32_OP_SLTI\t\t\t0x24u\n#define MMIPS32_OP_SRL\t\t\t0x040u\n#define MMIPS32_OP_SYNCI\t\t0x10u\n#define MMIPS32_OP_XOR\t\t\t0x310u\n#define MMIPS32_OP_XORI\t\t\t0x1Cu\n\n#define MMIPS32_ADDI(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_ADDI, tar, src, val)\n#define MMIPS32_ADDIU(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_ADDIU, tar, src, val)\n#define MMIPS32_ADDU(dst, src, tar)\t\tMIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_ADDU)\n#define MMIPS32_AND(dst, src, tar)\t\tMIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_AND)\n#define MMIPS32_ANDI(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_ANDI, tar, src, val)\n\n#define MMIPS32_B(off)\t\t\t\tMMIPS32_BEQ(0, 0, off)\n#define MMIPS32_BEQ(src, tar, off)\t\tMIPS32_I_INST(MMIPS32_OP_BEQ, tar, src, off)\n#define MMIPS32_BGTZ(reg, off)\t\t\tMIPS32_I_INST(POOL32I, MMIPS32_OP_BGTZ, reg, off)\n#define MMIPS32_BNE(src, tar, off)\t\tMIPS32_I_INST(MMIPS32_OP_BNE, tar, src, off)\n#define MMIPS32_CACHE(op, off, base)\t\tMIPS32_R_INST(POOL32B, op, base, MMIPS32_OP_CACHE << 1, 0, off)\n\n#define MMIPS32_J(tar)\t\t\t\tMIPS32_J_INST(MMIPS32_OP_J, ((0x07FFFFFFu & ((tar) >> 1))))\n#define MMIPS32_JR(reg)\t\t\t\tMIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_JALR, POOL32AXF)\n#define MMIPS32_LB(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_LB, reg, base, off)\n#define MMIPS32_LBU(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_LBU, reg, base, off)\n#define MMIPS32_LHU(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_LHU, reg, base, off)\n#define MMIPS32_LUI(reg, val)\t\t\tMIPS32_I_INST(POOL32I, MMIPS32_OP_LUI, reg, val)\n#define MMIPS32_LW(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_LW, reg, base, off)\n\n#define MMIPS32_MFC0(gpr, cpr, sel)\t\tMIPS32_R_INST(POOL32A, gpr, cpr, sel, MMIPS32_OP_MFC0, POOL32AXF)\n#define MMIPS32_MFLO(reg)\t\t\tMIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MFLO, POOL32AXF)\n#define MMIPS32_MFHI(reg)\t\t\tMIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MFHI, POOL32AXF)\n#define MMIPS32_MTC0(gpr, cpr, sel)\t\tMIPS32_R_INST(POOL32A, gpr, cpr, sel, MMIPS32_OP_MTC0, POOL32AXF)\n#define MMIPS32_MTLO(reg)\t\t\tMIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MTLO, POOL32AXF)\n#define MMIPS32_MTHI(reg)\t\t\tMIPS32_R_INST(POOL32A, 0, reg, 0, MMIPS32_OP_MTHI, POOL32AXF)\n\n#define MMIPS32_MOVN(dst, src, tar)\t\tMIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_MOVN)\n#define MMIPS32_NOP\t\t\t\t0\n#define MMIPS32_ORI(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_ORI, tar, src, val)\n#define MMIPS32_RDHWR(tar, dst)\t\t\tMIPS32_R_INST(POOL32A, dst, tar, 0, MMIPS32_OP_RDHWR, POOL32AXF)\n#define MMIPS32_SB(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_SB, reg, base, off)\n#define MMIPS32_SH(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_SH, reg, base, off)\n#define MMIPS32_SW(reg, off, base)\t\tMIPS32_I_INST(MMIPS32_OP_SW, reg, base, off)\n\n#define MMIPS32_SRL(reg, src, off)\t\tMIPS32_R_INST(POOL32A, reg, src, off, 0, MMIPS32_OP_SRL)\n#define MMIPS32_SLTU(dst, src, tar)\t\tMIPS32_R_INST(POOL32A, tar, src, dst, 0, MMIPS32_OP_SLTU)\n#define MMIPS32_SYNCI(off, base)\t\tMIPS32_I_INST(POOL32I, MMIPS32_OP_SYNCI, base, off)\n#define MMIPS32_SLL(dst, src, sa)\t\tMIPS32_R_INST(POOL32A, dst, src, sa, 0, MMIPS32_OP_SLL)\n#define MMIPS32_SLTI(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_SLTI, tar, src, val)\n#define MMIPS32_SYNC\t\t\t\t0x00001A7Cu /* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1ADu, POOL32AXF) */\n\n#define MMIPS32_XOR(reg, val1, val2)\t\tMIPS32_R_INST(POOL32A, val1, val2, reg, 0, MMIPS32_OP_XOR)\n#define MMIPS32_XORI(tar, src, val)\t\tMIPS32_I_INST(MMIPS32_OP_XORI, tar, src, val)\n\n#define MMIPS32_SYNCI_STEP\t0x1u\t/* reg num od address step size to be used with synci instruction */\n\n\n/* ejtag specific instructions */\n#define MMIPS32_DRET\t\t\t0x0000E37Cu\t/* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x38D, POOL32AXF) */\n#define MMIPS32_SDBBP\t\t\t0x0000DB7Cu\t/* MIPS32_R_INST(POOL32A, 0, 0, 0, 0x1BD, POOL32AXF) */\n#define MMIPS16_SDBBP\t\t\t0x46C0u\t\t/* POOL16C instr */\n\n/* instruction code with isa selection */\n#define MIPS32_NOP\t\t\t\t0\t/* same for both isa's */\n#define MIPS32_ADDI(isa, tar, src, val)\t\t(isa ? MMIPS32_ADDI(tar, src, val) : MIPS32_ISA_ADDI(tar, src, val))\n#define MIPS32_ADDIU(isa, tar, src, val)\t(isa ? MMIPS32_ADDIU(tar, src, val) : MIPS32_ISA_ADDIU(tar, src, val))\n#define MIPS32_ADDU(isa, dst, src, tar)\t\t(isa ? MMIPS32_ADDU(dst, src, tar) : MIPS32_ISA_ADDU(dst, src, tar))\n#define MIPS32_AND(isa, dst, src, tar)\t\t(isa ? MMIPS32_AND(dst, src, tar) : MIPS32_ISA_AND(dst, src, tar))\n#define MIPS32_ANDI(isa, tar, src, val)\t\t(isa ? MMIPS32_ANDI(tar, src, val) : MIPS32_ISA_ANDI(tar, src, val))\n\n#define MIPS32_B(isa, off)\t\t\t(isa ? MMIPS32_B(off) : MIPS32_ISA_B(off))\n#define MIPS32_BEQ(isa, src, tar, off)\t\t(isa ? MMIPS32_BEQ(src, tar, off) : MIPS32_ISA_BEQ(src, tar, off))\n#define MIPS32_BGTZ(isa, reg, off)\t\t(isa ? MMIPS32_BGTZ(reg, off) : MIPS32_ISA_BGTZ(reg, off))\n#define MIPS32_BNE(isa, src, tar, off)\t\t(isa ? MMIPS32_BNE(src, tar, off) : MIPS32_ISA_BNE(src, tar, off))\n#define MIPS32_CACHE(isa, op, off, base)\t(isa ? MMIPS32_CACHE(op, off, base) : MIPS32_ISA_CACHE(op, off, base))\n\n#define MIPS32_J(isa, tar)\t\t\t(isa ? MMIPS32_J(tar) : MIPS32_ISA_J(tar))\n#define MIPS32_JR(isa, reg)\t\t\t(isa ? MMIPS32_JR(reg) : MIPS32_ISA_JR(reg))\n#define MIPS32_LB(isa, reg, off, base)\t\t(isa ? MMIPS32_LB(reg, off, base) : MIPS32_ISA_LB(reg, off, base))\n#define MIPS32_LBU(isa, reg, off, base)\t\t(isa ? MMIPS32_LBU(reg, off, base) : MIPS32_ISA_LBU(reg, off, base))\n#define MIPS32_LHU(isa, reg, off, base)\t\t(isa ? MMIPS32_LHU(reg, off, base) : MIPS32_ISA_LHU(reg, off, base))\n#define MIPS32_LW(isa, reg, off, base)\t\t(isa ? MMIPS32_LW(reg, off, base) : MIPS32_ISA_LW(reg, off, base))\n#define MIPS32_LUI(isa, reg, val)\t\t(isa ? MMIPS32_LUI(reg, val) : MIPS32_ISA_LUI(reg, val))\n\n#define MIPS32_MFC0(isa, gpr, cpr, sel)\t\t(isa ? MMIPS32_MFC0(gpr, cpr, sel) : MIPS32_ISA_MFC0(gpr, cpr, sel))\n#define MIPS32_MTC0(isa, gpr, cpr, sel)\t\t(isa ? MMIPS32_MTC0(gpr, cpr, sel) : MIPS32_ISA_MTC0(gpr, cpr, sel))\n#define MIPS32_MFLO(isa, reg)\t\t\t(isa ? MMIPS32_MFLO(reg) : MIPS32_ISA_MFLO(reg))\n#define MIPS32_MFHI(isa, reg)\t\t\t(isa ? MMIPS32_MFHI(reg) : MIPS32_ISA_MFHI(reg))\n#define MIPS32_MTLO(isa, reg)\t\t\t(isa ? MMIPS32_MTLO(reg) : MIPS32_ISA_MTLO(reg))\n#define MIPS32_MTHI(isa, reg)\t\t\t(isa ? MMIPS32_MTHI(reg) : MIPS32_ISA_MTHI(reg))\n\n#define MIPS32_MOVN(isa, dst, src, tar)\t\t(isa ? MMIPS32_MOVN(dst, src, tar) : MIPS32_ISA_MOVN(dst, src, tar))\n#define MIPS32_ORI(isa, tar, src, val)\t\t(isa ? MMIPS32_ORI(tar, src, val) : MIPS32_ISA_ORI(tar, src, val))\n#define MIPS32_RDHWR(isa, tar, dst)\t\t(isa ? MMIPS32_RDHWR(tar, dst) : MIPS32_ISA_RDHWR(tar, dst))\n#define MIPS32_SB(isa, reg, off, base)\t\t(isa ? MMIPS32_SB(reg, off, base) : MIPS32_ISA_SB(reg, off, base))\n#define MIPS32_SH(isa, reg, off, base)\t\t(isa ? MMIPS32_SH(reg, off, base) : MIPS32_ISA_SH(reg, off, base))\n#define MIPS32_SW(isa, reg, off, base)\t\t(isa ? MMIPS32_SW(reg, off, base) : MIPS32_ISA_SW(reg, off, base))\n\n#define MIPS32_SLL(isa, dst, src, sa)\t\t(isa ? MMIPS32_SLL(dst, src, sa) : MIPS32_ISA_SLL(dst, src, sa))\n#define MIPS32_SLTI(isa, tar, src, val)\t\t(isa ? MMIPS32_SLTI(tar, src, val) : MIPS32_ISA_SLTI(tar, src, val))\n#define MIPS32_SLTU(isa, dst, src, tar)\t\t(isa ? MMIPS32_SLTU(dst, src, tar) : MIPS32_ISA_SLTU(dst, src, tar))\n#define MIPS32_SRL(isa, reg, src, off)\t\t(isa ? MMIPS32_SRL(reg, src, off) : MIPS32_ISA_SRL(reg, src, off))\n\n#define MIPS32_SYNCI(isa, off, base)\t\t(isa ? MMIPS32_SYNCI(off, base) : MIPS32_ISA_SYNCI(off, base))\n#define MIPS32_SYNC(isa)\t\t\t(isa ? MMIPS32_SYNC : MIPS32_ISA_SYNC)\n#define MIPS32_XOR(isa, reg, val1, val2)\t(isa ? MMIPS32_XOR(reg, val1, val2) : MIPS32_ISA_XOR(reg, val1, val2))\n#define MIPS32_XORI(isa, tar, src, val)\t\t(isa ? MMIPS32_XORI(tar, src, val) : MIPS32_ISA_XORI(tar, src, val))\n\n#define MIPS32_SYNCI_STEP\t\t\t0x1\n\n/* ejtag specific instructions */\n#define MIPS32_DRET(isa)\t\t\t(isa ? MMIPS32_DRET : MIPS32_ISA_DRET)\n#define MIPS32_SDBBP(isa)\t\t\t(isa ? MMIPS32_SDBBP : MIPS32_ISA_SDBBP)\n\n#define MIPS16_SDBBP(isa)\t\t\t(isa ? MMIPS16_SDBBP : MIPS16_ISA_SDBBP)\n\nextern const struct command_registration mips32_command_handlers[];\n\nint mips32_arch_state(struct target *target);\n\nint mips32_init_arch_info(struct target *target,\n\t\tstruct mips32_common *mips32, struct jtag_tap *tap);\n\nint mips32_restore_context(struct target *target);\nint mips32_save_context(struct target *target);\n\nstruct reg_cache *mips32_build_reg_cache(struct target *target);\n\nint mips32_run_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info);\n\nint mips32_configure_break_unit(struct target *target);\n\nint mips32_enable_interrupts(struct target *target, int enable);\n\nint mips32_examine(struct target *target);\n\nint mips32_read_config_regs(struct target *target);\n\nint mips32_register_commands(struct command_context *cmd_ctx);\n\nint mips32_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\nint mips32_checksum_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint32_t *checksum);\nint mips32_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value);\n\n#endif /* OPENOCD_TARGET_MIPS32_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32_dmaacc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by John McCarthy                                   *\n *   jgmcc@magma.ca                                                        *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mips32_dmaacc.h\"\n#include <helper/time_support.h>\n\nstatic int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, uint8_t *buf);\nstatic int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, uint16_t *buf);\nstatic int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, uint32_t *buf);\n\nstatic int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, const uint8_t *buf);\nstatic int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, const uint16_t *buf);\nstatic int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int count, const uint32_t *buf);\n\n/*\n * The following logic shamelessly cloned from HairyDairyMaid's wrt54g_debrick\n * to support the Broadcom BCM5352 SoC in the Linksys WRT54GL wireless router\n * (and any others that support EJTAG DMA transfers).\n * Note: This only supports memory read/write. Since the BCM5352 doesn't\n * appear to support PRACC accesses, all debug functions except halt\n * do not work.  Still, this does allow erasing/writing flash as well as\n * displaying/modifying memory and memory mapped registers.\n */\n\nstatic int ejtag_dma_dstrt_poll(struct mips_ejtag *ejtag_info)\n{\n\tuint32_t ejtag_ctrl;\n\tint64_t start = timeval_ms();\n\n\tdo {\n\t\tif (timeval_ms() - start > 1000) {\n\t\t\tLOG_ERROR(\"DMA time out\");\n\t\t\treturn -ETIMEDOUT;\n\t\t}\n\t\tejtag_ctrl = EJTAG_CTRL_DMAACC | ejtag_info->ejtag_ctrl;\n\t\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\t} while (ejtag_ctrl & EJTAG_CTRL_DSTRT);\n\treturn 0;\n}\n\nstatic int ejtag_dma_read(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\nbegin_ejtag_dma_read:\n\n\t/* Setup Address */\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Read & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Read Data */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, data);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl  & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_read;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ejtag_dma_read_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint16_t *data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\nbegin_ejtag_dma_read_h:\n\n\t/* Setup Address */\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Read & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD |\n\t\t\tEJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Read Data */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl  & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_read_h;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t/* Handle the bigendian/littleendian */\n\tif (addr & 0x2)\n\t\t*data = (v >> 16) & 0xffff;\n\telse\n\t\t*data = (v & 0x0000ffff);\n\n\treturn ERROR_OK;\n}\n\nstatic int ejtag_dma_read_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint8_t *data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\nbegin_ejtag_dma_read_b:\n\n\t/* Setup Address */\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Read & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Read Data */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl  & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_read_b;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Read Addr = %08\" PRIx32 \"  Data = ERROR ON READ\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t/* Handle the bigendian/littleendian */\n\tswitch (addr & 0x3) {\n\t\tcase 0:\n\t\t\t*data = v & 0xff;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\t*data = (v >> 8) & 0xff;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t*data = (v >> 16) & 0xff;\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\t*data = (v >> 24) & 0xff;\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ejtag_dma_write(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\nbegin_ejtag_dma_write:\n\n\t/* Setup Address */\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Setup Data */\n\tv = data;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Write & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_WORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl  & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_write;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ejtag_dma_write_h(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\n\t/* Handle the bigendian/littleendian */\n\tdata &= 0xffff;\n\tdata |= data << 16;\n\nbegin_ejtag_dma_write_h:\n\n\t/* Setup Address */\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Setup Data */\n\tv = data;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Write & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_write_h;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int ejtag_dma_write_b(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t data)\n{\n\tuint32_t v;\n\tuint32_t ejtag_ctrl;\n\tint retries = RETRY_ATTEMPTS;\n\n\t/* Handle the bigendian/littleendian */\n\tdata &= 0xff;\n\tdata |= data << 8;\n\tdata |= data << 16;\n\nbegin_ejtag_dma_write_b:\n\n\t/*  Setup Address*/\n\tv = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Setup Data */\n\tv = data;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\tmips_ejtag_drscan_32(ejtag_info, &v);\n\n\t/* Initiate DMA Write & set DSTRT */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DMA_BYTE | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* Wait for DSTRT to Clear */\n\tejtag_dma_dstrt_poll(ejtag_info);\n\n\t/* Clear DMA & Check DERR */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (ejtag_ctrl & EJTAG_CTRL_DERR) {\n\t\tif (retries--) {\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE (retrying)\", addr);\n\t\t\tgoto begin_ejtag_dma_write_b;\n\t\t} else\n\t\t\tLOG_ERROR(\"DMA Write Addr = %08\" PRIx32 \"  Data = ERROR ON WRITE\", addr);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)\n{\n\tswitch (size) {\n\t\tcase 1:\n\t\t\treturn mips32_dmaacc_read_mem8(ejtag_info, addr, count, (uint8_t *)buf);\n\t\tcase 2:\n\t\t\treturn mips32_dmaacc_read_mem16(ejtag_info, addr, count, (uint16_t *)buf);\n\t\tcase 4:\n\t\t\treturn mips32_dmaacc_read_mem32(ejtag_info, addr, count, (uint32_t *)buf);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)\n{\n\tint i;\n\tint\tretval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_read(ejtag_info, addr + i * sizeof(*buf), &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)\n{\n\tint i;\n\tint retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_read_h(ejtag_info, addr + i * sizeof(*buf), &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)\n{\n\tint i;\n\tint retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_read_b(ejtag_info, addr + i * sizeof(*buf), &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, const void *buf)\n{\n\tswitch (size) {\n\t\tcase 1:\n\t\t\treturn mips32_dmaacc_write_mem8(ejtag_info, addr, count, buf);\n\t\tcase 2:\n\t\t\treturn mips32_dmaacc_write_mem16(ejtag_info, addr, count, buf);\n\t\tcase 4:\n\t\t\treturn mips32_dmaacc_write_mem32(ejtag_info, addr, count, buf);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint32_t *buf)\n{\n\tint i;\n\tint retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_write(ejtag_info, addr + i * sizeof(*buf), buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint16_t *buf)\n{\n\tint i;\n\tint retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_write_h(ejtag_info, addr + i * sizeof(*buf), buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, const uint8_t *buf)\n{\n\tint i;\n\tint retval;\n\n\tfor (i = 0; i < count; i++) {\n\t\tretval = ejtag_dma_write_b(ejtag_info, addr + i * sizeof(*buf), buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32_dmaacc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by John McCarthy                                   *\n *   jgmcc@magma.ca                                                        *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_MIPS32_DMAACC_H\n#define OPENOCD_TARGET_MIPS32_DMAACC_H\n\n#include \"mips_ejtag.h\"\n\n#define EJTAG_CTRL_DMA_BYTE\t\t\t0x00000000\n#define EJTAG_CTRL_DMA_HALFWORD\t\t0x00000080\n#define EJTAG_CTRL_DMA_WORD\t\t\t0x00000100\n#define EJTAG_CTRL_DMA_TRIPLEBYTE\t0x00000180\n\n#define RETRY_ATTEMPTS\t0\n\nint mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int size, int count, void *buf);\nint mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int size, int count, const void *buf);\n\n#endif /* OPENOCD_TARGET_MIPS32_DMAACC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32_pracc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n/*\n * This version has optimized assembly routines for 32 bit operations:\n * - read word\n * - write word\n * - write array of words\n *\n * One thing to be aware of is that the MIPS32 cpu will execute the\n * instruction after a branch instruction (one delay slot).\n *\n * For example:\n *  LW $2, ($5 +10)\n *  B foo\n *  LW $1, ($2 +100)\n *\n * The LW $1, ($2 +100) instruction is also executed. If this is\n * not wanted a NOP can be inserted:\n *\n *  LW $2, ($5 +10)\n *  B foo\n *  NOP\n *  LW $1, ($2 +100)\n *\n * or the code can be changed to:\n *\n *  B foo\n *  LW $2, ($5 +10)\n *  LW $1, ($2 +100)\n *\n * The original code contained NOPs. I have removed these and moved\n * the branches.\n *\n * These changes result in a 35% speed increase when programming an\n * external flash.\n *\n * More improvement could be gained if the registers do no need\n * to be preserved but in that case the routines should be aware\n * OpenOCD is used as a flash programmer or as a debug tool.\n *\n * Nico Coesel\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/align.h>\n#include <helper/time_support.h>\n#include <jtag/adapter.h>\n\n#include \"mips32.h\"\n#include \"mips32_pracc.h\"\n\nstatic int wait_for_pracc_rw(struct mips_ejtag *ejtag_info)\n{\n\tint64_t then = timeval_ms();\n\n\t/* wait for the PrAcc to become \"1\" */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\n\twhile (1) {\n\t\tejtag_info->pa_ctrl = ejtag_info->ejtag_ctrl;\n\t\tint retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_info->pa_ctrl);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (ejtag_info->pa_ctrl & EJTAG_CTRL_PRACC)\n\t\t\tbreak;\n\n\t\tint64_t timeout = timeval_ms() - then;\n\t\tif (timeout > 1000) {\n\t\t\tLOG_DEBUG(\"DEBUGMODULE: No memory access in progress!\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Shift in control and address for a new processor access, save them in ejtag_info */\nstatic int mips32_pracc_read_ctrl_addr(struct mips_ejtag *ejtag_info)\n{\n\tint retval = wait_for_pracc_rw(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\n\tejtag_info->pa_addr = 0;\n\treturn  mips_ejtag_drscan_32(ejtag_info, &ejtag_info->pa_addr);\n}\n\n/* Finish processor access */\nstatic void mips32_pracc_finish(struct mips_ejtag *ejtag_info)\n{\n\tuint32_t ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tmips_ejtag_drscan_32_out(ejtag_info, ctrl);\n}\n\nstatic int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)\n{\n\tuint32_t jt_code = MIPS32_J(ejtag_info->isa, MIPS32_PRACC_TEXT);\n\tpracc_swap16_array(ejtag_info, &jt_code, 1);\n\t/* do 3 0/nops to clean pipeline before a jump to pracc text, NOP in delay slot */\n\tfor (int i = 0; i != 5; i++) {\n\t\t/* Wait for pracc */\n\t\tint retval = wait_for_pracc_rw(ejtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Data or instruction out */\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\t\tuint32_t data = (i == 3) ? jt_code : MIPS32_NOP;\n\t\tmips_ejtag_drscan_32_out(ejtag_info, data);\n\n\t\t/* finish pa */\n\t\tmips32_pracc_finish(ejtag_info);\n\t}\n\n\tif (ejtag_info->mode != 0)\t/* async mode support only for MIPS ... */\n\t\treturn ERROR_OK;\n\n\tfor (int i = 0; i != 2; i++) {\n\t\tint retval = mips32_pracc_read_ctrl_addr(ejtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (ejtag_info->pa_addr != MIPS32_PRACC_TEXT) {\t/* LEXRA/BMIPS ?, shift out another NOP, max 2 */\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\t\t\tmips_ejtag_drscan_32_out(ejtag_info, MIPS32_NOP);\n\t\t\tmips32_pracc_finish(ejtag_info);\n\t\t} else\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,\n\t\t\t\t\tuint32_t *param_out, bool check_last)\n{\n\tint code_count = 0;\n\tint store_pending = 0;\t\t/* increases with every store instr at dmseg, decreases with every store pa */\n\tuint32_t max_store_addr = 0;\t/* for store pa address testing */\n\tbool restart = 0;\t\t/* restarting control */\n\tint restart_count = 0;\n\tuint32_t instr = 0;\n\tbool final_check = 0;\t\t/* set to 1 if in final checks after function code shifted out */\n\tbool pass = 0;\t\t\t/* to check the pass through pracc text after function code sent */\n\tint retval;\n\n\twhile (1) {\n\t\tif (restart) {\n\t\t\tif (restart_count < 3) {\t\t\t\t\t/* max 3 restarts allowed */\n\t\t\t\tretval = mips32_pracc_clean_text_jump(ejtag_info);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else\n\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\trestart_count++;\n\t\t\trestart = 0;\n\t\t\tcode_count = 0;\n\t\t\tLOG_DEBUG(\"restarting code\");\n\t\t}\n\n\t\tretval = mips32_pracc_read_ctrl_addr(ejtag_info); /* update current pa info: control and address */\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Check for read or write access */\n\t\tif (ejtag_info->pa_ctrl & EJTAG_CTRL_PRNW) {\t\t\t\t/* write/store access */\n\t\t\t/* Check for pending store from a previous store instruction at dmseg */\n\t\t\tif (store_pending == 0) {\n\t\t\t\tLOG_DEBUG(\"unexpected write at address %\" PRIx32, ejtag_info->pa_addr);\n\t\t\t\tif (code_count < 2) {\t/* allow for restart */\n\t\t\t\t\trestart = 1;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else\n\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t} else {\n\t\t\t\t/* check address */\n\t\t\t\tif (ejtag_info->pa_addr < MIPS32_PRACC_PARAM_OUT ||\n\t\t\t\t\t\tejtag_info->pa_addr > max_store_addr) {\n\t\t\t\t\tLOG_DEBUG(\"writing at unexpected address %\" PRIx32, ejtag_info->pa_addr);\n\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* read data */\n\t\t\tuint32_t data = 0;\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\t\t\tretval = mips_ejtag_drscan_32(ejtag_info, &data);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* store data at param out, address based offset */\n\t\t\tparam_out[(ejtag_info->pa_addr - MIPS32_PRACC_PARAM_OUT) / 4] = data;\n\t\t\tstore_pending--;\n\n\t\t} else {\t\t\t\t\t/* read/fetch access */\n\t\t\t if (!final_check) {\t\t\t/* executing function code */\n\t\t\t\t/* check address */\n\t\t\t\tif (ejtag_info->pa_addr != (MIPS32_PRACC_TEXT + code_count * 4)) {\n\t\t\t\t\tLOG_DEBUG(\"reading at unexpected address %\" PRIx32 \", expected %x\",\n\t\t\t\t\t\t\tejtag_info->pa_addr, MIPS32_PRACC_TEXT + code_count * 4);\n\n\t\t\t\t\t/* restart code execution only in some cases */\n\t\t\t\t\tif (code_count == 1 && ejtag_info->pa_addr == MIPS32_PRACC_TEXT &&\n\t\t\t\t\t\t\t\t\t\trestart_count == 0) {\n\t\t\t\t\t\tLOG_DEBUG(\"restarting, without clean jump\");\n\t\t\t\t\t\trestart_count++;\n\t\t\t\t\t\tcode_count = 0;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else if (code_count < 2) {\n\t\t\t\t\t\trestart = 1;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t}\n\t\t\t\t/* check for store instruction at dmseg */\n\t\t\t\tuint32_t store_addr = ctx->pracc_list[code_count].addr;\n\t\t\t\tif (store_addr != 0) {\n\t\t\t\t\tif (store_addr > max_store_addr)\n\t\t\t\t\t\tmax_store_addr = store_addr;\n\t\t\t\t\tstore_pending++;\n\t\t\t\t}\n\n\t\t\t\tinstr = ctx->pracc_list[code_count++].instr;\n\t\t\t\tif (code_count == ctx->code_count)\t/* last instruction, start final check */\n\t\t\t\t\tfinal_check = 1;\n\n\t\t\t } else {\t/* final check after function code shifted out */\n\t\t\t\t\t/* check address */\n\t\t\t\tif (ejtag_info->pa_addr == MIPS32_PRACC_TEXT) {\n\t\t\t\t\tif (!pass) {\t/* first pass through pracc text */\n\t\t\t\t\t\tif (store_pending == 0)\t\t/* done, normal exit */\n\t\t\t\t\t\t\treturn ERROR_OK;\n\t\t\t\t\t\tpass = 1;\t\t/* pracc text passed */\n\t\t\t\t\t\tcode_count = 0;\t\t/* restart code count */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tLOG_DEBUG(\"unexpected second pass through pracc text\");\n\t\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (ejtag_info->pa_addr != (MIPS32_PRACC_TEXT + code_count * 4)) {\n\t\t\t\t\t\tLOG_DEBUG(\"unexpected read address in final check: %\"\n\t\t\t\t\t\t\tPRIx32 \", expected: %x\", ejtag_info->pa_addr,\n\t\t\t\t\t\t\tMIPS32_PRACC_TEXT + code_count * 4);\n\t\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!pass) {\n\t\t\t\t\tif ((code_count - ctx->code_count) > 1) { /* allow max 2 instr delay slot */\n\t\t\t\t\t\tLOG_DEBUG(\"failed to jump back to pracc text\");\n\t\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t}\n\t\t\t\t} else\n\t\t\t\t\tif (code_count > 10) {\t\t/* enough, abandon */\n\t\t\t\t\t\tLOG_DEBUG(\"execution abandoned, store pending: %d\", store_pending);\n\t\t\t\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t\t\t\t}\n\t\t\t\tinstr = MIPS32_NOP;\t/* shift out NOPs instructions */\n\t\t\t\tcode_count++;\n\t\t\t }\n\n\t\t\t/* Send instruction out */\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\t\t\tmips_ejtag_drscan_32_out(ejtag_info, instr);\n\t\t}\n\t\t/* finish processor access, let the processor eat! */\n\t\tmips32_pracc_finish(ejtag_info);\n\n\t\tif (final_check && !check_last)\t\t\t/* last instr, don't check, execute and exit */\n\t\t\treturn jtag_execute_queue();\n\n\t\tif (store_pending == 0 && pass) {\t/* store access done, but after passing pracc text */\n\t\t\tLOG_DEBUG(\"warning: store access pass pracc text\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n}\n\ninline void pracc_queue_init(struct pracc_queue_info *ctx)\n{\n\tctx->retval = ERROR_OK;\n\tctx->code_count = 0;\n\tctx->store_count = 0;\n\tctx->max_code = 0;\n\tctx->pracc_list = NULL;\n\tctx->isa = ctx->ejtag_info->isa ? 1 : 0;\n}\n\nvoid pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr)\n{\n\tif (ctx->retval != ERROR_OK)\t/* On previous out of memory, return */\n\t\treturn;\n\tif (ctx->code_count == ctx->max_code) {\n\t\tvoid *p = realloc(ctx->pracc_list, sizeof(struct pa_list) * (ctx->max_code + PRACC_BLOCK));\n\t\tif (p) {\n\t\t\tctx->max_code += PRACC_BLOCK;\n\t\t\tctx->pracc_list = p;\n\t\t} else {\n\t\t\tctx->retval = ERROR_FAIL;\t/* Out of memory */\n\t\t\treturn;\n\t\t}\n\t}\n\tctx->pracc_list[ctx->code_count].instr = instr;\n\tctx->pracc_list[ctx->code_count++].addr = addr;\n\tif (addr)\n\t\tctx->store_count++;\n}\n\nstatic void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize)\n{\n\tif (LOWER16(data) == 0 && optimize)\n\t\tpracc_add(ctx, 0, MIPS32_LUI(ctx->isa, reg_num, UPPER16(data)));\t/* load only upper value */\n\telse if (UPPER16(data) == 0 && optimize)\n\t\tpracc_add(ctx, 0, MIPS32_ORI(ctx->isa, reg_num, 0, LOWER16(data)));\t/* load only lower */\n\telse {\n\t\tpracc_add(ctx, 0, MIPS32_LUI(ctx->isa, reg_num, UPPER16(data)));\t/* load upper and lower */\n\t\tpracc_add(ctx, 0, MIPS32_ORI(ctx->isa, reg_num, reg_num, LOWER16(data)));\n\t}\n}\n\ninline void pracc_queue_free(struct pracc_queue_info *ctx)\n{\n\tfree(ctx->pracc_list);\n}\n\nint mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,\n\t\t\t\t\tuint32_t *buf, bool check_last)\n{\n\tif (ctx->retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (ejtag_info->isa && ejtag_info->endianness)\n\t\tfor (int i = 0; i != ctx->code_count; i++)\n\t\t\tctx->pracc_list[i].instr = SWAP16(ctx->pracc_list[i].instr);\n\n\tif (ejtag_info->mode == 0)\n\t\treturn mips32_pracc_exec(ejtag_info, ctx, buf, check_last);\n\n\tunion scan_in {\n\t\tuint8_t scan_96[12];\n\t\tstruct {\n\t\t\tuint8_t ctrl[4];\n\t\t\tuint8_t data[4];\n\t\t\tuint8_t addr[4];\n\t\t} scan_32;\n\n\t} *scan_in = malloc(sizeof(union scan_in) * (ctx->code_count + ctx->store_count));\n\tif (!scan_in) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tunsigned num_clocks =\n\t\t((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000;\n\n\tuint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);\n\n\tint scan_count = 0;\n\tfor (int i = 0; i != ctx->code_count; i++) {\n\t\tjtag_add_clocks(num_clocks);\n\t\tmips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, ctx->pracc_list[i].instr,\n\t\t\t\t       scan_in[scan_count++].scan_96);\n\n\t\t/* Check store address from previous instruction, if not the first */\n\t\tif (i > 0 && ctx->pracc_list[i - 1].addr) {\n\t\t\tjtag_add_clocks(num_clocks);\n\t\t\tmips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, 0, scan_in[scan_count++].scan_96);\n\t\t}\n\t}\n\n\tint retval = jtag_execute_queue();\t\t/* execute queued scans */\n\tif (retval != ERROR_OK)\n\t\tgoto exit;\n\n\tuint32_t fetch_addr = MIPS32_PRACC_TEXT;\t\t/* start address */\n\tscan_count = 0;\n\tfor (int i = 0; i != ctx->code_count; i++) {\t\t\t\t/* verify every pracc access */\n\t\t/* check pracc bit */\n\t\tejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);\n\t\tuint32_t addr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);\n\t\tif (!(ejtag_ctrl & EJTAG_CTRL_PRACC)) {\n\t\t\tLOG_ERROR(\"Error: access not pending  count: %d\", scan_count);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t\tif (ejtag_ctrl & EJTAG_CTRL_PRNW) {\n\t\t\tLOG_ERROR(\"Not a fetch/read access, count: %d\", scan_count);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t\tif (addr != fetch_addr) {\n\t\t\tLOG_ERROR(\"Fetch addr mismatch, read: %\" PRIx32 \" expected: %\" PRIx32 \" count: %d\",\n\t\t\t\t\t  addr, fetch_addr, scan_count);\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto exit;\n\t\t}\n\t\tfetch_addr += 4;\n\t\tscan_count++;\n\n\t\t/* check if previous instruction is a store instruction at dmesg */\n\t\tif (i > 0 && ctx->pracc_list[i - 1].addr) {\n\t\t\tuint32_t store_addr = ctx->pracc_list[i - 1].addr;\n\t\t\tejtag_ctrl = buf_get_u32(scan_in[scan_count].scan_32.ctrl, 0, 32);\n\t\t\taddr = buf_get_u32(scan_in[scan_count].scan_32.addr, 0, 32);\n\n\t\t\tif (!(ejtag_ctrl & EJTAG_CTRL_PRNW)) {\n\t\t\t\tLOG_ERROR(\"Not a store/write access, count: %d\", scan_count);\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto exit;\n\t\t\t}\n\t\t\tif (addr != store_addr) {\n\t\t\t\tLOG_ERROR(\"Store address mismatch, read: %\" PRIx32 \" expected: %\" PRIx32 \" count: %d\",\n\t\t\t\t\t\t\t      addr, store_addr, scan_count);\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto exit;\n\t\t\t}\n\t\t\tint buf_index = (addr - MIPS32_PRACC_PARAM_OUT) / 4;\n\t\t\tbuf[buf_index] = buf_get_u32(scan_in[scan_count].scan_32.data, 0, 32);\n\t\t\tscan_count++;\n\t\t}\n\t}\nexit:\n\tfree(scan_in);\n\treturn retval;\n}\n\nstatic int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR));\t/* $15 = MIPS32_PRACC_BASE_ADDR */\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16((addr + 0x8000)))); /* load  $8 with modified upper addr */\n\tpracc_add(&ctx, 0, MIPS32_LW(ctx.isa, 8, LOWER16(addr), 8));\t\t\t/* lw $8, LOWER16(addr)($8) */\n\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,\n\t\t\t\tMIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15));\t/* sw $8,PRACC_OUT_OFFSET($15) */\n\tpracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);\t\t\t\t/* restore $8 */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t\t/* move COP0 DeSave to $15 */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf, 1);\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\nint mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)\n{\n\tif (count == 1 && size == 4)\n\t\treturn mips32_pracc_read_u32(ejtag_info, addr, (uint32_t *)buf);\n\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tuint32_t *data = NULL;\n\tif (size != 4) {\n\t\tdata = malloc(256 * sizeof(uint32_t));\n\t\tif (!data) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tgoto exit;\n\t\t}\n\t}\n\n\tuint32_t *buf32 = buf;\n\tuint16_t *buf16 = buf;\n\tuint8_t *buf8 = buf;\n\n\twhile (count) {\n\t\tctx.code_count = 0;\n\t\tctx.store_count = 0;\n\n\t\tint this_round_count = (count > 256) ? 256 : count;\n\t\tuint32_t last_upper_base_addr = UPPER16((addr + 0x8000));\n\n\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */\n\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 9, last_upper_base_addr));\t/* upper memory addr to $9 */\n\n\t\tfor (int i = 0; i != this_round_count; i++) {\t\t\t/* Main code loop */\n\t\t\tuint32_t upper_base_addr = UPPER16((addr + 0x8000));\n\t\t\tif (last_upper_base_addr != upper_base_addr) {\t/* if needed, change upper addr in $9 */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 9, upper_base_addr));\n\t\t\t\tlast_upper_base_addr = upper_base_addr;\n\t\t\t}\n\n\t\t\tif (size == 4)\t\t\t\t/* load from memory to $8 */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_LW(ctx.isa, 8, LOWER16(addr), 9));\n\t\t\telse if (size == 2)\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_LHU(ctx.isa, 8, LOWER16(addr), 9));\n\t\t\telse\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_LBU(ctx.isa, 8, LOWER16(addr), 9));\n\n\t\t\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + i * 4,\t\t\t/* store $8 at param out */\n\t\t\t\t\t  MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + i * 4, 15));\n\t\t\taddr += size;\n\t\t}\n\t\tpracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);\t\t\t\t/* restore $8 */\n\t\tpracc_add_li32(&ctx, 9, ejtag_info->reg9, 0);\t\t\t\t/* restore $9 */\n\n\t\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t/* jump to start */\n\t\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t/* restore $15 from DeSave */\n\n\t\tif (size == 4) {\n\t\t\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32, 1);\n\t\t\tif (ctx.retval != ERROR_OK)\n\t\t\t\tgoto exit;\n\t\t\tbuf32 += this_round_count;\n\t\t} else {\n\t\t\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data, 1);\n\t\t\tif (ctx.retval != ERROR_OK)\n\t\t\t\tgoto exit;\n\n\t\t\tuint32_t *data_p = data;\n\t\t\tfor (int i = 0; i != this_round_count; i++) {\n\t\t\t\tif (size == 2)\n\t\t\t\t\t*buf16++ = *data_p++;\n\t\t\t\telse\n\t\t\t\t\t*buf8++ = *data_p++;\n\t\t\t}\n\t\t}\n\t\tcount -= this_round_count;\n\t}\nexit:\n\tpracc_queue_free(&ctx);\n\tfree(data);\n\treturn ctx.retval;\n}\n\nint mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR));\t/* $15 = MIPS32_PRACC_BASE_ADDR */\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, cp0_reg, cp0_sel));\t\t/* move cp0 reg / sel to $8 */\n\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,\n\t\t\t\tMIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15));\t/* store $8 to pracc_out */\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t\t/* restore $15 from DeSave */\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8)));\t/* restore upper 16 bits  of $8 */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1);\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\nint mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tpracc_add_li32(&ctx, 15, val, 0);\t\t\t\t/* Load val to $15 */\n\n\tpracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, cp0_reg, cp0_sel));\t\t/* write $15 to cp0 reg / sel */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t/* restore $15 from DeSave */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\n/**\n * \\b mips32_pracc_sync_cache\n *\n * Synchronize Caches to Make Instruction Writes Effective\n * (ref. doc. MIPS32 Architecture For Programmers Volume II: The MIPS32 Instruction Set,\n *  Document Number: MD00086, Revision 2.00, June 9, 2003)\n *\n * When the instruction stream is written, the SYNCI instruction should be used\n * in conjunction with other instructions to make the newly-written instructions effective.\n *\n * Explanation :\n * A program that loads another program into memory is actually writing the D- side cache.\n * The instructions it has loaded can't be executed until they reach the I-cache.\n *\n * After the instructions have been written, the loader should arrange\n * to write back any containing D-cache line and invalidate any locations\n * already in the I-cache.\n *\n * If the cache coherency attribute (CCA) is set to zero, it's a write through cache, there is no need\n * to write back.\n *\n * In the latest MIPS32/64 CPUs, MIPS provides the synci instruction,\n * which does the whole job for a cache-line-sized chunk of the memory you just loaded:\n * That is, it arranges a D-cache write-back (if CCA = 3) and an I-cache invalidate.\n *\n * The line size is obtained with the rdhwr SYNCI_Step in release 2 or from cp0 config 1 register in release 1.\n */\nstatic int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,\n\t\t\t\t\t uint32_t start_addr, uint32_t end_addr, int cached, int rel)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\t/** Find cache line size in bytes */\n\tuint32_t clsiz;\n\tif (rel) {\t/* Release 2 (rel = 1) */\n\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, PRACC_UPPER_BASE_ADDR)); /* $15 = MIPS32_PRACC_BASE_ADDR */\n\n\t\tpracc_add(&ctx, 0, MIPS32_RDHWR(ctx.isa, 8, MIPS32_SYNCI_STEP)); /* load synci_step value to $8 */\n\n\t\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,\n\t\t\t\tMIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 15));\t\t/* store $8 to pracc_out */\n\n\t\tpracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);\t\t\t\t/* restore $8 */\n\n\t\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t/* jump to start */\n\t\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t/* restore $15 from DeSave */\n\n\t\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz, 1);\n\t\tif (ctx.retval != ERROR_OK)\n\t\t\tgoto exit;\n\n\t} else {\t\t\t/* Release 1 (rel = 0) */\n\t\tuint32_t conf;\n\t\tctx.retval = mips32_cp0_read(ejtag_info, &conf, 16, 1);\n\t\tif (ctx.retval != ERROR_OK)\n\t\t\tgoto exit;\n\n\t\tuint32_t dl = (conf & MIPS32_CONFIG1_DL_MASK) >> MIPS32_CONFIG1_DL_SHIFT;\n\n\t\t/* dl encoding : dl=1 => 4 bytes, dl=2 => 8 bytes, etc... max dl=6 => 128 bytes cache line size */\n\t\tclsiz = 0x2 << dl;\n\t\tif (dl == 0)\n\t\t\tclsiz = 0;\n\t}\n\n\tif (clsiz == 0)\n\t\tgoto exit;  /* Nothing to do */\n\n\t/* make sure clsiz is power of 2 */\n\tif (!IS_PWR_OF_2(clsiz)) {\n\t\tLOG_DEBUG(\"clsiz must be power of 2\");\n\t\tctx.retval = ERROR_FAIL;\n\t\tgoto exit;\n\t}\n\n\t/* make sure start_addr and end_addr have the same offset inside de cache line */\n\tstart_addr |= clsiz - 1;\n\tend_addr |= clsiz - 1;\n\n\tctx.code_count = 0;\n\tctx.store_count = 0;\n\n\tint count = 0;\n\tuint32_t last_upper_base_addr = UPPER16((start_addr + 0x8000));\n\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, last_upper_base_addr)); /* load upper memory base addr to $15 */\n\n\twhile (start_addr <= end_addr) {\t\t\t\t\t\t/* main loop */\n\t\tuint32_t upper_base_addr = UPPER16((start_addr + 0x8000));\n\t\tif (last_upper_base_addr != upper_base_addr) {\t\t/* if needed, change upper addr in $15 */\n\t\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, upper_base_addr));\n\t\t\tlast_upper_base_addr = upper_base_addr;\n\t\t}\n\t\tif (rel)\t\t\t/* synci instruction, offset($15) */\n\t\t\tpracc_add(&ctx, 0, MIPS32_SYNCI(ctx.isa, LOWER16(start_addr), 15));\n\n\t\telse {\n\t\t\tif (cached == 3)\t/* cache Hit_Writeback_D, offset($15) */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_CACHE(ctx.isa, MIPS32_CACHE_D_HIT_WRITEBACK,\n\t\t\t\t\t\t\tLOWER16(start_addr), 15));\n\t\t\t/* cache Hit_Invalidate_I, offset($15) */\n\t\t\tpracc_add(&ctx, 0, MIPS32_CACHE(ctx.isa, MIPS32_CACHE_I_HIT_INVALIDATE,\n\t\t\t\t\t\t\tLOWER16(start_addr), 15));\n\t\t}\n\t\tstart_addr += clsiz;\n\t\tcount++;\n\t\tif (count == 256 && start_addr <= end_addr) {\t\t\t/* more ?, then execute code list */\n\t\t\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t/* to start */\n\t\t\tpracc_add(&ctx, 0, MIPS32_NOP);\t\t\t\t\t/* nop in delay slot */\n\n\t\t\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\n\t\t\tif (ctx.retval != ERROR_OK)\n\t\t\t\tgoto exit;\n\n\t\t\tctx.code_count = 0;\t/* reset counters for another loop */\n\t\t\tctx.store_count = 0;\n\t\t\tcount = 0;\n\t\t}\n\t}\n\tpracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa));\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t\t/* restore $15 from DeSave*/\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\nexit:\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\nstatic int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int size, int count, const void *buf)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tconst uint32_t *buf32 = buf;\n\tconst uint16_t *buf16 = buf;\n\tconst uint8_t *buf8 = buf;\n\n\twhile (count) {\n\t\tctx.code_count = 0;\n\t\tctx.store_count = 0;\n\n\t\tint this_round_count = (count > 128) ? 128 : count;\n\t\tuint32_t last_upper_base_addr = UPPER16((addr + 0x8000));\n\t\t\t      /* load $15 with memory base address */\n\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, last_upper_base_addr));\n\n\t\tfor (int i = 0; i != this_round_count; i++) {\n\t\t\tuint32_t upper_base_addr = UPPER16((addr + 0x8000));\n\t\t\tif (last_upper_base_addr != upper_base_addr) {\t/* if needed, change upper address in $15*/\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 15, upper_base_addr));\n\t\t\t\tlast_upper_base_addr = upper_base_addr;\n\t\t\t}\n\n\t\t\tif (size == 4) {\n\t\t\t\tpracc_add_li32(&ctx, 8, *buf32, 1);\t\t/* load with li32, optimize */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_SW(ctx.isa, 8, LOWER16(addr), 15)); /* store word to mem */\n\t\t\t\tbuf32++;\n\n\t\t\t} else if (size == 2) {\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 0, *buf16));\t\t/* load lower value */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_SH(ctx.isa, 8, LOWER16(addr), 15)); /* store half word */\n\t\t\t\tbuf16++;\n\n\t\t\t} else {\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 0, *buf8));\t\t/* load lower value */\n\t\t\t\tpracc_add(&ctx, 0, MIPS32_SB(ctx.isa, 8, LOWER16(addr), 15));\t/* store byte */\n\t\t\t\tbuf8++;\n\t\t\t}\n\t\t\taddr += size;\n\t\t}\n\n\t\tpracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);\t\t\t\t/* restore $8 */\n\n\t\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t/* jump to start */\n\t\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 15, 31, 0));\t\t\t/* restore $15 from DeSave */\n\n\t\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\n\t\tif (ctx.retval != ERROR_OK)\n\t\t\tgoto exit;\n\t\tcount -= this_round_count;\n\t}\nexit:\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\nint mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, const void *buf)\n{\n\tint retval = mips32_pracc_write_mem_generic(ejtag_info, addr, size, count, buf);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/**\n\t * If we are in the cacheable region and cache is activated,\n\t * we must clean D$ (if Cache Coherency Attribute is set to 3) + invalidate I$ after we did the write,\n\t * so that changes do not continue to live only in D$ (if CCA = 3), but to be\n\t * replicated in I$ also (maybe we wrote the instructions)\n\t */\n\tuint32_t conf = 0;\n\tint cached = 0;\n\n\tif ((KSEGX(addr) == KSEG1) || ((addr >= 0xff200000) && (addr <= 0xff3fffff)))\n\t\treturn retval; /*Nothing to do*/\n\n\tmips32_cp0_read(ejtag_info, &conf, 16, 0);\n\n\tswitch (KSEGX(addr)) {\n\t\tcase KUSEG:\n\t\t\tcached = (conf & MIPS32_CONFIG0_KU_MASK) >> MIPS32_CONFIG0_KU_SHIFT;\n\t\t\tbreak;\n\t\tcase KSEG0:\n\t\t\tcached = (conf & MIPS32_CONFIG0_K0_MASK) >> MIPS32_CONFIG0_K0_SHIFT;\n\t\t\tbreak;\n\t\tcase KSEG2:\n\t\tcase KSEG3:\n\t\t\tcached = (conf & MIPS32_CONFIG0_K23_MASK) >> MIPS32_CONFIG0_K23_SHIFT;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\t/* what ? */\n\t\t\tbreak;\n\t}\n\n\t/**\n\t * Check cacheability bits coherency algorithm\n\t * is the region cacheable or uncached.\n\t * If cacheable we have to synchronize the cache\n\t */\n\tif (cached == 3 || cached == 0) {\t\t/* Write back cache or write through cache */\n\t\tuint32_t start_addr = addr;\n\t\tuint32_t end_addr = addr + count * size;\n\t\tuint32_t rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT;\n\t\tif (rel > 1) {\n\t\t\tLOG_DEBUG(\"Unknown release in cache code\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tretval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, end_addr, cached, rel);\n\t}\n\n\treturn retval;\n}\n\nint mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tuint32_t cp0_write_code[] = {\n\t\tMIPS32_MTC0(ctx.isa, 1, 12, 0),\t\t\t\t\t/* move $1 to status */\n\t\tMIPS32_MTLO(ctx.isa, 1),\t\t\t\t\t\t/* move $1 to lo */\n\t\tMIPS32_MTHI(ctx.isa, 1),\t\t\t\t\t\t/* move $1 to hi */\n\t\tMIPS32_MTC0(ctx.isa, 1, 8, 0),\t\t\t\t\t/* move $1 to badvaddr */\n\t\tMIPS32_MTC0(ctx.isa, 1, 13, 0),\t\t\t\t\t/* move $1 to cause*/\n\t\tMIPS32_MTC0(ctx.isa, 1, 24, 0),\t\t\t\t\t/* move $1 to depc (pc) */\n\t};\n\n\t/* load registers 2 to 31 with li32, optimize */\n\tfor (int i = 2; i < 32; i++)\n\t\tpracc_add_li32(&ctx, i, regs[i], 1);\n\n\tfor (int i = 0; i != 6; i++) {\n\t\tpracc_add_li32(&ctx, 1, regs[i + 32], 0);\t/* load CPO value in $1 */\n\t\tpracc_add(&ctx, 0, cp0_write_code[i]);\t\t\t/* write value from $1 to CPO register */\n\t}\n\tpracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));\t\t\t\t/* load $15 in DeSave */\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, UPPER16((regs[1]))));\t\t/* load upper half word in $1 */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 1, 1, LOWER16((regs[1]))));\t/* load lower half word in $1 */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\n\n\tejtag_info->reg8 = regs[8];\n\tejtag_info->reg9 = regs[9];\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\nint mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tuint32_t cp0_read_code[] = {\n\t\tMIPS32_MFC0(ctx.isa, 8, 12, 0),\t\t\t\t\t/* move status to $8 */\n\t\tMIPS32_MFLO(ctx.isa, 8),\t\t\t\t\t\t/* move lo to $8 */\n\t\tMIPS32_MFHI(ctx.isa, 8),\t\t\t\t\t\t/* move hi to $8 */\n\t\tMIPS32_MFC0(ctx.isa, 8, 8, 0),\t\t\t\t\t/* move badvaddr to $8 */\n\t\tMIPS32_MFC0(ctx.isa, 8, 13, 0),\t\t\t\t\t/* move cause to $8 */\n\t\tMIPS32_MFC0(ctx.isa, 8, 24, 0),\t\t\t\t\t/* move depc (pc) to $8 */\n\t};\n\n\tpracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 1, 31, 0));\t\t\t\t/* move $1 to COP0 DeSave */\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 1, PRACC_UPPER_BASE_ADDR));\t/* $1 = MIP32_PRACC_BASE_ADDR */\n\n\tfor (int i = 2; i != 32; i++)\t\t\t\t\t/* store GPR's 2 to 31 */\n\t\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i * 4),\n\t\t\t\t  MIPS32_SW(ctx.isa, i, PRACC_OUT_OFFSET + (i * 4), 1));\n\n\tfor (int i = 0; i != 6; i++) {\n\t\tpracc_add(&ctx, 0, cp0_read_code[i]);\t\t\t\t/* load COP0 needed registers to $8 */\n\t\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i + 32) * 4,\t\t\t/* store $8 at PARAM OUT */\n\t\t\t\t  MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + (i + 32) * 4, 1));\n\t}\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 31, 0));\t\t\t/* move DeSave to $8, reg1 value */\n\tpracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + 4,\t\t\t/* store reg1 value from $8 to param out */\n\t\t\t  MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET + 4, 1));\n\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 1, 31, 0));\t\t/* move COP0 DeSave to $1, restore reg1 */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, 31, 0));\t\t\t\t/* load $15 in DeSave */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs, 1);\n\n\tejtag_info->reg8 = regs[8];\t/* reg8 is saved but not restored, next called function should restore it */\n\tejtag_info->reg9 = regs[9];\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\n/* fastdata upload/download requires an initialized working area\n * to load the download code; it should not be called otherwise\n * fetch order from the fastdata area\n * 1. start addr\n * 2. end addr\n * 3. data ...\n */\nint mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,\n\t\tint write_t, uint32_t addr, int count, uint32_t *buf)\n{\n\tuint32_t isa = ejtag_info->isa ? 1 : 0;\n\tuint32_t handler_code[] = {\n\t\t/* r15 points to the start of this code */\n\t\tMIPS32_SW(isa, 8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),\n\t\tMIPS32_SW(isa, 9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),\n\t\tMIPS32_SW(isa, 10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),\n\t\tMIPS32_SW(isa, 11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),\n\t\t/* start of fastdata area in t0 */\n\t\tMIPS32_LUI(isa, 8, UPPER16(MIPS32_PRACC_FASTDATA_AREA)),\n\t\tMIPS32_ORI(isa, 8, 8, LOWER16(MIPS32_PRACC_FASTDATA_AREA)),\n\t\tMIPS32_LW(isa, 9, 0, 8),\t\t\t\t\t\t/* start addr in t1 */\n\t\tMIPS32_LW(isa, 10, 0, 8),\t\t\t\t\t\t/* end addr to t2 */\n\t\t\t\t\t/* loop: */\n\t\twrite_t ? MIPS32_LW(isa, 11, 0, 8) : MIPS32_LW(isa, 11, 0, 9),\t/* from xfer area : from memory */\n\t\twrite_t ? MIPS32_SW(isa, 11, 0, 9) : MIPS32_SW(isa, 11, 0, 8),\t/* to memory      : to xfer area */\n\n\t\tMIPS32_BNE(isa, 10, 9, NEG16(3 << isa)),\t\t\t/* bne $t2,t1,loop */\n\t\tMIPS32_ADDI(isa, 9, 9, 4),\t\t\t\t\t/* addi t1,t1,4 */\n\n\t\tMIPS32_LW(isa, 8, MIPS32_FASTDATA_HANDLER_SIZE - 4, 15),\n\t\tMIPS32_LW(isa, 9, MIPS32_FASTDATA_HANDLER_SIZE - 8, 15),\n\t\tMIPS32_LW(isa, 10, MIPS32_FASTDATA_HANDLER_SIZE - 12, 15),\n\t\tMIPS32_LW(isa, 11, MIPS32_FASTDATA_HANDLER_SIZE - 16, 15),\n\n\t\tMIPS32_LUI(isa, 15, UPPER16(MIPS32_PRACC_TEXT)),\n\t\tMIPS32_ORI(isa, 15, 15, LOWER16(MIPS32_PRACC_TEXT) | isa),\t/* isa bit for JR instr */\n\t\tMIPS32_JR(isa, 15),\t\t\t\t\t\t\t\t/* jr start */\n\t\tMIPS32_MFC0(isa, 15, 31, 0),\t\t\t\t\t/* move COP0 DeSave to $15 */\n\t};\n\n\tif (source->size < MIPS32_FASTDATA_HANDLER_SIZE)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tpracc_swap16_array(ejtag_info, handler_code, ARRAY_SIZE(handler_code));\n\t\t/* write program into RAM */\n\tif (write_t != ejtag_info->fast_access_save) {\n\t\tmips32_pracc_write_mem(ejtag_info, source->address, 4, ARRAY_SIZE(handler_code), handler_code);\n\t\t/* save previous operation to speed to any consecutive read/writes */\n\t\tejtag_info->fast_access_save = write_t;\n\t}\n\n\tLOG_DEBUG(\"%s using 0x%.8\" TARGET_PRIxADDR \" for write handler\", __func__, source->address);\n\n\tuint32_t jmp_code[] = {\n\t\tMIPS32_LUI(isa, 15, UPPER16(source->address)),\t\t\t/* load addr of jump in $15 */\n\t\tMIPS32_ORI(isa, 15, 15, LOWER16(source->address) | isa),\t/* isa bit for JR instr */\n\t\tMIPS32_JR(isa, 15),\t\t\t\t\t\t/* jump to ram program */\n\t\tisa ? MIPS32_XORI(isa, 15, 15, 1) : MIPS32_NOP,\t/* drop isa bit, needed for LW/SW instructions */\n\t};\n\n\tpracc_swap16_array(ejtag_info, jmp_code, ARRAY_SIZE(jmp_code));\n\n\t/* execute jump code, with no address check */\n\tfor (unsigned i = 0; i < ARRAY_SIZE(jmp_code); i++) {\n\t\tint retval = wait_for_pracc_rw(ejtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);\n\t\tmips_ejtag_drscan_32_out(ejtag_info, jmp_code[i]);\n\n\t\t/* Clear the access pending bit (let the processor eat!) */\n\t\tmips32_pracc_finish(ejtag_info);\n\t}\n\n\t/* wait PrAcc pending bit for FASTDATA write, read address */\n\tint retval = mips32_pracc_read_ctrl_addr(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* next fetch to dmseg should be in FASTDATA_AREA, check */\n\tif (ejtag_info->pa_addr != MIPS32_PRACC_FASTDATA_AREA)\n\t\treturn ERROR_FAIL;\n\n\t/* Send the load start address */\n\tuint32_t val = addr;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);\n\tmips_ejtag_fastdata_scan(ejtag_info, 1, &val);\n\n\tretval = wait_for_pracc_rw(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Send the load end address */\n\tval = addr + (count - 1) * 4;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);\n\tmips_ejtag_fastdata_scan(ejtag_info, 1, &val);\n\n\tunsigned num_clocks = 0;\t/* like in legacy code */\n\tif (ejtag_info->mode != 0)\n\t\tnum_clocks = ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000;\n\n\tfor (int i = 0; i < count; i++) {\n\t\tjtag_add_clocks(num_clocks);\n\t\tmips_ejtag_fastdata_scan(ejtag_info, write_t, buf++);\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"fastdata load failed\");\n\t\treturn retval;\n\t}\n\n\tretval = mips32_pracc_read_ctrl_addr(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (ejtag_info->pa_addr != MIPS32_PRACC_TEXT)\n\t\tLOG_ERROR(\"mini program did not return to start\");\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips32_pracc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_MIPS32_PRACC_H\n#define OPENOCD_TARGET_MIPS32_PRACC_H\n\n#include <target/mips32.h>\n#include <target/mips_ejtag.h>\n\n#define MIPS32_PRACC_FASTDATA_AREA\t\t0xFF200000\n#define MIPS32_PRACC_FASTDATA_SIZE\t\t16\n#define MIPS32_PRACC_BASE_ADDR\t\t\t0xFF200000\n#define MIPS32_PRACC_TEXT\t\t\t0xFF200200\n#define MIPS32_PRACC_PARAM_OUT\t\t\t0xFF202000\n\n#define PRACC_UPPER_BASE_ADDR\t\t\t(MIPS32_PRACC_BASE_ADDR >> 16)\n#define PRACC_MAX_CODE\t\t\t\t(MIPS32_PRACC_PARAM_OUT - MIPS32_PRACC_TEXT)\n#define PRACC_MAX_INSTRUCTIONS\t\t\t(PRACC_MAX_CODE / 4)\n#define PRACC_OUT_OFFSET\t\t\t(MIPS32_PRACC_PARAM_OUT - MIPS32_PRACC_BASE_ADDR)\n\n#define MIPS32_FASTDATA_HANDLER_SIZE\t\t0x80\n#define UPPER16(addr)\t\t\t\t((addr) >> 16)\n#define LOWER16(addr)\t\t\t\t((addr) & 0xFFFF)\n#define NEG16(v)\t\t\t\t(((~(v)) + 1) & 0xFFFF)\n#define SWAP16(v)\t\t\t\t((LOWER16(v) << 16) | (UPPER16(v)))\n/*#define NEG18(v) (((~(v)) + 1) & 0x3FFFF)*/\n\n#define PRACC_BLOCK\t128\t/* 1 Kbyte */\n\nstruct pa_list {\n\tuint32_t instr;\n\tuint32_t addr;\n};\n\nstruct pracc_queue_info {\n\tstruct mips_ejtag *ejtag_info;\n\tunsigned isa;\n\tint retval;\n\tint code_count;\n\tint store_count;\n\tint max_code;\t\t/* max instructions with currently allocated memory */\n\tstruct pa_list *pracc_list;\t/* Code and store addresses at dmseg */\n};\n\nvoid pracc_queue_init(struct pracc_queue_info *ctx);\nvoid pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr);\nvoid pracc_queue_free(struct pracc_queue_info *ctx);\nint mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info,\n\t\t\t    struct pracc_queue_info *ctx, uint32_t *buf, bool check_last);\n\nint mips32_pracc_read_mem(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int size, int count, void *buf);\nint mips32_pracc_write_mem(struct mips_ejtag *ejtag_info,\n\t\tuint32_t addr, int size, int count, const void *buf);\nint mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,\n\t\tint write_t, uint32_t addr, int count, uint32_t *buf);\n\nint mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);\nint mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);\n\n/**\n * \\b mips32_cp0_read\n *\n * Simulates mfc0 ASM instruction (Move From C0),\n * i.e. implements copro C0 Register read.\n *\n * @param[in] ejtag_info\n * @param[in] val Storage to hold read value\n * @param[in] cp0_reg Number of copro C0 register we want to read\n * @param[in] cp0_sel Select for the given C0 register\n *\n * @return ERROR_OK on Success, ERROR_FAIL otherwise\n */\nint mips32_cp0_read(struct mips_ejtag *ejtag_info,\n\t\tuint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel);\n\n/**\n * \\b mips32_cp0_write\n *\n * Simulates mtc0 ASM instruction (Move To C0),\n * i.e. implements copro C0 Register read.\n *\n * @param[in] ejtag_info\n * @param[in] val Value to be written\n * @param[in] cp0_reg Number of copro C0 register we want to write to\n * @param[in] cp0_sel Select for the given C0 register\n *\n * @return ERROR_OK on Success, ERROR_FAIL otherwise\n */\nint mips32_cp0_write(struct mips_ejtag *ejtag_info,\n\t\tuint32_t val, uint32_t cp0_reg, uint32_t cp0_sel);\n\nstatic inline void pracc_swap16_array(struct mips_ejtag *ejtag_info, uint32_t *buf, int count)\n{\n\tif (ejtag_info->isa && ejtag_info->endianness)\n\t\tfor (int i = 0; i != count; i++)\n\t\t\tbuf[i] = SWAP16(buf[i]);\n}\n\n#endif /* OPENOCD_TARGET_MIPS32_PRACC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips64.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Support for processors implementing MIPS64 instruction set\n *\n * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n * Copyright (C) 2014 by Antony Pavlov <antonynpavlov@gmail.com>\n * Copyright (C) 2014 by Peter Mamonov <pmamonov@gmail.com>\n *\n * Based on the work of:\n *   Copyright (C) 2008 by Spencer Oliver\n *   Copyright (C) 2008 by David T.L. Wong\n *   Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mips64.h\"\n\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n\tint flag;\n} mips64_regs[] = {\n\t{  0,  \"r0\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  1,  \"r1\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  2,  \"r2\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  3,  \"r3\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  4,  \"r4\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  5,  \"r5\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  6,  \"r6\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  7,  \"r7\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  8,  \"r8\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{  9,  \"r9\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 10, \"r10\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 11, \"r11\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 12, \"r12\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 13, \"r13\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 14, \"r14\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 15, \"r15\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 16, \"r16\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 17, \"r17\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 18, \"r18\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 19, \"r19\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 20, \"r20\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 21, \"r21\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 22, \"r22\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 23, \"r23\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 24, \"r24\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 25, \"r25\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 26, \"r26\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 27, \"r27\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 28, \"r28\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 29, \"r29\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 30, \"r30\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 31, \"r31\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 32, \"lo\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ 33, \"hi\", REG_TYPE_UINT64, NULL, \"org.gnu.gdb.mips.cpu\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 0, \"pc\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cpu\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 1, \"Random\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 2, \"Entrylo_0\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 3, \"Entrylo_1\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 4, \"Context\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 5, \"Pagemask\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 6, \"Wired\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 7, \"badvaddr\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 8, \"Count\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 9, \"EntryHi\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 10, \"Compare\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 11, \"status\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 12, \"cause\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 13, \"EPC\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 14, \"PrID\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 15, \"Config\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 16, \"LLA\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 17, \"WatchLo0\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 18, \"WatchLo1\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 19, \"WatchHi0\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 20, \"WatchHi1\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 21, \"Xcontext\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 22, \"ChipMemCtrl\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 23, \"Debug\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 24, \"Perfcount, sel=0\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 25, \"Perfcount, sel=1\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 26, \"Perfcount, sel=2\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 27, \"Perfcount, sel=3\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 28, \"ECC\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 29, \"CacheErr\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 30, \"TagLo\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 31, \"TagHi\", REG_TYPE_UINT32, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 32, \"DataHi\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_REGS + 33, \"EEPC\", REG_TYPE_UINT64, NULL,\n\t\t\"org.gnu.gdb.mips.cp0\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 0,  \"f0\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 1,  \"f1\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 2,  \"f2\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 3,  \"f3\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 4, \"f4\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 5,  \"f5\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 6,  \"f6\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 7,  \"f7\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 8,  \"f8\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 9,  \"f9\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 10, \"f10\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 11, \"f11\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 12, \"f12\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 13, \"f13\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 14, \"f14\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 15, \"f15\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 16, \"f16\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 17, \"f17\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 18, \"f18\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 19, \"f19\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 20, \"f20\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 21, \"f21\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 22, \"f22\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 23, \"f23\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 24, \"f24\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 25, \"f25\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 26, \"f26\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 27, \"f27\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 28, \"f28\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 29, \"f29\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 30, \"f30\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 31, \"f31\", REG_TYPE_IEEE_DOUBLE, NULL,\n\t\t \"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 32, \"fcsr\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 33, \"fir\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 34, \"fconfig\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 35, \"fccr\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 36, \"fexr\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n\t{ MIPS64_NUM_CORE_C0_REGS + 37, \"fenr\", REG_TYPE_INT, \"float\",\n\t\t\"org.gnu.gdb.mips.fpu\", 0 },\n};\n\nstatic int reg_type2size(enum reg_type type)\n{\n\tswitch (type) {\n\tcase REG_TYPE_UINT32:\n\tcase REG_TYPE_INT:\n\t\treturn 32;\n\tcase REG_TYPE_UINT64:\n\tcase REG_TYPE_IEEE_DOUBLE:\n\t\treturn 64;\n\tdefault:\n\t\treturn 64;\n\t}\n}\n\nstatic int mips64_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct mips64_core_reg *mips64_reg = reg->arch_info;\n\tstruct target *target = mips64_reg->target;\n\tstruct mips64_common *mips64_target = target->arch_info;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = mips64_target->read_core_reg(target, mips64_reg->num);\n\n\treturn retval;\n}\n\nstatic int mips64_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct mips64_core_reg *mips64_reg = reg->arch_info;\n\tstruct target *target = mips64_reg->target;\n\tuint64_t value = buf_get_u64(buf, 0, 64);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u64(reg->value, 0, 64, value);\n\treg->dirty = 1;\n\treg->valid = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips64_read_core_reg(struct target *target, int num)\n{\n\tuint64_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif ((num < 0) || (num >= MIPS64_NUM_REGS))\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treg_value = mips64->core_regs[num];\n\tbuf_set_u64(mips64->core_cache->reg_list[num].value, 0, 64, reg_value);\n\tmips64->core_cache->reg_list[num].valid = 1;\n\tmips64->core_cache->reg_list[num].dirty = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips64_write_core_reg(struct target *target, int num)\n{\n\tuint64_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif ((num < 0) || (num >= MIPS64_NUM_REGS))\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\treg_value = buf_get_u64(mips64->core_cache->reg_list[num].value, 0, 64);\n\tmips64->core_regs[num] = reg_value;\n\tLOG_DEBUG(\"write core reg %i value 0x%\" PRIx64 \"\", num, reg_value);\n\tmips64->core_cache->reg_list[num].valid = 1;\n\tmips64->core_cache->reg_list[num].dirty = 0;\n\n\treturn ERROR_OK;\n}\n\nint mips64_invalidate_core_regs(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tunsigned int i;\n\n\tfor (i = 0; i < mips64->core_cache->num_regs; i++) {\n\t\tmips64->core_cache->reg_list[i].valid = 0;\n\t\tmips64->core_cache->reg_list[i].dirty = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nint mips64_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\tint *reg_list_size, enum target_register_class reg_class)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tregister int i;\n\n\t/* include floating point registers */\n\t*reg_list_size = MIPS64_NUM_REGS;\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\tfor (i = 0; i < MIPS64_NUM_REGS; i++)\n\t\t(*reg_list)[i] = &mips64->core_cache->reg_list[i];\n\n\treturn ERROR_OK;\n}\n\nint mips64_save_context(struct target *target)\n{\n\tint retval;\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\n\tretval = mips64_pracc_read_regs(ejtag_info, mips64->core_regs);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (unsigned i = 0; i < MIPS64_NUM_REGS; i++)\n\t\t\tretval = mips64->read_core_reg(target, i);\n\n\treturn retval;\n}\n\nint mips64_restore_context(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\n\tfor (unsigned i = 0; i < MIPS64_NUM_REGS; i++) {\n\t\tif (mips64->core_cache->reg_list[i].dirty)\n\t\t\tmips64->write_core_reg(target, i);\n\t}\n\n\treturn mips64_pracc_write_regs(ejtag_info, mips64->core_regs);\n}\n\nint mips64_arch_state(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];\n\n\tif (mips64->common_magic != MIPS64_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-MIPS64 target\");\n\t\texit(-1);\n\t}\n\n\tLOG_USER(\"target halted due to %s, pc: 0x%\" PRIx64 \"\",\n\t\t debug_reason_name(target), buf_get_u64(pc->value, 0, 64));\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type mips64_reg_type = {\n\t.get = mips64_get_core_reg,\n\t.set = mips64_set_core_reg,\n};\n\nint mips64_build_reg_cache(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct reg_cache **cache_p, *cache;\n\tstruct mips64_core_reg *arch_info = NULL;\n\tstruct reg *reg_list = NULL;\n\tunsigned i;\n\n\tcache = calloc(1, sizeof(*cache));\n\tif (!cache) {\n\t\tLOG_ERROR(\"unable to allocate cache\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treg_list = calloc(MIPS64_NUM_REGS, sizeof(*reg_list));\n\tif (!reg_list) {\n\t\tLOG_ERROR(\"unable to allocate reg_list\");\n\t\tgoto alloc_fail;\n\t}\n\n\tarch_info = calloc(MIPS64_NUM_REGS, sizeof(*arch_info));\n\tif (!arch_info) {\n\t\tLOG_ERROR(\"unable to allocate arch_info\");\n\t\tgoto alloc_fail;\n\t}\n\n\tfor (i = 0; i < MIPS64_NUM_REGS; i++) {\n\t\tstruct mips64_core_reg *a = &arch_info[i];\n\t\tstruct reg *r = &reg_list[i];\n\n\t\tr->arch_info = &arch_info[i];\n\t\tr->caller_save = true;\t/* gdb defaults to true */\n\t\tr->exist = true;\n\t\tr->feature = &a->feature;\n\t\tr->feature->name = mips64_regs[i].feature;\n\t\tr->group = mips64_regs[i].group;\n\t\tr->name = mips64_regs[i].name;\n\t\tr->number = i;\n\t\tr->reg_data_type = &a->reg_data_type;\n\t\tr->reg_data_type->type = mips64_regs[i].type;\n\t\tr->size = reg_type2size(mips64_regs[i].type);\n\t\tr->type = &mips64_reg_type;\n\t\tr->value = &a->value[0];\n\n\t\ta->mips64_common = mips64;\n\t\ta->num = mips64_regs[i].id;\n\t\ta->target = target;\n\t}\n\n\tcache->name = \"mips64 registers\";\n\tcache->reg_list = reg_list;\n\tcache->num_regs = MIPS64_NUM_REGS;\n\n\tcache_p = register_get_last_cache_p(&target->reg_cache);\n\t(*cache_p) = cache;\n\n\tmips64->core_cache = cache;\n\n\treturn ERROR_OK;\n\nalloc_fail:\n\tfree(cache);\n\tfree(reg_list);\n\tfree(arch_info);\n\n\treturn ERROR_FAIL;\n}\n\nint mips64_init_arch_info(struct target *target, struct mips64_common *mips64,\n\t\t\t  struct jtag_tap *tap)\n{\n\tmips64->bp_scanned = false;\n\tmips64->common_magic = MIPS64_COMMON_MAGIC;\n\tmips64->data_break_list = NULL;\n\tmips64->ejtag_info.tap = tap;\n\tmips64->fast_data_area = NULL;\n\tmips64->mips64mode32 = false;\n\tmips64->read_core_reg = mips64_read_core_reg;\n\tmips64->write_core_reg = mips64_write_core_reg;\n\n\treturn ERROR_OK;\n}\n\nint mips64_run_algorithm(struct target *target, int num_mem_params,\n\t\t\t struct mem_param *mem_params, int num_reg_params,\n\t\t\t struct reg_param *reg_params, target_addr_t entry_point,\n\t\t\t target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)\n{\n\t/* TODO */\n\treturn ERROR_OK;\n}\n\nint mips64_examine(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif (target_was_examined(target))\n\t\treturn ERROR_OK;\n\n\t/* TODO: why we do not do mips64_configure_break_unit() here? */\n\tmips64->bp_scanned = false;\n\tmips64->num_data_bpoints = 0;\n\tmips64->num_data_bpoints_avail = 0;\n\tmips64->num_inst_bpoints = 0;\n\tmips64->num_inst_bpoints_avail = 0;\n\n\ttarget_set_examined(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips64_configure_i_break_unit(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *ibl;\n\tuint64_t bpinfo;\n\tint retval;\n\tint i;\n\n\t/* get number of inst breakpoints */\n\tretval = target_read_u64(target, EJTAG64_V25_IBS, &bpinfo);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips64->num_inst_bpoints = (bpinfo >> 24) & 0x0F;\n\tmips64->num_inst_bpoints_avail = mips64->num_inst_bpoints;\n\tibl = calloc(mips64->num_inst_bpoints, sizeof(*ibl));\n\tif (!ibl) {\n\t\tLOG_ERROR(\"unable to allocate inst_break_list\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = 0; i < mips64->num_inst_bpoints; i++)\n\t\tibl[i].reg_address = EJTAG64_V25_IBA0 + (0x100 * i);\n\n\tmips64->inst_break_list = ibl;\n\t/* clear IBIS reg */\n\tretval = target_write_u64(target, EJTAG64_V25_IBS, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips64_configure_d_break_unit(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *dbl;\n\tuint64_t bpinfo;\n\tint retval;\n\tint i;\n\n\t/* get number of data breakpoints */\n\tretval = target_read_u64(target, EJTAG64_V25_DBS, &bpinfo);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips64->num_data_bpoints = (bpinfo >> 24) & 0x0F;\n\tmips64->num_data_bpoints_avail = mips64->num_data_bpoints;\n\n\tdbl = calloc(mips64->num_data_bpoints, sizeof(*dbl));\n\n\tif (!dbl) {\n\t\tLOG_ERROR(\"unable to allocate data_break_list\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (i = 0; i < mips64->num_data_bpoints; i++)\n\t\tdbl[i].reg_address = EJTAG64_V25_DBA0 + (0x100 * i);\n\n\tmips64->data_break_list = dbl;\n\n\t/* clear DBIS reg */\n\tretval = target_write_u64(target, EJTAG64_V25_DBS, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nint mips64_configure_break_unit(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tuint64_t dcr;\n\tint retval;\n\n\tif (mips64->bp_scanned)\n\t\treturn ERROR_OK;\n\n\t/* get info about breakpoint support */\n\tretval = target_read_u64(target, EJTAG64_DCR, &dcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (dcr & EJTAG64_DCR_IB) {\n\t\tretval = mips64_configure_i_break_unit(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (dcr & EJTAG64_DCR_DB) {\n\t\tretval = mips64_configure_d_break_unit(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"DCR 0x%\" PRIx64 \" numinst %i numdata %i\", dcr,\n\t\t  mips64->num_inst_bpoints, mips64->num_data_bpoints);\n\n\tmips64->bp_scanned = true;\n\n\treturn ERROR_OK;\n}\n\nint mips64_enable_interrupts(struct target *target, bool enable)\n{\n\tint retval;\n\tbool update = false;\n\tuint64_t dcr;\n\n\t/* read debug control register */\n\tretval = target_read_u64(target, EJTAG64_DCR, &dcr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (enable) {\n\t\tif (!(dcr & EJTAG64_DCR_INTE)) {\n\t\t\t/* enable interrupts */\n\t\t\tdcr |= EJTAG64_DCR_INTE;\n\t\t\tupdate = true;\n\t\t}\n\t} else {\n\t\tif (dcr & EJTAG64_DCR_INTE) {\n\t\t\t/* disable interrupts */\n\t\t\tdcr &= ~(uint64_t)EJTAG64_DCR_INTE;\n\t\t\tupdate = true;\n\t\t}\n\t}\n\n\tif (update) {\n\t\tretval = target_write_u64(target, EJTAG64_DCR, dcr);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips64.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/*\n * Support for processors implementing MIPS64 instruction set\n *\n * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>\n *\n * Based on the work of:\n *     Copyright (C) 2008 by Spencer Oliver\n *     Copyright (C) 2008 by David T.L. Wong\n *     Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev\n */\n\n#ifndef OPENOCD_TARGET_MIPS64_H\n#define OPENOCD_TARGET_MIPS64_H\n\n#include \"target.h\"\n#include \"register.h\"\n#include \"mips64_pracc.h\"\n\n#define MIPS64_COMMON_MAGIC\t\t0xB640B640U\n\n/* MIPS64 CP0 registers */\n#define MIPS64_C0_INDEX\t\t0\n#define MIPS64_C0_RANDOM\t1\n#define MIPS64_C0_ENTRYLO0\t2\n#define MIPS64_C0_ENTRYLO1\t3\n#define MIPS64_C0_CONTEXT\t4\n#define MIPS64_C0_PAGEMASK\t5\n#define MIPS64_C0_WIRED\t\t6\n#define MIPS64_C0_BADVADDR\t8\n#define MIPS64_C0_COUNT\t\t9\n#define MIPS64_C0_ENTRYHI\t10\n#define MIPS64_C0_COMPARE\t11\n#define MIPS64_C0_STATUS\t12\n#define MIPS64_C0_CAUSE\t\t13\n#define MIPS64_C0_EPC\t\t14\n#define MIPS64_C0_PRID\t\t15\n#define MIPS64_C0_CONFIG\t16\n#define MIPS64_C0_LLA\t\t17\n#define MIPS64_C0_WATCHLO\t18\n#define MIPS64_C0_WATCHHI\t19\n#define MIPS64_C0_XCONTEXT\t20\n#define MIPS64_C0_MEMCTRL\t22\n#define MIPS64_C0_DEBUG\t\t23\n#define MIPS64_C0_DEPC\t\t24\n#define MIPS64_C0_PERFCOUNT\t25\n#define MIPS64_C0_ECC\t\t26\n#define MIPS64_C0_CACHERR\t27\n#define MIPS64_C0_TAGLO\t\t28\n#define MIPS64_C0_TAGHI\t\t29\n#define MIPS64_C0_DATAHI\t29\n#define MIPS64_C0_EEPC\t\t30\n\n/* MIPS64 CP1 registers */\n#define MIPS64_C1_FIR\t\t0\n#define MIPS64_C1_FCONFIG\t24\n#define MIPS64_C1_FCSR\t\t31\n#define MIPS64_C1_FCCR\t\t25\n#define MIPS64_C1_FEXR\t\t26\n#define MIPS64_C1_FENR\t\t28\n\n/* offsets into mips64 register cache */\n#define MIPS64_NUM_CORE_REGS\t34\n#define MIPS64_NUM_C0_REGS\t34\n#define MIPS64_NUM_FP_REGS\t38\n\n#define MIPS64_NUM_REGS\t\t(MIPS64_NUM_CORE_REGS + \\\n\t\t\t\t MIPS64_NUM_C0_REGS + \\\n\t\t\t\t MIPS64_NUM_FP_REGS)\n\n#define MIPS64_NUM_CORE_C0_REGS\t(MIPS64_NUM_CORE_REGS + MIPS64_NUM_C0_REGS)\n\n#define MIPS64_PC\t\tMIPS64_NUM_CORE_REGS\n\nstruct mips64_comparator {\n\tbool used;\n\tuint64_t bp_value;\n\tuint64_t reg_address;\n};\n\nstruct mips64_common {\n\tunsigned int common_magic;\n\n\tvoid *arch_info;\n\tstruct reg_cache *core_cache;\n\tstruct mips_ejtag ejtag_info;\n\tuint64_t core_regs[MIPS64_NUM_REGS];\n\n\tstruct working_area *fast_data_area;\n\n\tbool bp_scanned;\n\tint num_inst_bpoints;\n\tint num_data_bpoints;\n\tint num_inst_bpoints_avail;\n\tint num_data_bpoints_avail;\n\tstruct mips64_comparator *inst_break_list;\n\tstruct mips64_comparator *data_break_list;\n\n\t/* register cache to processor synchronization */\n\tint (*read_core_reg)(struct target *target, int num);\n\tint (*write_core_reg)(struct target *target, int num);\n\n\tbool mips64mode32;\n};\n\nstruct mips64_core_reg {\n\tuint32_t num;\n\tstruct target *target;\n\tstruct mips64_common *mips64_common;\n\tuint8_t value[8];\n\tstruct reg_feature feature;\n\tstruct reg_data_type reg_data_type;\n};\n\n#define MIPS64_OP_SRL\t0x02\n#define MIPS64_OP_BEQ\t0x04\n#define MIPS64_OP_BNE\t0x05\n#define MIPS64_OP_ADDI\t0x08\n#define MIPS64_OP_ANDI\t0x0c\n#define MIPS64_OP_DADDI\t0x18\n#define MIPS64_OP_DADDIU\t0x19\n#define MIPS64_OP_AND\t0x24\n#define MIPS64_OP_LUI\t0x0F\n#define MIPS64_OP_LW\t0x23\n#define MIPS64_OP_LD\t0x37\n#define MIPS64_OP_LBU\t0x24\n#define MIPS64_OP_LHU\t0x25\n#define MIPS64_OP_MFHI\t0x10\n#define MIPS64_OP_MTHI\t0x11\n#define MIPS64_OP_MFLO\t0x12\n#define MIPS64_OP_MTLO\t0x13\n#define MIPS64_OP_SB\t0x28\n#define MIPS64_OP_SH\t0x29\n#define MIPS64_OP_SW\t0x2B\n#define MIPS64_OP_SD\t0x3F\n#define MIPS64_OP_ORI\t0x0D\n#define MIPS64_OP_JR\t0x08\n\n#define MIPS64_OP_COP0\t0x10\n#define MIPS64_OP_COP1\t0x11\n#define MIPS64_OP_COP2\t0x12\n\n#define MIPS64_COP_MF\t0x00\n#define MIPS64_COP_DMF\t0x01\n#define MIPS64_COP_MT\t0x04\n#define MIPS64_COP_DMT\t0x05\n#define MIPS64_COP_CF\t0x02\n#define MIPS64_COP_CT\t0x06\n\n#define MIPS64_R_INST(opcode, rs, rt, rd, shamt, funct) \\\n(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))\n#define MIPS64_I_INST(opcode, rs, rt, immd)\t(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))\n#define MIPS64_J_INST(opcode, addr)\t(((opcode) << 26) | (addr))\n\n#define MIPS64_NOP\t\t\t0\n#define MIPS64_ADDI(tar, src, val)\tMIPS64_I_INST(MIPS64_OP_ADDI, src, tar, val)\n#define MIPS64_DADDI(tar, src, val)\tMIPS64_I_INST(MIPS64_OP_DADDI, src, tar, val)\n#define MIPS64_DADDIU(tar, src, val)\tMIPS64_I_INST(MIPS64_OP_DADDIU, src, tar, val)\n#define MIPS64_AND(reg, off, val)\tMIPS64_R_INST(0, off, val, reg, 0, MIPS64_OP_AND)\n#define MIPS64_ANDI(d, s, im)\t\tMIPS64_I_INST(MIPS64_OP_ANDI, s, d, im)\n#define MIPS64_SRL(d, w, sh)\t\tMIPS64_R_INST(0, 0, w, d, sh, MIPS64_OP_SRL)\n#define MIPS64_B(off)\t\t\tMIPS64_BEQ(0, 0, off)\n#define MIPS64_BEQ(src, tar, off)\tMIPS64_I_INST(MIPS64_OP_BEQ, src, tar, off)\n#define MIPS64_BNE(src, tar, off)\tMIPS64_I_INST(MIPS64_OP_BNE, src, tar, off)\n#define MIPS64_MFC0(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MF, gpr, cpr, 0, sel)\n#define MIPS64_DMFC0(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMF, gpr, cpr, 0, sel)\n#define MIPS64_MTC0(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_MT, gpr, cpr, 0, sel)\n#define MIPS64_DMTC0(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP0, MIPS64_COP_DMT, gpr, cpr, 0, sel)\n#define MIPS64_MFC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MF, gpr, cpr, 0, 0)\n#define MIPS64_DMFC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMF, gpr, cpr, 0, 0)\n#define MIPS64_MTC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_MT, gpr, cpr, 0, 0)\n#define MIPS64_DMTC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_DMT, gpr, cpr, 0, 0)\n#define MIPS64_MFC2(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MF, gpr, cpr, 0, sel)\n#define MIPS64_MTC2(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_MT, gpr, cpr, 0, sel)\n#define MIPS64_CFC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CF, gpr, cpr, 0, 0)\n#define MIPS64_CTC1(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP1, MIPS64_COP_CT, gpr, cpr, 0, 0)\n#define MIPS64_CFC2(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CF, gpr, cpr, 0, sel)\n#define MIPS64_CTC2(gpr, cpr, sel)\tMIPS64_R_INST(MIPS64_OP_COP2, MIPS64_COP_CT, gpr, cpr, 0, sel)\n#define MIPS64_LBU(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_LBU, base, reg, off)\n#define MIPS64_LHU(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_LHU, base, reg, off)\n#define MIPS64_LUI(reg, val)\t\tMIPS64_I_INST(MIPS64_OP_LUI, 0, reg, val)\n#define MIPS64_LW(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_LW, base, reg, off)\n#define MIPS64_LD(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_LD, base, reg, off)\n#define MIPS64_MFLO(reg)\t\tMIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFLO)\n#define MIPS64_MFHI(reg)\t\tMIPS64_R_INST(0, 0, 0, reg, 0, MIPS64_OP_MFHI)\n#define MIPS64_MTLO(reg)\t\tMIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTLO)\n#define MIPS64_MTHI(reg)\t\tMIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_MTHI)\n#define MIPS64_ORI(src, tar, val)\tMIPS64_I_INST(MIPS64_OP_ORI, src, tar, val)\n#define MIPS64_SB(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_SB, base, reg, off)\n#define MIPS64_SH(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_SH, base, reg, off)\n#define MIPS64_SW(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_SW, base, reg, off)\n#define MIPS64_SD(reg, off, base)\tMIPS64_I_INST(MIPS64_OP_SD, base, reg, off)\n#define MIPS64_CACHE(op, reg, off)\t(47 << 26 | (reg) << 21 | (op) << 16 | (off))\n#define MIPS64_SYNCI(reg, off)\t\t(1 << 26 | (reg) << 21 | 0x1f << 16 | (off))\n#define MIPS64_JR(reg)\t\t\tMIPS64_R_INST(0, reg, 0, 0, 0, MIPS64_OP_JR)\n\n/* ejtag specific instructions */\n#define MIPS64_DRET\t\t\t0x4200001F\n#define MIPS64_SDBBP\t\t\t0x7000003F\n#define MIPS64_SDBBP_LE\t\t\t0x3f000007\n#define MIPS64_SDBBP_SIZE\t\t4\n#define MIPS16_SDBBP_SIZE\t\t2\n\n#define MIPS64_SYNC\t\t\t0x0000000F\n\nint mips64_arch_state(struct target *target);\nint mips64_init_arch_info(struct target *target, struct mips64_common *mips64, struct jtag_tap *tap);\nint mips64_restore_context(struct target *target);\nint mips64_save_context(struct target *target);\nint mips64_build_reg_cache(struct target *target);\nint mips64_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params,\n\tint num_reg_params, struct reg_param *reg_params,\n\ttarget_addr_t entry_point, target_addr_t exit_point,\n\tunsigned int timeout_ms, void *arch_info);\nint mips64_configure_break_unit(struct target *target);\nint mips64_enable_interrupts(struct target *target, bool enable);\nint mips64_examine(struct target *target);\n\nint mips64_register_commands(struct command_context *cmd_ctx);\nint mips64_invalidate_core_regs(struct target *target);\nint mips64_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[], int *reg_list_size,\n\tenum target_register_class reg_class);\n\n#endif\t/* OPENOCD_TARGET_MIPS64_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips64_pracc.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Support for processors implementing MIPS64 instruction set\n *\n *   Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n *   Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n *   Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>\n *\n *   Based on the work of:\n *       Copyright (C) 2008 by Spencer Oliver\n *       Copyright (C) 2008 by David T.L. Wong\n *       Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mips64.h\"\n#include \"mips64_pracc.h\"\n\n#include <helper/time_support.h>\n#include <jtag/adapter.h>\n\n#define STACK_DEPTH\t32\n\nstruct mips64_pracc_context {\n\tuint64_t *local_iparam;\n\tunsigned num_iparam;\n\tuint64_t *local_oparam;\n\tunsigned num_oparam;\n\tconst uint32_t *code;\n\tunsigned code_len;\n\tuint64_t stack[STACK_DEPTH];\n\tunsigned stack_offset;\n\tstruct mips_ejtag *ejtag_info;\n};\n\nstatic int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)\n{\n\tuint32_t ejtag_ctrl;\n\tint nt = 5;\n\tint rc;\n\n\twhile (1) {\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\t\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\t\trc = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\t\tif (rc != ERROR_OK)\n\t\t\treturn rc;\n\n\t\tif (ejtag_ctrl & EJTAG_CTRL_PRACC)\n\t\t\tbreak;\n\t\tLOG_DEBUG(\"DEBUGMODULE: No memory access in progress!\\n\");\n\t\tif (nt == 0)\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\tnt--;\n\t}\n\n\t*ctrl = ejtag_ctrl;\n\treturn ERROR_OK;\n}\n\nstatic int mips64_pracc_exec_read(struct mips64_pracc_context *ctx, uint64_t address)\n{\n\tstruct mips_ejtag *ejtag_info = ctx->ejtag_info;\n\tunsigned offset;\n\tuint32_t ejtag_ctrl;\n\tuint64_t data;\n\tint rc;\n\n\tif ((address >= MIPS64_PRACC_PARAM_IN)\n\t    && (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) {\n\n\t\toffset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP;\n\n\t\tif (offset >= MIPS64_PRACC_PARAM_IN_SIZE) {\n\t\t\tLOG_ERROR(\"Error: iparam size exceeds MIPS64_PRACC_PARAM_IN_SIZE\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tif (!ctx->local_iparam) {\n\t\t\tLOG_ERROR(\"Error: unexpected reading of input parameter\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tdata = ctx->local_iparam[offset];\n\t\tLOG_DEBUG(\"Reading %\" PRIx64 \" at %\" PRIx64, data, address);\n\n\t} else if ((address >= MIPS64_PRACC_PARAM_OUT)\n\t\t   && (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) {\n\n\t\toffset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP;\n\t\tif (!ctx->local_oparam) {\n\t\t\tLOG_ERROR(\"Error: unexpected reading of output parameter\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tdata = ctx->local_oparam[offset];\n\t\tLOG_DEBUG(\"Reading %\" PRIx64 \" at %\" PRIx64, data, address);\n\n\t} else if ((address >= MIPS64_PRACC_TEXT)\n\t\t   && (address < MIPS64_PRACC_TEXT + ctx->code_len * MIPS64_PRACC_ADDR_STEP)) {\n\n\t\toffset = ((address & ~7ull) - MIPS64_PRACC_TEXT) / MIPS64_PRACC_ADDR_STEP;\n\t\tdata = (uint64_t)ctx->code[offset] << 32;\n\t\tif (offset + 1 < ctx->code_len)\n\t\t\tdata |= (uint64_t)ctx->code[offset + 1];\n\n\t\tLOG_DEBUG(\"Running commands %\" PRIx64 \" at %\" PRIx64, data,\n\t\t\t  address);\n\n\t} else if ((address & ~7llu) == MIPS64_PRACC_STACK) {\n\n\t\t/* load from our debug stack */\n\t\tif (ctx->stack_offset == 0) {\n\t\t\tLOG_ERROR(\"Error reading from stack: stack is empty\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tdata = ctx->stack[--ctx->stack_offset];\n\t\tLOG_DEBUG(\"Reading %\" PRIx64 \" at %\" PRIx64, data, address);\n\n\t} else {\n\t\t/* TODO: send JMP 0xFF200000 instruction. Hopefully processor jump back\n\t\t * to start of debug vector */\n\n\t\tdata = 0;\n\t\tLOG_ERROR(\"Error reading unexpected address %\" PRIx64, address);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\t/* Send the data out */\n\tmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);\n\trc = mips_ejtag_drscan_64(ctx->ejtag_info, &data);\n\tif (rc != ERROR_OK)\n\t\treturn rc;\n\n\t/* Clear the access pending bit (let the processor eat!) */\n\n\tejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;\n\tmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);\n\trc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);\n\tif (rc != ERROR_OK)\n\t\treturn rc;\n\n\tjtag_add_clocks(5);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int mips64_pracc_exec_write(struct mips64_pracc_context *ctx, uint64_t address)\n{\n\tuint32_t ejtag_ctrl;\n\tuint64_t data;\n\tunsigned offset;\n\tstruct mips_ejtag *ejtag_info = ctx->ejtag_info;\n\tint rc;\n\n\tmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);\n\trc = mips_ejtag_drscan_64(ctx->ejtag_info, &data);\n\tif (rc != ERROR_OK)\n\t\treturn rc;\n\n\t/* Clear access pending bit */\n\tejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;\n\tmips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);\n\trc = mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);\n\tif (rc != ERROR_OK)\n\t\treturn rc;\n\n\tjtag_add_clocks(5);\n\trc = jtag_execute_queue();\n\tif (rc != ERROR_OK)\n\t\treturn rc;\n\n\tLOG_DEBUG(\"Writing %\" PRIx64 \" at %\" PRIx64, data, address);\n\n\tif ((address >= MIPS64_PRACC_PARAM_IN)\n\t\t&& (address < MIPS64_PRACC_PARAM_IN + ctx->num_iparam * MIPS64_PRACC_DATA_STEP)) {\n\t\toffset = (address - MIPS64_PRACC_PARAM_IN) / MIPS64_PRACC_DATA_STEP;\n\t\tif (!ctx->local_iparam) {\n\t\t\tLOG_ERROR(\"Error: unexpected writing of input parameter\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\tctx->local_iparam[offset] = data;\n\t} else if ((address >= MIPS64_PRACC_PARAM_OUT)\n\t\t&& (address < MIPS64_PRACC_PARAM_OUT + ctx->num_oparam * MIPS64_PRACC_DATA_STEP)) {\n\t\toffset = (address - MIPS64_PRACC_PARAM_OUT) / MIPS64_PRACC_DATA_STEP;\n\t\tif (!ctx->local_oparam) {\n\t\t\tLOG_ERROR(\"Error: unexpected writing of output parameter\");\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\t\tctx->local_oparam[offset] = data;\n\t} else if (address == MIPS64_PRACC_STACK) {\n\t\t/* save data onto our stack */\n\t\tif (ctx->stack_offset >= STACK_DEPTH) {\n\t\t\tLOG_ERROR(\"Error: PrAcc stack depth exceeded\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tctx->stack[ctx->stack_offset++] = data;\n\t} else {\n\t\tLOG_ERROR(\"Error writing unexpected address 0x%\" PRIx64, address);\n\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint mips64_pracc_exec(struct mips_ejtag *ejtag_info,\n\t\t      unsigned code_len, const uint32_t *code,\n\t\t      unsigned num_param_in, uint64_t *param_in,\n\t\t      unsigned num_param_out, uint64_t *param_out)\n{\n\tuint32_t ejtag_ctrl;\n\tuint64_t address = 0, address_prev = 0;\n\tstruct mips64_pracc_context ctx;\n\tint retval;\n\tint pass = 0;\n\tbool first_time_call = true;\n\tunsigned i;\n\n\tfor (i = 0; i < code_len; i++)\n\t\tLOG_DEBUG(\"%08\" PRIx32, code[i]);\n\n\tctx.local_iparam = param_in;\n\tctx.local_oparam = param_out;\n\tctx.num_iparam = num_param_in;\n\tctx.num_oparam = num_param_out;\n\tctx.code = code;\n\tctx.code_len = code_len;\n\tctx.ejtag_info = ejtag_info;\n\tctx.stack_offset = 0;\n\n\twhile (true) {\n\t\tuint32_t address32;\n\t\tretval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"ERROR wait_for_pracc_rw\");\n\t\t\treturn retval;\n\t\t}\n\t\tif (pass)\n\t\t\taddress_prev = address;\n\t\telse\n\t\t\taddress_prev = 0;\n\t\taddress32 = 0;\n\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\t\tmips_ejtag_drscan_32(ejtag_info, &address32);\n\t\tLOG_DEBUG(\"-> %08\" PRIx32, address32);\n\t\taddress = 0xffffffffff200000ull | address32;\n\n\t\tint psz = (ejtag_ctrl >> 29) & 3;\n\t\tint address20 = address & 7;\n\t\tswitch (psz) {\n\t\tcase 3:\n\t\t\tif (address20 != 7) {\n\t\t\t\tLOG_ERROR(\"PSZ=%d ADDRESS[2:0]=%d: not supported\", psz, address20);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\taddress &= ~7ull;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tif (address20 != 0 && address20 != 4) {\n\t\t\t\tLOG_ERROR(\"PSZ=%d ADDRESS[2:0]=%d: not supported\", psz, address20);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"PSZ=%d ADDRESS[2:0]=%d: not supported\", psz, address20);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (first_time_call && address != MIPS64_PRACC_TEXT) {\n\t\t\tLOG_ERROR(\"Error reading address \" TARGET_ADDR_FMT \" (0x%08llx expected)\",\n\t\t\t\taddress, MIPS64_PRACC_TEXT);\n\t\t\treturn ERROR_JTAG_DEVICE_ERROR;\n\t\t}\n\n\t\tfirst_time_call = false;\n\n\t\t/* Check for read or write */\n\t\tif (ejtag_ctrl & EJTAG_CTRL_PRNW) {\n\t\t\tretval = mips64_pracc_exec_write(&ctx, address);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"mips64_pracc_exec_write() failed\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Check to see if its reading at the debug vector. The first pass through\n\t\t\t * the module is always read at the vector, so the first one we allow.  When\n\t\t\t * the second read from the vector occurs we are done and just exit. */\n\t\t\tif ((address == MIPS64_PRACC_TEXT) && (pass++)) {\n\t\t\t\tLOG_DEBUG(\"@MIPS64_PRACC_TEXT, address_prev=%\" PRIx64, address_prev);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tretval = mips64_pracc_exec_read(&ctx, address);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"mips64_pracc_exec_read() failed\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t}\n\t}\n\n\t/* stack sanity check */\n\tif (ctx.stack_offset != 0)\n\t\tLOG_ERROR(\"Pracc Stack not zero\");\n\n\treturn ERROR_OK;\n}\n\nstatic int mips64_pracc_read_u64(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t uint64_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* load R8 @ param_in[0] = address */\n\t\tMIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN),  15),\n\t\t/* ld $8, 0($8),  Load $8 with the word @mem[$8] */\n\t\tMIPS64_LD(8, 0, 8),\n\t\t/* sd $8, 0($15) */\n\t\tMIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(10)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tuint64_t param_in[1];\n\tparam_in[0] = addr;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tARRAY_SIZE(param_in), param_in, 1, (uint64_t *) buf);\n}\n\nstatic int mips64_pracc_read_mem64(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t    unsigned count, uint64_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_read_u64(ejtag_info, addr + 8*i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_u32(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t uint32_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* load R8 @ param_in[0] = address */\n\t\tMIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN),  15),\n\t\t/* lw $8, 0($8),  Load $8 with the word @mem[$8] */\n\t\tMIPS64_LW(8, 0, 8),\n\t\t/* sd $8, 0($9) */\n\t\tMIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(10)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tint retval = ERROR_OK;\n\tuint64_t param_in[1];\n\tuint64_t param_out[1];\n\n\tparam_in[0] = addr;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\tretval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\t1, param_in, 1, param_out);\n\tbuf[0] = (uint32_t) param_out[0];\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t   unsigned count, uint32_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_read_u32(ejtag_info, addr + 4 * i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_u16(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t uint16_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* load R8 @ param_in[0] = address */\n\t\tMIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN),  15),\n\t\t/* lw $8, 0($8),  Load $8 with the word @mem[$8] */\n\t\tMIPS64_LHU(8, 0, 8),\n\t\t/* sd $8, 0($9) */\n\t\tMIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(10)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tint retval;\n\tuint64_t param_in[1];\n\tuint64_t param_out[1];\n\n\tparam_in[0] = addr;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\tretval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\t1, param_in, 1, param_out);\n\tbuf[0] = (uint16_t)param_out[0];\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t    unsigned count, uint16_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_read_u16(ejtag_info, addr + 2*i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_u8(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\tuint8_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* load R8 @ param_in[0] = address */\n\t\tMIPS64_LD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN),  15),\n\t\t/* lw $8, 0($8),  Load $8 with the word @mem[$8] */\n\t\tMIPS64_LBU(8, 0, 8),\n\t\t/* sd $8, 0($9) */\n\t\tMIPS64_SD(8, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_OUT), 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(10)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tint retval;\n\tuint64_t param_in[1];\n\tuint64_t param_out[1];\n\n\tparam_in[0] = addr;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\tretval = mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\t1, param_in, 1, param_out);\n\tbuf[0] = (uint8_t)param_out[0];\n\treturn retval;\n}\n\nstatic int mips64_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t  unsigned count, uint8_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_read_u8(ejtag_info, addr + i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nint mips64_pracc_read_mem(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t  unsigned size, unsigned count, void *buf)\n{\n\tswitch (size) {\n\tcase 1:\n\t\treturn mips64_pracc_read_mem8(ejtag_info, addr, count, buf);\n\tcase 2:\n\t\treturn mips64_pracc_read_mem16(ejtag_info, addr, count, buf);\n\tcase 4:\n\t\treturn mips64_pracc_read_mem32(ejtag_info, addr, count, buf);\n\tcase 8:\n\t\treturn mips64_pracc_read_mem64(ejtag_info, addr, count, buf);\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic int mips64_pracc_write_u64(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t  uint64_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* sd $9, ($15) */\n\t\tMIPS64_SD(9, 0, 15),\n\t\t/* load R8 @ param_in[1] = data */\n\t\tMIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN)-8), 15),\n\t\t/* load R9 @ param_in[0] = address */\n\t\tMIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),\n\t\t/* sd $8, 0($9) */\n\t\tMIPS64_SD(8, 0, 9),\n\t\tMIPS64_SYNCI(9, 0),\n\t\t/* ld $9, ($15) */\n\t\tMIPS64_LD(9, 0, 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(13)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\t/* TODO remove array */\n\tuint64_t param_in[2];\n\tparam_in[0] = addr;\n\tparam_in[1] = *buf;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tARRAY_SIZE(param_in), param_in, 0, NULL);\n}\n\nstatic int mips64_pracc_write_mem64(struct mips_ejtag *ejtag_info,\n\t\t\t     uint64_t addr, unsigned count, uint64_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_write_u64(ejtag_info, addr + 8 * i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_write_u32(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t  uint32_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(9, 0, 15),\n\t\t/* sd $9, ($15) */\n\t\tMIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),\n\t\t/* load R8 @ param_in[1] = data */\n\t\tMIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),\n\t\t/* load R9 @ param_in[0] = address */\n\t\tMIPS64_SW(8, 0, 9),\n\t\t/* sw $8, 0($9) */\n\t\tMIPS64_SYNCI(9, 0),\n\t\tMIPS64_LD(9, 0, 15),\n\t\t/* ld $9, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_SYNC,\n\t\tMIPS64_B(NEG16(13)),\n\t\t/* b start */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\t/* TODO remove array */\n\tuint64_t param_in[1 + 1];\n\tparam_in[0] = addr;\n\tparam_in[1] = *buf;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tARRAY_SIZE(param_in), param_in, 0, NULL);\n}\n\nstatic int mips64_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t     unsigned count, uint32_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_write_u32(ejtag_info, addr + 4 * i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_write_u16(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t  uint16_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* sd $9, ($15) */\n\t\tMIPS64_SD(9, 0, 15),\n\t\t/* load R8 @ param_in[1] = data */\n\t\tMIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),\n\t\t/* load R9 @ param_in[0] = address */\n\t\tMIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),\n\t\t/* sh $8, 0($9) */\n\t\tMIPS64_SH(8, 0, 9),\n\t\t/* ld $9, ($15) */\n\t\tMIPS64_LD(9, 0, 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(12)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tuint64_t param_in[2];\n\tparam_in[0] = addr;\n\tparam_in[1] = *buf;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tARRAY_SIZE(param_in), param_in, 0, NULL);\n}\n\nstatic int mips64_pracc_write_mem16(struct mips_ejtag *ejtag_info,\n\t\t\t     uint64_t addr, unsigned count, uint16_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_write_u16(ejtag_info, addr + 2 * i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int mips64_pracc_write_u8(struct mips_ejtag *ejtag_info, uint64_t addr,\n\t\t\t\t uint8_t *buf)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $8, ($15) */\n\t\tMIPS64_SD(8, 0, 15),\n\t\t/* sd $9, ($15) */\n\t\tMIPS64_SD(9, 0, 15),\n\t\t/* load R8 @ param_in[1] = data */\n\t\tMIPS64_LD(8, NEG16((MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN) - 8), 15),\n\t\t/* load R9 @ param_in[0] = address */\n\t\tMIPS64_LD(9, NEG16(MIPS64_PRACC_STACK-MIPS64_PRACC_PARAM_IN), 15),\n\t\t/* sh $8, 0($9) */\n\t\tMIPS64_SB(8, 0, 9),\n\t\t/* ld $9, ($15) */\n\t\tMIPS64_LD(9, 0, 15),\n\t\t/* ld $8, ($15) */\n\t\tMIPS64_LD(8, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(12)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\t/* TODO remove array */\n\tuint64_t param_in[2];\n\tparam_in[0] = addr;\n\tparam_in[1] = *buf;\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tARRAY_SIZE(param_in), param_in, 0, NULL);\n}\n\nstatic int mips64_pracc_write_mem8(struct mips_ejtag *ejtag_info,\n\t\t\t    uint64_t addr, unsigned count, uint8_t *buf)\n{\n\tint retval = ERROR_OK;\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tretval = mips64_pracc_write_u8(ejtag_info, addr + i, &buf[i]);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nint mips64_pracc_write_mem(struct mips_ejtag *ejtag_info,\n\t\t\t   uint64_t addr, unsigned size,\n\t\t\t   unsigned count, void *buf)\n{\n\tswitch (size) {\n\tcase 1:\n\t\treturn mips64_pracc_write_mem8(ejtag_info, addr, count, buf);\n\tcase 2:\n\t\treturn mips64_pracc_write_mem16(ejtag_info, addr, count, buf);\n\tcase 4:\n\t\treturn mips64_pracc_write_mem32(ejtag_info, addr, count, buf);\n\tcase 8:\n\t\treturn mips64_pracc_write_mem64(ejtag_info, addr, count, buf);\n\t}\n\treturn ERROR_FAIL;\n}\n\nint mips64_pracc_write_regs(struct mips_ejtag *ejtag_info, uint64_t *regs)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $2 to COP0 DeSave */\n\t\tMIPS64_DMTC0(2, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_IN)),\n\t\tMIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_IN)),\n\t\t/* sd $0, 0*8($2) */\n\t\tMIPS64_LD(1, 1*8, 2),\n\t\t/* sd $1, 1*8($2) */\n\t\tMIPS64_LD(15, 15*8, 2),\n\t\t/* sd $11, ($15) */\n\t\tMIPS64_DMFC0(2, 31, 0),\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_SD(1, 0, 15),\n\t\t/* $11 = MIPS64_PRACC_PARAM_OUT */\n\t\tMIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_IN)),\n\t\tMIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_IN)),\n\t\tMIPS64_LD(3, 3*8, 1),\n\t\tMIPS64_LD(4, 4*8, 1),\n\t\tMIPS64_LD(5, 5*8, 1),\n\t\tMIPS64_LD(6, 6*8, 1),\n\t\tMIPS64_LD(7, 7*8, 1),\n\t\tMIPS64_LD(8, 8*8, 1),\n\t\tMIPS64_LD(9, 9*8, 1),\n\t\tMIPS64_LD(10, 10*8, 1),\n\t\tMIPS64_LD(11, 11*8, 1),\n\t\tMIPS64_LD(12, 12*8, 1),\n\t\tMIPS64_LD(13, 13*8, 1),\n\t\tMIPS64_LD(14, 14*8, 1),\n\t\tMIPS64_LD(16, 16*8, 1),\n\t\tMIPS64_LD(17, 17*8, 1),\n\t\tMIPS64_LD(18, 18*8, 1),\n\t\tMIPS64_LD(19, 19*8, 1),\n\t\tMIPS64_LD(20, 20*8, 1),\n\t\tMIPS64_LD(21, 21*8, 1),\n\t\tMIPS64_LD(22, 22*8, 1),\n\t\tMIPS64_LD(23, 23*8, 1),\n\t\tMIPS64_LD(24, 24*8, 1),\n\t\tMIPS64_LD(25, 25*8, 1),\n\t\tMIPS64_LD(26, 26*8, 1),\n\t\tMIPS64_LD(27, 27*8, 1),\n\t\tMIPS64_LD(28, 28*8, 1),\n\t\tMIPS64_LD(29, 29*8, 1),\n\t\tMIPS64_LD(30, 30*8, 1),\n\t\tMIPS64_LD(31, 31*8, 1),\n\t\tMIPS64_LD(2, 32*8, 1),\n\t\tMIPS64_MTLO(2),\n\t\tMIPS64_LD(2, 33*8, 1),\n\t\tMIPS64_MTHI(2),\n\t\tMIPS64_LD(2, MIPS64_NUM_CORE_REGS * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_DEPC, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_ENTRYLO0, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_ENTRYLO1, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_CONTEXT, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_PAGEMASK, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_WIRED, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_COUNT, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_ENTRYHI, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_COMPARE, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_STATUS, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_CAUSE, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_EPC, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_CONFIG, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_LLA, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_XCONTEXT, 1),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_MEMCTRL, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 1),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 2),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_PERFCOUNT, 3),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_ECC, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_CACHERR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_TAGLO, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1),\n\t\tMIPS64_MTC0(2, MIPS64_C0_TAGHI, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_DATAHI, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1),\n\t\tMIPS64_DMTC0(2, MIPS64_C0_EEPC, 0),\n\t\t/* check if FPU is enabled, */\n\t\tMIPS64_MFC0(2, MIPS64_C0_STATUS, 0),\n\t\tMIPS64_SRL(2, 2, 29),\n\t\tMIPS64_ANDI(2, 2, 1),\n\t\t/* skip FPU registers restoration if not */\n\t\tMIPS64_BEQ(0, 2, 77),\n\t\tMIPS64_NOP,\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FIR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FCSR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FCONFIG, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FCCR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FEXR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1),\n\t\tMIPS64_CTC1(2, MIPS64_C1_FENR, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1),\n\t\tMIPS64_DMTC1(2, 0, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1),\n\t\tMIPS64_DMTC1(2, 1, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1),\n\t\tMIPS64_DMTC1(2, 2, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1),\n\t\tMIPS64_DMTC1(2, 3, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1),\n\t\tMIPS64_DMTC1(2, 4, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1),\n\t\tMIPS64_DMTC1(2, 5, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1),\n\t\tMIPS64_DMTC1(2, 6, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1),\n\t\tMIPS64_DMTC1(2, 7, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1),\n\t\tMIPS64_DMTC1(2, 8, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1),\n\t\tMIPS64_DMTC1(2, 9, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1),\n\t\tMIPS64_DMTC1(2, 10, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1),\n\t\tMIPS64_DMTC1(2, 11, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1),\n\t\tMIPS64_DMTC1(2, 12, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1),\n\t\tMIPS64_DMTC1(2, 13, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1),\n\t\tMIPS64_DMTC1(2, 14, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1),\n\t\tMIPS64_DMTC1(2, 15, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1),\n\t\tMIPS64_DMTC1(2, 16, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1),\n\t\tMIPS64_DMTC1(2, 17, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1),\n\t\tMIPS64_DMTC1(2, 18, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1),\n\t\tMIPS64_DMTC1(2, 19, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1),\n\t\tMIPS64_DMTC1(2, 20, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1),\n\t\tMIPS64_DMTC1(2, 21, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1),\n\t\tMIPS64_DMTC1(2, 22, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1),\n\t\tMIPS64_DMTC1(2, 23, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1),\n\t\tMIPS64_DMTC1(2, 24, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1),\n\t\tMIPS64_DMTC1(2, 25, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1),\n\t\tMIPS64_DMTC1(2, 26, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1),\n\t\tMIPS64_DMTC1(2, 27, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1),\n\t\tMIPS64_DMTC1(2, 28, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1),\n\t\tMIPS64_DMTC1(2, 29, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1),\n\t\tMIPS64_DMTC1(2, 30, 0),\n\t\tMIPS64_LD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1),\n\t\tMIPS64_DMTC1(2, 31, 0),\n\t\tMIPS64_LD(2, 2 * 8, 1),\n\t\tMIPS64_LD(1, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(181)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\tMIPS64_NUM_REGS, regs, 0, NULL);\n}\n\nint mips64_pracc_read_regs(struct mips_ejtag *ejtag_info, uint64_t *regs)\n{\n\tconst uint32_t code[] = {\n\t\t/* move $2 to COP0 DeSave */\n\t\tMIPS64_DMTC0(2, 31, 0),\n\t\t/* $2 = MIPS64_PRACC_PARAM_OUT */\n\t\tMIPS64_LUI(2, UPPER16(MIPS64_PRACC_PARAM_OUT)),\n\t\tMIPS64_ORI(2, 2, LOWER16(MIPS64_PRACC_PARAM_OUT)),\n\t\t/* sd $0, 0*8($2) */\n\t\tMIPS64_SD(0, 0*8, 2),\n\t\t/* sd $1, 1*8($2) */\n\t\tMIPS64_SD(1, 1*8, 2),\n\t\t/* sd $15, 15*8($2) */\n\t\tMIPS64_SD(15, 15*8, 2),\n\t\t/* move COP0 DeSave to $2 */\n\t\tMIPS64_DMFC0(2, 31, 0),\n\t\t/* move $15 to COP0 DeSave */\n\t\tMIPS64_DMTC0(15, 31, 0),\n\t\t/* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\t/* sd $1, ($15) */\n\t\tMIPS64_SD(1, 0, 15),\n\t\t/* sd $2, ($15) */\n\t\tMIPS64_SD(2, 0, 15),\n\t\t/* $1 = MIPS64_PRACC_PARAM_OUT */\n\t\tMIPS64_LUI(1, UPPER16(MIPS64_PRACC_PARAM_OUT)),\n\t\tMIPS64_ORI(1, 1, LOWER16(MIPS64_PRACC_PARAM_OUT)),\n\t\tMIPS64_SD(2, 2 * 8, 1),\n\t\tMIPS64_SD(3, 3 * 8, 1),\n\t\tMIPS64_SD(4, 4 * 8, 1),\n\t\tMIPS64_SD(5, 5 * 8, 1),\n\t\tMIPS64_SD(6, 6 * 8, 1),\n\t\tMIPS64_SD(7, 7 * 8, 1),\n\t\tMIPS64_SD(8, 8 * 8, 1),\n\t\tMIPS64_SD(9, 9 * 8, 1),\n\t\tMIPS64_SD(10, 10 * 8, 1),\n\t\tMIPS64_SD(11, 11 * 8, 1),\n\t\tMIPS64_SD(12, 12 * 8, 1),\n\t\tMIPS64_SD(13, 13 * 8, 1),\n\t\tMIPS64_SD(14, 14 * 8, 1),\n\t\tMIPS64_SD(16, 16 * 8, 1),\n\t\tMIPS64_SD(17, 17 * 8, 1),\n\t\tMIPS64_SD(18, 18 * 8, 1),\n\t\tMIPS64_SD(19, 19 * 8, 1),\n\t\tMIPS64_SD(20, 20 * 8, 1),\n\t\tMIPS64_SD(21, 21 * 8, 1),\n\t\tMIPS64_SD(22, 22 * 8, 1),\n\t\tMIPS64_SD(23, 23 * 8, 1),\n\t\tMIPS64_SD(24, 24 * 8, 1),\n\t\tMIPS64_SD(25, 25 * 8, 1),\n\t\tMIPS64_SD(26, 26 * 8, 1),\n\t\tMIPS64_SD(27, 27 * 8, 1),\n\t\tMIPS64_SD(28, 28 * 8, 1),\n\t\tMIPS64_SD(29, 29 * 8, 1),\n\t\tMIPS64_SD(30, 30 * 8, 1),\n\t\tMIPS64_SD(31, 31 * 8, 1),\n\t\tMIPS64_MFLO(2),\n\t\tMIPS64_SD(2, 32 * 8, 1),\n\t\tMIPS64_MFHI(2),\n\t\tMIPS64_SD(2, 33 * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_DEPC, 0),\n\t\tMIPS64_SD(2, MIPS64_NUM_CORE_REGS * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_RANDOM, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 1) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_ENTRYLO0, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 2) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_ENTRYLO1, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 3) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_CONTEXT, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 4) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PAGEMASK, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 5) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_WIRED, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 6) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_BADVADDR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 7) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_COUNT, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 8) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_ENTRYHI, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 9) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_COMPARE, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 10) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_STATUS, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 11) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_CAUSE, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 12) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_EPC, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 13) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PRID, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 14) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_CONFIG, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 15) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_LLA, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 16) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_XCONTEXT, 1),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 21) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_MEMCTRL, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 22) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_DEBUG, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 23) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 24) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 1),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 25) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 2),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 26) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_PERFCOUNT, 3),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 27) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_ECC, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 28) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_CACHERR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 29) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_TAGLO, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 30) * 8, 1),\n\t\tMIPS64_MFC0(2, MIPS64_C0_TAGHI, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 31) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_DATAHI, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 32) * 8, 1),\n\t\tMIPS64_DMFC0(2, MIPS64_C0_EEPC, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_REGS + 33) * 8, 1),\n\t\t/* check if FPU is enabled, */\n\t\tMIPS64_MFC0(2, MIPS64_C0_STATUS, 0),\n\t\tMIPS64_SRL(2, 2, 29),\n\t\tMIPS64_ANDI(2, 2, 1),\n\t\t/* skip FPU registers dump if not */\n\t\tMIPS64_BEQ(0, 2, 77),\n\t\tMIPS64_NOP,\n\t\tMIPS64_CFC1(2, MIPS64_C1_FIR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 33) * 8, 1),\n\t\tMIPS64_CFC1(2, MIPS64_C1_FCSR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 32) * 8, 1),\n\t\tMIPS64_CFC1(2, MIPS64_C1_FCONFIG, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 34) * 8, 1),\n\t\tMIPS64_CFC1(2, MIPS64_C1_FCCR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 35) * 8, 1),\n\t\tMIPS64_CFC1(2, MIPS64_C1_FEXR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 36) * 8, 1),\n\t\tMIPS64_CFC1(2, MIPS64_C1_FENR, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 37) * 8, 1),\n\t\tMIPS64_DMFC1(2, 0, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 0) * 8, 1),\n\t\tMIPS64_DMFC1(2, 1, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 1) * 8, 1),\n\t\tMIPS64_DMFC1(2, 2, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 2) * 8, 1),\n\t\tMIPS64_DMFC1(2, 3, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 3) * 8, 1),\n\t\tMIPS64_DMFC1(2, 4, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 4) * 8, 1),\n\t\tMIPS64_DMFC1(2, 5, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 5) * 8, 1),\n\t\tMIPS64_DMFC1(2, 6, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 6) * 8, 1),\n\t\tMIPS64_DMFC1(2, 7, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 7) * 8, 1),\n\t\tMIPS64_DMFC1(2, 8, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 8) * 8, 1),\n\t\tMIPS64_DMFC1(2, 9, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 9) * 8, 1),\n\t\tMIPS64_DMFC1(2, 10, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 10) * 8, 1),\n\t\tMIPS64_DMFC1(2, 11, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 11) * 8, 1),\n\t\tMIPS64_DMFC1(2, 12, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 12) * 8, 1),\n\t\tMIPS64_DMFC1(2, 13, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 13) * 8, 1),\n\t\tMIPS64_DMFC1(2, 14, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 14) * 8, 1),\n\t\tMIPS64_DMFC1(2, 15, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 15) * 8, 1),\n\t\tMIPS64_DMFC1(2, 16, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 16) * 8, 1),\n\t\tMIPS64_DMFC1(2, 17, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 17) * 8, 1),\n\t\tMIPS64_DMFC1(2, 18, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 18) * 8, 1),\n\t\tMIPS64_DMFC1(2, 19, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 19) * 8, 1),\n\t\tMIPS64_DMFC1(2, 20, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 20) * 8, 1),\n\t\tMIPS64_DMFC1(2, 21, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 21) * 8, 1),\n\t\tMIPS64_DMFC1(2, 22, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 22) * 8, 1),\n\t\tMIPS64_DMFC1(2, 23, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 23) * 8, 1),\n\t\tMIPS64_DMFC1(2, 24, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 24) * 8, 1),\n\t\tMIPS64_DMFC1(2, 25, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 25) * 8, 1),\n\t\tMIPS64_DMFC1(2, 26, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 26) * 8, 1),\n\t\tMIPS64_DMFC1(2, 27, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 27) * 8, 1),\n\t\tMIPS64_DMFC1(2, 28, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 28) * 8, 1),\n\t\tMIPS64_DMFC1(2, 29, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 29) * 8, 1),\n\t\tMIPS64_DMFC1(2, 30, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 30) * 8, 1),\n\t\tMIPS64_DMFC1(2, 31, 0),\n\t\tMIPS64_SD(2, (MIPS64_NUM_CORE_C0_REGS + 31) * 8, 1),\n\t\tMIPS64_LD(2, 0, 15),\n\t\tMIPS64_LD(1, 0, 15),\n\t\tMIPS64_SYNC,\n\t\t/* b start */\n\t\tMIPS64_B(NEG16(192)),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,\n\t\t0, NULL, MIPS64_NUM_REGS, regs);\n}\n\n/* fastdata upload/download requires an initialized working area\n * to load the download code; it should not be called otherwise\n * fetch order from the fastdata area\n * 1. start addr\n * 2. end addr\n * 3. data ...\n */\nint mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info,\n\t\t\t       struct working_area *source,\n\t\t\t       bool write_t, uint64_t addr,\n\t\t\t       unsigned count, uint64_t *buf)\n{\n\tuint32_t handler_code[] = {\n\t\t/* caution when editing, table is modified below */\n\t\t/* r15 points to the start of this code */\n\t\tMIPS64_SD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15),\n\t\tMIPS64_SD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15),\n\t\tMIPS64_SD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15),\n\t\tMIPS64_SD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15),\n\t\t/* start of fastdata area in t0 */\n\t\tMIPS64_LUI(8, UPPER16(MIPS64_PRACC_FASTDATA_AREA)),\n\t\tMIPS64_ORI(8, 8, LOWER16(MIPS64_PRACC_FASTDATA_AREA)),\n\t\t/* start addr in t1 */\n\t\tMIPS64_LD(9, 0, 8),\n\t\t/* end addr to t2 */\n\t\tMIPS64_LD(10, 0, 8),\n\n\t\t/* loop: */\n\t\t/* lw t3,[t8 | r9] */\n\t\t/* 8 */ MIPS64_LD(11, 0, 0),\n\t\t/* sw t3,[r9 | r8] */\n\t\t/* 9 */ MIPS64_SD(11, 0, 0),\n\t\t/* bne $t2,t1,loop */\n\t\tMIPS64_BNE(10, 9, NEG16(3)),\n\t\t/* addi t1,t1,4 */\n\t\tMIPS64_DADDIU(9, 9, 8),\n\n\t\tMIPS64_LD(8, MIPS64_FASTDATA_HANDLER_SIZE - 8, 15),\n\t\tMIPS64_LD(9, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 2, 15),\n\t\tMIPS64_LD(10, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 3, 15),\n\t\tMIPS64_LD(11, MIPS64_FASTDATA_HANDLER_SIZE - 8 * 4, 15),\n\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_TEXT)),\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_TEXT)),\n\t\t/* jr start */\n\t\tMIPS64_JR(15),\n\t\t/* move COP0 DeSave to $15 */\n\t\tMIPS64_DMFC0(15, 31, 0),\n\t};\n\n\tuint32_t jmp_code[] = {\n\t\t/* addr of working area added below */\n\t\t/* 0 */ MIPS64_LUI(15, 0),\n\t\t/* addr of working area added below */\n\t\t/* 1 */ MIPS64_ORI(15, 15, 0),\n\t\t/* jump to ram program */\n\t\tMIPS64_JR(15),\n\t\tMIPS64_NOP,\n\t};\n\n\tint retval;\n\tunsigned i;\n\tuint32_t ejtag_ctrl, address32;\n\tuint64_t address, val;\n\n\tif (source->size < MIPS64_FASTDATA_HANDLER_SIZE)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (write_t) {\n\t\t/* load data from probe at fastdata area */\n\t\thandler_code[8] = MIPS64_LD(11, 0, 8);\n\t\t/* store data to RAM @ r9 */\n\t\thandler_code[9] = MIPS64_SD(11, 0, 9);\n\t} else {\n\t\t/* load data from RAM @ r9 */\n\t\thandler_code[8] = MIPS64_LD(11, 0, 9);\n\t\t/* store data to probe at fastdata area */\n\t\thandler_code[9] = MIPS64_SD(11, 0, 8);\n\t}\n\n\t/* write program into RAM */\n\tif (write_t != ejtag_info->fast_access_save) {\n\t\tmips64_pracc_write_mem(ejtag_info, source->address, 4,\n\t\t\t\t       ARRAY_SIZE(handler_code), handler_code);\n\t\t/* save previous operation to speed to any consecutive read/writes */\n\t\tejtag_info->fast_access_save = write_t;\n\t}\n\n\tLOG_DEBUG(\"%s using \" TARGET_ADDR_FMT \" for write handler\", __func__,\n\t\t  source->address);\n\tLOG_DEBUG(\"daddiu: %08\" PRIx32, handler_code[11]);\n\n\tjmp_code[0] |= UPPER16(source->address);\n\tjmp_code[1] |= LOWER16(source->address);\n\tmips64_pracc_exec(ejtag_info,\n\t\t\t  ARRAY_SIZE(jmp_code), jmp_code,\n\t\t\t  0, NULL, 0, NULL);\n\n\t/* next fetch to dmseg should be in FASTDATA_AREA, check */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tretval = mips_ejtag_drscan_32(ejtag_info, &address32);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\taddress = 0xffffffffff200000ull | address32;\n\tif ((address & ~7ull) != MIPS64_PRACC_FASTDATA_AREA) {\n\t\tLOG_ERROR(\"! @MIPS64_PRACC_FASTDATA_AREA (\" TARGET_ADDR_FMT \")\", address);\n\t\treturn ERROR_FAIL;\n\t}\n\t/* Send the load start address */\n\tval = addr;\n\tLOG_DEBUG(\"start: \" TARGET_ADDR_FMT, val);\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);\n\tmips64_ejtag_fastdata_scan(ejtag_info, 1, &val);\n\n\tretval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Send the load end address */\n\tval = addr + (count - 1) * 8;\n\tLOG_DEBUG(\"stop: \" TARGET_ADDR_FMT, val);\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);\n\tmips64_ejtag_fastdata_scan(ejtag_info, 1, &val);\n\n\t/* like in legacy code */\n\tunsigned num_clocks = 0;\n\tif (ejtag_info->mode != 0)\n\t\tnum_clocks = ((uint64_t)(ejtag_info->scan_delay) * adapter_get_speed_khz() + 500000) / 1000000;\n\tLOG_DEBUG(\"num_clocks=%d\", num_clocks);\n\tfor (i = 0; i < count; i++) {\n\t\tjtag_add_clocks(num_clocks);\n\t\tretval = mips64_ejtag_fastdata_scan(ejtag_info, write_t, buf++);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"mips64_ejtag_fastdata_scan failed\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"jtag_execute_queue failed\");\n\t\treturn retval;\n\t}\n\n\tretval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"wait_for_pracc_rw failed\");\n\t\treturn retval;\n\t}\n\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);\n\tretval = mips_ejtag_drscan_32(ejtag_info, &address32);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"mips_ejtag_drscan_32 failed\");\n\t\treturn retval;\n\t}\n\n\taddress = 0xffffffffff200000ull | address32;\n\tif ((address & ~7ull) != MIPS64_PRACC_TEXT)\n\t\tLOG_ERROR(\"mini program did not return to start\");\n\n\treturn retval;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips64_pracc.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/*\n * Support for processors implementing MIPS64 instruction set\n *\n * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>\n *\n * Based on the work of:\n *     Copyright (C) 2008 by Spencer Oliver\n *     Copyright (C) 2008 by David T.L. Wong\n *     Copyright (C) 2010 by Konstantin Kostyukhin, Nikolay Shmyrev\n */\n\n#ifndef OPENOCD_TARGET_MIPS64_PRACC_H\n#define OPENOCD_TARGET_MIPS64_PRACC_H\n\n#include \"mips_ejtag.h\"\n\n#define MIPS64_PRACC_TEXT\t\t0xffffffffFF200200ull\n\n#define MIPS64_PRACC_STACK\t\t0xffffffffFF204000ull\n#define MIPS64_PRACC_PARAM_IN\t\t0xffffffffFF201000ull\n#define MIPS64_PRACC_PARAM_IN_SIZE\t0x1000\n#define MIPS64_PRACC_PARAM_OUT\t\t(MIPS64_PRACC_PARAM_IN + MIPS64_PRACC_PARAM_IN_SIZE)\n#define MIPS64_PRACC_PARAM_OUT_SIZE\t0x1000\n\n#undef UPPER16\n#undef LOWER16\n#define UPPER16(v) ((uint32_t)((v >> 16) & 0xFFFF))\n#define LOWER16(v) ((uint32_t)(v & 0xFFFF))\n#define MIPS64_PRACC_FASTDATA_AREA\t\t0xffffffffFF200000ull\n#define MIPS64_PRACC_FASTDATA_SIZE\t\t16\n#define MIPS64_FASTDATA_HANDLER_SIZE\t0x80\n\n/* FIXME: 16-bit NEG */\n#undef NEG16\n#define NEG16(v) ((uint32_t)(((~(v)) + 1) & 0xFFFF))\n\n#define MIPS64_PRACC_ADDR_STEP 4\n#define MIPS64_PRACC_DATA_STEP 8\n\nint mips64_pracc_read_mem(struct mips_ejtag *ejtag_info, uint64_t addr, unsigned size, unsigned count, void *buf);\nint mips64_pracc_write_mem(struct mips_ejtag *ejtag_info, uint64_t addr, unsigned size, unsigned count, void *buf);\n\nint mips64_pracc_read_regs(struct mips_ejtag *ejtag_info, uint64_t *regs);\nint mips64_pracc_write_regs(struct mips_ejtag *ejtag_info, uint64_t *regs);\n\nint mips64_pracc_exec(struct mips_ejtag *ejtag_info,\n\t\t      unsigned code_len, const uint32_t *code,\n\t\t      unsigned num_param_in, uint64_t *param_in,\n\t\t      unsigned num_param_out, uint64_t *param_out);\n\nint mips64_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info,\n\t\t\t       struct working_area *source,\n\t\t\t       bool write_t, uint64_t addr,\n\t\t\t       unsigned count, uint64_t *buf);\n\n#endif /* OPENOCD_TARGET_MIPS64_PRACC_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_ejtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"mips32.h\"\n#include \"mips_ejtag.h\"\n#include \"mips32_dmaacc.h\"\n#include \"mips64.h\"\n#include \"mips64_pracc.h\"\n\nvoid mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\n\t\tstruct scan_field field;\n\t\tfield.num_bits = tap->ir_length;\n\n\t\tuint8_t t[4] = { 0 };\n\t\tfield.out_value = t;\n\t\tbuf_set_u32(t, 0, field.num_bits, new_instr);\n\n\t\tfield.in_value = NULL;\n\n\t\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\t}\n}\n\nint mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info)\n{\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_IDCODE);\n\n\tejtag_info->idcode = 0;\n\treturn mips_ejtag_drscan_32(ejtag_info, &ejtag_info->idcode);\n}\n\nstatic int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info)\n{\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE);\n\n\tejtag_info->impcode = 0;\n\treturn mips_ejtag_drscan_32(ejtag_info, &ejtag_info->impcode);\n}\n\nvoid mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info, uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tstruct scan_field field;\n\tuint8_t out_scan[12];\n\n\t/* processor access \"all\" register 96 bit */\n\tfield.num_bits = 96;\n\n\tfield.out_value = out_scan;\n\tbuf_set_u32(out_scan, 0, 32, ctrl);\n\tbuf_set_u32(out_scan + 4, 0, 32, data);\n\tbuf_set_u32(out_scan + 8, 0, 32, 0);\n\n\tfield.in_value = in_scan_buf;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\tkeep_alive();\n}\n\nint mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data)\n{\n\tstruct jtag_tap *tap;\n\ttap  = ejtag_info->tap;\n\n\tif (!tap)\n\t\treturn ERROR_FAIL;\n\tstruct scan_field field;\n\tuint8_t t[8] = { 0 }, r[8];\n\tint retval;\n\n\tfield.num_bits = 64;\n\tfield.out_value = t;\n\tbuf_set_u64(t, 0, field.num_bits, *data);\n\tfield.in_value = r;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"register read failed\");\n\t\treturn retval;\n\t}\n\n\t*data = buf_get_u64(field.in_value, 0, 64);\n\n\tkeep_alive();\n\n\treturn ERROR_OK;\n}\n\nstatic void mips_ejtag_drscan_32_queued(struct mips_ejtag *ejtag_info,\n\t\tuint32_t data_out, uint8_t *data_in)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tstruct scan_field field;\n\tfield.num_bits = 32;\n\n\tuint8_t scan_out[4] = { 0 };\n\tfield.out_value = scan_out;\n\tbuf_set_u32(scan_out, 0, field.num_bits, data_out);\n\n\tfield.in_value = data_in;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\tkeep_alive();\n}\n\nint mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)\n{\n\tuint8_t scan_in[4];\n\tmips_ejtag_drscan_32_queued(ejtag_info, *data, scan_in);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"register read failed\");\n\t\treturn retval;\n\t}\n\n\t*data = buf_get_u32(scan_in, 0, 32);\n\treturn ERROR_OK;\n}\n\nvoid mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data)\n{\n\tmips_ejtag_drscan_32_queued(ejtag_info, data, NULL);\n}\n\nint mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tstruct scan_field field;\n\tfield.num_bits = 8;\n\n\tfield.out_value = data;\n\tfield.in_value = data;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"register read failed\");\n\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n\nvoid mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tstruct scan_field field;\n\tfield.num_bits = 8;\n\n\tfield.out_value = &data;\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n}\n\n/* Set (to enable) or clear (to disable stepping) the SSt bit (bit 8) in Cp0 Debug reg (reg 23, sel 0) */\nint mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)\n{\n\tstruct pracc_queue_info ctx = {.ejtag_info = ejtag_info};\n\tpracc_queue_init(&ctx);\n\n\tpracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 23, 0));\t\t\t/* move COP0 Debug to $8 */\n\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, 0x0100));\t\t\t/* set SSt bit in debug reg */\n\tif (!enable_step)\n\t\tpracc_add(&ctx, 0, MIPS32_XORI(ctx.isa, 8, 8, 0x0100));\t\t/* clear SSt bit in debug reg */\n\n\tpracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 23, 0));\t\t\t/* move $8 to COP0 Debug */\n\tpracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8)));\t/* restore upper 16 bits  of $8 */\n\tpracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa)));\t\t/* jump to start */\n\tpracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */\n\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);\n\tpracc_queue_free(&ctx);\n\treturn ctx.retval;\n}\n\n/*\n * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF\n * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs\n * For example bcm7401 and others. At leas on some\n * CPUs, DebugMode wont start if this bit is not removed.\n */\nstatic int disable_dcr_mp(struct mips_ejtag *ejtag_info)\n{\n\tuint32_t dcr;\n\tint retval;\n\n\tretval = mips32_dmaacc_read_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);\n\tif (retval != ERROR_OK)\n\t\tgoto error;\n\n\tdcr &= ~EJTAG_DCR_MP;\n\tretval = mips32_dmaacc_write_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);\n\tif (retval != ERROR_OK)\n\t\tgoto error;\n\treturn ERROR_OK;\nerror:\n\tLOG_ERROR(\"Failed to remove DCR MPbit!\");\n\treturn retval;\n}\n\nint mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)\n{\n\tuint32_t ejtag_ctrl;\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\n\tif (ejtag_info->ejtag_version == EJTAG_VERSION_20) {\n\t\tif (disable_dcr_mp(ejtag_info) != ERROR_OK)\n\t\t\tgoto error;\n\t}\n\n\t/* set debug break bit */\n\tejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_JTAGBRK;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* break bit will be cleared by hardware */\n\tejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tLOG_DEBUG(\"ejtag_ctrl: 0x%8.8\" PRIx32 \"\", ejtag_ctrl);\n\tif ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0)\n\t\tgoto error;\n\n\treturn ERROR_OK;\nerror:\n\tLOG_ERROR(\"Failed to enter Debug Mode!\");\n\treturn ERROR_FAIL;\n}\n\nint mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)\n{\n\tstruct pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0};\n\tstruct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};\n\n\t/* execute our dret instruction */\n\tctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */\n\n\t/* pic32mx workaround, false pending at low core clock */\n\tjtag_add_sleep(1000);\n\treturn ctx.retval;\n}\n\n/* mips_ejtag_init_mmr - assign Memory-Mapped Registers depending\n *\t\t\ton EJTAG version.\n */\nstatic void mips_ejtag_init_mmr(struct mips_ejtag *ejtag_info)\n{\n\tif (ejtag_info->ejtag_version == EJTAG_VERSION_20) {\n\t\tejtag_info->ejtag_ibs_addr\t= EJTAG_V20_IBS;\n\t\tejtag_info->ejtag_iba0_addr\t= EJTAG_V20_IBA0;\n\t\tejtag_info->ejtag_ibc_offs\t= EJTAG_V20_IBC_OFFS;\n\t\tejtag_info->ejtag_ibm_offs\t= EJTAG_V20_IBM_OFFS;\n\n\t\tejtag_info->ejtag_dbs_addr\t= EJTAG_V20_DBS;\n\t\tejtag_info->ejtag_dba0_addr\t= EJTAG_V20_DBA0;\n\t\tejtag_info->ejtag_dbc_offs\t= EJTAG_V20_DBC_OFFS;\n\t\tejtag_info->ejtag_dbm_offs\t= EJTAG_V20_DBM_OFFS;\n\t\tejtag_info->ejtag_dbv_offs\t= EJTAG_V20_DBV_OFFS;\n\n\t\tejtag_info->ejtag_iba_step_size\t= EJTAG_V20_IBAN_STEP;\n\t\tejtag_info->ejtag_dba_step_size\t= EJTAG_V20_DBAN_STEP;\n\t} else {\n\t\tejtag_info->ejtag_ibs_addr\t= EJTAG_V25_IBS;\n\t\tejtag_info->ejtag_iba0_addr\t= EJTAG_V25_IBA0;\n\t\tejtag_info->ejtag_ibm_offs\t= EJTAG_V25_IBM_OFFS;\n\t\tejtag_info->ejtag_ibasid_offs\t= EJTAG_V25_IBASID_OFFS;\n\t\tejtag_info->ejtag_ibc_offs\t= EJTAG_V25_IBC_OFFS;\n\n\t\tejtag_info->ejtag_dbs_addr\t= EJTAG_V25_DBS;\n\t\tejtag_info->ejtag_dba0_addr\t= EJTAG_V25_DBA0;\n\t\tejtag_info->ejtag_dbm_offs\t= EJTAG_V25_DBM_OFFS;\n\t\tejtag_info->ejtag_dbasid_offs\t= EJTAG_V25_DBASID_OFFS;\n\t\tejtag_info->ejtag_dbc_offs\t= EJTAG_V25_DBC_OFFS;\n\t\tejtag_info->ejtag_dbv_offs\t= EJTAG_V25_DBV_OFFS;\n\n\t\tejtag_info->ejtag_iba_step_size\t= EJTAG_V25_IBAN_STEP;\n\t\tejtag_info->ejtag_dba_step_size\t= EJTAG_V25_DBAN_STEP;\n\t}\n}\n\nstatic void ejtag_v20_print_imp(struct mips_ejtag *ejtag_info)\n{\n\tLOG_DEBUG(\"EJTAG v2.0: features:%s%s%s%s%s%s%s%s\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_SDBBP) ? \" SDBBP_SPECIAL2\" : \" SDBBP\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_EADDR_NO32BIT) ? \" EADDR>32bit\" : \" EADDR=32bit\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_COMPLEX_BREAK) ? \" COMPLEX_BREAK\" : \"\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_DCACHE_COH) ? \" DCACHE_COH\" : \" DCACHE_NOT_COH\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_ICACHE_COH) ? \" ICACHE_COH\" : \" ICACHE_NOT_COH\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_NOPB) ? \" noPB\" : \" PB\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_NODB) ? \" noDB\" : \" DB\",\n\t\tEJTAG_IMP_HAS(EJTAG_V20_IMP_NOIB) ? \" noIB\" : \" IB\");\n\tLOG_DEBUG(\"EJTAG v2.0: Break Channels: %\" PRIu8,\n\t\t(uint8_t)((ejtag_info->impcode >> EJTAG_V20_IMP_BCHANNELS_SHIFT) &\n\t\tEJTAG_V20_IMP_BCHANNELS_MASK));\n}\n\nstatic void ejtag_v26_print_imp(struct mips_ejtag *ejtag_info)\n{\n\tLOG_DEBUG(\"EJTAG v2.6: features:%s%s\",\n\t\tEJTAG_IMP_HAS(EJTAG_V26_IMP_R3K) ? \" R3k\" : \" R4k\",\n\t\tEJTAG_IMP_HAS(EJTAG_V26_IMP_DINT) ? \" DINT\" : \"\");\n}\n\nstatic void ejtag_main_print_imp(struct mips_ejtag *ejtag_info)\n{\n\tLOG_DEBUG(\"EJTAG main: features:%s%s%s%s%s\",\n\t\tEJTAG_IMP_HAS(EJTAG_IMP_ASID8) ? \" ASID_8\" : \"\",\n\t\tEJTAG_IMP_HAS(EJTAG_IMP_ASID6) ? \" ASID_6\" : \"\",\n\t\tEJTAG_IMP_HAS(EJTAG_IMP_MIPS16) ? \" MIPS16\" : \"\",\n\t\tEJTAG_IMP_HAS(EJTAG_IMP_NODMA) ? \" noDMA\" : \" DMA\",\n\t\tEJTAG_IMP_HAS(EJTAG_IMP_MIPS64) ? \" MIPS64\" : \" MIPS32\");\n\n\tswitch (ejtag_info->ejtag_version) {\n\t\tcase EJTAG_VERSION_20:\n\t\t\tejtag_v20_print_imp(ejtag_info);\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_25:\n\t\tcase EJTAG_VERSION_26:\n\t\tcase EJTAG_VERSION_31:\n\t\tcase EJTAG_VERSION_41:\n\t\tcase EJTAG_VERSION_51:\n\t\t\tejtag_v26_print_imp(ejtag_info);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n}\n\nint mips_ejtag_init(struct mips_ejtag *ejtag_info)\n{\n\tint retval = mips_ejtag_get_impcode(ejtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"impcode read failed\");\n\t\treturn retval;\n\t}\n\n\t/* get ejtag version */\n\tejtag_info->ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);\n\n\tswitch (ejtag_info->ejtag_version) {\n\t\tcase EJTAG_VERSION_20:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 1 or 2.0 Detected\");\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_25:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 2.5 Detected\");\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_26:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 2.6 Detected\");\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_31:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 3.1 Detected\");\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_41:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 4.1 Detected\");\n\t\t\tbreak;\n\t\tcase EJTAG_VERSION_51:\n\t\t\tLOG_DEBUG(\"EJTAG: Version 5.1 Detected\");\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_DEBUG(\"EJTAG: Unknown Version Detected\");\n\t\t\tbreak;\n\t}\n\tejtag_main_print_imp(ejtag_info);\n\n\tif ((ejtag_info->impcode & EJTAG_IMP_NODMA) == 0) {\n\t\tLOG_DEBUG(\"EJTAG: DMA Access Mode detected. Disabling to \"\n\t\t\t  \"workaround current broken code.\");\n\t\tejtag_info->impcode |= EJTAG_IMP_NODMA;\n\t}\n\n\tejtag_info->ejtag_ctrl = EJTAG_CTRL_PRACC | EJTAG_CTRL_PROBEN;\n\n\tif (ejtag_info->ejtag_version != EJTAG_VERSION_20)\n\t\tejtag_info->ejtag_ctrl |= EJTAG_CTRL_ROCC | EJTAG_CTRL_SETDEV;\n\n\tejtag_info->fast_access_save = -1;\n\n\tmips_ejtag_init_mmr(ejtag_info);\n\n\treturn ERROR_OK;\n}\n\nint mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data)\n{\n\tassert(ejtag_info->tap);\n\tstruct jtag_tap *tap = ejtag_info->tap;\n\n\tstruct scan_field fields[2];\n\n\t/* fastdata 1-bit register */\n\tfields[0].num_bits = 1;\n\n\tuint8_t spracc = 0;\n\tfields[0].out_value = &spracc;\n\tfields[0].in_value = NULL;\n\n\t/* processor access data register 32 bit */\n\tfields[1].num_bits = 32;\n\n\tuint8_t t[4] = {0, 0, 0, 0};\n\tfields[1].out_value = t;\n\n\tif (write_t) {\n\t\tfields[1].in_value = NULL;\n\t\tbuf_set_u32(t, 0, 32, *data);\n\t} else\n\t\tfields[1].in_value = (uint8_t *) data;\n\n\tjtag_add_dr_scan(tap, 2, fields, TAP_IDLE);\n\n\tif (!write_t && data)\n\t\tjtag_add_callback(mips_le_to_h_u32,\n\t\t\t(jtag_callback_data_t) data);\n\n\tkeep_alive();\n\n\treturn ERROR_OK;\n}\n\nint mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step)\n{\n\tconst uint32_t code_enable[] = {\n\t\tMIPS64_MTC0(1, 31, 0),\t\t    /* move $1 to COP0 DeSave */\n\t\tMIPS64_MFC0(1, 23, 0),\t\t    /* move COP0 Debug to $1 */\n\t\tMIPS64_ORI(1, 1, 0x0100),\t\t /* set SSt bit in debug reg */\n\t\tMIPS64_MTC0(1, 23, 0),\t\t    /* move $1 to COP0 Debug */\n\t\tMIPS64_B(NEG16(5)),\n\t\tMIPS64_MFC0(1, 31, 0),\t\t    /* move COP0 DeSave to $1 */\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\n\tconst uint32_t code_disable[] = {\n\t\tMIPS64_MTC0(15, 31, 0),                           /* move $15 to COP0 DeSave */\n\t\tMIPS64_LUI(15, UPPER16(MIPS64_PRACC_STACK)),     /* $15 = MIPS64_PRACC_STACK */\n\t\tMIPS64_ORI(15, 15, LOWER16(MIPS64_PRACC_STACK)),\n\t\tMIPS64_SD(1, 0, 15),                              /* sw $1,($15) */\n\t\tMIPS64_SD(2, 0, 15),                              /* sw $2,($15) */\n\t\tMIPS64_MFC0(1, 23, 0),                            /* move COP0 Debug to $1 */\n\t\tMIPS64_LUI(2, 0xFFFF),                           /* $2 = 0xfffffeff */\n\t\tMIPS64_ORI(2, 2, 0xFEFF),\n\t\tMIPS64_AND(1, 1, 2),\n\t\tMIPS64_MTC0(1, 23, 0),                            /* move $1 to COP0 Debug */\n\t\tMIPS64_LD(2, 0, 15),\n\t\tMIPS64_LD(1, 0, 15),\n\t\tMIPS64_SYNC,\n\t\tMIPS64_B(NEG16(14)),\n\t\tMIPS64_MFC0(15, 31, 0),                           /* move COP0 DeSave to $15 */\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\tconst uint32_t *code = enable_step ? code_enable : code_disable;\n\tunsigned code_len = enable_step ? ARRAY_SIZE(code_enable) :\n\t\t\t\t\t  ARRAY_SIZE(code_disable);\n\n\treturn mips64_pracc_exec(ejtag_info,\n\t\t\t\t code_len, code, 0, NULL, 0, NULL);\n}\n\nint mips64_ejtag_exit_debug(struct mips_ejtag *ejtag_info)\n{\n\tconst uint32_t code[] = {\n\t\tMIPS64_DRET,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t\tMIPS64_NOP,\n\t};\n\tLOG_DEBUG(\"enter mips64_pracc_exec\");\n\treturn mips64_pracc_exec(ejtag_info,\n\t\t\t\t ARRAY_SIZE(code), code, 0, NULL, 0, NULL);\n}\n\nint mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint64_t *data)\n{\n\tstruct jtag_tap *tap;\n\n\ttap = ejtag_info->tap;\n\tassert(tap);\n\n\tstruct scan_field fields[2];\n\tuint8_t spracc = 0;\n\tuint8_t t[8] = {0, 0, 0, 0, 0, 0, 0, 0};\n\n\t/* fastdata 1-bit register */\n\tfields[0].num_bits = 1;\n\tfields[0].out_value = &spracc;\n\tfields[0].in_value = NULL;\n\n\t/* processor access data register 64 bit */\n\tfields[1].num_bits = 64;\n\tfields[1].out_value = t;\n\n\tif (write_t) {\n\t\tfields[1].in_value = NULL;\n\t\tbuf_set_u64(t, 0, 64, *data);\n\t} else\n\t\tfields[1].in_value = (uint8_t *) data;\n\n\tjtag_add_dr_scan(tap, 2, fields, TAP_IDLE);\n\n\tif (!write_t && data)\n\t\tjtag_add_callback(mips_le_to_h_u64,\n\t\t\t(jtag_callback_data_t) data);\n\tkeep_alive();\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_ejtag.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_MIPS_EJTAG_H\n#define OPENOCD_TARGET_MIPS_EJTAG_H\n\n#include <jtag/jtag.h>\n\n/* tap instructions */\n#define EJTAG_INST_IDCODE\t\t0x01\n#define EJTAG_INST_IMPCODE\t\t0x03\n#define EJTAG_INST_ADDRESS\t\t0x08\n#define EJTAG_INST_DATA\t\t\t0x09\n#define EJTAG_INST_CONTROL\t\t0x0A\n#define EJTAG_INST_ALL\t\t\t0x0B\n#define EJTAG_INST_EJTAGBOOT\t0x0C\n#define EJTAG_INST_NORMALBOOT\t0x0D\n#define EJTAG_INST_FASTDATA\t\t0x0E\n#define EJTAG_INST_TCBCONTROLA\t0x10\n#define EJTAG_INST_TCBCONTROLB\t0x11\n#define EJTAG_INST_TCBDATA\t\t0x12\n#define EJTAG_INST_TCBCONTROLC\t0x13\n#define EJTAG_INST_PCSAMPLE\t\t0x14\n#define EJTAG_INST_TCBCONTROLD\t0x15\n#define EJTAG_INST_TCBCONTROLE\t0x16\n#define EJTAG_INST_FDC\t\t\t0x17\n#define EJTAG_INST_BYPASS\t\t0xFF\n\n/* microchip PIC32MX specific instructions */\n#define MTAP_SW_MTAP\t\t\t0x04\n#define MTAP_SW_ETAP\t\t\t0x05\n#define MTAP_COMMAND\t\t\t0x07\n\n/* microchip specific cmds */\n#define MCHP_ASERT_RST\t\t\t0xd1\n#define MCHP_DE_ASSERT_RST\t\t0xd0\n#define MCHP_ERASE\t\t\t\t0xfc\n#define MCHP_STATUS\t\t\t\t0x00\n\n/* ejtag control register bits ECR */\n#define EJTAG_CTRL_TOF\t\t\t(1 << 1)\n#define EJTAG_CTRL_TIF\t\t\t(1 << 2)\n#define EJTAG_CTRL_BRKST\t\t(1 << 3)\n#define EJTAG_CTRL_DLOCK\t\t(1 << 5)\n#define EJTAG_CTRL_DRWN\t\t\t(1 << 9)\n#define EJTAG_CTRL_DERR\t\t\t(1 << 10)\n#define EJTAG_CTRL_DSTRT\t\t(1 << 11)\n#define EJTAG_CTRL_JTAGBRK\t\t(1 << 12)\n#define EJTAG_CTRL_DBGISA\t\t(1 << 13)\n#define EJTAG_CTRL_SETDEV\t\t(1 << 14)\n#define EJTAG_CTRL_PROBEN\t\t(1 << 15)\n#define EJTAG_CTRL_PRRST\t\t(1 << 16)\n#define EJTAG_CTRL_DMAACC\t\t(1 << 17)\n#define EJTAG_CTRL_PRACC\t\t(1 << 18)\n#define EJTAG_CTRL_PRNW\t\t\t(1 << 19)\n#define EJTAG_CTRL_PERRST\t\t(1 << 20)\n#define EJTAG_CTRL_SYNC\t\t\t(1 << 23)\n#define EJTAG_CTRL_DNM\t\t\t(1 << 28)\n#define EJTAG_CTRL_ROCC\t\t\t(1 << 31)\n\n/* Debug Register (CP0 Register 23, Select 0) */\n\n#define EJTAG_DEBUG_DSS\t\t\t(1 << 0)\n#define EJTAG_DEBUG_DBP\t\t\t(1 << 1)\n#define EJTAG_DEBUG_DDBL\t\t(1 << 2)\n#define EJTAG_DEBUG_DDBS\t\t(1 << 3)\n#define EJTAG_DEBUG_DIB\t\t\t(1 << 4)\n#define EJTAG_DEBUG_DINT\t\t(1 << 5)\n#define EJTAG_DEBUG_OFFLINE\t\t(1 << 7)\n#define EJTAG_DEBUG_SST\t\t\t(1 << 8)\n#define EJTAG_DEBUG_NOSST\t\t(1 << 9)\n#define EJTAG_DEBUG_DDBLIMPR\t(1 << 18)\n#define EJTAG_DEBUG_DDBSIMPR\t(1 << 19)\n#define EJTAG_DEBUG_IEXI\t\t(1 << 20)\n#define EJTAG_DEBUG_DBUSEP\t\t(1 << 21)\n#define EJTAG_DEBUG_CACHEEP\t\t(1 << 22)\n#define EJTAG_DEBUG_MCHECKP\t\t(1 << 23)\n#define EJTAG_DEBUG_IBUSEP\t\t(1 << 24)\n#define EJTAG_DEBUG_COUNTDM\t\t(1 << 25)\n#define EJTAG_DEBUG_HALT\t\t(1 << 26)\n#define EJTAG_DEBUG_DOZE\t\t(1 << 27)\n#define EJTAG_DEBUG_LSNM\t\t(1 << 28)\n#define EJTAG_DEBUG_NODCR\t\t(1 << 29)\n#define EJTAG_DEBUG_DM\t\t\t(1 << 30)\n#define EJTAG_DEBUG_DBD\t\t\t(1 << 31)\n\n/* implementation MIPS register bits.\n * Bits marked with V20 or v2.0 mean that, this registers supported only\n * by EJTAG v2.0. Bits marked with Lexra or BMIPS are different from the\n * official EJATG.\n * NOTE: Lexra or BMIPS use EJTAG v2.0 */\n\n#define EJTAG_IMP_HAS(x)\t\t\t(ejtag_info->impcode & (x))\n/* v2.0(Lexra) 29 - 1’b1 - Lexra Internal Trace Buffer implemented. This bit\n * overlaps with version bit of MIPS EJTAG specification. */\n#define EJTAG_V26_IMP_R3K\t\t(1 << 28)\n/* v2.0 - 24:25 - 2’b00- No profiling support */\n#define EJTAG_V26_IMP_DINT\t\t(1 << 24)\n#define EJTAG_V20_IMP_SDBBP\t\t(1 << 23) /* 1’b1 - sdbbp is Special2 Opcode */\n#define EJTAG_IMP_ASID8\t\t\t(1 << 22)\n#define EJTAG_IMP_ASID6\t\t\t(1 << 21)\n#define EJTAG_V20_IMP_COMPLEX_BREAK\t(1 << 20) /* Complex Breaks supported*/\n#define EJTAG_V20_IMP_EADDR_NO32BIT\t(1 << 19) /* EJTAG_ADDR > 32 bits wide */\n#define EJTAG_V20_IMP_DCACHE_COH\t(1 << 18) /* DCache does keep DMA coherent */\n#define EJTAG_V20_IMP_ICACHE_COH\t(1 << 17) /* DCache does keep DMA coherent */\n#define EJTAG_IMP_MIPS16\t\t(1 << 16)\n#define EJTAG_IMP_NODMA\t\t\t(1 << 14)\n/* v2.0 - 11:13 external PC trace. Trace PC Width. */\n/* v2.0 - 8:10 external PC trace. PCST Width and DCLK Division Factor */\n#define EJTAG_V20_IMP_NOPB\t\t(1 << 7) /* no processor breaks */\n#define EJTAG_V20_IMP_NODB\t\t(1 << 6) /* no data breaks */\n#define EJTAG_V20_IMP_NOIB\t\t(1 << 5) /* no instruction breaks implemented */\n/* v2.0 - 1:4 Number of Break Channels. */\n#define EJTAG_V20_IMP_BCHANNELS_MASK\t0xf\n#define EJTAG_V20_IMP_BCHANNELS_SHIFT\t1\n#define EJTAG_IMP_MIPS64\t\t(1 << 0)\n\n/* Debug Control Register DCR */\n#define EJTAG_DCR\t\t\t\t0xFF300000\n#define EJTAG_DCR_ENM\t\t\t(1 << 29)\n#define EJTAG_DCR_DB\t\t\t(1 << 17)\n#define EJTAG_DCR_IB\t\t\t(1 << 16)\n#define EJTAG_DCR_INTE\t\t\t(1 << 4)\n#define EJTAG_DCR_MP\t\t\t(1 << 2)\n\n/* breakpoint support */\n/* EJTAG_V20_* was tested on Broadcom BCM7401\n * and may or will differ with other hardware. For example EZ4021-FC. */\n#define EJTAG_V20_IBS\t\t\t0xFF300004\n#define EJTAG_V20_IBA0\t\t\t0xFF300100\n#define EJTAG_V20_IBC_OFFS\t\t0x4\t/* IBC Offset */\n#define EJTAG_V20_IBM_OFFS\t\t0x8\n#define EJTAG_V20_IBAN_STEP\t\t0x10\t/* Offset for next channel */\n#define EJTAG_V20_DBS\t\t\t0xFF300008\n#define EJTAG_V20_DBA0\t\t\t0xFF300200\n#define EJTAG_V20_DBC_OFFS\t\t0x4\n#define EJTAG_V20_DBM_OFFS\t\t0x8\n#define EJTAG_V20_DBV_OFFS\t\t0xc\n#define EJTAG_V20_DBAN_STEP\t\t0x10\n\n#define EJTAG_V25_IBS\t\t\t0xFF301000\n#define EJTAG_V25_IBA0\t\t\t0xFF301100\n#define EJTAG_V25_IBM_OFFS\t\t0x8\n#define EJTAG_V25_IBASID_OFFS\t\t0x10\n#define EJTAG_V25_IBC_OFFS\t\t0x18\n#define EJTAG_V25_IBAN_STEP\t\t0x100\n#define EJTAG_V25_DBS\t\t\t0xFF302000\n#define EJTAG_V25_DBA0\t\t\t0xFF302100\n#define EJTAG_V25_DBM_OFFS\t\t0x8\n#define EJTAG_V25_DBASID_OFFS\t\t0x10\n#define EJTAG_V25_DBC_OFFS\t\t0x18\n#define EJTAG_V25_DBV_OFFS\t\t0x20\n#define EJTAG_V25_DBAN_STEP\t\t0x100\n\n#define\tEJTAG_DBCN_NOSB\t\t\t(1 << 13)\n#define\tEJTAG_DBCN_NOLB\t\t\t(1 << 12)\n#define\tEJTAG_DBCN_BLM_MASK\t\t0xff\n#define\tEJTAG_DBCN_BLM_SHIFT\t4\n#define\tEJTAG_DBCN_BE\t\t\t(1 << 0)\n\n#define EJTAG_VERSION_20\t\t0\n#define EJTAG_VERSION_25\t\t1\n#define EJTAG_VERSION_26\t\t2\n#define EJTAG_VERSION_31\t\t3\n#define EJTAG_VERSION_41\t\t4\n#define EJTAG_VERSION_51\t\t5\n\n/*\n * Additional defines for MIPS64 EJTAG\n */\n#define EJTAG64_DCR\t\t\t0xFFFFFFFFFF300000ull\n#define EJTAG64_DCR_ENM\t\t\t(1llu << 29)\n#define EJTAG64_DCR_DB\t\t\t(1llu << 17)\n#define EJTAG64_DCR_IB\t\t\t(1llu << 16)\n#define EJTAG64_DCR_INTE\t\t(1llu << 4)\n#define EJTAG64_DCR_MP\t\t\t(1llu << 2)\n#define EJTAG64_V25_DBA0\t\t0xFFFFFFFFFF302100ull\n#define EJTAG64_V25_DBS\t\t\t0xFFFFFFFFFF302000ull\n#define EJTAG64_V25_IBA0\t\t0xFFFFFFFFFF301100ull\n#define EJTAG64_V25_IBS\t\t\t0xFFFFFFFFFF301000ull\n\nstruct mips_ejtag {\n\tstruct jtag_tap *tap;\n\tuint32_t impcode;\n\tuint32_t idcode;\n\tuint32_t ejtag_ctrl;\n\tint fast_access_save;\n\tuint32_t config_regs;\t/* number of config registers read */\n\tuint32_t config[4];\t/* cp0 config to config3 */\n\n\tuint32_t reg8;\n\tuint32_t reg9;\n\tunsigned scan_delay;\n\tint mode;\n\tuint32_t pa_ctrl;\n\tuint32_t pa_addr;\n\tunsigned int ejtag_version;\n\tuint32_t isa;\n\tuint32_t endianness;\n\n\t/* Memory-Mapped Registers. This addresses are not same on different\n\t * EJTAG versions. */\n\tuint32_t debug_caps;\n\tuint32_t ejtag_ibs_addr;\t/* Instruction Address Break Status */\n\tuint32_t ejtag_iba0_addr;\t/* IAB channel 0 */\n\tuint32_t ejtag_ibc_offs;\t/* IAB Control offset */\n\tuint32_t ejtag_ibm_offs;\t/* IAB Mask offset */\n\tuint32_t ejtag_ibasid_offs;\t/* IAB ASID (4Kc) */\n\n\tuint32_t ejtag_dbs_addr;\t/* Data Address Break Status Register */\n\tuint32_t ejtag_dba0_addr;\t/* DAB channel 0 */\n\tuint32_t ejtag_dbc_offs;\t/* DAB Control offset */\n\tuint32_t ejtag_dbm_offs;\t/* DAB Mask offset */\n\tuint32_t ejtag_dbv_offs;\t/* DAB Value offset */\n\tuint32_t ejtag_dbasid_offs;\t/* DAB ASID (4Kc) */\n\n\tuint32_t ejtag_iba_step_size;\n\tuint32_t ejtag_dba_step_size;\t/* size of step till next *DBAn register. */\n};\n\nvoid mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr);\nint mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info);\nint mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info);\nint mips64_ejtag_exit_debug(struct mips_ejtag *ejtag_info);\nint mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info);\nvoid mips_ejtag_add_scan_96(struct mips_ejtag *ejtag_info,\n\t\t\t    uint32_t ctrl, uint32_t data, uint8_t *in_scan_buf);\nint mips_ejtag_drscan_64(struct mips_ejtag *ejtag_info, uint64_t *data);\nvoid mips_ejtag_drscan_32_out(struct mips_ejtag *ejtag_info, uint32_t data);\nint mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data);\nvoid mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data);\nint mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data);\nint mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_t *data);\nint mips64_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, bool write_t, uint64_t *data);\n\nint mips_ejtag_init(struct mips_ejtag *ejtag_info);\nint mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step);\nint mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step);\n\nstatic inline void mips_le_to_h_u32(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint32_t *)arg) = le_to_h_u32(in);\n}\n\nstatic inline void mips_le_to_h_u64(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint64_t *)arg) = le_to_h_u64(in);\n}\n\n#endif /* OPENOCD_TARGET_MIPS_EJTAG_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_m4k.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2009 by David N. Claffey <dnclaffey@gmail.com>          *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"mips32.h\"\n#include \"mips_m4k.h\"\n#include \"mips32_dmaacc.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"smp.h\"\n\nstatic void mips_m4k_enable_breakpoints(struct target *target);\nstatic void mips_m4k_enable_watchpoints(struct target *target);\nstatic int mips_m4k_set_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\nstatic int mips_m4k_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\nstatic int mips_m4k_internal_restore(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints,\n\t\tint debug_execution);\nstatic int mips_m4k_halt(struct target *target);\nstatic int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, const uint8_t *buffer);\nstatic int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint8_t *buffer);\n\nstatic int mips_m4k_examine_debug_reason(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tuint32_t break_status;\n\tint retval;\n\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\t\tif (ejtag_info->debug_caps & EJTAG_DCR_IB) {\n\t\t\t/* get info about inst breakpoint support */\n\t\t\tretval = target_read_u32(target,\n\t\t\t\tejtag_info->ejtag_ibs_addr, &break_status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (break_status & 0x1f) {\n\t\t\t\t/* we have halted on a  breakpoint */\n\t\t\t\tretval = target_write_u32(target,\n\t\t\t\t\tejtag_info->ejtag_ibs_addr, 0);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\t}\n\t\t}\n\n\t\tif (ejtag_info->debug_caps & EJTAG_DCR_DB) {\n\t\t\t/* get info about data breakpoint support */\n\t\t\tretval = target_read_u32(target,\n\t\t\t\tejtag_info->ejtag_dbs_addr, &break_status);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (break_status & 0x1f) {\n\t\t\t\t/* we have halted on a  breakpoint */\n\t\t\t\tretval = target_write_u32(target,\n\t\t\t\t\tejtag_info->ejtag_dbs_addr, 0);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_debug_entry(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tmips32_save_context(target);\n\n\t/* make sure stepping disabled, SSt bit in CP0 debug register cleared */\n\tmips_ejtag_config_step(ejtag_info, 0);\n\n\t/* make sure break unit configured */\n\tmips32_configure_break_unit(target);\n\n\t/* attempt to find halt reason */\n\tmips_m4k_examine_debug_reason(target);\n\n\tmips32_read_config_regs(target);\n\n\t/* default to mips32 isa, it will be changed below if required */\n\tmips32->isa_mode = MIPS32_ISA_MIPS32;\n\n\t/* other than mips32 only and isa bit set ? */\n\tif (mips32->isa_imp && buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1))\n\t\tmips32->isa_mode = mips32->isa_imp == 2 ? MIPS32_ISA_MIPS16E : MIPS32_ISA_MMIPS32;\n\n\tLOG_DEBUG(\"entered debug state at PC 0x%\" PRIx32 \", target->state: %s\",\n\t\t\tbuf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),\n\t\t\ttarget_state_name(target));\n\n\treturn ERROR_OK;\n}\n\nstatic struct target *get_mips_m4k(struct target *target, int32_t coreid)\n{\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tstruct target *curr = head->target;\n\t\tif ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))\n\t\t\treturn curr;\n\t}\n\treturn target;\n}\n\nstatic int mips_m4k_halt_smp(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tint ret = ERROR_OK;\n\t\tstruct target *curr = head->target;\n\t\tif ((curr != target) && (curr->state != TARGET_HALTED))\n\t\t\tret = mips_m4k_halt(curr);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"halt failed target->coreid: %\" PRId32, curr->coreid);\n\t\t\tretval = ret;\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int update_halt_gdb(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tif (target->gdb_service->core[0] == -1) {\n\t\ttarget->gdb_service->target = target;\n\t\ttarget->gdb_service->core[0] = target->coreid;\n\t\tretval = mips_m4k_halt_smp(target);\n\t}\n\treturn retval;\n}\n\nstatic int mips_m4k_poll(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tuint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;\n\tenum target_state prev_target_state = target->state;\n\n\t/*  toggle to another core is done by gdb as follow */\n\t/*  maint packet J core_id */\n\t/*  continue */\n\t/*  the next polling trigger an halt event sent to gdb */\n\tif ((target->state == TARGET_HALTED) && (target->smp) &&\n\t\t(target->gdb_service) &&\n\t\t(!target->gdb_service->target)) {\n\t\ttarget->gdb_service->target =\n\t\t\tget_mips_m4k(target, target->gdb_service->core[1]);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\treturn retval;\n\t}\n\n\t/* read ejtag control reg */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tretval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tejtag_info->isa = (ejtag_ctrl & EJTAG_CTRL_DBGISA) ? 1 : 0;\n\n\t/* clear this bit before handling polling\n\t * as after reset registers will read zero */\n\tif (ejtag_ctrl & EJTAG_CTRL_ROCC) {\n\t\t/* we have detected a reset, clear flag\n\t\t * otherwise ejtag will not work */\n\t\tejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;\n\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\t\tretval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"Reset Detected\");\n\t}\n\n\t/* check for processor halted */\n\tif (ejtag_ctrl & EJTAG_CTRL_BRKST) {\n\t\tif ((target->state != TARGET_HALTED)\n\t\t    && (target->state != TARGET_DEBUG_RUNNING)) {\n\t\t\tif (target->state == TARGET_UNKNOWN)\n\t\t\t\tLOG_DEBUG(\"EJTAG_CTRL_BRKST already set during server startup.\");\n\n\t\t\t/* OpenOCD was was probably started on the board with EJTAG_CTRL_BRKST already set\n\t\t\t * (maybe put on by HALT-ing the board in the previous session).\n\t\t\t *\n\t\t\t * Force enable debug entry for this session.\n\t\t\t */\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tretval = mips_m4k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (target->smp &&\n\t\t\t\t((prev_target_state == TARGET_RUNNING)\n\t\t\t     || (prev_target_state == TARGET_RESET))) {\n\t\t\t\tretval = update_halt_gdb(target);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t} else if (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = mips_m4k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (target->smp) {\n\t\t\t\tretval = update_halt_gdb(target);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n\n/*\tLOG_DEBUG(\"ctrl = 0x%08X\", ejtag_ctrl); */\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_halt(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {\n\t\t\tLOG_ERROR(\"can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\t/* we came here in a reset_halt or reset_init sequence\n\t\t\t * debug entry was already prepared in mips_m4k_assert_reset()\n\t\t\t */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* break processor */\n\tmips_ejtag_enter_debug(ejtag_info);\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_assert_reset(struct target *target)\n{\n\tstruct mips_m4k_common *mips_m4k = target_to_m4k(target);\n\tstruct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;\n\n\t/* TODO: apply hw reset signal in not examined state */\n\tif (!(target_was_examined(target))) {\n\t\tLOG_WARNING(\"Reset is not asserted because the target is not examined.\");\n\t\tLOG_WARNING(\"Use a reset button or power cycle the target.\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\t/* some cores support connecting while srst is asserted\n\t * use that mode is it has been configured */\n\n\tbool srst_asserted = false;\n\n\tif (!(jtag_reset_config & RESET_SRST_PULLS_TRST) &&\n\t\t\t(jtag_reset_config & RESET_SRST_NO_GATING)) {\n\t\tjtag_add_reset(0, 1);\n\t\tsrst_asserted = true;\n\t}\n\n\n\t/* EJTAG before v2.5/2.6 does not support EJTAGBOOT or NORMALBOOT */\n\tif (ejtag_info->ejtag_version != EJTAG_VERSION_20) {\n\t\tif (target->reset_halt) {\n\t\t\t/* use hardware to catch reset */\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);\n\t\t} else\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);\n\t}\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\t/* here we should issue a srst only, but we may have to assert trst as well */\n\t\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\t\tjtag_add_reset(1, 1);\n\t\telse if (!srst_asserted)\n\t\t\tjtag_add_reset(0, 1);\n\t} else if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\t} else {\n\t\tif (mips_m4k->is_pic32mx) {\n\t\t\tLOG_DEBUG(\"Using MTAP reset to reset processor...\");\n\n\t\t\t/* use microchip specific MTAP reset */\n\t\t\tmips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP);\n\t\t\tmips_ejtag_set_instr(ejtag_info, MTAP_COMMAND);\n\n\t\t\tmips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);\n\t\t\tmips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);\n\t\t\tmips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);\n\t\t} else {\n\t\t\t/* use ejtag reset - not supported by all cores */\n\t\t\tuint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;\n\t\t\tLOG_DEBUG(\"Using EJTAG reset (PRRST) to reset processor...\");\n\t\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\t\t\tmips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);\n\t\t}\n\t}\n\n\ttarget->state = TARGET_RESET;\n\tjtag_add_sleep(50000);\n\n\tregister_cache_invalidate(mips_m4k->mips32.core_cache);\n\n\tif (target->reset_halt) {\n\t\tint retval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_deassert_reset(struct target *target)\n{\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\t/* deassert reset lines */\n\tjtag_add_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_single_step_core(struct target *target)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\t/* configure single step mode */\n\tmips_ejtag_config_step(ejtag_info, 1);\n\n\t/* disable interrupts while stepping */\n\tmips32_enable_interrupts(target, 0);\n\n\t/* exit debug mode */\n\tmips_ejtag_exit_debug(ejtag_info);\n\n\tmips_m4k_debug_entry(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_restore_smp(struct target *target, uint32_t address, int handle_breakpoints)\n{\n\tint retval = ERROR_OK;\n\tstruct target_list *head;\n\n\tforeach_smp_target(head, target->smp_targets) {\n\t\tint ret = ERROR_OK;\n\t\tstruct target *curr = head->target;\n\t\tif ((curr != target) && (curr->state != TARGET_RUNNING)) {\n\t\t\t/*  resume current address , not in step mode */\n\t\t\tret = mips_m4k_internal_restore(curr, 1, address,\n\t\t\t\t\t\t   handle_breakpoints, 0);\n\n\t\t\tif (ret != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"target->coreid :%\" PRId32 \" failed to resume at address :0x%\" PRIx32,\n\t\t\t\t\t\t  curr->coreid, address);\n\t\t\t\tretval = ret;\n\t\t\t}\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int mips_m4k_internal_restore(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct breakpoint *breakpoint = NULL;\n\tuint32_t resume_pc;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tmips_m4k_enable_breakpoints(target);\n\t\tmips_m4k_enable_watchpoints(target);\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tmips_m4k_isa_filter(mips32->isa_imp, &address);\n\t\tbuf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);\n\t\tmips32->core_cache->reg_list[MIPS32_PC].dirty = true;\n\t\tmips32->core_cache->reg_list[MIPS32_PC].valid = true;\n\t}\n\n\tif ((mips32->isa_imp > 1) &&  debug_execution)\t/* if more than one isa supported */\n\t\tbuf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);\n\n\tif (!current)\n\t\tresume_pc = address;\n\telse\n\t\tresume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);\n\n\tmips32_restore_context(target);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at \" TARGET_ADDR_FMT \"\",\n\t\t\t\t\t  breakpoint->address);\n\t\t\tmips_m4k_unset_breakpoint(target, breakpoint);\n\t\t\tmips_m4k_single_step_core(target);\n\t\t\tmips_m4k_set_breakpoint(target, breakpoint);\n\t\t}\n\t}\n\n\t/* enable interrupts if we are running */\n\tmips32_enable_interrupts(target, !debug_execution);\n\n\t/* exit debug mode */\n\tmips_ejtag_exit_debug(ejtag_info);\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(mips32->core_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"target resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"target debug resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_resume(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tint retval = ERROR_OK;\n\n\t/* dummy resume for smp toggle in order to reduce gdb impact  */\n\tif ((target->smp) && (target->gdb_service->core[1] != -1)) {\n\t\t/*   simulate a start and halt of target */\n\t\ttarget->gdb_service->target = NULL;\n\t\ttarget->gdb_service->core[0] = target->gdb_service->core[1];\n\t\t/*  fake resume at next poll we play the  target core[1], see poll*/\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\treturn retval;\n\t}\n\n\tretval = mips_m4k_internal_restore(target, current, address,\n\t\t\t\thandle_breakpoints,\n\t\t\t\tdebug_execution);\n\n\tif (retval == ERROR_OK && target->smp) {\n\t\ttarget->gdb_service->core[0] = -1;\n\t\tretval = mips_m4k_restore_smp(target, address, handle_breakpoints);\n\t}\n\n\treturn retval;\n}\n\nstatic int mips_m4k_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct breakpoint *breakpoint = NULL;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tmips_m4k_isa_filter(mips32->isa_imp, &address);\n\t\tbuf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);\n\t\tmips32->core_cache->reg_list[MIPS32_PC].dirty = true;\n\t\tmips32->core_cache->reg_list[MIPS32_PC].valid = true;\n\t}\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\tbuf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32));\n\t\tif (breakpoint)\n\t\t\tmips_m4k_unset_breakpoint(target, breakpoint);\n\t}\n\n\t/* restore context */\n\tmips32_restore_context(target);\n\n\t/* configure single step mode */\n\tmips_ejtag_config_step(ejtag_info, 1);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\t/* disable interrupts while stepping */\n\tmips32_enable_interrupts(target, 0);\n\n\t/* exit debug mode */\n\tmips_ejtag_exit_debug(ejtag_info);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(mips32->core_cache);\n\n\tLOG_DEBUG(\"target stepped \");\n\tmips_m4k_debug_entry(target);\n\n\tif (breakpoint)\n\t\tmips_m4k_set_breakpoint(target, breakpoint);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\treturn ERROR_OK;\n}\n\nstatic void mips_m4k_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\t/* set any pending breakpoints */\n\twhile (breakpoint) {\n\t\tif (!breakpoint->is_set)\n\t\t\tmips_m4k_set_breakpoint(target, breakpoint);\n\t\tbreakpoint = breakpoint->next;\n\t}\n}\n\nstatic int mips_m4k_set_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct mips32_comparator *comparator_list = mips32->inst_break_list;\n\tint retval;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tint bp_num = 0;\n\n\t\twhile (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))\n\t\t\tbp_num++;\n\t\tif (bp_num >= mips32->num_inst_bpoints) {\n\t\t\tLOG_ERROR(\"Can not find free FP Comparator(bpid: %\" PRIu32 \")\",\n\t\t\t\t\tbreakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint_hw_set(breakpoint, bp_num);\n\t\tcomparator_list[bp_num].used = 1;\n\t\tcomparator_list[bp_num].bp_value = breakpoint->address;\n\n\t\tif (breakpoint->length != 4)\t\t\t/* make sure isa bit set */\n\t\t\tcomparator_list[bp_num].bp_value |= 1;\n\t\telse\t\t\t\t\t\t/* make sure isa bit cleared */\n\t\t\tcomparator_list[bp_num].bp_value &= ~1;\n\n\t\t/* EJTAG 2.0 uses 30bit IBA. First 2 bits are reserved.\n\t\t * Warning: there is no IB ASID registers in 2.0.\n\t\t * Do not set it! :) */\n\t\tif (ejtag_info->ejtag_version == EJTAG_VERSION_20)\n\t\t\tcomparator_list[bp_num].bp_value &= 0xFFFFFFFC;\n\n\t\ttarget_write_u32(target, comparator_list[bp_num].reg_address,\n\t\t\t\tcomparator_list[bp_num].bp_value);\n\t\ttarget_write_u32(target, comparator_list[bp_num].reg_address +\n\t\t\t\t ejtag_info->ejtag_ibm_offs, 0x00000000);\n\t\ttarget_write_u32(target, comparator_list[bp_num].reg_address +\n\t\t\t\t ejtag_info->ejtag_ibc_offs, 1);\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \", bp_num %i bp_value 0x%\" PRIx32 \"\",\n\t\t\t\t  breakpoint->unique_id,\n\t\t\t\t  bp_num, comparator_list[bp_num].bp_value);\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\n\t\tuint32_t isa_req = breakpoint->length & 1;\t/* micro mips request bit */\n\t\tuint32_t bplength = breakpoint->length & ~1;\t/* drop micro mips request bit for length */\n\t\tuint32_t bpaddr = breakpoint->address & ~1;\t/* drop isa bit from address, if set */\n\n\t\tif (bplength == 4) {\n\t\t\tuint32_t verify = 0xffffffff;\n\t\t\tuint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);\n\t\t\tif (ejtag_info->endianness && isa_req)\n\t\t\t\tsdbbp32_instr = SWAP16(sdbbp32_instr);\n\n\t\t\tif ((breakpoint->address & 3) == 0) {\t/* word aligned */\n\n\t\t\t\tretval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tretval = target_write_u32(target, bpaddr, sdbbp32_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tretval = target_read_u32(target, bpaddr, &verify);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tif (verify != sdbbp32_instr)\n\t\t\t\t\tverify = 0;\n\n\t\t\t} else {\t/* 16 bit aligned */\n\t\t\t\tretval = target_read_memory(target, bpaddr, 2, 2, breakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tuint8_t sdbbp_buf[4];\n\t\t\t\ttarget_buffer_set_u32(target, sdbbp_buf, sdbbp32_instr);\n\n\t\t\t\tretval = target_write_memory(target, bpaddr, 2, 2, sdbbp_buf);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tretval = target_read_memory(target, bpaddr, 2, 2, sdbbp_buf);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tif (target_buffer_get_u32(target, sdbbp_buf) != sdbbp32_instr)\n\t\t\t\t\tverify = 0;\n\t\t\t}\n\n\t\t\tif (verify == 0) {\n\t\t\t\tLOG_ERROR(\"Unable to set 32bit breakpoint at address %08\" TARGET_PRIxADDR\n\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\n\t\t} else {\n\t\t\tuint16_t verify = 0xffff;\n\n\t\t\tretval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_write_u16(target, bpaddr, MIPS16_SDBBP(isa_req));\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_read_u16(target, bpaddr, &verify);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (verify != MIPS16_SDBBP(isa_req)) {\n\t\t\t\tLOG_ERROR(\"Unable to set 16bit breakpoint at address %08\" TARGET_PRIxADDR\n\t\t\t\t\t\t\" - check that memory is read/writable\", breakpoint->address);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\n\t\tbreakpoint->is_set = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct mips32_comparator *comparator_list = mips32->inst_break_list;\n\tint retval;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tint bp_num = breakpoint->number;\n\t\tif (bp_num >= mips32->num_inst_bpoints) {\n\t\t\tLOG_DEBUG(\"Invalid FP Comparator number in breakpoint (bpid: %\" PRIu32 \")\",\n\t\t\t\t\t  breakpoint->unique_id);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \" - releasing hw: %d\",\n\t\t\t\tbreakpoint->unique_id,\n\t\t\t\tbp_num);\n\t\tcomparator_list[bp_num].used = 0;\n\t\tcomparator_list[bp_num].bp_value = 0;\n\t\ttarget_write_u32(target, comparator_list[bp_num].reg_address +\n\t\t\t\t ejtag_info->ejtag_ibc_offs, 0);\n\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tuint32_t isa_req = breakpoint->length & 1;\n\t\tuint32_t bplength = breakpoint->length & ~1;\n\t\tuint8_t current_instr[4];\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\t\tif (bplength == 4) {\n\t\t\tuint32_t sdbbp32_instr =  MIPS32_SDBBP(isa_req);\n\t\t\tif (ejtag_info->endianness && isa_req)\n\t\t\t\tsdbbp32_instr = SWAP16(sdbbp32_instr);\n\n\t\t\tif ((breakpoint->address & 3) == 0) {\t\t/* 32bit aligned */\n\t\t\t\t/* check that user program has not modified breakpoint instruction */\n\t\t\t\tretval = target_read_memory(target, breakpoint->address, 4, 1, current_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\t/**\n\t\t\t\t* target_read_memory() gets us data in _target_ endianness.\n\t\t\t\t* If we want to use this data on the host for comparisons with some macros\n\t\t\t\t* we must first transform it to _host_ endianness using target_buffer_get_u16().\n\t\t\t\t*/\n\t\t\t\tif (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {\n\t\t\t\t\tretval = target_write_memory(target, breakpoint->address, 4, 1,\n\t\t\t\t\t\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t} else {\t/* 16bit aligned */\n\t\t\t\tretval = target_read_memory(target, breakpoint->address, 2, 2, current_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\n\t\t\t\tif (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {\n\t\t\t\t\tretval = target_write_memory(target, breakpoint->address, 2, 2,\n\t\t\t\t\t\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* check that user program has not modified breakpoint instruction */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 2, 1, current_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (target_buffer_get_u16(target, current_instr) == MIPS16_SDBBP(isa_req)) {\n\t\t\t\tretval = target_write_memory(target, breakpoint->address, 2, 1,\n\t\t\t\t\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif ((breakpoint->length > 5 || breakpoint->length < 2) ||\t\t/* out of range */\n\t\t(breakpoint->length == 4 && (breakpoint->address & 2)) ||\t/* mips32 unaligned */\n\t\t(mips32->isa_imp == MIPS32_ONLY && breakpoint->length != 4) ||\t/* misp32 specific */\n\t\t((mips32->isa_imp & 1) != (breakpoint->length & 1)))\t\t/* isa not implemented */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tif (mips32->num_inst_bpoints_avail < 1) {\n\t\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tmips32->num_inst_bpoints_avail--;\n\t}\n\n\treturn mips_m4k_set_breakpoint(target, breakpoint);\n}\n\nstatic int mips_m4k_remove_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (breakpoint->is_set)\n\t\tmips_m4k_unset_breakpoint(target, breakpoint);\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tmips32->num_inst_bpoints_avail++;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_set_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct mips32_comparator *comparator_list = mips32->data_break_list;\n\tint wp_num = 0;\n\t/*\n\t * watchpoint enabled, ignore all byte lanes in value register\n\t * and exclude both load and store accesses from  watchpoint\n\t * condition evaluation\n\t*/\n\tint enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE |\n\t\t\t(0xff << EJTAG_DBCN_BLM_SHIFT);\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))\n\t\twp_num++;\n\tif (wp_num >= mips32->num_data_bpoints) {\n\t\tLOG_ERROR(\"Can not find free FP Comparator\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (watchpoint->length != 4) {\n\t\tLOG_ERROR(\"Only watchpoints of length 4 are supported\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tif (watchpoint->address % 4) {\n\t\tLOG_ERROR(\"Watchpoints address should be word aligned\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tenable &= ~EJTAG_DBCN_NOLB;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tenable &= ~EJTAG_DBCN_NOSB;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tenable &= ~(EJTAG_DBCN_NOLB | EJTAG_DBCN_NOSB);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: watchpoint->rw neither read, write nor access\");\n\t}\n\n\twatchpoint_set(watchpoint, wp_num);\n\tcomparator_list[wp_num].used = 1;\n\tcomparator_list[wp_num].bp_value = watchpoint->address;\n\n\t/* EJTAG 2.0 uses 29bit DBA. First 3 bits are reserved.\n\t * There is as well no ASID register support. */\n\tif (ejtag_info->ejtag_version == EJTAG_VERSION_20)\n\t\tcomparator_list[wp_num].bp_value &= 0xFFFFFFF8;\n\telse\n\t\ttarget_write_u32(target, comparator_list[wp_num].reg_address +\n\t\t\t ejtag_info->ejtag_dbasid_offs, 0x00000000);\n\n\ttarget_write_u32(target, comparator_list[wp_num].reg_address,\n\t\t\t comparator_list[wp_num].bp_value);\n\ttarget_write_u32(target, comparator_list[wp_num].reg_address +\n\t\t\t ejtag_info->ejtag_dbm_offs, 0x00000000);\n\n\ttarget_write_u32(target, comparator_list[wp_num].reg_address +\n\t\t\t ejtag_info->ejtag_dbc_offs, enable);\n\t/* TODO: probably this value is ignored on 2.0 */\n\ttarget_write_u32(target, comparator_list[wp_num].reg_address +\n\t\t\t ejtag_info->ejtag_dbv_offs, 0);\n\tLOG_DEBUG(\"wp_num %i bp_value 0x%\" PRIx32 \"\", wp_num, comparator_list[wp_num].bp_value);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_unset_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct mips32_comparator *comparator_list = mips32->data_break_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wp_num = watchpoint->number;\n\tif (wp_num >= mips32->num_data_bpoints) {\n\t\tLOG_DEBUG(\"Invalid FP Comparator number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tcomparator_list[wp_num].used = 0;\n\tcomparator_list[wp_num].bp_value = 0;\n\ttarget_write_u32(target, comparator_list[wp_num].reg_address +\n\t\t\t ejtag_info->ejtag_dbc_offs, 0);\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (mips32->num_data_bpoints_avail < 1) {\n\t\tLOG_INFO(\"no hardware watchpoints available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tmips32->num_data_bpoints_avail--;\n\n\tmips_m4k_set_watchpoint(target, watchpoint);\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\tmips_m4k_unset_watchpoint(target, watchpoint);\n\n\tmips32->num_data_bpoints_avail++;\n\n\treturn ERROR_OK;\n}\n\nstatic void mips_m4k_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\t/* set any pending watchpoints */\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\tmips_m4k_set_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n}\n\nstatic int mips_m4k_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (size == 4 && count > 32) {\n\t\tint retval = mips_m4k_bulk_read_memory(target, address, count, buffer);\n\t\tif (retval == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t\tLOG_WARNING(\"Falling back to non-bulk read\");\n\t}\n\t/* since we don't know if buffer is aligned, we allocate new mem that is always aligned */\n\tvoid *t = NULL;\n\n\tif (size > 1) {\n\t\tt = malloc(count * size * sizeof(uint8_t));\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else\n\t\tt = buffer;\n\n\t/* if noDMA off, use DMAACC mode for memory read */\n\tint retval;\n\tif (ejtag_info->impcode & EJTAG_IMP_NODMA)\n\t\tretval = mips32_pracc_read_mem(ejtag_info, address, size, count, t);\n\telse\n\t\tretval = mips32_dmaacc_read_mem(ejtag_info, address, size, count, t);\n\n\t/* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */\n\t/* endianness, but byte array should represent target endianness       */\n\tif (retval == ERROR_OK) {\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\ttarget_buffer_set_u32_array(target, buffer, count, t);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_set_u16_array(target, buffer, count, t);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (size > 1)\n\t\tfree(t);\n\n\treturn retval;\n}\n\nstatic int mips_m4k_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (size == 4 && count > 32) {\n\t\tint retval = mips_m4k_bulk_write_memory(target, address, count, buffer);\n\t\tif (retval == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t\tLOG_WARNING(\"Falling back to non-bulk write\");\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/** correct endianness if we have word or hword access */\n\tvoid *t = NULL;\n\tif (size > 1) {\n\t\t/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */\n\t\t/* endianness, but byte array represents target endianness               */\n\t\tt = malloc(count * size * sizeof(uint8_t));\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\ttarget_buffer_get_u32_array(target, buffer, count, (uint32_t *)t);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_get_u16_array(target, buffer, count, (uint16_t *)t);\n\t\t\tbreak;\n\t\t}\n\t\tbuffer = t;\n\t}\n\n\t/* if noDMA off, use DMAACC mode for memory write */\n\tint retval;\n\tif (ejtag_info->impcode & EJTAG_IMP_NODMA)\n\t\tretval = mips32_pracc_write_mem(ejtag_info, address, size, count, buffer);\n\telse\n\t\tretval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, buffer);\n\n\tfree(t);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tmips32_build_reg_cache(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_init_arch_info(struct target *target,\n\t\tstruct mips_m4k_common *mips_m4k, struct jtag_tap *tap)\n{\n\tstruct mips32_common *mips32 = &mips_m4k->mips32;\n\n\tmips_m4k->common_magic = MIPSM4K_COMMON_MAGIC;\n\n\t/* initialize mips4k specific info */\n\tmips32_init_arch_info(target, mips32, tap);\n\tmips32->arch_info = mips_m4k;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct mips_m4k_common *mips_m4k = calloc(1, sizeof(struct mips_m4k_common));\n\n\tmips_m4k_init_arch_info(target, mips_m4k, target->tap);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_m4k_examine(struct target *target)\n{\n\tstruct mips_m4k_common *mips_m4k = target_to_m4k(target);\n\tstruct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;\n\n\tif (!target_was_examined(target)) {\n\t\tint retval = mips_ejtag_get_idcode(ejtag_info);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"idcode read failed\");\n\t\t\treturn retval;\n\t\t}\n\t\tif (((ejtag_info->idcode >> 1) & 0x7FF) == 0x29) {\n\t\t\t/* we are using a pic32mx so select ejtag port\n\t\t\t * as it is not selected by default */\n\t\t\tmips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);\n\t\t\tLOG_DEBUG(\"PIC32 Detected - using EJTAG Interface\");\n\t\t\tmips_m4k->is_pic32mx = true;\n\t\t}\n\t}\n\n\t/* init rest of ejtag interface */\n\tint retval = mips_ejtag_init(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn mips32_examine(target);\n}\n\nstatic int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, const uint8_t *buffer)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct working_area *fast_data_area;\n\tint retval;\n\tint write_t = 1;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", count: 0x%8.8\" PRIx32 \"\",\n\t\t\t  address, count);\n\n\t/* check alignment */\n\tif (address & 0x3u)\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (!mips32->fast_data_area) {\n\t\t/* Get memory for block write handler\n\t\t * we preserve this area between calls and gain a speed increase\n\t\t * of about 3kb/sec when writing flash\n\t\t * this will be released/nulled by the system when the target is resumed or reset */\n\t\tretval = target_alloc_working_area(target,\n\t\t\t\tMIPS32_FASTDATA_HANDLER_SIZE,\n\t\t\t\t&mips32->fast_data_area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"No working area available\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* reset fastadata state so the algo get reloaded */\n\t\tejtag_info->fast_access_save = -1;\n\t}\n\n\tfast_data_area = mips32->fast_data_area;\n\n\tif (address < (fast_data_area->address + fast_data_area->size) &&\n\t\t\tfast_data_area->address < (address + count)) {\n\t\tLOG_ERROR(\"fast_data (\" TARGET_ADDR_FMT \") is within write area \"\n\t\t\t  \"(\" TARGET_ADDR_FMT \"-\" TARGET_ADDR_FMT \").\",\n\t\t\t  fast_data_area->address, address, address + count);\n\t\tLOG_ERROR(\"Change work-area-phys or load_image address!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */\n\t/* but byte array represents target endianness                      */\n\tuint32_t *t = NULL;\n\tt = malloc(count * sizeof(uint32_t));\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_buffer_get_u32_array(target, buffer, count, t);\n\n\tretval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,\n\t\t\tcount, t);\n\n\tfree(t);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Fastdata access Failed\");\n\n\treturn retval;\n}\n\nstatic int mips_m4k_bulk_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint8_t *buffer)\n{\n\tstruct mips32_common *mips32 = target_to_mips32(target);\n\tstruct mips_ejtag *ejtag_info = &mips32->ejtag_info;\n\tstruct working_area *fast_data_area;\n\tint retval;\n\tint write_t = 0;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", count: 0x%8.8\" PRIx32 \"\",\n\t\t\taddress, count);\n\n\t/* check alignment */\n\tif (address & 0x3u)\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (!mips32->fast_data_area) {\n\t\t/* Get memory for block read handler\n\t\t * we preserve this area between calls and gain a speed increase\n\t\t * of about 3kb/sec when reading flash\n\t\t * this will be released/nulled by the system when the target is resumed or reset */\n\t\tretval = target_alloc_working_area(target,\n\t\t\t\tMIPS32_FASTDATA_HANDLER_SIZE,\n\t\t\t\t&mips32->fast_data_area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"No working area available\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* reset fastadata state so the algo get reloaded */\n\t\tejtag_info->fast_access_save = -1;\n\t}\n\n\tfast_data_area = mips32->fast_data_area;\n\n\tif (address < (fast_data_area->address + fast_data_area->size) &&\n\t\t\tfast_data_area->address < (address + count)) {\n\t\tLOG_ERROR(\"fast_data (\" TARGET_ADDR_FMT \") is within read area \"\n\t\t\t\t\"(\" TARGET_ADDR_FMT \"-\" TARGET_ADDR_FMT \").\",\n\t\t\t\tfast_data_area->address, address, address + count);\n\t\tLOG_ERROR(\"Change work-area-phys or load_image address!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */\n\t/* but byte array represents target endianness                      */\n\tuint32_t *t = malloc(count * sizeof(uint32_t));\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,\n\t\t\tcount, t);\n\n\ttarget_buffer_set_u32_array(target, buffer, count, t);\n\n\tfree(t);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Fastdata access Failed\");\n\n\treturn retval;\n}\n\nstatic int mips_m4k_verify_pointer(struct command_invocation *cmd,\n\t\tstruct mips_m4k_common *mips_m4k)\n{\n\tif (mips_m4k->common_magic != MIPSM4K_COMMON_MAGIC) {\n\t\tcommand_print(cmd, \"target is not an MIPS_M4K\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(mips_m4k_handle_cp0_command)\n{\n\tint retval;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct mips_m4k_common *mips_m4k = target_to_m4k(target);\n\tstruct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;\n\n\tretval = mips_m4k_verify_pointer(CMD, mips_m4k);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* two or more argument, access a single register/select (write if third argument is given) */\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\telse {\n\t\tuint32_t cp0_reg, cp0_sel;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);\n\n\t\tif (CMD_ARGC == 2) {\n\t\t\tuint32_t value;\n\t\t\tretval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access reg %\" PRIu32,\n\t\t\t\t\t\tcp0_reg);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"cp0 reg %\" PRIu32 \", select %\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\tcp0_reg, cp0_sel, value);\n\n\t\t} else if (CMD_ARGC == 3) {\n\t\t\tuint32_t value;\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);\n\t\t\tretval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\"couldn't access cp0 reg %\" PRIu32 \", select %\" PRIu32,\n\t\t\t\t\t\tcp0_reg,  cp0_sel);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t\tcommand_print(CMD, \"cp0 reg %\" PRIu32 \", select %\" PRIu32 \": %8.8\" PRIx32,\n\t\t\t\t\tcp0_reg, cp0_sel, value);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(mips_m4k_handle_scan_delay_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct mips_m4k_common *mips_m4k = target_to_m4k(target);\n\tstruct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;\n\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);\n\telse if (CMD_ARGC > 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"scan delay: %d nsec\", ejtag_info->scan_delay);\n\tif (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {\n\t\tejtag_info->mode = 0;\n\t\tcommand_print(CMD, \"running in legacy mode\");\n\t} else {\n\t\tejtag_info->mode = 1;\n\t\tcommand_print(CMD, \"running in fast queued mode\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration mips_m4k_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cp0\",\n\t\t.handler = mips_m4k_handle_cp0_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"regnum [value]\",\n\t\t.help = \"display/modify cp0 register\",\n\t},\n\t{\n\t\t.name = \"scan_delay\",\n\t\t.handler = mips_m4k_handle_scan_delay_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"display/set scan delay in nano seconds\",\n\t\t.usage = \"[value]\",\n\t},\n\t{\n\t\t.chain = smp_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration mips_m4k_command_handlers[] = {\n\t{\n\t\t.chain = mips32_command_handlers,\n\t},\n\t{\n\t\t.name = \"mips_m4k\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mips_m4k command group\",\n\t\t.usage = \"\",\n\t\t.chain = mips_m4k_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type mips_m4k_target = {\n\t.name = \"mips_m4k\",\n\n\t.poll = mips_m4k_poll,\n\t.arch_state = mips32_arch_state,\n\n\t.halt = mips_m4k_halt,\n\t.resume = mips_m4k_resume,\n\t.step = mips_m4k_step,\n\n\t.assert_reset = mips_m4k_assert_reset,\n\t.deassert_reset = mips_m4k_deassert_reset,\n\n\t.get_gdb_reg_list = mips32_get_gdb_reg_list,\n\n\t.read_memory = mips_m4k_read_memory,\n\t.write_memory = mips_m4k_write_memory,\n\t.checksum_memory = mips32_checksum_memory,\n\t.blank_check_memory = mips32_blank_check_memory,\n\n\t.run_algorithm = mips32_run_algorithm,\n\n\t.add_breakpoint = mips_m4k_add_breakpoint,\n\t.remove_breakpoint = mips_m4k_remove_breakpoint,\n\t.add_watchpoint = mips_m4k_add_watchpoint,\n\t.remove_watchpoint = mips_m4k_remove_watchpoint,\n\n\t.commands = mips_m4k_command_handlers,\n\t.target_create = mips_m4k_target_create,\n\t.init_target = mips_m4k_init_target,\n\t.examine = mips_m4k_examine,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_m4k.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by David T.L. Wong                                 *\n *                                                                         *\n *   Copyright (C) 2011 by Drasko DRASKOVIC                                *\n *   drasko.draskovic@gmail.com                                            *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_MIPS_M4K_H\n#define OPENOCD_TARGET_MIPS_M4K_H\n\nstruct target;\n\n#define MIPSM4K_COMMON_MAGIC\t0xB321B321U\n\nstruct mips_m4k_common {\n\tunsigned int common_magic;\n\n\tstruct mips32_common mips32;\n\n\tbool is_pic32mx;\n};\n\nstatic inline struct mips_m4k_common *\ntarget_to_m4k(struct target *target)\n{\n\treturn container_of(target->arch_info,\n\t\t\tstruct mips_m4k_common, mips32);\n}\n\nstatic inline void mips_m4k_isa_filter(enum mips32_isa_imp isa_imp, target_addr_t  *addr)\n{\n\tif (isa_imp <= 1) {\t/* if only one isa implemented */\n\t\ttarget_addr_t address = (*addr & ~1) | isa_imp;\n\n\t\tif (address != *addr) {\n\t\t\tLOG_USER(\"Warning: isa bit changed due to isa not implemented\");\n\t\t\t*addr = address;\n\t\t}\n\t}\n}\n\n#endif /* OPENOCD_TARGET_MIPS_M4K_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_mips64.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * MIPS64 generic target support\n *\n * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>\n *\n * Based on the work of:\n *     Copyright (C) 2008 by Spencer Oliver\n *     Copyright (C) 2008 by David T.L. Wong\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"mips32.h\"\n#include \"mips64.h\"\n#include \"mips_mips64.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n\nstatic int mips_mips64_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\n\nstatic uint64_t mips64_extend_sign(uint64_t addr)\n{\n\tif (addr >> 32)\n\t\treturn addr;\n\tif (addr >> 31)\n\t\treturn addr | (ULLONG_MAX << 32);\n\treturn addr;\n}\n\nstatic int mips_mips64_examine_debug_reason(struct target *target)\n{\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP))\n\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_debug_entry(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tstruct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];\n\n\tmips64_save_context(target);\n\n\t/* make sure stepping disabled, SSt bit in CP0 debug register cleared */\n\tmips64_ejtag_config_step(ejtag_info, 0);\n\n\t/* make sure break unit configured */\n\tmips64_configure_break_unit(target);\n\n\t/* attempt to find halt reason */\n\tmips_mips64_examine_debug_reason(target);\n\n\tLOG_DEBUG(\"entered debug state at PC 0x%\" PRIx64 \", target->state: %s\",\n\t\t  buf_get_u64(pc->value, 0, 64), target_state_name(target));\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_poll(struct target *target)\n{\n\tint retval;\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tuint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl;\n\n\t/* read ejtag control reg */\n\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\n\t/* clear this bit before handling polling\n\t * as after reset registers will read zero */\n\tif (ejtag_ctrl & EJTAG_CTRL_ROCC) {\n\t\t/* we have detected a reset, clear flag\n\t\t * otherwise ejtag will not work */\n\t\tejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;\n\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);\n\t\tmips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);\n\t\tLOG_DEBUG(\"Reset Detected\");\n\t}\n\n\t/* check for processor halted */\n\tif (ejtag_ctrl & EJTAG_CTRL_BRKST) {\n\t\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tretval = mips_mips64_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t} else if (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\tretval = mips_mips64_debug_entry(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\t} else {\n\t\ttarget->state = TARGET_RUNNING;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_halt(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\t  target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {\n\t\t\tLOG_ERROR(\"can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\t/* we came here in a reset_halt or reset_init sequence\n\t\t\t * debug entry was already prepared in mips64_prepare_reset_halt()\n\t\t\t */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* break processor */\n\tmips_ejtag_enter_debug(ejtag_info);\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_assert_reset(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tint retval;\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\tif (!(jtag_reset_config & RESET_HAS_SRST)) {\n\t\tLOG_ERROR(\"Can't assert SRST\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->reset_halt)\n\t\t/* use hardware to catch reset */\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);\n\telse\n\t\tmips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);\n\n\t/* here we should issue a srst only, but we may have to assert trst as well */\n\tif (jtag_reset_config & RESET_SRST_PULLS_TRST)\n\t\tjtag_add_reset(1, 1);\n\telse\n\t\tjtag_add_reset(0, 1);\n\n\ttarget->state = TARGET_RESET;\n\tjtag_add_sleep(5000);\n\n\tretval = mips64_invalidate_core_regs(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->reset_halt) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_deassert_reset(struct target *target)\n{\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\t/* deassert reset lines */\n\tjtag_add_reset(0, 0);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_single_step_core(struct target *target)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tint retval;\n\n\t/* configure single step mode */\n\tmips64_ejtag_config_step(ejtag_info, 1);\n\n\t/* disable interrupts while stepping */\n\tretval = mips64_enable_interrupts(target, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* exit debug mode */\n\tretval = mips64_ejtag_exit_debug(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tmips_mips64_debug_entry(target);\n\n\treturn ERROR_OK;\n}\n\n/* TODO: HW breakpoints are in EJTAG spec. Should we share it for MIPS32? */\nstatic int mips_mips64_set_hwbp(struct target *target, struct breakpoint *bp)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *c, *cl = mips64->inst_break_list;\n\tuint64_t bp_value;\n\tint retval, bp_num = 0;\n\n\twhile (cl[bp_num].used && (bp_num < mips64->num_inst_bpoints))\n\t\tbp_num++;\n\n\tif (bp_num >= mips64->num_inst_bpoints) {\n\t\tLOG_DEBUG(\"ERROR Can not find free FP Comparator(bpid: %\" PRIu32 \")\",\n\t\t\t  bp->unique_id);\n\t\tLOG_WARNING(\"ERROR Can not find free FP Comparator\");\n\t\texit(-1);\n\t}\n\n\tc = &cl[bp_num];\n\tc->used = true;\n\tc->bp_value = bp->address;\n\tbp_value = bp->address;\n\n\t/* Instruction Breakpoint Address n (IBAn) Register */\n\tretval = target_write_u64(target, c->reg_address, bp_value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* TODO: use defines */\n\t/* Instruction Breakpoint Address Mask n (IBMn) Register */\n\tretval = target_write_u64(target, c->reg_address + 0x08, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Instruction Breakpoint Control n (IBCn) Register */\n\tretval = target_write_u64(target, c->reg_address + 0x18, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"bpid: %\" PRIu32 \", bp_num %i bp_value 0x%\" PRIx64, bp->unique_id,\n\t\t  bp_num, c->bp_value);\n\n\treturn ERROR_OK;\n}\n\n/* TODO: is it MIPS64 or MIPS32 instruction. If MIPS32, can it be shared with\n * MIPS32 code? */\nstatic int mips_mips64_set_sdbbp(struct target *target, struct breakpoint *bp)\n{\n\tuint32_t verify;\n\tint retval;\n\n\tretval = target_read_memory(target,\n\t\t\t\t    bp->address, bp->length, 1,\n\t\t\t\t    bp->orig_instr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u32(target, bp->address, MIPS64_SDBBP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u32(target, bp->address, &verify);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (verify != MIPS64_SDBBP) {\n\t\tLOG_ERROR(\"Unable to set 32bit breakpoint at address %16\" PRIx64,\n\t\t\t  bp->address);\n\t\tretval = ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\n/* TODO do MIPS64 support MIPS16 instructions? Can it be shared with MIPS32\n * code? */\nstatic int mips_mips16_set_sdbbp(struct target *target, struct breakpoint *bp)\n{\n\tuint32_t isa_req = bp->length & 1;\n\tuint16_t verify;\n\tint retval;\n\n\tretval = target_read_memory(target,\n\t\t\t\t    bp->address, bp->length, 1,\n\t\t\t\t    bp->orig_instr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u16(target, bp->address, MIPS16_SDBBP(isa_req));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_read_u16(target, bp->address, &verify);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (verify != MIPS16_SDBBP(isa_req)) {\n\t\tLOG_ERROR(\"Unable to set 16bit breakpoint at address %16\" PRIx64,\n\t\t\t  bp->address);\n\t\tretval = ERROR_FAIL;\n\t}\n\n\treturn retval;\n}\n\nstatic int mips_mips64_set_breakpoint(struct target *target,\n\t\t\t\t      struct breakpoint *bp)\n{\n\tint retval;\n\n\tif (bp->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (bp->type == BKPT_HARD) {\n\t\tretval = mips_mips64_set_hwbp(target, bp);\n\t} else {\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, bp->unique_id);\n\n\t\tswitch (bp->length) {\n\t\tcase MIPS64_SDBBP_SIZE:\n\t\t\tretval = mips_mips64_set_sdbbp(target, bp);\n\t\t\tbreak;\n\t\tcase MIPS16_SDBBP_SIZE:\n\t\t\tretval = mips_mips16_set_sdbbp(target, bp);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"can't unset breakpoint. Some thing wrong happened\");\n\t\treturn retval;\n\t}\n\n\tbp->is_set = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *bp = target->breakpoints;\n\tint retval = ERROR_OK;\n\n\t/* set any pending breakpoints */\n\twhile (bp) {\n\t\tif (!bp->is_set) {\n\t\t\tretval = mips_mips64_set_breakpoint(target, bp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tbp = bp->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* TODO: HW data breakpoints are in EJTAG spec. Should we share it for MIPS32? */\nstatic int mips_mips64_set_watchpoint(struct target *target,\n\t\t\t\t      struct watchpoint *watchpoint)\n{\n\tuint64_t wp_value;\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *c, *cl = mips64->data_break_list;\n\tint retval, wp_num = 0;\n\n\t/*\n\t * watchpoint enabled, ignore all byte lanes in value register\n\t * and exclude both load and store accesses from  watchpoint\n\t * condition evaluation\n\t*/\n\tint enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE\n\t\t| (0xff << EJTAG_DBCN_BLM_SHIFT);\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (cl[wp_num].used && (wp_num < mips64->num_data_bpoints))\n\t\twp_num++;\n\n\tif (wp_num >= mips64->num_data_bpoints) {\n\t\tLOG_ERROR(\"ERROR Can not find free comparator\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (watchpoint->length != 4) {\n\t\tLOG_ERROR(\"Only watchpoints of length 4 are supported\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tif (watchpoint->address % 4) {\n\t\tLOG_ERROR(\"Watchpoints address should be word aligned\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tswitch (watchpoint->rw)\t{\n\tcase WPT_READ:\n\t\tenable &= ~EJTAG_DBCN_NOLB;\n\t\tbreak;\n\tcase WPT_WRITE:\n\t\tenable &= ~EJTAG_DBCN_NOSB;\n\t\tbreak;\n\tcase WPT_ACCESS:\n\t\tenable &= ~(EJTAG_DBCN_NOLB | EJTAG_DBCN_NOSB);\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"BUG: watchpoint->rw neither read, write nor access\");\n\t}\n\n\tc = &cl[wp_num];\n\twatchpoint_set(watchpoint, wp_num);\n\tc->used = true;\n\tc->bp_value = watchpoint->address;\n\n\twp_value = watchpoint->address;\n\tif (wp_value & 0x80000000)\n\t\twp_value |= ULLONG_MAX << 32;\n\n\tretval = target_write_u64(target, c->reg_address, wp_value);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u64(target, c->reg_address + 0x08, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u64(target, c->reg_address + 0x10, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u64(target, c->reg_address + 0x18, enable);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_write_u64(target, c->reg_address + 0x20, 0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"wp_num %i bp_value 0x%\" PRIx64 \"\", wp_num, c->bp_value);\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\tint retval;\n\n\t/* set any pending watchpoints */\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set) {\n\t\t\tretval = mips_mips64_set_watchpoint(target, watchpoint);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_unset_hwbp(struct target *target, struct breakpoint *bp)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *comparator_list = mips64->inst_break_list;\n\n\tint bp_num = bp->number;\n\n\tif (bp_num >= mips64->num_inst_bpoints) {\n\t\tLOG_DEBUG(\"Invalid FP Comparator number in breakpoint (bpid: %\" PRIu32 \")\",\n\t\t\t  bp->unique_id);\n\t\treturn ERROR_OK;\n\t}\n\n\tLOG_DEBUG(\"bpid: %\" PRIu32 \" - releasing hw: %d\", bp->unique_id, bp_num);\n\tcomparator_list[bp_num].used = false;\n\tcomparator_list[bp_num].bp_value = 0;\n\n\treturn target_write_u64(target,\n\t\t\t\tcomparator_list[bp_num].reg_address + 0x18, 0);\n}\n\nstatic int mips_mips64_unset_sdbbp(struct target *target, struct breakpoint *bp)\n{\n\tuint8_t buf[MIPS64_SDBBP_SIZE];\n\tuint32_t instr;\n\tint retval;\n\n\tretval = target_read_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,\n\t\t\t\t    &buf[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tinstr = target_buffer_get_u32(target, &buf[0]);\n\tif (instr != MIPS64_SDBBP)\n\t\treturn ERROR_OK;\n\n\treturn target_write_memory(target, bp->address, MIPS64_SDBBP_SIZE, 1,\n\t\t\t\t   bp->orig_instr);\n}\n\nstatic int mips_mips16_unset_sdbbp(struct target *target, struct breakpoint *bp)\n{\n\tuint8_t buf[MIPS16_SDBBP_SIZE];\n\tuint16_t instr;\n\tint retval;\n\n\tretval = target_read_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,\n\t\t\t\t    &buf[0]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tinstr = target_buffer_get_u16(target, &buf[0]);\n\tif (instr != MIPS16_SDBBP(bp->length & 1))\n\t\treturn ERROR_OK;\n\n\treturn target_write_memory(target, bp->address, MIPS16_SDBBP_SIZE, 1,\n\t\t\t\t   bp->orig_instr);\n}\n\nstatic int mips_mips64_unset_breakpoint(struct target *target,\n\t\t\t\t\tstruct breakpoint *bp)\n{\n\t/* get pointers to arch-specific information */\n\tint retval;\n\n\tif (!bp->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (bp->type == BKPT_HARD) {\n\t\tretval = mips_mips64_unset_hwbp(target, bp);\n\t} else {\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, bp->unique_id);\n\n\t\tswitch (bp->length) {\n\t\tcase MIPS64_SDBBP_SIZE:\n\t\t\tretval = mips_mips64_unset_sdbbp(target, bp);\n\t\t\tbreak;\n\t\tcase MIPS16_SDBBP_SIZE:\n\t\t\tretval = mips_mips16_unset_sdbbp(target, bp);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"can't unset breakpoint. Some thing wrong happened\");\n\t\treturn retval;\n\t}\n\n\tbp->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_resume(struct target *target, int current,\n\t\t\t      uint64_t address, int handle_breakpoints,\n\t\t\t      int debug_execution)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tint retval = ERROR_OK;\n\tuint64_t resume_pc;\n\tstruct reg *pc;\n\n\tif (mips64->mips64mode32)\n\t\taddress = mips64_extend_sign(address);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted %d\", target->state);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tretval = mips_mips64_enable_breakpoints(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tretval = mips_mips64_enable_watchpoints(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tpc = &mips64->core_cache->reg_list[MIPS64_PC];\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tbuf_set_u64(pc->value, 0, 64, address);\n\t\tpc->dirty = 1;\n\t\tpc->valid = 1;\n\t}\n\n\tresume_pc = buf_get_u64(pc->value, 0, 64);\n\n\tretval = mips64_restore_context(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tstruct breakpoint *bp;\n\n\t\t/* Single step past breakpoint at current address */\n\t\tbp = breakpoint_find(target, (uint64_t) resume_pc);\n\t\tif (bp) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at 0x%16.16\" PRIx64 \"\",\n\t\t\t\t  bp->address);\n\t\t\tretval = mips_mips64_unset_breakpoint(target, bp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = mips_mips64_single_step_core(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = mips_mips64_set_breakpoint(target, bp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* enable interrupts if we are running */\n\tretval = mips64_enable_interrupts(target, !debug_execution);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* exit debug mode */\n\tretval = mips64_ejtag_exit_debug(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* registers are now invalid */\n\tretval = mips64_invalidate_core_regs(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\tretval = target_call_event_callbacks(target,\n\t\t\t\t\t\t     TARGET_EVENT_RESUMED);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"target resumed at 0x%\" PRIx64 \"\", resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\tretval = target_call_event_callbacks(target,\n\t\t\t\t\t\t     TARGET_EVENT_DEBUG_RESUMED);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"target debug resumed at 0x%\" PRIx64 \"\", resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_step(struct target *target, int current,\n\t\t\t    uint64_t address, int handle_breakpoints)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tstruct reg *pc = &mips64->core_cache->reg_list[MIPS64_PC];\n\tstruct breakpoint *bp = NULL;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (mips64->mips64mode32)\n\t\taddress = mips64_extend_sign(address);\n\n\t/* current = 1: continue on current pc, otherwise continue at\n\t * <address> */\n\tif (!current) {\n\t\tbuf_set_u64(pc->value, 0, 64, address);\n\t\tpc->dirty = 1;\n\t\tpc->valid = 1;\n\t}\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbp = breakpoint_find(target, buf_get_u64(pc->value, 0, 64));\n\t\tif (bp) {\n\t\t\tretval = mips_mips64_unset_breakpoint(target, bp);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = mips64_restore_context(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* configure single step mode */\n\tretval = mips64_ejtag_config_step(ejtag_info, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\tretval = target_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* disable interrupts while stepping */\n\tretval = mips64_enable_interrupts(target, false);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* exit debug mode */\n\tretval = mips64_ejtag_exit_debug(ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* registers are now invalid */\n\tretval = mips64_invalidate_core_regs(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (bp) {\n\t\tretval = mips_mips64_set_breakpoint(target, bp);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"target stepped \");\n\n\tretval = mips_mips64_debug_entry(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n}\n\nstatic int mips_mips64_add_breakpoint(struct target *target,\n\t\t\t\t      struct breakpoint *bp)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif (mips64->mips64mode32)\n\t\tbp->address = mips64_extend_sign(bp->address);\n\n\tif (bp->type == BKPT_HARD) {\n\t\tif (mips64->num_inst_bpoints_avail < 1) {\n\t\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tmips64->num_inst_bpoints_avail--;\n\t}\n\n\treturn mips_mips64_set_breakpoint(target, bp);\n}\n\nstatic int mips_mips64_remove_breakpoint(struct target *target,\n\t\t\t\t\t struct breakpoint *bp)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (bp->is_set)\n\t\tretval = mips_mips64_unset_breakpoint(target, bp);\n\n\tif (bp->type == BKPT_HARD)\n\t\tmips64->num_inst_bpoints_avail++;\n\n\treturn retval;\n}\n\nstatic int mips_mips64_unset_watchpoint(struct target *target,\n\t\t\t\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips64_comparator *comparator_list = mips64->data_break_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wp_num = watchpoint->number;\n\tif (wp_num >= mips64->num_data_bpoints) {\n\t\tLOG_DEBUG(\"Invalid FP Comparator number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tcomparator_list[wp_num].used = false;\n\tcomparator_list[wp_num].bp_value = 0;\n\ttarget_write_u64(target, comparator_list[wp_num].reg_address + 0x18, 0);\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int mips_mips64_add_watchpoint(struct target *target,\n\t\t\t\t      struct watchpoint *watchpoint)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif (mips64->num_data_bpoints_avail < 1) {\n\t\tLOG_INFO(\"no hardware watchpoints available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tmips64->num_data_bpoints_avail--;\n\n\treturn mips_mips64_set_watchpoint(target, watchpoint);\n}\n\nstatic int mips_mips64_remove_watchpoint(struct target *target,\n\t\t\t\t\t struct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct mips64_common *mips64 = target->arch_info;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\tretval = mips_mips64_unset_watchpoint(target, watchpoint);\n\n\tmips64->num_data_bpoints_avail++;\n\n\treturn retval;\n}\n\nstatic int mips_mips64_read_memory(struct target *target, uint64_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tint retval;\n\tvoid *t;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted %d\", target->state);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (mips64->mips64mode32)\n\t\taddress = mips64_extend_sign(address);\n\n\t/* sanitize arguments */\n\tif (((size != 8) && (size != 4) && (size != 2) && (size != 1))\n\t    || !count || !buffer)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\tif (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))\n\t    || ((size == 2) && (address & 0x1)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (size > 1) {\n\t\tt = calloc(count, size);\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else\n\t\tt = buffer;\n\n\tLOG_DEBUG(\"address: 0x%16.16\" PRIx64 \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\t  address, size, count);\n\tretval = mips64_pracc_read_mem(ejtag_info, address, size, count,\n\t\t\t\t       (void *)t);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"mips64_pracc_read_mem filed\");\n\t\tgoto read_done;\n\t}\n\n\tswitch (size) {\n\tcase 8:\n\t\ttarget_buffer_set_u64_array(target, buffer, count, t);\n\t\tbreak;\n\tcase 4:\n\t\ttarget_buffer_set_u32_array(target, buffer, count, t);\n\t\tbreak;\n\tcase 2:\n\t\ttarget_buffer_set_u16_array(target, buffer, count, t);\n\t\tbreak;\n\t}\n\nread_done:\n\tif (size > 1)\n\t\tfree(t);\n\n\treturn retval;\n}\n\nstatic int mips_mips64_bulk_write_memory(struct target *target,\n\t\t\t\t\t target_addr_t address, uint32_t count,\n\t\t\t\t\t const uint8_t *buffer)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tstruct working_area *fast_data_area;\n\tint retval;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", count: 0x%8.8\" PRIx32 \"\",\n\t\t  address, count);\n\n\tif (address & 0x7)\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\tif (!mips64->fast_data_area) {\n\t\t/* Get memory for block write handler\n\t\t * we preserve this area between calls and gain a speed increase\n\t\t * of about 3kb/sec when writing flash\n\t\t * this will be released/nulled by the system when the target is resumed or reset */\n\t\tretval = target_alloc_working_area(target,\n\t\t\t\t\t\t   MIPS64_FASTDATA_HANDLER_SIZE,\n\t\t\t\t\t\t   &mips64->fast_data_area);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"No working area available\");\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* reset fastadata state so the algo get reloaded */\n\t\tejtag_info->fast_access_save = -1;\n\t}\n\n\tfast_data_area = mips64->fast_data_area;\n\n\tif (address <= fast_data_area->address + fast_data_area->size &&\n\t    fast_data_area->address <= address + count) {\n\t\tLOG_ERROR(\"fast_data (\" TARGET_ADDR_FMT \") is within write area \"\n\t\t\t  \"(\" TARGET_ADDR_FMT \"-\" TARGET_ADDR_FMT \").\",\n\t\t\t  fast_data_area->address, address, address + count);\n\t\tLOG_ERROR(\"Change work-area-phys or load_image address!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */\n\t/* but byte array represents target endianness                      */\n\tuint64_t *t;\n\n\tt = calloc(count, sizeof(uint64_t));\n\tif (!t) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_buffer_get_u64_array(target, buffer, count, t);\n\n\tretval = mips64_pracc_fastdata_xfer(ejtag_info, mips64->fast_data_area,\n\t\t\t\t\t    true, address, count, t);\n\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Fastdata access Failed\");\n\n\tfree(t);\n\n\treturn retval;\n}\n\nstatic int mips_mips64_write_memory(struct target *target, uint64_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct mips64_common *mips64 = target->arch_info;\n\tstruct mips_ejtag *ejtag_info = &mips64->ejtag_info;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (mips64->mips64mode32)\n\t\taddress = mips64_extend_sign(address);\n\n\t/* sanitize arguments */\n\tif (((size != 8) && (size != 4) && (size != 2) && (size != 1))\n\t    || !count || !buffer)\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\n\tif (((size == 8) && (address & 0x7)) || ((size == 4) && (address & 0x3))\n\t    || ((size == 2) && (address & 0x1)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\n\n\tif (size == 8 && count > 8) {\n\t\tretval = mips_mips64_bulk_write_memory(target, address, count,\n\t\t\t\t\t\t       buffer);\n\t\tif (retval == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\n\t\tLOG_WARNING(\"Falling back to non-bulk write\");\n\t}\n\n\tvoid *t = NULL;\n\tif (size > 1) {\n\t\tt = calloc(count, size);\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"unable to allocate t for write buffer\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tswitch (size) {\n\t\tcase 8:\n\t\t\ttarget_buffer_get_u64_array(target, buffer, count,\n\t\t\t\t\t\t    (uint64_t *)t);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\ttarget_buffer_get_u32_array(target, buffer, count,\n\t\t\t\t\t\t    (uint32_t *)t);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_get_u16_array(target, buffer, count,\n\t\t\t\t\t\t    (uint16_t *)t);\n\t\t\tbreak;\n\t\t}\n\t\tbuffer = t;\n\t}\n\n\tLOG_DEBUG(\"address: 0x%16.16\" PRIx64 \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32 \"\",\n\t\t  address, size, count);\n\n\tretval = mips64_pracc_write_mem(ejtag_info, address, size, count,\n\t\t\t\t\t(void *)buffer);\n\tfree(t);\n\n\treturn retval;\n}\n\nstatic int mips_mips64_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\treturn mips64_build_reg_cache(target);\n}\n\nstatic int mips_mips64_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct mips_mips64_common *mips_mips64;\n\tstruct mips64_common *mips64;\n\n\tmips_mips64 = calloc(1, sizeof(*mips_mips64));\n\tif (!mips_mips64) {\n\t\tLOG_ERROR(\"unable to allocate mips_mips64\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmips_mips64->common_magic = MIPS64_COMMON_MAGIC;\n\n\tmips64 = &mips_mips64->mips64_common;\n\tmips64->arch_info = mips_mips64;\n\ttarget->arch_info = mips64;\n\n\treturn mips64_init_arch_info(target, mips64, target->tap);\n}\n\nstatic int mips_mips64_examine(struct target *target)\n{\n\tint retval;\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tretval = mips_ejtag_init(&mips64->ejtag_info);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn mips64_examine(target);\n}\n\nstatic int mips_mips64_checksum_memory(struct target *target, uint64_t address,\n\t\t\t\t       uint32_t size, uint32_t *checksum)\n{\n\treturn ERROR_FAIL; /* use bulk read method */\n}\n\nCOMMAND_HANDLER(handle_mips64mode32)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct mips64_common *mips64 = target->arch_info;\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_BOOL(CMD_ARGV[0], mips64->mips64mode32, \"on\", \"off\");\n\n\tif (mips64->mips64mode32)\n\t\tcommand_print(CMD, \"enabled\");\n\telse\n\t\tcommand_print(CMD, \"disabled\");\n\n\treturn ERROR_OK;\n}\n\n\nstatic const struct command_registration mips64_commands_handlers[] = {\n\t{\n\t\t.name = \"mips64mode32\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Enable/disable 32 bit mode\",\n\t\t.usage = \"[1|0]\",\n\t\t.handler = handle_mips64mode32\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type mips_mips64_target = {\n\t.name = \"mips_mips64\",\n\n\t.poll = mips_mips64_poll,\n\t.arch_state = mips64_arch_state,\n\n\t.target_request_data = NULL,\n\n\t.halt = mips_mips64_halt,\n\t.resume = mips_mips64_resume,\n\t.step = mips_mips64_step,\n\n\t.assert_reset = mips_mips64_assert_reset,\n\t.deassert_reset = mips_mips64_deassert_reset,\n\t/* TODO: add .soft_reset_halt */\n\n\t.get_gdb_reg_list = mips64_get_gdb_reg_list,\n\n\t.read_memory = mips_mips64_read_memory,\n\t.write_memory = mips_mips64_write_memory,\n\t.checksum_memory = mips_mips64_checksum_memory,\n\t.blank_check_memory = NULL,\n\n\t.run_algorithm = mips64_run_algorithm,\n\n\t.add_breakpoint = mips_mips64_add_breakpoint,\n\t.remove_breakpoint = mips_mips64_remove_breakpoint,\n\t.add_watchpoint = mips_mips64_add_watchpoint,\n\t.remove_watchpoint = mips_mips64_remove_watchpoint,\n\n\t.target_create = mips_mips64_target_create,\n\t.init_target = mips_mips64_init_target,\n\t.examine = mips_mips64_examine,\n\n\t.commands = mips64_commands_handlers,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/mips_mips64.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n/*\n * MIPS64 generic target support                                         *\n *\n * Copyright (C) 2014 by Andrey Sidorov <anysidorov@gmail.com>\n * Copyright (C) 2014 by Aleksey Kuleshov <rndfax@yandex.ru>\n * Copyright (C) 2014-2019 by Peter Mamonov <pmamonov@gmail.com>\n *\n * Based on the work of:\n *     Copyright (C) 2008 by Spencer Oliver\n *     Copyright (C) 2008 by David T.L. Wong\n */\n\n#ifndef OPENOCD_TARGET_MIPS_MIPS64_H\n#define OPENOCD_TARGET_MIPS_MIPS64_H\n\n#include \"helper/types.h\"\n\nstruct mips_mips64_common {\n\tunsigned int common_magic;\n\n\tstruct mips64_common mips64_common;\n};\n\n#endif /* OPENOCD_TARGET_MIPS_MIPS64_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libopenrisc.la\n%C%_libopenrisc_la_SOURCES = \\\n\t%D%/or1k.c \\\n\t%D%/or1k_du_adv.c \\\n\t%D%/or1k_tap_mohor.c \\\n\t%D%/or1k_tap_vjtag.c \\\n\t%D%/or1k_tap_xilinx_bscan.c \\\n\t%D%/jsp_server.c \\\n\t%D%/or1k.h \\\n\t%D%/or1k_du.h \\\n\t%D%/or1k_tap.h \\\n\t%D%/jsp_server.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/jsp_server.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2014 by Franck Jullien                                  *\n *   franck.jullien@gmail.com                                              *\n *                                                                         *\n *   Based on ./src/server/telnet_server.c                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <server/telnet_server.h>\n\n#include \"or1k_tap.h\"\n#include \"or1k_du.h\"\n#include \"jsp_server.h\"\n\nstatic char *jsp_port;\n\n/**A skim of the relevant RFCs suggests that if my application simply sent the\n * characters IAC DONT LINEMODE (\\377\\376\\042) as soon as the client connects,\n * the client should be forced into character mode. However it doesn't make any difference.\n */\n\nstatic const char * const negotiate =\n\t\"\\xFF\\xFB\\x03\"\t\t\t/* IAC WILL Suppress Go Ahead */\n\t\"\\xFF\\xFB\\x01\"\t\t\t/* IAC WILL Echo */\n\t\"\\xFF\\xFD\\x03\"\t\t\t/* IAC DO Suppress Go Ahead */\n\t\"\\xFF\\xFE\\x01\";\t\t\t/* IAC DON'T Echo */\n\n/* The only way we can detect that the socket is closed is the first time\n * we write to it, we will fail. Subsequent write operations will\n * succeed. Shudder!\n */\nstatic int telnet_write(struct connection *connection, const void *data, int len)\n{\n\tstruct telnet_connection *t_con = connection->priv;\n\tif (t_con->closed)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\n\tif (connection_write(connection, data, len) == len)\n\t\treturn ERROR_OK;\n\tt_con->closed = 1;\n\treturn ERROR_SERVER_REMOTE_CLOSED;\n}\n\nstatic int jsp_poll_read(void *priv)\n{\n\tstruct jsp_service *jsp_service = (struct jsp_service *)priv;\n\tunsigned char out_buffer[10];\n\tunsigned char in_buffer[10];\n\tint out_len = 0;\n\tint in_len;\n\n\tif (!jsp_service->connection)\n\t\treturn ERROR_FAIL;\n\n\tmemset(out_buffer, 0, 10);\n\n\tor1k_adv_jtag_jsp_xfer(jsp_service->jtag_info, &out_len, out_buffer, &in_len, in_buffer);\n\tif (in_len)\n\t\ttelnet_write(jsp_service->connection, in_buffer, in_len);\n\n\treturn ERROR_OK;\n}\n\nstatic int jsp_new_connection(struct connection *connection)\n{\n\tstruct telnet_connection *telnet_connection = malloc(sizeof(struct telnet_connection));\n\tstruct jsp_service *jsp_service = connection->service->priv;\n\n\tconnection->priv = telnet_connection;\n\n\t/* initialize telnet connection information */\n\ttelnet_connection->closed = 0;\n\ttelnet_connection->line_size = 0;\n\ttelnet_connection->line_cursor = 0;\n\ttelnet_connection->state = TELNET_STATE_DATA;\n\n\t/* negotiate telnet options */\n\ttelnet_write(connection, negotiate, strlen(negotiate));\n\n\t/* print connection banner */\n\tif (jsp_service->banner) {\n\t\ttelnet_write(connection, jsp_service->banner, strlen(jsp_service->banner));\n\t\ttelnet_write(connection, \"\\r\\n\", 2);\n\t}\n\n\tjsp_service->connection = connection;\n\n\tint retval = target_register_timer_callback(&jsp_poll_read, 1,\n\t\tTARGET_TIMER_TYPE_PERIODIC, jsp_service);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int jsp_input(struct connection *connection)\n{\n\tint bytes_read;\n\tunsigned char buffer[TELNET_BUFFER_SIZE];\n\tunsigned char *buf_p;\n\tstruct telnet_connection *t_con = connection->priv;\n\tstruct jsp_service *jsp_service = connection->service->priv;\n\n\tbytes_read = connection_read(connection, buffer, TELNET_BUFFER_SIZE);\n\n\tif (bytes_read == 0)\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\telse if (bytes_read == -1) {\n\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\tbuf_p = buffer;\n\twhile (bytes_read) {\n\t\tswitch (t_con->state) {\n\t\t\tcase TELNET_STATE_DATA:\n\t\t\t\tif (*buf_p == 0xff)\n\t\t\t\t\tt_con->state = TELNET_STATE_IAC;\n\t\t\t\telse {\n\t\t\t\t\tint out_len = 1;\n\t\t\t\t\tint in_len;\n\t\t\t\t\tunsigned char in_buffer[10];\n\t\t\t\t\tor1k_adv_jtag_jsp_xfer(jsp_service->jtag_info,\n\t\t\t\t\t\t\t       &out_len, buf_p, &in_len,\n\t\t\t\t\t\t\t       in_buffer);\n\t\t\t\t\tif (in_len)\n\t\t\t\t\t\ttelnet_write(connection,\n\t\t\t\t\t\t\t     in_buffer, in_len);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_IAC:\n\t\t\t\tswitch (*buf_p) {\n\t\t\t\tcase 0xfe:\n\t\t\t\t\tt_con->state = TELNET_STATE_DONT;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfd:\n\t\t\t\t\tt_con->state = TELNET_STATE_DO;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfc:\n\t\t\t\t\tt_con->state = TELNET_STATE_WONT;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 0xfb:\n\t\t\t\t\tt_con->state = TELNET_STATE_WILL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_SB:\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_SE:\n\t\t\t\tbreak;\n\t\t\tcase TELNET_STATE_WILL:\n\t\t\tcase TELNET_STATE_WONT:\n\t\t\tcase TELNET_STATE_DO:\n\t\t\tcase TELNET_STATE_DONT:\n\t\t\t\tt_con->state = TELNET_STATE_DATA;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"unknown telnet state\");\n\t\t\t\texit(-1);\n\t\t}\n\n\t\tbytes_read--;\n\t\tbuf_p++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int jsp_connection_closed(struct connection *connection)\n{\n\tstruct jsp_service *jsp_service = connection->service->priv;\n\n\tint retval = target_unregister_timer_callback(&jsp_poll_read, jsp_service);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfree(connection->priv);\n\tconnection->priv = NULL;\n\treturn ERROR_OK;\n}\n\nstatic const struct service_driver jsp_service_driver = {\n\t.name = \"jsp\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = jsp_new_connection,\n\t.input_handler = jsp_input,\n\t.connection_closed_handler = jsp_connection_closed,\n\t.keep_client_alive_handler = NULL,\n};\n\nint jsp_init(struct or1k_jtag *jtag_info, char *banner)\n{\n\tstruct jsp_service *jsp_service = malloc(sizeof(struct jsp_service));\n\tjsp_service->banner = banner;\n\tjsp_service->jtag_info = jtag_info;\n\n\treturn add_service(&jsp_service_driver, jsp_port, 1, jsp_service);\n}\n\nCOMMAND_HANDLER(handle_jsp_port_command)\n{\n\treturn CALL_COMMAND_HANDLER(server_pipe_command, &jsp_port);\n}\n\nstatic const struct command_registration jsp_command_handlers[] = {\n\t{\n\t\t.name = \"jsp_port\",\n\t\t.handler = handle_jsp_port_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Specify port on which to listen \"\n\t\t\t\"for incoming JSP telnet connections.\",\n\t\t.usage = \"[port_num]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint jsp_register_commands(struct command_context *cmd_ctx)\n{\n\tjsp_port = strdup(\"7777\");\n\treturn register_commands(cmd_ctx, NULL, jsp_command_handlers);\n}\n\nvoid jsp_service_free(void)\n{\n\tfree(jsp_port);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/jsp_server.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef OPENOCD_TARGET_OPENRISC_JSP_SERVER_H\n#define OPENOCD_TARGET_OPENRISC_JSP_SERVER_H\n\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n#include \"or1k_du.h\"\n\nstruct jsp_service {\n\tchar *banner;\n\tstruct or1k_jtag *jtag_info;\n\tstruct connection *connection;\n};\n\nint jsp_init(struct or1k_jtag *jtag_info, char *banner);\nint jsp_register_commands(struct command_context *cmd_ctx);\nvoid jsp_service_free(void);\n\n#endif /* OPENOCD_TARGET_OPENRISC_JSP_SERVER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2011 by Julius Baxter                                   *\n *   julius@opencores.org                                                  *\n *                                                                         *\n *   Copyright (C) 2013 by Marek Czerski                                   *\n *   ma.czerski@gmail.com                                                  *\n *                                                                         *\n *   Copyright (C) 2013 by Franck Jullien                                  *\n *   elec4fun@gmail.com                                                    *\n *                                                                         *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <jtag/jtag.h>\n#include <target/register.h>\n#include <target/target.h>\n#include <target/breakpoints.h>\n#include <target/target_type.h>\n#include <helper/time_support.h>\n#include <helper/fileio.h>\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n#include \"or1k_du.h\"\n\nLIST_HEAD(tap_list);\nLIST_HEAD(du_list);\n\nstatic int or1k_remove_breakpoint(struct target *target,\n\t\t\t\t  struct breakpoint *breakpoint);\n\nstatic int or1k_read_core_reg(struct target *target, int num);\nstatic int or1k_write_core_reg(struct target *target, int num);\n\nstatic struct or1k_core_reg *or1k_core_reg_list_arch_info;\n\nstatic const struct or1k_core_reg_init or1k_init_reg_list[] = {\n\t{\"r0\",        GROUP0 + 1024, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r1\",        GROUP0 + 1025, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r2\",        GROUP0 + 1026, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r3\",        GROUP0 + 1027, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r4\",        GROUP0 + 1028, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r5\",        GROUP0 + 1029, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r6\",        GROUP0 + 1030, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r7\",        GROUP0 + 1031, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r8\",        GROUP0 + 1032, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r9\",        GROUP0 + 1033, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r10\",       GROUP0 + 1034, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r11\",       GROUP0 + 1035, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r12\",       GROUP0 + 1036, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r13\",       GROUP0 + 1037, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r14\",       GROUP0 + 1038, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r15\",       GROUP0 + 1039, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r16\",       GROUP0 + 1040, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r17\",       GROUP0 + 1041, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r18\",       GROUP0 + 1042, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r19\",       GROUP0 + 1043, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r20\",       GROUP0 + 1044, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r21\",       GROUP0 + 1045, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r22\",       GROUP0 + 1046, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r23\",       GROUP0 + 1047, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r24\",       GROUP0 + 1048, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r25\",       GROUP0 + 1049, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r26\",       GROUP0 + 1050, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r27\",       GROUP0 + 1051, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r28\",       GROUP0 + 1052, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r29\",       GROUP0 + 1053, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r30\",       GROUP0 + 1054, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"r31\",       GROUP0 + 1055, \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"ppc\",       GROUP0 + 18,   \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"npc\",       GROUP0 + 16,   \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"sr\",        GROUP0 + 17,   \"org.gnu.gdb.or1k.group0\", NULL},\n\t{\"vr\",        GROUP0 + 0,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"upr\",       GROUP0 + 1,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"cpucfgr\",   GROUP0 + 2,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"dmmucfgr\",  GROUP0 + 3,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"immucfgr\",  GROUP0 + 4,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"dccfgr\",    GROUP0 + 5,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"iccfgr\",    GROUP0 + 6,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"dcfgr\",     GROUP0 + 7,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"pccfgr\",    GROUP0 + 8,    \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"fpcsr\",     GROUP0 + 20,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr0\",     GROUP0 + 32,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr1\",     GROUP0 + 33,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr2\",     GROUP0 + 34,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr3\",     GROUP0 + 35,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr4\",     GROUP0 + 36,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr5\",     GROUP0 + 37,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr6\",     GROUP0 + 38,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr7\",     GROUP0 + 39,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr8\",     GROUP0 + 40,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr9\",     GROUP0 + 41,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr10\",    GROUP0 + 42,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr11\",    GROUP0 + 43,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr12\",    GROUP0 + 44,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr13\",    GROUP0 + 45,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr14\",    GROUP0 + 46,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"epcr15\",    GROUP0 + 47,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear0\",     GROUP0 + 48,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear1\",     GROUP0 + 49,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear2\",     GROUP0 + 50,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear3\",     GROUP0 + 51,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear4\",     GROUP0 + 52,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear5\",     GROUP0 + 53,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear6\",     GROUP0 + 54,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear7\",     GROUP0 + 55,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear8\",     GROUP0 + 56,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear9\",     GROUP0 + 57,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear10\",    GROUP0 + 58,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear11\",    GROUP0 + 59,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear12\",    GROUP0 + 60,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear13\",    GROUP0 + 61,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear14\",    GROUP0 + 62,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"eear15\",    GROUP0 + 63,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr0\",      GROUP0 + 64,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr1\",      GROUP0 + 65,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr2\",      GROUP0 + 66,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr3\",      GROUP0 + 67,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr4\",      GROUP0 + 68,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr5\",      GROUP0 + 69,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr6\",      GROUP0 + 70,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr7\",      GROUP0 + 71,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr8\",      GROUP0 + 72,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr9\",      GROUP0 + 73,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr10\",     GROUP0 + 74,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr11\",     GROUP0 + 75,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr12\",     GROUP0 + 76,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr13\",     GROUP0 + 77,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr14\",     GROUP0 + 78,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\t{\"esr15\",     GROUP0 + 79,   \"org.gnu.gdb.or1k.group0\", \"system\"},\n\n\t{\"dmmuucr\",   GROUP1 + 0,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"dmmuupr\",   GROUP1 + 1,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"dtlbeir\",   GROUP1 + 2,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbmr0\",   GROUP1 + 4,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbmr1\",   GROUP1 + 5,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbmr2\",   GROUP1 + 6,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbmr3\",   GROUP1 + 7,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbtr0\",   GROUP1 + 8,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbtr1\",   GROUP1 + 9,    \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbtr2\",   GROUP1 + 10,   \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\t{\"datbtr3\",   GROUP1 + 11,   \"org.gnu.gdb.or1k.group1\", \"dmmu\"},\n\n\t{\"immucr\",    GROUP2 + 0,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"immupr\",    GROUP2 + 1,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"itlbeir\",   GROUP2 + 2,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbmr0\",   GROUP2 + 4,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbmr1\",   GROUP2 + 5,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbmr2\",   GROUP2 + 6,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbmr3\",   GROUP2 + 7,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbtr0\",   GROUP2 + 8,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbtr1\",   GROUP2 + 9,    \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbtr2\",   GROUP2 + 10,   \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\t{\"iatbtr3\",   GROUP2 + 11,   \"org.gnu.gdb.or1k.group2\", \"immu\"},\n\n\t{\"dccr\",      GROUP3 + 0,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\t{\"dcbpr\",     GROUP3 + 1,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\t{\"dcbfr\",     GROUP3 + 2,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\t{\"dcbir\",     GROUP3 + 3,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\t{\"dcbwr\",     GROUP3 + 4,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\t{\"dcblr\",     GROUP3 + 5,    \"org.gnu.gdb.or1k.group3\", \"dcache\"},\n\n\t{\"iccr\",      GROUP4 + 0,    \"org.gnu.gdb.or1k.group4\", \"icache\"},\n\t{\"icbpr\",     GROUP4 + 1,    \"org.gnu.gdb.or1k.group4\", \"icache\"},\n\t{\"icbir\",     GROUP4 + 2,    \"org.gnu.gdb.or1k.group4\", \"icache\"},\n\t{\"icblr\",     GROUP4 + 3,    \"org.gnu.gdb.or1k.group4\", \"icache\"},\n\n\t{\"maclo\",     GROUP5 + 0,    \"org.gnu.gdb.or1k.group5\", \"mac\"},\n\t{\"machi\",     GROUP5 + 1,    \"org.gnu.gdb.or1k.group5\", \"mac\"},\n\n\t{\"dvr0\",      GROUP6 + 0,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr1\",      GROUP6 + 1,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr2\",      GROUP6 + 2,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr3\",      GROUP6 + 3,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr4\",      GROUP6 + 4,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr5\",      GROUP6 + 5,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr6\",      GROUP6 + 6,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dvr7\",      GROUP6 + 7,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr0\",      GROUP6 + 8,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr1\",      GROUP6 + 9,    \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr2\",      GROUP6 + 10,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr3\",      GROUP6 + 11,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr4\",      GROUP6 + 12,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr5\",      GROUP6 + 13,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr6\",      GROUP6 + 14,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcr7\",      GROUP6 + 15,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dmr1\",      GROUP6 + 16,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dmr2\",      GROUP6 + 17,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcwr0\",     GROUP6 + 18,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dcwr1\",     GROUP6 + 19,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"dsr\",       GROUP6 + 20,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\t{\"drr\",       GROUP6 + 21,   \"org.gnu.gdb.or1k.group6\", \"debug\"},\n\n\t{\"pccr0\",     GROUP7 + 0,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr1\",     GROUP7 + 1,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr2\",     GROUP7 + 2,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr3\",     GROUP7 + 3,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr4\",     GROUP7 + 4,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr5\",     GROUP7 + 5,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr6\",     GROUP7 + 6,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pccr7\",     GROUP7 + 7,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr0\",     GROUP7 + 8,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr1\",     GROUP7 + 9,    \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr2\",     GROUP7 + 10,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr3\",     GROUP7 + 11,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr4\",     GROUP7 + 12,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr5\",     GROUP7 + 13,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr6\",     GROUP7 + 14,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\t{\"pcmr7\",     GROUP7 + 15,   \"org.gnu.gdb.or1k.group7\", \"perf\"},\n\n\t{\"pmr\",       GROUP8 + 0,    \"org.gnu.gdb.or1k.group8\", \"power\"},\n\n\t{\"picmr\",     GROUP9 + 0,    \"org.gnu.gdb.or1k.group9\", \"pic\"},\n\t{\"picsr\",     GROUP9 + 2,    \"org.gnu.gdb.or1k.group9\", \"pic\"},\n\n\t{\"ttmr\",      GROUP10 + 0,   \"org.gnu.gdb.or1k.group10\", \"timer\"},\n\t{\"ttcr\",      GROUP10 + 1,   \"org.gnu.gdb.or1k.group10\", \"timer\"},\n};\n\nstatic int or1k_add_reg(struct target *target, struct or1k_core_reg *new_reg)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tint reg_list_size = or1k->nb_regs * sizeof(struct or1k_core_reg);\n\n\tor1k_core_reg_list_arch_info = realloc(or1k_core_reg_list_arch_info,\n\t\t\t\treg_list_size + sizeof(struct or1k_core_reg));\n\n\tmemcpy(&or1k_core_reg_list_arch_info[or1k->nb_regs], new_reg,\n\t\tsizeof(struct or1k_core_reg));\n\n\tor1k_core_reg_list_arch_info[or1k->nb_regs].list_num = or1k->nb_regs;\n\n\tor1k->nb_regs++;\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_create_reg_list(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\n\tLOG_DEBUG(\"-\");\n\n\tor1k_core_reg_list_arch_info = malloc(ARRAY_SIZE(or1k_init_reg_list) *\n\t\t\t\t       sizeof(struct or1k_core_reg));\n\n\tfor (int i = 0; i < (int)ARRAY_SIZE(or1k_init_reg_list); i++) {\n\t\tor1k_core_reg_list_arch_info[i].name = or1k_init_reg_list[i].name;\n\t\tor1k_core_reg_list_arch_info[i].spr_num = or1k_init_reg_list[i].spr_num;\n\t\tor1k_core_reg_list_arch_info[i].group = or1k_init_reg_list[i].group;\n\t\tor1k_core_reg_list_arch_info[i].feature = or1k_init_reg_list[i].feature;\n\t\tor1k_core_reg_list_arch_info[i].list_num = i;\n\t\tor1k_core_reg_list_arch_info[i].target = NULL;\n\t\tor1k_core_reg_list_arch_info[i].or1k_common = NULL;\n\t}\n\n\tor1k->nb_regs = ARRAY_SIZE(or1k_init_reg_list);\n\n\tstruct or1k_core_reg new_reg;\n\tnew_reg.target = NULL;\n\tnew_reg.or1k_common = NULL;\n\n\tchar name[32];\n\tfor (int way = 0; way < 4; way++) {\n\t\tfor (int i = 0; i < 128; i++) {\n\n\t\t\tsprintf(name, \"dtlbw%dmr%d\", way, i);\n\t\t\tnew_reg.name = strdup(name);\n\t\t\tnew_reg.spr_num = GROUP1 + 512 + i + (way * 256);\n\t\t\tnew_reg.feature = \"org.gnu.gdb.or1k.group1\";\n\t\t\tnew_reg.group = \"dmmu\";\n\t\t\tor1k_add_reg(target, &new_reg);\n\n\t\t\tsprintf(name, \"dtlbw%dtr%d\", way, i);\n\t\t\tnew_reg.name = strdup(name);\n\t\t\tnew_reg.spr_num = GROUP1 + 640 + i + (way * 256);\n\t\t\tnew_reg.feature = \"org.gnu.gdb.or1k.group1\";\n\t\t\tnew_reg.group = \"dmmu\";\n\t\t\tor1k_add_reg(target, &new_reg);\n\n\n\t\t\tsprintf(name, \"itlbw%dmr%d\", way, i);\n\t\t\tnew_reg.name = strdup(name);\n\t\t\tnew_reg.spr_num = GROUP2 + 512 + i + (way * 256);\n\t\t\tnew_reg.feature = \"org.gnu.gdb.or1k.group2\";\n\t\t\tnew_reg.group = \"immu\";\n\t\t\tor1k_add_reg(target, &new_reg);\n\n\n\t\t\tsprintf(name, \"itlbw%dtr%d\", way, i);\n\t\t\tnew_reg.name = strdup(name);\n\t\t\tnew_reg.spr_num = GROUP2 + 640 + i + (way * 256);\n\t\t\tnew_reg.feature = \"org.gnu.gdb.or1k.group2\";\n\t\t\tnew_reg.group = \"immu\";\n\t\t\tor1k_add_reg(target, &new_reg);\n\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_jtag_read_regs(struct or1k_common *or1k, uint32_t *regs)\n{\n\tstruct or1k_du *du_core = or1k_jtag_to_du(&or1k->jtag);\n\n\tLOG_DEBUG(\"-\");\n\n\treturn du_core->or1k_jtag_read_cpu(&or1k->jtag,\n\t\t\tor1k->arch_info[OR1K_REG_R0].spr_num, OR1K_REG_R31 + 1,\n\t\t\tregs + OR1K_REG_R0);\n}\n\nstatic int or1k_jtag_write_regs(struct or1k_common *or1k, uint32_t *regs)\n{\n\tstruct or1k_du *du_core = or1k_jtag_to_du(&or1k->jtag);\n\n\tLOG_DEBUG(\"-\");\n\n\treturn du_core->or1k_jtag_write_cpu(&or1k->jtag,\n\t\t\tor1k->arch_info[OR1K_REG_R0].spr_num, OR1K_REG_R31 + 1,\n\t\t\t&regs[OR1K_REG_R0]);\n}\n\nstatic int or1k_save_context(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tint regs_read = 0;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (int i = 0; i < OR1KNUMCOREREGS; i++) {\n\t\tif (!or1k->core_cache->reg_list[i].valid) {\n\t\t\tif (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) {\n\t\t\t\tretval = du_core->or1k_jtag_read_cpu(&or1k->jtag,\n\t\t\t\t\t\tor1k->arch_info[i].spr_num, 1,\n\t\t\t\t\t\t&or1k->core_regs[i]);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t} else if (!regs_read) {\n\t\t\t\t/* read gpr registers at once (but only one time in this loop) */\n\t\t\t\tretval = or1k_jtag_read_regs(or1k, or1k->core_regs);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\t/* prevent next reads in this loop */\n\t\t\t\tregs_read = 1;\n\t\t\t}\n\t\t\t/* We've just updated the core_reg[i], now update\n\t\t\t   the core cache */\n\t\t\tor1k_read_core_reg(target, i);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_restore_context(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tint reg_write = 0;\n\tint retval;\n\n\tLOG_DEBUG(\"-\");\n\n\tfor (int i = 0; i < OR1KNUMCOREREGS; i++) {\n\t\tif (or1k->core_cache->reg_list[i].dirty) {\n\t\t\tor1k_write_core_reg(target, i);\n\n\t\t\tif (i == OR1K_REG_PPC || i == OR1K_REG_NPC || i == OR1K_REG_SR) {\n\t\t\t\tretval = du_core->or1k_jtag_write_cpu(&or1k->jtag,\n\t\t\t\t\t\tor1k->arch_info[i].spr_num, 1,\n\t\t\t\t\t\t&or1k->core_regs[i]);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Error while restoring context\");\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t} else\n\t\t\t\treg_write = 1;\n\t\t}\n\t}\n\n\tif (reg_write) {\n\t\t/* read gpr registers at once (but only one time in this loop) */\n\t\tretval = or1k_jtag_write_regs(or1k, or1k->core_regs);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while restoring context\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_read_core_reg(struct target *target, int num)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tuint32_t reg_value;\n\n\tLOG_DEBUG(\"-\");\n\n\tif ((num < 0) || (num >= or1k->nb_regs))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif ((num >= 0) && (num < OR1KNUMCOREREGS)) {\n\t\treg_value = or1k->core_regs[num];\n\t\tbuf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value);\n\t\tLOG_DEBUG(\"Read core reg %i value 0x%08\" PRIx32, num, reg_value);\n\t\tor1k->core_cache->reg_list[num].valid = true;\n\t\tor1k->core_cache->reg_list[num].dirty = false;\n\t} else {\n\t\t/* This is an spr, always read value from HW */\n\t\tint retval = du_core->or1k_jtag_read_cpu(&or1k->jtag,\n\t\t\t\t\t\t\t or1k->arch_info[num].spr_num, 1, &reg_value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while reading spr 0x%08\" PRIx32, or1k->arch_info[num].spr_num);\n\t\t\treturn retval;\n\t\t}\n\t\tbuf_set_u32(or1k->core_cache->reg_list[num].value, 0, 32, reg_value);\n\t\tLOG_DEBUG(\"Read spr reg %i value 0x%08\" PRIx32, num, reg_value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_write_core_reg(struct target *target, int num)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\n\tLOG_DEBUG(\"-\");\n\n\tif ((num < 0) || (num >= OR1KNUMCOREREGS))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t reg_value = buf_get_u32(or1k->core_cache->reg_list[num].value, 0, 32);\n\tor1k->core_regs[num] = reg_value;\n\tLOG_DEBUG(\"Write core reg %i value 0x%08\" PRIx32, num, reg_value);\n\tor1k->core_cache->reg_list[num].valid = true;\n\tor1k->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_get_core_reg(struct reg *reg)\n{\n\tstruct or1k_core_reg *or1k_reg = reg->arch_info;\n\tstruct target *target = or1k_reg->target;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\treturn or1k_read_core_reg(target, or1k_reg->list_num);\n}\n\nstatic int or1k_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct or1k_core_reg *or1k_reg = reg->arch_info;\n\tstruct target *target = or1k_reg->target;\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (or1k_reg->list_num < OR1KNUMCOREREGS) {\n\t\tbuf_set_u32(reg->value, 0, 32, value);\n\t\treg->dirty = true;\n\t\treg->valid = true;\n\t} else {\n\t\t/* This is an spr, write it to the HW */\n\t\tint retval = du_core->or1k_jtag_write_cpu(&or1k->jtag,\n\t\t\t\t\t\t\t  or1k_reg->spr_num, 1, &value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while writing spr 0x%08\" PRIx32, or1k_reg->spr_num);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type or1k_reg_type = {\n\t.get = or1k_get_core_reg,\n\t.set = or1k_set_core_reg,\n};\n\nstatic struct reg_cache *or1k_build_reg_cache(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(or1k->nb_regs, sizeof(struct reg));\n\tstruct or1k_core_reg *arch_info =\n\t\tmalloc((or1k->nb_regs) * sizeof(struct or1k_core_reg));\n\tstruct reg_feature *feature;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* Build the process context cache */\n\tcache->name = \"OpenRISC 1000 registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = or1k->nb_regs;\n\t(*cache_p) = cache;\n\tor1k->core_cache = cache;\n\tor1k->arch_info = arch_info;\n\n\tfor (int i = 0; i < or1k->nb_regs; i++) {\n\t\tarch_info[i] = or1k_core_reg_list_arch_info[i];\n\t\tarch_info[i].target = target;\n\t\tarch_info[i].or1k_common = or1k;\n\t\treg_list[i].name = or1k_core_reg_list_arch_info[i].name;\n\n\t\tfeature = malloc(sizeof(struct reg_feature));\n\t\tfeature->name = or1k_core_reg_list_arch_info[i].feature;\n\t\treg_list[i].feature = feature;\n\n\t\treg_list[i].group = or1k_core_reg_list_arch_info[i].group;\n\t\treg_list[i].size = 32;\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].valid = false;\n\t\treg_list[i].type = &or1k_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\t\treg_list[i].number = i;\n\t\treg_list[i].exist = true;\n\t}\n\n\treturn cache;\n}\n\nstatic int or1k_debug_entry(struct target *target)\n{\n\tLOG_DEBUG(\"-\");\n\n\tint retval = or1k_save_context(target);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while calling or1k_save_context\");\n\t\treturn retval;\n\t}\n\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tuint32_t addr = or1k->core_regs[OR1K_REG_NPC];\n\n\tif (breakpoint_find(target, addr))\n\t\t/* Halted on a breakpoint, step back to permit executing the instruction there */\n\t\tretval = or1k_set_core_reg(&or1k->core_cache->reg_list[OR1K_REG_NPC],\n\t\t\t\t\t   (uint8_t *)&addr);\n\n\treturn retval;\n}\n\nstatic int or1k_halt(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\t  target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"Target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"Target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\tif ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) &&\n\t\t    jtag_get_srst()) {\n\t\t\tLOG_ERROR(\"Can't request a halt while in reset if nSRST pulls nTRST\");\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t} else {\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tint retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Impossible to stall the CPU\");\n\t\treturn retval;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_is_cpu_running(struct target *target, int *running)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tint retval;\n\tint tries = 0;\n\tconst int RETRIES_MAX = 5;\n\n\t/* Have a retry loop to determine of the CPU is running.\n\t   If target has been hard reset for any reason, it might take a couple\n\t   of goes before it's ready again.\n\t*/\n\twhile (tries < RETRIES_MAX) {\n\n\t\ttries++;\n\n\t\tretval = du_core->or1k_is_cpu_running(&or1k->jtag, running);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_WARNING(\"Debug IF CPU control reg read failure.\");\n\t\t\t/* Try once to restart the JTAG infrastructure -\n\t\t\t   quite possibly the board has just been reset. */\n\t\t\tLOG_WARNING(\"Resetting JTAG TAP state and reconnecting to debug IF.\");\n\t\t\tdu_core->or1k_jtag_init(&or1k->jtag);\n\n\t\t\tLOG_WARNING(\"...attempt %d of %d\", tries, RETRIES_MAX);\n\n\t\t\talive_sleep(2);\n\n\t\t\tcontinue;\n\t\t} else\n\t\t\treturn ERROR_OK;\n\t}\n\n\tLOG_ERROR(\"Could not re-establish communication with target\");\n\treturn retval;\n}\n\nstatic int or1k_poll(struct target *target)\n{\n\tint retval;\n\tint running;\n\n\tretval = or1k_is_cpu_running(target, &running);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while calling or1k_is_cpu_running\");\n\t\treturn retval;\n\t}\n\n\t/* check for processor halted */\n\tif (!running) {\n\t\t/* It's actually stalled, so update our software's state */\n\t\tif ((target->state == TARGET_RUNNING) ||\n\t\t    (target->state == TARGET_RESET)) {\n\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = or1k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error while calling or1k_debug_entry\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget_call_event_callbacks(target,\n\t\t\t\t\t\t    TARGET_EVENT_HALTED);\n\t\t} else if (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\tretval = or1k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error while calling or1k_debug_entry\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget_call_event_callbacks(target,\n\t\t\t\t\t\t    TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\t} else { /* ... target is running */\n\n\t\t/* If target was supposed to be stalled, stall it again */\n\t\tif  (target->state == TARGET_HALTED) {\n\n\t\t\ttarget->state = TARGET_RUNNING;\n\n\t\t\tretval = or1k_halt(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error while calling or1k_halt\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tretval = or1k_debug_entry(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Error while calling or1k_debug_entry\");\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget_call_event_callbacks(target,\n\t\t\t\t\t\t    TARGET_EVENT_DEBUG_HALTED);\n\t\t}\n\n\t\ttarget->state = TARGET_RUNNING;\n\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_assert_reset(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = du_core->or1k_cpu_reset(&or1k->jtag, CPU_RESET);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while asserting RESET\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_deassert_reset(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = du_core->or1k_cpu_reset(&or1k->jtag, CPU_NOT_RESET);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while deasserting RESET\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_soft_reset_halt(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"-\");\n\n\tint retval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_STALL);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while stalling the CPU\");\n\t\treturn retval;\n\t}\n\n\tretval = or1k_assert_reset(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = or1k_deassert_reset(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic bool is_any_soft_breakpoint(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\twhile (breakpoint)\n\t\tif (breakpoint->type == BKPT_SOFT)\n\t\t\treturn true;\n\n\treturn false;\n}\n\nstatic int or1k_resume_or_step(struct target *target, int current,\n\t\t\t       uint32_t address, int handle_breakpoints,\n\t\t\t       int debug_execution, int step)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tstruct breakpoint *breakpoint = NULL;\n\tuint32_t resume_pc;\n\tuint32_t debug_reg_list[OR1K_DEBUG_REG_NUM];\n\n\tLOG_DEBUG(\"Addr: 0x%\" PRIx32 \", stepping: %s, handle breakpoints %s\\n\",\n\t\t  address, step ? \"yes\" : \"no\", handle_breakpoints ? \"yes\" : \"no\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n\t/* current ? continue on current pc : continue at <address> */\n\tif (!current)\n\t\tbuf_set_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value, 0,\n\t\t\t    32, address);\n\n\tint retval = or1k_restore_context(target);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while calling or1k_restore_context\");\n\t\treturn retval;\n\t}\n\n\t/* read debug registers (starting from DMR1 register) */\n\tretval = du_core->or1k_jtag_read_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,\n\t\t\t\t\t     OR1K_DEBUG_REG_NUM, debug_reg_list);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while reading debug registers\");\n\t\treturn retval;\n\t}\n\n\t/* Clear Debug Reason Register (DRR) */\n\tdebug_reg_list[OR1K_DEBUG_REG_DRR] = 0;\n\n\t/* Clear watchpoint break generation in Debug Mode Register 2 (DMR2) */\n\tdebug_reg_list[OR1K_DEBUG_REG_DMR2] &= ~OR1K_DMR2_WGB;\n\tif (step)\n\t\t/* Set the single step trigger in Debug Mode Register 1 (DMR1) */\n\t\tdebug_reg_list[OR1K_DEBUG_REG_DMR1] |= OR1K_DMR1_ST | OR1K_DMR1_BT;\n\telse\n\t\t/* Clear the single step trigger in Debug Mode Register 1 (DMR1) */\n\t\tdebug_reg_list[OR1K_DEBUG_REG_DMR1] &= ~(OR1K_DMR1_ST | OR1K_DMR1_BT);\n\n\t/* Set traps to be handled by the debug unit in the Debug Stop\n\t   Register (DSR). Check if we have any software breakpoints in\n\t   place before setting this value - the kernel, for instance,\n\t   relies on l.trap instructions not stalling the processor ! */\n\tif (is_any_soft_breakpoint(target) == true)\n\t\tdebug_reg_list[OR1K_DEBUG_REG_DSR] |= OR1K_DSR_TE;\n\n\t/* Write debug registers (starting from DMR1 register) */\n\tretval = du_core->or1k_jtag_write_cpu(&or1k->jtag, OR1K_DMR1_CPU_REG_ADD,\n\t\t\t\t\t      OR1K_DEBUG_REG_NUM, debug_reg_list);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while writing back debug registers\");\n\t\treturn retval;\n\t}\n\n\tresume_pc = buf_get_u32(or1k->core_cache->reg_list[OR1K_REG_NPC].value,\n\t\t\t\t0, 32);\n\n\t/* The front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"Unset breakpoint at 0x%08\" TARGET_PRIxADDR, breakpoint->address);\n\t\t\tretval = or1k_remove_breakpoint(target, breakpoint);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\t/* Unstall time */\n\tretval = du_core->or1k_cpu_stall(&or1k->jtag, CPU_UNSTALL);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while unstalling the CPU\");\n\t\treturn retval;\n\t}\n\n\tif (step)\n\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\telse\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* Registers are now invalid */\n\tregister_cache_invalidate(or1k->core_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"Target resumed at 0x%08\" PRIx32, resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"Target debug resumed at 0x%08\" PRIx32, resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_resume(struct target *target, int current,\n\t\t       target_addr_t address, int handle_breakpoints,\n\t\t       int debug_execution)\n{\n\treturn or1k_resume_or_step(target, current, address,\n\t\t\t\t   handle_breakpoints,\n\t\t\t\t   debug_execution,\n\t\t\t\t   NO_SINGLE_STEP);\n}\n\nstatic int or1k_step(struct target *target, int current,\n\t\t     target_addr_t address, int handle_breakpoints)\n{\n\treturn or1k_resume_or_step(target, current, address,\n\t\t\t\t   handle_breakpoints,\n\t\t\t\t   0,\n\t\t\t\t   SINGLE_STEP);\n\n}\n\nstatic int or1k_add_breakpoint(struct target *target,\n\t\t\t       struct breakpoint *breakpoint)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tuint8_t data;\n\n\tLOG_DEBUG(\"Adding breakpoint: addr 0x%08\" TARGET_PRIxADDR \", len %d, type %d, id: %\" PRIu32,\n\t\t  breakpoint->address, breakpoint->length, breakpoint->type,\n\t\t  breakpoint->unique_id);\n\n\t/* Only support SW breakpoints for now. */\n\tif (breakpoint->type == BKPT_HARD)\n\t\tLOG_ERROR(\"HW breakpoints not supported for now. Doing SW breakpoint.\");\n\n\t/* Read and save the instruction */\n\tint retval = du_core->or1k_jtag_read_memory(&or1k->jtag,\n\t\t\t\t\t breakpoint->address,\n\t\t\t\t\t 4,\n\t\t\t\t\t 1,\n\t\t\t\t\t &data);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while reading the instruction at 0x%08\" TARGET_PRIxADDR,\n\t\t\t   breakpoint->address);\n\t\treturn retval;\n\t}\n\n\tfree(breakpoint->orig_instr);\n\n\tbreakpoint->orig_instr = malloc(breakpoint->length);\n\tmemcpy(breakpoint->orig_instr, &data, breakpoint->length);\n\n\t/* Sub in the OR1K trap instruction */\n\tuint8_t or1k_trap_insn[4];\n\ttarget_buffer_set_u32(target, or1k_trap_insn, OR1K_TRAP_INSTR);\n\tretval = du_core->or1k_jtag_write_memory(&or1k->jtag,\n\t\t\t\t\t  breakpoint->address,\n\t\t\t\t\t  4,\n\t\t\t\t\t  1,\n\t\t\t\t\t  or1k_trap_insn);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while writing OR1K_TRAP_INSTR at 0x%08\" TARGET_PRIxADDR,\n\t\t\t   breakpoint->address);\n\t\treturn retval;\n\t}\n\n\t/* invalidate instruction cache */\n\tuint32_t addr = breakpoint->address;\n\tretval = du_core->or1k_jtag_write_cpu(&or1k->jtag,\n\t\t\tOR1K_ICBIR_CPU_REG_ADD, 1, &addr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while invalidating the ICACHE\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_remove_breakpoint(struct target *target,\n\t\t\t\t  struct breakpoint *breakpoint)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"Removing breakpoint: addr 0x%08\" TARGET_PRIxADDR \", len %d, type %d, id: %\" PRIu32,\n\t\t  breakpoint->address, breakpoint->length, breakpoint->type,\n\t\t  breakpoint->unique_id);\n\n\t/* Only support SW breakpoints for now. */\n\tif (breakpoint->type == BKPT_HARD)\n\t\tLOG_ERROR(\"HW breakpoints not supported for now. Doing SW breakpoint.\");\n\n\t/* Replace the removed instruction */\n\tint retval = du_core->or1k_jtag_write_memory(&or1k->jtag,\n\t\t\t\t\t  breakpoint->address,\n\t\t\t\t\t  4,\n\t\t\t\t\t  1,\n\t\t\t\t\t  breakpoint->orig_instr);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while writing back the instruction at 0x%08\" TARGET_PRIxADDR,\n\t\t\t   breakpoint->address);\n\t\treturn retval;\n\t}\n\n\t/* invalidate instruction cache */\n\tuint32_t addr = breakpoint->address;\n\tretval = du_core->or1k_jtag_write_cpu(&or1k->jtag,\n\t\t\tOR1K_ICBIR_CPU_REG_ADD, 1, &addr);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while invalidating the ICACHE\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_add_watchpoint(struct target *target,\n\t\t\t       struct watchpoint *watchpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int or1k_remove_watchpoint(struct target *target,\n\t\t\t\t  struct watchpoint *watchpoint)\n{\n\tLOG_ERROR(\"%s: implement me\", __func__);\n\treturn ERROR_OK;\n}\n\nstatic int or1k_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"Read memory at 0x%08\" TARGET_PRIxADDR \", size: %\" PRIu32 \", count: 0x%08\" PRIx32, address, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !buffer) {\n\t\tLOG_ERROR(\"Bad arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) {\n\t\tLOG_ERROR(\"Can't handle unaligned memory access\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\treturn du_core->or1k_jtag_read_memory(&or1k->jtag, address, size, count, buffer);\n}\n\nstatic int or1k_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tLOG_DEBUG(\"Write memory at 0x%08\" TARGET_PRIxADDR \", size: %\" PRIu32 \", count: 0x%08\" PRIx32, address, size, count);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"Target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !buffer) {\n\t\tLOG_ERROR(\"Bad arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) {\n\t\tLOG_ERROR(\"Can't handle unaligned memory access\");\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\treturn du_core->or1k_jtag_write_memory(&or1k->jtag, address, size, count, buffer);\n}\n\nstatic int or1k_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tstruct or1k_jtag *jtag = &or1k->jtag;\n\n\tif (!du_core) {\n\t\tLOG_ERROR(\"No debug unit selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!jtag->tap_ip) {\n\t\tLOG_ERROR(\"No tap selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tor1k->jtag.tap = target->tap;\n\tor1k->jtag.or1k_jtag_inited = 0;\n\tor1k->jtag.or1k_jtag_module_selected = -1;\n\tor1k->jtag.target = target;\n\n\tor1k_build_reg_cache(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_target_create(struct target *target, Jim_Interp *interp)\n{\n\tif (!target->tap)\n\t\treturn ERROR_FAIL;\n\n\tstruct or1k_common *or1k = calloc(1, sizeof(struct or1k_common));\n\n\ttarget->arch_info = or1k;\n\n\tor1k_create_reg_list(target);\n\n\tor1k_tap_vjtag_register();\n\tor1k_tap_xilinx_bscan_register();\n\tor1k_tap_mohor_register();\n\n\tor1k_du_adv_register();\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_examine(struct target *target)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\n\tif (!target_was_examined(target)) {\n\n\t\ttarget_set_examined(target);\n\n\t\tint running;\n\n\t\tint retval = du_core->or1k_is_cpu_running(&or1k->jtag, &running);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't read the CPU state\");\n\t\t\treturn retval;\n\t\t} else {\n\t\t\tif (running)\n\t\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\telse {\n\t\t\t\tLOG_DEBUG(\"Target is halted\");\n\n\t\t\t\t/* This is the first time we examine the target,\n\t\t\t\t * it is stalled and we don't know why. Let's\n\t\t\t\t * assume this is because of a debug reason.\n\t\t\t\t */\n\t\t\t\tif (target->state == TARGET_UNKNOWN)\n\t\t\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\t\t\ttarget->state = TARGET_HALTED;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int or1k_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\t\t  int *reg_list_size, enum target_register_class reg_class)\n{\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\n\tif (reg_class == REG_CLASS_GENERAL) {\n\t\t/* We will have this called whenever GDB connects. */\n\t\tint retval = or1k_save_context(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while calling or1k_save_context\");\n\t\t\treturn retval;\n\t\t}\n\t\t*reg_list_size = OR1KNUMCOREREGS;\n\t\t/* this is free()'d back in gdb_server.c's gdb_get_register_packet() */\n\t\t*reg_list = malloc((*reg_list_size) * sizeof(struct reg *));\n\n\t\tfor (int i = 0; i < OR1KNUMCOREREGS; i++)\n\t\t\t(*reg_list)[i] = &or1k->core_cache->reg_list[i];\n\t} else {\n\t\t*reg_list_size = or1k->nb_regs;\n\t\t*reg_list = malloc((*reg_list_size) * sizeof(struct reg *));\n\n\t\tfor (int i = 0; i < or1k->nb_regs; i++)\n\t\t\t(*reg_list)[i] = &or1k->core_cache->reg_list[i];\n\t}\n\n\treturn ERROR_OK;\n\n}\n\nstatic int or1k_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)\n{\n\treturn ERROR_FAIL;\n}\n\nstatic int or1k_checksum_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint32_t *checksum)\n{\n\treturn ERROR_FAIL;\n}\n\nstatic int or1k_profiling(struct target *target, uint32_t *samples,\n\t\tuint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)\n{\n\tstruct timeval timeout, now;\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_du *du_core = or1k_to_du(or1k);\n\tint retval = ERROR_OK;\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, seconds, 0);\n\n\tLOG_INFO(\"Starting or1k profiling. Sampling npc as fast as we can...\");\n\n\t/* Make sure the target is running */\n\ttarget_poll(target);\n\tif (target->state == TARGET_HALTED)\n\t\tretval = target_resume(target, 1, 0, 0, 0);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while resuming target\");\n\t\treturn retval;\n\t}\n\n\tuint32_t sample_count = 0;\n\n\tfor (;;) {\n\t\tuint32_t reg_value;\n\t\tretval = du_core->or1k_jtag_read_cpu(&or1k->jtag, GROUP0 + 16 /* NPC */, 1, &reg_value);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error while reading NPC\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tsamples[sample_count++] = reg_value;\n\n\t\tgettimeofday(&now, NULL);\n\t\tif ((sample_count >= max_num_samples) || timeval_compare(&now, &timeout) > 0) {\n\t\t\tLOG_INFO(\"Profiling completed. %\" PRIu32 \" samples.\", sample_count);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t*num_samples = sample_count;\n\treturn retval;\n}\n\nCOMMAND_HANDLER(or1k_tap_select_command_handler)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_jtag *jtag = &or1k->jtag;\n\tstruct or1k_tap_ip *or1k_tap;\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(or1k_tap, &tap_list, list) {\n\t\tif (or1k_tap->name) {\n\t\t\tif (!strcmp(CMD_ARGV[0], or1k_tap->name)) {\n\t\t\t\tjtag->tap_ip = or1k_tap;\n\t\t\t\tLOG_INFO(\"%s tap selected\", or1k_tap->name);\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_ERROR(\"%s unknown, no tap selected\", CMD_ARGV[0]);\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HANDLER(or1k_tap_list_command_handler)\n{\n\tstruct or1k_tap_ip *or1k_tap;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(or1k_tap, &tap_list, list) {\n\t\tif (or1k_tap->name)\n\t\t\tcommand_print(CMD, \"%s\", or1k_tap->name);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(or1k_du_select_command_handler)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct or1k_common *or1k = target_to_or1k(target);\n\tstruct or1k_jtag *jtag = &or1k->jtag;\n\tstruct or1k_du *or1k_du;\n\n\tif (CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(or1k_du, &du_list, list) {\n\t\tif (or1k_du->name) {\n\t\t\tif (!strcmp(CMD_ARGV[0], or1k_du->name)) {\n\t\t\t\tjtag->du_core = or1k_du;\n\t\t\t\tLOG_INFO(\"%s debug unit selected\", or1k_du->name);\n\n\t\t\t\tif (CMD_ARGC == 2) {\n\t\t\t\t\tint options;\n\t\t\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], options);\n\t\t\t\t\tor1k_du->options = options;\n\t\t\t\t\tLOG_INFO(\"Option %x is passed to %s debug unit\"\n\t\t\t\t\t\t , options, or1k_du->name);\n\t\t\t\t}\n\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_ERROR(\"%s unknown, no debug unit selected\", CMD_ARGV[0]);\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HANDLER(or1k_du_list_command_handler)\n{\n\tstruct or1k_du *or1k_du;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(or1k_du, &du_list, list) {\n\t\tif (or1k_du->name)\n\t\t\tcommand_print(CMD, \"%s\", or1k_du->name);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(or1k_addreg_command_handler)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct or1k_core_reg new_reg;\n\n\tif (CMD_ARGC != 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tnew_reg.target = NULL;\n\tnew_reg.or1k_common = NULL;\n\n\tuint32_t addr;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], addr);\n\n\tnew_reg.name = strdup(CMD_ARGV[0]);\n\tnew_reg.spr_num = addr;\n\tnew_reg.feature = strdup(CMD_ARGV[2]);\n\tnew_reg.group = strdup(CMD_ARGV[3]);\n\n\tor1k_add_reg(target, &new_reg);\n\n\tLOG_DEBUG(\"Add reg \\\"%s\\\" @ 0x%08\" PRIx32 \", group \\\"%s\\\", feature \\\"%s\\\"\",\n\t\t  new_reg.name, addr, new_reg.group, new_reg.feature);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration or1k_hw_ip_command_handlers[] = {\n\t{\n\t\t.name = \"tap_select\",\n\t\t.handler = or1k_tap_select_command_handler,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"name\",\n\t\t.help = \"Select the TAP core to use\",\n\t},\n\t{\n\t\t.name = \"tap_list\",\n\t\t.handler = or1k_tap_list_command_handler,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"\",\n\t\t.help = \"Display available TAP core\",\n\t},\n\t{\n\t\t.name = \"du_select\",\n\t\t.handler = or1k_du_select_command_handler,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"name\",\n\t\t.help = \"Select the Debug Unit core to use\",\n\t},\n\t{\n\t\t.name = \"du_list\",\n\t\t.handler = or1k_du_list_command_handler,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"select_tap name\",\n\t\t.help = \"Display available Debug Unit core\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration or1k_reg_command_handlers[] = {\n\t{\n\t\t.name = \"addreg\",\n\t\t.handler = or1k_addreg_command_handler,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"name addr feature group\",\n\t\t.help = \"Add a register to the register list\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration or1k_command_handlers[] = {\n\t{\n\t\t.chain = or1k_reg_command_handlers,\n\t},\n\t{\n\t\t.chain = or1k_hw_ip_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n\nstruct target_type or1k_target = {\n\t.name = \"or1k\",\n\n\t.poll = or1k_poll,\n\t.arch_state = or1k_arch_state,\n\n\t.target_request_data = NULL,\n\n\t.halt = or1k_halt,\n\t.resume = or1k_resume,\n\t.step = or1k_step,\n\n\t.assert_reset = or1k_assert_reset,\n\t.deassert_reset = or1k_deassert_reset,\n\t.soft_reset_halt = or1k_soft_reset_halt,\n\n\t.get_gdb_reg_list = or1k_get_gdb_reg_list,\n\n\t.read_memory = or1k_read_memory,\n\t.write_memory = or1k_write_memory,\n\t.checksum_memory = or1k_checksum_memory,\n\n\t.commands = or1k_command_handlers,\n\t.add_breakpoint = or1k_add_breakpoint,\n\t.remove_breakpoint = or1k_remove_breakpoint,\n\t.add_watchpoint = or1k_add_watchpoint,\n\t.remove_watchpoint = or1k_remove_watchpoint,\n\n\t.target_create = or1k_target_create,\n\t.init_target = or1k_init_target,\n\t.examine = or1k_examine,\n\n\t.get_gdb_fileio_info = or1k_get_gdb_fileio_info,\n\n\t.profiling = or1k_profiling,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2011 by Julius Baxter                                   *\n *   julius@opencores.org                                                  *\n *                                                                         *\n *   Copyright (C) 2013 by Marek Czerski                                   *\n *   ma.czerski@gmail.com                                                  *\n *                                                                         *\n *   Copyright (C) 2013 by Franck Jullien                                  *\n *   elec4fun@gmail.com                                                    *\n *                                                                         *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_OPENRISC_OR1K_H\n#define OPENOCD_TARGET_OPENRISC_OR1K_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <target/target.h>\n\n/* SPR groups start address */\n#define GROUP0\t\t(0  << 11)\n#define GROUP1\t\t(1  << 11)\n#define GROUP2\t\t(2  << 11)\n#define GROUP3\t\t(3  << 11)\n#define GROUP4\t\t(4  << 11)\n#define GROUP5\t\t(5  << 11)\n#define GROUP6\t\t(6  << 11)\n#define GROUP7\t\t(7  << 11)\n#define GROUP8\t\t(8  << 11)\n#define GROUP9\t\t(9  << 11)\n#define GROUP10\t\t(10 << 11)\n\n/* OR1K registers */\nenum or1k_reg_nums {\n\tOR1K_REG_R0 = 0,\n\tOR1K_REG_R1,\n\tOR1K_REG_R2,\n\tOR1K_REG_R3,\n\tOR1K_REG_R4,\n\tOR1K_REG_R5,\n\tOR1K_REG_R6,\n\tOR1K_REG_R7,\n\tOR1K_REG_R8,\n\tOR1K_REG_R9,\n\tOR1K_REG_R10,\n\tOR1K_REG_R11,\n\tOR1K_REG_R12,\n\tOR1K_REG_R13,\n\tOR1K_REG_R14,\n\tOR1K_REG_R15,\n\tOR1K_REG_R16,\n\tOR1K_REG_R17,\n\tOR1K_REG_R18,\n\tOR1K_REG_R19,\n\tOR1K_REG_R20,\n\tOR1K_REG_R21,\n\tOR1K_REG_R22,\n\tOR1K_REG_R23,\n\tOR1K_REG_R24,\n\tOR1K_REG_R25,\n\tOR1K_REG_R26,\n\tOR1K_REG_R27,\n\tOR1K_REG_R28,\n\tOR1K_REG_R29,\n\tOR1K_REG_R30,\n\tOR1K_REG_R31,\n\tOR1K_REG_PPC,\n\tOR1K_REG_NPC,\n\tOR1K_REG_SR,\n\tOR1KNUMCOREREGS\n};\n\nstruct or1k_jtag {\n\tstruct jtag_tap *tap;\n\tint or1k_jtag_inited;\n\tint or1k_jtag_module_selected;\n\tuint8_t *current_reg_idx;\n\tstruct or1k_tap_ip *tap_ip;\n\tstruct or1k_du *du_core;\n\tstruct target *target;\n};\n\nstruct or1k_common {\n\tstruct or1k_jtag jtag;\n\tstruct reg_cache *core_cache;\n\tuint32_t core_regs[OR1KNUMCOREREGS];\n\tint nb_regs;\n\tstruct or1k_core_reg *arch_info;\n};\n\nstatic inline struct or1k_common *\ntarget_to_or1k(struct target *target)\n{\n\treturn (struct or1k_common *)target->arch_info;\n}\n\nstruct or1k_core_reg {\n\tconst char *name;\n\tuint32_t list_num;   /* Index in register cache */\n\tuint32_t spr_num;    /* Number in architecture's SPR space */\n\tstruct target *target;\n\tstruct or1k_common *or1k_common;\n\tconst char *feature; /* feature name in XML tdesc file */\n\tconst char *group;   /* register group in XML tdesc file */\n};\n\nstruct or1k_core_reg_init {\n\tconst char *name;\n\tuint32_t spr_num;    /* Number in architecture's SPR space */\n\tconst char *feature; /* feature name in XML tdesc file */\n\tconst char *group;   /* register group in XML tdesc file */\n};\n\n/* ORBIS32 Trap instruction */\n#define OR1K_TRAP_INSTR  0x21000001\n\nenum or1k_debug_reg_nums {\n\tOR1K_DEBUG_REG_DMR1 = 0,\n\tOR1K_DEBUG_REG_DMR2,\n\tOR1K_DEBUG_REG_DCWR0,\n\tOR1K_DEBUG_REG_DCWR1,\n\tOR1K_DEBUG_REG_DSR,\n\tOR1K_DEBUG_REG_DRR,\n\tOR1K_DEBUG_REG_NUM\n};\n\n#define NO_SINGLE_STEP\t\t0\n#define SINGLE_STEP\t\t1\n\n/* OR1K Debug registers and bits needed for resuming */\n#define OR1K_DEBUG_REG_BASE\tGROUP6                     /* Debug registers Base address */\n#define OR1K_DMR1_CPU_REG_ADD\t(OR1K_DEBUG_REG_BASE + 16) /* Debug Mode Register 1 0x3010 */\n#define OR1K_DMR1_ST\t\t0x00400000                 /* Single-step trace */\n#define OR1K_DMR1_BT\t\t0x00800000                 /* Branch trace */\n#define OR1K_DMR2_WGB\t\t0x003ff000                 /* Watchpoints generating breakpoint */\n#define OR1K_DSR_TE\t\t0x00002000                 /* Trap exception */\n\n/* OR1K Instruction cache registers needed for invalidating instruction\n * memory during adding and removing breakpoints.\n */\n#define OR1K_ICBIR_CPU_REG_ADD ((4 << 11) + 2)             /* IC Block Invalidate Register 0x2002 */\n\n#endif /* OPENOCD_TARGET_OPENRISC_OR1K_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_du.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2013 Franck Jullien                                     *\n *   elec4fun@gmail.com                                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_OPENRISC_OR1K_DU_H\n#define OPENOCD_TARGET_OPENRISC_OR1K_DU_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#define CPU_STALL\t0\n#define CPU_UNSTALL\t1\n\n#define CPU_RESET\t0\n#define CPU_NOT_RESET\t1\n\nint or1k_du_adv_register(void);\n\n/* Linear list over all available or1k debug unit */\nextern struct list_head du_list;\n\nstruct or1k_du {\n\tconst char *name;\n\tstruct list_head list;\n\tint options;\n\n\tint (*or1k_jtag_init)(struct or1k_jtag *jtag_info);\n\n\tint (*or1k_is_cpu_running)(struct or1k_jtag *jtag_info, int *running);\n\n\tint (*or1k_cpu_stall)(struct or1k_jtag *jtag_info, int action);\n\n\tint (*or1k_cpu_reset)(struct or1k_jtag *jtag_info, int action);\n\n\tint (*or1k_jtag_read_cpu)(struct or1k_jtag *jtag_info,\n\t\t\t\t  uint32_t addr, int count, uint32_t *value);\n\n\tint (*or1k_jtag_write_cpu)(struct or1k_jtag *jtag_info,\n\t\t\t\t   uint32_t addr, int count, const uint32_t *value);\n\n\tint (*or1k_jtag_read_memory)(struct or1k_jtag *jtag_info, uint32_t addr, uint32_t size,\n\t\t\t\t\tint count, uint8_t *buffer);\n\n\tint (*or1k_jtag_write_memory)(struct or1k_jtag *jtag_info, uint32_t addr, uint32_t size,\n\t\t\t\t\t int count, const uint8_t *buffer);\n};\n\nstatic inline struct or1k_du *or1k_jtag_to_du(struct or1k_jtag *jtag_info)\n{\n\treturn (struct or1k_du *)jtag_info->du_core;\n}\n\nstatic inline struct or1k_du *or1k_to_du(struct or1k_common *or1k)\n{\n\tstruct or1k_jtag *jtag = &or1k->jtag;\n\treturn (struct or1k_du *)jtag->du_core;\n}\n\nint or1k_adv_jtag_jsp_xfer(struct or1k_jtag *jtag_info,\n\t\t\t\t  int *out_len, unsigned char *out_buffer,\n\t\t\t\t  int *in_len, unsigned char *in_buffer);\n\n#endif /* OPENOCD_TARGET_OPENRISC_OR1K_DU_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_du_adv.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013-2014 by Franck Jullien                             *\n *   elec4fun@gmail.com                                                    *\n *                                                                         *\n *   Inspired from adv_jtag_bridge which is:                               *\n *   Copyright (C) 2008-2010 Nathan Yawn                                   *\n *   nyawn@opencores.net                                                   *\n *                                                                         *\n *   And the Mohor interface version of this file which is:                *\n *   Copyright (C) 2011 by Julius Baxter                                   *\n *   julius@opencores.org                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n#include \"or1k_du.h\"\n#include \"jsp_server.h\"\n\n#include <helper/crc32.h>\n#include <jtag/jtag.h>\n#include <target/target.h>\n\n#define JSP_BANNER \"\\n\\r\" \\\n\t\t   \"******************************\\n\\r\" \\\n\t\t   \"**     JTAG Serial Port     **\\n\\r\" \\\n\t\t   \"******************************\\n\\r\" \\\n\t\t   \"\\n\\r\"\n\n#define NO_OPTION\t\t\t0\n\n/* This an option to the adv debug unit.\n * If this is defined, status bits will be skipped on burst\n * reads and writes to improve download speeds.\n * This option must match the RTL configured option.\n */\n#define ADBG_USE_HISPEED\t\t1\n\n/* This an option to the adv debug unit.\n * If this is defined, the JTAG Serial Port Server is started.\n * This option must match the RTL configured option.\n */\n#define ENABLE_JSP_SERVER\t\t2\n\n/* Define this if you intend to use the JSP in a system with multiple\n * devices on the JTAG chain\n */\n#define ENABLE_JSP_MULTI\t\t4\n\n/* Definitions for the top-level debug unit.  This really just consists\n * of a single register, used to select the active debug module (\"chain\").\n */\n#define DBG_MODULE_SELECT_REG_SIZE\t2\n#define DBG_MAX_MODULES\t\t\t4\n\n#define DC_NONE\t\t\t\t-1\n#define DC_WISHBONE\t\t\t0\n#define DC_CPU0\t\t\t\t1\n#define DC_CPU1\t\t\t\t2\n#define DC_JSP\t\t\t\t3\n\n/* CPU control register bits mask */\n#define DBG_CPU_CR_STALL\t\t0x01\n#define DBG_CPU_CR_RESET\t\t0x02\n\n/* These are for the internal registers in the Wishbone module\n * The first is the length of the index register,\n * the indexes of the various registers are defined after that.\n */\n#define DBG_WB_REG_SEL_LEN\t\t1\n#define DBG_WB_REG_ERROR\t\t0\n\n/* Opcode definitions for the Wishbone module. */\n#define DBG_WB_OPCODE_LEN\t\t4\n#define DBG_WB_CMD_NOP\t\t\t0x0\n#define DBG_WB_CMD_BWRITE8\t\t0x1\n#define DBG_WB_CMD_BWRITE16\t\t0x2\n#define DBG_WB_CMD_BWRITE32\t\t0x3\n#define DBG_WB_CMD_BREAD8\t\t0x5\n#define DBG_WB_CMD_BREAD16\t\t0x6\n#define DBG_WB_CMD_BREAD32\t\t0x7\n#define DBG_WB_CMD_IREG_WR\t\t0x9\n#define DBG_WB_CMD_IREG_SEL\t\t0xd\n\n/* Internal register definitions for the CPU0 module. */\n#define DBG_CPU0_REG_SEL_LEN\t\t1\n#define DBG_CPU0_REG_STATUS\t\t0\n\n/* Opcode definitions for the first CPU module. */\n#define DBG_CPU0_OPCODE_LEN\t\t4\n#define DBG_CPU0_CMD_NOP\t\t0x0\n#define DBG_CPU0_CMD_BWRITE32\t\t0x3\n#define DBG_CPU0_CMD_BREAD32\t\t0x7\n#define DBG_CPU0_CMD_IREG_WR\t\t0x9\n#define DBG_CPU0_CMD_IREG_SEL\t\t0xd\n\n/* Internal register definitions for the CPU1 module. */\n#define DBG_CPU1_REG_SEL_LEN\t\t1\n#define DBG_CPU1_REG_STATUS\t\t0\n\n/* Opcode definitions for the second CPU module. */\n#define DBG_CPU1_OPCODE_LEN\t\t4\n#define DBG_CPU1_CMD_NOP\t\t0x0\n#define DBG_CPU1_CMD_BWRITE32\t\t0x3\n#define DBG_CPU1_CMD_BREAD32\t\t0x7\n#define DBG_CPU1_CMD_IREG_WR\t\t0x9\n#define DBG_CPU1_CMD_IREG_SEL\t\t0xd\n\n#define MAX_READ_STATUS_WAIT\t\t10\n#define MAX_READ_BUSY_RETRY\t\t2\n#define MAX_READ_CRC_RETRY\t\t2\n#define MAX_WRITE_CRC_RETRY\t\t2\n#define BURST_READ_READY\t\t1\n#define MAX_BUS_ERRORS\t\t\t2\n\n#define MAX_BURST_SIZE\t\t\t(4 * 1024)\n\n#define STATUS_BYTES\t\t\t1\n#define CRC_LEN\t\t\t\t4\n\nstatic struct or1k_du or1k_du_adv;\n\nstatic const char * const chain_name[] = {\"WISHBONE\", \"CPU0\", \"CPU1\", \"JSP\"};\n\nstatic int find_status_bit(void *_buf, int len)\n{\n\tint i = 0;\n\tint count = 0;\n\tint ret = -1;\n\tuint8_t *buf = _buf;\n\n\twhile (!(buf[i] & (1 << count++)) && (i < len)) {\n\t\tif (count == 8) {\n\t\t\tcount = 0;\n\t\t\ti++;\n\t\t}\n\t}\n\n\tif (i < len)\n\t\tret = (i * 8) + count;\n\n\treturn ret;\n}\n\nstatic int or1k_adv_jtag_init(struct or1k_jtag *jtag_info)\n{\n\tstruct or1k_tap_ip *tap_ip = jtag_info->tap_ip;\n\n\tint retval = tap_ip->init(jtag_info);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"TAP initialization failed\");\n\t\treturn retval;\n\t}\n\n\t/* TAP is now configured to communicate with debug interface */\n\tjtag_info->or1k_jtag_inited = 1;\n\n\t/* TAP reset - not sure what state debug module chain is in now */\n\tjtag_info->or1k_jtag_module_selected = DC_NONE;\n\n\tjtag_info->current_reg_idx = malloc(DBG_MAX_MODULES * sizeof(uint8_t));\n\tmemset(jtag_info->current_reg_idx, 0, DBG_MAX_MODULES * sizeof(uint8_t));\n\n\tif (or1k_du_adv.options & ADBG_USE_HISPEED)\n\t\tLOG_INFO(\"adv debug unit is configured with option ADBG_USE_HISPEED\");\n\n\tif (or1k_du_adv.options & ENABLE_JSP_SERVER) {\n\t\tif (or1k_du_adv.options & ENABLE_JSP_MULTI)\n\t\t\tLOG_INFO(\"adv debug unit is configured with option ENABLE_JSP_MULTI\");\n\t\tLOG_INFO(\"adv debug unit is configured with option ENABLE_JSP_SERVER\");\n\t\tretval = jsp_init(jtag_info, JSP_BANNER);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Couldn't start the JSP server\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tLOG_DEBUG(\"Init done\");\n\n\treturn ERROR_OK;\n\n}\n\n/* Selects one of the modules in the debug unit\n * (e.g. wishbone unit, CPU0, etc.)\n */\nstatic int adbg_select_module(struct or1k_jtag *jtag_info, int chain)\n{\n\tif (jtag_info->or1k_jtag_module_selected == chain)\n\t\treturn ERROR_OK;\n\n\t/* MSB of the data out must be set to 1, indicating a module\n\t * select command\n\t */\n\tuint8_t data = chain | (1 << DBG_MODULE_SELECT_REG_SIZE);\n\n\tLOG_DEBUG(\"Select module: %s\", chain_name[chain]);\n\n\tstruct scan_field field;\n\n\tfield.num_bits = (DBG_MODULE_SELECT_REG_SIZE + 1);\n\tfield.out_value = &data;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tjtag_info->or1k_jtag_module_selected = chain;\n\n\treturn ERROR_OK;\n}\n\n/* Set the index of the desired register in the currently selected module\n * 1 bit module select command\n * 4 bits opcode\n * n bits index\n */\nstatic int adbg_select_ctrl_reg(struct or1k_jtag *jtag_info, uint8_t regidx)\n{\n\tint index_len;\n\tuint32_t opcode;\n\tuint32_t opcode_len;\n\n\t/* If this reg is already selected, don't do a JTAG transaction */\n\tif (jtag_info->current_reg_idx[jtag_info->or1k_jtag_module_selected] == regidx)\n\t\treturn ERROR_OK;\n\n\tswitch (jtag_info->or1k_jtag_module_selected) {\n\tcase DC_WISHBONE:\n\t\tindex_len = DBG_WB_REG_SEL_LEN;\n\t\topcode = DBG_WB_CMD_IREG_SEL;\n\t\topcode_len = DBG_WB_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU0:\n\t\tindex_len = DBG_CPU0_REG_SEL_LEN;\n\t\topcode = DBG_CPU0_CMD_IREG_SEL;\n\t\topcode_len = DBG_CPU0_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU1:\n\t\tindex_len = DBG_CPU1_REG_SEL_LEN;\n\t\topcode = DBG_CPU1_CMD_IREG_SEL;\n\t\topcode_len = DBG_CPU1_OPCODE_LEN;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Illegal debug chain selected (%i) while selecting control register\",\n\t\t\t  jtag_info->or1k_jtag_module_selected);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* MSB must be 0 to access modules */\n\tuint32_t data = (opcode & ~(1 << opcode_len)) << index_len;\n\tdata |= regidx;\n\n\tstruct scan_field field;\n\n\tfield.num_bits = (opcode_len + 1) + index_len;\n\tfield.out_value = (uint8_t *)&data;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tjtag_info->current_reg_idx[jtag_info->or1k_jtag_module_selected] = regidx;\n\n\treturn ERROR_OK;\n}\n\n/* Write control register (internal to the debug unit) */\nstatic int adbg_ctrl_write(struct or1k_jtag *jtag_info, uint8_t regidx,\n\t\t\t   uint32_t *cmd_data, int length_bits)\n{\n\tint index_len;\n\tuint32_t opcode;\n\tuint32_t opcode_len;\n\n\tLOG_DEBUG(\"Write control register %\" PRId8 \": 0x%08\" PRIx32, regidx, cmd_data[0]);\n\n\tint retval = adbg_select_ctrl_reg(jtag_info, regidx);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while calling adbg_select_ctrl_reg\");\n\t\treturn retval;\n\t}\n\n\tswitch (jtag_info->or1k_jtag_module_selected) {\n\tcase DC_WISHBONE:\n\t\tindex_len = DBG_WB_REG_SEL_LEN;\n\t\topcode = DBG_WB_CMD_IREG_WR;\n\t\topcode_len = DBG_WB_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU0:\n\t\tindex_len = DBG_CPU0_REG_SEL_LEN;\n\t\topcode = DBG_CPU0_CMD_IREG_WR;\n\t\topcode_len = DBG_CPU0_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU1:\n\t\tindex_len = DBG_CPU1_REG_SEL_LEN;\n\t\topcode = DBG_CPU1_CMD_IREG_WR;\n\t\topcode_len = DBG_CPU1_OPCODE_LEN;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Illegal debug chain selected (%i) while doing control write\",\n\t\t\t  jtag_info->or1k_jtag_module_selected);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct scan_field field[2];\n\n\t/* MSB must be 0 to access modules */\n\tuint32_t data = (opcode & ~(1 << opcode_len)) << index_len;\n\tdata |= regidx;\n\n\tfield[0].num_bits = length_bits;\n\tfield[0].out_value = (uint8_t *)cmd_data;\n\tfield[0].in_value = NULL;\n\n\tfield[1].num_bits = (opcode_len + 1) + index_len;\n\tfield[1].out_value = (uint8_t *)&data;\n\tfield[1].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 2, field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\n/* Reads control register (internal to the debug unit) */\nstatic int adbg_ctrl_read(struct or1k_jtag *jtag_info, uint32_t regidx,\n\t\t\t  uint32_t *data, int length_bits)\n{\n\n\tint retval = adbg_select_ctrl_reg(jtag_info, regidx);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Error while calling adbg_select_ctrl_reg\");\n\t\treturn retval;\n\t}\n\n\tint opcode_len;\n\tuint32_t opcode;\n\n\t/* There is no 'read' command, We write a NOP to read */\n\tswitch (jtag_info->or1k_jtag_module_selected) {\n\tcase DC_WISHBONE:\n\t\topcode = DBG_WB_CMD_NOP;\n\t\topcode_len = DBG_WB_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU0:\n\t\topcode = DBG_CPU0_CMD_NOP;\n\t\topcode_len = DBG_CPU0_OPCODE_LEN;\n\t\tbreak;\n\tcase DC_CPU1:\n\t\topcode = DBG_CPU1_CMD_NOP;\n\t\topcode_len = DBG_CPU1_OPCODE_LEN;\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Illegal debug chain selected (%i) while doing control read\",\n\t\t\t  jtag_info->or1k_jtag_module_selected);\n\t\t return ERROR_FAIL;\n\t}\n\n\t/* Zero MSB = op for module, not top-level debug unit */\n\tuint32_t outdata = opcode & ~(0x1 << opcode_len);\n\n\tstruct scan_field field[2];\n\n\tfield[0].num_bits = length_bits;\n\tfield[0].out_value = NULL;\n\tfield[0].in_value = (uint8_t *)data;\n\n\tfield[1].num_bits = opcode_len + 1;\n\tfield[1].out_value = (uint8_t *)&outdata;\n\tfield[1].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 2, field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\n/* sends out a burst command to the selected module in the debug unit (MSB to LSB):\n * 1-bit module command\n * 4-bit opcode\n * 32-bit address\n * 16-bit length (of the burst, in words)\n */\nstatic int adbg_burst_command(struct or1k_jtag *jtag_info, uint32_t opcode,\n\t\t\t      uint32_t address, uint16_t length_words)\n{\n\tuint32_t data[2];\n\n\t/* Set up the data */\n\tdata[0] = length_words | (address << 16);\n\t/* MSB must be 0 to access modules */\n\tdata[1] = ((address >> 16) | ((opcode & 0xf) << 16)) & ~(0x1 << 20);\n\n\tstruct scan_field field;\n\n\tfield.num_bits = 53;\n\tfield.out_value = (uint8_t *)&data[0];\n\tfield.in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic int adbg_wb_burst_read(struct or1k_jtag *jtag_info, int size,\n\t\t\t      int count, uint32_t start_address, uint8_t *data)\n{\n\tint retry_full_crc = 0;\n\tint retry_full_busy = 0;\n\tint retval;\n\tuint8_t opcode;\n\n\tLOG_DEBUG(\"Doing burst read, word size %d, word count %d, start address 0x%08\" PRIx32,\n\t\t  size, count, start_address);\n\n\t/* Select the appropriate opcode */\n\tswitch (jtag_info->or1k_jtag_module_selected) {\n\tcase DC_WISHBONE:\n\t\tif (size == 1)\n\t\t\topcode = DBG_WB_CMD_BREAD8;\n\t\telse if (size == 2)\n\t\t\topcode = DBG_WB_CMD_BREAD16;\n\t\telse if (size == 4)\n\t\t\topcode = DBG_WB_CMD_BREAD32;\n\t\telse {\n\t\t\tLOG_WARNING(\"Tried burst read with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_WB_CMD_BREAD32;\n\t\t}\n\t\tbreak;\n\tcase DC_CPU0:\n\t\tif (size == 4)\n\t\t\topcode = DBG_CPU0_CMD_BREAD32;\n\t\telse {\n\t\t\tLOG_WARNING(\"Tried burst read with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_CPU0_CMD_BREAD32;\n\t\t}\n\t\tbreak;\n\tcase DC_CPU1:\n\t\tif (size == 4)\n\t\t\topcode = DBG_CPU1_CMD_BREAD32;\n\t\telse {\n\t\t\tLOG_WARNING(\"Tried burst read with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_CPU0_CMD_BREAD32;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Illegal debug chain selected (%i) while doing burst read\",\n\t\t\t  jtag_info->or1k_jtag_module_selected);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint total_size_bytes = count * size;\n\tstruct scan_field field;\n\tuint8_t *in_buffer = malloc(total_size_bytes + CRC_LEN + STATUS_BYTES);\n\nretry_read_full:\n\n\t/* Send the BURST READ command, returns TAP to idle state */\n\tretval = adbg_burst_command(jtag_info, opcode, start_address, count);\n\tif (retval != ERROR_OK)\n\t\tgoto out;\n\n\tfield.num_bits = (total_size_bytes + CRC_LEN + STATUS_BYTES) * 8;\n\tfield.out_value = NULL;\n\tfield.in_value = in_buffer;\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\tgoto out;\n\n\t/* Look for the start bit in the first (STATUS_BYTES * 8) bits */\n\tint shift = find_status_bit(in_buffer, STATUS_BYTES);\n\n\t/* We expect the status bit to be in the first byte */\n\tif (shift < 0) {\n\t\tif (retry_full_busy++ < MAX_READ_BUSY_RETRY) {\n\t\t\tLOG_WARNING(\"Burst read timed out\");\n\t\t\tgoto retry_read_full;\n\t\t} else {\n\t\t\tLOG_ERROR(\"Burst read failed\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t}\n\n\tbuffer_shr(in_buffer, total_size_bytes + CRC_LEN + STATUS_BYTES, shift);\n\n\tuint32_t crc_read;\n\tmemcpy(data, in_buffer, total_size_bytes);\n\tmemcpy(&crc_read, &in_buffer[total_size_bytes], 4);\n\n\tuint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data,\n\t\t\ttotal_size_bytes);\n\n\tif (crc_calc != crc_read) {\n\t\tLOG_WARNING(\"CRC ERROR! Computed 0x%08\" PRIx32 \", read CRC 0x%08\" PRIx32, crc_calc, crc_read);\n\t\tif (retry_full_crc++ < MAX_READ_CRC_RETRY)\n\t\t\tgoto retry_read_full;\n\t\telse {\n\t\t\tLOG_ERROR(\"Burst read failed\");\n\t\t\tretval = ERROR_FAIL;\n\t\t\tgoto out;\n\t\t}\n\t} else\n\t\tLOG_DEBUG(\"CRC OK!\");\n\n\t/* Now, read the error register, and retry/recompute as necessary */\n\tif (jtag_info->or1k_jtag_module_selected == DC_WISHBONE &&\n\t    !(or1k_du_adv.options & ADBG_USE_HISPEED)) {\n\n\t\tuint32_t err_data[2] = {0, 0};\n\t\tuint32_t addr;\n\t\tint bus_error_retries = 0;\n\n\t\t/* First, just get 1 bit...read address only if necessary */\n\t\tretval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\tgoto out;\n\n\t\t/* Then we have a problem */\n\t\tif (err_data[0] & 0x1) {\n\n\t\t\tretval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 33);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto out;\n\n\t\t\taddr = (err_data[0] >> 1) | (err_data[1] << 31);\n\t\t\tLOG_WARNING(\"WB bus error during burst read, address 0x%08\" PRIx32 \", retrying!\", addr);\n\n\t\t\tbus_error_retries++;\n\t\t\tif (bus_error_retries > MAX_BUS_ERRORS) {\n\t\t\t\tLOG_ERROR(\"Max WB bus errors reached during burst read\");\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto out;\n\t\t\t}\n\n\t\t\t/* Don't call retry_do(), a JTAG reset won't help a WB bus error */\n\t\t\t/* Write 1 bit, to reset the error register */\n\t\t\terr_data[0] = 1;\n\t\t\tretval = adbg_ctrl_write(jtag_info, DBG_WB_REG_ERROR, err_data, 1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\tgoto out;\n\n\t\t\tgoto retry_read_full;\n\t\t}\n\t}\n\nout:\n\tfree(in_buffer);\n\n\treturn retval;\n}\n\n/* Set up and execute a burst write to a contiguous set of addresses */\nstatic int adbg_wb_burst_write(struct or1k_jtag *jtag_info, const uint8_t *data, int size,\n\t\t\tint count, unsigned long start_address)\n{\n\tint retry_full_crc = 0;\n\tint retval;\n\tuint8_t opcode;\n\n\tLOG_DEBUG(\"Doing burst write, word size %d, word count %d,\"\n\t\t  \"start address 0x%08lx\", size, count, start_address);\n\n\t/* Select the appropriate opcode */\n\tswitch (jtag_info->or1k_jtag_module_selected) {\n\tcase DC_WISHBONE:\n\t\tif (size == 1)\n\t\t\topcode = DBG_WB_CMD_BWRITE8;\n\t\telse if (size == 2)\n\t\t\topcode = DBG_WB_CMD_BWRITE16;\n\t\telse if (size == 4)\n\t\t\topcode = DBG_WB_CMD_BWRITE32;\n\t\telse {\n\t\t\tLOG_DEBUG(\"Tried WB burst write with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_WB_CMD_BWRITE32;\n\t\t}\n\t\tbreak;\n\tcase DC_CPU0:\n\t\tif (size == 4)\n\t\t\topcode = DBG_CPU0_CMD_BWRITE32;\n\t\telse {\n\t\t\tLOG_DEBUG(\"Tried CPU0 burst write with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_CPU0_CMD_BWRITE32;\n\t\t}\n\t\tbreak;\n\tcase DC_CPU1:\n\t\tif (size == 4)\n\t\t\topcode = DBG_CPU1_CMD_BWRITE32;\n\t\telse {\n\t\t\tLOG_DEBUG(\"Tried CPU1 burst write with invalid word size (%d),\"\n\t\t\t\t  \"defaulting to 4-byte words\", size);\n\t\t\topcode = DBG_CPU0_CMD_BWRITE32;\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tLOG_ERROR(\"Illegal debug chain selected (%i) while doing burst write\",\n\t\t\t  jtag_info->or1k_jtag_module_selected);\n\t\treturn ERROR_FAIL;\n\t}\n\nretry_full_write:\n\n\t/* Send the BURST WRITE command, returns TAP to idle state */\n\tretval = adbg_burst_command(jtag_info, opcode, start_address, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct scan_field field[3];\n\n\t/* Write a start bit so it knows when to start counting */\n\tuint8_t value = 1;\n\tfield[0].num_bits = 1;\n\tfield[0].out_value = &value;\n\tfield[0].in_value = NULL;\n\n\tuint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data,\n\t\t\tcount * size);\n\n\tfield[1].num_bits = count * size * 8;\n\tfield[1].out_value = data;\n\tfield[1].in_value = NULL;\n\n\tfield[2].num_bits = 32;\n\tfield[2].out_value = (uint8_t *)&crc_calc;\n\tfield[2].in_value = NULL;\n\n\tjtag_add_dr_scan(jtag_info->tap, 3, field, TAP_DRSHIFT);\n\n\t/* Read the 'CRC match' bit, and go to idle */\n\tfield[0].num_bits = 1;\n\tfield[0].out_value = NULL;\n\tfield[0].in_value = &value;\n\tjtag_add_dr_scan(jtag_info->tap, 1, field, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (!value) {\n\t\tLOG_WARNING(\"CRC ERROR! match bit after write is %\" PRIi8 \" (computed CRC 0x%08\" PRIx32 \")\", value, crc_calc);\n\t\tif (retry_full_crc++ < MAX_WRITE_CRC_RETRY)\n\t\t\tgoto retry_full_write;\n\t\telse\n\t\t\treturn ERROR_FAIL;\n\t} else\n\t\tLOG_DEBUG(\"CRC OK!\\n\");\n\n\t/* Now, read the error register, and retry/recompute as necessary */\n\tif (jtag_info->or1k_jtag_module_selected == DC_WISHBONE &&\n\t    !(or1k_du_adv.options & ADBG_USE_HISPEED)) {\n\t\tuint32_t addr;\n\t\tint bus_error_retries = 0;\n\t\tuint32_t err_data[2] = {0, 0};\n\n\t\t/* First, just get 1 bit...read address only if necessary */\n\t\tretval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 1);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* Then we have a problem */\n\t\tif (err_data[0] & 0x1) {\n\n\t\t\tretval = adbg_ctrl_read(jtag_info, DBG_WB_REG_ERROR, err_data, 33);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\taddr = (err_data[0] >> 1) | (err_data[1] << 31);\n\t\t\tLOG_WARNING(\"WB bus error during burst write, address 0x%08\" PRIx32 \", retrying!\", addr);\n\n\t\t\tbus_error_retries++;\n\t\t\tif (bus_error_retries > MAX_BUS_ERRORS) {\n\t\t\t\tLOG_ERROR(\"Max WB bus errors reached during burst read\");\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\t/* Don't call retry_do(), a JTAG reset won't help a WB bus error */\n\t\t\t/* Write 1 bit, to reset the error register */\n\t\t\terr_data[0] = 1;\n\t\t\tretval = adbg_ctrl_write(jtag_info, DBG_WB_REG_ERROR, err_data, 1);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tgoto retry_full_write;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Currently hard set in functions to 32-bits */\nstatic int or1k_adv_jtag_read_cpu(struct or1k_jtag *jtag_info,\n\t\tuint32_t addr, int count, uint32_t *value)\n{\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn adbg_wb_burst_read(jtag_info, 4, count, addr, (uint8_t *)value);\n}\n\nstatic int or1k_adv_jtag_write_cpu(struct or1k_jtag *jtag_info,\n\t\tuint32_t addr, int count, const uint32_t *value)\n{\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn adbg_wb_burst_write(jtag_info, (uint8_t *)value, 4, count, addr);\n}\n\nstatic int or1k_adv_cpu_stall(struct or1k_jtag *jtag_info, int action)\n{\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t cpu_cr;\n\tretval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (action == CPU_STALL)\n\t\tcpu_cr |= DBG_CPU_CR_STALL;\n\telse\n\t\tcpu_cr &= ~DBG_CPU_CR_STALL;\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn adbg_ctrl_write(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2);\n}\n\nstatic int or1k_adv_is_cpu_running(struct or1k_jtag *jtag_info, int *running)\n{\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tint current = jtag_info->or1k_jtag_module_selected;\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t cpu_cr = 0;\n\tretval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (cpu_cr & DBG_CPU_CR_STALL)\n\t\t*running = 0;\n\telse\n\t\t*running = 1;\n\n\tif (current != DC_NONE) {\n\t\tretval = adbg_select_module(jtag_info, current);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_adv_cpu_reset(struct or1k_jtag *jtag_info, int action)\n{\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t cpu_cr;\n\tretval = adbg_ctrl_read(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (action == CPU_RESET)\n\t\tcpu_cr |= DBG_CPU_CR_RESET;\n\telse\n\t\tcpu_cr &= ~DBG_CPU_CR_RESET;\n\n\tretval = adbg_select_module(jtag_info, DC_CPU0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn adbg_ctrl_write(jtag_info, DBG_CPU0_REG_STATUS, &cpu_cr, 2);\n}\n\nstatic int or1k_adv_jtag_read_memory(struct or1k_jtag *jtag_info,\n\t\t\t    uint32_t addr, uint32_t size, int count, uint8_t *buffer)\n{\n\tLOG_DEBUG(\"Reading WB%\" PRIu32 \" at 0x%08\" PRIx32, size * 8, addr);\n\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_WISHBONE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint block_count_left = count;\n\tuint32_t block_count_address = addr;\n\tuint8_t *block_count_buffer = buffer;\n\n\twhile (block_count_left) {\n\n\t\tint blocks_this_round = (block_count_left > MAX_BURST_SIZE) ?\n\t\t\tMAX_BURST_SIZE : block_count_left;\n\n\t\tretval = adbg_wb_burst_read(jtag_info, size, blocks_this_round,\n\t\t\t\t\t    block_count_address, block_count_buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tblock_count_left -= blocks_this_round;\n\t\tblock_count_address += size * MAX_BURST_SIZE;\n\t\tblock_count_buffer += size * MAX_BURST_SIZE;\n\t}\n\n\t/* The adv_debug_if always return words and half words in\n\t * little-endian order no matter what the target endian is.\n\t * So if the target endian is big, change the order.\n\t */\n\n\tstruct target *target = jtag_info->target;\n\tif ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) {\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\tbuf_bswap32(buffer, buffer, size * count);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbuf_bswap16(buffer, buffer, size * count);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int or1k_adv_jtag_write_memory(struct or1k_jtag *jtag_info,\n\t\t\t     uint32_t addr, uint32_t size, int count, const uint8_t *buffer)\n{\n\tLOG_DEBUG(\"Writing WB%\" PRIu32 \" at 0x%08\" PRIx32, size * 8, addr);\n\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited) {\n\t\tretval = or1k_adv_jtag_init(jtag_info);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = adbg_select_module(jtag_info, DC_WISHBONE);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* The adv_debug_if wants words and half words in little-endian\n\t * order no matter what the target endian is. So if the target\n\t * endian is big, change the order.\n\t */\n\n\tvoid *t = NULL;\n\tstruct target *target = jtag_info->target;\n\tif ((target->endianness == TARGET_BIG_ENDIAN) && (size != 1)) {\n\t\tt = calloc(count * size, sizeof(uint8_t));\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\tbuf_bswap32(t, buffer, size * count);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbuf_bswap16(t, buffer, size * count);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfree(t);\n\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t}\n\t\tbuffer = t;\n\t}\n\n\tint block_count_left = count;\n\tuint32_t block_count_address = addr;\n\tuint8_t *block_count_buffer = (uint8_t *)buffer;\n\n\twhile (block_count_left) {\n\n\t\tint blocks_this_round = (block_count_left > MAX_BURST_SIZE) ?\n\t\t\tMAX_BURST_SIZE : block_count_left;\n\n\t\tretval = adbg_wb_burst_write(jtag_info, block_count_buffer,\n\t\t\t\t\t     size, blocks_this_round,\n\t\t\t\t\t     block_count_address);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(t);\n\t\t\treturn retval;\n\t\t}\n\n\t\tblock_count_left -= blocks_this_round;\n\t\tblock_count_address += size * MAX_BURST_SIZE;\n\t\tblock_count_buffer += size * MAX_BURST_SIZE;\n\t}\n\n\tfree(t);\n\treturn ERROR_OK;\n}\n\nint or1k_adv_jtag_jsp_xfer(struct or1k_jtag *jtag_info,\n\t\t\t\t  int *out_len, unsigned char *out_buffer,\n\t\t\t\t  int *in_len, unsigned char *in_buffer)\n{\n\tLOG_DEBUG(\"JSP transfer\");\n\n\tint retval;\n\tif (!jtag_info->or1k_jtag_inited)\n\t\treturn ERROR_OK;\n\n\tretval = adbg_select_module(jtag_info, DC_JSP);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* return nb char xmit */\n\tint xmitsize;\n\tif (*out_len > 8)\n\t\txmitsize = 8;\n\telse\n\t\txmitsize = *out_len;\n\n\tuint8_t out_data[10];\n\tuint8_t in_data[10];\n\tstruct scan_field field;\n\tint startbit, stopbit, wrapbit;\n\n\tmemset(out_data, 0, 10);\n\n\tif (or1k_du_adv.options & ENABLE_JSP_MULTI) {\n\n\t\tstartbit = 1;\n\t\twrapbit = (xmitsize >> 3) & 0x1;\n\t\tout_data[0] = (xmitsize << 5) | 0x1;  /* set the start bit */\n\n\t\tint i;\n\t\t/* don't copy off the end of the input array */\n\t\tfor (i = 0; i < xmitsize; i++) {\n\t\t\tout_data[i + 1] = (out_buffer[i] << 1) | wrapbit;\n\t\t\twrapbit = (out_buffer[i] >> 7) & 0x1;\n\t\t}\n\n\t\tif (i < 8)\n\t\t\tout_data[i + 1] = wrapbit;\n\t\telse\n\t\t\tout_data[9] = wrapbit;\n\n\t\t/* If the last data bit is a '1', then we need to append a '0' so the top-level module\n\t\t * won't treat the burst as a 'module select' command.\n\t\t */\n\t\tstopbit = !!(out_data[9] & 0x01);\n\n\t} else {\n\t\tstartbit = 0;\n\t\t/* First byte out has write count in upper nibble */\n\t\tout_data[0] = 0x0 | (xmitsize << 4);\n\t\tif (xmitsize > 0)\n\t\t\tmemcpy(&out_data[1], out_buffer, xmitsize);\n\n\t\t/* If the last data bit is a '1', then we need to append a '0' so the top-level module\n\t\t * won't treat the burst as a 'module select' command.\n\t\t */\n\t\tstopbit = !!(out_data[8] & 0x80);\n\t}\n\n\tfield.num_bits = 72 + startbit + stopbit;\n\tfield.out_value = out_data;\n\tfield.in_value = in_data;\n\n\tjtag_add_dr_scan(jtag_info->tap, 1, &field, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* bytes available is in the upper nibble */\n\t*in_len = (in_data[0] >> 4) & 0xF;\n\tmemcpy(in_buffer, &in_data[1], *in_len);\n\n\tint bytes_free = in_data[0] & 0x0F;\n\t*out_len = (bytes_free < xmitsize) ? bytes_free : xmitsize;\n\n\treturn ERROR_OK;\n}\n\nstatic struct or1k_du or1k_du_adv = {\n\t.name                     = \"adv\",\n\t.options                  = NO_OPTION,\n\t.or1k_jtag_init           = or1k_adv_jtag_init,\n\n\t.or1k_is_cpu_running      = or1k_adv_is_cpu_running,\n\t.or1k_cpu_stall           = or1k_adv_cpu_stall,\n\t.or1k_cpu_reset           = or1k_adv_cpu_reset,\n\n\t.or1k_jtag_read_cpu       = or1k_adv_jtag_read_cpu,\n\t.or1k_jtag_write_cpu      = or1k_adv_jtag_write_cpu,\n\n\t.or1k_jtag_read_memory    = or1k_adv_jtag_read_memory,\n\t.or1k_jtag_write_memory   = or1k_adv_jtag_write_memory\n};\n\nint or1k_du_adv_register(void)\n{\n\tlist_add_tail(&or1k_du_adv.list, &du_list);\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_tap.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2012 by Franck Jullien                                  *\n *   elec4fun@gmail.com                                                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_OPENRISC_OR1K_TAP_H\n#define OPENOCD_TARGET_OPENRISC_OR1K_TAP_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/list.h>\n#include \"or1k.h\"\n\nint or1k_tap_vjtag_register(void);\nint or1k_tap_xilinx_bscan_register(void);\nint or1k_tap_mohor_register(void);\n\n/* Linear list over all available or1k taps */\nextern struct list_head tap_list;\n\nstruct or1k_tap_ip {\n\tstruct list_head list;\n\tint (*init)(struct or1k_jtag *jtag_info);\n\tconst char *name;\n};\n\n#endif /* OPENOCD_TARGET_OPENRISC_OR1K_TAP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_tap_mohor.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Franck Jullien                                  *\n *   elec4fun@gmail.com                                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n\n#include <jtag/jtag.h>\n\n#define OR1K_TAP_INST_DEBUG\t0x8\n\nstatic int or1k_tap_mohor_init(struct or1k_jtag *jtag_info)\n{\n\tLOG_DEBUG(\"Initialising OpenCores JTAG TAP\");\n\n\t/* Put TAP into state where it can talk to the debug interface\n\t * by shifting in correct value to IR.\n\t */\n\n\t/* Ensure TAP is reset - maybe not necessary*/\n\tjtag_add_tlr();\n\n\tstruct jtag_tap *tap = jtag_info->tap;\n\tstruct scan_field field;\n\tuint8_t ir_value = OR1K_TAP_INST_DEBUG;\n\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = &ir_value;\n\tfield.in_value = NULL;\n\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic struct or1k_tap_ip mohor_tap = {\n\t.name = \"mohor\",\n\t.init = or1k_tap_mohor_init,\n};\n\nint or1k_tap_mohor_register(void)\n{\n\tlist_add_tail(&mohor_tap.list, &tap_list);\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_tap_vjtag.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Franck Jullien                                  *\n *   elec4fun@gmail.com                                                    *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n\n#include <jtag/jtag.h>\n\n/* Contains constants relevant to the Altera Virtual JTAG\n * device, which are not included in the BSDL.\n * As of this writing, these are constant across every\n * device which supports virtual JTAG.\n */\n\n/* These are commands for the FPGA's IR. */\n#define ALTERA_CYCLONE_CMD_USER1\t0x0E\n#define ALTERA_CYCLONE_CMD_USER0\t0x0C\n\n/* These defines are for the virtual IR (not the FPGA's)\n * The virtual TAP was defined in hardware to match the OpenCores native\n * TAP in both IR size and DEBUG command.\n */\n#define ALT_VJTAG_IR_SIZE\t\t4\n#define ALT_VJTAG_CMD_DEBUG\t\t0x8\n\n/* SLD node ID. */\n#define JTAG_TO_AVALON_NODE_ID\t\t0x84\n#define VJTAG_NODE_ID\t\t\t0x08\n#define SIGNAL_TAP_NODE_ID\t\t0x00\n#define SERIAL_FLASH_LOADER_NODE_ID\t0x04\n\n#define VER(x)\t\t\t\t((x >> 27) & 0x1f)\n#define NB_NODES(x)\t\t\t((x >> 19) & 0xff)\n#define ID(x)\t\t\t\t((x >> 19) & 0xff)\n#define MANUF(x)\t\t\t((x >> 8)  & 0x7ff)\n#define M_WIDTH(x)\t\t\t((x >> 0)  & 0xff)\n#define INST_ID(x)\t\t\t((x >> 0)  & 0xff)\n\n/* tap instructions - Mohor JTAG TAP */\n#define OR1K_TAP_INST_IDCODE 0x2\n#define OR1K_TAP_INST_DEBUG 0x8\n\nstatic const char *id_to_string(unsigned char id)\n{\n\tswitch (id) {\n\tcase VJTAG_NODE_ID:\n\t\treturn \"Virtual JTAG\";\n\tcase JTAG_TO_AVALON_NODE_ID:\n\t\treturn \"JTAG to avalon bridge\";\n\tcase SIGNAL_TAP_NODE_ID:\n\t\treturn \"Signal TAP\";\n\tcase SERIAL_FLASH_LOADER_NODE_ID:\n\t\treturn \"Serial Flash Loader\";\n\t}\n\treturn \"unknown\";\n}\n\nstatic unsigned char guess_addr_width(unsigned char number_of_nodes)\n{\n\tunsigned char width = 0;\n\n\twhile (number_of_nodes) {\n\t\tnumber_of_nodes >>= 1;\n\t\twidth++;\n\t}\n\n\treturn width;\n}\n\nstatic int or1k_tap_vjtag_init(struct or1k_jtag *jtag_info)\n{\n\tLOG_DEBUG(\"Initialising Altera Virtual JTAG TAP\");\n\n\t/* Put TAP into state where it can talk to the debug interface\n\t * by shifting in correct value to IR.\n\t */\n\n\t/* Ensure TAP is reset - maybe not necessary*/\n\tjtag_add_tlr();\n\n\t/* You can use a custom JTAG controller to discover transactions\n\t * necessary to enumerate all Virtual JTAG megafunction instances\n\t * from your design at runtime. All SLD nodes and the virtual JTAG\n\t * registers that they contain are targeted by two Instruction Register\n\t * values, USER0 and USER1.\n\t *\n\t * The USER1 instruction targets the virtual IR of either the sld_hub\n\t * or a SLD node. That is,when the USER1 instruction is issued to\n\t * the device, the subsequent DR scans target a specific virtual\n\t * IR chain based on an address field contained within the DR scan.\n\t * The table below shows how the virtual IR, the DR target of the\n\t * USER1 instruction is interpreted.\n\t *\n\t * The VIR_VALUE in the table below is the virtual IR value for the\n\t * target SLD node. The width of this field is m bits in length,\n\t * where m is the length of the largest VIR for all of the SLD nodes\n\t * in the design. All SLD nodes with VIR lengths of fewer than m\n\t * bits must pad VIR_VALUE with zeros up to a length of m.\n\t *\n\t * -------------------------------+-------------------------------\n\t * m + n - 1                   m  |  m -1                       0\n\t * -------------------------------+-------------------------------\n\t *     ADDR [(n – 1)..0]          |     VIR_VALUE [(m – 1)..0]\n\t * -------------------------------+-------------------------------\n\t *\n\t * The ADDR bits act as address values to signal the active SLD node\n\t * that the virtual IR shift targets. ADDR is n bits in length, where\n\t * n bits must be long enough to encode all SLD nodes within the design,\n\t * as shown below.\n\t *\n\t * n = CEIL(log2(Number of SLD_nodes +1))\n\t *\n\t * The SLD hub is always 0 in the address map.\n\t *\n\t * Discovery and enumeration of the SLD instances within a design\n\t * requires interrogation of the sld_hub to determine the dimensions\n\t * of the USER1 DR (m and n) and associating each SLD instance, specifically\n\t * the Virtual JTAG megafunction instances, with an address value\n\t * contained within the ADDR bits of the USER1 DR.\n\t *\n\t * The SLD hub contains the HUB IP Configuration Register and SLD_NODE_INFO\n\t * register for each SLD node in the design. The HUB IP configuration register provides\n\t * information needed to determine the dimensions of the USER1 DR chain. The\n\t * SLD_NODE_INFO register is used to determine the address mapping for Virtual\n\t * JTAG instance in your design. This register set is shifted out by issuing the\n\t * HUB_INFO instruction. Both the ADDR bits for the SLD hub and the HUB_INFO\n\t * instruction is 0 × 0.\n\t * Because m and n are unknown at this point, the DR register\n\t * (ADDR bits + VIR_VALUE) must be filled with zeros. Shifting a sequence of 64 zeroes\n\t * into the USER1 DR is sufficient to cover the most conservative case for m and n.\n\t */\n\n\tuint8_t t[4] = { 0 };\n\tstruct scan_field field;\n\tstruct jtag_tap *tap = jtag_info->tap;\n\n\t/* Select VIR */\n\tbuf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1);\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = t;\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\t/* Select the SLD Hub */\n\tfield.num_bits = 64;\n\tfield.out_value = NULL;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\t/* HUB IP Configuration Register\n\t *\n\t * When the USER1 and HUB_INFO instruction sequence is issued, the\n\t * USER0 instruction must be applied to enable the target register\n\t * of the HUB_INFO instruction. The HUB IP configuration register\n\t * is shifted out using eight four-bit nibble scans of the DR register.\n\t * Each four-bit scan must pass through the UPDATE_DR state before\n\t * the next four-bit scan. The 8 scans are assembled into a 32-bit\n\t * value with the definitions shown in the table below.\n\t *\n\t * --------------------------------------------------------------------------------\n\t *  NIBBLE7 | NIBBLE6 | NIBBLE5 | NIBBLE4 | NIBBLE3 | NIBBLE2 | NIBBLE1 | NIBBLE0\n\t * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----\n\t *     |    |    |    |    |    |    |    |    |    |    |    |    |    |    |\n\t * ----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+-----\n\t * HUB IP version|         N         | ALTERA_MFG_ID (0x06E)  |     SUM (m, n)\n\t * --------------+-------------------+------------------------+--------------------\n\t */\n\n\t/* Select VDR */\n\tbuf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0);\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = t;\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint8_t nibble;\n\tuint32_t hub_info = 0;\n\n\tfor (int i = 0; i < 8; i++) {\n\t\tfield.num_bits = 4;\n\t\tfield.out_value = NULL;\n\t\tfield.in_value = &nibble;\n\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\thub_info = ((hub_info >> 4) | ((nibble & 0xf) << 28));\n\t}\n\n\tint nb_nodes = NB_NODES(hub_info);\n\tint m_width = M_WIDTH(hub_info);\n\n\tLOG_DEBUG(\"SLD HUB Configuration register\");\n\tLOG_DEBUG(\"------------------------------\");\n\tLOG_DEBUG(\"m_width         = %d\", m_width);\n\tLOG_DEBUG(\"manufacturer_id = 0x%02\" PRIx32, MANUF(hub_info));\n\tLOG_DEBUG(\"nb_of_node      = %d\", nb_nodes);\n\tLOG_DEBUG(\"version         = %\" PRIu32, VER(hub_info));\n\tLOG_DEBUG(\"VIR length      = %d\", guess_addr_width(nb_nodes) + m_width);\n\n\t/* Because the number of SLD nodes is now known, the Nodes on the hub can be\n\t * enumerated by repeating the 8 four-bit nibble scans, once for each Node,\n\t * to yield the SLD_NODE_INFO register of each Node. The DR nibble shifts\n\t * are a continuation of the HUB_INFO DR shift used to shift out the Hub IP\n\t * Configuration register.\n\t *\n\t * The order of the Nodes as they are shifted out determines the ADDR\n\t * values for the Nodes, beginning with, for the first Node SLD_NODE_INFO\n\t * shifted out, up to and including, for the last node on the hub. The\n\t * tables below show the SLD_NODE_INFO register and a their functional descriptions.\n\t *\n\t *  --------------+-----------+---------------+----------------\n\t *   31        27 | 26     19 | 18          8 | 7            0\n\t *  --------------+-----------+---------------+----------------\n\t *   Node Version |  NODE ID  |  NODE MFG_ID  |  NODE INST ID\n\t *\n\t */\n\n\tint vjtag_node_address = -1;\n\tint node_index;\n\tuint32_t node_info = 0;\n\tfor (node_index = 0; node_index < nb_nodes; node_index++) {\n\n\t\tfor (int i = 0; i < 8; i++) {\n\t\t\tfield.num_bits = 4;\n\t\t\tfield.out_value = NULL;\n\t\t\tfield.in_value = &nibble;\n\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\t\t\tretval = jtag_execute_queue();\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tnode_info = ((node_info >> 4) | ((nibble & 0xf) << 28));\n\t\t}\n\n\t\tLOG_DEBUG(\"Node info register\");\n\t\tLOG_DEBUG(\"--------------------\");\n\t\tLOG_DEBUG(\"instance_id     = %\" PRIu32, ID(node_info));\n\t\tLOG_DEBUG(\"manufacturer_id = 0x%02\" PRIx32, MANUF(node_info));\n\t\tLOG_DEBUG(\"node_id         = %\" PRIu32 \" (%s)\", ID(node_info),\n\t\t\t\t\t\t       id_to_string(ID(node_info)));\n\t\tLOG_DEBUG(\"version         = %\" PRIu32, VER(node_info));\n\n\t\tif (ID(node_info) == VJTAG_NODE_ID)\n\t\t\tvjtag_node_address = node_index + 1;\n\t}\n\n\tif (vjtag_node_address < 0) {\n\t\tLOG_ERROR(\"No VJTAG TAP instance found !\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Select VIR */\n\tbuf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER1);\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = t;\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\t/* Send the DEBUG command to the VJTAG IR */\n\tint dr_length = guess_addr_width(nb_nodes) + m_width;\n\tbuf_set_u32(t, 0, dr_length, (vjtag_node_address << m_width) | ALT_VJTAG_CMD_DEBUG);\n\tfield.num_bits = dr_length;\n\tfield.out_value = t;\n\tfield.in_value = NULL;\n\tjtag_add_dr_scan(tap, 1, &field, TAP_IDLE);\n\n\t/* Select the VJTAG DR */\n\tbuf_set_u32(t, 0, tap->ir_length, ALTERA_CYCLONE_CMD_USER0);\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = t;\n\tfield.in_value = NULL;\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic struct or1k_tap_ip vjtag_tap = {\n\t.name = \"vjtag\",\n\t.init = or1k_tap_vjtag_init,\n};\n\nint or1k_tap_vjtag_register(void)\n{\n\tlist_add_tail(&vjtag_tap.list, &tap_list);\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/openrisc/or1k_tap_xilinx_bscan.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2013 by Sergio Chico                                    *\n *   sergio.chico@gmail.com                                                *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"or1k_tap.h\"\n#include \"or1k.h\"\n\n#include <jtag/jtag.h>\n\n#define OR1K_XILINX_TAP_INST_USER1\t0x02\n\nstatic int or1k_tap_xilinx_bscan_init(struct or1k_jtag *jtag_info)\n{\n\tLOG_DEBUG(\"Initialising Xilinx Internal JTAG TAP\");\n\n\t/* Put TAP into state where it can talk to the debug interface\n\t * by shifting in correct value to IR.\n\t */\n\n\t/* Ensure TAP is reset - maybe not necessary*/\n\tjtag_add_tlr();\n\n\tstruct jtag_tap *tap = jtag_info->tap;\n\tstruct scan_field field;\n\tuint8_t ir_value = OR1K_XILINX_TAP_INST_USER1;\n\n\tfield.num_bits = tap->ir_length;\n\tfield.out_value = &ir_value;\n\tfield.in_value = NULL;\n\n\tjtag_add_ir_scan(tap, &field, TAP_IDLE);\n\n\treturn jtag_execute_queue();\n}\n\nstatic struct or1k_tap_ip xilinx_bscan_tap = {\n\t.name = \"xilinx_bscan\",\n\t.init = or1k_tap_xilinx_bscan_init,\n};\n\nint or1k_tap_xilinx_bscan_register(void)\n{\n\tlist_add_tail(&xilinx_bscan_tap.list, &tap_list);\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/quark_d20xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright(c) 2015-2016 Intel Corporation.\n *\n * Jessica Gomez (jessica.gomez.hernandez@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * Debugger for Intel Quark D20xx\n * The CPU TAP (Lakemont TAP) is used for software debug and the CLTAP is\n * used for SoC level operations.\n *\n * Reference document:\n * Intel Quark microcontroller D2000 Debug Operations (web search for doc num 333241)\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"breakpoints.h\"\n#include \"lakemont.h\"\n#include \"x86_32_common.h\"\n\nstatic int quark_d20xx_target_create(struct target *t, Jim_Interp *interp)\n{\n\tstruct x86_32_common *x86_32 = calloc(1, sizeof(struct x86_32_common));\n\tif (!x86_32) {\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tx86_32_common_init_arch_info(t, x86_32);\n\tlakemont_init_arch_info(t, x86_32);\n\tx86_32->core_type = LMT3_5;\n\treturn ERROR_OK;\n}\n\nstatic int quark_d20xx_init_target(struct command_context *cmd_ctx, struct target *t)\n{\n\treturn lakemont_init_target(cmd_ctx, t);\n}\n\nstatic int quark_d20xx_reset_deassert(struct target *t)\n{\n\tint retval;\n\n\t/* Can't detect if a warm reset happened while halted but we can make the\n\t * openocd and target state consistent here if in probe mode already\n\t */\n\tif (!check_not_halted(t)) {\n\t\tretval = lakemont_update_after_probemode_entry(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s core state update fail\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\t/* resume target if reset mode is run */\n\t\tif (!t->reset_halt) {\n\t\t\tretval = lakemont_resume(t, 1, 0, 0, 0);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s could not resume target\", __func__);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstruct target_type quark_d20xx_target = {\n\t.name = \"quark_d20xx\",\n\t.target_create = quark_d20xx_target_create,\n\t.init_target = quark_d20xx_init_target,\n\t/* lakemont probemode specific code */\n\t.poll = lakemont_poll,\n\t.arch_state = lakemont_arch_state,\n\t.halt = lakemont_halt,\n\t.resume = lakemont_resume,\n\t.step = lakemont_step,\n\t.assert_reset = lakemont_reset_assert,\n\t.deassert_reset = quark_d20xx_reset_deassert,\n\t/* common x86 code */\n\t.commands = x86_32_command_handlers,\n\t.get_gdb_reg_list = x86_32_get_gdb_reg_list,\n\t.read_memory = x86_32_common_read_memory,\n\t.write_memory = x86_32_common_write_memory,\n\t.add_breakpoint = x86_32_common_add_breakpoint,\n\t.remove_breakpoint = x86_32_common_remove_breakpoint,\n\t.add_watchpoint = x86_32_common_add_watchpoint,\n\t.remove_watchpoint = x86_32_common_remove_watchpoint,\n\t.virt2phys = x86_32_common_virt2phys,\n\t.read_phys_memory = x86_32_common_read_phys_mem,\n\t.write_phys_memory = x86_32_common_write_phys_mem,\n\t.mmu = x86_32_common_mmu,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/quark_x10xx.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright(c) 2013-2016 Intel Corporation.\n *\n * Adrian Burns (adrian.burns@intel.com)\n * Thomas Faust (thomas.faust@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n * Julien Carreno (julien.carreno@intel.com)\n * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * Debugger for Intel Quark SoC X1000\n * Intel Quark X10xx is the first product in the Quark family of SoCs.\n * It is an IA-32 (Pentium x86 ISA) compatible SoC. The core CPU in the\n * X10xx is codenamed Lakemont. Lakemont version 1 (LMT1) is used in X10xx.\n * The CPU TAP (Lakemont TAP) is used for software debug and the CLTAP is\n * used for SoC level operations.\n * Useful docs are here: https://communities.intel.com/community/makers/documentation\n * Intel Quark SoC X1000 OpenOCD/GDB/Eclipse App Note (web search for doc num 330015)\n * Intel Quark SoC X1000 Debug Operations User Guide (web search for doc num 329866)\n * Intel Quark SoC X1000 Datasheet (web search for doc num 329676)\n *\n * This file implements any Quark SoC specific features such as resetbreak (TODO)\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"lakemont.h\"\n#include \"x86_32_common.h\"\n\nstatic int quark_x10xx_target_create(struct target *t, Jim_Interp *interp)\n{\n\tstruct x86_32_common *x86_32 = calloc(1, sizeof(*x86_32));\n\n\tif (!x86_32)\n\t\treturn ERROR_FAIL;\n\n\tx86_32_common_init_arch_info(t, x86_32);\n\tlakemont_init_arch_info(t, x86_32);\n\tx86_32->core_type = LMT1;\n\n\treturn ERROR_OK;\n}\n\nstruct target_type quark_x10xx_target = {\n\t.name\t\t\t= \"quark_x10xx\",\n\n\t/* Quark X1000 SoC */\n\t.target_create\t\t= quark_x10xx_target_create,\n\n\t/* lakemont probemode specific code */\n\t.arch_state\t\t= lakemont_arch_state,\n\t.assert_reset\t\t= lakemont_reset_assert,\n\t.deassert_reset\t\t= lakemont_reset_deassert,\n\t.halt\t\t\t= lakemont_halt,\n\t.init_target\t\t= lakemont_init_target,\n\t.poll\t\t\t= lakemont_poll,\n\t.resume\t\t\t= lakemont_resume,\n\t.step\t\t\t= lakemont_step,\n\n\t/* common x86 code */\n\t.add_breakpoint\t\t= x86_32_common_add_breakpoint,\n\t.add_watchpoint\t\t= x86_32_common_add_watchpoint,\n\t.commands\t\t= x86_32_command_handlers,\n\t.get_gdb_reg_list\t= x86_32_get_gdb_reg_list,\n\t.mmu\t\t\t= x86_32_common_mmu,\n\t.read_memory\t\t= x86_32_common_read_memory,\n\t.read_phys_memory\t= x86_32_common_read_phys_mem,\n\t.remove_breakpoint\t= x86_32_common_remove_breakpoint,\n\t.remove_watchpoint\t= x86_32_common_remove_watchpoint,\n\t.virt2phys\t\t= x86_32_common_virt2phys,\n\t.write_memory\t\t= x86_32_common_write_memory,\n\t.write_phys_memory\t= x86_32_common_write_phys_mem,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/register.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"register.h\"\n#include <helper/log.h>\n\n/**\n * @file\n * Holds utilities to work with register caches.\n *\n * OpenOCD uses machine registers internally, and exposes them by name\n * to Tcl scripts.  Sets of related registers are grouped into caches.\n * For example, a CPU core will expose a set of registers, and there\n * may be separate registers associated with debug or trace modules.\n */\n\nstruct reg *register_get_by_number(struct reg_cache *first,\n\t\tuint32_t reg_num, bool search_all)\n{\n\tstruct reg_cache *cache = first;\n\n\twhile (cache) {\n\t\tfor (unsigned int i = 0; i < cache->num_regs; i++) {\n\t\t\tif (!cache->reg_list[i].exist)\n\t\t\t\tcontinue;\n\t\t\tif (cache->reg_list[i].number == reg_num)\n\t\t\t\treturn &(cache->reg_list[i]);\n\t\t}\n\n\t\tif (!search_all)\n\t\t\tbreak;\n\n\t\tcache = cache->next;\n\t}\n\n\treturn NULL;\n}\n\nstruct reg *register_get_by_name(struct reg_cache *first,\n\t\tconst char *name, bool search_all)\n{\n\tstruct reg_cache *cache = first;\n\n\twhile (cache) {\n\t\tfor (unsigned int i = 0; i < cache->num_regs; i++) {\n\t\t\tif (!cache->reg_list[i].exist)\n\t\t\t\tcontinue;\n\t\t\tif (strcmp(cache->reg_list[i].name, name) == 0)\n\t\t\t\treturn &(cache->reg_list[i]);\n\t\t}\n\n\t\tif (!search_all)\n\t\t\tbreak;\n\n\t\tcache = cache->next;\n\t}\n\n\treturn NULL;\n}\n\nstruct reg_cache **register_get_last_cache_p(struct reg_cache **first)\n{\n\tstruct reg_cache **cache_p = first;\n\n\tif (*cache_p)\n\t\twhile (*cache_p)\n\t\t\tcache_p = &((*cache_p)->next);\n\telse\n\t\treturn first;\n\n\treturn cache_p;\n}\n\nvoid register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache)\n{\n\twhile (*cache_p && *cache_p != cache)\n\t\tcache_p = &((*cache_p)->next);\n\tif (*cache_p)\n\t\t*cache_p = cache->next;\n}\n\n/** Marks the contents of the register cache as invalid (and clean). */\nvoid register_cache_invalidate(struct reg_cache *cache)\n{\n\tstruct reg *reg = cache->reg_list;\n\n\tfor (unsigned int n = cache->num_regs; n != 0; n--, reg++) {\n\t\tif (!reg->exist)\n\t\t\tcontinue;\n\t\treg->valid = false;\n\t\treg->dirty = false;\n\t}\n}\n\nstatic int register_get_dummy_core_reg(struct reg *reg)\n{\n\treturn ERROR_OK;\n}\n\nstatic int register_set_dummy_core_reg(struct reg *reg, uint8_t *buf)\n{\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type dummy_type = {\n\t.get = register_get_dummy_core_reg,\n\t.set = register_set_dummy_core_reg,\n};\n\nvoid register_init_dummy(struct reg *reg)\n{\n\treg->type = &dummy_type;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/register.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_REGISTER_H\n#define OPENOCD_TARGET_REGISTER_H\n\n#include \"helper/replacements.h\"\n#include \"helper/types.h\"\n\nstruct target;\n\nenum reg_type {\n\tREG_TYPE_BOOL,\n\tREG_TYPE_INT,\n\tREG_TYPE_INT8,\n\tREG_TYPE_INT16,\n\tREG_TYPE_INT32,\n\tREG_TYPE_INT64,\n\tREG_TYPE_INT128,\n\tREG_TYPE_UINT,\n\tREG_TYPE_UINT8,\n\tREG_TYPE_UINT16,\n\tREG_TYPE_UINT32,\n\tREG_TYPE_UINT64,\n\tREG_TYPE_UINT128,\n\tREG_TYPE_CODE_PTR,\n\tREG_TYPE_DATA_PTR,\n\tREG_TYPE_FLOAT,\n\tREG_TYPE_IEEE_SINGLE,\n\tREG_TYPE_IEEE_DOUBLE,\n\tREG_TYPE_ARCH_DEFINED,\n};\n\nstruct reg_feature {\n\tconst char *name;\n};\n\nstruct reg_data_type_vector {\n\tstruct reg_data_type *type;\n\tuint32_t count;\n};\n\nstruct reg_data_type_union_field {\n\tconst char *name;\n\tstruct reg_data_type *type;\n\tstruct reg_data_type_union_field *next;\n};\n\nstruct reg_data_type_union {\n\tstruct reg_data_type_union_field *fields;\n};\n\nstruct reg_data_type_bitfield {\n\tuint32_t start;\n\tuint32_t end;\n\tenum reg_type type;\n};\n\nstruct reg_data_type_struct_field {\n\tconst char *name;\n\tbool use_bitfields;\n\tunion {\n\t\tstruct reg_data_type_bitfield *bitfield;\n\t\tstruct reg_data_type *type;\n\t};\n\tstruct reg_data_type_struct_field *next;\n};\n\nstruct reg_data_type_struct {\n\tuint32_t size;\n\tstruct reg_data_type_struct_field *fields;\n};\n\nstruct reg_data_type_flags_field {\n\tconst char *name;\n\tstruct reg_data_type_bitfield *bitfield;\n\tstruct reg_data_type_flags_field *next;\n};\n\nstruct reg_data_type_flags {\n\tuint32_t size;\n\tstruct reg_data_type_flags_field *fields;\n};\n\nenum reg_data_type_class {\n\tREG_TYPE_CLASS_VECTOR,\n\tREG_TYPE_CLASS_UNION,\n\tREG_TYPE_CLASS_STRUCT,\n\tREG_TYPE_CLASS_FLAGS,\n};\n\nstruct reg_data_type {\n\tenum reg_type type;\n\tconst char *id;\n\tenum reg_data_type_class type_class;\n\tunion {\n\t\tstruct reg_data_type_vector *reg_type_vector;\n\t\tstruct reg_data_type_union *reg_type_union;\n\t\tstruct reg_data_type_struct *reg_type_struct;\n\t\tstruct reg_data_type_flags *reg_type_flags;\n\t};\n};\n\nstruct reg {\n\t/* Canonical name of the register. */\n\tconst char *name;\n\t/* Number that gdb uses to access this register. */\n\tuint32_t number;\n\t/* TODO. This should probably be const. */\n\tstruct reg_feature *feature;\n\t/* TODO: When true, the caller will save this register before running any algorithm. */\n\tbool caller_save;\n\t/* Pointer to place where the value is stored, in the format understood by\n\t * the binarybuffer.h functions. */\n\tuint8_t *value;\n\t/* The stored value needs to be written to the target. */\n\tbool dirty;\n\t/* When true, value is valid. */\n\tbool valid;\n\t/* When false, the register doesn't actually exist in the target. */\n\tbool exist;\n\t/* Hide the register from gdb and omit it in 'reg' cmd output */\n\tbool hidden;\n\t/* Size of the register in bits. */\n\tuint32_t size;\n\t/* Used for generating XML description of registers. Can be set to NULL for\n\t * targets that don't use that. */\n\tstruct reg_data_type *reg_data_type;\n\t/* Used for generating XML description of registers. Can be set to NULL for\n\t * targets that don't use that. */\n\tconst char *group;\n\t/* Pointer to architecture-specific info for this register. */\n\tvoid *arch_info;\n\tconst struct reg_arch_type *type;\n};\n\nstruct reg_cache {\n\tconst char *name;\n\tstruct reg_cache *next;\n\tstruct reg *reg_list;\n\tunsigned num_regs;\n};\n\nstruct reg_arch_type {\n\tint (*get)(struct reg *reg);\n\tint (*set)(struct reg *reg, uint8_t *buf);\n};\n\nstruct reg *register_get_by_number(struct reg_cache *first,\n\t\tuint32_t reg_num, bool search_all);\nstruct reg *register_get_by_name(struct reg_cache *first,\n\t\tconst char *name, bool search_all);\nstruct reg_cache **register_get_last_cache_p(struct reg_cache **first);\nvoid register_unlink_cache(struct reg_cache **cache_p, const struct reg_cache *cache);\nvoid register_cache_invalidate(struct reg_cache *cache);\n\nvoid register_init_dummy(struct reg *reg);\n\n#endif /* OPENOCD_TARGET_REGISTER_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libriscv.la\n%C%_libriscv_la_SOURCES = \\\n       %D%/asm.h \\\n       %D%/batch.h \\\n       %D%/debug_defines.h \\\n       %D%/encoding.h \\\n       %D%/gdb_regs.h \\\n       %D%/opcodes.h \\\n       %D%/program.h \\\n       %D%/riscv.h \\\n       %D%/batch.c \\\n       %D%/program.c \\\n       %D%/riscv-011.c \\\n       %D%/riscv-013.c \\\n       %D%/riscv.c \\\n       %D%/riscv_semihosting.c\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/asm.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef TARGET__RISCV__ASM_H\n#define TARGET__RISCV__ASM_H\n\n#include \"riscv.h\"\n\n/*** Version-independent functions that we don't want in the main address space. ***/\n\nstatic uint32_t load(const struct target *target, unsigned int rd,\n\t\tunsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t load(const struct target *target, unsigned int rd,\n\t\tunsigned int base, uint16_t offset)\n{\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\treturn lw(rd, base, offset);\n\t\tcase 64:\n\t\t\treturn ld(rd, base, offset);\n\t}\n\tassert(0);\n\treturn 0; /* Silence -Werror=return-type */\n}\n\nstatic uint32_t store(const struct target *target, unsigned int src,\n\t\tunsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t store(const struct target *target, unsigned int src,\n\t\tunsigned int base, uint16_t offset)\n{\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\treturn sw(src, base, offset);\n\t\tcase 64:\n\t\t\treturn sd(src, base, offset);\n\t}\n\tassert(0);\n\treturn 0; /* Silence -Werror=return-type */\n}\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/batch.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"batch.h\"\n#include \"debug_defines.h\"\n#include \"riscv.h\"\n\n#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))\n#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))\n\n#define DTM_DMI_MAX_ADDRESS_LENGTH\t((1<<DTM_DTMCS_ABITS_LENGTH)-1)\n#define DMI_SCAN_MAX_BIT_LENGTH (DTM_DMI_MAX_ADDRESS_LENGTH + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH)\n#define DMI_SCAN_BUF_SIZE (DIV_ROUND_UP(DMI_SCAN_MAX_BIT_LENGTH, 8))\n\nstatic void dump_field(int idle, const struct scan_field *field);\n\nstruct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans, size_t idle)\n{\n\tscans += 4;\n\tstruct riscv_batch *out = calloc(1, sizeof(*out));\n\tif (!out)\n\t\tgoto error0;\n\tout->target = target;\n\tout->allocated_scans = scans;\n\tout->idle_count = idle;\n\tout->data_out = malloc(sizeof(*out->data_out) * (scans) * DMI_SCAN_BUF_SIZE);\n\tif (!out->data_out) {\n\t\tLOG_ERROR(\"Failed to allocate data_out in RISC-V batch.\");\n\t\tgoto error1;\n\t};\n\tout->data_in = malloc(sizeof(*out->data_in) * (scans) * DMI_SCAN_BUF_SIZE);\n\tif (!out->data_in) {\n\t\tLOG_ERROR(\"Failed to allocate data_in in RISC-V batch.\");\n\t\tgoto error2;\n\t}\n\tout->fields = malloc(sizeof(*out->fields) * (scans));\n\tif (!out->fields) {\n\t\tLOG_ERROR(\"Failed to allocate fields in RISC-V batch.\");\n\t\tgoto error3;\n\t}\n\tif (bscan_tunnel_ir_width != 0) {\n\t\tout->bscan_ctxt = malloc(sizeof(*out->bscan_ctxt) * (scans));\n\t\tif (!out->bscan_ctxt) {\n\t\t\tLOG_ERROR(\"Failed to allocate bscan_ctxt in RISC-V batch.\");\n\t\t\tgoto error4;\n\t\t}\n\t}\n\tout->last_scan = RISCV_SCAN_TYPE_INVALID;\n\tout->read_keys = malloc(sizeof(*out->read_keys) * (scans));\n\tif (!out->read_keys) {\n\t\tLOG_ERROR(\"Failed to allocate read_keys in RISC-V batch.\");\n\t\tgoto error5;\n\t}\n\treturn out;\n\nerror5:\n\tfree(out->bscan_ctxt);\nerror4:\n\tfree(out->fields);\nerror3:\n\tfree(out->data_in);\nerror2:\n\tfree(out->data_out);\nerror1:\n\tfree(out);\nerror0:\n\treturn NULL;\n}\n\nvoid riscv_batch_free(struct riscv_batch *batch)\n{\n\tfree(batch->data_in);\n\tfree(batch->data_out);\n\tfree(batch->fields);\n\tfree(batch->bscan_ctxt);\n\tfree(batch->read_keys);\n\tfree(batch);\n}\n\nbool riscv_batch_full(struct riscv_batch *batch)\n{\n\treturn batch->used_scans > (batch->allocated_scans - 4);\n}\n\nint riscv_batch_run(struct riscv_batch *batch)\n{\n\tif (batch->used_scans == 0) {\n\t\tLOG_DEBUG(\"Ignoring empty batch.\");\n\t\treturn ERROR_OK;\n\t}\n\n\triscv_batch_add_nop(batch);\n\n\tfor (size_t i = 0; i < batch->used_scans; ++i) {\n\t\tif (bscan_tunnel_ir_width != 0)\n\t\t\triscv_add_bscan_tunneled_scan(batch->target, batch->fields+i, batch->bscan_ctxt+i);\n\t\telse\n\t\t\tjtag_add_dr_scan(batch->target->tap, 1, batch->fields + i, TAP_IDLE);\n\n\t\tif (batch->idle_count > 0)\n\t\t\tjtag_add_runtest(batch->idle_count, TAP_IDLE);\n\t}\n\n\tkeep_alive();\n\n\tif (jtag_execute_queue() != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to execute JTAG queue\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tkeep_alive();\n\n\tif (bscan_tunnel_ir_width != 0) {\n\t\t/* need to right-shift \"in\" by one bit, because of clock skew between BSCAN TAP and DM TAP */\n\t\tfor (size_t i = 0; i < batch->used_scans; ++i)\n\t\t\tbuffer_shr((batch->fields + i)->in_value, DMI_SCAN_BUF_SIZE, 1);\n\t}\n\n\tfor (size_t i = 0; i < batch->used_scans; ++i)\n\t\tdump_field(batch->idle_count, batch->fields + i);\n\n\treturn ERROR_OK;\n}\n\nvoid riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned address, uint64_t data)\n{\n\tassert(batch->used_scans < batch->allocated_scans);\n\tstruct scan_field *field = batch->fields + batch->used_scans;\n\tfield->num_bits = riscv_dmi_write_u64_bits(batch->target);\n\tfield->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\tfield->in_value  = (void *)(batch->data_in  + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\triscv_fill_dmi_write_u64(batch->target, (char *)field->out_value, address, data);\n\triscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);\n\tbatch->last_scan = RISCV_SCAN_TYPE_WRITE;\n\tbatch->used_scans++;\n}\n\nsize_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned address)\n{\n\tassert(batch->used_scans < batch->allocated_scans);\n\tstruct scan_field *field = batch->fields + batch->used_scans;\n\tfield->num_bits = riscv_dmi_write_u64_bits(batch->target);\n\tfield->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\tfield->in_value  = (void *)(batch->data_in  + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\triscv_fill_dmi_read_u64(batch->target, (char *)field->out_value, address);\n\triscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);\n\tbatch->last_scan = RISCV_SCAN_TYPE_READ;\n\tbatch->used_scans++;\n\n\tbatch->read_keys[batch->read_keys_used] = batch->used_scans;\n\treturn batch->read_keys_used++;\n}\n\nunsigned riscv_batch_get_dmi_read_op(struct riscv_batch *batch, size_t key)\n{\n\tassert(key < batch->read_keys_used);\n\tsize_t index = batch->read_keys[key];\n\tassert(index <= batch->used_scans);\n\tuint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index;\n\t/* extract \"op\" field from the DMI read result */\n\treturn (unsigned)buf_get_u32(base, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);\n}\n\nuint32_t riscv_batch_get_dmi_read_data(struct riscv_batch *batch, size_t key)\n{\n\tassert(key < batch->read_keys_used);\n\tsize_t index = batch->read_keys[key];\n\tassert(index <= batch->used_scans);\n\tuint8_t *base = batch->data_in + DMI_SCAN_BUF_SIZE * index;\n\t/* extract \"data\" field from the DMI read result */\n\treturn buf_get_u32(base, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);\n}\n\nvoid riscv_batch_add_nop(struct riscv_batch *batch)\n{\n\tassert(batch->used_scans < batch->allocated_scans);\n\tstruct scan_field *field = batch->fields + batch->used_scans;\n\tfield->num_bits = riscv_dmi_write_u64_bits(batch->target);\n\tfield->out_value = (void *)(batch->data_out + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\tfield->in_value  = (void *)(batch->data_in  + batch->used_scans * DMI_SCAN_BUF_SIZE);\n\triscv_fill_dmi_nop_u64(batch->target, (char *)field->out_value);\n\triscv_fill_dmi_nop_u64(batch->target, (char *)field->in_value);\n\tbatch->last_scan = RISCV_SCAN_TYPE_NOP;\n\tbatch->used_scans++;\n}\n\nvoid dump_field(int idle, const struct scan_field *field)\n{\n\tstatic const char * const op_string[] = {\"-\", \"r\", \"w\", \"?\"};\n\tstatic const char * const status_string[] = {\"+\", \"?\", \"F\", \"b\"};\n\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn;\n\n\tassert(field->out_value);\n\tuint64_t out = buf_get_u64(field->out_value, 0, field->num_bits);\n\tunsigned int out_op = get_field(out, DTM_DMI_OP);\n\tunsigned int out_data = get_field(out, DTM_DMI_DATA);\n\tunsigned int out_address = out >> DTM_DMI_ADDRESS_OFFSET;\n\n\tif (field->in_value) {\n\t\tuint64_t in = buf_get_u64(field->in_value, 0, field->num_bits);\n\t\tunsigned int in_op = get_field(in, DTM_DMI_OP);\n\t\tunsigned int in_data = get_field(in, DTM_DMI_DATA);\n\t\tunsigned int in_address = in >> DTM_DMI_ADDRESS_OFFSET;\n\n\t\tlog_printf_lf(LOG_LVL_DEBUG,\n\t\t\t\t__FILE__, __LINE__, __PRETTY_FUNCTION__,\n\t\t\t\t\"%db %s %08x @%02x -> %s %08x @%02x; %di\",\n\t\t\t\tfield->num_bits, op_string[out_op], out_data, out_address,\n\t\t\t\tstatus_string[in_op], in_data, in_address, idle);\n\t} else {\n\t\tlog_printf_lf(LOG_LVL_DEBUG,\n\t\t\t\t__FILE__, __LINE__, __PRETTY_FUNCTION__, \"%db %s %08x @%02x -> ?; %di\",\n\t\t\t\tfield->num_bits, op_string[out_op], out_data, out_address, idle);\n\t}\n}\n\nsize_t riscv_batch_available_scans(struct riscv_batch *batch)\n{\n\treturn batch->allocated_scans - batch->used_scans - 4;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/batch.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef TARGET__RISCV__SCANS_H\n#define TARGET__RISCV__SCANS_H\n\n#include \"target/target.h\"\n#include \"jtag/jtag.h\"\n#include \"riscv.h\"\n\nenum riscv_scan_type {\n\tRISCV_SCAN_TYPE_INVALID,\n\tRISCV_SCAN_TYPE_NOP,\n\tRISCV_SCAN_TYPE_READ,\n\tRISCV_SCAN_TYPE_WRITE,\n};\n\n/* A batch of multiple JTAG scans, which are grouped together to avoid the\n * overhead of some JTAG adapters when sending single commands.  This is\n * designed to support block copies, as that's what we actually need to go\n * fast. */\nstruct riscv_batch {\n\tstruct target *target;\n\n\tsize_t allocated_scans;\n\tsize_t used_scans;\n\n\tsize_t idle_count;\n\n\tuint8_t *data_out;\n\tuint8_t *data_in;\n\tstruct scan_field *fields;\n\n\t/* If in BSCAN mode, this field will be allocated (one per scan),\n\t   and utilized to tunnel all the scans in the batch.  If not in\n\t   BSCAN mode, this field is unallocated and stays NULL */\n\triscv_bscan_tunneled_scan_context_t *bscan_ctxt;\n\n\t/* In JTAG we scan out the previous value's output when performing a\n\t * scan.  This is a pain for users, so we just provide them the\n\t * illusion of not having to do this by eliding all but the last NOP.\n\t * */\n\tenum riscv_scan_type last_scan;\n\n\t/* The read keys. */\n\tsize_t *read_keys;\n\tsize_t read_keys_used;\n};\n\n/* Allocates (or frees) a new scan set.  \"scans\" is the maximum number of JTAG\n * scans that can be issued to this object, and idle is the number of JTAG idle\n * cycles between every real scan. */\nstruct riscv_batch *riscv_batch_alloc(struct target *target, size_t scans, size_t idle);\nvoid riscv_batch_free(struct riscv_batch *batch);\n\n/* Checks to see if this batch is full. */\nbool riscv_batch_full(struct riscv_batch *batch);\n\n/* Executes this scan batch. */\nint riscv_batch_run(struct riscv_batch *batch);\n\n/* Adds a DMI write to this batch. */\nvoid riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned address, uint64_t data);\n\n/* DMI reads must be handled in two parts: the first one schedules a read and\n * provides a key, the second one actually obtains the result of the read -\n * status (op) and the actual data. */\nsize_t riscv_batch_add_dmi_read(struct riscv_batch *batch, unsigned address);\nunsigned riscv_batch_get_dmi_read_op(struct riscv_batch *batch, size_t key);\nuint32_t riscv_batch_get_dmi_read_data(struct riscv_batch *batch, size_t key);\n\n/* Scans in a NOP. */\nvoid riscv_batch_add_nop(struct riscv_batch *batch);\n\n/* Returns the number of available scans. */\nsize_t riscv_batch_available_scans(struct riscv_batch *batch);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/debug_defines.h",
    "content": "/*\n * This file is auto-generated by running 'make debug_defines.h' in\n * https://github.com/riscv/riscv-debug-spec/ (d749752)\n */\n\n#define DTM_IDCODE                          0x01\n/*\n * Identifies the release version of this part.\n */\n#define DTM_IDCODE_VERSION_OFFSET           0x1c\n#define DTM_IDCODE_VERSION_LENGTH           4\n#define DTM_IDCODE_VERSION                  0xf0000000U\n/*\n * Identifies the designer's part number of this part.\n */\n#define DTM_IDCODE_PARTNUMBER_OFFSET        0xc\n#define DTM_IDCODE_PARTNUMBER_LENGTH        0x10\n#define DTM_IDCODE_PARTNUMBER               0xffff000\n/*\n * Identifies the designer/manufacturer of this part. Bits 6:0 must be\n * bits 6:0 of the designer/manufacturer's Identification Code as\n * assigned by JEDEC Standard JEP106. Bits 10:7 contain the modulo-16\n * count of the number of continuation characters (0x7f) in that same\n * Identification Code.\n */\n#define DTM_IDCODE_MANUFID_OFFSET           1\n#define DTM_IDCODE_MANUFID_LENGTH           0xb\n#define DTM_IDCODE_MANUFID                  0xffe\n#define DTM_IDCODE_1_OFFSET                 0\n#define DTM_IDCODE_1_LENGTH                 1\n#define DTM_IDCODE_1                        1\n#define DTM_DTMCS                           0x10\n/*\n * Writing 1 to this bit does a hard reset of the DTM,\n * causing the DTM to forget about any outstanding DMI transactions, and\n * returning all registers and internal state to their reset value.\n * In general this should only be used when the Debugger has\n * reason to expect that the outstanding DMI transaction will never\n * complete (e.g. a reset condition caused an inflight DMI transaction to\n * be cancelled).\n */\n#define DTM_DTMCS_DMIHARDRESET_OFFSET       0x11\n#define DTM_DTMCS_DMIHARDRESET_LENGTH       1\n#define DTM_DTMCS_DMIHARDRESET              0x20000\n/*\n * Writing 1 to this bit clears the sticky error state, but does\n * not affect outstanding DMI transactions.\n */\n#define DTM_DTMCS_DMIRESET_OFFSET           0x10\n#define DTM_DTMCS_DMIRESET_LENGTH           1\n#define DTM_DTMCS_DMIRESET                  0x10000\n/*\n * This is a hint to the debugger of the minimum number of\n * cycles a debugger should spend in\n * Run-Test/Idle after every DMI scan to avoid a `busy'\n * return code (\\FdtmDtmcsDmistat of 3). A debugger must still\n * check \\FdtmDtmcsDmistat when necessary.\n *\n * 0: It is not necessary to enter Run-Test/Idle at all.\n *\n * 1: Enter Run-Test/Idle and leave it immediately.\n *\n * 2: Enter Run-Test/Idle and stay there for 1 cycle before leaving.\n *\n * And so on.\n */\n#define DTM_DTMCS_IDLE_OFFSET               0xc\n#define DTM_DTMCS_IDLE_LENGTH               3\n#define DTM_DTMCS_IDLE                      0x7000\n/*\n * Read-only alias of \\FdtmDmiOp.\n */\n#define DTM_DTMCS_DMISTAT_OFFSET            0xa\n#define DTM_DTMCS_DMISTAT_LENGTH            2\n#define DTM_DTMCS_DMISTAT                   0xc00\n/*\n * The size of \\FdmSbaddressZeroAddress in \\RdtmDmi.\n */\n#define DTM_DTMCS_ABITS_OFFSET              4\n#define DTM_DTMCS_ABITS_LENGTH              6\n#define DTM_DTMCS_ABITS                     0x3f0\n#define DTM_DTMCS_VERSION_OFFSET            0\n#define DTM_DTMCS_VERSION_LENGTH            4\n#define DTM_DTMCS_VERSION                   0xf\n/*\n * 0.11: Version described in spec version 0.11.\n */\n#define DTM_DTMCS_VERSION_0_11              0\n/*\n * 1.0: Version described in spec versions 0.13 and 1.0.\n */\n#define DTM_DTMCS_VERSION_1_0               1\n/*\n * custom: Version not described in any available version of this spec.\n */\n#define DTM_DTMCS_VERSION_CUSTOM            15\n#define DTM_DMI                             0x11\n/*\n * Address used for DMI access. In Update-DR this value is used\n * to access the DM over the DMI.\n */\n#define DTM_DMI_ADDRESS_OFFSET              0x22\n#define DTM_DMI_ADDRESS_LENGTH(abits)       abits\n#define DTM_DMI_ADDRESS(abits)              ((0x400000000ULL * (1ULL<<abits)) + -0x400000000ULL)\n/*\n * The data to send to the DM over the DMI during Update-DR, and\n * the data returned from the DM as a result of the previous operation.\n */\n#define DTM_DMI_DATA_OFFSET                 2\n#define DTM_DMI_DATA_LENGTH                 0x20\n#define DTM_DMI_DATA                        0x3fffffffcULL\n/*\n * When the debugger writes this field, it has the following meaning:\n */\n#define DTM_DMI_OP_OFFSET                   0\n#define DTM_DMI_OP_LENGTH                   2\n#define DTM_DMI_OP                          3\n/*\n * nop: Ignore \\FdmSbdataZeroData and \\FdmSbaddressZeroAddress.\n *\n * Don't send anything over the DMI during Update-DR.\n * This operation should never result in a busy or error response.\n * The address and data reported in the following Capture-DR\n * are undefined.\n */\n#define DTM_DMI_OP_NOP                      0\n/*\n * read: Read from \\FdmSbaddressZeroAddress.\n */\n#define DTM_DMI_OP_READ                     1\n/*\n * write: Write \\FdmSbdataZeroData to \\FdmSbaddressZeroAddress.\n */\n#define DTM_DMI_OP_WRITE                    2\n/*\n * reserved: Reserved.\n */\n/*\n * When the debugger reads this field, it means the following:\n */\n/*\n * success: The previous operation completed successfully.\n */\n#define DTM_DMI_OP_SUCCESS                  0\n/*\n * reserved: Reserved.\n */\n/*\n * failed: A previous operation failed.  The data scanned into \\RdtmDmi in\n * this access will be ignored.  This status is sticky and can be\n * cleared by writing \\FdtmDtmcsDmireset in \\RdtmDtmcs.\n *\n * This indicates that the DM itself responded with an error.\n * There are no specified cases in which the DM would\n * respond with an error, and DMI is not required to support\n * returning errors.\n */\n#define DTM_DMI_OP_FAILED                   2\n/*\n * busy: An operation was attempted while a DMI request is still in\n * progress. The data scanned into \\RdtmDmi in this access will be\n * ignored. This status is sticky and can be cleared by writing\n * \\FdtmDtmcsDmireset in \\RdtmDtmcs. If a debugger sees this status, it\n * needs to give the target more TCK edges between Update-DR and\n * Capture-DR. The simplest way to do that is to add extra transitions\n * in Run-Test/Idle.\n */\n#define DTM_DMI_OP_BUSY                     3\n#define CSR_DCSR                            0x7b0\n#define CSR_DCSR_DEBUGVER_OFFSET            0x1c\n#define CSR_DCSR_DEBUGVER_LENGTH            4\n#define CSR_DCSR_DEBUGVER                   0xf0000000U\n/*\n * none: There is no debug support.\n */\n#define CSR_DCSR_DEBUGVER_NONE              0\n/*\n * 1.0: Debug support exists as it is described in this document.\n */\n#define CSR_DCSR_DEBUGVER_1_0               4\n/*\n * custom: There is debug support, but it does not conform to any\n * available version of this spec.\n */\n#define CSR_DCSR_DEBUGVER_CUSTOM            15\n#define CSR_DCSR_EBREAKVS_OFFSET            0x11\n#define CSR_DCSR_EBREAKVS_LENGTH            1\n#define CSR_DCSR_EBREAKVS                   0x20000\n/*\n * exception: {\\tt ebreak} instructions in VS-mode behave as described in the\n * Privileged Spec.\n */\n#define CSR_DCSR_EBREAKVS_EXCEPTION         0\n/*\n * debug mode: {\\tt ebreak} instructions in VS-mode enter Debug Mode.\n */\n#define CSR_DCSR_EBREAKVS_DEBUG_MODE        1\n/*\n * This bit is hardwired to 0 if the hart does not support virtualization mode.\n */\n#define CSR_DCSR_EBREAKVU_OFFSET            0x10\n#define CSR_DCSR_EBREAKVU_LENGTH            1\n#define CSR_DCSR_EBREAKVU                   0x10000\n/*\n * exception: {\\tt ebreak} instructions in VU-mode behave as described in the\n * Privileged Spec.\n */\n#define CSR_DCSR_EBREAKVU_EXCEPTION         0\n/*\n * debug mode: {\\tt ebreak} instructions in VU-mode enter Debug Mode.\n */\n#define CSR_DCSR_EBREAKVU_DEBUG_MODE        1\n/*\n * This bit is hardwired to 0 if the hart does not support virtualization mode.\n */\n#define CSR_DCSR_EBREAKM_OFFSET             0xf\n#define CSR_DCSR_EBREAKM_LENGTH             1\n#define CSR_DCSR_EBREAKM                    0x8000\n/*\n * exception: {\\tt ebreak} instructions in M-mode behave as described in the\n * Privileged Spec.\n */\n#define CSR_DCSR_EBREAKM_EXCEPTION          0\n/*\n * debug mode: {\\tt ebreak} instructions in M-mode enter Debug Mode.\n */\n#define CSR_DCSR_EBREAKM_DEBUG_MODE         1\n#define CSR_DCSR_EBREAKS_OFFSET             0xd\n#define CSR_DCSR_EBREAKS_LENGTH             1\n#define CSR_DCSR_EBREAKS                    0x2000\n/*\n * exception: {\\tt ebreak} instructions in S-mode behave as described in the\n * Privileged Spec.\n */\n#define CSR_DCSR_EBREAKS_EXCEPTION          0\n/*\n * debug mode: {\\tt ebreak} instructions in S-mode enter Debug Mode.\n */\n#define CSR_DCSR_EBREAKS_DEBUG_MODE         1\n/*\n * This bit is hardwired to 0 if the hart does not support S-mode.\n */\n#define CSR_DCSR_EBREAKU_OFFSET             0xc\n#define CSR_DCSR_EBREAKU_LENGTH             1\n#define CSR_DCSR_EBREAKU                    0x1000\n/*\n * exception: {\\tt ebreak} instructions in U-mode behave as described in the\n * Privileged Spec.\n */\n#define CSR_DCSR_EBREAKU_EXCEPTION          0\n/*\n * debug mode: {\\tt ebreak} instructions in U-mode enter Debug Mode.\n */\n#define CSR_DCSR_EBREAKU_DEBUG_MODE         1\n/*\n * This bit is hardwired to 0 if the hart does not support U-mode.\n */\n#define CSR_DCSR_STEPIE_OFFSET              0xb\n#define CSR_DCSR_STEPIE_LENGTH              1\n#define CSR_DCSR_STEPIE                     0x800\n/*\n * interrupts disabled: Interrupts (including NMI) are disabled during single stepping.\n */\n#define CSR_DCSR_STEPIE_INTERRUPTS_DISABLED 0\n/*\n * interrupts enabled: Interrupts (including NMI) are enabled during single stepping.\n */\n#define CSR_DCSR_STEPIE_INTERRUPTS_ENABLED  1\n/*\n * Implementations may hard wire this bit to 0.\n * In that case interrupt behavior can be emulated by the debugger.\n *\n * The debugger must not change the value of this bit while the hart\n * is running.\n */\n#define CSR_DCSR_STOPCOUNT_OFFSET           0xa\n#define CSR_DCSR_STOPCOUNT_LENGTH           1\n#define CSR_DCSR_STOPCOUNT                  0x400\n/*\n * normal: Increment counters as usual.\n */\n#define CSR_DCSR_STOPCOUNT_NORMAL           0\n/*\n * freeze: Don't increment any hart-local counters while in Debug Mode or\n * on {\\tt ebreak} instructions that cause entry into Debug Mode.\n * These counters include the {\\tt instret} CSR. On single-hart cores\n * {\\tt cycle} should be stopped, but on multi-hart cores it must keep\n * incrementing.\n */\n#define CSR_DCSR_STOPCOUNT_FREEZE           1\n/*\n * An implementation may hardwire this bit to 0 or 1.\n */\n#define CSR_DCSR_STOPTIME_OFFSET            9\n#define CSR_DCSR_STOPTIME_LENGTH            1\n#define CSR_DCSR_STOPTIME                   0x200\n/*\n * normal: Increment \\Rtime as usual.\n */\n#define CSR_DCSR_STOPTIME_NORMAL            0\n/*\n * freeze: Don't increment \\Rtime while in Debug Mode.  If all harts\n * have \\FcsrDcsrStoptime=1 and are in Debug Mode then \\Rmtime\n * is also allowed to stop incrementing.\n */\n#define CSR_DCSR_STOPTIME_FREEZE            1\n/*\n * An implementation may hardwire this bit to 0 or 1.\n */\n/*\n * Explains why Debug Mode was entered.\n *\n * When there are multiple reasons to enter Debug Mode in a single\n * cycle, hardware should set \\FcsrDcsrCause to the cause with the highest\n * priority.  See table~\\ref{tab:dcsrcausepriority} for priorities.\n */\n#define CSR_DCSR_CAUSE_OFFSET               6\n#define CSR_DCSR_CAUSE_LENGTH               3\n#define CSR_DCSR_CAUSE                      0x1c0\n/*\n * ebreak: An {\\tt ebreak} instruction was executed.\n */\n#define CSR_DCSR_CAUSE_EBREAK               1\n/*\n * trigger: A Trigger Module trigger fired with action=1.\n */\n#define CSR_DCSR_CAUSE_TRIGGER              2\n/*\n * haltreq: The debugger requested entry to Debug Mode using \\FdmDmcontrolHaltreq.\n */\n#define CSR_DCSR_CAUSE_HALTREQ              3\n/*\n * step: The hart single stepped because \\FcsrDcsrStep was set.\n */\n#define CSR_DCSR_CAUSE_STEP                 4\n/*\n * resethaltreq: The hart halted directly out of reset due to \\Fresethaltreq. It\n * is also acceptable to report 3 when this happens.\n */\n#define CSR_DCSR_CAUSE_RESETHALTREQ         5\n/*\n * group: The hart halted because it's part of a halt group.\n * Harts may report 3 for this cause instead.\n */\n#define CSR_DCSR_CAUSE_GROUP                6\n/*\n * Other values are reserved for future use.\n */\n/*\n * Extends the prv field with the virtualization mode the hart was operating\n * in when Debug Mode was entered. The encoding is described in Table\n * \\ref{tab:privmode}.\n * A debugger can change this value to change the hart's virtualization mode\n * when exiting Debug Mode.\n * This bit is hardwired to 0 on harts that do not support virtualization mode.\n */\n#define CSR_DCSR_V_OFFSET                   5\n#define CSR_DCSR_V_LENGTH                   1\n#define CSR_DCSR_V                          0x20\n#define CSR_DCSR_MPRVEN_OFFSET              4\n#define CSR_DCSR_MPRVEN_LENGTH              1\n#define CSR_DCSR_MPRVEN                     0x10\n/*\n * disabled: \\FcsrMstatusMprv in \\Rmstatus is ignored in Debug Mode.\n */\n#define CSR_DCSR_MPRVEN_DISABLED            0\n/*\n * enabled: \\FcsrMstatusMprv in \\Rmstatus takes effect in Debug Mode.\n */\n#define CSR_DCSR_MPRVEN_ENABLED             1\n/*\n * Implementing this bit is optional. It may be tied to either 0 or 1.\n */\n/*\n * When set, there is a Non-Maskable-Interrupt (NMI) pending for the hart.\n *\n * Since an NMI can indicate a hardware error condition,\n * reliable debugging may no longer be possible once this bit becomes set.\n * This is implementation-dependent.\n */\n#define CSR_DCSR_NMIP_OFFSET                3\n#define CSR_DCSR_NMIP_LENGTH                1\n#define CSR_DCSR_NMIP                       8\n/*\n * When set and not in Debug Mode, the hart will only execute a single\n * instruction and then enter Debug Mode. See Section~\\ref{stepBit}\n * for details.\n *\n * The debugger must not change the value of this bit while the hart\n * is running.\n */\n#define CSR_DCSR_STEP_OFFSET                2\n#define CSR_DCSR_STEP_LENGTH                1\n#define CSR_DCSR_STEP                       4\n/*\n * Contains the privilege mode the hart was operating in when Debug\n * Mode was entered. The encoding is described in Table\n * \\ref{tab:privmode}.  A debugger can change this value to change\n * the hart's privilege mode when exiting Debug Mode.\n *\n * Not all privilege modes are supported on all harts. If the\n * encoding written is not supported or the debugger is not allowed to\n * change to it, the hart may change to any supported privilege mode.\n */\n#define CSR_DCSR_PRV_OFFSET                 0\n#define CSR_DCSR_PRV_LENGTH                 2\n#define CSR_DCSR_PRV                        3\n#define CSR_DPC                             0x7b1\n#define CSR_DPC_DPC_OFFSET                  0\n#define CSR_DPC_DPC_LENGTH(DXLEN)           DXLEN\n#define CSR_DPC_DPC(DXLEN)                  ((1ULL<<DXLEN) + -1)\n#define CSR_DSCRATCH0                       0x7b2\n#define CSR_DSCRATCH1                       0x7b3\n#define CSR_TSELECT                         0x7a0\n#define CSR_TSELECT_INDEX_OFFSET            0\n#define CSR_TSELECT_INDEX_LENGTH(XLEN)      XLEN\n#define CSR_TSELECT_INDEX(XLEN)             ((1ULL<<XLEN) + -1)\n#define CSR_TDATA1                          0x7a1\n#define CSR_TDATA1_TYPE_OFFSET(XLEN)        (XLEN + -4)\n#define CSR_TDATA1_TYPE_LENGTH              4\n#define CSR_TDATA1_TYPE(XLEN)               (0xf * (1ULL<<(XLEN + -4)))\n/*\n * none: There is no trigger at this \\RcsrTselect.\n */\n#define CSR_TDATA1_TYPE_NONE                0\n/*\n * legacy: The trigger is a legacy SiFive address match trigger. These\n * should not be implemented and aren't further documented here.\n */\n#define CSR_TDATA1_TYPE_LEGACY              1\n/*\n * mcontrol: The trigger is an address/data match trigger. The remaining bits\n * in this register act as described in \\RcsrMcontrol.\n */\n#define CSR_TDATA1_TYPE_MCONTROL            2\n/*\n * icount: The trigger is an instruction count trigger. The remaining bits\n * in this register act as described in \\RcsrIcount.\n */\n#define CSR_TDATA1_TYPE_ICOUNT              3\n/*\n * itrigger: The trigger is an interrupt trigger. The remaining bits\n * in this register act as described in \\RcsrItrigger.\n */\n#define CSR_TDATA1_TYPE_ITRIGGER            4\n/*\n * etrigger: The trigger is an exception trigger. The remaining bits\n * in this register act as described in \\RcsrEtrigger.\n */\n#define CSR_TDATA1_TYPE_ETRIGGER            5\n/*\n * mcontrol6: The trigger is an address/data match trigger. The remaining bits\n * in this register act as described in \\RcsrMcontrolSix. This is similar\n * to a type 2 trigger, but provides additional functionality and\n * should be used instead of type 2 in newer implementations.\n */\n#define CSR_TDATA1_TYPE_MCONTROL6           6\n/*\n * tmexttrigger: The trigger is a trigger source external to the TM.  The\n * remaining bits in this register act as described in \\RcsrTmexttrigger.\n */\n#define CSR_TDATA1_TYPE_TMEXTTRIGGER        7\n/*\n * custom: These trigger types are available for non-standard use.\n */\n#define CSR_TDATA1_TYPE_CUSTOM_LOW          12\n#define CSR_TDATA1_TYPE_CUSTOM_HIGH         14\n/*\n * disabled: This trigger is disabled. In this state, \\RcsrTdataTwo and\n * \\RcsrTdataThree can be written with any value that is supported for\n * any of the types this trigger implements. The remaining bits in this\n * register are ignored.\n */\n#define CSR_TDATA1_TYPE_DISABLED            15\n/*\n * Other values are reserved for future use.\n */\n/*\n * If \\FcsrTdataOneType is 0, then this bit is hard-wired to 0.\n */\n#define CSR_TDATA1_DMODE_OFFSET(XLEN)       (XLEN + -5)\n#define CSR_TDATA1_DMODE_LENGTH             1\n#define CSR_TDATA1_DMODE(XLEN)              (1ULL<<(XLEN + -5))\n/*\n * both: Both Debug and M-mode can write the {\\tt tdata} registers at the\n * selected \\RcsrTselect.\n */\n#define CSR_TDATA1_DMODE_BOTH               0\n/*\n * dmode: Only Debug Mode can write the {\\tt tdata} registers at the\n * selected \\RcsrTselect.  Writes from other modes are ignored.\n */\n#define CSR_TDATA1_DMODE_DMODE              1\n/*\n * This bit is only writable from Debug Mode.\n * In ordinary use, external debuggers will always set this bit when\n * configuring a trigger.\n * When clearing this bit, debuggers should also set the action field\n * (whose location depends on \\FcsrTdataOneType) to something other\n * than 1.\n */\n/*\n * If \\FcsrTdataOneType is 0, then this field is hard-wired to 0.\n *\n * Trigger-specific data.\n */\n#define CSR_TDATA1_DATA_OFFSET              0\n#define CSR_TDATA1_DATA_LENGTH(XLEN)        (XLEN + -5)\n#define CSR_TDATA1_DATA(XLEN)               ((1ULL<<(XLEN + -5)) + -1)\n#define CSR_TDATA2                          0x7a2\n#define CSR_TDATA2_DATA_OFFSET              0\n#define CSR_TDATA2_DATA_LENGTH(XLEN)        XLEN\n#define CSR_TDATA2_DATA(XLEN)               ((1ULL<<XLEN) + -1)\n#define CSR_TDATA3                          0x7a3\n#define CSR_TDATA3_DATA_OFFSET              0\n#define CSR_TDATA3_DATA_LENGTH(XLEN)        XLEN\n#define CSR_TDATA3_DATA(XLEN)               ((1ULL<<XLEN) + -1)\n#define CSR_TINFO                           0x7a4\n/*\n * One bit for each possible \\FcsrTdataOneType enumerated in \\RcsrTdataOne. Bit N\n * corresponds to type N. If the bit is set, then that type is\n * supported by the currently selected trigger.\n *\n * If the currently selected trigger doesn't exist, this field\n * contains 1.\n */\n#define CSR_TINFO_INFO_OFFSET               0\n#define CSR_TINFO_INFO_LENGTH               0x10\n#define CSR_TINFO_INFO                      0xffff\n#define CSR_TCONTROL                        0x7a5\n/*\n * M-mode previous trigger enable field.\n *\n * \\FcsrTcontrolMpte and \\FcsrTcontrolMte provide one solution to a problem\n * regarding triggers with action=0 firing in M-mode trap handlers. See\n * Section~\\ref{sec:nativetrigger} for more details.\n *\n * When a breakpoint trap into M-mode is taken, \\FcsrTcontrolMpte is set to the value of\n * \\FcsrTcontrolMte.\n */\n#define CSR_TCONTROL_MPTE_OFFSET            7\n#define CSR_TCONTROL_MPTE_LENGTH            1\n#define CSR_TCONTROL_MPTE                   0x80\n/*\n * M-mode trigger enable field.\n */\n#define CSR_TCONTROL_MTE_OFFSET             3\n#define CSR_TCONTROL_MTE_LENGTH             1\n#define CSR_TCONTROL_MTE                    8\n/*\n * disabled: Triggers with action=0 do not match/fire while the hart is in M-mode.\n */\n#define CSR_TCONTROL_MTE_DISABLED           0\n/*\n * enabled: Triggers do match/fire while the hart is in M-mode.\n */\n#define CSR_TCONTROL_MTE_ENABLED            1\n/*\n * When a breakpoint trap into M-mode is taken, \\FcsrTcontrolMte is set to 0. When {\\tt\n * mret} is executed, \\FcsrTcontrolMte is set to the value of \\FcsrTcontrolMpte.\n */\n#define CSR_HCONTEXT                        0x6a8\n/*\n * Hypervisor mode software can write a context number to this register,\n * which can be used to set triggers that only fire in that specific\n * context.\n *\n * An implementation may tie any number of upper bits in this field to\n * 0. If the H extension is not implemented, it's recommended to implement\n * no more than 6 bits on RV32 and 13 on RV64 (as visible through the\n * \\RcsrMcontext register).  If the H extension is implemented,\n * it's recommended to implement no more than 7 bits on RV32\n * and 14 on RV64.\n */\n#define CSR_HCONTEXT_HCONTEXT_OFFSET        0\n#define CSR_HCONTEXT_HCONTEXT_LENGTH(XLEN)  XLEN\n#define CSR_HCONTEXT_HCONTEXT(XLEN)         ((1ULL<<XLEN) + -1)\n#define CSR_SCONTEXT                        0x5a8\n/*\n * Supervisor mode software can write a context number to this\n * register, which can be used to set triggers that only fire in that\n * specific context.\n *\n * An implementation may tie any number of high bits in this field to\n * 0. It's recommended to implement no more than 16 bits on RV32, and\n * 34 on RV64.\n */\n#define CSR_SCONTEXT_DATA_OFFSET            0\n#define CSR_SCONTEXT_DATA_LENGTH(XLEN)      XLEN\n#define CSR_SCONTEXT_DATA(XLEN)             ((1ULL<<XLEN) + -1)\n#define CSR_MCONTEXT                        0x7a8\n#define CSR_MSCONTEXT                       0x7aa\n#define CSR_MCONTROL                        0x7a1\n#define CSR_MCONTROL_TYPE_OFFSET(XLEN)      (XLEN + -4)\n#define CSR_MCONTROL_TYPE_LENGTH            4\n#define CSR_MCONTROL_TYPE(XLEN)             (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_MCONTROL_DMODE_OFFSET(XLEN)     (XLEN + -5)\n#define CSR_MCONTROL_DMODE_LENGTH           1\n#define CSR_MCONTROL_DMODE(XLEN)            (1ULL<<(XLEN + -5))\n/*\n * Specifies the largest naturally aligned powers-of-two (NAPOT) range\n * supported by the hardware when \\FcsrMcontrolMatch is 1. The value is the\n * logarithm base 2 of the number of bytes in that range.\n * A value of 0 indicates \\FcsrMcontrolMatch 1 is not supported.\n * A value of 63 corresponds to the maximum NAPOT range, which is\n * $2^{63}$ bytes in size.\n */\n#define CSR_MCONTROL_MASKMAX_OFFSET(XLEN)   (XLEN + -0xb)\n#define CSR_MCONTROL_MASKMAX_LENGTH         6\n#define CSR_MCONTROL_MASKMAX(XLEN)          (0x3f * (1ULL<<(XLEN + -0xb)))\n/*\n * This field only exists when XLEN is at least 64.\n * It contains the 2 high bits of the access size. The low bits\n * come from \\FcsrMcontrolSizelo. See \\FcsrMcontrolSizelo for how this\n * is used.\n */\n#define CSR_MCONTROL_SIZEHI_OFFSET          0x15\n#define CSR_MCONTROL_SIZEHI_LENGTH          2\n#define CSR_MCONTROL_SIZEHI                 0x600000\n/*\n * If this bit is implemented then it must become set when this\n * trigger fires and may become set when this trigger matches.\n * The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) matched.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_MCONTROL_HIT_OFFSET             0x14\n#define CSR_MCONTROL_HIT_LENGTH             1\n#define CSR_MCONTROL_HIT                    0x100000\n/*\n * This bit determines the contents of the XLEN-bit compare values.\n */\n#define CSR_MCONTROL_SELECT_OFFSET          0x13\n#define CSR_MCONTROL_SELECT_LENGTH          1\n#define CSR_MCONTROL_SELECT                 0x80000\n/*\n * address: There is at least one compare value and it contains the lowest\n * virtual address of the access.\n * It is recommended that there are additional compare values for\n * the other accessed virtual addresses.\n * (E.g. on a 32-bit read from 0x4000, the lowest address is 0x4000\n * and the other addresses are 0x4001, 0x4002, and 0x4003.)\n */\n#define CSR_MCONTROL_SELECT_ADDRESS         0\n/*\n * data: There is exactly one compare value and it contains the data\n * value loaded or stored, or the instruction executed.\n * Any bits beyond the size of the data access will contain 0.\n */\n#define CSR_MCONTROL_SELECT_DATA            1\n#define CSR_MCONTROL_TIMING_OFFSET          0x12\n#define CSR_MCONTROL_TIMING_LENGTH          1\n#define CSR_MCONTROL_TIMING                 0x40000\n/*\n * before: The action for this trigger will be taken just before the\n * instruction that triggered it is committed, but after all preceding\n * instructions are committed. \\Rxepc or \\RcsrDpc (depending\n * on \\FcsrMcontrolAction) must be set to the virtual address of the\n * instruction that matched.\n *\n * If this is combined with \\FcsrMcontrolLoad and\n * \\FcsrMcontrolSelect=1 then a memory access will be\n * performed (including any side effects of performing such an access) even\n * though the load will not update its destination register. Debuggers\n * should consider this when setting such breakpoints on, for example,\n * memory-mapped I/O addresses.\n */\n#define CSR_MCONTROL_TIMING_BEFORE          0\n/*\n * after: The action for this trigger will be taken after the instruction\n * that triggered it is committed. It should be taken before the next\n * instruction is committed, but it is better to implement triggers imprecisely\n * than to not implement them at all.  \\Rxepc or\n * \\RcsrDpc (depending on \\FcsrMcontrolAction) must be set to\n * the virtual address of the next instruction that must be executed to\n * preserve the program flow.\n */\n#define CSR_MCONTROL_TIMING_AFTER           1\n/*\n * Most hardware will only implement one timing or the other, possibly\n * dependent on \\FcsrMcontrolSelect, \\FcsrMcontrolExecute,\n * \\FcsrMcontrolLoad, and \\FcsrMcontrolStore. This bit\n * primarily exists for the hardware to communicate to the debugger\n * what will happen. Hardware may implement the bit fully writable, in\n * which case the debugger has a little more control.\n *\n * Data load triggers with \\FcsrMcontrolTiming of 0 will result in the same load\n * happening again when the debugger lets the hart run. For data load\n * triggers, debuggers must first attempt to set the breakpoint with\n * \\FcsrMcontrolTiming of 1.\n *\n * If a trigger with \\FcsrMcontrolTiming of 0 matches, it is\n * implementation-dependent whether that prevents a trigger with\n * \\FcsrMcontrolTiming of 1 matching as well.\n */\n/*\n * This field contains the 2 low bits of the access size. The high bits come\n * from \\FcsrMcontrolSizehi. The combined value is interpreted as follows:\n */\n#define CSR_MCONTROL_SIZELO_OFFSET          0x10\n#define CSR_MCONTROL_SIZELO_LENGTH          2\n#define CSR_MCONTROL_SIZELO                 0x30000\n/*\n * any: The trigger will attempt to match against an access of any size.\n * The behavior is only well-defined if $|select|=0$, or if the access\n * size is XLEN.\n */\n#define CSR_MCONTROL_SIZELO_ANY             0\n/*\n * 8bit: The trigger will only match against 8-bit memory accesses.\n */\n#define CSR_MCONTROL_SIZELO_8BIT            1\n/*\n * 16bit: The trigger will only match against 16-bit memory accesses or\n * execution of 16-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_16BIT           2\n/*\n * 32bit: The trigger will only match against 32-bit memory accesses or\n * execution of 32-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_32BIT           3\n/*\n * 48bit: The trigger will only match against execution of 48-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_48BIT           4\n/*\n * 64bit: The trigger will only match against 64-bit memory accesses or\n * execution of 64-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_64BIT           5\n/*\n * 80bit: The trigger will only match against execution of 80-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_80BIT           6\n/*\n * 96bit: The trigger will only match against execution of 96-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_96BIT           7\n/*\n * 112bit: The trigger will only match against execution of 112-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_112BIT          8\n/*\n * 128bit: The trigger will only match against 128-bit memory accesses or\n * execution of 128-bit instructions.\n */\n#define CSR_MCONTROL_SIZELO_128BIT          9\n/*\n * An implementation must support the value of 0, but all other values\n * are optional. When an implementation supports address triggers\n * (\\FcsrMcontrolSelect=0), it is recommended that those triggers\n * support every access size that the hart supports, as well as for\n * every instruction size that the hart supports.\n *\n * Implementations such as RV32D or RV64V are able to perform loads\n * and stores that are wider than XLEN. Custom extensions may also\n * support instructions that are wider than XLEN. Because\n * \\RcsrTdataTwo is of size XLEN, there is a known limitation that\n * data value triggers (\\FcsrMcontrolSelect=1) can only be supported\n * for access sizes up to XLEN bits.  When an implementation supports\n * data value triggers (\\FcsrMcontrolSelect=1), it is recommended\n * that those triggers support every access size up to XLEN that the\n * hart supports, as well as for every instruction length up to XLEN\n * that the hart supports.\n */\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_MCONTROL_ACTION_OFFSET          0xc\n#define CSR_MCONTROL_ACTION_LENGTH          4\n#define CSR_MCONTROL_ACTION                 0xf000\n/*\n * breakpoint:\n */\n#define CSR_MCONTROL_ACTION_BREAKPOINT      0\n/*\n * debug mode:\n */\n#define CSR_MCONTROL_ACTION_DEBUG_MODE      1\n/*\n * trace on:\n */\n#define CSR_MCONTROL_ACTION_TRACE_ON        2\n/*\n * trace off:\n */\n#define CSR_MCONTROL_ACTION_TRACE_OFF       3\n/*\n * trace notify:\n */\n#define CSR_MCONTROL_ACTION_TRACE_NOTIFY    4\n/*\n * external0:\n */\n#define CSR_MCONTROL_ACTION_EXTERNAL0       8\n/*\n * external1:\n */\n#define CSR_MCONTROL_ACTION_EXTERNAL1       9\n#define CSR_MCONTROL_CHAIN_OFFSET           0xb\n#define CSR_MCONTROL_CHAIN_LENGTH           1\n#define CSR_MCONTROL_CHAIN                  0x800\n/*\n * disabled: When this trigger matches, the configured action is taken.\n */\n#define CSR_MCONTROL_CHAIN_DISABLED         0\n/*\n * enabled: While this trigger does not match, it prevents the trigger with\n * the next index from matching.\n */\n#define CSR_MCONTROL_CHAIN_ENABLED          1\n/*\n * A trigger chain starts on the first trigger with $|chain|=1$ after\n * a trigger with $|chain|=0$, or simply on the first trigger if that\n * has $|chain|=1$. It ends on the first trigger after that which has\n * $|chain|=0$. This final trigger is part of the chain. The action\n * on all but the final trigger is ignored.  The action on that final\n * trigger will be taken if and only if all the triggers in the chain\n * match at the same time.\n *\n * Debuggers should not terminate a chain with a trigger with a\n * different type. It is undefined when exactly such a chain fires.\n *\n * Because \\FcsrMcontrolChain affects the next trigger, hardware must zero it in\n * writes to \\RcsrMcontrol that set \\FcsrTdataOneDmode to 0 if the next trigger has\n * \\FcsrTdataOneDmode of 1.\n * In addition hardware should ignore writes to \\RcsrMcontrol that set\n * \\FcsrTdataOneDmode to 1 if the previous trigger has both \\FcsrTdataOneDmode of 0 and\n * \\FcsrMcontrolChain of 1. Debuggers must avoid the latter case by checking\n * \\FcsrMcontrolChain on the previous trigger if they're writing \\RcsrMcontrol.\n *\n * Implementations that wish to limit the maximum length of a trigger\n * chain (eg. to meet timing requirements) may do so by zeroing\n * \\FcsrMcontrolChain in writes to \\RcsrMcontrol that would make the chain too long.\n */\n#define CSR_MCONTROL_MATCH_OFFSET           7\n#define CSR_MCONTROL_MATCH_LENGTH           4\n#define CSR_MCONTROL_MATCH                  0x780\n/*\n * equal: Matches when any compare value equals \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL_MATCH_EQUAL            0\n/*\n * napot: Matches when the top $M$ bits of any compare value match the top\n * $M$ bits of \\RcsrTdataTwo.\n * $M$ is $|XLEN|-1$ minus the index of the least-significant\n * bit containing 0 in \\RcsrTdataTwo. Debuggers should only write values\n * to \\RcsrTdataTwo such that $M + $\\FcsrMcontrolMaskmax$ \\geq |XLEN|$\n * and $M\\gt0$ , otherwise it's undefined on what conditions the\n * trigger will match.\n */\n#define CSR_MCONTROL_MATCH_NAPOT            1\n/*\n * ge: Matches when any compare value is greater than (unsigned) or\n * equal to \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL_MATCH_GE               2\n/*\n * lt: Matches when any compare value is less than (unsigned)\n * \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL_MATCH_LT               3\n/*\n * mask low: Matches when $\\frac{|XLEN|}{2}-1$:$0$ of any compare value\n * equals $\\frac{|XLEN|}{2}-1$:$0$ of \\RcsrTdataTwo after\n * $\\frac{|XLEN|}{2}-1$:$0$ of the compare value is ANDed with\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL_MATCH_MASK_LOW         4\n/*\n * mask high: Matches when $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of any compare\n * value equals $\\frac{|XLEN|}{2}-1$:$0$ of \\RcsrTdataTwo after\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of the compare value is ANDed with\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL_MATCH_MASK_HIGH        5\n/*\n * not equal: Matches when \\FcsrMcontrolMatch$=0$ would not match.\n */\n#define CSR_MCONTROL_MATCH_NOT_EQUAL        8\n/*\n * not napot: Matches when \\FcsrMcontrolMatch$=1$ would not match.\n */\n#define CSR_MCONTROL_MATCH_NOT_NAPOT        9\n/*\n * not mask low: Matches when \\FcsrMcontrolMatch$=4$ would not match.\n */\n#define CSR_MCONTROL_MATCH_NOT_MASK_LOW     12\n/*\n * not mask high: Matches when \\FcsrMcontrolMatch$=5$ would not match.\n */\n#define CSR_MCONTROL_MATCH_NOT_MASK_HIGH    13\n/*\n * Other values are reserved for future use.\n *\n * All comparisons only look at the lower XLEN (in the current mode)\n * bits of the compare values and of \\RcsrTdataTwo.\n * When \\FcsrMcontrolSelect=1 and access size is N, this is further\n * reduced, and comparisons only look at the lower N bits of the\n * compare values and of \\RcsrTdataTwo.\n */\n/*\n * When set, enable this trigger in M-mode.\n */\n#define CSR_MCONTROL_M_OFFSET               6\n#define CSR_MCONTROL_M_LENGTH               1\n#define CSR_MCONTROL_M                      0x40\n/*\n * When set, enable this trigger in S/HS-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * S-mode.\n */\n#define CSR_MCONTROL_S_OFFSET               4\n#define CSR_MCONTROL_S_LENGTH               1\n#define CSR_MCONTROL_S                      0x10\n/*\n * When set, enable this trigger in U-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * U-mode.\n */\n#define CSR_MCONTROL_U_OFFSET               3\n#define CSR_MCONTROL_U_LENGTH               1\n#define CSR_MCONTROL_U                      8\n/*\n * When set, the trigger fires on the virtual address or opcode of an\n * instruction that is executed.\n */\n#define CSR_MCONTROL_EXECUTE_OFFSET         2\n#define CSR_MCONTROL_EXECUTE_LENGTH         1\n#define CSR_MCONTROL_EXECUTE                4\n/*\n * When set, the trigger fires on the virtual address or data of any\n * store.\n */\n#define CSR_MCONTROL_STORE_OFFSET           1\n#define CSR_MCONTROL_STORE_LENGTH           1\n#define CSR_MCONTROL_STORE                  2\n/*\n * When set, the trigger fires on the virtual address or data of any\n * load.\n */\n#define CSR_MCONTROL_LOAD_OFFSET            0\n#define CSR_MCONTROL_LOAD_LENGTH            1\n#define CSR_MCONTROL_LOAD                   1\n#define CSR_MCONTROL6                       0x7a1\n#define CSR_MCONTROL6_TYPE_OFFSET(XLEN)     (XLEN + -4)\n#define CSR_MCONTROL6_TYPE_LENGTH           4\n#define CSR_MCONTROL6_TYPE(XLEN)            (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_MCONTROL6_DMODE_OFFSET(XLEN)    (XLEN + -5)\n#define CSR_MCONTROL6_DMODE_LENGTH          1\n#define CSR_MCONTROL6_DMODE(XLEN)           (1ULL<<(XLEN + -5))\n/*\n * When set, enable this trigger in VS-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_MCONTROL6_VS_OFFSET             0x18\n#define CSR_MCONTROL6_VS_LENGTH             1\n#define CSR_MCONTROL6_VS                    0x1000000\n/*\n * When set, enable this trigger in VU-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_MCONTROL6_VU_OFFSET             0x17\n#define CSR_MCONTROL6_VU_LENGTH             1\n#define CSR_MCONTROL6_VU                    0x800000\n/*\n * If this bit is implemented then it must become set when this\n * trigger fires and may become set when this trigger matches.\n * The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) matched.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_MCONTROL6_HIT_OFFSET            0x16\n#define CSR_MCONTROL6_HIT_LENGTH            1\n#define CSR_MCONTROL6_HIT                   0x400000\n/*\n * This bit determines the contents of the XLEN-bit compare values.\n */\n#define CSR_MCONTROL6_SELECT_OFFSET         0x15\n#define CSR_MCONTROL6_SELECT_LENGTH         1\n#define CSR_MCONTROL6_SELECT                0x200000\n/*\n * address: There is at least one compare value and it contains the lowest\n * virtual address of the access.\n * In addition, it is recommended that there are additional compare\n * values for the other accessed virtual addresses match.\n * (E.g. on a 32-bit read from 0x4000, the lowest address is 0x4000\n * and the other addresses are 0x4001, 0x4002, and 0x4003.)\n */\n#define CSR_MCONTROL6_SELECT_ADDRESS        0\n/*\n * data: There is exactly one compare value and it contains the data\n * value loaded or stored, or the instruction executed.\n * Any bits beyond the size of the data access will contain 0.\n */\n#define CSR_MCONTROL6_SELECT_DATA           1\n#define CSR_MCONTROL6_TIMING_OFFSET         0x14\n#define CSR_MCONTROL6_TIMING_LENGTH         1\n#define CSR_MCONTROL6_TIMING                0x100000\n/*\n * before: The action for this trigger will be taken just before the\n * instruction that triggered it is committed, but after all preceding\n * instructions are committed. \\Rxepc or \\RcsrDpc (depending\n * on \\FcsrMcontrolSixAction) must be set to the virtual address of the\n * instruction that matched.\n *\n * If this is combined with \\FcsrMcontrolSixLoad and\n * \\FcsrMcontrolSixSelect=1 then a memory access will be\n * performed (including any side effects of performing such an access) even\n * though the load will not update its destination register. Debuggers\n * should consider this when setting such breakpoints on, for example,\n * memory-mapped I/O addresses.\n */\n#define CSR_MCONTROL6_TIMING_BEFORE         0\n/*\n * after: The action for this trigger will be taken after the instruction\n * that triggered it is committed. It should be taken before the next\n * instruction is committed, but it is better to implement triggers imprecisely\n * than to not implement them at all.  \\Rxepc or\n * \\RcsrDpc (depending on \\FcsrMcontrolSixAction) must be set to\n * the virtual address of the next instruction that must be executed to\n * preserve the program flow.\n */\n#define CSR_MCONTROL6_TIMING_AFTER          1\n/*\n * Most hardware will only implement one timing or the other, possibly\n * dependent on \\FcsrMcontrolSixSelect, \\FcsrMcontrolSixExecute,\n * \\FcsrMcontrolSixLoad, and \\FcsrMcontrolSixStore. This bit\n * primarily exists for the hardware to communicate to the debugger\n * what will happen. Hardware may implement the bit fully writable, in\n * which case the debugger has a little more control.\n *\n * Data load triggers with \\FcsrMcontrolSixTiming of 0 will result in the same load\n * happening again when the debugger lets the hart run. For data load\n * triggers, debuggers must first attempt to set the breakpoint with\n * \\FcsrMcontrolSixTiming of 1.\n *\n * If a trigger with \\FcsrMcontrolSixTiming of 0 matches, it is\n * implementation-dependent whether that prevents a trigger with\n * \\FcsrMcontrolSixTiming of 1 matching as well.\n */\n#define CSR_MCONTROL6_SIZE_OFFSET           0x10\n#define CSR_MCONTROL6_SIZE_LENGTH           4\n#define CSR_MCONTROL6_SIZE                  0xf0000\n/*\n * any: The trigger will attempt to match against an access of any size.\n * The behavior is only well-defined if $|select|=0$, or if the access\n * size is XLEN.\n */\n#define CSR_MCONTROL6_SIZE_ANY              0\n/*\n * 8bit: The trigger will only match against 8-bit memory accesses.\n */\n#define CSR_MCONTROL6_SIZE_8BIT             1\n/*\n * 16bit: The trigger will only match against 16-bit memory accesses or\n * execution of 16-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_16BIT            2\n/*\n * 32bit: The trigger will only match against 32-bit memory accesses or\n * execution of 32-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_32BIT            3\n/*\n * 48bit: The trigger will only match against execution of 48-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_48BIT            4\n/*\n * 64bit: The trigger will only match against 64-bit memory accesses or\n * execution of 64-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_64BIT            5\n/*\n * 80bit: The trigger will only match against execution of 80-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_80BIT            6\n/*\n * 96bit: The trigger will only match against execution of 96-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_96BIT            7\n/*\n * 112bit: The trigger will only match against execution of 112-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_112BIT           8\n/*\n * 128bit: The trigger will only match against 128-bit memory accesses or\n * execution of 128-bit instructions.\n */\n#define CSR_MCONTROL6_SIZE_128BIT           9\n/*\n * An implementation must support the value of 0, but all other values\n * are optional. When an implementation supports address triggers\n * (\\FcsrMcontrolSixSelect=0), it is recommended that those triggers\n * support every access size that the hart supports, as well as for\n * every instruction size that the hart supports.\n *\n * Implementations such as RV32D or RV64V are able to perform loads\n * and stores that are wider than XLEN. Custom extensions may also\n * support instructions that are wider than XLEN. Because\n * \\RcsrTdataTwo is of size XLEN, there is a known limitation that\n * data value triggers (\\FcsrMcontrolSixSelect=1) can only be supported\n * for access sizes up to XLEN bits.  When an implementation supports\n * data value triggers (\\FcsrMcontrolSixSelect=1), it is recommended\n * that those triggers support every access size up to XLEN that the\n * hart supports, as well as for every instruction length up to XLEN\n * that the hart supports.\n */\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_MCONTROL6_ACTION_OFFSET         0xc\n#define CSR_MCONTROL6_ACTION_LENGTH         4\n#define CSR_MCONTROL6_ACTION                0xf000\n/*\n * breakpoint:\n */\n#define CSR_MCONTROL6_ACTION_BREAKPOINT     0\n/*\n * debug mode:\n */\n#define CSR_MCONTROL6_ACTION_DEBUG_MODE     1\n/*\n * trace on:\n */\n#define CSR_MCONTROL6_ACTION_TRACE_ON       2\n/*\n * trace off:\n */\n#define CSR_MCONTROL6_ACTION_TRACE_OFF      3\n/*\n * trace notify:\n */\n#define CSR_MCONTROL6_ACTION_TRACE_NOTIFY   4\n/*\n * external0:\n */\n#define CSR_MCONTROL6_ACTION_EXTERNAL0      8\n/*\n * external1:\n */\n#define CSR_MCONTROL6_ACTION_EXTERNAL1      9\n#define CSR_MCONTROL6_CHAIN_OFFSET          0xb\n#define CSR_MCONTROL6_CHAIN_LENGTH          1\n#define CSR_MCONTROL6_CHAIN                 0x800\n/*\n * disabled: When this trigger matches, the configured action is taken.\n */\n#define CSR_MCONTROL6_CHAIN_DISABLED        0\n/*\n * enabled: While this trigger does not match, it prevents the trigger with\n * the next index from matching.\n */\n#define CSR_MCONTROL6_CHAIN_ENABLED         1\n/*\n * A trigger chain starts on the first trigger with $|chain|=1$ after\n * a trigger with $|chain|=0$, or simply on the first trigger if that\n * has $|chain|=1$. It ends on the first trigger after that which has\n * $|chain|=0$. This final trigger is part of the chain. The action\n * on all but the final trigger is ignored.  The action on that final\n * trigger will be taken if and only if all the triggers in the chain\n * match at the same time.\n *\n * Debuggers should not terminate a chain with a trigger with a\n * different type. It is undefined when exactly such a chain fires.\n *\n * Because \\FcsrMcontrolSixChain affects the next trigger, hardware must zero it in\n * writes to \\RcsrMcontrolSix that set \\FcsrTdataOneDmode to 0 if the next trigger has\n * \\FcsrTdataOneDmode of 1.\n * In addition hardware should ignore writes to \\RcsrMcontrolSix that set\n * \\FcsrTdataOneDmode to 1 if the previous trigger has both \\FcsrTdataOneDmode of 0 and\n * \\FcsrMcontrolSixChain of 1. Debuggers must avoid the latter case by checking\n * \\FcsrMcontrolSixChain on the previous trigger if they're writing \\RcsrMcontrolSix.\n *\n * Implementations that wish to limit the maximum length of a trigger\n * chain (eg. to meet timing requirements) may do so by zeroing\n * \\FcsrMcontrolSixChain in writes to \\RcsrMcontrolSix that would make the chain too long.\n */\n#define CSR_MCONTROL6_MATCH_OFFSET          7\n#define CSR_MCONTROL6_MATCH_LENGTH          4\n#define CSR_MCONTROL6_MATCH                 0x780\n/*\n * equal: Matches when any compare value equals \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL6_MATCH_EQUAL           0\n/*\n * napot: Matches when the top $M$ bits of any compare value match the top\n * $M$ bits of \\RcsrTdataTwo.\n * $M$ is $|XLEN|-1$ minus the index of the least-significant bit\n * containing 0 in \\RcsrTdataTwo.\n * \\RcsrTdataTwo is WARL and if bits $|maskmax6|-1$:0 are written with all\n * ones then bit $|maskmax6|-1$ will be set to 0 while the values of bits $|maskmax6|-2$:0\n * are \\unspecified.\n * Legal values for \\RcsrTdataTwo require $M + |maskmax6| \\geq |XLEN|$ and $M\\gt0$.\n * See above for how to determine maskmax6.\n */\n#define CSR_MCONTROL6_MATCH_NAPOT           1\n/*\n * ge: Matches when any compare value is greater than (unsigned) or\n * equal to \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL6_MATCH_GE              2\n/*\n * lt: Matches when any compare value is less than (unsigned)\n * \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL6_MATCH_LT              3\n/*\n * mask low: Matches when $\\frac{|XLEN|}{2}-1$:$0$ of any compare value\n * equals $\\frac{|XLEN|}{2}-1$:$0$ of \\RcsrTdataTwo after\n * $\\frac{|XLEN|}{2}-1$:$0$ of the compare value is ANDed with\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL6_MATCH_MASK_LOW        4\n/*\n * mask high: Matches when $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of any compare\n * value equals $\\frac{|XLEN|}{2}-1$:$0$ of \\RcsrTdataTwo after\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of the compare value is ANDed with\n * $|XLEN|-1$:$\\frac{|XLEN|}{2}$ of \\RcsrTdataTwo.\n */\n#define CSR_MCONTROL6_MATCH_MASK_HIGH       5\n/*\n * not equal: Matches when \\FcsrMcontrolSixMatch$=0$ would not match.\n */\n#define CSR_MCONTROL6_MATCH_NOT_EQUAL       8\n/*\n * not napot: Matches when \\FcsrMcontrolSixMatch$=1$ would not match.\n */\n#define CSR_MCONTROL6_MATCH_NOT_NAPOT       9\n/*\n * not mask low: Matches when \\FcsrMcontrolSixMatch$=4$ would not match.\n */\n#define CSR_MCONTROL6_MATCH_NOT_MASK_LOW    12\n/*\n * not mask high: Matches when \\FcsrMcontrolSixMatch$=5$ would not match.\n */\n#define CSR_MCONTROL6_MATCH_NOT_MASK_HIGH   13\n/*\n * Other values are reserved for future use.\n *\n * All comparisons only look at the lower XLEN (in the current mode)\n * bits of the compare values and of \\RcsrTdataTwo.\n * When \\FcsrMcontrolSelect=1 and access size is N, this is further\n * reduced, and comparisons only look at the lower N bits of the\n * compare values and of \\RcsrTdataTwo.\n */\n/*\n * When set, enable this trigger in M-mode.\n */\n#define CSR_MCONTROL6_M_OFFSET              6\n#define CSR_MCONTROL6_M_LENGTH              1\n#define CSR_MCONTROL6_M                     0x40\n/*\n * When set, enable this trigger in S/HS-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * S-mode.\n */\n#define CSR_MCONTROL6_S_OFFSET              4\n#define CSR_MCONTROL6_S_LENGTH              1\n#define CSR_MCONTROL6_S                     0x10\n/*\n * When set, enable this trigger in U-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * U-mode.\n */\n#define CSR_MCONTROL6_U_OFFSET              3\n#define CSR_MCONTROL6_U_LENGTH              1\n#define CSR_MCONTROL6_U                     8\n/*\n * When set, the trigger fires on the virtual address or opcode of an\n * instruction that is executed.\n */\n#define CSR_MCONTROL6_EXECUTE_OFFSET        2\n#define CSR_MCONTROL6_EXECUTE_LENGTH        1\n#define CSR_MCONTROL6_EXECUTE               4\n/*\n * When set, the trigger fires on the virtual address or data of any\n * store.\n */\n#define CSR_MCONTROL6_STORE_OFFSET          1\n#define CSR_MCONTROL6_STORE_LENGTH          1\n#define CSR_MCONTROL6_STORE                 2\n/*\n * When set, the trigger fires on the virtual address or data of any\n * load.\n */\n#define CSR_MCONTROL6_LOAD_OFFSET           0\n#define CSR_MCONTROL6_LOAD_LENGTH           1\n#define CSR_MCONTROL6_LOAD                  1\n#define CSR_ICOUNT                          0x7a1\n#define CSR_ICOUNT_TYPE_OFFSET(XLEN)        (XLEN + -4)\n#define CSR_ICOUNT_TYPE_LENGTH              4\n#define CSR_ICOUNT_TYPE(XLEN)               (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_ICOUNT_DMODE_OFFSET(XLEN)       (XLEN + -5)\n#define CSR_ICOUNT_DMODE_LENGTH             1\n#define CSR_ICOUNT_DMODE(XLEN)              (1ULL<<(XLEN + -5))\n/*\n * When set, enable this trigger in VS-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ICOUNT_VS_OFFSET                0x1a\n#define CSR_ICOUNT_VS_LENGTH                1\n#define CSR_ICOUNT_VS                       0x4000000\n/*\n * When set, enable this trigger in VU-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ICOUNT_VU_OFFSET                0x19\n#define CSR_ICOUNT_VU_LENGTH                1\n#define CSR_ICOUNT_VU                       0x2000000\n/*\n * If this bit is implemented, the hardware sets it when this\n * trigger fires. The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) fires.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_ICOUNT_HIT_OFFSET               0x18\n#define CSR_ICOUNT_HIT_LENGTH               1\n#define CSR_ICOUNT_HIT                      0x1000000\n/*\n * The trigger will generally fire after \\FcsrIcountCount instructions\n * in enabled modes have been executed. See above for the precise behavior.\n */\n#define CSR_ICOUNT_COUNT_OFFSET             0xa\n#define CSR_ICOUNT_COUNT_LENGTH             0xe\n#define CSR_ICOUNT_COUNT                    0xfffc00\n/*\n * When set, enable this trigger in M-mode.\n */\n#define CSR_ICOUNT_M_OFFSET                 9\n#define CSR_ICOUNT_M_LENGTH                 1\n#define CSR_ICOUNT_M                        0x200\n/*\n * This bit becomes set when \\FcsrIcountCount is decremented from 1\n * to 0. It is cleared when the trigger fires, which will happen just\n * before executing the next instruction in one of the enabled modes.\n */\n#define CSR_ICOUNT_PENDING_OFFSET           8\n#define CSR_ICOUNT_PENDING_LENGTH           1\n#define CSR_ICOUNT_PENDING                  0x100\n/*\n * When set, enable this trigger in S/HS-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * S-mode.\n */\n#define CSR_ICOUNT_S_OFFSET                 7\n#define CSR_ICOUNT_S_LENGTH                 1\n#define CSR_ICOUNT_S                        0x80\n/*\n * When set, enable this trigger in U-mode.\n * This bit is hard-wired to 0 if the hart does not support\n * U-mode.\n */\n#define CSR_ICOUNT_U_OFFSET                 6\n#define CSR_ICOUNT_U_LENGTH                 1\n#define CSR_ICOUNT_U                        0x40\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_ICOUNT_ACTION_OFFSET            0\n#define CSR_ICOUNT_ACTION_LENGTH            6\n#define CSR_ICOUNT_ACTION                   0x3f\n/*\n * breakpoint:\n */\n#define CSR_ICOUNT_ACTION_BREAKPOINT        0\n/*\n * debug mode:\n */\n#define CSR_ICOUNT_ACTION_DEBUG_MODE        1\n/*\n * trace on:\n */\n#define CSR_ICOUNT_ACTION_TRACE_ON          2\n/*\n * trace off:\n */\n#define CSR_ICOUNT_ACTION_TRACE_OFF         3\n/*\n * trace notify:\n */\n#define CSR_ICOUNT_ACTION_TRACE_NOTIFY      4\n/*\n * external0:\n */\n#define CSR_ICOUNT_ACTION_EXTERNAL0         8\n/*\n * external1:\n */\n#define CSR_ICOUNT_ACTION_EXTERNAL1         9\n#define CSR_ITRIGGER                        0x7a1\n#define CSR_ITRIGGER_TYPE_OFFSET(XLEN)      (XLEN + -4)\n#define CSR_ITRIGGER_TYPE_LENGTH            4\n#define CSR_ITRIGGER_TYPE(XLEN)             (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_ITRIGGER_DMODE_OFFSET(XLEN)     (XLEN + -5)\n#define CSR_ITRIGGER_DMODE_LENGTH           1\n#define CSR_ITRIGGER_DMODE(XLEN)            (1ULL<<(XLEN + -5))\n/*\n * If this bit is implemented, the hardware sets it when this\n * trigger matches. The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) matched.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_ITRIGGER_HIT_OFFSET(XLEN)       (XLEN + -6)\n#define CSR_ITRIGGER_HIT_LENGTH             1\n#define CSR_ITRIGGER_HIT(XLEN)              (1ULL<<(XLEN + -6))\n/*\n * When set, enable this trigger for interrupts that are taken from VS\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ITRIGGER_VS_OFFSET              0xc\n#define CSR_ITRIGGER_VS_LENGTH              1\n#define CSR_ITRIGGER_VS                     0x1000\n/*\n * When set, enable this trigger for interrupts that are taken from VU\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ITRIGGER_VU_OFFSET              0xb\n#define CSR_ITRIGGER_VU_LENGTH              1\n#define CSR_ITRIGGER_VU                     0x800\n/*\n * When set, non-maskable interrupts cause this\n * trigger to fire if the trigger is enabled for the current mode.\n */\n#define CSR_ITRIGGER_NMI_OFFSET             0xa\n#define CSR_ITRIGGER_NMI_LENGTH             1\n#define CSR_ITRIGGER_NMI                    0x400\n/*\n * When set, enable this trigger for interrupts that are taken from M\n * mode.\n */\n#define CSR_ITRIGGER_M_OFFSET               9\n#define CSR_ITRIGGER_M_LENGTH               1\n#define CSR_ITRIGGER_M                      0x200\n/*\n * When set, enable this trigger for interrupts that are taken from S/HS\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * S-mode.\n */\n#define CSR_ITRIGGER_S_OFFSET               7\n#define CSR_ITRIGGER_S_LENGTH               1\n#define CSR_ITRIGGER_S                      0x80\n/*\n * When set, enable this trigger for interrupts that are taken from U\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * U-mode.\n */\n#define CSR_ITRIGGER_U_OFFSET               6\n#define CSR_ITRIGGER_U_LENGTH               1\n#define CSR_ITRIGGER_U                      0x40\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_ITRIGGER_ACTION_OFFSET          0\n#define CSR_ITRIGGER_ACTION_LENGTH          6\n#define CSR_ITRIGGER_ACTION                 0x3f\n/*\n * breakpoint:\n */\n#define CSR_ITRIGGER_ACTION_BREAKPOINT      0\n/*\n * debug mode:\n */\n#define CSR_ITRIGGER_ACTION_DEBUG_MODE      1\n/*\n * trace on:\n */\n#define CSR_ITRIGGER_ACTION_TRACE_ON        2\n/*\n * trace off:\n */\n#define CSR_ITRIGGER_ACTION_TRACE_OFF       3\n/*\n * trace notify:\n */\n#define CSR_ITRIGGER_ACTION_TRACE_NOTIFY    4\n/*\n * external0:\n */\n#define CSR_ITRIGGER_ACTION_EXTERNAL0       8\n/*\n * external1:\n */\n#define CSR_ITRIGGER_ACTION_EXTERNAL1       9\n#define CSR_ETRIGGER                        0x7a1\n#define CSR_ETRIGGER_TYPE_OFFSET(XLEN)      (XLEN + -4)\n#define CSR_ETRIGGER_TYPE_LENGTH            4\n#define CSR_ETRIGGER_TYPE(XLEN)             (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_ETRIGGER_DMODE_OFFSET(XLEN)     (XLEN + -5)\n#define CSR_ETRIGGER_DMODE_LENGTH           1\n#define CSR_ETRIGGER_DMODE(XLEN)            (1ULL<<(XLEN + -5))\n/*\n * If this bit is implemented, the hardware sets it when this\n * trigger matches. The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) matched.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_ETRIGGER_HIT_OFFSET(XLEN)       (XLEN + -6)\n#define CSR_ETRIGGER_HIT_LENGTH             1\n#define CSR_ETRIGGER_HIT(XLEN)              (1ULL<<(XLEN + -6))\n/*\n * When set, enable this trigger for exceptions that are taken from VS\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ETRIGGER_VS_OFFSET              0xc\n#define CSR_ETRIGGER_VS_LENGTH              1\n#define CSR_ETRIGGER_VS                     0x1000\n/*\n * When set, enable this trigger for exceptions that are taken from VU\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * virtualization mode.\n */\n#define CSR_ETRIGGER_VU_OFFSET              0xb\n#define CSR_ETRIGGER_VU_LENGTH              1\n#define CSR_ETRIGGER_VU                     0x800\n/*\n * When set, enable this trigger for exceptions that are taken from M\n * mode.\n */\n#define CSR_ETRIGGER_M_OFFSET               9\n#define CSR_ETRIGGER_M_LENGTH               1\n#define CSR_ETRIGGER_M                      0x200\n/*\n * When set, enable this trigger for exceptions that are taken from S/HS\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * S-mode.\n */\n#define CSR_ETRIGGER_S_OFFSET               7\n#define CSR_ETRIGGER_S_LENGTH               1\n#define CSR_ETRIGGER_S                      0x80\n/*\n * When set, enable this trigger for exceptions that are taken from U\n * mode.\n * This bit is hard-wired to 0 if the hart does not support\n * U-mode.\n */\n#define CSR_ETRIGGER_U_OFFSET               6\n#define CSR_ETRIGGER_U_LENGTH               1\n#define CSR_ETRIGGER_U                      0x40\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_ETRIGGER_ACTION_OFFSET          0\n#define CSR_ETRIGGER_ACTION_LENGTH          6\n#define CSR_ETRIGGER_ACTION                 0x3f\n/*\n * breakpoint:\n */\n#define CSR_ETRIGGER_ACTION_BREAKPOINT      0\n/*\n * debug mode:\n */\n#define CSR_ETRIGGER_ACTION_DEBUG_MODE      1\n/*\n * trace on:\n */\n#define CSR_ETRIGGER_ACTION_TRACE_ON        2\n/*\n * trace off:\n */\n#define CSR_ETRIGGER_ACTION_TRACE_OFF       3\n/*\n * trace notify:\n */\n#define CSR_ETRIGGER_ACTION_TRACE_NOTIFY    4\n/*\n * external0:\n */\n#define CSR_ETRIGGER_ACTION_EXTERNAL0       8\n/*\n * external1:\n */\n#define CSR_ETRIGGER_ACTION_EXTERNAL1       9\n#define CSR_TMEXTTRIGGER                    0x7a1\n#define CSR_TMEXTTRIGGER_TYPE_OFFSET(XLEN)  (XLEN + -4)\n#define CSR_TMEXTTRIGGER_TYPE_LENGTH        4\n#define CSR_TMEXTTRIGGER_TYPE(XLEN)         (0xf * (1ULL<<(XLEN + -4)))\n#define CSR_TMEXTTRIGGER_DMODE_OFFSET(XLEN) (XLEN + -5)\n#define CSR_TMEXTTRIGGER_DMODE_LENGTH       1\n#define CSR_TMEXTTRIGGER_DMODE(XLEN)        (1ULL<<(XLEN + -5))\n/*\n * If this bit is implemented, the hardware sets it when this\n * trigger matches. The trigger's user can set or clear it at any\n * time. It is used to determine which\n * trigger(s) matched.  If the bit is not implemented, it is always 0\n * and writing it has no effect.\n */\n#define CSR_TMEXTTRIGGER_HIT_OFFSET(XLEN)   (XLEN + -6)\n#define CSR_TMEXTTRIGGER_HIT_LENGTH         1\n#define CSR_TMEXTTRIGGER_HIT(XLEN)          (1ULL<<(XLEN + -6))\n/*\n * This optional bit, when set, causes this trigger to fire whenever an attached\n * interrupt controller signals a trigger.\n */\n#define CSR_TMEXTTRIGGER_INTCTL_OFFSET      0x16\n#define CSR_TMEXTTRIGGER_INTCTL_LENGTH      1\n#define CSR_TMEXTTRIGGER_INTCTL             0x400000\n/*\n * Selects any combination of up to 16 external debug trigger inputs\n * that cause this trigger to fire.\n */\n#define CSR_TMEXTTRIGGER_SELECT_OFFSET      6\n#define CSR_TMEXTTRIGGER_SELECT_LENGTH      0x10\n#define CSR_TMEXTTRIGGER_SELECT             0x3fffc0\n/*\n * The action to take when the trigger fires. The values are explained\n * in Table~\\ref{tab:action}.\n */\n#define CSR_TMEXTTRIGGER_ACTION_OFFSET      0\n#define CSR_TMEXTTRIGGER_ACTION_LENGTH      6\n#define CSR_TMEXTTRIGGER_ACTION             0x3f\n/*\n * breakpoint:\n */\n#define CSR_TMEXTTRIGGER_ACTION_BREAKPOINT  0\n/*\n * debug mode:\n */\n#define CSR_TMEXTTRIGGER_ACTION_DEBUG_MODE  1\n/*\n * trace on:\n */\n#define CSR_TMEXTTRIGGER_ACTION_TRACE_ON    2\n/*\n * trace off:\n */\n#define CSR_TMEXTTRIGGER_ACTION_TRACE_OFF   3\n/*\n * trace notify:\n */\n#define CSR_TMEXTTRIGGER_ACTION_TRACE_NOTIFY 4\n/*\n * external0:\n */\n#define CSR_TMEXTTRIGGER_ACTION_EXTERNAL0   8\n/*\n * external1:\n */\n#define CSR_TMEXTTRIGGER_ACTION_EXTERNAL1   9\n#define CSR_TEXTRA32                        0x7a3\n/*\n * Data used together with \\FcsrTextraThirtytwoMhselect.\n */\n#define CSR_TEXTRA32_MHVALUE_OFFSET         0x1a\n#define CSR_TEXTRA32_MHVALUE_LENGTH         6\n#define CSR_TEXTRA32_MHVALUE                0xfc000000U\n#define CSR_TEXTRA32_MHSELECT_OFFSET        0x17\n#define CSR_TEXTRA32_MHSELECT_LENGTH        3\n#define CSR_TEXTRA32_MHSELECT               0x3800000\n/*\n * ignore: Ignore \\FcsrTextraThirtytwoMhvalue.\n */\n#define CSR_TEXTRA32_MHSELECT_IGNORE        0\n/*\n * mcontext: This trigger will only match if the low bits of\n * \\RcsrMcontext/\\RcsrHcontext equal \\FcsrTextraThirtytwoMhvalue.\n */\n#define CSR_TEXTRA32_MHSELECT_MCONTEXT      4\n/*\n * 1, 5 (mcontext\\_select): This trigger will only match if the low bits of\n * \\RcsrMcontext/\\RcsrHcontext equal \\{\\FcsrTextraThirtytwoMhvalue, mhselect[2]\\}.\n *\n * 2, 6 (vmid\\_select): This trigger will only match if VMID in hgatp equals the lower VMIDMAX\n * (defined in the Privileged Spec) bits of \\{\\FcsrTextraThirtytwoMhvalue, mhselect[2]\\}.\n *\n * 3, 7 (reserved): Reserved.\n *\n * If the H extension is not supported, the only legal values are 0 and 4.\n */\n/*\n * When the least significant bit of this field is 1, it causes bits 7:0\n * in the comparison to be ignored, when \\FcsrTextraThirtytwoSselect=1.\n * When the next most significant bit of this field is 1, it causes bits 15:8\n * to be ignored in the comparison, when \\FcsrTextraThirtytwoSselect=1.\n */\n#define CSR_TEXTRA32_SBYTEMASK_OFFSET       0x12\n#define CSR_TEXTRA32_SBYTEMASK_LENGTH       2\n#define CSR_TEXTRA32_SBYTEMASK              0xc0000\n/*\n * Data used together with \\FcsrTextraThirtytwoSselect.\n *\n * This field should be tied to 0 when S-mode is not supported.\n */\n#define CSR_TEXTRA32_SVALUE_OFFSET          2\n#define CSR_TEXTRA32_SVALUE_LENGTH          0x10\n#define CSR_TEXTRA32_SVALUE                 0x3fffc\n#define CSR_TEXTRA32_SSELECT_OFFSET         0\n#define CSR_TEXTRA32_SSELECT_LENGTH         2\n#define CSR_TEXTRA32_SSELECT                3\n/*\n * ignore: Ignore \\FcsrTextraThirtytwoSvalue.\n */\n#define CSR_TEXTRA32_SSELECT_IGNORE         0\n/*\n * scontext: This trigger will only match if the low bits of\n * \\RcsrScontext equal \\FcsrTextraThirtytwoSvalue.\n */\n#define CSR_TEXTRA32_SSELECT_SCONTEXT       1\n/*\n * asid: This trigger will only match if:\n * \\begin{itemize}[noitemsep,nolistsep]\n * \\item the mode is VS-mode or VU-mode and ASID in \\Rvsatp\n * equals the lower ASIDMAX (defined in the Privileged Spec) bits\n * of \\FcsrTextraThirtytwoSvalue.\n * \\item in all other modes, ASID in \\Rsatp equals the lower\n * ASIDMAX (defined in the Privileged Spec) bits of\n * \\FcsrTextraThirtytwoSvalue.\n * \\end{itemize}\n */\n#define CSR_TEXTRA32_SSELECT_ASID           2\n/*\n * This field should be tied to 0 when S-mode is not supported.\n */\n#define CSR_TEXTRA64                        0x7a3\n#define CSR_TEXTRA64_MHVALUE_OFFSET         0x33\n#define CSR_TEXTRA64_MHVALUE_LENGTH         0xd\n#define CSR_TEXTRA64_MHVALUE                0xfff8000000000000ULL\n#define CSR_TEXTRA64_MHSELECT_OFFSET        0x30\n#define CSR_TEXTRA64_MHSELECT_LENGTH        3\n#define CSR_TEXTRA64_MHSELECT               0x7000000000000ULL\n/*\n * When the least significant bit of this field is 1, it causes bits 7:0\n * in the comparison to be ignored, when \\FcsrTextraSixtyfourSselect=1.\n * Likewise, the second bit controls the comparison of bits 15:8,\n * third bit controls the comparison of bits 23:16,\n * fourth bit controls the comparison of bits 31:24, and\n * fifth bit controls the comparison of bits 33:32.\n */\n#define CSR_TEXTRA64_SBYTEMASK_OFFSET       0x24\n#define CSR_TEXTRA64_SBYTEMASK_LENGTH       5\n#define CSR_TEXTRA64_SBYTEMASK              0x1f000000000ULL\n#define CSR_TEXTRA64_SVALUE_OFFSET          2\n#define CSR_TEXTRA64_SVALUE_LENGTH          0x22\n#define CSR_TEXTRA64_SVALUE                 0xffffffffcULL\n#define CSR_TEXTRA64_SSELECT_OFFSET         0\n#define CSR_TEXTRA64_SSELECT_LENGTH         2\n#define CSR_TEXTRA64_SSELECT                3\n#define DM_DMSTATUS                         0x11\n#define DM_DMSTATUS_NDMRESETPENDING_OFFSET  0x18\n#define DM_DMSTATUS_NDMRESETPENDING_LENGTH  1\n#define DM_DMSTATUS_NDMRESETPENDING         0x1000000\n/*\n * false: Unimplemented, or \\FdmDmcontrolNdmreset is zero and no ndmreset is currently\n * in progress.\n */\n#define DM_DMSTATUS_NDMRESETPENDING_FALSE   0\n/*\n * true: \\FdmDmcontrolNdmreset is currently nonzero, or there is an ndmreset in progress.\n */\n#define DM_DMSTATUS_NDMRESETPENDING_TRUE    1\n#define DM_DMSTATUS_STICKYUNAVAIL_OFFSET    0x17\n#define DM_DMSTATUS_STICKYUNAVAIL_LENGTH    1\n#define DM_DMSTATUS_STICKYUNAVAIL           0x800000\n/*\n * current: The per-hart {\\tt unavail} bits reflect the current state of the hart.\n */\n#define DM_DMSTATUS_STICKYUNAVAIL_CURRENT   0\n/*\n * sticky: The per-hart {\\tt unavail} bits are sticky. Once they are set, they will\n * not clear until the debugger acknowledges them using \\FdmDmcontrolAckunavail.\n */\n#define DM_DMSTATUS_STICKYUNAVAIL_STICKY    1\n/*\n * If 1, then there is an implicit {\\tt ebreak} instruction at the\n * non-existent word immediately after the Program Buffer. This saves\n * the debugger from having to write the {\\tt ebreak} itself, and\n * allows the Program Buffer to be one word smaller.\n *\n * This must be 1 when \\FdmAbstractcsProgbufsize is 1.\n */\n#define DM_DMSTATUS_IMPEBREAK_OFFSET        0x16\n#define DM_DMSTATUS_IMPEBREAK_LENGTH        1\n#define DM_DMSTATUS_IMPEBREAK               0x400000\n/*\n * This field is 1 when all currently selected harts have been reset\n * and reset has not been acknowledged for any of them.\n */\n#define DM_DMSTATUS_ALLHAVERESET_OFFSET     0x13\n#define DM_DMSTATUS_ALLHAVERESET_LENGTH     1\n#define DM_DMSTATUS_ALLHAVERESET            0x80000\n/*\n * This field is 1 when at least one currently selected hart has been\n * reset and reset has not been acknowledged for that hart.\n */\n#define DM_DMSTATUS_ANYHAVERESET_OFFSET     0x12\n#define DM_DMSTATUS_ANYHAVERESET_LENGTH     1\n#define DM_DMSTATUS_ANYHAVERESET            0x40000\n/*\n * This field is 1 when all currently selected harts have their\n * resume ack bit\\index{resume ack bit} set.\n */\n#define DM_DMSTATUS_ALLRESUMEACK_OFFSET     0x11\n#define DM_DMSTATUS_ALLRESUMEACK_LENGTH     1\n#define DM_DMSTATUS_ALLRESUMEACK            0x20000\n/*\n * This field is 1 when any currently selected hart has its\n * resume ack bit\\index{resume ack bit} set.\n */\n#define DM_DMSTATUS_ANYRESUMEACK_OFFSET     0x10\n#define DM_DMSTATUS_ANYRESUMEACK_LENGTH     1\n#define DM_DMSTATUS_ANYRESUMEACK            0x10000\n/*\n * This field is 1 when all currently selected harts do not exist in\n * this hardware platform.\n */\n#define DM_DMSTATUS_ALLNONEXISTENT_OFFSET   0xf\n#define DM_DMSTATUS_ALLNONEXISTENT_LENGTH   1\n#define DM_DMSTATUS_ALLNONEXISTENT          0x8000\n/*\n * This field is 1 when any currently selected hart does not exist in\n * this hardware platform.\n */\n#define DM_DMSTATUS_ANYNONEXISTENT_OFFSET   0xe\n#define DM_DMSTATUS_ANYNONEXISTENT_LENGTH   1\n#define DM_DMSTATUS_ANYNONEXISTENT          0x4000\n/*\n * This field is 1 when all currently selected harts are\n * unavailable, or (if \\FdmDmstatusStickyunavail is 1) were\n * unavailable without that being acknowledged.\n */\n#define DM_DMSTATUS_ALLUNAVAIL_OFFSET       0xd\n#define DM_DMSTATUS_ALLUNAVAIL_LENGTH       1\n#define DM_DMSTATUS_ALLUNAVAIL              0x2000\n/*\n * This field is 1 when any currently selected hart is unavailable,\n * or (if \\FdmDmstatusStickyunavail is 1) was unavailable without\n * that being acknowledged.\n */\n#define DM_DMSTATUS_ANYUNAVAIL_OFFSET       0xc\n#define DM_DMSTATUS_ANYUNAVAIL_LENGTH       1\n#define DM_DMSTATUS_ANYUNAVAIL              0x1000\n/*\n * This field is 1 when all currently selected harts are running.\n */\n#define DM_DMSTATUS_ALLRUNNING_OFFSET       0xb\n#define DM_DMSTATUS_ALLRUNNING_LENGTH       1\n#define DM_DMSTATUS_ALLRUNNING              0x800\n/*\n * This field is 1 when any currently selected hart is running.\n */\n#define DM_DMSTATUS_ANYRUNNING_OFFSET       0xa\n#define DM_DMSTATUS_ANYRUNNING_LENGTH       1\n#define DM_DMSTATUS_ANYRUNNING              0x400\n/*\n * This field is 1 when all currently selected harts are halted.\n */\n#define DM_DMSTATUS_ALLHALTED_OFFSET        9\n#define DM_DMSTATUS_ALLHALTED_LENGTH        1\n#define DM_DMSTATUS_ALLHALTED               0x200\n/*\n * This field is 1 when any currently selected hart is halted.\n */\n#define DM_DMSTATUS_ANYHALTED_OFFSET        8\n#define DM_DMSTATUS_ANYHALTED_LENGTH        1\n#define DM_DMSTATUS_ANYHALTED               0x100\n#define DM_DMSTATUS_AUTHENTICATED_OFFSET    7\n#define DM_DMSTATUS_AUTHENTICATED_LENGTH    1\n#define DM_DMSTATUS_AUTHENTICATED           0x80\n/*\n * false: Authentication is required before using the DM.\n */\n#define DM_DMSTATUS_AUTHENTICATED_FALSE     0\n/*\n * true: The authentication check has passed.\n */\n#define DM_DMSTATUS_AUTHENTICATED_TRUE      1\n/*\n * On components that don't implement authentication, this bit must be\n * preset as 1.\n */\n#define DM_DMSTATUS_AUTHBUSY_OFFSET         6\n#define DM_DMSTATUS_AUTHBUSY_LENGTH         1\n#define DM_DMSTATUS_AUTHBUSY                0x40\n/*\n * ready: The authentication module is ready to process the next\n * read/write to \\RdmAuthdata.\n */\n#define DM_DMSTATUS_AUTHBUSY_READY          0\n/*\n * busy: The authentication module is busy. Accessing \\RdmAuthdata results\n * in unspecified behavior.\n */\n#define DM_DMSTATUS_AUTHBUSY_BUSY           1\n/*\n * \\FdmDmstatusAuthbusy only becomes set in immediate response to an access to\n * \\RdmAuthdata.\n */\n/*\n * 1 if this Debug Module supports halt-on-reset functionality\n * controllable by the \\FdmDmcontrolSetresethaltreq and \\FdmDmcontrolClrresethaltreq bits.\n * 0 otherwise.\n */\n#define DM_DMSTATUS_HASRESETHALTREQ_OFFSET  5\n#define DM_DMSTATUS_HASRESETHALTREQ_LENGTH  1\n#define DM_DMSTATUS_HASRESETHALTREQ         0x20\n#define DM_DMSTATUS_CONFSTRPTRVALID_OFFSET  4\n#define DM_DMSTATUS_CONFSTRPTRVALID_LENGTH  1\n#define DM_DMSTATUS_CONFSTRPTRVALID         0x10\n/*\n * invalid: \\RdmConfstrptrZero--\\RdmConfstrptrThree hold information which\n * is not relevant to the configuration structure.\n */\n#define DM_DMSTATUS_CONFSTRPTRVALID_INVALID 0\n/*\n * valid: \\RdmConfstrptrZero--\\RdmConfstrptrThree hold the address of the\n * configuration structure.\n */\n#define DM_DMSTATUS_CONFSTRPTRVALID_VALID   1\n#define DM_DMSTATUS_VERSION_OFFSET          0\n#define DM_DMSTATUS_VERSION_LENGTH          4\n#define DM_DMSTATUS_VERSION                 0xf\n/*\n * none: There is no Debug Module present.\n */\n#define DM_DMSTATUS_VERSION_NONE            0\n/*\n * 0.11: There is a Debug Module and it conforms to version 0.11 of this\n * specification.\n */\n#define DM_DMSTATUS_VERSION_0_11            1\n/*\n * 0.13: There is a Debug Module and it conforms to version 0.13 of this\n * specification.\n */\n#define DM_DMSTATUS_VERSION_0_13            2\n/*\n * 1.0: There is a Debug Module and it conforms to version 1.0 of this\n * specification.\n */\n#define DM_DMSTATUS_VERSION_1_0             3\n/*\n * custom: There is a Debug Module but it does not conform to any\n * available version of this spec.\n */\n#define DM_DMSTATUS_VERSION_CUSTOM          15\n#define DM_DMCONTROL                        0x10\n/*\n * Writing 0 clears the halt request bit for all currently selected\n * harts. This may cancel outstanding halt requests for those harts.\n *\n * Writing 1 sets the halt request bit for all currently selected\n * harts. Running harts will halt whenever their halt request bit is\n * set.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_HALTREQ_OFFSET         0x1f\n#define DM_DMCONTROL_HALTREQ_LENGTH         1\n#define DM_DMCONTROL_HALTREQ                0x80000000U\n/*\n * Writing 1 causes the currently selected harts to resume once, if\n * they are halted when the write occurs. It also clears the resume\n * ack bit for those harts.\n *\n * \\FdmDmcontrolResumereq is ignored if \\FdmDmcontrolHaltreq is set.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_RESUMEREQ_OFFSET       0x1e\n#define DM_DMCONTROL_RESUMEREQ_LENGTH       1\n#define DM_DMCONTROL_RESUMEREQ              0x40000000\n/*\n * This optional field writes the reset bit for all the currently\n * selected harts.  To perform a reset the debugger writes 1, and then\n * writes 0 to deassert the reset signal.\n *\n * While this bit is 1, the debugger must not change which harts are\n * selected.\n *\n * If this feature is not implemented, the bit always stays 0, so\n * after writing 1 the debugger can read the register back to see if\n * the feature is supported.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_HARTRESET_OFFSET       0x1d\n#define DM_DMCONTROL_HARTRESET_LENGTH       1\n#define DM_DMCONTROL_HARTRESET              0x20000000\n#define DM_DMCONTROL_ACKHAVERESET_OFFSET    0x1c\n#define DM_DMCONTROL_ACKHAVERESET_LENGTH    1\n#define DM_DMCONTROL_ACKHAVERESET           0x10000000\n/*\n * nop: No effect.\n */\n#define DM_DMCONTROL_ACKHAVERESET_NOP       0\n/*\n * ack: Clears {\\tt havereset} for any selected harts.\n */\n#define DM_DMCONTROL_ACKHAVERESET_ACK       1\n/*\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_ACKUNAVAIL_OFFSET      0x1b\n#define DM_DMCONTROL_ACKUNAVAIL_LENGTH      1\n#define DM_DMCONTROL_ACKUNAVAIL             0x8000000\n/*\n * nop: No effect.\n */\n#define DM_DMCONTROL_ACKUNAVAIL_NOP         0\n/*\n * ack: Clears {\\tt unavail} for any selected harts that are currently available.\n */\n#define DM_DMCONTROL_ACKUNAVAIL_ACK         1\n/*\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n/*\n * Selects the definition of currently selected harts.\n */\n#define DM_DMCONTROL_HASEL_OFFSET           0x1a\n#define DM_DMCONTROL_HASEL_LENGTH           1\n#define DM_DMCONTROL_HASEL                  0x4000000\n/*\n * single: There is a single currently selected hart, that is selected by \\Fhartsel.\n */\n#define DM_DMCONTROL_HASEL_SINGLE           0\n/*\n * multiple: There may be multiple currently selected harts -- the hart\n * selected by \\Fhartsel, plus those selected by the hart array mask\n * register.\n */\n#define DM_DMCONTROL_HASEL_MULTIPLE         1\n/*\n * An implementation which does not implement the hart array mask register\n * must tie this field to 0. A debugger which wishes to use the hart array\n * mask register feature should set this bit and read back to see if the functionality\n * is supported.\n */\n/*\n * The low 10 bits of \\Fhartsel: the DM-specific index of the hart to\n * select. This hart is always part of the currently selected harts.\n */\n#define DM_DMCONTROL_HARTSELLO_OFFSET       0x10\n#define DM_DMCONTROL_HARTSELLO_LENGTH       0xa\n#define DM_DMCONTROL_HARTSELLO              0x3ff0000\n/*\n * The high 10 bits of \\Fhartsel: the DM-specific index of the hart to\n * select. This hart is always part of the currently selected harts.\n */\n#define DM_DMCONTROL_HARTSELHI_OFFSET       6\n#define DM_DMCONTROL_HARTSELHI_LENGTH       0xa\n#define DM_DMCONTROL_HARTSELHI              0xffc0\n/*\n * This optional field sets \\Fkeepalive for all currently selected\n * harts, unless \\FdmDmcontrolClrkeepalive is simultaneously set to\n * 1.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_SETKEEPALIVE_OFFSET    5\n#define DM_DMCONTROL_SETKEEPALIVE_LENGTH    1\n#define DM_DMCONTROL_SETKEEPALIVE           0x20\n/*\n * This optional field clears \\Fkeepalive for all currently selected\n * harts.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_CLRKEEPALIVE_OFFSET    4\n#define DM_DMCONTROL_CLRKEEPALIVE_LENGTH    1\n#define DM_DMCONTROL_CLRKEEPALIVE           0x10\n/*\n * This optional field writes the halt-on-reset request bit for all\n * currently selected harts, unless \\FdmDmcontrolClrresethaltreq is\n * simultaneously set to 1.\n * When set to 1, each selected hart will halt upon the next deassertion\n * of its reset. The halt-on-reset request bit is not automatically\n * cleared. The debugger must write to \\FdmDmcontrolClrresethaltreq to clear it.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n *\n * If \\FdmDmstatusHasresethaltreq is 0, this field is not implemented.\n */\n#define DM_DMCONTROL_SETRESETHALTREQ_OFFSET 3\n#define DM_DMCONTROL_SETRESETHALTREQ_LENGTH 1\n#define DM_DMCONTROL_SETRESETHALTREQ        8\n/*\n * This optional field clears the halt-on-reset request bit for all\n * currently selected harts.\n *\n * Writes apply to the new value of \\Fhartsel and \\FdmDmcontrolHasel.\n */\n#define DM_DMCONTROL_CLRRESETHALTREQ_OFFSET 2\n#define DM_DMCONTROL_CLRRESETHALTREQ_LENGTH 1\n#define DM_DMCONTROL_CLRRESETHALTREQ        4\n/*\n * This bit controls the reset signal from the DM to the rest of the\n * hardware platform. The signal should reset every part of the hardware platform, including\n * every hart, except for the DM and any logic required to access the\n * DM.\n * To perform a hardware platform reset the debugger writes 1,\n * and then writes 0\n * to deassert the reset.\n */\n#define DM_DMCONTROL_NDMRESET_OFFSET        1\n#define DM_DMCONTROL_NDMRESET_LENGTH        1\n#define DM_DMCONTROL_NDMRESET               2\n/*\n * This bit serves as a reset signal for the Debug Module itself.\n * After changing the value of this bit, the debugger must poll\n * \\RdmDmcontrol until \\FdmDmcontrolDmactive has taken the requested value\n * before performing any action that assumes the requested \\FdmDmcontrolDmactive\n * state change has completed.  Hardware may\n * take an arbitrarily long time to complete activation or deactivation and will\n * indicate completion by setting \\FdmDmcontrolDmactive to the requested value.\n */\n#define DM_DMCONTROL_DMACTIVE_OFFSET        0\n#define DM_DMCONTROL_DMACTIVE_LENGTH        1\n#define DM_DMCONTROL_DMACTIVE               1\n/*\n * inactive: The module's state, including authentication mechanism,\n * takes its reset values (the \\FdmDmcontrolDmactive bit is the only bit which can\n * be written to something other than its reset value). Any accesses\n * to the module may fail. Specifically, \\FdmDmstatusVersion might not return\n * correct data.\n */\n#define DM_DMCONTROL_DMACTIVE_INACTIVE      0\n/*\n * active: The module functions normally.\n */\n#define DM_DMCONTROL_DMACTIVE_ACTIVE        1\n/*\n * No other mechanism should exist that may result in resetting the\n * Debug Module after power up.\n *\n * To place the Debug Module into a known state, a debugger may write 0 to \\FdmDmcontrolDmactive,\n * poll until \\FdmDmcontrolDmactive is observed 0, write 1 to \\FdmDmcontrolDmactive, and\n * poll until \\FdmDmcontrolDmactive is observed 1.\n *\n * Implementations may pay attention to this bit to further aid\n * debugging, for example by preventing the Debug Module from being\n * power gated while debugging is active.\n */\n#define DM_HARTINFO                         0x12\n/*\n * Number of {\\tt dscratch} registers available for the debugger\n * to use during program buffer execution, starting from \\RcsrDscratchZero.\n * The debugger can make no assumptions about the contents of these\n * registers between commands.\n */\n#define DM_HARTINFO_NSCRATCH_OFFSET         0x14\n#define DM_HARTINFO_NSCRATCH_LENGTH         4\n#define DM_HARTINFO_NSCRATCH                0xf00000\n#define DM_HARTINFO_DATAACCESS_OFFSET       0x10\n#define DM_HARTINFO_DATAACCESS_LENGTH       1\n#define DM_HARTINFO_DATAACCESS              0x10000\n/*\n * csr: The {\\tt data} registers are shadowed in the hart by CSRs.\n * Each CSR is DXLEN bits in size, and corresponds\n * to a single argument, per Table~\\ref{tab:datareg}.\n */\n#define DM_HARTINFO_DATAACCESS_CSR          0\n/*\n * memory: The {\\tt data} registers are shadowed in the hart's memory map.\n * Each register takes up 4 bytes in the memory map.\n */\n#define DM_HARTINFO_DATAACCESS_MEMORY       1\n/*\n * If \\FdmHartinfoDataaccess is 0: Number of CSRs dedicated to\n * shadowing the {\\tt data} registers.\n *\n * If \\FdmHartinfoDataaccess is 1: Number of 32-bit words in the memory map\n * dedicated to shadowing the {\\tt data} registers.\n *\n * If this value is non-zero, then the {tt data} registers must go\n * beyond being MRs and guarantee they each store a single value, that is\n * readable/writable by either side.\n *\n * Since there are at most 12 {\\tt data} registers, the value in this\n * register must be 12 or smaller.\n */\n#define DM_HARTINFO_DATASIZE_OFFSET         0xc\n#define DM_HARTINFO_DATASIZE_LENGTH         4\n#define DM_HARTINFO_DATASIZE                0xf000\n/*\n * If \\FdmHartinfoDataaccess is 0: The number of the first CSR dedicated to\n * shadowing the {\\tt data} registers.\n *\n * If \\FdmHartinfoDataaccess is 1: Address of RAM where the data\n * registers are shadowed. This address is sign extended giving a\n * range of -2048 to 2047, easily addressed with a load or store using\n * \\Xzero as the address register.\n */\n#define DM_HARTINFO_DATAADDR_OFFSET         0\n#define DM_HARTINFO_DATAADDR_LENGTH         0xc\n#define DM_HARTINFO_DATAADDR                0xfff\n#define DM_HAWINDOWSEL                      0x14\n/*\n * The high bits of this field may be tied to 0, depending on how large\n * the array mask register is.  E.g.\\ on a hardware platform with 48 harts only bit 0\n * of this field may actually be writable.\n */\n#define DM_HAWINDOWSEL_HAWINDOWSEL_OFFSET   0\n#define DM_HAWINDOWSEL_HAWINDOWSEL_LENGTH   0xf\n#define DM_HAWINDOWSEL_HAWINDOWSEL          0x7fff\n#define DM_HAWINDOW                         0x15\n#define DM_HAWINDOW_MASKDATA_OFFSET         0\n#define DM_HAWINDOW_MASKDATA_LENGTH         0x20\n#define DM_HAWINDOW_MASKDATA                0xffffffffU\n#define DM_ABSTRACTCS                       0x16\n/*\n * Size of the Program Buffer, in 32-bit words. Valid sizes are 0 - 16.\n */\n#define DM_ABSTRACTCS_PROGBUFSIZE_OFFSET    0x18\n#define DM_ABSTRACTCS_PROGBUFSIZE_LENGTH    5\n#define DM_ABSTRACTCS_PROGBUFSIZE           0x1f000000\n#define DM_ABSTRACTCS_BUSY_OFFSET           0xc\n#define DM_ABSTRACTCS_BUSY_LENGTH           1\n#define DM_ABSTRACTCS_BUSY                  0x1000\n/*\n * ready: There is no abstract command currently being executed.\n */\n#define DM_ABSTRACTCS_BUSY_READY            0\n/*\n * busy: An abstract command is currently being executed.\n */\n#define DM_ABSTRACTCS_BUSY_BUSY             1\n/*\n * This bit is set as soon as \\RdmCommand is written, and is\n * not cleared until that command has completed.\n */\n/*\n * This optional bit controls whether program buffer and abstract\n * memory accesses are performed with the exact and full set of\n * permission checks that apply based on the current architectural\n * state of the hart performing the access, or with a relaxed set of\n * permission checks (e.g. PMP restrictions are ignored).  The\n * details of the latter are implementation-specific.  When set to 0,\n * full permissions apply; when set to 1, relaxed permissions apply.\n */\n#define DM_ABSTRACTCS_RELAXEDPRIV_OFFSET    0xb\n#define DM_ABSTRACTCS_RELAXEDPRIV_LENGTH    1\n#define DM_ABSTRACTCS_RELAXEDPRIV           0x800\n/*\n * Gets set if an abstract command fails. The bits in this field remain set until\n * they are cleared by writing 1 to them. No abstract command is\n * started until the value is reset to 0.\n *\n * This field only contains a valid value if \\FdmAbstractcsBusy is 0.\n */\n#define DM_ABSTRACTCS_CMDERR_OFFSET         8\n#define DM_ABSTRACTCS_CMDERR_LENGTH         3\n#define DM_ABSTRACTCS_CMDERR                0x700\n/*\n * none: No error.\n */\n#define DM_ABSTRACTCS_CMDERR_NONE           0\n/*\n * busy: An abstract command was executing while \\RdmCommand,\n * \\RdmAbstractcs, or \\RdmAbstractauto was written, or when one\n * of the {\\tt data} or {\\tt progbuf} registers was read or written.\n * This status is only written if \\FdmAbstractcsCmderr contains 0.\n */\n#define DM_ABSTRACTCS_CMDERR_BUSY           1\n/*\n * not supported: The command in \\RdmCommand is not supported.  It\n * may be supported with different options set, but it will not be\n * supported at a later time when the hart or system state are\n * different.\n */\n#define DM_ABSTRACTCS_CMDERR_NOT_SUPPORTED  2\n/*\n * exception: An exception occurred while executing the command\n * (e.g.\\ while executing the Program Buffer).\n */\n#define DM_ABSTRACTCS_CMDERR_EXCEPTION      3\n/*\n * halt/resume: The abstract command couldn't execute because the\n * hart wasn't in the required state (running/halted), or unavailable.\n */\n#define DM_ABSTRACTCS_CMDERR_HALT_RESUME    4\n/*\n * bus: The abstract command failed due to a bus error (e.g.\\\n * alignment, access size, or timeout).\n */\n#define DM_ABSTRACTCS_CMDERR_BUS            5\n/*\n * reserved: Reserved for future use.\n */\n#define DM_ABSTRACTCS_CMDERR_RESERVED       6\n/*\n * other: The command failed for another reason.\n */\n#define DM_ABSTRACTCS_CMDERR_OTHER          7\n/*\n * Number of {\\tt data} registers that are implemented as part of the\n * abstract command interface. Valid sizes are 1 -- 12.\n */\n#define DM_ABSTRACTCS_DATACOUNT_OFFSET      0\n#define DM_ABSTRACTCS_DATACOUNT_LENGTH      4\n#define DM_ABSTRACTCS_DATACOUNT             0xf\n#define DM_COMMAND                          0x17\n/*\n * The type determines the overall functionality of this\n * abstract command.\n */\n#define DM_COMMAND_CMDTYPE_OFFSET           0x18\n#define DM_COMMAND_CMDTYPE_LENGTH           8\n#define DM_COMMAND_CMDTYPE                  0xff000000U\n/*\n * This field is interpreted in a command-specific manner,\n * described for each abstract command.\n */\n#define DM_COMMAND_CONTROL_OFFSET           0\n#define DM_COMMAND_CONTROL_LENGTH           0x18\n#define DM_COMMAND_CONTROL                  0xffffff\n#define DM_ABSTRACTAUTO                     0x18\n/*\n * When a bit in this field is 1, read or write accesses to the\n * corresponding {\\tt progbuf} word cause the DM to act as if the\n * current value in \\RdmCommand was written there again after the\n * access to {\\tt progbuf} completes.\n */\n#define DM_ABSTRACTAUTO_AUTOEXECPROGBUF_OFFSET 0x10\n#define DM_ABSTRACTAUTO_AUTOEXECPROGBUF_LENGTH 0x10\n#define DM_ABSTRACTAUTO_AUTOEXECPROGBUF     0xffff0000U\n/*\n * When a bit in this field is 1, read or write accesses to the\n * corresponding {\\tt data} word cause the DM to act as if the current\n * value in \\RdmCommand was written there again after the\n * access to {\\tt data} completes.\n */\n#define DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET 0\n#define DM_ABSTRACTAUTO_AUTOEXECDATA_LENGTH 0xc\n#define DM_ABSTRACTAUTO_AUTOEXECDATA        0xfff\n#define DM_CONFSTRPTR0                      0x19\n#define DM_CONFSTRPTR0_ADDR_OFFSET          0\n#define DM_CONFSTRPTR0_ADDR_LENGTH          0x20\n#define DM_CONFSTRPTR0_ADDR                 0xffffffffU\n#define DM_CONFSTRPTR1                      0x1a\n#define DM_CONFSTRPTR1_ADDR_OFFSET          0\n#define DM_CONFSTRPTR1_ADDR_LENGTH          0x20\n#define DM_CONFSTRPTR1_ADDR                 0xffffffffU\n#define DM_CONFSTRPTR2                      0x1b\n#define DM_CONFSTRPTR2_ADDR_OFFSET          0\n#define DM_CONFSTRPTR2_ADDR_LENGTH          0x20\n#define DM_CONFSTRPTR2_ADDR                 0xffffffffU\n#define DM_CONFSTRPTR3                      0x1c\n#define DM_CONFSTRPTR3_ADDR_OFFSET          0\n#define DM_CONFSTRPTR3_ADDR_LENGTH          0x20\n#define DM_CONFSTRPTR3_ADDR                 0xffffffffU\n#define DM_NEXTDM                           0x1d\n#define DM_NEXTDM_ADDR_OFFSET               0\n#define DM_NEXTDM_ADDR_LENGTH               0x20\n#define DM_NEXTDM_ADDR                      0xffffffffU\n#define DM_DATA0                            0x04\n#define DM_DATA0_DATA_OFFSET                0\n#define DM_DATA0_DATA_LENGTH                0x20\n#define DM_DATA0_DATA                       0xffffffffU\n#define DM_DATA1                            0x05\n#define DM_DATA2                            0x06\n#define DM_DATA3                            0x07\n#define DM_DATA4                            0x08\n#define DM_DATA5                            0x09\n#define DM_DATA6                            0x0a\n#define DM_DATA7                            0x0b\n#define DM_DATA8                            0x0c\n#define DM_DATA9                            0x0d\n#define DM_DATA10                           0x0e\n#define DM_DATA11                           0x0f\n#define DM_PROGBUF0                         0x20\n#define DM_PROGBUF0_DATA_OFFSET             0\n#define DM_PROGBUF0_DATA_LENGTH             0x20\n#define DM_PROGBUF0_DATA                    0xffffffffU\n#define DM_PROGBUF1                         0x21\n#define DM_PROGBUF2                         0x22\n#define DM_PROGBUF3                         0x23\n#define DM_PROGBUF4                         0x24\n#define DM_PROGBUF5                         0x25\n#define DM_PROGBUF6                         0x26\n#define DM_PROGBUF7                         0x27\n#define DM_PROGBUF8                         0x28\n#define DM_PROGBUF9                         0x29\n#define DM_PROGBUF10                        0x2a\n#define DM_PROGBUF11                        0x2b\n#define DM_PROGBUF12                        0x2c\n#define DM_PROGBUF13                        0x2d\n#define DM_PROGBUF14                        0x2e\n#define DM_PROGBUF15                        0x2f\n#define DM_AUTHDATA                         0x30\n#define DM_AUTHDATA_DATA_OFFSET             0\n#define DM_AUTHDATA_DATA_LENGTH             0x20\n#define DM_AUTHDATA_DATA                    0xffffffffU\n#define DM_DMCS2                            0x32\n#define DM_DMCS2_GROUPTYPE_OFFSET           0xb\n#define DM_DMCS2_GROUPTYPE_LENGTH           1\n#define DM_DMCS2_GROUPTYPE                  0x800\n/*\n * halt: The remaining fields in this register configure halt groups.\n */\n#define DM_DMCS2_GROUPTYPE_HALT             0\n/*\n * resume: The remaining fields in this register configure resume groups.\n */\n#define DM_DMCS2_GROUPTYPE_RESUME           1\n/*\n * This field contains the currently selected DM external trigger.\n *\n * If a non-existent trigger value is written here, the hardware will\n * change it to a valid one or 0 if no DM external triggers exist.\n */\n#define DM_DMCS2_DMEXTTRIGGER_OFFSET        7\n#define DM_DMCS2_DMEXTTRIGGER_LENGTH        4\n#define DM_DMCS2_DMEXTTRIGGER               0x780\n/*\n * When \\FdmDmcsTwoHgselect is 0, contains the group of the hart\n * specified by \\Fhartsel.\n *\n * When \\FdmDmcsTwoHgselect is 1, contains the group of the DM external\n * trigger selected by \\FdmDmcsTwoDmexttrigger.\n *\n * The value written to this field is ignored unless \\FdmDmcsTwoHgwrite\n * is also written 1.\n *\n * Group numbers are contiguous starting at 0, with the highest number\n * being implementation-dependent, and possibly different between\n * different group types. Debuggers should read back this field after\n * writing to confirm they are using a hart group that is supported.\n *\n * If groups aren't implemented, then this entire field is 0.\n */\n#define DM_DMCS2_GROUP_OFFSET               2\n#define DM_DMCS2_GROUP_LENGTH               5\n#define DM_DMCS2_GROUP                      0x7c\n/*\n * When 1 is written and \\FdmDmcsTwoHgselect is 0, for every selected\n * hart the DM will change its group to the value written to \\FdmDmcsTwoGroup,\n * if the hardware supports that group for that hart.\n * Implementations may also change the group of a minimal set of\n * unselected harts in the same way, if that is necessary due to\n * a hardware limitation.\n *\n * When 1 is written and \\FdmDmcsTwoHgselect is 1, the DM will change\n * the group of the DM external trigger selected by \\FdmDmcsTwoDmexttrigger\n * to the value written to \\FdmDmcsTwoGroup, if the hardware supports\n * that group for that trigger.\n *\n * Writing 0 has no effect.\n */\n#define DM_DMCS2_HGWRITE_OFFSET             1\n#define DM_DMCS2_HGWRITE_LENGTH             1\n#define DM_DMCS2_HGWRITE                    2\n#define DM_DMCS2_HGSELECT_OFFSET            0\n#define DM_DMCS2_HGSELECT_LENGTH            1\n#define DM_DMCS2_HGSELECT                   1\n/*\n * harts: Operate on harts.\n */\n#define DM_DMCS2_HGSELECT_HARTS             0\n/*\n * triggers: Operate on DM external triggers.\n */\n#define DM_DMCS2_HGSELECT_TRIGGERS          1\n/*\n * If there are no DM external triggers, this field must be tied to 0.\n */\n#define DM_HALTSUM0                         0x40\n#define DM_HALTSUM0_HALTSUM0_OFFSET         0\n#define DM_HALTSUM0_HALTSUM0_LENGTH         0x20\n#define DM_HALTSUM0_HALTSUM0                0xffffffffU\n#define DM_HALTSUM1                         0x13\n#define DM_HALTSUM1_HALTSUM1_OFFSET         0\n#define DM_HALTSUM1_HALTSUM1_LENGTH         0x20\n#define DM_HALTSUM1_HALTSUM1                0xffffffffU\n#define DM_HALTSUM2                         0x34\n#define DM_HALTSUM2_HALTSUM2_OFFSET         0\n#define DM_HALTSUM2_HALTSUM2_LENGTH         0x20\n#define DM_HALTSUM2_HALTSUM2                0xffffffffU\n#define DM_HALTSUM3                         0x35\n#define DM_HALTSUM3_HALTSUM3_OFFSET         0\n#define DM_HALTSUM3_HALTSUM3_LENGTH         0x20\n#define DM_HALTSUM3_HALTSUM3                0xffffffffU\n#define DM_SBCS                             0x38\n#define DM_SBCS_SBVERSION_OFFSET            0x1d\n#define DM_SBCS_SBVERSION_LENGTH            3\n#define DM_SBCS_SBVERSION                   0xe0000000U\n/*\n * legacy: The System Bus interface conforms to mainline drafts of this\n * spec older than 1 January, 2018.\n */\n#define DM_SBCS_SBVERSION_LEGACY            0\n/*\n * 1.0: The System Bus interface conforms to this version of the spec.\n */\n#define DM_SBCS_SBVERSION_1_0               1\n/*\n * Other values are reserved for future versions.\n */\n/*\n * Set when the debugger attempts to read data while a read is in\n * progress, or when the debugger initiates a new access while one is\n * already in progress (while \\FdmSbcsSbbusy is set). It remains set until\n * it's explicitly cleared by the debugger.\n *\n * While this field is set, no more system bus accesses can be\n * initiated by the Debug Module.\n */\n#define DM_SBCS_SBBUSYERROR_OFFSET          0x16\n#define DM_SBCS_SBBUSYERROR_LENGTH          1\n#define DM_SBCS_SBBUSYERROR                 0x400000\n/*\n * When 1, indicates the system bus master is busy. (Whether the\n * system bus itself is busy is related, but not the same thing.) This\n * bit goes high immediately when a read or write is requested for any\n * reason, and does not go low until the access is fully completed.\n *\n * Writes to \\RdmSbcs while \\FdmSbcsSbbusy is high result in undefined\n * behavior.  A debugger must not write to \\RdmSbcs until it reads\n * \\FdmSbcsSbbusy as 0.\n */\n#define DM_SBCS_SBBUSY_OFFSET               0x15\n#define DM_SBCS_SBBUSY_LENGTH               1\n#define DM_SBCS_SBBUSY                      0x200000\n/*\n * When 1, every write to \\RdmSbaddressZero automatically triggers a\n * system bus read at the new address.\n */\n#define DM_SBCS_SBREADONADDR_OFFSET         0x14\n#define DM_SBCS_SBREADONADDR_LENGTH         1\n#define DM_SBCS_SBREADONADDR                0x100000\n/*\n * Select the access size to use for system bus accesses.\n */\n#define DM_SBCS_SBACCESS_OFFSET             0x11\n#define DM_SBCS_SBACCESS_LENGTH             3\n#define DM_SBCS_SBACCESS                    0xe0000\n/*\n * 8bit: 8-bit\n */\n#define DM_SBCS_SBACCESS_8BIT               0\n/*\n * 16bit: 16-bit\n */\n#define DM_SBCS_SBACCESS_16BIT              1\n/*\n * 32bit: 32-bit\n */\n#define DM_SBCS_SBACCESS_32BIT              2\n/*\n * 64bit: 64-bit\n */\n#define DM_SBCS_SBACCESS_64BIT              3\n/*\n * 128bit: 128-bit\n */\n#define DM_SBCS_SBACCESS_128BIT             4\n/*\n * If \\FdmSbcsSbaccess has an unsupported value when the DM starts a bus\n * access, the access is not performed and \\FdmSbcsSberror is set to 4.\n */\n/*\n * When 1, {\\tt sbaddress} is incremented by the access size (in\n * bytes) selected in \\FdmSbcsSbaccess after every system bus access.\n */\n#define DM_SBCS_SBAUTOINCREMENT_OFFSET      0x10\n#define DM_SBCS_SBAUTOINCREMENT_LENGTH      1\n#define DM_SBCS_SBAUTOINCREMENT             0x10000\n/*\n * When 1, every read from \\RdmSbdataZero automatically triggers a\n * system bus read at the (possibly auto-incremented) address.\n */\n#define DM_SBCS_SBREADONDATA_OFFSET         0xf\n#define DM_SBCS_SBREADONDATA_LENGTH         1\n#define DM_SBCS_SBREADONDATA                0x8000\n/*\n * When the Debug Module's system bus\n * master encounters an error, this field gets set. The bits in this\n * field remain set until they are cleared by writing 1 to them.\n * While this field is non-zero, no more system bus accesses can be\n * initiated by the Debug Module.\n *\n * An implementation may report ``Other'' (7) for any error condition.\n */\n#define DM_SBCS_SBERROR_OFFSET              0xc\n#define DM_SBCS_SBERROR_LENGTH              3\n#define DM_SBCS_SBERROR                     0x7000\n/*\n * none: There was no bus error.\n */\n#define DM_SBCS_SBERROR_NONE                0\n/*\n * timeout: There was a timeout.\n */\n#define DM_SBCS_SBERROR_TIMEOUT             1\n/*\n * address: A bad address was accessed.\n */\n#define DM_SBCS_SBERROR_ADDRESS             2\n/*\n * alignment: There was an alignment error.\n */\n#define DM_SBCS_SBERROR_ALIGNMENT           3\n/*\n * size: An access of unsupported size was requested.\n */\n#define DM_SBCS_SBERROR_SIZE                4\n/*\n * other: Other.\n */\n#define DM_SBCS_SBERROR_OTHER               7\n/*\n * Width of system bus addresses in bits. (0 indicates there is no bus\n * access support.)\n */\n#define DM_SBCS_SBASIZE_OFFSET              5\n#define DM_SBCS_SBASIZE_LENGTH              7\n#define DM_SBCS_SBASIZE                     0xfe0\n/*\n * 1 when 128-bit system bus accesses are supported.\n */\n#define DM_SBCS_SBACCESS128_OFFSET          4\n#define DM_SBCS_SBACCESS128_LENGTH          1\n#define DM_SBCS_SBACCESS128                 0x10\n/*\n * 1 when 64-bit system bus accesses are supported.\n */\n#define DM_SBCS_SBACCESS64_OFFSET           3\n#define DM_SBCS_SBACCESS64_LENGTH           1\n#define DM_SBCS_SBACCESS64                  8\n/*\n * 1 when 32-bit system bus accesses are supported.\n */\n#define DM_SBCS_SBACCESS32_OFFSET           2\n#define DM_SBCS_SBACCESS32_LENGTH           1\n#define DM_SBCS_SBACCESS32                  4\n/*\n * 1 when 16-bit system bus accesses are supported.\n */\n#define DM_SBCS_SBACCESS16_OFFSET           1\n#define DM_SBCS_SBACCESS16_LENGTH           1\n#define DM_SBCS_SBACCESS16                  2\n/*\n * 1 when 8-bit system bus accesses are supported.\n */\n#define DM_SBCS_SBACCESS8_OFFSET            0\n#define DM_SBCS_SBACCESS8_LENGTH            1\n#define DM_SBCS_SBACCESS8                   1\n#define DM_SBADDRESS0                       0x39\n/*\n * Accesses bits 31:0 of the physical address in {\\tt sbaddress}.\n */\n#define DM_SBADDRESS0_ADDRESS_OFFSET        0\n#define DM_SBADDRESS0_ADDRESS_LENGTH        0x20\n#define DM_SBADDRESS0_ADDRESS               0xffffffffU\n#define DM_SBADDRESS1                       0x3a\n/*\n * Accesses bits 63:32 of the physical address in {\\tt sbaddress} (if\n * the system address bus is that wide).\n */\n#define DM_SBADDRESS1_ADDRESS_OFFSET        0\n#define DM_SBADDRESS1_ADDRESS_LENGTH        0x20\n#define DM_SBADDRESS1_ADDRESS               0xffffffffU\n#define DM_SBADDRESS2                       0x3b\n/*\n * Accesses bits 95:64 of the physical address in {\\tt sbaddress} (if\n * the system address bus is that wide).\n */\n#define DM_SBADDRESS2_ADDRESS_OFFSET        0\n#define DM_SBADDRESS2_ADDRESS_LENGTH        0x20\n#define DM_SBADDRESS2_ADDRESS               0xffffffffU\n#define DM_SBADDRESS3                       0x37\n/*\n * Accesses bits 127:96 of the physical address in {\\tt sbaddress} (if\n * the system address bus is that wide).\n */\n#define DM_SBADDRESS3_ADDRESS_OFFSET        0\n#define DM_SBADDRESS3_ADDRESS_LENGTH        0x20\n#define DM_SBADDRESS3_ADDRESS               0xffffffffU\n#define DM_SBDATA0                          0x3c\n/*\n * Accesses bits 31:0 of {\\tt sbdata}.\n */\n#define DM_SBDATA0_DATA_OFFSET              0\n#define DM_SBDATA0_DATA_LENGTH              0x20\n#define DM_SBDATA0_DATA                     0xffffffffU\n#define DM_SBDATA1                          0x3d\n/*\n * Accesses bits 63:32 of {\\tt sbdata} (if the system bus is that\n * wide).\n */\n#define DM_SBDATA1_DATA_OFFSET              0\n#define DM_SBDATA1_DATA_LENGTH              0x20\n#define DM_SBDATA1_DATA                     0xffffffffU\n#define DM_SBDATA2                          0x3e\n/*\n * Accesses bits 95:64 of {\\tt sbdata} (if the system bus is that\n * wide).\n */\n#define DM_SBDATA2_DATA_OFFSET              0\n#define DM_SBDATA2_DATA_LENGTH              0x20\n#define DM_SBDATA2_DATA                     0xffffffffU\n#define DM_SBDATA3                          0x3f\n/*\n * Accesses bits 127:96 of {\\tt sbdata} (if the system bus is that\n * wide).\n */\n#define DM_SBDATA3_DATA_OFFSET              0\n#define DM_SBDATA3_DATA_LENGTH              0x20\n#define DM_SBDATA3_DATA                     0xffffffffU\n#define DM_CUSTOM                           0x1f\n#define DM_CUSTOM0                          0x70\n#define DM_CUSTOM1                          0x71\n#define DM_CUSTOM2                          0x72\n#define DM_CUSTOM3                          0x73\n#define DM_CUSTOM4                          0x74\n#define DM_CUSTOM5                          0x75\n#define DM_CUSTOM6                          0x76\n#define DM_CUSTOM7                          0x77\n#define DM_CUSTOM8                          0x78\n#define DM_CUSTOM9                          0x79\n#define DM_CUSTOM10                         0x7a\n#define DM_CUSTOM11                         0x7b\n#define DM_CUSTOM12                         0x7c\n#define DM_CUSTOM13                         0x7d\n#define DM_CUSTOM14                         0x7e\n#define DM_CUSTOM15                         0x7f\n#define SHORTNAME                           0x123\n/*\n * Description of what this field is used for.\n */\n#define SHORTNAME_FIELD_OFFSET              0\n#define SHORTNAME_FIELD_LENGTH              8\n#define SHORTNAME_FIELD                     0xff\n/*\n * This is 0 to indicate Access Register Command.\n */\n#define AC_ACCESS_REGISTER_CMDTYPE_OFFSET   0x18\n#define AC_ACCESS_REGISTER_CMDTYPE_LENGTH   8\n#define AC_ACCESS_REGISTER_CMDTYPE          0xff000000U\n#define AC_ACCESS_REGISTER_AARSIZE_OFFSET   0x14\n#define AC_ACCESS_REGISTER_AARSIZE_LENGTH   3\n#define AC_ACCESS_REGISTER_AARSIZE          0x700000\n/*\n * 32bit: Access the lowest 32 bits of the register.\n */\n#define AC_ACCESS_REGISTER_AARSIZE_32BIT    2\n/*\n * 64bit: Access the lowest 64 bits of the register.\n */\n#define AC_ACCESS_REGISTER_AARSIZE_64BIT    3\n/*\n * 128bit: Access the lowest 128 bits of the register.\n */\n#define AC_ACCESS_REGISTER_AARSIZE_128BIT   4\n/*\n * If \\FacAccessregisterAarsize specifies a size larger than the register's actual size,\n * then the access must fail. If a register is accessible, then reads of \\FacAccessregisterAarsize\n * less than or equal to the register's actual size must be supported.\n * Writing less than the full register may be supported, but what\n * happens to the high bits in that case is \\unspecified.\n *\n * This field controls the Argument Width as referenced in\n * Table~\\ref{tab:datareg}.\n */\n#define AC_ACCESS_REGISTER_AARPOSTINCREMENT_OFFSET 0x13\n#define AC_ACCESS_REGISTER_AARPOSTINCREMENT_LENGTH 1\n#define AC_ACCESS_REGISTER_AARPOSTINCREMENT 0x80000\n/*\n * disabled: No effect. This variant must be supported.\n */\n#define AC_ACCESS_REGISTER_AARPOSTINCREMENT_DISABLED 0\n/*\n * enabled: After a successful register access, \\FacAccessregisterRegno is\n * incremented. Incrementing past the highest supported value\n * causes \\FacAccessregisterRegno to become \\unspecified.  Supporting\n * this variant is optional. It is undefined whether the increment\n * happens when \\FacAccessregisterTransfer is 0.\n */\n#define AC_ACCESS_REGISTER_AARPOSTINCREMENT_ENABLED 1\n#define AC_ACCESS_REGISTER_POSTEXEC_OFFSET  0x12\n#define AC_ACCESS_REGISTER_POSTEXEC_LENGTH  1\n#define AC_ACCESS_REGISTER_POSTEXEC         0x40000\n/*\n * disabled: No effect. This variant must be supported, and is the only\n * supported one if \\FdmAbstractcsProgbufsize is 0.\n */\n#define AC_ACCESS_REGISTER_POSTEXEC_DISABLED 0\n/*\n * enabled: Execute the program in the Program Buffer exactly once after\n * performing the transfer, if any. Supporting this variant is\n * optional.\n */\n#define AC_ACCESS_REGISTER_POSTEXEC_ENABLED 1\n#define AC_ACCESS_REGISTER_TRANSFER_OFFSET  0x11\n#define AC_ACCESS_REGISTER_TRANSFER_LENGTH  1\n#define AC_ACCESS_REGISTER_TRANSFER         0x20000\n/*\n * disabled: Don't do the operation specified by \\FacAccessregisterWrite.\n */\n#define AC_ACCESS_REGISTER_TRANSFER_DISABLED 0\n/*\n * enabled: Do the operation specified by \\FacAccessregisterWrite.\n */\n#define AC_ACCESS_REGISTER_TRANSFER_ENABLED 1\n/*\n * This bit can be used to just execute the Program Buffer without\n * having to worry about placing valid values into \\FacAccessregisterAarsize or \\FacAccessregisterRegno.\n */\n/*\n * When \\FacAccessregisterTransfer is set:\n */\n#define AC_ACCESS_REGISTER_WRITE_OFFSET     0x10\n#define AC_ACCESS_REGISTER_WRITE_LENGTH     1\n#define AC_ACCESS_REGISTER_WRITE            0x10000\n/*\n * arg0: Copy data from the specified register into {\\tt arg0} portion\n * of {\\tt data}.\n */\n#define AC_ACCESS_REGISTER_WRITE_ARG0       0\n/*\n * register: Copy data from {\\tt arg0} portion of {\\tt data} into the\n * specified register.\n */\n#define AC_ACCESS_REGISTER_WRITE_REGISTER   1\n/*\n * Number of the register to access, as described in\n * Table~\\ref{tab:regno}.\n * \\RcsrDpc may be used as an alias for PC if this command is\n * supported on a non-halted hart.\n */\n#define AC_ACCESS_REGISTER_REGNO_OFFSET     0\n#define AC_ACCESS_REGISTER_REGNO_LENGTH     0x10\n#define AC_ACCESS_REGISTER_REGNO            0xffff\n/*\n * This is 1 to indicate Quick Access command.\n */\n#define AC_QUICK_ACCESS_CMDTYPE_OFFSET      0x18\n#define AC_QUICK_ACCESS_CMDTYPE_LENGTH      8\n#define AC_QUICK_ACCESS_CMDTYPE             0xff000000U\n/*\n * This is 2 to indicate Access Memory Command.\n */\n#define AC_ACCESS_MEMORY_CMDTYPE_OFFSET     0x18\n#define AC_ACCESS_MEMORY_CMDTYPE_LENGTH     8\n#define AC_ACCESS_MEMORY_CMDTYPE            0xff000000U\n/*\n * An implementation does not have to implement both virtual and\n * physical accesses, but it must fail accesses that it doesn't\n * support.\n */\n#define AC_ACCESS_MEMORY_AAMVIRTUAL_OFFSET  0x17\n#define AC_ACCESS_MEMORY_AAMVIRTUAL_LENGTH  1\n#define AC_ACCESS_MEMORY_AAMVIRTUAL         0x800000\n/*\n * physical: Addresses are physical (to the hart they are performed on).\n */\n#define AC_ACCESS_MEMORY_AAMVIRTUAL_PHYSICAL 0\n/*\n * virtual: Addresses are virtual, and translated the way they would be from\n * M-mode, with \\FcsrMstatusMprv set.\n */\n#define AC_ACCESS_MEMORY_AAMVIRTUAL_VIRTUAL 1\n/*\n * Debug Modules on systems without address translation (i.e. virtual addresses equal physical)\n * may optionally allow \\FacAccessmemoryAamvirtual set to 1, which would produce the same result as\n * that same abstract command with \\FacAccessmemoryAamvirtual cleared.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_OFFSET     0x14\n#define AC_ACCESS_MEMORY_AAMSIZE_LENGTH     3\n#define AC_ACCESS_MEMORY_AAMSIZE            0x700000\n/*\n * 8bit: Access the lowest 8 bits of the memory location.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_8BIT       0\n/*\n * 16bit: Access the lowest 16 bits of the memory location.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_16BIT      1\n/*\n * 32bit: Access the lowest 32 bits of the memory location.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_32BIT      2\n/*\n * 64bit: Access the lowest 64 bits of the memory location.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_64BIT      3\n/*\n * 128bit: Access the lowest 128 bits of the memory location.\n */\n#define AC_ACCESS_MEMORY_AAMSIZE_128BIT     4\n/*\n * After a memory access has completed, if this bit is 1, increment\n * {\\tt arg1} (which contains the address used) by the number of bytes\n * encoded in \\FacAccessmemoryAamsize.\n *\n * Supporting this variant is optional, but highly recommended for\n * performance reasons.\n */\n#define AC_ACCESS_MEMORY_AAMPOSTINCREMENT_OFFSET 0x13\n#define AC_ACCESS_MEMORY_AAMPOSTINCREMENT_LENGTH 1\n#define AC_ACCESS_MEMORY_AAMPOSTINCREMENT   0x80000\n#define AC_ACCESS_MEMORY_WRITE_OFFSET       0x10\n#define AC_ACCESS_MEMORY_WRITE_LENGTH       1\n#define AC_ACCESS_MEMORY_WRITE              0x10000\n/*\n * arg0: Copy data from the memory location specified in {\\tt arg1} into\n * the low bits of {\\tt arg0}. The value of the remaining bits of\n * {\\tt arg0} are \\unspecified.\n */\n#define AC_ACCESS_MEMORY_WRITE_ARG0         0\n/*\n * memory: Copy data from the low bits of {\\tt arg0} into the memory\n * location specified in {\\tt arg1}.\n */\n#define AC_ACCESS_MEMORY_WRITE_MEMORY       1\n/*\n * These bits are reserved for target-specific uses.\n */\n#define AC_ACCESS_MEMORY_TARGET_SPECIFIC_OFFSET 0xe\n#define AC_ACCESS_MEMORY_TARGET_SPECIFIC_LENGTH 2\n#define AC_ACCESS_MEMORY_TARGET_SPECIFIC    0xc000\n#define VIRT_PRIV                           virtual\n/*\n * Contains the virtualization mode the hart was operating in when Debug\n * Mode was entered. The encoding is described in Table \\ref{tab:privmode},\n * and matches the virtualization mode encoding from the Privileged Spec.\n * A user can write this value to change the hart's virtualization mode\n * when exiting Debug Mode.\n */\n#define VIRT_PRIV_V_OFFSET                  2\n#define VIRT_PRIV_V_LENGTH                  1\n#define VIRT_PRIV_V                         4\n/*\n * Contains the privilege mode the hart was operating in when Debug\n * Mode was entered. The encoding is described in Table\n * \\ref{tab:privmode}, and matches the privilege mode encoding from\n * the Privileged Spec. A user can write this\n * value to change the hart's privilege mode when exiting Debug Mode.\n */\n#define VIRT_PRIV_PRV_OFFSET                0\n#define VIRT_PRIV_PRV_LENGTH                2\n#define VIRT_PRIV_PRV                       3\n#define DMI_SERCS                           0x34\n/*\n * Number of supported serial ports.\n */\n#define DMI_SERCS_SERIALCOUNT_OFFSET        0x1c\n#define DMI_SERCS_SERIALCOUNT_LENGTH        4\n#define DMI_SERCS_SERIALCOUNT               0xf0000000U\n/*\n * Select which serial port is accessed by \\RdmiSerrx and \\RdmiSertx.\n */\n#define DMI_SERCS_SERIAL_OFFSET             0x18\n#define DMI_SERCS_SERIAL_LENGTH             3\n#define DMI_SERCS_SERIAL                    0x7000000\n#define DMI_SERCS_ERROR7_OFFSET             0x17\n#define DMI_SERCS_ERROR7_LENGTH             1\n#define DMI_SERCS_ERROR7                    0x800000\n#define DMI_SERCS_VALID7_OFFSET             0x16\n#define DMI_SERCS_VALID7_LENGTH             1\n#define DMI_SERCS_VALID7                    0x400000\n#define DMI_SERCS_FULL7_OFFSET              0x15\n#define DMI_SERCS_FULL7_LENGTH              1\n#define DMI_SERCS_FULL7                     0x200000\n#define DMI_SERCS_ERROR6_OFFSET             0x14\n#define DMI_SERCS_ERROR6_LENGTH             1\n#define DMI_SERCS_ERROR6                    0x100000\n#define DMI_SERCS_VALID6_OFFSET             0x13\n#define DMI_SERCS_VALID6_LENGTH             1\n#define DMI_SERCS_VALID6                    0x80000\n#define DMI_SERCS_FULL6_OFFSET              0x12\n#define DMI_SERCS_FULL6_LENGTH              1\n#define DMI_SERCS_FULL6                     0x40000\n#define DMI_SERCS_ERROR5_OFFSET             0x11\n#define DMI_SERCS_ERROR5_LENGTH             1\n#define DMI_SERCS_ERROR5                    0x20000\n#define DMI_SERCS_VALID5_OFFSET             0x10\n#define DMI_SERCS_VALID5_LENGTH             1\n#define DMI_SERCS_VALID5                    0x10000\n#define DMI_SERCS_FULL5_OFFSET              0xf\n#define DMI_SERCS_FULL5_LENGTH              1\n#define DMI_SERCS_FULL5                     0x8000\n#define DMI_SERCS_ERROR4_OFFSET             0xe\n#define DMI_SERCS_ERROR4_LENGTH             1\n#define DMI_SERCS_ERROR4                    0x4000\n#define DMI_SERCS_VALID4_OFFSET             0xd\n#define DMI_SERCS_VALID4_LENGTH             1\n#define DMI_SERCS_VALID4                    0x2000\n#define DMI_SERCS_FULL4_OFFSET              0xc\n#define DMI_SERCS_FULL4_LENGTH              1\n#define DMI_SERCS_FULL4                     0x1000\n#define DMI_SERCS_ERROR3_OFFSET             0xb\n#define DMI_SERCS_ERROR3_LENGTH             1\n#define DMI_SERCS_ERROR3                    0x800\n#define DMI_SERCS_VALID3_OFFSET             0xa\n#define DMI_SERCS_VALID3_LENGTH             1\n#define DMI_SERCS_VALID3                    0x400\n#define DMI_SERCS_FULL3_OFFSET              9\n#define DMI_SERCS_FULL3_LENGTH              1\n#define DMI_SERCS_FULL3                     0x200\n#define DMI_SERCS_ERROR2_OFFSET             8\n#define DMI_SERCS_ERROR2_LENGTH             1\n#define DMI_SERCS_ERROR2                    0x100\n#define DMI_SERCS_VALID2_OFFSET             7\n#define DMI_SERCS_VALID2_LENGTH             1\n#define DMI_SERCS_VALID2                    0x80\n#define DMI_SERCS_FULL2_OFFSET              6\n#define DMI_SERCS_FULL2_LENGTH              1\n#define DMI_SERCS_FULL2                     0x40\n#define DMI_SERCS_ERROR1_OFFSET             5\n#define DMI_SERCS_ERROR1_LENGTH             1\n#define DMI_SERCS_ERROR1                    0x20\n#define DMI_SERCS_VALID1_OFFSET             4\n#define DMI_SERCS_VALID1_LENGTH             1\n#define DMI_SERCS_VALID1                    0x10\n#define DMI_SERCS_FULL1_OFFSET              3\n#define DMI_SERCS_FULL1_LENGTH              1\n#define DMI_SERCS_FULL1                     8\n/*\n * 1 when the debugger-to-core queue for serial port 0 has\n * over or underflowed. This bit will remain set until it is reset by\n * writing 1 to this bit.\n */\n#define DMI_SERCS_ERROR0_OFFSET             2\n#define DMI_SERCS_ERROR0_LENGTH             1\n#define DMI_SERCS_ERROR0                    4\n/*\n * 1 when the core-to-debugger queue for serial port 0 is not empty.\n */\n#define DMI_SERCS_VALID0_OFFSET             1\n#define DMI_SERCS_VALID0_LENGTH             1\n#define DMI_SERCS_VALID0                    2\n/*\n * 1 when the debugger-to-core queue for serial port 0 is full.\n */\n#define DMI_SERCS_FULL0_OFFSET              0\n#define DMI_SERCS_FULL0_LENGTH              1\n#define DMI_SERCS_FULL0                     1\n#define DMI_SERTX                           0x35\n#define DMI_SERTX_DATA_OFFSET               0\n#define DMI_SERTX_DATA_LENGTH               0x20\n#define DMI_SERTX_DATA                      0xffffffffU\n#define DMI_SERRX                           0x36\n#define DMI_SERRX_DATA_OFFSET               0\n#define DMI_SERRX_DATA_LENGTH               0x20\n#define DMI_SERRX_DATA                      0xffffffffU\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/encoding.h",
    "content": "/* SPDX-License-Identifier: BSD-3-Clause */\n\n/* Copyright (c) 2022 RISC-V International */\n\n/*\n * This file is auto-generated by running 'make' in\n * https://github.com/riscv/riscv-opcodes (dcdf8d3)\n */\n\n#ifndef RISCV_CSR_ENCODING_H\n#define RISCV_CSR_ENCODING_H\n\n#define MSTATUS_UIE         0x00000001\n#define MSTATUS_SIE         0x00000002\n#define MSTATUS_HIE         0x00000004\n#define MSTATUS_MIE         0x00000008\n#define MSTATUS_UPIE        0x00000010\n#define MSTATUS_SPIE        0x00000020\n#define MSTATUS_UBE         0x00000040\n#define MSTATUS_MPIE        0x00000080\n#define MSTATUS_SPP         0x00000100\n#define MSTATUS_VS          0x00000600\n#define MSTATUS_MPP         0x00001800\n#define MSTATUS_FS          0x00006000\n#define MSTATUS_XS          0x00018000\n#define MSTATUS_MPRV        0x00020000\n#define MSTATUS_SUM         0x00040000\n#define MSTATUS_MXR         0x00080000\n#define MSTATUS_TVM         0x00100000\n#define MSTATUS_TW          0x00200000\n#define MSTATUS_TSR         0x00400000\n#define MSTATUS32_SD        0x80000000\n#define MSTATUS_UXL         0x0000000300000000\n#define MSTATUS_SXL         0x0000000C00000000\n#define MSTATUS_SBE         0x0000001000000000\n#define MSTATUS_MBE         0x0000002000000000\n#define MSTATUS_GVA         0x0000004000000000\n#define MSTATUS_MPV         0x0000008000000000\n#define MSTATUS64_SD        0x8000000000000000\n\n#define MSTATUSH_SBE        0x00000010\n#define MSTATUSH_MBE        0x00000020\n#define MSTATUSH_GVA        0x00000040\n#define MSTATUSH_MPV        0x00000080\n\n#define SSTATUS_UIE         0x00000001\n#define SSTATUS_SIE         0x00000002\n#define SSTATUS_UPIE        0x00000010\n#define SSTATUS_SPIE        0x00000020\n#define SSTATUS_UBE         0x00000040\n#define SSTATUS_SPP         0x00000100\n#define SSTATUS_VS          0x00000600\n#define SSTATUS_FS          0x00006000\n#define SSTATUS_XS          0x00018000\n#define SSTATUS_SUM         0x00040000\n#define SSTATUS_MXR         0x00080000\n#define SSTATUS32_SD        0x80000000\n#define SSTATUS_UXL         0x0000000300000000\n#define SSTATUS64_SD        0x8000000000000000\n\n#define HSTATUS_VSXL        0x300000000\n#define HSTATUS_VTSR        0x00400000\n#define HSTATUS_VTW         0x00200000\n#define HSTATUS_VTVM        0x00100000\n#define HSTATUS_VGEIN       0x0003f000\n#define HSTATUS_HU          0x00000200\n#define HSTATUS_SPVP        0x00000100\n#define HSTATUS_SPV         0x00000080\n#define HSTATUS_GVA         0x00000040\n#define HSTATUS_VSBE        0x00000020\n\n#define USTATUS_UIE         0x00000001\n#define USTATUS_UPIE        0x00000010\n\n#define DCSR_XDEBUGVER      (3U<<30)\n#define DCSR_NDRESET        (1<<29)\n#define DCSR_FULLRESET      (1<<28)\n#define DCSR_EBREAKM        (1<<15)\n#define DCSR_EBREAKH        (1<<14)\n#define DCSR_EBREAKS        (1<<13)\n#define DCSR_EBREAKU        (1<<12)\n#define DCSR_STOPCYCLE      (1<<10)\n#define DCSR_STOPTIME       (1<<9)\n#define DCSR_CAUSE          (7<<6)\n#define DCSR_DEBUGINT       (1<<5)\n#define DCSR_HALT           (1<<3)\n#define DCSR_STEP           (1<<2)\n#define DCSR_PRV            (3<<0)\n\n#define DCSR_CAUSE_NONE     0\n#define DCSR_CAUSE_SWBP     1\n#define DCSR_CAUSE_HWBP     2\n#define DCSR_CAUSE_DEBUGINT 3\n#define DCSR_CAUSE_STEP     4\n#define DCSR_CAUSE_HALT     5\n#define DCSR_CAUSE_GROUP    6\n\n#define MCONTROL_TYPE(xlen)    (0xfULL<<((xlen)-4))\n#define MCONTROL_DMODE(xlen)   (1ULL<<((xlen)-5))\n#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11))\n\n#define MCONTROL_SELECT     (1<<19)\n#define MCONTROL_TIMING     (1<<18)\n#define MCONTROL_ACTION     (0x3f<<12)\n#define MCONTROL_CHAIN      (1<<11)\n#define MCONTROL_MATCH      (0xf<<7)\n#define MCONTROL_M          (1<<6)\n#define MCONTROL_H          (1<<5)\n#define MCONTROL_S          (1<<4)\n#define MCONTROL_U          (1<<3)\n#define MCONTROL_EXECUTE    (1<<2)\n#define MCONTROL_STORE      (1<<1)\n#define MCONTROL_LOAD       (1<<0)\n\n#define MCONTROL_TYPE_NONE      0\n#define MCONTROL_TYPE_MATCH     2\n\n#define MCONTROL_ACTION_DEBUG_EXCEPTION   0\n#define MCONTROL_ACTION_DEBUG_MODE        1\n#define MCONTROL_ACTION_TRACE_START       2\n#define MCONTROL_ACTION_TRACE_STOP        3\n#define MCONTROL_ACTION_TRACE_EMIT        4\n\n#define MCONTROL_MATCH_EQUAL     0\n#define MCONTROL_MATCH_NAPOT     1\n#define MCONTROL_MATCH_GE        2\n#define MCONTROL_MATCH_LT        3\n#define MCONTROL_MATCH_MASK_LOW  4\n#define MCONTROL_MATCH_MASK_HIGH 5\n\n#define MIP_USIP            (1 << IRQ_U_SOFT)\n#define MIP_SSIP            (1 << IRQ_S_SOFT)\n#define MIP_VSSIP           (1 << IRQ_VS_SOFT)\n#define MIP_MSIP            (1 << IRQ_M_SOFT)\n#define MIP_UTIP            (1 << IRQ_U_TIMER)\n#define MIP_STIP            (1 << IRQ_S_TIMER)\n#define MIP_VSTIP           (1 << IRQ_VS_TIMER)\n#define MIP_MTIP            (1 << IRQ_M_TIMER)\n#define MIP_UEIP            (1 << IRQ_U_EXT)\n#define MIP_SEIP            (1 << IRQ_S_EXT)\n#define MIP_VSEIP           (1 << IRQ_VS_EXT)\n#define MIP_MEIP            (1 << IRQ_M_EXT)\n#define MIP_SGEIP           (1 << IRQ_S_GEXT)\n#define MIP_LCOFIP          (1 << IRQ_LCOF)\n\n#define MIP_S_MASK          (MIP_SSIP | MIP_STIP | MIP_SEIP)\n#define MIP_VS_MASK         (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)\n#define MIP_HS_MASK         (MIP_VS_MASK | MIP_SGEIP)\n\n#define MIDELEG_FORCED_MASK MIP_HS_MASK\n\n#define SIP_SSIP MIP_SSIP\n#define SIP_STIP MIP_STIP\n\n#define MENVCFG_FIOM  0x00000001\n#define MENVCFG_CBIE  0x00000030\n#define MENVCFG_CBCFE 0x00000040\n#define MENVCFG_CBZE  0x00000080\n#define MENVCFG_PBMTE 0x4000000000000000\n#define MENVCFG_STCE  0x8000000000000000\n\n#define MENVCFGH_PBMTE 0x40000000\n#define MENVCFGH_STCE  0x80000000\n\n#define MSTATEEN0_CS       0x00000001\n#define MSTATEEN0_FCSR     0x00000002\n#define MSTATEEN0_HCONTEXT 0x0200000000000000\n#define MSTATEEN0_HENVCFG  0x4000000000000000\n#define MSTATEEN_HSTATEEN  0x8000000000000000\n\n#define MSTATEEN0H_HCONTEXT 0x02000000\n#define MSTATEEN0H_HENVCFG  0x40000000\n#define MSTATEENH_HSTATEEN  0x80000000\n\n#define MHPMEVENT_VUINH 0x0400000000000000\n#define MHPMEVENT_VSINH 0x0800000000000000\n#define MHPMEVENT_UINH  0x1000000000000000\n#define MHPMEVENT_SINH  0x2000000000000000\n#define MHPMEVENT_MINH  0x4000000000000000\n#define MHPMEVENT_OF    0x8000000000000000\n\n#define MHPMEVENTH_VUINH 0x04000000\n#define MHPMEVENTH_VSINH 0x08000000\n#define MHPMEVENTH_UINH  0x10000000\n#define MHPMEVENTH_SINH  0x20000000\n#define MHPMEVENTH_MINH  0x40000000\n#define MHPMEVENTH_OF    0x80000000\n\n#define HENVCFG_FIOM  0x00000001\n#define HENVCFG_CBIE  0x00000030\n#define HENVCFG_CBCFE 0x00000040\n#define HENVCFG_CBZE  0x00000080\n#define HENVCFG_PBMTE 0x4000000000000000\n#define HENVCFG_STCE  0x8000000000000000\n\n#define HENVCFGH_PBMTE 0x40000000\n#define HENVCFGH_STCE  0x80000000\n\n#define HSTATEEN0_CS       0x00000001\n#define HSTATEEN0_FCSR     0x00000002\n#define HSTATEEN0_SCONTEXT 0x0200000000000000\n#define HSTATEEN0_SENVCFG  0x4000000000000000\n#define HSTATEEN_SSTATEEN  0x8000000000000000\n\n#define HSTATEEN0H_SCONTEXT 0x02000000\n#define HSTATEEN0H_SENVCFG  0x40000000\n#define HSTATEENH_SSTATEEN  0x80000000\n\n#define SENVCFG_FIOM  0x00000001\n#define SENVCFG_CBIE  0x00000030\n#define SENVCFG_CBCFE 0x00000040\n#define SENVCFG_CBZE  0x00000080\n\n#define SSTATEEN0_CS   0x00000001\n#define SSTATEEN0_FCSR 0x00000002\n\n#define MSECCFG_MML    0x00000001\n#define MSECCFG_MMWP   0x00000002\n#define MSECCFG_RLB    0x00000004\n#define MSECCFG_USEED  0x00000100\n#define MSECCFG_SSEED  0x00000200\n\n#define PRV_U 0\n#define PRV_S 1\n#define PRV_M 3\n\n#define PRV_HS (PRV_S + 1)\n\n#define SATP32_MODE 0x80000000\n#define SATP32_ASID 0x7FC00000\n#define SATP32_PPN  0x003FFFFF\n#define SATP64_MODE 0xF000000000000000\n#define SATP64_ASID 0x0FFFF00000000000\n#define SATP64_PPN  0x00000FFFFFFFFFFF\n\n#define SATP_MODE_OFF  0\n#define SATP_MODE_SV32 1\n#define SATP_MODE_SV39 8\n#define SATP_MODE_SV48 9\n#define SATP_MODE_SV57 10\n#define SATP_MODE_SV64 11\n\n#define HGATP32_MODE 0x80000000\n#define HGATP32_VMID 0x1FC00000\n#define HGATP32_PPN 0x003FFFFF\n\n#define HGATP64_MODE 0xF000000000000000\n#define HGATP64_VMID 0x03FFF00000000000\n#define HGATP64_PPN 0x00000FFFFFFFFFFF\n\n#define HGATP_MODE_OFF 0\n#define HGATP_MODE_SV32X4 1\n#define HGATP_MODE_SV39X4 8\n#define HGATP_MODE_SV48X4 9\n#define HGATP_MODE_SV57X4 10\n\n#define PMP_R     0x01\n#define PMP_W     0x02\n#define PMP_X     0x04\n#define PMP_A     0x18\n#define PMP_L     0x80\n#define PMP_SHIFT 2\n\n#define PMP_TOR   0x08\n#define PMP_NA4   0x10\n#define PMP_NAPOT 0x18\n\n#define IRQ_U_SOFT   0\n#define IRQ_S_SOFT   1\n#define IRQ_VS_SOFT  2\n#define IRQ_M_SOFT   3\n#define IRQ_U_TIMER  4\n#define IRQ_S_TIMER  5\n#define IRQ_VS_TIMER 6\n#define IRQ_M_TIMER  7\n#define IRQ_U_EXT    8\n#define IRQ_S_EXT    9\n#define IRQ_VS_EXT   10\n#define IRQ_M_EXT    11\n#define IRQ_S_GEXT   12\n#define IRQ_COP      12\n#define IRQ_LCOF     13\n\n/* page table entry (PTE) fields */\n#define PTE_V     0x001 /* Valid */\n#define PTE_R     0x002 /* Read */\n#define PTE_W     0x004 /* Write */\n#define PTE_X     0x008 /* Execute */\n#define PTE_U     0x010 /* User */\n#define PTE_G     0x020 /* Global */\n#define PTE_A     0x040 /* Accessed */\n#define PTE_D     0x080 /* Dirty */\n#define PTE_SOFT  0x300 /* Reserved for Software */\n#define PTE_RSVD  0x1FC0000000000000 /* Reserved for future standard use */\n#define PTE_PBMT  0x6000000000000000 /* Svpbmt: Page-based memory types */\n#define PTE_N     0x8000000000000000 /* Svnapot: NAPOT translation contiguity */\n#define PTE_ATTR  0xFFC0000000000000 /* All attributes and reserved bits */\n\n#define PTE_PPN_SHIFT 10\n\n#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)\n\n#ifdef __riscv\n\n#if __riscv_xlen == 64\n# define MSTATUS_SD MSTATUS64_SD\n# define SSTATUS_SD SSTATUS64_SD\n# define RISCV_PGLEVEL_BITS 9\n# define SATP_MODE SATP64_MODE\n#else\n# define MSTATUS_SD MSTATUS32_SD\n# define SSTATUS_SD SSTATUS32_SD\n# define RISCV_PGLEVEL_BITS 10\n# define SATP_MODE SATP32_MODE\n#endif\n#define RISCV_PGSHIFT 12\n#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)\n\n#ifndef __ASSEMBLER__\n\n#ifdef __GNUC__\n\n#define read_csr(reg) ({ unsigned long __tmp; \\\n  asm volatile (\"csrr %0, \" #reg : \"=r\"(__tmp)); \\\n  __tmp; })\n\n#define write_csr(reg, val) ({ \\\n  asm volatile (\"csrw \" #reg \", %0\" :: \"rK\"(val)); })\n\n#define swap_csr(reg, val) ({ unsigned long __tmp; \\\n  asm volatile (\"csrrw %0, \" #reg \", %1\" : \"=r\"(__tmp) : \"rK\"(val)); \\\n  __tmp; })\n\n#define set_csr(reg, bit) ({ unsigned long __tmp; \\\n  asm volatile (\"csrrs %0, \" #reg \", %1\" : \"=r\"(__tmp) : \"rK\"(bit)); \\\n  __tmp; })\n\n#define clear_csr(reg, bit) ({ unsigned long __tmp; \\\n  asm volatile (\"csrrc %0, \" #reg \", %1\" : \"=r\"(__tmp) : \"rK\"(bit)); \\\n  __tmp; })\n\n#define rdtime() read_csr(time)\n#define rdcycle() read_csr(cycle)\n#define rdinstret() read_csr(instret)\n\n#endif\n\n#endif\n\n#endif\n\n#endif\n\n/* Automatically generated by parse_opcodes. */\n#ifndef RISCV_ENCODING_H\n#define RISCV_ENCODING_H\n#define MATCH_ADD 0x33\n#define MASK_ADD 0xfe00707f\n#define MATCH_ADD16 0x40000077\n#define MASK_ADD16 0xfe00707f\n#define MATCH_ADD32 0x40002077\n#define MASK_ADD32 0xfe00707f\n#define MATCH_ADD64 0xc0001077\n#define MASK_ADD64 0xfe00707f\n#define MATCH_ADD8 0x48000077\n#define MASK_ADD8 0xfe00707f\n#define MATCH_ADD_UW 0x800003b\n#define MASK_ADD_UW 0xfe00707f\n#define MATCH_ADDD 0x7b\n#define MASK_ADDD 0xfe00707f\n#define MATCH_ADDI 0x13\n#define MASK_ADDI 0x707f\n#define MATCH_ADDID 0x5b\n#define MASK_ADDID 0x707f\n#define MATCH_ADDIW 0x1b\n#define MASK_ADDIW 0x707f\n#define MATCH_ADDW 0x3b\n#define MASK_ADDW 0xfe00707f\n#define MATCH_AES32DSI 0x2a000033\n#define MASK_AES32DSI 0x3e00707f\n#define MATCH_AES32DSMI 0x2e000033\n#define MASK_AES32DSMI 0x3e00707f\n#define MATCH_AES32ESI 0x22000033\n#define MASK_AES32ESI 0x3e00707f\n#define MATCH_AES32ESMI 0x26000033\n#define MASK_AES32ESMI 0x3e00707f\n#define MATCH_AES64DS 0x3a000033\n#define MASK_AES64DS 0xfe00707f\n#define MATCH_AES64DSM 0x3e000033\n#define MASK_AES64DSM 0xfe00707f\n#define MATCH_AES64ES 0x32000033\n#define MASK_AES64ES 0xfe00707f\n#define MATCH_AES64ESM 0x36000033\n#define MASK_AES64ESM 0xfe00707f\n#define MATCH_AES64IM 0x30001013\n#define MASK_AES64IM 0xfff0707f\n#define MATCH_AES64KS1I 0x31001013\n#define MASK_AES64KS1I 0xff00707f\n#define MATCH_AES64KS2 0x7e000033\n#define MASK_AES64KS2 0xfe00707f\n#define MATCH_AMOADD_D 0x302f\n#define MASK_AMOADD_D 0xf800707f\n#define MATCH_AMOADD_W 0x202f\n#define MASK_AMOADD_W 0xf800707f\n#define MATCH_AMOAND_D 0x6000302f\n#define MASK_AMOAND_D 0xf800707f\n#define MATCH_AMOAND_W 0x6000202f\n#define MASK_AMOAND_W 0xf800707f\n#define MATCH_AMOMAX_D 0xa000302f\n#define MASK_AMOMAX_D 0xf800707f\n#define MATCH_AMOMAX_W 0xa000202f\n#define MASK_AMOMAX_W 0xf800707f\n#define MATCH_AMOMAXU_D 0xe000302f\n#define MASK_AMOMAXU_D 0xf800707f\n#define MATCH_AMOMAXU_W 0xe000202f\n#define MASK_AMOMAXU_W 0xf800707f\n#define MATCH_AMOMIN_D 0x8000302f\n#define MASK_AMOMIN_D 0xf800707f\n#define MATCH_AMOMIN_W 0x8000202f\n#define MASK_AMOMIN_W 0xf800707f\n#define MATCH_AMOMINU_D 0xc000302f\n#define MASK_AMOMINU_D 0xf800707f\n#define MATCH_AMOMINU_W 0xc000202f\n#define MASK_AMOMINU_W 0xf800707f\n#define MATCH_AMOOR_D 0x4000302f\n#define MASK_AMOOR_D 0xf800707f\n#define MATCH_AMOOR_W 0x4000202f\n#define MASK_AMOOR_W 0xf800707f\n#define MATCH_AMOSWAP_D 0x800302f\n#define MASK_AMOSWAP_D 0xf800707f\n#define MATCH_AMOSWAP_W 0x800202f\n#define MASK_AMOSWAP_W 0xf800707f\n#define MATCH_AMOXOR_D 0x2000302f\n#define MASK_AMOXOR_D 0xf800707f\n#define MATCH_AMOXOR_W 0x2000202f\n#define MASK_AMOXOR_W 0xf800707f\n#define MATCH_AND 0x7033\n#define MASK_AND 0xfe00707f\n#define MATCH_ANDI 0x7013\n#define MASK_ANDI 0x707f\n#define MATCH_ANDN 0x40007033\n#define MASK_ANDN 0xfe00707f\n#define MATCH_AUIPC 0x17\n#define MASK_AUIPC 0x7f\n#define MATCH_AVE 0xe0000077\n#define MASK_AVE 0xfe00707f\n#define MATCH_BCLR 0x48001033\n#define MASK_BCLR 0xfe00707f\n#define MATCH_BCLRI 0x48001013\n#define MASK_BCLRI 0xfc00707f\n#define MATCH_BCOMPRESS 0x8006033\n#define MASK_BCOMPRESS 0xfe00707f\n#define MATCH_BCOMPRESSW 0x800603b\n#define MASK_BCOMPRESSW 0xfe00707f\n#define MATCH_BDECOMPRESS 0x48006033\n#define MASK_BDECOMPRESS 0xfe00707f\n#define MATCH_BDECOMPRESSW 0x4800603b\n#define MASK_BDECOMPRESSW 0xfe00707f\n#define MATCH_BEQ 0x63\n#define MASK_BEQ 0x707f\n#define MATCH_BEXT 0x48005033\n#define MASK_BEXT 0xfe00707f\n#define MATCH_BEXTI 0x48005013\n#define MASK_BEXTI 0xfc00707f\n#define MATCH_BFP 0x48007033\n#define MASK_BFP 0xfe00707f\n#define MATCH_BFPW 0x4800703b\n#define MASK_BFPW 0xfe00707f\n#define MATCH_BGE 0x5063\n#define MASK_BGE 0x707f\n#define MATCH_BGEU 0x7063\n#define MASK_BGEU 0x707f\n#define MATCH_BINV 0x68001033\n#define MASK_BINV 0xfe00707f\n#define MATCH_BINVI 0x68001013\n#define MASK_BINVI 0xfc00707f\n#define MATCH_BITREV 0xe6000077\n#define MASK_BITREV 0xfe00707f\n#define MATCH_BITREVI 0xe8000077\n#define MASK_BITREVI 0xfc00707f\n#define MATCH_BLT 0x4063\n#define MASK_BLT 0x707f\n#define MATCH_BLTU 0x6063\n#define MASK_BLTU 0x707f\n#define MATCH_BMATFLIP 0x60301013\n#define MASK_BMATFLIP 0xfff0707f\n#define MATCH_BMATOR 0x8003033\n#define MASK_BMATOR 0xfe00707f\n#define MATCH_BMATXOR 0x48003033\n#define MASK_BMATXOR 0xfe00707f\n#define MATCH_BNE 0x1063\n#define MASK_BNE 0x707f\n#define MATCH_BPICK 0x3077\n#define MASK_BPICK 0x600707f\n#define MATCH_BSET 0x28001033\n#define MASK_BSET 0xfe00707f\n#define MATCH_BSETI 0x28001013\n#define MASK_BSETI 0xfc00707f\n#define MATCH_C_ADD 0x9002\n#define MASK_C_ADD 0xf003\n#define MATCH_C_ADDI 0x1\n#define MASK_C_ADDI 0xe003\n#define MATCH_C_ADDI16SP 0x6101\n#define MASK_C_ADDI16SP 0xef83\n#define MATCH_C_ADDI4SPN 0x0\n#define MASK_C_ADDI4SPN 0xe003\n#define MATCH_C_ADDIW 0x2001\n#define MASK_C_ADDIW 0xe003\n#define MATCH_C_ADDW 0x9c21\n#define MASK_C_ADDW 0xfc63\n#define MATCH_C_AND 0x8c61\n#define MASK_C_AND 0xfc63\n#define MATCH_C_ANDI 0x8801\n#define MASK_C_ANDI 0xec03\n#define MATCH_C_BEQZ 0xc001\n#define MASK_C_BEQZ 0xe003\n#define MATCH_C_BNEZ 0xe001\n#define MASK_C_BNEZ 0xe003\n#define MATCH_C_EBREAK 0x9002\n#define MASK_C_EBREAK 0xffff\n#define MATCH_C_FLD 0x2000\n#define MASK_C_FLD 0xe003\n#define MATCH_C_FLDSP 0x2002\n#define MASK_C_FLDSP 0xe003\n#define MATCH_C_FLW 0x6000\n#define MASK_C_FLW 0xe003\n#define MATCH_C_FLWSP 0x6002\n#define MASK_C_FLWSP 0xe003\n#define MATCH_C_FSD 0xa000\n#define MASK_C_FSD 0xe003\n#define MATCH_C_FSDSP 0xa002\n#define MASK_C_FSDSP 0xe003\n#define MATCH_C_FSW 0xe000\n#define MASK_C_FSW 0xe003\n#define MATCH_C_FSWSP 0xe002\n#define MASK_C_FSWSP 0xe003\n#define MATCH_C_J 0xa001\n#define MASK_C_J 0xe003\n#define MATCH_C_JAL 0x2001\n#define MASK_C_JAL 0xe003\n#define MATCH_C_JALR 0x9002\n#define MASK_C_JALR 0xf07f\n#define MATCH_C_JR 0x8002\n#define MASK_C_JR 0xf07f\n#define MATCH_C_LD 0x6000\n#define MASK_C_LD 0xe003\n#define MATCH_C_LDSP 0x6002\n#define MASK_C_LDSP 0xe003\n#define MATCH_C_LI 0x4001\n#define MASK_C_LI 0xe003\n#define MATCH_C_LQ 0x2000\n#define MASK_C_LQ 0xe003\n#define MATCH_C_LQSP 0x2002\n#define MASK_C_LQSP 0xe003\n#define MATCH_C_LUI 0x6001\n#define MASK_C_LUI 0xe003\n#define MATCH_C_LW 0x4000\n#define MASK_C_LW 0xe003\n#define MATCH_C_LWSP 0x4002\n#define MASK_C_LWSP 0xe003\n#define MATCH_C_MV 0x8002\n#define MASK_C_MV 0xf003\n#define MATCH_C_NOP 0x1\n#define MASK_C_NOP 0xef83\n#define MATCH_C_OR 0x8c41\n#define MASK_C_OR 0xfc63\n#define MATCH_C_SD 0xe000\n#define MASK_C_SD 0xe003\n#define MATCH_C_SDSP 0xe002\n#define MASK_C_SDSP 0xe003\n#define MATCH_C_SLLI 0x2\n#define MASK_C_SLLI 0xe003\n#define MATCH_C_SQ 0xa000\n#define MASK_C_SQ 0xe003\n#define MATCH_C_SQSP 0xa002\n#define MASK_C_SQSP 0xe003\n#define MATCH_C_SRAI 0x8401\n#define MASK_C_SRAI 0xec03\n#define MATCH_C_SRLI 0x8001\n#define MASK_C_SRLI 0xec03\n#define MATCH_C_SUB 0x8c01\n#define MASK_C_SUB 0xfc63\n#define MATCH_C_SUBW 0x9c01\n#define MASK_C_SUBW 0xfc63\n#define MATCH_C_SW 0xc000\n#define MASK_C_SW 0xe003\n#define MATCH_C_SWSP 0xc002\n#define MASK_C_SWSP 0xe003\n#define MATCH_C_XOR 0x8c21\n#define MASK_C_XOR 0xfc63\n#define MATCH_CBO_CLEAN 0x10200f\n#define MASK_CBO_CLEAN 0xfff07fff\n#define MATCH_CBO_FLUSH 0x20200f\n#define MASK_CBO_FLUSH 0xfff07fff\n#define MATCH_CBO_INVAL 0x200f\n#define MASK_CBO_INVAL 0xfff07fff\n#define MATCH_CBO_ZERO 0x40200f\n#define MASK_CBO_ZERO 0xfff07fff\n#define MATCH_CLMUL 0xa001033\n#define MASK_CLMUL 0xfe00707f\n#define MATCH_CLMULH 0xa003033\n#define MASK_CLMULH 0xfe00707f\n#define MATCH_CLMULR 0xa002033\n#define MASK_CLMULR 0xfe00707f\n#define MATCH_CLO16 0xaeb00077\n#define MASK_CLO16 0xfff0707f\n#define MATCH_CLO32 0xafb00077\n#define MASK_CLO32 0xfff0707f\n#define MATCH_CLO8 0xae300077\n#define MASK_CLO8 0xfff0707f\n#define MATCH_CLRS16 0xae800077\n#define MASK_CLRS16 0xfff0707f\n#define MATCH_CLRS32 0xaf800077\n#define MASK_CLRS32 0xfff0707f\n#define MATCH_CLRS8 0xae000077\n#define MASK_CLRS8 0xfff0707f\n#define MATCH_CLZ 0x60001013\n#define MASK_CLZ 0xfff0707f\n#define MATCH_CLZ16 0xae900077\n#define MASK_CLZ16 0xfff0707f\n#define MATCH_CLZ32 0xaf900077\n#define MASK_CLZ32 0xfff0707f\n#define MATCH_CLZ8 0xae100077\n#define MASK_CLZ8 0xfff0707f\n#define MATCH_CLZW 0x6000101b\n#define MASK_CLZW 0xfff0707f\n#define MATCH_CMIX 0x6001033\n#define MASK_CMIX 0x600707f\n#define MATCH_CMOV 0x6005033\n#define MASK_CMOV 0x600707f\n#define MATCH_CMPEQ16 0x4c000077\n#define MASK_CMPEQ16 0xfe00707f\n#define MATCH_CMPEQ8 0x4e000077\n#define MASK_CMPEQ8 0xfe00707f\n#define MATCH_CPOP 0x60201013\n#define MASK_CPOP 0xfff0707f\n#define MATCH_CPOPW 0x6020101b\n#define MASK_CPOPW 0xfff0707f\n#define MATCH_CRAS16 0x44000077\n#define MASK_CRAS16 0xfe00707f\n#define MATCH_CRAS32 0x44002077\n#define MASK_CRAS32 0xfe00707f\n#define MATCH_CRC32_B 0x61001013\n#define MASK_CRC32_B 0xfff0707f\n#define MATCH_CRC32_D 0x61301013\n#define MASK_CRC32_D 0xfff0707f\n#define MATCH_CRC32_H 0x61101013\n#define MASK_CRC32_H 0xfff0707f\n#define MATCH_CRC32_W 0x61201013\n#define MASK_CRC32_W 0xfff0707f\n#define MATCH_CRC32C_B 0x61801013\n#define MASK_CRC32C_B 0xfff0707f\n#define MATCH_CRC32C_D 0x61b01013\n#define MASK_CRC32C_D 0xfff0707f\n#define MATCH_CRC32C_H 0x61901013\n#define MASK_CRC32C_H 0xfff0707f\n#define MATCH_CRC32C_W 0x61a01013\n#define MASK_CRC32C_W 0xfff0707f\n#define MATCH_CRSA16 0x46000077\n#define MASK_CRSA16 0xfe00707f\n#define MATCH_CRSA32 0x46002077\n#define MASK_CRSA32 0xfe00707f\n#define MATCH_CSRRC 0x3073\n#define MASK_CSRRC 0x707f\n#define MATCH_CSRRCI 0x7073\n#define MASK_CSRRCI 0x707f\n#define MATCH_CSRRS 0x2073\n#define MASK_CSRRS 0x707f\n#define MATCH_CSRRSI 0x6073\n#define MASK_CSRRSI 0x707f\n#define MATCH_CSRRW 0x1073\n#define MASK_CSRRW 0x707f\n#define MATCH_CSRRWI 0x5073\n#define MASK_CSRRWI 0x707f\n#define MATCH_CTZ 0x60101013\n#define MASK_CTZ 0xfff0707f\n#define MATCH_CTZW 0x6010101b\n#define MASK_CTZW 0xfff0707f\n#define MATCH_DIV 0x2004033\n#define MASK_DIV 0xfe00707f\n#define MATCH_DIVU 0x2005033\n#define MASK_DIVU 0xfe00707f\n#define MATCH_DIVUW 0x200503b\n#define MASK_DIVUW 0xfe00707f\n#define MATCH_DIVW 0x200403b\n#define MASK_DIVW 0xfe00707f\n#define MATCH_DRET 0x7b200073\n#define MASK_DRET 0xffffffff\n#define MATCH_EBREAK 0x100073\n#define MASK_EBREAK 0xffffffff\n#define MATCH_ECALL 0x73\n#define MASK_ECALL 0xffffffff\n#define MATCH_FADD_D 0x2000053\n#define MASK_FADD_D 0xfe00007f\n#define MATCH_FADD_H 0x4000053\n#define MASK_FADD_H 0xfe00007f\n#define MATCH_FADD_Q 0x6000053\n#define MASK_FADD_Q 0xfe00007f\n#define MATCH_FADD_S 0x53\n#define MASK_FADD_S 0xfe00007f\n#define MATCH_FCLASS_D 0xe2001053\n#define MASK_FCLASS_D 0xfff0707f\n#define MATCH_FCLASS_H 0xe4001053\n#define MASK_FCLASS_H 0xfff0707f\n#define MATCH_FCLASS_Q 0xe6001053\n#define MASK_FCLASS_Q 0xfff0707f\n#define MATCH_FCLASS_S 0xe0001053\n#define MASK_FCLASS_S 0xfff0707f\n#define MATCH_FCVT_D_H 0x42200053\n#define MASK_FCVT_D_H 0xfff0007f\n#define MATCH_FCVT_D_L 0xd2200053\n#define MASK_FCVT_D_L 0xfff0007f\n#define MATCH_FCVT_D_LU 0xd2300053\n#define MASK_FCVT_D_LU 0xfff0007f\n#define MATCH_FCVT_D_Q 0x42300053\n#define MASK_FCVT_D_Q 0xfff0007f\n#define MATCH_FCVT_D_S 0x42000053\n#define MASK_FCVT_D_S 0xfff0007f\n#define MATCH_FCVT_D_W 0xd2000053\n#define MASK_FCVT_D_W 0xfff0007f\n#define MATCH_FCVT_D_WU 0xd2100053\n#define MASK_FCVT_D_WU 0xfff0007f\n#define MATCH_FCVT_H_D 0x44100053\n#define MASK_FCVT_H_D 0xfff0007f\n#define MATCH_FCVT_H_L 0xd4200053\n#define MASK_FCVT_H_L 0xfff0007f\n#define MATCH_FCVT_H_LU 0xd4300053\n#define MASK_FCVT_H_LU 0xfff0007f\n#define MATCH_FCVT_H_Q 0x44300053\n#define MASK_FCVT_H_Q 0xfff0007f\n#define MATCH_FCVT_H_S 0x44000053\n#define MASK_FCVT_H_S 0xfff0007f\n#define MATCH_FCVT_H_W 0xd4000053\n#define MASK_FCVT_H_W 0xfff0007f\n#define MATCH_FCVT_H_WU 0xd4100053\n#define MASK_FCVT_H_WU 0xfff0007f\n#define MATCH_FCVT_L_D 0xc2200053\n#define MASK_FCVT_L_D 0xfff0007f\n#define MATCH_FCVT_L_H 0xc4200053\n#define MASK_FCVT_L_H 0xfff0007f\n#define MATCH_FCVT_L_Q 0xc6200053\n#define MASK_FCVT_L_Q 0xfff0007f\n#define MATCH_FCVT_L_S 0xc0200053\n#define MASK_FCVT_L_S 0xfff0007f\n#define MATCH_FCVT_LU_D 0xc2300053\n#define MASK_FCVT_LU_D 0xfff0007f\n#define MATCH_FCVT_LU_H 0xc4300053\n#define MASK_FCVT_LU_H 0xfff0007f\n#define MATCH_FCVT_LU_Q 0xc6300053\n#define MASK_FCVT_LU_Q 0xfff0007f\n#define MATCH_FCVT_LU_S 0xc0300053\n#define MASK_FCVT_LU_S 0xfff0007f\n#define MATCH_FCVT_Q_D 0x46100053\n#define MASK_FCVT_Q_D 0xfff0007f\n#define MATCH_FCVT_Q_H 0x46200053\n#define MASK_FCVT_Q_H 0xfff0007f\n#define MATCH_FCVT_Q_L 0xd6200053\n#define MASK_FCVT_Q_L 0xfff0007f\n#define MATCH_FCVT_Q_LU 0xd6300053\n#define MASK_FCVT_Q_LU 0xfff0007f\n#define MATCH_FCVT_Q_S 0x46000053\n#define MASK_FCVT_Q_S 0xfff0007f\n#define MATCH_FCVT_Q_W 0xd6000053\n#define MASK_FCVT_Q_W 0xfff0007f\n#define MATCH_FCVT_Q_WU 0xd6100053\n#define MASK_FCVT_Q_WU 0xfff0007f\n#define MATCH_FCVT_S_D 0x40100053\n#define MASK_FCVT_S_D 0xfff0007f\n#define MATCH_FCVT_S_H 0x40200053\n#define MASK_FCVT_S_H 0xfff0007f\n#define MATCH_FCVT_S_L 0xd0200053\n#define MASK_FCVT_S_L 0xfff0007f\n#define MATCH_FCVT_S_LU 0xd0300053\n#define MASK_FCVT_S_LU 0xfff0007f\n#define MATCH_FCVT_S_Q 0x40300053\n#define MASK_FCVT_S_Q 0xfff0007f\n#define MATCH_FCVT_S_W 0xd0000053\n#define MASK_FCVT_S_W 0xfff0007f\n#define MATCH_FCVT_S_WU 0xd0100053\n#define MASK_FCVT_S_WU 0xfff0007f\n#define MATCH_FCVT_W_D 0xc2000053\n#define MASK_FCVT_W_D 0xfff0007f\n#define MATCH_FCVT_W_H 0xc4000053\n#define MASK_FCVT_W_H 0xfff0007f\n#define MATCH_FCVT_W_Q 0xc6000053\n#define MASK_FCVT_W_Q 0xfff0007f\n#define MATCH_FCVT_W_S 0xc0000053\n#define MASK_FCVT_W_S 0xfff0007f\n#define MATCH_FCVT_WU_D 0xc2100053\n#define MASK_FCVT_WU_D 0xfff0007f\n#define MATCH_FCVT_WU_H 0xc4100053\n#define MASK_FCVT_WU_H 0xfff0007f\n#define MATCH_FCVT_WU_Q 0xc6100053\n#define MASK_FCVT_WU_Q 0xfff0007f\n#define MATCH_FCVT_WU_S 0xc0100053\n#define MASK_FCVT_WU_S 0xfff0007f\n#define MATCH_FDIV_D 0x1a000053\n#define MASK_FDIV_D 0xfe00007f\n#define MATCH_FDIV_H 0x1c000053\n#define MASK_FDIV_H 0xfe00007f\n#define MATCH_FDIV_Q 0x1e000053\n#define MASK_FDIV_Q 0xfe00007f\n#define MATCH_FDIV_S 0x18000053\n#define MASK_FDIV_S 0xfe00007f\n#define MATCH_FENCE 0xf\n#define MASK_FENCE 0x707f\n#define MATCH_FENCE_I 0x100f\n#define MASK_FENCE_I 0x707f\n#define MATCH_FEQ_D 0xa2002053\n#define MASK_FEQ_D 0xfe00707f\n#define MATCH_FEQ_H 0xa4002053\n#define MASK_FEQ_H 0xfe00707f\n#define MATCH_FEQ_Q 0xa6002053\n#define MASK_FEQ_Q 0xfe00707f\n#define MATCH_FEQ_S 0xa0002053\n#define MASK_FEQ_S 0xfe00707f\n#define MATCH_FLD 0x3007\n#define MASK_FLD 0x707f\n#define MATCH_FLE_D 0xa2000053\n#define MASK_FLE_D 0xfe00707f\n#define MATCH_FLE_H 0xa4000053\n#define MASK_FLE_H 0xfe00707f\n#define MATCH_FLE_Q 0xa6000053\n#define MASK_FLE_Q 0xfe00707f\n#define MATCH_FLE_S 0xa0000053\n#define MASK_FLE_S 0xfe00707f\n#define MATCH_FLH 0x1007\n#define MASK_FLH 0x707f\n#define MATCH_FLQ 0x4007\n#define MASK_FLQ 0x707f\n#define MATCH_FLT_D 0xa2001053\n#define MASK_FLT_D 0xfe00707f\n#define MATCH_FLT_H 0xa4001053\n#define MASK_FLT_H 0xfe00707f\n#define MATCH_FLT_Q 0xa6001053\n#define MASK_FLT_Q 0xfe00707f\n#define MATCH_FLT_S 0xa0001053\n#define MASK_FLT_S 0xfe00707f\n#define MATCH_FLW 0x2007\n#define MASK_FLW 0x707f\n#define MATCH_FMADD_D 0x2000043\n#define MASK_FMADD_D 0x600007f\n#define MATCH_FMADD_H 0x4000043\n#define MASK_FMADD_H 0x600007f\n#define MATCH_FMADD_Q 0x6000043\n#define MASK_FMADD_Q 0x600007f\n#define MATCH_FMADD_S 0x43\n#define MASK_FMADD_S 0x600007f\n#define MATCH_FMAX_D 0x2a001053\n#define MASK_FMAX_D 0xfe00707f\n#define MATCH_FMAX_H 0x2c001053\n#define MASK_FMAX_H 0xfe00707f\n#define MATCH_FMAX_Q 0x2e001053\n#define MASK_FMAX_Q 0xfe00707f\n#define MATCH_FMAX_S 0x28001053\n#define MASK_FMAX_S 0xfe00707f\n#define MATCH_FMIN_D 0x2a000053\n#define MASK_FMIN_D 0xfe00707f\n#define MATCH_FMIN_H 0x2c000053\n#define MASK_FMIN_H 0xfe00707f\n#define MATCH_FMIN_Q 0x2e000053\n#define MASK_FMIN_Q 0xfe00707f\n#define MATCH_FMIN_S 0x28000053\n#define MASK_FMIN_S 0xfe00707f\n#define MATCH_FMSUB_D 0x2000047\n#define MASK_FMSUB_D 0x600007f\n#define MATCH_FMSUB_H 0x4000047\n#define MASK_FMSUB_H 0x600007f\n#define MATCH_FMSUB_Q 0x6000047\n#define MASK_FMSUB_Q 0x600007f\n#define MATCH_FMSUB_S 0x47\n#define MASK_FMSUB_S 0x600007f\n#define MATCH_FMUL_D 0x12000053\n#define MASK_FMUL_D 0xfe00007f\n#define MATCH_FMUL_H 0x14000053\n#define MASK_FMUL_H 0xfe00007f\n#define MATCH_FMUL_Q 0x16000053\n#define MASK_FMUL_Q 0xfe00007f\n#define MATCH_FMUL_S 0x10000053\n#define MASK_FMUL_S 0xfe00007f\n#define MATCH_FMV_D_X 0xf2000053\n#define MASK_FMV_D_X 0xfff0707f\n#define MATCH_FMV_H_X 0xf4000053\n#define MASK_FMV_H_X 0xfff0707f\n#define MATCH_FMV_W_X 0xf0000053\n#define MASK_FMV_W_X 0xfff0707f\n#define MATCH_FMV_X_D 0xe2000053\n#define MASK_FMV_X_D 0xfff0707f\n#define MATCH_FMV_X_H 0xe4000053\n#define MASK_FMV_X_H 0xfff0707f\n#define MATCH_FMV_X_W 0xe0000053\n#define MASK_FMV_X_W 0xfff0707f\n#define MATCH_FNMADD_D 0x200004f\n#define MASK_FNMADD_D 0x600007f\n#define MATCH_FNMADD_H 0x400004f\n#define MASK_FNMADD_H 0x600007f\n#define MATCH_FNMADD_Q 0x600004f\n#define MASK_FNMADD_Q 0x600007f\n#define MATCH_FNMADD_S 0x4f\n#define MASK_FNMADD_S 0x600007f\n#define MATCH_FNMSUB_D 0x200004b\n#define MASK_FNMSUB_D 0x600007f\n#define MATCH_FNMSUB_H 0x400004b\n#define MASK_FNMSUB_H 0x600007f\n#define MATCH_FNMSUB_Q 0x600004b\n#define MASK_FNMSUB_Q 0x600007f\n#define MATCH_FNMSUB_S 0x4b\n#define MASK_FNMSUB_S 0x600007f\n#define MATCH_FSD 0x3027\n#define MASK_FSD 0x707f\n#define MATCH_FSGNJ_D 0x22000053\n#define MASK_FSGNJ_D 0xfe00707f\n#define MATCH_FSGNJ_H 0x24000053\n#define MASK_FSGNJ_H 0xfe00707f\n#define MATCH_FSGNJ_Q 0x26000053\n#define MASK_FSGNJ_Q 0xfe00707f\n#define MATCH_FSGNJ_S 0x20000053\n#define MASK_FSGNJ_S 0xfe00707f\n#define MATCH_FSGNJN_D 0x22001053\n#define MASK_FSGNJN_D 0xfe00707f\n#define MATCH_FSGNJN_H 0x24001053\n#define MASK_FSGNJN_H 0xfe00707f\n#define MATCH_FSGNJN_Q 0x26001053\n#define MASK_FSGNJN_Q 0xfe00707f\n#define MATCH_FSGNJN_S 0x20001053\n#define MASK_FSGNJN_S 0xfe00707f\n#define MATCH_FSGNJX_D 0x22002053\n#define MASK_FSGNJX_D 0xfe00707f\n#define MATCH_FSGNJX_H 0x24002053\n#define MASK_FSGNJX_H 0xfe00707f\n#define MATCH_FSGNJX_Q 0x26002053\n#define MASK_FSGNJX_Q 0xfe00707f\n#define MATCH_FSGNJX_S 0x20002053\n#define MASK_FSGNJX_S 0xfe00707f\n#define MATCH_FSH 0x1027\n#define MASK_FSH 0x707f\n#define MATCH_FSL 0x4001033\n#define MASK_FSL 0x600707f\n#define MATCH_FSLW 0x400103b\n#define MASK_FSLW 0x600707f\n#define MATCH_FSQ 0x4027\n#define MASK_FSQ 0x707f\n#define MATCH_FSQRT_D 0x5a000053\n#define MASK_FSQRT_D 0xfff0007f\n#define MATCH_FSQRT_H 0x5c000053\n#define MASK_FSQRT_H 0xfff0007f\n#define MATCH_FSQRT_Q 0x5e000053\n#define MASK_FSQRT_Q 0xfff0007f\n#define MATCH_FSQRT_S 0x58000053\n#define MASK_FSQRT_S 0xfff0007f\n#define MATCH_FSR 0x4005033\n#define MASK_FSR 0x600707f\n#define MATCH_FSRI 0x4005013\n#define MASK_FSRI 0x400707f\n#define MATCH_FSRIW 0x400501b\n#define MASK_FSRIW 0x600707f\n#define MATCH_FSRW 0x400503b\n#define MASK_FSRW 0x600707f\n#define MATCH_FSUB_D 0xa000053\n#define MASK_FSUB_D 0xfe00007f\n#define MATCH_FSUB_H 0xc000053\n#define MASK_FSUB_H 0xfe00007f\n#define MATCH_FSUB_Q 0xe000053\n#define MASK_FSUB_Q 0xfe00007f\n#define MATCH_FSUB_S 0x8000053\n#define MASK_FSUB_S 0xfe00007f\n#define MATCH_FSW 0x2027\n#define MASK_FSW 0x707f\n#define MATCH_GORC 0x28005033\n#define MASK_GORC 0xfe00707f\n#define MATCH_GORCI 0x28005013\n#define MASK_GORCI 0xfc00707f\n#define MATCH_GORCIW 0x2800501b\n#define MASK_GORCIW 0xfe00707f\n#define MATCH_GORCW 0x2800503b\n#define MASK_GORCW 0xfe00707f\n#define MATCH_GREV 0x68005033\n#define MASK_GREV 0xfe00707f\n#define MATCH_GREVI 0x68005013\n#define MASK_GREVI 0xfc00707f\n#define MATCH_GREVIW 0x6800501b\n#define MASK_GREVIW 0xfe00707f\n#define MATCH_GREVW 0x6800503b\n#define MASK_GREVW 0xfe00707f\n#define MATCH_HFENCE_GVMA 0x62000073\n#define MASK_HFENCE_GVMA 0xfe007fff\n#define MATCH_HFENCE_VVMA 0x22000073\n#define MASK_HFENCE_VVMA 0xfe007fff\n#define MATCH_HINVAL_GVMA 0x66000073\n#define MASK_HINVAL_GVMA 0xfe007fff\n#define MATCH_HINVAL_VVMA 0x26000073\n#define MASK_HINVAL_VVMA 0xfe007fff\n#define MATCH_HLV_B 0x60004073\n#define MASK_HLV_B 0xfff0707f\n#define MATCH_HLV_BU 0x60104073\n#define MASK_HLV_BU 0xfff0707f\n#define MATCH_HLV_D 0x6c004073\n#define MASK_HLV_D 0xfff0707f\n#define MATCH_HLV_H 0x64004073\n#define MASK_HLV_H 0xfff0707f\n#define MATCH_HLV_HU 0x64104073\n#define MASK_HLV_HU 0xfff0707f\n#define MATCH_HLV_W 0x68004073\n#define MASK_HLV_W 0xfff0707f\n#define MATCH_HLV_WU 0x68104073\n#define MASK_HLV_WU 0xfff0707f\n#define MATCH_HLVX_HU 0x64304073\n#define MASK_HLVX_HU 0xfff0707f\n#define MATCH_HLVX_WU 0x68304073\n#define MASK_HLVX_WU 0xfff0707f\n#define MATCH_HSV_B 0x62004073\n#define MASK_HSV_B 0xfe007fff\n#define MATCH_HSV_D 0x6e004073\n#define MASK_HSV_D 0xfe007fff\n#define MATCH_HSV_H 0x66004073\n#define MASK_HSV_H 0xfe007fff\n#define MATCH_HSV_W 0x6a004073\n#define MASK_HSV_W 0xfe007fff\n#define MATCH_INSB 0xac000077\n#define MASK_INSB 0xff80707f\n#define MATCH_JAL 0x6f\n#define MASK_JAL 0x7f\n#define MATCH_JALR 0x67\n#define MASK_JALR 0x707f\n#define MATCH_KABS16 0xad100077\n#define MASK_KABS16 0xfff0707f\n#define MATCH_KABS32 0xad200077\n#define MASK_KABS32 0xfff0707f\n#define MATCH_KABS8 0xad000077\n#define MASK_KABS8 0xfff0707f\n#define MATCH_KABSW 0xad400077\n#define MASK_KABSW 0xfff0707f\n#define MATCH_KADD16 0x10000077\n#define MASK_KADD16 0xfe00707f\n#define MATCH_KADD32 0x10002077\n#define MASK_KADD32 0xfe00707f\n#define MATCH_KADD64 0x90001077\n#define MASK_KADD64 0xfe00707f\n#define MATCH_KADD8 0x18000077\n#define MASK_KADD8 0xfe00707f\n#define MATCH_KADDH 0x4001077\n#define MASK_KADDH 0xfe00707f\n#define MATCH_KADDW 0x1077\n#define MASK_KADDW 0xfe00707f\n#define MATCH_KCRAS16 0x14000077\n#define MASK_KCRAS16 0xfe00707f\n#define MATCH_KCRAS32 0x14002077\n#define MASK_KCRAS32 0xfe00707f\n#define MATCH_KCRSA16 0x16000077\n#define MASK_KCRSA16 0xfe00707f\n#define MATCH_KCRSA32 0x16002077\n#define MASK_KCRSA32 0xfe00707f\n#define MATCH_KDMABB 0xd2001077\n#define MASK_KDMABB 0xfe00707f\n#define MATCH_KDMABB16 0xd8001077\n#define MASK_KDMABB16 0xfe00707f\n#define MATCH_KDMABT 0xe2001077\n#define MASK_KDMABT 0xfe00707f\n#define MATCH_KDMABT16 0xe8001077\n#define MASK_KDMABT16 0xfe00707f\n#define MATCH_KDMATT 0xf2001077\n#define MASK_KDMATT 0xfe00707f\n#define MATCH_KDMATT16 0xf8001077\n#define MASK_KDMATT16 0xfe00707f\n#define MATCH_KDMBB 0xa001077\n#define MASK_KDMBB 0xfe00707f\n#define MATCH_KDMBB16 0xda001077\n#define MASK_KDMBB16 0xfe00707f\n#define MATCH_KDMBT 0x1a001077\n#define MASK_KDMBT 0xfe00707f\n#define MATCH_KDMBT16 0xea001077\n#define MASK_KDMBT16 0xfe00707f\n#define MATCH_KDMTT 0x2a001077\n#define MASK_KDMTT 0xfe00707f\n#define MATCH_KDMTT16 0xfa001077\n#define MASK_KDMTT16 0xfe00707f\n#define MATCH_KHM16 0x86000077\n#define MASK_KHM16 0xfe00707f\n#define MATCH_KHM8 0x8e000077\n#define MASK_KHM8 0xfe00707f\n#define MATCH_KHMBB 0xc001077\n#define MASK_KHMBB 0xfe00707f\n#define MATCH_KHMBB16 0xdc001077\n#define MASK_KHMBB16 0xfe00707f\n#define MATCH_KHMBT 0x1c001077\n#define MASK_KHMBT 0xfe00707f\n#define MATCH_KHMBT16 0xec001077\n#define MASK_KHMBT16 0xfe00707f\n#define MATCH_KHMTT 0x2c001077\n#define MASK_KHMTT 0xfe00707f\n#define MATCH_KHMTT16 0xfc001077\n#define MASK_KHMTT16 0xfe00707f\n#define MATCH_KHMX16 0x96000077\n#define MASK_KHMX16 0xfe00707f\n#define MATCH_KHMX8 0x9e000077\n#define MASK_KHMX8 0xfe00707f\n#define MATCH_KMABB 0x5a001077\n#define MASK_KMABB 0xfe00707f\n#define MATCH_KMABB32 0x5a002077\n#define MASK_KMABB32 0xfe00707f\n#define MATCH_KMABT 0x6a001077\n#define MASK_KMABT 0xfe00707f\n#define MATCH_KMABT32 0x6a002077\n#define MASK_KMABT32 0xfe00707f\n#define MATCH_KMADA 0x48001077\n#define MASK_KMADA 0xfe00707f\n#define MATCH_KMADRS 0x6c001077\n#define MASK_KMADRS 0xfe00707f\n#define MATCH_KMADRS32 0x6c002077\n#define MASK_KMADRS32 0xfe00707f\n#define MATCH_KMADS 0x5c001077\n#define MASK_KMADS 0xfe00707f\n#define MATCH_KMADS32 0x5c002077\n#define MASK_KMADS32 0xfe00707f\n#define MATCH_KMAR64 0x94001077\n#define MASK_KMAR64 0xfe00707f\n#define MATCH_KMATT 0x7a001077\n#define MASK_KMATT 0xfe00707f\n#define MATCH_KMATT32 0x7a002077\n#define MASK_KMATT32 0xfe00707f\n#define MATCH_KMAXDA 0x4a001077\n#define MASK_KMAXDA 0xfe00707f\n#define MATCH_KMAXDA32 0x4a002077\n#define MASK_KMAXDA32 0xfe00707f\n#define MATCH_KMAXDS 0x7c001077\n#define MASK_KMAXDS 0xfe00707f\n#define MATCH_KMAXDS32 0x7c002077\n#define MASK_KMAXDS32 0xfe00707f\n#define MATCH_KMDA 0x38001077\n#define MASK_KMDA 0xfe00707f\n#define MATCH_KMDA32 0x38002077\n#define MASK_KMDA32 0xfe00707f\n#define MATCH_KMMAC 0x60001077\n#define MASK_KMMAC 0xfe00707f\n#define MATCH_KMMAC_U 0x70001077\n#define MASK_KMMAC_U 0xfe00707f\n#define MATCH_KMMAWB 0x46001077\n#define MASK_KMMAWB 0xfe00707f\n#define MATCH_KMMAWB2 0xce001077\n#define MASK_KMMAWB2 0xfe00707f\n#define MATCH_KMMAWB2_U 0xde001077\n#define MASK_KMMAWB2_U 0xfe00707f\n#define MATCH_KMMAWB_U 0x56001077\n#define MASK_KMMAWB_U 0xfe00707f\n#define MATCH_KMMAWT 0x66001077\n#define MASK_KMMAWT 0xfe00707f\n#define MATCH_KMMAWT2 0xee001077\n#define MASK_KMMAWT2 0xfe00707f\n#define MATCH_KMMAWT2_U 0xfe001077\n#define MASK_KMMAWT2_U 0xfe00707f\n#define MATCH_KMMAWT_U 0x76001077\n#define MASK_KMMAWT_U 0xfe00707f\n#define MATCH_KMMSB 0x42001077\n#define MASK_KMMSB 0xfe00707f\n#define MATCH_KMMSB_U 0x52001077\n#define MASK_KMMSB_U 0xfe00707f\n#define MATCH_KMMWB2 0x8e001077\n#define MASK_KMMWB2 0xfe00707f\n#define MATCH_KMMWB2_U 0x9e001077\n#define MASK_KMMWB2_U 0xfe00707f\n#define MATCH_KMMWT2 0xae001077\n#define MASK_KMMWT2 0xfe00707f\n#define MATCH_KMMWT2_U 0xbe001077\n#define MASK_KMMWT2_U 0xfe00707f\n#define MATCH_KMSDA 0x4c001077\n#define MASK_KMSDA 0xfe00707f\n#define MATCH_KMSDA32 0x4c002077\n#define MASK_KMSDA32 0xfe00707f\n#define MATCH_KMSR64 0x96001077\n#define MASK_KMSR64 0xfe00707f\n#define MATCH_KMSXDA 0x4e001077\n#define MASK_KMSXDA 0xfe00707f\n#define MATCH_KMSXDA32 0x4e002077\n#define MASK_KMSXDA32 0xfe00707f\n#define MATCH_KMXDA 0x3a001077\n#define MASK_KMXDA 0xfe00707f\n#define MATCH_KMXDA32 0x3a002077\n#define MASK_KMXDA32 0xfe00707f\n#define MATCH_KSLL16 0x64000077\n#define MASK_KSLL16 0xfe00707f\n#define MATCH_KSLL32 0x64002077\n#define MASK_KSLL32 0xfe00707f\n#define MATCH_KSLL8 0x6c000077\n#define MASK_KSLL8 0xfe00707f\n#define MATCH_KSLLI16 0x75000077\n#define MASK_KSLLI16 0xff00707f\n#define MATCH_KSLLI32 0x84002077\n#define MASK_KSLLI32 0xfe00707f\n#define MATCH_KSLLI8 0x7c800077\n#define MASK_KSLLI8 0xff80707f\n#define MATCH_KSLLIW 0x36001077\n#define MASK_KSLLIW 0xfe00707f\n#define MATCH_KSLLW 0x26001077\n#define MASK_KSLLW 0xfe00707f\n#define MATCH_KSLRA16 0x56000077\n#define MASK_KSLRA16 0xfe00707f\n#define MATCH_KSLRA16_U 0x66000077\n#define MASK_KSLRA16_U 0xfe00707f\n#define MATCH_KSLRA32 0x56002077\n#define MASK_KSLRA32 0xfe00707f\n#define MATCH_KSLRA32_U 0x66002077\n#define MASK_KSLRA32_U 0xfe00707f\n#define MATCH_KSLRA8 0x5e000077\n#define MASK_KSLRA8 0xfe00707f\n#define MATCH_KSLRA8_U 0x6e000077\n#define MASK_KSLRA8_U 0xfe00707f\n#define MATCH_KSLRAW 0x6e001077\n#define MASK_KSLRAW 0xfe00707f\n#define MATCH_KSLRAW_U 0x7e001077\n#define MASK_KSLRAW_U 0xfe00707f\n#define MATCH_KSTAS16 0xc4002077\n#define MASK_KSTAS16 0xfe00707f\n#define MATCH_KSTAS32 0xc0002077\n#define MASK_KSTAS32 0xfe00707f\n#define MATCH_KSTSA16 0xc6002077\n#define MASK_KSTSA16 0xfe00707f\n#define MATCH_KSTSA32 0xc2002077\n#define MASK_KSTSA32 0xfe00707f\n#define MATCH_KSUB16 0x12000077\n#define MASK_KSUB16 0xfe00707f\n#define MATCH_KSUB32 0x12002077\n#define MASK_KSUB32 0xfe00707f\n#define MATCH_KSUB64 0x92001077\n#define MASK_KSUB64 0xfe00707f\n#define MATCH_KSUB8 0x1a000077\n#define MASK_KSUB8 0xfe00707f\n#define MATCH_KSUBH 0x6001077\n#define MASK_KSUBH 0xfe00707f\n#define MATCH_KSUBW 0x2001077\n#define MASK_KSUBW 0xfe00707f\n#define MATCH_KWMMUL 0x62001077\n#define MASK_KWMMUL 0xfe00707f\n#define MATCH_KWMMUL_U 0x72001077\n#define MASK_KWMMUL_U 0xfe00707f\n#define MATCH_LB 0x3\n#define MASK_LB 0x707f\n#define MATCH_LBU 0x4003\n#define MASK_LBU 0x707f\n#define MATCH_LD 0x3003\n#define MASK_LD 0x707f\n#define MATCH_LDU 0x7003\n#define MASK_LDU 0x707f\n#define MATCH_LH 0x1003\n#define MASK_LH 0x707f\n#define MATCH_LHU 0x5003\n#define MASK_LHU 0x707f\n#define MATCH_LQ 0x300f\n#define MASK_LQ 0x707f\n#define MATCH_LR_D 0x1000302f\n#define MASK_LR_D 0xf9f0707f\n#define MATCH_LR_W 0x1000202f\n#define MASK_LR_W 0xf9f0707f\n#define MATCH_LUI 0x37\n#define MASK_LUI 0x7f\n#define MATCH_LW 0x2003\n#define MASK_LW 0x707f\n#define MATCH_LWU 0x6003\n#define MASK_LWU 0x707f\n#define MATCH_MADDR32 0xc4001077\n#define MASK_MADDR32 0xfe00707f\n#define MATCH_MAX 0xa006033\n#define MASK_MAX 0xfe00707f\n#define MATCH_MAXU 0xa007033\n#define MASK_MAXU 0xfe00707f\n#define MATCH_MAXW 0xf2000077\n#define MASK_MAXW 0xfe00707f\n#define MATCH_MIN 0xa004033\n#define MASK_MIN 0xfe00707f\n#define MATCH_MINU 0xa005033\n#define MASK_MINU 0xfe00707f\n#define MATCH_MINW 0xf0000077\n#define MASK_MINW 0xfe00707f\n#define MATCH_MRET 0x30200073\n#define MASK_MRET 0xffffffff\n#define MATCH_MSUBR32 0xc6001077\n#define MASK_MSUBR32 0xfe00707f\n#define MATCH_MUL 0x2000033\n#define MASK_MUL 0xfe00707f\n#define MATCH_MULH 0x2001033\n#define MASK_MULH 0xfe00707f\n#define MATCH_MULHSU 0x2002033\n#define MASK_MULHSU 0xfe00707f\n#define MATCH_MULHU 0x2003033\n#define MASK_MULHU 0xfe00707f\n#define MATCH_MULR64 0xf0001077\n#define MASK_MULR64 0xfe00707f\n#define MATCH_MULSR64 0xe0001077\n#define MASK_MULSR64 0xfe00707f\n#define MATCH_MULW 0x200003b\n#define MASK_MULW 0xfe00707f\n#define MATCH_OR 0x6033\n#define MASK_OR 0xfe00707f\n#define MATCH_ORI 0x6013\n#define MASK_ORI 0x707f\n#define MATCH_ORN 0x40006033\n#define MASK_ORN 0xfe00707f\n#define MATCH_PACK 0x8004033\n#define MASK_PACK 0xfe00707f\n#define MATCH_PACKH 0x8007033\n#define MASK_PACKH 0xfe00707f\n#define MATCH_PACKU 0x48004033\n#define MASK_PACKU 0xfe00707f\n#define MATCH_PACKUW 0x4800403b\n#define MASK_PACKUW 0xfe00707f\n#define MATCH_PACKW 0x800403b\n#define MASK_PACKW 0xfe00707f\n#define MATCH_PAUSE 0x100000f\n#define MASK_PAUSE 0xffffffff\n#define MATCH_PBSAD 0xfc000077\n#define MASK_PBSAD 0xfe00707f\n#define MATCH_PBSADA 0xfe000077\n#define MASK_PBSADA 0xfe00707f\n#define MATCH_PKBB16 0xe001077\n#define MASK_PKBB16 0xfe00707f\n#define MATCH_PKBB32 0xe002077\n#define MASK_PKBB32 0xfe00707f\n#define MATCH_PKBT16 0x1e001077\n#define MASK_PKBT16 0xfe00707f\n#define MATCH_PKBT32 0x1e002077\n#define MASK_PKBT32 0xfe00707f\n#define MATCH_PKTB16 0x3e001077\n#define MASK_PKTB16 0xfe00707f\n#define MATCH_PKTB32 0x3e002077\n#define MASK_PKTB32 0xfe00707f\n#define MATCH_PKTT16 0x2e001077\n#define MASK_PKTT16 0xfe00707f\n#define MATCH_PKTT32 0x2e002077\n#define MASK_PKTT32 0xfe00707f\n#define MATCH_PREFETCH_I 0x6013\n#define MASK_PREFETCH_I 0x1f07fff\n#define MATCH_PREFETCH_R 0x106013\n#define MASK_PREFETCH_R 0x1f07fff\n#define MATCH_PREFETCH_W 0x306013\n#define MASK_PREFETCH_W 0x1f07fff\n#define MATCH_RADD16 0x77\n#define MASK_RADD16 0xfe00707f\n#define MATCH_RADD32 0x2077\n#define MASK_RADD32 0xfe00707f\n#define MATCH_RADD64 0x80001077\n#define MASK_RADD64 0xfe00707f\n#define MATCH_RADD8 0x8000077\n#define MASK_RADD8 0xfe00707f\n#define MATCH_RADDW 0x20001077\n#define MASK_RADDW 0xfe00707f\n#define MATCH_RCRAS16 0x4000077\n#define MASK_RCRAS16 0xfe00707f\n#define MATCH_RCRAS32 0x4002077\n#define MASK_RCRAS32 0xfe00707f\n#define MATCH_RCRSA16 0x6000077\n#define MASK_RCRSA16 0xfe00707f\n#define MATCH_RCRSA32 0x6002077\n#define MASK_RCRSA32 0xfe00707f\n#define MATCH_REM 0x2006033\n#define MASK_REM 0xfe00707f\n#define MATCH_REMU 0x2007033\n#define MASK_REMU 0xfe00707f\n#define MATCH_REMUW 0x200703b\n#define MASK_REMUW 0xfe00707f\n#define MATCH_REMW 0x200603b\n#define MASK_REMW 0xfe00707f\n#define MATCH_ROL 0x60001033\n#define MASK_ROL 0xfe00707f\n#define MATCH_ROLW 0x6000103b\n#define MASK_ROLW 0xfe00707f\n#define MATCH_ROR 0x60005033\n#define MASK_ROR 0xfe00707f\n#define MATCH_RORI 0x60005013\n#define MASK_RORI 0xfc00707f\n#define MATCH_RORIW 0x6000501b\n#define MASK_RORIW 0xfe00707f\n#define MATCH_RORW 0x6000503b\n#define MASK_RORW 0xfe00707f\n#define MATCH_RSTAS16 0xb4002077\n#define MASK_RSTAS16 0xfe00707f\n#define MATCH_RSTAS32 0xb0002077\n#define MASK_RSTAS32 0xfe00707f\n#define MATCH_RSTSA16 0xb6002077\n#define MASK_RSTSA16 0xfe00707f\n#define MATCH_RSTSA32 0xb2002077\n#define MASK_RSTSA32 0xfe00707f\n#define MATCH_RSUB16 0x2000077\n#define MASK_RSUB16 0xfe00707f\n#define MATCH_RSUB32 0x2002077\n#define MASK_RSUB32 0xfe00707f\n#define MATCH_RSUB64 0x82001077\n#define MASK_RSUB64 0xfe00707f\n#define MATCH_RSUB8 0xa000077\n#define MASK_RSUB8 0xfe00707f\n#define MATCH_RSUBW 0x22001077\n#define MASK_RSUBW 0xfe00707f\n#define MATCH_SB 0x23\n#define MASK_SB 0x707f\n#define MATCH_SC_D 0x1800302f\n#define MASK_SC_D 0xf800707f\n#define MATCH_SC_W 0x1800202f\n#define MASK_SC_W 0xf800707f\n#define MATCH_SCLIP16 0x84000077\n#define MASK_SCLIP16 0xff00707f\n#define MATCH_SCLIP32 0xe4000077\n#define MASK_SCLIP32 0xfe00707f\n#define MATCH_SCLIP8 0x8c000077\n#define MASK_SCLIP8 0xff80707f\n#define MATCH_SCMPLE16 0x1c000077\n#define MASK_SCMPLE16 0xfe00707f\n#define MATCH_SCMPLE8 0x1e000077\n#define MASK_SCMPLE8 0xfe00707f\n#define MATCH_SCMPLT16 0xc000077\n#define MASK_SCMPLT16 0xfe00707f\n#define MATCH_SCMPLT8 0xe000077\n#define MASK_SCMPLT8 0xfe00707f\n#define MATCH_SD 0x3023\n#define MASK_SD 0x707f\n#define MATCH_SEXT_B 0x60401013\n#define MASK_SEXT_B 0xfff0707f\n#define MATCH_SEXT_H 0x60501013\n#define MASK_SEXT_H 0xfff0707f\n#define MATCH_SFENCE_INVAL_IR 0x18100073\n#define MASK_SFENCE_INVAL_IR 0xffffffff\n#define MATCH_SFENCE_VMA 0x12000073\n#define MASK_SFENCE_VMA 0xfe007fff\n#define MATCH_SFENCE_W_INVAL 0x18000073\n#define MASK_SFENCE_W_INVAL 0xffffffff\n#define MATCH_SH 0x1023\n#define MASK_SH 0x707f\n#define MATCH_SH1ADD 0x20002033\n#define MASK_SH1ADD 0xfe00707f\n#define MATCH_SH1ADD_UW 0x2000203b\n#define MASK_SH1ADD_UW 0xfe00707f\n#define MATCH_SH2ADD 0x20004033\n#define MASK_SH2ADD 0xfe00707f\n#define MATCH_SH2ADD_UW 0x2000403b\n#define MASK_SH2ADD_UW 0xfe00707f\n#define MATCH_SH3ADD 0x20006033\n#define MASK_SH3ADD 0xfe00707f\n#define MATCH_SH3ADD_UW 0x2000603b\n#define MASK_SH3ADD_UW 0xfe00707f\n#define MATCH_SHA256SIG0 0x10201013\n#define MASK_SHA256SIG0 0xfff0707f\n#define MATCH_SHA256SIG1 0x10301013\n#define MASK_SHA256SIG1 0xfff0707f\n#define MATCH_SHA256SUM0 0x10001013\n#define MASK_SHA256SUM0 0xfff0707f\n#define MATCH_SHA256SUM1 0x10101013\n#define MASK_SHA256SUM1 0xfff0707f\n#define MATCH_SHA512SIG0 0x10601013\n#define MASK_SHA512SIG0 0xfff0707f\n#define MATCH_SHA512SIG0H 0x5c000033\n#define MASK_SHA512SIG0H 0xfe00707f\n#define MATCH_SHA512SIG0L 0x54000033\n#define MASK_SHA512SIG0L 0xfe00707f\n#define MATCH_SHA512SIG1 0x10701013\n#define MASK_SHA512SIG1 0xfff0707f\n#define MATCH_SHA512SIG1H 0x5e000033\n#define MASK_SHA512SIG1H 0xfe00707f\n#define MATCH_SHA512SIG1L 0x56000033\n#define MASK_SHA512SIG1L 0xfe00707f\n#define MATCH_SHA512SUM0 0x10401013\n#define MASK_SHA512SUM0 0xfff0707f\n#define MATCH_SHA512SUM0R 0x50000033\n#define MASK_SHA512SUM0R 0xfe00707f\n#define MATCH_SHA512SUM1 0x10501013\n#define MASK_SHA512SUM1 0xfff0707f\n#define MATCH_SHA512SUM1R 0x52000033\n#define MASK_SHA512SUM1R 0xfe00707f\n#define MATCH_SHFL 0x8001033\n#define MASK_SHFL 0xfe00707f\n#define MATCH_SHFLI 0x8001013\n#define MASK_SHFLI 0xfe00707f\n#define MATCH_SHFLW 0x800103b\n#define MASK_SHFLW 0xfe00707f\n#define MATCH_SINVAL_VMA 0x16000073\n#define MASK_SINVAL_VMA 0xfe007fff\n#define MATCH_SLL 0x1033\n#define MASK_SLL 0xfe00707f\n#define MATCH_SLL16 0x54000077\n#define MASK_SLL16 0xfe00707f\n#define MATCH_SLL32 0x54002077\n#define MASK_SLL32 0xfe00707f\n#define MATCH_SLL8 0x5c000077\n#define MASK_SLL8 0xfe00707f\n#define MATCH_SLLD 0x107b\n#define MASK_SLLD 0xfe00707f\n#define MATCH_SLLI 0x1013\n#define MASK_SLLI 0xf800707f\n#define MATCH_SLLI16 0x74000077\n#define MASK_SLLI16 0xff00707f\n#define MATCH_SLLI32 0x74002077\n#define MASK_SLLI32 0xfe00707f\n#define MATCH_SLLI8 0x7c000077\n#define MASK_SLLI8 0xff80707f\n#define MATCH_SLLI_UW 0x800101b\n#define MASK_SLLI_UW 0xfc00707f\n#define MATCH_SLLID 0x105b\n#define MASK_SLLID 0xfc00707f\n#define MATCH_SLLIW 0x101b\n#define MASK_SLLIW 0xfe00707f\n#define MATCH_SLLW 0x103b\n#define MASK_SLLW 0xfe00707f\n#define MATCH_SLO 0x20001033\n#define MASK_SLO 0xfe00707f\n#define MATCH_SLOI 0x20001013\n#define MASK_SLOI 0xfc00707f\n#define MATCH_SLOIW 0x2000101b\n#define MASK_SLOIW 0xfe00707f\n#define MATCH_SLOW 0x2000103b\n#define MASK_SLOW 0xfe00707f\n#define MATCH_SLT 0x2033\n#define MASK_SLT 0xfe00707f\n#define MATCH_SLTI 0x2013\n#define MASK_SLTI 0x707f\n#define MATCH_SLTIU 0x3013\n#define MASK_SLTIU 0x707f\n#define MATCH_SLTU 0x3033\n#define MASK_SLTU 0xfe00707f\n#define MATCH_SM3P0 0x10801013\n#define MASK_SM3P0 0xfff0707f\n#define MATCH_SM3P1 0x10901013\n#define MASK_SM3P1 0xfff0707f\n#define MATCH_SM4ED 0x30000033\n#define MASK_SM4ED 0x3e00707f\n#define MATCH_SM4KS 0x34000033\n#define MASK_SM4KS 0x3e00707f\n#define MATCH_SMAL 0x5e001077\n#define MASK_SMAL 0xfe00707f\n#define MATCH_SMALBB 0x88001077\n#define MASK_SMALBB 0xfe00707f\n#define MATCH_SMALBT 0x98001077\n#define MASK_SMALBT 0xfe00707f\n#define MATCH_SMALDA 0x8c001077\n#define MASK_SMALDA 0xfe00707f\n#define MATCH_SMALDRS 0x9a001077\n#define MASK_SMALDRS 0xfe00707f\n#define MATCH_SMALDS 0x8a001077\n#define MASK_SMALDS 0xfe00707f\n#define MATCH_SMALTT 0xa8001077\n#define MASK_SMALTT 0xfe00707f\n#define MATCH_SMALXDA 0x9c001077\n#define MASK_SMALXDA 0xfe00707f\n#define MATCH_SMALXDS 0xaa001077\n#define MASK_SMALXDS 0xfe00707f\n#define MATCH_SMAQA 0xc8000077\n#define MASK_SMAQA 0xfe00707f\n#define MATCH_SMAQA_SU 0xca000077\n#define MASK_SMAQA_SU 0xfe00707f\n#define MATCH_SMAR64 0x84001077\n#define MASK_SMAR64 0xfe00707f\n#define MATCH_SMAX16 0x82000077\n#define MASK_SMAX16 0xfe00707f\n#define MATCH_SMAX32 0x92002077\n#define MASK_SMAX32 0xfe00707f\n#define MATCH_SMAX8 0x8a000077\n#define MASK_SMAX8 0xfe00707f\n#define MATCH_SMBB16 0x8001077\n#define MASK_SMBB16 0xfe00707f\n#define MATCH_SMBT16 0x18001077\n#define MASK_SMBT16 0xfe00707f\n#define MATCH_SMBT32 0x18002077\n#define MASK_SMBT32 0xfe00707f\n#define MATCH_SMDRS 0x68001077\n#define MASK_SMDRS 0xfe00707f\n#define MATCH_SMDRS32 0x68002077\n#define MASK_SMDRS32 0xfe00707f\n#define MATCH_SMDS 0x58001077\n#define MASK_SMDS 0xfe00707f\n#define MATCH_SMDS32 0x58002077\n#define MASK_SMDS32 0xfe00707f\n#define MATCH_SMIN16 0x80000077\n#define MASK_SMIN16 0xfe00707f\n#define MATCH_SMIN32 0x90002077\n#define MASK_SMIN32 0xfe00707f\n#define MATCH_SMIN8 0x88000077\n#define MASK_SMIN8 0xfe00707f\n#define MATCH_SMMUL 0x40001077\n#define MASK_SMMUL 0xfe00707f\n#define MATCH_SMMUL_U 0x50001077\n#define MASK_SMMUL_U 0xfe00707f\n#define MATCH_SMMWB 0x44001077\n#define MASK_SMMWB 0xfe00707f\n#define MATCH_SMMWB_U 0x54001077\n#define MASK_SMMWB_U 0xfe00707f\n#define MATCH_SMMWT 0x64001077\n#define MASK_SMMWT 0xfe00707f\n#define MATCH_SMMWT_U 0x74001077\n#define MASK_SMMWT_U 0xfe00707f\n#define MATCH_SMSLDA 0xac001077\n#define MASK_SMSLDA 0xfe00707f\n#define MATCH_SMSLXDA 0xbc001077\n#define MASK_SMSLXDA 0xfe00707f\n#define MATCH_SMSR64 0x86001077\n#define MASK_SMSR64 0xfe00707f\n#define MATCH_SMTT16 0x28001077\n#define MASK_SMTT16 0xfe00707f\n#define MATCH_SMTT32 0x28002077\n#define MASK_SMTT32 0xfe00707f\n#define MATCH_SMUL16 0xa0000077\n#define MASK_SMUL16 0xfe00707f\n#define MATCH_SMUL8 0xa8000077\n#define MASK_SMUL8 0xfe00707f\n#define MATCH_SMULX16 0xa2000077\n#define MASK_SMULX16 0xfe00707f\n#define MATCH_SMULX8 0xaa000077\n#define MASK_SMULX8 0xfe00707f\n#define MATCH_SMXDS 0x78001077\n#define MASK_SMXDS 0xfe00707f\n#define MATCH_SMXDS32 0x78002077\n#define MASK_SMXDS32 0xfe00707f\n#define MATCH_SQ 0x4023\n#define MASK_SQ 0x707f\n#define MATCH_SRA 0x40005033\n#define MASK_SRA 0xfe00707f\n#define MATCH_SRA16 0x50000077\n#define MASK_SRA16 0xfe00707f\n#define MATCH_SRA16_U 0x60000077\n#define MASK_SRA16_U 0xfe00707f\n#define MATCH_SRA32 0x50002077\n#define MASK_SRA32 0xfe00707f\n#define MATCH_SRA32_U 0x60002077\n#define MASK_SRA32_U 0xfe00707f\n#define MATCH_SRA8 0x58000077\n#define MASK_SRA8 0xfe00707f\n#define MATCH_SRA8_U 0x68000077\n#define MASK_SRA8_U 0xfe00707f\n#define MATCH_SRA_U 0x24001077\n#define MASK_SRA_U 0xfe00707f\n#define MATCH_SRAD 0x4000507b\n#define MASK_SRAD 0xfe00707f\n#define MATCH_SRAI 0x40005013\n#define MASK_SRAI 0xf800707f\n#define MATCH_SRAI16 0x70000077\n#define MASK_SRAI16 0xff00707f\n#define MATCH_SRAI16_U 0x71000077\n#define MASK_SRAI16_U 0xff00707f\n#define MATCH_SRAI32 0x70002077\n#define MASK_SRAI32 0xfe00707f\n#define MATCH_SRAI32_U 0x80002077\n#define MASK_SRAI32_U 0xfe00707f\n#define MATCH_SRAI8 0x78000077\n#define MASK_SRAI8 0xff80707f\n#define MATCH_SRAI8_U 0x78800077\n#define MASK_SRAI8_U 0xff80707f\n#define MATCH_SRAI_U 0xd4001077\n#define MASK_SRAI_U 0xfc00707f\n#define MATCH_SRAID 0x4000505b\n#define MASK_SRAID 0xfc00707f\n#define MATCH_SRAIW 0x4000501b\n#define MASK_SRAIW 0xfe00707f\n#define MATCH_SRAIW_U 0x34001077\n#define MASK_SRAIW_U 0xfe00707f\n#define MATCH_SRAW 0x4000503b\n#define MASK_SRAW 0xfe00707f\n#define MATCH_SRET 0x10200073\n#define MASK_SRET 0xffffffff\n#define MATCH_SRL 0x5033\n#define MASK_SRL 0xfe00707f\n#define MATCH_SRL16 0x52000077\n#define MASK_SRL16 0xfe00707f\n#define MATCH_SRL16_U 0x62000077\n#define MASK_SRL16_U 0xfe00707f\n#define MATCH_SRL32 0x52002077\n#define MASK_SRL32 0xfe00707f\n#define MATCH_SRL32_U 0x62002077\n#define MASK_SRL32_U 0xfe00707f\n#define MATCH_SRL8 0x5a000077\n#define MASK_SRL8 0xfe00707f\n#define MATCH_SRL8_U 0x6a000077\n#define MASK_SRL8_U 0xfe00707f\n#define MATCH_SRLD 0x507b\n#define MASK_SRLD 0xfe00707f\n#define MATCH_SRLI 0x5013\n#define MASK_SRLI 0xf800707f\n#define MATCH_SRLI16 0x72000077\n#define MASK_SRLI16 0xff00707f\n#define MATCH_SRLI16_U 0x73000077\n#define MASK_SRLI16_U 0xff00707f\n#define MATCH_SRLI32 0x72002077\n#define MASK_SRLI32 0xfe00707f\n#define MATCH_SRLI32_U 0x82002077\n#define MASK_SRLI32_U 0xfe00707f\n#define MATCH_SRLI8 0x7a000077\n#define MASK_SRLI8 0xff80707f\n#define MATCH_SRLI8_U 0x7a800077\n#define MASK_SRLI8_U 0xff80707f\n#define MATCH_SRLID 0x505b\n#define MASK_SRLID 0xfc00707f\n#define MATCH_SRLIW 0x501b\n#define MASK_SRLIW 0xfe00707f\n#define MATCH_SRLW 0x503b\n#define MASK_SRLW 0xfe00707f\n#define MATCH_SRO 0x20005033\n#define MASK_SRO 0xfe00707f\n#define MATCH_SROI 0x20005013\n#define MASK_SROI 0xfc00707f\n#define MATCH_SROIW 0x2000501b\n#define MASK_SROIW 0xfe00707f\n#define MATCH_SROW 0x2000503b\n#define MASK_SROW 0xfe00707f\n#define MATCH_STAS16 0xf4002077\n#define MASK_STAS16 0xfe00707f\n#define MATCH_STAS32 0xf0002077\n#define MASK_STAS32 0xfe00707f\n#define MATCH_STSA16 0xf6002077\n#define MASK_STSA16 0xfe00707f\n#define MATCH_STSA32 0xf2002077\n#define MASK_STSA32 0xfe00707f\n#define MATCH_SUB 0x40000033\n#define MASK_SUB 0xfe00707f\n#define MATCH_SUB16 0x42000077\n#define MASK_SUB16 0xfe00707f\n#define MATCH_SUB32 0x42002077\n#define MASK_SUB32 0xfe00707f\n#define MATCH_SUB64 0xc2001077\n#define MASK_SUB64 0xfe00707f\n#define MATCH_SUB8 0x4a000077\n#define MASK_SUB8 0xfe00707f\n#define MATCH_SUBD 0x4000007b\n#define MASK_SUBD 0xfe00707f\n#define MATCH_SUBW 0x4000003b\n#define MASK_SUBW 0xfe00707f\n#define MATCH_SUNPKD810 0xac800077\n#define MASK_SUNPKD810 0xfff0707f\n#define MATCH_SUNPKD820 0xac900077\n#define MASK_SUNPKD820 0xfff0707f\n#define MATCH_SUNPKD830 0xaca00077\n#define MASK_SUNPKD830 0xfff0707f\n#define MATCH_SUNPKD831 0xacb00077\n#define MASK_SUNPKD831 0xfff0707f\n#define MATCH_SUNPKD832 0xad300077\n#define MASK_SUNPKD832 0xfff0707f\n#define MATCH_SW 0x2023\n#define MASK_SW 0x707f\n#define MATCH_SWAP8 0xad800077\n#define MASK_SWAP8 0xfff0707f\n#define MATCH_UCLIP16 0x85000077\n#define MASK_UCLIP16 0xff00707f\n#define MATCH_UCLIP32 0xf4000077\n#define MASK_UCLIP32 0xfe00707f\n#define MATCH_UCLIP8 0x8d000077\n#define MASK_UCLIP8 0xff80707f\n#define MATCH_UCMPLE16 0x3c000077\n#define MASK_UCMPLE16 0xfe00707f\n#define MATCH_UCMPLE8 0x3e000077\n#define MASK_UCMPLE8 0xfe00707f\n#define MATCH_UCMPLT16 0x2c000077\n#define MASK_UCMPLT16 0xfe00707f\n#define MATCH_UCMPLT8 0x2e000077\n#define MASK_UCMPLT8 0xfe00707f\n#define MATCH_UKADD16 0x30000077\n#define MASK_UKADD16 0xfe00707f\n#define MATCH_UKADD32 0x30002077\n#define MASK_UKADD32 0xfe00707f\n#define MATCH_UKADD64 0xb0001077\n#define MASK_UKADD64 0xfe00707f\n#define MATCH_UKADD8 0x38000077\n#define MASK_UKADD8 0xfe00707f\n#define MATCH_UKADDH 0x14001077\n#define MASK_UKADDH 0xfe00707f\n#define MATCH_UKADDW 0x10001077\n#define MASK_UKADDW 0xfe00707f\n#define MATCH_UKCRAS16 0x34000077\n#define MASK_UKCRAS16 0xfe00707f\n#define MATCH_UKCRAS32 0x34002077\n#define MASK_UKCRAS32 0xfe00707f\n#define MATCH_UKCRSA16 0x36000077\n#define MASK_UKCRSA16 0xfe00707f\n#define MATCH_UKCRSA32 0x36002077\n#define MASK_UKCRSA32 0xfe00707f\n#define MATCH_UKMAR64 0xb4001077\n#define MASK_UKMAR64 0xfe00707f\n#define MATCH_UKMSR64 0xb6001077\n#define MASK_UKMSR64 0xfe00707f\n#define MATCH_UKSTAS16 0xe4002077\n#define MASK_UKSTAS16 0xfe00707f\n#define MATCH_UKSTAS32 0xe0002077\n#define MASK_UKSTAS32 0xfe00707f\n#define MATCH_UKSTSA16 0xe6002077\n#define MASK_UKSTSA16 0xfe00707f\n#define MATCH_UKSTSA32 0xe2002077\n#define MASK_UKSTSA32 0xfe00707f\n#define MATCH_UKSUB16 0x32000077\n#define MASK_UKSUB16 0xfe00707f\n#define MATCH_UKSUB32 0x32002077\n#define MASK_UKSUB32 0xfe00707f\n#define MATCH_UKSUB64 0xb2001077\n#define MASK_UKSUB64 0xfe00707f\n#define MATCH_UKSUB8 0x3a000077\n#define MASK_UKSUB8 0xfe00707f\n#define MATCH_UKSUBH 0x16001077\n#define MASK_UKSUBH 0xfe00707f\n#define MATCH_UKSUBW 0x12001077\n#define MASK_UKSUBW 0xfe00707f\n#define MATCH_UMAQA 0xcc000077\n#define MASK_UMAQA 0xfe00707f\n#define MATCH_UMAR64 0xa4001077\n#define MASK_UMAR64 0xfe00707f\n#define MATCH_UMAX16 0x92000077\n#define MASK_UMAX16 0xfe00707f\n#define MATCH_UMAX32 0xa2002077\n#define MASK_UMAX32 0xfe00707f\n#define MATCH_UMAX8 0x9a000077\n#define MASK_UMAX8 0xfe00707f\n#define MATCH_UMIN16 0x90000077\n#define MASK_UMIN16 0xfe00707f\n#define MATCH_UMIN32 0xa0002077\n#define MASK_UMIN32 0xfe00707f\n#define MATCH_UMIN8 0x98000077\n#define MASK_UMIN8 0xfe00707f\n#define MATCH_UMSR64 0xa6001077\n#define MASK_UMSR64 0xfe00707f\n#define MATCH_UMUL16 0xb0000077\n#define MASK_UMUL16 0xfe00707f\n#define MATCH_UMUL8 0xb8000077\n#define MASK_UMUL8 0xfe00707f\n#define MATCH_UMULX16 0xb2000077\n#define MASK_UMULX16 0xfe00707f\n#define MATCH_UMULX8 0xba000077\n#define MASK_UMULX8 0xfe00707f\n#define MATCH_UNSHFL 0x8005033\n#define MASK_UNSHFL 0xfe00707f\n#define MATCH_UNSHFLI 0x8005013\n#define MASK_UNSHFLI 0xfe00707f\n#define MATCH_UNSHFLW 0x800503b\n#define MASK_UNSHFLW 0xfe00707f\n#define MATCH_URADD16 0x20000077\n#define MASK_URADD16 0xfe00707f\n#define MATCH_URADD32 0x20002077\n#define MASK_URADD32 0xfe00707f\n#define MATCH_URADD64 0xa0001077\n#define MASK_URADD64 0xfe00707f\n#define MATCH_URADD8 0x28000077\n#define MASK_URADD8 0xfe00707f\n#define MATCH_URADDW 0x30001077\n#define MASK_URADDW 0xfe00707f\n#define MATCH_URCRAS16 0x24000077\n#define MASK_URCRAS16 0xfe00707f\n#define MATCH_URCRAS32 0x24002077\n#define MASK_URCRAS32 0xfe00707f\n#define MATCH_URCRSA16 0x26000077\n#define MASK_URCRSA16 0xfe00707f\n#define MATCH_URCRSA32 0x26002077\n#define MASK_URCRSA32 0xfe00707f\n#define MATCH_URSTAS16 0xd4002077\n#define MASK_URSTAS16 0xfe00707f\n#define MATCH_URSTAS32 0xd0002077\n#define MASK_URSTAS32 0xfe00707f\n#define MATCH_URSTSA16 0xd6002077\n#define MASK_URSTSA16 0xfe00707f\n#define MATCH_URSTSA32 0xd2002077\n#define MASK_URSTSA32 0xfe00707f\n#define MATCH_URSUB16 0x22000077\n#define MASK_URSUB16 0xfe00707f\n#define MATCH_URSUB32 0x22002077\n#define MASK_URSUB32 0xfe00707f\n#define MATCH_URSUB64 0xa2001077\n#define MASK_URSUB64 0xfe00707f\n#define MATCH_URSUB8 0x2a000077\n#define MASK_URSUB8 0xfe00707f\n#define MATCH_URSUBW 0x32001077\n#define MASK_URSUBW 0xfe00707f\n#define MATCH_VAADD_VV 0x24002057\n#define MASK_VAADD_VV 0xfc00707f\n#define MATCH_VAADD_VX 0x24006057\n#define MASK_VAADD_VX 0xfc00707f\n#define MATCH_VAADDU_VV 0x20002057\n#define MASK_VAADDU_VV 0xfc00707f\n#define MATCH_VAADDU_VX 0x20006057\n#define MASK_VAADDU_VX 0xfc00707f\n#define MATCH_VADC_VIM 0x40003057\n#define MASK_VADC_VIM 0xfe00707f\n#define MATCH_VADC_VVM 0x40000057\n#define MASK_VADC_VVM 0xfe00707f\n#define MATCH_VADC_VXM 0x40004057\n#define MASK_VADC_VXM 0xfe00707f\n#define MATCH_VADD_VI 0x3057\n#define MASK_VADD_VI 0xfc00707f\n#define MATCH_VADD_VV 0x57\n#define MASK_VADD_VV 0xfc00707f\n#define MATCH_VADD_VX 0x4057\n#define MASK_VADD_VX 0xfc00707f\n#define MATCH_VAMOADDEI16_V 0x502f\n#define MASK_VAMOADDEI16_V 0xf800707f\n#define MATCH_VAMOADDEI32_V 0x602f\n#define MASK_VAMOADDEI32_V 0xf800707f\n#define MATCH_VAMOADDEI64_V 0x702f\n#define MASK_VAMOADDEI64_V 0xf800707f\n#define MATCH_VAMOADDEI8_V 0x2f\n#define MASK_VAMOADDEI8_V 0xf800707f\n#define MATCH_VAMOANDEI16_V 0x6000502f\n#define MASK_VAMOANDEI16_V 0xf800707f\n#define MATCH_VAMOANDEI32_V 0x6000602f\n#define MASK_VAMOANDEI32_V 0xf800707f\n#define MATCH_VAMOANDEI64_V 0x6000702f\n#define MASK_VAMOANDEI64_V 0xf800707f\n#define MATCH_VAMOANDEI8_V 0x6000002f\n#define MASK_VAMOANDEI8_V 0xf800707f\n#define MATCH_VAMOMAXEI16_V 0xa000502f\n#define MASK_VAMOMAXEI16_V 0xf800707f\n#define MATCH_VAMOMAXEI32_V 0xa000602f\n#define MASK_VAMOMAXEI32_V 0xf800707f\n#define MATCH_VAMOMAXEI64_V 0xa000702f\n#define MASK_VAMOMAXEI64_V 0xf800707f\n#define MATCH_VAMOMAXEI8_V 0xa000002f\n#define MASK_VAMOMAXEI8_V 0xf800707f\n#define MATCH_VAMOMAXUEI16_V 0xe000502f\n#define MASK_VAMOMAXUEI16_V 0xf800707f\n#define MATCH_VAMOMAXUEI32_V 0xe000602f\n#define MASK_VAMOMAXUEI32_V 0xf800707f\n#define MATCH_VAMOMAXUEI64_V 0xe000702f\n#define MASK_VAMOMAXUEI64_V 0xf800707f\n#define MATCH_VAMOMAXUEI8_V 0xe000002f\n#define MASK_VAMOMAXUEI8_V 0xf800707f\n#define MATCH_VAMOMINEI16_V 0x8000502f\n#define MASK_VAMOMINEI16_V 0xf800707f\n#define MATCH_VAMOMINEI32_V 0x8000602f\n#define MASK_VAMOMINEI32_V 0xf800707f\n#define MATCH_VAMOMINEI64_V 0x8000702f\n#define MASK_VAMOMINEI64_V 0xf800707f\n#define MATCH_VAMOMINEI8_V 0x8000002f\n#define MASK_VAMOMINEI8_V 0xf800707f\n#define MATCH_VAMOMINUEI16_V 0xc000502f\n#define MASK_VAMOMINUEI16_V 0xf800707f\n#define MATCH_VAMOMINUEI32_V 0xc000602f\n#define MASK_VAMOMINUEI32_V 0xf800707f\n#define MATCH_VAMOMINUEI64_V 0xc000702f\n#define MASK_VAMOMINUEI64_V 0xf800707f\n#define MATCH_VAMOMINUEI8_V 0xc000002f\n#define MASK_VAMOMINUEI8_V 0xf800707f\n#define MATCH_VAMOOREI16_V 0x4000502f\n#define MASK_VAMOOREI16_V 0xf800707f\n#define MATCH_VAMOOREI32_V 0x4000602f\n#define MASK_VAMOOREI32_V 0xf800707f\n#define MATCH_VAMOOREI64_V 0x4000702f\n#define MASK_VAMOOREI64_V 0xf800707f\n#define MATCH_VAMOOREI8_V 0x4000002f\n#define MASK_VAMOOREI8_V 0xf800707f\n#define MATCH_VAMOSWAPEI16_V 0x800502f\n#define MASK_VAMOSWAPEI16_V 0xf800707f\n#define MATCH_VAMOSWAPEI32_V 0x800602f\n#define MASK_VAMOSWAPEI32_V 0xf800707f\n#define MATCH_VAMOSWAPEI64_V 0x800702f\n#define MASK_VAMOSWAPEI64_V 0xf800707f\n#define MATCH_VAMOSWAPEI8_V 0x800002f\n#define MASK_VAMOSWAPEI8_V 0xf800707f\n#define MATCH_VAMOXOREI16_V 0x2000502f\n#define MASK_VAMOXOREI16_V 0xf800707f\n#define MATCH_VAMOXOREI32_V 0x2000602f\n#define MASK_VAMOXOREI32_V 0xf800707f\n#define MATCH_VAMOXOREI64_V 0x2000702f\n#define MASK_VAMOXOREI64_V 0xf800707f\n#define MATCH_VAMOXOREI8_V 0x2000002f\n#define MASK_VAMOXOREI8_V 0xf800707f\n#define MATCH_VAND_VI 0x24003057\n#define MASK_VAND_VI 0xfc00707f\n#define MATCH_VAND_VV 0x24000057\n#define MASK_VAND_VV 0xfc00707f\n#define MATCH_VAND_VX 0x24004057\n#define MASK_VAND_VX 0xfc00707f\n#define MATCH_VASUB_VV 0x2c002057\n#define MASK_VASUB_VV 0xfc00707f\n#define MATCH_VASUB_VX 0x2c006057\n#define MASK_VASUB_VX 0xfc00707f\n#define MATCH_VASUBU_VV 0x28002057\n#define MASK_VASUBU_VV 0xfc00707f\n#define MATCH_VASUBU_VX 0x28006057\n#define MASK_VASUBU_VX 0xfc00707f\n#define MATCH_VCOMPRESS_VM 0x5e002057\n#define MASK_VCOMPRESS_VM 0xfe00707f\n#define MATCH_VCPOP_M 0x40082057\n#define MASK_VCPOP_M 0xfc0ff07f\n#define MATCH_VDIV_VV 0x84002057\n#define MASK_VDIV_VV 0xfc00707f\n#define MATCH_VDIV_VX 0x84006057\n#define MASK_VDIV_VX 0xfc00707f\n#define MATCH_VDIVU_VV 0x80002057\n#define MASK_VDIVU_VV 0xfc00707f\n#define MATCH_VDIVU_VX 0x80006057\n#define MASK_VDIVU_VX 0xfc00707f\n#define MATCH_VFADD_VF 0x5057\n#define MASK_VFADD_VF 0xfc00707f\n#define MATCH_VFADD_VV 0x1057\n#define MASK_VFADD_VV 0xfc00707f\n#define MATCH_VFCLASS_V 0x4c081057\n#define MASK_VFCLASS_V 0xfc0ff07f\n#define MATCH_VFCVT_F_X_V 0x48019057\n#define MASK_VFCVT_F_X_V 0xfc0ff07f\n#define MATCH_VFCVT_F_XU_V 0x48011057\n#define MASK_VFCVT_F_XU_V 0xfc0ff07f\n#define MATCH_VFCVT_RTZ_X_F_V 0x48039057\n#define MASK_VFCVT_RTZ_X_F_V 0xfc0ff07f\n#define MATCH_VFCVT_RTZ_XU_F_V 0x48031057\n#define MASK_VFCVT_RTZ_XU_F_V 0xfc0ff07f\n#define MATCH_VFCVT_X_F_V 0x48009057\n#define MASK_VFCVT_X_F_V 0xfc0ff07f\n#define MATCH_VFCVT_XU_F_V 0x48001057\n#define MASK_VFCVT_XU_F_V 0xfc0ff07f\n#define MATCH_VFDIV_VF 0x80005057\n#define MASK_VFDIV_VF 0xfc00707f\n#define MATCH_VFDIV_VV 0x80001057\n#define MASK_VFDIV_VV 0xfc00707f\n#define MATCH_VFIRST_M 0x4008a057\n#define MASK_VFIRST_M 0xfc0ff07f\n#define MATCH_VFMACC_VF 0xb0005057\n#define MASK_VFMACC_VF 0xfc00707f\n#define MATCH_VFMACC_VV 0xb0001057\n#define MASK_VFMACC_VV 0xfc00707f\n#define MATCH_VFMADD_VF 0xa0005057\n#define MASK_VFMADD_VF 0xfc00707f\n#define MATCH_VFMADD_VV 0xa0001057\n#define MASK_VFMADD_VV 0xfc00707f\n#define MATCH_VFMAX_VF 0x18005057\n#define MASK_VFMAX_VF 0xfc00707f\n#define MATCH_VFMAX_VV 0x18001057\n#define MASK_VFMAX_VV 0xfc00707f\n#define MATCH_VFMERGE_VFM 0x5c005057\n#define MASK_VFMERGE_VFM 0xfe00707f\n#define MATCH_VFMIN_VF 0x10005057\n#define MASK_VFMIN_VF 0xfc00707f\n#define MATCH_VFMIN_VV 0x10001057\n#define MASK_VFMIN_VV 0xfc00707f\n#define MATCH_VFMSAC_VF 0xb8005057\n#define MASK_VFMSAC_VF 0xfc00707f\n#define MATCH_VFMSAC_VV 0xb8001057\n#define MASK_VFMSAC_VV 0xfc00707f\n#define MATCH_VFMSUB_VF 0xa8005057\n#define MASK_VFMSUB_VF 0xfc00707f\n#define MATCH_VFMSUB_VV 0xa8001057\n#define MASK_VFMSUB_VV 0xfc00707f\n#define MATCH_VFMUL_VF 0x90005057\n#define MASK_VFMUL_VF 0xfc00707f\n#define MATCH_VFMUL_VV 0x90001057\n#define MASK_VFMUL_VV 0xfc00707f\n#define MATCH_VFMV_F_S 0x42001057\n#define MASK_VFMV_F_S 0xfe0ff07f\n#define MATCH_VFMV_S_F 0x42005057\n#define MASK_VFMV_S_F 0xfff0707f\n#define MATCH_VFMV_V_F 0x5e005057\n#define MASK_VFMV_V_F 0xfff0707f\n#define MATCH_VFNCVT_F_F_W 0x480a1057\n#define MASK_VFNCVT_F_F_W 0xfc0ff07f\n#define MATCH_VFNCVT_F_X_W 0x48099057\n#define MASK_VFNCVT_F_X_W 0xfc0ff07f\n#define MATCH_VFNCVT_F_XU_W 0x48091057\n#define MASK_VFNCVT_F_XU_W 0xfc0ff07f\n#define MATCH_VFNCVT_ROD_F_F_W 0x480a9057\n#define MASK_VFNCVT_ROD_F_F_W 0xfc0ff07f\n#define MATCH_VFNCVT_RTZ_X_F_W 0x480b9057\n#define MASK_VFNCVT_RTZ_X_F_W 0xfc0ff07f\n#define MATCH_VFNCVT_RTZ_XU_F_W 0x480b1057\n#define MASK_VFNCVT_RTZ_XU_F_W 0xfc0ff07f\n#define MATCH_VFNCVT_X_F_W 0x48089057\n#define MASK_VFNCVT_X_F_W 0xfc0ff07f\n#define MATCH_VFNCVT_XU_F_W 0x48081057\n#define MASK_VFNCVT_XU_F_W 0xfc0ff07f\n#define MATCH_VFNMACC_VF 0xb4005057\n#define MASK_VFNMACC_VF 0xfc00707f\n#define MATCH_VFNMACC_VV 0xb4001057\n#define MASK_VFNMACC_VV 0xfc00707f\n#define MATCH_VFNMADD_VF 0xa4005057\n#define MASK_VFNMADD_VF 0xfc00707f\n#define MATCH_VFNMADD_VV 0xa4001057\n#define MASK_VFNMADD_VV 0xfc00707f\n#define MATCH_VFNMSAC_VF 0xbc005057\n#define MASK_VFNMSAC_VF 0xfc00707f\n#define MATCH_VFNMSAC_VV 0xbc001057\n#define MASK_VFNMSAC_VV 0xfc00707f\n#define MATCH_VFNMSUB_VF 0xac005057\n#define MASK_VFNMSUB_VF 0xfc00707f\n#define MATCH_VFNMSUB_VV 0xac001057\n#define MASK_VFNMSUB_VV 0xfc00707f\n#define MATCH_VFRDIV_VF 0x84005057\n#define MASK_VFRDIV_VF 0xfc00707f\n#define MATCH_VFREC7_V 0x4c029057\n#define MASK_VFREC7_V 0xfc0ff07f\n#define MATCH_VFREDMAX_VS 0x1c001057\n#define MASK_VFREDMAX_VS 0xfc00707f\n#define MATCH_VFREDMIN_VS 0x14001057\n#define MASK_VFREDMIN_VS 0xfc00707f\n#define MATCH_VFREDOSUM_VS 0xc001057\n#define MASK_VFREDOSUM_VS 0xfc00707f\n#define MATCH_VFREDUSUM_VS 0x4001057\n#define MASK_VFREDUSUM_VS 0xfc00707f\n#define MATCH_VFRSQRT7_V 0x4c021057\n#define MASK_VFRSQRT7_V 0xfc0ff07f\n#define MATCH_VFRSUB_VF 0x9c005057\n#define MASK_VFRSUB_VF 0xfc00707f\n#define MATCH_VFSGNJ_VF 0x20005057\n#define MASK_VFSGNJ_VF 0xfc00707f\n#define MATCH_VFSGNJ_VV 0x20001057\n#define MASK_VFSGNJ_VV 0xfc00707f\n#define MATCH_VFSGNJN_VF 0x24005057\n#define MASK_VFSGNJN_VF 0xfc00707f\n#define MATCH_VFSGNJN_VV 0x24001057\n#define MASK_VFSGNJN_VV 0xfc00707f\n#define MATCH_VFSGNJX_VF 0x28005057\n#define MASK_VFSGNJX_VF 0xfc00707f\n#define MATCH_VFSGNJX_VV 0x28001057\n#define MASK_VFSGNJX_VV 0xfc00707f\n#define MATCH_VFSLIDE1DOWN_VF 0x3c005057\n#define MASK_VFSLIDE1DOWN_VF 0xfc00707f\n#define MATCH_VFSLIDE1UP_VF 0x38005057\n#define MASK_VFSLIDE1UP_VF 0xfc00707f\n#define MATCH_VFSQRT_V 0x4c001057\n#define MASK_VFSQRT_V 0xfc0ff07f\n#define MATCH_VFSUB_VF 0x8005057\n#define MASK_VFSUB_VF 0xfc00707f\n#define MATCH_VFSUB_VV 0x8001057\n#define MASK_VFSUB_VV 0xfc00707f\n#define MATCH_VFWADD_VF 0xc0005057\n#define MASK_VFWADD_VF 0xfc00707f\n#define MATCH_VFWADD_VV 0xc0001057\n#define MASK_VFWADD_VV 0xfc00707f\n#define MATCH_VFWADD_WF 0xd0005057\n#define MASK_VFWADD_WF 0xfc00707f\n#define MATCH_VFWADD_WV 0xd0001057\n#define MASK_VFWADD_WV 0xfc00707f\n#define MATCH_VFWCVT_F_F_V 0x48061057\n#define MASK_VFWCVT_F_F_V 0xfc0ff07f\n#define MATCH_VFWCVT_F_X_V 0x48059057\n#define MASK_VFWCVT_F_X_V 0xfc0ff07f\n#define MATCH_VFWCVT_F_XU_V 0x48051057\n#define MASK_VFWCVT_F_XU_V 0xfc0ff07f\n#define MATCH_VFWCVT_RTZ_X_F_V 0x48079057\n#define MASK_VFWCVT_RTZ_X_F_V 0xfc0ff07f\n#define MATCH_VFWCVT_RTZ_XU_F_V 0x48071057\n#define MASK_VFWCVT_RTZ_XU_F_V 0xfc0ff07f\n#define MATCH_VFWCVT_X_F_V 0x48049057\n#define MASK_VFWCVT_X_F_V 0xfc0ff07f\n#define MATCH_VFWCVT_XU_F_V 0x48041057\n#define MASK_VFWCVT_XU_F_V 0xfc0ff07f\n#define MATCH_VFWMACC_VF 0xf0005057\n#define MASK_VFWMACC_VF 0xfc00707f\n#define MATCH_VFWMACC_VV 0xf0001057\n#define MASK_VFWMACC_VV 0xfc00707f\n#define MATCH_VFWMSAC_VF 0xf8005057\n#define MASK_VFWMSAC_VF 0xfc00707f\n#define MATCH_VFWMSAC_VV 0xf8001057\n#define MASK_VFWMSAC_VV 0xfc00707f\n#define MATCH_VFWMUL_VF 0xe0005057\n#define MASK_VFWMUL_VF 0xfc00707f\n#define MATCH_VFWMUL_VV 0xe0001057\n#define MASK_VFWMUL_VV 0xfc00707f\n#define MATCH_VFWNMACC_VF 0xf4005057\n#define MASK_VFWNMACC_VF 0xfc00707f\n#define MATCH_VFWNMACC_VV 0xf4001057\n#define MASK_VFWNMACC_VV 0xfc00707f\n#define MATCH_VFWNMSAC_VF 0xfc005057\n#define MASK_VFWNMSAC_VF 0xfc00707f\n#define MATCH_VFWNMSAC_VV 0xfc001057\n#define MASK_VFWNMSAC_VV 0xfc00707f\n#define MATCH_VFWREDOSUM_VS 0xcc001057\n#define MASK_VFWREDOSUM_VS 0xfc00707f\n#define MATCH_VFWREDUSUM_VS 0xc4001057\n#define MASK_VFWREDUSUM_VS 0xfc00707f\n#define MATCH_VFWSUB_VF 0xc8005057\n#define MASK_VFWSUB_VF 0xfc00707f\n#define MATCH_VFWSUB_VV 0xc8001057\n#define MASK_VFWSUB_VV 0xfc00707f\n#define MATCH_VFWSUB_WF 0xd8005057\n#define MASK_VFWSUB_WF 0xfc00707f\n#define MATCH_VFWSUB_WV 0xd8001057\n#define MASK_VFWSUB_WV 0xfc00707f\n#define MATCH_VID_V 0x5008a057\n#define MASK_VID_V 0xfdfff07f\n#define MATCH_VIOTA_M 0x50082057\n#define MASK_VIOTA_M 0xfc0ff07f\n#define MATCH_VL1RE16_V 0x2805007\n#define MASK_VL1RE16_V 0xfff0707f\n#define MATCH_VL1RE32_V 0x2806007\n#define MASK_VL1RE32_V 0xfff0707f\n#define MATCH_VL1RE64_V 0x2807007\n#define MASK_VL1RE64_V 0xfff0707f\n#define MATCH_VL1RE8_V 0x2800007\n#define MASK_VL1RE8_V 0xfff0707f\n#define MATCH_VL2RE16_V 0x22805007\n#define MASK_VL2RE16_V 0xfff0707f\n#define MATCH_VL2RE32_V 0x22806007\n#define MASK_VL2RE32_V 0xfff0707f\n#define MATCH_VL2RE64_V 0x22807007\n#define MASK_VL2RE64_V 0xfff0707f\n#define MATCH_VL2RE8_V 0x22800007\n#define MASK_VL2RE8_V 0xfff0707f\n#define MATCH_VL4RE16_V 0x62805007\n#define MASK_VL4RE16_V 0xfff0707f\n#define MATCH_VL4RE32_V 0x62806007\n#define MASK_VL4RE32_V 0xfff0707f\n#define MATCH_VL4RE64_V 0x62807007\n#define MASK_VL4RE64_V 0xfff0707f\n#define MATCH_VL4RE8_V 0x62800007\n#define MASK_VL4RE8_V 0xfff0707f\n#define MATCH_VL8RE16_V 0xe2805007\n#define MASK_VL8RE16_V 0xfff0707f\n#define MATCH_VL8RE32_V 0xe2806007\n#define MASK_VL8RE32_V 0xfff0707f\n#define MATCH_VL8RE64_V 0xe2807007\n#define MASK_VL8RE64_V 0xfff0707f\n#define MATCH_VL8RE8_V 0xe2800007\n#define MASK_VL8RE8_V 0xfff0707f\n#define MATCH_VLE1024_V 0x10007007\n#define MASK_VLE1024_V 0x1df0707f\n#define MATCH_VLE1024FF_V 0x11007007\n#define MASK_VLE1024FF_V 0x1df0707f\n#define MATCH_VLE128_V 0x10000007\n#define MASK_VLE128_V 0x1df0707f\n#define MATCH_VLE128FF_V 0x11000007\n#define MASK_VLE128FF_V 0x1df0707f\n#define MATCH_VLE16_V 0x5007\n#define MASK_VLE16_V 0x1df0707f\n#define MATCH_VLE16FF_V 0x1005007\n#define MASK_VLE16FF_V 0x1df0707f\n#define MATCH_VLE256_V 0x10005007\n#define MASK_VLE256_V 0x1df0707f\n#define MATCH_VLE256FF_V 0x11005007\n#define MASK_VLE256FF_V 0x1df0707f\n#define MATCH_VLE32_V 0x6007\n#define MASK_VLE32_V 0x1df0707f\n#define MATCH_VLE32FF_V 0x1006007\n#define MASK_VLE32FF_V 0x1df0707f\n#define MATCH_VLE512_V 0x10006007\n#define MASK_VLE512_V 0x1df0707f\n#define MATCH_VLE512FF_V 0x11006007\n#define MASK_VLE512FF_V 0x1df0707f\n#define MATCH_VLE64_V 0x7007\n#define MASK_VLE64_V 0x1df0707f\n#define MATCH_VLE64FF_V 0x1007007\n#define MASK_VLE64FF_V 0x1df0707f\n#define MATCH_VLE8_V 0x7\n#define MASK_VLE8_V 0x1df0707f\n#define MATCH_VLE8FF_V 0x1000007\n#define MASK_VLE8FF_V 0x1df0707f\n#define MATCH_VLM_V 0x2b00007\n#define MASK_VLM_V 0xfff0707f\n#define MATCH_VLOXEI1024_V 0x1c007007\n#define MASK_VLOXEI1024_V 0x1c00707f\n#define MATCH_VLOXEI128_V 0x1c000007\n#define MASK_VLOXEI128_V 0x1c00707f\n#define MATCH_VLOXEI16_V 0xc005007\n#define MASK_VLOXEI16_V 0x1c00707f\n#define MATCH_VLOXEI256_V 0x1c005007\n#define MASK_VLOXEI256_V 0x1c00707f\n#define MATCH_VLOXEI32_V 0xc006007\n#define MASK_VLOXEI32_V 0x1c00707f\n#define MATCH_VLOXEI512_V 0x1c006007\n#define MASK_VLOXEI512_V 0x1c00707f\n#define MATCH_VLOXEI64_V 0xc007007\n#define MASK_VLOXEI64_V 0x1c00707f\n#define MATCH_VLOXEI8_V 0xc000007\n#define MASK_VLOXEI8_V 0x1c00707f\n#define MATCH_VLSE1024_V 0x18007007\n#define MASK_VLSE1024_V 0x1c00707f\n#define MATCH_VLSE128_V 0x18000007\n#define MASK_VLSE128_V 0x1c00707f\n#define MATCH_VLSE16_V 0x8005007\n#define MASK_VLSE16_V 0x1c00707f\n#define MATCH_VLSE256_V 0x18005007\n#define MASK_VLSE256_V 0x1c00707f\n#define MATCH_VLSE32_V 0x8006007\n#define MASK_VLSE32_V 0x1c00707f\n#define MATCH_VLSE512_V 0x18006007\n#define MASK_VLSE512_V 0x1c00707f\n#define MATCH_VLSE64_V 0x8007007\n#define MASK_VLSE64_V 0x1c00707f\n#define MATCH_VLSE8_V 0x8000007\n#define MASK_VLSE8_V 0x1c00707f\n#define MATCH_VLUXEI1024_V 0x14007007\n#define MASK_VLUXEI1024_V 0x1c00707f\n#define MATCH_VLUXEI128_V 0x14000007\n#define MASK_VLUXEI128_V 0x1c00707f\n#define MATCH_VLUXEI16_V 0x4005007\n#define MASK_VLUXEI16_V 0x1c00707f\n#define MATCH_VLUXEI256_V 0x14005007\n#define MASK_VLUXEI256_V 0x1c00707f\n#define MATCH_VLUXEI32_V 0x4006007\n#define MASK_VLUXEI32_V 0x1c00707f\n#define MATCH_VLUXEI512_V 0x14006007\n#define MASK_VLUXEI512_V 0x1c00707f\n#define MATCH_VLUXEI64_V 0x4007007\n#define MASK_VLUXEI64_V 0x1c00707f\n#define MATCH_VLUXEI8_V 0x4000007\n#define MASK_VLUXEI8_V 0x1c00707f\n#define MATCH_VMACC_VV 0xb4002057\n#define MASK_VMACC_VV 0xfc00707f\n#define MATCH_VMACC_VX 0xb4006057\n#define MASK_VMACC_VX 0xfc00707f\n#define MATCH_VMADC_VI 0x46003057\n#define MASK_VMADC_VI 0xfe00707f\n#define MATCH_VMADC_VIM 0x44003057\n#define MASK_VMADC_VIM 0xfe00707f\n#define MATCH_VMADC_VV 0x46000057\n#define MASK_VMADC_VV 0xfe00707f\n#define MATCH_VMADC_VVM 0x44000057\n#define MASK_VMADC_VVM 0xfe00707f\n#define MATCH_VMADC_VX 0x46004057\n#define MASK_VMADC_VX 0xfe00707f\n#define MATCH_VMADC_VXM 0x44004057\n#define MASK_VMADC_VXM 0xfe00707f\n#define MATCH_VMADD_VV 0xa4002057\n#define MASK_VMADD_VV 0xfc00707f\n#define MATCH_VMADD_VX 0xa4006057\n#define MASK_VMADD_VX 0xfc00707f\n#define MATCH_VMAND_MM 0x64002057\n#define MASK_VMAND_MM 0xfc00707f\n#define MATCH_VMANDN_MM 0x60002057\n#define MASK_VMANDN_MM 0xfc00707f\n#define MATCH_VMAX_VV 0x1c000057\n#define MASK_VMAX_VV 0xfc00707f\n#define MATCH_VMAX_VX 0x1c004057\n#define MASK_VMAX_VX 0xfc00707f\n#define MATCH_VMAXU_VV 0x18000057\n#define MASK_VMAXU_VV 0xfc00707f\n#define MATCH_VMAXU_VX 0x18004057\n#define MASK_VMAXU_VX 0xfc00707f\n#define MATCH_VMERGE_VIM 0x5c003057\n#define MASK_VMERGE_VIM 0xfe00707f\n#define MATCH_VMERGE_VVM 0x5c000057\n#define MASK_VMERGE_VVM 0xfe00707f\n#define MATCH_VMERGE_VXM 0x5c004057\n#define MASK_VMERGE_VXM 0xfe00707f\n#define MATCH_VMFEQ_VF 0x60005057\n#define MASK_VMFEQ_VF 0xfc00707f\n#define MATCH_VMFEQ_VV 0x60001057\n#define MASK_VMFEQ_VV 0xfc00707f\n#define MATCH_VMFGE_VF 0x7c005057\n#define MASK_VMFGE_VF 0xfc00707f\n#define MATCH_VMFGT_VF 0x74005057\n#define MASK_VMFGT_VF 0xfc00707f\n#define MATCH_VMFLE_VF 0x64005057\n#define MASK_VMFLE_VF 0xfc00707f\n#define MATCH_VMFLE_VV 0x64001057\n#define MASK_VMFLE_VV 0xfc00707f\n#define MATCH_VMFLT_VF 0x6c005057\n#define MASK_VMFLT_VF 0xfc00707f\n#define MATCH_VMFLT_VV 0x6c001057\n#define MASK_VMFLT_VV 0xfc00707f\n#define MATCH_VMFNE_VF 0x70005057\n#define MASK_VMFNE_VF 0xfc00707f\n#define MATCH_VMFNE_VV 0x70001057\n#define MASK_VMFNE_VV 0xfc00707f\n#define MATCH_VMIN_VV 0x14000057\n#define MASK_VMIN_VV 0xfc00707f\n#define MATCH_VMIN_VX 0x14004057\n#define MASK_VMIN_VX 0xfc00707f\n#define MATCH_VMINU_VV 0x10000057\n#define MASK_VMINU_VV 0xfc00707f\n#define MATCH_VMINU_VX 0x10004057\n#define MASK_VMINU_VX 0xfc00707f\n#define MATCH_VMNAND_MM 0x74002057\n#define MASK_VMNAND_MM 0xfc00707f\n#define MATCH_VMNOR_MM 0x78002057\n#define MASK_VMNOR_MM 0xfc00707f\n#define MATCH_VMOR_MM 0x68002057\n#define MASK_VMOR_MM 0xfc00707f\n#define MATCH_VMORN_MM 0x70002057\n#define MASK_VMORN_MM 0xfc00707f\n#define MATCH_VMSBC_VV 0x4e000057\n#define MASK_VMSBC_VV 0xfe00707f\n#define MATCH_VMSBC_VVM 0x4c000057\n#define MASK_VMSBC_VVM 0xfe00707f\n#define MATCH_VMSBC_VX 0x4e004057\n#define MASK_VMSBC_VX 0xfe00707f\n#define MATCH_VMSBC_VXM 0x4c004057\n#define MASK_VMSBC_VXM 0xfe00707f\n#define MATCH_VMSBF_M 0x5000a057\n#define MASK_VMSBF_M 0xfc0ff07f\n#define MATCH_VMSEQ_VI 0x60003057\n#define MASK_VMSEQ_VI 0xfc00707f\n#define MATCH_VMSEQ_VV 0x60000057\n#define MASK_VMSEQ_VV 0xfc00707f\n#define MATCH_VMSEQ_VX 0x60004057\n#define MASK_VMSEQ_VX 0xfc00707f\n#define MATCH_VMSGT_VI 0x7c003057\n#define MASK_VMSGT_VI 0xfc00707f\n#define MATCH_VMSGT_VX 0x7c004057\n#define MASK_VMSGT_VX 0xfc00707f\n#define MATCH_VMSGTU_VI 0x78003057\n#define MASK_VMSGTU_VI 0xfc00707f\n#define MATCH_VMSGTU_VX 0x78004057\n#define MASK_VMSGTU_VX 0xfc00707f\n#define MATCH_VMSIF_M 0x5001a057\n#define MASK_VMSIF_M 0xfc0ff07f\n#define MATCH_VMSLE_VI 0x74003057\n#define MASK_VMSLE_VI 0xfc00707f\n#define MATCH_VMSLE_VV 0x74000057\n#define MASK_VMSLE_VV 0xfc00707f\n#define MATCH_VMSLE_VX 0x74004057\n#define MASK_VMSLE_VX 0xfc00707f\n#define MATCH_VMSLEU_VI 0x70003057\n#define MASK_VMSLEU_VI 0xfc00707f\n#define MATCH_VMSLEU_VV 0x70000057\n#define MASK_VMSLEU_VV 0xfc00707f\n#define MATCH_VMSLEU_VX 0x70004057\n#define MASK_VMSLEU_VX 0xfc00707f\n#define MATCH_VMSLT_VV 0x6c000057\n#define MASK_VMSLT_VV 0xfc00707f\n#define MATCH_VMSLT_VX 0x6c004057\n#define MASK_VMSLT_VX 0xfc00707f\n#define MATCH_VMSLTU_VV 0x68000057\n#define MASK_VMSLTU_VV 0xfc00707f\n#define MATCH_VMSLTU_VX 0x68004057\n#define MASK_VMSLTU_VX 0xfc00707f\n#define MATCH_VMSNE_VI 0x64003057\n#define MASK_VMSNE_VI 0xfc00707f\n#define MATCH_VMSNE_VV 0x64000057\n#define MASK_VMSNE_VV 0xfc00707f\n#define MATCH_VMSNE_VX 0x64004057\n#define MASK_VMSNE_VX 0xfc00707f\n#define MATCH_VMSOF_M 0x50012057\n#define MASK_VMSOF_M 0xfc0ff07f\n#define MATCH_VMUL_VV 0x94002057\n#define MASK_VMUL_VV 0xfc00707f\n#define MATCH_VMUL_VX 0x94006057\n#define MASK_VMUL_VX 0xfc00707f\n#define MATCH_VMULH_VV 0x9c002057\n#define MASK_VMULH_VV 0xfc00707f\n#define MATCH_VMULH_VX 0x9c006057\n#define MASK_VMULH_VX 0xfc00707f\n#define MATCH_VMULHSU_VV 0x98002057\n#define MASK_VMULHSU_VV 0xfc00707f\n#define MATCH_VMULHSU_VX 0x98006057\n#define MASK_VMULHSU_VX 0xfc00707f\n#define MATCH_VMULHU_VV 0x90002057\n#define MASK_VMULHU_VV 0xfc00707f\n#define MATCH_VMULHU_VX 0x90006057\n#define MASK_VMULHU_VX 0xfc00707f\n#define MATCH_VMV1R_V 0x9e003057\n#define MASK_VMV1R_V 0xfe0ff07f\n#define MATCH_VMV2R_V 0x9e00b057\n#define MASK_VMV2R_V 0xfe0ff07f\n#define MATCH_VMV4R_V 0x9e01b057\n#define MASK_VMV4R_V 0xfe0ff07f\n#define MATCH_VMV8R_V 0x9e03b057\n#define MASK_VMV8R_V 0xfe0ff07f\n#define MATCH_VMV_S_X 0x42006057\n#define MASK_VMV_S_X 0xfff0707f\n#define MATCH_VMV_V_I 0x5e003057\n#define MASK_VMV_V_I 0xfff0707f\n#define MATCH_VMV_V_V 0x5e000057\n#define MASK_VMV_V_V 0xfff0707f\n#define MATCH_VMV_V_X 0x5e004057\n#define MASK_VMV_V_X 0xfff0707f\n#define MATCH_VMV_X_S 0x42002057\n#define MASK_VMV_X_S 0xfe0ff07f\n#define MATCH_VMXNOR_MM 0x7c002057\n#define MASK_VMXNOR_MM 0xfc00707f\n#define MATCH_VMXOR_MM 0x6c002057\n#define MASK_VMXOR_MM 0xfc00707f\n#define MATCH_VNCLIP_WI 0xbc003057\n#define MASK_VNCLIP_WI 0xfc00707f\n#define MATCH_VNCLIP_WV 0xbc000057\n#define MASK_VNCLIP_WV 0xfc00707f\n#define MATCH_VNCLIP_WX 0xbc004057\n#define MASK_VNCLIP_WX 0xfc00707f\n#define MATCH_VNCLIPU_WI 0xb8003057\n#define MASK_VNCLIPU_WI 0xfc00707f\n#define MATCH_VNCLIPU_WV 0xb8000057\n#define MASK_VNCLIPU_WV 0xfc00707f\n#define MATCH_VNCLIPU_WX 0xb8004057\n#define MASK_VNCLIPU_WX 0xfc00707f\n#define MATCH_VNMSAC_VV 0xbc002057\n#define MASK_VNMSAC_VV 0xfc00707f\n#define MATCH_VNMSAC_VX 0xbc006057\n#define MASK_VNMSAC_VX 0xfc00707f\n#define MATCH_VNMSUB_VV 0xac002057\n#define MASK_VNMSUB_VV 0xfc00707f\n#define MATCH_VNMSUB_VX 0xac006057\n#define MASK_VNMSUB_VX 0xfc00707f\n#define MATCH_VNSRA_WI 0xb4003057\n#define MASK_VNSRA_WI 0xfc00707f\n#define MATCH_VNSRA_WV 0xb4000057\n#define MASK_VNSRA_WV 0xfc00707f\n#define MATCH_VNSRA_WX 0xb4004057\n#define MASK_VNSRA_WX 0xfc00707f\n#define MATCH_VNSRL_WI 0xb0003057\n#define MASK_VNSRL_WI 0xfc00707f\n#define MATCH_VNSRL_WV 0xb0000057\n#define MASK_VNSRL_WV 0xfc00707f\n#define MATCH_VNSRL_WX 0xb0004057\n#define MASK_VNSRL_WX 0xfc00707f\n#define MATCH_VOR_VI 0x28003057\n#define MASK_VOR_VI 0xfc00707f\n#define MATCH_VOR_VV 0x28000057\n#define MASK_VOR_VV 0xfc00707f\n#define MATCH_VOR_VX 0x28004057\n#define MASK_VOR_VX 0xfc00707f\n#define MATCH_VREDAND_VS 0x4002057\n#define MASK_VREDAND_VS 0xfc00707f\n#define MATCH_VREDMAX_VS 0x1c002057\n#define MASK_VREDMAX_VS 0xfc00707f\n#define MATCH_VREDMAXU_VS 0x18002057\n#define MASK_VREDMAXU_VS 0xfc00707f\n#define MATCH_VREDMIN_VS 0x14002057\n#define MASK_VREDMIN_VS 0xfc00707f\n#define MATCH_VREDMINU_VS 0x10002057\n#define MASK_VREDMINU_VS 0xfc00707f\n#define MATCH_VREDOR_VS 0x8002057\n#define MASK_VREDOR_VS 0xfc00707f\n#define MATCH_VREDSUM_VS 0x2057\n#define MASK_VREDSUM_VS 0xfc00707f\n#define MATCH_VREDXOR_VS 0xc002057\n#define MASK_VREDXOR_VS 0xfc00707f\n#define MATCH_VREM_VV 0x8c002057\n#define MASK_VREM_VV 0xfc00707f\n#define MATCH_VREM_VX 0x8c006057\n#define MASK_VREM_VX 0xfc00707f\n#define MATCH_VREMU_VV 0x88002057\n#define MASK_VREMU_VV 0xfc00707f\n#define MATCH_VREMU_VX 0x88006057\n#define MASK_VREMU_VX 0xfc00707f\n#define MATCH_VRGATHER_VI 0x30003057\n#define MASK_VRGATHER_VI 0xfc00707f\n#define MATCH_VRGATHER_VV 0x30000057\n#define MASK_VRGATHER_VV 0xfc00707f\n#define MATCH_VRGATHER_VX 0x30004057\n#define MASK_VRGATHER_VX 0xfc00707f\n#define MATCH_VRGATHEREI16_VV 0x38000057\n#define MASK_VRGATHEREI16_VV 0xfc00707f\n#define MATCH_VRSUB_VI 0xc003057\n#define MASK_VRSUB_VI 0xfc00707f\n#define MATCH_VRSUB_VX 0xc004057\n#define MASK_VRSUB_VX 0xfc00707f\n#define MATCH_VS1R_V 0x2800027\n#define MASK_VS1R_V 0xfff0707f\n#define MATCH_VS2R_V 0x22800027\n#define MASK_VS2R_V 0xfff0707f\n#define MATCH_VS4R_V 0x62800027\n#define MASK_VS4R_V 0xfff0707f\n#define MATCH_VS8R_V 0xe2800027\n#define MASK_VS8R_V 0xfff0707f\n#define MATCH_VSADD_VI 0x84003057\n#define MASK_VSADD_VI 0xfc00707f\n#define MATCH_VSADD_VV 0x84000057\n#define MASK_VSADD_VV 0xfc00707f\n#define MATCH_VSADD_VX 0x84004057\n#define MASK_VSADD_VX 0xfc00707f\n#define MATCH_VSADDU_VI 0x80003057\n#define MASK_VSADDU_VI 0xfc00707f\n#define MATCH_VSADDU_VV 0x80000057\n#define MASK_VSADDU_VV 0xfc00707f\n#define MATCH_VSADDU_VX 0x80004057\n#define MASK_VSADDU_VX 0xfc00707f\n#define MATCH_VSBC_VVM 0x48000057\n#define MASK_VSBC_VVM 0xfe00707f\n#define MATCH_VSBC_VXM 0x48004057\n#define MASK_VSBC_VXM 0xfe00707f\n#define MATCH_VSE1024_V 0x10007027\n#define MASK_VSE1024_V 0x1df0707f\n#define MATCH_VSE128_V 0x10000027\n#define MASK_VSE128_V 0x1df0707f\n#define MATCH_VSE16_V 0x5027\n#define MASK_VSE16_V 0x1df0707f\n#define MATCH_VSE256_V 0x10005027\n#define MASK_VSE256_V 0x1df0707f\n#define MATCH_VSE32_V 0x6027\n#define MASK_VSE32_V 0x1df0707f\n#define MATCH_VSE512_V 0x10006027\n#define MASK_VSE512_V 0x1df0707f\n#define MATCH_VSE64_V 0x7027\n#define MASK_VSE64_V 0x1df0707f\n#define MATCH_VSE8_V 0x27\n#define MASK_VSE8_V 0x1df0707f\n#define MATCH_VSETIVLI 0xc0007057\n#define MASK_VSETIVLI 0xc000707f\n#define MATCH_VSETVL 0x80007057\n#define MASK_VSETVL 0xfe00707f\n#define MATCH_VSETVLI 0x7057\n#define MASK_VSETVLI 0x8000707f\n#define MATCH_VSEXT_VF2 0x4803a057\n#define MASK_VSEXT_VF2 0xfc0ff07f\n#define MATCH_VSEXT_VF4 0x4802a057\n#define MASK_VSEXT_VF4 0xfc0ff07f\n#define MATCH_VSEXT_VF8 0x4801a057\n#define MASK_VSEXT_VF8 0xfc0ff07f\n#define MATCH_VSLIDE1DOWN_VX 0x3c006057\n#define MASK_VSLIDE1DOWN_VX 0xfc00707f\n#define MATCH_VSLIDE1UP_VX 0x38006057\n#define MASK_VSLIDE1UP_VX 0xfc00707f\n#define MATCH_VSLIDEDOWN_VI 0x3c003057\n#define MASK_VSLIDEDOWN_VI 0xfc00707f\n#define MATCH_VSLIDEDOWN_VX 0x3c004057\n#define MASK_VSLIDEDOWN_VX 0xfc00707f\n#define MATCH_VSLIDEUP_VI 0x38003057\n#define MASK_VSLIDEUP_VI 0xfc00707f\n#define MATCH_VSLIDEUP_VX 0x38004057\n#define MASK_VSLIDEUP_VX 0xfc00707f\n#define MATCH_VSLL_VI 0x94003057\n#define MASK_VSLL_VI 0xfc00707f\n#define MATCH_VSLL_VV 0x94000057\n#define MASK_VSLL_VV 0xfc00707f\n#define MATCH_VSLL_VX 0x94004057\n#define MASK_VSLL_VX 0xfc00707f\n#define MATCH_VSM_V 0x2b00027\n#define MASK_VSM_V 0xfff0707f\n#define MATCH_VSMUL_VV 0x9c000057\n#define MASK_VSMUL_VV 0xfc00707f\n#define MATCH_VSMUL_VX 0x9c004057\n#define MASK_VSMUL_VX 0xfc00707f\n#define MATCH_VSOXEI1024_V 0x1c007027\n#define MASK_VSOXEI1024_V 0x1c00707f\n#define MATCH_VSOXEI128_V 0x1c000027\n#define MASK_VSOXEI128_V 0x1c00707f\n#define MATCH_VSOXEI16_V 0xc005027\n#define MASK_VSOXEI16_V 0x1c00707f\n#define MATCH_VSOXEI256_V 0x1c005027\n#define MASK_VSOXEI256_V 0x1c00707f\n#define MATCH_VSOXEI32_V 0xc006027\n#define MASK_VSOXEI32_V 0x1c00707f\n#define MATCH_VSOXEI512_V 0x1c006027\n#define MASK_VSOXEI512_V 0x1c00707f\n#define MATCH_VSOXEI64_V 0xc007027\n#define MASK_VSOXEI64_V 0x1c00707f\n#define MATCH_VSOXEI8_V 0xc000027\n#define MASK_VSOXEI8_V 0x1c00707f\n#define MATCH_VSRA_VI 0xa4003057\n#define MASK_VSRA_VI 0xfc00707f\n#define MATCH_VSRA_VV 0xa4000057\n#define MASK_VSRA_VV 0xfc00707f\n#define MATCH_VSRA_VX 0xa4004057\n#define MASK_VSRA_VX 0xfc00707f\n#define MATCH_VSRL_VI 0xa0003057\n#define MASK_VSRL_VI 0xfc00707f\n#define MATCH_VSRL_VV 0xa0000057\n#define MASK_VSRL_VV 0xfc00707f\n#define MATCH_VSRL_VX 0xa0004057\n#define MASK_VSRL_VX 0xfc00707f\n#define MATCH_VSSE1024_V 0x18007027\n#define MASK_VSSE1024_V 0x1c00707f\n#define MATCH_VSSE128_V 0x18000027\n#define MASK_VSSE128_V 0x1c00707f\n#define MATCH_VSSE16_V 0x8005027\n#define MASK_VSSE16_V 0x1c00707f\n#define MATCH_VSSE256_V 0x18005027\n#define MASK_VSSE256_V 0x1c00707f\n#define MATCH_VSSE32_V 0x8006027\n#define MASK_VSSE32_V 0x1c00707f\n#define MATCH_VSSE512_V 0x18006027\n#define MASK_VSSE512_V 0x1c00707f\n#define MATCH_VSSE64_V 0x8007027\n#define MASK_VSSE64_V 0x1c00707f\n#define MATCH_VSSE8_V 0x8000027\n#define MASK_VSSE8_V 0x1c00707f\n#define MATCH_VSSRA_VI 0xac003057\n#define MASK_VSSRA_VI 0xfc00707f\n#define MATCH_VSSRA_VV 0xac000057\n#define MASK_VSSRA_VV 0xfc00707f\n#define MATCH_VSSRA_VX 0xac004057\n#define MASK_VSSRA_VX 0xfc00707f\n#define MATCH_VSSRL_VI 0xa8003057\n#define MASK_VSSRL_VI 0xfc00707f\n#define MATCH_VSSRL_VV 0xa8000057\n#define MASK_VSSRL_VV 0xfc00707f\n#define MATCH_VSSRL_VX 0xa8004057\n#define MASK_VSSRL_VX 0xfc00707f\n#define MATCH_VSSUB_VV 0x8c000057\n#define MASK_VSSUB_VV 0xfc00707f\n#define MATCH_VSSUB_VX 0x8c004057\n#define MASK_VSSUB_VX 0xfc00707f\n#define MATCH_VSSUBU_VV 0x88000057\n#define MASK_VSSUBU_VV 0xfc00707f\n#define MATCH_VSSUBU_VX 0x88004057\n#define MASK_VSSUBU_VX 0xfc00707f\n#define MATCH_VSUB_VV 0x8000057\n#define MASK_VSUB_VV 0xfc00707f\n#define MATCH_VSUB_VX 0x8004057\n#define MASK_VSUB_VX 0xfc00707f\n#define MATCH_VSUXEI1024_V 0x14007027\n#define MASK_VSUXEI1024_V 0x1c00707f\n#define MATCH_VSUXEI128_V 0x14000027\n#define MASK_VSUXEI128_V 0x1c00707f\n#define MATCH_VSUXEI16_V 0x4005027\n#define MASK_VSUXEI16_V 0x1c00707f\n#define MATCH_VSUXEI256_V 0x14005027\n#define MASK_VSUXEI256_V 0x1c00707f\n#define MATCH_VSUXEI32_V 0x4006027\n#define MASK_VSUXEI32_V 0x1c00707f\n#define MATCH_VSUXEI512_V 0x14006027\n#define MASK_VSUXEI512_V 0x1c00707f\n#define MATCH_VSUXEI64_V 0x4007027\n#define MASK_VSUXEI64_V 0x1c00707f\n#define MATCH_VSUXEI8_V 0x4000027\n#define MASK_VSUXEI8_V 0x1c00707f\n#define MATCH_VWADD_VV 0xc4002057\n#define MASK_VWADD_VV 0xfc00707f\n#define MATCH_VWADD_VX 0xc4006057\n#define MASK_VWADD_VX 0xfc00707f\n#define MATCH_VWADD_WV 0xd4002057\n#define MASK_VWADD_WV 0xfc00707f\n#define MATCH_VWADD_WX 0xd4006057\n#define MASK_VWADD_WX 0xfc00707f\n#define MATCH_VWADDU_VV 0xc0002057\n#define MASK_VWADDU_VV 0xfc00707f\n#define MATCH_VWADDU_VX 0xc0006057\n#define MASK_VWADDU_VX 0xfc00707f\n#define MATCH_VWADDU_WV 0xd0002057\n#define MASK_VWADDU_WV 0xfc00707f\n#define MATCH_VWADDU_WX 0xd0006057\n#define MASK_VWADDU_WX 0xfc00707f\n#define MATCH_VWMACC_VV 0xf4002057\n#define MASK_VWMACC_VV 0xfc00707f\n#define MATCH_VWMACC_VX 0xf4006057\n#define MASK_VWMACC_VX 0xfc00707f\n#define MATCH_VWMACCSU_VV 0xfc002057\n#define MASK_VWMACCSU_VV 0xfc00707f\n#define MATCH_VWMACCSU_VX 0xfc006057\n#define MASK_VWMACCSU_VX 0xfc00707f\n#define MATCH_VWMACCU_VV 0xf0002057\n#define MASK_VWMACCU_VV 0xfc00707f\n#define MATCH_VWMACCU_VX 0xf0006057\n#define MASK_VWMACCU_VX 0xfc00707f\n#define MATCH_VWMACCUS_VX 0xf8006057\n#define MASK_VWMACCUS_VX 0xfc00707f\n#define MATCH_VWMUL_VV 0xec002057\n#define MASK_VWMUL_VV 0xfc00707f\n#define MATCH_VWMUL_VX 0xec006057\n#define MASK_VWMUL_VX 0xfc00707f\n#define MATCH_VWMULSU_VV 0xe8002057\n#define MASK_VWMULSU_VV 0xfc00707f\n#define MATCH_VWMULSU_VX 0xe8006057\n#define MASK_VWMULSU_VX 0xfc00707f\n#define MATCH_VWMULU_VV 0xe0002057\n#define MASK_VWMULU_VV 0xfc00707f\n#define MATCH_VWMULU_VX 0xe0006057\n#define MASK_VWMULU_VX 0xfc00707f\n#define MATCH_VWREDSUM_VS 0xc4000057\n#define MASK_VWREDSUM_VS 0xfc00707f\n#define MATCH_VWREDSUMU_VS 0xc0000057\n#define MASK_VWREDSUMU_VS 0xfc00707f\n#define MATCH_VWSUB_VV 0xcc002057\n#define MASK_VWSUB_VV 0xfc00707f\n#define MATCH_VWSUB_VX 0xcc006057\n#define MASK_VWSUB_VX 0xfc00707f\n#define MATCH_VWSUB_WV 0xdc002057\n#define MASK_VWSUB_WV 0xfc00707f\n#define MATCH_VWSUB_WX 0xdc006057\n#define MASK_VWSUB_WX 0xfc00707f\n#define MATCH_VWSUBU_VV 0xc8002057\n#define MASK_VWSUBU_VV 0xfc00707f\n#define MATCH_VWSUBU_VX 0xc8006057\n#define MASK_VWSUBU_VX 0xfc00707f\n#define MATCH_VWSUBU_WV 0xd8002057\n#define MASK_VWSUBU_WV 0xfc00707f\n#define MATCH_VWSUBU_WX 0xd8006057\n#define MASK_VWSUBU_WX 0xfc00707f\n#define MATCH_VXOR_VI 0x2c003057\n#define MASK_VXOR_VI 0xfc00707f\n#define MATCH_VXOR_VV 0x2c000057\n#define MASK_VXOR_VV 0xfc00707f\n#define MATCH_VXOR_VX 0x2c004057\n#define MASK_VXOR_VX 0xfc00707f\n#define MATCH_VZEXT_VF2 0x48032057\n#define MASK_VZEXT_VF2 0xfc0ff07f\n#define MATCH_VZEXT_VF4 0x48022057\n#define MASK_VZEXT_VF4 0xfc0ff07f\n#define MATCH_VZEXT_VF8 0x48012057\n#define MASK_VZEXT_VF8 0xfc0ff07f\n#define MATCH_WEXT 0xce000077\n#define MASK_WEXT 0xfe00707f\n#define MATCH_WEXTI 0xde000077\n#define MASK_WEXTI 0xfe00707f\n#define MATCH_WFI 0x10500073\n#define MASK_WFI 0xffffffff\n#define MATCH_WRS_NTO 0xd00073\n#define MASK_WRS_NTO 0xffffffff\n#define MATCH_WRS_STO 0x1d00073\n#define MASK_WRS_STO 0xffffffff\n#define MATCH_XNOR 0x40004033\n#define MASK_XNOR 0xfe00707f\n#define MATCH_XOR 0x4033\n#define MASK_XOR 0xfe00707f\n#define MATCH_XORI 0x4013\n#define MASK_XORI 0x707f\n#define MATCH_XPERM16 0x28006033\n#define MASK_XPERM16 0xfe00707f\n#define MATCH_XPERM32 0x28000033\n#define MASK_XPERM32 0xfe00707f\n#define MATCH_XPERM4 0x28002033\n#define MASK_XPERM4 0xfe00707f\n#define MATCH_XPERM8 0x28004033\n#define MASK_XPERM8 0xfe00707f\n#define MATCH_ZUNPKD810 0xacc00077\n#define MASK_ZUNPKD810 0xfff0707f\n#define MATCH_ZUNPKD820 0xacd00077\n#define MASK_ZUNPKD820 0xfff0707f\n#define MATCH_ZUNPKD830 0xace00077\n#define MASK_ZUNPKD830 0xfff0707f\n#define MATCH_ZUNPKD831 0xacf00077\n#define MASK_ZUNPKD831 0xfff0707f\n#define MATCH_ZUNPKD832 0xad700077\n#define MASK_ZUNPKD832 0xfff0707f\n\n#define CSR_FFLAGS 0x1\n#define CSR_FRM 0x2\n#define CSR_FCSR 0x3\n#define CSR_VSTART 0x8\n#define CSR_VXSAT 0x9\n#define CSR_VXRM 0xa\n#define CSR_VCSR 0xf\n#define CSR_SEED 0x15\n#define CSR_CYCLE 0xc00\n#define CSR_TIME 0xc01\n#define CSR_INSTRET 0xc02\n#define CSR_HPMCOUNTER3 0xc03\n#define CSR_HPMCOUNTER4 0xc04\n#define CSR_HPMCOUNTER5 0xc05\n#define CSR_HPMCOUNTER6 0xc06\n#define CSR_HPMCOUNTER7 0xc07\n#define CSR_HPMCOUNTER8 0xc08\n#define CSR_HPMCOUNTER9 0xc09\n#define CSR_HPMCOUNTER10 0xc0a\n#define CSR_HPMCOUNTER11 0xc0b\n#define CSR_HPMCOUNTER12 0xc0c\n#define CSR_HPMCOUNTER13 0xc0d\n#define CSR_HPMCOUNTER14 0xc0e\n#define CSR_HPMCOUNTER15 0xc0f\n#define CSR_HPMCOUNTER16 0xc10\n#define CSR_HPMCOUNTER17 0xc11\n#define CSR_HPMCOUNTER18 0xc12\n#define CSR_HPMCOUNTER19 0xc13\n#define CSR_HPMCOUNTER20 0xc14\n#define CSR_HPMCOUNTER21 0xc15\n#define CSR_HPMCOUNTER22 0xc16\n#define CSR_HPMCOUNTER23 0xc17\n#define CSR_HPMCOUNTER24 0xc18\n#define CSR_HPMCOUNTER25 0xc19\n#define CSR_HPMCOUNTER26 0xc1a\n#define CSR_HPMCOUNTER27 0xc1b\n#define CSR_HPMCOUNTER28 0xc1c\n#define CSR_HPMCOUNTER29 0xc1d\n#define CSR_HPMCOUNTER30 0xc1e\n#define CSR_HPMCOUNTER31 0xc1f\n#define CSR_VL 0xc20\n#define CSR_VTYPE 0xc21\n#define CSR_VLENB 0xc22\n#define CSR_SSTATUS 0x100\n#define CSR_SEDELEG 0x102\n#define CSR_SIDELEG 0x103\n#define CSR_SIE 0x104\n#define CSR_STVEC 0x105\n#define CSR_SCOUNTEREN 0x106\n#define CSR_SENVCFG 0x10a\n#define CSR_SSTATEEN0 0x10c\n#define CSR_SSTATEEN1 0x10d\n#define CSR_SSTATEEN2 0x10e\n#define CSR_SSTATEEN3 0x10f\n#define CSR_SSCRATCH 0x140\n#define CSR_SEPC 0x141\n#define CSR_SCAUSE 0x142\n#define CSR_STVAL 0x143\n#define CSR_SIP 0x144\n#define CSR_STIMECMP 0x14d\n#define CSR_SATP 0x180\n#define CSR_SCONTEXT 0x5a8\n#define CSR_VSSTATUS 0x200\n#define CSR_VSIE 0x204\n#define CSR_VSTVEC 0x205\n#define CSR_VSSCRATCH 0x240\n#define CSR_VSEPC 0x241\n#define CSR_VSCAUSE 0x242\n#define CSR_VSTVAL 0x243\n#define CSR_VSIP 0x244\n#define CSR_VSTIMECMP 0x24d\n#define CSR_VSATP 0x280\n#define CSR_HSTATUS 0x600\n#define CSR_HEDELEG 0x602\n#define CSR_HIDELEG 0x603\n#define CSR_HIE 0x604\n#define CSR_HTIMEDELTA 0x605\n#define CSR_HCOUNTEREN 0x606\n#define CSR_HGEIE 0x607\n#define CSR_HENVCFG 0x60a\n#define CSR_HSTATEEN0 0x60c\n#define CSR_HSTATEEN1 0x60d\n#define CSR_HSTATEEN2 0x60e\n#define CSR_HSTATEEN3 0x60f\n#define CSR_HTVAL 0x643\n#define CSR_HIP 0x644\n#define CSR_HVIP 0x645\n#define CSR_HTINST 0x64a\n#define CSR_HGATP 0x680\n#define CSR_HCONTEXT 0x6a8\n#define CSR_HGEIP 0xe12\n#define CSR_SCOUNTOVF 0xda0\n#define CSR_UTVT 0x7\n#define CSR_UNXTI 0x45\n#define CSR_UINTSTATUS 0x46\n#define CSR_USCRATCHCSW 0x48\n#define CSR_USCRATCHCSWL 0x49\n#define CSR_STVT 0x107\n#define CSR_SNXTI 0x145\n#define CSR_SINTSTATUS 0x146\n#define CSR_SSCRATCHCSW 0x148\n#define CSR_SSCRATCHCSWL 0x149\n#define CSR_MTVT 0x307\n#define CSR_MNXTI 0x345\n#define CSR_MINTSTATUS 0x346\n#define CSR_MSCRATCHCSW 0x348\n#define CSR_MSCRATCHCSWL 0x349\n#define CSR_MSTATUS 0x300\n#define CSR_MISA 0x301\n#define CSR_MEDELEG 0x302\n#define CSR_MIDELEG 0x303\n#define CSR_MIE 0x304\n#define CSR_MTVEC 0x305\n#define CSR_MCOUNTEREN 0x306\n#define CSR_MENVCFG 0x30a\n#define CSR_MSTATEEN0 0x30c\n#define CSR_MSTATEEN1 0x30d\n#define CSR_MSTATEEN2 0x30e\n#define CSR_MSTATEEN3 0x30f\n#define CSR_MCOUNTINHIBIT 0x320\n#define CSR_MSCRATCH 0x340\n#define CSR_MEPC 0x341\n#define CSR_MCAUSE 0x342\n#define CSR_MTVAL 0x343\n#define CSR_MIP 0x344\n#define CSR_MTINST 0x34a\n#define CSR_MTVAL2 0x34b\n#define CSR_PMPCFG0 0x3a0\n#define CSR_PMPCFG1 0x3a1\n#define CSR_PMPCFG2 0x3a2\n#define CSR_PMPCFG3 0x3a3\n#define CSR_PMPCFG4 0x3a4\n#define CSR_PMPCFG5 0x3a5\n#define CSR_PMPCFG6 0x3a6\n#define CSR_PMPCFG7 0x3a7\n#define CSR_PMPCFG8 0x3a8\n#define CSR_PMPCFG9 0x3a9\n#define CSR_PMPCFG10 0x3aa\n#define CSR_PMPCFG11 0x3ab\n#define CSR_PMPCFG12 0x3ac\n#define CSR_PMPCFG13 0x3ad\n#define CSR_PMPCFG14 0x3ae\n#define CSR_PMPCFG15 0x3af\n#define CSR_PMPADDR0 0x3b0\n#define CSR_PMPADDR1 0x3b1\n#define CSR_PMPADDR2 0x3b2\n#define CSR_PMPADDR3 0x3b3\n#define CSR_PMPADDR4 0x3b4\n#define CSR_PMPADDR5 0x3b5\n#define CSR_PMPADDR6 0x3b6\n#define CSR_PMPADDR7 0x3b7\n#define CSR_PMPADDR8 0x3b8\n#define CSR_PMPADDR9 0x3b9\n#define CSR_PMPADDR10 0x3ba\n#define CSR_PMPADDR11 0x3bb\n#define CSR_PMPADDR12 0x3bc\n#define CSR_PMPADDR13 0x3bd\n#define CSR_PMPADDR14 0x3be\n#define CSR_PMPADDR15 0x3bf\n#define CSR_PMPADDR16 0x3c0\n#define CSR_PMPADDR17 0x3c1\n#define CSR_PMPADDR18 0x3c2\n#define CSR_PMPADDR19 0x3c3\n#define CSR_PMPADDR20 0x3c4\n#define CSR_PMPADDR21 0x3c5\n#define CSR_PMPADDR22 0x3c6\n#define CSR_PMPADDR23 0x3c7\n#define CSR_PMPADDR24 0x3c8\n#define CSR_PMPADDR25 0x3c9\n#define CSR_PMPADDR26 0x3ca\n#define CSR_PMPADDR27 0x3cb\n#define CSR_PMPADDR28 0x3cc\n#define CSR_PMPADDR29 0x3cd\n#define CSR_PMPADDR30 0x3ce\n#define CSR_PMPADDR31 0x3cf\n#define CSR_PMPADDR32 0x3d0\n#define CSR_PMPADDR33 0x3d1\n#define CSR_PMPADDR34 0x3d2\n#define CSR_PMPADDR35 0x3d3\n#define CSR_PMPADDR36 0x3d4\n#define CSR_PMPADDR37 0x3d5\n#define CSR_PMPADDR38 0x3d6\n#define CSR_PMPADDR39 0x3d7\n#define CSR_PMPADDR40 0x3d8\n#define CSR_PMPADDR41 0x3d9\n#define CSR_PMPADDR42 0x3da\n#define CSR_PMPADDR43 0x3db\n#define CSR_PMPADDR44 0x3dc\n#define CSR_PMPADDR45 0x3dd\n#define CSR_PMPADDR46 0x3de\n#define CSR_PMPADDR47 0x3df\n#define CSR_PMPADDR48 0x3e0\n#define CSR_PMPADDR49 0x3e1\n#define CSR_PMPADDR50 0x3e2\n#define CSR_PMPADDR51 0x3e3\n#define CSR_PMPADDR52 0x3e4\n#define CSR_PMPADDR53 0x3e5\n#define CSR_PMPADDR54 0x3e6\n#define CSR_PMPADDR55 0x3e7\n#define CSR_PMPADDR56 0x3e8\n#define CSR_PMPADDR57 0x3e9\n#define CSR_PMPADDR58 0x3ea\n#define CSR_PMPADDR59 0x3eb\n#define CSR_PMPADDR60 0x3ec\n#define CSR_PMPADDR61 0x3ed\n#define CSR_PMPADDR62 0x3ee\n#define CSR_PMPADDR63 0x3ef\n#define CSR_MSECCFG 0x747\n#define CSR_TSELECT 0x7a0\n#define CSR_TDATA1 0x7a1\n#define CSR_TDATA2 0x7a2\n#define CSR_TDATA3 0x7a3\n#define CSR_TINFO 0x7a4\n#define CSR_TCONTROL 0x7a5\n#define CSR_MCONTEXT 0x7a8\n#define CSR_MSCONTEXT 0x7aa\n#define CSR_DCSR 0x7b0\n#define CSR_DPC 0x7b1\n#define CSR_DSCRATCH0 0x7b2\n#define CSR_DSCRATCH1 0x7b3\n#define CSR_MCYCLE 0xb00\n#define CSR_MINSTRET 0xb02\n#define CSR_MHPMCOUNTER3 0xb03\n#define CSR_MHPMCOUNTER4 0xb04\n#define CSR_MHPMCOUNTER5 0xb05\n#define CSR_MHPMCOUNTER6 0xb06\n#define CSR_MHPMCOUNTER7 0xb07\n#define CSR_MHPMCOUNTER8 0xb08\n#define CSR_MHPMCOUNTER9 0xb09\n#define CSR_MHPMCOUNTER10 0xb0a\n#define CSR_MHPMCOUNTER11 0xb0b\n#define CSR_MHPMCOUNTER12 0xb0c\n#define CSR_MHPMCOUNTER13 0xb0d\n#define CSR_MHPMCOUNTER14 0xb0e\n#define CSR_MHPMCOUNTER15 0xb0f\n#define CSR_MHPMCOUNTER16 0xb10\n#define CSR_MHPMCOUNTER17 0xb11\n#define CSR_MHPMCOUNTER18 0xb12\n#define CSR_MHPMCOUNTER19 0xb13\n#define CSR_MHPMCOUNTER20 0xb14\n#define CSR_MHPMCOUNTER21 0xb15\n#define CSR_MHPMCOUNTER22 0xb16\n#define CSR_MHPMCOUNTER23 0xb17\n#define CSR_MHPMCOUNTER24 0xb18\n#define CSR_MHPMCOUNTER25 0xb19\n#define CSR_MHPMCOUNTER26 0xb1a\n#define CSR_MHPMCOUNTER27 0xb1b\n#define CSR_MHPMCOUNTER28 0xb1c\n#define CSR_MHPMCOUNTER29 0xb1d\n#define CSR_MHPMCOUNTER30 0xb1e\n#define CSR_MHPMCOUNTER31 0xb1f\n#define CSR_MHPMEVENT3 0x323\n#define CSR_MHPMEVENT4 0x324\n#define CSR_MHPMEVENT5 0x325\n#define CSR_MHPMEVENT6 0x326\n#define CSR_MHPMEVENT7 0x327\n#define CSR_MHPMEVENT8 0x328\n#define CSR_MHPMEVENT9 0x329\n#define CSR_MHPMEVENT10 0x32a\n#define CSR_MHPMEVENT11 0x32b\n#define CSR_MHPMEVENT12 0x32c\n#define CSR_MHPMEVENT13 0x32d\n#define CSR_MHPMEVENT14 0x32e\n#define CSR_MHPMEVENT15 0x32f\n#define CSR_MHPMEVENT16 0x330\n#define CSR_MHPMEVENT17 0x331\n#define CSR_MHPMEVENT18 0x332\n#define CSR_MHPMEVENT19 0x333\n#define CSR_MHPMEVENT20 0x334\n#define CSR_MHPMEVENT21 0x335\n#define CSR_MHPMEVENT22 0x336\n#define CSR_MHPMEVENT23 0x337\n#define CSR_MHPMEVENT24 0x338\n#define CSR_MHPMEVENT25 0x339\n#define CSR_MHPMEVENT26 0x33a\n#define CSR_MHPMEVENT27 0x33b\n#define CSR_MHPMEVENT28 0x33c\n#define CSR_MHPMEVENT29 0x33d\n#define CSR_MHPMEVENT30 0x33e\n#define CSR_MHPMEVENT31 0x33f\n#define CSR_MVENDORID 0xf11\n#define CSR_MARCHID 0xf12\n#define CSR_MIMPID 0xf13\n#define CSR_MHARTID 0xf14\n#define CSR_MCONFIGPTR 0xf15\n#define CSR_STIMECMPH 0x15d\n#define CSR_VSTIMECMPH 0x25d\n#define CSR_HTIMEDELTAH 0x615\n#define CSR_HENVCFGH 0x61a\n#define CSR_HSTATEEN0H 0x61c\n#define CSR_HSTATEEN1H 0x61d\n#define CSR_HSTATEEN2H 0x61e\n#define CSR_HSTATEEN3H 0x61f\n#define CSR_CYCLEH 0xc80\n#define CSR_TIMEH 0xc81\n#define CSR_INSTRETH 0xc82\n#define CSR_HPMCOUNTER3H 0xc83\n#define CSR_HPMCOUNTER4H 0xc84\n#define CSR_HPMCOUNTER5H 0xc85\n#define CSR_HPMCOUNTER6H 0xc86\n#define CSR_HPMCOUNTER7H 0xc87\n#define CSR_HPMCOUNTER8H 0xc88\n#define CSR_HPMCOUNTER9H 0xc89\n#define CSR_HPMCOUNTER10H 0xc8a\n#define CSR_HPMCOUNTER11H 0xc8b\n#define CSR_HPMCOUNTER12H 0xc8c\n#define CSR_HPMCOUNTER13H 0xc8d\n#define CSR_HPMCOUNTER14H 0xc8e\n#define CSR_HPMCOUNTER15H 0xc8f\n#define CSR_HPMCOUNTER16H 0xc90\n#define CSR_HPMCOUNTER17H 0xc91\n#define CSR_HPMCOUNTER18H 0xc92\n#define CSR_HPMCOUNTER19H 0xc93\n#define CSR_HPMCOUNTER20H 0xc94\n#define CSR_HPMCOUNTER21H 0xc95\n#define CSR_HPMCOUNTER22H 0xc96\n#define CSR_HPMCOUNTER23H 0xc97\n#define CSR_HPMCOUNTER24H 0xc98\n#define CSR_HPMCOUNTER25H 0xc99\n#define CSR_HPMCOUNTER26H 0xc9a\n#define CSR_HPMCOUNTER27H 0xc9b\n#define CSR_HPMCOUNTER28H 0xc9c\n#define CSR_HPMCOUNTER29H 0xc9d\n#define CSR_HPMCOUNTER30H 0xc9e\n#define CSR_HPMCOUNTER31H 0xc9f\n#define CSR_MSTATUSH 0x310\n#define CSR_MENVCFGH 0x31a\n#define CSR_MSTATEEN0H 0x31c\n#define CSR_MSTATEEN1H 0x31d\n#define CSR_MSTATEEN2H 0x31e\n#define CSR_MSTATEEN3H 0x31f\n#define CSR_MHPMEVENT3H 0x723\n#define CSR_MHPMEVENT4H 0x724\n#define CSR_MHPMEVENT5H 0x725\n#define CSR_MHPMEVENT6H 0x726\n#define CSR_MHPMEVENT7H 0x727\n#define CSR_MHPMEVENT8H 0x728\n#define CSR_MHPMEVENT9H 0x729\n#define CSR_MHPMEVENT10H 0x72a\n#define CSR_MHPMEVENT11H 0x72b\n#define CSR_MHPMEVENT12H 0x72c\n#define CSR_MHPMEVENT13H 0x72d\n#define CSR_MHPMEVENT14H 0x72e\n#define CSR_MHPMEVENT15H 0x72f\n#define CSR_MHPMEVENT16H 0x730\n#define CSR_MHPMEVENT17H 0x731\n#define CSR_MHPMEVENT18H 0x732\n#define CSR_MHPMEVENT19H 0x733\n#define CSR_MHPMEVENT20H 0x734\n#define CSR_MHPMEVENT21H 0x735\n#define CSR_MHPMEVENT22H 0x736\n#define CSR_MHPMEVENT23H 0x737\n#define CSR_MHPMEVENT24H 0x738\n#define CSR_MHPMEVENT25H 0x739\n#define CSR_MHPMEVENT26H 0x73a\n#define CSR_MHPMEVENT27H 0x73b\n#define CSR_MHPMEVENT28H 0x73c\n#define CSR_MHPMEVENT29H 0x73d\n#define CSR_MHPMEVENT30H 0x73e\n#define CSR_MHPMEVENT31H 0x73f\n#define CSR_MSECCFGH 0x757\n#define CSR_MCYCLEH 0xb80\n#define CSR_MINSTRETH 0xb82\n#define CSR_MHPMCOUNTER3H 0xb83\n#define CSR_MHPMCOUNTER4H 0xb84\n#define CSR_MHPMCOUNTER5H 0xb85\n#define CSR_MHPMCOUNTER6H 0xb86\n#define CSR_MHPMCOUNTER7H 0xb87\n#define CSR_MHPMCOUNTER8H 0xb88\n#define CSR_MHPMCOUNTER9H 0xb89\n#define CSR_MHPMCOUNTER10H 0xb8a\n#define CSR_MHPMCOUNTER11H 0xb8b\n#define CSR_MHPMCOUNTER12H 0xb8c\n#define CSR_MHPMCOUNTER13H 0xb8d\n#define CSR_MHPMCOUNTER14H 0xb8e\n#define CSR_MHPMCOUNTER15H 0xb8f\n#define CSR_MHPMCOUNTER16H 0xb90\n#define CSR_MHPMCOUNTER17H 0xb91\n#define CSR_MHPMCOUNTER18H 0xb92\n#define CSR_MHPMCOUNTER19H 0xb93\n#define CSR_MHPMCOUNTER20H 0xb94\n#define CSR_MHPMCOUNTER21H 0xb95\n#define CSR_MHPMCOUNTER22H 0xb96\n#define CSR_MHPMCOUNTER23H 0xb97\n#define CSR_MHPMCOUNTER24H 0xb98\n#define CSR_MHPMCOUNTER25H 0xb99\n#define CSR_MHPMCOUNTER26H 0xb9a\n#define CSR_MHPMCOUNTER27H 0xb9b\n#define CSR_MHPMCOUNTER28H 0xb9c\n#define CSR_MHPMCOUNTER29H 0xb9d\n#define CSR_MHPMCOUNTER30H 0xb9e\n#define CSR_MHPMCOUNTER31H 0xb9f\n\n#define CAUSE_MISALIGNED_FETCH 0x0\n#define CAUSE_FETCH_ACCESS 0x1\n#define CAUSE_ILLEGAL_INSTRUCTION 0x2\n#define CAUSE_BREAKPOINT 0x3\n#define CAUSE_MISALIGNED_LOAD 0x4\n#define CAUSE_LOAD_ACCESS 0x5\n#define CAUSE_MISALIGNED_STORE 0x6\n#define CAUSE_STORE_ACCESS 0x7\n#define CAUSE_USER_ECALL 0x8\n#define CAUSE_SUPERVISOR_ECALL 0x9\n#define CAUSE_VIRTUAL_SUPERVISOR_ECALL 0xa\n#define CAUSE_MACHINE_ECALL 0xb\n#define CAUSE_FETCH_PAGE_FAULT 0xc\n#define CAUSE_LOAD_PAGE_FAULT 0xd\n#define CAUSE_STORE_PAGE_FAULT 0xf\n#define CAUSE_FETCH_GUEST_PAGE_FAULT 0x14\n#define CAUSE_LOAD_GUEST_PAGE_FAULT 0x15\n#define CAUSE_VIRTUAL_INSTRUCTION 0x16\n#define CAUSE_STORE_GUEST_PAGE_FAULT 0x17\n\n#define INSN_FIELD_RD 0xf80\n#define INSN_FIELD_RT 0xf8000\n#define INSN_FIELD_RS1 0xf8000\n#define INSN_FIELD_RS2 0x1f00000\n#define INSN_FIELD_RS3 0xf8000000\n#define INSN_FIELD_AQRL 0x6000000\n#define INSN_FIELD_AQ 0x4000000\n#define INSN_FIELD_RL 0x2000000\n#define INSN_FIELD_FM 0xf0000000\n#define INSN_FIELD_PRED 0xf000000\n#define INSN_FIELD_SUCC 0xf00000\n#define INSN_FIELD_RM 0x7000\n#define INSN_FIELD_FUNCT3 0x7000\n#define INSN_FIELD_FUNCT2 0x6000000\n#define INSN_FIELD_IMM20 0xfffff000\n#define INSN_FIELD_JIMM20 0xfffff000\n#define INSN_FIELD_IMM12 0xfff00000\n#define INSN_FIELD_CSR 0xfff00000\n#define INSN_FIELD_IMM12HI 0xfe000000\n#define INSN_FIELD_BIMM12HI 0xfe000000\n#define INSN_FIELD_IMM12LO 0xf80\n#define INSN_FIELD_BIMM12LO 0xf80\n#define INSN_FIELD_ZIMM 0xf8000\n#define INSN_FIELD_SHAMT 0x7f00000\n#define INSN_FIELD_SHAMTW 0x1f00000\n#define INSN_FIELD_SHAMTW4 0xf00000\n#define INSN_FIELD_SHAMTD 0x3f00000\n#define INSN_FIELD_BS 0xc0000000\n#define INSN_FIELD_RNUM 0xf00000\n#define INSN_FIELD_RC 0x3e000000\n#define INSN_FIELD_IMM2 0x300000\n#define INSN_FIELD_IMM3 0x700000\n#define INSN_FIELD_IMM4 0xf00000\n#define INSN_FIELD_IMM5 0x1f00000\n#define INSN_FIELD_IMM6 0x3f00000\n#define INSN_FIELD_OPCODE 0x7f\n#define INSN_FIELD_FUNCT7 0xfe000000\n#define INSN_FIELD_VD 0xf80\n#define INSN_FIELD_VS3 0xf80\n#define INSN_FIELD_VS1 0xf8000\n#define INSN_FIELD_VS2 0x1f00000\n#define INSN_FIELD_VM 0x2000000\n#define INSN_FIELD_WD 0x4000000\n#define INSN_FIELD_AMOOP 0xf8000000\n#define INSN_FIELD_NF 0xe0000000\n#define INSN_FIELD_SIMM5 0xf8000\n#define INSN_FIELD_ZIMM10 0x3ff00000\n#define INSN_FIELD_ZIMM11 0x7ff00000\n#define INSN_FIELD_C_NZUIMM10 0x1fe0\n#define INSN_FIELD_C_UIMM7LO 0x60\n#define INSN_FIELD_C_UIMM7HI 0x1c00\n#define INSN_FIELD_C_UIMM8LO 0x60\n#define INSN_FIELD_C_UIMM8HI 0x1c00\n#define INSN_FIELD_C_UIMM9LO 0x60\n#define INSN_FIELD_C_UIMM9HI 0x1c00\n#define INSN_FIELD_C_NZIMM6LO 0x7c\n#define INSN_FIELD_C_NZIMM6HI 0x1000\n#define INSN_FIELD_C_IMM6LO 0x7c\n#define INSN_FIELD_C_IMM6HI 0x1000\n#define INSN_FIELD_C_NZIMM10HI 0x1000\n#define INSN_FIELD_C_NZIMM10LO 0x7c\n#define INSN_FIELD_C_NZIMM18HI 0x1000\n#define INSN_FIELD_C_NZIMM18LO 0x7c\n#define INSN_FIELD_C_IMM12 0x1ffc\n#define INSN_FIELD_C_BIMM9LO 0x7c\n#define INSN_FIELD_C_BIMM9HI 0x1c00\n#define INSN_FIELD_C_NZUIMM5 0x7c\n#define INSN_FIELD_C_NZUIMM6LO 0x7c\n#define INSN_FIELD_C_NZUIMM6HI 0x1000\n#define INSN_FIELD_C_UIMM8SPLO 0x7c\n#define INSN_FIELD_C_UIMM8SPHI 0x1000\n#define INSN_FIELD_C_UIMM8SP_S 0x1f80\n#define INSN_FIELD_C_UIMM10SPLO 0x7c\n#define INSN_FIELD_C_UIMM10SPHI 0x1000\n#define INSN_FIELD_C_UIMM9SPLO 0x7c\n#define INSN_FIELD_C_UIMM9SPHI 0x1000\n#define INSN_FIELD_C_UIMM10SP_S 0x1f80\n#define INSN_FIELD_C_UIMM9SP_S 0x1f80\n#define INSN_FIELD_RS1_P 0x380\n#define INSN_FIELD_RS2_P 0x1c\n#define INSN_FIELD_RD_P 0x1c\n#define INSN_FIELD_RD_RS1_N0 0xf80\n#define INSN_FIELD_RD_RS1_P 0x380\n#define INSN_FIELD_RD_RS1 0xf80\n#define INSN_FIELD_RD_N2 0xf80\n#define INSN_FIELD_RD_N0 0xf80\n#define INSN_FIELD_RS1_N0 0xf80\n#define INSN_FIELD_C_RS2_N0 0x7c\n#define INSN_FIELD_C_RS1_N0 0xf80\n#define INSN_FIELD_C_RS2 0x7c\n#endif\n#ifdef DECLARE_INSN\nDECLARE_INSN(add, MATCH_ADD, MASK_ADD)\nDECLARE_INSN(add16, MATCH_ADD16, MASK_ADD16)\nDECLARE_INSN(add32, MATCH_ADD32, MASK_ADD32)\nDECLARE_INSN(add64, MATCH_ADD64, MASK_ADD64)\nDECLARE_INSN(add8, MATCH_ADD8, MASK_ADD8)\nDECLARE_INSN(add_uw, MATCH_ADD_UW, MASK_ADD_UW)\nDECLARE_INSN(addd, MATCH_ADDD, MASK_ADDD)\nDECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)\nDECLARE_INSN(addid, MATCH_ADDID, MASK_ADDID)\nDECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)\nDECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)\nDECLARE_INSN(aes32dsi, MATCH_AES32DSI, MASK_AES32DSI)\nDECLARE_INSN(aes32dsmi, MATCH_AES32DSMI, MASK_AES32DSMI)\nDECLARE_INSN(aes32esi, MATCH_AES32ESI, MASK_AES32ESI)\nDECLARE_INSN(aes32esmi, MATCH_AES32ESMI, MASK_AES32ESMI)\nDECLARE_INSN(aes64ds, MATCH_AES64DS, MASK_AES64DS)\nDECLARE_INSN(aes64dsm, MATCH_AES64DSM, MASK_AES64DSM)\nDECLARE_INSN(aes64es, MATCH_AES64ES, MASK_AES64ES)\nDECLARE_INSN(aes64esm, MATCH_AES64ESM, MASK_AES64ESM)\nDECLARE_INSN(aes64im, MATCH_AES64IM, MASK_AES64IM)\nDECLARE_INSN(aes64ks1i, MATCH_AES64KS1I, MASK_AES64KS1I)\nDECLARE_INSN(aes64ks2, MATCH_AES64KS2, MASK_AES64KS2)\nDECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)\nDECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)\nDECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)\nDECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)\nDECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)\nDECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)\nDECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)\nDECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)\nDECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)\nDECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)\nDECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)\nDECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)\nDECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)\nDECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)\nDECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)\nDECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)\nDECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)\nDECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)\nDECLARE_INSN(and, MATCH_AND, MASK_AND)\nDECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)\nDECLARE_INSN(andn, MATCH_ANDN, MASK_ANDN)\nDECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)\nDECLARE_INSN(ave, MATCH_AVE, MASK_AVE)\nDECLARE_INSN(bclr, MATCH_BCLR, MASK_BCLR)\nDECLARE_INSN(bclri, MATCH_BCLRI, MASK_BCLRI)\nDECLARE_INSN(bcompress, MATCH_BCOMPRESS, MASK_BCOMPRESS)\nDECLARE_INSN(bcompressw, MATCH_BCOMPRESSW, MASK_BCOMPRESSW)\nDECLARE_INSN(bdecompress, MATCH_BDECOMPRESS, MASK_BDECOMPRESS)\nDECLARE_INSN(bdecompressw, MATCH_BDECOMPRESSW, MASK_BDECOMPRESSW)\nDECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)\nDECLARE_INSN(bext, MATCH_BEXT, MASK_BEXT)\nDECLARE_INSN(bexti, MATCH_BEXTI, MASK_BEXTI)\nDECLARE_INSN(bfp, MATCH_BFP, MASK_BFP)\nDECLARE_INSN(bfpw, MATCH_BFPW, MASK_BFPW)\nDECLARE_INSN(bge, MATCH_BGE, MASK_BGE)\nDECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)\nDECLARE_INSN(binv, MATCH_BINV, MASK_BINV)\nDECLARE_INSN(binvi, MATCH_BINVI, MASK_BINVI)\nDECLARE_INSN(bitrev, MATCH_BITREV, MASK_BITREV)\nDECLARE_INSN(bitrevi, MATCH_BITREVI, MASK_BITREVI)\nDECLARE_INSN(blt, MATCH_BLT, MASK_BLT)\nDECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)\nDECLARE_INSN(bmatflip, MATCH_BMATFLIP, MASK_BMATFLIP)\nDECLARE_INSN(bmator, MATCH_BMATOR, MASK_BMATOR)\nDECLARE_INSN(bmatxor, MATCH_BMATXOR, MASK_BMATXOR)\nDECLARE_INSN(bne, MATCH_BNE, MASK_BNE)\nDECLARE_INSN(bpick, MATCH_BPICK, MASK_BPICK)\nDECLARE_INSN(bset, MATCH_BSET, MASK_BSET)\nDECLARE_INSN(bseti, MATCH_BSETI, MASK_BSETI)\nDECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)\nDECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)\nDECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)\nDECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN)\nDECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)\nDECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW)\nDECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND)\nDECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI)\nDECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ)\nDECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ)\nDECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK)\nDECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)\nDECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP)\nDECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)\nDECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP)\nDECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)\nDECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP)\nDECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)\nDECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP)\nDECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)\nDECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL)\nDECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR)\nDECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)\nDECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)\nDECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)\nDECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)\nDECLARE_INSN(c_lq, MATCH_C_LQ, MASK_C_LQ)\nDECLARE_INSN(c_lqsp, MATCH_C_LQSP, MASK_C_LQSP)\nDECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI)\nDECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)\nDECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)\nDECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV)\nDECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)\nDECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR)\nDECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)\nDECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)\nDECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)\nDECLARE_INSN(c_sq, MATCH_C_SQ, MASK_C_SQ)\nDECLARE_INSN(c_sqsp, MATCH_C_SQSP, MASK_C_SQSP)\nDECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)\nDECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)\nDECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)\nDECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW)\nDECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)\nDECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)\nDECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR)\nDECLARE_INSN(cbo_clean, MATCH_CBO_CLEAN, MASK_CBO_CLEAN)\nDECLARE_INSN(cbo_flush, MATCH_CBO_FLUSH, MASK_CBO_FLUSH)\nDECLARE_INSN(cbo_inval, MATCH_CBO_INVAL, MASK_CBO_INVAL)\nDECLARE_INSN(cbo_zero, MATCH_CBO_ZERO, MASK_CBO_ZERO)\nDECLARE_INSN(clmul, MATCH_CLMUL, MASK_CLMUL)\nDECLARE_INSN(clmulh, MATCH_CLMULH, MASK_CLMULH)\nDECLARE_INSN(clmulr, MATCH_CLMULR, MASK_CLMULR)\nDECLARE_INSN(clo16, MATCH_CLO16, MASK_CLO16)\nDECLARE_INSN(clo32, MATCH_CLO32, MASK_CLO32)\nDECLARE_INSN(clo8, MATCH_CLO8, MASK_CLO8)\nDECLARE_INSN(clrs16, MATCH_CLRS16, MASK_CLRS16)\nDECLARE_INSN(clrs32, MATCH_CLRS32, MASK_CLRS32)\nDECLARE_INSN(clrs8, MATCH_CLRS8, MASK_CLRS8)\nDECLARE_INSN(clz, MATCH_CLZ, MASK_CLZ)\nDECLARE_INSN(clz16, MATCH_CLZ16, MASK_CLZ16)\nDECLARE_INSN(clz32, MATCH_CLZ32, MASK_CLZ32)\nDECLARE_INSN(clz8, MATCH_CLZ8, MASK_CLZ8)\nDECLARE_INSN(clzw, MATCH_CLZW, MASK_CLZW)\nDECLARE_INSN(cmix, MATCH_CMIX, MASK_CMIX)\nDECLARE_INSN(cmov, MATCH_CMOV, MASK_CMOV)\nDECLARE_INSN(cmpeq16, MATCH_CMPEQ16, MASK_CMPEQ16)\nDECLARE_INSN(cmpeq8, MATCH_CMPEQ8, MASK_CMPEQ8)\nDECLARE_INSN(cpop, MATCH_CPOP, MASK_CPOP)\nDECLARE_INSN(cpopw, MATCH_CPOPW, MASK_CPOPW)\nDECLARE_INSN(cras16, MATCH_CRAS16, MASK_CRAS16)\nDECLARE_INSN(cras32, MATCH_CRAS32, MASK_CRAS32)\nDECLARE_INSN(crc32_b, MATCH_CRC32_B, MASK_CRC32_B)\nDECLARE_INSN(crc32_d, MATCH_CRC32_D, MASK_CRC32_D)\nDECLARE_INSN(crc32_h, MATCH_CRC32_H, MASK_CRC32_H)\nDECLARE_INSN(crc32_w, MATCH_CRC32_W, MASK_CRC32_W)\nDECLARE_INSN(crc32c_b, MATCH_CRC32C_B, MASK_CRC32C_B)\nDECLARE_INSN(crc32c_d, MATCH_CRC32C_D, MASK_CRC32C_D)\nDECLARE_INSN(crc32c_h, MATCH_CRC32C_H, MASK_CRC32C_H)\nDECLARE_INSN(crc32c_w, MATCH_CRC32C_W, MASK_CRC32C_W)\nDECLARE_INSN(crsa16, MATCH_CRSA16, MASK_CRSA16)\nDECLARE_INSN(crsa32, MATCH_CRSA32, MASK_CRSA32)\nDECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)\nDECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)\nDECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)\nDECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)\nDECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)\nDECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)\nDECLARE_INSN(ctz, MATCH_CTZ, MASK_CTZ)\nDECLARE_INSN(ctzw, MATCH_CTZW, MASK_CTZW)\nDECLARE_INSN(div, MATCH_DIV, MASK_DIV)\nDECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)\nDECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)\nDECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)\nDECLARE_INSN(dret, MATCH_DRET, MASK_DRET)\nDECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)\nDECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)\nDECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)\nDECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H)\nDECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)\nDECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)\nDECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)\nDECLARE_INSN(fclass_h, MATCH_FCLASS_H, MASK_FCLASS_H)\nDECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)\nDECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)\nDECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H)\nDECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)\nDECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)\nDECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)\nDECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)\nDECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)\nDECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)\nDECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D)\nDECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L)\nDECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU)\nDECLARE_INSN(fcvt_h_q, MATCH_FCVT_H_Q, MASK_FCVT_H_Q)\nDECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S)\nDECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W)\nDECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU)\nDECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)\nDECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H)\nDECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)\nDECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)\nDECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)\nDECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H)\nDECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)\nDECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)\nDECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)\nDECLARE_INSN(fcvt_q_h, MATCH_FCVT_Q_H, MASK_FCVT_Q_H)\nDECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)\nDECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)\nDECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)\nDECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)\nDECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)\nDECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)\nDECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H)\nDECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)\nDECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)\nDECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)\nDECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)\nDECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)\nDECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)\nDECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H)\nDECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)\nDECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)\nDECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)\nDECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H)\nDECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)\nDECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)\nDECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)\nDECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H)\nDECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)\nDECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)\nDECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)\nDECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)\nDECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)\nDECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H)\nDECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)\nDECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)\nDECLARE_INSN(fld, MATCH_FLD, MASK_FLD)\nDECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)\nDECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H)\nDECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)\nDECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)\nDECLARE_INSN(flh, MATCH_FLH, MASK_FLH)\nDECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)\nDECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)\nDECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H)\nDECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)\nDECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)\nDECLARE_INSN(flw, MATCH_FLW, MASK_FLW)\nDECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)\nDECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H)\nDECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)\nDECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)\nDECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)\nDECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H)\nDECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)\nDECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)\nDECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)\nDECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H)\nDECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)\nDECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)\nDECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)\nDECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H)\nDECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)\nDECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)\nDECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)\nDECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H)\nDECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)\nDECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)\nDECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)\nDECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X)\nDECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X)\nDECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)\nDECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H)\nDECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W)\nDECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)\nDECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H)\nDECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)\nDECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)\nDECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)\nDECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H)\nDECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)\nDECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)\nDECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)\nDECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)\nDECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H)\nDECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)\nDECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)\nDECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)\nDECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H)\nDECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)\nDECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)\nDECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)\nDECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H)\nDECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)\nDECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)\nDECLARE_INSN(fsh, MATCH_FSH, MASK_FSH)\nDECLARE_INSN(fsl, MATCH_FSL, MASK_FSL)\nDECLARE_INSN(fslw, MATCH_FSLW, MASK_FSLW)\nDECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)\nDECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)\nDECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H)\nDECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)\nDECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)\nDECLARE_INSN(fsr, MATCH_FSR, MASK_FSR)\nDECLARE_INSN(fsri, MATCH_FSRI, MASK_FSRI)\nDECLARE_INSN(fsriw, MATCH_FSRIW, MASK_FSRIW)\nDECLARE_INSN(fsrw, MATCH_FSRW, MASK_FSRW)\nDECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)\nDECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H)\nDECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)\nDECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)\nDECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)\nDECLARE_INSN(gorc, MATCH_GORC, MASK_GORC)\nDECLARE_INSN(gorci, MATCH_GORCI, MASK_GORCI)\nDECLARE_INSN(gorciw, MATCH_GORCIW, MASK_GORCIW)\nDECLARE_INSN(gorcw, MATCH_GORCW, MASK_GORCW)\nDECLARE_INSN(grev, MATCH_GREV, MASK_GREV)\nDECLARE_INSN(grevi, MATCH_GREVI, MASK_GREVI)\nDECLARE_INSN(greviw, MATCH_GREVIW, MASK_GREVIW)\nDECLARE_INSN(grevw, MATCH_GREVW, MASK_GREVW)\nDECLARE_INSN(hfence_gvma, MATCH_HFENCE_GVMA, MASK_HFENCE_GVMA)\nDECLARE_INSN(hfence_vvma, MATCH_HFENCE_VVMA, MASK_HFENCE_VVMA)\nDECLARE_INSN(hinval_gvma, MATCH_HINVAL_GVMA, MASK_HINVAL_GVMA)\nDECLARE_INSN(hinval_vvma, MATCH_HINVAL_VVMA, MASK_HINVAL_VVMA)\nDECLARE_INSN(hlv_b, MATCH_HLV_B, MASK_HLV_B)\nDECLARE_INSN(hlv_bu, MATCH_HLV_BU, MASK_HLV_BU)\nDECLARE_INSN(hlv_d, MATCH_HLV_D, MASK_HLV_D)\nDECLARE_INSN(hlv_h, MATCH_HLV_H, MASK_HLV_H)\nDECLARE_INSN(hlv_hu, MATCH_HLV_HU, MASK_HLV_HU)\nDECLARE_INSN(hlv_w, MATCH_HLV_W, MASK_HLV_W)\nDECLARE_INSN(hlv_wu, MATCH_HLV_WU, MASK_HLV_WU)\nDECLARE_INSN(hlvx_hu, MATCH_HLVX_HU, MASK_HLVX_HU)\nDECLARE_INSN(hlvx_wu, MATCH_HLVX_WU, MASK_HLVX_WU)\nDECLARE_INSN(hsv_b, MATCH_HSV_B, MASK_HSV_B)\nDECLARE_INSN(hsv_d, MATCH_HSV_D, MASK_HSV_D)\nDECLARE_INSN(hsv_h, MATCH_HSV_H, MASK_HSV_H)\nDECLARE_INSN(hsv_w, MATCH_HSV_W, MASK_HSV_W)\nDECLARE_INSN(insb, MATCH_INSB, MASK_INSB)\nDECLARE_INSN(jal, MATCH_JAL, MASK_JAL)\nDECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)\nDECLARE_INSN(kabs16, MATCH_KABS16, MASK_KABS16)\nDECLARE_INSN(kabs32, MATCH_KABS32, MASK_KABS32)\nDECLARE_INSN(kabs8, MATCH_KABS8, MASK_KABS8)\nDECLARE_INSN(kabsw, MATCH_KABSW, MASK_KABSW)\nDECLARE_INSN(kadd16, MATCH_KADD16, MASK_KADD16)\nDECLARE_INSN(kadd32, MATCH_KADD32, MASK_KADD32)\nDECLARE_INSN(kadd64, MATCH_KADD64, MASK_KADD64)\nDECLARE_INSN(kadd8, MATCH_KADD8, MASK_KADD8)\nDECLARE_INSN(kaddh, MATCH_KADDH, MASK_KADDH)\nDECLARE_INSN(kaddw, MATCH_KADDW, MASK_KADDW)\nDECLARE_INSN(kcras16, MATCH_KCRAS16, MASK_KCRAS16)\nDECLARE_INSN(kcras32, MATCH_KCRAS32, MASK_KCRAS32)\nDECLARE_INSN(kcrsa16, MATCH_KCRSA16, MASK_KCRSA16)\nDECLARE_INSN(kcrsa32, MATCH_KCRSA32, MASK_KCRSA32)\nDECLARE_INSN(kdmabb, MATCH_KDMABB, MASK_KDMABB)\nDECLARE_INSN(kdmabb16, MATCH_KDMABB16, MASK_KDMABB16)\nDECLARE_INSN(kdmabt, MATCH_KDMABT, MASK_KDMABT)\nDECLARE_INSN(kdmabt16, MATCH_KDMABT16, MASK_KDMABT16)\nDECLARE_INSN(kdmatt, MATCH_KDMATT, MASK_KDMATT)\nDECLARE_INSN(kdmatt16, MATCH_KDMATT16, MASK_KDMATT16)\nDECLARE_INSN(kdmbb, MATCH_KDMBB, MASK_KDMBB)\nDECLARE_INSN(kdmbb16, MATCH_KDMBB16, MASK_KDMBB16)\nDECLARE_INSN(kdmbt, MATCH_KDMBT, MASK_KDMBT)\nDECLARE_INSN(kdmbt16, MATCH_KDMBT16, MASK_KDMBT16)\nDECLARE_INSN(kdmtt, MATCH_KDMTT, MASK_KDMTT)\nDECLARE_INSN(kdmtt16, MATCH_KDMTT16, MASK_KDMTT16)\nDECLARE_INSN(khm16, MATCH_KHM16, MASK_KHM16)\nDECLARE_INSN(khm8, MATCH_KHM8, MASK_KHM8)\nDECLARE_INSN(khmbb, MATCH_KHMBB, MASK_KHMBB)\nDECLARE_INSN(khmbb16, MATCH_KHMBB16, MASK_KHMBB16)\nDECLARE_INSN(khmbt, MATCH_KHMBT, MASK_KHMBT)\nDECLARE_INSN(khmbt16, MATCH_KHMBT16, MASK_KHMBT16)\nDECLARE_INSN(khmtt, MATCH_KHMTT, MASK_KHMTT)\nDECLARE_INSN(khmtt16, MATCH_KHMTT16, MASK_KHMTT16)\nDECLARE_INSN(khmx16, MATCH_KHMX16, MASK_KHMX16)\nDECLARE_INSN(khmx8, MATCH_KHMX8, MASK_KHMX8)\nDECLARE_INSN(kmabb, MATCH_KMABB, MASK_KMABB)\nDECLARE_INSN(kmabb32, MATCH_KMABB32, MASK_KMABB32)\nDECLARE_INSN(kmabt, MATCH_KMABT, MASK_KMABT)\nDECLARE_INSN(kmabt32, MATCH_KMABT32, MASK_KMABT32)\nDECLARE_INSN(kmada, MATCH_KMADA, MASK_KMADA)\nDECLARE_INSN(kmadrs, MATCH_KMADRS, MASK_KMADRS)\nDECLARE_INSN(kmadrs32, MATCH_KMADRS32, MASK_KMADRS32)\nDECLARE_INSN(kmads, MATCH_KMADS, MASK_KMADS)\nDECLARE_INSN(kmads32, MATCH_KMADS32, MASK_KMADS32)\nDECLARE_INSN(kmar64, MATCH_KMAR64, MASK_KMAR64)\nDECLARE_INSN(kmatt, MATCH_KMATT, MASK_KMATT)\nDECLARE_INSN(kmatt32, MATCH_KMATT32, MASK_KMATT32)\nDECLARE_INSN(kmaxda, MATCH_KMAXDA, MASK_KMAXDA)\nDECLARE_INSN(kmaxda32, MATCH_KMAXDA32, MASK_KMAXDA32)\nDECLARE_INSN(kmaxds, MATCH_KMAXDS, MASK_KMAXDS)\nDECLARE_INSN(kmaxds32, MATCH_KMAXDS32, MASK_KMAXDS32)\nDECLARE_INSN(kmda, MATCH_KMDA, MASK_KMDA)\nDECLARE_INSN(kmda32, MATCH_KMDA32, MASK_KMDA32)\nDECLARE_INSN(kmmac, MATCH_KMMAC, MASK_KMMAC)\nDECLARE_INSN(kmmac_u, MATCH_KMMAC_U, MASK_KMMAC_U)\nDECLARE_INSN(kmmawb, MATCH_KMMAWB, MASK_KMMAWB)\nDECLARE_INSN(kmmawb2, MATCH_KMMAWB2, MASK_KMMAWB2)\nDECLARE_INSN(kmmawb2_u, MATCH_KMMAWB2_U, MASK_KMMAWB2_U)\nDECLARE_INSN(kmmawb_u, MATCH_KMMAWB_U, MASK_KMMAWB_U)\nDECLARE_INSN(kmmawt, MATCH_KMMAWT, MASK_KMMAWT)\nDECLARE_INSN(kmmawt2, MATCH_KMMAWT2, MASK_KMMAWT2)\nDECLARE_INSN(kmmawt2_u, MATCH_KMMAWT2_U, MASK_KMMAWT2_U)\nDECLARE_INSN(kmmawt_u, MATCH_KMMAWT_U, MASK_KMMAWT_U)\nDECLARE_INSN(kmmsb, MATCH_KMMSB, MASK_KMMSB)\nDECLARE_INSN(kmmsb_u, MATCH_KMMSB_U, MASK_KMMSB_U)\nDECLARE_INSN(kmmwb2, MATCH_KMMWB2, MASK_KMMWB2)\nDECLARE_INSN(kmmwb2_u, MATCH_KMMWB2_U, MASK_KMMWB2_U)\nDECLARE_INSN(kmmwt2, MATCH_KMMWT2, MASK_KMMWT2)\nDECLARE_INSN(kmmwt2_u, MATCH_KMMWT2_U, MASK_KMMWT2_U)\nDECLARE_INSN(kmsda, MATCH_KMSDA, MASK_KMSDA)\nDECLARE_INSN(kmsda32, MATCH_KMSDA32, MASK_KMSDA32)\nDECLARE_INSN(kmsr64, MATCH_KMSR64, MASK_KMSR64)\nDECLARE_INSN(kmsxda, MATCH_KMSXDA, MASK_KMSXDA)\nDECLARE_INSN(kmsxda32, MATCH_KMSXDA32, MASK_KMSXDA32)\nDECLARE_INSN(kmxda, MATCH_KMXDA, MASK_KMXDA)\nDECLARE_INSN(kmxda32, MATCH_KMXDA32, MASK_KMXDA32)\nDECLARE_INSN(ksll16, MATCH_KSLL16, MASK_KSLL16)\nDECLARE_INSN(ksll32, MATCH_KSLL32, MASK_KSLL32)\nDECLARE_INSN(ksll8, MATCH_KSLL8, MASK_KSLL8)\nDECLARE_INSN(kslli16, MATCH_KSLLI16, MASK_KSLLI16)\nDECLARE_INSN(kslli32, MATCH_KSLLI32, MASK_KSLLI32)\nDECLARE_INSN(kslli8, MATCH_KSLLI8, MASK_KSLLI8)\nDECLARE_INSN(kslliw, MATCH_KSLLIW, MASK_KSLLIW)\nDECLARE_INSN(ksllw, MATCH_KSLLW, MASK_KSLLW)\nDECLARE_INSN(kslra16, MATCH_KSLRA16, MASK_KSLRA16)\nDECLARE_INSN(kslra16_u, MATCH_KSLRA16_U, MASK_KSLRA16_U)\nDECLARE_INSN(kslra32, MATCH_KSLRA32, MASK_KSLRA32)\nDECLARE_INSN(kslra32_u, MATCH_KSLRA32_U, MASK_KSLRA32_U)\nDECLARE_INSN(kslra8, MATCH_KSLRA8, MASK_KSLRA8)\nDECLARE_INSN(kslra8_u, MATCH_KSLRA8_U, MASK_KSLRA8_U)\nDECLARE_INSN(kslraw, MATCH_KSLRAW, MASK_KSLRAW)\nDECLARE_INSN(kslraw_u, MATCH_KSLRAW_U, MASK_KSLRAW_U)\nDECLARE_INSN(kstas16, MATCH_KSTAS16, MASK_KSTAS16)\nDECLARE_INSN(kstas32, MATCH_KSTAS32, MASK_KSTAS32)\nDECLARE_INSN(kstsa16, MATCH_KSTSA16, MASK_KSTSA16)\nDECLARE_INSN(kstsa32, MATCH_KSTSA32, MASK_KSTSA32)\nDECLARE_INSN(ksub16, MATCH_KSUB16, MASK_KSUB16)\nDECLARE_INSN(ksub32, MATCH_KSUB32, MASK_KSUB32)\nDECLARE_INSN(ksub64, MATCH_KSUB64, MASK_KSUB64)\nDECLARE_INSN(ksub8, MATCH_KSUB8, MASK_KSUB8)\nDECLARE_INSN(ksubh, MATCH_KSUBH, MASK_KSUBH)\nDECLARE_INSN(ksubw, MATCH_KSUBW, MASK_KSUBW)\nDECLARE_INSN(kwmmul, MATCH_KWMMUL, MASK_KWMMUL)\nDECLARE_INSN(kwmmul_u, MATCH_KWMMUL_U, MASK_KWMMUL_U)\nDECLARE_INSN(lb, MATCH_LB, MASK_LB)\nDECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)\nDECLARE_INSN(ld, MATCH_LD, MASK_LD)\nDECLARE_INSN(ldu, MATCH_LDU, MASK_LDU)\nDECLARE_INSN(lh, MATCH_LH, MASK_LH)\nDECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)\nDECLARE_INSN(lq, MATCH_LQ, MASK_LQ)\nDECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)\nDECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)\nDECLARE_INSN(lui, MATCH_LUI, MASK_LUI)\nDECLARE_INSN(lw, MATCH_LW, MASK_LW)\nDECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)\nDECLARE_INSN(maddr32, MATCH_MADDR32, MASK_MADDR32)\nDECLARE_INSN(max, MATCH_MAX, MASK_MAX)\nDECLARE_INSN(maxu, MATCH_MAXU, MASK_MAXU)\nDECLARE_INSN(maxw, MATCH_MAXW, MASK_MAXW)\nDECLARE_INSN(min, MATCH_MIN, MASK_MIN)\nDECLARE_INSN(minu, MATCH_MINU, MASK_MINU)\nDECLARE_INSN(minw, MATCH_MINW, MASK_MINW)\nDECLARE_INSN(mret, MATCH_MRET, MASK_MRET)\nDECLARE_INSN(msubr32, MATCH_MSUBR32, MASK_MSUBR32)\nDECLARE_INSN(mul, MATCH_MUL, MASK_MUL)\nDECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)\nDECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)\nDECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)\nDECLARE_INSN(mulr64, MATCH_MULR64, MASK_MULR64)\nDECLARE_INSN(mulsr64, MATCH_MULSR64, MASK_MULSR64)\nDECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)\nDECLARE_INSN(or, MATCH_OR, MASK_OR)\nDECLARE_INSN(ori, MATCH_ORI, MASK_ORI)\nDECLARE_INSN(orn, MATCH_ORN, MASK_ORN)\nDECLARE_INSN(pack, MATCH_PACK, MASK_PACK)\nDECLARE_INSN(packh, MATCH_PACKH, MASK_PACKH)\nDECLARE_INSN(packu, MATCH_PACKU, MASK_PACKU)\nDECLARE_INSN(packuw, MATCH_PACKUW, MASK_PACKUW)\nDECLARE_INSN(packw, MATCH_PACKW, MASK_PACKW)\nDECLARE_INSN(pause, MATCH_PAUSE, MASK_PAUSE)\nDECLARE_INSN(pbsad, MATCH_PBSAD, MASK_PBSAD)\nDECLARE_INSN(pbsada, MATCH_PBSADA, MASK_PBSADA)\nDECLARE_INSN(pkbb16, MATCH_PKBB16, MASK_PKBB16)\nDECLARE_INSN(pkbb32, MATCH_PKBB32, MASK_PKBB32)\nDECLARE_INSN(pkbt16, MATCH_PKBT16, MASK_PKBT16)\nDECLARE_INSN(pkbt32, MATCH_PKBT32, MASK_PKBT32)\nDECLARE_INSN(pktb16, MATCH_PKTB16, MASK_PKTB16)\nDECLARE_INSN(pktb32, MATCH_PKTB32, MASK_PKTB32)\nDECLARE_INSN(pktt16, MATCH_PKTT16, MASK_PKTT16)\nDECLARE_INSN(pktt32, MATCH_PKTT32, MASK_PKTT32)\nDECLARE_INSN(prefetch_i, MATCH_PREFETCH_I, MASK_PREFETCH_I)\nDECLARE_INSN(prefetch_r, MATCH_PREFETCH_R, MASK_PREFETCH_R)\nDECLARE_INSN(prefetch_w, MATCH_PREFETCH_W, MASK_PREFETCH_W)\nDECLARE_INSN(radd16, MATCH_RADD16, MASK_RADD16)\nDECLARE_INSN(radd32, MATCH_RADD32, MASK_RADD32)\nDECLARE_INSN(radd64, MATCH_RADD64, MASK_RADD64)\nDECLARE_INSN(radd8, MATCH_RADD8, MASK_RADD8)\nDECLARE_INSN(raddw, MATCH_RADDW, MASK_RADDW)\nDECLARE_INSN(rcras16, MATCH_RCRAS16, MASK_RCRAS16)\nDECLARE_INSN(rcras32, MATCH_RCRAS32, MASK_RCRAS32)\nDECLARE_INSN(rcrsa16, MATCH_RCRSA16, MASK_RCRSA16)\nDECLARE_INSN(rcrsa32, MATCH_RCRSA32, MASK_RCRSA32)\nDECLARE_INSN(rem, MATCH_REM, MASK_REM)\nDECLARE_INSN(remu, MATCH_REMU, MASK_REMU)\nDECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)\nDECLARE_INSN(remw, MATCH_REMW, MASK_REMW)\nDECLARE_INSN(rol, MATCH_ROL, MASK_ROL)\nDECLARE_INSN(rolw, MATCH_ROLW, MASK_ROLW)\nDECLARE_INSN(ror, MATCH_ROR, MASK_ROR)\nDECLARE_INSN(rori, MATCH_RORI, MASK_RORI)\nDECLARE_INSN(roriw, MATCH_RORIW, MASK_RORIW)\nDECLARE_INSN(rorw, MATCH_RORW, MASK_RORW)\nDECLARE_INSN(rstas16, MATCH_RSTAS16, MASK_RSTAS16)\nDECLARE_INSN(rstas32, MATCH_RSTAS32, MASK_RSTAS32)\nDECLARE_INSN(rstsa16, MATCH_RSTSA16, MASK_RSTSA16)\nDECLARE_INSN(rstsa32, MATCH_RSTSA32, MASK_RSTSA32)\nDECLARE_INSN(rsub16, MATCH_RSUB16, MASK_RSUB16)\nDECLARE_INSN(rsub32, MATCH_RSUB32, MASK_RSUB32)\nDECLARE_INSN(rsub64, MATCH_RSUB64, MASK_RSUB64)\nDECLARE_INSN(rsub8, MATCH_RSUB8, MASK_RSUB8)\nDECLARE_INSN(rsubw, MATCH_RSUBW, MASK_RSUBW)\nDECLARE_INSN(sb, MATCH_SB, MASK_SB)\nDECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)\nDECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)\nDECLARE_INSN(sclip16, MATCH_SCLIP16, MASK_SCLIP16)\nDECLARE_INSN(sclip32, MATCH_SCLIP32, MASK_SCLIP32)\nDECLARE_INSN(sclip8, MATCH_SCLIP8, MASK_SCLIP8)\nDECLARE_INSN(scmple16, MATCH_SCMPLE16, MASK_SCMPLE16)\nDECLARE_INSN(scmple8, MATCH_SCMPLE8, MASK_SCMPLE8)\nDECLARE_INSN(scmplt16, MATCH_SCMPLT16, MASK_SCMPLT16)\nDECLARE_INSN(scmplt8, MATCH_SCMPLT8, MASK_SCMPLT8)\nDECLARE_INSN(sd, MATCH_SD, MASK_SD)\nDECLARE_INSN(sext_b, MATCH_SEXT_B, MASK_SEXT_B)\nDECLARE_INSN(sext_h, MATCH_SEXT_H, MASK_SEXT_H)\nDECLARE_INSN(sfence_inval_ir, MATCH_SFENCE_INVAL_IR, MASK_SFENCE_INVAL_IR)\nDECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)\nDECLARE_INSN(sfence_w_inval, MATCH_SFENCE_W_INVAL, MASK_SFENCE_W_INVAL)\nDECLARE_INSN(sh, MATCH_SH, MASK_SH)\nDECLARE_INSN(sh1add, MATCH_SH1ADD, MASK_SH1ADD)\nDECLARE_INSN(sh1add_uw, MATCH_SH1ADD_UW, MASK_SH1ADD_UW)\nDECLARE_INSN(sh2add, MATCH_SH2ADD, MASK_SH2ADD)\nDECLARE_INSN(sh2add_uw, MATCH_SH2ADD_UW, MASK_SH2ADD_UW)\nDECLARE_INSN(sh3add, MATCH_SH3ADD, MASK_SH3ADD)\nDECLARE_INSN(sh3add_uw, MATCH_SH3ADD_UW, MASK_SH3ADD_UW)\nDECLARE_INSN(sha256sig0, MATCH_SHA256SIG0, MASK_SHA256SIG0)\nDECLARE_INSN(sha256sig1, MATCH_SHA256SIG1, MASK_SHA256SIG1)\nDECLARE_INSN(sha256sum0, MATCH_SHA256SUM0, MASK_SHA256SUM0)\nDECLARE_INSN(sha256sum1, MATCH_SHA256SUM1, MASK_SHA256SUM1)\nDECLARE_INSN(sha512sig0, MATCH_SHA512SIG0, MASK_SHA512SIG0)\nDECLARE_INSN(sha512sig0h, MATCH_SHA512SIG0H, MASK_SHA512SIG0H)\nDECLARE_INSN(sha512sig0l, MATCH_SHA512SIG0L, MASK_SHA512SIG0L)\nDECLARE_INSN(sha512sig1, MATCH_SHA512SIG1, MASK_SHA512SIG1)\nDECLARE_INSN(sha512sig1h, MATCH_SHA512SIG1H, MASK_SHA512SIG1H)\nDECLARE_INSN(sha512sig1l, MATCH_SHA512SIG1L, MASK_SHA512SIG1L)\nDECLARE_INSN(sha512sum0, MATCH_SHA512SUM0, MASK_SHA512SUM0)\nDECLARE_INSN(sha512sum0r, MATCH_SHA512SUM0R, MASK_SHA512SUM0R)\nDECLARE_INSN(sha512sum1, MATCH_SHA512SUM1, MASK_SHA512SUM1)\nDECLARE_INSN(sha512sum1r, MATCH_SHA512SUM1R, MASK_SHA512SUM1R)\nDECLARE_INSN(shfl, MATCH_SHFL, MASK_SHFL)\nDECLARE_INSN(shfli, MATCH_SHFLI, MASK_SHFLI)\nDECLARE_INSN(shflw, MATCH_SHFLW, MASK_SHFLW)\nDECLARE_INSN(sinval_vma, MATCH_SINVAL_VMA, MASK_SINVAL_VMA)\nDECLARE_INSN(sll, MATCH_SLL, MASK_SLL)\nDECLARE_INSN(sll16, MATCH_SLL16, MASK_SLL16)\nDECLARE_INSN(sll32, MATCH_SLL32, MASK_SLL32)\nDECLARE_INSN(sll8, MATCH_SLL8, MASK_SLL8)\nDECLARE_INSN(slld, MATCH_SLLD, MASK_SLLD)\nDECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)\nDECLARE_INSN(slli16, MATCH_SLLI16, MASK_SLLI16)\nDECLARE_INSN(slli32, MATCH_SLLI32, MASK_SLLI32)\nDECLARE_INSN(slli8, MATCH_SLLI8, MASK_SLLI8)\nDECLARE_INSN(slli_uw, MATCH_SLLI_UW, MASK_SLLI_UW)\nDECLARE_INSN(sllid, MATCH_SLLID, MASK_SLLID)\nDECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)\nDECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)\nDECLARE_INSN(slo, MATCH_SLO, MASK_SLO)\nDECLARE_INSN(sloi, MATCH_SLOI, MASK_SLOI)\nDECLARE_INSN(sloiw, MATCH_SLOIW, MASK_SLOIW)\nDECLARE_INSN(slow, MATCH_SLOW, MASK_SLOW)\nDECLARE_INSN(slt, MATCH_SLT, MASK_SLT)\nDECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)\nDECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)\nDECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)\nDECLARE_INSN(sm3p0, MATCH_SM3P0, MASK_SM3P0)\nDECLARE_INSN(sm3p1, MATCH_SM3P1, MASK_SM3P1)\nDECLARE_INSN(sm4ed, MATCH_SM4ED, MASK_SM4ED)\nDECLARE_INSN(sm4ks, MATCH_SM4KS, MASK_SM4KS)\nDECLARE_INSN(smal, MATCH_SMAL, MASK_SMAL)\nDECLARE_INSN(smalbb, MATCH_SMALBB, MASK_SMALBB)\nDECLARE_INSN(smalbt, MATCH_SMALBT, MASK_SMALBT)\nDECLARE_INSN(smalda, MATCH_SMALDA, MASK_SMALDA)\nDECLARE_INSN(smaldrs, MATCH_SMALDRS, MASK_SMALDRS)\nDECLARE_INSN(smalds, MATCH_SMALDS, MASK_SMALDS)\nDECLARE_INSN(smaltt, MATCH_SMALTT, MASK_SMALTT)\nDECLARE_INSN(smalxda, MATCH_SMALXDA, MASK_SMALXDA)\nDECLARE_INSN(smalxds, MATCH_SMALXDS, MASK_SMALXDS)\nDECLARE_INSN(smaqa, MATCH_SMAQA, MASK_SMAQA)\nDECLARE_INSN(smaqa_su, MATCH_SMAQA_SU, MASK_SMAQA_SU)\nDECLARE_INSN(smar64, MATCH_SMAR64, MASK_SMAR64)\nDECLARE_INSN(smax16, MATCH_SMAX16, MASK_SMAX16)\nDECLARE_INSN(smax32, MATCH_SMAX32, MASK_SMAX32)\nDECLARE_INSN(smax8, MATCH_SMAX8, MASK_SMAX8)\nDECLARE_INSN(smbb16, MATCH_SMBB16, MASK_SMBB16)\nDECLARE_INSN(smbt16, MATCH_SMBT16, MASK_SMBT16)\nDECLARE_INSN(smbt32, MATCH_SMBT32, MASK_SMBT32)\nDECLARE_INSN(smdrs, MATCH_SMDRS, MASK_SMDRS)\nDECLARE_INSN(smdrs32, MATCH_SMDRS32, MASK_SMDRS32)\nDECLARE_INSN(smds, MATCH_SMDS, MASK_SMDS)\nDECLARE_INSN(smds32, MATCH_SMDS32, MASK_SMDS32)\nDECLARE_INSN(smin16, MATCH_SMIN16, MASK_SMIN16)\nDECLARE_INSN(smin32, MATCH_SMIN32, MASK_SMIN32)\nDECLARE_INSN(smin8, MATCH_SMIN8, MASK_SMIN8)\nDECLARE_INSN(smmul, MATCH_SMMUL, MASK_SMMUL)\nDECLARE_INSN(smmul_u, MATCH_SMMUL_U, MASK_SMMUL_U)\nDECLARE_INSN(smmwb, MATCH_SMMWB, MASK_SMMWB)\nDECLARE_INSN(smmwb_u, MATCH_SMMWB_U, MASK_SMMWB_U)\nDECLARE_INSN(smmwt, MATCH_SMMWT, MASK_SMMWT)\nDECLARE_INSN(smmwt_u, MATCH_SMMWT_U, MASK_SMMWT_U)\nDECLARE_INSN(smslda, MATCH_SMSLDA, MASK_SMSLDA)\nDECLARE_INSN(smslxda, MATCH_SMSLXDA, MASK_SMSLXDA)\nDECLARE_INSN(smsr64, MATCH_SMSR64, MASK_SMSR64)\nDECLARE_INSN(smtt16, MATCH_SMTT16, MASK_SMTT16)\nDECLARE_INSN(smtt32, MATCH_SMTT32, MASK_SMTT32)\nDECLARE_INSN(smul16, MATCH_SMUL16, MASK_SMUL16)\nDECLARE_INSN(smul8, MATCH_SMUL8, MASK_SMUL8)\nDECLARE_INSN(smulx16, MATCH_SMULX16, MASK_SMULX16)\nDECLARE_INSN(smulx8, MATCH_SMULX8, MASK_SMULX8)\nDECLARE_INSN(smxds, MATCH_SMXDS, MASK_SMXDS)\nDECLARE_INSN(smxds32, MATCH_SMXDS32, MASK_SMXDS32)\nDECLARE_INSN(sq, MATCH_SQ, MASK_SQ)\nDECLARE_INSN(sra, MATCH_SRA, MASK_SRA)\nDECLARE_INSN(sra16, MATCH_SRA16, MASK_SRA16)\nDECLARE_INSN(sra16_u, MATCH_SRA16_U, MASK_SRA16_U)\nDECLARE_INSN(sra32, MATCH_SRA32, MASK_SRA32)\nDECLARE_INSN(sra32_u, MATCH_SRA32_U, MASK_SRA32_U)\nDECLARE_INSN(sra8, MATCH_SRA8, MASK_SRA8)\nDECLARE_INSN(sra8_u, MATCH_SRA8_U, MASK_SRA8_U)\nDECLARE_INSN(sra_u, MATCH_SRA_U, MASK_SRA_U)\nDECLARE_INSN(srad, MATCH_SRAD, MASK_SRAD)\nDECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)\nDECLARE_INSN(srai16, MATCH_SRAI16, MASK_SRAI16)\nDECLARE_INSN(srai16_u, MATCH_SRAI16_U, MASK_SRAI16_U)\nDECLARE_INSN(srai32, MATCH_SRAI32, MASK_SRAI32)\nDECLARE_INSN(srai32_u, MATCH_SRAI32_U, MASK_SRAI32_U)\nDECLARE_INSN(srai8, MATCH_SRAI8, MASK_SRAI8)\nDECLARE_INSN(srai8_u, MATCH_SRAI8_U, MASK_SRAI8_U)\nDECLARE_INSN(srai_u, MATCH_SRAI_U, MASK_SRAI_U)\nDECLARE_INSN(sraid, MATCH_SRAID, MASK_SRAID)\nDECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)\nDECLARE_INSN(sraiw_u, MATCH_SRAIW_U, MASK_SRAIW_U)\nDECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)\nDECLARE_INSN(sret, MATCH_SRET, MASK_SRET)\nDECLARE_INSN(srl, MATCH_SRL, MASK_SRL)\nDECLARE_INSN(srl16, MATCH_SRL16, MASK_SRL16)\nDECLARE_INSN(srl16_u, MATCH_SRL16_U, MASK_SRL16_U)\nDECLARE_INSN(srl32, MATCH_SRL32, MASK_SRL32)\nDECLARE_INSN(srl32_u, MATCH_SRL32_U, MASK_SRL32_U)\nDECLARE_INSN(srl8, MATCH_SRL8, MASK_SRL8)\nDECLARE_INSN(srl8_u, MATCH_SRL8_U, MASK_SRL8_U)\nDECLARE_INSN(srld, MATCH_SRLD, MASK_SRLD)\nDECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)\nDECLARE_INSN(srli16, MATCH_SRLI16, MASK_SRLI16)\nDECLARE_INSN(srli16_u, MATCH_SRLI16_U, MASK_SRLI16_U)\nDECLARE_INSN(srli32, MATCH_SRLI32, MASK_SRLI32)\nDECLARE_INSN(srli32_u, MATCH_SRLI32_U, MASK_SRLI32_U)\nDECLARE_INSN(srli8, MATCH_SRLI8, MASK_SRLI8)\nDECLARE_INSN(srli8_u, MATCH_SRLI8_U, MASK_SRLI8_U)\nDECLARE_INSN(srlid, MATCH_SRLID, MASK_SRLID)\nDECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)\nDECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)\nDECLARE_INSN(sro, MATCH_SRO, MASK_SRO)\nDECLARE_INSN(sroi, MATCH_SROI, MASK_SROI)\nDECLARE_INSN(sroiw, MATCH_SROIW, MASK_SROIW)\nDECLARE_INSN(srow, MATCH_SROW, MASK_SROW)\nDECLARE_INSN(stas16, MATCH_STAS16, MASK_STAS16)\nDECLARE_INSN(stas32, MATCH_STAS32, MASK_STAS32)\nDECLARE_INSN(stsa16, MATCH_STSA16, MASK_STSA16)\nDECLARE_INSN(stsa32, MATCH_STSA32, MASK_STSA32)\nDECLARE_INSN(sub, MATCH_SUB, MASK_SUB)\nDECLARE_INSN(sub16, MATCH_SUB16, MASK_SUB16)\nDECLARE_INSN(sub32, MATCH_SUB32, MASK_SUB32)\nDECLARE_INSN(sub64, MATCH_SUB64, MASK_SUB64)\nDECLARE_INSN(sub8, MATCH_SUB8, MASK_SUB8)\nDECLARE_INSN(subd, MATCH_SUBD, MASK_SUBD)\nDECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)\nDECLARE_INSN(sunpkd810, MATCH_SUNPKD810, MASK_SUNPKD810)\nDECLARE_INSN(sunpkd820, MATCH_SUNPKD820, MASK_SUNPKD820)\nDECLARE_INSN(sunpkd830, MATCH_SUNPKD830, MASK_SUNPKD830)\nDECLARE_INSN(sunpkd831, MATCH_SUNPKD831, MASK_SUNPKD831)\nDECLARE_INSN(sunpkd832, MATCH_SUNPKD832, MASK_SUNPKD832)\nDECLARE_INSN(sw, MATCH_SW, MASK_SW)\nDECLARE_INSN(swap8, MATCH_SWAP8, MASK_SWAP8)\nDECLARE_INSN(uclip16, MATCH_UCLIP16, MASK_UCLIP16)\nDECLARE_INSN(uclip32, MATCH_UCLIP32, MASK_UCLIP32)\nDECLARE_INSN(uclip8, MATCH_UCLIP8, MASK_UCLIP8)\nDECLARE_INSN(ucmple16, MATCH_UCMPLE16, MASK_UCMPLE16)\nDECLARE_INSN(ucmple8, MATCH_UCMPLE8, MASK_UCMPLE8)\nDECLARE_INSN(ucmplt16, MATCH_UCMPLT16, MASK_UCMPLT16)\nDECLARE_INSN(ucmplt8, MATCH_UCMPLT8, MASK_UCMPLT8)\nDECLARE_INSN(ukadd16, MATCH_UKADD16, MASK_UKADD16)\nDECLARE_INSN(ukadd32, MATCH_UKADD32, MASK_UKADD32)\nDECLARE_INSN(ukadd64, MATCH_UKADD64, MASK_UKADD64)\nDECLARE_INSN(ukadd8, MATCH_UKADD8, MASK_UKADD8)\nDECLARE_INSN(ukaddh, MATCH_UKADDH, MASK_UKADDH)\nDECLARE_INSN(ukaddw, MATCH_UKADDW, MASK_UKADDW)\nDECLARE_INSN(ukcras16, MATCH_UKCRAS16, MASK_UKCRAS16)\nDECLARE_INSN(ukcras32, MATCH_UKCRAS32, MASK_UKCRAS32)\nDECLARE_INSN(ukcrsa16, MATCH_UKCRSA16, MASK_UKCRSA16)\nDECLARE_INSN(ukcrsa32, MATCH_UKCRSA32, MASK_UKCRSA32)\nDECLARE_INSN(ukmar64, MATCH_UKMAR64, MASK_UKMAR64)\nDECLARE_INSN(ukmsr64, MATCH_UKMSR64, MASK_UKMSR64)\nDECLARE_INSN(ukstas16, MATCH_UKSTAS16, MASK_UKSTAS16)\nDECLARE_INSN(ukstas32, MATCH_UKSTAS32, MASK_UKSTAS32)\nDECLARE_INSN(ukstsa16, MATCH_UKSTSA16, MASK_UKSTSA16)\nDECLARE_INSN(ukstsa32, MATCH_UKSTSA32, MASK_UKSTSA32)\nDECLARE_INSN(uksub16, MATCH_UKSUB16, MASK_UKSUB16)\nDECLARE_INSN(uksub32, MATCH_UKSUB32, MASK_UKSUB32)\nDECLARE_INSN(uksub64, MATCH_UKSUB64, MASK_UKSUB64)\nDECLARE_INSN(uksub8, MATCH_UKSUB8, MASK_UKSUB8)\nDECLARE_INSN(uksubh, MATCH_UKSUBH, MASK_UKSUBH)\nDECLARE_INSN(uksubw, MATCH_UKSUBW, MASK_UKSUBW)\nDECLARE_INSN(umaqa, MATCH_UMAQA, MASK_UMAQA)\nDECLARE_INSN(umar64, MATCH_UMAR64, MASK_UMAR64)\nDECLARE_INSN(umax16, MATCH_UMAX16, MASK_UMAX16)\nDECLARE_INSN(umax32, MATCH_UMAX32, MASK_UMAX32)\nDECLARE_INSN(umax8, MATCH_UMAX8, MASK_UMAX8)\nDECLARE_INSN(umin16, MATCH_UMIN16, MASK_UMIN16)\nDECLARE_INSN(umin32, MATCH_UMIN32, MASK_UMIN32)\nDECLARE_INSN(umin8, MATCH_UMIN8, MASK_UMIN8)\nDECLARE_INSN(umsr64, MATCH_UMSR64, MASK_UMSR64)\nDECLARE_INSN(umul16, MATCH_UMUL16, MASK_UMUL16)\nDECLARE_INSN(umul8, MATCH_UMUL8, MASK_UMUL8)\nDECLARE_INSN(umulx16, MATCH_UMULX16, MASK_UMULX16)\nDECLARE_INSN(umulx8, MATCH_UMULX8, MASK_UMULX8)\nDECLARE_INSN(unshfl, MATCH_UNSHFL, MASK_UNSHFL)\nDECLARE_INSN(unshfli, MATCH_UNSHFLI, MASK_UNSHFLI)\nDECLARE_INSN(unshflw, MATCH_UNSHFLW, MASK_UNSHFLW)\nDECLARE_INSN(uradd16, MATCH_URADD16, MASK_URADD16)\nDECLARE_INSN(uradd32, MATCH_URADD32, MASK_URADD32)\nDECLARE_INSN(uradd64, MATCH_URADD64, MASK_URADD64)\nDECLARE_INSN(uradd8, MATCH_URADD8, MASK_URADD8)\nDECLARE_INSN(uraddw, MATCH_URADDW, MASK_URADDW)\nDECLARE_INSN(urcras16, MATCH_URCRAS16, MASK_URCRAS16)\nDECLARE_INSN(urcras32, MATCH_URCRAS32, MASK_URCRAS32)\nDECLARE_INSN(urcrsa16, MATCH_URCRSA16, MASK_URCRSA16)\nDECLARE_INSN(urcrsa32, MATCH_URCRSA32, MASK_URCRSA32)\nDECLARE_INSN(urstas16, MATCH_URSTAS16, MASK_URSTAS16)\nDECLARE_INSN(urstas32, MATCH_URSTAS32, MASK_URSTAS32)\nDECLARE_INSN(urstsa16, MATCH_URSTSA16, MASK_URSTSA16)\nDECLARE_INSN(urstsa32, MATCH_URSTSA32, MASK_URSTSA32)\nDECLARE_INSN(ursub16, MATCH_URSUB16, MASK_URSUB16)\nDECLARE_INSN(ursub32, MATCH_URSUB32, MASK_URSUB32)\nDECLARE_INSN(ursub64, MATCH_URSUB64, MASK_URSUB64)\nDECLARE_INSN(ursub8, MATCH_URSUB8, MASK_URSUB8)\nDECLARE_INSN(ursubw, MATCH_URSUBW, MASK_URSUBW)\nDECLARE_INSN(vaadd_vv, MATCH_VAADD_VV, MASK_VAADD_VV)\nDECLARE_INSN(vaadd_vx, MATCH_VAADD_VX, MASK_VAADD_VX)\nDECLARE_INSN(vaaddu_vv, MATCH_VAADDU_VV, MASK_VAADDU_VV)\nDECLARE_INSN(vaaddu_vx, MATCH_VAADDU_VX, MASK_VAADDU_VX)\nDECLARE_INSN(vadc_vim, MATCH_VADC_VIM, MASK_VADC_VIM)\nDECLARE_INSN(vadc_vvm, MATCH_VADC_VVM, MASK_VADC_VVM)\nDECLARE_INSN(vadc_vxm, MATCH_VADC_VXM, MASK_VADC_VXM)\nDECLARE_INSN(vadd_vi, MATCH_VADD_VI, MASK_VADD_VI)\nDECLARE_INSN(vadd_vv, MATCH_VADD_VV, MASK_VADD_VV)\nDECLARE_INSN(vadd_vx, MATCH_VADD_VX, MASK_VADD_VX)\nDECLARE_INSN(vamoaddei16_v, MATCH_VAMOADDEI16_V, MASK_VAMOADDEI16_V)\nDECLARE_INSN(vamoaddei32_v, MATCH_VAMOADDEI32_V, MASK_VAMOADDEI32_V)\nDECLARE_INSN(vamoaddei64_v, MATCH_VAMOADDEI64_V, MASK_VAMOADDEI64_V)\nDECLARE_INSN(vamoaddei8_v, MATCH_VAMOADDEI8_V, MASK_VAMOADDEI8_V)\nDECLARE_INSN(vamoandei16_v, MATCH_VAMOANDEI16_V, MASK_VAMOANDEI16_V)\nDECLARE_INSN(vamoandei32_v, MATCH_VAMOANDEI32_V, MASK_VAMOANDEI32_V)\nDECLARE_INSN(vamoandei64_v, MATCH_VAMOANDEI64_V, MASK_VAMOANDEI64_V)\nDECLARE_INSN(vamoandei8_v, MATCH_VAMOANDEI8_V, MASK_VAMOANDEI8_V)\nDECLARE_INSN(vamomaxei16_v, MATCH_VAMOMAXEI16_V, MASK_VAMOMAXEI16_V)\nDECLARE_INSN(vamomaxei32_v, MATCH_VAMOMAXEI32_V, MASK_VAMOMAXEI32_V)\nDECLARE_INSN(vamomaxei64_v, MATCH_VAMOMAXEI64_V, MASK_VAMOMAXEI64_V)\nDECLARE_INSN(vamomaxei8_v, MATCH_VAMOMAXEI8_V, MASK_VAMOMAXEI8_V)\nDECLARE_INSN(vamomaxuei16_v, MATCH_VAMOMAXUEI16_V, MASK_VAMOMAXUEI16_V)\nDECLARE_INSN(vamomaxuei32_v, MATCH_VAMOMAXUEI32_V, MASK_VAMOMAXUEI32_V)\nDECLARE_INSN(vamomaxuei64_v, MATCH_VAMOMAXUEI64_V, MASK_VAMOMAXUEI64_V)\nDECLARE_INSN(vamomaxuei8_v, MATCH_VAMOMAXUEI8_V, MASK_VAMOMAXUEI8_V)\nDECLARE_INSN(vamominei16_v, MATCH_VAMOMINEI16_V, MASK_VAMOMINEI16_V)\nDECLARE_INSN(vamominei32_v, MATCH_VAMOMINEI32_V, MASK_VAMOMINEI32_V)\nDECLARE_INSN(vamominei64_v, MATCH_VAMOMINEI64_V, MASK_VAMOMINEI64_V)\nDECLARE_INSN(vamominei8_v, MATCH_VAMOMINEI8_V, MASK_VAMOMINEI8_V)\nDECLARE_INSN(vamominuei16_v, MATCH_VAMOMINUEI16_V, MASK_VAMOMINUEI16_V)\nDECLARE_INSN(vamominuei32_v, MATCH_VAMOMINUEI32_V, MASK_VAMOMINUEI32_V)\nDECLARE_INSN(vamominuei64_v, MATCH_VAMOMINUEI64_V, MASK_VAMOMINUEI64_V)\nDECLARE_INSN(vamominuei8_v, MATCH_VAMOMINUEI8_V, MASK_VAMOMINUEI8_V)\nDECLARE_INSN(vamoorei16_v, MATCH_VAMOOREI16_V, MASK_VAMOOREI16_V)\nDECLARE_INSN(vamoorei32_v, MATCH_VAMOOREI32_V, MASK_VAMOOREI32_V)\nDECLARE_INSN(vamoorei64_v, MATCH_VAMOOREI64_V, MASK_VAMOOREI64_V)\nDECLARE_INSN(vamoorei8_v, MATCH_VAMOOREI8_V, MASK_VAMOOREI8_V)\nDECLARE_INSN(vamoswapei16_v, MATCH_VAMOSWAPEI16_V, MASK_VAMOSWAPEI16_V)\nDECLARE_INSN(vamoswapei32_v, MATCH_VAMOSWAPEI32_V, MASK_VAMOSWAPEI32_V)\nDECLARE_INSN(vamoswapei64_v, MATCH_VAMOSWAPEI64_V, MASK_VAMOSWAPEI64_V)\nDECLARE_INSN(vamoswapei8_v, MATCH_VAMOSWAPEI8_V, MASK_VAMOSWAPEI8_V)\nDECLARE_INSN(vamoxorei16_v, MATCH_VAMOXOREI16_V, MASK_VAMOXOREI16_V)\nDECLARE_INSN(vamoxorei32_v, MATCH_VAMOXOREI32_V, MASK_VAMOXOREI32_V)\nDECLARE_INSN(vamoxorei64_v, MATCH_VAMOXOREI64_V, MASK_VAMOXOREI64_V)\nDECLARE_INSN(vamoxorei8_v, MATCH_VAMOXOREI8_V, MASK_VAMOXOREI8_V)\nDECLARE_INSN(vand_vi, MATCH_VAND_VI, MASK_VAND_VI)\nDECLARE_INSN(vand_vv, MATCH_VAND_VV, MASK_VAND_VV)\nDECLARE_INSN(vand_vx, MATCH_VAND_VX, MASK_VAND_VX)\nDECLARE_INSN(vasub_vv, MATCH_VASUB_VV, MASK_VASUB_VV)\nDECLARE_INSN(vasub_vx, MATCH_VASUB_VX, MASK_VASUB_VX)\nDECLARE_INSN(vasubu_vv, MATCH_VASUBU_VV, MASK_VASUBU_VV)\nDECLARE_INSN(vasubu_vx, MATCH_VASUBU_VX, MASK_VASUBU_VX)\nDECLARE_INSN(vcompress_vm, MATCH_VCOMPRESS_VM, MASK_VCOMPRESS_VM)\nDECLARE_INSN(vcpop_m, MATCH_VCPOP_M, MASK_VCPOP_M)\nDECLARE_INSN(vdiv_vv, MATCH_VDIV_VV, MASK_VDIV_VV)\nDECLARE_INSN(vdiv_vx, MATCH_VDIV_VX, MASK_VDIV_VX)\nDECLARE_INSN(vdivu_vv, MATCH_VDIVU_VV, MASK_VDIVU_VV)\nDECLARE_INSN(vdivu_vx, MATCH_VDIVU_VX, MASK_VDIVU_VX)\nDECLARE_INSN(vfadd_vf, MATCH_VFADD_VF, MASK_VFADD_VF)\nDECLARE_INSN(vfadd_vv, MATCH_VFADD_VV, MASK_VFADD_VV)\nDECLARE_INSN(vfclass_v, MATCH_VFCLASS_V, MASK_VFCLASS_V)\nDECLARE_INSN(vfcvt_f_x_v, MATCH_VFCVT_F_X_V, MASK_VFCVT_F_X_V)\nDECLARE_INSN(vfcvt_f_xu_v, MATCH_VFCVT_F_XU_V, MASK_VFCVT_F_XU_V)\nDECLARE_INSN(vfcvt_rtz_x_f_v, MATCH_VFCVT_RTZ_X_F_V, MASK_VFCVT_RTZ_X_F_V)\nDECLARE_INSN(vfcvt_rtz_xu_f_v, MATCH_VFCVT_RTZ_XU_F_V, MASK_VFCVT_RTZ_XU_F_V)\nDECLARE_INSN(vfcvt_x_f_v, MATCH_VFCVT_X_F_V, MASK_VFCVT_X_F_V)\nDECLARE_INSN(vfcvt_xu_f_v, MATCH_VFCVT_XU_F_V, MASK_VFCVT_XU_F_V)\nDECLARE_INSN(vfdiv_vf, MATCH_VFDIV_VF, MASK_VFDIV_VF)\nDECLARE_INSN(vfdiv_vv, MATCH_VFDIV_VV, MASK_VFDIV_VV)\nDECLARE_INSN(vfirst_m, MATCH_VFIRST_M, MASK_VFIRST_M)\nDECLARE_INSN(vfmacc_vf, MATCH_VFMACC_VF, MASK_VFMACC_VF)\nDECLARE_INSN(vfmacc_vv, MATCH_VFMACC_VV, MASK_VFMACC_VV)\nDECLARE_INSN(vfmadd_vf, MATCH_VFMADD_VF, MASK_VFMADD_VF)\nDECLARE_INSN(vfmadd_vv, MATCH_VFMADD_VV, MASK_VFMADD_VV)\nDECLARE_INSN(vfmax_vf, MATCH_VFMAX_VF, MASK_VFMAX_VF)\nDECLARE_INSN(vfmax_vv, MATCH_VFMAX_VV, MASK_VFMAX_VV)\nDECLARE_INSN(vfmerge_vfm, MATCH_VFMERGE_VFM, MASK_VFMERGE_VFM)\nDECLARE_INSN(vfmin_vf, MATCH_VFMIN_VF, MASK_VFMIN_VF)\nDECLARE_INSN(vfmin_vv, MATCH_VFMIN_VV, MASK_VFMIN_VV)\nDECLARE_INSN(vfmsac_vf, MATCH_VFMSAC_VF, MASK_VFMSAC_VF)\nDECLARE_INSN(vfmsac_vv, MATCH_VFMSAC_VV, MASK_VFMSAC_VV)\nDECLARE_INSN(vfmsub_vf, MATCH_VFMSUB_VF, MASK_VFMSUB_VF)\nDECLARE_INSN(vfmsub_vv, MATCH_VFMSUB_VV, MASK_VFMSUB_VV)\nDECLARE_INSN(vfmul_vf, MATCH_VFMUL_VF, MASK_VFMUL_VF)\nDECLARE_INSN(vfmul_vv, MATCH_VFMUL_VV, MASK_VFMUL_VV)\nDECLARE_INSN(vfmv_f_s, MATCH_VFMV_F_S, MASK_VFMV_F_S)\nDECLARE_INSN(vfmv_s_f, MATCH_VFMV_S_F, MASK_VFMV_S_F)\nDECLARE_INSN(vfmv_v_f, MATCH_VFMV_V_F, MASK_VFMV_V_F)\nDECLARE_INSN(vfncvt_f_f_w, MATCH_VFNCVT_F_F_W, MASK_VFNCVT_F_F_W)\nDECLARE_INSN(vfncvt_f_x_w, MATCH_VFNCVT_F_X_W, MASK_VFNCVT_F_X_W)\nDECLARE_INSN(vfncvt_f_xu_w, MATCH_VFNCVT_F_XU_W, MASK_VFNCVT_F_XU_W)\nDECLARE_INSN(vfncvt_rod_f_f_w, MATCH_VFNCVT_ROD_F_F_W, MASK_VFNCVT_ROD_F_F_W)\nDECLARE_INSN(vfncvt_rtz_x_f_w, MATCH_VFNCVT_RTZ_X_F_W, MASK_VFNCVT_RTZ_X_F_W)\nDECLARE_INSN(vfncvt_rtz_xu_f_w, MATCH_VFNCVT_RTZ_XU_F_W, MASK_VFNCVT_RTZ_XU_F_W)\nDECLARE_INSN(vfncvt_x_f_w, MATCH_VFNCVT_X_F_W, MASK_VFNCVT_X_F_W)\nDECLARE_INSN(vfncvt_xu_f_w, MATCH_VFNCVT_XU_F_W, MASK_VFNCVT_XU_F_W)\nDECLARE_INSN(vfnmacc_vf, MATCH_VFNMACC_VF, MASK_VFNMACC_VF)\nDECLARE_INSN(vfnmacc_vv, MATCH_VFNMACC_VV, MASK_VFNMACC_VV)\nDECLARE_INSN(vfnmadd_vf, MATCH_VFNMADD_VF, MASK_VFNMADD_VF)\nDECLARE_INSN(vfnmadd_vv, MATCH_VFNMADD_VV, MASK_VFNMADD_VV)\nDECLARE_INSN(vfnmsac_vf, MATCH_VFNMSAC_VF, MASK_VFNMSAC_VF)\nDECLARE_INSN(vfnmsac_vv, MATCH_VFNMSAC_VV, MASK_VFNMSAC_VV)\nDECLARE_INSN(vfnmsub_vf, MATCH_VFNMSUB_VF, MASK_VFNMSUB_VF)\nDECLARE_INSN(vfnmsub_vv, MATCH_VFNMSUB_VV, MASK_VFNMSUB_VV)\nDECLARE_INSN(vfrdiv_vf, MATCH_VFRDIV_VF, MASK_VFRDIV_VF)\nDECLARE_INSN(vfrec7_v, MATCH_VFREC7_V, MASK_VFREC7_V)\nDECLARE_INSN(vfredmax_vs, MATCH_VFREDMAX_VS, MASK_VFREDMAX_VS)\nDECLARE_INSN(vfredmin_vs, MATCH_VFREDMIN_VS, MASK_VFREDMIN_VS)\nDECLARE_INSN(vfredosum_vs, MATCH_VFREDOSUM_VS, MASK_VFREDOSUM_VS)\nDECLARE_INSN(vfredusum_vs, MATCH_VFREDUSUM_VS, MASK_VFREDUSUM_VS)\nDECLARE_INSN(vfrsqrt7_v, MATCH_VFRSQRT7_V, MASK_VFRSQRT7_V)\nDECLARE_INSN(vfrsub_vf, MATCH_VFRSUB_VF, MASK_VFRSUB_VF)\nDECLARE_INSN(vfsgnj_vf, MATCH_VFSGNJ_VF, MASK_VFSGNJ_VF)\nDECLARE_INSN(vfsgnj_vv, MATCH_VFSGNJ_VV, MASK_VFSGNJ_VV)\nDECLARE_INSN(vfsgnjn_vf, MATCH_VFSGNJN_VF, MASK_VFSGNJN_VF)\nDECLARE_INSN(vfsgnjn_vv, MATCH_VFSGNJN_VV, MASK_VFSGNJN_VV)\nDECLARE_INSN(vfsgnjx_vf, MATCH_VFSGNJX_VF, MASK_VFSGNJX_VF)\nDECLARE_INSN(vfsgnjx_vv, MATCH_VFSGNJX_VV, MASK_VFSGNJX_VV)\nDECLARE_INSN(vfslide1down_vf, MATCH_VFSLIDE1DOWN_VF, MASK_VFSLIDE1DOWN_VF)\nDECLARE_INSN(vfslide1up_vf, MATCH_VFSLIDE1UP_VF, MASK_VFSLIDE1UP_VF)\nDECLARE_INSN(vfsqrt_v, MATCH_VFSQRT_V, MASK_VFSQRT_V)\nDECLARE_INSN(vfsub_vf, MATCH_VFSUB_VF, MASK_VFSUB_VF)\nDECLARE_INSN(vfsub_vv, MATCH_VFSUB_VV, MASK_VFSUB_VV)\nDECLARE_INSN(vfwadd_vf, MATCH_VFWADD_VF, MASK_VFWADD_VF)\nDECLARE_INSN(vfwadd_vv, MATCH_VFWADD_VV, MASK_VFWADD_VV)\nDECLARE_INSN(vfwadd_wf, MATCH_VFWADD_WF, MASK_VFWADD_WF)\nDECLARE_INSN(vfwadd_wv, MATCH_VFWADD_WV, MASK_VFWADD_WV)\nDECLARE_INSN(vfwcvt_f_f_v, MATCH_VFWCVT_F_F_V, MASK_VFWCVT_F_F_V)\nDECLARE_INSN(vfwcvt_f_x_v, MATCH_VFWCVT_F_X_V, MASK_VFWCVT_F_X_V)\nDECLARE_INSN(vfwcvt_f_xu_v, MATCH_VFWCVT_F_XU_V, MASK_VFWCVT_F_XU_V)\nDECLARE_INSN(vfwcvt_rtz_x_f_v, MATCH_VFWCVT_RTZ_X_F_V, MASK_VFWCVT_RTZ_X_F_V)\nDECLARE_INSN(vfwcvt_rtz_xu_f_v, MATCH_VFWCVT_RTZ_XU_F_V, MASK_VFWCVT_RTZ_XU_F_V)\nDECLARE_INSN(vfwcvt_x_f_v, MATCH_VFWCVT_X_F_V, MASK_VFWCVT_X_F_V)\nDECLARE_INSN(vfwcvt_xu_f_v, MATCH_VFWCVT_XU_F_V, MASK_VFWCVT_XU_F_V)\nDECLARE_INSN(vfwmacc_vf, MATCH_VFWMACC_VF, MASK_VFWMACC_VF)\nDECLARE_INSN(vfwmacc_vv, MATCH_VFWMACC_VV, MASK_VFWMACC_VV)\nDECLARE_INSN(vfwmsac_vf, MATCH_VFWMSAC_VF, MASK_VFWMSAC_VF)\nDECLARE_INSN(vfwmsac_vv, MATCH_VFWMSAC_VV, MASK_VFWMSAC_VV)\nDECLARE_INSN(vfwmul_vf, MATCH_VFWMUL_VF, MASK_VFWMUL_VF)\nDECLARE_INSN(vfwmul_vv, MATCH_VFWMUL_VV, MASK_VFWMUL_VV)\nDECLARE_INSN(vfwnmacc_vf, MATCH_VFWNMACC_VF, MASK_VFWNMACC_VF)\nDECLARE_INSN(vfwnmacc_vv, MATCH_VFWNMACC_VV, MASK_VFWNMACC_VV)\nDECLARE_INSN(vfwnmsac_vf, MATCH_VFWNMSAC_VF, MASK_VFWNMSAC_VF)\nDECLARE_INSN(vfwnmsac_vv, MATCH_VFWNMSAC_VV, MASK_VFWNMSAC_VV)\nDECLARE_INSN(vfwredosum_vs, MATCH_VFWREDOSUM_VS, MASK_VFWREDOSUM_VS)\nDECLARE_INSN(vfwredusum_vs, MATCH_VFWREDUSUM_VS, MASK_VFWREDUSUM_VS)\nDECLARE_INSN(vfwsub_vf, MATCH_VFWSUB_VF, MASK_VFWSUB_VF)\nDECLARE_INSN(vfwsub_vv, MATCH_VFWSUB_VV, MASK_VFWSUB_VV)\nDECLARE_INSN(vfwsub_wf, MATCH_VFWSUB_WF, MASK_VFWSUB_WF)\nDECLARE_INSN(vfwsub_wv, MATCH_VFWSUB_WV, MASK_VFWSUB_WV)\nDECLARE_INSN(vid_v, MATCH_VID_V, MASK_VID_V)\nDECLARE_INSN(viota_m, MATCH_VIOTA_M, MASK_VIOTA_M)\nDECLARE_INSN(vl1re16_v, MATCH_VL1RE16_V, MASK_VL1RE16_V)\nDECLARE_INSN(vl1re32_v, MATCH_VL1RE32_V, MASK_VL1RE32_V)\nDECLARE_INSN(vl1re64_v, MATCH_VL1RE64_V, MASK_VL1RE64_V)\nDECLARE_INSN(vl1re8_v, MATCH_VL1RE8_V, MASK_VL1RE8_V)\nDECLARE_INSN(vl2re16_v, MATCH_VL2RE16_V, MASK_VL2RE16_V)\nDECLARE_INSN(vl2re32_v, MATCH_VL2RE32_V, MASK_VL2RE32_V)\nDECLARE_INSN(vl2re64_v, MATCH_VL2RE64_V, MASK_VL2RE64_V)\nDECLARE_INSN(vl2re8_v, MATCH_VL2RE8_V, MASK_VL2RE8_V)\nDECLARE_INSN(vl4re16_v, MATCH_VL4RE16_V, MASK_VL4RE16_V)\nDECLARE_INSN(vl4re32_v, MATCH_VL4RE32_V, MASK_VL4RE32_V)\nDECLARE_INSN(vl4re64_v, MATCH_VL4RE64_V, MASK_VL4RE64_V)\nDECLARE_INSN(vl4re8_v, MATCH_VL4RE8_V, MASK_VL4RE8_V)\nDECLARE_INSN(vl8re16_v, MATCH_VL8RE16_V, MASK_VL8RE16_V)\nDECLARE_INSN(vl8re32_v, MATCH_VL8RE32_V, MASK_VL8RE32_V)\nDECLARE_INSN(vl8re64_v, MATCH_VL8RE64_V, MASK_VL8RE64_V)\nDECLARE_INSN(vl8re8_v, MATCH_VL8RE8_V, MASK_VL8RE8_V)\nDECLARE_INSN(vle1024_v, MATCH_VLE1024_V, MASK_VLE1024_V)\nDECLARE_INSN(vle1024ff_v, MATCH_VLE1024FF_V, MASK_VLE1024FF_V)\nDECLARE_INSN(vle128_v, MATCH_VLE128_V, MASK_VLE128_V)\nDECLARE_INSN(vle128ff_v, MATCH_VLE128FF_V, MASK_VLE128FF_V)\nDECLARE_INSN(vle16_v, MATCH_VLE16_V, MASK_VLE16_V)\nDECLARE_INSN(vle16ff_v, MATCH_VLE16FF_V, MASK_VLE16FF_V)\nDECLARE_INSN(vle256_v, MATCH_VLE256_V, MASK_VLE256_V)\nDECLARE_INSN(vle256ff_v, MATCH_VLE256FF_V, MASK_VLE256FF_V)\nDECLARE_INSN(vle32_v, MATCH_VLE32_V, MASK_VLE32_V)\nDECLARE_INSN(vle32ff_v, MATCH_VLE32FF_V, MASK_VLE32FF_V)\nDECLARE_INSN(vle512_v, MATCH_VLE512_V, MASK_VLE512_V)\nDECLARE_INSN(vle512ff_v, MATCH_VLE512FF_V, MASK_VLE512FF_V)\nDECLARE_INSN(vle64_v, MATCH_VLE64_V, MASK_VLE64_V)\nDECLARE_INSN(vle64ff_v, MATCH_VLE64FF_V, MASK_VLE64FF_V)\nDECLARE_INSN(vle8_v, MATCH_VLE8_V, MASK_VLE8_V)\nDECLARE_INSN(vle8ff_v, MATCH_VLE8FF_V, MASK_VLE8FF_V)\nDECLARE_INSN(vlm_v, MATCH_VLM_V, MASK_VLM_V)\nDECLARE_INSN(vloxei1024_v, MATCH_VLOXEI1024_V, MASK_VLOXEI1024_V)\nDECLARE_INSN(vloxei128_v, MATCH_VLOXEI128_V, MASK_VLOXEI128_V)\nDECLARE_INSN(vloxei16_v, MATCH_VLOXEI16_V, MASK_VLOXEI16_V)\nDECLARE_INSN(vloxei256_v, MATCH_VLOXEI256_V, MASK_VLOXEI256_V)\nDECLARE_INSN(vloxei32_v, MATCH_VLOXEI32_V, MASK_VLOXEI32_V)\nDECLARE_INSN(vloxei512_v, MATCH_VLOXEI512_V, MASK_VLOXEI512_V)\nDECLARE_INSN(vloxei64_v, MATCH_VLOXEI64_V, MASK_VLOXEI64_V)\nDECLARE_INSN(vloxei8_v, MATCH_VLOXEI8_V, MASK_VLOXEI8_V)\nDECLARE_INSN(vlse1024_v, MATCH_VLSE1024_V, MASK_VLSE1024_V)\nDECLARE_INSN(vlse128_v, MATCH_VLSE128_V, MASK_VLSE128_V)\nDECLARE_INSN(vlse16_v, MATCH_VLSE16_V, MASK_VLSE16_V)\nDECLARE_INSN(vlse256_v, MATCH_VLSE256_V, MASK_VLSE256_V)\nDECLARE_INSN(vlse32_v, MATCH_VLSE32_V, MASK_VLSE32_V)\nDECLARE_INSN(vlse512_v, MATCH_VLSE512_V, MASK_VLSE512_V)\nDECLARE_INSN(vlse64_v, MATCH_VLSE64_V, MASK_VLSE64_V)\nDECLARE_INSN(vlse8_v, MATCH_VLSE8_V, MASK_VLSE8_V)\nDECLARE_INSN(vluxei1024_v, MATCH_VLUXEI1024_V, MASK_VLUXEI1024_V)\nDECLARE_INSN(vluxei128_v, MATCH_VLUXEI128_V, MASK_VLUXEI128_V)\nDECLARE_INSN(vluxei16_v, MATCH_VLUXEI16_V, MASK_VLUXEI16_V)\nDECLARE_INSN(vluxei256_v, MATCH_VLUXEI256_V, MASK_VLUXEI256_V)\nDECLARE_INSN(vluxei32_v, MATCH_VLUXEI32_V, MASK_VLUXEI32_V)\nDECLARE_INSN(vluxei512_v, MATCH_VLUXEI512_V, MASK_VLUXEI512_V)\nDECLARE_INSN(vluxei64_v, MATCH_VLUXEI64_V, MASK_VLUXEI64_V)\nDECLARE_INSN(vluxei8_v, MATCH_VLUXEI8_V, MASK_VLUXEI8_V)\nDECLARE_INSN(vmacc_vv, MATCH_VMACC_VV, MASK_VMACC_VV)\nDECLARE_INSN(vmacc_vx, MATCH_VMACC_VX, MASK_VMACC_VX)\nDECLARE_INSN(vmadc_vi, MATCH_VMADC_VI, MASK_VMADC_VI)\nDECLARE_INSN(vmadc_vim, MATCH_VMADC_VIM, MASK_VMADC_VIM)\nDECLARE_INSN(vmadc_vv, MATCH_VMADC_VV, MASK_VMADC_VV)\nDECLARE_INSN(vmadc_vvm, MATCH_VMADC_VVM, MASK_VMADC_VVM)\nDECLARE_INSN(vmadc_vx, MATCH_VMADC_VX, MASK_VMADC_VX)\nDECLARE_INSN(vmadc_vxm, MATCH_VMADC_VXM, MASK_VMADC_VXM)\nDECLARE_INSN(vmadd_vv, MATCH_VMADD_VV, MASK_VMADD_VV)\nDECLARE_INSN(vmadd_vx, MATCH_VMADD_VX, MASK_VMADD_VX)\nDECLARE_INSN(vmand_mm, MATCH_VMAND_MM, MASK_VMAND_MM)\nDECLARE_INSN(vmandn_mm, MATCH_VMANDN_MM, MASK_VMANDN_MM)\nDECLARE_INSN(vmax_vv, MATCH_VMAX_VV, MASK_VMAX_VV)\nDECLARE_INSN(vmax_vx, MATCH_VMAX_VX, MASK_VMAX_VX)\nDECLARE_INSN(vmaxu_vv, MATCH_VMAXU_VV, MASK_VMAXU_VV)\nDECLARE_INSN(vmaxu_vx, MATCH_VMAXU_VX, MASK_VMAXU_VX)\nDECLARE_INSN(vmerge_vim, MATCH_VMERGE_VIM, MASK_VMERGE_VIM)\nDECLARE_INSN(vmerge_vvm, MATCH_VMERGE_VVM, MASK_VMERGE_VVM)\nDECLARE_INSN(vmerge_vxm, MATCH_VMERGE_VXM, MASK_VMERGE_VXM)\nDECLARE_INSN(vmfeq_vf, MATCH_VMFEQ_VF, MASK_VMFEQ_VF)\nDECLARE_INSN(vmfeq_vv, MATCH_VMFEQ_VV, MASK_VMFEQ_VV)\nDECLARE_INSN(vmfge_vf, MATCH_VMFGE_VF, MASK_VMFGE_VF)\nDECLARE_INSN(vmfgt_vf, MATCH_VMFGT_VF, MASK_VMFGT_VF)\nDECLARE_INSN(vmfle_vf, MATCH_VMFLE_VF, MASK_VMFLE_VF)\nDECLARE_INSN(vmfle_vv, MATCH_VMFLE_VV, MASK_VMFLE_VV)\nDECLARE_INSN(vmflt_vf, MATCH_VMFLT_VF, MASK_VMFLT_VF)\nDECLARE_INSN(vmflt_vv, MATCH_VMFLT_VV, MASK_VMFLT_VV)\nDECLARE_INSN(vmfne_vf, MATCH_VMFNE_VF, MASK_VMFNE_VF)\nDECLARE_INSN(vmfne_vv, MATCH_VMFNE_VV, MASK_VMFNE_VV)\nDECLARE_INSN(vmin_vv, MATCH_VMIN_VV, MASK_VMIN_VV)\nDECLARE_INSN(vmin_vx, MATCH_VMIN_VX, MASK_VMIN_VX)\nDECLARE_INSN(vminu_vv, MATCH_VMINU_VV, MASK_VMINU_VV)\nDECLARE_INSN(vminu_vx, MATCH_VMINU_VX, MASK_VMINU_VX)\nDECLARE_INSN(vmnand_mm, MATCH_VMNAND_MM, MASK_VMNAND_MM)\nDECLARE_INSN(vmnor_mm, MATCH_VMNOR_MM, MASK_VMNOR_MM)\nDECLARE_INSN(vmor_mm, MATCH_VMOR_MM, MASK_VMOR_MM)\nDECLARE_INSN(vmorn_mm, MATCH_VMORN_MM, MASK_VMORN_MM)\nDECLARE_INSN(vmsbc_vv, MATCH_VMSBC_VV, MASK_VMSBC_VV)\nDECLARE_INSN(vmsbc_vvm, MATCH_VMSBC_VVM, MASK_VMSBC_VVM)\nDECLARE_INSN(vmsbc_vx, MATCH_VMSBC_VX, MASK_VMSBC_VX)\nDECLARE_INSN(vmsbc_vxm, MATCH_VMSBC_VXM, MASK_VMSBC_VXM)\nDECLARE_INSN(vmsbf_m, MATCH_VMSBF_M, MASK_VMSBF_M)\nDECLARE_INSN(vmseq_vi, MATCH_VMSEQ_VI, MASK_VMSEQ_VI)\nDECLARE_INSN(vmseq_vv, MATCH_VMSEQ_VV, MASK_VMSEQ_VV)\nDECLARE_INSN(vmseq_vx, MATCH_VMSEQ_VX, MASK_VMSEQ_VX)\nDECLARE_INSN(vmsgt_vi, MATCH_VMSGT_VI, MASK_VMSGT_VI)\nDECLARE_INSN(vmsgt_vx, MATCH_VMSGT_VX, MASK_VMSGT_VX)\nDECLARE_INSN(vmsgtu_vi, MATCH_VMSGTU_VI, MASK_VMSGTU_VI)\nDECLARE_INSN(vmsgtu_vx, MATCH_VMSGTU_VX, MASK_VMSGTU_VX)\nDECLARE_INSN(vmsif_m, MATCH_VMSIF_M, MASK_VMSIF_M)\nDECLARE_INSN(vmsle_vi, MATCH_VMSLE_VI, MASK_VMSLE_VI)\nDECLARE_INSN(vmsle_vv, MATCH_VMSLE_VV, MASK_VMSLE_VV)\nDECLARE_INSN(vmsle_vx, MATCH_VMSLE_VX, MASK_VMSLE_VX)\nDECLARE_INSN(vmsleu_vi, MATCH_VMSLEU_VI, MASK_VMSLEU_VI)\nDECLARE_INSN(vmsleu_vv, MATCH_VMSLEU_VV, MASK_VMSLEU_VV)\nDECLARE_INSN(vmsleu_vx, MATCH_VMSLEU_VX, MASK_VMSLEU_VX)\nDECLARE_INSN(vmslt_vv, MATCH_VMSLT_VV, MASK_VMSLT_VV)\nDECLARE_INSN(vmslt_vx, MATCH_VMSLT_VX, MASK_VMSLT_VX)\nDECLARE_INSN(vmsltu_vv, MATCH_VMSLTU_VV, MASK_VMSLTU_VV)\nDECLARE_INSN(vmsltu_vx, MATCH_VMSLTU_VX, MASK_VMSLTU_VX)\nDECLARE_INSN(vmsne_vi, MATCH_VMSNE_VI, MASK_VMSNE_VI)\nDECLARE_INSN(vmsne_vv, MATCH_VMSNE_VV, MASK_VMSNE_VV)\nDECLARE_INSN(vmsne_vx, MATCH_VMSNE_VX, MASK_VMSNE_VX)\nDECLARE_INSN(vmsof_m, MATCH_VMSOF_M, MASK_VMSOF_M)\nDECLARE_INSN(vmul_vv, MATCH_VMUL_VV, MASK_VMUL_VV)\nDECLARE_INSN(vmul_vx, MATCH_VMUL_VX, MASK_VMUL_VX)\nDECLARE_INSN(vmulh_vv, MATCH_VMULH_VV, MASK_VMULH_VV)\nDECLARE_INSN(vmulh_vx, MATCH_VMULH_VX, MASK_VMULH_VX)\nDECLARE_INSN(vmulhsu_vv, MATCH_VMULHSU_VV, MASK_VMULHSU_VV)\nDECLARE_INSN(vmulhsu_vx, MATCH_VMULHSU_VX, MASK_VMULHSU_VX)\nDECLARE_INSN(vmulhu_vv, MATCH_VMULHU_VV, MASK_VMULHU_VV)\nDECLARE_INSN(vmulhu_vx, MATCH_VMULHU_VX, MASK_VMULHU_VX)\nDECLARE_INSN(vmv1r_v, MATCH_VMV1R_V, MASK_VMV1R_V)\nDECLARE_INSN(vmv2r_v, MATCH_VMV2R_V, MASK_VMV2R_V)\nDECLARE_INSN(vmv4r_v, MATCH_VMV4R_V, MASK_VMV4R_V)\nDECLARE_INSN(vmv8r_v, MATCH_VMV8R_V, MASK_VMV8R_V)\nDECLARE_INSN(vmv_s_x, MATCH_VMV_S_X, MASK_VMV_S_X)\nDECLARE_INSN(vmv_v_i, MATCH_VMV_V_I, MASK_VMV_V_I)\nDECLARE_INSN(vmv_v_v, MATCH_VMV_V_V, MASK_VMV_V_V)\nDECLARE_INSN(vmv_v_x, MATCH_VMV_V_X, MASK_VMV_V_X)\nDECLARE_INSN(vmv_x_s, MATCH_VMV_X_S, MASK_VMV_X_S)\nDECLARE_INSN(vmxnor_mm, MATCH_VMXNOR_MM, MASK_VMXNOR_MM)\nDECLARE_INSN(vmxor_mm, MATCH_VMXOR_MM, MASK_VMXOR_MM)\nDECLARE_INSN(vnclip_wi, MATCH_VNCLIP_WI, MASK_VNCLIP_WI)\nDECLARE_INSN(vnclip_wv, MATCH_VNCLIP_WV, MASK_VNCLIP_WV)\nDECLARE_INSN(vnclip_wx, MATCH_VNCLIP_WX, MASK_VNCLIP_WX)\nDECLARE_INSN(vnclipu_wi, MATCH_VNCLIPU_WI, MASK_VNCLIPU_WI)\nDECLARE_INSN(vnclipu_wv, MATCH_VNCLIPU_WV, MASK_VNCLIPU_WV)\nDECLARE_INSN(vnclipu_wx, MATCH_VNCLIPU_WX, MASK_VNCLIPU_WX)\nDECLARE_INSN(vnmsac_vv, MATCH_VNMSAC_VV, MASK_VNMSAC_VV)\nDECLARE_INSN(vnmsac_vx, MATCH_VNMSAC_VX, MASK_VNMSAC_VX)\nDECLARE_INSN(vnmsub_vv, MATCH_VNMSUB_VV, MASK_VNMSUB_VV)\nDECLARE_INSN(vnmsub_vx, MATCH_VNMSUB_VX, MASK_VNMSUB_VX)\nDECLARE_INSN(vnsra_wi, MATCH_VNSRA_WI, MASK_VNSRA_WI)\nDECLARE_INSN(vnsra_wv, MATCH_VNSRA_WV, MASK_VNSRA_WV)\nDECLARE_INSN(vnsra_wx, MATCH_VNSRA_WX, MASK_VNSRA_WX)\nDECLARE_INSN(vnsrl_wi, MATCH_VNSRL_WI, MASK_VNSRL_WI)\nDECLARE_INSN(vnsrl_wv, MATCH_VNSRL_WV, MASK_VNSRL_WV)\nDECLARE_INSN(vnsrl_wx, MATCH_VNSRL_WX, MASK_VNSRL_WX)\nDECLARE_INSN(vor_vi, MATCH_VOR_VI, MASK_VOR_VI)\nDECLARE_INSN(vor_vv, MATCH_VOR_VV, MASK_VOR_VV)\nDECLARE_INSN(vor_vx, MATCH_VOR_VX, MASK_VOR_VX)\nDECLARE_INSN(vredand_vs, MATCH_VREDAND_VS, MASK_VREDAND_VS)\nDECLARE_INSN(vredmax_vs, MATCH_VREDMAX_VS, MASK_VREDMAX_VS)\nDECLARE_INSN(vredmaxu_vs, MATCH_VREDMAXU_VS, MASK_VREDMAXU_VS)\nDECLARE_INSN(vredmin_vs, MATCH_VREDMIN_VS, MASK_VREDMIN_VS)\nDECLARE_INSN(vredminu_vs, MATCH_VREDMINU_VS, MASK_VREDMINU_VS)\nDECLARE_INSN(vredor_vs, MATCH_VREDOR_VS, MASK_VREDOR_VS)\nDECLARE_INSN(vredsum_vs, MATCH_VREDSUM_VS, MASK_VREDSUM_VS)\nDECLARE_INSN(vredxor_vs, MATCH_VREDXOR_VS, MASK_VREDXOR_VS)\nDECLARE_INSN(vrem_vv, MATCH_VREM_VV, MASK_VREM_VV)\nDECLARE_INSN(vrem_vx, MATCH_VREM_VX, MASK_VREM_VX)\nDECLARE_INSN(vremu_vv, MATCH_VREMU_VV, MASK_VREMU_VV)\nDECLARE_INSN(vremu_vx, MATCH_VREMU_VX, MASK_VREMU_VX)\nDECLARE_INSN(vrgather_vi, MATCH_VRGATHER_VI, MASK_VRGATHER_VI)\nDECLARE_INSN(vrgather_vv, MATCH_VRGATHER_VV, MASK_VRGATHER_VV)\nDECLARE_INSN(vrgather_vx, MATCH_VRGATHER_VX, MASK_VRGATHER_VX)\nDECLARE_INSN(vrgatherei16_vv, MATCH_VRGATHEREI16_VV, MASK_VRGATHEREI16_VV)\nDECLARE_INSN(vrsub_vi, MATCH_VRSUB_VI, MASK_VRSUB_VI)\nDECLARE_INSN(vrsub_vx, MATCH_VRSUB_VX, MASK_VRSUB_VX)\nDECLARE_INSN(vs1r_v, MATCH_VS1R_V, MASK_VS1R_V)\nDECLARE_INSN(vs2r_v, MATCH_VS2R_V, MASK_VS2R_V)\nDECLARE_INSN(vs4r_v, MATCH_VS4R_V, MASK_VS4R_V)\nDECLARE_INSN(vs8r_v, MATCH_VS8R_V, MASK_VS8R_V)\nDECLARE_INSN(vsadd_vi, MATCH_VSADD_VI, MASK_VSADD_VI)\nDECLARE_INSN(vsadd_vv, MATCH_VSADD_VV, MASK_VSADD_VV)\nDECLARE_INSN(vsadd_vx, MATCH_VSADD_VX, MASK_VSADD_VX)\nDECLARE_INSN(vsaddu_vi, MATCH_VSADDU_VI, MASK_VSADDU_VI)\nDECLARE_INSN(vsaddu_vv, MATCH_VSADDU_VV, MASK_VSADDU_VV)\nDECLARE_INSN(vsaddu_vx, MATCH_VSADDU_VX, MASK_VSADDU_VX)\nDECLARE_INSN(vsbc_vvm, MATCH_VSBC_VVM, MASK_VSBC_VVM)\nDECLARE_INSN(vsbc_vxm, MATCH_VSBC_VXM, MASK_VSBC_VXM)\nDECLARE_INSN(vse1024_v, MATCH_VSE1024_V, MASK_VSE1024_V)\nDECLARE_INSN(vse128_v, MATCH_VSE128_V, MASK_VSE128_V)\nDECLARE_INSN(vse16_v, MATCH_VSE16_V, MASK_VSE16_V)\nDECLARE_INSN(vse256_v, MATCH_VSE256_V, MASK_VSE256_V)\nDECLARE_INSN(vse32_v, MATCH_VSE32_V, MASK_VSE32_V)\nDECLARE_INSN(vse512_v, MATCH_VSE512_V, MASK_VSE512_V)\nDECLARE_INSN(vse64_v, MATCH_VSE64_V, MASK_VSE64_V)\nDECLARE_INSN(vse8_v, MATCH_VSE8_V, MASK_VSE8_V)\nDECLARE_INSN(vsetivli, MATCH_VSETIVLI, MASK_VSETIVLI)\nDECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL)\nDECLARE_INSN(vsetvli, MATCH_VSETVLI, MASK_VSETVLI)\nDECLARE_INSN(vsext_vf2, MATCH_VSEXT_VF2, MASK_VSEXT_VF2)\nDECLARE_INSN(vsext_vf4, MATCH_VSEXT_VF4, MASK_VSEXT_VF4)\nDECLARE_INSN(vsext_vf8, MATCH_VSEXT_VF8, MASK_VSEXT_VF8)\nDECLARE_INSN(vslide1down_vx, MATCH_VSLIDE1DOWN_VX, MASK_VSLIDE1DOWN_VX)\nDECLARE_INSN(vslide1up_vx, MATCH_VSLIDE1UP_VX, MASK_VSLIDE1UP_VX)\nDECLARE_INSN(vslidedown_vi, MATCH_VSLIDEDOWN_VI, MASK_VSLIDEDOWN_VI)\nDECLARE_INSN(vslidedown_vx, MATCH_VSLIDEDOWN_VX, MASK_VSLIDEDOWN_VX)\nDECLARE_INSN(vslideup_vi, MATCH_VSLIDEUP_VI, MASK_VSLIDEUP_VI)\nDECLARE_INSN(vslideup_vx, MATCH_VSLIDEUP_VX, MASK_VSLIDEUP_VX)\nDECLARE_INSN(vsll_vi, MATCH_VSLL_VI, MASK_VSLL_VI)\nDECLARE_INSN(vsll_vv, MATCH_VSLL_VV, MASK_VSLL_VV)\nDECLARE_INSN(vsll_vx, MATCH_VSLL_VX, MASK_VSLL_VX)\nDECLARE_INSN(vsm_v, MATCH_VSM_V, MASK_VSM_V)\nDECLARE_INSN(vsmul_vv, MATCH_VSMUL_VV, MASK_VSMUL_VV)\nDECLARE_INSN(vsmul_vx, MATCH_VSMUL_VX, MASK_VSMUL_VX)\nDECLARE_INSN(vsoxei1024_v, MATCH_VSOXEI1024_V, MASK_VSOXEI1024_V)\nDECLARE_INSN(vsoxei128_v, MATCH_VSOXEI128_V, MASK_VSOXEI128_V)\nDECLARE_INSN(vsoxei16_v, MATCH_VSOXEI16_V, MASK_VSOXEI16_V)\nDECLARE_INSN(vsoxei256_v, MATCH_VSOXEI256_V, MASK_VSOXEI256_V)\nDECLARE_INSN(vsoxei32_v, MATCH_VSOXEI32_V, MASK_VSOXEI32_V)\nDECLARE_INSN(vsoxei512_v, MATCH_VSOXEI512_V, MASK_VSOXEI512_V)\nDECLARE_INSN(vsoxei64_v, MATCH_VSOXEI64_V, MASK_VSOXEI64_V)\nDECLARE_INSN(vsoxei8_v, MATCH_VSOXEI8_V, MASK_VSOXEI8_V)\nDECLARE_INSN(vsra_vi, MATCH_VSRA_VI, MASK_VSRA_VI)\nDECLARE_INSN(vsra_vv, MATCH_VSRA_VV, MASK_VSRA_VV)\nDECLARE_INSN(vsra_vx, MATCH_VSRA_VX, MASK_VSRA_VX)\nDECLARE_INSN(vsrl_vi, MATCH_VSRL_VI, MASK_VSRL_VI)\nDECLARE_INSN(vsrl_vv, MATCH_VSRL_VV, MASK_VSRL_VV)\nDECLARE_INSN(vsrl_vx, MATCH_VSRL_VX, MASK_VSRL_VX)\nDECLARE_INSN(vsse1024_v, MATCH_VSSE1024_V, MASK_VSSE1024_V)\nDECLARE_INSN(vsse128_v, MATCH_VSSE128_V, MASK_VSSE128_V)\nDECLARE_INSN(vsse16_v, MATCH_VSSE16_V, MASK_VSSE16_V)\nDECLARE_INSN(vsse256_v, MATCH_VSSE256_V, MASK_VSSE256_V)\nDECLARE_INSN(vsse32_v, MATCH_VSSE32_V, MASK_VSSE32_V)\nDECLARE_INSN(vsse512_v, MATCH_VSSE512_V, MASK_VSSE512_V)\nDECLARE_INSN(vsse64_v, MATCH_VSSE64_V, MASK_VSSE64_V)\nDECLARE_INSN(vsse8_v, MATCH_VSSE8_V, MASK_VSSE8_V)\nDECLARE_INSN(vssra_vi, MATCH_VSSRA_VI, MASK_VSSRA_VI)\nDECLARE_INSN(vssra_vv, MATCH_VSSRA_VV, MASK_VSSRA_VV)\nDECLARE_INSN(vssra_vx, MATCH_VSSRA_VX, MASK_VSSRA_VX)\nDECLARE_INSN(vssrl_vi, MATCH_VSSRL_VI, MASK_VSSRL_VI)\nDECLARE_INSN(vssrl_vv, MATCH_VSSRL_VV, MASK_VSSRL_VV)\nDECLARE_INSN(vssrl_vx, MATCH_VSSRL_VX, MASK_VSSRL_VX)\nDECLARE_INSN(vssub_vv, MATCH_VSSUB_VV, MASK_VSSUB_VV)\nDECLARE_INSN(vssub_vx, MATCH_VSSUB_VX, MASK_VSSUB_VX)\nDECLARE_INSN(vssubu_vv, MATCH_VSSUBU_VV, MASK_VSSUBU_VV)\nDECLARE_INSN(vssubu_vx, MATCH_VSSUBU_VX, MASK_VSSUBU_VX)\nDECLARE_INSN(vsub_vv, MATCH_VSUB_VV, MASK_VSUB_VV)\nDECLARE_INSN(vsub_vx, MATCH_VSUB_VX, MASK_VSUB_VX)\nDECLARE_INSN(vsuxei1024_v, MATCH_VSUXEI1024_V, MASK_VSUXEI1024_V)\nDECLARE_INSN(vsuxei128_v, MATCH_VSUXEI128_V, MASK_VSUXEI128_V)\nDECLARE_INSN(vsuxei16_v, MATCH_VSUXEI16_V, MASK_VSUXEI16_V)\nDECLARE_INSN(vsuxei256_v, MATCH_VSUXEI256_V, MASK_VSUXEI256_V)\nDECLARE_INSN(vsuxei32_v, MATCH_VSUXEI32_V, MASK_VSUXEI32_V)\nDECLARE_INSN(vsuxei512_v, MATCH_VSUXEI512_V, MASK_VSUXEI512_V)\nDECLARE_INSN(vsuxei64_v, MATCH_VSUXEI64_V, MASK_VSUXEI64_V)\nDECLARE_INSN(vsuxei8_v, MATCH_VSUXEI8_V, MASK_VSUXEI8_V)\nDECLARE_INSN(vwadd_vv, MATCH_VWADD_VV, MASK_VWADD_VV)\nDECLARE_INSN(vwadd_vx, MATCH_VWADD_VX, MASK_VWADD_VX)\nDECLARE_INSN(vwadd_wv, MATCH_VWADD_WV, MASK_VWADD_WV)\nDECLARE_INSN(vwadd_wx, MATCH_VWADD_WX, MASK_VWADD_WX)\nDECLARE_INSN(vwaddu_vv, MATCH_VWADDU_VV, MASK_VWADDU_VV)\nDECLARE_INSN(vwaddu_vx, MATCH_VWADDU_VX, MASK_VWADDU_VX)\nDECLARE_INSN(vwaddu_wv, MATCH_VWADDU_WV, MASK_VWADDU_WV)\nDECLARE_INSN(vwaddu_wx, MATCH_VWADDU_WX, MASK_VWADDU_WX)\nDECLARE_INSN(vwmacc_vv, MATCH_VWMACC_VV, MASK_VWMACC_VV)\nDECLARE_INSN(vwmacc_vx, MATCH_VWMACC_VX, MASK_VWMACC_VX)\nDECLARE_INSN(vwmaccsu_vv, MATCH_VWMACCSU_VV, MASK_VWMACCSU_VV)\nDECLARE_INSN(vwmaccsu_vx, MATCH_VWMACCSU_VX, MASK_VWMACCSU_VX)\nDECLARE_INSN(vwmaccu_vv, MATCH_VWMACCU_VV, MASK_VWMACCU_VV)\nDECLARE_INSN(vwmaccu_vx, MATCH_VWMACCU_VX, MASK_VWMACCU_VX)\nDECLARE_INSN(vwmaccus_vx, MATCH_VWMACCUS_VX, MASK_VWMACCUS_VX)\nDECLARE_INSN(vwmul_vv, MATCH_VWMUL_VV, MASK_VWMUL_VV)\nDECLARE_INSN(vwmul_vx, MATCH_VWMUL_VX, MASK_VWMUL_VX)\nDECLARE_INSN(vwmulsu_vv, MATCH_VWMULSU_VV, MASK_VWMULSU_VV)\nDECLARE_INSN(vwmulsu_vx, MATCH_VWMULSU_VX, MASK_VWMULSU_VX)\nDECLARE_INSN(vwmulu_vv, MATCH_VWMULU_VV, MASK_VWMULU_VV)\nDECLARE_INSN(vwmulu_vx, MATCH_VWMULU_VX, MASK_VWMULU_VX)\nDECLARE_INSN(vwredsum_vs, MATCH_VWREDSUM_VS, MASK_VWREDSUM_VS)\nDECLARE_INSN(vwredsumu_vs, MATCH_VWREDSUMU_VS, MASK_VWREDSUMU_VS)\nDECLARE_INSN(vwsub_vv, MATCH_VWSUB_VV, MASK_VWSUB_VV)\nDECLARE_INSN(vwsub_vx, MATCH_VWSUB_VX, MASK_VWSUB_VX)\nDECLARE_INSN(vwsub_wv, MATCH_VWSUB_WV, MASK_VWSUB_WV)\nDECLARE_INSN(vwsub_wx, MATCH_VWSUB_WX, MASK_VWSUB_WX)\nDECLARE_INSN(vwsubu_vv, MATCH_VWSUBU_VV, MASK_VWSUBU_VV)\nDECLARE_INSN(vwsubu_vx, MATCH_VWSUBU_VX, MASK_VWSUBU_VX)\nDECLARE_INSN(vwsubu_wv, MATCH_VWSUBU_WV, MASK_VWSUBU_WV)\nDECLARE_INSN(vwsubu_wx, MATCH_VWSUBU_WX, MASK_VWSUBU_WX)\nDECLARE_INSN(vxor_vi, MATCH_VXOR_VI, MASK_VXOR_VI)\nDECLARE_INSN(vxor_vv, MATCH_VXOR_VV, MASK_VXOR_VV)\nDECLARE_INSN(vxor_vx, MATCH_VXOR_VX, MASK_VXOR_VX)\nDECLARE_INSN(vzext_vf2, MATCH_VZEXT_VF2, MASK_VZEXT_VF2)\nDECLARE_INSN(vzext_vf4, MATCH_VZEXT_VF4, MASK_VZEXT_VF4)\nDECLARE_INSN(vzext_vf8, MATCH_VZEXT_VF8, MASK_VZEXT_VF8)\nDECLARE_INSN(wext, MATCH_WEXT, MASK_WEXT)\nDECLARE_INSN(wexti, MATCH_WEXTI, MASK_WEXTI)\nDECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)\nDECLARE_INSN(wrs_nto, MATCH_WRS_NTO, MASK_WRS_NTO)\nDECLARE_INSN(wrs_sto, MATCH_WRS_STO, MASK_WRS_STO)\nDECLARE_INSN(xnor, MATCH_XNOR, MASK_XNOR)\nDECLARE_INSN(xor, MATCH_XOR, MASK_XOR)\nDECLARE_INSN(xori, MATCH_XORI, MASK_XORI)\nDECLARE_INSN(xperm16, MATCH_XPERM16, MASK_XPERM16)\nDECLARE_INSN(xperm32, MATCH_XPERM32, MASK_XPERM32)\nDECLARE_INSN(xperm4, MATCH_XPERM4, MASK_XPERM4)\nDECLARE_INSN(xperm8, MATCH_XPERM8, MASK_XPERM8)\nDECLARE_INSN(zunpkd810, MATCH_ZUNPKD810, MASK_ZUNPKD810)\nDECLARE_INSN(zunpkd820, MATCH_ZUNPKD820, MASK_ZUNPKD820)\nDECLARE_INSN(zunpkd830, MATCH_ZUNPKD830, MASK_ZUNPKD830)\nDECLARE_INSN(zunpkd831, MATCH_ZUNPKD831, MASK_ZUNPKD831)\nDECLARE_INSN(zunpkd832, MATCH_ZUNPKD832, MASK_ZUNPKD832)\n#endif\n#ifdef DECLARE_CSR\nDECLARE_CSR(fflags, CSR_FFLAGS)\nDECLARE_CSR(frm, CSR_FRM)\nDECLARE_CSR(fcsr, CSR_FCSR)\nDECLARE_CSR(vstart, CSR_VSTART)\nDECLARE_CSR(vxsat, CSR_VXSAT)\nDECLARE_CSR(vxrm, CSR_VXRM)\nDECLARE_CSR(vcsr, CSR_VCSR)\nDECLARE_CSR(seed, CSR_SEED)\nDECLARE_CSR(cycle, CSR_CYCLE)\nDECLARE_CSR(time, CSR_TIME)\nDECLARE_CSR(instret, CSR_INSTRET)\nDECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3)\nDECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4)\nDECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5)\nDECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6)\nDECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7)\nDECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8)\nDECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9)\nDECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10)\nDECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11)\nDECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12)\nDECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13)\nDECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14)\nDECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15)\nDECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16)\nDECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17)\nDECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18)\nDECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19)\nDECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20)\nDECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21)\nDECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22)\nDECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23)\nDECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24)\nDECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25)\nDECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26)\nDECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27)\nDECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28)\nDECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29)\nDECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30)\nDECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)\nDECLARE_CSR(vl, CSR_VL)\nDECLARE_CSR(vtype, CSR_VTYPE)\nDECLARE_CSR(vlenb, CSR_VLENB)\nDECLARE_CSR(sstatus, CSR_SSTATUS)\nDECLARE_CSR(sedeleg, CSR_SEDELEG)\nDECLARE_CSR(sideleg, CSR_SIDELEG)\nDECLARE_CSR(sie, CSR_SIE)\nDECLARE_CSR(stvec, CSR_STVEC)\nDECLARE_CSR(scounteren, CSR_SCOUNTEREN)\nDECLARE_CSR(senvcfg, CSR_SENVCFG)\nDECLARE_CSR(sstateen0, CSR_SSTATEEN0)\nDECLARE_CSR(sstateen1, CSR_SSTATEEN1)\nDECLARE_CSR(sstateen2, CSR_SSTATEEN2)\nDECLARE_CSR(sstateen3, CSR_SSTATEEN3)\nDECLARE_CSR(sscratch, CSR_SSCRATCH)\nDECLARE_CSR(sepc, CSR_SEPC)\nDECLARE_CSR(scause, CSR_SCAUSE)\nDECLARE_CSR(stval, CSR_STVAL)\nDECLARE_CSR(sip, CSR_SIP)\nDECLARE_CSR(stimecmp, CSR_STIMECMP)\nDECLARE_CSR(satp, CSR_SATP)\nDECLARE_CSR(scontext, CSR_SCONTEXT)\nDECLARE_CSR(vsstatus, CSR_VSSTATUS)\nDECLARE_CSR(vsie, CSR_VSIE)\nDECLARE_CSR(vstvec, CSR_VSTVEC)\nDECLARE_CSR(vsscratch, CSR_VSSCRATCH)\nDECLARE_CSR(vsepc, CSR_VSEPC)\nDECLARE_CSR(vscause, CSR_VSCAUSE)\nDECLARE_CSR(vstval, CSR_VSTVAL)\nDECLARE_CSR(vsip, CSR_VSIP)\nDECLARE_CSR(vstimecmp, CSR_VSTIMECMP)\nDECLARE_CSR(vsatp, CSR_VSATP)\nDECLARE_CSR(hstatus, CSR_HSTATUS)\nDECLARE_CSR(hedeleg, CSR_HEDELEG)\nDECLARE_CSR(hideleg, CSR_HIDELEG)\nDECLARE_CSR(hie, CSR_HIE)\nDECLARE_CSR(htimedelta, CSR_HTIMEDELTA)\nDECLARE_CSR(hcounteren, CSR_HCOUNTEREN)\nDECLARE_CSR(hgeie, CSR_HGEIE)\nDECLARE_CSR(henvcfg, CSR_HENVCFG)\nDECLARE_CSR(hstateen0, CSR_HSTATEEN0)\nDECLARE_CSR(hstateen1, CSR_HSTATEEN1)\nDECLARE_CSR(hstateen2, CSR_HSTATEEN2)\nDECLARE_CSR(hstateen3, CSR_HSTATEEN3)\nDECLARE_CSR(htval, CSR_HTVAL)\nDECLARE_CSR(hip, CSR_HIP)\nDECLARE_CSR(hvip, CSR_HVIP)\nDECLARE_CSR(htinst, CSR_HTINST)\nDECLARE_CSR(hgatp, CSR_HGATP)\nDECLARE_CSR(hcontext, CSR_HCONTEXT)\nDECLARE_CSR(hgeip, CSR_HGEIP)\nDECLARE_CSR(scountovf, CSR_SCOUNTOVF)\nDECLARE_CSR(utvt, CSR_UTVT)\nDECLARE_CSR(unxti, CSR_UNXTI)\nDECLARE_CSR(uintstatus, CSR_UINTSTATUS)\nDECLARE_CSR(uscratchcsw, CSR_USCRATCHCSW)\nDECLARE_CSR(uscratchcswl, CSR_USCRATCHCSWL)\nDECLARE_CSR(stvt, CSR_STVT)\nDECLARE_CSR(snxti, CSR_SNXTI)\nDECLARE_CSR(sintstatus, CSR_SINTSTATUS)\nDECLARE_CSR(sscratchcsw, CSR_SSCRATCHCSW)\nDECLARE_CSR(sscratchcswl, CSR_SSCRATCHCSWL)\nDECLARE_CSR(mtvt, CSR_MTVT)\nDECLARE_CSR(mnxti, CSR_MNXTI)\nDECLARE_CSR(mintstatus, CSR_MINTSTATUS)\nDECLARE_CSR(mscratchcsw, CSR_MSCRATCHCSW)\nDECLARE_CSR(mscratchcswl, CSR_MSCRATCHCSWL)\nDECLARE_CSR(mstatus, CSR_MSTATUS)\nDECLARE_CSR(misa, CSR_MISA)\nDECLARE_CSR(medeleg, CSR_MEDELEG)\nDECLARE_CSR(mideleg, CSR_MIDELEG)\nDECLARE_CSR(mie, CSR_MIE)\nDECLARE_CSR(mtvec, CSR_MTVEC)\nDECLARE_CSR(mcounteren, CSR_MCOUNTEREN)\nDECLARE_CSR(menvcfg, CSR_MENVCFG)\nDECLARE_CSR(mstateen0, CSR_MSTATEEN0)\nDECLARE_CSR(mstateen1, CSR_MSTATEEN1)\nDECLARE_CSR(mstateen2, CSR_MSTATEEN2)\nDECLARE_CSR(mstateen3, CSR_MSTATEEN3)\nDECLARE_CSR(mcountinhibit, CSR_MCOUNTINHIBIT)\nDECLARE_CSR(mscratch, CSR_MSCRATCH)\nDECLARE_CSR(mepc, CSR_MEPC)\nDECLARE_CSR(mcause, CSR_MCAUSE)\nDECLARE_CSR(mtval, CSR_MTVAL)\nDECLARE_CSR(mip, CSR_MIP)\nDECLARE_CSR(mtinst, CSR_MTINST)\nDECLARE_CSR(mtval2, CSR_MTVAL2)\nDECLARE_CSR(pmpcfg0, CSR_PMPCFG0)\nDECLARE_CSR(pmpcfg1, CSR_PMPCFG1)\nDECLARE_CSR(pmpcfg2, CSR_PMPCFG2)\nDECLARE_CSR(pmpcfg3, CSR_PMPCFG3)\nDECLARE_CSR(pmpcfg4, CSR_PMPCFG4)\nDECLARE_CSR(pmpcfg5, CSR_PMPCFG5)\nDECLARE_CSR(pmpcfg6, CSR_PMPCFG6)\nDECLARE_CSR(pmpcfg7, CSR_PMPCFG7)\nDECLARE_CSR(pmpcfg8, CSR_PMPCFG8)\nDECLARE_CSR(pmpcfg9, CSR_PMPCFG9)\nDECLARE_CSR(pmpcfg10, CSR_PMPCFG10)\nDECLARE_CSR(pmpcfg11, CSR_PMPCFG11)\nDECLARE_CSR(pmpcfg12, CSR_PMPCFG12)\nDECLARE_CSR(pmpcfg13, CSR_PMPCFG13)\nDECLARE_CSR(pmpcfg14, CSR_PMPCFG14)\nDECLARE_CSR(pmpcfg15, CSR_PMPCFG15)\nDECLARE_CSR(pmpaddr0, CSR_PMPADDR0)\nDECLARE_CSR(pmpaddr1, CSR_PMPADDR1)\nDECLARE_CSR(pmpaddr2, CSR_PMPADDR2)\nDECLARE_CSR(pmpaddr3, CSR_PMPADDR3)\nDECLARE_CSR(pmpaddr4, CSR_PMPADDR4)\nDECLARE_CSR(pmpaddr5, CSR_PMPADDR5)\nDECLARE_CSR(pmpaddr6, CSR_PMPADDR6)\nDECLARE_CSR(pmpaddr7, CSR_PMPADDR7)\nDECLARE_CSR(pmpaddr8, CSR_PMPADDR8)\nDECLARE_CSR(pmpaddr9, CSR_PMPADDR9)\nDECLARE_CSR(pmpaddr10, CSR_PMPADDR10)\nDECLARE_CSR(pmpaddr11, CSR_PMPADDR11)\nDECLARE_CSR(pmpaddr12, CSR_PMPADDR12)\nDECLARE_CSR(pmpaddr13, CSR_PMPADDR13)\nDECLARE_CSR(pmpaddr14, CSR_PMPADDR14)\nDECLARE_CSR(pmpaddr15, CSR_PMPADDR15)\nDECLARE_CSR(pmpaddr16, CSR_PMPADDR16)\nDECLARE_CSR(pmpaddr17, CSR_PMPADDR17)\nDECLARE_CSR(pmpaddr18, CSR_PMPADDR18)\nDECLARE_CSR(pmpaddr19, CSR_PMPADDR19)\nDECLARE_CSR(pmpaddr20, CSR_PMPADDR20)\nDECLARE_CSR(pmpaddr21, CSR_PMPADDR21)\nDECLARE_CSR(pmpaddr22, CSR_PMPADDR22)\nDECLARE_CSR(pmpaddr23, CSR_PMPADDR23)\nDECLARE_CSR(pmpaddr24, CSR_PMPADDR24)\nDECLARE_CSR(pmpaddr25, CSR_PMPADDR25)\nDECLARE_CSR(pmpaddr26, CSR_PMPADDR26)\nDECLARE_CSR(pmpaddr27, CSR_PMPADDR27)\nDECLARE_CSR(pmpaddr28, CSR_PMPADDR28)\nDECLARE_CSR(pmpaddr29, CSR_PMPADDR29)\nDECLARE_CSR(pmpaddr30, CSR_PMPADDR30)\nDECLARE_CSR(pmpaddr31, CSR_PMPADDR31)\nDECLARE_CSR(pmpaddr32, CSR_PMPADDR32)\nDECLARE_CSR(pmpaddr33, CSR_PMPADDR33)\nDECLARE_CSR(pmpaddr34, CSR_PMPADDR34)\nDECLARE_CSR(pmpaddr35, CSR_PMPADDR35)\nDECLARE_CSR(pmpaddr36, CSR_PMPADDR36)\nDECLARE_CSR(pmpaddr37, CSR_PMPADDR37)\nDECLARE_CSR(pmpaddr38, CSR_PMPADDR38)\nDECLARE_CSR(pmpaddr39, CSR_PMPADDR39)\nDECLARE_CSR(pmpaddr40, CSR_PMPADDR40)\nDECLARE_CSR(pmpaddr41, CSR_PMPADDR41)\nDECLARE_CSR(pmpaddr42, CSR_PMPADDR42)\nDECLARE_CSR(pmpaddr43, CSR_PMPADDR43)\nDECLARE_CSR(pmpaddr44, CSR_PMPADDR44)\nDECLARE_CSR(pmpaddr45, CSR_PMPADDR45)\nDECLARE_CSR(pmpaddr46, CSR_PMPADDR46)\nDECLARE_CSR(pmpaddr47, CSR_PMPADDR47)\nDECLARE_CSR(pmpaddr48, CSR_PMPADDR48)\nDECLARE_CSR(pmpaddr49, CSR_PMPADDR49)\nDECLARE_CSR(pmpaddr50, CSR_PMPADDR50)\nDECLARE_CSR(pmpaddr51, CSR_PMPADDR51)\nDECLARE_CSR(pmpaddr52, CSR_PMPADDR52)\nDECLARE_CSR(pmpaddr53, CSR_PMPADDR53)\nDECLARE_CSR(pmpaddr54, CSR_PMPADDR54)\nDECLARE_CSR(pmpaddr55, CSR_PMPADDR55)\nDECLARE_CSR(pmpaddr56, CSR_PMPADDR56)\nDECLARE_CSR(pmpaddr57, CSR_PMPADDR57)\nDECLARE_CSR(pmpaddr58, CSR_PMPADDR58)\nDECLARE_CSR(pmpaddr59, CSR_PMPADDR59)\nDECLARE_CSR(pmpaddr60, CSR_PMPADDR60)\nDECLARE_CSR(pmpaddr61, CSR_PMPADDR61)\nDECLARE_CSR(pmpaddr62, CSR_PMPADDR62)\nDECLARE_CSR(pmpaddr63, CSR_PMPADDR63)\nDECLARE_CSR(mseccfg, CSR_MSECCFG)\nDECLARE_CSR(tselect, CSR_TSELECT)\nDECLARE_CSR(tdata1, CSR_TDATA1)\nDECLARE_CSR(tdata2, CSR_TDATA2)\nDECLARE_CSR(tdata3, CSR_TDATA3)\nDECLARE_CSR(tinfo, CSR_TINFO)\nDECLARE_CSR(tcontrol, CSR_TCONTROL)\nDECLARE_CSR(mcontext, CSR_MCONTEXT)\nDECLARE_CSR(mscontext, CSR_MSCONTEXT)\nDECLARE_CSR(dcsr, CSR_DCSR)\nDECLARE_CSR(dpc, CSR_DPC)\nDECLARE_CSR(dscratch0, CSR_DSCRATCH0)\nDECLARE_CSR(dscratch1, CSR_DSCRATCH1)\nDECLARE_CSR(mcycle, CSR_MCYCLE)\nDECLARE_CSR(minstret, CSR_MINSTRET)\nDECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3)\nDECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4)\nDECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5)\nDECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6)\nDECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7)\nDECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8)\nDECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9)\nDECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10)\nDECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11)\nDECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12)\nDECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13)\nDECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14)\nDECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15)\nDECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16)\nDECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17)\nDECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18)\nDECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19)\nDECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20)\nDECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21)\nDECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22)\nDECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23)\nDECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24)\nDECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25)\nDECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26)\nDECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27)\nDECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)\nDECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)\nDECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)\nDECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)\nDECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)\nDECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)\nDECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)\nDECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6)\nDECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7)\nDECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8)\nDECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9)\nDECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10)\nDECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11)\nDECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12)\nDECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13)\nDECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14)\nDECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15)\nDECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16)\nDECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17)\nDECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18)\nDECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19)\nDECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20)\nDECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21)\nDECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22)\nDECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23)\nDECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24)\nDECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25)\nDECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26)\nDECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27)\nDECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28)\nDECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29)\nDECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30)\nDECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31)\nDECLARE_CSR(mvendorid, CSR_MVENDORID)\nDECLARE_CSR(marchid, CSR_MARCHID)\nDECLARE_CSR(mimpid, CSR_MIMPID)\nDECLARE_CSR(mhartid, CSR_MHARTID)\nDECLARE_CSR(mconfigptr, CSR_MCONFIGPTR)\nDECLARE_CSR(stimecmph, CSR_STIMECMPH)\nDECLARE_CSR(vstimecmph, CSR_VSTIMECMPH)\nDECLARE_CSR(htimedeltah, CSR_HTIMEDELTAH)\nDECLARE_CSR(henvcfgh, CSR_HENVCFGH)\nDECLARE_CSR(hstateen0h, CSR_HSTATEEN0H)\nDECLARE_CSR(hstateen1h, CSR_HSTATEEN1H)\nDECLARE_CSR(hstateen2h, CSR_HSTATEEN2H)\nDECLARE_CSR(hstateen3h, CSR_HSTATEEN3H)\nDECLARE_CSR(cycleh, CSR_CYCLEH)\nDECLARE_CSR(timeh, CSR_TIMEH)\nDECLARE_CSR(instreth, CSR_INSTRETH)\nDECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H)\nDECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H)\nDECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H)\nDECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H)\nDECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H)\nDECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H)\nDECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H)\nDECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H)\nDECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H)\nDECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H)\nDECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H)\nDECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H)\nDECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H)\nDECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H)\nDECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H)\nDECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H)\nDECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H)\nDECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H)\nDECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H)\nDECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H)\nDECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H)\nDECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H)\nDECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H)\nDECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H)\nDECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H)\nDECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H)\nDECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H)\nDECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H)\nDECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H)\nDECLARE_CSR(mstatush, CSR_MSTATUSH)\nDECLARE_CSR(menvcfgh, CSR_MENVCFGH)\nDECLARE_CSR(mstateen0h, CSR_MSTATEEN0H)\nDECLARE_CSR(mstateen1h, CSR_MSTATEEN1H)\nDECLARE_CSR(mstateen2h, CSR_MSTATEEN2H)\nDECLARE_CSR(mstateen3h, CSR_MSTATEEN3H)\nDECLARE_CSR(mhpmevent3h, CSR_MHPMEVENT3H)\nDECLARE_CSR(mhpmevent4h, CSR_MHPMEVENT4H)\nDECLARE_CSR(mhpmevent5h, CSR_MHPMEVENT5H)\nDECLARE_CSR(mhpmevent6h, CSR_MHPMEVENT6H)\nDECLARE_CSR(mhpmevent7h, CSR_MHPMEVENT7H)\nDECLARE_CSR(mhpmevent8h, CSR_MHPMEVENT8H)\nDECLARE_CSR(mhpmevent9h, CSR_MHPMEVENT9H)\nDECLARE_CSR(mhpmevent10h, CSR_MHPMEVENT10H)\nDECLARE_CSR(mhpmevent11h, CSR_MHPMEVENT11H)\nDECLARE_CSR(mhpmevent12h, CSR_MHPMEVENT12H)\nDECLARE_CSR(mhpmevent13h, CSR_MHPMEVENT13H)\nDECLARE_CSR(mhpmevent14h, CSR_MHPMEVENT14H)\nDECLARE_CSR(mhpmevent15h, CSR_MHPMEVENT15H)\nDECLARE_CSR(mhpmevent16h, CSR_MHPMEVENT16H)\nDECLARE_CSR(mhpmevent17h, CSR_MHPMEVENT17H)\nDECLARE_CSR(mhpmevent18h, CSR_MHPMEVENT18H)\nDECLARE_CSR(mhpmevent19h, CSR_MHPMEVENT19H)\nDECLARE_CSR(mhpmevent20h, CSR_MHPMEVENT20H)\nDECLARE_CSR(mhpmevent21h, CSR_MHPMEVENT21H)\nDECLARE_CSR(mhpmevent22h, CSR_MHPMEVENT22H)\nDECLARE_CSR(mhpmevent23h, CSR_MHPMEVENT23H)\nDECLARE_CSR(mhpmevent24h, CSR_MHPMEVENT24H)\nDECLARE_CSR(mhpmevent25h, CSR_MHPMEVENT25H)\nDECLARE_CSR(mhpmevent26h, CSR_MHPMEVENT26H)\nDECLARE_CSR(mhpmevent27h, CSR_MHPMEVENT27H)\nDECLARE_CSR(mhpmevent28h, CSR_MHPMEVENT28H)\nDECLARE_CSR(mhpmevent29h, CSR_MHPMEVENT29H)\nDECLARE_CSR(mhpmevent30h, CSR_MHPMEVENT30H)\nDECLARE_CSR(mhpmevent31h, CSR_MHPMEVENT31H)\nDECLARE_CSR(mseccfgh, CSR_MSECCFGH)\nDECLARE_CSR(mcycleh, CSR_MCYCLEH)\nDECLARE_CSR(minstreth, CSR_MINSTRETH)\nDECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H)\nDECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H)\nDECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H)\nDECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H)\nDECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H)\nDECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H)\nDECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H)\nDECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H)\nDECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H)\nDECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H)\nDECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H)\nDECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H)\nDECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H)\nDECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H)\nDECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H)\nDECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H)\nDECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H)\nDECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H)\nDECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H)\nDECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H)\nDECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H)\nDECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H)\nDECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H)\nDECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H)\nDECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H)\nDECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H)\nDECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H)\nDECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H)\nDECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)\n#endif\n#ifdef DECLARE_CAUSE\nDECLARE_CAUSE(\"misaligned fetch\", CAUSE_MISALIGNED_FETCH)\nDECLARE_CAUSE(\"fetch access\", CAUSE_FETCH_ACCESS)\nDECLARE_CAUSE(\"illegal instruction\", CAUSE_ILLEGAL_INSTRUCTION)\nDECLARE_CAUSE(\"breakpoint\", CAUSE_BREAKPOINT)\nDECLARE_CAUSE(\"misaligned load\", CAUSE_MISALIGNED_LOAD)\nDECLARE_CAUSE(\"load access\", CAUSE_LOAD_ACCESS)\nDECLARE_CAUSE(\"misaligned store\", CAUSE_MISALIGNED_STORE)\nDECLARE_CAUSE(\"store access\", CAUSE_STORE_ACCESS)\nDECLARE_CAUSE(\"user_ecall\", CAUSE_USER_ECALL)\nDECLARE_CAUSE(\"supervisor_ecall\", CAUSE_SUPERVISOR_ECALL)\nDECLARE_CAUSE(\"virtual_supervisor_ecall\", CAUSE_VIRTUAL_SUPERVISOR_ECALL)\nDECLARE_CAUSE(\"machine_ecall\", CAUSE_MACHINE_ECALL)\nDECLARE_CAUSE(\"fetch page fault\", CAUSE_FETCH_PAGE_FAULT)\nDECLARE_CAUSE(\"load page fault\", CAUSE_LOAD_PAGE_FAULT)\nDECLARE_CAUSE(\"store page fault\", CAUSE_STORE_PAGE_FAULT)\nDECLARE_CAUSE(\"fetch guest page fault\", CAUSE_FETCH_GUEST_PAGE_FAULT)\nDECLARE_CAUSE(\"load guest page fault\", CAUSE_LOAD_GUEST_PAGE_FAULT)\nDECLARE_CAUSE(\"virtual instruction\", CAUSE_VIRTUAL_INSTRUCTION)\nDECLARE_CAUSE(\"store guest page fault\", CAUSE_STORE_GUEST_PAGE_FAULT)\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/gdb_regs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef TARGET__RISCV__GDB_REGS_H\n#define TARGET__RISCV__GDB_REGS_H\n\n/* gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in\n * its source tree. We must interpret the numbers the same here. */\nenum gdb_regno {\n\tGDB_REGNO_ZERO = 0,        /* Read-only register, always 0.  */\n\tGDB_REGNO_RA = 1,          /* Return Address.  */\n\tGDB_REGNO_SP = 2,          /* Stack Pointer.  */\n\tGDB_REGNO_GP = 3,          /* Global Pointer.  */\n\tGDB_REGNO_TP = 4,          /* Thread Pointer.  */\n\tGDB_REGNO_T0,\n\tGDB_REGNO_T1,\n\tGDB_REGNO_T2,\n\tGDB_REGNO_S0 = 8,\n\tGDB_REGNO_FP = 8,          /* Frame Pointer.  */\n\tGDB_REGNO_S1,\n\tGDB_REGNO_A0 = 10,         /* First argument.  */\n\tGDB_REGNO_A1 = 11,         /* Second argument.  */\n\tGDB_REGNO_A2,\n\tGDB_REGNO_A3,\n\tGDB_REGNO_A4,\n\tGDB_REGNO_A5,\n\tGDB_REGNO_XPR15 = GDB_REGNO_A5,\n\tGDB_REGNO_A6,\n\tGDB_REGNO_A7,\n\tGDB_REGNO_S2,\n\tGDB_REGNO_S3,\n\tGDB_REGNO_S4,\n\tGDB_REGNO_S5,\n\tGDB_REGNO_S6,\n\tGDB_REGNO_S7,\n\tGDB_REGNO_S8,\n\tGDB_REGNO_S9,\n\tGDB_REGNO_S10,\n\tGDB_REGNO_S11,\n\tGDB_REGNO_T3,\n\tGDB_REGNO_T4,\n\tGDB_REGNO_T5,\n\tGDB_REGNO_T6,\n\tGDB_REGNO_XPR31 = GDB_REGNO_T6,\n\n\tGDB_REGNO_PC = 32,\n\tGDB_REGNO_FPR0 = 33,\n\tGDB_REGNO_FT0 = GDB_REGNO_FPR0,\n\tGDB_REGNO_FT1,\n\tGDB_REGNO_FT2,\n\tGDB_REGNO_FT3,\n\tGDB_REGNO_FT4,\n\tGDB_REGNO_FT5,\n\tGDB_REGNO_FT6,\n\tGDB_REGNO_FT7,\n\tGDB_REGNO_FS0,\n\tGDB_REGNO_FS1,\n\tGDB_REGNO_FA0,\n\tGDB_REGNO_FA1,\n\tGDB_REGNO_FA2,\n\tGDB_REGNO_FA3,\n\tGDB_REGNO_FA4,\n\tGDB_REGNO_FA5,\n\tGDB_REGNO_FA6,\n\tGDB_REGNO_FA7,\n\tGDB_REGNO_FS2,\n\tGDB_REGNO_FS3,\n\tGDB_REGNO_FS4,\n\tGDB_REGNO_FS5,\n\tGDB_REGNO_FS6,\n\tGDB_REGNO_FS7,\n\tGDB_REGNO_FS8,\n\tGDB_REGNO_FS9,\n\tGDB_REGNO_FS10,\n\tGDB_REGNO_FS11,\n\tGDB_REGNO_FT8,\n\tGDB_REGNO_FT9,\n\tGDB_REGNO_FT10,\n\tGDB_REGNO_FT11,\n\tGDB_REGNO_FPR31 = GDB_REGNO_FT11,\n\tGDB_REGNO_CSR0 = 65,\n\tGDB_REGNO_VSTART = CSR_VSTART + GDB_REGNO_CSR0,\n\tGDB_REGNO_VXSAT = CSR_VXSAT + GDB_REGNO_CSR0,\n\tGDB_REGNO_VXRM = CSR_VXRM + GDB_REGNO_CSR0,\n\tGDB_REGNO_VLENB = CSR_VLENB + GDB_REGNO_CSR0,\n\tGDB_REGNO_VL = CSR_VL + GDB_REGNO_CSR0,\n\tGDB_REGNO_VTYPE = CSR_VTYPE + GDB_REGNO_CSR0,\n\tGDB_REGNO_TSELECT = CSR_TSELECT + GDB_REGNO_CSR0,\n\tGDB_REGNO_TDATA1 = CSR_TDATA1 + GDB_REGNO_CSR0,\n\tGDB_REGNO_TDATA2 = CSR_TDATA2 + GDB_REGNO_CSR0,\n\tGDB_REGNO_MISA = CSR_MISA + GDB_REGNO_CSR0,\n\tGDB_REGNO_DPC = CSR_DPC + GDB_REGNO_CSR0,\n\tGDB_REGNO_DCSR = CSR_DCSR + GDB_REGNO_CSR0,\n\tGDB_REGNO_DSCRATCH0 = CSR_DSCRATCH0 + GDB_REGNO_CSR0,\n\tGDB_REGNO_MSTATUS = CSR_MSTATUS + GDB_REGNO_CSR0,\n\tGDB_REGNO_MEPC = CSR_MEPC + GDB_REGNO_CSR0,\n\tGDB_REGNO_MCAUSE = CSR_MCAUSE + GDB_REGNO_CSR0,\n\tGDB_REGNO_SATP = CSR_SATP + GDB_REGNO_CSR0,\n\tGDB_REGNO_CSR4095 = GDB_REGNO_CSR0 + 4095,\n\tGDB_REGNO_PRIV = 4161,\n\t/* It's still undecided what register numbers GDB will actually use for\n\t * these. See\n\t * https://groups.google.com/a/groups.riscv.org/d/msg/sw-dev/7lQYiTUN9Ms/gTxGhzaYBQAJ\n\t */\n\tGDB_REGNO_V0, GDB_REGNO_V1, GDB_REGNO_V2, GDB_REGNO_V3,\n\tGDB_REGNO_V4, GDB_REGNO_V5, GDB_REGNO_V6, GDB_REGNO_V7,\n\tGDB_REGNO_V8, GDB_REGNO_V9, GDB_REGNO_V10, GDB_REGNO_V11,\n\tGDB_REGNO_V12, GDB_REGNO_V13, GDB_REGNO_V14, GDB_REGNO_V15,\n\tGDB_REGNO_V16, GDB_REGNO_V17, GDB_REGNO_V18, GDB_REGNO_V19,\n\tGDB_REGNO_V20, GDB_REGNO_V21, GDB_REGNO_V22, GDB_REGNO_V23,\n\tGDB_REGNO_V24, GDB_REGNO_V25, GDB_REGNO_V26, GDB_REGNO_V27,\n\tGDB_REGNO_V28, GDB_REGNO_V29, GDB_REGNO_V30, GDB_REGNO_V31,\n\tGDB_REGNO_COUNT\n};\n\nconst char *gdb_regno_name(enum gdb_regno regno);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/opcodes.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#include \"encoding.h\"\n\n#define ZERO\t0\n#define T0      5\n#define S0      8\n#define S1      9\n\nstatic uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo)\n{\n\treturn (value >> lo) & ((1 << (hi+1-lo)) - 1);\n}\n\nstatic uint32_t bit(uint32_t value, unsigned int b)\n{\n\treturn (value >> b) & 1;\n}\n\nstatic uint32_t inst_rd(uint32_t r) __attribute__ ((unused));\nstatic uint32_t inst_rd(uint32_t r)\n{\n\treturn bits(r, 4, 0) << 7;\n}\n\nstatic uint32_t inst_rs1(uint32_t r) __attribute__ ((unused));\nstatic uint32_t inst_rs1(uint32_t r)\n{\n\treturn bits(r, 4, 0) << 15;\n}\n\nstatic uint32_t inst_rs2(uint32_t r) __attribute__ ((unused));\nstatic uint32_t inst_rs2(uint32_t r)\n{\n\treturn bits(r, 4, 0) << 20;\n}\n\nstatic uint32_t imm_i(uint32_t imm) __attribute__ ((unused));\nstatic uint32_t imm_i(uint32_t imm)\n{\n\treturn bits(imm, 11, 0) << 20;\n}\n\nstatic uint32_t imm_s(uint32_t imm) __attribute__ ((unused));\nstatic uint32_t imm_s(uint32_t imm)\n{\n\treturn (bits(imm, 4, 0) << 7) | (bits(imm, 11, 5) << 25);\n}\n\nstatic uint32_t imm_b(uint32_t imm) __attribute__ ((unused));\nstatic uint32_t imm_b(uint32_t imm)\n{\n\treturn (bit(imm, 11) << 7) | (bits(imm, 4, 1) << 8) | (bits(imm, 10, 5) << 25) | (bit(imm, 12) << 31);\n}\n\nstatic uint32_t imm_u(uint32_t imm) __attribute__ ((unused));\nstatic uint32_t imm_u(uint32_t imm)\n{\n\treturn bits(imm, 31, 12) << 12;\n}\n\nstatic uint32_t imm_j(uint32_t imm) __attribute__ ((unused));\nstatic uint32_t imm_j(uint32_t imm)\n{\n\treturn (bits(imm, 19, 12) << 12) | (bit(imm, 11) << 20) | (bits(imm, 10, 1) << 21) | (bit(imm, 20) << 31);\n}\n\nstatic uint32_t jal(unsigned int rd, uint32_t imm) __attribute__ ((unused));\nstatic uint32_t jal(unsigned int rd, uint32_t imm)\n{\n\treturn imm_j(imm) | inst_rd(rd) | MATCH_JAL;\n}\n\nstatic uint32_t csrsi(unsigned int csr, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t csrsi(unsigned int csr, uint16_t imm)\n{\n\treturn imm_i(csr) | inst_rs1(imm) | MATCH_CSRRSI;\n}\n\nstatic uint32_t sw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t sw(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SW;\n}\n\nstatic uint32_t sd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t sd(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SD;\n}\n\nstatic uint32_t sh(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t sh(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SH;\n}\n\nstatic uint32_t sb(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t sb(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_SB;\n}\n\nstatic uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t ld(unsigned int rd, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LD;\n}\n\nstatic uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t lw(unsigned int rd, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LW;\n}\n\nstatic uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LH;\n}\n\nstatic uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(rd) | MATCH_LB;\n}\n\nstatic uint32_t csrw(unsigned int source, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrw(unsigned int source, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rs1(source) | MATCH_CSRRW;\n}\n\nstatic uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm)\n{\n\treturn imm_i(imm) | inst_rs1(src) | inst_rd(dest) | MATCH_ADDI;\n}\n\nstatic uint32_t csrr(unsigned int rd, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrr(unsigned int rd, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rd(rd) | MATCH_CSRRS;\n}\n\nstatic uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rs1(rs) | inst_rd(rd) | MATCH_CSRRS;\n}\n\nstatic uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rs1(rs) | inst_rd(rd) | MATCH_CSRRW;\n}\n\nstatic uint32_t csrrci(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrrci(unsigned int rd, unsigned int zimm, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rs1(zimm) | inst_rd(rd) | MATCH_CSRRCI;\n}\n\nstatic uint32_t csrrsi(unsigned int rd, unsigned int zimm, unsigned int csr) __attribute__ ((unused));\nstatic uint32_t csrrsi(unsigned int rd, unsigned int zimm, unsigned int csr)\n{\n\treturn imm_i(csr) | inst_rs1(zimm) | inst_rd(rd) | MATCH_CSRRSI;\n}\n\nstatic uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSW;\n}\n\nstatic uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset)\n{\n\treturn imm_s(offset) | inst_rs2(src) | inst_rs1(base) | MATCH_FSD;\n}\n\nstatic uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t flw(unsigned int dest, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLW;\n}\n\nstatic uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset)\n{\n\treturn imm_i(offset) | inst_rs1(base) | inst_rd(dest) | MATCH_FLD;\n}\n\nstatic uint32_t fmv_x_w(unsigned dest, unsigned src) __attribute__ ((unused));\nstatic uint32_t fmv_x_w(unsigned dest, unsigned src)\n{\n\treturn inst_rs1(src) | inst_rd(dest) | MATCH_FMV_X_W;\n}\n\nstatic uint32_t fmv_x_d(unsigned dest, unsigned src) __attribute__ ((unused));\nstatic uint32_t fmv_x_d(unsigned dest, unsigned src)\n{\n\treturn inst_rs1(src) | inst_rd(dest) | MATCH_FMV_X_D;\n}\n\nstatic uint32_t fmv_w_x(unsigned dest, unsigned src) __attribute__ ((unused));\nstatic uint32_t fmv_w_x(unsigned dest, unsigned src)\n{\n\treturn inst_rs1(src) | inst_rd(dest) | MATCH_FMV_W_X;\n}\n\nstatic uint32_t fmv_d_x(unsigned dest, unsigned src) __attribute__ ((unused));\nstatic uint32_t fmv_d_x(unsigned dest, unsigned src)\n{\n\treturn inst_rs1(src) | inst_rd(dest) | MATCH_FMV_D_X;\n}\n\nstatic uint32_t ebreak(void) __attribute__ ((unused));\nstatic uint32_t ebreak(void)\n{\n\treturn MATCH_EBREAK;\n}\nstatic uint32_t ebreak_c(void) __attribute__ ((unused));\nstatic uint32_t ebreak_c(void)\n{\n\treturn MATCH_C_EBREAK;\n}\n\nstatic uint32_t wfi(void) __attribute__ ((unused));\nstatic uint32_t wfi(void) { return MATCH_WFI; }\n\nstatic uint32_t fence_i(void) __attribute__ ((unused));\nstatic uint32_t fence_i(void)\n{\n\treturn MATCH_FENCE_I;\n}\n\nstatic uint32_t lui(unsigned int dest, uint32_t imm) __attribute__ ((unused));\nstatic uint32_t lui(unsigned int dest, uint32_t imm)\n{\n\treturn imm_u(imm) | inst_rd(dest) | MATCH_LUI;\n}\n\n/*\nstatic uint32_t csrci(unsigned int csr, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t csrci(unsigned int csr, uint16_t imm)\n{\n  return (csr << 20) |\n    (bits(imm, 4, 0) << 15) |\n    MATCH_CSRRCI;\n}\n\nstatic uint32_t li(unsigned int dest, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t li(unsigned int dest, uint16_t imm)\n{\n\treturn addi(dest, 0, imm);\n}\n\nstatic uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset) __attribute__ ((unused));\nstatic uint32_t fsd(unsigned int src, unsigned int base, uint16_t offset)\n{\n  return (bits(offset, 11, 5) << 25) |\n    (bits(src, 4, 0) << 20) |\n    (base << 15) |\n    (bits(offset, 4, 0) << 7) |\n    MATCH_FSD;\n}\n\nstatic uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t ori(unsigned int dest, unsigned int src, uint16_t imm)\n{\n  return (bits(imm, 11, 0) << 20) |\n    (src << 15) |\n    (dest << 7) |\n    MATCH_ORI;\n}\n\nstatic uint32_t nop(void) __attribute__ ((unused));\nstatic uint32_t nop(void)\n{\n  return addi(0, 0, 0);\n}\n*/\n\nstatic uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm) __attribute__ ((unused));\nstatic uint32_t xori(unsigned int dest, unsigned int src, uint16_t imm)\n{\n\treturn imm_i(imm) | inst_rs1(src) | inst_rd(dest) | MATCH_XORI;\n}\n\nstatic uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt) __attribute__ ((unused));\nstatic uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt)\n{\n\treturn inst_rs2(shamt) | inst_rs1(src) | inst_rd(dest) | MATCH_SRLI;\n}\n\nstatic uint32_t fence(void) __attribute__((unused));\nstatic uint32_t fence(void)\n{\n\treturn MATCH_FENCE;\n}\n\nstatic uint32_t auipc(unsigned int dest) __attribute__((unused));\nstatic uint32_t auipc(unsigned int dest)\n{\n\treturn MATCH_AUIPC | inst_rd(dest);\n}\n\nstatic uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t imm) __attribute__((unused));\nstatic uint32_t vsetvli(unsigned int dest, unsigned int src, uint16_t imm)\n{\n\treturn (bits(imm, 10, 0) << 20) | inst_rs1(src) | inst_rd(dest) | MATCH_VSETVLI;\n}\n\nstatic uint32_t vmv_x_s(unsigned int rd, unsigned int vs2) __attribute__((unused));\nstatic uint32_t vmv_x_s(unsigned int rd, unsigned int vs2)\n{\n\treturn inst_rs2(vs2) | inst_rd(rd) | MATCH_VMV_X_S;\n}\n\nstatic uint32_t vmv_s_x(unsigned int vd, unsigned int vs2) __attribute__((unused));\nstatic uint32_t vmv_s_x(unsigned int vd, unsigned int rs1)\n{\n\treturn inst_rs1(rs1) | inst_rd(vd) | MATCH_VMV_S_X;\n}\n\nstatic uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,\n\t\tunsigned int rs1, unsigned int vm) __attribute__((unused));\nstatic uint32_t vslide1down_vx(unsigned int vd, unsigned int vs2,\n\t\tunsigned int rs1, unsigned int vm)\n{\n\treturn ((vm & 1) << 25) | inst_rs2(vs2) | inst_rs1(rs1) | inst_rd(vd) | MATCH_VSLIDE1DOWN_VX;\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/program.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target/target.h\"\n#include \"target/register.h\"\n#include \"riscv.h\"\n#include \"program.h\"\n#include \"helper/log.h\"\n\n#include \"asm.h\"\n#include \"encoding.h\"\n\n/* Program interface. */\nint riscv_program_init(struct riscv_program *p, struct target *target)\n{\n\tmemset(p, 0, sizeof(*p));\n\tp->target = target;\n\tp->instruction_count = 0;\n\tp->target_xlen = riscv_xlen(target);\n\tfor (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)\n\t\tp->writes_xreg[i] = 0;\n\n\tfor (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)\n\t\tp->debug_buffer[i] = -1;\n\n\treturn ERROR_OK;\n}\n\nint riscv_program_write(struct riscv_program *program)\n{\n\tfor (unsigned i = 0; i < program->instruction_count; ++i) {\n\t\tLOG_DEBUG(\"debug_buffer[%02x] = DASM(0x%08x)\", i, program->debug_buffer[i]);\n\t\tif (riscv_write_debug_buffer(program->target, i,\n\t\t\t\t\tprogram->debug_buffer[i]) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\n/** Add ebreak and execute the program. */\nint riscv_program_exec(struct riscv_program *p, struct target *t)\n{\n\tkeep_alive();\n\n\triscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];\n\tfor (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {\n\t\tif (p->writes_xreg[i]) {\n\t\t\tLOG_DEBUG(\"Saving register %d as used by program\", (int)i);\n\t\t\tint result = riscv_get_register(t, &saved_registers[i], i);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t}\n\t}\n\n\tif (riscv_program_ebreak(p) != ERROR_OK) {\n\t\tLOG_ERROR(\"Unable to write ebreak\");\n\t\tfor (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)\n\t\t\tLOG_ERROR(\"ram[%02x]: DASM(0x%08\" PRIx32 \") [0x%08\" PRIx32 \"]\",\n\t\t\t\t\t(int)i, p->debug_buffer[i], p->debug_buffer[i]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (riscv_program_write(p) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (riscv_execute_debug_buffer(t) != ERROR_OK) {\n\t\tLOG_DEBUG(\"Unable to execute program %p\", p);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)\n\t\tif (i >= riscv_debug_buffer_size(p->target))\n\t\t\tp->debug_buffer[i] = riscv_read_debug_buffer(t, i);\n\n\tfor (size_t i = GDB_REGNO_ZERO; i <= GDB_REGNO_XPR31; ++i)\n\t\tif (p->writes_xreg[i])\n\t\t\triscv_set_register(t, i, saved_registers[i]);\n\n\treturn ERROR_OK;\n}\n\nint riscv_program_sdr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, sd(d, b, offset));\n}\n\nint riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, sw(d, b, offset));\n}\n\nint riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, sh(d, b, offset));\n}\n\nint riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, sb(d, b, offset));\n}\n\nint riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, ld(d, b, offset));\n}\n\nint riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, lw(d, b, offset));\n}\n\nint riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, lh(d, b, offset));\n}\n\nint riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)\n{\n\treturn riscv_program_insert(p, lb(d, b, offset));\n}\n\nint riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)\n{\n\tassert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);\n\treturn riscv_program_insert(p, csrrsi(d, z, csr - GDB_REGNO_CSR0));\n}\n\nint riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr)\n{\n\tassert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);\n\treturn riscv_program_insert(p, csrrci(d, z, csr - GDB_REGNO_CSR0));\n}\n\nint riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)\n{\n\tassert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);\n\treturn riscv_program_insert(p, csrrs(d, GDB_REGNO_ZERO, csr - GDB_REGNO_CSR0));\n}\n\nint riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)\n{\n\tassert(csr >= GDB_REGNO_CSR0);\n\treturn riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));\n}\n\nint riscv_program_fence_i(struct riscv_program *p)\n{\n\treturn riscv_program_insert(p, fence_i());\n}\n\nint riscv_program_fence(struct riscv_program *p)\n{\n\treturn riscv_program_insert(p, fence());\n}\n\nint riscv_program_ebreak(struct riscv_program *p)\n{\n\tstruct target *target = p->target;\n\tRISCV_INFO(r);\n\tif (p->instruction_count == riscv_debug_buffer_size(p->target) &&\n\t\t\tr->impebreak) {\n\t\treturn ERROR_OK;\n\t}\n\treturn riscv_program_insert(p, ebreak());\n}\n\nint riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)\n{\n\treturn riscv_program_insert(p, addi(d, s, u));\n}\n\nint riscv_program_insert(struct riscv_program *p, riscv_insn_t i)\n{\n\tif (p->instruction_count >= riscv_debug_buffer_size(p->target)) {\n\t\tLOG_ERROR(\"Unable to insert instruction:\");\n\t\tLOG_ERROR(\"  instruction_count=%d\", (int)p->instruction_count);\n\t\tLOG_ERROR(\"  buffer size      =%d\", (int)riscv_debug_buffer_size(p->target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tp->debug_buffer[p->instruction_count] = i;\n\tp->instruction_count++;\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/program.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef TARGET__RISCV__PROGRAM_H\n#define TARGET__RISCV__PROGRAM_H\n\n#include \"riscv.h\"\n\n#define RISCV_MAX_DEBUG_BUFFER_SIZE 32\n#define RISCV_REGISTER_COUNT 32\n#define RISCV_DSCRATCH_COUNT 2\n\n/* The various RISC-V debug specifications all revolve around setting up\n * program buffers and executing them on the target.  This structure contains a\n * single program, which can then be executed on targets.  */\nstruct riscv_program {\n\tstruct target *target;\n\n\tuint32_t debug_buffer[RISCV_MAX_DEBUG_BUFFER_SIZE];\n\n\t/* Number of 32-bit instructions in the program. */\n\tsize_t instruction_count;\n\n\t/* Side effects of executing this program.  These must be accounted for\n\t * in order to maintain correct executing of the target system.  */\n\tbool writes_xreg[RISCV_REGISTER_COUNT];\n\n\t/* XLEN on the target. */\n\tint target_xlen;\n};\n\n/* Initializes a program with the header. */\nint riscv_program_init(struct riscv_program *p, struct target *t);\n\n/* Write the program to the program buffer. */\nint riscv_program_write(struct riscv_program *program);\n\n/* Executes a program, returning 0 if the program successfully executed.  Note\n * that this may cause registers to be saved or restored, which could result to\n * calls to things like riscv_save_register which itself could require a\n * program to execute.  That's OK, just make sure this eventually terminates.\n * */\nint riscv_program_exec(struct riscv_program *p, struct target *t);\n\n/* A lower level interface, you shouldn't use this unless you have a reason. */\nint riscv_program_insert(struct riscv_program *p, riscv_insn_t i);\n\n/* Helpers to assemble various instructions.  Return 0 on success.  These might\n * assemble into a multi-instruction sequence that overwrites some other\n * register, but those will be properly saved and restored. */\nint riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);\nint riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);\nint riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);\nint riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);\n\nint riscv_program_sdr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);\nint riscv_program_swr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);\nint riscv_program_shr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);\nint riscv_program_sbr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);\n\nint riscv_program_csrrsi(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr);\nint riscv_program_csrrci(struct riscv_program *p, enum gdb_regno d, unsigned int z, enum gdb_regno csr);\nint riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr);\nint riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr);\n\nint riscv_program_fence_i(struct riscv_program *p);\nint riscv_program_fence(struct riscv_program *p);\nint riscv_program_ebreak(struct riscv_program *p);\n\nint riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/riscv-011.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Support for RISC-V, debug version 0.11. This was never an officially adopted\n * spec, but SiFive made some silicon that uses it.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <time.h>\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target/target.h\"\n#include \"target/algorithm.h\"\n#include \"target/target_type.h\"\n#include <helper/log.h>\n#include \"jtag/jtag.h\"\n#include \"target/register.h\"\n#include \"target/breakpoints.h\"\n#include \"helper/time_support.h\"\n#include \"riscv.h\"\n#include \"asm.h\"\n#include \"gdb_regs.h\"\n\n/**\n * Since almost everything can be accomplish by scanning the dbus register, all\n * functions here assume dbus is already selected. The exception are functions\n * called directly by OpenOCD, which can't assume anything about what's\n * currently in IR. They should set IR to dbus explicitly.\n */\n\n/**\n * Code structure\n *\n * At the bottom of the stack are the OpenOCD JTAG functions:\n *     jtag_add_[id]r_scan\n *     jtag_execute_query\n *     jtag_add_runtest\n *\n * There are a few functions to just instantly shift a register and get its\n * value:\n *    dtmcontrol_scan\n *    idcode_scan\n *    dbus_scan\n *\n * Because doing one scan and waiting for the result is slow, most functions\n * batch up a bunch of dbus writes and then execute them all at once. They use\n * the scans \"class\" for this:\n *    scans_new\n *    scans_delete\n *    scans_execute\n *    scans_add_...\n * Usually you new(), call a bunch of add functions, then execute() and look\n * at the results by calling scans_get...()\n *\n * Optimized functions will directly use the scans class above, but slightly\n * lazier code will use the cache functions that in turn use the scans\n * functions:\n *    cache_get...\n *    cache_set...\n *    cache_write\n * cache_set... update a local structure, which is then synced to the target\n * with cache_write(). Only Debug RAM words that are actually changed are sent\n * to the target. Afterwards use cache_get... to read results.\n */\n\n#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))\n#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))\n\n/* Constants for legacy SiFive hardware breakpoints. */\n#define CSR_BPCONTROL_X\t\t\t(1<<0)\n#define CSR_BPCONTROL_W\t\t\t(1<<1)\n#define CSR_BPCONTROL_R\t\t\t(1<<2)\n#define CSR_BPCONTROL_U\t\t\t(1<<3)\n#define CSR_BPCONTROL_S\t\t\t(1<<4)\n#define CSR_BPCONTROL_H\t\t\t(1<<5)\n#define CSR_BPCONTROL_M\t\t\t(1<<6)\n#define CSR_BPCONTROL_BPMATCH\t(0xf<<7)\n#define CSR_BPCONTROL_BPACTION\t(0xff<<11)\n\n#define DEBUG_ROM_START\t\t0x800\n#define DEBUG_ROM_RESUME\t(DEBUG_ROM_START + 4)\n#define DEBUG_ROM_EXCEPTION\t(DEBUG_ROM_START + 8)\n#define DEBUG_RAM_START\t\t0x400\n\n#define SETHALTNOT\t\t\t\t0x10c\n\n/*** JTAG registers. ***/\n\n#define DTMCONTROL\t\t\t\t\t0x10\n#define DTMCONTROL_DBUS_RESET\t\t(1<<16)\n#define DTMCONTROL_IDLE\t\t\t\t(7<<10)\n#define DTMCONTROL_ADDRBITS\t\t\t(0xf<<4)\n#define DTMCONTROL_VERSION\t\t\t(0xf)\n\n#define DBUS\t\t\t\t\t\t0x11\n#define DBUS_OP_START\t\t\t\t0\n#define DBUS_OP_SIZE\t\t\t\t2\ntypedef enum {\n\tDBUS_OP_NOP = 0,\n\tDBUS_OP_READ = 1,\n\tDBUS_OP_WRITE = 2\n} dbus_op_t;\ntypedef enum {\n\tDBUS_STATUS_SUCCESS = 0,\n\tDBUS_STATUS_FAILED = 2,\n\tDBUS_STATUS_BUSY = 3\n} dbus_status_t;\n#define DBUS_DATA_START\t\t\t\t2\n#define DBUS_DATA_SIZE\t\t\t\t34\n#define DBUS_ADDRESS_START\t\t\t36\n\ntypedef enum {\n\tRE_OK,\n\tRE_FAIL,\n\tRE_AGAIN\n} riscv_error_t;\n\ntypedef enum slot {\n\tSLOT0,\n\tSLOT1,\n\tSLOT_LAST,\n} slot_t;\n\n/*** Debug Bus registers. ***/\n\n#define DMCONTROL\t\t\t\t0x10\n#define DMCONTROL_INTERRUPT\t\t(((uint64_t)1)<<33)\n#define DMCONTROL_HALTNOT\t\t(((uint64_t)1)<<32)\n#define DMCONTROL_BUSERROR\t\t(7<<19)\n#define DMCONTROL_SERIAL\t\t(3<<16)\n#define DMCONTROL_AUTOINCREMENT\t(1<<15)\n#define DMCONTROL_ACCESS\t\t(7<<12)\n#define DMCONTROL_HARTID\t\t(0x3ff<<2)\n#define DMCONTROL_NDRESET\t\t(1<<1)\n#define DMCONTROL_FULLRESET\t\t1\n\n#define DMINFO\t\t\t\t\t0x11\n#define DMINFO_ABUSSIZE\t\t\t(0x7fU<<25)\n#define DMINFO_SERIALCOUNT\t\t(0xf<<21)\n#define DMINFO_ACCESS128\t\t(1<<20)\n#define DMINFO_ACCESS64\t\t\t(1<<19)\n#define DMINFO_ACCESS32\t\t\t(1<<18)\n#define DMINFO_ACCESS16\t\t\t(1<<17)\n#define DMINFO_ACCESS8\t\t\t(1<<16)\n#define DMINFO_DRAMSIZE\t\t\t(0x3f<<10)\n#define DMINFO_AUTHENTICATED\t(1<<5)\n#define DMINFO_AUTHBUSY\t\t\t(1<<4)\n#define DMINFO_AUTHTYPE\t\t\t(3<<2)\n#define DMINFO_VERSION\t\t\t3\n\n#define DMAUTHDATA0\t\t\t\t0x12\n#define DMAUTHDATA1\t\t\t\t0x13\n\n/*** Info about the core being debugged. ***/\n\n#define DBUS_ADDRESS_UNKNOWN\t0xffff\n\n#define DRAM_CACHE_SIZE\t\t16\n\nstruct trigger {\n\tuint64_t address;\n\tuint32_t length;\n\tuint64_t mask;\n\tuint64_t value;\n\tbool read, write, execute;\n\tint unique_id;\n};\n\nstruct memory_cache_line {\n\tuint32_t data;\n\tbool valid;\n\tbool dirty;\n};\n\ntypedef struct {\n\t/* Number of address bits in the dbus register. */\n\tuint8_t addrbits;\n\t/* Number of words in Debug RAM. */\n\tunsigned int dramsize;\n\tuint64_t dcsr;\n\tuint64_t dpc;\n\tuint64_t tselect;\n\tbool tselect_dirty;\n\t/* The value that mstatus actually has on the target right now. This is not\n\t * the value we present to the user. That one may be stored in the\n\t * reg_cache. */\n\tuint64_t mstatus_actual;\n\n\tstruct memory_cache_line dram_cache[DRAM_CACHE_SIZE];\n\n\t/* Number of run-test/idle cycles the target requests we do after each dbus\n\t * access. */\n\tunsigned int dtmcontrol_idle;\n\n\t/* This value is incremented every time a dbus access comes back as \"busy\".\n\t * It's used to determine how many run-test/idle cycles to feed the target\n\t * in between accesses. */\n\tunsigned int dbus_busy_delay;\n\n\t/* This value is incremented every time we read the debug interrupt as\n\t * high.  It's used to add extra run-test/idle cycles after setting debug\n\t * interrupt high, so ideally we never have to perform a whole extra scan\n\t * before the interrupt is cleared. */\n\tunsigned int interrupt_high_delay;\n\n\tbool never_halted;\n} riscv011_info_t;\n\ntypedef struct {\n\tbool haltnot;\n\tbool interrupt;\n} bits_t;\n\n/*** Necessary prototypes. ***/\n\nstatic int poll_target(struct target *target, bool announce);\nstatic int riscv011_poll(struct target *target);\nstatic int get_register(struct target *target, riscv_reg_t *value, int regid);\n\n/*** Utility functions. ***/\n\n#define DEBUG_LENGTH\t264\n\nstatic riscv011_info_t *get_info(const struct target *target)\n{\n\tstruct riscv_info *info = target->arch_info;\n\tassert(info);\n\tassert(info->version_specific);\n\treturn info->version_specific;\n}\n\nstatic unsigned int slot_offset(const struct target *target, slot_t slot)\n{\n\triscv011_info_t *info = get_info(target);\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\tswitch (slot) {\n\t\t\t\tcase SLOT0: return 4;\n\t\t\t\tcase SLOT1: return 5;\n\t\t\t\tcase SLOT_LAST: return info->dramsize-1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 64:\n\t\t\tswitch (slot) {\n\t\t\t\tcase SLOT0: return 4;\n\t\t\t\tcase SLOT1: return 6;\n\t\t\t\tcase SLOT_LAST: return info->dramsize-2;\n\t\t\t}\n\t}\n\tLOG_ERROR(\"slot_offset called with xlen=%d, slot=%d\",\n\t\t\triscv_xlen(target), slot);\n\tassert(0);\n\treturn 0; /* Silence -Werror=return-type */\n}\n\nstatic uint32_t load_slot(const struct target *target, unsigned int dest,\n\t\tslot_t slot)\n{\n\tunsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);\n\treturn load(target, dest, ZERO, offset);\n}\n\nstatic uint32_t store_slot(const struct target *target, unsigned int src,\n\t\tslot_t slot)\n{\n\tunsigned int offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);\n\treturn store(target, src, ZERO, offset);\n}\n\nstatic uint16_t dram_address(unsigned int index)\n{\n\tif (index < 0x10)\n\t\treturn index;\n\telse\n\t\treturn 0x40 + index - 0x10;\n}\n\nstatic uint32_t dtmcontrol_scan(struct target *target, uint32_t out)\n{\n\tstruct scan_field field;\n\tuint8_t in_value[4];\n\tuint8_t out_value[4] = { 0 };\n\n\tbuf_set_u32(out_value, 0, 32, out);\n\n\tjtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);\n\n\tfield.num_bits = 32;\n\tfield.out_value = out_value;\n\tfield.in_value = in_value;\n\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\n\t/* Always return to dbus. */\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\n\tuint32_t in = buf_get_u32(field.in_value, 0, 32);\n\tLOG_DEBUG(\"DTMCONTROL: 0x%x -> 0x%x\", out, in);\n\n\treturn in;\n}\n\nstatic uint32_t idcode_scan(struct target *target)\n{\n\tstruct scan_field field;\n\tuint8_t in_value[4];\n\n\tjtag_add_ir_scan(target->tap, &select_idcode, TAP_IDLE);\n\n\tfield.num_bits = 32;\n\tfield.out_value = NULL;\n\tfield.in_value = in_value;\n\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\n\t/* Always return to dbus. */\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tuint32_t in = buf_get_u32(field.in_value, 0, 32);\n\tLOG_DEBUG(\"IDCODE: 0x0 -> 0x%x\", in);\n\n\treturn in;\n}\n\nstatic void increase_dbus_busy_delay(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\tinfo->dbus_busy_delay += info->dbus_busy_delay / 10 + 1;\n\tLOG_DEBUG(\"dtmcontrol_idle=%d, dbus_busy_delay=%d, interrupt_high_delay=%d\",\n\t\t\tinfo->dtmcontrol_idle, info->dbus_busy_delay,\n\t\t\tinfo->interrupt_high_delay);\n\n\tdtmcontrol_scan(target, DTMCONTROL_DBUS_RESET);\n}\n\nstatic void increase_interrupt_high_delay(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\tinfo->interrupt_high_delay += info->interrupt_high_delay / 10 + 1;\n\tLOG_DEBUG(\"dtmcontrol_idle=%d, dbus_busy_delay=%d, interrupt_high_delay=%d\",\n\t\t\tinfo->dtmcontrol_idle, info->dbus_busy_delay,\n\t\t\tinfo->interrupt_high_delay);\n}\n\nstatic void add_dbus_scan(const struct target *target, struct scan_field *field,\n\t\tuint8_t *out_value, uint8_t *in_value, dbus_op_t op,\n\t\tuint16_t address, uint64_t data)\n{\n\triscv011_info_t *info = get_info(target);\n\tRISCV_INFO(r);\n\n\tif (r->reset_delays_wait >= 0) {\n\t\tr->reset_delays_wait--;\n\t\tif (r->reset_delays_wait < 0) {\n\t\t\tinfo->dbus_busy_delay = 0;\n\t\t\tinfo->interrupt_high_delay = 0;\n\t\t}\n\t}\n\n\tfield->num_bits = info->addrbits + DBUS_OP_SIZE + DBUS_DATA_SIZE;\n\tfield->in_value = in_value;\n\tfield->out_value = out_value;\n\n\tbuf_set_u64(out_value, DBUS_OP_START, DBUS_OP_SIZE, op);\n\tbuf_set_u64(out_value, DBUS_DATA_START, DBUS_DATA_SIZE, data);\n\tbuf_set_u64(out_value, DBUS_ADDRESS_START, info->addrbits, address);\n\n\tjtag_add_dr_scan(target->tap, 1, field, TAP_IDLE);\n\n\tint idle_count = info->dtmcontrol_idle + info->dbus_busy_delay;\n\tif (data & DMCONTROL_INTERRUPT)\n\t\tidle_count += info->interrupt_high_delay;\n\n\tif (idle_count)\n\t\tjtag_add_runtest(idle_count, TAP_IDLE);\n}\n\nstatic void dump_field(const struct scan_field *field)\n{\n\tstatic const char * const op_string[] = {\"nop\", \"r\", \"w\", \"?\"};\n\tstatic const char * const status_string[] = {\"+\", \"?\", \"F\", \"b\"};\n\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn;\n\n\tuint64_t out = buf_get_u64(field->out_value, 0, field->num_bits);\n\tunsigned int out_op = (out >> DBUS_OP_START) & ((1 << DBUS_OP_SIZE) - 1);\n\tchar out_interrupt = ((out >> DBUS_DATA_START) & DMCONTROL_INTERRUPT) ? 'i' : '.';\n\tchar out_haltnot = ((out >> DBUS_DATA_START) & DMCONTROL_HALTNOT) ? 'h' : '.';\n\tunsigned int out_data = out >> 2;\n\tunsigned int out_address = out >> DBUS_ADDRESS_START;\n\tuint64_t in = buf_get_u64(field->in_value, 0, field->num_bits);\n\tunsigned int in_op = (in >> DBUS_OP_START) & ((1 << DBUS_OP_SIZE) - 1);\n\tchar in_interrupt = ((in >> DBUS_DATA_START) & DMCONTROL_INTERRUPT) ? 'i' : '.';\n\tchar in_haltnot = ((in >> DBUS_DATA_START) & DMCONTROL_HALTNOT) ? 'h' : '.';\n\tunsigned int in_data = in >> 2;\n\tunsigned int in_address = in >> DBUS_ADDRESS_START;\n\n\tlog_printf_lf(LOG_LVL_DEBUG,\n\t\t\t__FILE__, __LINE__, \"scan\",\n\t\t\t\"%db %s %c%c:%08x @%02x -> %s %c%c:%08x @%02x\",\n\t\t\tfield->num_bits,\n\t\t\top_string[out_op], out_interrupt, out_haltnot, out_data,\n\t\t\tout_address,\n\t\t\tstatus_string[in_op], in_interrupt, in_haltnot, in_data,\n\t\t\tin_address);\n}\n\nstatic dbus_status_t dbus_scan(struct target *target, uint16_t *address_in,\n\t\tuint64_t *data_in, dbus_op_t op, uint16_t address_out, uint64_t data_out)\n{\n\triscv011_info_t *info = get_info(target);\n\tuint8_t in[8] = {0};\n\tuint8_t out[8] = {0};\n\tstruct scan_field field = {\n\t\t.num_bits = info->addrbits + DBUS_OP_SIZE + DBUS_DATA_SIZE,\n\t\t.out_value = out,\n\t\t.in_value = in\n\t};\n\n\tassert(info->addrbits != 0);\n\n\tbuf_set_u64(out, DBUS_OP_START, DBUS_OP_SIZE, op);\n\tbuf_set_u64(out, DBUS_DATA_START, DBUS_DATA_SIZE, data_out);\n\tbuf_set_u64(out, DBUS_ADDRESS_START, info->addrbits, address_out);\n\n\t/* Assume dbus is already selected. */\n\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\n\tint idle_count = info->dtmcontrol_idle + info->dbus_busy_delay;\n\n\tif (idle_count)\n\t\tjtag_add_runtest(idle_count, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"dbus_scan failed jtag scan\");\n\t\treturn DBUS_STATUS_FAILED;\n\t}\n\n\tif (data_in)\n\t\t*data_in = buf_get_u64(in, DBUS_DATA_START, DBUS_DATA_SIZE);\n\n\tif (address_in)\n\t\t*address_in = buf_get_u32(in, DBUS_ADDRESS_START, info->addrbits);\n\n\tdump_field(&field);\n\n\treturn buf_get_u32(in, DBUS_OP_START, DBUS_OP_SIZE);\n}\n\nstatic uint64_t dbus_read(struct target *target, uint16_t address)\n{\n\tuint64_t value;\n\tdbus_status_t status;\n\tuint16_t address_in;\n\n\t/* If the previous read/write was to the same address, we will get the read data\n\t * from the previous access.\n\t * While somewhat nonintuitive, this is an efficient way to get the data.\n\t */\n\n\tunsigned i = 0;\n\tdo {\n\t\tstatus = dbus_scan(target, &address_in, &value, DBUS_OP_READ, address, 0);\n\t\tif (status == DBUS_STATUS_BUSY)\n\t\t\tincrease_dbus_busy_delay(target);\n\t\tif (status == DBUS_STATUS_FAILED) {\n\t\t\tLOG_ERROR(\"dbus_read(0x%x) failed!\", address);\n\t\t\treturn 0;\n\t\t}\n\t} while (((status == DBUS_STATUS_BUSY) || (address_in != address)) &&\n\t\t\ti++ < 256);\n\n\tif (status != DBUS_STATUS_SUCCESS)\n\t\tLOG_ERROR(\"failed read from 0x%x; value=0x%\" PRIx64 \", status=%d\\n\", address, value, status);\n\n\treturn value;\n}\n\nstatic void dbus_write(struct target *target, uint16_t address, uint64_t value)\n{\n\tdbus_status_t status = DBUS_STATUS_BUSY;\n\tunsigned i = 0;\n\twhile (status == DBUS_STATUS_BUSY && i++ < 256) {\n\t\tstatus = dbus_scan(target, NULL, NULL, DBUS_OP_WRITE, address, value);\n\t\tif (status == DBUS_STATUS_BUSY)\n\t\t\tincrease_dbus_busy_delay(target);\n\t}\n\tif (status != DBUS_STATUS_SUCCESS)\n\t\tLOG_ERROR(\"failed to write 0x%\" PRIx64 \" to 0x%x; status=%d\\n\", value, address, status);\n}\n\n/*** scans \"class\" ***/\n\ntypedef struct {\n\t/* Number of scans that space is reserved for. */\n\tunsigned int scan_count;\n\t/* Size reserved in memory for each scan, in bytes. */\n\tunsigned int scan_size;\n\tunsigned int next_scan;\n\tuint8_t *in;\n\tuint8_t *out;\n\tstruct scan_field *field;\n\tconst struct target *target;\n} scans_t;\n\nstatic scans_t *scans_new(struct target *target, unsigned int scan_count)\n{\n\tscans_t *scans = malloc(sizeof(scans_t));\n\tif (!scans)\n\t\tgoto error0;\n\tscans->scan_count = scan_count;\n\t/* This code also gets called before xlen is detected. */\n\tif (riscv_xlen(target))\n\t\tscans->scan_size = 2 + riscv_xlen(target) / 8;\n\telse\n\t\tscans->scan_size = 2 + 128 / 8;\n\tscans->next_scan = 0;\n\tscans->in = calloc(scans->scan_size, scans->scan_count);\n\tif (!scans->in)\n\t\tgoto error1;\n\tscans->out = calloc(scans->scan_size, scans->scan_count);\n\tif (!scans->out)\n\t\tgoto error2;\n\tscans->field = calloc(scans->scan_count, sizeof(struct scan_field));\n\tif (!scans->field)\n\t\tgoto error3;\n\tscans->target = target;\n\treturn scans;\n\nerror3:\n\tfree(scans->out);\nerror2:\n\tfree(scans->in);\nerror1:\n\tfree(scans);\nerror0:\n\treturn NULL;\n}\n\nstatic scans_t *scans_delete(scans_t *scans)\n{\n\tassert(scans);\n\tfree(scans->field);\n\tfree(scans->out);\n\tfree(scans->in);\n\tfree(scans);\n\treturn NULL;\n}\n\nstatic void scans_reset(scans_t *scans)\n{\n\tscans->next_scan = 0;\n}\n\nstatic void scans_dump(scans_t *scans)\n{\n\tfor (unsigned int i = 0; i < scans->next_scan; i++)\n\t\tdump_field(&scans->field[i]);\n}\n\nstatic int scans_execute(scans_t *scans)\n{\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\n\tscans_dump(scans);\n\n\treturn ERROR_OK;\n}\n\n/** Add a 32-bit dbus write to the scans structure. */\nstatic void scans_add_write32(scans_t *scans, uint16_t address, uint32_t data,\n\t\tbool set_interrupt)\n{\n\tconst unsigned int i = scans->next_scan;\n\tint data_offset = scans->scan_size * i;\n\tadd_dbus_scan(scans->target, &scans->field[i], scans->out + data_offset,\n\t\t\tscans->in + data_offset, DBUS_OP_WRITE, address,\n\t\t\t(set_interrupt ? DMCONTROL_INTERRUPT : 0) | DMCONTROL_HALTNOT | data);\n\tscans->next_scan++;\n\tassert(scans->next_scan <= scans->scan_count);\n}\n\n/** Add a 32-bit dbus write for an instruction that jumps to the beginning of\n * debug RAM. */\nstatic void scans_add_write_jump(scans_t *scans, uint16_t address,\n\t\tbool set_interrupt)\n{\n\tscans_add_write32(scans, address,\n\t\t\tjal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*address))),\n\t\t\tset_interrupt);\n}\n\n/** Add a 32-bit dbus write for an instruction that loads from the indicated\n * slot. */\nstatic void scans_add_write_load(scans_t *scans, uint16_t address,\n\t\tunsigned int reg, slot_t slot, bool set_interrupt)\n{\n\tscans_add_write32(scans, address, load_slot(scans->target, reg, slot),\n\t\t\tset_interrupt);\n}\n\n/** Add a 32-bit dbus write for an instruction that stores to the indicated\n * slot. */\nstatic void scans_add_write_store(scans_t *scans, uint16_t address,\n\t\tunsigned int reg, slot_t slot, bool set_interrupt)\n{\n\tscans_add_write32(scans, address, store_slot(scans->target, reg, slot),\n\t\t\tset_interrupt);\n}\n\n/** Add a 32-bit dbus read. */\nstatic void scans_add_read32(scans_t *scans, uint16_t address, bool set_interrupt)\n{\n\tassert(scans->next_scan < scans->scan_count);\n\tconst unsigned int i = scans->next_scan;\n\tint data_offset = scans->scan_size * i;\n\tadd_dbus_scan(scans->target, &scans->field[i], scans->out + data_offset,\n\t\t\tscans->in + data_offset, DBUS_OP_READ, address,\n\t\t\t(set_interrupt ? DMCONTROL_INTERRUPT : 0) | DMCONTROL_HALTNOT);\n\tscans->next_scan++;\n}\n\n/** Add one or more scans to read the indicated slot. */\nstatic void scans_add_read(scans_t *scans, slot_t slot, bool set_interrupt)\n{\n\tconst struct target *target = scans->target;\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\tscans_add_read32(scans, slot_offset(target, slot), set_interrupt);\n\t\t\tbreak;\n\t\tcase 64:\n\t\t\tscans_add_read32(scans, slot_offset(target, slot), false);\n\t\t\tscans_add_read32(scans, slot_offset(target, slot) + 1, set_interrupt);\n\t\t\tbreak;\n\t}\n}\n\nstatic uint32_t scans_get_u32(scans_t *scans, unsigned int index,\n\t\tunsigned first, unsigned num)\n{\n\treturn buf_get_u32(scans->in + scans->scan_size * index, first, num);\n}\n\nstatic uint64_t scans_get_u64(scans_t *scans, unsigned int index,\n\t\tunsigned first, unsigned num)\n{\n\treturn buf_get_u64(scans->in + scans->scan_size * index, first, num);\n}\n\n/*** end of scans class ***/\n\nstatic uint32_t dram_read32(struct target *target, unsigned int index)\n{\n\tuint16_t address = dram_address(index);\n\tuint32_t value = dbus_read(target, address);\n\treturn value;\n}\n\nstatic void dram_write32(struct target *target, unsigned int index, uint32_t value,\n\t\tbool set_interrupt)\n{\n\tuint64_t dbus_value = DMCONTROL_HALTNOT | value;\n\tif (set_interrupt)\n\t\tdbus_value |= DMCONTROL_INTERRUPT;\n\tdbus_write(target, dram_address(index), dbus_value);\n}\n\n/** Read the haltnot and interrupt bits. */\nstatic bits_t read_bits(struct target *target)\n{\n\tuint64_t value;\n\tdbus_status_t status;\n\tuint16_t address_in;\n\triscv011_info_t *info = get_info(target);\n\n\tbits_t err_result = {\n\t\t.haltnot = 0,\n\t\t.interrupt = 0\n\t};\n\n\tdo {\n\t\tunsigned i = 0;\n\t\tdo {\n\t\t\tstatus = dbus_scan(target, &address_in, &value, DBUS_OP_READ, 0, 0);\n\t\t\tif (status == DBUS_STATUS_BUSY) {\n\t\t\t\tif (address_in == (1<<info->addrbits) - 1 &&\n\t\t\t\t\t\tvalue == (1ULL<<DBUS_DATA_SIZE) - 1) {\n\t\t\t\t\tLOG_ERROR(\"TDO seems to be stuck high.\");\n\t\t\t\t\treturn err_result;\n\t\t\t\t}\n\t\t\t\tincrease_dbus_busy_delay(target);\n\t\t\t} else if (status == DBUS_STATUS_FAILED) {\n\t\t\t\t/* TODO: return an actual error */\n\t\t\t\treturn err_result;\n\t\t\t}\n\t\t} while (status == DBUS_STATUS_BUSY && i++ < 256);\n\n\t\tif (i >= 256) {\n\t\t\tLOG_ERROR(\"Failed to read from 0x%x; status=%d\", address_in, status);\n\t\t\treturn err_result;\n\t\t}\n\t} while (address_in > 0x10 && address_in != DMCONTROL);\n\n\tbits_t result = {\n\t\t.haltnot = get_field(value, DMCONTROL_HALTNOT),\n\t\t.interrupt = get_field(value, DMCONTROL_INTERRUPT)\n\t};\n\treturn result;\n}\n\nstatic int wait_for_debugint_clear(struct target *target, bool ignore_first)\n{\n\ttime_t start = time(NULL);\n\tif (ignore_first) {\n\t\t/* Throw away the results of the first read, since they'll contain the\n\t\t * result of the read that happened just before debugint was set.\n\t\t * (Assuming the last scan before calling this function was one that\n\t\t * sets debugint.) */\n\t\tread_bits(target);\n\t}\n\twhile (1) {\n\t\tbits_t bits = read_bits(target);\n\t\tif (!bits.interrupt)\n\t\t\treturn ERROR_OK;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out waiting for debug int to clear.\"\n\t\t\t\t  \"Increase timeout with riscv set_command_timeout_sec.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n}\n\nstatic int dram_check32(struct target *target, unsigned int index,\n\t\tuint32_t expected)\n{\n\tuint16_t address = dram_address(index);\n\tuint32_t actual = dbus_read(target, address);\n\tif (expected != actual) {\n\t\tLOG_ERROR(\"Wrote 0x%x to Debug RAM at %d, but read back 0x%x\",\n\t\t\t\texpected, index, actual);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic void cache_set32(struct target *target, unsigned int index, uint32_t data)\n{\n\triscv011_info_t *info = get_info(target);\n\tif (info->dram_cache[index].valid &&\n\t\t\tinfo->dram_cache[index].data == data) {\n\t\t/* This is already preset on the target. */\n\t\tLOG_DEBUG(\"cache[0x%x] = 0x%08x: DASM(0x%x) (hit)\", index, data, data);\n\t\treturn;\n\t}\n\tLOG_DEBUG(\"cache[0x%x] = 0x%08x: DASM(0x%x)\", index, data, data);\n\tinfo->dram_cache[index].data = data;\n\tinfo->dram_cache[index].valid = true;\n\tinfo->dram_cache[index].dirty = true;\n}\n\nstatic void cache_set(struct target *target, slot_t slot, uint64_t data)\n{\n\tunsigned int offset = slot_offset(target, slot);\n\tcache_set32(target, offset, data);\n\tif (riscv_xlen(target) > 32)\n\t\tcache_set32(target, offset + 1, data >> 32);\n}\n\nstatic void cache_set_jump(struct target *target, unsigned int index)\n{\n\tcache_set32(target, index,\n\t\t\tjal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index))));\n}\n\nstatic void cache_set_load(struct target *target, unsigned int index,\n\t\tunsigned int reg, slot_t slot)\n{\n\tuint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);\n\tcache_set32(target, index, load(target, reg, ZERO, offset));\n}\n\nstatic void cache_set_store(struct target *target, unsigned int index,\n\t\tunsigned int reg, slot_t slot)\n{\n\tuint16_t offset = DEBUG_RAM_START + 4 * slot_offset(target, slot);\n\tcache_set32(target, index, store(target, reg, ZERO, offset));\n}\n\nstatic void dump_debug_ram(struct target *target)\n{\n\tfor (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {\n\t\tuint32_t value = dram_read32(target, i);\n\t\tLOG_ERROR(\"Debug RAM 0x%x: 0x%08x\", i, value);\n\t}\n}\n\n/* Call this if the code you just ran writes to debug RAM entries 0 through 3. */\nstatic void cache_invalidate(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\tinfo->dram_cache[i].valid = false;\n\t\tinfo->dram_cache[i].dirty = false;\n\t}\n}\n\n/* Called by cache_write() after the program has run. Also call this if you're\n * running programs without calling cache_write(). */\nstatic void cache_clean(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\tif (i >= 4)\n\t\t\tinfo->dram_cache[i].valid = false;\n\t\tinfo->dram_cache[i].dirty = false;\n\t}\n}\n\nstatic int cache_check(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\tint error = 0;\n\n\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\tif (info->dram_cache[i].valid && !info->dram_cache[i].dirty) {\n\t\t\tif (dram_check32(target, i, info->dram_cache[i].data) != ERROR_OK)\n\t\t\t\terror++;\n\t\t}\n\t}\n\n\tif (error) {\n\t\tdump_debug_ram(target);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** Write cache to the target, and optionally run the program.\n * Then read the value at address into the cache, assuming address < 128. */\n#define CACHE_NO_READ\t128\nstatic int cache_write(struct target *target, unsigned int address, bool run)\n{\n\tLOG_DEBUG(\"enter\");\n\triscv011_info_t *info = get_info(target);\n\tscans_t *scans = scans_new(target, info->dramsize + 2);\n\tif (!scans)\n\t\treturn ERROR_FAIL;\n\n\tunsigned int last = info->dramsize;\n\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\tif (info->dram_cache[i].dirty)\n\t\t\tlast = i;\n\t}\n\n\tif (last == info->dramsize) {\n\t\t/* Nothing needs to be written to RAM. */\n\t\tdbus_write(target, DMCONTROL, DMCONTROL_HALTNOT | (run ? DMCONTROL_INTERRUPT : 0));\n\n\t} else {\n\t\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\t\tif (info->dram_cache[i].dirty) {\n\t\t\t\tbool set_interrupt = (i == last && run);\n\t\t\t\tscans_add_write32(scans, i, info->dram_cache[i].data,\n\t\t\t\t\t\tset_interrupt);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (run || address < CACHE_NO_READ) {\n\t\t/* Throw away the results of the first read, since it'll contain the\n\t\t * result of the read that happened just before debugint was set. */\n\t\tscans_add_read32(scans, address, false);\n\n\t\t/* This scan contains the results of the read the caller requested, as\n\t\t * well as an interrupt bit worth looking at. */\n\t\tscans_add_read32(scans, address, false);\n\t}\n\n\tint retval = scans_execute(scans);\n\tif (retval != ERROR_OK) {\n\t\tscans_delete(scans);\n\t\tLOG_ERROR(\"JTAG execute failed.\");\n\t\treturn retval;\n\t}\n\n\tint errors = 0;\n\tfor (unsigned int i = 0; i < scans->next_scan; i++) {\n\t\tdbus_status_t status = scans_get_u32(scans, i, DBUS_OP_START,\n\t\t\t\tDBUS_OP_SIZE);\n\t\tswitch (status) {\n\t\t\tcase DBUS_STATUS_SUCCESS:\n\t\t\t\tbreak;\n\t\t\tcase DBUS_STATUS_FAILED:\n\t\t\t\tLOG_ERROR(\"Debug RAM write failed. Hardware error?\");\n\t\t\t\tscans_delete(scans);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tcase DBUS_STATUS_BUSY:\n\t\t\t\terrors++;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Got invalid bus access status: %d\", status);\n\t\t\t\tscans_delete(scans);\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (errors) {\n\t\tincrease_dbus_busy_delay(target);\n\n\t\t/* Try again, using the slow careful code.\n\t\t * Write all RAM, just to be extra cautious. */\n\t\tfor (unsigned int i = 0; i < info->dramsize; i++) {\n\t\t\tif (i == last && run)\n\t\t\t\tdram_write32(target, last, info->dram_cache[last].data, true);\n\t\t\telse\n\t\t\t\tdram_write32(target, i, info->dram_cache[i].data, false);\n\t\t\tinfo->dram_cache[i].dirty = false;\n\t\t}\n\t\tif (run)\n\t\t\tcache_clean(target);\n\n\t\tif (wait_for_debugint_clear(target, true) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Debug interrupt didn't clear.\");\n\t\t\tdump_debug_ram(target);\n\t\t\tscans_delete(scans);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else {\n\t\tif (run) {\n\t\t\tcache_clean(target);\n\t\t} else {\n\t\t\tfor (unsigned int i = 0; i < info->dramsize; i++)\n\t\t\t\tinfo->dram_cache[i].dirty = false;\n\t\t}\n\n\t\tif (run || address < CACHE_NO_READ) {\n\t\t\tint interrupt = scans_get_u32(scans, scans->next_scan-1,\n\t\t\t\t\tDBUS_DATA_START + 33, 1);\n\t\t\tif (interrupt) {\n\t\t\t\tincrease_interrupt_high_delay(target);\n\t\t\t\t/* Slow path wait for it to clear. */\n\t\t\t\tif (wait_for_debugint_clear(target, false) != ERROR_OK) {\n\t\t\t\t\tLOG_ERROR(\"Debug interrupt didn't clear.\");\n\t\t\t\t\tdump_debug_ram(target);\n\t\t\t\t\tscans_delete(scans);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* We read a useful value in that last scan. */\n\t\t\t\tunsigned int read_addr = scans_get_u32(scans, scans->next_scan-1,\n\t\t\t\t\t\tDBUS_ADDRESS_START, info->addrbits);\n\t\t\t\tif (read_addr != address) {\n\t\t\t\t\tLOG_INFO(\"Got data from 0x%x but expected it from 0x%x\",\n\t\t\t\t\t\t\tread_addr, address);\n\t\t\t\t}\n\t\t\t\tinfo->dram_cache[read_addr].data =\n\t\t\t\t\tscans_get_u32(scans, scans->next_scan-1, DBUS_DATA_START, 32);\n\t\t\t\tinfo->dram_cache[read_addr].valid = true;\n\t\t\t}\n\t\t}\n\t}\n\n\tscans_delete(scans);\n\tLOG_DEBUG(\"exit\");\n\n\treturn ERROR_OK;\n}\n\nstatic uint32_t cache_get32(struct target *target, unsigned int address)\n{\n\triscv011_info_t *info = get_info(target);\n\tif (!info->dram_cache[address].valid) {\n\t\tinfo->dram_cache[address].data = dram_read32(target, address);\n\t\tinfo->dram_cache[address].valid = true;\n\t}\n\treturn info->dram_cache[address].data;\n}\n\nstatic uint64_t cache_get(struct target *target, slot_t slot)\n{\n\tunsigned int offset = slot_offset(target, slot);\n\tuint64_t value = cache_get32(target, offset);\n\tif (riscv_xlen(target) > 32)\n\t\tvalue |= ((uint64_t) cache_get32(target, offset + 1)) << 32;\n\treturn value;\n}\n\n/* Write instruction that jumps from the specified word in Debug RAM to resume\n * in Debug ROM. */\nstatic void dram_write_jump(struct target *target, unsigned int index,\n\t\tbool set_interrupt)\n{\n\tdram_write32(target, index,\n\t\t\tjal(0, (uint32_t) (DEBUG_ROM_RESUME - (DEBUG_RAM_START + 4*index))),\n\t\t\tset_interrupt);\n}\n\nstatic int wait_for_state(struct target *target, enum target_state state)\n{\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tint result = riscv011_poll(target);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tif (target->state == state)\n\t\t\treturn ERROR_OK;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out waiting for state %d. \"\n\t\t\t\t  \"Increase timeout with riscv set_command_timeout_sec.\", state);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n}\n\nstatic int read_remote_csr(struct target *target, uint64_t *value, uint32_t csr)\n{\n\triscv011_info_t *info = get_info(target);\n\tcache_set32(target, 0, csrr(S0, csr));\n\tcache_set_store(target, 1, S0, SLOT0);\n\tcache_set_jump(target, 2);\n\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*value = cache_get(target, SLOT0);\n\tLOG_DEBUG(\"csr 0x%x = 0x%\" PRIx64, csr, *value);\n\n\tuint32_t exception = cache_get32(target, info->dramsize-1);\n\tif (exception) {\n\t\tLOG_WARNING(\"Got exception 0x%x when reading %s\", exception,\n\t\t\t\tgdb_regno_name(GDB_REGNO_CSR0 + csr));\n\t\t*value = ~0;\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int write_remote_csr(struct target *target, uint32_t csr, uint64_t value)\n{\n\tLOG_DEBUG(\"csr 0x%x <- 0x%\" PRIx64, csr, value);\n\tcache_set_load(target, 0, S0, SLOT0);\n\tcache_set32(target, 1, csrw(S0, csr));\n\tcache_set_jump(target, 2);\n\tcache_set(target, SLOT0, value);\n\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int write_gpr(struct target *target, unsigned int gpr, uint64_t value)\n{\n\tcache_set_load(target, 0, gpr, SLOT0);\n\tcache_set_jump(target, 1);\n\tcache_set(target, SLOT0, value);\n\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\nstatic int maybe_read_tselect(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tif (info->tselect_dirty) {\n\t\tint result = read_remote_csr(target, &info->tselect, CSR_TSELECT);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tinfo->tselect_dirty = false;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int maybe_write_tselect(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tif (!info->tselect_dirty) {\n\t\tint result = write_remote_csr(target, CSR_TSELECT, info->tselect);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tinfo->tselect_dirty = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int execute_resume(struct target *target, bool step)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tLOG_DEBUG(\"step=%d\", step);\n\n\tmaybe_write_tselect(target);\n\n\t/* TODO: check if dpc is dirty (which also is true if an exception was hit\n\t * at any time) */\n\tcache_set_load(target, 0, S0, SLOT0);\n\tcache_set32(target, 1, csrw(S0, CSR_DPC));\n\tcache_set_jump(target, 2);\n\tcache_set(target, SLOT0, info->dpc);\n\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tstruct reg *mstatus_reg = &target->reg_cache->reg_list[GDB_REGNO_MSTATUS];\n\tif (mstatus_reg->valid) {\n\t\tuint64_t mstatus_user = buf_get_u64(mstatus_reg->value, 0, riscv_xlen(target));\n\t\tif (mstatus_user != info->mstatus_actual) {\n\t\t\tcache_set_load(target, 0, S0, SLOT0);\n\t\t\tcache_set32(target, 1, csrw(S0, CSR_MSTATUS));\n\t\t\tcache_set_jump(target, 2);\n\t\t\tcache_set(target, SLOT0, mstatus_user);\n\t\t\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);\n\tinfo->dcsr &= ~DCSR_HALT;\n\n\tif (step)\n\t\tinfo->dcsr |= DCSR_STEP;\n\telse\n\t\tinfo->dcsr &= ~DCSR_STEP;\n\n\tdram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false);\n\tdram_write32(target, 1, csrw(S0, CSR_DCSR), false);\n\tdram_write32(target, 2, fence_i(), false);\n\tdram_write_jump(target, 3, false);\n\n\t/* Write DCSR value, set interrupt and clear haltnot. */\n\tuint64_t dbus_value = DMCONTROL_INTERRUPT | info->dcsr;\n\tdbus_write(target, dram_address(4), dbus_value);\n\n\tcache_invalidate(target);\n\n\tif (wait_for_debugint_clear(target, true) != ERROR_OK) {\n\t\tLOG_ERROR(\"Debug interrupt didn't clear.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget->state = TARGET_RUNNING;\n\tregister_cache_invalidate(target->reg_cache);\n\n\treturn ERROR_OK;\n}\n\n/* Execute a step, and wait for reentry into Debug Mode. */\nstatic int full_step(struct target *target, bool announce)\n{\n\tint result = execute_resume(target, true);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tresult = poll_target(target, announce);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tif (target->state != TARGET_DEBUG_RUNNING)\n\t\t\tbreak;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out waiting for step to complete.\"\n\t\t\t\t\t\"Increase timeout with riscv set_command_timeout_sec\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int resume(struct target *target, int debug_execution, bool step)\n{\n\tif (debug_execution) {\n\t\tLOG_ERROR(\"TODO: debug_execution is true\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn execute_resume(target, step);\n}\n\nstatic uint64_t reg_cache_get(struct target *target, unsigned int number)\n{\n\tstruct reg *r = &target->reg_cache->reg_list[number];\n\tif (!r->valid) {\n\t\tLOG_ERROR(\"Register cache entry for %d is invalid!\", number);\n\t\tassert(r->valid);\n\t}\n\tuint64_t value = buf_get_u64(r->value, 0, r->size);\n\tLOG_DEBUG(\"%s = 0x%\" PRIx64, r->name, value);\n\treturn value;\n}\n\nstatic void reg_cache_set(struct target *target, unsigned int number,\n\t\tuint64_t value)\n{\n\tstruct reg *r = &target->reg_cache->reg_list[number];\n\tLOG_DEBUG(\"%s <= 0x%\" PRIx64, r->name, value);\n\tr->valid = true;\n\tbuf_set_u64(r->value, 0, r->size, value);\n}\n\nstatic int update_mstatus_actual(struct target *target)\n{\n\tstruct reg *mstatus_reg = &target->reg_cache->reg_list[GDB_REGNO_MSTATUS];\n\tif (mstatus_reg->valid) {\n\t\t/* We previously made it valid. */\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Force reading the register. In that process mstatus_actual will be\n\t * updated. */\n\triscv_reg_t mstatus;\n\treturn get_register(target, &mstatus, GDB_REGNO_MSTATUS);\n}\n\n/*** OpenOCD target functions. ***/\n\nstatic int register_read(struct target *target, riscv_reg_t *value, int regnum)\n{\n\triscv011_info_t *info = get_info(target);\n\tif (regnum >= GDB_REGNO_CSR0 && regnum <= GDB_REGNO_CSR4095) {\n\t\tcache_set32(target, 0, csrr(S0, regnum - GDB_REGNO_CSR0));\n\t\tcache_set_store(target, 1, S0, SLOT0);\n\t\tcache_set_jump(target, 2);\n\t} else {\n\t\tLOG_ERROR(\"Don't know how to read register %d\", regnum);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t exception = cache_get32(target, info->dramsize-1);\n\tif (exception) {\n\t\tLOG_WARNING(\"Got exception 0x%x when reading %s\", exception, gdb_regno_name(regnum));\n\t\t*value = ~0;\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*value = cache_get(target, SLOT0);\n\tLOG_DEBUG(\"reg[%d]=0x%\" PRIx64, regnum, *value);\n\n\tif (regnum == GDB_REGNO_MSTATUS)\n\t\tinfo->mstatus_actual = *value;\n\n\treturn ERROR_OK;\n}\n\n/* Write the register. No caching or games. */\nstatic int register_write(struct target *target, unsigned int number,\n\t\tuint64_t value)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tmaybe_write_tselect(target);\n\n\tif (number == S0) {\n\t\tcache_set_load(target, 0, S0, SLOT0);\n\t\tcache_set32(target, 1, csrw(S0, CSR_DSCRATCH0));\n\t\tcache_set_jump(target, 2);\n\t} else if (number == S1) {\n\t\tcache_set_load(target, 0, S0, SLOT0);\n\t\tcache_set_store(target, 1, S0, SLOT_LAST);\n\t\tcache_set_jump(target, 2);\n\t} else if (number <= GDB_REGNO_XPR31) {\n\t\tcache_set_load(target, 0, number - GDB_REGNO_ZERO, SLOT0);\n\t\tcache_set_jump(target, 1);\n\t} else if (number == GDB_REGNO_PC) {\n\t\tinfo->dpc = value;\n\t\treturn ERROR_OK;\n\t} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\tint result = update_mstatus_actual(target);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tunsigned i = 0;\n\t\tif ((info->mstatus_actual & MSTATUS_FS) == 0) {\n\t\t\tinfo->mstatus_actual = set_field(info->mstatus_actual, MSTATUS_FS, 1);\n\t\t\tcache_set_load(target, i++, S0, SLOT1);\n\t\t\tcache_set32(target, i++, csrw(S0, CSR_MSTATUS));\n\t\t\tcache_set(target, SLOT1, info->mstatus_actual);\n\t\t}\n\n\t\tif (riscv_xlen(target) == 32)\n\t\t\tcache_set32(target, i++, flw(number - GDB_REGNO_FPR0, 0, DEBUG_RAM_START + 16));\n\t\telse\n\t\t\tcache_set32(target, i++, fld(number - GDB_REGNO_FPR0, 0, DEBUG_RAM_START + 16));\n\t\tcache_set_jump(target, i++);\n\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\tcache_set_load(target, 0, S0, SLOT0);\n\t\tcache_set32(target, 1, csrw(S0, number - GDB_REGNO_CSR0));\n\t\tcache_set_jump(target, 2);\n\n\t\tif (number == GDB_REGNO_MSTATUS)\n\t\t\tinfo->mstatus_actual = value;\n\t} else if (number == GDB_REGNO_PRIV) {\n\t\tinfo->dcsr = set_field(info->dcsr, DCSR_PRV, value);\n\t\treturn ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"Don't know how to write register %d\", number);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcache_set(target, SLOT0, value);\n\tif (cache_write(target, info->dramsize - 1, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t exception = cache_get32(target, info->dramsize-1);\n\tif (exception) {\n\t\tLOG_WARNING(\"Got exception 0x%x when writing %s\", exception,\n\t\t\t\tgdb_regno_name(number));\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int get_register(struct target *target, riscv_reg_t *value, int regid)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tmaybe_write_tselect(target);\n\n\tif (regid <= GDB_REGNO_XPR31) {\n\t\t*value = reg_cache_get(target, regid);\n\t} else if (regid == GDB_REGNO_PC) {\n\t\t*value = info->dpc;\n\t} else if (regid >= GDB_REGNO_FPR0 && regid <= GDB_REGNO_FPR31) {\n\t\tint result = update_mstatus_actual(target);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tunsigned i = 0;\n\t\tif ((info->mstatus_actual & MSTATUS_FS) == 0) {\n\t\t\tinfo->mstatus_actual = set_field(info->mstatus_actual, MSTATUS_FS, 1);\n\t\t\tcache_set_load(target, i++, S0, SLOT1);\n\t\t\tcache_set32(target, i++, csrw(S0, CSR_MSTATUS));\n\t\t\tcache_set(target, SLOT1, info->mstatus_actual);\n\t\t}\n\n\t\tif (riscv_xlen(target) == 32)\n\t\t\tcache_set32(target, i++, fsw(regid - GDB_REGNO_FPR0, 0, DEBUG_RAM_START + 16));\n\t\telse\n\t\t\tcache_set32(target, i++, fsd(regid - GDB_REGNO_FPR0, 0, DEBUG_RAM_START + 16));\n\t\tcache_set_jump(target, i++);\n\n\t\tif (cache_write(target, 4, true) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else if (regid == GDB_REGNO_PRIV) {\n\t\t*value = get_field(info->dcsr, DCSR_PRV);\n\t} else {\n\t\tint result = register_read(target, value, regid);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\tif (regid == GDB_REGNO_MSTATUS)\n\t\ttarget->reg_cache->reg_list[regid].valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int set_register(struct target *target, int regid, uint64_t value)\n{\n\treturn register_write(target, regid, value);\n}\n\nstatic int halt(struct target *target)\n{\n\tLOG_DEBUG(\"riscv_halt()\");\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tcache_set32(target, 0, csrsi(CSR_DCSR, DCSR_HALT));\n\tcache_set32(target, 1, csrr(S0, CSR_MHARTID));\n\tcache_set32(target, 2, sw(S0, ZERO, SETHALTNOT));\n\tcache_set_jump(target, 3);\n\n\tif (cache_write(target, 4, true) != ERROR_OK) {\n\t\tLOG_ERROR(\"cache_write() failed.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void deinit_target(struct target *target)\n{\n\tLOG_DEBUG(\"riscv_deinit_target()\");\n\tstruct riscv_info *info = target->arch_info;\n\tif (!info)\n\t\treturn;\n\n\tfree(info->version_specific);\n\tinfo->version_specific = NULL;\n}\n\nstatic int strict_step(struct target *target, bool announce)\n{\n\tLOG_DEBUG(\"enter\");\n\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\twhile (watchpoint) {\n\t\triscv_remove_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\tint result = full_step(target, announce);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\twatchpoint = target->watchpoints;\n\twhile (watchpoint) {\n\t\triscv_add_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int step(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints)\n{\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tif (!current) {\n\t\tif (riscv_xlen(target) > 32) {\n\t\t\tLOG_WARNING(\"Asked to resume at 32-bit PC on %d-bit target.\",\n\t\t\t\t\triscv_xlen(target));\n\t\t}\n\t\tint result = register_write(target, GDB_REGNO_PC, address);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\tif (handle_breakpoints) {\n\t\tint result = strict_step(target, true);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t} else {\n\t\treturn full_step(target, false);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int examine(struct target *target)\n{\n\t/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */\n\n\tuint32_t dtmcontrol = dtmcontrol_scan(target, 0);\n\tLOG_DEBUG(\"dtmcontrol=0x%x\", dtmcontrol);\n\tLOG_DEBUG(\"  addrbits=%d\", get_field(dtmcontrol, DTMCONTROL_ADDRBITS));\n\tLOG_DEBUG(\"  version=%d\", get_field(dtmcontrol, DTMCONTROL_VERSION));\n\tLOG_DEBUG(\"  idle=%d\", get_field(dtmcontrol, DTMCONTROL_IDLE));\n\tif (dtmcontrol == 0) {\n\t\tLOG_ERROR(\"dtmcontrol is 0. Check JTAG connectivity/board power.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (get_field(dtmcontrol, DTMCONTROL_VERSION) != 0) {\n\t\tLOG_ERROR(\"Unsupported DTM version %d. (dtmcontrol=0x%x)\",\n\t\t\t\tget_field(dtmcontrol, DTMCONTROL_VERSION), dtmcontrol);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tRISCV_INFO(r);\n\n\triscv011_info_t *info = get_info(target);\n\tinfo->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS);\n\tinfo->dtmcontrol_idle = get_field(dtmcontrol, DTMCONTROL_IDLE);\n\tif (info->dtmcontrol_idle == 0) {\n\t\t/* Some old SiFive cores don't set idle but need it to be 1. */\n\t\tuint32_t idcode = idcode_scan(target);\n\t\tif (idcode == 0x10e31913)\n\t\t\tinfo->dtmcontrol_idle = 1;\n\t}\n\n\tuint32_t dminfo = dbus_read(target, DMINFO);\n\tLOG_DEBUG(\"dminfo: 0x%08x\", dminfo);\n\tLOG_DEBUG(\"  abussize=0x%x\", get_field(dminfo, DMINFO_ABUSSIZE));\n\tLOG_DEBUG(\"  serialcount=0x%x\", get_field(dminfo, DMINFO_SERIALCOUNT));\n\tLOG_DEBUG(\"  access128=%d\", get_field(dminfo, DMINFO_ACCESS128));\n\tLOG_DEBUG(\"  access64=%d\", get_field(dminfo, DMINFO_ACCESS64));\n\tLOG_DEBUG(\"  access32=%d\", get_field(dminfo, DMINFO_ACCESS32));\n\tLOG_DEBUG(\"  access16=%d\", get_field(dminfo, DMINFO_ACCESS16));\n\tLOG_DEBUG(\"  access8=%d\", get_field(dminfo, DMINFO_ACCESS8));\n\tLOG_DEBUG(\"  dramsize=0x%x\", get_field(dminfo, DMINFO_DRAMSIZE));\n\tLOG_DEBUG(\"  authenticated=0x%x\", get_field(dminfo, DMINFO_AUTHENTICATED));\n\tLOG_DEBUG(\"  authbusy=0x%x\", get_field(dminfo, DMINFO_AUTHBUSY));\n\tLOG_DEBUG(\"  authtype=0x%x\", get_field(dminfo, DMINFO_AUTHTYPE));\n\tLOG_DEBUG(\"  version=0x%x\", get_field(dminfo, DMINFO_VERSION));\n\n\tif (get_field(dminfo, DMINFO_VERSION) != 1) {\n\t\tLOG_ERROR(\"OpenOCD only supports Debug Module version 1, not %d \"\n\t\t\t\t\"(dminfo=0x%x)\", get_field(dminfo, DMINFO_VERSION), dminfo);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tinfo->dramsize = get_field(dminfo, DMINFO_DRAMSIZE) + 1;\n\n\tif (get_field(dminfo, DMINFO_AUTHTYPE) != 0) {\n\t\tLOG_ERROR(\"Authentication required by RISC-V core but not \"\n\t\t\t\t\"supported by OpenOCD. dminfo=0x%x\", dminfo);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Pretend this is a 32-bit system until we have found out the true value. */\n\tr->xlen = 32;\n\n\t/* Figure out XLEN, and test writing all of Debug RAM while we're at it. */\n\tcache_set32(target, 0, xori(S1, ZERO, -1));\n\t/* 0xffffffff  0xffffffff:ffffffff  0xffffffff:ffffffff:ffffffff:ffffffff */\n\tcache_set32(target, 1, srli(S1, S1, 31));\n\t/* 0x00000001  0x00000001:ffffffff  0x00000001:ffffffff:ffffffff:ffffffff */\n\tcache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START));\n\tcache_set32(target, 3, srli(S1, S1, 31));\n\t/* 0x00000000  0x00000000:00000003  0x00000000:00000003:ffffffff:ffffffff */\n\tcache_set32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));\n\tcache_set_jump(target, 5);\n\tfor (unsigned i = 6; i < info->dramsize; i++)\n\t\tcache_set32(target, i, i * 0x01020304);\n\n\tcache_write(target, 0, false);\n\n\t/* Check that we can actually read/write dram. */\n\tif (cache_check(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tcache_write(target, 0, true);\n\tcache_invalidate(target);\n\n\tuint32_t word0 = cache_get32(target, 0);\n\tuint32_t word1 = cache_get32(target, 1);\n\tstruct riscv_info *generic_info = riscv_info(target);\n\tif (word0 == 1 && word1 == 0) {\n\t\tgeneric_info->xlen = 32;\n\t} else if (word0 == 0xffffffff && word1 == 3) {\n\t\tgeneric_info->xlen = 64;\n\t} else if (word0 == 0xffffffff && word1 == 0xffffffff) {\n\t\tgeneric_info->xlen = 128;\n\t} else {\n\t\tuint32_t exception = cache_get32(target, info->dramsize-1);\n\t\tLOG_ERROR(\"Failed to discover xlen; word0=0x%x, word1=0x%x, exception=0x%x\",\n\t\t\t\tword0, word1, exception);\n\t\tdump_debug_ram(target);\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"Discovered XLEN is %d\", riscv_xlen(target));\n\n\tif (read_remote_csr(target, &r->misa, CSR_MISA) != ERROR_OK) {\n\t\tconst unsigned old_csr_misa = 0xf10;\n\t\tLOG_WARNING(\"Failed to read misa at 0x%x; trying 0x%x.\", CSR_MISA,\n\t\t\t\told_csr_misa);\n\t\tif (read_remote_csr(target, &r->misa, old_csr_misa) != ERROR_OK) {\n\t\t\t/* Maybe this is an old core that still has $misa at the old\n\t\t\t * address. */\n\t\t\tLOG_ERROR(\"Failed to read misa at 0x%x.\", old_csr_misa);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* Update register list to match discovered XLEN/supported extensions. */\n\triscv_init_registers(target);\n\n\tinfo->never_halted = true;\n\n\tint result = riscv011_poll(target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\ttarget_set_examined(target);\n\triscv_set_current_hartid(target, 0);\n\tfor (size_t i = 0; i < 32; ++i)\n\t\treg_cache_set(target, i, -1);\n\tLOG_INFO(\"Examined RISCV core; XLEN=%d, misa=0x%\" PRIx64,\n\t\t\triscv_xlen(target), r->misa);\n\n\treturn ERROR_OK;\n}\n\nstatic riscv_error_t handle_halt_routine(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\n\tscans_t *scans = scans_new(target, 256);\n\tif (!scans)\n\t\treturn RE_FAIL;\n\n\t/* Read all GPRs as fast as we can, because gdb is going to ask for them\n\t * anyway. Reading them one at a time is much slower. */\n\n\t/* Write the jump back to address 1. */\n\tscans_add_write_jump(scans, 1, false);\n\tfor (int reg = 1; reg < 32; reg++) {\n\t\tif (reg == S0 || reg == S1)\n\t\t\tcontinue;\n\n\t\t/* Write store instruction. */\n\t\tscans_add_write_store(scans, 0, reg, SLOT0, true);\n\n\t\t/* Read value. */\n\t\tscans_add_read(scans, SLOT0, false);\n\t}\n\n\t/* Write store of s0 at index 1. */\n\tscans_add_write_store(scans, 1, S0, SLOT0, false);\n\t/* Write jump at index 2. */\n\tscans_add_write_jump(scans, 2, false);\n\n\t/* Read S1 from debug RAM */\n\tscans_add_write_load(scans, 0, S0, SLOT_LAST, true);\n\t/* Read value. */\n\tscans_add_read(scans, SLOT0, false);\n\n\t/* Read S0 from dscratch */\n\tunsigned int csr[] = {CSR_DSCRATCH0, CSR_DPC, CSR_DCSR};\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(csr); i++) {\n\t\tscans_add_write32(scans, 0, csrr(S0, csr[i]), true);\n\t\tscans_add_read(scans, SLOT0, false);\n\t}\n\n\t/* Final read to get the last value out. */\n\tscans_add_read32(scans, 4, false);\n\n\tint retval = scans_execute(scans);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG execute failed: %d\", retval);\n\t\tgoto error;\n\t}\n\n\tunsigned int dbus_busy = 0;\n\tunsigned int interrupt_set = 0;\n\tunsigned result = 0;\n\tuint64_t value = 0;\n\treg_cache_set(target, 0, 0);\n\t/* The first scan result is the result from something old we don't care\n\t * about. */\n\tfor (unsigned int i = 1; i < scans->next_scan && dbus_busy == 0; i++) {\n\t\tdbus_status_t status = scans_get_u32(scans, i, DBUS_OP_START,\n\t\t\t\tDBUS_OP_SIZE);\n\t\tuint64_t data = scans_get_u64(scans, i, DBUS_DATA_START, DBUS_DATA_SIZE);\n\t\tuint32_t address = scans_get_u32(scans, i, DBUS_ADDRESS_START,\n\t\t\t\tinfo->addrbits);\n\t\tswitch (status) {\n\t\t\tcase DBUS_STATUS_SUCCESS:\n\t\t\t\tbreak;\n\t\t\tcase DBUS_STATUS_FAILED:\n\t\t\t\tLOG_ERROR(\"Debug access failed. Hardware error?\");\n\t\t\t\tgoto error;\n\t\t\tcase DBUS_STATUS_BUSY:\n\t\t\t\tdbus_busy++;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"Got invalid bus access status: %d\", status);\n\t\t\t\tgoto error;\n\t\t}\n\t\tif (data & DMCONTROL_INTERRUPT) {\n\t\t\tinterrupt_set++;\n\t\t\tbreak;\n\t\t}\n\t\tif (address == 4 || address == 5) {\n\t\t\tunsigned int reg;\n\t\t\tswitch (result) {\n\t\t\t\tcase 0:\n\t\t\t\t\treg = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\treg = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\treg = 3;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\treg = 4;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4:\n\t\t\t\t\treg = 5;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5:\n\t\t\t\t\treg = 6;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 6:\n\t\t\t\t\treg = 7;\n\t\t\t\t\tbreak;\n\t\t\t\t\t/* S0 */\n\t\t\t\t\t/* S1 */\n\t\t\t\tcase 7:\n\t\t\t\t\treg = 10;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 8:\n\t\t\t\t\treg = 11;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 9:\n\t\t\t\t\treg = 12;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10:\n\t\t\t\t\treg = 13;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 11:\n\t\t\t\t\treg = 14;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 12:\n\t\t\t\t\treg = 15;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 13:\n\t\t\t\t\treg = 16;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 14:\n\t\t\t\t\treg = 17;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 15:\n\t\t\t\t\treg = 18;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 16:\n\t\t\t\t\treg = 19;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 17:\n\t\t\t\t\treg = 20;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 18:\n\t\t\t\t\treg = 21;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 19:\n\t\t\t\t\treg = 22;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 20:\n\t\t\t\t\treg = 23;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 21:\n\t\t\t\t\treg = 24;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 22:\n\t\t\t\t\treg = 25;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 23:\n\t\t\t\t\treg = 26;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 24:\n\t\t\t\t\treg = 27;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 25:\n\t\t\t\t\treg = 28;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 26:\n\t\t\t\t\treg = 29;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 27:\n\t\t\t\t\treg = 30;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 28:\n\t\t\t\t\treg = 31;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 29:\n\t\t\t\t\treg = S1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 30:\n\t\t\t\t\treg = S0;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 31:\n\t\t\t\t\treg = CSR_DPC;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 32:\n\t\t\t\t\treg = CSR_DCSR;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tassert(0);\n\t\t\t\t\tLOG_ERROR(\"Got invalid register result %d\", result);\n\t\t\t\t\tgoto error;\n\t\t\t}\n\t\t\tif (riscv_xlen(target) == 32) {\n\t\t\t\treg_cache_set(target, reg, data & 0xffffffff);\n\t\t\t\tresult++;\n\t\t\t} else if (riscv_xlen(target) == 64) {\n\t\t\t\tif (address == 4) {\n\t\t\t\t\tvalue = data & 0xffffffff;\n\t\t\t\t} else if (address == 5) {\n\t\t\t\t\treg_cache_set(target, reg, ((data & 0xffffffff) << 32) | value);\n\t\t\t\t\tvalue = 0;\n\t\t\t\t\tresult++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tscans_delete(scans);\n\n\tif (dbus_busy) {\n\t\tincrease_dbus_busy_delay(target);\n\t\treturn RE_AGAIN;\n\t}\n\tif (interrupt_set) {\n\t\tincrease_interrupt_high_delay(target);\n\t\treturn RE_AGAIN;\n\t}\n\n\t/* TODO: get rid of those 2 variables and talk to the cache directly. */\n\tinfo->dpc = reg_cache_get(target, CSR_DPC);\n\tinfo->dcsr = reg_cache_get(target, CSR_DCSR);\n\n\tcache_invalidate(target);\n\n\treturn RE_OK;\n\nerror:\n\tscans_delete(scans);\n\treturn RE_FAIL;\n}\n\nstatic int handle_halt(struct target *target, bool announce)\n{\n\triscv011_info_t *info = get_info(target);\n\ttarget->state = TARGET_HALTED;\n\n\triscv_error_t re;\n\tdo {\n\t\tre = handle_halt_routine(target);\n\t} while (re == RE_AGAIN);\n\tif (re != RE_OK) {\n\t\tLOG_ERROR(\"handle_halt_routine failed\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint cause = get_field(info->dcsr, DCSR_CAUSE);\n\tswitch (cause) {\n\t\tcase DCSR_CAUSE_SWBP:\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase DCSR_CAUSE_HWBP:\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase DCSR_CAUSE_DEBUGINT:\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase DCSR_CAUSE_STEP:\n\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t\t\tbreak;\n\t\tcase DCSR_CAUSE_HALT:\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Invalid halt cause %d in DCSR (0x%\" PRIx64 \")\",\n\t\t\t\t\tcause, info->dcsr);\n\t}\n\n\tif (info->never_halted) {\n\t\tinfo->never_halted = false;\n\n\t\tint result = maybe_read_tselect(target);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\triscv_enumerate_triggers(target);\n\t}\n\n\tif (target->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\tint retval;\n\t\tif (riscv_semihosting(target, &retval) != 0)\n\t\t\treturn retval;\n\t}\n\n\tif (announce)\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\tconst char *cause_string[] = {\n\t\t\"none\",\n\t\t\"software breakpoint\",\n\t\t\"hardware trigger\",\n\t\t\"debug interrupt\",\n\t\t\"step\",\n\t\t\"halt\"\n\t};\n\t/* This is logged to the user so that gdb will show it when a user types\n\t * 'monitor reset init'. At that time gdb appears to have the pc cached\n\t * still so if a user manually inspects the pc it will still have the old\n\t * value. */\n\tLOG_USER(\"halted at 0x%\" PRIx64 \" due to %s\", info->dpc, cause_string[cause]);\n\n\treturn ERROR_OK;\n}\n\nstatic int poll_target(struct target *target, bool announce)\n{\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\t/* Inhibit debug logging during poll(), which isn't usually interesting and\n\t * just fills up the screen/logs with clutter. */\n\tint old_debug_level = debug_level;\n\tif (debug_level >= LOG_LVL_DEBUG)\n\t\tdebug_level = LOG_LVL_INFO;\n\tbits_t bits = read_bits(target);\n\tdebug_level = old_debug_level;\n\n\tif (bits.haltnot && bits.interrupt) {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\tLOG_DEBUG(\"debug running\");\n\t} else if (bits.haltnot && !bits.interrupt) {\n\t\tif (target->state != TARGET_HALTED)\n\t\t\treturn handle_halt(target, announce);\n\t} else if (!bits.haltnot && bits.interrupt) {\n\t\t/* Target is halting. There is no state for that, so don't change anything. */\n\t\tLOG_DEBUG(\"halting\");\n\t} else if (!bits.haltnot && !bits.interrupt) {\n\t\ttarget->state = TARGET_RUNNING;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv011_poll(struct target *target)\n{\n\treturn poll_target(target, true);\n}\n\nstatic int riscv011_resume(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tRISCV_INFO(r);\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tr->prepped = false;\n\treturn resume(target, debug_execution, false);\n}\n\nstatic int assert_reset(struct target *target)\n{\n\triscv011_info_t *info = get_info(target);\n\t/* TODO: Maybe what I implemented here is more like soft_reset_halt()? */\n\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\t/* The only assumption we can make is that the TAP was reset. */\n\tif (wait_for_debugint_clear(target, true) != ERROR_OK) {\n\t\tLOG_ERROR(\"Debug interrupt didn't clear.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Not sure what we should do when there are multiple cores.\n\t * Here just reset the single hart we're talking to. */\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKM, riscv_ebreakm);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKS, riscv_ebreaks);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKU, riscv_ebreaku);\n\tinfo->dcsr = set_field(info->dcsr, DCSR_EBREAKH, 1);\n\tinfo->dcsr |= DCSR_HALT;\n\tif (target->reset_halt)\n\t\tinfo->dcsr |= DCSR_NDRESET;\n\telse\n\t\tinfo->dcsr |= DCSR_FULLRESET;\n\tdram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false);\n\tdram_write32(target, 1, csrw(S0, CSR_DCSR), false);\n\t/* We shouldn't actually need the jump because a reset should happen. */\n\tdram_write_jump(target, 2, false);\n\tdram_write32(target, 4, info->dcsr, true);\n\tcache_invalidate(target);\n\n\ttarget->state = TARGET_RESET;\n\n\treturn ERROR_OK;\n}\n\nstatic int deassert_reset(struct target *target)\n{\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\tif (target->reset_halt)\n\t\treturn wait_for_state(target, TARGET_HALTED);\n\telse\n\t\treturn wait_for_state(target, TARGET_RUNNING);\n}\n\nstatic int read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tif (increment != size) {\n\t\tLOG_ERROR(\"read_memory with custom increment not implemented\");\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tcache_set32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16));\n\tswitch (size) {\n\t\tcase 1:\n\t\t\tcache_set32(target, 1, lb(S1, S0, 0));\n\t\t\tcache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16));\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tcache_set32(target, 1, lh(S1, S0, 0));\n\t\t\tcache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16));\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tcache_set32(target, 1, lw(S1, S0, 0));\n\t\t\tcache_set32(target, 2, sw(S1, ZERO, DEBUG_RAM_START + 16));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d\", size);\n\t\t\treturn ERROR_FAIL;\n\t}\n\tcache_set_jump(target, 3);\n\tcache_write(target, CACHE_NO_READ, false);\n\n\triscv011_info_t *info = get_info(target);\n\tconst unsigned max_batch_size = 256;\n\tscans_t *scans = scans_new(target, max_batch_size);\n\tif (!scans)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t result_value = 0x777;\n\tuint32_t i = 0;\n\twhile (i < count + 3) {\n\t\tunsigned int batch_size = MIN(count + 3 - i, max_batch_size);\n\t\tscans_reset(scans);\n\n\t\tfor (unsigned int j = 0; j < batch_size; j++) {\n\t\t\tif (i + j == count) {\n\t\t\t\t/* Just insert a read so we can scan out the last value. */\n\t\t\t\tscans_add_read32(scans, 4, false);\n\t\t\t} else if (i + j >= count + 1) {\n\t\t\t\t/* And check for errors. */\n\t\t\t\tscans_add_read32(scans, info->dramsize-1, false);\n\t\t\t} else {\n\t\t\t\t/* Write the next address and set interrupt. */\n\t\t\t\tuint32_t offset = size * (i + j);\n\t\t\t\tscans_add_write32(scans, 4, address + offset, true);\n\t\t\t}\n\t\t}\n\n\t\tint retval = scans_execute(scans);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"JTAG execute failed: %d\", retval);\n\t\t\tgoto error;\n\t\t}\n\n\t\tint dbus_busy = 0;\n\t\tint execute_busy = 0;\n\t\tfor (unsigned int j = 0; j < batch_size; j++) {\n\t\t\tdbus_status_t status = scans_get_u32(scans, j, DBUS_OP_START,\n\t\t\t\t\tDBUS_OP_SIZE);\n\t\t\tswitch (status) {\n\t\t\t\tcase DBUS_STATUS_SUCCESS:\n\t\t\t\t\tbreak;\n\t\t\t\tcase DBUS_STATUS_FAILED:\n\t\t\t\t\tLOG_ERROR(\"Debug RAM write failed. Hardware error?\");\n\t\t\t\t\tgoto error;\n\t\t\t\tcase DBUS_STATUS_BUSY:\n\t\t\t\t\tdbus_busy++;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"Got invalid bus access status: %d\", status);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tuint64_t data = scans_get_u64(scans, j, DBUS_DATA_START,\n\t\t\t\t\tDBUS_DATA_SIZE);\n\t\t\tif (data & DMCONTROL_INTERRUPT)\n\t\t\t\texecute_busy++;\n\t\t\tif (i + j == count + 2) {\n\t\t\t\tresult_value = data;\n\t\t\t} else if (i + j > 1) {\n\t\t\t\tuint32_t offset = size * (i + j - 2);\n\t\t\t\tswitch (size) {\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tbuffer[offset] = data;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tbuffer[offset] = data;\n\t\t\t\t\t\tbuffer[offset+1] = data >> 8;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tbuffer[offset] = data;\n\t\t\t\t\t\tbuffer[offset+1] = data >> 8;\n\t\t\t\t\t\tbuffer[offset+2] = data >> 16;\n\t\t\t\t\t\tbuffer[offset+3] = data >> 24;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tLOG_DEBUG(\"j=%d status=%d data=%09\" PRIx64, j, status, data);\n\t\t}\n\t\tif (dbus_busy)\n\t\t\tincrease_dbus_busy_delay(target);\n\t\tif (execute_busy)\n\t\t\tincrease_interrupt_high_delay(target);\n\t\tif (dbus_busy || execute_busy) {\n\t\t\twait_for_debugint_clear(target, false);\n\n\t\t\t/* Retry. */\n\t\t\tLOG_INFO(\"Retrying memory read starting from 0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" with more delays\", address + size * i);\n\t\t} else {\n\t\t\ti += batch_size;\n\t\t}\n\t}\n\n\tif (result_value != 0) {\n\t\tLOG_USER(\"Core got an exception (0x%x) while reading from 0x%\"\n\t\t\t\tTARGET_PRIxADDR, result_value, address + size * (count-1));\n\t\tif (count > 1) {\n\t\t\tLOG_USER(\"(It may have failed between 0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" and 0x%\" TARGET_PRIxADDR \" as well, but we \"\n\t\t\t\t\t\"didn't check then.)\",\n\t\t\t\t\taddress, address + size * (count-2) + size - 1);\n\t\t}\n\t\tgoto error;\n\t}\n\n\tscans_delete(scans);\n\tcache_clean(target);\n\treturn ERROR_OK;\n\nerror:\n\tscans_delete(scans);\n\tcache_clean(target);\n\treturn ERROR_FAIL;\n}\n\nstatic int setup_write_memory(struct target *target, uint32_t size)\n{\n\tswitch (size) {\n\t\tcase 1:\n\t\t\tcache_set32(target, 0, lb(S0, ZERO, DEBUG_RAM_START + 16));\n\t\t\tcache_set32(target, 1, sb(S0, T0, 0));\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tcache_set32(target, 0, lh(S0, ZERO, DEBUG_RAM_START + 16));\n\t\t\tcache_set32(target, 1, sh(S0, T0, 0));\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tcache_set32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16));\n\t\t\tcache_set32(target, 1, sw(S0, T0, 0));\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d\", size);\n\t\t\treturn ERROR_FAIL;\n\t}\n\tcache_set32(target, 2, addi(T0, T0, size));\n\tcache_set_jump(target, 3);\n\tcache_write(target, 4, false);\n\n\treturn ERROR_OK;\n}\n\nstatic int write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\triscv011_info_t *info = get_info(target);\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\t/* Set up the address. */\n\tcache_set_store(target, 0, T0, SLOT1);\n\tcache_set_load(target, 1, T0, SLOT0);\n\tcache_set_jump(target, 2);\n\tcache_set(target, SLOT0, address);\n\tif (cache_write(target, 5, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t t0 = cache_get(target, SLOT1);\n\tLOG_DEBUG(\"t0 is 0x%\" PRIx64, t0);\n\n\tif (setup_write_memory(target, size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tconst unsigned max_batch_size = 256;\n\tscans_t *scans = scans_new(target, max_batch_size);\n\tif (!scans)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t result_value = 0x777;\n\tuint32_t i = 0;\n\twhile (i < count + 2) {\n\t\tunsigned int batch_size = MIN(count + 2 - i, max_batch_size);\n\t\tscans_reset(scans);\n\n\t\tfor (unsigned int j = 0; j < batch_size; j++) {\n\t\t\tif (i + j >= count) {\n\t\t\t\t/* Check for an exception. */\n\t\t\t\tscans_add_read32(scans, info->dramsize-1, false);\n\t\t\t} else {\n\t\t\t\t/* Write the next value and set interrupt. */\n\t\t\t\tuint32_t value;\n\t\t\t\tuint32_t offset = size * (i + j);\n\t\t\t\tswitch (size) {\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tvalue = buffer[offset];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tvalue = buffer[offset] |\n\t\t\t\t\t\t\t(buffer[offset+1] << 8);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tvalue = buffer[offset] |\n\t\t\t\t\t\t\t((uint32_t) buffer[offset+1] << 8) |\n\t\t\t\t\t\t\t((uint32_t) buffer[offset+2] << 16) |\n\t\t\t\t\t\t\t((uint32_t) buffer[offset+3] << 24);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\tscans_add_write32(scans, 4, value, true);\n\t\t\t}\n\t\t}\n\n\t\tint retval = scans_execute(scans);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"JTAG execute failed: %d\", retval);\n\t\t\tgoto error;\n\t\t}\n\n\t\tint dbus_busy = 0;\n\t\tint execute_busy = 0;\n\t\tfor (unsigned int j = 0; j < batch_size; j++) {\n\t\t\tdbus_status_t status = scans_get_u32(scans, j, DBUS_OP_START,\n\t\t\t\t\tDBUS_OP_SIZE);\n\t\t\tswitch (status) {\n\t\t\t\tcase DBUS_STATUS_SUCCESS:\n\t\t\t\t\tbreak;\n\t\t\t\tcase DBUS_STATUS_FAILED:\n\t\t\t\t\tLOG_ERROR(\"Debug RAM write failed. Hardware error?\");\n\t\t\t\t\tgoto error;\n\t\t\t\tcase DBUS_STATUS_BUSY:\n\t\t\t\t\tdbus_busy++;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"Got invalid bus access status: %d\", status);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tint interrupt = scans_get_u32(scans, j, DBUS_DATA_START + 33, 1);\n\t\t\tif (interrupt)\n\t\t\t\texecute_busy++;\n\t\t\tif (i + j == count + 1)\n\t\t\t\tresult_value = scans_get_u32(scans, j, DBUS_DATA_START, 32);\n\t\t}\n\t\tif (dbus_busy)\n\t\t\tincrease_dbus_busy_delay(target);\n\t\tif (execute_busy)\n\t\t\tincrease_interrupt_high_delay(target);\n\t\tif (dbus_busy || execute_busy) {\n\t\t\twait_for_debugint_clear(target, false);\n\n\t\t\t/* Retry.\n\t\t\t * Set t0 back to what it should have been at the beginning of this\n\t\t\t * batch. */\n\t\t\tLOG_INFO(\"Retrying memory write starting from 0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" with more delays\", address + size * i);\n\n\t\t\tcache_clean(target);\n\n\t\t\tif (write_gpr(target, T0, address + size * i) != ERROR_OK)\n\t\t\t\tgoto error;\n\n\t\t\tif (setup_write_memory(target, size) != ERROR_OK)\n\t\t\t\tgoto error;\n\t\t} else {\n\t\t\ti += batch_size;\n\t\t}\n\t}\n\n\tif (result_value != 0) {\n\t\tLOG_ERROR(\"Core got an exception (0x%x) while writing to 0x%\"\n\t\t\t\tTARGET_PRIxADDR, result_value, address + size * (count-1));\n\t\tif (count > 1) {\n\t\t\tLOG_ERROR(\"(It may have failed between 0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\" and 0x%\" TARGET_PRIxADDR \" as well, but we \"\n\t\t\t\t\t\"didn't check then.)\",\n\t\t\t\t\taddress, address + size * (count-2) + size - 1);\n\t\t}\n\t\tgoto error;\n\t}\n\n\tscans_delete(scans);\n\tcache_clean(target);\n\treturn register_write(target, T0, t0);\n\nerror:\n\tscans_delete(scans);\n\tcache_clean(target);\n\treturn ERROR_FAIL;\n}\n\nstatic int arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic COMMAND_HELPER(riscv011_print_info, struct target *target)\n{\n\t/* Abstract description. */\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running8\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running8\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running16\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running16\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running32\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running32\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running64\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running64\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running128\", 0);\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running128\", 0);\n\n\tuint32_t dminfo = dbus_read(target, DMINFO);\n\triscv_print_info_line(CMD, \"dm\", \"authenticated\", get_field(dminfo, DMINFO_AUTHENTICATED));\n\n\treturn 0;\n}\n\nstatic int wait_for_authbusy(struct target *target)\n{\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tuint32_t dminfo = dbus_read(target, DMINFO);\n\t\tif (!get_field(dminfo, DMINFO_AUTHBUSY))\n\t\t\tbreak;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out after %ds waiting for authbusy to go low (dminfo=0x%x). \"\n\t\t\t\t\t\"Increase the timeout with riscv set_command_timeout_sec.\",\n\t\t\t\t\triscv_command_timeout_sec,\n\t\t\t\t\tdminfo);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv011_authdata_read(struct target *target, uint32_t *value, unsigned int index)\n{\n\tif (index > 1) {\n\t\tLOG_ERROR(\"Spec 0.11 only has a two authdata registers.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (wait_for_authbusy(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint16_t authdata_address = index ? DMAUTHDATA1 : DMAUTHDATA0;\n\t*value = dbus_read(target, authdata_address);\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv011_authdata_write(struct target *target, uint32_t value, unsigned int index)\n{\n\tif (index > 1) {\n\t\tLOG_ERROR(\"Spec 0.11 only has a two authdata registers.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (wait_for_authbusy(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint16_t authdata_address = index ? DMAUTHDATA1 : DMAUTHDATA0;\n\tdbus_write(target, authdata_address, value);\n\n\treturn ERROR_OK;\n}\n\nstatic int init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tLOG_DEBUG(\"init\");\n\tRISCV_INFO(generic_info);\n\tgeneric_info->get_register = get_register;\n\tgeneric_info->set_register = set_register;\n\tgeneric_info->read_memory = read_memory;\n\tgeneric_info->authdata_read = &riscv011_authdata_read;\n\tgeneric_info->authdata_write = &riscv011_authdata_write;\n\tgeneric_info->print_info = &riscv011_print_info;\n\n\tgeneric_info->version_specific = calloc(1, sizeof(riscv011_info_t));\n\tif (!generic_info->version_specific)\n\t\treturn ERROR_FAIL;\n\n\t/* Assume 32-bit until we discover the real value in examine(). */\n\tgeneric_info->xlen = 32;\n\triscv_init_registers(target);\n\n\treturn ERROR_OK;\n}\n\nstruct target_type riscv011_target = {\n\t.name = \"riscv\",\n\n\t.init_target = init_target,\n\t.deinit_target = deinit_target,\n\t.examine = examine,\n\n\t/* poll current target status */\n\t.poll = riscv011_poll,\n\n\t.halt = halt,\n\t.resume = riscv011_resume,\n\t.step = step,\n\n\t.assert_reset = assert_reset,\n\t.deassert_reset = deassert_reset,\n\n\t.write_memory = write_memory,\n\n\t.arch_state = arch_state,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/riscv-013.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Support for RISC-V, debug version 0.13, which is currently (2/4/17) the\n * latest draft.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <time.h>\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target/target.h\"\n#include \"target/algorithm.h\"\n#include \"target/target_type.h\"\n#include <helper/log.h>\n#include \"jtag/jtag.h\"\n#include \"target/register.h\"\n#include \"target/breakpoints.h\"\n#include \"helper/time_support.h\"\n#include \"helper/list.h\"\n#include \"riscv.h\"\n#include \"debug_defines.h\"\n#include \"rtos/rtos.h\"\n#include \"program.h\"\n#include \"asm.h\"\n#include \"batch.h\"\n\nstatic int riscv013_on_step_or_resume(struct target *target, bool step);\nstatic int riscv013_step_or_resume_current_hart(struct target *target,\n\t\tbool step, bool use_hasel);\nstatic void riscv013_clear_abstract_error(struct target *target);\n\n/* Implementations of the functions in struct riscv_info. */\nstatic int riscv013_get_register(struct target *target,\n\t\triscv_reg_t *value, int rid);\nstatic int riscv013_set_register(struct target *target, int regid, uint64_t value);\nstatic int riscv013_select_current_hart(struct target *target);\nstatic int riscv013_halt_prep(struct target *target);\nstatic int riscv013_halt_go(struct target *target);\nstatic int riscv013_resume_go(struct target *target);\nstatic int riscv013_step_current_hart(struct target *target);\nstatic int riscv013_on_halt(struct target *target);\nstatic int riscv013_on_step(struct target *target);\nstatic int riscv013_resume_prep(struct target *target);\nstatic bool riscv013_is_halted(struct target *target);\nstatic enum riscv_halt_reason riscv013_halt_reason(struct target *target);\nstatic int riscv013_write_debug_buffer(struct target *target, unsigned index,\n\t\triscv_insn_t d);\nstatic riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned\n\t\tindex);\nstatic int riscv013_execute_debug_buffer(struct target *target);\nstatic void riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);\nstatic void riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a);\nstatic int riscv013_dmi_write_u64_bits(struct target *target);\nstatic void riscv013_fill_dmi_nop_u64(struct target *target, char *buf);\nstatic int register_read(struct target *target, uint64_t *value, uint32_t number);\nstatic int register_read_direct(struct target *target, uint64_t *value, uint32_t number);\nstatic int register_write_direct(struct target *target, unsigned number,\n\t\tuint64_t value);\nstatic int read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);\nstatic int write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\n\n/**\n * Since almost everything can be accomplish by scanning the dbus register, all\n * functions here assume dbus is already selected. The exception are functions\n * called directly by OpenOCD, which can't assume anything about what's\n * currently in IR. They should set IR to dbus explicitly.\n */\n\n#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))\n#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))\n\n#define CSR_DCSR_CAUSE_SWBP\t\t1\n#define CSR_DCSR_CAUSE_TRIGGER\t2\n#define CSR_DCSR_CAUSE_DEBUGINT\t3\n#define CSR_DCSR_CAUSE_STEP\t\t4\n#define CSR_DCSR_CAUSE_HALT\t\t5\n#define CSR_DCSR_CAUSE_GROUP\t6\n\n#define RISCV013_INFO(r) riscv013_info_t *r = get_info(target)\n\n/*** JTAG registers. ***/\n\ntypedef enum {\n\tDMI_OP_NOP = 0,\n\tDMI_OP_READ = 1,\n\tDMI_OP_WRITE = 2\n} dmi_op_t;\ntypedef enum {\n\tDMI_STATUS_SUCCESS = 0,\n\tDMI_STATUS_FAILED = 2,\n\tDMI_STATUS_BUSY = 3\n} dmi_status_t;\n\ntypedef enum slot {\n\tSLOT0,\n\tSLOT1,\n\tSLOT_LAST,\n} slot_t;\n\n/*** Debug Bus registers. ***/\n\n#define CMDERR_NONE\t\t\t\t0\n#define CMDERR_BUSY\t\t\t\t1\n#define CMDERR_NOT_SUPPORTED\t2\n#define CMDERR_EXCEPTION\t\t3\n#define CMDERR_HALT_RESUME\t\t4\n#define CMDERR_OTHER\t\t\t7\n\n/*** Info about the core being debugged. ***/\n\nstruct trigger {\n\tuint64_t address;\n\tuint32_t length;\n\tuint64_t mask;\n\tuint64_t value;\n\tbool read, write, execute;\n\tint unique_id;\n};\n\ntypedef enum {\n\tYNM_MAYBE,\n\tYNM_YES,\n\tYNM_NO\n} yes_no_maybe_t;\n\ntypedef struct {\n\tstruct list_head list;\n\tint abs_chain_position;\n\n\t/* The number of harts connected to this DM. */\n\tint hart_count;\n\t/* Indicates we already reset this DM, so don't need to do it again. */\n\tbool was_reset;\n\t/* Targets that are connected to this DM. */\n\tstruct list_head target_list;\n\t/* The currently selected hartid on this DM. */\n\tint current_hartid;\n\tbool hasel_supported;\n\n\t/* The program buffer stores executable code. 0 is an illegal instruction,\n\t * so we use 0 to mean the cached value is invalid. */\n\tuint32_t progbuf_cache[16];\n} dm013_info_t;\n\ntypedef struct {\n\tstruct list_head list;\n\tstruct target *target;\n} target_list_t;\n\ntypedef struct {\n\t/* The indexed used to address this hart in its DM. */\n\tunsigned index;\n\t/* Number of address bits in the dbus register. */\n\tunsigned abits;\n\t/* Number of abstract command data registers. */\n\tunsigned datacount;\n\t/* Number of words in the Program Buffer. */\n\tunsigned progbufsize;\n\n\t/* We cache the read-only bits of sbcs here. */\n\tuint32_t sbcs;\n\n\tyes_no_maybe_t progbuf_writable;\n\t/* We only need the address so that we know the alignment of the buffer. */\n\triscv_addr_t progbuf_address;\n\n\t/* Number of run-test/idle cycles the target requests we do after each dbus\n\t * access. */\n\tunsigned int dtmcs_idle;\n\n\t/* This value is incremented every time a dbus access comes back as \"busy\".\n\t * It's used to determine how many run-test/idle cycles to feed the target\n\t * in between accesses. */\n\tunsigned int dmi_busy_delay;\n\n\t/* Number of run-test/idle cycles to add between consecutive bus master\n\t * reads/writes respectively. */\n\tunsigned int bus_master_write_delay, bus_master_read_delay;\n\n\t/* This value is increased every time we tried to execute two commands\n\t * consecutively, and the second one failed because the previous hadn't\n\t * completed yet.  It's used to add extra run-test/idle cycles after\n\t * starting a command, so we don't have to waste time checking for busy to\n\t * go low. */\n\tunsigned int ac_busy_delay;\n\n\tbool abstract_read_csr_supported;\n\tbool abstract_write_csr_supported;\n\tbool abstract_read_fpr_supported;\n\tbool abstract_write_fpr_supported;\n\n\tyes_no_maybe_t has_aampostincrement;\n\n\t/* When a function returns some error due to a failure indicated by the\n\t * target in cmderr, the caller can look here to see what that error was.\n\t * (Compare with errno.) */\n\tuint8_t cmderr;\n\n\t/* Some fields from hartinfo. */\n\tuint8_t datasize;\n\tuint8_t dataaccess;\n\tint16_t dataaddr;\n\n\t/* The width of the hartsel field. */\n\tunsigned hartsellen;\n\n\t/* DM that provides access to this target. */\n\tdm013_info_t *dm;\n} riscv013_info_t;\n\nstatic LIST_HEAD(dm_list);\n\nstatic riscv013_info_t *get_info(const struct target *target)\n{\n\tstruct riscv_info *info = target->arch_info;\n\tassert(info);\n\tassert(info->version_specific);\n\treturn info->version_specific;\n}\n\n/**\n * Return the DM structure for this target. If there isn't one, find it in the\n * global list of DMs. If it's not in there, then create one and initialize it\n * to 0.\n */\nstatic dm013_info_t *get_dm(struct target *target)\n{\n\tRISCV013_INFO(info);\n\tif (info->dm)\n\t\treturn info->dm;\n\n\tint abs_chain_position = target->tap->abs_chain_position;\n\n\tdm013_info_t *entry;\n\tdm013_info_t *dm = NULL;\n\tlist_for_each_entry(entry, &dm_list, list) {\n\t\tif (entry->abs_chain_position == abs_chain_position) {\n\t\t\tdm = entry;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (!dm) {\n\t\tLOG_DEBUG(\"[%d] Allocating new DM\", target->coreid);\n\t\tdm = calloc(1, sizeof(dm013_info_t));\n\t\tif (!dm)\n\t\t\treturn NULL;\n\t\tdm->abs_chain_position = abs_chain_position;\n\t\tdm->current_hartid = -1;\n\t\tdm->hart_count = -1;\n\t\tINIT_LIST_HEAD(&dm->target_list);\n\t\tlist_add(&dm->list, &dm_list);\n\t}\n\n\tinfo->dm = dm;\n\ttarget_list_t *target_entry;\n\tlist_for_each_entry(target_entry, &dm->target_list, list) {\n\t\tif (target_entry->target == target)\n\t\t\treturn dm;\n\t}\n\ttarget_entry = calloc(1, sizeof(*target_entry));\n\tif (!target_entry) {\n\t\tinfo->dm = NULL;\n\t\treturn NULL;\n\t}\n\ttarget_entry->target = target;\n\tlist_add(&target_entry->list, &dm->target_list);\n\n\treturn dm;\n}\n\nstatic uint32_t set_hartsel(uint32_t initial, uint32_t index)\n{\n\tinitial &= ~DM_DMCONTROL_HARTSELLO;\n\tinitial &= ~DM_DMCONTROL_HARTSELHI;\n\n\tuint32_t index_lo = index & ((1 << DM_DMCONTROL_HARTSELLO_LENGTH) - 1);\n\tinitial |= index_lo << DM_DMCONTROL_HARTSELLO_OFFSET;\n\tuint32_t index_hi = index >> DM_DMCONTROL_HARTSELLO_LENGTH;\n\tassert(index_hi < 1 << DM_DMCONTROL_HARTSELHI_LENGTH);\n\tinitial |= index_hi << DM_DMCONTROL_HARTSELHI_OFFSET;\n\n\treturn initial;\n}\n\nstatic void decode_dmi(char *text, unsigned address, unsigned data)\n{\n\tstatic const struct {\n\t\tunsigned address;\n\t\tuint64_t mask;\n\t\tconst char *name;\n\t} description[] = {\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_HALTREQ, \"haltreq\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_RESUMEREQ, \"resumereq\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_HARTRESET, \"hartreset\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_HASEL, \"hasel\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_HARTSELHI, \"hartselhi\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_HARTSELLO, \"hartsello\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_NDMRESET, \"ndmreset\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_DMACTIVE, \"dmactive\" },\n\t\t{ DM_DMCONTROL, DM_DMCONTROL_ACKHAVERESET, \"ackhavereset\" },\n\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_IMPEBREAK, \"impebreak\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLHAVERESET, \"allhavereset\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYHAVERESET, \"anyhavereset\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLRESUMEACK, \"allresumeack\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYRESUMEACK, \"anyresumeack\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLNONEXISTENT, \"allnonexistent\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYNONEXISTENT, \"anynonexistent\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLUNAVAIL, \"allunavail\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYUNAVAIL, \"anyunavail\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLRUNNING, \"allrunning\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYRUNNING, \"anyrunning\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ALLHALTED, \"allhalted\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_ANYHALTED, \"anyhalted\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_AUTHENTICATED, \"authenticated\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_AUTHBUSY, \"authbusy\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_HASRESETHALTREQ, \"hasresethaltreq\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_CONFSTRPTRVALID, \"confstrptrvalid\" },\n\t\t{ DM_DMSTATUS, DM_DMSTATUS_VERSION, \"version\" },\n\n\t\t{ DM_ABSTRACTCS, DM_ABSTRACTCS_PROGBUFSIZE, \"progbufsize\" },\n\t\t{ DM_ABSTRACTCS, DM_ABSTRACTCS_BUSY, \"busy\" },\n\t\t{ DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR, \"cmderr\" },\n\t\t{ DM_ABSTRACTCS, DM_ABSTRACTCS_DATACOUNT, \"datacount\" },\n\n\t\t{ DM_COMMAND, DM_COMMAND_CMDTYPE, \"cmdtype\" },\n\n\t\t{ DM_SBCS, DM_SBCS_SBVERSION, \"sbversion\" },\n\t\t{ DM_SBCS, DM_SBCS_SBBUSYERROR, \"sbbusyerror\" },\n\t\t{ DM_SBCS, DM_SBCS_SBBUSY, \"sbbusy\" },\n\t\t{ DM_SBCS, DM_SBCS_SBREADONADDR, \"sbreadonaddr\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS, \"sbaccess\" },\n\t\t{ DM_SBCS, DM_SBCS_SBAUTOINCREMENT, \"sbautoincrement\" },\n\t\t{ DM_SBCS, DM_SBCS_SBREADONDATA, \"sbreadondata\" },\n\t\t{ DM_SBCS, DM_SBCS_SBERROR, \"sberror\" },\n\t\t{ DM_SBCS, DM_SBCS_SBASIZE, \"sbasize\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS128, \"sbaccess128\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS64, \"sbaccess64\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS32, \"sbaccess32\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS16, \"sbaccess16\" },\n\t\t{ DM_SBCS, DM_SBCS_SBACCESS8, \"sbaccess8\" },\n\t};\n\n\ttext[0] = 0;\n\tfor (unsigned i = 0; i < ARRAY_SIZE(description); i++) {\n\t\tif (description[i].address == address) {\n\t\t\tuint64_t mask = description[i].mask;\n\t\t\tunsigned value = get_field(data, mask);\n\t\t\tif (value) {\n\t\t\t\tif (i > 0)\n\t\t\t\t\t*(text++) = ' ';\n\t\t\t\tif (mask & (mask >> 1)) {\n\t\t\t\t\t/* If the field is more than 1 bit wide. */\n\t\t\t\t\tsprintf(text, \"%s=%d\", description[i].name, value);\n\t\t\t\t} else {\n\t\t\t\t\tstrcpy(text, description[i].name);\n\t\t\t\t}\n\t\t\t\ttext += strlen(text);\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic void dump_field(int idle, const struct scan_field *field)\n{\n\tstatic const char * const op_string[] = {\"-\", \"r\", \"w\", \"?\"};\n\tstatic const char * const status_string[] = {\"+\", \"?\", \"F\", \"b\"};\n\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn;\n\n\tuint64_t out = buf_get_u64(field->out_value, 0, field->num_bits);\n\tunsigned int out_op = get_field(out, DTM_DMI_OP);\n\tunsigned int out_data = get_field(out, DTM_DMI_DATA);\n\tunsigned int out_address = out >> DTM_DMI_ADDRESS_OFFSET;\n\n\tuint64_t in = buf_get_u64(field->in_value, 0, field->num_bits);\n\tunsigned int in_op = get_field(in, DTM_DMI_OP);\n\tunsigned int in_data = get_field(in, DTM_DMI_DATA);\n\tunsigned int in_address = in >> DTM_DMI_ADDRESS_OFFSET;\n\n\tlog_printf_lf(LOG_LVL_DEBUG,\n\t\t\t__FILE__, __LINE__, \"scan\",\n\t\t\t\"%db %s %08x @%02x -> %s %08x @%02x; %di\",\n\t\t\tfield->num_bits, op_string[out_op], out_data, out_address,\n\t\t\tstatus_string[in_op], in_data, in_address, idle);\n\n\tchar out_text[500];\n\tchar in_text[500];\n\tdecode_dmi(out_text, out_address, out_data);\n\tdecode_dmi(in_text, in_address, in_data);\n\tif (in_text[0] || out_text[0]) {\n\t\tlog_printf_lf(LOG_LVL_DEBUG, __FILE__, __LINE__, \"scan\", \"%s -> %s\",\n\t\t\t\tout_text, in_text);\n\t}\n}\n\n/*** Utility functions. ***/\n\nstatic void select_dmi(struct target *target)\n{\n\tif (bscan_tunnel_ir_width != 0) {\n\t\tselect_dmi_via_bscan(target);\n\t\treturn;\n\t}\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n}\n\nstatic uint32_t dtmcontrol_scan(struct target *target, uint32_t out)\n{\n\tstruct scan_field field;\n\tuint8_t in_value[4];\n\tuint8_t out_value[4] = { 0 };\n\n\tif (bscan_tunnel_ir_width != 0)\n\t\treturn dtmcontrol_scan_via_bscan(target, out);\n\n\tbuf_set_u32(out_value, 0, 32, out);\n\n\tjtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);\n\n\tfield.num_bits = 32;\n\tfield.out_value = out_value;\n\tfield.in_value = in_value;\n\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\n\t/* Always return to dmi. */\n\tselect_dmi(target);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\n\tuint32_t in = buf_get_u32(field.in_value, 0, 32);\n\tLOG_DEBUG(\"DTMCS: 0x%x -> 0x%x\", out, in);\n\n\treturn in;\n}\n\nstatic void increase_dmi_busy_delay(struct target *target)\n{\n\triscv013_info_t *info = get_info(target);\n\tinfo->dmi_busy_delay += info->dmi_busy_delay / 10 + 1;\n\tLOG_DEBUG(\"dtmcs_idle=%d, dmi_busy_delay=%d, ac_busy_delay=%d\",\n\t\t\tinfo->dtmcs_idle, info->dmi_busy_delay,\n\t\t\tinfo->ac_busy_delay);\n\n\tdtmcontrol_scan(target, DTM_DTMCS_DMIRESET);\n}\n\n/**\n * exec: If this is set, assume the scan results in an execution, so more\n * run-test/idle cycles may be required.\n */\nstatic dmi_status_t dmi_scan(struct target *target, uint32_t *address_in,\n\t\tuint32_t *data_in, dmi_op_t op, uint32_t address_out, uint32_t data_out,\n\t\tbool exec)\n{\n\triscv013_info_t *info = get_info(target);\n\tRISCV_INFO(r);\n\tunsigned num_bits = info->abits + DTM_DMI_OP_LENGTH + DTM_DMI_DATA_LENGTH;\n\tsize_t num_bytes = (num_bits + 7) / 8;\n\tuint8_t in[num_bytes];\n\tuint8_t out[num_bytes];\n\tstruct scan_field field = {\n\t\t.num_bits = num_bits,\n\t\t.out_value = out,\n\t\t.in_value = in\n\t};\n\triscv_bscan_tunneled_scan_context_t bscan_ctxt;\n\n\tif (r->reset_delays_wait >= 0) {\n\t\tr->reset_delays_wait--;\n\t\tif (r->reset_delays_wait < 0) {\n\t\t\tinfo->dmi_busy_delay = 0;\n\t\t\tinfo->ac_busy_delay = 0;\n\t\t}\n\t}\n\n\tmemset(in, 0, num_bytes);\n\tmemset(out, 0, num_bytes);\n\n\tassert(info->abits != 0);\n\n\tbuf_set_u32(out, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, op);\n\tbuf_set_u32(out, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, data_out);\n\tbuf_set_u32(out, DTM_DMI_ADDRESS_OFFSET, info->abits, address_out);\n\n\t/* I wanted to place this code in a different function, but the way JTAG command\n\t   queueing works in the jtag handling functions, the scan fields either have to be\n\t   heap allocated, global/static, or else they need to stay on the stack until\n\t   the jtag_execute_queue() call.  Heap or static fields in this case doesn't seem\n\t   the best fit.  Declaring stack based field values in a subsidiary function call wouldn't\n\t   work. */\n\tif (bscan_tunnel_ir_width != 0) {\n\t\triscv_add_bscan_tunneled_scan(target, &field, &bscan_ctxt);\n\t} else {\n\t\t/* Assume dbus is already selected. */\n\t\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\t}\n\n\tint idle_count = info->dmi_busy_delay;\n\tif (exec)\n\t\tidle_count += info->ac_busy_delay;\n\n\tif (idle_count)\n\t\tjtag_add_runtest(idle_count, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"dmi_scan failed jtag scan\");\n\t\tif (data_in)\n\t\t\t*data_in = ~0;\n\t\treturn DMI_STATUS_FAILED;\n\t}\n\n\tif (bscan_tunnel_ir_width != 0) {\n\t\t/* need to right-shift \"in\" by one bit, because of clock skew between BSCAN TAP and DM TAP */\n\t\tbuffer_shr(in, num_bytes, 1);\n\t}\n\n\tif (data_in)\n\t\t*data_in = buf_get_u32(in, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH);\n\n\tif (address_in)\n\t\t*address_in = buf_get_u32(in, DTM_DMI_ADDRESS_OFFSET, info->abits);\n\tdump_field(idle_count, &field);\n\treturn buf_get_u32(in, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH);\n}\n\n/**\n * @param target\n * @param data_in  The data we received from the target.\n * @param dmi_busy_encountered\n *                 If non-NULL, will be updated to reflect whether DMI busy was\n *                 encountered while executing this operation or not.\n * @param dmi_op   The operation to perform (read/write/nop).\n * @param address  The address argument to that operation.\n * @param data_out The data to send to the target.\n * @param timeout_sec\n * @param exec     When true, this scan will execute something, so extra RTI\n *                 cycles may be added.\n * @param ensure_success\n *                 Scan a nop after the requested operation, ensuring the\n *                 DMI operation succeeded.\n */\nstatic int dmi_op_timeout(struct target *target, uint32_t *data_in,\n\t\tbool *dmi_busy_encountered, int dmi_op, uint32_t address,\n\t\tuint32_t data_out, int timeout_sec, bool exec, bool ensure_success)\n{\n\tselect_dmi(target);\n\n\tdmi_status_t status;\n\tuint32_t address_in;\n\n\tif (dmi_busy_encountered)\n\t\t*dmi_busy_encountered = false;\n\n\tconst char *op_name;\n\tswitch (dmi_op) {\n\t\tcase DMI_OP_NOP:\n\t\t\top_name = \"nop\";\n\t\t\tbreak;\n\t\tcase DMI_OP_READ:\n\t\t\top_name = \"read\";\n\t\t\tbreak;\n\t\tcase DMI_OP_WRITE:\n\t\t\top_name = \"write\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Invalid DMI operation: %d\", dmi_op);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tkeep_alive();\n\n\ttime_t start = time(NULL);\n\t/* This first loop performs the request.  Note that if for some reason this\n\t * stays busy, it is actually due to the previous access. */\n\twhile (1) {\n\t\tstatus = dmi_scan(target, NULL, NULL, dmi_op, address, data_out,\n\t\t\t\texec);\n\t\tif (status == DMI_STATUS_BUSY) {\n\t\t\tincrease_dmi_busy_delay(target);\n\t\t\tif (dmi_busy_encountered)\n\t\t\t\t*dmi_busy_encountered = true;\n\t\t} else if (status == DMI_STATUS_SUCCESS) {\n\t\t\tbreak;\n\t\t} else {\n\t\t\tLOG_ERROR(\"failed %s at 0x%x, status=%d\", op_name, address, status);\n\t\t\tdtmcontrol_scan(target, DTM_DTMCS_DMIRESET);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tif (time(NULL) - start > timeout_sec)\n\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t}\n\n\tif (status != DMI_STATUS_SUCCESS) {\n\t\tLOG_ERROR(\"Failed %s at 0x%x; status=%d\", op_name, address, status);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (ensure_success) {\n\t\t/* This second loop ensures the request succeeded, and gets back data.\n\t\t * Note that NOP can result in a 'busy' result as well, but that would be\n\t\t * noticed on the next DMI access we do. */\n\t\twhile (1) {\n\t\t\tstatus = dmi_scan(target, &address_in, data_in, DMI_OP_NOP, address, 0,\n\t\t\t\t\tfalse);\n\t\t\tif (status == DMI_STATUS_BUSY) {\n\t\t\t\tincrease_dmi_busy_delay(target);\n\t\t\t\tif (dmi_busy_encountered)\n\t\t\t\t\t*dmi_busy_encountered = true;\n\t\t\t} else if (status == DMI_STATUS_SUCCESS) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tif (data_in) {\n\t\t\t\t\tLOG_ERROR(\"Failed %s (NOP) at 0x%x; value=0x%x, status=%d\",\n\t\t\t\t\t\t\top_name, address, *data_in, status);\n\t\t\t\t} else {\n\t\t\t\t\tLOG_ERROR(\"Failed %s (NOP) at 0x%x; status=%d\", op_name, address,\n\t\t\t\t\t\t\tstatus);\n\t\t\t\t}\n\t\t\t\tdtmcontrol_scan(target, DTM_DTMCS_DMIRESET);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (time(NULL) - start > timeout_sec)\n\t\t\t\treturn ERROR_TIMEOUT_REACHED;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int dmi_op(struct target *target, uint32_t *data_in,\n\t\tbool *dmi_busy_encountered, int dmi_op, uint32_t address,\n\t\tuint32_t data_out, bool exec, bool ensure_success)\n{\n\tint result = dmi_op_timeout(target, data_in, dmi_busy_encountered, dmi_op,\n\t\t\taddress, data_out, riscv_command_timeout_sec, exec, ensure_success);\n\tif (result == ERROR_TIMEOUT_REACHED) {\n\t\tLOG_ERROR(\"DMI operation didn't complete in %d seconds. The target is \"\n\t\t\t\t\"either really slow or broken. You could increase the \"\n\t\t\t\t\"timeout with riscv set_command_timeout_sec.\",\n\t\t\t\triscv_command_timeout_sec);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn result;\n}\n\nstatic int dmi_read(struct target *target, uint32_t *value, uint32_t address)\n{\n\treturn dmi_op(target, value, NULL, DMI_OP_READ, address, 0, false, true);\n}\n\nstatic int dmi_read_exec(struct target *target, uint32_t *value, uint32_t address)\n{\n\treturn dmi_op(target, value, NULL, DMI_OP_READ, address, 0, true, true);\n}\n\nstatic int dmi_write(struct target *target, uint32_t address, uint32_t value)\n{\n\treturn dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, false, true);\n}\n\nstatic int dmi_write_exec(struct target *target, uint32_t address,\n\t\tuint32_t value, bool ensure_success)\n{\n\treturn dmi_op(target, NULL, NULL, DMI_OP_WRITE, address, value, true, ensure_success);\n}\n\nstatic int dmstatus_read_timeout(struct target *target, uint32_t *dmstatus,\n\t\tbool authenticated, unsigned timeout_sec)\n{\n\tint result = dmi_op_timeout(target, dmstatus, NULL, DMI_OP_READ,\n\t\t\tDM_DMSTATUS, 0, timeout_sec, false, true);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\tint dmstatus_version = get_field(*dmstatus, DM_DMSTATUS_VERSION);\n\tif (dmstatus_version != 2 && dmstatus_version != 3) {\n\t\tLOG_ERROR(\"OpenOCD only supports Debug Module version 2 (0.13) and 3 (1.0), not \"\n\t\t\t\t\"%d (dmstatus=0x%x). This error might be caused by a JTAG \"\n\t\t\t\t\"signal issue. Try reducing the JTAG clock speed.\",\n\t\t\t\tget_field(*dmstatus, DM_DMSTATUS_VERSION), *dmstatus);\n\t} else if (authenticated && !get_field(*dmstatus, DM_DMSTATUS_AUTHENTICATED)) {\n\t\tLOG_ERROR(\"Debugger is not authenticated to target Debug Module. \"\n\t\t\t\t\"(dmstatus=0x%x). Use `riscv authdata_read` and \"\n\t\t\t\t\"`riscv authdata_write` commands to authenticate.\", *dmstatus);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int dmstatus_read(struct target *target, uint32_t *dmstatus,\n\t\tbool authenticated)\n{\n\treturn dmstatus_read_timeout(target, dmstatus, authenticated,\n\t\t\triscv_command_timeout_sec);\n}\n\nstatic void increase_ac_busy_delay(struct target *target)\n{\n\triscv013_info_t *info = get_info(target);\n\tinfo->ac_busy_delay += info->ac_busy_delay / 10 + 1;\n\tLOG_DEBUG(\"dtmcs_idle=%d, dmi_busy_delay=%d, ac_busy_delay=%d\",\n\t\t\tinfo->dtmcs_idle, info->dmi_busy_delay,\n\t\t\tinfo->ac_busy_delay);\n}\n\nstatic uint32_t __attribute__((unused)) abstract_register_size(unsigned width)\n{\n\tswitch (width) {\n\t\tcase 32:\n\t\t\treturn set_field(0, AC_ACCESS_REGISTER_AARSIZE, 2);\n\t\tcase 64:\n\t\t\treturn set_field(0, AC_ACCESS_REGISTER_AARSIZE, 3);\n\t\tcase 128:\n\t\t\treturn set_field(0, AC_ACCESS_REGISTER_AARSIZE, 4);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported register width: %d\", width);\n\t\t\treturn 0;\n\t}\n}\n\nstatic int wait_for_idle(struct target *target, uint32_t *abstractcs)\n{\n\tRISCV013_INFO(info);\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tif (dmi_read(target, abstractcs, DM_ABSTRACTCS) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (get_field(*abstractcs, DM_ABSTRACTCS_BUSY) == 0)\n\t\t\treturn ERROR_OK;\n\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tinfo->cmderr = get_field(*abstractcs, DM_ABSTRACTCS_CMDERR);\n\t\t\tif (info->cmderr != CMDERR_NONE) {\n\t\t\t\tconst char *errors[8] = {\n\t\t\t\t\t\"none\",\n\t\t\t\t\t\"busy\",\n\t\t\t\t\t\"not supported\",\n\t\t\t\t\t\"exception\",\n\t\t\t\t\t\"halt/resume\",\n\t\t\t\t\t\"reserved\",\n\t\t\t\t\t\"reserved\",\n\t\t\t\t\t\"other\" };\n\n\t\t\t\tLOG_ERROR(\"Abstract command ended in error '%s' (abstractcs=0x%x)\",\n\t\t\t\t\t\terrors[info->cmderr], *abstractcs);\n\t\t\t}\n\n\t\t\tLOG_ERROR(\"Timed out after %ds waiting for busy to go low (abstractcs=0x%x). \"\n\t\t\t\t\t\"Increase the timeout with riscv set_command_timeout_sec.\",\n\t\t\t\t\triscv_command_timeout_sec,\n\t\t\t\t\t*abstractcs);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n}\n\nstatic int execute_abstract_command(struct target *target, uint32_t command)\n{\n\tRISCV013_INFO(info);\n\tif (debug_level >= LOG_LVL_DEBUG) {\n\t\tswitch (get_field(command, DM_COMMAND_CMDTYPE)) {\n\t\t\tcase 0:\n\t\t\t\tLOG_DEBUG(\"command=0x%x; access register, size=%d, postexec=%d, \"\n\t\t\t\t\t\t\"transfer=%d, write=%d, regno=0x%x\",\n\t\t\t\t\t\tcommand,\n\t\t\t\t\t\t8 << get_field(command, AC_ACCESS_REGISTER_AARSIZE),\n\t\t\t\t\t\tget_field(command, AC_ACCESS_REGISTER_POSTEXEC),\n\t\t\t\t\t\tget_field(command, AC_ACCESS_REGISTER_TRANSFER),\n\t\t\t\t\t\tget_field(command, AC_ACCESS_REGISTER_WRITE),\n\t\t\t\t\t\tget_field(command, AC_ACCESS_REGISTER_REGNO));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_DEBUG(\"command=0x%x\", command);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (dmi_write_exec(target, DM_COMMAND, command, false) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t abstractcs = 0;\n\tint result = wait_for_idle(target, &abstractcs);\n\n\tinfo->cmderr = get_field(abstractcs, DM_ABSTRACTCS_CMDERR);\n\tif (info->cmderr != 0 || result != ERROR_OK) {\n\t\tLOG_DEBUG(\"command 0x%x failed; abstractcs=0x%x\", command, abstractcs);\n\t\t/* Clear the error. */\n\t\tdmi_write(target, DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic riscv_reg_t read_abstract_arg(struct target *target, unsigned index,\n\t\tunsigned size_bits)\n{\n\triscv_reg_t value = 0;\n\tuint32_t v;\n\tunsigned offset = index * size_bits / 32;\n\tswitch (size_bits) {\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d bits\", size_bits);\n\t\t\treturn ~0;\n\t\tcase 64:\n\t\t\tdmi_read(target, &v, DM_DATA0 + offset + 1);\n\t\t\tvalue |= ((uint64_t) v) << 32;\n\t\t\t/* falls through */\n\t\tcase 32:\n\t\t\tdmi_read(target, &v, DM_DATA0 + offset);\n\t\t\tvalue |= v;\n\t}\n\treturn value;\n}\n\nstatic int write_abstract_arg(struct target *target, unsigned index,\n\t\triscv_reg_t value, unsigned size_bits)\n{\n\tunsigned offset = index * size_bits / 32;\n\tswitch (size_bits) {\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d bits\", size_bits);\n\t\t\treturn ERROR_FAIL;\n\t\tcase 64:\n\t\t\tdmi_write(target, DM_DATA0 + offset + 1, value >> 32);\n\t\t\t/* falls through */\n\t\tcase 32:\n\t\t\tdmi_write(target, DM_DATA0 + offset, value);\n\t}\n\treturn ERROR_OK;\n}\n\n/**\n * @par size in bits\n */\nstatic uint32_t access_register_command(struct target *target, uint32_t number,\n\t\tunsigned size, uint32_t flags)\n{\n\tuint32_t command = set_field(0, DM_COMMAND_CMDTYPE, 0);\n\tswitch (size) {\n\t\tcase 32:\n\t\t\tcommand = set_field(command, AC_ACCESS_REGISTER_AARSIZE, 2);\n\t\t\tbreak;\n\t\tcase 64:\n\t\t\tcommand = set_field(command, AC_ACCESS_REGISTER_AARSIZE, 3);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%d-bit register %s not supported.\", size,\n\t\t\t\t\tgdb_regno_name(number));\n\t\t\tassert(0);\n\t}\n\n\tif (number <= GDB_REGNO_XPR31) {\n\t\tcommand = set_field(command, AC_ACCESS_REGISTER_REGNO,\n\t\t\t\t0x1000 + number - GDB_REGNO_ZERO);\n\t} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\tcommand = set_field(command, AC_ACCESS_REGISTER_REGNO,\n\t\t\t\t0x1020 + number - GDB_REGNO_FPR0);\n\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\tcommand = set_field(command, AC_ACCESS_REGISTER_REGNO,\n\t\t\t\tnumber - GDB_REGNO_CSR0);\n\t} else if (number >= GDB_REGNO_COUNT) {\n\t\t/* Custom register. */\n\t\tassert(target->reg_cache->reg_list[number].arch_info);\n\t\triscv_reg_info_t *reg_info = target->reg_cache->reg_list[number].arch_info;\n\t\tassert(reg_info);\n\t\tcommand = set_field(command, AC_ACCESS_REGISTER_REGNO,\n\t\t\t\t0xc000 + reg_info->custom_number);\n\t} else {\n\t\tassert(0);\n\t}\n\n\tcommand |= flags;\n\n\treturn command;\n}\n\nstatic int register_read_abstract(struct target *target, uint64_t *value,\n\t\tuint32_t number, unsigned size)\n{\n\tRISCV013_INFO(info);\n\n\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&\n\t\t\t!info->abstract_read_fpr_supported)\n\t\treturn ERROR_FAIL;\n\tif (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 &&\n\t\t\t!info->abstract_read_csr_supported)\n\t\treturn ERROR_FAIL;\n\t/* The spec doesn't define abstract register numbers for vector registers. */\n\tif (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t command = access_register_command(target, number, size,\n\t\t\tAC_ACCESS_REGISTER_TRANSFER);\n\n\tint result = execute_abstract_command(target, command);\n\tif (result != ERROR_OK) {\n\t\tif (info->cmderr == CMDERR_NOT_SUPPORTED) {\n\t\t\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\t\t\tinfo->abstract_read_fpr_supported = false;\n\t\t\t\tLOG_INFO(\"Disabling abstract command reads from FPRs.\");\n\t\t\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\t\t\tinfo->abstract_read_csr_supported = false;\n\t\t\t\tLOG_INFO(\"Disabling abstract command reads from CSRs.\");\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\tif (value)\n\t\t*value = read_abstract_arg(target, 0, size);\n\n\treturn ERROR_OK;\n}\n\nstatic int register_write_abstract(struct target *target, uint32_t number,\n\t\tuint64_t value, unsigned size)\n{\n\tRISCV013_INFO(info);\n\n\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&\n\t\t\t!info->abstract_write_fpr_supported)\n\t\treturn ERROR_FAIL;\n\tif (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095 &&\n\t\t\t!info->abstract_write_csr_supported)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t command = access_register_command(target, number, size,\n\t\t\tAC_ACCESS_REGISTER_TRANSFER |\n\t\t\tAC_ACCESS_REGISTER_WRITE);\n\n\tif (write_abstract_arg(target, 0, value, size) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tint result = execute_abstract_command(target, command);\n\tif (result != ERROR_OK) {\n\t\tif (info->cmderr == CMDERR_NOT_SUPPORTED) {\n\t\t\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\t\t\tinfo->abstract_write_fpr_supported = false;\n\t\t\t\tLOG_INFO(\"Disabling abstract command writes to FPRs.\");\n\t\t\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\t\t\tinfo->abstract_write_csr_supported = false;\n\t\t\t\tLOG_INFO(\"Disabling abstract command writes to CSRs.\");\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*\n * Sets the AAMSIZE field of a memory access abstract command based on\n * the width (bits).\n */\nstatic uint32_t abstract_memory_size(unsigned width)\n{\n\tswitch (width) {\n\t\tcase 8:\n\t\t\treturn set_field(0, AC_ACCESS_MEMORY_AAMSIZE, 0);\n\t\tcase 16:\n\t\t\treturn set_field(0, AC_ACCESS_MEMORY_AAMSIZE, 1);\n\t\tcase 32:\n\t\t\treturn set_field(0, AC_ACCESS_MEMORY_AAMSIZE, 2);\n\t\tcase 64:\n\t\t\treturn set_field(0, AC_ACCESS_MEMORY_AAMSIZE, 3);\n\t\tcase 128:\n\t\t\treturn set_field(0, AC_ACCESS_MEMORY_AAMSIZE, 4);\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported memory width: %d\", width);\n\t\t\treturn 0;\n\t}\n}\n\n/*\n * Creates a memory access abstract command.\n */\nstatic uint32_t access_memory_command(struct target *target, bool virtual,\n\t\tunsigned width, bool postincrement, bool write)\n{\n\tuint32_t command = set_field(0, AC_ACCESS_MEMORY_CMDTYPE, 2);\n\tcommand = set_field(command, AC_ACCESS_MEMORY_AAMVIRTUAL, virtual);\n\tcommand |= abstract_memory_size(width);\n\tcommand = set_field(command, AC_ACCESS_MEMORY_AAMPOSTINCREMENT,\n\t\t\t\t\t\tpostincrement);\n\tcommand = set_field(command, AC_ACCESS_MEMORY_WRITE, write);\n\n\treturn command;\n}\n\nstatic int examine_progbuf(struct target *target)\n{\n\triscv013_info_t *info = get_info(target);\n\n\tif (info->progbuf_writable != YNM_MAYBE)\n\t\treturn ERROR_OK;\n\n\t/* Figure out if progbuf is writable. */\n\n\tif (info->progbufsize < 1) {\n\t\tinfo->progbuf_writable = YNM_NO;\n\t\tLOG_INFO(\"No program buffer present.\");\n\t\treturn ERROR_OK;\n\t}\n\n\tuint64_t s0;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\triscv_program_insert(&program, auipc(S0));\n\tif (riscv_program_exec(&program, target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (register_read_direct(target, &info->progbuf_address, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\triscv_program_init(&program, target);\n\triscv_program_insert(&program, sw(S0, S0, 0));\n\tint result = riscv_program_exec(&program, target);\n\n\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (result != ERROR_OK) {\n\t\t/* This program might have failed if the program buffer is not\n\t\t * writable. */\n\t\tinfo->progbuf_writable = YNM_NO;\n\t\treturn ERROR_OK;\n\t}\n\n\tuint32_t written;\n\tif (dmi_read(target, &written, DM_PROGBUF0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (written == (uint32_t) info->progbuf_address) {\n\t\tLOG_INFO(\"progbuf is writable at 0x%\" PRIx64,\n\t\t\t\tinfo->progbuf_address);\n\t\tinfo->progbuf_writable = YNM_YES;\n\n\t} else {\n\t\tLOG_INFO(\"progbuf is not writeable at 0x%\" PRIx64,\n\t\t\t\tinfo->progbuf_address);\n\t\tinfo->progbuf_writable = YNM_NO;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int is_fpu_reg(uint32_t gdb_regno)\n{\n\treturn (gdb_regno >= GDB_REGNO_FPR0 && gdb_regno <= GDB_REGNO_FPR31) ||\n\t\t(gdb_regno == GDB_REGNO_CSR0 + CSR_FFLAGS) ||\n\t\t(gdb_regno == GDB_REGNO_CSR0 + CSR_FRM) ||\n\t\t(gdb_regno == GDB_REGNO_CSR0 + CSR_FCSR);\n}\n\nstatic int is_vector_reg(uint32_t gdb_regno)\n{\n\treturn (gdb_regno >= GDB_REGNO_V0 && gdb_regno <= GDB_REGNO_V31) ||\n\t\tgdb_regno == GDB_REGNO_VSTART ||\n\t\tgdb_regno == GDB_REGNO_VXSAT ||\n\t\tgdb_regno == GDB_REGNO_VXRM ||\n\t\tgdb_regno == GDB_REGNO_VL ||\n\t\tgdb_regno == GDB_REGNO_VTYPE ||\n\t\tgdb_regno == GDB_REGNO_VLENB;\n}\n\nstatic int prep_for_register_access(struct target *target, uint64_t *mstatus,\n\t\tint regno)\n{\n\tif (is_fpu_reg(regno) || is_vector_reg(regno)) {\n\t\tif (register_read(target, mstatus, GDB_REGNO_MSTATUS) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (is_fpu_reg(regno) && (*mstatus & MSTATUS_FS) == 0) {\n\t\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS,\n\t\t\t\t\t\tset_field(*mstatus, MSTATUS_FS, 1)) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t} else if (is_vector_reg(regno) && (*mstatus & MSTATUS_VS) == 0) {\n\t\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS,\n\t\t\t\t\t\tset_field(*mstatus, MSTATUS_VS, 1)) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\t*mstatus = 0;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int cleanup_after_register_access(struct target *target,\n\t\tuint64_t mstatus, int regno)\n{\n\tif ((is_fpu_reg(regno) && (mstatus & MSTATUS_FS) == 0) ||\n\t\t\t(is_vector_reg(regno) && (mstatus & MSTATUS_VS) == 0))\n\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\ntypedef enum {\n\tSPACE_DM_DATA,\n\tSPACE_DMI_PROGBUF,\n\tSPACE_DMI_RAM\n} memory_space_t;\n\ntypedef struct {\n\t/* How can the debugger access this memory? */\n\tmemory_space_t memory_space;\n\t/* Memory address to access the scratch memory from the hart. */\n\triscv_addr_t hart_address;\n\t/* Memory address to access the scratch memory from the debugger. */\n\triscv_addr_t debug_address;\n\tstruct working_area *area;\n} scratch_mem_t;\n\n/**\n * Find some scratch memory to be used with the given program.\n */\nstatic int scratch_reserve(struct target *target,\n\t\tscratch_mem_t *scratch,\n\t\tstruct riscv_program *program,\n\t\tunsigned size_bytes)\n{\n\triscv_addr_t alignment = 1;\n\twhile (alignment < size_bytes)\n\t\talignment *= 2;\n\n\tscratch->area = NULL;\n\n\triscv013_info_t *info = get_info(target);\n\n\t/* Option 1: See if data# registers can be used as the scratch memory */\n\tif (info->dataaccess == 1) {\n\t\t/* Sign extend dataaddr. */\n\t\tscratch->hart_address = info->dataaddr;\n\t\tif (info->dataaddr & (1<<11))\n\t\t\tscratch->hart_address |= 0xfffffffffffff000ULL;\n\t\t/* Align. */\n\t\tscratch->hart_address = (scratch->hart_address + alignment - 1) & ~(alignment - 1);\n\n\t\tif ((size_bytes + scratch->hart_address - info->dataaddr + 3) / 4 >=\n\t\t\t\tinfo->datasize) {\n\t\t\tscratch->memory_space = SPACE_DM_DATA;\n\t\t\tscratch->debug_address = (scratch->hart_address - info->dataaddr) / 4;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\t/* Option 2: See if progbuf can be used as the scratch memory */\n\tif (examine_progbuf(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Allow for ebreak at the end of the program. */\n\tunsigned program_size = (program->instruction_count + 1) * 4;\n\tscratch->hart_address = (info->progbuf_address + program_size + alignment - 1) &\n\t\t~(alignment - 1);\n\tif ((info->progbuf_writable == YNM_YES) &&\n\t\t\t((size_bytes + scratch->hart_address - info->progbuf_address + 3) / 4 >=\n\t\t\tinfo->progbufsize)) {\n\t\tscratch->memory_space = SPACE_DMI_PROGBUF;\n\t\tscratch->debug_address = (scratch->hart_address - info->progbuf_address) / 4;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Option 3: User-configured memory area as scratch RAM */\n\tif (target_alloc_working_area(target, size_bytes + alignment - 1,\n\t\t\t\t&scratch->area) == ERROR_OK) {\n\t\tscratch->hart_address = (scratch->area->address + alignment - 1) &\n\t\t\t~(alignment - 1);\n\t\tscratch->memory_space = SPACE_DMI_RAM;\n\t\tscratch->debug_address = scratch->hart_address;\n\t\treturn ERROR_OK;\n\t}\n\n\tLOG_ERROR(\"Couldn't find %d bytes of scratch RAM to use. Please configure \"\n\t\t\t\"a work area with 'configure -work-area-phys'.\", size_bytes);\n\treturn ERROR_FAIL;\n}\n\nstatic int scratch_release(struct target *target,\n\t\tscratch_mem_t *scratch)\n{\n\treturn target_free_working_area(target, scratch->area);\n}\n\nstatic int scratch_read64(struct target *target, scratch_mem_t *scratch,\n\t\tuint64_t *value)\n{\n\tuint32_t v;\n\tswitch (scratch->memory_space) {\n\t\tcase SPACE_DM_DATA:\n\t\t\tif (dmi_read(target, &v, DM_DATA0 + scratch->debug_address) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t*value = v;\n\t\t\tif (dmi_read(target, &v, DM_DATA1 + scratch->debug_address) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t*value |= ((uint64_t) v) << 32;\n\t\t\tbreak;\n\t\tcase SPACE_DMI_PROGBUF:\n\t\t\tif (dmi_read(target, &v, DM_PROGBUF0 + scratch->debug_address) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t*value = v;\n\t\t\tif (dmi_read(target, &v, DM_PROGBUF1 + scratch->debug_address) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t*value |= ((uint64_t) v) << 32;\n\t\t\tbreak;\n\t\tcase SPACE_DMI_RAM:\n\t\t\t{\n\t\t\t\tuint8_t buffer[8] = {0};\n\t\t\t\tif (read_memory(target, scratch->debug_address, 4, 2, buffer, 4) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t*value = buffer[0] |\n\t\t\t\t\t(((uint64_t) buffer[1]) << 8) |\n\t\t\t\t\t(((uint64_t) buffer[2]) << 16) |\n\t\t\t\t\t(((uint64_t) buffer[3]) << 24) |\n\t\t\t\t\t(((uint64_t) buffer[4]) << 32) |\n\t\t\t\t\t(((uint64_t) buffer[5]) << 40) |\n\t\t\t\t\t(((uint64_t) buffer[6]) << 48) |\n\t\t\t\t\t(((uint64_t) buffer[7]) << 56);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int scratch_write64(struct target *target, scratch_mem_t *scratch,\n\t\tuint64_t value)\n{\n\tswitch (scratch->memory_space) {\n\t\tcase SPACE_DM_DATA:\n\t\t\tdmi_write(target, DM_DATA0 + scratch->debug_address, value);\n\t\t\tdmi_write(target, DM_DATA1 + scratch->debug_address, value >> 32);\n\t\t\tbreak;\n\t\tcase SPACE_DMI_PROGBUF:\n\t\t\tdmi_write(target, DM_PROGBUF0 + scratch->debug_address, value);\n\t\t\tdmi_write(target, DM_PROGBUF1 + scratch->debug_address, value >> 32);\n\t\t\tbreak;\n\t\tcase SPACE_DMI_RAM:\n\t\t\t{\n\t\t\t\tuint8_t buffer[8] = {\n\t\t\t\t\tvalue,\n\t\t\t\t\tvalue >> 8,\n\t\t\t\t\tvalue >> 16,\n\t\t\t\t\tvalue >> 24,\n\t\t\t\t\tvalue >> 32,\n\t\t\t\t\tvalue >> 40,\n\t\t\t\t\tvalue >> 48,\n\t\t\t\t\tvalue >> 56\n\t\t\t\t};\n\t\t\t\tif (write_memory(target, scratch->debug_address, 4, 2, buffer) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\treturn ERROR_OK;\n}\n\n/** Return register size in bits. */\nstatic unsigned register_size(struct target *target, unsigned number)\n{\n\t/* If reg_cache hasn't been initialized yet, make a guess. We need this for\n\t * when this function is called during examine(). */\n\tif (target->reg_cache)\n\t\treturn target->reg_cache->reg_list[number].size;\n\telse\n\t\treturn riscv_xlen(target);\n}\n\nstatic bool has_sufficient_progbuf(struct target *target, unsigned size)\n{\n\tRISCV013_INFO(info);\n\tRISCV_INFO(r);\n\n\treturn info->progbufsize + r->impebreak >= size;\n}\n\n/**\n * Immediately write the new value to the requested register. This mechanism\n * bypasses any caches.\n */\nstatic int register_write_direct(struct target *target, unsigned number,\n\t\tuint64_t value)\n{\n\tLOG_DEBUG(\"{%d} %s <- 0x%\" PRIx64, riscv_current_hartid(target),\n\t\t\tgdb_regno_name(number), value);\n\n\tint result = register_write_abstract(target, number, value,\n\t\t\tregister_size(target, number));\n\tif (result == ERROR_OK || !has_sufficient_progbuf(target, 2) ||\n\t\t\t!riscv_is_halted(target))\n\t\treturn result;\n\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\n\tuint64_t s0;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t mstatus;\n\tif (prep_for_register_access(target, &mstatus, number) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tscratch_mem_t scratch;\n\tbool use_scratch = false;\n\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&\n\t\t\triscv_supports_extension(target, 'D') &&\n\t\t\triscv_xlen(target) < 64) {\n\t\t/* There are no instructions to move all the bits from a register, so\n\t\t * we need to use some scratch RAM. */\n\t\tuse_scratch = true;\n\t\triscv_program_insert(&program, fld(number - GDB_REGNO_FPR0, S0, 0));\n\n\t\tif (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (register_write_direct(target, GDB_REGNO_S0, scratch.hart_address)\n\t\t\t\t!= ERROR_OK) {\n\t\t\tscratch_release(target, &scratch);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (scratch_write64(target, &scratch, value) != ERROR_OK) {\n\t\t\tscratch_release(target, &scratch);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else if (number == GDB_REGNO_VTYPE) {\n\t\triscv_program_insert(&program, csrr(S0, CSR_VL));\n\t\triscv_program_insert(&program, vsetvli(ZERO, S0, value));\n\n\t} else {\n\t\tif (register_write_direct(target, GDB_REGNO_S0, value) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\t\tif (riscv_supports_extension(target, 'D'))\n\t\t\t\triscv_program_insert(&program, fmv_d_x(number - GDB_REGNO_FPR0, S0));\n\t\t\telse\n\t\t\t\triscv_program_insert(&program, fmv_w_x(number - GDB_REGNO_FPR0, S0));\n\t\t} else if (number == GDB_REGNO_VL) {\n\t\t\t/* \"The XLEN-bit-wide read-only vl CSR can only be updated by the\n\t\t\t * vsetvli and vsetvl instructions, and the fault-only-rst vector\n\t\t\t * load instruction variants.\" */\n\t\t\triscv_reg_t vtype;\n\t\t\tif (register_read(target, &vtype, GDB_REGNO_VTYPE) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tif (riscv_program_insert(&program, vsetvli(ZERO, S0, vtype)) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\t\triscv_program_csrw(&program, S0, number);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Unsupported register (enum gdb_regno)(%d)\", number);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tint exec_out = riscv_program_exec(&program, target);\n\t/* Don't message on error. Probably the register doesn't exist. */\n\tif (exec_out == ERROR_OK && target->reg_cache) {\n\t\tstruct reg *reg = &target->reg_cache->reg_list[number];\n\t\tbuf_set_u64(reg->value, 0, reg->size, value);\n\t}\n\n\tif (use_scratch)\n\t\tscratch_release(target, &scratch);\n\n\tif (cleanup_after_register_access(target, mstatus, number) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Restore S0. */\n\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn exec_out;\n}\n\n/** Read register value from the target. Also update the cached value. */\nstatic int register_read(struct target *target, uint64_t *value, uint32_t number)\n{\n\tif (number == GDB_REGNO_ZERO) {\n\t\t*value = 0;\n\t\treturn ERROR_OK;\n\t}\n\tint result = register_read_direct(target, value, number);\n\tif (result != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (target->reg_cache) {\n\t\tstruct reg *reg = &target->reg_cache->reg_list[number];\n\t\tbuf_set_u64(reg->value, 0, reg->size, *value);\n\t}\n\treturn ERROR_OK;\n}\n\n/** Actually read registers from the target right now. */\nstatic int register_read_direct(struct target *target, uint64_t *value, uint32_t number)\n{\n\tint result = register_read_abstract(target, value, number,\n\t\t\tregister_size(target, number));\n\n\tif (result != ERROR_OK &&\n\t\t\thas_sufficient_progbuf(target, 2) &&\n\t\t\tnumber > GDB_REGNO_XPR31) {\n\t\tstruct riscv_program program;\n\t\triscv_program_init(&program, target);\n\n\t\tscratch_mem_t scratch;\n\t\tbool use_scratch = false;\n\n\t\triscv_reg_t s0;\n\t\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Write program to move data into s0. */\n\n\t\tuint64_t mstatus;\n\t\tif (prep_for_register_access(target, &mstatus, number) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\t\tif (riscv_supports_extension(target, 'D')\n\t\t\t\t\t&& riscv_xlen(target) < 64) {\n\t\t\t\t/* There are no instructions to move all the bits from a\n\t\t\t\t * register, so we need to use some scratch RAM. */\n\t\t\t\triscv_program_insert(&program, fsd(number - GDB_REGNO_FPR0, S0,\n\t\t\t\t\t\t\t0));\n\n\t\t\t\tif (scratch_reserve(target, &scratch, &program, 8) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tuse_scratch = true;\n\n\t\t\t\tif (register_write_direct(target, GDB_REGNO_S0,\n\t\t\t\t\t\t\tscratch.hart_address) != ERROR_OK) {\n\t\t\t\t\tscratch_release(target, &scratch);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t} else if (riscv_supports_extension(target, 'D')) {\n\t\t\t\triscv_program_insert(&program, fmv_x_d(S0, number - GDB_REGNO_FPR0));\n\t\t\t} else {\n\t\t\t\triscv_program_insert(&program, fmv_x_w(S0, number - GDB_REGNO_FPR0));\n\t\t\t}\n\t\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\t\triscv_program_csrr(&program, S0, number);\n\t\t} else {\n\t\t\tLOG_ERROR(\"Unsupported register: %s\", gdb_regno_name(number));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Execute program. */\n\t\tresult = riscv_program_exec(&program, target);\n\t\t/* Don't message on error. Probably the register doesn't exist. */\n\n\t\tif (use_scratch) {\n\t\t\tresult = scratch_read64(target, &scratch, value);\n\t\t\tscratch_release(target, &scratch);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t} else {\n\t\t\t/* Read S0 */\n\t\t\tif (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (cleanup_after_register_access(target, mstatus, number) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Restore S0. */\n\t\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (result == ERROR_OK) {\n\t\tLOG_DEBUG(\"{%d} %s = 0x%\" PRIx64, riscv_current_hartid(target),\n\t\t\t\tgdb_regno_name(number), *value);\n\t}\n\n\treturn result;\n}\n\nstatic int wait_for_authbusy(struct target *target, uint32_t *dmstatus)\n{\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tuint32_t value;\n\t\tif (dmstatus_read(target, &value, false) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (dmstatus)\n\t\t\t*dmstatus = value;\n\t\tif (!get_field(value, DM_DMSTATUS_AUTHBUSY))\n\t\t\tbreak;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out after %ds waiting for authbusy to go low (dmstatus=0x%x). \"\n\t\t\t\t\t\"Increase the timeout with riscv set_command_timeout_sec.\",\n\t\t\t\t\triscv_command_timeout_sec,\n\t\t\t\t\tvalue);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/*** OpenOCD target functions. ***/\n\nstatic void deinit_target(struct target *target)\n{\n\tLOG_DEBUG(\"riscv_deinit_target()\");\n\tstruct riscv_info *info = target->arch_info;\n\tif (!info)\n\t\treturn;\n\n\tfree(info->version_specific);\n\t/* TODO: free register arch_info */\n\tinfo->version_specific = NULL;\n}\n\nstatic int set_haltgroup(struct target *target, bool *supported)\n{\n\tuint32_t write = set_field(DM_DMCS2_HGWRITE, DM_DMCS2_GROUP, target->smp);\n\tif (dmi_write(target, DM_DMCS2, write) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tuint32_t read;\n\tif (dmi_read(target, &read, DM_DMCS2) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*supported = get_field(read, DM_DMCS2_GROUP) == (unsigned)target->smp;\n\treturn ERROR_OK;\n}\n\nstatic int discover_vlenb(struct target *target)\n{\n\tRISCV_INFO(r);\n\triscv_reg_t vlenb;\n\n\tif (register_read(target, &vlenb, GDB_REGNO_VLENB) != ERROR_OK) {\n\t\tLOG_WARNING(\"Couldn't read vlenb for %s; vector register access won't work.\",\n\t\t\t\ttarget_name(target));\n\t\tr->vlenb = 0;\n\t\treturn ERROR_OK;\n\t}\n\tr->vlenb = vlenb;\n\n\tLOG_INFO(\"Vector support with vlenb=%d\", r->vlenb);\n\n\treturn ERROR_OK;\n}\n\nstatic int examine(struct target *target)\n{\n\t/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */\n\n\tuint32_t dtmcontrol = dtmcontrol_scan(target, 0);\n\tLOG_DEBUG(\"dtmcontrol=0x%x\", dtmcontrol);\n\tLOG_DEBUG(\"  dmireset=%d\", get_field(dtmcontrol, DTM_DTMCS_DMIRESET));\n\tLOG_DEBUG(\"  idle=%d\", get_field(dtmcontrol, DTM_DTMCS_IDLE));\n\tLOG_DEBUG(\"  dmistat=%d\", get_field(dtmcontrol, DTM_DTMCS_DMISTAT));\n\tLOG_DEBUG(\"  abits=%d\", get_field(dtmcontrol, DTM_DTMCS_ABITS));\n\tLOG_DEBUG(\"  version=%d\", get_field(dtmcontrol, DTM_DTMCS_VERSION));\n\tif (dtmcontrol == 0) {\n\t\tLOG_ERROR(\"dtmcontrol is 0. Check JTAG connectivity/board power.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (get_field(dtmcontrol, DTM_DTMCS_VERSION) != 1) {\n\t\tLOG_ERROR(\"Unsupported DTM version %d. (dtmcontrol=0x%x)\",\n\t\t\t\tget_field(dtmcontrol, DTM_DTMCS_VERSION), dtmcontrol);\n\t\treturn ERROR_FAIL;\n\t}\n\n\triscv013_info_t *info = get_info(target);\n\t/* TODO: This won't be true if there are multiple DMs. */\n\tinfo->index = target->coreid;\n\tinfo->abits = get_field(dtmcontrol, DTM_DTMCS_ABITS);\n\tinfo->dtmcs_idle = get_field(dtmcontrol, DTM_DTMCS_IDLE);\n\n\t/* Reset the Debug Module. */\n\tdm013_info_t *dm = get_dm(target);\n\tif (!dm)\n\t\treturn ERROR_FAIL;\n\tif (!dm->was_reset) {\n\t\tdmi_write(target, DM_DMCONTROL, 0);\n\t\tdmi_write(target, DM_DMCONTROL, DM_DMCONTROL_DMACTIVE);\n\t\tdm->was_reset = true;\n\t}\n\n\tdmi_write(target, DM_DMCONTROL, DM_DMCONTROL_HARTSELLO |\n\t\t\tDM_DMCONTROL_HARTSELHI | DM_DMCONTROL_DMACTIVE |\n\t\t\tDM_DMCONTROL_HASEL);\n\tuint32_t dmcontrol;\n\tif (dmi_read(target, &dmcontrol, DM_DMCONTROL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (!get_field(dmcontrol, DM_DMCONTROL_DMACTIVE)) {\n\t\tLOG_ERROR(\"Debug Module did not become active. dmcontrol=0x%x\",\n\t\t\t\tdmcontrol);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdm->hasel_supported = get_field(dmcontrol, DM_DMCONTROL_HASEL);\n\n\tuint32_t dmstatus;\n\tif (dmstatus_read(target, &dmstatus, false) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"dmstatus:  0x%08x\", dmstatus);\n\tint dmstatus_version = get_field(dmstatus, DM_DMSTATUS_VERSION);\n\tif (dmstatus_version != 2 && dmstatus_version != 3) {\n\t\t/* Error was already printed out in dmstatus_read(). */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t hartsel =\n\t\t(get_field(dmcontrol, DM_DMCONTROL_HARTSELHI) <<\n\t\t DM_DMCONTROL_HARTSELLO_LENGTH) |\n\t\tget_field(dmcontrol, DM_DMCONTROL_HARTSELLO);\n\tinfo->hartsellen = 0;\n\twhile (hartsel & 1) {\n\t\tinfo->hartsellen++;\n\t\thartsel >>= 1;\n\t}\n\tLOG_DEBUG(\"hartsellen=%d\", info->hartsellen);\n\n\tuint32_t hartinfo;\n\tif (dmi_read(target, &hartinfo, DM_HARTINFO) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tinfo->datasize = get_field(hartinfo, DM_HARTINFO_DATASIZE);\n\tinfo->dataaccess = get_field(hartinfo, DM_HARTINFO_DATAACCESS);\n\tinfo->dataaddr = get_field(hartinfo, DM_HARTINFO_DATAADDR);\n\n\tif (!get_field(dmstatus, DM_DMSTATUS_AUTHENTICATED)) {\n\t\tLOG_ERROR(\"Debugger is not authenticated to target Debug Module. \"\n\t\t\t\t\"(dmstatus=0x%x). Use `riscv authdata_read` and \"\n\t\t\t\t\"`riscv authdata_write` commands to authenticate.\", dmstatus);\n\t\t/* If we return ERROR_FAIL here, then in a multicore setup the next\n\t\t * core won't be examined, which means we won't set up the\n\t\t * authentication commands for them, which means the config script\n\t\t * needs to be a lot more complex. */\n\t\treturn ERROR_OK;\n\t}\n\n\tif (dmi_read(target, &info->sbcs, DM_SBCS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Check that abstract data registers are accessible. */\n\tuint32_t abstractcs;\n\tif (dmi_read(target, &abstractcs, DM_ABSTRACTCS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tinfo->datacount = get_field(abstractcs, DM_ABSTRACTCS_DATACOUNT);\n\tinfo->progbufsize = get_field(abstractcs, DM_ABSTRACTCS_PROGBUFSIZE);\n\n\tLOG_INFO(\"datacount=%d progbufsize=%d\", info->datacount, info->progbufsize);\n\n\tRISCV_INFO(r);\n\tr->impebreak = get_field(dmstatus, DM_DMSTATUS_IMPEBREAK);\n\n\tif (!has_sufficient_progbuf(target, 2)) {\n\t\tLOG_WARNING(\"We won't be able to execute fence instructions on this \"\n\t\t\t\t\"target. Memory may not always appear consistent. \"\n\t\t\t\t\"(progbufsize=%d, impebreak=%d)\", info->progbufsize,\n\t\t\t\tr->impebreak);\n\t}\n\n\tif (info->progbufsize < 4 && riscv_enable_virtual) {\n\t\tLOG_ERROR(\"set_enable_virtual is not available on this target. It \"\n\t\t\t\t\"requires a program buffer size of at least 4. (progbufsize=%d) \"\n\t\t\t\t\"Use `riscv set_enable_virtual off` to continue.\"\n\t\t\t\t\t, info->progbufsize);\n\t}\n\n\t/* Before doing anything else we must first enumerate the harts. */\n\tif (dm->hart_count < 0) {\n\t\tfor (int i = 0; i < MIN(RISCV_MAX_HARTS, 1 << info->hartsellen); ++i) {\n\t\t\tr->current_hartid = i;\n\t\t\tif (riscv013_select_current_hart(target) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\n\t\t\tuint32_t s;\n\t\t\tif (dmstatus_read(target, &s, true) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tif (get_field(s, DM_DMSTATUS_ANYNONEXISTENT))\n\t\t\t\tbreak;\n\t\t\tdm->hart_count = i + 1;\n\n\t\t\tif (get_field(s, DM_DMSTATUS_ANYHAVERESET))\n\t\t\t\tdmi_write(target, DM_DMCONTROL,\n\t\t\t\t\t\tset_hartsel(DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_ACKHAVERESET, i));\n\t\t}\n\n\t\tLOG_DEBUG(\"Detected %d harts.\", dm->hart_count);\n\t}\n\n\tr->current_hartid = target->coreid;\n\n\tif (dm->hart_count == 0) {\n\t\tLOG_ERROR(\"No harts found!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Don't call any riscv_* functions until after we've counted the number of\n\t * cores and initialized registers. */\n\n\tif (riscv013_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tbool halted = riscv_is_halted(target);\n\tif (!halted) {\n\t\tif (riscv013_halt_go(target) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Fatal: Hart %d failed to halt during examine()\", r->current_hartid);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\t/* Without knowing anything else we can at least mess with the\n\t\t* program buffer. */\n\tr->debug_buffer_size = info->progbufsize;\n\n\tint result = register_read_abstract(target, NULL, GDB_REGNO_S0, 64);\n\tif (result == ERROR_OK)\n\t\tr->xlen = 64;\n\telse\n\t\tr->xlen = 32;\n\n\tif (register_read(target, &r->misa, GDB_REGNO_MISA)) {\n\t\tLOG_ERROR(\"Fatal: Failed to read MISA from hart %d.\", r->current_hartid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (riscv_supports_extension(target, 'V')) {\n\t\tif (discover_vlenb(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Now init registers based on what we discovered. */\n\tif (riscv_init_registers(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Display this as early as possible to help people who are using\n\t\t* really slow simulators. */\n\tLOG_DEBUG(\" hart %d: XLEN=%d, misa=0x%\" PRIx64, r->current_hartid, r->xlen,\n\t\t\tr->misa);\n\n\tif (!halted)\n\t\triscv013_step_or_resume_current_hart(target, false, false);\n\n\ttarget_set_examined(target);\n\n\tif (target->smp) {\n\t\tbool haltgroup_supported;\n\t\tif (set_haltgroup(target, &haltgroup_supported) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (haltgroup_supported)\n\t\t\tLOG_INFO(\"Core %d made part of halt group %d.\", target->coreid,\n\t\t\t\t\ttarget->smp);\n\t\telse\n\t\t\tLOG_INFO(\"Core %d could not be made part of halt group %d.\",\n\t\t\t\t\ttarget->coreid, target->smp);\n\t}\n\n\t/* Some regression suites rely on seeing 'Examined RISC-V core' to know\n\t * when they can connect with gdb/telnet.\n\t * We will need to update those suites if we want to change that text. */\n\tLOG_INFO(\"Examined RISC-V core; found %d harts\",\n\t\t\triscv_count_harts(target));\n\tLOG_INFO(\" hart %d: XLEN=%d, misa=0x%\" PRIx64, r->current_hartid, r->xlen,\n\t\t\tr->misa);\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_authdata_read(struct target *target, uint32_t *value, unsigned int index)\n{\n\tif (index > 0) {\n\t\tLOG_ERROR(\"Spec 0.13 only has a single authdata register.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (wait_for_authbusy(target, NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn dmi_read(target, value, DM_AUTHDATA);\n}\n\nstatic int riscv013_authdata_write(struct target *target, uint32_t value, unsigned int index)\n{\n\tif (index > 0) {\n\t\tLOG_ERROR(\"Spec 0.13 only has a single authdata register.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t before, after;\n\tif (wait_for_authbusy(target, &before) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tdmi_write(target, DM_AUTHDATA, value);\n\n\tif (wait_for_authbusy(target, &after) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (!get_field(before, DM_DMSTATUS_AUTHENTICATED) &&\n\t\t\tget_field(after, DM_DMSTATUS_AUTHENTICATED)) {\n\t\tLOG_INFO(\"authdata_write resulted in successful authentication\");\n\t\tint result = ERROR_OK;\n\t\tdm013_info_t *dm = get_dm(target);\n\t\tif (!dm)\n\t\t\treturn ERROR_FAIL;\n\t\ttarget_list_t *entry;\n\t\tlist_for_each_entry(entry, &dm->target_list, list) {\n\t\t\tif (examine(entry->target) != ERROR_OK)\n\t\t\t\tresult = ERROR_FAIL;\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_hart_count(struct target *target)\n{\n\tdm013_info_t *dm = get_dm(target);\n\tassert(dm);\n\treturn dm->hart_count;\n}\n\n/* Try to find out the widest memory access size depending on the selected memory access methods. */\nstatic unsigned riscv013_data_bits(struct target *target)\n{\n\tRISCV013_INFO(info);\n\tRISCV_INFO(r);\n\n\tfor (unsigned int i = 0; i < RISCV_NUM_MEM_ACCESS_METHODS; i++) {\n\t\tint method = r->mem_access_methods[i];\n\n\t\tif (method == RISCV_MEM_ACCESS_PROGBUF) {\n\t\t\tif (has_sufficient_progbuf(target, 3))\n\t\t\t\treturn riscv_xlen(target);\n\t\t} else if (method == RISCV_MEM_ACCESS_SYSBUS) {\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBACCESS128))\n\t\t\t\treturn 128;\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBACCESS64))\n\t\t\t\treturn 64;\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBACCESS32))\n\t\t\t\treturn 32;\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBACCESS16))\n\t\t\t\treturn 16;\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBACCESS8))\n\t\t\t\treturn 8;\n\t\t} else if (method == RISCV_MEM_ACCESS_ABSTRACT) {\n\t\t\t/* TODO: Once there is a spec for discovering abstract commands, we can\n\t\t\t * take those into account as well.  For now we assume abstract commands\n\t\t\t * support XLEN-wide accesses. */\n\t\t\treturn riscv_xlen(target);\n\t\t} else if (method == RISCV_MEM_ACCESS_UNSPECIFIED)\n\t\t\t/* No further mem access method to try. */\n\t\t\tbreak;\n\t}\n\tLOG_ERROR(\"Unable to determine supported data bits on this target. Assuming 32 bits.\");\n\treturn 32;\n}\n\nstatic COMMAND_HELPER(riscv013_print_info, struct target *target)\n{\n\tRISCV013_INFO(info);\n\n\t/* Abstract description. */\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running8\", get_field(info->sbcs, DM_SBCS_SBACCESS8));\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running8\", get_field(info->sbcs, DM_SBCS_SBACCESS8));\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running16\", get_field(info->sbcs, DM_SBCS_SBACCESS16));\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running16\", get_field(info->sbcs, DM_SBCS_SBACCESS16));\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running32\", get_field(info->sbcs, DM_SBCS_SBACCESS32));\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running32\", get_field(info->sbcs, DM_SBCS_SBACCESS32));\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running64\", get_field(info->sbcs, DM_SBCS_SBACCESS64));\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running64\", get_field(info->sbcs, DM_SBCS_SBACCESS64));\n\triscv_print_info_line(CMD, \"target\", \"memory.read_while_running128\", get_field(info->sbcs, DM_SBCS_SBACCESS128));\n\triscv_print_info_line(CMD, \"target\", \"memory.write_while_running128\", get_field(info->sbcs, DM_SBCS_SBACCESS128));\n\n\t/* Lower level description. */\n\triscv_print_info_line(CMD, \"dm\", \"abits\", info->abits);\n\triscv_print_info_line(CMD, \"dm\", \"progbufsize\", info->progbufsize);\n\triscv_print_info_line(CMD, \"dm\", \"sbversion\", get_field(info->sbcs, DM_SBCS_SBVERSION));\n\triscv_print_info_line(CMD, \"dm\", \"sbasize\", get_field(info->sbcs, DM_SBCS_SBASIZE));\n\triscv_print_info_line(CMD, \"dm\", \"sbaccess128\", get_field(info->sbcs, DM_SBCS_SBACCESS128));\n\triscv_print_info_line(CMD, \"dm\", \"sbaccess64\", get_field(info->sbcs, DM_SBCS_SBACCESS64));\n\triscv_print_info_line(CMD, \"dm\", \"sbaccess32\", get_field(info->sbcs, DM_SBCS_SBACCESS32));\n\triscv_print_info_line(CMD, \"dm\", \"sbaccess16\", get_field(info->sbcs, DM_SBCS_SBACCESS16));\n\triscv_print_info_line(CMD, \"dm\", \"sbaccess8\", get_field(info->sbcs, DM_SBCS_SBACCESS8));\n\n\tuint32_t dmstatus;\n\tif (dmstatus_read(target, &dmstatus, false) == ERROR_OK)\n\t\triscv_print_info_line(CMD, \"dm\", \"authenticated\", get_field(dmstatus, DM_DMSTATUS_AUTHENTICATED));\n\n\treturn 0;\n}\n\nstatic int prep_for_vector_access(struct target *target, uint64_t *vtype,\n\t\tuint64_t *vl, unsigned *debug_vl)\n{\n\tRISCV_INFO(r);\n\t/* TODO: this continuous save/restore is terrible for performance. */\n\t/* Write vtype and vl. */\n\tunsigned encoded_vsew;\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\tencoded_vsew = 2;\n\t\t\tbreak;\n\t\tcase 64:\n\t\t\tencoded_vsew = 3;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported xlen: %d\", riscv_xlen(target));\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Save vtype and vl. */\n\tif (register_read(target, vtype, GDB_REGNO_VTYPE) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_read(target, vl, GDB_REGNO_VL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (register_write_direct(target, GDB_REGNO_VTYPE, encoded_vsew << 3) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t*debug_vl = DIV_ROUND_UP(r->vlenb * 8, riscv_xlen(target));\n\tif (register_write_direct(target, GDB_REGNO_VL, *debug_vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int cleanup_after_vector_access(struct target *target, uint64_t vtype,\n\t\tuint64_t vl)\n{\n\t/* Restore vtype and vl. */\n\tif (register_write_direct(target, GDB_REGNO_VTYPE, vtype) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_write_direct(target, GDB_REGNO_VL, vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_get_register_buf(struct target *target,\n\t\tuint8_t *value, int regno)\n{\n\tassert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\triscv_reg_t s0;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t mstatus;\n\tif (prep_for_register_access(target, &mstatus, regno) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t vtype, vl;\n\tunsigned debug_vl;\n\tif (prep_for_vector_access(target, &vtype, &vl, &debug_vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tunsigned vnum = regno - GDB_REGNO_V0;\n\tunsigned xlen = riscv_xlen(target);\n\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\triscv_program_insert(&program, vmv_x_s(S0, vnum));\n\triscv_program_insert(&program, vslide1down_vx(vnum, vnum, S0, true));\n\n\tint result = ERROR_OK;\n\tfor (unsigned i = 0; i < debug_vl; i++) {\n\t\t/* Executing the program might result in an exception if there is some\n\t\t * issue with the vector implementation/instructions we're using. If that\n\t\t * happens, attempt to restore as usual. We may have clobbered the\n\t\t * vector register we tried to read already.\n\t\t * For other failures, we just return error because things are probably\n\t\t * so messed up that attempting to restore isn't going to help. */\n\t\tresult = riscv_program_exec(&program, target);\n\t\tif (result == ERROR_OK) {\n\t\t\tuint64_t v;\n\t\t\tif (register_read_direct(target, &v, GDB_REGNO_S0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tbuf_set_u64(value, xlen * i, xlen, v);\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (cleanup_after_vector_access(target, vtype, vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (cleanup_after_register_access(target, mstatus, regno) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn result;\n}\n\nstatic int riscv013_set_register_buf(struct target *target,\n\t\tint regno, const uint8_t *value)\n{\n\tassert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\triscv_reg_t s0;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t mstatus;\n\tif (prep_for_register_access(target, &mstatus, regno) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t vtype, vl;\n\tunsigned debug_vl;\n\tif (prep_for_vector_access(target, &vtype, &vl, &debug_vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tunsigned vnum = regno - GDB_REGNO_V0;\n\tunsigned xlen = riscv_xlen(target);\n\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\triscv_program_insert(&program, vslide1down_vx(vnum, vnum, S0, true));\n\tint result = ERROR_OK;\n\tfor (unsigned i = 0; i < debug_vl; i++) {\n\t\tif (register_write_direct(target, GDB_REGNO_S0,\n\t\t\t\t\tbuf_get_u64(value, xlen * i, xlen)) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tresult = riscv_program_exec(&program, target);\n\t\tif (result != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\tif (cleanup_after_vector_access(target, vtype, vl) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (cleanup_after_register_access(target, mstatus, regno) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn result;\n}\n\nstatic uint32_t sb_sbaccess(unsigned int size_bytes)\n{\n\tswitch (size_bytes) {\n\t\tcase 1:\n\t\t\treturn set_field(0, DM_SBCS_SBACCESS, 0);\n\t\tcase 2:\n\t\t\treturn set_field(0, DM_SBCS_SBACCESS, 1);\n\t\tcase 4:\n\t\t\treturn set_field(0, DM_SBCS_SBACCESS, 2);\n\t\tcase 8:\n\t\t\treturn set_field(0, DM_SBCS_SBACCESS, 3);\n\t\tcase 16:\n\t\t\treturn set_field(0, DM_SBCS_SBACCESS, 4);\n\t}\n\tassert(0);\n\treturn 0;\n}\n\nstatic int sb_write_address(struct target *target, target_addr_t address,\n\t\t\t\t\t\t\tbool ensure_success)\n{\n\tRISCV013_INFO(info);\n\tunsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);\n\t/* There currently is no support for >64-bit addresses in OpenOCD. */\n\tif (sbasize > 96)\n\t\tdmi_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS3, 0, false, false);\n\tif (sbasize > 64)\n\t\tdmi_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS2, 0, false, false);\n\tif (sbasize > 32)\n\t\tdmi_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS1, address >> 32, false, false);\n\treturn dmi_op(target, NULL, NULL, DMI_OP_WRITE, DM_SBADDRESS0, address,\n\t\t\t\t  false, ensure_success);\n}\n\nstatic int batch_run(const struct target *target, struct riscv_batch *batch)\n{\n\tRISCV013_INFO(info);\n\tRISCV_INFO(r);\n\tif (r->reset_delays_wait >= 0) {\n\t\tr->reset_delays_wait -= batch->used_scans;\n\t\tif (r->reset_delays_wait <= 0) {\n\t\t\tbatch->idle_count = 0;\n\t\t\tinfo->dmi_busy_delay = 0;\n\t\t\tinfo->ac_busy_delay = 0;\n\t\t}\n\t}\n\treturn riscv_batch_run(batch);\n}\n\nstatic int sba_supports_access(struct target *target, unsigned int size_bytes)\n{\n\tRISCV013_INFO(info);\n\tswitch (size_bytes) {\n\t\tcase 1:\n\t\t\treturn get_field(info->sbcs, DM_SBCS_SBACCESS8);\n\t\tcase 2:\n\t\t\treturn get_field(info->sbcs, DM_SBCS_SBACCESS16);\n\t\tcase 4:\n\t\t\treturn get_field(info->sbcs, DM_SBCS_SBACCESS32);\n\t\tcase 8:\n\t\t\treturn get_field(info->sbcs, DM_SBCS_SBACCESS64);\n\t\tcase 16:\n\t\t\treturn get_field(info->sbcs, DM_SBCS_SBACCESS128);\n\t\tdefault:\n\t\t\treturn 0;\n\t}\n}\n\nstatic int sample_memory_bus_v1(struct target *target,\n\t\t\t\t\t\t\t\tstruct riscv_sample_buf *buf,\n\t\t\t\t\t\t\t\tconst riscv_sample_config_t *config,\n\t\t\t\t\t\t\t\tint64_t until_ms)\n{\n\tRISCV013_INFO(info);\n\tunsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);\n\tif (sbasize > 64) {\n\t\tLOG_ERROR(\"Memory sampling is only implemented for sbasize <= 64.\");\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tif (get_field(info->sbcs, DM_SBCS_SBVERSION) != 1) {\n\t\tLOG_ERROR(\"Memory sampling is only implemented for SBA version 1.\");\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tuint32_t sbcs = 0;\n\tuint32_t sbcs_valid = false;\n\n\tuint32_t sbaddress0 = 0;\n\tbool sbaddress0_valid = false;\n\tuint32_t sbaddress1 = 0;\n\tbool sbaddress1_valid = false;\n\n\t/* How often to read each value in a batch. */\n\tconst unsigned int repeat = 5;\n\n\tunsigned int enabled_count = 0;\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(config->bucket); i++) {\n\t\tif (config->bucket[i].enabled)\n\t\t\tenabled_count++;\n\t}\n\n\twhile (timeval_ms() < until_ms) {\n\t\t/*\n\t\t * batch_run() adds to the batch, so we can't simply reuse the same\n\t\t * batch over and over. So we create a new one every time through the\n\t\t * loop.\n\t\t */\n\t\tstruct riscv_batch *batch = riscv_batch_alloc(\n\t\t\ttarget, 1 + enabled_count * 5 * repeat,\n\t\t\tinfo->dmi_busy_delay + info->bus_master_read_delay);\n\t\tif (!batch)\n\t\t\treturn ERROR_FAIL;\n\n\t\tunsigned int result_bytes = 0;\n\t\tfor (unsigned int n = 0; n < repeat; n++) {\n\t\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(config->bucket); i++) {\n\t\t\t\tif (config->bucket[i].enabled) {\n\t\t\t\t\tif (!sba_supports_access(target, config->bucket[i].size_bytes)) {\n\t\t\t\t\t\tLOG_ERROR(\"Hardware does not support SBA access for %d-byte memory sampling.\",\n\t\t\t\t\t\t\t\tconfig->bucket[i].size_bytes);\n\t\t\t\t\t\treturn ERROR_NOT_IMPLEMENTED;\n\t\t\t\t\t}\n\n\t\t\t\t\tuint32_t sbcs_write = DM_SBCS_SBREADONADDR;\n\t\t\t\t\tif (enabled_count == 1)\n\t\t\t\t\t\tsbcs_write |= DM_SBCS_SBREADONDATA;\n\t\t\t\t\tsbcs_write |= sb_sbaccess(config->bucket[i].size_bytes);\n\t\t\t\t\tif (!sbcs_valid || sbcs_write != sbcs) {\n\t\t\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBCS, sbcs_write);\n\t\t\t\t\t\tsbcs = sbcs_write;\n\t\t\t\t\t\tsbcs_valid = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (sbasize > 32 &&\n\t\t\t\t\t\t\t(!sbaddress1_valid ||\n\t\t\t\t\t\t\tsbaddress1 != config->bucket[i].address >> 32)) {\n\t\t\t\t\t\tsbaddress1 = config->bucket[i].address >> 32;\n\t\t\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBADDRESS1, sbaddress1);\n\t\t\t\t\t\tsbaddress1_valid = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (!sbaddress0_valid ||\n\t\t\t\t\t\t\tsbaddress0 != (config->bucket[i].address & 0xffffffff)) {\n\t\t\t\t\t\tsbaddress0 = config->bucket[i].address;\n\t\t\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBADDRESS0, sbaddress0);\n\t\t\t\t\t\tsbaddress0_valid = true;\n\t\t\t\t\t}\n\t\t\t\t\tif (config->bucket[i].size_bytes > 4)\n\t\t\t\t\t\triscv_batch_add_dmi_read(batch, DM_SBDATA1);\n\t\t\t\t\triscv_batch_add_dmi_read(batch, DM_SBDATA0);\n\t\t\t\t\tresult_bytes += 1 + config->bucket[i].size_bytes;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (buf->used + result_bytes >= buf->size) {\n\t\t\triscv_batch_free(batch);\n\t\t\tbreak;\n\t\t}\n\n\t\tsize_t sbcs_key = riscv_batch_add_dmi_read(batch, DM_SBCS);\n\n\t\tint result = batch_run(target, batch);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tuint32_t sbcs_read = riscv_batch_get_dmi_read_data(batch, sbcs_key);\n\t\tif (get_field(sbcs_read, DM_SBCS_SBBUSYERROR)) {\n\t\t\t/* Discard this batch (too much hassle to try to recover partial\n\t\t\t * data) and try again with a larger delay. */\n\t\t\tinfo->bus_master_read_delay += info->bus_master_read_delay / 10 + 1;\n\t\t\tdmi_write(target, DM_SBCS, sbcs_read | DM_SBCS_SBBUSYERROR | DM_SBCS_SBERROR);\n\t\t\triscv_batch_free(batch);\n\t\t\tcontinue;\n\t\t}\n\t\tif (get_field(sbcs_read, DM_SBCS_SBERROR)) {\n\t\t\t/* The memory we're sampling was unreadable, somehow. Give up. */\n\t\t\tdmi_write(target, DM_SBCS, DM_SBCS_SBBUSYERROR | DM_SBCS_SBERROR);\n\t\t\triscv_batch_free(batch);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tunsigned int read = 0;\n\t\tfor (unsigned int n = 0; n < repeat; n++) {\n\t\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(config->bucket); i++) {\n\t\t\t\tif (config->bucket[i].enabled) {\n\t\t\t\t\tassert(i < RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE);\n\t\t\t\t\tuint64_t value = 0;\n\t\t\t\t\tif (config->bucket[i].size_bytes > 4)\n\t\t\t\t\t\tvalue = ((uint64_t)riscv_batch_get_dmi_read_data(batch, read++)) << 32;\n\t\t\t\t\tvalue |= riscv_batch_get_dmi_read_data(batch, read++);\n\n\t\t\t\t\tbuf->buf[buf->used] = i;\n\t\t\t\t\tbuf_set_u64(buf->buf + buf->used + 1, 0, config->bucket[i].size_bytes * 8, value);\n\t\t\t\t\tbuf->used += 1 + config->bucket[i].size_bytes;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\triscv_batch_free(batch);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int sample_memory(struct target *target,\n\t\t\t\t\t\t struct riscv_sample_buf *buf,\n\t\t\t\t\t\t riscv_sample_config_t *config,\n\t\t\t\t\t\t int64_t until_ms)\n{\n\tif (!config->enabled)\n\t\treturn ERROR_OK;\n\n\treturn sample_memory_bus_v1(target, buf, config, until_ms);\n}\n\nstatic int init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tLOG_DEBUG(\"init\");\n\tRISCV_INFO(generic_info);\n\n\tgeneric_info->get_register = &riscv013_get_register;\n\tgeneric_info->set_register = &riscv013_set_register;\n\tgeneric_info->get_register_buf = &riscv013_get_register_buf;\n\tgeneric_info->set_register_buf = &riscv013_set_register_buf;\n\tgeneric_info->select_current_hart = &riscv013_select_current_hart;\n\tgeneric_info->is_halted = &riscv013_is_halted;\n\tgeneric_info->resume_go = &riscv013_resume_go;\n\tgeneric_info->step_current_hart = &riscv013_step_current_hart;\n\tgeneric_info->on_halt = &riscv013_on_halt;\n\tgeneric_info->resume_prep = &riscv013_resume_prep;\n\tgeneric_info->halt_prep = &riscv013_halt_prep;\n\tgeneric_info->halt_go = &riscv013_halt_go;\n\tgeneric_info->on_step = &riscv013_on_step;\n\tgeneric_info->halt_reason = &riscv013_halt_reason;\n\tgeneric_info->read_debug_buffer = &riscv013_read_debug_buffer;\n\tgeneric_info->write_debug_buffer = &riscv013_write_debug_buffer;\n\tgeneric_info->execute_debug_buffer = &riscv013_execute_debug_buffer;\n\tgeneric_info->fill_dmi_write_u64 = &riscv013_fill_dmi_write_u64;\n\tgeneric_info->fill_dmi_read_u64 = &riscv013_fill_dmi_read_u64;\n\tgeneric_info->fill_dmi_nop_u64 = &riscv013_fill_dmi_nop_u64;\n\tgeneric_info->dmi_write_u64_bits = &riscv013_dmi_write_u64_bits;\n\tgeneric_info->authdata_read = &riscv013_authdata_read;\n\tgeneric_info->authdata_write = &riscv013_authdata_write;\n\tgeneric_info->dmi_read = &dmi_read;\n\tgeneric_info->dmi_write = &dmi_write;\n\tgeneric_info->read_memory = read_memory;\n\tgeneric_info->hart_count = &riscv013_hart_count;\n\tgeneric_info->data_bits = &riscv013_data_bits;\n\tgeneric_info->print_info = &riscv013_print_info;\n\tif (!generic_info->version_specific) {\n\t\tgeneric_info->version_specific = calloc(1, sizeof(riscv013_info_t));\n\t\tif (!generic_info->version_specific)\n\t\t\treturn ERROR_FAIL;\n\t}\n\tgeneric_info->sample_memory = sample_memory;\n\triscv013_info_t *info = get_info(target);\n\n\tinfo->progbufsize = -1;\n\n\tinfo->dmi_busy_delay = 0;\n\tinfo->bus_master_read_delay = 0;\n\tinfo->bus_master_write_delay = 0;\n\tinfo->ac_busy_delay = 0;\n\n\t/* Assume all these abstract commands are supported until we learn\n\t * otherwise.\n\t * TODO: The spec allows eg. one CSR to be able to be accessed abstractly\n\t * while another one isn't. We don't track that this closely here, but in\n\t * the future we probably should. */\n\tinfo->abstract_read_csr_supported = true;\n\tinfo->abstract_write_csr_supported = true;\n\tinfo->abstract_read_fpr_supported = true;\n\tinfo->abstract_write_fpr_supported = true;\n\n\tinfo->has_aampostincrement = YNM_MAYBE;\n\n\treturn ERROR_OK;\n}\n\nstatic int assert_reset(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tselect_dmi(target);\n\n\tuint32_t control_base = set_field(0, DM_DMCONTROL_DMACTIVE, 1);\n\n\tif (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {\n\t\t/* Run the user-supplied script if there is one. */\n\t\ttarget_handle_event(target, TARGET_EVENT_RESET_ASSERT);\n\t} else if (target->rtos) {\n\t\t/* There's only one target, and OpenOCD thinks each hart is a thread.\n\t\t * We must reset them all. */\n\n\t\t/* TODO: Try to use hasel in dmcontrol */\n\n\t\t/* Set haltreq for each hart. */\n\t\tuint32_t control = set_hartsel(control_base, target->coreid);\n\t\tcontrol = set_field(control, DM_DMCONTROL_HALTREQ,\n\t\t\t\ttarget->reset_halt ? 1 : 0);\n\t\tdmi_write(target, DM_DMCONTROL, control);\n\n\t\t/* Assert ndmreset */\n\t\tcontrol = set_field(control, DM_DMCONTROL_NDMRESET, 1);\n\t\tdmi_write(target, DM_DMCONTROL, control);\n\n\t} else {\n\t\t/* Reset just this hart. */\n\t\tuint32_t control = set_hartsel(control_base, r->current_hartid);\n\t\tcontrol = set_field(control, DM_DMCONTROL_HALTREQ,\n\t\t\t\ttarget->reset_halt ? 1 : 0);\n\t\tcontrol = set_field(control, DM_DMCONTROL_NDMRESET, 1);\n\t\tdmi_write(target, DM_DMCONTROL, control);\n\t}\n\n\ttarget->state = TARGET_RESET;\n\n\tdm013_info_t *dm = get_dm(target);\n\tif (!dm)\n\t\treturn ERROR_FAIL;\n\n\t/* The DM might have gotten reset if OpenOCD called us in some reset that\n\t * involves SRST being toggled. So clear our cache which may be out of\n\t * date. */\n\tmemset(dm->progbuf_cache, 0, sizeof(dm->progbuf_cache));\n\n\treturn ERROR_OK;\n}\n\nstatic int deassert_reset(struct target *target)\n{\n\tRISCV_INFO(r);\n\tRISCV013_INFO(info);\n\tselect_dmi(target);\n\n\t/* Clear the reset, but make sure haltreq is still set */\n\tuint32_t control = 0, control_haltreq;\n\tcontrol = set_field(control, DM_DMCONTROL_DMACTIVE, 1);\n\tcontrol_haltreq = set_field(control, DM_DMCONTROL_HALTREQ, target->reset_halt ? 1 : 0);\n\tdmi_write(target, DM_DMCONTROL,\n\t\t\tset_hartsel(control_haltreq, r->current_hartid));\n\n\tuint32_t dmstatus;\n\tint dmi_busy_delay = info->dmi_busy_delay;\n\ttime_t start = time(NULL);\n\n\tfor (int i = 0; i < riscv_count_harts(target); ++i) {\n\t\tint index = i;\n\t\tif (target->rtos) {\n\t\t\tif (index != target->coreid)\n\t\t\t\tcontinue;\n\t\t\tdmi_write(target, DM_DMCONTROL,\n\t\t\t\t\tset_hartsel(control_haltreq, index));\n\t\t} else {\n\t\t\tindex = r->current_hartid;\n\t\t}\n\n\t\tLOG_DEBUG(\"Waiting for hart %d to come out of reset.\", index);\n\t\twhile (1) {\n\t\t\tint result = dmstatus_read_timeout(target, &dmstatus, true,\n\t\t\t\t\triscv_reset_timeout_sec);\n\t\t\tif (result == ERROR_TIMEOUT_REACHED)\n\t\t\t\tLOG_ERROR(\"Hart %d didn't complete a DMI read coming out of \"\n\t\t\t\t\t\t\"reset in %ds; Increase the timeout with riscv \"\n\t\t\t\t\t\t\"set_reset_timeout_sec.\",\n\t\t\t\t\t\tindex, riscv_reset_timeout_sec);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t\t/* Certain debug modules, like the one in GD32VF103\n\t\t\t * MCUs, violate the specification's requirement that\n\t\t\t * each hart is in \"exactly one of four states\" and,\n\t\t\t * during reset, report harts as both unavailable and\n\t\t\t * halted/running. To work around this, we check for\n\t\t\t * the absence of the unavailable state rather than\n\t\t\t * the presence of any other state. */\n\t\t\tif (!get_field(dmstatus, DM_DMSTATUS_ALLUNAVAIL))\n\t\t\t\tbreak;\n\t\t\tif (time(NULL) - start > riscv_reset_timeout_sec) {\n\t\t\t\tLOG_ERROR(\"Hart %d didn't leave reset in %ds; \"\n\t\t\t\t\t\t\"dmstatus=0x%x; \"\n\t\t\t\t\t\t\"Increase the timeout with riscv set_reset_timeout_sec.\",\n\t\t\t\t\t\tindex, riscv_reset_timeout_sec, dmstatus);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\ttarget->state = TARGET_HALTED;\n\n\t\tif (get_field(dmstatus, DM_DMSTATUS_ALLHAVERESET)) {\n\t\t\t/* Ack reset and clear DM_DMCONTROL_HALTREQ if previously set */\n\t\t\tdmi_write(target, DM_DMCONTROL,\n\t\t\t\t\tset_hartsel(control, index) |\n\t\t\t\t\tDM_DMCONTROL_ACKHAVERESET);\n\t\t}\n\n\t\tif (!target->rtos)\n\t\t\tbreak;\n\t}\n\tinfo->dmi_busy_delay = dmi_busy_delay;\n\treturn ERROR_OK;\n}\n\nstatic int execute_fence(struct target *target)\n{\n\t/* FIXME: For non-coherent systems we need to flush the caches right\n\t * here, but there's no ISA-defined way of doing that. */\n\t{\n\t\tstruct riscv_program program;\n\t\triscv_program_init(&program, target);\n\t\triscv_program_fence_i(&program);\n\t\triscv_program_fence(&program);\n\t\tint result = riscv_program_exec(&program, target);\n\t\tif (result != ERROR_OK)\n\t\t\tLOG_DEBUG(\"Unable to execute pre-fence\");\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void log_memory_access(target_addr_t address, uint64_t value,\n\t\tunsigned size_bytes, bool read)\n{\n\tif (debug_level < LOG_LVL_DEBUG)\n\t\treturn;\n\n\tchar fmt[80];\n\tsprintf(fmt, \"M[0x%\" TARGET_PRIxADDR \"] %ss 0x%%0%d\" PRIx64,\n\t\t\taddress, read ? \"read\" : \"write\", size_bytes * 2);\n\tswitch (size_bytes) {\n\t\tcase 1:\n\t\t\tvalue &= 0xff;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tvalue &= 0xffff;\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tvalue &= 0xffffffffUL;\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tassert(false);\n\t}\n\tLOG_DEBUG(fmt, value);\n}\n\n/* Read the relevant sbdata regs depending on size, and put the results into\n * buffer. */\nstatic int read_memory_bus_word(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer)\n{\n\tuint32_t value;\n\tint result;\n\tstatic int sbdata[4] = { DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3 };\n\tassert(size <= 16);\n\tfor (int i = (size - 1) / 4; i >= 0; i--) {\n\t\tresult = dmi_op(target, &value, NULL, DMI_OP_READ, sbdata[i], 0, false, true);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tbuf_set_u32(buffer + i * 4, 0, 8 * MIN(size, 4), value);\n\t\tlog_memory_access(address + i * 4, value, MIN(size, 4), true);\n\t}\n\treturn ERROR_OK;\n}\n\nstatic target_addr_t sb_read_address(struct target *target)\n{\n\tRISCV013_INFO(info);\n\tunsigned sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);\n\ttarget_addr_t address = 0;\n\tuint32_t v;\n\tif (sbasize > 32) {\n\t\tdmi_read(target, &v, DM_SBADDRESS1);\n\t\taddress |= v;\n\t\taddress <<= 32;\n\t}\n\tdmi_read(target, &v, DM_SBADDRESS0);\n\taddress |= v;\n\treturn address;\n}\n\nstatic int read_sbcs_nonbusy(struct target *target, uint32_t *sbcs)\n{\n\ttime_t start = time(NULL);\n\twhile (1) {\n\t\tif (dmi_read(target, sbcs, DM_SBCS) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (!get_field(*sbcs, DM_SBCS_SBBUSY))\n\t\t\treturn ERROR_OK;\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"Timed out after %ds waiting for sbbusy to go low (sbcs=0x%x). \"\n\t\t\t\t\t\"Increase the timeout with riscv set_command_timeout_sec.\",\n\t\t\t\t\triscv_command_timeout_sec, *sbcs);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n}\n\nstatic int modify_privilege(struct target *target, uint64_t *mstatus, uint64_t *mstatus_old)\n{\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5)) {\n\t\t/* Read DCSR */\n\t\tuint64_t dcsr;\n\t\tif (register_read(target, &dcsr, GDB_REGNO_DCSR) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* Read and save MSTATUS */\n\t\tif (register_read(target, mstatus, GDB_REGNO_MSTATUS) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\t*mstatus_old = *mstatus;\n\n\t\t/* If we come from m-mode with mprv set, we want to keep mpp */\n\t\tif (get_field(dcsr, DCSR_PRV) < 3) {\n\t\t\t/* MPP = PRIV */\n\t\t\t*mstatus = set_field(*mstatus, MSTATUS_MPP, get_field(dcsr, DCSR_PRV));\n\n\t\t\t/* MPRV = 1 */\n\t\t\t*mstatus = set_field(*mstatus, MSTATUS_MPRV, 1);\n\n\t\t\t/* Write MSTATUS */\n\t\t\tif (*mstatus != *mstatus_old)\n\t\t\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS, *mstatus) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int read_memory_bus_v0(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tif (size != increment) {\n\t\tLOG_ERROR(\"sba v0 reads only support size==increment\");\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tLOG_DEBUG(\"System Bus Access: size: %d\\tcount:%d\\tstart address: 0x%08\"\n\t\t\tTARGET_PRIxADDR, size, count, address);\n\tuint8_t *t_buffer = buffer;\n\triscv_addr_t cur_addr = address;\n\triscv_addr_t fin_addr = address + (count * size);\n\tuint32_t access = 0;\n\n\tconst int DM_SBCS_SBSINGLEREAD_OFFSET = 20;\n\tconst uint32_t DM_SBCS_SBSINGLEREAD = (0x1U << DM_SBCS_SBSINGLEREAD_OFFSET);\n\n\tconst int DM_SBCS_SBAUTOREAD_OFFSET = 15;\n\tconst uint32_t DM_SBCS_SBAUTOREAD = (0x1U << DM_SBCS_SBAUTOREAD_OFFSET);\n\n\t/* ww favorise one off reading if there is an issue */\n\tif (count == 1) {\n\t\tfor (uint32_t i = 0; i < count; i++) {\n\t\t\tif (dmi_read(target, &access, DM_SBCS) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tdmi_write(target, DM_SBADDRESS0, cur_addr);\n\t\t\t/* size/2 matching the bit access of the spec 0.13 */\n\t\t\taccess = set_field(access, DM_SBCS_SBACCESS, size/2);\n\t\t\taccess = set_field(access, DM_SBCS_SBSINGLEREAD, 1);\n\t\t\tLOG_DEBUG(\"\\r\\nread_memory: sab: access:  0x%08x\", access);\n\t\t\tdmi_write(target, DM_SBCS, access);\n\t\t\t/* 3) read */\n\t\t\tuint32_t value;\n\t\t\tif (dmi_read(target, &value, DM_SBDATA0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tLOG_DEBUG(\"\\r\\nread_memory: sab: value:  0x%08x\", value);\n\t\t\tbuf_set_u32(t_buffer, 0, 8 * size, value);\n\t\t\tt_buffer += size;\n\t\t\tcur_addr += size;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\n\t/* has to be the same size if we want to read a block */\n\tLOG_DEBUG(\"reading block until final address 0x%\" PRIx64, fin_addr);\n\tif (dmi_read(target, &access, DM_SBCS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\t/* set current address */\n\tdmi_write(target, DM_SBADDRESS0, cur_addr);\n\t/* 2) write sbaccess=2, sbsingleread,sbautoread,sbautoincrement\n\t * size/2 matching the bit access of the spec 0.13 */\n\taccess = set_field(access, DM_SBCS_SBACCESS, size/2);\n\taccess = set_field(access, DM_SBCS_SBAUTOREAD, 1);\n\taccess = set_field(access, DM_SBCS_SBSINGLEREAD, 1);\n\taccess = set_field(access, DM_SBCS_SBAUTOINCREMENT, 1);\n\tLOG_DEBUG(\"\\r\\naccess:  0x%08x\", access);\n\tdmi_write(target, DM_SBCS, access);\n\n\twhile (cur_addr < fin_addr) {\n\t\tLOG_DEBUG(\"\\r\\nsab:autoincrement: \\r\\n size: %d\\tcount:%d\\taddress: 0x%08\"\n\t\t\t\tPRIx64, size, count, cur_addr);\n\t\t/* read */\n\t\tuint32_t value;\n\t\tif (dmi_read(target, &value, DM_SBDATA0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tbuf_set_u32(t_buffer, 0, 8 * size, value);\n\t\tcur_addr += size;\n\t\tt_buffer += size;\n\n\t\t/* if we are reaching last address, we must clear autoread */\n\t\tif (cur_addr == fin_addr && count != 1) {\n\t\t\tdmi_write(target, DM_SBCS, 0);\n\t\t\tif (dmi_read(target, &value, DM_SBDATA0) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tbuf_set_u32(t_buffer, 0, 8 * size, value);\n\t\t}\n\t}\n\n\tuint32_t sbcs;\n\tif (dmi_read(target, &sbcs, DM_SBCS) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Read the requested memory using the system bus interface.\n */\nstatic int read_memory_bus_v1(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tif (increment != size && increment != 0) {\n\t\tLOG_ERROR(\"sba v1 reads only support increment of size or 0\");\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\t}\n\n\tRISCV013_INFO(info);\n\ttarget_addr_t next_address = address;\n\ttarget_addr_t end_address = address + count * size;\n\n\twhile (next_address < end_address) {\n\t\tuint32_t sbcs_write = set_field(0, DM_SBCS_SBREADONADDR, 1);\n\t\tsbcs_write |= sb_sbaccess(size);\n\t\tif (increment == size)\n\t\t\tsbcs_write = set_field(sbcs_write, DM_SBCS_SBAUTOINCREMENT, 1);\n\t\tif (count > 1)\n\t\t\tsbcs_write = set_field(sbcs_write, DM_SBCS_SBREADONDATA, count > 1);\n\t\tif (dmi_write(target, DM_SBCS, sbcs_write) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\t/* This address write will trigger the first read. */\n\t\tif (sb_write_address(target, next_address, true) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (info->bus_master_read_delay) {\n\t\t\tjtag_add_runtest(info->bus_master_read_delay, TAP_IDLE);\n\t\t\tif (jtag_execute_queue() != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to scan idle sequence\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\t/* First value has been read, and is waiting for us to issue a DMI read\n\t\t * to get it. */\n\n\t\tstatic int sbdata[4] = {DM_SBDATA0, DM_SBDATA1, DM_SBDATA2, DM_SBDATA3};\n\t\tassert(size <= 16);\n\t\ttarget_addr_t next_read = address - 1;\n\t\tfor (uint32_t i = (next_address - address) / size; i < count - 1; i++) {\n\t\t\tfor (int j = (size - 1) / 4; j >= 0; j--) {\n\t\t\t\tuint32_t value;\n\t\t\t\tunsigned attempt = 0;\n\t\t\t\twhile (1) {\n\t\t\t\t\tif (attempt++ > 100) {\n\t\t\t\t\t\tLOG_ERROR(\"DMI keeps being busy in while reading memory just past \" TARGET_ADDR_FMT,\n\t\t\t\t\t\t\t\t  next_read);\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t\t}\n\t\t\t\t\tkeep_alive();\n\t\t\t\t\tdmi_status_t status = dmi_scan(target, NULL, &value,\n\t\t\t\t\t\t\t\t\t\t\t\t   DMI_OP_READ, sbdata[j], 0, false);\n\t\t\t\t\tif (status == DMI_STATUS_BUSY)\n\t\t\t\t\t\tincrease_dmi_busy_delay(target);\n\t\t\t\t\telse if (status == DMI_STATUS_SUCCESS)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\telse\n\t\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tif (next_read != address - 1) {\n\t\t\t\t\tbuf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), value);\n\t\t\t\t\tlog_memory_access(next_read, value, MIN(size, 4), true);\n\t\t\t\t}\n\t\t\t\tnext_read = address + i * size + j * 4;\n\t\t\t}\n\t\t}\n\n\t\tuint32_t sbcs_read = 0;\n\t\tif (count > 1) {\n\t\t\tuint32_t value;\n\t\t\tunsigned attempt = 0;\n\t\t\twhile (1) {\n\t\t\t\tif (attempt++ > 100) {\n\t\t\t\t\tLOG_ERROR(\"DMI keeps being busy in while reading memory just past \" TARGET_ADDR_FMT,\n\t\t\t\t\t\t\t\tnext_read);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\tdmi_status_t status = dmi_scan(target, NULL, &value, DMI_OP_NOP, 0, 0, false);\n\t\t\t\tif (status == DMI_STATUS_BUSY)\n\t\t\t\t\tincrease_dmi_busy_delay(target);\n\t\t\t\telse if (status == DMI_STATUS_SUCCESS)\n\t\t\t\t\tbreak;\n\t\t\t\telse\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbuf_set_u32(buffer + next_read - address, 0, 8 * MIN(size, 4), value);\n\t\t\tlog_memory_access(next_read, value, MIN(size, 4), true);\n\n\t\t\t/* \"Writes to sbcs while sbbusy is high result in undefined behavior.\n\t\t\t * A debugger must not write to sbcs until it reads sbbusy as 0.\" */\n\t\t\tif (read_sbcs_nonbusy(target, &sbcs_read) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\n\t\t\tsbcs_write = set_field(sbcs_write, DM_SBCS_SBREADONDATA, 0);\n\t\t\tif (dmi_write(target, DM_SBCS, sbcs_write) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Read the last word, after we disabled sbreadondata if necessary. */\n\t\tif (!get_field(sbcs_read, DM_SBCS_SBERROR) &&\n\t\t\t\t!get_field(sbcs_read, DM_SBCS_SBBUSYERROR)) {\n\t\t\tif (read_memory_bus_word(target, address + (count - 1) * size, size,\n\t\t\t\t\t\tbuffer + (count - 1) * size) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\n\t\t\tif (read_sbcs_nonbusy(target, &sbcs_read) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (get_field(sbcs_read, DM_SBCS_SBBUSYERROR)) {\n\t\t\t/* We read while the target was busy. Slow down and try again. */\n\t\t\tif (dmi_write(target, DM_SBCS, sbcs_read | DM_SBCS_SBBUSYERROR) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tnext_address = sb_read_address(target);\n\t\t\tinfo->bus_master_read_delay += info->bus_master_read_delay / 10 + 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tunsigned error = get_field(sbcs_read, DM_SBCS_SBERROR);\n\t\tif (error == 0) {\n\t\t\tnext_address = end_address;\n\t\t} else {\n\t\t\t/* Some error indicating the bus access failed, but not because of\n\t\t\t * something we did wrong. */\n\t\t\tif (dmi_write(target, DM_SBCS, DM_SBCS_SBERROR) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void log_mem_access_result(struct target *target, bool success, int method, bool read)\n{\n\tRISCV_INFO(r);\n\tbool warn = false;\n\tchar msg[60];\n\n\t/* Compose the message */\n\tsnprintf(msg, 60, \"%s to %s memory via %s.\",\n\t\t\tsuccess ? \"Succeeded\" : \"Failed\",\n\t\t\tread ? \"read\" : \"write\",\n\t\t\t(method == RISCV_MEM_ACCESS_PROGBUF) ? \"program buffer\" :\n\t\t\t(method == RISCV_MEM_ACCESS_SYSBUS) ? \"system bus\" : \"abstract access\");\n\n\t/* Determine the log message severity. Show warnings only once. */\n\tif (!success) {\n\t\tif (method == RISCV_MEM_ACCESS_PROGBUF) {\n\t\t\twarn = r->mem_access_progbuf_warn;\n\t\t\tr->mem_access_progbuf_warn = false;\n\t\t}\n\t\tif (method == RISCV_MEM_ACCESS_SYSBUS) {\n\t\t\twarn = r->mem_access_sysbus_warn;\n\t\t\tr->mem_access_sysbus_warn = false;\n\t\t}\n\t\tif (method == RISCV_MEM_ACCESS_ABSTRACT) {\n\t\t\twarn = r->mem_access_abstract_warn;\n\t\t\tr->mem_access_abstract_warn = false;\n\t\t}\n\t}\n\n\tif (warn)\n\t\tLOG_WARNING(\"%s\", msg);\n\telse\n\t\tLOG_DEBUG(\"%s\", msg);\n}\n\nstatic bool mem_should_skip_progbuf(struct target *target, target_addr_t address,\n\t\tuint32_t size, bool read, char **skip_reason)\n{\n\tassert(skip_reason);\n\n\tif (!has_sufficient_progbuf(target, 3)) {\n\t\tLOG_DEBUG(\"Skipping mem %s via progbuf - insufficient progbuf size.\",\n\t\t\t\tread ? \"read\" : \"write\");\n\t\t*skip_reason = \"skipped (insufficient progbuf)\";\n\t\treturn true;\n\t}\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"Skipping mem %s via progbuf - target not halted.\",\n\t\t\t\tread ? \"read\" : \"write\");\n\t\t*skip_reason = \"skipped (target not halted)\";\n\t\treturn true;\n\t}\n\tif (riscv_xlen(target) < size * 8) {\n\t\tLOG_DEBUG(\"Skipping mem %s via progbuf - XLEN (%d) is too short for %d-bit memory access.\",\n\t\t\t\tread ? \"read\" : \"write\", riscv_xlen(target), size * 8);\n\t\t*skip_reason = \"skipped (XLEN too short)\";\n\t\treturn true;\n\t}\n\tif (size > 8) {\n\t\tLOG_DEBUG(\"Skipping mem %s via progbuf - unsupported size.\",\n\t\t\t\tread ? \"read\" : \"write\");\n\t\t*skip_reason = \"skipped (unsupported size)\";\n\t\treturn true;\n\t}\n\tif ((sizeof(address) * 8 > riscv_xlen(target)) && (address >> riscv_xlen(target))) {\n\t\tLOG_DEBUG(\"Skipping mem %s via progbuf - progbuf only supports %u-bit address.\",\n\t\t\t\tread ? \"read\" : \"write\", riscv_xlen(target));\n\t\t*skip_reason = \"skipped (too large address)\";\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic bool mem_should_skip_sysbus(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t increment, bool read, char **skip_reason)\n{\n\tassert(skip_reason);\n\n\tRISCV013_INFO(info);\n\tif (!sba_supports_access(target, size)) {\n\t\tLOG_DEBUG(\"Skipping mem %s via system bus - unsupported size.\",\n\t\t\t\tread ? \"read\" : \"write\");\n\t\t*skip_reason = \"skipped (unsupported size)\";\n\t\treturn true;\n\t}\n\tunsigned int sbasize = get_field(info->sbcs, DM_SBCS_SBASIZE);\n\tif ((sizeof(address) * 8 > sbasize) && (address >> sbasize)) {\n\t\tLOG_DEBUG(\"Skipping mem %s via system bus - sba only supports %u-bit address.\",\n\t\t\t\tread ? \"read\" : \"write\", sbasize);\n\t\t*skip_reason = \"skipped (too large address)\";\n\t\treturn true;\n\t}\n\tif (read && increment != size && (get_field(info->sbcs, DM_SBCS_SBVERSION) == 0 || increment != 0)) {\n\t\tLOG_DEBUG(\"Skipping mem read via system bus - \"\n\t\t\t\t\"sba reads only support size==increment or also size==0 for sba v1.\");\n\t\t*skip_reason = \"skipped (unsupported increment)\";\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\nstatic bool mem_should_skip_abstract(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t increment, bool read, char **skip_reason)\n{\n\tassert(skip_reason);\n\n\tif (size > 8) {\n\t\t/* TODO: Add 128b support if it's ever used. Involves modifying\n\t\t\t\t read/write_abstract_arg() to work on two 64b values. */\n\t\tLOG_DEBUG(\"Skipping mem %s via abstract access - unsupported size: %d bits\",\n\t\t\t\tread ? \"read\" : \"write\", size * 8);\n\t\t*skip_reason = \"skipped (unsupported size)\";\n\t\treturn true;\n\t}\n\tif ((sizeof(address) * 8 > riscv_xlen(target)) && (address >> riscv_xlen(target))) {\n\t\tLOG_DEBUG(\"Skipping mem %s via abstract access - abstract access only supports %u-bit address.\",\n\t\t\t\tread ? \"read\" : \"write\", riscv_xlen(target));\n\t\t*skip_reason = \"skipped (too large address)\";\n\t\treturn true;\n\t}\n\tif (read && size != increment) {\n\t\tLOG_ERROR(\"Skipping mem read via abstract access - \"\n\t\t\t\t\"abstract command reads only support size==increment.\");\n\t\t*skip_reason = \"skipped (unsupported increment)\";\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/*\n * Performs a memory read using memory access abstract commands. The read sizes\n * supported are 1, 2, and 4 bytes despite the spec's support of 8 and 16 byte\n * aamsize fields in the memory access abstract command.\n */\nstatic int read_memory_abstract(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tRISCV013_INFO(info);\n\n\tint result = ERROR_OK;\n\tbool use_aampostincrement = info->has_aampostincrement != YNM_NO;\n\n\tLOG_DEBUG(\"reading %d words of %d bytes from 0x%\" TARGET_PRIxADDR, count,\n\t\t\t  size, address);\n\n\tmemset(buffer, 0, count * size);\n\n\t/* Convert the size (bytes) to width (bits) */\n\tunsigned width = size << 3;\n\n\t/* Create the command (physical address, postincrement, read) */\n\tuint32_t command = access_memory_command(target, false, width, use_aampostincrement, false);\n\n\t/* Execute the reads */\n\tuint8_t *p = buffer;\n\tbool updateaddr = true;\n\tunsigned int width32 = (width < 32) ? 32 : width;\n\tfor (uint32_t c = 0; c < count; c++) {\n\t\t/* Update the address if it is the first time or aampostincrement is not supported by the target. */\n\t\tif (updateaddr) {\n\t\t\t/* Set arg1 to the address: address + c * size */\n\t\t\tresult = write_abstract_arg(target, 1, address + c * size, riscv_xlen(target));\n\t\t\tif (result != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to write arg1 during read_memory_abstract().\");\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\t/* Execute the command */\n\t\tresult = execute_abstract_command(target, command);\n\n\t\tif (info->has_aampostincrement == YNM_MAYBE) {\n\t\t\tif (result == ERROR_OK) {\n\t\t\t\t/* Safety: double-check that the address was really auto-incremented */\n\t\t\t\triscv_reg_t new_address = read_abstract_arg(target, 1, riscv_xlen(target));\n\t\t\t\tif (new_address == address + size) {\n\t\t\t\t\tLOG_DEBUG(\"aampostincrement is supported on this target.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_YES;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_WARNING(\"Buggy aampostincrement! Address not incremented correctly.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_NO;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Try the same access but with postincrement disabled. */\n\t\t\t\tcommand = access_memory_command(target, false, width, false, false);\n\t\t\t\tresult = execute_abstract_command(target, command);\n\t\t\t\tif (result == ERROR_OK) {\n\t\t\t\t\tLOG_DEBUG(\"aampostincrement is not supported on this target.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_NO;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\t/* Copy arg0 to buffer (rounded width up to nearest 32) */\n\t\triscv_reg_t value = read_abstract_arg(target, 0, width32);\n\t\tbuf_set_u64(p, 0, 8 * size, value);\n\n\t\tif (info->has_aampostincrement == YNM_YES)\n\t\t\tupdateaddr = false;\n\t\tp += size;\n\t}\n\n\treturn result;\n}\n\n/*\n * Performs a memory write using memory access abstract commands. The write\n * sizes supported are 1, 2, and 4 bytes despite the spec's support of 8 and 16\n * byte aamsize fields in the memory access abstract command.\n */\nstatic int write_memory_abstract(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tRISCV013_INFO(info);\n\tint result = ERROR_OK;\n\tbool use_aampostincrement = info->has_aampostincrement != YNM_NO;\n\n\tLOG_DEBUG(\"writing %d words of %d bytes from 0x%\" TARGET_PRIxADDR, count,\n\t\t\t  size, address);\n\n\t/* Convert the size (bytes) to width (bits) */\n\tunsigned width = size << 3;\n\n\t/* Create the command (physical address, postincrement, write) */\n\tuint32_t command = access_memory_command(target, false, width, use_aampostincrement, true);\n\n\t/* Execute the writes */\n\tconst uint8_t *p = buffer;\n\tbool updateaddr = true;\n\tfor (uint32_t c = 0; c < count; c++) {\n\t\t/* Move data to arg0 */\n\t\triscv_reg_t value = buf_get_u64(p, 0, 8 * size);\n\t\tresult = write_abstract_arg(target, 0, value, riscv_xlen(target));\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to write arg0 during write_memory_abstract().\");\n\t\t\treturn result;\n\t\t}\n\n\t\t/* Update the address if it is the first time or aampostincrement is not supported by the target. */\n\t\tif (updateaddr) {\n\t\t\t/* Set arg1 to the address: address + c * size */\n\t\t\tresult = write_abstract_arg(target, 1, address + c * size, riscv_xlen(target));\n\t\t\tif (result != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to write arg1 during write_memory_abstract().\");\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\t/* Execute the command */\n\t\tresult = execute_abstract_command(target, command);\n\n\t\tif (info->has_aampostincrement == YNM_MAYBE) {\n\t\t\tif (result == ERROR_OK) {\n\t\t\t\t/* Safety: double-check that the address was really auto-incremented */\n\t\t\t\triscv_reg_t new_address = read_abstract_arg(target, 1, riscv_xlen(target));\n\t\t\t\tif (new_address == address + size) {\n\t\t\t\t\tLOG_DEBUG(\"aampostincrement is supported on this target.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_YES;\n\t\t\t\t} else {\n\t\t\t\t\tLOG_WARNING(\"Buggy aampostincrement! Address not incremented correctly.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_NO;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Try the same access but with postincrement disabled. */\n\t\t\t\tcommand = access_memory_command(target, false, width, false, true);\n\t\t\t\tresult = execute_abstract_command(target, command);\n\t\t\t\tif (result == ERROR_OK) {\n\t\t\t\t\tLOG_DEBUG(\"aampostincrement is not supported on this target.\");\n\t\t\t\t\tinfo->has_aampostincrement = YNM_NO;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tif (info->has_aampostincrement == YNM_YES)\n\t\t\tupdateaddr = false;\n\t\tp += size;\n\t}\n\n\treturn result;\n}\n\n/**\n * Read the requested memory, taking care to execute every read exactly once,\n * even if cmderr=busy is encountered.\n */\nstatic int read_memory_progbuf_inner(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tRISCV013_INFO(info);\n\n\tint result = ERROR_OK;\n\n\t/* Write address to S0. */\n\tresult = register_write_direct(target, GDB_REGNO_S0, address);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tif (increment == 0 &&\n\t\t\tregister_write_direct(target, GDB_REGNO_S2, 0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint32_t command = access_register_command(target, GDB_REGNO_S1,\n\t\t\triscv_xlen(target),\n\t\t\tAC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);\n\tif (execute_abstract_command(target, command) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* First read has just triggered. Result is in s1. */\n\tif (count == 1) {\n\t\tuint64_t value;\n\t\tif (register_read_direct(target, &value, GDB_REGNO_S1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tbuf_set_u64(buffer, 0, 8 * size, value);\n\t\tlog_memory_access(address, value, size, true);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (dmi_write(target, DM_ABSTRACTAUTO,\n\t\t\t1 << DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET) != ERROR_OK)\n\t\tgoto error;\n\t/* Read garbage from dmi_data0, which triggers another execution of the\n\t * program. Now dmi_data0 contains the first good result, and s1 the next\n\t * memory value. */\n\tif (dmi_read_exec(target, NULL, DM_DATA0) != ERROR_OK)\n\t\tgoto error;\n\n\t/* read_addr is the next address that the hart will read from, which is the\n\t * value in s0. */\n\tunsigned index = 2;\n\twhile (index < count) {\n\t\triscv_addr_t read_addr = address + index * increment;\n\t\tLOG_DEBUG(\"i=%d, count=%d, read_addr=0x%\" PRIx64, index, count, read_addr);\n\t\t/* The pipeline looks like this:\n\t\t * memory -> s1 -> dm_data0 -> debugger\n\t\t * Right now:\n\t\t * s0 contains read_addr\n\t\t * s1 contains mem[read_addr-size]\n\t\t * dm_data0 contains[read_addr-size*2]\n\t\t */\n\n\t\tstruct riscv_batch *batch = riscv_batch_alloc(target, 32,\n\t\t\t\tinfo->dmi_busy_delay + info->ac_busy_delay);\n\t\tif (!batch)\n\t\t\treturn ERROR_FAIL;\n\n\t\tunsigned reads = 0;\n\t\tfor (unsigned j = index; j < count; j++) {\n\t\t\tif (size > 4)\n\t\t\t\triscv_batch_add_dmi_read(batch, DM_DATA1);\n\t\t\triscv_batch_add_dmi_read(batch, DM_DATA0);\n\n\t\t\treads++;\n\t\t\tif (riscv_batch_full(batch))\n\t\t\t\tbreak;\n\t\t}\n\n\t\tbatch_run(target, batch);\n\n\t\t/* Wait for the target to finish performing the last abstract command,\n\t\t * and update our copy of cmderr. If we see that DMI is busy here,\n\t\t * dmi_busy_delay will be incremented. */\n\t\tuint32_t abstractcs;\n\t\tif (dmi_read(target, &abstractcs, DM_ABSTRACTCS) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\twhile (get_field(abstractcs, DM_ABSTRACTCS_BUSY))\n\t\t\tif (dmi_read(target, &abstractcs, DM_ABSTRACTCS) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\tinfo->cmderr = get_field(abstractcs, DM_ABSTRACTCS_CMDERR);\n\n\t\tunsigned next_index;\n\t\tunsigned ignore_last = 0;\n\t\tswitch (info->cmderr) {\n\t\t\tcase CMDERR_NONE:\n\t\t\t\tLOG_DEBUG(\"successful (partial?) memory read\");\n\t\t\t\tnext_index = index + reads;\n\t\t\t\tbreak;\n\t\t\tcase CMDERR_BUSY:\n\t\t\t\tLOG_DEBUG(\"memory read resulted in busy response\");\n\n\t\t\t\tincrease_ac_busy_delay(target);\n\t\t\t\triscv013_clear_abstract_error(target);\n\n\t\t\t\tdmi_write(target, DM_ABSTRACTAUTO, 0);\n\n\t\t\t\tuint32_t dmi_data0, dmi_data1 = 0;\n\t\t\t\t/* This is definitely a good version of the value that we\n\t\t\t\t * attempted to read when we discovered that the target was\n\t\t\t\t * busy. */\n\t\t\t\tif (dmi_read(target, &dmi_data0, DM_DATA0) != ERROR_OK) {\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\t\t\t\tif (size > 4 && dmi_read(target, &dmi_data1, DM_DATA1) != ERROR_OK) {\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\t/* See how far we got, clobbering dmi_data0. */\n\t\t\t\tif (increment == 0) {\n\t\t\t\t\tuint64_t counter;\n\t\t\t\t\tresult = register_read_direct(target, &counter, GDB_REGNO_S2);\n\t\t\t\t\tnext_index = counter;\n\t\t\t\t} else {\n\t\t\t\t\tuint64_t next_read_addr;\n\t\t\t\t\tresult = register_read_direct(target, &next_read_addr,\n\t\t\t\t\t\t\t\t\t\t\t\t  GDB_REGNO_S0);\n\t\t\t\t\tnext_index = (next_read_addr - address) / increment;\n\t\t\t\t}\n\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\tuint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0;\n\t\t\t\tbuf_set_u64(buffer + (next_index - 2) * size, 0, 8 * size, value64);\n\t\t\t\tlog_memory_access(address + (next_index - 2) * size, value64, size, true);\n\n\t\t\t\t/* Restore the command, and execute it.\n\t\t\t\t * Now DM_DATA0 contains the next value just as it would if no\n\t\t\t\t * error had occurred. */\n\t\t\t\tdmi_write_exec(target, DM_COMMAND, command, true);\n\t\t\t\tnext_index++;\n\n\t\t\t\tdmi_write(target, DM_ABSTRACTAUTO,\n\t\t\t\t\t\t1 << DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET);\n\n\t\t\t\tignore_last = 1;\n\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_DEBUG(\"error when reading memory, abstractcs=0x%08lx\", (long)abstractcs);\n\t\t\t\triscv013_clear_abstract_error(target);\n\t\t\t\triscv_batch_free(batch);\n\t\t\t\tresult = ERROR_FAIL;\n\t\t\t\tgoto error;\n\t\t}\n\n\t\t/* Now read whatever we got out of the batch. */\n\t\tdmi_status_t status = DMI_STATUS_SUCCESS;\n\t\tunsigned read = 0;\n\t\tassert(index >= 2);\n\t\tfor (unsigned j = index - 2; j < index + reads; j++) {\n\t\t\tassert(j < count);\n\t\t\tLOG_DEBUG(\"index=%d, reads=%d, next_index=%d, ignore_last=%d, j=%d\",\n\t\t\t\tindex, reads, next_index, ignore_last, j);\n\t\t\tif (j + 3 + ignore_last > next_index)\n\t\t\t\tbreak;\n\n\t\t\tstatus = riscv_batch_get_dmi_read_op(batch, read);\n\t\t\tuint64_t value = riscv_batch_get_dmi_read_data(batch, read);\n\t\t\tread++;\n\t\t\tif (status != DMI_STATUS_SUCCESS) {\n\t\t\t\t/* If we're here because of busy count, dmi_busy_delay will\n\t\t\t\t * already have been increased and busy state will have been\n\t\t\t\t * cleared in dmi_read(). */\n\t\t\t\t/* In at least some implementations, we issue a read, and then\n\t\t\t\t * can get busy back when we try to scan out the read result,\n\t\t\t\t * and the actual read value is lost forever. Since this is\n\t\t\t\t * rare in any case, we return error here and rely on our\n\t\t\t\t * caller to reread the entire block. */\n\t\t\t\tLOG_WARNING(\"Batch memory read encountered DMI error %d. \"\n\t\t\t\t\t\t\"Falling back on slower reads.\", status);\n\t\t\t\triscv_batch_free(batch);\n\t\t\t\tresult = ERROR_FAIL;\n\t\t\t\tgoto error;\n\t\t\t}\n\t\t\tif (size > 4) {\n\t\t\t\tstatus = riscv_batch_get_dmi_read_op(batch, read);\n\t\t\t\tif (status != DMI_STATUS_SUCCESS) {\n\t\t\t\t\tLOG_WARNING(\"Batch memory read encountered DMI error %d. \"\n\t\t\t\t\t\t\t\"Falling back on slower reads.\", status);\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tresult = ERROR_FAIL;\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\t\t\t\tvalue <<= 32;\n\t\t\t\tvalue |= riscv_batch_get_dmi_read_data(batch, read);\n\t\t\t\tread++;\n\t\t\t}\n\t\t\triscv_addr_t offset = j * size;\n\t\t\tbuf_set_u64(buffer + offset, 0, 8 * size, value);\n\t\t\tlog_memory_access(address + j * increment, value, size, true);\n\t\t}\n\n\t\tindex = next_index;\n\n\t\triscv_batch_free(batch);\n\t}\n\n\tdmi_write(target, DM_ABSTRACTAUTO, 0);\n\n\tif (count > 1) {\n\t\t/* Read the penultimate word. */\n\t\tuint32_t dmi_data0, dmi_data1 = 0;\n\t\tif (dmi_read(target, &dmi_data0, DM_DATA0) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (size > 4 && dmi_read(target, &dmi_data1, DM_DATA1) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tuint64_t value64 = (((uint64_t)dmi_data1) << 32) | dmi_data0;\n\t\tbuf_set_u64(buffer + size * (count - 2), 0, 8 * size, value64);\n\t\tlog_memory_access(address + size * (count - 2), value64, size, true);\n\t}\n\n\t/* Read the last word. */\n\tuint64_t value;\n\tresult = register_read_direct(target, &value, GDB_REGNO_S1);\n\tif (result != ERROR_OK)\n\t\tgoto error;\n\tbuf_set_u64(buffer + size * (count-1), 0, 8 * size, value);\n\tlog_memory_access(address + size * (count-1), value, size, true);\n\n\treturn ERROR_OK;\n\nerror:\n\tdmi_write(target, DM_ABSTRACTAUTO, 0);\n\n\treturn result;\n}\n\n/* Only need to save/restore one GPR to read a single word, and the progbuf\n * program doesn't need to increment. */\nstatic int read_memory_progbuf_one(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer)\n{\n\tuint64_t mstatus = 0;\n\tuint64_t mstatus_old = 0;\n\tif (modify_privilege(target, &mstatus, &mstatus_old) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tuint64_t s0;\n\tint result = ERROR_FAIL;\n\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\tgoto restore_mstatus;\n\n\t/* Write the program (load, increment) */\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrsi(&program, GDB_REGNO_ZERO, CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\tswitch (size) {\n\t\tcase 1:\n\t\t\triscv_program_lbr(&program, GDB_REGNO_S0, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\triscv_program_lhr(&program, GDB_REGNO_S0, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\triscv_program_lwr(&program, GDB_REGNO_S0, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\triscv_program_ldr(&program, GDB_REGNO_S0, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d\", size);\n\t\t\tgoto restore_mstatus;\n\t}\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrci(&program, GDB_REGNO_ZERO,  CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\n\tif (riscv_program_ebreak(&program) != ERROR_OK)\n\t\tgoto restore_mstatus;\n\tif (riscv_program_write(&program) != ERROR_OK)\n\t\tgoto restore_mstatus;\n\n\t/* Write address to S0, and execute buffer. */\n\tif (write_abstract_arg(target, 0, address, riscv_xlen(target)) != ERROR_OK)\n\t\tgoto restore_mstatus;\n\tuint32_t command = access_register_command(target, GDB_REGNO_S0,\n\t\t\triscv_xlen(target), AC_ACCESS_REGISTER_WRITE |\n\t\t\tAC_ACCESS_REGISTER_TRANSFER | AC_ACCESS_REGISTER_POSTEXEC);\n\tif (execute_abstract_command(target, command) != ERROR_OK)\n\t\tgoto restore_s0;\n\n\tuint64_t value;\n\tif (register_read(target, &value, GDB_REGNO_S0) != ERROR_OK)\n\t\tgoto restore_s0;\n\tbuf_set_u64(buffer, 0, 8 * size, value);\n\tlog_memory_access(address, value, size, true);\n\tresult = ERROR_OK;\n\nrestore_s0:\n\tif (riscv_set_register(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\tresult = ERROR_FAIL;\n\nrestore_mstatus:\n\tif (mstatus != mstatus_old)\n\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))\n\t\t\tresult = ERROR_FAIL;\n\n\treturn result;\n}\n\n/**\n * Read the requested memory, silently handling memory access errors.\n */\nstatic int read_memory_progbuf(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tif (riscv_xlen(target) < size * 8) {\n\t\tLOG_ERROR(\"XLEN (%d) is too short for %d-bit memory read.\",\n\t\t\t\triscv_xlen(target), size * 8);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint result = ERROR_OK;\n\n\tLOG_DEBUG(\"reading %d words of %d bytes from 0x%\" TARGET_PRIxADDR, count,\n\t\t\tsize, address);\n\n\tselect_dmi(target);\n\n\tmemset(buffer, 0, count*size);\n\n\tif (execute_fence(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (count == 1)\n\t\treturn read_memory_progbuf_one(target, address, size, buffer);\n\n\tuint64_t mstatus = 0;\n\tuint64_t mstatus_old = 0;\n\tif (modify_privilege(target, &mstatus, &mstatus_old) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* s0 holds the next address to read from\n\t * s1 holds the next data value read\n\t * s2 is a counter in case increment is 0\n\t */\n\tuint64_t s0, s1, s2;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_read(target, &s1, GDB_REGNO_S1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (increment == 0 && register_read(target, &s2, GDB_REGNO_S2) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Write the program (load, increment) */\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrsi(&program, GDB_REGNO_ZERO, CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\n\tswitch (size) {\n\t\tcase 1:\n\t\t\triscv_program_lbr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\triscv_program_lhr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\triscv_program_lwr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\triscv_program_ldr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported size: %d\", size);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrci(&program, GDB_REGNO_ZERO,  CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\tif (increment == 0)\n\t\triscv_program_addi(&program, GDB_REGNO_S2, GDB_REGNO_S2, 1);\n\telse\n\t\triscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, increment);\n\n\tif (riscv_program_ebreak(&program) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (riscv_program_write(&program) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tresult = read_memory_progbuf_inner(target, address, size, count, buffer, increment);\n\n\tif (result != ERROR_OK) {\n\t\t/* The full read did not succeed, so we will try to read each word individually. */\n\t\t/* This will not be fast, but reading outside actual memory is a special case anyway. */\n\t\t/* It will make the toolchain happier, especially Eclipse Memory View as it reads ahead. */\n\t\ttarget_addr_t address_i = address;\n\t\tuint32_t count_i = 1;\n\t\tuint8_t *buffer_i = buffer;\n\n\t\tfor (uint32_t i = 0; i < count; i++, address_i += increment, buffer_i += size) {\n\t\t\t/* TODO: This is much slower than it needs to be because we end up\n\t\t\t * writing the address to read for every word we read. */\n\t\t\tresult = read_memory_progbuf_inner(target, address_i, size, count_i, buffer_i, increment);\n\n\t\t\t/* The read of a single word failed, so we will just return 0 for that instead */\n\t\t\tif (result != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"error reading single word of %d bytes from 0x%\" TARGET_PRIxADDR,\n\t\t\t\t\t\tsize, address_i);\n\n\t\t\t\tbuf_set_u64(buffer_i, 0, 8 * size, 0);\n\t\t\t}\n\t\t}\n\t\tresult = ERROR_OK;\n\t}\n\n\triscv_set_register(target, GDB_REGNO_S0, s0);\n\triscv_set_register(target, GDB_REGNO_S1, s1);\n\tif (increment == 0)\n\t\triscv_set_register(target, GDB_REGNO_S2, s2);\n\n\t/* Restore MSTATUS */\n\tif (mstatus != mstatus_old)\n\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))\n\t\t\treturn ERROR_FAIL;\n\n\treturn result;\n}\n\nstatic int read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment)\n{\n\tif (count == 0)\n\t\treturn ERROR_OK;\n\n\tif (size != 1 && size != 2 && size != 4 && size != 8 && size != 16) {\n\t\tLOG_ERROR(\"BUG: Unsupported size for memory read: %d\", size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = ERROR_FAIL;\n\tRISCV_INFO(r);\n\tRISCV013_INFO(info);\n\n\tchar *progbuf_result = \"disabled\";\n\tchar *sysbus_result = \"disabled\";\n\tchar *abstract_result = \"disabled\";\n\n\tfor (unsigned int i = 0; i < RISCV_NUM_MEM_ACCESS_METHODS; i++) {\n\t\tint method = r->mem_access_methods[i];\n\n\t\tif (method == RISCV_MEM_ACCESS_PROGBUF) {\n\t\t\tif (mem_should_skip_progbuf(target, address, size, true, &progbuf_result))\n\t\t\t\tcontinue;\n\n\t\t\tret = read_memory_progbuf(target, address, size, count, buffer, increment);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tprogbuf_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_SYSBUS) {\n\t\t\tif (mem_should_skip_sysbus(target, address, size, increment, true, &sysbus_result))\n\t\t\t\tcontinue;\n\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBVERSION) == 0)\n\t\t\t\tret = read_memory_bus_v0(target, address, size, count, buffer, increment);\n\t\t\telse if (get_field(info->sbcs, DM_SBCS_SBVERSION) == 1)\n\t\t\t\tret = read_memory_bus_v1(target, address, size, count, buffer, increment);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tsysbus_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_ABSTRACT) {\n\t\t\tif (mem_should_skip_abstract(target, address, size, increment, true, &abstract_result))\n\t\t\t\tcontinue;\n\n\t\t\tret = read_memory_abstract(target, address, size, count, buffer, increment);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tabstract_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_UNSPECIFIED)\n\t\t\t/* No further mem access method to try. */\n\t\t\tbreak;\n\n\t\tlog_mem_access_result(target, ret == ERROR_OK, method, true);\n\n\t\tif (ret == ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tLOG_ERROR(\"Target %s: Failed to read memory (addr=0x%\" PRIx64 \")\", target_name(target), address);\n\tLOG_ERROR(\"  progbuf=%s, sysbus=%s, abstract=%s\", progbuf_result, sysbus_result, abstract_result);\n\treturn ret;\n}\n\nstatic int write_memory_bus_v0(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\t/*1) write sbaddress: for singlewrite and autoincrement, we need to write the address once*/\n\tLOG_DEBUG(\"System Bus Access: size: %d\\tcount:%d\\tstart address: 0x%08\"\n\t\t\tTARGET_PRIxADDR, size, count, address);\n\tdmi_write(target, DM_SBADDRESS0, address);\n\tint64_t value = 0;\n\tint64_t access = 0;\n\triscv_addr_t offset = 0;\n\triscv_addr_t t_addr = 0;\n\tconst uint8_t *t_buffer = buffer + offset;\n\n\t/* B.8 Writing Memory, single write check if we write in one go */\n\tif (count == 1) { /* count is in bytes here */\n\t\tvalue = buf_get_u64(t_buffer, 0, 8 * size);\n\n\t\taccess = 0;\n\t\taccess = set_field(access, DM_SBCS_SBACCESS, size/2);\n\t\tdmi_write(target, DM_SBCS, access);\n\t\tLOG_DEBUG(\"\\r\\naccess:  0x%08\" PRIx64, access);\n\t\tLOG_DEBUG(\"\\r\\nwrite_memory:SAB: ONE OFF: value 0x%08\" PRIx64, value);\n\t\tdmi_write(target, DM_SBDATA0, value);\n\t\treturn ERROR_OK;\n\t}\n\n\t/*B.8 Writing Memory, using autoincrement*/\n\n\taccess = 0;\n\taccess = set_field(access, DM_SBCS_SBACCESS, size/2);\n\taccess = set_field(access, DM_SBCS_SBAUTOINCREMENT, 1);\n\tLOG_DEBUG(\"\\r\\naccess:  0x%08\" PRIx64, access);\n\tdmi_write(target, DM_SBCS, access);\n\n\t/*2)set the value according to the size required and write*/\n\tfor (riscv_addr_t i = 0; i < count; ++i) {\n\t\toffset = size*i;\n\t\t/* for monitoring only */\n\t\tt_addr = address + offset;\n\t\tt_buffer = buffer + offset;\n\n\t\tvalue = buf_get_u64(t_buffer, 0, 8 * size);\n\t\tLOG_DEBUG(\"SAB:autoincrement: expected address: 0x%08x value: 0x%08x\"\n\t\t\t\tPRIx64, (uint32_t)t_addr, (uint32_t)value);\n\t\tdmi_write(target, DM_SBDATA0, value);\n\t}\n\t/*reset the autoincrement when finished (something weird is happening if this is not done at the end*/\n\taccess = set_field(access, DM_SBCS_SBAUTOINCREMENT, 0);\n\tdmi_write(target, DM_SBCS, access);\n\n\treturn ERROR_OK;\n}\n\nstatic int write_memory_bus_v1(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tRISCV013_INFO(info);\n\tuint32_t sbcs = sb_sbaccess(size);\n\tsbcs = set_field(sbcs, DM_SBCS_SBAUTOINCREMENT, 1);\n\tdmi_write(target, DM_SBCS, sbcs);\n\n\ttarget_addr_t next_address = address;\n\ttarget_addr_t end_address = address + count * size;\n\n\tint result;\n\n\tsb_write_address(target, next_address, true);\n\twhile (next_address < end_address) {\n\t\tLOG_DEBUG(\"transferring burst starting at address 0x%\" TARGET_PRIxADDR,\n\t\t\t\tnext_address);\n\n\t\tstruct riscv_batch *batch = riscv_batch_alloc(\n\t\t\t\ttarget,\n\t\t\t\t32,\n\t\t\t\tinfo->dmi_busy_delay + info->bus_master_write_delay);\n\t\tif (!batch)\n\t\t\treturn ERROR_FAIL;\n\n\t\tfor (uint32_t i = (next_address - address) / size; i < count; i++) {\n\t\t\tconst uint8_t *p = buffer + i * size;\n\n\t\t\tif (riscv_batch_available_scans(batch) < (size + 3) / 4)\n\t\t\t\tbreak;\n\n\t\t\tif (size > 12)\n\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBDATA3,\n\t\t\t\t\t\t((uint32_t) p[12]) |\n\t\t\t\t\t\t(((uint32_t) p[13]) << 8) |\n\t\t\t\t\t\t(((uint32_t) p[14]) << 16) |\n\t\t\t\t\t\t(((uint32_t) p[15]) << 24));\n\n\t\t\tif (size > 8)\n\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBDATA2,\n\t\t\t\t\t\t((uint32_t) p[8]) |\n\t\t\t\t\t\t(((uint32_t) p[9]) << 8) |\n\t\t\t\t\t\t(((uint32_t) p[10]) << 16) |\n\t\t\t\t\t\t(((uint32_t) p[11]) << 24));\n\t\t\tif (size > 4)\n\t\t\t\triscv_batch_add_dmi_write(batch, DM_SBDATA1,\n\t\t\t\t\t\t((uint32_t) p[4]) |\n\t\t\t\t\t\t(((uint32_t) p[5]) << 8) |\n\t\t\t\t\t\t(((uint32_t) p[6]) << 16) |\n\t\t\t\t\t\t(((uint32_t) p[7]) << 24));\n\t\t\tuint32_t value = p[0];\n\t\t\tif (size > 2) {\n\t\t\t\tvalue |= ((uint32_t) p[2]) << 16;\n\t\t\t\tvalue |= ((uint32_t) p[3]) << 24;\n\t\t\t}\n\t\t\tif (size > 1)\n\t\t\t\tvalue |= ((uint32_t) p[1]) << 8;\n\t\t\triscv_batch_add_dmi_write(batch, DM_SBDATA0, value);\n\n\t\t\tlog_memory_access(address + i * size, value, size, false);\n\t\t\tnext_address += size;\n\t\t}\n\n\t\t/* Execute the batch of writes */\n\t\tresult = batch_run(target, batch);\n\t\triscv_batch_free(batch);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\t/* Read sbcs value.\n\t\t * At the same time, detect if DMI busy has occurred during the batch write. */\n\t\tbool dmi_busy_encountered;\n\t\tif (dmi_op(target, &sbcs, &dmi_busy_encountered, DMI_OP_READ,\n\t\t\t\tDM_SBCS, 0, false, true) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (dmi_busy_encountered)\n\t\t\tLOG_DEBUG(\"DMI busy encountered during system bus write.\");\n\n\t\t/* Wait until sbbusy goes low */\n\t\ttime_t start = time(NULL);\n\t\twhile (get_field(sbcs, DM_SBCS_SBBUSY)) {\n\t\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\t\tLOG_ERROR(\"Timed out after %ds waiting for sbbusy to go low (sbcs=0x%x). \"\n\t\t\t\t\t\t  \"Increase the timeout with riscv set_command_timeout_sec.\",\n\t\t\t\t\t\t  riscv_command_timeout_sec, sbcs);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tif (dmi_read(target, &sbcs, DM_SBCS) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (get_field(sbcs, DM_SBCS_SBBUSYERROR)) {\n\t\t\t/* We wrote while the target was busy. */\n\t\t\tLOG_DEBUG(\"Sbbusyerror encountered during system bus write.\");\n\t\t\t/* Clear the sticky error flag. */\n\t\t\tdmi_write(target, DM_SBCS, sbcs | DM_SBCS_SBBUSYERROR);\n\t\t\t/* Slow down before trying again. */\n\t\t\tinfo->bus_master_write_delay += info->bus_master_write_delay / 10 + 1;\n\t\t}\n\n\t\tif (get_field(sbcs, DM_SBCS_SBBUSYERROR) || dmi_busy_encountered) {\n\t\t\t/* Recover from the case when the write commands were issued too fast.\n\t\t\t * Determine the address from which to resume writing. */\n\t\t\tnext_address = sb_read_address(target);\n\t\t\tif (next_address < address) {\n\t\t\t\t/* This should never happen, probably buggy hardware. */\n\t\t\t\tLOG_DEBUG(\"unexpected sbaddress=0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\t  \" - buggy sbautoincrement in hw?\", next_address);\n\t\t\t\t/* Fail the whole operation. */\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\t/* Try again - resume writing. */\n\t\t\tcontinue;\n\t\t}\n\n\t\tunsigned int sberror = get_field(sbcs, DM_SBCS_SBERROR);\n\t\tif (sberror != 0) {\n\t\t\t/* Sberror indicates the bus access failed, but not because we issued the writes\n\t\t\t * too fast. Cannot recover. Sbaddress holds the address where the error occurred\n\t\t\t * (unless sbautoincrement in the HW is buggy).\n\t\t\t */\n\t\t\ttarget_addr_t sbaddress = sb_read_address(target);\n\t\t\tLOG_DEBUG(\"System bus access failed with sberror=%u (sbaddress=0x%\" TARGET_PRIxADDR \")\",\n\t\t\t\t\t  sberror, sbaddress);\n\t\t\tif (sbaddress < address) {\n\t\t\t\t/* This should never happen, probably buggy hardware.\n\t\t\t\t * Make a note to the user not to trust the sbaddress value. */\n\t\t\t\tLOG_DEBUG(\"unexpected sbaddress=0x%\" TARGET_PRIxADDR\n\t\t\t\t\t\t  \" - buggy sbautoincrement in hw?\", next_address);\n\t\t\t}\n\t\t\t/* Clear the sticky error flag */\n\t\t\tdmi_write(target, DM_SBCS, DM_SBCS_SBERROR);\n\t\t\t/* Fail the whole operation */\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int write_memory_progbuf(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tRISCV013_INFO(info);\n\n\tif (riscv_xlen(target) < size * 8) {\n\t\tLOG_ERROR(\"XLEN (%d) is too short for %d-bit memory write.\",\n\t\t\t\triscv_xlen(target), size * 8);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"writing %d words of %d bytes to 0x%08lx\", count, size, (long)address);\n\n\tselect_dmi(target);\n\n\tuint64_t mstatus = 0;\n\tuint64_t mstatus_old = 0;\n\tif (modify_privilege(target, &mstatus, &mstatus_old) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* s0 holds the next address to write to\n\t * s1 holds the next data value to write\n\t */\n\n\tint result = ERROR_OK;\n\tuint64_t s0, s1;\n\tif (register_read(target, &s0, GDB_REGNO_S0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_read(target, &s1, GDB_REGNO_S1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Write the program (store, increment) */\n\tstruct riscv_program program;\n\triscv_program_init(&program, target);\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrsi(&program, GDB_REGNO_ZERO, CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\n\tswitch (size) {\n\t\tcase 1:\n\t\t\triscv_program_sbr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\triscv_program_shr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\triscv_program_swr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\triscv_program_sdr(&program, GDB_REGNO_S1, GDB_REGNO_S0, 0);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"write_memory_progbuf(): Unsupported size: %d\", size);\n\t\t\tresult = ERROR_FAIL;\n\t\t\tgoto error;\n\t}\n\n\tif (riscv_enable_virtual && has_sufficient_progbuf(target, 5) && get_field(mstatus, MSTATUS_MPRV))\n\t\triscv_program_csrrci(&program, GDB_REGNO_ZERO,  CSR_DCSR_MPRVEN, GDB_REGNO_DCSR);\n\triscv_program_addi(&program, GDB_REGNO_S0, GDB_REGNO_S0, size);\n\n\tresult = riscv_program_ebreak(&program);\n\tif (result != ERROR_OK)\n\t\tgoto error;\n\triscv_program_write(&program);\n\n\triscv_addr_t cur_addr = address;\n\triscv_addr_t fin_addr = address + (count * size);\n\tbool setup_needed = true;\n\tLOG_DEBUG(\"writing until final address 0x%016\" PRIx64, fin_addr);\n\twhile (cur_addr < fin_addr) {\n\t\tLOG_DEBUG(\"transferring burst starting at address 0x%016\" PRIx64,\n\t\t\t\tcur_addr);\n\n\t\tstruct riscv_batch *batch = riscv_batch_alloc(\n\t\t\t\ttarget,\n\t\t\t\t32,\n\t\t\t\tinfo->dmi_busy_delay + info->ac_busy_delay);\n\t\tif (!batch)\n\t\t\tgoto error;\n\n\t\t/* To write another word, we put it in S1 and execute the program. */\n\t\tunsigned start = (cur_addr - address) / size;\n\t\tfor (unsigned i = start; i < count; ++i) {\n\t\t\tunsigned offset = size*i;\n\t\t\tconst uint8_t *t_buffer = buffer + offset;\n\n\t\t\tuint64_t value = buf_get_u64(t_buffer, 0, 8 * size);\n\n\t\t\tlog_memory_access(address + offset, value, size, false);\n\t\t\tcur_addr += size;\n\n\t\t\tif (setup_needed) {\n\t\t\t\tresult = register_write_direct(target, GDB_REGNO_S0,\n\t\t\t\t\t\taddress + offset);\n\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\t/* Write value. */\n\t\t\t\tif (size > 4)\n\t\t\t\t\tdmi_write(target, DM_DATA1, value >> 32);\n\t\t\t\tdmi_write(target, DM_DATA0, value);\n\n\t\t\t\t/* Write and execute command that moves value into S1 and\n\t\t\t\t * executes program buffer. */\n\t\t\t\tuint32_t command = access_register_command(target,\n\t\t\t\t\t\tGDB_REGNO_S1, riscv_xlen(target),\n\t\t\t\t\t\tAC_ACCESS_REGISTER_POSTEXEC |\n\t\t\t\t\t\tAC_ACCESS_REGISTER_TRANSFER |\n\t\t\t\t\t\tAC_ACCESS_REGISTER_WRITE);\n\t\t\t\tresult = execute_abstract_command(target, command);\n\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\triscv_batch_free(batch);\n\t\t\t\t\tgoto error;\n\t\t\t\t}\n\n\t\t\t\t/* Turn on autoexec */\n\t\t\t\tdmi_write(target, DM_ABSTRACTAUTO,\n\t\t\t\t\t\t1 << DM_ABSTRACTAUTO_AUTOEXECDATA_OFFSET);\n\n\t\t\t\tsetup_needed = false;\n\t\t\t} else {\n\t\t\t\tif (size > 4)\n\t\t\t\t\triscv_batch_add_dmi_write(batch, DM_DATA1, value >> 32);\n\t\t\t\triscv_batch_add_dmi_write(batch, DM_DATA0, value);\n\t\t\t\tif (riscv_batch_full(batch))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tresult = batch_run(target, batch);\n\t\triscv_batch_free(batch);\n\t\tif (result != ERROR_OK)\n\t\t\tgoto error;\n\n\t\t/* Note that if the scan resulted in a Busy DMI response, it\n\t\t * is this read to abstractcs that will cause the dmi_busy_delay\n\t\t * to be incremented if necessary. */\n\n\t\tuint32_t abstractcs;\n\t\tbool dmi_busy_encountered;\n\t\tresult = dmi_op(target, &abstractcs, &dmi_busy_encountered,\n\t\t\t\tDMI_OP_READ, DM_ABSTRACTCS, 0, false, true);\n\t\tif (result != ERROR_OK)\n\t\t\tgoto error;\n\t\twhile (get_field(abstractcs, DM_ABSTRACTCS_BUSY))\n\t\t\tif (dmi_read(target, &abstractcs, DM_ABSTRACTCS) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\tinfo->cmderr = get_field(abstractcs, DM_ABSTRACTCS_CMDERR);\n\t\tif (info->cmderr == CMDERR_NONE && !dmi_busy_encountered) {\n\t\t\tLOG_DEBUG(\"successful (partial?) memory write\");\n\t\t} else if (info->cmderr == CMDERR_BUSY || dmi_busy_encountered) {\n\t\t\tif (info->cmderr == CMDERR_BUSY)\n\t\t\t\tLOG_DEBUG(\"Memory write resulted in abstract command busy response.\");\n\t\t\telse if (dmi_busy_encountered)\n\t\t\t\tLOG_DEBUG(\"Memory write resulted in DMI busy response.\");\n\t\t\triscv013_clear_abstract_error(target);\n\t\t\tincrease_ac_busy_delay(target);\n\n\t\t\tdmi_write(target, DM_ABSTRACTAUTO, 0);\n\t\t\tresult = register_read_direct(target, &cur_addr, GDB_REGNO_S0);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\tgoto error;\n\t\t\tsetup_needed = true;\n\t\t} else {\n\t\t\tLOG_ERROR(\"error when writing memory, abstractcs=0x%08lx\", (long)abstractcs);\n\t\t\triscv013_clear_abstract_error(target);\n\t\t\tresult = ERROR_FAIL;\n\t\t\tgoto error;\n\t\t}\n\t}\n\nerror:\n\tdmi_write(target, DM_ABSTRACTAUTO, 0);\n\n\tif (register_write_direct(target, GDB_REGNO_S1, s1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (register_write_direct(target, GDB_REGNO_S0, s0) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Restore MSTATUS */\n\tif (mstatus != mstatus_old)\n\t\tif (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))\n\t\t\treturn ERROR_FAIL;\n\n\tif (execute_fence(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn result;\n}\n\nstatic int write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tif (size != 1 && size != 2 && size != 4 && size != 8 && size != 16) {\n\t\tLOG_ERROR(\"BUG: Unsupported size for memory write: %d\", size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = ERROR_FAIL;\n\tRISCV_INFO(r);\n\tRISCV013_INFO(info);\n\n\tchar *progbuf_result = \"disabled\";\n\tchar *sysbus_result = \"disabled\";\n\tchar *abstract_result = \"disabled\";\n\n\tfor (unsigned int i = 0; i < RISCV_NUM_MEM_ACCESS_METHODS; i++) {\n\t\tint method = r->mem_access_methods[i];\n\n\t\tif (method == RISCV_MEM_ACCESS_PROGBUF) {\n\t\t\tif (mem_should_skip_progbuf(target, address, size, false, &progbuf_result))\n\t\t\t\tcontinue;\n\n\t\t\tret = write_memory_progbuf(target, address, size, count, buffer);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tprogbuf_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_SYSBUS) {\n\t\t\tif (mem_should_skip_sysbus(target, address, size, 0, false, &sysbus_result))\n\t\t\t\tcontinue;\n\n\t\t\tif (get_field(info->sbcs, DM_SBCS_SBVERSION) == 0)\n\t\t\t\tret = write_memory_bus_v0(target, address, size, count, buffer);\n\t\t\telse if (get_field(info->sbcs, DM_SBCS_SBVERSION) == 1)\n\t\t\t\tret = write_memory_bus_v1(target, address, size, count, buffer);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tsysbus_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_ABSTRACT) {\n\t\t\tif (mem_should_skip_abstract(target, address, size, 0, false, &abstract_result))\n\t\t\t\tcontinue;\n\n\t\t\tret = write_memory_abstract(target, address, size, count, buffer);\n\n\t\t\tif (ret != ERROR_OK)\n\t\t\t\tabstract_result = \"failed\";\n\t\t} else if (method == RISCV_MEM_ACCESS_UNSPECIFIED)\n\t\t\t/* No further mem access method to try. */\n\t\t\tbreak;\n\n\t\tlog_mem_access_result(target, ret == ERROR_OK, method, false);\n\n\t\tif (ret == ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tLOG_ERROR(\"Target %s: Failed to write memory (addr=0x%\" PRIx64 \")\", target_name(target), address);\n\tLOG_ERROR(\"  progbuf=%s, sysbus=%s, abstract=%s\", progbuf_result, sysbus_result, abstract_result);\n\treturn ret;\n}\n\nstatic int arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstruct target_type riscv013_target = {\n\t.name = \"riscv\",\n\n\t.init_target = init_target,\n\t.deinit_target = deinit_target,\n\t.examine = examine,\n\n\t.poll = &riscv_openocd_poll,\n\t.halt = &riscv_halt,\n\t.step = &riscv_openocd_step,\n\n\t.assert_reset = assert_reset,\n\t.deassert_reset = deassert_reset,\n\n\t.write_memory = write_memory,\n\n\t.arch_state = arch_state\n};\n\n/*** 0.13-specific implementations of various RISC-V helper functions. ***/\nstatic int riscv013_get_register(struct target *target,\n\t\triscv_reg_t *value, int rid)\n{\n\tLOG_DEBUG(\"[%s] reading register %s\", target_name(target),\n\t\t\tgdb_regno_name(rid));\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tint result = ERROR_OK;\n\tif (rid == GDB_REGNO_PC) {\n\t\t/* TODO: move this into riscv.c. */\n\t\tresult = register_read(target, value, GDB_REGNO_DPC);\n\t\tLOG_DEBUG(\"[%d] read PC from DPC: 0x%\" PRIx64, target->coreid, *value);\n\t} else if (rid == GDB_REGNO_PRIV) {\n\t\tuint64_t dcsr;\n\t\t/* TODO: move this into riscv.c. */\n\t\tresult = register_read(target, &dcsr, GDB_REGNO_DCSR);\n\t\t*value = set_field(0, VIRT_PRIV_V, get_field(dcsr, CSR_DCSR_V));\n\t\t*value = set_field(*value, VIRT_PRIV_PRV, get_field(dcsr, CSR_DCSR_PRV));\n\t} else {\n\t\tresult = register_read(target, value, rid);\n\t\tif (result != ERROR_OK)\n\t\t\t*value = -1;\n\t}\n\n\treturn result;\n}\n\nstatic int riscv013_set_register(struct target *target, int rid, uint64_t value)\n{\n\triscv013_select_current_hart(target);\n\tLOG_DEBUG(\"[%d] writing 0x%\" PRIx64 \" to register %s\",\n\t\t\ttarget->coreid, value, gdb_regno_name(rid));\n\n\tif (rid <= GDB_REGNO_XPR31) {\n\t\treturn register_write_direct(target, rid, value);\n\t} else if (rid == GDB_REGNO_PC) {\n\t\tLOG_DEBUG(\"[%d] writing PC to DPC: 0x%\" PRIx64, target->coreid, value);\n\t\tregister_write_direct(target, GDB_REGNO_DPC, value);\n\t\tuint64_t actual_value;\n\t\tregister_read_direct(target, &actual_value, GDB_REGNO_DPC);\n\t\tLOG_DEBUG(\"[%d]   actual DPC written: 0x%016\" PRIx64, target->coreid, actual_value);\n\t\tif (value != actual_value) {\n\t\t\tLOG_ERROR(\"Written PC (0x%\" PRIx64 \") does not match read back \"\n\t\t\t\t\t\"value (0x%\" PRIx64 \")\", value, actual_value);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else if (rid == GDB_REGNO_PRIV) {\n\t\tuint64_t dcsr;\n\t\tregister_read(target, &dcsr, GDB_REGNO_DCSR);\n\t\tdcsr = set_field(dcsr, CSR_DCSR_PRV, get_field(value, VIRT_PRIV_PRV));\n\t\tdcsr = set_field(dcsr, CSR_DCSR_V, get_field(value, VIRT_PRIV_V));\n\t\treturn register_write_direct(target, GDB_REGNO_DCSR, dcsr);\n\t} else {\n\t\treturn register_write_direct(target, rid, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_select_current_hart(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tdm013_info_t *dm = get_dm(target);\n\tif (!dm)\n\t\treturn ERROR_FAIL;\n\tif (r->current_hartid == dm->current_hartid)\n\t\treturn ERROR_OK;\n\n\tuint32_t dmcontrol;\n\t/* TODO: can't we just \"dmcontrol = DMI_DMACTIVE\"? */\n\tif (dmi_read(target, &dmcontrol, DM_DMCONTROL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tdmcontrol = set_hartsel(dmcontrol, r->current_hartid);\n\tint result = dmi_write(target, DM_DMCONTROL, dmcontrol);\n\tdm->current_hartid = r->current_hartid;\n\treturn result;\n}\n\n/* Select all harts that were prepped and that are selectable, clearing the\n * prepped flag on the harts that actually were selected. */\nstatic int select_prepped_harts(struct target *target, bool *use_hasel)\n{\n\tdm013_info_t *dm = get_dm(target);\n\tif (!dm)\n\t\treturn ERROR_FAIL;\n\tif (!dm->hasel_supported) {\n\t\tRISCV_INFO(r);\n\t\tr->prepped = false;\n\t\t*use_hasel = false;\n\t\treturn ERROR_OK;\n\t}\n\n\tassert(dm->hart_count);\n\tunsigned hawindow_count = (dm->hart_count + 31) / 32;\n\tuint32_t hawindow[hawindow_count];\n\n\tmemset(hawindow, 0, sizeof(uint32_t) * hawindow_count);\n\n\ttarget_list_t *entry;\n\tunsigned total_selected = 0;\n\tlist_for_each_entry(entry, &dm->target_list, list) {\n\t\tstruct target *t = entry->target;\n\t\tstruct riscv_info *r = riscv_info(t);\n\t\triscv013_info_t *info = get_info(t);\n\t\tunsigned index = info->index;\n\t\tLOG_DEBUG(\"index=%d, coreid=%d, prepped=%d\", index, t->coreid, r->prepped);\n\t\tr->selected = r->prepped;\n\t\tif (r->prepped) {\n\t\t\thawindow[index / 32] |= 1 << (index % 32);\n\t\t\tr->prepped = false;\n\t\t\ttotal_selected++;\n\t\t}\n\t\tindex++;\n\t}\n\n\t/* Don't use hasel if we only need to talk to one hart. */\n\tif (total_selected <= 1) {\n\t\t*use_hasel = false;\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (unsigned i = 0; i < hawindow_count; i++) {\n\t\tif (dmi_write(target, DM_HAWINDOWSEL, i) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (dmi_write(target, DM_HAWINDOW, hawindow[i]) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t*use_hasel = true;\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_halt_prep(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_halt_go(struct target *target)\n{\n\tbool use_hasel = false;\n\tif (select_prepped_harts(target, &use_hasel) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"halting hart %d\", r->current_hartid);\n\n\t/* Issue the halt command, and then wait for the current hart to halt. */\n\tuint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_HALTREQ;\n\tif (use_hasel)\n\t\tdmcontrol |= DM_DMCONTROL_HASEL;\n\tdmcontrol = set_hartsel(dmcontrol, r->current_hartid);\n\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\tfor (size_t i = 0; i < 256; ++i)\n\t\tif (riscv_is_halted(target))\n\t\t\tbreak;\n\n\tif (!riscv_is_halted(target)) {\n\t\tuint32_t dmstatus;\n\t\tif (dmstatus_read(target, &dmstatus, true) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (dmi_read(target, &dmcontrol, DM_DMCONTROL) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tLOG_ERROR(\"unable to halt hart %d\", r->current_hartid);\n\t\tLOG_ERROR(\"  dmcontrol=0x%08x\", dmcontrol);\n\t\tLOG_ERROR(\"  dmstatus =0x%08x\", dmstatus);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdmcontrol = set_field(dmcontrol, DM_DMCONTROL_HALTREQ, 0);\n\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\n\tif (use_hasel) {\n\t\ttarget_list_t *entry;\n\t\tdm013_info_t *dm = get_dm(target);\n\t\tif (!dm)\n\t\t\treturn ERROR_FAIL;\n\t\tlist_for_each_entry(entry, &dm->target_list, list) {\n\t\t\tstruct target *t = entry->target;\n\t\t\tt->state = TARGET_HALTED;\n\t\t\tif (t->debug_reason == DBG_REASON_NOTHALTED)\n\t\t\t\tt->debug_reason = DBG_REASON_DBGRQ;\n\t\t}\n\t}\n\t/* The \"else\" case is handled in halt_go(). */\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv013_resume_go(struct target *target)\n{\n\tbool use_hasel = false;\n\tif (select_prepped_harts(target, &use_hasel) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn riscv013_step_or_resume_current_hart(target, false, use_hasel);\n}\n\nstatic int riscv013_step_current_hart(struct target *target)\n{\n\treturn riscv013_step_or_resume_current_hart(target, true, false);\n}\n\nstatic int riscv013_resume_prep(struct target *target)\n{\n\treturn riscv013_on_step_or_resume(target, false);\n}\n\nstatic int riscv013_on_step(struct target *target)\n{\n\treturn riscv013_on_step_or_resume(target, true);\n}\n\nstatic int riscv013_on_halt(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic bool riscv013_is_halted(struct target *target)\n{\n\tuint32_t dmstatus;\n\tif (dmstatus_read(target, &dmstatus, true) != ERROR_OK)\n\t\treturn false;\n\tif (get_field(dmstatus, DM_DMSTATUS_ANYUNAVAIL))\n\t\tLOG_ERROR(\"Hart %d is unavailable.\", riscv_current_hartid(target));\n\tif (get_field(dmstatus, DM_DMSTATUS_ANYNONEXISTENT))\n\t\tLOG_ERROR(\"Hart %d doesn't exist.\", riscv_current_hartid(target));\n\tif (get_field(dmstatus, DM_DMSTATUS_ANYHAVERESET)) {\n\t\tint hartid = riscv_current_hartid(target);\n\t\tLOG_INFO(\"Hart %d unexpectedly reset!\", hartid);\n\t\t/* TODO: Can we make this more obvious to eg. a gdb user? */\n\t\tuint32_t dmcontrol = DM_DMCONTROL_DMACTIVE |\n\t\t\tDM_DMCONTROL_ACKHAVERESET;\n\t\tdmcontrol = set_hartsel(dmcontrol, hartid);\n\t\t/* If we had been halted when we reset, request another halt. If we\n\t\t * ended up running out of reset, then the user will (hopefully) get a\n\t\t * message that a reset happened, that the target is running, and then\n\t\t * that it is halted again once the request goes through.\n\t\t */\n\t\tif (target->state == TARGET_HALTED)\n\t\t\tdmcontrol |= DM_DMCONTROL_HALTREQ;\n\t\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\t}\n\treturn get_field(dmstatus, DM_DMSTATUS_ALLHALTED);\n}\n\nstatic enum riscv_halt_reason riscv013_halt_reason(struct target *target)\n{\n\triscv_reg_t dcsr;\n\tint result = register_read(target, &dcsr, GDB_REGNO_DCSR);\n\tif (result != ERROR_OK)\n\t\treturn RISCV_HALT_UNKNOWN;\n\n\tLOG_DEBUG(\"dcsr.cause: 0x%\" PRIx64, get_field(dcsr, CSR_DCSR_CAUSE));\n\n\tswitch (get_field(dcsr, CSR_DCSR_CAUSE)) {\n\tcase CSR_DCSR_CAUSE_SWBP:\n\t\treturn RISCV_HALT_BREAKPOINT;\n\tcase CSR_DCSR_CAUSE_TRIGGER:\n\t\t/* We could get here before triggers are enumerated if a trigger was\n\t\t * already set when we connected. Force enumeration now, which has the\n\t\t * side effect of clearing any triggers we did not set. */\n\t\triscv_enumerate_triggers(target);\n\t\tLOG_DEBUG(\"{%d} halted because of trigger\", target->coreid);\n\t\treturn RISCV_HALT_TRIGGER;\n\tcase CSR_DCSR_CAUSE_STEP:\n\t\treturn RISCV_HALT_SINGLESTEP;\n\tcase CSR_DCSR_CAUSE_DEBUGINT:\n\tcase CSR_DCSR_CAUSE_HALT:\n\t\treturn RISCV_HALT_INTERRUPT;\n\tcase CSR_DCSR_CAUSE_GROUP:\n\t\treturn RISCV_HALT_GROUP;\n\t}\n\n\tLOG_ERROR(\"Unknown DCSR cause field: 0x%\" PRIx64, get_field(dcsr, CSR_DCSR_CAUSE));\n\tLOG_ERROR(\"  dcsr=0x%016lx\", (long)dcsr);\n\treturn RISCV_HALT_UNKNOWN;\n}\n\nint riscv013_write_debug_buffer(struct target *target, unsigned index, riscv_insn_t data)\n{\n\tdm013_info_t *dm = get_dm(target);\n\tif (!dm)\n\t\treturn ERROR_FAIL;\n\tif (dm->progbuf_cache[index] != data) {\n\t\tif (dmi_write(target, DM_PROGBUF0 + index, data) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tdm->progbuf_cache[index] = data;\n\t} else {\n\t\tLOG_DEBUG(\"cache hit for 0x%\" PRIx32 \" @%d\", data, index);\n\t}\n\treturn ERROR_OK;\n}\n\nriscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned index)\n{\n\tuint32_t value;\n\tdmi_read(target, &value, DM_PROGBUF0 + index);\n\treturn value;\n}\n\nint riscv013_execute_debug_buffer(struct target *target)\n{\n\tuint32_t run_program = 0;\n\trun_program = set_field(run_program, AC_ACCESS_REGISTER_AARSIZE, 2);\n\trun_program = set_field(run_program, AC_ACCESS_REGISTER_POSTEXEC, 1);\n\trun_program = set_field(run_program, AC_ACCESS_REGISTER_TRANSFER, 0);\n\trun_program = set_field(run_program, AC_ACCESS_REGISTER_REGNO, 0x1000);\n\n\treturn execute_abstract_command(target, run_program);\n}\n\nvoid riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d)\n{\n\tRISCV013_INFO(info);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, DMI_OP_WRITE);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, d);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, a);\n}\n\nvoid riscv013_fill_dmi_read_u64(struct target *target, char *buf, int a)\n{\n\tRISCV013_INFO(info);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, DMI_OP_READ);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, 0);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, a);\n}\n\nvoid riscv013_fill_dmi_nop_u64(struct target *target, char *buf)\n{\n\tRISCV013_INFO(info);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_OP_OFFSET, DTM_DMI_OP_LENGTH, DMI_OP_NOP);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_DATA_OFFSET, DTM_DMI_DATA_LENGTH, 0);\n\tbuf_set_u64((unsigned char *)buf, DTM_DMI_ADDRESS_OFFSET, info->abits, 0);\n}\n\nint riscv013_dmi_write_u64_bits(struct target *target)\n{\n\tRISCV013_INFO(info);\n\treturn info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;\n}\n\nstatic int maybe_execute_fence_i(struct target *target)\n{\n\tif (has_sufficient_progbuf(target, 3))\n\t\treturn execute_fence(target);\n\treturn ERROR_OK;\n}\n\n/* Helper Functions. */\nstatic int riscv013_on_step_or_resume(struct target *target, bool step)\n{\n\tif (maybe_execute_fence_i(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* We want to twiddle some bits in the debug CSR so debugging works. */\n\triscv_reg_t dcsr;\n\tint result = register_read(target, &dcsr, GDB_REGNO_DCSR);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\tdcsr = set_field(dcsr, CSR_DCSR_STEP, step);\n\tdcsr = set_field(dcsr, CSR_DCSR_EBREAKM, riscv_ebreakm);\n\tdcsr = set_field(dcsr, CSR_DCSR_EBREAKS, riscv_ebreaks);\n\tdcsr = set_field(dcsr, CSR_DCSR_EBREAKU, riscv_ebreaku);\n\treturn riscv_set_register(target, GDB_REGNO_DCSR, dcsr);\n}\n\nstatic int riscv013_step_or_resume_current_hart(struct target *target,\n\t\tbool step, bool use_hasel)\n{\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"resuming hart %d (for step?=%d)\", r->current_hartid, step);\n\tif (!riscv_is_halted(target)) {\n\t\tLOG_ERROR(\"Hart %d is not halted!\", r->current_hartid);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Issue the resume command, and then wait for the current hart to resume. */\n\tuint32_t dmcontrol = DM_DMCONTROL_DMACTIVE | DM_DMCONTROL_RESUMEREQ;\n\tif (use_hasel)\n\t\tdmcontrol |= DM_DMCONTROL_HASEL;\n\tdmcontrol = set_hartsel(dmcontrol, r->current_hartid);\n\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\n\tdmcontrol = set_field(dmcontrol, DM_DMCONTROL_HASEL, 0);\n\tdmcontrol = set_field(dmcontrol, DM_DMCONTROL_RESUMEREQ, 0);\n\n\tuint32_t dmstatus;\n\tfor (size_t i = 0; i < 256; ++i) {\n\t\tusleep(10);\n\t\tif (dmstatus_read(target, &dmstatus, true) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tif (get_field(dmstatus, DM_DMSTATUS_ALLRESUMEACK) == 0)\n\t\t\tcontinue;\n\t\tif (step && get_field(dmstatus, DM_DMSTATUS_ALLHALTED) == 0)\n\t\t\tcontinue;\n\n\t\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\t\treturn ERROR_OK;\n\t}\n\n\tdmi_write(target, DM_DMCONTROL, dmcontrol);\n\n\tLOG_ERROR(\"unable to resume hart %d\", r->current_hartid);\n\tif (dmstatus_read(target, &dmstatus, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_ERROR(\"  dmstatus =0x%08x\", dmstatus);\n\n\tif (step) {\n\t\tLOG_ERROR(\"  was stepping, halting\");\n\t\triscv_halt(target);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nvoid riscv013_clear_abstract_error(struct target *target)\n{\n\t/* Wait for busy to go away. */\n\ttime_t start = time(NULL);\n\tuint32_t abstractcs;\n\tdmi_read(target, &abstractcs, DM_ABSTRACTCS);\n\twhile (get_field(abstractcs, DM_ABSTRACTCS_BUSY)) {\n\t\tdmi_read(target, &abstractcs, DM_ABSTRACTCS);\n\n\t\tif (time(NULL) - start > riscv_command_timeout_sec) {\n\t\t\tLOG_ERROR(\"abstractcs.busy is not going low after %d seconds \"\n\t\t\t\t\t\"(abstractcs=0x%x). The target is either really slow or \"\n\t\t\t\t\t\"broken. You could increase the timeout with riscv \"\n\t\t\t\t\t\"set_command_timeout_sec.\",\n\t\t\t\t\triscv_command_timeout_sec, abstractcs);\n\t\t\tbreak;\n\t\t}\n\t}\n\t/* Clear the error status. */\n\tdmi_write(target, DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/riscv.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n#include <assert.h>\n#include <stdlib.h>\n#include <time.h>\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/time_support.h>\n#include \"target/target.h\"\n#include \"target/algorithm.h\"\n#include \"target/target_type.h\"\n#include <target/smp.h>\n#include \"jtag/jtag.h\"\n#include \"target/register.h\"\n#include \"target/breakpoints.h\"\n#include \"riscv.h\"\n#include \"gdb_regs.h\"\n#include \"rtos/rtos.h\"\n#include \"debug_defines.h\"\n#include <helper/bits.h>\n\n#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))\n#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))\n\n/* Constants for legacy SiFive hardware breakpoints. */\n#define CSR_BPCONTROL_X\t\t\t(1<<0)\n#define CSR_BPCONTROL_W\t\t\t(1<<1)\n#define CSR_BPCONTROL_R\t\t\t(1<<2)\n#define CSR_BPCONTROL_U\t\t\t(1<<3)\n#define CSR_BPCONTROL_S\t\t\t(1<<4)\n#define CSR_BPCONTROL_H\t\t\t(1<<5)\n#define CSR_BPCONTROL_M\t\t\t(1<<6)\n#define CSR_BPCONTROL_BPMATCH\t(0xf<<7)\n#define CSR_BPCONTROL_BPACTION\t(0xff<<11)\n\n#define DEBUG_ROM_START         0x800\n#define DEBUG_ROM_RESUME\t(DEBUG_ROM_START + 4)\n#define DEBUG_ROM_EXCEPTION\t(DEBUG_ROM_START + 8)\n#define DEBUG_RAM_START         0x400\n\n#define SETHALTNOT\t\t\t\t0x10c\n\n/*** JTAG registers. ***/\n\n#define DTMCONTROL\t\t\t\t\t0x10\n#define DTMCONTROL_DBUS_RESET\t\t(1<<16)\n#define DTMCONTROL_IDLE\t\t\t\t(7<<10)\n#define DTMCONTROL_ADDRBITS\t\t\t(0xf<<4)\n#define DTMCONTROL_VERSION\t\t\t(0xf)\n\n#define DBUS\t\t\t\t\t\t0x11\n#define DBUS_OP_START\t\t\t\t0\n#define DBUS_OP_SIZE\t\t\t\t2\ntypedef enum {\n\tDBUS_OP_NOP = 0,\n\tDBUS_OP_READ = 1,\n\tDBUS_OP_WRITE = 2\n} dbus_op_t;\ntypedef enum {\n\tDBUS_STATUS_SUCCESS = 0,\n\tDBUS_STATUS_FAILED = 2,\n\tDBUS_STATUS_BUSY = 3\n} dbus_status_t;\n#define DBUS_DATA_START\t\t\t\t2\n#define DBUS_DATA_SIZE\t\t\t\t34\n#define DBUS_ADDRESS_START\t\t\t36\n\ntypedef enum slot {\n\tSLOT0,\n\tSLOT1,\n\tSLOT_LAST,\n} slot_t;\n\n/*** Debug Bus registers. ***/\n\n#define DMCONTROL\t\t\t\t0x10\n#define DMCONTROL_INTERRUPT\t\t(((uint64_t)1)<<33)\n#define DMCONTROL_HALTNOT\t\t(((uint64_t)1)<<32)\n#define DMCONTROL_BUSERROR\t\t(7<<19)\n#define DMCONTROL_SERIAL\t\t(3<<16)\n#define DMCONTROL_AUTOINCREMENT\t(1<<15)\n#define DMCONTROL_ACCESS\t\t(7<<12)\n#define DMCONTROL_HARTID\t\t(0x3ff<<2)\n#define DMCONTROL_NDRESET\t\t(1<<1)\n#define DMCONTROL_FULLRESET\t\t1\n\n#define DMINFO\t\t\t\t\t0x11\n#define DMINFO_ABUSSIZE\t\t\t(0x7fU<<25)\n#define DMINFO_SERIALCOUNT\t\t(0xf<<21)\n#define DMINFO_ACCESS128\t\t(1<<20)\n#define DMINFO_ACCESS64\t\t\t(1<<19)\n#define DMINFO_ACCESS32\t\t\t(1<<18)\n#define DMINFO_ACCESS16\t\t\t(1<<17)\n#define DMINFO_ACCESS8\t\t\t(1<<16)\n#define DMINFO_DRAMSIZE\t\t\t(0x3f<<10)\n#define DMINFO_AUTHENTICATED\t(1<<5)\n#define DMINFO_AUTHBUSY\t\t\t(1<<4)\n#define DMINFO_AUTHTYPE\t\t\t(3<<2)\n#define DMINFO_VERSION\t\t\t3\n\n/*** Info about the core being debugged. ***/\n\n#define DBUS_ADDRESS_UNKNOWN\t0xffff\n\n#define MAX_HWBPS\t\t\t16\n#define DRAM_CACHE_SIZE\t\t16\n\nstatic uint8_t ir_dtmcontrol[4] = {DTMCONTROL};\nstruct scan_field select_dtmcontrol = {\n\t.in_value = NULL,\n\t.out_value = ir_dtmcontrol\n};\nstatic uint8_t ir_dbus[4] = {DBUS};\nstruct scan_field select_dbus = {\n\t.in_value = NULL,\n\t.out_value = ir_dbus\n};\nstatic uint8_t ir_idcode[4] = {0x1};\nstruct scan_field select_idcode = {\n\t.in_value = NULL,\n\t.out_value = ir_idcode\n};\n\nstatic bscan_tunnel_type_t bscan_tunnel_type;\nint bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */\n\nstatic const uint8_t bscan_zero[4] = {0};\nstatic const uint8_t bscan_one[4] = {1};\n\nstatic uint8_t ir_user4[4];\nstatic struct scan_field select_user4 = {\n\t.in_value = NULL,\n\t.out_value = ir_user4\n};\n\n\nstatic uint8_t bscan_tunneled_ir_width[4] = {5};  /* overridden by assignment in riscv_init_target */\nstatic struct scan_field _bscan_tunnel_data_register_select_dmi[] = {\n\t\t{\n\t\t\t.num_bits = 3,\n\t\t\t.out_value = bscan_zero,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 5, /* initialized in riscv_init_target to ir width of DM */\n\t\t\t.out_value = ir_dbus,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 7,\n\t\t\t.out_value = bscan_tunneled_ir_width,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 1,\n\t\t\t.out_value = bscan_zero,\n\t\t\t.in_value = NULL,\n\t\t}\n};\n\nstatic struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {\n\t\t{\n\t\t\t.num_bits = 1,\n\t\t\t.out_value = bscan_zero,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 7,\n\t\t\t.out_value = bscan_tunneled_ir_width,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 0, /* initialized in riscv_init_target to ir width of DM */\n\t\t\t.out_value = ir_dbus,\n\t\t\t.in_value = NULL,\n\t\t},\n\t\t{\n\t\t\t.num_bits = 3,\n\t\t\t.out_value = bscan_zero,\n\t\t\t.in_value = NULL,\n\t\t}\n};\nstatic struct scan_field *bscan_tunnel_nested_tap_select_dmi = _bscan_tunnel_nested_tap_select_dmi;\nstatic uint32_t bscan_tunnel_nested_tap_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_nested_tap_select_dmi);\n\nstatic struct scan_field *bscan_tunnel_data_register_select_dmi = _bscan_tunnel_data_register_select_dmi;\nstatic uint32_t bscan_tunnel_data_register_select_dmi_num_fields = ARRAY_SIZE(_bscan_tunnel_data_register_select_dmi);\n\nstruct trigger {\n\tuint64_t address;\n\tuint32_t length;\n\tuint64_t mask;\n\tuint64_t value;\n\tbool read, write, execute;\n\tint unique_id;\n};\n\n/* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/\nint riscv_command_timeout_sec = DEFAULT_COMMAND_TIMEOUT_SEC;\n\n/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/\nint riscv_reset_timeout_sec = DEFAULT_RESET_TIMEOUT_SEC;\n\nstatic bool riscv_enable_virt2phys = true;\nbool riscv_ebreakm = true;\nbool riscv_ebreaks = true;\nbool riscv_ebreaku = true;\n\nbool riscv_enable_virtual;\n\nstatic enum {\n\tRO_NORMAL,\n\tRO_REVERSED\n} resume_order;\n\nstatic const virt2phys_info_t sv32 = {\n\t.name = \"Sv32\",\n\t.va_bits = 32,\n\t.level = 2,\n\t.pte_shift = 2,\n\t.vpn_shift = {12, 22},\n\t.vpn_mask = {0x3ff, 0x3ff},\n\t.pte_ppn_shift = {10, 20},\n\t.pte_ppn_mask = {0x3ff, 0xfff},\n\t.pa_ppn_shift = {12, 22},\n\t.pa_ppn_mask = {0x3ff, 0xfff},\n};\n\nstatic const virt2phys_info_t sv39 = {\n\t.name = \"Sv39\",\n\t.va_bits = 39,\n\t.level = 3,\n\t.pte_shift = 3,\n\t.vpn_shift = {12, 21, 30},\n\t.vpn_mask = {0x1ff, 0x1ff, 0x1ff},\n\t.pte_ppn_shift = {10, 19, 28},\n\t.pte_ppn_mask = {0x1ff, 0x1ff, 0x3ffffff},\n\t.pa_ppn_shift = {12, 21, 30},\n\t.pa_ppn_mask = {0x1ff, 0x1ff, 0x3ffffff},\n};\n\nstatic const virt2phys_info_t sv48 = {\n\t.name = \"Sv48\",\n\t.va_bits = 48,\n\t.level = 4,\n\t.pte_shift = 3,\n\t.vpn_shift = {12, 21, 30, 39},\n\t.vpn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ff},\n\t.pte_ppn_shift = {10, 19, 28, 37},\n\t.pte_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff},\n\t.pa_ppn_shift = {12, 21, 30, 39},\n\t.pa_ppn_mask = {0x1ff, 0x1ff, 0x1ff, 0x1ffff},\n};\n\nstatic enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid);\nstatic void riscv_info_init(struct target *target, struct riscv_info *r);\nstatic void riscv_invalidate_register_cache(struct target *target);\nstatic int riscv_step_rtos_hart(struct target *target);\n\nstatic void riscv_sample_buf_maybe_add_timestamp(struct target *target, bool before)\n{\n\tRISCV_INFO(r);\n\tuint32_t now = timeval_ms() & 0xffffffff;\n\tif (r->sample_buf.used + 5 < r->sample_buf.size) {\n\t\tif (before)\n\t\t\tr->sample_buf.buf[r->sample_buf.used++] = RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE;\n\t\telse\n\t\t\tr->sample_buf.buf[r->sample_buf.used++] = RISCV_SAMPLE_BUF_TIMESTAMP_AFTER;\n\t\tr->sample_buf.buf[r->sample_buf.used++] = now & 0xff;\n\t\tr->sample_buf.buf[r->sample_buf.used++] = (now >> 8) & 0xff;\n\t\tr->sample_buf.buf[r->sample_buf.used++] = (now >> 16) & 0xff;\n\t\tr->sample_buf.buf[r->sample_buf.used++] = (now >> 24) & 0xff;\n\t}\n}\n\nstatic int riscv_resume_go_all_harts(struct target *target);\n\nvoid select_dmi_via_bscan(struct target *target)\n{\n\tjtag_add_ir_scan(target->tap, &select_user4, TAP_IDLE);\n\tif (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)\n\t\tjtag_add_dr_scan(target->tap, bscan_tunnel_data_register_select_dmi_num_fields,\n\t\t\t\t\t\t\t\t\t\tbscan_tunnel_data_register_select_dmi, TAP_IDLE);\n\telse /* BSCAN_TUNNEL_NESTED_TAP */\n\t\tjtag_add_dr_scan(target->tap, bscan_tunnel_nested_tap_select_dmi_num_fields,\n\t\t\t\t\t\t\t\t\t\tbscan_tunnel_nested_tap_select_dmi, TAP_IDLE);\n}\n\nuint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out)\n{\n\t/* On BSCAN TAP: Select IR=USER4, issue tunneled IR scan via BSCAN TAP's DR */\n\tuint8_t tunneled_ir_width[4] = {bscan_tunnel_ir_width};\n\tuint8_t tunneled_dr_width[4] = {32};\n\tuint8_t out_value[5] = {0};\n\tuint8_t in_value[5] = {0};\n\n\tbuf_set_u32(out_value, 0, 32, out);\n\tstruct scan_field tunneled_ir[4] = {};\n\tstruct scan_field tunneled_dr[4] = {};\n\n\tif (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER) {\n\t\ttunneled_ir[0].num_bits = 3;\n\t\ttunneled_ir[0].out_value = bscan_zero;\n\t\ttunneled_ir[0].in_value = NULL;\n\t\ttunneled_ir[1].num_bits = bscan_tunnel_ir_width;\n\t\ttunneled_ir[1].out_value = ir_dtmcontrol;\n\t\ttunneled_ir[1].in_value = NULL;\n\t\ttunneled_ir[2].num_bits = 7;\n\t\ttunneled_ir[2].out_value = tunneled_ir_width;\n\t\ttunneled_ir[2].in_value = NULL;\n\t\ttunneled_ir[3].num_bits = 1;\n\t\ttunneled_ir[3].out_value = bscan_zero;\n\t\ttunneled_ir[3].in_value = NULL;\n\n\t\ttunneled_dr[0].num_bits = 3;\n\t\ttunneled_dr[0].out_value = bscan_zero;\n\t\ttunneled_dr[0].in_value = NULL;\n\t\ttunneled_dr[1].num_bits = 32 + 1;\n\t\ttunneled_dr[1].out_value = out_value;\n\t\ttunneled_dr[1].in_value = in_value;\n\t\ttunneled_dr[2].num_bits = 7;\n\t\ttunneled_dr[2].out_value = tunneled_dr_width;\n\t\ttunneled_dr[2].in_value = NULL;\n\t\ttunneled_dr[3].num_bits = 1;\n\t\ttunneled_dr[3].out_value = bscan_one;\n\t\ttunneled_dr[3].in_value = NULL;\n\t} else {\n\t\t/* BSCAN_TUNNEL_NESTED_TAP */\n\t\ttunneled_ir[3].num_bits = 3;\n\t\ttunneled_ir[3].out_value = bscan_zero;\n\t\ttunneled_ir[3].in_value = NULL;\n\t\ttunneled_ir[2].num_bits = bscan_tunnel_ir_width;\n\t\ttunneled_ir[2].out_value = ir_dtmcontrol;\n\t\ttunneled_ir[1].in_value = NULL;\n\t\ttunneled_ir[1].num_bits = 7;\n\t\ttunneled_ir[1].out_value = tunneled_ir_width;\n\t\ttunneled_ir[2].in_value = NULL;\n\t\ttunneled_ir[0].num_bits = 1;\n\t\ttunneled_ir[0].out_value = bscan_zero;\n\t\ttunneled_ir[0].in_value = NULL;\n\n\t\ttunneled_dr[3].num_bits = 3;\n\t\ttunneled_dr[3].out_value = bscan_zero;\n\t\ttunneled_dr[3].in_value = NULL;\n\t\ttunneled_dr[2].num_bits = 32 + 1;\n\t\ttunneled_dr[2].out_value = out_value;\n\t\ttunneled_dr[2].in_value = in_value;\n\t\ttunneled_dr[1].num_bits = 7;\n\t\ttunneled_dr[1].out_value = tunneled_dr_width;\n\t\ttunneled_dr[1].in_value = NULL;\n\t\ttunneled_dr[0].num_bits = 1;\n\t\ttunneled_dr[0].out_value = bscan_one;\n\t\ttunneled_dr[0].in_value = NULL;\n\t}\n\tjtag_add_ir_scan(target->tap, &select_user4, TAP_IDLE);\n\tjtag_add_dr_scan(target->tap, ARRAY_SIZE(tunneled_ir), tunneled_ir, TAP_IDLE);\n\tjtag_add_dr_scan(target->tap, ARRAY_SIZE(tunneled_dr), tunneled_dr, TAP_IDLE);\n\tselect_dmi_via_bscan(target);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\t/* Note the starting offset is bit 1, not bit 0.  In BSCAN tunnel, there is a one-bit TCK skew between\n\t   output and input */\n\tuint32_t in = buf_get_u32(in_value, 1, 32);\n\tLOG_DEBUG(\"DTMCS: 0x%x -> 0x%x\", out, in);\n\n\treturn in;\n}\n\nstatic uint32_t dtmcontrol_scan(struct target *target, uint32_t out)\n{\n\tstruct scan_field field;\n\tuint8_t in_value[4];\n\tuint8_t out_value[4] = { 0 };\n\n\tif (bscan_tunnel_ir_width != 0)\n\t\treturn dtmcontrol_scan_via_bscan(target, out);\n\n\n\tbuf_set_u32(out_value, 0, 32, out);\n\n\tjtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);\n\n\tfield.num_bits = 32;\n\tfield.out_value = out_value;\n\tfield.in_value = in_value;\n\tjtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);\n\n\t/* Always return to dbus. */\n\tjtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);\n\n\tint retval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"failed jtag scan: %d\", retval);\n\t\treturn retval;\n\t}\n\n\tuint32_t in = buf_get_u32(field.in_value, 0, 32);\n\tLOG_DEBUG(\"DTMCONTROL: 0x%x -> 0x%x\", out, in);\n\n\treturn in;\n}\n\nstatic struct target_type *get_target_type(struct target *target)\n{\n\tif (!target->arch_info) {\n\t\tLOG_ERROR(\"Target has not been initialized\");\n\t\treturn NULL;\n\t}\n\n\tRISCV_INFO(info);\n\tswitch (info->dtm_version) {\n\t\tcase 0:\n\t\t\treturn &riscv011_target;\n\t\tcase 1:\n\t\t\treturn &riscv013_target;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported DTM version: %d\", info->dtm_version);\n\t\t\treturn NULL;\n\t}\n}\n\nstatic int riscv_create_target(struct target *target, Jim_Interp *interp)\n{\n\tLOG_DEBUG(\"riscv_create_target()\");\n\ttarget->arch_info = calloc(1, sizeof(struct riscv_info));\n\tif (!target->arch_info) {\n\t\tLOG_ERROR(\"Failed to allocate RISC-V target structure.\");\n\t\treturn ERROR_FAIL;\n\t}\n\triscv_info_init(target, target->arch_info);\n\treturn ERROR_OK;\n}\n\nstatic int riscv_init_target(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tLOG_DEBUG(\"riscv_init_target()\");\n\tRISCV_INFO(info);\n\tinfo->cmd_ctx = cmd_ctx;\n\n\tselect_dtmcontrol.num_bits = target->tap->ir_length;\n\tselect_dbus.num_bits = target->tap->ir_length;\n\tselect_idcode.num_bits = target->tap->ir_length;\n\n\tif (bscan_tunnel_ir_width != 0) {\n\t\tassert(target->tap->ir_length >= 6);\n\t\tuint32_t ir_user4_raw = 0x23 << (target->tap->ir_length - 6);\n\t\th_u32_to_le(ir_user4, ir_user4_raw);\n\t\tselect_user4.num_bits = target->tap->ir_length;\n\t\tbscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;\n\t\tif (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)\n\t\t\tbscan_tunnel_data_register_select_dmi[1].num_bits = bscan_tunnel_ir_width;\n\t\telse /* BSCAN_TUNNEL_NESTED_TAP */\n\t\t\tbscan_tunnel_nested_tap_select_dmi[2].num_bits = bscan_tunnel_ir_width;\n\t}\n\n\triscv_semihosting_init(target);\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic void riscv_free_registers(struct target *target)\n{\n\t/* Free the shared structure use for most registers. */\n\tif (target->reg_cache) {\n\t\tif (target->reg_cache->reg_list) {\n\t\t\tfree(target->reg_cache->reg_list[0].arch_info);\n\t\t\t/* Free the ones we allocated separately. */\n\t\t\tfor (unsigned i = GDB_REGNO_COUNT; i < target->reg_cache->num_regs; i++)\n\t\t\t\tfree(target->reg_cache->reg_list[i].arch_info);\n\t\t\tfor (unsigned int i = 0; i < target->reg_cache->num_regs; i++)\n\t\t\t\tfree(target->reg_cache->reg_list[i].value);\n\t\t\tfree(target->reg_cache->reg_list);\n\t\t}\n\t\tfree(target->reg_cache);\n\t}\n}\n\nstatic void riscv_deinit_target(struct target *target)\n{\n\tLOG_DEBUG(\"riscv_deinit_target()\");\n\n\tstruct riscv_info *info = target->arch_info;\n\tstruct target_type *tt = get_target_type(target);\n\n\tif (tt && info && info->version_specific)\n\t\ttt->deinit_target(target);\n\n\triscv_free_registers(target);\n\n\tif (!info)\n\t\treturn;\n\n\trange_list_t *entry, *tmp;\n\tlist_for_each_entry_safe(entry, tmp, &info->expose_csr, list) {\n\t\tfree(entry->name);\n\t\tfree(entry);\n\t}\n\n\tlist_for_each_entry_safe(entry, tmp, &info->expose_custom, list) {\n\t\tfree(entry->name);\n\t\tfree(entry);\n\t}\n\n\tfree(info->reg_names);\n\tfree(target->arch_info);\n\n\ttarget->arch_info = NULL;\n}\n\nstatic void trigger_from_breakpoint(struct trigger *trigger,\n\t\tconst struct breakpoint *breakpoint)\n{\n\ttrigger->address = breakpoint->address;\n\ttrigger->length = breakpoint->length;\n\ttrigger->mask = ~0LL;\n\ttrigger->read = false;\n\ttrigger->write = false;\n\ttrigger->execute = true;\n\t/* unique_id is unique across both breakpoints and watchpoints. */\n\ttrigger->unique_id = breakpoint->unique_id;\n}\n\nstatic int maybe_add_trigger_t1(struct target *target,\n\t\tstruct trigger *trigger, uint64_t tdata1)\n{\n\tRISCV_INFO(r);\n\n\tconst uint32_t bpcontrol_x = 1<<0;\n\tconst uint32_t bpcontrol_w = 1<<1;\n\tconst uint32_t bpcontrol_r = 1<<2;\n\tconst uint32_t bpcontrol_u = 1<<3;\n\tconst uint32_t bpcontrol_s = 1<<4;\n\tconst uint32_t bpcontrol_h = 1<<5;\n\tconst uint32_t bpcontrol_m = 1<<6;\n\tconst uint32_t bpcontrol_bpmatch = 0xf << 7;\n\tconst uint32_t bpcontrol_bpaction = 0xff << 11;\n\n\tif (tdata1 & (bpcontrol_r | bpcontrol_w | bpcontrol_x)) {\n\t\t/* Trigger is already in use, presumably by user code. */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\ttdata1 = set_field(tdata1, bpcontrol_r, trigger->read);\n\ttdata1 = set_field(tdata1, bpcontrol_w, trigger->write);\n\ttdata1 = set_field(tdata1, bpcontrol_x, trigger->execute);\n\ttdata1 = set_field(tdata1, bpcontrol_u,\n\t\t\t!!(r->misa & BIT('U' - 'A')));\n\ttdata1 = set_field(tdata1, bpcontrol_s,\n\t\t\t!!(r->misa & BIT('S' - 'A')));\n\ttdata1 = set_field(tdata1, bpcontrol_h,\n\t\t\t!!(r->misa & BIT('H' - 'A')));\n\ttdata1 |= bpcontrol_m;\n\ttdata1 = set_field(tdata1, bpcontrol_bpmatch, 0); /* exact match */\n\ttdata1 = set_field(tdata1, bpcontrol_bpaction, 0); /* cause bp exception */\n\n\triscv_set_register(target, GDB_REGNO_TDATA1, tdata1);\n\n\triscv_reg_t tdata1_rb;\n\tif (riscv_get_register(target, &tdata1_rb, GDB_REGNO_TDATA1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"tdata1=0x%\" PRIx64, tdata1_rb);\n\n\tif (tdata1 != tdata1_rb) {\n\t\tLOG_DEBUG(\"Trigger doesn't support what we need; After writing 0x%\"\n\t\t\t\tPRIx64 \" to tdata1 it contains 0x%\" PRIx64,\n\t\t\t\ttdata1, tdata1_rb);\n\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\triscv_set_register(target, GDB_REGNO_TDATA2, trigger->address);\n\n\treturn ERROR_OK;\n}\n\nstatic int maybe_add_trigger_t2(struct target *target,\n\t\tstruct trigger *trigger, uint64_t tdata1)\n{\n\tRISCV_INFO(r);\n\n\t/* tselect is already set */\n\tif (tdata1 & (MCONTROL_EXECUTE | MCONTROL_STORE | MCONTROL_LOAD)) {\n\t\t/* Trigger is already in use, presumably by user code. */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* address/data match trigger */\n\ttdata1 |= MCONTROL_DMODE(riscv_xlen(target));\n\ttdata1 = set_field(tdata1, MCONTROL_ACTION,\n\t\t\tMCONTROL_ACTION_DEBUG_MODE);\n\ttdata1 = set_field(tdata1, MCONTROL_MATCH, MCONTROL_MATCH_EQUAL);\n\ttdata1 |= MCONTROL_M;\n\tif (r->misa & (1 << ('S' - 'A')))\n\t\ttdata1 |= MCONTROL_S;\n\tif (r->misa & (1 << ('U' - 'A')))\n\t\ttdata1 |= MCONTROL_U;\n\n\tif (trigger->execute)\n\t\ttdata1 |= MCONTROL_EXECUTE;\n\tif (trigger->read)\n\t\ttdata1 |= MCONTROL_LOAD;\n\tif (trigger->write)\n\t\ttdata1 |= MCONTROL_STORE;\n\n\triscv_set_register(target, GDB_REGNO_TDATA1, tdata1);\n\n\tuint64_t tdata1_rb;\n\tint result = riscv_get_register(target, &tdata1_rb, GDB_REGNO_TDATA1);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\tLOG_DEBUG(\"tdata1=0x%\" PRIx64, tdata1_rb);\n\n\tif (tdata1 != tdata1_rb) {\n\t\tLOG_DEBUG(\"Trigger doesn't support what we need; After writing 0x%\"\n\t\t\t\tPRIx64 \" to tdata1 it contains 0x%\" PRIx64,\n\t\t\t\ttdata1, tdata1_rb);\n\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\triscv_set_register(target, GDB_REGNO_TDATA2, trigger->address);\n\n\treturn ERROR_OK;\n}\n\nstatic int maybe_add_trigger_t6(struct target *target,\n\t\tstruct trigger *trigger, uint64_t tdata1)\n{\n\tRISCV_INFO(r);\n\n\t/* tselect is already set */\n\tif (tdata1 & (CSR_MCONTROL6_EXECUTE | CSR_MCONTROL6_STORE | CSR_MCONTROL6_LOAD)) {\n\t\t/* Trigger is already in use, presumably by user code. */\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* address/data match trigger */\n\ttdata1 |= MCONTROL_DMODE(riscv_xlen(target));\n\ttdata1 = set_field(tdata1, CSR_MCONTROL6_ACTION,\n\t\t\tMCONTROL_ACTION_DEBUG_MODE);\n\ttdata1 = set_field(tdata1, CSR_MCONTROL6_MATCH, MCONTROL_MATCH_EQUAL);\n\ttdata1 |= CSR_MCONTROL6_M;\n\tif (r->misa & (1 << ('H' - 'A')))\n\t\ttdata1 |= CSR_MCONTROL6_VS | CSR_MCONTROL6_VU;\n\tif (r->misa & (1 << ('S' - 'A')))\n\t\ttdata1 |= CSR_MCONTROL6_S;\n\tif (r->misa & (1 << ('U' - 'A')))\n\t\ttdata1 |= CSR_MCONTROL6_U;\n\n\tif (trigger->execute)\n\t\ttdata1 |= CSR_MCONTROL6_EXECUTE;\n\tif (trigger->read)\n\t\ttdata1 |= CSR_MCONTROL6_LOAD;\n\tif (trigger->write)\n\t\ttdata1 |= CSR_MCONTROL6_STORE;\n\n\triscv_set_register(target, GDB_REGNO_TDATA1, tdata1);\n\n\tuint64_t tdata1_rb;\n\tint result = riscv_get_register(target, &tdata1_rb, GDB_REGNO_TDATA1);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\tLOG_DEBUG(\"tdata1=0x%\" PRIx64, tdata1_rb);\n\n\tif (tdata1 != tdata1_rb) {\n\t\tLOG_DEBUG(\"Trigger doesn't support what we need; After writing 0x%\"\n\t\t\t\tPRIx64 \" to tdata1 it contains 0x%\" PRIx64,\n\t\t\t\ttdata1, tdata1_rb);\n\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\triscv_set_register(target, GDB_REGNO_TDATA2, trigger->address);\n\n\treturn ERROR_OK;\n}\n\nstatic int add_trigger(struct target *target, struct trigger *trigger)\n{\n\tRISCV_INFO(r);\n\n\tif (riscv_enumerate_triggers(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\triscv_reg_t tselect;\n\tif (riscv_get_register(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tunsigned int i;\n\tfor (i = 0; i < r->trigger_count; i++) {\n\t\tif (r->trigger_unique_id[i] != -1)\n\t\t\tcontinue;\n\n\t\triscv_set_register(target, GDB_REGNO_TSELECT, i);\n\n\t\tuint64_t tdata1;\n\t\tint result = riscv_get_register(target, &tdata1, GDB_REGNO_TDATA1);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tint type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target)));\n\n\t\tswitch (type) {\n\t\t\tcase 1:\n\t\t\t\tresult = maybe_add_trigger_t1(target, trigger, tdata1);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tresult = maybe_add_trigger_t2(target, trigger, tdata1);\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tresult = maybe_add_trigger_t6(target, trigger, tdata1);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_DEBUG(\"trigger %d has unknown type %d\", i, type);\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (result != ERROR_OK)\n\t\t\tcontinue;\n\n\t\tLOG_DEBUG(\"[%d] Using trigger %d (type %d) for bp %d\", target->coreid,\n\t\t\t\ti, type, trigger->unique_id);\n\t\tr->trigger_unique_id[i] = trigger->unique_id;\n\t\tbreak;\n\t}\n\n\triscv_set_register(target, GDB_REGNO_TSELECT, tselect);\n\n\tif (i >= r->trigger_count) {\n\t\tLOG_ERROR(\"Couldn't find an available hardware trigger.\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Write one memory item of given \"size\". Use memory access of given \"access_size\".\n * Utilize read-modify-write, if needed.\n * */\nstatic int write_by_given_size(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint8_t *buffer, uint32_t access_size)\n{\n\tassert(size == 1 || size == 2 || size == 4 || size == 8);\n\tassert(access_size == 1 || access_size == 2 || access_size == 4 || access_size == 8);\n\n\tif (access_size <= size && address % access_size == 0)\n\t\t/* Can do the memory access directly without a helper buffer. */\n\t\treturn target_write_memory(target, address, access_size, size / access_size, buffer);\n\n\tunsigned int offset_head = address % access_size;\n\tunsigned int n_blocks = ((size + offset_head) <= access_size) ? 1 : 2;\n\tuint8_t helper_buf[n_blocks * access_size];\n\n\t/* Read from memory */\n\tif (target_read_memory(target, address - offset_head, access_size, n_blocks, helper_buf) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Modify and write back */\n\tmemcpy(helper_buf + offset_head, buffer, size);\n\treturn target_write_memory(target, address - offset_head, access_size, n_blocks, helper_buf);\n}\n\n/**\n * Read one memory item of given \"size\". Use memory access of given \"access_size\".\n * Read larger section of memory and pick out the required portion, if needed.\n * */\nstatic int read_by_given_size(struct target *target, target_addr_t address,\n\tuint32_t size, uint8_t *buffer, uint32_t access_size)\n{\n\tassert(size == 1 || size == 2 || size == 4 || size == 8);\n\tassert(access_size == 1 || access_size == 2 || access_size == 4 || access_size == 8);\n\n\tif (access_size <= size && address % access_size == 0)\n\t\t/* Can do the memory access directly without a helper buffer. */\n\t\treturn target_read_memory(target, address, access_size, size / access_size, buffer);\n\n\tunsigned int offset_head = address % access_size;\n\tunsigned int n_blocks = ((size + offset_head) <= access_size) ? 1 : 2;\n\tuint8_t helper_buf[n_blocks * access_size];\n\n\t/* Read from memory */\n\tif (target_read_memory(target, address - offset_head, access_size, n_blocks, helper_buf) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\t/* Pick the requested portion from the buffer */\n\tmemcpy(buffer, helper_buf + offset_head, size);\n\treturn ERROR_OK;\n}\n\n/**\n * Write one memory item using any memory access size that will work.\n * Utilize read-modify-write, if needed.\n * */\nint riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)\n{\n\tassert(size == 1 || size == 2 ||  size == 4 || size == 8);\n\n\t/* Find access size that correspond to data size and the alignment. */\n\tunsigned int preferred_size = size;\n\twhile (address % preferred_size != 0)\n\t\tpreferred_size /= 2;\n\n\t/* First try the preferred (most natural) access size. */\n\tif (write_by_given_size(target, address, size, buffer, preferred_size) == ERROR_OK)\n\t\treturn ERROR_OK;\n\n\t/* On failure, try other access sizes.\n\t   Minimize the number of accesses by trying first the largest size. */\n\tfor (unsigned int access_size = 8; access_size > 0; access_size /= 2) {\n\t\tif (access_size == preferred_size)\n\t\t\t/* Already tried this size. */\n\t\t\tcontinue;\n\n\t\tif (write_by_given_size(target, address, size, buffer, access_size) == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t}\n\n\t/* No access attempt succeeded. */\n\treturn ERROR_FAIL;\n}\n\n/**\n * Read one memory item using any memory access size that will work.\n * Read larger section of memory and pick out the required portion, if needed.\n * */\nint riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)\n{\n\tassert(size == 1 || size == 2 ||  size == 4 || size == 8);\n\n\t/* Find access size that correspond to data size and the alignment. */\n\tunsigned int preferred_size = size;\n\twhile (address % preferred_size != 0)\n\t\tpreferred_size /= 2;\n\n\t/* First try the preferred (most natural) access size. */\n\tif (read_by_given_size(target, address, size, buffer, preferred_size) == ERROR_OK)\n\t\treturn ERROR_OK;\n\n\t/* On failure, try other access sizes.\n\t   Minimize the number of accesses by trying first the largest size. */\n\tfor (unsigned int access_size = 8; access_size > 0; access_size /= 2) {\n\t\tif (access_size == preferred_size)\n\t\t\t/* Already tried this size. */\n\t\t\tcontinue;\n\n\t\tif (read_by_given_size(target, address, size, buffer, access_size) == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t}\n\n\t/* No access attempt succeeded. */\n\treturn ERROR_FAIL;\n}\n\nstatic int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tLOG_DEBUG(\"[%d] @0x%\" TARGET_PRIxADDR, target->coreid, breakpoint->address);\n\tassert(breakpoint);\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\t/** @todo check RVC for size/alignment */\n\t\tif (!(breakpoint->length == 4 || breakpoint->length == 2)) {\n\t\t\tLOG_ERROR(\"Invalid breakpoint length %d\", breakpoint->length);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (0 != (breakpoint->address % 2)) {\n\t\t\tLOG_ERROR(\"Invalid breakpoint alignment for address 0x%\" TARGET_PRIxADDR, breakpoint->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Read the original instruction. */\n\t\tif (riscv_read_by_any_size(\n\t\t\t\ttarget, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to read original instruction at 0x%\" TARGET_PRIxADDR,\n\t\t\t\t\tbreakpoint->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tuint8_t buff[4] = { 0 };\n\t\tbuf_set_u32(buff, 0, breakpoint->length * CHAR_BIT, breakpoint->length == 4 ? ebreak() : ebreak_c());\n\t\t/* Write the ebreak instruction. */\n\t\tif (riscv_write_by_any_size(target, breakpoint->address, breakpoint->length, buff) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to write %d-byte breakpoint instruction at 0x%\"\n\t\t\t\t\tTARGET_PRIxADDR, breakpoint->length, breakpoint->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else if (breakpoint->type == BKPT_HARD) {\n\t\tstruct trigger trigger;\n\t\ttrigger_from_breakpoint(&trigger, breakpoint);\n\t\tint const result = add_trigger(target, &trigger);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t} else {\n\t\tLOG_INFO(\"OpenOCD only supports hardware and software breakpoints.\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tbreakpoint->is_set = true;\n\treturn ERROR_OK;\n}\n\nstatic int remove_trigger(struct target *target, struct trigger *trigger)\n{\n\tRISCV_INFO(r);\n\n\tif (riscv_enumerate_triggers(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tunsigned int i;\n\tfor (i = 0; i < r->trigger_count; i++) {\n\t\tif (r->trigger_unique_id[i] == trigger->unique_id)\n\t\t\tbreak;\n\t}\n\tif (i >= r->trigger_count) {\n\t\tLOG_ERROR(\"Couldn't find the hardware resources used by hardware \"\n\t\t\t\t\"trigger.\");\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"[%d] Stop using resource %d for bp %d\", target->coreid, i,\n\t\t\ttrigger->unique_id);\n\n\triscv_reg_t tselect;\n\tint result = riscv_get_register(target, &tselect, GDB_REGNO_TSELECT);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\triscv_set_register(target, GDB_REGNO_TSELECT, i);\n\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\triscv_set_register(target, GDB_REGNO_TSELECT, tselect);\n\tr->trigger_unique_id[i] = -1;\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_remove_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\t/* Write the original instruction. */\n\t\tif (riscv_write_by_any_size(\n\t\t\t\ttarget, breakpoint->address, breakpoint->length, breakpoint->orig_instr) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to restore instruction for %d-byte breakpoint at \"\n\t\t\t\t\t\"0x%\" TARGET_PRIxADDR, breakpoint->length, breakpoint->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else if (breakpoint->type == BKPT_HARD) {\n\t\tstruct trigger trigger;\n\t\ttrigger_from_breakpoint(&trigger, breakpoint);\n\t\tint result = remove_trigger(target, &trigger);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t} else {\n\t\tLOG_INFO(\"OpenOCD only supports hardware and software breakpoints.\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic void trigger_from_watchpoint(struct trigger *trigger,\n\t\tconst struct watchpoint *watchpoint)\n{\n\ttrigger->address = watchpoint->address;\n\ttrigger->length = watchpoint->length;\n\ttrigger->mask = watchpoint->mask;\n\ttrigger->value = watchpoint->value;\n\ttrigger->read = (watchpoint->rw == WPT_READ || watchpoint->rw == WPT_ACCESS);\n\ttrigger->write = (watchpoint->rw == WPT_WRITE || watchpoint->rw == WPT_ACCESS);\n\ttrigger->execute = false;\n\t/* unique_id is unique across both breakpoints and watchpoints. */\n\ttrigger->unique_id = watchpoint->unique_id;\n}\n\nint riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct trigger trigger;\n\ttrigger_from_watchpoint(&trigger, watchpoint);\n\n\tint result = add_trigger(target, &trigger);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\twatchpoint->is_set = true;\n\n\treturn ERROR_OK;\n}\n\nint riscv_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tLOG_DEBUG(\"[%d] @0x%\" TARGET_PRIxADDR, target->coreid, watchpoint->address);\n\n\tstruct trigger trigger;\n\ttrigger_from_watchpoint(&trigger, watchpoint);\n\n\tint result = remove_trigger(target, &trigger);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\n/* Sets *hit_watchpoint to the first watchpoint identified as causing the\n * current halt.\n *\n * The GDB server uses this information to tell GDB what data address has\n * been hit, which enables GDB to print the hit variable along with its old\n * and new value. */\nstatic int riscv_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)\n{\n\tstruct watchpoint *wp = target->watchpoints;\n\n\tLOG_DEBUG(\"Current hartid = %d\", riscv_current_hartid(target));\n\n\t/*TODO instead of disassembling the instruction that we think caused the\n\t * trigger, check the hit bit of each watchpoint first. The hit bit is\n\t * simpler and more reliable to check but as it is optional and relatively\n\t * new, not all hardware will implement it  */\n\triscv_reg_t dpc;\n\triscv_get_register(target, &dpc, GDB_REGNO_DPC);\n\tconst uint8_t length = 4;\n\tLOG_DEBUG(\"dpc is 0x%\" PRIx64, dpc);\n\n\t/* fetch the instruction at dpc */\n\tuint8_t buffer[length];\n\tif (target_read_buffer(target, dpc, length, buffer) != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read instruction at dpc 0x%\" PRIx64, dpc);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint32_t instruction = 0;\n\n\tfor (int i = 0; i < length; i++) {\n\t\tLOG_DEBUG(\"Next byte is %x\", buffer[i]);\n\t\tinstruction += (buffer[i] << 8 * i);\n\t}\n\tLOG_DEBUG(\"Full instruction is %x\", instruction);\n\n\t/* find out which memory address is accessed by the instruction at dpc */\n\t/* opcode is first 7 bits of the instruction */\n\tuint8_t opcode = instruction & 0x7F;\n\tuint32_t rs1;\n\tint16_t imm;\n\triscv_reg_t mem_addr;\n\n\tif (opcode == MATCH_LB || opcode == MATCH_SB) {\n\t\trs1 = (instruction & 0xf8000) >> 15;\n\t\triscv_get_register(target, &mem_addr, rs1);\n\n\t\tif (opcode == MATCH_SB) {\n\t\t\tLOG_DEBUG(\"%x is store instruction\", instruction);\n\t\t\timm = ((instruction & 0xf80) >> 7) | ((instruction & 0xfe000000) >> 20);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"%x is load instruction\", instruction);\n\t\t\timm = (instruction & 0xfff00000) >> 20;\n\t\t}\n\t\t/* sign extend 12-bit imm to 16-bits */\n\t\tif (imm & (1 << 11))\n\t\t\timm |= 0xf000;\n\t\tmem_addr += imm;\n\t\tLOG_DEBUG(\"memory address=0x%\" PRIx64, mem_addr);\n\t} else {\n\t\tLOG_DEBUG(\"%x is not a RV32I load or store\", instruction);\n\t\treturn ERROR_FAIL;\n\t}\n\n\twhile (wp) {\n\t\t/*TODO support length/mask */\n\t\tif (wp->address == mem_addr) {\n\t\t\t*hit_watchpoint = wp;\n\t\t\tLOG_DEBUG(\"Hit address=%\" TARGET_PRIxADDR, wp->address);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\twp = wp->next;\n\t}\n\n\t/* No match found - either we hit a watchpoint caused by an instruction that\n\t * this function does not yet disassemble, or we hit a breakpoint.\n\t *\n\t * OpenOCD will behave as if this function had never been implemented i.e.\n\t * report the halt to GDB with no address information. */\n\treturn ERROR_FAIL;\n}\n\n\nstatic int oldriscv_step(struct target *target, int current, uint32_t address,\n\t\tint handle_breakpoints)\n{\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->step(target, current, address, handle_breakpoints);\n}\n\nstatic int old_or_new_riscv_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"handle_breakpoints=%d\", handle_breakpoints);\n\tif (!r->is_halted)\n\t\treturn oldriscv_step(target, current, address, handle_breakpoints);\n\telse\n\t\treturn riscv_openocd_step(target, current, address, handle_breakpoints);\n}\n\n\nstatic int riscv_examine(struct target *target)\n{\n\tLOG_DEBUG(\"riscv_examine()\");\n\tif (target_was_examined(target)) {\n\t\tLOG_DEBUG(\"Target was already examined.\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */\n\n\tRISCV_INFO(info);\n\tuint32_t dtmcontrol = dtmcontrol_scan(target, 0);\n\tLOG_DEBUG(\"dtmcontrol=0x%x\", dtmcontrol);\n\tinfo->dtm_version = get_field(dtmcontrol, DTMCONTROL_VERSION);\n\tLOG_DEBUG(\"  version=0x%x\", info->dtm_version);\n\n\tstruct target_type *tt = get_target_type(target);\n\tif (!tt)\n\t\treturn ERROR_FAIL;\n\n\tint result = tt->init_target(info->cmd_ctx, target);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\treturn tt->examine(target);\n}\n\nstatic int oldriscv_poll(struct target *target)\n{\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->poll(target);\n}\n\nstatic int old_or_new_riscv_poll(struct target *target)\n{\n\tRISCV_INFO(r);\n\tif (!r->is_halted)\n\t\treturn oldriscv_poll(target);\n\telse\n\t\treturn riscv_openocd_poll(target);\n}\n\nint riscv_select_current_hart(struct target *target)\n{\n\treturn riscv_set_current_hartid(target, target->coreid);\n}\n\nstatic int halt_prep(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tLOG_DEBUG(\"[%s] prep hart, debug_reason=%d\", target_name(target),\n\t\t\t\ttarget->debug_reason);\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (riscv_is_halted(target)) {\n\t\tLOG_DEBUG(\"[%s] Hart is already halted (reason=%d).\",\n\t\t\t\ttarget_name(target), target->debug_reason);\n\t} else {\n\t\tif (r->halt_prep(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tr->prepped = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_halt_go_all_harts(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (riscv_is_halted(target)) {\n\t\tLOG_DEBUG(\"[%s] Hart is already halted.\", target_name(target));\n\t} else {\n\t\tif (r->halt_go(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\triscv_invalidate_register_cache(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int halt_go(struct target *target)\n{\n\tRISCV_INFO(r);\n\tint result;\n\tif (!r->is_halted) {\n\t\tstruct target_type *tt = get_target_type(target);\n\t\tresult = tt->halt(target);\n\t} else {\n\t\tresult = riscv_halt_go_all_harts(target);\n\t}\n\ttarget->state = TARGET_HALTED;\n\tif (target->debug_reason == DBG_REASON_NOTHALTED)\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn result;\n}\n\nstatic int halt_finish(struct target *target)\n{\n\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n}\n\nint riscv_halt(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tif (!r->is_halted) {\n\t\tstruct target_type *tt = get_target_type(target);\n\t\treturn tt->halt(target);\n\t}\n\n\tLOG_DEBUG(\"[%d] halting all harts\", target->coreid);\n\n\tint result = ERROR_OK;\n\tif (target->smp) {\n\t\tstruct target_list *tlist;\n\t\tforeach_smp_target(tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tif (halt_prep(t) != ERROR_OK)\n\t\t\t\tresult = ERROR_FAIL;\n\t\t}\n\n\t\tforeach_smp_target(tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tstruct riscv_info *i = riscv_info(t);\n\t\t\tif (i->prepped) {\n\t\t\t\tif (halt_go(t) != ERROR_OK)\n\t\t\t\t\tresult = ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tforeach_smp_target(tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tif (halt_finish(t) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else {\n\t\tif (halt_prep(target) != ERROR_OK)\n\t\t\tresult = ERROR_FAIL;\n\t\tif (halt_go(target) != ERROR_OK)\n\t\t\tresult = ERROR_FAIL;\n\t\tif (halt_finish(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int riscv_assert_reset(struct target *target)\n{\n\tLOG_DEBUG(\"[%d]\", target->coreid);\n\tstruct target_type *tt = get_target_type(target);\n\triscv_invalidate_register_cache(target);\n\treturn tt->assert_reset(target);\n}\n\nstatic int riscv_deassert_reset(struct target *target)\n{\n\tLOG_DEBUG(\"[%d]\", target->coreid);\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->deassert_reset(target);\n}\n\nstatic int riscv_resume_prep_all_harts(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tLOG_DEBUG(\"[%s] prep hart\", target_name(target));\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (riscv_is_halted(target)) {\n\t\tif (r->resume_prep(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_DEBUG(\"[%s] hart requested resume, but was already resumed\",\n\t\t\t\ttarget_name(target));\n\t}\n\n\tLOG_DEBUG(\"[%s] mark as prepped\", target_name(target));\n\tr->prepped = true;\n\n\treturn ERROR_OK;\n}\n\n/* state must be riscv_reg_t state[RISCV_MAX_HWBPS] = {0}; */\nstatic int disable_triggers(struct target *target, riscv_reg_t *state)\n{\n\tRISCV_INFO(r);\n\n\tLOG_DEBUG(\"deal with triggers\");\n\n\tif (riscv_enumerate_triggers(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (r->manual_hwbp_set) {\n\t\t/* Look at every trigger that may have been set. */\n\t\triscv_reg_t tselect;\n\t\tif (riscv_get_register(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tfor (unsigned int t = 0; t < r->trigger_count; t++) {\n\t\t\tif (riscv_set_register(target, GDB_REGNO_TSELECT, t) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\triscv_reg_t tdata1;\n\t\t\tif (riscv_get_register(target, &tdata1, GDB_REGNO_TDATA1) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tif (tdata1 & MCONTROL_DMODE(riscv_xlen(target))) {\n\t\t\t\tstate[t] = tdata1;\n\t\t\t\tif (riscv_set_register(target, GDB_REGNO_TDATA1, 0) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\tif (riscv_set_register(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t} else {\n\t\t/* Just go through the triggers we manage. */\n\t\tstruct watchpoint *watchpoint = target->watchpoints;\n\t\tint i = 0;\n\t\twhile (watchpoint) {\n\t\t\tLOG_DEBUG(\"watchpoint %d: set=%d\", i, watchpoint->is_set);\n\t\t\tstate[i] = watchpoint->is_set;\n\t\t\tif (watchpoint->is_set) {\n\t\t\t\tif (riscv_remove_watchpoint(target, watchpoint) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\twatchpoint = watchpoint->next;\n\t\t\ti++;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int enable_triggers(struct target *target, riscv_reg_t *state)\n{\n\tRISCV_INFO(r);\n\n\tif (r->manual_hwbp_set) {\n\t\t/* Look at every trigger that may have been set. */\n\t\triscv_reg_t tselect;\n\t\tif (riscv_get_register(target, &tselect, GDB_REGNO_TSELECT) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tfor (unsigned int t = 0; t < r->trigger_count; t++) {\n\t\t\tif (state[t] != 0) {\n\t\t\t\tif (riscv_set_register(target, GDB_REGNO_TSELECT, t) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tif (riscv_set_register(target, GDB_REGNO_TDATA1, state[t]) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\t\tif (riscv_set_register(target, GDB_REGNO_TSELECT, tselect) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t} else {\n\t\tstruct watchpoint *watchpoint = target->watchpoints;\n\t\tint i = 0;\n\t\twhile (watchpoint) {\n\t\t\tLOG_DEBUG(\"watchpoint %d: cleared=%\" PRId64, i, state[i]);\n\t\t\tif (state[i]) {\n\t\t\t\tif (riscv_add_watchpoint(target, watchpoint) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\twatchpoint = watchpoint->next;\n\t\t\ti++;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Get everything ready to resume.\n */\nstatic int resume_prep(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"[%d]\", target->coreid);\n\n\tif (!current)\n\t\triscv_set_register(target, GDB_REGNO_PC, address);\n\n\tif (target->debug_reason == DBG_REASON_WATCHPOINT) {\n\t\t/* To be able to run off a trigger, disable all the triggers, step, and\n\t\t * then resume as usual. */\n\t\triscv_reg_t trigger_state[RISCV_MAX_HWBPS] = {0};\n\n\t\tif (disable_triggers(target, trigger_state) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (old_or_new_riscv_step(target, true, 0, false) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (enable_triggers(target, trigger_state) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (r->is_halted) {\n\t\tif (riscv_resume_prep_all_harts(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"[%d] mark as prepped\", target->coreid);\n\tr->prepped = true;\n\n\treturn ERROR_OK;\n}\n\n/**\n * Resume all the harts that have been prepped, as close to instantaneous as\n * possible.\n */\nstatic int resume_go(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tRISCV_INFO(r);\n\tint result;\n\tif (!r->is_halted) {\n\t\tstruct target_type *tt = get_target_type(target);\n\t\tresult = tt->resume(target, current, address, handle_breakpoints,\n\t\t\t\tdebug_execution);\n\t} else {\n\t\tresult = riscv_resume_go_all_harts(target);\n\t}\n\n\treturn result;\n}\n\nstatic int resume_finish(struct target *target)\n{\n\tregister_cache_invalidate(target->reg_cache);\n\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn target_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n}\n\n/**\n * @par single_hart When true, only resume a single hart even if SMP is\n * configured.  This is used to run algorithms on just one hart.\n */\nstatic int riscv_resume(\n\t\tstruct target *target,\n\t\tint current,\n\t\ttarget_addr_t address,\n\t\tint handle_breakpoints,\n\t\tint debug_execution,\n\t\tbool single_hart)\n{\n\tLOG_DEBUG(\"handle_breakpoints=%d\", handle_breakpoints);\n\tint result = ERROR_OK;\n\tif (target->smp && !single_hart) {\n\t\tstruct target_list *tlist;\n\t\tforeach_smp_target_direction(resume_order == RO_NORMAL,\n\t\t\t\t\t\t\t\t\t tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tif (resume_prep(t, current, address, handle_breakpoints,\n\t\t\t\t\t\tdebug_execution) != ERROR_OK)\n\t\t\t\tresult = ERROR_FAIL;\n\t\t}\n\n\t\tforeach_smp_target_direction(resume_order == RO_NORMAL,\n\t\t\t\t\t\t\t\t\t tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tstruct riscv_info *i = riscv_info(t);\n\t\t\tif (i->prepped) {\n\t\t\t\tif (resume_go(t, current, address, handle_breakpoints,\n\t\t\t\t\t\t\tdebug_execution) != ERROR_OK)\n\t\t\t\t\tresult = ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tforeach_smp_target_direction(resume_order == RO_NORMAL,\n\t\t\t\t\t\t\t\t\t tlist, target->smp_targets) {\n\t\t\tstruct target *t = tlist->target;\n\t\t\tif (resume_finish(t) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t} else {\n\t\tif (resume_prep(target, current, address, handle_breakpoints,\n\t\t\t\t\tdebug_execution) != ERROR_OK)\n\t\t\tresult = ERROR_FAIL;\n\t\tif (resume_go(target, current, address, handle_breakpoints,\n\t\t\t\t\tdebug_execution) != ERROR_OK)\n\t\t\tresult = ERROR_FAIL;\n\t\tif (resume_finish(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn result;\n}\n\nstatic int riscv_target_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\treturn riscv_resume(target, current, address, handle_breakpoints,\n\t\t\tdebug_execution, false);\n}\n\nstatic int riscv_mmu(struct target *target, int *enabled)\n{\n\tif (!riscv_enable_virt2phys) {\n\t\t*enabled = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Don't use MMU in explicit or effective M (machine) mode */\n\triscv_reg_t priv;\n\tif (riscv_get_register(target, &priv, GDB_REGNO_PRIV) != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read priv register.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\triscv_reg_t mstatus;\n\tif (riscv_get_register(target, &mstatus, GDB_REGNO_MSTATUS) != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read mstatus register.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif ((get_field(mstatus, MSTATUS_MPRV) ? get_field(mstatus, MSTATUS_MPP) : priv) == PRV_M) {\n\t\tLOG_DEBUG(\"SATP/MMU ignored in Machine mode (mstatus=0x%\" PRIx64 \").\", mstatus);\n\t\t*enabled = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\triscv_reg_t satp;\n\tif (riscv_get_register(target, &satp, GDB_REGNO_SATP) != ERROR_OK) {\n\t\tLOG_DEBUG(\"Couldn't read SATP.\");\n\t\t/* If we can't read SATP, then there must not be an MMU. */\n\t\t*enabled = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tif (get_field(satp, RISCV_SATP_MODE(riscv_xlen(target))) == SATP_MODE_OFF) {\n\t\tLOG_DEBUG(\"MMU is disabled.\");\n\t\t*enabled = 0;\n\t} else {\n\t\tLOG_DEBUG(\"MMU is enabled.\");\n\t\t*enabled = 1;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_address_translate(struct target *target,\n\t\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tRISCV_INFO(r);\n\triscv_reg_t satp_value;\n\tint mode;\n\tuint64_t ppn_value;\n\ttarget_addr_t table_address;\n\tconst virt2phys_info_t *info;\n\tuint64_t pte = 0;\n\tint i;\n\n\tint result = riscv_get_register(target, &satp_value, GDB_REGNO_SATP);\n\tif (result != ERROR_OK)\n\t\treturn result;\n\n\tunsigned xlen = riscv_xlen(target);\n\tmode = get_field(satp_value, RISCV_SATP_MODE(xlen));\n\tswitch (mode) {\n\t\tcase SATP_MODE_SV32:\n\t\t\tinfo = &sv32;\n\t\t\tbreak;\n\t\tcase SATP_MODE_SV39:\n\t\t\tinfo = &sv39;\n\t\t\tbreak;\n\t\tcase SATP_MODE_SV48:\n\t\t\tinfo = &sv48;\n\t\t\tbreak;\n\t\tcase SATP_MODE_OFF:\n\t\t\tLOG_ERROR(\"No translation or protection.\" \\\n\t\t\t\t      \" (satp: 0x%\" PRIx64 \")\", satp_value);\n\t\t\treturn ERROR_FAIL;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"The translation mode is not supported.\" \\\n\t\t\t\t      \" (satp: 0x%\" PRIx64 \")\", satp_value);\n\t\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"virtual=0x%\" TARGET_PRIxADDR \"; mode=%s\", virtual, info->name);\n\n\t/* verify bits xlen-1:va_bits-1 are all equal */\n\tassert(xlen >= info->va_bits);\n\ttarget_addr_t mask = ((target_addr_t)1 << (xlen - (info->va_bits - 1))) - 1;\n\ttarget_addr_t masked_msbs = (virtual >> (info->va_bits - 1)) & mask;\n\tif (masked_msbs != 0 && masked_msbs != mask) {\n\t\tLOG_ERROR(\"Virtual address 0x%\" TARGET_PRIxADDR \" is not sign-extended \"\n\t\t\t\t\"for %s mode.\", virtual, info->name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tppn_value = get_field(satp_value, RISCV_SATP_PPN(xlen));\n\ttable_address = ppn_value << RISCV_PGSHIFT;\n\ti = info->level - 1;\n\twhile (i >= 0) {\n\t\tuint64_t vpn = virtual >> info->vpn_shift[i];\n\t\tvpn &= info->vpn_mask[i];\n\t\ttarget_addr_t pte_address = table_address +\n\t\t\t\t\t\t\t\t\t(vpn << info->pte_shift);\n\t\tuint8_t buffer[8];\n\t\tassert(info->pte_shift <= 3);\n\t\tint retval = r->read_memory(target, pte_address,\n\t\t\t\t4, (1 << info->pte_shift) / 4, buffer, 4);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (info->pte_shift == 2)\n\t\t\tpte = buf_get_u32(buffer, 0, 32);\n\t\telse\n\t\t\tpte = buf_get_u64(buffer, 0, 64);\n\n\t\tLOG_DEBUG(\"i=%d; PTE @0x%\" TARGET_PRIxADDR \" = 0x%\" PRIx64, i,\n\t\t\t\tpte_address, pte);\n\n\t\tif (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W)))\n\t\t\treturn ERROR_FAIL;\n\n\t\tif ((pte & PTE_R) || (pte & PTE_X)) /* Found leaf PTE. */\n\t\t\tbreak;\n\n\t\ti--;\n\t\tif (i < 0)\n\t\t\tbreak;\n\t\tppn_value = pte >> PTE_PPN_SHIFT;\n\t\ttable_address = ppn_value << RISCV_PGSHIFT;\n\t}\n\n\tif (i < 0) {\n\t\tLOG_ERROR(\"Couldn't find the PTE.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Make sure to clear out the high bits that may be set. */\n\t*physical = virtual & (((target_addr_t)1 << info->va_bits) - 1);\n\n\twhile (i < info->level) {\n\t\tppn_value = pte >> info->pte_ppn_shift[i];\n\t\tppn_value &= info->pte_ppn_mask[i];\n\t\t*physical &= ~(((target_addr_t)info->pa_ppn_mask[i]) <<\n\t\t\t\tinfo->pa_ppn_shift[i]);\n\t\t*physical |= (ppn_value << info->pa_ppn_shift[i]);\n\t\ti++;\n\t}\n\tLOG_DEBUG(\"0x%\" TARGET_PRIxADDR \" -> 0x%\" TARGET_PRIxADDR, virtual,\n\t\t\t*physical);\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_virt2phys(struct target *target, target_addr_t virtual, target_addr_t *physical)\n{\n\tint enabled;\n\tif (riscv_mmu(target, &enabled) == ERROR_OK) {\n\t\tif (!enabled)\n\t\t\treturn ERROR_FAIL;\n\n\t\tif (riscv_address_translate(target, virtual, physical) == ERROR_OK)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nstatic int riscv_read_phys_memory(struct target *target, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tRISCV_INFO(r);\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\treturn r->read_memory(target, phys_address, size, count, buffer, size);\n}\n\nstatic int riscv_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tif (count == 0) {\n\t\tLOG_WARNING(\"0-length read from 0x%\" TARGET_PRIxADDR, address);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttarget_addr_t physical_addr;\n\tif (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK)\n\t\taddress = physical_addr;\n\n\tRISCV_INFO(r);\n\treturn r->read_memory(target, address, size, count, buffer, size);\n}\n\nstatic int riscv_write_phys_memory(struct target *target, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->write_memory(target, phys_address, size, count, buffer);\n}\n\nstatic int riscv_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tif (count == 0) {\n\t\tLOG_WARNING(\"0-length write to 0x%\" TARGET_PRIxADDR, address);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttarget_addr_t physical_addr;\n\tif (target->type->virt2phys(target, address, &physical_addr) == ERROR_OK)\n\t\taddress = physical_addr;\n\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->write_memory(target, address, size, count, buffer);\n}\n\nstatic const char *riscv_get_gdb_arch(struct target *target)\n{\n\tswitch (riscv_xlen(target)) {\n\t\tcase 32:\n\t\t\treturn \"riscv:rv32\";\n\t\tcase 64:\n\t\t\treturn \"riscv:rv64\";\n\t}\n\tLOG_ERROR(\"Unsupported xlen: %d\", riscv_xlen(target));\n\treturn NULL;\n}\n\nstatic int riscv_get_gdb_reg_list_internal(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class, bool read)\n{\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"[%s] {%d} reg_class=%d, read=%d\",\n\t\t\ttarget_name(target), r->current_hartid, reg_class, read);\n\n\tif (!target->reg_cache) {\n\t\tLOG_ERROR(\"Target not initialized. Return ERROR_FAIL.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tswitch (reg_class) {\n\t\tcase REG_CLASS_GENERAL:\n\t\t\t*reg_list_size = 33;\n\t\t\tbreak;\n\t\tcase REG_CLASS_ALL:\n\t\t\t*reg_list_size = target->reg_cache->num_regs;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Unsupported reg_class: %d\", reg_class);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t*reg_list = calloc(*reg_list_size, sizeof(struct reg *));\n\tif (!*reg_list)\n\t\treturn ERROR_FAIL;\n\n\tfor (int i = 0; i < *reg_list_size; i++) {\n\t\tassert(!target->reg_cache->reg_list[i].valid ||\n\t\t\t\ttarget->reg_cache->reg_list[i].size > 0);\n\t\t(*reg_list)[i] = &target->reg_cache->reg_list[i];\n\t\tif (read &&\n\t\t\t\ttarget->reg_cache->reg_list[i].exist &&\n\t\t\t\t!target->reg_cache->reg_list[i].valid) {\n\t\t\tif (target->reg_cache->reg_list[i].type->get(\n\t\t\t\t\t\t&target->reg_cache->reg_list[i]) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_get_gdb_reg_list_noread(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class)\n{\n\treturn riscv_get_gdb_reg_list_internal(target, reg_list, reg_list_size,\n\t\t\treg_class, false);\n}\n\nstatic int riscv_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class)\n{\n\treturn riscv_get_gdb_reg_list_internal(target, reg_list, reg_list_size,\n\t\t\treg_class, true);\n}\n\nstatic int riscv_arch_state(struct target *target)\n{\n\tstruct target_type *tt = get_target_type(target);\n\treturn tt->arch_state(target);\n}\n\n/* Algorithm must end with a software breakpoint instruction. */\nstatic int riscv_run_algorithm(struct target *target, int num_mem_params,\n\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\tstruct reg_param *reg_params, target_addr_t entry_point,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms, void *arch_info)\n{\n\tRISCV_INFO(info);\n\n\tif (num_mem_params > 0) {\n\t\tLOG_ERROR(\"Memory parameters are not supported for RISC-V algorithms.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* Save registers */\n\tstruct reg *reg_pc = register_get_by_name(target->reg_cache, \"pc\", true);\n\tif (!reg_pc || reg_pc->type->get(reg_pc) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tuint64_t saved_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);\n\tLOG_DEBUG(\"saved_pc=0x%\" PRIx64, saved_pc);\n\n\tuint64_t saved_regs[32];\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tLOG_DEBUG(\"save %s\", reg_params[i].reg_name);\n\t\tstruct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false);\n\t\tif (!r) {\n\t\t\tLOG_ERROR(\"Couldn't find register named '%s'\", reg_params[i].reg_name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (r->size != reg_params[i].size) {\n\t\t\tLOG_ERROR(\"Register %s is %d bits instead of %d bits.\",\n\t\t\t\t\treg_params[i].reg_name, r->size, reg_params[i].size);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (r->number > GDB_REGNO_XPR31) {\n\t\t\tLOG_ERROR(\"Only GPRs can be use as argument registers.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (r->type->get(r) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tsaved_regs[r->number] = buf_get_u64(r->value, 0, r->size);\n\n\t\tif (reg_params[i].direction == PARAM_OUT || reg_params[i].direction == PARAM_IN_OUT) {\n\t\t\tif (r->type->set(r, reg_params[i].value) != ERROR_OK)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\n\t/* Disable Interrupts before attempting to run the algorithm. */\n\tuint64_t current_mstatus;\n\tuint8_t mstatus_bytes[8] = { 0 };\n\n\tLOG_DEBUG(\"Disabling Interrupts\");\n\tstruct reg *reg_mstatus = register_get_by_name(target->reg_cache,\n\t\t\t\"mstatus\", true);\n\tif (!reg_mstatus) {\n\t\tLOG_ERROR(\"Couldn't find mstatus!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treg_mstatus->type->get(reg_mstatus);\n\tcurrent_mstatus = buf_get_u64(reg_mstatus->value, 0, reg_mstatus->size);\n\tuint64_t ie_mask = MSTATUS_MIE | MSTATUS_HIE | MSTATUS_SIE | MSTATUS_UIE;\n\tbuf_set_u64(mstatus_bytes, 0, info->xlen, set_field(current_mstatus,\n\t\t\t\tie_mask, 0));\n\n\treg_mstatus->type->set(reg_mstatus, mstatus_bytes);\n\n\t/* Run algorithm */\n\tLOG_DEBUG(\"resume at 0x%\" TARGET_PRIxADDR, entry_point);\n\tif (riscv_resume(target, 0, entry_point, 0, 0, true) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tint64_t start = timeval_ms();\n\twhile (target->state != TARGET_HALTED) {\n\t\tLOG_DEBUG(\"poll()\");\n\t\tint64_t now = timeval_ms();\n\t\tif (now - start > timeout_ms) {\n\t\t\tLOG_ERROR(\"Algorithm timed out after %\" PRId64 \" ms.\", now - start);\n\t\t\triscv_halt(target);\n\t\t\told_or_new_riscv_poll(target);\n\t\t\tenum gdb_regno regnums[] = {\n\t\t\t\tGDB_REGNO_RA, GDB_REGNO_SP, GDB_REGNO_GP, GDB_REGNO_TP,\n\t\t\t\tGDB_REGNO_T0, GDB_REGNO_T1, GDB_REGNO_T2, GDB_REGNO_FP,\n\t\t\t\tGDB_REGNO_S1, GDB_REGNO_A0, GDB_REGNO_A1, GDB_REGNO_A2,\n\t\t\t\tGDB_REGNO_A3, GDB_REGNO_A4, GDB_REGNO_A5, GDB_REGNO_A6,\n\t\t\t\tGDB_REGNO_A7, GDB_REGNO_S2, GDB_REGNO_S3, GDB_REGNO_S4,\n\t\t\t\tGDB_REGNO_S5, GDB_REGNO_S6, GDB_REGNO_S7, GDB_REGNO_S8,\n\t\t\t\tGDB_REGNO_S9, GDB_REGNO_S10, GDB_REGNO_S11, GDB_REGNO_T3,\n\t\t\t\tGDB_REGNO_T4, GDB_REGNO_T5, GDB_REGNO_T6,\n\t\t\t\tGDB_REGNO_PC,\n\t\t\t\tGDB_REGNO_MSTATUS, GDB_REGNO_MEPC, GDB_REGNO_MCAUSE,\n\t\t\t};\n\t\t\tfor (unsigned i = 0; i < ARRAY_SIZE(regnums); i++) {\n\t\t\t\tenum gdb_regno regno = regnums[i];\n\t\t\t\triscv_reg_t reg_value;\n\t\t\t\tif (riscv_get_register(target, &reg_value, regno) != ERROR_OK)\n\t\t\t\t\tbreak;\n\t\t\t\tLOG_ERROR(\"%s = 0x%\" PRIx64, gdb_regno_name(regno), reg_value);\n\t\t\t}\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\n\t\tint result = old_or_new_riscv_poll(target);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t}\n\n\t/* The current hart id might have been changed in poll(). */\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tif (reg_pc->type->get(reg_pc) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tuint64_t final_pc = buf_get_u64(reg_pc->value, 0, reg_pc->size);\n\tif (exit_point && final_pc != exit_point) {\n\t\tLOG_ERROR(\"PC ended up at 0x%\" PRIx64 \" instead of 0x%\"\n\t\t\t\tTARGET_PRIxADDR, final_pc, exit_point);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Restore Interrupts */\n\tLOG_DEBUG(\"Restoring Interrupts\");\n\tbuf_set_u64(mstatus_bytes, 0, info->xlen, current_mstatus);\n\treg_mstatus->type->set(reg_mstatus, mstatus_bytes);\n\n\t/* Restore registers */\n\tuint8_t buf[8] = { 0 };\n\tbuf_set_u64(buf, 0, info->xlen, saved_pc);\n\tif (reg_pc->type->set(reg_pc, buf) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN ||\n\t\t\t\treg_params[i].direction == PARAM_IN_OUT) {\n\t\t\tstruct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false);\n\t\t\tif (r->type->get(r) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"get(%s) failed\", r->name);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbuf_cpy(r->value, reg_params[i].value, reg_params[i].size);\n\t\t}\n\t\tLOG_DEBUG(\"restore %s\", reg_params[i].reg_name);\n\t\tstruct reg *r = register_get_by_name(target->reg_cache, reg_params[i].reg_name, false);\n\t\tbuf_set_u64(buf, 0, info->xlen, saved_regs[r->number]);\n\t\tif (r->type->set(r, buf) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"set(%s) failed\", r->name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_checksum_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t count,\n\t\tuint32_t *checksum)\n{\n\tstruct working_area *crc_algorithm;\n\tstruct reg_param reg_params[2];\n\tint retval;\n\n\tLOG_DEBUG(\"address=0x%\" TARGET_PRIxADDR \"; count=0x%\" PRIx32, address, count);\n\n\tstatic const uint8_t riscv32_crc_code[] = {\n#include \"../../../contrib/loaders/checksum/riscv32_crc.inc\"\n\t};\n\tstatic const uint8_t riscv64_crc_code[] = {\n#include \"../../../contrib/loaders/checksum/riscv64_crc.inc\"\n\t};\n\n\tstatic const uint8_t *crc_code;\n\n\tunsigned xlen = riscv_xlen(target);\n\tunsigned crc_code_size;\n\tif (xlen == 32) {\n\t\tcrc_code = riscv32_crc_code;\n\t\tcrc_code_size = sizeof(riscv32_crc_code);\n\t} else {\n\t\tcrc_code = riscv64_crc_code;\n\t\tcrc_code_size = sizeof(riscv64_crc_code);\n\t}\n\n\tif (count < crc_code_size * 4) {\n\t\t/* Don't use the algorithm for relatively small buffers. It's faster\n\t\t * just to read the memory.  target_checksum_memory() will take care of\n\t\t * that if we fail. */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target_alloc_working_area(target, crc_code_size, &crc_algorithm);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (crc_algorithm->address + crc_algorithm->size > address &&\n\t\t\tcrc_algorithm->address < address + count) {\n\t\t/* Region to checksum overlaps with the work area we've been assigned.\n\t\t * Bail. (Would be better to manually checksum what we read there, and\n\t\t * use the algorithm for the rest.) */\n\t\ttarget_free_working_area(target, crc_algorithm);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target_write_buffer(target, crc_algorithm->address, crc_code_size,\n\t\t\tcrc_code);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to write code to \" TARGET_ADDR_FMT \": %d\",\n\t\t\t\tcrc_algorithm->address, retval);\n\t\ttarget_free_working_area(target, crc_algorithm);\n\t\treturn retval;\n\t}\n\n\tinit_reg_param(&reg_params[0], \"a0\", xlen, PARAM_IN_OUT);\n\tinit_reg_param(&reg_params[1], \"a1\", xlen, PARAM_OUT);\n\tbuf_set_u64(reg_params[0].value, 0, xlen, address);\n\tbuf_set_u64(reg_params[1].value, 0, xlen, count);\n\n\t/* 20 second timeout/megabyte */\n\tunsigned int timeout = 20000 * (1 + (count / (1024 * 1024)));\n\n\tretval = target_run_algorithm(target, 0, NULL, 2, reg_params,\n\t\t\tcrc_algorithm->address,\n\t\t\t0,\t/* Leave exit point unspecified because we don't know. */\n\t\t\ttimeout, NULL);\n\n\tif (retval == ERROR_OK)\n\t\t*checksum = buf_get_u32(reg_params[0].value, 0, 32);\n\telse\n\t\tLOG_ERROR(\"error executing RISC-V CRC algorithm\");\n\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\ttarget_free_working_area(target, crc_algorithm);\n\n\tLOG_DEBUG(\"checksum=0x%\" PRIx32 \", result=%d\", *checksum, retval);\n\n\treturn retval;\n}\n\n/*** OpenOCD Helper Functions ***/\n\nenum riscv_poll_hart {\n\tRPH_NO_CHANGE,\n\tRPH_DISCOVERED_HALTED,\n\tRPH_DISCOVERED_RUNNING,\n\tRPH_ERROR\n};\nstatic enum riscv_poll_hart riscv_poll_hart(struct target *target, int hartid)\n{\n\tRISCV_INFO(r);\n\tif (riscv_set_current_hartid(target, hartid) != ERROR_OK)\n\t\treturn RPH_ERROR;\n\n\tLOG_DEBUG(\"polling hart %d, target->state=%d\", hartid, target->state);\n\n\t/* If OpenOCD thinks we're running but this hart is halted then it's time\n\t * to raise an event. */\n\tbool halted = riscv_is_halted(target);\n\tif (target->state != TARGET_HALTED && halted) {\n\t\tLOG_DEBUG(\"  triggered a halt\");\n\t\tr->on_halt(target);\n\t\treturn RPH_DISCOVERED_HALTED;\n\t} else if (target->state != TARGET_RUNNING && !halted) {\n\t\tLOG_DEBUG(\"  triggered running\");\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t\treturn RPH_DISCOVERED_RUNNING;\n\t}\n\n\treturn RPH_NO_CHANGE;\n}\n\nstatic int set_debug_reason(struct target *target, enum riscv_halt_reason halt_reason)\n{\n\tswitch (halt_reason) {\n\t\tcase RISCV_HALT_BREAKPOINT:\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\tbreak;\n\t\tcase RISCV_HALT_TRIGGER:\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\tbreak;\n\t\tcase RISCV_HALT_INTERRUPT:\n\t\tcase RISCV_HALT_GROUP:\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\tbreak;\n\t\tcase RISCV_HALT_SINGLESTEP:\n\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t\t\tbreak;\n\t\tcase RISCV_HALT_UNKNOWN:\n\t\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\t\t\tbreak;\n\t\tcase RISCV_HALT_ERROR:\n\t\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"[%s] debug_reason=%d\", target_name(target), target->debug_reason);\n\treturn ERROR_OK;\n}\n\nstatic int sample_memory(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tif (!r->sample_buf.buf || !r->sample_config.enabled)\n\t\treturn ERROR_OK;\n\n\tLOG_DEBUG(\"buf used/size: %d/%d\", r->sample_buf.used, r->sample_buf.size);\n\n\tuint64_t start = timeval_ms();\n\triscv_sample_buf_maybe_add_timestamp(target, true);\n\tint result = ERROR_OK;\n\tif (r->sample_memory) {\n\t\tresult = r->sample_memory(target, &r->sample_buf, &r->sample_config,\n\t\t\t\t\t\t\t\t\t  start + TARGET_DEFAULT_POLLING_INTERVAL);\n\t\tif (result != ERROR_NOT_IMPLEMENTED)\n\t\t\tgoto exit;\n\t}\n\n\t/* Default slow path. */\n\twhile (timeval_ms() - start < TARGET_DEFAULT_POLLING_INTERVAL) {\n\t\tfor (unsigned int i = 0; i < ARRAY_SIZE(r->sample_config.bucket); i++) {\n\t\t\tif (r->sample_config.bucket[i].enabled &&\n\t\t\t\t\tr->sample_buf.used + 1 + r->sample_config.bucket[i].size_bytes < r->sample_buf.size) {\n\t\t\t\tassert(i < RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE);\n\t\t\t\tr->sample_buf.buf[r->sample_buf.used] = i;\n\t\t\t\tresult = riscv_read_phys_memory(\n\t\t\t\t\ttarget, r->sample_config.bucket[i].address,\n\t\t\t\t\tr->sample_config.bucket[i].size_bytes, 1,\n\t\t\t\t\tr->sample_buf.buf + r->sample_buf.used + 1);\n\t\t\t\tif (result == ERROR_OK)\n\t\t\t\t\tr->sample_buf.used += 1 + r->sample_config.bucket[i].size_bytes;\n\t\t\t\telse\n\t\t\t\t\tgoto exit;\n\t\t\t}\n\t\t}\n\t}\n\nexit:\n\triscv_sample_buf_maybe_add_timestamp(target, false);\n\tif (result != ERROR_OK) {\n\t\tLOG_INFO(\"Turning off memory sampling because it failed.\");\n\t\tr->sample_config.enabled = false;\n\t}\n\treturn result;\n}\n\n/*** OpenOCD Interface ***/\nint riscv_openocd_poll(struct target *target)\n{\n\tLOG_DEBUG(\"polling all harts\");\n\tint halted_hart = -1;\n\n\tif (target->smp) {\n\t\tunsigned should_remain_halted = 0;\n\t\tunsigned should_resume = 0;\n\t\tstruct target_list *list;\n\t\tforeach_smp_target(list, target->smp_targets) {\n\t\t\tstruct target *t = list->target;\n\t\t\tstruct riscv_info *r = riscv_info(t);\n\t\t\tenum riscv_poll_hart out = riscv_poll_hart(t, r->current_hartid);\n\t\t\tswitch (out) {\n\t\t\tcase RPH_NO_CHANGE:\n\t\t\t\tbreak;\n\t\t\tcase RPH_DISCOVERED_RUNNING:\n\t\t\t\tt->state = TARGET_RUNNING;\n\t\t\t\tt->debug_reason = DBG_REASON_NOTHALTED;\n\t\t\t\tbreak;\n\t\t\tcase RPH_DISCOVERED_HALTED:\n\t\t\t\tt->state = TARGET_HALTED;\n\t\t\t\tenum riscv_halt_reason halt_reason =\n\t\t\t\t\triscv_halt_reason(t, r->current_hartid);\n\t\t\t\tif (set_debug_reason(t, halt_reason) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\n\t\t\t\tif (halt_reason == RISCV_HALT_BREAKPOINT) {\n\t\t\t\t\tint retval;\n\t\t\t\t\tswitch (riscv_semihosting(t, &retval)) {\n\t\t\t\t\tcase SEMIHOSTING_NONE:\n\t\t\t\t\tcase SEMIHOSTING_WAITING:\n\t\t\t\t\t\t/* This hart should remain halted. */\n\t\t\t\t\t\tshould_remain_halted++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SEMIHOSTING_HANDLED:\n\t\t\t\t\t\t/* This hart should be resumed, along with any other\n\t\t\t\t\t\t\t * harts that halted due to haltgroups. */\n\t\t\t\t\t\tshould_resume++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase SEMIHOSTING_ERROR:\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\t}\n\t\t\t\t} else if (halt_reason != RISCV_HALT_GROUP) {\n\t\t\t\t\tshould_remain_halted++;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase RPH_ERROR:\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\tLOG_DEBUG(\"should_remain_halted=%d, should_resume=%d\",\n\t\t\t\t  should_remain_halted, should_resume);\n\t\tif (should_remain_halted && should_resume) {\n\t\t\tLOG_WARNING(\"%d harts should remain halted, and %d should resume.\",\n\t\t\t\t\t\tshould_remain_halted, should_resume);\n\t\t}\n\t\tif (should_remain_halted) {\n\t\t\tLOG_DEBUG(\"halt all\");\n\t\t\triscv_halt(target);\n\t\t} else if (should_resume) {\n\t\t\tLOG_DEBUG(\"resume all\");\n\t\t\triscv_resume(target, true, 0, 0, 0, false);\n\t\t}\n\n\t\t/* Sample memory if any target is running. */\n\t\tforeach_smp_target(list, target->smp_targets) {\n\t\t\tstruct target *t = list->target;\n\t\t\tif (t->state == TARGET_RUNNING) {\n\t\t\t\tsample_memory(target);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn ERROR_OK;\n\n\t} else {\n\t\tenum riscv_poll_hart out = riscv_poll_hart(target,\n\t\t\t\triscv_current_hartid(target));\n\t\tif (out == RPH_NO_CHANGE || out == RPH_DISCOVERED_RUNNING) {\n\t\t\tif (target->state == TARGET_RUNNING)\n\t\t\t\tsample_memory(target);\n\t\t\treturn ERROR_OK;\n\t\t} else if (out == RPH_ERROR) {\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\thalted_hart = riscv_current_hartid(target);\n\t\tLOG_DEBUG(\"  hart %d halted\", halted_hart);\n\n\t\tenum riscv_halt_reason halt_reason = riscv_halt_reason(target, halted_hart);\n\t\tif (set_debug_reason(target, halt_reason) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\ttarget->state = TARGET_HALTED;\n\t}\n\n\tif (target->debug_reason == DBG_REASON_BREAKPOINT) {\n\t\tint retval;\n\t\tswitch (riscv_semihosting(target, &retval)) {\n\t\t\tcase SEMIHOSTING_NONE:\n\t\t\tcase SEMIHOSTING_WAITING:\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t\tbreak;\n\t\t\tcase SEMIHOSTING_HANDLED:\n\t\t\t\tif (riscv_resume(target, true, 0, 0, 0, false) != ERROR_OK)\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\tcase SEMIHOSTING_ERROR:\n\t\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t}\n\n\treturn ERROR_OK;\n}\n\nint riscv_openocd_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\tLOG_DEBUG(\"stepping rtos hart\");\n\n\tif (!current)\n\t\triscv_set_register(target, GDB_REGNO_PC, address);\n\n\triscv_reg_t trigger_state[RISCV_MAX_HWBPS] = {0};\n\tif (disable_triggers(target, trigger_state) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tint out = riscv_step_rtos_hart(target);\n\tif (out != ERROR_OK) {\n\t\tLOG_ERROR(\"unable to step rtos hart\");\n\t\treturn out;\n\t}\n\n\tregister_cache_invalidate(target->reg_cache);\n\n\tif (enable_triggers(target, trigger_state) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\ttarget->state = TARGET_RUNNING;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\ttarget->state = TARGET_HALTED;\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\treturn out;\n}\n\n/* Command Handlers */\nCOMMAND_HANDLER(riscv_set_command_timeout_sec)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tint timeout = atoi(CMD_ARGV[0]);\n\tif (timeout <= 0) {\n\t\tLOG_ERROR(\"%s is not a valid integer argument for command.\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\triscv_command_timeout_sec = timeout;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_reset_timeout_sec)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tint timeout = atoi(CMD_ARGV[0]);\n\tif (timeout <= 0) {\n\t\tLOG_ERROR(\"%s is not a valid integer argument for command.\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\triscv_reset_timeout_sec = timeout;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_mem_access)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(r);\n\tint progbuf_cnt = 0;\n\tint sysbus_cnt = 0;\n\tint abstract_cnt = 0;\n\n\tif (CMD_ARGC < 1 || CMD_ARGC > RISCV_NUM_MEM_ACCESS_METHODS) {\n\t\tLOG_ERROR(\"Command takes 1 to %d parameters\", RISCV_NUM_MEM_ACCESS_METHODS);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* Check argument validity */\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tif (strcmp(\"progbuf\", CMD_ARGV[i]) == 0) {\n\t\t\tprogbuf_cnt++;\n\t\t} else if (strcmp(\"sysbus\", CMD_ARGV[i]) == 0) {\n\t\t\tsysbus_cnt++;\n\t\t} else if (strcmp(\"abstract\", CMD_ARGV[i]) == 0) {\n\t\t\tabstract_cnt++;\n\t\t} else {\n\t\t\tLOG_ERROR(\"Unknown argument '%s'. \"\n\t\t\t\t\"Must be one of: 'progbuf', 'sysbus' or 'abstract'.\", CMD_ARGV[i]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\tif (progbuf_cnt > 1 || sysbus_cnt > 1 || abstract_cnt > 1) {\n\t\tLOG_ERROR(\"Syntax error - duplicate arguments to `riscv set_mem_access`.\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* Args are valid, store them */\n\tfor (unsigned int i = 0; i < RISCV_NUM_MEM_ACCESS_METHODS; i++)\n\t\tr->mem_access_methods[i] = RISCV_MEM_ACCESS_UNSPECIFIED;\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tif (strcmp(\"progbuf\", CMD_ARGV[i]) == 0)\n\t\t\tr->mem_access_methods[i] = RISCV_MEM_ACCESS_PROGBUF;\n\t\telse if (strcmp(\"sysbus\", CMD_ARGV[i]) == 0)\n\t\t\tr->mem_access_methods[i] = RISCV_MEM_ACCESS_SYSBUS;\n\t\telse if (strcmp(\"abstract\", CMD_ARGV[i]) == 0)\n\t\t\tr->mem_access_methods[i] = RISCV_MEM_ACCESS_ABSTRACT;\n\t}\n\n\t/* Reset warning flags */\n\tr->mem_access_progbuf_warn = true;\n\tr->mem_access_sysbus_warn = true;\n\tr->mem_access_abstract_warn = true;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_enable_virtual)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_enable_virtual);\n\treturn ERROR_OK;\n}\n\nstatic int parse_ranges(struct list_head *ranges, const char *tcl_arg, const char *reg_type, unsigned int max_val)\n{\n\tchar *args = strdup(tcl_arg);\n\tif (!args)\n\t\treturn ERROR_FAIL;\n\n\t/* For backward compatibility, allow multiple parameters within one TCL argument, separated by ',' */\n\tchar *arg = strtok(args, \",\");\n\twhile (arg) {\n\t\tunsigned low = 0;\n\t\tunsigned high = 0;\n\t\tchar *name = NULL;\n\n\t\tchar *dash = strchr(arg, '-');\n\t\tchar *equals = strchr(arg, '=');\n\t\tunsigned int pos;\n\n\t\tif (!dash && !equals) {\n\t\t\t/* Expecting single register number. */\n\t\t\tif (sscanf(arg, \"%u%n\", &low, &pos) != 1 || pos != strlen(arg)) {\n\t\t\t\tLOG_ERROR(\"Failed to parse single register number from '%s'.\", arg);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t} else if (dash && !equals) {\n\t\t\t/* Expecting register range - two numbers separated by a dash: ##-## */\n\t\t\t*dash = 0;\n\t\t\tdash++;\n\t\t\tif (sscanf(arg, \"%u%n\", &low, &pos) != 1 || pos != strlen(arg)) {\n\t\t\t\tLOG_ERROR(\"Failed to parse single register number from '%s'.\", arg);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tif (sscanf(dash, \"%u%n\", &high, &pos) != 1 || pos != strlen(dash)) {\n\t\t\t\tLOG_ERROR(\"Failed to parse single register number from '%s'.\", dash);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\tif (high < low) {\n\t\t\t\tLOG_ERROR(\"Incorrect range encountered [%u, %u].\", low, high);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t} else if (!dash && equals) {\n\t\t\t/* Expecting single register number with textual name specified: ##=name */\n\t\t\t*equals = 0;\n\t\t\tequals++;\n\t\t\tif (sscanf(arg, \"%u%n\", &low, &pos) != 1 || pos != strlen(arg)) {\n\t\t\t\tLOG_ERROR(\"Failed to parse single register number from '%s'.\", arg);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tname = calloc(1, strlen(equals) + strlen(reg_type) + 2);\n\t\t\tif (!name) {\n\t\t\t\tLOG_ERROR(\"Failed to allocate register name.\");\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* Register prefix: \"csr_\" or \"custom_\" */\n\t\t\tstrcpy(name, reg_type);\n\t\t\tname[strlen(reg_type)] = '_';\n\n\t\t\tif (sscanf(equals, \"%[_a-zA-Z0-9]%n\", name + strlen(reg_type) + 1, &pos) != 1 || pos != strlen(equals)) {\n\t\t\t\tLOG_ERROR(\"Failed to parse register name from '%s'.\", equals);\n\t\t\t\tfree(args);\n\t\t\t\tfree(name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"Invalid argument '%s'.\", arg);\n\t\t\tfree(args);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\thigh = high > low ? high : low;\n\n\t\tif (high > max_val) {\n\t\t\tLOG_ERROR(\"Cannot expose %s register number %u, maximum allowed value is %u.\", reg_type, high, max_val);\n\t\t\tfree(name);\n\t\t\tfree(args);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Check for overlap, name uniqueness. */\n\t\trange_list_t *entry;\n\t\tlist_for_each_entry(entry, ranges, list) {\n\t\t\tif ((entry->low <= high) && (low <= entry->high)) {\n\t\t\t\tif (low == high)\n\t\t\t\t\tLOG_WARNING(\"Duplicate %s register number - \"\n\t\t\t\t\t\t\t\"Register %u has already been exposed previously\", reg_type, low);\n\t\t\t\telse\n\t\t\t\t\tLOG_WARNING(\"Overlapping register ranges - Register range starting from %u overlaps \"\n\t\t\t\t\t\t\t\"with already exposed register/range at %u.\", low, entry->low);\n\t\t\t}\n\n\t\t\tif (entry->name && name && (strcasecmp(entry->name, name) == 0)) {\n\t\t\t\tLOG_ERROR(\"Duplicate register name \\\"%s\\\" found.\", name);\n\t\t\t\tfree(name);\n\t\t\t\tfree(args);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\trange_list_t *range = calloc(1, sizeof(range_list_t));\n\t\tif (!range) {\n\t\t\tLOG_ERROR(\"Failed to allocate range list.\");\n\t\t\tfree(name);\n\t\t\tfree(args);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\trange->low = low;\n\t\trange->high = high;\n\t\trange->name = name;\n\t\tlist_add(&range->list, ranges);\n\n\t\targ = strtok(NULL, \",\");\n\t}\n\n\tfree(args);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_expose_csrs)\n{\n\tif (CMD_ARGC == 0) {\n\t\tLOG_ERROR(\"Command expects parameters\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(info);\n\tint ret = ERROR_OK;\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tret = parse_ranges(&info->expose_csr, CMD_ARGV[i], \"csr\", 0xfff);\n\t\tif (ret != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nCOMMAND_HANDLER(riscv_set_expose_custom)\n{\n\tif (CMD_ARGC == 0) {\n\t\tLOG_ERROR(\"Command expects parameters\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(info);\n\tint ret = ERROR_OK;\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tret = parse_ranges(&info->expose_custom, CMD_ARGV[i], \"custom\", 0x3fff);\n\t\tif (ret != ERROR_OK)\n\t\t\tbreak;\n\t}\n\n\treturn ret;\n}\n\nCOMMAND_HANDLER(riscv_authdata_read)\n{\n\tunsigned int index = 0;\n\tif (CMD_ARGC == 0) {\n\t\t/* nop */\n\t} else if (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], index);\n\t} else {\n\t\tLOG_ERROR(\"Command takes at most one parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tLOG_ERROR(\"target is NULL!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tRISCV_INFO(r);\n\tif (!r) {\n\t\tLOG_ERROR(\"riscv_info is NULL!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (r->authdata_read) {\n\t\tuint32_t value;\n\t\tif (r->authdata_read(target, &value, index) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tcommand_print_sameline(CMD, \"0x%08\" PRIx32, value);\n\t\treturn ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"authdata_read is not implemented for this target.\");\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nCOMMAND_HANDLER(riscv_authdata_write)\n{\n\tuint32_t value;\n\tunsigned int index = 0;\n\n\tif (CMD_ARGC == 0 || CMD_ARGC > 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], value);\n\t} else {\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], index);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(r);\n\n\tif (!r->authdata_write) {\n\t\tLOG_ERROR(\"authdata_write is not implemented for this target.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn r->authdata_write(target, value, index);\n}\n\nCOMMAND_HANDLER(riscv_dmi_read)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target) {\n\t\tLOG_ERROR(\"target is NULL!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tRISCV_INFO(r);\n\tif (!r) {\n\t\tLOG_ERROR(\"riscv_info is NULL!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (r->dmi_read) {\n\t\tuint32_t address, value;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\t\tif (r->dmi_read(target, &value, address) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t\tcommand_print(CMD, \"0x%\" PRIx32, value);\n\t\treturn ERROR_OK;\n\t} else {\n\t\tLOG_ERROR(\"dmi_read is not implemented for this target.\");\n\t\treturn ERROR_FAIL;\n\t}\n}\n\n\nCOMMAND_HANDLER(riscv_dmi_write)\n{\n\tif (CMD_ARGC != 2) {\n\t\tLOG_ERROR(\"Command takes exactly 2 arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(r);\n\n\tuint32_t address, value;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\tif (r->dmi_write) {\n\t\treturn r->dmi_write(target, address, value);\n\t} else {\n\t\tLOG_ERROR(\"dmi_write is not implemented for this target.\");\n\t\treturn ERROR_FAIL;\n\t}\n}\n\nCOMMAND_HANDLER(riscv_reset_delays)\n{\n\tint wait = 0;\n\n\tif (CMD_ARGC > 1) {\n\t\tLOG_ERROR(\"Command takes at most one argument\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC == 1)\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], wait);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(r);\n\tr->reset_delays_wait = wait;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_ir)\n{\n\tif (CMD_ARGC != 2) {\n\t\tLOG_ERROR(\"Command takes exactly 2 arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tuint32_t value;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\tif (!strcmp(CMD_ARGV[0], \"idcode\"))\n\t\tbuf_set_u32(ir_idcode, 0, 32, value);\n\telse if (!strcmp(CMD_ARGV[0], \"dtmcs\"))\n\t\tbuf_set_u32(ir_dtmcontrol, 0, 32, value);\n\telse if (!strcmp(CMD_ARGV[0], \"dmi\"))\n\t\tbuf_set_u32(ir_dbus, 0, 32, value);\n\telse\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_resume_order)\n{\n\tif (CMD_ARGC > 1) {\n\t\tLOG_ERROR(\"Command takes at most one argument\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (!strcmp(CMD_ARGV[0], \"normal\")) {\n\t\tresume_order = RO_NORMAL;\n\t} else if (!strcmp(CMD_ARGV[0], \"reversed\")) {\n\t\tresume_order = RO_REVERSED;\n\t} else {\n\t\tLOG_ERROR(\"Unsupported resume order: %s\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_use_bscan_tunnel)\n{\n\tint irwidth = 0;\n\tint tunnel_type = BSCAN_TUNNEL_NESTED_TAP;\n\n\tif (CMD_ARGC > 2) {\n\t\tLOG_ERROR(\"Command takes at most two arguments\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else if (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);\n\t} else if (CMD_ARGC == 2) {\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);\n\t}\n\tif (tunnel_type == BSCAN_TUNNEL_NESTED_TAP)\n\t\tLOG_INFO(\"Nested Tap based Bscan Tunnel Selected\");\n\telse if (tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)\n\t\tLOG_INFO(\"Simple Register based Bscan Tunnel Selected\");\n\telse\n\t\tLOG_INFO(\"Invalid Tunnel type selected ! : selecting default Nested Tap Type\");\n\n\tbscan_tunnel_type = tunnel_type;\n\tbscan_tunnel_ir_width = irwidth;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_enable_virt2phys)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_enable_virt2phys);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_ebreakm)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreakm);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_ebreaks)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaks);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(riscv_set_ebreaku)\n{\n\tif (CMD_ARGC != 1) {\n\t\tLOG_ERROR(\"Command takes exactly 1 parameter\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], riscv_ebreaku);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,\n\t\t\t   unsigned int value)\n{\n\tchar full_key[80];\n\tsnprintf(full_key, sizeof(full_key), \"%s.%s\", section, key);\n\tcommand_print(CMD, \"%-21s %3d\", full_key, value);\n\treturn 0;\n}\n\nCOMMAND_HANDLER(handle_info)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tRISCV_INFO(r);\n\n\t/* This output format can be fed directly into TCL's \"array set\". */\n\n\triscv_print_info_line(CMD, \"hart\", \"xlen\", riscv_xlen(target));\n\triscv_enumerate_triggers(target);\n\triscv_print_info_line(CMD, \"hart\", \"trigger_count\",\n\t\t\t\t\t\t  r->trigger_count);\n\n\tif (r->print_info)\n\t\treturn CALL_COMMAND_HANDLER(r->print_info, target);\n\n\treturn 0;\n}\n\nstatic const struct command_registration riscv_exec_command_handlers[] = {\n\t{\n\t\t.name = \"info\",\n\t\t.handler = handle_info,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"Displays some information OpenOCD detected about the target.\"\n\t},\n\t{\n\t\t.name = \"set_command_timeout_sec\",\n\t\t.handler = riscv_set_command_timeout_sec,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[sec]\",\n\t\t.help = \"Set the wall-clock timeout (in seconds) for individual commands\"\n\t},\n\t{\n\t\t.name = \"set_reset_timeout_sec\",\n\t\t.handler = riscv_set_reset_timeout_sec,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[sec]\",\n\t\t.help = \"Set the wall-clock timeout (in seconds) after reset is deasserted\"\n\t},\n\t{\n\t\t.name = \"set_mem_access\",\n\t\t.handler = riscv_set_mem_access,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"method1 [method2] [method3]\",\n\t\t.help = \"Set which memory access methods shall be used and in which order \"\n\t\t\t\"of priority. Method can be one of: 'progbuf', 'sysbus' or 'abstract'.\"\n\t},\n\t{\n\t\t.name = \"set_enable_virtual\",\n\t\t.handler = riscv_set_enable_virtual,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"on|off\",\n\t\t.help = \"When on, memory accesses are performed on physical or virtual \"\n\t\t\t\t\"memory depending on the current system configuration. \"\n\t\t\t\t\"When off (default), all memory accessses are performed on physical memory.\"\n\t},\n\t{\n\t\t.name = \"expose_csrs\",\n\t\t.handler = riscv_set_expose_csrs,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"n0[-m0|=name0][,n1[-m1|=name1]]...\",\n\t\t.help = \"Configure a list of inclusive ranges for CSRs to expose in \"\n\t\t\t\t\"addition to the standard ones. This must be executed before \"\n\t\t\t\t\"`init`.\"\n\t},\n\t{\n\t\t.name = \"expose_custom\",\n\t\t.handler = riscv_set_expose_custom,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.usage = \"n0[-m0|=name0][,n1[-m1|=name1]]...\",\n\t\t.help = \"Configure a list of inclusive ranges for custom registers to \"\n\t\t\t\"expose. custom0 is accessed as abstract register number 0xc000, \"\n\t\t\t\"etc. This must be executed before `init`.\"\n\t},\n\t{\n\t\t.name = \"authdata_read\",\n\t\t.handler = riscv_authdata_read,\n\t\t.usage = \"[index]\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Return the 32-bit value read from authdata or authdata0 \"\n\t\t\t\t\"(index=0), or authdata1 (index=1).\"\n\t},\n\t{\n\t\t.name = \"authdata_write\",\n\t\t.handler = riscv_authdata_write,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[index] value\",\n\t\t.help = \"Write the 32-bit value to authdata or authdata0 (index=0), \"\n\t\t\t\t\"or authdata1 (index=1).\"\n\t},\n\t{\n\t\t.name = \"dmi_read\",\n\t\t.handler = riscv_dmi_read,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"address\",\n\t\t.help = \"Perform a 32-bit DMI read at address, returning the value.\"\n\t},\n\t{\n\t\t.name = \"dmi_write\",\n\t\t.handler = riscv_dmi_write,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"address value\",\n\t\t.help = \"Perform a 32-bit DMI write of value at address.\"\n\t},\n\t{\n\t\t.name = \"reset_delays\",\n\t\t.handler = riscv_reset_delays,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[wait]\",\n\t\t.help = \"OpenOCD learns how many Run-Test/Idle cycles are required \"\n\t\t\t\"between scans to avoid encountering the target being busy. This \"\n\t\t\t\"command resets those learned values after `wait` scans. It's only \"\n\t\t\t\"useful for testing OpenOCD itself.\"\n\t},\n\t{\n\t\t.name = \"resume_order\",\n\t\t.handler = riscv_resume_order,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"normal|reversed\",\n\t\t.help = \"Choose the order that harts are resumed in when `hasel` is not \"\n\t\t\t\"supported. Normal order is from lowest hart index to highest. \"\n\t\t\t\"Reversed order is from highest hart index to lowest.\"\n\t},\n\t{\n\t\t.name = \"set_ir\",\n\t\t.handler = riscv_set_ir,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"[idcode|dtmcs|dmi] value\",\n\t\t.help = \"Set IR value for specified JTAG register.\"\n\t},\n\t{\n\t\t.name = \"use_bscan_tunnel\",\n\t\t.handler = riscv_use_bscan_tunnel,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"value [type]\",\n\t\t.help = \"Enable or disable use of a BSCAN tunnel to reach DM.  Supply \"\n\t\t\t\"the width of the DM transport TAP's instruction register to \"\n\t\t\t\"enable.  Supply a value of 0 to disable. Pass A second argument \"\n\t\t\t\"(optional) to indicate Bscan Tunnel Type {0:(default) NESTED_TAP , \"\n\t\t\t\"1: DATA_REGISTER}\"\n\t},\n\t{\n\t\t.name = \"set_enable_virt2phys\",\n\t\t.handler = riscv_set_enable_virt2phys,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"on|off\",\n\t\t.help = \"When on (default), enable translation from virtual address to \"\n\t\t\t\"physical address.\"\n\t},\n\t{\n\t\t.name = \"set_ebreakm\",\n\t\t.handler = riscv_set_ebreakm,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"on|off\",\n\t\t.help = \"Control dcsr.ebreakm. When off, M-mode ebreak instructions \"\n\t\t\t\"don't trap to OpenOCD. Defaults to on.\"\n\t},\n\t{\n\t\t.name = \"set_ebreaks\",\n\t\t.handler = riscv_set_ebreaks,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"on|off\",\n\t\t.help = \"Control dcsr.ebreaks. When off, S-mode ebreak instructions \"\n\t\t\t\"don't trap to OpenOCD. Defaults to on.\"\n\t},\n\t{\n\t\t.name = \"set_ebreaku\",\n\t\t.handler = riscv_set_ebreaku,\n\t\t.mode = COMMAND_ANY,\n\t\t.usage = \"on|off\",\n\t\t.help = \"Control dcsr.ebreaku. When off, U-mode ebreak instructions \"\n\t\t\t\"don't trap to OpenOCD. Defaults to on.\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\n/*\n * To be noted that RISC-V targets use the same semihosting commands as\n * ARM targets.\n *\n * The main reason is compatibility with existing tools. For example the\n * Eclipse OpenOCD/SEGGER J-Link/QEMU plug-ins have several widgets to\n * configure semihosting, which generate commands like `arm semihosting\n * enable`.\n * A secondary reason is the fact that the protocol used is exactly the\n * one specified by ARM. If RISC-V will ever define its own semihosting\n * protocol, then a command like `riscv semihosting enable` will make\n * sense, but for now all semihosting commands are prefixed with `arm`.\n */\n\nstatic const struct command_registration riscv_command_handlers[] = {\n\t{\n\t\t.name = \"riscv\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"RISC-V Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = riscv_exec_command_handlers\n\t},\n\t{\n\t\t.name = \"arm\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"ARM Command Group\",\n\t\t.usage = \"\",\n\t\t.chain = semihosting_common_handlers\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic unsigned riscv_xlen_nonconst(struct target *target)\n{\n\treturn riscv_xlen(target);\n}\n\nstatic unsigned int riscv_data_bits(struct target *target)\n{\n\tRISCV_INFO(r);\n\tif (r->data_bits)\n\t\treturn r->data_bits(target);\n\treturn riscv_xlen(target);\n}\n\nstruct target_type riscv_target = {\n\t.name = \"riscv\",\n\n\t.target_create = riscv_create_target,\n\t.init_target = riscv_init_target,\n\t.deinit_target = riscv_deinit_target,\n\t.examine = riscv_examine,\n\n\t/* poll current target status */\n\t.poll = old_or_new_riscv_poll,\n\n\t.halt = riscv_halt,\n\t.resume = riscv_target_resume,\n\t.step = old_or_new_riscv_step,\n\n\t.assert_reset = riscv_assert_reset,\n\t.deassert_reset = riscv_deassert_reset,\n\n\t.read_memory = riscv_read_memory,\n\t.write_memory = riscv_write_memory,\n\t.read_phys_memory = riscv_read_phys_memory,\n\t.write_phys_memory = riscv_write_phys_memory,\n\n\t.checksum_memory = riscv_checksum_memory,\n\n\t.mmu = riscv_mmu,\n\t.virt2phys = riscv_virt2phys,\n\n\t.get_gdb_arch = riscv_get_gdb_arch,\n\t.get_gdb_reg_list = riscv_get_gdb_reg_list,\n\t.get_gdb_reg_list_noread = riscv_get_gdb_reg_list_noread,\n\n\t.add_breakpoint = riscv_add_breakpoint,\n\t.remove_breakpoint = riscv_remove_breakpoint,\n\n\t.add_watchpoint = riscv_add_watchpoint,\n\t.remove_watchpoint = riscv_remove_watchpoint,\n\t.hit_watchpoint = riscv_hit_watchpoint,\n\n\t.arch_state = riscv_arch_state,\n\n\t.run_algorithm = riscv_run_algorithm,\n\n\t.commands = riscv_command_handlers,\n\n\t.address_bits = riscv_xlen_nonconst,\n\t.data_bits = riscv_data_bits\n};\n\n/*** RISC-V Interface ***/\n\n/* Initializes the shared RISC-V structure. */\nstatic void riscv_info_init(struct target *target, struct riscv_info *r)\n{\n\tmemset(r, 0, sizeof(*r));\n\n\tr->common_magic = RISCV_COMMON_MAGIC;\n\n\tr->dtm_version = 1;\n\tr->current_hartid = target->coreid;\n\tr->version_specific = NULL;\n\n\tmemset(r->trigger_unique_id, 0xff, sizeof(r->trigger_unique_id));\n\n\tr->xlen = -1;\n\n\tr->mem_access_methods[0] = RISCV_MEM_ACCESS_PROGBUF;\n\tr->mem_access_methods[1] = RISCV_MEM_ACCESS_SYSBUS;\n\tr->mem_access_methods[2] = RISCV_MEM_ACCESS_ABSTRACT;\n\n\tr->mem_access_progbuf_warn = true;\n\tr->mem_access_sysbus_warn = true;\n\tr->mem_access_abstract_warn = true;\n\n\tINIT_LIST_HEAD(&r->expose_csr);\n\tINIT_LIST_HEAD(&r->expose_custom);\n}\n\nstatic int riscv_resume_go_all_harts(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tLOG_DEBUG(\"[%s] resuming hart\", target_name(target));\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (riscv_is_halted(target)) {\n\t\tif (r->resume_go(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_DEBUG(\"[%s] hart requested resume, but was already resumed\",\n\t\t\t\ttarget_name(target));\n\t}\n\n\triscv_invalidate_register_cache(target);\n\treturn ERROR_OK;\n}\n\n/* Steps the hart that's currently selected in the RTOS, or if there is no RTOS\n * then the only hart. */\nstatic int riscv_step_rtos_hart(struct target *target)\n{\n\tRISCV_INFO(r);\n\tif (riscv_select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tLOG_DEBUG(\"[%s] stepping\", target_name(target));\n\n\tif (!riscv_is_halted(target)) {\n\t\tLOG_ERROR(\"Hart isn't halted before single step!\");\n\t\treturn ERROR_FAIL;\n\t}\n\triscv_invalidate_register_cache(target);\n\tr->on_step(target);\n\tif (r->step_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\triscv_invalidate_register_cache(target);\n\tr->on_halt(target);\n\tif (!riscv_is_halted(target)) {\n\t\tLOG_ERROR(\"Hart was not halted after single step!\");\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nbool riscv_supports_extension(struct target *target, char letter)\n{\n\tRISCV_INFO(r);\n\tunsigned num;\n\tif (letter >= 'a' && letter <= 'z')\n\t\tnum = letter - 'a';\n\telse if (letter >= 'A' && letter <= 'Z')\n\t\tnum = letter - 'A';\n\telse\n\t\treturn false;\n\treturn r->misa & BIT(num);\n}\n\nunsigned riscv_xlen(const struct target *target)\n{\n\tRISCV_INFO(r);\n\treturn r->xlen;\n}\n\nint riscv_set_current_hartid(struct target *target, int hartid)\n{\n\tRISCV_INFO(r);\n\tif (!r->select_current_hart)\n\t\treturn ERROR_OK;\n\n\tint previous_hartid = riscv_current_hartid(target);\n\tr->current_hartid = hartid;\n\tLOG_DEBUG(\"setting hartid to %d, was %d\", hartid, previous_hartid);\n\tif (r->select_current_hart(target) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\n/* Invalidates the register cache. */\nstatic void riscv_invalidate_register_cache(struct target *target)\n{\n\tLOG_DEBUG(\"[%d]\", target->coreid);\n\tregister_cache_invalidate(target->reg_cache);\n\tfor (size_t i = 0; i < target->reg_cache->num_regs; ++i) {\n\t\tstruct reg *reg = &target->reg_cache->reg_list[i];\n\t\treg->valid = false;\n\t}\n}\n\nint riscv_current_hartid(const struct target *target)\n{\n\tRISCV_INFO(r);\n\treturn r->current_hartid;\n}\n\nint riscv_count_harts(struct target *target)\n{\n\tif (!target)\n\t\treturn 1;\n\tRISCV_INFO(r);\n\tif (!r || !r->hart_count)\n\t\treturn 1;\n\treturn r->hart_count(target);\n}\n\n/**\n * If write is true:\n *   return true iff we are guaranteed that the register will contain exactly\n *       the value we just wrote when it's read.\n * If write is false:\n *   return true iff we are guaranteed that the register will read the same\n *       value in the future as the value we just read.\n */\nstatic bool gdb_regno_cacheable(enum gdb_regno regno, bool write)\n{\n\t/* GPRs, FPRs, vector registers are just normal data stores. */\n\tif (regno <= GDB_REGNO_XPR31 ||\n\t\t\t(regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31) ||\n\t\t\t(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31))\n\t\treturn true;\n\n\t/* Most CSRs won't change value on us, but we can't assume it about arbitrary\n\t * CSRs. */\n\tswitch (regno) {\n\t\tcase GDB_REGNO_DPC:\n\t\t\treturn true;\n\n\t\tcase GDB_REGNO_VSTART:\n\t\tcase GDB_REGNO_VXSAT:\n\t\tcase GDB_REGNO_VXRM:\n\t\tcase GDB_REGNO_VLENB:\n\t\tcase GDB_REGNO_VL:\n\t\tcase GDB_REGNO_VTYPE:\n\t\tcase GDB_REGNO_MISA:\n\t\tcase GDB_REGNO_DCSR:\n\t\tcase GDB_REGNO_DSCRATCH0:\n\t\tcase GDB_REGNO_MSTATUS:\n\t\tcase GDB_REGNO_MEPC:\n\t\tcase GDB_REGNO_MCAUSE:\n\t\tcase GDB_REGNO_SATP:\n\t\t\t/*\n\t\t\t * WARL registers might not contain the value we just wrote, but\n\t\t\t * these ones won't spontaneously change their value either. *\n\t\t\t */\n\t\t\treturn !write;\n\n\t\tcase GDB_REGNO_TSELECT:\t/* I think this should be above, but then it doesn't work. */\n\t\tcase GDB_REGNO_TDATA1:\t/* Changes value when tselect is changed. */\n\t\tcase GDB_REGNO_TDATA2:  /* Changse value when tselect is changed. */\n\t\tdefault:\n\t\t\treturn false;\n\t}\n}\n\n/**\n * This function is called when the debug user wants to change the value of a\n * register. The new value may be cached, and may not be written until the hart\n * is resumed. */\nint riscv_set_register(struct target *target, enum gdb_regno regid, riscv_reg_t value)\n{\n\tRISCV_INFO(r);\n\tLOG_DEBUG(\"[%s] %s <- %\" PRIx64, target_name(target), gdb_regno_name(regid), value);\n\tassert(r->set_register);\n\n\tkeep_alive();\n\n\t/* TODO: Hack to deal with gdb that thinks these registers still exist. */\n\tif (regid > GDB_REGNO_XPR15 && regid <= GDB_REGNO_XPR31 && value == 0 &&\n\t\t\triscv_supports_extension(target, 'E'))\n\t\treturn ERROR_OK;\n\n\tstruct reg *reg = &target->reg_cache->reg_list[regid];\n\tbuf_set_u64(reg->value, 0, reg->size, value);\n\n\tint result = r->set_register(target, regid, value);\n\tif (result == ERROR_OK)\n\t\treg->valid = gdb_regno_cacheable(regid, true);\n\telse\n\t\treg->valid = false;\n\tLOG_DEBUG(\"[%s] wrote 0x%\" PRIx64 \" to %s valid=%d\",\n\t\t\t  target_name(target), value, reg->name, reg->valid);\n\treturn result;\n}\n\nint riscv_get_register(struct target *target, riscv_reg_t *value,\n\t\tenum gdb_regno regid)\n{\n\tRISCV_INFO(r);\n\n\tkeep_alive();\n\n\tstruct reg *reg = &target->reg_cache->reg_list[regid];\n\tif (!reg->exist) {\n\t\tLOG_DEBUG(\"[%s] %s does not exist.\",\n\t\t\t\t  target_name(target), gdb_regno_name(regid));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (reg && reg->valid) {\n\t\t*value = buf_get_u64(reg->value, 0, reg->size);\n\t\tLOG_DEBUG(\"[%s] %s: %\" PRIx64 \" (cached)\", target_name(target),\n\t\t\t\t  gdb_regno_name(regid), *value);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* TODO: Hack to deal with gdb that thinks these registers still exist. */\n\tif (regid > GDB_REGNO_XPR15 && regid <= GDB_REGNO_XPR31 &&\n\t\t\triscv_supports_extension(target, 'E')) {\n\t\t*value = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tint result = r->get_register(target, value, regid);\n\n\tif (result == ERROR_OK)\n\t\treg->valid = gdb_regno_cacheable(regid, false);\n\n\tLOG_DEBUG(\"[%s] %s: %\" PRIx64, target_name(target),\n\t\t\tgdb_regno_name(regid), *value);\n\treturn result;\n}\n\nbool riscv_is_halted(struct target *target)\n{\n\tRISCV_INFO(r);\n\tassert(r->is_halted);\n\treturn r->is_halted(target);\n}\n\nstatic enum riscv_halt_reason riscv_halt_reason(struct target *target, int hartid)\n{\n\tRISCV_INFO(r);\n\tif (riscv_set_current_hartid(target, hartid) != ERROR_OK)\n\t\treturn RISCV_HALT_ERROR;\n\tif (!riscv_is_halted(target)) {\n\t\tLOG_ERROR(\"Hart is not halted!\");\n\t\treturn RISCV_HALT_UNKNOWN;\n\t}\n\treturn r->halt_reason(target);\n}\n\nsize_t riscv_debug_buffer_size(struct target *target)\n{\n\tRISCV_INFO(r);\n\treturn r->debug_buffer_size;\n}\n\nint riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn)\n{\n\tRISCV_INFO(r);\n\tr->write_debug_buffer(target, index, insn);\n\treturn ERROR_OK;\n}\n\nriscv_insn_t riscv_read_debug_buffer(struct target *target, int index)\n{\n\tRISCV_INFO(r);\n\treturn r->read_debug_buffer(target, index);\n}\n\nint riscv_execute_debug_buffer(struct target *target)\n{\n\tRISCV_INFO(r);\n\treturn r->execute_debug_buffer(target);\n}\n\nvoid riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d)\n{\n\tRISCV_INFO(r);\n\tr->fill_dmi_write_u64(target, buf, a, d);\n}\n\nvoid riscv_fill_dmi_read_u64(struct target *target, char *buf, int a)\n{\n\tRISCV_INFO(r);\n\tr->fill_dmi_read_u64(target, buf, a);\n}\n\nvoid riscv_fill_dmi_nop_u64(struct target *target, char *buf)\n{\n\tRISCV_INFO(r);\n\tr->fill_dmi_nop_u64(target, buf);\n}\n\nint riscv_dmi_write_u64_bits(struct target *target)\n{\n\tRISCV_INFO(r);\n\treturn r->dmi_write_u64_bits(target);\n}\n\n/**\n * Count triggers, and initialize trigger_count for each hart.\n * trigger_count is initialized even if this function fails to discover\n * something.\n * Disable any hardware triggers that have dmode set. We can't have set them\n * ourselves. Maybe they're left over from some killed debug session.\n * */\nint riscv_enumerate_triggers(struct target *target)\n{\n\tRISCV_INFO(r);\n\n\tif (r->triggers_enumerated)\n\t\treturn ERROR_OK;\n\n\tr->triggers_enumerated = true;\t/* At the very least we tried. */\n\n\triscv_reg_t tselect;\n\tint result = riscv_get_register(target, &tselect, GDB_REGNO_TSELECT);\n\t/* If tselect is not readable, the trigger module is likely not\n\t\t* implemented. There are no triggers to enumerate then and no error\n\t\t* should be thrown. */\n\tif (result != ERROR_OK) {\n\t\tLOG_DEBUG(\"[%s] Cannot access tselect register. \"\n\t\t\t\t\"Assuming that triggers are not implemented.\", target_name(target));\n\t\tr->trigger_count = 0;\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (unsigned int t = 0; t < RISCV_MAX_TRIGGERS; ++t) {\n\t\tr->trigger_count = t;\n\n\t\t/* If we can't write tselect, then this hart does not support triggers. */\n\t\tif (riscv_set_register(target, GDB_REGNO_TSELECT, t) != ERROR_OK)\n\t\t\tbreak;\n\t\tuint64_t tselect_rb;\n\t\tresult = riscv_get_register(target, &tselect_rb, GDB_REGNO_TSELECT);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\t/* Mask off the top bit, which is used as tdrmode in old\n\t\t\t* implementations. */\n\t\ttselect_rb &= ~(1ULL << (riscv_xlen(target) - 1));\n\t\tif (tselect_rb != t)\n\t\t\tbreak;\n\t\tuint64_t tdata1;\n\t\tresult = riscv_get_register(target, &tdata1, GDB_REGNO_TDATA1);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\n\t\tint type = get_field(tdata1, MCONTROL_TYPE(riscv_xlen(target)));\n\t\tif (type == 0)\n\t\t\tbreak;\n\t\tswitch (type) {\n\t\t\tcase 1:\n\t\t\t\t/* On these older cores we don't support software using\n\t\t\t\t\t* triggers. */\n\t\t\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (tdata1 & MCONTROL_DMODE(riscv_xlen(target)))\n\t\t\t\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\tif (tdata1 & MCONTROL_DMODE(riscv_xlen(target)))\n\t\t\t\t\triscv_set_register(target, GDB_REGNO_TDATA1, 0);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\triscv_set_register(target, GDB_REGNO_TSELECT, tselect);\n\n\tLOG_INFO(\"[%s] Found %d triggers\", target_name(target), r->trigger_count);\n\n\treturn ERROR_OK;\n}\n\nconst char *gdb_regno_name(enum gdb_regno regno)\n{\n\tstatic char buf[32];\n\n\tswitch (regno) {\n\t\tcase GDB_REGNO_ZERO:\n\t\t\treturn \"zero\";\n\t\tcase GDB_REGNO_RA:\n\t\t\treturn \"ra\";\n\t\tcase GDB_REGNO_SP:\n\t\t\treturn \"sp\";\n\t\tcase GDB_REGNO_GP:\n\t\t\treturn \"gp\";\n\t\tcase GDB_REGNO_TP:\n\t\t\treturn \"tp\";\n\t\tcase GDB_REGNO_T0:\n\t\t\treturn \"t0\";\n\t\tcase GDB_REGNO_T1:\n\t\t\treturn \"t1\";\n\t\tcase GDB_REGNO_T2:\n\t\t\treturn \"t2\";\n\t\tcase GDB_REGNO_S0:\n\t\t\treturn \"s0\";\n\t\tcase GDB_REGNO_S1:\n\t\t\treturn \"s1\";\n\t\tcase GDB_REGNO_A0:\n\t\t\treturn \"a0\";\n\t\tcase GDB_REGNO_A1:\n\t\t\treturn \"a1\";\n\t\tcase GDB_REGNO_A2:\n\t\t\treturn \"a2\";\n\t\tcase GDB_REGNO_A3:\n\t\t\treturn \"a3\";\n\t\tcase GDB_REGNO_A4:\n\t\t\treturn \"a4\";\n\t\tcase GDB_REGNO_A5:\n\t\t\treturn \"a5\";\n\t\tcase GDB_REGNO_A6:\n\t\t\treturn \"a6\";\n\t\tcase GDB_REGNO_A7:\n\t\t\treturn \"a7\";\n\t\tcase GDB_REGNO_S2:\n\t\t\treturn \"s2\";\n\t\tcase GDB_REGNO_S3:\n\t\t\treturn \"s3\";\n\t\tcase GDB_REGNO_S4:\n\t\t\treturn \"s4\";\n\t\tcase GDB_REGNO_S5:\n\t\t\treturn \"s5\";\n\t\tcase GDB_REGNO_S6:\n\t\t\treturn \"s6\";\n\t\tcase GDB_REGNO_S7:\n\t\t\treturn \"s7\";\n\t\tcase GDB_REGNO_S8:\n\t\t\treturn \"s8\";\n\t\tcase GDB_REGNO_S9:\n\t\t\treturn \"s9\";\n\t\tcase GDB_REGNO_S10:\n\t\t\treturn \"s10\";\n\t\tcase GDB_REGNO_S11:\n\t\t\treturn \"s11\";\n\t\tcase GDB_REGNO_T3:\n\t\t\treturn \"t3\";\n\t\tcase GDB_REGNO_T4:\n\t\t\treturn \"t4\";\n\t\tcase GDB_REGNO_T5:\n\t\t\treturn \"t5\";\n\t\tcase GDB_REGNO_T6:\n\t\t\treturn \"t6\";\n\t\tcase GDB_REGNO_PC:\n\t\t\treturn \"pc\";\n\t\tcase GDB_REGNO_FPR0:\n\t\t\treturn \"fpr0\";\n\t\tcase GDB_REGNO_FPR31:\n\t\t\treturn \"fpr31\";\n\t\tcase GDB_REGNO_CSR0:\n\t\t\treturn \"csr0\";\n\t\tcase GDB_REGNO_TSELECT:\n\t\t\treturn \"tselect\";\n\t\tcase GDB_REGNO_TDATA1:\n\t\t\treturn \"tdata1\";\n\t\tcase GDB_REGNO_TDATA2:\n\t\t\treturn \"tdata2\";\n\t\tcase GDB_REGNO_MISA:\n\t\t\treturn \"misa\";\n\t\tcase GDB_REGNO_DPC:\n\t\t\treturn \"dpc\";\n\t\tcase GDB_REGNO_DCSR:\n\t\t\treturn \"dcsr\";\n\t\tcase GDB_REGNO_DSCRATCH0:\n\t\t\treturn \"dscratch0\";\n\t\tcase GDB_REGNO_MSTATUS:\n\t\t\treturn \"mstatus\";\n\t\tcase GDB_REGNO_MEPC:\n\t\t\treturn \"mepc\";\n\t\tcase GDB_REGNO_MCAUSE:\n\t\t\treturn \"mcause\";\n\t\tcase GDB_REGNO_PRIV:\n\t\t\treturn \"priv\";\n\t\tcase GDB_REGNO_SATP:\n\t\t\treturn \"satp\";\n\t\tcase GDB_REGNO_VTYPE:\n\t\t\treturn \"vtype\";\n\t\tcase GDB_REGNO_VL:\n\t\t\treturn \"vl\";\n\t\tcase GDB_REGNO_V0:\n\t\t\treturn \"v0\";\n\t\tcase GDB_REGNO_V1:\n\t\t\treturn \"v1\";\n\t\tcase GDB_REGNO_V2:\n\t\t\treturn \"v2\";\n\t\tcase GDB_REGNO_V3:\n\t\t\treturn \"v3\";\n\t\tcase GDB_REGNO_V4:\n\t\t\treturn \"v4\";\n\t\tcase GDB_REGNO_V5:\n\t\t\treturn \"v5\";\n\t\tcase GDB_REGNO_V6:\n\t\t\treturn \"v6\";\n\t\tcase GDB_REGNO_V7:\n\t\t\treturn \"v7\";\n\t\tcase GDB_REGNO_V8:\n\t\t\treturn \"v8\";\n\t\tcase GDB_REGNO_V9:\n\t\t\treturn \"v9\";\n\t\tcase GDB_REGNO_V10:\n\t\t\treturn \"v10\";\n\t\tcase GDB_REGNO_V11:\n\t\t\treturn \"v11\";\n\t\tcase GDB_REGNO_V12:\n\t\t\treturn \"v12\";\n\t\tcase GDB_REGNO_V13:\n\t\t\treturn \"v13\";\n\t\tcase GDB_REGNO_V14:\n\t\t\treturn \"v14\";\n\t\tcase GDB_REGNO_V15:\n\t\t\treturn \"v15\";\n\t\tcase GDB_REGNO_V16:\n\t\t\treturn \"v16\";\n\t\tcase GDB_REGNO_V17:\n\t\t\treturn \"v17\";\n\t\tcase GDB_REGNO_V18:\n\t\t\treturn \"v18\";\n\t\tcase GDB_REGNO_V19:\n\t\t\treturn \"v19\";\n\t\tcase GDB_REGNO_V20:\n\t\t\treturn \"v20\";\n\t\tcase GDB_REGNO_V21:\n\t\t\treturn \"v21\";\n\t\tcase GDB_REGNO_V22:\n\t\t\treturn \"v22\";\n\t\tcase GDB_REGNO_V23:\n\t\t\treturn \"v23\";\n\t\tcase GDB_REGNO_V24:\n\t\t\treturn \"v24\";\n\t\tcase GDB_REGNO_V25:\n\t\t\treturn \"v25\";\n\t\tcase GDB_REGNO_V26:\n\t\t\treturn \"v26\";\n\t\tcase GDB_REGNO_V27:\n\t\t\treturn \"v27\";\n\t\tcase GDB_REGNO_V28:\n\t\t\treturn \"v28\";\n\t\tcase GDB_REGNO_V29:\n\t\t\treturn \"v29\";\n\t\tcase GDB_REGNO_V30:\n\t\t\treturn \"v30\";\n\t\tcase GDB_REGNO_V31:\n\t\t\treturn \"v31\";\n\t\tdefault:\n\t\t\tif (regno <= GDB_REGNO_XPR31)\n\t\t\t\tsprintf(buf, \"x%d\", regno - GDB_REGNO_ZERO);\n\t\t\telse if (regno >= GDB_REGNO_CSR0 && regno <= GDB_REGNO_CSR4095)\n\t\t\t\tsprintf(buf, \"csr%d\", regno - GDB_REGNO_CSR0);\n\t\t\telse if (regno >= GDB_REGNO_FPR0 && regno <= GDB_REGNO_FPR31)\n\t\t\t\tsprintf(buf, \"f%d\", regno - GDB_REGNO_FPR0);\n\t\t\telse\n\t\t\t\tsprintf(buf, \"gdb_regno_%d\", regno);\n\t\t\treturn buf;\n\t}\n}\n\nstatic int register_get(struct reg *reg)\n{\n\triscv_reg_info_t *reg_info = reg->arch_info;\n\tstruct target *target = reg_info->target;\n\tRISCV_INFO(r);\n\n\tif (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {\n\t\tif (!r->get_register_buf) {\n\t\t\tLOG_ERROR(\"Reading register %s not supported on this RISC-V target.\",\n\t\t\t\t\tgdb_regno_name(reg->number));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (r->get_register_buf(target, reg->value, reg->number) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tuint64_t value;\n\t\tint result = riscv_get_register(target, &value, reg->number);\n\t\tif (result != ERROR_OK)\n\t\t\treturn result;\n\t\tbuf_set_u64(reg->value, 0, reg->size, value);\n\t}\n\treg->valid = gdb_regno_cacheable(reg->number, false);\n\tchar *str = buf_to_hex_str(reg->value, reg->size);\n\tLOG_DEBUG(\"[%s] read 0x%s from %s (valid=%d)\", target_name(target),\n\t\t\tstr, reg->name, reg->valid);\n\tfree(str);\n\treturn ERROR_OK;\n}\n\nstatic int register_set(struct reg *reg, uint8_t *buf)\n{\n\triscv_reg_info_t *reg_info = reg->arch_info;\n\tstruct target *target = reg_info->target;\n\tRISCV_INFO(r);\n\n\tchar *str = buf_to_hex_str(buf, reg->size);\n\tLOG_DEBUG(\"[%s] write 0x%s to %s (valid=%d)\", target_name(target),\n\t\t\tstr, reg->name, reg->valid);\n\tfree(str);\n\n\t/* Exit early for writing x0, which on the hardware would be ignored, and we\n\t * don't want to update our cache. */\n\tif (reg->number == GDB_REGNO_ZERO)\n\t\treturn ERROR_OK;\n\n\tmemcpy(reg->value, buf, DIV_ROUND_UP(reg->size, 8));\n\treg->valid = gdb_regno_cacheable(reg->number, true);\n\n\tif (reg->number == GDB_REGNO_TDATA1 ||\n\t\t\treg->number == GDB_REGNO_TDATA2) {\n\t\tr->manual_hwbp_set = true;\n\t\t/* When enumerating triggers, we clear any triggers with DMODE set,\n\t\t * assuming they were left over from a previous debug session. So make\n\t\t * sure that is done before a user might be setting their own triggers.\n\t\t */\n\t\tif (riscv_enumerate_triggers(target) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (reg->number >= GDB_REGNO_V0 && reg->number <= GDB_REGNO_V31) {\n\t\tif (!r->set_register_buf) {\n\t\t\tLOG_ERROR(\"Writing register %s not supported on this RISC-V target.\",\n\t\t\t\t\tgdb_regno_name(reg->number));\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (r->set_register_buf(target, reg->number, reg->value) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tuint64_t value = buf_get_u64(buf, 0, reg->size);\n\t\tif (riscv_set_register(target, reg->number, value) != ERROR_OK)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic struct reg_arch_type riscv_reg_arch_type = {\n\t.get = register_get,\n\t.set = register_set\n};\n\nstruct csr_info {\n\tunsigned number;\n\tconst char *name;\n};\n\nstatic int cmp_csr_info(const void *p1, const void *p2)\n{\n\treturn (int) (((struct csr_info *)p1)->number) - (int) (((struct csr_info *)p2)->number);\n}\n\nint riscv_init_registers(struct target *target)\n{\n\tRISCV_INFO(info);\n\n\triscv_free_registers(target);\n\n\ttarget->reg_cache = calloc(1, sizeof(*target->reg_cache));\n\tif (!target->reg_cache)\n\t\treturn ERROR_FAIL;\n\ttarget->reg_cache->name = \"RISC-V Registers\";\n\ttarget->reg_cache->num_regs = GDB_REGNO_COUNT;\n\n\tif (!list_empty(&info->expose_custom)) {\n\t\trange_list_t *entry;\n\t\tlist_for_each_entry(entry, &info->expose_custom, list)\n\t\t\ttarget->reg_cache->num_regs += entry->high - entry->low + 1;\n\t}\n\n\tLOG_DEBUG(\"create register cache for %d registers\",\n\t\t\ttarget->reg_cache->num_regs);\n\n\ttarget->reg_cache->reg_list =\n\t\tcalloc(target->reg_cache->num_regs, sizeof(struct reg));\n\tif (!target->reg_cache->reg_list)\n\t\treturn ERROR_FAIL;\n\n\tconst unsigned int max_reg_name_len = 12;\n\tfree(info->reg_names);\n\tinfo->reg_names =\n\t\tcalloc(target->reg_cache->num_regs, max_reg_name_len);\n\tif (!info->reg_names)\n\t\treturn ERROR_FAIL;\n\tchar *reg_name = info->reg_names;\n\n\tstatic struct reg_feature feature_cpu = {\n\t\t.name = \"org.gnu.gdb.riscv.cpu\"\n\t};\n\tstatic struct reg_feature feature_fpu = {\n\t\t.name = \"org.gnu.gdb.riscv.fpu\"\n\t};\n\tstatic struct reg_feature feature_csr = {\n\t\t.name = \"org.gnu.gdb.riscv.csr\"\n\t};\n\tstatic struct reg_feature feature_vector = {\n\t\t.name = \"org.gnu.gdb.riscv.vector\"\n\t};\n\tstatic struct reg_feature feature_virtual = {\n\t\t.name = \"org.gnu.gdb.riscv.virtual\"\n\t};\n\tstatic struct reg_feature feature_custom = {\n\t\t.name = \"org.gnu.gdb.riscv.custom\"\n\t};\n\n\t/* These types are built into gdb. */\n\tstatic struct reg_data_type type_ieee_single = { .type = REG_TYPE_IEEE_SINGLE, .id = \"ieee_single\" };\n\tstatic struct reg_data_type type_ieee_double = { .type = REG_TYPE_IEEE_DOUBLE, .id = \"ieee_double\" };\n\tstatic struct reg_data_type_union_field single_double_fields[] = {\n\t\t{\"float\", &type_ieee_single, single_double_fields + 1},\n\t\t{\"double\", &type_ieee_double, NULL},\n\t};\n\tstatic struct reg_data_type_union single_double_union = {\n\t\t.fields = single_double_fields\n\t};\n\tstatic struct reg_data_type type_ieee_single_double = {\n\t\t.type = REG_TYPE_ARCH_DEFINED,\n\t\t.id = \"FPU_FD\",\n\t\t.type_class = REG_TYPE_CLASS_UNION,\n\t\t.reg_type_union = &single_double_union\n\t};\n\tstatic struct reg_data_type type_uint8 = { .type = REG_TYPE_UINT8, .id = \"uint8\" };\n\tstatic struct reg_data_type type_uint16 = { .type = REG_TYPE_UINT16, .id = \"uint16\" };\n\tstatic struct reg_data_type type_uint32 = { .type = REG_TYPE_UINT32, .id = \"uint32\" };\n\tstatic struct reg_data_type type_uint64 = { .type = REG_TYPE_UINT64, .id = \"uint64\" };\n\tstatic struct reg_data_type type_uint128 = { .type = REG_TYPE_UINT128, .id = \"uint128\" };\n\n\t/* This is roughly the XML we want:\n\t * <vector id=\"bytes\" type=\"uint8\" count=\"16\"/>\n\t * <vector id=\"shorts\" type=\"uint16\" count=\"8\"/>\n\t * <vector id=\"words\" type=\"uint32\" count=\"4\"/>\n\t * <vector id=\"longs\" type=\"uint64\" count=\"2\"/>\n\t * <vector id=\"quads\" type=\"uint128\" count=\"1\"/>\n\t * <union id=\"riscv_vector_type\">\n\t *   <field name=\"b\" type=\"bytes\"/>\n\t *   <field name=\"s\" type=\"shorts\"/>\n\t *   <field name=\"w\" type=\"words\"/>\n\t *   <field name=\"l\" type=\"longs\"/>\n\t *   <field name=\"q\" type=\"quads\"/>\n\t * </union>\n\t */\n\n\tinfo->vector_uint8.type = &type_uint8;\n\tinfo->vector_uint8.count = info->vlenb;\n\tinfo->type_uint8_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_uint8_vector.id = \"bytes\";\n\tinfo->type_uint8_vector.type_class = REG_TYPE_CLASS_VECTOR;\n\tinfo->type_uint8_vector.reg_type_vector = &info->vector_uint8;\n\n\tinfo->vector_uint16.type = &type_uint16;\n\tinfo->vector_uint16.count = info->vlenb / 2;\n\tinfo->type_uint16_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_uint16_vector.id = \"shorts\";\n\tinfo->type_uint16_vector.type_class = REG_TYPE_CLASS_VECTOR;\n\tinfo->type_uint16_vector.reg_type_vector = &info->vector_uint16;\n\n\tinfo->vector_uint32.type = &type_uint32;\n\tinfo->vector_uint32.count = info->vlenb / 4;\n\tinfo->type_uint32_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_uint32_vector.id = \"words\";\n\tinfo->type_uint32_vector.type_class = REG_TYPE_CLASS_VECTOR;\n\tinfo->type_uint32_vector.reg_type_vector = &info->vector_uint32;\n\n\tinfo->vector_uint64.type = &type_uint64;\n\tinfo->vector_uint64.count = info->vlenb / 8;\n\tinfo->type_uint64_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_uint64_vector.id = \"longs\";\n\tinfo->type_uint64_vector.type_class = REG_TYPE_CLASS_VECTOR;\n\tinfo->type_uint64_vector.reg_type_vector = &info->vector_uint64;\n\n\tinfo->vector_uint128.type = &type_uint128;\n\tinfo->vector_uint128.count = info->vlenb / 16;\n\tinfo->type_uint128_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_uint128_vector.id = \"quads\";\n\tinfo->type_uint128_vector.type_class = REG_TYPE_CLASS_VECTOR;\n\tinfo->type_uint128_vector.reg_type_vector = &info->vector_uint128;\n\n\tinfo->vector_fields[0].name = \"b\";\n\tinfo->vector_fields[0].type = &info->type_uint8_vector;\n\tif (info->vlenb >= 2) {\n\t\tinfo->vector_fields[0].next = info->vector_fields + 1;\n\t\tinfo->vector_fields[1].name = \"s\";\n\t\tinfo->vector_fields[1].type = &info->type_uint16_vector;\n\t} else {\n\t\tinfo->vector_fields[0].next = NULL;\n\t}\n\tif (info->vlenb >= 4) {\n\t\tinfo->vector_fields[1].next = info->vector_fields + 2;\n\t\tinfo->vector_fields[2].name = \"w\";\n\t\tinfo->vector_fields[2].type = &info->type_uint32_vector;\n\t} else {\n\t\tinfo->vector_fields[1].next = NULL;\n\t}\n\tif (info->vlenb >= 8) {\n\t\tinfo->vector_fields[2].next = info->vector_fields + 3;\n\t\tinfo->vector_fields[3].name = \"l\";\n\t\tinfo->vector_fields[3].type = &info->type_uint64_vector;\n\t} else {\n\t\tinfo->vector_fields[2].next = NULL;\n\t}\n\tif (info->vlenb >= 16) {\n\t\tinfo->vector_fields[3].next = info->vector_fields + 4;\n\t\tinfo->vector_fields[4].name = \"q\";\n\t\tinfo->vector_fields[4].type = &info->type_uint128_vector;\n\t} else {\n\t\tinfo->vector_fields[3].next = NULL;\n\t}\n\tinfo->vector_fields[4].next = NULL;\n\n\tinfo->vector_union.fields = info->vector_fields;\n\n\tinfo->type_vector.type = REG_TYPE_ARCH_DEFINED;\n\tinfo->type_vector.id = \"riscv_vector\";\n\tinfo->type_vector.type_class = REG_TYPE_CLASS_UNION;\n\tinfo->type_vector.reg_type_union = &info->vector_union;\n\n\tstruct csr_info csr_info[] = {\n#define DECLARE_CSR(name, number) { number, #name },\n#include \"encoding.h\"\n#undef DECLARE_CSR\n\t};\n\t/* encoding.h does not contain the registers in sorted order. */\n\tqsort(csr_info, ARRAY_SIZE(csr_info), sizeof(*csr_info), cmp_csr_info);\n\tunsigned csr_info_index = 0;\n\n\tint custom_within_range = 0;\n\n\triscv_reg_info_t *shared_reg_info = calloc(1, sizeof(riscv_reg_info_t));\n\tif (!shared_reg_info)\n\t\treturn ERROR_FAIL;\n\tshared_reg_info->target = target;\n\n\t/* When gdb requests register N, gdb_get_register_packet() assumes that this\n\t * is register at index N in reg_list. So if there are certain registers\n\t * that don't exist, we need to leave holes in the list (or renumber, but\n\t * it would be nice not to have yet another set of numbers to translate\n\t * between). */\n\tfor (uint32_t number = 0; number < target->reg_cache->num_regs; number++) {\n\t\tstruct reg *r = &target->reg_cache->reg_list[number];\n\t\tr->dirty = false;\n\t\tr->valid = false;\n\t\tr->exist = true;\n\t\tr->type = &riscv_reg_arch_type;\n\t\tr->arch_info = shared_reg_info;\n\t\tr->number = number;\n\t\tr->size = riscv_xlen(target);\n\t\t/* r->size is set in riscv_invalidate_register_cache, maybe because the\n\t\t * target is in theory allowed to change XLEN on us. But I expect a lot\n\t\t * of other things to break in that case as well. */\n\t\tif (number <= GDB_REGNO_XPR31) {\n\t\t\tr->exist = number <= GDB_REGNO_XPR15 ||\n\t\t\t\t!riscv_supports_extension(target, 'E');\n\t\t\t/* TODO: For now we fake that all GPRs exist because otherwise gdb\n\t\t\t * doesn't work. */\n\t\t\tr->exist = true;\n\t\t\tr->caller_save = true;\n\t\t\tswitch (number) {\n\t\t\t\tcase GDB_REGNO_ZERO:\n\t\t\t\t\tr->name = \"zero\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_RA:\n\t\t\t\t\tr->name = \"ra\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_SP:\n\t\t\t\t\tr->name = \"sp\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_GP:\n\t\t\t\t\tr->name = \"gp\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_TP:\n\t\t\t\t\tr->name = \"tp\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T0:\n\t\t\t\t\tr->name = \"t0\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T1:\n\t\t\t\t\tr->name = \"t1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T2:\n\t\t\t\t\tr->name = \"t2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FP:\n\t\t\t\t\tr->name = \"fp\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S1:\n\t\t\t\t\tr->name = \"s1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A0:\n\t\t\t\t\tr->name = \"a0\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A1:\n\t\t\t\t\tr->name = \"a1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A2:\n\t\t\t\t\tr->name = \"a2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A3:\n\t\t\t\t\tr->name = \"a3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A4:\n\t\t\t\t\tr->name = \"a4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A5:\n\t\t\t\t\tr->name = \"a5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A6:\n\t\t\t\t\tr->name = \"a6\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_A7:\n\t\t\t\t\tr->name = \"a7\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S2:\n\t\t\t\t\tr->name = \"s2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S3:\n\t\t\t\t\tr->name = \"s3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S4:\n\t\t\t\t\tr->name = \"s4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S5:\n\t\t\t\t\tr->name = \"s5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S6:\n\t\t\t\t\tr->name = \"s6\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S7:\n\t\t\t\t\tr->name = \"s7\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S8:\n\t\t\t\t\tr->name = \"s8\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S9:\n\t\t\t\t\tr->name = \"s9\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S10:\n\t\t\t\t\tr->name = \"s10\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_S11:\n\t\t\t\t\tr->name = \"s11\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T3:\n\t\t\t\t\tr->name = \"t3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T4:\n\t\t\t\t\tr->name = \"t4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T5:\n\t\t\t\t\tr->name = \"t5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_T6:\n\t\t\t\t\tr->name = \"t6\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr->group = \"general\";\n\t\t\tr->feature = &feature_cpu;\n\t\t} else if (number == GDB_REGNO_PC) {\n\t\t\tr->caller_save = true;\n\t\t\tsprintf(reg_name, \"pc\");\n\t\t\tr->group = \"general\";\n\t\t\tr->feature = &feature_cpu;\n\t\t} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {\n\t\t\tr->caller_save = true;\n\t\t\tif (riscv_supports_extension(target, 'D')) {\n\t\t\t\tr->size = 64;\n\t\t\t\tif (riscv_supports_extension(target, 'F'))\n\t\t\t\t\tr->reg_data_type = &type_ieee_single_double;\n\t\t\t\telse\n\t\t\t\t\tr->reg_data_type = &type_ieee_double;\n\t\t\t} else if (riscv_supports_extension(target, 'F')) {\n\t\t\t\tr->reg_data_type = &type_ieee_single;\n\t\t\t\tr->size = 32;\n\t\t\t} else {\n\t\t\t\tr->exist = false;\n\t\t\t}\n\t\t\tswitch (number) {\n\t\t\t\tcase GDB_REGNO_FT0:\n\t\t\t\t\tr->name = \"ft0\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT1:\n\t\t\t\t\tr->name = \"ft1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT2:\n\t\t\t\t\tr->name = \"ft2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT3:\n\t\t\t\t\tr->name = \"ft3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT4:\n\t\t\t\t\tr->name = \"ft4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT5:\n\t\t\t\t\tr->name = \"ft5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT6:\n\t\t\t\t\tr->name = \"ft6\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT7:\n\t\t\t\t\tr->name = \"ft7\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS0:\n\t\t\t\t\tr->name = \"fs0\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS1:\n\t\t\t\t\tr->name = \"fs1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA0:\n\t\t\t\t\tr->name = \"fa0\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA1:\n\t\t\t\t\tr->name = \"fa1\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA2:\n\t\t\t\t\tr->name = \"fa2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA3:\n\t\t\t\t\tr->name = \"fa3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA4:\n\t\t\t\t\tr->name = \"fa4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA5:\n\t\t\t\t\tr->name = \"fa5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA6:\n\t\t\t\t\tr->name = \"fa6\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FA7:\n\t\t\t\t\tr->name = \"fa7\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS2:\n\t\t\t\t\tr->name = \"fs2\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS3:\n\t\t\t\t\tr->name = \"fs3\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS4:\n\t\t\t\t\tr->name = \"fs4\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS5:\n\t\t\t\t\tr->name = \"fs5\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS6:\n\t\t\t\t\tr->name = \"fs6\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS7:\n\t\t\t\t\tr->name = \"fs7\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS8:\n\t\t\t\t\tr->name = \"fs8\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS9:\n\t\t\t\t\tr->name = \"fs9\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS10:\n\t\t\t\t\tr->name = \"fs10\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FS11:\n\t\t\t\t\tr->name = \"fs11\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT8:\n\t\t\t\t\tr->name = \"ft8\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT9:\n\t\t\t\t\tr->name = \"ft9\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT10:\n\t\t\t\t\tr->name = \"ft10\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase GDB_REGNO_FT11:\n\t\t\t\t\tr->name = \"ft11\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr->group = \"float\";\n\t\t\tr->feature = &feature_fpu;\n\t\t} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {\n\t\t\tr->group = \"csr\";\n\t\t\tr->feature = &feature_csr;\n\t\t\tunsigned csr_number = number - GDB_REGNO_CSR0;\n\n\t\t\twhile (csr_info[csr_info_index].number < csr_number &&\n\t\t\t\t\tcsr_info_index < ARRAY_SIZE(csr_info) - 1) {\n\t\t\t\tcsr_info_index++;\n\t\t\t}\n\t\t\tif (csr_info[csr_info_index].number == csr_number) {\n\t\t\t\tr->name = csr_info[csr_info_index].name;\n\t\t\t} else {\n\t\t\t\tsprintf(reg_name, \"csr%d\", csr_number);\n\t\t\t\t/* Assume unnamed registers don't exist, unless we have some\n\t\t\t\t * configuration that tells us otherwise. That's important\n\t\t\t\t * because eg. Eclipse crashes if a target has too many\n\t\t\t\t * registers, and apparently has no way of only showing a\n\t\t\t\t * subset of registers in any case. */\n\t\t\t\tr->exist = false;\n\t\t\t}\n\n\t\t\tswitch (csr_number) {\n\t\t\t\tcase CSR_FFLAGS:\n\t\t\t\tcase CSR_FRM:\n\t\t\t\tcase CSR_FCSR:\n\t\t\t\t\tr->exist = riscv_supports_extension(target, 'F');\n\t\t\t\t\tr->group = \"float\";\n\t\t\t\t\tr->feature = &feature_fpu;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CSR_SSTATUS:\n\t\t\t\tcase CSR_STVEC:\n\t\t\t\tcase CSR_SIP:\n\t\t\t\tcase CSR_SIE:\n\t\t\t\tcase CSR_SCOUNTEREN:\n\t\t\t\tcase CSR_SSCRATCH:\n\t\t\t\tcase CSR_SEPC:\n\t\t\t\tcase CSR_SCAUSE:\n\t\t\t\tcase CSR_STVAL:\n\t\t\t\tcase CSR_SATP:\n\t\t\t\t\tr->exist = riscv_supports_extension(target, 'S');\n\t\t\t\t\tbreak;\n\t\t\t\tcase CSR_MEDELEG:\n\t\t\t\tcase CSR_MIDELEG:\n\t\t\t\t\t/* \"In systems with only M-mode, or with both M-mode and\n\t\t\t\t\t * U-mode but without U-mode trap support, the medeleg and\n\t\t\t\t\t * mideleg registers should not exist.\" */\n\t\t\t\t\tr->exist = riscv_supports_extension(target, 'S') ||\n\t\t\t\t\t\triscv_supports_extension(target, 'N');\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CSR_PMPCFG1:\n\t\t\t\tcase CSR_PMPCFG3:\n\t\t\t\tcase CSR_CYCLEH:\n\t\t\t\tcase CSR_TIMEH:\n\t\t\t\tcase CSR_INSTRETH:\n\t\t\t\tcase CSR_HPMCOUNTER3H:\n\t\t\t\tcase CSR_HPMCOUNTER4H:\n\t\t\t\tcase CSR_HPMCOUNTER5H:\n\t\t\t\tcase CSR_HPMCOUNTER6H:\n\t\t\t\tcase CSR_HPMCOUNTER7H:\n\t\t\t\tcase CSR_HPMCOUNTER8H:\n\t\t\t\tcase CSR_HPMCOUNTER9H:\n\t\t\t\tcase CSR_HPMCOUNTER10H:\n\t\t\t\tcase CSR_HPMCOUNTER11H:\n\t\t\t\tcase CSR_HPMCOUNTER12H:\n\t\t\t\tcase CSR_HPMCOUNTER13H:\n\t\t\t\tcase CSR_HPMCOUNTER14H:\n\t\t\t\tcase CSR_HPMCOUNTER15H:\n\t\t\t\tcase CSR_HPMCOUNTER16H:\n\t\t\t\tcase CSR_HPMCOUNTER17H:\n\t\t\t\tcase CSR_HPMCOUNTER18H:\n\t\t\t\tcase CSR_HPMCOUNTER19H:\n\t\t\t\tcase CSR_HPMCOUNTER20H:\n\t\t\t\tcase CSR_HPMCOUNTER21H:\n\t\t\t\tcase CSR_HPMCOUNTER22H:\n\t\t\t\tcase CSR_HPMCOUNTER23H:\n\t\t\t\tcase CSR_HPMCOUNTER24H:\n\t\t\t\tcase CSR_HPMCOUNTER25H:\n\t\t\t\tcase CSR_HPMCOUNTER26H:\n\t\t\t\tcase CSR_HPMCOUNTER27H:\n\t\t\t\tcase CSR_HPMCOUNTER28H:\n\t\t\t\tcase CSR_HPMCOUNTER29H:\n\t\t\t\tcase CSR_HPMCOUNTER30H:\n\t\t\t\tcase CSR_HPMCOUNTER31H:\n\t\t\t\tcase CSR_MCYCLEH:\n\t\t\t\tcase CSR_MINSTRETH:\n\t\t\t\tcase CSR_MHPMCOUNTER3H:\n\t\t\t\tcase CSR_MHPMCOUNTER4H:\n\t\t\t\tcase CSR_MHPMCOUNTER5H:\n\t\t\t\tcase CSR_MHPMCOUNTER6H:\n\t\t\t\tcase CSR_MHPMCOUNTER7H:\n\t\t\t\tcase CSR_MHPMCOUNTER8H:\n\t\t\t\tcase CSR_MHPMCOUNTER9H:\n\t\t\t\tcase CSR_MHPMCOUNTER10H:\n\t\t\t\tcase CSR_MHPMCOUNTER11H:\n\t\t\t\tcase CSR_MHPMCOUNTER12H:\n\t\t\t\tcase CSR_MHPMCOUNTER13H:\n\t\t\t\tcase CSR_MHPMCOUNTER14H:\n\t\t\t\tcase CSR_MHPMCOUNTER15H:\n\t\t\t\tcase CSR_MHPMCOUNTER16H:\n\t\t\t\tcase CSR_MHPMCOUNTER17H:\n\t\t\t\tcase CSR_MHPMCOUNTER18H:\n\t\t\t\tcase CSR_MHPMCOUNTER19H:\n\t\t\t\tcase CSR_MHPMCOUNTER20H:\n\t\t\t\tcase CSR_MHPMCOUNTER21H:\n\t\t\t\tcase CSR_MHPMCOUNTER22H:\n\t\t\t\tcase CSR_MHPMCOUNTER23H:\n\t\t\t\tcase CSR_MHPMCOUNTER24H:\n\t\t\t\tcase CSR_MHPMCOUNTER25H:\n\t\t\t\tcase CSR_MHPMCOUNTER26H:\n\t\t\t\tcase CSR_MHPMCOUNTER27H:\n\t\t\t\tcase CSR_MHPMCOUNTER28H:\n\t\t\t\tcase CSR_MHPMCOUNTER29H:\n\t\t\t\tcase CSR_MHPMCOUNTER30H:\n\t\t\t\tcase CSR_MHPMCOUNTER31H:\n\t\t\t\t\tr->exist = riscv_xlen(target) == 32;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase CSR_VSTART:\n\t\t\t\tcase CSR_VXSAT:\n\t\t\t\tcase CSR_VXRM:\n\t\t\t\tcase CSR_VL:\n\t\t\t\tcase CSR_VTYPE:\n\t\t\t\tcase CSR_VLENB:\n\t\t\t\t\tr->exist = riscv_supports_extension(target, 'V');\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (!r->exist && !list_empty(&info->expose_csr)) {\n\t\t\t\trange_list_t *entry;\n\t\t\t\tlist_for_each_entry(entry, &info->expose_csr, list)\n\t\t\t\t\tif ((entry->low <= csr_number) && (csr_number <= entry->high)) {\n\t\t\t\t\t\tif (entry->name) {\n\t\t\t\t\t\t\t*reg_name = 0;\n\t\t\t\t\t\t\tr->name = entry->name;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tLOG_DEBUG(\"Exposing additional CSR %d (name=%s)\",\n\t\t\t\t\t\t\t\tcsr_number, entry->name ? entry->name : reg_name);\n\n\t\t\t\t\t\tr->exist = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t}\n\n\t\t} else if (number == GDB_REGNO_PRIV) {\n\t\t\tsprintf(reg_name, \"priv\");\n\t\t\tr->group = \"general\";\n\t\t\tr->feature = &feature_virtual;\n\t\t\tr->size = 8;\n\n\t\t} else if (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31) {\n\t\t\tr->caller_save = false;\n\t\t\tr->exist = riscv_supports_extension(target, 'V') && info->vlenb;\n\t\t\tr->size = info->vlenb * 8;\n\t\t\tsprintf(reg_name, \"v%d\", number - GDB_REGNO_V0);\n\t\t\tr->group = \"vector\";\n\t\t\tr->feature = &feature_vector;\n\t\t\tr->reg_data_type = &info->type_vector;\n\n\t\t} else if (number >= GDB_REGNO_COUNT) {\n\t\t\t/* Custom registers. */\n\t\t\tassert(!list_empty(&info->expose_custom));\n\n\t\t\trange_list_t *range = list_first_entry(&info->expose_custom, range_list_t, list);\n\n\t\t\tunsigned custom_number = range->low + custom_within_range;\n\n\t\t\tr->group = \"custom\";\n\t\t\tr->feature = &feature_custom;\n\t\t\tr->arch_info = calloc(1, sizeof(riscv_reg_info_t));\n\t\t\tif (!r->arch_info)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t((riscv_reg_info_t *) r->arch_info)->target = target;\n\t\t\t((riscv_reg_info_t *) r->arch_info)->custom_number = custom_number;\n\t\t\tsprintf(reg_name, \"custom%d\", custom_number);\n\n\t\t\tif (range->name) {\n\t\t\t\t*reg_name = 0;\n\t\t\t\tr->name = range->name;\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"Exposing additional custom register %d (name=%s)\",\n\t\t\t\t\tnumber, range->name ? range->name : reg_name);\n\n\t\t\tcustom_within_range++;\n\t\t\tif (custom_within_range > range->high - range->low) {\n\t\t\t\tcustom_within_range = 0;\n\t\t\t\tlist_rotate_left(&info->expose_custom);\n\t\t\t}\n\t\t}\n\n\t\tif (reg_name[0]) {\n\t\t\tr->name = reg_name;\n\t\t\treg_name += strlen(reg_name) + 1;\n\t\t\tassert(reg_name < info->reg_names + target->reg_cache->num_regs *\n\t\t\t\t\tmax_reg_name_len);\n\t\t}\n\t\tr->value = calloc(1, DIV_ROUND_UP(r->size, 8));\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nvoid riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,\n\t\t\t\t\triscv_bscan_tunneled_scan_context_t *ctxt)\n{\n\tjtag_add_ir_scan(target->tap, &select_user4, TAP_IDLE);\n\n\tmemset(ctxt->tunneled_dr, 0, sizeof(ctxt->tunneled_dr));\n\tif (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER) {\n\t\tctxt->tunneled_dr[3].num_bits = 1;\n\t\tctxt->tunneled_dr[3].out_value = bscan_one;\n\t\tctxt->tunneled_dr[2].num_bits = 7;\n\t\tctxt->tunneled_dr_width = field->num_bits;\n\t\tctxt->tunneled_dr[2].out_value = &ctxt->tunneled_dr_width;\n\t\t/* for BSCAN tunnel, there is a one-TCK skew between shift in and shift out, so\n\t\t   scanning num_bits + 1, and then will right shift the input field after executing the queues */\n\n\t\tctxt->tunneled_dr[1].num_bits = field->num_bits + 1;\n\t\tctxt->tunneled_dr[1].out_value = field->out_value;\n\t\tctxt->tunneled_dr[1].in_value = field->in_value;\n\n\t\tctxt->tunneled_dr[0].num_bits = 3;\n\t\tctxt->tunneled_dr[0].out_value = bscan_zero;\n\t} else {\n\t\t/* BSCAN_TUNNEL_NESTED_TAP */\n\t\tctxt->tunneled_dr[0].num_bits = 1;\n\t\tctxt->tunneled_dr[0].out_value = bscan_one;\n\t\tctxt->tunneled_dr[1].num_bits = 7;\n\t\tctxt->tunneled_dr_width = field->num_bits;\n\t\tctxt->tunneled_dr[1].out_value = &ctxt->tunneled_dr_width;\n\t\t/* for BSCAN tunnel, there is a one-TCK skew between shift in and shift out, so\n\t\t   scanning num_bits + 1, and then will right shift the input field after executing the queues */\n\t\tctxt->tunneled_dr[2].num_bits = field->num_bits + 1;\n\t\tctxt->tunneled_dr[2].out_value = field->out_value;\n\t\tctxt->tunneled_dr[2].in_value = field->in_value;\n\t\tctxt->tunneled_dr[3].num_bits = 3;\n\t\tctxt->tunneled_dr[3].out_value = bscan_zero;\n\t}\n\tjtag_add_dr_scan(target->tap, ARRAY_SIZE(ctxt->tunneled_dr), ctxt->tunneled_dr, TAP_IDLE);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/riscv.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n#ifndef RISCV_H\n#define RISCV_H\n\nstruct riscv_program;\n\n#include <stdint.h>\n#include \"opcodes.h\"\n#include \"gdb_regs.h\"\n#include \"jtag/jtag.h\"\n#include \"target/register.h\"\n#include \"target/semihosting_common.h\"\n#include <helper/command.h>\n\n#define RISCV_COMMON_MAGIC\t0x52495356U\n\n/* The register cache is statically allocated. */\n#define RISCV_MAX_HARTS 1024\n#define RISCV_MAX_REGISTERS 5000\n#define RISCV_MAX_TRIGGERS 32\n#define RISCV_MAX_HWBPS 16\n\n#define DEFAULT_COMMAND_TIMEOUT_SEC\t\t2\n#define DEFAULT_RESET_TIMEOUT_SEC\t\t30\n\n#define RISCV_SATP_MODE(xlen)  ((xlen) == 32 ? SATP32_MODE : SATP64_MODE)\n#define RISCV_SATP_PPN(xlen)  ((xlen) == 32 ? SATP32_PPN : SATP64_PPN)\n#define RISCV_PGSHIFT 12\n\n# define PG_MAX_LEVEL 4\n\n#define RISCV_NUM_MEM_ACCESS_METHODS  3\n\nextern struct target_type riscv011_target;\nextern struct target_type riscv013_target;\n\n/*\n * Definitions shared by code supporting all RISC-V versions.\n */\ntypedef uint64_t riscv_reg_t;\ntypedef uint32_t riscv_insn_t;\ntypedef uint64_t riscv_addr_t;\n\nenum riscv_mem_access_method {\n\tRISCV_MEM_ACCESS_UNSPECIFIED,\n\tRISCV_MEM_ACCESS_PROGBUF,\n\tRISCV_MEM_ACCESS_SYSBUS,\n\tRISCV_MEM_ACCESS_ABSTRACT\n};\n\nenum riscv_halt_reason {\n\tRISCV_HALT_INTERRUPT,\n\tRISCV_HALT_BREAKPOINT,\n\tRISCV_HALT_SINGLESTEP,\n\tRISCV_HALT_TRIGGER,\n\tRISCV_HALT_UNKNOWN,\n\tRISCV_HALT_GROUP,\n\tRISCV_HALT_ERROR\n};\n\ntypedef struct {\n\tstruct target *target;\n\tunsigned custom_number;\n} riscv_reg_info_t;\n\n#define RISCV_SAMPLE_BUF_TIMESTAMP_BEFORE\t0x80\n#define RISCV_SAMPLE_BUF_TIMESTAMP_AFTER\t0x81\nstruct riscv_sample_buf {\n\tuint8_t *buf;\n\tunsigned int used;\n\tunsigned int size;\n};\n\ntypedef struct {\n\tbool enabled;\n\tstruct {\n\t\tbool enabled;\n\t\ttarget_addr_t address;\n\t\tuint32_t size_bytes;\n\t} bucket[16];\n} riscv_sample_config_t;\n\ntypedef struct {\n\tstruct list_head list;\n\tuint16_t low, high;\n\tchar *name;\n} range_list_t;\n\nstruct riscv_info {\n\tunsigned int common_magic;\n\n\tunsigned dtm_version;\n\n\tstruct command_context *cmd_ctx;\n\tvoid *version_specific;\n\n\t/* The hart that is currently being debugged.  Note that this is\n\t * different than the hartid that the RTOS is expected to use.  This\n\t * one will change all the time, it's more of a global argument to\n\t * every function than an actual */\n\tint current_hartid;\n\n\t/* Single buffer that contains all register names, instead of calling\n\t * malloc for each register. Needs to be freed when reg_list is freed. */\n\tchar *reg_names;\n\n\t/* It's possible that each core has a different supported ISA set. */\n\tint xlen;\n\triscv_reg_t misa;\n\t/* Cached value of vlenb. 0 if vlenb is not readable for some reason. */\n\tunsigned int vlenb;\n\n\t/* The number of triggers per hart. */\n\tunsigned int trigger_count;\n\n\t/* For each physical trigger, contains -1 if the hwbp is available, or the\n\t * unique_id of the breakpoint/watchpoint that is using it.\n\t * Note that in RTOS mode the triggers are the same across all harts the\n\t * target controls, while otherwise only a single hart is controlled. */\n\tint trigger_unique_id[RISCV_MAX_HWBPS];\n\n\t/* The number of entries in the debug buffer. */\n\tint debug_buffer_size;\n\n\t/* This hart contains an implicit ebreak at the end of the program buffer. */\n\tbool impebreak;\n\n\tbool triggers_enumerated;\n\n\t/* Decremented every scan, and when it reaches 0 we clear the learned\n\t * delays, causing them to be relearned. Used for testing. */\n\tint reset_delays_wait;\n\n\t/* This target has been prepped and is ready to step/resume. */\n\tbool prepped;\n\t/* This target was selected using hasel. */\n\tbool selected;\n\n\t/* Helper functions that target the various RISC-V debug spec\n\t * implementations. */\n\tint (*get_register)(struct target *target, riscv_reg_t *value, int regid);\n\tint (*set_register)(struct target *target, int regid, uint64_t value);\n\tint (*get_register_buf)(struct target *target, uint8_t *buf, int regno);\n\tint (*set_register_buf)(struct target *target, int regno,\n\t\t\tconst uint8_t *buf);\n\tint (*select_current_hart)(struct target *target);\n\tbool (*is_halted)(struct target *target);\n\t/* Resume this target, as well as every other prepped target that can be\n\t * resumed near-simultaneously. Clear the prepped flag on any target that\n\t * was resumed. */\n\tint (*resume_go)(struct target *target);\n\tint (*step_current_hart)(struct target *target);\n\tint (*on_halt)(struct target *target);\n\t/* Get this target as ready as possible to resume, without actually\n\t * resuming. */\n\tint (*resume_prep)(struct target *target);\n\tint (*halt_prep)(struct target *target);\n\tint (*halt_go)(struct target *target);\n\tint (*on_step)(struct target *target);\n\tenum riscv_halt_reason (*halt_reason)(struct target *target);\n\tint (*write_debug_buffer)(struct target *target, unsigned index,\n\t\t\triscv_insn_t d);\n\triscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);\n\tint (*execute_debug_buffer)(struct target *target);\n\tint (*dmi_write_u64_bits)(struct target *target);\n\tvoid (*fill_dmi_write_u64)(struct target *target, char *buf, int a, uint64_t d);\n\tvoid (*fill_dmi_read_u64)(struct target *target, char *buf, int a);\n\tvoid (*fill_dmi_nop_u64)(struct target *target, char *buf);\n\n\tint (*authdata_read)(struct target *target, uint32_t *value, unsigned int index);\n\tint (*authdata_write)(struct target *target, uint32_t value, unsigned int index);\n\n\tint (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);\n\tint (*dmi_write)(struct target *target, uint32_t address, uint32_t value);\n\n\tint (*sample_memory)(struct target *target,\n\t\t\t\t\t\t struct riscv_sample_buf *buf,\n\t\t\t\t\t\t riscv_sample_config_t *config,\n\t\t\t\t\t\t int64_t until_ms);\n\n\tint (*read_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);\n\n\t/* How many harts are attached to the DM that this target is attached to? */\n\tint (*hart_count)(struct target *target);\n\tunsigned (*data_bits)(struct target *target);\n\n\tCOMMAND_HELPER((*print_info), struct target *target);\n\n\t/* Storage for vector register types. */\n\tstruct reg_data_type_vector vector_uint8;\n\tstruct reg_data_type_vector vector_uint16;\n\tstruct reg_data_type_vector vector_uint32;\n\tstruct reg_data_type_vector vector_uint64;\n\tstruct reg_data_type_vector vector_uint128;\n\tstruct reg_data_type type_uint8_vector;\n\tstruct reg_data_type type_uint16_vector;\n\tstruct reg_data_type type_uint32_vector;\n\tstruct reg_data_type type_uint64_vector;\n\tstruct reg_data_type type_uint128_vector;\n\tstruct reg_data_type_union_field vector_fields[5];\n\tstruct reg_data_type_union vector_union;\n\tstruct reg_data_type type_vector;\n\n\t/* Set when trigger registers are changed by the user. This indicates we eed\n\t * to beware that we may hit a trigger that we didn't realize had been set. */\n\tbool manual_hwbp_set;\n\n\t/* Memory access methods to use, ordered by priority, highest to lowest. */\n\tint mem_access_methods[RISCV_NUM_MEM_ACCESS_METHODS];\n\n\t/* Different memory regions may need different methods but single configuration is applied\n\t * for all. Following flags are used to warn only once about failing memory access method. */\n\tbool mem_access_progbuf_warn;\n\tbool mem_access_sysbus_warn;\n\tbool mem_access_abstract_warn;\n\n\t/* In addition to the ones in the standard spec, we'll also expose additional\n\t * CSRs in this list. */\n\tstruct list_head expose_csr;\n\t/* Same, but for custom registers.\n\t * Custom registers are for non-standard extensions and use abstract register numbers\n\t * from range 0xc000 ... 0xffff. */\n\tstruct list_head expose_custom;\n\n\triscv_sample_config_t sample_config;\n\tstruct riscv_sample_buf sample_buf;\n};\n\nCOMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,\n\t\t\t   unsigned int value);\n\ntypedef struct {\n\tuint8_t tunneled_dr_width;\n\tstruct scan_field tunneled_dr[4];\n} riscv_bscan_tunneled_scan_context_t;\n\ntypedef struct {\n\tconst char *name;\n\tint level;\n\tunsigned va_bits;\n\tunsigned pte_shift;\n\tunsigned vpn_shift[PG_MAX_LEVEL];\n\tunsigned vpn_mask[PG_MAX_LEVEL];\n\tunsigned pte_ppn_shift[PG_MAX_LEVEL];\n\tunsigned pte_ppn_mask[PG_MAX_LEVEL];\n\tunsigned pa_ppn_shift[PG_MAX_LEVEL];\n\tunsigned pa_ppn_mask[PG_MAX_LEVEL];\n} virt2phys_info_t;\n\n/* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/\nextern int riscv_command_timeout_sec;\n\n/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/\nextern int riscv_reset_timeout_sec;\n\nextern bool riscv_enable_virtual;\nextern bool riscv_ebreakm;\nextern bool riscv_ebreaks;\nextern bool riscv_ebreaku;\n\n/* Everything needs the RISC-V specific info structure, so here's a nice macro\n * that provides that. */\nstatic inline struct riscv_info *riscv_info(const struct target *target) __attribute__((unused));\nstatic inline struct riscv_info *riscv_info(const struct target *target)\n{\n\tassert(target->arch_info);\n\treturn target->arch_info;\n}\n#define RISCV_INFO(R) struct riscv_info *R = riscv_info(target);\n\nstatic inline bool is_riscv(const struct riscv_info *riscv_info)\n{\n\treturn riscv_info->common_magic == RISCV_COMMON_MAGIC;\n}\n\nextern struct scan_field select_dtmcontrol;\nextern struct scan_field select_dbus;\nextern struct scan_field select_idcode;\n\nextern struct scan_field *bscan_tunneled_select_dmi;\nextern uint32_t bscan_tunneled_select_dmi_num_fields;\ntypedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;\nextern int bscan_tunnel_ir_width;\n\nuint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out);\nvoid select_dmi_via_bscan(struct target *target);\n\n/*** OpenOCD Interface */\nint riscv_openocd_poll(struct target *target);\n\nint riscv_halt(struct target *target);\n\nint riscv_openocd_step(\n\tstruct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints\n);\n\nint riscv_openocd_assert_reset(struct target *target);\nint riscv_openocd_deassert_reset(struct target *target);\n\n/*** RISC-V Interface ***/\n\nbool riscv_supports_extension(struct target *target, char letter);\n\n/* Returns XLEN for the given (or current) hart. */\nunsigned riscv_xlen(const struct target *target);\nint riscv_xlen_of_hart(const struct target *target);\n\n/* Sets the current hart, which is the hart that will actually be used when\n * issuing debug commands. */\nint riscv_set_current_hartid(struct target *target, int hartid);\nint riscv_select_current_hart(struct target *target);\nint riscv_current_hartid(const struct target *target);\n\n/*** Support functions for the RISC-V 'RTOS', which provides multihart support\n * without requiring multiple targets.  */\n\n/* Lists the number of harts in the system, which are assumed to be\n * consecutive and start with mhartid=0. */\nint riscv_count_harts(struct target *target);\n\n/** Set register, updating the cache. */\nint riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);\n/** Get register, from the cache if it's in there. */\nint riscv_get_register(struct target *target, riscv_reg_t *value,\n\t\tenum gdb_regno r);\n\n/* Checks the state of the current hart -- \"is_halted\" checks the actual\n * on-device register. */\nbool riscv_is_halted(struct target *target);\n\n/* These helper functions let the generic program interface get target-specific\n * information. */\nsize_t riscv_debug_buffer_size(struct target *target);\n\nriscv_insn_t riscv_read_debug_buffer(struct target *target, int index);\nint riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn);\nint riscv_execute_debug_buffer(struct target *target);\n\nvoid riscv_fill_dmi_nop_u64(struct target *target, char *buf);\nvoid riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);\nvoid riscv_fill_dmi_read_u64(struct target *target, char *buf, int a);\nint riscv_dmi_write_u64_bits(struct target *target);\n\nint riscv_enumerate_triggers(struct target *target);\n\nint riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint);\nint riscv_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint);\n\nint riscv_init_registers(struct target *target);\n\nvoid riscv_semihosting_init(struct target *target);\n\nenum semihosting_result riscv_semihosting(struct target *target, int *retval);\n\nvoid riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,\n\t\triscv_bscan_tunneled_scan_context_t *ctxt);\n\nint riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);\nint riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);\n\n#endif\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/riscv/riscv_semihosting.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   ilg@livius.net                                                        *\n *                                                                         *\n *   Copyright (C) 2009 by Marvell Technology Group Ltd.                   *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n *                                                                         *\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n/**\n * @file\n * Hold RISC-V semihosting support.\n *\n * The RISC-V code is inspired from ARM semihosting.\n *\n * Details can be found in chapter 8 of DUI0203I_rvct_developer_guide.pdf\n * from ARM Ltd.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target/target.h\"\n#include \"riscv.h\"\n\nstatic int riscv_semihosting_setup(struct target *target, int enable);\nstatic int riscv_semihosting_post_result(struct target *target);\n\n/**\n * Initialize RISC-V semihosting. Use common ARM code.\n */\nvoid riscv_semihosting_init(struct target *target)\n{\n\tsemihosting_common_init(target, riscv_semihosting_setup,\n\t\triscv_semihosting_post_result);\n}\n\n/**\n * Check for and process a semihosting request using the ARM protocol). This\n * is meant to be called when the target is stopped due to a debug mode entry.\n *\n * @param target Pointer to the target to process.\n * @param retval Pointer to a location where the return code will be stored\n * @return non-zero value if a request was processed or an error encountered\n */\nenum semihosting_result riscv_semihosting(struct target *target, int *retval)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tLOG_DEBUG(\"   -> NONE (!semihosting)\");\n\t\treturn SEMIHOSTING_NONE;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tLOG_DEBUG(\"   -> NONE (!semihosting->is_active)\");\n\t\treturn SEMIHOSTING_NONE;\n\t}\n\n\triscv_reg_t pc;\n\tint result = riscv_get_register(target, &pc, GDB_REGNO_PC);\n\tif (result != ERROR_OK)\n\t\treturn SEMIHOSTING_ERROR;\n\n\tuint8_t tmp_buf[12];\n\n\t/* Read three uncompressed instructions: The previous, the current one (pointed to by PC) and the next one */\n\tfor (int i = 0; i < 3; i++) {\n\t\t/* Instruction memories may not support arbitrary read size. Use any size that will work. */\n\t\t*retval = riscv_read_by_any_size(target, (pc - 4) + 4 * i, 4, tmp_buf + 4 * i);\n\t\tif (*retval != ERROR_OK)\n\t\t\treturn SEMIHOSTING_ERROR;\n\t}\n\n\t/*\n\t * The instructions that trigger a semihosting call,\n\t * always uncompressed, should look like:\n\t *\n\t * 01f01013              slli    zero,zero,0x1f\n\t * 00100073              ebreak\n\t * 40705013              srai    zero,zero,0x7\n\t */\n\tuint32_t pre = target_buffer_get_u32(target, tmp_buf);\n\tuint32_t ebreak = target_buffer_get_u32(target, tmp_buf + 4);\n\tuint32_t post = target_buffer_get_u32(target, tmp_buf + 8);\n\tLOG_DEBUG(\"check %08x %08x %08x from 0x%\" PRIx64 \"-4\", pre, ebreak, post, pc);\n\n\tif (pre != 0x01f01013 || ebreak != 0x00100073 || post != 0x40705013) {\n\t\t/* Not the magic sequence defining semihosting. */\n\t\tLOG_DEBUG(\"   -> NONE (no magic)\");\n\t\treturn SEMIHOSTING_NONE;\n\t}\n\n\t/*\n\t * Perform semihosting call if we are not waiting on a fileio\n\t * operation to complete.\n\t */\n\tif (!semihosting->hit_fileio) {\n\t\t/* RISC-V uses A0 and A1 to pass function arguments */\n\t\triscv_reg_t r0;\n\t\triscv_reg_t r1;\n\n\t\tresult = riscv_get_register(target, &r0, GDB_REGNO_A0);\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"   -> ERROR (couldn't read a0)\");\n\t\t\treturn SEMIHOSTING_ERROR;\n\t\t}\n\n\t\tresult = riscv_get_register(target, &r1, GDB_REGNO_A1);\n\t\tif (result != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"   -> ERROR (couldn't read a1)\");\n\t\t\treturn SEMIHOSTING_ERROR;\n\t\t}\n\n\t\tsemihosting->op = r0;\n\t\tsemihosting->param = r1;\n\t\tsemihosting->word_size_bytes = riscv_xlen(target) / 8;\n\n\t\t/* Check for ARM operation numbers. */\n\t\tif ((semihosting->op >= 0 && semihosting->op <= 0x31) ||\n\t\t\t(semihosting->op >= 0x100 && semihosting->op <= 0x107)) {\n\n\t\t\t*retval = semihosting_common(target);\n\t\t\tif (*retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed semihosting operation (0x%02X)\", semihosting->op);\n\t\t\t\treturn SEMIHOSTING_ERROR;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Unknown operation number, not a semihosting call. */\n\t\t\tLOG_DEBUG(\"   -> NONE (unknown operation number)\");\n\t\t\treturn SEMIHOSTING_NONE;\n\t\t}\n\t}\n\n\t/* Resume right after the EBREAK 4 bytes instruction. */\n\t*retval = riscv_set_register(target, GDB_REGNO_PC, pc + 4);\n\tif (*retval != ERROR_OK)\n\t\treturn SEMIHOSTING_ERROR;\n\n\t/*\n\t * Resume target if we are not waiting on a fileio\n\t * operation to complete.\n\t */\n\tif (semihosting->is_resumable && !semihosting->hit_fileio) {\n\t\tLOG_DEBUG(\"   -> HANDLED\");\n\t\treturn SEMIHOSTING_HANDLED;\n\t}\n\n\tLOG_DEBUG(\"   -> WAITING\");\n\treturn SEMIHOSTING_WAITING;\n}\n\n/* -------------------------------------------------------------------------\n * Local functions. */\n\n/**\n * Called via semihosting->setup() later, after the target is known,\n * usually on the first semihosting command.\n */\nstatic int riscv_semihosting_setup(struct target *target, int enable)\n{\n\tLOG_DEBUG(\"[%s] enable=%d\", target_name(target), enable);\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (semihosting)\n\t\tsemihosting->setup_time = clock();\n\n\treturn ERROR_OK;\n}\n\nstatic int riscv_semihosting_post_result(struct target *target)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\t/* If not enabled, silently ignored. */\n\t\treturn 0;\n\t}\n\n\tLOG_DEBUG(\"0x%\" PRIx64, semihosting->result);\n\triscv_set_register(target, GDB_REGNO_A0, semihosting->result);\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/rtt.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stddef.h>\n#include <stdint.h>\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n#include <helper/command.h>\n#include <rtt/rtt.h>\n#include <target/rtt.h>\n\n#include \"target.h\"\n\nstatic int read_rtt_channel(struct target *target,\n\t\tconst struct rtt_control *ctrl, unsigned int channel_index,\n\t\tenum rtt_channel_type type, struct rtt_channel *channel)\n{\n\tint ret;\n\tuint8_t buf[RTT_CHANNEL_SIZE];\n\ttarget_addr_t address;\n\n\taddress = ctrl->address + RTT_CB_SIZE + (channel_index * RTT_CHANNEL_SIZE);\n\n\tif (type == RTT_CHANNEL_TYPE_DOWN)\n\t\taddress += ctrl->num_up_channels * RTT_CHANNEL_SIZE;\n\n\tret = target_read_buffer(target, address, RTT_CHANNEL_SIZE, buf);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tchannel->address = address;\n\tchannel->name_addr = buf_get_u32(buf + 0, 0, 32);\n\tchannel->buffer_addr = buf_get_u32(buf + 4, 0, 32);\n\tchannel->size = buf_get_u32(buf + 8, 0, 32);\n\tchannel->write_pos = buf_get_u32(buf + 12, 0, 32);\n\tchannel->read_pos = buf_get_u32(buf + 16, 0, 32);\n\tchannel->flags = buf_get_u32(buf + 20, 0, 32);\n\n\treturn ERROR_OK;\n}\n\nint target_rtt_start(struct target *target, const struct rtt_control *ctrl,\n\t\tvoid *user_data)\n{\n\treturn ERROR_OK;\n}\n\nint target_rtt_stop(struct target *target, void *user_data)\n{\n\treturn ERROR_OK;\n}\n\nstatic int read_channel_name(struct target *target, target_addr_t address,\n\t\tchar *name, size_t length)\n{\n\tsize_t offset;\n\n\toffset = 0;\n\n\twhile (offset < length) {\n\t\tint ret;\n\t\tsize_t read_length;\n\n\t\tread_length = MIN(32, length - offset);\n\t\tret = target_read_buffer(target, address + offset, read_length,\n\t\t\t(uint8_t *)name + offset);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tif (memchr(name + offset, '\\0', read_length))\n\t\t\treturn ERROR_OK;\n\n\t\toffset += read_length;\n\t}\n\n\tname[length - 1] = '\\0';\n\n\treturn ERROR_OK;\n}\n\nstatic int write_to_channel(struct target *target,\n\t\tconst struct rtt_channel *channel, const uint8_t *buffer,\n\t\tsize_t *length)\n{\n\tint ret;\n\tuint32_t len;\n\n\tif (!*length)\n\t\treturn ERROR_OK;\n\n\tif (channel->write_pos == channel->read_pos) {\n\t\tuint32_t first_length;\n\n\t\tlen = MIN(*length, channel->size - 1);\n\t\tfirst_length = MIN(len, channel->size - channel->write_pos);\n\n\t\tret = target_write_buffer(target,\n\t\t\tchannel->buffer_addr + channel->write_pos, first_length,\n\t\t\tbuffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_write_buffer(target, channel->buffer_addr,\n\t\t\tlen - first_length, buffer + first_length);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t} else if (channel->write_pos < channel->read_pos) {\n\t\tlen = MIN(*length, channel->read_pos - channel->write_pos - 1);\n\n\t\tif (!len) {\n\t\t\t*length = 0;\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tret = target_write_buffer(target,\n\t\t\tchannel->buffer_addr + channel->write_pos, len, buffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t} else {\n\t\tuint32_t first_length;\n\n\t\tlen = MIN(*length,\n\t\t\tchannel->size - channel->write_pos + channel->read_pos - 1);\n\n\t\tif (!len) {\n\t\t\t*length = 0;\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tfirst_length = MIN(len, channel->size - channel->write_pos);\n\n\t\tret = target_write_buffer(target,\n\t\t\tchannel->buffer_addr + channel->write_pos, first_length,\n\t\t\tbuffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tbuffer = buffer + first_length;\n\n\t\tret = target_write_buffer(target, channel->buffer_addr,\n\t\t\tlen - first_length, buffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tret = target_write_u32(target, channel->address + 12,\n\t\t(channel->write_pos + len) % channel->size);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\t*length = len;\n\n\treturn ERROR_OK;\n}\n\nstatic bool channel_is_active(const struct rtt_channel *channel)\n{\n\tif (!channel)\n\t\treturn false;\n\n\tif (!channel->size)\n\t\treturn false;\n\n\treturn true;\n}\n\nint target_rtt_write_callback(struct target *target, struct rtt_control *ctrl,\n\t\tunsigned int channel_index, const uint8_t *buffer, size_t *length,\n\t\tvoid *user_data)\n{\n\tint ret;\n\tstruct rtt_channel channel;\n\n\tret = read_rtt_channel(target, ctrl, channel_index,\n\t\tRTT_CHANNEL_TYPE_DOWN, &channel);\n\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"rtt: Failed to read down-channel %u description\",\n\t\t\tchannel_index);\n\t\treturn ret;\n\t}\n\n\tif (!channel_is_active(&channel)) {\n\t\tLOG_WARNING(\"rtt: Down-channel %u is not active\", channel_index);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {\n\t\tLOG_WARNING(\"rtt: Down-channel %u is not large enough\",\n\t\t\tchannel_index);\n\t\treturn ERROR_OK;\n\t}\n\n\tret = write_to_channel(target, &channel, buffer, length);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tLOG_DEBUG(\"rtt: Wrote %zu bytes into down-channel %u\", *length,\n\t\tchannel_index);\n\n\treturn ERROR_OK;\n}\n\nint target_rtt_read_control_block(struct target *target,\n\t\ttarget_addr_t address, struct rtt_control *ctrl, void *user_data)\n{\n\tint ret;\n\tuint8_t buf[RTT_CB_SIZE];\n\n\tret = target_read_buffer(target, address, RTT_CB_SIZE, buf);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tmemcpy(ctrl->id, buf, RTT_CB_MAX_ID_LENGTH);\n\tctrl->id[RTT_CB_MAX_ID_LENGTH - 1] = '\\0';\n\tctrl->num_up_channels = buf_get_u32(buf + RTT_CB_MAX_ID_LENGTH + 0,\n\t\t0, 32);\n\tctrl->num_down_channels = buf_get_u32(buf + RTT_CB_MAX_ID_LENGTH + 4,\n\t\t0, 32);\n\n\treturn ERROR_OK;\n}\n\nint target_rtt_find_control_block(struct target *target,\n\t\ttarget_addr_t *address, size_t size, const char *id, bool *found,\n\t\tvoid *user_data)\n{\n\ttarget_addr_t address_end = *address + size;\n\tuint8_t buf[1024];\n\n\t*found = false;\n\n\tsize_t id_matched_length = 0;\n\tconst size_t id_length = strlen(id);\n\n\tLOG_INFO(\"rtt: Searching for control block '%s'\", id);\n\n\tfor (target_addr_t addr = *address; addr < address_end; addr += sizeof(buf)) {\n\t\tint ret;\n\n\t\tconst size_t buf_size = MIN(sizeof(buf), address_end - addr);\n\t\tret = target_read_buffer(target, addr, buf_size, buf);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tfor (size_t buf_off = 0; buf_off < buf_size; buf_off++) {\n\t\t\tif (id_matched_length > 0 &&\n\t\t\t    buf[buf_off] != id[id_matched_length]) {\n\t\t\t\t/* Start from beginning */\n\t\t\t\tid_matched_length = 0;\n\t\t\t}\n\n\t\t\tif (buf[buf_off] == id[id_matched_length])\n\t\t\t\tid_matched_length++;\n\n\t\t\tif (id_matched_length == id_length) {\n\t\t\t\t*address = addr + buf_off + 1 - id_length;\n\t\t\t\t*found = true;\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_rtt_read_channel_info(struct target *target,\n\t\tconst struct rtt_control *ctrl, unsigned int channel_index,\n\t\tenum rtt_channel_type type, struct rtt_channel_info *info,\n\t\tvoid *user_data)\n{\n\tint ret;\n\tstruct rtt_channel channel;\n\n\tret = read_rtt_channel(target, ctrl, channel_index, type, &channel);\n\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"rtt: Failed to read channel %u description\",\n\t\t\tchannel_index);\n\t\treturn ret;\n\t}\n\n\tret = read_channel_name(target, channel.name_addr, info->name,\n\t\tinfo->name_length);\n\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tinfo->size = channel.size;\n\tinfo->flags = channel.flags;\n\n\treturn ERROR_OK;\n}\n\nstatic int read_from_channel(struct target *target,\n\t\tconst struct rtt_channel *channel, uint8_t *buffer,\n\t\tsize_t *length)\n{\n\tint ret;\n\tuint32_t len;\n\n\tif (!*length)\n\t\treturn ERROR_OK;\n\n\tif (channel->read_pos == channel->write_pos) {\n\t\tlen = 0;\n\t} else if (channel->read_pos < channel->write_pos) {\n\t\tlen = MIN(*length, channel->write_pos - channel->read_pos);\n\n\t\tret = target_read_buffer(target,\n\t\t\tchannel->buffer_addr + channel->read_pos, len, buffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t} else {\n\t\tuint32_t first_length;\n\n\t\tlen = MIN(*length,\n\t\t\tchannel->size - channel->read_pos + channel->write_pos);\n\t\tfirst_length = MIN(len, channel->size - channel->read_pos);\n\n\t\tret = target_read_buffer(target,\n\t\t\tchannel->buffer_addr + channel->read_pos, first_length, buffer);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = target_read_buffer(target, channel->buffer_addr,\n\t\t\tlen - first_length, buffer + first_length);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\tif (len > 0) {\n\t\tret = target_write_u32(target, channel->address + 16,\n\t\t\t(channel->read_pos + len) % channel->size);\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\t}\n\n\t*length = len;\n\n\treturn ERROR_OK;\n}\n\nint target_rtt_read_callback(struct target *target,\n\t\tconst struct rtt_control *ctrl, struct rtt_sink_list **sinks,\n\t\tsize_t num_channels, void *user_data)\n{\n\tnum_channels = MIN(num_channels, ctrl->num_up_channels);\n\n\tfor (size_t i = 0; i < num_channels; i++) {\n\t\tint ret;\n\t\tstruct rtt_channel channel;\n\t\tuint8_t buffer[1024];\n\t\tsize_t length;\n\n\t\tif (!sinks[i])\n\t\t\tcontinue;\n\n\t\tret = read_rtt_channel(target, ctrl, i, RTT_CHANNEL_TYPE_UP,\n\t\t\t&channel);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"rtt: Failed to read up-channel %zu description\", i);\n\t\t\treturn ret;\n\t\t}\n\n\t\tif (!channel_is_active(&channel)) {\n\t\t\tLOG_WARNING(\"rtt: Up-channel %zu is not active\", i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (channel.size < RTT_CHANNEL_BUFFER_MIN_SIZE) {\n\t\t\tLOG_WARNING(\"rtt: Up-channel %zu is not large enough\", i);\n\t\t\tcontinue;\n\t\t}\n\n\t\tlength = sizeof(buffer);\n\t\tret = read_from_channel(target, &channel, buffer, &length);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"rtt: Failed to read from up-channel %zu\", i);\n\t\t\treturn ret;\n\t\t}\n\n\t\tfor (struct rtt_sink_list *sink = sinks[i]; sink; sink = sink->next)\n\t\t\tsink->read(i, buffer, length, sink->user_data);\n\t}\n\n\treturn ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/rtt.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (C) 2016-2020 by Marc Schink <dev@zapb.de>\n */\n\n#ifndef OPENOCD_TARGET_RTT_H\n#define OPENOCD_TARGET_RTT_H\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#include <target/target.h>\n#include <rtt/rtt.h>\n\nint target_rtt_start(struct target *target, const struct rtt_control *ctrl,\n\t\tvoid *user_data);\nint target_rtt_stop(struct target *target, void *user_data);\nint target_rtt_find_control_block(struct target *target,\n\t\ttarget_addr_t *address, size_t size, const char *id, bool *found,\n\t\tvoid *user_data);\nint target_rtt_read_control_block(struct target *target,\n\t\ttarget_addr_t address, struct rtt_control *ctrl, void *user_data);\nint target_rtt_write_callback(struct target *target,\n\t\tstruct rtt_control *ctrl, unsigned int channel_index,\n\t\tconst uint8_t *buffer, size_t *length, void *user_data);\nint target_rtt_read_callback(struct target *target,\n\t\tconst struct rtt_control *ctrl, struct rtt_sink_list **sinks,\n\t\tsize_t length, void *user_data);\nint target_rtt_read_channel_info(struct target *target,\n\t\tconst struct rtt_control *ctrl, unsigned int channel_index,\n\t\tenum rtt_channel_type type, struct rtt_channel_info *info,\n\t\tvoid *user_data);\n\n#endif /* OPENOCD_TARGET_RTT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/semihosting_common.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n *                                                                         *\n *   Copyright (C) 2018 by Marvell Technology Group Ltd.                   *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n *                                                                         *\n *   Copyright (C) 2010 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2016 by Square, Inc.                                    *\n *   Steven Stallion <stallion@squareup.com>                               *\n ***************************************************************************/\n\n/**\n * @file\n * Common ARM semihosting support.\n *\n * Semihosting enables code running on a target to use some of the I/O\n * facilities on the host computer. The target application must be linked\n * against a library that forwards operation requests by using  an\n * instruction trapped by the debugger.\n *\n * Details can be found in\n * \"Semihosting for AArch32 and AArch64, Release 2.0\"\n * https://static.docs.arm.com/100863/0200/semihosting.pdf\n * from ARM Ltd.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"semihosting_common.h\"\n\n#include <helper/binarybuffer.h>\n#include <helper/log.h>\n#include <server/gdb_server.h>\n#include <sys/stat.h>\n\n/**\n * It is not possible to use O_... flags defined in sys/stat.h because they\n * are not guaranteed to match the values defined by the GDB Remote Protocol.\n * See https://sourceware.org/gdb/onlinedocs/gdb/Open-Flags.html#Open-Flags\n */\nenum {\n\tTARGET_O_RDONLY = 0x000,\n\tTARGET_O_WRONLY = 0x001,\n\tTARGET_O_RDWR   = 0x002,\n\tTARGET_O_APPEND = 0x008,\n\tTARGET_O_CREAT  = 0x200,\n\tTARGET_O_TRUNC  = 0x400,\n\t/* O_EXCL=0x800 is not required in this implementation. */\n};\n\n/* GDB remote protocol does not differentiate between text and binary open modes. */\nstatic const int open_gdb_modeflags[12] = {\n\tTARGET_O_RDONLY,\n\tTARGET_O_RDONLY,\n\tTARGET_O_RDWR,\n\tTARGET_O_RDWR,\n\tTARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,\n\tTARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_TRUNC,\n\tTARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_TRUNC,\n\tTARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_TRUNC,\n\tTARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,\n\tTARGET_O_WRONLY | TARGET_O_CREAT | TARGET_O_APPEND,\n\tTARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_APPEND,\n\tTARGET_O_RDWR   | TARGET_O_CREAT | TARGET_O_APPEND\n};\n\nstatic const int open_host_modeflags[12] = {\n\tO_RDONLY,\n\tO_RDONLY | O_BINARY,\n\tO_RDWR,\n\tO_RDWR   | O_BINARY,\n\tO_WRONLY | O_CREAT | O_TRUNC,\n\tO_WRONLY | O_CREAT | O_TRUNC  | O_BINARY,\n\tO_RDWR   | O_CREAT | O_TRUNC,\n\tO_RDWR   | O_CREAT | O_TRUNC  | O_BINARY,\n\tO_WRONLY | O_CREAT | O_APPEND,\n\tO_WRONLY | O_CREAT | O_APPEND | O_BINARY,\n\tO_RDWR   | O_CREAT | O_APPEND,\n\tO_RDWR   | O_CREAT | O_APPEND | O_BINARY\n};\n\nstatic int semihosting_common_fileio_info(struct target *target,\n\tstruct gdb_fileio_info *fileio_info);\nstatic int semihosting_common_fileio_end(struct target *target, int result,\n\tint fileio_errno, bool ctrl_c);\n\n/**\n * Initialize common semihosting support.\n *\n * @param target Pointer to the target to initialize.\n * @param setup\n * @param post_result\n * @return An error status if there is a problem during initialization.\n */\nint semihosting_common_init(struct target *target, void *setup,\n\tvoid *post_result)\n{\n\tLOG_DEBUG(\" \");\n\n\ttarget->fileio_info = malloc(sizeof(*target->fileio_info));\n\tif (!target->fileio_info) {\n\t\tLOG_ERROR(\"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tmemset(target->fileio_info, 0, sizeof(*target->fileio_info));\n\n\tstruct semihosting *semihosting;\n\tsemihosting = malloc(sizeof(*target->semihosting));\n\tif (!semihosting) {\n\t\tLOG_ERROR(\"out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tsemihosting->is_active = false;\n\tsemihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;\n\tsemihosting->tcp_connection = NULL;\n\tsemihosting->stdin_fd = -1;\n\tsemihosting->stdout_fd = -1;\n\tsemihosting->stderr_fd = -1;\n\tsemihosting->is_fileio = false;\n\tsemihosting->hit_fileio = false;\n\tsemihosting->is_resumable = false;\n\tsemihosting->has_resumable_exit = false;\n\tsemihosting->word_size_bytes = 0;\n\tsemihosting->op = -1;\n\tsemihosting->param = 0;\n\tsemihosting->result = -1;\n\tsemihosting->sys_errno = -1;\n\tsemihosting->cmdline = NULL;\n\tsemihosting->basedir = NULL;\n\n\t/* If possible, update it in setup(). */\n\tsemihosting->setup_time = clock();\n\n\tsemihosting->setup = setup;\n\tsemihosting->post_result = post_result;\n\tsemihosting->user_command_extension = NULL;\n\n\ttarget->semihosting = semihosting;\n\n\ttarget->type->get_gdb_fileio_info = semihosting_common_fileio_info;\n\ttarget->type->gdb_fileio_end = semihosting_common_fileio_end;\n\n\treturn ERROR_OK;\n}\n\nstruct semihosting_tcp_service {\n\tstruct semihosting *semihosting;\n\tchar *name;\n\tint error;\n};\n\nstatic bool semihosting_is_redirected(struct semihosting *semihosting, int fd)\n{\n\tif (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_NONE)\n\t\treturn false;\n\n\tbool is_read_op = false;\n\n\tswitch (semihosting->op) {\n\t/* check debug semihosting operations: READC, WRITEC and WRITE0 */\n\tcase SEMIHOSTING_SYS_READC:\n\t\tis_read_op = true;\n\t\t/* fall through */\n\tcase SEMIHOSTING_SYS_WRITEC:\n\tcase SEMIHOSTING_SYS_WRITE0:\n\t\t/* debug operations are redirected when CFG is either DEBUG or ALL */\n\t\tif (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_STDIO)\n\t\t\treturn false;\n\t\tbreak;\n\n\t/* check stdio semihosting operations: READ and WRITE */\n\tcase SEMIHOSTING_SYS_READ:\n\t\tis_read_op = true;\n\t\t/* fall through */\n\tcase SEMIHOSTING_SYS_WRITE:\n\t\t/* stdio operations are redirected when CFG is either STDIO or ALL */\n\t\tif (semihosting->redirect_cfg == SEMIHOSTING_REDIRECT_CFG_DEBUG)\n\t\t\treturn false;\n\t\tbreak;\n\n\tdefault:\n\t\treturn false;\n\t}\n\n\tif (is_read_op)\n\t\treturn fd == semihosting->stdin_fd;\n\n\t/* write operation */\n\treturn fd == semihosting->stdout_fd || fd == semihosting->stderr_fd;\n}\n\nstatic ssize_t semihosting_redirect_write(struct semihosting *semihosting, void *buf, int size)\n{\n\tif (!semihosting->tcp_connection) {\n\t\tLOG_ERROR(\"No connected TCP client for semihosting\");\n\t\tsemihosting->sys_errno = EBADF; /* Bad file number */\n\t\treturn -1;\n\t}\n\n\tstruct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;\n\n\tint retval = connection_write(semihosting->tcp_connection, buf, size);\n\n\tif (retval < 0)\n\t\tlog_socket_error(service->name);\n\n\treturn retval;\n}\n\nstatic ssize_t semihosting_write(struct semihosting *semihosting, int fd, void *buf, int size)\n{\n\tif (semihosting_is_redirected(semihosting, fd))\n\t\treturn semihosting_redirect_write(semihosting, buf, size);\n\n\t/* default write */\n\tint result = write(fd, buf, size);\n\tif (result == -1)\n\t\tsemihosting->sys_errno = errno;\n\treturn result;\n}\n\nstatic ssize_t semihosting_redirect_read(struct semihosting *semihosting, void *buf, int size)\n{\n\tif (!semihosting->tcp_connection) {\n\t\tLOG_ERROR(\"No connected TCP client for semihosting\");\n\t\tsemihosting->sys_errno = EBADF; /* Bad file number */\n\t\treturn -1;\n\t}\n\n\tstruct semihosting_tcp_service *service = semihosting->tcp_connection->service->priv;\n\n\tservice->error = ERROR_OK;\n\tsemihosting->tcp_connection->input_pending = true;\n\n\tint retval = connection_read(semihosting->tcp_connection, buf, size);\n\n\tif (retval <= 0)\n\t\tservice->error = ERROR_SERVER_REMOTE_CLOSED;\n\n\tif (retval < 0)\n\t\tlog_socket_error(service->name);\n\n\tsemihosting->tcp_connection->input_pending = false;\n\n\treturn retval;\n}\n\nstatic inline int semihosting_putchar(struct semihosting *semihosting, int fd, int c)\n{\n\tif (semihosting_is_redirected(semihosting, fd))\n\t\treturn semihosting_redirect_write(semihosting, &c, 1);\n\n\t/* default putchar */\n\treturn putchar(c);\n}\n\nstatic inline ssize_t semihosting_read(struct semihosting *semihosting, int fd, void *buf, int size)\n{\n\tif (semihosting_is_redirected(semihosting, fd))\n\t\treturn semihosting_redirect_read(semihosting, buf, size);\n\n\t/* default read */\n\tssize_t result = read(fd, buf, size);\n\tif (result == -1)\n\t\tsemihosting->sys_errno = errno;\n\n\treturn result;\n}\n\nstatic inline int semihosting_getchar(struct semihosting *semihosting, int fd)\n{\n\tif (semihosting_is_redirected(semihosting, fd)) {\n\t\tunsigned char c;\n\n\t\tif (semihosting_redirect_read(semihosting, &c, 1) > 0)\n\t\t\treturn c;\n\n\t\treturn EOF;\n\t}\n\n\t/* default getchar */\n\treturn getchar();\n}\n\n/**\n * User operation parameter string storage buffer. Contains valid data when the\n * TARGET_EVENT_SEMIHOSTING_USER_CMD_xxxxx event callbacks are running.\n */\nstatic char *semihosting_user_op_params;\n\nconst char *semihosting_opcode_to_str(const uint64_t opcode)\n{\n\tswitch (opcode) {\n\t\tcase SEMIHOSTING_SYS_CLOSE:\n\t\t\treturn \"CLOSE\";\n\t\tcase SEMIHOSTING_SYS_CLOCK:\n\t\t\treturn \"CLOCK\";\n\t\tcase SEMIHOSTING_SYS_ELAPSED:\n\t\t\treturn \"ELAPSED\";\n\t\tcase SEMIHOSTING_SYS_ERRNO:\n\t\t\treturn \"ERRNO\";\n\t\tcase SEMIHOSTING_SYS_EXIT:\n\t\t\treturn \"EXIT\";\n\t\tcase SEMIHOSTING_SYS_EXIT_EXTENDED:\n\t\t\treturn \"EXIT_EXTENDED\";\n\t\tcase SEMIHOSTING_SYS_FLEN:\n\t\t\treturn \"FLEN\";\n\t\tcase SEMIHOSTING_SYS_GET_CMDLINE:\n\t\t\treturn \"GET_CMDLINE\";\n\t\tcase SEMIHOSTING_SYS_HEAPINFO:\n\t\t\treturn \"HEAPINFO\";\n\t\tcase SEMIHOSTING_SYS_ISERROR:\n\t\t\treturn \"ISERROR\";\n\t\tcase SEMIHOSTING_SYS_ISTTY:\n\t\t\treturn \"ISTTY\";\n\t\tcase SEMIHOSTING_SYS_OPEN:\n\t\t\treturn \"OPEN\";\n\t\tcase SEMIHOSTING_SYS_READ:\n\t\t\treturn \"READ\";\n\t\tcase SEMIHOSTING_SYS_READC:\n\t\t\treturn \"READC\";\n\t\tcase SEMIHOSTING_SYS_REMOVE:\n\t\t\treturn \"REMOVE\";\n\t\tcase SEMIHOSTING_SYS_RENAME:\n\t\t\treturn \"RENAME\";\n\t\tcase SEMIHOSTING_SYS_SEEK:\n\t\t\treturn \"SEEK\";\n\t\tcase SEMIHOSTING_SYS_SYSTEM:\n\t\t\treturn \"SYSTEM\";\n\t\tcase SEMIHOSTING_SYS_TICKFREQ:\n\t\t\treturn \"TICKFREQ\";\n\t\tcase SEMIHOSTING_SYS_TIME:\n\t\t\treturn \"TIME\";\n\t\tcase SEMIHOSTING_SYS_TMPNAM:\n\t\t\treturn \"TMPNAM\";\n\t\tcase SEMIHOSTING_SYS_WRITE:\n\t\t\treturn \"WRITE\";\n\t\tcase SEMIHOSTING_SYS_WRITEC:\n\t\t\treturn \"WRITEC\";\n\t\tcase SEMIHOSTING_SYS_WRITE0:\n\t\t\treturn \"WRITE0\";\n\t\tcase SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X1FF:\n\t\t\treturn \"USER_CMD\";\n\t\tcase SEMIHOSTING_ARM_RESERVED_START ... SEMIHOSTING_ARM_RESERVED_END:\n\t\t\treturn \"ARM_RESERVED_CMD\";\n\t\tdefault:\n\t\t\treturn \"<unknown>\";\n\t}\n}\n\n/**\n * Portable implementation of ARM semihosting calls.\n * Performs the currently pending semihosting operation\n * encoded in target->semihosting.\n */\nint semihosting_common(struct target *target)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\t/* Silently ignore if the semihosting field was not set. */\n\t\treturn ERROR_OK;\n\t}\n\n\tstruct gdb_fileio_info *fileio_info = target->fileio_info;\n\n\t/*\n\t * By default return an error.\n\t * The actual result must be set by each function\n\t */\n\tsemihosting->result = -1;\n\n\t/* Most operations are resumable, except the two exit calls. */\n\tsemihosting->is_resumable = true;\n\n\tint retval;\n\n\t/* Enough space to hold 4 long words. */\n\tuint8_t fields[4*8];\n\n\tLOG_DEBUG(\"op=0x%x (%s), param=0x%\" PRIx64, semihosting->op,\n\t\t\t  semihosting_opcode_to_str(semihosting->op),\n\t\t\t  semihosting->param);\n\n\tswitch (semihosting->op) {\n\n\t\tcase SEMIHOSTING_SYS_CLOCK:\t/* 0x10 */\n\t\t\t/*\n\t\t\t * Returns the number of centiseconds (hundredths of a second)\n\t\t\t * since the execution started.\n\t\t\t *\n\t\t\t * Values returned can be of limited use for some benchmarking\n\t\t\t * purposes because of communication overhead or other\n\t\t\t * agent-specific factors. For example, with a debug hardware\n\t\t\t * unit the request is passed back to the host for execution.\n\t\t\t * This can lead to unpredictable delays in transmission and\n\t\t\t * process scheduling.\n\t\t\t *\n\t\t\t * Use this function to calculate time intervals, by calculating\n\t\t\t * differences between intervals with and without the code\n\t\t\t * sequence to be timed.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * The PARAMETER REGISTER must contain 0. There are no other\n\t\t\t * parameters.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - The number of centiseconds since some arbitrary start\n\t\t\t * point, if the call is successful.\n\t\t\t * - –1 if the call is not successful. For example, because\n\t\t\t * of a communications error.\n\t\t\t */\n\t\t{\n\t\t\tclock_t delta = clock() - semihosting->setup_time;\n\n\t\t\tsemihosting->result = delta / (CLOCKS_PER_SEC / 100);\n\t\t}\n\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_CLOSE:\t/* 0x02 */\n\t\t\t/*\n\t\t\t * Closes a file on the host system. The handle must reference\n\t\t\t * a file that was opened with SYS_OPEN.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * one-field argument block:\n\t\t\t * - field 1 Contains a handle for an open file.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the call is successful\n\t\t\t * - –1 if the call is not successful.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 1, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\t/* Do not allow to close OpenOCD's own standard streams */\n\t\t\t\tif (fd == 0 || fd == 1 || fd == 2) {\n\t\t\t\t\tLOG_DEBUG(\"ignoring semihosting attempt to close %s\",\n\t\t\t\t\t\t\t(fd == 0) ? \"stdin\" :\n\t\t\t\t\t\t\t(fd == 1) ? \"stdout\" : \"stderr\");\n\t\t\t\t\t/* Just pretend success */\n\t\t\t\t\tsemihosting->result = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t/* Close the descriptor */\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"close\";\n\t\t\t\t\tfileio_info->param_1 = fd;\n\t\t\t\t} else {\n\t\t\t\t\tsemihosting->result = close(fd);\n\t\t\t\t\tif (semihosting->result == -1)\n\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\tLOG_DEBUG(\"close(%d)=%\" PRId64, fd, semihosting->result);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_ERRNO:\t/* 0x13 */\n\t\t\t/*\n\t\t\t * Returns the value of the C library errno variable that is\n\t\t\t * associated with the semihosting implementation. The errno\n\t\t\t * variable can be set by a number of C library semihosted\n\t\t\t * functions, including:\n\t\t\t * - SYS_REMOVE\n\t\t\t * - SYS_OPEN\n\t\t\t * - SYS_CLOSE\n\t\t\t * - SYS_READ\n\t\t\t * - SYS_WRITE\n\t\t\t * - SYS_SEEK.\n\t\t\t *\n\t\t\t * Whether errno is set or not, and to what value, is entirely\n\t\t\t * host-specific, except where the ISO C standard defines the\n\t\t\t * behavior.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * There are no parameters. The PARAMETER REGISTER must be 0.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the value of the C\n\t\t\t * library errno variable.\n\t\t\t */\n\t\t\tsemihosting->result = semihosting->sys_errno;\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_EXIT:\t/* 0x18 */\n\t\t\t/*\n\t\t\t * Note: SYS_EXIT was called angel_SWIreason_ReportException in\n\t\t\t * previous versions of the documentation.\n\t\t\t *\n\t\t\t * An application calls this operation to report an exception\n\t\t\t * to the debugger directly. The most common use is to report\n\t\t\t * that execution has completed, using ADP_Stopped_ApplicationExit.\n\t\t\t *\n\t\t\t * Note: This semihosting operation provides no means for 32-bit\n\t\t\t * callers to indicate an application exit with a specified exit\n\t\t\t * code. Semihosting callers may prefer to check for the presence\n\t\t\t * of the SH_EXT_EXTENDED_REPORT_EXCEPTION extension and use\n\t\t\t * the SYS_REPORT_EXCEPTION_EXTENDED operation instead, if it\n\t\t\t * is available.\n\t\t\t *\n\t\t\t * Entry (32-bit)\n\t\t\t * On entry, the PARAMETER register is set to a reason code\n\t\t\t * describing the cause of the trap. Not all semihosting client\n\t\t\t * implementations will necessarily trap every corresponding\n\t\t\t * event. Important reason codes are:\n\t\t\t *\n\t\t\t * - ADP_Stopped_ApplicationExit 0x20026\n\t\t\t * - ADP_Stopped_RunTimeErrorUnknown 0x20023\n\t\t\t *\n\t\t\t * Entry (64-bit)\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field argument block:\n\t\t\t * - field 1 The exception type, which is one of the set of\n\t\t\t * reason codes in the above tables.\n\t\t\t * - field 2 A subcode, whose meaning depends on the reason\n\t\t\t * code in field 1.\n\t\t\t * In particular, if field 1 is ADP_Stopped_ApplicationExit\n\t\t\t * then field 2 is an exit status code, as passed to the C\n\t\t\t * standard library exit() function. A simulator receiving\n\t\t\t * this request must notify a connected debugger, if present,\n\t\t\t * and then exit with the specified status.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * No return is expected from these calls. However, it is\n\t\t\t * possible for the debugger to request that the application\n\t\t\t * continues by performing an RDI_Execute request or equivalent.\n\t\t\t * In this case, execution continues with the registers as they\n\t\t\t * were on entry to the operation, or as subsequently modified\n\t\t\t * by the debugger.\n\t\t\t */\n\t\t\tif (semihosting->word_size_bytes == 8) {\n\t\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\telse {\n\t\t\t\t\tint type = semihosting_get_field(target, 0, fields);\n\t\t\t\t\tint code = semihosting_get_field(target, 1, fields);\n\n\t\t\t\t\tif (type == ADP_STOPPED_APPLICATION_EXIT) {\n\t\t\t\t\t\tif (!gdb_get_actual_connections())\n\t\t\t\t\t\t\texit(code);\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\t\"semihosting: *** application exited with %d ***\\n\",\n\t\t\t\t\t\t\t\tcode);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\"semihosting: application exception %#x\\n\",\n\t\t\t\t\t\t\ttype);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (semihosting->param == ADP_STOPPED_APPLICATION_EXIT) {\n\t\t\t\t\tif (!gdb_get_actual_connections())\n\t\t\t\t\t\texit(0);\n\t\t\t\t\telse {\n\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\"semihosting: *** application exited normally ***\\n\");\n\t\t\t\t\t}\n\t\t\t\t} else if (semihosting->param == ADP_STOPPED_RUN_TIME_ERROR) {\n\t\t\t\t\t/* Chosen more or less arbitrarily to have a nicer message,\n\t\t\t\t\t * otherwise all other return the same exit code 1. */\n\t\t\t\t\tif (!gdb_get_actual_connections())\n\t\t\t\t\t\texit(1);\n\t\t\t\t\telse {\n\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\"semihosting: *** application exited with error ***\\n\");\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (!gdb_get_actual_connections())\n\t\t\t\t\t\texit(1);\n\t\t\t\t\telse {\n\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\"semihosting: application exception %#x\\n\",\n\t\t\t\t\t\t\t(unsigned) semihosting->param);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!semihosting->has_resumable_exit) {\n\t\t\t\tsemihosting->is_resumable = false;\n\t\t\t\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_EXIT_EXTENDED:\t/* 0x20 */\n\t\t\t/*\n\t\t\t * This operation is only supported if the semihosting extension\n\t\t\t * SH_EXT_EXIT_EXTENDED is implemented. SH_EXT_EXIT_EXTENDED is\n\t\t\t * reported using feature byte 0, bit 0. If this extension is\n\t\t\t * supported, then the implementation provides a means to\n\t\t\t * report a normal exit with a nonzero exit status in both 32-bit\n\t\t\t * and 64-bit semihosting APIs.\n\t\t\t *\n\t\t\t * The implementation must provide the semihosting call\n\t\t\t * SYS_EXIT_EXTENDED for both A64 and A32/T32 semihosting APIs.\n\t\t\t *\n\t\t\t * SYS_EXIT_EXTENDED is used by an application to report an\n\t\t\t * exception or exit to the debugger directly. The most common\n\t\t\t * use is to report that execution has completed, using\n\t\t\t * ADP_Stopped_ApplicationExit.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field argument block:\n\t\t\t * - field 1 The exception type, which should be one of the set\n\t\t\t * of reason codes that are documented for the SYS_EXIT\n\t\t\t * (0x18) call. For example, ADP_Stopped_ApplicationExit.\n\t\t\t * - field 2 A subcode, whose meaning depends on the reason\n\t\t\t * code in field 1. In particular, if field 1 is\n\t\t\t * ADP_Stopped_ApplicationExit then field 2 is an exit status\n\t\t\t * code, as passed to the C standard library exit() function.\n\t\t\t * A simulator receiving this request must notify a connected\n\t\t\t * debugger, if present, and then exit with the specified status.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * No return is expected from these calls.\n\t\t\t *\n\t\t\t * For the A64 API, this call is identical to the behavior of\n\t\t\t * the mandatory SYS_EXIT (0x18) call. If this extension is\n\t\t\t * supported, then both calls must be implemented.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint type = semihosting_get_field(target, 0, fields);\n\t\t\t\tint code = semihosting_get_field(target, 1, fields);\n\n\t\t\t\tif (type == ADP_STOPPED_APPLICATION_EXIT) {\n\t\t\t\t\tif (!gdb_get_actual_connections())\n\t\t\t\t\t\texit(code);\n\t\t\t\t\telse {\n\t\t\t\t\t\tfprintf(stderr,\n\t\t\t\t\t\t\t\"semihosting: *** application exited with %d ***\\n\",\n\t\t\t\t\t\t\tcode);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfprintf(stderr, \"semihosting: exception %#x\\n\",\n\t\t\t\t\t\ttype);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!semihosting->has_resumable_exit) {\n\t\t\t\tsemihosting->is_resumable = false;\n\t\t\t\treturn target_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_FLEN:\t/* 0x0C */\n\t\t\t/*\n\t\t\t * Returns the length of a specified file.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * one-field argument block:\n\t\t\t * - field 1 A handle for a previously opened, seekable file\n\t\t\t * object.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - The current length of the file object, if the call is\n\t\t\t * successful.\n\t\t\t * - –1 if an error occurs.\n\t\t\t */\n\t\t\tif (semihosting->is_fileio) {\n\t\t\t\tsemihosting->result = -1;\n\t\t\t\tsemihosting->sys_errno = EINVAL;\n\t\t\t}\n\t\t\tretval = semihosting_read_fields(target, 1, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\tstruct stat buf;\n\t\t\t\tsemihosting->result = fstat(fd, &buf);\n\t\t\t\tif (semihosting->result == -1) {\n\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\tLOG_DEBUG(\"fstat(%d)=%\" PRId64, fd, semihosting->result);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tLOG_DEBUG(\"fstat(%d)=%\" PRId64, fd, semihosting->result);\n\t\t\t\tsemihosting->result = buf.st_size;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_GET_CMDLINE:\t/* 0x15 */\n\t\t\t/*\n\t\t\t * Returns the command line that is used for the call to the\n\t\t\t * executable, that is, argc and argv.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER points to a two-field data\n\t\t\t * block to be used for returning the command string and its length:\n\t\t\t * - field 1 A pointer to a buffer of at least the size that is\n\t\t\t * specified in field 2.\n\t\t\t * - field 2 The length of the buffer in bytes.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit:\n\t\t\t * If the call is successful, then the RETURN REGISTER contains 0,\n\t\t\t * the PARAMETER REGISTER is unchanged, and the data block is\n\t\t\t * updated as follows:\n\t\t\t * - field 1 A pointer to a null-terminated string of the command\n\t\t\t * line.\n\t\t\t * - field 2 The length of the string in bytes.\n\t\t\t * If the call is not successful, then the RETURN REGISTER\n\t\t\t * contains -1.\n\t\t\t *\n\t\t\t * Note: The semihosting implementation might impose limits on\n\t\t\t * the maximum length of the string that can be transferred.\n\t\t\t * However, the implementation must be able to support a\n\t\t\t * command-line length of at least 80 bytes.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\t\t\t\tsize_t size = semihosting_get_field(target, 1, fields);\n\n\t\t\t\tchar *arg = semihosting->cmdline ?\n\t\t\t\t\tsemihosting->cmdline : \"\";\n\t\t\t\tuint32_t len = strlen(arg) + 1;\n\t\t\t\tif (len > size)\n\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\telse {\n\t\t\t\t\tsemihosting_set_field(target, len, 1, fields);\n\t\t\t\t\tretval = target_write_buffer(target, addr, len,\n\t\t\t\t\t\t\t(uint8_t *)arg);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\tsemihosting->result = 0;\n\n\t\t\t\t\tretval = semihosting_write_fields(target, 2, fields);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t\tLOG_DEBUG(\"SYS_GET_CMDLINE=[%s], %\" PRId64, arg, semihosting->result);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_HEAPINFO:\t/* 0x16 */\n\t\t\t/*\n\t\t\t * Returns the system stack and heap parameters.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains the address of a\n\t\t\t * pointer to a four-field data block. The contents of the data\n\t\t\t * block are filled by the function. The following C-like\n\t\t\t * pseudocode describes the layout of the block:\n\t\t\t * struct block {\n\t\t\t *   void* heap_base;\n\t\t\t *   void* heap_limit;\n\t\t\t *   void* stack_base;\n\t\t\t *   void* stack_limit;\n\t\t\t * };\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the PARAMETER REGISTER is unchanged and the data\n\t\t\t * block has been updated.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 1, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\t\t\t\t/* tell the remote we have no idea */\n\t\t\t\tmemset(fields, 0, 4 * semihosting->word_size_bytes);\n\t\t\t\tretval = target_write_memory(target, addr, 4,\n\t\t\t\t\t\tsemihosting->word_size_bytes,\n\t\t\t\t\t\tfields);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tsemihosting->result = 0;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_ISERROR:\t/* 0x08 */\n\t\t\t/*\n\t\t\t * Determines whether the return code from another semihosting\n\t\t\t * call is an error status or not.\n\t\t\t *\n\t\t\t * This call is passed a parameter block containing the error\n\t\t\t * code to examine.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * one-field data block:\n\t\t\t * - field 1 The required status word to check.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the status field is not an error indication\n\t\t\t * - A nonzero value if the status field is an error indication.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 1, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tuint64_t code = semihosting_get_field(target, 0, fields);\n\t\t\tsemihosting->result = (code != 0);\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_ISTTY:\t/* 0x09 */\n\t\t\t/*\n\t\t\t * Checks whether a file is connected to an interactive device.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * one-field argument block:\n\t\t\t * field 1 A handle for a previously opened file object.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 1 if the handle identifies an interactive device.\n\t\t\t * - 0 if the handle identifies a file.\n\t\t\t * - A value other than 1 or 0 if an error occurs.\n\t\t\t */\n\t\t\tif (semihosting->is_fileio) {\n\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\tfileio_info->identifier = \"isatty\";\n\t\t\t\tfileio_info->param_1 = semihosting->param;\n\t\t\t} else {\n\t\t\t\tretval = semihosting_read_fields(target, 1, fields);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\t// isatty() on Windows may return any non-zero value if fd is a terminal\n\t\t\t\tsemihosting->result = isatty(fd) ? 1 : 0;\n\t\t\t\tif (semihosting->result == 0)\n\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\tLOG_DEBUG(\"isatty(%d)=%\" PRId64, fd, semihosting->result);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_OPEN:\t/* 0x01 */\n\t\t\t/*\n\t\t\t * Opens a file on the host system.\n\t\t\t *\n\t\t\t * The file path is specified either as relative to the current\n\t\t\t * directory of the host process, or absolute, using the path\n\t\t\t * conventions of the host operating system.\n\t\t\t *\n\t\t\t * Semihosting implementations must support opening the special\n\t\t\t * path name :semihosting-features as part of the semihosting\n\t\t\t * extensions reporting mechanism.\n\t\t\t *\n\t\t\t * ARM targets interpret the special path name :tt as meaning\n\t\t\t * the console input stream, for an open-read or the console\n\t\t\t * output stream, for an open-write. Opening these streams is\n\t\t\t * performed as part of the standard startup code for those\n\t\t\t * applications that reference the C stdio streams. The\n\t\t\t * semihosting extension SH_EXT_STDOUT_STDERR allows the\n\t\t\t * semihosting caller to open separate output streams\n\t\t\t * corresponding to stdout and stderr. This extension is\n\t\t\t * reported using feature byte 0, bit 1. Use SYS_OPEN with\n\t\t\t * the special path name :semihosting-features to access the\n\t\t\t * feature bits.\n\t\t\t *\n\t\t\t * If this extension is supported, the implementation must\n\t\t\t * support the following additional semantics to SYS_OPEN:\n\t\t\t * - If the special path name :tt is opened with an fopen\n\t\t\t * mode requesting write access (w, wb, w+, or w+b), then\n\t\t\t * this is a request to open stdout.\n\t\t\t * - If the special path name :tt is opened with a mode\n\t\t\t * requesting append access (a, ab, a+, or a+b), then this is\n\t\t\t * a request to open stderr.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * three-field argument block:\n\t\t\t * - field 1 A pointer to a null-terminated string containing\n\t\t\t * a file or device name.\n\t\t\t * - field 2 An integer that specifies the file opening mode.\n\t\t\t * - field 3 An integer that gives the length of the string\n\t\t\t * pointed to by field 1.\n\t\t\t *\n\t\t\t * The length does not include the terminating null character\n\t\t\t * that must be present.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - A nonzero handle if the call is successful.\n\t\t\t * - –1 if the call is not successful.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 3, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\t\t\t\tuint32_t mode = semihosting_get_field(target, 1, fields);\n\t\t\t\tsize_t len = semihosting_get_field(target, 2, fields);\n\n\t\t\t\tif (mode > 11) {\n\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\tsemihosting->sys_errno = EINVAL;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsize_t basedir_len = semihosting->basedir ? strlen(semihosting->basedir) : 0;\n\t\t\t\tuint8_t *fn = malloc(basedir_len + len + 2);\n\t\t\t\tif (!fn) {\n\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t} else {\n\t\t\t\t\tif (basedir_len > 0) {\n\t\t\t\t\t\tstrcpy((char *)fn, semihosting->basedir);\n\t\t\t\t\t\tif (fn[basedir_len - 1] != '/')\n\t\t\t\t\t\t\tfn[basedir_len++] = '/';\n\t\t\t\t\t}\n\t\t\t\t\tretval = target_read_memory(target, addr, 1, len, fn + basedir_len);\n\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\tfree(fn);\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\t}\n\t\t\t\t\tfn[basedir_len + len] = 0;\n\t\t\t\t\t/* TODO: implement the :semihosting-features special file.\n\t\t\t\t\t * */\n\t\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\t\tif (strcmp((char *)fn, \":semihosting-features\") == 0) {\n\t\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\t\tsemihosting->sys_errno = EINVAL;\n\t\t\t\t\t\t} else if (strcmp((char *)fn, \":tt\") == 0) {\n\t\t\t\t\t\t\tif (mode == 0) {\n\t\t\t\t\t\t\t\tsemihosting->result = 0;\n\t\t\t\t\t\t\t} else if (mode == 4) {\n\t\t\t\t\t\t\t\tsemihosting->result = 1;\n\t\t\t\t\t\t\t} else if (mode == 8) {\n\t\t\t\t\t\t\t\tsemihosting->result = 2;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\t\t\tsemihosting->sys_errno = EINVAL;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\t\t\tfileio_info->identifier = \"open\";\n\t\t\t\t\t\t\tfileio_info->param_1 = addr;\n\t\t\t\t\t\t\tfileio_info->param_2 = len;\n\t\t\t\t\t\t\tfileio_info->param_3 = open_gdb_modeflags[mode];\n\t\t\t\t\t\t\tfileio_info->param_4 = 0644;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (strcmp((char *)fn, \":tt\") == 0) {\n\t\t\t\t\t\t\t/* Mode is:\n\t\t\t\t\t\t\t * - 0-3 (\"r\") for stdin,\n\t\t\t\t\t\t\t * - 4-7 (\"w\") for stdout,\n\t\t\t\t\t\t\t * - 8-11 (\"a\") for stderr */\n\t\t\t\t\t\t\tint fd;\n\t\t\t\t\t\t\tif (mode < 4) {\n\t\t\t\t\t\t\t\tfd = dup(STDIN_FILENO);\n\t\t\t\t\t\t\t\tsemihosting->stdin_fd = fd;\n\t\t\t\t\t\t\t\tLOG_DEBUG(\"dup(STDIN)=%d\", fd);\n\t\t\t\t\t\t\t} else if (mode < 8) {\n\t\t\t\t\t\t\t\tfd = dup(STDOUT_FILENO);\n\t\t\t\t\t\t\t\tsemihosting->stdout_fd = fd;\n\t\t\t\t\t\t\t\tLOG_DEBUG(\"dup(STDOUT)=%d\", fd);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfd = dup(STDERR_FILENO);\n\t\t\t\t\t\t\t\tsemihosting->stderr_fd = fd;\n\t\t\t\t\t\t\t\tLOG_DEBUG(\"dup(STDERR)=%d\", fd);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsemihosting->result = fd;\n\t\t\t\t\t\t\tif (fd == -1)\n\t\t\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* cygwin requires the permission setting\n\t\t\t\t\t\t\t * otherwise it will fail to reopen a previously\n\t\t\t\t\t\t\t * written file */\n\t\t\t\t\t\t\tsemihosting->result = open((char *)fn,\n\t\t\t\t\t\t\t\t\topen_host_modeflags[mode],\n\t\t\t\t\t\t\t\t\t0644);\n\t\t\t\t\t\t\tif (semihosting->result == -1)\n\t\t\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\t\t\tLOG_DEBUG(\"open('%s')=%\" PRId64, fn, semihosting->result);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfree(fn);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_READ:\t/* 0x06 */\n\t\t\t/*\n\t\t\t * Reads the contents of a file into a buffer. The file position\n\t\t\t * is specified either:\n\t\t\t * - Explicitly by a SYS_SEEK.\n\t\t\t * - Implicitly one byte beyond the previous SYS_READ or\n\t\t\t * SYS_WRITE request.\n\t\t\t *\n\t\t\t * The file position is at the start of the file when it is\n\t\t\t * opened, and is lost when the file is closed. Perform the\n\t\t\t * file operation as a single action whenever possible. For\n\t\t\t * example, do not split a read of 16KB into four 4KB chunks\n\t\t\t * unless there is no alternative.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * three-field data block:\n\t\t\t * - field 1 Contains a handle for a file previously opened\n\t\t\t * with SYS_OPEN.\n\t\t\t * - field 2 Points to a buffer.\n\t\t\t * - field 3 Contains the number of bytes to read to the buffer\n\t\t\t * from the file.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the number of bytes not\n\t\t\t * filled in the buffer (buffer_length - bytes_read) as follows:\n\t\t\t * - If the RETURN REGISTER is 0, the entire buffer was\n\t\t\t * successfully filled.\n\t\t\t * - If the RETURN REGISTER is the same as field 3, no bytes\n\t\t\t * were read (EOF can be assumed).\n\t\t\t * - If the RETURN REGISTER contains a value smaller than\n\t\t\t * field 3, the read succeeded but the buffer was only partly\n\t\t\t * filled. For interactive devices, this is the most common\n\t\t\t * return value.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 3, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 1, fields);\n\t\t\t\tsize_t len = semihosting_get_field(target, 2, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"read\";\n\t\t\t\t\tfileio_info->param_1 = fd;\n\t\t\t\t\tfileio_info->param_2 = addr;\n\t\t\t\t\tfileio_info->param_3 = len;\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t *buf = malloc(len);\n\t\t\t\t\tif (!buf) {\n\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsemihosting->result = semihosting_read(semihosting, fd, buf, len);\n\t\t\t\t\t\tLOG_DEBUG(\"read(%d, 0x%\" PRIx64 \", %zu)=%\" PRId64,\n\t\t\t\t\t\t\tfd,\n\t\t\t\t\t\t\taddr,\n\t\t\t\t\t\t\tlen,\n\t\t\t\t\t\t\tsemihosting->result);\n\t\t\t\t\t\tif (semihosting->result >= 0) {\n\t\t\t\t\t\t\tretval = target_write_buffer(target, addr,\n\t\t\t\t\t\t\t\t\tsemihosting->result,\n\t\t\t\t\t\t\t\t\tbuf);\n\t\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\t\tfree(buf);\n\t\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/* the number of bytes NOT filled in */\n\t\t\t\t\t\t\tsemihosting->result = len -\n\t\t\t\t\t\t\t\tsemihosting->result;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfree(buf);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_READC:\t/* 0x07 */\n\t\t\t/*\n\t\t\t * Reads a byte from the console.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * The PARAMETER REGISTER must contain 0. There are no other\n\t\t\t * parameters or values possible.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the byte read from\n\t\t\t * the console.\n\t\t\t */\n\t\t\tif (semihosting->is_fileio) {\n\t\t\t\tLOG_ERROR(\"SYS_READC not supported by semihosting fileio\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tsemihosting->result = semihosting_getchar(semihosting, semihosting->stdin_fd);\n\t\t\tLOG_DEBUG(\"getchar()=%\" PRId64, semihosting->result);\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_REMOVE:\t/* 0x0E */\n\t\t\t/*\n\t\t\t * Deletes a specified file on the host filing system.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field argument block:\n\t\t\t * - field 1 Points to a null-terminated string that gives the\n\t\t\t * path name of the file to be deleted.\n\t\t\t * - field 2 The length of the string.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the delete is successful\n\t\t\t * - A nonzero, host-specific error code if the delete fails.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\t\t\t\tsize_t len = semihosting_get_field(target, 1, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"unlink\";\n\t\t\t\t\tfileio_info->param_1 = addr;\n\t\t\t\t\tfileio_info->param_2 = len;\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t *fn = malloc(len+1);\n\t\t\t\t\tif (!fn) {\n\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tretval =\n\t\t\t\t\t\t\ttarget_read_memory(target, addr, 1, len,\n\t\t\t\t\t\t\t\tfn);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tfree(fn);\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfn[len] = 0;\n\t\t\t\t\t\tsemihosting->result = remove((char *)fn);\n\t\t\t\t\t\tif (semihosting->result == -1)\n\t\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\t\tLOG_DEBUG(\"remove('%s')=%\" PRId64, fn, semihosting->result);\n\n\t\t\t\t\t\tfree(fn);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_RENAME:\t/* 0x0F */\n\t\t\t/*\n\t\t\t * Renames a specified file.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * four-field data block:\n\t\t\t * - field 1 A pointer to the name of the old file.\n\t\t\t * - field 2 The length of the old filename.\n\t\t\t * - field 3 A pointer to the new filename.\n\t\t\t * - field 4 The length of the new filename. Both strings are\n\t\t\t * null-terminated.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the rename is successful.\n\t\t\t * - A nonzero, host-specific error code if the rename fails.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 4, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr1 = semihosting_get_field(target, 0, fields);\n\t\t\t\tsize_t len1 = semihosting_get_field(target, 1, fields);\n\t\t\t\tuint64_t addr2 = semihosting_get_field(target, 2, fields);\n\t\t\t\tsize_t len2 = semihosting_get_field(target, 3, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"rename\";\n\t\t\t\t\tfileio_info->param_1 = addr1;\n\t\t\t\t\tfileio_info->param_2 = len1;\n\t\t\t\t\tfileio_info->param_3 = addr2;\n\t\t\t\t\tfileio_info->param_4 = len2;\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t *fn1 = malloc(len1+1);\n\t\t\t\t\tuint8_t *fn2 = malloc(len2+1);\n\t\t\t\t\tif (!fn1 || !fn2) {\n\t\t\t\t\t\tfree(fn1);\n\t\t\t\t\t\tfree(fn2);\n\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tretval = target_read_memory(target, addr1, 1, len1,\n\t\t\t\t\t\t\t\tfn1);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tfree(fn1);\n\t\t\t\t\t\t\tfree(fn2);\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tretval = target_read_memory(target, addr2, 1, len2,\n\t\t\t\t\t\t\t\tfn2);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tfree(fn1);\n\t\t\t\t\t\t\tfree(fn2);\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfn1[len1] = 0;\n\t\t\t\t\t\tfn2[len2] = 0;\n\t\t\t\t\t\tsemihosting->result = rename((char *)fn1,\n\t\t\t\t\t\t\t\t(char *)fn2);\n\t\t\t\t\t\t// rename() on Windows returns nonzero on error\n\t\t\t\t\t\tif (semihosting->result != 0)\n\t\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\t\tLOG_DEBUG(\"rename('%s', '%s')=%\" PRId64 \" %d\", fn1, fn2, semihosting->result, errno);\n\t\t\t\t\t\tfree(fn1);\n\t\t\t\t\t\tfree(fn2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_SEEK:\t/* 0x0A */\n\t\t\t/*\n\t\t\t * Seeks to a specified position in a file using an offset\n\t\t\t * specified from the start of the file. The file is assumed\n\t\t\t * to be a byte array and the offset is given in bytes.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field data block:\n\t\t\t * - field 1 A handle for a seekable file object.\n\t\t\t * - field 2 The absolute byte position to seek to.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the request is successful.\n\t\t\t * - A negative value if the request is not successful.\n\t\t\t * Use SYS_ERRNO to read the value of the host errno variable\n\t\t\t * describing the error.\n\t\t\t *\n\t\t\t * Note: The effect of seeking outside the current extent of\n\t\t\t * the file object is undefined.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\toff_t pos = semihosting_get_field(target, 1, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"lseek\";\n\t\t\t\t\tfileio_info->param_1 = fd;\n\t\t\t\t\tfileio_info->param_2 = pos;\n\t\t\t\t\tfileio_info->param_3 = SEEK_SET;\n\t\t\t\t} else {\n\t\t\t\t\tsemihosting->result = lseek(fd, pos, SEEK_SET);\n\t\t\t\t\tif (semihosting->result == -1)\n\t\t\t\t\t\tsemihosting->sys_errno = errno;\n\t\t\t\t\tLOG_DEBUG(\"lseek(%d, %d)=%\" PRId64, fd, (int)pos, semihosting->result);\n\t\t\t\t\tif (semihosting->result == pos)\n\t\t\t\t\t\tsemihosting->result = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_SYSTEM:\t/* 0x12 */\n\t\t\t/*\n\t\t\t * Passes a command to the host command-line interpreter.\n\t\t\t * This enables you to execute a system command such as dir,\n\t\t\t * ls, or pwd. The terminal I/O is on the host, and is not\n\t\t\t * visible to the target.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field argument block:\n\t\t\t * - field 1 Points to a string to be passed to the host\n\t\t\t * command-line interpreter.\n\t\t\t * - field 2 The length of the string.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the return status.\n\t\t\t */\n\n\t\t\t/* Provide SYS_SYSTEM functionality.  Uses the\n\t\t\t * libc system command, there may be a reason *NOT*\n\t\t\t * to use this, but as I can't think of one, I\n\t\t\t * implemented it this way.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\t\t\t\tsize_t len = semihosting_get_field(target, 1, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"system\";\n\t\t\t\t\tfileio_info->param_1 = addr;\n\t\t\t\t\tfileio_info->param_2 = len;\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t *cmd = malloc(len+1);\n\t\t\t\t\tif (!cmd) {\n\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tretval = target_read_memory(target,\n\t\t\t\t\t\t\t\taddr,\n\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\tlen,\n\t\t\t\t\t\t\t\tcmd);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tfree(cmd);\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcmd[len] = 0;\n\t\t\t\t\t\t\tsemihosting->result = system(\n\t\t\t\t\t\t\t\t\t(const char *)cmd);\n\t\t\t\t\t\t\tLOG_DEBUG(\"system('%s')=%\" PRId64, cmd, semihosting->result);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfree(cmd);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_TIME:\t/* 0x11 */\n\t\t\t/*\n\t\t\t * Returns the number of seconds since 00:00 January 1, 1970.\n\t\t\t * This value is real-world time, regardless of any debug agent\n\t\t\t * configuration.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * There are no parameters.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the number of seconds.\n\t\t\t */\n\t\t\tsemihosting->result = time(NULL);\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_WRITE:\t/* 0x05 */\n\t\t\t/*\n\t\t\t * Writes the contents of a buffer to a specified file at the\n\t\t\t * current file position. The file position is specified either:\n\t\t\t * - Explicitly, by a SYS_SEEK.\n\t\t\t * - Implicitly as one byte beyond the previous SYS_READ or\n\t\t\t * SYS_WRITE request.\n\t\t\t *\n\t\t\t * The file position is at the start of the file when the file\n\t\t\t * is opened, and is lost when the file is closed.\n\t\t\t *\n\t\t\t * Perform the file operation as a single action whenever\n\t\t\t * possible. For example, do not split a write of 16KB into\n\t\t\t * four 4KB chunks unless there is no alternative.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * three-field data block:\n\t\t\t * - field 1 Contains a handle for a file previously opened\n\t\t\t * with SYS_OPEN.\n\t\t\t * - field 2 Points to the memory containing the data to be written.\n\t\t\t * - field 3 Contains the number of bytes to be written from\n\t\t\t * the buffer to the file.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains:\n\t\t\t * - 0 if the call is successful.\n\t\t\t * - The number of bytes that are not written, if there is an error.\n\t\t\t */\n\t\t\tretval = semihosting_read_fields(target, 3, fields);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\telse {\n\t\t\t\tint fd = semihosting_get_field(target, 0, fields);\n\t\t\t\tuint64_t addr = semihosting_get_field(target, 1, fields);\n\t\t\t\tsize_t len = semihosting_get_field(target, 2, fields);\n\t\t\t\tif (semihosting->is_fileio) {\n\t\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\t\tfileio_info->identifier = \"write\";\n\t\t\t\t\tfileio_info->param_1 = fd;\n\t\t\t\t\tfileio_info->param_2 = addr;\n\t\t\t\t\tfileio_info->param_3 = len;\n\t\t\t\t} else {\n\t\t\t\t\tuint8_t *buf = malloc(len);\n\t\t\t\t\tif (!buf) {\n\t\t\t\t\t\tsemihosting->result = -1;\n\t\t\t\t\t\tsemihosting->sys_errno = ENOMEM;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tretval = target_read_buffer(target, addr, len, buf);\n\t\t\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\t\t\tfree(buf);\n\t\t\t\t\t\t\treturn retval;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsemihosting->result = semihosting_write(semihosting, fd, buf, len);\n\t\t\t\t\t\tLOG_DEBUG(\"write(%d, 0x%\" PRIx64 \", %zu)=%\" PRId64,\n\t\t\t\t\t\t\tfd,\n\t\t\t\t\t\t\taddr,\n\t\t\t\t\t\t\tlen,\n\t\t\t\t\t\t\tsemihosting->result);\n\t\t\t\t\t\tif (semihosting->result >= 0) {\n\t\t\t\t\t\t\t/* The number of bytes that are NOT written.\n\t\t\t\t\t\t\t * */\n\t\t\t\t\t\t\tsemihosting->result = len -\n\t\t\t\t\t\t\t\tsemihosting->result;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfree(buf);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_WRITEC:\t/* 0x03 */\n\t\t\t/*\n\t\t\t * Writes a character byte, pointed to by the PARAMETER REGISTER,\n\t\t\t * to the debug channel. When executed under a semihosting\n\t\t\t * debugger, the character appears on the host debugger console.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to the\n\t\t\t * character.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * None. The RETURN REGISTER is corrupted.\n\t\t\t */\n\t\t\tif (semihosting->is_fileio) {\n\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\tfileio_info->identifier = \"write\";\n\t\t\t\tfileio_info->param_1 = 1;\n\t\t\t\tfileio_info->param_2 = semihosting->param;\n\t\t\t\tfileio_info->param_3 = 1;\n\t\t\t} else {\n\t\t\t\tuint64_t addr = semihosting->param;\n\t\t\t\tunsigned char c;\n\t\t\t\tretval = target_read_memory(target, addr, 1, 1, &c);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t\tsemihosting_putchar(semihosting, semihosting->stdout_fd, c);\n\t\t\t\tsemihosting->result = 0;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_WRITE0:\t/* 0x04 */\n\t\t\t/*\n\t\t\t * Writes a null-terminated string to the debug channel.\n\t\t\t * When executed under a semihosting debugger, the characters\n\t\t\t * appear on the host debugger console.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to the\n\t\t\t * first byte of the string.\n\t\t\t *\n\t\t\t * Return\n\t\t\t * None. The RETURN REGISTER is corrupted.\n\t\t\t */\n\t\t\tif (semihosting->is_fileio) {\n\t\t\t\tsize_t count = 0;\n\t\t\t\tuint64_t addr = semihosting->param;\n\t\t\t\tfor (;; addr++) {\n\t\t\t\t\tunsigned char c;\n\t\t\t\t\tretval = target_read_memory(target, addr, 1, 1, &c);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\tif (c == '\\0')\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcount++;\n\t\t\t\t}\n\t\t\t\tsemihosting->hit_fileio = true;\n\t\t\t\tfileio_info->identifier = \"write\";\n\t\t\t\tfileio_info->param_1 = 1;\n\t\t\t\tfileio_info->param_2 = semihosting->param;\n\t\t\t\tfileio_info->param_3 = count;\n\t\t\t} else {\n\t\t\t\tuint64_t addr = semihosting->param;\n\t\t\t\tdo {\n\t\t\t\t\tunsigned char c;\n\t\t\t\t\tretval = target_read_memory(target, addr++, 1, 1, &c);\n\t\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\t\treturn retval;\n\t\t\t\t\tif (!c)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tsemihosting_putchar(semihosting, semihosting->stdout_fd, c);\n\t\t\t\t} while (1);\n\t\t\t\tsemihosting->result = 0;\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X107:\n\t\t\t/**\n\t\t\t * This is a user defined operation (while user cmds 0x100-0x1ff\n\t\t\t * are possible, only 0x100-0x107 are currently implemented).\n\t\t\t *\n\t\t\t * Reads the user operation parameters from target, then fires the\n\t\t\t * corresponding target event. When the target callbacks returned,\n\t\t\t * cleans up the command parameter buffer.\n\t\t\t *\n\t\t\t * Entry\n\t\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t\t * two-field data block:\n\t\t\t * - field 1 Contains a pointer to the bound command parameter\n\t\t\t * string\n\t\t\t * - field 2 Contains the command parameter string length\n\t\t\t *\n\t\t\t * Return\n\t\t\t * On exit, the RETURN REGISTER contains the return status.\n\t\t\t */\n\t\t\tif (semihosting->user_command_extension) {\n\t\t\t\tretval = semihosting->user_command_extension(target);\n\t\t\t\tif (retval != ERROR_NOT_IMPLEMENTED)\n\t\t\t\t\tbreak;\n\t\t\t\t/* If custom user command not handled, we are looking for the TCL handler */\n\t\t\t}\n\n\t\t\tassert(!semihosting_user_op_params);\n\t\t\tretval = semihosting_read_fields(target, 2, fields);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to read fields for user defined command\"\n\t\t\t\t\t\t\" op=0x%x\", semihosting->op);\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\tuint64_t addr = semihosting_get_field(target, 0, fields);\n\n\t\t\tsize_t len = semihosting_get_field(target, 1, fields);\n\t\t\tif (len > SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH) {\n\t\t\t\tLOG_ERROR(\"The maximum length for user defined command \"\n\t\t\t\t\t\t\"parameter is %u, received length is %zu (op=0x%x)\",\n\t\t\t\t\t\tSEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH,\n\t\t\t\t\t\tlen,\n\t\t\t\t\t\tsemihosting->op);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tsemihosting_user_op_params = malloc(len + 1);\n\t\t\tif (!semihosting_user_op_params)\n\t\t\t\treturn ERROR_FAIL;\n\t\t\tsemihosting_user_op_params[len] = 0;\n\n\t\t\tretval = target_read_buffer(target, addr, len,\n\t\t\t\t\t(uint8_t *)(semihosting_user_op_params));\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Failed to read from target, semihosting op=0x%x (%s)\",\n\t\t\t\t\t\tsemihosting->op,\n\t\t\t\t\t\tsemihosting_opcode_to_str(semihosting->op));\n\t\t\t\tfree(semihosting_user_op_params);\n\t\t\t\tsemihosting_user_op_params = NULL;\n\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\ttarget_handle_event(target, semihosting->op);\n\t\t\tfree(semihosting_user_op_params);\n\t\t\tsemihosting_user_op_params = NULL;\n\t\t\tsemihosting->result = 0;\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_ELAPSED:\t/* 0x30 */\n\t\t/*\n\t\t * Returns the number of elapsed target ticks since execution\n\t\t * started.\n\t\t * Use SYS_TICKFREQ to determine the tick frequency.\n\t\t *\n\t\t * Entry (32-bit)\n\t\t * On entry, the PARAMETER REGISTER points to a two-field data\n\t\t * block to be used for returning the number of elapsed ticks:\n\t\t * - field 1 The least significant field and is at the low address.\n\t\t * - field 2 The most significant field and is at the high address.\n\t\t *\n\t\t * Entry (64-bit)\n\t\t * On entry the PARAMETER REGISTER points to a one-field data\n\t\t * block to be used for returning the number of elapsed ticks:\n\t\t * - field 1 The number of elapsed ticks as a 64-bit value.\n\t\t *\n\t\t * Return\n\t\t * On exit:\n\t\t * - On success, the RETURN REGISTER contains 0, the PARAMETER\n\t\t * REGISTER is unchanged, and the data block pointed to by the\n\t\t * PARAMETER REGISTER is filled in with the number of elapsed\n\t\t * ticks.\n\t\t * - On failure, the RETURN REGISTER contains -1, and the\n\t\t * PARAMETER REGISTER contains -1.\n\t\t *\n\t\t * Note: Some semihosting implementations might not support this\n\t\t * semihosting operation, and they always return -1 in the\n\t\t * RETURN REGISTER.\n\t\t */\n\n\t\tcase SEMIHOSTING_SYS_TICKFREQ:\t/* 0x31 */\n\t\t/*\n\t\t * Returns the tick frequency.\n\t\t *\n\t\t * Entry\n\t\t * The PARAMETER REGISTER must contain 0 on entry to this routine.\n\t\t *\n\t\t * Return\n\t\t * On exit, the RETURN REGISTER contains either:\n\t\t * - The number of ticks per second.\n\t\t * - –1 if the target does not know the value of one tick.\n\t\t *\n\t\t * Note: Some semihosting implementations might not support\n\t\t * this semihosting operation, and they always return -1 in the\n\t\t * RETURN REGISTER.\n\t\t */\n\n\t\tcase SEMIHOSTING_SYS_TMPNAM:\t/* 0x0D */\n\t\t/*\n\t\t * Returns a temporary name for a file identified by a system\n\t\t * file identifier.\n\t\t *\n\t\t * Entry\n\t\t * On entry, the PARAMETER REGISTER contains a pointer to a\n\t\t * three-word argument block:\n\t\t * - field 1 A pointer to a buffer.\n\t\t * - field 2 A target identifier for this filename. Its value\n\t\t * must be an integer in the range 0-255.\n\t\t * - field 3 Contains the length of the buffer. The length must\n\t\t * be at least the value of L_tmpnam on the host system.\n\t\t *\n\t\t * Return\n\t\t * On exit, the RETURN REGISTER contains:\n\t\t * - 0 if the call is successful.\n\t\t * - –1 if an error occurs.\n\t\t *\n\t\t * The buffer pointed to by the PARAMETER REGISTER contains\n\t\t * the filename, prefixed with a suitable directory name.\n\t\t * If you use the same target identifier again, the same\n\t\t * filename is returned.\n\t\t *\n\t\t * Note: The returned string must be null-terminated.\n\t\t */\n\n\t\tdefault:\n\t\t\tfprintf(stderr, \"semihosting: unsupported call %#x\\n\",\n\t\t\t\t(unsigned) semihosting->op);\n\t\t\tsemihosting->result = -1;\n\t\t\tsemihosting->sys_errno = ENOTSUP;\n\t}\n\n\tif (!semihosting->hit_fileio) {\n\t\tretval = semihosting->post_result(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to post semihosting result\");\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* -------------------------------------------------------------------------\n * Local functions. */\n\nstatic int semihosting_common_fileio_info(struct target *target,\n\tstruct gdb_fileio_info *fileio_info)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting)\n\t\treturn ERROR_FAIL;\n\n\t/*\n\t * To avoid unnecessary duplication, semihosting prepares the\n\t * fileio_info structure out-of-band when the target halts. See\n\t * do_semihosting for more detail.\n\t */\n\tif (!semihosting->is_fileio || !semihosting->hit_fileio)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int semihosting_common_fileio_end(struct target *target, int result,\n\tint fileio_errno, bool ctrl_c)\n{\n\tstruct gdb_fileio_info *fileio_info = target->fileio_info;\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting)\n\t\treturn ERROR_FAIL;\n\n\t/* clear pending status */\n\tsemihosting->hit_fileio = false;\n\n\tsemihosting->result = result;\n\n\t/*\n\t * Some fileio results do not match up with what the semihosting\n\t * operation expects; for these operations, we munge the results\n\t * below:\n\t */\n\tswitch (semihosting->op) {\n\t\tcase SEMIHOSTING_SYS_WRITE:\t/* 0x05 */\n\t\tcase SEMIHOSTING_SYS_READ:\t/* 0x06 */\n\t\t\tif (result < 0)\n\t\t\t\tsemihosting->result = fileio_info->param_3;  /* Zero bytes read/written. */\n\t\t\telse\n\t\t\t\tsemihosting->result = (int64_t)fileio_info->param_3 - result;\n\t\t\tbreak;\n\n\t\tcase SEMIHOSTING_SYS_SEEK:\t/* 0x0a */\n\t\t\tif (result > 0)\n\t\t\t\tsemihosting->result = 0;\n\t\t\tbreak;\n\t}\n\n\tbool fileio_failed = false;\n\tif (semihosting->op == SEMIHOSTING_SYS_ISTTY)\n\t\tfileio_failed = (semihosting->result == 0);\n\telse if (semihosting->op == SEMIHOSTING_SYS_RENAME)\n\t\tfileio_failed = (semihosting->result != 0);\n\telse\n\t\tfileio_failed = (semihosting->result == -1);\n\n\tif (fileio_failed)\n\t\tsemihosting->sys_errno = fileio_errno;\n\n\treturn semihosting->post_result(target);\n}\n\n/* -------------------------------------------------------------------------\n * Utility functions. */\n\n/**\n * Read all fields of a command from target to buffer.\n */\nint semihosting_read_fields(struct target *target, size_t number,\n\tuint8_t *fields)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\t/* Use 4-byte multiples to trigger fast memory access. */\n\treturn target_read_memory(target, semihosting->param, 4,\n\t\t\tnumber * (semihosting->word_size_bytes / 4), fields);\n}\n\n/**\n * Write all fields of a command from buffer to target.\n */\nint semihosting_write_fields(struct target *target, size_t number,\n\tuint8_t *fields)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\t/* Use 4-byte multiples to trigger fast memory access. */\n\treturn target_write_memory(target, semihosting->param, 4,\n\t\t\tnumber * (semihosting->word_size_bytes / 4), fields);\n}\n\n/**\n * Extract a field from the buffer, considering register size and endianness.\n */\nuint64_t semihosting_get_field(struct target *target, size_t index,\n\tuint8_t *fields)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (semihosting->word_size_bytes == 8)\n\t\treturn target_buffer_get_u64(target, fields + (index * 8));\n\telse\n\t\treturn target_buffer_get_u32(target, fields + (index * 4));\n}\n\n/**\n * Store a field in the buffer, considering register size and endianness.\n */\nvoid semihosting_set_field(struct target *target, uint64_t value,\n\tsize_t index,\n\tuint8_t *fields)\n{\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (semihosting->word_size_bytes == 8)\n\t\ttarget_buffer_set_u64(target, fields + (index * 8), value);\n\telse\n\t\ttarget_buffer_set_u32(target, fields + (index * 4), value);\n}\n\n/* -------------------------------------------------------------------------\n * Semihosting redirect over TCP structs and functions */\n\nstatic int semihosting_service_new_connection_handler(struct connection *connection)\n{\n\tstruct semihosting_tcp_service *service = connection->service->priv;\n\tservice->semihosting->tcp_connection = connection;\n\n\treturn ERROR_OK;\n}\n\nstatic int semihosting_service_input_handler(struct connection *connection)\n{\n\tstruct semihosting_tcp_service *service = connection->service->priv;\n\n\tif (!connection->input_pending) {\n\t\t/* consume received data, not for semihosting IO */\n\t\tconst int buf_len = 100;\n\t\tchar buf[buf_len];\n\t\tint bytes_read = connection_read(connection, buf, buf_len);\n\n\t\tif (bytes_read == 0) {\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t} else if (bytes_read == -1) {\n\t\t\tLOG_ERROR(\"error during read: %s\", strerror(errno));\n\t\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t\t}\n\t} else if (service->error != ERROR_OK) {\n\t\treturn ERROR_SERVER_REMOTE_CLOSED;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int semihosting_service_connection_closed_handler(struct connection *connection)\n{\n\tstruct semihosting_tcp_service *service = connection->service->priv;\n\tif (service) {\n\t\tfree(service->name);\n\t\tfree(service);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic void semihosting_tcp_close_cnx(struct semihosting *semihosting)\n{\n\tif (!semihosting->tcp_connection)\n\t\treturn;\n\n\tstruct service *service = semihosting->tcp_connection->service;\n\tremove_service(service->name, service->port);\n\tsemihosting->tcp_connection = NULL;\n\n}\n\nstatic const struct service_driver semihosting_service_driver = {\n\t.name = \"semihosting\",\n\t.new_connection_during_keep_alive_handler = NULL,\n\t.new_connection_handler = semihosting_service_new_connection_handler,\n\t.input_handler = semihosting_service_input_handler,\n\t.connection_closed_handler = semihosting_service_connection_closed_handler,\n\t.keep_client_alive_handler = NULL,\n};\n\n/* -------------------------------------------------------------------------\n * Common semihosting commands handlers. */\n\nCOMMAND_HANDLER(handle_common_semihosting_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC > 0) {\n\t\tint is_active;\n\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], is_active);\n\n\t\tif (!target_was_examined(target)) {\n\t\t\tLOG_ERROR(\"Target not examined yet\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (semihosting && semihosting->setup(target, is_active) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to Configure semihosting\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* FIXME never let that \"catch\" be dropped! (???) */\n\t\tsemihosting->is_active = is_active;\n\t}\n\n\tcommand_print(CMD, \"semihosting is %s\",\n\t\tsemihosting->is_active\n\t\t? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_redirect_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tcommand_print(CMD, \"semihosting not yet enabled for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tenum semihosting_redirect_config cfg;\n\tconst char *port;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (strcmp(CMD_ARGV[0], \"disable\") == 0) {\n\t\tcfg = SEMIHOSTING_REDIRECT_CFG_NONE;\n\t\tif (CMD_ARGC > 1)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t} else if (strcmp(CMD_ARGV[0], \"tcp\") == 0) {\n\t\tif (CMD_ARGC < 2 || CMD_ARGC > 3)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t\tport = CMD_ARGV[1];\n\n\t\tcfg = SEMIHOSTING_REDIRECT_CFG_ALL;\n\t\tif (CMD_ARGC == 3) {\n\t\t\tif (strcmp(CMD_ARGV[2], \"debug\") == 0)\n\t\t\t\tcfg = SEMIHOSTING_REDIRECT_CFG_DEBUG;\n\t\t\telse if (strcmp(CMD_ARGV[2], \"stdio\") == 0)\n\t\t\t\tcfg = SEMIHOSTING_REDIRECT_CFG_STDIO;\n\t\t\telse if (strcmp(CMD_ARGV[2], \"all\") != 0)\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t} else {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tsemihosting_tcp_close_cnx(semihosting);\n\tsemihosting->redirect_cfg = SEMIHOSTING_REDIRECT_CFG_NONE;\n\n\tif (cfg != SEMIHOSTING_REDIRECT_CFG_NONE) {\n\t\tstruct semihosting_tcp_service *service =\n\t\t\t\tcalloc(1, sizeof(struct semihosting_tcp_service));\n\t\tif (!service) {\n\t\t\tLOG_ERROR(\"Failed to allocate semihosting TCP service.\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tservice->semihosting = semihosting;\n\n\t\tservice->name = alloc_printf(\"%s semihosting service\", target_name(target));\n\t\tif (!service->name) {\n\t\t\tLOG_ERROR(\"Out of memory\");\n\t\t\tfree(service);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tint ret = add_service(&semihosting_service_driver,\n\t\t\t\tport, 1, service);\n\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to initialize %s\", service->name);\n\t\t\tfree(service->name);\n\t\t\tfree(service);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tsemihosting->redirect_cfg = cfg;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_fileio_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tcommand_print(CMD, \"semihosting not yet enabled for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->is_fileio);\n\n\tcommand_print(CMD, \"semihosting fileio is %s\",\n\t\tsemihosting->is_fileio\n\t\t? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_cmdline)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tunsigned int i;\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfree(semihosting->cmdline);\n\tsemihosting->cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;\n\n\tfor (i = 1; i < CMD_ARGC; i++) {\n\t\tchar *cmdline = alloc_printf(\"%s %s\", semihosting->cmdline, CMD_ARGV[i]);\n\t\tif (!cmdline)\n\t\t\tbreak;\n\t\tfree(semihosting->cmdline);\n\t\tsemihosting->cmdline = cmdline;\n\t}\n\n\tcommand_print(CMD, \"semihosting command line is [%s]\",\n\t\tsemihosting->cmdline);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_resumable_exit_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tcommand_print(CMD, \"semihosting not yet enabled for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC > 0)\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting->has_resumable_exit);\n\n\tcommand_print(CMD, \"semihosting resumable exit is %s\",\n\t\tsemihosting->has_resumable_exit\n\t\t? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_read_user_param_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct semihosting *semihosting = target->semihosting;\n\n\tif (CMD_ARGC)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!semihosting->is_active) {\n\t\tLOG_ERROR(\"semihosting not yet enabled for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting_user_op_params) {\n\t\tLOG_ERROR(\"This command is usable only from a registered user \"\n\t\t\t\t\"semihosting event callback.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcommand_print_sameline(CMD, \"%s\", semihosting_user_op_params);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_common_semihosting_basedir_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!target) {\n\t\tLOG_ERROR(\"No target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct semihosting *semihosting = target->semihosting;\n\tif (!semihosting) {\n\t\tcommand_print(CMD, \"semihosting not supported for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!semihosting->is_active) {\n\t\tcommand_print(CMD, \"semihosting not yet enabled for current target\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC > 0) {\n\t\tfree(semihosting->basedir);\n\t\tsemihosting->basedir = strdup(CMD_ARGV[0]);\n\t\tif (!semihosting->basedir) {\n\t\t\tcommand_print(CMD, \"semihosting failed to allocate memory for basedir!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"semihosting base dir: %s\",\n\t\tsemihosting->basedir ? semihosting->basedir : \"\");\n\n\treturn ERROR_OK;\n}\n\nconst struct command_registration semihosting_common_handlers[] = {\n\t{\n\t\t.name = \"semihosting\",\n\t\t.handler = handle_common_semihosting_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"activate support for semihosting operations\",\n\t},\n\t{\n\t\t.name = \"semihosting_redirect\",\n\t\t.handler = handle_common_semihosting_redirect_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"(disable | tcp <port> ['debug'|'stdio'|'all'])\",\n\t\t.help = \"redirect semihosting IO\",\n\t},\n\t{\n\t\t.name = \"semihosting_cmdline\",\n\t\t.handler = handle_common_semihosting_cmdline,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"arguments\",\n\t\t.help = \"command line arguments to be passed to program\",\n\t},\n\t{\n\t\t.name = \"semihosting_fileio\",\n\t\t.handler = handle_common_semihosting_fileio_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"activate support for semihosting fileio operations\",\n\t},\n\t{\n\t\t.name = \"semihosting_resexit\",\n\t\t.handler = handle_common_semihosting_resumable_exit_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"['enable'|'disable']\",\n\t\t.help = \"activate support for semihosting resumable exit\",\n\t},\n\t{\n\t\t.name = \"semihosting_read_user_param\",\n\t\t.handler = handle_common_semihosting_read_user_param_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"read parameters in semihosting-user-cmd-0x10X callbacks\",\n\t},\n\t{\n\t\t.name = \"semihosting_basedir\",\n\t\t.handler = handle_common_semihosting_basedir_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[dir]\",\n\t\t.help = \"set the base directory for semihosting I/O operations\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/semihosting_common.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2018 by Liviu Ionescu                                   *\n *   <ilg@livius.net>                                                      *\n *                                                                         *\n *   Copyright (C) 2009 by Marvell Technology Group Ltd.                   *\n *   Written by Nicolas Pitre <nico@marvell.com>                           *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_SEMIHOSTING_COMMON_H\n#define OPENOCD_TARGET_SEMIHOSTING_COMMON_H\n\n#include <stdint.h>\n#include <stdbool.h>\n#include <time.h>\n#include \"helper/replacements.h\"\n#include <server/server.h>\n\n/*\n * According to:\n * \"Semihosting for AArch32 and AArch64, Release 2.0\"\n * https://static.docs.arm.com/100863/0200/semihosting.pdf\n * from ARM Ltd.\n *\n * The available semihosting operation numbers passed in R0 are allocated\n * as follows:\n * - 0x00-0x31 Used by ARM.\n * - 0x32-0xFF Reserved for future use by ARM.\n * - 0x100-0x1FF Reserved for user applications. These are not used by ARM.\n *   However, if you are writing your own SVC operations, you are advised\n *   to use a different SVC number rather than using the semihosted\n *   SVC number and these operation type numbers.\n * - 0x200-0xFFFFFFFF Undefined and currently unused. It is recommended\n *   that you do not use these.\n */\n\nenum semihosting_operation_numbers {\n\t/*\n\t * ARM semihosting operations, in lexicographic order.\n\t */\n\tSEMIHOSTING_ENTER_SVC = 0x17,\t/* DEPRECATED */\n\n\tSEMIHOSTING_SYS_CLOSE = 0x02,\n\tSEMIHOSTING_SYS_CLOCK = 0x10,\n\tSEMIHOSTING_SYS_ELAPSED = 0x30,\n\tSEMIHOSTING_SYS_ERRNO = 0x13,\n\tSEMIHOSTING_SYS_EXIT = 0x18,\n\tSEMIHOSTING_SYS_EXIT_EXTENDED = 0x20,\n\tSEMIHOSTING_SYS_FLEN = 0x0C,\n\tSEMIHOSTING_SYS_GET_CMDLINE = 0x15,\n\tSEMIHOSTING_SYS_HEAPINFO = 0x16,\n\tSEMIHOSTING_SYS_ISERROR = 0x08,\n\tSEMIHOSTING_SYS_ISTTY = 0x09,\n\tSEMIHOSTING_SYS_OPEN = 0x01,\n\tSEMIHOSTING_SYS_READ = 0x06,\n\tSEMIHOSTING_SYS_READC = 0x07,\n\tSEMIHOSTING_SYS_REMOVE = 0x0E,\n\tSEMIHOSTING_SYS_RENAME = 0x0F,\n\tSEMIHOSTING_SYS_SEEK = 0x0A,\n\tSEMIHOSTING_SYS_SYSTEM = 0x12,\n\tSEMIHOSTING_SYS_TICKFREQ = 0x31,\n\tSEMIHOSTING_SYS_TIME = 0x11,\n\tSEMIHOSTING_SYS_TMPNAM = 0x0D,\n\tSEMIHOSTING_SYS_WRITE = 0x05,\n\tSEMIHOSTING_SYS_WRITEC = 0x03,\n\tSEMIHOSTING_SYS_WRITE0 = 0x04,\n\tSEMIHOSTING_ARM_RESERVED_START = 0x32,\n\tSEMIHOSTING_ARM_RESERVED_END = 0xFF,\n\tSEMIHOSTING_USER_CMD_0X100 = 0x100, /* First user cmd op code */\n\tSEMIHOSTING_USER_CMD_0X107 = 0x107, /* Last supported user cmd op code */\n\tSEMIHOSTING_USER_CMD_0X1FF = 0x1FF, /* Last user cmd op code */\n};\n\n/** Maximum allowed Tcl command segment length in bytes*/\n#define SEMIHOSTING_MAX_TCL_COMMAND_FIELD_LENGTH (1024 * 1024)\n\n/*\n * Codes used by SEMIHOSTING_SYS_EXIT (formerly\n * SEMIHOSTING_REPORT_EXCEPTION).\n * On 64-bits, the exit code is passed explicitly.\n */\nenum semihosting_reported_exceptions {\n\t/* On 32 bits, use it for exit(0) */\n\tADP_STOPPED_APPLICATION_EXIT = ((2 << 16) + 38),\n\t/* On 32 bits, use it for exit(1) */\n\tADP_STOPPED_RUN_TIME_ERROR = ((2 << 16) + 35),\n};\n\nenum semihosting_redirect_config {\n\tSEMIHOSTING_REDIRECT_CFG_NONE,\n\tSEMIHOSTING_REDIRECT_CFG_DEBUG,\n\tSEMIHOSTING_REDIRECT_CFG_STDIO,\n\tSEMIHOSTING_REDIRECT_CFG_ALL,\n};\n\nenum semihosting_result {\n\tSEMIHOSTING_NONE,\t\t/* Not halted for a semihosting call. */\n\tSEMIHOSTING_HANDLED,\t/* Call handled, and target was resumed. */\n\tSEMIHOSTING_WAITING,\t/* Call handled, target is halted waiting until we can resume. */\n\tSEMIHOSTING_ERROR\t\t/* Something went wrong. */\n};\n\nstruct target;\n\n/*\n * A pointer to this structure was added to the target structure.\n */\nstruct semihosting {\n\n\t/** A flag reporting whether semihosting is active. */\n\tbool is_active;\n\n\t/** Semihosting STDIO file descriptors */\n\tint stdin_fd, stdout_fd, stderr_fd;\n\n\t/** redirection configuration, NONE by default */\n\tenum semihosting_redirect_config redirect_cfg;\n\n\t/** Handle to redirect semihosting print via tcp */\n\tstruct connection *tcp_connection;\n\n\t/** A flag reporting whether semihosting fileio is active. */\n\tbool is_fileio;\n\n\t/** A flag reporting whether semihosting fileio operation is active. */\n\tbool hit_fileio;\n\n\t/** Most are resumable, except the two exit calls. */\n\tbool is_resumable;\n\n\t/**\n\t * When SEMIHOSTING_SYS_EXIT is called outside a debug session,\n\t * things are simple, the openocd process calls exit() and passes\n\t * the value returned by the target.\n\t * When SEMIHOSTING_SYS_EXIT is called during a debug session,\n\t * by default execution returns to the debugger, leaving the\n\t * debugger in a HALT state, similar to the state entered when\n\t * encountering a break.\n\t * In some use cases, it is useful to have SEMIHOSTING_SYS_EXIT\n\t * return normally, as any semihosting call, and do not break\n\t * to the debugger.\n\t * The standard allows this to happen, but the condition\n\t * to trigger it is a bit obscure (\"by performing an RDI_Execute\n\t * request or equivalent\").\n\t *\n\t * To make the SEMIHOSTING_SYS_EXIT call return normally, enable\n\t * this variable via the dedicated command (default: disabled).\n\t */\n\tbool has_resumable_exit;\n\n\t/** The Target (hart) word size; 8 for 64-bits targets. */\n\tsize_t word_size_bytes;\n\n\t/** The current semihosting operation (R0 on ARM). */\n\tint op;\n\n\t/** The current semihosting parameter (R1 or ARM). */\n\tuint64_t param;\n\n\t/**\n\t * The current semihosting result to be returned to the application.\n\t * Usually 0 for success, -1 for error,\n\t * but sometimes a useful value, even a pointer.\n\t */\n\tint64_t result;\n\n\t/** The value to be returned by semihosting SYS_ERRNO request. */\n\tint sys_errno;\n\n\t/** The semihosting command line to be passed to the target. */\n\tchar *cmdline;\n\n\t/** The current time when 'execution starts' */\n\tclock_t setup_time;\n\n\t/** Base directory for semihosting I/O operations. */\n\tchar *basedir;\n\n\t/**\n\t * Target's extension of semihosting user commands.\n\t * @returns ERROR_NOT_IMPLEMENTED when user command is not handled, otherwise\n\t * sets semihosting->result and semihosting->sys_errno and returns ERROR_OK.\n\t */\n\tint (*user_command_extension)(struct target *target);\n\n\tint (*setup)(struct target *target, int enable);\n\tint (*post_result)(struct target *target);\n};\n\n/**\n * @brief Convert the syscall opcode to a human-readable string\n * @param[in] opcode Syscall opcode\n * @return String representation of syscall opcode\n */\nconst char *semihosting_opcode_to_str(uint64_t opcode);\n\nint semihosting_common_init(struct target *target, void *setup,\n\tvoid *post_result);\nint semihosting_common(struct target *target);\n\n/* utility functions which may also be used by semihosting extensions (custom vendor-defined syscalls) */\nint semihosting_read_fields(struct target *target, size_t number,\n\tuint8_t *fields);\nint semihosting_write_fields(struct target *target, size_t number,\n\tuint8_t *fields);\nuint64_t semihosting_get_field(struct target *target, size_t index,\n\tuint8_t *fields);\nvoid semihosting_set_field(struct target *target, uint64_t value,\n\tsize_t index,\n\tuint8_t *fields);\n\nextern const struct command_registration semihosting_common_handlers[];\n\n#endif\t/* OPENOCD_TARGET_SEMIHOSTING_COMMON_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/smp.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *                                                                         *\n * Copyright (C) ST-Ericsson SA 2011                                       *\n * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson.   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"server/server.h\"\n\n#include \"target/target.h\"\n\n#include \"server/gdb_server.h\"\n#include \"smp.h\"\n#include \"helper/binarybuffer.h\"\n\n/* DEPRECATED: gdb_read_smp_packet/gdb_write_smp_packet to be removed      */\n/*  implementation of new packet in gdb interface for smp feature          */\n/*                                                                         */\n/*   j : smp  status request                                               */\n/*   J : smp  set request                                                  */\n/*                                                                         */\n/*   jc :read core id displayed by gdb connection                          */\n/*   reply XXXXXXXX core id is int32_t , 8 hex digits                      */\n/*                                                                         */\n/*   Reply ENN error not supported (target not smp)                        */\n/*                                                                         */\n/*   JcXX  set core id displayed at next gdb continue                      */\n/*   maximum 8 bytes described core id int32_t (8 hex digits)              */\n/*  (core id -1 , reserved for returning to normal continue mode) */\n/*  Reply ENN error not supported(target not smp,core id out of range)     */\n/*  Reply OK : for success                                                 */\n/*                                                                         */\n/*  handling of this packet within gdb can be done by the creation         */\n/*  internal variable by mean of function allocate_computed_value          */\n/*  set $_core 1 => Jc01 packet is sent                                    */\n/*  print $_core => jc packet is sent and result is affected in $          */\n/*  Another way to test this packet is the usage of maintenance packet     */\n/*  maint packet Jc01                                                      */\n/*  maint packet jc                                                        */\n\n/* packet j :smp status request */\n#define DEPRECATED_MSG \"DEPRECATED: This method is deprecated in favor of the hwthread pseudo RTOS\"\nint gdb_read_smp_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tint retval = ERROR_OK;\n\n\tLOG_WARNING(DEPRECATED_MSG);\n\n\tif (target->smp) {\n\t\tif (strncmp(packet, \"jc\", 2) == 0) {\n\t\t\tconst uint32_t len = sizeof(target->gdb_service->core[0]);\n\t\t\tchar hex_buffer[len * 2 + 1];\n\t\t\tuint8_t buffer[len];\n\t\t\tbuf_set_u32(buffer, 0, len * 8, target->gdb_service->core[0]);\n\t\t\tsize_t pkt_len = hexify(hex_buffer, buffer, sizeof(buffer),\n\t\t\t\tsizeof(hex_buffer));\n\n\t\t\tretval = gdb_put_packet(connection, hex_buffer, pkt_len);\n\t\t}\n\t} else\n\t\tretval = gdb_put_packet(connection, \"E01\", 3);\n\treturn retval;\n}\n\n/* J :  smp set request */\nint gdb_write_smp_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size)\n{\n\tstruct target *target = get_target_from_connection(connection);\n\tchar *separator;\n\tint coreid = 0;\n\tint retval = ERROR_OK;\n\n\tLOG_WARNING(DEPRECATED_MSG);\n\n\t/* skip command character */\n\tif (target->smp) {\n\t\tif (strncmp(packet, \"Jc\", 2) == 0) {\n\t\t\tpacket += 2;\n\t\t\tcoreid = strtoul(packet, &separator, 16);\n\t\t\ttarget->gdb_service->core[1] = coreid;\n\t\t\tretval = gdb_put_packet(connection, \"OK\", 2);\n\t\t}\n\t} else\n\t\tretval = gdb_put_packet(connection, \"E01\", 3);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(default_handle_smp_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct target_list *head;\n\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!CMD_ARGC) {\n\t\tcommand_print(CMD, \"%s\", target->smp ? \"on\" : \"off\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!strcmp(CMD_ARGV[0], \"on\")) {\n\t\tforeach_smp_target(head, target->smp_targets)\n\t\t\thead->target->smp = 1;\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!strcmp(CMD_ARGV[0], \"off\")) {\n\t\tforeach_smp_target(head, target->smp_targets)\n\t\t\thead->target->smp = 0;\n\n\t\t/* fixes the target display to the debugger */\n\t\tif (!list_empty(target->smp_targets))\n\t\t\ttarget->gdb_service->target = target;\n\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HANDLER(handle_smp_gdb_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = ERROR_OK;\n\tif (!list_empty(target->smp_targets)) {\n\t\tif (CMD_ARGC == 1) {\n\t\t\tint coreid = 0;\n\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\ttarget->gdb_service->core[1] = coreid;\n\n\t\t}\n\t\tcommand_print(CMD, \"gdb coreid  %\" PRId32 \" -> %\" PRId32, target->gdb_service->core[0]\n\t\t\t, target->gdb_service->core[1]);\n\t}\n\treturn ERROR_OK;\n}\n\nconst struct command_registration smp_command_handlers[] = {\n\t{\n\t\t.name = \"smp\",\n\t\t.handler = default_handle_smp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"smp handling\",\n\t\t.usage = \"[on|off]\",\n\t},\n\t{\n\t\t.name = \"smp_gdb\",\n\t\t.handler = handle_smp_gdb_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display/fix current core played to gdb\",\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/smp.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *                                                                         *\n * Copyright (C) ST-Ericsson SA 2011                                       *\n * Author: Michel Jaouen <michel.jaouen@stericsson.com> for ST-Ericsson.   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_SMP_H\n#define OPENOCD_TARGET_SMP_H\n\n#include <helper/list.h>\n#include \"server/server.h\"\n\n#define foreach_smp_target(pos, head) \\\n\tlist_for_each_entry(pos, head, lh)\n\n#define foreach_smp_target_direction(forward, pos, head) \\\n\tlist_for_each_entry_direction(forward, pos, head, lh)\n\nextern const struct command_registration smp_command_handlers[];\n\n/* DEPRECATED */\nint gdb_read_smp_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size);\n/* DEPRECATED */\nint gdb_write_smp_packet(struct connection *connection,\n\t\tchar const *packet, int packet_size);\n\n#endif /* OPENOCD_TARGET_SMP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/startup.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Defines basic Tcl procs for OpenOCD target module\n\nproc new_target_name { } {\n\treturn [target number [expr {[target count] - 1}]]\n}\n\nglobal in_process_reset\nset in_process_reset 0\n\n# Catch reset recursion\nproc ocd_process_reset { MODE } {\n\tglobal in_process_reset\n\tif {$in_process_reset} {\n\t\tset in_process_reset 0\n\t\treturn -code error \"'reset' can not be invoked recursively\"\n\t}\n\n\tset in_process_reset 1\n\tset success [expr {[catch {ocd_process_reset_inner $MODE} result] == 0}]\n\tset in_process_reset 0\n\n\tif {$success} {\n\t\treturn $result\n\t} else {\n\t\treturn -code error $result\n\t}\n}\n\nproc ocd_process_reset_inner { MODE } {\n\tset targets [target names]\n\n\t# If this target must be halted...\n\tswitch $MODE {\n\t\thalt -\n\t\tinit {\n\t\t\tset halt 1\n\t\t}\n\t\trun {\n\t\t\tset halt 0\n\t\t}\n\t\tdefault {\n\t\t\treturn -code error \"Invalid mode: $MODE, must be one of: halt, init, or run\";\n\t\t}\n\t}\n\n\t# Target event handlers *might* change which TAPs are enabled\n\t# or disabled, so we fire all of them.  But don't issue any\n\t# target \"arp_*\" commands, which may issue JTAG transactions,\n\t# unless we know the underlying TAP is active.\n\t#\n\t# NOTE:  ARP == \"Advanced Reset Process\" ... \"advanced\" is\n\t# relative to a previous restrictive scheme\n\n\tforeach t $targets {\n\t\t# New event script.\n\t\t$t invoke-event reset-start\n\t}\n\n\t# Use TRST or TMS/TCK operations to reset all the tap controllers.\n\t# TAP reset events get reported; they might enable some taps.\n\tinit_reset $MODE\n\n\t# Examine all targets on enabled taps.\n\tforeach t $targets {\n\t\tif {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {\n\t\t\t$t invoke-event examine-start\n\t\t\tset err [catch \"$t arp_examine allow-defer\"]\n\t\t\tif { $err } {\n\t\t\t\t$t invoke-event examine-fail\n\t\t\t} else {\n\t\t\t\t$t invoke-event examine-end\n\t\t\t}\n\t\t}\n\t}\n\n\t# Assert SRST, and report the pre/post events.\n\t# Note:  no target sees SRST before \"pre\" or after \"post\".\n\tforeach t $targets {\n\t\t$t invoke-event reset-assert-pre\n\t}\n\tforeach t $targets {\n\t\t# C code needs to know if we expect to 'halt'\n\t\tif {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {\n\t\t\t$t arp_reset assert $halt\n\t\t}\n\t}\n\tforeach t $targets {\n\t\t$t invoke-event reset-assert-post\n\t}\n\n\t# Now de-assert SRST, and report the pre/post events.\n\t# Note:  no target sees !SRST before \"pre\" or after \"post\".\n\tforeach t $targets {\n\t\t$t invoke-event reset-deassert-pre\n\t}\n\tforeach t $targets {\n\t\t# Again, de-assert code needs to know if we 'halt'\n\t\tif {![using_jtag] || [jtag tapisenabled [$t cget -chain-position]]} {\n\t\t\t$t arp_reset deassert $halt\n\t\t}\n\t}\n\tforeach t $targets {\n\t\t$t invoke-event reset-deassert-post\n\t}\n\n\t# Pass 1 - Now wait for any halt (requested as part of reset\n\t# assert/deassert) to happen.  Ideally it takes effect without\n\t# first executing any instructions.\n\tif { $halt } {\n\t\tforeach t $targets {\n\t\t\tif {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif { ![$t was_examined] } {\n\t\t\t\t# don't wait for targets where examination is deferred\n\t\t\t\t# they can not be halted anyway at this point\n\t\t\t\tif { [$t examine_deferred] } {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t# try to re-examine or target state will be unknown\n\t\t\t\t$t invoke-event examine-start\n\t\t\t\tset err [catch \"$t arp_examine allow-defer\"]\n\t\t\t\tif { $err } {\n\t\t\t\t\t$t invoke-event examine-fail\n\t\t\t\t\treturn -code error [format \"TARGET: %s - Not examined\" $t]\n\t\t\t\t} else {\n\t\t\t\t\t$t invoke-event examine-end\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# Wait up to 1 second for target to halt. Why 1sec? Cause\n\t\t\t# the JTAG tap reset signal might be hooked to a slow\n\t\t\t# resistor/capacitor circuit - and it might take a while\n\t\t\t# to charge\n\n\t\t\t# Catch, but ignore any errors.\n\t\t\tcatch { $t arp_waitstate halted 1000 }\n\n\t\t\t# Did we succeed?\n\t\t\tset s [$t curstate]\n\n\t\t\tif { $s != \"halted\" } {\n\t\t\t\treturn -code error [format \"TARGET: %s - Not halted\" $t]\n\t\t\t}\n\t\t}\n\t}\n\n\t#Pass 2 - if needed \"init\"\n\tif { $MODE == \"init\" } {\n\t\tforeach t $targets {\n\t\t\tif {[using_jtag] && ![jtag tapisenabled [$t cget -chain-position]]} {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t# don't wait for targets where examination is deferred\n\t\t\t# they can not be halted anyway at this point\n\t\t\tif { ![$t was_examined] && [$t examine_deferred] } {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tset err [catch \"$t arp_waitstate halted 5000\"]\n\t\t\t# Did it halt?\n\t\t\tif { $err == 0 } {\n\t\t\t\t$t invoke-event reset-init\n\t\t\t}\n\t\t}\n\t}\n\n\tforeach t $targets {\n\t\t$t invoke-event reset-end\n\t}\n}\n\nproc using_jtag {} {\n\tset _TRANSPORT [ transport select ]\n\texpr { [ string first \"jtag\" $_TRANSPORT ] != -1 }\n}\n\nproc using_swd {} {\n\tset _TRANSPORT [ transport select ]\n\texpr { [ string first \"swd\" $_TRANSPORT ] != -1 }\n}\n\nproc using_hla {} {\n\tset _TRANSPORT [ transport select ]\n\texpr { [ string first \"hla\" $_TRANSPORT ] != -1 }\n}\n\n#########\n\n# Target/chain configuration scripts can either execute commands directly\n# or define a procedure which is executed once all configuration\n# scripts have completed.\n#\n# By default(classic) the config scripts will set up the target configuration\nproc init_targets {} {\n}\n\nproc set_default_target_event {t e s} {\n\tif {[$t cget -event $e] == \"\"} {\n\t\t$t configure -event $e $s\n\t}\n}\n\nproc init_target_events {} {\n\tset targets [target names]\n\n\tforeach t $targets {\n\t\tset_default_target_event $t gdb-flash-erase-start \"reset init\"\n\t\tset_default_target_event $t gdb-flash-write-end \"reset halt\"\n\t\tset_default_target_event $t gdb-attach \"halt 1000\"\n\t}\n}\n\n# Additionally board config scripts can define a procedure init_board that will be executed after init and init_targets\nproc init_board {} {\n}\n\nproc mem2array {arrayname bitwidth address count {phys \"\"}} {\n\techo \"DEPRECATED! use 'read_memory' not 'mem2array'\"\n\n\tupvar $arrayname $arrayname\n\tset $arrayname \"\"\n\tset i 0\n\n\tforeach elem [read_memory $address $bitwidth $count {*}$phys] {\n\t\tset ${arrayname}($i) $elem\n\t\tincr i\n\t}\n}\n\nproc array2mem {arrayname bitwidth address count {phys \"\"}} {\n\techo \"DEPRECATED! use 'write_memory' not 'array2mem'\"\n\n\tupvar $arrayname $arrayname\n\tset data \"\"\n\n\tfor {set i 0} {$i < $count} {incr i} {\n\t\tlappend data [expr $${arrayname}($i)]\n\t}\n\n\twrite_memory $address $bitwidth $data {*}$phys\n}\n\n# smp_on/smp_off were already DEPRECATED in v0.11.0 through http://openocd.zylin.com/4615\nlappend _telnet_autocomplete_skip \"aarch64 smp_on\"\nproc \"aarch64 smp_on\" {args} {\n\techo \"DEPRECATED! use 'aarch64 smp on' not 'aarch64 smp_on'\"\n\teval aarch64 smp on $args\n}\n\nlappend _telnet_autocomplete_skip \"aarch64 smp_off\"\nproc \"aarch64 smp_off\" {args} {\n\techo \"DEPRECATED! use 'aarch64 smp off' not 'aarch64 smp_off'\"\n\teval aarch64 smp off $args\n}\n\nlappend _telnet_autocomplete_skip \"cortex_a smp_on\"\nproc \"cortex_a smp_on\" {args} {\n\techo \"DEPRECATED! use 'cortex_a smp on' not 'cortex_a smp_on'\"\n\teval cortex_a smp on $args\n}\n\nlappend _telnet_autocomplete_skip \"cortex_a smp_off\"\nproc \"cortex_a smp_off\" {args} {\n\techo \"DEPRECATED! use 'cortex_a smp off' not 'cortex_a smp_off'\"\n\teval cortex_a smp off $args\n}\n\nlappend _telnet_autocomplete_skip \"mips_m4k smp_on\"\nproc \"mips_m4k smp_on\" {args} {\n\techo \"DEPRECATED! use 'mips_m4k smp on' not 'mips_m4k smp_on'\"\n\teval mips_m4k smp on $args\n}\n\nlappend _telnet_autocomplete_skip \"mips_m4k smp_off\"\nproc \"mips_m4k smp_off\" {args} {\n\techo \"DEPRECATED! use 'mips_m4k smp off' not 'mips_m4k smp_off'\"\n\teval mips_m4k smp off $args\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/stm8.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n*   OpenOCD STM8 target driver\n*   Copyright (C) 2017  Ake Rehnman\n*   ake.rehnman(at)gmail.com\n*/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"hello.h\"\n#include \"jtag/interface.h\"\n#include \"jtag/jtag.h\"\n#include \"jtag/swim.h\"\n#include \"register.h\"\n#include \"breakpoints.h\"\n#include \"algorithm.h\"\n#include \"stm8.h\"\n\nstatic struct reg_cache *stm8_build_reg_cache(struct target *target);\nstatic int stm8_read_core_reg(struct target *target, unsigned int num);\nstatic int stm8_write_core_reg(struct target *target, unsigned int num);\nstatic int stm8_save_context(struct target *target);\nstatic void stm8_enable_breakpoints(struct target *target);\nstatic int stm8_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\nstatic int stm8_set_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\nstatic void stm8_enable_watchpoints(struct target *target);\nstatic int stm8_unset_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint);\nstatic int (*adapter_speed)(int speed);\nextern struct adapter_driver *adapter_driver;\n\nstatic const struct {\n\tunsigned id;\n\tconst char *name;\n\tconst uint8_t bits;\n\tenum reg_type type;\n\tconst char *group;\n\tconst char *feature;\n\tint flag;\n} stm8_regs[] = {\n\t{  0,  \"pc\", 32, REG_TYPE_UINT32, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n\t{  1,  \"a\", 8, REG_TYPE_UINT8, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n\t{  2,  \"x\", 16, REG_TYPE_UINT16, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n\t{  3,  \"y\", 16, REG_TYPE_UINT16, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n\t{  4,  \"sp\", 16, REG_TYPE_UINT16, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n\t{  5,  \"cc\", 8, REG_TYPE_UINT8, \"general\", \"org.gnu.gdb.stm8.core\", 0 },\n};\n\n#define STM8_NUM_REGS ARRAY_SIZE(stm8_regs)\n#define STM8_PC 0\n#define STM8_A 1\n#define STM8_X 2\n#define STM8_Y 3\n#define STM8_SP 4\n#define STM8_CC 5\n\n#define CC_I0 0x8\n#define CC_I1 0x20\n\n#define DM_REGS 0x7f00\n#define DM_REG_A 0x7f00\n#define DM_REG_PC 0x7f01\n#define DM_REG_X 0x7f04\n#define DM_REG_Y 0x7f06\n#define DM_REG_SP 0x7f08\n#define DM_REG_CC 0x7f0a\n\n#define DM_BKR1E 0x7f90\n#define DM_BKR2E 0x7f93\n#define DM_CR1 0x7f96\n#define DM_CR2 0x7f97\n#define DM_CSR1 0x7f98\n#define DM_CSR2 0x7f99\n\n#define STE 0x40\n#define STF 0x20\n#define RST 0x10\n#define BRW 0x08\n#define BK2F 0x04\n#define BK1F 0x02\n\n#define SWBRK 0x20\n#define SWBKF 0x10\n#define STALL 0x08\n#define FLUSH 0x01\n\n#define FLASH_CR1_STM8S 0x505A\n#define FLASH_CR2_STM8S 0x505B\n#define FLASH_NCR2_STM8S 0x505C\n#define FLASH_IAPSR_STM8S 0x505F\n#define FLASH_PUKR_STM8S 0x5062\n#define FLASH_DUKR_STM8S 0x5064\n\n#define FLASH_CR1_STM8L 0x5050\n#define FLASH_CR2_STM8L 0x5051\n#define FLASH_NCR2_STM8L 0\n#define FLASH_PUKR_STM8L 0x5052\n#define FLASH_DUKR_STM8L 0x5053\n#define FLASH_IAPSR_STM8L 0x5054\n\n/* FLASH_IAPSR */\n#define HVOFF 0x40\n#define DUL 0x08\n#define EOP 0x04\n#define PUL 0x02\n#define WR_PG_DIS 0x01\n\n/* FLASH_CR2 */\n#define OPT 0x80\n#define WPRG 0x40\n#define ERASE 0x20\n#define FPRG 0x10\n#define PRG 0x01\n\n/* SWIM_CSR */\n#define SAFE_MASK 0x80\n#define NO_ACCESS 0x40\n#define SWIM_DM 0x20\n#define HS 0x10\n#define OSCOFF 0x08\n#define SWIM_RST 0x04\n#define HSIT 0x02\n#define PRI 0x01\n\n#define SWIM_CSR 0x7f80\n\n#define STM8_BREAK 0x8B\n\nenum mem_type {\n\tRAM,\n\tFLASH,\n\tEEPROM,\n\tOPTION\n};\n\nstruct stm8_algorithm {\n\tint common_magic;\n};\n\nstruct stm8_core_reg {\n\tuint32_t num;\n\tstruct target *target;\n};\n\nenum hw_break_type {\n\t/* break on execute */\n\tHWBRK_EXEC,\n\t/* break on read */\n\tHWBRK_RD,\n\t/* break on write */\n\tHWBRK_WR,\n\t/* break on read, write and execute */\n\tHWBRK_ACC\n};\n\nstruct stm8_comparator {\n\tbool used;\n\tuint32_t bp_value;\n\tuint32_t reg_address;\n\tenum hw_break_type type;\n};\n\nstatic int stm8_adapter_read_memory(struct target *target,\n\t\tuint32_t addr, int size, int count, void *buf)\n{\n\treturn swim_read_mem(addr, size, count, buf);\n}\n\nstatic int stm8_adapter_write_memory(struct target *target,\n\t\tuint32_t addr, int size, int count, const void *buf)\n{\n\treturn swim_write_mem(addr, size, count, buf);\n}\n\nstatic int stm8_write_u8(struct target *target,\n\t\tuint32_t addr, uint8_t val)\n{\n\tuint8_t buf[1];\n\n\tbuf[0] = val;\n\treturn swim_write_mem(addr, 1, 1, buf);\n}\n\nstatic int stm8_read_u8(struct target *target,\n\t\tuint32_t addr, uint8_t *val)\n{\n\treturn swim_read_mem(addr, 1, 1, val);\n}\n\n/*\n\t<enable == 0> Disables interrupts.\n\tIf interrupts are enabled they are masked and the cc register\n\tis saved.\n\n\t<enable == 1> Enables interrupts.\n\tEnable interrupts is actually restoring I1 I0 state from previous\n\tcall with enable == 0. Note that if stepping and breaking on a sim\n\tinstruction will NOT work since the interrupt flags are restored on\n\tdebug_entry. We don't have any way for the debugger to exclusively\n\tdisable the interrupts\n*/\nstatic int stm8_enable_interrupts(struct target *target, int enable)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tuint8_t cc;\n\n\tif (enable) {\n\t\tif (!stm8->cc_valid)\n\t\t\treturn ERROR_OK; /* cc was not stashed */\n\t\t/* fetch current cc */\n\t\tstm8_read_u8(target, DM_REG_CC, &cc);\n\t\t/* clear I1 I0 */\n\t\tcc &= ~(CC_I0 + CC_I1);\n\t\t/* restore I1 & I0 from stash*/\n\t\tcc |= (stm8->cc & (CC_I0+CC_I1));\n\t\t/* update current cc */\n\t\tstm8_write_u8(target, DM_REG_CC, cc);\n\t\tstm8->cc_valid = false;\n\t} else {\n\t\tstm8_read_u8(target, DM_REG_CC, &cc);\n\t\tif ((cc & CC_I0) && (cc & CC_I1))\n\t\t\treturn ERROR_OK; /* interrupts already masked */\n\t\t/* stash cc */\n\t\tstm8->cc = cc;\n\t\tstm8->cc_valid = true;\n\t\t/* mask interrupts (disable) */\n\t\tcc |= (CC_I0 + CC_I1);\n\t\tstm8_write_u8(target, DM_REG_CC, cc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_set_hwbreak(struct target *target,\n\t\tstruct stm8_comparator comparator_list[])\n{\n\tuint8_t buf[3];\n\tint i, ret;\n\n\t/* Refer to Table 4 in UM0470 */\n\tuint8_t bc = 0x5;\n\tuint8_t bir = 0;\n\tuint8_t biw = 0;\n\n\tuint32_t data;\n\tuint32_t addr;\n\n\tif (!comparator_list[0].used) {\n\t\tcomparator_list[0].type = HWBRK_EXEC;\n\t\tcomparator_list[0].bp_value = -1;\n\t}\n\n\tif (!comparator_list[1].used) {\n\t\tcomparator_list[1].type = HWBRK_EXEC;\n\t\tcomparator_list[1].bp_value = -1;\n\t}\n\n\tif ((comparator_list[0].type == HWBRK_EXEC)\n\t\t\t&& (comparator_list[1].type == HWBRK_EXEC)) {\n\t\tcomparator_list[0].reg_address = 0;\n\t\tcomparator_list[1].reg_address = 1;\n\t}\n\n\tif ((comparator_list[0].type == HWBRK_EXEC)\n\t\t\t&& (comparator_list[1].type != HWBRK_EXEC)) {\n\t\tcomparator_list[0].reg_address = 0;\n\t\tcomparator_list[1].reg_address = 1;\n\t\tswitch (comparator_list[1].type) {\n\t\tcase HWBRK_RD:\n\t\t\tbir = 1;\n\t\t\tbreak;\n\t\tcase HWBRK_WR:\n\t\t\tbiw = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbir = 1;\n\t\t\tbiw = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif ((comparator_list[1].type == HWBRK_EXEC)\n\t\t\t&& (comparator_list[0].type != HWBRK_EXEC)) {\n\t\tcomparator_list[0].reg_address = 1;\n\t\tcomparator_list[1].reg_address = 0;\n\t\tswitch (comparator_list[0].type) {\n\t\tcase HWBRK_RD:\n\t\t\tbir = 1;\n\t\t\tbreak;\n\t\tcase HWBRK_WR:\n\t\t\tbiw = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbir = 1;\n\t\t\tbiw = 1;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif ((comparator_list[0].type != HWBRK_EXEC)\n\t\t\t&& (comparator_list[1].type != HWBRK_EXEC)) {\n\t\tif (comparator_list[0].type != comparator_list[1].type) {\n\t\t\tLOG_ERROR(\"data hw breakpoints must be of same type\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t}\n\n\tfor (i = 0; i < 2; i++) {\n\t\tdata = comparator_list[i].bp_value;\n\t\taddr = comparator_list[i].reg_address;\n\n\t\tbuf[0] = data >> 16;\n\t\tbuf[1] = data >> 8;\n\t\tbuf[2] = data;\n\n\t\tif (addr == 0) {\n\t\t\tret = stm8_adapter_write_memory(target, DM_BKR1E, 1, 3, buf);\n\t\t\tLOG_DEBUG(\"DM_BKR1E=%\" PRIx32, data);\n\t\t} else if (addr == 1) {\n\t\t\tret = stm8_adapter_write_memory(target, DM_BKR2E, 1, 3, buf);\n\t\t\tLOG_DEBUG(\"DM_BKR2E=%\" PRIx32, data);\n\t\t} else {\n\t\t\tLOG_DEBUG(\"addr=%\" PRIu32, addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tret = stm8_write_u8(target, DM_CR1,\n\t\t\t(bc << 3) + (bir << 2) + (biw << 1));\n\t\tLOG_DEBUG(\"DM_CR1=%\" PRIx8, buf[0]);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t}\n\treturn ERROR_OK;\n}\n\n/* read DM control and status regs */\nstatic int stm8_read_dm_csrx(struct target *target, uint8_t *csr1,\n\t\tuint8_t *csr2)\n{\n\tint ret;\n\tuint8_t buf[2];\n\n\tret =  stm8_adapter_read_memory(target, DM_CSR1, 1, sizeof(buf), buf);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tif (csr1)\n\t\t*csr1 = buf[0];\n\tif (csr2)\n\t\t*csr2 = buf[1];\n\treturn ERROR_OK;\n}\n\n/* set or clear the single step flag in DM */\nstatic int stm8_config_step(struct target *target, int enable)\n{\n\tint ret;\n\tuint8_t csr1, csr2;\n\n\tret = stm8_read_dm_csrx(target, &csr1, &csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tif (enable)\n\t\tcsr1 |= STE;\n\telse\n\t\tcsr1 &= ~STE;\n\n\tret =  stm8_write_u8(target, DM_CSR1, csr1);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\treturn ERROR_OK;\n}\n\n/* set the stall flag in DM */\nstatic int stm8_debug_stall(struct target *target)\n{\n\tint ret;\n\tuint8_t csr1, csr2;\n\n\tret = stm8_read_dm_csrx(target, &csr1, &csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tcsr2 |= STALL;\n\tret =  stm8_write_u8(target, DM_CSR2, csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\treturn ERROR_OK;\n}\n\nstatic int stm8_configure_break_unit(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (stm8->bp_scanned)\n\t\treturn ERROR_OK;\n\n\tstm8->num_hw_bpoints = 2;\n\tstm8->num_hw_bpoints_avail = stm8->num_hw_bpoints;\n\n\tstm8->hw_break_list = calloc(stm8->num_hw_bpoints,\n\t\tsizeof(struct stm8_comparator));\n\n\tstm8->hw_break_list[0].reg_address = 0;\n\tstm8->hw_break_list[1].reg_address = 1;\n\n\tLOG_DEBUG(\"hw breakpoints: numinst %i numdata %i\", stm8->num_hw_bpoints,\n\t\tstm8->num_hw_bpoints);\n\n\tstm8->bp_scanned = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_examine_debug_reason(struct target *target)\n{\n\tint retval;\n\tuint8_t csr1, csr2;\n\n\tretval = stm8_read_dm_csrx(target, &csr1, &csr2);\n\tif (retval == ERROR_OK)\n\t\tLOG_DEBUG(\"csr1 = 0x%02X csr2 = 0x%02X\", csr1, csr2);\n\n\tif ((target->debug_reason != DBG_REASON_DBGRQ)\n\t\t&& (target->debug_reason != DBG_REASON_SINGLESTEP)) {\n\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (csr1 & RST)\n\t\t\t/* halted on reset */\n\t\t\ttarget->debug_reason = DBG_REASON_UNDEFINED;\n\n\t\tif (csr1 & (BK1F+BK2F))\n\t\t\t/* we have halted on a  breakpoint (or wp)*/\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\n\t\tif (csr2 & SWBKF)\n\t\t\t/* we have halted on a  breakpoint */\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_debug_entry(struct target *target)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\t/* restore interrupts */\n\tstm8_enable_interrupts(target, 1);\n\n\tstm8_save_context(target);\n\n\t/* make sure stepping disabled STE bit in CSR1 cleared */\n\tstm8_config_step(target, 0);\n\n\t/* attempt to find halt reason */\n\tstm8_examine_debug_reason(target);\n\n\tLOG_DEBUG(\"entered debug state at PC 0x%\" PRIx32 \", target->state: %s\",\n\t\tbuf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32),\n\t\ttarget_state_name(target));\n\n\treturn ERROR_OK;\n}\n\n/* clear stall flag in DM and flush instruction pipe */\nstatic int stm8_exit_debug(struct target *target)\n{\n\tint ret;\n\tuint8_t csr1, csr2;\n\n\tret = stm8_read_dm_csrx(target, &csr1, &csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\tcsr2 |= FLUSH;\n\tret =  stm8_write_u8(target, DM_CSR2, csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tcsr2 &= ~STALL;\n\tcsr2 |= SWBRK;\n\tret =  stm8_write_u8(target, DM_CSR2, csr2);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\treturn ERROR_OK;\n}\n\nstatic int stm8_read_regs(struct target *target, uint32_t regs[])\n{\n\tint ret;\n\tuint8_t buf[11];\n\n\tret =  stm8_adapter_read_memory(target, DM_REGS, 1, sizeof(buf), buf);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tregs[0] = be_to_h_u24(buf+DM_REG_PC-DM_REGS);\n\tregs[1] = buf[DM_REG_A-DM_REGS];\n\tregs[2] = be_to_h_u16(buf+DM_REG_X-DM_REGS);\n\tregs[3] = be_to_h_u16(buf+DM_REG_Y-DM_REGS);\n\tregs[4] = be_to_h_u16(buf+DM_REG_SP-DM_REGS);\n\tregs[5] = buf[DM_REG_CC-DM_REGS];\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_write_regs(struct target *target, uint32_t regs[])\n{\n\tint ret;\n\tuint8_t buf[11];\n\n\th_u24_to_be(buf+DM_REG_PC-DM_REGS, regs[0]);\n\tbuf[DM_REG_A-DM_REGS] = regs[1];\n\th_u16_to_be(buf+DM_REG_X-DM_REGS, regs[2]);\n\th_u16_to_be(buf+DM_REG_Y-DM_REGS, regs[3]);\n\th_u16_to_be(buf+DM_REG_SP-DM_REGS, regs[4]);\n\tbuf[DM_REG_CC-DM_REGS] = regs[5];\n\n\tret =  stm8_adapter_write_memory(target, DM_REGS, 1, sizeof(buf), buf);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_get_core_reg(struct reg *reg)\n{\n\tint retval;\n\tstruct stm8_core_reg *stm8_reg = reg->arch_info;\n\tstruct target *target = stm8_reg->target;\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tretval = stm8->read_core_reg(target, stm8_reg->num);\n\n\treturn retval;\n}\n\nstatic int stm8_set_core_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct stm8_core_reg *stm8_reg = reg->arch_info;\n\tstruct target *target = stm8_reg->target;\n\tuint32_t value = buf_get_u32(buf, 0, reg->size);\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tbuf_set_u32(reg->value, 0, 32, value);\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_save_context(struct target *target)\n{\n\tunsigned int i;\n\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\t/* read core registers */\n\tstm8_read_regs(target, stm8->core_regs);\n\n\tfor (i = 0; i < STM8_NUM_REGS; i++) {\n\t\tif (!stm8->core_cache->reg_list[i].valid)\n\t\t\tstm8->read_core_reg(target, i);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_restore_context(struct target *target)\n{\n\tunsigned int i;\n\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tfor (i = 0; i < STM8_NUM_REGS; i++) {\n\t\tif (stm8->core_cache->reg_list[i].dirty)\n\t\t\tstm8->write_core_reg(target, i);\n\t}\n\n\t/* write core regs */\n\tstm8_write_regs(target, stm8->core_regs);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_unlock_flash(struct target *target)\n{\n\tuint8_t data[1];\n\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\t/* check if flash is unlocked */\n\tstm8_read_u8(target, stm8->flash_iapsr, data);\n\tif (~data[0] & PUL) {\n\t\t/* unlock flash */\n\t\tstm8_write_u8(target, stm8->flash_pukr, 0x56);\n\t\tstm8_write_u8(target, stm8->flash_pukr, 0xae);\n\t}\n\n\tstm8_read_u8(target, stm8->flash_iapsr, data);\n\tif (~data[0] & PUL)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\nstatic int stm8_unlock_eeprom(struct target *target)\n{\n\tuint8_t data[1];\n\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\t/* check if eeprom is unlocked */\n\tstm8_read_u8(target, stm8->flash_iapsr, data);\n\tif (~data[0] & DUL) {\n\t\t/* unlock eeprom */\n\t\tstm8_write_u8(target, stm8->flash_dukr, 0xae);\n\t\tstm8_write_u8(target, stm8->flash_dukr, 0x56);\n\t}\n\n\tstm8_read_u8(target, stm8->flash_iapsr, data);\n\tif (~data[0] & DUL)\n\t\treturn ERROR_FAIL;\n\treturn ERROR_OK;\n}\n\nstatic int stm8_write_flash(struct target *target, enum mem_type type,\n\t\tuint32_t address,\n\t\tuint32_t size, uint32_t count, uint32_t blocksize_param,\n\t\tconst uint8_t *buffer)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tuint8_t iapsr;\n\tuint8_t opt = 0;\n\tunsigned int i;\n\tuint32_t blocksize = 0;\n\tuint32_t bytecnt;\n\tint res;\n\n\tswitch (type) {\n\t\tcase (FLASH):\n\t\t\tstm8_unlock_flash(target);\n\t\t\tbreak;\n\t\tcase (EEPROM):\n\t\t\tstm8_unlock_eeprom(target);\n\t\t\tbreak;\n\t\tcase (OPTION):\n\t\t\tstm8_unlock_eeprom(target);\n\t\t\topt = OPT;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: wrong mem_type %d\", type);\n\t\t\tassert(0);\n\t}\n\n\tif (size == 2) {\n\t\t/* we don't support short writes */\n\t\tcount = count * 2;\n\t\tsize = 1;\n\t}\n\n\tbytecnt = count * size;\n\n\twhile (bytecnt) {\n\t\tif ((bytecnt >= blocksize_param) && ((address & (blocksize_param-1)) == 0)) {\n\t\t\tif (stm8->flash_cr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_cr2, PRG + opt);\n\t\t\tif (stm8->flash_ncr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_ncr2, ~(PRG + opt));\n\t\t\tblocksize = blocksize_param;\n\t\t} else\n\t\tif ((bytecnt >= 4) && ((address & 0x3) == 0)) {\n\t\t\tif (stm8->flash_cr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_cr2, WPRG + opt);\n\t\t\tif (stm8->flash_ncr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_ncr2, ~(WPRG + opt));\n\t\t\tblocksize = 4;\n\t\t} else\n\t\tif (blocksize != 1) {\n\t\t\tif (stm8->flash_cr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_cr2, opt);\n\t\t\tif (stm8->flash_ncr2)\n\t\t\t\tstm8_write_u8(target, stm8->flash_ncr2, ~opt);\n\t\t\tblocksize = 1;\n\t\t}\n\n\t\tres = stm8_adapter_write_memory(target, address, 1, blocksize, buffer);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\taddress += blocksize;\n\t\tbuffer += blocksize;\n\t\tbytecnt -= blocksize;\n\n\t\t/* lets hang here until end of program (EOP) */\n\t\tfor (i = 0; i < 16; i++) {\n\t\t\tstm8_read_u8(target, stm8->flash_iapsr, &iapsr);\n\t\t\tif (iapsr & EOP)\n\t\t\t\tbreak;\n\t\t\telse\n\t\t\t\tusleep(1000);\n\t\t}\n\t\tif (i == 16)\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* disable write access */\n\tres = stm8_write_u8(target, stm8->flash_iapsr, 0x0);\n\n\tif (res != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_write_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count,\n\t\tconst uint8_t *buffer)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tLOG_DEBUG(\"address: 0x%8.8\" TARGET_PRIxADDR\n\t\t\", size: 0x%8.8\" PRIx32\n\t\t\", count: 0x%8.8\" PRIx32,\n\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED)\n\t\tLOG_WARNING(\"target not halted\");\n\n\tint retval;\n\n\tif ((address >= stm8->flashstart) && (address <= stm8->flashend))\n\t\tretval = stm8_write_flash(target, FLASH, address, size, count,\n\t\t\t\tstm8->blocksize, buffer);\n\telse if ((address >= stm8->eepromstart) && (address <= stm8->eepromend))\n\t\tretval = stm8_write_flash(target, EEPROM, address, size, count,\n\t\t\t\tstm8->blocksize, buffer);\n\telse if ((address >= stm8->optionstart) && (address <= stm8->optionend))\n\t\tretval = stm8_write_flash(target, OPTION, address, size, count, 0, buffer);\n\telse\n\t\tretval = stm8_adapter_write_memory(target, address, size, count,\n\t\t\t\tbuffer);\n\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_TARGET_FAILURE;\n\n\treturn retval;\n}\n\nstatic int stm8_read_memory(struct target *target, target_addr_t address,\n\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tLOG_DEBUG(\"address: 0x%8.8\" TARGET_PRIxADDR\n\t\t\", size: 0x%8.8\" PRIx32\n\t\t\", count: 0x%8.8\" PRIx32,\n\t\taddress, size, count);\n\n\tif (target->state != TARGET_HALTED)\n\t\tLOG_WARNING(\"target not halted\");\n\n\tint retval;\n\tretval = stm8_adapter_read_memory(target, address, size, count, buffer);\n\n\tif (retval != ERROR_OK)\n\t\treturn ERROR_TARGET_FAILURE;\n\n\treturn retval;\n}\n\nstatic int stm8_speed(int speed)\n{\n\tint retval;\n\tuint8_t csr;\n\n\tLOG_DEBUG(\"stm8_speed: %d\", speed);\n\n\tcsr = SAFE_MASK | SWIM_DM;\n\tif (speed >= SWIM_FREQ_HIGH)\n\t\tcsr |= HS;\n\n\tLOG_DEBUG(\"writing B0 to SWIM_CSR (SAFE_MASK + SWIM_DM + HS:%d)\", csr & HS ? 1 : 0);\n\tretval = stm8_write_u8(NULL, SWIM_CSR, csr);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\treturn adapter_speed(speed);\n}\n\nstatic int stm8_init(struct command_context *cmd_ctx, struct target *target)\n{\n\t/*\n\t * FIXME: this is a temporarily hack that needs better implementation.\n\t * Being the only overwrite of adapter_driver, it prevents declaring const\n\t * the struct adapter_driver.\n\t * intercept adapter_driver->speed() calls\n\t */\n\tadapter_speed = adapter_driver->speed;\n\tadapter_driver->speed = stm8_speed;\n\n\tstm8_build_reg_cache(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_poll(struct target *target)\n{\n\tint retval = ERROR_OK;\n\tuint8_t csr1, csr2;\n\n#ifdef LOG_STM8\n\tLOG_DEBUG(\"target->state=%d\", target->state);\n#endif\n\n\t/* read dm_csrx control regs */\n\tretval = stm8_read_dm_csrx(target, &csr1, &csr2);\n\tif (retval != ERROR_OK) {\n\t\tLOG_DEBUG(\"stm8_read_dm_csrx failed retval=%d\", retval);\n\t\t/*\n\t\t   We return ERROR_OK here even if we didn't get an answer.\n\t\t   openocd will call target_wait_state until we get target state TARGET_HALTED\n\t\t*/\n\t\treturn ERROR_OK;\n\t}\n\n\t/* check for processor halted */\n\tif (csr2 & STALL) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tif (target->state == TARGET_UNKNOWN)\n\t\t\t\tLOG_DEBUG(\"DM_CSR2_STALL already set during server startup.\");\n\n\t\t\tretval = stm8_debug_entry(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_DEBUG(\"stm8_debug_entry failed retval=%d\", retval);\n\t\t\t\treturn ERROR_TARGET_FAILURE;\n\t\t\t}\n\n\t\t\tif (target->state == TARGET_DEBUG_RUNNING) {\n\t\t\t\ttarget->state = TARGET_HALTED;\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t\t} else {\n\t\t\t\ttarget->state = TARGET_HALTED;\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t\t}\n\t\t}\n\t} else\n\t\ttarget->state = TARGET_RUNNING;\n#ifdef LOG_STM8\n\tLOG_DEBUG(\"csr1 = 0x%02X csr2 = 0x%02X\", csr1, csr2);\n#endif\n\treturn ERROR_OK;\n}\n\nstatic int stm8_halt(struct target *target)\n{\n\tLOG_DEBUG(\"target->state: %s\", target_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state == TARGET_UNKNOWN)\n\t\tLOG_WARNING(\"target was in unknown state when halt was requested\");\n\n\tif (target->state == TARGET_RESET) {\n\t\t/* we came here in a reset_halt or reset_init sequence\n\t\t * debug entry was already prepared in stm8_assert_reset()\n\t\t */\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\t\treturn ERROR_OK;\n\t}\n\n\n\t/* break processor */\n\tstm8_debug_stall(target);\n\n\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_reset_assert(struct target *target)\n{\n\tint res = ERROR_OK;\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tbool use_srst_fallback = true;\n\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\tres = adapter_assert_reset();\n\t\tif (res == ERROR_OK)\n\t\t\t/* hardware srst supported */\n\t\t\tuse_srst_fallback = false;\n\t\telse if (res != ERROR_COMMAND_NOTFOUND)\n\t\t\t/* some other failure */\n\t\t\treturn res;\n\t}\n\n\tif (use_srst_fallback) {\n\t\tLOG_DEBUG(\"Hardware srst not supported, falling back to swim reset\");\n\t\tres = swim_system_reset();\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(stm8->core_cache);\n\n\ttarget->state = TARGET_RESET;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\tif (target->reset_halt) {\n\t\tres = target_halt(target);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_reset_deassert(struct target *target)\n{\n\tint res;\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (jtag_reset_config & RESET_HAS_SRST) {\n\t\tres = adapter_deassert_reset();\n\t\tif ((res != ERROR_OK) && (res != ERROR_COMMAND_NOTFOUND))\n\t\t\treturn res;\n\t}\n\n\t/* The cpu should now be stalled. If halt was requested\n\t   let poll detect the stall */\n\tif (target->reset_halt)\n\t\treturn ERROR_OK;\n\n\t/* Instead of going through saving context, polling and\n\t   then resuming target again just clear stall and proceed. */\n\ttarget->state = TARGET_RUNNING;\n\treturn stm8_exit_debug(target);\n}\n\n/* stm8_single_step_core() is only used for stepping over breakpoints\n   from stm8_resume() */\nstatic int stm8_single_step_core(struct target *target)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\t/* configure single step mode */\n\tstm8_config_step(target, 1);\n\n\t/* disable interrupts while stepping */\n\tif (!stm8->enable_step_irq)\n\t\tstm8_enable_interrupts(target, 0);\n\n\t/* exit debug mode */\n\tstm8_exit_debug(target);\n\n\tstm8_debug_entry(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_resume(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints,\n\t\tint debug_execution)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct breakpoint *breakpoint = NULL;\n\tuint32_t resume_pc;\n\n\tLOG_DEBUG(\"%d \" TARGET_ADDR_FMT \" %d %d\", current, address,\n\t\t\thandle_breakpoints, debug_execution);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution) {\n\t\ttarget_free_all_working_areas(target);\n\t\tstm8_enable_breakpoints(target);\n\t\tstm8_enable_watchpoints(target);\n\t\tstruct stm8_comparator *comparator_list = stm8->hw_break_list;\n\t\tstm8_set_hwbreak(target, comparator_list);\n\t}\n\n\t/* current = 1: continue on current pc,\n\t   otherwise continue at <address> */\n\tif (!current) {\n\t\tbuf_set_u32(stm8->core_cache->reg_list[STM8_PC].value,\n\t\t\t0, 32, address);\n\t\tstm8->core_cache->reg_list[STM8_PC].dirty = true;\n\t\tstm8->core_cache->reg_list[STM8_PC].valid = true;\n\t}\n\n\tif (!current)\n\t\tresume_pc = address;\n\telse\n\t\tresume_pc = buf_get_u32(\n\t\t\tstm8->core_cache->reg_list[STM8_PC].value,\n\t\t\t0, 32);\n\n\tstm8_restore_context(target);\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\t/* Single step past breakpoint at current address */\n\t\tbreakpoint = breakpoint_find(target, resume_pc);\n\t\tif (breakpoint) {\n\t\t\tLOG_DEBUG(\"unset breakpoint at \" TARGET_ADDR_FMT,\n\t\t\t\t\tbreakpoint->address);\n\t\t\tstm8_unset_breakpoint(target, breakpoint);\n\t\t\tstm8_single_step_core(target);\n\t\t\tstm8_set_breakpoint(target, breakpoint);\n\t\t}\n\t}\n\n\t/* disable interrupts if we are debugging */\n\tif (debug_execution)\n\t\tstm8_enable_interrupts(target, 0);\n\n\t/* exit debug mode */\n\tstm8_exit_debug(target);\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(stm8->core_cache);\n\n\tif (!debug_execution) {\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t\tLOG_DEBUG(\"target resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t\tLOG_DEBUG(\"target debug resumed at 0x%\" PRIx32 \"\", resume_pc);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_init_flash_regs(bool enable_stm8l, struct stm8_common *stm8)\n{\n\tstm8->enable_stm8l = enable_stm8l;\n\n\tif (stm8->enable_stm8l) {\n\t\tstm8->flash_cr2 = FLASH_CR2_STM8L;\n\t\tstm8->flash_ncr2 = FLASH_NCR2_STM8L;\n\t\tstm8->flash_iapsr = FLASH_IAPSR_STM8L;\n\t\tstm8->flash_dukr = FLASH_DUKR_STM8L;\n\t\tstm8->flash_pukr = FLASH_PUKR_STM8L;\n\t} else {\n\t\tstm8->flash_cr2 = FLASH_CR2_STM8S;\n\t\tstm8->flash_ncr2 = FLASH_NCR2_STM8S;\n\t\tstm8->flash_iapsr = FLASH_IAPSR_STM8S;\n\t\tstm8->flash_dukr = FLASH_DUKR_STM8S;\n\t\tstm8->flash_pukr = FLASH_PUKR_STM8S;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int stm8_init_arch_info(struct target *target,\n\t\tstruct stm8_common *stm8, struct jtag_tap *tap)\n{\n\ttarget->endianness = TARGET_BIG_ENDIAN;\n\ttarget->arch_info = stm8;\n\tstm8->common_magic = STM8_COMMON_MAGIC;\n\tstm8->fast_data_area = NULL;\n\tstm8->blocksize = 0x80;\n\tstm8->flashstart = 0x8000;\n\tstm8->flashend = 0xffff;\n\tstm8->eepromstart = 0x4000;\n\tstm8->eepromend = 0x43ff;\n\tstm8->optionstart = 0x4800;\n\tstm8->optionend = 0x487F;\n\n\t/* has breakpoint/watchpoint unit been scanned */\n\tstm8->bp_scanned = false;\n\tstm8->hw_break_list = NULL;\n\n\tstm8->read_core_reg = stm8_read_core_reg;\n\tstm8->write_core_reg = stm8_write_core_reg;\n\n\tstm8_init_flash_regs(0, stm8);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_target_create(struct target *target,\n\t\tJim_Interp *interp)\n{\n\n\tstruct stm8_common *stm8 = calloc(1, sizeof(struct stm8_common));\n\n\tstm8_init_arch_info(target, stm8, target->tap);\n\tstm8_configure_break_unit(target);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_read_core_reg(struct target *target, unsigned int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (num >= STM8_NUM_REGS)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = stm8->core_regs[num];\n\tLOG_DEBUG(\"read core reg %i value 0x%\" PRIx32 \"\", num, reg_value);\n\tbuf_set_u32(stm8->core_cache->reg_list[num].value, 0, 32, reg_value);\n\tstm8->core_cache->reg_list[num].valid = true;\n\tstm8->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_write_core_reg(struct target *target, unsigned int num)\n{\n\tuint32_t reg_value;\n\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (num >= STM8_NUM_REGS)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treg_value = buf_get_u32(stm8->core_cache->reg_list[num].value, 0, 32);\n\tstm8->core_regs[num] = reg_value;\n\tLOG_DEBUG(\"write core reg %i value 0x%\" PRIx32 \"\", num, reg_value);\n\tstm8->core_cache->reg_list[num].valid = true;\n\tstm8->core_cache->reg_list[num].dirty = false;\n\n\treturn ERROR_OK;\n}\n\nstatic const char *stm8_get_gdb_arch(struct target *target)\n{\n\treturn \"stm8\";\n}\n\nstatic int stm8_get_gdb_reg_list(struct target *target, struct reg **reg_list[],\n\t\tint *reg_list_size, enum target_register_class reg_class)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tunsigned int i;\n\n\t*reg_list_size = STM8_NUM_REGS;\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\n\tfor (i = 0; i < STM8_NUM_REGS; i++)\n\t\t(*reg_list)[i] = &stm8->core_cache->reg_list[i];\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type stm8_reg_type = {\n\t.get = stm8_get_core_reg,\n\t.set = stm8_set_core_reg,\n};\n\nstatic struct reg_cache *stm8_build_reg_cache(struct target *target)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tint num_regs = STM8_NUM_REGS;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct reg_cache *cache = malloc(sizeof(struct reg_cache));\n\tstruct reg *reg_list = calloc(num_regs, sizeof(struct reg));\n\tstruct stm8_core_reg *arch_info = malloc(\n\t\t\tsizeof(struct stm8_core_reg) * num_regs);\n\tstruct reg_feature *feature;\n\tint i;\n\n\t/* Build the process context cache */\n\tcache->name = \"stm8 registers\";\n\tcache->next = NULL;\n\tcache->reg_list = reg_list;\n\tcache->num_regs = num_regs;\n\t(*cache_p) = cache;\n\tstm8->core_cache = cache;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\tarch_info[i].num = stm8_regs[i].id;\n\t\tarch_info[i].target = target;\n\n\t\treg_list[i].name = stm8_regs[i].name;\n\t\treg_list[i].size = stm8_regs[i].bits;\n\n\t\treg_list[i].value = calloc(1, 4);\n\t\treg_list[i].valid = false;\n\t\treg_list[i].type = &stm8_reg_type;\n\t\treg_list[i].arch_info = &arch_info[i];\n\n\t\treg_list[i].reg_data_type = calloc(1, sizeof(struct reg_data_type));\n\t\tif (reg_list[i].reg_data_type)\n\t\t\treg_list[i].reg_data_type->type = stm8_regs[i].type;\n\t\telse {\n\t\t\tLOG_ERROR(\"unable to allocate reg type list\");\n\t\t\treturn NULL;\n\t\t}\n\n\t\treg_list[i].dirty = false;\n\t\treg_list[i].group = stm8_regs[i].group;\n\t\treg_list[i].number = stm8_regs[i].id;\n\t\treg_list[i].exist = true;\n\t\treg_list[i].caller_save = true;\t/* gdb defaults to true */\n\n\t\tfeature = calloc(1, sizeof(struct reg_feature));\n\t\tif (feature) {\n\t\t\tfeature->name = stm8_regs[i].feature;\n\t\t\treg_list[i].feature = feature;\n\t\t} else\n\t\t\tLOG_ERROR(\"unable to allocate feature list\");\n\t}\n\n\treturn cache;\n}\n\nstatic void stm8_free_reg_cache(struct target *target)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct reg_cache *cache;\n\tstruct reg *reg;\n\tunsigned int i;\n\n\tcache = stm8->core_cache;\n\n\tif (!cache)\n\t\treturn;\n\n\tfor (i = 0; i < cache->num_regs; i++) {\n\t\treg = &cache->reg_list[i];\n\n\t\tfree(reg->feature);\n\t\tfree(reg->reg_data_type);\n\t\tfree(reg->value);\n\t}\n\n\tfree(cache->reg_list[0].arch_info);\n\tfree(cache->reg_list);\n\tfree(cache);\n\n\tstm8->core_cache = NULL;\n}\n\nstatic void stm8_deinit(struct target *target)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tfree(stm8->hw_break_list);\n\n\tstm8_free_reg_cache(target);\n\n\tfree(stm8);\n}\n\nstatic int stm8_arch_state(struct target *target)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tLOG_USER(\"target halted due to %s, pc: 0x%8.8\" PRIx32 \"\",\n\t\tdebug_reason_name(target),\n\t\tbuf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_step(struct target *target, int current,\n\t\ttarget_addr_t address, int handle_breakpoints)\n{\n\tLOG_DEBUG(\"%x \" TARGET_ADDR_FMT \" %x\",\n\t\tcurrent, address, handle_breakpoints);\n\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct breakpoint *breakpoint = NULL;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current) {\n\t\tbuf_set_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32, address);\n\t\tstm8->core_cache->reg_list[STM8_PC].dirty = true;\n\t\tstm8->core_cache->reg_list[STM8_PC].valid = true;\n\t}\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\tbuf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32));\n\t\tif (breakpoint)\n\t\t\tstm8_unset_breakpoint(target, breakpoint);\n\t}\n\n\t/* restore context */\n\tstm8_restore_context(target);\n\n\t/* configure single step mode */\n\tstm8_config_step(target, 1);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\t/* disable interrupts while stepping */\n\tif (!stm8->enable_step_irq)\n\t\tstm8_enable_interrupts(target, 0);\n\n\t/* exit debug mode */\n\tstm8_exit_debug(target);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(stm8->core_cache);\n\n\tLOG_DEBUG(\"target stepped \");\n\tstm8_debug_entry(target);\n\n\tif (breakpoint)\n\t\tstm8_set_breakpoint(target, breakpoint);\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\treturn ERROR_OK;\n}\n\nstatic void stm8_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\t/* set any pending breakpoints */\n\twhile (breakpoint) {\n\t\tif (!breakpoint->is_set)\n\t\t\tstm8_set_breakpoint(target, breakpoint);\n\t\tbreakpoint = breakpoint->next;\n\t}\n}\n\nstatic int stm8_set_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct stm8_comparator *comparator_list = stm8->hw_break_list;\n\tint retval;\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tint bp_num = 0;\n\n\t\twhile (comparator_list[bp_num].used && (bp_num < stm8->num_hw_bpoints))\n\t\t\tbp_num++;\n\t\tif (bp_num >= stm8->num_hw_bpoints) {\n\t\t\tLOG_ERROR(\"Can not find free breakpoint register (bpid: %\" PRIu32 \")\",\n\t\t\t\t\tbreakpoint->unique_id);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint_hw_set(breakpoint, bp_num);\n\t\tcomparator_list[bp_num].used = true;\n\t\tcomparator_list[bp_num].bp_value = breakpoint->address;\n\t\tcomparator_list[bp_num].type = HWBRK_EXEC;\n\n\t\tretval = stm8_set_hwbreak(target, comparator_list);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \", bp_num %i bp_value 0x%\" PRIx32 \"\",\n\t\t\t\t  breakpoint->unique_id,\n\t\t\t\t  bp_num, comparator_list[bp_num].bp_value);\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\t\tif (breakpoint->length == 1) {\n\t\t\tuint8_t verify = 0x55;\n\n\t\t\tretval = target_read_u8(target, breakpoint->address,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tretval = target_write_u8(target, breakpoint->address, STM8_BREAK);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tretval = target_read_u8(target, breakpoint->address, &verify);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tif (verify != STM8_BREAK) {\n\t\t\t\tLOG_ERROR(\"Unable to set breakpoint at address \" TARGET_ADDR_FMT\n\t\t\t\t\t\t\" - check that memory is read/writable\",\n\t\t\t\t\t\tbreakpoint->address);\n\t\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\t}\n\t\t} else {\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tbreakpoint->is_set = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_add_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tint ret;\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tif (stm8->num_hw_bpoints_avail < 1) {\n\t\t\tLOG_INFO(\"no hardware breakpoint available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\tret = stm8_set_breakpoint(target, breakpoint);\n\t\tif (ret != ERROR_OK)\n\t\t\treturn ret;\n\n\t\tstm8->num_hw_bpoints_avail--;\n\t\treturn ERROR_OK;\n\t}\n\n\tret = stm8_set_breakpoint(target, breakpoint);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_unset_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct stm8_comparator *comparator_list = stm8->hw_break_list;\n\tint retval;\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tint bp_num = breakpoint->number;\n\t\tif (bp_num >= stm8->num_hw_bpoints) {\n\t\t\tLOG_DEBUG(\"Invalid comparator number in breakpoint (bpid: %\" PRIu32 \")\",\n\t\t\t\t\t  breakpoint->unique_id);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32 \" - releasing hw: %d\",\n\t\t\t\tbreakpoint->unique_id,\n\t\t\t\tbp_num);\n\t\tcomparator_list[bp_num].used = false;\n\t\tretval = stm8_set_hwbreak(target, comparator_list);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tLOG_DEBUG(\"bpid: %\" PRIu32, breakpoint->unique_id);\n\t\tif (breakpoint->length == 1) {\n\t\t\tuint8_t current_instr;\n\n\t\t\t/* check that user program has not\n\t\t\t  modified breakpoint instruction */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 1, 1,\n\t\t\t\t\t(uint8_t *)&current_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\tif (current_instr == STM8_BREAK) {\n\t\t\t\tretval = target_write_memory(target, breakpoint->address, 1, 1,\n\t\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else\n\t\t\treturn ERROR_FAIL;\n\t}\n\tbreakpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_remove_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (breakpoint->is_set)\n\t\tstm8_unset_breakpoint(target, breakpoint);\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\tstm8->num_hw_bpoints_avail++;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_set_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct stm8_comparator *comparator_list = stm8->hw_break_list;\n\tint wp_num = 0;\n\tint ret;\n\n\tif (watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\twhile (comparator_list[wp_num].used && (wp_num < stm8->num_hw_bpoints))\n\t\twp_num++;\n\tif (wp_num >= stm8->num_hw_bpoints) {\n\t\tLOG_ERROR(\"Can not find free hw breakpoint\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (watchpoint->length != 1) {\n\t\t\tLOG_ERROR(\"Only watchpoints of length 1 are supported\");\n\t\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\t}\n\n\tenum hw_break_type enable = 0;\n\n\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tenable = HWBRK_RD;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tenable = HWBRK_WR;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tenable = HWBRK_ACC;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: watchpoint->rw neither read, write nor access\");\n\t}\n\n\tcomparator_list[wp_num].used = true;\n\tcomparator_list[wp_num].bp_value = watchpoint->address;\n\tcomparator_list[wp_num].type = enable;\n\n\tret = stm8_set_hwbreak(target, comparator_list);\n\tif (ret != ERROR_OK) {\n\t\tcomparator_list[wp_num].used = false;\n\t\treturn ret;\n\t}\n\n\twatchpoint_set(watchpoint, wp_num);\n\n\tLOG_DEBUG(\"wp_num %i bp_value 0x%\" PRIx32 \"\",\n\t\t\twp_num,\n\t\t\tcomparator_list[wp_num].bp_value);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_add_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tint ret;\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (stm8->num_hw_bpoints_avail < 1) {\n\t\tLOG_INFO(\"no hardware watchpoints available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tret = stm8_set_watchpoint(target, watchpoint);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\n\tstm8->num_hw_bpoints_avail--;\n\treturn ERROR_OK;\n}\n\nstatic void stm8_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\t/* set any pending watchpoints */\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\tstm8_set_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n}\n\nstatic int stm8_unset_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tstruct stm8_comparator *comparator_list = stm8->hw_break_list;\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wp_num = watchpoint->number;\n\tif (wp_num >= stm8->num_hw_bpoints) {\n\t\tLOG_DEBUG(\"Invalid hw comparator number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tcomparator_list[wp_num].used = false;\n\twatchpoint->is_set = false;\n\n\tstm8_set_hwbreak(target, comparator_list);\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\tstm8_unset_watchpoint(target, watchpoint);\n\n\tstm8->num_hw_bpoints_avail++;\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_examine(struct target *target)\n{\n\tint retval;\n\tuint8_t csr1, csr2;\n\t/* get pointers to arch-specific information */\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tenum reset_types jtag_reset_config = jtag_get_reset_config();\n\n\tif (!target_was_examined(target)) {\n\t\tif (!stm8->swim_configured) {\n\t\t\tstm8->swim_configured = true;\n\t\t\t/*\n\t\t\t\tNow is the time to deassert reset if connect_under_reset.\n\t\t\t\tReleasing reset line will cause the option bytes to load.\n\t\t\t\tThe core will still be stalled.\n\t\t\t*/\n\t\t\tif (jtag_reset_config & RESET_CNCT_UNDER_SRST) {\n\t\t\t\tif (jtag_reset_config & RESET_SRST_NO_GATING)\n\t\t\t\t\tstm8_reset_deassert(target);\n\t\t\t\telse\n\t\t\t\t\tLOG_WARNING(\"\\'srst_nogate\\' reset_config option is required\");\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_INFO(\"trying to reconnect\");\n\n\t\t\tretval = swim_reconnect();\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"reconnect failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\t/* read dm_csrx control regs */\n\t\t\tretval = stm8_read_dm_csrx(target, &csr1, &csr2);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"state query failed\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t}\n\n\t\ttarget_set_examined(target);\n\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/** Checks whether a memory region is erased. */\nstatic int stm8_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)\n{\n\tstruct working_area *erase_check_algorithm;\n\tstruct reg_param reg_params[2];\n\tstruct mem_param mem_params[2];\n\tstruct stm8_algorithm stm8_info;\n\n\tstatic const uint8_t stm8_erase_check_code[] = {\n#include \"../../contrib/loaders/erase_check/stm8_erase_check.inc\"\n\t};\n\n\tif (erased_value != 0xff) {\n\t\tLOG_ERROR(\"Erase value 0x%02\" PRIx8 \" not yet supported for STM8\",\n\t\t\terased_value);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* make sure we have a working area */\n\tif (target_alloc_working_area(target, sizeof(stm8_erase_check_code),\n\t\t\t&erase_check_algorithm) != ERROR_OK)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\ttarget_write_buffer(target, erase_check_algorithm->address,\n\t\t\tsizeof(stm8_erase_check_code), stm8_erase_check_code);\n\n\tstm8_info.common_magic = STM8_COMMON_MAGIC;\n\n\tinit_mem_param(&mem_params[0], 0x0, 3, PARAM_OUT);\n\tbuf_set_u32(mem_params[0].value, 0, 24, blocks[0].address);\n\n\tinit_mem_param(&mem_params[1], 0x3, 3, PARAM_OUT);\n\tbuf_set_u32(mem_params[1].value, 0, 24, blocks[0].size);\n\n\tinit_reg_param(&reg_params[0], \"a\", 32, PARAM_IN_OUT);\n\tbuf_set_u32(reg_params[0].value, 0, 32, erased_value);\n\n\tinit_reg_param(&reg_params[1], \"sp\", 32, PARAM_OUT);\n\tbuf_set_u32(reg_params[1].value, 0, 32, erase_check_algorithm->address);\n\n\tint retval = target_run_algorithm(target, 2, mem_params, 2, reg_params,\n\t\t\terase_check_algorithm->address + 6,\n\t\t\terase_check_algorithm->address + (sizeof(stm8_erase_check_code) - 1),\n\t\t\t10000, &stm8_info);\n\n\tif (retval == ERROR_OK)\n\t\tblocks[0].result = (*(reg_params[0].value) == 0xff);\n\n\tdestroy_mem_param(&mem_params[0]);\n\tdestroy_mem_param(&mem_params[1]);\n\tdestroy_reg_param(&reg_params[0]);\n\tdestroy_reg_param(&reg_params[1]);\n\n\ttarget_free_working_area(target, erase_check_algorithm);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn 1;\t/* only one block has been checked */\n}\n\nstatic int stm8_checksum_memory(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint32_t *checksum)\n{\n\t/* let image_calculate_checksum() take care of business */\n\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n}\n\n/* run to exit point. return error if exit point was not reached. */\nstatic int stm8_run_and_wait(struct target *target, uint32_t entry_point,\n\t\tunsigned int timeout_ms, uint32_t exit_point, struct stm8_common *stm8)\n{\n\tuint32_t pc;\n\tint retval;\n\t/* This code relies on the target specific resume() and\n\t   poll()->debug_entry() sequence to write register values to the\n\t   processor and the read them back */\n\tretval = target_resume(target, 0, entry_point, 0, 1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_wait_state(target, TARGET_HALTED, timeout_ms);\n\t/* If the target fails to halt due to the breakpoint, force a halt */\n\tif (retval != ERROR_OK || target->state != TARGET_HALTED) {\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_wait_state(target, TARGET_HALTED, 500);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\tpc = buf_get_u32(stm8->core_cache->reg_list[STM8_PC].value, 0, 32);\n\tif (exit_point && (pc != exit_point)) {\n\t\tLOG_DEBUG(\"failed algorithm halted at 0x%\" PRIx32 \" \", pc);\n\t\treturn ERROR_TARGET_TIMEOUT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_run_algorithm(struct target *target, int num_mem_params,\n\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\tstruct reg_param *reg_params, target_addr_t entry_point,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms, void *arch_info)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\n\tuint32_t context[STM8_NUM_REGS];\n\tint retval = ERROR_OK;\n\n\tLOG_DEBUG(\"Running algorithm\");\n\n\t/* NOTE: stm8_run_algorithm requires that each\n\t   algorithm uses a software breakpoint\n\t   at the exit point */\n\n\tif (stm8->common_magic != STM8_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"current target isn't a STM8 target\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* refresh core register cache */\n\tfor (unsigned int i = 0; i < STM8_NUM_REGS; i++) {\n\t\tif (!stm8->core_cache->reg_list[i].valid)\n\t\t\tstm8->read_core_reg(target, i);\n\t\tcontext[i] = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);\n\t}\n\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\t\tretval = target_write_buffer(target, mem_params[i].address,\n\t\t\t\tmem_params[i].size, mem_params[i].value);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction == PARAM_IN)\n\t\t\tcontinue;\n\n\t\tstruct reg *reg = register_get_by_name(stm8->core_cache,\n\t\t\t\treg_params[i].reg_name, false);\n\n\t\tif (!reg) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' not found\", reg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tif (reg_params[i].size != 32) {\n\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\treg_params[i].reg_name);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tstm8_set_core_reg(reg, reg_params[i].value);\n\t}\n\n\tretval = stm8_run_and_wait(target, entry_point,\n\t\t\ttimeout_ms, exit_point, stm8);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tfor (int i = 0; i < num_mem_params; i++) {\n\t\tif (mem_params[i].direction != PARAM_OUT) {\n\t\t\tretval = target_read_buffer(target, mem_params[i].address,\n\t\t\t\t\tmem_params[i].size, mem_params[i].value);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t}\n\n\tfor (int i = 0; i < num_reg_params; i++) {\n\t\tif (reg_params[i].direction != PARAM_OUT) {\n\t\t\tstruct reg *reg = register_get_by_name(stm8->core_cache,\n\t\t\t\t\treg_params[i].reg_name, false);\n\t\t\tif (!reg) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' not found\",\n\t\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tif (reg_params[i].size != 32) {\n\t\t\t\tLOG_ERROR(\"BUG: register '%s' size doesn't match reg_params[i].size\",\n\t\t\t\t\t\treg_params[i].reg_name);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\n\t\t\tbuf_set_u32(reg_params[i].value,\n\t\t\t\t\t0, 32, buf_get_u32(reg->value, 0, 32));\n\t\t}\n\t}\n\n\t/* restore everything we saved before */\n\tfor (unsigned int i = 0; i < STM8_NUM_REGS; i++) {\n\t\tuint32_t regvalue;\n\t\tregvalue = buf_get_u32(stm8->core_cache->reg_list[i].value, 0, 32);\n\t\tif (regvalue != context[i]) {\n\t\t\tLOG_DEBUG(\"restoring register %s with value 0x%8.8\" PRIx32,\n\t\t\t\tstm8->core_cache->reg_list[i].name, context[i]);\n\t\t\tbuf_set_u32(stm8->core_cache->reg_list[i].value,\n\t\t\t\t\t0, 32, context[i]);\n\t\t\tstm8->core_cache->reg_list[i].valid = true;\n\t\t\tstm8->core_cache->reg_list[i].dirty = true;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int stm8_jim_configure(struct target *target, struct jim_getopt_info *goi)\n{\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tjim_wide w;\n\tint e;\n\tconst char *arg;\n\n\targ = Jim_GetString(goi->argv[0], NULL);\n\tif (!strcmp(arg, \"-blocksize\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-blocksize ?bytes? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->blocksize = w;\n\t\tLOG_DEBUG(\"blocksize=%8.8\" PRIx32, stm8->blocksize);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-flashstart\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-flashstart ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->flashstart = w;\n\t\tLOG_DEBUG(\"flashstart=%8.8\" PRIx32, stm8->flashstart);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-flashend\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-flashend ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->flashend = w;\n\t\tLOG_DEBUG(\"flashend=%8.8\" PRIx32, stm8->flashend);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-eepromstart\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-eepromstart ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->eepromstart = w;\n\t\tLOG_DEBUG(\"eepromstart=%8.8\" PRIx32, stm8->eepromstart);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-eepromend\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-eepromend ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->eepromend = w;\n\t\tLOG_DEBUG(\"eepromend=%8.8\" PRIx32, stm8->eepromend);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-optionstart\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-optionstart ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->optionstart = w;\n\t\tLOG_DEBUG(\"optionstart=%8.8\" PRIx32, stm8->optionstart);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-optionend\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tif (goi->argc == 0) {\n\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv,\n\t\t\t\t\t\"-optionend ?address? ...\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\te = jim_getopt_wide(goi, &w);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->optionend = w;\n\t\tLOG_DEBUG(\"optionend=%8.8\" PRIx32, stm8->optionend);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-enable_step_irq\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->enable_step_irq = true;\n\t\tLOG_DEBUG(\"enable_step_irq=%8.8x\", stm8->enable_step_irq);\n\t\treturn JIM_OK;\n\t}\n\tif (!strcmp(arg, \"-enable_stm8l\")) {\n\t\te = jim_getopt_string(goi, &arg, NULL);\n\t\tif (e != JIM_OK)\n\t\t\treturn e;\n\n\t\tstm8->enable_stm8l = true;\n\t\tLOG_DEBUG(\"enable_stm8l=%8.8x\", stm8->enable_stm8l);\n\t\tstm8_init_flash_regs(stm8->enable_stm8l, stm8);\n\t\treturn JIM_OK;\n\t}\n\treturn JIM_CONTINUE;\n}\n\nCOMMAND_HANDLER(stm8_handle_enable_step_irq_command)\n{\n\tconst char *msg;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tbool enable = stm8->enable_step_irq;\n\n\tif (CMD_ARGC > 0) {\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tstm8->enable_step_irq = enable;\n\t}\n\tmsg = stm8->enable_step_irq ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"enable_step_irq = %s\", msg);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(stm8_handle_enable_stm8l_command)\n{\n\tconst char *msg;\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct stm8_common *stm8 = target_to_stm8(target);\n\tbool enable = stm8->enable_stm8l;\n\n\tif (CMD_ARGC > 0) {\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tstm8->enable_stm8l = enable;\n\t}\n\tmsg = stm8->enable_stm8l ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"enable_stm8l = %s\", msg);\n\tstm8_init_flash_regs(stm8->enable_stm8l, stm8);\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration stm8_exec_command_handlers[] = {\n\t{\n\t\t.name = \"enable_step_irq\",\n\t\t.handler = stm8_handle_enable_step_irq_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Enable/disable irq handling during step\",\n\t\t.usage = \"[1/0]\",\n\t},\n\t{\n\t\t.name = \"enable_stm8l\",\n\t\t.handler = stm8_handle_enable_stm8l_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Enable/disable STM8L flash programming\",\n\t\t.usage = \"[1/0]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration stm8_command_handlers[] = {\n\t{\n\t\t.name = \"stm8\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"stm8 command group\",\n\t\t.usage = \"\",\n\t\t.chain = stm8_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type stm8_target = {\n\t.name = \"stm8\",\n\n\t.poll = stm8_poll,\n\t.arch_state = stm8_arch_state,\n\n\t.halt = stm8_halt,\n\t.resume = stm8_resume,\n\t.step = stm8_step,\n\n\t.assert_reset = stm8_reset_assert,\n\t.deassert_reset = stm8_reset_deassert,\n\n\t.get_gdb_arch = stm8_get_gdb_arch,\n\t.get_gdb_reg_list = stm8_get_gdb_reg_list,\n\n\t.read_memory = stm8_read_memory,\n\t.write_memory = stm8_write_memory,\n\t.checksum_memory = stm8_checksum_memory,\n\t.blank_check_memory = stm8_blank_check_memory,\n\n\t.run_algorithm = stm8_run_algorithm,\n\n\t.add_breakpoint = stm8_add_breakpoint,\n\t.remove_breakpoint = stm8_remove_breakpoint,\n\t.add_watchpoint = stm8_add_watchpoint,\n\t.remove_watchpoint = stm8_remove_watchpoint,\n\n\t.commands = stm8_command_handlers,\n\t.target_create = stm8_target_create,\n\t.init_target = stm8_init,\n\t.examine = stm8_examine,\n\n\t.deinit_target = stm8_deinit,\n\t.target_jim_configure = stm8_jim_configure,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/stm8.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n*   OpenOCD STM8 target driver\n*   Copyright (C) 2017  Ake Rehnman\n*   ake.rehnman(at)gmail.com\n*/\n\n#ifndef OPENOCD_TARGET_STM8_H\n#define OPENOCD_TARGET_STM8_H\n\nstruct target;\n\n#define STM8_COMMON_MAGIC\t0x53544D38U\n#define STM8_NUM_CORE_REGS 6\n\nstruct stm8_common {\n\tunsigned int common_magic;\n\n\tvoid *arch_info;\n\tstruct reg_cache *core_cache;\n\tuint32_t core_regs[STM8_NUM_CORE_REGS];\n\n\t/* working area for fastdata access */\n\tstruct working_area *fast_data_area;\n\n\tbool swim_configured;\n\tbool bp_scanned;\n\tuint8_t num_hw_bpoints;\n\tuint8_t num_hw_bpoints_avail;\n\tstruct stm8_comparator *hw_break_list;\n\tuint32_t blocksize;\n\tuint32_t flashstart;\n\tuint32_t flashend;\n\tuint32_t eepromstart;\n\tuint32_t eepromend;\n\tuint32_t optionstart;\n\tuint32_t optionend;\n\tbool enable_step_irq;\n\n\tbool enable_stm8l;\n\tuint32_t flash_cr2;\n\tuint32_t flash_ncr2;\n\tuint32_t flash_iapsr;\n\tuint32_t flash_dukr;\n\tuint32_t flash_pukr;\n\n\t/* cc value used for interrupt flags restore */\n\tuint32_t cc;\n\tbool cc_valid;\n\n\t/* register cache to processor synchronization */\n\tint (*read_core_reg)(struct target *target, unsigned int num);\n\tint (*write_core_reg)(struct target *target, unsigned int num);\n};\n\nstatic inline struct stm8_common *\ntarget_to_stm8(struct target *target)\n{\n\treturn target->arch_info;\n}\n\n#endif /* OPENOCD_TARGET_STM8_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/target.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008, Duane Ellis                                       *\n *   openocd@duaneeellis.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2008 by Rick Altherr                                    *\n *   kc8apf@kc8apf.net>                                                    *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011                                     *\n *   michel.jaouen@stericsson.com : smp minimum support                    *\n *                                                                         *\n *   Copyright (C) 2011 Andreas Fritiofson                                 *\n *   andreas.fritiofson@gmail.com                                          *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/align.h>\n#include <helper/nvp.h>\n#include <helper/time_support.h>\n#include <jtag/jtag.h>\n#include <flash/nor/core.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"target_request.h\"\n#include \"breakpoints.h\"\n#include \"register.h\"\n#include \"trace.h\"\n#include \"image.h\"\n#include \"rtos/rtos.h\"\n#include \"transport/transport.h\"\n#include \"arm_cti.h\"\n#include \"smp.h\"\n#include \"semihosting_common.h\"\n\n/* default halt wait timeout (ms) */\n#define DEFAULT_HALT_TIMEOUT 5000\n\nstatic int target_read_buffer_default(struct target *target, target_addr_t address,\n\t\tuint32_t count, uint8_t *buffer);\nstatic int target_write_buffer_default(struct target *target, target_addr_t address,\n\t\tuint32_t count, const uint8_t *buffer);\nstatic int target_array2mem(Jim_Interp *interp, struct target *target,\n\t\tint argc, Jim_Obj * const *argv);\nstatic int target_mem2array(Jim_Interp *interp, struct target *target,\n\t\tint argc, Jim_Obj * const *argv);\nstatic int target_register_user_commands(struct command_context *cmd_ctx);\nstatic int target_get_gdb_fileio_info_default(struct target *target,\n\t\tstruct gdb_fileio_info *fileio_info);\nstatic int target_gdb_fileio_end_default(struct target *target, int retcode,\n\t\tint fileio_errno, bool ctrl_c);\n\nstatic struct target_type *target_types[] = {\n\t&arm7tdmi_target,\n\t&arm9tdmi_target,\n\t&arm920t_target,\n\t&arm720t_target,\n\t&arm966e_target,\n\t&arm946e_target,\n\t&arm926ejs_target,\n\t&fa526_target,\n\t&feroceon_target,\n\t&dragonite_target,\n\t&xscale_target,\n\t&xtensa_chip_target,\n\t&cortexm_target,\n\t&cortexa_target,\n\t&cortexr4_target,\n\t&arm11_target,\n\t&ls1_sap_target,\n\t&mips_m4k_target,\n\t&avr_target,\n\t&dsp563xx_target,\n\t&dsp5680xx_target,\n\t&testee_target,\n\t&avr32_ap7k_target,\n\t&hla_target,\n\t&esp32_target,\n\t&esp32s2_target,\n\t&esp32s3_target,\n\t&or1k_target,\n\t&quark_x10xx_target,\n\t&quark_d20xx_target,\n\t&stm8_target,\n\t&riscv_target,\n\t&mem_ap_target,\n\t&esirisc_target,\n\t&arcv2_target,\n\t&aarch64_target,\n\t&armv8r_target,\n\t&mips_mips64_target,\n\tNULL,\n};\n\nstruct target *all_targets;\nstatic struct target_event_callback *target_event_callbacks;\nstatic struct target_timer_callback *target_timer_callbacks;\nstatic int64_t target_timer_next_event_value;\nstatic LIST_HEAD(target_reset_callback_list);\nstatic LIST_HEAD(target_trace_callback_list);\nstatic const int polling_interval = TARGET_DEFAULT_POLLING_INTERVAL;\nstatic LIST_HEAD(empty_smp_targets);\n\nenum nvp_assert {\n\tNVP_DEASSERT,\n\tNVP_ASSERT,\n};\n\nstatic const struct nvp nvp_assert[] = {\n\t{ .name = \"assert\", NVP_ASSERT },\n\t{ .name = \"deassert\", NVP_DEASSERT },\n\t{ .name = \"T\", NVP_ASSERT },\n\t{ .name = \"F\", NVP_DEASSERT },\n\t{ .name = \"t\", NVP_ASSERT },\n\t{ .name = \"f\", NVP_DEASSERT },\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic const struct nvp nvp_error_target[] = {\n\t{ .value = ERROR_TARGET_INVALID, .name = \"err-invalid\" },\n\t{ .value = ERROR_TARGET_INIT_FAILED, .name = \"err-init-failed\" },\n\t{ .value = ERROR_TARGET_TIMEOUT, .name = \"err-timeout\" },\n\t{ .value = ERROR_TARGET_NOT_HALTED, .name = \"err-not-halted\" },\n\t{ .value = ERROR_TARGET_FAILURE, .name = \"err-failure\" },\n\t{ .value = ERROR_TARGET_UNALIGNED_ACCESS, .name = \"err-unaligned-access\" },\n\t{ .value = ERROR_TARGET_DATA_ABORT, .name = \"err-data-abort\" },\n\t{ .value = ERROR_TARGET_RESOURCE_NOT_AVAILABLE, .name = \"err-resource-not-available\" },\n\t{ .value = ERROR_TARGET_TRANSLATION_FAULT, .name = \"err-translation-fault\" },\n\t{ .value = ERROR_TARGET_NOT_RUNNING, .name = \"err-not-running\" },\n\t{ .value = ERROR_TARGET_NOT_EXAMINED, .name = \"err-not-examined\" },\n\t{ .value = -1, .name = NULL }\n};\n\nstatic const char *target_strerror_safe(int err)\n{\n\tconst struct nvp *n;\n\n\tn = nvp_value2name(nvp_error_target, err);\n\tif (!n->name)\n\t\treturn \"unknown\";\n\telse\n\t\treturn n->name;\n}\n\nstatic const struct jim_nvp nvp_target_event[] = {\n\n\t{ .value = TARGET_EVENT_GDB_HALT, .name = \"gdb-halt\" },\n\t{ .value = TARGET_EVENT_HALTED, .name = \"halted\" },\n\t{ .value = TARGET_EVENT_RESUMED, .name = \"resumed\" },\n\t{ .value = TARGET_EVENT_RESUME_START, .name = \"resume-start\" },\n\t{ .value = TARGET_EVENT_RESUME_END, .name = \"resume-end\" },\n\t{ .value = TARGET_EVENT_STEP_START, .name = \"step-start\" },\n\t{ .value = TARGET_EVENT_STEP_END, .name = \"step-end\" },\n\n\t{ .name = \"gdb-start\", .value = TARGET_EVENT_GDB_START },\n\t{ .name = \"gdb-end\", .value = TARGET_EVENT_GDB_END },\n\n\t{ .value = TARGET_EVENT_RESET_START,         .name = \"reset-start\" },\n\t{ .value = TARGET_EVENT_RESET_ASSERT_PRE,    .name = \"reset-assert-pre\" },\n\t{ .value = TARGET_EVENT_RESET_ASSERT,        .name = \"reset-assert\" },\n\t{ .value = TARGET_EVENT_RESET_ASSERT_POST,   .name = \"reset-assert-post\" },\n\t{ .value = TARGET_EVENT_RESET_DEASSERT_PRE,  .name = \"reset-deassert-pre\" },\n\t{ .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = \"reset-deassert-post\" },\n\t{ .value = TARGET_EVENT_RESET_INIT,          .name = \"reset-init\" },\n\t{ .value = TARGET_EVENT_RESET_END,           .name = \"reset-end\" },\n\n\t{ .value = TARGET_EVENT_EXAMINE_START, .name = \"examine-start\" },\n\t{ .value = TARGET_EVENT_EXAMINE_FAIL, .name = \"examine-fail\" },\n\t{ .value = TARGET_EVENT_EXAMINE_END, .name = \"examine-end\" },\n\n\t{ .value = TARGET_EVENT_DEBUG_HALTED, .name = \"debug-halted\" },\n\t{ .value = TARGET_EVENT_DEBUG_RESUMED, .name = \"debug-resumed\" },\n\n\t{ .value = TARGET_EVENT_GDB_ATTACH, .name = \"gdb-attach\" },\n\t{ .value = TARGET_EVENT_GDB_DETACH, .name = \"gdb-detach\" },\n\n\t{ .value = TARGET_EVENT_GDB_FLASH_WRITE_START, .name = \"gdb-flash-write-start\" },\n\t{ .value = TARGET_EVENT_GDB_FLASH_WRITE_END,   .name = \"gdb-flash-write-end\"   },\n\n\t{ .value = TARGET_EVENT_GDB_FLASH_ERASE_START, .name = \"gdb-flash-erase-start\" },\n\t{ .value = TARGET_EVENT_GDB_FLASH_ERASE_END,   .name = \"gdb-flash-erase-end\" },\n\n\t{ .value = TARGET_EVENT_TRACE_CONFIG, .name = \"trace-config\" },\n\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X100, .name = \"semihosting-user-cmd-0x100\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X101, .name = \"semihosting-user-cmd-0x101\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X102, .name = \"semihosting-user-cmd-0x102\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X103, .name = \"semihosting-user-cmd-0x103\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X104, .name = \"semihosting-user-cmd-0x104\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X105, .name = \"semihosting-user-cmd-0x105\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X106, .name = \"semihosting-user-cmd-0x106\" },\n\t{ .value = TARGET_EVENT_SEMIHOSTING_USER_CMD_0X107, .name = \"semihosting-user-cmd-0x107\" },\n\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic const struct nvp nvp_target_state[] = {\n\t{ .name = \"unknown\", .value = TARGET_UNKNOWN },\n\t{ .name = \"running\", .value = TARGET_RUNNING },\n\t{ .name = \"halted\",  .value = TARGET_HALTED },\n\t{ .name = \"reset\",   .value = TARGET_RESET },\n\t{ .name = \"debug-running\", .value = TARGET_DEBUG_RUNNING },\n\t{ .name = NULL, .value = -1 },\n};\n\nstatic const struct nvp nvp_target_debug_reason[] = {\n\t{ .name = \"debug-request\",             .value = DBG_REASON_DBGRQ },\n\t{ .name = \"breakpoint\",                .value = DBG_REASON_BREAKPOINT },\n\t{ .name = \"watchpoint\",                .value = DBG_REASON_WATCHPOINT },\n\t{ .name = \"watchpoint-and-breakpoint\", .value = DBG_REASON_WPTANDBKPT },\n\t{ .name = \"single-step\",               .value = DBG_REASON_SINGLESTEP },\n\t{ .name = \"target-not-halted\",         .value = DBG_REASON_NOTHALTED  },\n\t{ .name = \"program-exit\",              .value = DBG_REASON_EXIT },\n\t{ .name = \"exception-catch\",           .value = DBG_REASON_EXC_CATCH },\n\t{ .name = \"undefined\",                 .value = DBG_REASON_UNDEFINED },\n\t{ .name = NULL, .value = -1 },\n};\n\nstatic const struct jim_nvp nvp_target_endian[] = {\n\t{ .name = \"big\",    .value = TARGET_BIG_ENDIAN },\n\t{ .name = \"little\", .value = TARGET_LITTLE_ENDIAN },\n\t{ .name = \"be\",     .value = TARGET_BIG_ENDIAN },\n\t{ .name = \"le\",     .value = TARGET_LITTLE_ENDIAN },\n\t{ .name = NULL,     .value = -1 },\n};\n\nstatic const struct nvp nvp_reset_modes[] = {\n\t{ .name = \"unknown\", .value = RESET_UNKNOWN },\n\t{ .name = \"run\",     .value = RESET_RUN },\n\t{ .name = \"halt\",    .value = RESET_HALT },\n\t{ .name = \"init\",    .value = RESET_INIT },\n\t{ .name = NULL,      .value = -1 },\n};\n\nconst char *debug_reason_name(struct target *t)\n{\n\tconst char *cp;\n\n\tcp = nvp_value2name(nvp_target_debug_reason,\n\t\t\tt->debug_reason)->name;\n\tif (!cp) {\n\t\tLOG_ERROR(\"Invalid debug reason: %d\", (int)(t->debug_reason));\n\t\tcp = \"(*BUG*unknown*BUG*)\";\n\t}\n\treturn cp;\n}\n\nconst char *target_state_name(struct target *t)\n{\n\tconst char *cp;\n\tcp = nvp_value2name(nvp_target_state, t->state)->name;\n\tif (!cp) {\n\t\tLOG_ERROR(\"Invalid target state: %d\", (int)(t->state));\n\t\tcp = \"(*BUG*unknown*BUG*)\";\n\t}\n\n\tif (!target_was_examined(t) && t->defer_examine)\n\t\tcp = \"examine deferred\";\n\n\treturn cp;\n}\n\nconst char *target_event_name(enum target_event event)\n{\n\tconst char *cp;\n\tcp = jim_nvp_value2name_simple(nvp_target_event, event)->name;\n\tif (!cp) {\n\t\tLOG_ERROR(\"Invalid target event: %d\", (int)(event));\n\t\tcp = \"(*BUG*unknown*BUG*)\";\n\t}\n\treturn cp;\n}\n\nconst char *target_reset_mode_name(enum target_reset_mode reset_mode)\n{\n\tconst char *cp;\n\tcp = nvp_value2name(nvp_reset_modes, reset_mode)->name;\n\tif (!cp) {\n\t\tLOG_ERROR(\"Invalid target reset mode: %d\", (int)(reset_mode));\n\t\tcp = \"(*BUG*unknown*BUG*)\";\n\t}\n\treturn cp;\n}\n\n/* determine the number of the new target */\nstatic int new_target_number(void)\n{\n\tstruct target *t;\n\tint x;\n\n\t/* number is 0 based */\n\tx = -1;\n\tt = all_targets;\n\twhile (t) {\n\t\tif (x < t->target_number)\n\t\t\tx = t->target_number;\n\t\tt = t->next;\n\t}\n\treturn x + 1;\n}\n\nstatic void append_to_list_all_targets(struct target *target)\n{\n\tstruct target **t = &all_targets;\n\n\twhile (*t)\n\t\tt = &((*t)->next);\n\t*t = target;\n}\n\n/* read a uint64_t from a buffer in target memory endianness */\nuint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\treturn le_to_h_u64(buffer);\n\telse\n\t\treturn be_to_h_u64(buffer);\n}\n\n/* read a uint32_t from a buffer in target memory endianness */\nuint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\treturn le_to_h_u32(buffer);\n\telse\n\t\treturn be_to_h_u32(buffer);\n}\n\n/* read a uint24_t from a buffer in target memory endianness */\nuint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\treturn le_to_h_u24(buffer);\n\telse\n\t\treturn be_to_h_u24(buffer);\n}\n\n/* read a uint16_t from a buffer in target memory endianness */\nuint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\treturn le_to_h_u16(buffer);\n\telse\n\t\treturn be_to_h_u16(buffer);\n}\n\n/* write a uint64_t to a buffer in target memory endianness */\nvoid target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\th_u64_to_le(buffer, value);\n\telse\n\t\th_u64_to_be(buffer, value);\n}\n\n/* write a uint32_t to a buffer in target memory endianness */\nvoid target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\th_u32_to_le(buffer, value);\n\telse\n\t\th_u32_to_be(buffer, value);\n}\n\n/* write a uint24_t to a buffer in target memory endianness */\nvoid target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\th_u24_to_le(buffer, value);\n\telse\n\t\th_u24_to_be(buffer, value);\n}\n\n/* write a uint16_t to a buffer in target memory endianness */\nvoid target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value)\n{\n\tif (target->endianness == TARGET_LITTLE_ENDIAN)\n\t\th_u16_to_le(buffer, value);\n\telse\n\t\th_u16_to_be(buffer, value);\n}\n\n/* write a uint8_t to a buffer in target memory endianness */\nstatic void target_buffer_set_u8(struct target *target, uint8_t *buffer, uint8_t value)\n{\n\t*buffer = value;\n}\n\n/* write a uint64_t array to a buffer in target memory endianness */\nvoid target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\tdstbuf[i] = target_buffer_get_u64(target, &buffer[i * 8]);\n}\n\n/* write a uint32_t array to a buffer in target memory endianness */\nvoid target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\tdstbuf[i] = target_buffer_get_u32(target, &buffer[i * 4]);\n}\n\n/* write a uint16_t array to a buffer in target memory endianness */\nvoid target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\tdstbuf[i] = target_buffer_get_u16(target, &buffer[i * 2]);\n}\n\n/* write a uint64_t array to a buffer in target memory endianness */\nvoid target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\ttarget_buffer_set_u64(target, &buffer[i * 8], srcbuf[i]);\n}\n\n/* write a uint32_t array to a buffer in target memory endianness */\nvoid target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\ttarget_buffer_set_u32(target, &buffer[i * 4], srcbuf[i]);\n}\n\n/* write a uint16_t array to a buffer in target memory endianness */\nvoid target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, const uint16_t *srcbuf)\n{\n\tuint32_t i;\n\tfor (i = 0; i < count; i++)\n\t\ttarget_buffer_set_u16(target, &buffer[i * 2], srcbuf[i]);\n}\n\n/* return a pointer to a configured target; id is name or number */\nstruct target *get_target(const char *id)\n{\n\tstruct target *target;\n\n\t/* try as tcltarget name */\n\tfor (target = all_targets; target; target = target->next) {\n\t\tif (!target_name(target))\n\t\t\tcontinue;\n\t\tif (strcmp(id, target_name(target)) == 0)\n\t\t\treturn target;\n\t}\n\n\t/* It's OK to remove this fallback sometime after August 2010 or so */\n\n\t/* no match, try as number */\n\tunsigned num;\n\tif (parse_uint(id, &num) != ERROR_OK)\n\t\treturn NULL;\n\n\tfor (target = all_targets; target; target = target->next) {\n\t\tif (target->target_number == (int)num) {\n\t\t\tLOG_WARNING(\"use '%s' as target identifier, not '%u'\",\n\t\t\t\t\ttarget_name(target), num);\n\t\t\treturn target;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\n/* returns a pointer to the n-th configured target */\nstruct target *get_target_by_num(int num)\n{\n\tstruct target *target = all_targets;\n\n\twhile (target) {\n\t\tif (target->target_number == num)\n\t\t\treturn target;\n\t\ttarget = target->next;\n\t}\n\n\treturn NULL;\n}\n\nstruct target *get_current_target(struct command_context *cmd_ctx)\n{\n\tstruct target *target = get_current_target_or_null(cmd_ctx);\n\n\tif (!target) {\n\t\tLOG_ERROR(\"BUG: current_target out of bounds\");\n\t\texit(-1);\n\t}\n\n\treturn target;\n}\n\nstruct target *get_current_target_or_null(struct command_context *cmd_ctx)\n{\n\treturn cmd_ctx->current_target_override\n\t\t? cmd_ctx->current_target_override\n\t\t: cmd_ctx->current_target;\n}\n\nint target_poll(struct target *target)\n{\n\tint retval;\n\n\t/* We can't poll until after examine */\n\tif (!target_was_examined(target)) {\n\t\t/* Fail silently lest we pollute the log */\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target->type->poll(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->halt_issued) {\n\t\tif (target->state == TARGET_HALTED)\n\t\t\ttarget->halt_issued = false;\n\t\telse {\n\t\t\tint64_t t = timeval_ms() - target->halt_issued_time;\n\t\t\tif (t > DEFAULT_HALT_TIMEOUT) {\n\t\t\t\ttarget->halt_issued = false;\n\t\t\t\tLOG_INFO(\"Halt timed out, wake up GDB.\");\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_halt(struct target *target)\n{\n\tint retval;\n\t/* We can't poll until after examine */\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target->type->halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget->halt_issued = true;\n\ttarget->halt_issued_time = timeval_ms();\n\n\treturn ERROR_OK;\n}\n\n/**\n * Make the target (re)start executing using its saved execution\n * context (possibly with some modifications).\n *\n * @param target Which target should start executing.\n * @param current True to use the target's saved program counter instead\n *\tof the address parameter\n * @param address Optionally used as the program counter.\n * @param handle_breakpoints True iff breakpoints at the resumption PC\n *\tshould be skipped.  (For example, maybe execution was stopped by\n *\tsuch a breakpoint, in which case it would be counterproductive to\n *\tlet it re-trigger.\n * @param debug_execution False if all working areas allocated by OpenOCD\n *\tshould be released and/or restored to their original contents.\n *\t(This would for example be true to run some downloaded \"helper\"\n *\talgorithm code, which resides in one such working buffer and uses\n *\tanother for data storage.)\n *\n * @todo Resolve the ambiguity about what the \"debug_execution\" flag\n * signifies.  For example, Target implementations don't agree on how\n * it relates to invalidation of the register cache, or to whether\n * breakpoints and watchpoints should be enabled.  (It would seem wrong\n * to enable breakpoints when running downloaded \"helper\" algorithms\n * (debug_execution true), since the breakpoints would be set to match\n * target firmware being debugged, not the helper algorithm.... and\n * enabling them could cause such helpers to malfunction (for example,\n * by overwriting data with a breakpoint instruction.  On the other\n * hand the infrastructure for running such helpers might use this\n * procedure but rely on hardware breakpoint to detect termination.)\n */\nint target_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution)\n{\n\tint retval;\n\n\t/* We can't poll until after examine */\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUME_START);\n\n\t/* note that resume *must* be asynchronous. The CPU can halt before\n\t * we poll. The CPU can even halt at the current PC as a result of\n\t * a software breakpoint being inserted by (a bug?) the application.\n\t */\n\t/*\n\t * resume() triggers the event 'resumed'. The execution of TCL commands\n\t * in the event handler causes the polling of targets. If the target has\n\t * already halted for a breakpoint, polling will run the 'halted' event\n\t * handler before the pending 'resumed' handler.\n\t * Disable polling during resume() to guarantee the execution of handlers\n\t * in the correct order.\n\t */\n\tbool save_poll_mask = jtag_poll_mask();\n\tretval = target->type->resume(target, current, address, handle_breakpoints, debug_execution);\n\tjtag_poll_unmask(save_poll_mask);\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUME_END);\n\n\treturn retval;\n}\n\nstatic int target_process_reset(struct command_invocation *cmd, enum target_reset_mode reset_mode)\n{\n\tchar buf[100];\n\tint retval;\n\tconst struct nvp *n;\n\tn = nvp_value2name(nvp_reset_modes, reset_mode);\n\tif (!n->name) {\n\t\tLOG_ERROR(\"invalid reset mode\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct target *target;\n\tfor (target = all_targets; target; target = target->next)\n\t\ttarget_call_reset_callbacks(target, reset_mode);\n\n\t/* disable polling during reset to make reset event scripts\n\t * more predictable, i.e. dr/irscan & pathmove in events will\n\t * not have JTAG operations injected into the middle of a sequence.\n\t */\n\tbool save_poll_mask = jtag_poll_mask();\n\n\tsprintf(buf, \"ocd_process_reset %s\", n->name);\n\tretval = Jim_Eval(cmd->ctx->interp, buf);\n\n\tjtag_poll_unmask(save_poll_mask);\n\n\tif (retval != JIM_OK) {\n\t\tJim_MakeErrorMessage(cmd->ctx->interp);\n\t\tcommand_print(cmd, \"%s\", Jim_GetString(Jim_GetResult(cmd->ctx->interp), NULL));\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* We want any events to be processed before the prompt */\n\tretval = target_call_timer_callbacks_now();\n\n\tfor (target = all_targets; target; target = target->next) {\n\t\ttarget->type->check_reset(target);\n\t\ttarget->running_alg = false;\n\t}\n\n\treturn retval;\n}\n\nstatic int identity_virt2phys(struct target *target,\n\t\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\t*physical = virtual;\n\treturn ERROR_OK;\n}\n\nstatic int no_mmu(struct target *target, int *enabled)\n{\n\t*enabled = 0;\n\treturn ERROR_OK;\n}\n\n/**\n * Reset the @c examined flag for the given target.\n * Pure paranoia -- targets are zeroed on allocation.\n */\nstatic inline void target_reset_examined(struct target *target)\n{\n\ttarget->examined = false;\n}\n\nstatic int default_examine(struct target *target)\n{\n\ttarget_set_examined(target);\n\treturn ERROR_OK;\n}\n\n/* no check by default */\nstatic int default_check_reset(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\n/* Equivalent Tcl code arp_examine_one is in src/target/startup.tcl\n * Keep in sync */\nint target_examine_one(struct target *target)\n{\n\ttarget_call_event_callbacks(target, TARGET_EVENT_EXAMINE_START);\n\n\tint retval = target->type->examine(target);\n\tif (retval != ERROR_OK) {\n\t\ttarget_reset_examined(target);\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_EXAMINE_FAIL);\n\t\treturn retval;\n\t}\n\n\ttarget_set_examined(target);\n\ttarget_call_event_callbacks(target, TARGET_EVENT_EXAMINE_END);\n\n\treturn ERROR_OK;\n}\n\nstatic int jtag_enable_callback(enum jtag_event event, void *priv)\n{\n\tstruct target *target = priv;\n\n\tif (event != JTAG_TAP_EVENT_ENABLE || !target->tap->enabled)\n\t\treturn ERROR_OK;\n\n\tjtag_unregister_event_callback(jtag_enable_callback, target);\n\n\treturn target_examine_one(target);\n}\n\n/* Targets that correctly implement init + examine, i.e.\n * no communication with target during init:\n *\n * XScale\n */\nint target_examine(void)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target;\n\n\tfor (target = all_targets; target; target = target->next) {\n\t\t/* defer examination, but don't skip it */\n\t\tif (!target->tap->enabled) {\n\t\t\tjtag_register_event_callback(jtag_enable_callback,\n\t\t\t\t\ttarget);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (target->defer_examine)\n\t\t\tcontinue;\n\n\t\tint retval2 = target_examine_one(target);\n\t\tif (retval2 != ERROR_OK) {\n\t\t\tLOG_WARNING(\"target %s examination failed\", target_name(target));\n\t\t\tretval = retval2;\n\t\t}\n\t}\n\treturn retval;\n}\n\nconst char *target_type_name(struct target *target)\n{\n\treturn target->type->name;\n}\n\nstatic int target_soft_reset_halt(struct target *target)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->soft_reset_halt) {\n\t\tLOG_ERROR(\"Target %s does not support soft_reset_halt\",\n\t\t\t\ttarget_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn target->type->soft_reset_halt(target);\n}\n\n/**\n * Downloads a target-specific native code algorithm to the target,\n * and executes it.  * Note that some targets may need to set up, enable,\n * and tear down a breakpoint (hard or * soft) to detect algorithm\n * termination, while others may support  lower overhead schemes where\n * soft breakpoints embedded in the algorithm automatically terminate the\n * algorithm.\n *\n * @param target used to run the algorithm\n * @param num_mem_params\n * @param mem_params\n * @param num_reg_params\n * @param reg_param\n * @param entry_point\n * @param exit_point\n * @param timeout_ms\n * @param arch_info target-specific description of the algorithm.\n */\nint target_run_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_param,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info)\n{\n\tint retval = ERROR_FAIL;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\tgoto done;\n\t}\n\tif (!target->type->run_algorithm) {\n\t\tLOG_ERROR(\"Target type '%s' does not support %s\",\n\t\t\t\ttarget_type_name(target), __func__);\n\t\tgoto done;\n\t}\n\n\ttarget->running_alg = true;\n\tretval = target->type->run_algorithm(target,\n\t\t\tnum_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_param,\n\t\t\tentry_point, exit_point, timeout_ms, arch_info);\n\ttarget->running_alg = false;\n\ndone:\n\treturn retval;\n}\n\n/**\n * Executes a target-specific native code algorithm and leaves it running.\n *\n * @param target used to run the algorithm\n * @param num_mem_params\n * @param mem_params\n * @param num_reg_params\n * @param reg_params\n * @param entry_point\n * @param exit_point\n * @param arch_info target-specific description of the algorithm.\n */\nint target_start_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tvoid *arch_info)\n{\n\tint retval = ERROR_FAIL;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\tgoto done;\n\t}\n\tif (!target->type->start_algorithm) {\n\t\tLOG_ERROR(\"Target type '%s' does not support %s\",\n\t\t\t\ttarget_type_name(target), __func__);\n\t\tgoto done;\n\t}\n\tif (target->running_alg) {\n\t\tLOG_ERROR(\"Target is already running an algorithm\");\n\t\tgoto done;\n\t}\n\n\ttarget->running_alg = true;\n\tretval = target->type->start_algorithm(target,\n\t\t\tnum_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\tentry_point, exit_point, arch_info);\n\ndone:\n\treturn retval;\n}\n\n/**\n * Waits for an algorithm started with target_start_algorithm() to complete.\n *\n * @param target used to run the algorithm\n * @param num_mem_params\n * @param mem_params\n * @param num_reg_params\n * @param reg_params\n * @param exit_point\n * @param timeout_ms\n * @param arch_info target-specific description of the algorithm.\n */\nint target_wait_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms,\n\t\tvoid *arch_info)\n{\n\tint retval = ERROR_FAIL;\n\n\tif (!target->type->wait_algorithm) {\n\t\tLOG_ERROR(\"Target type '%s' does not support %s\",\n\t\t\t\ttarget_type_name(target), __func__);\n\t\tgoto done;\n\t}\n\tif (!target->running_alg) {\n\t\tLOG_ERROR(\"Target is not running an algorithm\");\n\t\tgoto done;\n\t}\n\n\tretval = target->type->wait_algorithm(target,\n\t\t\tnum_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\texit_point, timeout_ms, arch_info);\n\tif (retval != ERROR_TARGET_TIMEOUT)\n\t\ttarget->running_alg = false;\n\ndone:\n\treturn retval;\n}\n\n/**\n * Streams data to a circular buffer on target intended for consumption by code\n * running asynchronously on target.\n *\n * This is intended for applications where target-specific native code runs\n * on the target, receives data from the circular buffer, does something with\n * it (most likely writing it to a flash memory), and advances the circular\n * buffer pointer.\n *\n * This assumes that the helper algorithm has already been loaded to the target,\n * but has not been started yet. Given memory and register parameters are passed\n * to the algorithm.\n *\n * The buffer is defined by (buffer_start, buffer_size) arguments and has the\n * following format:\n *\n *     [buffer_start + 0, buffer_start + 4):\n *         Write Pointer address (aka head). Written and updated by this\n *         routine when new data is written to the circular buffer.\n *     [buffer_start + 4, buffer_start + 8):\n *         Read Pointer address (aka tail). Updated by code running on the\n *         target after it consumes data.\n *     [buffer_start + 8, buffer_start + buffer_size):\n *         Circular buffer contents.\n *\n * See contrib/loaders/flash/stm32f1x.S for an example.\n *\n * @param target used to run the algorithm\n * @param buffer address on the host where data to be sent is located\n * @param count number of blocks to send\n * @param block_size size in bytes of each block\n * @param num_mem_params count of memory-based params to pass to algorithm\n * @param mem_params memory-based params to pass to algorithm\n * @param num_reg_params count of register-based params to pass to algorithm\n * @param reg_params memory-based params to pass to algorithm\n * @param buffer_start address on the target of the circular buffer structure\n * @param buffer_size size of the circular buffer structure\n * @param entry_point address on the target to execute to start the algorithm\n * @param exit_point address at which to set a breakpoint to catch the\n *     end of the algorithm; can be 0 if target triggers a breakpoint itself\n * @param arch_info\n */\n\nint target_run_flash_async_algorithm(struct target *target,\n\t\tconst uint8_t *buffer, uint32_t count, int block_size,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\tuint32_t buffer_start, uint32_t buffer_size,\n\t\tuint32_t entry_point, uint32_t exit_point, void *arch_info)\n{\n\tint retval;\n\tint timeout = 0;\n\n\tconst uint8_t *buffer_orig = buffer;\n\n\t/* Set up working area. First word is write pointer, second word is read pointer,\n\t * rest is fifo data area. */\n\tuint32_t wp_addr = buffer_start;\n\tuint32_t rp_addr = buffer_start + 4;\n\tuint32_t fifo_start_addr = buffer_start + 8;\n\tuint32_t fifo_end_addr = buffer_start + buffer_size;\n\n\tuint32_t wp = fifo_start_addr;\n\tuint32_t rp = fifo_start_addr;\n\n\t/* validate block_size is 2^n */\n\tassert(IS_PWR_OF_2(block_size));\n\n\tretval = target_write_u32(target, wp_addr, wp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, rp_addr, rp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Start up algorithm on target and let it idle while writing the first chunk */\n\tretval = target_start_algorithm(target, num_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\tentry_point,\n\t\t\texit_point,\n\t\t\tarch_info);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"error starting target flash write algorithm\");\n\t\treturn retval;\n\t}\n\n\twhile (count > 0) {\n\n\t\tretval = target_read_u32(target, rp_addr, &rp);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to get read pointer\");\n\t\t\tbreak;\n\t\t}\n\n\t\tLOG_DEBUG(\"offs 0x%zx count 0x%\" PRIx32 \" wp 0x%\" PRIx32 \" rp 0x%\" PRIx32,\n\t\t\t(size_t) (buffer - buffer_orig), count, wp, rp);\n\n\t\tif (rp == 0) {\n\t\t\tLOG_ERROR(\"flash write algorithm aborted by target\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!IS_ALIGNED(rp - fifo_start_addr, block_size) || rp < fifo_start_addr || rp >= fifo_end_addr) {\n\t\t\tLOG_ERROR(\"corrupted fifo read pointer 0x%\" PRIx32, rp);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Count the number of bytes available in the fifo without\n\t\t * crossing the wrap around. Make sure to not fill it completely,\n\t\t * because that would make wp == rp and that's the empty condition. */\n\t\tuint32_t thisrun_bytes;\n\t\tif (rp > wp)\n\t\t\tthisrun_bytes = rp - wp - block_size;\n\t\telse if (rp > fifo_start_addr)\n\t\t\tthisrun_bytes = fifo_end_addr - wp;\n\t\telse\n\t\t\tthisrun_bytes = fifo_end_addr - wp - block_size;\n\n\t\tif (thisrun_bytes == 0) {\n\t\t\t/* Throttle polling a bit if transfer is (much) faster than flash\n\t\t\t * programming. The exact delay shouldn't matter as long as it's\n\t\t\t * less than buffer size / flash speed. This is very unlikely to\n\t\t\t * run when using high latency connections such as USB. */\n\t\t\talive_sleep(2);\n\n\t\t\t/* to stop an infinite loop on some targets check and increment a timeout\n\t\t\t * this issue was observed on a stellaris using the new ICDI interface */\n\t\t\tif (timeout++ >= 2500) {\n\t\t\t\tLOG_ERROR(\"timeout waiting for algorithm, a target reset is recommended\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* reset our timeout */\n\t\ttimeout = 0;\n\n\t\t/* Limit to the amount of data we actually want to write */\n\t\tif (thisrun_bytes > count * block_size)\n\t\t\tthisrun_bytes = count * block_size;\n\n\t\t/* Force end of large blocks to be word aligned */\n\t\tif (thisrun_bytes >= 16)\n\t\t\tthisrun_bytes -= (rp + thisrun_bytes) & 0x03;\n\n\t\t/* Write data to fifo */\n\t\tretval = target_write_buffer(target, wp, thisrun_bytes, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Update counters and wrap write pointer */\n\t\tbuffer += thisrun_bytes;\n\t\tcount -= thisrun_bytes / block_size;\n\t\twp += thisrun_bytes;\n\t\tif (wp >= fifo_end_addr)\n\t\t\twp = fifo_start_addr;\n\n\t\t/* Store updated write pointer to target */\n\t\tretval = target_write_u32(target, wp_addr, wp);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Avoid GDB timeouts */\n\t\tkeep_alive();\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\t/* abort flash write algorithm on target */\n\t\ttarget_write_u32(target, wp_addr, 0);\n\t}\n\n\tint retval2 = target_wait_algorithm(target, num_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\texit_point,\n\t\t\t10000,\n\t\t\tarch_info);\n\n\tif (retval2 != ERROR_OK) {\n\t\tLOG_ERROR(\"error waiting for target flash write algorithm\");\n\t\tretval = retval2;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\t/* check if algorithm set rp = 0 after fifo writer loop finished */\n\t\tretval = target_read_u32(target, rp_addr, &rp);\n\t\tif (retval == ERROR_OK && rp == 0) {\n\t\t\tLOG_ERROR(\"flash write algorithm aborted by target\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint target_run_read_async_algorithm(struct target *target,\n\t\tuint8_t *buffer, uint32_t count, int block_size,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\tuint32_t buffer_start, uint32_t buffer_size,\n\t\tuint32_t entry_point, uint32_t exit_point, void *arch_info)\n{\n\tint retval;\n\tint timeout = 0;\n\n\tconst uint8_t *buffer_orig = buffer;\n\n\t/* Set up working area. First word is write pointer, second word is read pointer,\n\t * rest is fifo data area. */\n\tuint32_t wp_addr = buffer_start;\n\tuint32_t rp_addr = buffer_start + 4;\n\tuint32_t fifo_start_addr = buffer_start + 8;\n\tuint32_t fifo_end_addr = buffer_start + buffer_size;\n\n\tuint32_t wp = fifo_start_addr;\n\tuint32_t rp = fifo_start_addr;\n\n\t/* validate block_size is 2^n */\n\tassert(IS_PWR_OF_2(block_size));\n\n\tretval = target_write_u32(target, wp_addr, wp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tretval = target_write_u32(target, rp_addr, rp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* Start up algorithm on target */\n\tretval = target_start_algorithm(target, num_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\tentry_point,\n\t\t\texit_point,\n\t\t\tarch_info);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"error starting target flash read algorithm\");\n\t\treturn retval;\n\t}\n\n\twhile (count > 0) {\n\t\tretval = target_read_u32(target, wp_addr, &wp);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"failed to get write pointer\");\n\t\t\tbreak;\n\t\t}\n\n\t\tLOG_DEBUG(\"offs 0x%zx count 0x%\" PRIx32 \" wp 0x%\" PRIx32 \" rp 0x%\" PRIx32,\n\t\t\t(size_t)(buffer - buffer_orig), count, wp, rp);\n\n\t\tif (wp == 0) {\n\t\t\tLOG_ERROR(\"flash read algorithm aborted by target\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!IS_ALIGNED(wp - fifo_start_addr, block_size) || wp < fifo_start_addr || wp >= fifo_end_addr) {\n\t\t\tLOG_ERROR(\"corrupted fifo write pointer 0x%\" PRIx32, wp);\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Count the number of bytes available in the fifo without\n\t\t * crossing the wrap around. */\n\t\tuint32_t thisrun_bytes;\n\t\tif (wp >= rp)\n\t\t\tthisrun_bytes = wp - rp;\n\t\telse\n\t\t\tthisrun_bytes = fifo_end_addr - rp;\n\n\t\tif (thisrun_bytes == 0) {\n\t\t\t/* Throttle polling a bit if transfer is (much) faster than flash\n\t\t\t * reading. The exact delay shouldn't matter as long as it's\n\t\t\t * less than buffer size / flash speed. This is very unlikely to\n\t\t\t * run when using high latency connections such as USB. */\n\t\t\talive_sleep(2);\n\n\t\t\t/* to stop an infinite loop on some targets check and increment a timeout\n\t\t\t * this issue was observed on a stellaris using the new ICDI interface */\n\t\t\tif (timeout++ >= 2500) {\n\t\t\t\tLOG_ERROR(\"timeout waiting for algorithm, a target reset is recommended\");\n\t\t\t\treturn ERROR_FLASH_OPERATION_FAILED;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Reset our timeout */\n\t\ttimeout = 0;\n\n\t\t/* Limit to the amount of data we actually want to read */\n\t\tif (thisrun_bytes > count * block_size)\n\t\t\tthisrun_bytes = count * block_size;\n\n\t\t/* Force end of large blocks to be word aligned */\n\t\tif (thisrun_bytes >= 16)\n\t\t\tthisrun_bytes -= (rp + thisrun_bytes) & 0x03;\n\n\t\t/* Read data from fifo */\n\t\tretval = target_read_buffer(target, rp, thisrun_bytes, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Update counters and wrap write pointer */\n\t\tbuffer += thisrun_bytes;\n\t\tcount -= thisrun_bytes / block_size;\n\t\trp += thisrun_bytes;\n\t\tif (rp >= fifo_end_addr)\n\t\t\trp = fifo_start_addr;\n\n\t\t/* Store updated write pointer to target */\n\t\tretval = target_write_u32(target, rp_addr, rp);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\t/* Avoid GDB timeouts */\n\t\tkeep_alive();\n\n\t}\n\n\tif (retval != ERROR_OK) {\n\t\t/* abort flash write algorithm on target */\n\t\ttarget_write_u32(target, rp_addr, 0);\n\t}\n\n\tint retval2 = target_wait_algorithm(target, num_mem_params, mem_params,\n\t\t\tnum_reg_params, reg_params,\n\t\t\texit_point,\n\t\t\t10000,\n\t\t\tarch_info);\n\n\tif (retval2 != ERROR_OK) {\n\t\tLOG_ERROR(\"error waiting for target flash write algorithm\");\n\t\tretval = retval2;\n\t}\n\n\tif (retval == ERROR_OK) {\n\t\t/* check if algorithm set wp = 0 after fifo writer loop finished */\n\t\tretval = target_read_u32(target, wp_addr, &wp);\n\t\tif (retval == ERROR_OK && wp == 0) {\n\t\t\tLOG_ERROR(\"flash read algorithm aborted by target\");\n\t\t\tretval = ERROR_FLASH_OPERATION_FAILED;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint target_read_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->read_memory) {\n\t\tLOG_ERROR(\"Target %s doesn't support read_memory\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn target->type->read_memory(target, address, size, count, buffer);\n}\n\nint target_read_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->read_phys_memory) {\n\t\tLOG_ERROR(\"Target %s doesn't support read_phys_memory\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn target->type->read_phys_memory(target, address, size, count, buffer);\n}\n\nint target_write_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->write_memory) {\n\t\tLOG_ERROR(\"Target %s doesn't support write_memory\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn target->type->write_memory(target, address, size, count, buffer);\n}\n\nint target_write_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->write_phys_memory) {\n\t\tLOG_ERROR(\"Target %s doesn't support write_phys_memory\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\treturn target->type->write_phys_memory(target, address, size, count, buffer);\n}\n\nint target_add_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tif ((target->state != TARGET_HALTED) && (breakpoint->type != BKPT_HARD)) {\n\t\tLOG_WARNING(\"target %s is not halted (add breakpoint)\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->add_breakpoint(target, breakpoint);\n}\n\nint target_add_context_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (add context breakpoint)\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->add_context_breakpoint(target, breakpoint);\n}\n\nint target_add_hybrid_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (add hybrid breakpoint)\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->add_hybrid_breakpoint(target, breakpoint);\n}\n\nint target_remove_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint)\n{\n\treturn target->type->remove_breakpoint(target, breakpoint);\n}\n\nint target_add_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (add watchpoint)\", target_name(target));\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->add_watchpoint(target, watchpoint);\n}\nint target_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint)\n{\n\treturn target->type->remove_watchpoint(target, watchpoint);\n}\nint target_hit_watchpoint(struct target *target,\n\t\tstruct watchpoint **hit_watchpoint)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (hit watchpoint)\", target->cmd_name);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!target->type->hit_watchpoint) {\n\t\t/* For backward compatible, if hit_watchpoint is not implemented,\n\t\t * return ERROR_FAIL such that gdb_server will not take the nonsense\n\t\t * information. */\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn target->type->hit_watchpoint(target, hit_watchpoint);\n}\n\nconst char *target_get_gdb_arch(struct target *target)\n{\n\tif (!target->type->get_gdb_arch)\n\t\treturn NULL;\n\treturn target->type->get_gdb_arch(target);\n}\n\nint target_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class)\n{\n\tint result = ERROR_FAIL;\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\tgoto done;\n\t}\n\n\tresult = target->type->get_gdb_reg_list(target, reg_list,\n\t\t\treg_list_size, reg_class);\n\ndone:\n\tif (result != ERROR_OK) {\n\t\t*reg_list = NULL;\n\t\t*reg_list_size = 0;\n\t}\n\treturn result;\n}\n\nint target_get_gdb_reg_list_noread(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class)\n{\n\tif (target->type->get_gdb_reg_list_noread &&\n\t\t\ttarget->type->get_gdb_reg_list_noread(target, reg_list,\n\t\t\t\treg_list_size, reg_class) == ERROR_OK)\n\t\treturn ERROR_OK;\n\treturn target_get_gdb_reg_list(target, reg_list, reg_list_size, reg_class);\n}\n\nbool target_supports_gdb_connection(struct target *target)\n{\n\t/*\n\t * exclude all the targets that don't provide get_gdb_reg_list\n\t * or that have explicit gdb_max_connection == 0\n\t */\n\treturn !!target->type->get_gdb_reg_list && !!target->gdb_max_connections;\n}\n\nint target_step(struct target *target,\n\t\tint current, target_addr_t address, int handle_breakpoints)\n{\n\tint retval;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_STEP_START);\n\n\tretval = target->type->step(target, current, address, handle_breakpoints);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_STEP_END);\n\n\treturn retval;\n}\n\nint target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (gdb fileio)\", target->cmd_name);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->get_gdb_fileio_info(target, fileio_info);\n}\n\nint target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)\n{\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target %s is not halted (gdb fileio end)\", target->cmd_name);\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\treturn target->type->gdb_fileio_end(target, retcode, fileio_errno, ctrl_c);\n}\n\ntarget_addr_t target_address_max(struct target *target)\n{\n\tunsigned bits = target_address_bits(target);\n\tif (sizeof(target_addr_t) * 8 == bits)\n\t\treturn (target_addr_t) -1;\n\telse\n\t\treturn (((target_addr_t) 1) << bits) - 1;\n}\n\nunsigned target_address_bits(struct target *target)\n{\n\tif (target->type->address_bits)\n\t\treturn target->type->address_bits(target);\n\treturn 32;\n}\n\nunsigned int target_data_bits(struct target *target)\n{\n\tif (target->type->data_bits)\n\t\treturn target->type->data_bits(target);\n\treturn 32;\n}\n\nstatic int target_profiling(struct target *target, uint32_t *samples,\n\t\t\tuint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)\n{\n\treturn target->type->profiling(target, samples, max_num_samples,\n\t\t\tnum_samples, seconds);\n}\n\nstatic int handle_target(void *priv);\n\nstatic int target_init_one(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\ttarget_reset_examined(target);\n\n\tstruct target_type *type = target->type;\n\tif (!type->examine)\n\t\ttype->examine = default_examine;\n\n\tif (!type->check_reset)\n\t\ttype->check_reset = default_check_reset;\n\n\tassert(type->init_target);\n\n\tint retval = type->init_target(cmd_ctx, target);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"target '%s' init failed\", target_name(target));\n\t\treturn retval;\n\t}\n\n\t/* Sanity-check MMU support ... stub in what we must, to help\n\t * implement it in stages, but warn if we need to do so.\n\t */\n\tif (type->mmu) {\n\t\tif (!type->virt2phys) {\n\t\t\tLOG_ERROR(\"type '%s' is missing virt2phys\", type->name);\n\t\t\ttype->virt2phys = identity_virt2phys;\n\t\t}\n\t} else {\n\t\t/* Make sure no-MMU targets all behave the same:  make no\n\t\t * distinction between physical and virtual addresses, and\n\t\t * ensure that virt2phys() is always an identity mapping.\n\t\t */\n\t\tif (type->write_phys_memory || type->read_phys_memory || type->virt2phys)\n\t\t\tLOG_WARNING(\"type '%s' has bad MMU hooks\", type->name);\n\n\t\ttype->mmu = no_mmu;\n\t\ttype->write_phys_memory = type->write_memory;\n\t\ttype->read_phys_memory = type->read_memory;\n\t\ttype->virt2phys = identity_virt2phys;\n\t}\n\n\tif (!target->type->read_buffer)\n\t\ttarget->type->read_buffer = target_read_buffer_default;\n\n\tif (!target->type->write_buffer)\n\t\ttarget->type->write_buffer = target_write_buffer_default;\n\n\tif (!target->type->get_gdb_fileio_info)\n\t\ttarget->type->get_gdb_fileio_info = target_get_gdb_fileio_info_default;\n\n\tif (!target->type->gdb_fileio_end)\n\t\ttarget->type->gdb_fileio_end = target_gdb_fileio_end_default;\n\n\tif (!target->type->profiling)\n\t\ttarget->type->profiling = target_profiling_default;\n\n\treturn ERROR_OK;\n}\n\nstatic int target_init(struct command_context *cmd_ctx)\n{\n\tstruct target *target;\n\tint retval;\n\n\tfor (target = all_targets; target; target = target->next) {\n\t\tretval = target_init_one(cmd_ctx, target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tif (!all_targets)\n\t\treturn ERROR_OK;\n\n\tretval = target_register_user_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = target_register_timer_callback(&handle_target,\n\t\t\tpolling_interval, TARGET_TIMER_TYPE_PERIODIC, cmd_ctx->interp);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_init_command)\n{\n\tint retval;\n\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstatic bool target_initialized;\n\tif (target_initialized) {\n\t\tLOG_INFO(\"'target init' has already been called\");\n\t\treturn ERROR_OK;\n\t}\n\ttarget_initialized = true;\n\n\tretval = command_run_line(CMD_CTX, \"init_targets\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = command_run_line(CMD_CTX, \"init_target_events\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = command_run_line(CMD_CTX, \"init_board\");\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"Initializing targets...\");\n\treturn target_init(CMD_CTX);\n}\n\nint target_register_event_callback(int (*callback)(struct target *target,\n\t\tenum target_event event, void *priv), void *priv)\n{\n\tstruct target_event_callback **callbacks_p = &target_event_callbacks;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (*callbacks_p) {\n\t\twhile ((*callbacks_p)->next)\n\t\t\tcallbacks_p = &((*callbacks_p)->next);\n\t\tcallbacks_p = &((*callbacks_p)->next);\n\t}\n\n\t(*callbacks_p) = malloc(sizeof(struct target_event_callback));\n\t(*callbacks_p)->callback = callback;\n\t(*callbacks_p)->priv = priv;\n\t(*callbacks_p)->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nint target_register_reset_callback(int (*callback)(struct target *target,\n\t\tenum target_reset_mode reset_mode, void *priv), void *priv)\n{\n\tstruct target_reset_callback *entry;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tentry = malloc(sizeof(struct target_reset_callback));\n\tif (!entry) {\n\t\tLOG_ERROR(\"error allocating buffer for reset callback entry\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tentry->callback = callback;\n\tentry->priv = priv;\n\tlist_add(&entry->list, &target_reset_callback_list);\n\n\n\treturn ERROR_OK;\n}\n\nint target_register_trace_callback(int (*callback)(struct target *target,\n\t\tsize_t len, uint8_t *data, void *priv), void *priv)\n{\n\tstruct target_trace_callback *entry;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tentry = malloc(sizeof(struct target_trace_callback));\n\tif (!entry) {\n\t\tLOG_ERROR(\"error allocating buffer for trace callback entry\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tentry->callback = callback;\n\tentry->priv = priv;\n\tlist_add(&entry->list, &target_trace_callback_list);\n\n\n\treturn ERROR_OK;\n}\n\nint target_register_timer_callback(int (*callback)(void *priv),\n\t\tunsigned int time_ms, enum target_timer_type type, void *priv)\n{\n\tstruct target_timer_callback **callbacks_p = &target_timer_callbacks;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (*callbacks_p) {\n\t\twhile ((*callbacks_p)->next)\n\t\t\tcallbacks_p = &((*callbacks_p)->next);\n\t\tcallbacks_p = &((*callbacks_p)->next);\n\t}\n\n\t(*callbacks_p) = malloc(sizeof(struct target_timer_callback));\n\t(*callbacks_p)->callback = callback;\n\t(*callbacks_p)->type = type;\n\t(*callbacks_p)->time_ms = time_ms;\n\t(*callbacks_p)->removed = false;\n\n\t(*callbacks_p)->when = timeval_ms() + time_ms;\n\ttarget_timer_next_event_value = MIN(target_timer_next_event_value, (*callbacks_p)->when);\n\n\t(*callbacks_p)->priv = priv;\n\t(*callbacks_p)->next = NULL;\n\n\treturn ERROR_OK;\n}\n\nint target_unregister_event_callback(int (*callback)(struct target *target,\n\t\tenum target_event event, void *priv), void *priv)\n{\n\tstruct target_event_callback **p = &target_event_callbacks;\n\tstruct target_event_callback *c = target_event_callbacks;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\twhile (c) {\n\t\tstruct target_event_callback *next = c->next;\n\t\tif ((c->callback == callback) && (c->priv == priv)) {\n\t\t\t*p = next;\n\t\t\tfree(c);\n\t\t\treturn ERROR_OK;\n\t\t} else\n\t\t\tp = &(c->next);\n\t\tc = next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_unregister_reset_callback(int (*callback)(struct target *target,\n\t\tenum target_reset_mode reset_mode, void *priv), void *priv)\n{\n\tstruct target_reset_callback *entry;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(entry, &target_reset_callback_list, list) {\n\t\tif (entry->callback == callback && entry->priv == priv) {\n\t\t\tlist_del(&entry->list);\n\t\t\tfree(entry);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_unregister_trace_callback(int (*callback)(struct target *target,\n\t\tsize_t len, uint8_t *data, void *priv), void *priv)\n{\n\tstruct target_trace_callback *entry;\n\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tlist_for_each_entry(entry, &target_trace_callback_list, list) {\n\t\tif (entry->callback == callback && entry->priv == priv) {\n\t\t\tlist_del(&entry->list);\n\t\t\tfree(entry);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_unregister_timer_callback(int (*callback)(void *priv), void *priv)\n{\n\tif (!callback)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (struct target_timer_callback *c = target_timer_callbacks;\n\t     c; c = c->next) {\n\t\tif ((c->callback == callback) && (c->priv == priv)) {\n\t\t\tc->removed = true;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\treturn ERROR_FAIL;\n}\n\nint target_call_event_callbacks(struct target *target, enum target_event event)\n{\n\tstruct target_event_callback *callback = target_event_callbacks;\n\tstruct target_event_callback *next_callback;\n\n\tif (event == TARGET_EVENT_HALTED) {\n\t\t/* execute early halted first */\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n\t}\n\n\tLOG_DEBUG(\"target event %i (%s) for core %s\", event,\n\t\t\ttarget_event_name(event),\n\t\t\ttarget_name(target));\n\n\ttarget_handle_event(target, event);\n\n\twhile (callback) {\n\t\tnext_callback = callback->next;\n\t\tcallback->callback(target, event, callback->priv);\n\t\tcallback = next_callback;\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode)\n{\n\tstruct target_reset_callback *callback;\n\n\tLOG_DEBUG(\"target reset %i (%s)\", reset_mode,\n\t\t\tnvp_value2name(nvp_reset_modes, reset_mode)->name);\n\n\tlist_for_each_entry(callback, &target_reset_callback_list, list)\n\t\tcallback->callback(target, reset_mode, callback->priv);\n\n\treturn ERROR_OK;\n}\n\nint target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data)\n{\n\tstruct target_trace_callback *callback;\n\n\tlist_for_each_entry(callback, &target_trace_callback_list, list)\n\t\tcallback->callback(target, len, data, callback->priv);\n\n\treturn ERROR_OK;\n}\n\nstatic int target_timer_callback_periodic_restart(\n\t\tstruct target_timer_callback *cb, int64_t *now)\n{\n\tcb->when = *now + cb->time_ms;\n\treturn ERROR_OK;\n}\n\nstatic int target_call_timer_callback(struct target_timer_callback *cb,\n\t\tint64_t *now)\n{\n\tcb->callback(cb->priv);\n\n\tif (cb->type == TARGET_TIMER_TYPE_PERIODIC)\n\t\treturn target_timer_callback_periodic_restart(cb, now);\n\n\treturn target_unregister_timer_callback(cb->callback, cb->priv);\n}\n\nstatic int target_call_timer_callbacks_check_time(int checktime)\n{\n\tstatic bool callback_processing;\n\n\t/* Do not allow nesting */\n\tif (callback_processing)\n\t\treturn ERROR_OK;\n\n\tcallback_processing = true;\n\n\tkeep_alive();\n\n\tint64_t now = timeval_ms();\n\n\t/* Initialize to a default value that's a ways into the future.\n\t * The loop below will make it closer to now if there are\n\t * callbacks that want to be called sooner. */\n\ttarget_timer_next_event_value = now + 1000;\n\n\t/* Store an address of the place containing a pointer to the\n\t * next item; initially, that's a standalone \"root of the\n\t * list\" variable. */\n\tstruct target_timer_callback **callback = &target_timer_callbacks;\n\twhile (callback && *callback) {\n\t\tif ((*callback)->removed) {\n\t\t\tstruct target_timer_callback *p = *callback;\n\t\t\t*callback = (*callback)->next;\n\t\t\tfree(p);\n\t\t\tcontinue;\n\t\t}\n\n\t\tbool call_it = (*callback)->callback &&\n\t\t\t((!checktime && (*callback)->type == TARGET_TIMER_TYPE_PERIODIC) ||\n\t\t\t now >= (*callback)->when);\n\n\t\tif (call_it)\n\t\t\ttarget_call_timer_callback(*callback, &now);\n\n\t\tif (!(*callback)->removed && (*callback)->when < target_timer_next_event_value)\n\t\t\ttarget_timer_next_event_value = (*callback)->when;\n\n\t\tcallback = &(*callback)->next;\n\t}\n\n\tcallback_processing = false;\n\treturn ERROR_OK;\n}\n\nint target_call_timer_callbacks(void)\n{\n\treturn target_call_timer_callbacks_check_time(1);\n}\n\n/* invoke periodic callbacks immediately */\nint target_call_timer_callbacks_now(void)\n{\n\treturn target_call_timer_callbacks_check_time(0);\n}\n\nint64_t target_timer_next_event(void)\n{\n\treturn target_timer_next_event_value;\n}\n\n/* Prints the working area layout for debug purposes */\nstatic void print_wa_layout(struct target *target)\n{\n\tstruct working_area *c = target->working_areas;\n\n\twhile (c) {\n\t\tLOG_DEBUG(\"%c%c \" TARGET_ADDR_FMT \"-\" TARGET_ADDR_FMT \" (%\" PRIu32 \" bytes)\",\n\t\t\tc->backup ? 'b' : ' ', c->free ? ' ' : '*',\n\t\t\tc->address, c->address + c->size - 1, c->size);\n\t\tc = c->next;\n\t}\n}\n\n/* Reduce area to size bytes, create a new free area from the remaining bytes, if any. */\nstatic void target_split_working_area(struct working_area *area, uint32_t size)\n{\n\tassert(area->free); /* Shouldn't split an allocated area */\n\tassert(size <= area->size); /* Caller should guarantee this */\n\n\t/* Split only if not already the right size */\n\tif (size < area->size) {\n\t\tstruct working_area *new_wa = malloc(sizeof(*new_wa));\n\n\t\tif (!new_wa)\n\t\t\treturn;\n\n\t\tnew_wa->next = area->next;\n\t\tnew_wa->size = area->size - size;\n\t\tnew_wa->address = area->address + size;\n\t\tnew_wa->backup = NULL;\n\t\tnew_wa->user = NULL;\n\t\tnew_wa->free = true;\n\n\t\tarea->next = new_wa;\n\t\tarea->size = size;\n\n\t\t/* If backup memory was allocated to this area, it has the wrong size\n\t\t * now so free it and it will be reallocated if/when needed */\n\t\tfree(area->backup);\n\t\tarea->backup = NULL;\n\t}\n}\n\n/* Merge all adjacent free areas into one */\nstatic void target_merge_working_areas(struct target *target)\n{\n\tstruct working_area *c = target->working_areas;\n\n\twhile (c && c->next) {\n\t\tassert(c->next->address == c->address + c->size); /* This is an invariant */\n\n\t\t/* Find two adjacent free areas */\n\t\tif (c->free && c->next->free) {\n\t\t\t/* Merge the last into the first */\n\t\t\tc->size += c->next->size;\n\n\t\t\t/* Remove the last */\n\t\t\tstruct working_area *to_be_freed = c->next;\n\t\t\tc->next = c->next->next;\n\t\t\tfree(to_be_freed->backup);\n\t\t\tfree(to_be_freed);\n\n\t\t\t/* If backup memory was allocated to the remaining area, it's has\n\t\t\t * the wrong size now */\n\t\t\tfree(c->backup);\n\t\t\tc->backup = NULL;\n\t\t} else {\n\t\t\tc = c->next;\n\t\t}\n\t}\n}\n\nint target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)\n{\n\t/* Reevaluate working area address based on MMU state*/\n\tif (!target->working_areas) {\n\t\tint retval;\n\t\tint enabled;\n\n\t\tretval = target->type->mmu(target, &enabled);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tif (!enabled) {\n\t\t\tif (target->working_area_phys_spec) {\n\t\t\t\tLOG_DEBUG(\"MMU disabled, using physical \"\n\t\t\t\t\t\"address for working memory \" TARGET_ADDR_FMT,\n\t\t\t\t\ttarget->working_area_phys);\n\t\t\t\ttarget->working_area = target->working_area_phys;\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"No working memory available. \"\n\t\t\t\t\t\"Specify -work-area-phys to target.\");\n\t\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\t}\n\t\t} else {\n\t\t\tif (target->working_area_virt_spec) {\n\t\t\t\tLOG_DEBUG(\"MMU enabled, using virtual \"\n\t\t\t\t\t\"address for working memory \" TARGET_ADDR_FMT,\n\t\t\t\t\ttarget->working_area_virt);\n\t\t\t\ttarget->working_area = target->working_area_virt;\n\t\t\t} else {\n\t\t\t\tLOG_ERROR(\"No working memory available. \"\n\t\t\t\t\t\"Specify -work-area-virt to target.\");\n\t\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t\t}\n\t\t}\n\n\t\t/* Set up initial working area on first call */\n\t\tstruct working_area *new_wa = malloc(sizeof(*new_wa));\n\t\tif (new_wa) {\n\t\t\tnew_wa->next = NULL;\n\t\t\tnew_wa->size = ALIGN_DOWN(target->working_area_size, 4); /* 4-byte align */\n\t\t\tnew_wa->address = target->working_area;\n\t\t\tnew_wa->backup = NULL;\n\t\t\tnew_wa->user = NULL;\n\t\t\tnew_wa->free = true;\n\t\t}\n\n\t\ttarget->working_areas = new_wa;\n\t}\n\n\t/* only allocate multiples of 4 byte */\n\tsize = ALIGN_UP(size, 4);\n\n\tstruct working_area *c = target->working_areas;\n\n\t/* Find the first large enough working area */\n\twhile (c) {\n\t\tif (c->free && c->size >= size)\n\t\t\tbreak;\n\t\tc = c->next;\n\t}\n\n\tif (!c)\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\t/* Split the working area into the requested size */\n\ttarget_split_working_area(c, size);\n\n\tLOG_DEBUG(\"allocated new working area of %\" PRIu32 \" bytes at address \" TARGET_ADDR_FMT,\n\t\t\t  size, c->address);\n\n\tif (target->backup_working_area) {\n\t\tif (!c->backup) {\n\t\t\tc->backup = malloc(c->size);\n\t\t\tif (!c->backup)\n\t\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tint retval = target_read_memory(target, c->address, 4, c->size / 4, c->backup);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* mark as used, and return the new (reused) area */\n\tc->free = false;\n\t*area = c;\n\n\t/* user pointer */\n\tc->user = area;\n\n\tprint_wa_layout(target);\n\n\treturn ERROR_OK;\n}\n\nint target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)\n{\n\tint retval;\n\n\tretval = target_alloc_working_area_try(target, size, area);\n\tif (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)\n\t\tLOG_WARNING(\"not enough working area available(requested %\"PRIu32\")\", size);\n\treturn retval;\n\n}\n\nstatic int target_restore_working_area(struct target *target, struct working_area *area)\n{\n\tint retval = ERROR_OK;\n\n\tif (target->backup_working_area && area->backup) {\n\t\tretval = target_write_memory(target, area->address, 4, area->size / 4, area->backup);\n\t\tif (retval != ERROR_OK)\n\t\t\tLOG_ERROR(\"failed to restore %\" PRIu32 \" bytes of working area at address \" TARGET_ADDR_FMT,\n\t\t\t\t\tarea->size, area->address);\n\t}\n\n\treturn retval;\n}\n\n/* Restore the area's backup memory, if any, and return the area to the allocation pool */\nstatic int target_free_working_area_restore(struct target *target, struct working_area *area, int restore)\n{\n\tif (!area || area->free)\n\t\treturn ERROR_OK;\n\n\tint retval = ERROR_OK;\n\tif (restore) {\n\t\tretval = target_restore_working_area(target, area);\n\t\t/* REVISIT: Perhaps the area should be freed even if restoring fails. */\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tarea->free = true;\n\n\tLOG_DEBUG(\"freed %\" PRIu32 \" bytes of working area at address \" TARGET_ADDR_FMT,\n\t\t\tarea->size, area->address);\n\n\t/* mark user pointer invalid */\n\t/* TODO: Is this really safe? It points to some previous caller's memory.\n\t * How could we know that the area pointer is still in that place and not\n\t * some other vital data? What's the purpose of this, anyway? */\n\t*area->user = NULL;\n\tarea->user = NULL;\n\n\ttarget_merge_working_areas(target);\n\n\tprint_wa_layout(target);\n\n\treturn retval;\n}\n\nint target_free_working_area(struct target *target, struct working_area *area)\n{\n\treturn target_free_working_area_restore(target, area, 1);\n}\n\n/* free resources and restore memory, if restoring memory fails,\n * free up resources anyway\n */\nstatic void target_free_all_working_areas_restore(struct target *target, int restore)\n{\n\tstruct working_area *c = target->working_areas;\n\n\tLOG_DEBUG(\"freeing all working areas\");\n\n\t/* Loop through all areas, restoring the allocated ones and marking them as free */\n\twhile (c) {\n\t\tif (!c->free) {\n\t\t\tif (restore)\n\t\t\t\ttarget_restore_working_area(target, c);\n\t\t\tc->free = true;\n\t\t\t*c->user = NULL; /* Same as above */\n\t\t\tc->user = NULL;\n\t\t}\n\t\tc = c->next;\n\t}\n\n\t/* Run a merge pass to combine all areas into one */\n\ttarget_merge_working_areas(target);\n\n\tprint_wa_layout(target);\n}\n\nvoid target_free_all_working_areas(struct target *target)\n{\n\ttarget_free_all_working_areas_restore(target, 1);\n\n\t/* Now we have none or only one working area marked as free */\n\tif (target->working_areas) {\n\t\t/* Free the last one to allow on-the-fly moving and resizing */\n\t\tfree(target->working_areas->backup);\n\t\tfree(target->working_areas);\n\t\ttarget->working_areas = NULL;\n\t}\n}\n\n/* Find the largest number of bytes that can be allocated */\nuint32_t target_get_working_area_avail(struct target *target)\n{\n\tstruct working_area *c = target->working_areas;\n\tuint32_t max_size = 0;\n\n\tif (!c)\n\t\treturn ALIGN_DOWN(target->working_area_size, 4);\n\n\twhile (c) {\n\t\tif (c->free && max_size < c->size)\n\t\t\tmax_size = c->size;\n\n\t\tc = c->next;\n\t}\n\n\treturn max_size;\n}\n\nstatic void target_destroy(struct target *target)\n{\n\tif (target->type->deinit_target)\n\t\ttarget->type->deinit_target(target);\n\n\tif (target->semihosting)\n\t\tfree(target->semihosting->basedir);\n\tfree(target->semihosting);\n\n\tjtag_unregister_event_callback(jtag_enable_callback, target);\n\n\tstruct target_event_action *teap = target->event_action;\n\twhile (teap) {\n\t\tstruct target_event_action *next = teap->next;\n\t\tJim_DecrRefCount(teap->interp, teap->body);\n\t\tfree(teap);\n\t\tteap = next;\n\t}\n\n\ttarget_free_all_working_areas(target);\n\n\t/* release the targets SMP list */\n\tif (target->smp) {\n\t\tstruct target_list *head, *tmp;\n\n\t\tlist_for_each_entry_safe(head, tmp, target->smp_targets, lh) {\n\t\t\tlist_del(&head->lh);\n\t\t\thead->target->smp = 0;\n\t\t\tfree(head);\n\t\t}\n\t\tif (target->smp_targets != &empty_smp_targets)\n\t\t\tfree(target->smp_targets);\n\t\ttarget->smp = 0;\n\t}\n\n\trtos_destroy(target);\n\n\tfree(target->gdb_port_override);\n\tfree(target->type);\n\tfree(target->trace_info);\n\tfree(target->fileio_info);\n\tfree(target->cmd_name);\n\tfree(target);\n}\n\nvoid target_quit(void)\n{\n\tstruct target_event_callback *pe = target_event_callbacks;\n\twhile (pe) {\n\t\tstruct target_event_callback *t = pe->next;\n\t\tfree(pe);\n\t\tpe = t;\n\t}\n\ttarget_event_callbacks = NULL;\n\n\tstruct target_timer_callback *pt = target_timer_callbacks;\n\twhile (pt) {\n\t\tstruct target_timer_callback *t = pt->next;\n\t\tfree(pt);\n\t\tpt = t;\n\t}\n\ttarget_timer_callbacks = NULL;\n\n\tfor (struct target *target = all_targets; target;) {\n\t\tstruct target *tmp;\n\n\t\ttmp = target->next;\n\t\ttarget_destroy(target);\n\t\ttarget = tmp;\n\t}\n\n\tall_targets = NULL;\n}\n\nint target_arch_state(struct target *target)\n{\n\tint retval;\n\tif (!target) {\n\t\tLOG_WARNING(\"No target has been configured\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_OK;\n\n\tretval = target->type->arch_state(target);\n\treturn retval;\n}\n\nstatic int target_get_gdb_fileio_info_default(struct target *target,\n\t\tstruct gdb_fileio_info *fileio_info)\n{\n\t/* If target does not support semi-hosting function, target\n\t   has no need to provide .get_gdb_fileio_info callback.\n\t   It just return ERROR_FAIL and gdb_server will return \"Txx\"\n\t   as target halted every time.  */\n\treturn ERROR_FAIL;\n}\n\nstatic int target_gdb_fileio_end_default(struct target *target,\n\t\tint retcode, int fileio_errno, bool ctrl_c)\n{\n\treturn ERROR_OK;\n}\n\nint target_profiling_default(struct target *target, uint32_t *samples,\n\t\tuint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)\n{\n\tstruct timeval timeout, now;\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, seconds, 0);\n\n\tLOG_INFO(\"Starting profiling. Halting and resuming the\"\n\t\t\t\" target as often as we can...\");\n\n\tuint32_t sample_count = 0;\n\t/* hopefully it is safe to cache! We want to stop/restart as quickly as possible. */\n\tstruct reg *reg = register_get_by_name(target->reg_cache, \"pc\", true);\n\n\tint retval = ERROR_OK;\n\tfor (;;) {\n\t\ttarget_poll(target);\n\t\tif (target->state == TARGET_HALTED) {\n\t\t\tuint32_t t = buf_get_u32(reg->value, 0, 32);\n\t\t\tsamples[sample_count++] = t;\n\t\t\t/* current pc, addr = 0, do not handle breakpoints, not debugging */\n\t\t\tretval = target_resume(target, 1, 0, 0, 0);\n\t\t\ttarget_poll(target);\n\t\t\talive_sleep(10); /* sleep 10ms, i.e. <100 samples/second. */\n\t\t} else if (target->state == TARGET_RUNNING) {\n\t\t\t/* We want to quickly sample the PC. */\n\t\t\tretval = target_halt(target);\n\t\t} else {\n\t\t\tLOG_INFO(\"Target not halted or running\");\n\t\t\tretval = ERROR_OK;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tgettimeofday(&now, NULL);\n\t\tif ((sample_count >= max_num_samples) || timeval_compare(&now, &timeout) >= 0) {\n\t\t\tLOG_INFO(\"Profiling completed. %\" PRIu32 \" samples.\", sample_count);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t*num_samples = sample_count;\n\treturn retval;\n}\n\n/* Single aligned words are guaranteed to use 16 or 32 bit access\n * mode respectively, otherwise data is handled as quickly as\n * possible\n */\nint target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)\n{\n\tLOG_DEBUG(\"writing buffer of %\" PRIu32 \" byte at \" TARGET_ADDR_FMT,\n\t\t\t  size, address);\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (size == 0)\n\t\treturn ERROR_OK;\n\n\tif ((address + size - 1) < address) {\n\t\t/* GDB can request this when e.g. PC is 0xfffffffc */\n\t\tLOG_ERROR(\"address + size wrapped (\" TARGET_ADDR_FMT \", 0x%08\" PRIx32 \")\",\n\t\t\t\t  address,\n\t\t\t\t  size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn target->type->write_buffer(target, address, size, buffer);\n}\n\nstatic int target_write_buffer_default(struct target *target,\n\ttarget_addr_t address, uint32_t count, const uint8_t *buffer)\n{\n\tuint32_t size;\n\tunsigned int data_bytes = target_data_bits(target) / 8;\n\n\t/* Align up to maximum bytes. The loop condition makes sure the next pass\n\t * will have something to do with the size we leave to it. */\n\tfor (size = 1;\n\t\t\tsize < data_bytes && count >= size * 2 + (address & size);\n\t\t\tsize *= 2) {\n\t\tif (address & size) {\n\t\t\tint retval = target_write_memory(target, address, size, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += size;\n\t\t\tcount -= size;\n\t\t\tbuffer += size;\n\t\t}\n\t}\n\n\t/* Write the data with as large access size as possible. */\n\tfor (; size > 0; size /= 2) {\n\t\tuint32_t aligned = count - count % size;\n\t\tif (aligned > 0) {\n\t\t\tint retval = target_write_memory(target, address, size, aligned / size, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += aligned;\n\t\t\tcount -= aligned;\n\t\t\tbuffer += aligned;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Single aligned words are guaranteed to use 16 or 32 bit access\n * mode respectively, otherwise data is handled as quickly as\n * possible\n */\nint target_read_buffer(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)\n{\n\tLOG_DEBUG(\"reading buffer of %\" PRIu32 \" byte at \" TARGET_ADDR_FMT,\n\t\t\t  size, address);\n\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (size == 0)\n\t\treturn ERROR_OK;\n\n\tif ((address + size - 1) < address) {\n\t\t/* GDB can request this when e.g. PC is 0xfffffffc */\n\t\tLOG_ERROR(\"address + size wrapped (\" TARGET_ADDR_FMT \", 0x%08\" PRIx32 \")\",\n\t\t\t\t  address,\n\t\t\t\t  size);\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn target->type->read_buffer(target, address, size, buffer);\n}\n\nstatic int target_read_buffer_default(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)\n{\n\tuint32_t size;\n\tunsigned int data_bytes = target_data_bits(target) / 8;\n\n\t/* Align up to maximum bytes. The loop condition makes sure the next pass\n\t * will have something to do with the size we leave to it. */\n\tfor (size = 1;\n\t\t\tsize < data_bytes && count >= size * 2 + (address & size);\n\t\t\tsize *= 2) {\n\t\tif (address & size) {\n\t\t\tint retval = target_read_memory(target, address, size, 1, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += size;\n\t\t\tcount -= size;\n\t\t\tbuffer += size;\n\t\t}\n\t}\n\n\t/* Read the data with as large access size as possible. */\n\tfor (; size > 0; size /= 2) {\n\t\tuint32_t aligned = count - count % size;\n\t\tif (aligned > 0) {\n\t\t\tint retval = target_read_memory(target, address, size, aligned / size, buffer);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\taddress += aligned;\n\t\t\tcount -= aligned;\n\t\t\tbuffer += aligned;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nint target_checksum_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t *crc)\n{\n\tuint8_t *buffer;\n\tint retval;\n\tuint32_t i;\n\tuint32_t checksum = 0;\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->type->checksum_memory) {\n\t\tLOG_ERROR(\"Target %s doesn't support checksum_memory\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tretval = target->type->checksum_memory(target, address, size, &checksum);\n\tif (retval != ERROR_OK) {\n\t\tbuffer = malloc(size);\n\t\tif (!buffer) {\n\t\t\tLOG_ERROR(\"error allocating buffer for section (%\" PRIu32 \" bytes)\", size);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tretval = target_read_buffer(target, address, size, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* convert to target endianness */\n\t\tfor (i = 0; i < (size/sizeof(uint32_t)); i++) {\n\t\t\tuint32_t target_data;\n\t\t\ttarget_data = target_buffer_get_u32(target, &buffer[i*sizeof(uint32_t)]);\n\t\t\ttarget_buffer_set_u32(target, &buffer[i*sizeof(uint32_t)], target_data);\n\t\t}\n\n\t\tretval = image_calculate_checksum(buffer, size, &checksum);\n\t\tfree(buffer);\n\t}\n\n\t*crc = checksum;\n\n\treturn retval;\n}\n\nint target_blank_check_memory(struct target *target,\n\tstruct target_memory_check_block *blocks, int num_blocks,\n\tuint8_t erased_value)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!target->type->blank_check_memory)\n\t\treturn ERROR_NOT_IMPLEMENTED;\n\n\treturn target->type->blank_check_memory(target, blocks, num_blocks, erased_value);\n}\n\nint target_read_u64(struct target *target, target_addr_t address, uint64_t *value)\n{\n\tuint8_t value_buf[8];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = target_read_memory(target, address, 8, 1, value_buf);\n\n\tif (retval == ERROR_OK) {\n\t\t*value = target_buffer_get_u64(target, value_buf);\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%16.16\" PRIx64 \"\",\n\t\t\t\t  address,\n\t\t\t\t  *value);\n\t} else {\n\t\t*value = 0x0;\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \" failed\",\n\t\t\t\t  address);\n\t}\n\n\treturn retval;\n}\n\nint target_read_u32(struct target *target, target_addr_t address, uint32_t *value)\n{\n\tuint8_t value_buf[4];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = target_read_memory(target, address, 4, 1, value_buf);\n\n\tif (retval == ERROR_OK) {\n\t\t*value = target_buffer_get_u32(target, value_buf);\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%8.8\" PRIx32 \"\",\n\t\t\t\t  address,\n\t\t\t\t  *value);\n\t} else {\n\t\t*value = 0x0;\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \" failed\",\n\t\t\t\t  address);\n\t}\n\n\treturn retval;\n}\n\nint target_read_u16(struct target *target, target_addr_t address, uint16_t *value)\n{\n\tuint8_t value_buf[2];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = target_read_memory(target, address, 2, 1, value_buf);\n\n\tif (retval == ERROR_OK) {\n\t\t*value = target_buffer_get_u16(target, value_buf);\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%4.4\" PRIx16,\n\t\t\t\t  address,\n\t\t\t\t  *value);\n\t} else {\n\t\t*value = 0x0;\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \" failed\",\n\t\t\t\t  address);\n\t}\n\n\treturn retval;\n}\n\nint target_read_u8(struct target *target, target_addr_t address, uint8_t *value)\n{\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = target_read_memory(target, address, 1, 1, value);\n\n\tif (retval == ERROR_OK) {\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%2.2\" PRIx8,\n\t\t\t\t  address,\n\t\t\t\t  *value);\n\t} else {\n\t\t*value = 0x0;\n\t\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \" failed\",\n\t\t\t\t  address);\n\t}\n\n\treturn retval;\n}\n\nint target_write_u64(struct target *target, target_addr_t address, uint64_t value)\n{\n\tint retval;\n\tuint8_t value_buf[8];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%16.16\" PRIx64 \"\",\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u64(target, value_buf, value);\n\tretval = target_write_memory(target, address, 8, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_u32(struct target *target, target_addr_t address, uint32_t value)\n{\n\tint retval;\n\tuint8_t value_buf[4];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%8.8\" PRIx32 \"\",\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u32(target, value_buf, value);\n\tretval = target_write_memory(target, address, 4, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_u16(struct target *target, target_addr_t address, uint16_t value)\n{\n\tint retval;\n\tuint8_t value_buf[2];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%8.8\" PRIx16,\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u16(target, value_buf, value);\n\tretval = target_write_memory(target, address, 2, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_u8(struct target *target, target_addr_t address, uint8_t value)\n{\n\tint retval;\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%2.2\" PRIx8,\n\t\t\t  address, value);\n\n\tretval = target_write_memory(target, address, 1, 1, &value);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_phys_u64(struct target *target, target_addr_t address, uint64_t value)\n{\n\tint retval;\n\tuint8_t value_buf[8];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%16.16\" PRIx64 \"\",\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u64(target, value_buf, value);\n\tretval = target_write_phys_memory(target, address, 8, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_phys_u32(struct target *target, target_addr_t address, uint32_t value)\n{\n\tint retval;\n\tuint8_t value_buf[4];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%8.8\" PRIx32 \"\",\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u32(target, value_buf, value);\n\tretval = target_write_phys_memory(target, address, 4, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_phys_u16(struct target *target, target_addr_t address, uint16_t value)\n{\n\tint retval;\n\tuint8_t value_buf[2];\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%8.8\" PRIx16,\n\t\t\t  address,\n\t\t\t  value);\n\n\ttarget_buffer_set_u16(target, value_buf, value);\n\tretval = target_write_phys_memory(target, address, 2, 1, value_buf);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nint target_write_phys_u8(struct target *target, target_addr_t address, uint8_t value)\n{\n\tint retval;\n\tif (!target_was_examined(target)) {\n\t\tLOG_ERROR(\"Target not examined yet\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", value: 0x%2.2\" PRIx8,\n\t\t\t  address, value);\n\n\tretval = target_write_phys_memory(target, address, 1, 1, &value);\n\tif (retval != ERROR_OK)\n\t\tLOG_DEBUG(\"failed: %i\", retval);\n\n\treturn retval;\n}\n\nstatic int find_target(struct command_invocation *cmd, const char *name)\n{\n\tstruct target *target = get_target(name);\n\tif (!target) {\n\t\tcommand_print(cmd, \"Target: %s is unknown, try one of:\\n\", name);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (!target->tap->enabled) {\n\t\tcommand_print(cmd, \"Target: TAP %s is disabled, \"\n\t\t\t \"can't be the current target\\n\",\n\t\t\t target->tap->dotted_name);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tcmd->ctx->current_target = target;\n\tif (cmd->ctx->current_target_override)\n\t\tcmd->ctx->current_target_override = target;\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(handle_targets_command)\n{\n\tint retval = ERROR_OK;\n\tif (CMD_ARGC == 1) {\n\t\tretval = find_target(CMD, CMD_ARGV[0]);\n\t\tif (retval == ERROR_OK) {\n\t\t\t/* we're done! */\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tstruct target *target = all_targets;\n\tcommand_print(CMD, \"    TargetName         Type       Endian TapName            State       \");\n\tcommand_print(CMD, \"--  ------------------ ---------- ------ ------------------ ------------\");\n\twhile (target) {\n\t\tconst char *state;\n\t\tchar marker = ' ';\n\n\t\tif (target->tap->enabled)\n\t\t\tstate = target_state_name(target);\n\t\telse\n\t\t\tstate = \"tap-disabled\";\n\n\t\tif (CMD_CTX->current_target == target)\n\t\t\tmarker = '*';\n\n\t\t/* keep columns lined up to match the headers above */\n\t\tcommand_print(CMD,\n\t\t\t\t\"%2d%c %-18s %-10s %-6s %-18s %s\",\n\t\t\t\ttarget->target_number,\n\t\t\t\tmarker,\n\t\t\t\ttarget_name(target),\n\t\t\t\ttarget_type_name(target),\n\t\t\t\tjim_nvp_value2name_simple(nvp_target_endian,\n\t\t\t\t\ttarget->endianness)->name,\n\t\t\t\ttarget->tap->dotted_name,\n\t\t\t\tstate);\n\t\ttarget = target->next;\n\t}\n\n\treturn retval;\n}\n\n/* every 300ms we check for reset & powerdropout and issue a \"reset halt\" if so. */\n\nstatic int power_dropout;\nstatic int srst_asserted;\n\nstatic int run_power_restore;\nstatic int run_power_dropout;\nstatic int run_srst_asserted;\nstatic int run_srst_deasserted;\n\nstatic int sense_handler(void)\n{\n\tstatic int prev_srst_asserted;\n\tstatic int prev_power_dropout;\n\n\tint retval = jtag_power_dropout(&power_dropout);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint power_restored;\n\tpower_restored = prev_power_dropout && !power_dropout;\n\tif (power_restored)\n\t\trun_power_restore = 1;\n\n\tint64_t current = timeval_ms();\n\tstatic int64_t last_power;\n\tbool wait_more = last_power + 2000 > current;\n\tif (power_dropout && !wait_more) {\n\t\trun_power_dropout = 1;\n\t\tlast_power = current;\n\t}\n\n\tretval = jtag_srst_asserted(&srst_asserted);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tint srst_deasserted;\n\tsrst_deasserted = prev_srst_asserted && !srst_asserted;\n\n\tstatic int64_t last_srst;\n\twait_more = last_srst + 2000 > current;\n\tif (srst_deasserted && !wait_more) {\n\t\trun_srst_deasserted = 1;\n\t\tlast_srst = current;\n\t}\n\n\tif (!prev_srst_asserted && srst_asserted)\n\t\trun_srst_asserted = 1;\n\n\tprev_srst_asserted = srst_asserted;\n\tprev_power_dropout = power_dropout;\n\n\tif (srst_deasserted || power_restored) {\n\t\t/* Other than logging the event we can't do anything here.\n\t\t * Issuing a reset is a particularly bad idea as we might\n\t\t * be inside a reset already.\n\t\t */\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* process target state changes */\nstatic int handle_target(void *priv)\n{\n\tJim_Interp *interp = (Jim_Interp *)priv;\n\tint retval = ERROR_OK;\n\n\tif (!is_jtag_poll_safe()) {\n\t\t/* polling is disabled currently */\n\t\treturn ERROR_OK;\n\t}\n\n\t/* we do not want to recurse here... */\n\tstatic int recursive;\n\tif (!recursive) {\n\t\trecursive = 1;\n\t\tsense_handler();\n\t\t/* danger! running these procedures can trigger srst assertions and power dropouts.\n\t\t * We need to avoid an infinite loop/recursion here and we do that by\n\t\t * clearing the flags after running these events.\n\t\t */\n\t\tint did_something = 0;\n\t\tif (run_srst_asserted) {\n\t\t\tLOG_INFO(\"srst asserted detected, running srst_asserted proc.\");\n\t\t\tJim_Eval(interp, \"srst_asserted\");\n\t\t\tdid_something = 1;\n\t\t}\n\t\tif (run_srst_deasserted) {\n\t\t\tJim_Eval(interp, \"srst_deasserted\");\n\t\t\tdid_something = 1;\n\t\t}\n\t\tif (run_power_dropout) {\n\t\t\tLOG_INFO(\"Power dropout detected, running power_dropout proc.\");\n\t\t\tJim_Eval(interp, \"power_dropout\");\n\t\t\tdid_something = 1;\n\t\t}\n\t\tif (run_power_restore) {\n\t\t\tJim_Eval(interp, \"power_restore\");\n\t\t\tdid_something = 1;\n\t\t}\n\n\t\tif (did_something) {\n\t\t\t/* clear detect flags */\n\t\t\tsense_handler();\n\t\t}\n\n\t\t/* clear action flags */\n\n\t\trun_srst_asserted = 0;\n\t\trun_srst_deasserted = 0;\n\t\trun_power_restore = 0;\n\t\trun_power_dropout = 0;\n\n\t\trecursive = 0;\n\t}\n\n\t/* Poll targets for state changes unless that's globally disabled.\n\t * Skip targets that are currently disabled.\n\t */\n\tfor (struct target *target = all_targets;\n\t\t\tis_jtag_poll_safe() && target;\n\t\t\ttarget = target->next) {\n\n\t\tif (!target_was_examined(target))\n\t\t\tcontinue;\n\n\t\tif (!target->tap->enabled)\n\t\t\tcontinue;\n\n\t\tif (target->backoff.times > target->backoff.count) {\n\t\t\t/* do not poll this time as we failed previously */\n\t\t\ttarget->backoff.count++;\n\t\t\tcontinue;\n\t\t}\n\t\ttarget->backoff.count = 0;\n\n\t\t/* only poll target if we've got power and srst isn't asserted */\n\t\tif (!power_dropout && !srst_asserted) {\n\t\t\t/* polling may fail silently until the target has been examined */\n\t\t\tretval = target_poll(target);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t/* 100ms polling interval. Increase interval between polling up to 5000ms */\n\t\t\t\tif (target->backoff.times * polling_interval < 5000) {\n\t\t\t\t\ttarget->backoff.times *= 2;\n\t\t\t\t\ttarget->backoff.times++;\n\t\t\t\t}\n\n\t\t\t\t/* Tell GDB to halt the debugger. This allows the user to\n\t\t\t\t * run monitor commands to handle the situation.\n\t\t\t\t */\n\t\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n\t\t\t}\n\t\t\tif (target->backoff.times > 0) {\n\t\t\t\tLOG_USER(\"Polling target %s failed, trying to reexamine\", target_name(target));\n\t\t\t\ttarget_reset_examined(target);\n\t\t\t\tretval = target_examine_one(target);\n\t\t\t\t/* Target examination could have failed due to unstable connection,\n\t\t\t\t * but we set the examined flag anyway to repoll it later */\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\ttarget_set_examined(target);\n\t\t\t\t\tLOG_USER(\"Examination failed, GDB will be halted. Polling again in %dms\",\n\t\t\t\t\t\t target->backoff.times * polling_interval);\n\t\t\t\t\treturn retval;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Since we succeeded, we reset backoff count */\n\t\t\ttarget->backoff.times = 0;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_reg_command)\n{\n\tLOG_DEBUG(\"-\");\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct reg *reg = NULL;\n\n\t/* list all available registers for the current target */\n\tif (CMD_ARGC == 0) {\n\t\tstruct reg_cache *cache = target->reg_cache;\n\n\t\tunsigned int count = 0;\n\t\twhile (cache) {\n\t\t\tunsigned i;\n\n\t\t\tcommand_print(CMD, \"===== %s\", cache->name);\n\n\t\t\tfor (i = 0, reg = cache->reg_list;\n\t\t\t\t\ti < cache->num_regs;\n\t\t\t\t\ti++, reg++, count++) {\n\t\t\t\tif (reg->exist == false || reg->hidden)\n\t\t\t\t\tcontinue;\n\t\t\t\t/* only print cached values if they are valid */\n\t\t\t\tif (reg->valid) {\n\t\t\t\t\tchar *value = buf_to_hex_str(reg->value,\n\t\t\t\t\t\t\treg->size);\n\t\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\t\"(%i) %s (/%\" PRIu32 \"): 0x%s%s\",\n\t\t\t\t\t\t\tcount, reg->name,\n\t\t\t\t\t\t\treg->size, value,\n\t\t\t\t\t\t\treg->dirty\n\t\t\t\t\t\t\t\t? \" (dirty)\"\n\t\t\t\t\t\t\t\t: \"\");\n\t\t\t\t\tfree(value);\n\t\t\t\t} else {\n\t\t\t\t\tcommand_print(CMD, \"(%i) %s (/%\" PRIu32 \")\",\n\t\t\t\t\t\t\t  count, reg->name,\n\t\t\t\t\t\t\t  reg->size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcache = cache->next;\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* access a single register by its ordinal number */\n\tif ((CMD_ARGV[0][0] >= '0') && (CMD_ARGV[0][0] <= '9')) {\n\t\tunsigned num;\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], num);\n\n\t\tstruct reg_cache *cache = target->reg_cache;\n\t\tunsigned int count = 0;\n\t\twhile (cache) {\n\t\t\tunsigned i;\n\t\t\tfor (i = 0; i < cache->num_regs; i++) {\n\t\t\t\tif (count++ == num) {\n\t\t\t\t\treg = &cache->reg_list[i];\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (reg)\n\t\t\t\tbreak;\n\t\t\tcache = cache->next;\n\t\t}\n\n\t\tif (!reg) {\n\t\t\tcommand_print(CMD, \"%i is out of bounds, the current target \"\n\t\t\t\t\t\"has only %i registers (0 - %i)\", num, count, count - 1);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\t/* access a single register by its name */\n\t\treg = register_get_by_name(target->reg_cache, CMD_ARGV[0], true);\n\n\t\tif (!reg)\n\t\t\tgoto not_found;\n\t}\n\n\tassert(reg); /* give clang a hint that we *know* reg is != NULL here */\n\n\tif (!reg->exist)\n\t\tgoto not_found;\n\n\t/* display a register */\n\tif ((CMD_ARGC == 1) || ((CMD_ARGC == 2) && !((CMD_ARGV[1][0] >= '0')\n\t\t\t&& (CMD_ARGV[1][0] <= '9')))) {\n\t\tif ((CMD_ARGC == 2) && (strcmp(CMD_ARGV[1], \"force\") == 0))\n\t\t\treg->valid = 0;\n\n\t\tif (reg->valid == 0) {\n\t\t\tint retval = reg->type->get(reg);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not read register '%s'\", reg->name);\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t\tchar *value = buf_to_hex_str(reg->value, reg->size);\n\t\tcommand_print(CMD, \"%s (/%i): 0x%s\", reg->name, (int)(reg->size), value);\n\t\tfree(value);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* set register value */\n\tif (CMD_ARGC == 2) {\n\t\tuint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));\n\t\tif (!buf)\n\t\t\treturn ERROR_FAIL;\n\t\tstr_to_buf(CMD_ARGV[1], strlen(CMD_ARGV[1]), buf, reg->size, 0);\n\n\t\tint retval = reg->type->set(reg, buf);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Could not write to register '%s'\", reg->name);\n\t\t} else {\n\t\t\tchar *value = buf_to_hex_str(reg->value, reg->size);\n\t\t\tcommand_print(CMD, \"%s (/%i): 0x%s\", reg->name, (int)(reg->size), value);\n\t\t\tfree(value);\n\t\t}\n\n\t\tfree(buf);\n\n\t\treturn retval;\n\t}\n\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\nnot_found:\n\tcommand_print(CMD, \"register %s not found in current target\", CMD_ARGV[0]);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_poll_command)\n{\n\tint retval = ERROR_OK;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC == 0) {\n\t\tcommand_print(CMD, \"background polling: %s\",\n\t\t\t\tjtag_poll_get_enabled() ? \"on\" : \"off\");\n\t\tcommand_print(CMD, \"TAP: %s (%s)\",\n\t\t\t\ttarget->tap->dotted_name,\n\t\t\t\ttarget->tap->enabled ? \"enabled\" : \"disabled\");\n\t\tif (!target->tap->enabled)\n\t\t\treturn ERROR_OK;\n\t\tretval = target_poll(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = target_arch_state(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else if (CMD_ARGC == 1) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ON_OFF(CMD_ARGV[0], enable);\n\t\tjtag_poll_set_enabled(enable);\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_wait_halt_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned ms = DEFAULT_HALT_TIMEOUT;\n\tif (1 == CMD_ARGC) {\n\t\tint retval = parse_uint(CMD_ARGV[0], &ms);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\treturn target_wait_state(target, TARGET_HALTED, ms);\n}\n\n/* wait for target state to change. The trick here is to have a low\n * latency for short waits and not to suck up all the CPU time\n * on longer waits.\n *\n * After 500ms, keep_alive() is invoked\n */\nint target_wait_state(struct target *target, enum target_state state, unsigned int ms)\n{\n\tint retval;\n\tint64_t then = 0, cur;\n\tbool once = true;\n\n\tfor (;;) {\n\t\tretval = target_poll(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tif (target->state == state)\n\t\t\tbreak;\n\t\tcur = timeval_ms();\n\t\tif (once) {\n\t\t\tonce = false;\n\t\t\tthen = timeval_ms();\n\t\t\tLOG_DEBUG(\"waiting for target %s...\",\n\t\t\t\tnvp_value2name(nvp_target_state, state)->name);\n\t\t}\n\n\t\tif (cur-then > 500)\n\t\t\tkeep_alive();\n\n\t\tif ((cur-then) > ms) {\n\t\t\tLOG_ERROR(\"timed out while waiting for target %s\",\n\t\t\t\tnvp_value2name(nvp_target_state, state)->name);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_halt_command)\n{\n\tLOG_DEBUG(\"-\");\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\ttarget->verbose_halt_msg = true;\n\n\tint retval = target_halt(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC == 1) {\n\t\tunsigned wait_local;\n\t\tretval = parse_uint(CMD_ARGV[0], &wait_local);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\tif (!wait_local)\n\t\t\treturn ERROR_OK;\n\t}\n\n\treturn CALL_COMMAND_HANDLER(handle_wait_halt_command);\n}\n\nCOMMAND_HANDLER(handle_soft_reset_halt_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tLOG_TARGET_INFO(target, \"requesting target halt and executing a soft reset\");\n\n\ttarget_soft_reset_halt(target);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_reset_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tenum target_reset_mode reset_mode = RESET_RUN;\n\tif (CMD_ARGC == 1) {\n\t\tconst struct nvp *n;\n\t\tn = nvp_name2value(nvp_reset_modes, CMD_ARGV[0]);\n\t\tif ((!n->name) || (n->value == RESET_UNKNOWN))\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\treset_mode = n->value;\n\t}\n\n\t/* reset *all* targets */\n\treturn target_process_reset(CMD, reset_mode);\n}\n\n\nCOMMAND_HANDLER(handle_resume_command)\n{\n\tint current = 1;\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\t/* with no CMD_ARGV, resume from current pc, addr = 0,\n\t * with one arguments, addr = CMD_ARGV[0],\n\t * handle breakpoints, not debugging */\n\ttarget_addr_t addr = 0;\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\tcurrent = 0;\n\t}\n\n\treturn target_resume(target, current, addr, 1, 0);\n}\n\nCOMMAND_HANDLER(handle_step_command)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tLOG_DEBUG(\"-\");\n\n\t/* with no CMD_ARGV, step from current pc, addr = 0,\n\t * with one argument addr = CMD_ARGV[0],\n\t * handle breakpoints, debugging */\n\ttarget_addr_t addr = 0;\n\tint current_pc = 1;\n\tif (CMD_ARGC == 1) {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\tcurrent_pc = 0;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\treturn target_step(target, current_pc, addr, 1);\n}\n\nvoid target_handle_md_output(struct command_invocation *cmd,\n\t\tstruct target *target, target_addr_t address, unsigned size,\n\t\tunsigned count, const uint8_t *buffer)\n{\n\tconst unsigned line_bytecnt = 32;\n\tunsigned line_modulo = line_bytecnt / size;\n\n\tchar output[line_bytecnt * 4 + 1];\n\tunsigned output_len = 0;\n\n\tconst char *value_fmt;\n\tswitch (size) {\n\tcase 8:\n\t\tvalue_fmt = \"%16.16\"PRIx64\" \";\n\t\tbreak;\n\tcase 4:\n\t\tvalue_fmt = \"%8.8\"PRIx64\" \";\n\t\tbreak;\n\tcase 2:\n\t\tvalue_fmt = \"%4.4\"PRIx64\" \";\n\t\tbreak;\n\tcase 1:\n\t\tvalue_fmt = \"%2.2\"PRIx64\" \";\n\t\tbreak;\n\tdefault:\n\t\t/* \"can't happen\", caller checked */\n\t\tLOG_ERROR(\"invalid memory read size: %u\", size);\n\t\treturn;\n\t}\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tif (i % line_modulo == 0) {\n\t\t\toutput_len += snprintf(output + output_len,\n\t\t\t\t\tsizeof(output) - output_len,\n\t\t\t\t\tTARGET_ADDR_FMT \": \",\n\t\t\t\t\t(address + (i * size)));\n\t\t}\n\n\t\tuint64_t value = 0;\n\t\tconst uint8_t *value_ptr = buffer + i * size;\n\t\tswitch (size) {\n\t\tcase 8:\n\t\t\tvalue = target_buffer_get_u64(target, value_ptr);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tvalue = target_buffer_get_u32(target, value_ptr);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tvalue = target_buffer_get_u16(target, value_ptr);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tvalue = *value_ptr;\n\t\t}\n\t\toutput_len += snprintf(output + output_len,\n\t\t\t\tsizeof(output) - output_len,\n\t\t\t\tvalue_fmt, value);\n\n\t\tif ((i % line_modulo == line_modulo - 1) || (i == count - 1)) {\n\t\t\tcommand_print(cmd, \"%s\", output);\n\t\t\toutput_len = 0;\n\t\t}\n\t}\n}\n\nCOMMAND_HANDLER(handle_md_command)\n{\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned size = 0;\n\tswitch (CMD_NAME[2]) {\n\tcase 'd':\n\t\tsize = 8;\n\t\tbreak;\n\tcase 'w':\n\t\tsize = 4;\n\t\tbreak;\n\tcase 'h':\n\t\tsize = 2;\n\t\tbreak;\n\tcase 'b':\n\t\tsize = 1;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tbool physical = strcmp(CMD_ARGV[0], \"phys\") == 0;\n\tint (*fn)(struct target *target,\n\t\t\ttarget_addr_t address, uint32_t size_value, uint32_t count, uint8_t *buffer);\n\tif (physical) {\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tfn = target_read_phys_memory;\n\t} else\n\t\tfn = target_read_memory;\n\tif ((CMD_ARGC < 1) || (CMD_ARGC > 2))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget_addr_t address;\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\n\tunsigned count = 1;\n\tif (CMD_ARGC == 2)\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], count);\n\n\tuint8_t *buffer = calloc(count, size);\n\tif (!buffer) {\n\t\tLOG_ERROR(\"Failed to allocate md read buffer\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = fn(target, address, size, count, buffer);\n\tif (retval == ERROR_OK)\n\t\ttarget_handle_md_output(CMD, target, address, size, count, buffer);\n\n\tfree(buffer);\n\n\treturn retval;\n}\n\ntypedef int (*target_write_fn)(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\n\nstatic int target_fill_mem(struct target *target,\n\t\ttarget_addr_t address,\n\t\ttarget_write_fn fn,\n\t\tunsigned data_size,\n\t\t/* value */\n\t\tuint64_t b,\n\t\t/* count */\n\t\tunsigned c)\n{\n\t/* We have to write in reasonably large chunks to be able\n\t * to fill large memory areas with any sane speed */\n\tconst unsigned chunk_size = 16384;\n\tuint8_t *target_buf = malloc(chunk_size * data_size);\n\tif (!target_buf) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned i = 0; i < chunk_size; i++) {\n\t\tswitch (data_size) {\n\t\tcase 8:\n\t\t\ttarget_buffer_set_u64(target, target_buf + i * data_size, b);\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\ttarget_buffer_set_u32(target, target_buf + i * data_size, b);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\ttarget_buffer_set_u16(target, target_buf + i * data_size, b);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\ttarget_buffer_set_u8(target, target_buf + i * data_size, b);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\texit(-1);\n\t\t}\n\t}\n\n\tint retval = ERROR_OK;\n\n\tfor (unsigned x = 0; x < c; x += chunk_size) {\n\t\tunsigned current;\n\t\tcurrent = c - x;\n\t\tif (current > chunk_size)\n\t\t\tcurrent = chunk_size;\n\t\tretval = fn(target, address + x * data_size, data_size, current, target_buf);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\t/* avoid GDB timeouts */\n\t\tkeep_alive();\n\t}\n\tfree(target_buf);\n\n\treturn retval;\n}\n\n\nCOMMAND_HANDLER(handle_mw_command)\n{\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tbool physical = strcmp(CMD_ARGV[0], \"phys\") == 0;\n\ttarget_write_fn fn;\n\tif (physical) {\n\t\tCMD_ARGC--;\n\t\tCMD_ARGV++;\n\t\tfn = target_write_phys_memory;\n\t} else\n\t\tfn = target_write_memory;\n\tif ((CMD_ARGC < 2) || (CMD_ARGC > 3))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget_addr_t address;\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);\n\n\tuint64_t value;\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], value);\n\n\tunsigned count = 1;\n\tif (CMD_ARGC == 3)\n\t\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tunsigned wordsize;\n\tswitch (CMD_NAME[2]) {\n\t\tcase 'd':\n\t\t\twordsize = 8;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\twordsize = 4;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\twordsize = 2;\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\twordsize = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\treturn target_fill_mem(target, address, fn, wordsize, value, count);\n}\n\nstatic COMMAND_HELPER(parse_load_image_command, struct image *image,\n\t\ttarget_addr_t *min_address, target_addr_t *max_address)\n{\n\tif (CMD_ARGC < 1 || CMD_ARGC > 5)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* a base address isn't always necessary,\n\t * default to 0x0 (i.e. don't relocate) */\n\tif (CMD_ARGC >= 2) {\n\t\ttarget_addr_t addr;\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);\n\t\timage->base_address = addr;\n\t\timage->base_address_set = true;\n\t} else\n\t\timage->base_address_set = false;\n\n\timage->start_address_set = false;\n\n\tif (CMD_ARGC >= 4)\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[3], *min_address);\n\tif (CMD_ARGC == 5) {\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[4], *max_address);\n\t\t/* use size (given) to find max (required) */\n\t\t*max_address += *min_address;\n\t}\n\n\tif (*min_address > *max_address)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_load_image_command)\n{\n\tuint8_t *buffer;\n\tsize_t buf_cnt;\n\tuint32_t image_size;\n\ttarget_addr_t min_address = 0;\n\ttarget_addr_t max_address = -1;\n\tstruct image image;\n\n\tint retval = CALL_COMMAND_HANDLER(parse_load_image_command,\n\t\t\t&image, &min_address, &max_address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tif (image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\timage_size = 0x0;\n\tretval = ERROR_OK;\n\tfor (unsigned int i = 0; i < image.num_sections; i++) {\n\t\tbuffer = malloc(image.sections[i].size);\n\t\tif (!buffer) {\n\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t  \"error allocating buffer for section (%d bytes)\",\n\t\t\t\t\t\t  (int)(image.sections[i].size));\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tretval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\tbreak;\n\t\t}\n\n\t\tuint32_t offset = 0;\n\t\tuint32_t length = buf_cnt;\n\n\t\t/* DANGER!!! beware of unsigned comparison here!!! */\n\n\t\tif ((image.sections[i].base_address + buf_cnt >= min_address) &&\n\t\t\t\t(image.sections[i].base_address < max_address)) {\n\n\t\t\tif (image.sections[i].base_address < min_address) {\n\t\t\t\t/* clip addresses below */\n\t\t\t\toffset += min_address-image.sections[i].base_address;\n\t\t\t\tlength -= offset;\n\t\t\t}\n\n\t\t\tif (image.sections[i].base_address + buf_cnt > max_address)\n\t\t\t\tlength -= (image.sections[i].base_address + buf_cnt)-max_address;\n\n\t\t\tretval = target_write_buffer(target,\n\t\t\t\t\timage.sections[i].base_address + offset, length, buffer + offset);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\timage_size += length;\n\t\t\tcommand_print(CMD, \"%u bytes written at address \" TARGET_ADDR_FMT \"\",\n\t\t\t\t\t(unsigned int)length,\n\t\t\t\t\timage.sections[i].base_address + offset);\n\t\t}\n\n\t\tfree(buffer);\n\t}\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"downloaded %\" PRIu32 \" bytes \"\n\t\t\t\t\"in %fs (%0.3f KiB/s)\", image_size,\n\t\t\t\tduration_elapsed(&bench), duration_kbps(&bench, image_size));\n\t}\n\n\timage_close(&image);\n\n\treturn retval;\n\n}\n\nCOMMAND_HANDLER(handle_dump_image_command)\n{\n\tstruct fileio *fileio;\n\tuint8_t *buffer;\n\tint retval, retvaltemp;\n\ttarget_addr_t address, size;\n\tstruct duration bench;\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC != 3)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[1], address);\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[2], size);\n\n\tuint32_t buf_size = (size > 4096) ? 4096 : size;\n\tbuffer = malloc(buf_size);\n\tif (!buffer)\n\t\treturn ERROR_FAIL;\n\n\tretval = fileio_open(&fileio, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY);\n\tif (retval != ERROR_OK) {\n\t\tfree(buffer);\n\t\treturn retval;\n\t}\n\n\tduration_start(&bench);\n\n\twhile (size > 0) {\n\t\tsize_t size_written;\n\t\tuint32_t this_run_size = (size > buf_size) ? buf_size : size;\n\t\tretval = target_read_buffer(target, address, this_run_size, buffer);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tretval = fileio_write(fileio, this_run_size, buffer, &size_written);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\n\t\tsize -= this_run_size;\n\t\taddress += this_run_size;\n\t}\n\n\tfree(buffer);\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tsize_t filesize;\n\t\tretval = fileio_size(fileio, &filesize);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcommand_print(CMD,\n\t\t\t\t\"dumped %zu bytes in %fs (%0.3f KiB/s)\", filesize,\n\t\t\t\tduration_elapsed(&bench), duration_kbps(&bench, filesize));\n\t}\n\n\tretvaltemp = fileio_close(fileio);\n\tif (retvaltemp != ERROR_OK)\n\t\treturn retvaltemp;\n\n\treturn retval;\n}\n\nenum verify_mode {\n\tIMAGE_TEST = 0,\n\tIMAGE_VERIFY = 1,\n\tIMAGE_CHECKSUM_ONLY = 2\n};\n\nstatic COMMAND_HELPER(handle_verify_image_command_internal, enum verify_mode verify)\n{\n\tuint8_t *buffer;\n\tsize_t buf_cnt;\n\tuint32_t image_size;\n\tint retval;\n\tuint32_t checksum = 0;\n\tuint32_t mem_checksum = 0;\n\n\tstruct image image;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (!target) {\n\t\tLOG_ERROR(\"no target selected\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tif (CMD_ARGC >= 2) {\n\t\ttarget_addr_t addr;\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[1], addr);\n\t\timage.base_address = addr;\n\t\timage.base_address_set = true;\n\t} else {\n\t\timage.base_address_set = false;\n\t\timage.base_address = 0x0;\n\t}\n\n\timage.start_address_set = false;\n\n\tretval = image_open(&image, CMD_ARGV[0], (CMD_ARGC == 3) ? CMD_ARGV[2] : NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\timage_size = 0x0;\n\tint diffs = 0;\n\tretval = ERROR_OK;\n\tfor (unsigned int i = 0; i < image.num_sections; i++) {\n\t\tbuffer = malloc(image.sections[i].size);\n\t\tif (!buffer) {\n\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"error allocating buffer for section (%\" PRIu32 \" bytes)\",\n\t\t\t\t\timage.sections[i].size);\n\t\t\tbreak;\n\t\t}\n\t\tretval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\tbreak;\n\t\t}\n\n\t\tif (verify >= IMAGE_VERIFY) {\n\t\t\t/* calculate checksum of image */\n\t\t\tretval = image_calculate_checksum(buffer, buf_cnt, &checksum);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tretval = target_checksum_memory(target, image.sections[i].base_address, buf_cnt, &mem_checksum);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tfree(buffer);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ((checksum != mem_checksum) && (verify == IMAGE_CHECKSUM_ONLY)) {\n\t\t\t\tLOG_ERROR(\"checksum mismatch\");\n\t\t\t\tfree(buffer);\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tif (checksum != mem_checksum) {\n\t\t\t\t/* failed crc checksum, fall back to a binary compare */\n\t\t\t\tuint8_t *data;\n\n\t\t\t\tif (diffs == 0)\n\t\t\t\t\tLOG_ERROR(\"checksum mismatch - attempting binary compare\");\n\n\t\t\t\tdata = malloc(buf_cnt);\n\n\t\t\t\tretval = target_read_buffer(target, image.sections[i].base_address, buf_cnt, data);\n\t\t\t\tif (retval == ERROR_OK) {\n\t\t\t\t\tuint32_t t;\n\t\t\t\t\tfor (t = 0; t < buf_cnt; t++) {\n\t\t\t\t\t\tif (data[t] != buffer[t]) {\n\t\t\t\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\t\t\t\t\t  \"diff %d address 0x%08x. Was 0x%02x instead of 0x%02x\",\n\t\t\t\t\t\t\t\t\t\t  diffs,\n\t\t\t\t\t\t\t\t\t\t  (unsigned)(t + image.sections[i].base_address),\n\t\t\t\t\t\t\t\t\t\t  data[t],\n\t\t\t\t\t\t\t\t\t\t  buffer[t]);\n\t\t\t\t\t\t\tif (diffs++ >= 127) {\n\t\t\t\t\t\t\t\tcommand_print(CMD, \"More than 128 errors, the rest are not printed.\");\n\t\t\t\t\t\t\t\tfree(data);\n\t\t\t\t\t\t\t\tfree(buffer);\n\t\t\t\t\t\t\t\tgoto done;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tkeep_alive();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfree(data);\n\t\t\t}\n\t\t} else {\n\t\t\tcommand_print(CMD, \"address \" TARGET_ADDR_FMT \" length 0x%08zx\",\n\t\t\t\t\t\t  image.sections[i].base_address,\n\t\t\t\t\t\t  buf_cnt);\n\t\t}\n\n\t\tfree(buffer);\n\t\timage_size += buf_cnt;\n\t}\n\tif (diffs > 0)\n\t\tcommand_print(CMD, \"No more differences found.\");\ndone:\n\tif (diffs > 0)\n\t\tretval = ERROR_FAIL;\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"verified %\" PRIu32 \" bytes \"\n\t\t\t\t\"in %fs (%0.3f KiB/s)\", image_size,\n\t\t\t\tduration_elapsed(&bench), duration_kbps(&bench, image_size));\n\t}\n\n\timage_close(&image);\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_verify_image_checksum_command)\n{\n\treturn CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_CHECKSUM_ONLY);\n}\n\nCOMMAND_HANDLER(handle_verify_image_command)\n{\n\treturn CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_VERIFY);\n}\n\nCOMMAND_HANDLER(handle_test_image_command)\n{\n\treturn CALL_COMMAND_HANDLER(handle_verify_image_command_internal, IMAGE_TEST);\n}\n\nstatic int handle_bp_command_list(struct command_invocation *cmd)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\twhile (breakpoint) {\n\t\tif (breakpoint->type == BKPT_SOFT) {\n\t\t\tchar *buf = buf_to_hex_str(breakpoint->orig_instr,\n\t\t\t\t\tbreakpoint->length);\n\t\t\tcommand_print(cmd, \"IVA breakpoint: \" TARGET_ADDR_FMT \", 0x%x, 0x%s\",\n\t\t\t\t\tbreakpoint->address,\n\t\t\t\t\tbreakpoint->length,\n\t\t\t\t\tbuf);\n\t\t\tfree(buf);\n\t\t} else {\n\t\t\tif ((breakpoint->address == 0) && (breakpoint->asid != 0))\n\t\t\t\tcommand_print(cmd, \"Context breakpoint: 0x%8.8\" PRIx32 \", 0x%x, %u\",\n\t\t\t\t\t\t\tbreakpoint->asid,\n\t\t\t\t\t\t\tbreakpoint->length, breakpoint->number);\n\t\t\telse if ((breakpoint->address != 0) && (breakpoint->asid != 0)) {\n\t\t\t\tcommand_print(cmd, \"Hybrid breakpoint(IVA): \" TARGET_ADDR_FMT \", 0x%x, %u\",\n\t\t\t\t\t\t\tbreakpoint->address,\n\t\t\t\t\t\t\tbreakpoint->length, breakpoint->number);\n\t\t\t\tcommand_print(cmd, \"\\t|--->linked with ContextID: 0x%8.8\" PRIx32,\n\t\t\t\t\t\t\tbreakpoint->asid);\n\t\t\t} else\n\t\t\t\tcommand_print(cmd, \"Breakpoint(IVA): \" TARGET_ADDR_FMT \", 0x%x, %u\",\n\t\t\t\t\t\t\tbreakpoint->address,\n\t\t\t\t\t\t\tbreakpoint->length, breakpoint->number);\n\t\t}\n\n\t\tbreakpoint = breakpoint->next;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int handle_bp_command_set(struct command_invocation *cmd,\n\t\ttarget_addr_t addr, uint32_t asid, uint32_t length, int hw)\n{\n\tstruct target *target = get_current_target(cmd->ctx);\n\tint retval;\n\n\tif (asid == 0) {\n\t\tretval = breakpoint_add(target, addr, length, hw);\n\t\t/* error is always logged in breakpoint_add(), do not print it again */\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(cmd, \"breakpoint set at \" TARGET_ADDR_FMT \"\", addr);\n\n\t} else if (addr == 0) {\n\t\tif (!target->type->add_context_breakpoint) {\n\t\t\tLOG_ERROR(\"Context breakpoint not available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tretval = context_breakpoint_add(target, asid, length, hw);\n\t\t/* error is always logged in context_breakpoint_add(), do not print it again */\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(cmd, \"Context breakpoint set at 0x%8.8\" PRIx32 \"\", asid);\n\n\t} else {\n\t\tif (!target->type->add_hybrid_breakpoint) {\n\t\t\tLOG_ERROR(\"Hybrid breakpoint not available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tretval = hybrid_breakpoint_add(target, addr, asid, length, hw);\n\t\t/* error is always logged in hybrid_breakpoint_add(), do not print it again */\n\t\tif (retval == ERROR_OK)\n\t\t\tcommand_print(cmd, \"Hybrid breakpoint set at 0x%8.8\" PRIx32 \"\", asid);\n\t}\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_bp_command)\n{\n\ttarget_addr_t addr;\n\tuint32_t asid;\n\tuint32_t length;\n\tint hw = BKPT_SOFT;\n\n\tswitch (CMD_ARGC) {\n\t\tcase 0:\n\t\t\treturn handle_bp_command_list(CMD);\n\n\t\tcase 2:\n\t\t\tasid = 0;\n\t\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\t\t\treturn handle_bp_command_set(CMD, addr, asid, length, hw);\n\n\t\tcase 3:\n\t\t\tif (strcmp(CMD_ARGV[2], \"hw\") == 0) {\n\t\t\t\thw = BKPT_HARD;\n\t\t\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\t\t\t\tasid = 0;\n\t\t\t\treturn handle_bp_command_set(CMD, addr, asid, length, hw);\n\t\t\t} else if (strcmp(CMD_ARGV[2], \"hw_ctx\") == 0) {\n\t\t\t\thw = BKPT_HARD;\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], asid);\n\t\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\t\t\t\taddr = 0;\n\t\t\t\treturn handle_bp_command_set(CMD, addr, asid, length, hw);\n\t\t\t}\n\t\t\t/* fallthrough */\n\t\tcase 4:\n\t\t\thw = BKPT_HARD;\n\t\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], asid);\n\t\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], length);\n\t\t\treturn handle_bp_command_set(CMD, addr, asid, length, hw);\n\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n}\n\nCOMMAND_HANDLER(handle_rbp_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (!strcmp(CMD_ARGV[0], \"all\")) {\n\t\tbreakpoint_remove_all(target);\n\t} else {\n\t\ttarget_addr_t addr;\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\n\t\tbreakpoint_remove(target, addr);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_wp_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif (CMD_ARGC == 0) {\n\t\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\t\twhile (watchpoint) {\n\t\t\tcommand_print(CMD, \"address: \" TARGET_ADDR_FMT\n\t\t\t\t\t\", len: 0x%8.8\" PRIx32\n\t\t\t\t\t\", r/w/a: %i, value: 0x%8.8\" PRIx32\n\t\t\t\t\t\", mask: 0x%8.8\" PRIx32,\n\t\t\t\t\twatchpoint->address,\n\t\t\t\t\twatchpoint->length,\n\t\t\t\t\t(int)watchpoint->rw,\n\t\t\t\t\twatchpoint->value,\n\t\t\t\t\twatchpoint->mask);\n\t\t\twatchpoint = watchpoint->next;\n\t\t}\n\t\treturn ERROR_OK;\n\t}\n\n\tenum watchpoint_rw type = WPT_ACCESS;\n\ttarget_addr_t addr = 0;\n\tuint32_t length = 0;\n\tuint32_t data_value = 0x0;\n\tuint32_t data_mask = 0xffffffff;\n\n\tswitch (CMD_ARGC) {\n\tcase 5:\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], data_mask);\n\t\t/* fall through */\n\tcase 4:\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], data_value);\n\t\t/* fall through */\n\tcase 3:\n\t\tswitch (CMD_ARGV[2][0]) {\n\t\tcase 'r':\n\t\t\ttype = WPT_READ;\n\t\t\tbreak;\n\t\tcase 'w':\n\t\t\ttype = WPT_WRITE;\n\t\t\tbreak;\n\t\tcase 'a':\n\t\t\ttype = WPT_ACCESS;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"invalid watchpoint mode ('%c')\", CMD_ARGV[2][0]);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\t/* fall through */\n\tcase 2:\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], length);\n\t\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\t\tbreak;\n\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tint retval = watchpoint_add(target, addr, length, type,\n\t\t\tdata_value, data_mask);\n\tif (retval != ERROR_OK)\n\t\tLOG_ERROR(\"Failure setting watchpoints\");\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_rwp_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget_addr_t addr;\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\twatchpoint_remove(target, addr);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Translate a virtual address to a physical address.\n *\n * The low-level target implementation must have logged a detailed error\n * which is forwarded to telnet/GDB session.\n */\nCOMMAND_HANDLER(handle_virt2phys_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget_addr_t va;\n\tCOMMAND_PARSE_ADDRESS(CMD_ARGV[0], va);\n\ttarget_addr_t pa;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = target->type->virt2phys(target, va, &pa);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(CMD, \"Physical address \" TARGET_ADDR_FMT \"\", pa);\n\n\treturn retval;\n}\n\nstatic void write_data(FILE *f, const void *data, size_t len)\n{\n\tsize_t written = fwrite(data, 1, len, f);\n\tif (written != len)\n\t\tLOG_ERROR(\"failed to write %zu bytes: %s\", len, strerror(errno));\n}\n\nstatic void write_long(FILE *f, int l, struct target *target)\n{\n\tuint8_t val[4];\n\n\ttarget_buffer_set_u32(target, val, l);\n\twrite_data(f, val, 4);\n}\n\nstatic void write_string(FILE *f, char *s)\n{\n\twrite_data(f, s, strlen(s));\n}\n\ntypedef unsigned char UNIT[2];  /* unit of profiling */\n\n/* Dump a gmon.out histogram file. */\nstatic void write_gmon(uint32_t *samples, uint32_t sample_num, const char *filename, bool with_range,\n\t\t\tuint32_t start_address, uint32_t end_address, struct target *target, uint32_t duration_ms)\n{\n\tuint32_t i;\n\tFILE *f = fopen(filename, \"w\");\n\tif (!f)\n\t\treturn;\n\twrite_string(f, \"gmon\");\n\twrite_long(f, 0x00000001, target); /* Version */\n\twrite_long(f, 0, target); /* padding */\n\twrite_long(f, 0, target); /* padding */\n\twrite_long(f, 0, target); /* padding */\n\n\tuint8_t zero = 0;  /* GMON_TAG_TIME_HIST */\n\twrite_data(f, &zero, 1);\n\n\t/* figure out bucket size */\n\tuint32_t min;\n\tuint32_t max;\n\tif (with_range) {\n\t\tmin = start_address;\n\t\tmax = end_address;\n\t} else {\n\t\tmin = samples[0];\n\t\tmax = samples[0];\n\t\tfor (i = 0; i < sample_num; i++) {\n\t\t\tif (min > samples[i])\n\t\t\t\tmin = samples[i];\n\t\t\tif (max < samples[i])\n\t\t\t\tmax = samples[i];\n\t\t}\n\n\t\t/* max should be (largest sample + 1)\n\t\t * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */\n\t\tif (max < UINT32_MAX)\n\t\t\tmax++;\n\n\t\t/* gprof requires (max - min) >= 2 */\n\t\twhile ((max - min) < 2) {\n\t\t\tif (max < UINT32_MAX)\n\t\t\t\tmax++;\n\t\t\telse\n\t\t\t\tmin--;\n\t\t}\n\t}\n\n\tuint32_t address_space = max - min;\n\n\t/* FIXME: What is the reasonable number of buckets?\n\t * The profiling result will be more accurate if there are enough buckets. */\n\tstatic const uint32_t max_buckets = 128 * 1024; /* maximum buckets. */\n\tuint32_t num_buckets = address_space / sizeof(UNIT);\n\tif (num_buckets > max_buckets)\n\t\tnum_buckets = max_buckets;\n\tint *buckets = malloc(sizeof(int) * num_buckets);\n\tif (!buckets) {\n\t\tfclose(f);\n\t\treturn;\n\t}\n\tmemset(buckets, 0, sizeof(int) * num_buckets);\n\tfor (i = 0; i < sample_num; i++) {\n\t\tuint32_t address = samples[i];\n\n\t\tif ((address < min) || (max <= address))\n\t\t\tcontinue;\n\n\t\tlong long a = address - min;\n\t\tlong long b = num_buckets;\n\t\tlong long c = address_space;\n\t\tint index_t = (a * b) / c; /* danger!!!! int32 overflows */\n\t\tbuckets[index_t]++;\n\t}\n\n\t/* append binary memory gmon.out &profile_hist_hdr ((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */\n\twrite_long(f, min, target);\t\t\t/* low_pc */\n\twrite_long(f, max, target);\t\t\t/* high_pc */\n\twrite_long(f, num_buckets, target);\t/* # of buckets */\n\tfloat sample_rate = sample_num / (duration_ms / 1000.0);\n\twrite_long(f, sample_rate, target);\n\twrite_string(f, \"seconds\");\n\tfor (i = 0; i < (15-strlen(\"seconds\")); i++)\n\t\twrite_data(f, &zero, 1);\n\twrite_string(f, \"s\");\n\n\t/*append binary memory gmon.out profile_hist_data (profile_hist_data + profile_hist_hdr.hist_size) */\n\n\tchar *data = malloc(2 * num_buckets);\n\tif (data) {\n\t\tfor (i = 0; i < num_buckets; i++) {\n\t\t\tint val;\n\t\t\tval = buckets[i];\n\t\t\tif (val > 65535)\n\t\t\t\tval = 65535;\n\t\t\tdata[i * 2] = val&0xff;\n\t\t\tdata[i * 2 + 1] = (val >> 8) & 0xff;\n\t\t}\n\t\tfree(buckets);\n\t\twrite_data(f, data, num_buckets * 2);\n\t\tfree(data);\n\t} else\n\t\tfree(buckets);\n\n\tfclose(f);\n}\n\n/* profiling samples the CPU PC as quickly as OpenOCD is able,\n * which will be used as a random sampling of PC */\nCOMMAND_HANDLER(handle_profile_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tif ((CMD_ARGC != 2) && (CMD_ARGC != 4))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst uint32_t MAX_PROFILE_SAMPLE_NUM = 10000;\n\tuint32_t offset;\n\tuint32_t num_of_samples;\n\tint retval = ERROR_OK;\n\tbool halted_before_profiling = target->state == TARGET_HALTED;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], offset);\n\n\tuint32_t start_address = 0;\n\tuint32_t end_address = 0;\n\tbool with_range = false;\n\tif (CMD_ARGC == 4) {\n\t\twith_range = true;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], start_address);\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], end_address);\n\t\tif (start_address > end_address || (end_address - start_address) < 2) {\n\t\t\tcommand_print(CMD, \"Error: end - start < 2\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tuint32_t *samples = malloc(sizeof(uint32_t) * MAX_PROFILE_SAMPLE_NUM);\n\tif (!samples) {\n\t\tLOG_ERROR(\"No memory to store samples.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint64_t timestart_ms = timeval_ms();\n\t/**\n\t * Some cores let us sample the PC without the\n\t * annoying halt/resume step; for example, ARMv7 PCSR.\n\t * Provide a way to use that more efficient mechanism.\n\t */\n\tretval = target_profiling(target, samples, MAX_PROFILE_SAMPLE_NUM,\n\t\t\t\t&num_of_samples, offset);\n\tif (retval != ERROR_OK) {\n\t\tfree(samples);\n\t\treturn retval;\n\t}\n\tuint32_t duration_ms = timeval_ms() - timestart_ms;\n\n\tassert(num_of_samples <= MAX_PROFILE_SAMPLE_NUM);\n\n\tretval = target_poll(target);\n\tif (retval != ERROR_OK) {\n\t\tfree(samples);\n\t\treturn retval;\n\t}\n\n\tif (target->state == TARGET_RUNNING && halted_before_profiling) {\n\t\t/* The target was halted before we started and is running now. Halt it,\n\t\t * for consistency. */\n\t\tretval = target_halt(target);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(samples);\n\t\t\treturn retval;\n\t\t}\n\t} else if (target->state == TARGET_HALTED && !halted_before_profiling) {\n\t\t/* The target was running before we started and is halted now. Resume\n\t\t * it, for consistency. */\n\t\tretval = target_resume(target, 1, 0, 0, 0);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(samples);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tretval = target_poll(target);\n\tif (retval != ERROR_OK) {\n\t\tfree(samples);\n\t\treturn retval;\n\t}\n\n\twrite_gmon(samples, num_of_samples, CMD_ARGV[1],\n\t\t   with_range, start_address, end_address, target, duration_ms);\n\tcommand_print(CMD, \"Wrote %s\", CMD_ARGV[1]);\n\n\tfree(samples);\n\treturn retval;\n}\n\nstatic int new_u64_array_element(Jim_Interp *interp, const char *varname, int idx, uint64_t val)\n{\n\tchar *namebuf;\n\tJim_Obj *obj_name, *obj_val;\n\tint result;\n\n\tnamebuf = alloc_printf(\"%s(%d)\", varname, idx);\n\tif (!namebuf)\n\t\treturn JIM_ERR;\n\n\tobj_name = Jim_NewStringObj(interp, namebuf, -1);\n\tjim_wide wide_val = val;\n\tobj_val = Jim_NewWideObj(interp, wide_val);\n\tif (!obj_name || !obj_val) {\n\t\tfree(namebuf);\n\t\treturn JIM_ERR;\n\t}\n\n\tJim_IncrRefCount(obj_name);\n\tJim_IncrRefCount(obj_val);\n\tresult = Jim_SetVariable(interp, obj_name, obj_val);\n\tJim_DecrRefCount(interp, obj_name);\n\tJim_DecrRefCount(interp, obj_val);\n\tfree(namebuf);\n\t/* printf(\"%s(%d) <= 0%08x\\n\", varname, idx, val); */\n\treturn result;\n}\n\nstatic int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv)\n{\n\tint e;\n\n\tLOG_WARNING(\"DEPRECATED! use 'read_memory' not 'mem2array'\");\n\n\t/* argv[0] = name of array to receive the data\n\t * argv[1] = desired element width in bits\n\t * argv[2] = memory address\n\t * argv[3] = count of times to read\n\t * argv[4] = optional \"phys\"\n\t */\n\tif (argc < 4 || argc > 5) {\n\t\tJim_WrongNumArgs(interp, 0, argv, \"varname width addr nelems [phys]\");\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Arg 0: Name of the array variable */\n\tconst char *varname = Jim_GetString(argv[0], NULL);\n\n\t/* Arg 1: Bit width of one element */\n\tlong l;\n\te = Jim_GetLong(interp, argv[1], &l);\n\tif (e != JIM_OK)\n\t\treturn e;\n\tconst unsigned int width_bits = l;\n\n\tif (width_bits != 8 &&\n\t\t\twidth_bits != 16 &&\n\t\t\twidth_bits != 32 &&\n\t\t\twidth_bits != 64) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"Invalid width param. Must be one of: 8, 16, 32 or 64.\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\tconst unsigned int width = width_bits / 8;\n\n\t/* Arg 2: Memory address */\n\tjim_wide wide_addr;\n\te = Jim_GetWide(interp, argv[2], &wide_addr);\n\tif (e != JIM_OK)\n\t\treturn e;\n\ttarget_addr_t addr = (target_addr_t)wide_addr;\n\n\t/* Arg 3: Number of elements to read */\n\te = Jim_GetLong(interp, argv[3], &l);\n\tif (e != JIM_OK)\n\t\treturn e;\n\tsize_t len = l;\n\n\t/* Arg 4: phys */\n\tbool is_phys = false;\n\tif (argc > 4) {\n\t\tint str_len = 0;\n\t\tconst char *phys = Jim_GetString(argv[4], &str_len);\n\t\tif (!strncmp(phys, \"phys\", str_len))\n\t\t\tis_phys = true;\n\t\telse\n\t\t\treturn JIM_ERR;\n\t}\n\n\t/* Argument checks */\n\tif (len == 0) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp), \"mem2array: zero width read?\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\tif ((addr + (len * width)) < addr) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp), \"mem2array: addr + len - wraps to zero?\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\tif (len > 65536) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"mem2array: too large read request, exceeds 64K items\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\tif ((width == 1) ||\n\t\t((width == 2) && ((addr & 1) == 0)) ||\n\t\t((width == 4) && ((addr & 3) == 0)) ||\n\t\t((width == 8) && ((addr & 7) == 0))) {\n\t\t/* alignment correct */\n\t} else {\n\t\tchar buf[100];\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tsprintf(buf, \"mem2array address: \" TARGET_ADDR_FMT \" is not aligned for %\" PRIu32 \" byte reads\",\n\t\t\t\taddr,\n\t\t\t\twidth);\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Transfer loop */\n\n\t/* index counter */\n\tsize_t idx = 0;\n\n\tconst size_t buffersize = 4096;\n\tuint8_t *buffer = malloc(buffersize);\n\tif (!buffer)\n\t\treturn JIM_ERR;\n\n\t/* assume ok */\n\te = JIM_OK;\n\twhile (len) {\n\t\t/* Slurp... in buffer size chunks */\n\t\tconst unsigned int max_chunk_len = buffersize / width;\n\t\tconst size_t chunk_len = MIN(len, max_chunk_len); /* in elements.. */\n\n\t\tint retval;\n\t\tif (is_phys)\n\t\t\tretval = target_read_phys_memory(target, addr, width, chunk_len, buffer);\n\t\telse\n\t\t\tretval = target_read_memory(target, addr, width, chunk_len, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* BOO !*/\n\t\t\tLOG_ERROR(\"mem2array: Read @ \" TARGET_ADDR_FMT \", w=%u, cnt=%zu, failed\",\n\t\t\t\t\t  addr,\n\t\t\t\t\t  width,\n\t\t\t\t\t  chunk_len);\n\t\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\t\tJim_AppendStrings(interp, Jim_GetResult(interp), \"mem2array: cannot read memory\", NULL);\n\t\t\te = JIM_ERR;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tfor (size_t i = 0; i < chunk_len ; i++, idx++) {\n\t\t\t\tuint64_t v = 0;\n\t\t\t\tswitch (width) {\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\tv = target_buffer_get_u64(target, &buffer[i*width]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\tv = target_buffer_get_u32(target, &buffer[i*width]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 2:\n\t\t\t\t\t\tv = target_buffer_get_u16(target, &buffer[i*width]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\tv = buffer[i] & 0x0ff;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tnew_u64_array_element(interp, varname, idx, v);\n\t\t\t}\n\t\t\tlen -= chunk_len;\n\t\t\taddr += chunk_len * width;\n\t\t}\n\t}\n\n\tfree(buffer);\n\n\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\n\treturn e;\n}\n\nCOMMAND_HANDLER(handle_target_read_memory)\n{\n\t/*\n\t * CMD_ARGV[0] = memory address\n\t * CMD_ARGV[1] = desired element width in bits\n\t * CMD_ARGV[2] = number of elements to read\n\t * CMD_ARGV[3] = optional \"phys\"\n\t */\n\n\tif (CMD_ARGC < 3 || CMD_ARGC > 4)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Arg 1: Memory address. */\n\ttarget_addr_t addr;\n\tCOMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], addr);\n\n\t/* Arg 2: Bit width of one element. */\n\tunsigned int width_bits;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], width_bits);\n\n\t/* Arg 3: Number of elements to read. */\n\tunsigned int count;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], count);\n\n\t/* Arg 4: Optional 'phys'. */\n\tbool is_phys = false;\n\tif (CMD_ARGC == 4) {\n\t\tif (strcmp(CMD_ARGV[3], \"phys\")) {\n\t\t\tcommand_print(CMD, \"invalid argument '%s', must be 'phys'\", CMD_ARGV[3]);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\n\t\tis_phys = true;\n\t}\n\n\tswitch (width_bits) {\n\tcase 8:\n\tcase 16:\n\tcase 32:\n\tcase 64:\n\t\tbreak;\n\tdefault:\n\t\tcommand_print(CMD, \"invalid width, must be 8, 16, 32 or 64\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tconst unsigned int width = width_bits / 8;\n\n\tif ((addr + (count * width)) < addr) {\n\t\tcommand_print(CMD, \"read_memory: addr + count wraps to zero\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (count > 65536) {\n\t\tcommand_print(CMD, \"read_memory: too large read request, exceeds 64K elements\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tconst size_t buffersize = 4096;\n\tuint8_t *buffer = malloc(buffersize);\n\n\tif (!buffer) {\n\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tchar *separator = \"\";\n\twhile (count > 0) {\n\t\tconst unsigned int max_chunk_len = buffersize / width;\n\t\tconst size_t chunk_len = MIN(count, max_chunk_len);\n\n\t\tint retval;\n\n\t\tif (is_phys)\n\t\t\tretval = target_read_phys_memory(target, addr, width, chunk_len, buffer);\n\t\telse\n\t\t\tretval = target_read_memory(target, addr, width, chunk_len, buffer);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"read_memory: read at \" TARGET_ADDR_FMT \" with width=%u and count=%zu failed\",\n\t\t\t\taddr, width_bits, chunk_len);\n\t\t\t/*\n\t\t\t * FIXME: we append the errmsg to the list of value already read.\n\t\t\t * Add a way to flush and replace old output, but LOG_DEBUG() it\n\t\t\t */\n\t\t\tcommand_print(CMD, \"read_memory: failed to read memory\");\n\t\t\tfree(buffer);\n\t\t\treturn retval;\n\t\t}\n\n\t\tfor (size_t i = 0; i < chunk_len ; i++) {\n\t\t\tuint64_t v = 0;\n\n\t\t\tswitch (width) {\n\t\t\tcase 8:\n\t\t\t\tv = target_buffer_get_u64(target, &buffer[i * width]);\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\tv = target_buffer_get_u32(target, &buffer[i * width]);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tv = target_buffer_get_u16(target, &buffer[i * width]);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tv = buffer[i];\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcommand_print_sameline(CMD, \"%s0x%\" PRIx64, separator, v);\n\t\t\tseparator = \" \";\n\t\t}\n\n\t\tcount -= chunk_len;\n\t\taddr += chunk_len * width;\n\t}\n\n\tfree(buffer);\n\n\treturn ERROR_OK;\n}\n\nstatic int get_u64_array_element(Jim_Interp *interp, const char *varname, size_t idx, uint64_t *val)\n{\n\tchar *namebuf = alloc_printf(\"%s(%zu)\", varname, idx);\n\tif (!namebuf)\n\t\treturn JIM_ERR;\n\n\tJim_Obj *obj_name = Jim_NewStringObj(interp, namebuf, -1);\n\tif (!obj_name) {\n\t\tfree(namebuf);\n\t\treturn JIM_ERR;\n\t}\n\n\tJim_IncrRefCount(obj_name);\n\tJim_Obj *obj_val = Jim_GetVariable(interp, obj_name, JIM_ERRMSG);\n\tJim_DecrRefCount(interp, obj_name);\n\tfree(namebuf);\n\tif (!obj_val)\n\t\treturn JIM_ERR;\n\n\tjim_wide wide_val;\n\tint result = Jim_GetWide(interp, obj_val, &wide_val);\n\t*val = wide_val;\n\treturn result;\n}\n\nstatic int target_array2mem(Jim_Interp *interp, struct target *target,\n\t\tint argc, Jim_Obj *const *argv)\n{\n\tint e;\n\n\tLOG_WARNING(\"DEPRECATED! use 'write_memory' not 'array2mem'\");\n\n\t/* argv[0] = name of array from which to read the data\n\t * argv[1] = desired element width in bits\n\t * argv[2] = memory address\n\t * argv[3] = number of elements to write\n\t * argv[4] = optional \"phys\"\n\t */\n\tif (argc < 4 || argc > 5) {\n\t\tJim_WrongNumArgs(interp, 0, argv, \"varname width addr nelems [phys]\");\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Arg 0: Name of the array variable */\n\tconst char *varname = Jim_GetString(argv[0], NULL);\n\n\t/* Arg 1: Bit width of one element */\n\tlong l;\n\te = Jim_GetLong(interp, argv[1], &l);\n\tif (e != JIM_OK)\n\t\treturn e;\n\tconst unsigned int width_bits = l;\n\n\tif (width_bits != 8 &&\n\t\t\twidth_bits != 16 &&\n\t\t\twidth_bits != 32 &&\n\t\t\twidth_bits != 64) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"Invalid width param. Must be one of: 8, 16, 32 or 64.\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\tconst unsigned int width = width_bits / 8;\n\n\t/* Arg 2: Memory address */\n\tjim_wide wide_addr;\n\te = Jim_GetWide(interp, argv[2], &wide_addr);\n\tif (e != JIM_OK)\n\t\treturn e;\n\ttarget_addr_t addr = (target_addr_t)wide_addr;\n\n\t/* Arg 3: Number of elements to write */\n\te = Jim_GetLong(interp, argv[3], &l);\n\tif (e != JIM_OK)\n\t\treturn e;\n\tsize_t len = l;\n\n\t/* Arg 4: Phys */\n\tbool is_phys = false;\n\tif (argc > 4) {\n\t\tint str_len = 0;\n\t\tconst char *phys = Jim_GetString(argv[4], &str_len);\n\t\tif (!strncmp(phys, \"phys\", str_len))\n\t\t\tis_phys = true;\n\t\telse\n\t\t\treturn JIM_ERR;\n\t}\n\n\t/* Argument checks */\n\tif (len == 0) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"array2mem: zero width read?\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\tif ((addr + (len * width)) < addr) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"array2mem: addr + len - wraps to zero?\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\tif (len > 65536) {\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp),\n\t\t\t\t\"array2mem: too large memory write request, exceeds 64K items\", NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\tif ((width == 1) ||\n\t\t((width == 2) && ((addr & 1) == 0)) ||\n\t\t((width == 4) && ((addr & 3) == 0)) ||\n\t\t((width == 8) && ((addr & 7) == 0))) {\n\t\t/* alignment correct */\n\t} else {\n\t\tchar buf[100];\n\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\tsprintf(buf, \"array2mem address: \" TARGET_ADDR_FMT \" is not aligned for %\" PRIu32 \" byte reads\",\n\t\t\t\taddr,\n\t\t\t\twidth);\n\t\tJim_AppendStrings(interp, Jim_GetResult(interp), buf, NULL);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Transfer loop */\n\n\t/* assume ok */\n\te = JIM_OK;\n\n\tconst size_t buffersize = 4096;\n\tuint8_t *buffer = malloc(buffersize);\n\tif (!buffer)\n\t\treturn JIM_ERR;\n\n\t/* index counter */\n\tsize_t idx = 0;\n\n\twhile (len) {\n\t\t/* Slurp... in buffer size chunks */\n\t\tconst unsigned int max_chunk_len = buffersize / width;\n\n\t\tconst size_t chunk_len = MIN(len, max_chunk_len); /* in elements.. */\n\n\t\t/* Fill the buffer */\n\t\tfor (size_t i = 0; i < chunk_len; i++, idx++) {\n\t\t\tuint64_t v = 0;\n\t\t\tif (get_u64_array_element(interp, varname, idx, &v) != JIM_OK) {\n\t\t\t\tfree(buffer);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t\tswitch (width) {\n\t\t\tcase 8:\n\t\t\t\ttarget_buffer_set_u64(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\ttarget_buffer_set_u32(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttarget_buffer_set_u16(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tbuffer[i] = v & 0x0ff;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tlen -= chunk_len;\n\n\t\t/* Write the buffer to memory */\n\t\tint retval;\n\t\tif (is_phys)\n\t\t\tretval = target_write_phys_memory(target, addr, width, chunk_len, buffer);\n\t\telse\n\t\t\tretval = target_write_memory(target, addr, width, chunk_len, buffer);\n\t\tif (retval != ERROR_OK) {\n\t\t\t/* BOO !*/\n\t\t\tLOG_ERROR(\"array2mem: Write @ \" TARGET_ADDR_FMT \", w=%u, cnt=%zu, failed\",\n\t\t\t\t\t  addr,\n\t\t\t\t\t  width,\n\t\t\t\t\t  chunk_len);\n\t\t\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\t\t\tJim_AppendStrings(interp, Jim_GetResult(interp), \"array2mem: cannot read memory\", NULL);\n\t\t\te = JIM_ERR;\n\t\t\tbreak;\n\t\t}\n\t\taddr += chunk_len * width;\n\t}\n\n\tfree(buffer);\n\n\tJim_SetResult(interp, Jim_NewEmptyStringObj(interp));\n\n\treturn e;\n}\n\nstatic int target_jim_write_memory(Jim_Interp *interp, int argc,\n\t\tJim_Obj * const *argv)\n{\n\t/*\n\t * argv[1] = memory address\n\t * argv[2] = desired element width in bits\n\t * argv[3] = list of data to write\n\t * argv[4] = optional \"phys\"\n\t */\n\n\tif (argc < 4 || argc > 5) {\n\t\tJim_WrongNumArgs(interp, 1, argv, \"address width data ['phys']\");\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Arg 1: Memory address. */\n\tint e;\n\tjim_wide wide_addr;\n\te = Jim_GetWide(interp, argv[1], &wide_addr);\n\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\ttarget_addr_t addr = (target_addr_t)wide_addr;\n\n\t/* Arg 2: Bit width of one element. */\n\tlong l;\n\te = Jim_GetLong(interp, argv[2], &l);\n\n\tif (e != JIM_OK)\n\t\treturn e;\n\n\tconst unsigned int width_bits = l;\n\tsize_t count = Jim_ListLength(interp, argv[3]);\n\n\t/* Arg 4: Optional 'phys'. */\n\tbool is_phys = false;\n\n\tif (argc > 4) {\n\t\tconst char *phys = Jim_GetString(argv[4], NULL);\n\n\t\tif (strcmp(phys, \"phys\")) {\n\t\t\tJim_SetResultFormatted(interp, \"invalid argument '%s', must be 'phys'\", phys);\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tis_phys = true;\n\t}\n\n\tswitch (width_bits) {\n\tcase 8:\n\tcase 16:\n\tcase 32:\n\tcase 64:\n\t\tbreak;\n\tdefault:\n\t\tJim_SetResultString(interp, \"invalid width, must be 8, 16, 32 or 64\", -1);\n\t\treturn JIM_ERR;\n\t}\n\n\tconst unsigned int width = width_bits / 8;\n\n\tif ((addr + (count * width)) < addr) {\n\t\tJim_SetResultString(interp, \"write_memory: addr + len wraps to zero\", -1);\n\t\treturn JIM_ERR;\n\t}\n\n\tif (count > 65536) {\n\t\tJim_SetResultString(interp, \"write_memory: too large memory write request, exceeds 64K elements\", -1);\n\t\treturn JIM_ERR;\n\t}\n\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx != NULL);\n\tstruct target *target = get_current_target(cmd_ctx);\n\n\tconst size_t buffersize = 4096;\n\tuint8_t *buffer = malloc(buffersize);\n\n\tif (!buffer) {\n\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\treturn JIM_ERR;\n\t}\n\n\tsize_t j = 0;\n\n\twhile (count > 0) {\n\t\tconst unsigned int max_chunk_len = buffersize / width;\n\t\tconst size_t chunk_len = MIN(count, max_chunk_len);\n\n\t\tfor (size_t i = 0; i < chunk_len; i++, j++) {\n\t\t\tJim_Obj *tmp = Jim_ListGetIndex(interp, argv[3], j);\n\t\t\tjim_wide element_wide;\n\t\t\tJim_GetWide(interp, tmp, &element_wide);\n\n\t\t\tconst uint64_t v = element_wide;\n\n\t\t\tswitch (width) {\n\t\t\tcase 8:\n\t\t\t\ttarget_buffer_set_u64(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\ttarget_buffer_set_u32(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttarget_buffer_set_u16(target, &buffer[i * width], v);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tbuffer[i] = v & 0x0ff;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tcount -= chunk_len;\n\n\t\tint retval;\n\n\t\tif (is_phys)\n\t\t\tretval = target_write_phys_memory(target, addr, width, chunk_len, buffer);\n\t\telse\n\t\t\tretval = target_write_memory(target, addr, width, chunk_len, buffer);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"write_memory: write at \" TARGET_ADDR_FMT \" with width=%u and count=%zu failed\",\n\t\t\t\taddr,  width_bits, chunk_len);\n\t\t\tJim_SetResultString(interp, \"write_memory: failed to write memory\", -1);\n\t\t\te = JIM_ERR;\n\t\t\tbreak;\n\t\t}\n\n\t\taddr += chunk_len * width;\n\t}\n\n\tfree(buffer);\n\n\treturn e;\n}\n\n/* FIX? should we propagate errors here rather than printing them\n * and continuing?\n */\nvoid target_handle_event(struct target *target, enum target_event e)\n{\n\tstruct target_event_action *teap;\n\tint retval;\n\n\tfor (teap = target->event_action; teap; teap = teap->next) {\n\t\tif (teap->event == e) {\n\t\t\tLOG_DEBUG(\"target(%d): %s (%s) event: %d (%s) action: %s\",\n\t\t\t\t\t   target->target_number,\n\t\t\t\t\t   target_name(target),\n\t\t\t\t\t   target_type_name(target),\n\t\t\t\t\t   e,\n\t\t\t\t\t   target_event_name(e),\n\t\t\t\t\t   Jim_GetString(teap->body, NULL));\n\n\t\t\t/* Override current target by the target an event\n\t\t\t * is issued from (lot of scripts need it).\n\t\t\t * Return back to previous override as soon\n\t\t\t * as the handler processing is done */\n\t\t\tstruct command_context *cmd_ctx = current_command_context(teap->interp);\n\t\t\tstruct target *saved_target_override = cmd_ctx->current_target_override;\n\t\t\tcmd_ctx->current_target_override = target;\n\n\t\t\tretval = Jim_EvalObj(teap->interp, teap->body);\n\n\t\t\tcmd_ctx->current_target_override = saved_target_override;\n\n\t\t\tif (retval == ERROR_COMMAND_CLOSE_CONNECTION)\n\t\t\t\treturn;\n\n\t\t\tif (retval == JIM_RETURN)\n\t\t\t\tretval = teap->interp->returnCode;\n\n\t\t\tif (retval != JIM_OK) {\n\t\t\t\tJim_MakeErrorMessage(teap->interp);\n\t\t\t\tLOG_USER(\"Error executing event %s on target %s:\\n%s\",\n\t\t\t\t\t\t  target_event_name(e),\n\t\t\t\t\t\t  target_name(target),\n\t\t\t\t\t\t  Jim_GetString(Jim_GetResult(teap->interp), NULL));\n\t\t\t\t/* clean both error code and stacktrace before return */\n\t\t\t\tJim_Eval(teap->interp, \"error \\\"\\\" \\\"\\\"\");\n\t\t\t}\n\t\t}\n\t}\n}\n\nstatic int target_jim_get_reg(Jim_Interp *interp, int argc,\n\t\tJim_Obj * const *argv)\n{\n\tbool force = false;\n\n\tif (argc == 3) {\n\t\tconst char *option = Jim_GetString(argv[1], NULL);\n\n\t\tif (!strcmp(option, \"-force\")) {\n\t\t\targc--;\n\t\t\targv++;\n\t\t\tforce = true;\n\t\t} else {\n\t\t\tJim_SetResultFormatted(interp, \"invalid option '%s'\", option);\n\t\t\treturn JIM_ERR;\n\t\t}\n\t}\n\n\tif (argc != 2) {\n\t\tJim_WrongNumArgs(interp, 1, argv, \"[-force] list\");\n\t\treturn JIM_ERR;\n\t}\n\n\tconst int length = Jim_ListLength(interp, argv[1]);\n\n\tJim_Obj *result_dict = Jim_NewDictObj(interp, NULL, 0);\n\n\tif (!result_dict)\n\t\treturn JIM_ERR;\n\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx != NULL);\n\tconst struct target *target = get_current_target(cmd_ctx);\n\n\tfor (int i = 0; i < length; i++) {\n\t\tJim_Obj *elem = Jim_ListGetIndex(interp, argv[1], i);\n\n\t\tif (!elem)\n\t\t\treturn JIM_ERR;\n\n\t\tconst char *reg_name = Jim_String(elem);\n\n\t\tstruct reg *reg = register_get_by_name(target->reg_cache, reg_name,\n\t\t\tfalse);\n\n\t\tif (!reg || !reg->exist) {\n\t\t\tJim_SetResultFormatted(interp, \"unknown register '%s'\", reg_name);\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tif (force) {\n\t\t\tint retval = reg->type->get(reg);\n\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tJim_SetResultFormatted(interp, \"failed to read register '%s'\",\n\t\t\t\t\treg_name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\t\t}\n\n\t\tchar *reg_value = buf_to_hex_str(reg->value, reg->size);\n\n\t\tif (!reg_value) {\n\t\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tchar *tmp = alloc_printf(\"0x%s\", reg_value);\n\n\t\tfree(reg_value);\n\n\t\tif (!tmp) {\n\t\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tJim_DictAddElement(interp, result_dict, elem,\n\t\t\tJim_NewStringObj(interp, tmp, -1));\n\n\t\tfree(tmp);\n\t}\n\n\tJim_SetResult(interp, result_dict);\n\n\treturn JIM_OK;\n}\n\nstatic int target_jim_set_reg(Jim_Interp *interp, int argc,\n\t\tJim_Obj * const *argv)\n{\n\tif (argc != 2) {\n\t\tJim_WrongNumArgs(interp, 1, argv, \"dict\");\n\t\treturn JIM_ERR;\n\t}\n\n\tint tmp;\n#if JIM_VERSION >= 80\n\tJim_Obj **dict = Jim_DictPairs(interp, argv[1], &tmp);\n\n\tif (!dict)\n\t\treturn JIM_ERR;\n#else\n\tJim_Obj **dict;\n\tint ret = Jim_DictPairs(interp, argv[1], &dict, &tmp);\n\n\tif (ret != JIM_OK)\n\t\treturn ret;\n#endif\n\n\tconst unsigned int length = tmp;\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\tconst struct target *target = get_current_target(cmd_ctx);\n\n\tfor (unsigned int i = 0; i < length; i += 2) {\n\t\tconst char *reg_name = Jim_String(dict[i]);\n\t\tconst char *reg_value = Jim_String(dict[i + 1]);\n\t\tstruct reg *reg = register_get_by_name(target->reg_cache, reg_name,\n\t\t\tfalse);\n\n\t\tif (!reg || !reg->exist) {\n\t\t\tJim_SetResultFormatted(interp, \"unknown register '%s'\", reg_name);\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tuint8_t *buf = malloc(DIV_ROUND_UP(reg->size, 8));\n\n\t\tif (!buf) {\n\t\t\tLOG_ERROR(\"Failed to allocate memory\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\n\t\tstr_to_buf(reg_value, strlen(reg_value), buf, reg->size, 0);\n\t\tint retval = reg->type->set(reg, buf);\n\t\tfree(buf);\n\n\t\tif (retval != ERROR_OK) {\n\t\t\tJim_SetResultFormatted(interp, \"failed to set '%s' to register '%s'\",\n\t\t\t\treg_value, reg_name);\n\t\t\treturn JIM_ERR;\n\t\t}\n\t}\n\n\treturn JIM_OK;\n}\n\n/**\n * Returns true only if the target has a handler for the specified event.\n */\nbool target_has_event_action(struct target *target, enum target_event event)\n{\n\tstruct target_event_action *teap;\n\n\tfor (teap = target->event_action; teap; teap = teap->next) {\n\t\tif (teap->event == event)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nenum target_cfg_param {\n\tTCFG_TYPE,\n\tTCFG_EVENT,\n\tTCFG_WORK_AREA_VIRT,\n\tTCFG_WORK_AREA_PHYS,\n\tTCFG_WORK_AREA_SIZE,\n\tTCFG_WORK_AREA_BACKUP,\n\tTCFG_ENDIAN,\n\tTCFG_COREID,\n\tTCFG_CHAIN_POSITION,\n\tTCFG_DBGBASE,\n\tTCFG_RTOS,\n\tTCFG_DEFER_EXAMINE,\n\tTCFG_GDB_PORT,\n\tTCFG_GDB_MAX_CONNECTIONS,\n};\n\nstatic struct jim_nvp nvp_config_opts[] = {\n\t{ .name = \"-type\",             .value = TCFG_TYPE },\n\t{ .name = \"-event\",            .value = TCFG_EVENT },\n\t{ .name = \"-work-area-virt\",   .value = TCFG_WORK_AREA_VIRT },\n\t{ .name = \"-work-area-phys\",   .value = TCFG_WORK_AREA_PHYS },\n\t{ .name = \"-work-area-size\",   .value = TCFG_WORK_AREA_SIZE },\n\t{ .name = \"-work-area-backup\", .value = TCFG_WORK_AREA_BACKUP },\n\t{ .name = \"-endian\",           .value = TCFG_ENDIAN },\n\t{ .name = \"-coreid\",           .value = TCFG_COREID },\n\t{ .name = \"-chain-position\",   .value = TCFG_CHAIN_POSITION },\n\t{ .name = \"-dbgbase\",          .value = TCFG_DBGBASE },\n\t{ .name = \"-rtos\",             .value = TCFG_RTOS },\n\t{ .name = \"-defer-examine\",    .value = TCFG_DEFER_EXAMINE },\n\t{ .name = \"-gdb-port\",         .value = TCFG_GDB_PORT },\n\t{ .name = \"-gdb-max-connections\",   .value = TCFG_GDB_MAX_CONNECTIONS },\n\t{ .name = NULL, .value = -1 }\n};\n\nstatic int target_configure(struct jim_getopt_info *goi, struct target *target)\n{\n\tstruct jim_nvp *n;\n\tJim_Obj *o;\n\tjim_wide w;\n\tint e;\n\n\t/* parse config or cget options ... */\n\twhile (goi->argc > 0) {\n\t\tJim_SetEmptyResult(goi->interp);\n\t\t/* jim_getopt_debug(goi); */\n\n\t\tif (target->type->target_jim_configure) {\n\t\t\t/* target defines a configure function */\n\t\t\t/* target gets first dibs on parameters */\n\t\t\te = (*(target->type->target_jim_configure))(target, goi);\n\t\t\tif (e == JIM_OK) {\n\t\t\t\t/* more? */\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (e == JIM_ERR) {\n\t\t\t\t/* An error */\n\t\t\t\treturn e;\n\t\t\t}\n\t\t\t/* otherwise we 'continue' below */\n\t\t}\n\t\te = jim_getopt_nvp(goi, nvp_config_opts, &n);\n\t\tif (e != JIM_OK) {\n\t\t\tjim_getopt_nvp_unknown(goi, nvp_config_opts, 0);\n\t\t\treturn e;\n\t\t}\n\t\tswitch (n->value) {\n\t\tcase TCFG_TYPE:\n\t\t\t/* not settable */\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tJim_SetResultFormatted(goi->interp,\n\t\t\t\t\t\t\"not settable: %s\", n->name);\n\t\t\t\treturn JIM_ERR;\n\t\t\t} else {\nno_params:\n\t\t\t\tif (goi->argc != 0) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp,\n\t\t\t\t\t\t\tgoi->argc, goi->argv,\n\t\t\t\t\t\t\t\"NO PARAMS\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t}\n\t\t\tJim_SetResultString(goi->interp,\n\t\t\t\t\ttarget_type_name(target), -1);\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\t\tcase TCFG_EVENT:\n\t\t\tif (goi->argc == 0) {\n\t\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event ?event-name? ...\");\n\t\t\t\treturn JIM_ERR;\n\t\t\t}\n\n\t\t\te = jim_getopt_nvp(goi, nvp_target_event, &n);\n\t\t\tif (e != JIM_OK) {\n\t\t\t\tjim_getopt_nvp_unknown(goi, nvp_target_event, 1);\n\t\t\t\treturn e;\n\t\t\t}\n\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tif (goi->argc != 1) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event ?event-name? ?EVENT-BODY?\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0) {\n\t\t\t\t\tJim_WrongNumArgs(goi->interp, goi->argc, goi->argv, \"-event ?event-name?\");\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tstruct target_event_action *teap;\n\n\t\t\t\tteap = target->event_action;\n\t\t\t\t/* replace existing? */\n\t\t\t\twhile (teap) {\n\t\t\t\t\tif (teap->event == (enum target_event)n->value)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tteap = teap->next;\n\t\t\t\t}\n\n\t\t\t\tif (goi->isconfigure) {\n\t\t\t\t\t/* START_DEPRECATED_TPIU */\n\t\t\t\t\tif (n->value == TARGET_EVENT_TRACE_CONFIG)\n\t\t\t\t\t\tLOG_INFO(\"DEPRECATED target event %s; use TPIU events {pre,post}-{enable,disable}\", n->name);\n\t\t\t\t\t/* END_DEPRECATED_TPIU */\n\n\t\t\t\t\tbool replace = true;\n\t\t\t\t\tif (!teap) {\n\t\t\t\t\t\t/* create new */\n\t\t\t\t\t\tteap = calloc(1, sizeof(*teap));\n\t\t\t\t\t\treplace = false;\n\t\t\t\t\t}\n\t\t\t\t\tteap->event = n->value;\n\t\t\t\t\tteap->interp = goi->interp;\n\t\t\t\t\tjim_getopt_obj(goi, &o);\n\t\t\t\t\tif (teap->body)\n\t\t\t\t\t\tJim_DecrRefCount(teap->interp, teap->body);\n\t\t\t\t\tteap->body  = Jim_DuplicateObj(goi->interp, o);\n\t\t\t\t\t/*\n\t\t\t\t\t * FIXME:\n\t\t\t\t\t *     Tcl/TK - \"tk events\" have a nice feature.\n\t\t\t\t\t *     See the \"BIND\" command.\n\t\t\t\t\t *    We should support that here.\n\t\t\t\t\t *     You can specify %X and %Y in the event code.\n\t\t\t\t\t *     The idea is: %T - target name.\n\t\t\t\t\t *     The idea is: %N - target number\n\t\t\t\t\t *     The idea is: %E - event name.\n\t\t\t\t\t */\n\t\t\t\t\tJim_IncrRefCount(teap->body);\n\n\t\t\t\t\tif (!replace) {\n\t\t\t\t\t\t/* add to head of event list */\n\t\t\t\t\t\tteap->next = target->event_action;\n\t\t\t\t\t\ttarget->event_action = teap;\n\t\t\t\t\t}\n\t\t\t\t\tJim_SetEmptyResult(goi->interp);\n\t\t\t\t} else {\n\t\t\t\t\t/* get */\n\t\t\t\t\tif (!teap)\n\t\t\t\t\t\tJim_SetEmptyResult(goi->interp);\n\t\t\t\t\telse\n\t\t\t\t\t\tJim_SetResult(goi->interp, Jim_DuplicateObj(goi->interp, teap->body));\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_WORK_AREA_VIRT:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->working_area_virt = w;\n\t\t\t\ttarget->working_area_virt_spec = true;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt));\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_WORK_AREA_PHYS:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->working_area_phys = w;\n\t\t\t\ttarget->working_area_phys_spec = true;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys));\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_WORK_AREA_SIZE:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->working_area_size = w;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_WORK_AREA_BACKUP:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\t/* make this exactly 1 or 0 */\n\t\t\t\ttarget->backup_working_area = (!!w);\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area));\n\t\t\t/* loop for more e*/\n\t\t\tbreak;\n\n\n\t\tcase TCFG_ENDIAN:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\te = jim_getopt_nvp(goi, nvp_target_endian, &n);\n\t\t\t\tif (e != JIM_OK) {\n\t\t\t\t\tjim_getopt_nvp_unknown(goi, nvp_target_endian, 1);\n\t\t\t\t\treturn e;\n\t\t\t\t}\n\t\t\t\ttarget->endianness = n->value;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tn = jim_nvp_value2name_simple(nvp_target_endian, target->endianness);\n\t\t\tif (!n->name) {\n\t\t\t\ttarget->endianness = TARGET_LITTLE_ENDIAN;\n\t\t\t\tn = jim_nvp_value2name_simple(nvp_target_endian, target->endianness);\n\t\t\t}\n\t\t\tJim_SetResultString(goi->interp, n->name, -1);\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_COREID:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->coreid = (int32_t)w;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->coreid));\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_CHAIN_POSITION:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tJim_Obj *o_t;\n\t\t\t\tstruct jtag_tap *tap;\n\n\t\t\t\tif (target->has_dap) {\n\t\t\t\t\tJim_SetResultString(goi->interp,\n\t\t\t\t\t\t\"target requires -dap parameter instead of -chain-position!\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\n\t\t\t\ttarget_free_all_working_areas(target);\n\t\t\t\te = jim_getopt_obj(goi, &o_t);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttap = jtag_tap_by_jim_obj(goi->interp, o_t);\n\t\t\t\tif (!tap)\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\ttarget->tap = tap;\n\t\t\t\ttarget->tap_configured = true;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResultString(goi->interp, target->tap->dotted_name, -1);\n\t\t\t/* loop for more e*/\n\t\t\tbreak;\n\t\tcase TCFG_DBGBASE:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->dbgbase = (uint32_t)w;\n\t\t\t\ttarget->dbgbase_set = true;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\t\tcase TCFG_RTOS:\n\t\t\t/* RTOS */\n\t\t\t{\n\t\t\t\tint result = rtos_create(goi, target);\n\t\t\t\tif (result != JIM_OK)\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_DEFER_EXAMINE:\n\t\t\t/* DEFER_EXAMINE */\n\t\t\ttarget->defer_examine = true;\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_GDB_PORT:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tstruct command_context *cmd_ctx = current_command_context(goi->interp);\n\t\t\t\tif (cmd_ctx->mode != COMMAND_CONFIG) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"-gdb-port must be configured before 'init'\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\n\t\t\t\tconst char *s;\n\t\t\t\te = jim_getopt_string(goi, &s, NULL);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\tfree(target->gdb_port_override);\n\t\t\t\ttarget->gdb_port_override = strdup(s);\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResultString(goi->interp, target->gdb_port_override ? target->gdb_port_override : \"undefined\", -1);\n\t\t\t/* loop for more */\n\t\t\tbreak;\n\n\t\tcase TCFG_GDB_MAX_CONNECTIONS:\n\t\t\tif (goi->isconfigure) {\n\t\t\t\tstruct command_context *cmd_ctx = current_command_context(goi->interp);\n\t\t\t\tif (cmd_ctx->mode != COMMAND_CONFIG) {\n\t\t\t\t\tJim_SetResultString(goi->interp, \"-gdb-max-connections must be configured before 'init'\", -1);\n\t\t\t\t\treturn JIM_ERR;\n\t\t\t\t}\n\n\t\t\t\te = jim_getopt_wide(goi, &w);\n\t\t\t\tif (e != JIM_OK)\n\t\t\t\t\treturn e;\n\t\t\t\ttarget->gdb_max_connections = (w < 0) ? CONNECTION_LIMIT_UNLIMITED : (int)w;\n\t\t\t} else {\n\t\t\t\tif (goi->argc != 0)\n\t\t\t\t\tgoto no_params;\n\t\t\t}\n\t\t\tJim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->gdb_max_connections));\n\t\t\tbreak;\n\t\t}\n\t} /* while (goi->argc) */\n\n\n\t\t/* done - we return */\n\treturn JIM_OK;\n}\n\nstatic int jim_target_configure(Jim_Interp *interp, int argc, Jim_Obj * const *argv)\n{\n\tstruct command *c = jim_to_command(interp);\n\tstruct jim_getopt_info goi;\n\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tgoi.isconfigure = !strcmp(c->name, \"configure\");\n\tif (goi.argc < 1) {\n\t\tJim_WrongNumArgs(goi.interp, goi.argc, goi.argv,\n\t\t\t\t \"missing: -option ...\");\n\t\treturn JIM_ERR;\n\t}\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\tstruct target *target = get_current_target(cmd_ctx);\n\treturn target_configure(&goi, target);\n}\n\nstatic int jim_target_mem2array(Jim_Interp *interp,\n\t\tint argc, Jim_Obj *const *argv)\n{\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\tstruct target *target = get_current_target(cmd_ctx);\n\treturn target_mem2array(interp, target, argc - 1, argv + 1);\n}\n\nstatic int jim_target_array2mem(Jim_Interp *interp,\n\t\tint argc, Jim_Obj *const *argv)\n{\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\tstruct target *target = get_current_target(cmd_ctx);\n\treturn target_array2mem(interp, target, argc - 1, argv + 1);\n}\n\nCOMMAND_HANDLER(handle_target_examine)\n{\n\tbool allow_defer = false;\n\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 1) {\n\t\tif (strcmp(CMD_ARGV[0], \"allow-defer\"))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tallow_defer = true;\n\t}\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target->tap->enabled) {\n\t\tcommand_print(CMD, \"[TAP is disabled]\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (allow_defer && target->defer_examine) {\n\t\tLOG_INFO(\"Deferring arp_examine of %s\", target_name(target));\n\t\tLOG_INFO(\"Use arp_examine command to examine it manually!\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint retval = target->type->examine(target);\n\tif (retval != ERROR_OK) {\n\t\ttarget_reset_examined(target);\n\t\treturn retval;\n\t}\n\n\ttarget_set_examined(target);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_was_examined)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tcommand_print(CMD, \"%d\", target_was_examined(target) ? 1 : 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_examine_deferred)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tcommand_print(CMD, \"%d\", target->defer_examine ? 1 : 0);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_halt_gdb)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\treturn target_call_event_callbacks(target, TARGET_EVENT_GDB_HALT);\n}\n\nCOMMAND_HANDLER(handle_target_poll)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target->tap->enabled) {\n\t\tcommand_print(CMD, \"[TAP is disabled]\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!(target_was_examined(target)))\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\n\treturn target->type->poll(target);\n}\n\nCOMMAND_HANDLER(handle_target_reset)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst struct nvp *n = nvp_name2value(nvp_assert, CMD_ARGV[0]);\n\tif (!n->name) {\n\t\tnvp_unknown_command_print(CMD, nvp_assert, NULL, CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* the halt or not param */\n\tint a;\n\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], a);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target->tap->enabled) {\n\t\tcommand_print(CMD, \"[TAP is disabled]\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (!target->type->assert_reset || !target->type->deassert_reset) {\n\t\tcommand_print(CMD, \"No target-specific reset for %s\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (target->defer_examine)\n\t\ttarget_reset_examined(target);\n\n\t/* determine if we should halt or not. */\n\ttarget->reset_halt = (a != 0);\n\t/* When this happens - all workareas are invalid. */\n\ttarget_free_all_working_areas_restore(target, 0);\n\n\t/* do the assert */\n\tif (n->value == NVP_ASSERT)\n\t\treturn target->type->assert_reset(target);\n\treturn target->type->deassert_reset(target);\n}\n\nCOMMAND_HANDLER(handle_target_halt)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target->tap->enabled) {\n\t\tcommand_print(CMD, \"[TAP is disabled]\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn target->type->halt(target);\n}\n\nCOMMAND_HANDLER(handle_target_wait_state)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst struct nvp *n = nvp_name2value(nvp_target_state, CMD_ARGV[0]);\n\tif (!n->name) {\n\t\tnvp_unknown_command_print(CMD, nvp_target_state, NULL, CMD_ARGV[0]);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tunsigned int a;\n\tCOMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], a);\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\tif (!target->tap->enabled) {\n\t\tcommand_print(CMD, \"[TAP is disabled]\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint retval = target_wait_state(target, n->value, a);\n\tif (retval != ERROR_OK) {\n\t\tcommand_print(CMD,\n\t\t\t\t\"target: %s wait %s fails (%d) %s\",\n\t\t\t\ttarget_name(target), n->name,\n\t\t\t\tretval, target_strerror_safe(retval));\n\t\treturn retval;\n\t}\n\treturn ERROR_OK;\n}\n/* List for human, Events defined for this target.\n * scripts/programs should use 'name cget -event NAME'\n */\nCOMMAND_HANDLER(handle_target_event_list)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct target_event_action *teap = target->event_action;\n\n\tcommand_print(CMD, \"Event actions for target (%d) %s\\n\",\n\t\t\t\t   target->target_number,\n\t\t\t\t   target_name(target));\n\tcommand_print(CMD, \"%-25s | Body\", \"Event\");\n\tcommand_print(CMD, \"------------------------- | \"\n\t\t\t\"----------------------------------------\");\n\twhile (teap) {\n\t\tcommand_print(CMD, \"%-25s | %s\",\n\t\t\t\ttarget_event_name(teap->event),\n\t\t\t\tJim_GetString(teap->body, NULL));\n\t\tteap = teap->next;\n\t}\n\tcommand_print(CMD, \"***END***\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_current_state)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tcommand_print(CMD, \"%s\", target_state_name(target));\n\n\treturn ERROR_OK;\n}\n\nstatic int jim_target_invoke_event(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tif (goi.argc != 1) {\n\t\tconst char *cmd_name = Jim_GetString(argv[0], NULL);\n\t\tJim_SetResultFormatted(goi.interp, \"%s <eventname>\", cmd_name);\n\t\treturn JIM_ERR;\n\t}\n\tstruct jim_nvp *n;\n\tint e = jim_getopt_nvp(&goi, nvp_target_event, &n);\n\tif (e != JIM_OK) {\n\t\tjim_getopt_nvp_unknown(&goi, nvp_target_event, 1);\n\t\treturn e;\n\t}\n\tstruct command_context *cmd_ctx = current_command_context(interp);\n\tassert(cmd_ctx);\n\tstruct target *target = get_current_target(cmd_ctx);\n\ttarget_handle_event(target, n->value);\n\treturn JIM_OK;\n}\n\nstatic const struct command_registration target_instance_command_handlers[] = {\n\t{\n\t\t.name = \"configure\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_target_configure,\n\t\t.help  = \"configure a new target for use\",\n\t\t.usage = \"[target_attribute ...]\",\n\t},\n\t{\n\t\t.name = \"cget\",\n\t\t.mode = COMMAND_ANY,\n\t\t.jim_handler = jim_target_configure,\n\t\t.help  = \"returns the specified target attribute\",\n\t\t.usage = \"target_attribute\",\n\t},\n\t{\n\t\t.name = \"mwd\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Write 64-bit word(s) to target memory\",\n\t\t.usage = \"address data [count]\",\n\t},\n\t{\n\t\t.name = \"mww\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Write 32-bit word(s) to target memory\",\n\t\t.usage = \"address data [count]\",\n\t},\n\t{\n\t\t.name = \"mwh\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Write 16-bit half-word(s) to target memory\",\n\t\t.usage = \"address data [count]\",\n\t},\n\t{\n\t\t.name = \"mwb\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Write byte(s) to target memory\",\n\t\t.usage = \"address data [count]\",\n\t},\n\t{\n\t\t.name = \"mdd\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Display target memory as 64-bit words\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"mdw\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Display target memory as 32-bit words\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"mdh\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Display target memory as 16-bit half-words\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"mdb\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Display target memory as 8-bit bytes\",\n\t\t.usage = \"address [count]\",\n\t},\n\t{\n\t\t.name = \"array2mem\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = jim_target_array2mem,\n\t\t.help = \"Writes Tcl array of 8/16/32 bit numbers \"\n\t\t\t\"to target memory\",\n\t\t.usage = \"arrayname bitwidth address count\",\n\t},\n\t{\n\t\t.name = \"mem2array\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = jim_target_mem2array,\n\t\t.help = \"Loads Tcl array of 8/16/32 bit numbers \"\n\t\t\t\"from target memory\",\n\t\t.usage = \"arrayname bitwidth address count\",\n\t},\n\t{\n\t\t.name = \"get_reg\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_get_reg,\n\t\t.help = \"Get register values from the target\",\n\t\t.usage = \"list\",\n\t},\n\t{\n\t\t.name = \"set_reg\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_set_reg,\n\t\t.help = \"Set target register values\",\n\t\t.usage = \"dict\",\n\t},\n\t{\n\t\t.name = \"read_memory\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_read_memory,\n\t\t.help = \"Read Tcl list of 8/16/32/64 bit numbers from target memory\",\n\t\t.usage = \"address width count ['phys']\",\n\t},\n\t{\n\t\t.name = \"write_memory\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_write_memory,\n\t\t.help = \"Write Tcl list of 8/16/32/64 bit numbers to target memory\",\n\t\t.usage = \"address width data ['phys']\",\n\t},\n\t{\n\t\t.name = \"eventlist\",\n\t\t.handler = handle_target_event_list,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"displays a table of events defined for this target\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"curstate\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_current_state,\n\t\t.help = \"displays the current state of this target\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_examine\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_examine,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"['allow-defer']\",\n\t},\n\t{\n\t\t.name = \"was_examined\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_was_examined,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"examine_deferred\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_examine_deferred,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_halt_gdb\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_halt_gdb,\n\t\t.help = \"used internally for reset processing to halt GDB\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_poll\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_poll,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_reset\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_reset,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"'assert'|'deassert' halt\",\n\t},\n\t{\n\t\t.name = \"arp_halt\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_halt,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"arp_waitstate\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_wait_state,\n\t\t.help = \"used internally for reset processing\",\n\t\t.usage = \"statename timeoutmsecs\",\n\t},\n\t{\n\t\t.name = \"invoke-event\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = jim_target_invoke_event,\n\t\t.help = \"invoke handler for specified event\",\n\t\t.usage = \"event_name\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int target_create(struct jim_getopt_info *goi)\n{\n\tJim_Obj *new_cmd;\n\tJim_Cmd *cmd;\n\tconst char *cp;\n\tint e;\n\tint x;\n\tstruct target *target;\n\tstruct command_context *cmd_ctx;\n\n\tcmd_ctx = current_command_context(goi->interp);\n\tassert(cmd_ctx);\n\n\tif (goi->argc < 3) {\n\t\tJim_WrongNumArgs(goi->interp, 1, goi->argv, \"?name? ?type? ..options...\");\n\t\treturn JIM_ERR;\n\t}\n\n\t/* COMMAND */\n\tjim_getopt_obj(goi, &new_cmd);\n\t/* does this command exist? */\n\tcmd = Jim_GetCommand(goi->interp, new_cmd, JIM_NONE);\n\tif (cmd) {\n\t\tcp = Jim_GetString(new_cmd, NULL);\n\t\tJim_SetResultFormatted(goi->interp, \"Command/target: %s Exists\", cp);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* TYPE */\n\te = jim_getopt_string(goi, &cp, NULL);\n\tif (e != JIM_OK)\n\t\treturn e;\n\tstruct transport *tr = get_current_transport();\n\tif (tr->override_target) {\n\t\te = tr->override_target(&cp);\n\t\tif (e != ERROR_OK) {\n\t\t\tLOG_ERROR(\"The selected transport doesn't support this target\");\n\t\t\treturn JIM_ERR;\n\t\t}\n\t\tLOG_INFO(\"The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD\");\n\t}\n\t/* now does target type exist */\n\tfor (x = 0 ; target_types[x] ; x++) {\n\t\tif (strcmp(cp, target_types[x]->name) == 0) {\n\t\t\t/* found */\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (!target_types[x]) {\n\t\tJim_SetResultFormatted(goi->interp, \"Unknown target type %s, try one of \", cp);\n\t\tfor (x = 0 ; target_types[x] ; x++) {\n\t\t\tif (target_types[x + 1]) {\n\t\t\t\tJim_AppendStrings(goi->interp,\n\t\t\t\t\t\t\t\t   Jim_GetResult(goi->interp),\n\t\t\t\t\t\t\t\t   target_types[x]->name,\n\t\t\t\t\t\t\t\t   \", \", NULL);\n\t\t\t} else {\n\t\t\t\tJim_AppendStrings(goi->interp,\n\t\t\t\t\t\t\t\t   Jim_GetResult(goi->interp),\n\t\t\t\t\t\t\t\t   \" or \",\n\t\t\t\t\t\t\t\t   target_types[x]->name, NULL);\n\t\t\t}\n\t\t}\n\t\treturn JIM_ERR;\n\t}\n\n\t/* Create it */\n\ttarget = calloc(1, sizeof(struct target));\n\tif (!target) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn JIM_ERR;\n\t}\n\n\t/* set empty smp cluster */\n\ttarget->smp_targets = &empty_smp_targets;\n\n\t/* set target number */\n\ttarget->target_number = new_target_number();\n\n\t/* allocate memory for each unique target type */\n\ttarget->type = malloc(sizeof(struct target_type));\n\tif (!target->type) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(target);\n\t\treturn JIM_ERR;\n\t}\n\n\tmemcpy(target->type, target_types[x], sizeof(struct target_type));\n\n\t/* default to first core, override with -coreid */\n\ttarget->coreid = 0;\n\n\ttarget->working_area        = 0x0;\n\ttarget->working_area_size   = 0x0;\n\ttarget->working_areas       = NULL;\n\ttarget->backup_working_area = 0;\n\n\ttarget->state               = TARGET_UNKNOWN;\n\ttarget->debug_reason        = DBG_REASON_UNDEFINED;\n\ttarget->reg_cache           = NULL;\n\ttarget->breakpoints         = NULL;\n\ttarget->watchpoints         = NULL;\n\ttarget->next                = NULL;\n\ttarget->arch_info           = NULL;\n\n\ttarget->verbose_halt_msg\t= true;\n\n\ttarget->halt_issued\t\t\t= false;\n\n\t/* initialize trace information */\n\ttarget->trace_info = calloc(1, sizeof(struct trace));\n\tif (!target->trace_info) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\tfree(target->type);\n\t\tfree(target);\n\t\treturn JIM_ERR;\n\t}\n\n\ttarget->dbgmsg          = NULL;\n\ttarget->dbg_msg_enabled = 0;\n\n\ttarget->endianness = TARGET_ENDIAN_UNKNOWN;\n\n\ttarget->rtos = NULL;\n\ttarget->rtos_auto_detect = false;\n\n\ttarget->gdb_port_override = NULL;\n\ttarget->gdb_max_connections = 1;\n\n\t/* Do the rest as \"configure\" options */\n\tgoi->isconfigure = 1;\n\te = target_configure(goi, target);\n\n\tif (e == JIM_OK) {\n\t\tif (target->has_dap) {\n\t\t\tif (!target->dap_configured) {\n\t\t\t\tJim_SetResultString(goi->interp, \"-dap ?name? required when creating target\", -1);\n\t\t\t\te = JIM_ERR;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!target->tap_configured) {\n\t\t\t\tJim_SetResultString(goi->interp, \"-chain-position ?name? required when creating target\", -1);\n\t\t\t\te = JIM_ERR;\n\t\t\t}\n\t\t}\n\t\t/* tap must be set after target was configured */\n\t\tif (!target->tap)\n\t\t\te = JIM_ERR;\n\t}\n\n\tif (e != JIM_OK) {\n\t\trtos_destroy(target);\n\t\tfree(target->gdb_port_override);\n\t\tfree(target->trace_info);\n\t\tfree(target->type);\n\t\tfree(target);\n\t\treturn e;\n\t}\n\n\tif (target->endianness == TARGET_ENDIAN_UNKNOWN) {\n\t\t/* default endian to little if not specified */\n\t\ttarget->endianness = TARGET_LITTLE_ENDIAN;\n\t}\n\n\tcp = Jim_GetString(new_cmd, NULL);\n\ttarget->cmd_name = strdup(cp);\n\tif (!target->cmd_name) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\trtos_destroy(target);\n\t\tfree(target->gdb_port_override);\n\t\tfree(target->trace_info);\n\t\tfree(target->type);\n\t\tfree(target);\n\t\treturn JIM_ERR;\n\t}\n\n\tif (target->type->target_create) {\n\t\te = (*(target->type->target_create))(target, goi->interp);\n\t\tif (e != ERROR_OK) {\n\t\t\tLOG_DEBUG(\"target_create failed\");\n\t\t\tfree(target->cmd_name);\n\t\t\trtos_destroy(target);\n\t\t\tfree(target->gdb_port_override);\n\t\t\tfree(target->trace_info);\n\t\t\tfree(target->type);\n\t\t\tfree(target);\n\t\t\treturn JIM_ERR;\n\t\t}\n\t}\n\n\t/* create the target specific commands */\n\tif (target->type->commands) {\n\t\te = register_commands(cmd_ctx, NULL, target->type->commands);\n\t\tif (e != ERROR_OK)\n\t\t\tLOG_ERROR(\"unable to register '%s' commands\", cp);\n\t}\n\n\t/* now - create the new target name command */\n\tconst struct command_registration target_subcommands[] = {\n\t\t{\n\t\t\t.chain = target_instance_command_handlers,\n\t\t},\n\t\t{\n\t\t\t.chain = target->type->commands,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\tconst struct command_registration target_commands[] = {\n\t\t{\n\t\t\t.name = cp,\n\t\t\t.mode = COMMAND_ANY,\n\t\t\t.help = \"target command group\",\n\t\t\t.usage = \"\",\n\t\t\t.chain = target_subcommands,\n\t\t},\n\t\tCOMMAND_REGISTRATION_DONE\n\t};\n\te = register_commands_override_target(cmd_ctx, NULL, target_commands, target);\n\tif (e != ERROR_OK) {\n\t\tif (target->type->deinit_target)\n\t\t\ttarget->type->deinit_target(target);\n\t\tfree(target->cmd_name);\n\t\trtos_destroy(target);\n\t\tfree(target->gdb_port_override);\n\t\tfree(target->trace_info);\n\t\tfree(target->type);\n\t\tfree(target);\n\t\treturn JIM_ERR;\n\t}\n\n\t/* append to end of list */\n\tappend_to_list_all_targets(target);\n\n\tcmd_ctx->current_target = target;\n\treturn JIM_OK;\n}\n\nCOMMAND_HANDLER(handle_target_current)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = get_current_target_or_null(CMD_CTX);\n\tif (target)\n\t\tcommand_print(CMD, \"%s\", target_name(target));\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_types)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tfor (unsigned int x = 0; target_types[x]; x++)\n\t\tcommand_print(CMD, \"%s\", target_types[x]->name);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_names)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct target *target = all_targets;\n\twhile (target) {\n\t\tcommand_print(CMD, \"%s\", target_name(target));\n\t\ttarget = target->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic struct target_list *\n__attribute__((warn_unused_result))\ncreate_target_list_node(const char *targetname)\n{\n\tstruct target *target = get_target(targetname);\n\tLOG_DEBUG(\"%s \", targetname);\n\tif (!target)\n\t\treturn NULL;\n\n\tstruct target_list *new = malloc(sizeof(struct target_list));\n\tif (!new) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn new;\n\t}\n\n\tnew->target = target;\n\treturn new;\n}\n\nstatic int get_target_with_common_rtos_type(struct command_invocation *cmd,\n\tstruct list_head *lh, struct target **result)\n{\n\tstruct target *target = NULL;\n\tstruct target_list *curr;\n\tforeach_smp_target(curr, lh) {\n\t\tstruct rtos *curr_rtos = curr->target->rtos;\n\t\tif (curr_rtos) {\n\t\t\tif (target && target->rtos && target->rtos->type != curr_rtos->type) {\n\t\t\t\tcommand_print(cmd, \"Different rtos types in members of one smp target!\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\ttarget = curr->target;\n\t\t}\n\t}\n\t*result = target;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_smp)\n{\n\tstatic int smp_group = 1;\n\n\tif (CMD_ARGC == 0) {\n\t\tLOG_DEBUG(\"Empty SMP target\");\n\t\treturn ERROR_OK;\n\t}\n\tLOG_DEBUG(\"%d\", CMD_ARGC);\n\t/* CMD_ARGC[0] = target to associate in smp\n\t * CMD_ARGC[1] = target to associate in smp\n\t * CMD_ARGC[2] ...\n\t */\n\n\tstruct list_head *lh = malloc(sizeof(*lh));\n\tif (!lh) {\n\t\tLOG_ERROR(\"Out of memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tINIT_LIST_HEAD(lh);\n\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tstruct target_list *new = create_target_list_node(CMD_ARGV[i]);\n\t\tif (new)\n\t\t\tlist_add_tail(&new->lh, lh);\n\t}\n\t/*  now parse the list of cpu and put the target in smp mode*/\n\tstruct target_list *curr;\n\tforeach_smp_target(curr, lh) {\n\t\tstruct target *target = curr->target;\n\t\ttarget->smp = smp_group;\n\t\ttarget->smp_targets = lh;\n\t}\n\tsmp_group++;\n\n\tstruct target *rtos_target;\n\tint retval = get_target_with_common_rtos_type(CMD, lh, &rtos_target);\n\tif (retval == ERROR_OK && rtos_target)\n\t\tretval = rtos_smp_init(rtos_target);\n\n\treturn retval;\n}\n\nstatic int jim_target_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)\n{\n\tstruct jim_getopt_info goi;\n\tjim_getopt_setup(&goi, interp, argc - 1, argv + 1);\n\tif (goi.argc < 3) {\n\t\tJim_WrongNumArgs(goi.interp, goi.argc, goi.argv,\n\t\t\t\"<name> <target_type> [<target_options> ...]\");\n\t\treturn JIM_ERR;\n\t}\n\treturn target_create(&goi);\n}\n\nstatic const struct command_registration target_subcommand_handlers[] = {\n\t{\n\t\t.name = \"init\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.handler = handle_target_init_command,\n\t\t.help = \"initialize targets\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"create\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.jim_handler = jim_target_create,\n\t\t.usage = \"name type '-chain-position' name [options ...]\",\n\t\t.help = \"Creates and selects a new target\",\n\t},\n\t{\n\t\t.name = \"current\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_target_current,\n\t\t.help = \"Returns the currently selected target\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"types\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_target_types,\n\t\t.help = \"Returns the available target types as \"\n\t\t\t\t\"a list of strings\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"names\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_target_names,\n\t\t.help = \"Returns the names of all targets as a list of strings\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"smp\",\n\t\t.mode = COMMAND_ANY,\n\t\t.handler = handle_target_smp,\n\t\t.usage = \"targetname1 targetname2 ...\",\n\t\t.help = \"gather several target in a smp list\"\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct fast_load {\n\ttarget_addr_t address;\n\tuint8_t *data;\n\tint length;\n\n};\n\nstatic int fastload_num;\nstatic struct fast_load *fastload;\n\nstatic void free_fastload(void)\n{\n\tif (fastload) {\n\t\tfor (int i = 0; i < fastload_num; i++)\n\t\t\tfree(fastload[i].data);\n\t\tfree(fastload);\n\t\tfastload = NULL;\n\t}\n}\n\nCOMMAND_HANDLER(handle_fast_load_image_command)\n{\n\tuint8_t *buffer;\n\tsize_t buf_cnt;\n\tuint32_t image_size;\n\ttarget_addr_t min_address = 0;\n\ttarget_addr_t max_address = -1;\n\n\tstruct image image;\n\n\tint retval = CALL_COMMAND_HANDLER(parse_load_image_command,\n\t\t\t&image, &min_address, &max_address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tstruct duration bench;\n\tduration_start(&bench);\n\n\tretval = image_open(&image, CMD_ARGV[0], (CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\timage_size = 0x0;\n\tretval = ERROR_OK;\n\tfastload_num = image.num_sections;\n\tfastload = malloc(sizeof(struct fast_load)*image.num_sections);\n\tif (!fastload) {\n\t\tcommand_print(CMD, \"out of memory\");\n\t\timage_close(&image);\n\t\treturn ERROR_FAIL;\n\t}\n\tmemset(fastload, 0, sizeof(struct fast_load)*image.num_sections);\n\tfor (unsigned int i = 0; i < image.num_sections; i++) {\n\t\tbuffer = malloc(image.sections[i].size);\n\t\tif (!buffer) {\n\t\t\tcommand_print(CMD, \"error allocating buffer for section (%d bytes)\",\n\t\t\t\t\t\t  (int)(image.sections[i].size));\n\t\t\tretval = ERROR_FAIL;\n\t\t\tbreak;\n\t\t}\n\n\t\tretval = image_read_section(&image, i, 0x0, image.sections[i].size, buffer, &buf_cnt);\n\t\tif (retval != ERROR_OK) {\n\t\t\tfree(buffer);\n\t\t\tbreak;\n\t\t}\n\n\t\tuint32_t offset = 0;\n\t\tuint32_t length = buf_cnt;\n\n\t\t/* DANGER!!! beware of unsigned comparison here!!! */\n\n\t\tif ((image.sections[i].base_address + buf_cnt >= min_address) &&\n\t\t\t\t(image.sections[i].base_address < max_address)) {\n\t\t\tif (image.sections[i].base_address < min_address) {\n\t\t\t\t/* clip addresses below */\n\t\t\t\toffset += min_address-image.sections[i].base_address;\n\t\t\t\tlength -= offset;\n\t\t\t}\n\n\t\t\tif (image.sections[i].base_address + buf_cnt > max_address)\n\t\t\t\tlength -= (image.sections[i].base_address + buf_cnt)-max_address;\n\n\t\t\tfastload[i].address = image.sections[i].base_address + offset;\n\t\t\tfastload[i].data = malloc(length);\n\t\t\tif (!fastload[i].data) {\n\t\t\t\tfree(buffer);\n\t\t\t\tcommand_print(CMD, \"error allocating buffer for section (%\" PRIu32 \" bytes)\",\n\t\t\t\t\t\t\t  length);\n\t\t\t\tretval = ERROR_FAIL;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmemcpy(fastload[i].data, buffer + offset, length);\n\t\t\tfastload[i].length = length;\n\n\t\t\timage_size += length;\n\t\t\tcommand_print(CMD, \"%u bytes written at address 0x%8.8x\",\n\t\t\t\t\t\t  (unsigned int)length,\n\t\t\t\t\t\t  ((unsigned int)(image.sections[i].base_address + offset)));\n\t\t}\n\n\t\tfree(buffer);\n\t}\n\n\tif ((retval == ERROR_OK) && (duration_measure(&bench) == ERROR_OK)) {\n\t\tcommand_print(CMD, \"Loaded %\" PRIu32 \" bytes \"\n\t\t\t\t\"in %fs (%0.3f KiB/s)\", image_size,\n\t\t\t\tduration_elapsed(&bench), duration_kbps(&bench, image_size));\n\n\t\tcommand_print(CMD,\n\t\t\t\t\"WARNING: image has not been loaded to target!\"\n\t\t\t\t\"You can issue a 'fast_load' to finish loading.\");\n\t}\n\n\timage_close(&image);\n\n\tif (retval != ERROR_OK)\n\t\tfree_fastload();\n\n\treturn retval;\n}\n\nCOMMAND_HANDLER(handle_fast_load_command)\n{\n\tif (CMD_ARGC > 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (!fastload) {\n\t\tLOG_ERROR(\"No image in memory\");\n\t\treturn ERROR_FAIL;\n\t}\n\tint i;\n\tint64_t ms = timeval_ms();\n\tint size = 0;\n\tint retval = ERROR_OK;\n\tfor (i = 0; i < fastload_num; i++) {\n\t\tstruct target *target = get_current_target(CMD_CTX);\n\t\tcommand_print(CMD, \"Write to 0x%08x, length 0x%08x\",\n\t\t\t\t\t  (unsigned int)(fastload[i].address),\n\t\t\t\t\t  (unsigned int)(fastload[i].length));\n\t\tretval = target_write_buffer(target, fastload[i].address, fastload[i].length, fastload[i].data);\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t\tsize += fastload[i].length;\n\t}\n\tif (retval == ERROR_OK) {\n\t\tint64_t after = timeval_ms();\n\t\tcommand_print(CMD, \"Loaded image %f kBytes/s\", (float)(size/1024.0)/((float)(after-ms)/1000.0));\n\t}\n\treturn retval;\n}\n\nstatic const struct command_registration target_command_handlers[] = {\n\t{\n\t\t.name = \"targets\",\n\t\t.handler = handle_targets_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"change current default target (one parameter) \"\n\t\t\t\"or prints table of all targets (no parameters)\",\n\t\t.usage = \"[target]\",\n\t},\n\t{\n\t\t.name = \"target\",\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"configure target\",\n\t\t.chain = target_subcommand_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint target_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, target_command_handlers);\n}\n\nstatic bool target_reset_nag = true;\n\nbool get_target_reset_nag(void)\n{\n\treturn target_reset_nag;\n}\n\nCOMMAND_HANDLER(handle_target_reset_nag)\n{\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t\t&target_reset_nag, \"Nag after each reset about options to improve \"\n\t\t\t\"performance\");\n}\n\nCOMMAND_HANDLER(handle_ps_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tchar *display;\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_INFO(\"target not halted !!\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif ((target->rtos) && (target->rtos->type)\n\t\t\t&& (target->rtos->type->ps_command)) {\n\t\tdisplay = target->rtos->type->ps_command(target);\n\t\tcommand_print(CMD, \"%s\", display);\n\t\tfree(display);\n\t\treturn ERROR_OK;\n\t} else {\n\t\tLOG_INFO(\"failed\");\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n}\n\nstatic void binprint(struct command_invocation *cmd, const char *text, const uint8_t *buf, int size)\n{\n\tif (text)\n\t\tcommand_print_sameline(cmd, \"%s\", text);\n\tfor (int i = 0; i < size; i++)\n\t\tcommand_print_sameline(cmd, \" %02x\", buf[i]);\n\tcommand_print(cmd, \" \");\n}\n\nCOMMAND_HANDLER(handle_test_mem_access_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tuint32_t test_size;\n\tint retval = ERROR_OK;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_INFO(\"target not halted !!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], test_size);\n\n\t/* Test reads */\n\tsize_t num_bytes = test_size + 4;\n\n\tstruct working_area *wa = NULL;\n\tretval = target_alloc_working_area(target, num_bytes, &wa);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Not enough working area\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t *test_pattern = malloc(num_bytes);\n\n\tfor (size_t i = 0; i < num_bytes; i++)\n\t\ttest_pattern[i] = rand();\n\n\tretval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Test pattern write failed\");\n\t\tgoto out;\n\t}\n\n\tfor (int host_offset = 0; host_offset <= 1; host_offset++) {\n\t\tfor (int size = 1; size <= 4; size *= 2) {\n\t\t\tfor (int offset = 0; offset < 4; offset++) {\n\t\t\t\tuint32_t count = test_size / size;\n\t\t\t\tsize_t host_bufsiz = (count + 2) * size + host_offset;\n\t\t\t\tuint8_t *read_ref = malloc(host_bufsiz);\n\t\t\t\tuint8_t *read_buf = malloc(host_bufsiz);\n\n\t\t\t\tfor (size_t i = 0; i < host_bufsiz; i++) {\n\t\t\t\t\tread_ref[i] = rand();\n\t\t\t\t\tread_buf[i] = read_ref[i];\n\t\t\t\t}\n\t\t\t\tcommand_print_sameline(CMD,\n\t\t\t\t\t\t\"Test read %\" PRIu32 \" x %d @ %d to %saligned buffer: \", count,\n\t\t\t\t\t\tsize, offset, host_offset ? \"un\" : \"\");\n\n\t\t\t\tstruct duration bench;\n\t\t\t\tduration_start(&bench);\n\n\t\t\t\tretval = target_read_memory(target, wa->address + offset, size, count,\n\t\t\t\t\t\tread_buf + size + host_offset);\n\n\t\t\t\tduration_measure(&bench);\n\n\t\t\t\tif (retval == ERROR_TARGET_UNALIGNED_ACCESS) {\n\t\t\t\t\tcommand_print(CMD, \"Unsupported alignment\");\n\t\t\t\t\tgoto next;\n\t\t\t\t} else if (retval != ERROR_OK) {\n\t\t\t\t\tcommand_print(CMD, \"Memory read failed\");\n\t\t\t\t\tgoto next;\n\t\t\t\t}\n\n\t\t\t\t/* replay on host */\n\t\t\t\tmemcpy(read_ref + size + host_offset, test_pattern + offset, count * size);\n\n\t\t\t\t/* check result */\n\t\t\t\tint result = memcmp(read_ref, read_buf, host_bufsiz);\n\t\t\t\tif (result == 0) {\n\t\t\t\t\tcommand_print(CMD, \"Pass in %fs (%0.3f KiB/s)\",\n\t\t\t\t\t\t\tduration_elapsed(&bench),\n\t\t\t\t\t\t\tduration_kbps(&bench, count * size));\n\t\t\t\t} else {\n\t\t\t\t\tcommand_print(CMD, \"Compare failed\");\n\t\t\t\t\tbinprint(CMD, \"ref:\", read_ref, host_bufsiz);\n\t\t\t\t\tbinprint(CMD, \"buf:\", read_buf, host_bufsiz);\n\t\t\t\t}\nnext:\n\t\t\t\tfree(read_ref);\n\t\t\t\tfree(read_buf);\n\t\t\t}\n\t\t}\n\t}\n\nout:\n\tfree(test_pattern);\n\n\ttarget_free_working_area(target, wa);\n\n\t/* Test writes */\n\tnum_bytes = test_size + 4 + 4 + 4;\n\n\tretval = target_alloc_working_area(target, num_bytes, &wa);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Not enough working area\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\ttest_pattern = malloc(num_bytes);\n\n\tfor (size_t i = 0; i < num_bytes; i++)\n\t\ttest_pattern[i] = rand();\n\n\tfor (int host_offset = 0; host_offset <= 1; host_offset++) {\n\t\tfor (int size = 1; size <= 4; size *= 2) {\n\t\t\tfor (int offset = 0; offset < 4; offset++) {\n\t\t\t\tuint32_t count = test_size / size;\n\t\t\t\tsize_t host_bufsiz = count * size + host_offset;\n\t\t\t\tuint8_t *read_ref = malloc(num_bytes);\n\t\t\t\tuint8_t *read_buf = malloc(num_bytes);\n\t\t\t\tuint8_t *write_buf = malloc(host_bufsiz);\n\n\t\t\t\tfor (size_t i = 0; i < host_bufsiz; i++)\n\t\t\t\t\twrite_buf[i] = rand();\n\t\t\t\tcommand_print_sameline(CMD,\n\t\t\t\t\t\t\"Test write %\" PRIu32 \" x %d @ %d from %saligned buffer: \", count,\n\t\t\t\t\t\tsize, offset, host_offset ? \"un\" : \"\");\n\n\t\t\t\tretval = target_write_memory(target, wa->address, 1, num_bytes, test_pattern);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tcommand_print(CMD, \"Test pattern write failed\");\n\t\t\t\t\tgoto nextw;\n\t\t\t\t}\n\n\t\t\t\t/* replay on host */\n\t\t\t\tmemcpy(read_ref, test_pattern, num_bytes);\n\t\t\t\tmemcpy(read_ref + size + offset, write_buf + host_offset, count * size);\n\n\t\t\t\tstruct duration bench;\n\t\t\t\tduration_start(&bench);\n\n\t\t\t\tretval = target_write_memory(target, wa->address + size + offset, size, count,\n\t\t\t\t\t\twrite_buf + host_offset);\n\n\t\t\t\tduration_measure(&bench);\n\n\t\t\t\tif (retval == ERROR_TARGET_UNALIGNED_ACCESS) {\n\t\t\t\t\tcommand_print(CMD, \"Unsupported alignment\");\n\t\t\t\t\tgoto nextw;\n\t\t\t\t} else if (retval != ERROR_OK) {\n\t\t\t\t\tcommand_print(CMD, \"Memory write failed\");\n\t\t\t\t\tgoto nextw;\n\t\t\t\t}\n\n\t\t\t\t/* read back */\n\t\t\t\tretval = target_read_memory(target, wa->address, 1, num_bytes, read_buf);\n\t\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t\tcommand_print(CMD, \"Test pattern write failed\");\n\t\t\t\t\tgoto nextw;\n\t\t\t\t}\n\n\t\t\t\t/* check result */\n\t\t\t\tint result = memcmp(read_ref, read_buf, num_bytes);\n\t\t\t\tif (result == 0) {\n\t\t\t\t\tcommand_print(CMD, \"Pass in %fs (%0.3f KiB/s)\",\n\t\t\t\t\t\t\tduration_elapsed(&bench),\n\t\t\t\t\t\t\tduration_kbps(&bench, count * size));\n\t\t\t\t} else {\n\t\t\t\t\tcommand_print(CMD, \"Compare failed\");\n\t\t\t\t\tbinprint(CMD, \"ref:\", read_ref, num_bytes);\n\t\t\t\t\tbinprint(CMD, \"buf:\", read_buf, num_bytes);\n\t\t\t\t}\nnextw:\n\t\t\t\tfree(read_ref);\n\t\t\t\tfree(read_buf);\n\t\t\t}\n\t\t}\n\t}\n\n\tfree(test_pattern);\n\n\ttarget_free_working_area(target, wa);\n\treturn retval;\n}\n\nstatic const struct command_registration target_exec_command_handlers[] = {\n\t{\n\t\t.name = \"fast_load_image\",\n\t\t.handler = handle_fast_load_image_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Load image into server memory for later use by \"\n\t\t\t\"fast_load; primarily for profiling\",\n\t\t.usage = \"filename address ['bin'|'ihex'|'elf'|'s19'] \"\n\t\t\t\"[min_address [max_length]]\",\n\t},\n\t{\n\t\t.name = \"fast_load\",\n\t\t.handler = handle_fast_load_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"loads active fast load image to current target \"\n\t\t\t\"- mainly for profiling purposes\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"profile\",\n\t\t.handler = handle_profile_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"seconds filename [start end]\",\n\t\t.help = \"profiling samples the CPU PC\",\n\t},\n\t/** @todo don't register virt2phys() unless target supports it */\n\t{\n\t\t.name = \"virt2phys\",\n\t\t.handler = handle_virt2phys_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"translate a virtual address into a physical address\",\n\t\t.usage = \"virtual_address\",\n\t},\n\t{\n\t\t.name = \"reg\",\n\t\t.handler = handle_reg_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display (reread from target with \\\"force\\\") or set a register; \"\n\t\t\t\"with no arguments, displays all registers and their values\",\n\t\t.usage = \"[(register_number|register_name) [(value|'force')]]\",\n\t},\n\t{\n\t\t.name = \"poll\",\n\t\t.handler = handle_poll_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"poll target state; or reconfigure background polling\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.name = \"wait_halt\",\n\t\t.handler = handle_wait_halt_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"wait up to the specified number of milliseconds \"\n\t\t\t\"(default 5000) for a previously requested halt\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"halt\",\n\t\t.handler = handle_halt_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"request target to halt, then wait up to the specified \"\n\t\t\t\"number of milliseconds (default 5000) for it to complete\",\n\t\t.usage = \"[milliseconds]\",\n\t},\n\t{\n\t\t.name = \"resume\",\n\t\t.handler = handle_resume_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\t\"resume target execution from current PC or address\",\n\t\t.usage = \"[address]\",\n\t},\n\t{\n\t\t.name = \"reset\",\n\t\t.handler = handle_reset_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"[run|halt|init]\",\n\t\t.help = \"Reset all targets into the specified mode. \"\n\t\t\t\"Default reset mode is run, if not given.\",\n\t},\n\t{\n\t\t.name = \"soft_reset_halt\",\n\t\t.handler = handle_soft_reset_halt_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"\",\n\t\t.help = \"halt the target and do a soft reset\",\n\t},\n\t{\n\t\t.name = \"step\",\n\t\t.handler = handle_step_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\t\"step one instruction from current PC or address\",\n\t\t.usage = \"[address]\",\n\t},\n\t{\n\t\t.name = \"mdd\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display memory double-words\",\n\t\t.usage = \"['phys'] address [count]\",\n\t},\n\t{\n\t\t.name = \"mdw\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display memory words\",\n\t\t.usage = \"['phys'] address [count]\",\n\t},\n\t{\n\t\t.name = \"mdh\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display memory half-words\",\n\t\t.usage = \"['phys'] address [count]\",\n\t},\n\t{\n\t\t.name = \"mdb\",\n\t\t.handler = handle_md_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display memory bytes\",\n\t\t.usage = \"['phys'] address [count]\",\n\t},\n\t{\n\t\t.name = \"mwd\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write memory double-word\",\n\t\t.usage = \"['phys'] address value [count]\",\n\t},\n\t{\n\t\t.name = \"mww\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write memory word\",\n\t\t.usage = \"['phys'] address value [count]\",\n\t},\n\t{\n\t\t.name = \"mwh\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write memory half-word\",\n\t\t.usage = \"['phys'] address value [count]\",\n\t},\n\t{\n\t\t.name = \"mwb\",\n\t\t.handler = handle_mw_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"write memory byte\",\n\t\t.usage = \"['phys'] address value [count]\",\n\t},\n\t{\n\t\t.name = \"bp\",\n\t\t.handler = handle_bp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list or set hardware or software breakpoint\",\n\t\t.usage = \"[<address> [<asid>] <length> ['hw'|'hw_ctx']]\",\n\t},\n\t{\n\t\t.name = \"rbp\",\n\t\t.handler = handle_rbp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"remove breakpoint\",\n\t\t.usage = \"'all' | address\",\n\t},\n\t{\n\t\t.name = \"wp\",\n\t\t.handler = handle_wp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list (no params) or create watchpoints\",\n\t\t.usage = \"[address length [('r'|'w'|'a') value [mask]]]\",\n\t},\n\t{\n\t\t.name = \"rwp\",\n\t\t.handler = handle_rwp_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"remove watchpoint\",\n\t\t.usage = \"address\",\n\t},\n\t{\n\t\t.name = \"load_image\",\n\t\t.handler = handle_load_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename address ['bin'|'ihex'|'elf'|'s19'] \"\n\t\t\t\"[min_address] [max_length]\",\n\t},\n\t{\n\t\t.name = \"dump_image\",\n\t\t.handler = handle_dump_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename address size\",\n\t},\n\t{\n\t\t.name = \"verify_image_checksum\",\n\t\t.handler = handle_verify_image_checksum_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename [offset [type]]\",\n\t},\n\t{\n\t\t.name = \"verify_image\",\n\t\t.handler = handle_verify_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename [offset [type]]\",\n\t},\n\t{\n\t\t.name = \"test_image\",\n\t\t.handler = handle_test_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.usage = \"filename [offset [type]]\",\n\t},\n\t{\n\t\t.name = \"get_reg\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_get_reg,\n\t\t.help = \"Get register values from the target\",\n\t\t.usage = \"list\",\n\t},\n\t{\n\t\t.name = \"set_reg\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_set_reg,\n\t\t.help = \"Set target register values\",\n\t\t.usage = \"dict\",\n\t},\n\t{\n\t\t.name = \"read_memory\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_target_read_memory,\n\t\t.help = \"Read Tcl list of 8/16/32/64 bit numbers from target memory\",\n\t\t.usage = \"address width count ['phys']\",\n\t},\n\t{\n\t\t.name = \"write_memory\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.jim_handler = target_jim_write_memory,\n\t\t.help = \"Write Tcl list of 8/16/32/64 bit numbers to target memory\",\n\t\t.usage = \"address width data ['phys']\",\n\t},\n\t{\n\t\t.name = \"reset_nag\",\n\t\t.handler = handle_target_reset_nag,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Nag after each reset about options that could have been \"\n\t\t\t\t\"enabled to improve performance.\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"ps\",\n\t\t.handler = handle_ps_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"list all tasks\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"test_mem_access\",\n\t\t.handler = handle_test_mem_access_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Test the target's memory access functions\",\n\t\t.usage = \"size\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic int target_register_user_commands(struct command_context *cmd_ctx)\n{\n\tint retval = ERROR_OK;\n\tretval = target_request_register_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = trace_register_commands(cmd_ctx);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\n\treturn register_commands(cmd_ctx, NULL, target_exec_command_handlers);\n}\n\nconst char *target_debug_reason_str(enum target_debug_reason reason)\n{\n\tswitch (reason) {\n\t\tcase DBG_REASON_DBGRQ:\n\t\t\treturn \"DBGRQ\";\n\t\tcase DBG_REASON_BREAKPOINT:\n\t\t\treturn \"BREAKPOINT\";\n\t\tcase DBG_REASON_WATCHPOINT:\n\t\t\treturn \"WATCHPOINT\";\n\t\tcase DBG_REASON_WPTANDBKPT:\n\t\t\treturn \"WPTANDBKPT\";\n\t\tcase DBG_REASON_SINGLESTEP:\n\t\t\treturn \"SINGLESTEP\";\n\t\tcase DBG_REASON_NOTHALTED:\n\t\t\treturn \"NOTHALTED\";\n\t\tcase DBG_REASON_EXIT:\n\t\t\treturn \"EXIT\";\n\t\tcase DBG_REASON_EXC_CATCH:\n\t\t\treturn \"EXC_CATCH\";\n\t\tcase DBG_REASON_UNDEFINED:\n\t\t\treturn \"UNDEFINED\";\n\t\tdefault:\n\t\t\treturn \"UNKNOWN!\";\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/target.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n *                                                                         *\n *   Copyright (C) 2011 by Broadcom Corporation                            *\n *   Evan Hunter - ehunter@broadcom.com                                    *\n *                                                                         *\n *   Copyright (C) ST-Ericsson SA 2011                                     *\n *   michel.jaouen@stericsson.com : smp minimum support                    *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_TARGET_H\n#define OPENOCD_TARGET_TARGET_H\n\n#include <helper/list.h>\n#include \"helper/replacements.h\"\n#include \"helper/system.h\"\n#include <jim.h>\n\nstruct reg;\nstruct trace;\nstruct command_context;\nstruct command_invocation;\nstruct breakpoint;\nstruct watchpoint;\nstruct mem_param;\nstruct reg_param;\nstruct target_list;\nstruct gdb_fileio_info;\n\n/*\n * TARGET_UNKNOWN = 0: we don't know anything about the target yet\n * TARGET_RUNNING = 1: the target is executing or ready to execute user code\n * TARGET_HALTED  = 2: the target is not executing code, and ready to talk to the\n * debugger. on an xscale it means that the debug handler is executing\n * TARGET_RESET   = 3: the target is being held in reset (only a temporary state,\n * not sure how this is used with all the recent changes)\n * TARGET_DEBUG_RUNNING = 4: the target is running, but it is executing code on\n * behalf of the debugger (e.g. algorithm for flashing)\n *\n * also see: target_state_name();\n */\n\nenum target_state {\n\tTARGET_UNKNOWN = 0,\n\tTARGET_RUNNING = 1,\n\tTARGET_HALTED = 2,\n\tTARGET_RESET = 3,\n\tTARGET_DEBUG_RUNNING = 4,\n};\n\nenum target_reset_mode {\n\tRESET_UNKNOWN = 0,\n\tRESET_RUN = 1,\t\t/* reset and let target run */\n\tRESET_HALT = 2,\t\t/* reset and halt target out of reset */\n\tRESET_INIT = 3,\t\t/* reset and halt target out of reset, then run init script */\n};\n\nenum target_debug_reason {\n\tDBG_REASON_DBGRQ = 0,\n\tDBG_REASON_BREAKPOINT = 1,\n\tDBG_REASON_WATCHPOINT = 2,\n\tDBG_REASON_WPTANDBKPT = 3,\n\tDBG_REASON_SINGLESTEP = 4,\n\tDBG_REASON_NOTHALTED = 5,\n\tDBG_REASON_EXIT = 6,\n\tDBG_REASON_EXC_CATCH = 7,\n\tDBG_REASON_UNDEFINED = 8,\n};\n\nenum target_endianness {\n\tTARGET_ENDIAN_UNKNOWN = 0,\n\tTARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2\n};\n\nstruct working_area {\n\ttarget_addr_t address;\n\tuint32_t size;\n\tbool free;\n\tuint8_t *backup;\n\tstruct working_area **user;\n\tstruct working_area *next;\n};\n\nstruct gdb_service {\n\tstruct target *target;\n\t/*  field for smp display  */\n\t/*  element 0 coreid currently displayed ( 1 till n) */\n\t/*  element 1 coreid to be displayed at next resume 1 till n 0 means resume\n\t *  all cores core displayed  */\n\tint32_t core[2];\n};\n\n/* target back off timer */\nstruct backoff_timer {\n\tint times;\n\tint count;\n};\n\n/* split target registers into multiple class */\nenum target_register_class {\n\tREG_CLASS_ALL,\n\tREG_CLASS_GENERAL,\n};\n\n/* target_type.h contains the full definition of struct target_type */\nstruct target {\n\tstruct target_type *type;\t\t\t/* target type definition (name, access functions) */\n\tchar *cmd_name;\t\t\t\t/* tcl Name of target */\n\tint target_number;\t\t\t\t\t/* DO NOT USE!  field to be removed in 2010 */\n\tstruct jtag_tap *tap;\t\t\t\t/* where on the jtag chain is this */\n\tint32_t coreid;\t\t\t\t\t\t/* which device on the TAP? */\n\n\t/** Should we defer examine to later */\n\tbool defer_examine;\n\n\t/**\n\t * Indicates whether this target has been examined.\n\t *\n\t * Do @b not access this field directly, use target_was_examined()\n\t * or target_set_examined().\n\t */\n\tbool examined;\n\n\t/**\n\t * true if the  target is currently running a downloaded\n\t * \"algorithm\" instead of arbitrary user code. OpenOCD code\n\t * invoking algorithms is trusted to maintain correctness of\n\t * any cached state (e.g. for flash status), which arbitrary\n\t * code will have no reason to know about.\n\t */\n\tbool running_alg;\n\n\tstruct target_event_action *event_action;\n\n\tbool reset_halt;\t\t\t\t\t\t/* attempt resetting the CPU into the halted mode? */\n\ttarget_addr_t working_area;\t\t\t\t/* working area (initialised RAM). Evaluated\n\t\t\t\t\t\t\t\t\t\t * upon first allocation from virtual/physical address. */\n\tbool working_area_virt_spec;\t\t/* virtual address specified? */\n\ttarget_addr_t working_area_virt;\t\t\t/* virtual address */\n\tbool working_area_phys_spec;\t\t/* physical address specified? */\n\ttarget_addr_t working_area_phys;\t\t\t/* physical address */\n\tuint32_t working_area_size;\t\t\t/* size in bytes */\n\tuint32_t backup_working_area;\t\t/* whether the content of the working area has to be preserved */\n\tstruct working_area *working_areas;/* list of allocated working areas */\n\tenum target_debug_reason debug_reason;/* reason why the target entered debug state */\n\tenum target_endianness endianness;\t/* target endianness */\n\t/* also see: target_state_name() */\n\tenum target_state state;\t\t\t/* the current backend-state (running, halted, ...) */\n\tstruct reg_cache *reg_cache;\t\t/* the first register cache of the target (core regs) */\n\tstruct breakpoint *breakpoints;\t\t/* list of breakpoints */\n\tstruct watchpoint *watchpoints;\t\t/* list of watchpoints */\n\tstruct trace *trace_info;\t\t\t/* generic trace information */\n\tstruct debug_msg_receiver *dbgmsg;\t/* list of debug message receivers */\n\tuint32_t dbg_msg_enabled;\t\t\t/* debug message status */\n\tvoid *arch_info;\t\t\t\t\t/* architecture specific information */\n\tvoid *private_config;\t\t\t\t/* pointer to target specific config data (for jim_configure hook) */\n\tstruct target *next;\t\t\t\t/* next target in list */\n\n\tbool verbose_halt_msg;\t\t\t\t/* display async info in telnet session. Do not display\n\t\t\t\t\t\t\t\t\t\t * lots of halted/resumed info when stepping in debugger. */\n\tbool halt_issued;\t\t\t\t\t/* did we transition to halted state? */\n\tint64_t halt_issued_time;\t\t\t/* Note time when halt was issued */\n\n\t\t\t\t\t\t\t\t\t\t/* ARM v7/v8 targets with ADIv5 interface */\n\tbool dbgbase_set;\t\t\t\t\t/* By default the debug base is not set */\n\tuint32_t dbgbase;\t\t\t\t\t/* Really a Cortex-A specific option, but there is no\n\t\t\t\t\t\t\t\t\t\t * system in place to support target specific options\n\t\t\t\t\t\t\t\t\t\t * currently. */\n\tbool has_dap;\t\t\t\t\t\t/* set to true if target has ADIv5 support */\n\tbool dap_configured;\t\t\t\t/* set to true if ADIv5 DAP is configured */\n\tbool tap_configured;\t\t\t\t/* set to true if JTAG tap has been configured\n\t\t\t\t\t\t\t\t\t\t * through -chain-position */\n\n\tstruct rtos *rtos;\t\t\t\t\t/* Instance of Real Time Operating System support */\n\tbool rtos_auto_detect;\t\t\t\t/* A flag that indicates that the RTOS has been specified as \"auto\"\n\t\t\t\t\t\t\t\t\t\t * and must be detected when symbols are offered */\n\tstruct backoff_timer backoff;\n\tint smp;\t\t\t\t\t\t\t/* Unique non-zero number for each SMP group */\n\tstruct list_head *smp_targets;\t\t/* list all targets in this smp group/cluster\n\t\t\t\t\t\t\t\t\t\t * The head of the list is shared between the\n\t\t\t\t\t\t\t\t\t\t * cluster, thus here there is a pointer */\n\tbool smp_halt_event_postponed;\t\t/* Some SMP implementations (currently Cortex-M) stores\n\t\t\t\t\t\t\t\t\t\t * 'halted' events and emits them after all targets of\n\t\t\t\t\t\t\t\t\t\t * the SMP group has been polled */\n\n\t/* the gdb service is there in case of smp, we have only one gdb server\n\t * for all smp target\n\t * the target attached to the gdb is changing dynamically by changing\n\t * gdb_service->target pointer */\n\tstruct gdb_service *gdb_service;\n\n\t/* file-I/O information for host to do syscall */\n\tstruct gdb_fileio_info *fileio_info;\n\n\tchar *gdb_port_override;\t\t\t/* target-specific override for gdb_port */\n\n\tint gdb_max_connections;\t\t\t/* max number of simultaneous gdb connections */\n\n\t/* The semihosting information, extracted from the target. */\n\tstruct semihosting *semihosting;\n};\n\nstruct target_list {\n\tstruct list_head lh;\n\tstruct target *target;\n};\n\nstruct gdb_fileio_info {\n\tchar *identifier;\n\tuint64_t param_1;\n\tuint64_t param_2;\n\tuint64_t param_3;\n\tuint64_t param_4;\n};\n\n/** Returns a description of the endianness for the specified target. */\nstatic inline const char *target_endianness(struct target *target)\n{\n\treturn (target->endianness == TARGET_ENDIAN_UNKNOWN) ? \"unknown\" :\n\t\t\t(target->endianness == TARGET_BIG_ENDIAN) ? \"big endian\" : \"little endian\";\n}\n\n/** Returns the instance-specific name of the specified target. */\nstatic inline const char *target_name(struct target *target)\n{\n\treturn target->cmd_name;\n}\n\nconst char *debug_reason_name(struct target *t);\n\nenum target_event {\n\n\t/* allow GDB to do stuff before others handle the halted event,\n\t * this is in lieu of defining ordering of invocation of events,\n\t * which would be more complicated\n\t *\n\t * Telling GDB to halt does not mean that the target stopped running,\n\t * simply that we're dropping out of GDB's waiting for step or continue.\n\t *\n\t * This can be useful when e.g. detecting power dropout.\n\t */\n\tTARGET_EVENT_GDB_HALT,\n\tTARGET_EVENT_HALTED,\t\t/* target entered debug state from normal execution or reset */\n\tTARGET_EVENT_RESUMED,\t\t/* target resumed to normal execution */\n\tTARGET_EVENT_RESUME_START,\n\tTARGET_EVENT_RESUME_END,\n\tTARGET_EVENT_STEP_START,\n\tTARGET_EVENT_STEP_END,\n\n\tTARGET_EVENT_GDB_START, /* debugger started execution (step/run) */\n\tTARGET_EVENT_GDB_END, /* debugger stopped execution (step/run) */\n\n\tTARGET_EVENT_RESET_START,\n\tTARGET_EVENT_RESET_ASSERT_PRE,\n\tTARGET_EVENT_RESET_ASSERT,\t/* C code uses this instead of SRST */\n\tTARGET_EVENT_RESET_ASSERT_POST,\n\tTARGET_EVENT_RESET_DEASSERT_PRE,\n\tTARGET_EVENT_RESET_DEASSERT_POST,\n\tTARGET_EVENT_RESET_INIT,\n\tTARGET_EVENT_RESET_END,\n\n\tTARGET_EVENT_DEBUG_HALTED,\t/* target entered debug state, but was executing on behalf of the debugger */\n\tTARGET_EVENT_DEBUG_RESUMED, /* target resumed to execute on behalf of the debugger */\n\n\tTARGET_EVENT_EXAMINE_START,\n\tTARGET_EVENT_EXAMINE_FAIL,\n\tTARGET_EVENT_EXAMINE_END,\n\n\tTARGET_EVENT_GDB_ATTACH,\n\tTARGET_EVENT_GDB_DETACH,\n\n\tTARGET_EVENT_GDB_FLASH_ERASE_START,\n\tTARGET_EVENT_GDB_FLASH_ERASE_END,\n\tTARGET_EVENT_GDB_FLASH_WRITE_START,\n\tTARGET_EVENT_GDB_FLASH_WRITE_END,\n\n\tTARGET_EVENT_TRACE_CONFIG,\n\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X100 = 0x100, /* semihosting allows user cmds from 0x100 to 0x1ff */\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X101 = 0x101,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X102 = 0x102,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X103 = 0x103,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X104 = 0x104,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X105 = 0x105,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X106 = 0x106,\n\tTARGET_EVENT_SEMIHOSTING_USER_CMD_0X107 = 0x107,\n};\n\nstruct target_event_action {\n\tenum target_event event;\n\tJim_Interp *interp;\n\tJim_Obj *body;\n\tstruct target_event_action *next;\n};\n\nbool target_has_event_action(struct target *target, enum target_event event);\n\nstruct target_event_callback {\n\tint (*callback)(struct target *target, enum target_event event, void *priv);\n\tvoid *priv;\n\tstruct target_event_callback *next;\n};\n\nstruct target_reset_callback {\n\tstruct list_head list;\n\tvoid *priv;\n\tint (*callback)(struct target *target, enum target_reset_mode reset_mode, void *priv);\n};\n\nstruct target_trace_callback {\n\tstruct list_head list;\n\tvoid *priv;\n\tint (*callback)(struct target *target, size_t len, uint8_t *data, void *priv);\n};\n\nenum target_timer_type {\n\tTARGET_TIMER_TYPE_ONESHOT,\n\tTARGET_TIMER_TYPE_PERIODIC\n};\n\nstruct target_timer_callback {\n\tint (*callback)(void *priv);\n\tunsigned int time_ms;\n\tenum target_timer_type type;\n\tbool removed;\n\tint64_t when;\t/* output of timeval_ms() */\n\tvoid *priv;\n\tstruct target_timer_callback *next;\n};\n\nstruct target_memory_check_block {\n\ttarget_addr_t address;\n\tuint32_t size;\n\tuint32_t result;\n};\n\nint target_register_commands(struct command_context *cmd_ctx);\nint target_examine(void);\n\nint target_register_event_callback(\n\t\tint (*callback)(struct target *target,\n\t\tenum target_event event, void *priv),\n\t\tvoid *priv);\nint target_unregister_event_callback(\n\t\tint (*callback)(struct target *target,\n\t\tenum target_event event, void *priv),\n\t\tvoid *priv);\n\nint target_register_reset_callback(\n\t\tint (*callback)(struct target *target,\n\t\tenum target_reset_mode reset_mode, void *priv),\n\t\tvoid *priv);\nint target_unregister_reset_callback(\n\t\tint (*callback)(struct target *target,\n\t\tenum target_reset_mode reset_mode, void *priv),\n\t\tvoid *priv);\n\nint target_register_trace_callback(\n\t\tint (*callback)(struct target *target,\n\t\tsize_t len, uint8_t *data, void *priv),\n\t\tvoid *priv);\nint target_unregister_trace_callback(\n\t\tint (*callback)(struct target *target,\n\t\tsize_t len, uint8_t *data, void *priv),\n\t\tvoid *priv);\n\n/* Poll the status of the target, detect any error conditions and report them.\n *\n * Also note that this fn will clear such error conditions, so a subsequent\n * invocation will then succeed.\n *\n * These error conditions can be \"sticky\" error conditions. E.g. writing\n * to memory could be implemented as an open loop and if memory writes\n * fails, then a note is made of it, the error is sticky, but the memory\n * write loop still runs to completion. This improves performance in the\n * normal case as there is no need to verify that every single write succeed,\n * yet it is possible to detect error conditions.\n */\nint target_poll(struct target *target);\nint target_resume(struct target *target, int current, target_addr_t address,\n\t\tint handle_breakpoints, int debug_execution);\nint target_halt(struct target *target);\nint target_call_event_callbacks(struct target *target, enum target_event event);\nint target_call_reset_callbacks(struct target *target, enum target_reset_mode reset_mode);\nint target_call_trace_callbacks(struct target *target, size_t len, uint8_t *data);\n\n/**\n * The period is very approximate, the callback can happen much more often\n * or much more rarely than specified\n */\nint target_register_timer_callback(int (*callback)(void *priv),\n\t\tunsigned int time_ms, enum target_timer_type type, void *priv);\nint target_unregister_timer_callback(int (*callback)(void *priv), void *priv);\nint target_call_timer_callbacks(void);\n/**\n * Invoke this to ensure that e.g. polling timer callbacks happen before\n * a synchronous command completes.\n */\nint target_call_timer_callbacks_now(void);\n/**\n * Returns when the next registered event will take place. Callers can use this\n * to go to sleep until that time occurs.\n */\nint64_t target_timer_next_event(void);\n\nstruct target *get_target_by_num(int num);\nstruct target *get_current_target(struct command_context *cmd_ctx);\nstruct target *get_current_target_or_null(struct command_context *cmd_ctx);\nstruct target *get_target(const char *id);\n\n/**\n * Get the target type name.\n *\n * This routine is a wrapper for the target->type->name field.\n * Note that this is not an instance-specific name for his target.\n */\nconst char *target_type_name(struct target *target);\n\n/**\n * Examine the specified @a target, letting it perform any\n * Initialisation that requires JTAG access.\n *\n * This routine is a wrapper for target->type->examine.\n */\nint target_examine_one(struct target *target);\n\n/** @returns @c true if target_set_examined() has been called. */\nstatic inline bool target_was_examined(struct target *target)\n{\n\treturn target->examined;\n}\n\n/** Sets the @c examined flag for the given target. */\n/** Use in target->type->examine() after one-time setup is done. */\nstatic inline void target_set_examined(struct target *target)\n{\n\ttarget->examined = true;\n}\n\n/**\n * Add the @a breakpoint for @a target.\n *\n * This routine is a wrapper for target->type->add_breakpoint.\n */\nint target_add_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\n/**\n * Add the @a ContextID breakpoint  for @a target.\n *\n * This routine is a wrapper for target->type->add_context_breakpoint.\n */\nint target_add_context_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\n/**\n * Add the @a ContextID & IVA breakpoint  for @a target.\n *\n * This routine is a wrapper for target->type->add_hybrid_breakpoint.\n */\nint target_add_hybrid_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\n/**\n * Remove the @a breakpoint for @a target.\n *\n * This routine is a wrapper for target->type->remove_breakpoint.\n */\n\nint target_remove_breakpoint(struct target *target,\n\t\tstruct breakpoint *breakpoint);\n/**\n * Add the @a watchpoint for @a target.\n *\n * This routine is a wrapper for target->type->add_watchpoint.\n */\nint target_add_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint);\n/**\n * Remove the @a watchpoint for @a target.\n *\n * This routine is a wrapper for target->type->remove_watchpoint.\n */\nint target_remove_watchpoint(struct target *target,\n\t\tstruct watchpoint *watchpoint);\n\n/**\n * Find out the just hit @a watchpoint for @a target.\n *\n * This routine is a wrapper for target->type->hit_watchpoint.\n */\nint target_hit_watchpoint(struct target *target,\n\t\tstruct watchpoint **watchpoint);\n\n/**\n * Obtain the architecture for GDB.\n *\n * This routine is a wrapper for target->type->get_gdb_arch.\n */\nconst char *target_get_gdb_arch(struct target *target);\n\n/**\n * Obtain the registers for GDB.\n *\n * This routine is a wrapper for target->type->get_gdb_reg_list.\n */\nint target_get_gdb_reg_list(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\n\n/**\n * Obtain the registers for GDB, but don't read register values from the\n * target.\n *\n * This routine is a wrapper for target->type->get_gdb_reg_list_noread.\n */\nint target_get_gdb_reg_list_noread(struct target *target,\n\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\tenum target_register_class reg_class);\n\n/**\n * Check if @a target allows GDB connections.\n *\n * Some target do not implement the necessary code required by GDB.\n */\nbool target_supports_gdb_connection(struct target *target);\n\n/**\n * Step the target.\n *\n * This routine is a wrapper for target->type->step.\n */\nint target_step(struct target *target,\n\t\tint current, target_addr_t address, int handle_breakpoints);\n/**\n * Run an algorithm on the @a target given.\n *\n * This routine is a wrapper for target->type->run_algorithm.\n */\nint target_run_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_param,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tunsigned int timeout_ms, void *arch_info);\n\n/**\n * Starts an algorithm in the background on the @a target given.\n *\n * This routine is a wrapper for target->type->start_algorithm.\n */\nint target_start_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t entry_point, target_addr_t exit_point,\n\t\tvoid *arch_info);\n\n/**\n * Wait for an algorithm on the @a target given.\n *\n * This routine is a wrapper for target->type->wait_algorithm.\n */\nint target_wait_algorithm(struct target *target,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\ttarget_addr_t exit_point, unsigned int timeout_ms,\n\t\tvoid *arch_info);\n\n/**\n * This routine is a wrapper for asynchronous algorithms.\n *\n */\nint target_run_flash_async_algorithm(struct target *target,\n\t\tconst uint8_t *buffer, uint32_t count, int block_size,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\tuint32_t buffer_start, uint32_t buffer_size,\n\t\tuint32_t entry_point, uint32_t exit_point,\n\t\tvoid *arch_info);\n\n/**\n * This routine is a wrapper for asynchronous algorithms.\n *\n */\nint target_run_read_async_algorithm(struct target *target,\n\t\tuint8_t *buffer, uint32_t count, int block_size,\n\t\tint num_mem_params, struct mem_param *mem_params,\n\t\tint num_reg_params, struct reg_param *reg_params,\n\t\tuint32_t buffer_start, uint32_t buffer_size,\n\t\tuint32_t entry_point, uint32_t exit_point,\n\t\tvoid *arch_info);\n\n/**\n * Read @a count items of @a size bytes from the memory of @a target at\n * the @a address given.\n *\n * This routine is a wrapper for target->type->read_memory.\n */\nint target_read_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);\nint target_read_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);\n/**\n * Write @a count items of @a size bytes to the memory of @a target at\n * the @a address given. @a address must be aligned to @a size\n * in target memory.\n *\n * The endianness is the same in the host and target memory for this\n * function.\n *\n * \\todo TODO:\n * Really @a buffer should have been defined as \"const void *\" and\n * @a buffer should have been aligned to @a size in the host memory.\n *\n * This is not enforced via e.g. assert's today and e.g. the\n * target_write_buffer fn breaks this assumption.\n *\n * This routine is wrapper for target->type->write_memory.\n */\nint target_write_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\nint target_write_phys_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t count, const uint8_t *buffer);\n\n/*\n * Write to target memory using the virtual address.\n *\n * Note that this fn is used to implement software breakpoints. Targets\n * can implement support for software breakpoints to memory marked as read\n * only by making this fn write to ram even if it is read only(MMU or\n * MPUs).\n *\n * It is sufficient to implement for writing a single word(16 or 32 in\n * ARM32/16 bit case) to write the breakpoint to ram.\n *\n * The target should also take care of \"other things\" to make sure that\n * software breakpoints can be written using this function. E.g.\n * when there is a separate instruction and data cache, this fn must\n * make sure that the instruction cache is synced up to the potential\n * code change that can happen as a result of the memory write(typically\n * by invalidating the cache).\n *\n * The high level wrapper fn in target.c will break down this memory write\n * request to multiple write requests to the target driver to e.g. guarantee\n * that writing 4 bytes to an aligned address happens with a single 32 bit\n * write operation, thus making this fn suitable to e.g. write to special\n * peripheral registers which do not support byte operations.\n */\nint target_write_buffer(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, const uint8_t *buffer);\nint target_read_buffer(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint8_t *buffer);\nint target_checksum_memory(struct target *target,\n\t\ttarget_addr_t address, uint32_t size, uint32_t *crc);\nint target_blank_check_memory(struct target *target,\n\t\tstruct target_memory_check_block *blocks, int num_blocks,\n\t\tuint8_t erased_value);\nint target_wait_state(struct target *target, enum target_state state, unsigned int ms);\n\n/**\n * Obtain file-I/O information from target for GDB to do syscall.\n *\n * This routine is a wrapper for target->type->get_gdb_fileio_info.\n */\nint target_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info);\n\n/**\n * Pass GDB file-I/O response to target after finishing host syscall.\n *\n * This routine is a wrapper for target->type->gdb_fileio_end.\n */\nint target_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c);\n\n/**\n * Return the highest accessible address for this target.\n */\ntarget_addr_t target_address_max(struct target *target);\n\n/**\n * Return the number of address bits this target supports.\n *\n * This routine is a wrapper for target->type->address_bits.\n */\nunsigned target_address_bits(struct target *target);\n\n/**\n * Return the number of data bits this target supports.\n *\n * This routine is a wrapper for target->type->data_bits.\n */\nunsigned int target_data_bits(struct target *target);\n\n/** Return the *name* of this targets current state */\nconst char *target_state_name(struct target *target);\n\n/** Return the *name* of a target event enumeration value */\nconst char *target_event_name(enum target_event event);\n\n/** Return the *name* of a target reset reason enumeration value */\nconst char *target_reset_mode_name(enum target_reset_mode reset_mode);\n\n/* DANGER!!!!!\n *\n * if \"area\" passed in to target_alloc_working_area() points to a memory\n * location that goes out of scope (e.g. a pointer on the stack), then\n * the caller of target_alloc_working_area() is responsible for invoking\n * target_free_working_area() before \"area\" goes out of scope.\n *\n * target_free_all_working_areas() will NULL out the \"area\" pointer\n * upon resuming or resetting the CPU.\n *\n */\nint target_alloc_working_area(struct target *target,\n\t\tuint32_t size, struct working_area **area);\n/* Same as target_alloc_working_area, except that no error is logged\n * when ERROR_TARGET_RESOURCE_NOT_AVAILABLE is returned.\n *\n * This allows the calling code to *try* to allocate target memory\n * and have a fallback to another behaviour(slower?).\n */\nint target_alloc_working_area_try(struct target *target,\n\t\tuint32_t size, struct working_area **area);\n/**\n * Free a working area.\n * Restore target data if area backup is configured.\n * @param target\n * @param area Pointer to the area to be freed or NULL\n * @returns ERROR_OK if successful; error code if restore failed\n */\nint target_free_working_area(struct target *target, struct working_area *area);\nvoid target_free_all_working_areas(struct target *target);\nuint32_t target_get_working_area_avail(struct target *target);\n\n/**\n * Free all the resources allocated by targets and the target layer\n */\nvoid target_quit(void);\n\nextern struct target *all_targets;\n\nuint64_t target_buffer_get_u64(struct target *target, const uint8_t *buffer);\nuint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer);\nuint32_t target_buffer_get_u24(struct target *target, const uint8_t *buffer);\nuint16_t target_buffer_get_u16(struct target *target, const uint8_t *buffer);\nvoid target_buffer_set_u64(struct target *target, uint8_t *buffer, uint64_t value);\nvoid target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value);\nvoid target_buffer_set_u24(struct target *target, uint8_t *buffer, uint32_t value);\nvoid target_buffer_set_u16(struct target *target, uint8_t *buffer, uint16_t value);\n\nvoid target_buffer_get_u64_array(struct target *target, const uint8_t *buffer, uint32_t count, uint64_t *dstbuf);\nvoid target_buffer_get_u32_array(struct target *target, const uint8_t *buffer, uint32_t count, uint32_t *dstbuf);\nvoid target_buffer_get_u16_array(struct target *target, const uint8_t *buffer, uint32_t count, uint16_t *dstbuf);\nvoid target_buffer_set_u64_array(struct target *target, uint8_t *buffer, uint32_t count, const uint64_t *srcbuf);\nvoid target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf);\nvoid target_buffer_set_u16_array(struct target *target, uint8_t *buffer, uint32_t count, const uint16_t *srcbuf);\n\nint target_read_u64(struct target *target, target_addr_t address, uint64_t *value);\nint target_read_u32(struct target *target, target_addr_t address, uint32_t *value);\nint target_read_u16(struct target *target, target_addr_t address, uint16_t *value);\nint target_read_u8(struct target *target, target_addr_t address, uint8_t *value);\nint target_write_u64(struct target *target, target_addr_t address, uint64_t value);\nint target_write_u32(struct target *target, target_addr_t address, uint32_t value);\nint target_write_u16(struct target *target, target_addr_t address, uint16_t value);\nint target_write_u8(struct target *target, target_addr_t address, uint8_t value);\n\nint target_write_phys_u64(struct target *target, target_addr_t address, uint64_t value);\nint target_write_phys_u32(struct target *target, target_addr_t address, uint32_t value);\nint target_write_phys_u16(struct target *target, target_addr_t address, uint16_t value);\nint target_write_phys_u8(struct target *target, target_addr_t address, uint8_t value);\n\n/* Issues USER() statements with target state information */\nint target_arch_state(struct target *target);\n\nvoid target_handle_event(struct target *t, enum target_event e);\n\nvoid target_handle_md_output(struct command_invocation *cmd,\n\tstruct target *target, target_addr_t address, unsigned size,\n\tunsigned count, const uint8_t *buffer);\n\nint target_profiling_default(struct target *target, uint32_t *samples, uint32_t\n\t\tmax_num_samples, uint32_t *num_samples, uint32_t seconds);\n\n#define ERROR_TARGET_INVALID\t(-300)\n#define ERROR_TARGET_INIT_FAILED (-301)\n#define ERROR_TARGET_TIMEOUT\t(-302)\n#define ERROR_TARGET_NOT_HALTED (-304)\n#define ERROR_TARGET_FAILURE\t(-305)\n#define ERROR_TARGET_UNALIGNED_ACCESS\t(-306)\n#define ERROR_TARGET_DATA_ABORT\t(-307)\n#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE\t(-308)\n#define ERROR_TARGET_TRANSLATION_FAULT\t(-309)\n#define ERROR_TARGET_NOT_RUNNING (-310)\n#define ERROR_TARGET_NOT_EXAMINED (-311)\n#define ERROR_TARGET_DUPLICATE_BREAKPOINT (-312)\n#define ERROR_TARGET_ALGO_EXIT  (-313)\n\nextern bool get_target_reset_nag(void);\n\n#define TARGET_DEFAULT_POLLING_INTERVAL\t\t100\n\nconst char *target_debug_reason_str(enum target_debug_reason reason);\n\n#endif /* OPENOCD_TARGET_TARGET_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/target_request.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include <helper/binarybuffer.h>\n\n#include \"target.h\"\n#include \"target_request.h\"\n#include \"target_type.h\"\n#include \"trace.h\"\n\nstatic bool got_message;\n\nbool target_got_message(void)\n{\n\tbool t = got_message;\n\tgot_message = false;\n\treturn t;\n}\n\nstatic int charmsg_mode;\n\nstatic int target_asciimsg(struct target *target, uint32_t length)\n{\n\tchar *msg = malloc(DIV_ROUND_UP(length + 1, 4) * 4);\n\tstruct debug_msg_receiver *c = target->dbgmsg;\n\n\ttarget->type->target_request_data(target, DIV_ROUND_UP(length, 4), (uint8_t *)msg);\n\tmsg[length] = 0;\n\n\tLOG_DEBUG(\"%s\", msg);\n\n\twhile (c) {\n\t\tcommand_output_text(c->cmd_ctx, msg);\n\t\tc = c->next;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int target_charmsg(struct target *target, uint8_t msg)\n{\n\tLOG_USER_N(\"%c\", msg);\n\n\treturn ERROR_OK;\n}\n\nstatic int target_hexmsg(struct target *target, int size, uint32_t length)\n{\n\tuint8_t *data = malloc(DIV_ROUND_UP(length * size, 4) * 4);\n\tchar line[128];\n\tint line_len;\n\tstruct debug_msg_receiver *c = target->dbgmsg;\n\tuint32_t i;\n\n\tLOG_DEBUG(\"size: %i, length: %i\", (int)size, (int)length);\n\n\ttarget->type->target_request_data(target, DIV_ROUND_UP(length * size, 4), (uint8_t *)data);\n\n\tline_len = 0;\n\tfor (i = 0; i < length; i++) {\n\t\tswitch (size) {\n\t\t\tcase 4:\n\t\t\t\tline_len += snprintf(line + line_len, 128 - line_len, \"%8.8\" PRIx32 \" \", le_to_h_u32(data + (4*i)));\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tline_len += snprintf(line + line_len, 128 - line_len, \"%4.4x \", le_to_h_u16(data + (2*i)));\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tline_len += snprintf(line + line_len, 128 - line_len, \"%2.2x \", data[i]);\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ((i%8 == 7) || (i == length - 1)) {\n\t\t\tLOG_DEBUG(\"%s\", line);\n\n\t\t\twhile (c) {\n\t\t\t\tcommand_output_text(c->cmd_ctx, line);\n\t\t\t\tc = c->next;\n\t\t\t}\n\t\t\tc = target->dbgmsg;\n\t\t\tline_len = 0;\n\t\t}\n\t}\n\n\tfree(data);\n\n\treturn ERROR_OK;\n}\n\n/* handle requests from the target received by a target specific\n * side-band channel (e.g. ARM7/9 DCC)\n */\nint target_request(struct target *target, uint32_t request)\n{\n\ttarget_req_cmd_t target_req_cmd = request & 0xff;\n\n\tassert(target->type->target_request_data);\n\n\t/* Record that we got a target message for back-off algorithm */\n\tgot_message = true;\n\n\tif (charmsg_mode) {\n\t\ttarget_charmsg(target, target_req_cmd);\n\t\treturn ERROR_OK;\n\t}\n\n\tswitch (target_req_cmd) {\n\t\tcase TARGET_REQ_TRACEMSG:\n\t\t\ttrace_point(target, (request & 0xffffff00) >> 8);\n\t\t\tbreak;\n\t\tcase TARGET_REQ_DEBUGMSG:\n\t\t\tif (((request & 0xff00) >> 8) == 0)\n\t\t\t\ttarget_asciimsg(target, (request & 0xffff0000) >> 16);\n\t\t\telse\n\t\t\t\ttarget_hexmsg(target, (request & 0xff00) >> 8, (request & 0xffff0000) >> 16);\n\t\t\tbreak;\n\t\tcase TARGET_REQ_DEBUGCHAR:\n\t\t\ttarget_charmsg(target, (request & 0x00ff0000) >> 16);\n\t\t\tbreak;\n/*\t\tcase TARGET_REQ_SEMIHOSTING:\n *\t\t\tbreak;\n */\n\t\tdefault:\n\t\t\tLOG_ERROR(\"unknown target request: %2.2x\", target_req_cmd);\n\t\t\tbreak;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int add_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)\n{\n\tstruct debug_msg_receiver **p = &target->dbgmsg;\n\n\tif (!target)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* see if there's already a list */\n\tif (*p) {\n\t\t/* find end of linked list */\n\t\twhile ((*p)->next)\n\t\t\tp = &((*p)->next);\n\t\tp = &((*p)->next);\n\t}\n\n\t/* add new debug message receiver */\n\t(*p) = malloc(sizeof(struct debug_msg_receiver));\n\t(*p)->cmd_ctx = cmd_ctx;\n\t(*p)->next = NULL;\n\n\t/* enable callback */\n\ttarget->dbg_msg_enabled = 1;\n\n\treturn ERROR_OK;\n}\n\nstatic struct debug_msg_receiver *find_debug_msg_receiver(struct command_context *cmd_ctx,\n\t\tstruct target *target)\n{\n\tint do_all_targets = 0;\n\n\t/* if no target has been specified search all of them */\n\tif (!target) {\n\t\t/* if no targets haven been specified */\n\t\tif (!all_targets)\n\t\t\treturn NULL;\n\n\t\ttarget = all_targets;\n\t\tdo_all_targets = 1;\n\t}\n\n\t/* so we target != null */\n\tstruct debug_msg_receiver **p = &target->dbgmsg;\n\tdo {\n\t\twhile (*p) {\n\t\t\tif ((*p)->cmd_ctx == cmd_ctx)\n\t\t\t\treturn *p;\n\t\t\tp = &((*p)->next);\n\t\t}\n\n\t\ttarget = target->next;\n\t} while (target && do_all_targets);\n\n\treturn NULL;\n}\n\nint delete_debug_msg_receiver(struct command_context *cmd_ctx, struct target *target)\n{\n\tstruct debug_msg_receiver **p;\n\tstruct debug_msg_receiver *c;\n\tint do_all_targets = 0;\n\n\t/* if no target has been specified search all of them */\n\tif (!target) {\n\t\t/* if no targets haven been specified */\n\t\tif (!all_targets)\n\t\t\treturn ERROR_OK;\n\n\t\ttarget = all_targets;\n\t\tdo_all_targets = 1;\n\t}\n\n\tdo {\n\t\tp = &target->dbgmsg;\n\t\tc = *p;\n\t\twhile (c) {\n\t\t\tstruct debug_msg_receiver *next = c->next;\n\t\t\tif (c->cmd_ctx == cmd_ctx) {\n\t\t\t\t*p = next;\n\t\t\t\tfree(c);\n\t\t\t\tif (!*p) {\n\t\t\t\t\t/* disable callback */\n\t\t\t\t\ttarget->dbg_msg_enabled = 0;\n\t\t\t\t}\n\t\t\t\treturn ERROR_OK;\n\t\t\t} else\n\t\t\t\tp = &(c->next);\n\t\t\tc = next;\n\t\t}\n\n\t\ttarget = target->next;\n\t} while (target && do_all_targets);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_target_request_debugmsgs_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tint receiving = 0;\n\n\tif (!target->type->target_request_data) {\n\t\tLOG_ERROR(\"Target %s does not support target requests\", target_name(target));\n\t\treturn ERROR_OK;\n\t}\n\n\t/* see if receiver is already registered */\n\tif (find_debug_msg_receiver(CMD_CTX, target))\n\t\treceiving = 1;\n\n\tif (CMD_ARGC > 0) {\n\t\tif (!strcmp(CMD_ARGV[0], \"enable\") || !strcmp(CMD_ARGV[0], \"charmsg\")) {\n\t\t\t/* don't register if this command context is already receiving */\n\t\t\tif (!receiving) {\n\t\t\t\treceiving = 1;\n\t\t\t\tadd_debug_msg_receiver(CMD_CTX, target);\n\t\t\t}\n\t\t\tcharmsg_mode = !strcmp(CMD_ARGV[0], \"charmsg\");\n\t\t} else if (!strcmp(CMD_ARGV[0], \"disable\")) {\n\t\t\t/* no need to delete a receiver if none is registered */\n\t\t\tif (receiving) {\n\t\t\t\treceiving = 0;\n\t\t\t\tdelete_debug_msg_receiver(CMD_CTX, target);\n\t\t\t}\n\t\t} else\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tcommand_print(CMD, \"receiving debug messages from current target %s\",\n\t\t\t(receiving) ? (charmsg_mode ? \"charmsg\" : \"enabled\") : \"disabled\");\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration target_req_exec_command_handlers[] = {\n\t{\n\t\t.name = \"debugmsgs\",\n\t\t.handler = handle_target_request_debugmsgs_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display and/or modify reception of debug messages from target\",\n\t\t.usage = \"['enable'|'charmsg'|'disable']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration target_req_command_handlers[] = {\n\t{\n\t\t.name = \"target_request\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"target request command group\",\n\t\t.usage = \"\",\n\t\t.chain = target_req_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint target_request_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, target_req_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/target_request.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_TARGET_REQUEST_H\n#define OPENOCD_TARGET_TARGET_REQUEST_H\n\nstruct target;\nstruct command_context;\n\ntypedef enum target_req_cmd {\n\tTARGET_REQ_TRACEMSG,\n\tTARGET_REQ_DEBUGMSG,\n\tTARGET_REQ_DEBUGCHAR,\n/*\tTARGET_REQ_SEMIHOSTING, */\n} target_req_cmd_t;\n\nstruct debug_msg_receiver {\n\tstruct command_context *cmd_ctx;\n\tstruct debug_msg_receiver *next;\n};\n\nint target_request(struct target *target, uint32_t request);\nint delete_debug_msg_receiver(struct command_context *cmd_ctx,\n\t\tstruct target *target);\nint target_request_register_commands(struct command_context *cmd_ctx);\n/**\n * Read and clear the flag as to whether we got a message.\n *\n * This is used to implement the back-off algorithm on\n * sleeping in idle mode.\n */\nbool target_got_message(void);\n\n#endif /* OPENOCD_TARGET_TARGET_REQUEST_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/target_type.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007-2010 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 by Spencer Oliver                                  *\n *   spen@spen-soft.co.uk                                                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_TARGET_TYPE_H\n#define OPENOCD_TARGET_TARGET_TYPE_H\n\n#include <helper/jim-nvp.h>\n\nstruct target;\n\n/**\n * This holds methods shared between all instances of a given target\n * type.  For example, all Cortex-M3 targets on a scan chain share\n * the same method table.\n */\nstruct target_type {\n\t/**\n\t * Name of this type of target.  Do @b not access this\n\t * field directly, use target_type_name() instead.\n\t */\n\tconst char *name;\n\n\t/* poll current target status */\n\tint (*poll)(struct target *target);\n\t/* Invoked only from target_arch_state().\n\t * Issue USER() w/architecture specific status.  */\n\tint (*arch_state)(struct target *target);\n\n\t/* target request support */\n\tint (*target_request_data)(struct target *target, uint32_t size, uint8_t *buffer);\n\n\t/* halt will log a warning, but return ERROR_OK if the target is already halted. */\n\tint (*halt)(struct target *target);\n\t/* See target.c target_resume() for documentation. */\n\tint (*resume)(struct target *target, int current, target_addr_t address,\n\t\t\tint handle_breakpoints, int debug_execution);\n\tint (*step)(struct target *target, int current, target_addr_t address,\n\t\t\tint handle_breakpoints);\n\t/* target reset control. assert reset can be invoked when OpenOCD and\n\t * the target is out of sync.\n\t *\n\t * A typical example is that the target was power cycled while OpenOCD\n\t * thought the target was halted or running.\n\t *\n\t * assert_reset() can therefore make no assumptions whatsoever about the\n\t * state of the target\n\t *\n\t * Before assert_reset() for the target is invoked, a TRST/tms and\n\t * chain validation is executed. TRST should not be asserted\n\t * during target assert unless there is no way around it due to\n\t * the way reset's are configured.\n\t *\n\t */\n\tint (*assert_reset)(struct target *target);\n\t/**\n\t * The implementation is responsible for polling the\n\t * target such that target->state reflects the\n\t * state correctly.\n\t *\n\t * Otherwise the following would fail, as there will not\n\t * be any \"poll\" invoked between the \"reset run\" and\n\t * \"halt\".\n\t *\n\t * reset run; halt\n\t */\n\tint (*deassert_reset)(struct target *target);\n\tint (*soft_reset_halt)(struct target *target);\n\n\t/**\n\t * Target architecture for GDB.\n\t *\n\t * The string returned by this function will not be automatically freed;\n\t * if dynamic allocation is used for this value, it must be managed by\n\t * the target, ideally by caching the result for subsequent calls.\n\t */\n\tconst char *(*get_gdb_arch)(struct target *target);\n\n\t/**\n\t * Target register access for GDB.  Do @b not call this function\n\t * directly, use target_get_gdb_reg_list() instead.\n\t *\n\t * Danger! this function will succeed even if the target is running\n\t * and return a register list with dummy values.\n\t *\n\t * The reason is that GDB connection will fail without a valid register\n\t * list, however it is after GDB is connected that monitor commands can\n\t * be run to properly initialize the target\n\t */\n\tint (*get_gdb_reg_list)(struct target *target, struct reg **reg_list[],\n\t\t\tint *reg_list_size, enum target_register_class reg_class);\n\n\t/**\n\t * Same as get_gdb_reg_list, but doesn't read the register values.\n\t * */\n\tint (*get_gdb_reg_list_noread)(struct target *target,\n\t\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\t\tenum target_register_class reg_class);\n\n\t/* target memory access\n\t* size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)\n\t* count: number of items of <size>\n\t*/\n\n\t/**\n\t * Target memory read callback.  Do @b not call this function\n\t * directly, use target_read_memory() instead.\n\t */\n\tint (*read_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer);\n\t/**\n\t * Target memory write callback.  Do @b not call this function\n\t * directly, use target_write_memory() instead.\n\t */\n\tint (*write_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\n\n\t/* Default implementation will do some fancy alignment to improve performance, target can override */\n\tint (*read_buffer)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, uint8_t *buffer);\n\n\t/* Default implementation will do some fancy alignment to improve performance, target can override */\n\tint (*write_buffer)(struct target *target, target_addr_t address,\n\t\t\tuint32_t size, const uint8_t *buffer);\n\n\tint (*checksum_memory)(struct target *target, target_addr_t address,\n\t\t\tuint32_t count, uint32_t *checksum);\n\tint (*blank_check_memory)(struct target *target,\n\t\t\tstruct target_memory_check_block *blocks, int num_blocks,\n\t\t\tuint8_t erased_value);\n\n\t/*\n\t * target break-/watchpoint control\n\t * rw: 0 = write, 1 = read, 2 = access\n\t *\n\t * Target must be halted while this is invoked as this\n\t * will actually set up breakpoints on target.\n\t *\n\t * The breakpoint hardware will be set up upon adding the\n\t * first breakpoint.\n\t *\n\t * Upon GDB connection all breakpoints/watchpoints are cleared.\n\t */\n\tint (*add_breakpoint)(struct target *target, struct breakpoint *breakpoint);\n\tint (*add_context_breakpoint)(struct target *target, struct breakpoint *breakpoint);\n\tint (*add_hybrid_breakpoint)(struct target *target, struct breakpoint *breakpoint);\n\n\t/* remove breakpoint. hw will only be updated if the target\n\t * is currently halted.\n\t * However, this method can be invoked on unresponsive targets.\n\t */\n\tint (*remove_breakpoint)(struct target *target, struct breakpoint *breakpoint);\n\n\t/* add watchpoint ... see add_breakpoint() comment above. */\n\tint (*add_watchpoint)(struct target *target, struct watchpoint *watchpoint);\n\n\t/* remove watchpoint. hw will only be updated if the target\n\t * is currently halted.\n\t * However, this method can be invoked on unresponsive targets.\n\t */\n\tint (*remove_watchpoint)(struct target *target, struct watchpoint *watchpoint);\n\n\t/* Find out just hit watchpoint. After the target hits a watchpoint, the\n\t * information could assist gdb to locate where the modified/accessed memory is.\n\t */\n\tint (*hit_watchpoint)(struct target *target, struct watchpoint **hit_watchpoint);\n\n\t/**\n\t * Target algorithm support.  Do @b not call this method directly,\n\t * use target_run_algorithm() instead.\n\t */\n\tint (*run_algorithm)(struct target *target, int num_mem_params,\n\t\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\t\tstruct reg_param *reg_param, target_addr_t entry_point,\n\t\t\ttarget_addr_t exit_point, unsigned int timeout_ms, void *arch_info);\n\tint (*start_algorithm)(struct target *target, int num_mem_params,\n\t\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\t\tstruct reg_param *reg_param, target_addr_t entry_point,\n\t\t\ttarget_addr_t exit_point, void *arch_info);\n\tint (*wait_algorithm)(struct target *target, int num_mem_params,\n\t\t\tstruct mem_param *mem_params, int num_reg_params,\n\t\t\tstruct reg_param *reg_param, target_addr_t exit_point,\n\t\t\tunsigned int timeout_ms, void *arch_info);\n\n\tconst struct command_registration *commands;\n\n\t/* called when target is created */\n\tint (*target_create)(struct target *target, Jim_Interp *interp);\n\n\t/* called for various config parameters */\n\t/* returns JIM_CONTINUE - if option not understood */\n\t/* otherwise: JIM_OK, or JIM_ERR, */\n\tint (*target_jim_configure)(struct target *target, struct jim_getopt_info *goi);\n\n\t/* target commands specifically handled by the target */\n\t/* returns JIM_OK, or JIM_ERR, or JIM_CONTINUE - if option not understood */\n\tint (*target_jim_commands)(struct target *target, struct jim_getopt_info *goi);\n\n\t/**\n\t * This method is used to perform target setup that requires\n\t * JTAG access.\n\t *\n\t * This may be called multiple times.  It is called after the\n\t * scan chain is initially validated, or later after the target\n\t * is enabled by a JRC.  It may also be called during some\n\t * parts of the reset sequence.\n\t *\n\t * For one-time initialization tasks, use target_was_examined()\n\t * and target_set_examined().  For example, probe the hardware\n\t * before setting up chip-specific state, and then set that\n\t * flag so you don't do that again.\n\t */\n\tint (*examine)(struct target *target);\n\n\t/* Set up structures for target.\n\t *\n\t * It is illegal to talk to the target at this stage as this fn is invoked\n\t * before the JTAG chain has been examined/verified\n\t * */\n\tint (*init_target)(struct command_context *cmd_ctx, struct target *target);\n\n\t/**\n\t * Free all the resources allocated by the target.\n\t *\n\t * WARNING: deinit_target is called unconditionally regardless the target has\n\t * ever been examined/initialised or not.\n\t * If a problem has prevented establishing JTAG/SWD/... communication\n\t *  or\n\t * if the target was created with -defer-examine flag and has never been\n\t *  examined\n\t * then it is not possible to communicate with the target.\n\t *\n\t * If you need to talk to the target during deinit, first check if\n\t * target_was_examined()!\n\t *\n\t * @param target The target to deinit\n\t */\n\tvoid (*deinit_target)(struct target *target);\n\n\t/* translate from virtual to physical address. Default implementation is successful\n\t * no-op(i.e. virtual==physical).\n\t */\n\tint (*virt2phys)(struct target *target, target_addr_t address, target_addr_t *physical);\n\n\t/* read directly from physical memory. caches are bypassed and untouched.\n\t *\n\t * If the target does not support disabling caches, leaving them untouched,\n\t * then minimally the actual physical memory location will be read even\n\t * if cache states are unchanged, flushed, etc.\n\t *\n\t * Default implementation is to call read_memory.\n\t */\n\tint (*read_phys_memory)(struct target *target, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer);\n\n\t/*\n\t * same as read_phys_memory, except that it writes...\n\t */\n\tint (*write_phys_memory)(struct target *target, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\n\n\tint (*mmu)(struct target *target, int *enabled);\n\n\t/* after reset is complete, the target can check if things are properly set up.\n\t *\n\t * This can be used to check if e.g. DCC memory writes have been enabled for\n\t * arm7/9 targets, which they really should except in the most contrived\n\t * circumstances.\n\t */\n\tint (*check_reset)(struct target *target);\n\n\t/* get GDB file-I/O parameters from target\n\t */\n\tint (*get_gdb_fileio_info)(struct target *target, struct gdb_fileio_info *fileio_info);\n\n\t/* pass GDB file-I/O response to target\n\t */\n\tint (*gdb_fileio_end)(struct target *target, int retcode, int fileio_errno, bool ctrl_c);\n\n\t/* Parse target-specific GDB query commands.\n\t * The string pointer \"response_p\" is always assigned by the called function\n\t * to a pointer to a NULL-terminated string, even when the function returns\n\t * an error. The string memory is not freed by the caller, so this function\n\t * must pay attention for possible memory leaks if the string memory is\n\t * dynamically allocated.\n\t */\n\tint (*gdb_query_custom)(struct target *target, const char *packet, char **response_p);\n\n\t/* do target profiling\n\t */\n\tint (*profiling)(struct target *target, uint32_t *samples,\n\t\t\tuint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds);\n\n\t/* Return the number of address bits this target supports. This will\n\t * typically be 32 for 32-bit targets, and 64 for 64-bit targets. If not\n\t * implemented, it's assumed to be 32. */\n\tunsigned (*address_bits)(struct target *target);\n\n\t/* Return the number of system bus data bits this target supports. This\n\t * will typically be 32 for 32-bit targets, and 64 for 64-bit targets. If\n\t * not implemented, it's assumed to be 32. */\n\tunsigned int (*data_bits)(struct target *target);\n};\n\nextern struct target_type aarch64_target;\nextern struct target_type arcv2_target;\nextern struct target_type arm11_target;\nextern struct target_type arm720t_target;\nextern struct target_type arm7tdmi_target;\nextern struct target_type arm920t_target;\nextern struct target_type arm926ejs_target;\nextern struct target_type arm946e_target;\nextern struct target_type arm966e_target;\nextern struct target_type arm9tdmi_target;\nextern struct target_type armv8r_target;\nextern struct target_type avr32_ap7k_target;\nextern struct target_type avr_target;\nextern struct target_type cortexa_target;\nextern struct target_type cortexm_target;\nextern struct target_type cortexr4_target;\nextern struct target_type dragonite_target;\nextern struct target_type dsp563xx_target;\nextern struct target_type dsp5680xx_target;\nextern struct target_type esirisc_target;\nextern struct target_type esp32s2_target;\nextern struct target_type esp32s3_target;\nextern struct target_type esp32_target;\nextern struct target_type fa526_target;\nextern struct target_type feroceon_target;\nextern struct target_type hla_target;\nextern struct target_type ls1_sap_target;\nextern struct target_type mem_ap_target;\nextern struct target_type mips_m4k_target;\nextern struct target_type mips_mips64_target;\nextern struct target_type or1k_target;\nextern struct target_type quark_d20xx_target;\nextern struct target_type quark_x10xx_target;\nextern struct target_type riscv_target;\nextern struct target_type stm8_target;\nextern struct target_type testee_target;\nextern struct target_type xscale_target;\nextern struct target_type xtensa_chip_target;\n\n#endif /* OPENOCD_TARGET_TARGET_TYPE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/testee.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2009 Zachary T Welch <zw@superlucidity.net>             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"hello.h\"\n\nstatic const struct command_registration testee_command_handlers[] = {\n\t{\n\t\t.name = \"testee\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"testee target commands\",\n\t\t.chain = hello_command_handlers,\n\t\t.usage = \"\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic int testee_init(struct command_context *cmd_ctx, struct target *target)\n{\n\treturn ERROR_OK;\n}\nstatic int testee_poll(struct target *target)\n{\n\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))\n\t\ttarget->state = TARGET_HALTED;\n\treturn ERROR_OK;\n}\nstatic int testee_halt(struct target *target)\n{\n\ttarget->state = TARGET_HALTED;\n\treturn ERROR_OK;\n}\nstatic int testee_reset_assert(struct target *target)\n{\n\ttarget->state = TARGET_RESET;\n\treturn ERROR_OK;\n}\nstatic int testee_reset_deassert(struct target *target)\n{\n\ttarget->state = TARGET_RUNNING;\n\treturn ERROR_OK;\n}\nstruct target_type testee_target = {\n\t.name = \"testee\",\n\t.commands = testee_command_handlers,\n\n\t.init_target = &testee_init,\n\t.poll = &testee_poll,\n\t.halt = &testee_halt,\n\t.assert_reset = &testee_reset_assert,\n\t.deassert_reset = &testee_reset_deassert,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/trace.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n#include \"trace.h\"\n#include \"target.h\"\n\nint trace_point(struct target *target, uint32_t number)\n{\n\tstruct trace *trace = target->trace_info;\n\n\tLOG_DEBUG(\"tracepoint: %i\", (int)number);\n\n\tif (number < trace->num_trace_points)\n\t\ttrace->trace_points[number].hit_counter++;\n\n\tif (trace->trace_history_size) {\n\t\ttrace->trace_history[trace->trace_history_pos++] = number;\n\t\tif (trace->trace_history_pos == trace->trace_history_size) {\n\t\t\ttrace->trace_history_pos = 0;\n\t\t\ttrace->trace_history_overflowed = 1;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_trace_point_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct trace *trace = target->trace_info;\n\n\tif (CMD_ARGC == 0) {\n\t\tuint32_t i;\n\n\t\tfor (i = 0; i < trace->num_trace_points; i++) {\n\t\t\tcommand_print(CMD, \"trace point 0x%8.8\" PRIx32 \" (%lld times hit)\",\n\t\t\t\t\ttrace->trace_points[i].address,\n\t\t\t\t\t(long long)trace->trace_points[i].hit_counter);\n\t\t}\n\n\t\treturn ERROR_OK;\n\t}\n\n\tif (!strcmp(CMD_ARGV[0], \"clear\")) {\n\t\tfree(trace->trace_points);\n\t\ttrace->trace_points = NULL;\n\n\t\ttrace->num_trace_points = 0;\n\t\ttrace->trace_points_size = 0;\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* resize array if necessary */\n\tif (!trace->trace_points || (trace->trace_points_size == trace->num_trace_points)) {\n\t\ttrace->trace_points = realloc(trace->trace_points,\n\t\t\t\tsizeof(struct trace_point) * (trace->trace_points_size + 32));\n\t\ttrace->trace_points_size += 32;\n\t}\n\n\tuint32_t address;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\ttrace->trace_points[trace->num_trace_points].address = address;\n\ttrace->trace_points[trace->num_trace_points].hit_counter = 0;\n\ttrace->num_trace_points++;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_trace_history_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct trace *trace = target->trace_info;\n\n\tif (CMD_ARGC > 0) {\n\t\ttrace->trace_history_pos = 0;\n\t\ttrace->trace_history_overflowed = 0;\n\n\t\tif (!strcmp(CMD_ARGV[0], \"clear\")) {\n\t\t\t/* clearing is implicit, we've just reset position anyway */\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tfree(trace->trace_history);\n\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], trace->trace_history_size);\n\t\ttrace->trace_history = malloc(sizeof(uint32_t) * trace->trace_history_size);\n\n\t\tcommand_print(CMD, \"new trace history size: %i\", (int)(trace->trace_history_size));\n\t} else {\n\t\tuint32_t i;\n\t\tuint32_t first = 0;\n\t\tuint32_t last = trace->trace_history_pos;\n\n\t\tif (!trace->trace_history_size) {\n\t\t\tcommand_print(CMD, \"trace history buffer is not allocated\");\n\t\t\treturn ERROR_OK;\n\t\t}\n\n\t\tif (trace->trace_history_overflowed) {\n\t\t\tfirst = trace->trace_history_pos;\n\t\t\tlast = trace->trace_history_pos - 1;\n\t\t}\n\n\t\tfor (i = first; (i % trace->trace_history_size) != last; i++) {\n\t\t\tif (trace->trace_history[i % trace->trace_history_size] < trace->num_trace_points) {\n\t\t\t\tuint32_t address;\n\t\t\t\taddress = trace->trace_points[trace->trace_history[i % trace->trace_history_size]].address;\n\t\t\t\tcommand_print(CMD, \"trace point %i: 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\t\t(int)(trace->trace_history[i % trace->trace_history_size]),\n\t\t\t\t\t\taddress);\n\t\t\t} else\n\t\t\t\tcommand_print(CMD, \"trace point %i: -not defined-\",\n\t\t\t\t\t\t(int)(trace->trace_history[i % trace->trace_history_size]));\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration trace_exec_command_handlers[] = {\n\t{\n\t\t.name = \"history\",\n\t\t.handler = handle_trace_history_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display trace history, clear history or set size\",\n\t\t.usage = \"['clear'|size]\",\n\t},\n\t{\n\t\t.name = \"point\",\n\t\t.handler = handle_trace_point_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display trace points, clear list of trace points, \"\n\t\t\t\"or add new tracepoint at address\",\n\t\t.usage = \"['clear'|address]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration trace_command_handlers[] = {\n\t{\n\t\t.name = \"trace\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"trace command group\",\n\t\t.usage = \"\",\n\t\t.chain = trace_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint trace_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, trace_command_handlers);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/trace.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2007 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_TRACE_H\n#define OPENOCD_TARGET_TRACE_H\n\n#include \"helper/types.h\"\n\nstruct target;\nstruct command_context;\n\nstruct trace_point {\n\tuint32_t address;\n\tuint64_t hit_counter;\n};\n\nstruct trace {\n\tuint32_t num_trace_points;\n\tuint32_t trace_points_size;\n\tstruct trace_point *trace_points;\n\tuint32_t trace_history_size;\n\tuint32_t *trace_history;\n\tuint32_t trace_history_pos;\n\tint trace_history_overflowed;\n};\n\n/**\n * \\todo This enum is one of the few things in this file related\n * to *hardware* tracing ... split such \"real\" tracing out from\n * the contrib/libdcc support.\n */\ntypedef enum trace_status {\n\tTRACE_IDLE = 0x0,\n\tTRACE_RUNNING = 0x1,\n\tTRACE_TRIGGERED = 0x2,\n\tTRACE_COMPLETED = 0x4,\n\tTRACE_OVERFLOWED = 0x8,\n} trace_status_t;\n\nint trace_point(struct target *target, uint32_t number);\nint trace_register_commands(struct command_context *cmd_ctx);\n\n#define ERROR_TRACE_IMAGE_UNAVAILABLE\t\t(-1500)\n#define ERROR_TRACE_INSTRUCTION_UNAVAILABLE\t(-1501)\n\n#endif /* OPENOCD_TARGET_TRACE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/x86_32_common.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright(c) 2013 Intel Corporation.\n *\n * Adrian Burns (adrian.burns@intel.com)\n * Thomas Faust (thomas.faust@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n * Julien Carreno (julien.carreno@intel.com)\n * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * This implements generic x86 32 bit memory and breakpoint operations.\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <helper/log.h>\n\n#include \"target.h\"\n#include \"target_type.h\"\n#include \"register.h\"\n#include \"breakpoints.h\"\n#include \"x86_32_common.h\"\n\nstatic int set_debug_regs(struct target *t, uint32_t address,\n\t\t\tuint8_t bp_num, uint8_t bp_type, uint8_t bp_length);\nstatic int unset_debug_regs(struct target *t, uint8_t bp_num);\nstatic int read_mem(struct target *t, uint32_t size,\n\t\t\tuint32_t addr, uint8_t *buf);\nstatic int write_mem(struct target *t, uint32_t size,\n\t\t\tuint32_t addr, const uint8_t *buf);\nstatic int calcaddr_physfromlin(struct target *t, target_addr_t addr,\n\t\t\ttarget_addr_t *physaddr);\nstatic int read_phys_mem(struct target *t, uint32_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer);\nstatic int write_phys_mem(struct target *t, uint32_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\nstatic int set_breakpoint(struct target *target,\n\t\t\tstruct breakpoint *breakpoint);\nstatic int unset_breakpoint(struct target *target,\n\t\t\tstruct breakpoint *breakpoint);\nstatic int set_watchpoint(struct target *target,\n\t\t\tstruct watchpoint *watchpoint);\nstatic int unset_watchpoint(struct target *target,\n\t\t\tstruct watchpoint *watchpoint);\nstatic int read_hw_reg_to_cache(struct target *t, int num);\nstatic int write_hw_reg_from_cache(struct target *t, int num);\n\nint x86_32_get_gdb_reg_list(struct target *t,\n\t\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\t\tenum target_register_class reg_class)\n{\n\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tint i;\n\t*reg_list_size = x86_32->cache->num_regs;\n\tLOG_DEBUG(\"num_regs=%d, reg_class=%d\", (*reg_list_size), reg_class);\n\t*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));\n\tif (!*reg_list) {\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\t/* this will copy the values from our reg list to gdbs */\n\tfor (i = 0; i < (*reg_list_size); i++) {\n\t\t(*reg_list)[i] = &x86_32->cache->reg_list[i];\n\t\tLOG_DEBUG(\"value %s = %08\" PRIx32, x86_32->cache->reg_list[i].name,\n\t\t\t\tbuf_get_u32(x86_32->cache->reg_list[i].value, 0, 32));\n\t}\n\treturn ERROR_OK;\n}\n\nint x86_32_common_init_arch_info(struct target *t, struct x86_32_common *x86_32)\n{\n\tt->arch_info = x86_32;\n\tx86_32->common_magic = X86_32_COMMON_MAGIC;\n\tx86_32->num_hw_bpoints = MAX_DEBUG_REGS;\n\tx86_32->hw_break_list = calloc(x86_32->num_hw_bpoints,\n\t\t\t\tsizeof(struct x86_32_dbg_reg));\n\tif (!x86_32->hw_break_list) {\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tx86_32->curr_tap = t->tap;\n\tx86_32->fast_data_area = NULL;\n\tx86_32->flush = 1;\n\tx86_32->read_hw_reg_to_cache = read_hw_reg_to_cache;\n\tx86_32->write_hw_reg_from_cache = write_hw_reg_from_cache;\n\treturn ERROR_OK;\n}\n\nint x86_32_common_mmu(struct target *t, int *enabled)\n{\n\t*enabled = true;\n\treturn ERROR_OK;\n}\n\nint x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\t/*\n\t * We need to ignore 'segmentation' for now, as OpenOCD can't handle\n\t * segmented addresses.\n\t * In protected mode that is almost OK, as (almost) any known OS is using\n\t * flat segmentation. In real mode we use use the base of the DS segment,\n\t * as we don't know better ...\n\t */\n\n\tuint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32);\n\tif (!(cr0 & CR0_PG)) {\n\t\t/* target halted in real mode */\n\t\t/* TODO: needs validation !!! */\n\t\tuint32_t dsb = buf_get_u32(x86_32->cache->reg_list[DSB].value, 0, 32);\n\t\t*physical = dsb + address;\n\n\t} else {\n\t\t/* target halted in protected mode */\n\t\tif (calcaddr_physfromlin(t, address, physical) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to calculate physical address from \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nint x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tint error;\n\n\terror = read_phys_mem(t, phys_address, size, count, buffer);\n\tif (error != ERROR_OK)\n\t\treturn error;\n\n\t/* After reading memory from target, we must replace software breakpoints\n\t * with the original instructions again.\n\t */\n\tstruct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list;\n\twhile (iter) {\n\t\tif (iter->physaddr >= phys_address && iter->physaddr < phys_address+(size*count)) {\n\t\t\tuint32_t offset = iter->physaddr - phys_address;\n\t\t\tbuffer[offset] = iter->orig_byte;\n\t\t}\n\t\titer = iter->next;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int read_phys_mem(struct target *t, uint32_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tbool pg_disabled = false;\n\tLOG_DEBUG(\"addr=0x%08\" PRIx32 \", size=%\" PRIu32 \", count=0x%\" PRIx32 \", buf=%p\",\n\t\t\tphys_address, size, count, buffer);\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif (!count || !buffer || !phys_address) {\n\t\tLOG_ERROR(\"%s invalid params count=0x%\" PRIx32 \", buf=%p, addr=0x%08\" PRIx32,\n\t\t\t\t__func__, count, buffer, phys_address);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\t/* to access physical memory, switch off the CR0.PG bit */\n\tif (x86_32->is_paging_enabled(t)) {\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\tpg_disabled = true;\n\t}\n\n\tfor (uint32_t i = 0; i < count; i++) {\n\t\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tretval = read_mem(t, size, phys_address + i, buffer + i);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tretval = read_mem(t, size, phys_address + i * 2, buffer + i * 2);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tretval = read_mem(t, size, phys_address + i * 4, buffer + i * 4);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid read size\", __func__);\n\t\t\tbreak;\n\t\t}\n\t\tif (retval != ERROR_OK)\n\t\t\tbreak;\n\t}\n\t/* restore CR0.PG bit if needed (regardless of retval) */\n\tif (pg_disabled) {\n\t\tint retval2 = x86_32->enable_paging(t);\n\t\tif (retval2 != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval2;\n\t\t}\n\t}\n\t/* TODO: After reading memory from target, we must replace\n\t * software breakpoints with the original instructions again.\n\t * Solve this with the breakpoint fix\n\t */\n\treturn retval;\n}\n\nint x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tint error = ERROR_OK;\n\tuint8_t *newbuffer = NULL;\n\n\tcheck_not_halted(t);\n\tif (!count || !buffer || !phys_address) {\n\t\tLOG_ERROR(\"%s invalid params count=0x%\" PRIx32 \", buf=%p, addr=\" TARGET_ADDR_FMT,\n\t\t\t\t__func__, count, buffer, phys_address);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\t/* Before writing memory to target, we must update software breakpoints\n\t * with the new instructions and patch the memory buffer with the\n\t * breakpoint instruction.\n\t */\n\tnewbuffer = malloc(size*count);\n\tif (!newbuffer) {\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tmemcpy(newbuffer, buffer, size*count);\n\tstruct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list;\n\twhile (iter) {\n\t\tif (iter->physaddr >= phys_address && iter->physaddr < phys_address+(size*count)) {\n\t\t\tuint32_t offset = iter->physaddr - phys_address;\n\t\t\tnewbuffer[offset] = SW_BP_OPCODE;\n\n\t\t\t/* update the breakpoint */\n\t\t\tstruct breakpoint *pbiter = t->breakpoints;\n\t\t\twhile (pbiter && pbiter->unique_id != iter->swbp_unique_id)\n\t\t\t\tpbiter = pbiter->next;\n\t\t\tif (pbiter)\n\t\t\t\tpbiter->orig_instr[0] = buffer[offset];\n\t\t}\n\t\titer = iter->next;\n\t}\n\n\terror = write_phys_mem(t, phys_address, size, count, newbuffer);\n\tfree(newbuffer);\n\treturn error;\n}\n\nstatic int write_phys_mem(struct target *t, uint32_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tint retval = ERROR_OK;\n\tbool pg_disabled = false;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"addr=0x%08\" PRIx32 \", size=%\" PRIu32 \", count=0x%\" PRIx32 \", buf=%p\",\n\t\t\tphys_address, size, count, buffer);\n\n\tcheck_not_halted(t);\n\tif (!count || !buffer || !phys_address) {\n\t\tLOG_ERROR(\"%s invalid params count=0x%\" PRIx32 \", buf=%p, addr=0x%08\" PRIx32,\n\t\t\t\t__func__, count, buffer, phys_address);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\t/* TODO: Before writing memory to target, we must update\n\t * software breakpoints with the new instructions and\n\t * patch the memory buffer with the breakpoint instruction.\n\t * Solve this with the breakpoint fix\n\t */\n\n\t/* to access physical memory, switch off the CR0.PG bit */\n\tif (x86_32->is_paging_enabled(t)) {\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\tpg_disabled = true;\n\t}\n\tfor (uint32_t i = 0; i < count; i++) {\n\t\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tretval = write_mem(t, size, phys_address + i, buffer + i);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tretval = write_mem(t, size, phys_address + i * 2, buffer + i * 2);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tretval = write_mem(t, size, phys_address + i * 4, buffer + i * 4);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_DEBUG(\"invalid read size\");\n\t\t\tbreak;\n\t\t}\n\t}\n\t/* restore CR0.PG bit if needed (regardless of retval) */\n\tif (pg_disabled) {\n\t\tretval = x86_32->enable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t}\n\treturn retval;\n}\n\nstatic int read_mem(struct target *t, uint32_t size,\n\t\t\tuint32_t addr, uint8_t *buf)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\t/* if CS.D bit=1 then its a 32 bit code segment, else 16 */\n\tbool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D;\n\tint retval = x86_32->write_hw_reg(t, EAX, addr, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error write EAX\", __func__);\n\t\treturn retval;\n\t}\n\n\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDB32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDB16);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDH32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDH16);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDW32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMRDW16);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid read mem size\", __func__);\n\t\t\tbreak;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* read_hw_reg() will write to 4 bytes (uint32_t)\n\t * Watch out, the buffer passed into read_mem() might be 1 or 2 bytes.\n\t */\n\tuint32_t regval;\n\tretval = x86_32->read_hw_reg(t, EDX, &regval, 0);\n\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error read EDX\", __func__);\n\t\treturn retval;\n\t}\n\tfor (uint8_t i = 0; i < size; i++)\n\t\tbuf[i] = (regval >> (i*8)) & 0x000000FF;\n\n\tretval = x86_32->transaction_status(t);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on mem read\", __func__);\n\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nstatic int write_mem(struct target *t, uint32_t size,\n\t\t\tuint32_t addr, const uint8_t *buf)\n{\n\tuint32_t i = 0;\n\tuint32_t buf4bytes = 0;\n\tint retval = ERROR_OK;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tfor (i = 0; i < size; ++i) {\n\t\tbuf4bytes = buf4bytes << 8; /* first time we only shift 0s */\n\t\tbuf4bytes += buf[(size-1)-i]; /* it was hard to write, should be hard to read! */\n\t}\n\t/* if CS.D bit=1 then its a 32 bit code segment, else 16 */\n\tbool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D;\n\tretval = x86_32->write_hw_reg(t, EAX, addr, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error write EAX\", __func__);\n\t\treturn retval;\n\t}\n\n\t/* write_hw_reg() will write to 4 bytes (uint32_t)\n\t * Watch out, the buffer passed into write_mem() might be 1 or 2 bytes.\n\t */\n\tretval = x86_32->write_hw_reg(t, EDX, buf4bytes, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error write EDX\", __func__);\n\t\treturn retval;\n\t}\n\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRB32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRB16);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRH32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRH16);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRW32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, MEMWRW16);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid write mem size\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = x86_32->transaction_status(t);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on mem write\", __func__);\n\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nint calcaddr_physfromlin(struct target *t, target_addr_t addr, target_addr_t *physaddr)\n{\n\tuint8_t entry_buffer[8];\n\n\tif (!physaddr || !t)\n\t\treturn ERROR_FAIL;\n\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\t/* The 'user-visible' CR0.PG should be set - otherwise the function shouldn't be called\n\t * (Don't check the CR0.PG on the target, this might be temporally disabled at this point)\n\t */\n\tuint32_t cr0 = buf_get_u32(x86_32->cache->reg_list[CR0].value, 0, 32);\n\tif (!(cr0 & CR0_PG)) {\n\t\t/* you are wrong in this function, never mind */\n\t\t*physaddr = addr;\n\t\treturn ERROR_OK;\n\t}\n\n\tuint32_t cr4 = buf_get_u32(x86_32->cache->reg_list[CR4].value, 0, 32);\n\tbool is_pae = cr4 & 0x00000020; /* PAE - Physical Address Extension */\n\n\tuint32_t cr3 = buf_get_u32(x86_32->cache->reg_list[CR3].value, 0, 32);\n\tif (is_pae) {\n\t\tuint32_t pdpt_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */\n\t\tuint32_t pdpt_index = (addr & 0xC0000000) >> 30; /* A[31:30] index to PDPT */\n\t\tuint32_t pdpt_addr = pdpt_base + (8 * pdpt_index);\n\t\tif (x86_32_common_read_phys_mem(t, pdpt_addr, 4, 2, entry_buffer) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s couldn't read page directory pointer table entry at 0x%08\" PRIx32,\n\t\t\t\t\t__func__, pdpt_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tuint64_t pdpt_entry = target_buffer_get_u64(t, entry_buffer);\n\t\tif (!(pdpt_entry & 0x0000000000000001)) {\n\t\t\tLOG_ERROR(\"%s page directory pointer table entry at 0x%08\" PRIx32 \" is not present\",\n\t\t\t\t\t__func__, pdpt_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\tuint32_t pd_base = pdpt_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */\n\t\tuint32_t pd_index = (addr & 0x3FE00000) >> 21; /* A[29:21] index to PD entry with PAE */\n\t\tuint32_t pd_addr = pd_base + (8 * pd_index);\n\t\tif (x86_32_common_read_phys_mem(t, pd_addr, 4, 2, entry_buffer) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s couldn't read page directory entry at 0x%08\" PRIx32,\n\t\t\t\t\t__func__, pd_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tuint64_t pd_entry = target_buffer_get_u64(t, entry_buffer);\n\t\tif (!(pd_entry & 0x0000000000000001)) {\n\t\t\tLOG_ERROR(\"%s page directory entry at 0x%08\" PRIx32 \" is not present\",\n\t\t\t\t\t__func__, pd_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* PS bit in PD entry is indicating 4KB or 2MB page size */\n\t\tif (pd_entry & 0x0000000000000080) {\n\n\t\t\tuint32_t page_base = (uint32_t)(pd_entry & 0x00000000FFE00000); /* [31:21] */\n\t\t\tuint32_t offset = addr & 0x001FFFFF; /* [20:0] */\n\t\t\t*physaddr = page_base + offset;\n\t\t\treturn ERROR_OK;\n\n\t\t} else {\n\n\t\t\tuint32_t pt_base = (uint32_t)(pd_entry & 0x00000000FFFFF000); /*[31:12]*/\n\t\t\tuint32_t pt_index = (addr & 0x001FF000) >> 12; /*[20:12]*/\n\t\t\tuint32_t pt_addr = pt_base + (8 * pt_index);\n\t\t\tif (x86_32_common_read_phys_mem(t, pt_addr, 4, 2, entry_buffer) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s couldn't read page table entry at 0x%08\" PRIx32, __func__, pt_addr);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tuint64_t pt_entry = target_buffer_get_u64(t, entry_buffer);\n\t\t\tif (!(pt_entry & 0x0000000000000001)) {\n\t\t\t\tLOG_ERROR(\"%s page table entry at 0x%08\" PRIx32 \" is not present\", __func__, pt_addr);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\n\t\t\tuint32_t page_base = (uint32_t)(pt_entry & 0x00000000FFFFF000); /*[31:12]*/\n\t\t\tuint32_t offset =  addr & 0x00000FFF; /*[11:0]*/\n\t\t\t*physaddr = page_base + offset;\n\t\t\treturn ERROR_OK;\n\t\t}\n\t} else {\n\t\tuint32_t pd_base = cr3 & 0xFFFFF000; /* lower 12 bits of CR3 must always be 0 */\n\t\tuint32_t pd_index = (addr & 0xFFC00000) >> 22; /* A[31:22] index to PD entry */\n\t\tuint32_t pd_addr = pd_base + (4 * pd_index);\n\t\tif (x86_32_common_read_phys_mem(t, pd_addr, 4, 1, entry_buffer) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s couldn't read page directory entry at 0x%08\" PRIx32, __func__, pd_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tuint32_t pd_entry = target_buffer_get_u32(t, entry_buffer);\n\t\tif (!(pd_entry & 0x00000001)) {\n\t\t\tLOG_ERROR(\"%s page directory entry at 0x%08\" PRIx32 \" is not present\", __func__, pd_addr);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\t/* Bit 7 in page directory entry is page size.\n\t\t */\n\t\tif (pd_entry & 0x00000080) {\n\t\t\t/* 4MB pages */\n\t\t\tuint32_t page_base = pd_entry & 0xFFC00000;\n\t\t\t*physaddr = page_base + (addr & 0x003FFFFF);\n\n\t\t} else {\n\t\t\t/* 4KB pages */\n\t\t\tuint32_t pt_base = pd_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */\n\t\t\tuint32_t pt_index = (addr & 0x003FF000) >> 12; /* A[21:12] index to page table entry */\n\t\t\tuint32_t pt_addr = pt_base + (4 * pt_index);\n\t\t\tif (x86_32_common_read_phys_mem(t, pt_addr, 4, 1, entry_buffer) != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s couldn't read page table entry at 0x%08\" PRIx32, __func__, pt_addr);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tuint32_t pt_entry = target_buffer_get_u32(t, entry_buffer);\n\t\t\tif (!(pt_entry & 0x00000001)) {\n\t\t\t\tLOG_ERROR(\"%s page table entry at 0x%08\" PRIx32 \" is not present\", __func__, pt_addr);\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tuint32_t page_base = pt_entry & 0xFFFFF000; /* A[31:12] is PageTable/Page Base Address */\n\t\t\t*physaddr = page_base + (addr & 0x00000FFF); /* A[11:0] offset to 4KB page in linear address */\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nint x86_32_common_read_memory(struct target *t, target_addr_t addr,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buf)\n{\n\tint retval = ERROR_OK;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"addr=\" TARGET_ADDR_FMT \", size=%\" PRIu32 \", count=0x%\" PRIx32 \", buf=%p\",\n\t\t\taddr, size, count, buf);\n\tcheck_not_halted(t);\n\tif (!count || !buf || !addr) {\n\t\tLOG_ERROR(\"%s invalid params count=0x%\" PRIx32 \", buf=%p, addr=\" TARGET_ADDR_FMT,\n\t\t\t\t__func__, count, buf, addr);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (x86_32->is_paging_enabled(t)) {\n\t\t/* all memory accesses from debugger must be physical (CR0.PG == 0)\n\t\t * conversion to physical address space needed\n\t\t */\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\ttarget_addr_t physaddr = 0;\n\t\tif (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to calculate physical address from \" TARGET_ADDR_FMT,\n\t\t\t\t\t  __func__, addr);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t\t/* TODO: !!! Watch out for page boundaries\n\t\t * for every 4kB, the physical address has to be re-calculated\n\t\t * This should be fixed together with bulk memory reads\n\t\t */\n\n\t\tif (retval == ERROR_OK\n\t\t\t&& x86_32_common_read_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to read memory from physical address \" TARGET_ADDR_FMT,\n\t\t\t\t\t  __func__, physaddr);\n\t\t}\n\t\t/* restore PG bit if it was cleared prior (regardless of retval) */\n\t\tretval = x86_32->enable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t} else {\n\t\t/* paging is off - linear address is physical address */\n\t\tif (x86_32_common_read_phys_mem(t, addr, size, count, buf) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to read memory from address \" TARGET_ADDR_FMT,\n\t\t\t\t\t  __func__, addr);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\n\treturn retval;\n}\n\nint x86_32_common_write_memory(struct target *t, target_addr_t addr,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buf)\n{\n\tint retval = ERROR_OK;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"addr=\" TARGET_ADDR_FMT \", size=%\" PRIu32 \", count=0x%\" PRIx32 \", buf=%p\",\n\t\t\taddr, size, count, buf);\n\tcheck_not_halted(t);\n\tif (!count || !buf || !addr) {\n\t\tLOG_ERROR(\"%s invalid params count=0x%\" PRIx32 \", buf=%p, addr=\" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, count, buf, addr);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\tif (x86_32->is_paging_enabled(t)) {\n\t\t/* all memory accesses from debugger must be physical (CR0.PG == 0)\n\t\t * conversion to physical address space needed\n\t\t */\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\ttarget_addr_t physaddr = 0;\n\t\tif (calcaddr_physfromlin(t, addr, &physaddr) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to calculate physical address from \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, addr);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t\t/* TODO: !!! Watch out for page boundaries\n\t\t * for every 4kB, the physical address has to be re-calculated\n\t\t * This should be fixed together with bulk memory reads\n\t\t */\n\t\tif (retval == ERROR_OK\n\t\t\t&& x86_32_common_write_phys_mem(t, physaddr, size, count, buf) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to write memory to physical address \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, physaddr);\n\t\t}\n\t\t/* restore PG bit if it was cleared prior (regardless of retval) */\n\t\tretval = x86_32->enable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t} else {\n\n\t\t/* paging is off - linear address is physical address */\n\t\tif (x86_32_common_write_phys_mem(t, addr, size, count, buf) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s failed to write memory to address \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, addr);\n\t\t\tretval = ERROR_FAIL;\n\t\t}\n\t}\n\treturn retval;\n}\n\nint x86_32_common_read_io(struct target *t, uint32_t addr,\n\t\t\tuint32_t size, uint8_t *buf)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\t/* if CS.D bit=1 then its a 32 bit code segment, else 16 */\n\tbool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D;\n\tint retval = ERROR_FAIL;\n\tbool pg_disabled = false;\n\tLOG_DEBUG(\"addr=0x%08\" PRIx32 \", size=%\" PRIu32 \", buf=%p\", addr, size, buf);\n\tcheck_not_halted(t);\n\tif (!buf || !addr) {\n\t\tLOG_ERROR(\"%s invalid params buf=%p, addr=%08\" PRIx32, __func__, buf, addr);\n\t\treturn retval;\n\t}\n\tretval = x86_32->write_hw_reg(t, EDX, addr, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error EDX write\", __func__);\n\t\treturn retval;\n\t}\n\t/* to access physical memory, switch off the CR0.PG bit */\n\tif (x86_32->is_paging_enabled(t)) {\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\tpg_disabled = true;\n\t}\n\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDB32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDB16);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDH32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDH16);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDW32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IORDW16);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid read io size\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* restore CR0.PG bit if needed */\n\tif (pg_disabled) {\n\t\tint retval2 = x86_32->enable_paging(t);\n\t\tif (retval2 != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval2;\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tuint32_t regval = 0;\n\tretval = x86_32->read_hw_reg(t, EAX, &regval, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on read EAX\", __func__);\n\t\treturn retval;\n\t}\n\tfor (uint8_t i = 0; i < size; i++)\n\t\tbuf[i] = (regval >> (i*8)) & 0x000000FF;\n\tretval = x86_32->transaction_status(t);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on io read\", __func__);\n\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nint x86_32_common_write_io(struct target *t, uint32_t addr,\n\t\t\tuint32_t size, const uint8_t *buf)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\t/* if CS.D bit=1 then its a 32 bit code segment, else 16 */\n\tbool use32 = (buf_get_u32(x86_32->cache->reg_list[CSAR].value, 0, 32)) & CSAR_D;\n\tLOG_DEBUG(\"addr=0x%08\" PRIx32 \", size=%\" PRIu32 \", buf=%p\", addr, size, buf);\n\tcheck_not_halted(t);\n\tint retval = ERROR_FAIL;\n\tbool pg_disabled = false;\n\tif (!buf || !addr) {\n\t\tLOG_ERROR(\"%s invalid params buf=%p, addr=0x%08\" PRIx32, __func__, buf, addr);\n\t\treturn retval;\n\t}\n\t/* no do the write */\n\tretval = x86_32->write_hw_reg(t, EDX, addr, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on EDX write\", __func__);\n\t\treturn retval;\n\t}\n\tuint32_t regval = 0;\n\tfor (uint8_t i = 0; i < size; i++)\n\t\tregval += (buf[i] << (i*8));\n\tretval = x86_32->write_hw_reg(t, EAX, regval, 0);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on EAX write\", __func__);\n\t\treturn retval;\n\t}\n\t/* to access physical memory, switch off the CR0.PG bit */\n\tif (x86_32->is_paging_enabled(t)) {\n\t\tretval = x86_32->disable_paging(t);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not disable paging\", __func__);\n\t\t\treturn retval;\n\t\t}\n\t\tpg_disabled = true;\n\t}\n\tswitch (size) {\n\t\tcase BYTE:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRB32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRB16);\n\t\t\tbreak;\n\t\tcase WORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRH32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRH16);\n\t\t\tbreak;\n\t\tcase DWORD:\n\t\t\tif (use32)\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRW32);\n\t\t\telse\n\t\t\t\tretval = x86_32->submit_instruction(t, IOWRW16);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid write io size\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* restore CR0.PG bit if needed */\n\tif (pg_disabled) {\n\t\tint retval2 = x86_32->enable_paging(t);\n\t\tif (retval2 != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s could not enable paging\", __func__);\n\t\t\treturn retval2;\n\t\t}\n\t}\n\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tretval = x86_32->transaction_status(t);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"%s error on io write\", __func__);\n\t\treturn retval;\n\t}\n\treturn retval;\n}\n\nint x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp)\n{\n\tcheck_not_halted(t);\n\t/* set_watchpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all\n\t * hardware registers are gone\n\t */\n\treturn set_watchpoint(t, wp);\n}\n\nint x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp)\n{\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif (wp->is_set)\n\t\tunset_watchpoint(t, wp);\n\treturn ERROR_OK;\n}\n\nint x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp)\n{\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, bp->type, bp->address);\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t/* set_breakpoint() will return ERROR_TARGET_RESOURCE_NOT_AVAILABLE if all\n\t * hardware registers are gone (for hardware breakpoints)\n\t */\n\treturn set_breakpoint(t, bp);\n}\n\nint x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp)\n{\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, bp->type, bp->address);\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif (bp->is_set)\n\t\tunset_breakpoint(t, bp);\n\n\treturn ERROR_OK;\n}\n\nstatic int set_debug_regs(struct target *t, uint32_t address,\n\t\t\tuint8_t bp_num, uint8_t bp_type, uint8_t bp_length)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"addr=0x%08\" PRIx32 \", bp_num=%\" PRIu8 \", bp_type=%\" PRIu8 \", pb_length=%\" PRIu8,\n\t\t\taddress, bp_num, bp_type, bp_length);\n\n\t/* DR7 - set global enable */\n\tuint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32);\n\n\tif (bp_length != 1 && bp_length != 2 && bp_length != 4)\n\t\treturn ERROR_FAIL;\n\n\tif (DR7_BP_FREE(dr7, bp_num))\n\t\tDR7_GLOBAL_ENABLE(dr7, bp_num);\n\telse {\n\t\tLOG_ERROR(\"%s dr7 error, already enabled, val=%08\" PRIx32, __func__, dr7);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tswitch (bp_type) {\n\t\tcase 0:\n\t\t\t/* 00 - only on instruction execution */\n\t\t\tDR7_SET_EXE(dr7, bp_num);\n\t\t\tDR7_SET_LENGTH(dr7, bp_num, bp_length);\n\t\tbreak;\n\t\tcase 1:\n\t\t\t/* 01 - only on data writes */\n\t\t\tDR7_SET_WRITE(dr7, bp_num);\n\t\t\tDR7_SET_LENGTH(dr7, bp_num, bp_length);\n\t\tbreak;\n\t\tcase 2:\n\t\t\t/* 10 UNSUPPORTED - an I/O read and I/O write */\n\t\t\tLOG_ERROR(\"%s unsupported feature bp_type=%d\", __func__, bp_type);\n\t\t\treturn ERROR_FAIL;\n\t\tbreak;\n\t\tcase 3:\n\t\t\t/* on data read or data write */\n\t\t\tDR7_SET_ACCESS(dr7, bp_num);\n\t\t\tDR7_SET_LENGTH(dr7, bp_num, bp_length);\n\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s invalid request [only 0-3] bp_type=%d\", __func__, bp_type);\n\t\t\treturn ERROR_FAIL;\n\t}\n\n\t/* update regs in the reg cache ready to be written to hardware\n\t * when we exit PM\n\t*/\n\tbuf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, address);\n\tx86_32->cache->reg_list[bp_num+DR0].dirty = true;\n\tx86_32->cache->reg_list[bp_num+DR0].valid = true;\n\tbuf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6);\n\tx86_32->cache->reg_list[DR6].dirty = true;\n\tx86_32->cache->reg_list[DR6].valid = true;\n\tbuf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7);\n\tx86_32->cache->reg_list[DR7].dirty = true;\n\tx86_32->cache->reg_list[DR7].valid = true;\n\treturn ERROR_OK;\n}\n\nstatic int unset_debug_regs(struct target *t, uint8_t bp_num)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"bp_num=%\" PRIu8, bp_num);\n\n\tuint32_t dr7 = buf_get_u32(x86_32->cache->reg_list[DR7].value, 0, 32);\n\n\tif (!(DR7_BP_FREE(dr7, bp_num))) {\n\t\tDR7_GLOBAL_DISABLE(dr7, bp_num);\n\t} else {\n\t\tLOG_ERROR(\"%s dr7 error, not enabled, val=0x%08\" PRIx32, __func__, dr7);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\t/* this will clear rw and len bits */\n\tDR7_RESET_RWLEN_BITS(dr7, bp_num);\n\n\t/* update regs in the reg cache ready to be written to hardware\n\t * when we exit PM\n\t*/\n\tbuf_set_u32(x86_32->cache->reg_list[bp_num+DR0].value, 0, 32, 0);\n\tx86_32->cache->reg_list[bp_num+DR0].dirty = true;\n\tx86_32->cache->reg_list[bp_num+DR0].valid = true;\n\tbuf_set_u32(x86_32->cache->reg_list[DR6].value, 0, 32, PM_DR6);\n\tx86_32->cache->reg_list[DR6].dirty = true;\n\tx86_32->cache->reg_list[DR6].valid = true;\n\tbuf_set_u32(x86_32->cache->reg_list[DR7].value, 0, 32, dr7);\n\tx86_32->cache->reg_list[DR7].dirty = true;\n\tx86_32->cache->reg_list[DR7].valid = true;\n\treturn ERROR_OK;\n}\n\nstatic int set_hwbp(struct target *t, struct breakpoint *bp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;\n\tuint8_t hwbp_num = 0;\n\n\twhile (debug_reg_list[hwbp_num].used && (hwbp_num < x86_32->num_hw_bpoints))\n\t\thwbp_num++;\n\tif (hwbp_num >= x86_32->num_hw_bpoints) {\n\t\tLOG_ERROR(\"%s no free hw breakpoint bpid=0x%\" PRIx32, __func__, bp->unique_id);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tif (set_debug_regs(t, bp->address, hwbp_num, DR7_BP_EXECUTE, 1) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tbreakpoint_hw_set(bp, hwbp_num);\n\tdebug_reg_list[hwbp_num].used = 1;\n\tdebug_reg_list[hwbp_num].bp_value = bp->address;\n\tLOG_USER(\"%s hardware breakpoint %\" PRIu32 \" set at 0x%08\" PRIx32 \" (hwreg=%\" PRIu8 \")\", __func__,\n\t\t\tbp->unique_id, debug_reg_list[hwbp_num].bp_value, hwbp_num);\n\treturn ERROR_OK;\n}\n\nstatic int unset_hwbp(struct target *t, struct breakpoint *bp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;\n\tint hwbp_num = bp->number;\n\n\tif (hwbp_num >= x86_32->num_hw_bpoints) {\n\t\tLOG_ERROR(\"%s invalid breakpoint number=%d, bpid=%\" PRIu32,\n\t\t\t\t__func__, hwbp_num, bp->unique_id);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (unset_debug_regs(t, hwbp_num) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tdebug_reg_list[hwbp_num].used = 0;\n\tdebug_reg_list[hwbp_num].bp_value = 0;\n\n\tLOG_USER(\"%s hardware breakpoint %\" PRIu32 \" removed from \" TARGET_ADDR_FMT \" (hwreg=%d)\",\n\t\t\t__func__, bp->unique_id, bp->address, hwbp_num);\n\treturn ERROR_OK;\n}\n\nstatic int set_swbp(struct target *t, struct breakpoint *bp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"id %\" PRIx32, bp->unique_id);\n\ttarget_addr_t physaddr;\n\tuint8_t opcode = SW_BP_OPCODE;\n\tuint8_t readback;\n\n\tif (calcaddr_physfromlin(t, bp->address, &physaddr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (read_phys_mem(t, physaddr, 1, 1, bp->orig_instr))\n\t\treturn ERROR_FAIL;\n\n\tLOG_DEBUG(\"set software breakpoint - orig byte=0x%02\" PRIx8 \"\", *bp->orig_instr);\n\n\t/* just write the instruction trap byte */\n\tif (write_phys_mem(t, physaddr, 1, 1, &opcode))\n\t\treturn ERROR_FAIL;\n\n\t/* verify that this is not invalid/read-only memory */\n\tif (read_phys_mem(t, physaddr, 1, 1, &readback))\n\t\treturn ERROR_FAIL;\n\n\tif (readback != SW_BP_OPCODE) {\n\t\tLOG_ERROR(\"%s software breakpoint error at \" TARGET_ADDR_FMT \", check memory\",\n\t\t\t\t__func__, bp->address);\n\t\tLOG_ERROR(\"%s readback=0x%02\" PRIx8 \" orig=0x%02\" PRIx8 \"\",\n\t\t\t\t__func__, readback, *bp->orig_instr);\n\t\treturn ERROR_FAIL;\n\t}\n\tbp->is_set = true;\n\n\t/* add the memory patch */\n\tstruct swbp_mem_patch *new_patch = malloc(sizeof(struct swbp_mem_patch));\n\tif (!new_patch) {\n\t\tLOG_ERROR(\"%s out of memory\", __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tnew_patch->next = NULL;\n\tnew_patch->orig_byte = *bp->orig_instr;\n\tnew_patch->physaddr = physaddr;\n\tnew_patch->swbp_unique_id = bp->unique_id;\n\n\tstruct swbp_mem_patch *addto = x86_32->swbbp_mem_patch_list;\n\tif (!addto)\n\t\tx86_32->swbbp_mem_patch_list = new_patch;\n\telse {\n\t\twhile (addto->next)\n\t\t\taddto = addto->next;\n\t\taddto->next = new_patch;\n\t}\n\tLOG_USER(\"%s software breakpoint %\" PRIu32 \" set at \" TARGET_ADDR_FMT,\n\t\t\t__func__, bp->unique_id, bp->address);\n\treturn ERROR_OK;\n}\n\nstatic int unset_swbp(struct target *t, struct breakpoint *bp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"id %\" PRIx32, bp->unique_id);\n\ttarget_addr_t physaddr;\n\tuint8_t current_instr;\n\n\t/* check that user program has not modified breakpoint instruction */\n\tif (calcaddr_physfromlin(t, bp->address, &physaddr) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\tif (read_phys_mem(t, physaddr, 1, 1, &current_instr))\n\t\treturn ERROR_FAIL;\n\n\tif (current_instr == SW_BP_OPCODE) {\n\t\tif (write_phys_mem(t, physaddr, 1, 1, bp->orig_instr))\n\t\t\treturn ERROR_FAIL;\n\t} else {\n\t\tLOG_ERROR(\"%s software breakpoint remove error at \" TARGET_ADDR_FMT \", check memory\",\n\t\t\t\t__func__, bp->address);\n\t\tLOG_ERROR(\"%s current=0x%02\" PRIx8 \" orig=0x%02\" PRIx8 \"\",\n\t\t\t\t__func__, current_instr, *bp->orig_instr);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* remove from patch */\n\tstruct swbp_mem_patch *iter = x86_32->swbbp_mem_patch_list;\n\tif (iter) {\n\t\tif (iter->swbp_unique_id == bp->unique_id) {\n\t\t\t/* it's the first item */\n\t\t\tx86_32->swbbp_mem_patch_list = iter->next;\n\t\t\tfree(iter);\n\t\t} else {\n\t\t\twhile (iter->next && iter->next->swbp_unique_id != bp->unique_id)\n\t\t\t\titer = iter->next;\n\t\t\tif (iter->next) {\n\t\t\t\t/* it's the next one */\n\t\t\t\tstruct swbp_mem_patch *freeme = iter->next;\n\t\t\t\titer->next = iter->next->next;\n\t\t\t\tfree(freeme);\n\t\t\t}\n\t\t}\n\t}\n\n\tLOG_USER(\"%s software breakpoint %\" PRIu32 \" removed from \" TARGET_ADDR_FMT,\n\t\t\t__func__, bp->unique_id, bp->address);\n\treturn ERROR_OK;\n}\n\nstatic int set_breakpoint(struct target *t, struct breakpoint *bp)\n{\n\tint error = ERROR_OK;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, bp->type, bp->address);\n\tif (bp->is_set) {\n\t\tLOG_ERROR(\"breakpoint already set\");\n\t\treturn error;\n\t}\n\tif (bp->type == BKPT_HARD) {\n\t\terror = set_hwbp(t, bp);\n\t\tif (error != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s error setting hardware breakpoint at \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, bp->address);\n\t\t\treturn error;\n\t\t}\n\t} else {\n\t\tif (x86_32->sw_bpts_supported(t)) {\n\t\t\terror = set_swbp(t, bp);\n\t\t\tif (error != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"%s error setting software breakpoint at \" TARGET_ADDR_FMT,\n\t\t\t\t\t\t__func__, bp->address);\n\t\t\t\treturn error;\n\t\t\t}\n\t\t} else {\n\t\t\tLOG_ERROR(\"%s core doesn't support SW breakpoints\", __func__);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\treturn error;\n}\n\nstatic int unset_breakpoint(struct target *t, struct breakpoint *bp)\n{\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, bp->type, bp->address);\n\tif (!bp->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (bp->type == BKPT_HARD) {\n\t\tif (unset_hwbp(t, bp) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s error removing hardware breakpoint at \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, bp->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t} else {\n\t\tif (unset_swbp(t, bp) != ERROR_OK) {\n\t\t\tLOG_ERROR(\"%s error removing software breakpoint at \" TARGET_ADDR_FMT,\n\t\t\t\t\t__func__, bp->address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\tbp->is_set = false;\n\treturn ERROR_OK;\n}\n\nstatic int set_watchpoint(struct target *t, struct watchpoint *wp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;\n\tint wp_num = 0;\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, wp->rw, wp->address);\n\n\tif (wp->is_set) {\n\t\tLOG_ERROR(\"%s watchpoint already set\", __func__);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (wp->rw == WPT_READ) {\n\t\tLOG_ERROR(\"%s no support for 'read' watchpoints, use 'access' or 'write'\"\n\t\t\t\t, __func__);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\twhile (debug_reg_list[wp_num].used && (wp_num < x86_32->num_hw_bpoints))\n\t\twp_num++;\n\tif (wp_num >= x86_32->num_hw_bpoints) {\n\t\tLOG_ERROR(\"%s no debug registers left\", __func__);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (wp->length != 4 && wp->length != 2 && wp->length != 1) {\n\t\tLOG_ERROR(\"%s only watchpoints of length 1, 2 or 4 are supported\", __func__);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tswitch (wp->rw) {\n\t\tcase WPT_WRITE:\n\t\t\tif (set_debug_regs(t, wp->address, wp_num,\n\t\t\t\t\t\tDR7_BP_WRITE, wp->length) != ERROR_OK) {\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tif (set_debug_regs(t, wp->address, wp_num, DR7_BP_READWRITE,\n\t\t\t\t\t\twp->length) != ERROR_OK) {\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"%s only 'access' or 'write' watchpoints are supported\", __func__);\n\t\t\tbreak;\n\t}\n\twatchpoint_set(wp, wp_num);\n\tdebug_reg_list[wp_num].used = 1;\n\tdebug_reg_list[wp_num].bp_value = wp->address;\n\tLOG_USER(\"'%s' watchpoint %d set at \" TARGET_ADDR_FMT \" with length %\" PRIu32 \" (hwreg=%d)\",\n\t\t\twp->rw == WPT_READ ? \"read\" : wp->rw == WPT_WRITE ?\n\t\t\t\"write\" : wp->rw == WPT_ACCESS ? \"access\" : \"?\",\n\t\t\twp->unique_id, wp->address, wp->length, wp_num);\n\treturn ERROR_OK;\n}\n\nstatic int unset_watchpoint(struct target *t, struct watchpoint *wp)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;\n\tLOG_DEBUG(\"type=%d, addr=\" TARGET_ADDR_FMT, wp->rw, wp->address);\n\tif (!wp->is_set) {\n\t\tLOG_WARNING(\"watchpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tint wp_num = wp->number;\n\tif (wp_num >= x86_32->num_hw_bpoints) {\n\t\tLOG_DEBUG(\"Invalid FP Comparator number in watchpoint\");\n\t\treturn ERROR_OK;\n\t}\n\tif (unset_debug_regs(t, wp_num) != ERROR_OK)\n\t\treturn ERROR_FAIL;\n\n\tdebug_reg_list[wp_num].used = 0;\n\tdebug_reg_list[wp_num].bp_value = 0;\n\twp->is_set = false;\n\n\tLOG_USER(\"'%s' watchpoint %d removed from \" TARGET_ADDR_FMT \" with length %\" PRIu32 \" (hwreg=%d)\",\n\t\t\twp->rw == WPT_READ ? \"read\" : wp->rw == WPT_WRITE ?\n\t\t\t\"write\" : wp->rw == WPT_ACCESS ? \"access\" : \"?\",\n\t\t\twp->unique_id, wp->address, wp->length, wp_num);\n\n\treturn ERROR_OK;\n}\n\n/* after reset breakpoints and watchpoints in memory are not valid anymore and\n * debug registers are cleared.\n * we can't afford to remove sw breakpoints using the default methods as the\n * memory doesn't have the same layout yet and an access might crash the target,\n * so we just clear the openocd breakpoints structures.\n */\nvoid x86_32_common_reset_breakpoints_watchpoints(struct target *t)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tstruct x86_32_dbg_reg *debug_reg_list = x86_32->hw_break_list;\n\tstruct breakpoint *next_b;\n\tstruct watchpoint *next_w;\n\n\twhile (t->breakpoints) {\n\t\tnext_b = t->breakpoints->next;\n\t\tfree(t->breakpoints->orig_instr);\n\t\tfree(t->breakpoints);\n\t\tt->breakpoints = next_b;\n\t}\n\n\twhile (t->watchpoints) {\n\t\tnext_w = t->watchpoints->next;\n\t\tfree(t->watchpoints);\n\t\tt->watchpoints = next_w;\n\t}\n\n\tfor (int i = 0; i < x86_32->num_hw_bpoints; i++) {\n\t\tdebug_reg_list[i].used = 0;\n\t\tdebug_reg_list[i].bp_value = 0;\n\t}\n}\n\nstatic int read_hw_reg_to_cache(struct target *t, int num)\n{\n\tuint32_t reg_value;\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif ((num < 0) || (num >= x86_32->get_num_user_regs(t)))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (x86_32->read_hw_reg(t, num, &reg_value, 1) != ERROR_OK) {\n\t\tLOG_ERROR(\"%s fail for %s\", x86_32->cache->reg_list[num].name, __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"reg %s value 0x%08\" PRIx32,\n\t\t\tx86_32->cache->reg_list[num].name, reg_value);\n\treturn ERROR_OK;\n}\n\nstatic int write_hw_reg_from_cache(struct target *t, int num)\n{\n\tstruct x86_32_common *x86_32 = target_to_x86_32(t);\n\tif (check_not_halted(t))\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif ((num < 0) || (num >= x86_32->get_num_user_regs(t)))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tif (x86_32->write_hw_reg(t, num, 0, 1) != ERROR_OK) {\n\t\tLOG_ERROR(\"%s fail for %s\", x86_32->cache->reg_list[num].name, __func__);\n\t\treturn ERROR_FAIL;\n\t}\n\tLOG_DEBUG(\"reg %s value 0x%08\" PRIx32, x86_32->cache->reg_list[num].name,\n\t\t\tbuf_get_u32(x86_32->cache->reg_list[num].value, 0, 32));\n\treturn ERROR_OK;\n}\n\n/* x86 32 commands */\nstatic void handle_iod_output(struct command_invocation *cmd,\n\t\tstruct target *target, uint32_t address, unsigned size,\n\t\tunsigned count, const uint8_t *buffer)\n{\n\tconst unsigned line_bytecnt = 32;\n\tunsigned line_modulo = line_bytecnt / size;\n\n\tchar output[line_bytecnt * 4 + 1];\n\tunsigned output_len = 0;\n\n\tconst char *value_fmt;\n\tswitch (size) {\n\tcase 4:\n\t\tvalue_fmt = \"%8.8x \";\n\t\tbreak;\n\tcase 2:\n\t\tvalue_fmt = \"%4.4x \";\n\t\tbreak;\n\tcase 1:\n\t\tvalue_fmt = \"%2.2x \";\n\t\tbreak;\n\tdefault:\n\t\t/* \"can't happen\", caller checked */\n\t\tLOG_ERROR(\"%s invalid memory read size: %u\", __func__, size);\n\t\treturn;\n\t}\n\n\tfor (unsigned i = 0; i < count; i++) {\n\t\tif (i % line_modulo == 0) {\n\t\t\toutput_len += snprintf(output + output_len,\n\t\t\t\t\tsizeof(output) - output_len,\n\t\t\t\t\t\"0x%8.8x: \",\n\t\t\t\t\t(unsigned)(address + (i*size)));\n\t\t}\n\n\t\tuint32_t value = 0;\n\t\tconst uint8_t *value_ptr = buffer + i * size;\n\t\tswitch (size) {\n\t\tcase 4:\n\t\t\tvalue = target_buffer_get_u32(target, value_ptr);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tvalue = target_buffer_get_u16(target, value_ptr);\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\tvalue = *value_ptr;\n\t\t}\n\t\toutput_len += snprintf(output + output_len,\n\t\t\t\tsizeof(output) - output_len,\n\t\t\t\tvalue_fmt, value);\n\n\t\tif ((i % line_modulo == line_modulo - 1) || (i == count - 1)) {\n\t\t\tcommand_print(cmd, \"%s\", output);\n\t\t\toutput_len = 0;\n\t\t}\n\t}\n}\n\nCOMMAND_HANDLER(handle_iod_command)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tuint32_t address;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\tif (address > 0xffff) {\n\t\tLOG_ERROR(\"%s IA-32 I/O space is 2^16, 0x%08\" PRIx32 \" exceeds max\", __func__, address);\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tunsigned size = 0;\n\tswitch (CMD_NAME[2]) {\n\tcase 'w':\n\t\tsize = 4;\n\t\tbreak;\n\tcase 'h':\n\t\tsize = 2;\n\t\tbreak;\n\tcase 'b':\n\t\tsize = 1;\n\t\tbreak;\n\tdefault:\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\tunsigned count = 1;\n\tuint8_t *buffer = calloc(count, size);\n\tstruct target *target = get_current_target(CMD_CTX);\n\tint retval = x86_32_common_read_io(target, address, size, buffer);\n\tif (retval == ERROR_OK)\n\t\thandle_iod_output(CMD, target, address, size, count, buffer);\n\tfree(buffer);\n\treturn retval;\n}\n\nstatic int target_fill_io(struct target *target,\n\t\tuint32_t address,\n\t\tunsigned data_size,\n\t\t/* value */\n\t\tuint32_t b)\n{\n\tLOG_DEBUG(\"address=0x%08\" PRIx32 \", data_size=%u, b=0x%08\" PRIx32,\n\t\t\taddress, data_size, b);\n\tuint8_t target_buf[data_size];\n\tswitch (data_size) {\n\tcase 4:\n\t\ttarget_buffer_set_u32(target, target_buf, b);\n\t\tbreak;\n\tcase 2:\n\t\ttarget_buffer_set_u16(target, target_buf, b);\n\t\tbreak;\n\tcase 1:\n\t\ttarget_buf[0] = (b & 0x0ff);\n\t\tbreak;\n\tdefault:\n\t\texit(-1);\n\t}\n\treturn x86_32_common_write_io(target, address, data_size, target_buf);\n}\n\nCOMMAND_HANDLER(handle_iow_command)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\tuint32_t address;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);\n\tuint32_t value;\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\tstruct target *target = get_current_target(CMD_CTX);\n\n\tunsigned wordsize;\n\tswitch (CMD_NAME[2]) {\n\t\tcase 'w':\n\t\t\twordsize = 4;\n\t\t\tbreak;\n\t\tcase 'h':\n\t\t\twordsize = 2;\n\t\t\tbreak;\n\t\tcase 'b':\n\t\t\twordsize = 1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn target_fill_io(target, address, wordsize, value);\n}\n\nstatic const struct command_registration x86_32_exec_command_handlers[] = {\n\t{\n\t\t.name = \"iww\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iow_command,\n\t\t.help = \"write I/O port word\",\n\t\t.usage = \"port data[word]\",\n\t},\n\t{\n\t\t.name = \"iwh\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iow_command,\n\t\t.help = \"write I/O port halfword\",\n\t\t.usage = \"port data[halfword]\",\n\t},\n\t{\n\t\t.name = \"iwb\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iow_command,\n\t\t.help = \"write I/O port byte\",\n\t\t.usage = \"port data[byte]\",\n\t},\n\t{\n\t\t.name = \"idw\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iod_command,\n\t\t.help = \"display I/O port word\",\n\t\t.usage = \"port\",\n\t},\n\t{\n\t\t.name = \"idh\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iod_command,\n\t\t.help = \"display I/O port halfword\",\n\t\t.usage = \"port\",\n\t},\n\t{\n\t\t.name = \"idb\",\n\t\t.mode = COMMAND_EXEC,\n\t\t.handler = handle_iod_command,\n\t\t.help = \"display I/O port byte\",\n\t\t.usage = \"port\",\n\t},\n\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration x86_32_command_handlers[] = {\n\t{\n\t\t.name = \"x86_32\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"x86_32 target commands\",\n\t\t.usage = \"\",\n\t\t.chain = x86_32_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/x86_32_common.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright(c) 2013-2016 Intel Corporation.\n *\n * Adrian Burns (adrian.burns@intel.com)\n * Thomas Faust (thomas.faust@intel.com)\n * Ivan De Cesaris (ivan.de.cesaris@intel.com)\n * Julien Carreno (julien.carreno@intel.com)\n * Jeffrey Maxwell (jeffrey.r.maxwell@intel.com)\n *\n * Contact Information:\n * Intel Corporation\n */\n\n/*\n * @file\n * This is the interface to the x86 32 bit memory and breakpoint operations.\n */\n\n#ifndef OPENOCD_TARGET_X86_32_COMMON_H\n#define OPENOCD_TARGET_X86_32_COMMON_H\n\n#include <jtag/jtag.h>\n#include <helper/command.h>\n#include <helper/types.h>\n\nextern const struct command_registration x86_32_command_handlers[];\n\n/* for memory access */\n#define BYTE\t\t\t1\n#define WORD\t\t\t2\n#define DWORD\t\t\t4\n\n#define EFLAGS_TF\t\t((uint32_t)0x00000100) /* Trap Flag */\n#define EFLAGS_IF\t\t((uint32_t)0x00000200) /* Interrupt Flag */\n#define EFLAGS_RF\t\t((uint32_t)0x00010000) /* Resume Flag */\n#define EFLAGS_VM86\t\t((uint32_t)0x00020000) /* Virtual 8086 Mode */\n\n#define CSAR_DPL\t\t((uint32_t)0x00006000)\n#define CSAR_D\t\t\t((uint32_t)0x00400000)\n#define SSAR_DPL\t\t((uint32_t)0x00006000)\n\n#define CR0_PE\t\t\t((uint32_t)0x00000001) /* Protected Mode Enable */\n#define CR0_NW\t\t\t((uint32_t)0x20000000) /* Non Write-Through */\n#define CR0_CD\t\t\t((uint32_t)0x40000000) /* Cache Disable */\n#define CR0_PG\t\t\t((uint32_t)0x80000000) /* Paging Enable */\n\n/* TODO - move back to PM specific file */\n#define PM_DR6\t\t\t((uint32_t)0xFFFF0FF0)\n\n#define DR6_BRKDETECT_0\t\t((uint32_t)0x00000001) /* B0 through B3 */\n#define DR6_BRKDETECT_1\t\t((uint32_t)0x00000002) /* breakpoint condition detected */\n#define DR6_BRKDETECT_2\t\t((uint32_t)0x00000004)\n#define DR6_BRKDETECT_3\t\t((uint32_t)0x00000008)\n\nenum {\n\t/* general purpose registers */\n\tEAX = 0,\n\tECX,\n\tEDX,\n\tEBX,\n\tESP,\n\tEBP,\n\tESI,\n\tEDI,\n\t/* instruction pointer & flags */\n\tEIP,\n\tEFLAGS,\n\n\t/* segment registers */\n\tCS,\n\tSS,\n\tDS,\n\tES,\n\tFS,\n\tGS,\n\n\t/* floating point unit registers */\n\tST0,\n\tST1,\n\tST2,\n\tST3,\n\tST4,\n\tST5,\n\tST6,\n\tST7,\n\tFCTRL,\n\tFSTAT,\n\tFTAG,\n\tFISEG,\n\tFIOFF,\n\tFOSEG,\n\tFOOFF,\n\tFOP,\n\n\t/* control registers */\n\tCR0,\n\tCR2,\n\tCR3,\n\tCR4,\n\n\t/* debug registers */\n\tDR0,\n\tDR1,\n\tDR2,\n\tDR3,\n\tDR6,\n\tDR7,\n\n\t/* descriptor tables */\n\tIDTB,\n\tIDTL,\n\tIDTAR,\n\tGDTB,\n\tGDTL,\n\tGDTAR,\n\tTR,\n\tLDTR,\n\tLDTB,\n\tLDTL,\n\tLDTAR,\n\n\t/* segment registers */\n\tCSB,\n\tCSL,\n\tCSAR,\n\tDSB,\n\tDSL,\n\tDSAR,\n\tESB,\n\tESL,\n\tESAR,\n\tFSB,\n\tFSL,\n\tFSAR,\n\tGSB,\n\tGSL,\n\tGSAR,\n\tSSB,\n\tSSL,\n\tSSAR,\n\tTSSB,\n\tTSSL,\n\tTSSAR,\n\n\t/* PM control reg */\n\tPMCR,\n};\n\n#define X86_32_COMMON_MAGIC 0x86328632U\n\nenum {\n\t/* memory read/write */\n\tMEMRDB32 = 0,\n\tMEMRDB16,\n\tMEMRDH32,\n\tMEMRDH16,\n\tMEMRDW32,\n\tMEMRDW16,\n\tMEMWRB32,\n\tMEMWRB16,\n\tMEMWRH32,\n\tMEMWRH16,\n\tMEMWRW32,\n\tMEMWRW16,\n\t/* IO read/write */\n\tIORDB32,\n\tIORDB16,\n\tIORDH32,\n\tIORDH16,\n\tIORDW32,\n\tIORDW16,\n\tIOWRB32,\n\tIOWRB16,\n\tIOWRH32,\n\tIOWRH16,\n\tIOWRW32,\n\tIOWRW16,\n\t/* lakemont1 core shadow ram access opcodes */\n\tSRAMACCESS,\n\tSRAM2PDR,\n\tPDR2SRAM,\n\tWBINVD,\n};\n\nenum x86_core_type {\n\tLMT1,\n\tLMT3_5\n};\n\nstruct swbp_mem_patch {\n\tuint8_t orig_byte;\n\tuint32_t swbp_unique_id;\n\tuint32_t physaddr;\n\tstruct swbp_mem_patch *next;\n};\n\n/* TODO - probemode specific - consider removing */\n#define NUM_PM_REGS\t\t18 /* regs used in save/restore */\n\nstruct x86_32_common {\n\tunsigned int common_magic;\n\n\tvoid *arch_info;\n\tenum x86_core_type core_type;\n\tstruct reg_cache *cache;\n\tstruct jtag_tap *curr_tap;\n\tuint32_t stored_pc;\n\tint forced_halt_for_reset;\n\tint flush;\n\n\t/* pm_regs are for probemode save/restore state */\n\tuint32_t pm_regs[NUM_PM_REGS];\n\n\t/* working area for fastdata access */\n\tstruct working_area *fast_data_area;\n\n\tint num_hw_bpoints;\n\tstruct x86_32_dbg_reg *hw_break_list;\n\tstruct swbp_mem_patch *swbbp_mem_patch_list;\n\n\t/* core probemode implementation dependent functions */\n\tuint8_t (*get_num_user_regs)(struct target *t);\n\tbool (*is_paging_enabled)(struct target *t);\n\tint (*disable_paging)(struct target *t);\n\tint (*enable_paging)(struct target *t);\n\tbool (*sw_bpts_supported)(struct target *t);\n\tint (*transaction_status)(struct target *t);\n\tint (*submit_instruction)(struct target *t, int num);\n\tint (*read_hw_reg)(struct target *t, int reg, uint32_t *regval, uint8_t cache);\n\tint (*write_hw_reg)(struct target *t, int reg,\n\t\t\t\tuint32_t regval, uint8_t cache);\n\n\t/* register cache to processor synchronization */\n\tint (*read_hw_reg_to_cache)(struct target *target, int num);\n\tint (*write_hw_reg_from_cache)(struct target *target, int num);\n};\n\nstatic inline struct x86_32_common *\ntarget_to_x86_32(struct target *target)\n{\n\treturn target->arch_info;\n}\nbool check_not_halted(const struct target *t);\n\n/* breakpoint defines */\n#define MAX_DEBUG_REGS\t\t4\n#define SW_BP_OPCODE\t\t0xf1\n#define MAX_SW_BPTS\t\t20\n\nstruct x86_32_dbg_reg {\n\tint used;\n\tuint32_t bp_value;\n};\n\n#define DR7_G_ENABLE_SHIFT\t\t1\n#define DR7_ENABLE_SIZE\t\t\t2 /* 2 bits per debug reg */\n#define DR7_RW_SHIFT\t\t\t16\n#define DR7_LENGTH_SHIFT\t\t18\n#define DR7_RW_LEN_SIZE\t\t\t4\n#define DR7_BP_EXECUTE\t\t\t0 /* 00 - only on instruction execution*/\n#define DR7_BP_WRITE\t\t\t1 /* 01 - only on data writes */\n/*#define DR7_RW_IORW\t\t\t2 UNSUPPORTED 10 - an I/O read and I/O write */\n#define DR7_BP_READWRITE\t\t3 /* on data read or data write */\n#define DR7_BP_LENGTH_1\t\t\t0 /* 00 - 1 byte length */\n#define DR7_BP_LENGTH_2\t\t\t1 /* 01 - 2 byte length */\n#define DR7_BP_LENGTH_4\t\t\t3 /* 11 - 4 byte length */\n\n#define DR7_GLOBAL_ENABLE(val, regnum) \\\n\t(val |= (1 << (DR7_G_ENABLE_SHIFT + (DR7_ENABLE_SIZE * (regnum)))))\n\n#define DR7_GLOBAL_DISABLE(val, regnum) \\\n\t(val &= ~(3 << (DR7_ENABLE_SIZE * (regnum))))\n\n#define DR7_BP_FREE(val, regnum) \\\n\t((val & (3 << (DR7_ENABLE_SIZE * (regnum)))) == 0)\n\n#define DR7_RESET_RWLEN_BITS(val, regnum) \\\n\t(val &= ~(0x0f << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum))))\n\n#define DR7_SET_EXE(val, regnum) \\\n\t(val &= ~(0x0f << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum))))\n\n#define DR7_SET_WRITE(val, regnum) \\\n\t(val |= (DR7_BP_WRITE << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum))))\n\n#define DR7_SET_ACCESS(val, regnum) \\\n\t(val |= (DR7_BP_READWRITE << (DR7_RW_SHIFT + DR7_RW_LEN_SIZE * (regnum))))\n\n#define DR7_SET_LENGTH(val, regnum, len) \\\n\t(val |= (len == 1) ? (DR7_BP_LENGTH_1 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum))) : \\\n\t(len == 2) ? (DR7_BP_LENGTH_2 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum))) : \\\n\t(DR7_BP_LENGTH_4 << (DR7_LENGTH_SHIFT + DR7_RW_LEN_SIZE * (regnum))))\n\n/* public interface */\nint x86_32_get_gdb_reg_list(struct target *t,\n\t\t\tstruct reg **reg_list[], int *reg_list_size,\n\t\t\tenum target_register_class reg_class);\nint x86_32_common_init_arch_info(struct target *target,\n\t\t\tstruct x86_32_common *x86_32);\nint x86_32_common_mmu(struct target *t, int *enabled);\nint x86_32_common_virt2phys(struct target *t, target_addr_t address, target_addr_t *physical);\nint x86_32_common_read_phys_mem(struct target *t, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buffer);\nint x86_32_common_write_phys_mem(struct target *t, target_addr_t phys_address,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buffer);\nint x86_32_common_read_memory(struct target *t, target_addr_t addr,\n\t\t\tuint32_t size, uint32_t count, uint8_t *buf);\nint x86_32_common_write_memory(struct target *t, target_addr_t addr,\n\t\t\tuint32_t size, uint32_t count, const uint8_t *buf);\nint x86_32_common_read_io(struct target *t, uint32_t addr,\n\t\t\tuint32_t size, uint8_t *buf);\nint x86_32_common_write_io(struct target *t, uint32_t addr,\n\t\t\tuint32_t size, const uint8_t *buf);\nint x86_32_common_add_breakpoint(struct target *t, struct breakpoint *bp);\nint x86_32_common_remove_breakpoint(struct target *t, struct breakpoint *bp);\nint x86_32_common_add_watchpoint(struct target *t, struct watchpoint *wp);\nint x86_32_common_remove_watchpoint(struct target *t, struct watchpoint *wp);\nvoid x86_32_common_reset_breakpoints_watchpoints(struct target *t);\n\n#endif /* OPENOCD_TARGET_X86_32_COMMON_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xscale.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2006, 2007 by Dominic Rath                              *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2009 Michael Schwingen                                  *\n *   michael@schwingen.org                                                 *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"breakpoints.h\"\n#include \"xscale.h\"\n#include \"target_type.h\"\n#include \"arm_jtag.h\"\n#include \"arm_simulator.h\"\n#include \"arm_disassembler.h\"\n#include <helper/time_support.h>\n#include \"register.h\"\n#include \"image.h\"\n#include \"arm_opcodes.h\"\n#include \"armv4_5.h\"\n\n/*\n * Important XScale documents available as of October 2009 include:\n *\n *  Intel XScale® Core Developer’s Manual, January 2004\n *\t\tOrder Number: 273473-002\n *\tThis has a chapter detailing debug facilities, and punts some\n *\tdetails to chip-specific microarchitecture documents.\n *\n *  Hot-Debug for Intel XScale® Core Debug White Paper, May 2005\n *\t\tDocument Number: 273539-005\n *\tLess detailed than the developer's manual, but summarizes those\n *\tmissing details (for most XScales) and gives LOTS of notes about\n *\tdebugger/handler interaction issues.  Presents a simpler reset\n *\tand load-handler sequence than the arch doc.  (Note, OpenOCD\n *\tdoesn't currently support \"Hot-Debug\" as defined there.)\n *\n * Chip-specific microarchitecture documents may also be useful.\n */\n\n/* forward declarations */\nstatic int xscale_resume(struct target *, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution);\nstatic int xscale_debug_entry(struct target *);\nstatic int xscale_restore_banked(struct target *);\nstatic int xscale_get_reg(struct reg *reg);\nstatic int xscale_set_reg(struct reg *reg, uint8_t *buf);\nstatic int xscale_set_breakpoint(struct target *, struct breakpoint *);\nstatic int xscale_set_watchpoint(struct target *, struct watchpoint *);\nstatic int xscale_unset_breakpoint(struct target *, struct breakpoint *);\nstatic int xscale_read_trace(struct target *);\n\n/* This XScale \"debug handler\" is loaded into the processor's\n * mini-ICache, which is 2K of code writable only via JTAG.\n */\nstatic const uint8_t xscale_debug_handler[] = {\n#include \"../../contrib/loaders/debug/xscale/debug_handler.inc\"\n};\n\nstatic const char *const xscale_reg_list[] = {\n\t\"XSCALE_MAINID\",\t\t/* 0 */\n\t\"XSCALE_CACHETYPE\",\n\t\"XSCALE_CTRL\",\n\t\"XSCALE_AUXCTRL\",\n\t\"XSCALE_TTB\",\n\t\"XSCALE_DAC\",\n\t\"XSCALE_FSR\",\n\t\"XSCALE_FAR\",\n\t\"XSCALE_PID\",\n\t\"XSCALE_CPACCESS\",\n\t\"XSCALE_IBCR0\",\t\t\t/* 10 */\n\t\"XSCALE_IBCR1\",\n\t\"XSCALE_DBR0\",\n\t\"XSCALE_DBR1\",\n\t\"XSCALE_DBCON\",\n\t\"XSCALE_TBREG\",\n\t\"XSCALE_CHKPT0\",\n\t\"XSCALE_CHKPT1\",\n\t\"XSCALE_DCSR\",\n\t\"XSCALE_TX\",\n\t\"XSCALE_RX\",\t\t\t/* 20 */\n\t\"XSCALE_TXRXCTRL\",\n};\n\nstatic const struct xscale_reg xscale_reg_arch_info[] = {\n\t{XSCALE_MAINID, NULL},\n\t{XSCALE_CACHETYPE, NULL},\n\t{XSCALE_CTRL, NULL},\n\t{XSCALE_AUXCTRL, NULL},\n\t{XSCALE_TTB, NULL},\n\t{XSCALE_DAC, NULL},\n\t{XSCALE_FSR, NULL},\n\t{XSCALE_FAR, NULL},\n\t{XSCALE_PID, NULL},\n\t{XSCALE_CPACCESS, NULL},\n\t{XSCALE_IBCR0, NULL},\n\t{XSCALE_IBCR1, NULL},\n\t{XSCALE_DBR0, NULL},\n\t{XSCALE_DBR1, NULL},\n\t{XSCALE_DBCON, NULL},\n\t{XSCALE_TBREG, NULL},\n\t{XSCALE_CHKPT0, NULL},\n\t{XSCALE_CHKPT1, NULL},\n\t{XSCALE_DCSR, NULL},\t/* DCSR accessed via JTAG or SW */\n\t{-1, NULL},\t/* TX accessed via JTAG */\n\t{-1, NULL},\t/* RX accessed via JTAG */\n\t{-1, NULL},\t/* TXRXCTRL implicit access via JTAG */\n};\n\n/* convenience wrapper to access XScale specific registers */\nstatic int xscale_set_reg_u32(struct reg *reg, uint32_t value)\n{\n\tuint8_t buf[4] = { 0 };\n\n\tbuf_set_u32(buf, 0, 32, value);\n\n\treturn xscale_set_reg(reg, buf);\n}\n\nstatic const char xscale_not[] = \"target is not an XScale\";\n\nstatic int xscale_verify_pointer(struct command_invocation *cmd,\n\tstruct xscale_common *xscale)\n{\n\tif (xscale->common_magic != XSCALE_COMMON_MAGIC) {\n\t\tcommand_print(cmd, xscale_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)\n{\n\tassert(tap);\n\n\tif (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {\n\t\tstruct scan_field field;\n\t\tuint8_t scratch[4] = { 0 };\n\n\t\tmemset(&field, 0, sizeof(field));\n\t\tfield.num_bits = tap->ir_length;\n\t\tfield.out_value = scratch;\n\t\tbuf_set_u32(scratch, 0, field.num_bits, new_instr);\n\n\t\tjtag_add_ir_scan(tap, &field, end_state);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_dcsr(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\tstruct scan_field fields[3];\n\tuint8_t field0 = 0x0;\n\tuint8_t field0_check_value = 0x2;\n\tuint8_t field0_check_mask = 0x7;\n\tuint8_t field2 = 0x0;\n\tuint8_t field2_check_value = 0x0;\n\tuint8_t field2_check_mask = 0x1;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_SELDCSR << xscale->xscale_variant,\n\t\tTAP_DRPAUSE);\n\n\tbuf_set_u32(&field0, 1, 1, xscale->hold_rst);\n\tbuf_set_u32(&field0, 2, 1, xscale->external_debug_break);\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 3;\n\tfields[0].out_value = &field0;\n\tuint8_t tmp;\n\tfields[0].in_value = &tmp;\n\n\tfields[1].num_bits = 32;\n\tfields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &field2;\n\tuint8_t tmp2;\n\tfields[2].in_value = &tmp2;\n\n\tjtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);\n\n\tjtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);\n\tjtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while reading DCSR\");\n\t\treturn retval;\n\t}\n\n\txscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;\n\txscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;\n\n\t/* write the register with the value we just read\n\t * on this second pass, only the first bit of field0 is guaranteed to be 0)\n\t */\n\tfield0_check_mask = 0x1;\n\tfields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;\n\tfields[1].in_value = NULL;\n\n\tjtag_add_dr_scan(target->tap, 3, fields, TAP_DRPAUSE);\n\n\t/* DANGER!!! this must be here. It will make sure that the arguments\n\t * to jtag_set_check_value() does not go out of scope! */\n\treturn jtag_execute_queue();\n}\n\n\nstatic void xscale_getbuf(jtag_callback_data_t arg)\n{\n\tuint8_t *in = (uint8_t *)arg;\n\t*((uint32_t *)arg) = buf_get_u32(in, 0, 32);\n}\n\nstatic int xscale_receive(struct target *target, uint32_t *buffer, int num_words)\n{\n\tif (num_words == 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval = ERROR_OK;\n\ttap_state_t path[3];\n\tstruct scan_field fields[3];\n\tuint8_t *field0 = malloc(num_words * 1);\n\tuint8_t field0_check_value = 0x2;\n\tuint8_t field0_check_mask = 0x6;\n\tuint32_t *field1 = malloc(num_words * 4);\n\tuint8_t field2_check_value = 0x0;\n\tuint8_t field2_check_mask = 0x1;\n\tint words_done = 0;\n\tint words_scheduled = 0;\n\tint i;\n\n\tpath[0] = TAP_DRSELECT;\n\tpath[1] = TAP_DRCAPTURE;\n\tpath[2] = TAP_DRSHIFT;\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 3;\n\tuint8_t tmp;\n\tfields[0].in_value = &tmp;\n\tfields[0].check_value = &field0_check_value;\n\tfields[0].check_mask = &field0_check_mask;\n\n\tfields[1].num_bits = 32;\n\n\tfields[2].num_bits = 1;\n\tuint8_t tmp2;\n\tfields[2].in_value = &tmp2;\n\tfields[2].check_value = &field2_check_value;\n\tfields[2].check_mask = &field2_check_mask;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_DBGTX << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\tjtag_add_runtest(1, TAP_IDLE);\t/* ensures that we're in the TAP_IDLE state as the above\n\t\t\t\t\t *could be a no-op */\n\n\t/* repeat until all words have been collected */\n\tint attempts = 0;\n\twhile (words_done < num_words) {\n\t\t/* schedule reads */\n\t\twords_scheduled = 0;\n\t\tfor (i = words_done; i < num_words; i++) {\n\t\t\tfields[0].in_value = &field0[i];\n\n\t\t\tjtag_add_pathmove(3, path);\n\n\t\t\tfields[1].in_value = (uint8_t *)(field1 + i);\n\n\t\t\tjtag_add_dr_scan_check(target->tap, 3, fields, TAP_IDLE);\n\n\t\t\tjtag_add_callback(xscale_getbuf, (jtag_callback_data_t)(field1 + i));\n\n\t\t\twords_scheduled++;\n\t\t}\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"JTAG error while receiving data from debug handler\");\n\t\t\tbreak;\n\t\t}\n\n\t\t/* examine results */\n\t\tfor (i = words_done; i < num_words; i++) {\n\t\t\tif (!(field0[i] & 1)) {\n\t\t\t\t/* move backwards if necessary */\n\t\t\t\tint j;\n\t\t\t\tfor (j = i; j < num_words - 1; j++) {\n\t\t\t\t\tfield0[j] = field0[j + 1];\n\t\t\t\t\tfield1[j] = field1[j + 1];\n\t\t\t\t}\n\t\t\t\twords_scheduled--;\n\t\t\t}\n\t\t}\n\t\tif (words_scheduled == 0) {\n\t\t\tif (attempts++ == 1000) {\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"Failed to receiving data from debug handler after 1000 attempts\");\n\t\t\t\tretval = ERROR_TARGET_TIMEOUT;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\twords_done += words_scheduled;\n\t}\n\n\tfor (i = 0; i < num_words; i++)\n\t\t*(buffer++) = buf_get_u32((uint8_t *)&field1[i], 0, 32);\n\n\tfree(field1);\n\n\treturn retval;\n}\n\nstatic int xscale_read_tx(struct target *target, int consume)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\ttap_state_t path[3];\n\ttap_state_t noconsume_path[6];\n\tint retval;\n\tstruct timeval timeout, now;\n\tstruct scan_field fields[3];\n\tuint8_t field0_in = 0x0;\n\tuint8_t field0_check_value = 0x2;\n\tuint8_t field0_check_mask = 0x6;\n\tuint8_t field2_check_value = 0x0;\n\tuint8_t field2_check_mask = 0x1;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_DBGTX << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\tpath[0] = TAP_DRSELECT;\n\tpath[1] = TAP_DRCAPTURE;\n\tpath[2] = TAP_DRSHIFT;\n\n\tnoconsume_path[0] = TAP_DRSELECT;\n\tnoconsume_path[1] = TAP_DRCAPTURE;\n\tnoconsume_path[2] = TAP_DREXIT1;\n\tnoconsume_path[3] = TAP_DRPAUSE;\n\tnoconsume_path[4] = TAP_DREXIT2;\n\tnoconsume_path[5] = TAP_DRSHIFT;\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 3;\n\tfields[0].in_value = &field0_in;\n\n\tfields[1].num_bits = 32;\n\tfields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;\n\n\tfields[2].num_bits = 1;\n\tuint8_t tmp;\n\tfields[2].in_value = &tmp;\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, 1, 0);\n\n\tfor (;; ) {\n\t\t/* if we want to consume the register content (i.e. clear TX_READY),\n\t\t * we have to go straight from Capture-DR to Shift-DR\n\t\t * otherwise, we go from Capture-DR to Exit1-DR to Pause-DR\n\t\t*/\n\t\tif (consume)\n\t\t\tjtag_add_pathmove(3, path);\n\t\telse\n\t\t\tjtag_add_pathmove(ARRAY_SIZE(noconsume_path), noconsume_path);\n\n\t\tjtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);\n\n\t\tjtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);\n\t\tjtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"JTAG error while reading TX\");\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\n\t\tgettimeofday(&now, NULL);\n\t\tif (timeval_compare(&now, &timeout) > 0) {\n\t\t\tLOG_ERROR(\"time out reading TX register\");\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t\tif (!((!(field0_in & 1)) && consume))\n\t\t\tgoto done;\n\t\tif (debug_level >= 3) {\n\t\t\tLOG_DEBUG(\"waiting 100ms\");\n\t\t\talive_sleep(100);\t/* avoid flooding the logs */\n\t\t} else\n\t\t\tkeep_alive();\n\t}\ndone:\n\n\tif (!(field0_in & 1))\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_write_rx(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\tstruct timeval timeout, now;\n\tstruct scan_field fields[3];\n\tuint8_t field0_out = 0x0;\n\tuint8_t field0_in = 0x0;\n\tuint8_t field0_check_value = 0x2;\n\tuint8_t field0_check_mask = 0x6;\n\tuint8_t field2 = 0x0;\n\tuint8_t field2_check_value = 0x0;\n\tuint8_t field2_check_mask = 0x1;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_DBGRX << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 3;\n\tfields[0].out_value = &field0_out;\n\tfields[0].in_value = &field0_in;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &field2;\n\tuint8_t tmp;\n\tfields[2].in_value = &tmp;\n\n\tgettimeofday(&timeout, NULL);\n\ttimeval_add_time(&timeout, 1, 0);\n\n\t/* poll until rx_read is low */\n\tLOG_DEBUG(\"polling RX\");\n\tfor (;;) {\n\t\tjtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);\n\n\t\tjtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);\n\t\tjtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);\n\n\t\tretval = jtag_execute_queue();\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"JTAG error while writing RX\");\n\t\t\treturn retval;\n\t\t}\n\n\t\tgettimeofday(&now, NULL);\n\t\tif ((now.tv_sec > timeout.tv_sec) ||\n\t\t\t((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec))) {\n\t\t\tLOG_ERROR(\"time out writing RX register\");\n\t\t\treturn ERROR_TARGET_TIMEOUT;\n\t\t}\n\t\tif (!(field0_in & 1))\n\t\t\tgoto done;\n\t\tif (debug_level >= 3) {\n\t\t\tLOG_DEBUG(\"waiting 100ms\");\n\t\t\talive_sleep(100);\t/* avoid flooding the logs */\n\t\t} else\n\t\t\tkeep_alive();\n\t}\ndone:\n\n\t/* set rx_valid */\n\tfield2 = 0x1;\n\tjtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while writing RX\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* send count elements of size byte to the debug handler */\nstatic int xscale_send(struct target *target, const uint8_t *buffer, int count, int size)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\tint done_count = 0;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_DBGRX << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\tstatic const uint8_t t0;\n\tuint8_t t1[4] = { 0 };\n\tstatic const uint8_t t2 = 1;\n\tstruct scan_field fields[3] = {\n\t\t\t{ .num_bits = 3, .out_value = &t0 },\n\t\t\t{ .num_bits = 32, .out_value = t1 },\n\t\t\t{ .num_bits = 1, .out_value = &t2 },\n\t};\n\n\tint endianness = target->endianness;\n\twhile (done_count++ < count) {\n\t\tuint32_t t;\n\n\t\tswitch (size) {\n\t\t\tcase 4:\n\t\t\t\tif (endianness == TARGET_LITTLE_ENDIAN)\n\t\t\t\t\tt = le_to_h_u32(buffer);\n\t\t\t\telse\n\t\t\t\t\tt = be_to_h_u32(buffer);\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tif (endianness == TARGET_LITTLE_ENDIAN)\n\t\t\t\t\tt = le_to_h_u16(buffer);\n\t\t\t\telse\n\t\t\t\t\tt = be_to_h_u16(buffer);\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tt = buffer[0];\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"BUG: size neither 4, 2 nor 1\");\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\n\t\tbuf_set_u32(t1, 0, 32, t);\n\n\t\tjtag_add_dr_scan(target->tap,\n\t\t\t3,\n\t\t\tfields,\n\t\t\tTAP_IDLE);\n\t\tbuffer += size;\n\t}\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while sending data to debug handler\");\n\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_send_u32(struct target *target, uint32_t value)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);\n\treturn xscale_write_rx(target);\n}\n\nstatic int xscale_write_dcsr(struct target *target, int hold_rst, int ext_dbg_brk)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\tstruct scan_field fields[3];\n\tuint8_t field0 = 0x0;\n\tuint8_t field0_check_value = 0x2;\n\tuint8_t field0_check_mask = 0x7;\n\tuint8_t field2 = 0x0;\n\tuint8_t field2_check_value = 0x0;\n\tuint8_t field2_check_mask = 0x1;\n\n\tif (hold_rst != -1)\n\t\txscale->hold_rst = hold_rst;\n\n\tif (ext_dbg_brk != -1)\n\t\txscale->external_debug_break = ext_dbg_brk;\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_SELDCSR << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\tbuf_set_u32(&field0, 1, 1, xscale->hold_rst);\n\tbuf_set_u32(&field0, 2, 1, xscale->external_debug_break);\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 3;\n\tfields[0].out_value = &field0;\n\tuint8_t tmp;\n\tfields[0].in_value = &tmp;\n\n\tfields[1].num_bits = 32;\n\tfields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;\n\n\tfields[2].num_bits = 1;\n\tfields[2].out_value = &field2;\n\tuint8_t tmp2;\n\tfields[2].in_value = &tmp2;\n\n\tjtag_add_dr_scan(target->tap, 3, fields, TAP_IDLE);\n\n\tjtag_check_value_mask(fields + 0, &field0_check_value, &field0_check_mask);\n\tjtag_check_value_mask(fields + 2, &field2_check_value, &field2_check_mask);\n\n\tretval = jtag_execute_queue();\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"JTAG error while writing DCSR\");\n\t\treturn retval;\n\t}\n\n\txscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;\n\txscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;\n\n\treturn ERROR_OK;\n}\n\n/* parity of the number of bits 0 if even; 1 if odd. for 32 bit words */\nstatic unsigned int parity(unsigned int v)\n{\n\t/* unsigned int ov = v; */\n\tv ^= v >> 16;\n\tv ^= v >> 8;\n\tv ^= v >> 4;\n\tv &= 0xf;\n\t/* LOG_DEBUG(\"parity of 0x%x is %i\", ov, (0x6996 >> v) & 1); */\n\treturn (0x6996 >> v) & 1;\n}\n\nstatic int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8])\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint8_t packet[4] = { 0 };\n\tuint8_t cmd = 0;\n\tint word;\n\tstruct scan_field fields[2];\n\n\tLOG_DEBUG(\"loading miniIC at 0x%8.8\" PRIx32 \"\", va);\n\n\t/* LDIC into IR */\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_LDIC << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\t/* CMD is b011 to load a cacheline into the Mini ICache.\n\t * Loading into the main ICache is deprecated, and unused.\n\t * It's followed by three zero bits, and 27 address bits.\n\t */\n\tbuf_set_u32(&cmd, 0, 6, 0x3);\n\n\t/* virtual address of desired cache line */\n\tbuf_set_u32(packet, 0, 27, va >> 5);\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 6;\n\tfields[0].out_value = &cmd;\n\n\tfields[1].num_bits = 27;\n\tfields[1].out_value = packet;\n\n\tjtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);\n\n\t/* rest of packet is a cacheline: 8 instructions, with parity */\n\tfields[0].num_bits = 32;\n\tfields[0].out_value = packet;\n\n\tfields[1].num_bits = 1;\n\tfields[1].out_value = &cmd;\n\n\tfor (word = 0; word < 8; word++) {\n\t\tbuf_set_u32(packet, 0, 32, buffer[word]);\n\n\t\tuint32_t value;\n\t\tmemcpy(&value, packet, sizeof(uint32_t));\n\t\tcmd = parity(value);\n\n\t\tjtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);\n\t}\n\n\treturn jtag_execute_queue();\n}\n\nstatic int xscale_invalidate_ic_line(struct target *target, uint32_t va)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint8_t packet[4] = { 0 };\n\tuint8_t cmd = 0;\n\tstruct scan_field fields[2];\n\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_LDIC << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\t/* CMD for invalidate IC line b000, bits [6:4] b000 */\n\tbuf_set_u32(&cmd, 0, 6, 0x0);\n\n\t/* virtual address of desired cache line */\n\tbuf_set_u32(packet, 0, 27, va >> 5);\n\n\tmemset(&fields, 0, sizeof(fields));\n\n\tfields[0].num_bits = 6;\n\tfields[0].out_value = &cmd;\n\n\tfields[1].num_bits = 27;\n\tfields[1].out_value = packet;\n\n\tjtag_add_dr_scan(target->tap, 2, fields, TAP_IDLE);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_update_vectors(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint i;\n\tint retval;\n\n\tuint32_t low_reset_branch, high_reset_branch;\n\n\tfor (i = 1; i < 8; i++) {\n\t\t/* if there's a static vector specified for this exception, override */\n\t\tif (xscale->static_high_vectors_set & (1 << i))\n\t\t\txscale->high_vectors[i] = xscale->static_high_vectors[i];\n\t\telse {\n\t\t\tretval = target_read_u32(target, 0xffff0000 + 4*i, &xscale->high_vectors[i]);\n\t\t\tif (retval == ERROR_TARGET_TIMEOUT)\n\t\t\t\treturn retval;\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t/* Some of these reads will fail as part of normal execution */\n\t\t\t\txscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 1; i < 8; i++) {\n\t\tif (xscale->static_low_vectors_set & (1 << i))\n\t\t\txscale->low_vectors[i] = xscale->static_low_vectors[i];\n\t\telse {\n\t\t\tretval = target_read_u32(target, 0x0 + 4*i, &xscale->low_vectors[i]);\n\t\t\tif (retval == ERROR_TARGET_TIMEOUT)\n\t\t\t\treturn retval;\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\t/* Some of these reads will fail as part of normal execution */\n\t\t\t\txscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* calculate branches to debug handler */\n\tlow_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;\n\thigh_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;\n\n\txscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);\n\txscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);\n\n\t/* invalidate and load exception vectors in mini i-cache */\n\txscale_invalidate_ic_line(target, 0x0);\n\txscale_invalidate_ic_line(target, 0xffff0000);\n\n\txscale_load_ic(target, 0x0, xscale->low_vectors);\n\txscale_load_ic(target, 0xffff0000, xscale->high_vectors);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_arch_state(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\n\tstatic const char *state[] = {\n\t\t\"disabled\", \"enabled\"\n\t};\n\n\tstatic const char *arch_dbg_reason[] = {\n\t\t\"\", \"\\n(processor reset)\", \"\\n(trace buffer full)\"\n\t};\n\n\tif (arm->common_magic != ARM_COMMON_MAGIC) {\n\t\tLOG_ERROR(\"BUG: called for a non-ARMv4/5 target\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tarm_arch_state(target);\n\tLOG_USER(\"MMU: %s, D-Cache: %s, I-Cache: %s%s\",\n\t\tstate[xscale->armv4_5_mmu.mmu_enabled],\n\t\tstate[xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],\n\t\tstate[xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled],\n\t\tarch_dbg_reason[xscale->arch_debug_reason]);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_poll(struct target *target)\n{\n\tint retval = ERROR_OK;\n\n\tif ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) {\n\t\tenum target_state previous_state = target->state;\n\t\tretval = xscale_read_tx(target, 0);\n\t\tif (retval == ERROR_OK) {\n\n\t\t\t/* there's data to read from the tx register, we entered debug state */\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\t/* process debug entry, fetching current mode regs */\n\t\t\tretval = xscale_debug_entry(target);\n\t\t} else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {\n\t\t\tLOG_USER(\"error while polling TX register, reset CPU\");\n\t\t\t/* here we \"lie\" so GDB won't get stuck and a reset can be performed */\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t}\n\n\t\t/* debug_entry could have overwritten target state (i.e. immediate resume)\n\t\t * don't signal event handlers in that case\n\t\t */\n\t\tif (target->state != TARGET_HALTED)\n\t\t\treturn ERROR_OK;\n\n\t\t/* if target was running, signal that we halted\n\t\t * otherwise we reentered from debug execution */\n\t\tif (previous_state == TARGET_RUNNING)\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\telse\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t}\n\n\treturn retval;\n}\n\nstatic int xscale_debug_entry(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\tuint32_t pc;\n\tuint32_t buffer[10];\n\tunsigned i;\n\tint retval;\n\tuint32_t moe;\n\n\t/* clear external dbg break (will be written on next DCSR read) */\n\txscale->external_debug_break = 0;\n\tretval = xscale_read_dcsr(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* get r0, pc, r1 to r7 and cpsr */\n\tretval = xscale_receive(target, buffer, 10);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* move r0 from buffer to register cache */\n\tbuf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, buffer[0]);\n\tarm->core_cache->reg_list[0].dirty = true;\n\tarm->core_cache->reg_list[0].valid = true;\n\tLOG_DEBUG(\"r0: 0x%8.8\" PRIx32 \"\", buffer[0]);\n\n\t/* move pc from buffer to register cache */\n\tbuf_set_u32(arm->pc->value, 0, 32, buffer[1]);\n\tarm->pc->dirty = true;\n\tarm->pc->valid = true;\n\tLOG_DEBUG(\"pc: 0x%8.8\" PRIx32 \"\", buffer[1]);\n\n\t/* move data from buffer to register cache */\n\tfor (i = 1; i <= 7; i++) {\n\t\tbuf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);\n\t\tarm->core_cache->reg_list[i].dirty = true;\n\t\tarm->core_cache->reg_list[i].valid = true;\n\t\tLOG_DEBUG(\"r%i: 0x%8.8\" PRIx32 \"\", i, buffer[i + 1]);\n\t}\n\n\tarm_set_cpsr(arm, buffer[9]);\n\tLOG_DEBUG(\"cpsr: 0x%8.8\" PRIx32 \"\", buffer[9]);\n\n\tif (!is_arm_mode(arm->core_mode)) {\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\tLOG_ERROR(\"cpsr contains invalid mode value - communication failure\");\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\tLOG_DEBUG(\"target entered debug state in %s mode\",\n\t\tarm_mode_name(arm->core_mode));\n\n\t/* get banked registers, r8 to r14, and spsr if not in USR/SYS mode */\n\tif (arm->spsr) {\n\t\txscale_receive(target, buffer, 8);\n\t\tbuf_set_u32(arm->spsr->value, 0, 32, buffer[7]);\n\t\tarm->spsr->dirty = false;\n\t\tarm->spsr->valid = true;\n\t} else {\n\t\t/* r8 to r14, but no spsr */\n\t\txscale_receive(target, buffer, 7);\n\t}\n\n\t/* move data from buffer to right banked register in cache */\n\tfor (i = 8; i <= 14; i++) {\n\t\tstruct reg *r = arm_reg_current(arm, i);\n\n\t\tbuf_set_u32(r->value, 0, 32, buffer[i - 8]);\n\t\tr->dirty = false;\n\t\tr->valid = true;\n\t}\n\n\t/* mark xscale regs invalid to ensure they are retrieved from the\n\t * debug handler if requested  */\n\tfor (i = 0; i < xscale->reg_cache->num_regs; i++)\n\t\txscale->reg_cache->reg_list[i].valid = false;\n\n\t/* examine debug reason */\n\txscale_read_dcsr(target);\n\tmoe = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 2, 3);\n\n\t/* stored PC (for calculating fixup) */\n\tpc = buf_get_u32(arm->pc->value, 0, 32);\n\n\tswitch (moe) {\n\t\tcase 0x0:\t/* Processor reset */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_RESET;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x1:\t/* Instruction breakpoint hit */\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x2:\t/* Data breakpoint hit */\n\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x3:\t/* BKPT instruction executed */\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x4:\t/* Ext. debug event */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x5:\t/* Vector trap occurred */\n\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x6:\t/* Trace buffer full break */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\txscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;\n\t\t\tpc -= 4;\n\t\t\tbreak;\n\t\tcase 0x7:\t/* Reserved (may flag Hot-Debug support) */\n\t\tdefault:\n\t\t\tLOG_ERROR(\"Method of Entry is 'Reserved'\");\n\t\t\texit(-1);\n\t\t\tbreak;\n\t}\n\n\t/* apply PC fixup */\n\tbuf_set_u32(arm->pc->value, 0, 32, pc);\n\n\t/* on the first debug entry, identify cache type */\n\tif (xscale->armv4_5_mmu.armv4_5_cache.ctype == -1) {\n\t\tuint32_t cache_type_reg;\n\n\t\t/* read cp15 cache type register */\n\t\txscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CACHETYPE]);\n\t\tcache_type_reg = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CACHETYPE].value,\n\t\t\t\t0,\n\t\t\t\t32);\n\n\t\tarmv4_5_identify_cache(cache_type_reg, &xscale->armv4_5_mmu.armv4_5_cache);\n\t}\n\n\t/* examine MMU and Cache settings\n\t * read cp15 control register */\n\txscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);\n\txscale->cp15_control_reg =\n\t\tbuf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);\n\txscale->armv4_5_mmu.mmu_enabled = (xscale->cp15_control_reg & 0x1U) ? 1 : 0;\n\txscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled =\n\t\t(xscale->cp15_control_reg & 0x4U) ? 1 : 0;\n\txscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled =\n\t\t(xscale->cp15_control_reg & 0x1000U) ? 1 : 0;\n\n\t/* tracing enabled, read collected trace data */\n\tif (xscale->trace.mode != XSCALE_TRACE_DISABLED) {\n\t\txscale_read_trace(target);\n\n\t\t/* Resume if entered debug due to buffer fill and we're still collecting\n\t\t * trace data.  Note that a debug exception due to trace buffer full\n\t\t * can only happen in fill mode. */\n\t\tif (xscale->arch_debug_reason == XSCALE_DBG_REASON_TB_FULL) {\n\t\t\tif (--xscale->trace.fill_counter > 0)\n\t\t\t\txscale_resume(target, 1, 0x0, 1, 0);\n\t\t} else\t/* entered debug for other reason; reset counter */\n\t\t\txscale->trace.fill_counter = 0;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_halt(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_DEBUG(\"target was already halted\");\n\t\treturn ERROR_OK;\n\t} else if (target->state == TARGET_UNKNOWN) {\n\t\t/* this must not happen for a xscale target */\n\t\tLOG_ERROR(\"target was in unknown state when halt was requested\");\n\t\treturn ERROR_TARGET_INVALID;\n\t} else if (target->state == TARGET_RESET)\n\t\tLOG_DEBUG(\"target->state == TARGET_RESET\");\n\telse {\n\t\t/* assert external dbg break */\n\t\txscale->external_debug_break = 1;\n\t\txscale_read_dcsr(target);\n\n\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_enable_single_step(struct target *target, uint32_t next_pc)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];\n\tint retval;\n\n\tif (xscale->ibcr0_used) {\n\t\tstruct breakpoint *ibcr0_bp =\n\t\t\tbreakpoint_find(target, buf_get_u32(ibcr0->value, 0, 32) & 0xfffffffe);\n\n\t\tif (ibcr0_bp)\n\t\t\txscale_unset_breakpoint(target, ibcr0_bp);\n\t\telse {\n\t\t\tLOG_ERROR(\n\t\t\t\t\"BUG: xscale->ibcr0_used is set, but no breakpoint with that address found\");\n\t\t\texit(-1);\n\t\t}\n\t}\n\n\tretval = xscale_set_reg_u32(ibcr0, next_pc | 0x1);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_disable_single_step(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct reg *ibcr0 = &xscale->reg_cache->reg_list[XSCALE_IBCR0];\n\tint retval;\n\n\tretval = xscale_set_reg_u32(ibcr0, 0x0);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn ERROR_OK;\n}\n\nstatic void xscale_enable_watchpoints(struct target *target)\n{\n\tstruct watchpoint *watchpoint = target->watchpoints;\n\n\twhile (watchpoint) {\n\t\tif (!watchpoint->is_set)\n\t\t\txscale_set_watchpoint(target, watchpoint);\n\t\twatchpoint = watchpoint->next;\n\t}\n}\n\nstatic void xscale_enable_breakpoints(struct target *target)\n{\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\t/* set any pending breakpoints */\n\twhile (breakpoint) {\n\t\tif (!breakpoint->is_set)\n\t\t\txscale_set_breakpoint(target, breakpoint);\n\t\tbreakpoint = breakpoint->next;\n\t}\n}\n\nstatic void xscale_free_trace_data(struct xscale_common *xscale)\n{\n\tstruct xscale_trace_data *td = xscale->trace.data;\n\twhile (td) {\n\t\tstruct xscale_trace_data *next_td = td->next;\n\t\tfree(td->entries);\n\t\tfree(td);\n\t\ttd = next_td;\n\t}\n\txscale->trace.data = NULL;\n}\n\nstatic int xscale_resume(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints, int debug_execution)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\tuint32_t current_pc;\n\tint retval;\n\tint i;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!debug_execution)\n\t\ttarget_free_all_working_areas(target);\n\n\t/* update vector tables */\n\tretval = xscale_update_vectors(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current)\n\t\tbuf_set_u32(arm->pc->value, 0, 32, address);\n\n\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\t/* if we're at the reset vector, we have to simulate the branch */\n\tif (current_pc == 0x0) {\n\t\tarm_simulate_step(target, NULL);\n\t\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\t}\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints) {\n\t\tstruct breakpoint *breakpoint;\n\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\t\tif (breakpoint) {\n\t\t\tuint32_t next_pc;\n\t\t\tenum trace_mode saved_trace_mode;\n\n\t\t\t/* there's a breakpoint at the current PC, we have to step over it */\n\t\t\tLOG_DEBUG(\"unset breakpoint at \" TARGET_ADDR_FMT \"\",\n\t\t\t\tbreakpoint->address);\n\t\t\txscale_unset_breakpoint(target, breakpoint);\n\n\t\t\t/* calculate PC of next instruction */\n\t\t\tretval = arm_simulate_step(target, &next_pc);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tuint32_t current_opcode;\n\t\t\t\ttarget_read_u32(target, current_pc, &current_opcode);\n\t\t\t\tLOG_ERROR(\n\t\t\t\t\t\"BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\tcurrent_opcode);\n\t\t\t}\n\n\t\t\tLOG_DEBUG(\"enable single-step\");\n\t\t\txscale_enable_single_step(target, next_pc);\n\n\t\t\t/* restore banked registers */\n\t\t\tretval = xscale_restore_banked(target);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\n\t\t\t/* send resume request */\n\t\t\txscale_send_u32(target, 0x30);\n\n\t\t\t/* send CPSR */\n\t\t\txscale_send_u32(target,\n\t\t\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\t\t\tLOG_DEBUG(\"writing cpsr with value 0x%8.8\" PRIx32,\n\t\t\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\n\t\t\tfor (i = 7; i >= 0; i--) {\n\t\t\t\t/* send register */\n\t\t\t\txscale_send_u32(target,\n\t\t\t\t\tbuf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t\t\t\tLOG_DEBUG(\"writing r%i with value 0x%8.8\" PRIx32 \"\",\n\t\t\t\t\ti, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t\t\t}\n\n\t\t\t/* send PC */\n\t\t\txscale_send_u32(target,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\t\t\tLOG_DEBUG(\"writing PC with value 0x%8.8\" PRIx32,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\n\t\t\t/* disable trace data collection in xscale_debug_entry() */\n\t\t\tsaved_trace_mode = xscale->trace.mode;\n\t\t\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\n\t\t\t/* wait for and process debug entry */\n\t\t\txscale_debug_entry(target);\n\n\t\t\t/* re-enable trace buffer, if enabled previously */\n\t\t\txscale->trace.mode = saved_trace_mode;\n\n\t\t\tLOG_DEBUG(\"disable single-step\");\n\t\t\txscale_disable_single_step(target);\n\n\t\t\tLOG_DEBUG(\"set breakpoint at \" TARGET_ADDR_FMT \"\",\n\t\t\t\tbreakpoint->address);\n\t\t\txscale_set_breakpoint(target, breakpoint);\n\t\t}\n\t}\n\n\t/* enable any pending breakpoints and watchpoints */\n\txscale_enable_breakpoints(target);\n\txscale_enable_watchpoints(target);\n\n\t/* restore banked registers */\n\tretval = xscale_restore_banked(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send resume request (command 0x30 or 0x31)\n\t * clean the trace buffer if it is to be enabled (0x62) */\n\tif (xscale->trace.mode != XSCALE_TRACE_DISABLED) {\n\t\tif (xscale->trace.mode == XSCALE_TRACE_FILL) {\n\t\t\t/* If trace enabled in fill mode and starting collection of new set\n\t\t\t     * of buffers, initialize buffer counter and free previous buffers */\n\t\t\tif (xscale->trace.fill_counter == 0) {\n\t\t\t\txscale->trace.fill_counter = xscale->trace.buffer_fill;\n\t\t\t\txscale_free_trace_data(xscale);\n\t\t\t}\n\t\t} else\t/* wrap mode; free previous buffer */\n\t\t\txscale_free_trace_data(xscale);\n\n\t\txscale_send_u32(target, 0x62);\n\t\txscale_send_u32(target, 0x31);\n\t} else\n\t\txscale_send_u32(target, 0x30);\n\n\t/* send CPSR */\n\txscale_send_u32(target, buf_get_u32(arm->cpsr->value, 0, 32));\n\tLOG_DEBUG(\"writing cpsr with value 0x%8.8\" PRIx32,\n\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\n\tfor (i = 7; i >= 0; i--) {\n\t\t/* send register */\n\t\txscale_send_u32(target, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t\tLOG_DEBUG(\"writing r%i with value 0x%8.8\" PRIx32 \"\",\n\t\t\ti, buf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t}\n\n\t/* send PC */\n\txscale_send_u32(target, buf_get_u32(arm->pc->value, 0, 32));\n\tLOG_DEBUG(\"wrote PC with value 0x%8.8\" PRIx32,\n\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\n\tif (!debug_execution) {\n\t\t/* registers are now invalid */\n\t\tregister_cache_invalidate(arm->core_cache);\n\t\ttarget->state = TARGET_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\t} else {\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);\n\t}\n\n\tLOG_DEBUG(\"target resumed\");\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_step_inner(struct target *target, int current,\n\tuint32_t address, int handle_breakpoints)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\tuint32_t next_pc;\n\tint retval;\n\tint i;\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\n\t/* calculate PC of next instruction */\n\tretval = arm_simulate_step(target, &next_pc);\n\tif (retval != ERROR_OK) {\n\t\tuint32_t current_opcode, current_pc;\n\t\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\t\ttarget_read_u32(target, current_pc, &current_opcode);\n\t\tLOG_ERROR(\n\t\t\t\"BUG: couldn't calculate PC of next instruction, current opcode was 0x%8.8\" PRIx32 \"\",\n\t\t\tcurrent_opcode);\n\t\treturn retval;\n\t}\n\n\tLOG_DEBUG(\"enable single-step\");\n\tretval = xscale_enable_single_step(target, next_pc);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* restore banked registers */\n\tretval = xscale_restore_banked(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send resume request (command 0x30 or 0x31)\n\t * clean the trace buffer if it is to be enabled (0x62) */\n\tif (xscale->trace.mode != XSCALE_TRACE_DISABLED) {\n\t\tretval = xscale_send_u32(target, 0x62);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = xscale_send_u32(target, 0x31);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t} else {\n\t\tretval = xscale_send_u32(target, 0x30);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\t/* send CPSR */\n\tretval = xscale_send_u32(target,\n\t\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"writing cpsr with value 0x%8.8\" PRIx32,\n\t\tbuf_get_u32(arm->cpsr->value, 0, 32));\n\n\tfor (i = 7; i >= 0; i--) {\n\t\t/* send register */\n\t\tretval = xscale_send_u32(target,\n\t\t\t\tbuf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tLOG_DEBUG(\"writing r%i with value 0x%8.8\" PRIx32 \"\", i,\n\t\t\tbuf_get_u32(arm->core_cache->reg_list[i].value, 0, 32));\n\t}\n\n\t/* send PC */\n\tretval = xscale_send_u32(target,\n\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tLOG_DEBUG(\"wrote PC with value 0x%8.8\" PRIx32,\n\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\t/* registers are now invalid */\n\tregister_cache_invalidate(arm->core_cache);\n\n\t/* wait for and process debug entry */\n\tretval = xscale_debug_entry(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tLOG_DEBUG(\"disable single-step\");\n\tretval = xscale_disable_single_step(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_step(struct target *target, int current,\n\ttarget_addr_t address, int handle_breakpoints)\n{\n\tstruct arm *arm = target_to_arm(target);\n\tstruct breakpoint *breakpoint = NULL;\n\n\tuint32_t current_pc;\n\tint retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* current = 1: continue on current pc, otherwise continue at <address> */\n\tif (!current)\n\t\tbuf_set_u32(arm->pc->value, 0, 32, address);\n\n\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\n\t/* if we're at the reset vector, we have to simulate the step */\n\tif (current_pc == 0x0) {\n\t\tretval = arm_simulate_step(target, NULL);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcurrent_pc = buf_get_u32(arm->pc->value, 0, 32);\n\t\tLOG_DEBUG(\"current pc %\" PRIx32, current_pc);\n\n\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\t\treturn ERROR_OK;\n\t}\n\n\t/* the front-end may request us not to handle breakpoints */\n\tif (handle_breakpoints)\n\t\tbreakpoint = breakpoint_find(target,\n\t\t\t\tbuf_get_u32(arm->pc->value, 0, 32));\n\tif (breakpoint) {\n\t\tretval = xscale_unset_breakpoint(target, breakpoint);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\tretval = xscale_step_inner(target, current, address, handle_breakpoints);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (breakpoint)\n\t\txscale_set_breakpoint(target, breakpoint);\n\n\tLOG_DEBUG(\"target stepped\");\n\n\treturn ERROR_OK;\n\n}\n\nstatic int xscale_assert_reset(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\t/* TODO: apply hw reset signal in not examined state */\n\tif (!(target_was_examined(target))) {\n\t\tLOG_WARNING(\"Reset is not asserted because the target is not examined.\");\n\t\tLOG_WARNING(\"Use a reset button or power cycle the target.\");\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tLOG_DEBUG(\"target->state: %s\",\n\t\ttarget_state_name(target));\n\n\t/* assert reset */\n\tjtag_add_reset(0, 1);\n\n\t/* sleep 1ms, to be sure we fulfill any requirements */\n\tjtag_add_sleep(1000);\n\tjtag_execute_queue();\n\n\t/* select DCSR instruction (set endstate to R-T-I to ensure we don't\n\t * end up in T-L-R, which would reset JTAG\n\t */\n\txscale_jtag_set_instr(target->tap,\n\t\tXSCALE_SELDCSR << xscale->xscale_variant,\n\t\tTAP_IDLE);\n\n\t/* set Hold reset, Halt mode and Trap Reset */\n\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);\n\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);\n\txscale_write_dcsr(target, 1, 0);\n\n\t/* select BYPASS, because having DCSR selected caused problems on the PXA27x */\n\txscale_jtag_set_instr(target->tap, ~0, TAP_IDLE);\n\tjtag_execute_queue();\n\n\ttarget->state = TARGET_RESET;\n\n\tif (target->reset_halt) {\n\t\tint retval = target_halt(target);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_deassert_reset(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct breakpoint *breakpoint = target->breakpoints;\n\n\tLOG_DEBUG(\"-\");\n\n\txscale->ibcr_available = 2;\n\txscale->ibcr0_used = 0;\n\txscale->ibcr1_used = 0;\n\n\txscale->dbr_available = 2;\n\txscale->dbr0_used = 0;\n\txscale->dbr1_used = 0;\n\n\t/* mark all hardware breakpoints as unset */\n\twhile (breakpoint) {\n\t\tif (breakpoint->type == BKPT_HARD)\n\t\t\tbreakpoint->is_set = false;\n\t\tbreakpoint = breakpoint->next;\n\t}\n\n\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\txscale_free_trace_data(xscale);\n\n\tregister_cache_invalidate(xscale->arm.core_cache);\n\n\t/* FIXME mark hardware watchpoints got unset too.  Also,\n\t * at least some of the XScale registers are invalid...\n\t */\n\n\t/*\n\t * REVISIT:  *assumes* we had a SRST+TRST reset so the mini-icache\n\t * contents got invalidated.  Safer to force that, so writing new\n\t * contents can't ever fail..\n\t */\n\t{\n\t\tuint32_t address;\n\t\tunsigned buf_cnt;\n\t\tconst uint8_t *buffer = xscale_debug_handler;\n\t\tint retval;\n\n\t\t/* release SRST */\n\t\tjtag_add_reset(0, 0);\n\n\t\t/* wait 300ms; 150 and 100ms were not enough */\n\t\tjtag_add_sleep(300*1000);\n\n\t\tjtag_add_runtest(2030, TAP_IDLE);\n\t\tjtag_execute_queue();\n\n\t\t/* set Hold reset, Halt mode and Trap Reset */\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);\n\t\txscale_write_dcsr(target, 1, 0);\n\n\t\t/* Load the debug handler into the mini-icache.  Since\n\t\t * it's using halt mode (not monitor mode), it runs in\n\t\t * \"Special Debug State\" for access to registers, memory,\n\t\t * coprocessors, trace data, etc.\n\t\t */\n\t\taddress = xscale->handler_address;\n\t\tfor (unsigned binary_size = sizeof(xscale_debug_handler);\n\t\t\tbinary_size > 0;\n\t\t\tbinary_size -= buf_cnt, buffer += buf_cnt) {\n\t\t\tuint32_t cache_line[8];\n\t\t\tunsigned i;\n\n\t\t\tbuf_cnt = binary_size;\n\t\t\tif (buf_cnt > 32)\n\t\t\t\tbuf_cnt = 32;\n\n\t\t\tfor (i = 0; i < buf_cnt; i += 4) {\n\t\t\t\t/* convert LE buffer to host-endian uint32_t */\n\t\t\t\tcache_line[i / 4] = le_to_h_u32(&buffer[i]);\n\t\t\t}\n\n\t\t\tfor (; i < 32; i += 4)\n\t\t\t\tcache_line[i / 4] = 0xe1a08008;\n\n\t\t\t/* only load addresses other than the reset vectors */\n\t\t\tif ((address % 0x400) != 0x0) {\n\t\t\t\tretval = xscale_load_ic(target, address,\n\t\t\t\t\t\tcache_line);\n\t\t\t\tif (retval != ERROR_OK)\n\t\t\t\t\treturn retval;\n\t\t\t}\n\n\t\t\taddress += buf_cnt;\n\t\t}\n\n\t\tretval = xscale_load_ic(target, 0x0,\n\t\t\t\txscale->low_vectors);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = xscale_load_ic(target, 0xffff0000,\n\t\t\t\txscale->high_vectors);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tjtag_add_runtest(30, TAP_IDLE);\n\n\t\tjtag_add_sleep(100000);\n\n\t\t/* set Hold reset, Halt mode and Trap Reset */\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 30, 1, 0x1);\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 16, 1, 0x1);\n\t\txscale_write_dcsr(target, 1, 0);\n\n\t\t/* clear Hold reset to let the target run (should enter debug handler) */\n\t\txscale_write_dcsr(target, 0, 1);\n\t\ttarget->state = TARGET_RUNNING;\n\n\t\tif (!target->reset_halt) {\n\t\t\tjtag_add_sleep(10000);\n\n\t\t\t/* we should have entered debug now */\n\t\t\txscale_debug_entry(target);\n\t\t\ttarget->state = TARGET_HALTED;\n\n\t\t\t/* resume the target */\n\t\t\txscale_resume(target, 1, 0x0, 1, 0);\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode)\n{\n\t/** \\todo add debug handler support for core register reads */\n\tLOG_ERROR(\"not implemented\");\n\treturn ERROR_OK;\n}\n\nstatic int xscale_write_core_reg(struct target *target, struct reg *r,\n\tint num, enum arm_mode mode, uint8_t *value)\n{\n\t/** \\todo add debug handler support for core register writes */\n\tLOG_ERROR(\"not implemented\");\n\treturn ERROR_OK;\n}\n\nstatic int xscale_full_context(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tuint32_t *buffer;\n\n\tint i, j;\n\n\tLOG_DEBUG(\"-\");\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tbuffer = malloc(4 * 8);\n\n\t/* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)\n\t * we can't enter User mode on an XScale (unpredictable),\n\t * but User shares registers with SYS\n\t */\n\tfor (i = 1; i < 7; i++) {\n\t\tenum arm_mode mode = armv4_5_number_to_mode(i);\n\t\tbool valid = true;\n\t\tstruct reg *r;\n\n\t\tif (mode == ARM_MODE_USR)\n\t\t\tcontinue;\n\n\t\t/* check if there are invalid registers in the current mode\n\t\t */\n\t\tfor (j = 0; valid && j <= 16; j++) {\n\t\t\tif (!ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tmode, j).valid)\n\t\t\t\tvalid = false;\n\t\t}\n\t\tif (valid)\n\t\t\tcontinue;\n\n\t\t/* request banked registers */\n\t\txscale_send_u32(target, 0x0);\n\n\t\t/* send CPSR for desired bank mode */\n\t\txscale_send_u32(target, mode | 0xc0 /* I/F bits */);\n\n\t\t/* get banked registers:  r8 to r14; and SPSR\n\t\t * except in USR/SYS mode\n\t\t */\n\t\tif (mode != ARM_MODE_SYS) {\n\t\t\t/* SPSR */\n\t\t\tr = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\tmode, 16);\n\n\t\t\txscale_receive(target, buffer, 8);\n\n\t\t\tbuf_set_u32(r->value, 0, 32, buffer[7]);\n\t\t\tr->dirty = false;\n\t\t\tr->valid = true;\n\t\t} else\n\t\t\txscale_receive(target, buffer, 7);\n\n\t\t/* move data from buffer to register cache */\n\t\tfor (j = 8; j <= 14; j++) {\n\t\t\tr = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\tmode, j);\n\n\t\t\tbuf_set_u32(r->value, 0, 32, buffer[j - 8]);\n\t\t\tr->dirty = false;\n\t\t\tr->valid = true;\n\t\t}\n\t}\n\n\tfree(buffer);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_restore_banked(struct target *target)\n{\n\tstruct arm *arm = target_to_arm(target);\n\n\tint i, j;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* iterate through processor modes (FIQ, IRQ, SVC, ABT, UND and SYS)\n\t * and check if any banked registers need to be written.  Ignore\n\t * USR mode (number 0) in favor of SYS; we can't enter User mode on\n\t * an XScale (unpredictable), but they share all registers.\n\t */\n\tfor (i = 1; i < 7; i++) {\n\t\tenum arm_mode mode = armv4_5_number_to_mode(i);\n\t\tstruct reg *r;\n\n\t\tif (mode == ARM_MODE_USR)\n\t\t\tcontinue;\n\n\t\t/* check if there are dirty registers in this mode */\n\t\tfor (j = 8; j <= 14; j++) {\n\t\t\tif (ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tmode, j).dirty)\n\t\t\t\tgoto dirty;\n\t\t}\n\n\t\t/* if not USR/SYS, check if the SPSR needs to be written */\n\t\tif (mode != ARM_MODE_SYS) {\n\t\t\tif (ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\tmode, 16).dirty)\n\t\t\t\tgoto dirty;\n\t\t}\n\n\t\t/* there's nothing to flush for this mode */\n\t\tcontinue;\n\ndirty:\n\t\t/* command 0x1:  \"send banked registers\" */\n\t\txscale_send_u32(target, 0x1);\n\n\t\t/* send CPSR for desired mode */\n\t\txscale_send_u32(target, mode | 0xc0 /* I/F bits */);\n\n\t\t/* send r8 to r14/lr ... only FIQ needs more than r13..r14,\n\t\t * but this protocol doesn't understand that nuance.\n\t\t */\n\t\tfor (j = 8; j <= 14; j++) {\n\t\t\tr = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\tmode, j);\n\t\t\txscale_send_u32(target, buf_get_u32(r->value, 0, 32));\n\t\t\tr->dirty = false;\n\t\t}\n\n\t\t/* send spsr if not in USR/SYS mode */\n\t\tif (mode != ARM_MODE_SYS) {\n\t\t\tr = &ARMV4_5_CORE_REG_MODE(arm->core_cache,\n\t\t\t\t\tmode, 16);\n\t\t\txscale_send_u32(target, buf_get_u32(r->value, 0, 32));\n\t\t\tr->dirty = false;\n\t\t}\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t *buf32;\n\tuint32_t i;\n\tint retval;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32,\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* send memory read request (command 0x1n, n: access size) */\n\tretval = xscale_send_u32(target, 0x10 | size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send base address for read request */\n\tretval = xscale_send_u32(target, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send number of requested data words */\n\tretval = xscale_send_u32(target, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* receive data from target (count times 32-bit words in host endianness) */\n\tbuf32 = malloc(4 * count);\n\tretval = xscale_receive(target, buf32, count);\n\tif (retval != ERROR_OK) {\n\t\tfree(buf32);\n\t\treturn retval;\n\t}\n\n\t/* extract data from host-endian buffer into byte stream */\n\tfor (i = 0; i < count; i++) {\n\t\tswitch (size) {\n\t\t\tcase 4:\n\t\t\t\ttarget_buffer_set_u32(target, buffer, buf32[i]);\n\t\t\t\tbuffer += 4;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\ttarget_buffer_set_u16(target, buffer, buf32[i] & 0xffff);\n\t\t\t\tbuffer += 2;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\t*buffer++ = buf32[i] & 0xff;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"invalid read size\");\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tfree(buf32);\n\n\t/* examine DCSR, to see if Sticky Abort (SA) got set */\n\tretval = xscale_read_dcsr(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) {\n\t\t/* clear SA bit */\n\t\tretval = xscale_send_u32(target, 0x60);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_phys_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\t/* with MMU inactive, there are only physical addresses */\n\tif (!xscale->armv4_5_mmu.mmu_enabled)\n\t\treturn xscale_read_memory(target, address, size, count, buffer);\n\n\t/** \\todo: provide a non-stub implementation of this routine. */\n\tLOG_ERROR(\"%s: %s is not implemented.  Disable MMU?\",\n\t\ttarget_name(target), __func__);\n\treturn ERROR_FAIL;\n}\n\nstatic int xscale_write_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tLOG_DEBUG(\"address: \" TARGET_ADDR_FMT \", size: 0x%8.8\" PRIx32 \", count: 0x%8.8\" PRIx32,\n\t\taddress,\n\t\tsize,\n\t\tcount);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* sanitize arguments */\n\tif (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))\n\t\treturn ERROR_TARGET_UNALIGNED_ACCESS;\n\n\t/* send memory write request (command 0x2n, n: access size) */\n\tretval = xscale_send_u32(target, 0x20 | size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send base address for read request */\n\tretval = xscale_send_u32(target, address);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* send number of requested data words to be written*/\n\tretval = xscale_send_u32(target, count);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* extract data from host-endian buffer into byte stream */\n#if 0\n\tfor (i = 0; i < count; i++) {\n\t\tswitch (size) {\n\t\t\tcase 4:\n\t\t\t\tvalue = target_buffer_get_u32(target, buffer);\n\t\t\t\txscale_send_u32(target, value);\n\t\t\t\tbuffer += 4;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\tvalue = target_buffer_get_u16(target, buffer);\n\t\t\t\txscale_send_u32(target, value);\n\t\t\t\tbuffer += 2;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\tvalue = *buffer;\n\t\t\t\txscale_send_u32(target, value);\n\t\t\t\tbuffer += 1;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"should never get here\");\n\t\t\t\texit(-1);\n\t\t}\n\t}\n#endif\n\tretval = xscale_send(target, buffer, count, size);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* examine DCSR, to see if Sticky Abort (SA) got set */\n\tretval = xscale_read_dcsr(target);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tif (buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 5, 1) == 1) {\n\t\t/* clear SA bit */\n\t\tretval = xscale_send_u32(target, 0x60);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tLOG_ERROR(\"data abort writing memory\");\n\t\treturn ERROR_TARGET_DATA_ABORT;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_write_phys_memory(struct target *target, target_addr_t address,\n\tuint32_t size, uint32_t count, const uint8_t *buffer)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\t/* with MMU inactive, there are only physical addresses */\n\tif (!xscale->armv4_5_mmu.mmu_enabled)\n\t\treturn xscale_write_memory(target, address, size, count, buffer);\n\n\t/** \\todo: provide a non-stub implementation of this routine. */\n\tLOG_ERROR(\"%s: %s is not implemented.  Disable MMU?\",\n\t\ttarget_name(target), __func__);\n\treturn ERROR_FAIL;\n}\n\nstatic int xscale_get_ttb(struct target *target, uint32_t *result)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t ttb;\n\tint retval;\n\n\tretval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_TTB]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tttb = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_TTB].value, 0, 32);\n\n\t*result = ttb;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_disable_mmu_caches(struct target *target, int mmu,\n\tint d_u_cache, int i_cache)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);\n\n\tif (mmu)\n\t\tcp15_control &= ~0x1U;\n\n\tif (d_u_cache) {\n\t\t/* clean DCache */\n\t\tretval = xscale_send_u32(target, 0x50);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tretval = xscale_send_u32(target, xscale->cache_clean_address);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\t/* invalidate DCache */\n\t\tretval = xscale_send_u32(target, 0x51);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\n\t\tcp15_control &= ~0x4U;\n\t}\n\n\tif (i_cache) {\n\t\t/* invalidate ICache */\n\t\tretval = xscale_send_u32(target, 0x52);\n\t\tif (retval != ERROR_OK)\n\t\t\treturn retval;\n\t\tcp15_control &= ~0x1000U;\n\t}\n\n\t/* write new cp15 control register */\n\tretval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* execute cpwait to ensure outstanding operations complete */\n\tretval = xscale_send_u32(target, 0x53);\n\treturn retval;\n}\n\nstatic int xscale_enable_mmu_caches(struct target *target, int mmu,\n\tint d_u_cache, int i_cache)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t cp15_control;\n\tint retval;\n\n\t/* read cp15 control register */\n\tretval = xscale_get_reg(&xscale->reg_cache->reg_list[XSCALE_CTRL]);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\tcp15_control = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_CTRL].value, 0, 32);\n\n\tif (mmu)\n\t\tcp15_control |= 0x1U;\n\n\tif (d_u_cache)\n\t\tcp15_control |= 0x4U;\n\n\tif (i_cache)\n\t\tcp15_control |= 0x1000U;\n\n\t/* write new cp15 control register */\n\tretval = xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_CTRL], cp15_control);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\t/* execute cpwait to ensure outstanding operations complete */\n\tretval = xscale_send_u32(target, 0x53);\n\treturn retval;\n}\n\nstatic int xscale_set_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tint retval;\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint already set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tuint32_t value = breakpoint->address | 1;\n\t\tif (!xscale->ibcr0_used) {\n\t\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);\n\t\t\txscale->ibcr0_used = 1;\n\t\t\t/* breakpoint set on first breakpoint register */\n\t\t\tbreakpoint_hw_set(breakpoint, 0);\n\t\t} else if (!xscale->ibcr1_used) {\n\t\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);\n\t\t\txscale->ibcr1_used = 1;\n\t\t\t/* breakpoint set on second breakpoint register */\n\t\t\tbreakpoint_hw_set(breakpoint, 1);\n\t\t} else {/* bug: availability previously verified in xscale_add_breakpoint() */\n\t\t\tLOG_ERROR(\"BUG: no hardware comparator available\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t} else if (breakpoint->type == BKPT_SOFT) {\n\t\tif (breakpoint->length == 4) {\n\t\t\t/* keep the original instruction in target endianness */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 4, 1,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* write the bkpt instruction in target endianness\n\t\t\t *(arm7_9->arm_bkpt is host endian) */\n\t\t\tretval = target_write_u32(target, breakpoint->address,\n\t\t\t\t\txscale->arm_bkpt);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* keep the original instruction in target endianness */\n\t\t\tretval = target_read_memory(target, breakpoint->address, 2, 1,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\t/* write the bkpt instruction in target endianness\n\t\t\t *(arm7_9->arm_bkpt is host endian) */\n\t\t\tretval = target_write_u16(target, breakpoint->address,\n\t\t\t\t\txscale->thumb_bkpt);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tbreakpoint->is_set = true;\n\n\t\txscale_send_u32(target, 0x50);\t/* clean dcache */\n\t\txscale_send_u32(target, xscale->cache_clean_address);\n\t\txscale_send_u32(target, 0x51);\t/* invalidate dcache */\n\t\txscale_send_u32(target, 0x52);\t/* invalidate icache and flush fetch buffers */\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_add_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif ((breakpoint->type == BKPT_HARD) && (xscale->ibcr_available < 1)) {\n\t\tLOG_ERROR(\"no breakpoint unit available for hardware breakpoint\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif ((breakpoint->length != 2) && (breakpoint->length != 4)) {\n\t\tLOG_ERROR(\"only breakpoints of two (Thumb) or four (ARM) bytes length supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\txscale->ibcr_available--;\n\n\treturn xscale_set_breakpoint(target, breakpoint);\n}\n\nstatic int xscale_unset_breakpoint(struct target *target,\n\tstruct breakpoint *breakpoint)\n{\n\tint retval;\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!breakpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (breakpoint->type == BKPT_HARD) {\n\t\tif (breakpoint->number == 0) {\n\t\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);\n\t\t\txscale->ibcr0_used = 0;\n\t\t} else if (breakpoint->number == 1) {\n\t\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);\n\t\t\txscale->ibcr1_used = 0;\n\t\t}\n\t\tbreakpoint->is_set = false;\n\t} else {\n\t\t/* restore original instruction (kept in target endianness) */\n\t\tif (breakpoint->length == 4) {\n\t\t\tretval = target_write_memory(target, breakpoint->address, 4, 1,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t} else {\n\t\t\tretval = target_write_memory(target, breakpoint->address, 2, 1,\n\t\t\t\t\tbreakpoint->orig_instr);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tbreakpoint->is_set = false;\n\n\t\txscale_send_u32(target, 0x50);\t/* clean dcache */\n\t\txscale_send_u32(target, xscale->cache_clean_address);\n\t\txscale_send_u32(target, 0x51);\t/* invalidate dcache */\n\t\txscale_send_u32(target, 0x52);\t/* invalidate icache and flush fetch buffers */\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (breakpoint->is_set)\n\t\txscale_unset_breakpoint(target, breakpoint);\n\n\tif (breakpoint->type == BKPT_HARD)\n\t\txscale->ibcr_available++;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_set_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t enable = 0;\n\tstruct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];\n\tuint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tswitch (watchpoint->rw) {\n\t\tcase WPT_READ:\n\t\t\tenable = 0x3;\n\t\t\tbreak;\n\t\tcase WPT_ACCESS:\n\t\t\tenable = 0x2;\n\t\t\tbreak;\n\t\tcase WPT_WRITE:\n\t\t\tenable = 0x1;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"BUG: watchpoint->rw neither read, write nor access\");\n\t}\n\n\t/* For watchpoint across more than one word, both DBR registers must\n\t   be enlisted, with the second used as a mask. */\n\tif (watchpoint->length > 4) {\n\t\tif (xscale->dbr0_used || xscale->dbr1_used) {\n\t\t\tLOG_ERROR(\"BUG: sufficient hardware comparators unavailable\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\n\t\t/* Write mask value to DBR1, based on the length argument.\n\t\t * Address bits ignored by the comparator are those set in mask. */\n\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1],\n\t\t\twatchpoint->length - 1);\n\t\txscale->dbr1_used = 1;\n\t\tenable |= 0x100;\t\t/* DBCON[M] */\n\t}\n\n\tif (!xscale->dbr0_used) {\n\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);\n\t\tdbcon_value |= enable;\n\t\txscale_set_reg_u32(dbcon, dbcon_value);\n\t\twatchpoint_set(watchpoint, 0);\n\t\txscale->dbr0_used = 1;\n\t} else if (!xscale->dbr1_used) {\n\t\txscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);\n\t\tdbcon_value |= enable << 2;\n\t\txscale_set_reg_u32(dbcon, dbcon_value);\n\t\twatchpoint_set(watchpoint, 1);\n\t\txscale->dbr1_used = 1;\n\t} else {\n\t\tLOG_ERROR(\"BUG: no hardware comparator available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_add_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (xscale->dbr_available < 1) {\n\t\tLOG_ERROR(\"no more watchpoint registers available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (watchpoint->value)\n\t\tLOG_WARNING(\"xscale does not support value, mask arguments; ignoring\");\n\n\t/* check that length is a power of two */\n\tfor (uint32_t len = watchpoint->length; len != 1; len /= 2) {\n\t\tif (len % 2) {\n\t\t\tLOG_ERROR(\"xscale requires that watchpoint length is a power of two\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (watchpoint->length == 4) {\t/* single word watchpoint */\n\t\txscale->dbr_available--;/* one DBR reg used */\n\t\treturn ERROR_OK;\n\t}\n\n\t/* watchpoints across multiple words require both DBR registers */\n\tif (xscale->dbr_available < 2) {\n\t\tLOG_ERROR(\"insufficient watchpoint registers available\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tif (watchpoint->length > watchpoint->address) {\n\t\tLOG_ERROR(\"xscale does not support watchpoints with length \"\n\t\t\t\"greater than address\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\txscale->dbr_available = 0;\n\treturn ERROR_OK;\n}\n\nstatic int xscale_unset_watchpoint(struct target *target,\n\tstruct watchpoint *watchpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct reg *dbcon = &xscale->reg_cache->reg_list[XSCALE_DBCON];\n\tuint32_t dbcon_value = buf_get_u32(dbcon->value, 0, 32);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!watchpoint->is_set) {\n\t\tLOG_WARNING(\"breakpoint not set\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (watchpoint->number == 0) {\n\t\tif (watchpoint->length > 4) {\n\t\t\tdbcon_value &= ~0x103;\t/* clear DBCON[M] as well */\n\t\t\txscale->dbr1_used = 0;\t/* DBR1 was used for mask */\n\t\t} else\n\t\t\tdbcon_value &= ~0x3;\n\n\t\txscale_set_reg_u32(dbcon, dbcon_value);\n\t\txscale->dbr0_used = 0;\n\t} else if (watchpoint->number == 1) {\n\t\tdbcon_value &= ~0xc;\n\t\txscale_set_reg_u32(dbcon, dbcon_value);\n\t\txscale->dbr1_used = 0;\n\t}\n\twatchpoint->is_set = false;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->is_set)\n\t\txscale_unset_watchpoint(target, watchpoint);\n\n\tif (watchpoint->length > 4)\n\t\txscale->dbr_available++;/* both DBR regs now available */\n\n\txscale->dbr_available++;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_get_reg(struct reg *reg)\n{\n\tstruct xscale_reg *arch_info = reg->arch_info;\n\tstruct target *target = arch_info->target;\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\t/* DCSR, TX and RX are accessible via JTAG */\n\tif (strcmp(reg->name, \"XSCALE_DCSR\") == 0)\n\t\treturn xscale_read_dcsr(arch_info->target);\n\telse if (strcmp(reg->name, \"XSCALE_TX\") == 0) {\n\t\t/* 1 = consume register content */\n\t\treturn xscale_read_tx(arch_info->target, 1);\n\t} else if (strcmp(reg->name, \"XSCALE_RX\") == 0) {\n\t\t/* can't read from RX register (host -> debug handler) */\n\t\treturn ERROR_OK;\n\t} else if (strcmp(reg->name, \"XSCALE_TXRXCTRL\") == 0) {\n\t\t/* can't (explicitly) read from TXRXCTRL register */\n\t\treturn ERROR_OK;\n\t} else {/* Other DBG registers have to be transferred by the debug handler\n\t\t * send CP read request (command 0x40) */\n\t\txscale_send_u32(target, 0x40);\n\n\t\t/* send CP register number */\n\t\txscale_send_u32(target, arch_info->dbg_handler_number);\n\n\t\t/* read register value */\n\t\txscale_read_tx(target, 1);\n\t\tbuf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);\n\n\t\treg->dirty = false;\n\t\treg->valid = true;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_set_reg(struct reg *reg, uint8_t *buf)\n{\n\tstruct xscale_reg *arch_info = reg->arch_info;\n\tstruct target *target = arch_info->target;\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t value = buf_get_u32(buf, 0, 32);\n\n\t/* DCSR, TX and RX are accessible via JTAG */\n\tif (strcmp(reg->name, \"XSCALE_DCSR\") == 0) {\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32, value);\n\t\treturn xscale_write_dcsr(arch_info->target, -1, -1);\n\t} else if (strcmp(reg->name, \"XSCALE_RX\") == 0) {\n\t\tbuf_set_u32(xscale->reg_cache->reg_list[XSCALE_RX].value, 0, 32, value);\n\t\treturn xscale_write_rx(arch_info->target);\n\t} else if (strcmp(reg->name, \"XSCALE_TX\") == 0) {\n\t\t/* can't write to TX register (debug-handler -> host) */\n\t\treturn ERROR_OK;\n\t} else if (strcmp(reg->name, \"XSCALE_TXRXCTRL\") == 0) {\n\t\t/* can't (explicitly) write to TXRXCTRL register */\n\t\treturn ERROR_OK;\n\t} else {/* Other DBG registers have to be transferred by the debug handler\n\t\t * send CP write request (command 0x41) */\n\t\txscale_send_u32(target, 0x41);\n\n\t\t/* send CP register number */\n\t\txscale_send_u32(target, arch_info->dbg_handler_number);\n\n\t\t/* send CP register value */\n\t\txscale_send_u32(target, value);\n\t\tbuf_set_u32(reg->value, 0, 32, value);\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_write_dcsr_sw(struct target *target, uint32_t value)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct reg *dcsr = &xscale->reg_cache->reg_list[XSCALE_DCSR];\n\tstruct xscale_reg *dcsr_arch_info = dcsr->arch_info;\n\n\t/* send CP write request (command 0x41) */\n\txscale_send_u32(target, 0x41);\n\n\t/* send CP register number */\n\txscale_send_u32(target, dcsr_arch_info->dbg_handler_number);\n\n\t/* send CP register value */\n\txscale_send_u32(target, value);\n\tbuf_set_u32(dcsr->value, 0, 32, value);\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_trace(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\tstruct xscale_trace_data **trace_data_p;\n\n\t/* 258 words from debug handler\n\t * 256 trace buffer entries\n\t * 2 checkpoint addresses\n\t */\n\tuint32_t trace_buffer[258];\n\tint is_address[256];\n\tint i, j;\n\tunsigned int num_checkpoints = 0;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_WARNING(\"target must be stopped to read trace data\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\t/* send read trace buffer command (command 0x61) */\n\txscale_send_u32(target, 0x61);\n\n\t/* receive trace buffer content */\n\txscale_receive(target, trace_buffer, 258);\n\n\t/* parse buffer backwards to identify address entries */\n\tfor (i = 255; i >= 0; i--) {\n\t\t/* also count number of checkpointed entries */\n\t\tif ((trace_buffer[i] & 0xe0) == 0xc0)\n\t\t\tnum_checkpoints++;\n\n\t\tis_address[i] = 0;\n\t\tif (((trace_buffer[i] & 0xf0) == 0x90) ||\n\t\t\t((trace_buffer[i] & 0xf0) == 0xd0)) {\n\t\t\tif (i > 0)\n\t\t\t\tis_address[--i] = 1;\n\t\t\tif (i > 0)\n\t\t\t\tis_address[--i] = 1;\n\t\t\tif (i > 0)\n\t\t\t\tis_address[--i] = 1;\n\t\t\tif (i > 0)\n\t\t\t\tis_address[--i] = 1;\n\t\t}\n\t}\n\n\n\t/* search first non-zero entry that is not part of an address */\n\tfor (j = 0; (j < 256) && (trace_buffer[j] == 0) && (!is_address[j]); j++)\n\t\t;\n\n\tif (j == 256) {\n\t\tLOG_DEBUG(\"no trace data collected\");\n\t\treturn ERROR_XSCALE_NO_TRACE_DATA;\n\t}\n\n\t/* account for possible partial address at buffer start (wrap mode only) */\n\tif (is_address[0]) {\t/* first entry is address; complete set of 4? */\n\t\ti = 1;\n\t\twhile (i < 4)\n\t\t\tif (!is_address[i++])\n\t\t\t\tbreak;\n\t\tif (i < 4)\n\t\t\tj += i;\t\t/* partial address; can't use it */\n\t}\n\n\t/* if first valid entry is indirect branch, can't use that either (no address) */\n\tif (((trace_buffer[j] & 0xf0) == 0x90) || ((trace_buffer[j] & 0xf0) == 0xd0))\n\t\tj++;\n\n\t/* walk linked list to terminating entry */\n\tfor (trace_data_p = &xscale->trace.data; *trace_data_p;\n\t\ttrace_data_p = &(*trace_data_p)->next)\n\t\t;\n\n\t*trace_data_p = malloc(sizeof(struct xscale_trace_data));\n\t(*trace_data_p)->next = NULL;\n\t(*trace_data_p)->chkpt0 = trace_buffer[256];\n\t(*trace_data_p)->chkpt1 = trace_buffer[257];\n\t(*trace_data_p)->last_instruction = buf_get_u32(arm->pc->value, 0, 32);\n\t(*trace_data_p)->entries = malloc(sizeof(struct xscale_trace_entry) * (256 - j));\n\t(*trace_data_p)->depth = 256 - j;\n\t(*trace_data_p)->num_checkpoints = num_checkpoints;\n\n\tfor (i = j; i < 256; i++) {\n\t\t(*trace_data_p)->entries[i - j].data = trace_buffer[i];\n\t\tif (is_address[i])\n\t\t\t(*trace_data_p)->entries[i - j].type = XSCALE_TRACE_ADDRESS;\n\t\telse\n\t\t\t(*trace_data_p)->entries[i - j].type = XSCALE_TRACE_MESSAGE;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_read_instruction(struct target *target, uint32_t pc,\n\tstruct arm_instruction *instruction)\n{\n\tstruct xscale_common *const xscale = target_to_xscale(target);\n\tint section = -1;\n\tsize_t size_read;\n\tuint32_t opcode;\n\tint retval;\n\n\tif (!xscale->trace.image)\n\t\treturn ERROR_TRACE_IMAGE_UNAVAILABLE;\n\n\t/* search for the section the current instruction belongs to */\n\tfor (unsigned int i = 0; i < xscale->trace.image->num_sections; i++) {\n\t\tif ((xscale->trace.image->sections[i].base_address <= pc) &&\n\t\t\t(xscale->trace.image->sections[i].base_address +\n\t\t\txscale->trace.image->sections[i].size > pc)) {\n\t\t\tsection = i;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (section == -1) {\n\t\t/* current instruction couldn't be found in the image */\n\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t}\n\n\tif (xscale->trace.core_state == ARM_STATE_ARM) {\n\t\tuint8_t buf[4];\n\t\tretval = image_read_section(xscale->trace.image, section,\n\t\t\t\tpc - xscale->trace.image->sections[section].base_address,\n\t\t\t\t4, buf, &size_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error while reading instruction\");\n\t\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t\t}\n\t\topcode = target_buffer_get_u32(target, buf);\n\t\tarm_evaluate_opcode(opcode, pc, instruction);\n\t} else if (xscale->trace.core_state == ARM_STATE_THUMB) {\n\t\tuint8_t buf[2];\n\t\tretval = image_read_section(xscale->trace.image, section,\n\t\t\t\tpc - xscale->trace.image->sections[section].base_address,\n\t\t\t\t2, buf, &size_read);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"error while reading instruction\");\n\t\t\treturn ERROR_TRACE_INSTRUCTION_UNAVAILABLE;\n\t\t}\n\t\topcode = target_buffer_get_u16(target, buf);\n\t\tthumb_evaluate_opcode(opcode, pc, instruction);\n\t} else {\n\t\tLOG_ERROR(\"BUG: unknown core state encountered\");\n\t\texit(-1);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/* Extract address encoded into trace data.\n * Write result to address referenced by argument 'target', or 0 if incomplete.  */\nstatic inline void xscale_branch_address(struct xscale_trace_data *trace_data,\n\tint i, uint32_t *target)\n{\n\t/* if there are less than four entries prior to the indirect branch message\n\t * we can't extract the address */\n\tif (i < 4)\n\t\t*target = 0;\n\telse {\n\t\t*target = (trace_data->entries[i-1].data) | (trace_data->entries[i-2].data << 8) |\n\t\t\t(trace_data->entries[i-3].data << 16) | (trace_data->entries[i-4].data << 24);\n\t}\n}\n\nstatic inline void xscale_display_instruction(struct target *target, uint32_t pc,\n\tstruct arm_instruction *instruction,\n\tstruct command_invocation *cmd)\n{\n\tint retval = xscale_read_instruction(target, pc, instruction);\n\tif (retval == ERROR_OK)\n\t\tcommand_print(cmd, \"%s\", instruction->text);\n\telse\n\t\tcommand_print(cmd, \"0x%8.8\" PRIx32 \"\\t<not found in image>\", pc);\n}\n\nstatic int xscale_analyze_trace(struct target *target, struct command_invocation *cmd)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct xscale_trace_data *trace_data = xscale->trace.data;\n\tint i, retval;\n\tuint32_t breakpoint_pc = 0;\n\tstruct arm_instruction instruction;\n\tuint32_t current_pc = 0;/* initialized when address determined */\n\n\tif (!xscale->trace.image)\n\t\tLOG_WARNING(\"No trace image loaded; use 'xscale trace_image'\");\n\n\t/* loop for each trace buffer that was loaded from target */\n\twhile (trace_data) {\n\t\tint chkpt = 0;\t/* incremented as checkpointed entries found */\n\t\tint j;\n\n\t\t/* FIXME: set this to correct mode when trace buffer is first enabled */\n\t\txscale->trace.core_state = ARM_STATE_ARM;\n\n\t\t/* loop for each entry in this trace buffer */\n\t\tfor (i = 0; i < trace_data->depth; i++) {\n\t\t\tint exception = 0;\n\t\t\tuint32_t chkpt_reg = 0x0;\n\t\t\tuint32_t branch_target = 0;\n\t\t\tint count;\n\n\t\t\t/* trace entry type is upper nybble of 'message byte' */\n\t\t\tint trace_msg_type = (trace_data->entries[i].data & 0xf0) >> 4;\n\n\t\t\t/* Target addresses of indirect branches are written into buffer\n\t\t\t * before the message byte representing the branch. Skip past it */\n\t\t\tif (trace_data->entries[i].type == XSCALE_TRACE_ADDRESS)\n\t\t\t\tcontinue;\n\n\t\t\tswitch (trace_msg_type) {\n\t\t\t\tcase 0:\t/* Exceptions */\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\tcase 4:\n\t\t\t\tcase 5:\n\t\t\t\tcase 6:\n\t\t\t\tcase 7:\n\t\t\t\t\texception = (trace_data->entries[i].data & 0x70) >> 4;\n\n\t\t\t\t\t/* FIXME: vector table may be at ffff0000 */\n\t\t\t\t\tbranch_target = (trace_data->entries[i].data & 0xf0) >> 2;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 8:\t/* Direct Branch */\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 9:\t/* Indirect Branch */\n\t\t\t\t\txscale_branch_address(trace_data, i, &branch_target);\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 13:\t/* Checkpointed Indirect Branch */\n\t\t\t\t\txscale_branch_address(trace_data, i, &branch_target);\n\t\t\t\t\tif ((trace_data->num_checkpoints == 2) && (chkpt == 0))\n\t\t\t\t\t\tchkpt_reg = trace_data->chkpt1;\t/* 2 chkpts, this is\n\t\t\t\t\t\t\t\t\t\t *oldest */\n\t\t\t\t\telse\n\t\t\t\t\t\tchkpt_reg = trace_data->chkpt0;\t/* 1 chkpt, or 2 and\n\t\t\t\t\t\t\t\t\t\t *newest */\n\n\t\t\t\t\tchkpt++;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 12:\t/* Checkpointed Direct Branch */\n\t\t\t\t\tif ((trace_data->num_checkpoints == 2) && (chkpt == 0))\n\t\t\t\t\t\tchkpt_reg = trace_data->chkpt1;\t/* 2 chkpts, this is\n\t\t\t\t\t\t\t\t\t\t *oldest */\n\t\t\t\t\telse\n\t\t\t\t\t\tchkpt_reg = trace_data->chkpt0;\t/* 1 chkpt, or 2 and\n\t\t\t\t\t\t\t\t\t\t *newest */\n\n\t\t\t\t\t/* if no current_pc, checkpoint will be starting point */\n\t\t\t\t\tif (current_pc == 0)\n\t\t\t\t\t\tbranch_target = chkpt_reg;\n\n\t\t\t\t\tchkpt++;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase 15:/* Roll-over */\n\t\t\t\t\tbreak;\n\n\t\t\t\tdefault:/* Reserved */\n\t\t\t\t\tLOG_WARNING(\"trace is suspect: invalid trace message byte\");\n\t\t\t\t\tcontinue;\n\n\t\t\t}\n\n\t\t\t/* If we don't have the current_pc yet, but we did get the branch target\n\t\t\t * (either from the trace buffer on indirect branch, or from a checkpoint reg),\n\t\t\t * then we can start displaying instructions at the next iteration, with\n\t\t\t * branch_target as the starting point.\n\t\t\t */\n\t\t\tif (current_pc == 0) {\n\t\t\t\tcurrent_pc = branch_target;\t/* remains 0 unless branch_target *obtained */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* We have current_pc.  Read and display the instructions from the image.\n\t\t\t * First, display count instructions (lower nybble of message byte). */\n\t\t\tcount = trace_data->entries[i].data & 0x0f;\n\t\t\tfor (j = 0; j < count; j++) {\n\t\t\t\txscale_display_instruction(target, current_pc, &instruction,\n\t\t\t\t\tcmd);\n\t\t\t\tcurrent_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;\n\t\t\t}\n\n\t\t\t/* An additional instruction is implicitly added to count for\n\t\t\t * rollover and some exceptions: undef, swi, prefetch abort. */\n\t\t\tif ((trace_msg_type == 15) || (exception > 0 && exception < 4)) {\n\t\t\t\txscale_display_instruction(target, current_pc, &instruction,\n\t\t\t\t\tcmd);\n\t\t\t\tcurrent_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;\n\t\t\t}\n\n\t\t\tif (trace_msg_type == 15)\t/* rollover */\n\t\t\t\tcontinue;\n\n\t\t\tif (exception) {\n\t\t\t\tcommand_print(cmd, \"--- exception %i ---\", exception);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* not exception or rollover; next instruction is a branch and is\n\t\t\t * not included in the count */\n\t\t\txscale_display_instruction(target, current_pc, &instruction, cmd);\n\n\t\t\t/* for direct branches, extract branch destination from instruction */\n\t\t\tif ((trace_msg_type == 8) || (trace_msg_type == 12)) {\n\t\t\t\tretval = xscale_read_instruction(target, current_pc, &instruction);\n\t\t\t\tif (retval == ERROR_OK)\n\t\t\t\t\tcurrent_pc = instruction.info.b_bl_bx_blx.target_address;\n\t\t\t\telse\n\t\t\t\t\tcurrent_pc = 0;\t/* branch destination unknown */\n\n\t\t\t\t/* direct branch w/ checkpoint; can also get from checkpoint reg */\n\t\t\t\tif (trace_msg_type == 12) {\n\t\t\t\t\tif (current_pc == 0)\n\t\t\t\t\t\tcurrent_pc = chkpt_reg;\n\t\t\t\t\telse if (current_pc != chkpt_reg)\t/* sanity check */\n\t\t\t\t\t\tLOG_WARNING(\"trace is suspect: checkpoint register \"\n\t\t\t\t\t\t\t\"inconsistent with address from image\");\n\t\t\t\t}\n\n\t\t\t\tif (current_pc == 0)\n\t\t\t\t\tcommand_print(cmd, \"address unknown\");\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* indirect branch; the branch destination was read from trace buffer */\n\t\t\tif ((trace_msg_type == 9) || (trace_msg_type == 13)) {\n\t\t\t\tcurrent_pc = branch_target;\n\n\t\t\t\t/* sanity check (checkpoint reg is redundant) */\n\t\t\t\tif ((trace_msg_type == 13) && (chkpt_reg != branch_target))\n\t\t\t\t\tLOG_WARNING(\"trace is suspect: checkpoint register \"\n\t\t\t\t\t\t\"inconsistent with address from trace buffer\");\n\t\t\t}\n\n\t\t}\t/* END: for (i = 0; i < trace_data->depth; i++) */\n\n\t\tbreakpoint_pc = trace_data->last_instruction;\t/* used below */\n\t\ttrace_data = trace_data->next;\n\n\t}\t/* END: while (trace_data) */\n\n\t/* Finally... display all instructions up to the value of the pc when the\n\t * debug break occurred (saved when trace data was collected from target).\n\t * This is necessary because the trace only records execution branches and 16\n\t * consecutive instructions (rollovers), so last few typically missed.\n\t */\n\tif (current_pc == 0)\n\t\treturn ERROR_OK;/* current_pc was never found */\n\n\t/* how many instructions remaining? */\n\tint gap_count = (breakpoint_pc - current_pc) /\n\t\t(xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2);\n\n\t/* should never be negative or over 16, but verify */\n\tif (gap_count < 0 || gap_count > 16) {\n\t\tLOG_WARNING(\"trace is suspect: excessive gap at end of trace\");\n\t\treturn ERROR_OK;/* bail; large number or negative value no good */\n\t}\n\n\t/* display remaining instructions */\n\tfor (i = 0; i < gap_count; i++) {\n\t\txscale_display_instruction(target, current_pc, &instruction, cmd);\n\t\tcurrent_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type xscale_reg_type = {\n\t.get = xscale_get_reg,\n\t.set = xscale_set_reg,\n};\n\nstatic void xscale_build_reg_cache(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct arm *arm = &xscale->arm;\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tstruct xscale_reg *arch_info = malloc(sizeof(xscale_reg_arch_info));\n\tint i;\n\tint num_regs = ARRAY_SIZE(xscale_reg_arch_info);\n\n\t(*cache_p) = arm_build_reg_cache(target, arm);\n\n\t(*cache_p)->next = malloc(sizeof(struct reg_cache));\n\tcache_p = &(*cache_p)->next;\n\n\t/* fill in values for the xscale reg cache */\n\t(*cache_p)->name = \"XScale registers\";\n\t(*cache_p)->next = NULL;\n\t(*cache_p)->reg_list = calloc(num_regs, sizeof(struct reg));\n\t(*cache_p)->num_regs = num_regs;\n\n\tfor (i = 0; i < num_regs; i++) {\n\t\t(*cache_p)->reg_list[i].name = xscale_reg_list[i];\n\t\t(*cache_p)->reg_list[i].value = calloc(4, 1);\n\t\t(*cache_p)->reg_list[i].dirty = false;\n\t\t(*cache_p)->reg_list[i].valid = false;\n\t\t(*cache_p)->reg_list[i].size = 32;\n\t\t(*cache_p)->reg_list[i].arch_info = &arch_info[i];\n\t\t(*cache_p)->reg_list[i].type = &xscale_reg_type;\n\t\t(*cache_p)->reg_list[i].exist = true;\n\t\tarch_info[i] = xscale_reg_arch_info[i];\n\t\tarch_info[i].target = target;\n\t}\n\n\txscale->reg_cache = (*cache_p);\n}\n\nstatic void xscale_free_reg_cache(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct reg_cache *cache = xscale->reg_cache;\n\n\tfor (unsigned int i = 0; i < ARRAY_SIZE(xscale_reg_arch_info); i++)\n\t\tfree(cache->reg_list[i].value);\n\n\tfree(cache->reg_list[0].arch_info);\n\tfree(cache->reg_list);\n\tfree(cache);\n\n\tarm_free_reg_cache(&xscale->arm);\n}\n\nstatic int xscale_init_target(struct command_context *cmd_ctx,\n\tstruct target *target)\n{\n\txscale_build_reg_cache(target);\n\treturn ERROR_OK;\n}\n\nstatic void xscale_deinit_target(struct target *target)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\txscale_free_reg_cache(target);\n\tfree(xscale);\n}\n\nstatic int xscale_init_arch_info(struct target *target,\n\tstruct xscale_common *xscale, struct jtag_tap *tap)\n{\n\tstruct arm *arm;\n\tuint32_t high_reset_branch, low_reset_branch;\n\tint i;\n\n\tarm = &xscale->arm;\n\n\t/* store architecture specific data */\n\txscale->common_magic = XSCALE_COMMON_MAGIC;\n\n\t/* PXA3xx with 11 bit IR shifts the JTAG instructions */\n\tif (tap->ir_length == 11)\n\t\txscale->xscale_variant = XSCALE_PXA3XX;\n\telse\n\t\txscale->xscale_variant = XSCALE_IXP4XX_PXA2XX;\n\n\t/* the debug handler isn't installed (and thus not running) at this time */\n\txscale->handler_address = 0xfe000800;\n\n\t/* clear the vectors we keep locally for reference */\n\tmemset(xscale->low_vectors, 0, sizeof(xscale->low_vectors));\n\tmemset(xscale->high_vectors, 0, sizeof(xscale->high_vectors));\n\n\t/* no user-specified vectors have been configured yet */\n\txscale->static_low_vectors_set = 0x0;\n\txscale->static_high_vectors_set = 0x0;\n\n\t/* calculate branches to debug handler */\n\tlow_reset_branch = (xscale->handler_address + 0x20 - 0x0 - 0x8) >> 2;\n\thigh_reset_branch = (xscale->handler_address + 0x20 - 0xffff0000 - 0x8) >> 2;\n\n\txscale->low_vectors[0] = ARMV4_5_B((low_reset_branch & 0xffffff), 0);\n\txscale->high_vectors[0] = ARMV4_5_B((high_reset_branch & 0xffffff), 0);\n\n\tfor (i = 1; i <= 7; i++) {\n\t\txscale->low_vectors[i] = ARMV4_5_B(0xfffffe, 0);\n\t\txscale->high_vectors[i] = ARMV4_5_B(0xfffffe, 0);\n\t}\n\n\t/* 64kB aligned region used for DCache cleaning */\n\txscale->cache_clean_address = 0xfffe0000;\n\n\txscale->hold_rst = 0;\n\txscale->external_debug_break = 0;\n\n\txscale->ibcr_available = 2;\n\txscale->ibcr0_used = 0;\n\txscale->ibcr1_used = 0;\n\n\txscale->dbr_available = 2;\n\txscale->dbr0_used = 0;\n\txscale->dbr1_used = 0;\n\n\tLOG_INFO(\"%s: hardware has 2 breakpoints and 2 watchpoints\",\n\t\ttarget_name(target));\n\n\txscale->arm_bkpt = ARMV5_BKPT(0x0);\n\txscale->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;\n\n\txscale->vector_catch = 0x1;\n\n\txscale->trace.data = NULL;\n\txscale->trace.image = NULL;\n\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\txscale->trace.buffer_fill = 0;\n\txscale->trace.fill_counter = 0;\n\n\t/* prepare ARMv4/5 specific information */\n\tarm->arch_info = xscale;\n\tarm->core_type = ARM_CORE_TYPE_STD;\n\tarm->read_core_reg = xscale_read_core_reg;\n\tarm->write_core_reg = xscale_write_core_reg;\n\tarm->full_context = xscale_full_context;\n\n\tarm_init_arch_info(target, arm);\n\n\txscale->armv4_5_mmu.armv4_5_cache.ctype = -1;\n\txscale->armv4_5_mmu.get_ttb = xscale_get_ttb;\n\txscale->armv4_5_mmu.read_memory = xscale_read_memory;\n\txscale->armv4_5_mmu.write_memory = xscale_write_memory;\n\txscale->armv4_5_mmu.disable_mmu_caches = xscale_disable_mmu_caches;\n\txscale->armv4_5_mmu.enable_mmu_caches = xscale_enable_mmu_caches;\n\txscale->armv4_5_mmu.has_tiny_pages = 1;\n\txscale->armv4_5_mmu.mmu_enabled = 0;\n\n\treturn ERROR_OK;\n}\n\nstatic int xscale_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct xscale_common *xscale;\n\n\tif (sizeof(xscale_debug_handler) > 0x800) {\n\t\tLOG_ERROR(\"debug_handler.bin: larger than 2kb\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\txscale = calloc(1, sizeof(*xscale));\n\tif (!xscale)\n\t\treturn ERROR_FAIL;\n\n\treturn xscale_init_arch_info(target, xscale, target->tap);\n}\n\nCOMMAND_HANDLER(xscale_handle_debug_handler_command)\n{\n\tstruct target *target = NULL;\n\tstruct xscale_common *xscale;\n\tint retval;\n\tuint32_t handler_address;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_target(CMD_ARGV[0]);\n\tif (!target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\n\txscale = target_to_xscale(target);\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], handler_address);\n\n\tif (((handler_address >= 0x800) && (handler_address <= 0x1fef800)) ||\n\t\t((handler_address >= 0xfe000800) && (handler_address <= 0xfffff800)))\n\t\txscale->handler_address = handler_address;\n\telse {\n\t\tLOG_ERROR(\n\t\t\t\"xscale debug_handler <address> must be between 0x800 and 0x1fef800 or between 0xfe000800 and 0xfffff800\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_cache_clean_address_command)\n{\n\tstruct target *target = NULL;\n\tstruct xscale_common *xscale;\n\tint retval;\n\tuint32_t cache_clean_address;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttarget = get_target(CMD_ARGV[0]);\n\tif (!target) {\n\t\tLOG_ERROR(\"target '%s' not defined\", CMD_ARGV[0]);\n\t\treturn ERROR_FAIL;\n\t}\n\txscale = target_to_xscale(target);\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cache_clean_address);\n\n\tif (cache_clean_address & 0xffff)\n\t\tLOG_ERROR(\"xscale cache_clean_address <address> must be 64kb aligned\");\n\telse\n\t\txscale->cache_clean_address = cache_clean_address;\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_cache_info_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\treturn armv4_5_handle_cache_info_command(CMD, &xscale->armv4_5_mmu.armv4_5_cache);\n}\n\nstatic int xscale_virt2phys(struct target *target,\n\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t cb;\n\n\tif (xscale->common_magic != XSCALE_COMMON_MAGIC) {\n\t\tLOG_ERROR(xscale_not);\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\n\tuint32_t ret;\n\tint retval = armv4_5_mmu_translate_va(target, &xscale->armv4_5_mmu,\n\t\t\tvirtual, &cb, &ret);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\t*physical = ret;\n\treturn ERROR_OK;\n}\n\nstatic int xscale_mmu(struct target *target, int *enabled)\n{\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_ERROR(\"Target not halted\");\n\t\treturn ERROR_TARGET_INVALID;\n\t}\n\t*enabled = xscale->armv4_5_mmu.mmu_enabled;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_mmu_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC >= 1) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tif (enable)\n\t\t\txscale_enable_mmu_caches(target, 1, 0, 0);\n\t\telse\n\t\t\txscale_disable_mmu_caches(target, 1, 0, 0);\n\t\txscale->armv4_5_mmu.mmu_enabled = enable;\n\t}\n\n\tcommand_print(CMD, \"mmu %s\",\n\t\t(xscale->armv4_5_mmu.mmu_enabled) ? \"enabled\" : \"disabled\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_idcache_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\n\tint retval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\tbool icache = false;\n\tif (strcmp(CMD_NAME, \"icache\") == 0)\n\t\ticache = true;\n\tif (CMD_ARGC >= 1) {\n\t\tbool enable;\n\t\tCOMMAND_PARSE_ENABLE(CMD_ARGV[0], enable);\n\t\tif (icache) {\n\t\t\txscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled = enable;\n\t\t\tif (enable)\n\t\t\t\txscale_enable_mmu_caches(target, 0, 0, 1);\n\t\t\telse\n\t\t\t\txscale_disable_mmu_caches(target, 0, 0, 1);\n\t\t} else {\n\t\t\txscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = enable;\n\t\t\tif (enable)\n\t\t\t\txscale_enable_mmu_caches(target, 0, 1, 0);\n\t\t\telse\n\t\t\t\txscale_disable_mmu_caches(target, 0, 1, 0);\n\t\t}\n\t}\n\n\tbool enabled = icache ?\n\t\txscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled :\n\t\txscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled;\n\tconst char *msg = enabled ? \"enabled\" : \"disabled\";\n\tcommand_print(CMD, \"%s %s\", CMD_NAME, msg);\n\n\treturn ERROR_OK;\n}\n\nstatic const struct {\n\tchar name[15];\n\tunsigned mask;\n} vec_ids[] = {\n\t{ \"fiq\",\t\tDCSR_TF, },\n\t{ \"irq\",\t\tDCSR_TI, },\n\t{ \"dabt\",\t\tDCSR_TD, },\n\t{ \"pabt\",\t\tDCSR_TA, },\n\t{ \"swi\",\t\tDCSR_TS, },\n\t{ \"undef\",\t\tDCSR_TU, },\n\t{ \"reset\",\t\tDCSR_TR, },\n};\n\nCOMMAND_HANDLER(xscale_handle_vector_catch_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\tuint32_t dcsr_value;\n\tuint32_t catch = 0;\n\tstruct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR];\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC > 0) {\n\t\tif (CMD_ARGC == 1) {\n\t\t\tif (strcmp(CMD_ARGV[0], \"all\") == 0) {\n\t\t\t\tcatch = DCSR_TRAP_MASK;\n\t\t\t\tCMD_ARGC--;\n\t\t\t} else if (strcmp(CMD_ARGV[0], \"none\") == 0) {\n\t\t\t\tcatch = 0;\n\t\t\t\tCMD_ARGC--;\n\t\t\t}\n\t\t}\n\t\twhile (CMD_ARGC-- > 0) {\n\t\t\tunsigned i;\n\t\t\tfor (i = 0; i < ARRAY_SIZE(vec_ids); i++) {\n\t\t\t\tif (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name))\n\t\t\t\t\tcontinue;\n\t\t\t\tcatch |= vec_ids[i].mask;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i == ARRAY_SIZE(vec_ids)) {\n\t\t\t\tLOG_ERROR(\"No vector '%s'\", CMD_ARGV[CMD_ARGC]);\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t}\n\t\tbuf_set_u32(dcsr_reg->value, 0, 32,\n\t\t\t\t(buf_get_u32(dcsr_reg->value, 0, 32) & ~DCSR_TRAP_MASK) | catch);\n\t\txscale_write_dcsr(target, -1, -1);\n\t}\n\n\tdcsr_value = buf_get_u32(dcsr_reg->value, 0, 32);\n\tfor (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {\n\t\tcommand_print(CMD, \"%15s: %s\", vec_ids[i].name,\n\t\t\t(dcsr_value & vec_ids[i].mask) ? \"catch\" : \"ignore\");\n\t}\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(xscale_handle_vector_table_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint err = 0;\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (CMD_ARGC == 0) {\t/* print current settings */\n\t\tint idx;\n\n\t\tcommand_print(CMD, \"active user-set static vectors:\");\n\t\tfor (idx = 1; idx < 8; idx++)\n\t\t\tif (xscale->static_low_vectors_set & (1 << idx))\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"low  %d: 0x%\" PRIx32,\n\t\t\t\t\tidx,\n\t\t\t\t\txscale->static_low_vectors[idx]);\n\t\tfor (idx = 1; idx < 8; idx++)\n\t\t\tif (xscale->static_high_vectors_set & (1 << idx))\n\t\t\t\tcommand_print(CMD,\n\t\t\t\t\t\"high %d: 0x%\" PRIx32,\n\t\t\t\t\tidx,\n\t\t\t\t\txscale->static_high_vectors[idx]);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC != 3)\n\t\terr = 1;\n\telse {\n\t\tint idx;\n\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[1], idx);\n\t\tuint32_t vec;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], vec);\n\n\t\tif (idx < 1 || idx >= 8)\n\t\t\terr = 1;\n\n\t\tif (!err && strcmp(CMD_ARGV[0], \"low\") == 0) {\n\t\t\txscale->static_low_vectors_set |= (1<<idx);\n\t\t\txscale->static_low_vectors[idx] = vec;\n\t\t} else if (!err && (strcmp(CMD_ARGV[0], \"high\") == 0)) {\n\t\t\txscale->static_high_vectors_set |= (1<<idx);\n\t\t\txscale->static_high_vectors[idx] = vec;\n\t\t} else\n\t\t\terr = 1;\n\t}\n\n\tif (err)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\n\nCOMMAND_HANDLER(xscale_handle_trace_buffer_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tuint32_t dcsr_value;\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC >= 1) {\n\t\tif (strcmp(\"enable\", CMD_ARGV[0]) == 0)\n\t\t\txscale->trace.mode = XSCALE_TRACE_WRAP;\t/* default */\n\t\telse if (strcmp(\"disable\", CMD_ARGV[0]) == 0)\n\t\t\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\t\telse\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tif (CMD_ARGC >= 2 && xscale->trace.mode != XSCALE_TRACE_DISABLED) {\n\t\tif (strcmp(\"fill\", CMD_ARGV[1]) == 0) {\n\t\t\tint buffcount = 1;\t\t/* default */\n\t\t\tif (CMD_ARGC >= 3)\n\t\t\t\tCOMMAND_PARSE_NUMBER(int, CMD_ARGV[2], buffcount);\n\t\t\tif (buffcount < 1) {\t\t/* invalid */\n\t\t\t\tcommand_print(CMD, \"fill buffer count must be > 0\");\n\t\t\t\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t}\n\t\t\txscale->trace.buffer_fill = buffcount;\n\t\t\txscale->trace.mode = XSCALE_TRACE_FILL;\n\t\t} else if (strcmp(\"wrap\", CMD_ARGV[1]) == 0)\n\t\t\txscale->trace.mode = XSCALE_TRACE_WRAP;\n\t\telse {\n\t\t\txscale->trace.mode = XSCALE_TRACE_DISABLED;\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t}\n\n\tif (xscale->trace.mode != XSCALE_TRACE_DISABLED) {\n\t\tchar fill_string[12];\n\t\tsprintf(fill_string, \"fill %d\", xscale->trace.buffer_fill);\n\t\tcommand_print(CMD, \"trace buffer enabled (%s)\",\n\t\t\t(xscale->trace.mode == XSCALE_TRACE_FILL)\n\t\t\t? fill_string : \"wrap\");\n\t} else\n\t\tcommand_print(CMD, \"trace buffer disabled\");\n\n\tdcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);\n\tif (xscale->trace.mode == XSCALE_TRACE_FILL)\n\t\txscale_write_dcsr_sw(target, (dcsr_value & 0xfffffffc) | 2);\n\telse\n\t\txscale_write_dcsr_sw(target, dcsr_value & 0xfffffffc);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_trace_image_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (xscale->trace.image) {\n\t\timage_close(xscale->trace.image);\n\t\tfree(xscale->trace.image);\n\t\tcommand_print(CMD, \"previously loaded image found and closed\");\n\t}\n\n\txscale->trace.image = malloc(sizeof(struct image));\n\txscale->trace.image->base_address_set = false;\n\txscale->trace.image->start_address_set = false;\n\n\t/* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */\n\tif (CMD_ARGC >= 2) {\n\t\txscale->trace.image->base_address_set = true;\n\t\tCOMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);\n\t} else\n\t\txscale->trace.image->base_address_set = false;\n\n\tif (image_open(xscale->trace.image, CMD_ARGV[0],\n\t\t(CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) {\n\t\tfree(xscale->trace.image);\n\t\txscale->trace.image = NULL;\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_dump_trace_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tstruct xscale_trace_data *trace_data;\n\tstruct fileio *file;\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (CMD_ARGC < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\ttrace_data = xscale->trace.data;\n\n\tif (!trace_data) {\n\t\tcommand_print(CMD, \"no trace data collected\");\n\t\treturn ERROR_OK;\n\t}\n\n\tif (fileio_open(&file, CMD_ARGV[0], FILEIO_WRITE, FILEIO_BINARY) != ERROR_OK)\n\t\treturn ERROR_OK;\n\n\twhile (trace_data) {\n\t\tint i;\n\n\t\tfileio_write_u32(file, trace_data->chkpt0);\n\t\tfileio_write_u32(file, trace_data->chkpt1);\n\t\tfileio_write_u32(file, trace_data->last_instruction);\n\t\tfileio_write_u32(file, trace_data->depth);\n\n\t\tfor (i = 0; i < trace_data->depth; i++)\n\t\t\tfileio_write_u32(file, trace_data->entries[i].data |\n\t\t\t\t((trace_data->entries[i].type & 0xffff) << 16));\n\n\t\ttrace_data = trace_data->next;\n\t}\n\n\tfileio_close(file);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_analyze_trace_buffer_command)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\txscale_analyze_trace(target, CMD);\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xscale_handle_cp15)\n{\n\tstruct target *target = get_current_target(CMD_CTX);\n\tstruct xscale_common *xscale = target_to_xscale(target);\n\tint retval;\n\n\tretval = xscale_verify_pointer(CMD, xscale);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tcommand_print(CMD, \"target must be stopped for \\\"%s\\\" command\", CMD_NAME);\n\t\treturn ERROR_OK;\n\t}\n\tuint32_t reg_no = 0;\n\tstruct reg *reg = NULL;\n\tif (CMD_ARGC > 0) {\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], reg_no);\n\t\t/*translate from xscale cp15 register no to openocd register*/\n\t\tswitch (reg_no) {\n\t\t\tcase 0:\n\t\t\t\treg_no = XSCALE_MAINID;\n\t\t\t\tbreak;\n\t\t\tcase 1:\n\t\t\t\treg_no = XSCALE_CTRL;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\treg_no = XSCALE_TTB;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\treg_no = XSCALE_DAC;\n\t\t\t\tbreak;\n\t\t\tcase 5:\n\t\t\t\treg_no = XSCALE_FSR;\n\t\t\t\tbreak;\n\t\t\tcase 6:\n\t\t\t\treg_no = XSCALE_FAR;\n\t\t\t\tbreak;\n\t\t\tcase 13:\n\t\t\t\treg_no = XSCALE_PID;\n\t\t\t\tbreak;\n\t\t\tcase 15:\n\t\t\t\treg_no = XSCALE_CPACCESS;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcommand_print(CMD, \"invalid register number\");\n\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\treg = &xscale->reg_cache->reg_list[reg_no];\n\n\t}\n\tif (CMD_ARGC == 1) {\n\t\tuint32_t value;\n\n\t\t/* read cp15 control register */\n\t\txscale_get_reg(reg);\n\t\tvalue = buf_get_u32(reg->value, 0, 32);\n\t\tcommand_print(CMD, \"%s (/%i): 0x%\" PRIx32 \"\", reg->name, (int)(reg->size),\n\t\t\tvalue);\n\t} else if (CMD_ARGC == 2) {\n\t\tuint32_t value;\n\t\tCOMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);\n\n\t\t/* send CP write request (command 0x41) */\n\t\txscale_send_u32(target, 0x41);\n\n\t\t/* send CP register number */\n\t\txscale_send_u32(target, reg_no);\n\n\t\t/* send CP register value */\n\t\txscale_send_u32(target, value);\n\n\t\t/* execute cpwait to ensure outstanding operations complete */\n\t\txscale_send_u32(target, 0x53);\n\t} else\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration xscale_exec_command_handlers[] = {\n\t{\n\t\t.name = \"cache_info\",\n\t\t.handler = xscale_handle_cache_info_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display information about CPU caches\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"mmu\",\n\t\t.handler = xscale_handle_mmu_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"enable or disable the MMU\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"icache\",\n\t\t.handler = xscale_handle_idcache_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display ICache state, optionally enabling or \"\n\t\t\t\"disabling it\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"dcache\",\n\t\t.handler = xscale_handle_idcache_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display DCache state, optionally enabling or \"\n\t\t\t\"disabling it\",\n\t\t.usage = \"['enable'|'disable']\",\n\t},\n\t{\n\t\t.name = \"vector_catch\",\n\t\t.handler = xscale_handle_vector_catch_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set or display mask of vectors \"\n\t\t\t\"that should trigger debug entry\",\n\t\t.usage = \"['all'|'none'|'fiq'|'irq'|'dabt'|'pabt'|'swi'|'undef'|'reset']\",\n\t},\n\t{\n\t\t.name = \"vector_table\",\n\t\t.handler = xscale_handle_vector_table_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"set vector table entry in mini-ICache, \"\n\t\t\t\"or display current tables\",\n\t\t.usage = \"[('high'|'low') index code]\",\n\t},\n\t{\n\t\t.name = \"trace_buffer\",\n\t\t.handler = xscale_handle_trace_buffer_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"display trace buffer status, enable or disable \"\n\t\t\t\"tracing, and optionally reconfigure trace mode\",\n\t\t.usage = \"['enable'|'disable' ['fill' [number]|'wrap']]\",\n\t},\n\t{\n\t\t.name = \"dump_trace\",\n\t\t.handler = xscale_handle_dump_trace_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"dump content of trace buffer to file\",\n\t\t.usage = \"filename\",\n\t},\n\t{\n\t\t.name = \"analyze_trace\",\n\t\t.handler = xscale_handle_analyze_trace_buffer_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"analyze content of trace buffer\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"trace_image\",\n\t\t.handler = xscale_handle_trace_image_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"load image from file to address (default 0)\",\n\t\t.usage = \"filename [offset [filetype]]\",\n\t},\n\t{\n\t\t.name = \"cp15\",\n\t\t.handler = xscale_handle_cp15,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Read or write coprocessor 15 register.\",\n\t\t.usage = \"register [value]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration xscale_any_command_handlers[] = {\n\t{\n\t\t.name = \"debug_handler\",\n\t\t.handler = xscale_handle_debug_handler_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Change address used for debug handler.\",\n\t\t.usage = \"<target> <address>\",\n\t},\n\t{\n\t\t.name = \"cache_clean_address\",\n\t\t.handler = xscale_handle_cache_clean_address_command,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Change address used for cleaning data cache.\",\n\t\t.usage = \"address\",\n\t},\n\t{\n\t\t.chain = xscale_exec_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\nstatic const struct command_registration xscale_command_handlers[] = {\n\t{\n\t\t.chain = arm_command_handlers,\n\t},\n\t{\n\t\t.name = \"xscale\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"xscale command group\",\n\t\t.usage = \"\",\n\t\t.chain = xscale_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstruct target_type xscale_target = {\n\t.name = \"xscale\",\n\n\t.poll = xscale_poll,\n\t.arch_state = xscale_arch_state,\n\n\t.halt = xscale_halt,\n\t.resume = xscale_resume,\n\t.step = xscale_step,\n\n\t.assert_reset = xscale_assert_reset,\n\t.deassert_reset = xscale_deassert_reset,\n\n\t/* REVISIT on some cores, allow exporting iwmmxt registers ... */\n\t.get_gdb_arch = arm_get_gdb_arch,\n\t.get_gdb_reg_list = arm_get_gdb_reg_list,\n\n\t.read_memory = xscale_read_memory,\n\t.read_phys_memory = xscale_read_phys_memory,\n\t.write_memory = xscale_write_memory,\n\t.write_phys_memory = xscale_write_phys_memory,\n\n\t.checksum_memory = arm_checksum_memory,\n\t.blank_check_memory = arm_blank_check_memory,\n\n\t.run_algorithm = armv4_5_run_algorithm,\n\n\t.add_breakpoint = xscale_add_breakpoint,\n\t.remove_breakpoint = xscale_remove_breakpoint,\n\t.add_watchpoint = xscale_add_watchpoint,\n\t.remove_watchpoint = xscale_remove_watchpoint,\n\n\t.commands = xscale_command_handlers,\n\t.target_create = xscale_target_create,\n\t.init_target = xscale_init_target,\n\t.deinit_target = xscale_deinit_target,\n\n\t.virt2phys = xscale_virt2phys,\n\t.mmu = xscale_mmu\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xscale.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XSCALE_H\n#define OPENOCD_TARGET_XSCALE_H\n\n#include \"arm.h\"\n#include \"armv4_5_mmu.h\"\n#include \"trace.h\"\n\n#define\tXSCALE_COMMON_MAGIC 0x58534341U\n\n/* These four JTAG instructions are architecturally defined.\n * Lengths are core-specific; originally 5 bits, later 7.\n */\n#define XSCALE_DBGRX\t0x02\n#define XSCALE_DBGTX\t0x10\n#define XSCALE_LDIC\t0x07\n#define XSCALE_SELDCSR\t0x09\n\n/* Possible CPU types */\n#define\tXSCALE_IXP4XX_PXA2XX\t0x0\n#define\tXSCALE_PXA3XX\t\t0x4\n\nenum xscale_debug_reason {\n\tXSCALE_DBG_REASON_GENERIC,\n\tXSCALE_DBG_REASON_RESET,\n\tXSCALE_DBG_REASON_TB_FULL,\n};\n\nenum xscale_trace_entry_type {\n\tXSCALE_TRACE_MESSAGE = 0x0,\n\tXSCALE_TRACE_ADDRESS = 0x1,\n};\n\nstruct xscale_trace_entry {\n\tuint8_t data;\n\tenum xscale_trace_entry_type type;\n};\n\nstruct xscale_trace_data {\n\tstruct xscale_trace_entry *entries;\n\tint depth;\n\tuint32_t chkpt0;\n\tuint32_t chkpt1;\n\tuint32_t last_instruction;\n\tunsigned int num_checkpoints;\n\tstruct xscale_trace_data *next;\n};\n\nenum trace_mode {\n\tXSCALE_TRACE_DISABLED,\n\tXSCALE_TRACE_FILL,\n\tXSCALE_TRACE_WRAP\n};\n\nstruct xscale_trace {\n\tstruct image *image;\t\t\t\t\t/* source for target opcodes */\n\tstruct xscale_trace_data *data;\t\t/* linked list of collected trace data */\n\tint buffer_fill;\t\t\t\t/* maximum number of trace runs to read */\n\tint fill_counter;\t\t\t\t/* running count during trace collection */\n\tenum trace_mode mode;\n\tenum arm_state core_state;\t/* current core state (ARM, Thumb) */\n};\n\nstruct xscale_common {\n\tunsigned int common_magic;\n\n\t/* armv4/5 common stuff */\n\tstruct arm arm;\n\n\t/* XScale registers (CP15, DBG) */\n\tstruct reg_cache *reg_cache;\n\n\t/* current state of the debug handler */\n\tuint32_t handler_address;\n\n\t/* target-endian buffers with exception vectors */\n\tuint32_t low_vectors[8];\n\tuint32_t high_vectors[8];\n\n\t/* static low vectors */\n\tuint8_t static_low_vectors_set;\t/* bit field with static vectors set by the user */\n\tuint8_t static_high_vectors_set; /* bit field with static vectors set by the user */\n\tuint32_t static_low_vectors[8];\n\tuint32_t static_high_vectors[8];\n\n\t/* DCache cleaning */\n\tuint32_t cache_clean_address;\n\n\t/* whether hold_rst and ext_dbg_break should be set */\n\tint hold_rst;\n\tint external_debug_break;\n\n\t/* breakpoint / watchpoint handling */\n\tint dbr_available;\n\tint dbr0_used;\n\tint dbr1_used;\n\tint ibcr_available;\n\tint ibcr0_used;\n\tint\tibcr1_used;\n\tuint32_t arm_bkpt;\n\tuint16_t thumb_bkpt;\n\n\tuint8_t vector_catch;\n\n\tstruct xscale_trace trace;\n\n\tint arch_debug_reason;\n\n\t/* MMU/Caches */\n\tstruct armv4_5_mmu_common armv4_5_mmu;\n\tuint32_t cp15_control_reg;\n\n\tint fast_memory_access;\n\n\t/* CPU variant */\n\tint xscale_variant;\n};\n\nstatic inline struct xscale_common *\ntarget_to_xscale(struct target *target)\n{\n\treturn container_of(target->arch_info, struct xscale_common, arm);\n}\n\nstruct xscale_reg {\n\tint dbg_handler_number;\n\tstruct target *target;\n};\n\nenum {\n\tXSCALE_MAINID,\t\t/* 0 */\n\tXSCALE_CACHETYPE,\n\tXSCALE_CTRL,\n\tXSCALE_AUXCTRL,\n\tXSCALE_TTB,\n\tXSCALE_DAC,\n\tXSCALE_FSR,\n\tXSCALE_FAR,\n\tXSCALE_PID,\n\tXSCALE_CPACCESS,\n\tXSCALE_IBCR0,\t\t/* 10 */\n\tXSCALE_IBCR1,\n\tXSCALE_DBR0,\n\tXSCALE_DBR1,\n\tXSCALE_DBCON,\n\tXSCALE_TBREG,\n\tXSCALE_CHKPT0,\n\tXSCALE_CHKPT1,\n\tXSCALE_DCSR,\n\tXSCALE_TX,\n\tXSCALE_RX,\t\t\t/* 20 */\n\tXSCALE_TXRXCTRL,\n};\n\n#define ERROR_XSCALE_NO_TRACE_DATA\t(-700)\n\n/* DCSR bit and field definitions */\n#define DCSR_TR\t(1 << 16)\n#define DCSR_TU\t(1 << 17)\n#define DCSR_TS\t(1 << 18)\n#define DCSR_TA\t(1 << 19)\n#define DCSR_TD\t(1 << 20)\n#define DCSR_TI\t(1 << 22)\n#define DCSR_TF\t(1 << 23)\n#define DCSR_TRAP_MASK \\\n\t(DCSR_TF | DCSR_TI | DCSR_TD | DCSR_TA | DCSR_TS | DCSR_TU | DCSR_TR)\n\n#endif /* OPENOCD_TARGET_XSCALE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libxtensa.la\n%C%_libxtensa_la_SOURCES = \\\n       %D%/xtensa.c \\\n       %D%/xtensa.h \\\n       %D%/xtensa_chip.c \\\n       %D%/xtensa_chip.h \\\n       %D%/xtensa_debug_module.c \\\n       %D%/xtensa_debug_module.h \\\n       %D%/xtensa_fileio.c \\\n       %D%/xtensa_fileio.h \\\n       %D%/xtensa_regs.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Generic Xtensa target API for OpenOCD                                 *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n *   Copyright (C) 2016-2019 Espressif Systems Ltd.                        *\n *   Derived from esp108.c                                                 *\n *   Author: Angus Gratton gus@projectgus.com                              *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#include <helper/time_support.h>\n#include <helper/align.h>\n#include <target/register.h>\n\n#include \"xtensa_chip.h\"\n#include \"xtensa.h\"\n\n/* Swap 4-bit Xtensa opcodes and fields */\n#define XT_NIBSWAP8(V)\t\t\t\t\t\t\t\t\t\\\n\t((((V) & 0x0F) << 4)\t\t\t\t\t\t\t\t\\\n\t\t| (((V) & 0xF0) >> 4))\n\n#define XT_NIBSWAP16(V)\t\t\t\t\t\t\t\t\t\\\n\t((((V) & 0x000F) << 12)\t\t\t\t\t\t\t\t\\\n\t\t| (((V) & 0x00F0) << 4)\t\t\t\t\t\t\t\\\n\t\t| (((V) & 0x0F00) >> 4)\t\t\t\t\t\t\t\\\n\t\t| (((V) & 0xF000) >> 12))\n\n#define XT_NIBSWAP24(V)\t\t\t\t\t\t\t\t\t\\\n\t((((V) & 0x00000F) << 20)\t\t\t\t\t\t\t\\\n\t\t| (((V) & 0x0000F0) << 12)\t\t\t\t\t\t\\\n\t\t| (((V) & 0x000F00) << 4)\t\t\t\t\t\t\\\n\t\t| (((V) & 0x00F000) >> 4)\t\t\t\t\t\t\\\n\t\t| (((V) & 0x0F0000) >> 12)\t\t\t\t\t\t\\\n\t\t| (((V) & 0xF00000) >> 20))\n\n/* _XT_INS_FORMAT_*()\n * Instruction formatting converted from little-endian inputs\n * and shifted to the MSB-side of DIR for BE systems.\n */\n#define _XT_INS_FORMAT_RSR(X, OPCODE, SR, T)\t\t\t\\\n\t(XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE)\t\t\t\t\t\\\n\t\t\t| (((T) & 0x0F) << 16)\t\t\t\t\t\t\\\n\t\t\t| (((SR) & 0xFF) << 8)) << 8\t\t\t\t\\\n\t\t: (OPCODE)\t\t\t\t\t\t\t\t\t\t\\\n\t\t| (((SR) & 0xFF) << 8)\t\t\t\t\t\t\t\\\n\t\t| (((T) & 0x0F) << 4))\n\n#define _XT_INS_FORMAT_RRR(X, OPCODE, ST, R)\t\t\t\\\n\t(XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE)\t\t\t\t\t\\\n\t\t\t| ((XT_NIBSWAP8((ST) & 0xFF)) << 12)\t\t\\\n\t\t\t| (((R) & 0x0F) << 8)) << 8\t\t\t\t\t\\\n\t\t: (OPCODE)\t\t\t\t\t\t\t\t\t\t\\\n\t\t| (((ST) & 0xFF) << 4)\t\t\t\t\t\t\t\\\n\t\t| (((R) & 0x0F) << 12))\n\n#define _XT_INS_FORMAT_RRRN(X, OPCODE, S, T, IMM4)\t\t\\\n\t(XT_ISBE(X) ? (XT_NIBSWAP16(OPCODE)\t\t\t\t\t\\\n\t\t\t| (((T) & 0x0F) << 8)\t\t\t\t\t\t\\\n\t\t\t| (((S) & 0x0F) << 4)\t\t\t\t\t\t\\\n\t\t\t| ((IMM4) & 0x0F)) << 16\t\t\t\t\t\\\n\t\t: (OPCODE)\t\t\t\t\t\t\t\t\t\t\\\n\t\t| (((T) & 0x0F) << 4)\t\t\t\t\t\t\t\\\n\t\t| (((S) & 0x0F) << 8)\t\t\t\t\t\t\t\\\n\t\t| (((IMM4) & 0x0F) << 12))\n\n#define _XT_INS_FORMAT_RRI8(X, OPCODE, R, S, T, IMM8)\t\\\n\t(XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE)\t\t\t\t\t\\\n\t\t\t| (((T) & 0x0F) << 16)\t\t\t\t\t\t\\\n\t\t\t| (((S) & 0x0F) << 12)\t\t\t\t\t\t\\\n\t\t\t| (((R) & 0x0F) << 8)\t\t\t\t\t\t\\\n\t\t\t| ((IMM8) & 0xFF)) << 8\t\t\t\t\t\t\\\n\t\t: (OPCODE)\t\t\t\t\t\t\t\t\t\t\\\n\t\t| (((IMM8) & 0xFF) << 16)\t\t\t\t\t\t\\\n\t\t| (((R) & 0x0F) << 12)\t\t\t\t\t\t\t\\\n\t\t| (((S) & 0x0F) << 8)\t\t\t\t\t\t\t\\\n\t\t| (((T) & 0x0F) << 4))\n\n#define _XT_INS_FORMAT_RRI4(X, OPCODE, IMM4, R, S, T)\t\\\n\t(XT_ISBE(X) ? (XT_NIBSWAP24(OPCODE)\t\t\t\t\t\\\n\t\t\t| (((T) & 0x0F) << 16)\t\t\t\t\t\t\\\n\t\t\t| (((S) & 0x0F) << 12)\t\t\t\t\t\t\\\n\t\t\t| (((R) & 0x0F) << 8)) << 8\t\t\t\t\t\\\n\t\t| ((IMM4) & 0x0F)\t\t\t\t\t\t\t\t\\\n\t\t: (OPCODE)\t\t\t\t\t\t\t\t\t\t\\\n\t\t| (((IMM4) & 0x0F) << 20)\t\t\t\t\t\t\\\n\t\t| (((R) & 0x0F) << 12)\t\t\t\t\t\t\t\\\n\t\t| (((S) & 0x0F) << 8)\t\t\t\t\t\t\t\\\n\t\t| (((T) & 0x0F) << 4))\n\n/* Xtensa processor instruction opcodes\n*/\n/* \"Return From Debug Operation\" to Normal */\n#define XT_INS_RFDO(X) (XT_ISBE(X) ? 0x000e1f << 8 : 0xf1e000)\n/* \"Return From Debug and Dispatch\" - allow sw debugging stuff to take over */\n#define XT_INS_RFDD(X) (XT_ISBE(X) ? 0x010e1f << 8 : 0xf1e010)\n\n/* Load to DDR register, increase addr register */\n#define XT_INS_LDDR32P(X, S) (XT_ISBE(X) ? (0x0E0700 | ((S) << 12)) << 8 : (0x0070E0 | ((S) << 8)))\n/* Store from DDR register, increase addr register */\n#define XT_INS_SDDR32P(X, S) (XT_ISBE(X) ? (0x0F0700 | ((S) << 12)) << 8 : (0x0070F0 | ((S) << 8)))\n\n/* Load 32-bit Indirect from A(S)+4*IMM8 to A(T) */\n#define XT_INS_L32I(X, S, T, IMM8)  _XT_INS_FORMAT_RRI8(X, 0x002002, 0, S, T, IMM8)\n/* Load 16-bit Unsigned from A(S)+2*IMM8 to A(T) */\n#define XT_INS_L16UI(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x001002, 0, S, T, IMM8)\n/* Load 8-bit Unsigned from A(S)+IMM8 to A(T) */\n#define XT_INS_L8UI(X, S, T, IMM8)  _XT_INS_FORMAT_RRI8(X, 0x000002, 0, S, T, IMM8)\n\n/* Store 32-bit Indirect to A(S)+4*IMM8 from A(T) */\n#define XT_INS_S32I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x006002, 0, S, T, IMM8)\n/* Store 16-bit to A(S)+2*IMM8 from A(T) */\n#define XT_INS_S16I(X, S, T, IMM8) _XT_INS_FORMAT_RRI8(X, 0x005002, 0, S, T, IMM8)\n/* Store 8-bit to A(S)+IMM8 from A(T) */\n#define XT_INS_S8I(X, S, T, IMM8)  _XT_INS_FORMAT_RRI8(X, 0x004002, 0, S, T, IMM8)\n\n/* Cache Instructions */\n#define XT_INS_IHI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x0070E2, 0, S, 0, IMM8)\n#define XT_INS_DHWBI(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007052, 0, S, 0, IMM8)\n#define XT_INS_DHWB(X, S, IMM8) _XT_INS_FORMAT_RRI8(X, 0x007042, 0, S, 0, IMM8)\n#define XT_INS_ISYNC(X) (XT_ISBE(X) ? 0x000200 << 8 : 0x002000)\n\n/* Control Instructions */\n#define XT_INS_JX(X, S) (XT_ISBE(X) ? (0x050000 | ((S) << 12)) : (0x0000a0 | ((S) << 8)))\n#define XT_INS_CALL0(X, IMM18) (XT_ISBE(X) ? (0x500000 | ((IMM18) & 0x3ffff)) : (0x000005 | (((IMM18) & 0x3ffff) << 6)))\n\n/* Read Special Register */\n#define XT_INS_RSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x030000, SR, T)\n/* Write Special Register */\n#define XT_INS_WSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x130000, SR, T)\n/* Swap Special Register */\n#define XT_INS_XSR(X, SR, T) _XT_INS_FORMAT_RSR(X, 0x610000, SR, T)\n\n/* Rotate Window by (-8..7) */\n#define XT_INS_ROTW(X, N) (XT_ISBE(X) ? ((0x000804) | (((N) & 15) << 16)) << 8 : ((0x408000) | (((N) & 15) << 4)))\n\n/* Read User Register */\n#define XT_INS_RUR(X, UR, T) _XT_INS_FORMAT_RRR(X, 0xE30000, UR, T)\n/* Write User Register */\n#define XT_INS_WUR(X, UR, T) _XT_INS_FORMAT_RSR(X, 0xF30000, UR, T)\n\n/* Read Floating-Point Register */\n#define XT_INS_RFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((FR << 4) | 0x4), T)\n/* Write Floating-Point Register */\n#define XT_INS_WFR(X, FR, T) _XT_INS_FORMAT_RRR(X, 0xFA0000, ((T << 4) | 0x5), FR)\n\n#define XT_INS_L32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x090000, 0, R, S, T)\n#define XT_INS_S32E(X, R, S, T) _XT_INS_FORMAT_RRI4(X, 0x490000, 0, R, S, T)\n#define XT_INS_L32E_S32E_MASK(X)   (XT_ISBE(X) ? 0xF000FF << 8 : 0xFF000F)\n\n#define XT_INS_RFWO(X) (XT_ISBE(X) ? 0x004300 << 8 : 0x003400)\n#define XT_INS_RFWU(X) (XT_ISBE(X) ? 0x005300 << 8 : 0x003500)\n#define XT_INS_RFWO_RFWU_MASK(X)   (XT_ISBE(X) ? 0xFFFFFF << 8 : 0xFFFFFF)\n\n#define XT_WATCHPOINTS_NUM_MAX  2\n\n/* Special register number macro for DDR, PS, WB, A3, A4 registers.\n * These get used a lot so making a shortcut is useful.\n */\n#define XT_SR_DDR         (xtensa_regs[XT_REG_IDX_DDR].reg_num)\n#define XT_SR_PS          (xtensa_regs[XT_REG_IDX_PS].reg_num)\n#define XT_SR_WB          (xtensa_regs[XT_REG_IDX_WINDOWBASE].reg_num)\n#define XT_REG_A0         (xtensa_regs[XT_REG_IDX_AR0].reg_num)\n#define XT_REG_A3         (xtensa_regs[XT_REG_IDX_AR3].reg_num)\n#define XT_REG_A4         (xtensa_regs[XT_REG_IDX_AR4].reg_num)\n\n#define XT_PS_REG_NUM               (0xe6U)\n#define XT_EPS_REG_NUM_BASE         (0xc0U)\t/* (EPS2 - 2), for adding DBGLEVEL */\n#define XT_EPC_REG_NUM_BASE         (0xb0U)\t/* (EPC1 - 1), for adding DBGLEVEL */\n#define XT_PC_REG_NUM_VIRTUAL       (0xffU)\t/* Marker for computing PC (EPC[DBGLEVEL) */\n#define XT_PC_DBREG_NUM_BASE        (0x20U)\t/* External (i.e., GDB) access */\n#define XT_NX_IBREAKC_BASE          (0xc0U)\t/* (IBREAKC0..IBREAKC1) for NX */\n\n#define XT_SW_BREAKPOINTS_MAX_NUM       32\n#define XT_HW_IBREAK_MAX_NUM            2\n#define XT_HW_DBREAK_MAX_NUM            2\n\nstruct xtensa_reg_desc xtensa_regs[XT_NUM_REGS] = {\n\tXT_MK_REG_DESC(\"pc\", XT_PC_REG_NUM_VIRTUAL, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"ar0\", 0x00, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar1\", 0x01, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar2\", 0x02, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar3\", 0x03, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar4\", 0x04, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar5\", 0x05, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar6\", 0x06, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar7\", 0x07, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar8\", 0x08, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar9\", 0x09, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar10\", 0x0A, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar11\", 0x0B, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar12\", 0x0C, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar13\", 0x0D, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar14\", 0x0E, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar15\", 0x0F, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar16\", 0x10, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar17\", 0x11, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar18\", 0x12, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar19\", 0x13, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar20\", 0x14, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar21\", 0x15, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar22\", 0x16, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar23\", 0x17, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar24\", 0x18, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar25\", 0x19, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar26\", 0x1A, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar27\", 0x1B, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar28\", 0x1C, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar29\", 0x1D, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar30\", 0x1E, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar31\", 0x1F, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar32\", 0x20, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar33\", 0x21, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar34\", 0x22, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar35\", 0x23, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar36\", 0x24, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar37\", 0x25, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar38\", 0x26, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar39\", 0x27, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar40\", 0x28, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar41\", 0x29, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar42\", 0x2A, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar43\", 0x2B, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar44\", 0x2C, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar45\", 0x2D, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar46\", 0x2E, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar47\", 0x2F, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar48\", 0x30, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar49\", 0x31, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar50\", 0x32, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar51\", 0x33, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar52\", 0x34, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar53\", 0x35, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar54\", 0x36, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar55\", 0x37, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar56\", 0x38, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar57\", 0x39, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar58\", 0x3A, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar59\", 0x3B, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar60\", 0x3C, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar61\", 0x3D, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar62\", 0x3E, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"ar63\", 0x3F, XT_REG_GENERAL, 0),\n\tXT_MK_REG_DESC(\"windowbase\", 0x48, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"windowstart\", 0x49, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"ps\", XT_PS_REG_NUM, XT_REG_SPECIAL, 0),\t/* PS (not mapped through EPS[]) */\n\tXT_MK_REG_DESC(\"ibreakenable\", 0x60, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"ddr\", 0x68, XT_REG_DEBUG, XT_REGF_NOREAD),\n\tXT_MK_REG_DESC(\"ibreaka0\", 0x80, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"ibreaka1\", 0x81, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"dbreaka0\", 0x90, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"dbreaka1\", 0x91, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"dbreakc0\", 0xA0, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"dbreakc1\", 0xA1, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"cpenable\", 0xE0, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"exccause\", 0xE8, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"debugcause\", 0xE9, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"icount\", 0xEC, XT_REG_SPECIAL, 0),\n\tXT_MK_REG_DESC(\"icountlevel\", 0xED, XT_REG_SPECIAL, 0),\n\n\t/* WARNING: For these registers, regnum points to the\n\t * index of the corresponding ARx registers, NOT to\n\t * the processor register number! */\n\tXT_MK_REG_DESC(\"a0\", XT_REG_IDX_AR0, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a1\", XT_REG_IDX_AR1, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a2\", XT_REG_IDX_AR2, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a3\", XT_REG_IDX_AR3, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a4\", XT_REG_IDX_AR4, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a5\", XT_REG_IDX_AR5, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a6\", XT_REG_IDX_AR6, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a7\", XT_REG_IDX_AR7, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a8\", XT_REG_IDX_AR8, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a9\", XT_REG_IDX_AR9, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a10\", XT_REG_IDX_AR10, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a11\", XT_REG_IDX_AR11, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a12\", XT_REG_IDX_AR12, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a13\", XT_REG_IDX_AR13, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a14\", XT_REG_IDX_AR14, XT_REG_RELGEN, 0),\n\tXT_MK_REG_DESC(\"a15\", XT_REG_IDX_AR15, XT_REG_RELGEN, 0),\n};\n\n/**\n * Types of memory used at xtensa target\n */\nenum xtensa_mem_region_type {\n\tXTENSA_MEM_REG_IROM = 0x0,\n\tXTENSA_MEM_REG_IRAM,\n\tXTENSA_MEM_REG_DROM,\n\tXTENSA_MEM_REG_DRAM,\n\tXTENSA_MEM_REG_SRAM,\n\tXTENSA_MEM_REG_SROM,\n\tXTENSA_MEM_REGS_NUM\n};\n\n/* Register definition as union for list allocation */\nunion xtensa_reg_val_u {\n\txtensa_reg_val_t val;\n\tuint8_t buf[4];\n};\n\nstatic const struct xtensa_keyval_info_s xt_qerr[XT_QERR_NUM] = {\n\t{ .chrval = \"E00\", .intval = ERROR_FAIL },\n\t{ .chrval = \"E01\", .intval = ERROR_FAIL },\n\t{ .chrval = \"E02\", .intval = ERROR_COMMAND_ARGUMENT_INVALID },\n\t{ .chrval = \"E03\", .intval = ERROR_FAIL },\n};\n\n/* Set to true for extra debug logging */\nstatic const bool xtensa_extra_debug_log;\n\n/**\n * Gets a config for the specific mem type\n */\nstatic inline const struct xtensa_local_mem_config *xtensa_get_mem_config(\n\tstruct xtensa *xtensa,\n\tenum xtensa_mem_region_type type)\n{\n\tswitch (type) {\n\tcase XTENSA_MEM_REG_IROM:\n\t\treturn &xtensa->core_config->irom;\n\tcase XTENSA_MEM_REG_IRAM:\n\t\treturn &xtensa->core_config->iram;\n\tcase XTENSA_MEM_REG_DROM:\n\t\treturn &xtensa->core_config->drom;\n\tcase XTENSA_MEM_REG_DRAM:\n\t\treturn &xtensa->core_config->dram;\n\tcase XTENSA_MEM_REG_SRAM:\n\t\treturn &xtensa->core_config->sram;\n\tcase XTENSA_MEM_REG_SROM:\n\t\treturn &xtensa->core_config->srom;\n\tdefault:\n\t\treturn NULL;\n\t}\n}\n\n/**\n * Extracts an exact xtensa_local_mem_region_config from xtensa_local_mem_config\n * for a given address\n * Returns NULL if nothing found\n */\nstatic inline const struct xtensa_local_mem_region_config *xtensa_memory_region_find(\n\tconst struct xtensa_local_mem_config *mem,\n\ttarget_addr_t address)\n{\n\tfor (unsigned int i = 0; i < mem->count; i++) {\n\t\tconst struct xtensa_local_mem_region_config *region = &mem->regions[i];\n\t\tif (address >= region->base && address < (region->base + region->size))\n\t\t\treturn region;\n\t}\n\treturn NULL;\n}\n\n/**\n * Returns a corresponding xtensa_local_mem_region_config from the xtensa target\n * for a given address\n * Returns NULL if nothing found\n */\nstatic inline const struct xtensa_local_mem_region_config *xtensa_target_memory_region_find(\n\tstruct xtensa *xtensa,\n\ttarget_addr_t address)\n{\n\tconst struct xtensa_local_mem_region_config *result;\n\tconst struct xtensa_local_mem_config *mcgf;\n\tfor (unsigned int mtype = 0; mtype < XTENSA_MEM_REGS_NUM; mtype++) {\n\t\tmcgf = xtensa_get_mem_config(xtensa, mtype);\n\t\tresult = xtensa_memory_region_find(mcgf, address);\n\t\tif (result)\n\t\t\treturn result;\n\t}\n\treturn NULL;\n}\n\nstatic inline bool xtensa_is_cacheable(const struct xtensa_cache_config *cache,\n\tconst struct xtensa_local_mem_config *mem,\n\ttarget_addr_t address)\n{\n\tif (!cache->size)\n\t\treturn false;\n\treturn xtensa_memory_region_find(mem, address);\n}\n\nstatic inline bool xtensa_is_icacheable(struct xtensa *xtensa, target_addr_t address)\n{\n\treturn xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->iram, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->irom, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->sram, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->icache, &xtensa->core_config->srom, address);\n}\n\nstatic inline bool xtensa_is_dcacheable(struct xtensa *xtensa, target_addr_t address)\n{\n\treturn xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->dram, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->drom, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->sram, address) ||\n\t       xtensa_is_cacheable(&xtensa->core_config->dcache, &xtensa->core_config->srom, address);\n}\n\nstatic int xtensa_core_reg_get(struct reg *reg)\n{\n\t/* We don't need this because we read all registers on halt anyway. */\n\tstruct xtensa *xtensa = (struct xtensa *)reg->arch_info;\n\tstruct target *target = xtensa->target;\n\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\tif (!reg->exist) {\n\t\tif (strncmp(reg->name, \"?0x\", 3) == 0) {\n\t\t\tunsigned int regnum = strtoul(reg->name + 1, NULL, 0);\n\t\t\tLOG_WARNING(\"Read unknown register 0x%04x ignored\", regnum);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int xtensa_core_reg_set(struct reg *reg, uint8_t *buf)\n{\n\tstruct xtensa *xtensa = (struct xtensa *)reg->arch_info;\n\tstruct target *target = xtensa->target;\n\n\tassert(reg->size <= 64 && \"up to 64-bit regs are supported only!\");\n\tif (target->state != TARGET_HALTED)\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\n\tif (!reg->exist) {\n\t\tif (strncmp(reg->name, \"?0x\", 3) == 0) {\n\t\t\tunsigned int regnum = strtoul(reg->name + 1, NULL, 0);\n\t\t\tLOG_WARNING(\"Write unknown register 0x%04x ignored\", regnum);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tbuf_cpy(buf, reg->value, reg->size);\n\n\tif (xtensa->core_config->windowed) {\n\t\t/* If the user updates a potential scratch register, track for conflicts */\n\t\tfor (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {\n\t\t\tif (strcmp(reg->name, xtensa->scratch_ars[s].chrval) == 0) {\n\t\t\t\tLOG_DEBUG(\"Scratch reg %s [0x%08\" PRIx32 \"] set from gdb\", reg->name,\n\t\t\t\t\tbuf_get_u32(reg->value, 0, 32));\n\t\t\t\tLOG_DEBUG(\"scratch_ars mapping: a3/%s, a4/%s\",\n\t\t\t\t\txtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval,\n\t\t\t\t\txtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval);\n\t\t\t\txtensa->scratch_ars[s].intval = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treg->dirty = true;\n\treg->valid = true;\n\n\treturn ERROR_OK;\n}\n\nstatic const struct reg_arch_type xtensa_reg_type = {\n\t.get = xtensa_core_reg_get,\n\t.set = xtensa_core_reg_set,\n};\n\n/* Convert a register index that's indexed relative to windowbase, to the real address. */\nstatic enum xtensa_reg_id xtensa_windowbase_offset_to_canonical(struct xtensa *xtensa,\n\tenum xtensa_reg_id reg_idx,\n\tint windowbase)\n{\n\tunsigned int idx;\n\tif (reg_idx >= XT_REG_IDX_AR0 && reg_idx <= XT_REG_IDX_ARLAST) {\n\t\tidx = reg_idx - XT_REG_IDX_AR0;\n\t} else if (reg_idx >= XT_REG_IDX_A0 && reg_idx <= XT_REG_IDX_A15) {\n\t\tidx = reg_idx - XT_REG_IDX_A0;\n\t} else {\n\t\tLOG_ERROR(\"Error: can't convert register %d to non-windowbased register!\", reg_idx);\n\t\treturn -1;\n\t}\n\t/* Each windowbase value represents 4 registers on LX and 8 on NX */\n\tint base_inc = (xtensa->core_config->core_type == XT_LX) ? 4 : 8;\n\treturn ((idx + windowbase * base_inc) & (xtensa->core_config->aregs_num - 1)) + XT_REG_IDX_AR0;\n}\n\nstatic enum xtensa_reg_id xtensa_canonical_to_windowbase_offset(struct xtensa *xtensa,\n\tenum xtensa_reg_id reg_idx,\n\tint windowbase)\n{\n\treturn xtensa_windowbase_offset_to_canonical(xtensa, reg_idx, -windowbase);\n}\n\nstatic void xtensa_mark_register_dirty(struct xtensa *xtensa, enum xtensa_reg_id reg_idx)\n{\n\tstruct reg *reg_list = xtensa->core_cache->reg_list;\n\treg_list[reg_idx].dirty = true;\n}\n\nstatic void xtensa_queue_exec_ins(struct xtensa *xtensa, uint32_t ins)\n{\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DIR0EXEC, ins);\n}\n\nstatic void xtensa_queue_exec_ins_wide(struct xtensa *xtensa, uint8_t *ops, uint8_t oplen)\n{\n\tconst int max_oplen = 64;\t/* 8 DIRx regs: max width 64B */\n\tif ((oplen > 0) && (oplen <= max_oplen)) {\n\t\tuint8_t ops_padded[max_oplen];\n\t\tmemcpy(ops_padded, ops, oplen);\n\t\tmemset(ops_padded + oplen, 0, max_oplen - oplen);\n\t\tunsigned int oplenw = DIV_ROUND_UP(oplen, sizeof(uint32_t));\n\t\tfor (int32_t i = oplenw - 1; i > 0; i--)\n\t\t\txtensa_queue_dbg_reg_write(xtensa,\n\t\t\t\tXDMREG_DIR0 + i,\n\t\t\t\ttarget_buffer_get_u32(xtensa->target, &ops_padded[sizeof(uint32_t)*i]));\n\t\t/* Write DIR0EXEC last */\n\t\txtensa_queue_dbg_reg_write(xtensa,\n\t\t\tXDMREG_DIR0EXEC,\n\t\t\ttarget_buffer_get_u32(xtensa->target, &ops_padded[0]));\n\t}\n}\n\nstatic int xtensa_queue_pwr_reg_write(struct xtensa *xtensa, unsigned int reg, uint32_t data)\n{\n\tstruct xtensa_debug_module *dm = &xtensa->dbg_mod;\n\treturn dm->pwr_ops->queue_reg_write(dm, reg, data);\n}\n\n/* NOTE: Assumes A3 has already been saved */\nstatic int xtensa_window_state_save(struct target *target, uint32_t *woe)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB;\n\tuint32_t woe_dis;\n\tuint8_t woe_buf[4];\n\n\tif (xtensa->core_config->windowed) {\n\t\t/* Save PS (LX) or WB (NX) and disable window overflow exceptions prior to AR save */\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, woe_sr, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, woe_buf);\n\t\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to read %s (%d)!\",\n\t\t\t\t(woe_sr == XT_SR_PS) ? \"PS\" : \"WB\", res);\n\t\t\treturn res;\n\t\t}\n\t\txtensa_core_status_check(target);\n\t\t*woe = buf_get_u32(woe_buf, 0, 32);\n\t\twoe_dis = *woe & ~((woe_sr == XT_SR_PS) ? XT_PS_WOE_MSK : XT_WB_S_MSK);\n\t\tLOG_TARGET_DEBUG(target, \"Clearing %s (0x%08\" PRIx32 \" -> 0x%08\" PRIx32 \")\",\n\t\t\t(woe_sr == XT_SR_PS) ? \"PS.WOE\" : \"WB.S\", *woe, woe_dis);\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe_dis);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, woe_sr, XT_REG_A3));\n\t}\n\treturn ERROR_OK;\n}\n\n/* NOTE: Assumes A3 has already been saved */\nstatic void xtensa_window_state_restore(struct target *target, uint32_t woe)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int woe_sr = (xtensa->core_config->core_type == XT_LX) ? XT_SR_PS : XT_SR_WB;\n\tif (xtensa->core_config->windowed) {\n\t\t/* Restore window overflow exception state */\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, woe);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, woe_sr, XT_REG_A3));\n\t\tLOG_TARGET_DEBUG(target, \"Restored %s (0x%08\" PRIx32 \")\",\n\t\t\t(woe_sr == XT_SR_PS) ? \"PS.WOE\" : \"WB\", woe);\n\t}\n}\n\nstatic bool xtensa_reg_is_readable(int flags, int cpenable)\n{\n\tif (flags & XT_REGF_NOREAD)\n\t\treturn false;\n\tif ((flags & XT_REGF_COPROC0) && (cpenable & BIT(0)) == 0)\n\t\treturn false;\n\treturn true;\n}\n\nstatic bool xtensa_scratch_regs_fixup(struct xtensa *xtensa, struct reg *reg_list, int i, int j, int a_idx, int ar_idx)\n{\n\tint a_name = (a_idx == XT_AR_SCRATCH_A3) ? 3 : 4;\n\tif (xtensa->scratch_ars[a_idx].intval && !xtensa->scratch_ars[ar_idx].intval) {\n\t\tLOG_DEBUG(\"AR conflict: a%d -> ar%d\", a_name, j - XT_REG_IDX_AR0);\n\t\tmemcpy(reg_list[j].value, reg_list[i].value, sizeof(xtensa_reg_val_t));\n\t} else {\n\t\tLOG_DEBUG(\"AR conflict: ar%d -> a%d\", j - XT_REG_IDX_AR0, a_name);\n\t\tmemcpy(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t));\n\t}\n\treturn xtensa->scratch_ars[a_idx].intval && xtensa->scratch_ars[ar_idx].intval;\n}\n\nstatic int xtensa_write_dirty_registers(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res;\n\txtensa_reg_val_t regval, windowbase = 0;\n\tbool scratch_reg_dirty = false, delay_cpenable = false;\n\tstruct reg *reg_list = xtensa->core_cache->reg_list;\n\tunsigned int reg_list_size = xtensa->core_cache->num_regs;\n\tbool preserve_a3 = false;\n\tuint8_t a3_buf[4];\n\txtensa_reg_val_t a3 = 0, woe;\n\tunsigned int ms_idx = (xtensa->core_config->core_type == XT_NX) ?\n\t\txtensa->nx_reg_idx[XT_NX_REG_IDX_MS] : reg_list_size;\n\txtensa_reg_val_t ms = 0;\n\tbool restore_ms = false;\n\n\tLOG_TARGET_DEBUG(target, \"start\");\n\n\t/* We need to write the dirty registers in the cache list back to the processor.\n\t * Start by writing the SFR/user registers. */\n\tfor (unsigned int i = 0; i < reg_list_size; i++) {\n\t\tstruct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;\n\t\tunsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;\n\t\tif (reg_list[i].dirty) {\n\t\t\tif (rlist[ridx].type == XT_REG_SPECIAL ||\n\t\t\t\trlist[ridx].type == XT_REG_USER ||\n\t\t\t\trlist[ridx].type == XT_REG_FR) {\n\t\t\t\tscratch_reg_dirty = true;\n\t\t\t\tif (i == XT_REG_IDX_CPENABLE) {\n\t\t\t\t\tdelay_cpenable = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tregval = xtensa_reg_get(target, i);\n\t\t\t\tLOG_TARGET_DEBUG(target, \"Writing back reg %s (%d) val %08\" PRIX32,\n\t\t\t\t\treg_list[i].name,\n\t\t\t\t\trlist[ridx].reg_num,\n\t\t\t\t\tregval);\n\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t\tif (reg_list[i].exist) {\n\t\t\t\t\tunsigned int reg_num = rlist[ridx].reg_num;\n\t\t\t\t\tif (rlist[ridx].type == XT_REG_USER) {\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WUR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t\t} else if (rlist[ridx].type == XT_REG_FR) {\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WFR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t\t} else {/*SFR */\n\t\t\t\t\t\tif (reg_num == XT_PC_REG_NUM_VIRTUAL) {\n\t\t\t\t\t\t\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t\t\t\t\t\t\t/* reg number of PC for debug interrupt depends on NDEBUGLEVEL */\n\t\t\t\t\t\t\t\treg_num = (XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level);\n\t\t\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t/* NX PC set through issuing a jump instruction */\n\t\t\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_JX(xtensa, XT_REG_A3));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (i == ms_idx) {\n\t\t\t\t\t\t\t/* MS must be restored after ARs.  This ensures ARs remain in correct\n\t\t\t\t\t\t\t * order even for reversed register groups (overflow/underflow).\n\t\t\t\t\t\t\t */\n\t\t\t\t\t\t\tms = regval;\n\t\t\t\t\t\t\trestore_ms = true;\n\t\t\t\t\t\t\tLOG_TARGET_DEBUG(target, \"Delaying MS write: 0x%x\", ms);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treg_list[i].dirty = false;\n\t\t\t}\n\t\t}\n\t}\n\tif (scratch_reg_dirty)\n\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);\n\tif (delay_cpenable) {\n\t\tregval = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);\n\t\tLOG_TARGET_DEBUG(target, \"Writing back reg cpenable (224) val %08\" PRIX32, regval);\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,\n\t\t\txtensa_regs[XT_REG_IDX_CPENABLE].reg_num,\n\t\t\tXT_REG_A3));\n\t\treg_list[XT_REG_IDX_CPENABLE].dirty = false;\n\t}\n\n\tpreserve_a3 = (xtensa->core_config->windowed) || (xtensa->core_config->core_type == XT_NX);\n\tif (preserve_a3) {\n\t\t/* Save (windowed) A3 for scratch use */\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);\n\t\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\txtensa_core_status_check(target);\n\t\ta3 = buf_get_u32(a3_buf, 0, 32);\n\t}\n\n\tif (xtensa->core_config->windowed) {\n\t\tres = xtensa_window_state_save(target, &woe);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\t/* Grab the windowbase, we need it. */\n\t\tuint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?\n\t\t\tXT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB];\n\t\twindowbase = xtensa_reg_get(target, wb_idx);\n\t\tif (xtensa->core_config->core_type == XT_NX)\n\t\t\twindowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;\n\n\t\t/* Check if there are mismatches between the ARx and corresponding Ax registers.\n\t\t * When the user sets a register on a windowed config, xt-gdb may set the ARx\n\t\t * register directly.  Thus we take ARx as priority over Ax if both are dirty\n\t\t * and it's unclear if the user set one over the other explicitly.\n\t\t */\n\t\tfor (unsigned int i = XT_REG_IDX_A0; i <= XT_REG_IDX_A15; i++) {\n\t\t\tunsigned int j = xtensa_windowbase_offset_to_canonical(xtensa, i, windowbase);\n\t\t\tif (reg_list[i].dirty && reg_list[j].dirty) {\n\t\t\t\tif (memcmp(reg_list[i].value, reg_list[j].value, sizeof(xtensa_reg_val_t)) != 0) {\n\t\t\t\t\tbool show_warning = true;\n\t\t\t\t\tif (i == XT_REG_IDX_A3)\n\t\t\t\t\t\tshow_warning = xtensa_scratch_regs_fixup(xtensa,\n\t\t\t\t\t\t\treg_list, i, j, XT_AR_SCRATCH_A3, XT_AR_SCRATCH_AR3);\n\t\t\t\t\telse if (i == XT_REG_IDX_A4)\n\t\t\t\t\t\tshow_warning = xtensa_scratch_regs_fixup(xtensa,\n\t\t\t\t\t\t\treg_list, i, j, XT_AR_SCRATCH_A4, XT_AR_SCRATCH_AR4);\n\t\t\t\t\tif (show_warning)\n\t\t\t\t\t\tLOG_WARNING(\n\t\t\t\t\t\t\t\"Warning: Both A%d [0x%08\" PRIx32\n\t\t\t\t\t\t\t\"] as well as its underlying physical register \"\n\t\t\t\t\t\t\t\"(AR%d) [0x%08\" PRIx32 \"] are dirty and differ in value\",\n\t\t\t\t\t\t\ti - XT_REG_IDX_A0,\n\t\t\t\t\t\t\tbuf_get_u32(reg_list[i].value, 0, 32),\n\t\t\t\t\t\t\tj - XT_REG_IDX_AR0,\n\t\t\t\t\t\t\tbuf_get_u32(reg_list[j].value, 0, 32));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Write A0-A16. */\n\tfor (unsigned int i = 0; i < 16; i++) {\n\t\tif (reg_list[XT_REG_IDX_A0 + i].dirty) {\n\t\t\tregval = xtensa_reg_get(target, XT_REG_IDX_A0 + i);\n\t\t\tLOG_TARGET_DEBUG(target, \"Writing back reg %s value %08\" PRIX32 \", num =%i\",\n\t\t\t\txtensa_regs[XT_REG_IDX_A0 + i].name,\n\t\t\t\tregval,\n\t\t\t\txtensa_regs[XT_REG_IDX_A0 + i].reg_num);\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, i));\n\t\t\treg_list[XT_REG_IDX_A0 + i].dirty = false;\n\t\t\tif (i == 3) {\n\t\t\t\t/* Avoid stomping A3 during restore at end of function */\n\t\t\t\ta3 = regval;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (xtensa->core_config->windowed) {\n\t\t/* Now write AR registers */\n\t\tfor (unsigned int j = 0; j < XT_REG_IDX_ARLAST; j += 16) {\n\t\t\t/* Write the 16 registers we can see */\n\t\t\tfor (unsigned int i = 0; i < 16; i++) {\n\t\t\t\tif (i + j < xtensa->core_config->aregs_num) {\n\t\t\t\t\tenum xtensa_reg_id realadr =\n\t\t\t\t\t\txtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_AR0 + i + j,\n\t\t\t\t\t\twindowbase);\n\t\t\t\t\t/* Write back any dirty un-windowed registers */\n\t\t\t\t\tif (reg_list[realadr].dirty) {\n\t\t\t\t\t\tregval = xtensa_reg_get(target, realadr);\n\t\t\t\t\t\tLOG_TARGET_DEBUG(\n\t\t\t\t\t\t\ttarget,\n\t\t\t\t\t\t\t\"Writing back reg %s value %08\" PRIX32 \", num =%i\",\n\t\t\t\t\t\t\txtensa_regs[realadr].name,\n\t\t\t\t\t\t\tregval,\n\t\t\t\t\t\t\txtensa_regs[realadr].reg_num);\n\t\t\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, regval);\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa,\n\t\t\t\t\t\t\tXT_INS_RSR(xtensa, XT_SR_DDR,\n\t\t\t\t\t\t\t\txtensa_regs[XT_REG_IDX_AR0 + i].reg_num));\n\t\t\t\t\t\treg_list[realadr].dirty = false;\n\t\t\t\t\t\tif ((i + j) == 3)\n\t\t\t\t\t\t\t/* Avoid stomping AR during A3 restore at end of function */\n\t\t\t\t\t\t\ta3 = regval;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Now rotate the window so we'll see the next 16 registers. The final rotate\n\t\t\t * will wraparound, leaving us in the state we were.\n\t\t\t * Each ROTW rotates 4 registers on LX and 8 on NX */\n\t\t\tint rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2;\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, rotw_arg));\n\t\t}\n\n\t\txtensa_window_state_restore(target, woe);\n\n\t\tfor (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)\n\t\t\txtensa->scratch_ars[s].intval = false;\n\t}\n\n\tif (restore_ms) {\n\t\tuint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num;\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, ms);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, ms_regno, XT_REG_A3));\n\t\tLOG_TARGET_DEBUG(target, \"Delayed MS (0x%x) write complete: 0x%x\", ms_regno, ms);\n\t}\n\n\tif (preserve_a3) {\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t}\n\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\txtensa_core_status_check(target);\n\n\treturn res;\n}\n\nstatic inline bool xtensa_is_stopped(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\treturn xtensa->dbg_mod.core_status.dsr & OCDDSR_STOPPED;\n}\n\nint xtensa_examine(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa);\n\n\tLOG_DEBUG(\"coreid = %d\", target->coreid);\n\n\tif (xtensa->core_config->core_type == XT_UNDEF) {\n\t\tLOG_ERROR(\"XTensa core not configured; is xtensa-core-openocd.cfg missing?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\txtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);\n\txtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa));\n\txtensa_dm_queue_enable(&xtensa->dbg_mod);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (!xtensa_dm_is_online(&xtensa->dbg_mod)) {\n\t\tLOG_ERROR(\"Unexpected OCD_ID = %08\" PRIx32, xtensa->dbg_mod.device_id);\n\t\treturn ERROR_TARGET_FAILURE;\n\t}\n\tLOG_DEBUG(\"OCD_ID = %08\" PRIx32, xtensa->dbg_mod.device_id);\n\ttarget_set_examined(target);\n\txtensa_smpbreak_write(xtensa, xtensa->smp_break);\n\treturn ERROR_OK;\n}\n\nint xtensa_wakeup(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int cmd = PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) | PWRCTL_COREWAKEUP(xtensa);\n\n\tif (xtensa->reset_asserted)\n\t\tcmd |= PWRCTL_CORERESET(xtensa);\n\txtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd);\n\t/* TODO: can we join this with the write above? */\n\txtensa_queue_pwr_reg_write(xtensa, XDMREG_PWRCTL, cmd | PWRCTL_JTAGDEBUGUSE(xtensa));\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\treturn xtensa_dm_queue_execute(&xtensa->dbg_mod);\n}\n\nint xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set)\n{\n\tuint32_t dsr_data = 0x00110000;\n\tuint32_t clear = (set | OCDDCR_ENABLEOCD) ^\n\t\t(OCDDCR_BREAKINEN | OCDDCR_BREAKOUTEN | OCDDCR_RUNSTALLINEN |\n\t\tOCDDCR_DEBUGMODEOUTEN | OCDDCR_ENABLEOCD);\n\n\tLOG_TARGET_DEBUG(xtensa->target, \"write smpbreak set=0x%\" PRIx32 \" clear=0x%\" PRIx32, set, clear);\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, set | OCDDCR_ENABLEOCD);\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, clear);\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DSR, dsr_data);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\treturn xtensa_dm_queue_execute(&xtensa->dbg_mod);\n}\n\nint xtensa_smpbreak_set(struct target *target, uint32_t set)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res = ERROR_OK;\n\n\txtensa->smp_break = set;\n\tif (target_was_examined(target))\n\t\tres = xtensa_smpbreak_write(xtensa, xtensa->smp_break);\n\tLOG_TARGET_DEBUG(target, \"set smpbreak=%\" PRIx32 \", state=%i\", set, target->state);\n\treturn res;\n}\n\nint xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val)\n{\n\tuint8_t dcr_buf[sizeof(uint32_t)];\n\n\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DCRSET, dcr_buf);\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t*val = buf_get_u32(dcr_buf, 0, 32);\n\n\treturn res;\n}\n\nint xtensa_smpbreak_get(struct target *target, uint32_t *val)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\t*val = xtensa->smp_break;\n\treturn ERROR_OK;\n}\n\nstatic inline xtensa_reg_val_t xtensa_reg_get_value(struct reg *reg)\n{\n\treturn buf_get_u32(reg->value, 0, 32);\n}\n\nstatic inline void xtensa_reg_set_value(struct reg *reg, xtensa_reg_val_t value)\n{\n\tbuf_set_u32(reg->value, 0, 32, value);\n\treg->dirty = true;\n}\n\nstatic int xtensa_imprecise_exception_occurred(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tfor (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESR; idx++) {\n\t\tenum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx];\n\t\tif (xtensa->nx_reg_idx[idx]) {\n\t\t\txtensa_reg_val_t reg = xtensa_reg_get(target, xtensa->nx_reg_idx[idx]);\n\t\t\tif (reg & XT_IMPR_EXC_MSK) {\n\t\t\t\tLOG_TARGET_DEBUG(target, \"Imprecise exception: %s: 0x%x\",\n\t\t\t\t\txtensa->core_cache->reg_list[ridx].name, reg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\treturn false;\n}\n\nstatic void xtensa_imprecise_exception_clear(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tfor (enum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_IEVEC; idx <= XT_NX_REG_IDX_MESRCLR; idx++) {\n\t\tenum xtensa_reg_id ridx = xtensa->nx_reg_idx[idx];\n\t\tif (ridx && idx != XT_NX_REG_IDX_MESR) {\n\t\t\txtensa_reg_val_t value = (idx == XT_NX_REG_IDX_MESRCLR) ? XT_MESRCLR_IMPR_EXC_MSK : 0;\n\t\t\txtensa_reg_set(target, ridx, value);\n\t\t\tLOG_TARGET_DEBUG(target, \"Imprecise exception: clearing %s (0x%x)\",\n\t\t\t\txtensa->core_cache->reg_list[ridx].name, value);\n\t\t}\n\t}\n}\n\nint xtensa_core_status_check(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res, needclear = 0, needimprclear = 0;\n\n\txtensa_dm_core_status_read(&xtensa->dbg_mod);\n\txtensa_dsr_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod);\n\tLOG_TARGET_DEBUG(target, \"DSR (%08\" PRIX32 \")\", dsr);\n\tif (dsr & OCDDSR_EXECBUSY) {\n\t\tif (!xtensa->suppress_dsr_errors)\n\t\t\tLOG_TARGET_ERROR(target, \"DSR (%08\" PRIX32 \") indicates target still busy!\", dsr);\n\t\tneedclear = 1;\n\t}\n\tif (dsr & OCDDSR_EXECEXCEPTION) {\n\t\tif (!xtensa->suppress_dsr_errors)\n\t\t\tLOG_TARGET_ERROR(target,\n\t\t\t\t\"DSR (%08\" PRIX32 \") indicates DIR instruction generated an exception!\",\n\t\t\t\tdsr);\n\t\tneedclear = 1;\n\t}\n\tif (dsr & OCDDSR_EXECOVERRUN) {\n\t\tif (!xtensa->suppress_dsr_errors)\n\t\t\tLOG_TARGET_ERROR(target,\n\t\t\t\t\"DSR (%08\" PRIX32 \") indicates DIR instruction generated an overrun!\",\n\t\t\t\tdsr);\n\t\tneedclear = 1;\n\t}\n\tif (xtensa->core_config->core_type == XT_NX && (xtensa_imprecise_exception_occurred(target))) {\n\t\tif (!xtensa->suppress_dsr_errors)\n\t\t\tLOG_TARGET_ERROR(target,\n\t\t\t\t\"%s: Imprecise exception occurred!\", target_name(target));\n\t\tneedclear = 1;\n\t\tneedimprclear = 1;\n\t}\n\tif (needclear) {\n\t\tres = xtensa_dm_core_status_clear(&xtensa->dbg_mod,\n\t\t\tOCDDSR_EXECEXCEPTION | OCDDSR_EXECOVERRUN);\n\t\tif (res != ERROR_OK && !xtensa->suppress_dsr_errors)\n\t\t\tLOG_TARGET_ERROR(target, \"clearing DSR failed!\");\n\t\tif (xtensa->core_config->core_type == XT_NX && needimprclear)\n\t\t\txtensa_imprecise_exception_clear(target);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nxtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct reg *reg = &xtensa->core_cache->reg_list[reg_id];\n\treturn xtensa_reg_get_value(reg);\n}\n\nvoid xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct reg *reg = &xtensa->core_cache->reg_list[reg_id];\n\tif (xtensa_reg_get_value(reg) == value)\n\t\treturn;\n\txtensa_reg_set_value(reg, value);\n}\n\n/* Set Ax (XT_REG_RELGEN) register along with its underlying ARx (XT_REG_GENERAL) */\nvoid xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?\n\t\tXT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB];\n\tuint32_t windowbase = (xtensa->core_config->windowed ?\n\t\txtensa_reg_get(target, wb_idx) : 0);\n\tif (xtensa->core_config->core_type == XT_NX)\n\t\twindowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;\n\tint ar_idx = xtensa_windowbase_offset_to_canonical(xtensa, a_idx, windowbase);\n\txtensa_reg_set(target, a_idx, value);\n\txtensa_reg_set(target, ar_idx, value);\n}\n\n/* Read cause for entering halted state; return bitmask in DEBUGCAUSE_* format */\nuint32_t xtensa_cause_get(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t/* LX cause in DEBUGCAUSE */\n\t\treturn xtensa_reg_get(target, XT_REG_IDX_DEBUGCAUSE);\n\t}\n\tif (xtensa->nx_stop_cause & DEBUGCAUSE_VALID)\n\t\treturn xtensa->nx_stop_cause;\n\n\t/* NX cause determined from DSR.StopCause */\n\tif (xtensa_dm_core_status_read(&xtensa->dbg_mod) != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Read DSR error\");\n\t} else {\n\t\tuint32_t dsr = xtensa_dm_core_status_get(&xtensa->dbg_mod);\n\t\t/* NX causes are prioritized; only 1 bit can be set */\n\t\tswitch ((dsr & OCDDSR_STOPCAUSE) >> OCDDSR_STOPCAUSE_SHIFT) {\n\t\tcase OCDDSR_STOPCAUSE_DI:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_DI;\n\t\t\tbreak;\n\t\tcase OCDDSR_STOPCAUSE_SS:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_IC;\n\t\t\tbreak;\n\t\tcase OCDDSR_STOPCAUSE_IB:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_IB;\n\t\t\tbreak;\n\t\tcase OCDDSR_STOPCAUSE_B:\n\t\tcase OCDDSR_STOPCAUSE_B1:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_BI;\n\t\t\tbreak;\n\t\tcase OCDDSR_STOPCAUSE_BN:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_BN;\n\t\t\tbreak;\n\t\tcase OCDDSR_STOPCAUSE_DB0:\n\t\tcase OCDDSR_STOPCAUSE_DB1:\n\t\t\txtensa->nx_stop_cause = DEBUGCAUSE_DB;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_TARGET_ERROR(target, \"Unknown stop cause (DSR: 0x%08x)\", dsr);\n\t\t\tbreak;\n\t\t}\n\t\tif (xtensa->nx_stop_cause)\n\t\t\txtensa->nx_stop_cause |= DEBUGCAUSE_VALID;\n\t}\n\treturn xtensa->nx_stop_cause;\n}\n\nvoid xtensa_cause_clear(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tif (xtensa->core_config->core_type == XT_LX) {\n\t\txtensa_reg_set(target, XT_REG_IDX_DEBUGCAUSE, 0);\n\t\txtensa->core_cache->reg_list[XT_REG_IDX_DEBUGCAUSE].dirty = false;\n\t} else {\n\t\t/* NX DSR.STOPCAUSE is not writeable; clear cached copy but leave it valid */\n\t\txtensa->nx_stop_cause = DEBUGCAUSE_VALID;\n\t}\n}\n\nvoid xtensa_cause_reset(struct target *target)\n{\n\t/* Clear DEBUGCAUSE_VALID to trigger re-read (on NX) */\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\txtensa->nx_stop_cause = 0;\n}\n\nint xtensa_assert_reset(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_TARGET_DEBUG(target, \"target_number=%i, begin\", target->target_number);\n\txtensa_queue_pwr_reg_write(xtensa,\n\t\tXDMREG_PWRCTL,\n\t\tPWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) |\n\t\tPWRCTL_COREWAKEUP(xtensa) | PWRCTL_CORERESET(xtensa));\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/* registers are now invalid */\n\txtensa->reset_asserted = true;\n\tregister_cache_invalidate(xtensa->core_cache);\n\ttarget->state = TARGET_RESET;\n\treturn ERROR_OK;\n}\n\nint xtensa_deassert_reset(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_TARGET_DEBUG(target, \"halt=%d\", target->reset_halt);\n\tif (target->reset_halt)\n\t\txtensa_queue_dbg_reg_write(xtensa,\n\t\t\tXDMREG_DCRSET,\n\t\t\tOCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);\n\txtensa_queue_pwr_reg_write(xtensa,\n\t\tXDMREG_PWRCTL,\n\t\tPWRCTL_JTAGDEBUGUSE(xtensa) | PWRCTL_DEBUGWAKEUP(xtensa) | PWRCTL_MEMWAKEUP(xtensa) |\n\t\tPWRCTL_COREWAKEUP(xtensa));\n\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\ttarget->state = TARGET_RUNNING;\n\txtensa->reset_asserted = false;\n\treturn res;\n}\n\nint xtensa_soft_reset_halt(struct target *target)\n{\n\tLOG_TARGET_DEBUG(target, \"begin\");\n\treturn xtensa_assert_reset(target);\n}\n\nint xtensa_fetch_all_regs(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct reg *reg_list = xtensa->core_cache->reg_list;\n\tunsigned int reg_list_size = xtensa->core_cache->num_regs;\n\txtensa_reg_val_t cpenable = 0, windowbase = 0, a0 = 0, a3;\n\tunsigned int ms_idx = reg_list_size;\n\tuint32_t ms = 0;\n\tuint32_t woe;\n\tuint8_t a0_buf[4], a3_buf[4], ms_buf[4];\n\tbool debug_dsrs = !xtensa->regs_fetched || LOG_LEVEL_IS(LOG_LVL_DEBUG);\n\n\tunion xtensa_reg_val_u *regvals = calloc(reg_list_size, sizeof(*regvals));\n\tif (!regvals) {\n\t\tLOG_TARGET_ERROR(target, \"unable to allocate memory for regvals!\");\n\t\treturn ERROR_FAIL;\n\t}\n\tunion xtensa_reg_val_u *dsrs = calloc(reg_list_size, sizeof(*dsrs));\n\tif (!dsrs) {\n\t\tLOG_TARGET_ERROR(target, \"unable to allocate memory for dsrs!\");\n\t\tfree(regvals);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tLOG_TARGET_DEBUG(target, \"start\");\n\n\t/* Save (windowed) A3 so cache matches physical AR3; A3 usable as scratch */\n\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a3_buf);\n\tif (xtensa->core_config->core_type == XT_NX) {\n\t\t/* Save (windowed) A0 as well--it will be required for reading PC */\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A0));\n\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, a0_buf);\n\n\t\t/* Set MS.DispSt, clear MS.DE prior to accessing ARs.  This ensures ARs remain\n\t\t * in correct order even for reversed register groups (overflow/underflow).\n\t\t */\n\t\tms_idx = xtensa->nx_reg_idx[XT_NX_REG_IDX_MS];\n\t\tuint32_t ms_regno = xtensa->optregs[ms_idx - XT_NUM_REGS].reg_num;\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, ms_regno, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, ms_buf);\n\t\tLOG_TARGET_DEBUG(target, \"Overriding MS (0x%x): 0x%x\", ms_regno, XT_MS_DISPST_DBG);\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, XT_MS_DISPST_DBG);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, ms_regno, XT_REG_A3));\n\t}\n\n\tint res = xtensa_window_state_save(target, &woe);\n\tif (res != ERROR_OK)\n\t\tgoto xtensa_fetch_all_regs_done;\n\n\t/* Assume the CPU has just halted. We now want to fill the register cache with all the\n\t * register contents GDB needs. For speed, we pipeline all the read operations, execute them\n\t * in one go, then sort everything out from the regvals variable. */\n\n\t/* Start out with AREGS; we can reach those immediately. Grab them per 16 registers. */\n\tfor (unsigned int j = 0; j < XT_AREGS_NUM_MAX; j += 16) {\n\t\t/*Grab the 16 registers we can see */\n\t\tfor (unsigned int i = 0; i < 16; i++) {\n\t\t\tif (i + j < xtensa->core_config->aregs_num) {\n\t\t\t\txtensa_queue_exec_ins(xtensa,\n\t\t\t\t\tXT_INS_WSR(xtensa, XT_SR_DDR, xtensa_regs[XT_REG_IDX_AR0 + i].reg_num));\n\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,\n\t\t\t\t\tregvals[XT_REG_IDX_AR0 + i + j].buf);\n\t\t\t\tif (debug_dsrs)\n\t\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR,\n\t\t\t\t\t\tdsrs[XT_REG_IDX_AR0 + i + j].buf);\n\t\t\t}\n\t\t}\n\t\tif (xtensa->core_config->windowed) {\n\t\t\t/* Now rotate the window so we'll see the next 16 registers. The final rotate\n\t\t\t * will wraparound, leaving us in the state we were.\n\t\t\t * Each ROTW rotates 4 registers on LX and 8 on NX */\n\t\t\tint rotw_arg = (xtensa->core_config->core_type == XT_LX) ? 4 : 2;\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_ROTW(xtensa, rotw_arg));\n\t\t}\n\t}\n\txtensa_window_state_restore(target, woe);\n\n\tif (xtensa->core_config->coproc) {\n\t\t/* As the very first thing after AREGS, go grab CPENABLE */\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[XT_REG_IDX_CPENABLE].buf);\n\t}\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read ARs (%d)!\", res);\n\t\tgoto xtensa_fetch_all_regs_done;\n\t}\n\txtensa_core_status_check(target);\n\n\ta3 = buf_get_u32(a3_buf, 0, 32);\n\tif (xtensa->core_config->core_type == XT_NX) {\n\t\ta0 = buf_get_u32(a0_buf, 0, 32);\n\t\tms = buf_get_u32(ms_buf, 0, 32);\n\t}\n\n\tif (xtensa->core_config->coproc) {\n\t\tcpenable = buf_get_u32(regvals[XT_REG_IDX_CPENABLE].buf, 0, 32);\n\n\t\t/* Enable all coprocessors (by setting all bits in CPENABLE) so we can read FP and user registers. */\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, xtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));\n\n\t\t/* Save CPENABLE; flag dirty later (when regcache updated) so original value is always restored */\n\t\tLOG_TARGET_DEBUG(target, \"CPENABLE: was 0x%\" PRIx32 \", all enabled\", cpenable);\n\t\txtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);\n\t}\n\t/* We're now free to use any of A0-A15 as scratch registers\n\t * Grab the SFRs and user registers first. We use A3 as a scratch register. */\n\tfor (unsigned int i = 0; i < reg_list_size; i++) {\n\t\tstruct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;\n\t\tunsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;\n\t\tif (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {\n\t\t\tbool reg_fetched = true;\n\t\t\tunsigned int reg_num = rlist[ridx].reg_num;\n\t\t\tswitch (rlist[ridx].type) {\n\t\t\tcase XT_REG_USER:\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RUR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\tbreak;\n\t\t\tcase XT_REG_FR:\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RFR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\tbreak;\n\t\t\tcase XT_REG_SPECIAL:\n\t\t\t\tif (reg_num == XT_PC_REG_NUM_VIRTUAL) {\n\t\t\t\t\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t\t\t\t\t/* reg number of PC for debug interrupt depends on NDEBUGLEVEL */\n\t\t\t\t\t\treg_num = XT_EPC_REG_NUM_BASE + xtensa->core_config->debug.irq_level;\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* NX PC read through CALL0(0) and reading A0 */\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_CALL0(xtensa, 0));\n\t\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A0));\n\t\t\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);\n\t\t\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf);\n\t\t\t\t\t\treg_fetched = false;\n\t\t\t\t\t}\n\t\t\t\t} else if ((xtensa->core_config->core_type == XT_LX)\n\t\t\t\t\t&& (reg_num == xtensa_regs[XT_REG_IDX_PS].reg_num)) {\n\t\t\t\t\t/* reg number of PS for debug interrupt depends on NDEBUGLEVEL */\n\t\t\t\t\treg_num = XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level;\n\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t} else if (reg_num == xtensa_regs[XT_REG_IDX_CPENABLE].reg_num) {\n\t\t\t\t\t/* CPENABLE already read/updated; don't re-read */\n\t\t\t\t\treg_fetched = false;\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, reg_num, XT_REG_A3));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treg_fetched = false;\n\t\t\t}\n\t\t\tif (reg_fetched) {\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, regvals[i].buf);\n\t\t\t\tif (debug_dsrs)\n\t\t\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DSR, dsrs[i].buf);\n\t\t\t}\n\t\t}\n\t}\n\t/* Ok, send the whole mess to the CPU. */\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to fetch AR regs!\");\n\t\tgoto xtensa_fetch_all_regs_done;\n\t}\n\txtensa_core_status_check(target);\n\n\tif (debug_dsrs) {\n\t\t/* DSR checking: follows order in which registers are requested. */\n\t\tfor (unsigned int i = 0; i < reg_list_size; i++) {\n\t\t\tstruct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;\n\t\t\tunsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;\n\t\t\tif (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist &&\n\t\t\t\t(rlist[ridx].type != XT_REG_DEBUG) &&\n\t\t\t\t(rlist[ridx].type != XT_REG_RELGEN) &&\n\t\t\t\t(rlist[ridx].type != XT_REG_TIE) &&\n\t\t\t\t(rlist[ridx].type != XT_REG_OTHER)) {\n\t\t\t\tif (buf_get_u32(dsrs[i].buf, 0, 32) & OCDDSR_EXECEXCEPTION) {\n\t\t\t\t\tLOG_ERROR(\"Exception reading %s!\", reg_list[i].name);\n\t\t\t\t\tres = ERROR_FAIL;\n\t\t\t\t\tgoto xtensa_fetch_all_regs_done;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (xtensa->core_config->windowed) {\n\t\t/* We need the windowbase to decode the general addresses. */\n\t\tuint32_t wb_idx = (xtensa->core_config->core_type == XT_LX) ?\n\t\t\tXT_REG_IDX_WINDOWBASE : xtensa->nx_reg_idx[XT_NX_REG_IDX_WB];\n\t\twindowbase = buf_get_u32(regvals[wb_idx].buf, 0, 32);\n\t\tif (xtensa->core_config->core_type == XT_NX)\n\t\t\twindowbase = (windowbase & XT_WB_P_MSK) >> XT_WB_P_SHIFT;\n\t}\n\n\t/* Decode the result and update the cache. */\n\tfor (unsigned int i = 0; i < reg_list_size; i++) {\n\t\tstruct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;\n\t\tunsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;\n\t\tif (xtensa_reg_is_readable(rlist[ridx].flags, cpenable) && rlist[ridx].exist) {\n\t\t\tif ((xtensa->core_config->windowed) && (rlist[ridx].type == XT_REG_GENERAL)) {\n\t\t\t\t/* The 64-value general register set is read from (windowbase) on down.\n\t\t\t\t * We need to get the real register address by subtracting windowbase and\n\t\t\t\t * wrapping around. */\n\t\t\t\tenum xtensa_reg_id realadr = xtensa_canonical_to_windowbase_offset(xtensa, i,\n\t\t\t\t\twindowbase);\n\t\t\t\tbuf_cpy(regvals[realadr].buf, reg_list[i].value, reg_list[i].size);\n\t\t\t} else if (rlist[ridx].type == XT_REG_RELGEN) {\n\t\t\t\tbuf_cpy(regvals[rlist[ridx].reg_num].buf, reg_list[i].value, reg_list[i].size);\n\t\t\t\tif (xtensa_extra_debug_log) {\n\t\t\t\t\txtensa_reg_val_t regval = buf_get_u32(regvals[rlist[ridx].reg_num].buf, 0, 32);\n\t\t\t\t\tLOG_DEBUG(\"%s = 0x%x\", rlist[ridx].name, regval);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\txtensa_reg_val_t regval = buf_get_u32(regvals[i].buf, 0, 32);\n\t\t\t\tbool is_dirty = (i == XT_REG_IDX_CPENABLE);\n\t\t\t\tif (xtensa_extra_debug_log)\n\t\t\t\t\tLOG_INFO(\"Register %s: 0x%X\", reg_list[i].name, regval);\n\t\t\t\tif (rlist[ridx].reg_num == XT_PC_REG_NUM_VIRTUAL &&\n\t\t\t\t\txtensa->core_config->core_type == XT_NX) {\n\t\t\t\t\t/* A0 from prior CALL0 points to next instruction; decrement it */\n\t\t\t\t\tregval -= 3;\n\t\t\t\t\tis_dirty = 1;\n\t\t\t\t} else if (i == ms_idx) {\n\t\t\t\t\tLOG_TARGET_DEBUG(target, \"Caching MS: 0x%x\", ms);\n\t\t\t\t\tregval = ms;\n\t\t\t\t\tis_dirty = 1;\n\t\t\t\t}\n\t\t\t\txtensa_reg_set(target, i, regval);\n\t\t\t\treg_list[i].dirty = is_dirty;\t/*always do this _after_ xtensa_reg_set! */\n\t\t\t}\n\t\t\treg_list[i].valid = true;\n\t\t} else {\n\t\t\tif ((rlist[ridx].flags & XT_REGF_MASK) == XT_REGF_NOREAD) {\n\t\t\t\t/* Report read-only registers all-zero but valid */\n\t\t\t\treg_list[i].valid = true;\n\t\t\t\txtensa_reg_set(target, i, 0);\n\t\t\t} else {\n\t\t\t\treg_list[i].valid = false;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (xtensa->core_config->windowed) {\n\t\t/* We have used A3 as a scratch register.\n\t\t * Windowed configs: restore A3's AR (XT_REG_GENERAL) and and flag for write-back.\n\t\t */\n\t\tenum xtensa_reg_id ar3_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A3, windowbase);\n\t\txtensa_reg_set(target, ar3_idx, a3);\n\t\txtensa_mark_register_dirty(xtensa, ar3_idx);\n\n\t\t/* Reset scratch_ars[] on fetch.  .chrval tracks AR mapping and changes w/ window */\n\t\tsprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR3].chrval, \"ar%d\", ar3_idx - XT_REG_IDX_AR0);\n\t\tenum xtensa_reg_id ar4_idx = xtensa_windowbase_offset_to_canonical(xtensa, XT_REG_IDX_A4, windowbase);\n\t\tsprintf(xtensa->scratch_ars[XT_AR_SCRATCH_AR4].chrval, \"ar%d\", ar4_idx - XT_REG_IDX_AR0);\n\t\tfor (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)\n\t\t\txtensa->scratch_ars[s].intval = false;\n\t}\n\n\t/* We have used A3 (XT_REG_RELGEN) as a scratch register.  Restore and flag for write-back. */\n\txtensa_reg_set(target, XT_REG_IDX_A3, a3);\n\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);\n\tif (xtensa->core_config->core_type == XT_NX) {\n\t\txtensa_reg_set(target, XT_REG_IDX_A0, a0);\n\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A0);\n\t}\n\n\txtensa->regs_fetched = true;\nxtensa_fetch_all_regs_done:\n\tfree(regvals);\n\tfree(dsrs);\n\treturn res;\n}\n\nint xtensa_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[],\n\tint *reg_list_size,\n\tenum target_register_class reg_class)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int num_regs;\n\n\tif (reg_class == REG_CLASS_GENERAL) {\n\t\tif ((xtensa->genpkt_regs_num == 0) || !xtensa->contiguous_regs_list) {\n\t\t\tLOG_ERROR(\"reg_class %d unhandled; 'xtgregs' not found\", reg_class);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\tnum_regs = xtensa->genpkt_regs_num;\n\t} else {\n\t\t/* Determine whether to return a contiguous or sparse register map */\n\t\tnum_regs = xtensa->regmap_contiguous ? xtensa->total_regs_num : xtensa->dbregs_num;\n\t}\n\n\tLOG_DEBUG(\"reg_class=%i, num_regs=%d\", (int)reg_class, num_regs);\n\n\t*reg_list = calloc(num_regs, sizeof(struct reg *));\n\tif (!*reg_list)\n\t\treturn ERROR_FAIL;\n\n\t*reg_list_size = num_regs;\n\tif (xtensa->regmap_contiguous) {\n\t\tassert((num_regs <= xtensa->total_regs_num) && \"contiguous regmap size internal error!\");\n\t\tfor (unsigned int i = 0; i < num_regs; i++)\n\t\t\t(*reg_list)[i] = xtensa->contiguous_regs_list[i];\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (unsigned int i = 0; i < num_regs; i++)\n\t\t(*reg_list)[i] = (struct reg *)&xtensa->empty_regs[i];\n\tunsigned int k = 0;\n\tfor (unsigned int i = 0; i < xtensa->core_cache->num_regs && k < num_regs; i++) {\n\t\tif (xtensa->core_cache->reg_list[i].exist) {\n\t\t\tstruct xtensa_reg_desc *rlist = (i < XT_NUM_REGS) ? xtensa_regs : xtensa->optregs;\n\t\t\tunsigned int ridx = (i < XT_NUM_REGS) ? i : i - XT_NUM_REGS;\n\t\t\tint sparse_idx = rlist[ridx].dbreg_num;\n\t\t\tif (i == XT_REG_IDX_PS && xtensa->core_config->core_type == XT_LX) {\n\t\t\t\tif (xtensa->eps_dbglevel_idx == 0) {\n\t\t\t\t\tLOG_ERROR(\"eps_dbglevel_idx not set\\n\");\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\t(*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx];\n\t\t\t\tif (xtensa_extra_debug_log)\n\t\t\t\t\tLOG_DEBUG(\"SPARSE GDB reg 0x%x getting EPS%d 0x%x\",\n\t\t\t\t\t\tsparse_idx, xtensa->core_config->debug.irq_level,\n\t\t\t\t\t\txtensa_reg_get_value((*reg_list)[sparse_idx]));\n\t\t\t} else if (rlist[ridx].type == XT_REG_RELGEN) {\n\t\t\t\t(*reg_list)[sparse_idx - XT_REG_IDX_ARFIRST] = &xtensa->core_cache->reg_list[i];\n\t\t\t} else {\n\t\t\t\t(*reg_list)[sparse_idx] = &xtensa->core_cache->reg_list[i];\n\t\t\t}\n\t\t\tif (i == XT_REG_IDX_PC)\n\t\t\t\t/* Make a duplicate copy of PC for external access */\n\t\t\t\t(*reg_list)[XT_PC_DBREG_NUM_BASE] = &xtensa->core_cache->reg_list[i];\n\t\t\tk++;\n\t\t}\n\t}\n\n\tif (k == num_regs)\n\t\tLOG_ERROR(\"SPARSE GDB reg list full (size %d)\", k);\n\n\treturn ERROR_OK;\n}\n\nint xtensa_mmu_is_enabled(struct target *target, int *enabled)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\t*enabled = xtensa->core_config->mmu.itlb_entries_count > 0 ||\n\t\txtensa->core_config->mmu.dtlb_entries_count > 0;\n\treturn ERROR_OK;\n}\n\nint xtensa_halt(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_TARGET_DEBUG(target, \"start\");\n\tif (target->state == TARGET_HALTED) {\n\t\tLOG_TARGET_DEBUG(target, \"target was already halted\");\n\t\treturn ERROR_OK;\n\t}\n\t/* First we have to read dsr and check if the target stopped */\n\tint res = xtensa_dm_core_status_read(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to read core status!\");\n\t\treturn res;\n\t}\n\tLOG_TARGET_DEBUG(target, \"Core status 0x%\" PRIx32, xtensa_dm_core_status_get(&xtensa->dbg_mod));\n\tif (!xtensa_is_stopped(target)) {\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_ENABLEOCD | OCDDCR_DEBUGINTERRUPT);\n\t\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\t\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\tif (res != ERROR_OK)\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to set OCDDCR_DEBUGINTERRUPT. Can't halt.\");\n\t}\n\n\treturn res;\n}\n\nint xtensa_prepare_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint32_t bpena = 0;\n\n\tLOG_TARGET_DEBUG(target,\n\t\t\"current=%d address=\" TARGET_ADDR_FMT \", handle_breakpoints=%i, debug_execution=%i)\",\n\t\tcurrent,\n\t\taddress,\n\t\thandle_breakpoints,\n\t\tdebug_execution);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\txtensa->halt_request = false;\n\n\tif (address && !current) {\n\t\txtensa_reg_set(target, XT_REG_IDX_PC, address);\n\t} else {\n\t\tuint32_t cause = xtensa_cause_get(target);\n\t\tLOG_TARGET_DEBUG(target, \"DEBUGCAUSE 0x%x (watchpoint %lu) (break %lu)\",\n\t\t\tcause, (cause & DEBUGCAUSE_DB), (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)));\n\t\tif (cause & DEBUGCAUSE_DB)\n\t\t\t/* We stopped due to a watchpoint. We can't just resume executing the\n\t\t\t * instruction again because */\n\t\t\t/* that would trigger the watchpoint again. To fix this, we single-step,\n\t\t\t * which ignores watchpoints. */\n\t\t\txtensa_do_step(target, current, address, handle_breakpoints);\n\t\tif (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))\n\t\t\t/* We stopped due to a break instruction. We can't just resume executing the\n\t\t\t * instruction again because */\n\t\t\t/* that would trigger the break again. To fix this, we single-step, which\n\t\t\t * ignores break. */\n\t\t\txtensa_do_step(target, current, address, handle_breakpoints);\n\t}\n\n\t/* Write back hw breakpoints. Current FreeRTOS SMP code can set a hw breakpoint on an\n\t * exception; we need to clear that and return to the breakpoints gdb has set on resume. */\n\tfor (unsigned int slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {\n\t\tif (xtensa->hw_brps[slot]) {\n\t\t\t/* Write IBREAKA[slot] and set bit #slot in IBREAKENABLE */\n\t\t\txtensa_reg_set(target, XT_REG_IDX_IBREAKA0 + slot, xtensa->hw_brps[slot]->address);\n\t\t\tif (xtensa->core_config->core_type == XT_NX)\n\t\t\t\txtensa_reg_set(target, xtensa->nx_reg_idx[XT_NX_REG_IDX_IBREAKC0] + slot, XT_IBREAKC_FB);\n\t\t\tbpena |= BIT(slot);\n\t\t}\n\t}\n\tif (xtensa->core_config->core_type == XT_LX)\n\t\txtensa_reg_set(target, XT_REG_IDX_IBREAKENABLE, bpena);\n\n\t/* Here we write all registers to the targets */\n\tint res = xtensa_write_dirty_registers(target);\n\tif (res != ERROR_OK)\n\t\tLOG_TARGET_ERROR(target, \"Failed to write back register cache.\");\n\treturn res;\n}\n\nint xtensa_do_resume(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_TARGET_DEBUG(target, \"start\");\n\n\txtensa_cause_reset(target);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RFDO(xtensa));\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to exec RFDO %d!\", res);\n\t\treturn res;\n\t}\n\txtensa_core_status_check(target);\n\treturn ERROR_OK;\n}\n\nint xtensa_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution)\n{\n\tLOG_TARGET_DEBUG(target, \"start\");\n\tint res = xtensa_prepare_resume(target, current, address, handle_breakpoints, debug_execution);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to prepare for resume!\");\n\t\treturn res;\n\t}\n\tres = xtensa_do_resume(target);\n\tif (res != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to resume!\");\n\t\treturn res;\n\t}\n\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\tif (!debug_execution)\n\t\ttarget->state = TARGET_RUNNING;\n\telse\n\t\ttarget->state = TARGET_DEBUG_RUNNING;\n\n\ttarget_call_event_callbacks(target, TARGET_EVENT_RESUMED);\n\n\treturn ERROR_OK;\n}\n\nstatic bool xtensa_pc_in_winexc(struct target *target, target_addr_t pc)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tuint8_t insn_buf[XT_ISNS_SZ_MAX];\n\tint err = xtensa_read_buffer(target, pc, sizeof(insn_buf), insn_buf);\n\tif (err != ERROR_OK)\n\t\treturn false;\n\n\txtensa_insn_t insn = buf_get_u32(insn_buf, 0, 24);\n\txtensa_insn_t masked = insn & XT_INS_L32E_S32E_MASK(xtensa);\n\tif (masked == XT_INS_L32E(xtensa, 0, 0, 0) || masked == XT_INS_S32E(xtensa, 0, 0, 0))\n\t\treturn true;\n\n\tmasked = insn & XT_INS_RFWO_RFWU_MASK(xtensa);\n\tif (masked == XT_INS_RFWO(xtensa) || masked == XT_INS_RFWU(xtensa))\n\t\treturn true;\n\n\treturn false;\n}\n\nint xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint res;\n\tconst uint32_t icount_val = -2;\t/* ICOUNT value to load for 1 step */\n\txtensa_reg_val_t dbreakc[XT_WATCHPOINTS_NUM_MAX];\n\txtensa_reg_val_t icountlvl, cause;\n\txtensa_reg_val_t oldps, oldpc, cur_pc;\n\tbool ps_lowered = false;\n\n\tLOG_TARGET_DEBUG(target, \"current=%d, address=\" TARGET_ADDR_FMT \", handle_breakpoints=%i\",\n\t\tcurrent, address, handle_breakpoints);\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (xtensa->eps_dbglevel_idx == 0 && xtensa->core_config->core_type == XT_LX) {\n\t\tLOG_TARGET_ERROR(target, \"eps_dbglevel_idx not set\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Save old ps (EPS[dbglvl] on LX), pc */\n\toldps = xtensa_reg_get(target, (xtensa->core_config->core_type == XT_LX) ?\n\t\txtensa->eps_dbglevel_idx : XT_REG_IDX_PS);\n\toldpc = xtensa_reg_get(target, XT_REG_IDX_PC);\n\n\tcause = xtensa_cause_get(target);\n\tLOG_TARGET_DEBUG(target, \"oldps=%\" PRIx32 \", oldpc=%\" PRIx32 \" dbg_cause=%\" PRIx32 \" exc_cause=%\" PRIx32,\n\t\toldps,\n\t\toldpc,\n\t\tcause,\n\t\txtensa_reg_get(target, XT_REG_IDX_EXCCAUSE));\n\tif (handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN))) {\n\t\t/* handle hard-coded SW breakpoints (e.g. syscalls) */\n\t\tLOG_TARGET_DEBUG(target, \"Increment PC to pass break instruction...\");\n\t\txtensa_cause_clear(target);\t/* so we don't recurse into the same routine */\n\t\t/* pretend that we have stepped */\n\t\tif (cause & DEBUGCAUSE_BI)\n\t\t\txtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 3);\t/* PC = PC+3 */\n\t\telse\n\t\t\txtensa_reg_set(target, XT_REG_IDX_PC, oldpc + 2);\t/* PC = PC+2 */\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Xtensa LX has an ICOUNTLEVEL register which sets the maximum interrupt level\n\t * at which the instructions are to be counted while stepping.\n\t *\n\t * For example, if we need to step by 2 instructions, and an interrupt occurs\n\t * in between, the processor will trigger the interrupt and halt after the 2nd\n\t * instruction within the interrupt vector and/or handler.\n\t *\n\t * However, sometimes we don't want the interrupt handlers to be executed at all\n\t * while stepping through the code. In this case (XT_STEPPING_ISR_OFF),\n\t * ICOUNTLEVEL can be lowered to the executing code's (level + 1) to prevent ISR\n\t * code from being counted during stepping.  Note that C exception handlers must\n\t * run at level 0 and hence will be counted and stepped into, should one occur.\n\t *\n\t * TODO: Certain instructions should never be single-stepped and should instead\n\t * be emulated (per DUG): RSIL >= DBGLEVEL, RSR/WSR [ICOUNT|ICOUNTLEVEL], and\n\t * RFI >= DBGLEVEL.\n\t */\n\tif (xtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF) {\n\t\tif (!xtensa->core_config->high_irq.enabled) {\n\t\t\tLOG_TARGET_WARNING(\n\t\t\t\ttarget,\n\t\t\t\t\"disabling IRQs while stepping is not implemented w/o high prio IRQs option!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\t/* Update ICOUNTLEVEL accordingly */\n\t\ticountlvl = MIN((oldps & 0xF) + 1, xtensa->core_config->debug.irq_level);\n\t} else {\n\t\ticountlvl = xtensa->core_config->debug.irq_level;\n\t}\n\n\tif (cause & DEBUGCAUSE_DB) {\n\t\t/* We stopped due to a watchpoint. We can't just resume executing the instruction again because\n\t\t * that would trigger the watchpoint again. To fix this, we remove watchpoints,single-step and\n\t\t * re-enable the watchpoint. */\n\t\tLOG_TARGET_DEBUG(\n\t\t\ttarget,\n\t\t\t\"Single-stepping to get past instruction that triggered the watchpoint...\");\n\t\txtensa_cause_clear(target);\t/* so we don't recurse into the same routine */\n\t\t/* Save all DBREAKCx registers and set to 0 to disable watchpoints */\n\t\tfor (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {\n\t\t\tdbreakc[slot] = xtensa_reg_get(target, XT_REG_IDX_DBREAKC0 + slot);\n\t\t\txtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0);\n\t\t}\n\t}\n\n\tif (!handle_breakpoints && (cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)))\n\t\t/* handle normal SW breakpoint */\n\t\txtensa_cause_clear(target);\t/* so we don't recurse into the same routine */\n\tif (xtensa->core_config->core_type == XT_LX && ((oldps & 0xf) >= icountlvl)) {\n\t\t/* Lower interrupt level to allow stepping, but flag eps[dbglvl] to be restored */\n\t\tps_lowered = true;\n\t\tuint32_t newps = (oldps & ~0xf) | (icountlvl - 1);\n\t\txtensa_reg_set(target, xtensa->eps_dbglevel_idx, newps);\n\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\"Lowering PS.INTLEVEL to allow stepping: %s <- 0x%08\" PRIx32 \" (was 0x%08\" PRIx32 \")\",\n\t\t\txtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,\n\t\t\tnewps,\n\t\t\toldps);\n\t}\n\tdo {\n\t\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t\txtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, icountlvl);\n\t\t\txtensa_reg_set(target, XT_REG_IDX_ICOUNT, icount_val);\n\t\t} else {\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRSET, OCDDCR_STEPREQUEST);\n\t\t}\n\n\t\t/* Now that ICOUNT (LX) or DCR.StepRequest (NX) is set,\n\t\t * we can resume as if we were going to run\n\t\t */\n\t\tres = xtensa_prepare_resume(target, current, address, 0, 0);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to prepare resume for single step\");\n\t\t\treturn res;\n\t\t}\n\t\tres = xtensa_do_resume(target);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to resume after setting up single step\");\n\t\t\treturn res;\n\t\t}\n\n\t\t/* Wait for stepping to complete */\n\t\tlong long start = timeval_ms();\n\t\twhile (timeval_ms() < start + 500) {\n\t\t\t/* Do not use target_poll here, it also triggers other things... just manually read the DSR\n\t\t\t *until stepping is complete. */\n\t\t\tusleep(1000);\n\t\t\tres = xtensa_dm_core_status_read(&xtensa->dbg_mod);\n\t\t\tif (res != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"Failed to read core status!\");\n\t\t\t\treturn res;\n\t\t\t}\n\t\t\tif (xtensa_is_stopped(target))\n\t\t\t\tbreak;\n\t\t\tusleep(1000);\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"Finish stepping. dsr=0x%08\" PRIx32,\n\t\t\txtensa_dm_core_status_get(&xtensa->dbg_mod));\n\t\tif (!xtensa_is_stopped(target)) {\n\t\t\tLOG_TARGET_WARNING(\n\t\t\t\ttarget,\n\t\t\t\t\"Timed out waiting for target to finish stepping. dsr=0x%08\" PRIx32,\n\t\t\t\txtensa_dm_core_status_get(&xtensa->dbg_mod));\n\t\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\n\t\txtensa_fetch_all_regs(target);\n\t\tcur_pc = xtensa_reg_get(target, XT_REG_IDX_PC);\n\n\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\"cur_ps=%\" PRIx32 \", cur_pc=%\" PRIx32 \" dbg_cause=%\" PRIx32 \" exc_cause=%\" PRIx32,\n\t\t\txtensa_reg_get(target, XT_REG_IDX_PS),\n\t\t\tcur_pc,\n\t\t\txtensa_cause_get(target),\n\t\t\txtensa_reg_get(target, XT_REG_IDX_EXCCAUSE));\n\n\t\t/* Do not step into WindowOverflow if ISRs are masked.\n\t\t   If we stop in WindowOverflow at breakpoint with masked ISRs and\n\t\t   try to do a step it will get us out of that handler */\n\t\tif (xtensa->core_config->windowed &&\n\t\t\txtensa->stepping_isr_mode == XT_STEPPING_ISR_OFF &&\n\t\t\txtensa_pc_in_winexc(target, cur_pc)) {\n\t\t\t/* isrmask = on, need to step out of the window exception handler */\n\t\t\tLOG_DEBUG(\"Stepping out of window exception, PC=%\" PRIX32, cur_pc);\n\t\t\toldpc = cur_pc;\n\t\t\taddress = oldpc + 3;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (oldpc == cur_pc)\n\t\t\tLOG_TARGET_WARNING(target, \"Stepping doesn't seem to change PC! dsr=0x%08\" PRIx32,\n\t\t\t\txtensa_dm_core_status_get(&xtensa->dbg_mod));\n\t\telse\n\t\t\tLOG_DEBUG(\"Stepped from %\" PRIX32 \" to %\" PRIX32, oldpc, cur_pc);\n\t\tbreak;\n\t} while (true);\n\n\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\ttarget->state = TARGET_HALTED;\n\tLOG_DEBUG(\"Done stepping, PC=%\" PRIX32, cur_pc);\n\n\tif (cause & DEBUGCAUSE_DB) {\n\t\tLOG_TARGET_DEBUG(target, \"...Done, re-installing watchpoints.\");\n\t\t/* Restore the DBREAKCx registers */\n\t\tfor (unsigned int slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++)\n\t\t\txtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, dbreakc[slot]);\n\t}\n\n\t/* Restore int level */\n\tif (ps_lowered) {\n\t\tLOG_DEBUG(\"Restoring %s after stepping: 0x%08\" PRIx32,\n\t\t\txtensa->core_cache->reg_list[xtensa->eps_dbglevel_idx].name,\n\t\t\toldps);\n\t\txtensa_reg_set(target, xtensa->eps_dbglevel_idx, oldps);\n\t}\n\n\t/* write ICOUNTLEVEL back to zero */\n\txtensa_reg_set(target, XT_REG_IDX_ICOUNTLEVEL, 0);\n\t/* TODO: can we skip writing dirty registers and re-fetching them? */\n\tres = xtensa_write_dirty_registers(target);\n\txtensa_fetch_all_regs(target);\n\treturn res;\n}\n\nint xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints)\n{\n\tint retval = xtensa_do_step(target, current, address, handle_breakpoints);\n\tif (retval != ERROR_OK)\n\t\treturn retval;\n\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Returns true if two ranges are overlapping\n */\nstatic inline bool xtensa_memory_regions_overlap(target_addr_t r1_start,\n\ttarget_addr_t r1_end,\n\ttarget_addr_t r2_start,\n\ttarget_addr_t r2_end)\n{\n\tif ((r2_start >= r1_start) && (r2_start < r1_end))\n\t\treturn true;\t/* r2_start is in r1 region */\n\tif ((r2_end > r1_start) && (r2_end <= r1_end))\n\t\treturn true;\t/* r2_end is in r1 region */\n\treturn false;\n}\n\n/**\n * Returns a size of overlapped region of two ranges.\n */\nstatic inline target_addr_t xtensa_get_overlap_size(target_addr_t r1_start,\n\ttarget_addr_t r1_end,\n\ttarget_addr_t r2_start,\n\ttarget_addr_t r2_end)\n{\n\tif (xtensa_memory_regions_overlap(r1_start, r1_end, r2_start, r2_end)) {\n\t\ttarget_addr_t ov_start = r1_start < r2_start ? r2_start : r1_start;\n\t\ttarget_addr_t ov_end = r1_end > r2_end ? r2_end : r1_end;\n\t\treturn ov_end - ov_start;\n\t}\n\treturn 0;\n}\n\n/**\n * Check if the address gets to memory regions, and its access mode\n */\nstatic bool xtensa_memory_op_validate_range(struct xtensa *xtensa, target_addr_t address, size_t size, int access)\n{\n\ttarget_addr_t adr_pos = address;\t/* address cursor set to the beginning start */\n\ttarget_addr_t adr_end = address + size;\t/* region end */\n\ttarget_addr_t overlap_size;\n\tconst struct xtensa_local_mem_region_config *cm;\t/* current mem region */\n\n\twhile (adr_pos < adr_end) {\n\t\tcm = xtensa_target_memory_region_find(xtensa, adr_pos);\n\t\tif (!cm)\t/* address is not belong to anything */\n\t\t\treturn false;\n\t\tif ((cm->access & access) != access)\t/* access check */\n\t\t\treturn false;\n\t\toverlap_size = xtensa_get_overlap_size(cm->base, (cm->base + cm->size), adr_pos, adr_end);\n\t\tassert(overlap_size != 0);\n\t\tadr_pos += overlap_size;\n\t}\n\treturn true;\n}\n\nint xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\t/* We are going to read memory in 32-bit increments. This may not be what the calling\n\t * function expects, so we may need to allocate a temp buffer and read into that first. */\n\ttarget_addr_t addrstart_al = ALIGN_DOWN(address, 4);\n\ttarget_addr_t addrend_al = ALIGN_UP(address + size * count, 4);\n\ttarget_addr_t adr = addrstart_al;\n\tuint8_t *albuff;\n\tbool bswap = xtensa->target->endianness == TARGET_BIG_ENDIAN;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!xtensa->permissive_mode) {\n\t\tif (!xtensa_memory_op_validate_range(xtensa, address, (size * count),\n\t\t\t\tXT_MEM_ACCESS_READ)) {\n\t\t\tLOG_DEBUG(\"address \" TARGET_ADDR_FMT \" not readable\", address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tunsigned int alloc_bytes = ALIGN_UP(addrend_al - addrstart_al, sizeof(uint32_t));\n\talbuff = calloc(alloc_bytes, 1);\n\tif (!albuff) {\n\t\tLOG_TARGET_ERROR(target, \"Out of memory allocating %\" PRId64 \" bytes!\",\n\t\t\taddrend_al - addrstart_al);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* We're going to use A3 here */\n\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);\n\t/* Write start address to A3 */\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t/* Now we can safely read data from addrstart_al up to addrend_al into albuff */\n\tif (xtensa->probe_lsddr32p != 0) {\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));\n\t\tfor (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t))\n\t\t\txtensa_queue_dbg_reg_read(xtensa,\n\t\t\t\t(adr + sizeof(uint32_t) == addrend_al) ? XDMREG_DDR : XDMREG_DDREXEC,\n\t\t\t\t&albuff[i]);\n\t} else {\n\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);\n\t\tfor (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A4, 0));\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A4));\n\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[i]);\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t}\n\t}\n\tint res = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res == ERROR_OK) {\n\t\tbool prev_suppress = xtensa->suppress_dsr_errors;\n\t\txtensa->suppress_dsr_errors = true;\n\t\tres = xtensa_core_status_check(target);\n\t\tif (xtensa->probe_lsddr32p == -1)\n\t\t\txtensa->probe_lsddr32p = 1;\n\t\txtensa->suppress_dsr_errors = prev_suppress;\n\t}\n\tif (res != ERROR_OK) {\n\t\tif (xtensa->probe_lsddr32p != 0) {\n\t\t\t/* Disable fast memory access instructions and retry before reporting an error */\n\t\t\tLOG_TARGET_DEBUG(target, \"Disabling LDDR32.P/SDDR32.P\");\n\t\t\txtensa->probe_lsddr32p = 0;\n\t\t\tres = xtensa_read_memory(target, address, size, count, albuff);\n\t\t\tbswap = false;\n\t\t} else {\n\t\t\tLOG_TARGET_WARNING(target, \"Failed reading %d bytes at address \"TARGET_ADDR_FMT,\n\t\t\t\tcount * size, address);\n\t\t}\n\t}\n\n\tif (bswap)\n\t\tbuf_bswap32(albuff, albuff, addrend_al - addrstart_al);\n\tmemcpy(buffer, albuff + (address & 3), (size * count));\n\tfree(albuff);\n\treturn res;\n}\n\nint xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)\n{\n\t/* xtensa_read_memory can also read unaligned stuff. Just pass through to that routine. */\n\treturn xtensa_read_memory(target, address, 1, count, buffer);\n}\n\nint xtensa_write_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer)\n{\n\t/* This memory write function can get thrown nigh everything into it, from\n\t * aligned uint32 writes to unaligned uint8ths. The Xtensa memory doesn't always\n\t * accept anything but aligned uint32 writes, though. That is why we convert\n\t * everything into that. */\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\ttarget_addr_t addrstart_al = ALIGN_DOWN(address, 4);\n\ttarget_addr_t addrend_al = ALIGN_UP(address + size * count, 4);\n\ttarget_addr_t adr = addrstart_al;\n\tint res;\n\tuint8_t *albuff;\n\tbool fill_head_tail = false;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (!xtensa->permissive_mode) {\n\t\tif (!xtensa_memory_op_validate_range(xtensa, address, (size * count), XT_MEM_ACCESS_WRITE)) {\n\t\t\tLOG_WARNING(\"address \" TARGET_ADDR_FMT \" not writable\", address);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (size == 0 || count == 0 || !buffer)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Allocate a temporary buffer to put the aligned bytes in, if needed. */\n\tif (addrstart_al == address && addrend_al == address + (size * count)) {\n\t\tif (xtensa->target->endianness == TARGET_BIG_ENDIAN)\n\t\t\t/* Need a buffer for byte-swapping */\n\t\t\talbuff = malloc(addrend_al - addrstart_al);\n\t\telse\n\t\t\t/* We discard the const here because albuff can also be non-const */\n\t\t\talbuff = (uint8_t *)buffer;\n\t} else {\n\t\tfill_head_tail = true;\n\t\talbuff = malloc(addrend_al - addrstart_al);\n\t}\n\tif (!albuff) {\n\t\tLOG_TARGET_ERROR(target, \"Out of memory allocating %\" PRId64 \" bytes!\",\n\t\t\taddrend_al - addrstart_al);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* We're going to use A3 here */\n\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);\n\n\t/* If we're using a temp aligned buffer, we need to fill the head and/or tail bit of it. */\n\tif (fill_head_tail) {\n\t\t/* See if we need to read the first and/or last word. */\n\t\tif (address & 3) {\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\tif (xtensa->probe_lsddr32p == 1) {\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));\n\t\t\t} else {\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t}\n\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR, &albuff[0]);\n\t\t}\n\t\tif ((address + (size * count)) & 3) {\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrend_al - 4);\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\tif (xtensa->probe_lsddr32p == 1) {\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_LDDR32P(xtensa, XT_REG_A3));\n\t\t\t} else {\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_L32I(xtensa, XT_REG_A3, XT_REG_A3, 0));\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t}\n\t\t\txtensa_queue_dbg_reg_read(xtensa, XDMREG_DDR,\n\t\t\t\t&albuff[addrend_al - addrstart_al - 4]);\n\t\t}\n\t\t/* Grab bytes */\n\t\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\tif (res != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error issuing unaligned memory write context instruction(s): %d\", res);\n\t\t\tif (albuff != buffer)\n\t\t\t\tfree(albuff);\n\t\t\treturn res;\n\t\t}\n\t\txtensa_core_status_check(target);\n\t\tif (xtensa->target->endianness == TARGET_BIG_ENDIAN) {\n\t\t\tbool swapped_w0 = false;\n\t\t\tif (address & 3) {\n\t\t\t\tbuf_bswap32(&albuff[0], &albuff[0], 4);\n\t\t\t\tswapped_w0 = true;\n\t\t\t}\n\t\t\tif ((address + (size * count)) & 3) {\n\t\t\t\tif ((addrend_al - addrstart_al - 4 == 0) && swapped_w0) {\n\t\t\t\t\t/* Don't double-swap if buffer start/end are within the same word */\n\t\t\t\t} else {\n\t\t\t\t\tbuf_bswap32(&albuff[addrend_al - addrstart_al - 4],\n\t\t\t\t\t\t&albuff[addrend_al - addrstart_al - 4], 4);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t/* Copy data to be written into the aligned buffer (in host-endianness) */\n\t\tmemcpy(&albuff[address & 3], buffer, size * count);\n\t\t/* Now we can write albuff in aligned uint32s. */\n\t}\n\n\tif (xtensa->target->endianness == TARGET_BIG_ENDIAN)\n\t\tbuf_bswap32(albuff, fill_head_tail ? albuff : buffer, addrend_al - addrstart_al);\n\n\t/* Write start address to A3 */\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, addrstart_al);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t/* Write the aligned buffer */\n\tif (xtensa->probe_lsddr32p != 0) {\n\t\tfor (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {\n\t\t\tif (i == 0) {\n\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_SDDR32P(xtensa, XT_REG_A3));\n\t\t\t} else {\n\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDREXEC, buf_get_u32(&albuff[i], 0, 32));\n\t\t\t}\n\t\t}\n\t} else {\n\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A4);\n\t\tfor (unsigned int i = 0; adr != addrend_al; i += sizeof(uint32_t), adr += sizeof(uint32_t)) {\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, buf_get_u32(&albuff[i], 0, 32));\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_S32I(xtensa, XT_REG_A3, XT_REG_A4, 0));\n\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr + sizeof(uint32_t));\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t}\n\t}\n\n\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (res == ERROR_OK) {\n\t\tbool prev_suppress = xtensa->suppress_dsr_errors;\n\t\txtensa->suppress_dsr_errors = true;\n\t\tres = xtensa_core_status_check(target);\n\t\tif (xtensa->probe_lsddr32p == -1)\n\t\t\txtensa->probe_lsddr32p = 1;\n\t\txtensa->suppress_dsr_errors = prev_suppress;\n\t}\n\tif (res != ERROR_OK) {\n\t\tif (xtensa->probe_lsddr32p != 0) {\n\t\t\t/* Disable fast memory access instructions and retry before reporting an error */\n\t\t\tLOG_TARGET_INFO(target, \"Disabling LDDR32.P/SDDR32.P\");\n\t\t\txtensa->probe_lsddr32p = 0;\n\t\t\tres = xtensa_write_memory(target, address, size, count, buffer);\n\t\t} else {\n\t\t\tLOG_TARGET_WARNING(target, \"Failed writing %d bytes at address \"TARGET_ADDR_FMT,\n\t\t\t\tcount * size, address);\n\t\t}\n\t} else {\n\t\t/* Invalidate ICACHE, writeback DCACHE if present */\n\t\tuint32_t issue_ihi = xtensa_is_icacheable(xtensa, address);\n\t\tuint32_t issue_dhwb = xtensa_is_dcacheable(xtensa, address);\n\t\tif (issue_ihi || issue_dhwb) {\n\t\t\tuint32_t ilinesize = issue_ihi ?  xtensa->core_config->icache.line_size : UINT32_MAX;\n\t\t\tuint32_t dlinesize = issue_dhwb ? xtensa->core_config->dcache.line_size : UINT32_MAX;\n\t\t\tuint32_t linesize = MIN(ilinesize, dlinesize);\n\t\t\tuint32_t off = 0;\n\t\t\tadr = addrstart_al;\n\n\t\t\twhile ((adr + off) < addrend_al) {\n\t\t\t\tif (off == 0) {\n\t\t\t\t\t/* Write start address to A3 */\n\t\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, adr);\n\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t\t}\n\t\t\t\tif (issue_ihi)\n\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, off));\n\t\t\t\tif (issue_dhwb)\n\t\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, off));\n\t\t\t\toff += linesize;\n\t\t\t\tif (off > 1020) {\n\t\t\t\t\t/* IHI, DHWB have 8-bit immediate operands (0..1020) */\n\t\t\t\t\tadr += off;\n\t\t\t\t\toff = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Execute cache WB/INV instructions */\n\t\t\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\t\txtensa_core_status_check(target);\n\t\t\tif (res != ERROR_OK)\n\t\t\t\tLOG_TARGET_ERROR(target,\n\t\t\t\t\t\"Error issuing cache writeback/invaldate instruction(s): %d\",\n\t\t\t\t\tres);\n\t\t}\n\t}\n\tif (albuff != buffer)\n\t\tfree(albuff);\n\n\treturn res;\n}\n\nint xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer)\n{\n\t/* xtensa_write_memory can handle everything. Just pass on to that. */\n\treturn xtensa_write_memory(target, address, 1, count, buffer);\n}\n\nint xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum)\n{\n\tLOG_WARNING(\"not implemented yet\");\n\treturn ERROR_FAIL;\n}\n\nint xtensa_poll(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tif (xtensa_dm_poll(&xtensa->dbg_mod) != ERROR_OK) {\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\treturn ERROR_TARGET_NOT_EXAMINED;\n\t}\n\n\tint res = xtensa_dm_power_status_read(&xtensa->dbg_mod, PWRSTAT_DEBUGWASRESET(xtensa) |\n\t\tPWRSTAT_COREWASRESET(xtensa));\n\tif (xtensa->dbg_mod.power_status.stat != xtensa->dbg_mod.power_status.stath)\n\t\tLOG_TARGET_DEBUG(target, \"PWRSTAT: read 0x%08\" PRIx32 \", clear 0x%08lx, reread 0x%08\" PRIx32,\n\t\t\txtensa->dbg_mod.power_status.stat,\n\t\t\tPWRSTAT_DEBUGWASRESET(xtensa) | PWRSTAT_COREWASRESET(xtensa),\n\t\t\txtensa->dbg_mod.power_status.stath);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (xtensa_dm_tap_was_reset(&xtensa->dbg_mod)) {\n\t\tLOG_TARGET_INFO(target, \"Debug controller was reset.\");\n\t\tres = xtensa_smpbreak_write(xtensa, xtensa->smp_break);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\tif (xtensa_dm_core_was_reset(&xtensa->dbg_mod))\n\t\tLOG_TARGET_INFO(target, \"Core was reset.\");\n\txtensa_dm_power_status_cache(&xtensa->dbg_mod);\n\t/* Enable JTAG, set reset if needed */\n\tres = xtensa_wakeup(target);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tuint32_t prev_dsr = xtensa->dbg_mod.core_status.dsr;\n\tres = xtensa_dm_core_status_read(&xtensa->dbg_mod);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (prev_dsr != xtensa->dbg_mod.core_status.dsr)\n\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\"DSR has changed: was 0x%08\" PRIx32 \" now 0x%08\" PRIx32,\n\t\t\tprev_dsr,\n\t\t\txtensa->dbg_mod.core_status.dsr);\n\tif (xtensa->dbg_mod.power_status.stath & PWRSTAT_COREWASRESET(xtensa)) {\n\t\t/* if RESET state is persitent  */\n\t\ttarget->state = TARGET_RESET;\n\t} else if (!xtensa_dm_is_powered(&xtensa->dbg_mod)) {\n\t\tLOG_TARGET_DEBUG(target, \"not powered 0x%\" PRIX32 \"%ld\",\n\t\t\txtensa->dbg_mod.core_status.dsr,\n\t\t\txtensa->dbg_mod.core_status.dsr & OCDDSR_STOPPED);\n\t\ttarget->state = TARGET_UNKNOWN;\n\t\tif (xtensa->come_online_probes_num == 0)\n\t\t\ttarget->examined = false;\n\t\telse\n\t\t\txtensa->come_online_probes_num--;\n\t} else if (xtensa_is_stopped(target)) {\n\t\tif (target->state != TARGET_HALTED) {\n\t\t\tenum target_state oldstate = target->state;\n\t\t\ttarget->state = TARGET_HALTED;\n\t\t\t/* Examine why the target has been halted */\n\t\t\ttarget->debug_reason = DBG_REASON_DBGRQ;\n\t\t\txtensa_fetch_all_regs(target);\n\t\t\t/* When setting debug reason DEBUGCAUSE events have the following\n\t\t\t * priorities: watchpoint == breakpoint > single step > debug interrupt. */\n\t\t\t/* Watchpoint and breakpoint events at the same time results in special\n\t\t\t * debug reason: DBG_REASON_WPTANDBKPT. */\n\t\t\tuint32_t halt_cause = xtensa_cause_get(target);\n\t\t\t/* TODO: Add handling of DBG_REASON_EXC_CATCH */\n\t\t\tif (halt_cause & DEBUGCAUSE_IC)\n\t\t\t\ttarget->debug_reason = DBG_REASON_SINGLESTEP;\n\t\t\tif (halt_cause & (DEBUGCAUSE_IB | DEBUGCAUSE_BN | DEBUGCAUSE_BI)) {\n\t\t\t\tif (halt_cause & DEBUGCAUSE_DB)\n\t\t\t\t\ttarget->debug_reason = DBG_REASON_WPTANDBKPT;\n\t\t\t\telse\n\t\t\t\t\ttarget->debug_reason = DBG_REASON_BREAKPOINT;\n\t\t\t} else if (halt_cause & DEBUGCAUSE_DB) {\n\t\t\t\ttarget->debug_reason = DBG_REASON_WATCHPOINT;\n\t\t\t}\n\t\t\tLOG_TARGET_DEBUG(target, \"Target halted, pc=0x%08\" PRIx32\n\t\t\t\t\", debug_reason=%08\" PRIx32 \", oldstate=%08\" PRIx32,\n\t\t\t\txtensa_reg_get(target, XT_REG_IDX_PC),\n\t\t\t\ttarget->debug_reason,\n\t\t\t\toldstate);\n\t\t\tLOG_TARGET_DEBUG(target, \"Halt reason=0x%08\" PRIX32 \", exc_cause=%\" PRId32 \", dsr=0x%08\" PRIx32,\n\t\t\t\thalt_cause,\n\t\t\t\txtensa_reg_get(target, XT_REG_IDX_EXCCAUSE),\n\t\t\t\txtensa->dbg_mod.core_status.dsr);\n\t\t\txtensa_dm_core_status_clear(\n\t\t\t\t&xtensa->dbg_mod,\n\t\t\t\tOCDDSR_DEBUGPENDBREAK | OCDDSR_DEBUGINTBREAK | OCDDSR_DEBUGPENDTRAX |\n\t\t\t\tOCDDSR_DEBUGINTTRAX |\n\t\t\t\tOCDDSR_DEBUGPENDHOST | OCDDSR_DEBUGINTHOST);\n\t\t\tif (xtensa->core_config->core_type == XT_NX) {\n\t\t\t\t/* Enable imprecise exceptions while in halted state */\n\t\t\t\txtensa_reg_val_t ps = xtensa_reg_get(target, XT_REG_IDX_PS);\n\t\t\t\txtensa_reg_val_t newps = ps & ~(XT_PS_DIEXC_MSK);\n\t\t\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_PS);\n\t\t\t\tLOG_TARGET_DEBUG(target, \"Enabling PS.DIEXC: 0x%08x -> 0x%08x\", ps, newps);\n\t\t\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, newps);\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa, XT_SR_PS, XT_REG_A3));\n\t\t\t\tres = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\t\t\tif (res != ERROR_OK) {\n\t\t\t\t\tLOG_TARGET_ERROR(target, \"Failed to write PS.DIEXC (%d)!\", res);\n\t\t\t\t\treturn res;\n\t\t\t\t}\n\t\t\t\txtensa_core_status_check(target);\n\t\t\t}\n\t\t}\n\t} else {\n\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t\tif (target->state != TARGET_RUNNING && target->state != TARGET_DEBUG_RUNNING) {\n\t\t\ttarget->state = TARGET_RUNNING;\n\t\t\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\t\t}\n\t}\n\tif (xtensa->trace_active) {\n\t\t/* Detect if tracing was active but has stopped. */\n\t\tstruct xtensa_trace_status trace_status;\n\t\tres = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);\n\t\tif (res == ERROR_OK) {\n\t\t\tif (!(trace_status.stat & TRAXSTAT_TRACT)) {\n\t\t\t\tLOG_INFO(\"Detected end of trace.\");\n\t\t\t\tif (trace_status.stat & TRAXSTAT_PCMTG)\n\t\t\t\t\tLOG_TARGET_INFO(target, \"Trace stop triggered by PC match\");\n\t\t\t\tif (trace_status.stat & TRAXSTAT_PTITG)\n\t\t\t\t\tLOG_TARGET_INFO(target, \"Trace stop triggered by Processor Trigger Input\");\n\t\t\t\tif (trace_status.stat & TRAXSTAT_CTITG)\n\t\t\t\t\tLOG_TARGET_INFO(target, \"Trace stop triggered by Cross-trigger Input\");\n\t\t\t\txtensa->trace_active = false;\n\t\t\t}\n\t\t}\n\t}\n\treturn ERROR_OK;\n}\n\nstatic int xtensa_update_instruction(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int issue_ihi = xtensa_is_icacheable(xtensa, address);\n\tunsigned int issue_dhwbi = xtensa_is_dcacheable(xtensa, address);\n\tuint32_t icache_line_size = issue_ihi ? xtensa->core_config->icache.line_size : UINT32_MAX;\n\tuint32_t dcache_line_size = issue_dhwbi ? xtensa->core_config->dcache.line_size : UINT32_MAX;\n\tunsigned int same_ic_line = ((address & (icache_line_size - 1)) + size) <= icache_line_size;\n\tunsigned int same_dc_line = ((address & (dcache_line_size - 1)) + size) <= dcache_line_size;\n\tint ret;\n\n\tif (size > icache_line_size)\n\t\treturn ERROR_FAIL;\n\n\tif (issue_ihi || issue_dhwbi) {\n\t\t/* We're going to use A3 here */\n\t\txtensa_mark_register_dirty(xtensa, XT_REG_IDX_A3);\n\n\t\t/* Write start address to A3 and invalidate */\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\tLOG_TARGET_DEBUG(target, \"DHWBI, IHI for address \"TARGET_ADDR_FMT, address);\n\t\tif (issue_dhwbi) {\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 0));\n\t\t\tif (!same_dc_line) {\n\t\t\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\t\t\"DHWBI second dcache line for address \"TARGET_ADDR_FMT,\n\t\t\t\t\taddress + 4);\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_DHWBI(xtensa, XT_REG_A3, 4));\n\t\t\t}\n\t\t}\n\t\tif (issue_ihi) {\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 0));\n\t\t\tif (!same_ic_line) {\n\t\t\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\t\t\"IHI second icache line for address \"TARGET_ADDR_FMT,\n\t\t\t\t\taddress + 4);\n\t\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_IHI(xtensa, XT_REG_A3, 4));\n\t\t\t}\n\t\t}\n\n\t\t/* Execute invalidate instructions */\n\t\tret = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\txtensa_core_status_check(target);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Error issuing cache invaldate instruction(s): %d\", ret);\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t/* Write new instructions to memory */\n\tret = target_write_buffer(target, address, size, buffer);\n\tif (ret != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Error writing instruction to memory: %d\", ret);\n\t\treturn ret;\n\t}\n\n\tif (issue_dhwbi) {\n\t\t/* Flush dcache so instruction propagates.  A3 may be corrupted during memory write */\n\t\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, address);\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\t\txtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 0));\n\t\tLOG_DEBUG(\"DHWB dcache line for address \"TARGET_ADDR_FMT, address);\n\t\tif (!same_dc_line) {\n\t\t\tLOG_TARGET_DEBUG(target, \"DHWB second dcache line for address \"TARGET_ADDR_FMT, address + 4);\n\t\t\txtensa_queue_exec_ins(xtensa, XT_INS_DHWB(xtensa, XT_REG_A3, 4));\n\t\t}\n\n\t\t/* Execute invalidate instructions */\n\t\tret = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\txtensa_core_status_check(target);\n\t}\n\n\t/* TODO: Handle L2 cache if present */\n\treturn ret;\n}\n\nstatic int xtensa_sw_breakpoint_add(struct target *target,\n\tstruct breakpoint *breakpoint,\n\tstruct xtensa_sw_breakpoint *sw_bp)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint ret = target_read_buffer(target, breakpoint->address, XT_ISNS_SZ_MAX, sw_bp->insn);\n\tif (ret != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to read original instruction (%d)!\", ret);\n\t\treturn ret;\n\t}\n\n\tsw_bp->insn_sz = MIN(XT_ISNS_SZ_MAX, breakpoint->length);\n\tsw_bp->oocd_bp = breakpoint;\n\n\tuint32_t break_insn = sw_bp->insn_sz == XT_ISNS_SZ_MAX ? XT_INS_BREAK(xtensa, 0, 0) : XT_INS_BREAKN(xtensa, 0);\n\n\t/* Underlying memory write will convert instruction endianness, don't do that here */\n\tret = xtensa_update_instruction(target, breakpoint->address, sw_bp->insn_sz, (uint8_t *)&break_insn);\n\tif (ret != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to write breakpoint instruction (%d)!\", ret);\n\t\treturn ret;\n\t}\n\n\treturn ERROR_OK;\n}\n\nstatic int xtensa_sw_breakpoint_remove(struct target *target, struct xtensa_sw_breakpoint *sw_bp)\n{\n\tint ret = xtensa_update_instruction(target, sw_bp->oocd_bp->address, sw_bp->insn_sz, sw_bp->insn);\n\tif (ret != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"Failed to write insn (%d)!\", ret);\n\t\treturn ret;\n\t}\n\tsw_bp->oocd_bp = NULL;\n\treturn ERROR_OK;\n}\n\nint xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int slot;\n\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\tfor (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {\n\t\t\tif (!xtensa->sw_brps[slot].oocd_bp ||\n\t\t\t\txtensa->sw_brps[slot].oocd_bp == breakpoint)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (slot == XT_SW_BREAKPOINTS_MAX_NUM) {\n\t\t\tLOG_TARGET_WARNING(target, \"No free slots to add SW breakpoint!\");\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tint ret = xtensa_sw_breakpoint_add(target, breakpoint, &xtensa->sw_brps[slot]);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to add SW breakpoint!\");\n\t\t\treturn ret;\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"placed SW breakpoint %u @ \" TARGET_ADDR_FMT,\n\t\t\tslot,\n\t\t\tbreakpoint->address);\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {\n\t\tif (!xtensa->hw_brps[slot] || xtensa->hw_brps[slot] == breakpoint)\n\t\t\tbreak;\n\t}\n\tif (slot == xtensa->core_config->debug.ibreaks_num) {\n\t\tLOG_TARGET_ERROR(target, \"No free slots to add HW breakpoint!\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\txtensa->hw_brps[slot] = breakpoint;\n\t/* We will actually write the breakpoints when we resume the target. */\n\tLOG_TARGET_DEBUG(target, \"placed HW breakpoint %u @ \" TARGET_ADDR_FMT,\n\t\tslot,\n\t\tbreakpoint->address);\n\n\treturn ERROR_OK;\n}\n\nint xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int slot;\n\n\tif (breakpoint->type == BKPT_SOFT) {\n\t\tfor (slot = 0; slot < XT_SW_BREAKPOINTS_MAX_NUM; slot++) {\n\t\t\tif (xtensa->sw_brps[slot].oocd_bp && xtensa->sw_brps[slot].oocd_bp == breakpoint)\n\t\t\t\tbreak;\n\t\t}\n\t\tif (slot == XT_SW_BREAKPOINTS_MAX_NUM) {\n\t\t\tLOG_TARGET_WARNING(target, \"Max SW breakpoints slot reached, slot=%u!\", slot);\n\t\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t\t}\n\t\tint ret = xtensa_sw_breakpoint_remove(target, &xtensa->sw_brps[slot]);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_TARGET_ERROR(target, \"Failed to remove SW breakpoint (%d)!\", ret);\n\t\t\treturn ret;\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"cleared SW breakpoint %u @ \" TARGET_ADDR_FMT, slot, breakpoint->address);\n\t\treturn ERROR_OK;\n\t}\n\n\tfor (slot = 0; slot < xtensa->core_config->debug.ibreaks_num; slot++) {\n\t\tif (xtensa->hw_brps[slot] == breakpoint)\n\t\t\tbreak;\n\t}\n\tif (slot == xtensa->core_config->debug.ibreaks_num) {\n\t\tLOG_TARGET_ERROR(target, \"HW breakpoint not found!\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\txtensa->hw_brps[slot] = NULL;\n\tif (xtensa->core_config->core_type == XT_NX)\n\t\txtensa_reg_set(target, xtensa->nx_reg_idx[XT_NX_REG_IDX_IBREAKC0] + slot, 0);\n\tLOG_TARGET_DEBUG(target, \"cleared HW breakpoint %u @ \" TARGET_ADDR_FMT, slot, breakpoint->address);\n\treturn ERROR_OK;\n}\n\nint xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int slot;\n\txtensa_reg_val_t dbreakcval;\n\n\tif (target->state != TARGET_HALTED) {\n\t\tLOG_TARGET_WARNING(target, \"target not halted\");\n\t\treturn ERROR_TARGET_NOT_HALTED;\n\t}\n\n\tif (watchpoint->mask != ~(uint32_t)0) {\n\t\tLOG_TARGET_ERROR(target, \"watchpoint value masks not supported\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\tfor (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {\n\t\tif (!xtensa->hw_wps[slot] || xtensa->hw_wps[slot] == watchpoint)\n\t\t\tbreak;\n\t}\n\tif (slot == xtensa->core_config->debug.dbreaks_num) {\n\t\tLOG_TARGET_WARNING(target, \"No free slots to add HW watchpoint!\");\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\n\t/* Figure out value for dbreakc5..0\n\t * It's basically 0x3F with an incremental bit removed from the LSB for each extra length power of 2. */\n\tif (watchpoint->length < 1 || watchpoint->length > 64 ||\n\t\t!IS_PWR_OF_2(watchpoint->length) ||\n\t\t!IS_ALIGNED(watchpoint->address, watchpoint->length)) {\n\t\tLOG_TARGET_WARNING(\n\t\t\ttarget,\n\t\t\t\"Watchpoint with length %d on address \" TARGET_ADDR_FMT\n\t\t\t\" not supported by hardware.\",\n\t\t\twatchpoint->length,\n\t\t\twatchpoint->address);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\tdbreakcval = ALIGN_DOWN(0x3F, watchpoint->length);\n\n\tif (watchpoint->rw == WPT_READ)\n\t\tdbreakcval |= BIT(30);\n\tif (watchpoint->rw == WPT_WRITE)\n\t\tdbreakcval |= BIT(31);\n\tif (watchpoint->rw == WPT_ACCESS)\n\t\tdbreakcval |= BIT(30) | BIT(31);\n\n\t/* Write DBREAKA[slot] and DBCREAKC[slot] */\n\txtensa_reg_set(target, XT_REG_IDX_DBREAKA0 + slot, watchpoint->address);\n\txtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, dbreakcval);\n\txtensa->hw_wps[slot] = watchpoint;\n\tLOG_TARGET_DEBUG(target, \"placed HW watchpoint @ \" TARGET_ADDR_FMT,\n\t\twatchpoint->address);\n\treturn ERROR_OK;\n}\n\nint xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tunsigned int slot;\n\n\tfor (slot = 0; slot < xtensa->core_config->debug.dbreaks_num; slot++) {\n\t\tif (xtensa->hw_wps[slot] == watchpoint)\n\t\t\tbreak;\n\t}\n\tif (slot == xtensa->core_config->debug.dbreaks_num) {\n\t\tLOG_TARGET_WARNING(target, \"HW watchpoint \" TARGET_ADDR_FMT \" not found!\", watchpoint->address);\n\t\treturn ERROR_TARGET_RESOURCE_NOT_AVAILABLE;\n\t}\n\txtensa_reg_set(target, XT_REG_IDX_DBREAKC0 + slot, 0);\n\txtensa->hw_wps[slot] = NULL;\n\tLOG_TARGET_DEBUG(target, \"cleared HW watchpoint @ \" TARGET_ADDR_FMT,\n\t\twatchpoint->address);\n\treturn ERROR_OK;\n}\n\nstatic int xtensa_build_reg_cache(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);\n\tunsigned int last_dbreg_num = 0;\n\n\tif (xtensa->core_regs_num + xtensa->num_optregs != xtensa->total_regs_num)\n\t\tLOG_TARGET_WARNING(target, \"Register count MISMATCH: %d core regs, %d extended regs; %d expected\",\n\t\t\txtensa->core_regs_num, xtensa->num_optregs, xtensa->total_regs_num);\n\n\tstruct reg_cache *reg_cache = calloc(1, sizeof(struct reg_cache));\n\n\tif (!reg_cache) {\n\t\tLOG_ERROR(\"Failed to alloc reg cache!\");\n\t\treturn ERROR_FAIL;\n\t}\n\treg_cache->name = \"Xtensa registers\";\n\treg_cache->next = NULL;\n\t/* Init reglist */\n\tunsigned int reg_list_size = XT_NUM_REGS + xtensa->num_optregs;\n\tstruct reg *reg_list = calloc(reg_list_size, sizeof(struct reg));\n\tif (!reg_list) {\n\t\tLOG_ERROR(\"Failed to alloc reg list!\");\n\t\tgoto fail;\n\t}\n\txtensa->dbregs_num = 0;\n\tunsigned int didx = 0;\n\tfor (unsigned int whichlist = 0; whichlist < 2; whichlist++) {\n\t\tstruct xtensa_reg_desc *rlist = (whichlist == 0) ? xtensa_regs : xtensa->optregs;\n\t\tunsigned int listsize = (whichlist == 0) ? XT_NUM_REGS : xtensa->num_optregs;\n\t\tfor (unsigned int i = 0; i < listsize; i++, didx++) {\n\t\t\treg_list[didx].exist = rlist[i].exist;\n\t\t\treg_list[didx].name = rlist[i].name;\n\t\t\treg_list[didx].size = 32;\n\t\t\treg_list[didx].value = calloc(1, 4 /*XT_REG_LEN*/);\t/* make Clang Static Analyzer happy */\n\t\t\tif (!reg_list[didx].value) {\n\t\t\t\tLOG_ERROR(\"Failed to alloc reg list value!\");\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\treg_list[didx].dirty = false;\n\t\t\treg_list[didx].valid = false;\n\t\t\treg_list[didx].type = &xtensa_reg_type;\n\t\t\treg_list[didx].arch_info = xtensa;\n\t\t\tif (rlist[i].exist && (rlist[i].dbreg_num > last_dbreg_num))\n\t\t\t\tlast_dbreg_num = rlist[i].dbreg_num;\n\n\t\t\tif (xtensa_extra_debug_log) {\n\t\t\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\t\t\"POPULATE %-16s list %d exist %d, idx %d, type %d, dbreg_num 0x%04x\",\n\t\t\t\t\treg_list[didx].name,\n\t\t\t\t\twhichlist,\n\t\t\t\t\treg_list[didx].exist,\n\t\t\t\t\tdidx,\n\t\t\t\t\trlist[i].type,\n\t\t\t\t\trlist[i].dbreg_num);\n\t\t\t}\n\t\t}\n\t}\n\n\txtensa->dbregs_num = last_dbreg_num + 1;\n\treg_cache->reg_list = reg_list;\n\treg_cache->num_regs = reg_list_size;\n\n\tLOG_TARGET_DEBUG(target, \"xtensa->total_regs_num %d reg_list_size %d xtensa->dbregs_num %d\",\n\t\txtensa->total_regs_num, reg_list_size, xtensa->dbregs_num);\n\n\t/* Construct empty-register list for handling unknown register requests */\n\txtensa->empty_regs = calloc(xtensa->dbregs_num, sizeof(struct reg));\n\tif (!xtensa->empty_regs) {\n\t\tLOG_TARGET_ERROR(target, \"ERROR: Out of memory\");\n\t\tgoto fail;\n\t}\n\tfor (unsigned int i = 0; i < xtensa->dbregs_num; i++) {\n\t\txtensa->empty_regs[i].name = calloc(8, sizeof(char));\n\t\tif (!xtensa->empty_regs[i].name) {\n\t\t\tLOG_TARGET_ERROR(target, \"ERROR: Out of memory\");\n\t\t\tgoto fail;\n\t\t}\n\t\tsprintf((char *)xtensa->empty_regs[i].name, \"?0x%04x\", i & 0x0000FFFF);\n\t\txtensa->empty_regs[i].size = 32;\n\t\txtensa->empty_regs[i].type = &xtensa_reg_type;\n\t\txtensa->empty_regs[i].value = calloc(1, 4 /*XT_REG_LEN*/);\t/* make Clang Static Analyzer happy */\n\t\tif (!xtensa->empty_regs[i].value) {\n\t\t\tLOG_ERROR(\"Failed to alloc empty reg list value!\");\n\t\t\tgoto fail;\n\t\t}\n\t\txtensa->empty_regs[i].arch_info = xtensa;\n\t}\n\n\t/* Construct contiguous register list from contiguous descriptor list */\n\tif (xtensa->regmap_contiguous && xtensa->contiguous_regs_desc) {\n\t\txtensa->contiguous_regs_list = calloc(xtensa->total_regs_num, sizeof(struct reg *));\n\t\tif (!xtensa->contiguous_regs_list) {\n\t\t\tLOG_TARGET_ERROR(target, \"ERROR: Out of memory\");\n\t\t\tgoto fail;\n\t\t}\n\t\tfor (unsigned int i = 0; i < xtensa->total_regs_num; i++) {\n\t\t\tunsigned int j;\n\t\t\tfor (j = 0; j < reg_cache->num_regs; j++) {\n\t\t\t\tif (!strcmp(reg_cache->reg_list[j].name, xtensa->contiguous_regs_desc[i]->name)) {\n\t\t\t\t\t/*\tRegister number field is not filled above.\n\t\t\t\t\t\tHere we are assigning the corresponding index from the contiguous reg list.\n\t\t\t\t\t\tThese indexes are in the same order with gdb g-packet request/response.\n\t\t\t\t\t\tSome more changes may be required for sparse reg lists.\n\t\t\t\t\t*/\n\t\t\t\t\treg_cache->reg_list[j].number = i;\n\t\t\t\t\txtensa->contiguous_regs_list[i] = &(reg_cache->reg_list[j]);\n\t\t\t\t\tLOG_TARGET_DEBUG(target,\n\t\t\t\t\t\t\"POPULATE contiguous regs list: %-16s, dbreg_num 0x%04x\",\n\t\t\t\t\t\txtensa->contiguous_regs_list[i]->name,\n\t\t\t\t\t\txtensa->contiguous_regs_desc[i]->dbreg_num);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (j == reg_cache->num_regs)\n\t\t\t\tLOG_TARGET_WARNING(target, \"contiguous register %s not found\",\n\t\t\t\t\txtensa->contiguous_regs_desc[i]->name);\n\t\t}\n\t}\n\n\txtensa->algo_context_backup = calloc(reg_cache->num_regs, sizeof(void *));\n\tif (!xtensa->algo_context_backup) {\n\t\tLOG_ERROR(\"Failed to alloc mem for algorithm context backup!\");\n\t\tgoto fail;\n\t}\n\tfor (unsigned int i = 0; i < reg_cache->num_regs; i++) {\n\t\tstruct reg *reg = &reg_cache->reg_list[i];\n\t\txtensa->algo_context_backup[i] = calloc(1, reg->size / 8);\n\t\tif (!xtensa->algo_context_backup[i]) {\n\t\t\tLOG_ERROR(\"Failed to alloc mem for algorithm context!\");\n\t\t\tgoto fail;\n\t\t}\n\t}\n\txtensa->core_cache = reg_cache;\n\tif (cache_p)\n\t\t*cache_p = reg_cache;\n\treturn ERROR_OK;\n\nfail:\n\tif (reg_list) {\n\t\tfor (unsigned int i = 0; i < reg_list_size; i++)\n\t\t\tfree(reg_list[i].value);\n\t\tfree(reg_list);\n\t}\n\tif (xtensa->empty_regs) {\n\t\tfor (unsigned int i = 0; i < xtensa->dbregs_num; i++) {\n\t\t\tfree((void *)xtensa->empty_regs[i].name);\n\t\t\tfree(xtensa->empty_regs[i].value);\n\t\t}\n\t\tfree(xtensa->empty_regs);\n\t}\n\tif (xtensa->algo_context_backup) {\n\t\tfor (unsigned int i = 0; i < reg_cache->num_regs; i++)\n\t\t\tfree(xtensa->algo_context_backup[i]);\n\t\tfree(xtensa->algo_context_backup);\n\t}\n\tfree(reg_cache);\n\n\treturn ERROR_FAIL;\n}\n\nstatic int32_t xtensa_gdbqc_parse_exec_tie_ops(struct target *target, char *opstr)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint32_t status = ERROR_COMMAND_ARGUMENT_INVALID;\n\t/* Process op[] list */\n\twhile (opstr && (*opstr == ':')) {\n\t\tuint8_t ops[32];\n\t\tunsigned int oplen = strtoul(opstr + 1, &opstr, 16);\n\t\tif (oplen > 32) {\n\t\t\tLOG_TARGET_ERROR(target, \"TIE access instruction too long (%d)\\n\", oplen);\n\t\t\tbreak;\n\t\t}\n\t\tunsigned int i = 0;\n\t\twhile ((i < oplen) && opstr && (*opstr == ':'))\n\t\t\tops[i++] = strtoul(opstr + 1, &opstr, 16);\n\t\tif (i != oplen) {\n\t\t\tLOG_TARGET_ERROR(target, \"TIE access instruction malformed (%d)\\n\", i);\n\t\t\tbreak;\n\t\t}\n\n\t\tchar insn_buf[128];\n\t\tsprintf(insn_buf, \"Exec %d-byte TIE sequence: \", oplen);\n\t\tfor (i = 0; i < oplen; i++)\n\t\t\tsprintf(insn_buf + strlen(insn_buf), \"%02x:\", ops[i]);\n\t\tLOG_TARGET_DEBUG(target, \"%s\", insn_buf);\n\t\txtensa_queue_exec_ins_wide(xtensa, ops, oplen);\t/* Handles endian-swap */\n\t\tstatus = ERROR_OK;\n\t}\n\treturn status;\n}\n\nstatic int xtensa_gdbqc_qxtreg(struct target *target, const char *packet, char **response_p)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tbool iswrite = (packet[0] == 'Q');\n\tenum xtensa_qerr_e error;\n\n\t/* Read/write TIE register.  Requires spill location.\n\t * qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]\n\t * Qxtreg<num>:<len>:<oplen>:<op[0]>:<...>[:<oplen>:<op[0]>:<...>]=<value>\n\t */\n\tif (!(xtensa->spill_buf)) {\n\t\tLOG_ERROR(\"Spill location not specified. Try 'target remote <host>:3333 &spill_location0'\");\n\t\terror = XT_QERR_FAIL;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\n\tchar *delim;\n\tuint32_t regnum = strtoul(packet + 6, &delim, 16);\n\tif (*delim != ':') {\n\t\tLOG_ERROR(\"Malformed qxtreg packet\");\n\t\terror = XT_QERR_INVAL;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\tuint32_t reglen = strtoul(delim + 1, &delim, 16);\n\tif (*delim != ':') {\n\t\tLOG_ERROR(\"Malformed qxtreg packet\");\n\t\terror = XT_QERR_INVAL;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\tuint8_t regbuf[XT_QUERYPKT_RESP_MAX];\n\tmemset(regbuf, 0, XT_QUERYPKT_RESP_MAX);\n\tLOG_DEBUG(\"TIE reg 0x%08\" PRIx32 \" %s (%d bytes)\", regnum, iswrite ? \"write\" : \"read\", reglen);\n\tif (reglen * 2 + 1 > XT_QUERYPKT_RESP_MAX) {\n\t\tLOG_ERROR(\"TIE register too large\");\n\t\terror = XT_QERR_MEM;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\n\t/* (1) Save spill memory, (1.5) [if write then store value to spill location],\n\t * (2) read old a4, (3) write spill address to a4.\n\t * NOTE: ensure a4 is restored properly by all error handling logic\n\t */\n\tunsigned int memop_size = (xtensa->spill_loc & 3) ? 1 : 4;\n\tint status = xtensa_read_memory(target, xtensa->spill_loc, memop_size,\n\t\txtensa->spill_bytes / memop_size, xtensa->spill_buf);\n\tif (status != ERROR_OK) {\n\t\tLOG_ERROR(\"Spill memory save\");\n\t\terror = XT_QERR_MEM;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\tif (iswrite) {\n\t\t/* Extract value and store in spill memory */\n\t\tunsigned int b = 0;\n\t\tchar *valbuf = strchr(delim, '=');\n\t\tif (!(valbuf && (*valbuf == '='))) {\n\t\t\tLOG_ERROR(\"Malformed Qxtreg packet\");\n\t\t\terror = XT_QERR_INVAL;\n\t\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t\t}\n\t\tvalbuf++;\n\t\twhile (*valbuf && *(valbuf + 1)) {\n\t\t\tchar bytestr[3] = { 0, 0, 0 };\n\t\t\tstrncpy(bytestr, valbuf, 2);\n\t\t\tregbuf[b++] = strtoul(bytestr, NULL, 16);\n\t\t\tvalbuf += 2;\n\t\t}\n\t\tif (b != reglen) {\n\t\t\tLOG_ERROR(\"Malformed Qxtreg packet\");\n\t\t\terror = XT_QERR_INVAL;\n\t\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t\t}\n\t\tstatus = xtensa_write_memory(target, xtensa->spill_loc, memop_size,\n\t\t\treglen / memop_size, regbuf);\n\t\tif (status != ERROR_OK) {\n\t\t\tLOG_ERROR(\"TIE value store\");\n\t\t\terror = XT_QERR_MEM;\n\t\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t\t}\n\t}\n\txtensa_reg_val_t orig_a4 = xtensa_reg_get(target, XT_REG_IDX_A4);\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, xtensa->spill_loc);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));\n\n\tint32_t tieop_status = xtensa_gdbqc_parse_exec_tie_ops(target, delim);\n\n\t/* Restore a4 but not yet spill memory.  Execute it all... */\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, orig_a4);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A4));\n\tstatus = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (status != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"TIE queue execute: %d\\n\", status);\n\t\ttieop_status = status;\n\t}\n\tstatus = xtensa_core_status_check(target);\n\tif (status != ERROR_OK) {\n\t\tLOG_TARGET_ERROR(target, \"TIE instr execute: %d\\n\", status);\n\t\ttieop_status = status;\n\t}\n\n\tif (tieop_status == ERROR_OK) {\n\t\tif (iswrite) {\n\t\t\t/* TIE write succeeded; send OK */\n\t\t\tstrcpy(*response_p, \"OK\");\n\t\t} else {\n\t\t\t/* TIE read succeeded; copy result from spill memory */\n\t\t\tstatus = xtensa_read_memory(target, xtensa->spill_loc, memop_size, reglen, regbuf);\n\t\t\tif (status != ERROR_OK) {\n\t\t\t\tLOG_TARGET_ERROR(target, \"TIE result read\");\n\t\t\t\ttieop_status = status;\n\t\t\t}\n\t\t\tunsigned int i;\n\t\t\tfor (i = 0; i < reglen; i++)\n\t\t\t\tsprintf(*response_p + 2 * i, \"%02x\", regbuf[i]);\n\t\t\t*(*response_p + 2 * i) = '\\0';\n\t\t\tLOG_TARGET_DEBUG(target, \"TIE response: %s\", *response_p);\n\t\t}\n\t}\n\n\t/* Restore spill memory first, then report any previous errors */\n\tstatus = xtensa_write_memory(target, xtensa->spill_loc, memop_size,\n\t\txtensa->spill_bytes / memop_size, xtensa->spill_buf);\n\tif (status != ERROR_OK) {\n\t\tLOG_ERROR(\"Spill memory restore\");\n\t\terror = XT_QERR_MEM;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\tif (tieop_status != ERROR_OK) {\n\t\tLOG_ERROR(\"TIE execution\");\n\t\terror = XT_QERR_FAIL;\n\t\tgoto xtensa_gdbqc_qxtreg_fail;\n\t}\n\treturn ERROR_OK;\n\nxtensa_gdbqc_qxtreg_fail:\n\tstrcpy(*response_p, xt_qerr[error].chrval);\n\treturn xt_qerr[error].intval;\n}\n\nint xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tenum xtensa_qerr_e error;\n\tif (!packet || !response_p) {\n\t\tLOG_TARGET_ERROR(target, \"invalid parameter: packet %p response_p %p\", packet, response_p);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t*response_p = xtensa->qpkt_resp;\n\tif (strncmp(packet, \"qxtn\", 4) == 0) {\n\t\tstrcpy(*response_p, \"OpenOCD\");\n\t\treturn ERROR_OK;\n\t} else if (strncasecmp(packet, \"qxtgdbversion=\", 14) == 0) {\n\t\treturn ERROR_OK;\n\t} else if ((strncmp(packet, \"Qxtsis=\", 7) == 0) || (strncmp(packet, \"Qxtsds=\", 7) == 0)) {\n\t\t/* Confirm host cache params match core .cfg file */\n\t\tstruct xtensa_cache_config *cachep = (packet[4] == 'i') ?\n\t\t\t&xtensa->core_config->icache : &xtensa->core_config->dcache;\n\t\tunsigned int line_size = 0, size = 0, way_count = 0;\n\t\tsscanf(&packet[7], \"%x,%x,%x\", &line_size, &size, &way_count);\n\t\tif ((cachep->line_size != line_size) ||\n\t\t\t(cachep->size != size) ||\n\t\t\t(cachep->way_count != way_count)) {\n\t\t\tLOG_TARGET_WARNING(target, \"%cCache mismatch; check xtensa-core-XXX.cfg file\",\n\t\t\t\tcachep == &xtensa->core_config->icache ? 'I' : 'D');\n\t\t}\n\t\tstrcpy(*response_p, \"OK\");\n\t\treturn ERROR_OK;\n\t} else if ((strncmp(packet, \"Qxtiram=\", 8) == 0) || (strncmp(packet, \"Qxtirom=\", 8) == 0)) {\n\t\t/* Confirm host IRAM/IROM params match core .cfg file */\n\t\tstruct xtensa_local_mem_config *memp = (packet[5] == 'a') ?\n\t\t\t&xtensa->core_config->iram : &xtensa->core_config->irom;\n\t\tunsigned int base = 0, size = 0, i;\n\t\tchar *pkt = (char *)&packet[7];\n\t\tdo {\n\t\t\tpkt++;\n\t\t\tsize = strtoul(pkt, &pkt, 16);\n\t\t\tpkt++;\n\t\t\tbase = strtoul(pkt, &pkt, 16);\n\t\t\tLOG_TARGET_DEBUG(target, \"memcheck: %dB @ 0x%08x\", size, base);\n\t\t\tfor (i = 0; i < memp->count; i++) {\n\t\t\t\tif ((memp->regions[i].base == base) && (memp->regions[i].size == size))\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (i == memp->count) {\n\t\t\t\tLOG_TARGET_WARNING(target, \"%s mismatch; check xtensa-core-XXX.cfg file\",\n\t\t\t\t\tmemp == &xtensa->core_config->iram ? \"IRAM\" : \"IROM\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tfor (i = 0; i < 11; i++) {\n\t\t\t\tpkt++;\n\t\t\t\tstrtoul(pkt, &pkt, 16);\n\t\t\t}\n\t\t} while (pkt && (pkt[0] == ','));\n\t\tstrcpy(*response_p, \"OK\");\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"Qxtexcmlvl=\", 11) == 0) {\n\t\t/* Confirm host EXCM_LEVEL matches core .cfg file */\n\t\tunsigned int excm_level = strtoul(&packet[11], NULL, 0);\n\t\tif (!xtensa->core_config->high_irq.enabled ||\n\t\t\t(excm_level != xtensa->core_config->high_irq.excm_level))\n\t\t\tLOG_TARGET_WARNING(target, \"EXCM_LEVEL mismatch; check xtensa-core-XXX.cfg file\");\n\t\tstrcpy(*response_p, \"OK\");\n\t\treturn ERROR_OK;\n\t} else if ((strncmp(packet, \"Qxtl2cs=\", 8) == 0) ||\n\t\t(strncmp(packet, \"Qxtl2ca=\", 8) == 0) ||\n\t\t(strncmp(packet, \"Qxtdensity=\", 11) == 0)) {\n\t\tstrcpy(*response_p, \"OK\");\n\t\treturn ERROR_OK;\n\t} else if (strncmp(packet, \"Qxtspill=\", 9) == 0) {\n\t\tchar *delim;\n\t\tuint32_t spill_loc = strtoul(packet + 9, &delim, 16);\n\t\tif (*delim != ':') {\n\t\t\tLOG_ERROR(\"Malformed Qxtspill packet\");\n\t\t\terror = XT_QERR_INVAL;\n\t\t\tgoto xtensa_gdb_query_custom_fail;\n\t\t}\n\t\txtensa->spill_loc = spill_loc;\n\t\txtensa->spill_bytes = strtoul(delim + 1, NULL, 16);\n\t\tif (xtensa->spill_buf)\n\t\t\tfree(xtensa->spill_buf);\n\t\txtensa->spill_buf = calloc(1, xtensa->spill_bytes);\n\t\tif (!xtensa->spill_buf) {\n\t\t\tLOG_ERROR(\"Spill buf alloc\");\n\t\t\terror = XT_QERR_MEM;\n\t\t\tgoto xtensa_gdb_query_custom_fail;\n\t\t}\n\t\tLOG_TARGET_DEBUG(target, \"Set spill 0x%08\" PRIx32 \" (%d)\", xtensa->spill_loc, xtensa->spill_bytes);\n\t\tstrcpy(*response_p, \"OK\");\n\t\treturn ERROR_OK;\n\t} else if (strncasecmp(packet, \"qxtreg\", 6) == 0) {\n\t\treturn xtensa_gdbqc_qxtreg(target, packet, response_p);\n\t} else if ((strncmp(packet, \"qTStatus\", 8) == 0) ||\n\t\t(strncmp(packet, \"qxtftie\", 7) == 0) ||\n\t\t(strncmp(packet, \"qxtstie\", 7) == 0)) {\n\t\t/* Return empty string to indicate trace, TIE wire debug are unsupported */\n\t\tstrcpy(*response_p, \"\");\n\t\treturn ERROR_OK;\n\t}\n\n\t/* Warn for all other queries, but do not return errors */\n\tLOG_TARGET_WARNING(target, \"Unknown target-specific query packet: %s\", packet);\n\tstrcpy(*response_p, \"\");\n\treturn ERROR_OK;\n\nxtensa_gdb_query_custom_fail:\n\tstrcpy(*response_p, xt_qerr[error].chrval);\n\treturn xt_qerr[error].intval;\n}\n\nint xtensa_init_arch_info(struct target *target, struct xtensa *xtensa,\n\tconst struct xtensa_debug_module_config *dm_cfg)\n{\n\ttarget->arch_info = xtensa;\n\txtensa->common_magic = XTENSA_COMMON_MAGIC;\n\txtensa->target = target;\n\txtensa->stepping_isr_mode = XT_STEPPING_ISR_ON;\n\n\txtensa->core_config = calloc(1, sizeof(struct xtensa_config));\n\tif (!xtensa->core_config) {\n\t\tLOG_ERROR(\"Xtensa configuration alloc failed\\n\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Default cache settings are disabled with 1 way */\n\txtensa->core_config->icache.way_count = 1;\n\txtensa->core_config->dcache.way_count = 1;\n\n\t/* chrval: AR3/AR4 register names will change with window mapping.\n\t * intval: tracks whether scratch register was set through gdb P packet.\n\t */\n\tfor (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++) {\n\t\txtensa->scratch_ars[s].chrval = calloc(8, sizeof(char));\n\t\tif (!xtensa->scratch_ars[s].chrval) {\n\t\t\tfor (enum xtensa_ar_scratch_set_e f = 0; f < s; f++)\n\t\t\t\tfree(xtensa->scratch_ars[f].chrval);\n\t\t\tfree(xtensa->core_config);\n\t\t\tLOG_ERROR(\"Xtensa scratch AR alloc failed\\n\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\txtensa->scratch_ars[s].intval = false;\n\t\tsprintf(xtensa->scratch_ars[s].chrval, \"%s%d\",\n\t\t\t((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_A4)) ? \"a\" : \"ar\",\n\t\t\t((s == XT_AR_SCRATCH_A3) || (s == XT_AR_SCRATCH_AR3)) ? 3 : 4);\n\t}\n\n\treturn xtensa_dm_init(&xtensa->dbg_mod, dm_cfg);\n}\n\nvoid xtensa_set_permissive_mode(struct target *target, bool state)\n{\n\ttarget_to_xtensa(target)->permissive_mode = state;\n}\n\nint xtensa_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\txtensa->come_online_probes_num = 3;\n\txtensa->hw_brps = calloc(XT_HW_IBREAK_MAX_NUM, sizeof(struct breakpoint *));\n\tif (!xtensa->hw_brps) {\n\t\tLOG_ERROR(\"Failed to alloc memory for HW breakpoints!\");\n\t\treturn ERROR_FAIL;\n\t}\n\txtensa->hw_wps = calloc(XT_HW_DBREAK_MAX_NUM, sizeof(struct watchpoint *));\n\tif (!xtensa->hw_wps) {\n\t\tfree(xtensa->hw_brps);\n\t\tLOG_ERROR(\"Failed to alloc memory for HW watchpoints!\");\n\t\treturn ERROR_FAIL;\n\t}\n\txtensa->sw_brps = calloc(XT_SW_BREAKPOINTS_MAX_NUM, sizeof(struct xtensa_sw_breakpoint));\n\tif (!xtensa->sw_brps) {\n\t\tfree(xtensa->hw_brps);\n\t\tfree(xtensa->hw_wps);\n\t\tLOG_ERROR(\"Failed to alloc memory for SW breakpoints!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\txtensa->spill_loc = 0xffffffff;\n\txtensa->spill_bytes = 0;\n\txtensa->spill_buf = NULL;\n\txtensa->probe_lsddr32p = -1;\t/* Probe for fast load/store operations */\n\n\treturn xtensa_build_reg_cache(target);\n}\n\nstatic void xtensa_free_reg_cache(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tstruct reg_cache *cache = xtensa->core_cache;\n\n\tif (cache) {\n\t\tregister_unlink_cache(&target->reg_cache, cache);\n\t\tfor (unsigned int i = 0; i < cache->num_regs; i++) {\n\t\t\tfree(xtensa->algo_context_backup[i]);\n\t\t\tfree(cache->reg_list[i].value);\n\t\t}\n\t\tfree(xtensa->algo_context_backup);\n\t\tfree(cache->reg_list);\n\t\tfree(cache);\n\t}\n\txtensa->core_cache = NULL;\n\txtensa->algo_context_backup = NULL;\n\n\tif (xtensa->empty_regs) {\n\t\tfor (unsigned int i = 0; i < xtensa->dbregs_num; i++) {\n\t\t\tfree((void *)xtensa->empty_regs[i].name);\n\t\t\tfree(xtensa->empty_regs[i].value);\n\t\t}\n\t\tfree(xtensa->empty_regs);\n\t}\n\txtensa->empty_regs = NULL;\n\tif (xtensa->optregs) {\n\t\tfor (unsigned int i = 0; i < xtensa->num_optregs; i++)\n\t\t\tfree((void *)xtensa->optregs[i].name);\n\t\tfree(xtensa->optregs);\n\t}\n\txtensa->optregs = NULL;\n}\n\nvoid xtensa_target_deinit(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tLOG_DEBUG(\"start\");\n\n\tif (target_was_examined(target)) {\n\t\tint ret = xtensa_queue_dbg_reg_write(xtensa, XDMREG_DCRCLR, OCDDCR_ENABLEOCD);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to queue OCDDCR_ENABLEOCD clear operation!\");\n\t\t\treturn;\n\t\t}\n\t\txtensa_dm_queue_tdi_idle(&xtensa->dbg_mod);\n\t\tret = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\t\tif (ret != ERROR_OK) {\n\t\t\tLOG_ERROR(\"Failed to clear OCDDCR_ENABLEOCD!\");\n\t\t\treturn;\n\t\t}\n\t\txtensa_dm_deinit(&xtensa->dbg_mod);\n\t}\n\txtensa_free_reg_cache(target);\n\tfree(xtensa->hw_brps);\n\tfree(xtensa->hw_wps);\n\tfree(xtensa->sw_brps);\n\tif (xtensa->spill_buf) {\n\t\tfree(xtensa->spill_buf);\n\t\txtensa->spill_buf = NULL;\n\t}\n\tfor (enum xtensa_ar_scratch_set_e s = 0; s < XT_AR_SCRATCH_NUM; s++)\n\t\tfree(xtensa->scratch_ars[s].chrval);\n\tfree(xtensa->core_config);\n}\n\nconst char *xtensa_get_gdb_arch(struct target *target)\n{\n\treturn \"xtensa\";\n}\n\n/* exe <ascii-encoded hexadecimal instruction bytes> */\nstatic COMMAND_HELPER(xtensa_cmd_exe_do, struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* Process ascii-encoded hex byte string */\n\tconst char *parm = CMD_ARGV[0];\n\tunsigned int parm_len = strlen(parm);\n\tif ((parm_len >= 64) || (parm_len & 1)) {\n\t\tLOG_ERROR(\"Invalid parameter length (%d): must be even, < 64 characters\", parm_len);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tuint8_t ops[32];\n\tmemset(ops, 0, 32);\n\tunsigned int oplen = parm_len / 2;\n\tchar encoded_byte[3] = { 0, 0, 0 };\n\tfor (unsigned int i = 0; i < oplen; i++) {\n\t\tencoded_byte[0] = *parm++;\n\t\tencoded_byte[1] = *parm++;\n\t\tops[i] = strtoul(encoded_byte, NULL, 16);\n\t}\n\n\t/* GDB must handle state save/restore.\n\t * Flush reg cache in case spill location is in an AR\n\t * Update CPENABLE only for this execution; later restore cached copy\n\t * Keep a copy of exccause in case executed code triggers an exception\n\t */\n\tint status = xtensa_write_dirty_registers(target);\n\tif (status != ERROR_OK) {\n\t\tLOG_ERROR(\"%s: Failed to write back register cache.\", target_name(target));\n\t\treturn ERROR_FAIL;\n\t}\n\txtensa_reg_val_t exccause = xtensa_reg_get(target, XT_REG_IDX_EXCCAUSE);\n\txtensa_reg_val_t cpenable = xtensa_reg_get(target, XT_REG_IDX_CPENABLE);\n\txtensa_reg_val_t a3 = xtensa_reg_get(target, XT_REG_IDX_A3);\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, 0xffffffff);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\txtensa_queue_exec_ins(xtensa, XT_INS_WSR(xtensa,\n\t\t\txtensa_regs[XT_REG_IDX_CPENABLE].reg_num, XT_REG_A3));\n\txtensa_queue_dbg_reg_write(xtensa, XDMREG_DDR, a3);\n\txtensa_queue_exec_ins(xtensa, XT_INS_RSR(xtensa, XT_SR_DDR, XT_REG_A3));\n\n\t/* Queue instruction list and execute everything */\n\tLOG_TARGET_DEBUG(target, \"execute stub: %s\", CMD_ARGV[0]);\n\txtensa_queue_exec_ins_wide(xtensa, ops, oplen);\t/* Handles endian-swap */\n\tstatus = xtensa_dm_queue_execute(&xtensa->dbg_mod);\n\tif (status != ERROR_OK)\n\t\tLOG_TARGET_ERROR(target, \"TIE queue execute: %d\\n\", status);\n\tstatus = xtensa_core_status_check(target);\n\tif (status != ERROR_OK)\n\t\tLOG_TARGET_ERROR(target, \"TIE instr execute: %d\\n\", status);\n\n\t/* Reread register cache and restore saved regs after instruction execution */\n\tif (xtensa_fetch_all_regs(target) != ERROR_OK)\n\t\tLOG_TARGET_ERROR(target, \"%s: Failed to fetch register cache (post-exec).\", target_name(target));\n\txtensa_reg_set(target, XT_REG_IDX_EXCCAUSE, exccause);\n\txtensa_reg_set(target, XT_REG_IDX_CPENABLE, cpenable);\n\treturn status;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_exe)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_exe_do, get_current_target(CMD_CTX));\n}\n\n/* xtdef <name> */\nCOMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC != 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst char *core_name = CMD_ARGV[0];\n\tif (strcasecmp(core_name, \"LX\") == 0) {\n\t\txtensa->core_config->core_type = XT_LX;\n\t} else if (strcasecmp(core_name, \"NX\") == 0) {\n\t\txtensa->core_config->core_type = XT_NX;\n\t} else {\n\t\tLOG_ERROR(\"xtdef [LX|NX]\\n\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtdef)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtdef_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nstatic inline bool xtensa_cmd_xtopt_legal_val(char *opt, int val, int min, int max)\n{\n\tif ((val < min) || (val > max)) {\n\t\tLOG_ERROR(\"xtopt %s (%d) out of range [%d..%d]\\n\", opt, val, min, max);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/* xtopt <name> <value> */\nCOMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC != 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tconst char *opt_name = CMD_ARGV[0];\n\tint opt_val = strtol(CMD_ARGV[1], NULL, 0);\n\tif (strcasecmp(opt_name, \"arnum\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"arnum\", opt_val, 0, 64))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->aregs_num = opt_val;\n\t} else if (strcasecmp(opt_name, \"windowed\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"windowed\", opt_val, 0, 1))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->windowed = opt_val;\n\t} else if (strcasecmp(opt_name, \"cpenable\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"cpenable\", opt_val, 0, 1))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->coproc = opt_val;\n\t} else if (strcasecmp(opt_name, \"exceptions\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"exceptions\", opt_val, 0, 1))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->exceptions = opt_val;\n\t} else if (strcasecmp(opt_name, \"intnum\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"intnum\", opt_val, 0, 32))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->irq.enabled = (opt_val > 0);\n\t\txtensa->core_config->irq.irq_num = opt_val;\n\t} else if (strcasecmp(opt_name, \"hipriints\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"hipriints\", opt_val, 0, 1))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->high_irq.enabled = opt_val;\n\t} else if (strcasecmp(opt_name, \"excmlevel\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"excmlevel\", opt_val, 1, 6))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\tif (!xtensa->core_config->high_irq.enabled) {\n\t\t\tLOG_ERROR(\"xtopt excmlevel requires hipriints\\n\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\txtensa->core_config->high_irq.excm_level = opt_val;\n\t} else if (strcasecmp(opt_name, \"intlevels\") == 0) {\n\t\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t\tif (!xtensa_cmd_xtopt_legal_val(\"intlevels\", opt_val, 2, 6))\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t} else {\n\t\t\tif (!xtensa_cmd_xtopt_legal_val(\"intlevels\", opt_val, 1, 255))\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\tif (!xtensa->core_config->high_irq.enabled) {\n\t\t\tLOG_ERROR(\"xtopt intlevels requires hipriints\\n\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\txtensa->core_config->high_irq.level_num = opt_val;\n\t} else if (strcasecmp(opt_name, \"debuglevel\") == 0) {\n\t\tif (xtensa->core_config->core_type == XT_LX) {\n\t\t\tif (!xtensa_cmd_xtopt_legal_val(\"debuglevel\", opt_val, 2, 6))\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t} else {\n\t\t\tif (!xtensa_cmd_xtopt_legal_val(\"debuglevel\", opt_val, 0, 0))\n\t\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t\txtensa->core_config->debug.enabled = 1;\n\t\txtensa->core_config->debug.irq_level = opt_val;\n\t} else if (strcasecmp(opt_name, \"ibreaknum\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"ibreaknum\", opt_val, 0, 2))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->debug.ibreaks_num = opt_val;\n\t} else if (strcasecmp(opt_name, \"dbreaknum\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"dbreaknum\", opt_val, 0, 2))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->debug.dbreaks_num = opt_val;\n\t} else if (strcasecmp(opt_name, \"tracemem\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"tracemem\", opt_val, 0, 256 * 1024))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->trace.mem_sz = opt_val;\n\t\txtensa->core_config->trace.enabled = (opt_val > 0);\n\t} else if (strcasecmp(opt_name, \"tracememrev\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"tracememrev\", opt_val, 0, 1))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->trace.reversed_mem_access = opt_val;\n\t} else if (strcasecmp(opt_name, \"perfcount\") == 0) {\n\t\tif (!xtensa_cmd_xtopt_legal_val(\"perfcount\", opt_val, 0, 8))\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\txtensa->core_config->debug.perfcount_num = opt_val;\n\t} else {\n\t\tLOG_WARNING(\"Unknown xtensa command ignored: \\\"xtopt %s %s\\\"\", CMD_ARGV[0], CMD_ARGV[1]);\n\t\treturn ERROR_OK;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtopt)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtopt_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* xtmem <type> [parameters] */\nCOMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa)\n{\n\tstruct xtensa_cache_config *cachep = NULL;\n\tstruct xtensa_local_mem_config *memp = NULL;\n\tint mem_access = 0;\n\tbool is_dcache = false;\n\n\tif (CMD_ARGC == 0) {\n\t\tLOG_ERROR(\"xtmem <type> [parameters]\\n\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tconst char *mem_name = CMD_ARGV[0];\n\tif (strcasecmp(mem_name, \"icache\") == 0) {\n\t\tcachep = &xtensa->core_config->icache;\n\t} else if (strcasecmp(mem_name, \"dcache\") == 0) {\n\t\tcachep = &xtensa->core_config->dcache;\n\t\tis_dcache = true;\n\t} else if (strcasecmp(mem_name, \"l2cache\") == 0) {\n\t\t/* TODO: support L2 cache */\n\t} else if (strcasecmp(mem_name, \"l2addr\") == 0) {\n\t\t/* TODO: support L2 cache */\n\t} else if (strcasecmp(mem_name, \"iram\") == 0) {\n\t\tmemp = &xtensa->core_config->iram;\n\t\tmem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;\n\t} else if (strcasecmp(mem_name, \"dram\") == 0) {\n\t\tmemp = &xtensa->core_config->dram;\n\t\tmem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;\n\t} else if (strcasecmp(mem_name, \"sram\") == 0) {\n\t\tmemp = &xtensa->core_config->sram;\n\t\tmem_access = XT_MEM_ACCESS_READ | XT_MEM_ACCESS_WRITE;\n\t} else if (strcasecmp(mem_name, \"irom\") == 0) {\n\t\tmemp = &xtensa->core_config->irom;\n\t\tmem_access = XT_MEM_ACCESS_READ;\n\t} else if (strcasecmp(mem_name, \"drom\") == 0) {\n\t\tmemp = &xtensa->core_config->drom;\n\t\tmem_access = XT_MEM_ACCESS_READ;\n\t} else if (strcasecmp(mem_name, \"srom\") == 0) {\n\t\tmemp = &xtensa->core_config->srom;\n\t\tmem_access = XT_MEM_ACCESS_READ;\n\t} else {\n\t\tLOG_ERROR(\"xtmem types: <icache|dcache|l2cache|l2addr|iram|irom|dram|drom|sram|srom>\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (cachep) {\n\t\tif ((CMD_ARGC != 4) && (CMD_ARGC != 5)) {\n\t\t\tLOG_ERROR(\"xtmem <cachetype> <linebytes> <cachebytes> <ways> [writeback]\\n\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tcachep->line_size = strtoul(CMD_ARGV[1], NULL, 0);\n\t\tcachep->size = strtoul(CMD_ARGV[2], NULL, 0);\n\t\tcachep->way_count = strtoul(CMD_ARGV[3], NULL, 0);\n\t\tcachep->writeback = ((CMD_ARGC == 5) && is_dcache) ?\n\t\t\tstrtoul(CMD_ARGV[4], NULL, 0) : 0;\n\t} else if (memp) {\n\t\tif (CMD_ARGC != 3) {\n\t\t\tLOG_ERROR(\"xtmem <memtype> <baseaddr> <bytes>\\n\");\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tstruct xtensa_local_mem_region_config *memcfgp = &memp->regions[memp->count];\n\t\tmemcfgp->base = strtoul(CMD_ARGV[1], NULL, 0);\n\t\tmemcfgp->size = strtoul(CMD_ARGV[2], NULL, 0);\n\t\tmemcfgp->access = mem_access;\n\t\tmemp->count++;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtmem)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmem_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* xtmpu <num FG seg> <min seg size> <lockable> <executeonly> */\nCOMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC != 4) {\n\t\tLOG_ERROR(\"xtmpu <num FG seg> <min seg size> <lockable> <executeonly>\\n\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tunsigned int nfgseg = strtoul(CMD_ARGV[0], NULL, 0);\n\tunsigned int minsegsize = strtoul(CMD_ARGV[1], NULL, 0);\n\tunsigned int lockable = strtoul(CMD_ARGV[2], NULL, 0);\n\tunsigned int execonly = strtoul(CMD_ARGV[3], NULL, 0);\n\n\tif ((nfgseg > 32)) {\n\t\tLOG_ERROR(\"<nfgseg> must be within [0..32]\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t} else if (minsegsize & (minsegsize - 1)) {\n\t\tLOG_ERROR(\"<minsegsize> must be a power of 2 >= 32\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t} else if (lockable > 1) {\n\t\tLOG_ERROR(\"<lockable> must be 0 or 1\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t} else if (execonly > 1) {\n\t\tLOG_ERROR(\"<execonly> must be 0 or 1\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\txtensa->core_config->mpu.enabled = true;\n\txtensa->core_config->mpu.nfgseg = nfgseg;\n\txtensa->core_config->mpu.minsegsize = minsegsize;\n\txtensa->core_config->mpu.lockable = lockable;\n\txtensa->core_config->mpu.execonly = execonly;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtmpu)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmpu_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56> */\nCOMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC != 2) {\n\t\tLOG_ERROR(\"xtmmu <NIREFILLENTRIES> <NDREFILLENTRIES>\\n\");\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\tunsigned int nirefillentries = strtoul(CMD_ARGV[0], NULL, 0);\n\tunsigned int ndrefillentries = strtoul(CMD_ARGV[1], NULL, 0);\n\tif ((nirefillentries != 16) && (nirefillentries != 32)) {\n\t\tLOG_ERROR(\"<nirefillentries> must be 16 or 32\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t} else if ((ndrefillentries != 16) && (ndrefillentries != 32)) {\n\t\tLOG_ERROR(\"<ndrefillentries> must be 16 or 32\\n\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\txtensa->core_config->mmu.enabled = true;\n\txtensa->core_config->mmu.itlb_entries_count = nirefillentries;\n\txtensa->core_config->mmu.dtlb_entries_count = ndrefillentries;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtmmu)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtmmu_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* xtregs <numregs>\n * xtreg <regname> <regnum> */\nCOMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC == 1) {\n\t\tint32_t numregs = strtoul(CMD_ARGV[0], NULL, 0);\n\t\tif ((numregs <= 0) || (numregs > UINT16_MAX)) {\n\t\t\tLOG_ERROR(\"xtreg <numregs>: Invalid 'numregs' (%d)\", numregs);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\tif ((xtensa->genpkt_regs_num > 0) && (numregs < (int32_t)xtensa->genpkt_regs_num)) {\n\t\t\tLOG_ERROR(\"xtregs (%d) must be larger than numgenregs (%d) (if xtregfmt specified)\",\n\t\t\t\tnumregs, xtensa->genpkt_regs_num);\n\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t}\n\t\txtensa->total_regs_num = numregs;\n\t\txtensa->core_regs_num = 0;\n\t\txtensa->num_optregs = 0;\n\t\t/* A little more memory than required, but saves a second initialization pass */\n\t\txtensa->optregs = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc));\n\t\tif (!xtensa->optregs) {\n\t\t\tLOG_ERROR(\"Failed to allocate xtensa->optregs!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t\treturn ERROR_OK;\n\t} else if (CMD_ARGC != 2) {\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t}\n\n\t/* \"xtregfmt contiguous\" must be specified prior to the first \"xtreg\" definition\n\t * if general register (g-packet) requests or contiguous register maps are supported */\n\tif (xtensa->regmap_contiguous && !xtensa->contiguous_regs_desc) {\n\t\txtensa->contiguous_regs_desc = calloc(xtensa->total_regs_num, sizeof(struct xtensa_reg_desc *));\n\t\tif (!xtensa->contiguous_regs_desc) {\n\t\t\tLOG_ERROR(\"Failed to allocate xtensa->contiguous_regs_desc!\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tconst char *regname = CMD_ARGV[0];\n\tunsigned int regnum = strtoul(CMD_ARGV[1], NULL, 0);\n\tif (regnum > UINT16_MAX) {\n\t\tLOG_ERROR(\"<regnum> must be a 16-bit number\");\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif ((xtensa->num_optregs + xtensa->core_regs_num) >= xtensa->total_regs_num) {\n\t\tif (xtensa->total_regs_num)\n\t\t\tLOG_ERROR(\"'xtreg %s 0x%04x': Too many registers (%d expected, %d core %d extended)\",\n\t\t\t\tregname, regnum,\n\t\t\t\txtensa->total_regs_num, xtensa->core_regs_num, xtensa->num_optregs);\n\t\telse\n\t\t\tLOG_ERROR(\"'xtreg %s 0x%04x': Number of registers unspecified\",\n\t\t\t\tregname, regnum);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Determine whether register belongs in xtensa_regs[] or xtensa->xtensa_spec_regs[] */\n\tstruct xtensa_reg_desc *rptr = &xtensa->optregs[xtensa->num_optregs];\n\tbool is_extended_reg = true;\n\tunsigned int ridx;\n\tfor (ridx = 0; ridx < XT_NUM_REGS; ridx++) {\n\t\tif (strcmp(CMD_ARGV[0], xtensa_regs[ridx].name) == 0) {\n\t\t\t/* Flag core register as defined */\n\t\t\trptr = &xtensa_regs[ridx];\n\t\t\txtensa->core_regs_num++;\n\t\t\tis_extended_reg = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\trptr->exist = true;\n\tif (is_extended_reg) {\n\t\t/* Register ID, debugger-visible register ID */\n\t\trptr->name = strdup(CMD_ARGV[0]);\n\t\trptr->dbreg_num = regnum;\n\t\trptr->reg_num = (regnum & XT_REG_INDEX_MASK);\n\t\txtensa->num_optregs++;\n\n\t\t/* Register type */\n\t\tif ((regnum & XT_REG_GENERAL_MASK) == XT_REG_GENERAL_VAL) {\n\t\t\trptr->type = XT_REG_GENERAL;\n\t\t} else if ((regnum & XT_REG_USER_MASK) == XT_REG_USER_VAL) {\n\t\t\trptr->type = XT_REG_USER;\n\t\t} else if ((regnum & XT_REG_FR_MASK) == XT_REG_FR_VAL) {\n\t\t\trptr->type = XT_REG_FR;\n\t\t} else if ((regnum & XT_REG_SPECIAL_MASK) == XT_REG_SPECIAL_VAL) {\n\t\t\trptr->type = XT_REG_SPECIAL;\n\t\t} else if ((regnum & XT_REG_RELGEN_MASK) == XT_REG_RELGEN_VAL) {\n\t\t\t/* WARNING: For these registers, regnum points to the\n\t\t\t * index of the corresponding ARx registers, NOT to\n\t\t\t * the processor register number! */\n\t\t\trptr->type = XT_REG_RELGEN;\n\t\t\trptr->reg_num += XT_REG_IDX_ARFIRST;\n\t\t\trptr->dbreg_num += XT_REG_IDX_ARFIRST;\n\t\t} else if ((regnum & XT_REG_TIE_MASK) != 0) {\n\t\t\trptr->type = XT_REG_TIE;\n\t\t} else {\n\t\t\trptr->type = XT_REG_OTHER;\n\t\t}\n\n\t\t/* Register flags */\n\t\tif ((strcmp(rptr->name, \"mmid\") == 0) || (strcmp(rptr->name, \"eraccess\") == 0) ||\n\t\t\t(strcmp(rptr->name, \"ddr\") == 0) || (strcmp(rptr->name, \"intset\") == 0) ||\n\t\t\t(strcmp(rptr->name, \"intclear\") == 0))\n\t\t\trptr->flags = XT_REGF_NOREAD;\n\t\telse\n\t\t\trptr->flags = 0;\n\n\t\tif (rptr->reg_num == (XT_EPS_REG_NUM_BASE + xtensa->core_config->debug.irq_level) &&\n\t\t\txtensa->core_config->core_type == XT_LX && rptr->type == XT_REG_SPECIAL) {\n\t\t\txtensa->eps_dbglevel_idx = XT_NUM_REGS + xtensa->num_optregs - 1;\n\t\t\tLOG_DEBUG(\"Setting PS (%s) index to %d\", rptr->name, xtensa->eps_dbglevel_idx);\n\t\t}\n\t\tif (xtensa->core_config->core_type == XT_NX) {\n\t\t\tenum xtensa_nx_reg_idx idx = XT_NX_REG_IDX_NUM;\n\t\t\tif (strcmp(rptr->name, \"ibreakc0\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_IBREAKC0;\n\t\t\telse if (strcmp(rptr->name, \"wb\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_WB;\n\t\t\telse if (strcmp(rptr->name, \"ms\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_MS;\n\t\t\telse if (strcmp(rptr->name, \"ievec\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_IEVEC;\n\t\t\telse if (strcmp(rptr->name, \"ieextern\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_IEEXTERN;\n\t\t\telse if (strcmp(rptr->name, \"mesr\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_MESR;\n\t\t\telse if (strcmp(rptr->name, \"mesrclr\") == 0)\n\t\t\t\tidx = XT_NX_REG_IDX_MESRCLR;\n\t\t\tif (idx < XT_NX_REG_IDX_NUM) {\n\t\t\t\tif (xtensa->nx_reg_idx[idx] != 0) {\n\t\t\t\t\tLOG_ERROR(\"nx_reg_idx[%d] previously set to %d\",\n\t\t\t\t\t\tidx, xtensa->nx_reg_idx[idx]);\n\t\t\t\t\treturn ERROR_FAIL;\n\t\t\t\t}\n\t\t\t\txtensa->nx_reg_idx[idx] = XT_NUM_REGS + xtensa->num_optregs - 1;\n\t\t\t\tLOG_DEBUG(\"NX reg %s: index %d (%d)\",\n\t\t\t\t\trptr->name, xtensa->nx_reg_idx[idx], idx);\n\t\t\t}\n\t\t}\n\t} else if (strcmp(rptr->name, \"cpenable\") == 0) {\n\t\txtensa->core_config->coproc = true;\n\t}\n\n\t/* Build out list of contiguous registers in specified order */\n\tunsigned int running_reg_count = xtensa->num_optregs + xtensa->core_regs_num;\n\tif (xtensa->contiguous_regs_desc) {\n\t\tassert((running_reg_count <= xtensa->total_regs_num) && \"contiguous register address internal error!\");\n\t\txtensa->contiguous_regs_desc[running_reg_count - 1] = rptr;\n\t}\n\tif (xtensa_extra_debug_log)\n\t\tLOG_DEBUG(\"Added %s register %-16s: 0x%04x/0x%02x t%d (%d of %d)\",\n\t\t\tis_extended_reg ? \"config-specific\" : \"core\",\n\t\t\trptr->name, rptr->dbreg_num, rptr->reg_num, rptr->type,\n\t\t\tis_extended_reg ? xtensa->num_optregs : ridx,\n\t\t\tis_extended_reg ? xtensa->total_regs_num : XT_NUM_REGS);\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtreg)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtreg_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* xtregfmt <contiguous|sparse> [numgregs] */\nCOMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa)\n{\n\tif ((CMD_ARGC == 1) || (CMD_ARGC == 2)) {\n\t\tif (!strcasecmp(CMD_ARGV[0], \"sparse\")) {\n\t\t\treturn ERROR_OK;\n\t\t} else if (!strcasecmp(CMD_ARGV[0], \"contiguous\")) {\n\t\t\txtensa->regmap_contiguous = true;\n\t\t\tif (CMD_ARGC == 2) {\n\t\t\t\tunsigned int numgregs = strtoul(CMD_ARGV[1], NULL, 0);\n\t\t\t\tif ((numgregs <= 0) ||\n\t\t\t\t\t((numgregs > xtensa->total_regs_num) &&\n\t\t\t\t\t(xtensa->total_regs_num > 0))) {\n\t\t\t\t\tLOG_ERROR(\"xtregfmt: if specified, numgregs (%d) must be <= numregs (%d)\",\n\t\t\t\t\t\tnumgregs, xtensa->total_regs_num);\n\t\t\t\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\t\t\t\t}\n\t\t\t\txtensa->genpkt_regs_num = numgregs;\n\t\t\t}\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\treturn ERROR_COMMAND_SYNTAX_ERROR;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_xtregfmt)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_xtregfmt_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nCOMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa)\n{\n\treturn CALL_COMMAND_HANDLER(handle_command_parse_bool,\n\t\t&xtensa->permissive_mode, \"xtensa permissive mode\");\n}\n\nCOMMAND_HANDLER(xtensa_cmd_permissive_mode)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_permissive_mode_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* perfmon_enable <counter_id> <select> [mask] [kernelcnt] [tracelevel] */\nCOMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa)\n{\n\tstruct xtensa_perfmon_config config = {\n\t\t.mask = 0xffff,\n\t\t.kernelcnt = 0,\n\t\t.tracelevel = -1\t/* use DEBUGLEVEL by default */\n\t};\n\n\tif (CMD_ARGC < 2 || CMD_ARGC > 6)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tunsigned int counter_id = strtoul(CMD_ARGV[0], NULL, 0);\n\tif (counter_id >= XTENSA_MAX_PERF_COUNTERS) {\n\t\tcommand_print(CMD, \"counter_id should be < %d\", XTENSA_MAX_PERF_COUNTERS);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tconfig.select = strtoul(CMD_ARGV[1], NULL, 0);\n\tif (config.select > XTENSA_MAX_PERF_SELECT) {\n\t\tcommand_print(CMD, \"select should be < %d\", XTENSA_MAX_PERF_SELECT);\n\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t}\n\n\tif (CMD_ARGC >= 3) {\n\t\tconfig.mask = strtoul(CMD_ARGV[2], NULL, 0);\n\t\tif (config.mask > XTENSA_MAX_PERF_MASK) {\n\t\t\tcommand_print(CMD, \"mask should be < %d\", XTENSA_MAX_PERF_MASK);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (CMD_ARGC >= 4) {\n\t\tconfig.kernelcnt = strtoul(CMD_ARGV[3], NULL, 0);\n\t\tif (config.kernelcnt > 1) {\n\t\t\tcommand_print(CMD, \"kernelcnt should be 0 or 1\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (CMD_ARGC >= 5) {\n\t\tconfig.tracelevel = strtoul(CMD_ARGV[4], NULL, 0);\n\t\tif (config.tracelevel > 7) {\n\t\t\tcommand_print(CMD, \"tracelevel should be <=7\");\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tif (config.tracelevel == -1)\n\t\tconfig.tracelevel = xtensa->core_config->debug.irq_level;\n\n\treturn xtensa_dm_perfmon_enable(&xtensa->dbg_mod, counter_id, &config);\n}\n\nCOMMAND_HANDLER(xtensa_cmd_perfmon_enable)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_enable_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\n/* perfmon_dump [counter_id] */\nCOMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tint counter_id = -1;\n\tif (CMD_ARGC == 1) {\n\t\tcounter_id = strtol(CMD_ARGV[0], NULL, 0);\n\t\tif (counter_id > XTENSA_MAX_PERF_COUNTERS) {\n\t\t\tcommand_print(CMD, \"counter_id should be < %d\", XTENSA_MAX_PERF_COUNTERS);\n\t\t\treturn ERROR_COMMAND_ARGUMENT_INVALID;\n\t\t}\n\t}\n\n\tunsigned int counter_start = (counter_id < 0) ? 0 : counter_id;\n\tunsigned int counter_end = (counter_id < 0) ? XTENSA_MAX_PERF_COUNTERS : counter_id + 1;\n\tfor (unsigned int counter = counter_start; counter < counter_end; ++counter) {\n\t\tchar result_buf[128] = { 0 };\n\t\tsize_t result_pos = snprintf(result_buf, sizeof(result_buf), \"Counter %d: \", counter);\n\t\tstruct xtensa_perfmon_result result;\n\t\tint res = xtensa_dm_perfmon_dump(&xtensa->dbg_mod, counter, &result);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t\tsnprintf(result_buf + result_pos, sizeof(result_buf) - result_pos,\n\t\t\t\"%-12\" PRIu64 \"%s\",\n\t\t\tresult.value,\n\t\t\tresult.overflow ? \" (overflow)\" : \"\");\n\t\tLOG_INFO(\"%s\", result_buf);\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_perfmon_dump)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_perfmon_dump_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nCOMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa)\n{\n\tint state = -1;\n\n\tif (CMD_ARGC < 1) {\n\t\tconst char *st;\n\t\tstate = xtensa->stepping_isr_mode;\n\t\tif (state == XT_STEPPING_ISR_ON)\n\t\t\tst = \"OFF\";\n\t\telse if (state == XT_STEPPING_ISR_OFF)\n\t\t\tst = \"ON\";\n\t\telse\n\t\t\tst = \"UNKNOWN\";\n\t\tcommand_print(CMD, \"Current ISR step mode: %s\", st);\n\t\treturn ERROR_OK;\n\t}\n\n\tif (xtensa->core_config->core_type == XT_NX) {\n\t\tcommand_print(CMD, \"ERROR: ISR step mode only supported on Xtensa LX\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Masking is ON -> interrupts during stepping are OFF, and vice versa */\n\tif (!strcasecmp(CMD_ARGV[0], \"off\"))\n\t\tstate = XT_STEPPING_ISR_ON;\n\telse if (!strcasecmp(CMD_ARGV[0], \"on\"))\n\t\tstate = XT_STEPPING_ISR_OFF;\n\n\tif (state == -1) {\n\t\tcommand_print(CMD, \"Argument unknown. Please pick one of ON, OFF\");\n\t\treturn ERROR_FAIL;\n\t}\n\txtensa->stepping_isr_mode = state;\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_mask_interrupts)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_mask_interrupts_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nCOMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target)\n{\n\tint res;\n\tuint32_t val = 0;\n\n\tif (CMD_ARGC >= 1) {\n\t\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\t\tif (!strcasecmp(CMD_ARGV[0], \"none\")) {\n\t\t\t\tval = 0;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"BreakIn\")) {\n\t\t\t\tval |= OCDDCR_BREAKINEN;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"BreakOut\")) {\n\t\t\t\tval |= OCDDCR_BREAKOUTEN;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"RunStallIn\")) {\n\t\t\t\tval |= OCDDCR_RUNSTALLINEN;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"DebugModeOut\")) {\n\t\t\t\tval |= OCDDCR_DEBUGMODEOUTEN;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"BreakInOut\")) {\n\t\t\t\tval |= OCDDCR_BREAKINEN | OCDDCR_BREAKOUTEN;\n\t\t\t} else if (!strcasecmp(CMD_ARGV[i], \"RunStall\")) {\n\t\t\t\tval |= OCDDCR_RUNSTALLINEN | OCDDCR_DEBUGMODEOUTEN;\n\t\t\t} else {\n\t\t\t\tcommand_print(CMD, \"Unknown arg %s\", CMD_ARGV[i]);\n\t\t\t\tcommand_print(\n\t\t\t\t\tCMD,\n\t\t\t\t\t\"use either BreakInOut, None or RunStall as arguments, or any combination of BreakIn, BreakOut, RunStallIn and DebugModeOut.\");\n\t\t\t\treturn ERROR_OK;\n\t\t\t}\n\t\t}\n\t\tres = xtensa_smpbreak_set(target, val);\n\t\tif (res != ERROR_OK)\n\t\t\tcommand_print(CMD, \"Failed to set smpbreak config %d\", res);\n\t} else {\n\t\tstruct xtensa *xtensa = target_to_xtensa(target);\n\t\tres = xtensa_smpbreak_read(xtensa, &val);\n\t\tif (res == ERROR_OK)\n\t\t\tcommand_print(CMD, \"Current bits set:%s%s%s%s\",\n\t\t\t\t(val & OCDDCR_BREAKINEN) ? \" BreakIn\" : \"\",\n\t\t\t\t(val & OCDDCR_BREAKOUTEN) ? \" BreakOut\" : \"\",\n\t\t\t\t(val & OCDDCR_RUNSTALLINEN) ? \" RunStallIn\" : \"\",\n\t\t\t\t(val & OCDDCR_DEBUGMODEOUTEN) ? \" DebugModeOut\" : \"\"\n\t\t\t\t);\n\t\telse\n\t\t\tcommand_print(CMD, \"Failed to get smpbreak config %d\", res);\n\t}\n\treturn res;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_smpbreak)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_smpbreak_do,\n\t\tget_current_target(CMD_CTX));\n}\n\nCOMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa)\n{\n\tstruct xtensa_trace_status trace_status;\n\tstruct xtensa_trace_start_config cfg = {\n\t\t.stoppc = 0,\n\t\t.stopmask = XTENSA_STOPMASK_DISABLED,\n\t\t.after = 0,\n\t\t.after_is_words = false\n\t};\n\n\t/* Parse arguments */\n\tfor (unsigned int i = 0; i < CMD_ARGC; i++) {\n\t\tif ((!strcasecmp(CMD_ARGV[i], \"pc\")) && CMD_ARGC > i) {\n\t\t\tchar *e;\n\t\t\ti++;\n\t\t\tcfg.stoppc = strtol(CMD_ARGV[i], &e, 0);\n\t\t\tcfg.stopmask = 0;\n\t\t\tif (*e == '/')\n\t\t\t\tcfg.stopmask = strtol(e, NULL, 0);\n\t\t} else if ((!strcasecmp(CMD_ARGV[i], \"after\")) && CMD_ARGC > i) {\n\t\t\ti++;\n\t\t\tcfg.after = strtol(CMD_ARGV[i], NULL, 0);\n\t\t} else if (!strcasecmp(CMD_ARGV[i], \"ins\")) {\n\t\t\tcfg.after_is_words = 0;\n\t\t} else if (!strcasecmp(CMD_ARGV[i], \"words\")) {\n\t\t\tcfg.after_is_words = 1;\n\t\t} else {\n\t\t\tcommand_print(CMD, \"Did not understand %s\", CMD_ARGV[i]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tint res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tif (trace_status.stat & TRAXSTAT_TRACT) {\n\t\tLOG_WARNING(\"Silently stop active tracing!\");\n\t\tres = xtensa_dm_trace_stop(&xtensa->dbg_mod, false);\n\t\tif (res != ERROR_OK)\n\t\t\treturn res;\n\t}\n\n\tres = xtensa_dm_trace_start(&xtensa->dbg_mod, &cfg);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\txtensa->trace_active = true;\n\tcommand_print(CMD, \"Trace started.\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_tracestart)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracestart_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nCOMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa)\n{\n\tstruct xtensa_trace_status trace_status;\n\n\tint res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (!(trace_status.stat & TRAXSTAT_TRACT)) {\n\t\tcommand_print(CMD, \"No trace is currently active.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = xtensa_dm_trace_stop(&xtensa->dbg_mod, true);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\txtensa->trace_active = false;\n\tcommand_print(CMD, \"Trace stop triggered.\");\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_tracestop)\n{\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracestop_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)));\n}\n\nCOMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname)\n{\n\tstruct xtensa_trace_config trace_config;\n\tstruct xtensa_trace_status trace_status;\n\tuint32_t memsz, wmem;\n\n\tint res = xtensa_dm_trace_status_read(&xtensa->dbg_mod, &trace_status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (trace_status.stat & TRAXSTAT_TRACT) {\n\t\tcommand_print(CMD, \"Tracing is still active. Please stop it first.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tres = xtensa_dm_trace_config_read(&xtensa->dbg_mod, &trace_config);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (!(trace_config.ctrl & TRAXCTRL_TREN)) {\n\t\tcommand_print(CMD, \"No active trace found; nothing to dump.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tmemsz = trace_config.memaddr_end - trace_config.memaddr_start + 1;\n\tLOG_INFO(\"Total trace memory: %d words\", memsz);\n\tif ((trace_config.addr &\n\t\t\t((TRAXADDR_TWRAP_MASK << TRAXADDR_TWRAP_SHIFT) | TRAXADDR_TWSAT)) == 0) {\n\t\t/*Memory hasn't overwritten itself yet. */\n\t\twmem = trace_config.addr & TRAXADDR_TADDR_MASK;\n\t\tLOG_INFO(\"...but trace is only %d words\", wmem);\n\t\tif (wmem < memsz)\n\t\t\tmemsz = wmem;\n\t} else {\n\t\tif (trace_config.addr & TRAXADDR_TWSAT) {\n\t\t\tLOG_INFO(\"Real trace is many times longer than that (overflow)\");\n\t\t} else {\n\t\t\tuint32_t trc_sz = (trace_config.addr >> TRAXADDR_TWRAP_SHIFT) & TRAXADDR_TWRAP_MASK;\n\t\t\ttrc_sz = (trc_sz * memsz) + (trace_config.addr & TRAXADDR_TADDR_MASK);\n\t\t\tLOG_INFO(\"Real trace is %d words, but the start has been truncated.\", trc_sz);\n\t\t}\n\t}\n\n\tuint8_t *tracemem = malloc(memsz * 4);\n\tif (!tracemem) {\n\t\tcommand_print(CMD, \"Failed to alloc memory for trace data!\");\n\t\treturn ERROR_FAIL;\n\t}\n\tres = xtensa_dm_trace_data_read(&xtensa->dbg_mod, tracemem, memsz * 4);\n\tif (res != ERROR_OK) {\n\t\tfree(tracemem);\n\t\treturn res;\n\t}\n\n\tint f = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0666);\n\tif (f <= 0) {\n\t\tfree(tracemem);\n\t\tcommand_print(CMD, \"Unable to open file %s\", fname);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (write(f, tracemem, memsz * 4) != (int)memsz * 4)\n\t\tcommand_print(CMD, \"Unable to write to file %s\", fname);\n\telse\n\t\tcommand_print(CMD, \"Written %d bytes of trace data to %s\", memsz * 4, fname);\n\tclose(f);\n\n\tbool is_all_zeroes = true;\n\tfor (unsigned int i = 0; i < memsz * 4; i++) {\n\t\tif (tracemem[i] != 0) {\n\t\t\tis_all_zeroes = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tfree(tracemem);\n\tif (is_all_zeroes)\n\t\tcommand_print(\n\t\t\tCMD,\n\t\t\t\"WARNING: File written is all zeroes. Are you sure you enabled trace memory?\");\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(xtensa_cmd_tracedump)\n{\n\tif (CMD_ARGC != 1) {\n\t\tcommand_print(CMD, \"Command takes exactly 1 parameter.Need filename to dump to as output!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn CALL_COMMAND_HANDLER(xtensa_cmd_tracedump_do,\n\t\ttarget_to_xtensa(get_current_target(CMD_CTX)), CMD_ARGV[0]);\n}\n\nstatic const struct command_registration xtensa_any_command_handlers[] = {\n\t{\n\t\t.name = \"xtdef\",\n\t\t.handler = xtensa_cmd_xtdef,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa core type\",\n\t\t.usage = \"<type>\",\n\t},\n\t{\n\t\t.name = \"xtopt\",\n\t\t.handler = xtensa_cmd_xtopt,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa core option\",\n\t\t.usage = \"<name> <value>\",\n\t},\n\t{\n\t\t.name = \"xtmem\",\n\t\t.handler = xtensa_cmd_xtmem,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa memory/cache option\",\n\t\t.usage = \"<type> [parameters]\",\n\t},\n\t{\n\t\t.name = \"xtmmu\",\n\t\t.handler = xtensa_cmd_xtmmu,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa MMU option\",\n\t\t.usage = \"<NIREFILLENTRIES> <NDREFILLENTRIES> <IVARWAY56> <DVARWAY56>\",\n\t},\n\t{\n\t\t.name = \"xtmpu\",\n\t\t.handler = xtensa_cmd_xtmpu,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa MPU option\",\n\t\t.usage = \"<num FG seg> <min seg size> <lockable> <executeonly>\",\n\t},\n\t{\n\t\t.name = \"xtreg\",\n\t\t.handler = xtensa_cmd_xtreg,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure Xtensa register\",\n\t\t.usage = \"<regname> <regnum>\",\n\t},\n\t{\n\t\t.name = \"xtregs\",\n\t\t.handler = xtensa_cmd_xtreg,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure number of Xtensa registers\",\n\t\t.usage = \"<numregs>\",\n\t},\n\t{\n\t\t.name = \"xtregfmt\",\n\t\t.handler = xtensa_cmd_xtregfmt,\n\t\t.mode = COMMAND_CONFIG,\n\t\t.help = \"Configure format of Xtensa register map\",\n\t\t.usage = \"<contiguous|sparse> [numgregs]\",\n\t},\n\t{\n\t\t.name = \"set_permissive\",\n\t\t.handler = xtensa_cmd_permissive_mode,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"When set to 1, enable Xtensa permissive mode (fewer client-side checks)\",\n\t\t.usage = \"[0|1]\",\n\t},\n\t{\n\t\t.name = \"maskisr\",\n\t\t.handler = xtensa_cmd_mask_interrupts,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"mask Xtensa interrupts at step\",\n\t\t.usage = \"['on'|'off']\",\n\t},\n\t{\n\t\t.name = \"smpbreak\",\n\t\t.handler = xtensa_cmd_smpbreak,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Set the way the CPU chains OCD breaks\",\n\t\t.usage = \"[none|breakinout|runstall] | [BreakIn] [BreakOut] [RunStallIn] [DebugModeOut]\",\n\t},\n\t{\n\t\t.name = \"perfmon_enable\",\n\t\t.handler = xtensa_cmd_perfmon_enable,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Enable and start performance counter\",\n\t\t.usage = \"<counter_id> <select> [mask] [kernelcnt] [tracelevel]\",\n\t},\n\t{\n\t\t.name = \"perfmon_dump\",\n\t\t.handler = xtensa_cmd_perfmon_dump,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Dump performance counter value. If no argument specified, dumps all counters.\",\n\t\t.usage = \"[counter_id]\",\n\t},\n\t{\n\t\t.name = \"tracestart\",\n\t\t.handler = xtensa_cmd_tracestart,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help =\n\t\t\t\"Tracing: Set up and start a trace. Optionally set stop trigger address and amount of data captured after.\",\n\t\t.usage = \"[pc <pcval>/[maskbitcount]] [after <n> [ins|words]]\",\n\t},\n\t{\n\t\t.name = \"tracestop\",\n\t\t.handler = xtensa_cmd_tracestop,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Tracing: Stop current trace as started by the tracestart command\",\n\t\t.usage = \"\",\n\t},\n\t{\n\t\t.name = \"tracedump\",\n\t\t.handler = xtensa_cmd_tracedump,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Tracing: Dump trace memory to a files. One file per core.\",\n\t\t.usage = \"<outfile>\",\n\t},\n\t{\n\t\t.name = \"exe\",\n\t\t.handler = xtensa_cmd_exe,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Xtensa stub execution\",\n\t\t.usage = \"<ascii-encoded hexadecimal instruction bytes>\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nconst struct command_registration xtensa_command_handlers[] = {\n\t{\n\t\t.name = \"xtensa\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Xtensa command group\",\n\t\t.usage = \"\",\n\t\t.chain = xtensa_any_command_handlers,\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Generic Xtensa target                                                 *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_H\n#define OPENOCD_TARGET_XTENSA_H\n\n#include \"assert.h\"\n#include <target/target.h>\n#include <target/breakpoints.h>\n#include \"xtensa_regs.h\"\n#include \"xtensa_debug_module.h\"\n\n/**\n * @file\n * Holds the interface to Xtensa cores.\n */\n\n/* Big-endian vs. little-endian detection */\n#define XT_ISBE(X)                              ((X)->target->endianness == TARGET_BIG_ENDIAN)\n\n/* 24-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */\n#define XT_INS_BREAK_LE(S, T)                   (0x004000 | (((S) & 0xF) << 8) | (((T) & 0xF) << 4))\n#define XT_INS_BREAK_BE(S, T)                   (0x000400 | (((S) & 0xF) << 12) | ((T) & 0xF))\n#define XT_INS_BREAK(X, S, T)                   (XT_ISBE(X) ? XT_INS_BREAK_BE(S, T) : XT_INS_BREAK_LE(S, T))\n\n/* 16-bit break; BE version field-swapped then byte-swapped for use in memory R/W fns */\n#define XT_INS_BREAKN_LE(IMM4)                  (0xF02D | (((IMM4) & 0xF) << 8))\n#define XT_INS_BREAKN_BE(IMM4)                  (0x0FD2 | (((IMM4) & 0xF) << 12))\n#define XT_INS_BREAKN(X, IMM4)                  (XT_ISBE(X) ? XT_INS_BREAKN_BE(IMM4) : XT_INS_BREAKN_LE(IMM4))\n\n#define XT_ISNS_SZ_MAX                          3\n\n/* PS register bits (LX) */\n#define XT_PS_RING(_v_)                         ((uint32_t)((_v_) & 0x3) << 6)\n#define XT_PS_RING_MSK                          (0x3 << 6)\n#define XT_PS_RING_GET(_v_)                     (((_v_) >> 6) & 0x3)\n#define XT_PS_CALLINC_MSK                       (0x3 << 16)\n#define XT_PS_OWB_MSK                           (0xF << 8)\n#define XT_PS_WOE_MSK                           BIT(18)\n\n/* PS register bits (NX) */\n#define XT_PS_DIEXC_MSK                         BIT(2)\n\n/* MS register bits (NX) */\n#define XT_MS_DE_MSK                            BIT(5)\n#define XT_MS_DISPST_MSK                        (0x1f)\n#define XT_MS_DISPST_DBG                        (0x10)\n\n/* WB register bits (NX) */\n#define XT_WB_P_SHIFT                           (0)\n#define XT_WB_P_MSK                             (0x7U << XT_WB_P_SHIFT)\n#define XT_WB_C_SHIFT                           (4)\n#define XT_WB_C_MSK                             (0x7U << XT_WB_C_SHIFT)\n#define XT_WB_N_SHIFT                           (8)\n#define XT_WB_N_MSK                             (0x7U << XT_WB_N_SHIFT)\n#define XT_WB_S_SHIFT                           (30)\n#define XT_WB_S_MSK                             (0x3U << XT_WB_S_SHIFT)\n\n/* IBREAKC register bits (NX) */\n#define XT_IBREAKC_FB                           (0x80000000)\n\n/* Definitions for imprecise exception registers (NX) */\n#define XT_IMPR_EXC_MSK                         (0x00000013)\n#define XT_MESRCLR_IMPR_EXC_MSK                 (0x00000090)\n\n#define XT_LOCAL_MEM_REGIONS_NUM_MAX            8\n\n#define XT_AREGS_NUM_MAX                        64\n#define XT_USER_REGS_NUM_MAX                    256\n\n#define XT_MEM_ACCESS_NONE                      0x0\n#define XT_MEM_ACCESS_READ                      0x1\n#define XT_MEM_ACCESS_WRITE                     0x2\n\n#define XT_MAX_TIE_REG_WIDTH                    (512)\t/* TIE register file max 4096 bits */\n#define XT_QUERYPKT_RESP_MAX                    (XT_MAX_TIE_REG_WIDTH * 2 + 1)\n\nenum xtensa_qerr_e {\n\tXT_QERR_INTERNAL = 0,\n\tXT_QERR_FAIL,\n\tXT_QERR_INVAL,\n\tXT_QERR_MEM,\n\tXT_QERR_NUM,\n};\n\n/* An and ARn registers potentially used as scratch regs */\nenum xtensa_ar_scratch_set_e {\n\tXT_AR_SCRATCH_A3 = 0,\n\tXT_AR_SCRATCH_AR3,\n\tXT_AR_SCRATCH_A4,\n\tXT_AR_SCRATCH_AR4,\n\tXT_AR_SCRATCH_NUM\n};\n\nstruct xtensa_keyval_info_s {\n\tchar *chrval;\n\tint intval;\n};\n\nenum xtensa_type {\n\tXT_UNDEF = 0,\n\tXT_LX,\n\tXT_NX,\n};\n\nstruct xtensa_cache_config {\n\tuint8_t way_count;\n\tuint32_t line_size;\n\tuint32_t size;\n\tint writeback;\n};\n\nstruct xtensa_local_mem_region_config {\n\ttarget_addr_t base;\n\tuint32_t size;\n\tint access;\n};\n\nstruct xtensa_local_mem_config {\n\tuint16_t count;\n\tstruct xtensa_local_mem_region_config regions[XT_LOCAL_MEM_REGIONS_NUM_MAX];\n};\n\nstruct xtensa_mmu_config {\n\tbool enabled;\n\tuint8_t itlb_entries_count;\n\tuint8_t dtlb_entries_count;\n};\n\nstruct xtensa_mpu_config {\n\tbool enabled;\n\tuint8_t nfgseg;\n\tuint32_t minsegsize;\n\tbool lockable;\n\tbool execonly;\n};\n\nstruct xtensa_irq_config {\n\tbool enabled;\n\tuint8_t irq_num;\n};\n\nstruct xtensa_high_prio_irq_config {\n\tbool enabled;\n\tuint8_t level_num;\n\tuint8_t excm_level;\n};\n\nstruct xtensa_debug_config {\n\tbool enabled;\n\tuint8_t irq_level;\n\tuint8_t ibreaks_num;\n\tuint8_t dbreaks_num;\n\tuint8_t perfcount_num;\n};\n\nstruct xtensa_tracing_config {\n\tbool enabled;\n\tuint32_t mem_sz;\n\tbool reversed_mem_access;\n};\n\nstruct xtensa_config {\n\tenum xtensa_type core_type;\n\tuint8_t aregs_num;\n\tbool windowed;\n\tbool coproc;\n\tbool exceptions;\n\tstruct xtensa_irq_config irq;\n\tstruct xtensa_high_prio_irq_config high_irq;\n\tstruct xtensa_mmu_config mmu;\n\tstruct xtensa_mpu_config mpu;\n\tstruct xtensa_debug_config debug;\n\tstruct xtensa_tracing_config trace;\n\tstruct xtensa_cache_config icache;\n\tstruct xtensa_cache_config dcache;\n\tstruct xtensa_local_mem_config irom;\n\tstruct xtensa_local_mem_config iram;\n\tstruct xtensa_local_mem_config drom;\n\tstruct xtensa_local_mem_config dram;\n\tstruct xtensa_local_mem_config sram;\n\tstruct xtensa_local_mem_config srom;\n};\n\ntypedef uint32_t xtensa_insn_t;\n\nenum xtensa_stepping_isr_mode {\n\tXT_STEPPING_ISR_OFF,\t/* interrupts are disabled during stepping */\n\tXT_STEPPING_ISR_ON,\t\t/* interrupts are enabled during stepping */\n};\n\nenum xtensa_nx_reg_idx {\n\tXT_NX_REG_IDX_IBREAKC0 = 0,\n\tXT_NX_REG_IDX_WB,\n\tXT_NX_REG_IDX_MS,\n\tXT_NX_REG_IDX_IEVEC,\t\t/* IEVEC, IEEXTERN, and MESR must be contiguous */\n\tXT_NX_REG_IDX_IEEXTERN,\n\tXT_NX_REG_IDX_MESR,\n\tXT_NX_REG_IDX_MESRCLR,\n\tXT_NX_REG_IDX_NUM\n};\n\n/* Only supported in cores with in-CPU MMU. None of Espressif chips as of now. */\nenum xtensa_mode {\n\tXT_MODE_RING0,\n\tXT_MODE_RING1,\n\tXT_MODE_RING2,\n\tXT_MODE_RING3,\n\tXT_MODE_ANY\t/* special value to run algorithm in current core mode */\n};\n\nstruct xtensa_sw_breakpoint {\n\tstruct breakpoint *oocd_bp;\n\t/* original insn */\n\tuint8_t insn[XT_ISNS_SZ_MAX];\n\t/* original insn size */\n\tuint8_t insn_sz;\t/* 2 or 3 bytes */\n};\n\n#define XTENSA_COMMON_MAGIC 0x54E4E555U\n\n/**\n * Represents a generic Xtensa core.\n */\nstruct xtensa {\n\tunsigned int common_magic;\n\tstruct xtensa_chip_common *xtensa_chip;\n\tstruct xtensa_config *core_config;\n\tstruct xtensa_debug_module dbg_mod;\n\tstruct reg_cache *core_cache;\n\tunsigned int total_regs_num;\n\tunsigned int core_regs_num;\n\tbool regmap_contiguous;\n\tunsigned int genpkt_regs_num;\n\tstruct xtensa_reg_desc **contiguous_regs_desc;\n\tstruct reg **contiguous_regs_list;\n\t/* Per-config Xtensa registers as specified via \"xtreg\" in xtensa-core*.cfg */\n\tstruct xtensa_reg_desc *optregs;\n\tunsigned int num_optregs;\n\tstruct reg *empty_regs;\n\tchar qpkt_resp[XT_QUERYPKT_RESP_MAX];\n\t/* An array of pointers to buffers to backup registers' values while algo is run on target.\n\t * Size is 'regs_num'. */\n\tvoid **algo_context_backup;\n\tunsigned int eps_dbglevel_idx;\n\tunsigned int dbregs_num;\n\tstruct target *target;\n\tbool reset_asserted;\n\tenum xtensa_stepping_isr_mode stepping_isr_mode;\n\tstruct breakpoint **hw_brps;\n\tstruct watchpoint **hw_wps;\n\tstruct xtensa_sw_breakpoint *sw_brps;\n\tbool trace_active;\n\tbool permissive_mode;\t/* bypass memory checks */\n\tbool suppress_dsr_errors;\n\tuint32_t smp_break;\n\tuint32_t spill_loc;\n\tunsigned int spill_bytes;\n\tuint8_t *spill_buf;\n\tint8_t probe_lsddr32p;\n\t/* Sometimes debug module's 'powered' bit is cleared after reset, but get set after some\n\t * time.This is the number of polling periods after which core is considered to be powered\n\t * off (marked as unexamined) if the bit retains to be cleared (e.g. if core is disabled by\n\t * SW running on target).*/\n\tuint8_t come_online_probes_num;\n\tbool proc_syscall;\n\tbool halt_request;\n\tuint32_t nx_stop_cause;\n\tuint32_t nx_reg_idx[XT_NX_REG_IDX_NUM];\n\tstruct xtensa_keyval_info_s scratch_ars[XT_AR_SCRATCH_NUM];\n\tbool regs_fetched;\t/* true after first register fetch completed successfully */\n};\n\nstatic inline struct xtensa *target_to_xtensa(struct target *target)\n{\n\tassert(target);\n\tstruct xtensa *xtensa = target->arch_info;\n\tassert(xtensa->common_magic == XTENSA_COMMON_MAGIC);\n\treturn xtensa;\n}\n\nint xtensa_init_arch_info(struct target *target,\n\tstruct xtensa *xtensa,\n\tconst struct xtensa_debug_module_config *dm_cfg);\nint xtensa_target_init(struct command_context *cmd_ctx, struct target *target);\nvoid xtensa_target_deinit(struct target *target);\n\nstatic inline bool xtensa_addr_in_mem(const struct xtensa_local_mem_config *mem, uint32_t addr)\n{\n\tfor (unsigned int i = 0; i < mem->count; i++) {\n\t\tif (addr >= mem->regions[i].base &&\n\t\t\taddr < mem->regions[i].base + mem->regions[i].size)\n\t\t\treturn true;\n\t}\n\treturn false;\n}\n\nstatic inline bool xtensa_data_addr_valid(struct target *target, uint32_t addr)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\n\tif (xtensa_addr_in_mem(&xtensa->core_config->drom, addr))\n\t\treturn true;\n\tif (xtensa_addr_in_mem(&xtensa->core_config->dram, addr))\n\t\treturn true;\n\tif (xtensa_addr_in_mem(&xtensa->core_config->sram, addr))\n\t\treturn true;\n\treturn false;\n}\n\nstatic inline int xtensa_queue_dbg_reg_read(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint8_t *data)\n{\n\tstruct xtensa_debug_module *dm = &xtensa->dbg_mod;\n\n\tif (!xtensa->core_config->trace.enabled &&\n\t\t(reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {\n\t\tLOG_ERROR(\"Can not access %u reg when Trace Port option disabled!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn dm->dbg_ops->queue_reg_read(dm, reg, data);\n}\n\nstatic inline int xtensa_queue_dbg_reg_write(struct xtensa *xtensa, enum xtensa_dm_reg reg, uint32_t data)\n{\n\tstruct xtensa_debug_module *dm = &xtensa->dbg_mod;\n\n\tif (!xtensa->core_config->trace.enabled &&\n\t\t(reg <= XDMREG_MEMADDREND || (reg >= XDMREG_PMG && reg <= XDMREG_PMSTAT7))) {\n\t\tLOG_ERROR(\"Can not access %u reg when Trace Port option disabled!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn dm->dbg_ops->queue_reg_write(dm, reg, data);\n}\n\nstatic inline int xtensa_core_status_clear(struct target *target, uint32_t bits)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\treturn xtensa_dm_core_status_clear(&xtensa->dbg_mod, bits);\n}\n\nint xtensa_core_status_check(struct target *target);\n\nint xtensa_examine(struct target *target);\nint xtensa_wakeup(struct target *target);\nint xtensa_smpbreak_set(struct target *target, uint32_t set);\nint xtensa_smpbreak_get(struct target *target, uint32_t *val);\nint xtensa_smpbreak_write(struct xtensa *xtensa, uint32_t set);\nint xtensa_smpbreak_read(struct xtensa *xtensa, uint32_t *val);\nxtensa_reg_val_t xtensa_reg_get(struct target *target, enum xtensa_reg_id reg_id);\nvoid xtensa_reg_set(struct target *target, enum xtensa_reg_id reg_id, xtensa_reg_val_t value);\nvoid xtensa_reg_set_deep_relgen(struct target *target, enum xtensa_reg_id a_idx, xtensa_reg_val_t value);\nint xtensa_fetch_all_regs(struct target *target);\nint xtensa_get_gdb_reg_list(struct target *target,\n\tstruct reg **reg_list[],\n\tint *reg_list_size,\n\tenum target_register_class reg_class);\nuint32_t xtensa_cause_get(struct target *target);\nvoid xtensa_cause_clear(struct target *target);\nvoid xtensa_cause_reset(struct target *target);\nint xtensa_poll(struct target *target);\nvoid xtensa_on_poll(struct target *target);\nint xtensa_halt(struct target *target);\nint xtensa_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution);\nint xtensa_prepare_resume(struct target *target,\n\tint current,\n\ttarget_addr_t address,\n\tint handle_breakpoints,\n\tint debug_execution);\nint xtensa_do_resume(struct target *target);\nint xtensa_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);\nint xtensa_do_step(struct target *target, int current, target_addr_t address, int handle_breakpoints);\nint xtensa_mmu_is_enabled(struct target *target, int *enabled);\nint xtensa_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer);\nint xtensa_read_buffer(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer);\nint xtensa_write_memory(struct target *target,\n\ttarget_addr_t address,\n\tuint32_t size,\n\tuint32_t count,\n\tconst uint8_t *buffer);\nint xtensa_write_buffer(struct target *target, target_addr_t address, uint32_t count, const uint8_t *buffer);\nint xtensa_checksum_memory(struct target *target, target_addr_t address, uint32_t count, uint32_t *checksum);\nint xtensa_assert_reset(struct target *target);\nint xtensa_deassert_reset(struct target *target);\nint xtensa_soft_reset_halt(struct target *target);\nint xtensa_breakpoint_add(struct target *target, struct breakpoint *breakpoint);\nint xtensa_breakpoint_remove(struct target *target, struct breakpoint *breakpoint);\nint xtensa_watchpoint_add(struct target *target, struct watchpoint *watchpoint);\nint xtensa_watchpoint_remove(struct target *target, struct watchpoint *watchpoint);\nvoid xtensa_set_permissive_mode(struct target *target, bool state);\nconst char *xtensa_get_gdb_arch(struct target *target);\nint xtensa_gdb_query_custom(struct target *target, const char *packet, char **response_p);\n\nCOMMAND_HELPER(xtensa_cmd_xtdef_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtopt_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtmem_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtmpu_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtmmu_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtreg_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_xtregfmt_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_permissive_mode_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_mask_interrupts_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_smpbreak_do, struct target *target);\nCOMMAND_HELPER(xtensa_cmd_perfmon_dump_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_perfmon_enable_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_tracestart_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_tracestop_do, struct xtensa *xtensa);\nCOMMAND_HELPER(xtensa_cmd_tracedump_do, struct xtensa *xtensa, const char *fname);\n\nextern const struct command_registration xtensa_command_handlers[];\n\n#endif\t/* OPENOCD_TARGET_XTENSA_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_chip.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Xtensa Chip-level Target Support for OpenOCD                          *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"assert.h\"\n#include <target/target.h>\n#include <target/target_type.h>\n#include <target/arm_adi_v5.h>\n#include <rtos/rtos.h>\n#include \"xtensa_chip.h\"\n#include \"xtensa_fileio.h\"\n\nint xtensa_chip_init_arch_info(struct target *target, void *arch_info,\n\tstruct xtensa_debug_module_config *dm_cfg)\n{\n\tstruct xtensa_chip_common *xtensa_chip = (struct xtensa_chip_common *)arch_info;\n\tint ret = xtensa_init_arch_info(target, &xtensa_chip->xtensa, dm_cfg);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\t/* All xtensa target structures point back to original xtensa_chip */\n\txtensa_chip->xtensa.xtensa_chip = arch_info;\n\treturn ERROR_OK;\n}\n\nint xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target)\n{\n\tint ret = xtensa_target_init(cmd_ctx, target);\n\tif (ret != ERROR_OK)\n\t\treturn ret;\n\treturn xtensa_fileio_init(target);\n}\n\nint xtensa_chip_arch_state(struct target *target)\n{\n\treturn ERROR_OK;\n}\n\nstatic int xtensa_chip_poll(struct target *target)\n{\n\tenum target_state old_state = target->state;\n\tint ret = xtensa_poll(target);\n\n\tif (old_state != TARGET_HALTED && target->state == TARGET_HALTED) {\n\t\t/*Call any event callbacks that are applicable */\n\t\tif (old_state == TARGET_DEBUG_RUNNING) {\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);\n\t\t} else {\n\t\t\txtensa_fileio_detect_proc(target);\n\t\t\ttarget_call_event_callbacks(target, TARGET_EVENT_HALTED);\n\t\t}\n\t}\n\n\treturn ret;\n}\n\nstatic int xtensa_chip_virt2phys(struct target *target,\n\ttarget_addr_t virtual, target_addr_t *physical)\n{\n\tif (physical) {\n\t\t*physical = virtual;\n\t\treturn ERROR_OK;\n\t}\n\treturn ERROR_FAIL;\n}\n\nstatic const struct xtensa_debug_ops xtensa_chip_dm_dbg_ops = {\n\t.queue_enable = xtensa_dm_queue_enable,\n\t.queue_reg_read = xtensa_dm_queue_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_reg_write\n};\n\nstatic const struct xtensa_power_ops xtensa_chip_dm_pwr_ops = {\n\t.queue_reg_read = xtensa_dm_queue_pwr_reg_read,\n\t.queue_reg_write = xtensa_dm_queue_pwr_reg_write\n};\n\nstatic int xtensa_chip_target_create(struct target *target, Jim_Interp *interp)\n{\n\tstruct xtensa_debug_module_config xtensa_chip_dm_cfg = {\n\t\t.dbg_ops = &xtensa_chip_dm_dbg_ops,\n\t\t.pwr_ops = &xtensa_chip_dm_pwr_ops,\n\t\t.tap = NULL,\n\t\t.queue_tdi_idle = NULL,\n\t\t.queue_tdi_idle_arg = NULL,\n\t\t.dap = NULL,\n\t\t.debug_ap = NULL,\n\t\t.debug_apsel = DP_APSEL_INVALID,\n\t\t.ap_offset = 0,\n\t};\n\n\tstruct adiv5_private_config *pc = target->private_config;\n\tif (adiv5_verify_config(pc) == ERROR_OK) {\n\t\txtensa_chip_dm_cfg.dap = pc->dap;\n\t\txtensa_chip_dm_cfg.debug_apsel = pc->ap_num;\n\t\txtensa_chip_dm_cfg.ap_offset = target->dbgbase;\n\t\tLOG_DEBUG(\"DAP: ap_num %\" PRId64 \" DAP %p\\n\", pc->ap_num, pc->dap);\n\t} else {\n\t\txtensa_chip_dm_cfg.tap = target->tap;\n\t\tLOG_DEBUG(\"JTAG: %s:%s pos %d\", target->tap->chip, target->tap->tapname,\n\t\t\ttarget->tap->abs_chain_position);\n\t}\n\n\tstruct xtensa_chip_common *xtensa_chip = calloc(1, sizeof(struct xtensa_chip_common));\n\tif (!xtensa_chip) {\n\t\tLOG_ERROR(\"Failed to alloc chip-level memory!\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tint ret = xtensa_chip_init_arch_info(target, xtensa_chip, &xtensa_chip_dm_cfg);\n\tif (ret != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to init arch info!\");\n\t\tfree(xtensa_chip);\n\t\treturn ret;\n\t}\n\n\t/*Assume running target. If different, the first poll will fix this. */\n\ttarget->state = TARGET_RUNNING;\n\ttarget->debug_reason = DBG_REASON_NOTHALTED;\n\treturn ERROR_OK;\n}\n\nstatic void xtensa_chip_target_deinit(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\txtensa_target_deinit(target);\n\tfree(xtensa->xtensa_chip);\n}\n\nstatic int xtensa_chip_examine(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint retval = xtensa_dm_examine(&xtensa->dbg_mod);\n\tif (retval == ERROR_OK)\n\t\tretval = xtensa_examine(target);\n\treturn retval;\n}\n\nstatic int xtensa_chip_jim_configure(struct target *target, struct jim_getopt_info *goi)\n{\n\tstatic bool dap_configured;\n\tint ret = adiv5_jim_configure(target, goi);\n\tif (ret == JIM_OK) {\n\t\tLOG_DEBUG(\"xtensa '-dap' target option found\");\n\t\tdap_configured = true;\n\t}\n\tif (!dap_configured) {\n\t\tLOG_DEBUG(\"xtensa '-dap' target option not yet found, assuming JTAG...\");\n\t\ttarget->has_dap = false;\n\t}\n\treturn ret;\n}\n\n/** Methods for generic example of Xtensa-based chip-level targets. */\nstruct target_type xtensa_chip_target = {\n\t.name = \"xtensa\",\n\n\t.poll = xtensa_chip_poll,\n\t.arch_state = xtensa_chip_arch_state,\n\n\t.halt = xtensa_halt,\n\t.resume = xtensa_resume,\n\t.step = xtensa_step,\n\n\t.assert_reset = xtensa_assert_reset,\n\t.deassert_reset = xtensa_deassert_reset,\n\t.soft_reset_halt = xtensa_soft_reset_halt,\n\n\t.virt2phys = xtensa_chip_virt2phys,\n\t.mmu = xtensa_mmu_is_enabled,\n\t.read_memory = xtensa_read_memory,\n\t.write_memory = xtensa_write_memory,\n\n\t.read_buffer = xtensa_read_buffer,\n\t.write_buffer = xtensa_write_buffer,\n\n\t.checksum_memory = xtensa_checksum_memory,\n\n\t.get_gdb_reg_list = xtensa_get_gdb_reg_list,\n\n\t.add_breakpoint = xtensa_breakpoint_add,\n\t.remove_breakpoint = xtensa_breakpoint_remove,\n\n\t.add_watchpoint = xtensa_watchpoint_add,\n\t.remove_watchpoint = xtensa_watchpoint_remove,\n\n\t.target_create = xtensa_chip_target_create,\n\t.target_jim_configure = xtensa_chip_jim_configure,\n\t.init_target = xtensa_chip_target_init,\n\t.examine = xtensa_chip_examine,\n\t.deinit_target = xtensa_chip_target_deinit,\n\n\t.gdb_query_custom = xtensa_gdb_query_custom,\n\n\t.commands = xtensa_command_handlers,\n\n\t.get_gdb_fileio_info = xtensa_get_gdb_fileio_info,\n\t.gdb_fileio_end = xtensa_gdb_fileio_end,\n};\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_chip.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Xtensa Chip-level Target Support for OpenOCD                          *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_CHIP_H\n#define OPENOCD_TARGET_XTENSA_CHIP_H\n\n#include <target/target.h>\n#include \"xtensa.h\"\n#include \"xtensa_debug_module.h\"\n\nstruct xtensa_chip_common {\n\tstruct xtensa xtensa;\n\t/* Chip-specific extensions can be added here */\n};\n\nstatic inline struct xtensa_chip_common *target_to_xtensa_chip(struct target *target)\n{\n\treturn container_of(target->arch_info, struct xtensa_chip_common, xtensa);\n}\n\nint xtensa_chip_init_arch_info(struct target *target, void *arch_info,\n\tstruct xtensa_debug_module_config *dm_cfg);\nint xtensa_chip_target_init(struct command_context *cmd_ctx, struct target *target);\nint xtensa_chip_arch_state(struct target *target);\nvoid xtensa_chip_queue_tdi_idle(struct target *target);\nvoid xtensa_chip_on_reset(struct target *target);\nbool xtensa_chip_on_halt(struct target *target);\nvoid xtensa_chip_on_poll(struct target *target);\n\n#endif\t/* OPENOCD_TARGET_XTENSA_CHIP_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_debug_module.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Xtensa Debug Module (XDM) Support for OpenOCD                         *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <helper/align.h>\n#include \"xtensa_debug_module.h\"\n\n#define TAPINS_PWRCTL           0x08\n#define TAPINS_PWRSTAT          0x09\n#define TAPINS_NARSEL           0x1C\n#define TAPINS_IDCODE           0x1E\n#define TAPINS_BYPASS           0x1F\n\n#define TAPINS_PWRCTL_LEN       8\n#define TAPINS_PWRSTAT_LEN      8\n#define TAPINS_NARSEL_ADRLEN    8\n#define TAPINS_NARSEL_DATALEN   32\n#define TAPINS_IDCODE_LEN       32\n#define TAPINS_BYPASS_LEN       1\n\n/* Table of power register offsets for APB space */\nstatic const struct xtensa_dm_pwr_reg_offsets xdm_pwr_regs[XDMREG_PWRNUM] =\n\tXTENSA_DM_PWR_REG_OFFSETS;\n\n/* Table of debug register offsets for Nexus and APB space */\nstatic const struct xtensa_dm_reg_offsets xdm_regs[XDMREG_NUM] =\n\tXTENSA_DM_REG_OFFSETS;\n\nstatic void xtensa_dm_add_set_ir(struct xtensa_debug_module *dm, uint8_t value)\n{\n\tstruct scan_field field;\n\tuint8_t t[4] = { 0, 0, 0, 0 };\n\n\tmemset(&field, 0, sizeof(field));\n\tfield.num_bits = dm->tap->ir_length;\n\tfield.out_value = t;\n\tbuf_set_u32(t, 0, field.num_bits, value);\n\tjtag_add_ir_scan(dm->tap, &field, TAP_IDLE);\n}\n\nstatic void xtensa_dm_add_dr_scan(struct xtensa_debug_module *dm,\n\tint len,\n\tconst uint8_t *src,\n\tuint8_t *dest,\n\ttap_state_t endstate)\n{\n\tstruct scan_field field;\n\n\tmemset(&field, 0, sizeof(field));\n\tfield.num_bits = len;\n\tfield.out_value = src;\n\tfield.in_value = dest;\n\tjtag_add_dr_scan(dm->tap, 1, &field, endstate);\n}\n\nint xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg)\n{\n\tif (!dm || !cfg)\n\t\treturn ERROR_FAIL;\n\tif (!IS_ALIGNED(cfg->ap_offset, XTENSA_DM_APB_ALIGN)) {\n\t\tLOG_ERROR(\"Xtensa DM APB offset must be aligned to a %dKB multiple\",\n\t\t\tXTENSA_DM_APB_ALIGN / 1024);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tdm->pwr_ops = cfg->pwr_ops;\n\tdm->dbg_ops = cfg->dbg_ops;\n\tdm->tap = cfg->tap;\n\tdm->queue_tdi_idle = cfg->queue_tdi_idle;\n\tdm->queue_tdi_idle_arg = cfg->queue_tdi_idle_arg;\n\tdm->dap = cfg->dap;\n\tdm->debug_ap = cfg->debug_ap;\n\tdm->debug_apsel = cfg->debug_apsel;\n\tdm->ap_offset = cfg->ap_offset;\n\treturn ERROR_OK;\n}\n\nvoid xtensa_dm_deinit(struct xtensa_debug_module *dm)\n{\n\tif (dm->debug_ap) {\n\t\tdap_put_ap(dm->debug_ap);\n\t\tdm->debug_ap = NULL;\n\t}\n}\n\nint xtensa_dm_poll(struct xtensa_debug_module *dm)\n{\n\t/* Check if debug_ap is available to prevent segmentation fault.\n\t * If the re-examination after an error does not find a MEM-AP\n\t * (e.g. the target stopped communicating), debug_ap pointer\n\t * can suddenly become NULL.\n\t */\n\treturn (!dm || (dm->dap && !dm->debug_ap)) ? ERROR_FAIL : ERROR_OK;\n}\n\nint xtensa_dm_examine(struct xtensa_debug_module *dm)\n{\n\tstruct adiv5_dap *swjdp = dm->dap;\n\tint retval = ERROR_OK;\n\n\tif (swjdp) {\n\t\tLOG_DEBUG(\"DM examine: DAP AP select %d\", dm->debug_apsel);\n\t\tif (dm->debug_ap) {\n\t\t\tdap_put_ap(dm->debug_ap);\n\t\t\tdm->debug_ap = NULL;\n\t\t}\n\t\tif (dm->debug_apsel == DP_APSEL_INVALID) {\n\t\t\tLOG_DEBUG(\"DM examine: search for APB-type MEM-AP...\");\n\t\t\t/* TODO: Determine whether AP_TYPE_AXI_AP APs can be supported... */\n\t\t\tretval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &dm->debug_ap);\n\t\t\tif (retval != ERROR_OK) {\n\t\t\t\tLOG_ERROR(\"Could not find MEM-AP to control the core\");\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t} else {\n\t\t\tdm->debug_ap = dap_get_ap(swjdp, dm->debug_apsel);\n\t\t}\n\n\t\t/* TODO: Allow a user-specified AP instead of relying on AP_TYPE_APB_AP */\n\t\tdm->debug_apsel = dm->debug_ap->ap_num;\n\t\tLOG_DEBUG(\"DM examine: Setting apsel to %d\", dm->debug_apsel);\n\n\t\t/* Leave (only) generic DAP stuff for debugport_init(); */\n\t\tdm->debug_ap->memaccess_tck = 8;\n\n\t\tretval = mem_ap_init(dm->debug_ap);\n\t\tif (retval != ERROR_OK) {\n\t\t\tLOG_ERROR(\"MEM-AP init failed: %d\", retval);\n\t\t\treturn retval;\n\t\t}\n\n\t\t/* TODO: how to set autoincrement range? Hard-code it to 1024 bytes for now */\n\t\tdm->debug_ap->tar_autoincr_block = (1 << 10);\n\t}\n\n\treturn retval;\n}\n\nint xtensa_dm_queue_enable(struct xtensa_debug_module *dm)\n{\n\treturn dm->dbg_ops->queue_reg_write(dm, XDMREG_DCRSET, OCDDCR_ENABLEOCD);\n}\n\nint xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value)\n{\n\tif (reg >= XDMREG_NUM) {\n\t\tLOG_ERROR(\"Invalid DBG reg ID %d!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (dm->dap)\n\t\t/* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with\n\t\t * queued reads, but requires an API change to pass value as a 32-bit pointer.\n\t\t */\n\t\treturn mem_ap_read_buf(dm->debug_ap, value, 4, 1, xdm_regs[reg].apb + dm->ap_offset);\n\tuint8_t regdata = (xdm_regs[reg].nar << 1) | 0;\n\tuint8_t dummy[4] = { 0, 0, 0, 0 };\n\txtensa_dm_add_set_ir(dm, TAPINS_NARSEL);\n\txtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, &regdata, NULL, TAP_IDLE);\n\txtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, dummy, value, TAP_IDLE);\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value)\n{\n\tif (reg >= XDMREG_NUM) {\n\t\tLOG_ERROR(\"Invalid DBG reg ID %d!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (dm->dap)\n\t\treturn mem_ap_write_u32(dm->debug_ap, xdm_regs[reg].apb + dm->ap_offset, value);\n\tuint8_t regdata = (xdm_regs[reg].nar << 1) | 1;\n\tuint8_t valdata[] = { value, value >> 8, value >> 16, value >> 24 };\n\txtensa_dm_add_set_ir(dm, TAPINS_NARSEL);\n\txtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_ADRLEN, &regdata, NULL, TAP_IDLE);\n\txtensa_dm_add_dr_scan(dm, TAPINS_NARSEL_DATALEN, valdata, NULL, TAP_IDLE);\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,\n\tenum xtensa_dm_pwr_reg reg,\n\tuint8_t *data,\n\tuint32_t clear)\n{\n\tif (reg >= XDMREG_PWRNUM) {\n\t\tLOG_ERROR(\"Invalid PWR reg ID %d!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (dm->dap) {\n\t\t/* NOTE: Future optimization: mem_ap_read_u32() offers higher performance with\n\t\t * queued reads, but requires an API change to pass value as a 32-bit pointer.\n\t\t */\n\t\tuint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;\n\t\tint retval = mem_ap_read_buf(dm->debug_ap, data, 4, 1, apbreg);\n\t\tif (retval == ERROR_OK)\n\t\t\tretval = mem_ap_write_u32(dm->debug_ap, apbreg, clear);\n\t\treturn retval;\n\t}\n\tuint8_t value_clr = (uint8_t)clear;\n\tuint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;\n\tint tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;\n\txtensa_dm_add_set_ir(dm, tap_insn);\n\txtensa_dm_add_dr_scan(dm, tap_insn_sz, &value_clr, data, TAP_IDLE);\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,\n\tenum xtensa_dm_pwr_reg reg,\n\tuint32_t data)\n{\n\tif (reg >= XDMREG_PWRNUM) {\n\t\tLOG_ERROR(\"Invalid PWR reg ID %d!\", reg);\n\t\treturn ERROR_FAIL;\n\t}\n\tif (dm->dap) {\n\t\tuint32_t apbreg = xdm_pwr_regs[reg].apb + dm->ap_offset;\n\t\treturn mem_ap_write_u32(dm->debug_ap, apbreg, data);\n\t}\n\tuint8_t tap_insn = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL : TAPINS_PWRSTAT;\n\tint tap_insn_sz = (reg == XDMREG_PWRCTL) ? TAPINS_PWRCTL_LEN : TAPINS_PWRSTAT_LEN;\n\tuint8_t value = (uint8_t)data;\n\txtensa_dm_add_set_ir(dm, tap_insn);\n\txtensa_dm_add_dr_scan(dm, tap_insn_sz, &value, NULL, TAP_IDLE);\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_device_id_read(struct xtensa_debug_module *dm)\n{\n\tuint8_t id_buf[sizeof(uint32_t)];\n\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tdm->device_id = buf_get_u32(id_buf, 0, 32);\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear)\n{\n\tuint8_t stat_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };\n\tuint8_t stath_buf[sizeof(uint32_t)] = { 0, 0, 0, 0 };\n\n\t/* TODO: JTAG does not work when PWRCTL_JTAGDEBUGUSE is not set.\n\t * It is set in xtensa_examine(), need to move reading of XDMREG_OCDID out of this function */\n\t/* dm->dbg_ops->queue_reg_read(dm, XDMREG_OCDID, id_buf);\n\t *Read reset state */\n\tdm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stat_buf, clear);\n\tdm->pwr_ops->queue_reg_read(dm, XDMREG_PWRSTAT, stath_buf, clear);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tdm->power_status.stat = buf_get_u32(stat_buf, 0, 32);\n\tdm->power_status.stath = buf_get_u32(stath_buf, 0, 32);\n\treturn res;\n}\n\nint xtensa_dm_core_status_read(struct xtensa_debug_module *dm)\n{\n\tuint8_t dsr_buf[sizeof(uint32_t)];\n\n\txtensa_dm_queue_enable(dm);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_DSR, dsr_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\tdm->core_status.dsr = buf_get_u32(dsr_buf, 0, 32);\n\treturn res;\n}\n\nint xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits)\n{\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_DSR, bits);\n\txtensa_dm_queue_tdi_idle(dm);\n\treturn xtensa_dm_queue_execute(dm);\n}\n\nint xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg)\n{\n\t/*Turn off trace unit so we can start a new trace. */\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, 0);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/*Set up parameters */\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXADDR, 0);\n\tif (cfg->stopmask != XTENSA_STOPMASK_DISABLED) {\n\t\tdm->dbg_ops->queue_reg_write(dm, XDMREG_PCMATCHCTRL,\n\t\t\t(cfg->stopmask << PCMATCHCTRL_PCML_SHIFT));\n\t\tdm->dbg_ops->queue_reg_write(dm, XDMREG_TRIGGERPC, cfg->stoppc);\n\t}\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_DELAYCNT, cfg->after);\n\t/*Options are mostly hardcoded for now. ToDo: make this more configurable. */\n\tdm->dbg_ops->queue_reg_write(\n\t\tdm,\n\t\tXDMREG_TRAXCTRL,\n\t\tTRAXCTRL_TREN |\n\t\t((cfg->stopmask != XTENSA_STOPMASK_DISABLED) ? TRAXCTRL_PCMEN : 0) | TRAXCTRL_TMEN |\n\t\t(cfg->after_is_words ? 0 : TRAXCTRL_CNTU) | (0 << TRAXCTRL_SMPER_SHIFT) | TRAXCTRL_PTOWS);\n\txtensa_dm_queue_tdi_idle(dm);\n\treturn xtensa_dm_queue_execute(dm);\n}\n\nint xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable)\n{\n\tuint8_t traxctl_buf[sizeof(uint32_t)];\n\tuint32_t traxctl;\n\tstruct xtensa_trace_status trace_status;\n\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\ttraxctl = buf_get_u32(traxctl_buf, 0, 32);\n\n\tif (!pto_enable)\n\t\ttraxctl &= ~(TRAXCTRL_PTOWS | TRAXCTRL_PTOWT);\n\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_TRAXCTRL, traxctl | TRAXCTRL_TRSTP);\n\txtensa_dm_queue_tdi_idle(dm);\n\tres = xtensa_dm_queue_execute(dm);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\t/*Check current status of trace hardware */\n\tres = xtensa_dm_trace_status_read(dm, &trace_status);\n\tif (res != ERROR_OK)\n\t\treturn res;\n\n\tif (trace_status.stat & TRAXSTAT_TRACT) {\n\t\tLOG_ERROR(\"Failed to stop tracing (0x%x)!\", trace_status.stat);\n\t\treturn ERROR_FAIL;\n\t}\n\treturn ERROR_OK;\n}\n\nint xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status)\n{\n\tuint8_t traxstat_buf[sizeof(uint32_t)];\n\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXSTAT, traxstat_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res == ERROR_OK && status)\n\t\tstatus->stat = buf_get_u32(traxstat_buf, 0, 32);\n\treturn res;\n}\n\nint xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config)\n{\n\tuint8_t traxctl_buf[sizeof(uint32_t)];\n\tuint8_t memadrstart_buf[sizeof(uint32_t)];\n\tuint8_t memadrend_buf[sizeof(uint32_t)];\n\tuint8_t adr_buf[sizeof(uint32_t)];\n\n\tif (!config)\n\t\treturn ERROR_FAIL;\n\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXCTRL, traxctl_buf);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDRSTART, memadrstart_buf);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_MEMADDREND, memadrend_buf);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXADDR, adr_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res == ERROR_OK) {\n\t\tconfig->ctrl = buf_get_u32(traxctl_buf, 0, 32);\n\t\tconfig->memaddr_start = buf_get_u32(memadrstart_buf, 0, 32);\n\t\tconfig->memaddr_end = buf_get_u32(memadrend_buf, 0, 32);\n\t\tconfig->addr = buf_get_u32(adr_buf, 0, 32);\n\t}\n\treturn res;\n}\n\nint xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size)\n{\n\tif (!dest)\n\t\treturn ERROR_FAIL;\n\n\tfor (unsigned int i = 0; i < size / 4; i++)\n\t\tdm->dbg_ops->queue_reg_read(dm, XDMREG_TRAXDATA, &dest[i * 4]);\n\txtensa_dm_queue_tdi_idle(dm);\n\treturn xtensa_dm_queue_execute(dm);\n}\n\nint xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,\n\tconst struct xtensa_perfmon_config *config)\n{\n\tif (!config)\n\t\treturn ERROR_FAIL;\n\n\tuint8_t pmstat_buf[4];\n\tuint32_t pmctrl = ((config->tracelevel) << 4) +\n\t\t(config->select << 8) +\n\t\t(config->mask << 16) +\n\t\t(config->kernelcnt << 3);\n\n\t/* enable performance monitor */\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_PMG, 0x1);\n\t/* reset counter */\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_PM0 + counter_id, 0);\n\tdm->dbg_ops->queue_reg_write(dm, XDMREG_PMCTRL0 + counter_id, pmctrl);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\treturn xtensa_dm_queue_execute(dm);\n}\n\nint xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,\n\tstruct xtensa_perfmon_result *out_result)\n{\n\tuint8_t pmstat_buf[4];\n\tuint8_t pmcount_buf[4];\n\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_PMSTAT0 + counter_id, pmstat_buf);\n\tdm->dbg_ops->queue_reg_read(dm, XDMREG_PM0 + counter_id, pmcount_buf);\n\txtensa_dm_queue_tdi_idle(dm);\n\tint res = xtensa_dm_queue_execute(dm);\n\tif (res == ERROR_OK) {\n\t\tuint32_t stat = buf_get_u32(pmstat_buf, 0, 32);\n\t\tuint64_t result = buf_get_u32(pmcount_buf, 0, 32);\n\n\t\t/* TODO: if counter # counter_id+1 has 'select' set to 1, use its value as the\n\t\t* high 32 bits of the counter. */\n\t\tif (out_result) {\n\t\t\tout_result->overflow = ((stat & 1) != 0);\n\t\t\tout_result->value = result;\n\t\t}\n\t}\n\n\treturn res;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_debug_module.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Xtensa Debug Module (XDM) Support for OpenOCD                         *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n *   Copyright (C) 2019 Espressif Systems Ltd.                             *\n *   Derived from original ESP8266 target.                                 *\n *   Author: Angus Gratton gus@projectgus.com                              *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H\n#define OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H\n\n#include <jtag/jtag.h>\n#include <target/arm_adi_v5.h>\n#include <helper/bits.h>\n#include <target/target.h>\n\n/* Virtual IDs for using with xtensa_power_ops API */\nenum xtensa_dm_pwr_reg {\n\tXDMREG_PWRCTL = 0x00,\n\tXDMREG_PWRSTAT,\n\tXDMREG_PWRNUM\n};\n\n/* Debug Module Power Register offsets within APB */\nstruct xtensa_dm_pwr_reg_offsets {\n\tuint16_t apb;\n};\n\n/* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */\n#define XTENSA_DM_PWR_REG_OFFSETS\t{\t\t\t\t\\\n\t/* Power/Reset Registers */\t\t\t\t\t\t\\\n\t{ .apb = 0x3020 },\t\t/* XDMREG_PWRCTL */\t\t\\\n\t{ .apb = 0x3024 },\t\t/* XDMREG_PWRSTAT */\t\\\n}\n\n/*\n From the manual:\n To properly use Debug registers through JTAG, software must ensure that:\n - Tap is out of reset\n - Xtensa Debug Module is out of reset\n - Other bits of PWRCTL are set to their desired values, and finally\n - JtagDebugUse transitions from 0 to 1\n The bit must continue to be 1 in order for JTAG accesses to the Debug\n Module to happen correctly. When it is set, any write to this bit clears it.\n Either don't access it, or re-write it to 1 so JTAG accesses continue.\n*/\n#define PWRCTL_JTAGDEBUGUSE(x)\t\t(((x)->dbg_mod.dap) ? (0)     : BIT(7))\n#define PWRCTL_DEBUGRESET(x)\t\t(((x)->dbg_mod.dap) ? BIT(28) : BIT(6))\n#define PWRCTL_CORERESET(x)\t\t\t(((x)->dbg_mod.dap) ? BIT(16) : BIT(4))\n#define PWRCTL_DEBUGWAKEUP(x)\t\t(((x)->dbg_mod.dap) ? BIT(12) : BIT(2))\n#define PWRCTL_MEMWAKEUP(x)\t\t\t(((x)->dbg_mod.dap) ? BIT(8)  : BIT(1))\n#define PWRCTL_COREWAKEUP(x)\t\t(((x)->dbg_mod.dap) ? BIT(0)  : BIT(0))\n\n#define PWRSTAT_DEBUGWASRESET_DM(d)\t(((d)->dap) ? BIT(28) : BIT(6))\n#define PWRSTAT_COREWASRESET_DM(d)\t(((d)->dap) ? BIT(16) : BIT(4))\n#define PWRSTAT_DEBUGWASRESET(x)\t(PWRSTAT_DEBUGWASRESET_DM(&((x)->dbg_mod)))\n#define PWRSTAT_COREWASRESET(x)\t\t(PWRSTAT_COREWASRESET_DM(&((x)->dbg_mod)))\n#define PWRSTAT_CORESTILLNEEDED(x)\t(((x)->dbg_mod.dap) ? BIT(4)  : BIT(3))\n#define PWRSTAT_DEBUGDOMAINON(x)\t(((x)->dbg_mod.dap) ? BIT(12) : BIT(2))\n#define PWRSTAT_MEMDOMAINON(x)\t\t(((x)->dbg_mod.dap) ? BIT(8)  : BIT(1))\n#define PWRSTAT_COREDOMAINON(x)\t\t(((x)->dbg_mod.dap) ? BIT(0)  : BIT(0))\n\n/* Virtual IDs for using with xtensa_debug_ops API */\nenum xtensa_dm_reg {\n\t/* TRAX Registers */\n\tXDMREG_TRAXID = 0x00,\n\tXDMREG_TRAXCTRL,\n\tXDMREG_TRAXSTAT,\n\tXDMREG_TRAXDATA,\n\tXDMREG_TRAXADDR,\n\tXDMREG_TRIGGERPC,\n\tXDMREG_PCMATCHCTRL,\n\tXDMREG_DELAYCNT,\n\tXDMREG_MEMADDRSTART,\n\tXDMREG_MEMADDREND,\n\n\t/* Performance Monitor Registers */\n\tXDMREG_PMG,\n\tXDMREG_INTPC,\n\tXDMREG_PM0,\n\tXDMREG_PM1,\n\tXDMREG_PM2,\n\tXDMREG_PM3,\n\tXDMREG_PM4,\n\tXDMREG_PM5,\n\tXDMREG_PM6,\n\tXDMREG_PM7,\n\tXDMREG_PMCTRL0,\n\tXDMREG_PMCTRL1,\n\tXDMREG_PMCTRL2,\n\tXDMREG_PMCTRL3,\n\tXDMREG_PMCTRL4,\n\tXDMREG_PMCTRL5,\n\tXDMREG_PMCTRL6,\n\tXDMREG_PMCTRL7,\n\tXDMREG_PMSTAT0,\n\tXDMREG_PMSTAT1,\n\tXDMREG_PMSTAT2,\n\tXDMREG_PMSTAT3,\n\tXDMREG_PMSTAT4,\n\tXDMREG_PMSTAT5,\n\tXDMREG_PMSTAT6,\n\tXDMREG_PMSTAT7,\n\n\t/* OCD Registers */\n\tXDMREG_OCDID,\n\tXDMREG_DCRCLR,\n\tXDMREG_DCRSET,\n\tXDMREG_DSR,\n\tXDMREG_DDR,\n\tXDMREG_DDREXEC,\n\tXDMREG_DIR0EXEC,\n\tXDMREG_DIR0,\n\tXDMREG_DIR1,\n\tXDMREG_DIR2,\n\tXDMREG_DIR3,\n\tXDMREG_DIR4,\n\tXDMREG_DIR5,\n\tXDMREG_DIR6,\n\tXDMREG_DIR7,\n\n\t/* Misc Registers */\n\tXDMREG_ERISTAT,\n\n\t/* CoreSight Registers */\n\tXDMREG_ITCTRL,\n\tXDMREG_CLAIMSET,\n\tXDMREG_CLAIMCLR,\n\tXDMREG_LOCKACCESS,\n\tXDMREG_LOCKSTATUS,\n\tXDMREG_AUTHSTATUS,\n\tXDMREG_DEVID,\n\tXDMREG_DEVTYPE,\n\tXDMREG_PERID4,\n\tXDMREG_PERID5,\n\tXDMREG_PERID6,\n\tXDMREG_PERID7,\n\tXDMREG_PERID0,\n\tXDMREG_PERID1,\n\tXDMREG_PERID2,\n\tXDMREG_PERID3,\n\tXDMREG_COMPID0,\n\tXDMREG_COMPID1,\n\tXDMREG_COMPID2,\n\tXDMREG_COMPID3,\n\n\tXDMREG_NUM\n};\n\n/* Debug Module Register offsets within Nexus (NAR) or APB */\nstruct xtensa_dm_reg_offsets {\n\tuint8_t  nar;\n\tuint16_t apb;\n};\n\n/* Debug Module Register offset structure; must include XDMREG_NUM entries */\n#define XTENSA_DM_REG_OFFSETS\t{\t\t\t\t\t\t\t\t\\\n\t/* TRAX Registers */\t\t\t\t\t\t\t\t\t\t\\\n\t{ .nar = 0x00, .apb = 0x0000 },\t/* XDMREG_TRAXID */\t\t\t\\\n\t{ .nar = 0x01, .apb = 0x0004 },\t/* XDMREG_TRAXCTRL */\t\t\\\n\t{ .nar = 0x02, .apb = 0x0008 },\t/* XDMREG_TRAXSTAT */\t\t\\\n\t{ .nar = 0x03, .apb = 0x000c },\t/* XDMREG_TRAXDATA */\t\t\\\n\t{ .nar = 0x04, .apb = 0x0010 },\t/* XDMREG_TRAXADDR */\t\t\\\n\t{ .nar = 0x05, .apb = 0x0014 },\t/* XDMREG_TRIGGERPC */\t\t\\\n\t{ .nar = 0x06, .apb = 0x0018 },\t/* XDMREG_PCMATCHCTRL */\t\\\n\t{ .nar = 0x07, .apb = 0x001c },\t/* XDMREG_DELAYCNT */\t\t\\\n\t{ .nar = 0x08, .apb = 0x0020 },\t/* XDMREG_MEMADDRSTART */\t\\\n\t{ .nar = 0x09, .apb = 0x0024 },\t/* XDMREG_MEMADDREND */\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t/* Performance Monitor Registers */\t\t\t\t\t\t\t\\\n\t{ .nar = 0x20, .apb = 0x1000 },\t/* XDMREG_PMG */\t\t\t\\\n\t{ .nar = 0x24, .apb = 0x1010 },\t/* XDMREG_INTPC */\t\t\t\\\n\t{ .nar = 0x28, .apb = 0x1080 },\t/* XDMREG_PM0 */\t\t\t\\\n\t{ .nar = 0x29, .apb = 0x1084 },\t/* XDMREG_PM1 */\t\t\t\\\n\t{ .nar = 0x2a, .apb = 0x1088 },\t/* XDMREG_PM2 */\t\t\t\\\n\t{ .nar = 0x2b, .apb = 0x108c },\t/* XDMREG_PM3 */\t\t\t\\\n\t{ .nar = 0x2c, .apb = 0x1090 },\t/* XDMREG_PM4 */\t\t\t\\\n\t{ .nar = 0x2d, .apb = 0x1094 },\t/* XDMREG_PM5 */\t\t\t\\\n\t{ .nar = 0x2e, .apb = 0x1098 },\t/* XDMREG_PM6 */\t\t\t\\\n\t{ .nar = 0x2f, .apb = 0x109c },\t/* XDMREG_PM7 */\t\t\t\\\n\t{ .nar = 0x30, .apb = 0x1100 },\t/* XDMREG_PMCTRL0 */\t\t\\\n\t{ .nar = 0x31, .apb = 0x1104 },\t/* XDMREG_PMCTRL1 */\t\t\\\n\t{ .nar = 0x32, .apb = 0x1108 },\t/* XDMREG_PMCTRL2 */\t\t\\\n\t{ .nar = 0x33, .apb = 0x110c },\t/* XDMREG_PMCTRL3 */\t\t\\\n\t{ .nar = 0x34, .apb = 0x1110 },\t/* XDMREG_PMCTRL4 */\t\t\\\n\t{ .nar = 0x35, .apb = 0x1114 },\t/* XDMREG_PMCTRL5 */\t\t\\\n\t{ .nar = 0x36, .apb = 0x1118 },\t/* XDMREG_PMCTRL6 */\t\t\\\n\t{ .nar = 0x37, .apb = 0x111c },\t/* XDMREG_PMCTRL7 */\t\t\\\n\t{ .nar = 0x38, .apb = 0x1180 },\t/* XDMREG_PMSTAT0 */\t\t\\\n\t{ .nar = 0x39, .apb = 0x1184 },\t/* XDMREG_PMSTAT1 */\t\t\\\n\t{ .nar = 0x3a, .apb = 0x1188 },\t/* XDMREG_PMSTAT2 */\t\t\\\n\t{ .nar = 0x3b, .apb = 0x118c },\t/* XDMREG_PMSTAT3 */\t\t\\\n\t{ .nar = 0x3c, .apb = 0x1190 },\t/* XDMREG_PMSTAT4 */\t\t\\\n\t{ .nar = 0x3d, .apb = 0x1194 },\t/* XDMREG_PMSTAT5 */\t\t\\\n\t{ .nar = 0x3e, .apb = 0x1198 },\t/* XDMREG_PMSTAT6 */\t\t\\\n\t{ .nar = 0x3f, .apb = 0x119c },\t/* XDMREG_PMSTAT7 */\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t/* OCD Registers */\t\t\t\t\t\t\t\t\t\t\t\\\n\t{ .nar = 0x40, .apb = 0x2000 },\t/* XDMREG_OCDID */\t\t\t\\\n\t{ .nar = 0x42, .apb = 0x2008 },\t/* XDMREG_DCRCLR */\t\t\t\\\n\t{ .nar = 0x43, .apb = 0x200c },\t/* XDMREG_DCRSET */\t\t\t\\\n\t{ .nar = 0x44, .apb = 0x2010 },\t/* XDMREG_DSR */\t\t\t\\\n\t{ .nar = 0x45, .apb = 0x2014 },\t/* XDMREG_DDR */\t\t\t\\\n\t{ .nar = 0x46, .apb = 0x2018 },\t/* XDMREG_DDREXEC */\t\t\\\n\t{ .nar = 0x47, .apb = 0x201c },\t/* XDMREG_DIR0EXEC */\t\t\\\n\t{ .nar = 0x48, .apb = 0x2020 },\t/* XDMREG_DIR0 */\t\t\t\\\n\t{ .nar = 0x49, .apb = 0x2024 },\t/* XDMREG_DIR1 */\t\t\t\\\n\t{ .nar = 0x4a, .apb = 0x2028 },\t/* XDMREG_DIR2 */\t\t\t\\\n\t{ .nar = 0x4b, .apb = 0x202c },\t/* XDMREG_DIR3 */\t\t\t\\\n\t{ .nar = 0x4c, .apb = 0x2030 },\t/* XDMREG_DIR4 */\t\t\t\\\n\t{ .nar = 0x4d, .apb = 0x2034 },\t/* XDMREG_DIR5 */\t\t\t\\\n\t{ .nar = 0x4e, .apb = 0x2038 },\t/* XDMREG_DIR6 */\t\t\t\\\n\t{ .nar = 0x4f, .apb = 0x203c },\t/* XDMREG_DIR7 */\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t/* Misc Registers */\t\t\t\t\t\t\t\t\t\t\\\n\t{ .nar = 0x5a, .apb = 0x3028 },\t/* XDMREG_ERISTAT */\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t/* CoreSight Registers */\t\t\t\t\t\t\t\t\t\\\n\t{ .nar = 0x60, .apb = 0x3f00 },\t/* XDMREG_ITCTRL */\t\t\t\\\n\t{ .nar = 0x68, .apb = 0x3fa0 },\t/* XDMREG_CLAIMSET */\t\t\\\n\t{ .nar = 0x69, .apb = 0x3fa4 },\t/* XDMREG_CLAIMCLR */\t\t\\\n\t{ .nar = 0x6c, .apb = 0x3fb0 },\t/* XDMREG_LOCKACCESS */\t\t\\\n\t{ .nar = 0x6d, .apb = 0x3fb4 },\t/* XDMREG_LOCKSTATUS */\t\t\\\n\t{ .nar = 0x6e, .apb = 0x3fb8 },\t/* XDMREG_AUTHSTATUS */\t\t\\\n\t{ .nar = 0x72, .apb = 0x3fc8 },\t/* XDMREG_DEVID */\t\t\t\\\n\t{ .nar = 0x73, .apb = 0x3fcc },\t/* XDMREG_DEVTYPE */\t\t\\\n\t{ .nar = 0x74, .apb = 0x3fd0 },\t/* XDMREG_PERID4 */\t\t\t\\\n\t{ .nar = 0x75, .apb = 0x3fd4 },\t/* XDMREG_PERID5 */\t\t\t\\\n\t{ .nar = 0x76, .apb = 0x3fd8 },\t/* XDMREG_PERID6 */\t\t\t\\\n\t{ .nar = 0x77, .apb = 0x3fdc },\t/* XDMREG_PERID7 */\t\t\t\\\n\t{ .nar = 0x78, .apb = 0x3fe0 },\t/* XDMREG_PERID0 */\t\t\t\\\n\t{ .nar = 0x79, .apb = 0x3fe4 },\t/* XDMREG_PERID1 */\t\t\t\\\n\t{ .nar = 0x7a, .apb = 0x3fe8 },\t/* XDMREG_PERID2 */\t\t\t\\\n\t{ .nar = 0x7b, .apb = 0x3fec },\t/* XDMREG_PERID3 */\t\t\t\\\n\t{ .nar = 0x7c, .apb = 0x3ff0 },\t/* XDMREG_COMPID0 */\t\t\\\n\t{ .nar = 0x7d, .apb = 0x3ff4 },\t/* XDMREG_COMPID1 */\t\t\\\n\t{ .nar = 0x7e, .apb = 0x3ff8 },\t/* XDMREG_COMPID2 */\t\t\\\n\t{ .nar = 0x7f, .apb = 0x3ffc },\t/* XDMREG_COMPID3 */\t\t\\\n}\n\n#define XTENSA_DM_APB_ALIGN         0x4000\n\n/* OCD registers, bit definitions */\n#define OCDDCR_ENABLEOCD            BIT(0)\n#define OCDDCR_DEBUGINTERRUPT       BIT(1)\n#define OCDDCR_INTERRUPTALLCONDS    BIT(2)\n#define OCDDCR_STEPREQUEST          BIT(3)\t\t/* NX only */\n#define OCDDCR_BREAKINEN            BIT(16)\n#define OCDDCR_BREAKOUTEN           BIT(17)\n#define OCDDCR_DEBUGSWACTIVE        BIT(20)\n#define OCDDCR_RUNSTALLINEN         BIT(21)\n#define OCDDCR_DEBUGMODEOUTEN       BIT(22)\n#define OCDDCR_BREAKOUTITO          BIT(24)\n#define OCDDCR_BREAKACKITO          BIT(25)\n\n#define OCDDSR_EXECDONE             BIT(0)\n#define OCDDSR_EXECEXCEPTION        BIT(1)\n#define OCDDSR_EXECBUSY             BIT(2)\n#define OCDDSR_EXECOVERRUN          BIT(3)\n#define OCDDSR_STOPPED              BIT(4)\n#define OCDDSR_STOPCAUSE            (0xF << 5)\t/* NX only */\n#define OCDDSR_STOPCAUSE_SHIFT      (5)\t\t\t/* NX only */\n#define OCDDSR_COREWROTEDDR         BIT(10)\n#define OCDDSR_COREREADDDR          BIT(11)\n#define OCDDSR_HOSTWROTEDDR         BIT(14)\n#define OCDDSR_HOSTREADDDR          BIT(15)\n#define OCDDSR_DEBUGPENDBREAK       BIT(16)\n#define OCDDSR_DEBUGPENDHOST        BIT(17)\n#define OCDDSR_DEBUGPENDTRAX        BIT(18)\n#define OCDDSR_DEBUGINTBREAK        BIT(20)\n#define OCDDSR_DEBUGINTHOST         BIT(21)\n#define OCDDSR_DEBUGINTTRAX         BIT(22)\n#define OCDDSR_RUNSTALLTOGGLE       BIT(23)\n#define OCDDSR_RUNSTALLSAMPLE       BIT(24)\n#define OCDDSR_BREACKOUTACKITI      BIT(25)\n#define OCDDSR_BREAKINITI           BIT(26)\n#define OCDDSR_DBGMODPOWERON        BIT(31)\n\n/* NX stop cause */\n#define OCDDSR_STOPCAUSE_DI         (0)\t\t/* Debug Interrupt */\n#define OCDDSR_STOPCAUSE_SS         (1)\t\t/* Single-step completed */\n#define OCDDSR_STOPCAUSE_IB         (2)\t\t/* HW breakpoint (IBREAKn match) */\n#define OCDDSR_STOPCAUSE_B1         (4)\t\t/* SW breakpoint (BREAK.1 instruction) */\n#define OCDDSR_STOPCAUSE_BN         (5)\t\t/* SW breakpoint (BREAK.N instruction) */\n#define OCDDSR_STOPCAUSE_B          (6)\t\t/* SW breakpoint (BREAK instruction) */\n#define OCDDSR_STOPCAUSE_DB0        (8)\t\t/* HW watchpoint (DBREAK0 match) */\n#define OCDDSR_STOPCAUSE_DB1        (9)\t\t/* HW watchpoint (DBREAK0 match) */\n\n/* LX stop cause */\n#define DEBUGCAUSE_IC               BIT(0)\t/* ICOUNT exception */\n#define DEBUGCAUSE_IB               BIT(1)\t/* IBREAK exception */\n#define DEBUGCAUSE_DB               BIT(2)\t/* DBREAK exception */\n#define DEBUGCAUSE_BI               BIT(3)\t/* BREAK instruction encountered */\n#define DEBUGCAUSE_BN               BIT(4)\t/* BREAK.N instruction encountered */\n#define DEBUGCAUSE_DI               BIT(5)\t/* Debug Interrupt */\n#define DEBUGCAUSE_VALID            BIT(31)\t/* Pseudo-value to trigger reread (NX only) */\n\n#define TRAXCTRL_TREN               BIT(0)\t/* Trace enable. Tracing starts on 0->1 */\n#define TRAXCTRL_TRSTP              BIT(1)\t/* Trace Stop. Make 1 to stop trace. */\n#define TRAXCTRL_PCMEN              BIT(2)\t/* PC match enable */\n#define TRAXCTRL_PTIEN              BIT(4)\t/* Processor-trigger enable */\n#define TRAXCTRL_CTIEN              BIT(5)\t/* Cross-trigger enable */\n#define TRAXCTRL_TMEN               BIT(7)\t/* Tracemem Enable. Always set. */\n#define TRAXCTRL_CNTU               BIT(9)\t/* Post-stop-trigger countdown units; selects when DelayCount-- happens.\n\t\t\t\t\t\t\t\t\t\t\t * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */\n#define TRAXCTRL_TSEN               BIT(11)\t/* Undocumented/deprecated? */\n#define TRAXCTRL_SMPER_SHIFT        12\t\t/* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */\n#define TRAXCTRL_SMPER_MASK         0x07\t/* Synchronization message period */\n#define TRAXCTRL_PTOWT              BIT(16)\t/* Processor Trigger Out (OCD halt) enabled when stop triggered */\n#define TRAXCTRL_PTOWS              BIT(17)\t/* Processor Trigger Out (OCD halt) enabled when trace stop completes */\n#define TRAXCTRL_CTOWT              BIT(20)\t/* Cross-trigger Out enabled when stop triggered */\n#define TRAXCTRL_CTOWS              BIT(21)\t/* Cross-trigger Out enabled when trace stop completes */\n#define TRAXCTRL_ITCTO              BIT(22)\t/* Integration mode: cross-trigger output */\n#define TRAXCTRL_ITCTIA             BIT(23)\t/* Integration mode: cross-trigger ack */\n#define TRAXCTRL_ITATV              BIT(24)\t/* replaces ATID when in integration mode: ATVALID output */\n#define TRAXCTRL_ATID_MASK          0x7F\t/* ARB source ID */\n#define TRAXCTRL_ATID_SHIFT         24\n#define TRAXCTRL_ATEN               BIT(31)\t/* ATB interface enable */\n\n#define TRAXSTAT_TRACT              BIT(0)\t/* Trace active flag. */\n#define TRAXSTAT_TRIG               BIT(1)\t/* Trace stop trigger. Clears on TREN 1->0 */\n#define TRAXSTAT_PCMTG              BIT(2)\t/* Stop trigger caused by PC match. Clears on TREN 1->0 */\n#define TRAXSTAT_PJTR               BIT(3)\t/* JTAG transaction result. 1=err in preceding jtag transaction. */\n#define TRAXSTAT_PTITG              BIT(4)\t/* Stop trigger caused by Processor Trigger Input.Clears on TREN 1->0 */\n#define TRAXSTAT_CTITG              BIT(5)\t/* Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0 */\n#define TRAXSTAT_MEMSZ_SHIFT        8\t\t/* Traceram size inducator. Usable trace ram is 2^MEMSZ bytes. */\n#define TRAXSTAT_MEMSZ_MASK         0x1F\n#define TRAXSTAT_PTO                BIT(16)\t/* Processor Trigger Output: current value */\n#define TRAXSTAT_CTO                BIT(17)\t/* Cross-Trigger Output: current value */\n#define TRAXSTAT_ITCTOA             BIT(22)\t/* Cross-Trigger Out Ack: current value */\n#define TRAXSTAT_ITCTI              BIT(23)\t/* Cross-Trigger Input: current value */\n#define TRAXSTAT_ITATR              BIT(24)\t/* ATREADY Input: current value */\n\n#define TRAXADDR_TADDR_SHIFT        0\t\t/* Trax memory address, in 32-bit words. */\n#define TRAXADDR_TADDR_MASK         0x1FFFFF\t/* Actually is only as big as the trace buffer size max addr. */\n#define TRAXADDR_TWRAP_SHIFT        21\t\t/* Amount of times TADDR has overflown */\n#define TRAXADDR_TWRAP_MASK         0x3FF\n#define TRAXADDR_TWSAT              BIT(31)\t/* 1 if TWRAP has overflown, clear by disabling tren.*/\n\n#define PCMATCHCTRL_PCML_SHIFT      0\t\t/* Amount of lower bits to ignore in pc trigger register */\n#define PCMATCHCTRL_PCML_MASK       0x1F\n#define PCMATCHCTRL_PCMS            BIT(31)\t/* PC Match Sense, 0-match when procs PC is in-range, 1-match when\n\t\t\t\t\t\t\t\t\t\t\t * out-of-range */\n\n#define XTENSA_MAX_PERF_COUNTERS    2\n#define XTENSA_MAX_PERF_SELECT      32\n#define XTENSA_MAX_PERF_MASK        0xffff\n\n#define XTENSA_STOPMASK_DISABLED    UINT32_MAX\n\nstruct xtensa_debug_module;\n\nstruct xtensa_debug_ops {\n\t/** enable operation */\n\tint (*queue_enable)(struct xtensa_debug_module *dm);\n\t/** register read. */\n\tint (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data);\n\t/** register write. */\n\tint (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data);\n};\n\n/* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide\n * when accessed via APB/DAP.  In order to use DAP queuing APIs (for optimal\n * performance), the XDM power register APIs take 32-bit register params.\n */\nstruct xtensa_power_ops {\n\t/** register read. */\n\tint (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data,\n\t\tuint32_t clear);\n\t/** register write. */\n\tint (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data);\n};\n\ntypedef uint32_t xtensa_pwrstat_t;\ntypedef uint32_t xtensa_ocdid_t;\ntypedef uint32_t xtensa_dsr_t;\ntypedef uint32_t xtensa_traxstat_t;\n\nstruct xtensa_power_status {\n\txtensa_pwrstat_t stat;\n\txtensa_pwrstat_t stath;\n\t/* TODO: do not need to keep previous status to detect that core or debug module has been\n\t * reset, */\n\t/*       we can clear PWRSTAT_DEBUGWASRESET and PWRSTAT_COREWASRESET after reading will do\n\t * the job; */\n\t/*       upon next reet those bits will be set again. So we can get rid of\n\t *       xtensa_dm_power_status_cache_reset() and xtensa_dm_power_status_cache(). */\n\txtensa_pwrstat_t prev_stat;\n};\n\nstruct xtensa_core_status {\n\txtensa_dsr_t dsr;\n};\n\nstruct xtensa_trace_config {\n\tuint32_t ctrl;\n\tuint32_t memaddr_start;\n\tuint32_t memaddr_end;\n\tuint32_t addr;\n};\n\nstruct xtensa_trace_status {\n\txtensa_traxstat_t stat;\n};\n\nstruct xtensa_trace_start_config {\n\tuint32_t stoppc;\n\tbool after_is_words;\n\tuint32_t after;\n\tuint32_t stopmask;\t/* UINT32_MAX: disable PC match option */\n};\n\nstruct xtensa_perfmon_config {\n\tint select;\n\tuint32_t mask;\n\tint kernelcnt;\n\tint tracelevel;\n};\n\nstruct xtensa_perfmon_result {\n\tuint64_t value;\n\tbool overflow;\n};\n\nstruct xtensa_debug_module_config {\n\tconst struct xtensa_power_ops *pwr_ops;\n\tconst struct xtensa_debug_ops *dbg_ops;\n\n\t/* Either JTAG or DAP structures will be populated */\n\tstruct jtag_tap *tap;\n\tvoid (*queue_tdi_idle)(struct target *target);\n\tvoid *queue_tdi_idle_arg;\n\n\t/* For targets conforming to ARM Debug Interface v5,\n\t * \"dap\" references the Debug Access Port (DAP)\n\t * used to make requests to the target;\n\t * \"debug_ap\" is AP instance connected to processor\n\t */\n\tstruct adiv5_dap *dap;\n\tstruct adiv5_ap *debug_ap;\n\tint debug_apsel;\n\tuint32_t ap_offset;\n};\n\nstruct xtensa_debug_module {\n\tconst struct xtensa_power_ops *pwr_ops;\n\tconst struct xtensa_debug_ops *dbg_ops;\n\n\t/* Either JTAG or DAP structures will be populated */\n\tstruct jtag_tap *tap;\n\tvoid (*queue_tdi_idle)(struct target *target);\n\tvoid *queue_tdi_idle_arg;\n\n\t/* DAP struct; AP instance connected to processor */\n\tstruct adiv5_dap *dap;\n\tstruct adiv5_ap *debug_ap;\n\tint debug_apsel;\n\n\tstruct xtensa_power_status power_status;\n\tstruct xtensa_core_status core_status;\n\txtensa_ocdid_t device_id;\n\tuint32_t ap_offset;\n};\n\nint xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg);\nvoid xtensa_dm_deinit(struct xtensa_debug_module *dm);\nint xtensa_dm_poll(struct xtensa_debug_module *dm);\nint xtensa_dm_examine(struct xtensa_debug_module *dm);\nint xtensa_dm_queue_enable(struct xtensa_debug_module *dm);\nint xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value);\nint xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value);\nint xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm,\n\tenum xtensa_dm_pwr_reg reg,\n\tuint8_t *data,\n\tuint32_t clear);\nint xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm,\n\tenum xtensa_dm_pwr_reg reg,\n\tuint32_t data);\n\nstatic inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm)\n{\n\treturn dm->dap ? dap_run(dm->dap) : jtag_execute_queue();\n}\n\nstatic inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm)\n{\n\tif (dm->queue_tdi_idle)\n\t\tdm->queue_tdi_idle(dm->queue_tdi_idle_arg);\n}\n\nint xtensa_dm_power_status_read(struct xtensa_debug_module *dm, uint32_t clear);\nstatic inline void xtensa_dm_power_status_cache_reset(struct xtensa_debug_module *dm)\n{\n\tdm->power_status.prev_stat = 0;\n}\nstatic inline void xtensa_dm_power_status_cache(struct xtensa_debug_module *dm)\n{\n\tdm->power_status.prev_stat = dm->power_status.stath;\n}\nstatic inline xtensa_pwrstat_t xtensa_dm_power_status_get(struct xtensa_debug_module *dm)\n{\n\treturn dm->power_status.stat;\n}\n\nint xtensa_dm_core_status_read(struct xtensa_debug_module *dm);\nint xtensa_dm_core_status_clear(struct xtensa_debug_module *dm, xtensa_dsr_t bits);\nint xtensa_dm_core_status_check(struct xtensa_debug_module *dm);\nstatic inline xtensa_dsr_t xtensa_dm_core_status_get(struct xtensa_debug_module *dm)\n{\n\treturn dm->core_status.dsr;\n}\n\nint xtensa_dm_device_id_read(struct xtensa_debug_module *dm);\nstatic inline xtensa_ocdid_t xtensa_dm_device_id_get(struct xtensa_debug_module *dm)\n{\n\treturn dm->device_id;\n}\n\nint xtensa_dm_trace_start(struct xtensa_debug_module *dm, struct xtensa_trace_start_config *cfg);\nint xtensa_dm_trace_stop(struct xtensa_debug_module *dm, bool pto_enable);\nint xtensa_dm_trace_config_read(struct xtensa_debug_module *dm, struct xtensa_trace_config *config);\nint xtensa_dm_trace_status_read(struct xtensa_debug_module *dm, struct xtensa_trace_status *status);\nint xtensa_dm_trace_data_read(struct xtensa_debug_module *dm, uint8_t *dest, uint32_t size);\n\nstatic inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm)\n{\n\tint res = xtensa_dm_device_id_read(dm);\n\tif (res != ERROR_OK)\n\t\treturn false;\n\treturn dm->device_id != 0xffffffff && dm->device_id != 0;\n}\n\nstatic inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)\n{\n\treturn !(dm->power_status.prev_stat & PWRSTAT_DEBUGWASRESET_DM(dm)) &&\n\t       dm->power_status.stat & PWRSTAT_DEBUGWASRESET_DM(dm);\n}\n\nstatic inline bool xtensa_dm_core_was_reset(struct xtensa_debug_module *dm)\n{\n\treturn !(dm->power_status.prev_stat & PWRSTAT_COREWASRESET_DM(dm)) &&\n\t       dm->power_status.stat & PWRSTAT_COREWASRESET_DM(dm);\n}\n\nstatic inline bool xtensa_dm_core_is_stalled(struct xtensa_debug_module *dm)\n{\n\treturn dm->core_status.dsr & OCDDSR_RUNSTALLSAMPLE;\n}\n\nstatic inline bool xtensa_dm_is_powered(struct xtensa_debug_module *dm)\n{\n\treturn dm->core_status.dsr & OCDDSR_DBGMODPOWERON;\n}\n\nint xtensa_dm_perfmon_enable(struct xtensa_debug_module *dm, int counter_id,\n\tconst struct xtensa_perfmon_config *config);\nint xtensa_dm_perfmon_dump(struct xtensa_debug_module *dm, int counter_id,\n\tstruct xtensa_perfmon_result *out_result);\n\n#endif\t/* OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_fileio.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Xtensa Target File-I/O Support for OpenOCD                            *\n *   Copyright (C) 2020-2023 Cadence Design Systems, Inc.                  *\n ***************************************************************************/\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"xtensa_chip.h\"\n#include \"xtensa_fileio.h\"\n#include \"xtensa.h\"\n\n#define XTENSA_SYSCALL(x)\t\tXT_INS_BREAK(x, 1, 14)\n#define XTENSA_SYSCALL_SZ\t\t3\n#define XTENSA_SYSCALL_LEN_MAX\t255\n\n\nint xtensa_fileio_init(struct target *target)\n{\n\tchar *idmem = malloc(XTENSA_SYSCALL_LEN_MAX + 1);\n\ttarget->fileio_info = malloc(sizeof(struct gdb_fileio_info));\n\tif (!idmem || !target->fileio_info) {\n\t\tLOG_TARGET_ERROR(target, \"Out of memory!\");\n\t\tfree(idmem);\n\t\tfree(target->fileio_info);\n\t\treturn ERROR_FAIL;\n\t}\n\ttarget->fileio_info->identifier = idmem;\n\treturn ERROR_OK;\n}\n\n/**\n * Checks for and processes an Xtensa File-IO request.\n *\n * Return ERROR_OK if request was found and handled; or\n * return ERROR_FAIL if no request was detected.\n */\nint xtensa_fileio_detect_proc(struct target *target)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tint retval;\n\n\txtensa_reg_val_t dbg_cause = xtensa_cause_get(target);\n\tif ((dbg_cause & (DEBUGCAUSE_BI | DEBUGCAUSE_BN)) == 0 || xtensa->halt_request)\n\t\treturn ERROR_FAIL;\n\n\tuint8_t brk_insn_buf[sizeof(uint32_t)] = {0};\n\txtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);\n\tretval = target_read_memory(target,\n\t\tpc,\n\t\tXTENSA_SYSCALL_SZ,\n\t\t1,\n\t\t(uint8_t *)brk_insn_buf);\n\tif (retval != ERROR_OK) {\n\t\tLOG_ERROR(\"Failed to read break instruction!\");\n\t\treturn ERROR_FAIL;\n\t}\n\tif (buf_get_u32(brk_insn_buf, 0, 32) != XTENSA_SYSCALL(xtensa))\n\t\treturn ERROR_FAIL;\n\n\tLOG_TARGET_DEBUG(target, \"File-I/O: syscall breakpoint found at 0x%x\", pc);\n\txtensa->proc_syscall = true;\n\treturn ERROR_OK;\n}\n\nint xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info)\n{\n\t/* fill syscall parameters to file-I/O info */\n\tif (!fileio_info) {\n\t\tLOG_ERROR(\"File-I/O data structure uninitialized\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tif (!xtensa->proc_syscall)\n\t\treturn ERROR_FAIL;\n\n\txtensa_reg_val_t syscall = xtensa_reg_get(target, XTENSA_SYSCALL_OP_REG);\n\txtensa_reg_val_t arg0 = xtensa_reg_get(target, XT_REG_IDX_A6);\n\txtensa_reg_val_t arg1 = xtensa_reg_get(target, XT_REG_IDX_A3);\n\txtensa_reg_val_t arg2 = xtensa_reg_get(target, XT_REG_IDX_A4);\n\txtensa_reg_val_t arg3 = xtensa_reg_get(target, XT_REG_IDX_A5);\n\tint retval = ERROR_OK;\n\n\tLOG_TARGET_DEBUG(target, \"File-I/O: syscall 0x%x 0x%x 0x%x 0x%x 0x%x\",\n\t\tsyscall, arg0, arg1, arg2, arg3);\n\n\tswitch (syscall) {\n\tcase XTENSA_SYSCALL_OPEN:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"open\");\n\t\tfileio_info->param_1 = arg0;\t// pathp\n\t\tfileio_info->param_2 = arg3;\t// len\n\t\tfileio_info->param_3 = arg1;\t// flags\n\t\tfileio_info->param_4 = arg2;\t// mode\n\t\tbreak;\n\tcase XTENSA_SYSCALL_CLOSE:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"close\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tbreak;\n\tcase XTENSA_SYSCALL_READ:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"read\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tfileio_info->param_2 = arg1;\t// bufp\n\t\tfileio_info->param_3 = arg2;\t// count\n\t\tbreak;\n\tcase XTENSA_SYSCALL_WRITE:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"write\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tfileio_info->param_2 = arg1;\t// bufp\n\t\tfileio_info->param_3 = arg2;\t// count\n\t\tbreak;\n\tcase XTENSA_SYSCALL_LSEEK:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"lseek\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tfileio_info->param_2 = arg1;\t// offset\n\t\tfileio_info->param_3 = arg2;\t// flags\n\t\tbreak;\n\tcase XTENSA_SYSCALL_RENAME:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"rename\");\n\t\tfileio_info->param_1 = arg0;\t// old pathp\n\t\tfileio_info->param_2 = arg3;\t// old len\n\t\tfileio_info->param_3 = arg1;\t// new pathp\n\t\tfileio_info->param_4 = arg2;\t// new len\n\t\tbreak;\n\tcase XTENSA_SYSCALL_UNLINK:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"unlink\");\n\t\tfileio_info->param_1 = arg0;\t// pathnamep\n\t\tfileio_info->param_2 = arg1;\t// len\n\t\tbreak;\n\tcase XTENSA_SYSCALL_STAT:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"stat\");\n\t\tfileio_info->param_1 = arg0;\t// pathnamep\n\t\tfileio_info->param_2 = arg2;\t// len\n\t\tfileio_info->param_3 = arg1;\t// bufp\n\t\tbreak;\n\tcase XTENSA_SYSCALL_FSTAT:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"fstat\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tfileio_info->param_2 = arg1;\t// bufp\n\t\tbreak;\n\tcase XTENSA_SYSCALL_GETTIMEOFDAY:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"gettimeofday\");\n\t\tfileio_info->param_1 = arg0;\t// tvp\n\t\tfileio_info->param_2 = arg1;\t// tzp\n\t\tbreak;\n\tcase XTENSA_SYSCALL_ISATTY:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"isatty\");\n\t\tfileio_info->param_1 = arg0;\t// fd\n\t\tbreak;\n\tcase XTENSA_SYSCALL_SYSTEM:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"system\");\n\t\tfileio_info->param_1 = arg0;\t// cmdp\n\t\tfileio_info->param_2 = arg1;\t// len\n\t\tbreak;\n\tdefault:\n\t\tsnprintf(fileio_info->identifier, XTENSA_SYSCALL_LEN_MAX, \"unknown\");\n\t\tLOG_TARGET_DEBUG(target, \"File-I/O: syscall unknown (%d), pc=0x%08X\",\n\t\t\tsyscall, xtensa_reg_get(target, XT_REG_IDX_PC));\n\t\tLOG_INFO(\"File-I/O: syscall unknown (%d), pc=0x%08X\",\n\t\t\tsyscall, xtensa_reg_get(target, XT_REG_IDX_PC));\n\t\tretval = ERROR_FAIL;\n\t\tbreak;\n\t}\n\n\treturn retval;\n}\n\nint xtensa_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c)\n{\n\tstruct xtensa *xtensa = target_to_xtensa(target);\n\tif (!xtensa->proc_syscall)\n\t\treturn ERROR_FAIL;\n\n\tLOG_TARGET_DEBUG(target, \"File-I/O: syscall return code: 0x%x, errno: 0x%x , ctrl_c: %s\",\n\t\tretcode, fileio_errno, ctrl_c ? \"true\" : \"false\");\n\n\t/* If interrupt was requested before FIO completion (ERRNO==4), halt and repeat\n\t * syscall. Otherwise, set File-I/O Ax and underlying ARx registers, increment PC.\n\t * NOTE: sporadic cases of ((ERRNO==4) && !ctrl_c) were observed; most have ctrl_c.\n\t */\n\tif (fileio_errno != 4) {\n\t\txtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_RETVAL_REG, retcode);\n\t\txtensa_reg_set_deep_relgen(target, XTENSA_SYSCALL_ERRNO_REG, fileio_errno);\n\n\t\txtensa_reg_val_t pc = xtensa_reg_get(target, XT_REG_IDX_PC);\n\t\txtensa_reg_set(target, XT_REG_IDX_PC, pc + XTENSA_SYSCALL_SZ);\n\t}\n\n\txtensa->proc_syscall = false;\n\txtensa->halt_request = true;\n\treturn ctrl_c ? ERROR_FAIL : ERROR_OK;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_fileio.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Xtensa Target File-I/O Support for OpenOCD                            *\n *   Copyright (C) 2020-2023 Cadence Design Systems, Inc.                  *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_FILEIO_H\n#define OPENOCD_TARGET_XTENSA_FILEIO_H\n\n#include <target/target.h>\n#include <helper/command.h>\n#include \"xtensa.h\"\n\n#define XTENSA_SYSCALL_OP_REG\t\tXT_REG_IDX_A2\n#define XTENSA_SYSCALL_RETVAL_REG\tXT_REG_IDX_A2\n#define XTENSA_SYSCALL_ERRNO_REG\tXT_REG_IDX_A3\n\n#define XTENSA_SYSCALL_OPEN\t\t\t(-2)\n#define XTENSA_SYSCALL_CLOSE\t\t(-3)\n#define XTENSA_SYSCALL_READ\t\t\t(-4)\n#define XTENSA_SYSCALL_WRITE\t\t(-5)\n#define XTENSA_SYSCALL_LSEEK\t\t(-6)\n#define XTENSA_SYSCALL_RENAME\t\t(-7)\n#define XTENSA_SYSCALL_UNLINK\t\t(-8)\n#define XTENSA_SYSCALL_STAT\t\t\t(-9)\n#define XTENSA_SYSCALL_FSTAT\t\t(-10)\n#define XTENSA_SYSCALL_GETTIMEOFDAY\t(-11)\n#define XTENSA_SYSCALL_ISATTY\t\t(-12)\n#define XTENSA_SYSCALL_SYSTEM\t\t(-13)\n\nint xtensa_fileio_init(struct target *target);\nint xtensa_fileio_detect_proc(struct target *target);\nint xtensa_get_gdb_fileio_info(struct target *target, struct gdb_fileio_info *fileio_info);\nint xtensa_gdb_fileio_end(struct target *target, int retcode, int fileio_errno, bool ctrl_c);\n\n#endif\t/* OPENOCD_TARGET_XTENSA_FILEIO_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/target/xtensa/xtensa_regs.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Generic Xtensa target API for OpenOCD                                 *\n *   Copyright (C) 2020-2022 Cadence Design Systems, Inc.                  *\n *   Copyright (C) 2016-2019 Espressif Systems Ltd.                        *\n *   Author: Angus Gratton gus@projectgus.com                              *\n ***************************************************************************/\n\n#ifndef OPENOCD_TARGET_XTENSA_REGS_H\n#define OPENOCD_TARGET_XTENSA_REGS_H\n\nstruct reg_arch_type;\n\nenum xtensa_reg_id {\n\tXT_REG_IDX_PC = 0,\n\tXT_REG_IDX_AR0,\n\tXT_REG_IDX_ARFIRST = XT_REG_IDX_AR0,\n\tXT_REG_IDX_AR1,\n\tXT_REG_IDX_AR2,\n\tXT_REG_IDX_AR3,\n\tXT_REG_IDX_AR4,\n\tXT_REG_IDX_AR5,\n\tXT_REG_IDX_AR6,\n\tXT_REG_IDX_AR7,\n\tXT_REG_IDX_AR8,\n\tXT_REG_IDX_AR9,\n\tXT_REG_IDX_AR10,\n\tXT_REG_IDX_AR11,\n\tXT_REG_IDX_AR12,\n\tXT_REG_IDX_AR13,\n\tXT_REG_IDX_AR14,\n\tXT_REG_IDX_AR15,\n\tXT_REG_IDX_ARLAST = 64,\t/* Max 64 ARs */\n\tXT_REG_IDX_WINDOWBASE,\n\tXT_REG_IDX_WINDOWSTART,\n\tXT_REG_IDX_PS,\n\tXT_REG_IDX_IBREAKENABLE,\n\tXT_REG_IDX_DDR,\n\tXT_REG_IDX_IBREAKA0,\n\tXT_REG_IDX_IBREAKA1,\n\tXT_REG_IDX_DBREAKA0,\n\tXT_REG_IDX_DBREAKA1,\n\tXT_REG_IDX_DBREAKC0,\n\tXT_REG_IDX_DBREAKC1,\n\tXT_REG_IDX_CPENABLE,\n\tXT_REG_IDX_EXCCAUSE,\n\tXT_REG_IDX_DEBUGCAUSE,\n\tXT_REG_IDX_ICOUNT,\n\tXT_REG_IDX_ICOUNTLEVEL,\n\tXT_REG_IDX_A0,\n\tXT_REG_IDX_A1,\n\tXT_REG_IDX_A2,\n\tXT_REG_IDX_A3,\n\tXT_REG_IDX_A4,\n\tXT_REG_IDX_A5,\n\tXT_REG_IDX_A6,\n\tXT_REG_IDX_A7,\n\tXT_REG_IDX_A8,\n\tXT_REG_IDX_A9,\n\tXT_REG_IDX_A10,\n\tXT_REG_IDX_A11,\n\tXT_REG_IDX_A12,\n\tXT_REG_IDX_A13,\n\tXT_REG_IDX_A14,\n\tXT_REG_IDX_A15,\n\tXT_NUM_REGS\n};\n\ntypedef uint32_t xtensa_reg_val_t;\n\n#define XT_NUM_A_REGS   16\n\nenum xtensa_reg_type {\n\tXT_REG_GENERAL = 0,\t\t/* General-purpose register; part of the windowed register set */\n\tXT_REG_USER = 1,\t\t/* User register, needs RUR to read */\n\tXT_REG_SPECIAL = 2,\t\t/* Special register, needs RSR to read */\n\tXT_REG_DEBUG = 3,\t\t/* Register used for the debug interface. Don't mess with this. */\n\tXT_REG_RELGEN = 4,\t\t/* Relative general address. Points to the absolute addresses plus the window\n\t\t\t\t\t * index */\n\tXT_REG_FR = 5,\t\t\t/* Floating-point register */\n\tXT_REG_TIE = 6,\t\t\t/* TIE (custom) register */\n\tXT_REG_OTHER = 7,\t\t/* Other (typically legacy) register */\n\tXT_REG_TYPE_NUM,\n\n\t/* enum names must be one of the above types + _VAL or _MASK */\n\tXT_REG_GENERAL_MASK             = 0xFFC0,\n\tXT_REG_GENERAL_VAL              = 0x0100,\n\tXT_REG_USER_MASK                = 0xFF00,\n\tXT_REG_USER_VAL                 = 0x0300,\n\tXT_REG_SPECIAL_MASK             = 0xFF00,\n\tXT_REG_SPECIAL_VAL              = 0x0200,\n\tXT_REG_DEBUG_MASK               = 0xFF00,\n\tXT_REG_DEBUG_VAL                = 0x0200,\n\tXT_REG_RELGEN_MASK              = 0xFFE0,\n\tXT_REG_RELGEN_VAL               = 0x0000,\n\tXT_REG_FR_MASK                  = 0xFFF0,\n\tXT_REG_FR_VAL                   = 0x0030,\n\tXT_REG_TIE_MASK                 = 0xF000,\n\tXT_REG_TIE_VAL                  = 0xF000,\t/* unused */\n\tXT_REG_OTHER_MASK               = 0xFFFF,\n\tXT_REG_OTHER_VAL                = 0xF000,\t/* unused */\n\n\tXT_REG_INDEX_MASK               = 0x00FF\n};\n\nenum xtensa_reg_flags {\n\tXT_REGF_NOREAD = 0x01,\t/* Register is write-only */\n\tXT_REGF_COPROC0 = 0x02,\t/* Can't be read if coproc0 isn't enabled */\n\tXT_REGF_MASK = 0x03\n};\n\nstruct xtensa_reg_desc {\n\tconst char *name;\n\tbool exist;\n\tunsigned int reg_num;\t\t\t/* ISA register num (meaning depends on register type) */\n\tunsigned int dbreg_num;\t\t\t/* Debugger-visible register num (reg type encoded) */\n\tenum xtensa_reg_type type;\n\tenum xtensa_reg_flags flags;\n};\n\n#define _XT_MK_DBREGN(reg_num, reg_type)\t\t\t\t\t\\\n\t((reg_type ## _VAL) | (reg_num))\n\n#define _XT_MK_DBREGN_MASK(reg_num, reg_mask)\t\t\t\t\\\n\t((reg_mask) | (reg_num))\n\n#define XT_MK_REG_DESC(n, r, t, f)\t\t\t\t\t\t\t\\\n\t{ .name = (n), .exist = false, .reg_num = (r),\t\t\t\\\n\t  .dbreg_num = _XT_MK_DBREGN(r, t), .type = (t),\t\t\\\n\t  .flags = (f) }\n\nextern struct xtensa_reg_desc xtensa_regs[XT_NUM_REGS];\n\n#endif\t/* OPENOCD_TARGET_XTENSA_REGS_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/transport/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libtransport.la\n%C%_libtransport_la_SOURCES = \\\n\t%D%/transport.c \\\n\t%D%/transport.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/transport/transport.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/*\n * Copyright (c) 2010 by David Brownell\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n/** @file\n * Infrastructure for specifying and managing the transport protocol\n * used in a given debug or programming session.\n *\n * Examples of \"debug-capable\" transports are JTAG or SWD.\n * Additionally, JTAG supports boundary scan testing.\n *\n * Examples of \"programming-capable\" transports include SPI or UART;\n * those are used (often mediated by a ROM bootloader) for ISP style\n * programming, to perform an initial load of code into flash, or\n * sometimes into SRAM.  Target code could use \"variant\" options to\n * decide how to use such protocols.  For example, Cortex-M3 cores\n * from TI/Luminary and from NXP use different protocols for for\n * UART or SPI based firmware loading.\n *\n * As a rule, there are protocols layered on top of the transport.\n * For example, different chip families use JTAG in different ways\n * for debugging.  Also, each family that supports programming over\n * a UART link for initial firmware loading tends to define its own\n * messaging and error handling.\n */\n\n#include <helper/log.h>\n#include <helper/replacements.h>\n#include <transport/transport.h>\n\nextern struct command_context *global_cmd_ctx;\n\n/*-----------------------------------------------------------------------*/\n\n/*\n * Infrastructure internals\n */\n\n/** List of transports known to OpenOCD. */\nstatic struct transport *transport_list;\n\n/**\n * NULL-terminated Vector of names of transports which the\n * currently selected debug adapter supports.  This is declared\n * by the time that adapter is fully set up.\n */\nstatic const char * const *allowed_transports;\n\n/** * The transport being used for the current OpenOCD session.  */\nstatic struct transport *session;\n\nstatic int transport_select(struct command_context *ctx, const char *name)\n{\n\t/* name may only identify a known transport;\n\t * caller guarantees session's transport isn't yet set.*/\n\tfor (struct transport *t = transport_list; t; t = t->next) {\n\t\tif (strcmp(t->name, name) == 0) {\n\t\t\tint retval = t->select(ctx);\n\t\t\t/* select() registers commands specific to this\n\t\t\t * transport, and may also reset the link, e.g.\n\t\t\t * forcing it to JTAG or SWD mode.\n\t\t\t */\n\t\t\tif (retval == ERROR_OK)\n\t\t\t\tsession = t;\n\t\t\telse\n\t\t\t\tLOG_ERROR(\"Error selecting '%s' as transport\", t->name);\n\t\t\treturn retval;\n\t\t}\n\t}\n\n\tLOG_ERROR(\"No transport named '%s' is available.\", name);\n\treturn ERROR_FAIL;\n}\n\n/**\n * Called by debug adapter drivers, or affiliated Tcl config scripts,\n * to declare the set of transports supported by an adapter.  When\n * there is only one member of that set, it is automatically selected.\n */\nint allow_transports(struct command_context *ctx, const char * const *vector)\n{\n\t/* NOTE:  caller is required to provide only a list\n\t * of *valid* transport names\n\t *\n\t * REVISIT should we validate that?  and insist there's\n\t * at least one non-NULL element in that list?\n\t *\n\t * ... allow removals, e.g. external strapping prevents use\n\t * of one transport; C code should be definitive about what\n\t * can be used when all goes well.\n\t */\n\tif (allowed_transports || session) {\n\t\tLOG_ERROR(\"Can't modify the set of allowed transports.\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tallowed_transports = vector;\n\n\t/* autoselect if there's no choice ... */\n\tif (!vector[1]) {\n\t\tLOG_INFO(\"only one transport option; autoselecting '%s'\", vector[0]);\n\t\treturn transport_select(ctx, vector[0]);\n\t}\n\n\treturn ERROR_OK;\n}\n\n/**\n * Registers a transport.  There are general purpose transports\n * (such as JTAG), as well as relatively proprietary ones which are\n * specific to a given chip (or chip family).\n *\n * Code implementing a transport needs to register it before it can\n * be selected and then activated.  This is a dynamic process, so\n * that chips (and families) can define transports as needed (without\n * needing error-prone static tables).\n *\n * @param new_transport the transport being registered.  On a\n * successful return, this memory is owned by the transport framework.\n *\n * @returns ERROR_OK on success, else a fault code.\n */\nint transport_register(struct transport *new_transport)\n{\n\tstruct transport *t;\n\n\tfor (t = transport_list; t; t = t->next) {\n\t\tif (strcmp(t->name, new_transport->name) == 0) {\n\t\t\tLOG_ERROR(\"transport name already used\");\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\tif (!new_transport->select || !new_transport->init)\n\t\tLOG_ERROR(\"invalid transport %s\", new_transport->name);\n\n\t/* splice this into the list */\n\tnew_transport->next = transport_list;\n\ttransport_list = new_transport;\n\tLOG_DEBUG(\"register '%s'\", new_transport->name);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Returns the transport currently being used by this debug or\n * programming session.\n *\n * @returns handle to the read-only transport entity.\n */\nstruct transport *get_current_transport(void)\n{\n\t/* REVISIT -- constify */\n\treturn session;\n}\n\n/*-----------------------------------------------------------------------*/\n\n/*\n * Infrastructure for Tcl interface to transports.\n */\n\n/**\n * Makes and stores a copy of a set of transports passed as\n * parameters to a command.\n *\n * @param vector where the resulting copy is stored, as an argv-style\n *\tNULL-terminated vector.\n */\nCOMMAND_HELPER(transport_list_parse, char ***vector)\n{\n\tchar **argv;\n\tunsigned n = CMD_ARGC;\n\tunsigned j = 0;\n\n\t*vector = NULL;\n\n\tif (n < 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* our return vector must be NULL terminated */\n\targv = calloc(n + 1, sizeof(char *));\n\tif (!argv)\n\t\treturn ERROR_FAIL;\n\n\tfor (unsigned i = 0; i < n; i++) {\n\t\tstruct transport *t;\n\n\t\tfor (t = transport_list; t; t = t->next) {\n\t\t\tif (strcmp(t->name, CMD_ARGV[i]) != 0)\n\t\t\t\tcontinue;\n\t\t\targv[j++] = strdup(CMD_ARGV[i]);\n\t\t\tbreak;\n\t\t}\n\t\tif (!t) {\n\t\t\tLOG_ERROR(\"no such transport '%s'\", CMD_ARGV[i]);\n\t\t\tgoto fail;\n\t\t}\n\t}\n\n\t*vector = argv;\n\treturn ERROR_OK;\n\nfail:\n\tfor (unsigned i = 0; i < n; i++)\n\t\tfree(argv[i]);\n\tfree(argv);\n\treturn ERROR_FAIL;\n}\n\nCOMMAND_HANDLER(handle_transport_init)\n{\n\tLOG_DEBUG(\"%s\", __func__);\n\tif (!session) {\n\t\tLOG_ERROR(\"session transport was not selected. Use 'transport select <transport>'\");\n\n\t\t/* no session transport configured, print transports then fail */\n\t\tLOG_ERROR(\"Transports available:\");\n\t\tconst char * const *vector = allowed_transports;\n\t\twhile (*vector) {\n\t\t\tLOG_ERROR(\"%s\", *vector);\n\t\t\tvector++;\n\t\t}\n\t\treturn ERROR_FAIL;\n\t}\n\n\treturn session->init(CMD_CTX);\n}\n\nCOMMAND_HANDLER(handle_transport_list)\n{\n\tif (CMD_ARGC != 0)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tcommand_print(CMD, \"The following transports are available:\");\n\n\tfor (struct transport *t = transport_list; t; t = t->next)\n\t\tcommand_print(CMD, \"\\t%s\", t->name);\n\n\treturn ERROR_OK;\n}\n\n/**\n * Implements the Tcl \"transport select\" command, choosing the\n * transport to be used in this debug session from among the\n * set supported by the debug adapter being used.  Return value\n * is scriptable (allowing \"if swd then...\" etc).\n */\nCOMMAND_HANDLER(handle_transport_select)\n{\n\tif (CMD_ARGC > 1)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\tif (CMD_ARGC == 0) {\n\t\t/* autoselect if necessary, then return/display current config */\n\t\tif (!session) {\n\t\t\tif (!allowed_transports) {\n\t\t\t\tcommand_print(CMD, \"Debug adapter does not support any transports? Check config file order.\");\n\t\t\t\treturn ERROR_FAIL;\n\t\t\t}\n\t\t\tLOG_INFO(\"auto-selecting first available session transport \\\"%s\\\". \"\n\t\t\t\t\"To override use 'transport select <transport>'.\", allowed_transports[0]);\n\t\t\tint retval = transport_select(CMD_CTX, allowed_transports[0]);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t}\n\t\tcommand_print(CMD, \"%s\", session->name);\n\t\treturn ERROR_OK;\n\t}\n\n\t/* assign transport */\n\tif (session) {\n\t\tif (!strcmp(session->name, CMD_ARGV[0])) {\n\t\t\tLOG_WARNING(\"Transport \\\"%s\\\" was already selected\", session->name);\n\t\t\tcommand_print(CMD, \"%s\", session->name);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t\tcommand_print(CMD, \"Can't change session's transport after the initial selection was made\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* Is this transport supported by our debug adapter?\n\t * Example, \"JTAG-only\" means SWD is not supported.\n\t *\n\t * NOTE:  requires adapter to have been set up, with\n\t * transports declared via C.\n\t */\n\tif (!allowed_transports) {\n\t\tcommand_print(CMD, \"Debug adapter doesn't support any transports?\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfor (unsigned int i = 0; allowed_transports[i]; i++) {\n\t\tif (!strcmp(allowed_transports[i], CMD_ARGV[0])) {\n\t\t\tint retval = transport_select(CMD_CTX, CMD_ARGV[0]);\n\t\t\tif (retval != ERROR_OK)\n\t\t\t\treturn retval;\n\t\t\tcommand_print(CMD, \"%s\", session->name);\n\t\t\treturn ERROR_OK;\n\t\t}\n\t}\n\n\tcommand_print(CMD, \"Debug adapter doesn't support '%s' transport\", CMD_ARGV[0]);\n\treturn ERROR_FAIL;\n}\n\nstatic const struct command_registration transport_commands[] = {\n\t{\n\t\t.name = \"init\",\n\t\t.handler = handle_transport_init,\n\t\t/* this would be COMMAND_CONFIG ... except that\n\t\t * it needs to trigger event handlers that may\n\t\t * require COMMAND_EXEC ...\n\t\t */\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Initialize this session's transport\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"list\",\n\t\t.handler = handle_transport_list,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"list all built-in transports\",\n\t\t.usage = \"\"\n\t},\n\t{\n\t\t.name = \"select\",\n\t\t.handler = handle_transport_select,\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Select this session's transport\",\n\t\t.usage = \"[transport_name]\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nstatic const struct command_registration transport_group[] = {\n\t{\n\t\t.name = \"transport\",\n\t\t.mode = COMMAND_ANY,\n\t\t.help = \"Transport command group\",\n\t\t.chain = transport_commands,\n\t\t.usage = \"\"\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint transport_register_commands(struct command_context *ctx)\n{\n\treturn register_commands(ctx, NULL, transport_group);\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/transport/transport.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/*\n * Copyright (c) 2010 by David Brownell\n * Copyright (C) 2011 Tomasz Boleslaw CEDRO (http://www.tomek.cedro.info)\n */\n\n#ifndef OPENOCD_TRANSPORT_TRANSPORT_H\n#define OPENOCD_TRANSPORT_TRANSPORT_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"helper/command.h\"\n\n/**\n * Wrapper for transport lifecycle operations.\n *\n * OpenOCD talks to targets through some kind of debugging\n * or programming adapter, using some protocol that probably\n * has target-specific aspects.\n *\n * A \"transport\" reflects electrical protocol to the target,\n * e..g jtag, swd, spi, uart, ... NOT the messaging protocols\n * layered over it (e.g. JTAG has eICE, CoreSight, Nexus, OnCE,\n * and more).\n *\n * In addition to the lifecycle operations packaged by this\n * structure, a transport also involves  an interface supported\n * by debug adapters and used by components such as debug targets.\n * For non-debug transports,  there may be interfaces used to\n * write to flash chips.\n */\nstruct transport {\n\t/**\n\t * Each transport has a unique name, used to select it\n\t * from among the alternatives.  Examples might include\n\t * \"jtag\", * \"swd\", \"AVR_ISP\" and more.\n\t */\n\tconst char *name;\n\n\t/**\n\t * When a transport is selected, this method registers\n\t * its commands and activates the transport (e.g. resets\n\t * the link).\n\t *\n\t * After those commands are registered, they will often\n\t * be used for further configuration of the debug link.\n\t */\n\tint (*select)(struct command_context *ctx);\n\n\t/**\n\t * server startup uses this method to validate transport\n\t * configuration.  (For example, with JTAG this interrogates\n\t * the scan chain against the list of expected TAPs.)\n\t */\n\tint (*init)(struct command_context *ctx);\n\n\t/**\n\t * Optional. If defined, allows transport to override target\n\t * name prior to initialisation.\n\t *\n\t * @returns ERROR_OK on success, or an error code on failure.\n\t */\n\tint (*override_target)(const char **targetname);\n\n\t/**\n\t * Transports are stored in a singly linked list.\n\t */\n\tstruct transport *next;\n};\n\nint transport_register(struct transport *new_transport);\n\nstruct transport *get_current_transport(void);\n\nint transport_register_commands(struct command_context *ctx);\n\nCOMMAND_HELPER(transport_list_parse, char ***vector);\n\nint allow_transports(struct command_context *ctx, const char * const *vector);\n\nbool transport_is_jtag(void);\nbool transport_is_swd(void);\nbool transport_is_dapdirect_jtag(void);\nbool transport_is_dapdirect_swd(void);\nbool transport_is_swim(void);\n\n#if BUILD_HLADAPTER\nbool transport_is_hla(void);\n#else\nstatic inline bool transport_is_hla(void)\n{\n\treturn false;\n}\n#endif\n\n#endif /* OPENOCD_TRANSPORT_TRANSPORT_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/xsvf/Makefile.am",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nnoinst_LTLIBRARIES += %D%/libxsvf.la\n%C%_libxsvf_la_SOURCES = %D%/xsvf.c %D%/xsvf.h\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/xsvf/xsvf.c",
    "content": "// SPDX-License-Identifier: GPL-2.0-or-later\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n *                                                                         *\n *   Copyright (C) 2007,2008 Øyvind Harboe                                 *\n *   oyvind.harboe@zylin.com                                               *\n *                                                                         *\n *   Copyright (C) 2008 Peter Hettkamp                                     *\n *   peter.hettkamp@htp-tel.de                                             *\n *                                                                         *\n *   Copyright (C) 2009 SoftPLC Corporation. http://softplc.com            *\n *   Dick Hollenbeck <dick@softplc.com>                                    *\n ***************************************************************************/\n\n/* The specification for SVF is available here:\n * http://www.asset-intertech.com/support/svf.pdf\n * Below, this document is referred to as the \"SVF spec\".\n *\n * The specification for XSVF is available here:\n * http://www.xilinx.com/support/documentation/application_notes/xapp503.pdf\n * Below, this document is referred to as the \"XSVF spec\".\n */\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"xsvf.h\"\n#include \"helper/system.h\"\n#include <jtag/jtag.h>\n#include <svf/svf.h>\n\n/* XSVF commands, from appendix B of xapp503.pdf  */\n#define XCOMPLETE\t\t\t0x00\n#define XTDOMASK\t\t\t0x01\n#define XSIR\t\t\t\t0x02\n#define XSDR\t\t\t\t0x03\n#define XRUNTEST\t\t\t0x04\n#define XREPEAT\t\t\t\t0x07\n#define XSDRSIZE\t\t\t0x08\n#define XSDRTDO\t\t\t\t0x09\n#define XSETSDRMASKS\t\t0x0A\n#define XSDRINC\t\t\t\t0x0B\n#define XSDRB\t\t\t\t0x0C\n#define XSDRC\t\t\t\t0x0D\n#define XSDRE\t\t\t\t0x0E\n#define XSDRTDOB\t\t\t0x0F\n#define XSDRTDOC\t\t\t0x10\n#define XSDRTDOE\t\t\t0x11\n#define XSTATE\t\t\t\t0x12\n#define XENDIR\t\t\t\t0x13\n#define XENDDR\t\t\t\t0x14\n#define XSIR2\t\t\t\t0x15\n#define XCOMMENT\t\t\t0x16\n#define XWAIT\t\t\t\t0x17\n\n/* XWAITSTATE is not in the xilinx XSVF spec, but the svf2xsvf.py translator\n * generates this.  Arguably it is needed because the XSVF XRUNTEST command\n * was ill conceived and does not directly flow out of the SVF RUNTEST command.\n * This XWAITSTATE does map directly from the SVF RUNTEST command.\n */\n#define XWAITSTATE\t\t\t0x18\n\n/* Lattice has extended the SVF file format, and Dick Hollenbeck's python based\n * SVF2XSVF converter supports these 3 additional XSVF opcodes, LCOUNT, LDELAY, LSDR.\n * Here is an example of usage of the 3 lattice opcode extensions:\n\n! Set the maximum loop count to 25.\nLCOUNT\t25;\n! Step to DRPAUSE give 5 clocks and wait for 1.00e + 000 SEC.\nLDELAY\tDRPAUSE\t5 TCK\t1.00E-003 SEC;\n! Test for the completed status. Match means pass.\n! Loop back to LDELAY line if not match and loop count less than 25.\n\nLSDR 1  TDI  (0)\nTDO  (1);\n*/\n\n#define LCOUNT\t\t\t\t0x19\n#define LDELAY\t\t\t\t0x1A\n#define LSDR\t\t\t\t0x1B\n#define XTRST\t\t\t\t0x1C\n\n/* XSVF valid state values for the XSTATE command, from appendix B of xapp503.pdf */\n#define XSV_RESET\t\t\t0x00\n#define XSV_IDLE\t\t\t0x01\n#define XSV_DRSELECT\t\t0x02\n#define XSV_DRCAPTURE\t\t0x03\n#define XSV_DRSHIFT\t\t\t0x04\n#define XSV_DREXIT1\t\t\t0x05\n#define XSV_DRPAUSE\t\t\t0x06\n#define XSV_DREXIT2\t\t\t0x07\n#define XSV_DRUPDATE\t\t0x08\n#define XSV_IRSELECT\t\t0x09\n#define XSV_IRCAPTURE\t\t0x0A\n#define XSV_IRSHIFT\t\t\t0x0B\n#define XSV_IREXIT1\t\t\t0x0C\n#define XSV_IRPAUSE\t\t\t0x0D\n#define XSV_IREXIT2\t\t\t0x0E\n#define XSV_IRUPDATE\t\t0x0F\n\n/* arguments to XTRST */\n#define XTRST_ON\t\t\t0\n#define XTRST_OFF\t\t\t1\n#define XTRST_Z\t\t\t\t2\n#define XTRST_ABSENT\t\t3\n\n#define XSTATE_MAX_PATH 12\n\nstatic int xsvf_fd;\n\n/* map xsvf tap state to an openocd \"tap_state_t\" */\nstatic tap_state_t xsvf_to_tap(int xsvf_state)\n{\n\ttap_state_t ret;\n\n\tswitch (xsvf_state) {\n\t\tcase XSV_RESET:\n\t\t\tret = TAP_RESET;\n\t\t\tbreak;\n\t\tcase XSV_IDLE:\n\t\t\tret = TAP_IDLE;\n\t\t\tbreak;\n\t\tcase XSV_DRSELECT:\n\t\t\tret = TAP_DRSELECT;\n\t\t\tbreak;\n\t\tcase XSV_DRCAPTURE:\n\t\t\tret = TAP_DRCAPTURE;\n\t\t\tbreak;\n\t\tcase XSV_DRSHIFT:\n\t\t\tret = TAP_DRSHIFT;\n\t\t\tbreak;\n\t\tcase XSV_DREXIT1:\n\t\t\tret = TAP_DREXIT1;\n\t\t\tbreak;\n\t\tcase XSV_DRPAUSE:\n\t\t\tret = TAP_DRPAUSE;\n\t\t\tbreak;\n\t\tcase XSV_DREXIT2:\n\t\t\tret = TAP_DREXIT2;\n\t\t\tbreak;\n\t\tcase XSV_DRUPDATE:\n\t\t\tret = TAP_DRUPDATE;\n\t\t\tbreak;\n\t\tcase XSV_IRSELECT:\n\t\t\tret = TAP_IRSELECT;\n\t\t\tbreak;\n\t\tcase XSV_IRCAPTURE:\n\t\t\tret = TAP_IRCAPTURE;\n\t\t\tbreak;\n\t\tcase XSV_IRSHIFT:\n\t\t\tret = TAP_IRSHIFT;\n\t\t\tbreak;\n\t\tcase XSV_IREXIT1:\n\t\t\tret = TAP_IREXIT1;\n\t\t\tbreak;\n\t\tcase XSV_IRPAUSE:\n\t\t\tret = TAP_IRPAUSE;\n\t\t\tbreak;\n\t\tcase XSV_IREXIT2:\n\t\t\tret = TAP_IREXIT2;\n\t\t\tbreak;\n\t\tcase XSV_IRUPDATE:\n\t\t\tret = TAP_IRUPDATE;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tLOG_ERROR(\"UNKNOWN XSVF STATE 0x%02X\", xsvf_state);\n\t\t\texit(1);\n\t}\n\n\treturn ret;\n}\n\nstatic int xsvf_read_buffer(int num_bits, int fd, uint8_t *buf)\n{\n\tint num_bytes;\n\n\tfor (num_bytes = (num_bits + 7) / 8; num_bytes > 0; num_bytes--) {\n\t\t/* reverse the order of bytes as they are read sequentially from file */\n\t\tif (read(fd, buf + num_bytes - 1, 1) < 0)\n\t\t\treturn ERROR_XSVF_EOF;\n\t}\n\n\treturn ERROR_OK;\n}\n\nCOMMAND_HANDLER(handle_xsvf_command)\n{\n\tuint8_t *dr_out_buf = NULL;\t\t\t\t/* from host to device (TDI) */\n\tuint8_t *dr_in_buf = NULL;\t\t\t\t/* from device to host (TDO) */\n\tuint8_t *dr_in_mask = NULL;\n\n\tint xsdrsize = 0;\n\tint xruntest = 0;\t\t\t\t\t/* number of TCK cycles OR *microseconds */\n\tint xrepeat = 0;\t\t\t\t\t/* number of retries */\n\n\ttap_state_t xendir = TAP_IDLE;\t\t\t/* see page 8 of the SVF spec, initial\n\t\t\t\t\t\t\t *xendir to be TAP_IDLE */\n\ttap_state_t xenddr = TAP_IDLE;\n\n\tuint8_t opcode;\n\tuint8_t uc = 0;\n\tlong file_offset = 0;\n\n\tint loop_count = 0;\n\ttap_state_t loop_state = TAP_IDLE;\n\tint loop_clocks = 0;\n\tint loop_usecs = 0;\n\n\tint do_abort = 0;\n\tint unsupported = 0;\n\tint tdo_mismatch = 0;\n\tint result;\n\tint verbose = 1;\n\n\tbool collecting_path = false;\n\ttap_state_t path[XSTATE_MAX_PATH];\n\tunsigned pathlen = 0;\n\n\t/* a flag telling whether to clock TCK during waits,\n\t * or simply sleep, controlled by virt2\n\t */\n\tint runtest_requires_tck = 0;\n\n\t/* use NULL to indicate a \"plain\" xsvf file which accounts for\n\t * additional devices in the scan chain, otherwise the device\n\t * that should be affected\n\t*/\n\tstruct jtag_tap *tap = NULL;\n\n\tif (CMD_ARGC < 2)\n\t\treturn ERROR_COMMAND_SYNTAX_ERROR;\n\n\t/* we mess with CMD_ARGV starting point below, snapshot filename here */\n\tconst char *filename = CMD_ARGV[1];\n\n\tif (strcmp(CMD_ARGV[0], \"plain\") != 0) {\n\t\ttap = jtag_tap_by_string(CMD_ARGV[0]);\n\t\tif (!tap) {\n\t\t\tcommand_print(CMD, \"Tap: %s unknown\", CMD_ARGV[0]);\n\t\t\treturn ERROR_FAIL;\n\t\t}\n\t}\n\n\txsvf_fd = open(filename, O_RDONLY);\n\tif (xsvf_fd < 0) {\n\t\tcommand_print(CMD, \"file \\\"%s\\\" not found\", filename);\n\t\treturn ERROR_FAIL;\n\t}\n\n\t/* if this argument is present, then interpret xruntest counts as TCK cycles rather than as\n\t *usecs */\n\tif ((CMD_ARGC > 2) && (strcmp(CMD_ARGV[2], \"virt2\") == 0)) {\n\t\truntest_requires_tck = 1;\n\t\t--CMD_ARGC;\n\t\t++CMD_ARGV;\n\t}\n\n\tif ((CMD_ARGC > 2) && (strcmp(CMD_ARGV[2], \"quiet\") == 0))\n\t\tverbose = 0;\n\n\tLOG_WARNING(\"XSVF support in OpenOCD is limited. Consider using SVF instead\");\n\tLOG_USER(\"xsvf processing file: \\\"%s\\\"\", filename);\n\n\twhile (read(xsvf_fd, &opcode, 1) > 0) {\n\t\t/* record the position of this opcode within the file */\n\t\tfile_offset = lseek(xsvf_fd, 0, SEEK_CUR) - 1;\n\n\t\t/* maybe collect another state for a pathmove();\n\t\t * or terminate a path.\n\t\t */\n\t\tif (collecting_path) {\n\t\t\ttap_state_t mystate;\n\n\t\t\tswitch (opcode) {\n\t\t\t\tcase XCOMMENT:\n\t\t\t\t\t/* ignore/show comments between XSTATE ops */\n\t\t\t\t\tbreak;\n\t\t\t\tcase XSTATE:\n\t\t\t\t\t/* try to collect another transition */\n\t\t\t\t\tif (pathlen == XSTATE_MAX_PATH) {\n\t\t\t\t\t\tLOG_ERROR(\"XSVF: path too long\");\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (read(xsvf_fd, &uc, 1) < 0) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tmystate = xsvf_to_tap(uc);\n\t\t\t\t\tpath[pathlen++] = mystate;\n\n\t\t\t\t\tLOG_DEBUG(\"XSTATE 0x%02X %s\", uc,\n\t\t\t\t\ttap_state_name(mystate));\n\n\t\t\t\t\t/* If path is incomplete, collect more */\n\t\t\t\t\tif (!svf_tap_state_is_stable(mystate))\n\t\t\t\t\t\tcontinue;\n\n\t\t\t\t\t/* Else execute the path transitions we've\n\t\t\t\t\t * collected so far.\n\t\t\t\t\t *\n\t\t\t\t\t * NOTE:  Punting on the saved path is not\n\t\t\t\t\t * strictly correct, but we must to do this\n\t\t\t\t\t * unless jtag_add_pathmove() stops rejecting\n\t\t\t\t\t * paths containing RESET.  This is probably\n\t\t\t\t\t * harmless, since there aren't many options\n\t\t\t\t\t * for going from a stable state to reset;\n\t\t\t\t\t * at the worst, we may issue extra clocks\n\t\t\t\t\t * once we get to RESET.\n\t\t\t\t\t */\n\t\t\t\t\tif (mystate == TAP_RESET) {\n\t\t\t\t\t\tLOG_WARNING(\"XSVF: dodgey RESET\");\n\t\t\t\t\t\tpath[0] = mystate;\n\t\t\t\t\t}\n\n\t\t\t\t/* FALL THROUGH */\n\t\t\t\tdefault:\n\t\t\t\t\t/* Execute the path we collected\n\t\t\t\t\t *\n\t\t\t\t\t * NOTE: OpenOCD requires something that XSVF\n\t\t\t\t\t * doesn't:  the last TAP state in the path\n\t\t\t\t\t * must be stable.  In practice, tools that\n\t\t\t\t\t * create XSVF seem to follow that rule too.\n\t\t\t\t\t */\n\t\t\t\t\tcollecting_path = false;\n\n\t\t\t\t\tif (path[0] == TAP_RESET)\n\t\t\t\t\t\tjtag_add_tlr();\n\t\t\t\t\telse\n\t\t\t\t\t\tjtag_add_pathmove(pathlen, path);\n\n\t\t\t\t\tresult = jtag_execute_queue();\n\t\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\t\tLOG_ERROR(\"XSVF: pathmove error %d\", result);\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tswitch (opcode) {\n\t\t\tcase XCOMPLETE:\n\t\t\t\tLOG_DEBUG(\"XCOMPLETE\");\n\n\t\t\t\tresult = jtag_execute_queue();\n\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\ttdo_mismatch = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase XTDOMASK:\n\t\t\t\tLOG_DEBUG(\"XTDOMASK\");\n\t\t\t\tif (dr_in_mask &&\n\t\t\t\t\t\t(xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_mask) != ERROR_OK))\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XRUNTEST:\n\t\t\t{\n\t\t\t\tuint8_t xruntest_buf[4];\n\n\t\t\t\tif (read(xsvf_fd, xruntest_buf, 4) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\txruntest = be_to_h_u32(xruntest_buf);\n\t\t\t\tLOG_DEBUG(\"XRUNTEST %d 0x%08X\", xruntest, xruntest);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XREPEAT:\n\t\t\t{\n\t\t\t\tuint8_t myrepeat;\n\n\t\t\t\tif (read(xsvf_fd, &myrepeat, 1) < 0)\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\telse {\n\t\t\t\t\txrepeat = myrepeat;\n\t\t\t\t\tLOG_DEBUG(\"XREPEAT %d\", xrepeat);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XSDRSIZE:\n\t\t\t{\n\t\t\t\tuint8_t xsdrsize_buf[4];\n\n\t\t\t\tif (read(xsvf_fd, xsdrsize_buf, 4) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\txsdrsize = be_to_h_u32(xsdrsize_buf);\n\t\t\t\tLOG_DEBUG(\"XSDRSIZE %d\", xsdrsize);\n\n\t\t\t\tfree(dr_out_buf);\n\t\t\t\tfree(dr_in_buf);\n\t\t\t\tfree(dr_in_mask);\n\n\t\t\t\tdr_out_buf = malloc((xsdrsize + 7) / 8);\n\t\t\t\tdr_in_buf = malloc((xsdrsize + 7) / 8);\n\t\t\t\tdr_in_mask = malloc((xsdrsize + 7) / 8);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XSDR:\t\t/* these two are identical except for the dr_in_buf */\n\t\t\tcase XSDRTDO:\n\t\t\t{\n\t\t\t\tint limit = xrepeat;\n\t\t\t\tint matched = 0;\n\t\t\t\tint attempt;\n\n\t\t\t\tconst char *op_name = (opcode == XSDR ? \"XSDR\" : \"XSDRTDO\");\n\n\t\t\t\tif (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (opcode == XSDRTDO) {\n\t\t\t\t\tif (xsvf_read_buffer(xsdrsize, xsvf_fd,\n\t\t\t\t\t\tdr_in_buf)  != ERROR_OK) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (limit < 1)\n\t\t\t\t\tlimit = 1;\n\n\t\t\t\tLOG_DEBUG(\"%s %d\", op_name, xsdrsize);\n\n\t\t\t\tfor (attempt = 0; attempt < limit; ++attempt) {\n\t\t\t\t\tstruct scan_field field;\n\n\t\t\t\t\tif (attempt > 0) {\n\t\t\t\t\t\t/* perform the XC9500 exception handling sequence shown in xapp067.pdf and\n\t\t\t\t\t\t * illustrated in pseudo code at end of this file.  We start from state\n\t\t\t\t\t\t * DRPAUSE:\n\t\t\t\t\t\t * go to Exit2-DR\n\t\t\t\t\t\t * go to Shift-DR\n\t\t\t\t\t\t * go to Exit1-DR\n\t\t\t\t\t\t * go to Update-DR\n\t\t\t\t\t\t * go to Run-Test/Idle\n\t\t\t\t\t\t *\n\t\t\t\t\t\t * This sequence should be harmless for other devices, and it\n\t\t\t\t\t\t * will be skipped entirely if xrepeat is set to zero.\n\t\t\t\t\t\t */\n\n\t\t\t\t\t\tstatic tap_state_t exception_path[] = {\n\t\t\t\t\t\t\tTAP_DREXIT2,\n\t\t\t\t\t\t\tTAP_DRSHIFT,\n\t\t\t\t\t\t\tTAP_DREXIT1,\n\t\t\t\t\t\t\tTAP_DRUPDATE,\n\t\t\t\t\t\t\tTAP_IDLE,\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\tjtag_add_pathmove(ARRAY_SIZE(exception_path), exception_path);\n\n\t\t\t\t\t\tif (verbose)\n\t\t\t\t\t\t\tLOG_USER(\"%s mismatch, xsdrsize=%d retry=%d\",\n\t\t\t\t\t\t\t\t\top_name,\n\t\t\t\t\t\t\t\t\txsdrsize,\n\t\t\t\t\t\t\t\t\tattempt);\n\t\t\t\t\t}\n\n\t\t\t\t\tfield.num_bits = xsdrsize;\n\t\t\t\t\tfield.out_value = dr_out_buf;\n\t\t\t\t\tfield.in_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\n\t\t\t\t\tif (!tap)\n\t\t\t\t\t\tjtag_add_plain_dr_scan(field.num_bits,\n\t\t\t\t\t\t\t\tfield.out_value,\n\t\t\t\t\t\t\t\tfield.in_value,\n\t\t\t\t\t\t\t\tTAP_DRPAUSE);\n\t\t\t\t\telse\n\t\t\t\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);\n\n\t\t\t\t\tjtag_check_value_mask(&field, dr_in_buf, dr_in_mask);\n\n\t\t\t\t\tfree(field.in_value);\n\n\t\t\t\t\t/* LOG_DEBUG(\"FLUSHING QUEUE\"); */\n\t\t\t\t\tresult = jtag_execute_queue();\n\t\t\t\t\tif (result == ERROR_OK) {\n\t\t\t\t\t\tmatched = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matched) {\n\t\t\t\t\tLOG_USER(\"%s mismatch\", op_name);\n\t\t\t\t\ttdo_mismatch = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* See page 19 of XSVF spec regarding opcode \"XSDR\" */\n\t\t\t\tif (xruntest) {\n\t\t\t\t\tresult = svf_add_statemove(TAP_IDLE);\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\treturn result;\n\n\t\t\t\t\tif (runtest_requires_tck)\n\t\t\t\t\t\tjtag_add_clocks(xruntest);\n\t\t\t\t\telse\n\t\t\t\t\t\tjtag_add_sleep(xruntest);\n\t\t\t\t} else if (xendir != TAP_DRPAUSE) {\n\t\t\t\t\t/* we are already in TAP_DRPAUSE */\n\t\t\t\t\tresult = svf_add_statemove(xenddr);\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XSETSDRMASKS:\n\t\t\t\tLOG_ERROR(\"unsupported XSETSDRMASKS\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRINC:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRINC\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRB:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRB\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRC:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRC\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRE:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRE\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRTDOB:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRTDOB\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRTDOC:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRTDOC\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSDRTDOE:\n\t\t\t\tLOG_ERROR(\"unsupported XSDRTDOE\");\n\t\t\t\tunsupported = 1;\n\t\t\t\tbreak;\n\n\t\t\tcase XSTATE:\n\t\t\t{\n\t\t\t\ttap_state_t mystate;\n\n\t\t\t\tif (read(xsvf_fd, &uc, 1) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tmystate = xsvf_to_tap(uc);\n\n\t\t\t\tLOG_DEBUG(\"XSTATE 0x%02X %s\", uc, tap_state_name(mystate));\n\n\t\t\t\tif (mystate == TAP_INVALID) {\n\t\t\t\t\tLOG_ERROR(\"XSVF: bad XSTATE %02x\", uc);\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* NOTE: the current state is SVF-stable! */\n\n\t\t\t\t/* no change == NOP */\n\t\t\t\tif (mystate == cmd_queue_cur_state\n\t\t\t\t\t\t&& mystate != TAP_RESET)\n\t\t\t\t\tbreak;\n\n\t\t\t\t/* Hand off to SVF? */\n\t\t\t\tif (svf_tap_state_is_stable(mystate)) {\n\t\t\t\t\tresult = svf_add_statemove(mystate);\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\tunsupported = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * A sequence of XSTATE transitions, each TAP\n\t\t\t\t * state adjacent to the previous one.  Start\n\t\t\t\t * collecting them.\n\t\t\t\t */\n\t\t\t\tcollecting_path = true;\n\t\t\t\tpathlen = 1;\n\t\t\t\tpath[0] = mystate;\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XENDIR:\n\n\t\t\t\tif (read(xsvf_fd, &uc, 1) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* see page 22 of XSVF spec */\n\t\t\t\tif (uc == 0)\n\t\t\t\t\txendir = TAP_IDLE;\n\t\t\t\telse if (uc == 1)\n\t\t\t\t\txendir = TAP_IRPAUSE;\n\t\t\t\telse {\n\t\t\t\t\tLOG_ERROR(\"illegial XENDIR argument: 0x%02X\", uc);\n\t\t\t\t\tunsupported = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tLOG_DEBUG(\"XENDIR 0x%02X %s\", uc, tap_state_name(xendir));\n\t\t\t\tbreak;\n\n\t\t\tcase XENDDR:\n\n\t\t\t\tif (read(xsvf_fd, &uc, 1) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* see page 22 of XSVF spec */\n\t\t\t\tif (uc == 0)\n\t\t\t\t\txenddr = TAP_IDLE;\n\t\t\t\telse if (uc == 1)\n\t\t\t\t\txenddr = TAP_DRPAUSE;\n\t\t\t\telse {\n\t\t\t\t\tLOG_ERROR(\"illegial XENDDR argument: 0x%02X\", uc);\n\t\t\t\t\tunsupported = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tLOG_DEBUG(\"XENDDR %02X %s\", uc, tap_state_name(xenddr));\n\t\t\t\tbreak;\n\n\t\t\tcase XSIR:\n\t\t\tcase XSIR2:\n\t\t\t{\n\t\t\t\tuint8_t short_buf[2];\n\t\t\t\tuint8_t *ir_buf;\n\t\t\t\tint bitcount;\n\t\t\t\ttap_state_t my_end_state = xruntest ? TAP_IDLE : xendir;\n\n\t\t\t\tif (opcode == XSIR) {\n\t\t\t\t\t/* one byte bitcount */\n\t\t\t\t\tif (read(xsvf_fd, short_buf, 1) < 0) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbitcount = short_buf[0];\n\t\t\t\t\tLOG_DEBUG(\"XSIR %d\", bitcount);\n\t\t\t\t} else {\n\t\t\t\t\tif (read(xsvf_fd, short_buf, 2) < 0) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbitcount = be_to_h_u16(short_buf);\n\t\t\t\t\tLOG_DEBUG(\"XSIR2 %d\", bitcount);\n\t\t\t\t}\n\n\t\t\t\tir_buf = malloc((bitcount + 7) / 8);\n\n\t\t\t\tif (xsvf_read_buffer(bitcount, xsvf_fd, ir_buf) != ERROR_OK)\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\telse {\n\t\t\t\t\tstruct scan_field field;\n\n\t\t\t\t\tfield.num_bits = bitcount;\n\t\t\t\t\tfield.out_value = ir_buf;\n\n\t\t\t\t\tfield.in_value = NULL;\n\n\t\t\t\t\tif (!tap)\n\t\t\t\t\t\tjtag_add_plain_ir_scan(field.num_bits,\n\t\t\t\t\t\t\t\tfield.out_value, field.in_value, my_end_state);\n\t\t\t\t\telse\n\t\t\t\t\t\tjtag_add_ir_scan(tap, &field, my_end_state);\n\n\t\t\t\t\tif (xruntest) {\n\t\t\t\t\t\tif (runtest_requires_tck)\n\t\t\t\t\t\t\tjtag_add_clocks(xruntest);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tjtag_add_sleep(xruntest);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Note that an -irmask of non-zero in your config file\n\t\t\t\t\t * can cause this to fail.  Setting -irmask to zero cand work\n\t\t\t\t\t * around the problem.\n\t\t\t\t\t */\n\n\t\t\t\t\t/* LOG_DEBUG(\"FLUSHING QUEUE\"); */\n\t\t\t\t\tresult = jtag_execute_queue();\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\ttdo_mismatch = 1;\n\t\t\t\t}\n\t\t\t\tfree(ir_buf);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XCOMMENT:\n\t\t\t{\n\t\t\t\tunsigned int ndx = 0;\n\t\t\t\tchar comment[128];\n\n\t\t\t\tdo {\n\t\t\t\t\tif (read(xsvf_fd, &uc, 1) < 0) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (ndx < sizeof(comment)-1)\n\t\t\t\t\t\tcomment[ndx++] = uc;\n\n\t\t\t\t} while (uc != 0);\n\n\t\t\t\tcomment[sizeof(comment)-1] = 0;\t\t/* regardless, terminate */\n\t\t\t\tif (verbose)\n\t\t\t\t\tLOG_USER(\"# %s\", comment);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XWAIT:\n\t\t\t{\n\t\t\t\t/* expected in stream:\n\t\t\t\t   XWAIT <uint8_t wait_state> <uint8_t end_state> <uint32_t usecs>\n\t\t\t\t*/\n\n\t\t\t\tuint8_t wait_local;\n\t\t\t\tuint8_t end;\n\t\t\t\tuint8_t delay_buf[4];\n\n\t\t\t\ttap_state_t wait_state;\n\t\t\t\ttap_state_t end_state;\n\t\t\t\tint delay;\n\n\t\t\t\tif (read(xsvf_fd, &wait_local, 1) < 0\n\t\t\t\t\t|| read(xsvf_fd, &end, 1) < 0\n\t\t\t\t\t|| read(xsvf_fd, delay_buf, 4) < 0) {\n\t\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\twait_state = xsvf_to_tap(wait_local);\n\t\t\t\tend_state  = xsvf_to_tap(end);\n\t\t\t\tdelay = be_to_h_u32(delay_buf);\n\n\t\t\t\tLOG_DEBUG(\"XWAIT %s %s usecs:%d\", tap_state_name(\n\t\t\t\t\t\twait_state), tap_state_name(end_state), delay);\n\n\t\t\t\tif (runtest_requires_tck && wait_state == TAP_IDLE)\n\t\t\t\t\tjtag_add_runtest(delay, end_state);\n\t\t\t\telse {\n\t\t\t\t\t/* FIXME handle statemove errors ... */\n\t\t\t\t\tresult = svf_add_statemove(wait_state);\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\treturn result;\n\t\t\t\t\tjtag_add_sleep(delay);\n\t\t\t\t\tresult = svf_add_statemove(end_state);\n\t\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\t\treturn result;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XWAITSTATE:\n\t\t\t{\n\t\t\t\t/* expected in stream:\n\t\t\t\t * XWAITSTATE <uint8_t wait_state> <uint8_t end_state> <uint32_t clock_count>\n\t\t\t\t * <uint32_t usecs>\n\t\t\t\t*/\n\n\t\t\t\tuint8_t clock_buf[4];\n\t\t\t\tuint8_t usecs_buf[4];\n\t\t\t\tuint8_t wait_local;\n\t\t\t\tuint8_t end;\n\t\t\t\ttap_state_t wait_state;\n\t\t\t\ttap_state_t end_state;\n\t\t\t\tint clock_count;\n\t\t\t\tint usecs;\n\n\t\t\t\tif (read(xsvf_fd, &wait_local, 1) < 0\n\t\t\t\t\t\t||  read(xsvf_fd, &end, 1) < 0\n\t\t\t\t\t\t||  read(xsvf_fd, clock_buf, 4) < 0\n\t\t\t\t\t\t||  read(xsvf_fd, usecs_buf, 4) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\twait_state = xsvf_to_tap(wait_local);\n\t\t\t\tend_state  = xsvf_to_tap(end);\n\n\t\t\t\tclock_count = be_to_h_u32(clock_buf);\n\t\t\t\tusecs = be_to_h_u32(usecs_buf);\n\n\t\t\t\tLOG_DEBUG(\"XWAITSTATE %s %s clocks:%i usecs:%i\",\n\t\t\t\t\t\ttap_state_name(wait_state),\n\t\t\t\t\t\ttap_state_name(end_state),\n\t\t\t\t\t\tclock_count, usecs);\n\n\t\t\t\t/* the following states are 'stable', meaning that they have a transition\n\t\t\t\t * in the state diagram back to themselves.  This is necessary because we will\n\t\t\t\t * be issuing a number of clocks in this state.  This set of allowed states is also\n\t\t\t\t * determined by the SVF RUNTEST command's allowed states.\n\t\t\t\t */\n\t\t\t\tif (!svf_tap_state_is_stable(wait_state)) {\n\t\t\t\t\tLOG_ERROR(\"illegal XWAITSTATE wait_state: \\\"%s\\\"\",\n\t\t\t\t\t\t\ttap_state_name(wait_state));\n\t\t\t\t\tunsupported = 1;\n\t\t\t\t\t/* REVISIT \"break\" so we won't run? */\n\t\t\t\t}\n\n\t\t\t\t/* FIXME handle statemove errors ... */\n\t\t\t\tresult = svf_add_statemove(wait_state);\n\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\treturn result;\n\n\t\t\t\tjtag_add_clocks(clock_count);\n\t\t\t\tjtag_add_sleep(usecs);\n\n\t\t\t\tresult = svf_add_statemove(end_state);\n\t\t\t\tif (result != ERROR_OK)\n\t\t\t\t\treturn result;\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase LCOUNT:\n\t\t\t{\n\t\t\t\t/* expected in stream:\n\t\t\t\t * LCOUNT <uint32_t loop_count>\n\t\t\t\t*/\n\t\t\t\tuint8_t count_buf[4];\n\n\t\t\t\tif (read(xsvf_fd, count_buf, 4) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tloop_count = be_to_h_u32(count_buf);\n\t\t\t\tLOG_DEBUG(\"LCOUNT %d\", loop_count);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase LDELAY:\n\t\t\t{\n\t\t\t\t/* expected in stream:\n\t\t\t\t * LDELAY <uint8_t wait_state> <uint32_t clock_count> <uint32_t usecs_to_sleep>\n\t\t\t\t*/\n\t\t\t\tuint8_t state;\n\t\t\t\tuint8_t clock_buf[4];\n\t\t\t\tuint8_t usecs_buf[4];\n\n\t\t\t\tif (read(xsvf_fd, &state, 1) < 0\n\t\t\t\t\t\t|| read(xsvf_fd, clock_buf, 4) < 0\n\t\t\t\t\t\t|| read(xsvf_fd, usecs_buf, 4) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* NOTE:  loop_state must be stable! */\n\t\t\t\tloop_state  = xsvf_to_tap(state);\n\t\t\t\tloop_clocks = be_to_h_u32(clock_buf);\n\t\t\t\tloop_usecs  = be_to_h_u32(usecs_buf);\n\n\t\t\t\tLOG_DEBUG(\"LDELAY %s clocks:%d usecs:%d\", tap_state_name(\n\t\t\t\t\t\tloop_state), loop_clocks, loop_usecs);\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\t/* LSDR is more like XSDRTDO than it is like XSDR.  It uses LDELAY which\n\t\t\t * comes with clocks !AND! sleep requirements.\n\t\t\t */\n\t\t\tcase LSDR:\n\t\t\t{\n\t\t\t\tint limit = loop_count;\n\t\t\t\tint matched = 0;\n\t\t\t\tint attempt;\n\n\t\t\t\tLOG_DEBUG(\"LSDR\");\n\n\t\t\t\tif (xsvf_read_buffer(xsdrsize, xsvf_fd, dr_out_buf) != ERROR_OK\n\t\t\t\t\t\t|| xsvf_read_buffer(xsdrsize, xsvf_fd, dr_in_buf) != ERROR_OK) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (limit < 1)\n\t\t\t\t\tlimit = 1;\n\n\t\t\t\tfor (attempt = 0; attempt < limit; ++attempt) {\n\t\t\t\t\tstruct scan_field field;\n\n\t\t\t\t\tresult = svf_add_statemove(loop_state);\n\t\t\t\t\tif (result != ERROR_OK) {\n\t\t\t\t\t\tfree(dr_in_mask);\n\t\t\t\t\t\treturn result;\n\t\t\t\t\t}\n\t\t\t\t\tjtag_add_clocks(loop_clocks);\n\t\t\t\t\tjtag_add_sleep(loop_usecs);\n\n\t\t\t\t\tfield.num_bits = xsdrsize;\n\t\t\t\t\tfield.out_value = dr_out_buf;\n\t\t\t\t\tfield.in_value = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);\n\n\t\t\t\t\tif (attempt > 0 && verbose)\n\t\t\t\t\t\tLOG_USER(\"LSDR retry %d\", attempt);\n\n\t\t\t\t\tif (!tap)\n\t\t\t\t\t\tjtag_add_plain_dr_scan(field.num_bits,\n\t\t\t\t\t\t\t\tfield.out_value,\n\t\t\t\t\t\t\t\tfield.in_value,\n\t\t\t\t\t\t\t\tTAP_DRPAUSE);\n\t\t\t\t\telse\n\t\t\t\t\t\tjtag_add_dr_scan(tap, 1, &field, TAP_DRPAUSE);\n\n\t\t\t\t\tjtag_check_value_mask(&field, dr_in_buf, dr_in_mask);\n\n\t\t\t\t\tfree(field.in_value);\n\n\n\t\t\t\t\t/* LOG_DEBUG(\"FLUSHING QUEUE\"); */\n\t\t\t\t\tresult = jtag_execute_queue();\n\t\t\t\t\tif (result == ERROR_OK) {\n\t\t\t\t\t\tmatched = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!matched) {\n\t\t\t\t\tLOG_USER(\"LSDR mismatch\");\n\t\t\t\t\ttdo_mismatch = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tcase XTRST:\n\t\t\t{\n\t\t\t\tuint8_t trst_mode;\n\n\t\t\t\tif (read(xsvf_fd, &trst_mode, 1) < 0) {\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tswitch (trst_mode) {\n\t\t\t\tcase XTRST_ON:\n\t\t\t\t\tjtag_add_reset(1, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase XTRST_OFF:\n\t\t\t\tcase XTRST_Z:\n\t\t\t\t\tjtag_add_reset(0, 0);\n\t\t\t\t\tbreak;\n\t\t\t\tcase XTRST_ABSENT:\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tLOG_ERROR(\"XTRST mode argument (0x%02X) out of range\", trst_mode);\n\t\t\t\t\tdo_abort = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tLOG_ERROR(\"unknown xsvf command (0x%02X)\", uc);\n\t\t\t\tunsupported = 1;\n\t\t}\n\n\t\tif (do_abort || unsupported || tdo_mismatch) {\n\t\t\tLOG_DEBUG(\"xsvf failed, setting taps to reasonable state\");\n\n\t\t\t/* upon error, return the TAPs to a reasonable state */\n\t\t\tresult = svf_add_statemove(TAP_IDLE);\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t\tresult = jtag_execute_queue();\n\t\t\tif (result != ERROR_OK)\n\t\t\t\treturn result;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tif (tdo_mismatch) {\n\t\tcommand_print(CMD,\n\t\t\t\"TDO mismatch, somewhere near offset %lu in xsvf file, aborting\",\n\t\t\tfile_offset);\n\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (unsupported) {\n\t\toff_t offset = lseek(xsvf_fd, 0, SEEK_CUR) - 1;\n\t\tcommand_print(CMD,\n\t\t\t\"unsupported xsvf command (0x%02X) at offset %jd, aborting\",\n\t\t\tuc, (intmax_t)offset);\n\t\treturn ERROR_FAIL;\n\t}\n\n\tif (do_abort) {\n\t\tcommand_print(CMD, \"premature end of xsvf file detected, aborting\");\n\t\treturn ERROR_FAIL;\n\t}\n\n\tfree(dr_out_buf);\n\tfree(dr_in_buf);\n\tfree(dr_in_mask);\n\n\tclose(xsvf_fd);\n\n\tcommand_print(CMD, \"XSVF file programmed successfully\");\n\n\treturn ERROR_OK;\n}\n\nstatic const struct command_registration xsvf_command_handlers[] = {\n\t{\n\t\t.name = \"xsvf\",\n\t\t.handler = handle_xsvf_command,\n\t\t.mode = COMMAND_EXEC,\n\t\t.help = \"Runs a XSVF file.  If 'virt2' is given, xruntest \"\n\t\t\t\"counts are interpreted as TCK cycles rather than \"\n\t\t\t\"as microseconds.  Without the 'quiet' option, all \"\n\t\t\t\"comments, retries, and mismatches will be reported.\",\n\t\t.usage = \"(tapname|'plain') filename ['virt2'] ['quiet']\",\n\t},\n\tCOMMAND_REGISTRATION_DONE\n};\n\nint xsvf_register_commands(struct command_context *cmd_ctx)\n{\n\treturn register_commands(cmd_ctx, NULL, xsvf_command_handlers);\n}\n\n/*\n\nPSEUDO-Code from Xilinx Appnote XAPP067.pdf :\n\nthe following pseudo code clarifies the intent of the xrepeat support.The\nflow given is for the entire processing of an SVF file, not an XSVF file.\nNo idea if this is just for the XC9500/XL/XV devices or all Xilinx parts.\n\n\"Pseudo-Code Algorithm for SVF-Based ISP\"\n\n1. Go to Test-Logic-Reset state\n2. Go to Run-Test Idle state\n3. Read SVF record\n\n4. if SIR record then\ngo to Shift-IR state\nScan in <TDI value>\n\n5. else if SDR record then\nset <repeat count> to 0\nstore <TDI value> as <current TDI value>\nstore <TDO value> as <current TDO value>\n6. go to Shift-DR state\nscan in <current TDI value>\nif < current TDO value > is specified then\nif < current TDO value > does not equal <actual TDO value> then\nif < repeat count > > 32 then\nLOG ERROR\ngo to Run-Test Idle state\ngo to Step 3\nend if\ngo to Pause-DR\ngo to Exit2-DR\ngo to Shift-DR\ngo to Exit1-DR\ngo to Update-DR\ngo to Run-Test/Idle\nincrement <repeat count> by 1\npause <current pause time> microseconds\ngo to Step 6)\nend if\nelse\n\tgo to Run-Test Idle state\n\tgo to Step 3\n\tendif\n\telse if RUNTEST record then\n\tpause tester for < TCK value > microseconds\n\tstore <TCK value> as <current pause time>\n\tend if\n\n*/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/src/xsvf/xsvf.h",
    "content": "/* SPDX-License-Identifier: GPL-2.0-or-later */\n\n/***************************************************************************\n *   Copyright (C) 2005 by Dominic Rath                                    *\n *   Dominic.Rath@gmx.de                                                   *\n ***************************************************************************/\n\n#ifndef OPENOCD_XSVF_XSVF_H\n#define OPENOCD_XSVF_XSVF_H\n\n#include <helper/command.h>\n\nint xsvf_register_commands(struct command_context *cmd_ctx);\n\n#define ERROR_XSVF_EOF  (-200)\n#define ERROR_XSVF_FAILED       (-201)\n\n#endif /* OPENOCD_XSVF_XSVF_H */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/bitsbytes.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#----------------------------------------\n# Purpose - Create some $BIT variables\n#           Create $K and $M variables\n#          and some bit field extraction variables.\n# Create helper variables ...\n#    BIT0.. BIT31\n\nfor { set x 0  } { $x < 32 } { set x [expr {$x + 1}]} {\n    set vn [format \"BIT%d\" $x]\n    global $vn\n    set $vn   [expr {1 << $x}]\n}\n\n# Create K bytes values\n#    __1K ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dK\" $x]\n    global $vn\n    set $vn   [expr {1024 * $x}]\n}\n\n# Create M bytes values\n#    __1M ... to __2048K\nfor { set x 1  } { $x < 2048 } { set x [expr {$x * 2}]} {\n    set vn [format \"__%dM\" $x]\n    global $vn\n    set $vn [expr {1024 * 1024 * $x}]\n}\n\nproc create_mask { MSB LSB } {\n    return [expr {((1 << ($MSB - $LSB + 1))-1) << $LSB}]\n}\n\n# Cut Bits $MSB to $LSB out of this value.\n# Example: % format \"0x%08x\" [extract_bitfield 0x12345678 27 16]\n# Result:  0x02340000\n\nproc extract_bitfield { VALUE MSB LSB } {\n    return [expr {[create_mask $MSB $LSB] & $VALUE}]\n}\n\n\n# Cut bits $MSB to $LSB out of this value\n# and shift (normalize) them down to bit 0.\n#\n# Example: % format \"0x%08x\" [normalize_bitfield 0x12345678 27 16]\n# Result:  0x00000234\n#\nproc normalize_bitfield { VALUE MSB LSB } {\n    return [expr {[extract_bitfield $VALUE $MSB $LSB ] >> $LSB}]\n}\n\nproc show_normalize_bitfield { VALUE MSB LSB } {\n    set m [create_mask $MSB $LSB]\n    set mr [expr {$VALUE & $m}]\n    set sr [expr {$mr >> $LSB}]\n    echo [format \"((0x%08x & 0x%08x) -> 0x%08x) >> %2d => (0x%x) %5d \" $VALUE $m $mr $LSB $sr $sr]\n   return $sr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/8devices-lima.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Product page:\n# https://www.8devices.com/products/lima\n#\n# Location of JTAG pins:\n# J2 GPIO0\tJTAG TCK\n# J2 GPIO1\tJTAG TDI\n# J2 GPIO2\tJTAG TDO\n# J2 GPIO3\tJTAG TMS\n# J2 RST\tdirectly connected to RESET_L of the SoC and can be used as\n#               JTAG SRST. Note: this pin will also reset the debug engine.\n# J1 +3,3V\tCan be use as JTAG Vref\n# J1 or J2 GND\tCan be used for JTAG GND\n#\n# This board is powered from mini USB connecter which is also used\n# as USB to UART converted based on FTDI FT230XQ chip\n\nsource [find target/qualcomm_qca4531.cfg]\n\nproc board_init { } {\n\tqca4531_ddr2_550_550_init\n}\n\n$_TARGETNAME configure -event reset-init {\n\tboard_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/actux3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# board config file for AcTux3/XBA IXP42x board\n# Date:   2010-12-16\n# Author: Michael Schwingen <michael@schwingen.org>\n\nreset_config trst_and_srst separate\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nsource [find target/ixp42x.cfg]\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init { init_actux3 }\n\nproc init_actux3 { } {\n    ##########################################################################\n    # setup expansion bus CS\n    ##########################################################################\n    mww 0xc4000000  0xbd113842  ;#CS0  : Flash, write enabled @0x50000000\n    mww 0xc4000004  0x94d10013  ;#CS1\n    mww 0xc4000008  0x95960003  ;#CS2\n    mww 0xc400000c  0x00000000  ;#CS3\n    mww 0xc4000010  0x80900003  ;#CS4\n    mww 0xc4000014  0x9d520003  ;#CS5\n    mww 0xc4000018  0x81860001  ;#CS6\n    mww 0xc400001c  0x80900003  ;#CS7\n\n    ixp42x_init_sdram $::IXP42x_SDRAM_16MB_4Mx16_1BANK 2100 3\n\n    #mww 0xc4000020  0xffffee ;# CFG0: remove expansion bus boot flash mirror at 0x00000000\n\n    ixp42x_set_bigendian\n\n    flash probe 0\n}\n\nproc flash_boot { {FILE \"/tftpboot/actux3/u-boot.bin\"} } {\n    echo \"writing bootloader: $FILE\"\n    flash write_image erase $FILE 0x50000000 bin\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x400000 2 2 $_TARGETNAME\n\ninit\nreset init\n\n# setup to debug u-boot in flash\nproc uboot_debug {} {\n    gdb_breakpoint_override hard\n    xscale vector_catch 0xFF\n\n    xscale vector_table low  1 0xe59ff018\n    xscale vector_table low  2 0xe59ff018\n    xscale vector_table low  3 0xe59ff018\n    xscale vector_table low  4 0xe59ff018\n    xscale vector_table low  5 0xe59ff018\n    xscale vector_table low  6 0xe59ff018\n    xscale vector_table low  7 0xe59ff018\n\n    xscale vector_table high 1 0xe59ff018\n    xscale vector_table high 2 0xe59ff018\n    xscale vector_table high 3 0xe59ff018\n    xscale vector_table high 4 0xe59ff018\n    xscale vector_table high 5 0xe59ff018\n    xscale vector_table high 6 0xe59ff018\n    xscale vector_table high 7 0xe59ff018\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/adapteva_parallella1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Adapteva Parallella-I board (via Porcupine-1 adapter board)\n#\n\nreset_config srst_only\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/adsp-sc584-ezbrd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Analog Devices ADSP-SC584-EZBRD evaluation board\n#\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\n# Analog expects users to use their proprietary ICE-1000 / ICE-2000 with all\n# ADSP-SC58x designs, but this is an ARM target (and subject to the\n# qualifications above) many ARM debug pods should be compatible.\n\n#source [find interface/cmsis-dap.cfg]\nsource [find interface/jlink.cfg]\n\n# Analog's silicon supports SWD and JTAG, but their proprietary ICE is limited\n# to JTAG.  (This is presumably why their connector pinout was modified.)\n# SWD is chosen here, as it is more efficient and doesn't require /TRST.\n\ntransport select swd\n\n# chosen speed is 'safe' choice, but your adapter may be capable of more\nadapter speed 400\n\nsource [find target/adsp-sc58x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/alphascale_asm9260_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/alphascale_asm9260t.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configure clock\"\n\t# Enable SRAM clk\n\tmww 0x80040024 0x4\n\t# Enable IRQ clk\n\tmww 0x80040034 0x100\n\t# Enable DMA0,1 clk\n\tmww 0x80040024 0x600\n\t# Make sysre syspll is enabled\n\tmww 0x80040238 0x750\n\t#CPU = PLLCLK/2\n\tmww 0x8004017C 0x2\n\t#SYSAHBCLK = CPUCLK/2\n\tmww 0x80040180 0x2\n\t# Set PLL freq to 480MHz\n\tmww 0x80040100 480\n\t# normally we shoul waiting here until we get 0x1 (0x80040104)&0x1)==0x0)\n\tsleep 100\n\n\t# select PLL as main source\n\tmww 0x80040120 0x1\n\t# disable and enable main clk to update changes?\n\tmww 0x80040124 0x0\n\tmww 0x80040124 0x1\n\n\techo \"Configure memory\"\n\t#enable EMI CLK\n\tmww 0x80040024 0x40\n\n\t# configure memory controller for internal SRAM\n\tmww 0x80700000 0x1188\n\t# change default emi clk delay\n\tmww 0x8004034C 0xA0503\n\t# make sure chip_select_register2_low has correct value (why?)\n\tmww 0x8070001c 0x20000000\n\t# set type to sdram and size to 32MB\n\tmww 0x8070005c 0xa\n\t# configure internal SDRAM timing\n\tmww 0x80700004 0x024996d9\n\t# configure Static Memory timing\n\tmww 0x80700094 0x00542b4f\n\n\techo \"Configure uart4\"\n\t# enable pinctrl clk\n\tmww 0x80040024 0x2000000\n\t# mux GPIO3_0 and GPIO3_1 to UART4\n\tmww 0x80044060 0x2\n\tmww 0x80044064 0x2\n\t# configure UART4CLKDIV\n\tmww 0x800401a8 0x1\n\t# enable uart4 clk\n\tmww 0x80040024 0x8000\n\t# clear softrst and clkgate on uart4\n\tmww 0x80010008 0xC0000000\n\t# set bandrate 115200 12M\n\tmww 0x80010030 0x00062070\n\t# enable Rx&Tx\n\tmww 0x80010024 0x301\n\t# clear hw control\n\tmww 0x80010028 0xc000\n}\n\n$_TARGETNAME configure -work-area-phys 0x21ffe000 -work-area-virt 0xc1ffe000 -work-area-size 0x1000\n$_TARGETNAME arm7_9 fast_memory_access enable\n$_TARGETNAME arm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/altera_sockit.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Cyclone V SocKit board\n# http://www.altera.com/b/arrow-sockit.html\n#\n# Software support page:\n# http://www.rocketboards.org/\n\n# openocd does not currently support the on-board USB Blaster II.\n# Install the JTAG header and use a USB Blaster instead.\nadapter driver usb_blaster\n\nsource [find target/altera_fpgasoc.cfg]\n\n# If the USB Blaster II were supported, these settings would be needed\n#usb_blaster vid_pid 0x09fb 0x6810\n#usb_blaster device_desc \"USB-Blaster II\"\n\nadapter speed 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/am3517evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# DANGER!!!! early work in progress for this PCB/target.\n#\n# The most basic operations work well enough that it is\n# useful to have this in the repository for cooperation\n# alpha testing purposes.\n#\n# TI AM3517\n#\n# http://focus.ti.com/docs/prod/folders/print/am3517.html\n# http://processors.wiki.ti.com/index.php/Debug_Access_Port_(DAP)\n# http://processors.wiki.ti.com/index.php?title=How_to_Find_the_Silicon_Revision_of_your_OMAP35x\n\nset CHIPTYPE \"am35x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit am35x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ampere_emag8180.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# OpenOCD Board Configuration for eMAG Development Platform\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n\n#\n# Configure JTAG speed\n#\n\nadapter speed 2000\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nsource [find target/ampere_emag.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ampere_qs_mq_1s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# OpenOCD Board Configuration for Ampere Altra (\"Quicksilver\") and\n# Ampere Altra Max (\"Mystique\") processors\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n\n# Argument Description\n#\n# JTAGFREQ\n# Set the JTAG clock frequency\n# Syntax: -c \"set JTAGFREQ {freq_in_khz}\"\n#\n# SYSNAME\n# Set the system name\n# If not specified, defaults to \"qs\"\n# Syntax: -c \"set SYSNAME {qs}\"\n#\n# Life-Cycle State (LCS)\n# If not specified, defaults to \"Secure LCS\"\n# LCS=0, \"Secure LCS\"\n# LCS=1, \"Chip Manufacturing LCS\"\n# Syntax: -c \"set LCS {0}\"\n# Syntax: -c \"set LCS {1}\"\n#\n# CORELIST_S0\n# Specify available physical cores by number\n# Example syntax to connect to physical cores 16 and 17 for S0\n# Syntax: -c \"set CORELIST_S0 {16 17}\"\n#\n# COREMASK_S0_LO\n# Specify available physical cores 0-63 by mask\n# Example syntax to connect to physical cores 16 and 17 for S0\n# Syntax: -c \"set COREMASK_S0_LO {0x0000000000030000}\"\n#\n# COREMASK_S0_HI\n# Specify available physical cores 64 and above by mask\n# Example syntax to connect to physical cores 94 and 95 for S0\n# Syntax: -c \"set COREMASK_S0_HI {0x00000000C0000000}\"\n#\n# PHYS_IDX\n# Enable OpenOCD ARMv8 core target physical indexing\n# If not specified, defaults to OpenOCD ARMv8 core target logical indexing\n# Syntax: -c \"set PHYS_IDX {}\"\n\n#\n# Configure JTAG speed\n#\n\nif { [info exists JTAGFREQ] } {\n\tadapter speed $JTAGFREQ\n} else {\n\tadapter speed 100\n}\n\n#\n# Set the system name\n#\n\nif { [info exists SYSNAME] } {\n\tset _SYSNAME $SYSNAME\n} else {\n\tset _SYSNAME qs\n}\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nif { [info exists CORELIST_S0] || [info exists COREMASK_S0_LO] || [info exists COREMASK_S0_HI] } {\n\tset CHIPNAME ${_SYSNAME}0\n\tif { [info exists CORELIST_S0] } {\n\t\tset CORELIST $CORELIST_S0\n\t} else {\n\t\tif { [info exists COREMASK_S0_LO] } {\n\t\t\tset COREMASK_LO $COREMASK_S0_LO\n\t\t} else {\n\t\t\tset COREMASK_LO 0x0\n\t\t}\n\n\t\tif { [info exists COREMASK_S0_HI] } {\n\t\t\tset COREMASK_HI $COREMASK_S0_HI\n\t\t} else {\n\t\t\tset COREMASK_HI 0x0\n\t\t}\n\t}\n} else {\n\tset CHIPNAME ${_SYSNAME}0\n\tset COREMASK_LO 0x1\n\tset COREMASK_HI 0x0\n}\n\nsource [find target/ampere_qs_mq.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ampere_qs_mq_2s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# OpenOCD Board Configuration for Ampere Altra (\"Quicksilver\") and\n# Ampere Altra Max (\"Mystique\") processors\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n\n# Argument Description\n#\n# JTAGFREQ\n# Set the JTAG clock frequency\n# Syntax: -c \"set JTAGFREQ {freq_in_khz}\"\n#\n# SYSNAME\n# Set the system name\n# If not specified, defaults to \"qs\"\n# Syntax: -c \"set SYSNAME {qs}\"\n#\n# Life-Cycle State (LCS)\n# If not specified, defaults to \"Secure LCS\"\n# LCS=0, \"Secure LCS\"\n# LCS=1, \"Chip Manufacturing LCS\"\n# Syntax: -c \"set LCS {0}\"\n# Syntax: -c \"set LCS {1}\"\n#\n# CORELIST_S0, CORELIST_S1\n# Specify available physical cores by number\n# Example syntax to connect to physical cores 16 and 17 for S0 and S1\n# Syntax: -c \"set CORELIST_S0 {16 17}\"\n# Syntax: -c \"set CORELIST_S1 {16 17}\"\n#\n# COREMASK_S0_LO, COREMASK_S1_LO\n# Specify available physical cores 0-63 by mask\n# Example syntax to connect to physical cores 16 and 17 for S0 and S1\n# Syntax: -c \"set COREMASK_S0_LO {0x0000000000030000}\"\n# Syntax: -c \"set COREMASK_S1_LO {0x0000000000030000}\"\n#\n# COREMASK_S0_HI, COREMASK_S1_HI\n# Specify available physical cores 64 and above by mask\n# Example syntax to connect to physical cores 94 and 95 for S0 and S1\n# Syntax: -c \"set COREMASK_S0_HI {0x00000000C0000000}\"\n# Syntax: -c \"set COREMASK_S1_HI {0x00000000C0000000}\"\n#\n# SPLITSMP\n# Group all ARMv8 cores per socket into individual SMP sessions\n# If not specified, group ARMv8 cores from both sockets into one SMP session\n# Syntax: -c \"set SPLITSMP {}\"\n#\n# PHYS_IDX\n# Enable OpenOCD ARMv8 core target physical indexing\n# If not specified, defaults to OpenOCD ARMv8 core target logical indexing\n# Syntax: -c \"set PHYS_IDX {}\"\n\n#\n# Configure JTAG speed\n#\n\nif { [info exists JTAGFREQ] } {\n\tadapter speed $JTAGFREQ\n} else {\n\tadapter speed 100\n}\n\n#\n# Set the system name\n#\n\nif { [info exists SYSNAME] } {\n\tset _SYSNAME $SYSNAME\n} else {\n\tset _SYSNAME qs\n}\n\n#\n# Configure Board level SMP configuration if necessary\n#\n\nif { ![info exists SPLITSMP] } {\n\t# Group dual chip into a single SMP configuration\n\tset SMP_STR \"target smp\"\n\tset CORE_INDEX_OFFSET 0\n\tset DUAL_SOCKET_SMP_ENABLED \"\"\n}\n\n#\n# Configure Resets\n#\n\njtag_ntrst_delay 100\nreset_config trst_only\n\n#\n# Configure Targets\n#\n\nif { [info exists CORELIST_S0] || [info exists COREMASK_S0_LO] || [info exists COREMASK_S0_HI] || \\\n     [info exists CORELIST_S1] || [info exists COREMASK_S1_LO] || [info exists COREMASK_S1_HI] } {\n\tset CHIPNAME ${_SYSNAME}1\n\tif { [info exists CORELIST_S1] } {\n\t\tset CORELIST $CORELIST_S1\n\t} else {\n\t\tif { [info exists COREMASK_S1_LO] } {\n\t\t\tset COREMASK_LO $COREMASK_S1_LO\n\t\t} else {\n\t\t\tset COREMASK_LO 0x0\n\t\t}\n\n\t\tif { [info exists COREMASK_S1_HI] } {\n\t\t\tset COREMASK_HI $COREMASK_S1_HI\n\t\t} else {\n\t\t\tset COREMASK_HI 0x0\n\t\t}\n\t}\n\tsource [find target/ampere_qs_mq.cfg]\n\n\tif { [info exists DUAL_SOCKET_SMP_ENABLED] && [info exists PHYS_IDX]} {\n\t\tif { [info exists MQ_ENABLE] } {\n\t\t\tset CORE_INDEX_OFFSET 128\n\t\t} else {\n\t\t\tset CORE_INDEX_OFFSET 80\n\t\t}\n\t}\n\n\tset CHIPNAME ${_SYSNAME}0\n\tif { [info exists CORELIST_S0] } {\n\t\tset CORELIST $CORELIST_S0\n\t} else {\n\t\tif { [info exists COREMASK_S0_LO] } {\n\t\t\tset COREMASK_LO $COREMASK_S0_LO\n\t\t} else {\n\t\t\tset COREMASK_LO 0x0\n\t\t}\n\n\t\tif { [info exists COREMASK_S0_HI] } {\n\t\t\tset COREMASK_HI $COREMASK_S0_HI\n\t\t} else {\n\t\t\tset COREMASK_HI 0x0\n\t\t}\n\t}\n\tsource [find target/ampere_qs_mq.cfg]\n} else {\n\tset CHIPNAME ${_SYSNAME}1\n\tset COREMASK_LO 0x0\n\tset COREMASK_HI 0x0\n\tsource [find target/ampere_qs_mq.cfg]\n\n\tif { [info exists DUAL_SOCKET_SMP_ENABLED] && [info exists PHYS_IDX]} {\n\t\tif { [info exists MQ_ENABLE] } {\n\t\t\tset CORE_INDEX_OFFSET 128\n\t\t} else {\n\t\t\tset CORE_INDEX_OFFSET 80\n\t\t}\n\t}\n\n\tset CHIPNAME ${_SYSNAME}0\n\tset COREMASK_LO 0x1\n\tset COREMASK_HI 0x0\n\tsource [find target/ampere_qs_mq.cfg]\n}\n\nif { [info exists DUAL_SOCKET_SMP_ENABLED] } {\n\t# For dual socket SMP configuration, evaluate the string\n\teval $SMP_STR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/arm_evaluator7t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This board is from ARM and has an samsung s3c45101x01 chip\n\nsource [find target/samsung_s3c4510.cfg]\n\n#\n# FIXME:\n#  Add (A) sdram configuration\n#  Add (B) flash cfi programming configuration\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/arm_musca_a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration script for ARM Musca-A development board\n#\n# For now we do not support Musca A flash programming using OpenOCD. However, a\n# work area is configured for flash programming speed up.\n#\n# GDB considers all memory as RAM unless target supplies a memory map.\n# OpenOCD will only send memory map if flash banks are configured. Otherwise,\n# configure GDB after connection by issuing following commands:\n# (gdb) mem 0x10200000 0x109FFFFF ro\n# (gdb) mem 0x00200000 0x009FFFFF ro\n# (gdb) set mem inaccessible-by-default off\n\n# ARM Musca A board supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME MUSCA_A\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x6ba00477\n}\n\n# Enable CPU1 debugging as a separate GDB target\nset _ENABLE_CPU1 1\n\n# Musca A1 has 32KB SRAM banks. Override default work-area-size to 8KB per CPU\nset WORKAREASIZE_CPU0 0x2000\nset WORKAREASIZE_CPU1 0x2000\n\n# Set SRAM bank 1 to be used for work area. Override here if needed.\nset WORKAREAADDR_CPU0 0x30008000\nset WORKAREAADDR_CPU1 0x3000A000\n\nsource [find target/arm_corelink_sse200.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/arty_s7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Arty S7: Spartan7 25/50 FPGA Board for Makers and Hobbyists\n#\n# https://www.xilinx.com/products/boards-and-kits/1-pnziih.html\n# https://store.digilentinc.com/arty-s7-spartan-7-fpga-board-for-makers-and-hobbyists/\n\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# Xilinx Spartan7-25/50 FPGA (XC7S{25,50}-CSGA324)\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n\n# Usage:\n#\n# Load Bitstream into FPGA:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    pld load 0 bitstream.bit;\\\n#    shutdown\"\n#\n# Write Bitstream to Flash:\n#    openocd -f board/arty_s7.cfg -c \"init;\\\n#    jtagspi_init 0 bscan_spi_xc7s??.bit;\\\n#    jtagspi_program bitstream.bin 0;\\\n#    xc7_program xc7.tap;\\\n#    shutdown\"\n#\n# jtagspi flash proxies can be found at:\n# https://github.com/quartiq/bscan_spi_bitstreams\n#\n# For the Spartan 50 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s50.bit\n# For the Spartan 25 variant, use\n#  - https://github.com/quartiq/bscan_spi_bitstreams/raw/master/bscan_spi_xc7s25.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/asus-rt-n16.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# http://wikidevi.com/wiki/ASUS_RT-N16\n#\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4718.cfg]\n\n# External 32MB NOR Flash (Macronix MX29GL256EHTI2I-90Q)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/asus-rt-n66u.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# http://wikidevi.com/wiki/Asus_RT-N66U\n#\n\necho \"ATTENTION: you need to solder a 4.7-10k pullup resistor to pin 21 of flash IC\"\necho \"to enable JTAG, see http://wl500g.info/album.php?albumid=28&attachmentid=8991 ,\"\necho \"there is an unpopulated footprint near U8.\\n\"\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0xbc000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0xbc040000 0x01fa0000 }\n    nvram\t{ \"Config space\"\t\t0xbdfe0000 0x00020000 }\n}\n\nsource [find target/bcm4706.cfg]\n\n# External 32MB NOR Flash (Spansion S29GL256P10TF101\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbc000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91cap7a-stk-sdram.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4394\n#\n# use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME cap7\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x40700f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start {\n\t# start off real slow when we're running off internal RC oscillator\n\tadapter speed 32\n}\n\nproc peek32 {address} {\n\treturn [read_memory $address 32 1]\n}\n\n# Wait for an expression to be true with a timeout\nproc wait_state {expression} {\n\tfor {set i 0} {$i < 1000} {set i [expr {$i + 1}]} {\n\t\tif {[uplevel 1 $expression] == 0} {\n\t\t\treturn\n\t\t}\n\t}\n\treturn -code 1 \"Timed out\"\n}\n\n# Use a global variable here to be able to tinker interactively with\n# post reset jtag frequency.\nglobal post_reset_khz\n# Danger!!!! Even 16MHz kinda works with this target, but\n# it needs to be as low as 2000kHz to be stable.\nset post_reset_khz 2000\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Configuring master clock\"\n\t# disable watchdog\n\tmww 0xfffffd44 0xff008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# Enable main oscillator\n\tmww 0xFFFFFc20  0x00000f01\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x1) == 0}}\n\n\t# Set PLLA to 96MHz\n\tmww 0xFFFFFc28 0x20072801\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x2) == 0}}\n\n\t# Select prescaler\n\tmww 0xFFFFFC30 0x00000004\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\t# Select master clock to 48MHz\n\tmww 0xFFFFFC30 0x00000006\n\twait_state {expr {([peek32 0xFFFFFC68] & 0x8) == 0}}\n\n\techo \"Master clock ok.\"\n\n\t# Now that we're up and running, crank up speed!\n\tglobal post_reset_khz ;\tadapter speed $post_reset_khz\n\n\techo \"Configuring the SDRAM controller...\"\n\n\t# Configure EBI Chip select for SDRAM\n\tmww 0xFFFFEF30 0x00000102\n\n\t# Enable clock on EBI PIOs\n\tmww 0xFFFFFC10 0x00000004\n\n\t# Configure PIO for SDRAM\n\tmww 0xFFFFF470 0xFFFF0000\n\tmww 0xFFFFF474 0x00000000\n\tmww 0xFFFFF404 0xFFFF0000\n\n\t# Configure SDRAMC CR\n\tmww 0xFFFFEA08 0xA63392F9\n\n\t# NOP command\n\tmww 0xFFFFEA00 0x1\n\tmww 0x20000000 0\n\n\t# Precharge All Banks command\n\tmww 0xFFFFEA00 0x2\n\tmww 0x20000000 0\n\n\t# Set 1st CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000010 0x00000001\n\n\t# Set 2nd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000020 0x00000002\n\n\t# Set 3rd CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000030 0x00000003\n\n\t# Set 4th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000040 0x00000004\n\n\t# Set 5th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000050 0x00000005\n\n\t# Set 6th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000060 0x00000006\n\n\t# Set 7th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000070 0x00000007\n\n\t# Set 8th CBR\n\tmww 0xFFFFEA00 0x00000004\n\tmww 0x20000080 0x00000008\n\n\t# Set LMR operation\n\tmww 0xFFFFEA00 0x00000003\n\n\t# Perform LMR burst=1, lat=2\n\tmww 0x20000020 0xCAFEDEDE\n\n\t# Set Refresh Timer\n\tmww 0xFFFFEA04 0x00000203\n\n\t# Set Normal mode\n\tmww 0xFFFFEA00 0x00000000\n\tmww 0x20000000 0x00000000\n\n\t#remap internal memory at address 0x0\n\tmww 0xffffef00 0x3\n\n\techo \"SDRAM configuration ok.\"\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91eb40a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#Script for AT91EB40a\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\n\n#Atmel ties SRST & TRST together, at which point it makes\n#no sense to use TRST, but use TMS instead.\n#\n#The annoying thing with tying SRST & TRST together is that\n#there is no way to halt the CPU *before and during* the\n#SRST reset, which means that the CPU will run a number\n#of cycles before it can be halted(as much as milliseconds).\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n#flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x01000000 0x200000 2 2 $_TARGETNAME\n\n# required for usable performance. Used for lots of\n# other things than flash programming.\n$_TARGETNAME configure -work-area-phys 0x00030000 -work-area-size 0x10000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"Running reset init script for AT91EB40A\"\n\t# Reset script for AT91EB40a\n\treg cpsr 0x000000D3\n\tmww 0xFFE00020 0x1\n\tmww 0xFFE00024 0x00000000\n\tmww 0xFFE00000 0x01002539\n\tmww 0xFFFFF124 0xFFFFFFFF\n\tmww 0xffff0010 0x100\n\tmww 0xffff0034 0x100\n}\n\n# This target is pretty snappy...\nadapter speed 16000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91rm9200-dk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is for the \"at91rm9200-DK\" (not the EK) eval board.\n#\n# The two are probably very simular.... I have DK...\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_dk_init }\n\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00200000 2 2 $_TARGETNAME\n\n\nproc at91rm9200_dk_init { } {\n    # Try to run at 1khz... Yea, that slow!\n    # Chip is really running @ 32khz\n    adapter speed 8\n\n    mww 0xfffffc64 0xffffffff\n    ##  disable all clocks but system clock\n    mww 0xfffffc04 0xfffffffe\n    ##  disable all clocks to pioa and piob\n    mww 0xfffffc14 0xffffffc3\n    ##  master clock = slow cpu = slow\n    ##  (means the CPU is running at 32khz!)\n    mww 0xfffffc30 0\n    ##  main osc enable\n    mww 0xfffffc20 0x0000ff01\n    ##  program pllA\n    mww 0xfffffc28 0x20263e04\n    ##  program pllB\n    mww 0xfffffc2c 0x10483e0e\n    ##  let pll settle... sleep 100msec\n    sleep 100\n    ##  switch to fast clock\n    mww 0xfffffc30 0x202\n    ## Sleep some - (go read)\n    sleep 100\n\n    #========================================\n    # CPU now runs at 180mhz\n    # SYS runs at 60mhz.\n    adapter speed 40000\n    #========================================\n\n\n    ##  set memc for all memories\n    mww 0xffffff60 0x02\n    ##  program smc controller\n    mww 0xffffff70 0x3284\n    ##  init sdram\n    mww 0xffffff98 0x7fffffd0\n    ##  all banks precharge\n    mww 0xffffff80 0x02\n    ##  touch sdram chip to make it work\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    mww 0xffffff90 0x04\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    mww 0x20000000 0\n    ##  sdram controller mode register\n    ##  Refresh, etc....\n    mww 0xffffff90 0x03\n    mww 0x20000080 0\n    mww 0xffffff94 0x1f4\n    mww 0x20000080 0\n    mww 0xffffff90 0x10\n    mww 0x20000000 0\n    mww 0xffffff00 0x01\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91rm9200-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright 2010 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>\n#\n# under GPLv2 Only\n#\n# This is for the \"at91rm9200-ek\" eval board.\n#\n#\n# It has atmel at91rm9200 chip.\nsource [find target/at91rm9200.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91rm9200_ek_init }\n\n## flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# The chip may run @ 32khz, so set a really low JTAG speed\nadapter speed 8\n\nproc at91rm9200_ek_init { } {\n\t# Try to run at 1khz... Yea, that slow!\n\t# Chip is really running @ 32khz\n\tadapter speed 8\n\n\tmww 0xfffffc64 0xffffffff\n\t## disable all clocks but system clock\n\tmww 0xfffffc04 0xfffffffe\n\t## disable all clocks to pioa and piob\n\tmww 0xfffffc14 0xffffffc3\n\t## master clock = slow cpu = slow\n\t## (means the CPU is running at 32khz!)\n\tmww 0xfffffc30 0\n\t## main osc enable\n\tmww 0xfffffc20 0x0000ff01\n\t## MC_PUP\n\tmww 0xFFFFFF50 0x00000000\n\t## MC_PUER: Memory controller protection unit disable\n\tmww 0xFFFFFF54 0x00000000\n\t## EBI_CFGR\n\tmww 0xFFFFFF64 0x00000000\n\t## SMC2_CSR[0]: 16bit, 2 TDF, 4 WS\n\tmww 0xFFFFFF70 0x00003284\n\n\t## Init Clocks\n\t## CKGR_PLLAR\n\tmww 0xFFFFFC28 0x2000BF05\n\t## PLLAR: 179,712000 MHz for PCK\n\tmww 0xFFFFFC28 0x20263E04\n\tsleep 100\n\t## PMC_MCKR\n\tmww 0xFFFFFC30 0x00000100\n\tsleep 100\n\t## ;MCKR : PCK/3 = MCK Master Clock = 59,904000MHz from PLLA\n\tmww 0xFFFFFC30 0x00000202\n\tsleep 100\n\n\t#========================================\n\t# CPU now runs at 180mhz\n\t# SYS runs at 60mhz.\n\tadapter speed 40000\n\t#========================================\n\n\t## Init SDRAM\n\t## PIOC_ASR: Configure PIOC as peripheral (D16/D31)\n\tmww 0xFFFFF870 0xFFFF0000\n\t## PIOC_BSR:\n\tmww 0xFFFFF874 0x00000000\n\t## PIOC_PDR:\n\tmww 0xFFFFF804 0xFFFF0000\n\t## EBI_CSA : CS1=SDRAM\n\tmww 0xFFFFFF60 0x00000002\n\t## EBI_CFGR:\n\tmww 0xFFFFFF64 0x00000000\n\t## SDRC_CR :\n\tmww 0xFFFFFF98 0x2188c155\n\t## SDRC_MR : Precharge All\n\tmww 0xFFFFFF90 0x00000002\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Refresh\n\tmww 0xFFFFFF90 0x00000004\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Load Mode Register\n\tmww 0xFFFFFF90 0x00000003\n\t## access SDRAM\n\tmww 0x20000080 0x00000000\n\t## SDRC_TR : Write refresh rate\n\tmww 0xFFFFFF94 0x000002E0\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n\t## SDRC_MR : Normal Mode\n\tmww 0xFFFFFF90 0x00000000\n\t## access SDRAM\n\tmww 0x20000000 0x00000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91sam9261-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Atmel AT91SAM9261-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9261.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9261_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9261.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9261ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9261ek_reset_init { } {\n\n\t;# for ppla at 199 Mhz\n\tset config(master_pll_div)\t15\n\tset config(master_pll_mul)\t162\n\n\t;# for ppla at 239 Mhz\n\t;# set master_pll_div\t1\n\t;# set master_pll_mul\t13\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBICSA\n\tset config(matrix_ebicsa_val) [expr {$::AT91_MATRIX_DBPUC | $::AT91_MATRIX_CS1A_SDRAMC}]\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (2 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (3 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (8 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91sam9263-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Atmel AT91SAM9263-EK eval board\n################################################################################\n\nsource [find mem_helper.tcl]\nsource [find target/at91sam9263.cfg]\nuplevel #0 [list source [find chip/atmel/at91/hardware.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9263_matrix.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_init.cfg]]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9263.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\nscan_chain\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { at91sam9263ek_reset_init }\n$_TARGETNAME configure -event reset-start { at91sam9_reset_start }\n\nproc at91sam9263ek_reset_init { } {\n\n\tset config(master_pll_div)\t14\n\tset config(master_pll_mul)\t171\n\n\tset val\t$::AT91_WDT_WDV\t\t\t\t\t\t\t;# Counter Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDIS}]\t\t;# Watchdog Disable\n\tset val\t[expr {$val | $::AT91_WDT_WDD}]\t\t\t;# Delta Value\n\tset val\t[expr {$val | $::AT91_WDT_WDDBGHLT}]\t;# Debug Halt\n\tset val\t[expr {$val | $::AT91_WDT_WDIDLEHLT}]\t;# Idle Halt\n\n\tset config(wdt_mr_val) $val\n\n\tset config(sdram_piod) 1\n\t;# EBI_CSA, no pull-ups for D[15:0], CS1 SDRAM, CS3 NAND Flash\n\tset config(matrix_ebicsa_addr)\t$::AT91_MATRIX_EBI0CSA\n\n\tset val\t$::AT91_MATRIX_EBI0_DBPUC\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_VDDIOMSEL_3_3V}]\n\tset val [expr {$val | $::AT91_MATRIX_EBI0_CS1A_SDRAMC}]\n\tset config(matrix_ebicsa_val) $val\n\n\t;# SDRAMC_CR - Configuration register\n\tset val $::AT91_SDRAMC_NC_9\n\tset val [expr {$val | $::AT91_SDRAMC_NR_13}]\n\tset val [expr {$val | $::AT91_SDRAMC_NB_4}]\n\tset val [expr {$val | $::AT91_SDRAMC_CAS_3}]\n\tset val [expr {$val | $::AT91_SDRAMC_DBW_32}]\n\tset val [expr {$val | (1 <<  8)}]\t\t;# Write Recovery Delay\n\tset val [expr {$val | (7 << 12)}]\t\t;# Row Cycle Delay\n\tset val [expr {$val | (2 << 16)}]\t\t;# Row Precharge Delay\n\tset val [expr {$val | (2 << 20)}]\t\t;# Row to Column Delay\n\tset val [expr {$val | (5 << 24)}]\t\t;# Active to Precharge Delay\n\tset val [expr {$val | (1 << 28)}]\t\t;# Exit Self Refresh to Active Delay\n\n\tset config(sdram_cr_val) $val\n\n\tset config(sdram_tr_val) 0x13c\n\n\tset config(sdram_base) $::AT91_CHIPSELECT_1\n\tat91sam9_reset_init $config\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/at91sam9g20-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n# Author: Gary Carlson (gcarlson@carlson-minot.com)\t\t\t\t\t\t#\n# Generated for Atmel AT91SAM9G20-EK evaluation board using Atmel SAM-ICE (J-Link) version 8.\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\nsource [find target/at91sam9g20.cfg]\n\nset _FLASHTYPE nandflash_cs3\n\n# Set reset type.  Note that the AT91SAM9G20-EK board has the trst signal disconnected.  Therefore\n# the reset needs to be configured for \"srst_only\".  If for some reason, a zero-ohm jumper is\n# added to the board to connect the trst signal, then this parameter may need to be changed.\n\nreset_config srst_only\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init}\n$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start}\n\n# NandFlash configuration and definition\n\nnand device nandflash_cs3 at91sam9 $_TARGETNAME 0x40000000 0xfffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g20_reset_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n\tadapter speed 2                 ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\thalt                            ;# Make sure processor is halted, or error will result in following steps.\n\twait_halt 10000\n\tmww 0xfffffd08 0xa5000501       ;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9g20_reset_init { } {\n\n\t# At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G20 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\tmww 0xfffffd44 0x00008000\t;# WDT_MR : disable watchdog.\n\n\t# Enable the main 18.432 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\tmww 0xfffffc28 0x202a3f01\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00000101\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 0\n\n\t# Enable faster DCC downloads and memory accesses.\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\tmww 0xffffef1c 0x000100a\n\n\t# The AT91SAM9G20-EK evaluation board has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# a number of registers.  The first step involves setting up the general I/O pins on the processor\n\t# to be able to interface and support the external memory.\n\n\tmww 0xfffffc10 0x00000010\t;# PMC_PCER : enable PIOC clock\n\tmww 0xfffff800 0x00006000\t;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n\tmww 0xfffff810 0x00004000\t;# PIOC_OER : enable output on 14\n\tmww 0xfffff814 0x00002000\t;# PIOC_ODR : disable output on 13\n    \tmww 0xfffff830 0x00004000\t;# PIOC_SODR : set 14 to disable NAND\n\n\t# The exact physical timing characteristics for the memory type used on the current board\n\t# (MT29F2G08AACWP) can be established by setting four registers in order:  SMC_SETUP3,\n\t# SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.  Computing the exact values of these registers\n\t# is a little tedious to do here.  If you have questions about how to do this, Atmel has\n\t# a decent application note #6255B that covers this process.\n\n\tmww 0xffffec30 0x00020002\t;# SMC_SETUP3 : 2 clock cycle setup for NRD and NWE\n\tmww 0xffffec34 0x04040404\t;# SMC_PULSE3 : 4 clock cycle pulse for all signals\n\tmww 0xffffec38 0x00070006\t;# SMC_CYCLE3 : 7 clock cycle NRD and 6 NWE cycle\n\tmww 0xffffec3C 0x00020003\t;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n\n\tmww 0xffffe800 0x00000001\t;# ECC_CR : reset the ECC parity registers\n\tmww 0xffffe804 0x00000002\t;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n\t# Identify NandFlash bank 0.\n\n\tnand probe nandflash_cs3\n\n\t# The AT91SAM9G20-EK evaluation board has built-in serial data flash also.\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Micron MT48LC16M16A2-75 memory (4 M x 16 bit x 4 banks).  If you use this file as a reference\n\t# for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted\n\t# into the SDRAM_CR register.  Using the memory datasheet for the -75 grade part and assuming a master clock\n\t# of 132.096 MHz then the SDCLK period is equal to 7.6 ns.  This means the device requires:\n\t#\n\t#\tCAS latency = 3 cycles\n\t#\tTXSR = 10 cycles\n\t#\tTRAS = 6 cycles\n\t#\tTRCD = 3 cycles\n\t#\tTRP = 3 cycles\n\t#\tTRC = 9 cycles\n\t#\tTWR = 2 cycles\n\t#\t9 column, 13 row, 4 banks\n\t#\trefresh equal to or less then 7.8 us for commercial/industrial rated devices\n\t#\n\t#\tThus SDRAM_CR = 0xa6339279\n\n\tmww 0xffffea08 0xa6339279\n\n\t# Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000001\n\tmww 0x20000000 0\n\n\t# Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero\n\t# value into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x00000002\n\tmww 0x20000000 0\n\n\t# Now issue an 'Auto-Refresh' command through the SDRAMC_MR register.  Follow this operation by writing\n\t# zero values eight times into the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the\n\t# the starting memory location for the SDRAM.\n\n\tmww 0xffffea00 0x3\n\tmww 0x20000000 0\n\n\t# Signal normal mode using the SDRAMC_MR register and follow with a zero value write the the starting\n\t# memory location for the SDRAM.\n\n\tmww 0xffffea00 0x0\n\tmww 0x20000000 0\n\n\t# Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles).\n\n\tmww 0xffffea04 0x0000039c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_at91sam7s-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Atmel AT91SAM7S-EK\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3784\n\nset CHIPNAME at91sam7s256\n\nsource [find target/at91sam7sx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_at91sam9260-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Atmel AT91SAM9260-EK eval board\n#\n# http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n# By default S1 is open and this means that NTRST is not connected.\n# The reset_config in target/at91sam9260.cfg is overridden here.\n# (or S1 must be populated with a 0 Ohm resistor)\nreset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198.656 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (99.328 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n\n        mww 0xffffef1c 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_at91sam9rl-ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n#\n# Generated for Atmel AT91SAM9RL-EK evaluation board using Atmel SAM-ICE (J-Link) V6\n#\n# Atmel AT91SAM9RL : PLL = 200 MHz, MCK = 100 MHz\n#                     OSCSEL configured for external 32.768 kHz crystal\n#\n# 32-bit SDRAM : 2 x Micron MT48LC16M16A2, 4M x 16Bit x 4 Banks\n#\n################################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9rl.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 32.768 kHz.\n        # JTAG Frequency must be 6 times slower if RCLK is not supported.\n        jtag_rclk 5\n        halt\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x2031bf03         ;# CKGR_PLLR: Set PLL Register for 200 MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLL is selected (100 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xfffff670 0xffff0000         ;# PIO_ASR  : Select peripheral function for D16..D31 (PIOB)\n        mww 0xfffff604 0xffff0000         ;# PIO_PDR  : Disable PIO function for D16..D31 (PIOB)\n\n        mww 0xffffef20 0x00010002         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Micron MT48LC16M16A2 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2b6              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam3n_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Board configuration for Atmel's SAM3N-EK\n#\n\nreset_config srst_only\n\nset CHIPNAME at91sam3n4c\n\nadapter speed 32\n\nsource [find target/at91sam3nXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam3s_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/at91sam3sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam3u_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/at91sam3u4e.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam3x_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/at91sam3ax_8x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam4e_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an SAM4E-EK board with a single SAM4E16 chip.\n# http://www.atmel.com/tools/sam4e-ek.aspx\n\n# chip name\nset CHIPNAME SAM4E16E\n\nsource [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam4l8_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAM4L8 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4L8-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4LC8CA\n\nsource [find target/at91sam4lXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam4s_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/at91sam4sXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_sam4s_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAM4S Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAM4S-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAM4SD32C\n\nsource [find target/at91sam4sd32x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samc20_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMC20 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samc21_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMC21 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMC21-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samc21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samd10_xplained_mini.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMD10 Xplained mini evaluation kit.\n# http://www.atmel.com/tools/atsamd10-xmini.aspx\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd10d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samd11_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMD11 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd11d14\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samd20_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMD20 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMD20-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd20j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samd21_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMD21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samd21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_same70_xplained.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAME70 Xplained evaluation kit.\n# http://www.atmel.com/tools/ATSAME70-XPLD.aspx\n#\n# Connect using the EDBG chip on the dev kit over USB\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME atsame70q21\n\nsource [find target/atsamv.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samg53_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMG53 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG53-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG53N19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samg55_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMG55 Xplained Pro evaluation kit.\n# http://www.atmel.com/tools/ATSAMG55-XPRO.aspx\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME ATSAMG55J19\n\nsource [find target/at91samg5x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_saml21_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAML21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91saml21j18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samr21_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMR21 Xplained Pro evaluation kit.\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# chip name\nset CHIPNAME at91samr21g18\n\nsource [find target/at91samdXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/atmel_samv71_xplained_ultra.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Atmel SAMV71 Xplained Ultra evaluation kit.\n# http://www.atmel.com/tools/ATSAMV71-XULT.aspx\n#\n# To connect using the EDBG chip on the dev kit over USB, you will\n# first need to source [find interface/cmsis-dap.cfg]\n# however, since this board also has a SWD+ETM connector, we don't\n# automatically source that file here.\n\nset CHIPNAME samv71\n\nsource [find target/atsamv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/avnet_ultrazed-eg.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# AVNET UltraZED EG StarterKit\n# ZynqMP UlraScale-EG plus IO Carrier with on-board digilent smt2\n#\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n# jtag transport only\ntransport select jtag\n# reset lines are not wired\nreset_config none\n\n# slow default clock\nadapter speed 1000\n\nset CHIPNAME uscale\n\nsource [find target/xilinx_zynqmp.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/balloon3-cpu.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config for balloon3 board, cpu JTAG port. http://balloonboard.org/\n# The board has separate JTAG ports for cpu and CPLD/FPGA devices\n# Chaining is done on IO interfaces if desired.\n\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\n# 29LV650 64Mbit Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/bcm28155_ap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# BCM28155_AP\n\nadapter speed 20000\n\nset CHIPNAME bcm28155\nsource [find target/bcm281xx.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/bemicro_cycloneiii.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# BeMicro Cyclone III\n\n\nadapter driver ftdi\nftdi channel 0\nftdi layout_init 0x0008 0x008b\nftdi vid_pid 0x0403 0xa4a0\nreset_config none\ntransport select jtag\n\nadapter speed 10000\n\nsource [find fpga/altera-cycloneiii.cfg]\n\n#quartus_cpf --option=bitstream_compression=off -c output_files\\cycloneiii_blinker.sof cycloneiii_blinker.rbf\n\n#openocd -f board/bemicro_cycloneiii.cfg -c \"init\" -c \"pld load 0 cycloneiii_blinker.rbf\"\n# \"ipdbg -start -tap cycloneiii.tap -hub 0x00e -tool 0 -port 5555\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/bluefield.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Board configuration for BlueField SoC.\n#\n\nsource [find interface/rshim.cfg]\nsource [find target/bluefield.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/bt-homehubv1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# BT HomeHub v1\n#\n\nset partition_list {\n    CFE       { Bootloader              0xbe400000 0x00020000 }\n    firmware  { \"Kernel+rootfs\"         0xbe420000 0x007d0000 }\n    fisdir    { \"FIS Directory\"         0xbebf0000 0x0000f000 }\n    nvram     { \"Config space\"          0xbebff000 0x00001000 }\n}\n\nsource [find target/bcm6348.cfg]\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0xbe400000 0x00800000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/calao-usb-a9260.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# CALAO Systems USB-A9260 (C01 and C02)\n\nadapter driver ftdi\nftdi device_desc \"USB-A9260\"\nftdi vid_pid 0x0403 0x6001 0x0403 0x6010\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\ntransport select jtag\n\nsource [find target/at91sam9260.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/calao-usb-a9g20-c01.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# CALAO Systems USB-A9G20-C01\n# Authors: Gregory Hermant, Jean-Christophe PLAGNIOL-VILLARD, Wolfram Sang\n\nadapter driver ftdi\nftdi device_desc \"USB-A9G20\"\nftdi vid_pid 0x0403 0x6010\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\ntransport select jtag\n\nsource [find target/at91sam9g20.cfg]\nsource [find mem_helper.tcl]\n\nproc at91sam9g20_reset_start { } {\n\n        # Make sure that the jtag is running slow, since there are a number of different ways the board\n        # can be configured coming into this state that can cause communication problems with the jtag\n        # adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n        # are enabled, Need to temporarily shut this down so that the RSTC_MR register can be written at slower\n        # jtag speed without causing GDB keep alive problem.\n\n        arm7_9 fast_memory_access disable\n        adapter speed 2                   ;# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n        halt 0                            ;# Make sure processor is halted, or error will result in following steps.\n        wait_halt 10000\n        # RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\nproc at91sam9g20_reset_init { } {\n\n        # At reset AT91SAM9G20 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n        # a number of steps that must be carefully performed.  The process outline below follows the\n        # recommended procedure outlined in the AT91SAM9G20 technical manual.\n        #\n        # Several key and very important things to keep in mind:\n        # The SDRAM parts used currently on the Atmel evaluation board are -75 grade parts.  This\n        # means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n        # core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n        mww 0xfffffd44 0x00008000      ;# WDT_MR : disable watchdog.\n\n        # Set oscillator bypass bit (12.00 MHz external oscillator) in CKGR_MOR register.\n\n        mww 0xfffffc20 0x00000002\n\n        # Set PLLA Register for 798.000 MHz (divider: bypass, multiplier: 132).\n        # Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n        mww 0xfffffc28 0x20843F02\n        while { [expr { [mrw 0xfffffc68] & 0x02 } ] != 2 } { sleep 1 }\n\n        # Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n        # Wait for MCKRDY signal from PMC_SR to assert.\n\n        mww 0xfffffc30 0x00001300\n        while { [expr { [mrw 0xfffffc68] & 0x08 } ] != 8 } { sleep 1 }\n\n        # Now change PMC_MCKR register to select PLLA.\n        # Wait for MCKRDY signal from PMC_SR to assert.\n\n        mww 0xfffffc30 0x00001302\n        while { [expr { [mrw 0xfffffc68] & 0x08 } ] != 8 } { sleep 1 }\n\n        # Processor and master clocks are now operating and stable at maximum frequency possible:\n        #       -> MCLK = 133.000 MHz\n        #       -> PCLK = 400.000 MHz\n\n        # Switch to fast JTAG speed\n\n        adapter speed 9500\n\n        # Enable faster DCC downloads.\n\n        arm7_9 dcc_downloads enable\n        arm7_9 fast_memory_access enable\n\n        # To be able to use external SDRAM, several peripheral configuration registers must\n        # be modified.  The first change is made to PIO_ASR to select peripheral functions\n        # for D15 through D31.  The second change is made to the PIO_PDR register to disable\n        # this for D15 through D31.\n\n        mww 0xfffff870 0xffff0000\n        mww 0xfffff804 0xffff0000\n\n        # The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n        # using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n        # the board to the 1.8V VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n        mww 0xffffef1c 0x000000a\n\n        # The USB-A9G20 Embedded computer has built-in NandFlash.  The exact physical timing characteristics\n        # for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n        # four registers in order:  SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.\n\n        mww 0xffffec30 0x00020002\n        mww 0xffffec34 0x04040404\n        mww 0xffffec38 0x00070007\n        mww 0xffffec3c 0x00030003\n\n        # Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n        # are based on 2 x Micron LPSDRAM MT48H16M16LFBF-75 memory (4 M x 16 bit x 4 banks).  If you use this file as a reference\n        # for a new board that uses different SDRAM devices or clock rates, you need to recalculate the value inserted\n        # into the SDRAM_CR register.  Using the memory datasheet for the -75 grade part and assuming a master clock\n        # of 133.000 MHz then the SDCLK period is equal to 7.6 ns.  This means the device requires:\n        #\n        #       CAS latency = 3 cycles\n        #       TXSR = 10 cycles\n        #       TRAS = 6 cycles\n        #       TRCD = 3 cycles\n        #       TRP = 3 cycles\n        #       TRC = 9 cycles\n        #       TWR = 2 cycles\n        #       9 column, 13 row, 4 banks\n        #       refresh equal to or less then 7.8 us for commercial/industrial rated devices\n        #\n        #       Thus SDRAM_CR = 0xa6339279\n\n        mww 0xffffea08 0xa6339279\n\n        # Memory Device Type: SDRAM (low-power would be 0x1)\n        mww 0xffffea24 0x00000000\n\n        # Next issue a 'NOP' command through the SDRAMC_MR register followed by writing a zero value into\n        # the starting memory location for the SDRAM.\n\n        mww 0xffffea00 0x00000001\n        mww 0x20000000 0\n\n        # Issue an 'All Banks Precharge' command through the SDRAMC_MR register followed by writing a zero\n        # value into the starting memory location for the SDRAM.\n\n        mww 0xffffea00 0x00000002\n        mww 0x20000000 0\n\n        # Now issue an 'Auto-Refresh' command through the SDRAMC_MR register.  Follow this operation by writing\n        # zero values eight times into the starting memory location for the SDRAM.\n\n        mww 0xffffea00 0x4\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n        mww 0x20000000 0\n\n        # Almost done, so next issue a 'Load Mode Register' command followed by a zero value write to the\n        # the starting memory location for the SDRAM.\n\n        mww 0xffffea00 0x3\n        mww 0x20000000 0\n\n        # Signal normal mode using the SDRAMC_MR register and follow with a zero value write the starting\n        # memory location for the SDRAM.\n\n        mww 0xffffea00 0x0\n        mww 0x20000000 0\n\n        # Finally set the refresh rate to about every 7 us (7.5 ns x 924 cycles).\n\n        mww 0xffffea04 0x0000039c\n}\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-start {at91sam9g20_reset_start}\n$_TARGETNAME configure -event reset-init {at91sam9g20_reset_init}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/certuspro_evaluation.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# https://www.latticesemi.com/products/developmentboardsandkits/certuspro-nx-versa-board\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x008b\nreset_config none\ntransport select jtag\nadapter speed 10000\n\nsource [find fpga/lattice_certuspro.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/colibri.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Toradex Colibri PXA270\nsource [find target/pxa270.cfg]\nreset_config trst_and_srst srst_push_pull\nadapter srst pulse_width 40\n\n# CS0 -- one bank of CFI flash, 32 MBytes\n# the bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/crossbow_tech_imote2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Crossbow Technology iMote2\n\nset  CHIPNAME imote2\nsource [find target/pxa270.cfg]\n\n# longer-than-normal reset delay\nadapter srst delay 800\n\nreset_config trst_and_srst separate\n\n# works for P30 flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/csb337.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Cogent CSB337\n#   http://cogcomp.com/csb_csb337.htm\n\nsource [find target/at91rm9200.cfg]\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n\n# ETM9 trace port connector present on this board, 16 data pins.\nif { [info exists ETM_DRIVER] } {\n\tetm config $_TARGETNAME 16 normal half $ETM_DRIVER\n\t# OpenOCD may someday support a real trace port driver...\n\t# system config file would need to configure it.\n} else {\n\tetm config $_TARGETNAME 16 normal half dummy\n\tetm_dummy config $_TARGETNAME\n}\n\nproc csb337_clk_init { } {\n\t# CPU is in Slow Clock Mode (32KiHz) ... needs slow JTAG clock\n\tadapter speed 8\n\n\t# CKGR_MOR:  start main oscillator (3.6864 MHz)\n\tmww 0xfffffc20 0xff01\n\tsleep 10\n\n\t# CKGR_PLLAR:  start PLL A for CPU and peripherals (184.32 MHz)\n\tmww 0xfffffc28 0x20313e01\n\t# CKGR_PLLBR:  start PLL B for USB timing (96 MHz, with div2)\n\tmww 0xfffffc2c 0x12703e18\n\t# let PLLs lock\n\tsleep 10\n\n\t# PMC_MCKR:  switch to CPU clock = PLLA, master clock = CPU/4\n\tmww 0xfffffc30 0x0302\n\tsleep 20\n\n\t# CPU is in Normal Mode ... allows faster JTAG clock speed\n\tadapter speed 40000\n}\n\nproc csb337_nor_init { } {\n\t# SMC_CSR0:  adjust timings (10 wait states)\n\tmww 0xffffff70 0x1100318a\n\n\tflash probe 0\n}\n\nproc csb337_sdram_init { } {\n\t# enable PIOC clock\n\tmww 0xfffffc10 0x0010\n\t# PC31..PC16 are D31..D16, with internal pullups like D15..D0\n\tmww 0xfffff870 0xffff0000\n\tmww 0xfffff874 0x0\n\tmww 0xfffff804 0xffff0000\n\n\t# SDRC_CR: set timings\n\tmww 0xffffff98 0x2188b0d5\n\n\t# SDRC_MR: issue all banks precharge to SDRAM\n\tmww 0xffffff90 2\n\tmww 0x20000000 0\n\n\t# SDRC_MR: 8 autorefresh cycles\n\tmww 0xffffff90 4\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\tmww 0x20000000 0\n\n\t# SDRC_MR: set SDRAM mode registers (CAS, burst len, etc)\n\tmww 0xffffff90 3\n\tmww 0x20000080 0\n\n\t# SDRC_TR: set refresh rate\n\tmww 0xffffff94 0x200\n\tmww 0x20000000 0\n\n\t# SDRC_MR: normal mode, 32 bit bus\n\tmww 0xffffff90 0\n\tmww 0x20000000 0\n}\n\n# The rm9200 chip has just been reset.  Bring it up far enough\n# that we can write flash or run code from SDRAM.\nproc csb337_reset_init { } {\n\tcsb337_clk_init\n\n\t# EBI_CSA:  CS0 = NOR, CS1 = SDRAM\n\tmww 0xffffff60 0x02\n\n\tcsb337_nor_init\n\tcsb337_sdram_init\n\n\t# Update CP15 control register ... we don't seem to be able to\n\t# read/modify/write its value through a TCL variable, so just\n\t# write it.  Fields are zero unless listed here ... and note\n\t# that OpenOCD numbers this register \"2\", not \"1\" (!).\n\t#\n\t#  - Core to use Async Clocking mode (so it uses 184 MHz most\n\t#    of the time instead of limiting to the master clock rate):\n\t#\tiA(31) = 1, nF(30) = 1\n\t#  - Icache on (it's disabled now, slowing i-fetches)\n\t#\tI(12) = 1\n\t#  - Reserved/ones\n\t#\t6:3 = 1\n\tarm920t cp15 2 0xc0001078\n}\n\n$_TARGETNAME configure -event reset-init {csb337_reset_init}\n\narm7_9 fast_memory_access enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/csb732.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Cogent CSB732 board has a single i.MX35 chip\nsource [find target/imx35.cfg]\n\n# Determined by trial and error\nreset_config trst_and_srst combined\nadapter srst delay 200\njtag_ntrst_delay 200\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { csb732_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc csb732_init { } {\n\n\t# Disable fast writing only for init\n\tmemwrite burst disable\n\n\t# All delay loops are omitted.\n\t# We assume the interpreter latency is enough.\n\n\t# Allow access to all coprocessors\n\tarm mcr 15 0 15 1 0 0x2001\n\n\t# Disable MMU, caches, write buffer\n\tarm mcr 15 0 1 0 0 0x78\n\n\t# Grant manager access to all domains\n\tarm mcr 15 0 3 0 0 0xFFFFFFFF\n\n\t# Set ARM clock to 532 MHz, AHB to 133 MHz\n\tmww 0x53F80004 0x1000\n\n\t# Set core clock to 2 * 24 MHz * (11 + 1/12) = 532 MHz\n\tmww 0x53F8001C 0xB2C01\n\n\tset ESDMISC 0xB8001010\n\tset ESDCFG0 0xB8001004\n\tset ESDCTL0 0xB8001000\n\n\t# Enable DDR\n\tmww $ESDMISC 0x4\n\n\t# Timing\n\tmww $ESDCFG0 0x007fff3f\n\n\t# CS0\n\tmww $ESDCTL0 0x92120080\n\n\t# Precharge all dummy write\n\tmww 0x80000400 0\n\n\t# Enable CS) auto-refresh\n\tmww $ESDCTL0 0xA2120080\n\n\t# Refresh twice (dummy writes)\n\tmww 0x80000000 0\n\tmww 0x80000000 0\n\n\t# Enable CS0 load mode register\n\tmww $ESDCTL0 0xB2120080\n\n\t# Dummy writes\n\tmwb 0x80000033 0x01\n\tmwb 0x81000000 0x01\n\n\tmww $ESDCTL0 0x82226080\n\tmww 0x80000000 0\n\n\t# Re-enable fast writing\n\tmemwrite burst enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/da850evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#DA850 EVM board\n# http://focus.ti.com/dsp/docs/thirdparty/catalog/devtoolsproductfolder.tsp?actionPerformed=productFolder&productId=5939\n# http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit\n\nsource [find target/omapl138.cfg]\n\nreset_config trst_and_srst separate\n\n#currently any pinmux/timing must be setup by UBL before openocd can do debug\n#TODO: implement pinmux/timing on reset like in board/dm365evm.cfg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/digi_connectcore_wi-9c.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target: DIGI ConnectCore Wi-9C\n######################################\n\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ns9360\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set  _ENDIAN big\n}\n\n\n# What's a good fallback frequency for this board if RCLK is\n# not available??\njtag_rclk 1000\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 200\njtag_ntrst_delay 0\n\n\n######################\n# Target configuration\n######################\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x90600104 0x33313333\n\tmww 0xA0700000 0x00000001  ;# Enable the memory controller.\n\tmww 0xA0700024 0x00000006  ;# Set the refresh counter 6\n\tmww 0xA0700028 0x00000001  ;#\n\tmww 0xA0700030 0x00000001  ;# Set the precharge period\n\tmww 0xA0700034 0x00000004  ;# Active to precharge command period is 16 clock cycles\n\tmww 0xA070003C 0x00000001  ;# tAPR\n\tmww 0xA0700040 0x00000005  ;# tDAL\n\tmww 0xA0700044 0x00000001  ;# tWR\n\tmww 0xA0700048 0x00000006  ;# tRC 32 clock cycles\n\tmww 0xA070004C 0x00000006  ;# tRFC 32 clock cycles\n\tmww 0xA0700054 0x00000001  ;# tRRD\n\tmww 0xA0700058 0x00000001  ;# tMRD\n\tmww 0xA0700100 0x00004280  ;# Dynamic Config 0 (cs4)\n\tmww 0xA0700120 0x00004280  ;# Dynamic Config 1 (cs5)\n\tmww 0xA0700140 0x00004280  ;# Dynamic Config 2 (cs6)\n\tmww 0xA0700160 0x00004280  ;# Dynamic Config 3 (cs7)\n\t#\n\tmww 0xA0700104 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700124 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700144 0x00000203  ;# CAS latency is 2 at 100 MHz\n\tmww 0xA0700164 0x00000203  ;# CAS latency is 2 at 100 MHz\n\t#\n\tmww 0xA0700020 0x00000103  ;# issue SDRAM PALL command\n\t#\n\tmww 0xA0700024 0x00000001  ;# Set the refresh counter to be as small as possible\n\t#\n\t# Add some dummy writes to give the SDRAM time to settle, it needs two\n\t# AHB clock cycles, here we poke in the debugger flag, this lets\n\t# the software know that we are in the debugger\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\tmww 0xA0900000 0x00000002\n\t#\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\tmdw 0xA0900000\n\t#\n\tmww 0xA0700024 0x00000030 ;# Set the refresh counter to 30\n\tmww 0xA0700020 0x00000083 ;# Issue SDRAM MODE command\n\t#\n\t# Next we perform a read of RAM.\n\t# mw = move word.\n\tmdw 0x00022000\n\t# mw 0x00022000:P, r3  # 22000 for cas2 latency, 32000 for cas 3\n\t#\n\tmww 0xA0700020 0x00000003   ;# issue SDRAM NORMAL command\n\tmww 0xA0700100 0x00084280   ;# Enable buffer access\n\tmww 0xA0700120 0x00084280   ;# Enable buffer access\n\tmww 0xA0700140 0x00084280   ;# Enable buffer access\n\tmww 0xA0700160 0x00084280   ;# Enable buffer access\n\n\t#Set byte lane state (static mem 1)\"\n\tmww 0xA0700220 0x00000082\n\t#Flash Start\n\tmww 0xA09001F8 0x50000000\n\t#Flash Mask Reg\n\tmww 0xA09001FC 0xFF000001\n\tmww 0xA0700028 0x00000001\n\n\t#  RAMAddr = 0x00020000\n\t#  RAMSize = 0x00004000\n\n\t# Set the processor mode\n\treg cpsr 0xd3\n}\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x1000 -work-area-backup 1\n\n#####################\n# Flash configuration\n#####################\n\n#M29DW323DB - not working\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x50000000 0x0400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/digilent_analog_discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Digilent Analog Discovery\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,842,1018&Prod=ANALOG-DISCOVERY\n#\n# Config is based on data from\n# https://github.com/bvanheu/urjtag-ad/commit/8bd883ee01d134f94b79cbbd00df42cd03bafd71\n#\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x8008 0x800b\n\nadapter speed 25000\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/digilent_atlys.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://digilentinc.com/atlys/\n#\n# The Digilent Atlys normally requires proprietary tools to program and will\n# enumerate as:\n#   ID 1443:0007 Digilent Development board JTAG\n#\n# However, the ixo-usb-jtag project provides an alternative open firmware for\n# the on board programmer. When using this firmware the board will then\n# enumerate as:\n#   ID 16c0:06ad Van Ooijen Technische Informatica\n# (With SerialNumber == hw_nexys)\n#\n# See the interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/digilent_nexys_video.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Digilent Nexys Video with Xilinx Artix-7 FPGA\n# https://reference.digilentinc.com/programmable-logic/nexys-video/start\n\nadapter driver ftdi\nadapter speed 30000\n\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6010\n\n# channel 0 is dedicated for Digilent's DPTI Interface\n# channel 1 is used for JTAG\nftdi channel 1\n\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n\n# Enable sampling on falling edge for high JTAG speeds.\nftdi tdo_sample_edge falling\n\ntransport select jtag\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/digilent_zedboard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Digilent Zedboard Rev.C, Rev.D with Xilinx Zynq chip\n#\n# http://zedboard.com/product/zedboard\n#\n\nsource [find interface/ftdi/digilent_jtag_smt2.cfg]\n\nreset_config srst_only srst_push_pull\n\nsource [find target/zynq_7000.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/diolan_lpc4350-db1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Diolan LPC-4350-DB1 development board\n#\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/diolan_lpc4357-db1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Diolan LPC-4357-DB1 development board\n#\n\nset CHIPNAME lpc4357\n\nsource [find target/lpc4357.cfg]\n\nflash bank $_CHIPNAME.nor cfi 0x1C000000 0x00200000 2 2 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dk-tm4c129.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: board/dk-tm4c129.cfg is deprecated, please switch to board/ti_dk-tm4c129.cfg\"\n\nsource [find board/ti_dk-tm4c129.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dm355evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# DM355 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm355.html\n#   http://c6000.spectrumdigital.com/evmdm355/\n\nsource [find target/ti_dm355.cfg]\n\nreset_config trst_and_srst separate\n\n# NOTE:  disable or replace this call to dm355evm_init if you're\n# debugging new UBL code from SRAM.\n$_TARGETNAME configure -event reset-init { dm355evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm355evm_init {} {\n\tglobal dm355\n\n\techo \"Initialize DM355 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tjtag_rclk 1500\n\n\t########################\n\t# PLL1\t\t= 432 MHz (/8, x144)\n\t# ...SYSCLK1\t= 216 MHz (/2)  ... ARM, MJCP\n\t# ...SYSCLK2\t= 108 MHz (/4)  ... Peripherals\n\t# ...SYSCLK3\t= 27  MHz (/16) ... VPBE, DAC\n\t# ...SYSCLK4\t= 108 MHz (/4)  ... VPSS\n\t#\tpll1.{prediv,div1,div2} are fixed\n\t#\tpll1.postdiv set in MISC (for *this* speed grade)\n\n\tset addr [dict get $dm355 pllc1]\n\tset pll_divs [dict create]\n\tdict set pll_divs div3 16\n\tdict set pll_divs div4 4\n\tpll_v02_setup $addr 144 $pll_divs\n\n\t# ARM is now running at 216 MHz, so JTAG can go faster\n\tjtag_rclk 20000\n\n\t########################\n\t# PLL2\t\t= 342 MHz (/8, x114)\n\t# ....SYSCLK1\t= 342 MHz (/1)  ... DDR PHY at 171 MHz, 2x clock\n\t#\tpll2.{postdiv,div1} are fixed\n\n\tset addr [dict get $dm355 pllc2]\n\tset pll_divs [dict create]\n\tdict set pll_divs div1 1\n\tdict set pll_divs prediv 8\n\tpll_v02_setup $addr 114 $pll_divs\n\n\t########################\n\t# PINMUX\n\n\t# All Video Inputs\n\tdavinci_pinmux $dm355 0 0x00007f55\n\t# All Video Outputs\n\tdavinci_pinmux $dm355 1 0x00145555\n\t# EMIFA (NOTE: more could be set up for use as GPIOs)\n\tdavinci_pinmux $dm355 2 0x00000c08\n\t# SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs\n\tdavinci_pinmux $dm355 3 0x1bff55ff\n\t# MMC/SD0 instead of MS; SPI0\n\tdavinci_pinmux $dm355 4 0x00000000\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t########################\n\t# DDR2 EMIF\n\n\t# VTPIOCR impedance calibration\n\tset addr [dict get $dm355 sysbase]\n\tset addr [expr {$addr + 0x70}]\n\n\t# clear CLR, LOCK, PWRDN; wait a clock; set CLR\n\tmmw $addr 0 0x20c0\n\tmmw $addr 0x2000 0\n\n\t# wait for READY\n        while { [expr {[mrw $addr] & 0x8000}] == 0 } { sleep 1 }\n\n\t# set IO_READY; then LOCK and PWRSAVE; then PWRDN\n\tmmw $addr 0x4000 0\n\tmmw $addr 0x0180 0\n\tmmw $addr 0x0040 0\n\n\t# NOTE:  this DDR2 initialization sequence borrows from\n\t# both UBL 1.50 and the SPRUEH7D DDR2 EMIF spec.\n\n\t# reset (then re-enable) DDR controller\n\tpsc_reset 13\n\tpsc_go\n\tpsc_enable 13\n\tpsc_go\n\n\t# now set it up for Micron MT47H64M16HR-37E @ 171 MHz\n\n\tset addr [dict get $dm355 ddr_emif]\n\n\t# DDRPHYCR1\n\tmww [expr {$addr + 0xe4}] 0x50006404\n\n\t# PBBPR -- burst priority\n\tmww [expr {$addr + 0x20}] 0xfe\n\n\t# SDCR -- unlock boot config; init for DDR2, relock, unlock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0x00800000 0\n\tmmw [expr {$addr + 0x08}] 0x0013c632 0x03870fff\n\n\t# SDTIMR0, SDTIMR1\n\tmww [expr {$addr + 0x10}] 0x2a923249\n\tmww [expr {$addr + 0x14}] 0x4c17c763\n\n\t# SDCR -- relock SDTIM*\n\tmmw [expr {$addr + 0x08}] 0 0x00008000\n\n\t# SDRCR -- refresh rate (171 MHz * 7.8usec)\n\tmww [expr {$addr + 0x0c}] 1336\n\n\t########################\n\t# ASYNC EMIF\n\n\tset addr [dict get $dm355 a_emif]\n\n\t# slow/pessimistic timings\n\tset nand_timings 0x40400204\n\t# fast (25% faster page reads)\n\t#set nand_timings 0x0400008c\n\n\t# AWCCR\n\tmww [expr {$addr + 0x04}] 0xff\n\t# CS0 == socketed NAND (default MT29F16G08FAA, 2GByte)\n\tmww [expr {$addr + 0x10}] $nand_timings\n\t# CS1 == dm9000 Ethernet\n\tmww [expr {$addr + 0x14}] 0x00a00505\n\t# NANDFCR -- only CS0 has NAND\n\tmww [expr {$addr + 0x60}] 0x01\n\n\t# default: both chipselects to the NAND socket are used\n\tnand probe 0\n\tnand probe 1\n\n\t########################\n\t# UART0\n\n\tset addr [dict get $dm355 uart0]\n\n\t# PWREMU_MGNT -- rx + tx in reset\n\tmww [expr {$addr + 0x30}] 0\n\n\t# DLL, DLH -- 115200 baud\n\tmwb [expr {$addr + 0x20}] 0x0d\n\tmwb [expr {$addr + 0x24}] 0x00\n\n\t# FCR - clear and disable FIFOs\n\tmwb [expr {$addr + 0x08}] 0x07\n\tmwb [expr {$addr + 0x08}] 0x00\n\n\t# IER - disable IRQs\n\tmwb [expr {$addr + 0x04}] 0x00\n\n\t# LCR - 8-N-1\n\tmwb [expr {$addr + 0x0c}] 0x03\n\n\t# MCR - no flow control or loopback\n\tmwb [expr {$addr + 0x10}] 0x00\n\n\t# PWREMU_MGNT -- rx + tx normal, free running during JTAG halt\n\tmww [expr {$addr + 0x30}] 0xe001\n\n\n\t########################\n\n\t# turn on icache - set I bit in cp15 register c1\n\tarm mcr 15 0 0 1 0 0x00051078\n}\n\n# NAND -- socket has two chipselects, MT29F16G08FAA puts 1GByte on each one.\n#\n# NOTE:  \"hwecc4\" here presumes that if you're using the standard 2GB NAND\n# you either (a) have 'new' DM355 chips, with boot ROMs that don't need to\n# use \"hwecc4_infix\" for the UBL; or else (b) aren't updating anything that\n# needs infix layout ... like an old UBL, old U-Boot, old MVL kernel, etc.\nset _FLASHNAME $_CHIPNAME.boot\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02000000 hwecc4 0x01e10000\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME davinci $_TARGETNAME 0x02004000 hwecc4 0x01e10000\n\n# FIXME\n#  - support writing UBL with its header (new layout only with new ROMs)\n#  - support writing ABL/U-Boot with its header (new layout)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dm365evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# DM365 EVM board -- Beta\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdxevm365.html\n#   http://support.spectrumdigital.com/boards/evmdm365\n\nsource [find target/ti_dm365.cfg]\n\n# NOTE:  in Rev C boards, the CPLD ignores SRST from the ARM-20 JTAG\n# connector, so it doesn't affect generation of the reset signal.\n# Accordingly, resets require something else.  ICEpick could do it;\n# but its docs aren't generally available.\n#\n# At this writing, newer boards aren't available ... so assume no SRST.\n# Also ICEpick docs aren't available ... so we must use watchdog reset,\n# and hope the CPU isn't wedged or in a WFI loop (either of which can\n# block access to CPU and thus watchdog registers).\n\nreset_config trst_only\n$_TARGETNAME configure -event reset-assert \"davinci_wdog_reset\"\n\n# SW5.1 routes CS0: NAND vs OneNAND.\n# SW4.6:4 controls AEMIF width (8 for NAND, 16 for OneNand)\n# for boot-from-flash, those must agree with SW4.3:1 settings.\n\nif { [info exists CS0MODE] } {\n\t# NAND or OneNAND\n\tset CS0 $CS0MODE\n} else {\n\tset CS0 \"\"\n\techo \"WARNING:  CS0 configuration not known\"\n\tproc cs0_setup {a_emif} {}\n\tproc flashprobe {} {}\n}\n\nset a_emif [dict get $dm365 a_emif]\n\n# As shipped:  boot from NAND.\nif { $CS0 == \"NAND\" } {\n\techo \"CS0 NAND\"\n\n\t# NAND socket has two chipselects.  Default MT29F16G08FAA chip\n\t# has 1GByte on each one.\n\t# NOTE:  \"hwecc4\" here presumes that you're not updating anything\n\t# that needs infix layout (e.g. UBL, old U-Boot, etc)\n\tnand device low davinci $_TARGETNAME 0x02000000 hwecc4 $a_emif\n\tnand device high davinci $_TARGETNAME 0x02004000 hwecc4 $a_emif\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 8 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000016\n\n\t\t# slow/pessimistic timings\n\t\tset nand_timings 0x40400204\n\t\t# fast (25% faster page reads)\n\t\t#set nand_timings 0x0400008c\n\n\t\t# CS0 == socketed NAND (default MT29F16G08FAA, 2 GBytes)\n\t\tmww [expr {$a_emif + 0x10}] $nand_timings\n\n\t\t# NANDFCR -- CS0 has NAND\n\t\tmww [expr {$a_emif + 0x60}] 0x01\n\t}\n\tproc flashprobe {} {\n\t\tnand probe 0\n\t\tnand probe 1\n\t}\n\n} elseif { $CS0 == \"OneNAND\" } {\n\techo \"CS0 OneNAND\"\n\n\t# No support for this OneNAND in OpenOCD (yet) or Linux ...\n\t# REVISIT OneNAND timings not verified to work!\n\techo \"WARNING -- OneNAND not yet tested!\"\n\n\tproc cs0_setup {a_emif} {\n\t\tglobal dm365\n\n\t\t# 16 bit EMIF\n\t\tdavinci_pinmux $dm365 2 0x00000055\n\n\t\t# CS0 == OneNAND (KFG1G16U2B-DIB6, 128 KBytes)\n\t\tmww [expr {$a_emif + 0x10}] 0x00000001\n\n\t\t# ONENANDCTRL -- CS0 has OneNAND, enable sync reads\n\t\tmww [expr {$a_emif + 0x5c}] 0x0441\n\t}\n\tproc flashprobe {} { }\n}\n\n# NOTE:  disable or replace this call to dm365evm_init if you're\n# debugging new UBL/NANDboot code from SRAM.\n$_TARGETNAME configure -event reset-init { dm365evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm365evm_init {} {\n\tglobal dm365\n\n\techo \"Initialize DM365 EVM board\"\n\n\t# CLKIN\t= 24 MHz ... can't talk quickly to ARM yet\n\tadapter speed 1500\n\n\t# FIXME -- PLL init\n\n\t########################\n\t# PINMUX setup\n\n\tdavinci_pinmux $dm365 0 0x00fd0000\n\tdavinci_pinmux $dm365 1 0x00145555\n\t# mux2 controls AEMIF ... 8 bit for NAND, 16 for OneNand\n\tdavinci_pinmux $dm365 3 0x375affff\n\tdavinci_pinmux $dm365 4 0x55556555\n\n\t########################\n\t# PSC setup (minimal)\n\n\t# DDR EMIF/13, AEMIF/14, UART0/19\n\tpsc_enable 13\n\tpsc_enable 14\n\tpsc_enable 19\n\tpsc_go\n\n\t# FIXME setup DDR2 (needs PLL)\n\n\t########################\n\t# ASYNC EMIF\n\n\tset a_emif [dict get $dm365 a_emif]\n\n\t# AWCCR\n\tmww [expr {$a_emif + 0x04}] 0xff\n\t# CS0 == NAND or OneNAND\n\tcs0_setup $a_emif\n\t# CS1 == CPLD\n\tmww [expr {$a_emif + 0x14}] 0x00a00505\n\n\t# FIXME setup UART0\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dm6446evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# DM6446 EVM board\n#   http://focus.ti.com/docs/toolsw/folders/print/tmdsevm6446.html\n#   http://c6000.spectrumdigital.com/davincievm/\n# EVM is just the board; buy that at Spectrum.\n# The \"kit\" from TI also has: video camera, LCD video monitor, more.\n\nsource [find target/ti_dm6446.cfg]\n\n# J4 controls what CS2 hooks up to, usually NOR or NAND flash.\n# S3.1/S3.2 controls boot mode, which may force J4 and S3.3 settings.\n# S3.3 controls AEMIF bus width.\n\nif { [info exists J4_OPTION] } {\n\t# NOR, NAND, SRAM, ...\n\tset CS2_MODE $J4_OPTION\n} else {\n\tset CS2_MODE \"\"\n}\n\n# ARM boot:\n#  S3.1 = 0, S3.2 = 0\t==> ROM/UBL boot via NAND (J4 == NAND)\n#  S3.1 = 1, S3.2 = 0\t==> AEMIF boot (J4 == NOR or SRAM)\n#  S3.1 = 0, S3.2 = 1\t==> ROM/UBL boot via HPI\n#  S3.1 = 1, S3.2 = 1\t==> ROM/UBL boot via UART (J4 == don't care)\n# AEMIF bus width:\n#  S3.3 = 0\t\t==> 8 bit bus width\n#  S3.3 = 1\t\t==> 16 bit bus width\n# DSP boot:\n#  S3.4 = 0\t\t==> controlled by ARM\n\nif { $CS2_MODE == \"NOR\" } {\n\t# 16 Mbytes address space; 16 bit bus width\n\t# (older boards used 32MB parts, with upper 16 MB unusable)\n\tset _FLASHNAME $_CHIPNAME.flash\n\tflash bank $_FLASHNAME cfi 0x02000000 0x01000000 2 2 $_TARGETNAME\n\tproc flashprobe {} { flash probe 0 }\n} elseif { $CS2_MODE == \"NAND\" } {\n\t# 64 Mbyte small page; 8 bit bus width\n\tnand device davinci $_TARGETNAME 0x02000000 hwecc1 0x01e00000\n\tproc flashprobe {} { nand probe 0 }\n} elseif { $CS2_MODE == \"SRAM\" } {\n\t# 4 Mbyte address space; 16 bit bus width\n\t# loaded via JTAG or HPI\n\tproc flashprobe {} {}\n} else {\n\t# maybe it's HPI boot?  can't tell...\n\techo \"WARNING:  CS2/flash configuration not recognized\"\n\tproc flashprobe {} {}\n}\n\n# NOTE:  disable or replace this call to dm6446evm_init if you're\n# debugging new UBL code from SRAM (for NAND boot).\n$_TARGETNAME configure -event reset-init { dm6446evm_init }\n\n#\n# This post-reset init is called when the MMU isn't active, all IRQs\n# are disabled, etc.  It should do most of what a UBL does, except for\n# loading code (like U-Boot) into DRAM and running it.\n#\nproc dm6446evm_init {} {\n\n\techo \"Initialize DM6446 EVM board\"\n\n\t# FIXME initialize everything:\n\t#  - PLL1\n\t#  - PLL2\n\t#  - PINMUX\n\t#  - PSC\n\t#  - DDR\n\t#  - AEMIF\n\t#  - UART0\n\t#  - icache\n\n\tflashprobe\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dp_busblaster_v3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v3.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c32a tap -expected-id 0x06e1c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dp_busblaster_v4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://raw.githubusercontent.com/dergraaf/busblaster_v4/master/ktlink/ktlink.svf\n#\n# To reprogram the on-board CPLD do:\n# openocd -f board/dp_busblaster_v4.cfg -c \"adapter speed 1000; init; svf <path_to_svf>; shutdown\"\n#\n\nsource [find interface/ftdi/dp_busblaster.cfg]\nftdi channel 1\n\njtag newtap xc2c64a tap -expected-id 0x06e5c093 -irlen 8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/dptechnics_dpt-board-v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Product page:\n# https://www.dptechnics.com/en/products/dpt-board-v1.html\n#\n# JTAG is a 5 pin array located close to main module in following order:\n# 1. JTAG TCK\n# 2. JTAG TDO\n# 3. JTAG TDI\n# 4. JTAG TMS\n# 5. GND\tThe GND is located near letter G of word JTAG on board.\n#\n# Two RST pins are connected to:\n# 1. GND\n# 2. GPIO11\tthis pin is located near letter R of word RST.\n#\n# To enable EJTAG mode, GPIO11 (RST[1]) pin should be pulled up. For example\n# with 10K resistor connected to V3.3 pin.\n#\n# This board is powered from micro USB connector. No real reset pin or button, for\n# example RESET_L is available.\n\nsource [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr2_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ecp5_evaluation.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Lattice ECP5 evaluation Kit\n# https://www.latticesemi.com/view_document?document_id=52479\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x008b\nreset_config none\ntransport select jtag\nadapter speed 6000\n\nsource [find fpga/lattice_ecp5.cfg]\n\n#openocd -f board/ecp5_evaluation.cfg -c \"init\" -c \"pld load 0 shared_folder/ecp5_blinker_impl1.bit\"\n#ipdbg -start -tap ecp5.tap -hub 0x32 -port 5555 -tool 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/efikamx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Genesi USA EfikaMX\n#  http://www.genesi-usa.com/products/efika\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 6000 }\n\nsource [find target/imx51.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/efm32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for EFM32 boards with on-board SEGGER J-Link\n#\n# Tested with Tiny, Giant and Zero Gecko Starter Kit.\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nset CHIPNAME efm32\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/eir.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Elector Internet Radio board\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nsource [find target/at91sam7se512.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# WDT_MR, disable watchdog\n\tmww 0xFFFFFD44 0x00008000\n\n\t# RSTC_MR, enable user reset\n\tmww 0xfffffd08 0xa5000001\n\n\t# CKGR_MOR\n\tmww 0xFFFFFC20 0x00000601\n\tsleep 10\n\n\t# CKGR_PLLR\n\tmww 0xFFFFFC2C 0x00481c0e\n\tsleep 10\n\n\t# PMC_MCKR\n\tmww 0xFFFFFC30 0x00000007\n\tsleep 10\n\n\t# PMC_IER\n\tmww 0xFFFFFF60 0x00480100\n\n\t#\n\t# Enable SDRAM interface.\n\t#\n\n\t# Enable SDRAM control at PIO A.\n\tmww 0xfffff474 0x3f800000 ;# PIO_BSR_OFF\n\tmww 0xfffff404 0x3f800000 ;# PIO_PDR_OFF\n\n\t# Enable address bus (A0, A2-A11, A13-A17) at PIO B\n\tmww 0xfffff674 0x0003effd ;# PIO_BSR_OFF\n\tmww 0xfffff604 0x0003effd ;# PIO_PDR_OFF\n\n\t# Enable 16 bit data bus at PIO C\n\tmww 0xfffff870 0x0000ffff ;# PIO_ASR_OFF\n\tmww 0xfffff804 0x0000ffff ;# PIO_PDR_OFF\n\n\t# Enable SDRAM chip select\n\tmww 0xffffff80 0x00000002 ;# EBI_CSA_OFF\n\n\t# Set SDRAM characteristics in configuration register.\n\t# Hard coded values for MT48LC32M16A2 with 48MHz CPU.\n\tmww 0xffffffb8 0x2192215a ;# SDRAMC_CR_OFF\n\tsleep 10\n\n\t# Issue 16 bit SDRAM command: NOP\n\tmww 0xffffffb0 0x00000011 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Precharge all\n\tmww 0xffffffb0 0x00000012 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 8 auto-refresh cycles\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\tmww 0xffffffb0 0x00000014 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000000\n\n\t# Issue 16 bit SDRAM command: Set mode register\n\tmww 0xffffffb0 0x00000013 ;# SDRAMC_MR_OFF\n\tmww 0x20000014 0xcafedede\n\n\t# Set refresh rate count ???\n\tmww 0xffffffb4 0x00000013 ;# SDRAMC_TR_OFF\n\n\t# Issue 16 bit SDRAM command: Normal mode\n\tmww 0xffffffb0 0x00000010 ;# SDRAMC_MR_OFF\n\tmww 0x20000000 0x00000180\n\n\t#\n\t# Enable external reset key.\n\t#\n\tmww 0xfffffd08 0xa5000001\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s1968.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S1968 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s1968\n#\n\n# NOTE:  to use J-Link instead of the on-board interface,\n# you may also need to reduce adapter speed to be about 1200.\n# source [find interface/jlink.cfg]\n\n# include the FT2232 interface config for on-board JTAG interface\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s1968\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s3748.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris lm3s3748 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s3748\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s3748\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s6965.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S6965 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s6965\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 20k working area\nset WORKAREASIZE 0x5000\nset CHIPNAME lm3s6965\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s811-revb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits (rev B and earlier)\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE: newer 811-EK boards (rev C and above) shouldn't use this.\n# use board/ek-lm3s811.cfg\nsource [find interface/ftdi/luminary-lm3s811.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s811.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S811 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s811\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\n# NOTE:  older '811-EK boards (before rev C) shouldn't use this.\nsource [find interface/ftdi/luminary.cfg]\n\n# include the target config\nset WORKAREASIZE 0x2000\nset CHIPNAME lm3s811\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s8962.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S8962 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s8962\n#\n\n# NOTE:  using the on-board FT2232 JTAG/SWD/SWO interface is optional!\n# so is using it in JTAG mode, as done here.\nsource [find interface/ftdi/luminary.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s8962\n# include the target config\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s9b9x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S9B9x Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9b90\n# http://www.ti.com/tool/ek-lm3s9b92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\nset WORKAREASIZE 0x4000\nset CHIPNAME lm3s9b9x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm3s9d92.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI/Luminary Stellaris LM3S9D92 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm3s9d92\n#\n\n# NOTE:  using the bundled FT2232 JTAG/SWD/SWO interface is optional!\n# so is using in JTAG mode, as done here.\nsource [find interface/ftdi/luminary-icdi.cfg]\n\n# 64k working area\nset WORKAREASIZE 0x10000\nset CHIPNAME lm3s9d92\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm4f120xl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Stellaris Launchpad ek-lm4f120xl Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f120xl\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f120h5qr\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-lm4f232.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Stellaris LM4F232 Evaluation Kits\n#\n# http://www.ti.com/tool/ek-lm4f232\n#\n\n#\n# NOTE: using the bundled ICDI interface is optional!\n# This interface is not ftdi based as previous boards were\n#\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME lm4f23x\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-tm4c123gxl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: board/ek-tm4c123gxl.cfg is deprecated, please switch to board/ti_ek-tm4c123gxl.cfg\"\n\nsource [find board/ti_ek-tm4c123gxl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ek-tm4c1294xl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: board/ek-tm4c1294xl.cfg is deprecated, please switch to board/ti_ek-tm4c1294xl.cfg\"\n\nsource [find board/ti_ek-tm4c1294xl.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/embedded-artists_lpc2478-32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Embedded Artists eval board for LPC2478\n# http://www.embeddedartists.com/\n\n# Target device: LPC2478\nset CCLK 72000\nsource [find target/lpc2478.cfg]\n\n# Helper\n#\nproc read_register {register} {\n    return [read_memory $register 32 1]\n}\n\nproc init_board {} {\n    # Delays on reset lines\n    adapter srst delay 500\n    jtag_ntrst_delay 1\n\n    # Adaptive JTAG clocking through RTCK.\n    #\n    jtag_rclk 20\n\n    global _TARGETNAME\n    global _CHIPNAME\n\n    # A working area will help speeding the flash programming\n    $_TARGETNAME configure -work-area-phys 0x40000200 -work-area-size [expr {0x10000-0x200-0x20}] -work-area-backup 0\n\n    # External 16-bit flash at chip select CS0 (SST39VF3201-70, 4 MiB)\n    flash bank $_CHIPNAME.extflash cfi 0x80000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n    # Event handlers\n    #\n    $_TARGETNAME configure -event reset-start {\n        # Back to the slow JTAG clock\n        jtag_rclk 20\n    }\n\n    $_TARGETNAME configure -event reset-init {\n        arm core_state arm\n        arm7_9 dcc_downloads enable     ;# Speed up downloads by using DCC transfer\n        arm7_9 fast_memory_access enable\n\n        # Peripheral clocks\n        mww 0xE01FC0C4 0x04280FFE       ;# PCONP: (reset value)\n\n        # Map the user flash to the vector table area (0x00...0x3F)\n        mww 0xE01FC040 0x00000001       ;# MEMMAP: User flash\n\n        # Memory accelerator module\n        mww 0xE01FC004 0x00000003       ;# MAMTIM: 3 clock cycles\n        mww 0xE01FC000 0x00000002       ;# MAMCR: fully enabled\n\n        # Enable external memory bus (32-bit SDRAM at DYCS0, 16-bit flash at CS0)\n        mww 0xE002C014 0x55010115       ;# PINSEL5: P2.16=CAS, P2.17=RAS, P2.18=CLKOUT0,\n                                         # P2.20=DYCS0, P2.24=CKEOUT0, P2.28=DQMOUT0,\n                                         # P2.29=DQMOUT1, P2.30=DQMOUT2, P2.31=DQMOUT3\n        mww 0xE002C018 0x55555555       ;# PINSEL6: P3.0...P3.15=D0...D15\n        mww 0xE002C01C 0x55555555       ;# PINSEL7: P3.16...P3.31=D16...D31\n        mww 0xE002C020 0x55555555       ;# PINSEL8: P4.0...P4.15=A0...A15\n        mww 0xE002C024 0x50051555       ;# PINSEL9: P4.16...P4.22=A16...A22, P4.24=OE,\n                                         # P4.25=WE, P4.30=CS0, P4.31=CS1\n        mww 0xFFE08000 0x00000001       ;# EMCControl: Enable EMC\n\n        # Start PLL, then use faster JTAG clock\n        enable_pll\n        jtag_rclk 3000\n\n        # 16-bit flash @ CS0 (SST39VF3201-70)\n        mww 0xFFE08200 0x00080081       ;# EMCStaticConfig0: 16 bit, PB=1, buffers on\n        mww 0xFFE08204 0x00000000       ;# EMCStaticWaitWen0\n        mww 0xFFE08208 0x00000000       ;# EMCStaticWaitOen0\n        mww 0xFFE0820C 0x00000005       ;# EMCStaticWaitRd0\n        mww 0xFFE08210 0x00000005       ;# EMCStaticWaitPage0\n        mww 0xFFE08214 0x00000003       ;# EMCStaticWaitWr0\n        mww 0xFFE08218 0x00000001       ;# EMCStaticWaitTurn0\n\n        # 8-bit NAND @ CS1\n        # TODO\n\n        # 32-bit SDRAM @ DYCS0 (K4M563233G-HN75)\n        mww 0xFFE08028 0x00000001       ;# EMCDynamicReadConfig\n        mww 0xFFE08030 0x00000001       ;# EMCDynamicRP\n        mww 0xFFE08034 0x00000003       ;# EMCDynamicRAS\n        mww 0xFFE08038 0x00000005       ;# EMCDynamicSREX\n        mww 0xFFE0803C 0x00000001       ;# EMCDynamicAPR\n        mww 0xFFE08040 0x00000005       ;# EMCDynamicDAL\n        mww 0xFFE08044 0x00000001       ;# EMCDynamicWR\n        mww 0xFFE08048 0x00000005       ;# EMCDynamicRC\n        mww 0xFFE0804C 0x00000005       ;# EMCDynamicRFC\n        mww 0xFFE08050 0x00000005       ;# EMCDynamicXSR\n        mww 0xFFE08054 0x00000001       ;# EMCDynamicRRD\n        mww 0xFFE08058 0x00000001       ;# EMCDynamicMRD\n        #\n        mww 0xFFE08104 0x00000202       ;# EMCDynamicRasCas0\n        mww 0xFFE08100 0x00005488       ;# EMCDynamicConfig0\n        sleep 100\n        mww 0xFFE08020 0x00000183       ;# EMCDynamicControl: Clock on continuously, NOP\n        sleep 10\n        mww 0xFFE08020 0x00000103       ;# EMCDynamicControl: PRECHARGE-ALL\n        mww 0xFFE08024 0x00000046       ;# EMCDynamicRefresh\n        sleep 100\n        mww 0xFFE08020 0x00000083       ;# EMCDynamicControl: MODE\n        mdw 0xA0011000 1                ;# Set SDRAM mode register\n        mww 0xFFE08020 0x00000000       ;# EMCDynamicControl: NORMAL\n        mww 0xFFE08100 0x00085488       ;# EMCDynamicConfig0: Enable buffers\n    }\n\n    $_TARGETNAME configure -event gdb-attach {\n        # Without this gdb-attach will first time as probe will fail\n        reset init\n    }\n}\n\n# Enable the PLL.\n# Generate maximum CPU clock (72 MHz) Run from internal RC oscillator.\n# Note: The PLL output runs at a frequency N times the desired CPU clock.\n#       It in unavoidable that the CPU clock drops down to (4 MHz/N) during\n#       the initialization!\n#       Here: N=4\n#       Note that if the PLL is already active at the time this script is\n#       called, the effective value of N is the value of CCLKCFG at that time!\n#\nproc enable_pll {} {\n    # Disconnect PLL in case it is already connected\n    if {[expr {[read_register 0xE01FC080] & 0x03}] == 3} {\n        # Disconnect it, but leave it enabled\n        # (This MUST be done in two steps)\n        mww 0xE01FC080 0x00000001       ;# PLLCON: disconnect PLL\n        mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n        mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    }\n    # Disable PLL (as it might already be enabled at this time!)\n    mww 0xE01FC080 0x00000000       ;# PLLCON: disable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n\n    # Setup PLL to generate 288 MHz from internal RC oscillator\n    mww 0xE01FC10C 0x00000000       ;# CLKSRCSEL: IRC\n    mww 0xE01FC084 0x00000023       ;# PLLCFG: N=1, M=36\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    mww 0xE01FC080 0x00000001       ;# PLLCON: enable PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n    sleep 100\n    mww 0xE01FC104 0x00000003       ;# CCLKCFG: divide by 4 (72 MHz)\n    mww 0xE01FC080 0x00000003       ;# PLLCON: connect PLL\n    mww 0xE01FC08C 0x000000AA       ;# PLLFEED\n    mww 0xE01FC08C 0x00000055       ;# PLLFEED\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/emcraft_imx8m-som-bsb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# configuration file for Emcraft IMX8M-SOM-BSB\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# SRST and TRST are wired up\nreset_config trst_and_srst\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/emcraft_twr-vf6-som-bsb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# EmCraft Systems TWR-VF6-SOM-BSB\n#\n# http://www.emcraft.com/products/259#twr-kit\n#\n\nsource [find board/emcraft_vf6-som.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/emcraft_vf6-som.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# EmCraft Systems Vybrid VF6 SOM\n#\n# http://www.emcraft.com/products/259#som\n#\n\nset CHIPNAME vf610\nsource [find target/vybrid_vf6xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32-bridge.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32 connected via ESP USB Bridge board\n#\n# For example, OpenOCD can be started for ESP32 debugging on\n#\n#   openocd -f board/esp32-bridge.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/esp_usb_bridge.cfg]\n# ESP32 chip id defined in the idf esp_chip_model_t\nespusbjtag chip_id 1\n# Source the ESP32 configuration file\nsource [find target/esp32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32-ethernet-kit-3.3v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-ETHERNET-KIT board.\n#\n# For example, OpenOCD can be started for ESP32 debugging on\n#\n#   openocd -f board/esp32-ethernet-kit-3.3v.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/ftdi/esp32_devkitj_v1.cfg]\nset ESP32_FLASH_VOLTAGE 3.3\n# Source the ESP32 configuration file\nsource [find target/esp32.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n#\n# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32-wrover-kit-1.8v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-WROVER-KIT board.\n#\n# For example, OpenOCD can be started for ESP32 debugging on\n#\n#   openocd -f board/esp32-wrover-kit-1.8v.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/ftdi/esp32_devkitj_v1.cfg]\nset ESP32_FLASH_VOLTAGE 1.8\n# Source the ESP32 configuration file\nsource [find target/esp32.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n#\n# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32-wrover-kit-3.3v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-WROVER-KIT board.\n#\n# For example, OpenOCD can be started for ESP32 debugging on\n#\n#   openocd -f board/esp32-wrover-kit-3.3v.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/ftdi/esp32_devkitj_v1.cfg]\nset ESP32_FLASH_VOLTAGE 3.3\n# Source the ESP32 configuration file\nsource [find target/esp32.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n#\n# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32s2-bridge.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S2 connected via ESP USB Bridge board\n#\n# For example, OpenOCD can be started for ESP32-S2 debugging on\n#\n#   openocd -f board/esp32s2-bridge.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/esp_usb_bridge.cfg]\n# ESP32S2 chip id defined in the idf esp_chip_model_t\nespusbjtag chip_id 2\n# Source the ESP32-S2 configuration file\nsource [find target/esp32s2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32s2-kaluga-1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S2 Kaluga board.\n#\n# For example, OpenOCD can be started for ESP32-S2 debugging on\n#\n#   openocd -f board/esp32s2-kaluga-1.cfg\n#\n\nsource [find interface/ftdi/esp32s2_kaluga_v1.cfg]\nsource [find target/esp32s2.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n# On ESP32-S2, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32s3-bridge.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S3 connected via ESP USB Bridge board\n#\n# For example, OpenOCD can be started for ESP32-S3 debugging on\n#\n#   openocd -f board/esp32s3-bridge.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/esp_usb_bridge.cfg]\n# ESP32S3 chip id defined in the idf esp_chip_model_t\nespusbjtag chip_id 9\n# Source the ESP32-S3 configuration file\nsource [find target/esp32s3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32s3-builtin.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S3 connected via builtin USB-JTAG adapter.\n#\n# For example, OpenOCD can be started for ESP32-S3 debugging on\n#\n#   openocd -f board/esp32s3-builtin.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/esp_usb_jtag.cfg]\n# Source the ESP32-S3 configuration file\nsource [find target/esp32s3.cfg]\n\nadapter speed 40000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/esp32s3-ftdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Example OpenOCD configuration file for ESP32-S3 connected via ESP-Prog.\n#\n# For example, OpenOCD can be started for ESP32-S3 debugging on\n#\n#   openocd -f board/esp32s3-ftdi.cfg\n#\n\n# Source the JTAG interface configuration file\nsource [find interface/ftdi/esp32_devkitj_v1.cfg]\n# Source the ESP32-S3 configuration file\nsource [find target/esp32s3.cfg]\n\n# The speed of the JTAG interface, in kHz. If you get DSR/DIR errors (and they\n# do not relate to OpenOCD trying to read from a memory range without physical\n# memory being present there), you can try lowering this.\n#\n# On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz\n# if CPU frequency is 160MHz or 240MHz.\nadapter speed 20000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ethernut3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Ethernut 3 board configuration file\n#\n# http://www.ethernut.de/en/hardware/enut3/\n\n\n# AT91R40008-66AU ARM7TDMI Microcontroller\n# 256kB internal RAM\nsource [find target/at91r40008.cfg]\n\n\n# AT49BV322A-70TU NOR Flash\n# 2M x 16 mode at address 0x10000000\n# Common flash interface supported\n#\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x400000 2 2 $_TARGETNAME\n\n\n# Micrel MIC2775-29YM5 Supervisor\n# Reset output will remain active for 280ms (maximum)\n#\nadapter srst delay 300\njtag_ntrst_delay 300\n\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\nadapter speed 16000\n\n\n# Target events\n#\n$_TARGETNAME configure -event reset-init { board_init }\n\n# Initialize board hardware\n#\nproc board_init { } {\n\tboard_remap\n\tflash probe 0\n}\n\n# Memory remap\n#\nproc board_remap {{VERBOSE 0}} {\n\t# CS0: NOR flash\n\t#      16MB @ 0x10000000\n\t#      16-bit data bus\n\t#      4 wait states\n\t#\n\tmww 0xffe00000 0x1000212d\n\n\t# CS1: Ethernet controller\n\t#      1MB @ 0x20000000\n\t#      16-bit data bus\n\t#      2 wait states\n\t#      Byte select access\n\t#\n\tmww 0xffe00004 0x20003025\n\n\t# CS2: CPLD registers\n\t#      1MB @ 0x21000000\n\t#      8-bit data bus\n\t#      2 wait states\n\t#\n\tmww 0xffe00008 0x21002026\n\n\t# CS3: Expansion bus\n\t#      1MB @ 0x22000000\n\t#      8-bit data bus\n\t#      8 wait states\n\t#\n\tmww 0xffe00010 0x22002e3e\n\n\t# Remap command\n\t#\n\tmww 0xffe00020 0x00000001\n\n\tif {$VERBOSE != 0} {\n\t\techo \"0x00000000 RAM\"\n\t\techo \"0x10000000 Flash\"\n\t\techo \"0x20000000 Ethernet\"\n\t\techo \"0x21000000 CPLD\"\n\t\techo \"0x22000000 Expansion\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/evb-lan9255.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip LAN9255 evaluation board\n# https://www.microchip.com/en-us/development-tool/EV25Y25A\n#\n\nset CHIPNAME same53\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/frdm-kl25z.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an Freescale Freedom eval board with a single MKL25Z128VLK4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL25Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL25Z128VLK4\n\nreset_config srst_only\n\nsource [find target/kl25.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/frdm-kl46z.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an Freescale Freedom eval board with a single MKL46Z256VLL4 chip.\n# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=FRDM-KL46Z\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# increase working area to 16KB\nset WORKAREASIZE 0x4000\n\n# chip name\nset CHIPNAME MKL46Z256VLL4\n\nreset_config srst_only\n\nsource [find target/kl46.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/fsl_imx6q_sabresd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Board configuration file for the Freescale IMX6Q Sabre SD EVM\n#\n# This board does not have an embedded JTAG adapter, you must source\n# a suitable adapter configuration before sourcing this file.\n\n# Sabre SD has a standard ARM-20 JTAG connector with\n# nTRST and nSRST available.\nreset_config trst_and_srst\n\n# the only possible transport is JTAG\ntransport select jtag\n\n# iMX6Q POR gates JTAG and the chip is completely incommunicado\n# over JTAG for at least 10ms after nSRST is deasserted\nadapter srst delay 11\n\n# Source generic iMX6Q target configuration\nset CHIPNAME imx6q\nsource [find target/imx6.cfg]\n\n# function to apply initial configuration after a reset. It\n# provides a basic pad configuration and also DDR memory and clocks\n# sufficient to load and execute a boot loader (e.g. barebox) from\n# DDR memory. This list is extracted from the barebox flash image\n# header.\nproc apply_dcd { } {\n\tmww 0x020e05a8 0x00000030\n\tmww 0x020e05b0 0x00000030\n\tmww 0x020e0524 0x00000030\n\tmww 0x020e051c 0x00000030\n\tmww 0x020e0518 0x00000030\n\tmww 0x020e050c 0x00000030\n\tmww 0x020e05b8 0x00000030\n\tmww 0x020e05c0 0x00000030\n\tmww 0x020e05ac 0x00020030\n\tmww 0x020e05b4 0x00020030\n\tmww 0x020e0528 0x00020030\n\tmww 0x020e0520 0x00020030\n\tmww 0x020e0514 0x00020030\n\tmww 0x020e0510 0x00020030\n\tmww 0x020e05bc 0x00020030\n\tmww 0x020e05c4 0x00020030\n\tmww 0x020e056c 0x00020030\n\tmww 0x020e0578 0x00020030\n\tmww 0x020e0588 0x00020030\n\tmww 0x020e0594 0x00020030\n\tmww 0x020e057c 0x00020030\n\tmww 0x020e0590 0x00003000\n\tmww 0x020e0598 0x00003000\n\tmww 0x020e058c 0x00000000\n\tmww 0x020e059c 0x00003030\n\tmww 0x020e05a0 0x00003030\n\tmww 0x020e0784 0x00000030\n\tmww 0x020e0788 0x00000030\n\tmww 0x020e0794 0x00000030\n\tmww 0x020e079c 0x00000030\n\tmww 0x020e07a0 0x00000030\n\tmww 0x020e07a4 0x00000030\n\tmww 0x020e07a8 0x00000030\n\tmww 0x020e0748 0x00000030\n\tmww 0x020e074c 0x00000030\n\tmww 0x020e0750 0x00020000\n\tmww 0x020e0758 0x00000000\n\tmww 0x020e0774 0x00020000\n\tmww 0x020e078c 0x00000030\n\tmww 0x020e0798 0x000c0000\n\tmww 0x021b081c 0x33333333\n\tmww 0x021b0820 0x33333333\n\tmww 0x021b0824 0x33333333\n\tmww 0x021b0828 0x33333333\n\tmww 0x021b481c 0x33333333\n\tmww 0x021b4820 0x33333333\n\tmww 0x021b4824 0x33333333\n\tmww 0x021b4828 0x33333333\n\tmww 0x021b0018 0x00081740\n\tmww 0x021b001c 0x00008000\n\tmww 0x021b000c 0x555a7975\n\tmww 0x021b0010 0xff538e64\n\tmww 0x021b0014 0x01ff00db\n\tmww 0x021b002c 0x000026d2\n\tmww 0x021b0030 0x005b0e21\n\tmww 0x021b0008 0x09444040\n\tmww 0x021b0004 0x00025576\n\tmww 0x021b0040 0x00000027\n\tmww 0x021b0000 0x831a0000\n\tmww 0x021b001c 0x04088032\n\tmww 0x021b001c 0x0408803a\n\tmww 0x021b001c 0x00008033\n\tmww 0x021b001c 0x0000803b\n\tmww 0x021b001c 0x00428031\n\tmww 0x021b001c 0x00428039\n\tmww 0x021b001c 0x09408030\n\tmww 0x021b001c 0x09408038\n\tmww 0x021b001c 0x04008040\n\tmww 0x021b001c 0x04008048\n\tmww 0x021b0800 0xa1380003\n\tmww 0x021b4800 0xa1380003\n\tmww 0x021b0020 0x00005800\n\tmww 0x021b0818 0x00022227\n\tmww 0x021b4818 0x00022227\n\tmww 0x021b083c 0x434b0350\n\tmww 0x021b0840 0x034c0359\n\tmww 0x021b483c 0x434b0350\n\tmww 0x021b4840 0x03650348\n\tmww 0x021b0848 0x4436383b\n\tmww 0x021b4848 0x39393341\n\tmww 0x021b0850 0x35373933\n\tmww 0x021b4850 0x48254A36\n\tmww 0x021b080c 0x001f001f\n\tmww 0x021b0810 0x001f001f\n\tmww 0x021b480c 0x00440044\n\tmww 0x021b4810 0x00440044\n\tmww 0x021b08b8 0x00000800\n\tmww 0x021b48b8 0x00000800\n\tmww 0x021b001c 0x00000000\n\tmww 0x021b0404 0x00011006\n\tmww 0x020c4068 0x00c03f3f\n\tmww 0x020c406c 0x0030fc03\n\tmww 0x020c4070 0x0fffc000\n\tmww 0x020c4074 0x3ff00000\n\tmww 0x020c4078 0x00fff300\n\tmww 0x020c407c 0x0f0000c3\n\tmww 0x020c4080 0x000003ff\n\tmww 0x020e0010 0xf00000cf\n\tmww 0x020e0018 0x007f007f\n\tmww 0x020e001c 0x007f007f\n}\n\n# disable watchdog\nproc disable_wdog { } {\n\tmwh 0x020bc000 0x30\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc imx6q_sabresd_init { } {\n\tdisable_wdog\n\tapply_dcd\n}\n\n# prevent cortex-a code from asserting SRST again\n$_TARGETNAME.0 configure -event reset-assert { }\n# hook the init function into the reset-init event\n$_TARGETNAME.0 configure -event reset-init { imx6q_sabresd_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/gatemate_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# GateMateTM FPGA Evaluation Board\n# https://www.colognechip.com/programmable-logic/gatemate-evaluation-board/\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0014 0x011b\nreset_config none\ntransport select jtag\nadapter speed 6000\n\nsource [find fpga/gatemate.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/glyn_tonga2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Glyn Tonga2 SO-DIMM CPU module (Toshiba TMPA900CMXBG, ARM9)\n#\n# http://toshiba-mikrocontroller.de/sites/TMPA900CPUBOARDStarter.htm\n#\n# Hardware on the S0-DIMM module:\n#   - Toshiba TMPA900CMXBG (ARM9, ARM926EJ-S, max. 200MHz)\n#   - DDR SDRAM: Hynix H5MS5162DFR-J3M (64Mbyte, x16, 1.8V, 166/83MHz at CL3/2)\n#   - NAND flash: Samsung K9F2G08U0B-PIB0 (256M x 8 Bit, 3.3V)\n#   - Ethernet: SMSC LAN9221I-ABZJ (10/100Mbit, Non-PCI, 16 bit interface)\n#\n\nsource [find target/tmpa900.cfg]\n\n########################\n# Target configuration #\n########################\n\n# Initial JTAG speed should not exceed 1/6 of the initial CPU clock\n# frequency (24MHz). Be conservative and use 1/8 of the frequency.\n# (24MHz / 8 = 3MHz)\nadapter speed 3000\n\n$_TARGETNAME configure -event reset-start {\n\t# Upon reset, set the JTAG frequency to 3MHz again, see above.\n\techo \"Setting JTAG speed to 3MHz until clocks are initialized.\"\n\tadapter speed 3000\n\n\t# Halt the CPU.\n\thalt\n\n\t# Disable faster memory access for now.\n\tarm7_9 fast_memory_access disable\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# Setup clocks, and initialize SRAM and DDR SDRAM.\n\ttonga2_init\n\n\t# At this point the CPU is running at 192MHz, increase JTAG speed.\n\t# Tests showed that 15MHz works OK, higher speeds can cause problems,\n\t# though. Not sure if this is a CPU issue or JTAG adapter issue.\n\techo \"Increasing JTAG speed to 15MHz.\"\n\tadapter speed 15000\n\n\t# Enable faster memory access.\n\tarm7_9 fast_memory_access enable\n}\n\nproc tonga2_init { } {\n\t######################\n\t# PLL initialization #\n\t######################\n\n\t# Clock overview (see datasheet chapter 3.5.2, page 57):\n\t#   - fs: Low-frequency oscillator\n\t#   - fOSCH: High-frequency oscillator (24MHz on this board)\n\t#   - fPLL = fOSCH * multiplier (where multiplier can be 6 or 8)\n\t#   - fFCLK = fPLL / gear (where gear can be 1/2/4/8)\n\t#   - fHCLK is always fFCLK/2. fPCLK is also fFCLK/2.\n\t#\n\t# We select multiplier = 8 and gear = 1, so\n\t#   fFCLK = fOSCH * 8 / 1 = 192MHz.\n\n\t# SYSCR3 (System Control Register 3): Disable and configure PLL.\n\t#   - PLL operation control: off\n\t#   - PLL constant value setting 1: always 0, as per datasheet\n\t#   - PLL constant value setting 2: x8 (multiplier = 8)\n\tmww 0xf005000c 0x00000007\n\n\t# SYSCR4 (System Control Register 4): Configure PLL.\n\t#   - PLL constant value setting 3: 140MHz or more\n\t#   - PLL constant value setting 4: always 1, as per datasheet\n\t#   - PLL constant value setting 5: 140MHz or more\n\tmww 0xf0050010 0x00000065\n\n\t# SYSCR3 (System Control Register 3): Enable PLL.\n\t#   - PLL operation control: on\n\t#   - All other bits remain set as above.\n\tmww 0xf005000c 0x00000087\n\n\t# Wait for PLL to stabilize.\n\tsleep 10\n\n\t# SYSCR2 (System Control Register 2): Switch from fOSCH to fPLL.\n\t#   - Selection of the PLL output clock: fPLL\n\tmww 0xf0050008 0x00000002\n\n\t# SYSCR1 (System Control Register 1):\n\t#   - Clock gear programming: fc/1 (i.e., gear = 1, don't divide).\n\tmww 0xf0050004 0x00000000\n\n\t# CLKCR5 (Clock Control Register 5): Set bits 3 and 6. The datasheet\n\t# says the bits are reserved, but also recommends \"Write as one\".\n\tmww 0xf0050054 0x00000048\n\n\n\t##############################################################\n\t# Dynamic Memory Controller (DMC) / DDR SDRAM initialization #\n\t##############################################################\n\n\t# PMC (Power Management Controller):\n\t# PMCDRV (External Port \"Driverbility\" control register):\n\t# Bits DRV_MEM0/DRV_MEM1 (memory relation port drive power):\n\tmww 0xf0020260 0x00000003\t;# Select 1.8V +/- 0.1V\n\n\t# Setup DDR SDRAM timing parameters for our specific chip.\n\tmww 0xf4310014 0x00000004\t;# cas_latency = 2\n\tmww 0xf4310018 0x00000001\t;# t_dqss = 1\n\tmww 0xf431001c 0x00000002\t;# t_mrd = 2\n\tmww 0xf4310020 0x0000000a\t;# t_ras = 10\n\tmww 0xf4310024 0x0000000a\t;# t_rc = 10\n\tmww 0xf4310028 0x00000013\t;# t_rcd = 3, schedule_rcd = 2\n\tmww 0xf431002c 0x0000010a\t;# t_rfc = 10, schedule_rfc = 8\n\tmww 0xf4310030 0x00000013\t;# t_rp = 3, schedule_rp = 2\n\tmww 0xf4310034 0x00000002\t;# t_rrd = 2\n\tmww 0xf4310038 0x00000002\t;# t_wr = 2\n\tmww 0xf431003c 0x00000001\t;# t_wtr = 1\n\tmww 0xf4310040 0x0000000a\t;# t_xp = 10\n\tmww 0xf4310044 0x0000000c\t;# t_xsr = 12\n\tmww 0xf4310048 0x00000014\t;# t_esr = 20\n\n\t# dmc_memory_cfg_5 (DMC Memory Configuration register):\n\t# Set memory configuration:\n\t# column_bits = 10, row_bits = 13, ap-bit = 10, power_down_prd = 0,\n\t# auto_power_down = disable, stop_mem_clock = disable, memory_burst = 4\n\tmww 0xf431000c 0x00010012\n\n\t# dmc_user_config_5 (DMC user_config register):\n\t# Data bus width of DDR SDRAM: 16 bit\n\tmww 0xf4310304 0x00000058\n\n\t# dmc_refresh_prd_5 (DMC Refresh Period register):\n\t# Auto refresh: every 2656 (0xa60) DMCSCLK periods.\n\tmww 0xf4310010 0x00000a60\n\n\t# dmc_chip_0_cfg_5 (DMC chip_0_cfg registers):\n\t#   - SDRAM address structure: bank, row, column\n\t#   - address_match = 01000000 (start address [31:24])\n\t#   - address_mask  = 11111100 (start address [31:24] mask value)\n\tmww 0xf4310200 0x000140fc\n\n\t# Initialize the DDR SDRAM chip.\n\t# dmc_direct_cmd_5 (DMC Direct Command register).\n\t# See datasheet chapter 3.10.5.1, page 268.\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x00000000\t;# RAM init: Precharge all\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00040000\t;# RAM init: Autorefresh\n\tmww 0xf4310008 0x00080032\t;# RAM init: addr_13_to_0 = 0x32\n\tmww 0xf4310008 0x000c0000\t;# RAM init: NOP\n\tmww 0xf4310008 0x000a0000\t;# RAM init: bank_addr = bank 2\n\n\t# dmc_id_<0-5>_cfg_5 (DMC id_<0-5>_cfg registers):\n\t# Set min./max. QoS values.\n\t#   - 0x5: Enable QoS, max. QoS = 1\n\t#   - 0xb: Enable QoS, min. QoS = 2\n\tmww 0xf4310100 0x00000005\t;# AHB0: CPU Data\n\tmww 0xf4310104 0x00000005\t;# AHB1: CPU Inst\n\tmww 0xf4310108 0x0000000b\t;# AHB2: LCDC\n\tmww 0xf431010c 0x00000005\t;# AHB3: LCDDA, USB\n\tmww 0xf4310110 0x00000005\t;# AHB4: DMA1\n\tmww 0xf4310114 0x00000005\t;# AHB5: DMA2\n\n\t# dmc_memc_cmd_5 (DMC Memory Controller Command register):\n\t# Change DMC state to ready.\n\tmww 0xf4310004 0x00000000\t;# memc_cmd = \"Go\"\n\n\t# EBI: SMC Timeout register\n\tmww 0xf00a0050 0x00000001\t;# smc_timeout = 1\n\n\n\t########################################################\n\t# Static Memory Controller (SMC) / SRAM initialization #\n\t########################################################\n\n\t# smc_set_cycles_5 (SMC Set Cycles register):\n\t# tRC = 10, tWC = 10, tCEOE = 7, tWP = 5, tPC=2, tTR=2\n\tmww 0xf4311014 0x0004afaa\n\n\t# smc_set_opmode_5 (SMC Set Opmode register):\n\t# Memory data bus width = 16 bits, async read mode, read burst\n\t# length = 1 beat, async write mode, write burst length = 1 beat,\n\t# byte enable (SMCBE0-1) timing = SMCCSn timing, memory burst boundary\n\t# split setting = burst can cross any address boundary\n\tmww 0xf4311018 0x00000001\n\n\t# smc_direct_cmd_5 (SMC Direct Command register):\n\t# cmd_type = UpdateRegs, chip_select = CS1\n\tmww 0xf4311010 0x00c00000\n\n\techo \"Clocks, SRAM, and DDR SDRAM are now initialized.\"\n}\n\n#######################\n# Flash configuration #\n#######################\n\n# TODO: Implement NAND support.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/gowin_runber.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Gowin RUNBER FPGA Development Board\n# https://www.seeedstudio.com/Gowin-RUNBER-Development-Board-p-4779.html\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x008b\nreset_config none\ntransport select jtag\nadapter speed 6000\n\nsource [find fpga/gowin_gw1n.cfg]\n\n\n#openocd -f board/gowin_runber.cfg  -c \"init\" -c \"pld load 0 impl/pnr/gw1n_blinker.fs\"\n#ipdbg -start -tap gw1n.tap -hub 0x42 -port 5555 -tool 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/gti/espressobin.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# config for ESPRESSObin from\n# Globalscale Technologies Inc.\n\n# srst is isolated through missing resistor\nreset_config trst_only\n\nsource [find target/marvell/88f3720.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/gumstix-aerocore.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# JTAG for the STM32F4x chip used on the Gumstix AeroCore is available on\n# the first interface of a Quad FTDI chip.  nTRST is bit 4.\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\n\nftdi layout_init 0x0000 0x001b\nftdi layout_signal nTRST -data 0x0010\n\nsource [find target/stm32f4x.cfg]\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hammer.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target Configuration for the TinCanTools S3C2410 Based Hammer Module\n# http://www.tincantools.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\t# Reset Script for the TinCanTools S3C2410 Based Hammer Module\n\t# http://www.tincantools.com\n\t#\n\t# Setup primary clocks and initialize the SDRAM\n\tmww 0x53000000 0x00000000\n\tmww 0x4a000008 0xffffffff\n\tmww 0x4a00000c 0x000007ff\n\tmww 0x4c000000 0x00ffffff\n\tmww 0x4c000014 0x00000003\n\tmww 0x4c000004 0x000a1031\n\tmww 0x48000000 0x11111122\n\tmww 0x48000004 0x00000700\n\tmww 0x48000008 0x00000700\n\tmww 0x4800000c 0x00000700\n\tmww 0x48000010 0x00000700\n\tmww 0x48000014 0x00000700\n\tmww 0x48000018 0x00000700\n\tmww 0x4800001c 0x00018005\n\tmww 0x48000020 0x00018005\n\tmww 0x48000024 0x009c0459\n\tmww 0x48000028 0x000000b2\n\tmww 0x4800002c 0x00000030\n\tmww 0x48000030 0x00000030\n\tflash probe 0\n}\n\n\n#flash configuration\n#flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxdb500sys.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for paired K4S561632C (64MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C13261\n  mww 0x00100140 0x030D0121\n\n  puts \"Configuring SRAM nCS0 for 150ns paired Par. Flash (x32)\"\n  mww 0x00100100 0x0201000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x02000000 4 4 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxeb500hmi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads disable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC8M32 (32MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0111\n\n  puts \"Configuring SRAM nCS0 for 150ns Par. Flash (x16)\"\n  mww 0x00100100 0x0101000E\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxhx10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx10.cfg]\n\n# Usually it is not needed to set srst_pulls_trst\n# but sometimes it does not work without it. If you encounter\n# problems try to line below\n# reset_config trst_and_srst srst_pulls_trst\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x08000000 -work-area-phys 0x08000000 -work-area-size 0x4000 -work-area-backup 1\n\n# Par. Flash can only be accessed if DIP switch on the board is set in proper\n# position and init_sdrambus was called. Don't call these functions if the DIP\n# switch is in invalid position, as some outputs may collide. This is why this\n# function is not called automatically\nproc flash_init { } {\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x101C0100 0x01010008\n\n  flash probe 0\n}\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\nproc init_clocks { } {\n  puts \"Enabling all clocks \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n\n  mww  0x101c0028 0x00007511\n}\n\nproc init_sdrambus { } {\n  puts \"Initializing external SDRAM Bus 16 Bit \"\n  set accesskey [mread32 0x101c0070]\n  mww  0x101c0070 $accesskey\n  mww  0x101c0C40 0x00000050\n\n  puts \"Configuring SDRAM controller for K4S561632E (32MB) \"\n  mww 0x101C0140 0\n  sleep 100\n  #mww 0x101C0144 0x00a13262\n  mww 0x101C0144 0x00a13251\n  mww 0x101C0148 0x00000033\n  mww 0x101C0140 0x030d0121\n}\n\n$_TARGETNAME configure -event reset-init {\n  halt\n  wait_halt 1000\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  init_clocks\n#  init_sdrambus\n\n  puts \"\"\n  puts \"-------------------------------------------------\"\n  puts \"Call 'init_clocks' to enable all clocks\"\n  puts \"Call 'init_sdrambus' to enable external SDRAM bus\"\n  puts \"-------------------------------------------------\"\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\n#flash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxhx50.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx50.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x10000000 -work-area-phys 0x10000000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x1C000140 0\n  mww 0x1C000144 0x00A12151\n  mww 0x1C000140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x1C000100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxhx500.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sleep 100\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n  puts \"Configuring SRAM nCS0 for 90ns Par. Flash (x16)\"\n  mww 0x00100100 0x01010008\n\n  flash probe 0\n}\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> <driver> <base> <size> <chip width> <bus width> <target#>\nflash bank parflash cfi 0xC0000000 0x01000000 2 2 $_TARGETNAME\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hilscher_nxsb100.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\nsource [find target/hilscher_netx500.cfg]\n\nreset_config trst_and_srst\nadapter srst delay 500\njtag_ntrst_delay 500\n\n$_TARGETNAME configure -work-area-virt 0x1000 -work-area-phys 0x1000 -work-area-size 0x4000 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n  halt\n\n  arm7_9 fast_memory_access enable\n  arm7_9 dcc_downloads enable\n\n  sdram_fix\n\n  puts \"Configuring SDRAM controller for MT48LC2M32 (8MB) \"\n  mww 0x00100140 0\n  mww 0x00100144 0x03C23251\n  mww 0x00100140 0x030D0001\n\n}\n\ninit\nreset init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hitex_lpc1768stick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hitex LPC1768 Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/hitex_lpc1768stick.cfg]\n\nsource [find target/lpc17xx.cfg]\n\n\n# startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hitex_lpc2929.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hitex eval board for LPC2929/LPC2939\n# http://www.hitex.com/\n\n# Delays on reset lines\nadapter srst delay 50\njtag_ntrst_delay 1\n\n# Maximum of 1/8 of clock frequency (XTAL = 16 MHz).\n# Adaptive clocking through RTCK is not supported.\nadapter speed 2000\n\n# Target device: LPC29xx with ETB\n# The following variables are used by the LPC2900 script:\n#   HAS_ETB             Must be set to 1. The CPU on this board has ETB.\n#   FLASH_CLOCK         CPU frequency at the time of flash programming (in kHz)\nset HAS_ETB             1\nset FLASH_CLOCK         112000\nsource [find target/lpc2900.cfg]\n\n# A working area will help speeding the flash programming\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000 -work-area-backup 0\n$_TARGETNAME configure -work-area-phys 0x58000000 -work-area-size 0x10000 -work-area-backup 0\n\n# Event handlers\n$_TARGETNAME configure -event reset-start {\n  # Back to the slow JTAG clock\n  adapter speed 2000\n}\n\n# External 16-bit flash at chip select CS7 (SST39VF3201-70, 4 MiB)\nset _FLASHNAME $_CHIPNAME.extflash\nflash bank $_FLASHNAME cfi 0x5C000000 0x400000 2 2 $_TARGETNAME jedec_probe\n\n\n$_TARGETNAME configure -event reset-init {\n  # Flash\n  mww 0x20200010 0x00000007     ;# FBWST: 7 wait states, not cached\n\n  # Use PLL\n  mww 0xFFFF8020 0x00000001     ;# XTAL_OSC_CONTROL: enable, 1-20 MHz\n  mww 0xFFFF8070 0x01000000     ;# SYS_CLK_CONF: Crystal\n  mww 0xFFFF8028 0x00000005     ;# PLL: (power down)\n  mww 0xFFFF8028 0x01060004     ;# PLL: M=7, 2P=2 (power up)\n                                 # --> f=112 MHz, fcco=224 MHz\n  sleep 100\n  mww 0xFFFF8070 0x02000000     ;# SYS_CLK_CONF: PLL\n\n  # Increase JTAG speed\n  adapter speed 6000\n\n  # Enable external memory bus (16-bit SRAM at CS6, 16-bit flash at CS7)\n  mww 0xE0001138 0x0000001F     ;# P1.14 = D0\n  mww 0xE000113C 0x0000001F     ;# P1.15 = D1\n  mww 0xE0001140 0x0000001F     ;# P1.16 = D2\n  mww 0xE0001144 0x0000001F     ;# P1.17 = D3\n  mww 0xE0001148 0x0000001F     ;# P1.18 = D4\n  mww 0xE000114C 0x0000001F     ;# P1.19 = D5\n  mww 0xE0001150 0x0000001F     ;# P1.20 = D6\n  mww 0xE0001154 0x0000001F     ;# P1.21 = D7\n  mww 0xE0001200 0x0000001F     ;# P2.0  = D8\n  mww 0xE0001204 0x0000001F     ;# P2.1  = D9\n  mww 0xE0001208 0x0000001F     ;# P2.2  = D10\n  mww 0xE000120C 0x0000001F     ;# P2.3  = D11\n  mww 0xE0001210 0x0000001F     ;# P2.4  = D12\n  mww 0xE0001214 0x0000001F     ;# P2.5  = D13\n  mww 0xE0001218 0x0000001F     ;# P2.6  = D14\n  mww 0xE000121C 0x0000001F     ;# P2.7  = D15\n  mww 0xE0001104 0x00000007     ;# P1.1  = A1\n  mww 0xE0001108 0x00000007     ;# P1.2  = A2\n  mww 0xE000110C 0x00000007     ;# P1.3  = A3\n  mww 0xE0001110 0x00000007     ;# P1.4  = A4\n  mww 0xE0001114 0x00000007     ;# P1.5  = A5\n  mww 0xE0001118 0x00000007     ;# P1.6  = A6\n  mww 0xE000111C 0x00000007     ;# P1.7  = A7\n  mww 0xE0001028 0x00000007     ;# P0.10 = A8\n  mww 0xE000102C 0x00000007     ;# P0.11 = A9\n  mww 0xE0001030 0x00000007     ;# P0.12 = A10\n  mww 0xE0001034 0x00000007     ;# P0.13 = A11\n  mww 0xE0001038 0x00000007     ;# P0.14 = A12\n  mww 0xE000103C 0x00000007     ;# P0.15 = A13\n  mww 0xE0001048 0x00000007     ;# P0.18 = A14\n  mww 0xE000104C 0x00000007     ;# P0.19 = A15\n  mww 0xE0001050 0x00000007     ;# P0.20 = A16\n  mww 0xE0001054 0x00000007     ;# P0.21 = A17\n  mww 0xE0001058 0x00000007     ;# P0.22 = A18\n  mww 0xE000105C 0x00000007     ;# P0.23 = A19\n  mww 0xE0001238 0x00000007     ;# P2.14 = BLS0\n  mww 0xE000123C 0x00000007     ;# P2.15 = BLS1\n  mww 0xE0001300 0x00000007     ;# P3.0  = CS6\n  mww 0xE0001304 0x00000007     ;# P3.1  = CS7\n  mww 0xE0001130 0x00000007     ;# P1.12 = OE_N\n  mww 0xE0001134 0x00000007     ;# P1.13 = WE_N\n  mww 0x600000BC 0x00000041     ;# Bank6 16-bit mode, RBLE=1\n  mww 0x600000B4 0x00000000     ;# Bank6 WSTOEN=0\n  mww 0x600000AC 0x00000005     ;# Bank6 WST1=5\n  mww 0x600000B8 0x00000001     ;# Bank6 WSTWEN=1\n  mww 0x600000B0 0x00000006     ;# Bank6 WST2=6\n  mww 0x600000A8 0x00000002     ;# Bank6 IDCY=2\n  mww 0x600000D8 0x00000041     ;# Bank7 16-bit mode, RBLE=1\n  mww 0x600000D0 0x00000000     ;# Bank7 WSTOEN=0\n  mww 0x600000C8 0x0000000A     ;# Bank7 WST1=10\n  mww 0x600000D4 0x00000001     ;# Bank7 WSTWEN=1\n  mww 0x600000CC 0x0000000C     ;# Bank7 WST2=8\n  mww 0x600000C4 0x00000002     ;# Bank7 IDCY=2\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hitex_stm32-performancestick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hitex stm32 performance stick\n\nreset_config trst_and_srst\n\nsource [find interface/ftdi/stm32-stick.cfg]\n\nset  CHIPNAME stm32_hitex\nsource [find target/stm32f1x.cfg]\n\n# configure str750 connected to jtag chain\n# FIXME -- source [find target/str750.cfg] after cleaning that up\njtag newtap str750 cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id 0x4f1f0041\n\n# for some reason this board like to startup @ 500kHz\nadapter speed 500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/hitex_str9-comstick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hitex STR9-comStick\n# http://www.hitex.com/index.php?id=383\n# This works for the STR9-comStick revisions STR912CS-A1 and STR912CS-A2.\n\nsource [find interface/ftdi/hitex_str9-comstick.cfg]\n\n# set jtag speed\nadapter speed 3000\n\nadapter srst delay 100\njtag_ntrst_delay 100\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\n#\n# FIXME use the standard str912 target config; that script might need\n# updating to \"-ignore-version\" for the boundary scan TAP\n#\n#\tsource [find target/str912.cfg]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # Found on STR9-comStick, revision STR912CS-A1\n   set _BSTAPID1 0x1457f041\n   # Found on STR9-comStick, revision STR912CS-A2\n   set _BSTAPID2 0x2457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID1 -expected-id $_BSTAPID2\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/iar_lpc1768.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Board from IAR KickStart Kit for LPC1768\n# See www.iar.com and also\n# http://www.olimex.com/dev/lpc-1766stk.html\n#\n\nsource [find target/lpc17xx.cfg]\n\n# The chip has just been reset.\n#\n$_TARGETNAME configure -event reset-init {\n\t# FIXME update the core clock to run at 100 MHz;\n\t# and update JTAG clocking similarly; then\n\t# make CCLK match,\n\n\tflash probe 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/iar_str912_sk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The IAR str912-sk evaluation kick start board has an str912\n\nsource [find target/str912.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/icnova_imx53_sodimm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#################################################################################################\n# Author: Benjamin Tietz <benjamin.tietz@in-circuit.de>                                        ;#\n# based on work from: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com>   ;#\n# Kiwigrid GmbH                                                                                ;#\n# Generated for In-Circuit i.MX53 SO-Dimm                                                      ;#\n#################################################################################################\n\n# The In-Circuit ICnova IMX53SODIMM board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"i.MX53 SO-Dimm board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { sodimm_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc sodimm_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n#*========================================================================================== ======\n# Initialization script for 32 bit DDR3 (CS0+CS1)\n#*========================================================================================== ======\n# Remux D24/D25 to perform Flash-access\n\tmww 0x53fa818C 0x00000000 ; #EIM_RW\n\tmww 0x53fa8180 0x00000000 ; #EIM_CS0\n\tmww 0x53fa8188 0x00000000 ; #EIM_OE\n\tmww 0x53fa817C 0x00000000 ; #A16\n\tmww 0x53fa8178 0x00000000 ; #A17\n\tmww 0x53fa8174 0x00000000 ; #A18\n\tmww 0x53fa8170 0x00000000 ; #A19\n\tmww 0x53fa816C 0x00000000 ; #A20\n\tmww 0x53fa8168 0x00000000 ; #A21\n\tmww 0x53fa819C 0x00000000 ; #DA0\n\tmww 0x53fa81A0 0x00000000 ; #DA1\n\tmww 0x53fa81A4 0x00000000 ; #DA2\n\tmww 0x53fa81A8 0x00000000 ; #DA3\n\tmww 0x53fa81AC 0x00000000 ; #DA4\n\tmww 0x53fa81B0 0x00000000 ; #DA5\n\tmww 0x53fa81B4 0x00000000 ; #DA6\n\tmww 0x53fa81B8 0x00000000 ; #DA7\n\tmww 0x53fa81BC 0x00000000 ; #DA8\n\tmww 0x53fa81C0 0x00000000 ; #DA9\n\tmww 0x53fa81C4 0x00000000 ; #DA10\n\tmww 0x53fa81C8 0x00000000 ; #DA11\n\tmww 0x53fa81CC 0x00000000 ; #DA12\n\tmww 0x53fa81D0 0x00000000 ; #DA13\n\tmww 0x53fa81D4 0x00000000 ; #DA14\n\tmww 0x53fa81D8 0x00000000 ; #DA15\n\tmww 0x53fa8118 0x00000000 ; #D16\n\tmww 0x53fa811C 0x00000000 ; #D17\n\tmww 0x53fa8120 0x00000000 ; #D18\n\tmww 0x53fa8124 0x00000000 ; #D19\n\tmww 0x53fa8128 0x00000000 ; #D20\n\tmww 0x53fa812C 0x00000000 ; #D21\n\tmww 0x53fa8130 0x00000000 ; #D22\n\tmww 0x53fa8134 0x00000000 ; #D23\n\tmww 0x53fa813c 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D24\n\tmww 0x53fa8140 0x00000000 ; #IOMUXC_SW_PAD_CTL_PAD_EIM_D25\n\tmww 0x53fa8144 0x00000000 ; #D26\n\tmww 0x53fa8148 0x00000000 ; #D27\n\tmww 0x53fa814C 0x00000000 ; #D28\n\tmww 0x53fa8150 0x00000000 ; #D29\n\tmww 0x53fa8154 0x00000000 ; #D30\n\tmww 0x53fa8158 0x00000000 ; #D31\n\n# DDR3 IOMUX configuration\n#* Global pad control options */\n\tmww 0x53fa8554 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53fa8558 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53fa8560 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53fa8564 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n\tmww 0x53fa8568 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53fa8570 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa8574 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53fa8578 0x00200000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 - boazp: weaker sdclk EVK DDR max frequency\n\tmww 0x53fa857c 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53fa8580 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53fa8584 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53fa8588 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53fa8590 0x00380040 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53fa8594 0x00380000 ; #IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53fa86f0 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53fa86f4 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53fa86fc 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8714 0x00000200 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8714 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode XXX\n\tmww 0x53fa8718 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53fa871c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53fa8720 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53fa8724 0x00000000 ; #IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=0 XXX\n\tmww 0x53fa8728 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53fa872c 0x00380000 ; #IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa86f4 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL for sDQS[3:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa8714 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRMODE for D[31:0], 1=DDR2, 0=CMOS mode\n#\tmww 0x53fa86fc 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n#\tmww 0x53fa8724 0x00000000 ;IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL=00\n\n#* Data bus byte lane pad drive strength control options */\n#\tmww 0x53fa872c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B3DS\n#\tmww 0x53fa8554 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n#\tmww 0x53fa8558 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n#\tmww 0x53fa8728 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B2DS\n#\tmww 0x53fa8560 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n#\tmww 0x53fa8568 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n#\tmww 0x53fa871c 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B1DS\n#\tmww 0x53fa8594 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n#\tmww 0x53fa8590 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n#\tmww 0x53fa8718 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_B0DS\n#\tmww 0x53fa8584 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n#\tmww 0x53fa857c 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\n#* SDCLK pad drive strength control options */\n#\tmww 0x53fa8578 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n#\tmww 0x53fa8570 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\n#* Control and addr bus pad drive strength control options */\n#\tmww 0x53fa8574 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n#\tmww 0x53fa8588 0x00300000 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n#\tmww 0x53fa86f0 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_ADDDS for DDR addr bus\n#\tmww 0x53fa8720 0x00300000 ;IOMUXC_SW_PAD_CTL_GRP_CTLDS for CSD0, CSD1, SDCKE0, SDCKE1, SDWE\n\n#\tmww 0x53fa8564 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1\n#\tmww 0x53fa8580 0x00300040 ;IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\n# Initialize DDR3 memory - Micron MT41J128M16-187Er\n#** Keep for now, same setting as CPU3 board **#\n\tmww 0x63fd901c 0x00008000\n#\tmww 0x63fd904c 0x01680172 ; #write leveling reg 0\n#\tmww 0x63fd9050 0x0021017f ; #write leveling reg 1\n\tmww 0x63fd9088 0x32383535 ; #read delay lines\n\tmww 0x63fd9090 0x40383538 ; #write delay lines\n#\tmww 0x63fd90F8 0x00000800 ; #Measure unit\n\tmww 0x63fd907c 0x0136014d ; #DQS gating 0\n\tmww 0x63fd9080 0x01510141 ; #DQS gating 1\n#* CPU3 Board settingr\n# Enable bank interleaving, Address mirror on, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n#\tmww 0x63fd9018 0x00091740 ; #Misc register:\n#* Quick Silver board setting\n# Enable bank interleaving, Address mirror off, WALAT 0x1, RALAT = 0x5, DDR2_EN = 0\n\tmww 0x63fd9018 0x00011740 ; #Misc register\n\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n#\tmww 0x63fd9000 0xc3190000 ; #Main control register\n# Enable CSD0 and CSD1, row width = 14, column width = 10, burst length = 8, data width = 32bit\n\tmww 0x63fd9000 0x83190000 ; #Main control register\n# tRFC=64ck;tXS=68;tXP=3;tXPDLL=10;tFAW=15;CAS=6ck\n\tmww 0x63fd900C 0x555952E3 ; #timing configuration Reg 0\n# tRCD=6;tRP=6;tRC=21;tRAS=15;tRPA=1;tWR=6;tMRD=4;tCWL=5ck\n\tmww 0x63fd9010 0xb68e8b63 ; #timing configuration Reg 1\n# tDLLK(tXSRD)=512 cycles; tRTP=4;tWTR=4;tRRD=4\n\tmww 0x63fd9014 0x01ff00db ; #timing configuration Reg 2\n\tmww 0x63fd902c 0x000026d2 ; #command delay (default)\n\tmww 0x63fd9030 0x009f0e21 ; #out of reset delays\n# Keep tAOFPD, tAONPD, tANPD, and tAXPD as default since they are bigger than calc values\n\tmww 0x63fd9008 0x12273030 ; #ODT timings\n# tCKE=3; tCKSRX=5; tCKSRE=5\n\tmww 0x63fd9004 0x0002002d\n#Power down control\n#**********************************\n#DDR device configuration:\n#**********************************\n#**********************************\n# CS0:\n#**********************************\n\tmww 0x63fd901c 0x00008032 ; #write mode reg MR2 with cs0 (see below for settings)\n# Full array self refresh\n# Rtt_WR disabled (no ODT at IO CMOS operation)\n# Manual self refresh\n# CWS=5\n\tmww 0x63fd901c 0x00008033 ; #write mode reg MR3 with cs0.\n\tmww 0x63fd901c 0x00028031 ; #write mode reg MR1 with cs0. ODS=01: out buff= RZQ/7 (see below for settings)\n# out impedance = RZQ/7\n# Rtt_nom disabled (no ODT at IO CMOS operation)\n# Aditive latency off\n# write leveling disabled\n# tdqs (differential?) disabled\n\n\tmww 0x63fd901c 0x09208030 ; #write mode reg MR0 with cs0 , with dll_rst0\n\tmww 0x63fd901c 0x04008040 ; #ZQ calibration with cs0 (A10 high indicates ZQ cal long ZQCL)\n#**********************************\n# CS1:\n#**********************************\n#\tmww 0x63fd901c 0x0000803a ; #write mode reg MR2 with cs1.\n#\tmww 0x63fd901c 0x0000803b ; #write mode reg MR3 with cs1.\n#\tmww 0x63fd901c 0x00028039 ; #write mode reg MR1 with cs1. ODS=01: out buff= RZQ/7\n#\tmww 0x63fd901c 0x09208138 ; #write mode reg MR0 with cs1.\n#\tmww 0x63fd901c 0x04008048 ; #ZQ calibration with cs1(A10 high indicates ZQ cal long ZQCL)\n#**********************************\n\n\n\tmww 0x63fd9020 0x00001800 ; # Refresh control register\n\tmww 0x63fd9040 0x04b80003 ; # ZQ HW control\n\tmww 0x63fd9058 0x00022227 ; # ODT control register\n\n\tmww 0x63fd901c 0x00000000\n\n# CLKO muxing (comment out for now till needed to avoid conflicts with intended usage of signals)\n#\tmww 0x53FA8314 = 0\n#\tmww 0x53FA8320 0x4\n#\tmww 0x53FD4060 0x01e900f0\n\n#\tdap apsel 0\n}\n\n# IRAM\n$_TARGETNAME configure -work-area-phys 0xF8000000 -work-area-size 0x20000 -work-area-backup 1\n\nflash bank mx535_nor cfi 0xf0000000 0x800000 2 2 $_TARGETNAME\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/icnova_sam9g45_sodimm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#################################################################################################\n#\t\t\t\t\t\t\t\t\t\t\t\t                                                #\n# Author: Lars Poeschel (larsi@wh2.tu-dresden.de)\t\t\t\t\t\t\t\t\t\t\t\t#\n# Generated for In-Circuit ICnova SAM9G45 SODIMM\t\t\t\t\t\t\t\t\t\t\t\t#\n# http://www.ic-board.de/product_info.php?info=p214_ICnova-SAM9G45-SODIMM.html|ICnova\t\t\t#\n#\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t#\n#################################################################################################\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nsource [find target/at91sam9g45.cfg]\n\n# Set reset type.\n# reset_config trst_and_srst\n\n# adapter srst delay 200\n# jtag_ntrst_delay 200\n\n\n# If you don't want to execute built-in boot rom code (and there are good reasons at times not to do that) in the\n# AT91SAM9 family, the microcontroller is a lump on a log without initialization.  Because this family has\n# some powerful features, we want to have a special function that handles \"reset init\".  To do this we declare\n# an event handler where these special activities can take place.\n\nscan_chain\n$_TARGETNAME configure -event reset-init {at91sam9g45_init}\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n# Slow-speed oscillator enabled at reset, so run jtag speed slow.\n$_TARGETNAME configure -event reset-start {at91sam9g45_start}\n\n\n# NandFlash configuration and definition\n# Future TBD\n# Flash configuration\n# flash bank cfi <base> <size> <chip width> <bus width> <target#>\nset _FLASHNAME $_CHIPNAME.flash\n# set _NANDNAME $_CHIPNAME.nand\nflash bank $_FLASHNAME cfi 0x10000000 0x00800000 2 2 $_TARGETNAME\n# nand device $_NANDNAME at91sam9 $_TARGETNAME 0x40000000 0xFFFFE800\n\n\nproc read_register {register} {\n\treturn [read_memory $register 32 1]\n}\n\nproc at91sam9g45_start { } {\n\n\t# Make sure that the the jtag is running slow, since there are a number of different ways the board\n\t# can be configured coming into this state that can cause communication problems with the jtag\n\t# adapter.  Also since this call can be made following a \"reset init\" where fast memory accesses\n\t# are enabled, need to temporarily shut this down so that the RSTC_MR register can be written at slower\n\t# jtag speed without causing GDB keep alive problem.\n\n\tarm7_9 fast_memory_access disable\n    # Slow-speed oscillator enabled at reset, so run jtag speed slow.\n\tadapter speed 4\n    # Make sure processor is halted, or error will result in following steps.\n\thalt\n\twait_halt 10000\n    # RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n}\n\n\nproc at91sam9g45_init { } {\n\n\t# At reset AT91SAM9G45 chip runs on slow clock (32.768 kHz).  To shift over to a normal clock requires\n\t# a number of steps that must be carefully performed.  The process outline below follows the\n\t# recommended procedure outlined in the AT91SAM9G45 technical manual.\n\t#\n\t# Several key and very important things to keep in mind:\n\t# The SDRAM parts used currently on the board are -75 grade parts.  This\n\t# means the master clock (MCLK) must be at or below 133 MHz or timing errors will occur.  The processor\n\t# core can operate up to 400 MHz and therefore PCLK must be at or below this to function properly.\n\n\t# Make sure processor is halted, or error will result in following steps.\n\thalt\n\t# RSTC_MR : enable user reset.\n\tmww 0xfffffd08 0xa5000501\n\t# WDT_MR : disable watchdog.\n\tmww 0xfffffd44 0x00008000\n\n\t# Enable the main 15.000 MHz oscillator in CKGR_MOR register.\n\t# Wait for MOSCS in PMC_SR to assert indicating oscillator is again stable after change to CKGR_MOR.\n\n\tmww 0xfffffc20 0x00004001\n\twhile { [expr {[read_register 0xfffffc68] & 0x01}] != 1 } { sleep 1 }\n\n\t# Set PLLA Register for 792.576 MHz (divider: bypass, multiplier: 43).\n\t# Wait for LOCKA signal in PMC_SR to assert indicating PLLA is stable.\n\n\t#mww 0xfffffc28 0x202a3f01\n\tmww 0xfffffc28 0x20c73f03\n\twhile { [expr {[read_register 0xfffffc68] & 0x02}] != 2 } { sleep 1 }\n\n\t# Set master system clock prescaler divide by 6 and processor clock divide by 2 in PMC_MCKR.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\t#mww 0xfffffc30 0x00000101\n\tmww 0xfffffc30 0x00001301\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Now change PMC_MCKR register to select PLLA.\n\t# Wait for MCKRDY signal from PMC_SR to assert.\n\n\tmww 0xfffffc30 0x00001302\n\twhile { [expr {[read_register 0xfffffc68] & 0x08}] != 8 } { sleep 1 }\n\n\t# Processor and master clocks are now operating and stable at maximum frequency possible:\n\t#\t-> MCLK = 132.096 MHz\n\t#\t-> PCLK = 396.288 MHz\n\n\t# Switch over to adaptive clocking.\n\n\tadapter speed 6000\n\n\t# Enable faster DCC downloads.\n\n\tarm7_9 dcc_downloads enable\n\n\t# To be able to use external SDRAM, several peripheral configuration registers must\n\t# be modified.  The first change is made to PIO_ASR to select peripheral functions\n\t# for D15 through D31.  The second change is made to the PIO_PDR register to disable\n\t# this for D15 through D31.\n\n#\tmww 0xfffff870 0xffff0000\n#\tmww 0xfffff804 0xffff0000\n\n\t# The EBI chip select register EBI_CS must be specifically configured to enable the internal SDRAM controller\n\t# using CS1.  Additionally we want CS3 assigned to NandFlash.  Also VDDIO is connected physically on\n\t# the board to the 3.3 VDC power supply so set the appropriate register bit to notify the micrcontroller.\n\n\t# mww 0xffffef1c 0x000100a\n\n\t# The ICnova SAM9G45 SODIMM has built-in NandFlash.  The exact physical timing characteristics\n\t# for the memory type used on the current board (MT29F2G08AACWP) can be established by setting\n\t# four registers in order:  SMC_SETUP3, SMC_PULSE3, SMC_CYCLE3, and SMC_MODE3.\n\n\t# mww 0xffffec30 0x00020002\n\t# mww 0xffffec34 0x04040404\n\t# mww 0xffffec38 0x00070007\n\t# mww 0xffffec3c 0x00030003\n\n\t# Identify NandFlash bank 0.  Disabled at the moment because a memory driver is not yet complete.\n\n#\tnand probe 0\n\n    # SMC_SETUP0 : Setup SMC for NOR Flash\n\tmww 0xffffe800 0x0012000a\n    # SMC_PULSE0\n\tmww 0xffffe804 0x3b38343b\n    # SMC_CYCLE0\n\tmww 0xffffe808 0x003f003f\n    # SMC_MODE0\n\tmww 0xffffe80c 0x00001000\n    # Identify flash bank 0\n\tflash probe 0\n\n\t# Now setup SDRAM.  This is tricky and configuration is very important for reliability!  The current calculations\n\t# are based on 2 x Samsung K4T51083QG memory.\n\n\t# 0. Enable DDR2 Clock\n\tmww 0xfffffc00 0x4\n\t# 1. Program memory device type\n\t# 1.1 configure the DDR controller\n\tmww 0xffffe620 0x16\n\t# 1.2 program the DDR controller\n\tmww 0xffffe608 0x3d\n\n\t# 2. program memory device features\n\t# 2.1 assume timings for 7.5ns min clock period\n\tmww 0xffffe60c 0x21128226\n\t# 2.2 pSDDRC->HDDRSDRC2_T1PR\n\tmww 0xffffe610 0x02c8100e\n\t# 2.3 pSDDRC->HDDRSDRC2_T2PR\n\tmww 0xffffe614 0x01000702\n\t# 3. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 3.1 delay 200us\n\tsleep 1\n\t# jim tcl alternative: after ms\n\t# after 0.2\n\n\t# 4. NOP\n\tmww 0xffffe600 0x1\n\tmww 0x70000000 0x1\n\t# 4.1 delay 400ns\n\n\t# 5. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 5.1 delay 400ns\n\n\t# 6. set EMR operation (EMRS2)\n\tmww 0xffffe600 0x5\n\tmww 0x74000000 0x1\n\t# 6.1 delay 2 cycles\n\n\t# 7. set EMR operation (EMRS3)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 7.1 delay 2 cycles\n\n\t# 8. set EMR operation (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 8.1 delay 200 cycles (400Mhz -> 5 * 10^-7s)\n\tsleep 1\n\n\t# 9. Enable DLL Reset (set DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] | 0x80}]\n\tmww 0xffffe608 $CR\n\n\t# 10. mode register cycle to reset the DLL\n\tmww 0xffffe600 0x5\n\tmww 0x70000000 0x1\n\t# 10.1 delay 2 cycles\n\n\t# 11. set all bank precharge\n\tmww 0xffffe600 0x2\n\tmww 0x70000000 0x1\n\t# 11.1 delay 400 ns\n\n\t# 12. two auto-refresh (CBR) cycles are provided.\n\tmww 0xffffe600 0x4\n\tmww 0x70000000 0x1\n\t# 12.1 delay 10 cycles\n\t# 12.2 2nd cycle (schreiben des Mode Register sparen wir uns)\n\tmww 0x70000000 0x1\n\t# 12.3 delay 10 cycles\n\n\t# 13. disable DLL reset (clear DLL bit)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffffff7f}]\n\tmww 0xffffe608 $CR\n\n\t# 14. mode register set cycle\n\tmww 0xffffe600 0x3\n\tmww 0x70000000 0x1\n\n\t# 15. program OCD field (set OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] | 0x7000}]\n\tmww 0xffffe608 $CR\n\n\t# 16. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x72000000 0x1\n\t# 16.1 delay 2 cycles\n\n\t# 17. disable OCD field (clear OCD bits)\n\tset CR  [expr {[read_register 0xffffe608] & 0xffff8fff}]\n\tmww 0xffffe608 $CR\n\n\t# 18. (EMRS1)\n\tmww 0xffffe600 0x5\n\tmww 0x76000000 0x1\n\t# 18.1 delay 2 cycles\n\n\t# 19. normal mode command\n\tmww 0xffffe600 0x0\n\tmww 0x70000000 0x1\n\n\t# 20. perform write to any address\n\t#mww 0x70000000 0x1\n\n\t# 21. write refresh rate into the count field of the refresh rate register\n\tmww 0xffffe604 0x24b\n\t# 21.1 delay (500 * 6 cycles)\n\n\tarm7_9 fast_memory_access enable\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx27ads.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The IMX27 ADS eval board has a single IMX27 chip\n# Note: tested on IMX27ADS Board REV-2.6 and REV-2.8\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27ads_init }\n\n# The IMX27 ADS board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\nproc imx27ads_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\t# ========================================\n\t#  Configure PSRAM on CS5\n\t# ========================================\n\tmww 0xd8002050 0x0000dcf6\n\tmww 0xd8002054 0x444a4541\n\tmww 0xd8002058 0x44443302\n\n\t#  ========================================\n\t#         Configure16 bit NorFlash on CS0\n\t#  ========================================\n\tmww 0xd8002000 0x0000CC03\n\tmww 0xd8002004 0xa0330D01\n\tmww 0xd8002008 0x00220800\n\n\t# ========================================\n\t#  Configure CPLD on CS4\n\t# ========================================\n\tmww 0xd8002040 0x0000DCF6\n\tmww 0xd8002044 0x444A4541\n\tmww 0xd8002048 0x44443302\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\tmww 0xD8001000 0x92200000\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xA2200000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\tmww 0xD8001000 0xB2200000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\tmww 0xD8001000 0x82228085\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx27lnst.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Linuxstamp-mx27 is board has a single IMX27 chip\n# For further info see http://opencircuits.com/Linuxstamp_mx27#OpenOCD\nsource [find target/imx27.cfg]\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { imx27lnst_init }\n\nproc imx27lnst_init { } {\n\t# This setup puts RAM at 0xA0000000\n\n\t# reset the board correctly\n\tadapter speed 500\n\treset run\n\treset halt\n\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- initial reset\n\t# ========================================\n\tmww 0xD8001010 0x00000008\n\n\tsleep 100\n\n\t# ========================================\n\t#  Configure DDR on CSD0 -- wait 5000 cycle\n\t# ========================================\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\tmww 0xD8001010 0x00000004\n\n\tmww 0xD8001004 0x00795729\n\n\t#mww 0xD8001000 0x92200000\n\tmww 0xD8001000 0x91120000\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xA2200000\n\tmww 0xD8001000 0xA1120000\n\tmww 0xA0000F00 0x0\n\tmww 0xA0000F00 0x0\n\n\t#mww 0xD8001000 0xB2200000\n\tmww 0xD8001000 0xB1120000\n\tmwb 0xA0000033 0xFF\n\tmwb 0xA1000000 0xAA\n\n\t#mww 0xD8001000 0x82228085\n\tmww 0xD8001000 0x81128080\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx28evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The IMX28EVK eval board has a IMX28 chip\n# Tested on SCH-26241 Rev D board with Olimex ARM-USB-OCD\n# Date:\t201-02-01\n# Authors: James Robinson & Fabio Estevam\n\nsource [find target/imx28.cfg]\n$_TARGETNAME configure -event gdb-attach { imx28evk_init }\n$_TARGETNAME configure -event reset-init { imx28evk_init }\n\nproc imx28evk_init { } {\n\n\thalt\n\n\t#****************************\n\t# VDDD setting\n\t#****************************\n\t# set VDDD =1.55V =(0.8v + TRIG x 0.025v), TRIG=0x1e\n\tmww 0x80044010 0x0003F503\n\tmww 0x80044040 0x0002041E\n\n\t#****************************\n\t# CLOCK set up\n\t#****************************\n\t# Power up PLL0 HW_CLKCTRL_PLL0CTRL0\n\tmww 0x80040000 0x00020000\n\t# Set up fractional dividers for CPU and EMI - HW_CLKCTRL_FRAC0\n\t# EMI - first set DIV_EMI to div-by-2 before programming frac divider\n\tmww 0x800400F0 0x80000002\n\n\n\t# CPU: CPUFRAC=19 480*18/29=454.7MHz, EMI: EMIFRAC=22, (480/2)*18/22=196.4MHz\n\tmww 0x800401B0 0x92921613\n\t# Clear the bypass bits for CPU and EMI clocks in HW_CLKCTRL_CLKSEQ_CLR\n\tmww 0x800401D8 0x00040080\n\t# HCLK = 227MHz,HW_CLKCTRL_HBUS DIV =0x2\n\tmww 0x80040060 0x00000002\n\n\t#****************************\n\t# POWER up DCDD_VDDA (DDR2)\n\t#****************************\n\t# Now set the voltage level to 1.8V HW_POWER_VDDACTRL bits TRC=0xC\n\tmww 0x80044050 0x0000270C\n\n\t#****************************\n\t# DDR2 DCDD_VDDA\n\t#****************************\n\t# First set up pin muxing and drive strength\n\t# Ungate module clock and bring out of reset HW_PINCTRL_CTRL_CLR\n\tmww 0x80018008 0xC0000000\n\n\t#****************************\n\t# EMI PAD setting\n\t#****************************\n\t# Set up drive strength for EMI pins\n\tmww 0x80019B80 0x00030000\n\t#IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\n\t# Set up pin muxing for EMI, HW_PINCTRL_MUXSEL10, 11, 12, 13\n\tmww 0x800181A8 0xFFFFFFFF\n\tmww 0x800181B8 0xFFFFFFFF\n\tmww 0x800181C8 0xFFFFFFFF\n\tmww 0x800181D8 0xFFFFFFFF\n\n\t#** Ungate EMI clock in CCM\n\tmww 0x800400F0 0x00000002\n\n\t#============================================================================\n\t# DDR Controller Registers\n\t#============================================================================\n\t# Manufacturer:    Elpida\n\t# Device Part Number:    EDE1116AEBG\n\t# Clock Freq.:     200MHz\n\t# Density:         1Gb\n\t# Chip Selects:    1\n\t# Number of Banks: 8\n\t# Row address:     13\n\t# Column address:  10\n\t#============================================================================\n\tmww 0x800E0000 0x00000000\n\tmww 0x800E0040 0x00000000\n\tmww 0x800E0054 0x00000000\n\tmww 0x800E0058 0x00000000\n\tmww 0x800E005C 0x00000000\n\tmww 0x800E0060 0x00000000\n\tmww 0x800E0064 0x00000000\n\tmww 0x800E0068 0x00010101\n\tmww 0x800E006C 0x01010101\n\tmww 0x800E0070 0x000f0f01\n\tmww 0x800E0074 0x0102020A\n\tmww 0x800E007C 0x00010101\n\tmww 0x800E0080 0x00000100\n\tmww 0x800E0084 0x00000100\n\tmww 0x800E0088 0x00000000\n\tmww 0x800E008C 0x00000002\n\tmww 0x800E0090 0x01010000\n\tmww 0x800E0094 0x07080403\n\tmww 0x800E0098 0x06005003\n\tmww 0x800E009C 0x0A0000C8\n\tmww 0x800E00A0 0x02009C40\n\tmww 0x800E00A4 0x0002030C\n\tmww 0x800E00A8 0x0036B009\n\tmww 0x800E00AC 0x031A0612\n\tmww 0x800E00B0 0x02030202\n\tmww 0x800E00B4 0x00C8001C\n\tmww 0x800E00C0 0x00011900\n\tmww 0x800E00C4 0xffff0303\n\tmww 0x800E00C8 0x00012100\n\tmww 0x800E00CC 0xffff0303\n\tmww 0x800E00D0 0x00012100\n\tmww 0x800E00D4 0xffff0303\n\tmww 0x800E00D8 0x00012100\n\tmww 0x800E00DC 0xffff0303\n\tmww 0x800E00E0 0x00000003\n\tmww 0x800E00E8 0x00000000\n\tmww 0x800E0108 0x00000612\n\tmww 0x800E010C 0x01000f02\n\tmww 0x800E0114 0x00000200\n\tmww 0x800E0118 0x00020007\n\tmww 0x800E011C 0xf4004a27\n\tmww 0x800E0120 0xf4004a27\n\tmww 0x800E012C 0x07400300\n\tmww 0x800E0130 0x07400300\n\tmww 0x800E013C 0x00000005\n\tmww 0x800E0140 0x00000000\n\tmww 0x800E0144 0x00000000\n\tmww 0x800E0148 0x01000000\n\tmww 0x800E014C 0x01020408\n\tmww 0x800E0150 0x08040201\n\tmww 0x800E0154 0x000f1133\n\tmww 0x800E015C 0x00001f04\n\tmww 0x800E0160 0x00001f04\n\tmww 0x800E016C 0x00001f04\n\tmww 0x800E0170 0x00001f04\n\tmww 0x800E0288 0x00010000\n\tmww 0x800E028C 0x00030404\n\tmww 0x800E0290 0x00000003\n\tmww 0x800E02AC 0x01010000\n\tmww 0x800E02B0 0x01000000\n\tmww 0x800E02B4 0x03030000\n\tmww 0x800E02B8 0x00010303\n\tmww 0x800E02BC 0x01020202\n\tmww 0x800E02C0 0x00000000\n\tmww 0x800E02C4 0x02030303\n\tmww 0x800E02C8 0x21002103\n\tmww 0x800E02CC 0x00061200\n\tmww 0x800E02D0 0x06120612\n\tmww 0x800E02D4 0x04420442\n\t# Mode register 0 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02D8 0x00000000\n\t# Mode register 0 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02DC 0x00040004\n\t# Mode register 1 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E0 0x00000000\n\t# Mode register 1 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02E4 0x00000000\n\t# Mode register 2 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02E8 0x00000000\n\t# Mode register 2 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02EC 0x00000000\n\t# Mode register 3 for CS1 and CS0, ok to program CS1 even if not used\n\tmww 0x800E02F0 0x00000000\n\t# Mode register 3 for CS2 and CS3, not supported in this processor\n\tmww 0x800E02F4 0xffffffff\n\n\t#**  start controller **#\n\tmww 0x800E0040 0x00000001\n\t# bit[0]: start\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx31pdk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The IMX31PDK eval board has a single IMX31 chip\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx31pdk_init }\n\nproc self_test {} {\n\techo \"Running 100 iterations of test.\"\n\tdump_image /ram/test 0x80000000 0x40000\n\tfor {set i 0} {$i < 100} {set i [expr {$i+1}]} {\n\t\techo \"Iteration $i\"\n\t\treset init\n\t\tmww 0x80000000 0x12345678 0x10000\n\t\tload_image /ram/test 0x80000000 bin\n\t\tverify_image /ram/test 0x80000000 bin\n\t}\n}\n\n\n# Slow fallback frequency\n# measure_clk indicates ca. 3-4MHz.\njtag_rclk 1000\n\nproc imx31pdk_init { } {\n\n\timx3x_reset\n\n\t# This setup puts RAM at 0x80000000\n\n\tmww 0x53FC0000 0x040\n\tmww 0x53F80000 0x074B0B7D\n\n\t# 399MHz - 26MHz input, PD=1,MFI=7, MFN=27, MFD=40\n\t#mww 0x53F80004 0xFF871D50\n\t#mww 0x53F80010 0x00271C1B\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000CC03\n\tmww 0xb8002004 0xa0330D01\n\tmww 0xb8002008 0x00220800\n\n\t# Configure CPLD on CS4\n\tmww 0xb8002040 0x0000DCF6\n\tmww 0xb8002044 0x444A4541\n\tmww 0xb8002048 0x44443302\n\n\t# SDCLK\n\tmww 0x43FAC26C 0\n\n\t# CAS\n\tmww 0x43FAC270 0\n\n\t# RAS\n\tmww 0x43FAC274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43FAC27C 0x1000\n\n\t# DQM3\n\tmww 0x43FAC284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2DC)\n\tmww 0x43FAC288 0\n\tmww 0x43FAC28C 0\n\tmww 0x43FAC290 0\n\tmww 0x43FAC294 0\n\tmww 0x43FAC298 0\n\tmww 0x43FAC29C 0\n\tmww 0x43FAC2A0 0\n\tmww 0x43FAC2A4 0\n\tmww 0x43FAC2A8 0\n\tmww 0x43FAC2AC 0\n\tmww 0x43FAC2B0 0\n\tmww 0x43FAC2B4 0\n\tmww 0x43FAC2B8 0\n\tmww 0x43FAC2BC 0\n\tmww 0x43FAC2C0 0\n\tmww 0x43FAC2C4 0\n\tmww 0x43FAC2C8 0\n\tmww 0x43FAC2CC 0\n\tmww 0x43FAC2D0 0\n\tmww 0x43FAC2D4 0\n\tmww 0x43FAC2D8 0\n\tmww 0x43FAC2DC 0\n\n\t# Initialization script for 32 bit DDR on MX31 ADS\n\tmww 0xB8001010 0x00000004\n\tmww 0xB8001004 0x006ac73a\n\tmww 0xB8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\tmww 0xB8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\tmww 0xB8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\tmww 0xB8001000 0x82226080\n\tmww 0x80000000 0xDEADBEEF\n\tmww 0xB8001010 0x0000000c\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx35pdk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The IMX35PDK eval board has a single IMX35 chip\nsource [find target/imx35.cfg]\nsource [find target/imx.cfg]\n$_TARGETNAME configure -event reset-init { imx35pdk_init }\n\n# Stick to *really* low clock rate or reset will fail\n# without RTCK / RCLK\njtag_rclk 10\n\nproc imx35pdk_init { } {\n\n\timx3x_reset\n\n\tmww 0x43f00040 0x00000000\n\tmww 0x43f00044 0x00000000\n\tmww 0x43f00048 0x00000000\n\tmww 0x43f0004C 0x00000000\n\tmww 0x43f00050 0x00000000\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00040 0x00000000\n\tmww 0x53f00044 0x00000000\n\tmww 0x53f00048 0x00000000\n\tmww 0x53f0004C 0x00000000\n\tmww 0x53f00050 0x00000000\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# clock setup\n\tmww 0x53F80004 0x00821000 ;# first need to set IPU_HND_BYP\n\tmww 0x53F80004 0x00821000 ;#arm clock is 399Mhz and ahb clock is 133Mhz.\n\n\t#=================================================\n\t# WEIM config\n\t#=================================================\n\t# CS0U\n\tmww 0xB8002000 0x0000CC03\n\t# CS0L\n\tmww 0xB8002004 0xA0330D01\n\t# CS0A\n\tmww 0xB8002008 0x00220800\n\t# CS5U\n\tmww 0xB8002050 0x0000dcf6\n\t# CS5L\n\tmww 0xB8002054 0x444a4541\n\t# CS5A\n\tmww 0xB8002058 0x44443302\n\n\t# IO SW PAD Control registers - setting of 0x0002 is high drive, mDDR\n\tmww 0x43FAC368 0x00000006\n\tmww 0x43FAC36C 0x00000006\n\tmww 0x43FAC370 0x00000006\n\tmww 0x43FAC374 0x00000006\n\tmww 0x43FAC378 0x00000006\n\tmww 0x43FAC37C 0x00000006\n\tmww 0x43FAC380 0x00000006\n\tmww 0x43FAC384 0x00000006\n\tmww 0x43FAC388 0x00000006\n\tmww 0x43FAC38C 0x00000006\n\tmww 0x43FAC390 0x00000006\n\tmww 0x43FAC394 0x00000006\n\tmww 0x43FAC398 0x00000006\n\tmww 0x43FAC39C 0x00000006\n\tmww 0x43FAC3A0 0x00000006\n\tmww 0x43FAC3A4 0x00000006\n\tmww 0x43FAC3A8 0x00000006\n\tmww 0x43FAC3AC 0x00000006\n\tmww 0x43FAC3B0 0x00000006\n\tmww 0x43FAC3B4 0x00000006\n\tmww 0x43FAC3B8 0x00000006\n\tmww 0x43FAC3BC 0x00000006\n\tmww 0x43FAC3C0 0x00000006\n\tmww 0x43FAC3C4 0x00000006\n\tmww 0x43FAC3C8 0x00000006\n\tmww 0x43FAC3CC 0x00000006\n\tmww 0x43FAC3D0 0x00000006\n\tmww 0x43FAC3D4 0x00000006\n\tmww 0x43FAC3D8 0x00000006\n\n\t# DDR data bus SD 0 through 31\n\tmww 0x43FAC3DC 0x00000082\n\tmww 0x43FAC3E0 0x00000082\n\tmww 0x43FAC3E4 0x00000082\n\tmww 0x43FAC3E8 0x00000082\n\tmww 0x43FAC3EC 0x00000082\n\tmww 0x43FAC3F0 0x00000082\n\tmww 0x43FAC3F4 0x00000082\n\tmww 0x43FAC3F8 0x00000082\n\tmww 0x43FAC3FC 0x00000082\n\tmww 0x43FAC400 0x00000082\n\tmww 0x43FAC404 0x00000082\n\tmww 0x43FAC408 0x00000082\n\tmww 0x43FAC40C 0x00000082\n\tmww 0x43FAC410 0x00000082\n\tmww 0x43FAC414 0x00000082\n\tmww 0x43FAC418 0x00000082\n\tmww 0x43FAC41c 0x00000082\n\tmww 0x43FAC420 0x00000082\n\tmww 0x43FAC424 0x00000082\n\tmww 0x43FAC428 0x00000082\n\tmww 0x43FAC42c 0x00000082\n\tmww 0x43FAC430 0x00000082\n\tmww 0x43FAC434 0x00000082\n\tmww 0x43FAC438 0x00000082\n\tmww 0x43FAC43c 0x00000082\n\tmww 0x43FAC440 0x00000082\n\tmww 0x43FAC444 0x00000082\n\tmww 0x43FAC448 0x00000082\n\tmww 0x43FAC44c 0x00000082\n\tmww 0x43FAC450 0x00000082\n\tmww 0x43FAC454 0x00000082\n\tmww 0x43FAC458 0x00000082\n\n\t# DQM setup\n\tmww 0x43FAC45c 0x00000082\n\tmww 0x43FAC460 0x00000082\n\tmww 0x43FAC464 0x00000082\n\tmww 0x43FAC468 0x00000082\n\n\tmww 0x43FAC46c 0x00000006\n\tmww 0x43FAC470 0x00000006\n\tmww 0x43FAC474 0x00000006\n\tmww 0x43FAC478 0x00000006\n\tmww 0x43FAC47c 0x00000006\n\tmww 0x43FAC480 0x00000006\t;# CSD0\n\tmww 0x43FAC484 0x00000006\t;# CSD1\n\tmww 0x43FAC488 0x00000006\n\tmww 0x43FAC48c 0x00000006\n\tmww 0x43FAC490 0x00000006\n\tmww 0x43FAC494 0x00000006\n\tmww 0x43FAC498 0x00000006\n\tmww 0x43FAC49c 0x00000006\n\tmww 0x43FAC4A0 0x00000006\n\tmww 0x43FAC4A4 0x00000006\t;# RAS\n\tmww 0x43FAC4A8 0x00000006\t;# CAS\n\tmww 0x43FAC4Ac 0x00000006\t;# SDWE\n\tmww 0x43FAC4B0 0x00000006 \t;# SDCKE0\n\tmww 0x43FAC4B4 0x00000006  ;# SDCKE1\n\tmww 0x43FAC4B8 0x00000002  ;# SDCLK\n\n\t# SDQS0 through SDQS3\n\tmww 0x43FAC4Bc 0x00000082\n\tmww 0x43FAC4C0 0x00000082\n\tmww 0x43FAC4C4 0x00000082\n\tmww 0x43FAC4C8 0x00000082\n\n\n\t# *==================================================\n\t#  Initialization script for 32 bit DDR2 on RINGO 3DS\n\t# *==================================================\n\n\t#--------------------------------------------\n\t# Init CCM\n\t#--------------------------------------------\n\tmww 0x53F80028 0x7D000028\n\n\t#--------------------------------------------\n\t# Init IOMUX for JTAG\n\t#--------------------------------------------\n\tmww 0x43FAC5EC 0x000000C3\n\tmww 0x43FAC5F0 0x000000C3\n\tmww 0x43FAC5F4 0x000000F3\n\tmww 0x43FAC5F8 0x000000F3\n\tmww 0x43FAC5FC 0x000000F3\n\tmww 0x43FAC600 0x000000F3\n\tmww 0x43FAC604 0x000000F3\n\n\n\t# ESD_MISC : enable DDR2\n\tmww 0xB8001010 0x00000304\n\n\t#--------------------------------------------\n\t# Init 32-bit DDR2 memory on CSD0\n\t# COL=10-bit, ROW=13-bit, BA[1:0]=Addr[26:25]\n\t#--------------------------------------------\n\n\t# ESD_ESDCFG0 : set timing parameters\n\tmww 0xB8001004 0x007ffC2f\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmww 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg EMR2\n\tmwb 0x84000000 0xda\n\t# DDR2 : Load reg EMR3\n\tmwb 0x86000000 0xda\n\t# DDR2 : Load reg EMR1 -- enable DLL\n\tmwb 0x82000400 0xda\n\t# DDR2 : Load reg MR -- reset DLL\n\tmwb 0x80000333 0xda\n\n\t# ESD_ESDCTL0 : select Prechare-All mode\n\tmww 0xB8001000 0x92220000\n\t# DDR2 : Prechare-All\n\tmwb 0x80000400 0x12345678\n\n\t# ESD_ESDCTL0 : select Manual-Refresh mode\n\tmww 0xB8001000 0xA2220000\n\t# DDR2 : Manual-Refresh 2 times\n\tmww 0x80000000 0x87654321\n\tmww 0x80000000 0x87654321\n\n\t# ESD_ESDCTL0 : select Load-Mode-Register mode\n\tmww 0xB8001000 0xB2220000\n\t# DDR2 : Load reg MR -- CL=3, BL=8, end DLL reset\n\tmwb 0x80000233 0xda\n\t# DDR2 : Load reg EMR1 -- OCD default\n\tmwb 0x82000780 0xda\n\t# DDR2 : Load reg EMR1 -- OCD exit\n\tmwb 0x82000400 0xda\t;# ODT disabled\n\n\t# ESD_ESDCTL0 : select normal-operation mode\n\t# DSIZ=32-bit, BL=8, COL=10-bit, ROW=13-bit\n\t# disable PWT & PRCT\n\t# disable Auto-Refresh\n\tmww 0xB8001000 0x82220080\n\n\t## ESD_ESDCTL0 : enable Auto-Refresh\n\tmww 0xB8001000 0x82228080\n\t## ESD_ESDCTL1 : enable Auto-Refresh\n\tmww 0xB8001008 0x00002000\n\n\n\t#***********************************************\n\t# Adjust the ESDCDLY5 register\n\t#***********************************************\n\t# Vary DQS_ABS_OFFSET5 for writes\n\tmww 0xB8001020 0x00F48000\t;# this is the default value\n\tmww 0xB8001024 0x00F48000\t;# this is the default value\n\tmww 0xB8001028 0x00F48000\t;# this is the default value\n\tmww 0xB800102c 0x00F48000\t;# this is the default value\n\n\n\t#Then you can make force measure with the dedicated bit (Bit 7 at ESDMISC)\n\tmww 0xB8001010 0x00000384\n\t# wait a while\n\tsleep 1000\n\t# now clear the force measurement bit\n\tmww 0xB8001010 0x00000304\n\n\t# dummy write to DDR memory to set DQS low\n\tmww 0x80000000 0x00000000\n\n\tmww 0x30000100 0x0\n\tmww 0x30000104 0x31024\n\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx53-m53evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#######################################\n# DENX M53EVK                         #\n# http://www.denx-cs.de/?q=M53EVK     #\n# Author: Marek Vasut <marex@denx.de> #\n# Based on imx53loco.cfg              #\n#######################################\n\n# The DENX M53EVK has on-board JTAG adapter\nsource [find interface/ftdi/m53evk.cfg]\n# The DENX M53EVK board has a single i.MX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 M53EVK board lodaded.\"\n\n# Set reset type\nreset_config trst_and_srst separate trst_open_drain srst_open_drain\n\n# Run at 6 MHz\nadapter speed 6000\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { m53evk_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc m53evk_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53fa86f4 0x00000000\t ;# GRP_DDRMODE_CTL\n\tmww 0x53fa8714 0x00000000\t ;# GRP_DDRMODE\n\tmww 0x53fa86fc 0x00000000\t ;# GRP_DDRPKE\n\tmww 0x53fa8724 0x04000000\t ;# GRP_DDR_TYPE\n\n\tmww 0x53fa872c 0x00300000\t ;# GRP_B3DS\n\tmww 0x53fa8554 0x00300000\t ;# DRAM_DQM3\n\tmww 0x53fa8558 0x00300040\t ;# DRAM_SDQS3\n\n\tmww 0x53fa8728 0x00300000\t ;# GRP_B2DS\n\tmww 0x53fa8560 0x00300000\t ;# DRAM_DQM2\n\tmww 0x53fa8568 0x00300040\t ;# DRAM_SDQS2\n\n\tmww 0x53fa871c 0x00300000\t ;# GRP_B1DS\n\tmww 0x53fa8594 0x00300000\t ;# DRAM_DQM1\n\tmww 0x53fa8590 0x00300040\t ;# DRAM_SDQS1\n\n\tmww 0x53fa8718 0x00300000\t ;# GRP_B0DS\n\tmww 0x53fa8584 0x00300000\t ;# DRAM_DQM0\n\tmww 0x53fa857c 0x00300040\t ;# DRAM_SDQS0\n\n\tmww 0x53fa8578 0x00300000\t ;# DRAM_SDCLK_0\n\tmww 0x53fa8570 0x00300000\t ;# DRAM_SDCLK_1\n\n\tmww 0x53fa8574 0x00300000\t ;# DRAM_CAS\n\tmww 0x53fa8588 0x00300000\t ;# DRAM_RAS\n\tmww 0x53fa86f0 0x00300000\t ;# GRP_ADDDS\n\tmww 0x53fa8720 0x00300000\t ;# GRP_CTLDS\n\n\tmww 0x53fa8564 0x00300040\t ;# DRAM_SDODT1\n\tmww 0x53fa8580 0x00300040\t ;# DRAM_SDODT0\n\n\t# Initialize DDR2 memory\n\tmww 0x63fd9088 0x32383535\n\tmww 0x63fd9090 0x40383538\n\tmww 0x63fd907c 0x0136014d\n\tmww 0x63fd9080 0x01510141\n\n\tmww 0x63fd9018 0x00011740\n\tmww 0x63fd9000 0xc3190000\n\tmww 0x63fd900c 0x555952e3\n\tmww 0x63fd9010 0xb68e8b63\n\tmww 0x63fd9014 0x01ff00db\n\tmww 0x63fd902c 0x000026d2\n\tmww 0x63fd9030 0x009f0e21\n\tmww 0x63fd9008 0x12273030\n\tmww 0x63fd9004 0x0002002d\n\tmww 0x63fd901c 0x00008032\n\tmww 0x63fd901c 0x00008033\n\tmww 0x63fd901c 0x00028031\n\tmww 0x63fd901c 0x092080b0\n\tmww 0x63fd901c 0x04008040\n\tmww 0x63fd901c 0x0000803a\n\tmww 0x63fd901c 0x0000803b\n\tmww 0x63fd901c 0x00028039\n\tmww 0x63fd901c 0x09208138\n\tmww 0x63fd901c 0x04008048\n\tmww 0x63fd9020 0x00001800\n\tmww 0x63fd9040 0x04b80003\n\tmww 0x63fd9058 0x00022227\n\tmww 0x63fd901c 0x00000000\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx53loco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n##################################################################################\n# Author: Wjatscheslaw Stoljarski (Slawa) <wjatscheslaw.stoljarski@kiwigrid.com> #\n# Kiwigrid GmbH                                                                  #\n##################################################################################\n\n# The IMX53LOCO (QSB) board has a single IMX53 chip\nsource [find target/imx53.cfg]\n# Helper for common memory read/modify/write procedures\nsource [find mem_helper.tcl]\n\necho \"iMX53 Loco board lodaded.\"\n\n# Set reset type\n#reset_config srst_only\n\nadapter speed 3000\n\n# Slow speed to be sure it will work\njtag_rclk 1000\n$_TARGETNAME configure -event \"reset-start\" { jtag_rclk 1000 }\n\n#adapter srst delay 200\n#jtag_ntrst_delay 200\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\techo \"Resetting ....\"\n\t#cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-init { loco_init }\n\nglobal AIPS1_BASE_ADDR\nset AIPS1_BASE_ADDR     0x53F00000\nglobal AIPS2_BASE_ADDR\nset AIPS2_BASE_ADDR     0x63F00000\n\nproc loco_init { } {\n\techo \"Reset-init...\"\n\t; # halt the CPU\n\thalt\n\n\techo \"HW version [format %x [mrw 0x48]]\"\n\n\tdap apsel 1\n\tDCD\n\n\t; # ARM errata ID #468414\n\tset tR [arm mrc 15 0 1 0 1]\n\tarm mcr 15 0 1 0 1 [expr {$tR | (1<<5)}]\t; # enable L1NEON bit\n\n\tinit_l2cc\n\tinit_aips\n\tinit_clock\n\n\tdap apsel 0\n\n\t; # Force ARM state\n\t; #reg cpsr 0x000001D3\n\tarm core_state arm\n\n\tjtag_rclk 3000\n#\tadapter speed 3000\n}\n\n\n# L2CC Cache setup/invalidation/disable\nproc init_l2cc { } {\n\t; #/* explicitly disable L2 cache */\n\t; #mrc 15, 0, r0, c1, c0, 1\n\tset tR [arm mrc 15 0 1 0 1]\n\t; #bic r0, r0, #0x2\n\t; #mcr 15, 0, r0, c1, c0, 1\n\tarm mcr 15 0 1 0 1 [expr {$tR & ~(1 << 2)}]\n\n\t; #/* reconfigure L2 cache aux control reg */\n\t; #mov r0, #0xC0                   /* tag RAM */\n\t; #add r0, r0, #0x4                /* data RAM */\n\t; #orr r0, r0, #(1 << 24)          /* disable write allocate delay */\n\t; #orr r0, r0, #(1 << 23)          /* disable write allocate combine */\n\t; #orr r0, r0, #(1 << 22)          /* disable write allocate */\n\n\t; #mcr 15, 1, r0, c9, c0, 2\n\tarm mcr 15 1 9 0 2 [expr {0xC4 | (1<<24) | (1<<23) | (1<<22)}]\n}\n\n\n# AIPS setup - Only setup MPROTx registers.\n# The PACR default values are good.\nproc init_aips { } {\n\t; # Set all MPROTx to be non-bufferable, trusted for R/W,\n\t; # not forced to user-mode.\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset VAL\t\t\t0x77777777\n\n#\tdap apsel 1\n\tmww [expr {$AIPS1_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS1_BASE_ADDR + 0x4}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x0}] $VAL\n\tmww [expr {$AIPS2_BASE_ADDR + 0x4}] $VAL\n#\tdap apsel 0\n}\n\n\nproc init_clock { } {\n\tglobal AIPS1_BASE_ADDR\n\tglobal AIPS2_BASE_ADDR\n\tset CCM_BASE_ADDR\t[expr {$AIPS1_BASE_ADDR + 0x000D4000}]\n\tset CLKCTL_CCSR         0x0C\n\tset CLKCTL_CBCDR\t0x14\n\tset CLKCTL_CBCMR        0x18\n\tset PLL1_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00080000}]\n\tset PLL2_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00084000}]\n\tset PLL3_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x00088000}]\n\tset PLL4_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x0008C000}]\n\tset CLKCTL_CSCMR1\t0x1C\n\tset CLKCTL_CDHIPR\t0x48\n\tset PLATFORM_BASE_ADDR\t[expr {$AIPS2_BASE_ADDR + 0x000A0000}]\n\tset CLKCTL_CSCDR1\t0x24\n\tset CLKCTL_CCDR\t\t0x04\n\n\t; # Switch ARM to step clock\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x4\n\n\treturn\n\techo \"not returned\"\n\tsetup_pll $PLL1_BASE_ADDR 800\n\tsetup_pll $PLL3_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL3\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00015154\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x02888945 | (1<<16)}]\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL2_BASE_ADDR 400\n\n\t; # Switch peripheral to PLL2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCDR}] [expr {0x00808145 | (2<<10) | (9<<16) | (1<<19)}]\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CBCMR}] 0x00016154\n\n\t; # change uart clk parent to pll2\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCMR1}]] & 0xfcffffff | 0x01000000}]\n\n\t; # make sure change is effective\n\twhile {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CDHIPR}]] != 0} { sleep 1 }\n\n\tsetup_pll $PLL3_BASE_ADDR 216\n\n\tsetup_pll $PLL4_BASE_ADDR 455\n\n\t; # Set the platform clock dividers\n\tmww [expr {$PLATFORM_BASE_ADDR + 0x14}] 0x00000124\n\n\tmww [expr {$CCM_BASE_ADDR + 0x10}] 0\n\n\t; # Switch ARM back to PLL 1.\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCSR}] 0x0\n\n\t; # make uart div=6\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}] [expr {[mrw [expr {$CCM_BASE_ADDR + $CLKCTL_CSCDR1}]] & 0xffffffc0 | 0x0a}]\n\n\t; # Restore the default values in the Gate registers\n\tmww [expr {$CCM_BASE_ADDR + 0x68}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x6C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x70}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x74}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x78}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x7C}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x80}] 0xFFFFFFFF\n\tmww [expr {$CCM_BASE_ADDR + 0x84}] 0xFFFFFFFF\n\n\tmww [expr {$CCM_BASE_ADDR + $CLKCTL_CCDR}] 0x00000\n\n\t; # for cko - for ARM div by 8\n\tmww [expr {$CCM_BASE_ADDR + 0x60}] [expr {0x000A0000 & 0x00000F0}]\n}\n\n\nproc setup_pll { PLL_ADDR CLK } {\n\tset PLL_DP_CTL\t\t0x00\n\tset PLL_DP_CONFIG   \t0x04\n\tset PLL_DP_OP\t\t0x08\n\tset PLL_DP_HFS_OP\t0x1C\n\tset PLL_DP_MFD\t\t0x0C\n\tset PLL_DP_HFS_MFD\t0x20\n\tset PLL_DP_MFN\t\t0x10\n\tset PLL_DP_HFS_MFN\t0x24\n\n\tif {$CLK == 1000} {\n\t\tset DP_OP\t[expr {(10 << 4) + ((1 - 1) << 0)}]\n\t\tset DP_MFD\t[expr {12 - 1}]\n\t\tset DP_MFN\t5\n\t} elseif {$CLK == 850} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t41\n\t} elseif {$CLK == 800} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 700} {\n\t\tset DP_OP\t[expr {(7 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t7\n\t} elseif {$CLK == 600} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 665} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {96 - 1}]\n\t\tset DP_MFN\t89\n\t} elseif {$CLK == 532} {\n\t\tset DP_OP\t[expr {(5 << 4) + ((1 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {24 - 1}]\n\t\tset DP_MFN\t13\n\t} elseif {$CLK == 455} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {48 - 1}]\n\t\tset DP_MFN\t71\n\t} elseif {$CLK == 400} {\n\t\tset DP_OP\t[expr {(8 << 4) + ((2 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {3 - 1}]\n\t\tset DP_MFN\t1\n\t} elseif {$CLK == 216} {\n\t\tset DP_OP\t[expr {(6 << 4) + ((3 - 1)  << 0)}]\n\t\tset DP_MFD\t[expr {4 - 1}]\n\t\tset DP_MFN\t3\n\t} else {\n\t\terror \"Error (setup_dll): clock not found!\"\n\t}\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\tmww [expr {$PLL_ADDR + $PLL_DP_CONFIG}] 0x2\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_OP}] $DP_OP\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_OP\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFD}] $DP_MFD\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFD}] $DP_MFD\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_MFN}] $DP_MFN\n\tmww [expr {$PLL_ADDR + $PLL_DP_HFS_MFN}] $DP_MFN\n\n\tmww [expr {$PLL_ADDR + $PLL_DP_CTL}] 0x00001232\n\twhile {[expr {[mrw [expr {$PLL_ADDR + $PLL_DP_CTL}]] & 0x1}] == 0} { sleep 1 }\n}\n\n\nproc CPU_2_BE_32 { L } {\n\treturn [expr {(($L & 0x000000FF) << 24) | (($L & 0x0000FF00) << 8) | (($L & 0x00FF0000) >> 8)  | (($L & 0xFF000000) >> 24)}]\n}\n\n\n# Device Configuration Data\nproc DCD { } {\n#\tdap apsel 1\n\tmww 0x53FA8554 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3\n\tmww 0x53FA8558 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3\n\tmww 0x53FA8560 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2\n\tmww 0x53FA8564 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT\n\tmww 0x53FA8568 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2\n\tmww 0x53FA8570 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1\n\tmww 0x53FA8574 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS\n\tmww 0x53FA8578 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0\n\tmww 0x53FA857c 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0\n\tmww 0x53FA8580 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0\n\tmww 0x53FA8584 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0\n\tmww 0x53FA8588 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS\n\tmww 0x53FA8590 0x00300040\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1\n\tmww 0x53FA8594 0x00300000\t;# IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1\n\tmww 0x53FA86f0 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_ADDDS\n\tmww 0x53FA86f4 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL\n\tmww 0x53FA86fc 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRPKE\n\tmww 0x53FA8714 0x00000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDRMODE - CMOS mode\n\tmww 0x53FA8718 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B0DS\n\tmww 0x53FA871c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B1DS\n\tmww 0x53FA8720 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_CTLDS\n\tmww 0x53FA8724 0x04000000\t;# IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE - DDR_SEL0=\n\tmww 0x53FA8728 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B2DS\n\tmww 0x53FA872c 0x00300000\t;# IOMUXC_SW_PAD_CTL_GRP_B3DS\n\n\t# Initialize DDR2 memory\n\tmww 0x63FD9088 0x35343535\t;# ESDCTL_RDDLCTL\n\tmww 0x63FD9090 0x4d444c44\t;# ESDCTL_WRDLCTL\n\tmww 0x63FD907c 0x01370138\t;# ESDCTL_DGCTRL0\n\tmww 0x63FD9080 0x013b013c\t;# ESDCTL_DGCTRL1\n\tmww 0x63FD9018 0x00011740\t;# ESDCTL_ESDMISC\n\tmww 0x63FD9000 0xc3190000\t;# ESDCTL_ESDCTL\n\tmww 0x63FD900c 0x9f5152e3\t;# ESDCTL_ESDCFG0\n\tmww 0x63FD9010 0xb68e8a63\t;# ESDCTL_ESDCFG1\n\tmww 0x63FD9014 0x01ff00db\t;# ESDCTL_ESDCFG2\n\tmww 0x63FD902c 0x000026d2\t;# ESDCTL_ESDRWD\n\tmww 0x63FD9030 0x009f0e21\t;# ESDCTL_ESDOR\n\tmww 0x63FD9008 0x12273030\t;# ESDCTL_ESDOTC\n\tmww 0x63FD9004 0x0002002d\t;# ESDCTL_ESDPDC\n\tmww 0x63FD901c 0x00008032\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00008033\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028031\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x052080b0\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008040\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803a\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x0000803b\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x00028039\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x05208138\t;# ESDCTL_ESDSCR\n\tmww 0x63FD901c 0x04008048\t;# ESDCTL_ESDSCR\n\tmww 0x63FD9020 0x00005800\t;# ESDCTL_ESDREF\n\tmww 0x63FD9040 0x04b80003\t;# ESDCTL_ZQHWCTRL\n\tmww 0x63FD9058 0x00022227\t;# ESDCTL_ODTCTRL\n\tmww 0x63FD901C 0x00000000\t;# ESDCTL_ESDSCR\n#\tdap apsel 0\n}\n\n# vim:filetype=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/imx8mp-evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# configuration file for NXP MC-IMX8MP-EVK\n#\n# Board includes FTDI-based JTAG adapter: interface/ftdi/imx8mp-evk.cfg\n#\n\ntransport select jtag\nadapter speed 1000\nreset_config srst_only\nadapter srst delay 100\n\nset CHIPNAME imx8mp\nset CHIPCORES 4\n\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/insignal_arndale.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# InSignal Arndale board\n#\n\nsource [find target/exynos5250.cfg]\n\n# Experimentally determined highest working speed\nadapter speed 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kasli.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\nftdi layout_init 0x0008 0x000b\n# adapter usb location 1:8\n\nreset_config none\ntransport select jtag\nadapter speed 25000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kc100.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Knovative KC-100 cable modem\n\n# TNETC4401PYP, 208-QFP U3\nsource [find target/tnetc4401.cfg]\n\n# 14-pin EJTAG on JP1. Standard pinout, 1-3-5-7-9-11 = nTRST-TDI-TDO-TMS-TCK-nSRST. Use 2 for GND.\n# Was initially disabled in hardware; had to add a solder bridge reenabling R124, R125 on back.\nreset_config trst_and_srst separate\n\n# 16Mb Intel CFI flash. Note this CPU has an internal ROM at 0x1FC0000 (phys) for cold boot.\n# All that really does is some minimal checks before jumping to external flash at 0x00000000 phys.\n# That is remapped to 0xB0000000 uncached, 0x90000000 cached.\nflash bank intel cfi 0xB0000000 0x200000 2 2 $_TARGETNAME\n\n# Perform this after a clean reboot, halt, and reset init (which should also leave it halted).\nproc kc100_dump_flash {} {\n\techo \"Probing 48 TSOP Intel CFI flash chip (2MB)...\"\n\tflash probe intel\n\techo \"Dumping 2MB flash chip to flashdump.bin.\n\tflash read_bank 0 flashdump.bin 0 0x200000\n}\n\n#TODO figure out memory init sequence to be able to dump from cached segment instead\n\n# There is also a serial console on JP2, 3-5-6 = TX-RX-GND. 9600/8/N/1.\n\n# Possibly of note, this modem's ancient ethernet port does not support Auto-MDIX.\n\n# This modem in many ways appears to be essentially a clone of the SB5120. See usbjtag.com.\n# The firmware/OS is also susceptible to many of the same procedures in \"Hacking the Cable Modem\"\n# by DerEngel (Ryan Harris), available from No Starch Press.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kc705.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html\n\nsource [find interface/ftdi/digilent-hs1.cfg]\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\nsource [find fpga/xilinx-xadc.cfg]\nsource [find fpga/xilinx-dna.cfg]\nadapter speed 25000\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/kc705.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc7k325t.bit;\\\n# jtagspi_program bitstream-kc705.bin 0;\\\n# jtagspi_program bios.bin 0xaf0000;\\\n# jtagspi_program runtime.fbi 0xb00000;\\\n# xc7_program xc7.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kcu105.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx ultrascale\n# http://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nsource [find interface/ftdi/digilent_jtag_smt2_nc.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nsource [find cpld/jtagspi.cfg]\n\nadapter speed 25000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/keil_mcb1700.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Keil MCB1700 eval board\n#\n# http://www.keil.com/mcb1700/picture.asp\n#\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/keil_mcb2140.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Keil MCB2140 eval board\n#\n# http://www.keil.com/mcb2140/picture.asp\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kindle2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Board configuration file for Amazon Kindle Model No. D00701 and D00801\n# AKA Kindle 2nd generation and Kindle DX\n# using a Freescale MCIMX31LDVKN5D i.MX31 processor\n#\n# Pins at J9 40-Pin FFC-A:\n#  1 - GND\n# 16 - TRSTB\n# 17 - TDI\n# 18 - TMS\n# 19 - TCK\n# 20 - RTCK\n# 21 - TDO\n# 22 - DE\n# 25 - BOOT_MODE4\n# 27 - BOOT_MODE2\n\nsource [find target/imx31.cfg]\nsource [find target/imx.cfg]\n\n$_TARGETNAME configure -event reset-init { kindle2_init }\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n# 8MiB NOR Flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xa0000000 0x800000 2 2 $_TARGETNAME\n\n# 16kiB internal SRAM\n$_TARGETNAME configure -work-area-phys 0x1fffc000 \\\n\t-work-area-size 0x4000 -work-area-backup 0\n\n# FIXME: currently SRST is not wired to the system\nreset_config trst_only\njtag_ntrst_assert_width 10\njtag_ntrst_delay 30\n\n# this is broken but enabled by default\narm11 memwrite burst disable\n\nadapter speed 1000\nftdi tdo_sample_edge falling\n\nproc kindle2_init {} {\n\timx3x_reset\n\tkindle2_clock_setup\n\tdisable_mmu_and_cache\n\tkindle2_misc_init\n\tkindle2_sdram_init\n\tarm core_state arm\n}\n\nproc kindle2_clock_setup {} {\n\t# CCMR: clock from FPM/CKIL\n\tmww 0x53f80000  0x074b0b7b\n\t# IPU_CONF\n\tmww 0x53fc0000  0x040\n\t# 398MHz\n\tmww 0x53f80004 0xff871650\n\tmww 0x53f80010 0x00331c23\n}\n\nproc kindle2_misc_init { } {\n\t# AIPS1\n\tmww 0x43f00040 0x0\n\tmww 0x43f00044 0x0\n\tmww 0x43f00048 0x0\n\tmww 0x43f0004c 0x0\n\tmww 0x43f00050 0x0\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\n\t# AIPS2\n\tmww 0x53f00040 0x0\n\tmww 0x53f00044 0x0\n\tmww 0x53f00048 0x0\n\tmww 0x53f0004c 0x0\n\tmww 0x53f00050 0x0\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\t# Start 16 bit NorFlash Initialization on CS0\n\tmww 0xb8002000 0x0000cc03\n\tmww 0xb8002004 0xa0330d01\n\tmww 0xb8002008 0x00220800\n}\n\nproc disable_mmu_and_cache {} {\n\t# Mode Supervisor, disable FIQ, IRQ and imprecise data aborts\n\treg cpsr 0x1d3\n\n\t# flush entire BTAC\n\tarm mcr 15 0 7 5 6 0\n\t# invalidate instruction and data cache\n\t# MCR CP15, 0, R1, C7, C7, 0\n\tarm mcr 15 0 7 7 0\n\n\t# clean and invalidate cache\n\tarm mcr 15 0 7 15 0\n\n\t# disable MMU and caches\n\tarm mcr 15 0 1 0 0 0\n\n\tarm mcr 15 0 15 2 4 0\n\n\t# invalidate TLBs\n\tarm mcr 15 0 8 7 0 0\n\n\t# Drain the write buffer\n\tarm mcr 15 0 7 10 4 0\n\n\t# start from AIPS 2GB region\n\tarm mcr 15 0 15 2 4 0x40000015\n}\n\nproc kindle2_sdram_init {} {\n\t#--------------------------------------------\n\t# Samsung K4X1G323PC-8GC3 32Mx32 Mobile DDR SDRAM\n\t#--------------------------------------------\n\t# SDCLK\n\tmww 0x43fac26c 0\n\n\t# CAS\n\tmww 0x43fac270 0\n\n\t# RAS\n\tmww 0x43fac274 0\n\n\t# CS2 (CSD0)\n\tmww 0x43fac27c 0x1000\n\n\t# DQM3\n\tmww 0x43fac284 0\n\n\t# DQM2, DQM1, DQM0, SD31-SD0, A25-A0, MA10 (0x288..0x2dc)\n\tmww 0x43fac288 0\n\tmww 0x43fac28c 0\n\tmww 0x43fac290 0\n\tmww 0x43fac294 0\n\tmww 0x43fac298 0\n\tmww 0x43fac29c 0\n\tmww 0x43fac2a0 0\n\tmww 0x43fac2a4 0\n\tmww 0x43fac2a8 0\n\tmww 0x43fac2ac 0\n\tmww 0x43fac2b0 0\n\tmww 0x43fac2b4 0\n\tmww 0x43fac2b8 0\n\tmww 0x43fac2bc 0\n\tmww 0x43fac2c0 0\n\tmww 0x43fac2c4 0\n\tmww 0x43fac2c8 0\n\tmww 0x43fac2cc 0\n\tmww 0x43fac2d0 0\n\tmww 0x43fac2d4 0\n\tmww 0x43fac2d8 0\n\tmww 0x43fac2dc 0\n\n\t# ?\n\tmww 0xb8002000 0x00006602\n\tmww 0xb8002004 0x00000501\n\tmww 0xb8002008 0x00000000\n\n\t# LPDDR1 Initialization script\n\tmww 0xb8001010 0x00000002\n\tmww 0xb8001010 0x00000004\n\t# ESDCFG0: set timing parameters\n\tmww 0xb8001004 0x007fff7f\n\t# ESDCTL0: select Prechare-All mode\n\tmww 0xb8001000 0x92100000\n\tmww 0x80000f00 0x12344321\n\t# ESDCTL0: Auto Refresh\n\tmww 0xb8001000 0xa2100000\n\tmww 0x80000000 0x12344321\n\tmww 0x80000000 0x12344321\n\t# ESDCTL0: Load Mode Register\n\tmww 0xb8001000 0xb2100000\n\tmwb 0x80000033 0xda\n\tmwb 0x81000000 0xff\n\t# ESDCTL0: enable Auto-Refresh\n\tmww 0xb8001000 0x82226080\n\tmww 0x80000000 0xdeadbeef\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kontron_sl28.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Kontron SMARC-sAL28\n\ntransport select jtag\nreset_config srst_only srst_nogate\n\njtag newtap unknown0 tap -irlen 12\n\nset _CPUS 2\nsource [find target/ls1028a.cfg]\n\nsource [find tcl/cpld/altera-epm240.cfg]\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/kwikstik.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale KwikStik development board\n#\n\n#\n# JLINK interface is onboard\n#\nsource [find interface/jlink.cfg]\n\nsource [find target/k40.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/la_fonera-fon2200.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/atheros_ar2315.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# LambdaConcept ECPIX-5\n# http://docs.lambdaconcept.com/ecpix-5/\n# Currently there are following board variants:\n# ECPIX-5 45F - LFE5UM5G-45F\n# ECPIX-5 85F - LFE5UM5G-85F\n#\n# This boards have two JTAG interfaces:\n# - CN4, micro USB port connected to FT2232HQ chip:\n#        ADBUS0 TCK\n#        ADBUS1 TDI\n#        ADBUS2 TDO\n#        ADBUS3 TMS\n#        BDBUS0 UART_TXD\n#        BDBUS1 UART_RXD\n#   This interface should be used with following config:\n#        interface/ftdi/lambdaconcept_ecpix-5.cfg\n# - CN3, 6 pin connector\n# See schematics for more details:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n#\n# No reset lines are implemented. So it is not possible to remote reset the FPGA\n# by using any of this interfaces\n\nsource [find interface/ftdi/lambdaconcept_ecpix-5.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lemaker_hikey.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# board configuration for LeMaker Hikey\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi6220.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/linksys-wag200g.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Linksys WAG200G Router\n#\n# The stock firmware Flash layout is organized as follow:\n#\n#   Start       End         Device\n#   0x90000000  0x90020000  /dev/mtdblock/2\n#   0x90020000  0x900d0000  /dev/mtdblock/1\n#   0x900d0000  0x903a0000  /dev/mtdblock/0\n#   0x903a0000  0x903e0000  /dev/mtdblock/5\n#   0x903e0000  0x903f0000  /dev/mtdblock/3\n#   0x903f0000  0x90400000  /dev/mtdblock/4\n\nset partition_list {\n    adam2\t{ \"Adam2 bootloader\"\t\t0x90000000 0x00020000 }\n    kernel\t{ \"Kernel\"\t\t\t0x90020000 0x000b0000 }\n    rootfs\t{ \"Root FS\"\t\t\t0x900d0000 0x002d0000 }\n    lang\t{ \"Minix language part\"\t\t0x903a0000 0x00040000 }\n    config\t{ \"Firmware config\"\t\t0x903e0000 0x00010000 }\n    adam2env\t{ \"Adam2 environment\"\t\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 4MB MXIC 29LV320MBTC Flash (Manufacturer/Device: 0x00c2 0x227e)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/linksys-wrt54gl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Linksys WRT54GL v1.1\n#\n\nsource [find target/bcm5352e.cfg]\n\nset partition_list {\n    CFE\t\t{ Bootloader\t\t\t0x1c000000 0x00040000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x1c040000 0x003b0000 }\n    nvram\t{ \"Config space\"\t\t0x1c3f0000 0x00010000 }\n}\n\n# External 4MB NOR Flash (Intel TE28F320C3BD90 or similar)\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x1c000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/linksys_nslu2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for the LinkSys (CISCO) NSLU2 board\n# It is an Intel XSCALE IXP420 CPU.\n\nsource [find target/ixp42x.cfg]\n# The _TARGETNAME is set by the above.\n\n$_TARGETNAME configure -work-area-phys 0x00020000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lisa-l.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# the Lost Illusions Serendipitous Autopilot\n# http://paparazzi.enac.fr/wiki/Lisa\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/logicpd_imx27.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The LogicPD Eval IMX27 eval board has a single IMX27 chip\nsource [find target/imx27.cfg]\n\n# The Logic PD board has a NOR flash on CS0\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xc0000000 0x00200000 2 2 $_TARGETNAME\n\n#\n# FIX ME, Add support to\n#\n# (A) hard reset the board.\n# (B) Initialize the SDRAM on the board\n#\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lpc1850_spifi_generic.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Generic LPC1850 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC1850 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc1850\n\nsource [find target/lpc1850.cfg]\n\n#A large working area greatly reduces flash write times\nset _WORKAREASIZE 0x4000\n\n$_CHIPNAME.m3 configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lpc4350_spifi_generic.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Generic LPC4350 board w/ SPIFI flash.\n# This config file is intended as an example of how to\n# use the lpcspifi flash driver, but it should be functional\n# for most LPC4350 boards utilizing SPIFI flash.\n\nset CHIPNAME lpc4350\n\nsource [find target/lpc4350.cfg]\n\n#Configure the flash bank; 0x14000000 is the base address for\n#lpc43xx/lpc18xx family micros.\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/lubbock.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel \"Lubbock\" Development Board with PXA255 (dbpxa255)\n#  Obsolete; this was Intel's original PXA255 development system\n#  Board also had CPU cards for SA1100, PXA210, PXA250, and more.\n\nsource [find target/pxa255.cfg]\n\nadapter srst delay 250\njtag_ntrst_delay 250\n\n# NOTE: until after pinmux and such are set up, only CS0 is\n# available ... not 2nd bank of CFI, or FPGA, SRAM, ENET, etc.\n\n# CS0, CS1 -- two banks of CFI flash, 32 MBytes each\n# each bank is 32-bits wide, two 16-bit chips in parallel\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME cfi 0x00000000 0x02000000 2 4 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME cfi 0x04000000 0x02000000 2 4 $_TARGETNAME\n\n# CS2 low -- FPGA registers\n# CS2 high -- 1 MByte SRAM at 0x0a00.0000 ... last 64K for scratch\n$_TARGETNAME configure -work-area-phys 0x0a0f0000\n\n$_TARGETNAME configure -event reset-assert-pre \\\n\t\"$_TARGETNAME configure -work-area-size 0\"\n\n# Make the hex led display a number, assuming CS2 is set up\n# and all digits have been enabled through the FPGA.\nproc hexled {u32} {\n\tmww 0x08000010 $u32\n}\n\n# CS3 -- Ethernet\n# CS4 -- SA1111\n# CS5 -- PCMCIA\n\n# NOTE:  system console normally uses the FF UART connector\n\nproc lubbock_init {target} {\n\n\techo \"Initialize PXA255 Lubbock board\"\n\n\t# (1) pinmux\n\n\t# GPSR0..GPSR2\n\tmww 0x40e00018 0x00008000\n\tmww 0x40e0001c 0x00FC0382\n\tmww 0x40e00020 0x0001FFFF\n\t# GPDR0..GPDR2\n\tmww 0x40e0000c 0x0060A800\n\tmww 0x40e00010 0x00FF0382\n\tmww 0x40e00014 0x0001C000\n\t# GAFR0_[LU]..GAFR2_[LU]\n\tmww 0x40e00054 0x98400000\n\tmww 0x40e00058 0x00002950\n\tmww 0x40e0005c 0x000A9558\n\tmww 0x40e00060 0x0005AAAA\n\tmww 0x40e00064 0xA0000000\n\tmww 0x40e00068 0x00000002\n\n\t# write PSSR, enable GPIOs\n\tmww 0x40f00000 0x00000020\n\n\t# write LED ctrl register ... ones disable\n\t# high byte, 8 hex leds; low byte, 8 discretes\n\tmwh 0x08000040 0xf0ff\n\n\thexled 0x0000\n\n\t# (2) Address space setup\n\n\t# MSC0/MSC1/MSC2\n\tmww 0x48000008 0x23f223f2\n\tmww 0x4800000c 0x3ff1a441\n\tmww 0x48000010 0x7ff97ff1\n\t# pcmcia/cf\n\tmww 0x48000014 0x00000000\n\tmww 0x48000028 0x00010504\n\tmww 0x4800002c 0x00010504\n\tmww 0x48000030 0x00010504\n\tmww 0x48000034 0x00010504\n\tmww 0x48000038 0x00004715\n\tmww 0x4800003c 0x00004715\n\n\thexled 0x1111\n\n\t# (3) SDRAM setup\n\t# REVISIT this looks dubious ... no refresh cycles\n\tmww 0x48000004 0x03CA4018\n\tmww 0x48000004 0x004B4018\n\tmww 0x48000004 0x000B4018\n\tmww 0x48000004 0x000BC018\n\tmww 0x48000000 0x00001AC8\n\tmww 0x48000000 0x00001AC9\n\n\tmww 0x48000040 0x00000000\n\n\t# FIXME -- setup:\n\t#  CLOCKS (and faster JTAG)\n\t#  enable icache\n\n\t# FIXME SRAM isn't working\n\t# $target configure -work-area-size 0x10000\n\n\thexled 0x2222\n\n\tflash probe 0\n\tflash probe 1\n\n\thexled 0xcafe\n}\n$_TARGETNAME configure -event reset-init \"lubbock_init $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/marsohod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Marsohod CPLD Development and Education board\n#\n# http://marsohod.org/howtostart/plata\n#\n\n# Recommended MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Altera MAXII EPM240T100C CPLD\nsource [find cpld/altera-epm240.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/marsohod2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Marsohod2 FPGA Development and Education board\n#\n# http://www.marsohod.org/prodmarsohod2\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# Cyclone III EP3C10E144 FPGA\nsource [find fpga/altera-ep3c10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/marsohod3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Marsohod3 FPGA Development and Education board\n#\n# http://www.marsohod.org/plata-marsokhod3\n#\n\n# Built-in MBFTDI programmer\nsource [find interface/ftdi/mbftdi.cfg]\nadapter speed 2000\ntransport select jtag\n\n# MAX10 10M50SAE144C8GES FPGA\nsource [find fpga/altera-10m50.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/mbed-lpc11u24.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an mbed eval board with a single NXP LPC11U24 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC11U24\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# NXP LPC11U24 Cortex-M0 with 32kB Flash and 8kB SRAM\nset WORKAREASIZE 0x2000\n\nsource [find target/lpc11xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/mbed-lpc1768.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an mbed eval board with a single NXP LPC1768 chip.\n# http://mbed.org/handbook/mbed-NXP-LPC1768\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nsource [find target/lpc17xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/mcb1700.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Keil MCB1700 PCB with 1768\n#\n# Reset init script sets it to 100MHz\nset CCLK 100000\n\nsource [find target/lpc17xx.cfg]\n\nglobal MCB1700_CCLK\nset MCB1700_CCLK $CCLK\n\n$_TARGETNAME configure -event reset-start {\n\t# Start *real slow* as we do not know the\n    # state the boot rom left the clock in\n\tadapter speed 10\n}\n\n# Set up 100MHz clock to CPU\n$_TARGETNAME configure -event reset-init {\n    # PLL0CON: Disable PLL\n\tmww 0x400FC080 0x00000000\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n    # CCLK=PLL/4 (=100 MHz)\n\tmww 0x400FC104 0x00000003\n    # CLKSRCSEL: Clock source = internal RC oscillator\n\tmww 0x400FC10C 0x00000000\n\n    # PLL0CFG: M=50,N=1 -> PLL=400 MHz\n\tmww 0x400FC084 0x00000031\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# PLL0CON: Enable PLL\n\tmww 0x400FC080 0x00000001\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\tsleep 50\n\n    # PLL0CON: Connect PLL\n\tmww 0x400FC080 0x00000003\n    # PLLFEED\n\tmww 0x400FC08C 0x000000AA\n    # PLLFEED\n\tmww 0x400FC08C 0x00000055\n\n\t# Dividing CPU clock by 8 should be pretty conservative\n\t#\n\t#\n\tglobal MCB1700_CCLK\n\tadapter speed [expr {$MCB1700_CCLK / 8}]\n\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\n\tmww 0x400FC040 0x01\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/microchip_explorer16.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Microchip Explorer 16 with PIC32MX360F512L PIM module.\n# http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858\n\n# TAPID for PIC32MX360F512L\nset CPUTAPID 0x30938053\n\n# use 32k working area\nset WORKAREASIZE 32768\n\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/microchip_sama5d27_som1_kit1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAMA5D27-SOM1-EK1\n# https://www.microchip.com/DevelopmentTools/ProductDetails/PartNO/ATSAMA5D27-SOM1-EK1\n# This board provide two jtag interfaces:\n# J11 - 10 pin interface\n# J10 - USB interface connected to the J-Link-OB.\n#       This functionality is implemented with an ATSAM3U4C microcontroller and\n#       provides JTAG functions and a bridge USB/Serial debug port (CDC).\n#\n# Jumper J7 disables the J-Link-OB-ATSAM3U4C JTAG functionality.\n# - Jumper J7 not installed: J-Link-OB-ATSAM3U4C is enabled and fully functional.\n# - Jumper J7 installed: J-Link-OB-ATSAM3U4C is disabled and an external JTAG\n#   controller can be used through the 10-pin JTAG port J11.\n\nsource [find interface/jlink.cfg]\nreset_config srst_only\n\nsource [find target/at91sama5d2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/microchip_same51_curiosity_nano.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Microchip SAME51 Curiosity Nano evaluation kit.\n#\n# https://www.microchip.com/en-us/development-tool/EV76S68A\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same51\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/microchip_same54_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Microchip (former Atmel) SAM E54 Xplained Pro evaluation kit.\n# http://www.microchip.com/developmenttools/productdetails.aspx?partno=atsame54-xpro\n#\n\nsource [find interface/cmsis-dap.cfg]\n\nset CHIPNAME same54\n\nsource [find target/atsame5x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/microchip_saml11_xplained_pro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Microchip (formerly Atmel) SAM L11 Xplained Pro Evaluation Kit.\n# https://www.microchip.com/DevelopmentTools/ProductDetails/dm320205\n#\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 1000\n\nset CHIPNAME saml11\nsource [find target/atsaml1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/mini2440.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#-------------------------------------------------------------------------\n# Mini2440 Samsung s3c2440A Processor with 64MB DRAM, 64MB NAND, 2 MB N0R\n# NOTE: Configured for NAND boot (switch S2 in NANDBOOT)\n# 64 MB NAND (Samsung K9D1208V0M)\n# B Findlay  08/09\n#\n#   ----------- Important notes to help you on your way ----------\n# README:\n#     NOR/NAND Boot Switch - I have not read the vivi source, but from\n#     what I could tell from reading the registers it appears that vivi\n#     loads itself into DRAM and then flips NFCONT (0x4E000004) bits\n#     Mode (bit 0 = 1), and REG_nCE (bit 1 = 0) which maps the NAND\n#     FLASH at the bottom 64MB of memory. This essentially takes the\n#     NOR Flash out of the circuit so you can't trash it.\n#\n#     I adapted the samsung_s3c2440.cfg file which is why I did not\n#     include \"source [find target/samsung_s3c2440.cfg]\".  I believe\n#     the -work-area-phys 0x200000 is incorrect, but also had to pad\n#     some additional resets.  I didn't modify it as if it is working\n#     for someone, the work-area-phys is not used by most.\n#\n#     JTAG ADAPTER SPECIFIC\n#     IMPORTANT! Any JTAG device that uses ADAPTIVE CLOCKING will likely\n#     FAIL as the pin RTCK on the mini2440 10 pin JTAG Conn doesn't exist.\n#     This is Pin 11 (RTCK) on 20 pin JTAG connector. Therefore it is\n#     necessary to FORCE setting the clock. Normally this should be configured\n#     in the openocd.cfg file, but was placed here as it can be a tough\n#     problem to figure out.  THIS MAY NOT FIX YOUR PROBLEM.. I modified\n#     the openOCD driver jlink.c and posted it here. It may eventually end\n#     up changed in openOCD, but its a hack in the driver and really should\n#     be in the jtag layer (core.c me thinks), but haven't done it yet. My\n#     hack for jlink.c may be found here.\n#\n#     http://forum.sparkfun.com/viewtopic.php?t=16763&sid=946e65abdd3bab39cc7d90dee33ff135\n#\n#     Note: Also if you have a USB JTAG, you will need the USB library installed\n#     on your system \"libusb-dev\" or the make of openocd will fail. I *think*\n#     it's apt-get install libusb-dev.  When I made my config I only included\n#     --enable-jlink and --enable-usbdevs\n#\n#     I HAVE NOT Tested this thoroughly, so there could still be problems.\n#     But it should get you way ahead of the game from where I started.\n#     If you find problems (and fixes) please post them to\n#     openocd-development@lists.berlios.de and join the developers and\n#     check in fixes to this and anything else you find.  I do not\n#     provide support, but if you ask really nice and I see anything\n#     obvious I will tell you.. mostly just dig, fix, and submit to openocd.\n#\n#     best!   brfindla@yahoo.com   Nashua, NH USA\n#\n#     Recommended resources:\n#       - first two are the best Mini2440 resources anywhere\n#       - maintained by buserror... thanks guy!\n#\n#       http://bliterness.blogspot.com/\n#       http://code.google.com/p/mini2440/\n#\n#       others....\n#\n#       http://forum.sparkfun.com/viewforum.php?f=18\n#       http://labs.kernelconcepts.de/Publications/Micro24401/\n#       http://www.friendlyarm.net/home\n#       http://www.amontec.com/jtag_pinout.shtml\n#\n#-------------------------------------------------------------------------\n#\n#\n# Your openocd.cfg file should contain:\n# source [find interface/<yourjtag>.cfg]\n# source [find board/mini2440.cfg]\n#\n#\n#\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\n#-------------------------------------------------------------------------\n# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor : ARM920Tid(wb) rev 0 (v4l)\n# Info: JTAG tap: s3c2440.cpu tap/device found: 0x0032409d\n#  (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n#-------------------------------------------------------------------------\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x40000000  -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\n#-------------------------------------------------------------------------\n# JTAG ADAPTER SPECIFIC\n# IMPORTANT! See README at top of this file.\n#-------------------------------------------------------------------------\n\n    adapter speed 12000\n\n#-------------------------------------------------------------------------\n# GDB Setup\n#-------------------------------------------------------------------------\n\n    gdb_breakpoint_override hard\n\n#------------------------------------------------\n# ARM SPECIFIC\n#------------------------------------------------\n\n    targets\n  #  arm7_9 dcc_downloads enable\n  #  arm7_9 fast_memory_access enable\n\n\n    nand device s3c2440 0\n\n    adapter srst delay 100\n    jtag_ntrst_delay 100\n    reset_config trst_and_srst\n    init\n\n    echo \" \"\n    echo \"-------------------------------------------\"\n    echo \"--- login with - telnet localhost 4444  ---\"\n    echo \"--- then type help_2440                 ---\"\n    echo \"-------------------------------------------\"\n    echo \" \"\n\n\n\n#------------------------------------------------\n# Processor Initialialization\n# Note: Processor writes can only occur when\n# the state is in SYSTEM. When you call init_2440\n# one of the first lines will tell you what state\n# you are in. If a linux image is booting\n# when you run this, it will not work\n# a vivi boot loader will run with this just\n# fine. The reg values were obtained by a combination\n# of figuring them out fromt the manual, and looking\n# at post vivi values with the debugger. Don't\n# place too much faith in them, but seem to work.\n#------------------------------------------------\n\nproc init_2440 { } {\n\n    halt\n    s3c2440.cpu curstate\n\n    #-----------------------------------------------\n    # Set Processor Clocks - mini2440 xtal=12mHz\n    # we set main clock for 405mHZ\n    # we set the USB Clock for 48mHz\n    # OM2 OM3 pulled to ground so main clock and\n    # usb clock are off 12mHz xtal\n    #-----------------------------------------------\n\n    mww phys 0x4C000014 0x00000005 ;#  Clock Divider control Reg\n    mww phys 0x4C000000 0xFFFFFFFF ;#  LOCKTIME count register\n    mww phys 0x4C000008 0x00038022 ;#  UPPLCON  USB clock config Reg\n    mww phys 0x4C000004 0x0007F021 ;#  MPPLCON  Proc clock config Reg\n\n    #-----------------------------------------------\n    # Configure Memory controller\n    # BWSCON configures all banks, NAND, NOR, DRAM\n    # DRAM - 64MB - 32 bit bus, uses BANKCON6 BANKCON7\n    #-----------------------------------------------\n\n    mww phys 0x48000000 0x22111112 ;#  BWSCON - Bank and Bus Width\n    mww phys 0x48000010 0x00001112 ;#  BANKCON4 - ?\n    mww phys 0x4800001c 0x00018009 ;#  BANKCON6 - DRAM\n    mww phys 0x48000020 0x00018009 ;#  BANKCON7 - DRAM\n    mww phys 0x48000024 0x008E04EB ;#  REFRESH  - DRAM\n    mww phys 0x48000028 0x000000B2 ;#  BANKSIZE - DRAM\n    mww phys 0x4800002C 0x00000030 ;#  MRSRB6 - DRAM\n    mww phys 0x48000030 0x00000030 ;#  MRSRB7 - DRAM\n\n    #-----------------------------------------------\n    # Now port configuration for enables for memory\n    # and other stuff.\n    #-----------------------------------------------\n\n    mww phys 0x56000000\t0x007FFFFF ;#  GPACON\n\n    mww phys 0x56000010\t0x00295559 ;#  GPBCON\n    mww phys 0x56000018\t0x000003FF ;#  GPBUP (PULLUP ENABLE)\n    mww phys 0x56000014\t0x000007C2 ;#  GPBDAT\n\n    mww phys 0x56000020\t0xAAAAA6AA ;#  GPCCON\n    mww phys 0x56000028\t0x0000FFFF ;#  GPCUP\n    mww phys 0x56000024\t0x00000020 ;#  GPCDAT\n\n    mww phys 0x56000030\t0xAAAAAAAA ;#  GPDCON\n    mww phys 0x56000038\t0x0000FFFF ;#  GPDUP\n\n    mww phys 0x56000040\t0xAAAAAAAA ;#  GPECON\n    mww phys 0x56000048\t0x0000FFFF ;#  GPEUP\n\n    mww phys 0x56000050\t0x00001555 ;#  GPFCON\n    mww phys 0x56000058\t0x0000007F ;#  GPFUP\n    mww phys 0x56000054\t0x00000000 ;#  GPFDAT\n\n    mww phys 0x56000060\t0x00150114 ;#  GPGCON\n    mww phys 0x56000068\t0x0000007F ;#  GPGUP\n\n    mww phys 0x56000070\t0x0015AAAA ;#  GPHCON\n    mww phys 0x56000078\t0x000003FF ;#  GPGUP\n\n}\n\n\n\nproc flash_config { } {\n\n    #-----------------------------------------\n    # Finish Flash Configuration\n    #-----------------------------------------\n\n    halt\n\n    #flash configuration (K9D1208V0M: 512Mbit, x8, 3.3V, Mode: Normal, 1st gen)\n    nand probe 0\n    nand list\n}\n\nproc flash_uboot { } {\n\n\t# flash the u-Boot binary and reboot into it\n\tinit_2440\n\tflash_config\n\tnand erase 0 0x0 0x40000\n\tnand write 0 /tftpboot/u-boot-nand512.bin 0 oob_softecc_kw\n\tresume\n}\n\n\nproc load_uboot { } {\n        echo \" \"\n        echo \" \"\n        echo \"----------------------------------------------------------\"\n        echo \"---- Load U-Boot into RAM and execute it.              ---\"\n        echo \"---- NOTE: loads, partially runs, and hangs            ---\"\n        echo \"---- U-Boot is fine, this image runs from vivi.        ---\"\n        echo \"---- I burned u-boot into NAND so I didn't finish      ---\"\n        echo \"---- debugging it. I am leaving this here as it is     ---\"\n        echo \"---- part of the way there if you want to fix it.      ---\"\n        echo \"----                                                   ---\"\n        echo \"---- mini2440 U-boot here:                             ---\"\n        echo \"---- http://repo.or.cz/w/u-boot-openmoko/mini2440.git  ---\"\n        echo \"---- Also this:                                        ---\"\n        echo \"---- http://code.google.com/p/mini2440/wiki/MiniBringup --\"\n        echo \"----------------------------------------------------------\"\n\n\tinit_2440\n\techo \"Loading /tftpboot/u-boot-nand512.bin\"\n\tload_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"Verifying image....\"\n\tverify_image /tftpboot/u-boot-nand512.bin 0x33f80000 bin\n\techo \"jumping to u-boot\"\n        #bp 0x33f80068 4 hw\n        reg 0 0\n        reg 1 0\n        reg 2 0\n        reg 3 0\n        reg 4 0x33f80000\n      \tresume 0x33f80000\n}\n\n       # this may help a little bit debugging the load_uboot\nproc s {} {\n        step\n        reg\n        arm disassemble 0x33F80068 0x10\n}\n\nproc help_2440 {} {\n    echo \" \"\n    echo \" \"\n    echo \"-----------------------------------------------------------\"\n    echo \"---- The following mini2440 funcs are supported        ----\"\n    echo \"----   init_2440 - initialize clocks, DRAM, IO         ----\"\n    echo \"----   flash_config - configures nand flash            ----\"\n    echo \"----   load_uboot - loads uboot into ram               ----\"\n    echo \"----   flash_uboot - flashes uboot to nand (untested)  ----\"\n    echo \"----   help_2440 - this help display                   ----\"\n    echo \"-----------------------------------------------------------\"\n    echo \" \"\n    echo \" \"\n}\n\n\n#----------------------------------------------------------------------------\n#----------------------------------- END ------------------------------------\n#----------------------------------------------------------------------------\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/mini6410.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a tiny6410\n# Processor       : ARM1176\n# Info : JTAG tap: s3c6410.etb tap/device found: 0x2b900f0f (mfg: 0x787, part: 0xb900, ver: 0x2)\n# Info : JTAG tap: s3c6410.cpu tap/device found: 0x07b76f0f (mfg: 0x787, part: 0x7b76, ver: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nproc init_6410 {} {\n\thalt\n\treg cpsr 0x1D3\n\tarm mcr 15 0 15 2 4 0x70000013\n\n\t#-----------------------------------------------\n\t# Clock and Timer Setting\n\t#-----------------------------------------------\n\tmww 0x7e004000 0\t\t;# WATCHDOG \t- Disable\n\tmww 0x7E00F120 0x0003\t\t;# MEM_SYS_CFG\t- CS0:8 bit, Mem1:32bit, CS2=NAND\n\t#mww 0x7E00F120 0x1000\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=SROMC\n\t#mww 0x7E00F120 0x1002\t\t;# MEM_SYS_CFG\t- CS0:16bit, Mem1:32bit, CS2=OND\n\tmww 0x7E00F900 0x805e\t\t;# OTHERS\t- Change SYNCMUX[6] to “1”\n\tsleep 1000\n\tmww 0x7E00F900 0x80de\t\t;# OTHERS\t- Assert SYNCREQ&VICSYNCEN to “1”(rb1004modify)\n\tsleep 1000\t\t\t;#\t\t- Others[11:8] to 0xF\n\tmww 0x7E00F000 0xffff\t\t;# APLL_LOCK\t- APLL LockTime\n\tmww 0x7E00F004 0xffff\t\t;# MPLL_LOCK\t- MPLL LockTime\n\tmww 0x7E00F020 0x1047310\t;# CLK_DIV0 \t- ARMCLK:HCLK:PCLK = 1:4:16\n\tmww 0x7E00F00c 0x81900302\t;# APLL_CON \t- A:400, P:3, S:2 => 400MHz\n\tmww 0x7E00F010 0x81900303\t;# MPLL_CON \t- M:400, P:3, S:3 => 200MHz\n\tmww 0x7E00F01c 0x3\t\t;# CLK_SRC \t- APLL,MPLL Clock Select\n\n\t#-----------------------------------------------\n\t# DRAM initialization\n\t#-----------------------------------------------\n\tmww 0x7e001004 0x4\t\t;# P1MEMCCMD\t- Enter the config state\n\tmww 0x7e001010 0x30C\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 100MHz\n#\tmww 0x7e001010 0x40e\t\t;# P1REFRESH\t- Refresh Period register (7800ns), 133MHz\n\tmww 0x7e001014 0x6\t\t;# P1CASLAT\t- CAS Latency = 3\n\tmww 0x7e001018 0x1\t\t;# P1T_DQSS\n\tmww 0x7e00101c 0x2\t\t;# P1T_MRD\n\tmww 0x7e001020 0x7\t\t;# P1T_RAS\t- 45 ns\n\tmww 0x7e001024 0xA\t\t;# P1T_RC\t- 67.5 ns\n\tmww 0x7e001028 0xC\t\t;# P1T_RCD\t- 22.5 ns\n\tmww 0x7e00102C 0x10B\t\t;# P1T_RFC\t- 80 ns\n\tmww 0x7e001030 0xC\t\t;# P1T_RP\t- 22.5 ns\n\tmww 0x7e001034 0x3\t\t;# P1T_RRD\t- 15 ns\n\tmww 0x7e001038 0x3\t\t;# P1T_WR\t- 15 ns\n\tmww 0x7e00103C 0x2\t\t;# P1T_WTR\n\tmww 0x7e001040 0x2\t\t;# P1T_XP\n\tmww 0x7e001044 0x11\t\t;# P1T_XSR\t- 120 ns\n\tmww 0x7e001048 0x11\t\t;# P1T_ESR\n\n\t#-----------------------------------------------\n\t# Memory Configuration Registers\n\t#-----------------------------------------------\n\tmww 0x7e00100C 0x00010012 \t;# P1MEMCFG\t- 1 CKE, 1Chip, 4burst, Alw, AP[10],ROW/Column bit\n\tmww 0x7e00104C 0x0B41 \t\t;# P1MEMCFG2\t- Read delay 1 Cycle, mDDR, 32bit, Sync.\n\tmww 0x7e001200 0x150F0 \t\t;# CHIP_N_CFG\t- 0x150F0 for 256M, 0x150F8 for 128M\n\n\t#-----------------------------------------------\n\t# Memory Direct Commands\n\t#-----------------------------------------------\n\tmww 0x7e001008 0xc0000\t\t;# Chip0 Direct Command :NOP5\n\tmww 0x7e001008 0x0\t\t;# Chip0 Direct Command :PreCharge al\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0x40000\t\t;# Chip0 Direct Command :AutoRefresh\n\tmww 0x7e001008 0xA0000\t\t;# EMRS, DS:Full, PASR:Full\n\tmww 0x7e001008 0x80032\t\t;# MRS, CAS3, BL4\n\tmww 0x7e001004 0x0\t\t;# Enable DMC1\n}\n\nproc install_6410_uboot {} {\n\t# write U-boot magic number\n\tmww 0x50000000 0x24564236\n\tmww 0x50000004 0x20764316\n\tload_image u-boot_nand-ram256.bin 0x50008000 bin\n\tload_image u-boot_nand-ram256.bin 0x57E00000 bin\n\n\t#Kick in\n\treg pc 0x57E00000\n\tresume\n}\n\nproc init_6410_flash {} {\n\thalt\n\tnand probe 0\n\tnand list\n}\n\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst\n\ngdb_breakpoint_override hard\n\ntargets\nnand device $_CHIPNAME.flash s3c6400 $_CHIPNAME.cpu\n\ninit\necho \" \"\necho \" \"\necho \"-------------------------------------------------------------------\"\necho \"---- The following mini6410/tiny6410 functions are available:  ----\"\necho \"----   init_6410 - initialize clock, timer, DRAM               ----\"\necho \"----   init_6410_flash - initializes NAND flash support        ----\"\necho \"----   install_6410_uboot - copies u-boot image into RAM and   ----\"\necho \"----                        runs it                            ----\"\necho \"-------------------------------------------------------------------\"\necho \" \"\necho \" \"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/minispartan6.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# https://www.scarabhardware.com/minispartan6/\n\nsource [find interface/ftdi/minispartan6.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to read the device dna of the FPGA on the board;\n# openocd -f board/minispartan6.cfg -c \"init;xc6s_print_dna xc6s.tap;shutdown\"\n\n# example command to write bitstream\n# openocd -f board/minispartan6.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx??.bit;\\\n# jtagspi_program bitstream.bin 0;\\\n# xc6s_program xc6s.tap;\\\n# shutdown\"\n#\n# jtagspi flash procies can be found in the contrib/loaders/flash/fpga/\n# directory, with prebuilt versions available at\n# https://github.com/jordens/bscan_spi_bitstreams\n#\n# For the SLX25 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx25.bit\n# For the SLX9 variant, use\n#  - https://github.com/jordens/bscan_spi_bitstreams/raw/master/bscan_spi_xc6slx9.bit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nds32_corvettef1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-Corvette-F1 R1.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r1/\n# ADP-Corvette-F1 R2.0\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/corvette-f1-r2/\n\nadapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nreset_config srst_only\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nds32_xc7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ADP-XC7K160/410\n# http://www.andestech.com/en/products-solutions/andeshape-platforms/adp-xc7k160-410/\n\nsource [find target/nds32v5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/netgear-dg834v3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Netgear DG834v3 Router\n# Internal 4Kb RAM (@0x80000000)\n# Flash is located at 0x90000000 (CS0) and RAM is located at 0x94000000 (CS1)\n#\n\nset partition_list {\n    loader\t{ \"Bootloader (ADAM2)\"\t\t0x90000000 0x00020000 }\n    firmware\t{ \"Kernel+rootfs\"\t\t0x90020000 0x003d0000 }\n    config\t{ \"Bootloader config space\"\t0x903f0000 0x00010000 }\n}\n\nsource [find target/ti-ar7.cfg]\n\n# External 16MB SDRAM - disabled as we use internal sram\n#$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n\n# External 4MB NOR Flash\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x90000000 0x00400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/netgear-wg102.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/atheros_ar2313.cfg]\n\nreset_config trst_and_srst\n\n$_TARGETNAME configure -event reset-init {\n\tmips32 cp0 12 0 0x10400000\n\n\t# configure sdram controller\n\tmww 0xb8300004 0x0e03\n\tsleep 100\n\tmww 0xb8300004 0x0e01\n\tmww 0xb8300008 0x10\n\tsleep 500\n\tmww 0xb8300004 0x0e02\n\n\tmww 0xb8300000 0x6c0088\n\tmww 0xb8300008 0x57e\n\tmww 0xb8300004 0x0e00\n\tmww 0xb8300004 0xb00\n\n\t# configure flash\n\t#                 0x00000001 - 0x01 << FLASHCTL_IDCY_S\n\t#                 0x000000e0 - 0x07 << FLASHCTL_WST1_S\n\t# FLASHCTL_RBLE   0x00000400 - Read byte lane enable\n\t#                 0x00003800 - 0x07 << FLASHCTL_WST2_S\n\t# FLASHCTL_AC_8M  0x00060000 - Size of flash\n\t# FLASHCTL_E      0x00080000 - Flash bank enable (added)\n\t# FLASHCTL_WP     0x04000000 - write protect. If used, CFI mode wont work!!\n\t# FLASHCTL_MWx16  0x10000000 - 16bit mode. Do not use it!!\n\t# FLASHCTL_MWx8   0x00000000 - 8bit mode.\n\tmww 0xb8400000 0x000d3ce1\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xbe000000 0x00400000 1 1 $_TARGETNAME x16_as_x8\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nordic_nrf51822_mkit.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nordic Semiconductor PCA10024 board (aka nRF51822-mKIT)\n#\n\nsource [find interface/cmsis-dap.cfg]\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nordic_nrf51_dk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nordic Semiconductor NRF51 Development Kit (nRF6824)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf51.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nordic_nrf52_dk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nordic Semiconductor NRF52 Development Kit (nRF52832)\n#\n\nsource [find interface/jlink.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nordic_nrf52_ftx232.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# nordic module NRF52 (nRF52832/52840) attached to an adafruit ft232h module\n# or any FT232H/FT2232H/FT4232H based board/module\n#\n\nsource [find interface/ftdi/ft232h-module-swd.cfg]\n#source [find interface/ftdi/minimodule-swd.cfg]\n\ntransport select swd\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/novena-internal-fpga.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Novena open hardware and F/OSS-friendly computing platform\n#\n# Design documentation:\n# http://www.kosagi.com/w/index.php?title=Novena_PVT_Design_Source\n#\n# +-------------+--------------+------+-------+---------+\n# | Pad name    | Schematic    | GPIO | sysfs | JTAG    |\n# +-------------+--------------+------+-------+---------+\n# | DISP0_DAT13 | FPGA_RESET_N | 5-07 |  135  | RESET_N |\n# | DISP0_DAT14 | FPGA_TCK     | 5-08 |  136  | TCK     |\n# | DISP0_DAT15 | FPGA_TDI     | 5-09 |  137  | TDI     |\n# | DISP0_DAT16 | FPGA_TDO     | 5-10 |  138  | TDO     |\n# | DISP0_DAT17 | FPGA_TMS     | 5-11 |  139  | TMS     |\n# +-------------+--------------+------+-------+---------+\n\nadapter driver sysfsgpio\n\ntransport select jtag\n\n# TCK TMS TDI TDO\nsysfsgpio jtag_nums 136 139 137 138\n\nsource [find cpld/xilinx-xc6s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/npcx_evb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Nuvoton NPCX Evaluation Board\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\nsource [find target/npcx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/numato_mimas_a7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Numato Mimas A7 - Artix 7 FPGA Board\n#\n# https://numato.com/product/mimas-a7-artix-7-fpga-development-board-with-ddr-sdram-and-gigabit-ethernet\n#\n# Note: Connect external DC power supply if programming a heavy design onto FPGA.\n#       Programming while powering via USB may lead to programming failure.\n#       Therefore, prefer external power supply.\n\nadapter driver ftdi\nftdi device_desc \"Mimas Artix 7 FPGA Module\"\nftdi vid_pid 0x2a19 0x1009\n\n# channel 0 is for custom purpose by users (like uart, fifo etc)\n# channel 1 is reserved for JTAG (by-default) or SPI (possible via changing solder jumpers)\nftdi channel 1\nftdi tdo_sample_edge falling\n\n\n# FTDI Pin Layout\n#\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | DBUS7  | DBUS6 | DBUS5 | DBUS4 | DBUS3 | DBUS2 | DBUS1 | DBUS0 |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n# | PROG_B | OE_N  |  NC   |  NC   |  TMS  |  TDO  |  TDI  |  TCK  |\n# +--------+-------+-------+-------+-------+-------+-------+-------+\n#\n# OE_N is JTAG buffer output enable signal (active-low)\n# PROG_B is not used, so left as input to FTDI.\n#\nftdi layout_init 0x0008 0x004b\nreset_config none\nadapter speed 30000\n\nsource [find cpld/xilinx-xc7.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/numato_opsis.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://opsis.hdmi2usb.tv\n#\n# The Numato Opsis is an FPGA based, open video platform.\n#\n# The board is supported via ixo-usb-jtag project. See the\n# interface/usb-jtag.cfg for more information.\n\nsource [find interface/usb-jtag.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_frdm-k64f.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an NXP Freedom eval board with a single MK64FN1M0VLL12 chip.\n# https://www.nxp.com/design/development-boards/freedom-development-boards/mcu-boards/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F\n#\n\nsource [find interface/cmsis-dap.cfg]\n\n# Set working area to 16 KiB\nset WORKAREASIZE 0x4000\n\nset CHIPNAME k64f\nreset_config srst_only\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_frdm-ls1012a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP FRDM-LS1012A (Freedom)\n#\n\n#\n# NXP Kinetis K20\n#\nsource [find interface/cmsis-dap.cfg]\ntransport select jtag\n\n# Also offers a 10-pin 0.05\" CoreSight JTAG connector.\n\nsource [find target/ls1012a.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_imx7sabre.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP IMX7SABRE board\n# use on-board JTAG header\ntransport select jtag\n\n# set a safe speed, can be overridden\nadapter speed 1000\n\n# reset configuration has TRST and SRST support\nreset_config trst_and_srst srst_push_pull\n# need at least 100ms delay after SRST release for JTAG\nadapter srst delay 100\n\n# source the target file\nsource [find target/imx7.cfg]\n# import mrw proc\nsource [find mem_helper.tcl]\n\n# function to disable the on-chip watchdog\nproc imx7_disable_wdog { } {\n        # echo \"disable watchdog power-down counter\"\n        mwh phys 0x30280008 0x00\n}\n\nproc imx7_uart_dbgconf { } {\n\t# disable response to debug_req signal for uart1\n\tmww phys 0x308600b4 0x0a60\n}\n\nproc check_bits_set_32 { addr mask } {\n    while { [expr {[mrw $addr] & $mask} == 0] } { }\n}\n\nproc apply_dcd { } {\n    # echo \"apply dcd\"\n\n    mww phys 0x30340004 0x4F400005\n    # Clear then set bit30 to ensure exit from DDR retention\n    mww phys 0x30360388 0x40000000\n    mww phys 0x30360384 0x40000000\n\n    mww phys 0x30391000 0x00000002\n    mww phys 0x307a0000 0x01040001\n    mww phys 0x307a01a0 0x80400003\n    mww phys 0x307a01a4 0x00100020\n    mww phys 0x307a01a8 0x80100004\n    mww phys 0x307a0064 0x00400046\n    mww phys 0x307a0490 0x00000001\n    mww phys 0x307a00d0 0x00020083\n    mww phys 0x307a00d4 0x00690000\n    mww phys 0x307a00dc 0x09300004\n    mww phys 0x307a00e0 0x04080000\n    mww phys 0x307a00e4 0x00100004\n    mww phys 0x307a00f4 0x0000033f\n    mww phys 0x307a0100 0x09081109\n    mww phys 0x307a0104 0x0007020d\n    mww phys 0x307a0108 0x03040407\n    mww phys 0x307a010c 0x00002006\n    mww phys 0x307a0110 0x04020205\n    mww phys 0x307a0114 0x03030202\n    mww phys 0x307a0120 0x00000803\n    mww phys 0x307a0180 0x00800020\n    mww phys 0x307a0184 0x02000100\n    mww phys 0x307a0190 0x02098204\n    mww phys 0x307a0194 0x00030303\n    mww phys 0x307a0200 0x00000016\n    mww phys 0x307a0204 0x00171717\n    mww phys 0x307a0214 0x04040404\n    mww phys 0x307a0218 0x0f040404\n    mww phys 0x307a0240 0x06000604\n    mww phys 0x307a0244 0x00000001\n    mww phys 0x30391000 0x00000000\n    mww phys 0x30790000 0x17420f40\n    mww phys 0x30790004 0x10210100\n    mww phys 0x30790010 0x00060807\n    mww phys 0x307900b0 0x1010007e\n    mww phys 0x3079009c 0x00000d6e\n    mww phys 0x30790020 0x08080808\n    mww phys 0x30790030 0x08080808\n    mww phys 0x30790050 0x01000010\n    mww phys 0x30790050 0x00000010\n\n    mww phys 0x307900c0 0x0e407304\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e447306\n\n    check_bits_set_32 0x307900c4 0x1\n\n    mww phys 0x307900c0 0x0e447304\n    mww phys 0x307900c0 0x0e407304\n\n\n    mww phys 0x30384130 0x00000000\n    mww phys 0x30340020 0x00000178\n    mww phys 0x30384130 0x00000002\n    mww phys 0x30790018 0x0000000f\n\n    check_bits_set_32 0x307a0004 0x1\n}\n\n# disable internal reset-assert handling to\n# allow reset-init to work\n$_TARGETNAME.0 configure -event reset-assert \"\"\n$_TARGETNAME.1 configure -event reset-assert \"\"\n$_TARGETNAME_2 configure -event reset-assert \"\"\n\n$_TARGETNAME.0 configure -event reset-init {\n    global _CHIPNAME\n    imx7_disable_wdog\n    imx7_uart_dbgconf\n    apply_dcd\n    $_CHIPNAME.dap memaccess 0\n}\n\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_lpc-link2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP LPC-Link2\n#\n# http://www.nxp.com/board/OM13054.html\n# https://www.lpcware.com/lpclink2\n# http://embeddedartists.com/products/lpcxpresso/lpclink2.php\n#\n\nsource [find target/lpc4370.cfg]\n\n# W25Q80BVSSIG w/ 1 MB flash\nflash bank SPIFI_FLASH lpcspifi 0x14000000 0 0 0 $_CHIPNAME.m4\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_mcimx8m-evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# configuration file for NXP MC-IMX8M-EVK\n#\n\n# only JTAG supported\ntransport select jtag\n\n# set a safe JTAG clock speed, can be overridden\nadapter speed 1000\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\n# board has an i.MX8MQ with 4 Cortex-A53 cores\nset CHIPNAME imx8mq\nset CHIPCORES 4\n\n# source SoC configuration\nsource [find target/imx8m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_rdb-ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046ARDB (Reference Design Board)\n# This is for the \"console\" USB port on the front panel\n# You must ensure that SW4-7 is in the \"off\" position\n\n# NXP K20\n# The firmware implements the old CMSIS-DAP v1 USB HID interface\n# You must pass --enable-cmsis-dap to ./configure to enable it\nsource [find interface/cmsis-dap.cfg]\n\ntransport select jtag\nreset_config srst_only\n\nsource [find target/ls1046a.cfg]\n\n# The adapter can't handle 10MHz\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/nxp_rdb-ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088ARDB (Reference Design Board)\n# This is for the \"main\" JTAG connector J55\n\ntransport select jtag\nreset_config srst_only\n\n# To access the CPLD, populate J48 and add `-c 'set CWTAP 1'` to your command\n# line. At the time of this writing, programming is unsupported.\nif { [info exists CWTAP] } {\n\tsource [find cpld/altera-epm240.cfg]\n} else {\n\tsource [find target/ls1088a.cfg]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_LPC2378STK.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#####################################################\n# Olimex LPC2378STK eval board\n#\n# http://olimex.com/dev/lpc-2378stk.html\n#\n# Author: Sten, debian@sansys-electronic.com\n#####################################################\n#\n\nsource [find target/lpc2378.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_lpc_h2148.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex LPC-H2148 eval board\n#\n# http://www.olimex.com/dev/lpc-h2148.html\n#\n\nsource [find target/lpc2148.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_sam7_ex256.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Olimex SAM7-EX256 has a single Atmel at91sam7ex256 on it.\n\nsource [find target/at91sam7x256.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_sam7_la2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/at91sam7a2.cfg]\n\n# delays needed to get stable reads of cpu state\njtag_ntrst_delay 10\nadapter srst delay 200\n\n# board uses pullup and connects only srst\nreset_config srst_open_drain\n\n# srst is connected to NRESET of CPU and fully resets everything...\nreset_config srst_only srst_pulls_trst\n\nadapter speed 1\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 1\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# init script from http://www.mikrocontroller.net/topic/107462\n\t# AT91SAM7A2\n\t# AMC (advanced memory controller)\n\n\techo \"setting up AMC\"\n\t# AMC_CS0 - FLASH 1MB (0x40000000-0x400FFFFF) + DM9000E (0x40100000)\n\tmww 0xFFE00000 0x40003EBD\n\n\t# AMC_CS1 - RAM low 2MB (0x40400000-0x405FFFFF)\n\tmww 0xFFE00004 0x404030A9\n\n\t# AMC_CS2 - RAM high 2MB (0x40800000-0x405FFFFF)\n\t#mww 0xFFE00008 0x404030A9\n\t# changed to  0x40_8_\n\tmww 0xFFE00008 0x408030A9\n\n\t# AMC_MCR\n\tmww 0xFFE00024 0x00000004\n\n\t# AMC_RCR force remap\n\tmww 0xFFE00020 0x00000001\n\n\techo \"set up AMC\"\n\tsleep 100\n\n\t# the following base addresses from the original script did not correspond to those from datasheet\n\t# changed bases from 0xFF000000 to 0xFFF00000\n\n\t# disable watchdog, to prevent unwanted resets\n\tmww 0xFFFA0068 0x00000000\n\techo \"disabled watchdog\"\n\n\tsleep 50\n\n\t# disable PLL\n\tmww 0xFFFEC004 0x18070004\n\n\t# PLL = 10 ==> Coreclock = 6Mhz*10/2 = 30 Mhz\n\tmww 0xFFFEC010 0x762D800A\n\n\t# enable PLL\n\tmww 0xFFFEC000 0x23050004\n\techo \"set up pll\"\n\n\tsleep 100\n\tadapter speed 5000\n}\n\n$_TARGETNAME arm7_9 dcc_downloads enable\n$_TARGETNAME arm7_9 fast_memory_access enable\n\n# remap:  ram at 0, flash at 0x40000000, like reset-init above does\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\nflash bank onboard.flash cfi 0x40000000 0x00100000 2 2 at91sam7a2.cpu\n\n# boot: ram at 0x300000, flash at 0x0, useful if board is in funny configuration\n#$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n#flash bank onboard1.flash cfi 0x00000000 0x00100000 2 2 at91sam7a2.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_sam9_l9260.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Olimex SAM9-L9260 Development Board\n#\n# http://www.olimex.com/dev/sam9-L9260.html\n#\n# Atmel AT91SAM9260 : PLLA = 198.656 MHz, MCK = 99.328 MHz\n#                     PMC configured for external 18.432 MHz crystal\n#\n# 32-bit SDRAM : 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks\n# 8-bit NAND Flash : 1 x Samsung K9F4G08U0M, 512M x 8Bit\n# Dataflash : 1 x Atmel AT45DB161D, 16Mbit\n#\n################################################################################\n\nsource [find target/at91sam9260.cfg]\n\n# NTRST_E jumper is enabled by default, so we don't need to override the reset\n# config.\n#reset_config srst_only\n\n$_TARGETNAME configure -event reset-start {\n\t# At reset, CPU runs at 32.768 kHz.  JTAG frequency must be 6 times slower if\n\t# RCLK is not supported.\n\tjtag_rclk 5\n\thalt\n\n\t# RSTC_MR : enable user reset, reset length is 64 slow clock cycles.  MMU may\n\t# be enabled... use physical address.\n\tmww phys 0xfffffd08 0xa5000501\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0xfffffd44 0x00008000 ;# WDT_MR : disable watchdog\n\n\t##\n\t# Clock configuration for 99.328 MHz main clock.\n\t##\n    echo \"Setting up clock\"\n\tmww 0xfffffc20 0x00004001 ;# CKGR_MOR : enable main oscillator, 512 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 15.6 ms for startup)\n\tmww 0xfffffc30 0x00000001 ;# PMC_MCKR : switch to main oscillator (18.432 MHz)\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09 ;# CKGR_PLLAR : 18.432 MHz / 9 * 97 = 198.656 MHz, 63 slow clock startup\n\tsleep 20                  ;# wait 20 ms (need 1.9 ms for startup)\n\tmww 0xfffffc30 0x00000101 ;# PMC_MCKR : no scale on proc clock, master is proc / 2\n\tsleep 10                  ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102 ;# PMC_MCKR : switch to PLLA (99.328 MHz)\n\n\t# Increase JTAG speed to 6 MHz if RCLK is not supported.\n\tjtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable ;# Enable faster DCC downloads.\n\n\t##\n\t# SDRAM configuration for 2 x Samsung K4S561632J-UC75, 4M x 16Bit x 4 Banks.\n\t##\n    echo \"Configuring SDRAM\"\n\tmww 0xfffff870 0xffff0000 ;# PIOC_ASR : select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000 ;# PIOC_PDR : disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x00010002 ;# EBI_CSA : assign EBI CS1 to SDRAM, VDDIOMSEL set for +3V3 memory\n\n\tmww 0xffffea08 0x85237259 ;# SDRAMC_CR : configure SDRAM for Samsung chips\n\n\tmww 0xffffea00 0x1        ;# SDRAMC_MR : issue NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2        ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4        ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3        ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0        ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\n\tmww 0xffffea04 0x2b6      ;# SDRAMC_TR : set refresh timer count to 7 us\n\n    ##\n    # NAND Flash Configuration for 1 x Samsung K9F4G08U0M, 512M x 8Bit.\n    ##\n    echo \"Configuring NAND flash\"\n    mww 0xfffffc10 0x00000010 ;# PMC_PCER : enable PIOC clock\n    mww 0xfffff800 0x00006000 ;# PIOC_PER : enable PIO function for 13(RDY/~BSY) and 14(~CS)\n    mww 0xfffff810 0x00004000 ;# PIOC_OER : enable output on 14\n    mww 0xfffff814 0x00002000 ;# PIOC_ODR : disable output on 13\n    mww 0xfffff830 0x00004000 ;# PIOC_SODR : set 14 to disable NAND\n    mww 0xfffff864 0x00002000 ;# PIOC_PUER : enable pull-up on 13\n\n    mww 0xffffef1c 0x0001000A ;# EBI_CSA : assign EBI CS3 to NAND, same settings as before\n\n    mww 0xffffec30 0x00010001 ;# SMC_SETUP3 : 1 clock cycle setup for NRD and NWE\n    mww 0xffffec34 0x03030303 ;# SMC_PULSE3 : 3 clock cycle pulse for all signals\n    mww 0xffffec38 0x00050005 ;# SMC_CYCLE3 : 5 clock cycle NRD and NWE cycle\n    mww 0xffffec3C 0x00020003 ;# SMC_MODE3 : NRD and NWE control, no NWAIT, 8-bit DBW,\n                               #             3 TDF cycles, no optimization\n\n    mww 0xffffe800 0x00000001 ;# ECC_CR : reset the ECC parity registers\n    mww 0xffffe804 0x00000002 ;# ECC_MR : page size is 2112 words (word is 8 bits)\n\n    nand probe at91sam9260.flash\n\n    ##\n    # Dataflash configuration for 1 x Atmel AT45DB161D, 16Mbit\n    ##\n    echo \"Setting up dataflash\"\n    mww 0xfffff404 0x00000807 ;# PIOA_PDR : disable PIO function for 0(SPI0_MISO), 1(SPI0_MOSI),\n                               #            2(SPI0_SPCK), and 11(SPI0_NPCS1)\n    mww 0xfffff470 0x00000007 ;# PIOA_ASR : select peripheral A function for 0, 1, and 2\n    mww 0xfffff474 0x00000800 ;# PIOA_BSR : select peripheral B function for 11\n    mww 0xfffffc10 0x00001000 ;# PMC_PCER : enable SPI0 clock\n\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : software reset SPI0\n    mww 0xfffc8000 0x00000080 ;# SPI0_CR : again to be sure\n    mww 0xfffc8004 0x000F0011 ;# SPI0_MR : master mode with nothing selected\n\n    mww 0xfffc8034 0x011a0302 ;# SPI0_CSR1 : capture on leading edge, 8-bits/tx. 33MHz baud,\n                               #             250ns delay before SPCK, 250ns b/n tx\n\n    mww 0xfffc8004 0x000D0011 ;# SPI0_MR : same config, select NPCS1\n    mww 0xfffc8000 0x00000001 ;# SPI0_CR : enable SPI0\n}\n\nnand device at91sam9260.flash at91sam9 at91sam9260.cpu 0x40000000 0xffffe800\nat91sam9 cle 0 22\nat91sam9 ale 0 21\nat91sam9 rdy_busy 0 0xfffff800 13\nat91sam9 ce 0 0xfffff800 14\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_stm32_h103.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Olimex STM32-H103 eval board\n# http://olimex.com/dev/stm32-h103.html\n\n# Work-area size (RAM size) = 20kB for STM32F103RB device\nset WORKAREASIZE 0x5000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_stm32_h107.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex STM32-H107\n#\n# http://olimex.com/dev/stm32-h107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_stm32_h405.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Olimex STM32-H405 eval board\n# https://www.olimex.com/Products/ARM/ST/STM32-H405/\n\n# Work-area size (RAM size) = 128kB for STM32F405RG device\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/olimex_stm32_p107.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex STM32-P107\n#\n# http://olimex.com/dev/stm32-p107.html\n#\n\n# Work-area size (RAM size) = 64kB for STM32F107VC device\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/omap2420_h4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OMAP2420 SDP board (\"H4\")\n\nsource [find target/omap2420.cfg]\n\n# NOTE: this assumes you're *NOT* using a TI-14 connector.\nreset_config trst_and_srst separate\n\n# Board configs can vary a *LOT* ... parts, jumpers, etc.\n# This GP board boots from cs0 using NOR (2x32M), and also\n# has 64M NAND on cs6.\nflash bank h4.u10 cfi 0x04000000 0x02000000 2 2 $_TARGETNAME\nflash bank h4.u11 cfi 0x06000000 0x02000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/openrd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Marvell OpenRD\n\nsource [find interface/ftdi/openrd.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc openrd_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x37543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000A33 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000004 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x00120012 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000E40F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc openrd_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\topenrd_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc openrd_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\topenrd_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/or1k_generic.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# If you want to use the VJTAG TAP or the XILINX BSCAN,\n# you must set your FPGA TAP ID here\n\nset FPGATAPID 0x020b30dd\n\n# Choose your TAP core (VJTAG , MOHOR or XILINX_BSCAN)\nif { [info exists TAP_TYPE] == 0} {\n   set TAP_TYPE VJTAG\n}\n\n# Set your chip name\nset CHIPNAME or1200\n\nsource [find target/or1k.cfg]\n\n# Set the servers polling period to 1ms (needed to JSP Server)\npoll_period 1\n\n# Set the adapter speed\nadapter speed 3000\n\n# Enable the target description feature\ngdb_target_description enable\n\n# Add a new register in the cpu register list. This register will be\n# included in the generated target descriptor file.\n# format is addreg [name] [address] [feature] [reg_group]\naddreg rtest 0x1234 org.gnu.gdb.or1k.group0 system\n\n# Override default init_reset\nproc init_reset {mode} {\n\tsoft_reset_halt\n\tresume\n}\n\n# Target initialization\ninit\necho \"Halting processor\"\nhalt\n\nforeach name [target names] {\n\tset y [$name cget -endian]\n\tset z [$name cget -type]\n\tputs [format \"Chip is %s, Endian: %s, type: %s\" \\\n\t      $name $y $z]\n}\n\nset c_blue  \"\\033\\[01;34m\"\nset c_reset \"\\033\\[0m\"\n\nputs [format \"%sTarget ready...%s\" $c_blue $c_reset]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/osk5912.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://omap.spectrumdigital.com/osk5912/\n\nsource [find target/omap5912.cfg]\n\n# NOTE: this assumes you're using the ARM 20-pin (\"Multi-ICE\")\n# JTAG connector, and accordingly have J1 connecting pins 1 & 2.\n# The TI-14 pin needs \"trst_only\", and J1 connecting 2 & 3.\nreset_config trst_and_srst separate\n\n# NOTE:  boards with XOMAP parts wire nSRST to nPWRON_RESET.\n# That resets everything -- including JTAG and EmbeddedICE.\n# So they must use \"reset_config srst_pulls_trst\".\n\n# NOTE:  an expansion board could add a trace connector ... if\n# it does, change this appropriately.  And reset_config too,\n# assuming JTAG_DIS reroutes JTAG to that connector.\netm config $_TARGETNAME 8 demultiplexed full dummy\netm_dummy config $_TARGETNAME\n\n# standard boards populate two 16 MB chips, but manufacturing\n# options or an expansion board could change this config.\nflash bank osk.u1 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\nflash bank osk.u2 cfi 0x01000000 0x01000000 2 2 $_TARGETNAME\n\nproc osk5912_init {} {\n\tomap5912_reset\n\n\t# detect flash\n\tflash probe 0\n\tflash probe 1\n}\n$_TARGETNAME configure -event reset-init { osk5912_init }\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/phone_se_j100i.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Sony Ericsson J100I Phone\n#\n# more information can be found on\n# http://bb.osmocom.org/trac/wiki/SonyEricssonJ100i\n#\nsource [find target/ti_calypso.cfg]\n\n# external flash\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x400000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/phytec_lpc3250.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/lpc3250.cfg]\n\nadapter srst delay 200\njtag_ntrst_delay 1\nadapter speed 200\nreset_config trst_and_srst separate\n\narm7_9 dcc_downloads enable\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n\n$_TARGETNAME configure -event reset-start {\n             arm7_9 fast_memory_access disable\n             adapter speed 200\n}\n\n$_TARGETNAME configure -event reset-end {\n             adapter speed 6000\n             arm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-init { phytec_lpc3250_init }\n\n# Bare-bones initialization of core clocks and SDRAM\nproc phytec_lpc3250_init { } {\n        # Set clock dividers\n        #   ARMCLK = 266.5 MHz\n        #   HCLK   = 133.25 MHz\n        #   PERIPHCLK = 13.325 MHz\n        mww 0x400040BC 0\n        mww 0x40004050 0x140\n        mww 0x40004040 0x4D\n        mww 0x40004058 0x16250\n\n        # Init PLLs\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004044 0x106\n        sleep 1 busy\n        mww 0x40004044 0x006\n        sleep 1 busy\n        mww 0x40004048 0x2\n\n        # Init SDRAM with 133 MHz timings\n        mww 0x40028134 0x00FFFFFF\n        mww 0x4002802C 0x00000008\n\n        mww 0x31080000 1\n        mww 0x31080008 0\n        mww 0x40004068 0x1C000\n        mww 0x31080028 0x11\n\n        mww 0x31080400 0\n        mww 0x31080440 0\n        mww 0x31080460 0\n        mww 0x31080480 0\n\n        # Delays\n        mww 0x31080030 1\n        mww 0x31080034 6\n        mww 0x31080038 10\n        mww 0x31080044 1\n        mww 0x31080048 9\n        mww 0x3108004C 12\n        mww 0x31080050 10\n        mww 0x31080054 1\n        mww 0x31080058 1\n        mww 0x3108005C 0\n\n        mww 0x31080100 0x5680\n        mww 0x31080104 0x302\n\n        # Init sequence\n        mww 0x31080020 0x193\n        sleep 1 busy\n        mww 0x31080024 1\n        mww 0x31080020 0x113\n        sleep 1 busy\n        mww 0x31080020 0x013\n        sleep 1 busy\n        mww 0x31080024 65\n        mww 0x31080020 0x093\n        mdw 0x80020000\n        mww 0x31080020 0x013\n\n        # SYS_CTRL remapping\n        mww 0x40004014 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/pic-p32mx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Olimex PIC-P32MX has a PIC32MX\n\nset CPUTAPID 0x40916053\nsource [find target/pic32mx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/pico-debug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# pico-debug is a virtual CMSIS-DAP debug adapter\n# it runs on the very same RP2040 target being debugged without additional hardware\n# https://github.com/majbthrd/pico-debug\n\nsource [find interface/cmsis-dap.cfg]\nadapter speed 4000\n\nset CHIPNAME rp2040\nsource [find target/rp2040-core0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/pipistrello.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://pipistrello.saanlima.com/\n\nsource [find interface/ftdi/pipistrello.cfg]\nsource [find cpld/xilinx-xc6s.cfg]\nsource [find cpld/jtagspi.cfg]\n\n# example command to write bitstream, soft-cpu bios and runtime:\n# openocd -f board/pipistrello.cfg -c \"init;\\\n# jtagspi_init 0 bscan_spi_xc6slx45.bit;\\\n# jtagspi_program bitstream-pistrello.bin 0;\\\n# jtagspi_program bios.bin 0x170000;\\\n# jtagspi_program runtime.fbi 0x180000;\\\n# xc6s_program xc6s.tap;\\\n# exit\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/propox_mmnet1001.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n## Chip:\nset CHIPNAME at91sam9260\nset CPUTAPID 0x0792603f\nset ENDIAN little\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n\nproc at91sam_init { } {\n\n\t# at reset chip runs at 32 kHz => 1/8 * 32 kHz = 4 kHz\n\tjtag_rclk 4\n\n\t# Enable user reset and disable watchdog\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\t# Oscillator setup\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator (18.432 MHz)\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 18.432 MHz kHz => 1/8 * 18.432 MHz = 2.304 MHz\n\tjtag_rclk 2000\n\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc2c 0x207c3f0c         ;# CKGR_PLLBR: Set PLLB Register for USB usage (USB_CLK = 48 MHz)\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# now we are running at 198.656 MHz kHz => full speed jtag\n\tjtag_rclk 30000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\t# Configure PIO Controller for SDRAM data-lines D16-D31\n\t# PC16-PC31 = Peripheral A: D16-D32\n\tmww 0xfffff844 0xffff0000\t;# Interrupt Disable\n\tmww 0xfffff854 0xffff0000\t;# Multi-Drive Disable\n\tmww 0xfffff860 0xffff0000\t;# Pull-Up Disable\n\tmww 0xfffff870 0xffff0000\t;# PIO_ASR : Select peripheral A function for D15..D31\n\tmww 0xfffff804 0xffff0000\t;# PIO_PDR : Disable PIO function for D15..D31 (Peripheral function enable)\n\tmww 0xfffffc10 0x00000010\t;# Enable PIO-C Clock in PMC (PID=4)\n\n\t# SD-Ram setup\n\tmww 0xffffef1c 0x2\t\t\t;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\tmww 0xffffea08 0x85227259\t;# SDRAMC_CR : Configure SDRAM (IS42S32160A: 4M Words x 32 Bits x 4 Banks (512-Mbit))\n\tmww 0xffffea00 0x1\t\t\t;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2\t\t\t;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (1st)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (2nd)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (3th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (4th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (5th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (6th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (7th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\t\t\t;# SDRAMC_MR : issue an 'Auto-Refresh' command (8th)\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3\t\t\t;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0\t\t\t;# SDRAMC_MR : Normal Mode\n\tmww 0x20000000 0\n\tmww 0xFFFFEA04 0x30d\t\t;# SDRAM Refresh Time Register\n\t\t\t\t\t\t\t\t #  datasheet: 8k refresh cycles / 64 ms\n\t\t\t\t\t\t\t\t #  MCLK / (8*1024 / 64e-3) = 100e6 / 128000 = 781 = 0x30d\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/pxa255_sst.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# A PXA255 test board with SST 39LF400A flash\n#\n# At reset the memory map is as follows. Note that\n# the memory map changes later on as the application\n# starts...\n#\n# RAM at 0x4000000\n# Flash at 0x00000000\n#\nsource [find target/pxa255.cfg]\n\n# Target name is set by above\n$_TARGETNAME configure -work-area-phys 0x4000000 -work-area-size 0x4000 -work-area-backup 0\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width> <target> [options]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x80000 2 2 $_TARGETNAME jedec_probe\n\nproc pxa255_sst_init {} {\n\txscale cp15   15      0x00002001  ;#Enable CP0 and CP13 access\n\t#\n\t# setup GPIO\n\t#\n\tmww    0x40E00018  0x00008000  ;#CPSR0\n\tsleep   20\n\tmww    0x40E0001C  0x00000002  ;#GPSR1\n\tsleep   20\n\tmww    0x40E00020  0x00000008  ;#GPSR2\n\tsleep   20\n\tmww    0x40E0000C  0x00008000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00054  0x80000000  ;#GAFR0_L\n\tsleep   20\n\tmww    0x40E00058  0x00188010  ;#GAFR0_H\n\tsleep   20\n\tmww    0x40E0005C  0x60908018  ;#GAFR1_L\n\tsleep   20\n\tmww    0x40E0000C  0x0280E000  ;#GPDR0\n\tsleep   20\n\tmww    0x40E00010  0x821C88B2  ;#GPDR1\n\tsleep   20\n\tmww    0x40E00014  0x000F03DB  ;#GPDR2\n\tsleep   20\n\tmww    0x40E00000  0x000F03DB  ;#GPLR0\n\tsleep   20\n\n\n\tmww    0x40F00004  0x00000020  ;#PSSR\n\tsleep   20\n\n\t#\n\t# setup memory controller\n\t#\n\tmww    0x48000008  0x01111998  ;#MSC0\n\tsleep   20\n\tmww    0x48000010  0x00047ff0  ;#MSC2\n\tsleep   20\n\tmww    0x48000014  0x00000000  ;#MECR\n\tsleep   20\n\tmww    0x48000028  0x00010504  ;#MCMEM0\n\tsleep   20\n\tmww    0x4800002C  0x00010504  ;#MCMEM1\n\tsleep   20\n\tmww    0x48000030  0x00010504  ;#MCATT0\n\tsleep   20\n\tmww    0x48000034  0x00010504  ;#MCATT1\n\tsleep   20\n\tmww    0x48000038  0x00004715  ;#MCIO0\n\tsleep   20\n\tmww    0x4800003C  0x00004715  ;#MCIO1\n\tsleep   20\n\t#\n\tmww    0x48000004  0x03CA4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x004B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000B4018  ;#MDREF\n\tsleep   20\n\tmww    0x48000004  0x000BC018  ;#MDREF\n\tsleep   20\n\tmww    0x48000000  0x00001AC8  ;#MDCNFG\n\tsleep   20\n\n\tsleep   20\n\n\tmww    0x48000000  0x00001AC9  ;#MDCNFG\n\tsleep   20\n\tmww    0x48000040  0x00000000  ;#MDMRS\n\tsleep   20\n}\n\n$_TARGETNAME configure -event reset-init {pxa255_sst_init}\n\nreset_config trst_and_srst\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n#xscale debug_handler 0  0xFFFF0800      ;# debug handler base address\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/quark_d2000_refboard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Quark microcontroller D2000 Reference Board (web search for doc num 333582)\n\n# the board has an onboard FTDI FT232H chip\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\n\nftdi layout_init 0x0000 0x030b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0100\n\nsource [find target/quark_d20xx.cfg]\n\nadapter speed 1000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/quark_x10xx_board.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# There are many Quark boards that can host the quark_x10xx SoC\n# Galileo is an example board\n\nsource [find target/quark_x10xx.cfg]\n\n#default frequency but this can be adjusted at runtime\nadapter speed 4000\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/quicklogic_quickfeather.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3 QuickFeather\n# https://www.quicklogic.com/products/eos-s3/quickfeather-development-kit/\n\nsource [find target/eos_s3.cfg]\n\nreset_config srst_only\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Radiona ULX3S\n# https://radiona.org/ulx3s/\n# Currently there are following board variants:\n# CS-ULX3S-01 - LFE5U 12F\n# CS-ULX3S-02 - LFE5U 45F\n# CS-ULX3S-03 - LFE5U 85F\n#\n# two JTAG interfaces:\n# - US1, micro USB port connected to FT231XQ\n#   This interface should be used with following config:\n#        interface/ft232r/radiona_ulx3s.cfg\n# - J4, 6 pin connector\n#\n# Both of this interfaces share the JTAG lines (TDI, TMS, TCK, TDO) between\n# Lattice ECP5 FPGA chip and ESP32 WiFi controller.\n# Note: TRST_N of the ESP32 is pulled up by default and can be pulled down over\n# J3 interface.\n# See schematics for more information:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v308.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v314.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v315.pdf\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nsource [find interface/ft232r/radiona_ulx3s.cfg]\nsource [find fpga/lattice_ecp5.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/redbee.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/mc13224v.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/reflexces_achilles_i-dev_kit_arria10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Achilles Instant-Development Kit Arria 10 SoC SoM\n# https://www.reflexces.com/products-solutions/achilles-instant-development-kit-arria-10-soc-som\n#\n\nif { [info exists USE_EXTERNAL_DEBUGGER] } {\n\techo \"Using external debugger\"\n} else {\n\tsource [find interface/altera-usb-blaster2.cfg]\n\tusb_blaster device_desc \"Arria10 IDK\"\n}\n\nsource [find fpga/altera-10m50.cfg]\nsource [find target/altera_fpgasoc_arria10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_dk-s7g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Renesas Synergy DK-S7G2\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# XXX 19-pin SWD+TRACE connector also available\n\n# Synergy R7FS7G27H2A01CBD\nsource [find target/renesas_s7g2.cfg]\n\n# 32 MB QSPI flash (Micron N25Q256A13EF840E)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_falcon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Renesas R-Car V3U Falcon Board Config\n\n# The Falcon board comes with either an V3U SOC.\n\necho \"\\nFalcon:\"\nif { ![info exists SOC] } {\n\tset SOC V3U\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_gr_peach.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/A1H GR-Peach board\n\nreset_config srst_only\n\nsource [find target/renesas_r7s72100.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_porter.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car M2 Evaluation Board\n\nset SOC M2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_salvator-xs.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car Gen3 Salvator-X(S) Board Config\n\n# The Salvator-X(S) boards come with either an H3, M3W, or M3N SOC.\n\necho \"\\nSalvator-X(S):\"\nif { ![info exists SOC] } {\n\tset SOC H3\n}\nsource [find target/renesas_rcar_gen3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_silk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car E2 Evaluation Board\n\nset SOC E2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/renesas_stout.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car H2 Evaluation Board\n\nset SOC H2\nsource [find target/renesas_rcar_gen2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/rigado_bmd300_ek.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Rigado BMD-300 Evaluation Kit\n#\n# https://www.rigado.com/products/modules/bmd-300/\n#\n\nsource [find interface/jlink.cfg]\ntransport select swd\nadapter speed 1000\n\nsource [find target/nrf52.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/rpi3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 3 board with BCM2837 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2837.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/rpi4b.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Raspberry Pi 4 model B board with BCM2711 chip\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/README.md\n#\n# Enable JTAG GPIO on Raspberry Pi boards\n# https://www.raspberrypi.org/documentation/configuration/config-txt/gpio.md\n\nsource [find target/bcm2711.cfg]\ntransport select jtag\n\n# Raspberry Pi boards only expose Test Reset (TRST) pin, no System Reset (SRST)\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/rsc-w910.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Avalue RSC-W8910 sbc\n# http://www.avalue.com.tw/products/RSC-W910.cfm\n# 2MB NOR Flash\n# 64MB SDRAM\n# 128MB NAND Flash\n\n# Based on Nuvoton nuc910\nsource [find target/nuc910.cfg]\n\n#\n# reset only behaves correctly if we use srst_pulls_trst\n#\nreset_config trst_and_srst srst_pulls_trst\n\nadapter speed 1000\nadapter srst delay 100\njtag_ntrst_delay 100\n\n$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x04000000 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x00200000 2 2 $_TARGETNAME\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME nuc910 $_TARGETNAME\n\n#\n# Target events\n#\n\n$_TARGETNAME configure -event reset-start {adapter speed 1000}\n\n$_TARGETNAME configure -event reset-init {\n\t# switch on PLL for 200MHz operation\n\t# running from 15MHz input clock\n\n\tmww 0xB0000200 0x00000030 ;# CLKEN\n\tmww 0xB0000204 0x00000f3c ;# CLKSEL\n\tmww 0xB0000208 0x05007000 ;# CLKDIV\n\tmww 0xB000020C 0x00004f24 ;# PLLCON0\n\tmww 0xB0000210 0x00002b63 ;# PLLCON1\n\tmww 0xB000000C 0x08817fa6 ;# MFSEL\n\tsleep 10\n\n\t# we are now running @ 200MHz\n\t# enable all openocd speed tweaks\n\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n\tadapter speed 15000\n\n\t# map nor flash to 0x20000000\n\t# map sdram to 0x00000000\n\n\tmww 0xb0001000 0x000530c1 ;# EBICON\n\tmww 0xb0001004 0x40030084 ;# ROMCON\n\tmww 0xb0001008 0x000010ee ;# SDCONF0\n\tmww 0xb000100C 0x00000000 ;# SDCONF1\n\tmww 0xb0001010 0x0000015b ;# SDTIME0\n\tmww 0xb0001014 0x0000015b ;# SDTIME1\n\tmww 0xb0001018 0x00000000 ;# EXT0CON\n\tmww 0xb000101C 0x00000000 ;# EXT1CON\n\tmww 0xb0001020 0x00000000 ;# EXT2CON\n\tmww 0xb0001024 0x00000000 ;# EXT3CON\n\tmww 0xb000102c 0x00ff0048 ;# CKSKEW\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sayma_amc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Sayma AMC is an FPGA board for the µTCA AMC format\n# The board is open hardware (CERN OHL) and the gateware and software\n# running on it are open source (ARTIQ, LGPLv3+).\n#\n# https://github.com/m-labs/sinara/wiki/Sayma\n#\n# It contains a Xilinx Kintex Ultrascale 040 FPGA (xcku040).\n# There is a SCANSTA112SM JTAG router on the board which is configured to\n# automatically add devices to the JTAG svcan chain when they are added.\n# Sayma AMC is usually combined with Sayma RTM (rear transition module)\n# which features an Artix 7 FPGA.\n\nadapter driver ftdi\nftdi device_desc \"Quad RS232-HS\"\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n# Use this to distinguish multiple boards by topology\n#adapter usb location 5:1\n# sampling on falling edge generally seems to work and accelerates things but\n# is not fully tested\n#ftdi tdo_sample_edge falling\n# EN_USB_JTAG on ADBUS7: out, high\n# USB_nTRST on ADBUS4: out, high, but R46 is DNP\nftdi layout_init 0x0098 0x008b\n#ftdi layout_signal EN_USB -data 0x0080\n#ftdi layout_signal nTRST -data 0x0010\nreset_config none\n\nadapter speed 5000\n\ntransport select jtag\n\n# Add the RTM Artix to the chain. Note that this changes the PLD numbering.\n# Unfortunately openocd TAPs can't be disabled after they have been added and\n# before `init`.\n#source [find cpld/xilinx-xc7.cfg]\n\nset CHIP XCKU040\nsource [find cpld/xilinx-xcu.cfg]\n\nset XILINX_USER1 0x02\nset XILINX_USER2 0x03\nset JTAGSPI_IR $XILINX_USER1\nsource [find cpld/jtagspi.cfg]\nflash bank xcu.spi1 jtagspi 0 0 0 0 xcu.proxy $XILINX_USER2\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sheevaplug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Marvell SheevaPlug\n\nsource [find interface/ftdi/sheevaplug.cfg]\nsource [find target/feroceon.cfg]\n\nadapter speed 2000\n\n$_TARGETNAME configure \\\n\t-work-area-phys 0x10000000 \\\n\t-work-area-size 65536 \\\n\t-work-area-backup 0\n\narm7_9 dcc_downloads enable\n\n# this assumes the hardware default peripherals location before u-Boot moves it\nset _FLASHNAME $_CHIPNAME.flash\nnand device $_FLASHNAME orion 0 0xd8000000\n\nproc sheevaplug_init { } {\n\n\t# We need to assert DBGRQ while holding nSRST down.\n\t# However DBGACK will be set only when nSRST is released.\n\t# Furthermore, the JTAG interface doesn't respond at all when\n\t# the CPU is in the WFI (wait for interrupts) state, so it is\n\t# possible that initial tap examination failed.  So let's\n\t# re-examine the target again here when nSRST is asserted which\n\t# should then succeed.\n\tadapter assert srst\n\tferoceon.cpu arp_examine\n\thalt 0\n\tadapter deassert srst\n\twait_halt\n\n\tarm mcr 15 0 0 1 0 0x00052078\n\n\tmww 0xD0001400 0x43000C30 ;#  DDR SDRAM Configuration Register\n\tmww 0xD0001404 0x39543000 ;#  Dunit Control Low Register\n\tmww 0xD0001408 0x22125451 ;#  DDR SDRAM Timing (Low) Register\n\tmww 0xD000140C 0x00000833 ;#  DDR SDRAM Timing (High) Register\n\tmww 0xD0001410 0x000000CC ;#  DDR SDRAM Address Control Register\n\tmww 0xD0001414 0x00000000 ;#  DDR SDRAM Open Pages Control Register\n\tmww 0xD0001418 0x00000000 ;#  DDR SDRAM Operation Register\n\tmww 0xD000141C 0x00000C52 ;#  DDR SDRAM Mode Register\n\tmww 0xD0001420 0x00000042 ;#  DDR SDRAM Extended Mode Register\n\tmww 0xD0001424 0x0000F17F ;#  Dunit Control High Register\n\tmww 0xD0001428 0x00085520 ;#  Dunit Control High Register\n\tmww 0xD000147c 0x00008552 ;#  Dunit Control High Register\n\tmww 0xD0001504 0x0FFFFFF1 ;#  CS0n Size Register\n\tmww 0xD0001508 0x10000000 ;#  CS1n Base Register\n\tmww 0xD000150C 0x0FFFFFF5 ;#  CS1n Size Register\n\tmww 0xD0001514 0x00000000 ;#  CS2n Size Register\n\tmww 0xD000151C 0x00000000 ;#  CS3n Size Register\n\tmww 0xD0001494 0x003C0000 ;#  DDR2 SDRAM ODT Control (Low) Register\n\tmww 0xD0001498 0x00000000 ;#  DDR2 SDRAM ODT Control (High) REgister\n\tmww 0xD000149C 0x0000F80F ;#  DDR2 Dunit ODT Control Register\n\tmww 0xD0001480 0x00000001 ;#  DDR SDRAM Initialization Control Register\n\tmww 0xD0020204 0x00000000 ;#  Main IRQ Interrupt Mask Register\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\tmww 0xD0020204 0x00000000 ;#              \"\n\n\tmww 0xD0010000 0x01111111 ;#  MPP  0 to 7\n\tmww 0xD0010004 0x11113322 ;#  MPP  8 to 15\n\tmww 0xD0010008 0x00001111 ;#  MPP 16 to 23\n\n\tmww 0xD0010418 0x003E07CF ;#  NAND Read Parameters REgister\n\tmww 0xD001041C 0x000F0F0F ;#  NAND Write Parameters Register\n\tmww 0xD0010470 0x01C7D943 ;#  NAND Flash Control Register\n\n}\n\nproc sheevaplug_reflash_uboot { } {\n\n\t# reflash the u-Boot binary and reboot into it\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0x0 0xa0000\n\tnand write 0 uboot.bin 0 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_reflash_uboot_env { } {\n\n\t# reflash the u-Boot environment variables area\n\tsheevaplug_init\n\tnand probe 0\n\tnand erase 0 0xa0000 0x40000\n\tnand write 0 uboot-env.bin 0xa0000 oob_softecc_kw\n\tresume\n\n}\n\nproc sheevaplug_load_uboot { } {\n\n\t# load u-Boot into RAM and execute it\n\tsheevaplug_init\n\tload_image uboot.elf\n\tverify_image uboot.elf\n\tresume 0x00600000\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sifive-e31arty.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e31arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sifive-e51arty.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Be sure you include the speed and interface before this file\n# Example:\n# -c \"adapter speed 5000\" -f \"interface/ftdi/olimex-arm-usb-tiny-h.cfg\" -f \"board/sifive-e51arty.cfg\"\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000001\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank spi0 fespi 0x40000000 0 0 0 $_TARGETNAME.0 0x20004000\ninit\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n}\nhalt\nflash protect 0 64 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sifive-hifive1-revb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter speed 4000\n\nadapter driver jlink\ntransport select jtag\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME\n$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 0\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME.0\n\ninit\n\njlink jtag 3\n\nhalt\nflash protect 0 1 last off\necho \"Ready for Remote Connections\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/sifive-hifive1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter speed     10000\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nSRST -oe 0x0020 -data 0x0020\n\n#Reset Stretcher logic on FE310 is ~1 second long\n#This doesn't apply if you use\n# ftdi set_signal, but still good to document\n#adapter srst delay 1500\n\nset _CHIPNAME riscv\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1\n\nflash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME\ninit\n#reset -- This type of reset is not implemented yet\nif {[ info exists pulse_srst]} {\n  ftdi set_signal nSRST 0\n  ftdi set_signal nSRST z\n  #Wait for the reset stretcher\n  #It will work without this, but\n  #will incur lots of delays for later commands.\n  sleep 1500\n}\nhalt\nflash protect 0 64 last off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/smdk6410.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nsource [find target/samsung_s3c6410.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x00000000 0x00100000 2 2 $_TARGETNAME jedec_probe\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/snps_em_sk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.x\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# 5MHz seems to work good with all cores that might happen in 2.x\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/snps_em_sk_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v1.0 and v1.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\nadapter speed 10000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/snps_em_sk_v2.1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2014-2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.1\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# JTAG 10MHz is too fast for EM7D FPU in EM SK 2.1 which has core frequency\n# 20MHz. 7.5 MHz seems to work fine.\nadapter speed 7500\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/snps_em_sk_v2.2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2016,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys DesignWare ARC EM Starter Kit v2.2\n#\n\n# Configure JTAG cable\n# EM Starter Kit has built-in FT2232 chip, which is similar to Digilent HS-1.\nsource [find interface/ftdi/digilent-hs1.cfg]\n\n# EM11D reportedly requires 5 MHz. Other cores and board can work faster.\nadapter speed 5000\n\n# ARCs support only JTAG.\ntransport select jtag\n\n# Configure FPGA. This script supports both LX45 and LX150.\nsource [find target/snps_em_sk_fpga.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/snps_hsdk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2019, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys DesignWare ARC HSDK Software Development Platform (HS38 cores)\n#\n\nsource [find interface/ftdi/snps_sdp.cfg]\nadapter speed 10000\n\n# ARCs supports only JTAG.\ntransport select jtag\n\n# Configure SoC\nsource [find target/snps_hsdk.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spansion_sk-fm4-176l-s6e2cc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Spansion SK-FM4-176L-S6E2CC\n#\n\n#\n# FM3 MB9AF312K\n#\nsource [find interface/cmsis-dap.cfg]\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\n#\n# FM4 S6E2CCAJ0A w/ 192 KB SRAM0\n#\nset CHIPNAME s6e2cc\nset CHIPSERIES S6E2CCAJ0A\nset WORKAREASIZE 0x30000\nsource [find target/fm4_s6e2cc.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spansion_sk-fm4-u120-9b560.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Spansion SK-FM4-U120-9B560\n#\n\n#\n# FM3 MB9AF312K\n#\n# source [find interface/cmsis-dap.cfg]\n\n#\n# FM4 MB9BF568R w/ 64 KB SRAM0\n#\nset CHIPNAME mb9bf568\nset CHIPSERIES MB9BF568R\nset WORKAREASIZE 0x10000\nsource [find target/fm4_mb9bf.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear300evb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0\n# http://www.st.com/spear\n#\n# Date:      2010-11-27\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear300evb_init }\n\nproc spear300evb_init {} {\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp300_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear300evb_mod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr300 Evaluation board\n# EVALSPEAr300 Rev. 1.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the top layer:\n#    1. replace reset chip U4 with a STM6315SDW13F;\n# - Modifications on the bottom layer:\n#    2. add 0 ohm resistor R10. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 and solder it between R10 and R54:\n# - one pad soldered with the pad of R54 connected to 3.3V (this\n#   is the pad of R54 far from JTAG connector J4)\n# - the other pad soldered with the nearest pad of R10.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear300evb.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear310evb20.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n#\n# Check ST Application Note AN3321 on how to fix SRST on\n# the board, then use the script board/spear310evb20_mod.cfg\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n# CFI parallel NOR on EMI CS0. 2x 16bit 8M devices = 16Mbyte.\nset _FLASHNAME0 $_CHIPNAME.pnor\nflash bank $_FLASHNAME0 cfi 0x50000000 0x01000000 2 4 $_TARGETNAME\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear310evb20_init }\n\nproc spear310evb20_init {} {\n\treg pc 0xffff0020\t;# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\"\n\tsp310_init\n\tsp310_emi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear310evb20_mod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr310 Evaluation board\n# EVALSPEAr310 Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note AN3321.\n# - Modifications on the top layer:\n#    1. remove R137 and C57, located near the SMII PHY U18;\n#    2. remove R172 and C75, located near the SMII PHY U19;\n#    3. remove R207 and C90, located near the SMII PHY U20;\n#    4. remove C236, located near the SMII PHY U21;\n#    5. remove U12, located near the JTAG connector;\n#    6. solder together pins 7, 8 and 9 of U12;\n#    7. solder together pins 11, 12, 13, 14, 15, 16, 17 and 18 of U12.\n# - Modifications on the bottom layer:\n#    8. replace reset chip U11 with a STM6315SDW13F;\n#    9. add 0 ohm resistor R329. It is located close to JTAG connector.\n#\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear310evb20.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear320cpu.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr320 CPU board\n# EVAL_SPEAr320CPU Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# The standard board has JTAG SRST not connected.\n# This script targets such boards using quirky code to bypass the issue.\n\n\nsource [find mem_helper.tcl]\nsource [find target/spear3xx.cfg]\nsource [find chip/st/spear/spear3xx_ddr.tcl]\nsource [find chip/st/spear/spear3xx.tcl]\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n\n# Serial NOR on SMI CS0. 8Mbyte.\nset _FLASHNAME1 $_CHIPNAME.snor\nflash bank $_FLASHNAME1 stmsmi 0xf8000000 0 0 0 $_TARGETNAME\n\nif { [info exists BOARD_HAS_SRST] } {\n\t# Modified board has SRST on JTAG connector\n\treset_config trst_and_srst separate srst_gates_jtag \\\n\t\ttrst_push_pull srst_open_drain\n} else {\n\t# Standard board has no SRST on JTAG connector\n\treset_config trst_only separate srst_gates_jtag trst_push_pull\n\tsource [find chip/st/spear/quirk_no_srst.tcl]\n}\n\n$_TARGETNAME configure -event reset-init { spear320cpu_init }\n\nif { [info exists DDR_CHIPS] } {\n        set _DDR_CHIPS $DDR_CHIPS\n} else {\n        set _DDR_CHIPS 1\n}\n\nproc spear320cpu_init {} {\n\tglobal _DDR_CHIPS\n\treg pc 0xffff0020;\t# loop forever\n\n\tsp3xx_clock_default\n\tsp3xx_common_init\n\tsp3xx_ddr_init \"mt47h64m16_3_333_cl5_async\" $_DDR_CHIPS\n\tsp320_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/spear320cpu_mod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Configuration for the ST SPEAr320 Evaluation board\n# EVAL_SPEAr320CPU Rev. 2.0, modified to enable SRST on JTAG connector\n# http://www.st.com/spear\n#\n# List of board modifications to enable SRST, as reported in\n# ST Application Note (FIXME: add reference).\n# - Modifications on the bottom layer:\n#    1. replace reset chip U7 with a STM6315SDW13F;\n#    2. add 0 ohm resistor R45. It is located close to JTAG connector.\n#    3. add a 10K ohm pull-up resistor on the reset wire named as\n#       POWERGOOD in the schematic.\n#\n# The easier way to do modification 3, is to use a resistor in package\n# 0603 or 0402 and solder it between R15 and R45:\n# - one pad soldered with the pad of R15 connected to 3.3V (this\n#   is the pad of R15 closer to R45)\n# - the other pad soldered with the nearest pad of R45.\n#\n# Date:      2011-11-18\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Modified boards has SRST on JTAG connector\nset BOARD_HAS_SRST 1\nsource [find board/spear320cpu.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_b-l475e-iot01a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an B-L475E-IOT01A Discovery kit for IoT node with a single STM32L475VGT6 chip.\n# http://www.st.com/en/evaluation-tools/b-l475e-iot01a.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000\t;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_8l152r8.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a ST NUCLEO 8L152R8 board with a single STM8L152R8T6 chip.\n# http://www.st.com/en/evaluation-tools/nucleo-8l152r8.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\nsource [find target/stm8l15xx8.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_8s208rb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a ST NUCLEO 8S208RB board with a single STM8S208RBT6 chip.\n# https://www.st.com/en/evaluation-tools/nucleo-8s208rb.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select swim\n\n# 128 KiB flash and 2 KiB EEPROM\nset FLASHEND 0x27fff\nset EEPROMEND 0x47ff\n\nsource [find target/stm8s.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_f0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32F0. Known boards at the moment:\n# STM32F030R8\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# NUCLEO-F072RB\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259997\n# STM32F091RC\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260944\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_f103rb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO F103RB board with a single STM32F103RBT6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF259875\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_f3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO F334R8 board with a single STM32F334R8T6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260004\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_f4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32F4. Known boards at the moment:\n# STM32F401RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260000\n# STM32F411RET6\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260320\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_f7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STMicroelectronics STM32F7 Nucleo development board\n# Known boards: NUCLEO-F746ZG and NUCLEO-F767ZI\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_g0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G0. Known boards at the moment:\n# NUCLEO-G031K8\n# https://www.st.com/en/evaluation-tools/nucleo-g031k8.html\n# NUCLEO-G070RB\n# https://www.st.com/en/evaluation-tools/nucleo-g070rb.html\n# NUCLEO-G071RB\n# https://www.st.com/en/evaluation-tools/nucleo-g071rb.html\n# NUCLEO-G0B1RE\n# https://www.st.com/en/evaluation-tools/nucleo-g0b1re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_g4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for all ST NUCLEO with any STM32G4. Known boards at the moment:\n# NUCLEO-G431KB\n# https://www.st.com/en/evaluation-tools/nucleo-g431kb.html\n# NUCLEO-G431RB\n# https://www.st.com/en/evaluation-tools/nucleo-g431rb.html\n# NUCLEO-G474RE\n# https://www.st.com/en/evaluation-tools/nucleo-g474re.html\n# NUCLEO-G491RE\n# https://www.st.com/en/evaluation-tools/nucleo-g491re.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32g4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_h743zi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO-H743ZI board with single STM32H743ZI chip.\n# http://www.st.com/en/evaluation-tools/nucleo-h743zi.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_h745zi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO-H745ZI-Q board with single STM32H745ZITx chip.\n\nsource [find interface/stlink-dap.cfg]\ntransport select dapdirect_swd\n\n# STM32H745xx devices are dual core (Cortex-M7 and Cortex-M4)\nset DUAL_CORE 1\n\n# enable CTI for cross halting both cores\nset USE_CTI 1\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_l073rz.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO-L073RZ board with single STM32L073RZ chip.\n# http://www.st.com/en/evaluation-tools/nucleo-l073rz.html\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32l0_dual_bank.cfg]\n\n# There is only system reset line and JTAG/SWD command can be issued when SRST\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_l1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an ST NUCLEO L152RE board with a single STM32L152RET6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1847/PF260002\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l1x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_l4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Should work with all STM32L4 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_l5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for STM32L5 Nucleo Dev Boards.\n# http://www.st.com/en/evaluation-tools/stm32-mcu-nucleo.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32l5x.cfg]\n\n# use hardware reset\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/st_nucleo_wb55.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration for STM32WB55 Nucleo board (STM32WB55RGV6)\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32wbx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/steval-idb007v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an evaluation board with a single BlueNRG-1 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb008v1.html\nset CHIPNAME bluenrg-1\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/steval-idb008v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an evaluation board with a single BlueNRG-2 chip.\n# http://www.st.com/content/st_com/en/products/evaluation-tools/solution-evaluation-tools/communication-and-connectivity-solution-eval-boards/steval-idb007v1.html\nset CHIPNAME bluenrg-2\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/steval-idb011v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an evaluation board with a single BlueNRG-LP chip.\nset CHIPNAME bluenrg-lp\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/steval-idb012v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an evaluation board with a single BlueNRG-LPS chip.\nset CHIPNAME bluenrg-lps\nsource [find interface/cmsis-dap.cfg]\nsource [find target/bluenrg-x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/steval_pcc010.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use for the STM207VG plug-in board (1 MiB Flash and 112+16 KiB Ram\n# coming with the STEVAL-PCC010 board\n# http://www.st.com/internet/evalboard/product/251530.jsp\n# or any other board with only a STM32F2x in the JTAG chain\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm320518_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm320518_eval_stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM320518-EVAL: This is an STM32F0 eval board with a single STM32F051R8T6\n# (64KB) chip.\n# http://www.st.com/internet/evalboard/product/252994.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 8KB\nset WORKAREASIZE 0x2000\n\n# chip name\nset CHIPNAME STM32F051R8T6\n\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32100b_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32 eval board with a single STM32F100VBT6 chip.\n# http://www.st.com/internet/evalboard/product/247099.jsp\n\n# The chip has only 8KB sram\nset WORKAREASIZE 0x2000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3210b_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32 eval board with a single STM32F10x (128KB) chip.\n# http://www.st.com/internet/evalboard/product/176090.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3210c_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32 eval board with a single STM32F107VCT chip.\n# http://www.st.com/internet/evalboard/product/217965.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3210e_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32 eval board with a single STM32F103ZET6 chip.\n# http://www.st.com/internet/evalboard/product/204176.jsp\n\n# increase working area to 32KB for faster flash programming\nset WORKAREASIZE 0x8000\n\nsource [find target/stm32f1x.cfg]\n\n#\n# configure FSMC Bank 1 (NOR/PSRAM Bank 2) NOR flash\n# M29W128GL70ZA6E\n#\n\nset _FLASHNAME $_CHIPNAME.norflash\nflash bank $_FLASHNAME cfi 0x64000000 0x01000000 2 2 $_TARGETNAME\n\nproc stm32_enable_fsmc {} {\n\n\techo \"Enabling FSMC Bank 1 (NOR/PSRAM Bank 2)\"\n\n\t# enable gpio (defg) clocks for fsmc\n\t# RCC_APB2ENR\n\tmww 0x40021018 0x000001E0\n\n\t# enable fsmc clock\n\t# RCC_AHBENR\n\tmww 0x40021014 0x00000114\n\n\t# configure gpio to alternate function\n\t# GPIOD_CRL\n\tmww 0x40011400 0x44BB44BB\n\t# GPIOD_CRH\n\tmww 0x40011404 0xBBBBBBBB\n\n\t# GPIOE_CRL\n\tmww 0x40011800 0xBBBBB444\n\t# GPIOE_CRH\n\tmww 0x40011804 0xBBBBBBBB\n\n\t# GPIOF_CRL\n\tmww 0x40011C00 0x44BBBBBB\n\t# GPIOF_CRH\n\tmww 0x40011C04 0xBBBB4444\n\n\t# GPIOG_CRL\n\tmww 0x40012000 0x44BBBBBB\n\t# GPIOG_CRH\n\tmww 0x40012004 0x444444B4\n\n\t# setup fsmc timings\n\t# FSMC_BCR1\n\tmww 0xA0000008 0x00001058\n\n\t# FSMC_BTR1\n\tmww 0xA000000C 0x10000502\n\n\t# FSMC_BCR1 - enable fsmc\n\tmww 0xA0000008 0x00001059\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32_enable_fsmc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3220g_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3220g_eval_stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM3220G-EVAL: This is an STM32F2 eval board with a single STM32F207IGH6\n# (128KB) chip.\n# http://www.st.com/internet/evalboard/product/250374.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F207IGH6\n\nsource [find target/stm32f2x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3241g_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm3241g_eval_stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM3241G-EVAL: This is an STM32F4 eval board with a single STM32F417IGH6\n# (1024KB) chip.\n# http://www.st.com/internet/evalboard/product/252216.jsp\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F417IGH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32429i_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32429i_eval_stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32429I-EVAL: This is an STM32F4 eval board with a single STM32F429NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259093\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F429NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32439i_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32439i_eval_stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32439I-EVAL: This is an STM32F4 eval board with a single STM32F439NIH6\n# (2048KB) chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF259094\n#\n# This is for using the onboard STLINK/V2\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# chip name\nset CHIPNAME STM32F439NIH6\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm327x6g_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM327[4|5]6G-EVAL: This is for the STM32F7 eval boards.\n# STM32746G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261639\n# STM32756G-EVAL\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF261640\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f0discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F0 discovery board with a single STM32F051R8T6 chip.\n# http://www.st.com/internet/evalboard/product/253215.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f0x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f103c8_blue_pill.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32F103C8 \"Blue Pill\"\n\n# NOTE:\n# There is a fair bit of confusion about whether the \"Blue Pill\" has 128kB or 64kB flash size.\n# The most likely cause is that there exist a -C8 and a -CB variant of the STM32F103, where\n# the C8 has 64kB, the CB has 128kB as per specification. \"Blue Pill\" boards are manufactured\n# by a lot of different vendors, some may actually use the CB variant but from a cursory look\n# it very hard to tell them apart (\"C8\" and \"CB\" look very similar). Nevertheless, people have\n# tried using the full 128kB of flash on the C8 and found it to be working. Hence this board file\n# overrides the internal size detection. Be aware though that you may be using you particular\n# board outside of its specification. If in doubt, comment the following line.\nset FLASH_SIZE 0x20000\n\nsource [find target/stm32f1x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f334discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F334 discovery board with a single STM32F334C8T6 chip.\n# As it is one of the few boards with stlink V.2-1, we source the corresponding\n# nucleo file.\n# http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1848/PF260318\n\nsource [find board/st_nucleo_f3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f3discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F3 discovery board with a single STM32F303VCT6 chip.\n# http://www.st.com/internet/evalboard/product/254044.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f3x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f412g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F412G discovery board with a single STM32F412ZGT6 chip.\n# http://www.st.com/en/evaluation-tools/32f412gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PG06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x000AA000 0x00055000\t;# MODER\n\tmmw 0x40021408 0x000FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f413h-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F413H discovery board with a single STM32F413ZHT6 chip.\n# http://www.st.com/en/evaluation-tools/32f413hdiscovery.html\n\n#\n# Untested!!!\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000000FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOHEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PD13: BK1_IO3, PE02: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB02:AF09:V, PD13:AF09:V, PE02:AF09:V, PF09:AF10:V, PF08:AF10:V, PG06:AF10:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x40020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x00000900 0x00000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\t# Port F: PF09:AF10:V, PF08:AF10:V\n\tmmw 0x40021400 0x000A0000 0x00050000\t;# MODER\n\tmmw 0x40021408 0x000F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021424 0x000000AA 0x00000055\t;# AFRH\n\n\t# Port G: PG06:AF10:V\n\tmmw 0x40021800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40021808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021820 0x0A000000 0x05000000\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000003\t\t\t\t;# 3 WS for 96 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24001808\t\t\t\t;# 96 MHz: HSI, PLLM=8, PLLN=96, PLLP=2\n\tmww 0x40023808 0x00001000\t\t\t\t;# APB1: /2, APB2: /1\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f429disc1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f429discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is an STM32F429 discovery board with a single STM32F429ZI chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/PF259090\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f469discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is an STM32F469 discovery board with a single STM32F469NI chip.\n# http://www.st.com/web/catalog/tools/FM116/CL1620/SC959/SS1532/LN1848/PF262395\n#\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f469i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F469I discovery board with a single STM32F469NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f469idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PF10: CLK, PB06: BK1_NCS, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PF08: BK1_IO0\n\n\t# PB06:AF10:V, PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\n\t# Port B: PB06:AF10:V\n\tmmw 0x40020400 0x00002000 0x00001000\t;# MODER\n\tmmw 0x40020408 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000000 0x05000000\t;# AFRL\n\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF08:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x40021400 0x002AA000 0x00155000\t;# MODER\n\tmmw 0x40021408 0x003FF000 0x00000000\t;# OSPEEDR\n\tmmw 0x40021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x40021424 0x000009AA 0x00000655\t;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000005\t\t\t\t;# 5 WS for 160 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24002808\t\t\t\t;# 160 MHz: HSI, PLLM=8, PLLN=160, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f4discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F4 discovery board with a single STM32F407VGT6 chip.\n# http://www.st.com/internet/evalboard/product/252419.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 64KB\nset WORKAREASIZE 0x10000\n\nsource [find target/stm32f4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f723e-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F723E discovery board with a single STM32F723IEK6 chip.\n# http://www.st.com/en/evaluation-tools/32f723ediscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 128KB\nset WORKAREASIZE 0x20000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f746g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F746G discovery board with a single STM32F746NGH6 chip.\n# http://www.st.com/en/evaluation-tools/32f746gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PD12: BK1_IO1, PD11: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V\n\tmmw 0x40020C00 0x0A800000 0x05400000\t;# MODER\n\tmmw 0x40020C08 0x0FC00000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00999000 0x00666000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f769i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F769I discovery board with a single STM32F769NIH6 chip.\n# http://www.st.com/en/evaluation-tools/32f769idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x40023830 0x000007FF 0\t\t\t\t;# RCC_AHB1ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x40023838 0x00000002 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB02: CLK, PB06: BK1_NCS, PD13: BK1_IO3, PE02: BK1_IO2, PC10: BK1_IO1, PC09: BK1_IO0\n\n\t# PB06:AF10:V, PB02:AF09:V, PC10:AF09:V, PC09:AF09:V, PD13:AF09:V, PE02:AF09:V\n\n\t# Port B: PB06:AF10:V, PB02:AF09:V\n\tmmw 0x40020400 0x00002020 0x00001010\t;# MODER\n\tmmw 0x40020408 0x00003030 0x00000000\t;# OSPEEDR\n\tmmw 0x40020420 0x0A000900 0x05000600\t;# AFRL\n\n\t# Port C: PC10:AF09:V, PC09:AF09:V\n\tmmw 0x40020800 0x00280000 0x00140000\t;# MODER\n\tmmw 0x40020808 0x003C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020824 0x00000990 0x00000660\t;# AFRH\n\n\t# Port D: PD13:AF09:V\n\tmmw 0x40020C00 0x08000000 0x04000000\t;# MODER\n\tmmw 0x40020C08 0x0C000000 0x00000000\t;# OSPEEDR\n\tmmw 0x40020C24 0x00900000 0x00600000\t;# AFRH\n\n\t# Port E: PE02:AF09:V\n\tmmw 0x40021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x40021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x40021020 0x00000900 0x00000600\t;# AFRL\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x03500008\t\t\t\t;# QUADSPI_CR: PRESCALER=3, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00190100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x19, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# exit qpi mode\n\tmww 0xA0001014 0x000033f5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\n\t# 1-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0D003513\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\n\t# 4-line qpi mode\n\tmww 0xA0001014 0x00003135\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=EQIO\n\n\t# 4-line memory-mapped read mode with 4-byte addresses\n\tmww 0xA0001014 0x0F283FEC\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0xA, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=4READ4B\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmww 0x40023C00 0x00000006\t\t\t\t;# 6 WS for 192 MHz HCLK\n\tsleep 1\n\tmww 0x40023804 0x24003008\t\t\t\t;# 192 MHz: PLLM=8, PLLN=192, PLLP=2\n\tmww 0x40023808 0x00009400\t\t\t\t;# APB1: /4, APB2: /2\n\tmmw 0x40023800 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40023808 0x00000002 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32f7discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32F7 discovery board with a single STM32F756NGH6 chip.\n# http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF261641\n\n# This is for using the onboard STLINK/V2-1\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 256KB\nset WORKAREASIZE 0x40000\n\nsource [find target/stm32f7x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h735g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a stm32h735g-dk with a single STM32H735IGK6 chip.\n# https://www.st.com/en/evaluation-tools/stm32h735g-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h735igk6\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000006FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PF10: OCSPI1_CLK, PB02: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PD05: OCSPI1_IO5,\n\t# PD04: OCSPI1_IO4, PD13: OCSPI1_IO3, PE02: OCSPI1_IO2, PD12: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF10:V, PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V\n\t# PD04:AF10:V, PE02:AF09:V, PF10:AF09:V, PG09:AF09:V, PG06:AF10:V\n\t# Port B: PB02:AF10:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000A00 0x00000500\t;# AFRL\n\t# Port D: PD13:AF09:V, PD12:AF09:V, PD11:AF09:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x58020C00 0x0A808A00 0x05404500\t;# MODER\n\tmmw 0x58020C08 0x0FC0CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x0FC0CF00\t;# PUPDR\n\tmmw 0x58020C20 0xA0AA0000 0x50550000\t;# AFRL\n\tmmw 0x58020C24 0x00999000 0x00666000\t;# AFRH\n\t# Port E: PE02:AF09:V\n\tmmw 0x58021000 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58021008 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802100C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58021020 0x00000900 0x00000600\t;# AFRL\n\t# Port F: PF10:AF09:V\n\tmmw 0x58021400 0x00200000 0x00100000\t;# MODER\n\tmmw 0x58021408 0x00300000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x00300000\t;# PUPDR\n\tmmw 0x58021424 0x00000900 0x00000600\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h745i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a stm32h745i-disco with a single STM32H745XIH6 chip.\n# www.st.com/en/product/stm32h745i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h745xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h747i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a stm32h747i-disco with a single STM32H747XIH6 chip.\n# www.st.com/en/product/stm32h747i-disco.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h747xih6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PB02: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PB02:AF09:V, PD11:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h750b-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a stm32h750b-dk with a single STM32H750XBH6 chip.\n# www.st.com/en/product/stm32h750b-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h750xbh6\n\n# enable stmqspi\nif {![info exists QUADSPI]} {\n\tset QUADSPI 1\n}\n\nsource [find target/stm32h7x.cfg]\n\nreset_config srst_only\n\nsource [find board/stm32h7x_dual_qspi.cfg]\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal QUADSPI\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $QUADSPI } {\n\t\tqspi_init 1\n\t}\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h7b3i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a stm32h7b3i-dk with a single STM32H7B3LIH6Q chip.\n# https://www.st.com/en/evaluation-tools/stm32h7b3i-dk.html\n#\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset CHIPNAME stm32h7b3lih6q\n\n# enable stmqspi\nif {![info exists OCTOSPI1]} {\n\tset OCTOSPI1 1\n\tset OCTOSPI2 0\n}\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x58024540 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x58024534 0x00284000 0\t\t\t\t;# RCC_AHB3ENR |= IOMNGREN, OSPI2EN, OSPI1EN (enable clocks)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmww 0x5200B404 0x03010111\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI1\n\tmww 0x5200B408 0x00000000\t\t\t\t;# OCTOSPIM_P2CR: disable Port 2\n\n\t# PG06: OCSPI1_NCS, PB02: OCSPI1_CLK, PC05: OCSPI1_DQS, PD07: OCSPI1_IO7, PG09: OCSPI1_IO6, PH03: OCSPI1_IO5,\n\t# PC01: OCSPI1_IO4, PF06: OCSPI1_IO3, PF07: OCSPI1_IO2, PF09: OCSPI1_IO1, PD11: OCSPI1_IO0\n\n\t# PB02:AF09:V, PC05:AF10:V, PC01:AF10:V, PD11:AF09:V, PD07:AF10:V, PF09:AF10:V\n\t# PF07:AF10:V, PF06:AF10:V, PG09:AF09:V, PG06:AF10:V, PH03:AF09:V\n\t# Port B: PB02:AF09:V\n\tmmw 0x58020400 0x00000020 0x00000010\t;# MODER\n\tmmw 0x58020408 0x00000030 0x00000000\t;# OSPEEDR\n\tmmw 0x5802040C 0x00000000 0x00000030\t;# PUPDR\n\tmmw 0x58020420 0x00000900 0x00000600\t;# AFRL\n\t# Port C: PC05:AF10:V, PC01:AF10:V\n\tmmw 0x58020800 0x00000808 0x00000404\t;# MODER\n\tmmw 0x58020808 0x00000C0C 0x00000000\t;# OSPEEDR\n\tmmw 0x5802080C 0x00000000 0x00000C0C\t;# PUPDR\n\tmmw 0x58020820 0x00A000A0 0x00500050\t;# AFRL\n\t# Port D: PD11:AF09:V, PD07:AF10:V\n\tmmw 0x58020C00 0x00808000 0x00404000\t;# MODER\n\tmmw 0x58020C08 0x00C0C000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C0C 0x00000000 0x00C0C000\t;# PUPDR\n\tmmw 0x58020C20 0xA0000000 0x50000000\t;# AFRL\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF09:AF10:V, PF07:AF10:V, PF06:AF10:V\n\tmmw 0x58021400 0x0008A000 0x00045000\t;# MODER\n\tmmw 0x58021408 0x000CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802140C 0x00000000 0x000CF000\t;# PUPDR\n\tmmw 0x58021420 0xAA000000 0x55000000\t;# AFRL\n\tmmw 0x58021424 0x000000A0 0x00000050\t;# AFRH\n\t# Port G: PG09:AF09:V, PG06:AF10:V\n\tmmw 0x58021800 0x00082000 0x00041000\t;# MODER\n\tmmw 0x58021808 0x000C3000 0x00000000\t;# OSPEEDR\n\tmmw 0x5802180C 0x00000000 0x000C3000\t;# PUPDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x00000090 0x00000060\t;# AFRH\n\t# Port H: PH03:AF09:V\n\tmmw 0x58021C00 0x00000080 0x00000040\t;# MODER\n\tmmw 0x58021C08 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C0C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x58021C20 0x00009000 0x00006000\t;# AFRL\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0x52005130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0x52005008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0x5200500C 0x00000005\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=5\n\n\tmww 0x52005108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0x52005100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0x52005110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tflash probe $a\t\t\t\t\t\t\t;# load configuration from CR, TCR, CCR, IR register values\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0x52005000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0x52005108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0x52005100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0x52005110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\tglobal OCTOSPI1\n\tglobal OCTOSPI2\n\n\tmmw 0x52002000 0x00000004 0x0000000B\t;# FLASH_ACR: 4 WS for 192 MHZ HCLK\n\n\tmmw 0x58024400 0x00000001 0x00000018\t;# RCC_CR: HSIDIV=1, HSI on\n\tmmw 0x58024410 0x10000000 0xEE000007\t;# RCC_CFGR: MCO2=system, MCO2PRE=8, HSI as system clock\n\tmww 0x58024418 0x00000040\t\t\t\t;# RCC_D1CFGR: D1CPRE=1, D1PPRE=2, HPRE=1\n\tmww 0x5802441C 0x00000440\t\t\t\t;# RCC_D2CFGR: D2PPRE2=2, D2PPRE1=2\n\tmww 0x58024420 0x00000040\t\t\t\t;# RCC_D3CFGR: D3PPRE=2\n\tmww 0x58024428 0x00000040\t\t\t\t;# RCC_PPLCKSELR: DIVM3=0, DIVM2=0, DIVM1=4, PLLSRC=HSI\n\tmmw 0x5802442C 0x0001000C 0x00000002\t;# RCC_PLLCFGR: PLL1RGE=8MHz to 16MHz, PLL1VCOSEL=wide\n\tmww 0x58024430 0x01070217\t\t\t\t;# RCC_PLL1DIVR: 192 MHz: DIVR1=2, DIVQ=8, DIVP1=2, DIVN1=24\n\tmmw 0x58024400 0x01000000 0\t\t\t\t;# RCC_CR: PLL1ON=1\n\tsleep 1\n\tmmw 0x58024410 0x00000003 0\t\t\t\t;# RCC_CFGR: PLL1 as system clock\n\tsleep 1\n\n\tadapter speed 24000\n\n\tif { $OCTOSPI1 } {\n\t\toctospi_init 1\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h7x3i_eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STM32H7[4|5]3I-EVAL: this is for the H7 eval boards.\n# This is an ST EVAL-H743XI board with single STM32H743XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h743i-eval.html\n# This is an ST EVAL-H753XI board with single STM32H753XI chip.\n# http://www.st.com/en/evaluation-tools/stm32h753i-eval.html\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32h7x_dual_bank.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32h7x_dual_qspi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# stm32h754i-disco and stm32h750b-dk dual quad qspi.\n\n# QUADSPI initialization\n# qpi: 4-line mode\nproc qspi_init { qpi } {\n\tglobal a\n\tmmw 0x580244E0 0x000007FF 0\t\t\t\t;# RCC_AHB4ENR |= GPIOAEN-GPIOKEN (enable clocks)\n\tmmw 0x580244D4 0x00004000 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PG06: BK1_NCS, PF10: CLK, PF06: BK1_IO3, PF07: BK1_IO2, PF09: BK1_IO1, PD11: BK1_IO0,\n\t# PG14: BK2_IO3, PG09: BK2_IO2, PH03: BK2_IO1, PH02: BK2_IO0\n\n\t# PD11:AF09:V, PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V, PG14:AF09:H\n\t# PG09:AF09:V, PG06:AF10:H, PH03:AF09:V, PH02:AF09:V\n\n\t# Port D: PD11:AF09:V\n\tmmw 0x58020C00 0x00800000 0x00400000\t;# MODER\n\tmmw 0x58020C08 0x00C00000 0x00000000\t;# OSPEEDR\n\tmmw 0x58020C24 0x00009000 0x00006000\t;# AFRH\n\t# Port F: PF10:AF09:V, PF09:AF10:V, PF07:AF09:V, PF06:AF09:V\n\tmmw 0x58021400 0x0028A000 0x00145000\t;# MODER\n\tmmw 0x58021408 0x003CF000 0x00000000\t;# OSPEEDR\n\tmmw 0x58021420 0x99000000 0x66000000\t;# AFRL\n\tmmw 0x58021424 0x000009A0 0x00000650\t;# AFRH\n\t# Port G: PG14:AF09:H, PG09:AF09:V, PG06:AF10:H\n\tmmw 0x58021800 0x20082000 0x10041000\t;# MODER\n\tmmw 0x58021808 0x200C2000 0x10001000\t;# OSPEEDR\n\tmmw 0x58021820 0x0A000000 0x05000000\t;# AFRL\n\tmmw 0x58021824 0x09000090 0x06000060\t;# AFRH\n\t# Port H: PH03:AF09:V, PH02:AF09:V\n\tmmw 0x58021C00 0x000000A0 0x00000050\t;# MODER\n\tmmw 0x58021C08 0x000000F0 0x00000000\t;# OSPEEDR\n\tmmw 0x58021C20 0x00009900 0x00006600\t;# AFRL\n\n\t# correct FSIZE is 0x1A, however, this causes trouble when\n\t# reading the last bytes at end of bank in *memory mapped* mode\n\n\t# for dual flash mode 2 * mt25ql512\n\tmww 0x52005000 0x05500058\t\t\t\t;# QUADSPI_CR: PRESCALER=5, APMS=1, FTHRES=0, FSEL=0, DFM=1, SSHIFT=1, TCEN=1\n\tmww 0x52005004 0x001A0200\t\t\t\t;# QUADSPI_DCR: FSIZE=0x1A, CSHT=0x02, CKMODE=0\n\n\tmww 0x52005030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0x52005014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1\n\tmmw 0x52005000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# Exit QPI mode\n\tmmw 0x52005000 0x00000002 0\t\t\t\t;# QUADSPI_CR: ABORT=1\n\tmww 0x52005014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=Exit QPI\n\tsleep 1\n\n\tif { $qpi == 1 } {\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Configure dummy clocks via volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000181\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Volatile Conf. Reg.\n\t\tmwh 0x52005020 0xABAB\t\t\t\t;# QUADSPI_DR: 0xAB 0xAB for 10 dummy clocks\n\t\tsleep 1\n\n\t\t# Write Enable\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000106\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enable\n\t\tsleep 1\n\n\t\t# Enable QPI mode via enhanced volatile configuration register\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005010 0x00000001\t\t\t;# QUADSPI_DLR: 2 data bytes\n\t\tmww 0x52005014 0x01000161\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x1, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Write Enhanced Conf. Reg.\n\t\tmwh 0x52005020 0x3F3F\t\t\t\t;# QUADSPI_DR: 0x3F 0x3F to enable QPI and DPI mode\n\t\tsleep 1\n\n\t\t# Enter QPI mode\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x00000135\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x1, INSTR=Enter QPI\n\t\tsleep 1\n\n\t\t# memory-mapped fast read mode with 4-byte addresses and 10 dummy cycles (for read only)\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0F283FEC\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x3, DCYC=0xA, ADSIZE=0x3, ADMODE=0x3, IMODE=0x3, INSTR=Fast READ\n\t} else {\n\t\t# memory-mapped read mode with 4-byte addresses\n\t\tmmw 0x52005000 0x00000002 0\t\t\t;# QUADSPI_CR: ABORT=1\n\t\tmww 0x52005014 0x0D003513\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x3, ADMODE=0x1, IMODE=0x1, INSTR=READ\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l0discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32L053 discovery board with a single STM32L053 chip.\n# http://www.st.com/web/en/catalog/tools/PF260319\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32l0.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l476g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32L476G discovery board with a single STM32L476VGT6 chip.\n# http://www.st.com/en/evaluation-tools/32l476gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PE11: NCS, PE10: CLK, PE15: BK1_IO3, PE14: BK1_IO2, PE13: BK1_IO1, PE12: BK1_IO0\n\n\t# PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\n\t# Port E: PE15:AF10:V, PE14:AF10:V, PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0xAAA00000 0x55500000    ;# MODER\n\tmmw 0x48001008 0xFFF00000 0x00000000    ;# OSPEEDR\n\tmmw 0x48001024 0xAAAAAA00 0x55555500    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00170100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x17, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l496g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32L496G discovery board with a single STM32L496AGI6 chip.\n# http://www.st.com/en/evaluation-tools/32l496gdiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset QUADSPI 1\n\nsource [find target/stm32l4x.cfg]\n\n# QUADSPI initialization\nproc qspi_init { } {\n\tglobal a\n\tmmw 0x4002104C 0x000001FF 0\t\t\t\t;# RCC_AHB2ENR |= GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000100 0\t\t\t\t;# RCC_AHB3ENR |= QSPIEN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\t# PB11: BK1_NCS, PA03: CLK, PA06: BK1_IO3, PA07: BK1_IO2, PB00: BK1_IO1, PB01: BK1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PA03:AF10:V, PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V, PA03:AF10:V\n\tmmw 0x48000000 0x0000A080 0x00005040    ;# MODER\n\tmmw 0x48000008 0x0000F0C0 0x00000000    ;# OSPEEDR\n\tmmw 0x48000020 0xAA00A000 0x55005000    ;# AFRL\n\n\t# Port B: PB11:AF10:V, PB01:AF10:V, PB00:AF10:V\n\tmmw 0x48000400 0x0080000A 0x00400005    ;# MODER\n\tmmw 0x48000408 0x00C0000F 0x00000000    ;# OSPEEDR\n\tmmw 0x48000420 0x000000AA 0x00000055    ;# AFRL\n\tmmw 0x48000424 0x0000A000 0x00005000    ;# AFRH\n\n\tmww 0xA0001030 0x00001000\t\t\t\t;# QUADSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x01500008\t\t\t\t;# QUADSPI_CR: PRESCALER=1, APMS=1, FTHRES=0, FSEL=0, DFM=0, SSHIFT=0, TCEN=1\n\tmww 0xA0001004 0x00160100\t\t\t\t;# QUADSPI_DCR: FSIZE=0x16, CSHT=0x01, CKMODE=0\n\tmmw 0xA0001000 0x00000001 0\t\t\t\t;# QUADSPI_CR: EN=1\n\n\t# 1-line spi mode\n\tmww 0xA0001014 0x000003F5\t\t\t\t;# QUADSPI_CCR: FMODE=0x0, DMODE=0x0, DCYC=0x0, ADSIZE=0x0, ADMODE=0x0, IMODE=0x3, INSTR=RSTQIO\n\tsleep 1\n\n\t# memory-mapped read mode with 3-byte addresses\n\tmww 0xA0001014 0x0D002503\t\t\t\t;# QUADSPI_CCR: FMODE=0x3, DMODE=0x1, DCYC=0x0, ADSIZE=0x2, ADMODE=0x1, IMODE=0x1, INSTR=READ\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000004 0x00000003\t;# 4 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\tqspi_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l4discovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Explicitly for the STM32L476 discovery board:\n# http://www.st.com/web/en/catalog/tools/PF261635\n# but perfectly functional for any other STM32L4 board connected via\n# an stlink-v2-1 interface.\n# This is for STM32L4 boards that are connected via stlink-v2-1.\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nsource [find target/stm32l4x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l4p5g-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a STM32L4P5G discovery board with a single STM32L4R9AGI6 chip.\n# http://www.st.com/en/evaluation-tools/stm32l4p5g-dk.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x07050333\t\t\t\t;# OCTOSPIM_P1CR: assign Port 1 to OCTOSPI2\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PE11: P1_NCS, PE10: P1_CLK, PG06: P1_DQS, PD07: P1_IO7, PC03: P1_IO6, PD05: P1_IO5\n\t# PD04: P1_IO4, PA06: P1_IO3, PA07: P1_IO2, PE13: P1_IO1, PE11: P1_IO0\n\n\t# PA07:AF10:V, PA06:AF10:V, PC03:AF10:V, PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\t# PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V, PG06:AF03:V\n\n\t# Port A: PA07:AF10:V, PA06:AF10:V\n\tmmw 0x48000000 0x0000A000 0x00005000\t;# MODER\n\tmmw 0x48000008 0x0000F000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800000C 0x00000000 0x0000F000\t;# PUPDR\n\tmmw 0x48000020 0xAA000000 0x55000000\t;# AFRL\n\t# Port C: PC03:AF10:V\n\tmmw 0x48000800 0x00000080 0x00000040\t;# MODER\n\tmmw 0x48000808 0x000000C0 0x00000000\t;# OSPEEDR\n\tmmw 0x4800080C 0x00000000 0x000000C0\t;# PUPDR\n\tmmw 0x48000820 0x0000A000 0x00005000\t;# AFRL\n\t# Port D: PD07:AF10:V, PD05:AF10:V, PD04:AF10:V\n\tmmw 0x48000C00 0x00008A00 0x00004500\t;# MODER\n\tmmw 0x48000C08 0x0000CF00 0x00000000\t;# OSPEEDR\n\tmmw 0x48000C0C 0x00000000 0x0000CF00\t;# PUPDR\n\tmmw 0x48000C20 0xA0AA0000 0x50550000\t;# AFRL\n\t# Port E: PE13:AF10:V, PE12:AF10:V, PE11:AF10:V, PE10:AF10:V\n\tmmw 0x48001000 0x0AA00000 0x05500000\t;# MODER\n\tmmw 0x48001008 0x0FF00000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800100C 0x00000000 0x0FF00000\t;# PUPDR\n\tmmw 0x48001024 0x00AAAA00 0x00555500\t;# AFRH\n\t# Port G: PG06:AF03:V\n\tmmw 0x48001800 0x00002000 0x00001000\t;# MODER\n\tmmw 0x48001808 0x00003000 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x00003000\t;# PUPDR\n\tmmw 0x48001820 0x03000000 0x0C000000\t;# AFRL\n\n\t# PG12: P2_NCS, PF04: P2_CLK, PF12: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PG01: P2_IO5\n\t# PG00: P2_IO4, PF03: P2_IO3, PF02: P2_IO2, PF01: P2_IO1, PF00: P2_IO0\n\n\t# PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\t# PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\n\t# Port F: PF12:AF05:V, PF04:AF05:V, PF03:AF05:V, PF02:AF05:V, PF01:AF05:V, PF00:AF05:V\n\tmmw 0x48001400 0x020002AA 0x01000155\t;# MODER\n\tmmw 0x48001408 0x030003FF 0x00000000\t;# OSPEEDR\n\tmmw 0x4800140C 0x00000000 0x030003FF\t;# PUPDR\n\tmmw 0x48001420 0x00055555 0x000AAAAA\t;# AFRL\n\tmmw 0x48001424 0x00050000 0x000A0000\t;# AFRH\n\t# Port G: PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PG01:AF05:V, PG00:AF05:V\n\tmmw 0x48001800 0x0228000A 0x01140005\t;# MODER\n\tmmw 0x48001808 0x033C000F 0x00000000\t;# OSPEEDR\n\tmmw 0x4800180C 0x00000000 0x033C000F\t;# PUPDR\n\tmmw 0x48001820 0x00000055 0x000000AA\t;# AFRL\n\tmmw 0x48001824 0x00050550 0x000A0AA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 24000\n\n\toctospi_init 1\n}\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32l4r9i-disco.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is a STM32L4R9I discovery board with a single STM32L4R9AII6 chip.\n# http://www.st.com/en/evaluation-tools/32l4r9idiscovery.html\n\n# This is for using the onboard STLINK\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\n# increase working area to 96KB\nset WORKAREASIZE 0x18000\n\n# enable stmqspi\nset OCTOSPI1 1\nset OCTOSPI2 0\n\nsource [find target/stm32l4x.cfg]\n\n# OCTOSPI initialization\n# octo: 8-line mode\nproc octospi_init { octo } {\n\tglobal a b\n\tmmw 0x4002104C 0x001001FF 0\t\t\t\t;# RCC_AHB2ENR |= OSPIMEN, GPIOAEN-GPIOIEN (enable clocks)\n\tmmw 0x40021050 0x00000300 0\t\t\t\t;# RCC_AHB3ENR |= OSPI2EN, OSPI1EN (enable clocks)\n\tmmw 0x40021058 0x10000000 0\t\t\t\t;# RCC_APB1ENR1 |= PWREN (enable clock)\n\tsleep 1\t\t\t\t\t\t\t\t\t;# Wait for clock startup\n\n\tmmw 0x40007004 0x00000200 0\t\t\t\t;# PWR_CR2 |= IOSV (required for use of GPOIG, cf. RM0432)\n\n\tmww 0x50061C04 0x00000000\t\t\t\t;# OCTOSPIM_P1CR: disable Port 1\n\tmww 0x50061C08 0x03010111\t\t\t\t;# OCTOSPIM_P2CR: assign Port 2 to OCTOSPI1\n\n\t# PG12: P2_NCS, PI06: P2_CLK, PG15: P2_DQS, PG10: P2_IO7, PG09: P2_IO6, PH10: P2_IO5,\n\t# PH09: P2_IO4, PH08: P2_IO3, PI09: P2_IO2, PI10: P2_IO1, PI11: P2_IO0\n\n\t# PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V, PH10:AF05:V, PH09:AF05:V\n\t# PH08:AF05:V, PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\n\t# Port G: PG15:AF05:V, PG12:AF05:V, PG10:AF05:V, PG09:AF05:V\n\tmmw 0x48001800 0x82280000 0x41140000\t;# MODER\n\tmmw 0x48001808 0xC33C0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001824 0x50050550 0xA00A0AA0\t;# AFRH\n\n\t# Port H: PH10:AF05:V, PH09:AF05:V, PH08:AF05:V\n\tmmw 0x48001C00 0x002A0000 0x00150000\t;# MODER\n\tmmw 0x48001C08 0x003F0000 0x00000000\t;# OSPEEDR\n\tmmw 0x48001C24 0x00000555 0x00000AAA\t;# AFRH\n\n\t# Port I: PI11:AF05:V, PI10:AF05:V, PI09:AF05:V, PI06:AF05:V\n\tmmw 0x48002000 0x00A82000 0x00541000\t;# MODER\n\tmmw 0x48002008 0x00FC3000 0x00000000\t;# OSPEEDR\n\tmmw 0x48002020 0x05000000 0x0A000000\t;# AFRL\n\tmmw 0x48002024 0x00005550 0x0000AAA0\t;# AFRH\n\n\t# OCTOSPI1: memory-mapped 1-line read mode with 4-byte addresses\n\tmww 0xA0001130 0x00001000\t\t\t\t;# OCTOSPI_LPTR: deactivate CS after 4096 clocks when FIFO is full\n\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x1, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=0\n\tmww 0xA0001008 0x01190100\t\t\t\t;# OCTOSPI_DCR1: MTYP=0x1, FSIZE=0x19, CSHT=0x01, CKMODE=0, DLYBYP=0\n\tmww 0xA000100C 0x00000001\t\t\t\t;# OCTOSPI_DCR2: PRESCALER=1\n\n\tmww 0xA0001108 0x00000000\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=0, DCYC=0x0\n\tmww 0xA0001100 0x01003101\t\t\t\t;# OCTOSPI_CCR: DMODE=0x1, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x1, ISIZE=0x0, IMODE=0x1\n\tmww 0xA0001110 0x00000013\t\t\t\t;# OCTOSPI_IR: INSTR=READ4B\n\n\tif { $octo == 1 } {\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05\t\t\t\t\t\t\t\t;# Read Status Register\n\t\tstmqspi cmd $a 0 0x72 0x00 0x00 0x00 0x00 0x02\t\t;# Write Conf. Reg. 2, addr 0x00000000: DTR OPI enable\n\n\t\t# OCTOSPI1: memory-mapped 8-line read mode with 4-byte addresses\n\t\tmww 0xA0001000 0x3040000B\t\t\t\t;# OCTOSPI_CR: FMODE=0x3, APMS=1, FTHRES=0, FSEL=0, DQM=0, TCEN=1, EN=1\n\t\tmww 0xA0001108 0x10000006\t\t\t\t;# OCTOSPI_TCR: SSHIFT=0, DHQC=1, DCYC=0x6\n\t\tmww 0xA0001100 0x2C003C1C\t\t\t\t;# OCTOSPI_CCR: DTR, DMODE=0x4, ABMODE=0x0, ADSIZE=0x3, ADMODE=0x4, ISIZE=0x1, IMODE=0x4\n\t\tmww 0xA0001110 0x0000EE11\t\t\t\t;# OCTOSPI_IR: INSTR=OCTA DTR Read\n\n\t\tflash probe $a\t\t\t\t\t\t\t;# reload configuration from CR, TCR, CCR, IR register values\n\n\t\tstmqspi cmd $a 0 0x06\t\t\t\t\t\t\t\t;# Write Enable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 0 0x04\t\t\t\t\t\t\t\t;# Write Disable\n\t\tstmqspi cmd $a 1 0x05 0x00 0x00 0x00 0x00\t\t\t;# Read Status Register (note dummy address in 8-line mode)\n\t\tstmqspi cmd $a 1 0x71 0x00 0x00 0x00 0x00\t\t\t;# Read Conf. Reg. 2, addr 0x00000000: DOPI, SOPI bits\n\t}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tmmw 0x40022000 0x00000003 0x0000000C\t;# 3 WS for 72 MHz HCLK\n\tsleep 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# HSI on\n\tmww 0x4002100C 0x01002432\t\t\t\t;# RCC_PLLCFGR 72 MHz: PLLREN=1, PLLM=4, PLLN=36, PLLR=2, HSI\n\tmww 0x40021008 0x00008001\t\t\t\t;# always HSI, APB1: /1, APB2: /1\n\tmmw 0x40021000 0x01000000 0x00000000\t;# PLL on\n\tsleep 1\n\tmmw 0x40021008 0x00000003 0x00000000\t;# switch to PLL\n\tsleep 1\n\n\tadapter speed 4000\n\n\toctospi_init 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32ldiscovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32L discovery board with a single STM32L152RBT6 chip.\n# http://www.st.com/internet/evalboard/product/250990.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x4000\nsource [find target/stm32l1.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32mp13x_dk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# board MB1635x\n# http://www.st.com/en/evaluation-tools/stm32mp135f-dk.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp13x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32mp15x_dk2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# board MB1272B\n# http://www.st.com/en/evaluation-tools/stm32mp157a-dk1.html\n# http://www.st.com/en/evaluation-tools/stm32mp157c-dk2.html\n\nsource [find interface/stlink-dap.cfg]\n\ntransport select dapdirect_swd\n\nsource [find target/stm32mp15x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/stm32vldiscovery.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is an STM32VL discovery board with a single STM32F100RB chip.\n# http://www.st.com/internet/evalboard/product/250863.jsp\n\nsource [find interface/stlink.cfg]\n\ntransport select hla_swd\n\nset WORKAREASIZE 0x2000\nsource [find target/stm32f1x.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/str910-eval.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# str910-eval eval board\n#\n# Need reset scripts\nreset_config trst_and_srst\n\n# FIXME use some standard target config, maybe create one from this\n#\n#\tsource [find target/...cfg]\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu   -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs    -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#jtag_rclk 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 0\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/telo.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/c100.cfg]\n# basic register definition for C100\nsource [find target/c100regs.tcl]\n# board-config info\nsource [find target/c100config.tcl]\n# C100 helper functions\nsource [find target/c100helper.tcl]\n\n\n# Telo board & C100 support trst and srst\n# make the reset asserted to\n# allow RC circuit to discharge for: [ms]\nadapter srst pulse_width 100\njtag_ntrst_assert_width 100\n# don't talk to JTAG after reset for: [ms]\nadapter srst delay 100\njtag_ntrst_delay 100\nreset_config trst_and_srst separate\n\n\n\n\n# issue telnet: reset init\n# issue gdb: monitor reset init\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 100\n\t# this will setup Telo board\n\tsetupTelo\n\t#turn up the JTAG speed\n\tadapter speed 3000\n\techo \"JTAG speek now 3MHz\"\n\techo \"type helpC100 to get help on C100\"\n}\n\n$_TARGETNAME configure -event reset-deassert-post {\n\t# Force target into ARM state.\n#\tsoft_reset_halt ;# not implemented on ARM11\n\techo \"Detected SRSRT asserted on C100.CPU\"\n\n}\n\n$_TARGETNAME configure -event reset-assert-post {\n  echo \"Assering reset\"\n  #sleep 10\n}\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n\n# boots from NOR on CS0:  8 MBytes CFI flash, 16-bit bus\n# it's really 16MB but the upper 8mb is controller via gpio\n# openocd does not support 'complex reads/writes' to NOR\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x01000000 2 2 $_TARGETNAME\n\n# writing data to memory does not work without this\narm11 memwrite burst disable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am335xevm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI AM335x Evaluation Module\n#\n# For more information please see http://www.ti.com/tool/tmdxevm3358\n#\njtag_rclk 6000\n\nsource [find target/am335x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am437x_idk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Texas Instruments AM437x Industrial Development Kit\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\ntransport select jtag\nadapter speed 30000\n\nsource [find target/am437x.cfg]\n$_TARGETNAME configure -event reset-init { init_platform 0x61a11b32 }\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am43xx_evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Works on both AM437x GP EVM and AM438x ePOS EVM\ntransport select jtag\nadapter speed 16000\n\nsource [find target/am437x.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am625evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021-2022 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments am625 EVM/SK\n# Link: https://www.ti.com/lit/zip/sprr448\n#\n\n# AM625 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am625\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am642evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM642 EVM\n#\n\n# AM642 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC am642\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 250\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_am654evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments AM654 EVM/IDK Base Board\n#\n\n# AM654 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 70\n\nif { ![info exists SOC] } {\n\tset SOC am654\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_beagleboard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OMAP3 BeagleBoard\n#  http://beagleboard.org\n\n# Fall back to 6MHz if RTCK is not supported\njtag_rclk 6000\n\nsource [find target/omap3530.cfg]\n\n# TI-14 JTAG connector\nreset_config trst_only\n\n# Later run:  omap3_dbginit\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_beagleboard_xm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# BeagleBoard xM (DM37x)\n#  http://beagleboard.org\n\nset CHIPTYPE \"dm37x\"\nsource [find target/amdm37x.cfg]\n\n# The TI-14 JTAG connector does not have srst.  CPU reset is handled in\n# hardware.\nreset_config trst_only\n\n# \"amdm37x_dbginit dm37x.cpu\" needs to be run after init.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_beaglebone-base.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# AM335x Beaglebone family base configuration\n#  http://beagleboard.org/bone\n\nsource [find target/am335x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_beaglebone.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# AM335x Beaglebone\n#  http://beagleboard.org/bone\n\n# The JTAG interface is built directly on the board.\nsource [find interface/ftdi/xds100v2.cfg]\n\nadapter speed 16000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_beaglebone_black.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# AM335x Beaglebone Black\n#  http://beagleboard.org/bone\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\nsource [find board/ti_beaglebone-base.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_blaze.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\njtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc13x0_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC13x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\ntransport select jtag\nadapter speed 5500\nsource [find target/ti_cc13x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc13x2_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC13x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc13x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc26x0_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC26x0 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc26x2_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC26x2 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 5500\ntransport select jtag\nsource [find target/ti_cc26x2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc3200_launchxl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI SimpleLink Wi-Fi CC3200 LaunchPad\n#\n# http://www.ti.com/tool/cc3200-launchxl\n#\n\nsource [find interface/ftdi/ti-icdi.cfg]\n\nif { [info exists TRANSPORT] } {\n   transport select $TRANSPORT\n} else {\n   transport select jtag\n}\n\nadapter speed 2500\n\nset WORKAREASIZE 0x40000\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc3220sf_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC3220SF-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc3220sf.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_cc32xx_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI CC32xx-LaunchXL LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 8500\ntransport select swd\nsource [find target/ti_cc32xx.cfg]\n\nreset_config srst_only\nadapter srst delay 1100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_dk-tm4c129.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Tiva C DK-TM4C129X Connected Development Kit\n#\n# http://www.ti.com/tool/dk-tm4c129x\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c129xnczad\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_ek-tm4c123gxl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Tiva C Series ek-tm4c123gxl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c123gxl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c123gh6pm\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_ek-tm4c1294xl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Tiva C Series ek-tm4c1294xl Launchpad Evaluation Kit\n#\n# http://www.ti.com/tool/ek-tm4c1294xl\n#\n\nsource [find interface/ti-icdi.cfg]\n\ntransport select hla_jtag\n\nset WORKAREASIZE 0x8000\nset CHIPNAME tm4c1294ncpdt\n\nsource [find target/stellaris.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_j7200evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J7200 EVM\n#\n\n# J7200 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j7200\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_j721evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721E EVM\n#\n\n# J721E EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721e\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_j721s2evm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments J721s2 EVM\n# Link(SoM): https://www.ti.com/lit/zip/sprr439\n#\n\n# J721s2 EVM has an xds110 onboard.\nsource [find interface/xds110.cfg]\n\ntransport select jtag\n\n# default JTAG configuration has only SRST and no TRST\nreset_config srst_only srst_push_pull\n\n# delay after SRST goes inactive\nadapter srst delay 20\n\nif { ![info exists SOC] } {\n\tset SOC j721s2\n}\n\nsource [find target/ti_k3.cfg]\n\nadapter speed 2500\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_msp432_launchpad.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI MSP432 LaunchPad Evaluation Kit\n#\nsource [find interface/xds110.cfg]\nadapter speed 10000\ntransport select swd\nsource [find target/ti_msp432.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_pandaboard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\njtag_rclk 6000\n\nsource [find target/omap4430.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_pandaboard_es.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\njtag_rclk 6000\n\nsource [find target/omap4460.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_tmdx570ls20susb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TMS570 Microcontroller USB Kit\n# http://www.ti.com/tool/TMDX570LS20SUSB\n\n# Board uses a FT2232H to emulate an XDS100v2 JTAG debugger\n# TODO: board also supports an SCI UART on the 2232's B Bus\nsource [find interface/ftdi/xds100v2.cfg]\n\n# Processor is TMS570LS20216\nsource [find target/ti_tms570ls20xxx.cfg]\n\nreset_config trst_only\n\n# xds100v2 config says add this to the end\ninit\nftdi set_signal PWR_RST 1\njtag arp_init\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/ti_tmdx570ls31usb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter speed 1500\n\nsource [find interface/ftdi/xds100v2.cfg]\nsource [find target/ti_tms570.cfg]\n\nreset_config trst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/tocoding_poplar.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# board configuration for Tocoding Poplar\n#\n\n# board does not feature anything but JTAG\ntransport select jtag\n\nadapter speed 10000\n\n# SRST-only reset configuration\nreset_config srst_only srst_push_pull\n\nsource [find target/hi3798.cfg]\n\n# make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/topas910.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Toshiba TOPAS910 -- TMPA910 Starterkit\n#\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa910.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topas910_init }\n\nproc topas910_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;\n#  // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/topasa900.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Thanks to Pieter Conradie for this script!\n# Target:    Toshiba TOPAS900 -- TMPA900 Starterkit\n######################################\n\n# We add to the minimal configuration.\nsource [find target/tmpa900.cfg]\n\n######################\n# Target configuration\n######################\n\n#$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { topasa900_init }\n\nproc topasa900_init { } {\n# Init PLL\n# my settings\n\tmww 0xf005000c 0x00000007\n\tmww 0xf0050010 0x00000065\n\tmww 0xf005000c 0x000000a7\n\tsleep 10\n\tmdw 0xf0050008\n\tmww 0xf0050008 0x00000002\n\tmww 0xf0050004 0x00000000\n# NEW: set CLKCR5\n\tmww 0xf0050054 0x00000040\n#\n# bplan settings\n#\tmww 0xf0050004 0x00000000\n#\tmww 0xf005000c 0x000000a7\n#\tsleep 10\n#\tmdw 0xf0050008\n#\tmww 0xf0050008 0x00000002\n#\tmww 0xf0050010 0x00000065\n#\tmww 0xf0050054 0x00000040\n\tsleep 10\n# Init SDRAM\n#  _PMCDRV          = 0x00000071;\n#  //\n#  // Initialize SDRAM timing parameter\n#  //\n#  _DMC_CAS_LATENCY = 0x00000006;\n#  _DMC_T_DQSS      = 0x00000000;\n#  _DMC_T_MRD       = 0x00000002;\n#  _DMC_T_RAS       = 0x00000007;\n#\n#  _DMC_T_RC        = 0x0000000A;\n#  _DMC_T_RCD       = 0x00000013;\n#\n#  _DMC_T_RFC       = 0x0000010A;\n#\n#  _DMC_T_RP        = 0x00000013;\n#  _DMC_T_RRD       = 0x00000002;\n#  _DMC_T_WR        = 0x00000002;\n#  _DMC_T_WTR       = 0x00000001;\n#  _DMC_T_XP        = 0x0000000A;\n#  _DMC_T_XSR       = 0x0000000B;\n#  _DMC_T_ESR       = 0x00000014;\n#\n#  //\n#  // Configure SDRAM type parameter\n#  _DMC_MEMORY_CFG  = 0x00008011;\n#  _DMC_USER_CONFIG = 0x00000011;   // 32 bit memory interface\n#\n#\n#  _DMC_REFRESH_PRD = 0x00000A60;\n#  _DMC_CHIP_0_CFG  = 0x000140FC;\n#\n#  _DMC_DIRECT_CMD  = 0x000C0000;\n#  _DMC_DIRECT_CMD  = 0x00000000;\n#\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00040000;\n#  _DMC_DIRECT_CMD  = 0x00080031;\n#  //\n#  // Finally start SDRAM\n#  //\n#  _DMC_MEMC_CMD    = MEMC_CMD_GO;\n#  */\n\n\tmww 0xf0020260 0x00000071\n\tmww 0xf4300014 0x00000006\n\tmww 0xf4300018 0x00000000\n\tmww 0xf430001C 0x00000002\n\tmww 0xf4300020 0x00000007\n\tmww 0xf4300024 0x0000000A\n\tmww 0xf4300028 0x00000013\n\tmww 0xf430002C 0x0000010A\n\tmww 0xf4300030 0x00000013\n\tmww 0xf4300034 0x00000002\n\tmww 0xf4300038 0x00000002\n\tmww 0xf430003C 0x00000001\n\tmww 0xf4300040 0x0000000A\n\tmww 0xf4300044 0x0000000B\n\tmww 0xf4300048 0x00000014\n\tmww 0xf430000C 0x00008011\n\tmww 0xf4300304 0x00000011\n\tmww 0xf4300010 0x00000A60\n\tmww 0xf4300200 0x000140FC\n\tmww 0xf4300008 0x000C0000\n\tmww 0xf4300008 0x00000000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00040000\n\tmww 0xf4300008 0x00080031\n\tmww 0xf4300004 0x00000000\n\n\tsleep 10\n#\tadapter speed NNNN\n\n# remap off in case of IROM boot\n\tmww 0xf0000004 0x00000001\n\n}\n\n# comment the following out if usinf J-Link, it soes not support DCC\narm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x20000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/tp-link_tl-mr3020.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/atheros_ar9331.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tar9331_25mhz_pll_init\n\tsleep 1\n\tar9331_ddr1_init\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0xa1FFE000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/tp-link_wdr4300.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/atheros_ar9344.cfg]\n\nreset_config trst_only separate\n\nproc ar9344_40mhz_pll_init {} {\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x13210f00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x13210f00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_BB_DPLL_BASE_REG\n\tmww 0xb8116188 0x03000000\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\tmww 0xb8050008 0x0130001C\n\n\t# QCA_PLL_CPU_PLL_CFG_REG\n\tmww 0xb8050000 0x40021380\n\t# QCA_PLL_DDR_PLL_CFG_REG\n\tmww 0xb8050004 0x40815800\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x0130801C\n\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0x10810F00\n\tmww 0xb81161C0 0x41C00000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0810F00\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL2_REG\n\tmww 0xb81161C4 0xD0800F00\n\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x03000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x43000000\n\t# QCA_PLL_SRIF_CPU_DPLL3_REG\n\tmww 0xb81161C8 0x030003E8\n\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0x10810F00\n\tmww 0xb8116240 0x41680000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0810F00\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL2_REG\n\tmww 0xb8116244 0xD0800F00\n\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x43000000\n\t# QCA_PLL_SRIF_DDR_DPLL3_REG\n\tmww 0xb8116248 0x03000718\n\n\t# QCA_PLL_CPU_DDR_CLK_CTRL_REG\n\tmww 0xb8050008 0x01308018\n\tmww 0xb8050008 0x01308010\n\tmww 0xb8050008 0x01308000\n\n\t# QCA_PLL_DDR_PLL_DITHER_REG\n\tmww 0xb8050044 0x78180200\n\t# QCA_PLL_CPU_PLL_DITHER_REG\n\tmww 0xb8050048 0x41C00000\n\n}\n\nproc ar9344_ddr_init {} {\n\t# QCA_DDR_CTRL_CFG_REG\n\tmww 0xb8000108 0x40\n\t# QCA_DDR_RD_DATA_THIS_CYCLE_REG\n\tmww 0xb8000018 0xFF\n\t# QCA_DDR_BURST_REG\n\tmww 0xb80000C4 0x74444444\n\t# QCA_DDR_BURST2_REG\n\tmww 0xb80000C8 0x0222\n\t# QCA_AHB_MASTER_TOUT_MAX_REG\n\tmww 0xb80000CC 0xFFFFF\n\n\t# QCA_DDR_CFG_REG\n\tmww 0xb8000000 0xC7D48CD0\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_DDR2_CFG_REG\n\tmww 0xb80000B8 0x0E59\n\t# QCA_DDR_CFG2_REG\n\tmww 0xb8000004 0x9DD0E6A8\n\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x08\n\tmww 0xb8000010 0x10\n\tmww 0xb8000010 0x20\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x02\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x02\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x0133\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\n\t# QCA_DDR_MR_REG\n\tmww 0xb8000008 0x33\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x1\n\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0382\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\t# QCA_DDR_EMR_REG\n\tmww 0xb800000C 0x0402\n\t# QCA_DDR_CTRL_REG\n\tmww 0xb8000010 0x2\n\n\t# QCA_DDR_REFRESH_REG\n\tmww 0xb8000014 0x4270\n\n\t# QCA_DDR_TAP_CTRL_0_REG\n\tmww 0xb800001C 0x0e\n\t# QCA_DDR_TAP_CTRL_1_REG\n\tmww 0xb8000020 0x0e\n\t# QCA_DDR_TAP_CTRL_2_REG\n\tmww 0xb8000024 0x0e\n\t# QCA_DDR_TAP_CTRL_3_REG\n\tmww 0xb8000028 0x0e\n}\n\n$_TARGETNAME configure -event reset-init {\n\n\t# mww 0xb806001c 0x1000000\n\tar9344_40mhz_pll_init\n\tsleep 100\n\n\t# flash remap\n\t# SPI_CONTROL_ADDR\n\tmww 0xbF000004 0x43\n\n\tar9344_ddr_init\n\tsleep 100\n}\n\nset ram_boot_address 0xa0000000\n$_TARGETNAME configure -work-area-phys 0x1d000000 -work-area-size 0x1000\n\nflash bank flash0 ath79 0xbf000000 0 0 0 $_TARGETNAME cs0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/trion_t20_bga256.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Trion® T20 BGA256 Development Kit\n# https://www.efinixinc.com/docs/trion20-devkit-ug-v1.5.pdf\n#\n# works after power cycle or pushing sw1.\n# it is because we cannot control CDONE which is connected to ftdi channel 0\n# note from an006: For JTAG programming, T4, T8, T13, and T20 FPGAs use the\n# CRESET_N and SS_N pins in addition to the standard JTAG pins.\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 1\nftdi layout_init 0x0008 0x008b\nreset_config none\ntransport select jtag\nadapter speed 6000\n\nsource [find fpga/efinix_trion.cfg]\n\n#openocd -f board/trion_t20_bga256.cfg -c \"init\" -c \"pld load 0 outflow/trion_blinker.bit\"\n#ipdbg -start -tap trion.tap -hub 0x8 -port 5555 -tool 0\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/twr-k60f120m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale TWRK60F120M development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' banks\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.2 kinetis 0x00080000 0x40000 0 4 $_TARGETNAME\nflash bank pflash.3 kinetis 0x000c0000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/twr-k60n512.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale TWRK60N512 development board\n#\n\nsource [find target/k60.cfg]\n\n$_TARGETNAME configure -event reset-init {\n\tputs \"-event reset-init occurred\"\n}\n\n#\n# Definitions for the additional 'program flash' bank\n# (instructions and/or data)\n#\nflash bank pflash.1 kinetis 0x00040000 0x40000 0 4 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/twr-vf65gs10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# Board has a 20 pin Cortex+ETM debug connector with only nSRST available\nreset_config srst_only\n\n# This configuration file only deals with the hardware JTAG.\n# There is has also an embedded Kinetis K20 with OpenSDA\n# where a CMSIS-DAP application can be installed.\n\n# Source generic VF6xx target configuration\nsource [find target/vybrid_vf6xx.cfg]\n\n# basic DDR memory init, setting up pad configuration\n# for DDR first then configuring the DDRMC for the\n# board\nproc ddr_init { } {\n\t# iomux ddr\n\tmww phys 0x40048220 0x00000180\n\tmww phys 0x40048224 0x00000180\n\tmww phys 0x40048228 0x00000180\n\tmww phys 0x4004822c 0x00000180\n\tmww phys 0x40048230 0x00000180\n\tmww phys 0x40048234 0x00000180\n\tmww phys 0x40048238 0x00000180\n\tmww phys 0x4004823c 0x00000180\n\tmww phys 0x40048240 0x00000180\n\tmww phys 0x40048244 0x00000180\n\tmww phys 0x40048248 0x00000180\n\tmww phys 0x4004824c 0x00000180\n\tmww phys 0x40048250 0x00000180\n\tmww phys 0x40048254 0x00000180\n\tmww phys 0x40048258 0x00000180\n\tmww phys 0x4004825c 0x00000180\n\tmww phys 0x40048260 0x00000180\n\tmww phys 0x40048264 0x00000180\n\tmww phys 0x40048268 0x00000180\n\tmww phys 0x4004826c 0x00000180\n\tmww phys 0x40048270 0x00000180\n\tmww phys 0x40048274 0x00000180\n\tmww phys 0x40048278 0x00000180\n\tmww phys 0x4004827c 0x00010180\n\tmww phys 0x40048280 0x00010180\n\tmww phys 0x40048284 0x00010180\n\tmww phys 0x40048288 0x00010180\n\tmww phys 0x4004828c 0x00010180\n\tmww phys 0x40048290 0x00010180\n\tmww phys 0x40048294 0x00010180\n\tmww phys 0x40048298 0x00010180\n\tmww phys 0x4004829c 0x00010180\n\tmww phys 0x400482a0 0x00010180\n\tmww phys 0x400482a4 0x00010180\n\tmww phys 0x400482a8 0x00010180\n\tmww phys 0x400482ac 0x00010180\n\tmww phys 0x400482b0 0x00010180\n\tmww phys 0x400482b4 0x00010180\n\tmww phys 0x400482b8 0x00010180\n\tmww phys 0x400482bc 0x00010180\n\tmww phys 0x400482c0 0x00010180\n\tmww phys 0x400482c4 0x00010180\n\tmww phys 0x400482c8 0x00010180\n\tmww phys 0x400482cc 0x00000180\n\tmww phys 0x400482d0 0x00000180\n\tmww phys 0x400482d4 0x00000180\n\tmww phys 0x400482d8 0x00000180\n\tmww phys 0x4004821c 0x000001a0\n\t# ddr_ctrl_init\n\tmww phys 0x400ae000 0x00000600\n\tmww phys 0x400ae008 0x00000020\n\tmww phys 0x400ae028 0x00013880\n\tmww phys 0x400ae02c 0x00030d40\n\tmww phys 0x400ae030 0x0000050c\n\tmww phys 0x400ae034 0x15040400\n\tmww phys 0x400ae038 0x1406040f\n\tmww phys 0x400ae040 0x04040000\n\tmww phys 0x400ae044 0x006db00c\n\tmww phys 0x400ae048 0x00000403\n\tmww phys 0x400ae050 0x01000000\n\tmww phys 0x400ae054 0x00060001\n\tmww phys 0x400ae058 0x000c0000\n\tmww phys 0x400ae05c 0x03000200\n\tmww phys 0x400ae060 0x00000006\n\tmww phys 0x400ae064 0x00010000\n\tmww phys 0x400ae068 0x0c30002c\n\tmww phys 0x400ae070 0x00000000\n\tmww phys 0x400ae074 0x00000003\n\tmww phys 0x400ae078 0x0000000a\n\tmww phys 0x400ae07c 0x003001d4\n\tmww phys 0x400ae084 0x00010000\n\tmww phys 0x400ae088 0x00050500\n\tmww phys 0x400ae098 0x00000000\n\tmww phys 0x400ae09c 0x04001002\n\tmww phys 0x400ae0a4 0x00000001\n\tmww phys 0x400ae0c0 0x00460420\n\tmww phys 0x400ae108 0x01000200\n\tmww phys 0x400ae10c 0x00000040\n\tmww phys 0x400ae114 0x00000200\n\tmww phys 0x400ae118 0x00000040\n\tmww phys 0x400ae120 0x00000000\n\tmww phys 0x400ae124 0x0a010300\n\tmww phys 0x400ae128 0x01014040\n\tmww phys 0x400ae12c 0x01010101\n\tmww phys 0x400ae130 0x03030100\n\tmww phys 0x400ae134 0x01000101\n\tmww phys 0x400ae138 0x0700000c\n\tmww phys 0x400ae13c 0x00000000\n\tmww phys 0x400ae148 0x10000000\n\tmww phys 0x400ae15c 0x01000000\n\tmww phys 0x400ae160 0x00040000\n\tmww phys 0x400ae164 0x00000002\n\tmww phys 0x400ae16c 0x00020000\n\tmww phys 0x400ae180 0x00002819\n\tmww phys 0x400ae184 0x01000000\n\tmww phys 0x400ae188 0x00000000\n\tmww phys 0x400ae18c 0x00000000\n\tmww phys 0x400ae198 0x00000000\n\tmww phys 0x400ae1a4 0x00000c00\n\tmww phys 0x400ae1a8 0x00000000\n\tmww phys 0x400ae1b8 0x0000000c\n\tmww phys 0x400ae1c8 0x00000000\n\tmww phys 0x400ae1cc 0x00000000\n\tmww phys 0x400ae1d4 0x00000000\n\tmww phys 0x400ae1d8 0x01010000\n\tmww phys 0x400ae1e0 0x02020000\n\tmww phys 0x400ae1e4 0x00000202\n\tmww phys 0x400ae1e8 0x01010064\n\tmww phys 0x400ae1ec 0x00010101\n\tmww phys 0x400ae1f0 0x00000064\n\tmww phys 0x400ae1f8 0x00000800\n\tmww phys 0x400ae210 0x00000506\n\tmww phys 0x400ae224 0x00020000\n\tmww phys 0x400ae228 0x01000000\n\tmww phys 0x400ae22c 0x04070303\n\tmww phys 0x400ae230 0x00000040\n\tmww phys 0x400ae23c 0x06000080\n\tmww phys 0x400ae240 0x04070303\n\tmww phys 0x400ae244 0x00000040\n\tmww phys 0x400ae248 0x00000040\n\tmww phys 0x400ae24c 0x000f0000\n\tmww phys 0x400ae250 0x000f0000\n\tmww phys 0x400ae25c 0x00000101\n\tmww phys 0x400ae268 0x682c4000\n\tmww phys 0x400ae26c 0x00000012\n\tmww phys 0x400ae278 0x00000006\n\tmww phys 0x400ae284 0x00010202\n\tmww phys 0x400ae400 0x00002613\n\tmww phys 0x400ae440 0x00002613\n\tmww phys 0x400ae404 0x00002615\n\tmww phys 0x400ae444 0x00002615\n\tmww phys 0x400ae408 0x00210000\n\tmww phys 0x400ae448 0x00210000\n\tmww phys 0x400ae488 0x00210000\n\tmww phys 0x400ae40c 0x0001012a\n\tmww phys 0x400ae44c 0x0001012a\n\tmww phys 0x400ae48c 0x0001012a\n\tmww phys 0x400ae410 0x00002400\n\tmww phys 0x400ae450 0x00002400\n\tmww phys 0x400ae490 0x00002400\n\tmww phys 0x400ae4c4 0x00000000\n\tmww phys 0x400ae4c8 0x00001100\n\tmww phys 0x400ae4d0 0x00010101\n\tmww phys 0x400ae000 0x00000601\n}\n\n# clock control init, setting up basic\n# clocks\nproc clock_init { } {\n\t# captured from u-boot\n\tmww phys 0x4006b040 0xffffffff\n\tmww phys 0x4006b044 0xffffffff\n\tmww phys 0x4006b048 0xffffffff\n\tmww phys 0x4006b04c 0xffffffff\n\tmww phys 0x4006b050 0xffffffff\n\tmww phys 0x4006b058 0xffffffff\n\tmww phys 0x4006b05c 0xffffffff\n\tmww phys 0x4006b060 0xffffffff\n\tmww phys 0x4006b064 0xffffffff\n\tmww phys 0x4006b068 0xffffffff\n\tmww phys 0x40050030 0x00002001\n\tmww phys 0x40050270 0x80002001\n\tmww phys 0x4006b000 0x00011005\n\tmww phys 0x4006b008 0x0001ff24\n\tmww phys 0x4006b00c 0x00000810\n\tmww phys 0x4006b010 0x00cc0000\n\tmww phys 0x4006b014 0x01000000\n\tmww phys 0x4006b018 0x20000000\n\tmww phys 0x4006b01c 0x0000001f\n\tmww phys 0x4006b020 0x00000000\n}\n\n# This function applies the initial configuration after a \"reset init\"\n# command\nproc board_init { } {\n\tclock_init\n\tddr_init\n}\n\n# hook the init function into the reset-init event\n${_TARGETNAME}0 configure -event reset-init { board_init }\n# set a slow default JTAG clock, can be overridden later\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/twr-vf65gs10_cmsisdap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Board configuration file for the Freescale VF65GS10 tower board\n#\n# CMSIS-DAP via USB-OTG connector\n#\nsource [find interface/cmsis-dap.cfg]\n\n# only SWD is supported by the CMSIS-DAP on this board\ntransport select swd\n\n# Source generic part of twr-vf65gs10 configuration\nsource [find board/twr-vf65gs10.cfg]\n\n# override reset configuration\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/tx25_stk5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# -------------------------------------------------------------------------\n# KaRo TX25 CPU Module on a StarterkitV base board\n# http://www.karo-electronics.com/tx25.html\n# -------------------------------------------------------------------------\n\n\nsource [find target/imx25.cfg]\n\n\t#-------------------------------------------------------------------------\n\t# Declare Nand\n\t#-------------------------------------------------------------------------\n\n\tnand device K9F1G08UOC mxc imx25.cpu mx25 hwecc biswap\n\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx25_init }\n\n\nproc tx25_init { } {\n\n\t#-------------------------------------------------------------------------\n\t# AIPS setup - Only setup MPROTx registers. The PACR default values are good.\n\t# Set all MPROTx to be non-bufferable, trusted for R/W,\n\t# not forced to user-mode.\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f00000 0x77777777\n\tmww 0x43f00004 0x77777777\n\tmww 0x53f00000 0x77777777\n\tmww 0x53f00004 0x77777777\n\n\tsleep 100\n\n\t#-------------------------------------------------------------------------\n\t# MAX (Multi-Layer AHB Crossbar Switch) setup\n\t# MPR - priority for MX25 is (SDHC2/SDMA)>USBOTG>RTIC>IAHB>DAHB\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43f04000 0x00043210\n\tmww 0x43f04100 0x00043210\n\tmww 0x43f04200 0x00043210\n\tmww 0x43f04300 0x00043210\n\tmww 0x43f04400 0x00043210\n\n\t# SGPCR - always park on last master\n\tmww 0x43f04010 0x10\n\tmww 0x43f04110 0x10\n\tmww 0x43f04210 0x10\n\tmww 0x43f04310 0x10\n\tmww 0x43f04410 0x10\n\n\t# MGPCR - restore default values\n\tmww 0x43f04800 0x0\n\tmww 0x43f04900 0x0\n\tmww 0x43f04a00 0x0\n\tmww 0x43f04b00 0x0\n\tmww 0x43f04c00 0x0\n\n\t# Configure M3IF registers\n\t# M3IF Control Register (M3IFCTL) for MX25\n\t# MRRP[0] = LCDC           on priority list (1 << 0)  = 0x00000001\n\t# MRRP[1] = MAX1       not on priority list (0 << 1)  = 0x00000000\n\t# MRRP[2] = MAX0       not on priority list (0 << 2)  = 0x00000000\n\t# MRRP[3] = USB HOST   not on priority list (0 << 3)  = 0x00000000\n\t# MRRP[4] = SDMA       not on priority list (0 << 4)  = 0x00000000\n\t# MRRP[5] = SD/ATA/FEC not on priority list (0 << 5)  = 0x00000000\n\t# MRRP[6] = SCMFBC     not on priority list (0 << 6)  = 0x00000000\n\t# MRRP[7] = CSI        not on priority list (0 << 7)  = 0x00000000\n\t#                                                       ----------\n\t#                                                       0x00000001\n\tmww 0xb8003000 0x00000001\n\n\t#-------------------------------------------------------------------------\n\t# configure ARM CLK\n\t#-------------------------------------------------------------------------\n\n\t# Set the Clock CTL (HRM p. 355)\n\tmww 0x53F80008 0x20034000\n\n\t# Setup Clock Gating CTL 0-2 (HRM p. 357)\n\tmww 0x53F8000C 0x1fffffff\n\tmww 0x53F80010 0xffffffff\n\tmww 0x53F80014 0x000fdfff\n\n\t#-------------------------------------------------------------------------\n\t# SDRAM initialization\n\t#-------------------------------------------------------------------------\n\n\t# set to 3.3v SDRAM\n\tmww 0x43FAC454 0x00000800\n\n\t# reset (set up ESDMISC)\n\tmww 0xB8001010 0x00000002\n\n\t# Setup for SDRAM Bank 0\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG0\n\tmww 0xB8001004 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001000 0x92116480\n\tmww 0x80000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001000 0xA2116480\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\tmww 0x80000000 0x0\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001000 0xB2116480\n\tmwb 0x80000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001000 0x82116480\n\n\t# Setup for SDRAM Bank 1\n\t#-------------------------------------------------------------------------\n\n\t# Write ESDCFG1\n\tmww 0xB800100C 0x00095728\n\n\t# CTL SMode = Precharge command\n\tmww 0xB8001008 0x92116480\n\tmww 0x90000400 0x00000000\n\n\t# CTL SMode = Auto Refresh command\n\tmww 0xB8001008 0xA2116480\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\tmww 0x90000000 0x00000000\n\n\t# CTL SMode = Load Mode Register command\n\tmww 0xB8001008 0xB2116480\n\tmwb 0x90000033 0x00\n\n\t# CTL SMode = normal\n\tmww 0xB8001008 0x82116480\n\n\t# GPIO configuration\n\t#-------------------------------------------------------------------------\n\n\tmww 0x43FAC02C 0x00000015\n\tmww 0x53FD0000 0x01000000\n\tmww 0x53FD0004 0x00000080\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/tx27_stk5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# KaRo TX27 CPU Module on a StarterkitV base board\n#\n# http://www.karo-electronics.com/tx27.html\n#\nsource [find target/imx27.cfg]\n\n$_TARGETNAME configure -event gdb-attach { reset init }\n$_TARGETNAME configure -event reset-init { tx27_init }\n\nproc tx27_init { } {\n\t# This setup puts RAM at 0xA0000000\n\t# init_aipi (AIPI1.PSR0, AIPI2.PSR0, AIPI1.PSR1 and AIPI2.PSR1)\n\tmww 0x10000000 0x20040304\n\tmww 0x10020000 0x00000000\n\tmww 0x10000004 0xDFFBFCFB\n\tmww 0x10020004 0xFFFFFFFF\n\n\tsleep 100\n\n\t#init_max ( PORT0.MPR, #PORT0.AMPR, #PORT1.MPR, #PORT1.AMPR, #PORT2.MPR, #PORT2.AMPR)\n\tmww 0x1003F000 0x00302145\n\tmww 0x1003F004 0x00302145\n\tmww 0x1003F100 0x00302145\n\tmww 0x1003F104 0x00302145\n\tmww 0x1003F200 0x00302145\n\tmww 0x1003F204 0x00302145\n\n\t#init_drive_strength (#DSCR3, #DSCR5, #DSCR6, #DSCR7, #DSCR8 )\n\tmww 0x10027828 0x55555555\n\tmww 0x10027830 0x55555555\n\tmww 0x10027834 0x55555555\n\tmww 0x10027838 0x00005005\n\tmww 0x1002783C 0x15555555\n\n\t#init_sdram_speed\n\t#mww 0xD8001010 0x00000004\n\tmww 0xD8001010 0x00000024\n\n\tmww 0xD8001004 0x00395729\n\n\tmww 0xD8001000 0x92120000\n\tmww 0xA0000400 0x0\n\n\tmww 0xD8001000 0xA2120000\n\tmww 0xA0000000 0x0\n\tmww 0xA0000000 0x0\n\n\tmww 0xD8001000 0xB2120000\n\tmdb 0xA0000000\n\tmdb 0xA0000033\n\n\tmww 0xD8001000 0x82126485\n\n\t# =============================================\n\t# Sync mode (AHB Clk = 133MHz ; BCLK = 44.3MHz)\n\t# =============================================\n\tmww 0xD8002000 0x23524E80\n\tmww 0xD8002004 0x10000D03\n\tmww 0xD8002008 0x00720900\n\n\tnand probe 0\n}\n\nnand device tx27.nand mxc $_TARGETNAME mx27 hwecc biswap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/unknown_at91sam9260.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Thanks to Pieter Conradie for this script!\n#\n# Unknown vendor board contains:\n#\n# Atmel AT91SAM9260 : PLLA = 192.512MHz, MCK = 96.256 MHz\n#                     OSCSEL configured for internal RC oscillator (22 to 42 kHz)\n#\n# 16-bit NOR FLASH : Intel JS28F128P30T85 128MBit\n# 32-bit SDRAM : 2 x Samsung K4S561632H-UC75, 4M x 16Bit x 4 Banks\n##################################################################\n\n# We add to the minimal configuration.\nsource [find target/at91sam9260.cfg]\n\n$_TARGETNAME configure -event reset-start {\n        # At reset CPU runs at 22 to 42 kHz.\n        # JTAG Frequency must be 6 times slower.\n        jtag_rclk 3\n        halt\n\t# RSTC_MR : enable user reset, MMU may be enabled... use physical address\n        mww phys 0xfffffd08 0xa5000501\n}\n\n\n$_TARGETNAME configure -event reset-init {\n        mww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc28 0x205dbf09         ;# CKGR_PLLAR: Set PLLA Register for 192.512MHz\n        sleep 20                          ;# wait 20 ms\n        mww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler (divide by 2)\n        sleep 10                          ;# wait 10 ms\n        mww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected (96.256 MHz)\n        sleep 10                          ;# wait 10 ms\n\n\t# Increase JTAG Speed to 6 MHz if RCLK is not supported\n        jtag_rclk 6000\n\n\tarm7_9 dcc_downloads enable       ;# Enable faster DCC downloads\n\n\tmww 0xffffec00 0x01020102         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x09070806         ;# SMC_PULSE0\n\tmww 0xffffec08 0x000d000b         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00001003         ;# SMC_MODE0\n\n\tflash probe 0                     ;# Identify flash bank 0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR  : Select peripheral function for D15..D31\n        mww 0xfffff804 0xffff0000         ;# PIO_PDR  : Disable PIO function for D15..D31\n        mww 0xfffff860 0xffff0000         ;# PIO_PUDR : Disable D15..D31 pull-ups\n\n        mww 0xffffef1c 0x00010102         ;# EBI_CSA  : Assign EBI Chip Select 1 to SDRAM\n                                           #            VDDIOMSEL set for +3V3 memory\n                                           #            Disable D0..D15 pull-ups\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x2a2              ;# SDRAMC_TR : Set refresh timer count to 7us\n}\n\n\n#####################\n# Flash configuration\n#####################\n\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/uptech_2410.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target Configuration for the Uptech 2410 board.\n# This configuration should also work on smdk2410, but I haven't tested it yet.\n# Author: xionglingfeng@Gmail.com\n\nsource [find target/samsung_s3c2410.cfg]\n\n$_TARGETNAME configure -event reset-init { uptech2410_init }\n$_TARGETNAME configure -event gdb-attach { reset init }\n\nproc init_pll_sdram { } {\n\t#echo \"---------- Initializing PLL and SDRAM ---------\"\n\t#watchdog timer disable\n\tmww phys 0x53000000 0x00000000\n\n\t#disable all interrupts\n\tmww phys 0x4a000008 0xffffffff\n\n\t#disable all sub-interrupts\n\tmww phys 0x4a00001c 0x000007ff\n\n\t#clear all source pending bits\n\tmww phys 0x4a000000 0xffffffff\n\n\t#clear all sub-source pending bits\n\tmww phys 0x4a000018 0x000007ff\n\n\t#clear interrupt pending bit\n\tmww phys 0x4a000010 0xffffffff\n\n\t#PLL locktime counter\n\tmww phys 0x4c000000 0x00ffffff\n\n\t#Fin=12MHz Fout=202.8MHz\n\t#mww phys 0x4c000004 0x000a1031\n\n\t#FCLK:HCLK:PCLK = 1:2:4\n\tmww phys 0x4c000014 0x00000003\n\n\n\tmww phys 0x48000000 0x11111110\n\tmww phys 0x48000004 0x00007FFC\n\tmww phys 0x48000008 0x00007FFC\n\tmww phys 0x4800000c 0x00000700\n\tmww phys 0x48000010 0x00000700\n\tmww phys 0x48000014 0x00002E50\n\tmww phys 0x48000018 0x00002E50\n\tmww phys 0x4800001c 0x00018005\n\tmww phys 0x48000020 0x00018005\n\tmww phys 0x48000024 0x008c04e9\n\tmww phys 0x48000028 0x000000b2\n\tmww phys 0x4800002c 0x00000030\n\tmww phys 0x48000030 0x00000030\n}\n\nproc uptech2410_init { } {\n\tinit_pll_sdram\n\t#echo \"---------- Probing Nand flash ----------\"\n\tnand probe 0\n\t#echo \"---------- Enable some functions ----------\"\n}\n\nset _NANDNAME $_CHIPNAME.nand\nnand device $_NANDNAME s3c2410 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_a53x2_dap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex A53x2 through DAP\n\nsource [find interface/vdebug.cfg]\n\nset _CORES 2\nset _CHIPNAME a53\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x1000000\n\n# vdebug select transport\ntransport select dapdirect_swd\n\n# JTAG reset config, frequency and reset delay\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_swdp_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\nsource [find target/vd_aarch64.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_a53x2_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex A53x2 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CORES 2\nset _CHIPNAME a53\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x1000000\nset _CPUTAPID 0x5ba00477\n\n# vdebug select transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_memory.mem_array $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_aarch64.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_m4_dap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m4 through DAP\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m4\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\n\n# vdebug select transport\ntransport select dapdirect_swd\nadapter speed 25000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_swdp_bfm 20ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_m4_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m4 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m4\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\nset _CPUTAPID 0x4ba00477\n\n# vdebug select transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 25000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 20ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_rom.rom $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_m7_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm Cortex m7 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME m7\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x100000\nset _CPUTAPID 0x0ba02477\n\n# vdebug select JTAG transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.u_mcu.u_sys.u_itcm_ram.Mem $_MEMSTART $_MEMSIZE\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_cortex_m.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_pulpissimo_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV Ibex core with Pulpissimo through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME ibex\nset _HARTID 0x20\nset _CPUTAPID 0x249511c3\n\n# vdebug select transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 12500\nadapter srst delay 10\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 40ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[0\\].sram_i.mem_array 0x1c000000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2_pri\\[1\\].sram_i.mem_array 0x1c008000 0x8000\nvdebug mem_path tbench.soc_domain_i.pulp_soc_i.gen_mem_l2\\[0\\].sram_i.mem_array 0x1c010000 0x80000\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x05 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_swerv_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV swerv core with Swerv through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset _CHIPNAME rv32\nset _HARTID 0x00\nset _CPUTAPID 0x1000008b\nset _MEMSTART 0x00000000\nset _MEMSIZE 0x10000\n\n# vdebug select transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path tbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor (up to 4)\nvdebug mem_path tbench.i_ahb_ic.mem $_MEMSTART $_MEMSIZE\n\n# need to explicitly define riscv tap, autoprobing does not work for icapture != 0x01\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\n\njtag arp_init-reset\n\nsource [find target/vd_riscv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/vd_xt8_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Xtensa xt8 through JTAG\n\nsource [find interface/vdebug.cfg]\n\nset CHIPNAME xt8\nset CPUTAPID 0x120034e5\n\n# vdebug select transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\n# BFM hierarchical path and input clk period\nvdebug bfm_path Testbench.u_vd_jtag_bfm 10ns\n\n# DMA Memories to access backdoor, the values come from generated xtensa-core-xt8.cfg\n#vdebug mem_path Testbench.Xtsubsystem.Core0.iram0.iram0.mem.dataArray 0x40000000 0x100000\n#vdebug mem_path Testbench.Xtsubsystem.Core0.dram0.dram0.mem.dataArray 0x3ff00000 0x40000\n\n# Create Xtensa target first\nsource [find target/xtensa.cfg]\n# Generate [xtensa-core-XXX.cfg] via \"xt-gdb --dump-oocd-config\"\nsource  [find target/xtensa-core-xt8.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/verdex.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config for Gumstix Verdex XM4 and XL6P (PXA270)\n\nset CHIPNAME verdex\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# XM4 = 400MHz, XL6P = 600MHz...let's run at 0.1*400MHz=40MHz\nadapter speed 40000\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n# XL6P has 32 MB flash\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x02000000 2 2 $_TARGETNAME\n# XM4 has 16 MB flash\n#flash bank $_CHIPNAME.flash0 cfi 0x00000000 0x01000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/voipac.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config for Voipac PXA270/PXA270M module.\n\nset CHIPNAME voipac\nsource [find target/pxa270.cfg]\n\n# The board supports separate reset lines\n# Override this in the interface config for parallel dongles\nreset_config trst_and_srst separate\n\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank $_CHIPNAME.flash0 cfi 0x00000000 0x2000000 2 2 $_TARGETNAME\nflash bank $_CHIPNAME.flash1 cfi 0x02000000 0x2000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/voltcraft_dso-3062c.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Voltcraft DSO-3062C digital oscilloscope (uses a Samsung S3C2440)\n#\n# http://www.eevblog.com/forum/general-chat/hantek-tekway-dso-hack-get-200mhz-bw-for-free/\n# http://www.mikrocontroller.net/topic/249628\n# http://elinux.org/Das_Oszi\n# http://randomprojects.org/wiki/Voltcraft_DSO-3062C\n#\n\n# Enable this if your JTAG adapter supports multiple transports (JTAG or SWD).\n# Otherwise comment it out, as it will cause an OpenOCD error.\n### transport select jtag\n\nsource [find target/samsung_s3c2440.cfg]\n\nadapter speed 16000\n\n# Samsung K9F1208U0C NAND flash chip (64MiB, 3.3V, 8-bit)\nnand device $_CHIPNAME.nand s3c2440 $_TARGETNAME\n\n# arm7_9 fast_memory_access enable\n# arm7_9 dcc_downloads enable\n\ninit\nreset\nhalt\nscan_chain\ntargets\nnand probe 0\nnand list\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/x300t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is for the T-Home X300T / X301T IPTV box,\n# which are based on IPTV reference designs from Kiss/Cisco KMM-3***\n#\n# It has Sigma Designs SMP8634 chip.\nsource [find target/smp8634.cfg]\n\n$_TARGETNAME configure -event reset-init { x300t_init }\n\n# 1MB CFI capable flash\n# flash bank <name> <driver> <base> <size> <chip_width> <bus_width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0xac000000 0x100000 2 2 $_TARGETNAME\n\nproc x300t_init { } {\n\t# Setup SDRAM config and flash mapping\n\t# initialize ram\n\tmww 0xa003fffc 3\n\tmww 0xa003fffc 2\n\tmww 0xa0030000 0xE34111BA\n\tmww 0xa003fffc 0xa4444\n\tmww 0xa003fffc 0\n\n\t# remap boot vector in CPU local RAM\n\tmww 0xa006f000 0x60000\n\n\t# map flash to CPU address space REG_BASE_cpu_block+CPU_remap4\n\tmww 0x0006f010 0x48000000\n\n\t# map flash addr to REG_BASE_cpu_block + LR_XENV_LOCATION (normally done by XOS)\n\tmww 0x00061ff0 0x48000000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc-2go.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC 2Go\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc1100-boot-kit.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC1100 Boot Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc1100\nset WORKAREASIZE 0x4000\nsource [find target/xmc1xxx.cfg]\n\nreset_config srst_only srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4200-application-kit-actuator.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4200 Application Kit - Actuator\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4200\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4300-relax.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4300 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\nset CHIPNAME xmc4300\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4500-application-kit-general.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4500 Application Kit - General Purpose\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4500-application-kit-sdram.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4500 Application Kit - SDRAM\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4500-relax.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4500 Relax Kit / Relax Lite Kit\n#\n\n#\n# Segger J-Link Lite XMC4500 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4500\nsource [find target/xmc4xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4700-relax.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4700 Relax Lite Kit / Relax Kit for 5V Shields / Relax Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4700\nsource [find target/xmc4xxx.cfg]\n\n# Relax Kit only: N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmc4800-relax.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4800 Relax EtherCAT Kit\n#\n\n#\n# Segger J-Link Lite XMC4200 on-board\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n# There's also an unpopulated 10-pin 0.05\" pinout.\n\nset CHIPNAME xmc4800\nsource [find target/xmc4xxx.cfg]\n\n# N25Q032A qSPI flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xmos_xk-xac-xa8_arm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# xCORE-XA Core Module\n#\n# https://www.xmos.com/support/boards?product=17940\n#\n\n#\n# J-Link OB STM32F103\n#\nsource [find interface/jlink.cfg]\ntransport select swd\n\n#\n# XS1-XAU8A-10\n#\nsource [find target/xmos_xs1-xau8a-10_arm.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xtensa-kc705-ext-dap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence KC705 FPGA Development Platform for Xtensa targets\n# Can be used with various external adapters that support DAP, e.g. JLink\n#\n\nadapter speed 5000\n\n# KC705 supports DAP/JTAG\ntransport select jtag\nset XTENSA_DAP enable\nset XTENSA_DAP_BASE 0x10000\n\n# Create Xtensa target first\nsource [find target/xtensa.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xtensa-kc705-ext.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence KC705 FPGA Development Platform for Xtensa targets\n# Can be used with various external adapters, e.g. Flyswatter2 or JLink\n#\n\nadapter speed 10000\n\n# KC705 supports JTAG only\ntransport select jtag\n\n# Create Xtensa target first\nsource [find target/xtensa.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xtensa-kc705-onboard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence KC705 FPGA Development Platform for Xtensa targets\n# Can be used with on-board (FTDI) adapter or various external adapters\n#\n\nsource [find interface/ftdi/xt_kc705_ml605.cfg]\nadapter speed 10000\n\n# KC705 supports JTAG only\ntransport select jtag\n\n# Create Xtensa target first\nsource [find target/xtensa.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xtensa-palladium-vdebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# for Palladium emulation systems\n#\n\nsource [find interface/vdebug.cfg]\n\n# vdebug select JTAG transport\ntransport select jtag\n\n# JTAG reset config, frequency and reset delay\nreset_config trst_and_srst\nadapter speed 50000\nadapter srst delay 5\n\nsource [find target/vd_xtensa_jtag.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/board/xtensa-rt685-ext.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP RT6XX Developemnt Platform with Xtensa HiFi DSP\n# Can be used with various external adapters that support DAP, e.g. JLink\n#\n\nadapter speed 10000\n\n# RT6XX supports SWD only\ntransport select swd\nset XTENSA_DAP enable\n\n# Create Xtensa target first\nsource [find target/xtensa.cfg]\n\nsource [find target/xtensa-core-nxp_rt600.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/aic.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset AIC_SMR      \t[expr {$AT91C_BASE_AIC + 0x00000000} ]\nglobal AIC_SMR\nset AIC_SVR      \t[expr {$AT91C_BASE_AIC + 0x00000080} ]\nglobal AIC_SVR\nset AIC_IVR      \t[expr {$AT91C_BASE_AIC + 0x00000100} ]\nglobal AIC_IVR\nset AIC_FVR      \t[expr {$AT91C_BASE_AIC + 0x00000104} ]\nglobal AIC_FVR\nset AIC_ISR      \t[expr {$AT91C_BASE_AIC + 0x00000108} ]\nglobal AIC_ISR\nset AIC_IPR      \t[expr {$AT91C_BASE_AIC + 0x0000010C} ]\nglobal AIC_IPR\nset AIC_IMR      \t[expr {$AT91C_BASE_AIC + 0x00000110} ]\nglobal AIC_IMR\nset AIC_CISR     \t[expr {$AT91C_BASE_AIC + 0x00000114} ]\nglobal AIC_CISR\nset AIC_IECR     \t[expr {$AT91C_BASE_AIC + 0x00000120} ]\nglobal AIC_IECR\nset AIC_IDCR     \t[expr {$AT91C_BASE_AIC + 0x00000124} ]\nglobal AIC_IDCR\nset AIC_ICCR     \t[expr {$AT91C_BASE_AIC + 0x00000128} ]\nglobal AIC_ICCR\nset AIC_ISCR     \t[expr {$AT91C_BASE_AIC + 0x0000012C} ]\nglobal AIC_ISCR\nset AIC_EOICR    \t[expr {$AT91C_BASE_AIC + 0x00000130} ]\nglobal AIC_EOICR\nset AIC_SPU      \t[expr {$AT91C_BASE_AIC + 0x00000134} ]\nglobal AIC_SPU\nset AIC_DCR      \t[expr {$AT91C_BASE_AIC + 0x00000138} ]\nglobal AIC_DCR\nset AIC_FFER     \t[expr {$AT91C_BASE_AIC + 0x00000140} ]\nglobal AIC_FFER\nset AIC_FFDR     \t[expr {$AT91C_BASE_AIC + 0x00000144} ]\nglobal AIC_FFDR\nset AIC_FFSR     \t[expr {$AT91C_BASE_AIC + 0x00000148} ]\nglobal AIC_FFSR\n\n\nproc aic_enable_disable_list { VAL ENAME DNAME } {\n    global AT91C_ID\n\n    show_mmr32_bits AT91C_ID $VAL\n\n}\n\nproc show_AIC_IPR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ PENDING\" \"irq not-pending\"\n}\n\nproc show_AIC_IMR_helper { NAME ADDR VAL } {\n    aic_enable_disable_list  $VAL \"IRQ ENABLED\" \"irq disabled\"\n}\n\n\nproc show_AIC { } {\n    global AIC_SMR\n    if [catch { set aaa [read_memory $AIC_SMR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SMR]\n    }\n    echo \"AIC_SMR: Mode & Type\"\n    global AT91C_ID\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo  [format \"%2d: %5s 0x%08x\"  $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n    global AIC_SVR\n    if [catch { set aaa [read_memory $AIC_SVR 32 [expr {32 * 4}]] } msg ] {\n\terror [format \"%s (%s)\" $msg AIC_SVR]\n    }\n    echo \"AIC_SVR: Vectors\"\n    for { set x 0 } { $x < 32 } {  } {\n\techo -n \"   \"\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo -n [format \"%2d: %5s 0x%08x | \" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n\techo [format \"%2d: %5s 0x%08x\" $x $AT91C_ID($x) [lindex $aaa $x]]\n\tincr x\n    }\n\n    foreach REG {\n\tAIC_IVR   AIC_FVR  AIC_ISR\n\tAIC_IPR  AIC_IMR  AIC_CISR  AIC_IECR AIC_IDCR\n\tAIC_ICCR AIC_ISCR AIC_EOICR AIC_SPU  AIC_DCR\n\tAIC_FFER AIC_FFDR AIC_FFSR } {\n\tif [catch { show_mmr32_reg $REG } msg ] {\n\t    error $msg\n\t    break\n\t}\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91_pio.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset PIO_PER\t0x00\t;# Enable Register\nset PIO_PDR\t0x04\t;# Disable Register\nset PIO_PSR\t0x08\t;# Status Register\nset PIO_OER\t0x10\t;# Output Enable Register\nset PIO_ODR\t0x14\t;# Output Disable Register\nset PIO_OSR\t0x18\t;# Output Status Register\nset PIO_IFER\t0x20\t;# Glitch Input Filter Enable\nset PIO_IFDR\t0x24\t;# Glitch Input Filter Disable\nset PIO_IFSR\t0x28\t;# Glitch Input Filter Status\nset PIO_SODR\t0x30\t;# Set Output Data Register\nset PIO_CODR\t0x34\t;# Clear Output Data Register\nset PIO_ODSR\t0x38\t;# Output Data Status Register\nset PIO_PDSR\t0x3c\t;# Pin Data Status Register\nset PIO_IER\t0x40\t;# Interrupt Enable Register\nset PIO_IDR\t0x44\t;# Interrupt Disable Register\nset PIO_IMR\t0x48\t;# Interrupt Mask Register\nset PIO_ISR\t0x4c\t;# Interrupt Status Register\nset PIO_MDER\t0x50\t;# Multi-driver Enable Register\nset PIO_MDDR\t0x54\t;# Multi-driver Disable Register\nset PIO_MDSR\t0x58\t;# Multi-driver Status Register\nset PIO_PUDR\t0x60\t;# Pull-up Disable Register\nset PIO_PUER\t0x64\t;# Pull-up Enable Register\nset PIO_PUSR\t0x68\t;# Pull-up Status Register\nset PIO_ASR\t0x70\t;# Peripheral A Select Register\nset PIO_BSR\t0x74\t;# Peripheral B Select Register\nset PIO_ABSR\t0x78\t;# AB Status Register\nset PIO_OWER\t0xa0\t;# Output Write Enable Register\nset PIO_OWDR\t0xa4\t;# Output Write Disable Register\nset PIO_OWSR\t0xa8\t;# Output Write Status Register\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91_pmc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset\tAT91_PMC_SCER\t\t[expr {$AT91_PMC + 0x00}]\t;# System Clock Enable Register\nset\tAT91_PMC_SCDR\t\t[expr {$AT91_PMC + 0x04}]\t;# System Clock Disable Register\n\nset\tAT91_PMC_SCSR\t\t[expr {$AT91_PMC + 0x08}]\t;# System Clock Status Register\nset\t\tAT91_PMC_PCK\t\t[expr {1 <<  0}]\t\t;# Processor Clock\nset\t\tAT91RM9200_PMC_UDP\t[expr {1 <<  1}]\t\t;# USB Devcice Port Clock [AT91RM9200 only]\nset\t\tAT91RM9200_PMC_MCKUDP\t[expr {1 <<  2}]\t\t;# USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only]\nset\t\tAT91CAP9_PMC_DDR\t[expr {1 <<  2}]\t\t;# DDR Clock [CAP9 revC & some SAM9 only]\nset\t\tAT91RM9200_PMC_UHP\t[expr {1 <<  4}]\t\t;# USB Host Port Clock [AT91RM9200 only]\nset\t\tAT91SAM926x_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91SAM926x only]\nset\t\tAT91CAP9_PMC_UHP\t[expr {1 <<  6}]\t\t;# USB Host Port Clock [AT91CAP9 only]\nset\t\tAT91SAM926x_PMC_UDP\t[expr {1 <<  7}]\t\t;# USB Devcice Port Clock [AT91SAM926x only]\nset\t\tAT91_PMC_PCK0\t\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1\t\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2\t\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3\t\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\t\tAT91_PMC_HCK0\t\t[expr {1 << 16}]\t\t;# AHB Clock (USB host) [AT91SAM9261 only]\nset\t\tAT91_PMC_HCK1\t\t[expr {1 << 17}]\t\t;# AHB Clock (LCD) [AT91SAM9261 only]\n\nset\tAT91_PMC_PCER\t\t[expr {$AT91_PMC + 0x10}]\t;# Peripheral Clock Enable Register\nset\tAT91_PMC_PCDR\t\t[expr {$AT91_PMC + 0x14}]\t;# Peripheral Clock Disable Register\nset\tAT91_PMC_PCSR\t\t[expr {$AT91_PMC + 0x18}]\t;# Peripheral Clock Status Register\n\nset\tAT91_CKGR_UCKR\t\t[expr {$AT91_PMC + 0x1C}]\t;# UTMI Clock Register [some SAM9, CAP9]\nset\t\tAT91_PMC_UPLLEN\t\t[expr {1   << 16}]\t\t;# UTMI PLL Enable\nset\t\tAT91_PMC_UPLLCOUNT\t[expr {0xf << 20}]\t\t;# UTMI PLL Start-up Time\nset\t\tAT91_PMC_BIASEN\t\t[expr {1   << 24}]\t\t;# UTMI BIAS Enable\nset\t\tAT91_PMC_BIASCOUNT\t[expr {0xf << 28}]\t\t;# UTMI BIAS Start-up Time\n\nset\tAT91_CKGR_MOR\t\t[expr {$AT91_PMC + 0x20}]\t;# Main Oscillator Register [not on SAM9RL]\nset\t\tAT91_PMC_MOSCEN\t\t[expr {1    << 0}]\t\t;# Main Oscillator Enable\nset\t\tAT91_PMC_OSCBYPASS\t[expr {1    << 1}]\t\t;# Oscillator Bypass [SAM9x, CAP9]\nset\t\tAT91_PMC_OSCOUNT\t[expr {0xff << 8}]\t\t;# Main Oscillator Start-up Time\n\nset\tAT91_CKGR_MCFR\t\t[expr {$AT91_PMC + 0x24}]\t;# Main Clock Frequency Register\nset\t\tAT91_PMC_MAINF\t\t[expr {0xffff <<  0}]\t\t;# Main Clock Frequency\nset\t\tAT91_PMC_MAINRDY\t[expr {1\t<< 16}]\t\t;# Main Clock Ready\n\nset\tAT91_CKGR_PLLAR\t\t[expr {$AT91_PMC + 0x28}]\t;# PLL A Register\nset\tAT91_CKGR_PLLBR\t\t[expr {$AT91_PMC + 0x2c}]\t;# PLL B Register\nset\t\tAT91_PMC_DIV\t\t[expr {0xff  <<  0}]\t\t;# Divider\nset\t\tAT91_PMC_PLLCOUNT\t[expr {0x3f  <<  8}]\t\t;# PLL Counter\nset\t\tAT91_PMC_OUT\t\t[expr {3     << 14}]\t\t;# PLL Clock Frequency Range\nset\t\tAT91_PMC_MUL\t\t[expr {0x7ff << 16}]\t\t;# PLL Multiplier\nset\t\tAT91_PMC_USBDIV\t\t[expr {3     << 28}]\t\t;# USB Divisor (PLLB only)\nset\t\t\tAT91_PMC_USBDIV_1\t\t[expr {0 << 28}]\nset\t\t\tAT91_PMC_USBDIV_2\t\t[expr {1 << 28}]\nset\t\t\tAT91_PMC_USBDIV_4\t\t[expr {2 << 28}]\nset\t\tAT91_PMC_USB96M\t\t[expr {1     << 28}]\t\t;# Divider by 2 Enable (PLLB only)\nset\t\tAT91_PMC_PLLA_WR_ERRATA\t[expr {1     << 29}]\t\t;# Bit 29 must always be set to 1 when programming the CKGR_PLLAR register\n\nset\tAT91_PMC_MCKR\t\t[expr {$AT91_PMC + 0x30}]\t;# Master Clock Register\nset\t\tAT91_PMC_CSS\t\t[expr {3 <<  0}]\t\t;# Master Clock Selection\nset\t\t\tAT91_PMC_CSS_SLOW\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_CSS_MAIN\t\t[expr {1 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLA\t\t[expr {2 << 0}]\nset\t\t\tAT91_PMC_CSS_PLLB\t\t[expr {3 << 0}]\nset\t\t\tAT91_PMC_CSS_UPLL\t\t[expr {3 << 0}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PRES\t\t[expr {7 <<  2}]\t\t;# Master Clock Prescaler\nset\t\t\tAT91_PMC_PRES_1\t\t\t[expr {0 << 2}]\nset\t\t\tAT91_PMC_PRES_2\t\t\t[expr {1 << 2}]\nset\t\t\tAT91_PMC_PRES_4\t\t\t[expr {2 << 2}]\nset\t\t\tAT91_PMC_PRES_8\t\t\t[expr {3 << 2}]\nset\t\t\tAT91_PMC_PRES_16\t\t[expr {4 << 2}]\nset\t\t\tAT91_PMC_PRES_32\t\t[expr {5 << 2}]\nset\t\t\tAT91_PMC_PRES_64\t\t[expr {6 << 2}]\nset\t\tAT91_PMC_MDIV\t\t[expr {3 <<  8}]\t\t;# Master Clock Division\nset\t\t\tAT91RM9200_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [AT91RM9200 only]\nset\t\t\tAT91RM9200_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_3\t\t[expr {2 << 8}]\nset\t\t\tAT91RM9200_PMC_MDIV_4\t\t[expr {3 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_1\t\t[expr {0 << 8}]\t;# [SAM9,CAP9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_2\t\t[expr {1 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_4\t\t[expr {2 << 8}]\nset\t\t\tAT91SAM9_PMC_MDIV_6\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\t\tAT91SAM9_PMC_MDIV_3\t\t[expr {3 << 8}]\t;# [some SAM9 only]\nset\t\tAT91_PMC_PDIV\t\t[expr {1 << 12}]\t\t;# Processor Clock Division [some SAM9 only]\nset\t\t\tAT91_PMC_PDIV_1\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PDIV_2\t\t\t[expr {1 << 12}]\nset\t\tAT91_PMC_PLLADIV2\t[expr {1 << 12}]\t\t;# PLLA divisor by 2 [some SAM9 only]\nset\t\t\tAT91_PMC_PLLADIV2_OFF\t\t[expr {0 << 12}]\nset\t\t\tAT91_PMC_PLLADIV2_ON\t\t[expr {1 << 12}]\n\nset\tAT91_PMC_USB\t\t[expr {$AT91_PMC + 0x38}]\t;# USB Clock Register [some SAM9 only]\nset\t\tAT91_PMC_USBS\t\t[expr {0x1 <<  0}]\t\t;# USB OHCI Input clock selection\nset\t\t\tAT91_PMC_USBS_PLLA\t\t[expr {0 << 0}]\nset\t\t\tAT91_PMC_USBS_UPLL\t\t[expr {1 << 0}]\nset\t\tAT91_PMC_OHCIUSBDIV\t[expr {0xF <<  8}]\t\t;# Divider for USB OHCI Clock\n\n;# set\tAT91_PMC_PCKR(n)\t[expr {$AT91_PMC + 0x40 + ((n) * 4)}]\t;# Programmable Clock 0-N Registers\nset\t\tAT91_PMC_CSSMCK\t\t[expr {0x1 <<  8}]\t\t;# CSS or Master Clock Selection\nset\t\t\tAT91_PMC_CSSMCK_CSS\t\t[expr {0 << 8}]\nset\t\t\tAT91_PMC_CSSMCK_MCK\t\t[expr {1 << 8}]\n\nset\tAT91_PMC_IER\t\t[expr {$AT91_PMC + 0x60}]\t;# Interrupt Enable Register\nset\tAT91_PMC_IDR\t\t[expr {$AT91_PMC + 0x64}]\t;# Interrupt Disable Register\nset\tAT91_PMC_SR\t\t[expr {$AT91_PMC + 0x68}]\t;# Status Register\nset\t\tAT91_PMC_MOSCS\t\t[expr {1 <<  0}]\t\t;# MOSCS Flag\nset\t\tAT91_PMC_LOCKA\t\t[expr {1 <<  1}]\t\t;# PLLA Lock\nset\t\tAT91_PMC_LOCKB\t\t[expr {1 <<  2}]\t\t;# PLLB Lock\nset\t\tAT91_PMC_MCKRDY\t\t[expr {1 <<  3}]\t\t;# Master Clock\nset\t\tAT91_PMC_LOCKU\t\t[expr {1 <<  6}]\t\t;# UPLL Lock [some SAM9, AT91CAP9 only]\nset\t\tAT91_PMC_OSCSEL\t\t[expr {1 <<  7}]\t\t;# Slow Clock Oscillator [AT91CAP9 revC only]\nset\t\tAT91_PMC_PCK0RDY\t[expr {1 <<  8}]\t\t;# Programmable Clock 0\nset\t\tAT91_PMC_PCK1RDY\t[expr {1 <<  9}]\t\t;# Programmable Clock 1\nset\t\tAT91_PMC_PCK2RDY\t[expr {1 << 10}]\t\t;# Programmable Clock 2\nset\t\tAT91_PMC_PCK3RDY\t[expr {1 << 11}]\t\t;# Programmable Clock 3\nset\tAT91_PMC_IMR\t\t[expr {$AT91_PMC + 0x6c}]\t;# Interrupt Mask Register\n\nset AT91_PMC_PROT\t\t[expr {$AT91_PMC + 0xe4}]\t;# Protect Register [AT91CAP9 revC only]\nset\t\tAT91_PMC_PROTKEY\t0x504d4301\t;# Activation Code\n\nset AT91_PMC_VER\t\t[expr {$AT91_PMC + 0xfc}]\t;# PMC Module Version [AT91CAP9 only]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91_rstc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset AT91_RSTC_CR\t\t[expr {$AT91_RSTC + 0x00}]\t;# Reset Controller Control Register\nset\t\tAT91_RSTC_PROCRST\t[expr {1 << 0}]\t\t;# Processor Reset\nset\t\tAT91_RSTC_PERRST\t[expr {1 << 2}]\t\t;# Peripheral Reset\nset\t\tAT91_RSTC_EXTRST\t[expr {1 << 3}]\t\t;# External Reset\nset\t\tAT91_RSTC_KEY\t\t[expr {0xa5 << 24}]\t\t;# KEY Password\n\nset AT91_RSTC_SR\t\t[expr {$AT91_RSTC + 0x04}]\t;# Reset Controller Status Register\nset\t\tAT91_RSTC_URSTS\t\t[expr {1 << 0}]\t\t;# User Reset Status\nset\t\tAT91_RSTC_RSTTYP\t[expr {7 << 8}]\t\t;# Reset Type\nset\t\t\tAT91_RSTC_RSTTYP_GENERAL\t[expr {0 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WAKEUP\t\t[expr {1 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_WATCHDOG\t[expr {2 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_SOFTWARE\t[expr {3 << 8}]\nset\t\t\tAT91_RSTC_RSTTYP_USER\t[expr {4 << 8}]\nset\t\tAT91_RSTC_NRSTL\t\t[expr {1 << 16}]\t\t;# NRST Pin Level\nset\t\tAT91_RSTC_SRCMP\t\t[expr {1 << 17}]\t\t;# Software Reset Command in Progress\n\nset AT91_RSTC_MR\t\t[expr {$AT91_RSTC + 0x08}]\t;# Reset Controller Mode Register\nset\t\tAT91_RSTC_URSTEN\t[expr {1 << 0}]\t\t;# User Reset Enable\nset\t\tAT91_RSTC_URSTIEN\t[expr {1 << 4}]\t\t;# User Reset Interrupt Enable\nset\t\tAT91_RSTC_ERSTL\t\t[expr {0xf << 8}]\t\t;# External Reset Length\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91_wdt.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset AT91_WDT_CR\t\t[expr {$AT91_WDT + 0x00}]\t;# Watchdog Control Register\nset\t\tAT91_WDT_WDRSTT\t\t[expr {1    << 0}]\t;# Restart\nset\t\tAT91_WDT_KEY\t\t[expr {0xa5 << 24}]\t;# KEY Password\n\nset AT91_WDT_MR\t\t[expr {$AT91_WDT + 0x04}]\t;# Watchdog Mode Register\nset\t\tAT91_WDT_WDV\t\t[expr {0xfff << 0}]\t;# Counter Value\nset\t\tAT91_WDT_WDFIEN\t\t[expr {1     << 12}]\t;# Fault Interrupt Enable\nset\t\tAT91_WDT_WDRSTEN\t[expr {1     << 13}]\t;# Reset Processor\nset\t\tAT91_WDT_WDRPROC\t[expr {1     << 14}]\t;# Timer Restart\nset\t\tAT91_WDT_WDDIS\t\t[expr {1     << 15}]\t;# Watchdog Disable\nset\t\tAT91_WDT_WDD\t\t[expr {0xfff << 16}]\t;# Delta Value\nset\t\tAT91_WDT_WDDBGHLT\t[expr {1     << 28}]\t;# Debug Halt\nset\t\tAT91_WDT_WDIDLEHLT\t[expr {1     << 29}]\t;# Idle Halt\n\nset AT91_WDT_SR\t\t[expr {$AT91_WDT + 0x08}]\t;# Watchdog Status Register\nset\t\tAT91_WDT_WDUNF\t\t[expr {1 << 0}]\t\t;# Watchdog Underflow\nset\t\tAT91_WDT_WDERR\t\t[expr {1 << 1}]\t\t;# Watchdog Error\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam7x128.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x128\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__128K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__32K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\n\n\n\nset AT91C_BASE_SYS       0xFFFFF000\nset AT91C_BASE_AIC       0xFFFFF000\nset AT91C_BASE_PDC_DBGU  0xFFFFF300\nset AT91C_BASE_DBGU      0xFFFFF200\nset AT91C_BASE_PIOA      0xFFFFF400\nset AT91C_BASE_PIOB      0xFFFFF600\nset AT91C_BASE_CKGR      0xFFFFFC20\nset AT91C_BASE_PMC       0xFFFFFC00\nset AT91C_BASE_RSTC      0xFFFFFD00\nset AT91C_BASE_RTTC      0xFFFFFD20\nset AT91C_BASE_PITC      0xFFFFFD30\nset AT91C_BASE_WDTC      0xFFFFFD40\nset AT91C_BASE_VREG      0xFFFFFD60\nset AT91C_BASE_MC        0xFFFFFF00\nset AT91C_BASE_PDC_SPI1  0xFFFE4100\nset AT91C_BASE_SPI1      0xFFFE4000\nset AT91C_BASE_PDC_SPI0  0xFFFE0100\nset AT91C_BASE_SPI0      0xFFFE0000\nset AT91C_BASE_PDC_US1   0xFFFC4100\nset AT91C_BASE_US1       0xFFFC4000\nset AT91C_BASE_PDC_US0   0xFFFC0100\nset AT91C_BASE_US0       0xFFFC0000\nset AT91C_BASE_PDC_SSC   0xFFFD4100\nset AT91C_BASE_SSC       0xFFFD4000\nset AT91C_BASE_TWI       0xFFFB8000\nset AT91C_BASE_PWMC_CH3  0xFFFCC260\nset AT91C_BASE_PWMC_CH2  0xFFFCC240\nset AT91C_BASE_PWMC_CH1  0xFFFCC220\nset AT91C_BASE_PWMC_CH0  0xFFFCC200\nset AT91C_BASE_PWMC      0xFFFCC000\nset AT91C_BASE_UDP       0xFFFB0000\nset AT91C_BASE_TC0       0xFFFA0000\nset AT91C_BASE_TC1       0xFFFA0040\nset AT91C_BASE_TC2       0xFFFA0080\nset AT91C_BASE_TCB       0xFFFA0000\nset AT91C_BASE_CAN_MB0   0xFFFD0200\nset AT91C_BASE_CAN_MB1   0xFFFD0220\nset AT91C_BASE_CAN_MB2   0xFFFD0240\nset AT91C_BASE_CAN_MB3   0xFFFD0260\nset AT91C_BASE_CAN_MB4   0xFFFD0280\nset AT91C_BASE_CAN_MB5   0xFFFD02A0\nset AT91C_BASE_CAN_MB6   0xFFFD02C0\nset AT91C_BASE_CAN_MB7   0xFFFD02E0\nset AT91C_BASE_CAN       0xFFFD0000\nset AT91C_BASE_EMAC      0xFFFDC000\nset AT91C_BASE_PDC_ADC   0xFFFD8100\nset AT91C_BASE_ADC       0xFFFD8000\n\nset AT91C_ID(0) FIQ\nset AT91C_ID(1) SYS\nset AT91C_ID(2) PIOA\nset AT91C_ID(3) PIOB\nset AT91C_ID(4) SPI0\nset AT91C_ID(5) SPI1\nset AT91C_ID(6) US0\nset AT91C_ID(7) US1\nset AT91C_ID(8) SSC\nset AT91C_ID(9) TWI\nset AT91C_ID(10) PWMC\nset AT91C_ID(11) UDP\nset AT91C_ID(12) TC0\nset AT91C_ID(13) TC1\nset AT91C_ID(14) TC2\nset AT91C_ID(15) CAN\nset AT91C_ID(16) EMAC\nset AT91C_ID(17) ADC\nset AT91C_ID(18) \"\"\nset AT91C_ID(19) \"\"\nset AT91C_ID(20) \"\"\nset AT91C_ID(21) \"\"\nset AT91C_ID(22) \"\"\nset AT91C_ID(23) \"\"\nset AT91C_ID(24) \"\"\nset AT91C_ID(25) \"\"\nset AT91C_ID(26) \"\"\nset AT91C_ID(27) \"\"\nset AT91C_ID(28) \"\"\nset AT91C_ID(29) \"\"\nset AT91C_ID(30) IRQ0\nset AT91C_ID(31) IRQ1\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam7x256.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER  atmel\nset CHIP_FAMILY at91sam7\nset CHIP_NAME   at91sam7x256\n# how many flash regions.\nset N_FLASH                1\nset FLASH(0,CHIPSELECT)    -1\nset FLASH(0,BASE)          0x00100000\nset FLASH(0,LEN)           $__256K\nset FLASH(0,HUMAN)         \"internal flash\"\nset FLASH(0,TYPE)          \"flash\"\nset FLASH(0,RWX)           $RWX_R_X\nset FLASH(0,ACCESS_WIDTH)  $ACCESS_WIDTH_ANY\n# how many ram regions.\nset N_RAM                  1\nset RAM(0,CHIPSELECT)      -1\nset RAM(0,BASE)            0x00200000\nset RAM(0,LEN)             $__64K\nset RAM(0,HUMAN)           \"internal ram\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS    1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0xfff00000\nset MMREGS(0,LEN)             0x000fffff\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# no external memory\nset N_XMEM 0\n\nset  AT91C_BASE_SYS              0xFFFFF000\nset  AT91C_BASE_AIC              0xFFFFF000\nset  AT91C_BASE_PDC_DBGU         0xFFFFF300\nset  AT91C_BASE_DBGU             0xFFFFF200\nset  AT91C_BASE_PIOA             0xFFFFF400\nset  AT91C_BASE_PIOB             0xFFFFF600\nset  AT91C_BASE_CKGR             0xFFFFFC20\nset  AT91C_BASE_PMC              0xFFFFFC00\nset  AT91C_BASE_RSTC             0xFFFFFD00\nset  AT91C_BASE_RTTC             0xFFFFFD20\nset  AT91C_BASE_PITC             0xFFFFFD30\nset  AT91C_BASE_WDTC             0xFFFFFD40\nset  AT91C_BASE_VREG             0xFFFFFD60\nset  AT91C_BASE_MC          0xFFFFFF00\nset  AT91C_BASE_PDC_SPI1      0xFFFE4100\nset  AT91C_BASE_SPI1          0xFFFE4000\nset  AT91C_BASE_PDC_SPI0      0xFFFE0100\nset  AT91C_BASE_SPI0          0xFFFE0000\nset  AT91C_BASE_PDC_US1       0xFFFC4100\nset  AT91C_BASE_US1           0xFFFC4000\nset  AT91C_BASE_PDC_US0       0xFFFC0100\nset  AT91C_BASE_US0           0xFFFC0000\nset  AT91C_BASE_PDC_SSC       0xFFFD4100\nset  AT91C_BASE_SSC           0xFFFD4000\nset  AT91C_BASE_TWI           0xFFFB8000\nset  AT91C_BASE_PWMC_CH3      0xFFFCC260\nset  AT91C_BASE_PWMC_CH2      0xFFFCC240\nset  AT91C_BASE_PWMC_CH1      0xFFFCC220\nset  AT91C_BASE_PWMC_CH0      0xFFFCC200\nset  AT91C_BASE_PWMC          0xFFFCC000\nset  AT91C_BASE_UDP           0xFFFB0000\nset  AT91C_BASE_TC0         0xFFFA0000\nset  AT91C_BASE_TC1         0xFFFA0040\nset  AT91C_BASE_TC2         0xFFFA0080\nset  AT91C_BASE_TCB             0xFFFA0000\nset  AT91C_BASE_CAN_MB0         0xFFFD0200\nset  AT91C_BASE_CAN_MB1         0xFFFD0220\nset  AT91C_BASE_CAN_MB2         0xFFFD0240\nset  AT91C_BASE_CAN_MB3         0xFFFD0260\nset  AT91C_BASE_CAN_MB4         0xFFFD0280\nset  AT91C_BASE_CAN_MB5         0xFFFD02A0\nset  AT91C_BASE_CAN_MB6         0xFFFD02C0\nset  AT91C_BASE_CAN_MB7         0xFFFD02E0\nset  AT91C_BASE_CAN             0xFFFD0000\nset  AT91C_BASE_EMAC            0xFFFDC000\nset  AT91C_BASE_PDC_ADC         0xFFFD8100\nset  AT91C_BASE_ADC             0xFFFD8000\n\nset AT91C_ID(0)   \"FIQ\"\nset AT91C_ID(1)   \"SYS\"\nset AT91C_ID(2)   \"PIOA\"\nset AT91C_ID(3)   \"PIOB\"\nset AT91C_ID(4)   \"SPI0\"\nset AT91C_ID(5)   \"SPI1\"\nset AT91C_ID(6)   \"US0\"\nset AT91C_ID(7)   \"US1\"\nset AT91C_ID(8)   \"SSC\"\nset AT91C_ID(9)   \"TWI\"\nset AT91C_ID(10)   \"PWMC\"\nset AT91C_ID(11)   \"UDP\"\nset AT91C_ID(12)   \"TC0\"\nset AT91C_ID(13)   \"TC1\"\nset AT91C_ID(14)   \"TC2\"\nset AT91C_ID(15)   \"CAN\"\nset AT91C_ID(16)   \"EMAC\"\nset AT91C_ID(17)   \"ADC\"\nset AT91C_ID(18)   \"\"\nset AT91C_ID(19)   \"\"\nset AT91C_ID(20)   \"\"\nset AT91C_ID(21)   \"\"\nset AT91C_ID(22)   \"\"\nset AT91C_ID(23)   \"\"\nset AT91C_ID(24)   \"\"\nset AT91C_ID(25)   \"\"\nset AT91C_ID(26)   \"\"\nset AT91C_ID(27)   \"\"\nset AT91C_ID(28)   \"\"\nset AT91C_ID(29)   \"\"\nset AT91C_ID(30)   \"IRQ0\"\nset AT91C_ID(31)   \"IRQ1\"\n\n\nsource [find chip/atmel/at91/aic.tcl]\nsource [find chip/atmel/at91/usarts.tcl]\nsource [find chip/atmel/at91/pmc.tcl]\nsource [find chip/atmel/at91/rtt.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9261.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9261_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9261_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9261_ID_PIOC\t4\t;# Parallel IO Controller C\nset AT91SAM9261_ID_US0\t6\t;# USART 0\nset AT91SAM9261_ID_US1\t7\t;# USART 1\nset AT91SAM9261_ID_US2\t8\t;# USART 2\nset AT91SAM9261_ID_MCI\t9\t;# Multimedia Card Interface\nset AT91SAM9261_ID_UDP\t10\t;# USB Device Port\nset AT91SAM9261_ID_TWI\t11\t;# Two-Wire Interface\nset AT91SAM9261_ID_SPI0\t12\t;# Serial Peripheral Interface 0\nset AT91SAM9261_ID_SPI1\t13\t;# Serial Peripheral Interface 1\nset AT91SAM9261_ID_SSC0\t14\t;# Serial Synchronous Controller 0\nset AT91SAM9261_ID_SSC1\t15\t;# Serial Synchronous Controller 1\nset AT91SAM9261_ID_SSC2\t16\t;# Serial Synchronous Controller 2\nset AT91SAM9261_ID_TC0\t17\t;# Timer Counter 0\nset AT91SAM9261_ID_TC1\t18\t;# Timer Counter 1\nset AT91SAM9261_ID_TC2\t19\t;# Timer Counter 2\nset AT91SAM9261_ID_UHP\t20\t;# USB Host port\nset AT91SAM9261_ID_LCDC\t21\t;# LDC Controller\nset AT91SAM9261_ID_IRQ0\t29\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9261_ID_IRQ1\t30\t;# Advanced Interrupt Controller (IRQ1)\nset AT91SAM9261_ID_IRQ2\t31\t;# Advanced Interrupt Controller (IRQ2)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9261_BASE_TCB0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC0\t\t0xfffa0000\nset AT91SAM9261_BASE_TC1\t\t0xfffa0040\nset AT91SAM9261_BASE_TC2\t\t0xfffa0080\nset AT91SAM9261_BASE_UDP\t\t0xfffa4000\nset AT91SAM9261_BASE_MCI\t\t0xfffa8000\nset AT91SAM9261_BASE_TWI\t\t0xfffac000\nset AT91SAM9261_BASE_US0\t\t0xfffb0000\nset AT91SAM9261_BASE_US1\t\t0xfffb4000\nset AT91SAM9261_BASE_US2\t\t0xfffb8000\nset AT91SAM9261_BASE_SSC0\t\t0xfffbc000\nset AT91SAM9261_BASE_SSC1\t\t0xfffc0000\nset AT91SAM9261_BASE_SSC2\t\t0xfffc4000\nset AT91SAM9261_BASE_SPI0\t\t0xfffc8000\nset AT91SAM9261_BASE_SPI1\t\t0xfffcc000\nset AT91_BASE_SYS\t\t\t0xffffea00\n\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_SDRAMC\t0xffffea00\nset AT91_SMC\t0xffffec00\nset AT91_MATRIX\t0xffffee00\nset AT91_AIC\t0xfffff000\nset AT91_DBGU\t0xfffff200\nset AT91_PIOA\t0xfffff400\nset AT91_PIOB\t0xfffff600\nset AT91_PIOC\t0xfffff800\nset AT91_PMC\t0xfffffc00\nset AT91_RSTC\t0xfffffd00\nset AT91_SHDWC\t0xfffffd10\nset AT91_RTT\t0xfffffd20\nset AT91_PIT\t0xfffffd30\nset AT91_WDT\t0xfffffd40\nset AT91_GPBR\t0xfffffd50\n\nset AT91_USART0\t$AT91SAM9261_BASE_US0\nset AT91_USART1\t$AT91SAM9261_BASE_US1\nset AT91_USART2\t$AT91SAM9261_BASE_US2\n\n\n#\n# Internal Memory.\n#\nset AT91SAM9261_SRAM_BASE\t0x00300000\t;# Internal SRAM base address\nset AT91SAM9261_SRAM_SIZE\t0x00028000\t;# Internal SRAM size (160Kb)\n\nset AT91SAM9261_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9261_ROM_SIZE\t0x00008000\t;# Internal ROM size (32Kb)\n\nset AT91SAM9261_UHP_BASE\t0x00500000\t;# USB Host controller\nset AT91SAM9261_LCDC_BASE\t0x00600000\t;# LDC controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9261\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9261_matrix.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset AT91_MATRIX_MCFG\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register #\nset\t\tAT91_MATRIX_RCB0\t[expr {1 << 0}]\t\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t[expr {1 << 1}]\t\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x04}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x08}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x0C}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x10}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x14}]\t;# Slave Configuration Register 4\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {7    << 18}]\t;# Fixed Index of Default Master\n\nset AT91_MATRIX_TCR\t\t[expr {$AT91_MATRIX + 0x24}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_64\t\t[expr {7 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_64\t\t[expr {7 << 4}]\n\nset AT91_MATRIX_EBICSA\t[expr {$AT91_MATRIX + 0x30}]\t;# EBI Chip Select Assignment Register\nset\t\tAT91_MATRIX_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_CS4A_SMC_CF1\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_CS5A_SMC_CF2\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\n\nset AT91_MATRIX_USBPUCR\t[expr {$AT91_MATRIX + 0x34}]\t;# USB Pad Pull-Up Control Register\nset\t\tAT91_MATRIX_USBPUCR_PUON\t[expr {1 << 30}]\t;# USB Device PAD Pull-up Enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9263.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Peripheral identifiers/interrupts.\n#\nset AT91_ID_FIQ\t\t0\t;# Advanced Interrupt Controller (FIQ)\nset AT91_ID_SYS\t\t1\t;# System Peripherals\nset AT91SAM9263_ID_PIOA\t2\t;# Parallel IO Controller A\nset AT91SAM9263_ID_PIOB\t3\t;# Parallel IO Controller B\nset AT91SAM9263_ID_PIOCDE\t4\t;# Parallel IO Controller C, D and E\nset AT91SAM9263_ID_US0\t7\t;# USART 0\nset AT91SAM9263_ID_US1\t8\t;# USART 1\nset AT91SAM9263_ID_US2\t9\t;# USART 2\nset AT91SAM9263_ID_MCI0\t10\t;# Multimedia Card Interface 0\nset AT91SAM9263_ID_MCI1\t11\t;# Multimedia Card Interface 1\nset AT91SAM9263_ID_CAN\t12\t;# CAN\nset AT91SAM9263_ID_TWI\t13\t;# Two-Wire Interface\nset AT91SAM9263_ID_SPI0\t14\t;# Serial Peripheral Interface 0\nset AT91SAM9263_ID_SPI1\t15\t;# Serial Peripheral Interface 1\nset AT91SAM9263_ID_SSC0\t16\t;# Serial Synchronous Controller 0\nset AT91SAM9263_ID_SSC1\t17\t;# Serial Synchronous Controller 1\nset AT91SAM9263_ID_AC97C\t18\t;# AC97 Controller\nset AT91SAM9263_ID_TCB\t19\t;# Timer Counter 0, 1 and 2\nset AT91SAM9263_ID_PWMC\t20\t;# Pulse Width Modulation Controller\nset AT91SAM9263_ID_EMAC\t21\t;# Ethernet\nset AT91SAM9263_ID_2DGE\t23\t;# 2D Graphic Engine\nset AT91SAM9263_ID_UDP\t24\t;# USB Device Port\nset AT91SAM9263_ID_ISI\t25\t;# Image Sensor Interface\nset AT91SAM9263_ID_LCDC\t26\t;# LCD Controller\nset AT91SAM9263_ID_DMA\t27\t;# DMA Controller\nset AT91SAM9263_ID_UHP\t29\t;# USB Host port\nset AT91SAM9263_ID_IRQ0\t30\t;# Advanced Interrupt Controller (IRQ0)\nset AT91SAM9263_ID_IRQ1\t31\t;# Advanced Interrupt Controller (IRQ1)\n\n\n#\n# User Peripheral physical base addresses.\n#\nset AT91SAM9263_BASE_UDP\t\t0xfff78000\nset AT91SAM9263_BASE_TCB0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC0\t\t0xfff7c000\nset AT91SAM9263_BASE_TC1\t\t0xfff7c040\nset AT91SAM9263_BASE_TC2\t\t0xfff7c080\nset AT91SAM9263_BASE_MCI0\t\t0xfff80000\nset AT91SAM9263_BASE_MCI1\t\t0xfff84000\nset AT91SAM9263_BASE_TWI\t\t0xfff88000\nset AT91SAM9263_BASE_US0\t\t0xfff8c000\nset AT91SAM9263_BASE_US1\t\t0xfff90000\nset AT91SAM9263_BASE_US2\t\t0xfff94000\nset AT91SAM9263_BASE_SSC0\t\t0xfff98000\nset AT91SAM9263_BASE_SSC1\t\t0xfff9c000\nset AT91SAM9263_BASE_AC97C\t\t0xfffa0000\nset AT91SAM9263_BASE_SPI0\t\t0xfffa4000\nset AT91SAM9263_BASE_SPI1\t\t0xfffa8000\nset AT91SAM9263_BASE_CAN\t\t0xfffac000\nset AT91SAM9263_BASE_PWMC\t\t0xfffb8000\nset AT91SAM9263_BASE_EMAC\t\t0xfffbc000\nset AT91SAM9263_BASE_ISI\t\t0xfffc4000\nset AT91SAM9263_BASE_2DGE\t\t0xfffc8000\nset AT91_BASE_SYS\t\t\t0xffffe000\n\n#\n# System Peripherals (offset from AT91_BASE_SYS)\n#\nset AT91_ECC0\t\t0xffffe000\nset AT91_SDRAMC0\t0xffffe200\nset AT91_SMC0\t\t0xffffe400\nset AT91_ECC1\t\t0xffffe600\nset AT91_SDRAMC1\t0xffffe800\nset AT91_SMC1\t\t0xffffea00\nset AT91_MATRIX\t\t0xffffec00\nset AT91_CCFG\t\t0xffffed10\nset AT91_DBGU\t\t0xffffee00\nset AT91_AIC\t\t0xfffff000\nset AT91_PIOA\t\t0xfffff200\nset AT91_PIOB\t\t0xfffff400\nset AT91_PIOC\t\t0xfffff600\nset AT91_PIOD\t\t0xfffff800\nset AT91_PIOE\t\t0xfffffa00\nset AT91_PMC\t\t0xfffffc00\nset AT91_RSTC\t\t0xfffffd00\nset AT91_SHDWC\t\t0xfffffd10\nset AT91_RTT0\t\t0xfffffd20\nset AT91_PIT\t\t0xfffffd30\nset AT91_WDT\t\t0xfffffd40\nset AT91_RTT1\t\t0xfffffd50\nset AT91_GPBR\t\t0xfffffd60\n\nset AT91_USART0\t$AT91SAM9263_BASE_US0\nset AT91_USART1\t$AT91SAM9263_BASE_US1\nset AT91_USART2\t$AT91SAM9263_BASE_US2\n\nset AT91_SMC\t$AT91_SMC0\nset AT91_SDRAMC\t$AT91_SDRAMC0\n\n#\n# Internal Memory.\n#\nset AT91SAM9263_SRAM0_BASE\t0x00300000\t;# Internal SRAM 0 base address\nset AT91SAM9263_SRAM0_SIZE\t0x00014000\t;# Internal SRAM 0 size (80Kb)\n\nset AT91SAM9263_ROM_BASE\t0x00400000\t;# Internal ROM base address\nset AT91SAM9263_ROM_SIZE\t0x00020000\t;# Internal ROM size (128Kb)\n\nset AT91SAM9263_SRAM1_BASE\t0x00500000\t;# Internal SRAM 1 base address\nset AT91SAM9263_SRAM1_SIZE\t0x00004000\t;# Internal SRAM 1 size (16Kb)\n\nset AT91SAM9263_LCDC_BASE\t0x00700000\t;# LCD Controller\nset AT91SAM9263_DMAC_BASE\t0x00800000\t;# DMA Controller\nset AT91SAM9263_UHP_BASE\t0x00a00000\t;# USB Host controller\n\n#\n# Cpu Name\n#\nset AT91_CPU_NAME\t\"AT91SAM9263\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9263_matrix.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset AT91_MATRIX_MCFG0\t[expr {$AT91_MATRIX + 0x00}]\t;# Master Configuration Register 0\nset AT91_MATRIX_MCFG1\t[expr {$AT91_MATRIX + 0x04}]\t;# Master Configuration Register 1\nset AT91_MATRIX_MCFG2\t[expr {$AT91_MATRIX + 0x08}]\t;# Master Configuration Register 2\nset AT91_MATRIX_MCFG3\t[expr {$AT91_MATRIX + 0x0C}]\t;# Master Configuration Register 3\nset AT91_MATRIX_MCFG4\t[expr {$AT91_MATRIX + 0x10}]\t;# Master Configuration Register 4\nset AT91_MATRIX_MCFG5\t[expr {$AT91_MATRIX + 0x14}]\t;# Master Configuration Register 5\nset AT91_MATRIX_MCFG6\t[expr {$AT91_MATRIX + 0x18}]\t;# Master Configuration Register 6\nset AT91_MATRIX_MCFG7\t[expr {$AT91_MATRIX + 0x1C}]\t;# Master Configuration Register 7\nset AT91_MATRIX_MCFG8\t[expr {$AT91_MATRIX + 0x20}]\t;# Master Configuration Register 8\nset\t\tAT91_MATRIX_ULBT\t[expr {7 << 0}]\t;# Undefined Length Burst Type\nset\t\t\tAT91_MATRIX_ULBT_INFINITE\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SINGLE\t\t[expr {1 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_FOUR\t\t[expr {2 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_EIGHT\t\t[expr {3 << 0}]\nset\t\t\tAT91_MATRIX_ULBT_SIXTEEN\t[expr {4 << 0}]\n\nset AT91_MATRIX_SCFG0\t[expr {$AT91_MATRIX + 0x40}]\t;# Slave Configuration Register 0\nset AT91_MATRIX_SCFG1\t[expr {$AT91_MATRIX + 0x44}]\t;# Slave Configuration Register 1\nset AT91_MATRIX_SCFG2\t[expr {$AT91_MATRIX + 0x48}]\t;# Slave Configuration Register 2\nset AT91_MATRIX_SCFG3\t[expr {$AT91_MATRIX + 0x4C}]\t;# Slave Configuration Register 3\nset AT91_MATRIX_SCFG4\t[expr {$AT91_MATRIX + 0x50}]\t;# Slave Configuration Register 4\nset AT91_MATRIX_SCFG5\t[expr {$AT91_MATRIX + 0x54}]\t;# Slave Configuration Register 5\nset AT91_MATRIX_SCFG6\t[expr {$AT91_MATRIX + 0x58}]\t;# Slave Configuration Register 6\nset AT91_MATRIX_SCFG7\t[expr {$AT91_MATRIX + 0x5C}]\t;# Slave Configuration Register 7\nset\t\tAT91_MATRIX_SLOT_CYCLE\t\t[expr {0xff << 0}]\t;# Maximum Number of Allowed Cycles for a Burst\nset\t\tAT91_MATRIX_DEFMSTR_TYPE\t[expr {3    << 16}]\t;# Default Master Type\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_NONE\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_LAST\t[expr {1 << 16}]\nset\t\t\tAT91_MATRIX_DEFMSTR_TYPE_FIXED\t[expr {2 << 16}]\nset\t\tAT91_MATRIX_FIXED_DEFMSTR\t[expr {0xf  << 18}]\t;# Fixed Index of Default Master\nset\t\tAT91_MATRIX_ARBT\t\t[expr {3    << 24}]\t;# Arbitration Type\nset\t\t\tAT91_MATRIX_ARBT_ROUND_ROBIN\t[expr {0 << 24}]\nset\t\t\tAT91_MATRIX_ARBT_FIXED_PRIORITY\t[expr {1 << 24}]\n\nset AT91_MATRIX_PRAS0\t[expr {$AT91_MATRIX + 0x80}]\t;# Priority Register A for Slave 0\nset AT91_MATRIX_PRBS0\t[expr {$AT91_MATRIX + 0x84}]\t;# Priority Register B for Slave 0\nset AT91_MATRIX_PRAS1\t[expr {$AT91_MATRIX + 0x88}]\t;# Priority Register A for Slave 1\nset AT91_MATRIX_PRBS1\t[expr {$AT91_MATRIX + 0x8C}]\t;# Priority Register B for Slave 1\nset AT91_MATRIX_PRAS2\t[expr {$AT91_MATRIX + 0x90}]\t;# Priority Register A for Slave 2\nset AT91_MATRIX_PRBS2\t[expr {$AT91_MATRIX + 0x94}]\t;# Priority Register B for Slave 2\nset AT91_MATRIX_PRAS3\t[expr {$AT91_MATRIX + 0x98}]\t;# Priority Register A for Slave 3\nset AT91_MATRIX_PRBS3\t[expr {$AT91_MATRIX + 0x9C}]\t;# Priority Register B for Slave 3\nset AT91_MATRIX_PRAS4\t[expr {$AT91_MATRIX + 0xA0}]\t;# Priority Register A for Slave 4\nset AT91_MATRIX_PRBS4\t[expr {$AT91_MATRIX + 0xA4}]\t;# Priority Register B for Slave 4\nset AT91_MATRIX_PRAS5\t[expr {$AT91_MATRIX + 0xA8}]\t;# Priority Register A for Slave 5\nset AT91_MATRIX_PRBS5\t[expr {$AT91_MATRIX + 0xAC}]\t;# Priority Register B for Slave 5\nset AT91_MATRIX_PRAS6\t[expr {$AT91_MATRIX + 0xB0}]\t;# Priority Register A for Slave 6\nset AT91_MATRIX_PRBS6\t[expr {$AT91_MATRIX + 0xB4}]\t;# Priority Register B for Slave 6\nset AT91_MATRIX_PRAS7\t[expr {$AT91_MATRIX + 0xB8}]\t;# Priority Register A for Slave 7\nset AT91_MATRIX_PRBS7\t[expr {$AT91_MATRIX + 0xBC}]\t;# Priority Register B for Slave 7\nset\t\tAT91_MATRIX_M0PR\t\t[expr {3 << 0}]\t\t;# Master 0 Priority\nset\t\tAT91_MATRIX_M1PR\t\t[expr {3 << 4}]\t\t;# Master 1 Priority\nset\t\tAT91_MATRIX_M2PR\t\t[expr {3 << 8}]\t\t;# Master 2 Priority\nset\t\tAT91_MATRIX_M3PR\t\t[expr {3 << 12}]\t;# Master 3 Priority\nset\t\tAT91_MATRIX_M4PR\t\t[expr {3 << 16}]\t;# Master 4 Priority\nset\t\tAT91_MATRIX_M5PR\t\t[expr {3 << 20}]\t;# Master 5 Priority\nset\t\tAT91_MATRIX_M6PR\t\t[expr {3 << 24}]\t;# Master 6 Priority\nset\t\tAT91_MATRIX_M7PR\t\t[expr {3 << 28}]\t;# Master 7 Priority\nset\t\tAT91_MATRIX_M8PR\t\t[expr {3 << 0}]\t\t;# Master 8 Priority (in Register B)\n\nset AT91_MATRIX_MRCR\t[expr {$AT91_MATRIX + 0x100}]\t;# Master Remap Control Register\nset\t\tAT91_MATRIX_RCB0\t\t[expr {1 << 0}]\t;# Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master)\nset\t\tAT91_MATRIX_RCB1\t\t[expr {1 << 1}]\t;# Remap Command for AHB Master 1 (ARM926EJ-S Data Master)\nset\t\tAT91_MATRIX_RCB2\t\t[expr {1 << 2}]\nset\t\tAT91_MATRIX_RCB3\t\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_RCB4\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_RCB5\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_RCB6\t\t[expr {1 << 6}]\nset\t\tAT91_MATRIX_RCB7\t\t[expr {1 << 7}]\nset\t\tAT91_MATRIX_RCB8\t\t[expr {1 << 8}]\n\nset AT91_MATRIX_TCMR\t[expr {$AT91_MATRIX + 0x114}]\t;# TCM Configuration Register\nset\t\tAT91_MATRIX_ITCM_SIZE\t\t[expr {0xf << 0}]\t;# Size of ITCM enabled memory block\nset\t\t\tAT91_MATRIX_ITCM_0\t\t[expr {0 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_16\t\t[expr {5 << 0}]\nset\t\t\tAT91_MATRIX_ITCM_32\t\t[expr {6 << 0}]\nset\t\tAT91_MATRIX_DTCM_SIZE\t\t[expr {0xf << 4}]\t;# Size of DTCM enabled memory block\nset\t\t\tAT91_MATRIX_DTCM_0\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_16\t\t[expr {5 << 4}]\nset\t\t\tAT91_MATRIX_DTCM_32\t\t[expr {6 << 4}]\n\nset AT91_MATRIX_EBI0CSA\t[expr {$AT91_MATRIX + 0x120}]\t;# EBI0 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI0_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI0_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI0_CS3A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignmen\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI0_CS4A\t\t[expr {1 << 4}]\t;# Chip Select 4 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC\t\t[expr {0 << 4}]\nset\t\t\tAT91_MATRIX_EBI0_CS4A_SMC_CF1\t\t[expr {1 << 4}]\nset\t\tAT91_MATRIX_EBI0_CS5A\t\t[expr {1 << 5}]\t;# Chip Select 5 Assignment\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC\t\t[expr {0 << 5}]\nset\t\t\tAT91_MATRIX_EBI0_CS5A_SMC_CF2\t\t[expr {1 << 5}]\nset\t\tAT91_MATRIX_EBI0_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI0_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI0_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n\nset AT91_MATRIX_EBI1CSA\t[expr {$AT91_MATRIX + 0x124}]\t;# EBI1 Chip Select Assignment Register\nset\t\tAT91_MATRIX_EBI1_CS1A\t\t[expr {1 << 1}]\t;# Chip Select 1 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SMC\t\t[expr {0 << 1}]\nset\t\t\tAT91_MATRIX_EBI1_CS1A_SDRAMC\t\t[expr {1 << 1}]\nset\t\tAT91_MATRIX_EBI1_CS2A\t\t[expr {1 << 3}]\t;# Chip Select 3 Assignment\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC\t\t[expr {0 << 3}]\nset\t\t\tAT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA\t[expr {1 << 3}]\nset\t\tAT91_MATRIX_EBI1_DBPUC\t\t[expr {1 << 8}]\t;# Data Bus Pull-up Configuration\nset\t\tAT91_MATRIX_EBI1_VDDIOMSEL\t[expr {1 << 16}]\t;# Memory voltage selection\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_1_8V\t\t[expr {0 << 16}]\nset\t\t\tAT91_MATRIX_EBI1_VDDIOMSEL_3_3V\t\t[expr {1 << 16}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9_init.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nuplevel #0 [list source [find chip/atmel/at91/at91sam9_sdramc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pmc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_pio.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_rstc.cfg]]\nuplevel #0 [list source [find chip/atmel/at91/at91_wdt.cfg]]\n\nproc at91sam9_reset_start { } {\n\n\tarm7_9 fast_memory_access disable\n\n\tjtag_rclk 8\n\thalt\n\twait_halt 10000\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | (5 << 8)}]\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# RSTC_MR : enable user reset.\n}\n\nproc at91sam9_reset_init { config } {\n\n\tmww $::AT91_WDT_MR $config(wdt_mr_val)\t;# disable watchdog\n\n\tset ckgr_mor [expr {$::AT91_PMC_MOSCEN | (255 << 8)}]\n\n\tmww $::AT91_CKGR_MOR $ckgr_mor\t;# CKGR_MOR - enable main osc.\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MOSCS}] != $::AT91_PMC_MOSCS } { sleep 1 }\n\n\tset pllar_val\t$::AT91_PMC_PLLA_WR_ERRATA ;# Bit 29 must be 1 when prog\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_OUT}]\n\tset pllar_val\t[expr {$pllar_val | $::AT91_PMC_PLLCOUNT}]\n\tset pllar_val\t[expr {$pllar_val | ($config(master_pll_mul) - 1) << 16}]\n\tset pllar_val\t[expr {$pllar_val | $config(master_pll_div)}]\n\n\tmww $::AT91_CKGR_PLLAR $pllar_val\t ;# CKGR_PLLA - (18.432MHz/13)*141 = 199.9 MHz\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_LOCKA}] != $::AT91_PMC_LOCKA } { sleep 1 }\n\n\t;# PCK/2 = MCK Master Clock from PLLA\n\tset mckr_val\t$::AT91_PMC_CSS_PLLA\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PRES_1}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91SAM9_PMC_MDIV_2}]\n\tset mckr_val\t[expr {$mckr_val | $::AT91_PMC_PDIV_1}]\n\n\tmww $::AT91_PMC_MCKR $mckr_val\t;# PMC_MCKR (MCLK: 0x102 - (CLK/2)MHZ, 0x202 - (CLK/3)MHz)\n\twhile { [expr {[mrw $::AT91_PMC_SR] & $::AT91_PMC_MCKRDY}] != $::AT91_PMC_MCKRDY } { sleep 1 }\n\n\t## switch JTAG clock to highspeed clock\n\tjtag_rclk 0\n\n\tarm7_9 dcc_downloads enable\t;# Enable faster DCC downloads\n\tarm7_9 fast_memory_access enable\n\n\tset rstc_mr_val $::AT91_RSTC_KEY\n\tset rstc_mr_val [expr {$rstc_mr_val | $::AT91_RSTC_URSTEN}]\n\tmww $::AT91_RSTC_MR $rstc_mr_val\t;# user reset enable\n\n\tif { [info exists config(sdram_piod)] } {\n\t\tset pdr_addr\t[expr {$::AT91_PIOD + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOD + $::PIO_PUDR}]\n\t\tset asr_addr\t[expr {$::AT91_PIOD + $::PIO_ASR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t\tmww $asr_addr 0xffff0000\n\t} else {\n\t\tset pdr_addr\t[expr {$::AT91_PIOC + $::PIO_PDR}]\n\t\tset pudr_addr\t[expr {$::AT91_PIOC + $::PIO_PUDR}]\n\t\tmww $pdr_addr 0xffff0000\t\t\t\t;# define PDC[31:16] as DATA[31:16]\n\t\tmww $pudr_addr 0xffff0000\t\t\t\t;# no pull-up for D[31:16]\n\t}\n\n\tmww $config(matrix_ebicsa_addr) $config(matrix_ebicsa_val)\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRAMC_MR Mode register\n\tmww $::AT91_SDRAMC_TR\t$config(sdram_tr_val)\t\t;# SDRAMC_TR - Refresh Timer register\n\tmww $::AT91_SDRAMC_CR\t$config(sdram_cr_val)\t\t;# SDRAMC_CR - Configuration register\n\tmww $::AT91_SDRAMC_MDR\t$::AT91_SDRAMC_MD_SDRAM\t\t;# Memory Device Register -> SDRAM\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_PRECHARGE\t;# SDRAMC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_REFRESH\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_LMR\t\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_MR\t$::AT91_SDRAMC_MODE_NORMAL\t;# SDRC_MR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\tmww $::AT91_SDRAMC_TR\t1200\t\t\t\t;# SDRAM_TR\n\tmww $config(sdram_base)\t0\t\t\t\t;# SDRAM_BASE\n\n\tmww $::AT91_MATRIX 0xf\t\t;# MATRIX_MCFG - REMAP all masters\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9_sdramc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# SDRAM Controller (SDRAMC) registers\nset AT91_SDRAMC_MR\t\t[expr {$AT91_SDRAMC + 0x00}]\t;# SDRAM Controller Mode Register\nset\t\tAT91_SDRAMC_MODE\t[expr {0xf << 0}]\t;# Command Mode\nset\t\t\tAT91_SDRAMC_MODE_NORMAL\t\t0\nset\t\t\tAT91_SDRAMC_MODE_NOP\t\t1\nset\t\t\tAT91_SDRAMC_MODE_PRECHARGE\t2\nset\t\t\tAT91_SDRAMC_MODE_LMR\t\t3\nset\t\t\tAT91_SDRAMC_MODE_REFRESH\t4\nset\t\t\tAT91_SDRAMC_MODE_EXT_LMR\t5\nset\t\t\tAT91_SDRAMC_MODE_DEEP\t\t6\n\nset AT91_SDRAMC_TR\t\t[expr {$AT91_SDRAMC + 0x04}]\t;# SDRAM Controller Refresh Timer Register\nset\t\tAT91_SDRAMC_COUNT\t[expr {0xfff << 0}]\t\t;# Refresh Timer Counter\n\nset AT91_SDRAMC_CR\t\t[expr {$AT91_SDRAMC + 0x08}]\t;# SDRAM Controller Configuration Register\nset\t\tAT91_SDRAMC_NC\t\t[expr {3 << 0}]\t\t;# Number of Column Bits\nset\t\t\tAT91_SDRAMC_NC_8\t[expr {0 << 0}]\nset\t\t\tAT91_SDRAMC_NC_9\t[expr {1 << 0}]\nset\t\t\tAT91_SDRAMC_NC_10\t[expr {2 << 0}]\nset\t\t\tAT91_SDRAMC_NC_11\t[expr {3 << 0}]\nset\t\tAT91_SDRAMC_NR\t\t[expr {3 << 2}]\t\t;# Number of Row Bits\nset\t\t\tAT91_SDRAMC_NR_11\t[expr {0 << 2}]\nset\t\t\tAT91_SDRAMC_NR_12\t[expr {1 << 2}]\nset\t\t\tAT91_SDRAMC_NR_13\t[expr {2 << 2}]\nset\t\tAT91_SDRAMC_NB\t\t[expr {1 << 4}]\t\t;# Number of Banks\nset\t\t\tAT91_SDRAMC_NB_2\t[expr {0 << 4}]\nset\t\t\tAT91_SDRAMC_NB_4\t[expr {1 << 4}]\nset\t\tAT91_SDRAMC_CAS\t\t[expr {3 << 5}]\t\t;# CAS Latency\nset\t\t\tAT91_SDRAMC_CAS_1\t[expr {1 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_2\t[expr {2 << 5}]\nset\t\t\tAT91_SDRAMC_CAS_3\t[expr {3 << 5}]\nset\t\tAT91_SDRAMC_DBW\t\t[expr {1 << 7}]\t\t;# Data Bus Width\nset\t\t\tAT91_SDRAMC_DBW_32\t[expr {0 << 7}]\nset\t\t\tAT91_SDRAMC_DBW_16\t[expr {1 << 7}]\nset\t\tAT91_SDRAMC_TWR\t\t[expr {0xf <<  8}]\t\t;# Write Recovery Delay\nset\t\tAT91_SDRAMC_TRC\t\t[expr {0xf << 12}]\t\t;# Row Cycle Delay\nset\t\tAT91_SDRAMC_TRP\t\t[expr {0xf << 16}]\t\t;# Row Precharge Delay\nset\t\tAT91_SDRAMC_TRCD\t[expr {0xf << 20}]\t\t;# Row to Column Delay\nset\t\tAT91_SDRAMC_TRAS\t[expr {0xf << 24}]\t\t;# Active to Precharge Delay\nset\t\tAT91_SDRAMC_TXSR\t[expr {0xf << 28}]\t\t;# Exit Self Refresh to Active Delay\n\nset AT91_SDRAMC_LPR\t\t[expr {$AT91_SDRAMC + 0x10}]\t;# SDRAM Controller Low Power Register\nset\t\tAT91_SDRAMC_LPCB\t\t[expr {3 << 0}]\t;# Low-power Configurations\nset\t\t\tAT91_SDRAMC_LPCB_DISABLE\t\t0\nset\t\t\tAT91_SDRAMC_LPCB_SELF_REFRESH\t\t1\nset\t\t\tAT91_SDRAMC_LPCB_POWER_DOWN\t\t2\nset\t\t\tAT91_SDRAMC_LPCB_DEEP_POWER_DOWN\t3\nset\t\tAT91_SDRAMC_PASR\t\t[expr {7 << 4}]\t;# Partial Array Self Refresh\nset\t\tAT91_SDRAMC_TCSR\t\t[expr {3 << 8}]\t;# Temperature Compensated Self Refresh\nset\t\tAT91_SDRAMC_DS\t\t\t[expr {3 << 10}]\t;# Drive Strength\nset\t\tAT91_SDRAMC_TIMEOUT\t\t[expr {3 << 12}]\t;# Time to define when Low Power Mode is enabled\nset\t\t\tAT91_SDRAMC_TIMEOUT_0_CLK_CYCLES\t[expr {0 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_64_CLK_CYCLES\t[expr {1 << 12}]\nset\t\t\tAT91_SDRAMC_TIMEOUT_128_CLK_CYCLES\t[expr {2 << 12}]\n\nset AT91_SDRAMC_IER\t\t[expr {$AT91_SDRAMC + 0x14}]\t;# SDRAM Controller Interrupt Enable Register\nset AT91_SDRAMC_IDR\t\t[expr {$AT91_SDRAMC + 0x18}]\t;# SDRAM Controller Interrupt Disable Register\nset AT91_SDRAMC_IMR\t\t[expr {$AT91_SDRAMC + 0x1C}]\t;# SDRAM Controller Interrupt Mask Register\nset AT91_SDRAMC_ISR\t\t[expr {$AT91_SDRAMC + 0x20}]\t;# SDRAM Controller Interrupt Status Register\nset\t\tAT91_SDRAMC_RES\t\t[expr {1 << 0}]\t\t;# Refresh Error Status\n\nset AT91_SDRAMC_MDR\t\t[expr {$AT91_SDRAMC + 0x24}]\t;# SDRAM Memory Device Register\nset\t\tAT91_SDRAMC_MD\t\t[expr {3 << 0}]\t\t;# Memory Device Type\nset\t\t\tAT91_SDRAMC_MD_SDRAM\t\t0\nset\t\t\tAT91_SDRAMC_MD_LOW_POWER_SDRAM\t1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/at91sam9_smc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset\t\tAT91_SMC_READMODE\t[expr {1 <<  0}]\t\t;# Read Mode\nset\t\tAT91_SMC_WRITEMODE\t[expr {1 <<  1}]\t\t;# Write Mode\nset\t\tAT91_SMC_EXNWMODE\t[expr {3 <<  4}]\t\t;# NWAIT Mode\nset\t\t\tAT91_SMC_EXNWMODE_DISABLE\t[expr {0 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_FROZEN\t[expr {2 << 4}]\nset\t\t\tAT91_SMC_EXNWMODE_READY\t\t[expr {3 << 4}]\nset\t\tAT91_SMC_BAT\t\t[expr {1 <<  8}]\t\t;# Byte Access Type\nset\t\t\tAT91_SMC_BAT_SELECT\t\t[expr {0 << 8}]\nset\t\t\tAT91_SMC_BAT_WRITE\t\t[expr {1 << 8}]\nset\t\tAT91_SMC_DBW\t\t[expr {3 << 12}]\t\t;# Data Bus Width */\nset\t\t\tAT91_SMC_DBW_8\t\t\t[expr {0 << 12}]\nset\t\t\tAT91_SMC_DBW_16\t\t\t[expr {1 << 12}]\nset\t\t\tAT91_SMC_DBW_32\t\t\t[expr {2 << 12}]\nset\t\tAT91_SMC_TDFMODE\t[expr {1 << 20}]\t\t;# TDF Optimization - Enabled\nset\t\tAT91_SMC_PMEN\t\t[expr {1 << 24}]\t\t;# Page Mode Enabled\nset\t\tAT91_SMC_PS\t\t[expr {3 << 28}]\t\t;# Page Size\nset\t\t\tAT91_SMC_PS_4\t\t\t[expr {0 << 28}]\nset\t\t\tAT91_SMC_PS_8\t\t\t[expr {1 << 28}]\nset\t\t\tAT91_SMC_PS_16\t\t\t[expr {2 << 28}]\nset\t\t\tAT91_SMC_PS_32\t\t\t[expr {3 << 28}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/hardware.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# External Memory Map\nset AT91_CHIPSELECT_0\t0x10000000\nset AT91_CHIPSELECT_1\t0x20000000\nset AT91_CHIPSELECT_2\t0x30000000\nset AT91_CHIPSELECT_3\t0x40000000\nset AT91_CHIPSELECT_4\t0x50000000\nset AT91_CHIPSELECT_5\t0x60000000\nset AT91_CHIPSELECT_6\t0x70000000\nset AT91_CHIPSELECT_7\t0x80000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/pmc.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif [info exists AT91C_MAINOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 18.432mhz is a common thing...\n    set AT91C_MAINOSC_FREQ 18432000\n}\nglobal AT91C_MAINOSC_FREQ\n\nif [info exists AT91C_SLOWOSC_FREQ] {\n    # user set this... let it be.\n} {\n    # 32khz is the norm\n    set AT91C_SLOWOSC_FREQ 32768\n}\nglobal AT91C_SLOWOSC_FREQ\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/rtt.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset RTTC_RTMR [expr {$AT91C_BASE_RTTC + 0x00}]\nset RTTC_RTAR [expr {$AT91C_BASE_RTTC + 0x04}]\nset RTTC_RTVR [expr {$AT91C_BASE_RTTC + 0x08}]\nset RTTC_RTSR [expr {$AT91C_BASE_RTTC + 0x0c}]\nglobal RTTC_RTMR\nglobal RTTC_RTAR\nglobal RTTC_RTVR\nglobal RTTC_RTSR\n\nproc show_RTTC_RTMR_helper { NAME ADDR VAL } {\n    set rtpres [expr {$VAL & 0x0ffff}]\n    global BIT16 BIT17\n    if { $rtpres == 0 } {\n\tset rtpres 65536;\n    }\n    global AT91C_SLOWOSC_FREQ\n    # Nasty hack, make this a float by tacking a .0 on the end\n    # otherwise, jim makes the value an integer\n    set f [expr \"$AT91C_SLOWOSC_FREQ.0 / $rtpres.0\"]\n    echo [format \"\\tPrescale value: 0x%04x (%5d) => %f Hz\" $rtpres $rtpres $f]\n    if { $VAL & $BIT16 } {\n\techo \"\\tBit16 -> Alarm IRQ Enabled\"\n    } else {\n\techo \"\\tBit16 -> Alarm IRQ Disabled\"\n    }\n    if { $VAL & $BIT17 } {\n\techo \"\\tBit17 -> RTC Inc IRQ Enabled\"\n    } else {\n\techo \"\\tBit17 -> RTC Inc IRQ Disabled\"\n    }\n    # Bit 18 is write only.\n}\n\nproc show_RTTC_RTSR_helper { NAME ADDR VAL } {\n    global BIT0 BIT1\n    if { $VAL & $BIT0 } {\n\techo \"\\tBit0 -> ALARM PENDING\"\n    } else {\n\techo \"\\tBit0 -> alarm not pending\"\n    }\n    if { $VAL & $BIT1 } {\n\techo \"\\tBit0 -> RTINC PENDING\"\n    } else {\n\techo \"\\tBit0 -> rtinc not pending\"\n    }\n}\n\nproc show_RTTC { } {\n\n    show_mmr32_reg RTTC_RTMR\n    show_mmr32_reg RTTC_RTAR\n    show_mmr32_reg RTTC_RTVR\n    show_mmr32_reg RTTC_RTSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/sam9_smc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Setup register\n#\n# ncs_read_setup\n# nrd_setup\n# ncs_write_setup\n# set nwe_setup\n#\n#\n# Pulse register\n#\n# ncs_read_pulse\n# nrd_pulse\n# ncs_write_pulse\n# nwe_pulse\n#\n#\n# Cycle register\n#\n# read_cycle 0\n# write_cycle 0\n#\n#\n# Mode register\n#\n# mode\n# tdf_cycles\nproc sam9_smc_config { cs smc_config } {\n\t;# Setup Register for CS n\n\tset AT91_SMC_SETUP [expr {$::AT91_SMC + 0x00 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_setup) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_setup) << 8}]\n\tset val [expr {$val | $smc_config(nrd_setup)) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_setup) << 24}]\n\tmww $AT91_SMC_SETUP $val\n\n\t;# Pulse Register for CS n\n\tset AT91_SMC_PULSE [expr {$::AT91_SMC + 0x04 + $cs * 0x10}]\n\tset val [expr {$smc_config(nwe_pulse) << 0}]\n\tset val [expr {$val | $smc_config(ncs_write_pulse) << 8}]\n\tset val [expr {$val | $smc_config(nrd_pulse) << 16}]\n\tset val [expr {$val | $smc_config(ncs_read_pulse) << 24}]\n\tmww $AT91_SMC_PULSE $val\n\n\t;# Cycle Register for CS n\n\tset AT91_SMC_CYCLE [expr {$::AT91_SMC + 0x08 + $cs * 0x10}]\n\tset val [expr {$smc_config(write_cycle) << 0}]\n\tset val [expr {$val | $smc_config(read_cycle) << 16}]\n\tmww $AT91_SMC_CYCLE $val\n\n\t;# Mode Register for CS n\n\tset AT91_SMC_MODE [expr {$::AT91_SMC + 0x0c + $cs * 0x10}]\n\tset val [expr {$smc_config(mode) << 0}]\n\tset val [expr {$val | $smc_config(tdf_cycles) << 16}]\n\tmww $AT91_SMC_MODE $val\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/atmel/at91/usarts.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# the DBGU and USARTs are 'almost' indentical'\nset DBGU_CR         [expr {$AT91C_BASE_DBGU + 0x00000000}]\nset DBGU_MR         [expr {$AT91C_BASE_DBGU + 0x00000004}]\nset DBGU_IER        [expr {$AT91C_BASE_DBGU + 0x00000008}]\nset DBGU_IDR        [expr {$AT91C_BASE_DBGU + 0x0000000C}]\nset DBGU_IMR        [expr {$AT91C_BASE_DBGU + 0x00000010}]\nset DBGU_CSR        [expr {$AT91C_BASE_DBGU + 0x00000014}]\nset DBGU_RHR        [expr {$AT91C_BASE_DBGU + 0x00000018}]\nset DBGU_THR        [expr {$AT91C_BASE_DBGU + 0x0000001C}]\nset DBGU_BRGR       [expr {$AT91C_BASE_DBGU + 0x00000020}]\n# no RTOR\n# no TTGR\n# no FIDI\n# no NER\nset DBGU_CIDR       [expr {$AT91C_BASE_DBGU + 0x00000040}]\nset DBGU_EXID       [expr {$AT91C_BASE_DBGU + 0x00000044}]\nset DBGU_FNTR       [expr {$AT91C_BASE_DBGU + 0x00000048}]\n\n\nset USx_CR           0x00000000\nset USx_MR           0x00000004\nset USx_IER          0x00000008\nset USx_IDR          0x0000000C\nset USx_IMR          0x00000010\nset USx_CSR          0x00000014\nset USx_RHR          0x00000018\nset USx_THR          0x0000001C\nset USx_BRGR         0x00000020\nset USx_RTOR         0x00000024\nset USx_TTGR         0x00000028\nset USx_FIDI         0x00000040\nset USx_NER          0x00000044\nset USx_IF           0x0000004C\n\n# Create all the uarts that exist..\n# we blow up if there are >9\n\n\nproc show_mmr_USx_MR_helper { NAME ADDR VAL } {\n    # First - just print it\n\n    set x [show_normalize_bitfield $VAL 3 0]\n    if { $x == 0 } {\n\techo \"\\tNormal operation\"\n    } else {\n\techo [format \"\\tNon Normal operation mode: 0x%02x\" $x]\n    }\n\n    set x [show_normalize_bitfield $VAL 11 9]\n    set s \"unknown\"\n    switch -exact $x {\n\t0 { set s \"Even\" }\n\t1 { set s \"Odd\" }\n\t2 { set s \"Force=0\" }\n\t3 { set s \"Force=1\" }\n\t* {\n\t    set $x [expr {$x & 6}]\n\t    switch -exact $x {\n\t\t4 { set s \"None\" }\n\t\t6 { set s \"Multidrop Mode\" }\n\t    }\n\t}\n    }\n    echo [format \"\\tParity: %s \" $s]\n\n    set x [expr {5 + [show_normalize_bitfield $VAL 7 6]}]\n    echo [format \"\\tDatabits: %d\" $x]\n\n    set x [show_normalize_bitfield $VAL 13 12]\n    switch -exact $x {\n\t0 { echo \"\\tStop bits: 1\" }\n\t1 { echo \"\\tStop bits: 1.5\" }\n\t2 { echo \"\\tStop bits: 2\" }\n\t3 { echo \"\\tStop bits: Illegal/Reserved\" }\n    }\n}\n\n# For every possbile usart...\nforeach WHO { US0 US1 US2 US3 US4 US5 US6 US7 US8 US9 } {\n    set n AT91C_BASE_[set WHO]\n    set str \"\"\n\n    # Only if it exists on the chip\n    if [ info exists $n ] {\n\t# Hence: $n - is like AT91C_BASE_USx\n\t# For every sub-register\n\tforeach REG {CR MR IER IDR IMR CSR RHR THR BRGR RTOR TTGR FIDI NER IF}\t{\n\t    # vn = variable name\n\t    set vn [set WHO]_[set REG]\n\t    # vn = USx_IER\n\t    # vv = variable value\n\t    set vv [expr \"$$n + [set USx_[set REG]]\"]\n\t    # And VV is the address in memory of that register\n\n\n\t    # make that VN a GLOBAL so others can find it\n\t    global $vn\n\t    set $vn $vv\n\n\t    # Create a command for this specific register.\n\t    proc show_$vn { } \"show_mmr32_reg $vn\"\n\n\t    # Add this command to the Device(as a whole) command\n\t    set str \"$str\\nshow_$vn\"\n\t}\n\t# Now - create the DEVICE(as a whole) command\n\tset fn show_$WHO\n\tproc $fn { } $str\n    }\n}\n\n# The Debug Uart is special..\nset str \"\"\n\n\n# For every sub-register\nforeach REG {DBGU_CR DBGU_MR DBGU_IER DBGU_IDR DBGU_IMR\n    DBGU_CSR DBGU_RHR DBGU_THR DBGU_BRGR DBGU_CIDR DBGU_EXID DBGU_FNTR} {\n\n    # Create a command for this specific register.\n    proc show_$REG { } \"show_mmr32_reg $REG\"\n\n    # Add this command to the Device(as a whole) command\n    set str \"$str\\nshow_$REG\"\n}\n\n# Now - create the DEVICE(as a whole) command\nproc show_DBGU { } $str\n\nunset str\n\nproc show_DBGU_MR_helper { NAME ADDR VAL } { show_mmr_USx_MR_helper $NAME $ADDR $VAL }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/spear/quirk_no_srst.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Quirks to bypass missing SRST on JTAG connector\n# EVALSPEAr310 Rev. 2.0\n# http://www.st.com/spear\n#\n# Date:      2010-08-17\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n# For boards that have JTAG SRST not connected.\n# We use \"arm9 vector_catch reset\" to catch button reset event.\n\n\n$_TARGETNAME configure -event reset-assert sp_reset_assert\n$_TARGETNAME configure -event reset-deassert-post sp_reset_deassert_post\n\n# keeps the name of the SPEAr target\nglobal sp_target_name\nset sp_target_name $_TARGETNAME\n\n# Keeps the argument of \"reset\" command (run, init, halt).\nglobal sp_reset_mode\nset sp_reset_mode \"\"\n\n# Helper procedure. Returns 0 is target is halted.\nproc sp_is_halted {} {\n\tglobal sp_target_name\n\n\treturn [expr {[string compare [$sp_target_name curstate] \"halted\" ] == 0}]\n}\n\n# wait for reset button to be pressed, causing CPU to get halted\nproc sp_reset_deassert_post {} {\n\tglobal sp_reset_mode\n\n\tset bar(0) |\n\tset bar(1) /\n\tset bar(2) -\n\tset bar(3) \\\\\n\n\tpoll on\n\techo \"====> Press reset button on the board <====\"\n\tfor {set i 0} { [sp_is_halted] == 0 } { set i [expr {$i + 1}]} {\n\t\techo -n \"$bar([expr {$i & 3}])\\r\"\n\t\tsleep 200\n\t}\n\n\t# Remove catch reset event\n\tarm9 vector_catch none\n\n\t# CPU is halted, but we typed \"reset run\" ...\n\tif { [string compare $sp_reset_mode \"run\"] == 0 } {\n\t\tresume\n\t}\n}\n\n# Override reset-assert, since no SRST available\n# Catch reset event\nproc sp_reset_assert {} {\n\tarm9 vector_catch reset\n}\n\n# Override default init_reset{mode} to catch parameter \"mode\"\nproc init_reset {mode} {\n\tglobal sp_reset_mode\n\n\tset sp_reset_mode $mode\n\n\t# We need to detect CPU get halted, so exit from halt\n\tif { [sp_is_halted] } {\n\t\techo \"Resuming CPU to detect reset\"\n\t\tresume\n\t}\n\n\t# Execute default init_reset{mode}\n\tjtag arp_init-reset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/spear/spear3xx.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Generic init scripts for all ST SPEAr3xx family\n# http://www.st.com/spear\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\n# Initialize internal clock\n# Default:\n# - Crystal =  24 MHz\n# - PLL1    = 332 MHz\n# - PLL2    = 332 MHz\n# - CPU_CLK = 332 MHz\n# - DDR_CLK = 332 MHz async\n# - HCLK    = 166 MHz\n# - PCLK    =  83 MHz\nproc sp3xx_clock_default {} {\n\tmww 0xfca00000 0x00000002\t;# set sysclk slow\n\tmww 0xfca00014 0x0ffffff8\t;# set pll timeout to minimum (100us ?!?)\n\n\t# DDRCORE disable to change frequency\n\tset val [expr {([mrw 0xfca8002c] & ~0x20000000) | 0x40000000}]\n\tmww 0xfca8002c $val\n\tmww 0xfca8002c $val ;# Yes, write twice!\n\n\t# programming PLL1\n\tmww 0xfca8000c 0xa600010c\t;# M=166 P=1 N=12\n\tmww 0xfca80008 0x00001c0a\t;# power down\n\tmww 0xfca80008 0x00001c0e\t;# enable\n\tmww 0xfca80008 0x00001c06\t;# strobe\n\tmww 0xfca80008 0x00001c0e\n\twhile { [expr {[mrw 0xfca80008] & 0x01}] == 0x00 } { sleep 1 }\n\n\t# programming PLL2\n\tmww 0xfca80018 0xa600010c\t;# M=166, P=1, N=12\n\tmww 0xfca80014 0x00001c0a\t;# power down\n\tmww 0xfca80014 0x00001c0e\t;# enable\n\tmww 0xfca80014 0x00001c06\t;# strobe\n\tmww 0xfca80014 0x00001c0e\n\twhile { [expr {[mrw 0xfca80014] & 0x01}] == 0x00 } { sleep 1 }\n\n\tmww 0xfca80028 0x00000082\t;# enable plltimeen\n\tmww 0xfca80024 0x00000511\t;# set hclkdiv=\"/2\" & pclkdiv=\"/2\"\n\n\tmww 0xfca00000 0x00000004\t;# setting SYSCTL to NORMAL mode\n\twhile { [expr {[mrw 0xfca00000] & 0x20}] != 0x20 } { sleep 1 }\n\n\t# Select source of DDR clock\n\t#mmw 0xfca80020 0x10000000 0x70000000 ;# PLL1\n\tmmw 0xfca80020 0x30000000 0x70000000 ;# PLL2\n\n\t# DDRCORE enable after change frequency\n\tmmw 0xfca8002c 0x20000000 0x00000000\n}\n\nproc sp3xx_common_init {} {\n\tmww 0xfca8002c 0xfffffff8\t;# enable clock of all peripherals\n\tmww 0xfca80038 0x00000000\t;# remove reset of all peripherals\n\n\tmww 0xfca80034 0x0000ffff\t;# enable all RAS clocks\n\tmww 0xfca80040 0x00000000\t;# remove all RAS resets\n\n\tmww 0xfca800e4 0x78000008\t;# COMP1V8_REG\n\tmww 0xfca800ec 0x78000008\t;# COMP3V3_REG\n\n\tmww 0xfc000000 0x10000f5f\t;# init SMI and set HW mode\n\tmww 0xfc000000 0x00000f5f\n\n\t# Initialize Bus Interconnection Matrix\n\t# All ports Round-Robin and lowest priority\n\tmww 0xfca8007c 0x80000007\n\tmww 0xfca80080 0x80000007\n\tmww 0xfca80084 0x80000007\n\tmww 0xfca80088 0x80000007\n\tmww 0xfca8008c 0x80000007\n\tmww 0xfca80090 0x80000007\n\tmww 0xfca80094 0x80000007\n\tmww 0xfca80098 0x80000007\n\tmww 0xfca8009c 0x80000007\n}\n\n\n# Specific init scripts for ST SPEAr300\nproc sp300_init {} {\n\tmww 0x99000000 0x00003fff\t;# RAS function enable\n}\n\n\n# Specific init scripts for ST SPEAr310\nproc sp310_init {} {\n\tmww 0xb4000008 0x00002ff4\t;# RAS function enable\n\n\tmww 0xfca80050 0x00000001\t;# Enable clk mem port 1\n\n\tmww 0xfca8013c 0x2f7bc210\t;# plgpio_pad_drv\n\tmww 0xfca80140 0x017bdef6\n}\n\nproc sp310_emi_init {} {\n\t# set EMI pad strength\n\tmmw 0xfca80134 0x0e000000 0x00000000\n\tmmw 0xfca80138 0x0e739ce7 0x00000000\n\tmmw 0xfca8013c 0x00039ce7 0x00000000\n\n\t# set safe EMI timing as in BootROM\n\t#mww 0x4f000000 0x0000000f\t;# tAP_0_reg\n\t#mww 0x4f000004 0x00000000\t;# tSDP_0_reg\n\t#mww 0x4f000008 0x000000ff\t;# tDPw_0_reg\n\t#mww 0x4f00000c 0x00000111\t;# tDPr_0_reg\n\t#mww 0x4f000010 0x00000002\t;# tDCS_0_reg\n\n\t# set fast EMI timing as in Linux\n\tmww 0x4f000000 0x00000010\t;# tAP_0_reg\n\tmww 0x4f000004 0x00000005\t;# tSDP_0_reg\n\tmww 0x4f000008 0x0000000a\t;# tDPw_0_reg\n\tmww 0x4f00000c 0x0000000a\t;# tDPr_0_reg\n\tmww 0x4f000010 0x00000005\t;# tDCS_0_re\n\n\t# 32bit wide, 8/16/32bit access\n\tmww 0x4f000014 0x0000000e\t;# control_0_reg\n\tmww 0x4f000094 0x0000003f\t;# ack_reg\n}\n\n\n# Specific init scripts for ST SPEAr320\nproc sp320_init {} {\n\tmww 0xb300000c 0xffffac04\t;# RAS function enable\n\tmww 0xb3000010 0x00000001\t;# RAS mode select\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/spear/spear3xx_ddr.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Init scripts to configure DDR controller of SPEAr3xx\n# http://www.st.com/spear\n# Original values taken from XLoader source code\n#\n# Date:      2010-09-23\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\n\nproc sp3xx_ddr_init {ddr_type {ddr_chips 1}} {\n\tif { $ddr_chips != 1 && $ddr_chips != 2 } {\n\t\terror \"Only 1 or 2 DDR chips permitted. Wrong value \"$ddr_chips\n\t}\n\n\tif { $ddr_type == \"mt47h64m16_3_333_cl5_async\" } {\n\t\tddr_spr3xx_mt47h64m16_3_333_cl5_async $ddr_chips\n\t\tset ddr_size 0x08000000\n\t## add here new DDR chip definition. Prototype:\n\t#} elseif { $ddr_type == \"?????\" } {\n\t#\t????? $ddr_chips\n\t#\tset ddr_size 0x?????\n\t} else {\n\t\terror \"sp3xx_ddr_init: unrecognized DDR type \"$ddr_type\n\t}\n\n\t# MPMC START\n\tmww 0xfc60001c 0x01000100\n\n\tif { $ddr_chips == 2 } {\n\t\techo [format \\\n\t\t\t\"Double chip DDR memory. Total memory size 0x%08x byte\" \\\n\t\t\t[expr {2 * $ddr_size}]]\n\t} else {\n\t\techo [format \\\n\t\t\t\"Single chip DDR memory. Memory size 0x%08x byte\" \\\n\t\t\t$ddr_size]\n\t}\n}\n\n\n# from Xloader file ddr/spr300_mt47h64m16_3_333_cl5_async.S\nproc ddr_spr3xx_mt47h64m16_3_333_cl5_async {ddr_chips} {\n\t# DDR_PAD_REG\n\tmww 0xfca800f0 0x00003aa5\n\n\t# Use \"1:2 sync\" only when DDR clock source is PLL1 and\n\t# HCLK is half of PLL1\n\tmww 0xfc600000 0x00000001\t;# MEMCTL_AHB_SET_00 # This is async\n\tmww 0xfc600004 0x00000000\t;# MEMCTL_AHB_SET_01\n#\tmww 0xfc600000 0x02020201\t;# MEMCTL_AHB_SET_00 # This is 1:2 sync\n#\tmww 0xfc600004 0x02020202\t;# MEMCTL_AHB_SET_01\n\n\tmww 0xfc600008 0x01000000\t;# MEMCTL_RFSH_SET_00\n\tmww 0xfc60000c 0x00000101\t;# MEMCTL_DLL_SET_00\n\tmww 0xfc600010 0x00000101\t;# MEMCTL_GP_00\n\tmww 0xfc600014 0x01000000\t;# MEMCTL_GP_01\n\tmww 0xfc600018 0x00010001\t;# MEMCTL_GP_02\n\tmww 0xfc60001c 0x00000100\t;# MEMCTL_GP_03\n\tmww 0xfc600020 0x00010001\t;# MEMCTL_GP_04\n\tif { $ddr_chips == 2 } {\n\t\tmww 0xfc600024 0x01020203\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x01000102\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000202\t;# MEMCTL_AHB_SET_02\n\t} else {\n\t\tmww 0xfc600024 0x00000201\t;# MEMCTL_GP_05\n\t\tmww 0xfc600028 0x02000001\t;# MEMCTL_GP_06\n\t\tmww 0xfc60002c 0x02000201\t;# MEMCTL_AHB_SET_02\n\t}\n\tmww 0xfc600030 0x04040105\t;# MEMCTL_AHB_SET_03\n\tmww 0xfc600034 0x03030302\t;# MEMCTL_AHB_SET_04\n\tmww 0xfc600038 0x02040101\t;# MEMCTL_AHB_SET_05\n\tmww 0xfc60003c 0x00000002\t;# MEMCTL_AHB_SET_06\n\tmww 0xfc600044 0x03000405\t;# MEMCTL_DQS_SET_0\n\tmww 0xfc600048 0x03040002\t;# MEMCTL_TIME_SET_01\n\tmww 0xfc60004c 0x04000305\t;# MEMCTL_TIME_SET_02\n\tmww 0xfc600050 0x0505053f\t;# MEMCTL_AHB_RELPR_00\n\tmww 0xfc600054 0x05050505\t;# MEMCTL_AHB_RELPR_01\n\tmww 0xfc600058 0x04040405\t;# MEMCTL_AHB_RELPR_02\n\tmww 0xfc60005c 0x04040404\t;# MEMCTL_AHB_RELPR_03\n\tmww 0xfc600060 0x03030304\t;# MEMCTL_AHB_RELPR_04\n\tmww 0xfc600064 0x03030303\t;# MEMCTL_AHB_RELPR_05\n\tmww 0xfc600068 0x02020203\t;# MEMCTL_AHB_RELPR_06\n\tmww 0xfc60006c 0x02020202\t;# MEMCTL_AHB_RELPR_07\n\tmww 0xfc600070 0x01010102\t;# MEMCTL_AHB_RELPR_08\n\tmww 0xfc600074 0x01010101\t;# MEMCTL_AHB_RELPR_09\n\tmww 0xfc600078 0x00000001\t;# MEMCTL_AHB_RELPR_10\n\tmww 0xfc600088 0x0a0c0a00\t;# MEMCTL_DQS_SET_1\n\tmww 0xfc60008c 0x0000023f\t;# MEMCTL_GP_07\n\tmww 0xfc600090 0x00050a00\t;# MEMCTL_GP_08\n\tmww 0xfc600094 0x11000000\t;# MEMCTL_GP_09\n\tmww 0xfc600098 0x00001302\t;# MEMCTL_GP_10\n\tmww 0xfc60009c 0x00001c1c\t;# MEMCTL_DLL_SET_01\n\tmww 0xfc6000a0 0x7c000000\t;# MEMCTL_DQS_OUT_SHIFT\n\tmww 0xfc6000a4 0x005c0000\t;# MEMCTL_WR_DQS_SHIFT\n\tmww 0xfc6000a8 0x2b050e00\t;# MEMCTL_TIME_SET_03\n\tmww 0xfc6000ac 0x00640064\t;# MEMCTL_AHB_PRRLX_00\n\tmww 0xfc6000b0 0x00640064\t;# MEMCTL_AHB_PRRLX_01\n\tmww 0xfc6000b4 0x00000064\t;# MEMCTL_AHB_PRRLX_02\n\tmww 0xfc6000b8 0x00000000\t;# MEMCTL_OUTRANGE_LGTH\n\tmww 0xfc6000bc 0x00200020\t;# MEMCTL_AHB_RW_SET_00\n\tmww 0xfc6000c0 0x00200020\t;# MEMCTL_AHB_RW_SET_01\n\tmww 0xfc6000c4 0x00200020\t;# MEMCTL_AHB_RW_SET_02\n\tmww 0xfc6000c8 0x00200020\t;# MEMCTL_AHB_RW_SET_03\n\tmww 0xfc6000cc 0x00200020\t;# MEMCTL_AHB_RW_SET_04\n\tmww 0xfc6000d8 0x00000a24\t;# MEMCTL_TREF\n\tmww 0xfc6000dc 0x00000000\t;# MEMCTL_EMRS3_DATA\n\tmww 0xfc6000e0 0x5b1c00c8\t;# MEMCTL_TIME_SET_04\n\tmww 0xfc6000e4 0x00c8002e\t;# MEMCTL_TIME_SET_05\n\tmww 0xfc6000e8 0x00000000\t;# MEMCTL_VERSION\n\tmww 0xfc6000ec 0x0001046b\t;# MEMCTL_TINIT\n\tmww 0xfc6000f0 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_01\n\tmww 0xfc6000f4 0x00000000\t;# MEMCTL_OUTRANGE_ADDR_02\n\tmww 0xfc600104 0x001c0000\t;# MEMCTL_DLL_DQS_DELAY_BYPASS_0\n\tmww 0xfc600108 0x0019001c\t;# MEMCTL_DLL_SET_02\n\tmww 0xfc60010c 0x00100000\t;# MEMCTL_DLL_SET_03\n\tmww 0xfc600110 0x001e007a\t;# MEMCTL_DQS_SET_2\n\tmww 0xfc600188 0x00000000\t;# MEMCTL_USER_DEF_REG_0\n\tmww 0xfc60018c 0x00000000\t;# MEMCTL_USER_DEF_REG_1\n\tmww 0xfc600190 0x01010001\t;# MEMCTL_GP_11\n\tmww 0xfc600194 0x01000000\t;# MEMCTL_GP_12\n\tmww 0xfc600198 0x00000001\t;# MEMCTL_GP_13\n\tmww 0xfc60019c 0x00400000\t;# MEMCTL_GP_14\n\tmww 0xfc6001a0 0x00000000\t;# MEMCTL_EMRS2_DATA_X\n\tmww 0xfc6001a4 0x00000000\t;# MEMCTL_LWPWR_CNT\n\tmww 0xfc6001a8 0x00000000\t;# MEMCTL_LWPWR_REG\n\tmww 0xfc6001ac 0x00860000\t;# MEMCTL_GP_15\n\tmww 0xfc6001b0 0x00000002\t;# MEMCTL_TPDEX\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/stm32/stm32.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find bitsbytes.tcl]\nsource [find cpu/arm/cortex_m3.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nsource [find chip/st/stm32/stm32_regs.tcl]\nsource [find chip/st/stm32/stm32_rcc.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/stm32/stm32_rcc.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset RCC_CR            [expr {$RCC_BASE + 0x00}]\nset RCC_CFGR          [expr {$RCC_BASE + 0x04}]\nset RCC_CIR           [expr {$RCC_BASE + 0x08}]\nset RCC_APB2RSTR      [expr {$RCC_BASE + 0x0c}]\nset RCC_APB1RSTR      [expr {$RCC_BASE + 0x10}]\nset RCC_AHBENR        [expr {$RCC_BASE + 0x14}]\nset RCC_APB2ENR       [expr {$RCC_BASE + 0x18}]\nset RCC_APB1ENR       [expr {$RCC_BASE + 0x1c}]\nset RCC_BDCR          [expr {$RCC_BASE + 0x20}]\nset RCC_CSR           [expr {$RCC_BASE + 0x24}]\n\n\nproc show_RCC_CR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CR] } msg ] {\n\terror $msg\n    }\n\n    show_mmr_bitfield  0  0 $val HSI      { OFF ON }\n    show_mmr_bitfield  1  1 $val HSIRDY   { NOTRDY RDY  }\n    show_mmr_bitfield  7  3 $val HSITRIM  { _NUMBER_ }\n    show_mmr_bitfield 15  8 $val HSICAL   { _NUMBER_ }\n    show_mmr_bitfield 16 16 $val HSEON    { OFF ON }\n    show_mmr_bitfield 17 17 $val HSERDY   { NOTRDY RDY  }\n    show_mmr_bitfield 18 18 $val HSEBYP   { NOTBYPASSED BYPASSED }\n    show_mmr_bitfield 19 19 $val CSSON    { OFF ON }\n    show_mmr_bitfield 24 24 $val PLLON    { OFF ON }\n    show_mmr_bitfield 25 25 $val PLLRDY   { NOTRDY RDY }\n}\n\nproc show_RCC_CFGR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CFGR] } msg ] {\n\terror $msg\n    }\n\n\n    show_mmr_bitfield  1  0 $val  SW     { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  3  2 $val  SWS    { HSI HSE PLL ILLEGAL }\n    show_mmr_bitfield  7  4 $val  HPRE   { sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_1 sysclk_div_2 sysclk_div_4 sysclk_div_8 sysclk_div_16 sysclk_div_64 sysclk_div_128 sysclk_div_256 sysclk_div_512 }\n    show_mmr_bitfield 10  8 $val  PPRE1  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 13 11 $val  PPRE2  { hclk_div1 hclk_div1 hclk_div1 hclk_div1 hclk_div2 hclk_div4 hclk_div8 hclk_div16 }\n    show_mmr_bitfield 15 14 $val  ADCPRE { pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div1 pclk2_div2 pclk2_div4 pclk2_div8 pclk2_div16 }\n    show_mmr_bitfield 16 16 $val  PLLSRC { HSI_div_2 HSE }\n    show_mmr_bitfield 17 17 $val  PLLXTPRE { hse_div1 hse_div2 }\n    show_mmr_bitfield 21 18 $val  PLLMUL { x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x16 }\n    show_mmr_bitfield 22 22 $val  USBPRE { div1 div1_5 }\n    show_mmr_bitfield 26 24 $val  MCO    { none none none none SysClk HSI HSE PLL_div2 }\n}\n\n\nproc show_RCC_CIR { } {\n    if [ catch { set val [show_mmr32_reg RCC_CIR] } msg ] {\n\terror $msg\n    }\n\n}\n\nproc show_RCC_APB2RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2RSTR] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB1RSTR { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1RSTR] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) uart5\n    set bits(19) uart4\n    set bits(18) uart3\n    set bits(17) uart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_AHBENR   { } {\n    if [ catch { set val [ show_mmr32_reg RCC_AHBENR  ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) xxx\n    set bits(14) xxx\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) xxx\n    set bits(10) sdio\n    set bits(9) xxx\n    set bits(8) fsmc\n    set bits(7) xxx\n    set bits(6) crce\n    set bits(5) xxx\n    set bits(4) flitf\n    set bits(3) xxx\n    set bits(2) sram\n    set bits(1) dma2\n    set bits(0) dma1\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_APB2ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB2ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) xxx\n    set bits(28) xxx\n    set bits(27) xxx\n    set bits(26) xxx\n    set bits(25) xxx\n    set bits(24) xxx\n    set bits(23) xxx\n    set bits(22) xxx\n    set bits(21) xxx\n    set bits(20) xxx\n    set bits(19) xxx\n    set bits(18) xxx\n    set bits(17) xxx\n    set bits(16) xxx\n    set bits(15) adc3\n    set bits(14) usart1\n    set bits(13) tim8\n    set bits(12) spi1\n    set bits(11) tim1\n    set bits(10) adc2\n    set bits(9) adc1\n    set bits(8) iopg\n    set bits(7) iopf\n    set bits(6) iope\n    set bits(5) iopd\n    set bits(4) iopc\n    set bits(3) iopb\n    set bits(2) iopa\n    set bits(1) xxx\n    set bits(0) afio\n    show_mmr32_bits bits $val\n\n}\n\nproc show_RCC_APB1ENR  { } {\n    if [ catch { set val [ show_mmr32_reg RCC_APB1ENR ] } msg ] {\n\terror $msg\n    }\n    set bits(31) xxx\n    set bits(30) xxx\n    set bits(29) dac\n    set bits(28) pwr\n    set bits(27) bkp\n    set bits(26) xxx\n    set bits(25) can\n    set bits(24) xxx\n    set bits(23) usb\n    set bits(22) i2c2\n    set bits(21) i2c1\n    set bits(20) usart5\n    set bits(19) usart4\n    set bits(18) usart3\n    set bits(17) usart2\n    set bits(16) xxx\n    set bits(15) spi3\n    set bits(14) spi2\n    set bits(13) xxx\n    set bits(12) xxx\n    set bits(11) wwdg\n    set bits(10) xxx\n    set bits(9) xxx\n    set bits(8) xxx\n    set bits(7) xxx\n    set bits(6) xxx\n    set bits(5) tim7\n    set bits(4) tim6\n    set bits(3) tim5\n    set bits(2) tim4\n    set bits(1) tim3\n    set bits(0) tim2\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_BDCR     { } {\n    if [ catch { set val [ show_mmr32_reg RCC_BDCR    ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lseon\n    set bits(1) lserdy\n    set bits(2) lsebyp\n    set bits(8) rtcsel0\n    set bits(9) rtcsel1\n    set bits(15) rtcen\n    set bits(16) bdrst\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC_CSR      { } {\n    if [ catch { set val [ show_mmr32_reg RCC_CSR     ] } msg ] {\n\terror $msg\n    }\n    for { set x 0 } { $x < 32 } { incr x } {\n\tset bits($x) xxx\n    }\n    set bits(0) lsion\n    set bits(1) lsirdy\n    set bits(24) rmvf\n    set bits(26) pin\n    set bits(27) por\n    set bits(28) sft\n    set bits(29) iwdg\n    set bits(30) wwdg\n    set bits(31) lpwr\n    show_mmr32_bits bits $val\n}\n\nproc show_RCC { } {\n\n    show_RCC_CR\n    show_RCC_CFGR\n    show_RCC_CIR\n    show_RCC_APB2RSTR\n    show_RCC_APB1RSTR\n    show_RCC_AHBENR\n    show_RCC_APB2ENR\n    show_RCC_APB1ENR\n    show_RCC_BDCR\n    show_RCC_CSR\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/st/stm32/stm32_regs.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# /* Peripheral and SRAM base address in the alias region */\nset PERIPH_BB_BASE        0x42000000\nset SRAM_BB_BASE          0x22000000\n\n# /*Peripheral and SRAM base address in the bit-band region */\nset SRAM_BASE             0x20000000\nset PERIPH_BASE           0x40000000\n\n# /*FSMC registers base address */\nset FSMC_R_BASE           0xA0000000\n\n# /*Peripheral memory map */\nset APB1PERIPH_BASE       [set PERIPH_BASE]\nset APB2PERIPH_BASE       [expr {$PERIPH_BASE + 0x10000}]\nset AHBPERIPH_BASE        [expr {$PERIPH_BASE + 0x20000}]\n\nset TIM2_BASE             [expr {$APB1PERIPH_BASE + 0x0000}]\nset TIM3_BASE             [expr {$APB1PERIPH_BASE + 0x0400}]\nset TIM4_BASE             [expr {$APB1PERIPH_BASE + 0x0800}]\nset TIM5_BASE             [expr {$APB1PERIPH_BASE + 0x0C00}]\nset TIM6_BASE             [expr {$APB1PERIPH_BASE + 0x1000}]\nset TIM7_BASE             [expr {$APB1PERIPH_BASE + 0x1400}]\nset RTC_BASE              [expr {$APB1PERIPH_BASE + 0x2800}]\nset WWDG_BASE             [expr {$APB1PERIPH_BASE + 0x2C00}]\nset IWDG_BASE             [expr {$APB1PERIPH_BASE + 0x3000}]\nset SPI2_BASE             [expr {$APB1PERIPH_BASE + 0x3800}]\nset SPI3_BASE             [expr {$APB1PERIPH_BASE + 0x3C00}]\nset USART2_BASE           [expr {$APB1PERIPH_BASE + 0x4400}]\nset USART3_BASE           [expr {$APB1PERIPH_BASE + 0x4800}]\nset UART4_BASE            [expr {$APB1PERIPH_BASE + 0x4C00}]\nset UART5_BASE            [expr {$APB1PERIPH_BASE + 0x5000}]\nset I2C1_BASE             [expr {$APB1PERIPH_BASE + 0x5400}]\nset I2C2_BASE             [expr {$APB1PERIPH_BASE + 0x5800}]\nset CAN_BASE              [expr {$APB1PERIPH_BASE + 0x6400}]\nset BKP_BASE              [expr {$APB1PERIPH_BASE + 0x6C00}]\nset PWR_BASE              [expr {$APB1PERIPH_BASE + 0x7000}]\nset DAC_BASE              [expr {$APB1PERIPH_BASE + 0x7400}]\n\nset AFIO_BASE             [expr {$APB2PERIPH_BASE + 0x0000}]\nset EXTI_BASE             [expr {$APB2PERIPH_BASE + 0x0400}]\nset GPIOA_BASE            [expr {$APB2PERIPH_BASE + 0x0800}]\nset GPIOB_BASE            [expr {$APB2PERIPH_BASE + 0x0C00}]\nset GPIOC_BASE            [expr {$APB2PERIPH_BASE + 0x1000}]\nset GPIOD_BASE            [expr {$APB2PERIPH_BASE + 0x1400}]\nset GPIOE_BASE            [expr {$APB2PERIPH_BASE + 0x1800}]\nset GPIOF_BASE            [expr {$APB2PERIPH_BASE + 0x1C00}]\nset GPIOG_BASE            [expr {$APB2PERIPH_BASE + 0x2000}]\nset ADC1_BASE             [expr {$APB2PERIPH_BASE + 0x2400}]\nset ADC2_BASE             [expr {$APB2PERIPH_BASE + 0x2800}]\nset TIM1_BASE             [expr {$APB2PERIPH_BASE + 0x2C00}]\nset SPI1_BASE             [expr {$APB2PERIPH_BASE + 0x3000}]\nset TIM8_BASE             [expr {$APB2PERIPH_BASE + 0x3400}]\nset USART1_BASE           [expr {$APB2PERIPH_BASE + 0x3800}]\nset ADC3_BASE             [expr {$APB2PERIPH_BASE + 0x3C00}]\n\nset SDIO_BASE             [expr {$PERIPH_BASE + 0x18000}]\n\nset DMA1_BASE             [expr {$AHBPERIPH_BASE + 0x0000}]\nset DMA1_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0008}]\nset DMA1_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x001C}]\nset DMA1_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0030}]\nset DMA1_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0044}]\nset DMA1_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0058}]\nset DMA1_Channel6_BASE    [expr {$AHBPERIPH_BASE + 0x006C}]\nset DMA1_Channel7_BASE    [expr {$AHBPERIPH_BASE + 0x0080}]\nset DMA2_BASE             [expr {$AHBPERIPH_BASE + 0x0400}]\nset DMA2_Channel1_BASE    [expr {$AHBPERIPH_BASE + 0x0408}]\nset DMA2_Channel2_BASE    [expr {$AHBPERIPH_BASE + 0x041C}]\nset DMA2_Channel3_BASE    [expr {$AHBPERIPH_BASE + 0x0430}]\nset DMA2_Channel4_BASE    [expr {$AHBPERIPH_BASE + 0x0444}]\nset DMA2_Channel5_BASE    [expr {$AHBPERIPH_BASE + 0x0458}]\nset RCC_BASE              [expr {$AHBPERIPH_BASE + 0x1000}]\nset CRC_BASE              [expr {$AHBPERIPH_BASE + 0x3000}]\n\n# /*Flash registers base address */\nset FLASH_R_BASE          [expr {$AHBPERIPH_BASE + 0x2000}]\n# /*Flash Option Bytes base address */\nset OB_BASE               0x1FFFF800\n\n# /*FSMC Bankx registers base address */\nset FSMC_Bank1_R_BASE     [expr {$FSMC_R_BASE + 0x0000}]\nset FSMC_Bank1E_R_BASE    [expr {$FSMC_R_BASE + 0x0104}]\nset FSMC_Bank2_R_BASE     [expr {$FSMC_R_BASE + 0x0060}]\nset FSMC_Bank3_R_BASE     [expr {$FSMC_R_BASE + 0x0080}]\nset FSMC_Bank4_R_BASE     [expr {$FSMC_R_BASE + 0x00A0}]\n\n# /*Debug MCU registers base address */\nset DBGMCU_BASE           0xE0042000\n\n# /*System Control Space memory map */\nset SCS_BASE              0xE000E000\n\nset SysTick_BASE          [expr {$SCS_BASE + 0x0010}]\nset NVIC_BASE             [expr {$SCS_BASE + 0x0100}]\nset SCB_BASE              [expr {$SCS_BASE + 0x0D00}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/ti/lm3s/lm3s.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find chip/ti/lm3s/lm3s_regs.tcl]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/chip/ti/lm3s/lm3s_regs.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#*****************************************************************************\n#\n# The following are defines for the System Control register addresses.\n#\n#*****************************************************************************\n\nset SYSCTL_DID0             0x400FE000  ;# Device Identification 0\nset SYSCTL_DID1             0x400FE004  ;# Device Identification 1\nset SYSCTL_DC0              0x400FE008  ;# Device Capabilities 0\nset SYSCTL_DC1              0x400FE010  ;# Device Capabilities 1\nset SYSCTL_DC2              0x400FE014  ;# Device Capabilities 2\nset SYSCTL_DC3              0x400FE018  ;# Device Capabilities 3\nset SYSCTL_DC4              0x400FE01C  ;# Device Capabilities 4\nset SYSCTL_DC5              0x400FE020  ;# Device Capabilities 5\nset SYSCTL_DC6              0x400FE024  ;# Device Capabilities 6\nset SYSCTL_DC7              0x400FE028  ;# Device Capabilities 7\nset SYSCTL_DC8              0x400FE02C  ;# Device Capabilities 8 ADC\n                                        ;# Channels\nset SYSCTL_PBORCTL          0x400FE030  ;# Brown-Out Reset Control\nset SYSCTL_LDOPCTL          0x400FE034  ;# LDO Power Control\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\nset SYSCTL_RIS              0x400FE050  ;# Raw Interrupt Status\nset SYSCTL_IMC              0x400FE054  ;# Interrupt Mask Control\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and\n                                        ;# Clear\nset SYSCTL_RESC             0x400FE05C  ;# Reset Cause\nset SYSCTL_RCC              0x400FE060  ;# Run-Mode Clock Configuration\nset SYSCTL_PLLCFG           0x400FE064  ;# XTAL to PLL Translation\nset SYSCTL_GPIOHSCTL        0x400FE06C  ;# GPIO High-Speed Control\nset SYSCTL_GPIOHBCTL        0x400FE06C  ;# GPIO High-Performance Bus\n                                        ;# Control\nset SYSCTL_RCC2             0x400FE070  ;# Run-Mode Clock Configuration 2\nset SYSCTL_MOSCCTL          0x400FE07C  ;# Main Oscillator Control\nset SYSCTL_RCGC0            0x400FE100  ;# Run Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_RCGC1            0x400FE104  ;# Run Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_RCGC2            0x400FE108  ;# Run Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_SCGC0            0x400FE110  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 0\nset SYSCTL_SCGC1            0x400FE114  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 1\nset SYSCTL_SCGC2            0x400FE118  ;# Sleep Mode Clock Gating Control\n                                        ;# Register 2\nset SYSCTL_DCGC0            0x400FE120  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 0\nset SYSCTL_DCGC1            0x400FE124  ;# Deep-Sleep Mode Clock Gating\n                                        ;# Control Register 1\nset SYSCTL_DCGC2            0x400FE128  ;# Deep Sleep Mode Clock Gating\n                                        ;# Control Register 2\nset SYSCTL_DSLPCLKCFG       0x400FE144  ;# Deep Sleep Clock Configuration\nset SYSCTL_CLKVCLR          0x400FE150  ;# Clock Verification Clear\nset SYSCTL_PIOSCCAL         0x400FE150  ;# Precision Internal Oscillator\n                                        ;# Calibration\nset SYSCTL_PIOSCSTAT        0x400FE154  ;# Precision Internal Oscillator\n                                        ;# Statistics\nset SYSCTL_LDOARST          0x400FE160  ;# Allow Unregulated LDO to Reset\n                                        ;# the Part\nset SYSCTL_I2SMCLKCFG       0x400FE170  ;# I2S MCLK Configuration\nset SYSCTL_DC9              0x400FE190  ;# Device Capabilities 9 ADC\n                                        ;# Digital Comparators\nset SYSCTL_NVMSTAT          0x400FE1A0  ;# Non-Volatile Memory Information\n\nset SYSCTL_RCC_USESYSDIV    0x00400000  ;# Enable System Clock Divider\nset SYSCTL_RCC2_BYPASS2     0x00000800  ;# PLL Bypass 2\nset SYSCTL_RCC_MOSCDIS      0x00000001  ;# Main Oscillator Disable\n\nset SYSCTL_SRCR0            0x400FE040  ;# Software Reset Control 0\nset SYSCTL_SRCR1            0x400FE044  ;# Software Reset Control 1\nset SYSCTL_SRCR2            0x400FE048  ;# Software Reset Control 2\n\nset SYSCTL_MISC             0x400FE058  ;# Masked Interrupt Status and Clear\n\nset FLASH_FMA               0x400FD000  ;# Flash Memory Address\nset FLASH_FMD               0x400FD004  ;# Flash Memory Data\nset FLASH_FMC               0x400FD008  ;# Flash Memory Control\nset FLASH_FCRIS             0x400FD00C  ;# Flash Controller Raw Interrupt Status\nset FLASH_FCIM              0x400FD010  ;# Flash Controller Interrupt Mask\nset FLASH_FCMISC            0x400FD014  ;# Flash Controller Masked Interrupt Status and Clear\nset FLASH_FMC2              0x400FD020  ;#  Flash Memory Control 2\nset FLASH_FWBVAL            0x400FD030  ;# Flash Write Buffer Valid\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/altera-5m570z-cpld.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# file altera-5m570z-cpld.cfg replaced by altera-maxv.cfg\necho \"DEPRECATED: use altera-maxv.cfg instead of deprecated altera-5m570z-cpld.cfg\"\n\n#just to be backward compatible:\n#tap will be 5m570z.tap instead of maxv.tap:\nset CHIPNAME 5m570z\nsource [find cpld/altera-maxv.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/altera-epm240.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# file altera-epm240.cfg replaced by altera-maxii.cfg\necho \"DEPRECATED: use altera-maxii.cfg instead of deprecated altera-epm240.cfg\"\n\n#just to be backward compatible:\n#tap will be epm240.tap instead of maxii.tap:\nset CHIPNAME epm240\nsource [find cpld/altera-maxii.cfg]\n\n# 200ns seems like a good speed\n# c.f. Table 5-34: MAX II JTAG Timing Parameters\nadapter speed 5000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/altera-max10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# see MAX 10 FPGA Device Architecture\n# Table 3-1: IDCODE Information for MAX 10 Devices\n# Intel MAX 10M02 0x31810dd\n# Intel MAX 10M04 0x318a0dd\n# Intel MAX 10M08 0x31820dd\n# Intel MAX 10M16 0x31830dd\n# Intel MAX 10M25 0x31840dd\n# Intel MAX 10M40 0x318d0dd\n# Intel MAX 10M50 0x31850dd\n# Intel MAX 10M02 0x31010dd\n# Intel MAX 10M04 0x310a0dd\n# Intel MAX 10M08 0x31020dd\n# Intel MAX 10M16 0x31030dd\n# Intel MAX 10M25 0x31040dd\n# Intel MAX 10M40 0x310d0dd\n# Intel MAX 10M50 0x31050dd\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME max10\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 -expected-id 0x31810dd -expected-id 0x318a0dd \\\n\t-expected-id 0x31820dd -expected-id 0x31830dd -expected-id 0x31840dd \\\n\t-expected-id 0x318d0dd -expected-id 0x31850dd -expected-id 0x31010dd \\\n\t-expected-id 0x310a0dd -expected-id 0x31020dd -expected-id 0x31030dd \\\n\t-expected-id 0x31040dd -expected-id 0x310d0dd -expected-id 0x31050dd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/altera-maxii.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Altera MAXII CPLD\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME maxii\n}\n\n# see MAX II Device Handbook\n# Table 3-3: 32-Bit MAX II Device IDCODE\n# Version     Part Number             Manuf. ID        LSB\n# 0000        0010 0000 1010 0001     000 0110 1110    1\njtag newtap $_CHIPNAME tap -irlen 10 \\\n\t-expected-id 0x020a10dd \\\n\t-expected-id 0x020a20dd \\\n\t-expected-id 0x020a30dd \\\n\t-expected-id 0x020a40dd \\\n\t-expected-id 0x020a50dd \\\n\t-expected-id 0x020a60dd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/altera-maxv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Altera MAXV 5M24OZ/5M570Z CPLD\n# see MAX V Device Handbook\n# Table 6-3: 32-Bit MAX V Device IDCODE\n# 5M40Z 5M80Z 5M160Z 5M240Z: 0x020A50DD\n# 5M570Z:                    0x020A60DD\n# 5M1270Z:                   0x020A30DD\n# 5M1270Z 5M2210Z:           0x020A40DD\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME maxv\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x020A50DD -expected-id 0x020A60DD \\\n  -expected-id 0x020A30DD -expected-id 0x020A40DD\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/jtagspi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _USER1 0x02\n\nif { [info exists JTAGSPI_IR] } {\n\tset _JTAGSPI_IR $JTAGSPI_IR\n} else {\n\tset _JTAGSPI_IR $_USER1\n}\n\nif { [info exists TARGETNAME] } {\n\tset _TARGETNAME $TARGETNAME\n} else {\n\tset _TARGETNAME $_CHIPNAME.proxy\n}\n\nif { [info exists FLASHNAME] } {\n\tset _FLASHNAME $FLASHNAME\n} else {\n\tset _FLASHNAME $_CHIPNAME.spi\n}\n\ntarget create $_TARGETNAME testee -chain-position $_CHIPNAME.tap\nflash bank $_FLASHNAME jtagspi 0 0 0 0 $_TARGETNAME $_JTAGSPI_IR\n\n# initialize jtagspi flash\n# chain_id: identifier of pld (you can get a list with 'pld devices')\n# proxy_bit: file with bitstream connecting JTAG and SPI interface in the PLD.\n# release_from_pwr_down_cmd: optional, command sent to spi flash before probing.\n#                            ex: 0xAB to release from power-dowm.\n#                            Just omit it to not send a command.\n\nproc jtagspi_init {chain_id proxy_bit {release_from_pwr_down_cmd -1}} {\n\t# load proxy bitstream $proxy_bit and probe spi flash\n\tglobal _FLASHNAME\n\tpld load $chain_id $proxy_bit\n\treset halt\n\tif {$release_from_pwr_down_cmd != -1} {\n\t\tjtagspi cmd $_FLASHNAME 0 $release_from_pwr_down_cmd\n\t}\n\tflash probe $_FLASHNAME\n}\n\nproc jtagspi_program {bin addr} {\n\t# write and verify binary file $bin at offset $addr\n\tglobal _FLASHNAME\n\tflash write_image erase $bin $addr\n\tflash verify_bank $_FLASHNAME $bin $addr\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/lattice-lc4032ze.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Lattice ispMACH 4000ZE family, device LC4032ZE\n# just configure a tap\njtag newtap LC4032ZE tap -irlen 8 -expected-id  0x01806043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx spartan3\n# https://docs.xilinx.com/v/u/en-US/ug332\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc3s\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x01414093 \\\n\t-expected-id 0x0141C093 \\\n\t-expected-id 0x01428093 \\\n\t-expected-id 0x01434093 \\\n\t-expected-id 0x01440093 \\\n\t-expected-id 0x01448093 \\\n\t-expected-id 0x01450093 \\\n\t-expected-id 0x01C10093 \\\n\t-expected-id 0x01C1A093 \\\n\t-expected-id 0x01C22093 \\\n\t-expected-id 0x01C2E093 \\\n\t-expected-id 0x01C3A093 \\\n\t-expected-id 0x0140C093 \\\n\t-expected-id 0x02210093 \\\n\t-expected-id 0x02218093 \\\n\t-expected-id 0x02220093 \\\n\t-expected-id 0x02228093 \\\n\t-expected-id 0x02230093 \\\n\t-expected-id 0x02610093 \\\n\t-expected-id 0x02618093 \\\n\t-expected-id 0x02620093 \\\n\t-expected-id 0x02628093 \\\n\t-expected-id 0x02630093 \\\n\t-expected-id 0x03840093 \\\n\t-expected-id 0x0384e093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc4v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx virtex 4\n# https://docs.xilinx.com/v/u/en-US/ug071\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc4v\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 10 -ignore-version \\\n\t-expected-id 0x01658093 \\\n\t-expected-id 0x01E58093 \\\n\t-expected-id 0x0167C093 \\\n\t-expected-id 0x02068093 \\\n\t-expected-id 0x01E64093 \\\n\t-expected-id 0x016A4093 \\\n\t-expected-id 0x02088093 \\\n\t-expected-id 0x016B4093 \\\n\t-expected-id 0x020B0093 \\\n\t-expected-id 0x016D8093 \\\n\t-expected-id 0x01700093 \\\n\t-expected-id 0x01718093 \\\n\t-expected-id 0x01734093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n# cfg_out cfg_in jprogb jstart jshutdown user1-4\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3C4 0x3C5 0x3CB 0x3CC 0x3CD\nvirtex2 set_user_codes $_CHIPNAME.pld 0x3C2 0x3C3 0x3E2 0x3E3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc4vfx_40_60_100_140.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx virtex 4\n# https://docs.xilinx.com/v/u/en-US/ug071\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc4vfx\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 14 -ignore-version \\\n\t-expected-id 0x01E8C093 \\\n\t-expected-id 0x01EB4093 \\\n\t-expected-id 0x01EE4093 \\\n\t-expected-id 0x01F14093 \\\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n# cfg_out cfg_in jprogb jstart jshutdown user1-4\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3FC4 0x3FC5 0x3FCB 0x3FCC 0x3FCD\nvirtex2 set_user_codes $_CHIPNAME.pld 0x3FC2 0x3FC3 0x3FE2 0x3FE3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc5v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx virtex 5\n# https://docs.xilinx.com/v/u/en-US/ug191\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc5v\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 10 -ignore-version \\\n\t-expected-id 0x0286E093 \\\n\t-expected-id 0x02896093 \\\n\t-expected-id 0x028AE093 \\\n\t-expected-id 0x028D6093 \\\n\t-expected-id 0x028EC093 \\\n\t-expected-id 0x0290C093 \\\n\t-expected-id 0x0295C093 \\\n\t-expected-id 0x02A56093 \\\n\t-expected-id 0x02A6E093 \\\n\t-expected-id 0x02A96093 \\\n\t-expected-id 0x02AAE093 \\\n\t-expected-id 0x02AD6093 \\\n\t-expected-id 0x02AEC093 \\\n\t-expected-id 0x02B0C093 \\\n\t-expected-id 0x02B5C093 \\\n\t-expected-id 0x02E72093 \\\n\t-expected-id 0x02E9A093 \\\n\t-expected-id 0x02ECE093 \\\n\t-expected-id 0x02F3E093 \\\n\t-expected-id 0x03276093 \\\n\t-expected-id 0x032C6093 \\\n\t-expected-id 0x04502093 \\\n\t-expected-id 0x0453E093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n# cfg_out cfg_in jprogb jstart jshutdown user1-4\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3C4 0x3C5 0x3CB 0x3CC 0x3CD\nvirtex2 set_user_codes $_CHIPNAME.pld 0x3C2 0x3C3 0x3E2 0x3E3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc5vfx_100_130_200.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx virtex 5\n# https://docs.xilinx.com/v/u/en-US/ug191\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc5vfx\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 14 -ignore-version \\\n\t-expected-id 0x032D8093 \\\n\t-expected-id 0x03300093 \\\n\t-expected-id 0x03334093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n# cfg_out cfg_in jprogb jstart jshutdown user1-4\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3FC4 0x3FC5 0x3FCB 0x3FCC 0x3FCD\nvirtex2 set_user_codes $_CHIPNAME.pld 0x3FC2 0x3FC3 0x3FE2 0x3FE3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc6s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx spartan6\n# http://www.xilinx.com/support/documentation/user_guides/ug380.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc6s\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x04000093 \\\n\t-expected-id 0x04001093 \\\n\t-expected-id 0x04002093 \\\n\t-expected-id 0x04004093 \\\n\t-expected-id 0x04024093 \\\n\t-expected-id 0x04008093 \\\n\t-expected-id 0x04028093 \\\n\t-expected-id 0x0400E093 \\\n\t-expected-id 0x0402E093 \\\n\t-expected-id 0x04011093 \\\n\t-expected-id 0x04031093 \\\n\t-expected-id 0x0401D093 \\\n\t-expected-id 0x0403D093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\nvirtex2 set_user_codes $_CHIPNAME.pld 0x02 0x03 0x1A 0x1B\n\nset XC6S_CFG_IN 0x05\nset XC6S_JSHUTDOWN 0x0d\nset XC6S_JPROGRAM 0x0b\nset XC6S_JSTART 0x0c\nset XC6S_BYPASS 0x3f\n\nproc xc6s_program {tap} {\n\techo \"DEPRECATED! use 'virtex2 program ...' not 'xc6s_program'\"\n\tglobal XC6S_JSHUTDOWN XC6S_JPROGRAM XC6S_JSTART XC6S_BYPASS\n\tirscan $tap $XC6S_JSHUTDOWN\n\tirscan $tap $XC6S_JPROGRAM\n\tirscan $tap $XC6S_JSTART\n\tirscan $tap $XC6S_BYPASS\n}\n\n#xtp038 and xc3sprog approach\nproc xc6s_program_iprog {tap} {\n\techo \"DEPRECATED! use 'virtex2 program ...' not 'xc6s_program_iprog'\"\n\tglobal XC6S_JSHUTDOWN XC6S_JSTART XC6S_BYPASS XC6S_CFG_IN\n\tirscan $tap $XC6S_JSHUTDOWN\n\truntest 16\n\tirscan $tap $XC6S_CFG_IN\n\t# xtp038 IPROG 16bit flipped\n\tdrscan $tap 16 0xffff 16 0x9955 16 0x66aa 16 0x850c 16 0x7000 16 0x0004\n\tirscan $tap $XC6S_JSTART\n\truntest 32\n\tirscan $tap $XC6S_BYPASS\n\truntest 1\n}\n\nset XC6S_ISC_ENABLE 0x10\nset XC6S_ISC_DISABLE 0x16\nset XC6S_ISC_DNA 0x30\n\n# Get the \"Device DNA\" from the Spartan 6.\n# Most Xilinx FPGA devices contain an embedded, unique device identifier called\n# the \"Device DNA\". The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\nproc xc6s_get_dna {tap} {\n\tglobal XC6S_ISC_ENABLE XC6S_ISC_DISABLE XC6S_ISC_DNA\n\tirscan $tap $XC6S_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC6S_ISC_DNA\n\t# Device DNA is 57 bits long, but we can only read 32bits at a time\n\t# with OpenOCD.\n\tset dna [drscan $tap 16 0 16 0 16 0 9 0]\n\truntest 64\n\tirscan $tap $XC6S_ISC_DISABLE\n\truntest 64\n\n\t# Convert the binary data into the order impact uses\n\tscan $dna \"%x %x %x %x\" v1 v2 v3 v4\n\tset bin_dna [string reverse [concat [format \"%09b\" $v4][format \"%016b\" $v3][format \"%016b\" $v2][format \"%016b\" $v1]]]\n\n\t# Return a hex version of binary\n\tscan [format \"0b%s\" $bin_dna] \"%i\" hex_dna\n\treturn $hex_dna\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xc6s_print_dna {tap} {\n\tset hex_dna [xc6s_get_dna $tap]\n\n\tputs [format \"DNA = %57b (0x%x)\\n\" $hex_dna $hex_dna]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc6v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx virtex 6\n# https://www.xilinx.com/support/documentation/user_guides/ug360.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc6v\n}\n\n# the 4 top bits (28:31) are the die stepping. ignore it.\njtag newtap $_CHIPNAME tap -irlen 10 -ignore-version \\\n\t-expected-id 0x042A2093 \\\n\t-expected-id 0x042A4093 \\\n\t-expected-id 0x042A8093 \\\n\t-expected-id 0x042AC093 \\\n\t-expected-id 0x04244093 \\\n\t-expected-id 0x0424A093 \\\n\t-expected-id 0x0424C093 \\\n\t-expected-id 0x04250093 \\\n\t-expected-id 0x04252093 \\\n\t-expected-id 0x04256093 \\\n\t-expected-id 0x0423A093 \\\n\t-expected-id 0x04286093 \\\n\t-expected-id 0x04288093 \\\n\t-expected-id 0x042C4093 \\\n\t-expected-id 0x042CA093 \\\n\t-expected-id 0x042CC093 \\\n\t-expected-id 0x042D0093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap\n# cfg_out cfg_in jprogb jstart jshutdown user1-4\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3C4 0x3C5 0x3CB 0x3CC 0x3CD\nvirtex2 set_user_codes $_CHIPNAME.pld 0x3C2 0x3C3 0x3E2 0x3E3\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx series 7 (spartan, artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7\n}\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x03622093 \\\n\t-expected-id 0x03620093 \\\n\t-expected-id 0x037C4093 \\\n\t-expected-id 0x0362F093 \\\n\t-expected-id 0x037C8093 \\\n\t-expected-id 0x037C7093 \\\n\t-expected-id 0x037C3093 \\\n\t-expected-id 0x0362E093 \\\n\t-expected-id 0x037C2093 \\\n\t-expected-id 0x0362D093 \\\n\t-expected-id 0x0362C093 \\\n\t-expected-id 0x03632093 \\\n\t-expected-id 0x03631093 \\\n\t-expected-id 0x03636093 \\\n\t-expected-id 0x03647093 \\\n\t-expected-id 0x0364C093 \\\n\t-expected-id 0x03651093 \\\n\t-expected-id 0x03747093 \\\n\t-expected-id 0x03656093 \\\n\t-expected-id 0x03752093 \\\n\t-expected-id 0x03751093 \\\n\t-expected-id 0x03671093 \\\n\t-expected-id 0x03667093 \\\n\t-expected-id 0x03682093 \\\n\t-expected-id 0x03687093 \\\n\t-expected-id 0x03692093 \\\n\t-expected-id 0x03691093 \\\n\t-expected-id 0x03696093\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart\nvirtex2 set_user_codes $_CHIPNAME.pld 0x02 0x03 0x22 0x23\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc xc7_program {tap} {\n\techo \"DEPRECATED! use 'virtex2 program ...' not 'xc7_program'\"\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc7v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n# https://bsdl.info/view.htm?sid=08e275a0cd3ac38988ca59b002289d77\n# https://bsdl.info/view.htm?sid=44dae65d3cf9593188ca59b002289d77\n#\n# this config file is for XC7VX1140T and XC7V2000T only.\n# for other virtex-7 devices use xilinx-xc7vh580t.cfg or xilinx-xc7vh870t.cfg or xilinx-xc7.cfg\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7v\n}\n\n#0x036D5093: XC7VX1140T\n#0x036By093: XC7V2000T\n#y = xx11 = 3, 7, B or F\n\njtag newtap $_CHIPNAME tap -irlen 24 -ignore-version \\\n\t-expected-id 0x036B3093 -expected-id 0x036B7093 \\\n\t-expected-id 0x036BB093 -expected-id 0x036BF093 \\\n\t-expected-id 0x036D5093\n\n#CFG_OUT_SLR0 0x124924\n#CFG_IN_SLR0  0x164924\n#CFG_OUT_SLR1 0x904924\n#CFG_IN_SLR1  0x905924\n#CFG_OUT_SLR2 0x924124\n#CFG_IN_SLR2  0x924164\n#CFG_OUT_SLR3 0x924904\n#CFG_IN_SLR3  0x924905\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart\n# cfg_out cfg_in jprogb jstart jshutdown\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3FFFFF 0x3FFFFF 0x2CB2CB 0x30C30C 0x34D34D\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc7vh580t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n# https://bsdl.info/view.htm?sid=65c6b2cfe1467b4988ca59b002289d77\n#\n# this config file is for xc7vh580t only.\n# for other virtex-7 devices use xilinx-xc7vh870t.cfg or xilinx-xc7v.cfg or xilinx-xc7.cfg\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7vh580t\n}\n\njtag newtap $_CHIPNAME tap -irlen 22 -ignore-version -expected-id 0x036D9093\n\n#CFG_OUT_SLR0 0x0492A0\n#CFG_IN_SLR0  0x0592A0\n#CFG_OUT_SLR1 0x2412A0\n#CFG_IN_SLR1  0x2416A0\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart\n# cfg_out cfg_in jprogb jstart jshutdown\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3FFFFF 0x3FFFFF 0x0B2EA0 0x0C32A0 0x0D36A0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xc7vh870t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# xilinx series 7 (artix, kintex, virtex)\n# http://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf\n# https://bsdl.info/view.htm?sid=d9ff0bb764df004588ca59b002289d77\n#\n# this config file is for xc7vh870t only.\n# for other virtex-7 devices use xilinx-xc7vh580t.cfg or xilinx-xc7v.cfg or xilinx-xc7.cfg\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xc7vh870t\n}\n\njtag newtap $_CHIPNAME tap -irlen 38 -ignore-version -expected-id 0x036DB093\n\n#CFG_OUT_SLR0 0x0492A092A0\n#CFG_IN_SLR0  0x0592A092A0\n#CFG_OUT_SLR1 0x2412A092A0\n#CFG_IN_SLR1  0x2416A092A0\n#CFG_OUT_SLR2 0x2492A012A0\n#CFG_IN_SLR2  0x2492A016A0\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart\n# cfg_out cfg_in jprogb jstart jshutdown\nvirtex2 set_instr_codes $_CHIPNAME.pld 0x3FFFFFFFFF 0x3FFFFFFFFF 0x0B2EA02EA0 0x0C32A032A0 0x0D36A036A0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xcf-p.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF08P <v>5057093\n# XCF16P <v>5058093\n# XCF32P <v>5059093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 16 -ignore-version \\\n\t-expected-id 0x05057093 \\\n\t-expected-id 0x05058093 \\\n\t-expected-id 0x05059093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_P xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xcf-s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcf\n}\n\n# IDs acquired from Xilinx's DS123.pdf\n# XCF01S <v>5044093\n# XCF02S <v>5045093\n# XCF04S <v>5046093\n# The 4 top bits (28:31) are the device revision. Ignore it.\njtag newtap $_CHIPNAME flash -irlen 8 -ignore-version \\\n\t-expected-id 0x05044093 \\\n\t-expected-id 0x05045093 \\\n\t-expected-id 0x05046093\n\ntarget create xcf.flash testee -chain-position $_CHIPNAME.flash\nflash bank XCF_S xcf 0 0 0 0 xcf.flash\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xcr3256.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#xilinx coolrunner xcr3256\n#simple device - just configure a tap\njtag newtap xcr tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id  0x0494c093\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpld/xilinx-xcu.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Xilinx Ultrascale (Kintex, Virtex, Zynq)\n# https://www.xilinx.com/support/documentation/user_guides/ug570-ultrascale-configuration.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xcu\n}\n\n# The various chips in the Ultrascale family have different IR length.\n# Set $CHIP before including this file to determine the device.\narray set _XCU_DATA {\n\tXCKU025         {0x03824093  6}\n\tXCKU035         {0x03823093  6}\n\tXCKU040         {0x03822093  6}\n\tXCKU060         {0x03919093  6}\n\tXCKU060_CIV     {0x0381b093  6}\n\tXCKU095         {0x03844093  6}\n\tXCKU095_CIV     {0x03845093  6}\n\tXCKU3P          {0x04A63093  6}\n\tXCKU5P          {0x04A62093  6}\n\tXCKU9P          {0x0484A093  6}\n\tXCKU11P         {0x04A4E093  6}\n\tXCKU11P_CIV     {0x04A51093  6}\n\tXCKU13P         {0x04A52093  6}\n\tXCKU15P         {0x04A56093  6}\n\tXCKU15P_CIV     {0x04A59093  6}\n\tXCVU065         {0x03939093  6}\n\tXCVU065_CIV     {0x0393b093  6}\n\tXCVU080         {0x03843093  6}\n\tXCVU080_CIV     {0x03845093  6}\n\tXCVU095         {0x03842093  6}\n\tXCVU2P          {0x04aea093  6}\n\tXCVU3P          {0x04B39093  6}\n\tXCVU3P_CIV      {0x04b3d093  6}\n\tXCAU10P         {0x04AC4033  6}\n\tXCAU10P_FFVB676 {0x04AC4093  6}\n\tXCAU15P         {0x04AC2033  6}\n\tXCAU15P_FFVB676 {0x04AC2093  6}\n\tXCAU20P         {0x04A65093  6}\n\tXCAU25P         {0x04A64093  6}\n\tXCKU5P_CIV      {0x04A64093  6}\n\tXCKU19P         {0x04ACF093  6}\n\tXCKU19P_CIV     {0x04AD3093  6}\n\tXCKU085         {0x0380F093 12}\n\tXCKU115         {0x0390D093 12}\n\tXCVU125         {0x0392D093 12}\n\tXCVU125_CIV     {0x0392f093 12}\n\tXCVU5P          {0x04B2B093 12}\n\tXCVU5P_CIV      {0x04b2f093 12}\n\tXCVU7P          {0x04B29093 12}\n\tXCVU7P_CIV      {0x04b2d093 12}\n\tXCVU160         {0x03933093 18}\n\tXCVU190         {0x03931093 18}\n\tXCVU440         {0x0396D093 18}\n\tXCVU440_CIV     {0x0396f093 18}\n\tXCVU9P          {0x04B31093 18}\n\tXCVU9P_CIV      {0x04b35093 18}\n\tXCVU11P         {0x04B49093 18}\n\tXCVU11P_CIV     {0x04b4f093 18}\n\tXCU200_FSGD2104 {0x04b37093 18}\n\tXCU250          {0x04b57093 24}\n\tXCVU13P         {0x04B51093 24}\n\tXCVU13P_CIV     {0x04b55093 24}\n\tXCVU15P         {0x04ba3093 24}\n\tXCVU19P         {0x04ba1093 24}\n\tXCVU19P_CIV     {0x04ba5093 24}\n}\n\nif { ![info exists CHIP] } {\n\terror \"set CHIP to one of \"[concat [array names _XCU_DATA]]\n}\n\nif { ![llength [array names _XCU_DATA $CHIP]] } {\n\terror \"unknown CHIP: \"$CHIP\n}\n\nset _EXPID [lindex $_XCU_DATA($CHIP) 0]\nset _IRLEN [lindex $_XCU_DATA($CHIP) 1]\n\n# the 4 top bits (28:31) are the die stepping/revisions. ignore it.\njtag newtap $_CHIPNAME tap -irlen $_IRLEN -ignore-version -expected-id $_EXPID\n\npld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart\n\n# set the correct instruction codes for jtag hub and\n# at least the right code for jprogb, jstart and jshutdown for SSI devices\nif { $_IRLEN == 6 } {\n\tvirtex2 set_user_codes $_CHIPNAME.pld 0x2 0x3 0x22 0x23\n} elseif {$_IRLEN == 12 } {\n\tputs \"loading bitstream through jtag will not work, but reprogram (refresh)\"\n\tvirtex2 set_instr_codes $_CHIPNAME.pld 0x905 0x904 0x2cb 0x30c 0x34d\n\tvirtex2 set_user_codes $_CHIPNAME.pld 0x0a4 0x0e4 0x8a4 0x8e4\n} elseif {$_IRLEN == 18 } {\n\tputs \"loading bitstream through jtag will not work, but reprogram (refresh)\"\n\tvirtex2 set_instr_codes $_CHIPNAME.pld 0x24905 0x24904 0x0b2cb 0x0c30c 0x0d34d\n\tvirtex2 set_user_codes $_CHIPNAME.pld 0x000a4 0x000e4 0x008a4 0x008e4\n} else {\n\tputs \"loading bitstream through jtag will not work, but reprogram (refresh)\"\n\tvirtex2 set_instr_codes $_CHIPNAME.pld 0x924905 0x924904 0x2cb2cb 0x30c30c 0x34d34d\n\tvirtex2 set_user_codes $_CHIPNAME.pld 0x0a4924 0x0e4924 0x8a4924 0x8e4924\n}\n\nset XCU_JSHUTDOWN 0x0d\nset XCU_JPROGRAM 0x0b\nset XCU_JSTART 0x0c\nset XCU_BYPASS 0x3f\n\nproc xcu_program {tap} {\n\techo \"DEPRECATED! use 'virtex2 program ...' not 'xcu_program'\"\n\tglobal XCU_JSHUTDOWN XCU_JPROGRAM XCU_JSTART XCU_BYPASS\n\tirscan $tap $XCU_JSHUTDOWN\n\tirscan $tap $XCU_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XCU_JSTART\n\truntest 2000\n\tirscan $tap $XCU_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arc/common.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n# Things common to all ARCs\n\n# It is assumed that target is already halted.\nproc arc_common_reset { {target \"\"} } {\n        if { $target != \"\" } {\n                targets $target\n        }\n\n        halt\n\n        # 1. Interrupts are disabled (STATUS32.IE)\n        # 2. The status register flags are cleared.\n        # All fields, except the H bit, are set to 0 when the processor is Reset.\n\n        arc jtag set-aux-reg 0xA 0x1\n\n        # 3. The loop count, loop start, and loop end registers are cleared.\n        arc jtag set-core-reg 60 0\n        arc jtag set-aux-reg 0x2 0\n        arc jtag set-aux-reg 0x3 0\n\n        # Program execution begins at the address referenced by the four byte reset\n        # vector located at the interrupt vector base address, which is the first\n        # entry (offset 0x00) in the vector table.\n        set int_vector_base [arc jtag get-aux-reg 0x25]\n        set start_pc [read_memory $int_vector_base 32 1]\n        arc jtag set-aux-reg 0x6 $start_pc\n\n        # It is OK to do uncached writes - register cache will be invalidated by\n        # the reset_assert() function.\n}\n\n# vim:expandtab:\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arc/em.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_em_examine_target { {target \"\"} } {\n\t# Will set current target\n\tarc_v2_examine_target $target\n}\n\nproc arc_em_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_em_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_em_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Set DEBUG.ED bit to enable clock in actionpoint module.\n\t# This is specific to ARC EM.\n\tset debug [arc jtag get-aux-reg 5]\n\tif { !($debug & (1 << 20)) } {\n\t\tarc jtag set-aux-reg 5 [expr {$debug | (1 << 20)}]\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arc/hs.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\nsource [find cpu/arc/v2.tcl]\n\nproc arc_hs_examine_target { target } {\n\t# Will set current target for us.\n\tarc_v2_examine_target $target\n}\n\nproc arc_hs_init_regs { } {\n\tarc_v2_init_regs\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_hs_examine_target [target current]\"\n}\n\n# Scripts in \"target\" folder should call this function instead of direct\n# invocation of arc_common_reset.\nproc arc_hs_reset { {target \"\"} } {\n\tarc_v2_reset $target\n\n\t# Invalidate L2 cache if there is one.\n\tset l2_config [$target arc jtag get-aux-reg 0x901]\n\t# Will return 0, if cache is not present and register doesn't exist.\n\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\tif { ($l2_config != 0) && (($l2_ctrl & 1) == 0) } {\n\t\tputs \"L2 cache is present and not disabled\"\n\n\t\t# Wait until BUSY bit is 0.\n\t\tputs \"Invalidating L2 cache...\"\n\t\t$target arc jtag set-aux-reg 0x905 1\n\t\t# Dummy read of SLC_AUX_CACHE_CTRL bit, as described in:\n\t\t# https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/commit/arch/arc?id=c70c473396cbdec1168a6eff60e13029c0916854\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\twhile { ($l2_ctrl & 0x100) != 0 } {\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t}\n\n\t\t# Flush cache if needed. If SLC_AUX_CACHE_CTRL.IM is 1, then invalidate\n\t\t# operation already flushed everything.\n\t\tif { ($l2_ctrl & 0x40) == 0 } {\n\t\t\tputs \"Flushing L2 cache...\"\n\t\t\t$target arc jtag set-aux-reg 0x904 1\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\twhile { [expr {$l2_ctrl & 0x100}] != 0 } {\n\t\t\t\tset l2_ctrl [$target arc jtag get-aux-reg 0x903]\n\t\t\t}\n\t\t}\n\n\t\tputs \"L2 cache has been flushed and invalidated.\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arc/v2.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2015, 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\nsource [find cpu/arc/common.tcl]\n\n# Currently 'examine_target' can only read JTAG registers and set properties -\n# but it shouldn't write any of registers - writes will be cached, but cache\n# will be invalidated before flushing after examine_target, and changes will be\n# lost.  Perhaps that would be fixed later - perhaps writes shouldn't be cached\n# after all.  But if write to register is really needed from TCL - then it\n# should be done via \"arc jtag\" for now.\nproc arc_v2_examine_target { {target \"\"} } {\n\t# Set current target, because OpenOCD event handlers don't do this for us.\n\tif { $target != \"\" } {\n\t\ttargets $target\n\t}\n\n\t# Those registers always exist. DEBUG and DEBUGI are formally optional,\n\t# however they come with JTAG interface, and so far there is no way\n\t# OpenOCD can communicate with target without JTAG interface.\n\tarc set-reg-exists identity pc status32 bta debug lp_start lp_end \\\n\t\teret erbta erstatus ecr efa\n\n\t# 32 core registers\n\tarc set-reg-exists \\\n\t\tr0  r1  r2  r3  r4  r5  r6  r7  r8  r9  r10 r11 r12 \\\n\t\tr13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 \\\n\t\tgp fp sp ilink r30 blink lp_count pcl\n\n\t# Actionpoints\n\tif { [arc get-reg-field ap_build version] == 5 } {\n\t\tset ap_build_type [arc get-reg-field ap_build type]\n\t\t# AP_BUILD.TYPE > 0b0110 is reserved in current ISA.\n\t\t# Current ISA supports up to 8 actionpoints.\n\t\tif { $ap_build_type < 8 } {\n\t\t\t# Two LSB bits of AP_BUILD.TYPE define amount of actionpoints:\n\t\t\t# 0b00 - 2 actionpoints\n\t\t\t# 0b01 - 4 actionpoints\n\t\t\t# 0b10 - 8 actionpoints\n\t\t\t# 0b11 - reserved.\n\t\t\tset ap_num [expr {0x2 << ($ap_build_type & 3)}]\n\t\t\t# Expression on top may produce 16 action points - which is a\n\t\t\t# reserved value for now.\n\t\t\tif { $ap_num < 16 } {\n\t\t\t\t# Enable actionpoint registers\n\t\t\t\tfor {set i 0} {$i < $ap_num} {incr i} {\n\t\t\t\t\tarc set-reg-exists ap_amv$i ap_amm$i ap_ac$i\n\t\t\t\t}\n\n\t\t\t\t# Set amount of actionpoints\n\t\t\t\tarc num-actionpoints $ap_num\n\t\t\t}\n\t\t}\n\t}\n\n\t# DCCM\n\tset dccm_version [arc get-reg-field dccm_build version]\n\tif { $dccm_version == 3 || $dccm_version == 4 } {\n\t\tarc set-reg-exists aux_dccm\n\t}\n\n\t# ICCM\n\tif { [arc get-reg-field iccm_build version] == 4 } {\n\t\tarc set-reg-exists aux_iccm\n\t}\n\n\t# MPU\n\tif { [arc get-reg-field mpu_build version] >= 2 &&\n\t\t [arc get-reg-field mpu_build version] <= 4 } {\n\t\tarc set-reg-exists mpu_en mpu_ecr\n\t\tset mpu_regions [arc get-reg-field mpu_build regions]\n\t\tfor {set i 0} {$i < $mpu_regions} {incr i} {\n\t\t\tarc set-reg-exists mpu_rdp$i mpu_rdb$i\n\t\t}\n\n\t\t# Secure MPU\n\t\tif { [arc get-reg-field mpu_build version] == 4 } {\n\t\t\tarc set-reg-exists mpu_index mpu_rstart mpu_rend mpu_rper\n\t\t}\n\t}\n}\n\nproc arc_v2_init_regs { } {\n\t# XML features\n\tset core_feature \"org.gnu.gdb.arc.core.v2\"\n\tset aux_min_feature \"org.gnu.gdb.arc.aux-minimal\"\n\tset aux_other_feature \"org.gnu.gdb.arc.aux-other\"\n\n\t# Describe types\n\t# Types are sorted alphabetically according to their name.\n\tarc add-reg-type-struct -name ap_build_t -bitfield version 0 7 \\\n\t\t-bitfield type 8 11\n\tarc add-reg-type-struct -name ap_control_t -bitfield at 0 3 -bitfield tt 4 5 \\\n\t\t-bitfield m 6 6 -bitfield p 7 7 -bitfield aa 8 8 -bitfield q 9 9\n\t# Cycles field added in version 4.\n\tarc add-reg-type-struct -name dccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield size0 8 11 -bitfield size1 12 15 -bitfield cycles 17 19\n\n\tarc add-reg-type-struct -name debug_t \\\n\t\t-bitfield fh 1 1   -bitfield ah 2 2   -bitfield asr 3 10 \\\n\t\t-bitfield is 11 11 -bitfield ep 19 19 -bitfield ed 20 20 \\\n\t\t-bitfield eh 21 21 -bitfield ra 22 22 -bitfield zz 23 23 \\\n\t\t-bitfield sm 24 26 -bitfield ub 28 28 -bitfield bh 29 29 \\\n\t\t-bitfield sh 30 30 -bitfield ld 31 31\n\n\tarc add-reg-type-struct -name ecr_t \\\n\t\t-bitfield parameter 0 7 \\\n\t\t-bitfield cause 8 15 \\\n\t\t-bitfield vector 16 23 \\\n\t\t-bitfield U 30 30 \\\n\t\t-bitfield P 31 31\n\tarc add-reg-type-struct -name iccm_build_t -bitfield version 0 7 \\\n\t\t-bitfield iccm0_size0  8 11 -bitfield iccm1_size0 12 15 \\\n\t\t-bitfield iccm0_size1 16 19 -bitfield iccm1_size1 20 23\n\tarc add-reg-type-struct -name identity_t \\\n\t\t-bitfield arcver 0 7 -bitfield arcnum 8 15 -bitfield chipid 16 31\n\tarc add-reg-type-struct -name isa_config_t -bitfield version 0 7 \\\n\t\t-bitfield pc_size 8 11 -bitfield lpc_size 12 15 -bitfield addr_size 16 19 \\\n\t\t-bitfield b 20 20 -bitfield a 21 21 -bitfield n 22 22 -bitfield l 23 23 \\\n\t\t-bitfield c 24 27 -bitfield d 28 31\n\tarc add-reg-type-struct -name mpu_build_t -bitfield version 0 7 \\\n\t\t-bitfield regions 8 15 \\\n\t\t-bitfield s 16 16 \\\n\t\t-bitfield i 17 17\n\tarc add-reg-type-struct -name mpu_ecr_t \\\n\t\t-bitfield MR 0 7 \\\n\t\t-bitfield VT 8 9 \\\n\t\t-bitfield EC_CODE 16 31\n\tarc add-reg-type-struct -name mpu_en_t \\\n\t\t-bitfield UE  3  3 -bitfield UW   4  4 -bitfield UR 5 5 \\\n\t\t-bitfield KE  6  6 -bitfield KW   7  7 -bitfield KR 8 8 \\\n\t\t-bitfield S  15 15 -bitfield SID 16 23 \\\n\t\t-bitfield EN 30 30\n\tarc add-reg-type-struct -name mpu_index_t \\\n\t\t-bitfield I 0 3 -bitfield M 30 30 -bitfield D 31 31\n\tarc add-reg-type-struct -name mpu_rper_t \\\n\t\t-bitfield V 0 0 \\\n\t\t-bitfield UE 3 3 -bitfield UW 4 4 -bitfield UR 5 5 \\\n\t\t-bitfield KE 6 6 -bitfield KW 7 7 -bitfield KR 8 8 \\\n\t\t-bitfield S 15 15 -bitfield SID 16 23\n\tarc add-reg-type-flags -name status32_t \\\n\t\t-flag   H  0 -flag E0   1 -flag E1   2 -flag E2  3 \\\n\t\t-flag  E3  4 -flag AE   5 -flag DE   6 -flag  U  7 \\\n\t\t-flag   V  8 -flag  C   9 -flag  N  10 -flag  Z 11 \\\n\t\t-flag   L 12 -flag DZ  13 -flag SC  14 -flag ES 15 \\\n\t\t-flag RB0 16 -flag RB1 17 -flag RB2 18 \\\n\t\t-flag  AD 19 -flag US  20 -flag IE  31\n\n\t# Core registers\n\tset core_regs {\n\t\tr0       0  uint32\n\t\tr1       1  uint32\n\t\tr2       2  uint32\n\t\tr3       3  uint32\n\t\tr4       4  uint32\n\t\tr5       5  uint32\n\t\tr6       6  uint32\n\t\tr7       7  uint32\n\t\tr8       8  uint32\n\t\tr9       9  uint32\n\t\tr10      10 uint32\n\t\tr11      11 uint32\n\t\tr12      12 uint32\n\t\tr13      13 uint32\n\t\tr14      14 uint32\n\t\tr15      15 uint32\n\t\tr16      16 uint32\n\t\tr17      17 uint32\n\t\tr18      18 uint32\n\t\tr19      19 uint32\n\t\tr20      20 uint32\n\t\tr21      21 uint32\n\t\tr22      23 uint32\n\t\tr23      24 uint32\n\t\tr24      24 uint32\n\t\tr25      25 uint32\n\t\tgp       26 data_ptr\n\t\tfp       27 data_ptr\n\t\tsp       28 data_ptr\n\t\tilink    29 code_ptr\n\t\tr30      30 uint32\n\t\tblink    31 code_ptr\n\t\tr32      32 uint32\n\t\tr33      33 uint32\n\t\tr34      34 uint32\n\t\tr35      35 uint32\n\t\tr36      36 uint32\n\t\tr37      37 uint32\n\t\tr38      38 uint32\n\t\tr39      39 uint32\n\t\tr40      40 uint32\n\t\tr41      41 uint32\n\t\tr42      42 uint32\n\t\tr43      43 uint32\n\t\tr44      44 uint32\n\t\tr45      45 uint32\n\t\tr46      46 uint32\n\t\tr47      47 uint32\n\t\tr48      48 uint32\n\t\tr49      49 uint32\n\t\tr50      50 uint32\n\t\tr51      51 uint32\n\t\tr52      52 uint32\n\t\tr53      53 uint32\n\t\tr54      54 uint32\n\t\tr55      55 uint32\n\t\tr56      56 uint32\n\t\tr57      57 uint32\n\t\taccl     58 uint32\n\t\tacch     59 uint32\n\t\tlp_count 60 uint32\n\t\tlimm     61 uint32\n\t\treserved 62 uint32\n\t\tpcl      63 code_ptr\n\t}\n\tforeach {reg count type} $core_regs {\n\t\tarc add-reg -name $reg -num $count -core -type $type -g \\\n\t\t\t-feature $core_feature\n\t}\n\n\t# AUX min\n\tset aux_min {\n\t\t0x6 pc       code_ptr\n\t\t0x2 lp_start code_ptr\n\t\t0x3 lp_end   code_ptr\n\t\t0xA status32 status32_t\n\t}\n\tforeach {num name type} $aux_min {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_min_feature -g\n\t}\n\n\t# AUX other\n\tset aux_other {\n\t\t0x004 identity\tidentity_t\n\t\t0x005 debug\t\tdebug_t\n\t\t0x018 aux_dccm\tint\n\t\t0x208 aux_iccm\tint\n\n\t\t0x220 ap_amv0\tuint32\n\t\t0x221 ap_amm0\tuint32\n\t\t0x222 ap_ac0\tap_control_t\n\t\t0x223 ap_amv1\tuint32\n\t\t0x224 ap_amm1\tuint32\n\t\t0x225 ap_ac1\tap_control_t\n\t\t0x226 ap_amv2\tuint32\n\t\t0x227 ap_amm2\tuint32\n\t\t0x228 ap_ac2\tap_control_t\n\t\t0x229 ap_amv3\tuint32\n\t\t0x22A ap_amm3\tuint32\n\t\t0x22B ap_ac3\tap_control_t\n\t\t0x22C ap_amv4\tuint32\n\t\t0x22D ap_amm4\tuint32\n\t\t0x22E ap_ac4\tap_control_t\n\t\t0x22F ap_amv5\tuint32\n\t\t0x230 ap_amm5\tuint32\n\t\t0x231 ap_ac5\tap_control_t\n\t\t0x232 ap_amv6\tuint32\n\t\t0x233 ap_amm6\tuint32\n\t\t0x234 ap_ac6\tap_control_t\n\t\t0x235 ap_amv7\tuint32\n\t\t0x236 ap_amm7\tuint32\n\t\t0x237 ap_ac7\tap_control_t\n\n\t\t0x400 eret\t\tcode_ptr\n\t\t0x401 erbta\t\tcode_ptr\n\t\t0x402 erstatus\tstatus32_t\n\t\t0x403 ecr\t\tecr_t\n\t\t0x404 efa\t\tdata_ptr\n\n\t\t0x409 mpu_en\tmpu_en_t\n\n\t\t0x412 bta\t\tcode_ptr\n\n\t\t0x420 mpu_ecr\tmpu_ecr_t\n\t\t0x422 mpu_rdb0\tint\n\t\t0x423 mpu_rdp0\tint\n\t\t0x424 mpu_rdb1\tint\n\t\t0x425 mpu_rdp1\tint\n\t\t0x426 mpu_rdb2\tint\n\t\t0x427 mpu_rdp2\tint\n\t\t0x428 mpu_rdb3\tint\n\t\t0x429 mpu_rdp3\tint\n\t\t0x42A mpu_rdb4\tint\n\t\t0x42B mpu_rdp4\tint\n\t\t0x42C mpu_rdb5\tint\n\t\t0x42D mpu_rdp5\tint\n\t\t0x42E mpu_rdb6\tint\n\t\t0x42F mpu_rdp6\tint\n\t\t0x430 mpu_rdb7\tint\n\t\t0x431 mpu_rdp7\tint\n\t\t0x432 mpu_rdb8\tint\n\t\t0x433 mpu_rdp8\tint\n\t\t0x434 mpu_rdb9\tint\n\t\t0x435 mpu_rdp9\tint\n\t\t0x436 mpu_rdb10\tint\n\t\t0x437 mpu_rdp10\tint\n\t\t0x438 mpu_rdb11\tint\n\t\t0x439 mpu_rdp11\tint\n\t\t0x43A mpu_rdb12\tint\n\t\t0x43B mpu_rdp12\tint\n\t\t0x43C mpu_rdb13\tint\n\t\t0x43D mpu_rdp13\tint\n\t\t0x43E mpu_rdb14\tint\n\t\t0x43F mpu_rdp14\tint\n\t\t0x440 mpu_rdb15\tint\n\t\t0x441 mpu_rdp15\tint\n\t\t0x448 mpu_index\tmpu_index_t\n\t\t0x449 mpu_rstart uint32\n\t\t0x44A mpu_rend\tuint32\n\t\t0x44B mpu_rper\tmpu_rper_t\n\t\t0x44C mpu_probe uint32\n\t}\n\tforeach {num name type} $aux_other {\n\t\tarc add-reg -name $name -num $num -type $type -feature $aux_other_feature\n\t}\n\n\t# AUX BCR\n\tset bcr {\n\t\t0x6D mpu_build\n\t\t0x74 dccm_build\n\t\t0x76 ap_build\n\t\t0x78 iccm_build\n\t\t0xC1 isa_config\n\t}\n\tforeach {num reg} $bcr {\n\t\tarc add-reg -name $reg -num $num -type ${reg}_t -bcr -feature $aux_other_feature\n\t}\n\n\t[target current] configure \\\n\t\t-event examine-end \"arc_v2_examine_target [target current]\"\n}\n\nproc arc_v2_reset { {target \"\"} } {\n\tarc_common_reset $target\n\n\t# Disable all actionpoints.  Cannot write via regcache yet, because it will\n\t# not be flushed and all changes to registers will get lost.  Therefore has\n\t# to write directly via JTAG layer...\n\tset num_ap [arc num-actionpoints]\n\tfor {set i 0} {$i < $num_ap} {incr i} {\n\t\tarc jtag set-aux-reg [expr {0x222 + $i * 3}] 0\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arm/arm7tdmi.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset CPU_TYPE   arm\nset CPU_NAME   arm7tdmi\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arm/arm920.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset CPU_TYPE   arm\nset CPU_NAME   arm920\nset CPU_ARCH   armv4t\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arm/arm946.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset CPU_TYPE   arm\nset CPU_NAME   arm946\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arm/arm966.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset CPU_TYPE   arm\nset CPU_NAME   arm966\nset CPU_ARCH   armv5te\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/cpu/arm/cortex_m3.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset CPU_TYPE   arm\nset CPU_NAME   cortex_m3\nset CPU_ARCH   armv7\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nset CPU_NBITS  32\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-10m50.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# file altera-10m50.cfg replaced by altera-max10.cfg\necho \"DEPRECATED: use altera-max10.cfg instead of deprecated altera-10m50.cfg\"\n\n#just to be backward compatible:\n#tap will be 10m50.tap instead of max10.tap:\nset CHIPNAME 10m50\nsource [find cpld/altera-max10.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-arriaii.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Arria II FPGA\n# Arria II Device Handbook\n# Table 11–2. 32-Bit IDCODE for Arria II Devices\n\n#GX:\n#EP2AGX45:  0x025120dd\n#EP2AGX65:  0x025020dd\n#EP2AGX95:  0x025130dd\n#EP2AGX125: 0x025030dd\n#EP2AGX190: 0x025140dd\n#EP2AGX260: 0x025040dd\n#EP2AGZ225: 0x024810dd\n#EP2AGZ300: 0x0240a0dd\n#EP2AGZ350: 0x024820dd\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME arriaii\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x025120dd -expected-id 0x025040dd \\\n  -expected-id 0x025020dd -expected-id 0x024810dd \\\n  -expected-id 0x025130dd -expected-id 0x0240a0dd \\\n  -expected-id 0x025030dd -expected-id 0x024820dd \\\n  -expected-id 0x025140dd\n\npld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family arriaii\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-cyclone10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Cyclone 10 FPGA\n# see: https://www.intel.com/content/www/us/en/docs/programmable/683777/current/bst-operation-control.html\n# and: https://www.intel.cn/content/dam/support/us/en/programmable/kdb/pdfs/literature/hb/cyclone-10/c10gx-51003.pdf\n\n# GX085: 0x02e120dd\n# GX105: 0x02e320dd\n# GX150: 0x02e720dd\n# GX220: 0x02ef20dd\n# 10cl006: 0x020f10dd\n# 10cl010: 0x020f10dd\n# 10cl016: 0x020f20dd\n# 10cl025: 0x020f30dd\n# 10cl040: 0x020f40dd\n# 10cl055: 0x020f50dd\n# 10cl080: 0x020f60dd\n# 10cl120: 0x020f70dd\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cyclone10\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x02e720dd -expected-id 0x02e120dd \\\n  -expected-id 0x02ef20dd -expected-id 0x02e320dd \\\n  -expected-id 0x020f10dd -expected-id 0x020f20dd \\\n  -expected-id 0x020f30dd -expected-id 0x020f40dd \\\n  -expected-id 0x020f50dd -expected-id 0x020f60dd \\\n  -expected-id 0x020f70dd\n\npld device intel $_CHIPNAME.tap cyclone10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-cycloneiii.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Cyclone III FPGA\n# see Cyclone III Device Handbook\n# Table 12-2: Device IDCODE for Cyclone III Device Family\n\n#EP3C5     0x020f10dd\n#EP3C10    0x020f10dd\n#EP3C16    0x020f20dd\n#EP3C25    0x020f30dd\n#EP3C40    0x020f40dd\n#EP3C55    0x020f50dd\n#EP3C80    0x020f60dd\n#EP3C120   0x020f70dd\n#Cyclone III LS\n#EP3CLS70  0x027010dd\n#EP3CLS100 0x027000dd\n#EP3CLS150 0x027030dd\n#EP3CLS200 0x027020dd\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cycloneiii\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x020f10dd -expected-id 0x020f20dd \\\n  -expected-id 0x020f30dd -expected-id 0x020f40dd \\\n  -expected-id 0x020f50dd -expected-id 0x020f60dd \\\n  -expected-id 0x020f70dd -expected-id 0x027010dd \\\n  -expected-id 0x027000dd -expected-id 0x027030dd \\\n  -expected-id 0x027020dd\n\npld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiii\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-cycloneiv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Cyclone IV FPGA\n# see Cyclone IV Device Handbook\n# Table 10-2: IDCODE Information for 32-Bit Cyclone IV Devices\n\n#EP4CE6       0x020f10dd\n#EP4CE10      0x020f10dd\n#EP4CE15      0x020f20dd\n#EP4CE22      0x020f30dd\n#EP4CE30      0x020f40dd\n#EP4CE40      0x020f40dd\n#EP4CE55      0x020f50dd\n#EP4CE75      0x020f60dd\n#EP4CE115     0x020f70dd\n#EP4CGX15     0x028010dd\n#EP4CGX22     0x028120dd\n#EP4CGX30 (3) 0x028020dd\n#EP4CGX30 (4) 0x028230dd\n#EP4CGX50     0x028130dd\n#EP4CGX75     0x028030dd\n#EP4CGX110    0x028140dd\n#EP4CGX150    0x028040dd\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cycloneiv\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x020f10dd -expected-id 0x020f20dd \\\n  -expected-id 0x020f30dd -expected-id 0x020f40dd \\\n  -expected-id 0x020f50dd -expected-id 0x020f60dd \\\n  -expected-id 0x020f70dd -expected-id 0x028010dd \\\n  -expected-id 0x028120dd -expected-id 0x028020dd \\\n  -expected-id 0x028230dd -expected-id 0x028130dd \\\n  -expected-id 0x028030dd -expected-id 0x028140dd \\\n  -expected-id 0x028040dd\n\npld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiv\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-cyclonev.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel Cyclone 5 FPGA\n# see Cyclone V Device Handbook\n# Table 9-1: IDCODE Information for Cyclone V Devices\n\n#5CEA2 0x02b150dd\n#5CEA4 0x02b050dd\n#5CEA5 0x02b220dd\n#5CEA7 0x02b130dd\n#5CEA9 0x02b140dd\n#5CGXC3 0x02b010dd\n#5CGXC4 0x02b120dd\n#5CGXC5 0x02b020dd\n#5CGXC7 0x02b030dd\n#5CGXC9 0x02b040dd\n#5CGTD5 0x02b020dd\n#5CGTD7 0x02b030dd\n#5CGTD9 0x02b040dd\n#5CSEA2 0x02d110dd\n#5CSEA4 0x02d010dd\n#5CSEA5 0x02d120dd\n#5CSEA6 0x02d020dd\n#5CSXC2 0x02d110dd\n#5CSXC4 0x02d010dd\n#5CSXC5 0x02d120dd\n#5CSXC6 0x02d020dd\n#5CSTD5 0x02d120dd\n#5CSTD6 0x02d020dd\n\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cyclonev\n}\n\njtag newtap $_CHIPNAME tap -irlen 10 \\\n  -expected-id 0x02b150dd -expected-id 0x02b050dd \\\n  -expected-id 0x02b220dd -expected-id 0x02b130dd \\\n  -expected-id 0x02b140dd -expected-id 0x02b010dd \\\n  -expected-id 0x02b120dd -expected-id 0x02b020dd \\\n  -expected-id 0x02b030dd -expected-id 0x02b040dd \\\n  -expected-id 0x02d110dd -expected-id 0x02d010dd \\\n  -expected-id 0x02d120dd -expected-id 0x02d020dd\n\npld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cyclonev\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/altera-ep3c10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# file altera-ep3c10.cfg replaced by altera-cycloneiii.cfg\necho \"DEPRECATED: use altera-cycloneiii.cfg instead of deprecated altera-ep3c10.cfg\"\n\n#just to be backward compatible:\n#tap will be ep3c10.tap instead of cycloneiii.tap:\nset CHIPNAME ep3c10\nsource [find fpga/altera-cycloneiii.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/efinix_titanium.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# efinix titanium\n# https://www.efinixinc.com/docs/an048-jtag-bst-titanium-v1.0.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME titanium\n}\n\njtag newtap $_CHIPNAME tap -irlen 5 -ignore-version \\\n\t-expected-id 0x10661A79 \\\n\t-expected-id 0x00360A79 \\\n\t-expected-id 0x10660A79 \\\n\t-expected-id 0x00681A79 \\\n\t-expected-id 0x00688A79 \\\n\t-expected-id 0x00682A79 \\\n\t-expected-id 0x0068CA79 \\\n\t-expected-id 0x00680A79 \\\n\t-expected-id 0x00684A79\n\npld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap -family titanium\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/efinix_trion.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# efinix trion\n# https://www.efinixinc.com/docs/an021-jtag-bst-trion-v1.0.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME trion\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ignore-version \\\n\t-expected-id 0x00210A79 \\\n\t-expected-id 0x00240A79 \\\n\t-expected-id 0x00220A79\n\npld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap -family trion\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/gatemate.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# GateMateTM FPGA\n# https://www.colognechip.com/programmable-logic/gatemate/\n# https://colognechip.com/docs/ds1001-gatemate1-datasheet-latest.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME gatemate\n}\n\njtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \\\n\t-expected-id 0x20000001\n\npld create $_CHIPNAME.pld gatemate -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/gowin_gw1n.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Gowin FPGA IDCODEs\n# from JTAG Programming and Configuration Guide\n# http://cdn.gowinsemi.com.cn/TN653E.pdf\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME gw1n\n}\n\njtag newtap $_CHIPNAME tap -irlen 8 -ignore-version \\\n\t-expected-id 0x0900281B \\\n\t-expected-id 0x0900381B \\\n\t-expected-id 0x0100681B \\\n\t-expected-id 0x0300081B \\\n\t-expected-id 0x0300181B \\\n\t-expected-id 0x0120681B \\\n\t-expected-id 0x0100381B \\\n\t-expected-id 0x1100381B \\\n\t-expected-id 0x0100981B \\\n\t-expected-id 0x1100581B \\\n\t-expected-id 0x1100481B \\\n\t-expected-id 0x0100181B \\\n\t-expected-id 0x1100181B \\\n\t-expected-id 0x0100481B\n\npld create $_CHIPNAME.pld gowin -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_certus.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME certus\n}\n\n# Lattice Certus\n#\n# Certus NX LFD2NX-17     0x310f0043\n# Certus NX LFD2NX-40     0x310f1043\n\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x310F1043 -expected-id 0x310F0043\n\npld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_certuspro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME certuspro\n}\n\n# Lattice CertusPro\n#\n# 0x010f4043 - LFCPNX-100\n# 0x     043 - LFCPNX-50\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x010f4043\n#    -expected-id 0x01112043\n\npld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_ecp2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp2\n}\n\n# Lattice ECP2 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/LatticeECP2M\n#\n# LFE2M20E: 0x01279043\n# LFE2M35E: 0x0127A043\n# LFE2M50E: 0x0127B043\n# LFE2M70E: 0x0127C043\n# LFE2M100E: 0x0127D043\n# LFEC2_6E: 0x01270043\n# LFEC2_12E: 0x01271043\n# LFEC2_20E: 0x01272043\n# LFEC2_35E: 0x01274043\n# LFEC2_50E: 0x01273043\n# LFEC2_70E: 0x01275043\n\njtag newtap $_CHIPNAME tap -irlen 8  \\\n\t-expected-id 0x01279043 -expected-id 0x0127A043 -expected-id 0x0127B043 \\\n\t-expected-id 0x0127C043 -expected-id 0x0127D043 -expected-id 0x01270043 \\\n\t-expected-id 0x01271043 -expected-id 0x01272043 -expected-id 0x01274043 \\\n\t-expected-id 0x01273043 -expected-id 0x01275043\n\npld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_ecp3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp3\n}\n\n# Lattice ECP3 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/LatticeECP3\n#\n# LFE3_17:  0x01010043\n# LFE3_35:  0x01012043\n# LFE3_95:  0x01014043 and LFE3_70\n# LFE3_150: 0x01015043\n\njtag newtap $_CHIPNAME tap -irlen 8  \\\n\t-expected-id 0x01010043 -expected-id 0x01012043 \\\n\t-expected-id 0x01014043 -expected-id 0x01015043\n\npld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_ecp5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ecp5\n}\n\n# Lattice ECP5 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/ECP5\n#\n# 0x01111043 - LAE5UM_25F/LFE5UM_25F\n# 0x01112043 - LAE5UM_45F/LFE5UM_45F\n# 0x01113043 - LAE5UM_85F/LFE5UM_85\n# 0x21111043 - LFE5U_12F\n# 0x41111043 - LFE5U_25F\n# 0x41112043 - LFE5U_45F\n# 0x41113043 - LFE5U_85F\n# 0x81111043 - LFE5UM5G-25\n# 0x81112043 - LFE5UM5G-45\n# 0x81113043 - LFE5UM5G-85\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x01111043 -expected-id 0x01112043 -expected-id 0x01113043 \\\n\t-expected-id 0x21111043 -expected-id 0x41111043 -expected-id 0x41112043 \\\n\t-expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \\\n\t-expected-id 0x81113043\n\npld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/lattice_machxo3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME machxo3\n}\n\n# Lattice MachXO3 family\n# TAP IDs are extracted from BSDL files found on this page:\n# https://www.latticesemi.com/Products/FPGAandCPLD/MachXO3\n#\n# 0x412b2043 - LCMXO3L_1300E_XXUWG36/XXMG121\n# 0x412b3043 - LCMXO3L_2100E_XXMG121/XXMG256/XXUWG49\n# 0x412b4043 - LCMXO3L_4300E_XXMG121/XXMG324/XXUWG81\n# 0x412b5043 - LCMXO3L_6900E_XXMG256/XXMG324\n# 0x412b6043 - LCMXO3L_9400E_XXBG256/XXMG256\n# 0x412bb043 - LCMXO3L_2100C_XXBG256\n# 0x412bc043 - LCMXO3L_4300C_XXBG256/XXBG324\n# 0x412bd043 - LCMXO3L_6900C_XXBG256/XXBG324/XXBG400\n# 0x412be043 - LCMXO3L_9400C_XXBG256/XXBG400/XXBG484\n# 0x612b2043 - LCMXO3LF_1300E_XXMG121/XXUWG36\n# 0x612b3043 - LCMXO3LF_2100E_XXMG121/XXMG256/XXUWG49\n# 0x612b4043 - LCMXO3LF_4300E_XXMG121/XXMG256/XXMG324/XXUWG81\n# 0x612b5043 - LCMXO3LF_6900E_XXMG256/XXMG324\n# 0x612b6043 - LCMXO3LF_9400E_XXBG256/XXMG256\n# 0x612bb043 - LCMXO3LF_2100C_XXBG256\n# 0x612bc043 - LCMXO3LF_4300C_XXBG256/XXBG324\n# 0x612bd043 - LCMXO3LF_6900C_XXBG256/XXBG324/XXBG400\n# 0x612be043 - LCMXO3LF_9400C_XXBG256/XXBG400/XXBG484\n# 0xc12b2043 - LCMXO3L_640E_XXMG121\n# 0xc12b4043 - LCMXO3L_2100E_XXMG324\n# 0xc12bb043 - LCMXO3L_1300C_XXBG256/XXMG256\n# 0xc12bc043 - LCMXO3L_2100C_XXBG324\n# 0xc12bd043 - LCMXO3L_4300C_XXBG400\n# 0xe12b2043 - LCMXO3LF_640E_XXMG121\n# 0xe12b3043 - LCMXO3LF_1300E_XXMG256\n# 0xe12b4043 - LCMXO3LF_2100E_XXMG324\n# 0xe12bb043 - LCMXO3LF_1300C_XXBG256\n# 0xe12bc043 - LCMXO3LF_2100C_XXBG324\n# 0xe12bd043 - LCMXO3LF_4300C_XXBG400\n\njtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \\\n\t-expected-id 0x412b2043 -expected-id 0x412b3043 -expected-id 0x412b4043 \\\n\t-expected-id 0x412b5043 -expected-id 0x412b6043 -expected-id 0x412bb043 \\\n\t-expected-id 0x412bc043 -expected-id 0x412bd043 -expected-id 0x412be043 \\\n\t-expected-id 0x612b2043 -expected-id 0x612b3043 -expected-id 0x612b4043 \\\n\t-expected-id 0x612b5043 -expected-id 0x612b6043 -expected-id 0x612bb043 \\\n\t-expected-id 0x612bc043 -expected-id 0x612bd043 -expected-id 0x612be043 \\\n\t-expected-id 0xc12b2043 -expected-id 0xc12b4043 -expected-id 0xc12bb043 \\\n\t-expected-id 0xc12bc043 -expected-id 0xc12bd043 -expected-id 0xe12b2043 \\\n\t-expected-id 0xe12b3043 -expected-id 0xe12b4043 -expected-id 0xe12bb043 \\\n\t-expected-id 0xe12bc043 -expected-id 0xe12bd043\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/xilinx-dna.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nproc xilinx_dna_addr {chip} {\n\tarray set addrs {\n\t\tSpartan6 0x30\n\t\tSeries7 0x17\n\t}\n\treturn $addrs($chip)\n}\n\n# Get the \"Device DNA\".\n# Most Xilinx FPGA devices contain an embedded, unique device identifier.\n# The identifier is nonvolatile, permanently programmed into\n# the FPGA, and is unchangeable providing a great serial / tracking number.\n# This function returns the DNA as a 64 bit integer with the 7 LSBs zeroed.\n# This is compatible with the FUSE DNA which contains all 64 bits.\nproc xilinx_get_dna {tap chip} {\n\tset XC7_ISC_ENABLE 0x10\n\tset XC7_ISC_DISABLE 0x16\n\tset XC7_ISC_DNA [xilinx_dna_addr $chip]\n\n\tirscan $tap $XC7_ISC_ENABLE\n\truntest 64\n\tirscan $tap $XC7_ISC_DNA\n\tscan [drscan $tap 32 0 32 0] \"%08x %08x\" hi lo\n\truntest 64\n\tirscan $tap $XC7_ISC_DISABLE\n\truntest 64\n\t# openocd interprets DR scans as LSB first, bit-reverse it\n\treturn [scan [string reverse [format \"%032b%032bb0\" $lo $hi]] \"%i\"]\n}\n\n# Print out the \"Device DNA\" in the same format that impact uses.\nproc xilinx_print_dna {dna} {\n\tset dna [expr {$dna >> 64 - 57}]\n\techo [format \"DNA = %057b (0x%016x)\" $dna $dna]\n}\n\nproc xc7_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Series7]\n}\n\nproc xc6s_get_dna {tap} {\n\treturn [xilinx_get_dna $tap Spartan6]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/fpga/xilinx-xadc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Xilinx XADC support for 7 Series FPGAs\n#\n# The 7 Series FPGAs contain an on-chip 12 bit ADC that can probe die\n# temperature, internal power supply rail voltages as well as external\n# voltages. The XADC is available both from fabric as well as through the\n# JTAG TAP.\n#\n# This code implements access through the JTAG TAP.\n#\n# https://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf\n\n# build a 32 bit DRP command for the XADC DR\nproc xadc_cmd {cmd addr data} {\n\tarray set cmds {\n\t\tNOP 0x00\n\t\tREAD 0x01\n\t\tWRITE 0x02\n\t}\n\treturn [expr {($cmds($cmd) << 26) | ($addr << 16) | ($data << 0)}]\n}\n\n# XADC register addresses\n# Some addresses (status registers 0-3) have special function when written to.\nproc XADC {key} {\n\tarray set addrs {\n\t\tTEMP 0x00\n\t\tLOCK 0x00\n\t\tVCCINT 0x01\n\t\tVCCAUX 0x02\n\t\tVAUXEN 0x02\n\t\tVPVN 0x03\n\t\tRESET 0x03\n\t\tVREFP 0x04\n\t\tVREFN 0x05\n\t\tVCCBRAM 0x06\n\t\tSUPAOFFS 0x08\n\t\tADCAOFFS 0x09\n\t\tADCAGAIN 0x0a\n\t\tVCCPINT 0x0d\n\t\tVCCPAUX 0x0e\n\t\tVCCODDR 0x0f\n\t\tVAUX0 0x10\n\t\tVAUX1 0x11\n\t\tVAUX2 0x12\n\t\tVAUX3 0x13\n\t\tVAUX4 0x14\n\t\tVAUX5 0x15\n\t\tVAUX6 0x16\n\t\tVAUX7 0x17\n\t\tVAUX8 0x18\n\t\tVAUX9 0x19\n\t\tVAUX10 0x1a\n\t\tVAUX11 0x1b\n\t\tVAUX12 0x1c\n\t\tVAUX13 0x1d\n\t\tVAUX14 0x1e\n\t\tVAUX15 0x1f\n\t\tSUPBOFFS 0x30\n\t\tADCBOFFS 0x31\n\t\tADCBGAIN 0x32\n\t\tFLAG 0x3f\n\t\tCFG0 0x40\n\t\tCFG1 0x41\n\t\tCFG2 0x42\n\t\tSEQ0 0x48\n\t\tSEQ1 0x49\n\t\tSEQ2 0x4a\n\t\tSEQ3 0x4b\n\t\tSEQ4 0x4c\n\t\tSEQ5 0x4d\n\t\tSEQ6 0x4e\n\t\tSEQ7 0x4f\n\t\tALARM0 0x50\n\t\tALARM1 0x51\n\t\tALARM2 0x52\n\t\tALARM3 0x53\n\t\tALARM4 0x54\n\t\tALARM5 0x55\n\t\tALARM6 0x56\n\t\tALARM7 0x57\n\t\tALARM8 0x58\n\t\tALARM9 0x59\n\t\tALARM10 0x5a\n\t\tALARM11 0x5b\n\t\tALARM12 0x5c\n\t\tALARM13 0x5d\n\t\tALARM14 0x5e\n\t\tALARM15 0x5f\n\t}\n\treturn $addrs($key)\n}\n\n# Select the XADC DR\nproc xadc_select {tap} {\n\tset XADC_IR 0x37\n\tirscan $tap $XADC_IR\n\truntest 10\n}\n\n# XADC transfer\nproc xadc_xfer {tap cmd addr data} {\n\tset ret [drscan $tap 32 [xadc_cmd $cmd $addr $data]]\n\truntest 10\n\treturn [expr \"0x$ret\"]\n}\n\n# XADC register write\nproc xadc_write {tap addr data} {\n\txadc_xfer $tap WRITE $addr $data\n}\n\n# XADC register read, non-pipelined\nproc xadc_read {tap addr} {\n\txadc_xfer $tap READ $addr 0\n\treturn [xadc_xfer $tap NOP 0 0]\n}\n\n# convert 16 bit register code from ADC measurement on\n# external voltages (VAUX) to Volt\nproc xadc_volt {code} {\n\treturn [expr {$code * 1./(1 << 16)}]\n}\n\n# convert 16 bit temperature measurement to Celsius\nproc xadc_temp {code} {\n\treturn [expr {$code * 503.975/(1 << 16) - 273.15}]\n}\n\n# convert 16 bit suppply voltage measurement to Volt\nproc xadc_sup {code} {\n\treturn [expr {$code * 3./(1 << 16)}]\n}\n\n# perform a single channel measurement using default settings\nproc xadc_single {tap ch} {\n\tset cfg0 [xadc_read $tap [XADC CFG0]]\n\tset cfg1 [xadc_read $tap [XADC CFG1]]\n\t# set channel\n\txadc_write $tap [XADC CFG0] $cfg0\n\t# single channel, disable the sequencer\n\txadc_write $tap [XADC CFG1] 0x3000\n\t# leave some time for the conversion\n\truntest 100\n\tset ret [xadc_read $tap [XADC $ch]]\n\t# restore CFG0/1\n\txadc_write $tap [XADC CFG0] $cfg0\n\txadc_write $tap [XADC CFG1] $cfg1\n\treturn $ret\n}\n\n# measure all internal voltages\nproc xadc_report {tap} {\n\txadc_select $tap\n\techo \"TEMP [format %.2f [xadc_temp [xadc_single $tap TEMP]]] C\"\n\tforeach ch [list VCCINT VCCAUX VCCBRAM VPVN VREFP VREFN \\\n\t\tVCCPINT VCCPAUX VCCODDR] {\n\t\techo \"$ch [format %.3f [xadc_sup [xadc_single $tap $ch]]] V\"\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/altera-usb-blaster.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Altera USB-Blaster\n#\n# http://www.altera.com/literature/ug/ug_usb_blstr.pdf\n#\n\nadapter driver usb_blaster\nusb_blaster lowlevel_driver ftdi\n# These are already the defaults.\n# usb_blaster vid_pid 0x09FB 0x6001\n# usb_blaster device_desc \"USB-Blaster\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/altera-usb-blaster2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Altera USB-Blaster II\n#\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x09fb 0x6010 0x09fb 0x6810\nusb_blaster lowlevel_driver ublast2\nusb_blaster firmware /path/to/quartus/blaster_6810.hex\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/arm-jtag-ew.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM-JTAG-EW\n#\n# http://www.olimex.com/dev/arm-jtag-ew.html\n#\n\nadapter driver arm-jtag-ew\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ast2600-gpiod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use AST2600 GPIO through linuxgpiod\n#\n# +-----------+-------------+-------------+\n# | signal    | GPIO name   | gpio offset |\n# +-----------+-------------+-------------+\n# | TCK/SWCLK | GPIOI2      | 66          |\n# | TMS/SWDIO | GPIOI3      | 67          |\n# | TDI       | GPIOI1      | 65          |\n# | TDO       | GPIOI4      | 68          |\n# | nTRST     | GPIOI0      | 64          |\n# +-----------+-------------+-------------+\n\nadapter driver linuxgpiod\n\nadapter gpio trst 64 -chip 0\nadapter gpio tdi 65 -chip 0\nadapter gpio tck 66 -chip 0\nadapter gpio swclk 66 -chip 0\nadapter gpio tms 67 -chip 0\nadapter gpio swdio 67 -chip 0\nadapter gpio tdo 68 -chip 0\n\nreset_config trst_only separate trst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/at91rm9200.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Various Atmel AT91RM9200 boards\n#\n# TODO: URL?\n#\n\nadapter driver at91rm9200\nat91rm9200_device rea_ecr\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/beaglebone-jtag-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for JTAG\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\n# BeagleBone pin P9_41\nadapter gpio tdo 20 -chip 0\n\n# BeagleBone pin P9_12\nadapter gpio tdi 28 -chip 1\n\n# BeagleBone pin P9_18\nadapter gpio tms 4 -chip 0\n\n# BeagleBone pin P9_22\nadapter gpio tck 2 -chip 0\n\n# BeagleBone pin P9_16\nadapter gpio led 19 -chip 1\n\n# BeagleBone pin P8_18\nadapter gpio srst 1 -chip 2\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/beaglebone-swd-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# BeagleBone native GPIO interface for SWD\n#\n# This is best used with a fast buffer but it is also suitable for a direct\n# connection if the target voltage matches the host's IO voltage (typically\n# 3.3V) and the cable is short.\n#\n# DO NOT APPLY VOLTAGE TO THE GPIO PINS UNTIL SYS_RESETN IS HIGH.\n#\n# Do not forget the GND connection.\n\nadapter driver am335xgpio\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on the system clock, calibrated for stock 1 GHz BeagleBoneBlack\n# am335xgpio speed SPEED_COEFF SPEED_OFFSET\nam335xgpio speed_coeffs 600000 575\n\n# BeagleBone pin P9_22\nadapter gpio swclk 2 -chip 0\n\n# BeagleBone pin P9_18\nadapter gpio swdio 4 -chip 0\n\n# BeagleBone pin P9_12\nadapter gpio swdio_dir 28 -chip 1\n\n# USR0 LED\nadapter gpio led 21 -chip 1\n\n# BeagleBone pin P8_18\nadapter gpio srst 1 -chip 2\nreset_config srst_only srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/buspirate.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Buspirate with OpenOCD support\n#\n# http://dangerousprototypes.com/bus-pirate-manual/\n#\n\nadapter driver buspirate\n\n# you need to specify port on which BP lives\n#buspirate port /dev/ttyUSB0\n\n# communication speed setting\nbuspirate speed normal ;# or fast\n\n# voltage regulator Enabled = 1 Disabled = 0\n#buspirate vreg 0\n\n# pin mode normal or open-drain (jtag only)\n#buspirate mode normal\n\n# pullup state Enabled = 1 Disabled = 0\n#buspirate pullup 0\n\n# this depends on the cable, you are safe with this option\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/chameleon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Amontec Chameleon POD\n#\n# http://www.amontec.com/chameleon.shtml\n#\n\nadapter driver parport\nparport cable chameleon\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/cmsis-dap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# ARM CMSIS-DAP compliant adapter\n#\n# http://www.keil.com/support/man/docs/dapdebug/\n#\n\nadapter driver cmsis-dap\n\n# Optionally specify the serial number of CMSIS-DAP usb device.\n# adapter serial 02200201E6661E601B98E3B9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/dln-2-gpiod.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Use DLN-2 GPIO through linuxgpiod\n#\n# +-----------+-------------+-------------+\n# | signal    | DLN-2       | gpio offset |\n# +-----------+-------------+-------------+\n# | nSRST     | J3.1  (PA0) | 0           |\n# | TDO       | J3.2  (PA1) | 1           |\n# | TCK/SWCLK | J3.3  (PA2) | 2           |\n# | TMS/SWDIO | J3.4  (PA3) | 3           |\n# | TDI       | J3.5  (PA4) | 4           |\n# | nTRST     | J3.6  (PA5) | 5           |\n# | LED       | J3.7  (PA6) | 6           |\n# | GND       | J3.12 (GND) |             |\n# +-----------+-------------+-------------+\n\nadapter driver linuxgpiod\n\nadapter gpio srst 0 -chip 0\nadapter gpio tdo 1 -chip 0\nadapter gpio tck 2 -chip 0\nadapter gpio swclk 2 -chip 0\nadapter gpio tms 3 -chip 0\nadapter gpio swdio 3 -chip 0\nadapter gpio tdi 4 -chip 0\nadapter gpio trst 5 -chip 0\nadapter gpio led 6 -chip 0\n\nreset_config trst_and_srst separate srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/dummy.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Dummy interface (for testing purposes)\n#\n\nadapter driver dummy\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/esp_usb_bridge.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# ESP USB Bridge jtag adapter\n#\n\nadapter driver esp_usb_jtag\n\nespusbjtag vid_pid 0x303a 0x1002\nespusbjtag caps_descriptor 0x030A  # string descriptor index:10\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/esp_usb_jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Espressif builtin USB-JTAG adapter\n#\n\nadapter driver esp_usb_jtag\n\nespusbjtag vid_pid 0x303a 0x1001\nespusbjtag caps_descriptor 0x2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/estick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# eStick\n#\n# http://code.google.com/p/estick-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/flashlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# ST FlashLINK JTAG parallel cable\n#\n# http://www.st.com/internet/evalboard/product/94023.jsp\n# http://www.st.com/stonline/products/literature/um/7889.pdf\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable flashlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ft232r/radiona_ulx3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to Radiona ULX3S board:\n# \tboard/radiona_ulx3s.cfg\n# See schematics for the ft232r layout:\n# https://github.com/emard/ulx3s/blob/master/doc/schematics_v316.pdf\n\nadapter driver ft232r\nadapter speed 1000\nft232r vid_pid 0x0403 0x6015\nft232r tck_num DSR\nft232r tms_num DCD\nft232r tdi_num RI\nft232r tdo_num CTS\nft232r trst_num RTS\nft232r srst_num DTR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ft232r.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter driver ft232r\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/100ask-openjtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# www.100ask.org OpenJTAG\n#\n# http://www.100ask.net/OpenJTAG.html\n#\n# Schematics are available from\n# https://blog.matthiasbock.net/wp-content/uploads/2015/04/100ask-JTAGv3.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"USB<=>JTAG&RS232\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0f08 0x0f1b\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/ashling-opella-ld-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi tdo_sample_edge falling\nftdi layout_init 0x0A68 0xFF7B\nftdi channel 0\nftdi layout_signal JTAGOE -ndata 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/ashling-opella-ld-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Ashling Opella-LD\n#\n# https://www.ashling.com/Opella-LD/\n#\n\nadapter driver ftdi\nftdi device_desc \"Opella-LD Debug Probe\"\nftdi vid_pid 0x0B6B 0x0040\nftdi layout_init 0x0860 0x0b7b\nftdi channel 0\nftdi layout_signal JTAGOE -data 0x0010\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0040\nftdi layout_signal SWD_EN -data 0x0100\nftdi layout_signal SWDIO_OE -data 0x0200\nftdi layout_signal LED -ndata 0x0800\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/axm0432.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Axiom axm0432\n#\n# http://www.axman.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Symphony SoundBite\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/c232hm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# FTDI USB Hi-Speed to MPSSE Cable\n#\n# http://www.ftdichip.com/Products/Cables/USBMPSSE.htm\n#\n# C232HM-DDHSL-0 and C232HM-EDSL-0 provide 3.3V and 5V on pin 1 (Red),\n# respectively.\n#\n# Adapter: http://www.ftdichip.com/Support/Documents/DataSheets/Cables/DS_C232HM_MPSSE_CABLE.PDF\n# Chip: http://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT232H.pdf\n# See pinout/colors at end of this file.\n#\n# Tech notes:\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf\n# http://www.ftdichip.com/Support/Documents/AppNotes/AN_129_FTDI_Hi_Speed_USB_To_JTAG_Example.pdf\n\nadapter driver ftdi\n#ftdi device_desc \"C232HM-DDHSL-0\"\n#ftdi device_desc \"C232HM-EDHSL-0\"\n\n# Common PID for FT232H\nftdi vid_pid 0x0403 0x6014\n\n# Layout\n# High data byte 0x40 configures red LED on ACBUS6 initially high (unlit, since active-low)\n# Low data byte 0x08 configures TMS on ACBUS3 initially high (asserted); TCK, TDI low\n# High direction byte 0x40 configures red LED on ACBUS6 as high (output)\n# Low direction byte 0x0b configures TDO on ACBUS2 as low (input)\nftdi layout_init 0x4008 0x400b\n\n# ---A*BUS-------CCCCCCCC|DDDDDDDD\n# --------\\______76543210|76543210\n# LED\t0x4000 = 01000000|00000000 = ACBUS6\n#GPIOL0\t0x0010 = 00000000|00010000 = ADBUS4\n#GPIOL1\t0x0020 = 00000000|00100000 = ADBUS5\n#GPIOL2\t0x0040 = 00000000|01000000 = ADBUS6\n#GPIOL3\t0x0080 = 00000000|10000000 = ADBUS7\n# -ndata treats the LED as active-low for expected behavior (toggle when transferring)\nftdi layout_signal LED -ndata 0x4000\n# Available for aliasing as desired\nftdi layout_signal GPIOL0 -data 0x0010 -oe 0x0010\nftdi layout_signal GPIOL1 -data 0x0020 -oe 0x0020\nftdi layout_signal GPIOL2 -data 0x0040 -oe 0x0040\nftdi layout_signal GPIOL3 -data 0x0080 -oe 0x0080\n\n# C232HM\t\tFT232H\tJTAG/Other\n# Num\tColor\tName\tFunc\n# 1\t\tRed\t\tVCC\t\tOptionally, can power the board if it is not using its own power supply.\n# 2\t\tOrange\tADBUS0\tTCK\n# 3\t\tYellow  ADBUS1\tTDI\n# 4\t\tGreen\tADBUS2\tTDO\n# 5\t\tBrown   ADBUS3\tTMS\n# 6\t\tGrey\tADBUS4\tGPIOL0\n# 7\t\tPurple\tADBUS5\tGPIOL1\n# 8\t\tWhite\tADBUS6\tGPIOL2\n# 9\t\tBlue\tADBUS7\tGPIOL3\n# 10\tBlack\tGND\t\tConnect to ground\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/cortino.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hitex Cortino\n#\n# http://www.hitex.com/index.php?id=cortino\n#\n\nadapter driver ftdi\nftdi device_desc \"Cortino\"\nftdi vid_pid 0x0640 0x0032\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/digilent-hs1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# this supports JTAG-HS1 and JTAG-SMT1\n# (the later being the OEM on-board version)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6010\n# channel 1 does not have any functionality\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0088 0x008b\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/digilent-hs2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# this supports JTAG-HS2 (and apparently Nexys4 as well)\n\nadapter driver ftdi\nftdi device_desc \"Digilent Adept USB Device\"\nftdi vid_pid 0x0403 0x6014\n\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\n\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/digilent_jtag_hs3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Digilent JTAG-HS3\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"Digilent USB Device\"\n\n# From Digilent support:\n# The SRST pin is [...] 0x20 and 0x10 is the /OE (active low output enable)\n\nftdi layout_init 0x2088 0x308b\nftdi layout_signal nSRST -data 0x2000 -noe 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/digilent_jtag_smt2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Digilent JTAG-SMT2\n#\n# http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,395,1053&Prod=JTAG-SMT2\n#\n# Config is based on data from\n# http://electronix.ru/forum/index.php?showtopic=114633&view=findpost&p=1215497 and ZedBoard schematics\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0x20e8 0x3feb\nftdi layout_signal nSRST -data 0x2000\nftdi layout_signal GPIO2 -data 0x2000\nftdi layout_signal GPIO1 -data 0x0200\nftdi layout_signal GPIO0 -data 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/digilent_jtag_smt2_nc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Digilent JTAG-SMT2-NC\n#\n# http://store.digilentinc.com/jtag-smt2-nc-surface-mount-programming-module/\n# https://reference.digilentinc.com/_media/jtag_smt2nc/jtag-smt2-nc_rm.pdf\n#\n# Based on reference sheet (above) and Xilinx KCU105 schematics\n# https://www.xilinx.com/products/boards-and-kits/kcu105.html#documentation\n#\n# Note that the digilent_jtag_smt2 layout does not work and hangs while\n# the ftdi device_desc from digilent_hs2 is wrong.\n\nadapter driver ftdi\nftdi device_desc \"Digilent USB Device\"\nftdi vid_pid 0x0403 0x6014\nftdi channel 0\nftdi layout_init 0x00e8 0x60eb\nreset_config none\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/dlp-usb1232h.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# DLP Design DLP-USB1232H USB-to-UART/FIFO interface module\n#\n# http://www.dlpdesign.com/usb/usb1232h.shtml\n#\n# Schematics for OpenOCD usage:\n# http://randomprojects.org/wiki/DLP-USB1232H_and_OpenOCD_based_JTAG_adapter\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/dp_busblaster.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Dangerous Prototypes - Bus Blaster\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H and the\n# JTAG header which allows it to emulate various debugger types. It comes\n# configured as a JTAGkey device.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\necho \"Info : If you need SWD support, flash KT-Link buffer from https://github.com/bharrisau/busblaster\nand use dp_busblaster_kt-link.cfg instead\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/dp_busblaster_kt-link.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Dangerous Prototypes - Bus Blaster (with KT-Link buffer)\n#\n# The Bus Blaster has a configurable buffer between the FTDI FT2232H\n# and the JTAG header which allows it to emulate various debugger\n# types. This config works with KT-Link compatible implementation from\n# https://github.com/bharrisau/busblaster and is SWD-enabled.\n#\n# http://dangerousprototypes.com/docs/Bus_Blaster\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -ndata 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/esp32_devkitj_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Driver for the FT2232H JTAG chip on the Espressif DevkitJ board\n# (and most other FT2232H and FT232H based boards)\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010 0x0403 0x6014\n\n# interface 1 is the uart\nftdi channel 0\n\n# TCK, TDI, TDO, TMS: ADBUS0-3\n# LEDs: ACBUS4-7\n\nftdi layout_init 0x0008 0xf00b\nftdi layout_signal LED -data 0x1000\nftdi layout_signal LED2 -data 0x2000\nftdi layout_signal LED3 -data 0x4000\nftdi layout_signal LED4 -data 0x8000\n\n# ESP32 series chips do not have a TRST input, and the SRST line is connected to the EN pin.\n# The target code doesn't handle SRST reset properly yet, so this is commented out:\n# ftdi layout_signal nSRST -oe 0x0020\n# reset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/esp32s2_kaluga_v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Driver for the FT2232H JTAG chip on the Espressif Kaluga-1 ESP32-S2 board\n# (and most other FT2232H and FT232H based boards)\n#\n# JTAG DIP switch (labelled SW5 in the schematic) should be \"ON\" for lines\n# labelled TCK, TDO, TDI and TWS, to connect the FT2232H to the ESP32-S2.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010 0x0403 0x6014\n\n# interface 1 is the uart\nftdi channel 0\n\n# TCK, TDI, TDO, TMS: ADBUS0-3\n# TRST/SRST: ADBUS5 (unused for now)\n# LEDs: ACBUS3-4 (inverted)\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal LED -ndata 0x0800\nftdi layout_signal LED2 -ndata 0x1000\n\n# ESP32* series chips do not have a TRST input, and the SRST line is connected\n# to the EN pin.\n# The target code doesn't handle SRST reset properly yet, so this is\n# commented out:\n# ftdi layout_signal nSRST -oe 0x0020\n# reset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/flossjtag-noeeprom.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the pre v0.3 Floss-JTAG compatible config file. It can also be used\n# for newer versions of Floss-JTAG with empty or not populated EEPROM. If you\n# have several Floss-JTAG connected you have to use the USB ID to select a\n# specific one.\n#\n# If you have a Floss-JTAG WITH EEPROM that is programmed, use the\n# flossjtag.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/flossjtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# FlossJTAG\n#\n# http://github.com/esden/floss-jtag\n#\n# This is the v0.3 and v1.0 Floss-JTAG compatible config file. It relies on the\n# existence of an EEPROM on Floss-JTAG containing a name. If you have several\n# Floss-JTAG adapters connected you can use the serial number to select a\n# specific device.\n#\n# If your Floss-JTAG does not have an EEPROM, or the EEPROM is empty, use the\n# flossjtag-noeeprom.cfg file.\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi device_desc \"FLOSS-JTAG\"\n# adapter serial \"FJ000001\"\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x0800\nftdi layout_signal LED2 -data 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/flyswatter.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TinCanTools Flyswatter\n#\n# http://web.archive.org/web/20150419072034/http://www.tincantools.com/JTAG/Flyswatter.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0818 0x0cfb\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/flyswatter2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TinCanTools Flyswatter2\n#\n# https://www.tincantools.com/product/flyswatter2/\n#\n\nadapter driver ftdi\nftdi device_desc \"Flyswatter2\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0538 0x057b\nftdi layout_signal LED -ndata 0x0400\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020 -noe 0x0100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/ft232h-module-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# ADAFRUIT FTDI FT232H as a SWD direct connect interface\n# Any FT232H based board may work\n#\n# http://www.ftdichip.com/Products/ICs/FT232H.htm\n#\n#\n\nadapter driver ftdi\n\nftdi vid_pid 0x0403 0x6014\n\n# data MSB..LSB       direction (1:out) MSB..LSB\n# 0000'0000'0011'0000 0000'0000'0011'1011\nftdi layout_init 0x0030 0x003b\n# 0xfff8 0xfffb\n# Those signal are only required on some platforms or may required to be\n# enabled explicitly (e.g. nrf5x chips).\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\n\n# swd enable\nftdi layout_signal SWD_EN -data 0\n# tri-state (configure as input) TDO/TIO when reading\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n\n# re-configure TDO as tri-state\n#ftdi layout_signal TDO -data 0x0002 -oe 0x0002\n#ftdi layout_signal TDI -data 0x0004\n\n# Adafruit      FT232H    JTAG       SWD\n# Name  Pin     Name      Func       Func\n#  D0   J1-3    ADBUS0    TCK        SWDCLK\n#  D1   J1-4    ADBUS1    TDO/DI     SWDIO\n#  D2   J1-5    ADBUS2    TDI/DO     SWDIO\n#  D3   J1-6    ADBUS3    TMS        N/A\n#  D4   J1-7    ADBUS4    (GPIOL0)   /nSRST  optional module reset\n#  D5   J1-8    ADBUS5    (GPIOL1)   /nTRST  optional target reset\n#  D6   J1-9    ADBUS6    (GPIOL2)\n#  D7   J1-10   ADBUS7    (GPIOL3)\n#  C0   J2-1    ACBUS0    (GPIOH0)\n#  C1   J2-2    ACBUS1    (GPIOH1)\n#  C2   J2-3    ACBUS2    (GPIOH2)\n#  C3   J2-4    ACBUS3    (GPIOH3)\n#  C4   J2-5    ACBUS4    (GPIOH4)\n#  C5   J2-6    ACBUS5    (GPIOH5)\n#  C6   J2-7    ACBUS6    (GPIOH6)\n#  C7   J2-8    ACBUS7    (GPIOH7)\n#  C8   J2-9    ACBUS8\n#  C9   J2-10   ACBUS9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/gw16042.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Gateworks GW16042 JTAG Dongle\n#\n# http://www.gateworks.com/\n#\n# Layout:  FTDI FT2232H\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO (input)\n#   ADBUS3 TMS\n#   ADBUS4 nTRST\n#   ADBUS5 nSRST\n#   ADBUS6 OE (active high) for TRST, TDI, TMS, TCK\n#   ADBUS7 NC\n#   ACBUS0-7 NC\n#   BDBUS0 RXD\n#   BDBUS1 TXD (input)\n#\n\nadapter driver ftdi\nftdi device_desc \"USB-JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0058 0x007b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hie-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Hofstädtler Industrie-Electronic (HIE) JTAG Debugger\n#\n# https://www.hofstaedtler.com/jtag\n#\n\nadapter driver ftdi\nftdi channel 0\nftdi vid_pid 0x0403 0x6014\nftdi device_desc \"HIE JTAG Debugger\"\n\nftdi layout_init 0x0c08 0x4f1b\n\n# define both Reset signals\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n\n# Toggle USB LED\nftdi layout_signal LED -ndata 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hilscher_nxhx10_etm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hilscher NXHX 10-ETM\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_4ce145a5983e6\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 10-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hilscher_nxhx500_etm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hilscher NXHX 500-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX500-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hilscher_nxhx500_re.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hilscher NXHX 500-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_461ff2053bad1&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 500-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hilscher_nxhx50_etm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hilscher NXHX 50-ETM\n#\n# http://de.hilscher.com/files_design/8/NXHX50-ETM_description_Rev01_EN.pdf\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX 50-ETM\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hilscher_nxhx50_re.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hilscher NXHX 50-RE\n#\n# http://de.hilscher.com/products_details_hardware.html?p_id=P_483c0f582ad36&bs=20\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NXHX50-RE\"\nftdi vid_pid 0x0640 0x0028\n\nftdi layout_init 0x0308 0x030b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hitex_lpc1768stick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hitex LPC1768-Stick\n#\n# http://www.hitex.com/?id=1602\n#\n\n\nadapter driver ftdi\nftdi device_desc \"LPC1768-Stick\"\nftdi vid_pid 0x0640 0x0026\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/hitex_str9-comstick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hitex STR9-comStick\n#\n# http://www.hitex.com/index.php?id=383\n#\n\nadapter driver ftdi\nftdi device_desc \"STR9-comStick\"\nftdi vid_pid 0x0640 0x002c\n\nftdi layout_init 0x0108 0x010b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/icebear.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Section5 ICEBear\n#\n# http://section5.ch/icebear\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"ICEbear JTAG adapter\"\nftdi vid_pid 0x0403 0xc140\n\nftdi layout_init 0x0028 0x002b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/imx8mp-evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration file for NXP MC-IMX8MP-EVK on-board internal JTAG\n#\n# Using this interface requires enabling \"remote mode\" for the board using the\n# NXP bcu tool (see https://github.com/NXPmicro/bcu)\n#\n#\tbcu set_gpio remote_en 1 -board=imx8mpevk\n#\n# The REMOTE_EN gpio is accessible through the same FTDI adapter but it's\n# behind an I2C GPIO expander.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6011\nftdi channel 0\n\nftdi layout_init 0x00f8 0x000b\n\nftdi layout_signal RESET_B\t-data 0x0010 -oe 0x0010\n# Called SYS_nRST in schematics\nftdi layout_signal nSRST\t-data 0x0020 -oe 0x0020\nftdi layout_signal IO_nRST\t-data 0x0040 -oe 0x0040\nftdi layout_signal ONOFF_B\t-data 0x0080 -oe 0x0080\n\nftdi layout_signal GPIO1\t-data 0x0100 -oe 0x0100\nftdi layout_signal GPIO2\t-data 0x0200 -oe 0x0200\nftdi layout_signal GPIO3\t-data 0x0400 -oe 0x0400\nftdi layout_signal GPIO4\t-data 0x0800 -oe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/incircuit-icprog.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# In-Circuit's ICprog OpenOCD JTAG Adapter\n# https://shop.in-circuit.de/product_info.php?products_id=112\n#\n# Schematics available at\n# http://wiki.in-circuit.de/images/0/06/610000158A_openocd.pdf\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nSRST -noe 0x0400 -data 0x0800\nftdi layout_signal nTRST -noe 0x0100 -data 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/iotlab-usb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is the integrated adapter as found on the IoT-LAB boards\n# https://github.com/iot-lab/iot-lab/wiki\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/isodebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# isodebug v1\n# 5 kV isolated JTAG/SWD + UART adapter by Unjo AB\n\nadapter driver ftdi\nftdi vid_pid 0x22b7 0x150d\n\nftdi layout_init 0x0ff8 0xfffb\n\nftdi layout_signal LED -ndata 0x0100\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\nftdi layout_signal SWDIO_OE -data 0x0008\n\n# Mode signals, either of these needs to be high to drive the JTAG/SWD pins.\n# The power-on state is low for both signals but the init setting above sets\n# JTAG_EN high.\nftdi layout_signal SWD_EN -data 0x1000\nftdi layout_signal JTAG_EN -data 0x0800\n\n# In SWD mode, the JTAG_EN signal doubles as SWO_EN_N which switches the\n# second FTDI channel UART RxD to the SWO pin instead of the separate RxD\n# pin. Note that the default init state has this pin high so when OpenOCD\n# starts in SWD mode, SWO is by default disabled. To enable SWO tracing,\n# issue the command 'ftdi set_signal SWO_EN 1' where tracing is configured.\n# To switch back to using the separate UART, SWO_EN needs to be disabled\n# before exiting OpenOCD, or the adapter replugged.\nftdi layout_signal SWO_EN -nalias JTAG_EN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/jtag-lock-pick_tiny_2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# DISTORTEC JTAG-lock-pick Tiny 2\n#\n# http://www.distortec.com\n#\n\nadapter driver ftdi\nftdi device_desc \"JTAG-lock-pick Tiny 2\"\nftdi vid_pid 0x0403 0x8220\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal SWDIO_OE -ndata 0x1000\nftdi layout_signal LED -ndata 0x8000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/jtagkey.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Amontec JTAGkey\n#\n# http://www.amontec.com/jtagkey.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/jtagkey2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Amontec JTAGkey2\n#\n# http://www.amontec.com/jtagkey2.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/jtagkey2p.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Amontec JTAGkey2P\n#\n# http://www.amontec.com/jtagkey2p.shtml\n#\n\nadapter driver ftdi\nftdi device_desc \"Amontec JTAGkey-2P\"\nftdi vid_pid 0x0403 0xcff8\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/kt-link.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Kristech KT-Link\n#\n# http://www.kristech.eu\n#\n\nadapter driver ftdi\nftdi device_desc \"KT-LINK\"\nftdi vid_pid 0x0403 0xbbe2\n\nftdi layout_init 0x8c28 0xff3b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\nftdi layout_signal LED -data 0x8000\nftdi layout_signal SWD_EN -ndata 0x0020 -oe 0x2000\nftdi layout_signal SWDIO_OE -ndata 0x1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/lambdaconcept_ecpix-5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# This adapter is integrated in to LambdaConcept ECPIX-5 board:\n# \tinterface/ftdi/lambdaconcept_ecpix-5.cfg\n# See schematics for the ftdi layout:\n# http://docs.lambdaconcept.com/ecpix-5/_static/resources/SCH_ECPIX-5_R02.PDF\n\nadapter driver ftdi\nadapter speed 10000\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0xfff8 0xfffb\ntransport select jtag\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/lisa-l.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Lisa/L\n#\n# http://paparazzi.enac.fr/wiki/Lisa\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Lisa/L\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0008 0x180b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0040 -oe 0x0040\nftdi layout_signal LED -data 0x1800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/luminary-icdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Luminary Micro Stellaris LM3S9B9x Evaluation Kits\n# In-Circuit Debug Interface (ICDI) Board\n#\n# Essentially all Luminary debug hardware is the same, (with both\n# JTAG and SWD support compatible with ICDI boards.  This ICDI adapter\n# configuration is JTAG-only, but the same hardware handles SWD too.\n#\n# This is a discrete ftdi based debug board which supports ARM's\n# JTAG/SWD connectors in both backwards-compatible 20-pin format and\n# in the new-style compact 10-pin.  There's also an 8-pin connector\n# with serial port support.  It's included with LM3S9B9x eval boards.\n#\n# http://www.luminarymicro.com/products/ek-lm3s9b90.html\n# http://www.luminarymicro.com/products/ek-lm3s9b92.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Luminary Micro ICDI Board\"\nftdi vid_pid 0x0403 0xbcda\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/luminary-lm3s811.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Luminary Micro Stellaris LM3S811 Evaluation Kit\n#\n# http://www.luminarymicro.com/products/stellaris_811_evaluation_kits.html\n#\n# NOTE:  this is only for boards *before* Rev C, which adds support\n# for SWO tracing with ADBUS_6 DBG_ENn and BDBUS_4 SWO_EN signals.\n# The \"evb_lm3s811\" layout doesn't set up those signals.\n#\n# Rev C boards work more like the other Stellaris eval boards.  They\n# need to use the \"luminary_icdi\" layout to work correctly.\n#\n\nadapter driver ftdi\nftdi device_desc \"LM3S811 Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x0088 0x008b\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/luminary.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Luminary Micro Stellaris Evaluation Kits\n#\n# http://www.luminarymicro.com/products/evaluation_kits.html\n#\n# There are a number of evaluation kits for Stellaris Cortex-M3 chips.\n# Currently they all bundle ftdi based debug support.  When that is\n# used (instead of an external adapter), use this config file in one\n# of these two modes:\n#\n# - Eval board debug ... debug of the Stellaris chip via port A.\n#\n# - Other board debug ... same thing, but the board acts as a debug\n#   adapter for another board (using a standard ARM JTAG connector).\n#   The Stellaris chip stays in reset.\n#\n# Those support both JTAG and SWD.  SWD is an ARM-only two-wire debug\n# protocol; in 2009, OpenOCD does not support SWD.\n#\n# Port B of the ftdi chip is normally used as a serial link to the\n# Stellaris chip.  On most boards (but not older LM3S811 eval boards),\n# when SWD is used Port B may instead be used to read low-bandwidth\n# \"SWO trace\" data, including so-called \"printf style\" output from\n# firmware via the ITM module as well as profile data.\n#\n\nadapter driver ftdi\nftdi device_desc \"Stellaris Evaluation Board\"\nftdi vid_pid 0x0403 0xbcd9\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/m53evk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# DENX M53EVK\n#\n# http://www.denx-cs.de/?q=M53EVK\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/mbftdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# MBFTDI\n#\n# http://www.marsohod.org/prodmbftdi\n#\n# Also the Marsohod2 and the Marsohod3 boards\n# include a built-in MBFTDI for FPGA programming.\n# See http://www.marsohod.org/prodmarsohod2\n# and http://www.marsohod.org/plata-marsokhod3 for details.\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0008 0x000b\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/minimodule-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Supports SWD using the FT2232H or FT4232H minimodule.\n# Each can support 2 SWD interfaces.\n#\n# FT2232H or FT4232H minimodule channel 0 (Channel A)\n# Connector  FTDI              Target\n# Pin        Name\n# ---------  ------            ------\n# CN2-11     VIO               VDD_IO (Or connect to CN2-5 on the minimodule instead for a 3V3 interface)\n# CN2-2      GND               GND\n# CN2-7      ADBUS0 (TCK)      SWCLK\n# CN2-9      ADBUS2 (TDI/TDO)  SWDIO\n# CN2-10     ADBUS1 (TDO/TDI)  SWDIO\n# CN2-14     ADBUS4 (GPIOL0)   nRESET\n#\n# FT2232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN3-26  -  SWCLK\n# CN3-25  -  SWDIO\n# CN3-24  -  SWDIO\n# CN3-21  -  nRESET\n#\n# FT4232H minimodule channel 1 (Channel B)\n# FTDI       Target\n# ----       ------\n# CN2-11  -  VDD_IO\n# CN2-2   -  GND\n# CN2-18  -  SWCLK\n# CN2-17  -  SWDIO\n# CN2-20  -  SWDIO\n# CN2-22  -  nRESET\n#\n\nadapter driver ftdi\n\n#Select your module type and channel\n\n#ftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n#ftdi channel 1\n\n#ftdi device_desc \"FT4232H MiniModule\"\n#ftdi vid_pid 0x0403 0x6011\n#ftdi channel 1\n\nftdi layout_init 0x0000 0x000b\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\nftdi layout_signal SWD_EN -data 0\nftdi layout_signal SWDIO_OE -data 0\n\ntransport select swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/minimodule.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# FTDI MiniModule\n#\n# http://www.ftdichip.com/Support/Documents/DataSheets/Modules/DS_FT2232H_Mini_Module.pdf\n#\n\nadapter driver ftdi\nftdi device_desc \"FT2232H MiniModule\"\nftdi vid_pid 0x0403 0x6010\n\n# Every pin set as high impedance except TCK, TDI, TDO and TMS\nftdi layout_init 0x0008 0x000b\n\n# nSRST defined on pin CN2-13 of the MiniModule (pin ADBUS5 [AD5] on the FT2232H chip)\n# This choice is arbitrary. Use other GPIO pin if desired.\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/minispartan6.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# https://www.scarabhardware.com/minispartan6/\n# https://github.com/scarabhardware/miniSpartan6-plus/raw/master/miniSpartan6%2B_Rev_B.pdf\nadapter driver ftdi\n# The miniSpartan6+ sadly doesn't have a custom device description, so we just\n# have to hope you got it right.\n#ftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 30000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/miniwiggler.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Infineon DAP miniWiggler V3\n#\n# https://www.infineon.com/cms/en/product/evaluation-boards/kit_miniwiggler_3_usb/\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 nOE (output enable)\n#   ADBUS5\n#   ADBUS6\n#   ADBUS7 Blue LED\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5\n#   ACBUS6\n#   ACBUS7\n#\n\nadapter driver ftdi\nftdi device_desc \"DAS JDS miniWiggler V3.1\"\nftdi vid_pid 0x058b 0x0043\n\nftdi channel 0\nftdi layout_init 0x0008 0x001b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/neodb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Openmoko USB JTAG/RS232 adapter\n#\n# http://wiki.openmoko.org/wiki/Debug_Board_v3\n#\n\nadapter driver ftdi\nftdi device_desc \"Debug Board for Neo1973\"\nftdi vid_pid 0x1457 0x5118\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\nftdi layout_signal nNOR_WP -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/ngxtech.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NGX ARM USB JTAG\n#\n# http://shop.ngxtechnologies.com/product_info.php?cPath=26&products_id=30\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"NGX JTAG\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/olimex-arm-jtag-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM JTAG SWD adapter\n# https://www.olimex.com/Products/ARM/JTAG/ARM-JTAG-SWD/\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/olimex-arm-usb-ocd-h.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM-USB-OCD-H\n#\n# http://www.olimex.com/dev/arm-usb-ocd-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-OCD-H\"\nftdi vid_pid 0x15ba 0x002b\n\nftdi layout_init 0x0908 0x0b1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/olimex-arm-usb-ocd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM-USB-OCD\n#\n# http://www.olimex.com/dev/arm-usb-ocd.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG\"\nftdi vid_pid 0x15ba 0x0003\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/olimex-arm-usb-tiny-h.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM-USB-TINY-H\n#\n# http://www.olimex.com/dev/arm-usb-tiny-h.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG ARM-USB-TINY-H\"\nftdi vid_pid 0x15ba 0x002a\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/olimex-jtag-tiny.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Olimex ARM-USB-TINY\n#\n# http://www.olimex.com/dev/arm-usb-tiny.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Olimex OpenOCD JTAG TINY\"\nftdi vid_pid 0x15ba 0x0004\n\nftdi layout_init 0x0808 0x0a1b\nftdi layout_signal nSRST -oe 0x0200\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal LED -data 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/oocdlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Joern Kaipf's OOCDLink\n#\n# http://www.joernonline.de/contrexx2/cms/index.php?page=126\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"OOCDLink\"\nftdi vid_pid 0x0403 0xbaf8\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/opendous_ftdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Opendous\n#\n# http://code.google.com/p/opendous/wiki/JTAG\n#\n# According to the website, it is similar to jtagkey, but it uses channel B\n# (and it has a different pid number).\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0f1b\nftdi layout_signal nTRST -data 0x0100 -noe 0x0400\nftdi layout_signal nSRST -data 0x0200 -noe 0x0800\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/openocd-usb-hs.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# embedded projects openocd usb adapter v3\n#\n# http://shop.embedded-projects.net/index.php?module=artikel&action=artikel&id=14\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232-HS\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/openocd-usb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hubert Hoegl's USB to JTAG\n#\n# http://www.hs-augsburg.de/~hhoegl/proj/usbjtag/usbjtag.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Dual RS232\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/openrd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Marvell OpenRD\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/openrd.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"OpenRD JTAGKey FT2232D B\"\nftdi vid_pid 0x0403 0x9e90\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200\nftdi layout_signal nSRST -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/pipistrello.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# http://pipistrello.saanlima.com/\n# http://www.saanlima.com/download/pipistrello-v2.0/pipistrello_v2_schematic.pdf\nadapter driver ftdi\nftdi device_desc \"Pipistrello LX45\"\nftdi vid_pid 0x0403 0x6010\n# interface 1 is the uart\nftdi channel 0\n# just TCK TDI TDO TMS, no reset\nftdi layout_init 0x0008 0x000b\nreset_config none\n# this generally works fast: the fpga can handle 30MHz, the spi flash can handle\n# 54MHz with simple read, no dummy cycles, and wait-for-write-completion\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/pls_spc5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# PLS SPC5-UDESTK\n#\n# https://www.st.com/en/development-tools/spc5-udestk.html\n#\n# Reference the SPC56D Discovery schematics.\n#\n# Layout:  FTDI FT2232\n#   ADBUS0 TCK\n#   ADBUS1 TDI\n#   ADBUS2 TDO\n#   ADBUS3 TMS\n#   ADBUS4 TMS\n#   ADBUS5 RTCK\n#   ADBUS6\n#   ADBUS7 LED1\n#\n#   ACBUS0 nTRST\n#   ACBUS1 nSRST (external pull-down)\n#   ACUBS2\n#   ACBUS3\n#   ACBUS4\n#   ACBUS5 nSRST direction (input=L, output=H, external pull-down)\n#   ACBUS6 TMS direction (input=L, output=H, external pull-up)\n#   ACBUS7 LED2\n#\n\nadapter driver ftdi\nftdi device_desc \"PLS USB/JTAG Adapter for SPC5xxx\"\nftdi vid_pid 0x263d 0x4001\n\nftdi channel 0\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -ndata 0x2000 -oe 0x2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/redbee-econotag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Redwire Redbee-Econotag\n#\n# http://www.redwirellc.com/store/node/1\n#\n# The Redbee-Econotag has an onboard FT2232H with:\n#  - FT2232H channel A wired to mc13224v JTAG\n#  - FT2232H channel B wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/redbee-usb.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Redwire Redbee-USB\n#\n# http://www.redwirellc.com\n#\n# The Redbee-USB has an onboard FT2232H with:\n#  - FT2232H channel B wired to mc13224v JTAG\n#  - FT2232H channel A wired to mc13224v UART1\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi channel 1\n\nftdi layout_init 0x0c08 0x0c2b\nftdi layout_signal nTRST -data 0x0800\nftdi layout_signal nSRST -data 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/rowley-cc-arm-swd.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Rowley ARM SWD Adapter\n# http://sites.fastspring.com/rowley/product/armswdadapter\n# https://drive.google.com/file/d/0Bzv7UpKpOQhnTUNNdzI5OUR4WGs/edit?usp=sharing\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -nalias nTRST\nftdi layout_signal SWDIO_OE -alias TMS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/sheevaplug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Marvel SheevaPlug Development Kit\n#\n# http://www.marvell.com/products/embedded_processors/developer/kirkwood/sheevaplug.jsp\n#\n\nadapter driver ftdi\nftdi device_desc \"SheevaPlug JTAGKey FT2232D B\"\nftdi vid_pid 0x9e88 0x9e8f\nftdi channel 0\n\nftdi layout_init 0x0608 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/signalyzer-lite.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xverve Signalyzer LITE (DT-USB-SLITE)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer LITE\"\nftdi vid_pid 0x0403 0xbca1\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/signalyzer.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xverve Signalyzer Tool (DT-USB-ST)\n#\n# http://www.signalyzer.com\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on code in ft2232.c.\"\necho \"Please report your experience with this file to openocd-devel mailing list,\"\necho \"so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Signalyzer\"\nftdi vid_pid 0x0403 0xbca0\n\nftdi layout_init 0x0008 0x000b\nftdi layout_signal nTRST -data 0x0010 -oe 0x0010\nftdi layout_signal nSRST -data 0x0020 -oe 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/snps_sdp.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Synopsys SDP Mainboard has embdded FT2232 chip, which is similar to Digilent\n# HS-1, except that it uses channel B for JTAG communication, instead of\n# channel A.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\nftdi layout_init 0x0088 0x008b\nftdi channel 1\n\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/steppenprobe.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Steppenprobe\n# https://github.com/diegoherranz/steppenprobe\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n\n# Initial Layout\nftdi layout_init 0x0058 0x99fb\n# Signal        Data    Direction       Notes\n# TCK           0       1 (out)\n# TDI           0       1 (out)\n# TDO           0       0 (in)\n# TMS           1       1 (out)         JTAG IEEE std recommendation\n# LED           1       1 (out)         LED off\n# SWD_EN        0       1 (out)         OpenOCD sets this high for SWD\n# SWDIO_OE      1       1 (out)         Ext. buffer tristated\n# SRST          0       1 (out)         Translates to nSRST=Z\n\n# Unused        0       1 (out)\n# GPIO_A        0       0 (in)\n# GPIO_B        0       0 (in)\n# Unused        0       1 (out)\n# Unused        0       1 (out)\n# GPIO_C        0       0 (in)\n# GPIO_D        0       0 (in)\n# Unused        0       1 (out)\n\n# Signals definition\nftdi layout_signal LED -ndata 0x0010\nftdi layout_signal SWD_EN -data 0x0020\nftdi layout_signal SWDIO_OE -ndata 0x0040\nftdi layout_signal nSRST -oe 0x0080\n\nftdi layout_signal GPIO_A -data 0x0200 -oe 0x0200 -input 0x0200\nftdi layout_signal GPIO_B -data 0x0400 -oe 0x0400 -input 0x0400\nftdi layout_signal GPIO_C -data 0x2000 -oe 0x2000 -input 0x2000\nftdi layout_signal GPIO_D -data 0x4000 -oe 0x4000 -input 0x4000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/stm32-stick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Hitex STM32-PerformanceStick\n#\n# http://www.hitex.com/index.php?id=340\n#\n\nadapter driver ftdi\nftdi device_desc \"STM32-PerformanceStick\"\nftdi vid_pid 0x0640 0x002d\n\nftdi layout_init 0x0388 0x038b\nftdi layout_signal nTRST -data 0x0100\nftdi layout_signal nSRST -data 0x0080 -noe 0x200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/swd-resistor-hack.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Connect TDI to SWDIO via a suitable series resistor (220-470 Ohm or\n# so depending on the drive capability of the target and adapter);\n# connect TDO directly to SWDIO.\n#\n# You also need to have reliable GND connection between the target and\n# adapter. Vref of the adapter should be supplied with a voltage equal\n# to the target's (preferably connect it to Vcc). You can also\n# optionally connect nSRST. Leave everything else unconnected.\n#\n# FTDI                          Target\n# ----                          ------\n# 1  - Vref   ----------------- Vcc\n# 3  - nTRST  -\n# 4  - GND    ----------------- GND\n# 5  - TDI    ---/\\470 Ohm/\\--- SWDIO\n# 7  - TMS    -\n# 9  - TCK    ----------------- SWCLK\n# 11 - RTCK   -\n# 13 - TDO    ----------------- SWDIO\n# 15 - nSRST  - - - - - - - - - nRESET\n#\n\ntransport select swd\n\nftdi layout_signal SWD_EN -data 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/ti-icdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This is an FTDI-based debugging solution as found on some TI boards,\n# e.g. CC3200 LaunchPad.\n#\n# The schematics are identical to luminary-icdi (including SWD\n# support) but the USB IDs are different.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0451 0xc32a\n\nftdi layout_init 0x00a8 0x00eb\nftdi layout_signal nSRST -noe 0x0020\nftdi layout_signal SWD_EN -ndata 0x0080\nftdi layout_signal SWDIO_OE -data 0x0008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/tigard.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Tigard: An FTDI FT2232H-based multi-protocol tool for hardware hacking.\n# https://github.com/tigard-tools/tigard\n\nadapter driver ftdi\n\nftdi device_desc \"Tigard V1.1\"\nftdi vid_pid 0x0403 0x6010\n\nftdi channel 1\n\nftdi layout_init 0x0038 0x003b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -data 0x0020\n\n# This board doesn't support open-drain reset modes since its output buffer is\n# always enabled.\nreset_config srst_push_pull trst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/tumpa-lite.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TIAO USB Multi-Protocol Adapter (TUMPA) Lite\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-lite-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a99\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020 -oe 0x0020\nftdi layout_signal nSRST -data 0x0010 -oe 0x0010\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/tumpa.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TIAO USB Multi-Protocol Adapter (TUMPA)\n#\n# http://www.diygadget.com/tiao-usb-multi-protocol-adapter-jtag-spi-i2c-serial.html\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x8a98 0x0403 0x6010\n\nftdi layout_init 0x0038 0x087b\nftdi layout_signal nTRST -data 0x0020\nftdi layout_signal nSRST -data 0x0010\n\nreset_config srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/turtelizer2-revB.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# egnite Turtelizer 2 rev B (with SRST only)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, it is based on schematics and code\"\necho \"in ft2232.c. Please report your experience with this file to openocd-devel\"\necho \"mailing list, so it could be marked as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c5b\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -data 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/turtelizer2-revC.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# egnite Turtelizer 2 revC (with TRST and SRST)\n#\n# http://www.ethernut.de/en/hardware/turtelizer/index.html\n#\n\nadapter driver ftdi\nftdi device_desc \"Turtelizer JTAG/RS232 Adapter\"\nftdi vid_pid 0x0403 0xbdc8\n\nftdi layout_init 0x0008 0x0c7b\nftdi layout_signal nTRST -oe 0x0020\nftdi layout_signal nSRST -oe 0x0040\nftdi layout_signal LED -ndata 0x0c00\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/um232h.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# FTDI UM232H as a JTAG interface\n#\n# http://www.ftdichip.com/Products/Modules/DevelopmentModules.htm#UM232H\n#\n# This should also work with a UM232H-B, but that has not been tested.\n# Note that UM232H and UM232H-B are 3.3V only.\n#\n\nadapter driver ftdi\n#ftdi device_desc \"UM232H\"\nftdi vid_pid 0x0403 0x6014\n\nftdi layout_init 0xfff8 0xfffb\nftdi layout_signal nTRST -data 0x0100 -oe 0x0100\nftdi layout_signal nSRST -data 0x0200 -oe 0x0200\n\n# UM232H        FT232H    JTAG\n# Name  Pin     Name      Func\n# AD0   J2-6    ADBUS0    TCK\n# AD1   J2-7    ADBUS1    TDI\n# AD2   J2-8    ADBUS2    TDO\n# AD3   J2-9    ADBUS3    TMS\n# AD4   J2-10   ADBUS4    (GPIOL0)\n# AD5   J2-11   ADBUS5    (GPIOL1)\n# AD6   J2-12   ADBUS6    (GPIOL2)\n# AD7   J2-13   ADBUS7    (GPIOL3)\n# AD0   J1-14   ACBUS0    /TRST\n# AD1   J1-13   ACBUS1    /SRST\n# AD2   J1-12   ACBUS2    (GPIOH2)\n# AD3   J1-11   ACBUS3    (GPIOH3)\n# AD4   J1-10   ACBUS4    (GPIOH4)\n# AD5   J1-9    ACBUS5    (GPIOH5)\n# AD6   J1-8    ACBUS6    (GPIOH6)\n# AD7   J1-7    ACBUS7    (GPIOH7)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/vpaclink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Voipac VPACLink\n#\n# http://voipac.com/27M-JTG-000\n#\n\necho \"WARNING!\"\necho \"This file was not tested with real interface, but is assumed to work as this\"\necho \"interface uses the same layout as configs that were verified. Please report your\"\necho \"experience with this file to openocd-devel mailing list, so it could be marked\"\necho \"as working or fixed.\"\n\nadapter driver ftdi\nftdi device_desc \"VPACLink\"\nftdi vid_pid 0x0403 0x6010\n\nftdi layout_init 0x0508 0x0f1b\nftdi layout_signal nTRST -data 0x0200 -noe 0x0100\nftdi layout_signal nSRST -data 0x0800 -noe 0x0400\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/xds100v2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments XDS100v2\n#\n# http://processors.wiki.ti.com/index.php/XDS100#XDS100v2_Features\n#\n# Detailed documentation is available only as CPLD verilog source code\n# to the registered TI users.\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0xa6d0 0x0403 0x6010\n\nftdi layout_init 0x0038 0x597b\n\n#  8000 z - unused\n#  4000 0 > CPLD loopback          (all target side pins high-Z)\n#  2000 z < !( cable connected )   (open drain on CPLD side for $reasons)\n#  1000 0 > EMU1_oe\n#\n#   800 0 > PWR_RST = clear power-loss flag on rising edge\n#   400 z < !( power-loss flag )\n#   200 z < nSRST\n#   100 0 > nSRST_oe\n#\n#    80 z < RTCK\n#    40 0 > EMU0_oe\n#    20 1 > EMU_EN\n#    10 1 > nTRST\n#\n#     8 1 > TMS\n#     4 z < TDO\n#     2 0 > TDI\n#     1 0 > TCK\n#\n# As long as the power-loss flag is set, all target-side pins are\n# high-Z except the EMU-pins for which the opposite holds unless\n# EMU_EN is high.\n#\n# To use wait-in-reset, drive EMU0 low at power-on reset. If the\n# target normally reuses EMU0 for other purposes, clear EMU_EN to\n# keep the EMU pins high-Z until the target is power-cycled.\n#\n# The LED only turns off at USB suspend, which is also the only way to\n# set the power-loss flag manually. (Can be done in software e.g. by\n# changing the USB configuration to zero.)\n#\n\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -oe 0x0100\nftdi layout_signal EMU_EN -data 0x0020\nftdi layout_signal EMU0 -oe 0x0040\nftdi layout_signal EMU1 -oe 0x1000\nftdi layout_signal PWR_RST -data 0x0800\nftdi layout_signal LOOPBACK -data 0x4000\n\necho \"\\nInfo : to use this adapter you MUST add ``init; ftdi set_signal PWR_RST 1; jtag arp_init'' to the end of your config file!\\n\"\n# note: rising edge on PWR_RST is also needed after power-cycling the\n# target\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/xds100v3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments XDS100 ver 3.0\n#\n# http://processors.wiki.ti.com/index.php/XDS100\n#\n\n# Version 3.0 is the same as 2.0 as far as OpenOCD is concerned\nsource [find interface/ftdi/xds100v2.cfg]\n\n# The USB ids are different.\nftdi vid_pid 0x0403 0xa6d1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ftdi/xt_kc705_ml605.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Xilinx KC705 / ML605 with Xtensa daughtercard; onboard USB/FT2232\n#\n\nadapter driver ftdi\nftdi vid_pid 0x0403 0x6010\n# Specify \"adapter serial <identifier>\" here as needed\n\nftdi layout_init 0x0010 0x007b\nftdi layout_signal nTRST -data 0x0010\nftdi layout_signal nSRST -ndata 0x0020\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/imx-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Config for using NXP IMX CPU\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches to host voltage and the cable is short enough.\n#\n#\n\nadapter driver imx_gpio\n\n# For most IMX processors 0x0209c000\nimx_gpio_peripheral_base 0x0209c000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for IMX6UL@528MHz\n# imx_gpio_speed SPEED_COEFF SPEED_OFFSET\nimx_gpio_speed_coeffs 50000 50\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo.\n# Example configuration:\n# imx_gpio_jtag_nums 6 7 8 9\n\n# SWD interface pins: swclk swdio\n# Example configuration:\nimx_gpio_swd_nums 1 6\n\n# imx_gpio_trst_num 10\n# reset_config trst_only\n\n# imx_gpio_srst_num 11\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/jlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# SEGGER J-Link\n#\n# http://www.segger.com/jlink.html\n#\n\nadapter driver jlink\n\n# The serial number can be used to select a specific device in case more than\n# one is connected to the host.\n#\n# Example: Select J-Link with serial number 123456789\n#\n# adapter serial 123456789\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/jtag_dpi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Provide support for the Cadence JTAG BFM\n#\n# Copyright (c) 2020, Ampere Computing LLC\n#\n\nadapter driver jtag_dpi\n\n# Set the DPI JTAG server port\nif { [info exists DPI_PORT] } {\n   set _DPI_PORT $DPI_PORT\n} else {\n   set _DPI_PORT 5555\n}\n\n# Set the DPI JTAG server address\nif { [info exists DPI_ADDRESS] } {\n   set _DPI_ADDRESS $DPI_ADDRESS\n} else {\n   set _DPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_dpi set_port $_DPI_PORT\njtag_dpi set_address $_DPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/jtag_hat_rpi2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Blinkinlabs JTAG_Hat\n#\n# https://github.com/blinkinlabs/jtag_hat\n#\n\nadapter driver bcm2835gpio\n\nbcm2835gpio peripheral_base 0x3F000000\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# These depend on system clock, calibrated for stock 700MHz\n# bcm2835gpio_speed SPEED_COEFF SPEED_OFFSET\nbcm2835gpio speed_coeffs 146203 36\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nadapter gpio tck -chip 0 11\nadapter gpio tms -chip 0 25\nadapter gpio tdi -chip 0 10\nadapter gpio tdo -chip 0 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nadapter gpio swclk -chip 0 11\nadapter gpio swdio -chip 0 25\n\n# Direction pin for SWDIO level shifting buffer\nadapter gpio swdio_dir -chip 0 6\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\nadapter gpio trst -chip 0 7\n#reset_config trst_only\n\nadapter gpio srst -chip 0 24\n#reset_config srst_only\n\n# or if you have both connected\n#reset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/jtag_vpi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter driver jtag_vpi\n\n# Set the VPI JTAG server port\nif { [info exists VPI_PORT] } {\n   set _VPI_PORT $VPI_PORT\n} else {\n   set _VPI_PORT 5555\n}\n\n# Set the VPI JTAG server address\nif { [info exists VPI_ADDRESS] } {\n   set _VPI_ADDRESS $VPI_ADDRESS\n} else {\n   set _VPI_ADDRESS \"127.0.0.1\"\n}\n\njtag_vpi set_port $_VPI_PORT\njtag_vpi set_address $_VPI_ADDRESS\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/kitprog.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Cypress Semiconductor KitProg\n#\n# Note: This is the driver for the proprietary KitPtog protocol. If the\n# KitProg is in CMSIS-DAP mode, you should either use the cmsis-dap\n# interface driver or switch the KitProg to KitProg mode.\n#\n\nadapter driver kitprog\n\n# Optionally specify the serial number of the KitProg you want to use.\n# adapter serial 1926402735485200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/nulink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nuvoton Nu-Link in-circuit debugger/programmer\n#\n\nadapter driver hla\nhla_layout nulink\nhla_device_desc \"Nu-Link\"\nhla_vid_pid 0x0416 0x511b 0x0416 0x511c 0x0416 0x511d 0x0416 0x5200 0x0416 0x5201\n\n# Only swd is supported\ntransport select hla_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/opendous.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# opendous-jtag\n#\n# http://code.google.com/p/opendous-jtag/\n#\n\nadapter driver opendous\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/openjtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# OpenJTAG\n#\n# www.openjtag.org\n#\n\nadapter driver openjtag\nopenjtag device_desc \"Open JTAG Project\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/osbdm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# P&E Micro OSBDM (aka OSJTAG) interface\n#\n# http://pemicro.com/osbdm/\n#\nadapter driver osbdm\nreset_config srst_only\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/parport.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Parallel port wiggler (many clones available) on port 0x378\n#\n# Addresses: 0x378/LPT1 or 0x278/LPT2 ...\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   if {$tcl_platform(platform) eq \"windows\"} {\n      set _PARPORTADDR 0x378\n   } {\n      set _PARPORTADDR 0\n   }\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable wiggler\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/parport_dlc5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Xilinx Parallel Cable III 'DLC 5' (and various clones)\n#\n# http://www.xilinx.com/itp/xilinx4/data/docs/pac/appendixb.html\n#\n\nif { [info exists PARPORTADDR] } {\n   set _PARPORTADDR $PARPORTADDR\n} else {\n   set _PARPORTADDR 0\n}\n\nadapter driver parport\nparport port $_PARPORTADDR\nparport cable dlc5\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/raspberrypi-gpio-connector.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Config for Raspberry Pi GPIO header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V and the cable is short enough.\n#\n# Do not forget the GND connection, e.g. pin 20 of the GPIO header.\n#\n\n# GPIO 25 (pin 22) previously used for TMS/SWDIO is pulled-down by default.\n# The JTAG/SWD specification requires pull-up at the target board\n# for either signal. Connecting the signal pulled-up on the target\n# to the pull-down on the adapter is not a good idea.\n# GPIO 8 is pulled-up by default.\necho \"Warn : TMS/SWDIO moved to GPIO 8 (pin 24). Check the wiring please!\"\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 24 19 21\nadapter gpio tck -chip 0 11\nadapter gpio tms -chip 0 8\nadapter gpio tdi -chip 0 10\nadapter gpio tdo -chip 0 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 24\nadapter gpio swclk -chip 0 11\nadapter gpio swdio -chip 0 8\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# adapter gpio trst -chip 0 7\n# reset_config trst_only\n\n# adapter gpio srst -chip 0 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/raspberrypi-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config for Raspberry Pi used as a bitbang adapter.\n# https://www.raspberrypi.com/documentation/computers/raspberry-pi.html\n\n# Supports all models with 40-pin or 26-pin GPIO connector up to Raspberry Pi 4 B\n# also supports Raspberry Pi Zero, Zero W and Zero 2 W.\n\n# Adapter speed calibration is computed from cpufreq/scaling_max_freq.\n# Adjusts automatically if CPU is overclocked.\n\nadapter driver bcm2835gpio\n\nproc read_file { name } {\n\tif {[catch {open $name r} fd]} {\n\t\treturn \"\"\n\t}\n\tset result [read $fd]\n\tclose $fd\n\treturn $result\n}\n\nproc measure_clock {} {\n\tset result [exec vcgencmd measure_clock arm]\n\tset clock_hz [lindex [split $result \"=\"] 1]\n\texpr { $clock_hz / 1000 }\n}\n\nproc get_max_cpu_clock { default } {\n\tset clock [read_file /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq]\n\tif { $clock > 100000 } {\n\t\treturn $clock\n\t}\n\n\t# cpufreq not available. As the last resort try Broadcom's proprietary utility\n\tif {![catch measure_clock clock] && $clock > 100000} {\n\t\treturn $clock\n\t}\n\n\techo \"WARNING: Host CPU clock unknown.\"\n\techo \"WARNING: Using the highest possible value $default kHz as a safe default.\"\n\techo \"WARNING: Expect JTAG/SWD clock significantly slower than requested.\"\n\n\treturn $default\n}\n\nset compat [read_file /proc/device-tree/compatible]\nset clocks_per_timing_loop 4\n\nif {[string match *bcm2711* $compat]} {\n\tset speed_offset 52\n} elseif {[string match *bcm2837* $compat] || [string match *bcm2710* $compat]} {\n\tset speed_offset 34\n} elseif {[string match *bcm2836* $compat] || [string match *bcm2709* $compat]} {\n\tset speed_offset 36\n} elseif {[string match *bcm2835* $compat] || [string match *bcm2708* $compat]} {\n\tset clocks_per_timing_loop 6\n\tset speed_offset 32\n} else {\n\tset speed_offset 32\n\techo \"WARNING: Unknown type of the host SoC. Expect JTAG/SWD clock slower than requested.\"\n}\n\nset clock [get_max_cpu_clock 2000000]\nset speed_coeff [expr { $clock / $clocks_per_timing_loop }]\n\n# Transition delay calculation: SPEED_COEFF/khz - SPEED_OFFSET\n# The coefficients depend on system clock and CPU frequency scaling.\nbcm2835gpio speed_coeffs $speed_coeff $speed_offset\n\nsource [find interface/raspberrypi-gpio-connector.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/raspberrypi2-native.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: interface/raspberrypi2-native.cfg is deprecated.\"\necho \"WARNING: Please use interface/raspberrypi-native.cfg for all Raspberry Pi models.\"\n\nsource [find interface/raspberrypi-native.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/rlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Raisonance RLink\n#\n# http://www.mcu-raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html\n#\n\nadapter driver rlink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/rshim.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# BlueField SoC in-circuit debugger/programmer\n#\n\nadapter driver rshim\ntransport select dapdirect_swd\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/stlink-dap.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n# This new interface driver creates a ST-Link wrapper for ARM-DAP named \"dapdirect\"\n# Old ST-LINK/V1 and ST-LINK/V2 pre version V2J24 don't support \"dapdirect\"\n#\n# SWIM transport is natively supported\n#\n\nadapter driver st-link\nst-link vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757\n\n# transport select dapdirect_jtag\n# transport select dapdirect_swd\n# transport select swim\n\n# Optionally specify the serial number of usb device\n# e.g.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/stlink-v1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: interface/stlink-v1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/stlink-v2-1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: interface/stlink-v2-1.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/stlink-v2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"WARNING: interface/stlink-v2.cfg is deprecated, please switch to interface/stlink.cfg\"\nsource [find interface/stlink.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/stlink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# STMicroelectronics ST-LINK/V1, ST-LINK/V2, ST-LINK/V2-1, STLINK-V3 in-circuit\n# debugger/programmer\n#\n\nadapter driver hla\nhla_layout stlink\nhla_device_desc \"ST-LINK\"\nhla_vid_pid 0x0483 0x3744 0x0483 0x3748 0x0483 0x374b 0x0483 0x374d 0x0483 0x374e 0x0483 0x374f 0x0483 0x3752 0x0483 0x3753 0x0483 0x3754 0x0483 0x3755 0x0483 0x3757\n\n# Optionally specify the serial number of ST-LINK/V2 usb device.  ST-LINK/V2\n# devices seem to have serial numbers with unreadable characters.  ST-LINK/V2\n# firmware version >= V2.J21.S4 recommended to avoid issues with adapter serial\n# number reset issues.\n# eg.\n# adapter serial \"\\xaa\\xbc\\x6e\\x06\\x50\\x75\\xff\\x55\\x17\\x42\\x19\\x3f\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/sysfsgpio-raspberrypi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Config for using RaspberryPi's expansion header\n#\n# This is best used with a fast enough buffer but also\n# is suitable for direct connection if the target voltage\n# matches RPi's 3.3V\n#\n# Do not forget the GND connection, pin 6 of the expansion header.\n#\n\nadapter driver sysfsgpio\n\n# Each of the JTAG lines need a gpio number set: tck tms tdi tdo\n# Header pin numbers: 23 22 19 21\nsysfsgpio jtag_nums 11 25 10 9\n\n# Each of the SWD lines need a gpio number set: swclk swdio\n# Header pin numbers: 23 22\nsysfsgpio swd_nums 11 25\n\n# If you define trst or srst, use appropriate reset_config\n# Header pin numbers: TRST - 26, SRST - 18\n\n# sysfsgpio trst_num 7\n# reset_config trst_only\n\n# sysfsgpio srst_num 24\n# reset_config srst_only srst_push_pull\n\n# or if you have both connected,\n# reset_config trst_and_srst srst_push_pull\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ti-icdi.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Stellaris In-Circuit Debug Interface (ICDI) Board\n#\n# This is the propriety ICDI interface used on newer boards such as\n# LM4F232 Evaluation Kit - http://www.ti.com/tool/ek-lm4f232\n# Stellaris Launchpad - http://www.ti.com/stellaris-launchpad\n# http://www.ti.com/tool/ek-lm4f232\n#\n\nadapter driver hla\nhla_layout ti-icdi\nhla_vid_pid 0x1cbe 0x00fd\n\n# Optionally specify the serial number of TI-ICDI devices, for when using\n# multiple devices. Serial numbers can be obtained using lsusb -v\n# Ex.\n# adapter serial \"0F003065\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/ulink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Keil ULINK running OpenULINK firmware.\n#\n# http://www.keil.com/ulink1/\n# http://article.gmane.org/gmane.comp.debugging.openocd.devel/17362\n#\n\nadapter driver ulink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/usb-jtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ixo-usb-jtag - Emulation of a Altera Bus Blaster I on a Cypress FX2 IC.\n#\n# The ixo-usb-jtag firmware can be loaded onto a bunch of different hardware\n# including;\n#  * Xilinx USB Platform Cable\n#  * Many Digilent boards such as the Nexys, Nexys 2 and Atlys boards\n#  * Many fpga4fun.com boards from such as the Saxo and Xylo boards\n#  * The Numato Opsis\n#\n# Original version - http://www.ixo.de/info/usb_jtag/\n#  Updated version - http://ixo-jtag.sourceforge.net/\n#   Newest version - http://github.com/mithro/ixo-usb-jtag\n#\n# Procedure for using is;\n#  * Get the ixo-usb-jtag firmware for your hardware (or build it yourself).\n#  * Load the firmware using the fxload tool.\n#  * Use openocd.\n#\n# Unless you burn the firmware into the EEPROM on your device, power cycling\n# will require you to reload the firmware using the fxload tool. This can be\n# automated by using udev rules (which can be found in the firmware\n# repository).\n#\n# Ubuntu packages built from mithro's version (with prebuilt firmware and udev\n# rules) can be found at\n# https://launchpad.net/~timvideos/+archive/ubuntu/fpga-support\n#\n# TODO: Refactor the usb_blaster driver to allow loading firmware using any low\n# level driver. Loading firmware is currently only supported on the ublast2\n# driver but ixo-usb-jtag requires the ftdi driver.\n\nadapter driver usb_blaster\nusb_blaster vid_pid 0x16C0 0x06AD\nusb_blaster device_desc \"Van Ooijen Technische Informatica\"\n# ixo-usb-jtag is only compatible with the ublast1 protocol implemented via the\n# ftdi modes, using ublast2 will cause openocd to hang.\nusb_blaster lowlevel_driver ftdi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/usbprog.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Embedded Projects USBprog\n#\n# http://embedded-projects.net/index.php?page_id=135\n#\n\nadapter driver usbprog\n# USBprog is broken w/short TMS sequences, this is a workaround\n# until the C code can be fixed.\ntms_sequence long\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/vdebug.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n\nif { [info exists VDEBUGHOST] } {\n\tset _VDEBUGHOST $VDEBUGHOST\n} else {\n\tset _VDEBUGHOST localhost\n}\nif { [info exists VDEBUGPORT] } {\n\tset _VDEBUGPORT $VDEBUGPORT\n} else {\n\tset _VDEBUGPORT 8192\n}\n\nadapter driver vdebug\n# vdebug server:port\nvdebug server $_VDEBUGHOST:$_VDEBUGPORT\n\n# example config debug level and log\n#debug_level 3\n#log_output vd_ocd.log\n\n# example config listen on all interfaces, disable tcl/telnet server\nbindto 0.0.0.0\n#gdb_port 3333\n#telnet_port disabled\ntcl_port disabled\n\n# transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw\nvdebug batching 1\n\n# Polling values\nvdebug polling 100 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/vsllink.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Versaloon Link -- VSLLink\n#\n# http://www.versaloon.com/\n#\n\nadapter driver vsllink\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/interface/xds110.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments XDS110\n#\n# http://processors.wiki.ti.com/index.php/XDS110\n# http://processors.wiki.ti.com/index.php/Emulation_Software_Package#XDS110_Support_Utilities\n#\n\nadapter driver xds110\n\n# Use serial number option to use a specific XDS110\n# when more than one are connected to the host.\n# adapter serial 00000000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/mem_helper.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Helper for common memory read/modify/write procedures\n\n# mrw: \"memory read word\", returns value of $reg\nproc mrw {reg} {\n\treturn [read_memory $reg 32 1]\n}\n\nadd_usage_text mrw \"address\"\nadd_help_text mrw \"Returns value of word in memory.\"\n\n# mrh: \"memory read halfword\", returns value of $reg\nproc mrh {reg} {\n\treturn [read_memory $reg 16 1]\n}\n\nadd_usage_text mrh \"address\"\nadd_help_text mrh \"Returns value of halfword in memory.\"\n\n# mrb: \"memory read byte\", returns value of $reg\nproc mrb {reg} {\n\treturn [read_memory $reg 8 1]\n}\n\nadd_usage_text mrb \"address\"\nadd_help_text mrb \"Returns value of byte in memory.\"\n\n# mmw: \"memory modify word\", updates value of $reg\n#       $reg <== ((value & ~$clearbits) | $setbits)\nproc mmw {reg setbits clearbits} {\n\tset old [mrw $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\tmww $reg $new\n}\n\nadd_usage_text mmw \"address setbits clearbits\"\nadd_help_text mmw \"Modify word in memory. new_val = (old_val & ~clearbits) | setbits;\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/memory.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# MEMORY\n#\n# All Memory regions have two components.\n#    (1) A count of regions, in the form N_NAME\n#    (2) An array within info about each region.\n#\n# The ARRAY\n#\n#       <NAME>(  RegionNumber ,  ATTRIBUTE )\n#\n# Where <NAME> is one of:\n#\n#     N_FLASH  & FLASH   (internal memory)\n#     N_RAM    & RAM     (internal memory)\n#     N_MMREGS & MMREGS  (for memory mapped registers)\n#     N_XMEM   & XMEM    (off chip memory, ie: flash on cs0, sdram on cs2)\n# or  N_UNKNOWN & UNKNOWN for things that do not exist.\n#\n# We have 1 unknown region.\nset N_UNKNOWN 1\n# All MEMORY regions must have these attributes\n#     CS          - chip select (if internal, use -1)\nset UNKNOWN(0,CHIPSELECT) -1\n#     BASE        - base address in memory\nset UNKNOWN(0,BASE)       0\n#     LEN         - length in bytes\nset UNKNOWN(0,LEN)        $CPU_MAX_ADDRESS\n#     HUMAN       - human name of the region\nset UNKNOWN(0,HUMAN) \"unknown\"\n#     TYPE        - one of:\n#                       flash, ram, mmr, unknown\n#                    For harvard arch:\n#                       iflash, dflash, iram, dram\nset UNKNOWN(0,TYPE)       \"unknown\"\n#     RWX         - access ablity\n#                       unix style chmod bits\n#                           0 - no access\n#                           1 - execute\n#                           2 - write\n#                           4 - read\n#                       hence: 7 - readwrite execute\nset RWX_NO_ACCESS     0\nset RWX_X_ONLY        $BIT0\nset RWX_W_ONLY        $BIT1\nset RWX_R_ONLY        $BIT2\nset RWX_RW            [expr {$RWX_R_ONLY + $RWX_W_ONLY}]\nset RWX_R_X           [expr {$RWX_R_ONLY + $RWX_X_ONLY}]\nset RWX_RWX           [expr {$RWX_R_ONLY + $RWX_W_ONLY + $RWX_X_ONLY}]\nset UNKNOWN(0,RWX)     $RWX_NO_ACCESS\n\n#     WIDTH       - access width\n#                      8,16,32 [0 means ANY]\nset ACCESS_WIDTH_NONE 0\nset ACCESS_WIDTH_8    $BIT0\nset ACCESS_WIDTH_16   $BIT1\nset ACCESS_WIDTH_32   $BIT2\nset ACCESS_WIDTH_ANY  [expr {$ACCESS_WIDTH_8 + $ACCESS_WIDTH_16 + $ACCESS_WIDTH_32}]\nset UNKNOWN(0,ACCESS_WIDTH) $ACCESS_WIDTH_NONE\n\nproc iswithin { ADDRESS BASE LEN } {\n    return [expr {(($ADDRESS - $BASE) >= 0) && (($BASE + $LEN - $ADDRESS) > 0)}]\n}\n\nproc address_info { ADDRESS } {\n\n    foreach WHERE { FLASH RAM MMREGS XMEM UNKNOWN } {\n\tif { info exists $WHERE } {\n\t    set lmt [set N_[set WHERE]]\n\t    for { set region 0 } { $region < $lmt } { incr region } {\n\t\tif { iswithin $ADDRESS $WHERE($region,BASE) $WHERE($region,LEN) } {\n\t\t    return  \"$WHERE $region\";\n\t\t}\n\t    }\n\t}\n    }\n\n    # Return the 'unknown'\n    return \"UNKNOWN 0\"\n}\n\nproc memread32 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8 {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8 {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n\nproc memread32_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 32 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread32: $msg\"\n    }\n}\n\nproc memread16_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 16 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread16: $msg\"\n    }\n}\n\nproc memread8_phys {ADDR} {\n    if ![ catch { set foo [read_memory $ADDR 8 1 phys] } msg ] {\n\treturn $foo\n    } else {\n\terror \"memread8: $msg\"\n    }\n}\n\nproc memwrite32_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 32 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite32: $msg\"\n    }\n}\n\nproc memwrite16_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 16 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite16: $msg\"\n    }\n}\n\nproc memwrite8_phys {ADDR DATA} {\n    if ![ catch { write_memory $ADDR 8 $DATA phys } msg ] {\n\treturn $DATA\n    } else {\n\terror \"memwrite8: $msg\"\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/mmr_helpers.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nproc proc_exists { NAME } {\n    set n [info commands $NAME]\n    set l [string length $n]\n    return [expr {$l != 0}]\n}\n\n# Give: REGISTER name - must be a global variable.\nproc show_mmr32_reg { NAME } {\n\n    global $NAME\n    # we want $($NAME)\n    set a [set [set NAME]]\n\n    if ![catch { set v [memread32 $a] } msg ] {\n\techo [format \"%15s: (0x%08x): 0x%08x\" $NAME $a $v]\n\n\t# Was a helper defined?\n\tset fn show_${NAME}_helper\n\tif [ proc_exists $fn ] {\n\t    # Then call it\n\t    $fn $NAME $a $v\n\t}\n\treturn $v;\n    } else {\n\terror [format \"%s (%s)\" $msg $NAME ]\n    }\n}\n\n\n# Give: NAMES - an array of names accessible\n#               in the callers symbol-scope.\n#       VAL - the bits to display.\n\nproc show_mmr32_bits { NAMES VAL } {\n\n    upvar $NAMES MYNAMES\n\n    set w 5\n    foreach {IDX N} $MYNAMES {\n\tset l [string length $N]\n\tif { $l > $w } { set w $l }\n    }\n\n    for { set x 24 } { $x >= 0 } { incr x -8 } {\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    set s $MYNAMES([expr {$x + $y}])\n\t    echo -n [format \"%2d: %-*s | \" [expr {$x + $y}] $w $s ]\n\t}\n\techo \"\"\n\n\techo -n \"  \"\n\tfor { set y 7 } { $y >= 0 } { incr y -1 } {\n\t    echo -n [format \"    %d%*s | \" [expr {!!($VAL & (1 << ($x + $y)))}] [expr {$w -1}] \"\"]\n\t}\n\techo \"\"\n    }\n}\n\n\nproc show_mmr_bitfield { MSB LSB VAL FIELDNAME FIELDVALUES } {\n    set width [expr {(($MSB - $LSB + 1) + 7) / 4}]\n    set nval [show_normalize_bitfield $VAL $MSB $LSB ]\n    set name0 [lindex $FIELDVALUES 0 ]\n    if [ string compare $name0 _NUMBER_ ] {\n\tset sval [lindex $FIELDVALUES $nval]\n    } else {\n\tset sval \"\"\n    }\n    echo [format \"%-15s: %d (0x%0*x) %s\" $FIELDNAME $nval $width $nval $sval ]\n}\n\n# Give: ADDR - address of the register.\n#       BIT - bit's number.\n\nproc get_mmr_bit { ADDR BIT } {\n\tset val [memread32 $ADDR]\n\tset bit_val [expr {$val & [expr {1 << $BIT}]}]\n\treturn $bit_val\n}\n\n\n# Give: ADDR - address of the register.\n#       MSB - MSB bit's number.\n#       LSB - LSB bit's number.\n\nproc get_mmr_bitfield { ADDR MSB LSB } {\n\tset rval [memread32 $ADDR]\n\treturn normalize_bitfield $rval $MSB $LSB\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/1986ве1т.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# 1986ВЕ1Т\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=236&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME 1986ве1т\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# use AHB-Lite SRAM for work area\n$_TARGETNAME configure -work-area-phys 0x20100000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x00000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x00000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/adsp-sc58x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Analog Devices ADSP-SC58x (ARM Cortex-A5 plus one or two SHARC+ DSPs)\n#\n\n# Evaluation boards by Analog Devices (and designs derived from them) use a\n# non-standard 10-pin 0.05\" ARM Cortex Debug Connector.  In this bastardized\n# implementation, pin 9 (GND or GNDDetect) has been usurped with JTAG /TRST.\n#\n# As a result, a standards-compliant debug pod will force /TRST active,\n# putting the processor's debug interface into reset and preventing usage.\n#\n# A connector adapter must be employed on these boards to isolate or remap\n# /TRST so that it is only asserted when intended.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ADSP-SC58x\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3BA02477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ap0.mem mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -event examine-end {\n   global _TARGETNAME\n   sc58x_enabledebug\n}\n\nproc sc58x_enabledebug {} {\n   # Enable debugging functionality by setting bits in the TAPC_DBGCTL register\n   # it is not possible to halt the target unless these bits have been set\n   ap0.mem mww 0x31131000 0xFFFF\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/aduc702x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aduc702x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n## JTAG scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# allocate the entire SRAM as working area\n$_TARGETNAME configure -work-area-phys 0x10000 -work-area-size 0x2000\n\n## flash configuration\n# only target number is needed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aduc702x 0 0 0 0 $_TARGETNAME\n\n## If you use the watchdog, the following code makes sure that the board\n## doesn't reboot when halted via JTAG.  Yes, on the older generation\n## AdUC702x, timer3 continues running even when the CPU is halted.\n\nproc watchdog_service {} {\n    global watchdog_hdl\n    mww 0xffff036c 0\n#    echo \"watchdog!!\"\n    set watchdog_hdl [after 500 watchdog_service]\n}\n\n$_TARGETNAME configure -event reset-halt-post {  watchdog_service }\n$_TARGETNAME configure -event resume-start { global watchdog_hdl; after cancel $watchdog_hdl }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/aducm360.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# This file was created using as references the stm32f1x.cfg and aduc702x.cfg\n#\nsource [find target/swj-dp.tcl]\n\n# Chip name\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME aducm360\n}\n\n# Endianness\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# Eventually, the whole SRAM of ADuCM360 will be used (8kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# SWD/JTAG speed\nadapter speed 1000\n\n##\n## Target configuration\n##\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# allocate the working area\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME aducm360 0x00 0 0 0 $_TARGETNAME\n\nadapter srst delay 100\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/allwinner_v3s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the config for an Allwinner V3/V3s (sun8iw8).\n#\n# Notes:\n# - Single core ARM Cortex-A7 with a maximum frequency of 1.2 GHz.\n# - Thumb-2 Technology\n# - Support NEON Advanced SIMD(Single Instruction Multiple Data)instruction\n#   for acceleration of media and signal processing functions\n# - Support Large Physical Address Extensions(LPAE)\n# - VFPv4 Floating Point Unit\n# - 32KB L1 Instruction cache and 32KB L1 Data cache\n# - 128KB L2 cache\n# - has some integrated DDR2 RAM.\n#\n# Pins related for debug and bootstrap:\n#   JTAG\n# JTAG_TMS\tPF0, SDC0_D1\n# JTAG_TDI\tPF1, SDC0_D0\n# JTAG_TDO\tPF3, SDC0_CMD\n# JTAG_TCK\tPF5, SDC0_D2\n#   UART\n# None of UART ports seems to be enabled by ROM.\n# UART0_TX\tPF2, SDC0_CLK\t\tPer default disabled\n# UART0_RX\tPF4, SDC0_D3 \t\tPer default disabled\n# UART1_TX\tPE21\t\t\tPer default disabled\n# UART1_RX\tPE22\t \t\tPer default disabled\n# UART2_TX\tPB0\t\t\tPer default disabled\n# UART2_RX\tPB1\t \t\tPer default disabled\n#\n# JTAG is enabled by default after power on on listed JTAG_* pins. So far the\n# boot sequence is:\n# Time\t\tAction\n# 0000ms\tPower ON\n# 0200ms\tJTAG enabled\n# 0220ms\tJTAG pins switched to SD mode\n#\n# The time frame of 20ms can be not enough to init and halt the CPU. In this\n# case I would recommend to set: \"adapter speed 15000\"\n# To get more or less precise timings, the board should provide reset pin,\n# or some bench power supply with remote function. In my case I used\n# EEZ H24005 with this command to power on and halt the target:\n# \"exec  echo \"*TRG\" > /dev/ttyACM0; sleep 220; reset halt\"\n# After this it is possible to enable JTAG mode again from boot loader or OS.\n# Following DAPs are available:\n# dap[0]->MEM-AP AHB\n# dap[1]->MEM-AP APB->CA7[0]\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME v3s\n}\n\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# No NRST or SRST is present on the SoC. Boards may provide\n# some sort of Power cycle reset for complete board or SoC.\n# For this case we provide srst_pulls_trst so the board config\n# only needs to set srst_only.\nreset_config none srst_pulls_trst\n\njtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Add Cortex A7 core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -chain-position $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/alphascale_asm9260t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME asm9260t\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x079264F3\n}\n\n# And srst_pulls_trst by chip design.\nreset_config srst_pulls_trst\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/altera_fpgasoc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Altera cyclone V SoC family, 5Cxxx\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME fpgasoc\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga\nif { [info exists FPGA_TAPID] } {\n   set _FPGA_TAPID $FPGA_TAPID\n} else {\n   set _FPGA_TAPID 0x02d020dd\n}\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -ircapture 0x01 -irmask 0x3 -expected-id $_FPGA_TAPID\n\n\n#\n# Cortex-A9 target\n#\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80110000\n# core 1  -  0x80112000\n\n# Slow speed to be sure it will work\nadapter speed 1000\n\nset _TARGETNAME1 $_CHIPNAME.cpu.0\nset _TARGETNAME2 $_CHIPNAME.cpu.1\n\n# A9 core 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80110000\n\n$_TARGETNAME1 configure -event reset-start { adapter speed 1000 }\n$_TARGETNAME1 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME1\"\n\n\n# A9 core 1\n#target create $_TARGETNAME2 cortex_a -dap $_CHIPNAME.dap \\\n#        -coreid 1 -dbgbase 0x80112000\n\n#$_TARGETNAME2 configure -event reset-start { adapter speed 1000 }\n#$_TARGETNAME2 configure -event reset-assert-post \"cycv_dbginit $_TARGETNAME2\"\n\nproc cycv_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/altera_fpgasoc_arria10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Intel (Altera) Arria10 FPGA SoC\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME arria10\n}\n\n# ARM CoreSight Debug Access Port (dap HPS)\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_TAPID\n\n# Subsidiary TAP: fpga (tap)\n# See Intel Arria 10 Handbook\n# https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/arria-10/a10_handbook.pdf\n# Intel Arria 10 GX 160  0x02ee20dd\n# Intel Arria 10 GX 220  0x02e220dd\n# Intel Arria 10 GX 270  0x02ee30dd\n# Intel Arria 10 GX 320  0x02e230dd\n# Intel Arria 10 GX 480  0x02e240dd\n# Intel Arria 10 GX 570  0x02ee50dd\n# Intel Arria 10 GX 660  0x02e250dd\n# Intel Arria 10 GX 900  0x02ee60dd\n# Intel Arria 10 GX 1150 0x02e660dd\n# Intel Arria 10 GT 900  0x02e260dd\n# Intel Arria 10 GT 1150 0x02e060dd\n# Intel Arria 10 SX 160  0x02e620dd\n# Intel Arria 10 SX 220  0x02e020dd\n# Intel Arria 10 SX 270  0x02e630dd\n# Intel Arria 10 SX 320  0x02e030dd\n# Intel Arria 10 SX 480  0x02e040dd\n# Intel Arria 10 SX 570  0x02e650dd\n# Intel Arria 10 SX 660  0x02e050dd\njtag newtap $_CHIPNAME.fpga tap -irlen 10 -expected-id 0x02ee20dd -expected-id 0x02e220dd \\\n\t-expected-id 0x02ee30dd -expected-id 0x02e230dd -expected-id 0x02e240dd \\\n\t-expected-id 0x02ee50dd -expected-id 0x02e250dd -expected-id 0x02ee60dd \\\n\t-expected-id 0x02e660dd -expected-id 0x02e260dd -expected-id 0x02e060dd \\\n\t-expected-id 0x02e620dd -expected-id 0x02e020dd -expected-id 0x02e630dd \\\n\t-expected-id 0x02e030dd -expected-id 0x02e040dd -expected-id 0x02e650dd \\\n\t-expected-id 0x02e050dd\n\nset _TARGETNAME $_CHIPNAME.cpu\n\n#\n# Cortex-A9 target\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap -coreid 0\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap -coreid 1 \\\n\t-defer-examine\ntarget smp $_TARGETNAME.0 $_TARGETNAME.1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/am335x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME am335x\n}\n\n# set the taps to be enabled by default. this can be overridden\n# by setting DEFAULT_TAPS in a separate configuration file\n# or directly on the command line.\nif { [info exists DEFAULT_TAPS] } {\n\tset _DEFAULT_TAPS \"$DEFAULT_TAPS\"\n} else {\n\tset _DEFAULT_TAPS \"$_CHIPNAME.tap\"\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 12 0\"\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# M3 DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME m3_tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m3_tap -event tap-enable \"icepick_d_tapenable $_CHIPNAME.jrc 11 0\"\ndap create $_CHIPNAME.m3_dap -chain-position $_CHIPNAME.m3_tap\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0b94402f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup {\n\tglobal _DEFAULT_TAPS\n\tenable_default_taps $_DEFAULT_TAPS\n}\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n#\n# helper function that enables all taps passed as argument\n#\nproc enable_default_taps { taps } {\n\tforeach tap $taps {\n\t\tjtag tapenable $tap\n\t}\n}\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME_2 $_CHIPNAME.m3\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.m3_dap\n\n#\n# Cortex-A8 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80001000\n\n# SRAM: 64K at 0x4030.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x4000\n\n\n# when putting the target into 'reset halt', we need to disable the watchdog as\n# it would otherwise trigger while we're in JTAG\n# FIXME: unify with target/am437x.cfg\nsource [find mem_helper.tcl]\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/am437x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/icepick.cfg]\nsource [find mem_helper.tcl]\n\n###############################################################################\n##\t\t\t\tAM437x Registers\t\t\t     ##\n###############################################################################\nset  PRCM_BASE_ADDR                  0x44df0000\nset  REVISION_PRM                    [expr       {$PRCM_BASE_ADDR     +  0x0000}]\nset  PRM_IRQSTATUS_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0004}]\nset  PRM_IRQENABLE_MPU               [expr       {$PRCM_BASE_ADDR     +  0x0008}]\nset  PRM_IRQSTATUS_M3                [expr       {$PRCM_BASE_ADDR     +  0x000c}]\nset  PRM_IRQENABLE_M3                [expr       {$PRCM_BASE_ADDR     +  0x0010}]\nset  PM_MPU_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0300}]\nset  PM_MPU_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0304}]\nset  RM_MPU_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0314}]\nset  RM_MPU_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0324}]\nset  PM_GFX_PWRSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x0400}]\nset  PM_GFX_PWRSTST                  [expr       {$PRCM_BASE_ADDR     +  0x0404}]\nset  RM_GFX_RSTCTRL                  [expr       {$PRCM_BASE_ADDR     +  0x0410}]\nset  RM_GFX_RSTST                    [expr       {$PRCM_BASE_ADDR     +  0x0414}]\nset  RM_GFX_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0424}]\nset  RM_RTC_CONTEXT                  [expr       {$PRCM_BASE_ADDR     +  0x0524}]\nset  RM_WKUP_RSTCTRL                 [expr       {$PRCM_BASE_ADDR     +  0x2010}]\nset  RM_WKUP_RSTST                   [expr       {$PRCM_BASE_ADDR     +  0x2014}]\nset  CM_L3_AON_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x2800}]\nset  CM_WKUP_DEBUGSS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2820}]\nset  CM_L3S_TSC_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2900}]\nset  CM_WKUP_ADC_TSC_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2920}]\nset  CM_L4_WKUP_AON_CLKSTCTRL        [expr       {$PRCM_BASE_ADDR     +  0x2a00}]\nset  CM_WKUP_L4WKUP_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2a20}]\nset  CM_WKUP_WKUP_M3_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a28}]\nset  CM_WKUP_SYNCTIMER_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a30}]\nset  CM_WKUP_CLKDIV32K_CLKCTRL       [expr       {$PRCM_BASE_ADDR     +  0x2a38}]\nset  CM_WKUP_USBPHY0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a40}]\nset  CM_WKUP_USBPHY1_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2a48}]\nset  CM_WKUP_CLKSTCTRL               [expr       {$PRCM_BASE_ADDR     +  0x2b00}]\nset  CM_WKUP_TIMER0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b20}]\nset  CM_WKUP_TIMER1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x2b28}]\nset  CM_WKUP_WDT0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b30}]\nset  CM_WKUP_WDT1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b38}]\nset  CM_WKUP_I2C0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x2b40}]\nset  CM_WKUP_UART0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b48}]\nset  CM_WKUP_SMARTREFLEX0_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b50}]\nset  CM_WKUP_SMARTREFLEX1_CLKCTRL    [expr       {$PRCM_BASE_ADDR     +  0x2b58}]\nset  CM_WKUP_CONTROL_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x2b60}]\nset  CM_WKUP_GPIO0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x2b68}]\nset  CM_CLKMODE_DPLL_CORE            [expr       {$PRCM_BASE_ADDR     +  0x2d20}]\nset  CM_IDLEST_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d24}]\nset  CM_CLKSEL_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d2c}]\nset  CM_DIV_M4_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d38}]\nset  CM_DIV_M5_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d3c}]\nset  CM_DIV_M6_DPLL_CORE             [expr       {$PRCM_BASE_ADDR     +  0x2d40}]\nset  CM_SSC_DELTAMSTEP_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d48}]\nset  CM_SSC_MODFREQDIV_DPLL_CORE     [expr       {$PRCM_BASE_ADDR     +  0x2d4c}]\nset  CM_CLKMODE_DPLL_MPU             [expr       {$PRCM_BASE_ADDR     +  0x2d60}]\nset  CM_IDLEST_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d64}]\nset  CM_CLKSEL_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d6c}]\nset  CM_DIV_M2_DPLL_MPU              [expr       {$PRCM_BASE_ADDR     +  0x2d70}]\nset  CM_SSC_DELTAMSTEP_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d88}]\nset  CM_SSC_MODFREQDIV_DPLL_MPU      [expr       {$PRCM_BASE_ADDR     +  0x2d8c}]\nset  CM_CLKMODE_DPLL_DDR             [expr       {$PRCM_BASE_ADDR     +  0x2da0}]\nset  CM_IDLEST_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2da4}]\nset  CM_CLKSEL_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2dac}]\nset  CM_DIV_M2_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db0}]\nset  CM_DIV_M4_DPLL_DDR              [expr       {$PRCM_BASE_ADDR     +  0x2db8}]\nset  CM_SSC_DELTAMSTEP_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dc8}]\nset  CM_SSC_MODFREQDIV_DPLL_DDR      [expr       {$PRCM_BASE_ADDR     +  0x2dcc}]\nset  CM_CLKMODE_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2de0}]\nset  CM_IDLEST_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2de4}]\nset  CM_CLKSEL_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2dec}]\nset  CM_DIV_M2_DPLL_PER              [expr       {$PRCM_BASE_ADDR     +  0x2df0}]\nset  CM_CLKSEL2_DPLL_PER             [expr       {$PRCM_BASE_ADDR     +  0x2e04}]\nset  CM_SSC_DELTAMSTEP_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e08}]\nset  CM_SSC_MODFREQDIV_DPLL_PER      [expr       {$PRCM_BASE_ADDR     +  0x2e0c}]\nset  CM_CLKDCOLDO_DPLL_PER           [expr       {$PRCM_BASE_ADDR     +  0x2e14}]\nset  CM_CLKMODE_DPLL_DISP            [expr       {$PRCM_BASE_ADDR     +  0x2e20}]\nset  CM_IDLEST_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e24}]\nset  CM_CLKSEL_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e2c}]\nset  CM_DIV_M2_DPLL_DISP             [expr       {$PRCM_BASE_ADDR     +  0x2e30}]\nset  CM_SSC_DELTAMSTEP_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e48}]\nset  CM_SSC_MODFREQDIV_DPLL_DISP     [expr       {$PRCM_BASE_ADDR     +  0x2e4c}]\nset  CM_CLKMODE_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e60}]\nset  CM_IDLEST_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e64}]\nset  CM_CLKSEL_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e6c}]\nset  CM_DIV_M2_DPLL_EXTDEV           [expr       {$PRCM_BASE_ADDR     +  0x2e70}]\nset  CM_CLKSEL2_DPLL_EXTDEV          [expr       {$PRCM_BASE_ADDR     +  0x2e84}]\nset  CM_SSC_DELTAMSTEP_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e88}]\nset  CM_SSC_MODFREQDIV_DPLL_EXTDEV   [expr       {$PRCM_BASE_ADDR     +  0x2e8c}]\nset  CM_SHADOW_FREQ_CONFIG1          [expr       {$PRCM_BASE_ADDR     +  0x2fa0}]\nset  CM_SHADOW_FREQ_CONFIG2          [expr       {$PRCM_BASE_ADDR     +  0x2fa4}]\nset  CM_CLKOUT1_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4100}]\nset  CM_DLL_CTRL                     [expr       {$PRCM_BASE_ADDR     +  0x4104}]\nset  CM_CLKOUT2_CTRL                 [expr       {$PRCM_BASE_ADDR     +  0x4108}]\nset  CLKSEL_TIMER1MS_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4200}]\nset  CLKSEL_TIMER2_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4204}]\nset  CLKSEL_TIMER3_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4208}]\nset  CLKSEL_TIMER4_CLK               [expr       {$PRCM_BASE_ADDR     +  0x420c}]\nset  CLKSEL_TIMER5_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4210}]\nset  CLKSEL_TIMER6_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4214}]\nset  CLKSEL_TIMER7_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4218}]\nset  CLKSEL_TIMER8_CLK               [expr       {$PRCM_BASE_ADDR     +  0x421c}]\nset  CLKSEL_TIMER9_CLK               [expr       {$PRCM_BASE_ADDR     +  0x4220}]\nset  CLKSEL_TIMER10_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4224}]\nset  CLKSEL_TIMER11_CLK              [expr       {$PRCM_BASE_ADDR     +  0x4228}]\nset  CLKSEL_WDT1_CLK                 [expr       {$PRCM_BASE_ADDR     +  0x422c}]\nset  CLKSEL_SYNCTIMER_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4230}]\nset  CLKSEL_MAC_CLK                  [expr       {$PRCM_BASE_ADDR     +  0x4234}]\nset  CLKSEL_CPTS_RFT_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4238}]\nset  CLKSEL_GFX_FCLK                 [expr       {$PRCM_BASE_ADDR     +  0x423c}]\nset  CLKSEL_GPIO0_DBCLK              [expr       {$PRCM_BASE_ADDR     +  0x4240}]\nset  CLKSEL_LCDC_PIXEL_CLK           [expr       {$PRCM_BASE_ADDR     +  0x4244}]\nset  CLKSEL_ICSS_OCP_CLK             [expr       {$PRCM_BASE_ADDR     +  0x4248}]\nset  CLKSEL_DLL_AGING_CLK            [expr       {$PRCM_BASE_ADDR     +  0x4250}]\nset  CLKSEL_USBPHY32KHZ_GCLK         [expr       {$PRCM_BASE_ADDR     +  0x4260}]\nset  CM_MPU_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8300}]\nset  CM_MPU_MPU_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8320}]\nset  CM_GFX_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8400}]\nset  CM_GFX_GFX_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8420}]\nset  CM_RTC_CLKSTCTRL                [expr       {$PRCM_BASE_ADDR     +  0x8500}]\nset  CM_RTC_RTC_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8520}]\nset  CM_PER_L3_CLKSTCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8800}]\nset  CM_PER_L3_CLKCTRL               [expr       {$PRCM_BASE_ADDR     +  0x8820}]\nset  CM_PER_AES0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8828}]\nset  CM_PER_DES_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8830}]\nset  CM_PER_CRYPTODMA_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8838}]\nset  CM_PER_L3_INSTR_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8840}]\nset  CM_PER_MSTR_EXPS_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8848}]\nset  CM_PER_OCMCRAM_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8850}]\nset  CM_PER_SHA0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8858}]\nset  CM_PER_SLV_EXPS_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8860}]\nset  CM_PER_VPFE0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8868}]\nset  CM_PER_VPFE1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8870}]\nset  CM_PER_TPCC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8878}]\nset  CM_PER_TPTC0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8880}]\nset  CM_PER_TPTC1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8888}]\nset  CM_PER_TPTC2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8890}]\nset  CM_PER_DLL_AGING_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8898}]\nset  CM_PER_L4HS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a0}]\nset  CM_PER_L4FW_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x88a8}]\nset  CM_PER_L3S_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8a00}]\nset  CM_PER_GPMC_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a20}]\nset  CM_PER_IEEE5000_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8a28}]\nset  CM_PER_MCASP0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a38}]\nset  CM_PER_MCASP1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8a40}]\nset  CM_PER_MMC2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a48}]\nset  CM_PER_QSPI_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8a58}]\nset  CM_PER_USB_OTG_SS0_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a60}]\nset  CM_PER_USB_OTG_SS1_CLKCTRL      [expr       {$PRCM_BASE_ADDR     +  0x8a68}]\nset  CM_PER_ICSS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8b00}]\nset  CM_PER_ICSS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8b20}]\nset  CM_PER_L4LS_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8c00}]\nset  CM_PER_L4LS_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8c20}]\nset  CM_PER_DCAN0_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c28}]\nset  CM_PER_DCAN1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c30}]\nset  CM_PER_EPWMSS0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c38}]\nset  CM_PER_EPWMSS1_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c40}]\nset  CM_PER_EPWMSS2_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c48}]\nset  CM_PER_EPWMSS3_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c50}]\nset  CM_PER_EPWMSS4_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c58}]\nset  CM_PER_EPWMSS5_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8c60}]\nset  CM_PER_ELM_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8c68}]\nset  CM_PER_GPIO1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c78}]\nset  CM_PER_GPIO2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c80}]\nset  CM_PER_GPIO3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c88}]\nset  CM_PER_GPIO4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c90}]\nset  CM_PER_GPIO5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8c98}]\nset  CM_PER_HDQ1W_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8ca0}]\nset  CM_PER_I2C1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8ca8}]\nset  CM_PER_I2C2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cb0}]\nset  CM_PER_MAILBOX0_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8cb8}]\nset  CM_PER_MMC0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc0}]\nset  CM_PER_MMC1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8cc8}]\nset  CM_PER_PKA_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8cd0}]\nset  CM_PER_RNG_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8ce0}]\nset  CM_PER_SPARE0_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8ce8}]\nset  CM_PER_SPARE1_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8cf0}]\nset  CM_PER_SPI0_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d00}]\nset  CM_PER_SPI1_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d08}]\nset  CM_PER_SPI2_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d10}]\nset  CM_PER_SPI3_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d18}]\nset  CM_PER_SPI4_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8d20}]\nset  CM_PER_SPINLOCK_CLKCTRL         [expr       {$PRCM_BASE_ADDR     +  0x8d28}]\nset  CM_PER_TIMER2_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d30}]\nset  CM_PER_TIMER3_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d38}]\nset  CM_PER_TIMER4_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d40}]\nset  CM_PER_TIMER5_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d48}]\nset  CM_PER_TIMER6_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d50}]\nset  CM_PER_TIMER7_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d58}]\nset  CM_PER_TIMER8_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d60}]\nset  CM_PER_TIMER9_CLKCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8d68}]\nset  CM_PER_TIMER10_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d70}]\nset  CM_PER_TIMER11_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8d78}]\nset  CM_PER_UART1_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d80}]\nset  CM_PER_UART2_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d88}]\nset  CM_PER_UART3_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d90}]\nset  CM_PER_UART4_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8d98}]\nset  CM_PER_UART5_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x8da0}]\nset  CM_PER_USBPHYOCP2SCP0_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8db8}]\nset  CM_PER_USBPHYOCP2SCP1_CLKCTRL   [expr       {$PRCM_BASE_ADDR     +  0x8dc0}]\nset  CM_PER_EMIF_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x8f00}]\nset  CM_PER_EMIF_CLKCTRL             [expr       {$PRCM_BASE_ADDR     +  0x8f20}]\nset  CM_PER_DLL_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x8f28}]\nset  CM_PER_EMIF_FW_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x8f30}]\nset  CM_PER_OTFA_EMIF_CLKCTRL        [expr       {$PRCM_BASE_ADDR     +  0x8f38}]\nset  CM_PER_DSS_CLKSTCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9200}]\nset  CM_PER_DSS_CLKCTRL              [expr       {$PRCM_BASE_ADDR     +  0x9220}]\nset  CM_PER_CPSW_CLKSTCTRL           [expr       {$PRCM_BASE_ADDR     +  0x9300}]\nset  CM_PER_CPGMAC0_CLKCTRL          [expr       {$PRCM_BASE_ADDR     +  0x9320}]\nset  CM_PER_OCPWP_L3_CLKSTCTRL       [expr       {$PRCM_BASE_ADDR     +  0x9400}]\nset  CM_PER_OCPWP_CLKCTRL            [expr       {$PRCM_BASE_ADDR     +  0x9420}]\n\nset  CONTROL_BASE_ADDR               0x44e10000\nset  CONTROL_STATUS                  [expr       {$CONTROL_BASE_ADDR  +  0x0040}]\nset  DEVICE_ID                       [expr       {$CONTROL_BASE_ADDR  +  0x0600}]\nset  DEV_FEATURE                     [expr       {$CONTROL_BASE_ADDR  +  0x0604}]\nset  DEV_ATTRIBUTE                   [expr       {$CONTROL_BASE_ADDR  +  0x0610}]\nset  MAC_ID0_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0630}]\nset  MAC_ID0_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x0634}]\nset  MAC_ID1_LO                      [expr       {$CONTROL_BASE_ADDR  +  0x0638}]\nset  MAC_ID1_HI                      [expr       {$CONTROL_BASE_ADDR  +  0x063c}]\nset  USB_VID_PID                     [expr       {$CONTROL_BASE_ADDR  +  0x07f4}]\nset  CONTROL_CONF_ECAP0_IN_PWM0_OUT  [expr       {$CONTROL_BASE_ADDR  +  0x0964}]\nset  CONTROL_CONF_SPI4_CS0           [expr       {$CONTROL_BASE_ADDR  +  0x0a5c}]\nset  CONTROL_CONF_SPI2_SCLK          [expr       {$CONTROL_BASE_ADDR  +  0x0a60}]\nset  CONTROL_CONF_SPI2_D0            [expr       {$CONTROL_BASE_ADDR  +  0x0a64}]\nset  CONTROL_CONF_XDMA_EVENT_INTR0   [expr       {$CONTROL_BASE_ADDR  +  0x0a70}]\nset  CONTROL_CONF_XDMA_EVENT_INTR1   [expr       {$CONTROL_BASE_ADDR  +  0x0a74}]\nset  CONTROL_CONF_GPMC_A0            [expr       {$CONTROL_BASE_ADDR  +  0x0840}]\nset  DDR_IO_CTRL                     [expr       {$CONTROL_BASE_ADDR  +  0x0e04}]\nset  VTP_CTRL_REG                    [expr       {$CONTROL_BASE_ADDR  +  0x0e0c}]\nset  VREF_CTRL                       [expr       {$CONTROL_BASE_ADDR  +  0x0e14}]\nset  DDR_CKE_CTRL                    [expr       {$CONTROL_BASE_ADDR  +  0x131c}]\nset  DDR_ADDRCTRL_IOCTRL             [expr       {$CONTROL_BASE_ADDR  +  0x1404}]\nset  DDR_ADDRCTRL_WD0_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x1408}]\nset  DDR_ADDRCTRL_WD1_IOCTRL         [expr       {$CONTROL_BASE_ADDR  +  0x140c}]\nset  DDR_DATA0_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1440}]\nset  DDR_DATA1_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1444}]\nset  DDR_DATA2_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x1448}]\nset  DDR_DATA3_IOCTRL                [expr       {$CONTROL_BASE_ADDR  +  0x144c}]\nset  EMIF_SDRAM_CONFIG_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1460}]\nset  EMIF_SDRAM_STATUS_EXT           [expr       {$CONTROL_BASE_ADDR  +  0x1464}]\n\nset  GPIO0_BASE_ADDR                 0x44e07000\nset  GPIO0_SYSCONFIG                 [expr       {$GPIO0_BASE_ADDR    +  0x0010}]\nset  GPIO0_SYSSTATUS                 [expr       {$GPIO0_BASE_ADDR    +  0x0114}]\nset  GPIO0_CTRL                      [expr       {$GPIO0_BASE_ADDR    +  0x0130}]\nset  GPIO0_OE                        [expr       {$GPIO0_BASE_ADDR    +  0x0134}]\nset  GPIO0_CLEARDATAOUT              [expr       {$GPIO0_BASE_ADDR    +  0x0190}]\nset  GPIO0_SETDATAOUT                [expr       {$GPIO0_BASE_ADDR    +  0x0194}]\n\nset  GPIO5_BASE_ADDR                 0x48322000\nset  GPIO5_SYSCONFIG                 [expr       {$GPIO5_BASE_ADDR    +  0x0010}]\nset  GPIO5_SYSSTATUS                 [expr       {$GPIO5_BASE_ADDR    +  0x0114}]\nset  GPIO5_CTRL                      [expr       {$GPIO5_BASE_ADDR    +  0x0130}]\nset  GPIO5_OE                        [expr       {$GPIO5_BASE_ADDR    +  0x0134}]\nset  GPIO5_CLEARDATAOUT              [expr       {$GPIO5_BASE_ADDR    +  0x0190}]\nset  GPIO5_SETDATAOUT                [expr       {$GPIO5_BASE_ADDR    +  0x0194}]\n\nset  GPIO1_BASE_ADDR                 0x4804c000\nset  GPIO1_SYSCONFIG                 [expr       {$GPIO1_BASE_ADDR    +  0x0010}]\nset  GPIO1_SYSSTATUS                 [expr       {$GPIO1_BASE_ADDR    +  0x0114}]\nset  GPIO1_CTRL                      [expr       {$GPIO1_BASE_ADDR    +  0x0130}]\nset  GPIO1_OE                        [expr       {$GPIO1_BASE_ADDR    +  0x0134}]\nset  GPIO1_CLEARDATAOUT              [expr       {$GPIO1_BASE_ADDR    +  0x0190}]\nset  GPIO1_SETDATAOUT                [expr       {$GPIO1_BASE_ADDR    +  0x0194}]\n\nset  EMIF_BASE_ADDR                  0x4c000000\nset  EMIF_STATUS                     [expr       {$EMIF_BASE_ADDR     +  0x0004}]\nset  EMIF_SDRAM_CONFIG               [expr       {$EMIF_BASE_ADDR     +  0x0008}]\nset  EMIF_SDRAM_CONFIG_2             [expr       {$EMIF_BASE_ADDR     +  0x000c}]\nset  EMIF_SDRAM_REF_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0010}]\nset  EMIF_SDRAM_REF_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0014}]\nset  EMIF_SDRAM_TIM_1                [expr       {$EMIF_BASE_ADDR     +  0x0018}]\nset  EMIF_SDRAM_TIM_1_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x001c}]\nset  EMIF_SDRAM_TIM_2                [expr       {$EMIF_BASE_ADDR     +  0x0020}]\nset  EMIF_SDRAM_TIM_2_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x0024}]\nset  EMIF_SDRAM_TIM_3                [expr       {$EMIF_BASE_ADDR     +  0x0028}]\nset  EMIF_SDRAM_TIM_3_SHDW           [expr       {$EMIF_BASE_ADDR     +  0x002c}]\nset  EMIF_LPDDR2_NVM_TIM             [expr       {$EMIF_BASE_ADDR     +  0x0030}]\nset  EMIF_LPDDR2_NVM_TIM_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x0034}]\nset  EMIF_PWR_MGMT_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x0038}]\nset  EMIF_PWR_MGMT_CTRL_SHDW         [expr       {$EMIF_BASE_ADDR     +  0x003c}]\nset  EMIF_LPDDR2_MODE_REG_DATA       [expr       {$EMIF_BASE_ADDR     +  0x0040}]\nset  EMIF_LPDDR2_MODE_REG_CFG        [expr       {$EMIF_BASE_ADDR     +  0x0050}]\nset  EMIF_OCP_CONFIG                 [expr       {$EMIF_BASE_ADDR     +  0x0054}]\nset  EMIF_OCP_CFG_VAL_1              [expr       {$EMIF_BASE_ADDR     +  0x0058}]\nset  EMIF_OCP_CFG_VAL_2              [expr       {$EMIF_BASE_ADDR     +  0x005c}]\nset  EMIF_IODFT_TLGC                 [expr       {$EMIF_BASE_ADDR     +  0x0060}]\nset  EMIF_IODFT_CTRL_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0064}]\nset  EMIF_IODFT_ADDR_MISR_RSLT       [expr       {$EMIF_BASE_ADDR     +  0x0068}]\nset  EMIF_IODFT_DATA_MISR_RSLT_1     [expr       {$EMIF_BASE_ADDR     +  0x006c}]\nset  EMIF_IODFT_DATA_MISR_RSLT_2     [expr       {$EMIF_BASE_ADDR     +  0x0070}]\nset  EMIF_IODFT_DATA_MISR_RSLT_3     [expr       {$EMIF_BASE_ADDR     +  0x0074}]\nset  EMIF_PERF_CNT_1                 [expr       {$EMIF_BASE_ADDR     +  0x0080}]\nset  EMIF_PERF_CNT_2                 [expr       {$EMIF_BASE_ADDR     +  0x0084}]\nset  EMIF_PERF_CNT_CFG               [expr       {$EMIF_BASE_ADDR     +  0x0088}]\nset  EMIF_PERF_CNT_SEL               [expr       {$EMIF_BASE_ADDR     +  0x008c}]\nset  EMIF_PERF_CNT_TIM               [expr       {$EMIF_BASE_ADDR     +  0x0090}]\nset  EMIF_MISC_REG                   [expr       {$EMIF_BASE_ADDR     +  0x0094}]\nset  EMIF_DLL_CALIB_CTRL             [expr       {$EMIF_BASE_ADDR     +  0x0098}]\nset  EMIF_DLL_CALIB_CTRL_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x009c}]\nset  EMIF_IRQ_EOI                    [expr       {$EMIF_BASE_ADDR     +  0x00a0}]\nset  EMIF_IRQSTATUS_RAW_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00a4}]\nset  EMIF_IRQSTATUS_SYS              [expr       {$EMIF_BASE_ADDR     +  0x00ac}]\nset  EMIF_IRQENABLE_SET_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00b4}]\nset  EMIF_IRQENABLE_CLR_SYS          [expr       {$EMIF_BASE_ADDR     +  0x00bc}]\nset  EMIF_ZQ_CONFIG                  [expr       {$EMIF_BASE_ADDR     +  0x00c8}]\nset  EMIF_TEMP_ALERT_CONFIG          [expr       {$EMIF_BASE_ADDR     +  0x00cc}]\nset  EMIF_OCP_ERR_LOG                [expr       {$EMIF_BASE_ADDR     +  0x00d0}]\nset  EMIF_RDWR_LVL_RMP_WIN           [expr       {$EMIF_BASE_ADDR     +  0x00d4}]\nset  EMIF_RDWR_LVL_RMP_CTRL          [expr       {$EMIF_BASE_ADDR     +  0x00d8}]\nset  EMIF_RDWR_LVL_CTRL              [expr       {$EMIF_BASE_ADDR     +  0x00dc}]\nset  EMIF_DDR_PHY_CTRL_1             [expr       {$EMIF_BASE_ADDR     +  0x00e4}]\nset  EMIF_DDR_PHY_CTRL_1_SHDW        [expr       {$EMIF_BASE_ADDR     +  0x00e8}]\nset  EMIF_DDR_PHY_CTRL_2             [expr       {$EMIF_BASE_ADDR     +  0x00ec}]\nset  EMIF_PRI_COS_MAP                [expr       {$EMIF_BASE_ADDR     +  0x0100}]\nset  EMIF_CONNID_COS_1_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0104}]\nset  EMIF_CONNID_COS_2_MAP           [expr       {$EMIF_BASE_ADDR     +  0x0108}]\nset  ECC_CTRL                        [expr       {$EMIF_BASE_ADDR     +  0x0110}]\nset  ECC_ADDR_RNG_1                  [expr       {$EMIF_BASE_ADDR     +  0x0114}]\nset  ECC_ADDR_RNG_2                  [expr       {$EMIF_BASE_ADDR     +  0x0118}]\nset  EMIF_RD_WR_EXEC_THRSH           [expr       {$EMIF_BASE_ADDR     +  0x0120}]\nset  COS_CONFIG                      [expr       {$EMIF_BASE_ADDR     +  0x0124}]\n\nset  PHY_STATUS_1                    [expr       {$EMIF_BASE_ADDR     +  0x0144}]\nset  PHY_STATUS_2                    [expr       {$EMIF_BASE_ADDR     +  0x0148}]\nset  PHY_STATUS_3                    [expr       {$EMIF_BASE_ADDR     +  0x014c}]\nset  PHY_STATUS_4                    [expr       {$EMIF_BASE_ADDR     +  0x0150}]\nset  PHY_STATUS_5                    [expr       {$EMIF_BASE_ADDR     +  0x0154}]\nset  PHY_STATUS_6                    [expr       {$EMIF_BASE_ADDR     +  0x0158}]\nset  PHY_STATUS_7                    [expr       {$EMIF_BASE_ADDR     +  0x015c}]\nset  PHY_STATUS_8                    [expr       {$EMIF_BASE_ADDR     +  0x0160}]\nset  PHY_STATUS_9                    [expr       {$EMIF_BASE_ADDR     +  0x0164}]\nset  PHY_STATUS_10                   [expr       {$EMIF_BASE_ADDR     +  0x0168}]\nset  PHY_STATUS_11                   [expr       {$EMIF_BASE_ADDR     +  0x016c}]\nset  PHY_STATUS_12                   [expr       {$EMIF_BASE_ADDR     +  0x0170}]\nset  PHY_STATUS_13                   [expr       {$EMIF_BASE_ADDR     +  0x0174}]\nset  PHY_STATUS_14                   [expr       {$EMIF_BASE_ADDR     +  0x0178}]\nset  PHY_STATUS_15                   [expr       {$EMIF_BASE_ADDR     +  0x017c}]\nset  PHY_STATUS_16                   [expr       {$EMIF_BASE_ADDR     +  0x0180}]\nset  PHY_STATUS_17                   [expr       {$EMIF_BASE_ADDR     +  0x0184}]\nset  PHY_STATUS_18                   [expr       {$EMIF_BASE_ADDR     +  0x0188}]\nset  PHY_STATUS_19                   [expr       {$EMIF_BASE_ADDR     +  0x018c}]\nset  PHY_STATUS_20                   [expr       {$EMIF_BASE_ADDR     +  0x0190}]\nset  PHY_STATUS_21                   [expr       {$EMIF_BASE_ADDR     +  0x0194}]\nset  PHY_STATUS_22                   [expr       {$EMIF_BASE_ADDR     +  0x0198}]\nset  PHY_STATUS_23                   [expr       {$EMIF_BASE_ADDR     +  0x019c}]\nset  PHY_STATUS_24                   [expr       {$EMIF_BASE_ADDR     +  0x01a0}]\nset  PHY_STATUS_25                   [expr       {$EMIF_BASE_ADDR     +  0x01a4}]\nset  PHY_STATUS_26                   [expr       {$EMIF_BASE_ADDR     +  0x01a8}]\nset  PHY_STATUS_27                   [expr       {$EMIF_BASE_ADDR     +  0x01ac}]\nset  PHY_STATUS_28                   [expr       {$EMIF_BASE_ADDR     +  0x01b0}]\n\nset  EXT_PHY_CTRL_1                  [expr       {$EMIF_BASE_ADDR     +  0x0200}]\nset  EXT_PHY_CTRL_1_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0204}]\nset  EXT_PHY_CTRL_2                  [expr       {$EMIF_BASE_ADDR     +  0x0208}]\nset  EXT_PHY_CTRL_2_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x020c}]\nset  EXT_PHY_CTRL_3                  [expr       {$EMIF_BASE_ADDR     +  0x0210}]\nset  EXT_PHY_CTRL_3_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0214}]\nset  EXT_PHY_CTRL_4                  [expr       {$EMIF_BASE_ADDR     +  0x0218}]\nset  EXT_PHY_CTRL_4_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x021c}]\nset  EXT_PHY_CTRL_5                  [expr       {$EMIF_BASE_ADDR     +  0x0220}]\nset  EXT_PHY_CTRL_5_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0224}]\nset  EXT_PHY_CTRL_6                  [expr       {$EMIF_BASE_ADDR     +  0x0228}]\nset  EXT_PHY_CTRL_6_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x022c}]\nset  EXT_PHY_CTRL_7                  [expr       {$EMIF_BASE_ADDR     +  0x0230}]\nset  EXT_PHY_CTRL_7_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0234}]\nset  EXT_PHY_CTRL_8                  [expr       {$EMIF_BASE_ADDR     +  0x0238}]\nset  EXT_PHY_CTRL_8_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x023c}]\nset  EXT_PHY_CTRL_9                  [expr       {$EMIF_BASE_ADDR     +  0x0240}]\nset  EXT_PHY_CTRL_9_SHDW             [expr       {$EMIF_BASE_ADDR     +  0x0244}]\nset  EXT_PHY_CTRL_10                 [expr       {$EMIF_BASE_ADDR     +  0x0248}]\nset  EXT_PHY_CTRL_10_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x024c}]\nset  EXT_PHY_CTRL_11                 [expr       {$EMIF_BASE_ADDR     +  0x0250}]\nset  EXT_PHY_CTRL_11_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0254}]\nset  EXT_PHY_CTRL_12                 [expr       {$EMIF_BASE_ADDR     +  0x0258}]\nset  EXT_PHY_CTRL_12_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x025c}]\nset  EXT_PHY_CTRL_13                 [expr       {$EMIF_BASE_ADDR     +  0x0260}]\nset  EXT_PHY_CTRL_13_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0264}]\nset  EXT_PHY_CTRL_14                 [expr       {$EMIF_BASE_ADDR     +  0x0268}]\nset  EXT_PHY_CTRL_14_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x026c}]\nset  EXT_PHY_CTRL_15                 [expr       {$EMIF_BASE_ADDR     +  0x0270}]\nset  EXT_PHY_CTRL_15_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0274}]\nset  EXT_PHY_CTRL_16                 [expr       {$EMIF_BASE_ADDR     +  0x0278}]\nset  EXT_PHY_CTRL_16_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x027c}]\nset  EXT_PHY_CTRL_17                 [expr       {$EMIF_BASE_ADDR     +  0x0280}]\nset  EXT_PHY_CTRL_17_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0284}]\nset  EXT_PHY_CTRL_18                 [expr       {$EMIF_BASE_ADDR     +  0x0288}]\nset  EXT_PHY_CTRL_18_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x028c}]\nset  EXT_PHY_CTRL_19                 [expr       {$EMIF_BASE_ADDR     +  0x0290}]\nset  EXT_PHY_CTRL_19_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0294}]\nset  EXT_PHY_CTRL_20                 [expr       {$EMIF_BASE_ADDR     +  0x0298}]\nset  EXT_PHY_CTRL_20_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x029c}]\nset  EXT_PHY_CTRL_21                 [expr       {$EMIF_BASE_ADDR     +  0x02a0}]\nset  EXT_PHY_CTRL_21_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02a4}]\nset  EXT_PHY_CTRL_22                 [expr       {$EMIF_BASE_ADDR     +  0x02a8}]\nset  EXT_PHY_CTRL_22_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ac}]\nset  EXT_PHY_CTRL_23                 [expr       {$EMIF_BASE_ADDR     +  0x02b0}]\nset  EXT_PHY_CTRL_23_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02b4}]\nset  EXT_PHY_CTRL_24                 [expr       {$EMIF_BASE_ADDR     +  0x02b8}]\nset  EXT_PHY_CTRL_24_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02bc}]\nset  EXT_PHY_CTRL_25                 [expr       {$EMIF_BASE_ADDR     +  0x02c0}]\nset  EXT_PHY_CTRL_25_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02c4}]\nset  EXT_PHY_CTRL_26                 [expr       {$EMIF_BASE_ADDR     +  0x02c8}]\nset  EXT_PHY_CTRL_26_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02cc}]\nset  EXT_PHY_CTRL_27                 [expr       {$EMIF_BASE_ADDR     +  0x02d0}]\nset  EXT_PHY_CTRL_27_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02d4}]\nset  EXT_PHY_CTRL_28                 [expr       {$EMIF_BASE_ADDR     +  0x02d8}]\nset  EXT_PHY_CTRL_28_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02dc}]\nset  EXT_PHY_CTRL_29                 [expr       {$EMIF_BASE_ADDR     +  0x02e0}]\nset  EXT_PHY_CTRL_29_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02e4}]\nset  EXT_PHY_CTRL_30                 [expr       {$EMIF_BASE_ADDR     +  0x02e8}]\nset  EXT_PHY_CTRL_30_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02ec}]\nset  EXT_PHY_CTRL_31                 [expr       {$EMIF_BASE_ADDR     +  0x02f0}]\nset  EXT_PHY_CTRL_31_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02f4}]\nset  EXT_PHY_CTRL_32                 [expr       {$EMIF_BASE_ADDR     +  0x02f8}]\nset  EXT_PHY_CTRL_32_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x02fc}]\nset  EXT_PHY_CTRL_33                 [expr       {$EMIF_BASE_ADDR     +  0x0300}]\nset  EXT_PHY_CTRL_33_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0304}]\nset  EXT_PHY_CTRL_34                 [expr       {$EMIF_BASE_ADDR     +  0x0308}]\nset  EXT_PHY_CTRL_34_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x030c}]\nset  EXT_PHY_CTRL_35                 [expr       {$EMIF_BASE_ADDR     +  0x0310}]\nset  EXT_PHY_CTRL_35_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x0314}]\nset  EXT_PHY_CTRL_36                 [expr       {$EMIF_BASE_ADDR     +  0x0318}]\nset  EXT_PHY_CTRL_36_SHDW            [expr       {$EMIF_BASE_ADDR     +  0x031c}]\n\nset  WDT1_BASE_ADDR                  0x44e35000\nset  WDT1_W_PEND_WSPR                [expr       {$WDT1_BASE_ADDR     +  0x0034}]\nset  WDT1_WSPR                       [expr       {$WDT1_BASE_ADDR     +  0x0048}]\n\nset  RTC_BASE_ADDR                   0x44e3e000\nset  RTC_KICK0R                      [expr       {$RTC_BASE_ADDR      +  0x6c}]\nset  RTC_KICK1R                      [expr       {$RTC_BASE_ADDR      +  0x70}]\n\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME am437x\n}\n\nset JRC_MODULE\t\ticepick_d\nset DEBUGSS_MODULE\tdebugss\nset M3_MODULE\t\tm3_wakeupss\n\nset JRC_NAME\t\t$_CHIPNAME.$JRC_MODULE\nset DEBUGSS_NAME\t$_CHIPNAME.$DEBUGSS_MODULE\nset M3_NAME\t\t$_CHIPNAME.$M3_MODULE\nset _TARGETNAME\t\t$_CHIPNAME.mpuss\n\n#\n# M3 WakeupSS DAP\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4b6b902f\n}\njtag newtap $_CHIPNAME $M3_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_DAP_TAPID -disable\njtag configure $M3_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 11 0\"\ndap create $M3_NAME.dap -chain-position $M3_NAME\n\n#\n# DebugSS DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x46b6902f\n}\njtag newtap $_CHIPNAME $DEBUGSS_MODULE -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $DEBUGSS_NAME -event tap-enable \"icepick_d_tapenable $JRC_NAME 12 0\"\ndap create $DEBUGSS_NAME.dap -chain-position $DEBUGSS_NAME\n\n#\n# ICEpick-D (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b98c02f\n}\njtag newtap $_CHIPNAME $JRC_MODULE -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $JRC_NAME -event setup \"jtag tapenable $DEBUGSS_NAME\"\n # some TCK tycles are required to activate the DEBUG power domain\njtag configure $JRC_NAME -event post-reset \"runtest 100\"\n\n#\n# Cortex-A9 target\n#\ntarget create $_TARGETNAME cortex_a -dap $DEBUGSS_NAME.dap -coreid 0 -dbgbase 0x80000000\n\n\n# SRAM: 256K at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x40000\n\n# Disables watchdog timer after reset otherwise board won't stay in\n# halted state.\nproc disable_watchdog { } {\n\tglobal WDT1_WSPR\n\tglobal WDT1_W_PEND_WSPR\n\tglobal _TARGETNAME\n\n\tset curstate [$_TARGETNAME curstate]\n\n\tif { [string compare $curstate halted] == 0 } {\n\t\tset WDT_DISABLE_SEQ1\t0xaaaa\n\t\tset WDT_DISABLE_SEQ2\t0x5555\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ1\n\n\t\t# Empty body to make sure this executes as fast as possible.\n\t\t# We don't want any delays here otherwise romcode might start\n\t\t# executing and end up changing state of certain IPs.\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\n\t\tmww phys $WDT1_WSPR $WDT_DISABLE_SEQ2\n\t\twhile { [expr {[mrw $WDT1_W_PEND_WSPR] & 0x10}] } { }\n\t}\n}\n\nproc ceil { x y } {\n\treturn [ expr {($x + $y - 1) / $y} ]\n}\n\nproc device_type { } {\n\tglobal CONTROL_STATUS\n\n\tset tmp [ mrw $CONTROL_STATUS ]\n\tset tmp [ expr {$tmp & 0x700} ]\n\tset tmp [ expr {$tmp >> 8} ]\n\n\treturn $tmp\n}\n\nproc get_input_clock_frequency { } {\n\tglobal CONTROL_STATUS\n\n\tif { [ device_type ] != 3 } {\n\t\terror \"Unknown device type\\n\"\n\t\treturn -1\n\t}\n\n\tset freq [ mrw $CONTROL_STATUS ]\n\tset freq [ expr {$freq & 0x00c00000} ]\n\tset freq [ expr {$freq >> 22} ]\n\n\tswitch $freq {\n\t\t0 {\n\t\t\tset CLKIN 19200000\n\t\t}\n\n\t\t1 {\n\t\t\tset CLKIN 24000000\n\t\t}\n\n\t\t2 {\n\t\t\tset CLKIN 25000000\n\t\t}\n\n\t\t3 {\n\t\t\tset CLKIN 26000000\n\t\t}\n\t}\n\n\treturn $CLKIN\n}\n\nproc mpu_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_MPU\n\tglobal CM_CLKSEL_DPLL_MPU\n\tglobal CM_DIV_M2_DPLL_MPU\n\tglobal CM_IDLEST_DPLL_MPU\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_MPU ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_MPU ]\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_MPU ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_MPU $clksel\n\n\tset div_m2 [ expr {$div_m2 & (~0x1f)} ]\n\tset div_m2 [ expr {$div_m2 | $M2} ]\n\tmww $CM_DIV_M2_DPLL_MPU $div_m2\n\n\tmww $CM_CLKMODE_DPLL_MPU 0x7\n\twhile { [ mrw $CM_IDLEST_DPLL_MPU ] != 1 } { }\n\n\techo \"MPU DPLL locked\"\n}\n\nproc core_pll_config { CLKIN N M M4 M5 M6 } {\n\tglobal CM_CLKMODE_DPLL_CORE\n\tglobal CM_CLKSEL_DPLL_CORE\n\tglobal CM_DIV_M4_DPLL_CORE\n\tglobal CM_DIV_M5_DPLL_CORE\n\tglobal CM_DIV_M6_DPLL_CORE\n\tglobal CM_IDLEST_DPLL_CORE\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_CORE ]\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_CORE $clksel\n\tmww $CM_DIV_M4_DPLL_CORE $M4\n\tmww $CM_DIV_M5_DPLL_CORE $M5\n\tmww $CM_DIV_M6_DPLL_CORE $M6\n\n\tmww $CM_CLKMODE_DPLL_CORE 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_CORE ] & 0x01) } { }\n\n\techo \"CORE DPLL locked\"\n}\n\nproc per_pll_config { CLKIN N M M2 } {\n\tglobal CM_CLKMODE_DPLL_PER\n\tglobal CM_CLKSEL_DPLL_PER\n\tglobal CM_DIV_M2_DPLL_PER\n\tglobal CM_IDLEST_DPLL_PER\n\n\tset x [ expr {$M * $CLKIN / 1000000} ]\n\tset y [ expr {($N + 1) * 250} ]\n\tset sd [ ceil $x $y ]\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_PER ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_PER ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0xff0fffff)} ]\n\tset clksel [ expr {$clksel | ($M << 0x8) | $N} ]\n\tset clksel [ expr {$clksel | ($sd << 24)} ]\n\tmww $CM_CLKSEL_DPLL_PER $clksel\n\n\tset div_m2 [ expr {0xffffff80 | $M2} ]\n\n\tmww $CM_CLKMODE_DPLL_PER 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_PER ] & 0x01) } { }\n\n\techo \"PER DPLL locked\"\n}\n\nproc ddr_pll_config { CLKIN N M M2 M4 } {\n\tglobal CM_CLKMODE_DPLL_DDR\n\tglobal CM_CLKSEL_DPLL_DDR\n\tglobal CM_DIV_M2_DPLL_DDR\n\tglobal CM_DIV_M4_DPLL_DDR\n\tglobal CM_IDLEST_DPLL_DDR\n\n\tset clksel [ mrw $CM_CLKSEL_DPLL_DDR ]\n\tset div_m2 [ mrw $CM_DIV_M2_DPLL_DDR ]\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x4\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x0100) } { }\n\n\tset clksel [ expr {$clksel & (~0x7ffff)} ]\n\tset clksel [ expr {$clksel | ($M << 8) | $N} ]\n\tmww $CM_CLKSEL_DPLL_DDR $clksel\n\n\tset div_m2 [ expr {($div_m2 & 0xffffffe0) | $M2} ]\n\tmww $CM_DIV_M2_DPLL_DDR $div_m2\n\tmww $CM_DIV_M4_DPLL_DDR $M4\n\n\tmww $CM_CLKMODE_DPLL_DDR 0x7\n\twhile { !([ mrw $CM_IDLEST_DPLL_DDR ] & 0x01) } { }\n\n\techo \"DDR DPLL Locked\"\n}\n\nproc config_opp100 { } {\n\tset CLKIN [ get_input_clock_frequency ]\n\n\tif { $CLKIN == -1 } {\n\t\treturn -1\n\t}\n\n\tswitch $CLKIN {\n\t\t24000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  25   1\n\t\t\tcore_pll_config  $CLKIN  2  125  10  8  4\n\t\t\tper_pll_config   $CLKIN  9  400  5\n\t\t\tddr_pll_config   $CLKIN  2  50   1   2\n\t\t}\n\n\t\t25000000 {\n\t\t\tmpu_pll_config   $CLKIN  0  24   1\n\t\t\tcore_pll_config  $CLKIN  0  40   10  8  4\n\t\t\tper_pll_config   $CLKIN  9  384  5\n\t\t\tddr_pll_config   $CLKIN  0  16   1   2\n\t\t}\n\n\t\t26000000 {\n\t\t\tmpu_pll_config   $CLKIN  12  300  1\n\t\t\tcore_pll_config  $CLKIN  12  500  10  8  4\n\t\t\tper_pll_config   $CLKIN  12  480  5\n\t\t\tddr_pll_config   $CLKIN  12  200  1   2\n\t\t}\n\n\t\t19200000 {\n\t\t\tmpu_pll_config   $CLKIN  3   125  1\n\t\t\tcore_pll_config  $CLKIN  11  625  10  8  4\n\t\t\tper_pll_config   $CLKIN  7   400  5\n\t\t\tddr_pll_config   $CLKIN  2   125  1   2\n\t\t}\n\t}\n}\n\nproc emif_prcm_clk_enable { } {\n\tglobal CM_PER_EMIF_FW_CLKCTRL\n\tglobal CM_PER_EMIF_CLKCTRL\n\n\tmww $CM_PER_EMIF_FW_CLKCTRL 0x02\n\tmww $CM_PER_EMIF_CLKCTRL 0x02\n\n\twhile { [ mrw $CM_PER_EMIF_CLKCTRL ] != 0x02 } { }\n}\n\nproc vtp_enable { } {\n\tglobal VTP_CTRL_REG\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x40 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] & ~0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n\tset vtp [ expr {[ mrw $VTP_CTRL_REG ] | 0x01 }]\n\tmww $VTP_CTRL_REG $vtp\n\n}\n\nproc config_ddr_ioctrl { } {\n\tglobal DDR_ADDRCTRL_IOCTRL\n\tglobal DDR_ADDRCTRL_WD0_IOCTRL\n\tglobal DDR_ADDRCTRL_WD1_IOCTRL\n\tglobal DDR_CKE_CTRL\n\tglobal DDR_DATA0_IOCTRL\n\tglobal DDR_DATA1_IOCTRL\n\tglobal DDR_DATA2_IOCTRL\n\tglobal DDR_DATA3_IOCTRL\n\tglobal DDR_IO_CTRL\n\n\tmww $DDR_ADDRCTRL_IOCTRL\t0x84\n\tmww $DDR_ADDRCTRL_WD0_IOCTRL\t0x00\n\tmww $DDR_ADDRCTRL_WD1_IOCTRL\t0x00\n\tmww $DDR_DATA0_IOCTRL\t\t0x84\n\tmww $DDR_DATA1_IOCTRL\t\t0x84\n\tmww $DDR_DATA2_IOCTRL\t\t0x84\n\tmww $DDR_DATA3_IOCTRL\t\t0x84\n\n\tmww $DDR_IO_CTRL\t\t0x00\n\tmww $DDR_CKE_CTRL\t\t0x03\n}\n\nproc config_ddr_phy { } {\n\tglobal EMIF_DDR_PHY_CTRL_1\n\tglobal EMIF_DDR_PHY_CTRL_1_SHDW\n\n\tglobal EXT_PHY_CTRL_1\n\tglobal EXT_PHY_CTRL_1_SHDW\n\tglobal EXT_PHY_CTRL_2\n\tglobal EXT_PHY_CTRL_2_SHDW\n\tglobal EXT_PHY_CTRL_3\n\tglobal EXT_PHY_CTRL_3_SHDW\n\tglobal EXT_PHY_CTRL_4\n\tglobal EXT_PHY_CTRL_4_SHDW\n\tglobal EXT_PHY_CTRL_5\n\tglobal EXT_PHY_CTRL_5_SHDW\n\tglobal EXT_PHY_CTRL_6\n\tglobal EXT_PHY_CTRL_6_SHDW\n\tglobal EXT_PHY_CTRL_7\n\tglobal EXT_PHY_CTRL_7_SHDW\n\tglobal EXT_PHY_CTRL_8\n\tglobal EXT_PHY_CTRL_8_SHDW\n\tglobal EXT_PHY_CTRL_9\n\tglobal EXT_PHY_CTRL_9_SHDW\n\tglobal EXT_PHY_CTRL_10\n\tglobal EXT_PHY_CTRL_10_SHDW\n\tglobal EXT_PHY_CTRL_11\n\tglobal EXT_PHY_CTRL_11_SHDW\n\tglobal EXT_PHY_CTRL_12\n\tglobal EXT_PHY_CTRL_12_SHDW\n\tglobal EXT_PHY_CTRL_13\n\tglobal EXT_PHY_CTRL_13_SHDW\n\tglobal EXT_PHY_CTRL_14\n\tglobal EXT_PHY_CTRL_14_SHDW\n\tglobal EXT_PHY_CTRL_15\n\tglobal EXT_PHY_CTRL_15_SHDW\n\tglobal EXT_PHY_CTRL_16\n\tglobal EXT_PHY_CTRL_16_SHDW\n\tglobal EXT_PHY_CTRL_17\n\tglobal EXT_PHY_CTRL_17_SHDW\n\tglobal EXT_PHY_CTRL_18\n\tglobal EXT_PHY_CTRL_18_SHDW\n\tglobal EXT_PHY_CTRL_19\n\tglobal EXT_PHY_CTRL_19_SHDW\n\tglobal EXT_PHY_CTRL_20\n\tglobal EXT_PHY_CTRL_20_SHDW\n\tglobal EXT_PHY_CTRL_21\n\tglobal EXT_PHY_CTRL_21_SHDW\n\tglobal EXT_PHY_CTRL_22\n\tglobal EXT_PHY_CTRL_22_SHDW\n\tglobal EXT_PHY_CTRL_23\n\tglobal EXT_PHY_CTRL_23_SHDW\n\tglobal EXT_PHY_CTRL_24\n\tglobal EXT_PHY_CTRL_24_SHDW\n\tglobal EXT_PHY_CTRL_25\n\tglobal EXT_PHY_CTRL_25_SHDW\n\tglobal EXT_PHY_CTRL_26\n\tglobal EXT_PHY_CTRL_26_SHDW\n\tglobal EXT_PHY_CTRL_27\n\tglobal EXT_PHY_CTRL_27_SHDW\n\tglobal EXT_PHY_CTRL_28\n\tglobal EXT_PHY_CTRL_28_SHDW\n\tglobal EXT_PHY_CTRL_29\n\tglobal EXT_PHY_CTRL_29_SHDW\n\tglobal EXT_PHY_CTRL_30\n\tglobal EXT_PHY_CTRL_30_SHDW\n\tglobal EXT_PHY_CTRL_31\n\tglobal EXT_PHY_CTRL_31_SHDW\n\tglobal EXT_PHY_CTRL_32\n\tglobal EXT_PHY_CTRL_32_SHDW\n\tglobal EXT_PHY_CTRL_33\n\tglobal EXT_PHY_CTRL_33_SHDW\n\tglobal EXT_PHY_CTRL_34\n\tglobal EXT_PHY_CTRL_34_SHDW\n\tglobal EXT_PHY_CTRL_35\n\tglobal EXT_PHY_CTRL_35_SHDW\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\tmww $EMIF_DDR_PHY_CTRL_1\t0x8009\n\tmww $EMIF_DDR_PHY_CTRL_1_SHDW\t0x8009\n\n\tset slave_ratio\t\t0x80\n\tset gatelvl_init_ratio\t0x20\n\tset wr_dqs_slave_delay\t0x60\n\tset rd_dqs_slave_delay\t0x60\n\tset dq_offset\t\t0x40\n\tset gatelvl_init_mode\t0x01\n\tset wr_data_slave_delay\t0x80\n\tset gatelvl_num_dq0 0x0f\n\tset wrlvl_num_dq0 0x0f\n\n\tmww $EXT_PHY_CTRL_1        [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_1_SHDW   [ expr {($slave_ratio << 20) | ($slave_ratio << 10) | $slave_ratio} ]\n\tmww $EXT_PHY_CTRL_26       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_26_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_27_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_28_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_29_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30       [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_30_SHDW  [ expr {($gatelvl_init_ratio << 16) | $gatelvl_init_ratio} ]\n\tmww $EXT_PHY_CTRL_31       0x00\n\tmww $EXT_PHY_CTRL_31_SHDW  0x00\n\tmww $EXT_PHY_CTRL_32       0x00\n\tmww $EXT_PHY_CTRL_32_SHDW  0x00\n\tmww $EXT_PHY_CTRL_33       0x00\n\tmww $EXT_PHY_CTRL_33_SHDW  0x00\n\tmww $EXT_PHY_CTRL_34       0x00\n\tmww $EXT_PHY_CTRL_34_SHDW  0x00\n\tmww $EXT_PHY_CTRL_35       0x00\n\tmww $EXT_PHY_CTRL_35_SHDW  0x00\n\tmww $EXT_PHY_CTRL_22       0x00\n\tmww $EXT_PHY_CTRL_22_SHDW  0x00\n\tmww $EXT_PHY_CTRL_23       [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_23_SHDW  [ expr {($wr_dqs_slave_delay  <<  16) | $rd_dqs_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24       [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay} ]\n\tmww $EXT_PHY_CTRL_24_SHDW  [ expr {($dq_offset << 24) | ($gatelvl_init_mode << 16) | $wr_data_slave_delay << 0} ]\n\tmww $EXT_PHY_CTRL_25       [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_25_SHDW  [ expr {($dq_offset << 21) | ($dq_offset << 14) | ($dq_offset << 7) | $dq_offset} ]\n\tmww $EXT_PHY_CTRL_36       [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n\tmww $EXT_PHY_CTRL_36_SHDW  [ expr {($wrlvl_num_dq0 << 4) | $gatelvl_num_dq0} ]\n}\n\nproc config_ddr_timing { } {\n\tglobal EMIF_SDRAM_TIM_1\n\tglobal EMIF_SDRAM_TIM_2\n\tglobal EMIF_SDRAM_TIM_3\n\tglobal EMIF_SDRAM_TIM_1_SHDW\n\tglobal EMIF_SDRAM_TIM_2_SHDW\n\tglobal EMIF_SDRAM_TIM_3_SHDW\n\tglobal EMIF_ZQ_CONFIG\n\n\tmww $EMIF_SDRAM_TIM_1\t\t0xeaaad4db\n\tmww $EMIF_SDRAM_TIM_1_SHDW\t0xeaaad4db\n\n\tmww $EMIF_SDRAM_TIM_2\t\t0x266b7fda\n\tmww $EMIF_SDRAM_TIM_2_SHDW\t0x266b7fda\n\n\tmww $EMIF_SDRAM_TIM_3\t\t0x107f8678\n\tmww $EMIF_SDRAM_TIM_3_SHDW\t0x107f8678\n\n\tmww $EMIF_ZQ_CONFIG\t\t0x50074be4\n}\n\nproc config_ddr_pm { } {\n\tglobal EMIF_PWR_MGMT_CTRL\n\tglobal EMIF_PWR_MGMT_CTRL_SHDW\n\tglobal EMIF_DLL_CALIB_CTRL\n\tglobal EMIF_DLL_CALIB_CTRL_SHDW\n\tglobal EMIF_TEMP_ALERT_CONFIG\n\n\tmww $EMIF_PWR_MGMT_CTRL\t\t0x00\n\tmww $EMIF_PWR_MGMT_CTRL_SHDW\t0x00\n\tmww $EMIF_DLL_CALIB_CTRL\t0x00050000\n\tmww $EMIF_DLL_CALIB_CTRL_SHDW\t0x00050000\n\tmww $EMIF_TEMP_ALERT_CONFIG\t0x00\n}\n\nproc config_ddr_priority { } {\n\tglobal EMIF_PRI_COS_MAP\n\tglobal EMIF_CONNID_COS_1_MAP\n\tglobal EMIF_CONNID_COS_2_MAP\n\tglobal EMIF_RD_WR_EXEC_THRSH\n\tglobal COS_CONFIG\n\n\tmww $EMIF_PRI_COS_MAP       0x00\n\tmww $EMIF_CONNID_COS_1_MAP  0x00\n\tmww $EMIF_CONNID_COS_2_MAP  0x0\n\tmww $EMIF_RD_WR_EXEC_THRSH  0x0405\n\tmww $COS_CONFIG             0x00ffffff\n}\n\nproc config_ddr3 { SDRAM_CONFIG } {\n\tglobal CM_DLL_CTRL\n\tglobal EMIF_IODFT_TLGC\n\tglobal EMIF_RDWR_LVL_CTRL\n\tglobal EMIF_RDWR_LVL_RMP_CTRL\n\tglobal EMIF_SDRAM_CONFIG\n\tglobal EMIF_SDRAM_CONFIG_EXT\n\tglobal EMIF_SDRAM_REF_CTRL\n\tglobal EMIF_SDRAM_REF_CTRL_SHDW\n\tglobal EMIF_STATUS\n\tglobal EXT_PHY_CTRL_36\n\tglobal EXT_PHY_CTRL_36_SHDW\n\n\temif_prcm_clk_enable\n\tvtp_enable\n\n\tset dll [ expr {[ mrw $CM_DLL_CTRL ] & ~0x01 }]\n\tmww $CM_DLL_CTRL $dll\n\twhile { !([ mrw $CM_DLL_CTRL ] & 0x04) } { }\n\n\tconfig_ddr_ioctrl\n\n\tmww $EMIF_SDRAM_CONFIG_EXT\t0xc163\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_SDRAM_REF_CTRL\t0x80003000\n\n\tconfig_ddr_phy\n\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\tmww $EMIF_IODFT_TLGC\t\t0x2411\n\tmww $EMIF_IODFT_TLGC\t\t0x2011\n\n\tconfig_ddr_timing\n\tconfig_ddr_pm\n\tconfig_ddr_priority\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x3000\n\tmww $EMIF_SDRAM_CONFIG\t\t$SDRAM_CONFIG\n\n\tmww $EMIF_SDRAM_REF_CTRL\t0x0c30\n\tmww $EMIF_SDRAM_REF_CTRL_SHDW\t0x0c30\n\n\tsleep 10\n\n\tset tmp [ expr {[ mrw $EXT_PHY_CTRL_36 ] | 0x0100 }]\n\tmww $EXT_PHY_CTRL_36\t\t$tmp\n\tmww $EXT_PHY_CTRL_36_SHDW\t$tmp\n\n\tmww $EMIF_RDWR_LVL_RMP_CTRL\t0x80000000\n\tmww $EMIF_RDWR_LVL_CTRL\t\t0x80000000\n\n\twhile { [ mrw $EMIF_RDWR_LVL_CTRL ] & 0x80000000 } { }\n\n\tif { [ mrw $EMIF_STATUS ]  & 0x70 } {\n\t\terror \"DDR3 Hardware Leveling incomplete!!!\"\n\t}\n}\n\nproc init_platform { SDRAM_CONFIG } {\n\tconfig_opp100\n\tconfig_ddr3 $SDRAM_CONFIG\n}\n\n$_TARGETNAME configure -event reset-init { init_platform 0x61a013b2 }\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/amdm37x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright (C)   2010-2011   by Karl Kurbjun\n# Copyright (C)   2009-2011   by Øyvind Harboe\n# Copyright (C)   2009        by David Brownell\n# Copyright (C)   2009        by Magnus Lundin\n#\n# TI AM/DM37x Technical Reference Manual (Version R)\n#  http://www.ti.com/lit/ug/sprugn4r/sprugn4r.pdf\n#\n# This script is based on the AM3517 initialization.  It should be considered\n# preliminary since it needs more complete testing and only the basic\n# operations work.\n#\n\n###############################################################################\n# User modifiable parameters\n###############################################################################\n\n# This script uses the variable CHIPTYPE to determine whether this is an AM35x\n# or DM37x target. If CHIPTYPE is not set it will error out.\nif { [info exists CHIPTYPE] } {\n\n   if { [info exists CHIPNAME] } {\n      set _CHIPNAME $CHIPNAME\n   } else {\n      set _CHIPNAME $CHIPTYPE\n   }\n\n   switch $CHIPTYPE {\n      dm37x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x2b89102f -expected-id 0x1b89102f -expected-id 0x0b89102f\"\n      }\n      am35x {\n         # Primary TAP: ICEPick-C (JTAG route controller) and boundary scan\n         set _JRC_TAPID \"-expected-id 0x0b7ae02f -expected-id 0x0b86802f\"\n      }\n      default {\n         error \"ERROR: CHIPTYPE was set, but it was not set to a valid value.  Acceptable values are \\\"dm37x\\\" or \\\"am35x\\\".\"\n      }\n   }\n} else {\n  error \"ERROR: CHIPTYPE was not defined. Please set CHIPTYPE to \\\"am35x\\\" for the AM35x or \\\"dm37x\\\" for the DM37x series in the board configuration.\"\n}\n\n# Run the adapter at the fastest acceptable speed with the slowest possible\n# core clock.\nadapter speed 10\n\n###############################################################################\n# JTAG setup\n# The OpenOCD commands are described in the TAP Declaration section\n#  http://openocd.org/doc/html/TAP-Declaration.html\n###############################################################################\n\n# The AM/DM37x has an ICEPick module in it like many of TI's other devices. More\n#  can be read about this module in sprugn4r in chapter 27:  \"Debug and\n#  Emulation\".  The module is used to route the JTAG chain to the various\n#  subsystems in the chip.\nsource [find target/icepick.cfg]\n\n# The TAP order should be described from the TDO connection in OpenOCD to the\n#  TDI pin.  The OpenOCD FAQ describes this in more detail:\n#  http://openocd.org/doc/html/FAQ.html\n\n# From SPRUGN4R CH27 the available secondary TAPs are in this order from TDO:\n#\n#  Device   |  TAP number\n#  ---------|------------\n#  DAP      |  3\n#  Sequencer|  2   Note: The sequencer is an ARM968\n#  DSP      |  1\n#  D2D      |  0\n#\n# Right now the only secondary tap enabled is the DAP so the rest are left\n# undescribed.\n\n######\n# Start of Chain Description\n# The Secondary TAPs all have enable functions defined for use with the ICEPick\n# Only the DAP is enabled.  The AM37xx does not have the Sequencer or DSP but\n# the TAP numbers for ICEPick do not change.\n#\n# TODO: A disable function should also be added.\n######\n\n# Secondary TAP: DAP is closest to the TDO output\n# The TAP enable event also needs to be described\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# These taps are only present in the DM37x series.\nif { $CHIPTYPE == \"dm37x\" } {\n   # Secondary TAP: Sequencer (ARM968) it is not in the chain by default\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME arm2 -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\n   jtag configure $_CHIPNAME.arm2 -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n   # Secondary TAP: C64x+ DSP - it is not in the chain by default (-disable)\n   # The ICEPick can be used to enable it in the chain.\n   jtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n   jtag configure $_CHIPNAME.dsp -event tap-enable \\\n      \"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n}\n\n# Secondary TAP: D2D it is not in the chain by default (-disable)\n# The ICEPick can be used to enable it in the chain.\n# This IRLEN is probably incorrect - not sure where the documentation is.\njtag newtap $_CHIPNAME d2d -irlen 4 -ircapture 0x1 -irmask 0x0f -disable\njtag configure $_CHIPNAME.d2d -event tap-enable \\\n   \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEPick - it is closest to TDI so last in the chain\neval \"jtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f $_JRC_TAPID\"\n\n######\n# End of Chain Description\n######\n\n######\n# Start JTAG TAP events\n######\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# Enable the DAP TAP\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\n######\n# End JTAG TAP events\n######\n\n###############################################################################\n# Target Setup:\n# This section is described in the OpenOCD documentation under CPU Configuration\n#  http://openocd.org/doc/html/CPU-Configuration.html\n###############################################################################\n\n# Create the CPU target to be used with GDB:  Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# The DM37x has 64K of SRAM starting at address 0x4020_0000.  Allow the first\n# 16K to be used as a scratchpad for OpenOCD.\n\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n######\n# Start Target Reset Event Setup:\n######\n\n# Set the JTAG clock down to 10 kHz to be sure that it will work with the\n#  slowest possible core clock (16.8MHz/2 = 8.4MHz). It is OK to speed up\n#  *after* PLL and clock tree setup.\n\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 10 }\n\n# Describe the reset assert process for openocd - this is asserted with the\n# ICEPick\n$_TARGETNAME configure -event \"reset-assert\" {\n\n   global _CHIPNAME\n\n   # assert warm system reset through ICEPick\n   icepick_c_wreset $_CHIPNAME.jrc\n}\n\n# After the reset is asserted we need to re-initialize debugging and speed up\n# the JTAG clock.\n\n$_TARGETNAME configure -event reset-assert-post {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n   adapter speed 1000\n}\n\n$_TARGETNAME configure -event gdb-attach {\n\n   global _TARGETNAME\n   amdm37x_dbginit $_TARGETNAME\n\n   echo \"Halting target\"\n   halt\n}\n\n######\n# End Target Reset Event Setup:\n######\n\n###############################################################################\n# Target Functions\n# Add any functions needed for the target here\n###############################################################################\n\n# Run this to enable invasive debugging.  This is run automatically in the\n# reset sequence.\nproc amdm37x_dbginit {target} {\n   # General Cortex-A8 debug initialisation\n   cortex_a dbginit\n\n   # Enable DBGEN signal.  This signal is described in the ARM v7 TRM, but\n   # access to the signal appears to be implementation specific.  TI does not\n   # describe this register much except a quick line that states DBGEM (sic) is\n   # at this address and this bit.\n   $target mww phys 0x5401d030 0x00002000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ampere_emag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# OpenOCD Target Configuration for eMAG ARMv8 Processor\n#\n# Copyright (c) 2019-2021, Ampere Computing LLC\n#\n\n#\n# Configure defaults for target\n# Can be overriden in board configuration file\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME emag\n}\n\nif { [info exists NUMCORES] } {\n\tset _NUMCORES $NUMCORES\n} else {\n\tset _NUMCORES 32\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID ] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4BA00477\n}\n\n#\n# Configure JTAG TAP\n#\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID\nset _TAPNAME $_CHIPNAME.cpu\n\nset _DAPNAME ${_TAPNAME}_dap\nset _APNUM 1\ndap create $_DAPNAME -chain-position $_TAPNAME\n$_DAPNAME apsel $_APNUM\n\n# Create the DAP AP0 MEM-AP AHB-AP target\ntarget create AHB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 0\n\n# Create the DAP AP1 MEM-AP APB-AP target\ntarget create APB mem_ap -endian $_ENDIAN -dap $_DAPNAME -ap-num 1\n\n#\n# Configure target CPUs\n#\n\n# Build string used to enable smp mode\nset _SMP_STR \"target smp\"\n\nfor {set _i 0} {$_i < $_NUMCORES} {incr _i} {\n\t# Format a string to reference which CPU target to use\n\tset _TARGETNAME [format \"${_TAPNAME}_%02d\" $_i]\n\n\t# Create and configure Cross Trigger Interface (CTI) - required for halt and resume\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $_DAPNAME -ap-num $_APNUM -baseaddr [expr {0xFC020000 + ($_i << 20)}]\n\n\t# Create the target\n\ttarget create $_TARGETNAME aarch64 -endian $_ENDIAN -dap $_DAPNAME -ap-num $_APNUM -cti $_CTINAME -coreid $_i\n\tset _SMP_STR \"$_SMP_STR $_TARGETNAME\"\n\n\t# Clear CTI output/input enables that are not configured by OpenOCD for aarch64\n\t$_TARGETNAME configure -event examine-start [subst {\n\t\t$_CTINAME write INEN0 0x00000000\n\t\t$_CTINAME write INEN1 0x00000000\n\t\t$_CTINAME write INEN2 0x00000000\n\t\t$_CTINAME write INEN3 0x00000000\n\t\t$_CTINAME write INEN4 0x00000000\n\t\t$_CTINAME write INEN5 0x00000000\n\t\t$_CTINAME write INEN6 0x00000000\n\t\t$_CTINAME write INEN7 0x00000000\n\t\t$_CTINAME write INEN8 0x00000000\n\n\t\t$_CTINAME write OUTEN2 0x00000000\n\t\t$_CTINAME write OUTEN3 0x00000000\n\t\t$_CTINAME write OUTEN4 0x00000000\n\t\t$_CTINAME write OUTEN5 0x00000000\n\t\t$_CTINAME write OUTEN6 0x00000000\n\t\t$_CTINAME write OUTEN7 0x00000000\n\t\t$_CTINAME write OUTEN8 0x00000000\n\t}]\n\n\t# Enable OpenOCD HWTHREAD RTOS feature for GDB thread (CPU) selection support\n\t# This feature presents CPU cores (\"hardware threads\") in an SMP system as threads to GDB\n\t$_TARGETNAME configure -rtos hwthread\n}\neval $_SMP_STR\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ampere_qs_mq.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# OpenOCD Target Configuration for Ampere Altra (\"Quicksilver\") and\n# Ampere Altra Max (\"Mystique\") processors\n#\n# Copyright (c) 2019-2022, Ampere Computing LLC\n\n# Command Line Argument Description\n#\n# SPLITSMP\n# Only used for dual socket systems. Do not use for a single socket setup.\n# Option pertains to the ARMv8 target core naming in a dual socket setup.\n# If specified, name all ARMv8 cores per socket as individual SMP sessions.\n# If not specified, name ARMv8 cores from both sockets as one SMP session.\n# This option is used in conjunction with the SMP_STR board file option.\n# Syntax: -c \"set SPLITSMP {}\"\n#\n# PHYS_IDX\n# Enable OpenOCD ARMv8 core target physical indexing.\n# If not specified, defaults to OpenOCD ARMv8 core target logical indexing.\n# Syntax: -c \"set PHYS_IDX {}\"\n#\n# CHIPNAME\n# Specifies the name of the chip.\n# Will typically be either qs, qs0, qs1, mq, mq0 or mq1.\n# If not specified, defaults to qs.\n# Syntax: -c \"set CHIPNAME {qs}\"\n#\n# SYSNAME\n# Specifies the name of the system.\n# Will typically be either qs or mq.\n# If not specified, defaults to qs.\n# Syntax: -c \"set SYSNAME {qs}\"\n#\n# Life-Cycle State (LCS)\n# If not specified, defaults to \"Secure LCS\".\n# LCS=0, \"Secure LCS\"\n# LCS=1, \"Chip Manufacturing LCS\"\n# Syntax: -c \"set LCS {0}\"\n# Syntax: -c \"set LCS {1}\"\n#\n# CORELIST\n# Specify available physical cores by number.\n# Example syntax to connect to physical cores 16 and 17.\n# Syntax: -c \"set CORELIST {16 17}\"\n#\n# COREMASK_LO\n# Specify available physical cores 0-63 by mask.\n# Example syntax to connect to physical cores 16 and 17.\n# Syntax: -c \"set COREMASK_LO {0x0000000000030000}\"\n#\n# COREMASK_HI\n# Specify available physical cores 64 and above by mask.\n# Example syntax to connect to physical cores 94 and 95.\n# Syntax: -c \"set COREMASK_HI {0x00000000C0000000}\"\n#\n# ARMV8_TAPID\n# Can override the ARMV8 TAPID default value if necessary.\n# Experimental Use. Most users will not use this option.\n# Syntax: -c \"set ARMV8_TAPID {0x3BA06477}\"\n#\n# SMPMPRO_TAPID\n# Can override the SMPMPRO TAPID default value if necessary.\n# Experimental Use. Most users will not use this option.\n# Syntax: -c \"set SMPMPRO_TAPID {0x4BA00477}\"\n#\n#\n# Board File Argument Description\n# These optional arguments are defined in the board file and\n# referenced by the target file. See the corresponding board\n# files for examples of their use.\n#\n# SMP_STR\n# This option is used primarily for a dual socket system and it is not\n# recommended for a single socket setup. This option configures whether\n# the SMP ARMv8 core grouping is maintained at the board or target cfg level.\n# Specify the option if the SMP core grouping is defined at the board level.\n# Do not specify if the SMP core grouping is defined at the chip level.\n# If not specified, defaults to SMP core grouping defined per socket.\n# If specified, \"SMP_STR=target smp\", the SMP core grouping is maintained\n# at the board cfg level.\n# Used in conjunction with the SPLITSMP option to group two chips into\n# a single SMP configuration or maintain as two separate SMP sessions.\n#\n# CORE_INDEX_OFFSET\n# Specifies the starting logical core index value.\n# Used for dual-socket systems.\n# For socket #0, set to 0.\n# For socket #1, set the starting logical core based from\n# the last logical core on socket #0.\n# If not specified, defaults to 0.\n#\n\n#\n# Configure defaults for target.\n# Can be overridden in board configuration file.\n#\n\nif { [info exists SMP_STR] } {\n\t# SMP configured at the dual socket board level\n\tset _SMP_STR $SMP_STR\n} else {\n\t# SMP configured at the single socket target level\n\tset _SMP_STR \"target smp\"\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME qs\n}\n\nif { [info exists SYSNAME] } {\n\tset _SYSNAME $SYSNAME\n} else {\n\tset _SYSNAME qs\n}\n\nif { [info exists CORE_INDEX_OFFSET] } {\n\tset _CORE_INDEX_OFFSET $CORE_INDEX_OFFSET\n} else {\n\tset _CORE_INDEX_OFFSET 0\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists ARMV8_TAPID] } {\n\tset _ARMV8_TAPID $ARMV8_TAPID\n} else {\n\tif { [info exists MQ_ENABLE] } {\n\t\t# Configure for Mystique\n\t\tset _ARMV8_TAPID 0x3BA06477\n\t\tset _MAX_CORE 128\n\t} else {\n\t\t# Configure for Quicksilver\n\t\tset _ARMV8_TAPID 0x2BA06477\n\t\tset _MAX_CORE 80\n\t}\n}\n\nif { [info exists SMPMPRO_TAPID] } {\n\tset _SMPMPRO_TAPID $SMPMPRO_TAPID\n} else {\n\tset _SMPMPRO_TAPID 0x4BA00477\n}\n\nif { [info exists CORELIST] } {\n\tset _CORELIST $CORELIST\n} else {\n\tif { [info exists COREMASK_LO] } {\n\t\tset _COREMASK_LO $COREMASK_LO\n\t} else {\n\t\tset _COREMASK_LO 0x0\n\t}\n\n\tif { [info exists COREMASK_HI] } {\n\t\tset _COREMASK_HI $COREMASK_HI\n\t} else {\n\t\tset _COREMASK_HI 0x0\n\t}\n\n\tset _CORELIST {}\n\n\tset _MASK 0x1\n\tfor {set i 0} {$i < 64} {incr i} {\n\t\tif { [expr {$_COREMASK_LO & $_MASK}] != 0x0 } {\n\t\t\tset _CORELIST \"$_CORELIST $i\"\n\t\t}\n\t\tset _MASK [expr {$_MASK << 0x1}]\n\t}\n\n\tset _MASK 0x1\n\tfor {} {$i < $_MAX_CORE} {incr i} {\n\t\tif { [expr {$_COREMASK_HI & $_MASK}] != 0x0 } {\n\t\t\tset _CORELIST \"$_CORELIST $i\"\n\t\t}\n\t\tset _MASK [expr {$_MASK << 0x1}]\n\t}\n}\n\n#\n# Definition of target names\n#\nset _TARGETNAME_PMPRO pmpro\nset _TARGETNAME_SMPRO smpro\nset _TARGETNAME_ARMV8 armv8\n\n#\n# Configure JTAG TAPs - TAP chain declaration order is important\n#\n\njtag newtap $_CHIPNAME pmpro.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_SMPMPRO_TAPID\nset _TAPNAME_PMPRO $_CHIPNAME.$_TARGETNAME_PMPRO.tap\n\njtag newtap $_CHIPNAME smpro.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_SMPMPRO_TAPID\nset _TAPNAME_SMPRO $_CHIPNAME.$_TARGETNAME_SMPRO.tap\n\njtag newtap $_CHIPNAME armv8.tap -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_ARMV8_TAPID\nset _TAPNAME_ARMV8 $_CHIPNAME.$_TARGETNAME_ARMV8.tap\n\nset _DAPNAME_PMPRO $_CHIPNAME.$_TARGETNAME_PMPRO.dap\nset _DAPNAME_SMPRO $_CHIPNAME.$_TARGETNAME_SMPRO.dap\nset _DAPNAME_ARMV8 $_CHIPNAME.$_TARGETNAME_ARMV8.dap\n\nset _AP_PMPRO_AHB 0\nset _AP_SMPRO_AHB 0\nset _AP_ARMV8_APB 0x00010000\nset _AP_ARMV8_AXI 0x00020000\n\n#\n# Configure JTAG DAPs\n#\n\ndap create $_DAPNAME_PMPRO -chain-position $_TAPNAME_PMPRO -adiv5\ndap create $_DAPNAME_SMPRO -chain-position $_TAPNAME_SMPRO -adiv5\ndap create $_DAPNAME_ARMV8 -chain-position $_TAPNAME_ARMV8 -adiv6\n\nif { [info exists LCS] && [expr {\"$LCS\"!=\"0\"}] } {\n\t#\n\t# Create the DAP AHB-AP MEM-AP target for the PMPRO CPU\n\t#\n\n\ttarget create $_CHIPNAME.$_TARGETNAME_PMPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_PMPRO -ap-num $_AP_PMPRO_AHB\n\n\t#\n\t# Configure target PMPRO CPU\n\t#\n\n\ttarget create $_CHIPNAME.$_TARGETNAME_PMPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_PMPRO -ap-num $_AP_PMPRO_AHB\n\n\t#\n\t# Create the DAP AHB-AP MEM-AP target for the SMPRO CPU\n\t#\n\n\ttarget create $_CHIPNAME.$_TARGETNAME_SMPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_SMPRO -ap-num $_AP_SMPRO_AHB\n\n\t#\n\t# Configure target SMPRO CPU\n\t#\n\n\ttarget create $_CHIPNAME.$_TARGETNAME_SMPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_SMPRO -ap-num $_AP_SMPRO_AHB\n}\n\n# Create the DAP APB-AP MEM-AP target for the ARMV8 cores\ntarget create $_CHIPNAME.$_TARGETNAME_ARMV8.apb mem_ap -endian $_ENDIAN -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB\n\n# Create the DAP AXI-AP MEM-AP target for the ARMV8 cores\ntarget create $_CHIPNAME.$_TARGETNAME_ARMV8.axi mem_ap -endian $_ENDIAN -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_AXI\n\n# Set CSW register value default correctly for AXI accessible device memory:\n# Select the correct Access Port Number\n$_DAPNAME_ARMV8 apsel $_AP_ARMV8_AXI\n# First set the CSW to OpenOCD's internal default\n$_DAPNAME_ARMV8 apcsw default\n# Set Domain[1:0]=b'11  (CSW[14:13]=b'11)\n# Set Cache[3:0]=b'0000 (CSW[27:24]=b'0000)\n# Porter Cfg registers require secure access, AxPROT[1] (CSW[29]) must be b'0'.\n# Set AxPROT[2:0]=b'000 (CSW[30:28]=b'000) for an Unpriveleged, Secure, Data access.\n$_DAPNAME_ARMV8 apcsw 0x00006000 0x7F006000\n\n#\n# Configure target CPUs\n#\n\nset logical_index $_CORE_INDEX_OFFSET\n\nforeach physical_index $_CORELIST {\n\tif { [info exists PHYS_IDX] } {\n\t\tset logical_index [expr {$physical_index + $_CORE_INDEX_OFFSET}]\n\t}\n\n\t# Format a string to reference which CPU target to use\n\tif { [info exists SPLITSMP] } {\n\t\teval \"set _TARGETNAME $_CHIPNAME.${_TARGETNAME_ARMV8}_$logical_index\"\n\t} else {\n\t\teval \"set _TARGETNAME $_SYSNAME.${_TARGETNAME_ARMV8}_$logical_index\"\n\t}\n\n\t# Create and configure Cross Trigger Interface (CTI) - required for halt and resume\n\tset _CTINAME $_TARGETNAME.cti\n\tset _offset [expr {(0x00100000 * $physical_index) + (0x00200000 * ($physical_index>>1))}]\n\tcti create $_CTINAME -dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB -baseaddr [expr {0xA0220000 + $_offset}]\n\n\t# Create the target\n\ttarget create $_TARGETNAME aarch64 -endian $_ENDIAN \\\n\t\t-dap $_DAPNAME_ARMV8 -ap-num $_AP_ARMV8_APB -dbgbase [expr {0xA0210000 + $_offset}] \\\n\t\t-rtos hwthread -cti $_CTINAME -coreid $logical_index\n\n\t# Build string used to enable SMP mode for the ARMv8 CPU cores\n\tset _SMP_STR \"$_SMP_STR $_TARGETNAME\"\n\n\t# Clear CTI output/input enables that are not configured by OpenOCD for aarch64\n\t$_TARGETNAME configure -event reset-init [subst {\n\t\t$_CTINAME write INEN0 0x00000000\n\t\t$_CTINAME write INEN1 0x00000000\n\t\t$_CTINAME write INEN2 0x00000000\n\t\t$_CTINAME write INEN3 0x00000000\n\t\t$_CTINAME write INEN4 0x00000000\n\t\t$_CTINAME write INEN5 0x00000000\n\t\t$_CTINAME write INEN6 0x00000000\n\t\t$_CTINAME write INEN7 0x00000000\n\t\t$_CTINAME write INEN8 0x00000000\n\n\t\t$_CTINAME write OUTEN0 0x00000000\n\t\t$_CTINAME write OUTEN1 0x00000000\n\t\t$_CTINAME write OUTEN2 0x00000000\n\t\t$_CTINAME write OUTEN3 0x00000000\n\t\t$_CTINAME write OUTEN4 0x00000000\n\t\t$_CTINAME write OUTEN5 0x00000000\n\t\t$_CTINAME write OUTEN6 0x00000000\n\t\t$_CTINAME write OUTEN7 0x00000000\n\t\t$_CTINAME write OUTEN8 0x00000000\n\t}]\n\n\tincr logical_index\n}\n\nif { [info exists SMP_STR] } {\n\t# Return updated SMP configuration string back to board level\n\tset SMP_STR $_SMP_STR\n} else {\n\t# For single socket per SMP configuration, evaluate the string\n\teval $_SMP_STR\n}\n\nif { [info exists CORE_INDEX_OFFSET] } {\n\t# For multi-socket, return total number of cores back to board level\n\tset CORE_INDEX_OFFSET $logical_index\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ar71xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Atheros AR71xx MIPS 24Kc SoC.\n# tested on PB44 refererence board\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst\n\nset CHIPNAME ar71xx\n\njtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1\n\nset _TARGETNAME $CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-halt-post {\n\t#setup PLL to lowest common denominator 300/300/150 setting\n\tmww 0xb8050000 0x000f40a3\t;# reset val + CPU:3 DDR:3 AHB:0\n\tmww 0xb8050000 0x800f40a3\t;# send to PLL\n\n\t#next command will reset for PLL changes to take effect\n\tmww 0xb8050008 3\t\t;# set reset_switch and clock_switch (resets SoC)\n}\n\n$_TARGETNAME configure -event reset-init {\n\t#complete pll initialization\n\tmww 0xb8050000 0x800f0080\t;# set sw_update bit\n\tmww 0xb8050008 0\t\t;# clear reset_switch bit\n\tmww 0xb8050000 0x800f00e8       ;# clr pwrdwn & bypass\n\tmww 0xb8050008 1\t\t;# set clock_switch bit\n\tsleep 1                         ;# wait for lock\n\n\t# Setup DDR config and flash mapping\n\tmww 0xb8000000 0xefbc8cd0       ;# DDR cfg cdl val (rst: 0x5bfc8d0)\n\tmww 0xb8000004 0x8e7156a2       ;# DDR cfg2 cdl val (rst: 0x80d106a8)\n\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb800000c 0                ;# clr ext. mode register\n\tmww 0xb8000010 2 \t\t;# force auto refresh all banks\n\tmww 0xb8000010 8\t\t;# force precharge all banks\n\tmww 0xb8000008 0x31             ;# set DDR mode value CAS=3\n\tmww 0xb8000010 1 \t\t;# force EMRS update cycle\n\tmww 0xb8000014 0x461b           ;# DDR refresh value\n\tmww 0xb8000018 0xffff           ;# DDR Read Data This Cycle value (16bit: 0xffff)\n\tmww 0xb800001c 0x7              ;# delay added to the DQS line (normal = 7)\n\tmww 0xb8000020 0\n\tmww 0xb8000024 0\n\tmww 0xb8000028 0\n}\n\n# setup working area somewhere in RAM\n$_TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000\n\n# serial SPI capable flash\n# flash bank <driver> <base> <size> <chip_width> <bus_width>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/arm_corelink_sse200.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration script for Arm CoreLink SSE-200 Subsystem based IoT SoCs.\n#\n\nglobal TARGET\nset TARGET $_CHIPNAME\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n#\n# SRAM on ARM CoreLink SSE-200 can be 4 banks of 8/16/32/64 KB\n# We will configure work area assuming 8-KB bank size in SRAM bank 1.\n# Also SRAM start addresses defaults to secure mode alias.\n# These values can be overridden as per board configuration\n#\n\nglobal _WORKAREASIZE_CPU0\nif { [info exists WORKAREASIZE_CPU0] } {\n\tset _WORKAREASIZE_CPU0 $WORKAREASIZE_CPU0\n} else {\n\tset _WORKAREASIZE_CPU0 0x1000\n}\n\nglobal _WORKAREAADDR_CPU0\nif { [info exists WORKAREAADDR_CPU0] } {\n\tset _WORKAREAADDR_CPU0 $WORKAREAADDR_CPU0\n} else {\n\tset _WORKAREAADDR_CPU0 0x30008000\n}\n\n#\n# Target configuration for Cortex M33 Core 0 on ARM CoreLink SSE-200\n# Core 0 is the boot core and will always be configured.\n#\n\ntarget create ${TARGET}.CPU0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\n${TARGET}.CPU0 configure -work-area-phys $_WORKAREAADDR_CPU0 -work-area-size $_WORKAREASIZE_CPU0 -work-area-backup 0\n\n${TARGET}.CPU0 cortex_m reset_config sysresetreq\n\n#\n# Target configuration for Cortex M33 Core 1 on ARM CoreLink SSE-200\n# Core 1 is optional and locked at boot until core 0 unlocks it.\n#\n\nif { $_ENABLE_CPU1 } {\n\tglobal _WORKAREASIZE_CPU1\n\tif { [info exists WORKAREASIZE_CPU1] } {\n\t\tset _WORKAREASIZE_CPU1 $WORKAREASIZE_CPU1\n\t} else {\n\t\tset _WORKAREASIZE_CPU1 0x1000\n\t}\n\n\tglobal _WORKAREAADDR_CPU1\n\tif { [info exists WORKAREAADDR_CPU1] } {\n\t\tset _WORKAREAADDR_CPU1 $WORKAREAADDR_CPU1\n\t} else {\n\t\tset _WORKAREAADDR_CPU1 0x30009000\n\t}\n\n\ttarget create ${TARGET}.CPU1 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\n\t${TARGET}.CPU1 configure -work-area-phys $_WORKAREAADDR_CPU1 -work-area-size $_WORKAREASIZE_CPU1 -work-area-backup 0\n\n\t${TARGET}.CPU1 cortex_m reset_config vectreset\n}\n\n# Make sure the default target is the boot core\ntargets ${TARGET}.CPU0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/armada370.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# armada370 -- support for the Marvell Armada/370 CPU family\n#\n# gerg@uclinux.org, OCT-2013\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME armada370\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\nproc armada370_dbginit {target} {\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"armada370_dbginit $_TARGETNAME\"\n\ndap apsel 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at32ap7000.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Atmel AT32AP7000\n#\n# This is the only core in the now-inactive high end AVR32 product line,\n# with MMU, Java Acceleration, and \"pixel coprocessor\".  The AP7 line\n# is for \"Application Processors\" (AP) with 7-stage pipelines.\n#\n# Most current AVR32 parts are in the UC3 flash based microcontroller (UC)\n# product line with 3-stage pipelines and without those extras.\n#\n# All AVR32 parts provide the Nexus Class 3 on-chip debug interfaces\n# through their JTAG interfaces.\n\njtag newtap ap7 nexus -irlen 5 -expected-id 0x21e8203f\n\n# REVISIT declare an avr32 target ... needs OpenOCD infrastructure\n# for both Nexus (generic) and AVR32 (Atmel-specific).\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91r40008.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# AT91R40008 target configuration file\n\n# TRST is tied to SRST on the AT91X40 family.\nreset_config srst_only srst_pulls_trst\n\n\nif {[info exists CHIPNAME]} {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91r40008\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Setup the JTAG scan chain.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91rm9200.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Atmel AT91rm9200\n# http://atmel.com/products/at91/\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91rm9200\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x05b0203f\n}\n\n# Never allow the following!\nif { $_CPUTAPID == 0x15b0203f } {\n   echo \"-------------------------------------------------------\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: TapID 0x15b0203f is wrong for at91rm9200     -\"\n   echo \"- ERROR: The chip/board has a JTAG select pin/jumper  -\"\n   echo \"- ERROR:                                              -\"\n   echo \"- ERROR: In one position (0x05b0203f) it selects the  -\"\n   echo \"- ERROR: ARM CPU, in the other position (0x1b0203f)   -\"\n   echo \"- ERROR: it selects boundary-scan not the ARM         -\"\n   echo \"- ERROR:                                              -\"\n   echo \"-------------------------------------------------------\"\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# AT91RM9200 has a 16K block of sram @ 0x0020.0000\n$_TARGETNAME configure -work-area-phys 0x00200000 \\\n\t\t-work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3XXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam3\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n    halt\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3ax_4x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000A0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3ax_8x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3ax_xx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 512K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x0000C0000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3ax_xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3A4C\n# at91sam3A8C\n# at91sam3X4C\n# at91sam3X4E\n# at91sam3X8C\n# at91sam3X8E\n# at91sam3X8H\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3nXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration for Atmel's SAM3N series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME at91sam3n\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank flash0 at91sam3 0x00400000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3sXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3s4c\n# at91sam3s4b\n# at91sam3s4a\n# at91sam3s2c\n# at91sam3s2b\n# at91sam3s2a\n# at91sam3s1c\n# at91sam3s1b\n# at91sam3s1a\n\nsource [find target/at91sam3XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u1c.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u1e.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u2c.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u2e.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u4c.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip, it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3u4e.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common stuff\nsource [find target/at91sam3uxx.cfg]\n\n# size is automatically \"calculated\" by probing\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam3 0x000080000 0 1 1 $_TARGETNAME\n# This is a 256K chip - it has the 2nd bank\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam3 0x000100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam3uxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam3, a Cortex-M3 chip\n#\n# at91sam3u4e\n# at91sam3u2e\n# at91sam3u1e\n# at91sam3u4c\n# at91sam3u2c\n# at91sam3u1c\n\nsource [find target/at91sam3XXX.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4XXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# script for ATMEL sam4, a Cortex-M4 chip\n#\n\n#\n# sam4 devices can support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam4\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# 16K is plenty, the smallest chip has this much\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 4 MHz, so use F_JTAG = 0.5MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\n\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4c32x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam4c32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x01100000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4cXXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam4c, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x01000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4lXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam4l, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4l 0x00000000 0 1 1 $_TARGETNAME\n\n# SAM4L SMAP will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet 42023E-SAM-07/2013 sec 8.11.3).\n#\n# smap_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the SMAP to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post \"at91sam4l smap_reset_deassert\"\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# SAM4L starts from POR with SYSCLK set to 115kHz RCSYS, needs slow JTAG speed.\n# Datasheet does not specify SYSCLK to JTAG/SWD clock ratio.\n# Usually used SYSCLK/6 is hell slow, testing shows that debugging can work @ SYSCLK/2\n# but your mileage may vary.\nadapter speed 50\n\n# System RC oscillator RCSYS starts in 3 cycles\nadapter srst delay 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4sXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam4, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam4sd32x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for ATMEL sam4sd32, a Cortex-M4 chip\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME at91sam4 0x00500000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam7a2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7a2\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam7se512.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ATMEL sam7se512\n# Example: the \"Elektor Internet Radio\" - EIR\n# http://www.ethernut.de/en/hardware/eir/index.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7se512\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# The target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam7sx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91sam7s\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n$_TARGETNAME configure -event reset-init {\n        soft_reset_halt\n        # RSTC_CR : Reset peripherals\n        mww 0xfffffd00 0xa5000004\n        # disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=73)\n\tmww 0xffffff60 0x00490100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam7x256.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME sam7x256\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam7x512.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME sam7x512\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\t# disable watchdog\n\tmww 0xfffffd44 0x00008000\n\t# enable user reset\n\tmww 0xfffffd08 0xa5000001\n\t# CKGR_MOR : enable the main oscillator\n\tmww 0xfffffc20 0x00000601\n\tsleep 10\n\t# CKGR_PLLR: 96.1097 MHz\n\tmww 0xfffffc2c 0x00481c0e\n\tsleep 10\n\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\n\tmww 0xfffffc30 0x00000007\n\tsleep 10\n\t# MC_FMR: flash mode (FWS=1,FMCN=60)\n\tmww 0xffffff60 0x003c0100\n\tsleep 100\n}\n\n$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base_addr> <size> <chip_width> <bus_width> <target_number> [<target_name> <banks> <sectors_per_bank> <pages_per_sector> <page_size> <num_nvmbits> <ext_freq_khz>]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME.0 at91sam7 0 0 0 0 $_TARGETNAME 0 0 0 0 0 0 0 18432\nflash bank $_FLASHNAME.1 at91sam7 0 0 0 0 $_TARGETNAME 1 0 0 0 0 0 0 18432\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9\n######################################\n\nif { [info exists AT91_CHIPNAME] } {\n\tset _CHIPNAME $AT91_CHIPNAME\n} else {\n\terror \"you must specify a chip name\"\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0792603f\n}\n\nreset_config trst_and_srst separate trst_push_pull srst_open_drain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nadapter srst delay 300\njtag_ntrst_delay 200\n\nadapter speed 3\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9260.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9260\n}\n\nsource [find target/at91sam9.cfg]\n\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9260 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 4 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x1000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x1000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9260_ext_RAM_ext_flash.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9260\n######################################\n\nsource [find target/at91sam9261.cfg]\n\nreset_config trst_and_srst\n\nadapter speed 4\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\nscan_chain\n$_TARGETNAME configure -event reset-start {\n\t# at reset chip runs at 32khz\n\tadapter speed 8\n}\n\n$_TARGETNAME configure -event reset-init {at91sam_init}\n\n# Flash configuration\n#flash bank <name> cfi <base> <size> <chip width> <bus width> <target>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x10000000 0x01000000 2 2 $_TARGETNAME\n\n# Faster memory downloads. This is disabled automatically during\n# reset init since all reset init sequences are too short for\n# fast memory access\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\nproc at91sam_init { } {\n\tmww 0xfffffd08 0xa5000501         ;# RSTC_MR : enable user reset\n\tmww 0xfffffd44 0x00008000         ;# WDT_MR : disable watchdog\n\n\tmww 0xfffffc20 0x00004001         ;# CKGR_MOR : enable the main oscillator\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000001         ;# PMC_MCKR : switch to main oscillator\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc28 0x2060bf09         ;# CKGR_PLLAR: Set PLLA Register for 198,656MHz\n\tsleep 20                          ;# wait 20 ms\n\tmww 0xfffffc30 0x00000101         ;# PMC_MCKR : Select prescaler\n\tsleep 10                          ;# wait 10 ms\n\tmww 0xfffffc30 0x00000102         ;# PMC_MCKR : Clock from PLLA is selected\n\tsleep 10                          ;# wait 10 ms\n\n\t# Now run at anything fast... ie: 10mhz!\n\tadapter speed 10000               ;# Increase JTAG Speed to 6 MHz\n\n\tmww 0xffffec00 0x0a0a0a0a         ;# SMC_SETUP0 : Setup SMC for Intel NOR Flash JS28F128P30T85 128MBit\n\tmww 0xffffec04 0x0b0b0b0b         ;# SMC_PULSE0\n\tmww 0xffffec08 0x00160016         ;# SMC_CYCLE0\n\tmww 0xffffec0c 0x00161003         ;# SMC_MODE0\n\n\tmww 0xfffff870 0xffff0000         ;# PIO_ASR : Select peripheral function for D15..D31\n\tmww 0xfffff804 0xffff0000         ;# PIO_PDR : Disable PIO function for D15..D31\n\n\tmww 0xffffef1c 0x2                ;# EBI_CSA : Assign EBI Chip Select 1 to SDRAM\n\n\tmww 0xffffea08 0x85227259         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S561632H-UC75 : 4M x 16Bit x 4 Banks)\n\t#mww 0xffffea08 0x85227254         ;# SDRAMC_CR : Configure SDRAM (2 x Samsung K4S641632H-UC75 : 1M x 16Bit x 4 Banks)\n\n\tmww 0xffffea00 0x1                ;# SDRAMC_MR : issue a NOP command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x2                ;# SDRAMC_MR : issue an 'All Banks Precharge' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4                ;# SDRAMC_MR : issue 8 x 'Auto-Refresh' Command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x4\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x3                ;# SDRAMC_MR : issue a 'Load Mode Register' command\n\tmww 0x20000000 0\n\tmww 0xffffea00 0x0                ;# SDRAMC_MR : normal mode\n\tmww 0x20000000 0\n\tmww 0xffffea04 0x5d2              ;# SDRAMC_TR : Set refresh timer count to 15us\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9261.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9261\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9261\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x28000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9263.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9263\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9263\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9263 has two SRAM areas,\n# one starting at 0x00300000 of 80KiB\n# and the other  starting at 0x00500000 of 16KiB.\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x14000 -work-area-backup 1\n#$_TARGETNAME configure -work-area-phys 0x00500000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9g10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9G10\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g10\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G10 has one SRAM area at 0x00300000 of 16KiB\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9g20.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9G20\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g20\n}\n\nsource [find target/at91sam9.cfg]\n\n# Set fallback clock to 1/6 of worst-case clock speed (which would be the 32.768 kHz slow clock).\n\nadapter speed 5\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G20 has two SRAM areas, one starting at 0x00200000 and the other starting at 0x00300000.\n# Both areas are 16 kB long.\n\n#$_TARGETNAME configure -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup 1\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x4000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9g45.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9G45\n######################################\n\nif { [info exists CHIPNAME] } {\n\tset AT91_CHIPNAME $CHIPNAME\n} else {\n\tset AT91_CHIPNAME at91sam9g45\n}\n\nsource [find target/at91sam9.cfg]\n\n# Establish internal SRAM memory work areas that are important to pre-bootstrap loaders, etc.  The\n# AT91SAM9G45 has one SRAM area starting at 0x00300000 of 64 KiB.\n\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x200000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sam9rl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Atmel AT91SAM9RL\n######################################\n\nif { [info exists CHIPNAME] } {\n   set AT91_CHIPNAME $CHIPNAME\n} else {\n   set AT91_CHIPNAME at91sam9rl\n}\n\nsource [find target/at91sam9.cfg]\n\n# Internal sram1 memory\n$_TARGETNAME configure -work-area-phys 0x00300000 -work-area-size 0x10000 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91sama5d2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# The JTAG connection is disabled at reset, and during the ROM Code execution.\n# It is re-enabled when the ROM code jumps in the boot file copied from an\n# external Flash memory into the internalSRAM, or when the ROM code launches\n# the SAM-BA monitor, when no boot file has been found in any external Flash\n# memory.\n# For more JTAG related information see, :\n# https://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-sheet-ds60001476G.pdf\n#\n# If JTAGSEL pin:\n# - if enabled, boundary Scan mode is activated. JTAG ID Code value is 0x05B3F03F.\n# - if disabled, ICE mode is activated. Debug Port JTAG IDCODE value is 0x5BA00477\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME at91sama5d2\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n\t-expected-id 0x5ba00477\n\n# Cortex-A5 target\nset _TARGETNAME $_CHIPNAME.cpu_a5\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91samdXX.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# script for Atmel SAMD, SAMR, SAML or SAMC, a Cortex-M0 chip\n#\n\n#\n# samdXX devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91samd\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAMD DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts (see datasheet Atmel-42181E–SAM-D21_Datasheet–02/2015, section 12.6.2)\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        at91samd dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAMD runs at SYSCLK = 1 MHz divided from RC oscillator after reset.\n# Other members of family usually use SYSCLK = 4 MHz after reset.\n# Datasheet does not specify SYSCLK to SWD clock ratio.\n# Usually used SYSCLK/6 is slow, testing shows that debugging can\n# work @ SYSCLK/2 but your mileage may vary.\n# This limit is most probably imposed by incorrectly handled SWD WAIT\n# on some SWD adapters.\n\nadapter speed 400\n\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at maximal clock speed. Atmel recommends\n# adapter speed less than 10 * CPU clock.\n# adapter speed 5000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91samd 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/at91samg5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for the ATMEL samg5x Cortex-M4F chip family\n#\n\nsource [find target/at91sam4XXX.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME at91sam4 0x00400000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atheros_ar2313.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2313\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atheros_ar2315.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar2315\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atheros_ar9331.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Atheros AR9331 is a highly integrated and cost effective\n# IEEE 802.11n 1x1 2.4 GHz System- on-a-Chip (SoC) for wireless\n# local area network (WLAN) AP and router platforms.\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 400 MHz\n# - External 16-bit DDR1, DDR2, or SDRAM memory interface\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin A72 on the SoC will reset internal JTAG logic.\n#\n\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO6, (B46)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO7, (A54)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO8, (A52)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (A72)\tInput only\n# SYS_RST_L\t????????\tOutput reset request or GPIO\n#   Bootstrap\n# MEM_TYPE[1]\tGPIO28, (A74)\t0 - SDRAM, 1 - DDR1 RAM, 2 - DDR2 RAM\n# MEM_TYPE[0]\tGPIO12, (A56)\n# FW_DOWNLOAD\tGPIO16, (A75)\tUsed if BOOT_FROM_SPI = 0. 0 - boot from USB\n#                               1 - boot from MDIO.\n# JTAG_MODE(JS)\tGPIO11, (B48)\t0 - JTAG (Default); 1 - EJTAG\n# BOOT_FROM_SPI\tGPIO1, (A77)\t0 - ROM boot; 1 - SPI boot\n# SEL_25M_40M\tGPIO0, (A78)\t0 - 25MHz; 1 - 40MHz\n#   UART\n# UART0_SOUT\tGPIO10, (A79)\n# UART0_SIN\tGPIO9, (B68)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9331\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\nproc disable_watchdog { } {\n\t;# disable watchdog\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event reset-end { disable_watchdog }\n\n# Section with helpers which can be used by boards\nproc ar9331_25mhz_pll_init {} {\n\tmww 0xb8050008 0x00018004\t;# bypass PLL; AHB_POST_DIV - ratio 4\n\tmww 0xb8050004 0x00000352\t;# 34000(ns)/40ns(25MHz) = 0x352 (850)\n\tmww 0xb8050000 0x40818000\t;# Power down control for CPU PLL\n\t\t\t\t\t;# OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050010 0x001003e8\t;# CPU PLL Dither FRAC Register\n\t\t\t\t\t;# (disabled?)\n\tmww 0xb8050000 0x00818000\t;# Power on | OUTDIV | REFDIV | DIV_INT\n\tmww 0xb8050008 0x00008000\t;# remove bypass;\n\t\t\t\t\t;# AHB_POST_DIV - ratio 2\n}\n\nproc ar9331_ddr1_init {} {\n\tmww 0xb8000000 0x7fbc8cd0       ;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x133\t;# mode reg: 0x133 - default\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb800000c 0x2\t;# Extended mode register value.\n\t\t\t\t;# default 0x2 - Reset to weak driver, DLL on\n\tmww 0xb8000010 0x2\t;# Forces an EMRS update cycle\n\tmww 0xb8000010 0x8\t;# Forces a PRECHARGE ALL cycle\n\tmww 0xb8000008 0x33\t;# mode reg: remove some bit?\n\tmww 0xb8000010 0x1\t;# Forces an MRS update cycl\n\tmww 0xb8000014 0x4186\t;# enable refres: bit(14) - set refresh rate\n\tmww 0xb800001c 0x8\t;# This register is used along with DQ Lane 0,\n\t\t\t\t;# DQ[7:0], DQS_0\n\tmww 0xb8000020 0x9\t;# This register is used along with DQ Lane 1,\n\t\t\t\t;# DQ[15:8], DQS_1.\n\tmww 0xb8000018 0xff\t;# DDR read and capture bit mask.\n\t\t\t\t;# Each bit represents a cycle of valid data.\n}\n\nproc ar9331_ddr2_init {} {\n\tmww 0xb8000000 0x7fbc8cd0\t;# DDR_CONFIG - lots of DRAM confs\n\tmww 0xb8000004 0x9dd0e6a8\t;# DDR_CONFIG2 - more DRAM confs\n\n\tmww 0xb800008c 0x00000a59\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000090 0x00000000\n\tmww 0xb8000010 0x00000010\t;# EMR2S update cycle\n\n\tmww 0xb8000094 0x00000000\n\tmww 0xb8000010 0x00000020\t;# EMR3S update cycle\n\n\tmww 0xb800000c 0x00000000\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000008 0x00000100\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb8000010 0x00000008\t;# PRECHARGE ALL cycle\n\n\tmww 0xb8000010 0x00000004\n\tmww 0xb8000010 0x00000004\t;# AUTO REFRESH cycle\n\n\tmww 0xb8000008 0x00000a33\n\tmww 0xb8000010 0x00000001\t;# MRS update cycle\n\n\tmww 0xb800000c 0x00000382\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb800000c 0x00000402\n\tmww 0xb8000010 0x00000002\t;# EMRS update cycle\n\n\tmww 0xb8000014 0x00004186\t;# DDR_REFRESH\n\tmww 0xb800001c 0x00000008\t;# DDR_TAP_CTRL0\n\tmww 0xb8000020 0x00000009\t;# DDR_TAP_CTRL1\n\n\t;# DDR read and capture bit mask.\n\t;# Each bit represents a cycle of valid data.\n\t;# 0xff: use 16-bit DDR\n\tmww 0xb8000018 0x000000ff\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atheros_ar9344.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME ar9344\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x00000001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\nproc test_ar9344_uart0_tx {} {\n\techo \"configuring uart0..\"\n\tmww 0xb802000c 0x87\n\tmww 0xb8020000 0x15\n\tmww 0xb8020004 0\n\tmww 0xb802000c 7\n\tmww 0xb8020004 0\n\n\techo \"send message: hallo world\"\n\tmww 0xb8020000 0x68\n\tmww 0xb8020000 0x65\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x20\n\tmww 0xb8020000 0x77\n\tmww 0xb8020000 0x6f\n\tmww 0xb8020000 0x72\n\tmww 0xb8020000 0x6c\n\tmww 0xb8020000 0x64\n\tmww 0xb8020000 0x0a\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atmega128.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# for avr\n\n   set _CHIPNAME avr\n   set _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\nreset_config srst_only\nadapter srst delay 100\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x8970203F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n\n#to use it, script will be like:\n#init\n#adapter speed 4500\n#reset init\n#verify_ircapture disable\n#\n#halt\n#wait halt\n#poll\n#avr mass_erase 0\n#flash write_image E:/Versaloon/Software/CAMERAPROTOCOLAGENT.hex\n#reset run\n#shutdown\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atmega128rfa1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME avr\nset _ENDIAN little\n\n# jtag speed\nadapter speed 4500\n\n# avr jtag docs never connect RSTN\nreset_config none\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0a70103f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atmega32u4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# ATmega32U4\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME avr\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4958703f\n}\n\nadapter speed 4500\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME avr -endian $_ENDIAN -chain-position $_TARGETNAME\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME avr 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atsame5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Microchip (former Atmel) SAM E54, E53, E51 and D51 devices\n# with a Cortex-M4 core\n#\n\n#\n# Devices only support SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME atsame5\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (the smallest RAM size is 128kB)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# SAM DSU will hold the CPU in reset if TCK is low when RESET_N\n# deasserts\n#\n# dsu_reset_deassert configures whether we want to run or halt out of reset,\n# then instruct the DSU to let us out of reset.\n$_TARGETNAME configure -event reset-deassert-post {\n        atsame5 dsu_reset_deassert\n}\n\n# SRST (wired to RESET_N) resets debug circuitry\n# srst_pulls_trst is not configured here to avoid an error raised in reset halt\nreset_config srst_gates_jtag\n\n# Do not use a reset button with other SWD adapter than Atmel's EDBG.\n# DSU usually locks MCU in reset state until you issue a reset command\n# in OpenOCD.\n\n# SAM E5x/D51 runs at SYSCLK = 48 MHz from RC oscillator after reset.\n# Atmel's EDBG (on-board cmsis-dap adapter of Xplained kits) works\n# without problem at clock speed over 5000 khz. Atmel recommends\n# adapter speed less than 10 * CPU clock.\nadapter speed 2000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsame5 0x00000000 0 1 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atsaml1x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Microchip (formerly Atmel) SAM L1x target\n#\n# Note: These devices support SWD only.\n#\n\ntransport select swd\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME saml1x\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nswd newdap $_CHIPNAME cpu -expected-id 0x0bf11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/atsamv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ATMEL SAMV, SAMS, and SAME chips are Cortex-M7 parts\n# The chips are very similar; the SAMV series just has\n# more peripherals and seems like the \"flagship\" of the\n# family. This script will work for all of them.\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME samv\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bd11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20400000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 1800\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME atsamv 0x00400000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/avr32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME avr32\nset _ENDIAN big\n\nset _CPUTAPID 0x21e8203f\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_CPUTAPID\n\nset _TARGETNAME [format \"%s.cpu\" $_CHIPNAME]\ntarget create $_TARGETNAME avr32_ap7k -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm2711.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom BCM2711 used in Raspberry Pi 4\n# No documentation was found on Broadcom website\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2711/\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2711\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm281xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# BCM281xx\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm281xx\n}\n\n\n# Main CPU DAP\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\n\n\n# Dual Cortex-A9\nset _TARGETNAME0 $_CHIPNAME.cpu0\nset _TARGETNAME1 $_CHIPNAME.cpu1\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME0 cortex_a -dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x3fe10000\ntarget create $_TARGETNAME1 cortex_a -dap $_CHIPNAME.dap -coreid 1 -dbgbase 0x3fe12000\ntarget smp $_TARGETNAME0 $_TARGETNAME1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm2835.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi Model A, B, B+,\n# the Compute Module, and the Raspberry Pi Zero.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2835\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x07b7617F\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 5\nadapter speed 4000\n\ntarget create $_CHIPNAME.cpu0 arm11 -chain-position $_CHIPNAME.cpu\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm2836.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The Broadcom chip used in the Raspberry Pi 2 Model B\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2836\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2836\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\ttarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -coreid $_core -dbgbase [lindex $_DBGBASE $_core]\n\t$_TARGETNAME configure -event reset-assert-post { cortex_a dbginit }\n\n\tset _smp_command \"$_smp_command $_CHIPNAME.cpu$_core\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm2837.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This is the Broadcom chip used in the Raspberry Pi 3,\n# and in later models of the Raspberry Pi 2.\n\n# Partial information is available in raspberry pi website:\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837\n# https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2837b0\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME bcm2837\n}\n\nif { [info exists CHIPCORES] } {\n\tset _cores $CHIPCORES\n} else {\n\tset _cores 4\n}\n\nif { [info exists USE_SMP] } {\n\tset _USE_SMP $USE_SMP\n} else {\n\tset _USE_SMP 0\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -expected-id $_DAP_TAPID -irlen 4\nadapter speed 4000\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# MEM-AP for direct access\ntarget create $_CHIPNAME.ap mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# these addresses are obtained from the ROM table via 'dap info 0' command\nset _DBGBASE {0x80010000 0x80012000 0x80014000 0x80016000}\nset _CTIBASE {0x80018000 0x80019000 0x8001a000 0x8001b000}\n\nset _smp_command \"target smp\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\tset _CTINAME $_CHIPNAME.cti$_core\n\tset _TARGETNAME $_CHIPNAME.cpu$_core\n\n\tcti create $_CTINAME -dap $_CHIPNAME.dap -ap-num 0 -baseaddr [lindex $_CTIBASE $_core]\n\ttarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -ap-num 0 -dbgbase [lindex $_DBGBASE $_core] -cti $_CTINAME\n\t$_TARGETNAME configure -event reset-assert-post { aarch64  dbginit }\n\n\tset _smp_command \"$_smp_command $_TARGETNAME\"\n}\n\nif {$_USE_SMP} {\n\teval $_smp_command\n}\n\n# default target is cpu0\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm4706.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME bcm4706\nset _CPUID 0x1008c17f\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm4718.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME bcm4718\nset _LVTAPID 0x1471617f\nset _CPUID 0x0008c17f\n\nsource [find target/bcm47xx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm47xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"Forcing reset_config to none to prevent OpenOCD from pulling SRST after the switch from LV is already performed\"\nreset_config none\n\njtag newtap $_CHIPNAME-lv tap -irlen 32 -ircapture 0x1 -irmask 0x1f -expected-id $_LVTAPID -expected-id $_CPUID\njtag configure $_CHIPNAME-lv.tap -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME-lv.tap -event tap-disable {}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"switch_lv_to_ejtag\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n\nproc switch_lv_to_ejtag {} {\n    global _CHIPNAME\n    poll 0\n    irscan $_CHIPNAME-lv.tap 0x143ff3a\n    drscan $_CHIPNAME-lv.tap 32 1\n    jtag tapdisable $_CHIPNAME-lv.tap\n    poll 1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm5352e.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME bcm5352e\nset _CPUID 0x0535217f\n\njtag newtap $_CHIPNAME cpu -irlen 8 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian little -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bcm6348.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset _CHIPNAME bcm6348\nset _CPUID 0x0634817f\n\nadapter speed 1000\n\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bluefield.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# BlueField SoC Target\n\nset _CHIPNAME bluefield\n\n# Specify the target device\n#rshim device /dev/rshim0/rshim\n\n# Main DAP\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\nadapter speed 1500\n\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Initialize the target name and command variable.\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\n# CTI relative address\nset $_TARGETNAME.cti(0) 0xC4020000\nset $_TARGETNAME.cti(1) 0xC4120000\nset $_TARGETNAME.cti(2) 0xC8020000\nset $_TARGETNAME.cti(3) 0xC8120000\nset $_TARGETNAME.cti(4) 0xCC020000\nset $_TARGETNAME.cti(5) 0xCC120000\nset $_TARGETNAME.cti(6) 0xD0020000\nset $_TARGETNAME.cti(7) 0xD0120000\nset $_TARGETNAME.cti(8) 0xD4020000\nset $_TARGETNAME.cti(9) 0xD4120000\nset $_TARGETNAME.cti(10) 0xD8020000\nset $_TARGETNAME.cti(11) 0xD8120000\nset $_TARGETNAME.cti(12) 0xDC020000\nset $_TARGETNAME.cti(13) 0xDC120000\nset $_TARGETNAME.cti(14) 0xE0020000\nset $_TARGETNAME.cti(15) 0xE0120000\n\n# Create debug targets for a number of cores starting from core '_core_start'.\n# Adjust the numbers according to board configuration.\nset _core_start 0\nset _cores 16\n\n# Create each core\nfor { set _core $_core_start } { $_core < $_core_start + $_cores } { incr _core 1 } {\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != $_core_start } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\n# Configure SMP\nif { $_cores > 1 } {\n    eval $_smp_command\n}\n\n# Make sure the default target is the boot core\ntargets ${_TARGETNAME}0\n\nproc core_up { args } {\n\tglobal _TARGETNAME\n\n\t# Examine remaining cores\n\tforeach _core $args {\n\t\t${_TARGETNAME}$_core arp_examine\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/bluenrg-x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# bluenrg-1/2 and bluenrg-lp devices support only SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME bluenrg-1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 24kB-256bytes\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x5F00\n}\n\nadapter speed 4000\n\nswj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\nset WDOG_VALUE 0\nset WDOG_VALUE_SET 0\n\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000100 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME bluenrg-x 0 0 0 0 $_TARGETNAME\n\n# In BlueNRG-X reset pin is actually a shutdown (power-off), so define reset as none\nreset_config none\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nset JTAG_IDCODE_B2 0x0200A041\nset JTAG_IDCODE_B1 0x0\n\n$_TARGETNAME configure -event halted {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        # Stop watchdog during halt, if enabled. Only Bluenrg-1/2\n        set WDOG_VALUE [mrw 0x40700008]\n        if [expr {$WDOG_VALUE & (1 << 1)}] {\n            set WDOG_VALUE_SET 1\n            mww 0x40700008 [expr {$WDOG_VALUE & 0xFFFFFFFD}]\n        }\n    }\n}\n$_TARGETNAME configure -event resumed {\n    global WDOG_VALUE\n    global WDOG_VALUE_SET\n    set _JTAG_IDCODE [mrw 0x40000004]\n    if {$_JTAG_IDCODE == $JTAG_IDCODE_B2 || $_JTAG_IDCODE == $JTAG_IDCODE_B1} {\n        if {$WDOG_VALUE_SET} {\n            # Restore watchdog enable value after resume. Only Bluenrg-1/2\n            mww 0x40700008 $WDOG_VALUE\n            set WDOG_VALUE_SET 0\n           }\n   }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/c100.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# c100 config.\n# This is ARM1136 dual core\n# this script only configures one core (that is used to run Linux)\n\n# assume no PLL lock, start slowly\nadapter speed 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME c100\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x27b3645b\n}\n\nif { [info exists DSPTAPID] } {\n   set _DSPTAPID $DSPTAPID\n} else {\n   set _DSPTAPID 0x27b3645b\n}\n\njtag newtap $_CHIPNAME dsp -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_DSPTAPID\n\n\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# C100's ARAM 64k SRAM\n$_TARGETNAME configure -work-area-phys 0x0a000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/c100config.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# board(-config) specific parameters file.\n\n# set CFG_REFCLKFREQ [configC100 CFG_REFCLKFREQ]\nproc config {label} {\n    return [dict get [configC100] $label ]\n}\n\n# show the value for the param. with label\nproc showconfig {label} {\n    echo [format \"0x%x\" [dict get [configC100] $label ]]\n}\n\n# Telo board config\n# when there are more then one board config\n# use soft links to c100board-config.tcl\n# so that only the right board-config gets\n# included (just like include/configs/board-configs.h\n# in u-boot.\nproc configC100 {} {\n    # xtal freq. 24MHz\n    dict set configC100 CFG_REFCLKFREQ\t         24000000\n\n    # Amba Clk 165MHz\n    dict set configC100 CONFIG_SYS_HZ_CLOCK      165000000\n    dict set configC100 w_amba 1\n    dict set configC100 x_amba 1\n    # y = amba_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_amba [expr {[dict get $configC100 CONFIG_SYS_HZ_CLOCK] * ( ([dict get $configC100 w_amba]+1 ) * ([dict get $configC100 x_amba]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n    # Arm Clk 450MHz, must be a multiple of 25 MHz\n    dict set configC100 CFG_ARM_CLOCK      450000000\n    dict set configC100 w_arm 0\n    dict set configC100 x_arm 1\n    # y = arm_clk * (w+1)*(x+1)*2/xtal_clk\n    dict set configC100 y_arm [expr {[dict get $configC100 CFG_ARM_CLOCK] * ( ([dict get $configC100 w_arm]+1 ) * ([dict get $configC100 x_arm]+1 ) *2 ) / [dict get $configC100 CFG_REFCLKFREQ]} ]\n\n\n}\n\n# This should be called for reset init event handler\nproc setupTelo {} {\n\n    # setup GPIO used as control signals for C100\n    setupGPIO\n    # This will allow access to lower 8MB or NOR\n    lowGPIO5\n    # setup NOR size,timing,etc.\n    setupNOR\n    # setup internals + PLL + DDR2\n    initC100\n}\n\n\nproc setupNOR {} {\n    echo \"Setting up NOR: 16MB, 16-bit wide bus, CS0\"\n    # this is taken from u-boot/boards/mindspeed/ooma-darwin/board.c:nor_hw_init()\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    # enable Expansion Bus Clock + CS0 (NOR)\n    mww $EX_CSEN_REG 0x3\n    # set the address space for CS0=16MB\n    mww $EX_CS0_SEG_REG 0x7ff\n    # set the CS0 bus width to 16-bit\n    mww $EX_CS0_CFG_REG 0x202\n    # set timings to NOR\n    mww $EX_CS0_TMG1_REG 0x03034006\n    mww $EX_CS0_TMG2_REG 0x04040002\n    #mww $EX_CS0_TMG3_REG\n    # set EBUS clock 165/5=33MHz\n    mww $EX_CLOCK_DIV_REG 0x5\n    # everything else is OK with default\n}\n\nproc bootNOR {} {\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n    set BLOCK_RESET_REG\t       [regs BLOCK_RESET_REG]\n    set DDR_RST\t\t       [regs DDR_RST]\n\n    # put DDR controller in reset (so that it comes reset in u-boot)\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $EXP_CS0_BASEADDR\n    # run\n    resume\n}\nproc setupGPIO {} {\n    echo \"Setting up GPIO block for Telo\"\n    # This is current setup for Telo (see sch. for details):\n    #GPIO0 reset for FXS-FXO IC, leave as input, the IC has internal pullup\n    #GPIO1 irq line for FXS-FXO\n    #GPIO5 addr22 for NOR flash (access to upper 8MB)\n    #GPIO17 reset for DECT module.\n    #GPIO29 CS_n for NAND\n\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n\n    # set GPIO29=GPIO17=1, GPIO5=0\n    mww $GPIO_OUTPUT_REG [expr {1<<29 | 1<<17}]\n    # enable [as output] GPIO29,GPIO17,GPIO5\n    mww $GPIO_OE_REG [expr  {1<<29 | 1<<17 | 1<<5}]\n}\n\nproc highGPIO5 {} {\n    echo \"GPIO5 high\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=1\n    mmw $GPIO_OUTPUT_REG [expr {1 << 5}] 0x0\n}\n\nproc lowGPIO5 {} {\n    echo \"GPIO5 low\"\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # set GPIO5=0\n    mmw $GPIO_OUTPUT_REG 0x0 [expr {1 << 5}]\n}\n\nproc boardID {id} {\n    # so far built:\n    # 4'b1111\n    dict set boardID 15 name \"EVT1\"\n    dict set boardID 15 ddr2size 128M\n    # dict set boardID 15 nandsize 1G\n    # dict set boardID 15 norsize 16M\n    # 4'b0000\n    dict set boardID 0 name \"EVT2\"\n    dict set boardID 0 ddr2size 128M\n    # 4'b0001\n    dict set boardID 1 name \"EVT3\"\n    dict set boardID 1 ddr2size 256M\n    # 4'b1110\n    dict set boardID 14 name \"EVT3_old\"\n    dict set boardID 14 ddr2size 128M\n    # 4'b0010\n    dict set boardID 2 name \"EVT4\"\n    dict set boardID 2 ddr2size 256M\n\n    return $boardID\n}\n\n\n# converted from u-boot/boards/mindspeed/ooma-darwin/board.c:ooma_board_detect()\n# figure out what board revision this is, uses BOOTSTRAP register to read stuffed resistors\nproc ooma_board_detect {} {\n    set GPIO_BOOTSTRAP_REG\t[regs GPIO_BOOTSTRAP_REG]\n\n    # read the current value of the BOOTSTRAP pins\n    set tmp [mrw $GPIO_BOOTSTRAP_REG]\n    echo [format \"GPIO_BOOTSTRAP_REG  (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG $tmp]\n    # extract the GPBP bits\n    set gpbt [expr {($tmp &0x1C00) >> 10 | ($tmp & 0x40) >>3}]\n\n    # display board ID\n    echo [format \"This is %s (0x%x)\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # show it on serial console\n    putsUART0 [format \"This is %s (0x%x)\\n\" [dict get [boardID $gpbt] $gpbt name] $gpbt]\n    # return the ddr2 size, used to configure DDR2 on a given board.\n    return [dict get [boardID $gpbt] $gpbt ddr2size]\n}\n\nproc configureDDR2regs_256M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set DENALI_CTL_02_VAL 0x0100000000010100\n    set DENALI_CTL_11_VAL 0x433a32164a560a00\n\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    # 01_DATA mod [40]=1, enable BA2\n    mw64bit $DENALI_CTL_01_DATA  0x0100010100000001\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0000010100000001\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x060a020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x0000000300000206\n    mw64bit $DENALI_CTL_08_DATA  0x6400003f3f0a0209\n    mw64bit $DENALI_CTL_09_DATA  0x1a000000001a1a1a\n    mw64bit $DENALI_CTL_10_DATA  0x0120202020191a18\n    # 11_DATA mod [39-32]=16,more refresh\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000000000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x04f8000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000000002cca0000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000000000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001300c8030600\n    mw64bit $DENALI_CTL_20_DATA  0x0000000081fe00c8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c:config_board99()\n# The values are computed based on Mindspeed and Nanya datasheets\nproc configureDDR2regs_128M {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n\n    set DENALI_CTL_02_VAL 0x0100010000010100\n    set DENALI_CTL_11_VAL 0x433A42124A650A37\n    # set some default values\n    mw64bit $DENALI_CTL_00_DATA  0x0100000101010101\n    mw64bit $DENALI_CTL_01_DATA  0x0100000100000101\n    mw64bit $DENALI_CTL_02_DATA  $DENALI_CTL_02_VAL\n    mw64bit $DENALI_CTL_03_DATA  0x0102020202020201\n    mw64bit $DENALI_CTL_04_DATA  0x0201010100000201\n    mw64bit $DENALI_CTL_05_DATA  0x0203010300010101\n    mw64bit $DENALI_CTL_06_DATA  0x050A020200020202\n    mw64bit $DENALI_CTL_07_DATA  0x000000030E0B0205\n    mw64bit $DENALI_CTL_08_DATA  0x6427003F3F0A0209\n    mw64bit $DENALI_CTL_09_DATA  0x1A00002F00001A00\n    mw64bit $DENALI_CTL_10_DATA  0x01202020201A1A1A\n    mw64bit $DENALI_CTL_11_DATA  $DENALI_CTL_11_VAL\n    mw64bit $DENALI_CTL_12_DATA  0x0000080000000800\n    mw64bit $DENALI_CTL_13_DATA  0x0010002000100040\n    mw64bit $DENALI_CTL_14_DATA  0x0010004000100040\n    mw64bit $DENALI_CTL_15_DATA  0x0508000000000000\n    mw64bit $DENALI_CTL_16_DATA  0x000020472D200000\n    mw64bit $DENALI_CTL_17_DATA  0x0000000008000000\n    mw64bit $DENALI_CTL_18_DATA  0x0302000000000000\n    mw64bit $DENALI_CTL_19_DATA  0x00001400C8030604\n    mw64bit $DENALI_CTL_20_DATA  0x00000000823600C8\n\n    set wr_dqs_shift 0x40\n    # start DDRC\n    mw64bit $DENALI_CTL_02_DATA [expr {$DENALI_CTL_02_VAL | (1 << 32)}]\n    # wait int_status[2] (DRAM init complete)\n    echo -n \"Waiting for DDR2 controller to init...\"\n    set tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    while { [expr {$tmp & 0x040000}] == 0 } {\n\tsleep 1\n\tset tmp [mrw [expr {$DENALI_CTL_08_DATA + 4}]]\n    }\n    # This is not necessary\n    #mw64bit $DENALI_CTL_11_DATA [expr {($DENALI_CTL_11_VAL  & ~0x00007F0000000000) | ($wr_dqs_shift << 40)} ]\n    echo \"done.\"\n\n    # do ddr2 training sequence\n    # TBD (for now, if you need it, run trainDDR command)\n}\n\n\n\nproc setupUART0 {} {\n    # configure UART0 to 115200, 8N1\n    set GPIO_LOCK_REG      [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL    [regs GPIO_IOCTRL_VAL]\n    set GPIO_IOCTRL_UART0  [regs GPIO_IOCTRL_UART0]\n    set UART0_LCR\t            [regs UART0_LCR]\n    set LCR_DLAB\t\t    [regs LCR_DLAB]\n    set UART0_DLL\t\t    [regs UART0_DLL]\n    set UART0_DLH\t\t    [regs UART0_DLH]\n    set UART0_IIR\t\t    [regs UART0_IIR]\n    set UART0_IER\t\t    [regs UART0_IER]\n    set LCR_ONE_STOP\t\t    [regs LCR_ONE_STOP]\n    set LCR_CHAR_LEN_8\t\t    [regs LCR_CHAR_LEN_8]\n    set FCR_XMITRES\t\t    [regs FCR_XMITRES]\n    set FCR_RCVRRES\t\t    [regs FCR_RCVRRES]\n    set FCR_FIFOEN\t\t    [regs FCR_FIFOEN]\n    set IER_UUE\t\t\t    [regs IER_UUE]\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable UART0\n    mmw $GPIO_IOCTRL_REG $GPIO_IOCTRL_UART0 0x0\n    # baudrate  115200\n    # This should really be amba_clk/(16*115200) but amba_clk=165MHz\n    set tmp 89\n    # Enable Divisor Latch access\n    mmw  $UART0_LCR $LCR_DLAB 0x0\n    # set the divisor to $tmp\n    mww $UART0_DLL [expr {$tmp & 0xff}]\n    mww $UART0_DLH [expr {$tmp >> 8}]\n    # Disable Divisor Latch access\n    mmw  $UART0_LCR 0x0 $LCR_DLAB\n    # set the UART to 8N1\n    mmw  $UART0_LCR [expr {$LCR_ONE_STOP | $LCR_CHAR_LEN_8} ] 0x0\n    # reset FIFO\n    mmw  $UART0_IIR [expr {$FCR_XMITRES  | $FCR_RCVRRES | $FCR_FIFOEN} ] 0x0\n    #  enable FFUART\n    mww $UART0_IER $IER_UUE\n}\n\nproc putcUART0 {char} {\n\n    set UART0_LSR\t    [regs UART0_LSR]\n    set UART0_THR\t    [regs UART0_THR]\n    set LSR_TEMT\t    [regs LSR_TEMT]\n\n    # convert the 'char' to digit\n    set tmp [ scan $char %c ]\n    # /* wait for room in the tx FIFO on FFUART */\n    while {[expr {[mrw $UART0_LSR] & $LSR_TEMT}] == 0} { sleep 1 }\n    mww $UART0_THR $tmp\n    if { $char == \"\\n\" } { putcUART0 \\r }\n}\n\nproc putsUART0 {str} {\n    set index 0\n    set len [string length $str]\n    while { $index < $len } {\n\tputcUART0 [string index $str $index]\n\tset index [expr {$index + 1}]\n    }\n}\n\n\nproc trainDDR2 {} {\n    set ARAM_BASEADDR\t[regs ARAM_BASEADDR]\n\n    # you must have run 'reset init' or u-boot\n    # load the training code to ARAM\n    load_image ./images/ddr2train.bin $ARAM_BASEADDR bin\n    # set PC to start of NOR (at boot 0x20000000 = 0x0)\n    reg pc $ARAM_BASEADDR\n    # run\n    resume\n}\n\nproc flashUBOOT {file} {\n    # this will update uboot on NOR partition\n    set EXP_CS0_BASEADDR       [regs EXP_CS0_BASEADDR]\n\n    # setup CS0 controller for NOR\n    setupNOR\n    # make sure we are accessing the lower part of NOR\n    lowGPIO5\n    flash probe 0\n    echo \"Erasing sectors 0-3 for uboot\"\n    putsUART0 \"Erasing sectors 0-3 for uboot\\n\"\n    flash erase_sector 0 0 3\n    echo \"Programming u-boot\"\n    putsUART0 \"Programming u-boot...\"\n    arm11 memwrite burst enable\n    flash write_image $file $EXP_CS0_BASEADDR\n    arm11 memwrite burst disable\n    putsUART0 \"done.\\n\"\n    putsUART0 \"Rebooting, please wait!\\n\"\n    reboot\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/c100helper.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nproc helpC100 {} {\n    echo \"List of useful functions for C100 processor:\"\n    echo \"1)  reset init:        will set up your Telo board\"\n    echo \"2)  setupNOR:          will setup NOR access\"\n    echo \"3)  showNOR:           will show current NOR config registers for 16-bit, 16MB NOR\"\n    echo \"4)  setupGPIO:         will setup GPIOs for Telo board\"\n    echo \"5)  showGPIO:          will show current GPIO config registers\"\n    echo \"6)  highGPIO5:         will set GPIO5=NOR_addr22=1 to access upper 8MB\"\n    echo \"7)  lowGPIO5:          will set GPIO5=NOR_addr22=0 to access lower 8MB\"\n    echo \"8)  showAmbaClk:       will show current config registers for Amba Bus Clock\"\n    echo \"9)  setupAmbaClk:      will setup Amba Bus Clock=165MHz\"\n    echo \"10) showArmClk:        will show current config registers for Arm Bus Clock\"\n    echo \"11) setupArmClk:       will setup Amba Bus Clock=450MHz\"\n    echo \"12) ooma_board_detect: will show which version of Telo you have\"\n    echo \"13) setupDDR2:         will configure DDR2 controller, you must have PLLs configured\"\n    echo \"14) showDDR2:          will show DDR2 config registers\"\n    echo \"15) showWatchdog:      will show current register config for watchdog\"\n    echo \"16) reboot:            will trigger watchdog and reboot Telo (hw reset)\"\n    echo \"17) bootNOR:           will boot Telo from NOR\"\n    echo \"18) setupUART0:        will configure UART0 for 115200 8N1, PLLs have to be configured\"\n    echo \"19) putcUART0:         will print a character on UART0\"\n    echo \"20) putsUART0:         will print a string on UART0\"\n    echo \"21) trainDDR2:         will run DDR2 training program\"\n    echo \"22) flashUBOOT:        will program NOR sectors 0-3 with u-boot.bin\"\n}\n\nsource [find mem_helper.tcl]\n\n# read a 64-bit register (memory mapped)\nproc mr64bit {reg} {\n    return [read_memory $reg 32 2]\n}\n\n\n# write a 64-bit register (memory mapped)\nproc mw64bit {reg value} {\n    set high [expr {$value >> 32}]\n    set low  [expr {$value & 0xffffffff}]\n    #echo [format \"mw64bit(0x%x): 0x%08x%08x\" $reg $high $low]\n    mww $reg $low\n    mww [expr {$reg+4}] $high\n}\n\n\nproc showNOR {} {\n    echo \"This is the current NOR setup\"\n    set EX_CSEN_REG\t    [regs EX_CSEN_REG ]\n    set EX_CS0_SEG_REG\t    [regs EX_CS0_SEG_REG ]\n    set EX_CS0_CFG_REG\t    [regs EX_CS0_CFG_REG ]\n    set EX_CS0_TMG1_REG\t    [regs EX_CS0_TMG1_REG ]\n    set EX_CS0_TMG2_REG\t    [regs EX_CS0_TMG2_REG ]\n    set EX_CS0_TMG3_REG\t    [regs EX_CS0_TMG3_REG ]\n    set EX_CLOCK_DIV_REG    [regs EX_CLOCK_DIV_REG ]\n    set EX_MFSM_REG\t    [regs EX_MFSM_REG ]\n    set EX_CSFSM_REG\t    [regs EX_CSFSM_REG ]\n    set EX_WRFSM_REG\t    [regs EX_WRFSM_REG ]\n    set EX_RDFSM_REG\t    [regs EX_RDFSM_REG ]\n\n    echo [format \"EX_CSEN_REG      (0x%x): 0x%x\" $EX_CSEN_REG [mrw $EX_CSEN_REG]]\n    echo [format \"EX_CS0_SEG_REG   (0x%x): 0x%x\" $EX_CS0_SEG_REG [mrw $EX_CS0_SEG_REG]]\n    echo [format \"EX_CS0_CFG_REG   (0x%x): 0x%x\" $EX_CS0_CFG_REG [mrw $EX_CS0_CFG_REG]]\n    echo [format \"EX_CS0_TMG1_REG  (0x%x): 0x%x\" $EX_CS0_TMG1_REG [mrw $EX_CS0_TMG1_REG]]\n    echo [format \"EX_CS0_TMG2_REG  (0x%x): 0x%x\" $EX_CS0_TMG2_REG [mrw $EX_CS0_TMG2_REG]]\n    echo [format \"EX_CS0_TMG3_REG  (0x%x): 0x%x\" $EX_CS0_TMG3_REG [mrw $EX_CS0_TMG3_REG]]\n    echo [format \"EX_CLOCK_DIV_REG (0x%x): 0x%x\" $EX_CLOCK_DIV_REG [mrw $EX_CLOCK_DIV_REG]]\n    echo [format \"EX_MFSM_REG      (0x%x): 0x%x\" $EX_MFSM_REG [mrw $EX_MFSM_REG]]\n    echo [format \"EX_CSFSM_REG     (0x%x): 0x%x\" $EX_CSFSM_REG [mrw $EX_CSFSM_REG]]\n    echo [format \"EX_WRFSM_REG     (0x%x): 0x%x\" $EX_WRFSM_REG [mrw $EX_WRFSM_REG]]\n    echo [format \"EX_RDFSM_REG     (0x%x): 0x%x\" $EX_RDFSM_REG [mrw $EX_RDFSM_REG]]\n}\n\n\n\nproc showGPIO {} {\n    echo \"This is the current GPIO register setup\"\n    # GPIO outputs register\n    set GPIO_OUTPUT_REG\t\t    [regs GPIO_OUTPUT_REG]\n    # GPIO Output Enable register\n    set GPIO_OE_REG\t\t    [regs GPIO_OE_REG]\n    set GPIO_HI_INT_ENABLE_REG\t    [regs GPIO_HI_INT_ENABLE_REG]\n    set GPIO_LO_INT_ENABLE_REG\t    [regs GPIO_LO_INT_ENABLE_REG]\n    # GPIO input register\n    set GPIO_INPUT_REG\t\t    [regs GPIO_INPUT_REG]\n    set APB_ACCESS_WS_REG\t    [regs APB_ACCESS_WS_REG]\n    set MUX_CONF_REG\t\t    [regs MUX_CONF_REG]\n    set SYSCONF_REG\t\t    [regs SYSCONF_REG]\n    set GPIO_ARM_ID_REG\t\t    [regs GPIO_ARM_ID_REG]\n    set GPIO_BOOTSTRAP_REG\t    [regs GPIO_BOOTSTRAP_REG]\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_DEVID_REG\t\t    [regs GPIO_DEVID_REG]\n\n    echo [format \"GPIO_OUTPUT_REG       (0x%x): 0x%x\" $GPIO_OUTPUT_REG [mrw $GPIO_OUTPUT_REG]]\n    echo [format \"GPIO_OE_REG           (0x%x): 0x%x\" $GPIO_OE_REG [mrw $GPIO_OE_REG]]\n    echo [format \"GPIO_HI_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_HI_INT_ENABLE_REG [mrw $GPIO_HI_INT_ENABLE_REG]]\n    echo [format \"GPIO_LO_INT_ENABLE_REG(0x%x): 0x%x\" $GPIO_LO_INT_ENABLE_REG [mrw $GPIO_LO_INT_ENABLE_REG]]\n    echo [format \"GPIO_INPUT_REG        (0x%x): 0x%x\" $GPIO_INPUT_REG [mrw $GPIO_INPUT_REG]]\n    echo [format \"APB_ACCESS_WS_REG     (0x%x): 0x%x\" $APB_ACCESS_WS_REG [mrw $APB_ACCESS_WS_REG]]\n    echo [format \"MUX_CONF_REG          (0x%x): 0x%x\" $MUX_CONF_REG [mrw $MUX_CONF_REG]]\n    echo [format \"SYSCONF_REG           (0x%x): 0x%x\" $SYSCONF_REG [mrw $SYSCONF_REG]]\n    echo [format \"GPIO_ARM_ID_REG       (0x%x): 0x%x\" $GPIO_ARM_ID_REG [mrw $GPIO_ARM_ID_REG]]\n    echo [format \"GPIO_BOOTSTRAP_REG    (0x%x): 0x%x\" $GPIO_BOOTSTRAP_REG [mrw $GPIO_BOOTSTRAP_REG]]\n    echo [format \"GPIO_LOCK_REG         (0x%x): 0x%x\" $GPIO_LOCK_REG [mrw $GPIO_LOCK_REG]]\n    echo [format \"GPIO_IOCTRL_REG       (0x%x): 0x%x\" $GPIO_IOCTRL_REG [mrw $GPIO_IOCTRL_REG]]\n    echo [format \"GPIO_DEVID_REG        (0x%x): 0x%x\" $GPIO_DEVID_REG [mrw $GPIO_DEVID_REG]]\n}\n\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_amba_clk())\nproc showAmbaClk {} {\n    set CFG_REFCLKFREQ\t\t     [config CFG_REFCLKFREQ]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t             [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_AHB_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_AHB_CLK_CNTRL [mrw $CLKCORE_AHB_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_AHB_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Amba PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_amba_clk())\n# this clock is useb by all peripherals (DDR2, ethernet, ebus, etc)\nproc setupAmbaClk {} {\n    set CLKCORE_PLL_STATUS           [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_AHB_CLK_CNTRL\t     [regs CLKCORE_AHB_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t    [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t    [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t    [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t    [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t    [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t    [regs DIV_BYPASS]\n    set AHBCLK_PLL_LOCK\t    [regs AHBCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t [config CFG_REFCLKFREQ]\n    set CONFIG_SYS_HZ_CLOCK      [config CONFIG_SYS_HZ_CLOCK]\n    set w    [config w_amba]\n    set x    [config x_amba]\n    set y    [config y_amba]\n\n    echo [format \"Setting Amba PLL to lock to %d MHz\" [expr {$CONFIG_SYS_HZ_CLOCK/1000000}]]\n    #echo [format \"setupAmbaClk: w= %d\" $w]\n    #echo [format \"setupAmbaClk: x= %d\" $x]\n    #echo [format \"setupAmbaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL $AHB_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_AHB_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $AHBCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $AHB_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_AHB_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_get_arm_clk())\nproc showArmClk {} {\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CLKCORE_ARM_CLK_CNTRL\t[regs CLKCORE_ARM_CLK_CNTRL]\n    set PLL_CLK_BYPASS\t        [regs PLL_CLK_BYPASS]\n\n    echo [format \"CLKCORE_ARM_CLK_CNTRL       (0x%x): 0x%x\" $CLKCORE_ARM_CLK_CNTRL [mrw $CLKCORE_ARM_CLK_CNTRL]]\n    set value [read_memory $CLKCORE_ARM_CLK_CNTRL 32 1]\n    # see if the PLL is in bypass mode\n    set bypass [expr {($value & $PLL_CLK_BYPASS) >> 24}]\n    echo [format \"PLL bypass bit: %d\" $bypass]\n    if {$bypass == 1} {\n\techo [format \"Amba Clk is set to REFCLK: %d (MHz)\" [expr {$CFG_REFCLKFREQ/1000000}]]\n    } else {\n\t# nope, extract x,y,w and compute the PLL output freq.\n\tset x [expr {($value & 0x0001F0000) >> 16}]\n\techo [format \"x: %d\" $x]\n\tset y [expr {($value & 0x00000007F)}]\n\techo [format \"y: %d\" $y]\n\tset w [expr {($value & 0x000000300) >> 8}]\n\techo [format \"w: %d\" $w]\n\techo [format \"Arm PLL Clk: %d (MHz)\" [expr {($CFG_REFCLKFREQ * $y / (($w + 1) * ($x + 1) * 2))/1000000}]]\n    }\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/bsp100.c (HAL_set_arm_clk())\n# Arm Clock is used by two ARM1136 cores\nproc setupArmClk {} {\n    set CLKCORE_PLL_STATUS        [regs CLKCORE_PLL_STATUS]\n    set CLKCORE_ARM_CLK_CNTRL\t  [regs CLKCORE_ARM_CLK_CNTRL]\n    set ARM_PLL_BY_CTRL\t          [regs ARM_PLL_BY_CTRL]\n    set ARM_AHB_BYP\t          [regs ARM_AHB_BYP]\n    set PLL_DISABLE\t          [regs PLL_DISABLE]\n    set PLL_CLK_BYPASS\t          [regs PLL_CLK_BYPASS]\n    set AHB_PLL_BY_CTRL\t          [regs AHB_PLL_BY_CTRL]\n    set DIV_BYPASS\t          [regs DIV_BYPASS]\n    set FCLK_PLL_LOCK\t          [regs FCLK_PLL_LOCK]\n    set CFG_REFCLKFREQ\t\t[config CFG_REFCLKFREQ]\n    set CFG_ARM_CLOCK\t\t[config CFG_ARM_CLOCK]\n    set w    [config w_arm]\n    set x    [config x_arm]\n    set y    [config y_arm]\n\n    echo [format \"Setting Arm PLL to lock to %d MHz\" [expr {$CFG_ARM_CLOCK/1000000}]]\n    #echo [format \"setupArmClk: w= %d\" $w]\n    #echo [format \"setupArmaClk: x= %d\" $x]\n    #echo [format \"setupArmaClk: y= %d\" $y]\n    # set PLL into BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_CLK_BYPASS 0x0\n    # do an internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL $ARM_PLL_BY_CTRL 0x0\n    # wait 500us (ARM running @24Mhz -> 12000 cycles => 500us)\n    # openocd smallest resolution is 1ms so, wait 1ms\n    sleep 1\n    # disable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL $PLL_DISABLE 0x0\n    # wait 1ms\n    sleep 1\n    # enable the PLL\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_DISABLE\n    sleep 1\n    # set X, W and X\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 0xFFFFFF\n    mmw $CLKCORE_ARM_CLK_CNTRL [expr {($x << 16) + ($w << 8) + $y}] 0x0\n    # wait for PLL to lock\n    echo \"Waiting for Amba PLL to lock\"\n    while {[expr {[mrw $CLKCORE_PLL_STATUS] & $FCLK_PLL_LOCK]} == 0} { sleep 1 }\n    # remove the internal PLL bypass\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $ARM_PLL_BY_CTRL\n    # remove PLL from BYPASS mode using MUX\n    mmw $CLKCORE_ARM_CLK_CNTRL 0x0 $PLL_CLK_BYPASS\n}\n\n\n\nproc setupPLL {} {\n    echo \"PLLs setup\"\n    setupAmbaClk\n    setupArmClk\n}\n\n# converted from u-boot/cpu/arm1136/bsp100.c:SoC_mem_init()\nproc setupDDR2 {} {\n    echo \"Configuring DDR2\"\n\n    set MEMORY_BASE_ADDR\t    [regs  MEMORY_BASE_ADDR]\n    set MEMORY_MAX_ADDR\t            [regs  MEMORY_MAX_ADDR]\n    set MEMORY_CR \t\t    [regs  MEMORY_CR]\n    set BLOCK_RESET_REG\t\t    [regs  BLOCK_RESET_REG]\n    set DDR_RST\t\t            [regs  DDR_RST]\n\n    # put DDR controller in reset (so that it is reset and correctly configured)\n    # this is only necessary if DDR was previously confiured\n    # and not reset.\n    mmw $BLOCK_RESET_REG 0x0 $DDR_RST\n\n    set M [expr {1024 * 1024}]\n    set DDR_SZ_1024M\t[expr {1024 * $M}]\n    set DDR_SZ_256M\t[expr {256 * $M}]\n    set DDR_SZ_128M\t[expr {128 * $M}]\n    set DDR_SZ_64M\t[expr {64 * $M}]\n    # ooma_board_detect returns DDR2 memory size\n    set tmp [ooma_board_detect]\n    if {$tmp == \"128M\"} {\n\techo \"DDR2 size 128MB\"\n\tset ddr_size $DDR_SZ_128M\n    } elseif {$tmp == \"256M\"} {\n\techo \"DDR2 size 256MB\"\n\tset ddr_size $DDR_SZ_256M\n    } else {\n\techo \"Don't know how to handle this DDR2 size?\"\n    }\n\n    # Memory setup register\n    mww $MEMORY_MAX_ADDR  [expr {($ddr_size - 1) + $MEMORY_BASE_ADDR}]\n    # disable ROM remap\n    mww $MEMORY_CR 0x0\n    # Take DDR controller out of reset\n    mmw $BLOCK_RESET_REG $DDR_RST 0x0\n    # min. 20 ops delay\n    sleep 1\n\n    # This will setup Denali DDR2 controller\n    if {$tmp == \"128M\"} {\n\tconfigureDDR2regs_128M\n    } elseif {$tmp == \"256M\"} {\n\tconfigureDDR2regs_256M\n    } else {\n\techo \"Don't know how to configure DDR2 setup?\"\n    }\n}\n\n\n\nproc showDDR2 {} {\n\n    set DENALI_CTL_00_DATA    [regs DENALI_CTL_00_DATA]\n    set DENALI_CTL_01_DATA    [regs DENALI_CTL_01_DATA]\n    set DENALI_CTL_02_DATA    [regs DENALI_CTL_02_DATA]\n    set DENALI_CTL_03_DATA    [regs DENALI_CTL_03_DATA]\n    set DENALI_CTL_04_DATA    [regs DENALI_CTL_04_DATA]\n    set DENALI_CTL_05_DATA    [regs DENALI_CTL_05_DATA]\n    set DENALI_CTL_06_DATA    [regs DENALI_CTL_06_DATA]\n    set DENALI_CTL_07_DATA    [regs DENALI_CTL_07_DATA]\n    set DENALI_CTL_08_DATA    [regs DENALI_CTL_08_DATA]\n    set DENALI_CTL_09_DATA    [regs DENALI_CTL_09_DATA]\n    set DENALI_CTL_10_DATA    [regs DENALI_CTL_10_DATA]\n    set DENALI_CTL_11_DATA    [regs DENALI_CTL_11_DATA]\n    set DENALI_CTL_12_DATA    [regs DENALI_CTL_12_DATA]\n    set DENALI_CTL_13_DATA    [regs DENALI_CTL_13_DATA]\n    set DENALI_CTL_14_DATA    [regs DENALI_CTL_14_DATA]\n    set DENALI_CTL_15_DATA    [regs DENALI_CTL_15_DATA]\n    set DENALI_CTL_16_DATA    [regs DENALI_CTL_16_DATA]\n    set DENALI_CTL_17_DATA    [regs DENALI_CTL_17_DATA]\n    set DENALI_CTL_18_DATA    [regs DENALI_CTL_18_DATA]\n    set DENALI_CTL_19_DATA    [regs DENALI_CTL_19_DATA]\n    set DENALI_CTL_20_DATA    [regs DENALI_CTL_20_DATA]\n\n    set tmp [mr64bit $DENALI_CTL_00_DATA]\n    echo [format \"DENALI_CTL_00_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_00_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_01_DATA]\n    echo [format \"DENALI_CTL_01_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_01_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_02_DATA]\n    echo [format \"DENALI_CTL_02_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_02_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_03_DATA]\n    echo [format \"DENALI_CTL_03_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_03_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_04_DATA]\n    echo [format \"DENALI_CTL_04_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_04_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_05_DATA]\n    echo [format \"DENALI_CTL_05_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_05_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_06_DATA]\n    echo [format \"DENALI_CTL_06_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_06_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_07_DATA]\n    echo [format \"DENALI_CTL_07_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_07_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_08_DATA]\n    echo [format \"DENALI_CTL_08_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_08_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_09_DATA]\n    echo [format \"DENALI_CTL_09_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_09_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_10_DATA]\n    echo [format \"DENALI_CTL_10_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_10_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_11_DATA]\n    echo [format \"DENALI_CTL_11_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_11_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_12_DATA]\n    echo [format \"DENALI_CTL_12_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_12_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_13_DATA]\n    echo [format \"DENALI_CTL_13_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_13_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_14_DATA]\n    echo [format \"DENALI_CTL_14_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_14_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_15_DATA]\n    echo [format \"DENALI_CTL_15_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_15_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_16_DATA]\n    echo [format \"DENALI_CTL_16_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_16_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_17_DATA]\n    echo [format \"DENALI_CTL_17_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_17_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_18_DATA]\n    echo [format \"DENALI_CTL_18_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_18_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_19_DATA]\n    echo [format \"DENALI_CTL_19_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_19_DATA $tmp(1) $tmp(0)]\n    set tmp [mr64bit $DENALI_CTL_20_DATA]\n    echo [format \"DENALI_CTL_20_DATA   (0x%x): 0x%08x%08x\" $DENALI_CTL_20_DATA $tmp(1) $tmp(0)]\n\n}\n\nproc initC100 {} {\n    # this follows u-boot/cpu/arm1136/start.S\n    set GPIO_LOCK_REG\t\t    [regs GPIO_LOCK_REG]\n    set GPIO_IOCTRL_REG\t\t    [regs GPIO_IOCTRL_REG]\n    set GPIO_IOCTRL_VAL\t            [regs GPIO_IOCTRL_VAL]\n    set APB_ACCESS_WS_REG           [regs APB_ACCESS_WS_REG]\n    set ASA_ARAM_BASEADDR\t    [regs ASA_ARAM_BASEADDR]\n    set ASA_ARAM_TC_CR_REG\t    [regs ASA_ARAM_TC_CR_REG]\n    set ASA_EBUS_BASEADDR\t    [regs ASA_EBUS_BASEADDR]\n    set ASA_EBUS_TC_CR_REG\t    [regs ASA_EBUS_TC_CR_REG]\n    set ASA_TC_REQIDMAEN\t    [regs ASA_TC_REQIDMAEN]\n    set ASA_TC_REQTDMEN\t            [regs ASA_TC_REQTDMEN]\n    set ASA_TC_REQIPSECUSBEN        [regs ASA_TC_REQIPSECUSBEN]\n    set ASA_TC_REQARM0EN\t    [regs ASA_TC_REQARM0EN]\n    set ASA_TC_REQARM1EN\t    [regs ASA_TC_REQARM1EN]\n    set ASA_TC_REQMDMAEN\t    [regs ASA_TC_REQMDMAEN]\n    set INTC_ARM1_CONTROL_REG       [regs INTC_ARM1_CONTROL_REG]\n\n\n    # unlock writing to IOCTRL register\n    mww $GPIO_LOCK_REG $GPIO_IOCTRL_VAL\n    # enable address lines A15-A21\n    mmw $GPIO_IOCTRL_REG 0xf 0x0\n    # set ARM into supervisor mode (SVC32)\n    # disable IRQ, FIQ\n    # Do I need this in JTAG mode?\n    # it really should be done as 'and ~0x1f | 0xd3 but\n    # openocd does not support this yet\n    reg cpsr 0xd3\n    #\t/*\n    #\t * flush v4 I/D caches\n    #\t */\n    #\tmov\tr0, #0\n    #\tmcr\tp15, 0, r0, c7, c7, 0\t/* flush v3/v4 cache */\n    arm mcr 15 0 7 7 0 0x0\n    #\tmcr\tp15, 0, r0, c8, c7, 0\t/* flush v4 TLB */\n    arm mcr 15 0 8 7 0 0x0\n\n    #\t/*\n    #\t * disable MMU stuff and caches\n    #\t */\n    #\tmrc\tp15, 0, r0, c1, c0, 0\n    arm mrc 15 0 1 0 0\n    #\tbic\tr0, r0, #0x00002300\t@ clear bits 13, 9:8 (--V- --RS)\n    #\tbic\tr0, r0, #0x00000087\t@ clear bits 7, 2:0 (B--- -CAM)\n    #\torr\tr0, r0, #0x00000002\t@ set bit 2 (A) Align\n    #\torr\tr0, r0, #0x00001000\t@ set bit 12 (I) I-Cache\n    #\torr\tr0, r0, #0x00400000\t@ set bit 22 (U)\n    #\tmcr\tp15, 0, r0, c1, c0, 0\n    arm mcr 15 0 1 0 0 0x401002\n    # This is from bsp_init() in u-boot/boards/mindspeed/ooma-darwin/board.c\n    # APB init\n    #    \t// Setting APB Bus Wait states to 1, set post write\n    #\t(*(volatile u32*)(APB_ACCESS_WS_REG)) = 0x40;\n    mww $APB_ACCESS_WS_REG 0x40\n    # AHB init\n    #\t// enable all 6 masters for ARAM\n    mmw $ASA_ARAM_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n    #\t// enable all 6 masters for EBUS\n    mmw $ASA_EBUS_TC_CR_REG [expr {$ASA_TC_REQIDMAEN | $ASA_TC_REQTDMEN | $ASA_TC_REQIPSECUSBEN | $ASA_TC_REQARM0EN | $ASA_TC_REQARM1EN | $ASA_TC_REQMDMAEN}] 0x0\n\n    # ARAM init\n    #\t// disable pipeline mode in ARAM\n    # I don't think this is documented anywhere?\n    mww $INTC_ARM1_CONTROL_REG 0x1\n    # configure clocks\n    setupPLL\n    # setupUART0 must be run before setupDDR2 as setupDDR2 uses UART.\n    setupUART0\n    # enable cache\n    # ? (u-boot does nothing here)\n    # DDR2 memory init\n    setupDDR2\n    putsUART0 \"C100 initialization complete.\\n\"\n    echo \"C100 initialization complete.\"\n}\n\n# show current state of watchdog timer\nproc showWatchdog {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    echo [format \"TIMER_WDT_HIGH_BOUND    (0x%x): 0x%x\" $TIMER_WDT_HIGH_BOUND [mrw $TIMER_WDT_HIGH_BOUND]]\n    echo [format \"TIMER_WDT_CONTROL       (0x%x): 0x%x\" $TIMER_WDT_CONTROL [mrw $TIMER_WDT_CONTROL]]\n    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n}\n\n# converted from u-boot/cpu/arm1136/comcerto/intrrupts.c:void reset_cpu (ulong ignored)\n# this will trigger watchdog reset\n# the sw. reset does not work on C100\n# watchdog reset effectively works as hw. reset\nproc reboot {} {\n    set TIMER_WDT_HIGH_BOUND\t[regs TIMER_WDT_HIGH_BOUND]\n    set TIMER_WDT_CONTROL\t[regs TIMER_WDT_CONTROL]\n    set TIMER_WDT_CURRENT_COUNT\t[regs TIMER_WDT_CURRENT_COUNT]\n\n    # allow the counter to count to high value  before triggering\n    # this is because register writes are slow over JTAG and\n    # I don't want to miss the high_bound==curr_count condition\n    mww $TIMER_WDT_HIGH_BOUND  0xffffff\n    mww $TIMER_WDT_CURRENT_COUNT 0x0\n    echo \"JTAG speed lowered to 100kHz\"\n    adapter speed 100\n    mww $TIMER_WDT_CONTROL 0x1\n    # wait until the reset\n    echo -n \"Waiting for watchdog to trigger...\"\n    #while {[mrw $TIMER_WDT_CONTROL] == 1} {\n    #    echo [format \"TIMER_WDT_CURRENT_COUNT (0x%x): 0x%x\" $TIMER_WDT_CURRENT_COUNT [mrw $TIMER_WDT_CURRENT_COUNT]]\n    #    sleep 1\n    #\n    #}\n    while {[c100.cpu curstate] != \"running\"} { sleep 1}\n    echo \"done.\"\n    echo [format \"Note that C100 is in %s state, type halt to stop\" [c100.cpu curstate]]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/c100regs.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Note that I basically converted\n# u-boot/include/asm-arm/arch/comcerto_100.h\n# defines\n\n# this is a work-around for 'global' not working under Linux\n# access registers by calling this routine.\n# For example:\n# set EX_CS_TMG1_REG [regs EX_CS0_TMG1_REG]\nproc regs {reg} {\n    return [dict get [regsC100] $reg ]\n}\n\nproc showreg {reg} {\n    echo [format \"0x%x\" [dict get [regsC100] $reg ]]\n}\n\nproc regsC100 {} {\n#/* memcore */\n#/* device memory base addresses */\n#// device memory sizes\n#/* ARAM SIZE=64K */\ndict set regsC100 ARAM_SIZE\t\t0x00010000\ndict set regsC100 ARAM_BASEADDR\t0x0A000000\n\n#/* Hardware Interface Units */\ndict set regsC100 APB_BASEADDR\t0x10000000\n#/* APB_SIZE=16M address range */\ndict set regsC100 APB_SIZE\t\t0x01000000\n\ndict set regsC100 EXP_CS0_BASEADDR       0x20000000\ndict set regsC100 EXP_CS1_BASEADDR       0x24000000\ndict set regsC100 EXP_CS2_BASEADDR       0x28000000\ndict set regsC100 EXP_CS3_BASEADDR       0x2C000000\ndict set regsC100 EXP_CS4_BASEADDR       0x30000000\n\ndict set regsC100 DDR_BASEADDR           0x80000000\n\ndict set regsC100 TDM_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x000000}]\ndict set regsC100 PHI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x010000}]\ndict set regsC100 TDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x020000}]\ndict set regsC100 ASA_DDR_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x040000}]\ndict set regsC100 ASA_ARAM_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x048000}]\ndict set regsC100 TIMER_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x050000}]\ndict set regsC100 ASD_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x060000}]\ndict set regsC100 GPIO_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x070000}]\ndict set regsC100 UART0_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x090000}]\ndict set regsC100 UART1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x094000}]\ndict set regsC100 SPI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x098000}]\ndict set regsC100 I2C_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x09C000}]\ndict set regsC100 INTC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0A0000}]\ndict set regsC100 CLKCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 PUI_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0B0000}]\ndict set regsC100 GEMAC_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0D0000}]\ndict set regsC100 IDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x0E0000}]\ndict set regsC100 MEMCORE_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x0F0000}]\ndict set regsC100 ASA_EBUS_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x100000}]\ndict set regsC100 ASA_AAB_BASEADDR\t        [expr {[dict get $regsC100 APB_BASEADDR ] + 0x108000}]\ndict set regsC100 GEMAC1_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x190000}]\ndict set regsC100 EBUS_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1A0000}]\ndict set regsC100 MDMA_BASEADDR\t\t[expr {[dict get $regsC100 APB_BASEADDR ] + 0x1E0000}]\n\n\n#////////////////////////////////////////////////////////////\n#//\tAHB block\t\t\t\t\t\t\t\t\t\t\t    //\n#////////////////////////////////////////////////////////////\ndict set regsC100 ASA_ARAM_PRI_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_ARAM_TC_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_ARAM_TC_CR_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_ARAM_STAT_REG\t[expr {[dict get $regsC100 ASA_ARAM_BASEADDR ] + 0x0C}]\n\ndict set regsC100 ASA_EBUS_PRI_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 ASA_EBUS_TC_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 ASA_EBUS_TC_CR_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 ASA_EBUS_STAT_REG\t[expr {[dict get $regsC100 ASA_EBUS_BASEADDR ] + 0x0C}]\n\ndict set regsC100 IDMA_MASTER\t\t0\ndict set regsC100 TDMA_MASTER\t\t1\ndict set regsC100 USBIPSEC_MASTER\t2\ndict set regsC100 ARM0_MASTER\t\t3\ndict set regsC100 ARM1_MASTER\t\t4\ndict set regsC100 MDMA_MASTER\t\t5\n\n#define IDMA_PRIORITY(level) (level)\n#define TDM_PRIORITY(level) (level << 4)\n#define USBIPSEC_PRIORITY(level) (level << 8)\n#define ARM0_PRIORITY(level) (level << 12)\n#define ARM1_PRIORITY(level) (level << 16)\n#define MDMA_PRIORITY(level) (level << 20)\n\ndict set regsC100 ASA_TC_REQIDMAEN\t [expr {1<<18}]\ndict set regsC100 ASA_TC_REQTDMEN\t [expr {1<<19}]\ndict set regsC100 ASA_TC_REQIPSECUSBEN [expr {1<<20}]\ndict set regsC100 ASA_TC_REQARM0EN\t [expr {1<<21}]\ndict set regsC100 ASA_TC_REQARM1EN\t [expr {1<<22}]\ndict set regsC100 ASA_TC_REQMDMAEN\t [expr {1<<23}]\n\ndict set regsC100 MEMORY_BASE_ADDR\t0x80000000\ndict set regsC100 MEMORY_MAX_ADDR\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x10}]\ndict set regsC100 MEMORY_CR \t\t[expr {[dict get $regsC100 ASD_BASEADDR ] + 0x14}]\ndict set regsC100 ROM_REMAP_EN\t0x1\n\n#define HAL_asb_priority(level) \\\n#*(volatile unsigned *)ASA_PRI_REG = level\n\n#define HAL_aram_priority(level) \\\n#*(volatile unsigned *)ASA_ARAM_PRI_REG = level\n\n#define HAL_aram_arbitration(arbitration_mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG |= arbitration_mask\n\n#define HAL_aram_defmaster(mask) \\\n#*(volatile unsigned *)ASA_ARAM_TC_CR_REG = (*(volatile unsigned *)ASA_TC_CR_REG & 0xFFFF) | (mask << 24)\n\n#////////////////////////////////////////////////////////////\n#// INTC block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 INTC_ARM1_CONTROL_REG\t[expr {[dict get $regsC100 INTC_BASEADDR ] + 0x18}]\n\n#////////////////////////////////////////////////////////////\n#// TIMER block\t\t\t\t\t\t  //\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 TIMER0_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x00}]\ndict set regsC100 TIMER0_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x04}]\ndict set regsC100 TIMER1_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x08}]\ndict set regsC100 TIMER1_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x0C}]\n\ndict set regsC100 TIMER2_CNTR_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x18}]\ndict set regsC100 TIMER2_LBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x10}]\ndict set regsC100 TIMER2_HBOUND_REG\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x14}]\ndict set regsC100 TIMER2_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x1C}]\n\ndict set regsC100 TIMER3_LOBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x20}]\ndict set regsC100 TIMER3_HIBND\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x24}]\ndict set regsC100 TIMER3_CTRL\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x28}]\ndict set regsC100 TIMER3_CURR_COUNT\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x2C}]\n\ndict set regsC100 TIMER_MASK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x40}]\ndict set regsC100 TIMER_STATUS\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_ACK\t\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0x50}]\ndict set regsC100 TIMER_WDT_HIGH_BOUND [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD0}]\ndict set regsC100 TIMER_WDT_CONTROL\t[expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD4}]\ndict set regsC100 TIMER_WDT_CURRENT_COUNT [expr {[dict get $regsC100 TIMER_BASEADDR ] + 0xD8}]\n\n\n\n#////////////////////////////////////////////////////////////\n#//  EBUS block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 EX_SWRST_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x00}]\ndict set regsC100 EX_CSEN_REG\t\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x04}]\ndict set regsC100 EX_CS0_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x08}]\ndict set regsC100 EX_CS1_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x0C}]\ndict set regsC100 EX_CS2_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x10}]\ndict set regsC100 EX_CS3_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x14}]\ndict set regsC100 EX_CS4_SEG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x18}]\ndict set regsC100 EX_CS0_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x1C}]\ndict set regsC100 EX_CS1_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x20}]\ndict set regsC100 EX_CS2_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x24}]\ndict set regsC100 EX_CS3_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x28}]\ndict set regsC100 EX_CS4_CFG_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x2C}]\ndict set regsC100 EX_CS0_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x30}]\ndict set regsC100 EX_CS1_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x34}]\ndict set regsC100 EX_CS2_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x38}]\ndict set regsC100 EX_CS3_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x3C}]\ndict set regsC100 EX_CS4_TMG1_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x40}]\ndict set regsC100 EX_CS0_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x44}]\ndict set regsC100 EX_CS1_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x48}]\ndict set regsC100 EX_CS2_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x4C}]\ndict set regsC100 EX_CS3_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x50}]\ndict set regsC100 EX_CS4_TMG2_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x54}]\ndict set regsC100 EX_CS0_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x58}]\ndict set regsC100 EX_CS1_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x5C}]\ndict set regsC100 EX_CS2_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x60}]\ndict set regsC100 EX_CS3_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x64}]\ndict set regsC100 EX_CS4_TMG3_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x68}]\ndict set regsC100 EX_CLOCK_DIV_REG\t        [expr {[dict get $regsC100 EBUS_BASEADDR ] + 0x6C}]\n\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_MFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x100}]\ndict set regsC100 EX_CSFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x104}]\ndict set regsC100 EX_WRFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x108}]\ndict set regsC100 EX_RDFSM_REG\t\t[expr {[dict get $regsC100 EBUS_BASEADDR] + 0x10C}]\n\n\ndict set regsC100 EX_CLK_EN\t\t0x00000001\ndict set regsC100 EX_CSBOOT_EN\t0x00000002\ndict set regsC100 EX_CS0_EN\t\t0x00000002\ndict set regsC100 EX_CS1_EN\t\t0x00000004\ndict set regsC100 EX_CS2_EN\t\t0x00000008\ndict set regsC100 EX_CS3_EN\t\t0x00000010\ndict set regsC100 EX_CS4_EN\t\t0x00000020\n\ndict set regsC100 EX_MEM_BUS_8\t0x00000000\ndict set regsC100 EX_MEM_BUS_16       0x00000002\ndict set regsC100 EX_MEM_BUS_32\t0x00000004\ndict set regsC100 EX_CS_HIGH\t\t0x00000008\ndict set regsC100 EX_WE_HIGH\t\t0x00000010\ndict set regsC100 EX_RE_HIGH\t\t0x00000020\ndict set regsC100 EX_ALE_MODE\t\t0x00000040\ndict set regsC100 EX_STRB_MODE\t0x00000080\ndict set regsC100 EX_DM_MODE\t\t0x00000100\ndict set regsC100 EX_NAND_MODE\t0x00000200\ndict set regsC100 EX_RDY_EN\t\t0x00000400\ndict set regsC100 EX_RDY_EDGE\t\t0x00000800\n\n#////////////////////////////////////////////////////////////\n#//  GPIO block\n#////////////////////////////////////////////////////////////\n\n# GPIO outputs register\ndict set regsC100 GPIO_OUTPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x00}]\n# GPIO Output Enable register\ndict set regsC100 GPIO_OE_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x04}]\ndict set regsC100 GPIO_HI_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x08}]\ndict set regsC100 GPIO_LO_INT_ENABLE_REG\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x0C}]\n# GPIO input register\ndict set regsC100 GPIO_INPUT_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x10}]\ndict set regsC100 APB_ACCESS_WS_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x14}]\ndict set regsC100 MUX_CONF_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x18}]\ndict set regsC100 SYSCONF_REG\t\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x1C}]\ndict set regsC100 GPIO_ARM_ID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x30}]\ndict set regsC100 GPIO_BOOTSTRAP_REG\t        [expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x40}]\ndict set regsC100 GPIO_LOCK_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x38}]\ndict set regsC100 GPIO_IOCTRL_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x44}]\ndict set regsC100 GPIO_DEVID_REG\t\t[expr {[dict get $regsC100 GPIO_BASEADDR ] + 0x50}]\n\ndict set regsC100 GPIO_IOCTRL_A15A16\t0x00000001\ndict set regsC100 GPIO_IOCTRL_A17A18\t0x00000002\ndict set regsC100 GPIO_IOCTRL_A19A21\t0x00000004\ndict set regsC100 GPIO_IOCTRL_TMREVT0\t0x00000008\ndict set regsC100 GPIO_IOCTRL_TMREVT1\t0x00000010\ndict set regsC100 GPIO_IOCTRL_GPBT3\t0x00000020\ndict set regsC100 GPIO_IOCTRL_I2C\t0x00000040\ndict set regsC100 GPIO_IOCTRL_UART0\t0x00000080\ndict set regsC100 GPIO_IOCTRL_UART1\t0x00000100\ndict set regsC100 GPIO_IOCTRL_SPI\t0x00000200\ndict set regsC100 GPIO_IOCTRL_HBMODE\t0x00000400\n\ndict set regsC100 GPIO_IOCTRL_VAL\t0x55555555\n\ndict set regsC100 GPIO_0\t\t\t0x01\ndict set regsC100 GPIO_1\t\t\t0x02\ndict set regsC100 GPIO_2\t\t\t0x04\ndict set regsC100 GPIO_3\t\t\t0x08\ndict set regsC100 GPIO_4\t\t\t0x10\ndict set regsC100 GPIO_5\t\t\t0x20\ndict set regsC100 GPIO_6\t\t\t0x40\ndict set regsC100 GPIO_7\t\t\t0x80\n\ndict set regsC100 GPIO_RISING_EDGE\t1\ndict set regsC100 GPIO_FALLING_EDGE\t2\ndict set regsC100 GPIO_BOTH_EDGES\t3\n\n#////////////////////////////////////////////////////////////\n#// UART\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 UART0_RBR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_THR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_DLL\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x00}]\ndict set regsC100 UART0_IER\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_DLH\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x04}]\ndict set regsC100 UART0_IIR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_FCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x08}]\ndict set regsC100 UART0_LCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x0C}]\ndict set regsC100 UART0_MCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x10}]\ndict set regsC100 UART0_LSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x14}]\ndict set regsC100 UART0_MSR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x18}]\ndict set regsC100 UART0_SCR\t\t[expr {[dict get $regsC100 UART0_BASEADDR ] + 0x1C}]\n\ndict set regsC100 UART1_RBR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_THR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_DLL\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x00}]\ndict set regsC100 UART1_IER\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_DLH\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x04}]\ndict set regsC100 UART1_IIR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_FCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x08}]\ndict set regsC100 UART1_LCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x0C}]\ndict set regsC100 UART1_MCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x10}]\ndict set regsC100 UART1_LSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x14}]\ndict set regsC100 UART1_MSR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x18}]\ndict set regsC100 UART1_SCR\t\t[expr {[dict get $regsC100 UART1_BASEADDR ] + 0x1C}]\n\n# /* default */\ndict set regsC100 LCR_CHAR_LEN_5\t\t0x00\ndict set regsC100 LCR_CHAR_LEN_6\t\t0x01\ndict set regsC100 LCR_CHAR_LEN_7\t\t0x02\ndict set regsC100 LCR_CHAR_LEN_8\t\t0x03\n#/* One stop bit! - default */\ndict set regsC100 LCR_ONE_STOP\t\t0x00\n#/* Two stop bit! */\ndict set regsC100 LCR_TWO_STOP\t\t0x04\n#/* Parity Enable */\ndict set regsC100 LCR_PEN\t\t\t0x08\ndict set regsC100 LCR_PARITY_NONE\t\t0x00\n#/* Even Parity Select */\ndict set regsC100 LCR_EPS\t\t\t0x10\n#/* Enable Parity  Stuff */\ndict set regsC100 LCR_PS\t\t\t0x20\n#/* Start Break */\ndict set regsC100 LCR_SBRK\t\t        0x40\n#/* Parity Stuff Bit */\ndict set regsC100 LCR_PSB\t\t\t0x80\n#/* UART 16550 Divisor Latch Assess */\ndict set regsC100 LCR_DLAB\t\t        0x80\n\n#/* FIFO Error Status */\ndict set regsC100 LSR_FIFOE\t\t[expr {1 << 7}]\n#/* Transmitter Empty */\ndict set regsC100 LSR_TEMT\t\t[expr {1 << 6}]\n#/* Transmit Data Request */\ndict set regsC100 LSR_TDRQ\t\t[expr {1 << 5}]\n#/* Break Interrupt */\ndict set regsC100 LSR_BI\t\t\t[expr {1 << 4}]\n#/* Framing Error */\ndict set regsC100 LSR_FE\t\t\t[expr {1 << 3}]\n#/* Parity Error */\ndict set regsC100 LSR_PE\t\t\t[expr {1 << 2}]\n#/* Overrun Error */\ndict set regsC100 LSR_OE\t\t\t[expr {1 << 1}]\n#/* Data Ready */\ndict set regsC100 LSR_DR\t\t\t[expr {1 << 0}]\n\n#/* DMA Requests Enable */\ndict set regsC100 IER_DMAE\t\t        [expr {1 << 7}]\n#/* UART Unit Enable */\ndict set regsC100 IER_UUE\t\t\t[expr {1 << 6}]\n#/* NRZ coding Enable */\ndict set regsC100 IER_NRZE\t\t        [expr {1 << 5}]\n#/* Receiver Time Out Interrupt Enable */\ndict set regsC100 IER_RTIOE\t\t        [expr {1 << 4}]\n#/* Modem Interrupt Enable */\ndict set regsC100 IER_MIE\t\t\t[expr {1 << 3}]\n#/* Receiver Line Status Interrupt Enable */\ndict set regsC100 IER_RLSE\t\t        [expr {1 << 2}]\n#/* Transmit Data request Interrupt Enable */\ndict set regsC100 IER_TIE\t\t\t[expr {1 << 1}]\n#/* Receiver Data Available Interrupt Enable */\ndict set regsC100 IER_RAVIE\t\t        [expr {1 << 0}]\n\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES1\t\t        [expr {1 << 7}]\n#/* FIFO Mode Enable Status */\ndict set regsC100 IIR_FIFOES0\t\t        [expr {1 << 6}]\n#/* Time Out Detected */\ndict set regsC100 IIR_TOD\t\t\t[expr {1 << 3}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID2\t\t        [expr {1 << 2}]\n#/* Interrupt Source Encoded */\ndict set regsC100 IIR_IID1\t\t        [expr {1 << 1}]\n#/* Interrupt Pending (active low) */\ndict set regsC100 IIR_IP\t\t\t[expr {1 << 0}]\n\n#/* UART 16550 FIFO Control Register */\ndict set regsC100 FCR_FIFOEN\t\t0x01\ndict set regsC100 FCR_RCVRRES\t\t0x02\ndict set regsC100 FCR_XMITRES\t\t0x04\n\n#/* Interrupt Enable Register */\n#// UART 16550\n#// Enable Received Data Available Interrupt\ndict set regsC100 IER_RXTH\t\t0x01\n#// Enable Transmitter Empty Interrupt\ndict set regsC100 IER_TXTH\t\t0x02\n\n\n\n#////////////////////////////////////////////////////////////\n#// CLK  + RESET block\n#////////////////////////////////////////////////////////////\n\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x00}]\ndict set regsC100 CLKCORE_AHB_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x04}]\ndict set regsC100 CLKCORE_PLL_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x08}]\ndict set regsC100 CLKCORE_CLKDIV_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x0C}]\ndict set regsC100 CLKCORE_TDM_CLK_CNTRL\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x10}]\ndict set regsC100 CLKCORE_FSYNC_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x14}]\ndict set regsC100 CLKCORE_CLK_PWR_DWN\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x18}]\ndict set regsC100 CLKCORE_RNG_CNTRL\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x1C}]\ndict set regsC100 CLKCORE_RNG_STATUS\t        [expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x20}]\ndict set regsC100 CLKCORE_ARM_CLK_CNTRL2\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x24}]\ndict set regsC100 CLKCORE_TDM_REF_DIV_RST\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x40}]\n\ndict set regsC100 ARM_PLL_BY_CTRL\t0x80000000\ndict set regsC100 ARM_AHB_BYP\t\t0x04000000\ndict set regsC100 PLL_DISABLE\t\t0x02000000\ndict set regsC100 PLL_CLK_BYPASS\t0x01000000\n\ndict set regsC100 AHB_PLL_BY_CTRL\t0x80000000\ndict set regsC100 DIV_BYPASS\t\t0x40000000\ndict set regsC100 SYNC_MODE\t\t0x20000000\n\ndict set regsC100 EPHY_CLKDIV_BYPASS\t0x00200000\ndict set regsC100 EPHY_CLKDIV_RATIO_SHIFT\t16\ndict set regsC100 PUI_CLKDIV_BYPASS\t0x00004000\ndict set regsC100 PUI_CLKDIV_SRCCLK\t0x00002000\ndict set regsC100 PUI_CLKDIV_RATIO_SHIFT\t8\ndict set regsC100 PCI_CLKDIV_BYPASS\t0x00000020\ndict set regsC100 PCI_CLKDIV_RATIO_SHIFT\t0\n\ndict set regsC100 ARM0_CLK_PD\t\t0x00200000\ndict set regsC100 ARM1_CLK_PD\t\t0x00100000\ndict set regsC100 EPHY_CLK_PD\t\t0x00080000\ndict set regsC100 TDM_CLK_PD\t\t0x00040000\ndict set regsC100 PUI_CLK_PD\t\t0x00020000\ndict set regsC100 PCI_CLK_PD\t\t0x00010000\ndict set regsC100 MDMA_AHBCLK_PD\t0x00000400\ndict set regsC100 I2CSPI_AHBCLK_PD\t0x00000200\ndict set regsC100 UART_AHBCLK_PD\t0x00000100\ndict set regsC100 IPSEC_AHBCLK_PD\t0x00000080\ndict set regsC100 TDM_AHBCLK_PD\t0x00000040\ndict set regsC100 USB1_AHBCLK_PD\t0x00000020\ndict set regsC100 USB0_AHBCLK_PD\t0x00000010\ndict set regsC100 GEMAC1_AHBCLK_PD\t0x00000008\ndict set regsC100 GEMAC0_AHBCLK_PD\t0x00000004\ndict set regsC100 PUI_AHBCLK_PD\t0x00000002\ndict set regsC100 HIF_AHBCLK_PD\t0x00000001\n\ndict set regsC100 ARM1_DIV_BP\t\t0x00001000\ndict set regsC100 ARM1_DIV_VAL_SHIFT\t8\ndict set regsC100 ARM0_DIV_BP\t\t0x00000010\ndict set regsC100 ARM0_DIV_VAL_SHIFT\t0\n\ndict set regsC100 AHBCLK_PLL_LOCK\t0x00000002\ndict set regsC100 FCLK_PLL_LOCK\t0x00000001\n\n\n#// reset block\ndict set regsC100 BLOCK_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x100}]\ndict set regsC100 CSP_RESET_REG\t\t[expr {[dict get $regsC100 CLKCORE_BASEADDR ] + 0x104}]\n\ndict set regsC100 RNG_RST\t\t0x1000\ndict set regsC100 IPSEC_RST\t\t0x0800\ndict set regsC100 DDR_RST\t\t0x0400\ndict set regsC100 USB1_PHY_RST\t0x0200\ndict set regsC100 USB0_PHY_RST\t0x0100\ndict set regsC100 USB1_RST\t\t0x0080\ndict set regsC100 USB0_RST\t\t0x0040\ndict set regsC100 GEMAC1_RST\t\t0x0020\ndict set regsC100 GEMAC0_RST\t\t0x0010\ndict set regsC100 TDM_RST\t\t0x0008\ndict set regsC100 PUI_RST\t\t0x0004\ndict set regsC100 HIF_RST\t\t0x0002\ndict set regsC100 PCI_RST\t\t0x0001\n\n#////////////////////////////////////////////////////////////////\n#//\tDDR  CONTROLLER block\n#////////////////////////////////////////////////////////////////\n\ndict set regsC100 DDR_CONFIG_BASEADDR\t0x0D000000\ndict set regsC100 DENALI_CTL_00_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x00}]\ndict set regsC100 DENALI_CTL_01_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x08}]\ndict set regsC100 DENALI_CTL_02_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x10}]\ndict set regsC100 DENALI_CTL_03_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x18}]\ndict set regsC100 DENALI_CTL_04_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x20}]\ndict set regsC100 DENALI_CTL_05_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x28}]\ndict set regsC100 DENALI_CTL_06_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x30}]\ndict set regsC100 DENALI_CTL_07_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x38}]\ndict set regsC100 DENALI_CTL_08_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x40}]\ndict set regsC100 DENALI_CTL_09_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x48}]\ndict set regsC100 DENALI_CTL_10_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x50}]\ndict set regsC100 DENALI_CTL_11_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x58}]\ndict set regsC100 DENALI_CTL_12_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x60}]\ndict set regsC100 DENALI_CTL_13_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x68}]\ndict set regsC100 DENALI_CTL_14_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x70}]\ndict set regsC100 DENALI_CTL_15_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x78}]\ndict set regsC100 DENALI_CTL_16_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x80}]\ndict set regsC100 DENALI_CTL_17_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x88}]\ndict set regsC100 DENALI_CTL_18_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x90}]\ndict set regsC100 DENALI_CTL_19_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x98}]\ndict set regsC100 DENALI_CTL_20_DATA\t[expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0xA0}]\n\n# 32-bit value\ndict set regsC100 DENALI_READY_CHECK         [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x44}]\n# 8-bit\ndict set regsC100 DENALI_WR_DQS              [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5D}]\n# 8-bit\ndict set regsC100 DENALI_DQS_OUT             [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x5A}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY0          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] + 0x4F}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY1          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x50}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY2          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x51}]\n# 8-bit\ndict set regsC100 DENALI_DQS_DELAY3          [expr {[dict get $regsC100 DDR_CONFIG_BASEADDR ] +0x52}]\n\n\n# end of proc regsC100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/cc2538.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config for Texas Instruments low power RF SoC CC2538\n# http://www.ti.com/lit/pdf/swru319\n\nadapter speed 100\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc2538\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x8B96402F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n# A start sequence is needed to change from cJTAG (Compact JTAG) to\n# 4-pin JTAG before talking via JTAG commands\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\n#\n# Cortex-M3 target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/cs351x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME cs351x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00526fa1\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME fa526 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# There is 16K of SRAM on this chip\n# FIXME: flash programming is not working by using this work area. So comment this out for now.\n#$_TARGETNAME configure -work-area-phys 0x00000000 -work-area-size 0x4000 -work-area-backup 1\n\n# This chip has a DCC ... use it\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/davinci.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Utility code for DaVinci-family chips\n#\n\n# davinci_pinmux: assigns PINMUX$reg <== $value\nproc davinci_pinmux {soc reg value} {\n\tmww [expr {[dict get $soc sysbase] + 4 * $reg}] $value\n}\n\nsource [find mem_helper.tcl]\n\n#\n# pll_setup: initialize PLL\n#  - pll_addr ... physical addr of controller\n#  - mult ... pll multiplier\n#  - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers\n#\n# For PLLs that don't have a given register (e.g. plldiv8), or where a\n# given divider is non-programmable, caller provides *NO* config mapping.\n#\n\n# PLL version 0x02: tested on dm355\n# REVISIT: On dm6446/dm357 the PLLRST polarity is different.\nproc pll_v02_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - clear CLKMODE (bit 8) iff using on-chip oscillator\n\t# NOTE: this assumes we should clear that bit\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0100}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 4 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 5 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 6 - set PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 7 - clear PLLPWRDN (bit 1)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 8 - clear PLLDIS (bit 4)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0010}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\t# NOTE: for dm355 PLL1, postdiv is controlled via MISC register\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult - 1) & 0xff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - optional: set plldiv1, plldiv2, ...\n\t# NOTE:  this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\t#\t- ALNCTL has everything set\n\tset go 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset go 1\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset go 1\n\t}\n\tif {$go != 0} {\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\n\t# 11 - wait at least 5 usec for reset to finish\n\t# (assume covered by overheads including JTAG messaging)\n\n\t# 12 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 13 - wait at least 8000 refclk cycles for PLL to lock\n\t# if we assume 24 MHz (slowest osc), that's 1/3 msec\n\tsleep 3\n\n\t# 14 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# PLL version 0x03: tested on dm365\nproc pll_v03_setup {pll_addr mult config} {\n\tset pll_ctrl_addr [expr {$pll_addr + 0x100}]\n\tset pll_secctrl_addr [expr {$pll_addr + 0x108}]\n\tset pll_ctrl [mrw $pll_ctrl_addr]\n\n\t# 1 - power up the PLL\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0002}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLENSRC (bit 5)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0020}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 2 - clear PLLEN (bit 0) ... enter bypass mode\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 3 - wait at least 4 refclk cycles\n\tsleep 1\n\n\t# 4 - set PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl | 0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 5 - wait at least 5 usec\n\tsleep 1\n\n\t# 6 - clear PLLRST (bit 3)\n\tset pll_ctrl [expr {$pll_ctrl & ~0x0008}]\n\tmww $pll_ctrl_addr $pll_ctrl\n\n\t# 9 - optional: write prediv, postdiv, and pllm\n\tmww [expr {$pll_addr + 0x0110}] [expr {($mult / 2) & 0x1ff}]\n\tif { [dict exists $config prediv] } {\n\t\tset div [dict get $config prediv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0114}] $div\n\t}\n\tif { [dict exists $config postdiv] } {\n\t\tset div [dict get $config postdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0128}] $div\n\t}\n\n\t# 10 - write start sequence to PLLSECCTL\n\tmww $pll_secctrl_addr 0x00470000\n\tmww $pll_secctrl_addr 0x00460000\n\tmww $pll_secctrl_addr 0x00400000\n\tmww $pll_secctrl_addr 0x00410000\n\n\t# 11 - optional: set plldiv1, plldiv2, ...\n\t# NOTE: this assumes some registers have their just-reset values:\n\t#\t- PLLSTAT.GOSTAT is clear when we enter\n\tset aln 0\n\tif { [dict exists $config div1] } {\n\t\tset div [dict get $config div1]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0118}] $div\n\t\tset aln [expr {$aln | 0x1}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0118}] 0\n\t}\n\tif { [dict exists $config div2] } {\n\t\tset div [dict get $config div2]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x011c}] $div\n\t\tset aln [expr {$aln | 0x2}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x011c}] 0\n\t}\n\tif { [dict exists $config div3] } {\n\t\tset div [dict get $config div3]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0120}] $div\n\t\tset aln [expr {$aln | 0x4}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0120}] 0\n\t}\n\tif { [dict exists $config oscdiv] } {\n\t\tset div [dict get $config oscdiv]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0124}] $div\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0124}] 0\n\t}\n\tif { [dict exists $config div4] } {\n\t\tset div [dict get $config div4]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0160}] $div\n\t\tset aln [expr {$aln | 0x8}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0160}] 0\n\t}\n\tif { [dict exists $config div5] } {\n\t\tset div [dict get $config div5]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0164}] $div\n\t\tset aln [expr {$aln | 0x10}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0164}] 0\n\t}\n\tif { [dict exists $config div6] } {\n\t\tset div [dict get $config div6]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0168}] $div\n\t\tset aln [expr {$aln | 0x20}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0168}] 0\n\t}\n\tif { [dict exists $config div7] } {\n\t\tset div [dict get $config div7]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x016c}] $div\n\t\tset aln [expr {$aln | 0x40}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x016c}] 0\n\t}\n\tif { [dict exists $config div8] } {\n\t\tset div [dict get $config div8]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0170}] $div\n\t\tset aln [expr {$aln | 0x80}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0170}] 0\n\t}\n\tif { [dict exists $config div9] } {\n\t\tset div [dict get $config div9]\n\t\tset div [expr {0x8000 | ($div - 1)}]\n\t\tmww [expr {$pll_addr + 0x0174}] $div\n\t\tset aln [expr {$aln | 0x100}]\n\t} else {\n\t\tmww [expr {$pll_addr + 0x0174}] 0\n\t}\n\tif {$aln != 0} {\n\t\t# clear pllcmd.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x00\n\t\t# write alignment flags\n\t\tmww [expr {$pll_addr + 0x0140}] $aln\n\t\t# write pllcmd.GO; poll pllstat.GO\n\t\tmww [expr {$pll_addr + 0x0138}] 0x01\n\t\tset pllstat [expr {$pll_addr + 0x013c}]\n\t\twhile {[expr {[mrw $pllstat] & 0x01}] != 0} { sleep 1 }\n\t}\n\tmww [expr {$pll_addr + 0x0138}] 0x00\n\tset addr [dict get $config ctladdr]\n\twhile {[expr {[mrw $addr] & 0x0e000000}] != 0x0e000000} { sleep 1 }\n\n\t# 12 - set PLLEN (bit 0) ... leave bypass mode\n\tset pll_ctrl [expr {$pll_ctrl | 0x0001}]\n\tmww $pll_ctrl_addr $pll_ctrl\n}\n\n# NOTE: dm6446 requires EMURSTIE set in MDCTL before certain\n# modules can be enabled.\n\n# prepare a non-DSP module to be enabled; finish with psc_go\nproc psc_enable {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x03 0x1f\n}\n\n# prepare a non-DSP module to be reset; finish with psc_go\nproc psc_reset {module} {\n\tset psc_addr 0x01c41000\n\t# write MDCTL\n\tmmw [expr {$psc_addr + 0x0a00 + (4 * $module)}] 0x01 0x1f\n}\n\n# execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc\nproc psc_go {} {\n\tset psc_addr 0x01c41000\n\tset ptstat_addr [expr {$psc_addr + 0x0128}]\n\n\t# just in case PTSTAT.go isn't clear\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n\n\t# write PTCMD.go ... ignoring any DSP power domain\n\tmww [expr {$psc_addr + 0x0120}] 1\n\n\t# wait for PTSTAT.go to clear (again ignoring DSP power domain)\n\twhile { [expr {[mrw $ptstat_addr] & 0x01}] != 0 } { sleep 1 }\n}\n\n#\n# A reset using only SRST is a \"Warm Reset\", resetting everything in the\n# chip except ARM emulation (and everything _outside_ the chip that hooks\n# up to SRST).  But many boards don't expose SRST via their JTAG connectors\n# (it's not present on TI-14 headers).\n#\n# From the chip-only perspective, a \"Max Reset\" is a \"Warm\" reset ... except\n# without any board-wide side effects, since it's triggered using JTAG using\n# either (a) ARM watchdog timer, or (b) ICEpick.\n#\nproc davinci_wdog_reset {} {\n\tset timer2_phys 0x01c21c00\n\n\t# NOTE -- on entry\n\t#   - JTAG communication with the ARM *must* be working OK; this\n\t#     may imply using adaptive clocking or disabling WFI-in-idle\n\t#   - current target must be the DaVinci ARM\n\t#   - that ARM core must be halted\n\t#   - timer2 clock is still enabled (PSC 29 on most chips)\n\n\t#\n\t# Part I -- run regardless of being halted via JTAG\n\t#\n\t# NOTE:  for now, we assume there's no DSP that could control the\n\t# watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog\n\t# suspend signal is controlled via ARM emulation suspend.\n\t#\n\n\t# EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n\n\t#\n\t# Part II -- in case watchdog hasn't been set up\n\t#\n\n\t# TCR: disable, force internal clock source\n\tmww phys [expr {$timer2_phys + 0x20}] 0\n\n\t# TGCR: reset, force to 64-bit wdog mode, un-reset (\"initial\" state)\n\tmww phys [expr {$timer2_phys + 0x24}] 0\n\tmww phys [expr {$timer2_phys + 0x24}] 0x110b\n\n\t# clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers\n\t# so watchdog triggers ASAP\n\tmww phys [expr {$timer2_phys + 0x10}] 0\n\tmww phys [expr {$timer2_phys + 0x14}] 0\n\tmww phys [expr {$timer2_phys + 0x18}] 0\n\tmww phys [expr {$timer2_phys + 0x1c}] 0\n\n\t# WDTCR: put into pre-active state, then active\n\tmww phys [expr {$timer2_phys + 0x28}] 0xa5c64000\n\tmww phys [expr {$timer2_phys + 0x28}] 0xda7e4000\n\n\t#\n\t# Part III -- it's ready to rumble\n\t#\n\n\t# WDTCR: write invalid WDKEY to trigger reset\n\tmww phys [expr {$timer2_phys + 0x28}] 0x00004000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/dragonite.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Marvell Dragonite CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dragonite\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x121003d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dragonite -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/dsp56321.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Script for freescale DSP56321\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp56321\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1181501d\n}\n\n#jtag speed\nadapter speed 4500\n\n#has only srst\nreset_config srst_only\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/dsp568013.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Script for freescale DSP568013\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568013\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2401d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\n# Disable polling to be able to get idcode from core tap. If re enabled, can be re enabled, but it should be disabled to correctly unlock flash (operations require certain instruction to be in the IR register during reset, and polling would change this)\njtag configure $_CHIPNAME.chp -event setup \"\n     jtag tapenable $_TARGETNAME\n     poll off\n\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/dsp568037.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Script for freescale DSP568037\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dsp568037\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a big endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x01f2801d\n}\n\n#jtag speed\nadapter speed 800\n\nreset_config srst_only\n\n#MASTER tap\njtag newtap $_CHIPNAME chp -irlen 8 -ircapture 1 -irmask 0x03 -expected-id $_CPUTAPID\n\n#CORE tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x03 -disable -expected-id 0x02211004\n\n#target configuration - There is only 1 tap at a time, hence only 1 target is defined.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME dsp5680xx -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Setup the interesting tap\njtag configure $_CHIPNAME.chp -event setup \"jtag tapenable $_TARGETNAME\"\n\n#select CORE tap by modifying the TLM register.\n#to be used when MASTER tap is selected.\njtag configure $_TARGETNAME -event tap-enable \"\n     irscan $_CHIPNAME.chp 0x05;\n     drscan $_CHIPNAME.chp 4 0x02;\n     jtag tapdisable $_CHIPNAME.chp;\n\"\n\n#select MASTER tap by modifying the TLM register.\n#to be used when CORE tap is selected.\njtag configure $_CHIPNAME.chp -event tap-enable \"\n     irscan $_TARGETNAME 0x08;\n     drscan $_TARGETNAME 4 0x1;\n     jtag tapdisable $_TARGETNAME;\n\"\n\n#disables the master tap\njtag configure $_TARGETNAME -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\njtag configure $_CHIPNAME.chp -event tap-disable \"\n\"\n#TODO FIND SMARTER WAY.\n\n\n#working area at base of ram\n$_TARGETNAME configure -work-area-virt 0\n\n#setup flash\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME dsp5680xx_flash 0 0 2 1 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/efm32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Silicon Labs (formerly Energy Micro) EFM32 target\n#\n# Note: All EFM32 chips have SWD support, but only newer series 1\n# chips have JTAG support.\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME efm32\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nadapter speed 1000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME efm32 0 0 0 0 $_TARGETNAME\nflash bank userdata.flash efm32 0x0FE00000 0 0 0 $_TARGETNAME\nflash bank lockbits.flash efm32 0x0FE04000 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/em357.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Target configuration for the Silicon Labs EM357 chips\n#\n\n#\n# em357 family supports JTAG and SWD transports\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em357\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } else {\n      set _CPUTAPID 0x1ba00477\n   }\n}\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n  set _BSTAPID 0x069a962b\n}\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME em358\n}\n\nif { [info exists FLASHSIZE] } {\n    set _FLASHSIZE $FLASHSIZE\n} else {\n    set _FLASHSIZE 0x30000\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nif { [using_jtag] } {\n    jtag newtap $_CHIPNAME bs -irlen 4 -expected-id $_BSTAPID -ircapture 0xe -irmask 0xf\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME em357 0x08000000 $_FLASHSIZE 0 0 $_TARGETNAME\n\nif { ![using_hla]} {\n# according to errata, we need to use vectreset rather than sysresetreq to avoid lockup\n# There is a bug in the chip, which means that when using external debuggers the chip\n# may lock up in certain CPU clock modes. Affected modes are operating the CPU at\n# 24MHz derived from the 24MHz crystal, or 12MHz derived from the high frequency RC\n# oscillator. If an external debugger tool asserts SYSRESETREQ, the chip will lock up and\n# require a pin reset or power cycle.\n#\n# for details, refer to:\n# http://www.silabs.com/Support%20Documents/TechnicalDocs/EM35x-Errata.pdf\n    cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/em358.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the Silicon Labs EM358 chips\n\n#\n# em357 family supports JTAG and SWD transports\n#\n\nif { ![info exists CHIPNAME] } {\n   set CHIPNAME em358\n}\n\nif { ![info exists BSTAPID] } {\n  set BSTAPID 0x069aa62b\n}\n\n# 512K of flash in the em358 chips\nset FLASHSIZE 0x80000\nsource [find target/em357.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/eos_s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# QuickLogic EOS S3\n# https://www.quicklogic.com/products/soc/eos-s3-microcontroller/\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME eos_s3\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x80000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# For now we use SRAM only for software upload\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nadapter speed 4000\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/epc9301.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Cirrus Logic EP9301 processor on an Olimex CS-E9301 board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ep9301\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\nadapter srst delay 100\njtag_ntrst_delay 100\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME -work-area-phys 0x80014000 -work-area-size 0x1000 -work-area-backup 1\n\n#flash configuration\n#flash bank <driver> <base> <size> <chip_width> <bus_width> [driver_options ...]\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cfi 0x60000000 0x1000000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/esi32xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# EnSilica eSi-32xx SoC (eSi-RISC Family)\n# http://www.ensilica.com/risc-ip/\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME esi32xx\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x11234001\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME esirisc -chain-position $_CHIPNAME.cpu\n\n# Targets with the UNIFIED_ADDRESS_SPACE option disabled should set\n# CACHEARCH to 'harvard'. By default, 'von_neumann' is assumed.\nif { [info exists CACHEARCH] } {\n    $_TARGETNAME esirisc cache_arch $CACHEARCH\n}\n\nadapter speed 2000\n\nreset_config none\n\n# The default linker scripts provided by the eSi-RISC toolchain do not\n# specify attributes on memory regions, which results in incorrect\n# application of software breakpoints by GDB.\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/esp32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n\n# Source the ESP common configuration file.\nsource [find target/esp_common.cfg]\n\n# Target specific global variables\nset _CHIPNAME \t\t\t\t\t\"esp32\"\nset _CPUTAPID \t\t\t\t\t0x120034e5\nset _ESP_ARCH \t\t\t\t\t\"xtensa\"\nset _ONLYCPU\t\t\t\t\t3\nset _FLASH_VOLTAGE \t\t\t\t3.3\nset _ESP_SMP_TARGET\t\t\t\t1\nset _ESP_SMP_BREAK \t\t\t\t1\nset _ESP_EFUSE_MAC_ADDR_REG \t0x3ff5A004\n\nif { [info exists ESP32_ONLYCPU] } {\n\tset _ONLYCPU $ESP32_ONLYCPU\n}\n\nif { [info exists ESP32_FLASH_VOLTAGE] } {\n\tset _FLASH_VOLTAGE $ESP32_FLASH_VOLTAGE\n}\n\nproc esp32_memprot_is_enabled { } {\n\treturn 0\n}\n\nproc esp32_soc_reset { } {\n\tsoft_reset_halt\n}\n\ncreate_esp_target $_ESP_ARCH\n\nsource [find target/xtensa-core-esp32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/esp32s2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n\n# Source the ESP common configuration file.\nsource [find target/esp_common.cfg]\n\n# Target specific global variables\nset _CHIPNAME \t\t\t\t\t\"esp32s2\"\nset _CPUTAPID \t\t\t\t\t0x120034e5\nset _ESP_ARCH\t\t\t\t\t\"xtensa\"\nset _ONLYCPU\t\t\t\t\t1\nset _ESP_SMP_TARGET\t\t\t\t0\nset _ESP_SMP_BREAK \t\t\t\t1\nset _ESP_EFUSE_MAC_ADDR_REG  \t0x3f41A004\n\nproc esp32s2_memprot_is_enabled { } {\n\t# IRAM0, DPORT_PMS_PRO_IRAM0_0_REG\n\tif { [get_mmr_bit 0x3f4c1010 0] != 0 } {\n\t\treturn 1\n\t}\n\t# DRAM0, DPORT_PMS_PRO_DRAM0_0_REG\n\tif { [get_mmr_bit 0x3f4c1028 0] != 0 } {\n\t\treturn 1\n\t}\n\t# PERI1, DPORT_PMS_PRO_DPORT_0_REG\n\tif { [get_mmr_bit 0x3f4c103c 0] != 0 } {\n\t\treturn 1\n\t}\n\t# PERI2, DPORT_PMS_PRO_AHB_0_REG\n\tif { [get_mmr_bit 0x3f4c105c 0] != 0 } {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nproc esp32s2_soc_reset { } {\n\tsoft_reset_halt\n}\n\ncreate_esp_target $_ESP_ARCH\n\nsource [find target/xtensa-core-esp32s2.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/esp32s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n\n# Source the ESP common configuration file.\nsource [find target/esp_common.cfg]\n\n# Target specific global variables\nset _CHIPNAME \t\t\t\t\t\"esp32s3\"\nset _CPUTAPID \t\t\t\t\t0x120034e5\nset _ESP_ARCH \t\t\t\t\t\"xtensa\"\nset _ONLYCPU\t\t\t\t\t3\nset _ESP_SMP_TARGET\t\t\t\t1\nset _ESP_SMP_BREAK \t\t\t\t1\nset _ESP_EFUSE_MAC_ADDR_REG  \t0x60007044\n\nif { [info exists ESP32_S3_ONLYCPU] } {\n\tset _ONLYCPU $ESP32_S3_ONLYCPU\n}\n\nproc esp32s3_memprot_is_enabled { } {\n\t# SENSITIVE_CORE_X_IRAM0_DRAM0_DMA_SPLIT_LINE_CONSTRAIN_0_REG\n\tif { [get_mmr_bit 0x600C10C0 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_0_PIF_PMS_CONSTRAIN_0_REG\n\tif { [get_mmr_bit 0x600C1124 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_1_PIF_PMS_CONSTRAIN_0_REG\n\tif { [get_mmr_bit 0x600C11D0 0] != 0 } {\n\t\treturn 1\n\t}\n\t# IRAM0, SENSITIVE_CORE_X_IRAM0_PMS_CONSTRAIN_0_REG\n\tif { [get_mmr_bit 0x600C10D8 0] != 0 } {\n\t\treturn 1\n\t}\n\t# DRAM0, SENSITIVE_CORE_X_DRAM0_PMS_CONSTRAIN_0_REG\n\tif { [get_mmr_bit 0x600C10FC 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_0_IRAM0_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C10E4 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_1_IRAM0_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C10F0 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_0_DRAM0_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C1104 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_1_DRAM0_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C1114 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_0_PIF_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C119C 0] != 0 } {\n\t\treturn 1\n\t}\n\t# SENSITIVE_CORE_1_PIF_PMS_MONITOR_0_REG\n\tif { [get_mmr_bit 0x600C1248 0] != 0 } {\n\t\treturn 1\n\t}\n\treturn 0\n}\n\nproc esp32s3_soc_reset { } {\n\tsoft_reset_halt\n}\n\ncreate_esp_target $_ESP_ARCH\n\nsource [find target/xtensa-core-esp32s3.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/esp_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nsource [find bitsbytes.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\n# Common ESP chips definitions\n\n# Espressif supports only NuttX in the upstream.\n# FreeRTOS support is not upstreamed yet.\nset _RTOS \"hwthread\"\nif { [info exists ESP_RTOS] } {\n\tset _RTOS \"$ESP_RTOS\"\n}\n\n# by default current dir (when OOCD has been started)\nset _SEMIHOST_BASEDIR \".\"\nif { [info exists ESP_SEMIHOST_BASEDIR] } {\n\tset _SEMIHOST_BASEDIR $ESP_SEMIHOST_BASEDIR\n}\n\nproc set_esp_common_variables { } {\n\tglobal _CHIPNAME _ONLYCPU _ESP_SMP_TARGET\n\tglobal _CPUNAME_0 _CPUNAME_1 _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1\n\tglobal _ESP_WDT_DISABLE _ESP_SOC_RESET _ESP_MEMPROT_IS_ENABLED\n\n\t# For now we support dual core at most.\n\tif { $_ONLYCPU == 1 && $_ESP_SMP_TARGET == 0} {\n\t\tset _TARGETNAME_0 \t\t\t\t$_CHIPNAME\n\t\tset _CPUNAME_0\t\t\t\t\tcpu\n\t\tset _TAPNAME_0 \t\t\t\t\t$_CHIPNAME.$_CPUNAME_0\n\t} else {\n\t\tset _CPUNAME_0 \t\t\t\t\tcpu0\n\t\tset _CPUNAME_1 \t\t\t\t\tcpu1\n\t\tset _TARGETNAME_0 \t\t\t\t$_CHIPNAME.$_CPUNAME_0\n\t\tset _TARGETNAME_1 \t\t\t\t$_CHIPNAME.$_CPUNAME_1\n\t\tset _TAPNAME_0 \t\t\t\t\t$_TARGETNAME_0\n\t\tset _TAPNAME_1 \t\t\t\t\t$_TARGETNAME_1\n\t}\n\n\tset _ESP_WDT_DISABLE \t\t\t\"${_CHIPNAME}_wdt_disable\"\n\tset _ESP_SOC_RESET \t\t\t\t\"${_CHIPNAME}_soc_reset\"\n\tset _ESP_MEMPROT_IS_ENABLED \t\"${_CHIPNAME}_memprot_is_enabled\"\n}\n\nproc create_esp_jtag { } {\n\tglobal _CHIPNAME _CPUNAME_0 _CPUNAME_1 _CPUTAPID _ONLYCPU\n\tjtag newtap $_CHIPNAME $_CPUNAME_0 -irlen 5 -expected-id $_CPUTAPID\n\tif { $_ONLYCPU != 1 } {\n\t\tjtag newtap $_CHIPNAME $_CPUNAME_1 -irlen 5 -expected-id $_CPUTAPID\n\t} elseif [info exists _CPUNAME_1] {\n\t\tjtag newtap $_CHIPNAME $_CPUNAME_1 -irlen 5 -disable -expected-id $_CPUTAPID\n\t}\n}\n\nproc create_openocd_targets  { } {\n\tglobal _TARGETNAME_0 _TARGETNAME_1 _TAPNAME_0 _TAPNAME_1 _RTOS _CHIPNAME _ONLYCPU\n\n\ttarget create $_TARGETNAME_0 $_CHIPNAME -chain-position $_TAPNAME_0 -coreid 0 -rtos $_RTOS\n\tif { $_ONLYCPU != 1 } {\n\t\ttarget create $_TARGETNAME_1 $_CHIPNAME -chain-position $_TAPNAME_1 -coreid 1 -rtos $_RTOS\n\t\ttarget smp $_TARGETNAME_0 $_TARGETNAME_1\n\t}\n}\n\nproc create_esp_target { ARCH } {\n\tset_esp_common_variables\n\tcreate_esp_jtag\n\tcreate_openocd_targets\n\tconfigure_openocd_events\n\n\tif { $ARCH == \"xtensa\"} {\n\t\tconfigure_esp_xtensa_default_settings\n\t} else {\n\t\t# riscv targets are not upstreamed yet.\n\t\t# they can be found at the official Espressif fork.\n\t}\n}\n\n#################### Set event handlers and default settings  ####################\n\nproc configure_event_examine_end { } {\n\tglobal _TARGETNAME_0 _TARGETNAME_1 _ONLYCPU\n\n\t$_TARGETNAME_0 configure -event examine-end {\n\t\t# Need to enable to set 'semihosting_basedir'\n\t\tarm semihosting enable\n\t\tarm semihosting_resexit enable\n\t\tif { [info exists _SEMIHOST_BASEDIR] } {\n\t\t\tif { $_SEMIHOST_BASEDIR != \"\" } {\n\t\t\t\tarm semihosting_basedir $_SEMIHOST_BASEDIR\n\t\t\t}\n\t\t}\n\t}\n\n\tif { $_ONLYCPU != 1 } {\n\t\t$_TARGETNAME_1 configure -event examine-end {\n\t\t\t# Need to enable to set 'semihosting_basedir'\n\t\t\tarm semihosting enable\n\t\t\tarm semihosting_resexit enable\n\t\t\tif { [info exists _SEMIHOST_BASEDIR] } {\n\t\t\t\tif { $_SEMIHOST_BASEDIR != \"\" } {\n\t\t\t\t\tarm semihosting_basedir $_SEMIHOST_BASEDIR\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nproc configure_event_reset_assert_post { } {\n\tglobal _TARGETNAME_0 _TARGETNAME_1 _ONLYCPU\n\n\t$_TARGETNAME_0 configure -event reset-assert-post {\n\t\tglobal _ESP_SOC_RESET\n\t\t$_ESP_SOC_RESET\n\t}\n\n\tif { $_ONLYCPU != 1 } {\n\t\t$_TARGETNAME_1 configure -event reset-assert-post {\n\t\t\tglobal _ESP_SOC_RESET\n\t\t\t$_ESP_SOC_RESET\n\t\t}\n\t}\n}\n\nproc configure_event_halted { } {\n\tglobal _TARGETNAME_0\n\n\t$_TARGETNAME_0 configure -event halted {\n\t\tglobal _ESP_WDT_DISABLE\n\t    $_ESP_WDT_DISABLE\n\t    esp halted_event_handler\n\t}\n}\n\nproc configure_event_gdb_attach { } {\n\tglobal _TARGETNAME_0 _TARGETNAME_1 _ONLYCPU\n\n\t$_TARGETNAME_0 configure -event gdb-attach {\n\t\tif { $_ESP_SMP_BREAK != 0 } {\n\t\t\t$_TARGETNAME_0 xtensa smpbreak BreakIn BreakOut\n\t\t}\n\t\t# necessary to auto-probe flash bank when GDB is connected and generate proper memory map\n\t\thalt 1000\n\t\tif { [$_ESP_MEMPROT_IS_ENABLED] } {\n\t\t\t# 'reset halt' to disable memory protection and allow flasher to work correctly\n\t\t\techo \"Memory protection is enabled. Reset target to disable it...\"\n\t\t\treset halt\n\t\t}\n\t}\n\n\tif { $_ONLYCPU != 1 } {\n\t\t$_TARGETNAME_1 configure -event gdb-attach {\n\t\t\tif { $_ESP_SMP_BREAK != 0 } {\n\t\t\t\t$_TARGETNAME_1 xtensa smpbreak BreakIn BreakOut\n\t\t\t}\n\t\t\t# necessary to auto-probe flash bank when GDB is connected\n\t\t\thalt 1000\n\t\t\tif { [$_ESP_MEMPROT_IS_ENABLED] } {\n\t\t\t\t# 'reset halt' to disable memory protection and allow flasher to work correctly\n\t\t\t\techo \"Memory protection is enabled. Reset target to disable it...\"\n\t\t\t\treset halt\n\t\t\t}\n\t\t}\n\t}\n}\n\nproc configure_openocd_events { } {\n\tconfigure_event_examine_end\n\tconfigure_event_reset_assert_post\n\tconfigure_event_gdb_attach\n}\n\nproc configure_esp_xtensa_default_settings { } {\n\tglobal _TARGETNAME_0 _ESP_SMP_BREAK _FLASH_VOLTAGE _CHIPNAME\n\n\t$_TARGETNAME_0 xtensa maskisr on\n\tif { $_ESP_SMP_BREAK != 0 } {\n\t\t$_TARGETNAME_0 xtensa smpbreak BreakIn BreakOut\n\t}\n\n\tgdb_breakpoint_override hard\n\n\tif { [info exists _FLASH_VOLTAGE] } {\n\t\t$_TARGETNAME_0 $_CHIPNAME flashbootstrap $_FLASH_VOLTAGE\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/exynos5250.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Samsung Exynos 5250 - dual-core ARM Cortex-A15\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME exynos5250\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap\n\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/faux.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#Script for faux target - used for testing\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME at91eb40a\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x00000000\n}\n\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#dummy flash driver\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME faux 0x01000000 0x200000 2 2 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/feroceon.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Marvell Feroceon CPU core\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME feroceon\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x20a023d3\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME feroceon -endian $_ENDIAN -chain-position $_TARGETNAME\n\nreset_config trst_and_srst\nadapter srst delay 200\njtag_ntrst_delay 200\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/fm3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# MB9BF506\n# Fujitsu Cortex-M3 with 512kB Flash and 64kB RAM\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME mb9bfxx6\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\n\n# delays on reset lines\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\n# Fujitsu Cortex-M3 reset configuration\nreset_config trst_only\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n# MB9BF506 has 64kB of SRAM on its main system bus\n$_TARGETNAME configure -work-area-phys 0x1FFF8000 -work-area-size 0x10000 -work-area-backup 0\n\n# MB9BF506 has 512kB internal FLASH\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm3 0 0 0 0 $_TARGETNAME\n\n# 4MHz / 6 = 666kHz, so use 500\nadapter speed 500\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/fm4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Spansion FM4 (ARM Cortex-M4)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME fm4\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} elseif { [using_jtag] } {\n\tset _CPU_TAPID 0x4ba00477\n} else {\n\tset _CPU_TAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nadapter speed 500\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/fm4_mb9bf.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Spansion FM4 MB9BFxxx (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# MB9BF566 M/N/R have 32 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x8000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/fm4_s6e2cc.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Spansion FM4 S6E2CC (ARM Cortex-M4)\n#\n\nsource [find target/fm4.cfg]\n\n# S6E2CC8 H/J/L have 96 KB SRAM0\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x18000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank ${_FLASHNAME}0 fm4 0x00000000 0 0 0 $_TARGETNAME $CHIPSERIES\nflash bank ${_FLASHNAME}1 fm4 0x00100000 0 0 0 $_TARGETNAME $CHIPSERIES\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/gd32e23x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for GigaDevice gd32e23x Cortex-M23 Series\n\n# https://www.gigadevice.com/microcontroller/gd32e230c8t6/\n\n#\n# gd32e23x devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32e23x\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some GD32E230s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # this is the SW-DP tap id not the jtag tap id\n   set _CPUTAPID 0x0bf11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# SWD speed (may be updated to higher value in board config file)\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Debug clock enable\n\t# RCU_APB2EN |= DBGMCUEN\n\tmmw 0x40021018 0x00400000 0\n\n\t# Stop watchdog counters during halt\n\t# DBG_CTL0 |= WWDGT_HOLD | FWDGT_HOLD | STB_HOLD | DSLP_HOLD | SLP_HOLD\n\tmmw 0x40015804 0x00000307 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/gd32vf103.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# GigaDevice GD32VF103 target\n#\n# https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/\n#\n\nsource [find mem_helper.tcl]\n\ntransport select jtag\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gd32vf103\n}\n\n# The smallest RAM size 6kB (GD32VF103C4/T4/R4)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1800\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 0 0 0 $_TARGETNAME\n\n# DBGMCU_CR register cannot be set in examine-end event as the running RISC-V CPU\n# does not allow the debugger to access memory.\n# Stop watchdogs at least before flash programming.\n$_TARGETNAME configure -event reset-init {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP\n\tmmw 0xE0042004 0x00000300 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/gp326xxxa.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Support for General Plus GP326XXXA chips\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME gp326xxxa\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0f0f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Use internal SRAM as a work area\n$_TARGETNAME configure -work-area-phys 0xf8000000 -work-area-size 0x8000 -work-area-backup 0\n\n# The chip has both lines connected together\nreset_config trst_and_srst srst_pulls_trst\n# This delay is needed otherwise communication with the target would\n# be unreliable\nadapter srst delay 100\n\n# Set the adapter speed ridiculously low just in case we are\n# running off of a 32kHz clock\nadapter speed 2\n\nproc gp32xxxa_halt_and_reset_control_registers {} {\n\t# System control registers\n\tset P_SYSTEM_CTRL_NEW       0xD0000008\n\tset P_SYSTEM_CTRL           0xD000000C\n\tset P_SYSTEM_CLK_EN0        0xD0000010\n\tset P_SYSTEM_CLK_EN1        0xD0000014\n\tset P_SYSTEM_RESET_FLAG     0xD0000018\n\tset P_SYSTEM_CLK_CTRL       0xD000001C\n\tset P_SYSTEM_LVR_CTRL       0xD0000020\n\tset P_SYSTEM_WATCHDOG_CTRL  0xD0000024\n\tset P_SYSTEM_PLLEN          0xD000005C\n\n\t# Since we can't use SRST without pulling TRST\n\t# we can't assume the state of the clock configuration\n\t# or watchdog settings. So reset them before porceeding\n\n\t# Set the adapter speed ridiculously low just in case we are\n\t# running off of a 32kHz clock\n\tadapter speed 2\n\n\t# Disable any advanced features at this stage\n\tarm7_9 dcc_downloads disable\n\tarm7_9 fast_memory_access disable\n\n\t# Do a \"soft reset\"\n\tsoft_reset_halt\n\t# Reset all system control registers to their default \"after-reset\" values\n\tmwh $P_SYSTEM_WATCHDOG_CTRL  0x0000\n\tmwh $P_SYSTEM_LVR_CTRL       0x0000\n\n\tmwh $P_SYSTEM_CTRL_NEW       0x0001\n\tmwh $P_SYSTEM_CTRL           0x0001\n\t# Clear all reset flags by writing 1's\n\tmwh $P_SYSTEM_RESET_FLAG     0x001C\n\n\tmwh $P_SYSTEM_CLK_CTRL       0x8000\n\tmwh $P_SYSTEM_CLK_EN0        0xFFFF\n\tmwh $P_SYSTEM_CLK_EN1        0xFFFF\n\tmwh $P_SYSTEM_PLLEN          0x0010\n\n\t# Unfortunately there's no register that would allow us to\n\t# know if PLL is locked. So just wait for 100ms in hopes that\n\t# it would be enough.\n\tsleep 100\n\n\t# Now that we know that we are running at 48Mhz\n\t# Increase JTAG speed and enable speed optimization features\n\tadapter speed 5000\n\tarm7_9 dcc_downloads enable\n\tarm7_9 fast_memory_access enable\n}\n\n$_TARGETNAME configure -event reset-end { gp32xxxa_halt_and_reset_control_registers }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/hi3798.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hisilicon Hi3798 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi3798\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80020000\nset $_TARGETNAME.cti(1) 0x80120000\nset $_TARGETNAME.cti(2) 0x80220000\nset $_TARGETNAME.cti(3) 0x80320000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        #set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _command \"$_command -rtos hwthread\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/hi6220.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Hisilicon Hi6220 Target\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME hi6220\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n# declare the 8 main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nset $_TARGETNAME.cti(0) 0x80198000\nset $_TARGETNAME.cti(1) 0x80199000\nset $_TARGETNAME.cti(2) 0x8019A000\nset $_TARGETNAME.cti(3) 0x8019B000\nset $_TARGETNAME.cti(4) 0x801D8000\nset $_TARGETNAME.cti(5) 0x801D9000\nset $_TARGETNAME.cti(6) 0x801DA000\nset $_TARGETNAME.cti(7) 0x801DB000\n\nset _cores 8\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _command \"$_command -rtos hwthread\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ncti create cti.sys -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0x80003000\n\n# declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\n# declare the auxiliary Cortex-A7 core\ntarget create ${_TARGETNAME}.a7 cortex_a -dap $_CHIPNAME.dap -dbgbase 0x80210000 -defer-examine\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/hilscher_netx10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 10 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx10\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/hilscher_netx50.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n################################################################################\n# Author: Michael Trensch (MTrensch@googlemail.com)\n################################################################################\n\n#Hilscher netX 50 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx50\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# On netX50 SDRAM is not accessible at offset 0xDEAD0-0xDEADF as it is busy from\n# DMA controller at init. This function will setup a dummy DMA to free this ares\n# and must be called before using SDRAM\nproc sdram_fix { } {\n\n  mww 0x1c005830 0x00000001\n\n  mww 0x1c005104 0xBFFFFFFC\n  mww 0x1c00510c 0x00480001\n  mww 0x1c005110 0x00000001\n\n  sleep 100\n\n  mww 0x1c00510c 0\n  mww 0x1c005110 0\n  mww 0x1c005830 0x00000000\n\n\tputs \"SDRAM Fix executed!\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/hilscher_netx500.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#Hilscher netX 500 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME netx500\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926021\n}\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# that TAP is associated with a target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc mread32 {addr} {\n  return [read_memory $addr 32 1]\n}\n\n# This function must be called on netX100/500 right after halt\n# If it is called later the needed register cannot be written anymore\nproc sdram_fix { } {\n\n  set accesskey [mread32 0x00100070]\n  mww 0x00100070 $accesskey\n  mww 0x0010002c 0x00000001\n\n  if {[expr {[mread32 0x0010002c] & 0x07}] == 0x07} {\n\t puts \"SDRAM Fix was not executed. Probably your CPU halted too late and the register is already locked!\"\n  } else {\n\t puts \"SDRAM Fix succeeded!\"\n  }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/icepick.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Copyright (C)   2011        by Karl Kurbjun\n# Copyright (C)   2009        by David Brownell\n#\n\n# Utilities for TI ICEpick-C/D used in most TI SoCs\n# Details about the ICEPick are available in the the TRM for each SoC\n# and http://processors.wiki.ti.com/index.php/ICEPICK\n\n# create \"constants\"\nproc CONST { key } {\n\n\tarray set constant {\n\t\t# define ICEPick instructions\n\t\tIR_BYPASS   0x00\n\t\tIR_ROUTER   0x02\n\t\tIR_CONNECT  0x07\n\t\tIF_BYPASS   0x3F\n\t}\n\treturn $constant($key)\n}\n\n# Instruction to connect to the icepick module\nproc icepick_c_connect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x89 -endstate DRPAUSE\n}\n\n# Instruction to disconnect to the icepick module\nproc icepick_c_disconnect {jrc} {\n\n\t# Send CONNECT instruction in IR state\n\tirscan $jrc [CONST IR_CONNECT] -endstate IRPAUSE\n\n\t# Send write and connect key\n\tdrscan $jrc 8 0x86 -endstate DRPAUSE\n}\n\n#\n# icepick_c_router:\n#  this function is for sending router commands\n# arguments are:\n#  jrc:        TAP name for the ICEpick\n#  rw:         read/write (0 for read, 1 for write)\n#  block:      icepick or DAP\n#  register:   which register to read/write\n#  payload:    value to read/write\n# this function is for sending router commands\n#\nproc icepick_c_router {jrc rw block register payload} {\n\n\tset new_dr_value \\\n\t\t[expr { ( ($rw & 0x1) << 31)        | ( ($block & 0x7) << 28) | \\\n\t\t\t\t( ($register & 0xF) << 24)  | ( $payload & 0xFFFFFF ) } ]\n\n#\techo \"\\tNew router value:\\t0x[format %x $new_dr_value]\"\n\n\t# select router\n\tirscan $jrc [CONST IR_ROUTER] -endstate IRPAUSE\n\n\t# ROUTER instructions are 32 bits wide\n\tset old_dr_value 0x[drscan $jrc 32 $new_dr_value -endstate DRPAUSE]\n#\techo \"\\tOld router value:\\t0x[format %x $old_dr_value]\"\n}\n\n# Configure the icepick control register\nproc icepick_c_setup {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x001000\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15 for debug tap, 16..31 for test tap\nproc icepick_c_tapenable {jrc port} {\n\n\tif { ($port >= 0) && ($port < 16) } {\n\t\t# Debug tap\"\n\t\tset tap $port\n\t\tset block 0x2\n\t} elseif { $port < 32 } {\n\t\t# Test tap\n\t\tset tap [expr {$port - 16}]\n\t\tset block 0x1\n\t} else {\n\t\techo \"ERROR: Invalid ICEPick C port number: $port\"\n\t\treturn\n\t}\n\n\t# First CONNECT to the ICEPick\n#\techo \"Connecting to ICEPick\"\n\ticepick_c_connect $jrc\n\n#\techo \"Configuring the ICEpick\"\n\ticepick_c_setup $jrc\n\n\t# NOTE: it's important not to enter RUN/IDLE state until\n\t# done sending these instructions and data to the ICEpick.\n\t# And never to enter RESET, which will disable the TAPs.\n\n\t# first enable power and clock for TAP\n\ticepick_c_router $jrc 1 $block $tap 0x110048\n\n\t# TRM states that the register should be read back here, skipped for now\n\n\t# enable debug \"default\" mode\n\ticepick_c_router $jrc 1 $block $tap 0x112048\n\n\t# TRM states that debug enable and debug mode should be read back and\n\t# confirmed - skipped for now\n\n\t# Finally select the tap\n\ticepick_c_router $jrc 1 $block $tap 0x112148\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IR_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# jrc\t== TAP name for the ICEpick\n# coreid== core id number 0..15 (not same as port number!)\nproc icepick_d_set_core_control {jrc coreid value } {\n\ticepick_c_router $jrc 1 0x6 $coreid $value\n}\n\n# jrc\t== TAP name for the ICEpick\n# port\t== a port number, 0..15\n# Follow the sequence described in\n# http://processors.wiki.ti.com/images/f/f6/Router_Scan_Sequence-ICEpick-D.pdf\nproc icepick_d_tapenable {jrc port coreid { value 0x2008 } } {\n\n\t# First CONNECT to the ICEPick\n\ticepick_c_connect $jrc\n\ticepick_c_setup $jrc\n\n\t# Select the port\n\ticepick_c_router $jrc 1 0x2 $port 0x2108\n\n\t# Set icepick core control for $coreid\n\ticepick_d_set_core_control $jrc $coreid $value\n\n\t# Enter the bypass state\n\tirscan $jrc [CONST IF_BYPASS] -endstate RUN/IDLE\n\truntest 10\n}\n\n# This function uses the ICEPick to send a warm system reset\nproc icepick_c_wreset {jrc} {\n\n\t# send a router write, block is 0, register is 1, value is 0x2100\n\ticepick_c_router $jrc 1 0x0 0x1 0x002101\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# utility fn's for Freescale i.MX series\n\nglobal TARGETNAME\nset TARGETNAME $_TARGETNAME\n\n# rewrite commands of the form below to arm11 mcr...\n#\tData.Set c15:0x042f %long 0x40000015\nproc setc15 {regs value} {\n\tglobal TARGETNAME\n\n\techo [format \"set p15 0x%04x, 0x%08x\" $regs $value]\n\n\tarm mcr 15 [expr {($regs>>12)&0x7}] [expr {($regs>>0)&0xf}] [expr {($regs>>4)&0xf}] [expr {($regs>>8)&0x7}] $value\n}\n\n\nproc imx3x_reset {} {\n\t# this reset script comes from the Freescale PDK\n\t#\n\t# http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX35PDK\n\n\techo \"Target Setup: initialize DRAM controller and peripherals\"\n\n#\tData.Set c15:0x01 %long 0x00050078\n\tsetc15 0x01 0x00050078\n\n\techo \"configuring CP15 for enabling the peripheral bus\"\n#\tData.Set c15:0x042f %long 0x40000015\n\tsetc15 0x042f 0x40000015\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx21.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\n#\n# Hmmm.... should srst_pulls_trst be used here like i.MX27???\nreset_config trst_and_srst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx21\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0792611f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx25.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# imx25 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx25\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0x0f -expected-id $_ETBTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0x0 -irmask 0x0 -expected-id 0x0\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882301d\n}\njtag newtap $_CHIPNAME sdma -irlen 5 -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t\t-chain-position $_TARGETNAME\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx27.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# page 3-34 of \"MCIMC27 Multimedia Applications Processor Reference Manual, Rev 0.3\"\n# SRST pulls TRST\n#\n# Without setting these options correctly you'll see all sorts\n# of weird errors, e.g. MOE=0xe, invalid cpsr values, reset\n# failing, etc.\nreset_config trst_and_srst srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx27\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# Note above there are 2 taps\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x1b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926121\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n# REVISIT what operating environment sets up this virtual address mapping?\n$_TARGETNAME configure -work-area-virt 0xffff4c00 -work-area-phys 0xffff4c00 \\\n\t-work-area-size 0x8000 -work-area-backup 1\n# Internal to the chip, there is 45K of SRAM\n#\n\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx28.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# i.MX28 config file.\n# based off of the imx21.cfg file.\n\nreset_config trst_and_srst\n\n#jtag nTRST and nSRST delay\nadapter srst delay 100\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx28\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\n\n# Note above there is 1 tap\n\n# The CPU tap\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x079264f3\n}\njtag newtap $_CHIPNAME cpu  -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\n# Create the GDB Target.\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx31.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# imx31 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\n\nadapter srst delay 5\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx31\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x2190101d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\n\n# The \"SDMA\" - <S>mart <DMA> controller debug tap\n# Based on some IO pins - this can be disabled & removed\n# See diagram: 6-14\n#   SIGNAL NAME:\n#    SJC_MOD - controls multiplexer - disables ARM1136\n#    SDMA_BYPASS - disables SDMA    -\n#\n# Per ARM: DDI0211J_arm1136_r1p5_trm.pdf - the ARM 1136 as a 5 bit IR register\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0xf -expected-id 0x0\n\n# Per section 40.17.1, table 40-85 the IR register is 4 bits\n# But this conflicts with Diagram 6-13, \"3bits ir and drs\"\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx35.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# imx35 config\n#\n\nreset_config trst_and_srst srst_gates_jtag\njtag_ntrst_delay 100\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx35\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b3601d\n}\n\nif { [info exists SDMATAPID] } {\n   set _SDMATAPID $SDMATAPID\n} else {\n   set _SDMATAPID 0x0882601d\n}\n\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\n#========================================\n\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\n# No IDCODE for this TAP\njtag newtap $_CHIPNAME whatchacallit -irlen 4 -ircapture 0 -irmask 0x0 -expected-id 0x0\n\njtag newtap $_CHIPNAME smda -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_SDMATAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx51.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Freescale i.MX51\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx51\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190c01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx51_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx51_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx53.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Freescale i.MX53\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME imx53\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x1ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x0 -irmask 0xf\n\n# SJC\nif { [info exists SJC_TAPID] } {\n   set _SJC_TAPID SJC_TAPID\n} else {\n   set _SJC_TAPID 0x0190d01d\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x1 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx53_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n}\n\n$_TARGETNAME configure -event reset-assert-post \"imx53_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx6.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale i.MX6 series\n#\n# Supports 6Q 6D 6QP 6DP 6DL 6S 6SL 6SLL\n#\n# Some imx6 chips have Cortex-A7 or an Cortex-M and need special handling\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx6\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\n\n# List supported SJC TAPIDs from imx reference manuals:\nset _SJC_TAPID_6Q   0x0191c01d\nset _SJC_TAPID_6D   0x0191e01d\nset _SJC_TAPID_6QP  0x3191c01d\nset _SJC_TAPID_6DP  0x3191d01d\nset _SJC_TAPID_6DL  0x0891a01d\nset _SJC_TAPID_6S   0x0891b01d\nset _SJC_TAPID_6SL  0x0891f01d\nset _SJC_TAPID_6SLL 0x088c201d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6Q\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6QP \\\n        -expected-id $_SJC_TAPID_6DP \\\n        -expected-id $_SJC_TAPID_6D \\\n        -expected-id $_SJC_TAPID_6DL \\\n        -expected-id $_SJC_TAPID_6S \\\n        -expected-id $_SJC_TAPID_6SL \\\n        -expected-id $_SJC_TAPID_6SLL\n\n# GDB target: Cortex-A9, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x82150000\n# core 1  -  0x82152000\n# core 2  -  0x82154000\n# core 3  -  0x82156000\nset _TARGETNAME $_CHIPNAME.cpu.0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x82150000\n\n# some TCK cycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.sjc -event post-reset \"runtest 100\"\n\nproc imx6_dbginit {target} {\n        # General Cortex-A8/A9 debug initialisation\n        cortex_a dbginit\n}\n\n# Slow speed to be sure it will work\nadapter speed 1000\n$_TARGETNAME configure -event reset-start { adapter speed 1000 }\n\n$_TARGETNAME configure -event reset-assert-post \"imx6_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx6sx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale i.MX6SoloX\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6sx\n}\n\n# 2x CoreSight Debug Access Port for Cortex-M4 and Cortex-A9\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu_m4 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_m4 -chain-position $_CHIPNAME.cpu_m4\n\njtag newtap $_CHIPNAME cpu_a9 -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap_a9 -chain-position $_CHIPNAME.cpu_a9\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID 0x0891c01d\n}\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -expected-id $_SJC_TAPID -ignore-version\n\n# Cortex-A9 (boot core)\ntarget create $_CHIPNAME.cpu_a9 cortex_a -dap $_CHIPNAME.dap_a9 \\\n        -coreid 0 -dbgbase 0x82150000\n\n# Cortex-M4 (default off)\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap_m4 \\\n        -ap-num 0 -defer-examine\n\n# AHB mem-ap target\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap_a9 -ap-num 0\n\n# Default target is Cortex-A9\ntargets $_CHIPNAME.cpu_a9\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx6ul.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale i.MX6UltraLite series: 6UL 6ULL 6ULZ\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx6ul\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n# SDMA / no IDCODE\njtag newtap $_CHIPNAME sdma -irlen 4 -ircapture 0x00 -irmask 0x0f\n\n# System JTAG Controller\nset _SJC_TAPID_6UL  0x0891d01d\nset _SJC_TAPID_6ULL 0x0891e01d\nset _SJC_TAPID_6ULZ 0x1891e01d\n\n# Allow external override of the first SJC TAPID\nif { [info exists SJC_TAPID] } {\n    set _SJC_TAPID $SJC_TAPID\n} else {\n    set _SJC_TAPID $_SJC_TAPID_6UL\n}\n\njtag newtap $_CHIPNAME sjc -irlen 5 -ircapture 0x01 -irmask 0x1f \\\n        -ignore-version \\\n        -expected-id $_SJC_TAPID \\\n        -expected-id $_SJC_TAPID_6ULL \\\n        -expected-id $_SJC_TAPID_6ULZ \\\n\n# Create DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Main AHB bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Cortex-A7 single core\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap -dbgbase 0x82130000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx7\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\n#\n# Cortex-A7 target\n#\n# GDB target: Cortex-A7, using DAP, configuring only one core\n# Base addresses of cores:\n# core 0  -  0x80070000\n# core 1  -  0x80072000\nset _TARGETNAME $_CHIPNAME.cpu_a7\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME.0 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80070000\n\ntarget create $_TARGETNAME.1 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 1 -dbgbase 0x80072000 -defer-examine\n#\n# Cortex-M4 target\n#\nset _TARGETNAME_2 $_CHIPNAME.cpu_m4\ntarget create $_TARGETNAME_2 cortex_m -dap $_CHIPNAME.dap -ap-num 4 \\\n        -defer-examine\n\n#\n# AHB mem-ap target\n#\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx7ulp.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP i.MX7ULP: Cortex-A7 + Cortex-M4\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME imx7ulp\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x188e101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-A7\ntarget create $_CHIPNAME.cpu_a7 cortex_a -dap $_CHIPNAME.dap \\\n        -coreid 0 -dbgbase 0x80030000\n\n# Cortex-M4\n# Boots by default so don't defer examination\ntarget create $_CHIPNAME.cpu_m4 cortex_m -dap $_CHIPNAME.dap -ap-num 3\n\n# AHB main soc bus\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# Default is Cortex-A7\ntargets $_CHIPNAME.cpu_a7\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx8m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# configuration file for NXP i.MX8M family of SoCs\n#\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8m\n}\n\nif { [info exists CHIPCORES] } {\n    set _cores $CHIPCORES\n} else {\n    set _cores 1\n}\n\n# CoreSight Debug Access Port\nif { [info exists DAP_TAPID] } {\n        set _DAP_TAPID $DAP_TAPID\n} else {\n        set _DAP_TAPID 0x5ba00477\n}\n\n# the DAP tap\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        set _command \"$_command -rtos hwthread\"\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M4 core on AP #4\ntarget create ${_CHIPNAME}.m4 cortex_m -dap ${_CHIPNAME}.dap -ap-num 4 \\\n               -defer-examine\n\n# AHB-AP for direct access to soc bus\ntarget create ${_CHIPNAME}.ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# default target is A53 core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/imx8qm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP i.MX8QuadMax\n#\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME imx8qm\n}\n\n# CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    # TAPID is from FreeScale!\n    set _DAP_TAPID 0x1890101d\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f \\\n        -expected-id $_DAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# AXI: Main SOC bus on AP #0\ntarget create ${_CHIPNAME}.axi mem_ap -dap ${_CHIPNAME}.dap -ap-num 0\n\n# 4x Cortex-A53 on AP #6\nset _A53_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset _A53_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\n\ncti create $_CHIPNAME.a53_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 0]\ncti create $_CHIPNAME.a53_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 1]\ncti create $_CHIPNAME.a53_cti.2 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 2]\ncti create $_CHIPNAME.a53_cti.3 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A53_CTIBASE 3]\ntarget create $_CHIPNAME.a53.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.0 -dbgbase [lindex $_A53_DBGBASE 0]\ntarget create $_CHIPNAME.a53.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.1 -dbgbase [lindex $_A53_DBGBASE 1] -defer-examine\ntarget create $_CHIPNAME.a53.2 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.2 -dbgbase [lindex $_A53_DBGBASE 2] -defer-examine\ntarget create $_CHIPNAME.a53.3 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a53_cti.3 -dbgbase [lindex $_A53_DBGBASE 3] -defer-examine\n\n# 2x Cortex-A72 on AP #6\nset _A72_DBGBASE {0x80210000 0x80310000}\nset _A72_CTIBASE {0x80220000 0x80220000}\n\ncti create $_CHIPNAME.a72_cti.0 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 0]\ncti create $_CHIPNAME.a72_cti.1 -dap $_CHIPNAME.dap \\\n            -ap-num 6 -baseaddr [lindex $_A72_CTIBASE 1]\ntarget create $_CHIPNAME.a72.0 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.0 -dbgbase [lindex $_A72_DBGBASE 0] -defer-examine\ntarget create $_CHIPNAME.a72.1 aarch64 -dap $_CHIPNAME.dap \\\n            -cti $_CHIPNAME.a72_cti.1 -dbgbase [lindex $_A72_DBGBASE 1] -defer-examine\n\n# All Cortex-A in SMP\ntarget smp \\\n        $_CHIPNAME.a53.0 \\\n        $_CHIPNAME.a53.1 \\\n        $_CHIPNAME.a53.2 \\\n        $_CHIPNAME.a53.3 \\\n        $_CHIPNAME.a72.0 \\\n        $_CHIPNAME.a72.1\n\n# SCU: Cortex-M4 core\n# always running imx SC firmware\ntarget create ${_CHIPNAME}.scu cortex_m -dap ${_CHIPNAME}.dap -ap-num 1\n\n# AHB from SCU perspective\ntarget create ${_CHIPNAME}.scu_ahb mem_ap -dap ${_CHIPNAME}.dap -ap-num 4\n\n# Cortex-M4 M4_0 core on AP #2 (default off)\ntarget create ${_CHIPNAME}.m4_0 cortex_m -dap ${_CHIPNAME}.dap -ap-num 2 \\\n        -defer-examine\n\n# Cortex-M4 M4_1 core on AP #3 (default off)\ntarget create ${_CHIPNAME}.m4_1 cortex_m -dap ${_CHIPNAME}.dap -ap-num 3 \\\n        -defer-examine\n\n# Debug APB bus\ntarget create ${_CHIPNAME}.apb mem_ap -dap ${_CHIPNAME}.dap -ap-num 6\n\n# Default target is boot core a53.0\ntargets $_CHIPNAME.a53.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/infineon/tle987x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon TLE987x family (Arm Cortex-M3 @ up to 40 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tle987x\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\t# JTAG not supported, only SWD\n\tset _CPU_TAPID 0\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME dap -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/is5114.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Insilica IS-5114\n# AKA: Atmel AT76C114 - an ARM946 chip\n# ATMEL sold his product line to Insilica...\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME is5114\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a little endian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nreset_config trst_and_srst\n\n# Do not specify a tap id here...\njtag newtap $_CHIPNAME unknown1 -irlen 8 -ircapture 0x01 -irmask 1\n# This is the \"arm946\" chip.\njtag newtap $_CHIPNAME cpu      -irlen 4 -ircapture 0x0e -irmask 0xf\njtag newtap $_CHIPNAME unknown2 -irlen 5 -ircapture 1 -irmask 1\n\n\n#arm946e-s and\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\tadapter speed 3000\n}\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ixp42x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#xscale ixp42x CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME ixp42x\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN big\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x19274013\n}\nset _CPUTAPID2 0x19275013\nset _CPUTAPID3 0x19277013\nset _CPUTAPID4 0x29274013\nset _CPUTAPID5 0x29275013\nset _CPUTAPID6 0x29277013\n\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3 -expected-id $_CPUTAPID4 -expected-id $_CPUTAPID5 -expected-id $_CPUTAPID6\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\n# register constants for IXP42x SDRAM controller\nglobal IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\nglobal IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\nset IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\t0x0000\nset IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\t0x0001\n\nglobal IXP42x_SDRAM_CL3\nglobal IXP42x_SDRAM_CL2\nset IXP42x_SDRAM_CL3\t\t\t0x0008\nset IXP42x_SDRAM_CL2\t\t\t0x0000\n\nglobal IXP42x_SDRAM_8MB_2Mx32_1BANK\nglobal IXP42x_SDRAM_16MB_2Mx32_2BANK\nglobal IXP42x_SDRAM_16MB_4Mx16_1BANK\nglobal IXP42x_SDRAM_32MB_4Mx16_2BANK\nglobal IXP42x_SDRAM_32MB_8Mx16_1BANK\nglobal IXP42x_SDRAM_64MB_8Mx16_2BANK\nglobal IXP42x_SDRAM_64MB_16Mx16_1BANK\nglobal IXP42x_SDRAM_128MB_16Mx16_2BANK\nglobal IXP42x_SDRAM_128MB_32Mx16_1BANK\nglobal IXP42x_SDRAM_256MB_32Mx16_2BANK\n\nset IXP42x_SDRAM_8MB_2Mx32_1BANK\t0x0030\nset IXP42x_SDRAM_16MB_2Mx32_2BANK\t0x0031\nset IXP42x_SDRAM_16MB_4Mx16_1BANK\t0x0032\nset IXP42x_SDRAM_32MB_4Mx16_2BANK\t0x0033\nset IXP42x_SDRAM_32MB_8Mx16_1BANK\t0x0010\nset IXP42x_SDRAM_64MB_8Mx16_2BANK\t0x0011\nset IXP42x_SDRAM_64MB_16Mx16_1BANK\t0x0012\nset IXP42x_SDRAM_128MB_16Mx16_2BANK\t0x0013\nset IXP42x_SDRAM_128MB_32Mx16_1BANK\t0x0014\nset IXP42x_SDRAM_256MB_32Mx16_2BANK\t0x0015\n\n\n# helper function to init SDRAM on IXP42x.\n# SDRAM_CFG: one of IXP42X_SDRAM_xxx\n# REFRESH: refresh counter reload value (integer)\n# CASLAT: 2 or 3\nproc ixp42x_init_sdram { SDRAM_CFG REFRESH CASLAT } {\n\n    switch $CASLAT {\n\t2 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL2} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS2_CMD\n\t}\n\t3 {\n\t    set SDRAM_CFG [expr {$SDRAM_CFG | $::IXP42x_SDRAM_CL3} ]\n\t    set CASCMD $::IXP425_SDRAM_IR_MODE_SET_CAS3_CMD\n\t}\n\tdefault { error [format \"unsupported cas latency \\\"%s\\\" \" $CASLAT] }\n    }\n    echo [format \"\\tIXP42x SDRAM Config: 0x%x, Refresh %d \" $SDRAM_CFG $REFRESH]\n\n    mww 0xCC000000 $SDRAM_CFG ;# SDRAM_CFG: 0x2A: 64MBit, CL3\n    mww 0xCC000004          0 ;# disable refresh\n    mww 0xCC000008          3 ;# NOP\n    sleep 100\n    mww 0xCC000004   $REFRESH ;# set refresh counter\n    mww 0xCC000008          2 ;# Precharge All Banks\n    sleep 100\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008          4 ;# Auto Refresh\n    mww 0xCC000008    $CASCMD ;# Mode Select CL2/CL3\n}\n\nproc ixp42x_set_bigendian { } {\n    reg XSCALE_CTRL 0xF8\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/k1921vk01t.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# K1921VK01T\n# http://niiet.ru/chips/nis?id=354\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME k1921vk01t\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash niietcm4 0 0 0 0 $_TARGETNAME\n\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/k40.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Kinetis K40 devices\n#\n\nset CHIPNAME k40\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/k60.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Kinetis K60 devices\n#\n\nset CHIPNAME k60\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ke0x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Kinetis KE0x and KEAx series devices\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ke\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME kinetis_ke 0 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\n   # It is important that \"kinetis_ke mdm check_security\" is called for\n   # 'examine-end' event and not 'eximine-start'. Calling it in 'examine-start'\n   # causes \"kinetis_ke mdm check_security\" to fail the first time openocd\n   # calls it when it tries to connect after the CPU has been power-cycled.\n   $_CHIPNAME.cpu configure -event examine-end {\n      kinetis_ke mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ke1xf.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP (Freescale) Kinetis KE1xF devices\n#\n\nset CHIPNAME ke\n\nsource [find target/kx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ke1xz.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP (Freescale) Kinetis KE1xZ devices\n#\n\nset CHIPNAME ke\n\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/kl25.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Kinetis KL25 devices\n#\n\nset CHIPNAME kl25\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/kl46.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Kinetis KL46 devices\n#\n\nset CHIPNAME kl46\nsource [find target/klx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/klx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP (former Freescale) Kinetis KL series devices\n# Also used for Cortex-M0+ equipped members of KVx and KE1xZ series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME klx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1KiB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\n# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual\n# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;\n# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ks869x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ARM920T CPU\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME ks869x\n}\n\nif { [info exists ENDIAN] } {\n   set  _ENDIAN $ENDIAN\n} else {\n   set  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set  _CPUTAPID $CPUTAPID\n} else {\n   set  _CPUTAPID 0x00922f0f\n}\n\nadapter speed 6000\n\n# jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x20000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/kx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP (former Freescale) Kinetis Kx series devices\n# Also used for Cortex-M4 equipped members of KVx and KE1xF series\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME kx\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.pflash\nflash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME\nkinetis create_banks\n\nadapter speed 1000\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n   echo \"\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \" Kinetis MCUs have a MDM-AP dedicated mainly to MCU security related functions.\"\n   echo \" A high level adapter (like a ST-Link) you are currently using cannot access\"\n   echo \" the MDM-AP, so commands like 'mdm mass_erase' are not available in your\"\n   echo \" configuration. Also security locked state of the device will not be reported.\"\n   echo \" Expect problems connecting to a blank device without boot ROM.\"\n   echo \"\"\n   echo \" Be very careful as you can lock the device though there is no way to unlock\"\n   echo \" it without mass erase. Don't set write protection on the first block.\"\n   echo \"!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!\"\n   echo \"\"\n} else {\n   # Detect secured MCU or boot lock-up in RESET/WDOG loop\n   $_TARGETNAME configure -event examine-fail {\n      kinetis mdm check_security\n   }\n   # During RESET/WDOG loop the target is sometimes falsely examined\n   $_TARGETNAME configure -event examine-end {\n      kinetis mdm check_security\n   }\n\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n# Disable watchdog not to disturb OpenOCD algorithms running on MCU\n# (e.g. armv7m_checksum_memory() in verify_image)\n# Flash driver also disables watchdog before FTFA flash programming.\n$_TARGETNAME configure -event reset-init {\n   kinetis disable_wdog\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc11xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC11xx Cortex-M0 with at least 1kB SRAM\nset CHIPNAME lpc11xx\nset CHIPSERIES lpc1100\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc12xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC12xx Cortex-M0 with at least 4kB SRAM\nset CHIPNAME lpc12xx\nset CHIPSERIES lpc1200\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc13xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC13xx Cortex-M3 with at least 4kB SRAM\nset CHIPNAME lpc13xx\nset CHIPSERIES lpc1300\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc17xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC17xx Cortex-M3 with at least 8kB SRAM\nset CHIPNAME lpc17xx\nset CHIPSERIES lpc1700\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x2000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc1850.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc1850\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n#\n# M3 JTAG mode TAP\n#\nif { [info exists M3_JTAG_TAPID] } {\n   set _M3_JTAG_TAPID $M3_JTAG_TAPID\n} else {\n   set _M3_JTAG_TAPID 0x4ba00477\n}\n\nswj_newdap $_CHIPNAME m3 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_M3_JTAG_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.m3\n\nset _TARGETNAME $_CHIPNAME.m3\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc1xxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Main file for NXP LPC1xxx/LPC40xx series Cortex-M0/0+/3/4F parts\n#\n# !!!!!!\n#\n# This file should not be included directly, rather by the lpc11xx.cfg,\n# lpc13xx.cfg, lpc17xx.cfg, etc. which set the needed variables to the\n# appropriate values.\n#\n# !!!!!!\n\n# LPC8xx chips support only SWD transport.\n# LPC11xx chips support only SWD transport.\n# LPC12xx chips support only SWD transport.\n# LPC11Uxx chips support only SWD transports.\n# LPC13xx chips support only SWD transports.\n# LPC17xx chips support both JTAG and SWD transports.\n# LPC40xx chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\terror \"CHIPNAME not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\nif { [info exists CHIPSERIES] } {\n\t# Validate chip series is supported\n\tif { $CHIPSERIES != \"lpc800\" && $CHIPSERIES != \"lpc1100\" && $CHIPSERIES != \"lpc1200\" && $CHIPSERIES != \"lpc1300\" && $CHIPSERIES != \"lpc1700\"  && $CHIPSERIES != \"lpc4000\" } {\n\t\terror \"Unsupported LPC1xxx chip series specified.\"\n\t}\n\tset _CHIPSERIES $CHIPSERIES\n} else {\n\terror \"CHIPSERIES not set. Please do not include lpc1xxx.cfg directly, but the specific chip configuration file (lpc11xx.cfg, lpc13xx.cfg, lpc17xx.cfg, etc).\"\n}\n\n# After reset, the chip is clocked by an internal RC oscillator.\n# When board-specific code (reset-init handler or device firmware)\n# configures another oscillator and/or PLL0, set CCLK to match; if\n# you don't, then flash erase and write operations may misbehave.\n# (The ROM code doing those updates cares about core clock speed...)\n# CCLK is the core clock frequency in KHz\nif { [info exists CCLK] } {\n\t# Allow user override\n\tset _CCLK $CCLK\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx/LPC13xx use a 12MHz one, LPC17xx uses a 4MHz one(except for LPC177x/8x,LPC407x/8x)\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t\tset _CCLK 12000\n\t} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tset _CCLK 4000\n\t}\n}\n\nif { [info exists CPUTAPID] } {\n\t# Allow user override\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# LPC8xx/LPC11xx/LPC12xx use a Cortex-M0/M0+ core, LPC13xx/LPC17xx use a Cortex-M3 core, LPC40xx use a Cortex-M4F core.\n\tif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" } {\n\t\tset _CPUTAPID 0x0bb11477\n\t} elseif { $_CHIPSERIES == \"lpc1300\" || $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t\tif { [using_jtag] } {\n\t\t\tset _CPUTAPID 0x4ba00477\n\t\t} {\n\t\t\tset _CPUTAPID 0x2ba01477\n\t\t}\n\t}\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\terror \"WORKAREASIZE is not set. The $CHIPNAME part is available in several Flash and RAM size configurations. Please set WORKAREASIZE.\"\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# The LPC11xx devices have 2/4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC12xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC11Uxx devices have 4/6/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC13xx devices have 4/8kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC17xx devices have 8/16/32/64kB of SRAM in the ARMv7-M \"Code\" area (at 0x10000000)\n# The LPC40xx devices have 16/32/64kB of SRAM in the ARMv7-ME \"Code\" area (at 0x10000000)\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size $_WORKAREASIZE\n\n# The LPC11xx devies have 8/16/24/32/48/56/64kB of flash memory (at 0x00000000)\n# The LPC12xx devies have 32/48/64/80/96/128kB of flash memory (at 0x00000000)\n# The LPC11Uxx devies have 16/24/32/40/48/64/96/128kB of flash memory (at 0x00000000)\n# The LPC13xx devies have 8/16/32kB of flash memory (at 0x00000000)\n# The LPC17xx devies have 32/64/128/256/512kB of flash memory (at 0x00000000)\n# The LPC40xx devies have 64/128/256/512kB of flash memory (at 0x00000000)\n#\n# All are compatible with the \"lpc1700\" variant of the LPC2000 flash driver\n# (same cmd51 destination boundary alignment, and all three support 256 byte\n# transfers).\n#\n# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum] [iap entry]\nset _IAP_ENTRY 0\nif { [info exists IAP_ENTRY] } {\n\tset _IAP_ENTRY $IAP_ENTRY\n}\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0 0 0 $_TARGETNAME \\\n\tauto $_CCLK calc_checksum $_IAP_ENTRY\n\nif { $_CHIPSERIES == \"lpc800\" || $_CHIPSERIES == \"lpc1100\" || $_CHIPSERIES == \"lpc1200\" || $_CHIPSERIES == \"lpc1300\" } {\n\t# Do not remap 0x0000-0x0200 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# Table 8. System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n\t# Bit Symbol Value Description\n\t# 1:0 MAP          System memory remap\n\t#            0x0   Boot Loader Mode. Interrupt vectors are re-mapped to Boot ROM.\n\t#            0x1   User RAM Mode. Interrupt vectors are re-mapped to Static RAM.\n\t#            0x2   User Flash Mode. Interrupt vectors are not re-mapped and reside in Flash.\n\t# 31:2 -     -     Reserved.\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x40048000 0x02\n\t}\n} elseif { $_CHIPSERIES == \"lpc1700\" || $_CHIPSERIES == \"lpc4000\" } {\n\t# Do not remap 0x0000-0x0020 to anything but the flash (i.e. select\n\t# \"User Flash Mode\" where interrupt vectors are _not_ remapped,\n\t# and reside in flash instead).\n\t#\n\t# See Table 612. Memory Mapping Control register (MEMMAP - 0x400F C040) bit description\n\t# Bit Symbol Value Description Reset\n\t# value\n\t# 0 MAP Memory map control. 0\n\t# 0 Boot mode. A portion of the Boot ROM is mapped to address 0.\n\t# 1 User mode. The on-chip Flash memory is mapped to address 0.\n\t# 31:1 - Reserved. The value read from a reserved bit is not defined. NA\n\t#\n\t# http://ics.nxp.com/support/documents/microcontrollers/?scope=LPC1768&type=user\n\t$_TARGETNAME configure -event reset-init {\n\t\tmww 0x400FC040 0x01\n\t}\n}\n\n# Run with *real slow* clock by default since the\n# boot rom could have been playing with the PLL, so\n# we have no idea what clock the target is running at.\nadapter speed 10\n\n# delays on reset lines\nadapter srst delay 200\nif {[using_jtag]} {\n jtag_ntrst_delay 200\n}\n\n# LPC8xx (Cortex-M0+ core) support SYSRESETREQ\n# LPC11xx/LPC12xx (Cortex-M0 core) support SYSRESETREQ\n# LPC13xx/LPC17xx (Cortex-M3 core) support SYSRESETREQ\n# LPC40xx (Cortex-M4F core) support SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2103.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2103 ARM7TDMI-S with 32kB flash and 8kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2103 {core_freq_khz adapter_freq_khz} {\n\t# 32kB flash and 8kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2103 0x4f1f0f0f 0x8000 lpc2000_v2 0x2000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2103 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2103 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2124.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2124 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2124 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2124 0x4f1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2124 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2124 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2129.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2129 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2129 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2129 0xcf1f0f0f 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2129 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2129 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2148.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2148 ARM7TDMI-S with 512kB flash (12kB used by bootloader) and 40kB SRAM (8kB for USB DMA), clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2148 {core_freq_khz adapter_freq_khz} {\n\t# 500kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2148 \"0x3f0f0f0f 0x4f1f0f0f\" 0x7d000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2148 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2148 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2294.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2294 ARM7TDMI-S with 256kB flash and 16kB SRAM, clocked with 12MHz crystal\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2294 {core_freq_khz adapter_freq_khz} {\n\t# 256kB flash and 16kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\n\t# !! TAPID unknown !!\n\tsetup_lpc2xxx lpc2294 0xffffffff 0x40000 lpc2000_v1 0x4000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 12MHz crystal\n\techo \"Warning - assuming default core clock 12MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2294 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2294 12000 1500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2378.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2378 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 56kB SRAM (16kB for ETH, 8kB for DMA), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2378 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 32kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2378 0x4f1f0f0f 0x7e000 lpc2000_v2 0x8000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2378 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2378 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2460.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2460 ARM7TDMI-S with 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2460 {core_freq_khz adapter_freq_khz} {\n\t# 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2460 0x4f1f0f0f 0 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2460 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2460 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2478.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC2478 ARM7TDMI-S with 512kB flash (8kB used by bootloader) and 98kB SRAM (16kB for ETH, 16kB for DMA, 2kB for RTC), clocked with 4MHz internal oscillator\n\nsource [find target/lpc2xxx.cfg]\n\n# parameters:\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2478 {core_freq_khz adapter_freq_khz} {\n\t# 504kB flash and 64kB SRAM\n\t# setup_lpc2xxx <chip_name> <cputapid> <flash_size> <flash_variant> <workarea_size> <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2xxx lpc2478 0x4f1f0f0f 0x7e000 lpc2000_v2 0x10000 $core_freq_khz $adapter_freq_khz\n}\n\nproc init_targets {} {\n\t# default to core clocked with 4MHz internal oscillator\n\techo \"Warning - assuming default core clock 4MHz! Flashing may fail if actual core clock is different.\"\n\n\t# setup_lpc2478 <core_freq_khz> <adapter_freq_khz>\n\tsetup_lpc2478 4000 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2900.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME lpc2900\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0596802B\n}\n\nif { [info exists HAS_ETB] } {\n} else {\n    # Set default (no ETB).\n    # Show a warning, because this should have been configured explicitly.\n    set HAS_ETB 0\n    # TODO: warning?\n}\n\nif { [info exists ETBTAPID] } {\n    set _ETBTAPID $ETBTAPID\n} else {\n    set _ETBTAPID 0x1B900F0F\n}\n\n# TRST and SRST both exist, and can be controlled independently\nreset_config trst_and_srst separate\n\n# Define the _TARGETNAME\nset _TARGETNAME $_CHIPNAME.cpu\n\n# Include the ETB tap controller if asked for.\n# Has to be done manually for newer devices (not an \"old\" LPC2917/2919).\nif { $HAS_ETB == 1 } {\n    # Clear the HAS_ETB flag. Must be set again for a new tap in the chain.\n    set HAS_ETB 0\n\n    # Add the ETB tap controller and the ARM9 core debug tap\n    jtag newtap $_CHIPNAME etb -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_ETBTAPID\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n\n    # Configure ETM and ETB\n    etm config $_TARGETNAME 8 normal full etb\n    etb config $_TARGETNAME $_CHIPNAME.etb\n\n} else {\n    # Add the ARM9 core debug tap\n    jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n    # Create the \".cpu\" target\n    target create $_TARGETNAME arm966e -endian little -chain-position $_TARGETNAME\n}\n\narm7_9 dbgrq enable\narm7_9 dcc_downloads enable\n\n# Flash bank configuration:\n# Flash: flash bank lpc2900 0 0 0 0 <target#> <flash clock (CLK_SYS_FMC) in kHz>\n# Flash base address, total flash size, and number of sectors are all configured automatically.\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2900 0 0 0 0 $_TARGETNAME $FLASH_CLOCK\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc2xxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Common setup for the LPC2xxx parts\n\n# parameters:\n# - chip_name - name of the chip, e.g. lpc2103\n# - cputapids - TAP IDs of the core, should be quoted if more than one, e.g. 0x4f1f0f0f or \"0x3f0f0f0f 0x4f1f0f0f\"\n# - flash_size - size of on-chip flash (available for code, not including the bootloader) in bytes, e.g. 0x8000\n# - flash_variant - \"type\" of LPC2xxx device, lpc2000_v1 (LPC22xx and older LPC21xx) or lpc2000_v2 (LPC213x, LPC214x, LPC210[123], LPC23xx and LPC24xx)\n# - workarea_size - size of work-area in RAM for flashing procedures, must not exceed the size of RAM available at 0x40000000, e.g. 0x2000\n# - core_freq_khz - frequency of core in kHz during flashing, usually equal to connected crystal or internal oscillator, e.g. 12000\n# - adapter_freq_khz - frequency of debug adapter in kHz, should be 8x slower than core_freq_khz, e.g. 1000\n\nproc setup_lpc2xxx {chip_name cputapids flash_size flash_variant workarea_size core_freq_khz adapter_freq_khz} {\n\treset_config trst_and_srst\n\n\t# reset delays\n\tadapter srst delay 100\n\tjtag_ntrst_delay 100\n\n\tadapter speed $adapter_freq_khz\n\n\tforeach i $cputapids {\n\t\tappend expected_ids \"-expected-id \" $i \" \"\n\t}\n\n\teval \"jtag newtap $chip_name cpu -irlen 4 -ircapture 0x1 -irmask 0xf $expected_ids\"\n\n\tglobal _TARGETNAME\n\tset _TARGETNAME $chip_name.cpu\n\ttarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n\t$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size $workarea_size -work-area-backup 0\n\n\tif { $flash_size > 0 } {\n\t\t# flash bank <name> lpc2000 <base> <size> 0 0 <target#> <variant> <clock> [calc checksum]\n\t\tset _FLASHNAME $chip_name.flash\n\t\tflash bank $_FLASHNAME lpc2000 0x0 $flash_size 0 0 $_TARGETNAME $flash_variant $core_freq_khz calc_checksum\n\t}\n}\n\nproc init_targets {} {\n\t# FIX!!! read out CPUTAPID here and choose right setup. In addition to the\n\t# CPUTAPID some querying of the target would be required.\n\treturn -error \"This is a generic LPC2xxx configuration file, use a specific target file.\"\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc3131.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    NXP lpc3131\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3131\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# ARM926EJS core\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926f0f\n}\n\n# Scan Tap\n# Wired to separate STDO pin on the lpc3131, externally muxed to TDO on ea3131 module\n# JTAGSEL pin must be 0 to activate, which reassigns arm tdo to a pass through.\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1541E02B\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n##################################################################\n# various symbol definitions, to avoid hard-wiring addresses\n##################################################################\n\nglobal lpc313x\nset lpc313x [ dict create ]\n\n# Physical addresses for controllers and memory\ndict set lpc313x sram0\t\t\t0x11028000\ndict set lpc313x sram1\t\t\t0x11040000\ndict set lpc313x uart\t\t\t0x15001000\ndict set lpc313x cgu\t\t\t0x13004000\ndict set lpc313x ioconfig\t\t0x13003000\ndict set lpc313x sysconfig\t\t0x13002800\ndict set lpc313x wdt\t\t\t0x13002400\n\n##################################################################\n# Target configuration\n##################################################################\n\nadapter srst delay 1000\njtag_ntrst_delay 0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME invoke-event halted\n\n$_TARGETNAME configure -work-area-phys [dict get $lpc313x sram0] -work-area-size 0x30000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\n\techo \"\\nRunning reset init script for LPC3131\\n\"\n\thalt\n\twait_halt\n\treg cpsr 0xa00000d3\t;#Supervisor mode\n\treg pc 0x11029000\n\tpoll\n\tsleep 500\n}\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc3250.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# lpc3250 config\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lpc3250\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x17900f0f\n}\n\nif { [info exists CPUTAPID_REV_A0] } {\n   set _CPUTAPID_REV_A0 $CPUTAPID_REV_A0\n} else {\n   set _CPUTAPID_REV_A0 0x17926f0f\n}\n\nif { [info exists SJCTAPID] } {\n   set _SJCTAPID $SJCTAPID\n} else {\n   set _SJCTAPID 0x1b900f0f\n}\n\njtag newtap $_CHIPNAME sjc -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_SJCTAPID\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID \\\n     -expected-id $_CPUTAPID_REV_A0\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian little -chain-position $_TARGETNAME -work-area-phys 0x00000000 -work-area-size 0x7d0000 -work-area-backup 0\n\nproc power_restore {} { echo \"Sensed power restore. No action.\" }\nproc srst_deasserted {} { echo \"Sensed nSRST deasserted. No action.\" }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc40xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC40xx Cortex-M4F with at least 16kB SRAM\nset CHIPNAME lpc40xx\nset CHIPSERIES lpc4000\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x4000\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc4350.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4350\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\nif { [using_jtag] } {\n\tswj_newdap $_CHIPNAME m0 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tdap create $_CHIPNAME.m0.dap -chain-position $_CHIPNAME.m0\n\ttarget create $_CHIPNAME.m0 cortex_m -dap $_CHIPNAME.m0.dap\n}\n\n# LPC4350 has 96+32 KB SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n\t\t\t-work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # on this CPU we should use VECTRESET to perform a soft reset and\n   # manually reset the periphery\n   # SRST or SYSRESETREQ disable the debug interface for the time of\n   # the reset and will not fit our requirements for a consistent debug\n   # session\n   cortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc4357.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP LPC4357\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc4357\n}\nset WORKAREASIZE 0x8000\nsource [find target/lpc4350.cfg]\n\nflash bank $_CHIPNAME.flasha lpc2000 0x1A000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\nflash bank $_CHIPNAME.flashb lpc2000 0x1B000000 0x80000 0 0 $_CHIPNAME.m4 lpc4300 204000 calc_checksum\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc4370.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP LPC4370 - 1x ARM Cortex-M4 + 2x ARM Cortex-M0 @ up to 204 MHz each\n#\n\nadapter speed 500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME lpc4370\n}\n\n#\n# M4 JTAG mode TAP\n#\nif { [info exists M4_JTAG_TAPID] } {\n\tset _M4_JTAG_TAPID $M4_JTAG_TAPID\n} else {\n\tset _M4_JTAG_TAPID 0x4ba00477\n}\n\n#\n# M4 SWD mode TAP\n#\nif { [info exists M4_SWD_TAPID] } {\n\tset _M4_SWD_TAPID $M4_SWD_TAPID\n} else {\n\tset _M4_SWD_TAPID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _M4_TAPID $_M4_JTAG_TAPID\n} else {\n\tset _M4_TAPID $_M4_SWD_TAPID\n}\n\n#\n# M0 TAP\n#\nif { [info exists M0_JTAG_TAPID] } {\n\tset _M0_JTAG_TAPID $M0_JTAG_TAPID\n} else {\n\tset _M0_JTAG_TAPID 0x0ba01477\n}\n\nswj_newdap $_CHIPNAME m4 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t-expected-id $_M4_TAPID\ndap create $_CHIPNAME.m4.dap -chain-position $_CHIPNAME.m4\ntarget create $_CHIPNAME.m4 cortex_m -dap $_CHIPNAME.m4.dap\n\n# LPC4370 has 96+32 KB contiguous SRAM\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x20000\n}\n$_CHIPNAME.m4 configure -work-area-phys 0x10000000 \\\n                        -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME m0app -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\tjtag newtap $_CHIPNAME m0sub -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t\t\t\t\t-expected-id $_M0_JTAG_TAPID\n\n\tdap create $_CHIPNAME.m0app.dap -chain-position $_CHIPNAME.m0app\n\tdap create $_CHIPNAME.m0sub.dap -chain-position $_CHIPNAME.m0sub\n\ttarget create $_CHIPNAME.m0app cortex_m -dap $_CHIPNAME.m0app.dap\n\ttarget create $_CHIPNAME.m0sub cortex_m -dap $_CHIPNAME.m0sub.dap\n\n\t# 32+8+32 KB SRAM\n\t$_CHIPNAME.m0app configure -work-area-phys 0x10080000 \\\n\t                           -work-area-size 0x92000 -work-area-backup 0\n\n\t# 16+2 KB M0 subsystem SRAM\n\t$_CHIPNAME.m0sub configure -work-area-phys 0x18000000 \\\n\t                           -work-area-size 0x4800 -work-area-backup 0\n\n\t# Default to the Cortex-M4\n\ttargets $_CHIPNAME.m4\n}\n\nif { ![using_hla] } {\n\tcortex_m reset_config vectreset\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc84x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC84x Cortex-M0+ with at least 8kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc84x\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x1fe0\n}\n\nset IAP_ENTRY 0x0F001FF1\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc8nxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC8Nxx NHS31xx Cortex-M0+ with 8kB SRAM\n# Copyright (C) 2018 by Jean-Christian de Rivaz\n# Based on NXP proposal https://community.nxp.com/message/1011149\n# Many thanks to Dries Moors from NXP support.\n# SWD only transport\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME lpc8nxx\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id 0\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\nif {![using_hla]} {\n\t# If srst is not fitted use SYSRESETREQ to  perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\nadapter srst delay 100\n\n$_TARGETNAME configure -work-area-phys 0x10000000 -work-area-size 0x1ff0 -work-area-backup 0\n\nflash bank $_CHIPNAME.flash lpc2000 0x0 0x7800 0 0 $_TARGETNAME lpc800 500\n\necho \"*********************************************************************************\"\necho \"*         !!!!! IMPORTANT NOTICE FOR LPC8Nxx and NHS31xx CHIPS !!!!!\"\necho \"* When this IC is in power-off or peep power down mode, the SWD HW block is also\"\necho \"* unpowered. These modes can be entered by firmware. The default firmware image\"\necho \"* (flashed in production) makes use of this. Best is to avoid these power modes\"\necho \"* during development, and only later add them when the functionality is complete.\"\necho \"* Hardware reset or NFC field are the only ways to connect in case the SWD is\"\necho \"* powered off. OpenOCD can do a hardware reset if you wire the adapter SRST\"\necho \"* signal to the chip RESETN pin and add the following in your configuration:\"\necho \"*     reset_config srst_only; flash init; catch init; reset\"\necho \"* But if the actual firmware immediately set the power down mode after reset,\"\necho \"* OpenOCD might be not fast enough to halt the CPU before the SWD lost power. In\"\necho \"* that case the only solution is to apply a NFC field to keep the SWD powered.\"\necho \"*********************************************************************************\"\n\n# Using soft-reset 'reset_config none' is strongly discouraged.\n# RESETN sets the system clock to 500 kHz. Unlike soft-reset does not.\n# Set the system clock to 500 kHz before reset to simulate the functionality of hw reset.\n#\nproc set_sysclk_500khz {} {\n\tset SYSCLKCTRL 0x40048020\n\tset SYSCLKUEN 0x40048024\n\tmww $SYSCLKUEN 0\n\tmmw $SYSCLKCTRL 0x8 0xe\n\tmww $SYSCLKUEN 1\n\techo \"Notice: sysclock set to 500kHz.\"\n}\n\n# Do not remap the ARM interrupt vectors to anything but the beginning of the flash.\n# Table System memory remap register (SYSMEMREMAP, address 0x4004 8000) bit description\n# Bit Symbol  Value   Description\n# 0   map         -   interrupt vector remap. 0 after boot.\n#                 0   interrupt vector reside in Flash\n#                 1   interrupt vector reside in SRAM\n# 5:1 offset      -   system memory remap offset. 00000b after boot.\n#            00000b   interrupt vectors in flash or remapped to SRAM but no offset\n#            00001b -\n#            00111b   interrupt vectors offset in flash or SRAM to 1K word segment\n#            01000b -\n#            11111b   interrupt vectors offset in flash to 1K word segment 8 to 31\n# 31:6                reserved\n#\nproc set_no_remap {} {\n\tmww 0x40048000 0x00\n\techo \"Notice: interrupt vector set to no remap.\"\n}\n\n$_TARGETNAME configure -event reset-init {\n\tset_sysclk_500khz\n\tset_no_remap\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lpc8xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP LPC8xx Cortex-M0+ with at least 1kB SRAM\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME lpc8xx\n}\nset CHIPSERIES lpc800\nif { ![info exists WORKAREASIZE] } {\n\tset WORKAREASIZE 0x400\n}\n\nsource [find target/lpc1xxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ls1012a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# NXP LS1012A\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1012a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b2001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ncti create $_CHIPNAME.cti -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0x80420000\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME aarch64 -dap $_CHIPNAME.dap -dbgbase 0x80410000 -cti $_CHIPNAME.cti\n\ntarget smp $_TARGETNAME\n\nadapter speed 2000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ls1028a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1028A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1028a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\nset _CPUS 2\n\nsource [find target/lsch3_common.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ls1046a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1046A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1046a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nif { [info exists SAP_TAPID] } {\n\tset _SAP_TAPID $SAP_TAPID\n} else {\n\tset _SAP_TAPID 0x06b3001d\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\nset _CPU_BASE 0x80400000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < 4} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t-coreid $i {*}[expr {$i ? {-defer-examine} : {-rtos hwthread} }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\njtag newtap $_CHIPNAME sap -irlen 8 -expected-id $_SAP_TAPID\ntarget create $_CHIPNAME.sap ls1_sap -chain-position $_CHIPNAME.sap -endian big\n\nproc core_up { args } {\n    foreach core $args {\n        $::_CHIPNAME.cpu$core arp_examine\n    }\n}\n\ntargets $_CHIPNAME.cpu0\n\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ls1088a.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# NXP LS1088A\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME ls1088a\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\nset _CPUS 8\n\nsource [find target/lsch3_common.cfg]\n\n# Seems to work OK in testing\nadapter speed 10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/lsch3_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# This contains common configuration for NXP Layerscape chassis generation 3\n\nif { ![info exists _CPUS] } {\n\terror \"_CPUS must be set to the number of cores\"\n}\n\njtag newtap $_CHIPNAME dap -irlen 4 -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.dap\n\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 1\n\nset _CPU_BASE 0x81000000\nset _CPU_STRIDE 0x100000\nset _CPU_DBGOFF 0x10000\nset _CPU_CTIOFF 0x20000\n\nset _TARGETS {}\nfor {set i 0} {$i < $_CPUS} {incr i} {\n\tset _BASE [expr {$_CPU_BASE + $_CPU_STRIDE * $i}]\n\tcti create $_CHIPNAME.cti$i -dap $_CHIPNAME.dap -ap-num 0 \\\n\t\t-baseaddr [expr {$_BASE + $_CPU_CTIOFF}]\n\ttarget create $_CHIPNAME.cpu$i aarch64 -dap $_CHIPNAME.dap \\\n\t\t-cti $_CHIPNAME.cti$i -dbgbase [expr {$_BASE + $_CPU_DBGOFF}] \\\n\t\t{*}[expr {$i ? \"-coreid $i\" : \"-rtos hwthread\" }]\n\tlappend _TARGETS $_CHIPNAME.cpu$i\n}\n\ntarget smp {*}$_TARGETS\n\n# Service processor\ntarget create $_CHIPNAME.sp cortex_a -dap $_CHIPNAME.dap -ap-num 0 -dbgbase 0x80138000\n\n# Normally you will not need to call this, but if you are using the hard-coded\n# Reset Configuration Word (RCW) you will need to call this manually. The CPU's\n# reset vector is 0, and the boot ROM at that location contains ARMv7-A 32-bit\n# instructions. This will cause the CPU to almost immediately execute an\n# illegal instruction.\n#\n# This code is idempotent; releasing a released CPU has no effect, although it\n# will halt/resume the service processor.\nadd_help_text release_cpu \"Release a cpu which is held off\"\nproc release_cpu {cpu} {\n\tset RST_BRRL 0x1e60060\n\n\tset old [target current]\n\ttargets $::_CHIPNAME.sp\n\tset not_halted [string compare halted [$::_CHIPNAME.sp curstate]]\n\tif {$not_halted} {\n\t\thalt\n\t}\n\n\t# Release the cpu; it will start executing something bogus\n\tmem2array regs 32 $RST_BRRL 1\n\tmww $RST_BRRL [expr {$regs(0) | 1 << $cpu}]\n\n\tif {$not_halted} {\n\t\tresume\n\t}\n\ttargets $old\n}\n\ntargets $_CHIPNAME.cpu0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/marvell/88f3710.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Marvell Armada 3710\n\nset CORES 1\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/marvell/88f3720.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Marvell Armada 3720\n\nset CORES 2\n\nsource [find target/marvell/88f37x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/marvell/88f37x0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Main file for Marvell Armada 3700 series targets\n#\n# !!!!!!\n#\n# This file should not be included directly. Instead, please include\n# either marvell/88f3710.cfg or marvell/88f3720.cfg, which set the needed\n# variables to the appropriate values.\n#\n# !!!!!!\n\n# Armada 3700 supports both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CORES] } {\n    set _cores $CORES\n} else {\n    error \"CORES not set. Please do not include marvell/88f37x0.cfg directly, but the specific chip configuration file (marvell/88f3710.cfg, marvell/88f3720.cfg, etc.).\"\n}\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME [format a37%s0 $_cores]\n}\n\nset _ctis {0x80820000 0x80920000}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x4ba00477\n}\n\n# declare the one JTAG tap to access the DAP\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -ignore-version -enable\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# declare the main application cores\nset _TARGETNAME $_CHIPNAME.cpu\nset _smp_command \"\"\n\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [lindex $_ctis $_core] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core \\\n                         -cti cti$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n    } else {\n        set _command \"$_command -rtos hwthread\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\n# declare the auxiliary Cortex-M3 core on AP #3\ntarget create ${_TARGETNAME}.m3 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/max32620.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Maxim Integrated MAX32620 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -ignore-version\n} else {\n    swd newdap max32620 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\ndap create max32620.dap -chain-position max32620.cpu\n\n# target configuration\ntarget create max32620.cpu cortex_m -dap max32620.dap\nmax32620.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32620 flash base address   0x00000000\n#   max32620 flash size           0x200000 (2MB)\n#   max32620 FLC base address     0x40002000\n#   max32620 sector (page) size   0x2000 (8kB)\n#   max32620 clock speed          96 (MHz)\nflash bank max32620.flash max32xxx 0x00000000 0x200000 0 0 max32620.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/max32625.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Maxim Integrated MAX32625 OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f71197 -ignore-version\n} else {\n    swd newdap max32625 cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\ndap create max32625.dap -chain-position max32625.cpu\n\n# target configuration\ntarget create max32625.cpu cortex_m -dap max32625.dap\nmax32625.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max32625 flash base address   0x00000000\n#   max32625 flash size           0x80000 (512k)\n#   max32625 FLC base address     0x40002000\n#   max32625 sector (page) size   0x2000 (8kB)\n#   max32625 clock speed          96 (MHz)\nflash bank max32625.flash max32xxx 0x00000000 0x80000 0 0 max32625.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/max3263x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Maxim Integrated MAX3263X OpenOCD target configuration file\n# www.maximintegrated.com\n\n# adapter speed\nadapter speed 4000\n\n# reset pin configuration\nreset_config srst_only\n\nif {[using_jtag]} {\n    jtag newtap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x4ba00477 -ignore-version\n    jtag newtap maxtest tap -irlen 4 -irmask 0xf -ircapture 0x1 -expected-id 0x07f76197 -ignore-version\n} else {\n    swd newdap max3263x cpu -irlen 4 -irmask 0xf -expected-id 0x2ba01477 -ignore-version\n}\n\ndap create max3263x.dap -chain-position max3263x.cpu\n\n# target configuration\ntarget create max3263x.cpu cortex_m -dap max3263x.dap\nmax3263x.cpu configure -work-area-phys 0x20005000 -work-area-size 0x2000\n\n# Config Command: flash bank name driver base size chip_width bus_width target [driver_options]\n#   flash bank <name> max32xxx <base> <size> 0 0 <target> <flc base> <sector> <clk> <burst>\n#   max3263x flash base address   0x00000000\n#   max3263x flash size           0x200000 (2MB)\n#   max3263x FLC base address     0x40002000\n#   max3263x sector (page) size   0x2000 (8kB)\n#   max3263x clock speed          96 (MHz)\nflash bank max3263x.flash max32xxx 0x00000000 0x200000 0 0 max3263x.cpu 0x40002000 0x2000 96\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/mc13224v.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find bitsbytes.tcl]\nsource [find cpu/arm/arm7tdmi.tcl]\nsource [find memory.tcl]\nsource [find mmr_helpers.tcl]\n\nset CHIP_MAKER             freescale\nset CHIP_FAMILY            mc1322x\nset CHIP_NAME              mc13224\nset N_RAM                  1\nset RAM(0,BASE)            0x00400000\nset RAM(0,LEN)             0x18000\nset RAM(0,HUMAN)           \"internal SRAM\"\nset RAM(0,TYPE)            \"ram\"\nset RAM(0,RWX)             $RWX_RWX\nset RAM(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\n# I AM LAZY... I create 1 region for all MMRs.\nset N_MMREGS                  1\nset MMREGS(0,CHIPSELECT)      -1\nset MMREGS(0,BASE)            0x80000000\nset MMREGS(0,LEN)             0x00030000\nset MMREGS(0,HUMAN)           \"mm-regs\"\nset MMREGS(0,TYPE)            \"mmr\"\nset MMREGS(0,RWX)             $RWX_RW\nset MMREGS(0,ACCESS_WIDTH)    $ACCESS_WIDTH_ANY\n\nset N_XMEM 0\n\nset _CHIPNAME mc13224v\nset _CPUTAPID 0x1f1f001d\n\njtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\nreset_config srst_only\njtag_ntrst_delay 200\n\n# rclk hasn't been working well. This maybe the mc13224v or something else.\n#adapter speed 2000\nadapter speed 2000\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -chain-position $_TARGETNAME\n\n# Internal sram memory\n$_TARGETNAME configure -work-area-phys 0x00408000 \\\n                       -work-area-size 0x1000     \\\n                       -work-area-backup 1\n\n# flash support is pending (should be straightforward to implement)\n#flash bank mc1322x 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/mdr32f9q2i.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# MDR32F9Q2I (1986ВЕ92У)\n# http://milandr.ru/index.php?mact=Products,cntnt01,details,0&cntnt01productid=57&cntnt01returnid=68\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME mdr32f9q2i\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x4ba00477\n   } {\n      # SWD IDCODE\n      set _CPUTAPID 0x2ba01477\n   }\n}\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# can't handle overlapping memory regions\nif { [info exists IMEMORY] && [string equal $IMEMORY true] } {\n   flash bank ${_CHIPNAME}_info.flash mdr 0x08000000 0x01000 0 0 $_TARGETNAME 1 1 4\n} else {\n   flash bank $_CHIPNAME.flash mdr 0x08000000 0x20000 0 0 $_TARGETNAME 0 32 4\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n   jtag_ntrst_delay 100\n}\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/nds32v5.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Andes Core\n#\n# http://www.andestech.com\n#\n\nset _CHIPNAME nds\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563D\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ngultra.cfg",
    "content": "# SPDX-License-Identifier: BSD-3-Clause\n# Copyright (C) 2022 by NanoXplore, France - all rights reserved\n#\n# configuration file for NG-Ultra SoC from NanoXplore.\n# NG-Ultra is a quad-core Cortex-R52 SoC + an FPGA.\n#\ntransport select jtag\nadapter speed 10000\n\nif { [info exists CHIPNAME] } {\n   set  _CHIPNAME $CHIPNAME\n} else {\n   set  _CHIPNAME NGULTRA\n}\n\nif { [info exists CHIPCORES] } {\n    set _cores $CHIPCORES\n} else {\n    set _cores 4\n}\n\nset DBGBASE {0x88210000 0x88310000 0x88410000 0x88510000}\nset CTIBASE {0x88220000 0x88320000 0x88420000 0x88520000}\n\n# Coresight access to the SoC\njtag newtap $_CHIPNAME.coresight cpu      -irlen 4 -expected-id 0x6BA00477\n\n# Misc TAP devices\njtag newtap $_CHIPNAME.soc       cpu      -irlen 7 -expected-id 0xFAAA0555\njtag newtap $_CHIPNAME.pmb       unknown1 -irlen 5 -expected-id 0xBA20A005\njtag newtap $_CHIPNAME.fpga      fpga     -irlen 4 -ignore-version -ignore-bypass\n\n# Create the Coresight DAP\ndap create $_CHIPNAME.coresight.dap -chain-position $_CHIPNAME.coresight.cpu\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n    cti create cti.$_core -dap $_CHIPNAME.coresight.dap -ap-num 0 \\\n        -baseaddr [lindex $CTIBASE $_core]\n# Cores are armv8-r but works with aarch64 (since armv8-r not directly supported by openocd yet).\n    if { $_core == 0} {\n        target create core.$_core aarch64 -dap $_CHIPNAME.coresight.dap \\\n            -ap-num 0 -dbgbase [lindex $DBGBASE $_core] -cti cti.$_core\n    } else {\n        target create core.$_core aarch64 -dap $_CHIPNAME.coresight.dap \\\n            -ap-num 0 -dbgbase [lindex $DBGBASE $_core] -cti cti.$_core -defer-examine\n    }\n}\n\n# Create direct APB and AXI interfaces\ntarget create APB mem_ap -dap $_CHIPNAME.coresight.dap -ap-num 0\ntarget create AXI mem_ap -dap $_CHIPNAME.coresight.dap -ap-num 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/nhs31xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP NHS31xx Cortex-M0+ with 8kB SRAM\n\nset CHIPNAME nhs31xx\nsource [find target/lpc8nxx.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/npcx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton NPCX Cortex-M4 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NPCX_M4\n}\n\n# SWD DAP ID of Nuvoton NPCX Cortex-M4.\nif { [info exists CPUDAPID ] } {\n   set _CPUDAPID $CPUDAPID\n} else {\n   set _CPUDAPID 0x4BA00477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x200c0000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# Initial JTAG/SWD speed\n# For safety purposes, set for the lowest cpu clock configuration\n# 4MHz / 6 = 666KHz, so use 600KHz for it\nadapter speed 600\n\n# For safety purposes, set for the lowest cpu clock configuration\n$_TARGETNAME configure -event reset-start {adapter speed 600}\n\n# use sysresetreq to perform a system reset\ncortex_m reset_config sysresetreq\n\n# flash configuration\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME npcx 0x64000000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/nrf51.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# script for Nordic nRF51 series, a Cortex-M0 chip\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nrf51\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif {![using_hla]} {\n   # The chip supports standard ARM/Cortex-M0 SYSRESETREQ signal\n   cortex_m reset_config sysresetreq\n}\n\nflash bank $_CHIPNAME.flash nrf51 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf51 0x10001000 0 1 1 $_TARGETNAME\n\n#\n#  The chip should start up from internal 16Mhz RC, so setting adapter\n#  clock to 1Mhz should be OK\n#\nadapter speed 1000\n\nproc enable_all_ram {} {\n\t# nRF51822 Product Anomaly Notice (PAN) #16 explains that not all RAM banks\n\t# are reliably enabled after reset on some revisions (contrary to spec.) So after\n\t# resetting we enable all banks via the RAMON register\n\tmww 0x40000524 0xF\n}\n$_TARGETNAME configure -event reset-end {  enable_all_ram }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/nrf52.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nordic nRF52 series: ARM Cortex-M4 @ 64 MHz\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME nrf52\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nadapter speed 1000\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { [using_hla] } {\n\techo \"\"\n\techo \"nRF52 device has a CTRL-AP dedicated to recover the device from AP lock.\"\n\techo \"A high level adapter (like a ST-Link) you are currently using cannot access\"\n\techo \"the CTRL-AP so 'nrf52_recover' command will not work.\"\n\techo \"Do not enable UICR APPROTECT.\"\n\techo \"\"\n} else {\n\tcortex_m reset_config sysresetreq\n\n\t$_TARGETNAME configure -event examine-fail nrf52_check_ap_lock\n}\n\nflash bank $_CHIPNAME.flash nrf5 0x00000000 0 1 1 $_TARGETNAME\nflash bank $_CHIPNAME.uicr nrf5 0x10001000 0 1 1 $_TARGETNAME\n\n# Test if MEM-AP is locked by UICR APPROTECT\nproc nrf52_check_ap_lock {} {\n\tset dap [[target current] cget -dap]\n\tset err [catch {set APPROTECTSTATUS [$dap apreg 1 0xc]}]\n\tif {$err == 0 && $APPROTECTSTATUS != 1} {\n\t\techo \"****** WARNING ******\"\n\t\techo \"nRF52 device has AP lock engaged (see UICR APPROTECT register).\"\n\t\techo \"Debug access is denied.\"\n\t\techo \"Use 'nrf52_recover' to erase and unlock the device.\"\n\t\techo \"\"\n\t\tpoll off\n\t}\n}\n\n# Mass erase and unlock the device using proprietary nRF CTRL-AP (AP #1)\n# http://www.ebyte.com produces modules with nRF52 locked by default,\n# use nrf52_recover to enable flashing and debug.\nproc nrf52_recover {} {\n\tset target [target current]\n\tset dap [$target cget -dap]\n\n\tset IDR [$dap apreg 1 0xfc]\n\tif {$IDR != 0x02880000} {\n\t\techo \"Error: Cannot access nRF52 CTRL-AP!\"\n\t\treturn\n\t}\n\n\tpoll off\n\n\t# Reset and trigger ERASEALL task\n\t$dap apreg 1 4 0\n\t$dap apreg 1 4 1\n\n\tfor {set i 0} {1} {incr i} {\n\t\tset ERASEALLSTATUS [$dap apreg 1 8]\n\t\tif {$ERASEALLSTATUS == 0} {\n\t\t\techo \"$target device has been successfully erased and unlocked.\"\n\t\t\tbreak\n\t\t}\n\t\tif {$i == 0} {\n\t\t\techo \"Waiting for chip erase...\"\n\t\t}\n\t\tif {$i >= 150} {\n\t\t\techo \"Error: $target recovery failed.\"\n\t\t\tbreak\n\t\t}\n\t\tsleep 100\n\t}\n\n\t# Assert reset\n\t$dap apreg 1 0 1\n\n\t# Deassert reset\n\t$dap apreg 1 0 0\n\n\t# Reset ERASEALL task\n\t$dap apreg 1 4 0\n\n\tsleep 100\n\t$target arp_examine\n\tpoll on\n}\n\nadd_help_text nrf52_recover \"Mass erase and unlock nRF52 device\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/nuc910.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Nuvoton nuc910 (previously W90P910) based soc\n#\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME nuc910\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x07926f0f\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/numicro.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton MuMicro Cortex-M0 Series\n\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NuMicro\n}\n\n# SWD DP-ID Nuvoton NuMicro Cortex-M0 has SWD Transport only.\nif { [info exists CPUDAPID] } {\n\tset _CPUDAPID $CPUDAPID\n} else {\n\tset _CPUDAPID 0x0BB11477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash_aprom\nflash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_data\nflash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_ldrom\nflash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_config\nflash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME\n\n# set default SWCLK frequency\nadapter speed 1000\n\n# set default srst setting \"none\"\nreset_config none\n\n# HLA doesn't have cortex_m commands\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/numicro_m4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Nuvoton MuMicro Cortex-M4 Series\n\nsource [find target/swj-dp.tcl]\n\n# Set Chipname\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME NuMicro\n}\n\n# SWD DP-ID Nuvoton NuMicro Cortex-M4 has SWD Transport only.\nif { [info exists CPUDAPID] } {\n\tset _CPUDAPID $CPUDAPID\n} else {\n\tset _CPUDAPID 0x2BA01477\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n\n# Debug Adapter Target Settings\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUDAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash bank <name> numicro <base> <size(autodetect,set to 0)> 0 0 <target#>\n#set _FLASHNAME $_CHIPNAME.flash\n#flash bank $_FLASHNAME numicro 0 $_FLASHSIZE 0 0 $_TARGETNAME\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash_aprom\nflash bank $_FLASHNAME numicro 0x00000000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_data\nflash bank $_FLASHNAME numicro 0x0001F000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_ldrom\nflash bank $_FLASHNAME numicro 0x00100000 0 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash_config\nflash bank $_FLASHNAME numicro 0x00300000 0 0 0 $_TARGETNAME\n\n# set default SWCLK frequency\nadapter speed 1000\n\n# set default srst setting \"none\"\nreset_config none\n\n# HLA doesn't have cortex_m commands\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omap2420.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Texas Instruments OMAP 2420\n#\thttp://www.ti.com/omap\n# as seen in Nokia N8x0 tablets\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap2420\n}\n\n# NOTE: likes slowish clock on reset (1.5 MBit/s or less) or use RCLK\nreset_config srst_nogate\n\n# Subsidiary TAP: ARM7TDMIr4 plus imaging ... must add via ICEpick (addr 6).\njtag newtap $_CHIPNAME iva -irlen 4 -disable\n\n# Subsidiary TAP: C55x DSP ... must add via ICEpick (addr 2).\njtag newtap $_CHIPNAME dsp -irlen 38 -disable\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETB_TAPID\n\n# Subsidiary TAP: ARM1136jf-s with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07b3602f\n}\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\n# Primary TAP: ICEpick-B (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x01ce4801\n}\njtag newtap $_CHIPNAME jrc -irlen 2 -expected-id $_JRC_TAPID\n\n# GDB target: the ARM.\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_TARGETNAME\n\n# scratch: framebuffer, may be initially unavailable in some chips\n$_TARGETNAME configure -work-area-phys 0x40210000\n$_TARGETNAME configure -work-area-size 0x00081000\n$_TARGETNAME configure -work-area-backup 0\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\n# RM_RSTCTRL_WKUP.RST.GS - Trigger a global software reset, and\n# give it a chance to finish before we talk to the chip again.\nset RM_RSTCTRL_WKUP 0x48008450\n$_TARGETNAME configure -event reset-assert \\\n\t\"halt; $_TARGETNAME mww $RM_RSTCTRL_WKUP 2; sleep 200\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omap3530.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TI OMAP3530\n# http://focus.ti.com/docs/prod/folders/print/omap3530.html\n# Other OMAP3 chips remove DSP and/or the OpenGL support\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap3530\n}\n\n# ICEpick-C ... used to route Cortex, DSP, and more not shown here\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\n\n# Subsidiary TAP: CoreSight Debug Access Port (DAP)\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x0b6d602f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7ae02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID\n\n# GDB target: Cortex-A8, using DAP\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap\n\n# SRAM: 64K at 0x4020.0000; use the first 16K\n$_TARGETNAME configure -work-area-phys 0x40200000 -work-area-size 0x4000\n\n###################\n\n# the reset sequence is event-driven\n# and kind of finicky...\n\n# some TCK tycles are required to activate the DEBUG power domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\n# have the DAP \"always\" be active\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.dap\"\n\nproc omap3_dbginit {target} {\n     # General Cortex-A8 debug initialisation\n     cortex_a dbginit\n     # Enable DBGU signal for OMAP353x\n     $target mww phys 0x5401d030 0x00002000\n}\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# 16.8MHz/2 = 8.4MHz core clock, even before a bootloader kicks in.\n# OK to speed up *after* PLL and clock tree setup.\nadapter speed 1000\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1000 }\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  RST_GS (2) is a warm reset, like ICEpick\n# would issue.  RST_DPLL3 (4) is a cold reset.\nset PRM_RSTCTRL 0x48307250\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww $PRM_RSTCTRL 2\"\n\n$_TARGETNAME configure -event reset-assert-post \"omap3_dbginit $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omap4430.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OMAP4430\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4430\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x3b95c02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omap4460.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OMAP4460\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME omap4460\n}\n\n\n# Although the OMAP4430 supposedly has an ICEpick-D, only the\n# ICEpick-C router commands seem to work.\n# See http://processors.wiki.ti.com/index.php/ICEPICK\nsource [find target/icepick.cfg]\n\n\n#\n# A9 DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x3BA00477\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 9\"\n\n\n#\n# M3 DAPs, one per core\n#\nif { [info exists M3_DAP_TAPID] } {\n\tset _M3_DAP_TAPID $M3_DAP_TAPID\n} else {\n\tset _M3_DAP_TAPID 0x4BA00477\n}\n\njtag newtap $_CHIPNAME m31 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m31 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 5\"\n\njtag newtap $_CHIPNAME m30 -irlen 4 -ircapture 0x1 -irmask 0xf \\\n\t-expected-id $_M3_DAP_TAPID -disable\njtag configure $_CHIPNAME.m30 -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 4\"\n\n\n#\n# ICEpick-D JRC (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID  0x2b94e02f\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n# PandaBoard REV EA1 (PEAP platforms)\nif { [info exists JRC_TAPID2] } {\n\tset _JRC_TAPID2 $JRC_TAPID2\n} else {\n\tset _JRC_TAPID2 0x1b85202f\n}\n\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID -expected-id $_JRC_TAPID2\n\n# Required by ICEpick to power-up the debug domain\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 200\"\n\n\n#\n# GDB target: Cortex-A9, using DAP\n#\n# The debugger can connect to either core of the A9, but currently\n# not both simultaneously.  Change -coreid to 1 to connect to the\n# second core.\n#\nset _TARGETNAME $_CHIPNAME.cpu\n\n# APB DBGBASE reads 0x80040000, but this points to an empty ROM table.\n# 0x80000000 is cpu0 coresight region\n#\n#\n# CORTEX_A8_PADDRDBG_CPU_SHIFT 13\n# 0x80000000 | (coreid << CORTEX_A8_PADDRDBG_CPU_SHIFT)\n\nset _coreid 0\nset _dbgbase [expr {0x80000000 | ($_coreid << 13)}]\necho \"Using dbgbase = [format 0x%x $_dbgbase]\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_a -dap $_CHIPNAME.dap \\\n  -coreid 0 -dbgbase $_dbgbase\n\n# SRAM: 56KiB at 0x4030.0000\n$_TARGETNAME configure -work-area-phys 0x40300000 -work-area-size 0x1000\n\n\n#\n# M3 targets, separate TAP/DAP for each core\n#\ndap create $_CHIPNAME.m30_dap -chain-position $_CHIPNAME.m30\ndap create $_CHIPNAME.m31_dap -chain-position $_CHIPNAME.m31\ntarget create $_CHIPNAME.m30 cortex_m -dap $_CHIPNAME.m30_dap\ntarget create $_CHIPNAME.m31 cortex_m -dap $_CHIPNAME.m31_dap\n\n\n# Once the JRC is up, enable our TAPs\njtag configure $_CHIPNAME.jrc -event setup \"\n\tjtag tapenable $_CHIPNAME.cpu\n\tjtag tapenable $_CHIPNAME.m30\n\tjtag tapenable $_CHIPNAME.m31\n\"\n\n# Assume SRST is unavailable (e.g. TI-14 JTAG), so we must assert reset\n# ourselves using PRM_RSTCTRL.  1 is a warm reset, 2 a cold reset.\nset PRM_RSTCTRL 0x4A307B00\n$_TARGETNAME configure -event reset-assert \"$_TARGETNAME mww phys $PRM_RSTCTRL 0x1\"\n$_CHIPNAME.m30 configure -event reset-assert { }\n$_CHIPNAME.m31 configure -event reset-assert { }\n\n# Soft breakpoints don't currently work due to broken cache handling\ngdb_breakpoint_override hard\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omap5912.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TI OMAP5912 dual core processor\n# http://focus.ti.com/docs/prod/folders/print/omap5912.html\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omap5912\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # NOTE: validated with XOMAP5912 part\n   set _CPUTAPID 0x0692602f\n}\n\nadapter srst delay 100\n\n# NOTE: presumes irlen 38 is the C55x DSP, matching BSDL for\n# its standalone siblings (like TMS320VC5502) of the same era\n\n#jtag scan chain\njtag newtap $_CHIPNAME dsp -irlen 38 -expected-id 0x03df1d81\njtag newtap $_CHIPNAME arm -irlen 4 -expected-id $_CPUTAPID\njtag newtap $_CHIPNAME unknown -irlen 8\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\nproc omap5912_reset {} {\n\t#\n\t# halt target\n\t#\n\tpoll\n\tsleep 1\n\thalt\n\twait_halt\n\t#\n\t# disable wdt\n\t#\n\tmww 0xfffec808 0x000000f5\n\tmww 0xfffec808 0x000000a0\n\n\tmww 0xfffeb048 0x0000aaaa\n\tsleep 500\n\tmww 0xfffeb048 0x00005555\n\tsleep 500\n}\n\n# omap5912 lcd frame buffer as working area\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n\t-work-area-size 0x3e800 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/omapl138.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments DaVinci family: OMAPL138\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME omapl138\n}\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID -disable\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID -disable\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b7d102f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target:  the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n\ngdb_breakpoint_override hard\narm7_9 dbgrq enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/or1k.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset  _ENDIAN big\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME or1k\n}\n\nif { [info exists TAP_TYPE] } {\n   set _TAP_TYPE $TAP_TYPE\n} else {\n   puts \"You need to select a tap type\"\n   shutdown\n}\n\n# Configure the target\nif { [string compare $_TAP_TYPE \"VJTAG\"] == 0 } {\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 10 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select vjtag\n\n} elseif { [string compare $_TAP_TYPE \"XILINX_BSCAN\"] == 0 } {\n\n\tif { [info exists FPGATAPID] } {\n\t   set _FPGATAPID $FPGATAPID\n\t} else {\n\t   puts \"You need to set your FPGA JTAG ID\"\n\t\tshutdown\n\t}\n\n\tjtag newtap $_CHIPNAME cpu -irlen 6 -expected-id $_FPGATAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select xilinx_bscan\n} else {\n\t# OpenCores Mohor JTAG TAP ID\n\tset _CPUTAPID  0x14951185\n\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\ttarget create $_TARGETNAME or1k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n\t# Select the TAP core we are using\n\ttap_select mohor\n}\n\n# Select the debug unit core we are using. This debug unit as an option.\n\nset ADBG_USE_HISPEED\t\t1\nset ENABLE_JSP_SERVER\t\t2\nset ENABLE_JSP_MULTI\t\t4\n\n# If ADBG_USE_HISPEED is set (options bit 1), status bits will be skipped\n# on burst reads and writes to improve download speeds.\n# This option must match the RTL configured option.\n\ndu_select adv [expr {$ADBG_USE_HISPEED | $ENABLE_JSP_SERVER | $ENABLE_JSP_MULTI}]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/pic32mx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pic32mx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x30938053\n}\n\n# default working area is 16384\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_TARGETNAME\n\n#\n# At reset the pic32mx does not allow code execution from RAM\n# we have to setup the BMX registers to allow this.\n# One limitation is that we loose the first 2k of RAM.\n#\n\nglobal _PIC32MX_DATASIZE\nglobal _WORKAREASIZE\nset _PIC32MX_DATASIZE 0x800\nset _PIC32MX_PROGSIZE [expr {$_WORKAREASIZE - $_PIC32MX_DATASIZE}]\n\n$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size $_PIC32MX_PROGSIZE -work-area-backup 0\n$_TARGETNAME configure -event reset-init {\n\t#\n\t# from reset the pic32 cannot execute code in ram - enable ram execution\n\t# minimum offset from start of ram is 2k\n\t#\n\tglobal _PIC32MX_DATASIZE\n\tglobal _WORKAREASIZE\n\n\t# BMXCON\tset 0 wait state option by clearing BMXWSDRM bit, bit 6\n\tmww 0xbf882000 0x001f0000\n\t# BMXDKPBA: 2k kernel data @ 0xa0000000\n\tmww 0xbf882010 $_PIC32MX_DATASIZE\n\t# BMXDUDBA: 14k kernel program @ 0xa0000800 - (BMXDUDBA - BMXDKPBA)\n\tmww 0xbf882020 $_WORKAREASIZE\n\t# BMXDUPBA: 0k user program - (BMXDUPBA - BMXDUDBA)\n\tmww 0xbf882030 $_WORKAREASIZE\n\n\t#\n\t# Set system clock to 8Mhz if the default clock configuration is set\n\t#\n\n\t# SYSKEY register, make sure OSCCON is locked\n\tmww 0xbf80f230 0x0\n\t# SYSKEY register, write unlock sequence\n\tmww 0xbf80f230 0xaa996655\n\tmww 0xbf80f230 0x556699aa\n\t# OSCCON register + 4, clear OSCCON FRCDIV bits: 24, 25 and 26, divided by 1\n\tmww 0xbf80f004 0x07000000\n\t# SYSKEY register, relock OSCCON\n\tmww 0xbf80f230 0x0\n}\n\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank0 virtual 0xbfc00000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank1 virtual 0x9fc00000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME\n# add virtual banks for kseg0 and kseg1\nflash bank vbank2 virtual 0xbd000000 0 0 0 $_TARGETNAME $_FLASHNAME\nflash bank vbank3 virtual 0x9d000000 0 0 0 $_TARGETNAME $_FLASHNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/psoc4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Cypress PSoC 4 devices\n\n#\n# PSoC 4 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME psoc4\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc4 0 0 0 0 $_TARGETNAME\n\nadapter speed 1500\n\n# Reset, bloody PSoC 4 reset\n#\n# 1) XRES (nSRST) resets also SWD DP so SWD line reset and DP reinit is needed.\n# High level adapter stops working after SRST and needs OpenOCD restart.\n# If your hw does not use SRST for other circuits, use sysresetreq instead\n#\n# 2) PSoC 4 executes initialization code from system ROM after reset.\n# This code subsequently jumps to user flash reset vector address.\n# Unfortunately the system ROM code is protected from reading and debugging.\n# Protection breaks vector catch VC_CORERESET used for \"reset halt\" by cortex_m.\n#\n# Cypress uses TEST_MODE flag to loop CPU in system ROM before executing code\n# from user flash. Programming specifications states that TEST_MODE flag must be\n# set in time frame 400 usec delayed about 1 msec from reset.\n#\n# OpenOCD have no standard way how to set TEST_MODE in specified time frame.\n# As a workaround the TEST_MODE flag is set before reset instead.\n# It worked for the oldest family PSoC4100/4200 even though it is not guaranteed\n# by specification.\n#\n# Newer families like PSoC 4000, 4100M, 4200M, 4100L, 4200L and PSoC 4 BLE\n# clear TEST_MODE flag during device reset so workaround is not possible.\n# Use a KitProg adapter for these devices or \"reset halt\" will not stop\n# before executing user code.\n#\n# 3) SWD cannot be connected during system initialization after reset.\n# This might be a reason for unconnecting ST-Link v2 when deasserting reset.\n# As a workaround arp_reset deassert is not called for hla\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc psoc4_get_family_id {} {\n\tset err [catch {set romtable_pid [read_memory 0xF0000FE0 32 3]}]\n\tif { $err } {\n\t\treturn 0\n\t}\n\tif { [expr {[lindex $romtable_pid 0] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 1] & 0xffffff00 }]\n\t  || [expr {[lindex $romtable_pid 2] & 0xffffff00 }] } {\n\t\techo \"Unexpected data in ROMTABLE\"\n\t\treturn 0\n\t}\n\tset designer_id [expr {(( [lindex $romtable_pid 1] & 0xf0 ) >> 4) | (( [lindex $romtable_pid 2] & 0xf ) << 4 ) }]\n\tif { $designer_id != 0xb4 } {\n\t\techo [format \"ROMTABLE Designer ID 0x%02x is not Cypress\" $designer_id]\n\t\treturn 0\n\t}\n\tset family_id [expr {( [lindex $romtable_pid 0] & 0xff ) | (( [lindex $romtable_pid 1] & 0xf ) << 8 ) }]\n\treturn $family_id\n}\n\nproc ocd_process_reset_inner { MODE } {\n\tglobal PSOC4_USE_ACQUIRE PSOC4_TEST_MODE_WORKAROUND\n\tglobal _TARGETNAME\n\n\tif { 0 != [string compare $_TARGETNAME [target names]] } {\n\t\treturn -code error \"PSoC 4 reset can handle only one $_TARGETNAME target\";\n\t}\n\tset t $_TARGETNAME\n\n\t# If this target must be halted...\n\tset halt -1\n\tif { 0 == [string compare $MODE halt] } {\n\t\tset halt 1\n\t}\n\tif { 0 == [string compare $MODE init] } {\n\t\tset halt 1;\n\t}\n\tif { 0 == [string compare $MODE run ] } {\n\t\tset halt 0;\n\t}\n\tif { $halt < 0 } {\n\t\treturn -code error \"Invalid mode: $MODE, must be one of: halt, init, or run\";\n\t}\n\n\tif { ! [info exists PSOC4_USE_ACQUIRE] } {\n\t\tif { 0 == [string compare [adapter name] kitprog ] } {\n\t\t\tset PSOC4_USE_ACQUIRE 1\n\t\t} else {\n\t\t\tset PSOC4_USE_ACQUIRE 0\n\t\t}\n\t}\n\tif { $PSOC4_USE_ACQUIRE } {\n\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t} elseif { ! [info exists PSOC4_TEST_MODE_WORKAROUND] } {\n\t\tif { [psoc4_get_family_id] == 0x93 } {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 1\n\t\t} else {\n\t\t\tset PSOC4_TEST_MODE_WORKAROUND 0\n\t\t}\n\t}\n\n\t#$t invoke-event reset-start\n\t$t invoke-event reset-assert-pre\n\n\tif { $halt && $PSOC4_USE_ACQUIRE } {\n\t\tcatch { [adapter name] acquire_psoc }\n\t\t$t arp_examine\n\t} else {\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tset TEST_MODE 0x40030014\n\t\t\tif { $halt == 1 } {\n\t\t\t\tcatch { mww $TEST_MODE 0x80000000 }\n\t\t\t} else {\n\t\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t\t}\n\t\t}\n\n\t\t$t arp_reset assert 0\n\t}\n\n\t$t invoke-event reset-assert-post\n\t$t invoke-event reset-deassert-pre\n\tif {![using_hla]} {\t# workaround ST-Link v2 fails and forcing reconnect\n\t\t$t arp_reset deassert 0\n\t}\n\t$t invoke-event reset-deassert-post\n\n\t# Pass 1 - Now wait for any halt (requested as part of reset\n\t# assert/deassert) to happen.  Ideally it takes effect without\n\t# first executing any instructions.\n\tif { $halt } {\n\t\t# Now PSoC CPU should loop in system ROM\n\t\t$t arp_waitstate running 200\n\t\t$t arp_halt\n\n\t\t# Catch, but ignore any errors.\n\t\tcatch { $t arp_waitstate halted 1000 }\n\n\t\t# Did we succeed?\n\t\tset s [$t curstate]\n\n\t\tif { 0 != [string compare $s \"halted\" ] } {\n\t\t\treturn -code error [format \"TARGET: %s - Not halted\" $t]\n\t\t}\n\n\t\t# Check if PSoC CPU is stopped in system ROM\n\t\tset pc [reg pc]\n\t\tregsub {pc[^:]*: } $pc \"\" pc\n\t\tif { $pc < 0x10000000 || $pc > 0x1000ffff } {\n\t\t\tset hint \"\"\n\t\t\tset family_id [psoc4_get_family_id]\n\t\t\tif { $family_id == 0x93 } {\n\t\t\t\tset hint \", use 'reset_config none'\"\n\t\t\t} elseif { $family_id > 0x93 } {\n\t\t\t\tset hint \", use a KitProg adapter\"\n\t\t\t}\n\t\t\treturn -code error [format \"TARGET: %s - Not halted in system ROM%s\" $t $hint]\n\t\t}\n\n\t\t# Set registers to reset vector values\n\t\tset value [read_memory 0x0 32 2]\n\t\treg pc [expr {[lindex $value 1] & 0xfffffffe}]\n\t\treg msp [lindex $value 0]\n\n\t\tif { $PSOC4_TEST_MODE_WORKAROUND } {\n\t\t\tcatch { mww $TEST_MODE 0 }\n\t\t}\n\t}\n\n\t#Pass 2 - if needed \"init\"\n\tif { 0 == [string compare init $MODE] } {\n\t\tset err [catch \"$t arp_waitstate halted 5000\"]\n\n\t\t# Did it halt?\n\t\tif { $err == 0 } {\n\t\t\t$t invoke-event reset-init\n\t\t}\n\t}\n\n\t$t invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/psoc5lp.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Cypress PSoC 5LP\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc5lp\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_TAPID $CPUTAPID\n} else {\n\tset _CPU_TAPID 0x4BA00477\n}\n\nif { [using_jtag] } {\n\tset _CPU_DAP_ID $_CPU_TAPID\n} else {\n\tset _CPU_DAP_ID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys [expr {0x20000000 - $_WORKAREASIZE / 2}] \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nsource [find mem_helper.tcl]\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure Target Device (PSoC 5LP Device Programming Specification 5.2)\n\n\tset PANTHER_DBG_CFG 0x4008000C\n\tset PANTHER_DBG_CFG_BYPASS [expr {1 << 1}]\n\tmmw $PANTHER_DBG_CFG $PANTHER_DBG_CFG_BYPASS 0\n\n\tset PM_ACT_CFG0 0x400043A0\n\tmww $PM_ACT_CFG0 0xBF\n\n\tset FASTCLK_IMO_CR 0x40004200\n\tset FASTCLK_IMO_CR_F_RANGE_2    [expr {2 << 0}]\n\tset FASTCLK_IMO_CR_F_RANGE_MASK [expr {7 << 0}]\n\tmmw $FASTCLK_IMO_CR $FASTCLK_IMO_CR_F_RANGE_2 $FASTCLK_IMO_CR_F_RANGE_MASK\n}\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME psoc5lp 0x00000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.eeprom psoc5lp_eeprom 0x40008000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvl psoc5lp_nvl 0 0 0 0 $_TARGETNAME\n\nif {![using_hla]} {\n\tcortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/psoc6.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Configuration script for Cypress PSoC6 family of microcontrollers (CY8C6xxx)\n# PSoC6 is a dual-core device with CM0+ and CM4 cores. Both cores share\n# the same Flash/RAM/MMIO address space.\n#\n\nsource [find target/swj-dp.tcl]\n\nadapter speed 1000\n\nglobal _CHIPNAME\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME psoc6\n}\n\nglobal TARGET\nset TARGET $_CHIPNAME.cpu\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Is CM0 Debugging enabled ?\nglobal _ENABLE_CM0\nif { [info exists ENABLE_CM0] } {\n\tset _ENABLE_CM0 $ENABLE_CM0\n} else {\n\tset _ENABLE_CM0 1\n}\n\n# Is CM4 Debugging enabled ?\nglobal _ENABLE_CM4\nif { [info exists ENABLE_CM4] } {\n\tset _ENABLE_CM4 $ENABLE_CM4\n} else {\n\tset _ENABLE_CM4 1\n}\n\nglobal _WORKAREASIZE_CM0\nif { [info exists WORKAREASIZE_CM0] } {\n\tset _WORKAREASIZE_CM0 $WORKAREASIZE_CM0\n} else {\n\tset _WORKAREASIZE_CM0 0x4000\n}\n\nglobal _WORKAREASIZE_CM4\nif { [info exists WORKAREASIZE_CM4] } {\n\tset _WORKAREASIZE_CM4 $WORKAREASIZE_CM4\n} else {\n\tset _WORKAREASIZE_CM4 0x4000\n}\n\nglobal _WORKAREAADDR_CM0\nif { [info exists WORKAREAADDR_CM0] } {\n\tset _WORKAREAADDR_CM0 $WORKAREAADDR_CM0\n} else {\n\tset _WORKAREAADDR_CM0 0x08000000\n}\n\nglobal _WORKAREAADDR_CM4\nif { [info exists WORKAREAADDR_CM4] } {\n\tset _WORKAREAADDR_CM4 $WORKAREAADDR_CM4\n} else {\n\tset _WORKAREAADDR_CM4 0x08000000\n}\n\nproc init_reset { mode } {\n\tglobal RESET_MODE\n\tset RESET_MODE $mode\n\n\tif {[using_jtag]} {\n\t\tjtag arp_init-reset\n\t}\n}\n\n# Utility to make 'reset halt' work as reset;halt on a target\n# It does not prevent running code after reset\nproc psoc6_deassert_post { target } {\n\t# PSoC6 cleared AP registers including TAR during reset\n\t# Force examine to synchronize OpenOCD target status\n\t$target arp_examine\n\n\tglobal RESET_MODE\n\tglobal TARGET\n\n\tif { $RESET_MODE ne \"run\" } {\n\t\t$target arp_poll\n\t\t$target arp_poll\n\t\tset st [$target curstate]\n\n\t\tif { $st eq \"reset\" } {\n\t\t\t# we assume running state follows\n\t\t\t# if reset accidentally halts, waiting is useless\n\t\t\tcatch { $target arp_waitstate running 100 }\n\t\t\tset st [$target curstate]\n\t\t}\n\n\t\tif { $st eq \"running\" } {\n\t\t\techo \"$target: Ran after reset and before halt...\"\n\t\t\tif { $target eq \"${TARGET}.cm0\" } {\n\t\t\t\t# Try to cleanly reset whole system\n\t\t\t\t# and halt the CM0 at entry point\n\t\t\t\tpsoc6 reset_halt\n\t\t\t\t$target arp_waitstate halted 100\n\t\t\t} else {\n\t\t\t\t$target arp_halt\n\t\t\t}\n\t\t}\n\t}\n}\n\nif { $_ENABLE_CM0 } {\n\ttarget create ${TARGET}.cm0 cortex_m -dap $_CHIPNAME.dap -ap-num 1 -coreid 0\n\t${TARGET}.cm0 configure -work-area-phys $_WORKAREAADDR_CM0 -work-area-size $_WORKAREASIZE_CM0 -work-area-backup 0\n\n\tflash bank main_flash_cm0\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm0\n\tflash bank work_flash_cm0\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_user_cm0\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_nar_cm0\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_key_cm0\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm0\n\tflash bank super_flash_toc2_cm0\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm0\n\n\t${TARGET}.cm0 cortex_m reset_config sysresetreq\n\t${TARGET}.cm0 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm0\"\n}\n\nif { $_ENABLE_CM4 } {\n\ttarget create ${TARGET}.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -coreid 1\n\t${TARGET}.cm4 configure -work-area-phys $_WORKAREAADDR_CM4 -work-area-size $_WORKAREASIZE_CM4 -work-area-backup 0\n\n\tflash bank main_flash_cm4\t\tpsoc6 0x10000000 0 0 0 ${TARGET}.cm4\n\tflash bank work_flash_cm4\t\tpsoc6 0x14000000 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_user_cm4\tpsoc6 0x16000800 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_nar_cm4\tpsoc6 0x16001A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_key_cm4\tpsoc6 0x16005A00 0 0 0 ${TARGET}.cm4\n\tflash bank super_flash_toc2_cm4\tpsoc6 0x16007C00 0 0 0 ${TARGET}.cm4\n\n\t${TARGET}.cm4 cortex_m reset_config vectreset\n\t${TARGET}.cm4 configure -event reset-deassert-post \"psoc6_deassert_post ${TARGET}.cm4\"\n}\n\nif { $_ENABLE_CM0 } {\n\t# Use CM0+ by default on dual-core devices\n\ttargets ${TARGET}.cm0\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 18 -expected-id 0x2e200069\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/pxa255.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# PXA255 chip ... originally from Intel, PXA line was sold to Marvell.\n# This chip is now at end-of-life.  Final orders have been taken.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa255\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x69264013\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_CHIPNAME.cpu\n\n# PXA255 comes out of reset using 3.6864 MHz oscillator.\n# Until the PLL kicks in, keep the JTAG clock slow enough\n# that we get no errors.\nadapter speed 300\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 300 }\n\n# both TRST and SRST are *required* for debug\n# DCSR is often accessed with SRST active\nreset_config trst_and_srst separate srst_nogate\n\n# reset processing that works with PXA\nproc init_reset {mode} {\n\t# assert both resets; equivalent to power-on reset\n\tadapter assert trst assert srst\n\n\t# drop TRST after at least 32 cycles\n\tsleep 1\n\tadapter deassert trst assert srst\n\n\t# minimum 32 TCK cycles to wake up the controller\n\truntest 50\n\n\t# now the TAP will be responsive; validate scanchain\n\tjtag arp_init\n\n\t# ... and take it out of reset\n\tadapter deassert trst deassert srst\n}\n\nproc jtag_init {} {\n\tinit_reset startup\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/pxa270.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#Marvell/Intel PXA270 Script\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa270\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n#IDs for pxa270. Are there more?\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # set useful default\n   set _CPUTAPID 0x49265013\n}\n\nif { [info exists CPUTAPID2] } {\n   set _CPUTAPID2 $CPUTAPID2\n} else {\n  # set useful default\n   set _CPUTAPID2 0x79265013\n}\n\nif { [info exists CPUTAPID3] } {\n   set _CPUTAPID2 $CPUTAPID3\n} else {\n  # set useful default\n   set _CPUTAPID3 0x89265013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 7 -ircapture 0x1 -irmask 0x7f -expected-id $_CPUTAPID -expected-id $_CPUTAPID2 -expected-id $_CPUTAPID3\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN -chain-position $_TARGETNAME\n# maps to PXA internal RAM. If you are using a PXA255\n# you must initialize SDRAM or leave this option off\n$_TARGETNAME configure -work-area-phys 0x5c000000 -work-area-size 0x10000 -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/pxa3xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Marvell PXA3xx\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME pxa3xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# IDs for all currently known PXA3xx chips\nif { [info exists CPUTAPID_PXA30X_A0] } {\n   set _CPUTAPID_PXA30X_A0 $CPUTAPID_PXA30X_A0\n} else {\n   set _CPUTAPID_PXA30X_A0 0x0E648013\n}\nif { [info exists CPUTAPID_PXA30X_A1] } {\n   set _CPUTAPID_PXA30X_A1 $CPUTAPID_PXA30X_A1\n} else {\n   set _CPUTAPID_PXA30X_A1 0x1E648013\n}\nif { [info exists CPUTAPID_PXA31X_A0] } {\n   set _CPUTAPID_PXA31X_A0 $CPUTAPID_PXA31X_A0\n} else {\n   set _CPUTAPID_PXA31X_A0 0x0E649013\n}\nif { [info exists CPUTAPID_PXA31X_A1] } {\n   set _CPUTAPID_PXA31X_A1 $CPUTAPID_PXA31X_A1\n} else {\n   set _CPUTAPID_PXA31X_A1 0x1E649013\n}\nif { [info exists CPUTAPID_PXA31X_A2] } {\n   set _CPUTAPID_PXA31X_A2 $CPUTAPID_PXA31X_A2\n} else {\n   set _CPUTAPID_PXA31X_A2 0x2E649013\n}\nif { [info exists CPUTAPID_PXA31X_B0] } {\n   set _CPUTAPID_PXA31X_B0 $CPUTAPID_PXA31X_B0\n} else {\n   set _CPUTAPID_PXA31X_B0 0x3E649013\n}\nif { [info exists CPUTAPID_PXA32X_B1] } {\n   set _CPUTAPID_PXA32X_B1 $CPUTAPID_PXA32X_B1\n} else {\n   set _CPUTAPID_PXA32X_B1 0x5E642013\n}\nif { [info exists CPUTAPID_PXA32X_B2] } {\n   set _CPUTAPID_PXA32X_B2 $CPUTAPID_PXA32X_B2\n} else {\n   set _CPUTAPID_PXA32X_B2 0x6E642013\n}\nif { [info exists CPUTAPID_PXA32X_C0] } {\n   set _CPUTAPID_PXA32X_C0 $CPUTAPID_PXA32X_C0\n} else {\n   set _CPUTAPID_PXA32X_C0 0x7E642013\n}\n\n# set adapter srst delay to the delay introduced by your reset circuit\n# the rest of the needed delays are built into the openocd program\nadapter srst delay 260\n\n# set the jtag_ntrst_delay to the delay introduced by a reset circuit\n# the rest of the needed delays are built into the openocd program\njtag_ntrst_delay 250\n\nset _TARGETNAME $_CHIPNAME.cpu\njtag newtap $_CHIPNAME cpu -irlen 11 -ircapture 0x1 -irmask 0x7f \\\n\t-expected-id $_CPUTAPID_PXA30X_A0 \\\n\t-expected-id $_CPUTAPID_PXA30X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A0 \\\n\t-expected-id $_CPUTAPID_PXA31X_A1 \\\n\t-expected-id $_CPUTAPID_PXA31X_A2 \\\n\t-expected-id $_CPUTAPID_PXA31X_B0 \\\n\t-expected-id $_CPUTAPID_PXA32X_B1 \\\n\t-expected-id $_CPUTAPID_PXA32X_B2 \\\n\t-expected-id $_CPUTAPID_PXA32X_C0\n\ntarget create $_TARGETNAME xscale -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# work area in internal RAM.\n$_TARGETNAME configure -work-area-phys 0x5c030000 -work-area-size 0x10000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/qn908x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# NXP QN908x Cortex-M4F with 128 KiB SRAM\n\nsource [find target/swj-dp.tcl]\n\nset CHIPNAME qn908x\nset CHIPSERIES qn9080\nif { ![info exists WORKAREASIZE] } {\n  set WORKAREASIZE 0x20000\n}\n\n# SWD IDCODE (Cortex M4).\nset CPUTAPID 0x2ba01477\n\nswj_newdap $CHIPNAME cpu -irlen 4 -expected-id $CPUTAPID\ndap create $CHIPNAME.dap -chain-position $CHIPNAME.cpu\n\nset TARGETNAME $CHIPNAME.cpu\ntarget create $TARGETNAME cortex_m -dap $CHIPNAME.dap\n\n# SRAM is mapped at 0x04000000.\n$TARGETNAME configure -work-area-phys 0x04000000 -work-area-size $WORKAREASIZE\n\n# flash bank <name> qn908x <base> <size> 0 0 <target#> [calc_checksum]\n# The base must be set as 0x01000000, and the size parameter is unused.\nset FLASHNAME $CHIPNAME.flash\nflash bank $FLASHNAME qn908x 0x01000000 0 0 0 $TARGETNAME calc_checksum\n\n# We write directly to flash memory over this adapter interface. For debugging\n# this could in theory be faster (the Core clock on reset is normally at 32MHz),\n# but for flashing 1MHz is more reliable.\nadapter speed 1000\n\n# Delay on reset line.\nadapter srst delay 200\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/qualcomm_qca4531.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The QCA4531 is a two stream (2x2) 802.11b/g/n single-band programmable\n# Wi-Fi System-on-Chip (SoC) for the Internet of Things (IoT).\n#\n# Product page:\n# https://www.qualcomm.com/products/qca4531\n#\n# Notes:\n# - MIPS Processor ID (PRId): 0x00019374\n# - 24Kc MIPS processor with 64 KB I-Cache and 32 KB D-Cache,\n#   operating at up to 650 MHz\n# - External 16-bit DDR1, operating at up to 200 MHz, DDR2 operating at up\n#   to 300 MHz\n# - TRST is not available.\n# - EJTAG PrRst signal is not supported\n# - RESET_L pin B56 on the SoC will reset internal JTAG logic.\n#\n# Pins related for debug and bootstrap:\n# Name\t\tPin\t\tDescription\n#   JTAG\n# JTAG_TCK\tGPIO0, (A27)\tSoftware configurable, default JTAG\n# JTAG_TDI\tGPIO1, (B23)\tSoftware configurable, default JTAG\n# JTAG_TDO\tGPIO2, (A28)\tSoftware configurable, default JTAG\n# JTAG_TMS\tGPIO3, (A29)\tSoftware configurable, default JTAG\n#   Reset\n# RESET_L\t-, (B56)\tInput only\n# SYS_RST_L\tGPIO17, (A79)\tOutput reset request or GPIO\n#   Bootstrap\n# JTAG_MODE\tGPIO16, (A78)\t0 - JTAG (Default); 1 - EJTAG\n# DDR_SELECT\tGPIO10, (A57)\t0 - DDR2; 1 - DDR1\n#   UART\n# UART0_SOUT\tGPIO10, (A57)\n# UART0_SIN\tGPIO9, (B49)\n\n# Per default we need to use \"none\" variant to be able properly \"reset init\"\n# or \"reset halt\" the CPU.\nreset_config none srst_pulls_trst\n\n# For SRST based variant we still need proper timings.\n# For ETH part the reset should be asserted at least for 10ms\n# Since there is no other information let's take 100ms to be sure.\nadapter srst pulse_width 100\n\n# according to the SoC documentation it should take at least 5ms from\n# reset end till bootstrap end. In the practice we need 8ms to get JTAG back\n# to live.\nadapter srst delay 8\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $_CHIPNAME\n} else {\n\tset _CHIPNAME qca4531\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00000001\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME\n\n# provide watchdog helper.\nproc disable_watchdog { } {\n\tmww 0xb8060008 0x0\n}\n\n$_TARGETNAME configure -event halted { disable_watchdog }\n\n# Since PrRst is not supported and SRST will reset complete chip\n# with JTAG engine, we need to reset CPU from CPU itself.\n$_TARGETNAME configure -event reset-assert-pre {\n\thalt\n}\n\n$_TARGETNAME configure -event reset-assert {\n\tcatch \"mww 0xb806001C 0x01000000\"\n}\n\n# To be able to trigger complete chip reset, in case JTAG is blocked\n# or CPU not responding, we still can use this helper.\nproc full_reset { } {\n\treset_config srst_only\n\treset\n\thalt\n\treset_config none\n}\n\n# Section with helpers which can be used by boards\nproc qca4531_ddr2_550_550_init {} {\n\t# Clear reset flags for different SoC components\n\tmww 0xb806001c 0xfeceffff\n\tmww 0xb806001c 0xeeceffff\n\tmww 0xb806001c 0xe6ceffff\n\n\t# PMU configurations\n\t# Internal Switcher\n\tmww 0xb8116c40 0x633c8176\n\t# Increase the DDR voltage\n\tmww 0xb8116c44 0x10200000\n\t# XTAL Configurations\n\tmww 0xb81162c0 0x4b962100\n\tmww 0xb81162c4 0x480\n\tmww 0xb81162c8 0x04000144\n\t# Recommended PLL configurations\n\tmww 0xb81161c4 0x54086000\n\tmww 0xb8116244 0x54086000\n\n\t# PLL init\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x40001580\n\tmww 0xb8050004 0x40015800\n\tmww 0xb8050008 0x0131001c\n\tmww 0xb8050000 0x00001580\n\tmww 0xb8050004 0x00015800\n\tmww 0xb8050008 0x01310000\n\tmww 0xb8050044 0x781003ff\n\tmww 0xb8050048 0x003c103f\n\n\t# DDR2 init\n\tmww 0xb8000108 0x401f0042\n\tmww 0xb80000b8 0x0000166d\n\tmww 0xb8000000 0xcfaaf33b\n\tmww 0xb800015c 0x0000000f\n\tmww 0xb8000004 0xa272efa8\n\tmww 0xb8000018 0x0000ffff\n\tmww 0xb80000c4 0x74444444\n\tmww 0xb80000c8 0x00000444\n\tmww 0xb8000004 0xa210ee28\n\tmww 0xb8000004 0xa2b2e1a8\n\tmww 0xb8000010 0x8\n\tmww 0xb80000bc 0x0\n\tmww 0xb8000010 0x10\n\tmww 0xb80000c0 0x0\n\tmww 0xb8000010 0x40\n\tmww 0xb800000c 0x2\n\tmww 0xb8000010 0x2\n\tmww 0xb8000008 0xb43\n\tmww 0xb8000010 0x1\n\tmww 0xb8000010 0x8\n\tmww 0xb8000010 0x4\n\tmww 0xb8000010 0x4\n\tmww 0xb8000008 0xa43\n\tmww 0xb8000010 0x1\n\tmww 0xb800000c 0x382\n\tmww 0xb8000010 0x2\n\tmww 0xb800000c 0x402\n\tmww 0xb8000010 0x2\n\tmww 0xb8000014 0x40be\n\tmww 0xb800001C 0x20\n\tmww 0xb8000020 0x20\n\tmww 0xb80000cc 0xfffff\n\n\t# UART GPIO programming\n\tmww 0xb8040000 0xff30b\n\tmww 0xb8040044 0x908\n\tmww 0xb8040034 0x160000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/quark_d20xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x38289013\n}\n\njtag newtap quark_d20xx quark -irlen 8 -irmask 0xff -expected-id $_CPUTAPID -disable\njtag newtap quark_d20xx cltap -irlen 8 -irmask 0xff -expected-id 0x0e786013 -enable\n\nproc quark_d20xx_tapenable {} {\n\techo \"enabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 1\n\truntest 10\n}\n\nproc quark_d20xx_tapdisable {} {\n\techo \"disabling quark core tap\"\n\tirscan quark_d20xx.cltap 0x11\n\tdrscan quark_d20xx.cltap 12 0\n\truntest 10\n}\n\nproc quark_d20xx_setup {} {\n\tjtag tapenable quark_d20xx.quark\n}\n\njtag configure quark_d20xx.quark -event tap-enable \\\n   \"quark_d20xx_tapenable\"\n\njtag configure quark_d20xx.quark -event tap-disable \\\n   \"quark_d20xx_tapdisable\"\n\ntarget create quark_d20xx.quark quark_d20xx -endian little -chain-position quark_d20xx.quark\n\nquark_d20xx.quark configure -event reset-start {\n\t# need to halt the target to write to memory\n\tif {[quark_d20xx.quark curstate] ne \"halted\"} { halt }\n\t# set resetbreak via the core tap\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x1\n\t# trigger a warm reset\n\tmww 0xb0800570 0x2\n\t# clear resetbreak\n\tirscan quark_d20xx.quark 0x35 ; drscan quark_d20xx.quark 1 0x0\n}\n\njtag configure quark_d20xx.quark -event setup \\\n   \"quark_d20xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/quark_x10xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME quark_x10xx\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x18289013\n}\n\njtag newtap quark_x10xx cpu   -irlen 8  -irmask 0xff  -expected-id   $_CPUTAPID  -disable\njtag newtap quark_x10xx cltap -irlen 8  -irmask 0xff  -expected-id   0x0e681013  -enable\n\n#openocd puts tap at front of chain not end of chain\nproc quark_x10xx_tapenable {} {\n\techo \"enabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 1\n\truntest 10\n}\n\nproc quark_x10xx_tapdisable {} {\n\techo \"disabling core tap\"\n\tirscan quark_x10xx.cltap 0x11\n\tdrscan quark_x10xx.cltap 64 0\n\truntest 10\n}\n\nproc quark_x10xx_setup {} {\n\tjtag tapenable quark_x10xx.cpu\n}\n\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n   \"quark_x10xx_tapenable\"\n\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n   \"quark_x10xx_tapdisable\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create quark_x10xx.cpu quark_x10xx -endian $_ENDIAN -chain-position quark_x10xx.cpu\n\njtag configure $_CHIPNAME.cpu -event setup \\\n   \"quark_x10xx_setup\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/readme.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nPrerequisites:\nThe users of OpenOCD as well as computer programs interacting with OpenOCD are expecting that certain commands\ndo the same thing across all the targets.\n\nRules to follow when writing scripts:\n\n1. The configuration script should be defined such as , for example, the following sequences are working:\n\treset\n\tflash info <bank>\nand\n\treset\n\tflash erase_address <start> <len>\nand\n\treset init\n\tload\n\nIn most cases this can be accomplished by specifying the default startup mode as reset_init (target command\nin the configuration file).\n\n2. If the target is correctly configured, flash must be writable without any other helper commands. It is\nassumed that all write-protect mechanisms should be disabled.\n\n3. The configuration scripts should be defined such as the binary that was written to flash verifies\n(turn off remapping, checksums, etc...)\n\nflash write_image [file] <parameters>\nverify_image [file] <parameters>\n\n4. adapter speed sets the maximum speed (or alternatively RCLK). If invoked\nmultiple times only the last setting is used.\n\ninterface/xxx.cfg files are always executed *before* target/xxx.cfg\nfiles, so any adapter speed in interface/xxx.cfg will be overridden by\ntarget/xxx.cfg. adapter speed in interface/xxx.cfg would then, effectively,\nset the default JTAG speed.\n\nNote that a target/xxx.cfg file can invoke another target/yyy.cfg file,\nso one can create target subtype configurations where e.g. only\namount of DRAM, oscillator speeds differ and having a single\nconfig file for the default/common settings.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_r7s72100.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/A1H\n# https://www.renesas.com/eu/en/products/microcontrollers-microprocessors/rz/rza/rza1h.html\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME r7s72100\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\n\n# Configuring only one core using DAP.\n# Base addresses of cores:\n#  core 0  -  0x80030000\nset _TARGETNAME $_CHIPNAME.ca9\ndap create ${_CHIPNAME}.dap -chain-position $_CHIPNAME.cpu\ntarget create ${_TARGETNAME} cortex_a -dap ${_CHIPNAME}.dap -coreid 0 -dbgbase 0x80030000\n\ntargets ${_TARGETNAME}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_rcar_gen2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car Generation 2 SOCs\n# - There are a combination of Cortex-A15s and Cortex-A7s for each Gen2 SOC\n# - Each SOC can boot through any of the, up to 2, core types that it has\n#   e.g. H2 can boot through Cortex-A15 or Cortex-A7\n\n# Supported Gen2 SOCs and their cores:\n# H2:  Cortex-A15 x 4, Cortex-A7 x 4\n# M2:  Cortex-A15 x 2\n# V2H: Cortex-A15 x 2\n# M2N: Cortex-A15 x 2\n# E2:                  Cortex-A7 x 2\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H2')\n# BOOT_CORE: Selects the booting core. 'CA15', or 'CA7'\n#            Defaults to 'CA15' if the SOC has one, else defaults to 'CA7'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H2\n}\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH2 {\n\t\tset _CHIPNAME r8a7790\n\t\tset _num_ca15 4\n\t\tset _num_ca7 4\n\t\tset _boot_core CA15\n\t}\n\tM2 {\n\t\tset _CHIPNAME r8a7791\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tV2H {\n\t\tset _CHIPNAME r8a7792\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tM2N {\n\t\tset _CHIPNAME r8a7793\n\t\tset _num_ca15 2\n\t\tset _num_ca7 0\n\t\tset _boot_core CA15\n\t}\n\tE2 {\n\t\tset _CHIPNAME r8a7794\n\t\tset _num_ca15 0\n\t\tset _num_ca7 2\n\t\tset _boot_core CA7\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\necho \"\\t$_soc - $_num_ca15 CA15(s), $_num_ca7 CA7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA15_DBGBASE {0x800B0000 0x800B2000 0x800B4000 0x800B6000}\nset CA7_DBGBASE  {0x800F0000 0x800F2000 0x800F4000 0x800F6000}\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_ca {core_name dbgbase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tset _command \"target create $_TARGETNAME cortex_a -dap $_DAPNAME \\\n\t\t\t-coreid $_core -dbgbase [lindex $dbgbase $_core]\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA15] } {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 1\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n} elseif { [string equal $_boot_core CA7] } {\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 1\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n} else {\n\tsetup_ca a15 $CA15_DBGBASE $_num_ca15 0\n\tsetup_ca a7  $CA7_DBGBASE  $_num_ca7 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_rcar_gen3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car Generation 3 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, and Cortex-R7 for each Gen3 SOC\n# - Each SOC can boot through any of the, up to 3, core types that it has\n#   e.g. H3 can boot through Cortex-A57, Cortex-A53, or Cortex-R7\n\n# Supported Gen3 SOCs and their cores:\n#  H3: Cortex-A57 x 4, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3W: Cortex-A57 x 2, Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# M3N: Cortex-A57 x 2,                 Cortex-R7 x 2 (Lock-Step)\n# V3U:                 Cortex-A76 x 8, Cortex-R52 x2 (Lock-Step)\n# V3H:                 Cortex-A53 x 4, Cortex-R7 x 2 (Lock-Step)\n# V3M:                 Cortex-A53 x 2, Cortex-R7 x 2 (Lock-Step)\n#  E3:                 Cortex-A53 x 1, Cortex-R7 x 2 (Lock-Step)\n#  D3:                 Cortex-A53 x 1\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'H3')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53', or 'CR7'\n#            Defaults to 'CA57' if the SOC has one, else defaults to 'CA53'\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc H3\n}\n\nset _num_ca53 0\nset _num_ca57 0\nset _num_ca76 0\nset _num_cr52 0\nset _num_cr7 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tH3 {\n\t\tset _CHIPNAME r8a77950\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3W {\n\t\tset _CHIPNAME r8a77960\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tM3N {\n\t\tset _CHIPNAME r8a77965\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t}\n\tV3M {\n\t\tset _CHIPNAME r8a77970\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tV3H {\n\t\tset _CHIPNAME r8a77980\n\t\tset _num_ca57 0\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tE3 {\n\t\tset _CHIPNAME r8a77990\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t}\n\tD3 {\n\t\tset _CHIPNAME r8a77995\n\t\tset _num_ca57 0\n\t\tset _num_ca53 1\n\t\tset _num_cr7 0\n\t\tset _boot_core CA53\n\t}\n\tV3U {\n\t\tset _CHIPNAME r8a779a0\n\t\tset _num_ca76 8\n\t\tset _num_cr52 1\n\t\tset _boot_core CA76\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x5ba00477\n}\n\necho \"\\t$_soc - $_num_ca76 CA76(s), $_num_ca57 CA57(s), $_num_ca53 CA53(s), $_num_cr52 CR52(s), $_num_cr7 CR7(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x0f -expected-id $_DAP_TAPID\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\n\nset CA76_DBGBASE {0x81410000 0x81510000 0x81610000 0x81710000 0x81c10000 0x81d10000 0x81e10000 0x81f10000}\nset CA76_CTIBASE {0x81420000 0x81520000 0x81620000 0x81720000 0x81c20000 0x81d20000 0x81e20000 0x81f20000}\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset CR52_DBGBASE 0x80c10000\nset CR52_CTIBASE 0x80c20000\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\n\nset _targets \"\"\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tglobal smp_targets\n\tglobal _targets\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\tset _command \"target create $_TARGETNAME aarch64 -dap $_DAPNAME \\\n\t\t\t-ap-num 1 -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\"\n\t\tif { $_core == 0  && $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\tset smp_targets \"$smp_targets $_TARGETNAME\"\n\t\teval $_command\n\t}\n}\n\nproc setup_crx {core_name dbgbase ctibase num boot} {\n\tglobal _CHIPNAME\n\tglobal _DAPNAME\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $_CHIPNAME.$core_name\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $_DAPNAME -ap-num 1 -baseaddr $ctibase\n\t\tif { $core_name == \"r52\" } {\n\t\t\tset _command \"target create $_TARGETNAME armv8r -dap $_DAPNAME \\\n\t\t\t\t-ap-num 1 -dbgbase $dbgbase -cti $_CTINAME\"\n\t\t} else {\n\t\t\tset _command \"target create $_TARGETNAME cortex_r4 -dap $_DAPNAME \\\n\t\t\t\t-ap-num 1 -dbgbase $dbgbase\"\n\t\t}\n\t\tif { $boot == 1 } {\n\t\t\tset _targets \"$_TARGETNAME\"\n\t\t} else {\n\t\t\tset _command \"$_command -defer-examine\"\n\t\t}\n\t\teval $_command\n\t}\n}\n\n# Organize target list based on the boot core\nif { [string equal $_boot_core CA76] } {\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 1\n\tsetup_crx r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 0\n} elseif { [string equal $_boot_core CA57] } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_crx r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CA53] } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_crx r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  0\n} elseif { [string equal $_boot_core CR52] } {\n\tsetup_crx r52 $CR52_DBGBASE $CR52_CTIBASE $_num_cr52 1\n\tsetup_a5x a76 $CA76_DBGBASE $CA76_CTIBASE $_num_ca76 0\n} else {\n\tsetup_crx r7  $CR7_DBGBASE  $CR7_CTIBASE  $_num_cr7  1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n}\n\nsource [find target/renesas_rcar_reset_common.cfg]\n\neval \"target smp $smp_targets\"\ntargets $_targets\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_rcar_reset_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas R-Car Gen2 Evaluation Board common settings\n\nreset_config trst_and_srst srst_nogate\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_rz_five.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/Five SoC\n#\n# General-purpose Microprocessors with RISC-V CPU Core (Andes AX45MP Single) (1.0 GHz)\n\ntransport select jtag\n\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME r9A07g043u\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1000563d\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_rz_g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Renesas RZ/G2 SOCs\n# - There are a combination of Cortex-A57s, Cortex-A53s, Cortex-A55, Cortex-R7\n# and Cortex-M33 for each SOC\n# - Each SOC can boot through the Cortex-A5x cores\n\n# Supported RZ/G2 SOCs and their cores:\n# RZ/G2H:   Cortex-A57 x4, Cortex-A53 x4, Cortex-R7\n# RZ/G2M:   Cortex-A57 x2, Cortex-A53 x4, Cortex-R7\n# RZ/G2N:   Cortex-A57 x2,                Cortex-R7\n# RZ/G2E:                  Cortex-A53 x2, Cortex-R7\n# RZ/G2L:                  Cortex-A55 x2, Cortex-M33\n# RZ/G2LC:                 Cortex-A55 x2, Cortex-M33\n# RZ/G2UL:                 Cortex-A55 x1, Cortex-M33\n\n# Usage:\n# There are 2 configuration options:\n# SOC:       Selects the supported SOC. (Default 'G2L')\n# BOOT_CORE: Selects the booting core. 'CA57', 'CA53' or 'CA55'\n\ntransport select jtag\nreset_config trst_and_srst srst_gates_jtag\nadapter speed 4000\nadapter srst delay 500\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc G2L\n}\n\nset _num_ca57 0\nset _num_ca55 0\nset _num_ca53 0\nset _num_cr7 0\nset _num_cm33 0\n\n# Set configuration for each SOC and the default 'BOOT_CORE'\nswitch $_soc {\n\tG2H {\n\t\tset _CHIPNAME r8a774ex\n\t\tset _num_ca57 4\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2M {\n\t\tset _CHIPNAME r8a774ax\n\t\tset _num_ca57 2\n\t\tset _num_ca53 4\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2N {\n\t\tset _CHIPNAME r8a774bx\n\t\tset _num_ca57 2\n\t\tset _num_ca53 0\n\t\tset _num_cr7 1\n\t\tset _boot_core CA57\n\t\tset _ap_num 1\n\t}\n\tG2E {\n\t\tset _CHIPNAME r8a774c0\n\t\tset _num_ca57 0\n\t\tset _num_ca53 2\n\t\tset _num_cr7 1\n\t\tset _boot_core CA53\n\t\tset _ap_num 1\n\t}\n\tG2L {\n\t\tset _CHIPNAME r9a07g044l\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2LC {\n\t\tset _CHIPNAME r9a07g044c\n\t\tset _num_ca55 2\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tG2UL {\n\t\tset _CHIPNAME r9a07g043u\n\t\tset _num_ca55 1\n\t\tset _num_cm33 1\n\t\tset _boot_core CA55\n\t\tset _ap_num 0\n\t}\n\tdefault {\n\t\terror \"'$_soc' is invalid!\"\n\t}\n}\n\n# If configured, override the default 'CHIPNAME'\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n}\n\n# If configured, override the default 'BOOT_CORE'\nif { [info exists BOOT_CORE] } {\n\tset _boot_core $BOOT_CORE\n}\n\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x6ba00477\n}\n\necho \"\\t$_soc - $_num_ca57 CA57(s), $_num_ca55 CA55(s), $_num_ca53 CA53(s), $_num_cr7 CR7(s), \\\n\t$_num_cm33 CM33(s)\"\necho \"\\tBoot Core - $_boot_core\\n\"\n\nset _DAPNAME $_CHIPNAME.dap\n\n\n# TAP and DAP\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID \\\n\t-ignore-version\ndap create $_DAPNAME -chain-position $_CHIPNAME.cpu\necho \"$_CHIPNAME.cpu\"\n\nset CA57_DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CA57_CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset CA55_DBGBASE {0x10E10000 0x10F10000}\nset CA55_CTIBASE {0x10E20000 0x10F20000}\nset CA53_DBGBASE {0x80C10000 0x80D10000 0x80E10000 0x80F10000}\nset CA53_CTIBASE {0x80C20000 0x80D20000 0x80E20000 0x80F20000}\nset  CR7_DBGBASE 0x80910000\nset  CR7_CTIBASE 0x80918000\nset CM33_DBGBASE 0xE000E000\nset CM33_CTIBASE 0xE0042000\n\nset smp_targets \"\"\n\nproc setup_a5x {core_name dbgbase ctibase num boot} {\n\tfor { set _core 0 } { $_core < $num } { incr _core } {\n\t\tset _TARGETNAME $::_CHIPNAME.$core_name.$_core\n\t\tset _CTINAME $_TARGETNAME.cti\n\t\tcti create $_CTINAME -dap $::_DAPNAME -ap-num $::_ap_num \\\n\t\t\t-baseaddr [lindex $ctibase $_core]\n\t\ttarget create $_TARGETNAME aarch64 -dap $::_DAPNAME \\\n\t\t\t-ap-num $::_ap_num -dbgbase [lindex $dbgbase $_core] -cti $_CTINAME\n\t\tif { $_core > 0 || $boot == 0 } {\n\t\t\t$_TARGETNAME configure -defer-examine\n\t\t}\n\t\tset ::smp_targets \"$::smp_targets $_TARGETNAME\"\n\t}\n}\n\nproc setup_cr7 {dbgbase ctibase} {\n\tset _TARGETNAME $::_CHIPNAME.r7\n\tset _CTINAME $_TARGETNAME.cti\n\tcti create $_CTINAME -dap $::_DAPNAME -ap-num 1 -baseaddr $ctibase\n\ttarget create $_TARGETNAME cortex_r4 -dap $::_DAPNAME \\\n\t\t-ap-num 1 -dbgbase $dbgbase -defer-examine\n}\n\nproc setup_cm33 {dbgbase ctibase} {\n        set _TARGETNAME $::_CHIPNAME.m33\n        set _CTINAME $_TARGETNAME.cti\n        cti create $_CTINAME -dap $::_DAPNAME -ap-num 2 -baseaddr $ctibase\n        target create $_TARGETNAME cortex_m -dap $::_DAPNAME \\\n                -ap-num 2 -dbgbase $dbgbase -defer-examine\n}\n\n# Organize target list based on the boot core\nif { $_boot_core == \"CA57\" } {\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 1\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA53\" } {\n\tsetup_a5x a53 $CA53_DBGBASE $CA53_CTIBASE $_num_ca53 1\n\tsetup_a5x a57 $CA57_DBGBASE $CA57_CTIBASE $_num_ca57 0\n\tsetup_cr7 $CR7_DBGBASE $CR7_CTIBASE\n} elseif { $_boot_core == \"CA55\" } {\n\tsetup_a5x a55 $CA55_DBGBASE $CA55_CTIBASE $_num_ca55 1\n\tsetup_cm33 $CM33_DBGBASE $CM33_CTIBASE\n}\necho \"SMP targets:$smp_targets\"\neval \"target smp $smp_targets\"\n\nif { $_soc == \"G2L\" || $_soc == \"G2LC\" || $_soc == \"G2UL\" } {\n\ttarget create $_CHIPNAME.axi_ap mem_ap -dap $_DAPNAME -ap-num 1\n}\n\nproc init_reset {mode} {\n    # Assert both resets: equivalent to a power-on reset\n    adapter assert trst assert srst\n\n    # Deassert TRST to begin TAP communication\n    adapter deassert trst assert srst\n\n    # TAP should now be responsive, validate the scan-chain\n    jtag arp_init\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/renesas_s7g2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Renesas Synergy S7 G2 w/ ARM Cortex-M4 @ 240 MHz\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME s7g2\n}\n\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x5ba00477\n}\n\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x5ba02477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\t# 640 KB On-Chip SRAM\n\tset _WORKAREASIZE 0xa0000\n}\n\n$_TARGETNAME configure -work-area-phys 0x1ffe0000 \\\n                       -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/rk3308.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Rockchip RK3308 Target\n# https://rockchip.fr/RK3308%20datasheet%20V1.5.pdf\n# https://dl.radxa.com/rockpis/docs/hw/datasheets/Rockchip%20RK3308TRM%20V1.1%20Part1-20180810.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3308\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x2ba01477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\n\n# declare the 4 main application cores\nset _TARGETNAME $_CHIPNAME.core\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x81010000\nset $_TARGETNAME.base(1) 0x81012000\nset $_TARGETNAME.base(2) 0x81014000\nset $_TARGETNAME.base(3) 0x81016000\n\nset $_TARGETNAME.cti(0) 0x81018000\nset $_TARGETNAME.cti(1) 0x81019000\nset $_TARGETNAME.cti(2) 0x8101a000\nset $_TARGETNAME.cti(3) 0x8101b000\n\nset _cores 4\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 0\n\n    set _command \"target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\"\n\n    if { $_core != 0 } {\n        set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n        set _command \"$_command -defer-examine\"\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # set _command \"$_command -rtos hwthread\"\n        set _command \"$_command -work-area-size 0x40000 -work-area-phys 0xfff80000 \\\n                                -work-area-backup 0\"\n        set _smp_command \"target smp ${_TARGETNAME}$_core\"\n    }\n\n    eval $_command\n}\n\neval $_smp_command\n\ntargets ${_TARGETNAME}0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/rk3399.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Rockchip RK3399 Target\n# https://rockchip.fr/RK3399%20datasheet%20V1.8.pdf\n# https://rockchip.fr/Rockchip%20RK3399%20TRM%20V1.4%20Part1.pdf\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME rk3399\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n   set _DAP_TAPID $DAP_TAPID\n} else {\n   set _DAP_TAPID 0x5ba02477\n}\n\nadapter speed 12000\n\ntransport select swd\n\n# declare the one SWD tap to access the DAP\nswd newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID -ignore-version\n\n# create the DAP\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_CHIPNAME.ahb mem_ap -dap $_CHIPNAME.dap -ap-num 0\nset _TARGETNAME $_CHIPNAME.lcore\n# declare the 6 main application cores\nset _smp_command \"\"\n\nset $_TARGETNAME.base(0) 0x80030000\nset $_TARGETNAME.base(1) 0x80032000\nset $_TARGETNAME.base(2) 0x80034000\nset $_TARGETNAME.base(3) 0x80036000\nset $_TARGETNAME.cti(0) 0x80038000\nset $_TARGETNAME.cti(1) 0x80039000\nset $_TARGETNAME.cti(2) 0x8003a000\nset $_TARGETNAME.cti(3) 0x8003b000\n\n\nset _TARGETNAME $_CHIPNAME.bcore\nset $_TARGETNAME.base(4) 0x80210000\nset $_TARGETNAME.base(5) 0x80310000\nset $_TARGETNAME.cti(4) 0x80220000\nset $_TARGETNAME.cti(5) 0x80320000\n\nset _cores 6\nfor { set _core 0 } { $_core < $_cores } { incr _core 1 } {\n    if {$_core < 4} {\n        set _TARGETNAME $_CHIPNAME.lcore\n    } else {\n        set _TARGETNAME $_CHIPNAME.bcore\n    }\n\n\n    cti create cti$_core -dap $_CHIPNAME.dap -baseaddr [set $_TARGETNAME.cti($_core)] -ap-num 1\n\n    target create ${_TARGETNAME}$_core aarch64 \\\n                         -dap $_CHIPNAME.dap -coreid $_core -cti cti$_core \\\n                         -dbgbase [set $_TARGETNAME.base($_core)]\n\n    if { $_core != 0 } {\n        ${_TARGETNAME}$_core configure -defer-examine\n    } else {\n        # uncomment to use hardware threads pseudo rtos\n        # ${_TARGETNAME}$_core configure -rtos hwthread\"\n        ${_TARGETNAME}$_core configure -work-area-size 0x30000 -work-area-phys 0xff8c0000 \\\n                                -work-area-backup 0\n    }\n    set _smp_command \"$_smp_command ${_TARGETNAME}$_core\"\n}\n\ntarget smp $_smp_command\n\ntargets rk3399.lcore0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/rp2040.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# RP2040 is a microcontroller with dual Cortex-M0+ core.\n# https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html\n\n# The device requires multidrop SWD for debug.\ntransport select swd\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME rp2040\n}\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x01002927\n}\n\n# Set to '1' to start rescue mode\nif { [info exists RESCUE] } {\n\tset _RESCUE $RESCUE\n} else {\n\tset _RESCUE 0\n}\n\n# Set to '0' or '1' for single core configuration, 'SMP' for -rtos hwthread\n# handling of both cores, anything else for isolated debugging of both cores\nif { [info exists USE_CORE] } {\n\tset _USE_CORE $USE_CORE\n} else {\n\tset _USE_CORE SMP\n}\nset _BOTH_CORES [expr { $_USE_CORE != 0 && $_USE_CORE != 1 }]\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\n\n# The rescue debug port uses the DP CTRL/STAT bit DBGPWRUPREQ to reset the\n# PSM (power on state machine) of the RP2040 with a flag set in the\n# VREG_AND_POR_CHIP_RESET register. Once the reset is released\n# (by clearing the DBGPWRUPREQ flag), the bootrom will run, see this flag,\n# and halt. Allowing the user to load some fresh code, rather than loading\n# the potentially broken code stored in flash\nif { $_RESCUE } {\n\tdap create $_CHIPNAME.rescue_dap -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0xf -ignore-syspwrupack\n\tinit\n\n\t# Clear DBGPWRUPREQ\n\t$_CHIPNAME.rescue_dap dpreg 0x4 0x00000000\n\n\t# Verifying CTRL/STAT is 0\n\tset _CTRLSTAT [$_CHIPNAME.rescue_dap dpreg 0x4]\n\tif {[expr {$_CTRLSTAT & 0xf0000000}]} {\n\t\techo \"Rescue failed, DP CTRL/STAT readback $_CTRLSTAT\"\n\t} else {\n\t\techo \"Now restart OpenOCD without RESCUE flag and load code to RP2040\"\n\t}\n\tshutdown\n}\n\n# core 0\nif { $_USE_CORE != 1 } {\n\tdap create $_CHIPNAME.dap0 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 0\n\tset _TARGETNAME_0 $_CHIPNAME.core0\n\ttarget create $_TARGETNAME_0 cortex_m -dap $_CHIPNAME.dap0 -coreid 0\n\t# srst does not exist; use SYSRESETREQ to perform a soft reset\n\t$_TARGETNAME_0 cortex_m reset_config sysresetreq\n}\n\n# core 1\nif { $_USE_CORE != 0 } {\n\tdap create $_CHIPNAME.dap1 -chain-position $_CHIPNAME.cpu -dp-id $_CPUTAPID -instance-id 1\n\tset _TARGETNAME_1 $_CHIPNAME.core1\n\ttarget create $_TARGETNAME_1 cortex_m -dap $_CHIPNAME.dap1 -coreid 1\n\t$_TARGETNAME_1 cortex_m reset_config sysresetreq\n}\n\nif {[string compare $_USE_CORE SMP] == 0} {\n\t$_TARGETNAME_0 configure  -rtos hwthread\n\t$_TARGETNAME_1 configure  -rtos hwthread\n\ttarget smp $_TARGETNAME_0 $_TARGETNAME_1\n}\n\nif { $_USE_CORE == 1 } {\n\tset _FLASH_TARGET $_TARGETNAME_1\n} else {\n\tset _FLASH_TARGET $_TARGETNAME_0\n}\n# Backup the work area. The flash probe runs an algorithm on the target CPU.\n# The flash is probed during gdb connect if gdb_memory_map is enabled (by default).\n$_FLASH_TARGET configure -work-area-phys 0x20010000 -work-area-size $_WORKAREASIZE -work-area-backup 1\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME rp2040_flash 0x10000000 0 0 0 $_FLASH_TARGET\n\nif { $_BOTH_CORES } {\n\t# Alias to ensure gdb connecting to core 1 gets the correct memory map\n\tflash bank $_CHIPNAME.alias virtual 0x10000000 0 0 0 $_TARGETNAME_1 $_FLASHNAME\n\n\t# Select core 0\n\ttargets $_TARGETNAME_0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/rsl10.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# RSL10: ARM Cortex-M3\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME rsl10\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x2ba01477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# TODO: configure reset\n# reset_config srst_only srst_nogate connect_assert_srst\n\n$_TARGETNAME configure -event examine-fail rsl10_lock_warning\n\nproc rsl10_check_connection {} {\n    set target [target current]\n    set dap [$target cget -dap]\n\n\tset IDR [$dap apreg 0 0xfc]\n\tif {$IDR != 0x24770011} {\n\t\techo \"Error: Cannot access RSL10 AP, maybe connection problem!\"\n\t\treturn 1\n\t}\n    return 0\n}\n\nproc rsl10_lock_warning {} {\n    if {[rsl10_check_connection]} {return}\n\n    poll off\n    echo \"****** WARNING ******\"\n    echo \"RSL10 device probably has lock engaged.\"\n    echo \"Debug access is denied.\"\n    echo \"Use 'rsl10 unlock key1 key2 key3 key4' to erase and unlock the device.\"\n    echo \"****** ....... ******\"\n    echo \"\"\n}\n\nflash bank $_CHIPNAME.main rsl10 0x00100000 0x60000 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvr1 rsl10 0x00080000 0x800 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvr2 rsl10 0x00080800 0x800 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.nvr3 rsl10 0x00081000 0x800 0 0 $_TARGETNAME\n\n# TODO: implement flashing for nvr4\n# flash bank $_CHIPNAME.nvr4 rsl10 0x00081800 0x400 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/samsung_s3c2410.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Found on the 'TinCanTools' Hammer board.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # This config file was defaulting to big endian..\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # Force an error until we get a good number.\n   set _CPUTAPID 0xffffffff\n}\n\n#use combined on interfaces or targets that cannot set TRST/SRST separately\nreset_config trst_and_srst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x30800000 -work-area-size 0x20000 -work-area-backup 0\n\n# speed up memory downloads\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/samsung_s3c2440.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the Samsung 2440 system on chip\n# Tested on a S3C2440 Evaluation board by keesj\n# Processor       : ARM920Tid(wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2440.cpu tap/device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c2440\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0032409d\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm920t -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -work-area-phys 0x200000 -work-area-size 0x4000 -work-area-backup 1\n\n#reset configuration\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/samsung_s3c2450.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the Samsung 2450 system on chip\n# Processor       : ARM926ejs (wb) rev 0 (v4l)\n# Info:   JTAG tap: s3c2450.cpu tap/device found: 0x07926F0F\n\n\n# FIX!!! what to use here?\n#\n# RCLK?\n#\n# adapter speed 0\n#\n# Really low clock during reset?\n#\n# adapter speed 1\n\nif { [info exists CHIPNAME] } {\n  set _CHIPNAME $CHIPNAME\n} else {\n  set _CHIPNAME s3c2450\n}\n\nif { [info exists ENDIAN] } {\n  set _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n  set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n  set _CPUTAPID $CPUTAPID\n} else {\n  set _CPUTAPID 0x07926f0f\n}\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xE -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# FIX!!!!! should this really use srst_pulls_trst?\n# With srst_pulls_trst \"reset halt\" will not reset into the\n# halted mode, but rather \"reset run\" and then halt the target.\n#\n# However, without \"srst_pulls_trst\", then \"reset halt\" produces weird\n# errors:\n# WARNING: unknown debug reason: 0x0\nreset_config trst_and_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/samsung_s3c4510.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c4510\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n\n# This appears to be a \"Version 1\" arm7tdmi.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x1f0f0f0f\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/samsung_s3c6410.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# -*- tcl -*-\n# Target configuration for the Samsung s3c6410 system on chip\n# Tested on a SMDK6410\n# Processor       : ARM1176\n# Info:   JTAG device found: 0x0032409d (Manufacturer: 0x04e, Part: 0x0324, Version: 0x0)\n# [Duane Ellis 27/nov/2008: Above 0x0032409d appears to be copy/paste from other places]\n# [and I do not believe it to be accurate, hence the 0xffffffff below]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME s3c6410\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n  # this defaults to a bigendian\n   set _ENDIAN little\n}\n\n# trace buffer\nif { [info exists ETBTAPID] } {\n   set _ETBTAPID $ETBTAPID\n} else {\n   set _ETBTAPID 0x2b900f0f\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07b76f0f\n}\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME etb -irlen 4 -expected-id $_ETBTAPID\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm11 -endian $_ENDIAN -chain-position $_TARGETNAME\n\nadapter srst delay 500\njtag_ntrst_delay 500\n\n#reset configuration\nreset_config trst_and_srst\n\n# trace setup ... NOTE, \"normal full\" mode fudges the real ETMv3.1 mode\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/sharp_lh79532.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nreset_config srst_only srst_pulls_trst\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lh79532\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # sharp changed the number!\n   set _CPUTAPID 0x00002061\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/sim3x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Silicon Laboratories SiM3x Cortex-M3\n#\n\n# SiM3x devices support both JTAG and SWD transports.\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME SiM3x\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4ba00477\n}\n\nif { [info exists CPURAMSIZE] } {\n  set _CPURAMSIZE $CPURAMSIZE\n} else {\n# Minimum size of RAM in the Silicon Labs product matrix (8KB)\n\tset _CPURAMSIZE 0x2000\n}\n\nif { [info exists CPUROMSIZE] } {\n  set _CPUROMSIZE $CPUROMSIZE\n} else {\n# Minimum size of FLASH in the Silicon Labs product matrix (32KB)\n\tset _CPUROMSIZE 0x8000\n}\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE $_CPURAMSIZE\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME sim3x 0 $_CPUROMSIZE 0 0 $_TARGETNAME\n\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/smp8634.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for Sigma Designs SMP8634 (eventually even SMP8635)\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME smp8634\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x08630001\n}\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\nreset_config trst_and_srst separate\n\n# jtag scan chain\n# format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/snps_em_sk_fpga.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2014-2015,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# Xilinx Spartan-6 XC6SLX45  FPGA on EM Starter Kit v1.\n# Xilinx Spartan-6 XC6SLX150 FPGA on EM Starter Kit v2.\n#\n\nsource [find cpu/arc/em.tcl]\n\nset _CHIPNAME arc-em\nset _TARGETNAME $_CHIPNAME.cpu\n\n# EM SK IDENTITY is 0x200444b1\n# EM SK v2 IDENTITY is 0x200044b1\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -expected-id 0x200444b1 \\\n  -expected-id 0x200044b1\n\nset _coreid 0\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME \\\n  -coreid 0 -dbgbase $_dbgbase -endian little\n\n# There is no SRST, so do a software reset\n$_TARGETNAME configure -event reset-assert \"arc_em_reset $_TARGETNAME\"\n\narc_em_init_regs\n\n# vim:ft=tcl\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/snps_hsdk.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) 2019,2020 Synopsys, Inc.\n#  Anton Kolesov <anton.kolesov@synopsys.com>\n#  Didin Evgeniy <didin@synopsys.com>\n\n#\n# HS Development Kit SoC.\n#\n# Contains quad-core ARC HS38.\n#\n\nsource [find cpu/arc/hs.tcl]\n\nset _coreid 0\nset _dbgbase [expr {$_coreid << 13}]\n\n# CHIPNAME will be used to choose core family (600, 700 or EM). As far as\n# OpenOCD is concerned EM and HS are identical.\nset _CHIPNAME arc-em\n\n# OpenOCD discovers JTAG TAPs in reverse order.\n\n# ARC HS38 core 4\nset _TARGETNAME $_CHIPNAME.cpu4\njtag newtap $_CHIPNAME cpu4 -irlen 4 -ircapture 0x1 -expected-id 0x200c24b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n# Flush L2$.\n$_TARGETNAME configure -event reset-assert \"arc_hs_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 4.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 3\nset _TARGETNAME $_CHIPNAME.cpu3\njtag newtap $_CHIPNAME cpu3 -irlen 4 -ircapture 0x1 -expected-id 0x200824b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 3.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 2\nset _TARGETNAME $_CHIPNAME.cpu2\njtag newtap $_CHIPNAME cpu2 -irlen 4 -ircapture 0x1 -expected-id 0x200424b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {$_coreid << 13}]\n\narc_hs_init_regs\n\n# Enable L2 cache support for core 2.\n$_TARGETNAME arc cache l2 auto 1\n\n# ARC HS38 core 1\nset _TARGETNAME $_CHIPNAME.cpu1\njtag newtap $_CHIPNAME cpu1 -irlen 4 -ircapture 0x1 -expected-id 0x200024b1\n\ntarget create $_TARGETNAME arcv2 -chain-position $_TARGETNAME\n$_TARGETNAME configure -coreid $_coreid\n$_TARGETNAME configure -dbgbase $_dbgbase\n$_TARGETNAME configure -event reset-assert \"arc_common_reset $_TARGETNAME\"\nset _coreid [expr {$_coreid + 1}]\nset _dbgbase [expr {0x00000000 | ($_coreid << 13)}]\narc_hs_init_regs\n\n# Enable L2 cache support for core 1.\n$_TARGETNAME arc cache l2 auto 1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/spear3xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Target configuration for the ST SPEAr3xx family of system on chip\n# Supported SPEAr300, SPEAr310, SPEAr320\n# http://www.st.com/spear\n#\n# Processor: ARM926ejs\n# Info:      JTAG tap: spear3xx.cpu tap/device found: 0x07926041\n# Date:      2009-10-31\n# Author:    Antonio Borneo <borneo.antonio@gmail.com>\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME spear3xx\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x07926041\n}\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x01 -irmask 0x03 \\\n\t-expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN \\\n\t-chain-position $_TARGETNAME\n\n# SPEAr3xx has a 8K block of sram @ 0xd280.0000\n# REVISIT: what OS puts virtual address equal to phys?\n$_TARGETNAME configure \\\n\t-work-area-virt 0xd2800000 \\\n\t-work-area-phys 0xd2800000 \\\n\t-work-area-size 0x2000 \\\n\t-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stellaris.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TI/Luminary Stellaris LM3S chip family\n\n# Some devices have errata in returning their device class.\n# DEVICECLASS is provided as a manual override\n# Manual setting of a device class of 0xff is not allowed\n\nglobal _DEVICECLASS\n\nif { [info exists DEVICECLASS] } {\n   set _DEVICECLASS $DEVICECLASS\n} else {\n   set _DEVICECLASS 0xff\n}\n\n# Luminary chips support both JTAG and SWD transports.\n# Adapt based on what transport is active.\nsource [find target/swj-dp.tcl]\n\n# For now we ignore the SPI and UART options, which\n# are usable only for ISP style initial flash programming.\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME lm3s\n}\n\n# CPU TAP ID 0x1ba00477 for early Sandstorm parts\n# CPU TAP ID 0x2ba00477 for later SandStorm parts, e.g. lm3s811 Rev C2\n# CPU TAP ID 0x3ba00477 for Cortex-M3 r1p2 (on Fury, DustDevil)\n# CPU TAP ID 0x4ba00477 for Cortex-M3 r2p0 (on Tempest, Firestorm)\n# CPU TAP ID 0x4ba00477 for Cortex-M4 r0p1 (on Blizzard)\n# ... we'll ignore the JTAG version field, rather than list every\n# chip revision that turns up.\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x0ba00477\n}\n\n# SWD DAP, and JTAG TAP, take same params for now;\n# ... even though SWD ignores all except TAPID, and\n# JTAG shouldn't need anything more then irlen. (and TAPID).\nswj_newdap $_CHIPNAME cpu -irlen 4 -irmask 0xf \\\n    -expected-id $_CPUTAPID -ignore-version\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   # default to 2K working area\n   set _WORKAREASIZE 0x800\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# 8K working area at base of ram, not backed up\n#\n# NOTE: you may need or want to reconfigure the work area;\n# some parts have just 6K, and you may want to use other\n# addresses (at end of mem not beginning) or back it up.\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\n\n# JTAG speed ... slow enough to work with a 12 MHz RC oscillator;\n# LM3S parts don't support RTCK\n#\n# NOTE: this may be increased by a reset-init handler, after it\n# configures and enables the PLL.  Or you might need to decrease\n# this, if you're using a slower clock.\nadapter speed 500\n\nsource [find mem_helper.tcl]\n\nproc reset_peripherals {family} {\n\n\tsource [find chip/ti/lm3s/lm3s.tcl]\n\n\techo \"Resetting Core Peripherals\"\n\n\t# Disable the PLL and the system clock divider (nop if disabled)\n\tmmw $SYSCTL_RCC 0 $SYSCTL_RCC_USESYSDIV\n\tmmw $SYSCTL_RCC2 $SYSCTL_RCC2_BYPASS2 0\n\n\t# RCC and RCC2 to their reset values\n\tmww $SYSCTL_RCC [expr {0x078e3ad0 | ([mrw $SYSCTL_RCC] & $SYSCTL_RCC_MOSCDIS)}]\n\tmww $SYSCTL_RCC2 0x07806810\n\tmww $SYSCTL_RCC 0x078e3ad1\n\n\t# Reset the deep sleep clock configuration register\n\tmww $SYSCTL_DSLPCLKCFG 0x07800000\n\n\t# Reset the clock gating registers\n\tmww $SYSCTL_RCGC0 0x00000040\n\tmww $SYSCTL_RCGC1 0\n\tmww $SYSCTL_RCGC2 0\n\tmww $SYSCTL_SCGC0 0x00000040\n\tmww $SYSCTL_SCGC1 0\n\tmww $SYSCTL_SCGC2 0\n\tmww $SYSCTL_DCGC0 0x00000040\n\tmww $SYSCTL_DCGC1 0\n\tmww $SYSCTL_DCGC2 0\n\n\t# Reset the remaining SysCtl registers\n\tmww $SYSCTL_PBORCTL 0\n\tmww $SYSCTL_IMC 0\n\tmww $SYSCTL_GPIOHBCTL 0\n\tmww $SYSCTL_MOSCCTL 0\n\tmww $SYSCTL_PIOSCCAL 0\n\tmww $SYSCTL_I2SMCLKCFG 0\n\n\t# Reset the peripherals\n\tmww $SYSCTL_SRCR0 0xffffffff\n\tmww $SYSCTL_SRCR1 0xffffffff\n\tmww $SYSCTL_SRCR2 0xffffffff\n\tmww $SYSCTL_SRCR0 0\n\tmww $SYSCTL_SRCR1 0\n\tmww $SYSCTL_SRCR2 0\n\n\t# Clear any pending SysCtl interrupts\n\tmww $SYSCTL_MISC 0xffffffff\n\n\t# Wait for any pending flash operations to complete\n\twhile {[expr {[mrw $FLASH_FMC] & 0xffff}] != 0} { sleep 1 }\n\twhile {[expr {[mrw $FLASH_FMC2] & 0xffff}] != 0} { sleep 1 }\n\n\t# Reset the flash controller registers\n\tmww $FLASH_FMA 0\n\tmww $FLASH_FCIM 0\n\tmww $FLASH_FCMISC 0xffffffff\n\tmww $FLASH_FWBVAL 0\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 500\n\n\t#\n\t# When nRST is asserted on most Stellaris devices, it clears some of\n\t# the debug state.  The ARMv7M and Cortex-M3 TRMs say that's wrong;\n\t# and OpenOCD depends on those TRMs.  So we won't use SRST on those\n\t# chips.  (Only power-on reset should affect debug state, beyond a\n\t# few specified bits; not the chip's nRST input, wired to SRST.)\n\t#\n\t# REVISIT current errata specs don't seem to cover this issue.\n\t# Do we have more details than this email?\n\t#   https://lists.berlios.de/pipermail\n\t#\t/openocd-development/2008-August/003065.html\n\t#\n\n\tglobal _DEVICECLASS\n\n\tif {$_DEVICECLASS != 0xff} {\n\t   set device_class $_DEVICECLASS\n\t} else {\n\t   set device_class [expr {([mrw 0x400fe000] >> 16) & 0xff}]\n\t}\n\n\tif {$device_class == 0 || $device_class == 1 ||\n\t\t$device_class == 3 || $device_class == 5 || $device_class == 0xa} {\n\t\tif {![using_hla]} {\n\t\t   # Sandstorm, Fury, DustDevil, Blizzard and Snowflake are able to use NVIC SYSRESETREQ\n\t\t   cortex_m reset_config sysresetreq\n\t\t}\n\t} else {\n\t\tif {![using_hla]} {\n\t\t   # Tempest and Firestorm default to using NVIC VECTRESET\n\t\t   # peripherals will need resetting manually, see proc reset_peripherals\n\t\t   cortex_m reset_config vectreset\n\t\t}\n\t\t# reset peripherals, based on code in\n\t\t# http://www.ti.com/lit/er/spmz573a/spmz573a.pdf\n\t\treset_peripherals $device_class\n\t}\n}\n\n# flash configuration ... autodetects sizes, autoprobed\nflash bank $_CHIPNAME.flash stellaris 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32c0x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32c0x family\n#\n# stm32c0 devices support SWD transports only.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32c0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 6kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1800\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   # SWD IDCODE (single drop, arm)\n   set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable DBGMCU clock\n\t# RCC_APB1ENR |= DBGMCUEN\n\tmmw 0x4002103C 0x08000000 0\n\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0x40015804 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_WDGLS_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f0x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f0x family\n\n#\n# stm32 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n\tset _FLASH_SIZE $FLASH_SIZE\n} else {\n\t# autodetect size\n\tset _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n  # See STM Document RM0091\n  # Section 29.5.3\n   set _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f0x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f0x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0x40015804 0x00000006 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\n\t# Stop watchdog counters during halt\n\tmmw 0x40015808 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f0x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 6 (48 MHz)\n\tmww 0x40021004 0x00100000   ;# RCC_CFGR = PLLMUL[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR[31:16] |= PLLON\n\tmww 0x40022000 0x00000011   ;# FLASH_ACR = PRFTBE | LATENCY[0]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f1x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f1x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f1x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 4kB (as found on some STM32F100s)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n    set _FLASH_SIZE $FLASH_SIZE\n} else {\n    # autodetect size\n    set _FLASH_SIZE 0\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0008 Section 26.6.3\n      set _CPUTAPID 0x3ba00477\n   } {\n      # this is the SW-DP tap id not the jtag tap id\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0x08000000 $_FLASH_SIZE 0 0 $_TARGETNAME\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_WWDG_STOP | DBG_IWDG_STOP |\n\t#              DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000307 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f2x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f2x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f2x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0033\n      # Section 32.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f3x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f3x family\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f3x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n# Allow overriding the Flash bank size\nif { [info exists FLASH_SIZE] } {\n   set _FLASH_SIZE $FLASH_SIZE\n} else {\n   # autodetect size\n   set _FLASH_SIZE 0\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 8MHz, so use F_JTAG = 1MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 1000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0316\n      # Section 29.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f1x 0 $_FLASH_SIZE 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32f3x_default_reset_start {} {\n\t# Reset clock is HSI (8 MHz)\n\tadapter speed 1000\n}\n\nproc stm32f3x_default_examine_end {} {\n\t# Enable debug during low power modes (uses more power)\n\tmmw 0xe0042004 0x00000007 0 ;# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\n\t# Stop watchdog counters during halt\n\tmmw 0xe0042008 0x00001800 0 ;# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n}\n\nproc stm32f3x_default_reset_init {} {\n\t# Configure PLL to boost clock to HSI x 8 (64 MHz)\n\tmww 0x40021004 0x00380400   ;# RCC_CFGR = PLLMUL[3:1] | PPRE1[2]\n\tmmw 0x40021000 0x01000000 0 ;# RCC_CR |= PLLON\n\tmww 0x40022000 0x00000012   ;# FLASH_ACR = PRFTBE | LATENCY[1]\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40021004 0x00000002 0 ;# RCC_CFGR |= SW[1]\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32f3x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32f3x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32f3x_default_reset_init }\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xe0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f4x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f4x family\n\n#\n# stm32f4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 32kB (Available RAM in smallest device STM32F410)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x8000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0090\n      # Section 38.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\n\nflash bank $_CHIPNAME.otp stm32f2x 0x1fff7800 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# JTAG speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\n#\n# Since we may be running of an RC oscilator, we crank down the speed a\n# bit more to be on the safe side. Perhaps superstition, but if are\n# running off a crystal, we can run closer to the limit. Note\n# that there can be a pretty wide band where things are more or less stable.\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 1 bit; GPIOE[2-3] to AF0\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x40021000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x40021008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 2 bit; GPIOE[2-4] to AF0\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x40021000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x40021008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 4 bit; GPIOE[2-6] to AF0\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x40021020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x40021000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x40021008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\t# Set TRACE_IOEN; TRACE_MODE to async\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# Configure PLL to boost clock to HSI x 4 (64 MHz)\n\tmww 0x40023804 0x08012008   ;# RCC_PLLCFGR 16 Mhz /8 (M) * 128 (N) /4(P)\n\tmww 0x40023C00 0x00000102   ;# FLASH_ACR = PRFTBE | 2(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmmw 0x40023808 0x00001000 0 ;# RCC_CFGR |= RCC_CFGR_PPRE1_DIV2\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost JTAG frequency\n\tadapter speed 8000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32f7x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32f7x family\n\n#\n# stm32f7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32f7x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 128kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x20000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0385\n      # Section 40.6.3 - corresponds to Cortex-M7 with FPU r0p0\n      set _CPUTAPID 0x5ba00477\n   } {\n      set _CPUTAPID 0x5ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32f2x 0 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32f2x 0x1ff0f000 0 0 0 $_TARGETNAME\n\n# On the STM32F7, the Flash is mapped at address 0x08000000 via the AXI and\n# also address 0x00200000 via the ITCM. The former mapping is read-write in\n# hardware, while the latter is read-only. By presenting an alias, we\n# accomplish two things:\n# (1) We allow writing at 0x00200000 (because the alias acts identically to the\n#     original bank), which allows code intended to run from that address to\n#     also be linked for loading at that address, simplifying linking.\n# (2) We allow the proper memory map to be delivered to GDB, which will cause\n#     it to use hardware breakpoints at the 0x00200000 mapping (correctly\n#     identifying it as Flash), which it would otherwise not do. Configuring\n#     the Flash via ITCM alias as virtual\nflash bank $_CHIPNAME.itcm-flash.alias virtual 0x00200000 0 0 0 $_TARGETNAME $_FLASHNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# adapter speed should be <= F_CPU/6. F_CPU after reset is 16MHz, so use F_JTAG = 2MHz\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# Use hardware reset.\n#\n# This target is compatible with connect_assert_srst, which may be set in a\n# board file.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# If the HSE was previously enabled and the external clock source\n\t# disappeared, RCC_CR.HSERDY can get stuck at 1 and the PLL cannot be\n\t# properly switched back to HSI. This situation persists even over a system\n\t# reset, including a pin reset via SRST. However, activating the clock\n\t# security system will detect the problem and clear HSERDY to 0, which in\n\t# turn allows the PLL to switch back to HSI properly. Since we just came\n\t# out of reset, HSEON should be 0. If HSERDY is 1, then this situation must\n\t# have happened; in that case, activate the clock security system to clear\n\t# HSERDY.\n\tif {[mrw 0x40023800] & 0x00020000} {\n\t\tmmw 0x40023800 0x00090000 0 ;# RCC_CR = CSSON | HSEON\n\t\tsleep 10                    ;# Wait for CSS to fire, if it wants to\n\t\tmmw 0x40023800 0 0x00090000 ;# RCC_CR &= ~CSSON & ~HSEON\n\t\tmww 0x4002380C 0x00800000   ;# RCC_CIR = CSSC\n\t\tsleep 1                     ;# Wait for CSSF to clear\n\t}\n\n\t# If the clock security system fired, it will pend an NMI. A pending NMI\n\t# will cause a bad time for any subsequent executing code, such as a\n\t# programming algorithm.\n\tif {[mrw 0xE000ED04] & 0x80000000} {\n\t\t# ICSR.NMIPENDSET reads as 1. Need to clear it. A pending NMI can’t be\n\t\t# cleared by any normal means (such as ICSR or NVIC). It can only be\n\t\t# cleared by entering the NMI handler or by resetting the processor.\n\t\techo \"[target current]: Clock security system generated NMI. Clearing.\"\n\n\t\t# Keep the old DEMCR value.\n\t\tset old [mrw 0xE000EDFC]\n\n\t\t# Enable vector catch on reset.\n\t\tmww 0xE000EDFC 0x01000001\n\n\t\t# Issue local reset via AIRCR.\n\t\tmww 0xE000ED0C 0x05FA0001\n\n\t\t# Restore old DEMCR value.\n\t\tmww 0xE000EDFC $old\n\t}\n\n\t# Configure PLL to boost clock to HSI x 10 (160 MHz)\n\tmww 0x40023804 0x08002808   ;# RCC_PLLCFGR 16 Mhz /10 (M) * 128 (N) /2(P)\n\tmww 0x40023C00 0x00000107   ;# FLASH_ACR = PRFTBE | 7(Latency)\n\tmmw 0x40023800 0x01000000 0 ;# RCC_CR |= PLLON\n\tsleep 10                    ;# Wait for PLL to lock\n\tmww 0x40023808 0x00009400   ;# RCC_CFGR_PPRE1 = 5(div 4), PPRE2 = 4(div 2)\n\tmmw 0x40023808 0x00000002 0 ;# RCC_CFGR |= RCC_CFGR_SW_PLL\n\n\t# Boost SWD frequency\n\t# Do not boost JTAG frequency and slow down JTAG memory access or flash write algo\n\t# suffers from DAP WAITs\n\tif {[using_jtag]} {\n\t\t[[target current] cget -dap] memaccess 16\n\t} {\n\t\tadapter speed 8000\n\t}\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reduce speed since CPU speed will slow down to 16MHz with the reset\n\tadapter speed 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32g0x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32g0x family\n\n#\n# stm32g0 devices support SWD transports only.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g0x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest proposed target has 8kB ram, use 4kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x1000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\t# Section 37.5.5 - corresponds to Cortex-M0+\n\tset _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32g0x_default_reset_start {} {\n\t# Reset clock is HSI16 (16 MHz)\n\tadapter speed 2000\n}\n\nproc stm32g0x_default_examine_end {} {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0x40015804 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n\nproc stm32g0x_default_reset_init {} {\n\t# Increase clock to 64 Mhz\n\tmmw 0x40022000 0x00000002 0x00000005\t;# FLASH_ACR: Latency = 2\n\tmww 0x4002100C 0x30000802\t\t\t\t;# RCC_PLLCFGR = PLLR=/2, PLLN=8, PLLM=/1, PLLSRC=0x2\n\tmmw 0x40021000 0x01000000 0x00000000\t;# RCC_CR |= PLLON\n\tmmw 0x40021008 0x00000002 0x00000005\t;# RCC_CFGR: SW=PLLRCLK\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n# Default hooks\n$_TARGETNAME configure -event examine-end { stm32g0x_default_examine_end }\n$_TARGETNAME configure -event reset-start { stm32g0x_default_reset_start }\n$_TARGETNAME configure -event reset-init { stm32g0x_default_reset_init }\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32g4x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32g4x family\n\n#\n# stm32g4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32g4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# Smallest current target has 32kB ram, use 16kB by default to avoid surprises\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# See STM Document RM0440\n\t\t# Section 46.6.3 - corresponds to Cortex-M4 r0p1\n\t\tset _CPUTAPID 0x4ba00477\n\t} {\n\t\tset _CPUTAPID 0x2ba01477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n\tset a [llength [flash list]]\n\tset _QSPINAME $_CHIPNAME.qspi\n\tflash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n}\n\n# reasonable default\nadapter speed 2000\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with HSION | HSIRDY.\n\t# Use HSI 16 MHz clock, compliant even with VOS == 2.\n\t# 1 WS compliant with VOS == 2 and 16 MHz.\n\tmmw 0x40022000 0x00000001 0x0000000E\t;# FLASH_ACR: Latency = 1\n\tmmw 0x40021000 0x00000100 0x00000000\t;# RCC_CR |= HSION\n\tmmw 0x40021008 0x00000001 0x00000002\t;# RCC_CFGR: SW=HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is HSI (16 MHz)\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32h7x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32h7x family\n\n#\n# stm32h7 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32h7x\n}\n\nif { [info exists DUAL_BANK] } {\n\tset $_CHIPNAME.DUAL_BANK $DUAL_BANK\n\tunset DUAL_BANK\n} else {\n\tset $_CHIPNAME.DUAL_BANK 0\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists USE_CTI] } {\n\tset $_CHIPNAME.USE_CTI $USE_CTI\n\tunset USE_CTI\n} else {\n\tset $_CHIPNAME.USE_CTI 0\n}\n\n# Issue a warning when DUAL_CORE=0 and USE_CTI=1, and fallback to USE_CTI=0\nif { ![set $_CHIPNAME.DUAL_CORE] && [set $_CHIPNAME.USE_CTI] } {\n\techo \"Warning : could not use CTI with a single core device, CTI is disabled\"\n\tset $_CHIPNAME.USE_CTI 0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n\t  set _CPUTAPID 0x6ba00477\n   } {\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nif {![using_hla]} {\n\t# STM32H7 provides an APB-AP at access port 2, which allows the access to\n\t# the debug and trace features on the system APB System Debug Bus (APB-D).\n\ttarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\n\tswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00E3000\n\ttpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE00F5000\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 0\n\n$_CHIPNAME.cpu0 configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.bank1.cpu0 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu0\n\nif {[set $_CHIPNAME.DUAL_BANK]} {\n\tflash bank $_CHIPNAME.bank2.cpu0 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu0\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap -ap-num 3\n\n\t$_CHIPNAME.cpu1 configure -work-area-phys 0x38000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.bank1.cpu1 stm32h7x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {[set $_CHIPNAME.DUAL_BANK]} {\n\t\tflash bank $_CHIPNAME.bank2.cpu1 stm32h7x 0x08100000 0 0 0 $_CHIPNAME.cpu1\n\t}\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_CHIPNAME.cpu0 0x52005000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_CHIPNAME.cpu0 0x5200A000\n   }\n}\n\n# Clock after reset is HSI at 64 MHz, no need of PLL\nadapter speed 1800\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n# use hardware reset\n#\n# The STM32H7 does not support connect_assert_srst mode because the AXI is\n# unavailable while SRST is asserted, and that is used to access the DBGMCU\n# component at 0x5C001000 in the examine-end event handler.\n#\n# It is possible to access the DBGMCU component at 0xE00E1000 via AP2 instead\n# of the default AP0, and that works with SRST asserted; however, nonzero AP\n# usage does not work with HLA, so is not done by default. That change could be\n# made in a local configuration file if connect_assert_srst mode is needed for\n# a specific application and a non-HLA adapter is in use.\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n\n\tif {[set $_CHIPNAME.DUAL_CORE]} {\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n   # Set CSW[27], which according to ARM ADI v5 appendix E1.4 maps to AHB signal\n   # HPROT[3], which according to AMBA AHB/ASB/APB specification chapter 3.7.3\n   # makes the data access cacheable. This allows reading and writing data in the\n   # CPU cache from the debugger, which is far more useful than going straight to\n   # RAM when operating on typical variables, and is generally no worse when\n   # operating on special memory locations.\n   $_CHIPNAME.dap apcsw 0x08000000 0x08000000\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable D3 and D1 DBG clocks\n\t# DBGMCU_CR |= D3DBGCKEN | D1DBGCKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00600000 0\n\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D1 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000007 0\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP D2 Domain\n\tstm32h7x_dbgmcu_mmw 0x004 0x00000038 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB3FZ1 |= WWDG1\n\tstm32h7x_dbgmcu_mmw 0x034 0x00000040 0\n\t# DBGMCU_APB1LFZ1 |= WWDG2\n\tstm32h7x_dbgmcu_mmw 0x03C 0x00000800 0\n\t# DBGMCU_APB4FZ1 |= WDGLSD1 | WDGLSD2\n\tstm32h7x_dbgmcu_mmw 0x054 0x000C0000 0\n\n\t# Enable clock for tracing\n\t# DBGMCU_CR |= TRACECLKEN\n\tstm32h7x_dbgmcu_mmw 0x004 0x00100000 0\n\n\t# RM0399 (id 0x450) M7+M4 with SWO Funnel\n\t# RM0433 (id 0x450) M7 with SWO Funnel\n\t# RM0455 (id 0x480) M7 without SWO Funnel\n\t# RM0468 (id 0x483) M7 without SWO Funnel\n\t# Enable CM7 and CM4 slave ports in SWO trace Funnel\n\t# Works ok also on devices single core and without SWO funnel\n\t# Hack, use stm32h7x_dbgmcu_mmw with big offset to control SWTF\n\t# SWTF_CTRL |= ENS0 | ENS1\n\tstm32h7x_dbgmcu_mmw 0x3000 0x00000003 0\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# Clock after reset is HSI at 64 MHz, no need of PLL\n\tadapter speed 4000\n}\n\n# get _CHIPNAME from current target\nproc stm32h7x_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\t$_CHIPNAME.cpu1 configure -event examine-end {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tglobal $_CHIPNAME.USE_CTI\n\n\t\t# Stop watchdog counters during halt\n\t\t# DBGMCU_APB3FZ2 |= WWDG1\n\t\tstm32h7x_dbgmcu_mmw 0x038 0x00000040 0\n\t\t# DBGMCU_APB1LFZ2 |= WWDG2\n\t\tstm32h7x_dbgmcu_mmw 0x040 0x00000800 0\n\t\t# DBGMCU_APB4FZ2 |= WDGLSD1 | WDGLSD2\n\t\tstm32h7x_dbgmcu_mmw 0x058 0x000C0000 0\n\n\t\tif {[set $_CHIPNAME.USE_CTI]} {\n\t\t\tstm32h7x_cti_start\n\t\t}\n\t}\n}\n\n# like mrw, but with target selection\nproc stm32h7x_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32h7x_mmw {used_target reg setbits clearbits} {\n\tset old [stm32h7x_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# mmw for dbgmcu component registers, it accepts the register offset from dbgmcu base\n# this procedure will use the mem_ap on AP2 whenever possible\nproc stm32h7x_dbgmcu_mmw {reg_offset setbits clearbits} {\n\t# use $_CHIPNAME.ap2 if possible, and use the proper dbgmcu base address\n\tif {![using_hla]} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\t\tset used_target $_CHIPNAME.ap2\n\t\tset reg_addr [expr {0xE00E1000 + $reg_offset}]\n\t} {\n\t\tset used_target [target current]\n\t\tset reg_addr [expr {0x5C001000 + $reg_offset}]\n\t}\n\n\tstm32h7x_mmw $used_target $reg_addr $setbits $clearbits\n}\n\nif {[set $_CHIPNAME.USE_CTI]} {\n\t# create CTI instances for both cores\n\tcti create $_CHIPNAME.cti0 -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0043000\n\tcti create $_CHIPNAME.cti1 -dap $_CHIPNAME.dap -ap-num 3 -baseaddr 0xE0043000\n\n\t$_CHIPNAME.cpu0 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event halted { stm32h7x_cti_prepare_restart_all }\n\n\t$_CHIPNAME.cpu0 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\t$_CHIPNAME.cpu1 configure -event debug-halted { stm32h7x_cti_prepare_restart_all }\n\n\tproc stm32h7x_cti_start {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Configure Cores' CTIs to halt each other\n\t\t# TRIGIN0 (DBGTRIGGER) and TRIGOUT0 (EDBGRQ) at CTM_CHANNEL_0\n\t\t$_CHIPNAME.cti0 write INEN0 0x1\n\t\t$_CHIPNAME.cti0 write OUTEN0 0x1\n\t\t$_CHIPNAME.cti1 write INEN0 0x1\n\t\t$_CHIPNAME.cti1 write OUTEN0 0x1\n\n\t\t# enable CTIs\n\t\t$_CHIPNAME.cti0 enable on\n\t\t$_CHIPNAME.cti1 enable on\n\t}\n\n\tproc stm32h7x_cti_stop {} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t$_CHIPNAME.cti0 enable off\n\t\t$_CHIPNAME.cti1 enable off\n\t}\n\n\tproc stm32h7x_cti_prepare_restart_all {} {\n\t\tstm32h7x_cti_prepare_restart cti0\n\t\tstm32h7x_cti_prepare_restart cti1\n\t}\n\n\tproc stm32h7x_cti_prepare_restart {cti} {\n\t\tset _CHIPNAME [stm32h7x_get_chipname]\n\n\t\t# Acknowlodge EDBGRQ at TRIGOUT0\n\t\t$_CHIPNAME.$cti write INACK 0x01\n\t\t$_CHIPNAME.$cti write INACK 0x00\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32h7x_dual_bank.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32h7x family (dual flash bank)\n\n# STM32H7xxxI 2Mo have a dual bank flash.\nset DUAL_BANK 1\n\nsource [find target/stm32h7x.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# M0+ devices only have SW-DP, but swj-dp code works, just don't\n# set any jtag related features\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l0\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 2kB (max ram on smallest part)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is ~2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    # Arm, m0+, non-multidrop.\n    # http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16088.html\n    set _CPUTAPID 0x0bc11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l0_enable_HSI16 {} {\n\t# Enable HSI16 as clock source\n\techo \"STM32L0: Enabling HSI16\"\n\n\t# Set HSI16ON in RCC_CR (leave MSI enabled)\n    mmw 0x40021000 0x00000101 0\n\n\t# Set HSI16 as SYSCLK (RCC_CFGR)\n\tmmw 0x4002100c 0x00000001 0\n\n\t# Wait until System clock switches to HSI16\n\twhile { ([ mrw 0x4002100c ] & 0x0c) != 0x04 } { }\n\n\t# Increase speed\n\tadapter speed 2500\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l0_enable_HSI16\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0x40015804 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0x40015808 0x00001800 0\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l0_dual_bank.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/stm32l0.cfg]\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# stm32l1 devices support both JTAG and SWD transports.\n#\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l1\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 10kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2800\n}\n\n# JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is 2MHz, so use F_JTAG max = 333kHz\nadapter speed 300\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0038\n      # Section 30.6.3 - corresponds to Cortex-M3 r2p0\n      set _CPUTAPID 0x4ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32lx 0x08000000 0 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\nproc stm32l_enable_HSI {} {\n\t# Enable HSI as clock source\n\techo \"STM32L: Enabling HSI\"\n\n\t# Set HSION in RCC_CR\n\tmmw 0x40023800 0x00000101 0\n\n\t# Set HSI as SYSCLK\n\tmmw 0x40023808 0x00000001 0\n\n\t# Increase JTAG speed\n\tadapter speed 2000\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l_enable_HSI\n}\n\n$_TARGETNAME configure -event reset-start {\n\tadapter speed 300\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n\t# change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l1x_dual_bank.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/stm32l1.cfg]\n\n# The stm32l1x 384kb have a dual bank flash.\n# Let's add a definition for the second bank here.\n\n# Add the second flash bank.\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32lx 0 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l4x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32l4x family\n\n#\n# stm32l4 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32l4x\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 40kB (Available RAM in smallest device STM32L412)\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0xa000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      # See STM Document RM0351\n      # Section 44.6.3 - corresponds to Cortex-M4 r0p1\n      set _CPUTAPID 0x4ba00477\n   } {\n      set _CPUTAPID 0x2ba01477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\nif { [info exists QUADSPI] && $QUADSPI } {\n   set a [llength [flash list]]\n   set _QSPINAME $_CHIPNAME.qspi\n   flash bank $_QSPINAME stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n} else {\n   if { [info exists OCTOSPI1] && $OCTOSPI1 } {\n      set a [llength [flash list]]\n      set _OCTOSPINAME1 $_CHIPNAME.octospi1\n      flash bank $_OCTOSPINAME1 stmqspi 0x90000000 0 0 0 $_TARGETNAME 0xA0001000\n   }\n   if { [info exists OCTOSPI2] && $OCTOSPI2 } {\n      set b [llength [flash list]]\n      set _OCTOSPINAME2 $_CHIPNAME.octospi2\n      flash bank $_OCTOSPINAME2 stmqspi 0x70000000 0 0 0 $_TARGETNAME 0xA0001400\n   }\n}\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0042008 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_chipname} {\n\ttargets $_chipname.cpu\n\n\tif { [$_chipname.tpiu cget -protocol] eq \"sync\" } {\n\t\tswitch [$_chipname.tpiu cget -port-width] {\n\t\t\t1 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 1 bit; GPIOE[2-3] to AF0\n\t\t\t\tmmw 0xE0042004 0x00000060 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0000ff00\n\t\t\t\tmmw 0x48001000 0x000000a0 0x000000f0\n\t\t\t\tmmw 0x48001008 0x000000f0 0x00000000\n\t\t\t  }\n\t\t\t2 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 2 bit; GPIOE[2-4] to AF0\n\t\t\t\tmmw 0xE0042004 0x000000a0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x000fff00\n\t\t\t\tmmw 0x48001000 0x000002a0 0x000003f0\n\t\t\t\tmmw 0x48001008 0x000003f0 0x00000000\n\t\t\t  }\n\t\t\t4 {\n\t\t\t\t# Set TRACE_IOEN; TRACE_MODE to sync 4 bit; GPIOE[2-6] to AF0\n\t\t\t\tmmw 0xE0042004 0x000000e0 0x000000c0\n\t\t\t\tmmw 0x48001020 0x00000000 0x0fffff00\n\t\t\t\tmmw 0x48001000 0x00002aa0 0x00003ff0\n\t\t\t\tmmw 0x48001008 0x00003ff0 0x00000000\n\t\t\t  }\n\t\t}\n\t} else {\n\t\t# Set TRACE_IOEN; TRACE_MODE to async\n\t\tmmw 0xE0042004 0x00000020 0x000000c0\n\t}\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_CHIPNAME\"\n\n$_TARGETNAME configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 6 (4 MHz).\n\t# Use MSI 24 MHz clock, compliant even with VOS == 2.\n\t# 3 WS compliant with VOS == 2 and 24 MHz.\n\tmww 0x40022000 0x00000103   ;# FLASH_ACR = PRFTBE | 3(Latency)\n\tmww 0x40021000 0x00000099   ;# RCC_CR = MSI_ON | MSIRGSEL | MSI Range 9\n\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32l5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32l5x family\n# stm32l5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32l5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32l5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is MSI (4MHz) after reset, set MCU freq at 110 MHz with PLL\n\t# RCC_APB1ENR1 = PWREN\n\tmww [expr {0x40021058 + $offset}] 0x10000000\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x40021058 + $offset}]\n\t# PWR_CR1 : VOS Range 0\n\tmww [expr {0x40007000 + $offset}] 0\n\t# while (PWR_SR2 & VOSF)\n\twhile {([mrw [expr {0x40007014 + $offset}]] & 0x0400)} {}\n\t# FLASH_ACR : 5 WS for 110 MHz HCLK\n\tmww 0x40022000 0x00000005\n\t# RCC_PLLCFGR = PLLP=PLLQ=0, PLLR=00=2, PLLREN=1, PLLN=55, PLLM=0000=1, PLLSRC=MSI 4MHz\n\t# fVCO = 4 x 55 /1 = 220\n\t# SYSCLOCK = fVCO/PLLR = 220/2 = 110 MHz\n\tmww [expr {0x4002100C + $offset}] 0x01003711\n\t# RCC_CR |= PLLON\n\tmmw [expr {0x40021000 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLLRDY)\n\twhile {!([mrw [expr {0x40021000 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR |= SW_PLL\n\tmmw [expr {0x40021008 + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR & SWS) != PLL)\n\twhile {([mrw [expr {0x40021008 + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32l5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32mp13x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STMicroelectronics STM32MP13x (Single Cortex-A7)\n# http://www.st.com/stm32mp1\n\n# HLA does not support custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp13x_dk.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp13x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06501041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\n\n$_CHIPNAME.cpu cortex_a maskisr on\n$_CHIPNAME.cpu cortex_a dacrfixup on\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# srst resets the debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# keep clock enabled in low-power\n\t## catch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000004}\n\t# freeze watchdog 1 and 2 on core halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\n# FIXME: most of handlers below will be removed once reset framework get merged\n$_CHIPNAME.ap1 configure -event reset-deassert-pre {\n\tadapter deassert srst deassert trst\n\tcatch {dap init}\n\tcatch {$::_CHIPNAME.dap apid 1}\n}\n$_CHIPNAME.cpu configure -event reset-deassert-pre  {$::_CHIPNAME.cpu arp_examine}\n$_CHIPNAME.cpu configure -event reset-deassert-post {toggle_cpu_dbg_claim0; dbgmcu_enable_debug}\n$_CHIPNAME.ap1 configure -event examine-start       {dap init}\n$_CHIPNAME.ap1 configure -event examine-end         {dbgmcu_enable_debug}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32mp15x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# STMicroelectronics STM32MP15x (Single/Dual Cortex-A7 plus Cortex-M4)\n# http://www.st.com/stm32mp1\n\n# HLA does not support multi-cores nor custom CSW nor AP other than 0\nif { [using_hla] } {\n\techo \"ERROR: HLA transport cannot work with this target.\"\n\techo \"ERROR: To use STLink switch to DAP mode, as in \\\"board/stm32mp15x_dk2.cfg\\\".\"\n\tshutdown\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32mp15x\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\n# Chip Level TAP Controller, only in jtag mode\nif { [info exists CLCTAPID] } {\n\tset _CLCTAPID $CLCTAPID\n} else {\n\tset _CLCTAPID 0x06500041\n}\n\nswj_newdap $_CHIPNAME tap -expected-id $_CPUTAPID -irlen 4\nif { [using_jtag] } {\n\tjtag newtap $_CHIPNAME.clc tap -expected-id $_CLCTAPID -irlen 5\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap -ignore-syspwrupack\n\n# FIXME: Cortex-M code requires target accessible during reset, but this is not possible in STM32MP1\n# so defer-examine it until the reset framework get merged\n# NOTE: keep ap-num and dbgbase to speed-up examine after reset\n# NOTE: do not change the order of target create\ntarget create $_CHIPNAME.ap1 mem_ap -dap $_CHIPNAME.dap -ap-num 1\ntarget create $_CHIPNAME.ap2 mem_ap -dap $_CHIPNAME.dap -ap-num 2\ntarget create $_CHIPNAME.axi mem_ap -dap $_CHIPNAME.dap -ap-num 0\ntarget create $_CHIPNAME.cpu0 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 0 -dbgbase 0xE00D0000\ntarget create $_CHIPNAME.cpu1 cortex_a -dap $_CHIPNAME.dap -ap-num 1 -coreid 1 -dbgbase 0xE00D2000\ntarget create $_CHIPNAME.cm4 cortex_m -dap $_CHIPNAME.dap -ap-num 2 -defer-examine\n\ntargets $_CHIPNAME.cpu0\n\ntarget smp $_CHIPNAME.cpu0 $_CHIPNAME.cpu1\n$_CHIPNAME.cpu0 cortex_a maskisr on\n$_CHIPNAME.cpu1 cortex_a maskisr on\n$_CHIPNAME.cpu0 cortex_a dacrfixup on\n$_CHIPNAME.cpu1 cortex_a dacrfixup on\n\ncti create $_CHIPNAME.cti.sys  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0094000\ncti create $_CHIPNAME.cti.cpu0 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D8000\ncti create $_CHIPNAME.cti.cpu1 -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE00D9000\ncti create $_CHIPNAME.cti.cm4  -dap $_CHIPNAME.dap -ap-num 2 -baseaddr 0xE0043000\n\nswo  create $_CHIPNAME.swo  -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0083000\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 1 -baseaddr 0xE0093000\n\n# interface does not work while srst is asserted\n# this is target specific, valid for every board\n# Errata \"2.3.5 Incorrect reset of glitch-free kernel clock switch\" requires\n# srst to force VDDCORE power cycle or pull srst_core. Both cases reset the\n# debug unit, behavior equivalent to \"srst_pulls_trst\"\nreset_config srst_gates_jtag srst_pulls_trst\n\nadapter speed 5000\nadapter srst pulse_width 200\n# bootrom has an internal timeout of 1 second for detecting the boot flash.\n# wait at least 1 second to guarantee we are out of bootrom\nadapter srst delay 1100\n\nadd_help_text axi_secure \"Set secure mode for following AXI accesses\"\nproc axi_secure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x10006000\n}\n\nadd_help_text axi_nsecure \"Set non-secure mode for following AXI accesses\"\nproc axi_nsecure {} {\n\t$::_CHIPNAME.dap apsel 0\n\t$::_CHIPNAME.dap apcsw 0x30006000\n}\n\naxi_secure\n\nproc dbgmcu_enable_debug {} {\n\t# set debug enable bits in DBGMCU_CR to get ap2 and cm4 visible\n\tcatch {$::_CHIPNAME.ap1 mww 0xe0081004 0x00000007}\n\t# freeze watchdog 1 and 2 on cores halted\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008102c 0x00000004}\n\tcatch {$::_CHIPNAME.ap1 mww 0xe008104c 0x00000008}\n}\n\nproc toggle_cpu0_dbg_claim0 {} {\n\t# toggle CPU0 DBG_CLAIM[0]\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa0 1\n\t$::_CHIPNAME.ap1 mww 0xe00d0fa4 1\n}\n\nproc detect_cpu1 {} {\n\tset cpu1_prsr [$::_CHIPNAME.ap1 read_memory 0xE00D2314 32 1]\n\tset dual_core [expr {$cpu1_prsr & 1}]\n\tif {! $dual_core} {$::_CHIPNAME.cpu1 configure -defer-examine}\n}\n\nproc rcc_enable_traceclk {} {\n\t$::_CHIPNAME.ap2 mww 0x5000080c 0x301\n}\n\n# FIXME: most of handler below will be removed once reset framework get merged\n$_CHIPNAME.ap1  configure -event reset-deassert-pre  {adapter deassert srst deassert trst;catch {dap init};catch {$::_CHIPNAME.dap apid 1}}\n$_CHIPNAME.ap2  configure -event reset-deassert-pre  {dbgmcu_enable_debug;rcc_enable_traceclk}\n$_CHIPNAME.cpu0 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu0 arp_examine}\n$_CHIPNAME.cpu1 configure -event reset-deassert-pre  {$::_CHIPNAME.cpu1 arp_examine allow-defer}\n$_CHIPNAME.cpu0 configure -event reset-deassert-post {toggle_cpu0_dbg_claim0}\n$_CHIPNAME.cm4  configure -event reset-deassert-post {$::_CHIPNAME.cm4 arp_examine;if {[$::_CHIPNAME.ap2 curstate] == \"halted\"} {$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_poll;$::_CHIPNAME.cm4 arp_halt}}\n$_CHIPNAME.ap1  configure -event examine-start       {dap init}\n$_CHIPNAME.ap2  configure -event examine-start       {dbgmcu_enable_debug}\n$_CHIPNAME.cpu0 configure -event examine-end         {detect_cpu1}\n$_CHIPNAME.ap2  configure -event examine-end         {rcc_enable_traceclk;$::_CHIPNAME.cm4 arp_examine}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32u5x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32u5x family\n# stm32u5x devices support both JTAG and SWD transports.\n\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32u5x\n}\n\nsource [find target/stm32x5x_common.cfg]\n\nproc stm32u5x_clock_config {} {\n\tset offset [expr {[stm32x5x_is_secure] ? 0x10000000 : 0}]\n\t# MCU clock is at MSI 4MHz after reset, set MCU freq at 160 MHz with PLL\n\n\t# Enable voltage range 1 for frequency above 100 Mhz\n\t# RCC_AHB3ENR = PWREN\n\tmww [expr {0x46020C94 + $offset}] 0x00000004\n\t# delay for register clock enable (read back reg)\n\tmrw [expr {0x46020C94 + $offset}]\n\t# PWR_VOSR : VOS Range 1\n\tmmw [expr {0x4602080C + $offset}] 0x00030000 0\n\t# while !(PWR_VOSR & VOSRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00008000)} {}\n\t# FLASH_ACR : 4 WS for 160 MHz HCLK\n\tmww [expr {0x40022000 + $offset}] 0x00000004\n\t# RCC_PLL1CFGR => PLL1MBOOST=0, PLL1M=0=/1, PLL1FRACEN=0, PLL1SRC=MSI 4MHz\n\t#                 PLL1REN=1, PLL1RGE => VCOInputRange=PLLInputRange_4_8\n\tmww [expr {0x46020C28 + $offset}] 0x00040009\n\t# Enable EPOD Booster\n\tmmw [expr {0x4602080C + $offset}] 0x00040000 0\n\t# while !(PWR_VOSR & BOOSTRDY)\n\twhile {!([mrw [expr {0x4602080C + $offset}]] & 0x00004000)} {}\n\t# RCC_PLL1DIVR => PLL1P=PLL1Q=PLL1R=000001=/2, PLL1N=0x4F=80\n\t# fVCO = 4 x 80 /1 = 320\n\t# SYSCLOCK = fVCO/PLL1R = 320/2 = 160 MHz\n\tmww [expr {0x46020C34 + $offset}] 0x0101024F\n\t# RCC_CR |= PLL1ON\n\tmmw [expr {0x46020C00 + $offset}] 0x01000000 0\n\t# while !(RCC_CR & PLL1RDY)\n\twhile {!([mrw [expr {0x46020C00 + $offset}]] & 0x02000000)} {}\n\t# RCC_CFGR1 |= SW_PLL\n\tmmw [expr {0x46020C1C + $offset}] 0x00000003 0\n\t# while ((RCC_CFGR1 & SWS) != PLL)\n\twhile {([mrw [expr {0x46020C1C + $offset}]] & 0x0C) != 0x0C} {}\n}\n\n$_TARGETNAME configure -event reset-init {\n\tstm32u5x_clock_config\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32w108xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Target configuration for the ST STM32W108xx chips\n#\n# Processor: ARM Cortex-M3\n# Date:      2013-06-09\n# Author:    Giuseppe Barba <giuseppe.barba@gmail.com>\n\n#\n# stm32 devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] == 0 } {\n   set _CHIPNAME stm32w108\n} else {\n   set _CHIPNAME $CHIPNAME\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x2000\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x3ba00477\n   } {\n      set _CPUTAPID 0x1ba01477\n   }\n}\n\nset _ENDIAN little\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n if { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf -expected-id _BSTAPID\n } else {\n   set _BSTAPID_1 0x169a862b\n   set _BSTAPID_2 0x269a862b\n   jtag newtap $_CHIPNAME bs -irlen 4 -ircapture 0xe -irmask 0xf \\\n\t\t-expected-id $_BSTAPID_1 -expected-id $_BSTAPID_2\n }\n}\n#\n# Set Target\n#\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\n# Use the flash driver from the EM357\nset _FLASHNAME $_CHIPNAME.flash\n\n# 64k (0x10000) of flash\nflash bank $_FLASHNAME em357 0x08000000 0x10000 0 0 $_TARGETNAME\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32wbx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32wbx family\n\n#\n# stm32wb devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm32wbx\n}\n\nset _ENDIAN little\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   if { [using_jtag] } {\n      set _CPUTAPID 0x6ba00477\n   } else {\n      # SWD IDCODE (single drop, arm)\n      set _CPUTAPID 0x6ba02477\n   }\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n   jtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian $_ENDIAN -dap $_CHIPNAME.dap\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp   stm32l4x 0x1fff7000 0 0 0 $_TARGETNAME\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n jtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {![using_hla]} {\n   # if srst is not fitted use SYSRESETREQ to\n   # perform a soft reset\n   cortex_m reset_config sysresetreq\n}\n\n$_TARGETNAME configure -event reset-init {\n    # CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n    # Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n    # 2 WS compliant with VOS=Range1 and 24 MHz.\n    mmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTBE | 2(Latency)\n    mmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n    # Boost JTAG frequency\n    adapter speed 4000\n}\n\n$_TARGETNAME configure -event reset-start {\n    # Reset clock is MSI (4 MHz)\n    adapter speed 500\n}\n\n$_TARGETNAME configure -event examine-end {\n    # Enable debug during low power modes (uses more power)\n    # DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n    mmw 0xE0042004 0x00000007 0\n\n    # Stop watchdog counters during halt\n    # DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n    mmw 0xE004203C 0x00001800 0\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n    targets $_targetname\n\n    # Set TRACE_IOEN; TRACE_MODE is set to async; when using sync\n    # change this value accordingly to configure trace pins\n    # assignment\n    mmw 0xE0042004 0x00000020 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32wlx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32wlx family\n\n#\n# stm32wl devices support both JTAG and SWD transports.\n#\nsource [find target/swj-dp.tcl]\nsource [find mem_helper.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME stm32wlx\n}\n\nif { [info exists DUAL_CORE] } {\n\tset $_CHIPNAME.DUAL_CORE $DUAL_CORE\n\tunset DUAL_CORE\n} else {\n\tset $_CHIPNAME.DUAL_CORE 0\n}\n\nif { [info exists WKUP_CM0P] } {\n\tset $_CHIPNAME.WKUP_CM0P $WKUP_CM0P\n\tunset WKUP_CM0P\n} else {\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# Issue a warning when hla is used, and fallback to single core configuration\nif { [set $_CHIPNAME.DUAL_CORE] && [using_hla] } {\n\techo \"Warning : hla does not support multicore debugging\"\n\tset $_CHIPNAME.DUAL_CORE 0\n\tset $_CHIPNAME.WKUP_CM0P 0\n}\n\n# setup the Work-area start address and size\n# Work-area is a space in RAM used for flash programming\n\n# Memory map for known devices:\n# STM32WL   x5JC   x5JB   x5J8\n#   FLASH   256    128    64\n#   SRAM1   32     16     0\n#   SRAM2   32     32     20\n\n# By default use 8kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n# Use SRAM2 as work area (some devices do not have SRAM1):\nset WORKAREASTART_CM4   0x20008000\nset WORKAREASTART_CM0P  [expr {$WORKAREASTART_CM4 + $_WORKAREASIZE}]\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\tset _CPUTAPID 0x6ba00477\n\t} else {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x6ba02477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\ntarget create $_CHIPNAME.cpu0 cortex_m -endian little -dap $_CHIPNAME.dap\n\n$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM4 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nflash bank $_CHIPNAME.flash.cpu0 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu0\nflash bank $_CHIPNAME.otp.cpu0   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu0\n\nif {![using_hla]} {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\t$_CHIPNAME.cpu0 cortex_m reset_config sysresetreq\n}\n\n$_CHIPNAME.cpu0 configure -event reset-init {\n\t# CPU comes out of reset with MSI_ON | MSI_RDY | MSI Range 4 MHz.\n\t# Configure system to use MSI 24 MHz clock, compliant with VOS default Range1.\n\t# 2 WS compliant with VOS=Range1 and 24 MHz.\n\tmmw 0x58004000 0x00000102 0  ;# FLASH_ACR |= PRFTEN | 2(Latency)\n\tmmw 0x58000000 0x00000091 0  ;# RCC_CR = MSI_ON | MSI Range 24 MHz\n\t# Boost JTAG frequency\n\tadapter speed 4000\n}\n\n$_CHIPNAME.cpu0 configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 500\n}\n\n$_CHIPNAME.cpu0 configure -event examine-end {\n\t# Enable debug during low power modes (uses more power)\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP | DBG_SLEEP\n\tmmw 0xE0042004 0x00000007 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZR1 |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE004203C 0x00001800 0\n\n\tset _CHIPNAME [stm32wlx_get_chipname]\n\tglobal $_CHIPNAME.WKUP_CM0P\n\n\tif {[set $_CHIPNAME.WKUP_CM0P]} {\n\t\tstm32wlx_wkup_cm0p\n\t}\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nif {[set $_CHIPNAME.DUAL_CORE]} {\n\ttarget create $_CHIPNAME.cpu1 cortex_m -endian little -dap $_CHIPNAME.dap -ap-num 1\n\n\t$_CHIPNAME.cpu0 configure -work-area-phys $WORKAREASTART_CM0P -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n\tflash bank $_CHIPNAME.flash.cpu1 stm32l4x 0x08000000 0 0 0 $_CHIPNAME.cpu1\n\tflash bank $_CHIPNAME.otp.cpu1   stm32l4x 0x1fff7000 0 0 0 $_CHIPNAME.cpu1\n\n\tif {![using_hla]} {\n\t\t# if srst is not fitted use SYSRESETREQ to\n\t\t# perform a soft reset\n\t\t$_CHIPNAME.cpu1 cortex_m reset_config sysresetreq\n\t}\n\n\tproc stm32wlx_wkup_cm0p {} {\n\t\tset _CHIPNAME [stm32wlx_get_chipname]\n\n\t\t# enable CPU2 boot after reset and after wakeup from Stop or Standby mode\n\t\t# PWR_CR4 |= C2BOOT\n\t\tstm32wlx_mmw $_CHIPNAME.cpu0 0x5800040C 0x00008000 0\n\t}\n}\n\n# get _CHIPNAME from current target\nproc stm32wlx_get_chipname {} {\n\tset t [target current]\n\tset sep [string last \".\" $t]\n\tif {$sep == -1} {\n\t\treturn $t\n\t}\n\treturn [string range $t 0 [expr {$sep - 1}]]\n}\n\n# like mrw, but with target selection\nproc stm32wlx_mrw {used_target reg} {\n\treturn [$used_target read_memory $reg 32 1]\n}\n\n# like mmw, but with target selection\nproc stm32wlx_mmw {used_target reg setbits clearbits} {\n\tset old [stm32wlx_mrw $used_target $reg]\n\tset new [expr {($old & ~$clearbits) | $setbits}]\n\t$used_target mww $reg $new\n}\n\n# Make sure that cpu0 is selected\ntargets $_CHIPNAME.cpu0\n\n# Common knowledges tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://openocd.zylin.com/#/c/3366/\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32x5x_common.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# common script for stm32l5x and stm32u5x families\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\n#jtag scan chain\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tif { [using_jtag] } {\n\t\t# STM32L5x: RM0438 Rev5, Section 52.2.8 JTAG debug port - Table 425. JTAG-DP data registers\n\t\t# STM32U5x: RM0456 Rev1, Section 65.2.8 JTAG debug port - Table 661. JTAG-DP data registers\n\t\t# Corresponds to Cortex®-M33 JTAG debug port ID code\n\t\tset _CPUTAPID 0x0ba04477\n\t} {\n\t\t# SWD IDCODE (single drop, arm)\n\t\tset _CPUTAPID 0x0be12477\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME bs -irlen 5\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\n# use non-secure RAM by default\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\n# create sec/ns flash and otp memories (sizes will be probed)\nflash bank $_CHIPNAME.flash_ns      stm32l4x 0x08000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.flash_alias_s stm32l4x 0x0C000000 0 0 0 $_TARGETNAME\nflash bank $_CHIPNAME.otp           stm32l4x 0x0BFA0000 0 0 0 $_TARGETNAME\n\n# Common knowledge tells JTAG speed should be <= F_CPU/6.\n# F_CPU after reset is MSI 4MHz, so use F_JTAG = 500 kHz to stay on\n# the safe side.\n#\n# Note that there is a pretty wide band where things are\n# more or less stable, see http://review.openocd.org/3366\nadapter speed 500\n\nadapter srst delay 100\nif {[using_jtag]} {\n\tjtag_ntrst_delay 100\n}\n\nreset_config srst_nogate\n\nif {[using_hla]} {\n\techo \"Warn : The selected adapter does not support debugging this device in secure mode\"\n} else {\n\t# if srst is not fitted use SYSRESETREQ to\n\t# perform a soft reset\n\tcortex_m reset_config sysresetreq\n}\n\nproc stm32x5x_is_secure {} {\n\t# read Debug Security Control and Status Register (DSCSR) and check CDS (bit 16)\n\tset DSCSR [mrw 0xE000EE08]\n\treturn [expr {($DSCSR & (1 << 16)) != 0}]\n}\n\nproc stm32x5x_ahb_ap_non_secure_access {} {\n\t# in HLA mode, non-secure debugging is possible without changing the AP CSW\n\tif {![using_hla]} {\n\t\t# SPROT=1=Non Secure access, Priv=1\n\t\t[[target current] cget -dap] apcsw 0x4B000000 0x4F000000\n\t}\n}\n\nproc stm32x5x_ahb_ap_secure_access {} {\n\tif {![using_hla]} {\n\t\t# SPROT=0=Secure access, Priv=1\n\t\t[[target current] cget -dap] apcsw 0x0B000000 0x4F000000\n\t}\n}\n\n$_TARGETNAME configure -event reset-start {\n\t# Reset clock is MSI (4 MHz)\n\tadapter speed 480\n}\n\n$_TARGETNAME configure -event examine-end {\n\t# DBGMCU_CR |= DBG_STANDBY | DBG_STOP\n\tmmw 0xE0044004 0x00000006 0\n\n\t# Stop watchdog counters during halt\n\t# DBGMCU_APB1_FZ |= DBG_IWDG_STOP | DBG_WWDG_STOP\n\tmmw 0xE0044008 0x00001800 0\n}\n\n$_TARGETNAME configure -event halted {\n\tset secure [stm32x5x_is_secure]\n\n\tif {$secure} {\n\t\tset secure_str \"Secure\"\n\t\tstm32x5x_ahb_ap_secure_access\n\t} else {\n\t\tset secure_str \"Non-Secure\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t}\n\n\t# print the secure state only when it changes\n\tset _TARGETNAME [target current]\n\tglobal $_TARGETNAME.secure\n\n\tif {![info exists $_TARGETNAME.secure] || $secure != [set $_TARGETNAME.secure]} {\n\t\techo \"CPU in $secure_str state\"\n\t\t# update saved security state\n\t\tset $_TARGETNAME.secure $secure\n\t}\n}\n\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tset use_secure_workarea 0\n\t# check if FLASH_OPTR.TZEN is enabled\n\tset FLASH_OPTR [mrw 0x40022040]\n\tif {[expr {$FLASH_OPTR & 0x80000000}] == 0} {\n\t\techo \"TZEN option bit disabled\"\n\t\tstm32x5x_ahb_ap_non_secure_access\n\t} else {\n\t\tstm32x5x_ahb_ap_secure_access\n\t\techo \"TZEN option bit enabled\"\n\n\t\t# check if FLASH_OPTR.RDP is not Level 0.5\n\t\tif {[expr {$FLASH_OPTR & 0xFF}] != 0x55} {\n\t\t\tset use_secure_workarea 1\n\t\t}\n\t}\n\n\tset _TARGETNAME [target current]\n\tset workarea_addr [$_TARGETNAME cget -work-area-phys]\n\techo \"workarea_addr $workarea_addr\"\n\n\tif {$use_secure_workarea} {\n\t\tset workarea_addr [expr {$workarea_addr | 0x10000000}]\n\t} else {\n\t\tset workarea_addr [expr {$workarea_addr & ~0x10000000}]\n\t}\n\n\t$_TARGETNAME configure -work-area-phys $workarea_addr\n}\n\ntpiu create $_CHIPNAME.tpiu -dap $_CHIPNAME.dap -ap-num 0 -baseaddr 0xE0040000\n\nlappend _telnet_autocomplete_skip _proc_pre_enable_$_CHIPNAME.tpiu\nproc _proc_pre_enable_$_CHIPNAME.tpiu {_targetname} {\n\ttargets $_targetname\n\n\t# Set TRACE_EN and TRACE_IOEN in DBGMCU_CR\n\t# Leave TRACE_MODE untouched (defaults to async).\n\t# When using sync change this value accordingly to configure trace pins\n\t# assignment\n\tmmw 0xE0044004 0x00000030 0\n}\n\n$_CHIPNAME.tpiu configure -event pre-enable \"_proc_pre_enable_$_CHIPNAME.tpiu $_TARGETNAME\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm32xl.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm32xl family (dual flash bank)\nsource [find target/stm32f1x.cfg]\n\n# flash size will be probed\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME stm32f1x 0x08080000 0 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm8l family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8l\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set stm8l type\n$_TARGETNAME configure -enable_stm8l\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n#uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l151x2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config script for STM8L151x2\n# Supported Devices:\n# STM8L151C2\n# STM8L151F2\n# STM8L151G2\n# STM8L151K2\n\n# 1kB RAM\n# Start 0x0000\n# End   0x03ff\nset WORKAREASIZE 1024\n\n# 4kB Flash\nset FLASHSTART  0x8000\nset FLASHEND    0x8fff\n\n# 256B EEPROM\nset EEPROMSTART 0x1000\nset EEPROMEND   0x10ff\n\nset OPTIONSTART 0x4800\nset OPTIONEND   0x487f\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l151x3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config script for STM8L151x3\n# Supported Devices:\n# STM8L151C3\n# STM8L151F3\n# STM8L151G3\n# STM8L151K3\n\n# 1kB RAM\n# Start 0x0000\n# End   0x03ff\nset WORKAREASIZE 1024\n\n# 8kB Flash\nset FLASHSTART  0x8000\nset FLASHEND    0x9fff\n\n# 256B EEPROM\nset EEPROMSTART 0x1000\nset EEPROMEND   0x10ff\n\nset OPTIONSTART 0x4800\nset OPTIONEND   0x487f\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l152.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho 'DEPRECATED: choose between stm8l15xx4.cfg, stm8l15xx6.cfg and stm8l15xx8.cfg instead of stm8l152.cfg'\necho '            using stm8l152.cfg for backwards compatability'\n\nset EEPROMSTART 0x1000\nset EEPROMEND 0x13ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l15xx4.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config script for STM8L151x4/STM8L152x4\n# Supported Devices:\n# STM8L151C4\n# STM8L151G4\n# STM8L151K4\n# STM8L152C4\n# STM8L152K4\n\n# 2kB RAM\n# Start 0x0000\n# End   0x07ff\nset WORKAREASIZE 2048\n\n# 16kB Flash\nset FLASHSTART  0x8000\nset FLASHEND    0xbfff\n\n# 1kB EEPROM\nset EEPROMSTART 0x1000\nset EEPROMEND   0x13ff\n\nset OPTIONSTART 0x4800\nset OPTIONEND   0x48ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l15xx6.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config script for STM8L151x6/STM8L152x6\n# Supported Devices:\n# STM8L151C6\n# STM8L151G6\n# STM8L151K6\n# STM8L151R6\n# STM8L152C6\n# STM8L152K6\n# STM8L152R6\n\n# 2kB RAM\n# Start 0x0000\n# End   0x07ff\nset WORKAREASIZE 2048\n\n# 32kB Flash\nset FLASHSTART  0x8000\nset FLASHEND    0xffff\n\n# 1kB EEPROM\nset EEPROMSTART 0x1000\nset EEPROMEND   0x13ff\n\nset OPTIONSTART 0x4800\nset OPTIONEND   0x48ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8l15xx8.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Config script for STM8L151x8/STM8L152x8\n# Supported Devices:\n# STM8L151C8\n# STM8L151M8\n# STM8L151R8\n# STM8L152C8\n# STM8L152K8\n# STM8L152M8\n# STM8L152R8\n\n# 4kB RAM\n# Start 0x0000\n# End   0x0fff\nset WORKAREASIZE 4096\n\n# 64kB Flash\nset FLASHSTART  0x08000\nset FLASHEND    0x17fff\n\n# 2kB EEPROM\nset EEPROMSTART 0x1000\nset EEPROMEND   0x17ff\n\nset OPTIONSTART 0x4800\nset OPTIONEND   0x48ff\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0xaa\n   mwb 0x4800 0xaa\n   reset halt\n}\n\nsource [find target/stm8l.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8s.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for stm8s family\n\n#\n# stm8 devices support SWIM transports only.\n#\n\ntransport select swim\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME stm8s\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 1kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x400\n}\n\nif { [info exists FLASHSTART] } {\n   set _FLASHSTART $FLASHSTART\n} else {\n   set _FLASHSTART 0x8000\n}\n\nif { [info exists FLASHEND] } {\n   set _FLASHEND $FLASHEND\n} else {\n   set _FLASHEND 0xffff\n}\n\nif { [info exists EEPROMSTART] } {\n   set _EEPROMSTART $EEPROMSTART\n} else {\n   set _EEPROMSTART 0x4000\n}\n\nif { [info exists EEPROMEND] } {\n   set _EEPROMEND $EEPROMEND\n} else {\n   set _EEPROMEND 0x43ff\n}\n\nif { [info exists OPTIONSTART] } {\n   set _OPTIONSTART $OPTIONSTART\n} else {\n   set _OPTIONSTART 0x4800\n}\n\nif { [info exists OPTIONEND] } {\n   set _OPTIONEND $OPTIONEND\n} else {\n   set _OPTIONEND 0x487f\n}\n\nif { [info exists BLOCKSIZE] } {\n   set _BLOCKSIZE $BLOCKSIZE\n} else {\n   set _BLOCKSIZE 0x80\n}\n\nswim newtap $_CHIPNAME cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME stm8 -chain-position $_CHIPNAME.cpu\n\n$_TARGETNAME configure -work-area-phys 0x0 -work-area-size $_WORKAREASIZE -work-area-backup 1\n$_TARGETNAME configure -flashstart $_FLASHSTART -flashend $_FLASHEND -eepromstart $_EEPROMSTART -eepromend $_EEPROMEND\n$_TARGETNAME configure -optionstart $_OPTIONSTART -optionend $_OPTIONEND -blocksize $_BLOCKSIZE\n\n# Uncomment this line to enable interrupts while instruction step\n#$_TARGETNAME configure -enable_step_irq\n\n# Set high speed\nadapter speed 800\n# Set low speed\n#adapter speed 363\n\nreset_config srst_only\n\n# uncomment this line to connect under reset\n#reset_config srst_nogate connect_assert_srst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8s003.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#config script for STM8S003\n\nset FLASHEND 0x9FFF\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8s103.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#config script for STM8S103\n\nset FLASHEND 0x9FFF\nset EEPROMEND 0x427F\nset OPTIONEND 0x480A\nset BLOCKSIZE 0x40\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/stm8s105.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#config script for STM8S105\n\nproc stm8_reset_rop {} {\n   mwb 0x4800 0x00\n   reset halt\n}\n\nsource [find target/stm8s.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/str710.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#start slow, speed up after reset\nadapter speed 10\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str710\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 6000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x40000000 0x00040000 0 0 $_TARGETNAME STR71x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x400C0000 0x00004000 0 0 $_TARGETNAME STR71x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/str730.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#STR730 CPU\n\nadapter speed 3000\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str730\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x3f0f0f0f\n}\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0xA0000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME str7x 0x80000000 0x00040000 0 0 $_TARGETNAME STR73x\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/str750.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#STR750 CPU\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str750\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x4f1f0041\n}\n\n# jtag speed\nadapter speed 10\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0x0f -expected-id $_CPUTAPID\n\n#jtag nTRST and nSRST delay\nadapter srst delay 500\njtag_ntrst_delay 500\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position 0\n\n$_TARGETNAME configure -event reset-start { adapter speed 10 }\n$_TARGETNAME configure -event reset-init {\n\tadapter speed 3000\n\n\tinit_smi\n# Because the hardware cannot be interrogated for the protection state\n# of sectors, initialize all the sectors to be unprotected. The initial\n# state is reflected by the driver, too.\n\tflash protect 0 0 last off\n\tflash protect 1 0 last off\n}\n$_TARGETNAME configure -event gdb-flash-erase-start {\n\tflash protect 0 0 7 off\n\tflash protect 1 0 1 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup 0\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str7x 0x20000000 0x00040000 0 0 $_TARGETNAME STR75x\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str7x 0x200C0000 0x00004000 0 0 $_TARGETNAME STR75x\n\n# Serial NOR on SMI CS0.\nset _FLASHNAME $_CHIPNAME.snor\nflash bank $_FLASHNAME stmsmi 0x80000000 0 0 0 $_TARGETNAME\n\nsource [find mem_helper.tcl]\n\nproc init_smi {} {\n\tmmw 0x60000030 0x01000000 0x00000000; # enable clock for GPIO regs\n\tmmw 0xffffe420 0x00000001 0x00000000; # set SMI_EN bit\n\tmmw 0x90000000 0x00000001 0x00000000; # set BLOCK_EN_1\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/str912.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# script for str9\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME str912\n}\n\nif { [info exists ENDIAN] } {\n   set _ENDIAN $ENDIAN\n} else {\n   set _ENDIAN little\n}\n\n# jtag speed. We need to stick to 16kHz until we've finished reset.\nadapter speed 16\n\nadapter srst delay 100\njtag_ntrst_delay 100\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\nif { [info exists FLASHTAPID] } {\n   set _FLASHTAPID $FLASHTAPID\n} else {\n   set _FLASHTAPID 0x04570041\n}\njtag newtap $_CHIPNAME flash -irlen 8 -ircapture 0x1 -irmask 0x1 -expected-id $_FLASHTAPID\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x25966041\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n\nif { [info exists BSTAPID] } {\n   set _BSTAPID $BSTAPID\n} else {\n   # possible values: 0x1457f041, 0x2457f041\n   # we ignore version in check below\n   set _BSTAPID 0x1457f041\n}\njtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID -ignore-version\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm966e -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-start { adapter speed 16 }\n\n$_TARGETNAME configure -event reset-init {\n\t# We can increase speed now that we know the target is halted.\n\t#adapter speed 3000\n\n\t# -- Enable 96K RAM\n\t# PFQBC enabled / DTCM & AHB wait-states disabled\n\tmww 0x5C002034 0x0191\n\n\tstr9x flash_config 0 4 2 0 0x80000\n\tflash protect 0 0 7 off\n}\n\n$_TARGETNAME configure -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup 0\n\n#flash bank str9x <base> <size> 0 0 <target#> <variant>\nset _FLASHNAME $_CHIPNAME.flash0\nflash bank $_FLASHNAME str9x 0x00000000 0x00080000 0 0 $_TARGETNAME\nset _FLASHNAME $_CHIPNAME.flash1\nflash bank $_FLASHNAME str9x 0x00080000 0x00008000 0 0 $_TARGETNAME\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/swj-dp.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# ARM Debug Interface V5 (ADI_V5) utility\n# ... Mostly for SWJ-DP (not SW-DP or JTAG-DP, since\n# SW-DP and JTAG-DP targets don't need to switch based\n# on which transport is active.\n#\n# declare a JTAG or SWD Debug Access Point (DAP)\n# based on the transport in use with this session.\n# You can't access JTAG ops when SWD is active, etc.\n\n# params are currently what \"jtag newtap\" uses\n# because OpenOCD internals are still strongly biased\n# to JTAG ....  but for SWD, \"irlen\" etc are ignored,\n# and the internals work differently\n\n# for now, ignore non-JTAG and non-SWD transports\n# (e.g. initial flash programming via SPI or UART)\n\n# split out \"chip\" and \"tag\" so we can someday handle\n# them more uniformly irlen too...)\n\nif [catch {transport select}] {\n  echo \"Error: unable to select a session transport. Can't continue.\"\n  shutdown\n}\n\nproc swj_newdap {chip tag args} {\n if [using_jtag] {\n     eval jtag newtap $chip $tag $args\n } elseif [using_swd] {\n     eval swd newdap $chip $tag $args\n } else {\n     echo \"Error: transport '[ transport select ]' not supported by swj_newdap\"\n     shutdown\n }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/swm050.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Synwit SWM050\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME swm050\n}\nset _CHIPSERIES swm050\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x400\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x0bb11477\n}\n\nswj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME swm050 0x0 0x2000 0 0 $_TARGETNAME\n\nadapter speed 1000\n\n$_TARGETNAME configure -event reset-init {\n\t# Stop the watchdog, just to be safe\n\tmww 0x40019000 0x00\n\t# Set clock divider value to 1\n\tmww 0x400F0000 0x01\n\t# Set system clock to 18Mhz\n\tmww 0x400F0008 0x00\n}\n\n# SWM050 (Cortex-M0 core) supports SYSRESETREQ\nif {![using_hla]} {\n    # if srst is not fitted use SYSRESETREQ to\n    # perform a soft reset\n    cortex_m reset_config sysresetreq\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/test_reset_syntax_error.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Test script to check that syntax error in reset\n# script is reported properly.\n\n# at91eb40a target\n\n#jtag scan chain\nset _CHIPNAME syntaxtest\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf\n\n#target configuration\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME\n\n$_TARGETNAME configure -event reset-init {\n\n\tsyntax error\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/test_syntax_error.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# This script tests a syntax error in the startup\n# config script\n\nsyntax error here\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti-ar7.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments AR7 SOC - used in many adsl modems.\n# http://www.linux-mips.org/wiki/AR7\n#\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME ti-ar7\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n    set _CPUTAPID $CPUTAPID\n} else {\n    set _CPUTAPID 0x0000100f\n}\n\njtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position $_CHIPNAME.cpu\n\n# use onboard 4k sram as working area\n$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 0x00001000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti-cjtag.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# A start sequence to change from cJTAG to 4-pin JTAG\n# This is needed for CC2538 and CC26xx to be able to communicate through JTAG\n# Read section 6.3 in http://www.ti.com/lit/pdf/swru319 for more information.\nproc ti_cjtag_to_4pin_jtag {jrc} {\n\t# Bypass\n\truntest 20\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\t# Two zero bit scans and a one bit drshift\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# A two bit drhift and a 9 bit drshift\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRSHIFT DREXIT1 DRPAUSE\n\tpathmove DRPAUSE DREXIT2 DRUPDATE RUN/IDLE\n\tpathmove RUN/IDLE DRSELECT DRCAPTURE DREXIT1 DRPAUSE\n\n\t# Bypass\n\tirscan $jrc 0x3f -endstate RUN/IDLE\n\n\t# Set ICEPick IDCODE in data register\n\tirscan $jrc 0x04 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_calypso.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# TI Calypso (lite) G2 C035 Digital Base Band chip\n#\n# ARM7TDMIE + DSP subchip (S28C128)\n#\n# 512K SRAM Calypso\n# 256K SRAM Calypso lite\n#\nif { [info exists CHIPNAME] } {\n\tset  _CHIPNAME $CHIPNAME\n} else {\n\tset  _CHIPNAME calypso\n}\n\nif { [info exists ENDIAN] } {\n\tset  _ENDIAN $ENDIAN\n} else {\n\tset  _ENDIAN little\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x3100e02f\n}\n\n# Work-area is a space in RAM used for flash programming\n# By default use 64kB\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x10000\n}\n\nadapter speed 1000\n\nreset_config trst_and_srst\n\njtag newtap $_CHIPNAME dsp -expected-id 0x00000000 -irlen 8\njtag newtap $_CHIPNAME arm -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n# target\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm7tdmi -endian little -chain-position $_TARGETNAME\n\n# workarea\n\n$_TARGETNAME configure -work-area-phys 0x00800000 -work-area-size $_WORKAREASIZE -work-area-backup 1\n\narm7_9 dcc_downloads enable\narm7_9 fast_memory_access enable\n\n$_TARGETNAME configure -event examine-start {\n\tirscan calypso.arm 0x0b -endstate DRPAUSE\n\tdrscan calypso.arm 2 2 -endstate RUN/IDLE\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc13x0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC13x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x0\nset JRC_TAPID 0x0B9BE02F\nset WORKAREASIZE 0x4000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc13x2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC13x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc13x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc26x0.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC26x0 - ARM Cortex-M3\n#\n# http://www.ti.com\n#\n\nsource [find target/icepick.cfg]\nsource [find target/ti-cjtag.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc26x0\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tset _DAP_TAPID 0x4BA00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B99A02F\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n# A start sequence is needed to change from 2-pin cJTAG to 4-pin JTAG\njtag configure $_CHIPNAME.jrc -event post-reset \"ti_cjtag_to_4pin_jtag $_CHIPNAME.jrc\"\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc26xx 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config vectreset\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc26x2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC26x2 - ARM Cortex-M4\n#\n# http://www.ti.com\n#\n\nset CHIPNAME cc26x2\nset JRC_TAPID 0x0BB4102F\nset WORKAREASIZE 0x7000\n\nsource [find target/ti_cc26x0.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc3220sf.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC3220SF - ARM Cortex-M4\n#\n# http://www.ti.com/CC3220SF\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\nsource [find target/ti_cc32xx.cfg]\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME cc3220sf 0 0 0 0 $_TARGETNAME\n\n#\n# On CC32xx family of devices, sysreqreset is disabled, and vectreset is\n# blocked by the boot loader (stops in a while(1) statement). srst reset can\n# leave the target in a state that prevents debug. The following uses the\n# soft_reset_halt command to reset and halt the target. Then the PC and stack\n# are initialized from internal flash. This allows for a more reliable reset,\n# but with two caveats: it only works for the SF variant that has internal\n# flash, and it only resets the CPU and not any peripherals.\n#\n\nproc ocd_process_reset_inner { MODE } {\n\n\tsoft_reset_halt\n\n\t# Initialize MSP, PSP, and PC from vector table at flash 0x01000800\n\tset boot [read_memory 0x01000800 32 2]\n\n\treg msp [lindex $boot 0]\n\treg psp [lindex $boot 0]\n\treg pc [lindex $boot 1]\n\n\tif { 0 == [string compare $MODE run ] } {\n\t\tresume\n\t}\n\n\tcc32xx.cpu invoke-event reset-end\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_cc32xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments CC32xx - ARM Cortex-M4\n#\n# http://www.ti.com/product/CC3200\n# http://www.ti.com/product/CC3220\n#\n\nsource [find target/swj-dp.tcl]\nsource [find target/icepick.cfg]\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME cc32xx\n}\n\n#\n# Main DAP\n#\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n} else {\n\tif {[using_jtag]} {\n\t\tset _DAP_TAPID 0x4BA00477\n\t} else {\n\t\tset _DAP_TAPID 0x2BA01477\n\t}\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable\n\tjtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n} else {\n\tswj_newdap $_CHIPNAME cpu -expected-id $_DAP_TAPID\n}\n\n#\n# ICEpick-C (JTAG route controller)\n#\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n} else {\n\tset _JRC_TAPID 0x0B97C02F\n}\n\nif {[using_jtag]} {\n\tjtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f -expected-id $_JRC_TAPID -ignore-version\n\tjtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\n}\n\nset _TARGETNAME $_CHIPNAME.cpu\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x2000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_dm355.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments DaVinci family: TMS320DM355\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm355\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n#\n# Also note: when running without RTCK before the PLLs are set up, you\n# may need to slow the JTAG clock down quite a lot (under 2 MHz).\n#\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b73b02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm355\nset dm355 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm355 sram0\t\t0x00010000\ndict set dm355 sram1\t\t0x00014000\ndict set dm355 sysbase\t\t0x01c40000\ndict set dm355 pllc1\t\t0x01c40800\ndict set dm355 pllc2\t\t0x01c40c00\ndict set dm355 psc\t\t0x01c41000\ndict set dm355 gpio\t\t0x01c67000\ndict set dm355 a_emif\t\t0x01e10000\ndict set dm355 a_emif_cs0\t0x02000000\ndict set dm355 a_emif_cs1\t0x04000000\ndict set dm355 ddr_emif\t\t0x20000000\ndict set dm355 ddr\t\t0x80000000\ndict set dm355 uart0\t\t0x01c20000\ndict set dm355 uart1\t\t0x01c20400\ndict set dm355 uart2\t\t0x01e06000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm355 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 24 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_dm365.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments DaVinci family: TMS320DM365\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm365\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x0792602f\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b83e02f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n\n# various symbol definitions, to avoid hard-wiring addresses\n# and enable some sharing of DaVinci-family utility code\nglobal dm365\nset dm365 [ dict create ]\n\n# Physical addresses for controllers and memory\n# (Some of these are valid for many DaVinci family chips)\ndict set dm365 sram0\t\t0x00010000\ndict set dm365 sram1\t\t0x00014000\ndict set dm365 sysbase\t\t0x01c40000\ndict set dm365 pllc1\t\t0x01c40800\ndict set dm365 pllc2\t\t0x01c40c00\ndict set dm365 psc\t\t0x01c41000\ndict set dm365 gpio\t\t0x01c67000\ndict set dm365 a_emif\t\t0x01d10000\ndict set dm365 a_emif_cs0\t0x02000000\ndict set dm365 a_emif_cs1\t0x04000000\ndict set dm365 ddr_emif\t\t0x20000000\ndict set dm365 ddr\t\t0x80000000\n\nsource [find target/davinci.cfg]\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 16K)\n# and the ETB memory (4K) are other options, while trace is unused.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n\n# NOTE that work-area-virt presumes a Linux 2.6.30-rc2+ kernel,\n# and that the work area is used only with a kernel mmu context ...\n$_TARGETNAME configure \\\n\t-work-area-virt [expr {0xfffe0000 + 0x4000}] \\\n\t-work-area-phys [dict get $dm365 sram1] \\\n\t-work-area-size 0x4000 \\\n\t-work-area-backup 0\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 19.2 MHz (best case: 36 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_dm6446.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments DaVinci family: TMS320DM6446\n#\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME dm6446\n}\n\n# TI boards default to EMU0/EMU1 *high* -- ARM and ETB are *disabled*\n# after JTAG reset until ICEpick is used to route them in.\nset EMU01 \"-disable\"\n\n# With EMU0/EMU1 jumpered *low* ARM and ETB are *enabled* without\n# needing any ICEpick interaction.\n#set EMU01 \"-enable\"\n\nsource [find target/icepick.cfg]\n\n# Subsidiary TAP: unknown ... must enable via ICEpick\njtag newtap $_CHIPNAME unknown -irlen 8 -disable\njtag configure $_CHIPNAME.unknown -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 3\"\n\n# Subsidiary TAP: C64x+ DSP ... must enable via ICEpick\njtag newtap $_CHIPNAME dsp -irlen 38 -ircapture 0x25 -irmask 0x3f -disable\njtag configure $_CHIPNAME.dsp -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 2\"\n\n# Subsidiary TAP: ARM ETB11, with scan chain for 4K of ETM trace buffer\nif { [info exists ETB_TAPID] } {\n   set _ETB_TAPID $ETB_TAPID\n} else {\n   set _ETB_TAPID 0x2b900f0f\n}\njtag newtap $_CHIPNAME etb -irlen 4 -irmask 0xf -expected-id $_ETB_TAPID $EMU01\njtag configure $_CHIPNAME.etb -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 1\"\n\n# Subsidiary TAP: ARM926ejs with scan chains for ARM Debug, EmbeddedICE-RT, ETM.\nif { [info exists CPU_TAPID] } {\n   set _CPU_TAPID $CPU_TAPID\n} else {\n   set _CPU_TAPID 0x07926001\n}\njtag newtap $_CHIPNAME arm -irlen 4 -irmask 0xf -expected-id $_CPU_TAPID $EMU01\njtag configure $_CHIPNAME.arm -event tap-enable \\\n\t\"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# Primary TAP: ICEpick-C (JTAG route controller) and boundary scan\nif { [info exists JRC_TAPID] } {\n   set _JRC_TAPID $JRC_TAPID\n} else {\n   set _JRC_TAPID 0x0b70002f\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -irmask 0x3f -expected-id $_JRC_TAPID\n\njtag configure $_CHIPNAME.jrc -event setup \\\n\t\"jtag tapenable $_CHIPNAME.etb; jtag tapenable $_CHIPNAME.arm\"\n\n################\n# GDB target: the ARM, using SRAM1 for scratch.  SRAM0 (also 8K)\n# and the ETB memory (4K) are other options, while trace is unused.\n# Little-endian; use the OpenOCD default.\nset _TARGETNAME $_CHIPNAME.arm\n\ntarget create $_TARGETNAME arm926ejs -chain-position $_TARGETNAME\n$_TARGETNAME configure -work-area-phys 0x0000a000 -work-area-size 0x2000\n\n# be absolutely certain the JTAG clock will work with the worst-case\n# CLKIN = 20 MHz (best case: 30 MHz) even when no bootloader turns\n# on the PLL and starts using it.  OK to speed up after clock setup.\nadapter speed 1500\n$_TARGETNAME configure -event \"reset-start\" { adapter speed 1500 }\n\narm7_9 fast_memory_access enable\narm7_9 dcc_downloads enable\n\n# trace setup\netm config $_TARGETNAME 16 normal full etb\netb config $_TARGETNAME $_CHIPNAME.etb\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_k3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Copyright (C) 2019-2021 Texas Instruments Incorporated - http://www.ti.com/\n#\n# Texas Instruments K3 devices:\n# * AM654x: https://www.ti.com/lit/pdf/spruid7\n#  Has 4 ARMV8 Cores and 2 R5 Cores and an M3\n# * J721E: https://www.ti.com/lit/pdf/spruil1\n#  Has 2 ARMV8 Cores and 6 R5 Cores and an M3\n# * J7200: https://www.ti.com/lit/pdf/spruiu1\n#  Has 2 ARMV8 Cores and 4 R5 Cores and an M3\n# * AM642: https://www.ti.com/lit/pdf/spruim2\n#  Has 2 ARMV8 Cores and 4 R5 Cores, M4F and an M3\n#\n\nsource [find target/swj-dp.tcl]\n\nif { [info exists SOC] } {\n\tset _soc $SOC\n} else {\n\tset _soc am654\n}\n\n# set V8_SMP_DEBUG to non 0 value in board if you'd like to use SMP debug\nif { [info exists V8_SMP_DEBUG] } {\n\tset _v8_smp_debug $V8_SMP_DEBUG\n} else {\n\tset _v8_smp_debug 0\n}\n\n# Common Definitions\n\n# System Controller is the very first processor - all current SoCs have it.\nset CM3_CTIBASE\t\t{0x3C016000}\n\n# sysctrl power-ap unlock offsets\nset _sysctrl_ap_unlock_offsets {0xf0 0x44}\n\n# All the ARMV8s are the next processors.\n#\t\t   CL0,CORE0  CL0,CORE1  CL1,CORE0  CL1,CORE1\nset ARMV8_DBGBASE {0x90410000 0x90510000 0x90810000 0x90910000}\nset ARMV8_CTIBASE {0x90420000 0x90520000 0x90820000 0x90920000}\n\n# And we add up the R5s\n#\t\t(0)MCU 0   (1)MCU 1   (2)MAIN_0_0 (3)MAIN_0_1 (4)MAIN_1_0 (5)MAIN_1_1\nset R5_DBGBASE {0x9d010000 0x9d012000 0x9d410000 0x9d412000 0x9d510000 0x9d512000}\nset R5_CTIBASE {0x9d018000 0x9d019000 0x9d418000 0x9d419000 0x9d518000 0x9d519000}\nset R5_NAMES {mcu_r5.0 mcu_r5.1 main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\n# Finally an General Purpose(GP) MCU\nset CM4_CTIBASE\t\t{0x20001000}\n\n# General Purpose MCU (M4) may be present on some very few SoCs\nset _gp_mcu_cores 0\n# General Purpose MCU power-ap unlock offsets\nset _gp_mcu_ap_unlock_offsets {0xf0 0x60}\n\n# Set configuration overrides for each SOC\nswitch $_soc {\n\tam654 {\n\t\tset _CHIPNAME am654\n\t\tset _K3_DAP_TAPID 0x0bb5a02f\n\n\t\t# AM654 has 2 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\n\t\t# AM654 has 1 cluster of 2 R5s cores.\n\t\tset _r5_cores 2\n\t\tset R5_NAMES {mcu_r5.0 mcu_r5.1}\n\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x50}\n\t}\n\tam642 {\n\t\tset _CHIPNAME am642\n\t\tset _K3_DAP_TAPID 0x0bb3802f\n\n\t\t# AM642 has 1 clusters of 2 A53 cores each.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 2\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000}\n\n\t\t# AM642 has 2 cluster of 2 R5s cores.\n\t\tset _r5_cores 4\n\t\tset R5_NAMES {main0_r5.0 main0_r5.1 main1_r5.0 main1_r5.1}\n\t\tset R5_DBGBASE {0x9d410000 0x9d412000 0x9d510000 0x9d512000}\n\t\tset R5_CTIBASE {0x9d418000 0x9d419000 0x9d518000 0x9d519000}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t}\n\tam625 {\n\t\tset _CHIPNAME am625\n\t\tset _K3_DAP_TAPID 0x0bb7e02f\n\n\t\t# AM625 has 1 clusters of 4 A53 cores.\n\t\tset _armv8_cpu_name a53\n\t\tset _armv8_cores 4\n\t\tset ARMV8_DBGBASE {0x90010000 0x90110000 0x90210000 0x90310000}\n\t\tset ARMV8_CTIBASE {0x90020000 0x90120000 0x90220000 0x90320000}\n\n\t\t# AM625 has 1 cluster of 1 R5s core.\n\t\tset _r5_cores 1\n\t\tset R5_NAMES {main0_r5.0}\n\t\tset R5_DBGBASE {0x9d410000}\n\t\tset R5_CTIBASE {0x9d418000}\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tj721e {\n\t\tset _CHIPNAME j721e\n\t\tset _K3_DAP_TAPID 0x0bb6402f\n\t\t# J721E has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721E has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\t}\n\tj7200 {\n\t\tset _CHIPNAME j7200\n\t\tset _K3_DAP_TAPID 0x0bb6d02f\n\n\t\t# J7200 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J7200 has 2 clusters of 2 R5 cores each.\n\t\tset _r5_cores 4\n\t\tset R5_DBGBASE {0x9d010000 0x9d012000 0x9d110000 0x9d112000}\n\t\tset R5_CTIBASE {0x9d018000 0x9d019000 0x9d118000 0x9d119000}\n\n\t\t# M3 CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t}\n\tj721s2 {\n\t\tset _CHIPNAME j721s2\n\t\tset _K3_DAP_TAPID 0x0bb7502f\n\n\t\t# J721s2 has 1 cluster of 2 A72 cores.\n\t\tset _armv8_cpu_name a72\n\t\tset _armv8_cores 2\n\n\t\t# J721s2 has 3 clusters of 2 R5 cores each.\n\t\tset _r5_cores 6\n\n\t\t# sysctrl CTI base\n\t\tset CM3_CTIBASE {0x20001000}\n\t\t# Sysctrl power-ap unlock offsets\n\t\tset _sysctrl_ap_unlock_offsets {0xf0 0x78}\n\n\t\t# M4 processor\n\t\tset _gp_mcu_cores 1\n\t\tset _gp_mcu_ap_unlock_offsets {0xf0 0x7c}\n\t}\n\tdefault {\n\t\techo \"'$_soc' is invalid!\"\n\t}\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_K3_DAP_TAPID -ignore-version\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\n\nset _CTINAME $_CHIPNAME.cti\n\n# sysctrl is always present\ncti create $_CTINAME.sysctrl -dap $_CHIPNAME.dap -ap-num 7 -baseaddr [lindex $CM3_CTIBASE 0]\ntarget create $_TARGETNAME.sysctrl cortex_m -dap $_CHIPNAME.dap -ap-num 7 -defer-examine\n$_TARGETNAME.sysctrl configure -event reset-assert { }\n\nproc sysctrl_up {} {\n\t# To access sysctrl, we need to enable the JTAG access for the same.\n\t# Ensure Power-AP unlocked\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 0] 0x00190000\n\t$::_CHIPNAME.dap apreg 3 [lindex $::_sysctrl_ap_unlock_offsets 1] 0x00102098\n\n\t$::_TARGETNAME.sysctrl arp_examine\n}\n\n$_TARGETNAME.sysctrl configure -event gdb-attach {\n\tsysctrl_up\n\t# gdb-attach default rule\n\thalt 1000\n}\n\nproc _cpu_no_smp_up {} {\n\tset _current_target [target current]\n\tset _current_type [$_current_target cget -type]\n\n\t$_current_target arp_examine\n\t$_current_target $_current_type dbginit\n}\n\nproc _armv8_smp_up {} {\n\tfor { set _core 0 } { $_core < $::_armv8_cores } { incr _core } {\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core arp_examine\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 dbginit\n\t\t$::_TARGETNAME.$::_armv8_cpu_name.$_core aarch64 smp on\n\t}\n\t# Set Default target as core 0\n\ttargets $::_TARGETNAME.$::_armv8_cpu_name.0\n}\n\nset _v8_smp_targets \"\"\n\nfor { set _core 0 } { $_core < $_armv8_cores } { incr _core } {\n\n\tcti create $_CTINAME.$_armv8_cpu_name.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $ARMV8_CTIBASE $_core]\n\n\ttarget create $_TARGETNAME.$_armv8_cpu_name.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $ARMV8_DBGBASE $_core] -cti $_CTINAME.$_armv8_cpu_name.$_core -defer-examine\n\n\tset _v8_smp_targets \"$_v8_smp_targets $_TARGETNAME.$_armv8_cpu_name.$_core\"\n\n\tif { $_v8_smp_debug == 0 } {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_cpu_no_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t} else {\n\t\t$_TARGETNAME.$_armv8_cpu_name.$_core configure -event gdb-attach {\n\t\t\t_armv8_smp_up\n\t\t\t# gdb-attach default rule\n\t\t\thalt 1000\n\t\t}\n\t}\n}\n\n# Setup ARMV8 proc commands based on CPU to prevent people confusing SoCs\nset _armv8_up_cmd \"$_armv8_cpu_name\"_up\n# Available if V8_SMP_DEBUG is set to non-zero value\nset _armv8_smp_cmd \"$_armv8_cpu_name\"_smp\n\nif { $_v8_smp_debug == 0 } {\n\tproc $_armv8_up_cmd { args } {\n\t\tforeach _core $args {\n\t\t\ttargets $_core\n\t\t\t_cpu_no_smp_up\n\t\t}\n\t}\n} else {\n\tproc $_armv8_smp_cmd { args } {\n\t\t_armv8_smp_up\n\t}\n\t# Declare SMP\n\ttarget smp $:::_v8_smp_targets\n}\n\nfor { set _core 0 } { $_core < $_r5_cores } { incr _core } {\n\tset _r5_name [lindex $R5_NAMES $_core]\n\tcti create $_CTINAME.$_r5_name -dap $_CHIPNAME.dap -ap-num 1 \\\n\t\t-baseaddr [lindex $R5_CTIBASE $_core]\n\n\t# inactive core examination will fail - wait till startup of additional core\n\ttarget create $_TARGETNAME.$_r5_name cortex_r4 -dap $_CHIPNAME.dap \\\n\t\t-dbgbase [lindex $R5_DBGBASE $_core] -ap-num 1 -defer-examine\n\n\t$_TARGETNAME.$_r5_name configure -event gdb-attach {\n\t\t_cpu_no_smp_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n\nproc r5_up { args } {\n\tforeach  _core $args {\n\t\ttargets $_core\n\t\t_cpu_no_smp_up\n\t}\n}\n\nif { $_gp_mcu_cores != 0 } {\n\tcti create $_CTINAME.gp_mcu -dap $_CHIPNAME.dap -ap-num 8 -baseaddr [lindex $CM4_CTIBASE 0]\n\ttarget create $_TARGETNAME.gp_mcu cortex_m -dap $_CHIPNAME.dap -ap-num 8 -defer-examine\n\t$_TARGETNAME.gp_mcu configure -event reset-assert { }\n\n\tproc gp_mcu_up {} {\n\t\t# To access GP MCU, we need to enable the JTAG access for the same.\n\t\t# Ensure Power-AP unlocked\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 0] 0x00190000\n\t\t$::_CHIPNAME.dap apreg 3 [lindex $::_gp_mcu_ap_unlock_offsets 1] 0x00102098\n\n\t\t$::_TARGETNAME.gp_mcu arp_examine\n\t}\n\n\t$_TARGETNAME.gp_mcu configure -event gdb-attach {\n\t\tgp_mcu_up\n\t\t# gdb-attach default rule\n\t\thalt 1000\n\t}\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_msp432.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Texas Instruments MSP432 - ARM Cortex-M4F @ up to 48 MHz\n#\n# http://www.ti.com/MSP432\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME msp432\n}\n\nif { [info exists CPUTAPID] } {\n\tset _DAP_TAPID $CPUTAPID\n} else {\n\tset _DAP_TAPID 0x4ba00477\n}\n\nif { [info exists DAP_SWD_ID] } {\n\tset _DAP_SWD_ID $DAP_SWD_ID\n} else {\n\tset _DAP_SWD_ID 0x2ba01477\n}\n\nsource [find target/swj-dp.tcl]\n\nif { [using_jtag] } {\n\tset _DAP_ID $_DAP_TAPID\n} else {\n\tset _DAP_ID $_DAP_SWD_ID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_DAP_ID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n\tset _WORKAREASIZE $WORKAREASIZE\n} else {\n\tset _WORKAREASIZE 0x4000\n}\n\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME msp432 0 0 0 0 $_TARGETNAME\n\ncortex_m reset_config sysresetreq\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_rm4x.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_tms570.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter speed 1500\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME tms570\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n\tset _ENDIAN big\n}\n\n# TMS570 has an ICEpick-C on which we need the router commands.\nsource [find target/icepick.cfg]\n\n# Main DAP\n# DAP_TAPID should be set before source-ing this file\nif { [info exists DAP_TAPID] } {\n\tset _DAP_TAPID $DAP_TAPID\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -disable -ignore-version\njtag configure $_CHIPNAME.cpu -event tap-enable \"icepick_c_tapenable $_CHIPNAME.jrc 0\"\n\n# ICEpick-C (JTAG route controller)\n# JRC_TAPID should be set before source-ing this file\nif { [info exists JRC_TAPID] } {\n\tset _JRC_TAPID $JRC_TAPID\n}\n\nset _JRC_TAPID2 0x0B7B302F\nset _JRC_TAPID3 0x0B95502F\nset _JRC_TAPID4 0x0B97102F\nset _JRC_TAPID5 0x0D8A002F\nset _JRC_TAPID6 0x0B8A002F\n\n\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x1 -irmask 0x3f \\\n\t-expected-id $_JRC_TAPID \\\n\t-expected-id $_JRC_TAPID2 \\\n\t-expected-id $_JRC_TAPID3 \\\n\t-expected-id $_JRC_TAPID4 \\\n\t-expected-id $_JRC_TAPID5 \\\n\t-expected-id $_JRC_TAPID6 \\\n\t-ignore-version\njtag configure $_CHIPNAME.jrc -event setup \"jtag tapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.jrc -event post-reset \"runtest 100\"\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n# Cortex-R4 target\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_r4 -endian $_ENDIAN \\\n\t-dap $_CHIPNAME.dap -coreid 0 -dbgbase 0x80001000\n\n# TMS570 uses quirky BE-32 mode\n$_CHIPNAME.dap ti_be_32_quirks 1\n\n$_TARGETNAME configure -event \"reset-assert\" {\n\tglobal _CHIPNAME\n\n\t# assert warm system reset through ICEPick\n\ticepick_c_wreset $_CHIPNAME.jrc\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_tms570lc43xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nset DAP_TAPID 0x0B95A02F\nset JRC_TAPID 0x0B95A02F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_tms570ls20xxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TMS570LS20216, TMS570LS20206, TMS570LS10216\n# TMS570LS10206, TMS570LS10116, TMS570LS10106\nset DAP_TAPID 0x0B7B302F\nset JRC_TAPID 0x0B7B302F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/ti_tms570ls3137.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# TMS570LS3137\nset DAP_TAPID 0x0B8A002F\nset JRC_TAPID 0x0B8A002F\n\nsource [find target/ti_tms570.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/tmpa900.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Toshiba TMPA900\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa900\n}\n\n# Toshiba TMPA900 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA900 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (8kB): 0xf8008000\n\n# Use internal RAM-0 and RAM-1 as working area (24kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0x6000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/tmpa910.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n######################################\n# Target:    Toshiba TMPA910\n######################################\n\nif { [info exists CHIPNAME] } {\n   set _CHIPNAME $CHIPNAME\n} else {\n   set _CHIPNAME tmpa910\n}\n\n# Toshiba TMPA910 series MCUs are always little endian as per datasheet.\nset _ENDIAN little\n\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n   set _CPUTAPID 0x07926031\n}\n\n#TMPA910 has following IDs:\n# CP15.0 register 0x41069265\n# CP15.1 register 0x1d152152\n# ARM core 0x07926031\n\n\n#\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\nadapter srst delay 20\njtag_ntrst_delay 20\n\n######################\n# Target configuration\n######################\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME arm926ejs -endian $_ENDIAN -chain-position $_TARGETNAME\n\n# Internal RAM-0 (16kB): 0xf8004000\n# Internal RAM-1 (16kB): 0xf8008000\n# Internal RAM-2 (16kB): 0xf800c000\n\n# Use internal RAM-0, RAM-1, and RAM-2 as working area (48kB total).\n$_TARGETNAME configure -work-area-phys 0xf8004000 -work-area-size 0xc000 \\\n-work-area-backup 0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/tnetc4401.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Texas Instruments (TI) TNETC4401, MIPS32 DOCSIS-tailored SoC (4Kc-based)\n# Used in Knovative KC-100 and Motorola Surfboard SB5120 cable modems.\n# Datasheet: https://brezn.muc.ccc.de/~mazzoo/DOCSIS/tnetc4401.pdf\ntransport select jtag\nset _TARGETNAME tnetc4401\nset _CPUTAPID 0x0000100f\njtag newtap $_TARGETNAME tap -irlen 5 -ircapture 0x01 -irmask 0x1f -expected-id $_CPUTAPID\ntarget create $_TARGETNAME mips_m4k -chain-position $_TARGETNAME.tap -endian big\n\n# May need to halt manually before calling reset init\n$_TARGETNAME configure -event reset-init {\n\thalt\n\techo \"Attempting to disable watchdog...\"\n\tmwb phys 0xa8610b00 0 256\n\thalt\n\twait_halt\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/u8500.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#  Copyright (C) ST-Ericsson SA 2011\n#  Author : michel.jaouen@stericsson.com\n#  U8500 target\n\nproc mmu_off {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp & ~1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc mmu_on {} {\n\tset cp [arm mrc 15 0 1 0 0]\n\tset cp [expr {$cp | 1}]\n\tarm mcr 15 0 1 0 0 $cp\n}\n\nproc ocd_gdb_restart {target_id} {\n    global _TARGETNAME_1\n\tglobal _SMP\n    targets $_TARGETNAME_1\n\tif { $_SMP == 1 } {\n\tcortex_a smp off\n\t}\n\trst_run\n\thalt\n\tif { $_SMP == 1 } {\n\tcortex_a smp on\n\t}\n}\n\nproc smp_reg {} {\n\tglobal _TARGETNAME_1\n    global _TARGETNAME_2\n    targets $_TARGETNAME_1\n\techo \"$_TARGETNAME_1\"\n\tset pc1 [reg pc]\n\tset stck1 [reg sp_svc]\n\ttargets $_TARGETNAME_2\n\techo \"$_TARGETNAME_1\"\n\tset pc2 [reg pc]\n\tset stck2 [reg sp_svc]\n}\n\n\nproc u8500_tapenable {chip val} {\n\techo \"JTAG tap enable $chip\"\n}\n\n\nproc pwrsts { } {\n\tglobal _CHIPNAME\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\techo \"pwrsts =\"$pwrsts\n\tset a9 [expr \"0x$pwrsts & 0xc\"]\n\tset ape [expr \"0x$pwrsts & 0x3\"]\n\tif {[string equal \"0\" $ape]} {\n\t\techo \"ape off\"\n\t} else {\n\t\techo \"ape on\"\n\t}\n\techo \"$a9\"\n\tswitch $a9 {\n\t\t4 {\n\t\t\techo \"A9 in retention\"\n\t\t  }\n\t\t8 {\n\t\t\techo \"A9 100% DVFS\"\n\t\t  }\n\t\tc {\n\t\t\techo \"A9 50% DVFS\"\n\t\t}\n\t}\n}\n\nproc poll_pwrsts { } {\n\tglobal _CHIPNAME\n\tset result 1\n\tset i 0\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 0\n\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\twhile {[string equal \"4\" $pwrsts] && $i<20} {\n\t\tirscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 0;\n\t\tset pwrsts [drscan $_CHIPNAME.jrc 16 0]\n\t\tset pwrsts [expr \"0x$pwrsts & 0xc\"]\n\t\tif {![string equal \"4\" $pwrsts]} {\n\t\t\tset result 1\n\t\t} else {\n\t\t\tset result 0\n\t\t\tsleep 200\n\t\t\techo \"loop $i\"\n\t\t}\n\t\tincr i\n\t}\n\treturn $result\n}\n\nproc halt_ { } {\n\tif {[poll_pwrsts]==1} {\n\t\thalt\n\t} else {\n\t\techo \"halt failed : target in retention\"\n\t}\n}\n\n\nproc u8500_dapenable {chip} {\n}\n\nproc u8500_tapdisable {chip val} {\n\techo \"JTAG tap disable $chip\"\n}\n\n\nproc enable_apetap {} {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n    global _TARGETNAME_1\n\tpoll off\n\tirscan $_CHIPNAME.jrc 0x3e\n\tdrscan $_CHIPNAME.jrc 8 0xcf\n\tjtag tapenable $_CHIPNAME.dap\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tirscan $_CHIPNAME.jrc 0x6\n\tdrscan $_CHIPNAME.jrc 32 0\n\tset status [$_TARGETNAME_1 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_1 arp_examine\n\tcache_config l2x 0xa0412000 8\n\t}\n\n\tset status [$_TARGETNAME_2 curstate]\n    if {[string equal \"unknown\" $status]} {\n\t$_TARGETNAME_2 arp_examine\n\t}\n\t}\n\ntcl_port 5555\ntelnet_port 4444\ngdb_port 3333\n\nif { [info exists CHIPNAME] } {\nglobal _CHIPNAME\n    set _CHIPNAME $CHIPNAME\n} else {\nglobal _CHIPNAME\n\tset _CHIPNAME u8500\n}\n\nif { [info exists ENDIAN] } {\n\tset _ENDIAN $ENDIAN\n} else {\n # this defaults to a bigendian\n\tset _ENDIAN little\n}\n\n\n\n# Subsidiary TAP: APE with scan chains for ARM Debug, EmbeddedICE-RT,\nif { [info exists CPUTAPID] } {\n   set _CPUTAPID $CPUTAPID\n} else {\n\tset _CPUTAPID 0x4ba00477\n}\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0xe -irmask 0xf -expected-id $_CPUTAPID -disable\njtag configure $_CHIPNAME.cpu -event tap-enable \\\n\t\"u8500_dapenable $_CHIPNAME.cpu\"\njtag configure $_CHIPNAME.cpu -event tap-disable \\\n\t\"u8500_tapdisable $_CHIPNAME.cpu 0xc0\"\n\n\n#CLTAPC TAP JRC equivalent\nif { [info exists CLTAPC_ID] } {\n   set _CLTAPC_ID $CLTAPC_ID\n} else {\n   set _CLTAPC_ID 0x22286041\n}\njtag newtap $_CHIPNAME jrc -irlen 6 -ircapture 0x6 -irmask 0xf -expected-id $_CLTAPC_ID -ignore-version\n\n\nif { ![info exists TARGETNAME_1] } {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $_CHIPNAME.cpu1\n} else {\nglobal _TARGETNAME_1\nset _TARGETNAME_1 $TARGETNAME_1\n}\n\nif { [info exists DAP_DBG1] } {\n\tset _DAP_DBG1 $DAP_DBG1\n} else {\n\tset _DAP_DBG1 0x801A8000\n}\nif { [info exists DAP_DBG2] } {\n\tset _DAP_DBG2 $DAP_DBG2\n} else {\n\tset _DAP_DBG2 0x801AA000\n}\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME_1 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG1 -coreid 0 -rtos linux\n\n\nif { ![info exists TARGETNAME_2] } {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $_CHIPNAME.cpu2\n} else {\nglobal _TARGETNAME_2\nset _TARGETNAME_2 $TARGETNAME_2\n}\n\ntarget create $_TARGETNAME_2 cortex_a -dap $_CHIPNAME.dap -dbgbase $_DAP_DBG2 -coreid 1 -rtos linux\n\n\nif {![info exists SMP]} {\nglobal _SMP\nset _SMP 1\n} else {\nglobal _SMP\nset _SMP $SMP\n}\nglobal SMP\nif { $_SMP == 1} {\ntarget smp $_CHIPNAME.cpu2 $_CHIPNAME.cpu1\n}\n\n\n\n\nproc secsts1 { } {\n\tglobal _CHIPNAME\n        irscan $_CHIPNAME.jrc 0x3a\n\t\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {![string equal \"4\" $secsts1]} {\n\techo \"APE target secured\"\n        } else {\n        echo \"APE target not secured\"\n        }\n}\n\nproc att { } {\n\tglobal _CHIPNAME\n\tjtag arp_init\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\tif {[string equal \"4\" $secsts1]} {\n\t\tif {[poll_pwrsts]==1} {\n\t\tenable_apetap\n                } else {\n\t\techo \"target in retention\"\n\t\t}\n\t} else {\n\t\techo \"target secured\"\n\t}\n\n}\n\n\n\nproc rst_run { } {\n\tglobal _CHIPNAME\n\tglobal _TARGETNAME_2\n\tglobal _TARGETNAME_1\n\tset status [$_TARGETNAME_1 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_1\n\t}\n    set status [$_TARGETNAME_2 curstate]\n\tif {[string equal \"halted\" $status]} {\n\tresume\n\ttargets $_TARGETNAME_2\n\t}\n   \tpoll off\n\tjtag arp_init\n\treset\n\tsleep 20\n\tirscan $_CHIPNAME.jrc 0x3a\n\tdrscan $_CHIPNAME.jrc 4 4\n\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\techo \"secsts1 =\"$secsts1\n\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\twhile {![string equal \"4\" $secsts1]} {\n\t\tirscan u8500.jrc 0x3a\n\t\tdrscan u8500.jrc 4 4\n\t\tset secsts1 [drscan $_CHIPNAME.jrc 16 0]\n\t\techo \"secsts1 =\"$secsts1\n\t\tset secsts1 [expr \"0x$secsts1 & 0x4\"]\n\t}\n\techo \"ape debugable\"\n\tenable_apetap\n\tpoll on\n\ttargets $_TARGETNAME_1\n\tdap apsel 1\n}\n\nif {![info exists MAXSPEED]} {\nglobal _MAXSPEED\nset _MAXSPEED 15000\n} else {\nglobal _MAXSPEED\nset _MAXSPEED $MAXSPEED\n}\nglobal _MAXSPEED\nadapter speed $_MAXSPEED\n\n\ngdb_breakpoint_override hard\nset mem inaccessible-by-default-off\n\njtag_ntrst_delay 100\nreset_config trst_and_srst combined\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/vd_aarch64.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# Arm v8 64b Cortex A\n\nif {![info exists _CORES]} {\n\tset _CORES 1\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME aarch64\n}\nset _TARGETNAME $_CHIPNAME.cpu\nset _CTINAME $_CHIPNAME.cti\n\nset DBGBASE {0x80810000 0x80910000}\nset CTIBASE {0x80820000 0x80920000}\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n$_CHIPNAME.dap apsel 1\n\nfor { set _core 0 } { $_core < $_CORES } { incr _core } \\\n{\n\tcti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 -baseaddr [lindex $CTIBASE $_core]\n\tset _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n\t-dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core -coreid $_core\"\n\tif { $_core != 0 } {\n\t\t# non-boot core examination may fail\n\t\tset _command \"$_command -defer-examine\"\n\t\tset _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n\t} else {\n\t\tset _smp_command \"target smp $_TARGETNAME.$_core\"\n\t}\n\teval $_command\n}\neval $_smp_command\n\n# default target is core 0\ntargets $_TARGETNAME.0\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/vd_cortex_m.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# ARM Cortex M\n\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME cortex_m\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ndap create $_CHIPNAME.dap -chain-position $_TARGETNAME\n\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/vd_riscv.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Cadence virtual debug interface\n# RISCV core\n\nif {![info exists _HARTID]} {\n\tset _HARTID 0x00\n}\nif {![info exists _CHIPNAME]} {\n\tset _CHIPNAME riscv\n}\nset _TARGETNAME $_CHIPNAME.cpu\n\ntarget create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid $_HARTID\n\nriscv set_reset_timeout_sec 120\nriscv set_command_timeout_sec 120\nriscv set_mem_access sysbus progbuf\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/vybrid_vf6xx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Freescale Vybrid VF610\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME vf610\n}\n\nif { [info exists A5_JTAG_TAPID] } {\n\tset _A5_JTAG_TAPID $A5_JTAG_TAPID\n} else {\n\tset _A5_JTAG_TAPID 0x4BA00477\n}\n\nif { [info exists A5_SWD_TAPID] } {\n\tset _A5_SWD_TAPID $A5_SWD_TAPID\n} else {\n\tset _A5_SWD_TAPID 0x3BA02477\n}\n\nif { [using_jtag] } {\n\tset _A5_TAPID $_A5_JTAG_TAPID\n} else {\n\tset _A5_TAPID $_A5_SWD_TAPID\n}\n\nsource [find target/swj-dp.tcl]\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_A5_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap -dbgbase 0xc0088000\ntarget create ${_TARGETNAME}1 cortex_m -dap $_CHIPNAME.dap -ap-num 3 -defer-examine\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xilinx_zynqmp.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# target configuration for\n# Xilinx ZynqMP (UltraScale+ / A53)\n#\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME uscale\n}\n\n#\n# DAP tap (Quard core A53)\n#\nif { [info exists DAP_TAPID] } {\n    set _DAP_TAPID $DAP_TAPID\n} else {\n    set _DAP_TAPID 0x5ba00477\n}\n\njtag newtap $_CHIPNAME tap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.tap\n\n#\n# PS tap (UltraScale+)\n#\nif { [info exists PS_TAPID] } {\n    set _PS_TAPID $PS_TAPID\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -expected-id $_PS_TAPID\n} else {\n    # FPGA Programmable logic. Values take from Table 39-1 in UG1085:\n    jtag newtap $_CHIPNAME ps -irlen 12 -ircapture 0x1 -irmask 0x03 -ignore-version \\\n        -expected-id 0x04711093 \\\n        -expected-id 0x04710093 \\\n        -expected-id 0x04721093 \\\n        -expected-id 0x04720093 \\\n        -expected-id 0x04739093 \\\n        -expected-id 0x04730093 \\\n        -expected-id 0x04738093 \\\n        -expected-id 0x04740093 \\\n        -expected-id 0x04750093 \\\n        -expected-id 0x04759093 \\\n        -expected-id 0x04758093\n}\n\nset jtag_configured 0\n\njtag configure $_CHIPNAME.ps -event setup {\n    global _CHIPNAME\n    global jtag_configured\n\n    if { $jtag_configured == 0 } {\n        # add the DAP tap to the chain\n        # See https://forums.xilinx.com/t5/UltraScale-Architecture/JTAG-Chain-Configuration-for-Zynq-UltraScale-MPSoC/td-p/758924\n        irscan $_CHIPNAME.ps 0x824\n        drscan $_CHIPNAME.ps 32 0x00000003\n        runtest 100\n\n        # setup event will be re-entered through jtag arp_init\n        # break the recursion\n        set jtag_configured 1\n        # re-initialized the jtag chain\n        jtag arp_init\n    }\n}\n\nset _TARGETNAME $_CHIPNAME.a53\nset _CTINAME $_CHIPNAME.cti\nset _smp_command \"\"\n\nset DBGBASE {0x80410000 0x80510000 0x80610000 0x80710000}\nset CTIBASE {0x80420000 0x80520000 0x80620000 0x80720000}\nset _cores 4\n\nfor { set _core 0 } { $_core < $_cores } { incr _core } {\n\n    cti create $_CTINAME.$_core -dap $_CHIPNAME.dap -ap-num 1 \\\n        -baseaddr [lindex $CTIBASE $_core]\n\n    set _command \"target create $_TARGETNAME.$_core aarch64 -dap $_CHIPNAME.dap \\\n        -dbgbase [lindex $DBGBASE $_core] -cti $_CTINAME.$_core\"\n\n    if { $_core != 0 } {\n        # non-boot core examination may fail\n        set _command \"$_command -defer-examine\"\n        set _smp_command \"$_smp_command $_TARGETNAME.$_core\"\n    } else {\n        set _command \"$_command -rtos hwthread\"\n        set _smp_command \"target smp $_TARGETNAME.$_core\"\n    }\n\n    eval $_command\n}\n\ntarget create uscale.axi mem_ap -dap uscale.dap -ap-num 0\n\neval $_smp_command\ntargets $_TARGETNAME.0\n\nproc core_up { args } {\n    global _TARGETNAME\n    foreach core $args {\n        $_TARGETNAME.$core arp_examine\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xmc1xxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC1100/XMC1200/XMC1300 family (ARM Cortex-M0 @ 32 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc1000\n}\n\n#\n# Only SWD and SPD supported\n#\nsource [find target/swj-dp.tcl]\n\nif { [info exists CPUTAPID] } {\n\tset _CPU_SWD_TAPID $CPUTAPID\n} else {\n\tset _CPU_SWD_TAPID 0x0BB11477\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_SWD_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -endian little -dap $_CHIPNAME.dap\n\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x4000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 \\\n                       -work-area-size $_WORKAREASIZE \\\n                       -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc1xxx 0x10000000 0 0 0 $_TARGETNAME\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xmc4xxx.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# Infineon XMC4100/XMC4200/XMC4400/XMC4500 family (ARM Cortex-M4 @ 80-120 MHz)\n#\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xmc4000\n}\n\nsource [find target/swj-dp.tcl]\n\n#\n# SWJ-DP\n#\nif { [info exists CPU_JTAG_TAPID] } {\n\tset _CPU_JTAG_TAPID $CPU_JTAG_TAPID\n} else {\n\tset _CPU_JTAG_TAPID 0x4BA00477\n}\n\n#\n# SW_DP\n#\nif { [info exists CPU_SWD_TAPID] } {\n\tset _CPU_SWD_TAPID $CPU_SWD_TAPID\n} else {\n\tset _CPU_SWD_TAPID 0x2BA01477\n}\n\nif { [using_jtag] } {\n\tset _CPU_TAPID $_CPU_JTAG_TAPID\n} else {\n\tset _CPU_TAPID $_CPU_SWD_TAPID\n}\n\nswj_newdap $_CHIPNAME cpu -irlen 4 -expected-id $_CPU_TAPID\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\nset _TARGETNAME $_CHIPNAME.cpu\ntarget create $_TARGETNAME cortex_m -dap $_CHIPNAME.dap\n\n# Work-area is a space in RAM used for flash programming\n# By default use 16 kB\nif { [info exists WORKAREASIZE] } {\n   set _WORKAREASIZE $WORKAREASIZE\n} else {\n   set _WORKAREASIZE 0x1000\n}\n\n$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size $_WORKAREASIZE -work-area-backup 0\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME xmc4xxx 0x0C000000 0 0 0 $_TARGETNAME\n\nif { ![using_hla] } {\n\tcortex_m reset_config sysresetreq\n}\n\nadapter speed 1000\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xmos_xs1-xau8a-10_arm.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n#\n# XMOS xCORE-XA XS1-XAU8A-10: ARM Cortex-M3 @ 48 MHz\n#\n# http://www.xmos.com/products/silicon/xcore-xa/xa-series\n#\n\nif { ![info exists CHIPNAME] } {\n\tset CHIPNAME xcorexa\n}\n\nif { ![info exists WORKAREASIZE] } {\n\t# XS1-XAU8A-10-FB265: 128 KB SRAM\n\tset WORKAREASIZE 0x20000\n}\n\nsource [find target/efm32.cfg]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa-core-esp32.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# OpenOCD configuration file for Xtensa ESP32 target\n\n#  Core definition and ABI\nxtensa xtdef\tLX\nxtensa xtopt\tarnum\t\t\t\t64\nxtensa xtopt\twindowed\t\t\t1\n\n#  Exception/Interrupt Options\nxtensa xtopt\texceptions\t\t\t1\nxtensa xtopt\thipriints\t\t\t1\nxtensa xtopt\tintlevels\t\t\t6\nxtensa xtopt\texcmlevel\t\t\t3\n\n#  Cache Options\nxtensa xtmem\ticache\t\t\t\t4 0 1\nxtensa xtmem\tdcache\t\t\t\t4 0 1 0\n\n#  Memory Options\nxtensa xtmem\tirom\t\t\t\t0x400D0000\t0x330000\nxtensa xtmem\tirom\t\t\t\t0x40000000\t0x64F00\nxtensa xtmem\tiram\t\t\t\t0x40070000\t0x30000\nxtensa xtmem\tiram\t\t\t\t0x400C0000\t0x2000\nxtensa xtmem\tdrom\t\t\t\t0x3F400000\t0x800000\nxtensa xtmem\tdrom\t\t\t\t0x3FF90000\t0x10000\nxtensa xtmem\tdram\t\t\t\t0x3FFAE000\t0x52000\nxtensa xtmem\tdram\t\t\t\t0x3FF80000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x3F800000\t0x400000\nxtensa xtmem\tdram\t\t\t\t0x50000000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x3FF00000\t0x71000\nxtensa xtmem\tdram\t\t\t\t0x60000000\t0x20000000\n\n#  Memory Protection/Translation Options\n\n#  Debug Options\nxtensa xtopt\tdebuglevel\t\t\t6\nxtensa xtopt\tibreaknum\t\t\t2\nxtensa xtopt\tdbreaknum\t\t\t2\nxtensa xtopt\ttracemem\t\t\t0x4000\nxtensa xtopt\ttracememrev\t\t\t1\nxtensa xtopt\tperfcount\t\t\t2\n\n#  Core Registers\n#  xtregfmt:\tOptionally specify \"contiguous\" vs. \"sparse\" GDB register map.\n#\t\t\t\tDefault setting is \"sparse\" and is used with xt-gdb.\n#\t\t\t\tIf contiguous, optional parameter specifies number of registers\n#\t\t\t\tin \"Read General Registers\" (g-packet) requests.\n#\t\t\t\tNOTE: For contiguous format, registers listed in GDB order.\n#  xtregs:\t\tTotal number of Xtensa registers in the system\nxtensa xtregs\t173\nxtensa xtregfmt\tcontiguous\t\t\t105\nxtensa xtreg\tpc\t\t\t\t\t0x0020\nxtensa xtreg\tar0\t\t\t\t\t0x0100\nxtensa xtreg\tar1\t\t\t\t\t0x0101\nxtensa xtreg\tar2\t\t\t\t\t0x0102\nxtensa xtreg\tar3\t\t\t\t\t0x0103\nxtensa xtreg\tar4\t\t\t\t\t0x0104\nxtensa xtreg\tar5\t\t\t\t\t0x0105\nxtensa xtreg\tar6\t\t\t\t\t0x0106\nxtensa xtreg\tar7\t\t\t\t\t0x0107\nxtensa xtreg\tar8\t\t\t\t\t0x0108\nxtensa xtreg\tar9\t\t\t\t\t0x0109\nxtensa xtreg\tar10\t\t\t\t0x010a\nxtensa xtreg\tar11\t\t\t\t0x010b\nxtensa xtreg\tar12\t\t\t\t0x010c\nxtensa xtreg\tar13\t\t\t\t0x010d\nxtensa xtreg\tar14\t\t\t\t0x010e\nxtensa xtreg\tar15\t\t\t\t0x010f\nxtensa xtreg\tar16\t\t\t\t0x0110\nxtensa xtreg\tar17\t\t\t\t0x0111\nxtensa xtreg\tar18\t\t\t\t0x0112\nxtensa xtreg\tar19\t\t\t\t0x0113\nxtensa xtreg\tar20\t\t\t\t0x0114\nxtensa xtreg\tar21\t\t\t\t0x0115\nxtensa xtreg\tar22\t\t\t\t0x0116\nxtensa xtreg\tar23\t\t\t\t0x0117\nxtensa xtreg\tar24\t\t\t\t0x0118\nxtensa xtreg\tar25\t\t\t\t0x0119\nxtensa xtreg\tar26\t\t\t\t0x011a\nxtensa xtreg\tar27\t\t\t\t0x011b\nxtensa xtreg\tar28\t\t\t\t0x011c\nxtensa xtreg\tar29\t\t\t\t0x011d\nxtensa xtreg\tar30\t\t\t\t0x011e\nxtensa xtreg\tar31\t\t\t\t0x011f\nxtensa xtreg\tar32\t\t\t\t0x0120\nxtensa xtreg\tar33\t\t\t\t0x0121\nxtensa xtreg\tar34\t\t\t\t0x0122\nxtensa xtreg\tar35\t\t\t\t0x0123\nxtensa xtreg\tar36\t\t\t\t0x0124\nxtensa xtreg\tar37\t\t\t\t0x0125\nxtensa xtreg\tar38\t\t\t\t0x0126\nxtensa xtreg\tar39\t\t\t\t0x0127\nxtensa xtreg\tar40\t\t\t\t0x0128\nxtensa xtreg\tar41\t\t\t\t0x0129\nxtensa xtreg\tar42\t\t\t\t0x012a\nxtensa xtreg\tar43\t\t\t\t0x012b\nxtensa xtreg\tar44\t\t\t\t0x012c\nxtensa xtreg\tar45\t\t\t\t0x012d\nxtensa xtreg\tar46\t\t\t\t0x012e\nxtensa xtreg\tar47\t\t\t\t0x012f\nxtensa xtreg\tar48\t\t\t\t0x0130\nxtensa xtreg\tar49\t\t\t\t0x0131\nxtensa xtreg\tar50\t\t\t\t0x0132\nxtensa xtreg\tar51\t\t\t\t0x0133\nxtensa xtreg\tar52\t\t\t\t0x0134\nxtensa xtreg\tar53\t\t\t\t0x0135\nxtensa xtreg\tar54\t\t\t\t0x0136\nxtensa xtreg\tar55\t\t\t\t0x0137\nxtensa xtreg\tar56\t\t\t\t0x0138\nxtensa xtreg\tar57\t\t\t\t0x0139\nxtensa xtreg\tar58\t\t\t\t0x013a\nxtensa xtreg\tar59\t\t\t\t0x013b\nxtensa xtreg\tar60\t\t\t\t0x013c\nxtensa xtreg\tar61\t\t\t\t0x013d\nxtensa xtreg\tar62\t\t\t\t0x013e\nxtensa xtreg\tar63\t\t\t\t0x013f\nxtensa xtreg\tlbeg\t\t\t\t0x0200\nxtensa xtreg\tlend\t\t\t\t0x0201\nxtensa xtreg\tlcount\t\t\t\t0x0202\nxtensa xtreg\tsar\t\t\t\t\t0x0203\nxtensa xtreg\twindowbase\t\t\t0x0248\nxtensa xtreg\twindowstart\t\t\t0x0249\nxtensa xtreg\tconfigid0\t\t\t0x02b0\nxtensa xtreg\tconfigid1\t\t\t0x02d0\nxtensa xtreg\tps\t\t\t\t\t0x02e6\nxtensa xtreg\tthreadptr\t\t\t0x03e7\nxtensa xtreg\tbr\t\t\t\t\t0x0204\nxtensa xtreg\tscompare1\t\t\t0x020c\nxtensa xtreg\tacclo\t\t\t\t0x0210\nxtensa xtreg\tacchi\t\t\t\t0x0211\nxtensa xtreg\tm0\t\t\t\t\t0x0220\nxtensa xtreg\tm1\t\t\t\t\t0x0221\nxtensa xtreg\tm2\t\t\t\t\t0x0222\nxtensa xtreg\tm3\t\t\t\t\t0x0223\nxtensa xtreg\texpstate\t\t\t0x03e6\nxtensa xtreg\tf64r_lo\t\t\t\t0x03ea\nxtensa xtreg\tf64r_hi\t\t\t\t0x03eb\nxtensa xtreg\tf64s\t\t\t\t0x03ec\nxtensa xtreg\tf0\t\t\t\t\t0x0030\nxtensa xtreg\tf1\t\t\t\t\t0x0031\nxtensa xtreg\tf2\t\t\t\t\t0x0032\nxtensa xtreg\tf3\t\t\t\t\t0x0033\nxtensa xtreg\tf4\t\t\t\t\t0x0034\nxtensa xtreg\tf5\t\t\t\t\t0x0035\nxtensa xtreg\tf6\t\t\t\t\t0x0036\nxtensa xtreg\tf7\t\t\t\t\t0x0037\nxtensa xtreg\tf8\t\t\t\t\t0x0038\nxtensa xtreg\tf9\t\t\t\t\t0x0039\nxtensa xtreg\tf10\t\t\t\t\t0x003a\nxtensa xtreg\tf11\t\t\t\t\t0x003b\nxtensa xtreg\tf12\t\t\t\t\t0x003c\nxtensa xtreg\tf13\t\t\t\t\t0x003d\nxtensa xtreg\tf14\t\t\t\t\t0x003e\nxtensa xtreg\tf15\t\t\t\t\t0x003f\nxtensa xtreg\tfcr\t\t\t\t\t0x03e8\nxtensa xtreg\tfsr\t\t\t\t\t0x03e9\nxtensa xtreg\tmmid\t\t\t\t0x0259\nxtensa xtreg\tibreakenable\t\t0x0260\nxtensa xtreg\tmemctl\t\t\t\t0x0261\nxtensa xtreg\tatomctl\t\t\t\t0x0263\nxtensa xtreg\tddr\t\t\t\t\t0x0268\nxtensa xtreg\tibreaka0\t\t\t0x0280\nxtensa xtreg\tibreaka1\t\t\t0x0281\nxtensa xtreg\tdbreaka0\t\t\t0x0290\nxtensa xtreg\tdbreaka1\t\t\t0x0291\nxtensa xtreg\tdbreakc0\t\t\t0x02a0\nxtensa xtreg\tdbreakc1\t\t\t0x02a1\nxtensa xtreg\tepc1\t\t\t\t0x02b1\nxtensa xtreg\tepc2\t\t\t\t0x02b2\nxtensa xtreg\tepc3\t\t\t\t0x02b3\nxtensa xtreg\tepc4\t\t\t\t0x02b4\nxtensa xtreg\tepc5\t\t\t\t0x02b5\nxtensa xtreg\tepc6\t\t\t\t0x02b6\nxtensa xtreg\tepc7\t\t\t\t0x02b7\nxtensa xtreg\tdepc\t\t\t\t0x02c0\nxtensa xtreg\teps2\t\t\t\t0x02c2\nxtensa xtreg\teps3\t\t\t\t0x02c3\nxtensa xtreg\teps4\t\t\t\t0x02c4\nxtensa xtreg\teps5\t\t\t\t0x02c5\nxtensa xtreg\teps6\t\t\t\t0x02c6\nxtensa xtreg\teps7\t\t\t\t0x02c7\nxtensa xtreg\texcsave1\t\t\t0x02d1\nxtensa xtreg\texcsave2\t\t\t0x02d2\nxtensa xtreg\texcsave3\t\t\t0x02d3\nxtensa xtreg\texcsave4\t\t\t0x02d4\nxtensa xtreg\texcsave5\t\t\t0x02d5\nxtensa xtreg\texcsave6\t\t\t0x02d6\nxtensa xtreg\texcsave7\t\t\t0x02d7\nxtensa xtreg\tcpenable\t\t\t0x02e0\nxtensa xtreg\tinterrupt\t\t\t0x02e2\nxtensa xtreg\tintset\t\t\t\t0x02e2\nxtensa xtreg\tintclear\t\t\t0x02e3\nxtensa xtreg\tintenable\t\t\t0x02e4\nxtensa xtreg\tvecbase\t\t\t\t0x02e7\nxtensa xtreg\texccause\t\t\t0x02e8\nxtensa xtreg\tdebugcause\t\t\t0x02e9\nxtensa xtreg\tccount\t\t\t\t0x02ea\nxtensa xtreg\tprid\t\t\t\t0x02eb\nxtensa xtreg\ticount\t\t\t\t0x02ec\nxtensa xtreg\ticountlevel\t\t\t0x02ed\nxtensa xtreg\texcvaddr\t\t\t0x02ee\nxtensa xtreg\tccompare0\t\t\t0x02f0\nxtensa xtreg\tccompare1\t\t\t0x02f1\nxtensa xtreg\tccompare2\t\t\t0x02f2\nxtensa xtreg\tmisc0\t\t\t\t0x02f4\nxtensa xtreg\tmisc1\t\t\t\t0x02f5\nxtensa xtreg\tmisc2\t\t\t\t0x02f6\nxtensa xtreg\tmisc3\t\t\t\t0x02f7\nxtensa xtreg\ta0\t\t\t\t\t0x0000\nxtensa xtreg\ta1\t\t\t\t\t0x0001\nxtensa xtreg\ta2\t\t\t\t\t0x0002\nxtensa xtreg\ta3\t\t\t\t\t0x0003\nxtensa xtreg\ta4\t\t\t\t\t0x0004\nxtensa xtreg\ta5\t\t\t\t\t0x0005\nxtensa xtreg\ta6\t\t\t\t\t0x0006\nxtensa xtreg\ta7\t\t\t\t\t0x0007\nxtensa xtreg\ta8\t\t\t\t\t0x0008\nxtensa xtreg\ta9\t\t\t\t\t0x0009\nxtensa xtreg\ta10\t\t\t\t\t0x000a\nxtensa xtreg\ta11\t\t\t\t\t0x000b\nxtensa xtreg\ta12\t\t\t\t\t0x000c\nxtensa xtreg\ta13\t\t\t\t\t0x000d\nxtensa xtreg\ta14\t\t\t\t\t0x000e\nxtensa xtreg\ta15\t\t\t\t\t0x000f\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa-core-esp32s2.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# OpenOCD configuration file for Xtensa ESP32S2 target\n\n#  Core definition and ABI\nxtensa xtdef\tLX\nxtensa xtopt\tarnum\t\t\t\t64\nxtensa xtopt\twindowed\t\t\t1\n\n#  Exception/Interrupt Options\nxtensa xtopt\texceptions\t\t\t1\nxtensa xtopt\thipriints\t\t\t1\nxtensa xtopt\tintlevels\t\t\t6\nxtensa xtopt\texcmlevel\t\t\t3\n\n#  Cache Options\nxtensa xtmem\ticache\t\t\t\t4 0 1\nxtensa xtmem\tdcache\t\t\t\t4 0 1 0\n\n#  Memory Options\nxtensa xtmem\tirom\t\t\t\t0x40080000\t0x780000\nxtensa xtmem\tirom\t\t\t\t0x40000000\t0x20000\nxtensa xtmem\tiram\t\t\t\t0x40020000\t0x50000\nxtensa xtmem\tiram\t\t\t\t0x40070000\t0x2000\nxtensa xtmem\tdrom\t\t\t\t0x3F000000\t0x400000\nxtensa xtmem\tdrom\t\t\t\t0x3F4D3FFC\t0xAAC004\nxtensa xtmem\tdrom\t\t\t\t0x3FFA0000\t0x10000\nxtensa xtmem\tdram\t\t\t\t0x3FFB0000\t0x50000\nxtensa xtmem\tdram\t\t\t\t0x3FF9E000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x50000000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x3F500000\t0xA80000\nxtensa xtmem\tdram\t\t\t\t0x3F400000\t0xD3FFC\nxtensa xtmem\tdram\t\t\t\t0x60000000\t0x20000000\n\n#  Memory Protection/Translation Options\n\n#  Debug Options\nxtensa xtopt\tdebuglevel\t\t\t6\nxtensa xtopt\tibreaknum\t\t\t2\nxtensa xtopt\tdbreaknum\t\t\t2\nxtensa xtopt\ttracemem\t\t\t0x4000\nxtensa xtopt\ttracememrev\t\t\t0\nxtensa xtopt\tperfcount\t\t\t2\n\n#  Core Registers\n#  xtregfmt:\tOptionally specify \"contiguous\" vs. \"sparse\" GDB register map.\n#\t\t\t\tDefault setting is \"sparse\" and is used with xt-gdb.\n#\t\t\t\tIf contiguous, optional parameter specifies number of registers\n#\t\t\t\tin \"Read General Registers\" (g-packet) requests.\n#\t\t\t\tNOTE: For contiguous format, registers listed in GDB order.\n#  xtregs:\t\tTotal number of Xtensa registers in the system\nxtensa xtregs\t171\nxtensa xtregfmt\tcontiguous\t\t\t73\nxtensa xtreg\tpc\t\t\t\t\t0x0020\nxtensa xtreg\tar0\t\t\t\t\t0x0100\nxtensa xtreg\tar1\t\t\t\t\t0x0101\nxtensa xtreg\tar2\t\t\t\t\t0x0102\nxtensa xtreg\tar3\t\t\t\t\t0x0103\nxtensa xtreg\tar4\t\t\t\t\t0x0104\nxtensa xtreg\tar5\t\t\t\t\t0x0105\nxtensa xtreg\tar6\t\t\t\t\t0x0106\nxtensa xtreg\tar7\t\t\t\t\t0x0107\nxtensa xtreg\tar8\t\t\t\t\t0x0108\nxtensa xtreg\tar9\t\t\t\t\t0x0109\nxtensa xtreg\tar10\t\t\t\t0x010a\nxtensa xtreg\tar11\t\t\t\t0x010b\nxtensa xtreg\tar12\t\t\t\t0x010c\nxtensa xtreg\tar13\t\t\t\t0x010d\nxtensa xtreg\tar14\t\t\t\t0x010e\nxtensa xtreg\tar15\t\t\t\t0x010f\nxtensa xtreg\tar16\t\t\t\t0x0110\nxtensa xtreg\tar17\t\t\t\t0x0111\nxtensa xtreg\tar18\t\t\t\t0x0112\nxtensa xtreg\tar19\t\t\t\t0x0113\nxtensa xtreg\tar20\t\t\t\t0x0114\nxtensa xtreg\tar21\t\t\t\t0x0115\nxtensa xtreg\tar22\t\t\t\t0x0116\nxtensa xtreg\tar23\t\t\t\t0x0117\nxtensa xtreg\tar24\t\t\t\t0x0118\nxtensa xtreg\tar25\t\t\t\t0x0119\nxtensa xtreg\tar26\t\t\t\t0x011a\nxtensa xtreg\tar27\t\t\t\t0x011b\nxtensa xtreg\tar28\t\t\t\t0x011c\nxtensa xtreg\tar29\t\t\t\t0x011d\nxtensa xtreg\tar30\t\t\t\t0x011e\nxtensa xtreg\tar31\t\t\t\t0x011f\nxtensa xtreg\tar32\t\t\t\t0x0120\nxtensa xtreg\tar33\t\t\t\t0x0121\nxtensa xtreg\tar34\t\t\t\t0x0122\nxtensa xtreg\tar35\t\t\t\t0x0123\nxtensa xtreg\tar36\t\t\t\t0x0124\nxtensa xtreg\tar37\t\t\t\t0x0125\nxtensa xtreg\tar38\t\t\t\t0x0126\nxtensa xtreg\tar39\t\t\t\t0x0127\nxtensa xtreg\tar40\t\t\t\t0x0128\nxtensa xtreg\tar41\t\t\t\t0x0129\nxtensa xtreg\tar42\t\t\t\t0x012a\nxtensa xtreg\tar43\t\t\t\t0x012b\nxtensa xtreg\tar44\t\t\t\t0x012c\nxtensa xtreg\tar45\t\t\t\t0x012d\nxtensa xtreg\tar46\t\t\t\t0x012e\nxtensa xtreg\tar47\t\t\t\t0x012f\nxtensa xtreg\tar48\t\t\t\t0x0130\nxtensa xtreg\tar49\t\t\t\t0x0131\nxtensa xtreg\tar50\t\t\t\t0x0132\nxtensa xtreg\tar51\t\t\t\t0x0133\nxtensa xtreg\tar52\t\t\t\t0x0134\nxtensa xtreg\tar53\t\t\t\t0x0135\nxtensa xtreg\tar54\t\t\t\t0x0136\nxtensa xtreg\tar55\t\t\t\t0x0137\nxtensa xtreg\tar56\t\t\t\t0x0138\nxtensa xtreg\tar57\t\t\t\t0x0139\nxtensa xtreg\tar58\t\t\t\t0x013a\nxtensa xtreg\tar59\t\t\t\t0x013b\nxtensa xtreg\tar60\t\t\t\t0x013c\nxtensa xtreg\tar61\t\t\t\t0x013d\nxtensa xtreg\tar62\t\t\t\t0x013e\nxtensa xtreg\tar63\t\t\t\t0x013f\nxtensa xtreg\tsar\t\t\t\t\t0x0203\nxtensa xtreg\twindowbase\t\t\t0x0248\nxtensa xtreg\twindowstart\t\t\t0x0249\nxtensa xtreg\tconfigid0\t\t\t0x02b0\nxtensa xtreg\tconfigid1\t\t\t0x02d0\nxtensa xtreg\tps\t\t\t\t\t0x02e6\nxtensa xtreg\tthreadptr\t\t\t0x03e7\nxtensa xtreg\tgpio_out\t\t\t0x0300\nxtensa xtreg\tmmid\t\t\t\t0x0259\nxtensa xtreg\tibreakenable\t\t0x0260\nxtensa xtreg\tddr\t\t\t\t\t0x0268\nxtensa xtreg\tibreaka0\t\t\t0x0280\nxtensa xtreg\tibreaka1\t\t\t0x0281\nxtensa xtreg\tdbreaka0\t\t\t0x0290\nxtensa xtreg\tdbreaka1\t\t\t0x0291\nxtensa xtreg\tdbreakc0\t\t\t0x02a0\nxtensa xtreg\tdbreakc1\t\t\t0x02a1\nxtensa xtreg\tepc1\t\t\t\t0x02b1\nxtensa xtreg\tepc2\t\t\t\t0x02b2\nxtensa xtreg\tepc3\t\t\t\t0x02b3\nxtensa xtreg\tepc4\t\t\t\t0x02b4\nxtensa xtreg\tepc5\t\t\t\t0x02b5\nxtensa xtreg\tepc6\t\t\t\t0x02b6\nxtensa xtreg\tepc7\t\t\t\t0x02b7\nxtensa xtreg\tdepc\t\t\t\t0x02c0\nxtensa xtreg\teps2\t\t\t\t0x02c2\nxtensa xtreg\teps3\t\t\t\t0x02c3\nxtensa xtreg\teps4\t\t\t\t0x02c4\nxtensa xtreg\teps5\t\t\t\t0x02c5\nxtensa xtreg\teps6\t\t\t\t0x02c6\nxtensa xtreg\teps7\t\t\t\t0x02c7\nxtensa xtreg\texcsave1\t\t\t0x02d1\nxtensa xtreg\texcsave2\t\t\t0x02d2\nxtensa xtreg\texcsave3\t\t\t0x02d3\nxtensa xtreg\texcsave4\t\t\t0x02d4\nxtensa xtreg\texcsave5\t\t\t0x02d5\nxtensa xtreg\texcsave6\t\t\t0x02d6\nxtensa xtreg\texcsave7\t\t\t0x02d7\nxtensa xtreg\tcpenable\t\t\t0x02e0\nxtensa xtreg\tinterrupt\t\t\t0x02e2\nxtensa xtreg\tintset\t\t\t\t0x02e2\nxtensa xtreg\tintclear\t\t\t0x02e3\nxtensa xtreg\tintenable\t\t\t0x02e4\nxtensa xtreg\tvecbase\t\t\t\t0x02e7\nxtensa xtreg\texccause\t\t\t0x02e8\nxtensa xtreg\tdebugcause\t\t\t0x02e9\nxtensa xtreg\tccount\t\t\t\t0x02ea\nxtensa xtreg\tprid\t\t\t\t0x02eb\nxtensa xtreg\ticount\t\t\t\t0x02ec\nxtensa xtreg\ticountlevel\t\t\t0x02ed\nxtensa xtreg\texcvaddr\t\t\t0x02ee\nxtensa xtreg\tccompare0\t\t\t0x02f0\nxtensa xtreg\tccompare1\t\t\t0x02f1\nxtensa xtreg\tccompare2\t\t\t0x02f2\nxtensa xtreg\tmisc0\t\t\t\t0x02f4\nxtensa xtreg\tmisc1\t\t\t\t0x02f5\nxtensa xtreg\tmisc2\t\t\t\t0x02f6\nxtensa xtreg\tmisc3\t\t\t\t0x02f7\nxtensa xtreg\tpwrctl\t\t\t\t0x2014\nxtensa xtreg\tpwrstat\t\t\t\t0x2015\nxtensa xtreg\teristat\t\t\t\t0x2016\nxtensa xtreg\tcs_itctrl\t\t\t0x2017\nxtensa xtreg\tcs_claimset\t\t\t0x2018\nxtensa xtreg\tcs_claimclr\t\t\t0x2019\nxtensa xtreg\tcs_lockaccess\t\t0x201a\nxtensa xtreg\tcs_lockstatus\t\t0x201b\nxtensa xtreg\tcs_authstatus\t\t0x201c\nxtensa xtreg\tfault_info\t\t\t0x202b\nxtensa xtreg\ttrax_id\t\t\t\t0x202c\nxtensa xtreg\ttrax_control\t\t0x202d\nxtensa xtreg\ttrax_status\t\t\t0x202e\nxtensa xtreg\ttrax_data\t\t\t0x202f\nxtensa xtreg\ttrax_address\t\t0x2030\nxtensa xtreg\ttrax_pctrigger\t\t0x2031\nxtensa xtreg\ttrax_pcmatch\t\t0x2032\nxtensa xtreg\ttrax_delay\t\t\t0x2033\nxtensa xtreg\ttrax_memstart\t\t0x2034\nxtensa xtreg\ttrax_memend\t\t\t0x2035\nxtensa xtreg\tpmg\t\t\t\t\t0x2043\nxtensa xtreg\tpmpc\t\t\t\t0x2044\nxtensa xtreg\tpm0\t\t\t\t\t0x2045\nxtensa xtreg\tpm1\t\t\t\t\t0x2046\nxtensa xtreg\tpmctrl0\t\t\t\t0x2047\nxtensa xtreg\tpmctrl1\t\t\t\t0x2048\nxtensa xtreg\tpmstat0\t\t\t\t0x2049\nxtensa xtreg\tpmstat1\t\t\t\t0x204a\nxtensa xtreg\tocdid\t\t\t\t0x204b\nxtensa xtreg\tocd_dcrclr\t\t\t0x204c\nxtensa xtreg\tocd_dcrset\t\t\t0x204d\nxtensa xtreg\tocd_dsr\t\t\t\t0x204e\nxtensa xtreg\ta0\t\t\t\t\t0x0000\nxtensa xtreg\ta1\t\t\t\t\t0x0001\nxtensa xtreg\ta2\t\t\t\t\t0x0002\nxtensa xtreg\ta3\t\t\t\t\t0x0003\nxtensa xtreg\ta4\t\t\t\t\t0x0004\nxtensa xtreg\ta5\t\t\t\t\t0x0005\nxtensa xtreg\ta6\t\t\t\t\t0x0006\nxtensa xtreg\ta7\t\t\t\t\t0x0007\nxtensa xtreg\ta8\t\t\t\t\t0x0008\nxtensa xtreg\ta9\t\t\t\t\t0x0009\nxtensa xtreg\ta10\t\t\t\t\t0x000a\nxtensa xtreg\ta11\t\t\t\t\t0x000b\nxtensa xtreg\ta12\t\t\t\t\t0x000c\nxtensa xtreg\ta13\t\t\t\t\t0x000d\nxtensa xtreg\ta14\t\t\t\t\t0x000e\nxtensa xtreg\ta15\t\t\t\t\t0x000f\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa-core-esp32s3.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# OpenOCD configuration file for Xtensa ESP32S3 target\n\n#  Core definition and ABI\nxtensa xtdef\tLX\nxtensa xtopt\tarnum\t\t\t\t64\nxtensa xtopt\twindowed\t\t\t1\n\n#  Exception/Interrupt Options\nxtensa xtopt\texceptions\t\t\t1\nxtensa xtopt\thipriints\t\t\t1\nxtensa xtopt\tintlevels\t\t\t6\nxtensa xtopt\texcmlevel\t\t\t3\n\n#  Cache Options\n\n#  Memory Options\nxtensa xtmem\tirom\t\t\t\t0x42000000\t0x2000000\nxtensa xtmem\tirom\t\t\t\t0x40000000\t0x60000\nxtensa xtmem\tiram\t\t\t\t0x40370000\t0x70000\nxtensa xtmem\tiram\t\t\t\t0x600FE000\t0x2000\nxtensa xtmem\tdrom\t\t\t\t0x3C000000\t0x1000000\nxtensa xtmem\tdrom\t\t\t\t0x3FF00000\t0x20000\nxtensa xtmem\tdram\t\t\t\t0x3FC88000\t0x78000\nxtensa xtmem\tdram\t\t\t\t0x600FE000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x50000000\t0x2000\nxtensa xtmem\tdram\t\t\t\t0x60000000\t0x10000000\n\n#  Memory Protection/Translation Options\n\n#  Debug Options\nxtensa xtopt\tdebuglevel\t\t\t6\nxtensa xtopt\tibreaknum\t\t\t2\nxtensa xtopt\tdbreaknum\t\t\t2\nxtensa xtopt\ttracemem\t\t\t0x4000\nxtensa xtopt\ttracememrev\t\t\t0\nxtensa xtopt\tperfcount\t\t\t2\n\n\n#  Core Registers\n#  xtregfmt:\tOptionally specify \"contiguous\" vs. \"sparse\" GDB register map.\n#\t\t\t\tDefault setting is \"sparse\" and is used with xt-gdb.\n#\t\t\t\tIf contiguous, optional parameter specifies number of registers\n#\t\t\t\tin \"Read General Registers\" (g-packet) requests.\n#\t\t\t\tNOTE: For contiguous format, registers listed in GDB order.\n#  xtregs:\t\tTotal number of Xtensa registers in the system\nxtensa xtregs\t228\nxtensa xtregfmt\tcontiguous\t\t\t128\nxtensa xtreg\tpc\t\t\t\t\t0x0020\nxtensa xtreg\tar0\t\t\t\t\t0x0100\nxtensa xtreg\tar1\t\t\t\t\t0x0101\nxtensa xtreg\tar2\t\t\t\t\t0x0102\nxtensa xtreg\tar3\t\t\t\t\t0x0103\nxtensa xtreg\tar4\t\t\t\t\t0x0104\nxtensa xtreg\tar5\t\t\t\t\t0x0105\nxtensa xtreg\tar6\t\t\t\t\t0x0106\nxtensa xtreg\tar7\t\t\t\t\t0x0107\nxtensa xtreg\tar8\t\t\t\t\t0x0108\nxtensa xtreg\tar9\t\t\t\t\t0x0109\nxtensa xtreg\tar10\t\t\t\t0x010a\nxtensa xtreg\tar11\t\t\t\t0x010b\nxtensa xtreg\tar12\t\t\t\t0x010c\nxtensa xtreg\tar13\t\t\t\t0x010d\nxtensa xtreg\tar14\t\t\t\t0x010e\nxtensa xtreg\tar15\t\t\t\t0x010f\nxtensa xtreg\tar16\t\t\t\t0x0110\nxtensa xtreg\tar17\t\t\t\t0x0111\nxtensa xtreg\tar18\t\t\t\t0x0112\nxtensa xtreg\tar19\t\t\t\t0x0113\nxtensa xtreg\tar20\t\t\t\t0x0114\nxtensa xtreg\tar21\t\t\t\t0x0115\nxtensa xtreg\tar22\t\t\t\t0x0116\nxtensa xtreg\tar23\t\t\t\t0x0117\nxtensa xtreg\tar24\t\t\t\t0x0118\nxtensa xtreg\tar25\t\t\t\t0x0119\nxtensa xtreg\tar26\t\t\t\t0x011a\nxtensa xtreg\tar27\t\t\t\t0x011b\nxtensa xtreg\tar28\t\t\t\t0x011c\nxtensa xtreg\tar29\t\t\t\t0x011d\nxtensa xtreg\tar30\t\t\t\t0x011e\nxtensa xtreg\tar31\t\t\t\t0x011f\nxtensa xtreg\tar32\t\t\t\t0x0120\nxtensa xtreg\tar33\t\t\t\t0x0121\nxtensa xtreg\tar34\t\t\t\t0x0122\nxtensa xtreg\tar35\t\t\t\t0x0123\nxtensa xtreg\tar36\t\t\t\t0x0124\nxtensa xtreg\tar37\t\t\t\t0x0125\nxtensa xtreg\tar38\t\t\t\t0x0126\nxtensa xtreg\tar39\t\t\t\t0x0127\nxtensa xtreg\tar40\t\t\t\t0x0128\nxtensa xtreg\tar41\t\t\t\t0x0129\nxtensa xtreg\tar42\t\t\t\t0x012a\nxtensa xtreg\tar43\t\t\t\t0x012b\nxtensa xtreg\tar44\t\t\t\t0x012c\nxtensa xtreg\tar45\t\t\t\t0x012d\nxtensa xtreg\tar46\t\t\t\t0x012e\nxtensa xtreg\tar47\t\t\t\t0x012f\nxtensa xtreg\tar48\t\t\t\t0x0130\nxtensa xtreg\tar49\t\t\t\t0x0131\nxtensa xtreg\tar50\t\t\t\t0x0132\nxtensa xtreg\tar51\t\t\t\t0x0133\nxtensa xtreg\tar52\t\t\t\t0x0134\nxtensa xtreg\tar53\t\t\t\t0x0135\nxtensa xtreg\tar54\t\t\t\t0x0136\nxtensa xtreg\tar55\t\t\t\t0x0137\nxtensa xtreg\tar56\t\t\t\t0x0138\nxtensa xtreg\tar57\t\t\t\t0x0139\nxtensa xtreg\tar58\t\t\t\t0x013a\nxtensa xtreg\tar59\t\t\t\t0x013b\nxtensa xtreg\tar60\t\t\t\t0x013c\nxtensa xtreg\tar61\t\t\t\t0x013d\nxtensa xtreg\tar62\t\t\t\t0x013e\nxtensa xtreg\tar63\t\t\t\t0x013f\nxtensa xtreg\tlbeg\t\t\t\t0x0200\nxtensa xtreg\tlend\t\t\t\t0x0201\nxtensa xtreg\tlcount\t\t\t\t0x0202\nxtensa xtreg\tsar\t\t\t\t\t0x0203\nxtensa xtreg\twindowbase\t\t\t0x0248\nxtensa xtreg\twindowstart\t\t\t0x0249\nxtensa xtreg\tconfigid0\t\t\t0x02b0\nxtensa xtreg\tconfigid1\t\t\t0x02d0\nxtensa xtreg\tps\t\t\t\t\t0x02e6\nxtensa xtreg\tthreadptr\t\t\t0x03e7\nxtensa xtreg\tbr\t\t\t\t\t0x0204\nxtensa xtreg\tscompare1\t\t\t0x020c\nxtensa xtreg\tacclo\t\t\t\t0x0210\nxtensa xtreg\tacchi\t\t\t\t0x0211\nxtensa xtreg\tm0\t\t\t\t\t0x0220\nxtensa xtreg\tm1\t\t\t\t\t0x0221\nxtensa xtreg\tm2\t\t\t\t\t0x0222\nxtensa xtreg\tm3\t\t\t\t\t0x0223\nxtensa xtreg\tgpio_out\t\t\t0x030c\nxtensa xtreg\tf0\t\t\t\t\t0x0030\nxtensa xtreg\tf1\t\t\t\t\t0x0031\nxtensa xtreg\tf2\t\t\t\t\t0x0032\nxtensa xtreg\tf3\t\t\t\t\t0x0033\nxtensa xtreg\tf4\t\t\t\t\t0x0034\nxtensa xtreg\tf5\t\t\t\t\t0x0035\nxtensa xtreg\tf6\t\t\t\t\t0x0036\nxtensa xtreg\tf7\t\t\t\t\t0x0037\nxtensa xtreg\tf8\t\t\t\t\t0x0038\nxtensa xtreg\tf9\t\t\t\t\t0x0039\nxtensa xtreg\tf10\t\t\t\t\t0x003a\nxtensa xtreg\tf11\t\t\t\t\t0x003b\nxtensa xtreg\tf12\t\t\t\t\t0x003c\nxtensa xtreg\tf13\t\t\t\t\t0x003d\nxtensa xtreg\tf14\t\t\t\t\t0x003e\nxtensa xtreg\tf15\t\t\t\t\t0x003f\nxtensa xtreg\tfcr\t\t\t\t\t0x03e8\nxtensa xtreg\tfsr\t\t\t\t\t0x03e9\nxtensa xtreg\taccx_0\t\t\t\t0x0300\nxtensa xtreg\taccx_1\t\t\t\t0x0301\nxtensa xtreg\tqacc_h_0\t\t\t0x0302\nxtensa xtreg\tqacc_h_1\t\t\t0x0303\nxtensa xtreg\tqacc_h_2\t\t\t0x0304\nxtensa xtreg\tqacc_h_3\t\t\t0x0305\nxtensa xtreg\tqacc_h_4\t\t\t0x0306\nxtensa xtreg\tqacc_l_0\t\t\t0x0307\nxtensa xtreg\tqacc_l_1\t\t\t0x0308\nxtensa xtreg\tqacc_l_2\t\t\t0x0309\nxtensa xtreg\tqacc_l_3\t\t\t0x030a\nxtensa xtreg\tqacc_l_4\t\t\t0x030b\nxtensa xtreg\tsar_byte\t\t\t0x030d\nxtensa xtreg\tfft_bit_width\t\t0x030e\nxtensa xtreg\tua_state_0\t\t\t0x030f\nxtensa xtreg\tua_state_1\t\t\t0x0310\nxtensa xtreg\tua_state_2\t\t\t0x0311\nxtensa xtreg\tua_state_3\t\t\t0x0312\nxtensa xtreg\tq0\t\t\t\t\t0x1008\nxtensa xtreg\tq1\t\t\t\t\t0x1009\nxtensa xtreg\tq2\t\t\t\t\t0x100a\nxtensa xtreg\tq3\t\t\t\t\t0x100b\nxtensa xtreg\tq4\t\t\t\t\t0x100c\nxtensa xtreg\tq5\t\t\t\t\t0x100d\nxtensa xtreg\tq6\t\t\t\t\t0x100e\nxtensa xtreg\tq7\t\t\t\t\t0x100f\nxtensa xtreg\tmmid\t\t\t\t0x0259\nxtensa xtreg\tibreakenable\t\t0x0260\nxtensa xtreg\tmemctl\t\t\t\t0x0261\nxtensa xtreg\tatomctl\t\t\t\t0x0263\nxtensa xtreg\tddr\t\t\t\t\t0x0268\nxtensa xtreg\tibreaka0\t\t\t0x0280\nxtensa xtreg\tibreaka1\t\t\t0x0281\nxtensa xtreg\tdbreaka0\t\t\t0x0290\nxtensa xtreg\tdbreaka1\t\t\t0x0291\nxtensa xtreg\tdbreakc0\t\t\t0x02a0\nxtensa xtreg\tdbreakc1\t\t\t0x02a1\nxtensa xtreg\tepc1\t\t\t\t0x02b1\nxtensa xtreg\tepc2\t\t\t\t0x02b2\nxtensa xtreg\tepc3\t\t\t\t0x02b3\nxtensa xtreg\tepc4\t\t\t\t0x02b4\nxtensa xtreg\tepc5\t\t\t\t0x02b5\nxtensa xtreg\tepc6\t\t\t\t0x02b6\nxtensa xtreg\tepc7\t\t\t\t0x02b7\nxtensa xtreg\tdepc\t\t\t\t0x02c0\nxtensa xtreg\teps2\t\t\t\t0x02c2\nxtensa xtreg\teps3\t\t\t\t0x02c3\nxtensa xtreg\teps4\t\t\t\t0x02c4\nxtensa xtreg\teps5\t\t\t\t0x02c5\nxtensa xtreg\teps6\t\t\t\t0x02c6\nxtensa xtreg\teps7\t\t\t\t0x02c7\nxtensa xtreg\texcsave1\t\t\t0x02d1\nxtensa xtreg\texcsave2\t\t\t0x02d2\nxtensa xtreg\texcsave3\t\t\t0x02d3\nxtensa xtreg\texcsave4\t\t\t0x02d4\nxtensa xtreg\texcsave5\t\t\t0x02d5\nxtensa xtreg\texcsave6\t\t\t0x02d6\nxtensa xtreg\texcsave7\t\t\t0x02d7\nxtensa xtreg\tcpenable\t\t\t0x02e0\nxtensa xtreg\tinterrupt\t\t\t0x02e2\nxtensa xtreg\tintset\t\t\t\t0x02e2\nxtensa xtreg\tintclear\t\t\t0x02e3\nxtensa xtreg\tintenable\t\t\t0x02e4\nxtensa xtreg\tvecbase\t\t\t\t0x02e7\nxtensa xtreg\texccause\t\t\t0x02e8\nxtensa xtreg\tdebugcause\t\t\t0x02e9\nxtensa xtreg\tccount\t\t\t\t0x02ea\nxtensa xtreg\tprid\t\t\t\t0x02eb\nxtensa xtreg\ticount\t\t\t\t0x02ec\nxtensa xtreg\ticountlevel\t\t\t0x02ed\nxtensa xtreg\texcvaddr\t\t\t0x02ee\nxtensa xtreg\tccompare0\t\t\t0x02f0\nxtensa xtreg\tccompare1\t\t\t0x02f1\nxtensa xtreg\tccompare2\t\t\t0x02f2\nxtensa xtreg\tmisc0\t\t\t\t0x02f4\nxtensa xtreg\tmisc1\t\t\t\t0x02f5\nxtensa xtreg\tmisc2\t\t\t\t0x02f6\nxtensa xtreg\tmisc3\t\t\t\t0x02f7\nxtensa xtreg\tpwrctl\t\t\t\t0x2028\nxtensa xtreg\tpwrstat\t\t\t\t0x2029\nxtensa xtreg\teristat\t\t\t\t0x202a\nxtensa xtreg\tcs_itctrl\t\t\t0x202b\nxtensa xtreg\tcs_claimset\t\t\t0x202c\nxtensa xtreg\tcs_claimclr\t\t\t0x202d\nxtensa xtreg\tcs_lockaccess\t\t0x202e\nxtensa xtreg\tcs_lockstatus\t\t0x202f\nxtensa xtreg\tcs_authstatus\t\t0x2030\nxtensa xtreg\tfault_info\t\t\t0x203f\nxtensa xtreg\ttrax_id\t\t\t\t0x2040\nxtensa xtreg\ttrax_control\t\t0x2041\nxtensa xtreg\ttrax_status\t\t\t0x2042\nxtensa xtreg\ttrax_data\t\t\t0x2043\nxtensa xtreg\ttrax_address\t\t0x2044\nxtensa xtreg\ttrax_pctrigger\t\t0x2045\nxtensa xtreg\ttrax_pcmatch\t\t0x2046\nxtensa xtreg\ttrax_delay\t\t\t0x2047\nxtensa xtreg\ttrax_memstart\t\t0x2048\nxtensa xtreg\ttrax_memend\t\t\t0x2049\nxtensa xtreg\tpmg\t\t\t\t\t0x2057\nxtensa xtreg\tpmpc\t\t\t\t0x2058\nxtensa xtreg\tpm0\t\t\t\t\t0x2059\nxtensa xtreg\tpm1\t\t\t\t\t0x205a\nxtensa xtreg\tpmctrl0\t\t\t\t0x205b\nxtensa xtreg\tpmctrl1\t\t\t\t0x205c\nxtensa xtreg\tpmstat0\t\t\t\t0x205d\nxtensa xtreg\tpmstat1\t\t\t\t0x205e\nxtensa xtreg\tocdid\t\t\t\t0x205f\nxtensa xtreg\tocd_dcrclr\t\t\t0x2060\nxtensa xtreg\tocd_dcrset\t\t\t0x2061\nxtensa xtreg\tocd_dsr\t\t\t\t0x2062\nxtensa xtreg\ta0\t\t\t\t\t0x0000\nxtensa xtreg\ta1\t\t\t\t\t0x0001\nxtensa xtreg\ta2\t\t\t\t\t0x0002\nxtensa xtreg\ta3\t\t\t\t\t0x0003\nxtensa xtreg\ta4\t\t\t\t\t0x0004\nxtensa xtreg\ta5\t\t\t\t\t0x0005\nxtensa xtreg\ta6\t\t\t\t\t0x0006\nxtensa xtreg\ta7\t\t\t\t\t0x0007\nxtensa xtreg\ta8\t\t\t\t\t0x0008\nxtensa xtreg\ta9\t\t\t\t\t0x0009\nxtensa xtreg\ta10\t\t\t\t\t0x000a\nxtensa xtreg\ta11\t\t\t\t\t0x000b\nxtensa xtreg\ta12\t\t\t\t\t0x000c\nxtensa xtreg\ta13\t\t\t\t\t0x000d\nxtensa xtreg\ta14\t\t\t\t\t0x000e\nxtensa xtreg\ta15\t\t\t\t\t0x000f\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa-core-nxp_rt600.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# OpenOCD configuration file for Xtensa HiFi DSP in NXP RT600 target\n\n\n#  Core definition and ABI\nxtensa xtdef\tLX\nxtensa xtopt\tarnum           \t32\nxtensa xtopt\twindowed        \t1\n\n\n#  Exception/Interrupt Options\nxtensa xtopt\texceptions      \t1\nxtensa xtopt\thipriints       \t1\nxtensa xtopt\tintlevels       \t4\nxtensa xtopt\texcmlevel       \t2\n\n\n#  Cache Options\nxtensa xtmem\ticache          \t256\t32768\t4\nxtensa xtmem\tdcache          \t256\t65536\t4\t1\n\n\n#  Memory Options\nxtensa xtmem\tiram            \t0x24020000\t65536\nxtensa xtmem\tdram            \t0x24000000\t65536\nxtensa xtmem\tsram            \t0x00000000\t603979776\n\n\n#  Memory Protection/Translation Options\n\n\n#  Debug Options\nxtensa xtopt\tdebuglevel      \t4\nxtensa xtopt\tibreaknum       \t2\nxtensa xtopt\tdbreaknum       \t2\n\n\n#  Core Registers\nxtensa xtregs\t208\nxtensa xtreg\tpc              \t0x0020\nxtensa xtreg\tar0             \t0x0100\nxtensa xtreg\tar1             \t0x0101\nxtensa xtreg\tar2             \t0x0102\nxtensa xtreg\tar3             \t0x0103\nxtensa xtreg\tar4             \t0x0104\nxtensa xtreg\tar5             \t0x0105\nxtensa xtreg\tar6             \t0x0106\nxtensa xtreg\tar7             \t0x0107\nxtensa xtreg\tar8             \t0x0108\nxtensa xtreg\tar9             \t0x0109\nxtensa xtreg\tar10            \t0x010a\nxtensa xtreg\tar11            \t0x010b\nxtensa xtreg\tar12            \t0x010c\nxtensa xtreg\tar13            \t0x010d\nxtensa xtreg\tar14            \t0x010e\nxtensa xtreg\tar15            \t0x010f\nxtensa xtreg\tar16            \t0x0110\nxtensa xtreg\tar17            \t0x0111\nxtensa xtreg\tar18            \t0x0112\nxtensa xtreg\tar19            \t0x0113\nxtensa xtreg\tar20            \t0x0114\nxtensa xtreg\tar21            \t0x0115\nxtensa xtreg\tar22            \t0x0116\nxtensa xtreg\tar23            \t0x0117\nxtensa xtreg\tar24            \t0x0118\nxtensa xtreg\tar25            \t0x0119\nxtensa xtreg\tar26            \t0x011a\nxtensa xtreg\tar27            \t0x011b\nxtensa xtreg\tar28            \t0x011c\nxtensa xtreg\tar29            \t0x011d\nxtensa xtreg\tar30            \t0x011e\nxtensa xtreg\tar31            \t0x011f\nxtensa xtreg\tlbeg            \t0x0200\nxtensa xtreg\tlend            \t0x0201\nxtensa xtreg\tlcount          \t0x0202\nxtensa xtreg\tsar             \t0x0203\nxtensa xtreg\tprefctl         \t0x0228\nxtensa xtreg\twindowbase      \t0x0248\nxtensa xtreg\twindowstart     \t0x0249\nxtensa xtreg\tconfigid0       \t0x02b0\nxtensa xtreg\tconfigid1       \t0x02d0\nxtensa xtreg\tps              \t0x02e6\nxtensa xtreg\tthreadptr       \t0x03e7\nxtensa xtreg\tbr              \t0x0204\nxtensa xtreg\tscompare1       \t0x020c\nxtensa xtreg\tacclo           \t0x0210\nxtensa xtreg\tacchi           \t0x0211\nxtensa xtreg\tm0              \t0x0220\nxtensa xtreg\tm1              \t0x0221\nxtensa xtreg\tm2              \t0x0222\nxtensa xtreg\tm3              \t0x0223\nxtensa xtreg\texpstate        \t0x03e6\nxtensa xtreg\tf64r_lo         \t0x03ea\nxtensa xtreg\tf64r_hi         \t0x03eb\nxtensa xtreg\tf64s            \t0x03ec\nxtensa xtreg\tae_ovf_sar      \t0x03f0\nxtensa xtreg\tae_bithead      \t0x03f1\nxtensa xtreg\tae_ts_fts_bu_bp \t0x03f2\nxtensa xtreg\tae_cw_sd_no     \t0x03f3\nxtensa xtreg\tae_cbegin0      \t0x03f6\nxtensa xtreg\tae_cend0        \t0x03f7\nxtensa xtreg\tae_cbegin1      \t0x03f8\nxtensa xtreg\tae_cend1        \t0x03f9\nxtensa xtreg\taed0            \t0x1010\nxtensa xtreg\taed1            \t0x1011\nxtensa xtreg\taed2            \t0x1012\nxtensa xtreg\taed3            \t0x1013\nxtensa xtreg\taed4            \t0x1014\nxtensa xtreg\taed5            \t0x1015\nxtensa xtreg\taed6            \t0x1016\nxtensa xtreg\taed7            \t0x1017\nxtensa xtreg\taed8            \t0x1018\nxtensa xtreg\taed9            \t0x1019\nxtensa xtreg\taed10           \t0x101a\nxtensa xtreg\taed11           \t0x101b\nxtensa xtreg\taed12           \t0x101c\nxtensa xtreg\taed13           \t0x101d\nxtensa xtreg\taed14           \t0x101e\nxtensa xtreg\taed15           \t0x101f\nxtensa xtreg\tu0              \t0x1020\nxtensa xtreg\tu1              \t0x1021\nxtensa xtreg\tu2              \t0x1022\nxtensa xtreg\tu3              \t0x1023\nxtensa xtreg\taep0            \t0x1024\nxtensa xtreg\taep1            \t0x1025\nxtensa xtreg\taep2            \t0x1026\nxtensa xtreg\taep3            \t0x1027\nxtensa xtreg\tfcr_fsr         \t0x1029\nxtensa xtreg\tmmid            \t0x0259\nxtensa xtreg\tibreakenable    \t0x0260\nxtensa xtreg\tmemctl          \t0x0261\nxtensa xtreg\tatomctl         \t0x0263\nxtensa xtreg\tddr             \t0x0268\nxtensa xtreg\tibreaka0        \t0x0280\nxtensa xtreg\tibreaka1        \t0x0281\nxtensa xtreg\tdbreaka0        \t0x0290\nxtensa xtreg\tdbreaka1        \t0x0291\nxtensa xtreg\tdbreakc0        \t0x02a0\nxtensa xtreg\tdbreakc1        \t0x02a1\nxtensa xtreg\tepc1            \t0x02b1\nxtensa xtreg\tepc2            \t0x02b2\nxtensa xtreg\tepc3            \t0x02b3\nxtensa xtreg\tepc4            \t0x02b4\nxtensa xtreg\tepc5            \t0x02b5\nxtensa xtreg\tdepc            \t0x02c0\nxtensa xtreg\teps2            \t0x02c2\nxtensa xtreg\teps3            \t0x02c3\nxtensa xtreg\teps4            \t0x02c4\nxtensa xtreg\teps5            \t0x02c5\nxtensa xtreg\texcsave1        \t0x02d1\nxtensa xtreg\texcsave2        \t0x02d2\nxtensa xtreg\texcsave3        \t0x02d3\nxtensa xtreg\texcsave4        \t0x02d4\nxtensa xtreg\texcsave5        \t0x02d5\nxtensa xtreg\tcpenable        \t0x02e0\nxtensa xtreg\tinterrupt       \t0x02e2\nxtensa xtreg\tintset          \t0x02e2\nxtensa xtreg\tintclear        \t0x02e3\nxtensa xtreg\tintenable       \t0x02e4\nxtensa xtreg\tvecbase         \t0x02e7\nxtensa xtreg\texccause        \t0x02e8\nxtensa xtreg\tdebugcause      \t0x02e9\nxtensa xtreg\tccount          \t0x02ea\nxtensa xtreg\tprid            \t0x02eb\nxtensa xtreg\ticount          \t0x02ec\nxtensa xtreg\ticountlevel     \t0x02ed\nxtensa xtreg\texcvaddr        \t0x02ee\nxtensa xtreg\tccompare0       \t0x02f0\nxtensa xtreg\tccompare1       \t0x02f1\nxtensa xtreg\tmisc0           \t0x02f4\nxtensa xtreg\tmisc1           \t0x02f5\nxtensa xtreg\tpwrctl          \t0x2024\nxtensa xtreg\tpwrstat         \t0x2025\nxtensa xtreg\teristat         \t0x2026\nxtensa xtreg\tcs_itctrl       \t0x2027\nxtensa xtreg\tcs_claimset     \t0x2028\nxtensa xtreg\tcs_claimclr     \t0x2029\nxtensa xtreg\tcs_lockaccess   \t0x202a\nxtensa xtreg\tcs_lockstatus   \t0x202b\nxtensa xtreg\tcs_authstatus   \t0x202c\nxtensa xtreg\tpmg             \t0x203b\nxtensa xtreg\tpmpc            \t0x203c\nxtensa xtreg\tpm0             \t0x203d\nxtensa xtreg\tpm1             \t0x203e\nxtensa xtreg\tpmctrl0         \t0x203f\nxtensa xtreg\tpmctrl1         \t0x2040\nxtensa xtreg\tpmstat0         \t0x2041\nxtensa xtreg\tpmstat1         \t0x2042\nxtensa xtreg\tocdid           \t0x2043\nxtensa xtreg\tocd_dcrclr      \t0x2044\nxtensa xtreg\tocd_dcrset      \t0x2045\nxtensa xtreg\tocd_dsr         \t0x2046\nxtensa xtreg\ta0              \t0x0000\nxtensa xtreg\ta1              \t0x0001\nxtensa xtreg\ta2              \t0x0002\nxtensa xtreg\ta3              \t0x0003\nxtensa xtreg\ta4              \t0x0004\nxtensa xtreg\ta5              \t0x0005\nxtensa xtreg\ta6              \t0x0006\nxtensa xtreg\ta7              \t0x0007\nxtensa xtreg\ta8              \t0x0008\nxtensa xtreg\ta9              \t0x0009\nxtensa xtreg\ta10             \t0x000a\nxtensa xtreg\ta11             \t0x000b\nxtensa xtreg\ta12             \t0x000c\nxtensa xtreg\ta13             \t0x000d\nxtensa xtreg\ta14             \t0x000e\nxtensa xtreg\ta15             \t0x000f\nxtensa xtreg\tb0              \t0x0010\nxtensa xtreg\tb1              \t0x0011\nxtensa xtreg\tb2              \t0x0012\nxtensa xtreg\tb3              \t0x0013\nxtensa xtreg\tb4              \t0x0014\nxtensa xtreg\tb5              \t0x0015\nxtensa xtreg\tb6              \t0x0016\nxtensa xtreg\tb7              \t0x0017\nxtensa xtreg\tb8              \t0x0018\nxtensa xtreg\tb9              \t0x0019\nxtensa xtreg\tb10             \t0x001a\nxtensa xtreg\tb11             \t0x001b\nxtensa xtreg\tb12             \t0x001c\nxtensa xtreg\tb13             \t0x001d\nxtensa xtreg\tb14             \t0x001e\nxtensa xtreg\tb15             \t0x001f\nxtensa xtreg\tpsintlevel      \t0x2006\nxtensa xtreg\tpsum            \t0x2007\nxtensa xtreg\tpswoe           \t0x2008\nxtensa xtreg\tpsexcm          \t0x2009\nxtensa xtreg\tpscallinc       \t0x200a\nxtensa xtreg\tpsowb           \t0x200b\nxtensa xtreg\tacc             \t0x200c\nxtensa xtreg\tdbnum           \t0x2011\nxtensa xtreg\tae_overflow     \t0x2014\nxtensa xtreg\tae_sar          \t0x2015\nxtensa xtreg\tae_cwrap        \t0x2016\nxtensa xtreg\tae_bitptr       \t0x2017\nxtensa xtreg\tae_bitsused     \t0x2018\nxtensa xtreg\tae_tablesize    \t0x2019\nxtensa xtreg\tae_first_ts     \t0x201a\nxtensa xtreg\tae_nextoffset   \t0x201b\nxtensa xtreg\tae_searchdone   \t0x201c\nxtensa xtreg\troundmode       \t0x201d\nxtensa xtreg\tinvalidflag     \t0x201e\nxtensa xtreg\tdivzeroflag     \t0x201f\nxtensa xtreg\toverflowflag    \t0x2020\nxtensa xtreg\tunderflowflag   \t0x2021\nxtensa xtreg\tinexactflag     \t0x2022\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa-core-xt8.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# OpenOCD configuration file for Xtensa xt8 target\n\n#  Core definition and ABI\nxtensa xtdef\tLX\nxtensa xtopt\tarnum           \t32\nxtensa xtopt\twindowed        \t1\n\n\n#  Exception/Interrupt Options\nxtensa xtopt\texceptions      \t1\nxtensa xtopt\thipriints       \t1\nxtensa xtopt\tintlevels       \t3\nxtensa xtopt\texcmlevel       \t1\n\n\n#  Cache Options\nxtensa xtmem\ticache          \t16\t1024\t1\nxtensa xtmem\tdcache          \t16\t1024\t1\t1\n\n\n#  Memory Options\nxtensa xtmem\tiram            \t0x40000000\t1048576\nxtensa xtmem\tdram            \t0x3ff00000\t262144\nxtensa xtmem\tsrom            \t0x50000000\t131072\nxtensa xtmem\tsram            \t0x60000000\t4194304\n\n\n#  Memory Protection/Translation Options\n\n\n#  Debug Options\nxtensa xtopt\tdebuglevel      \t3\nxtensa xtopt\tibreaknum       \t2\nxtensa xtopt\tdbreaknum       \t2\n\n\n#  Core Registers\nxtensa xtregs\t127\nxtensa xtreg\ta0              \t0x0000\nxtensa xtreg\ta1              \t0x0001\nxtensa xtreg\ta2              \t0x0002\nxtensa xtreg\ta3              \t0x0003\nxtensa xtreg\ta4              \t0x0004\nxtensa xtreg\ta5              \t0x0005\nxtensa xtreg\ta6              \t0x0006\nxtensa xtreg\ta7              \t0x0007\nxtensa xtreg\ta8              \t0x0008\nxtensa xtreg\ta9              \t0x0009\nxtensa xtreg\ta10             \t0x000a\nxtensa xtreg\ta11             \t0x000b\nxtensa xtreg\ta12             \t0x000c\nxtensa xtreg\ta13             \t0x000d\nxtensa xtreg\ta14             \t0x000e\nxtensa xtreg\ta15             \t0x000f\nxtensa xtreg\tpc              \t0x0020\nxtensa xtreg\tar0             \t0x0100\nxtensa xtreg\tar1             \t0x0101\nxtensa xtreg\tar2             \t0x0102\nxtensa xtreg\tar3             \t0x0103\nxtensa xtreg\tar4             \t0x0104\nxtensa xtreg\tar5             \t0x0105\nxtensa xtreg\tar6             \t0x0106\nxtensa xtreg\tar7             \t0x0107\nxtensa xtreg\tar8             \t0x0108\nxtensa xtreg\tar9             \t0x0109\nxtensa xtreg\tar10            \t0x010a\nxtensa xtreg\tar11            \t0x010b\nxtensa xtreg\tar12            \t0x010c\nxtensa xtreg\tar13            \t0x010d\nxtensa xtreg\tar14            \t0x010e\nxtensa xtreg\tar15            \t0x010f\nxtensa xtreg\tar16            \t0x0110\nxtensa xtreg\tar17            \t0x0111\nxtensa xtreg\tar18            \t0x0112\nxtensa xtreg\tar19            \t0x0113\nxtensa xtreg\tar20            \t0x0114\nxtensa xtreg\tar21            \t0x0115\nxtensa xtreg\tar22            \t0x0116\nxtensa xtreg\tar23            \t0x0117\nxtensa xtreg\tar24            \t0x0118\nxtensa xtreg\tar25            \t0x0119\nxtensa xtreg\tar26            \t0x011a\nxtensa xtreg\tar27            \t0x011b\nxtensa xtreg\tar28            \t0x011c\nxtensa xtreg\tar29            \t0x011d\nxtensa xtreg\tar30            \t0x011e\nxtensa xtreg\tar31            \t0x011f\nxtensa xtreg\tlbeg            \t0x0200\nxtensa xtreg\tlend            \t0x0201\nxtensa xtreg\tlcount          \t0x0202\nxtensa xtreg\tsar             \t0x0203\nxtensa xtreg\twindowbase      \t0x0248\nxtensa xtreg\twindowstart     \t0x0249\nxtensa xtreg\tconfigid0       \t0x02b0\nxtensa xtreg\tconfigid1       \t0x02d0\nxtensa xtreg\tps              \t0x02e6\nxtensa xtreg\texpstate        \t0x03e6\nxtensa xtreg\tmmid            \t0x0259\nxtensa xtreg\tibreakenable    \t0x0260\nxtensa xtreg\tddr             \t0x0268\nxtensa xtreg\tibreaka0        \t0x0280\nxtensa xtreg\tibreaka1        \t0x0281\nxtensa xtreg\tdbreaka0        \t0x0290\nxtensa xtreg\tdbreaka1        \t0x0291\nxtensa xtreg\tdbreakc0        \t0x02a0\nxtensa xtreg\tdbreakc1        \t0x02a1\nxtensa xtreg\tepc1            \t0x02b1\nxtensa xtreg\tepc2            \t0x02b2\nxtensa xtreg\tepc3            \t0x02b3\nxtensa xtreg\tdepc            \t0x02c0\nxtensa xtreg\teps2            \t0x02c2\nxtensa xtreg\teps3            \t0x02c3\nxtensa xtreg\texcsave1        \t0x02d1\nxtensa xtreg\texcsave2        \t0x02d2\nxtensa xtreg\texcsave3        \t0x02d3\nxtensa xtreg\tinterrupt       \t0x02e2\nxtensa xtreg\tintset          \t0x02e2\nxtensa xtreg\tintclear        \t0x02e3\nxtensa xtreg\tintenable       \t0x02e4\nxtensa xtreg\texccause        \t0x02e8\nxtensa xtreg\tdebugcause      \t0x02e9\nxtensa xtreg\tccount          \t0x02ea\nxtensa xtreg\ticount          \t0x02ec\nxtensa xtreg\ticountlevel     \t0x02ed\nxtensa xtreg\texcvaddr        \t0x02ee\nxtensa xtreg\tccompare0       \t0x02f0\nxtensa xtreg\tccompare1       \t0x02f1\nxtensa xtreg\tpwrctl          \t0x200f\nxtensa xtreg\tpwrstat         \t0x2010\nxtensa xtreg\teristat         \t0x2011\nxtensa xtreg\tcs_itctrl       \t0x2012\nxtensa xtreg\tcs_claimset     \t0x2013\nxtensa xtreg\tcs_claimclr     \t0x2014\nxtensa xtreg\tcs_lockaccess   \t0x2015\nxtensa xtreg\tcs_lockstatus   \t0x2016\nxtensa xtreg\tcs_authstatus   \t0x2017\nxtensa xtreg\tfault_info      \t0x2026\nxtensa xtreg\ttrax_id         \t0x2027\nxtensa xtreg\ttrax_control    \t0x2028\nxtensa xtreg\ttrax_status     \t0x2029\nxtensa xtreg\ttrax_data       \t0x202a\nxtensa xtreg\ttrax_address    \t0x202b\nxtensa xtreg\ttrax_pctrigger  \t0x202c\nxtensa xtreg\ttrax_pcmatch    \t0x202d\nxtensa xtreg\ttrax_delay      \t0x202e\nxtensa xtreg\ttrax_memstart   \t0x202f\nxtensa xtreg\ttrax_memend     \t0x2030\nxtensa xtreg\tpmg             \t0x203e\nxtensa xtreg\tpmpc            \t0x203f\nxtensa xtreg\tpm0             \t0x2040\nxtensa xtreg\tpm1             \t0x2041\nxtensa xtreg\tpmctrl0         \t0x2042\nxtensa xtreg\tpmctrl1         \t0x2043\nxtensa xtreg\tpmstat0         \t0x2044\nxtensa xtreg\tpmstat1         \t0x2045\nxtensa xtreg\tocdid           \t0x2046\nxtensa xtreg\tocd_dcrclr      \t0x2047\nxtensa xtreg\tocd_dcrset      \t0x2048\nxtensa xtreg\tocd_dsr         \t0x2049\nxtensa xtreg\tpsintlevel      \t0x2003\nxtensa xtreg\tpsum            \t0x2004\nxtensa xtreg\tpswoe           \t0x2005\nxtensa xtreg\tpsexcm          \t0x2006\nxtensa xtreg\tpscallinc       \t0x2007\nxtensa xtreg\tpsowb           \t0x2008\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/xtensa.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n# Target Support for Xtensa Processors\n#\n\nset xtensa_ids { 0x120034e5 0x120134e5\n\t\t\t\t 0x209034e5 0x209134e5 0x209234e5 0x209334e5 0x209434e5 0x209534e5 0x209634e5 0x209734e5\n\t\t\t\t 0x20a034e5 0x20a134e5 0x20a234e5 0x20a334e5 0x20a434e5 0x20a534e5 0x20a634e5 0x20a734e5 0x20a834e5\n\t\t\t\t 0x20b034e5 }\nset expected_xtensa_ids {}\nforeach i $xtensa_ids {\n\tlappend expected_xtensa_ids -expected-id $i\n}\n\nif { [info exists CHIPNAME] } {\n\tset _CHIPNAME $CHIPNAME\n} else {\n\tset _CHIPNAME xtensa\n}\n\nif { [info exists CPUTAPID] } {\n\tset _CPUTAPARGLIST \"-expected-id $CPUTAPID\"\n} else {\n\tset _CPUTAPARGLIST [join $expected_xtensa_ids]\n}\n\nset _TARGETNAME $_CHIPNAME\nset _CPU0NAME cpu\nset _TAPNAME $_CHIPNAME.$_CPU0NAME\n\nif { [info exists XTENSA_DAP] } {\n\tsource [find target/swj-dp.tcl]\n\t# SWD mode ignores the -irlen parameter\n\teval swj_newdap $_CHIPNAME cpu -irlen 4 $_CPUTAPARGLIST\n\tdap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\n\tset _TARGETNAME $_CHIPNAME.cpu\n\tif { [info exists XTENSA_DAP_BASE] } {\n\t\t# Specify fixed offset for accessing XDM via APB behind a DAP interface\n\t\ttarget create $_TARGETNAME xtensa -dap $_CHIPNAME.dap -dbgbase $XTENSA_DAP_BASE\n\t} else {\n\t\ttarget create $_TARGETNAME xtensa -dap $_CHIPNAME.dap\n\t}\n} else {\n\t# JTAG direct (without DAP)\n\teval jtag newtap $_CHIPNAME $_CPU0NAME -irlen 5 $_CPUTAPARGLIST\n\ttarget create $_TARGETNAME xtensa -chain-position $_TAPNAME\n}\n\n$_TARGETNAME configure -event reset-assert-post { soft_reset_halt }\n\ngdb_report_register_access_error enable\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/zynq_7000.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Xilinx Zynq-7000 All Programmable SoC\n#\n# http://www.xilinx.com/products/silicon-devices/soc/zynq-7000/index.htm\n# https://www.xilinx.com/member/forms/download/sim-model-eval-license-xef.html?filename=bsdl_zynq_2.zip\n#\n# 0x03736093  XQ7Z100 XC7Z100I XC7Z100\n# 0x03731093  XQ7Z045 XC7Z045I XC7Z045\n# 0x0372c093  XQ7Z030 XC7Z030I XC7Z030 XA7Z030\n# 0x03727093  XQ7Z020 XC7Z020I XC7Z020 XA7Z020\n# 0x03732093  XC7Z035I XC7Z035\n# 0x0373b093  XC7Z015I XC7Z015\n# 0x03728093  XC7Z014S\n# 0x0373c093  XC7Z012S\n# 0x03722093  XC7Z010I XC7Z010 XA7Z010\n# 0x03723093  XC7Z007S\n\nset _CHIPNAME zynq\nset _TARGETNAME $_CHIPNAME.cpu\n\njtag newtap zynq_pl bs -irlen 6 -ignore-version -ircapture 0x1 -irmask 0x03 \\\n    -expected-id 0x03723093 \\\n    -expected-id 0x03722093 \\\n    -expected-id 0x0373c093 \\\n    -expected-id 0x03728093 \\\n    -expected-id 0x0373B093 \\\n    -expected-id 0x03732093 \\\n    -expected-id 0x03727093 \\\n    -expected-id 0x0372C093 \\\n    -expected-id 0x03731093 \\\n    -expected-id 0x03736093\n\njtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477\n\ndap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu\n\ntarget create ${_TARGETNAME}0 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 0 -dbgbase 0x80090000\ntarget create ${_TARGETNAME}1 cortex_a -dap $_CHIPNAME.dap \\\n    -coreid 1 -dbgbase 0x80092000\ntarget smp ${_TARGETNAME}0 ${_TARGETNAME}1\n\nadapter speed 1000\n\n${_TARGETNAME}0 configure -event reset-assert-post \"cortex_a dbginit\"\n${_TARGETNAME}1 configure -event reset-assert-post \"cortex_a dbginit\"\n\npld create zynq_pl.pld virtex2 -chain-position zynq_pl.bs -no_jstart\nvirtex2 set_user_codes $zynq_pl.pld 0x02 0x03 0x22 0x23\n\nset XC7_JSHUTDOWN 0x0d\nset XC7_JPROGRAM 0x0b\nset XC7_JSTART 0x0c\nset XC7_BYPASS 0x3f\n\nproc zynqpl_program {tap} {\n\techo \"DEPRECATED! use 'virtex2 program ...' not 'zynqpl_program'\"\n\tglobal XC7_JSHUTDOWN XC7_JPROGRAM XC7_JSTART XC7_BYPASS\n\tirscan $tap $XC7_JSHUTDOWN\n\tirscan $tap $XC7_JPROGRAM\n\truntest 60000\n\t#JSTART prevents this from working...\n\t#irscan $tap $XC7_JSTART\n\truntest 2000\n\tirscan $tap $XC7_BYPASS\n\truntest 2000\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/target/к1879xб1я.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# СБИС К1879ХБ1Я\n# http://www.module.ru/catalog/micro/mikroshema_dekodera_cifrovogo_televizionnogo_signala_sbis_k1879hb1ya/\n\nadapter speed 1000\n\nif { [info exists CHIPNAME] } {\n    set _CHIPNAME $CHIPNAME\n} else {\n    set _CHIPNAME к1879хб1я\n}\n\nif { [info exists ENDIAN] } {\n    set _ENDIAN $ENDIAN\n} else {\n    set _ENDIAN little\n}\n\nif { [info exists DSP_TAPID] } {\n    set _DSP_TAPID $DSP_TAPID\n} else {\n    set _DSP_TAPID 0x2b900f0f\n}\n\njtag newtap $_CHIPNAME dsp -irlen 4 -expected-id $_DSP_TAPID\n\nif { [info exists CPU_TAPID] } {\n    set _CPU_TAPID $CPU_TAPID\n} else {\n    set _CPU_TAPID 0x07b76f0f\n}\n\njtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID\n\nset _TARGETNAME $_CHIPNAME.arm\ntarget create $_TARGETNAME arm11 -chain-position $_CHIPNAME.arm\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/test/selftest.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadd_help_text selftest \"run selftest using working ram <tmpfile> <address> <size>\"\n\nproc selftest {tmpfile address size} {\n\n   for {set i 0} {$i < $size } {set i [expr {$i+4}]} {\n       mww [expr {$address+$i}] $i\n   }\n\n   for {set i 0} {$i < 10 } {set i [expr {$i+1}]} {\n    echo \"Test iteration $i\"\n    dump_image $tmpfile $address $size\n\tverify_image $tmpfile $address bin\n\tload_image $tmpfile $address bin\n   }\n\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/test/syntax1.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nadapter srst delay 200\njtag_ntrst_delay 200\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#LPCs need reset pulled while RTCK is low. 0 to activate JTAG, power-on reset is not enough\nadapter assert trst assert srst\nadapter deassert trst deassert srst\n\n#jtag scan chain\n#format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)\njtag newtap lpc2148 one -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4f1f0f0f\n\n#target configuration\n#daemon_startup reset\n\nset _TARGETNAME [format \"%s.cpu\" lpc2148]\ntarget create lpc2148.cpu arm7tdmi -endian little -work-area-size 0x4000 -work-area-phys 0x40000000 -work-area-backup 0\n\n$_TARGETNAME configure -event reset-init {\nsoft_reset_halt\nmvb 0xE01FC040 0x01\n}\n\n\n\nset _FLASHNAME $_CHIPNAME.flash\nflash bank $_FLASHNAME lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/tools/firmware-recovery.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\necho \"\\n\\nFirmware recovery helpers\"\necho \"Use -c firmware_help to get help\\n\"\n\nset known_boards {\n    \"asus-rt-n16\t\tASUS RT-N16\"\n    \"asus-rt-n66u\t\tASUS RT-N66U\"\n    \"linksys-wag200g\t\tLinksys WAG200G\"\n    \"linksys-wrt54gl\t\tLinksys WRT54GL v1.1\"\n    \"netgear-dg834v3\t\tNetgear DG834G v3\"\n    \"tp-link_tl-mr3020\t\tTP-LINK TL-MR3020\"\n    \"bt-homehubv1\t\tBT HomeHub v1\"\n}\n\nproc firmware_help { } {\n    echo \"\nYour OpenOCD command should look like this:\nopenocd -f interface/<jtag adapter>.cfg -f tools/firmware-recovery.tcl -c \\\"<commands>*; shutdown\\\"\n\nWhere:\n<jtag adapter> is one of the supported devices, e.g. ftdi/jtagkey2\n<commands> are firmware-recovery commands separated by semicolon\n\nSupported commands:\nfirmware_help\t\t\tget this help\nlist_boards\t\t\tlist known boards and exit\nboard <name>\t\t\tselect board you work with\nlist_partitions\t\t\tlist partitions of the currently selected board\ndump_part <name> <filename>\tsave partition's contents to a file\nerase_part <name>\t\terase the given partition\nflash_part <name> <filename>\terase, flash and verify the given partition\nram_boot <filename>\t\tload binary file to RAM and run it\nadapter speed <freq>\t\tset JTAG clock frequency in kHz\n\nFor example, to clear nvram and reflash CFE on an RT-N16 using TUMPA, run:\nopenocd -f interface/ftdi/tumpa.cfg -f tools/firmware-recovery.tcl \\\\\n\t-c \\\"board asus-rt-n16; erase_part nvram; flash_part CFE cfe-n16.bin; shutdown\\\"\n\\n\\n\"\n    shutdown\n}\n\n# set default, can be overridden later\nadapter speed 1000\n\nproc get_partition { name } {\n    global partition_list\n    dict get $partition_list $name\n}\n\nproc partition_desc { name } { lindex [get_partition $name] 0 }\nproc partition_start { name } { lindex [get_partition $name] 1 }\nproc partition_size { name } { lindex [get_partition $name] 2 }\n\nproc list_boards { } {\n    global known_boards\n    echo \"List of the supported boards:\\n\"\n    echo \"Board name\\t\\tDescription\"\n    echo \"-----------------------------------\"\n    foreach i $known_boards {\n\techo $i\n    }\n    echo \"\\n\\n\"\n}\n\nproc board { name } {\n    script [find board/$name.cfg]\n}\n\nproc list_partitions { } {\n    global partition_list\n    set fstr \"%-16s%-14s%-14s%s\"\n    echo \"\\nThe currently selected board is known to have these partitions:\\n\"\n    echo [format $fstr Name Start Size Description]\n    echo \"-------------------------------------------------------\"\n    for {set i 0} {$i < [llength $partition_list]} {incr i 2} {\n\tset key [lindex $partition_list $i]\n\techo [format $fstr $key [partition_start $key] [partition_size $key] [partition_desc $key]]\n    }\n    echo \"\\n\\n\"\n}\n\n# Magic to work with any targets, including semi-functional\nproc prepare_target { } {\n    init\n    catch {halt}\n    catch {reset init}\n    catch {halt}\n}\n\nproc dump_part { name filename } {\n    prepare_target\n    dump_image $filename [partition_start $name] [partition_size $name]\n}\n\nproc erase_part { name } {\n    prepare_target\n    flash erase_address [partition_start $name] [partition_size $name]\n}\n\nproc flash_part { name filename } {\n    prepare_target\n    flash write_image erase $filename [partition_start $name] bin\n    echo \"Verifying:\"\n    verify_image $filename [partition_start $name]\n}\n\nproc ram_boot { filename } {\n    global ram_boot_address\n    prepare_target\n    load_image $filename $ram_boot_address bin\n    resume $ram_boot_address\n}\n\necho \"\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/tools/memtest.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Algorithms by Michael Barr, released into public domain\n# Ported to OpenOCD by Shane Volpe, additional fixes by Paul Fertser\n\nset CPU_MAX_ADDRESS 0xFFFFFFFF\nsource [find bitsbytes.tcl]\nsource [find memory.tcl]\n\nproc runAllMemTests { baseAddress nBytes } {\n    memTestDataBus $baseAddress\n    memTestAddressBus $baseAddress $nBytes\n    memTestDevice $baseAddress $nBytes\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDataBus()\n# *\n# * Description: Test the data bus wiring in a memory region by\n# *              performing a walking 1's test at a fixed address\n# *              within that region.  The address (and hence the\n# *              memory region) is selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first pattern that failed.\n# *\n#***********************************************************************************\nproc memTestDataBus { address } {\n    echo \"Running memTestDataBus\"\n\n    for {set i 0} {$i < 32} {incr i} {\n\t# Shift bit\n\tset pattern [expr {1 << $i}]\n\n\t# Write pattern to memory\n\tmemwrite32 $address $pattern\n\n\t# Read pattern from memory\n\tset data [memread32 $address]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATABUS: Address: $address, Pattern: $pattern, Returned: $data\"\n\t    return $pattern\n\t}\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestAddressBus()\n# *\n# * Description: Perform a walking 1's test on the relevant bits\n# *              of the address and check for aliasing.  This test\n# *              will find single-bit address failures such as stuck\n# *              -high, stuck-low, and shorted pins.  The base address\n# *              and size of the region are selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# *\n# * Notes:       For best results, the selected base address should\n# *              have enough LSB 0's to guarantee single address bit\n# *              changes.  For example, to test a 64-Kbyte region,\n# *              select a base address on a 64-Kbyte boundary.  Also,\n# *              select the region size as a power-of-two--if at all\n# *              possible.\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              aliasing problem was uncovered.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestAddressBus { baseAddress nBytes } {\n    set addressMask [expr {$nBytes - 1}]\n    set pattern 0xAAAAAAAA\n    set antipattern 0x55555555\n\n    echo \"Running memTestAddressBus\"\n\n    echo \"addressMask: [convertToHex $addressMask]\"\n\n    echo \"memTestAddressBus: Writing the default pattern at each of the power-of-two offsets...\"\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}] } {\n\tset addr [expr {$baseAddress + $offset}]\n\tmemwrite32 $addr $pattern\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck high...\"\n    memwrite32 $baseAddress $antipattern\n\n    for {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SHIGH: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n    }\n\n    echo \"memTestAddressBus: Checking for address bits stuck low or shorted...\"\n    memwrite32 $baseAddress $pattern\n    for {set testOffset 32} {[expr {$testOffset & $addressMask}] != 0} {set testOffset [expr {$testOffset << 1}] } {\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $antipattern\n\n\tset data [memread32 $baseAddress]\n\tif {$data != $pattern} {\n\t    echo \"FAILED DATA_ADDR_BUS_SLOW: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data]\"\n\t    return $pattern\n\t}\n\n\tfor {set offset 32} {[expr {$offset & $addressMask}] != 0} {set offset [expr {$offset << 1}]} {\n\t    set addr [expr {$baseAddress + $offset}]\n\t    set data [memread32 $baseAddress]\n\n            if {(($data != $pattern) && ($offset != $testOffset))} {\n\t\techo \"FAILED DATA_ADDR_BUS_SLOW2: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset], testOffset [convertToHex $testOffset]\"\n\t\treturn $pattern\n\t    }\n        }\n\tset addr [expr {$baseAddress + $testOffset}]\n\tmemwrite32 $addr $pattern\n    }\n}\n\n#***********************************************************************************\n# *\n# * Function:    memTestDevice()\n# *\n# * Description: Test the integrity of a physical memory device by\n# *              performing an increment/decrement test over the\n# *              entire region.  In the process every storage bit\n# *              in the device is tested as zero and as one.  The\n# *              base address and the size of the region are\n# *              selected by the caller.\n# *\t\t Ported from:\n# *\t\t http://www.netrino.com/Embedded-Systems/How-To/Memory-Test-Suite-C\n# * Notes:\n# *\n# * Returns:     Empty string if the test succeeds.\n# *              A non-zero result is the first address at which an\n# *              incorrect value was read back.  By examining the\n# *              contents of memory, it may be possible to gather\n# *              additional information about the problem.\n# *\n#***********************************************************************************\nproc memTestDevice { baseAddress nBytes } {\n    echo \"Running memTestDevice\"\n\n    echo \"memTestDevice: Filling memory with a known pattern...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tmemwrite32 [expr {$baseAddress + $offset}] $pattern\n    }\n\n    echo \"memTestDevice: Checking each location and inverting it for the second pass...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\n\tif {$data != $pattern} {\n\t    echo \"FAILED memTestDevice_pattern: Address: [convertToHex $addr], Pattern: [convertToHex $pattern], Returned: [convertToHex $data], offset: [convertToHex $offset]\"\n\t    return $pattern\n\t}\n\n\tset antiPattern [expr {~$pattern}]\n\tmemwrite32 [expr {$baseAddress + $offset}] $antiPattern\n    }\n\n    echo \"memTestDevice: Checking each location for the inverted pattern and zeroing it...\"\n    for {set pattern 1; set offset 0} {$offset < $nBytes} {incr pattern; incr offset 32} {\n\tset antiPattern [expr {~$pattern & ((1<<32) - 1)}]\n\tset addr [expr {$baseAddress + $offset}]\n\tset data [memread32 $addr]\n\tset dataHex [convertToHex $data]\n\tset antiPatternHex [convertToHex $antiPattern]\n\tif {$dataHex != $antiPatternHex} {\n\t    echo \"FAILED memTestDevice_antipattern: Address: [convertToHex $addr], antiPattern: $antiPatternHex, Returned: $dataHex, offset: $offset\"\n\t    return $pattern\n\t}\n    }\n}\n\nproc convertToHex { value } {\n    format 0x%08x $value\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tcl/tools/test_cpu_speed.tcl",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Description:\n#  Measure the CPU clock frequency of an ARM Cortex-M based device.\n#\n# Return:\n#  The CPU clock frequency in Hz. A negative value indicates that the loop\n#  counter was saturated.\n#\n# Note:\n#  You may need to adapt the number of cycles for your device.\n#\nadd_help_text cortex_m_test_cpu_speed \"Measure the CPU clock frequency of an ARM Cortex-M based device\"\nadd_usage_text cortex_m_test_cpu_speed {address [timeout [cycles_per_loop]]}\nproc cortex_m_test_cpu_speed { address { timeout 200 } { cycles_per_loop 4 } } {\n\tset loop_counter_start 0xffffffff\n\n\thalt\n\n\t# Backup registers and memory.\n\tset backup_regs [get_reg -force {pc r0 xpsr}]\n\tset backup_mem [read_memory $address 16 3]\n\n\t# We place the following code at the given address to measure the\n\t# CPU clock frequency:\n\t#\n\t# 3801: subs r0, #1\n\t# d1fd: bne #-2\n\t# e7fe: b #-4\n\twrite_memory $address 16 {0x3801 0xd1fd 0xe7fe}\n\n\tset_reg \"pc $address r0 $loop_counter_start\"\n\tresume\n\tsleep $timeout\n\thalt\n\n\t# Get the loop counter value from register r0.\n\tset loop_counter_end [dict values [get_reg r0]]\n\tset loop_counter_diff [expr {$loop_counter_start - $loop_counter_end}]\n\n\t# Restore registers and memory.\n\tset_reg $backup_regs\n\twrite_memory $address 16 $backup_mem\n\n\tif { [expr {$loop_counter_end == 0}] } {\n\t\treturn -1\n\t}\n\n\treturn [expr {double($loop_counter_diff) * $cycles_per_loop / $timeout * 1000}]\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/prj/at91r40008_reset.script",
    "content": "wait_halt\nsleep 10\npoll\n# Ethernut 3 remapping is required to access external flash memory.\nmww 0xffe00000 0x1000213d\nmww 0xffe00004 0x20003e3d\nmww 0xffe00020 0x00000001\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/prj/at91r40008_turtle.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\ngdb_memory_map enable\n# enable flash programming\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Turtelizer JTAG/RS232 Adapter A\"\nft2232_layout turtelizer2\nft2232_vid_pid 0x0403 0xbdc8\njtag_speed 0\njtag_nsrst_delay 200\njtag_ntrst_delay 200\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap at91 cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x3C000 -work-area-size 0x4000 -work-area-backup false\n\ntarget_script 0 reset .\\prj\\at91r40008_reset.script\n\nflash bank cfi 0x10000000 0x400000 2 2 0\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\nmonitor mww 0xFFE00000 0x1000213D\nmonitor mww 0xFFE00004 0x20003E3D\nmonitor mww 0xFFE00020 0x00000001\nmonitor mdw 0xFFE00000 1\nmonitor mdw 0xFFE00004 1\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/prj/ethernut3_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  09.04.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, ethernut3_ram.ld, locate the program in the internal\n * ram of the AT91R40008. For more information about the memory of the \n * AT91R40008 take a look in the AT91 ARM data sheet.\n * Reference is made to Rev. 1354D-ATARM-08/02\n *\n * Take a look at page 15, Memory Map, Figure 3\n */\n \nMEMORY\n{\n  ram : org = 0x00000000, len = 256k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  09.04.06  mifi   First Version\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n          \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include <stdio.h>\n#include <stdlib.h>\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/AT91R40008Test/test_ram.hex",
    "content": ":1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040000000B0000000B4000000B800000074\n:10003000BC00000000000000C0000000C400000080\n:10004000DBF021E37CD09FE5D7F021E378D09FE57A\n:10005000D1F021E374D09FE5D2F021E370D09FE589\n:10006000D3F021E36CD09FE56C109FE56C209FE5F9\n:100070000030A0E3020051E104308114FCFFFF1ABC\n:1000800000000FE1C000C0E300F029E10000A0E3A0\n:100090000010A0E348209FE50FE0A0E112FF2FE150\n:1000A0000000A0E10000A0E10000A0E1FBFFFFEAEA\n:1000B000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEAA8\n:1000C000FEFFFFEAFEFFFFEA000600000005000059\n:1000D0000003000000040000000A00004C010000C2\n:1000E0004C010000E80000000CD04DE20130A0E31C\n:1000F00000308DE50230A0E304308DE50030A0E350\n:1001000008308DE538309FE5002093E500309DE50F\n:10011000023083E000308DE500309DE5013083E260\n:1001200000308DE504309DE5013083E204308DE53B\n:1001300000209DE504309DE5033082E008308DE528\n:0C014000F4FFFFEA480100000700000087\n:0400000300000040B9\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\nmonitor mww 0xE01FC040 0x0002\nmonitor mdw 0xE01FC040\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\nmonitor mww 0xE01FC040 0x0002\nmonitor mdw 0xE01FC040\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/prj/lpc2148_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 3\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap lpc cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup false\n\n#flash bank lpc2000 <base> <size> 0 0 <target#> <variant>\nflash bank lpc2000 0x0 0x7d000 0 0 0 lpc2000_v2 14765 calc_checksum\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/prj/lpc2148_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  18.12.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, olimex_lpcp2148_ram.ld, locate the program in the internal\n * ram of the LPC2148. For more information about the memory of the LPC2148\n * take a look in the LPC2141/2142/2144/2146/2148 USER MANUAL.\n * Reference is made to the user manual from 25 July 2006 Rev. 02\n *\n * Take a look at page 8, section 1.Memory maps\n */\n \nMEMORY\n{\n  ram : org = 0x40000000, len = 32k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/prj/lpc2148_rom.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  26.01.08  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, olimex_lpcp2148_ram.ld, locate the program in the internal\n * ram of the LPC2148. For more information about the memory of the LPC2148\n * take a look in the LPC2141/2142/2144/2146/2148 USER MANUAL.\n * Reference is made to the user manual from 25 July 2006 Rev. 02\n *\n * Take a look at page 8, section 1.Memory maps\n */\n \nMEMORY\n{\n  rom : org = 0x00000000, len = 512k\t\n  ram : org = 0x40000000, len = 32k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > rom\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  31.03.06  mifi   First Version\n*                   This version based on an example from Ethernut and\n*                   \"ARM Cross Development with Eclipse\" from James P. Lynch\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n/*\n * Register Base Address\n */\n          \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   .word 0xB8A06F60\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n/*\n * Wait for the oscillator is stable\n */   \n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   \n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include <stdio.h>\n#include <stdlib.h>\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/test_ram.hex",
    "content": ":020000044000BA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE5606FA0B818F09FE518F09FE515\n:1000200040000040D0000040D4000040D800004014\n:10003000DC00004000000000E0000040E400004060\n:100040000000A0E10000A0E10000A0E10000A0E1AC\n:100050000000A0E10000A0E10000A0E10000A0E19C\n:10006000DBF021E37CD09FE5D7F021E378D09FE55A\n:10007000D1F021E374D09FE5D2F021E370D09FE569\n:10008000D3F021E36CD09FE56C109FE56C209FE5D9\n:100090000030A0E3020051E104308114FCFFFF1A9C\n:1000A00000000FE1C000C0E300F029E10000A0E380\n:1000B0000010A0E348209FE50FE0A0E112FF2FE130\n:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA\n:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88\n:1000E000FEFFFFEAFEFFFFEA0006004000050040B9\n:1000F0000003004000040040000A00406C01004082\n:100100006C010040080100400CD04DE20130A0E33A\n:1001100000308DE50230A0E304308DE50030A0E32F\n:1001200008308DE538309FE5002093E500309DE5EF\n:10013000023083E000308DE500309DE5013083E240\n:1001400000308DE504309DE5013083E204308DE51B\n:1001500000209DE504309DE5033082E008308DE508\n:0C016000F4FFFFEA680100400700000007\n:040000054000004077\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2148Test/test_rom.hex",
    "content": ":1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE5606FA0B818F09FE518F09FE515\n:1000200040000000D0000000D4000000D800000014\n:10003000DC00000000000000E0000000E400000020\n:100040000000A0E10000A0E10000A0E10000A0E1AC\n:100050000000A0E10000A0E10000A0E10000A0E19C\n:10006000DBF021E37CD09FE5D7F021E378D09FE55A\n:10007000D1F021E374D09FE5D2F021E370D09FE569\n:10008000D3F021E36CD09FE56C109FE56C209FE5D9\n:100090000030A0E3020051E104308114FCFFFF1A9C\n:1000A00000000FE1C000C0E300F029E10000A0E380\n:1000B0000010A0E348209FE50FE0A0E112FF2FE130\n:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA\n:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88\n:1000E000FEFFFFEAFEFFFFEA0004004000030040BD\n:1000F00000010040000200400008004000000040F5\n:1001000000000040080100000CD04DE20130A0E3E7\n:1001100000308DE50230A0E304308DE50030A0E32F\n:1001200008308DE538309FE5002093E500309DE5EF\n:10013000023083E000308DE500309DE5013083E240\n:1001400000308DE504309DE5013083E204308DE51B\n:1001500000209DE504309DE5033082E008308DE508\n:0C016000F4FFFFEA680100000700000047\n:0400000300000040B9\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\nmonitor mww 0xE01FC040 0x0002\nmonitor mdw 0xE01FC040\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\nmonitor mww 0xE01FC040 0x0002\nmonitor mdw 0xE01FC040\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/prj/lpc2294_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 3\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap lpc cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x40000000 -work-area-size 0x4000 -work-area-backup false\n\n#flash configuration\n#flash bank lpc2000 <base> <size> 0 0 <target#> <variant>\nflash bank lpc2000 0x0 0x40000 0 0 0 lpc2000_v1 14765 calc_checksum\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/prj/lpc2294_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  31.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, olimex_lpce2294_ram.ld, locate the program in the internal\n * ram of the LPC2294. For more information about the memory of the LPC2294\n * take a look in the LPC2119/2129/2194/2292/2294 USER MANUAL.\n * Reference is made to the user manual from 2004 May 03\n *\n * Take a look at page 48, section 2.Memory Addressing\n */\n \nMEMORY\n{\n  ram : org = 0x40000000, len = 16k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/prj/lpc2294_rom.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  31.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, olimex_lpce2294_ram.ld, locate the program in the internal\n * ram of the LPC2294. For more information about the memory of the LPC2294\n * take a look in the LPC2119/2129/2194/2292/2294 USER MANUAL.\n * Reference is made to the user manual from 2004 May 03\n *\n * Take a look at page 48, section 2.Memory Addressing\n */\n \nMEMORY\n{\n  rom : org = 0x00000000, len = 256k\n  ram : org = 0x40000000, len = 16k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > rom\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  31.03.06  mifi   First Version\n*                   This version based on an example from Ethernut and\n*                   \"ARM Cross Development with Eclipse\" from James P. Lynch\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n/*\n * Register Base Address\n */\n          \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n/*\n * Wait for the oscillator is stable\n */   \n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   \n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include <stdio.h>\n#include <stdlib.h>\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/test_ram.hex",
    "content": ":020000044000BA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040000040D0000040D4000040D800004014\n:10003000DC00004000000000E0000040E400004060\n:100040000000A0E10000A0E10000A0E10000A0E1AC\n:100050000000A0E10000A0E10000A0E10000A0E19C\n:10006000DBF021E37CD09FE5D7F021E378D09FE55A\n:10007000D1F021E374D09FE5D2F021E370D09FE569\n:10008000D3F021E36CD09FE56C109FE56C209FE5D9\n:100090000030A0E3020051E104308114FCFFFF1A9C\n:1000A00000000FE1C000C0E300F029E10000A0E380\n:1000B0000010A0E348209FE50FE0A0E112FF2FE130\n:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA\n:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88\n:1000E000FEFFFFEAFEFFFFEA0006004000050040B9\n:1000F0000003004000040040000A00406C01004082\n:100100006C010040080100400CD04DE20130A0E33A\n:1001100000308DE50230A0E304308DE50030A0E32F\n:1001200008308DE538309FE5002093E500309DE5EF\n:10013000023083E000308DE500309DE5013083E240\n:1001400000308DE504309DE5013083E204308DE51B\n:1001500000209DE504309DE5033082E008308DE508\n:0C016000F4FFFFEA680100400700000007\n:040000054000004077\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/LPC2294Test/test_rom.hex",
    "content": ":1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040000000D0000000D4000000D800000014\n:10003000DC00000000000000E0000000E400000020\n:100040000000A0E10000A0E10000A0E10000A0E1AC\n:100050000000A0E10000A0E10000A0E10000A0E19C\n:10006000DBF021E37CD09FE5D7F021E378D09FE55A\n:10007000D1F021E374D09FE5D2F021E370D09FE569\n:10008000D3F021E36CD09FE56C109FE56C209FE5D9\n:100090000030A0E3020051E104308114FCFFFF1A9C\n:1000A00000000FE1C000C0E300F029E10000A0E380\n:1000B0000010A0E348209FE50FE0A0E112FF2FE130\n:1000C0000000A0E10000A0E10000A0E1FBFFFFEACA\n:1000D000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA88\n:1000E000FEFFFFEAFEFFFFEA0004004000030040BD\n:1000F00000010040000200400008004000000040F5\n:1001000000000040080100000CD04DE20130A0E3E7\n:1001100000308DE50230A0E304308DE50030A0E32F\n:1001200008308DE538309FE5002093E500309DE5EF\n:10013000023083E000308DE500309DE5013083E240\n:1001400000308DE504309DE5013083E204308DE51B\n:1001500000209DE504309DE5033082E008308DE508\n:0C016000F4FFFFEA680100000700000047\n:0400000300000040B9\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/PIC32/BlinkingLeds.c",
    "content": "#include <plib.h>\nint main(void)\n{\n\tint i;\n\tmPORTDClearBits(BIT_0);\n\tmPORTDSetPinsDigitalOut(BIT_0);\n\tmPORTDClearBits(BIT_1);\n\tmPORTDSetPinsDigitalOut(BIT_1);\n\tmPORTDClearBits(BIT_2);\n\tmPORTDSetPinsDigitalOut(BIT_2);\n\n\twhile (1)\n\t{\n\t\tfor (i = 0; i < 500000; i++)\n\t\t\tmPORTDToggleBits(BIT_0);\n\t\tfor (i = 0; i < 500000; i++)\n\t\t\tmPORTDToggleBits(BIT_1);\n\t\tfor (i = 0; i < 500000; i++)\n\t\t\tmPORTDToggleBits(BIT_2);\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/PIC32/readme.txt",
    "content": "Here you'll find a simple example tested with PIC32 Starter kit (source code and .elf file). It will blink repeatedly the LEDs on the board.\nThe program was compiled and written on the target using MPLAB IDE v 8.0 that comes with the kit because openocd is missing currently the ability\nto program the flash for this specific target. It is possible in the future this limitation to be removed.\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\n\n# WDT_MR, disable watchdog \nmonitor mww 0xFFFFFD44 0x00008000\n\n# RSTC_MR, enable user reset\nmonitor mww 0xfffffd08 0xa5000001\n\n# CKGR_MOR\nmonitor mww 0xFFFFFC20 0x00000601\nmonitor sleep 10\n\n# CKGR_PLLR\nmonitor mww 0xFFFFFC2C 0x00481c0e\nmonitor sleep 10\n\n# PMC_MCKR\nmonitor mww 0xFFFFFC30 0x00000007\nmonitor sleep 10\n\n# PMC_IER\nmonitor mww 0xFFFFFF60 0x00480100\nmonitor sleep 100\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\n\n# WDT_MR, disable watchdog \nmonitor mww 0xFFFFFD44 0x00008000\n\n# RSTC_MR, enable user reset\nmonitor mww 0xfffffd08 0xa5000001\n\n# CKGR_MOR\nmonitor mww 0xFFFFFC20 0x00000601\nmonitor sleep 10\n\n# CKGR_PLLR\nmonitor mww 0xFFFFFC2C 0x00481c0e\nmonitor sleep 10\n\n# PMC_MCKR\nmonitor mww 0xFFFFFC30 0x00000007\nmonitor sleep 10\n\n# PMC_IER\nmonitor mww 0xFFFFFF60 0x00480100\nmonitor sleep 100\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/sam7s256_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 0\njtag_nsrst_delay 200\njtag_ntrst_delay 200\n\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap sam7 cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup false\n\ntarget_script 0 reset .\\prj\\sam7s256_reset.script\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank at91sam7 0 0 0 0 0\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/sam7s256_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  30.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n\nMEMORY\n{\n  ram : org = 0x00200000, len = 64k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/sam7s256_reset.script",
    "content": "#\n# Init - taken form the script openocd_at91sam7_ecr.script \n#\n# I take this script from the following page:\n#\n# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html\n#\nmww 0xfffffd44 0x00008000\t# disable watchdog\nmww 0xfffffd08 0xa5000001\t# enable user reset\nmww 0xfffffc20 0x00000601\t# CKGR_MOR : enable the main oscillator\nsleep 10\nmww 0xfffffc2c 0x00481c0e \t# CKGR_PLLR: 96.1097 MHz\nsleep 10\nmww 0xfffffc30 0x00000007\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\nsleep 10\nmww 0xffffff60 0x003c0100\t# MC_FMR: flash mode (FWS=1,FMCN=60)\nsleep 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/prj/sam7s256_rom.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  26.01.08  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n\nMEMORY\n{\n  rom : org = 0x00100000, len = 256k\n  ram : org = 0x00200000, len = 64k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > rom\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/results/607.html",
    "content": "<html>\n<head>\n<title>Test results for revision 607</title>\n</head>\n\n<body>\n<H1>Test cases</H1>\n<H2>Test case results</H2>\nThe test results are stored in seperate documents. One document for\neach subversion number.\n<table border=\"1\">\n       <tr><td>Test results</td><td>comment</td></tr>\n       <tr><td>607</a></td><td></td></tr>\n       <tr><td><a href=\"results/template.html\">template</a></td><td>Test results template</td></tr>\n</table>\n\n<H1>SAM7S64</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"CON001\"/>CON001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Telnet connection</td>\n               <td>Power on, jtag target attached</td>\n               <td>On console, type<br><code>telnet ip port</code></td>\n               <td><code>Open On-Chip Debugger<br>></code></td>\n               <td><code>Open On-Chip Debugger<br>></code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"CON002\"/>CON002</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>GDB server connection</td>\n               <td>Power on, jtag target attached</td>\n               <td>On GDB console, type<br><code>target remote ip:port</code></td>\n               <td><code>Remote debugging using 10.0.0.73:3333</code></td>\n               <td><code>Remote debugging using 10.0.0.73:3333</code></td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES001\"/>RES001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Reset halt on a blank target</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n               <td>\n                       <code>\n                               JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n                               nSRST pulls nTRST, falling back to \"reset run_and_halt\"<br>\n                               target state: halted<br>\n                               target halted in ARM state due to debug request, current mode: Supervisor<br>\n                               cpsr: 0x60000013 pc: 0x00100178\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES002\"/>RES002</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Reset init on a blank target</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset init</code></td>\n               <td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n               <td>\n                       <code>\n                               JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n                               nSRST pulls nTRST, falling back to \"reset run_and_init\"<br>\n                               target state: halted<br>\n                               target halted in ARM state due to debug request, current mode: Supervisor<br>\n                               cpsr: 0x600000d3 pc: 0x00003e24<br>\n                               executing reset script 'event/sam7s256_reset.script'\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES003\"/>RES003</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Reset after a power cycle of the target</td>\n               <td>Reset the target then power cycle the target</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n               <td>\n                       <code>\n                               JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n                               nSRST pulls nTRST, falling back to \"reset run_and_halt\"<br>\n                               target state: halted<br>\n                               target halted in ARM state due to debug request, current mode: Supervisor<br>\n                               cpsr: 0x300000d3 pc: 0x00003a38\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>ZY1000</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"SPD001\"/>RES001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>16MHz on normal operation</td>\n               <td>Reset init the target according to RES002 </td>\n               <td>Exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n               <td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n               <td>\n                       <code>\n                               > jtag_khz 16000<br>\n                               > mdw 0 32<br>\n                               0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG001\"/>DBG001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Load is working</td>\n               <td>Reset init is working, RAM is accesible, GDB server is started</td>\n               <td>On the console of the OS: <br>\n                       <code>arm-elf-gdb test_ram.elf</code><br>\n                       <code>(gdb) target remote ip:port</code><br>\n                       <code>(gdb) load</load>\n               </td>\n               <td>Load should return without error, typical output looks like:<br>\n                       <code>\n                               Loading section .text, size 0x14c lma 0x0<br>\n                               Start address 0x40, load size 332<br>\n                               Transfer rate: 180 bytes/sec, 332 bytes/write.<br>\n                       </code>\n               </td>\n               <td><code>\n                       (gdb) load<br>\n                       Loading section .text, size 0x194 lma 0x200000<br>\n                       Start address 0x200040, load size 404<br>\n                       Transfer rate: 17470 bits/sec, 404 bytes/write.\n               </code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG002\"/>DBG002</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Software breakpoint</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001</td>\n               <td>In the GDB console:<br>\n                       <code>\n                               (gdb) monitor arm7_9 sw_bkpts enable<br>\n                               software breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0xec: file src/main.c, line 71.<br>\n                               (gdb) continue<br>\n                               Continuing.\n                       </code>\n               </td>\n               <td>The software breakpoint should be reached, a typical output looks like:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                               cpsr: 0x000000d3 pc: 0x000000ec<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:71<br>\n                               71        DWORD a = 1;\n                       </code>\n               </td>\n               <td>\n                       <code>\n                               (gdb) break main<br>\n                               Breakpoint 2 at 0x200134: file src/main.c, line 69.<br>\n                               (gdb) c<br>\n                               Continuing.<br>\n                               target state: halted<br>\n                               target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                               cpsr: 0x60000013 pc: 0x00200134<br>\n                               <br>\n                               Breakpoint 2, main () at src/main.c:69<br>\n                               69        DWORD a = 1;\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG003\"/>DBG003</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Single step in a RAM application</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n               <td>In GDB, type <br><code>(gdb) step</code></td>\n               <td>The next instruction should be reached, typical output:<br>\n                       <code>\n                               (gdb) step<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f0<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f4<br>\n                               72        DWORD b = 2;\n                       </code>\n               </td>\n               <td>\n                               <code>\n                               (gdb) step<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f0<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f4<br>\n                               72        DWORD b = 2;\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG004\"/>DBG004</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Software break points are working after a reset</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n               <td>In GDB, type <br><code>\n                       (gdb) monitor reset<br>\n                       (gdb) load<br>\n                       (gdb) continue<br>\n                       </code></td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                               cpsr: 0x000000d3 pc: 0x000000ec<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:71<br>\n                               71        DWORD a = 1;\n                       </code>\n               </td>\n               <td><code>\n                       (gdb) moni reset<br>\n                       JTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n                       target state: halted<br>\n                       target halted in ARM state due to debug request, current mode: Supervisor<br>\n                       cpsr: 0x600000d3 pc: 0x00003e28<br>\n                       executing reset script 'event/sam7s256_reset.script'<br>\n                       (gdb) load<br>\n                       Loading section .text, size 0x194 lma 0x200000<br>\n                       Start address 0x200040, load size 404<br>\n                       Transfer rate: 20455 bits/sec, 404 bytes/write.<br>\n                       (gdb) continue<br>\n                       Continuing.<br>\n                       target state: halted<br>\n                       target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x00200134<br>\n                       <br>\n                       Breakpoint 2, main () at src/main.c:69<br>\n                       69        DWORD a = 1;\n               </code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG005\"/>DBG005</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Hardware breakpoint</td>\n               <td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n               <td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) load<br>\n                               Loading section .text, size 0x194 lma 0x100000<br>\n                               Start address 0x100040, load size 404<br>\n                               Transfer rate: 179 bytes/sec, 404 bytes/write.<br>\n                               (gdb) monitor arm7_9  force_hw_bkpts enable<br>\n                               force hardware breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n                               (gdb) continue<br>\n                       </code>\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                       </code>\n               </td>\n               <td>\n               <code>\n                       (gdb) break main<br>\n                       Breakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n                       (gdb) c<br>\n                       Continuing.<br>\n                       target state: halted<br>\n                       target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x00100134<br>\n                       <br>\n                       Breakpoint 1, main () at src/main.c:69<br>\n                       69        DWORD a = 1;\n               </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG006\"/>DBG006</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Hardware breakpoint is set after a reset</td>\n               <td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n               <td>In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) monitor reg pc 0x100000<br>\n                               pc (/32): 0x00100000<br>\n                               (gdb) continue\n                       </code><br>\n                       where the value inserted in PC is the start address of the application\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                       </code>\n               </td>\n               <td>\n               <code>\n                       Continuing.<br>\n                       target state: halted<br>\n                       target halted in ARM state due to single step, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x00100040<br>\n                       target state: halted<br>\n                       target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x00100134<br>\n                       <br>\n                       Breakpoint 1, main () at src/main.c:69<br>\n                       69        DWORD a = 1;\n               </code><br>\n               <b>Aren't there too many \"halted\" signs?</b>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG007\"/>DBG007</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Single step in ROM</td>\n               <td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n               <td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) load<br>\n                               Loading section .text, size 0x194 lma 0x100000<br>\n                               Start address 0x100040, load size 404<br>\n                               Transfer rate: 179 bytes/sec, 404 bytes/write.<br>\n                               (gdb) monitor arm7_9  force_hw_bkpts enable<br>\n                               force hardware breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n                               (gdb) continue<br>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                               (gdb) step\n                       </code>\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Supervisor<br>\n                               cpsr: 0x60000013 pc: 0x0010013c<br>\n                               70        DWORD b = 2;<br>\n                       </code>\n               </td>\n               <td><code>\n                       (gdb) step<br>\n                       target state: halted<br>\n                       target halted in ARM state due to single step, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x00100138<br>\n                       target state: halted<br>\n                       target halted in ARM state due to single step, current mode: Supervisor<br>\n                       cpsr: 0x60000013 pc: 0x0010013c<br>\n                       70        DWORD b = 2;\n               </code></td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM001\"/>RAM001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>32 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mww ram_address 0xdeadbeef 16<br>\n                                       > mdw ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n                       <code>\n                               > mww 0x0 0xdeadbeef 16<br>\n                               > mdw 0x0 32<br>\n                               0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n                               0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n                       </code>\n               </td>\n               <td>\n               <code>\n                       > mww 0x00200000 0xdeadbeef 16<br>\n                       > mdw 0x00200000 32<br>\n                       0x00200000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                       0x00200020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                       0x00200040: e59f10b4 e3a00902 e5810004 e59f00ac e59f10ac e5810000 e3e010ff e59f00a4<br>\n                       0x00200060: e5810060 e59f10a0 e3e00000 e5810130 e5810124 e321f0db e59fd090 e321f0d7\n               </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM002\"/>RAM002</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>16 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mwh ram_address 0xbeef 16<br>\n                                       > mdh ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n                       <code>\n                               > mwh 0x0 0xbeef 16<br>\n                               > mdh 0x0 32<br>\n                               0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n                               0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n                               >\n                       </code>\n               </td>\n               <td><code>\n                       > mwh 0x00200000 0xbeef 16<br>\n                       > mdh 0x00200000 32<br>\n                       0x00200000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n                       0x00200020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000\n               </code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM003\"/>RAM003</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>8 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mwb ram_address 0xab 16<br>\n                                       > mdb ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n                       <code>\n                               > mwb ram_address 0xab 16<br>\n                               > mdb ram_address 32<br>\n                               0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n                               >\n                       </code>\n               </td>\n               <td><code>\n                       > mwb 0x00200000 0xab 16<br>\n                       > mdb 0x00200000 32<br>\n                       0x00200000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n               </code></td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Actual output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA001\"/>FLA001</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Flash probe</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface:<br>\n                       <code>  > flash probe 0</code>\n               </td>\n               <td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n                       <code>flash 'ecosflash' found at 0x01000000</code>\n               </td>\n               <td>\n               <code>\n                       > flash probe 0<br>\n                       flash 'at91sam7' found at 0x00100000\n               </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA002\"/>FLA002</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>flash fillw</td>\n               <td>Reset init is working, flash is probed</td>\n               <td>On the telnet interface<br>\n                       <code>  > flash fillw 0x1000000 0xdeadbeef 16\n                       </code>\n               </td>\n               <td>The commands should execute without error. The output looks like:<br>\n                       <code>\n                               wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s)\n                       </code><br>\n                       To verify the contents of the flash:<br>\n                       <code>\n                               > mdw 0x1000000 32<br>\n                               0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n                       </code>\n               </td>\n               <td><code>\n                       > flash fillw 0x100000 0xdeadbeef 16<br>\n                       wrote 64 bytes to 0x00100000 in 1.110000s (0.957207 kb/s)<br>\n                       > mdw 0x100000 32<br>\n                       0x00100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                       0x00100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                       0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                       0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n               </code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA003\"/>FLA003</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Flash erase</td>\n               <td>Reset init is working, flash is probed</td>\n               <td>On the telnet interface<br>\n                       <code>  >  flash erase_address 0x1000000 0x2000\n                       </code>\n               </td>\n               <td>The commands should execute without error.<br>\n                       <code>\n                               erased address 0x01000000 length 8192 in 4.970000s\n                       </code>\n                       To check that the flash has been erased, read at different addresses. The result should always be 0xff.\n                       <code>\n                               > mdw 0x1000000 32<br>\n                               0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n                       </code>\n               </td>\n               <td><code>\n                       > flash erase_address 0x100000 0x2000<br>\n                       erased address 0x00100000 length 8192 in 0.510000s<br>\n                       > mdw 0x100000 32<br>\n                       0x00100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                       0x00100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                       0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                       0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                       >\n               </code></td>\n               <td>PASS</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA004\"/>FLA004</td>\n               <td>SAM7S64</td>\n               <td>ZY1000</td>\n               <td>Loading to flash from GDB</td>\n               <td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n               <td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n                               <code>\n                                       (gdb) target remote ip:port<br>\n                                       (gdb) monitor reset<br>\n                                       (gdb) load<br>\n                                       Loading section .text, size 0x194 lma 0x100000<br>\n                                       Start address 0x100040, load size 404<br>\n                                       Transfer rate: 179 bytes/sec, 404 bytes/write.\n                                       (gdb) monitor verify_image path_to_elf_file\n                               </code>\n               </td>\n               <td>The output should look like:<br>\n                       <code>\n                               verified 404 bytes in 5.060000s\n                       </code><br>\n                       The failure message is something like:<br>\n                       <code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n               </td>\n               <td>\n                       <code>\n                               (gdb) load<br>\n                               Loading section .text, size 0x194 lma 0x100000<br>\n                               Start address 0x100040, load size 404<br>\n                               Transfer rate: 1540 bits/sec, 404 bytes/write.<br>\n                               (gdb) monitor verify_image /tftp/10.0.0.9/c:\\workspace/ecosboard/ecosboard/phi/openocd/rep/testing/examples/SAM7S256Test/test_rom.elf<br>\n                               verified 404 bytes in 4.860000s\n                       </code>\n               </td>\n               <td>PASS</td>\n       </tr>\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  18.12.06  mifi   First Version\n*                   The hardware initialization is based on the startup file\n*                   crtat91sam7x256_rom.S from NutOS 4.2.1. \n*                   Therefore partial copyright by egnite Software GmbH.\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n/*\n * Register Base Address\n */\n   AIC_BASE         = 0xFFFFF000\n   AIC_EOICR_OFF    = 0x130\n   AIC_IDCR_OFF     = 0x124\n\n   RSTC_MR          = 0xFFFFFD08\n   RSTC_KEY         = 0xA5000000\n   RSTC_URSTEN      = 0x00000001\n\n   WDT_BASE         = 0xFFFFFD40\n   WDT_MR_OFF       = 0x00000004\n   WDT_WDDIS        = 0x00008000\n\n   MC_BASE          = 0xFFFFFF00\n   MC_FMR_OFF       = 0x00000060\n   MC_FWS_1FWS      = 0x00480100\n      \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n   /*\n    * The watchdog is enabled after processor reset. Disable it.\n    */\n   ldr   r1, =WDT_BASE\n   ldr   r0, =WDT_WDDIS\n   str   r0, [r1, #WDT_MR_OFF]\n\n   \n   /*\n    * Enable user reset: assertion length programmed to 1ms\n    */\n   ldr   r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8))\n   ldr   r1, =RSTC_MR\n   str   r0, [r1, #0]\n\n   \n   /*\n    * Use 2 cycles for flash access.\n    */\n   ldr   r1, =MC_BASE\n   ldr   r0, =MC_FWS_1FWS\n   str   r0, [r1, #MC_FMR_OFF]\n\n\n   /*\n    * Disable all interrupts. Useful for debugging w/o target reset.\n    */\n   ldr   r1, =AIC_BASE\n   mvn   r0, #0\n   str   r0, [r1, #AIC_EOICR_OFF]\n   str   r0, [r1, #AIC_IDCR_OFF]\n\n    \n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/test_ram.hex",
    "content": ":020000040020DA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040002000E4002000E8002000EC00200058\n:10003000F000200000000000F4002000F800200084\n:10004000B4109FE50209A0E3040081E5AC009FE540\n:10005000AC109FE5000081E5FF10E0E3A4009FE500\n:10006000600081E5A0109FE50000E0E3300181E53C\n:10007000240181E5DBF021E390D09FE5D7F021E377\n:100080008CD09FE5D1F021E388D09FE5D2F021E329\n:1000900084D09FE5D3F021E380D09FE580109FE5D9\n:1000A00080209FE50030A0E3020051E1043081147C\n:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF\n:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA\n:1000D00012FF2FE10000A0E10000A0E10000A0E17C\n:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B\n:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13\n:10010000010400A508FDFFFF0001480000F0FFFF0B\n:10011000000620000005200000032000000420004D\n:10012000000A2000940120009401200030012000EA\n:100130000CD04DE20130A0E300308DE50230A0E3A9\n:1001400004308DE50030A0E308308DE538309FE5C0\n:10015000002093E500309DE5023083E000308DE51E\n:1001600000309DE5013083E200308DE504309DE5EF\n:10017000013083E204308DE500209DE504309DE5EB\n:10018000033082E008308DE5F4FFFFEA90012000A3\n:040190000700000064\n:040000050020004097\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7S256Test/test_rom.hex",
    "content": ":020000040010EA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040001000E4001000E8001000EC00100098\n:10003000F000100000000000F4001000F8001000B4\n:10004000B4109FE50209A0E3040081E5AC009FE540\n:10005000AC109FE5000081E5FF10E0E3A4009FE500\n:10006000600081E5A0109FE50000E0E3300181E53C\n:10007000240181E5DBF021E390D09FE5D7F021E377\n:100080008CD09FE5D1F021E388D09FE5D2F021E329\n:1000900084D09FE5D3F021E380D09FE580109FE5D9\n:1000A00080209FE50030A0E3020051E1043081147C\n:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF\n:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA\n:1000D00012FF2FE10000A0E10000A0E10000A0E17C\n:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B\n:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13\n:10010000010400A508FDFFFF0001480000F0FFFF0B\n:100110000004200000032000000120000002200055\n:100120000008200000002000000020003001100026\n:100130000CD04DE20130A0E300308DE50230A0E3A9\n:1001400004308DE50030A0E308308DE538309FE5C0\n:10015000002093E500309DE5023083E000308DE51E\n:1001600000309DE5013083E200308DE504309DE5EF\n:10017000013083E204308DE500209DE504309DE5EB\n:10018000033082E008308DE5F4FFFFEA90011000B3\n:040190000700000064\n:0400000500100040A7\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\n\n# WDT_MR, disable watchdog \nmonitor mww 0xFFFFFD44 0x00008000\n\n# RSTC_MR, enable user reset\nmonitor mww 0xfffffd08 0xa5000001\n\n# CKGR_MOR\nmonitor mww 0xFFFFFC20 0x00000601\nmonitor sleep 10\n\n# CKGR_PLLR\nmonitor mww 0xFFFFFC2C 0x00481c0e\nmonitor sleep 10\n\n# PMC_MCKR\nmonitor mww 0xFFFFFC30 0x00000007\nmonitor sleep 10\n\n# PMC_IER\nmonitor mww 0xFFFFFF60 0x00480100\nmonitor sleep 100\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\n\n# WDT_MR, disable watchdog \nmonitor mww 0xFFFFFD44 0x00008000\n\n# RSTC_MR, enable user reset\nmonitor mww 0xfffffd08 0xa5000001\n\n# CKGR_MOR\nmonitor mww 0xFFFFFC20 0x00000601\nmonitor sleep 10\n\n# CKGR_PLLR\nmonitor mww 0xFFFFFC2C 0x00481c0e\nmonitor sleep 10\n\n# PMC_MCKR\nmonitor mww 0xFFFFFC30 0x00000007\nmonitor sleep 10\n\n# PMC_IER\nmonitor mww 0xFFFFFF60 0x00480100\nmonitor sleep 100\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/sam7x256_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 0\njtag_nsrst_delay 200\njtag_ntrst_delay 200\n\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config srst_only srst_pulls_trst\n\n#jtag scan chain\njtag newtap sam7 cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x00200000 -work-area-size 0x4000 -work-area-backup false\n\ntarget_script 0 reset .\\prj\\sam7x256_reset.script\n\n#flash bank <driver> <base> <size> <chip_width> <bus_width>\nflash bank at91sam7 0 0 0 0 0\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/sam7x256_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  30.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n\nMEMORY\n{\n  ram : org = 0x00200000, len = 64k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/sam7x256_reset.script",
    "content": "#\n# Init - taken form the script openocd_at91sam7_ecr.script \n#\n# I take this script from the following page:\n#\n# http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/openocd_intro/index.html\n#\nmww 0xfffffd44 0x00008000\t# disable watchdog\nmww 0xfffffd08 0xa5000001\t# enable user reset\nmww 0xfffffc20 0x00000601\t# CKGR_MOR : enable the main oscillator\nsleep 10\nmww 0xfffffc2c 0x00481c0e \t# CKGR_PLLR: 96.1097 MHz\nsleep 10\nmww 0xfffffc30 0x00000007\t# PMC_MCKR : MCK = PLL / 2 ~= 48 MHz\nsleep 10\nmww 0xffffff60 0x003c0100\t# MC_FMR: flash mode (FWS=1,FMCN=60)\nsleep 100\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/prj/sam7x256_rom.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  26.01.08  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n\nMEMORY\n{\n  rom : org = 0x00100000, len = 256k\n  ram : org = 0x00200000, len = 64k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > rom\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  18.12.06  mifi   First Version\n*                   The hardware initialization is based on the startup file\n*                   crtat91sam7x256_rom.S from NutOS 4.2.1. \n*                   Therefore partial copyright by egnite Software GmbH.\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode                             */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode                     */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode                 */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode                   */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode          */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode                  */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n/*\n * Register Base Address\n */\n   AIC_BASE         = 0xFFFFF000\n   AIC_EOICR_OFF    = 0x130\n   AIC_IDCR_OFF     = 0x124\n\n   RSTC_MR          = 0xFFFFFD08\n   RSTC_KEY         = 0xA5000000\n   RSTC_URSTEN      = 0x00000001\n\n   WDT_BASE         = 0xFFFFFD40\n   WDT_MR_OFF       = 0x00000004\n   WDT_WDDIS        = 0x00008000\n\n   MC_BASE          = 0xFFFFFF00\n   MC_FMR_OFF       = 0x00000060\n   MC_FWS_1FWS      = 0x00480100\n      \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n   /*\n    * The watchdog is enabled after processor reset. Disable it.\n    */\n   ldr   r1, =WDT_BASE\n   ldr   r0, =WDT_WDDIS\n   str   r0, [r1, #WDT_MR_OFF]\n\n   \n   /*\n    * Enable user reset: assertion length programmed to 1ms\n    */\n   ldr   r0, =(RSTC_KEY | RSTC_URSTEN | (4 << 8))\n   ldr   r1, =RSTC_MR\n   str   r0, [r1, #0]\n\n   \n   /*\n    * Use 2 cycles for flash access.\n    */\n   ldr   r1, =MC_BASE\n   ldr   r0, =MC_FWS_1FWS\n   str   r0, [r1, #MC_FMR_OFF]\n\n\n   /*\n    * Disable all interrupts. Useful for debugging w/o target reset.\n    */\n   ldr   r1, =AIC_BASE\n   mvn   r0, #0\n   str   r0, [r1, #AIC_EOICR_OFF]\n   str   r0, [r1, #AIC_IDCR_OFF]\n\n    \n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/test_ram.hex",
    "content": ":020000040020DA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040002000E4002000E8002000EC00200058\n:10003000F000200000000000F4002000F800200084\n:10004000B4109FE50209A0E3040081E5AC009FE540\n:10005000AC109FE5000081E5FF10E0E3A4009FE500\n:10006000600081E5A0109FE50000E0E3300181E53C\n:10007000240181E5DBF021E390D09FE5D7F021E377\n:100080008CD09FE5D1F021E388D09FE5D2F021E329\n:1000900084D09FE5D3F021E380D09FE580109FE5D9\n:1000A00080209FE50030A0E3020051E1043081147C\n:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF\n:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA\n:1000D00012FF2FE10000A0E10000A0E10000A0E17C\n:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B\n:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13\n:10010000010400A508FDFFFF0001480000F0FFFF0B\n:10011000000620000005200000032000000420004D\n:10012000000A2000940120009401200030012000EA\n:100130000CD04DE20130A0E300308DE50230A0E3A9\n:1001400004308DE50030A0E308308DE538309FE5C0\n:10015000002093E500309DE5023083E000308DE51E\n:1001600000309DE5013083E200308DE504309DE5EF\n:10017000013083E204308DE500209DE504309DE5EB\n:10018000033082E008308DE5F4FFFFEA90012000A3\n:040190000700000064\n:040000050020004097\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/SAM7X256Test/test_rom.hex",
    "content": ":020000040010EA\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:1000200040001000E4001000E8001000EC00100098\n:10003000F000100000000000F4001000F8001000B4\n:10004000B4109FE50209A0E3040081E5AC009FE540\n:10005000AC109FE5000081E5FF10E0E3A4009FE500\n:10006000600081E5A0109FE50000E0E3300181E53C\n:10007000240181E5DBF021E390D09FE5D7F021E377\n:100080008CD09FE5D1F021E388D09FE5D2F021E329\n:1000900084D09FE5D3F021E380D09FE580109FE5D9\n:1000A00080209FE50030A0E3020051E1043081147C\n:1000B000FCFFFF1A00000FE1C000C0E300F029E1DF\n:1000C0000000A0E30010A0E35C209FE50FE0A0E1AA\n:1000D00012FF2FE10000A0E10000A0E10000A0E17C\n:1000E000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA7B\n:1000F000FEFFFFEAFEFFFFEAFEFFFFEA40FDFFFF13\n:10010000010400A508FDFFFF0001480000F0FFFF0B\n:100110000004200000032000000120000002200055\n:100120000008200000002000000020003001100026\n:100130000CD04DE20130A0E300308DE50230A0E3A9\n:1001400004308DE50030A0E308308DE538309FE5C0\n:10015000002093E500309DE5023083E000308DE51E\n:1001600000309DE5013083E200308DE504309DE5EF\n:10017000013083E204308DE500209DE504309DE5EB\n:10018000033082E008308DE5F4FFFFEA90011000B3\n:040190000700000064\n:0400000500100040A7\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STM32-103/readme.txt",
    "content": "Olimex STM32-p103 board.\n\nmain.elf is a file that can be programmed to flash for\ntesting purposes(e.g. test GDB load performance).\n\nhttp://www.olimex.com/dev/stm32-p103.html\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H_ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/prj/eclipse_ft2232_ram.gdb",
    "content": "target remote localhost:3333\n\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\nmonitor mww 0xA0000050 0x01c2\nmonitor mdw 0xA0000050\nmonitor mww 0x6C000004 0x8005\nmonitor mdw 0x6C000004\nmonitor mww 0xE0005000 0xFFFF\nmonitor mww 0xE0005004 0x00FF\nmonitor mww 0xE0005008 0xFFFF\nmonitor mdw 0xE0005000\nmonitor mdw 0xE0005004\nmonitor mdw 0xE0005008\nmonitor mww 0xE000500C 0x0000\n\nmonitor arm7_9 fast_memory_access enable\nmonitor arm7_9 dcc_downloads enable\nmonitor verify_ircapture disable\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/prj/str710_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 0\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap str7 cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup false\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nflash bank str7x 0x40000000 0x00040000 0 0 0 STR71x\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/prj/str7_ram.ld",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  30.03.06  mifi   First Version\n****************************************************************************/\n\n\nENTRY(ResetHandler)\nSEARCH_DIR(.)\n\n/*\n * Define stack size here\n */\nFIQ_STACK_SIZE = 0x0100;\nIRQ_STACK_SIZE = 0x0100;\nABT_STACK_SIZE = 0x0100;\nUND_STACK_SIZE = 0x0100;\nSVC_STACK_SIZE = 0x0400;\n\n/*\n * This file, hitex_str7_ram.ld, locate the program in the internal\n * ram of the STR7. For more information about the memory of the STR7\n * take a look in the STR71X Microcontroller Reference Manual.\n * Reference is made to Rev. 6 March 2005\n *\n * Take a look at page 16, section 2.1.1 Memory Map\n */\n \nMEMORY\n{\n  ram : org = 0x62000000, len = 512k\n}\n\n/*\n * Do not change the next code\n */\nSECTIONS\n{\n  .text :\n  {\n    *(.vectors);\n    . = ALIGN(4);\n    *(.init);\n    . = ALIGN(4);\n    *(.text);\n    . = ALIGN(4);\n    *(.rodata);\n    . = ALIGN(4);\n    *(.rodata*);\n    . = ALIGN(4);\n    *(.glue_7t);\n    . = ALIGN(4);\n    *(.glue_7);\n    . = ALIGN(4);\n    etext = .;\n  } > ram\n\n  .data :\n  {\n    PROVIDE (__data_start = .);\n    *(.data)\n    . = ALIGN(4);\n    edata = .;\n    _edata = .;\n    PROVIDE (__data_end = .);\n  } > ram\n\n  .bss :\n  {\n    PROVIDE (__bss_start = .);\n    *(.bss)\n    *(COMMON)\n    . = ALIGN(4);\n    PROVIDE (__bss_end = .);\n    \n    . = ALIGN(256);\n    \n    PROVIDE (__stack_start = .);\n    \n    PROVIDE (__stack_fiq_start = .);\n    . += FIQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_fiq_end = .);\n\n    PROVIDE (__stack_irq_start = .);\n    . += IRQ_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_irq_end = .);\n\n    PROVIDE (__stack_abt_start = .);\n    . += ABT_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_abt_end = .);\n\n    PROVIDE (__stack_und_start = .);\n    . += UND_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_und_end = .);\n\n    PROVIDE (__stack_svc_start = .);\n    . += SVC_STACK_SIZE;\n    . = ALIGN(4);\n    PROVIDE (__stack_svc_end = .);\n    PROVIDE (__stack_end = .);\n    PROVIDE (__heap_start = .);   \n  } > ram\n    \n}\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without \n*  modification, are permitted provided that the following conditions \n*  are met:\n*  \n*  1. Redistributions of source code must retain the above copyright \n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the \n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may \n*     be used to endorse or promote products derived from this software \n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS \n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL \n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS \n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED \n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, \n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF \n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF \n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  04.03.06  mifi   First Version\n*                   This version based on an example from Ethernut and\n*                   \"ARM Cross Development with Eclipse\" from James P. Lynch\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode \t\t\t\t\t               */ \n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode \t\t\t\t         */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode \t\t\t         */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode \t\t\t         */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode \t\t   */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode \t\t            */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n   \n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n   \n/*\n * Register Base Address\n */\n   PRCCU_BASE     = 0xA0000000\n   RCCU_CFR       = 0x08\n   RCCU_PLL1CR    = 0x18\n   PCU_MDIVR      = 0x40\n   PCU_PDIVR      = 0x44\n   PCU_BOOTCR     = 0x50\n          \n      \n      \n      \n   .section .vectors,\"ax\"\n   .code 32\n        \n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n\n   .section .init, \"ax\"\n   .code 32\n   \n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n/*\n * Wait for the oscillator is stable\n */   \n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   \n/*\n * Setup STR71X, for more information about the register\n * take a look in the STR71x Microcontroller Reference Manual.\n *\n * Reference is made to: Rev. 6 March 2005\n * \n * 1. Map internal RAM to address 0\n *    In this case, we are running always in the RAM\n *    this make no sence. But if we are in flash, we\n *    can copy the interrupt vectors into the ram and\n *    switch to RAM mode.\n *\n * 2. Setup the PLL, the eval board HITEX STR7 is equipped\n *    with an external 16MHz oscillator. We want:\n *\n *    RCLK:  32MHz = (CLK2 * 16) / 4\n *    MCLK:  32Mhz\n *    PCLK1: 32MHz\n *    PCLK2: 32MHz\n *\n */   \n \n   /* \n    * 1. Map RAM to the boot memory 0x00000000\n    */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x01C2          \n   str   r1, [r0, #PCU_BOOTCR] \n   \n   \n   /*\n    * 2. Setup PLL start\n    */\n   \n   /* Set the prescaling factor for APB and APB1 group */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0000             /* no prescaling PCLKx = RCLK */          \n   str   r1, [r0, #PCU_PDIVR] \n\n   /* Set the prescaling factor for the Main System Clock MCLK */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0000             /* no prescaling MCLK = RCLK\n   str   r1, [r0, #PCU_MDIVR] \n   \n   /* Configure the PLL1 ( * 16 , / 4 ) */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0073          \n   str   r1, [r0, #RCCU_PLL1CR]        \n\n   /* Check if the PLL is locked */\npll_lock_loop:\n   ldr   r1, [r0, #RCCU_CFR]\n   tst   r1, #0x0002\n   beq   pll_lock_loop\n   \n   /*  Select PLL1_Output as RCLK clock */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x8009          \n   str   r1, [r0, #RCCU_CFR]        \n   \n   /*\n    * Setup PLL end\n    */\n    \n    \n   /*\n    * Setup a stack for each mode\n    */    \n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */     \n   ldr   sp, =__stack_und_end\n   \n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end\n   \n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */   \n   ldr   sp, =__stack_fiq_end\n   \n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */   \n   ldr   sp, =__stack_irq_end\n   \n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end\n\n\n   /*\n    * Clear .bss section\n    */\n   ldr   r1, =__bss_start\n   ldr   r2, =__bss_end\n   ldr   r3, =0\nbss_clear_loop:\n   cmp   r1, r2\n   strne r3, [r1], #+4\n   bne   bss_clear_loop\n   \n   \n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n   \n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n                       \nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction   \n   \n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n   \nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n   \nIRQHandler:\n   b IRQHandler\n   \nFIQHandler:\n   b FIQHandler\n   \n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const BYTE ConstArray1[128*1024] = {1};\nstatic const BYTE ConstArray2[128*1024] = {2};\nstatic const BYTE ConstArray3[128*1024] = {3};\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710JtagSpeed/test.hex",
    "content": ":02000004620098\n:1000000018F09FE518F09FE518F09FE518F09FE5C0\n:1000100018F09FE518F09FE518F09FE518F09FE5B0\n:100020004000006214010062180100621C010062BD\n:10003000200100620000000024010062280100622B\n:100040000000A0E10000A0E10000A0E10000A0E1AC\n:100050000000A0E10000A0E10000A0E10000A0E19C\n:100060000A02A0E3C0109FE5501080E50A02A0E359\n:100070000010A0E3441080E50A02A0E30010A0E312\n:100080000A02A0E37310A0E3181080E5081090E5C1\n:10009000020011E3FCFFFF0A0A02A0E38C109FE5B7\n:1000A000081080E5DBF021E384D09FE5D7F021E361\n:1000B00080D09FE5D1F021E37CD09FE5D2F021E311\n:1000C00078D09FE5D3F021E374D09FE574109FE5CD\n:1000D00074209FE50030A0E3020051E10430811458\n:1000E000FCFFFF1A00000FE1C000C0E300F029E1AF\n:1000F0000000A0E30010A0E350209FE50FE0A0E186\n:1001000012FF2FE10000A0E10000A0E10000A0E14B\n:10011000FBFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA4A\n:10012000FEFFFFEAFEFFFFEAFEFFFFEAC20100005A\n:1001300009800000000606620005066200030662F0\n:1001400000040662000A06629C0106629C010662C7\n:10015000540100620CD04DE20130A0E300308DE587\n:100160000230A0E304308DE50030A0E308308DE5D7\n:1001700000309DE5013083E200308DE504309DE5DF\n:10018000013083E204308DE500209DE504309DE5DB\n:10019000033082E008308DE5F4FFFFEA0100000043\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620197\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:10019000000000000000000000000000000000005F\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620296\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:10019000000000000000000000000000020000005D\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620395\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:10019000000000000000000000000000000000005F\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620494\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:10019000000000000000000000000000030000005C\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620593\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:10019000000000000000000000000000000000005F\n:1001A000000000000000000000000000000000004F\n:1001B000000000000000000000000000000000003F\n:1001C000000000000000000000000000000000002F\n:1001D000000000000000000000000000000000001F\n:1001E000000000000000000000000000000000000F\n:1001F00000000000000000000000000000000000FF\n:1002000000000000000000000000000000000000EE\n:1002100000000000000000000000000000000000DE\n:1002200000000000000000000000000000000000CE\n:1002300000000000000000000000000000000000BE\n:1002400000000000000000000000000000000000AE\n:10025000000000000000000000000000000000009E\n:10026000000000000000000000000000000000008E\n:10027000000000000000000000000000000000007E\n:10028000000000000000000000000000000000006E\n:10029000000000000000000000000000000000005E\n:1002A000000000000000000000000000000000004E\n:1002B000000000000000000000000000000000003E\n:1002C000000000000000000000000000000000002E\n:1002D000000000000000000000000000000000001E\n:1002E000000000000000000000000000000000000E\n:1002F00000000000000000000000000000000000FE\n:1003000000000000000000000000000000000000ED\n:1003100000000000000000000000000000000000DD\n:1003200000000000000000000000000000000000CD\n:1003300000000000000000000000000000000000BD\n:1003400000000000000000000000000000000000AD\n:10035000000000000000000000000000000000009D\n:10036000000000000000000000000000000000008D\n:10037000000000000000000000000000000000007D\n:10038000000000000000000000000000000000006D\n:10039000000000000000000000000000000000005D\n:1003A000000000000000000000000000000000004D\n:1003B000000000000000000000000000000000003D\n:1003C000000000000000000000000000000000002D\n:1003D000000000000000000000000000000000001D\n:1003E000000000000000000000000000000000000D\n:1003F00000000000000000000000000000000000FD\n:1004000000000000000000000000000000000000EC\n:1004100000000000000000000000000000000000DC\n:1004200000000000000000000000000000000000CC\n:1004300000000000000000000000000000000000BC\n:1004400000000000000000000000000000000000AC\n:10045000000000000000000000000000000000009C\n:10046000000000000000000000000000000000008C\n:10047000000000000000000000000000000000007C\n:10048000000000000000000000000000000000006C\n:10049000000000000000000000000000000000005C\n:1004A000000000000000000000000000000000004C\n:1004B000000000000000000000000000000000003C\n:1004C000000000000000000000000000000000002C\n:1004D000000000000000000000000000000000001C\n:1004E000000000000000000000000000000000000C\n:1004F00000000000000000000000000000000000FC\n:1005000000000000000000000000000000000000EB\n:1005100000000000000000000000000000000000DB\n:1005200000000000000000000000000000000000CB\n:1005300000000000000000000000000000000000BB\n:1005400000000000000000000000000000000000AB\n:10055000000000000000000000000000000000009B\n:10056000000000000000000000000000000000008B\n:10057000000000000000000000000000000000007B\n:10058000000000000000000000000000000000006B\n:10059000000000000000000000000000000000005B\n:1005A000000000000000000000000000000000004B\n:1005B000000000000000000000000000000000003B\n:1005C000000000000000000000000000000000002B\n:1005D000000000000000000000000000000000001B\n:1005E000000000000000000000000000000000000B\n:1005F00000000000000000000000000000000000FB\n:1006000000000000000000000000000000000000EA\n:1006100000000000000000000000000000000000DA\n:1006200000000000000000000000000000000000CA\n:1006300000000000000000000000000000000000BA\n:1006400000000000000000000000000000000000AA\n:10065000000000000000000000000000000000009A\n:10066000000000000000000000000000000000008A\n:10067000000000000000000000000000000000007A\n:10068000000000000000000000000000000000006A\n:10069000000000000000000000000000000000005A\n:1006A000000000000000000000000000000000004A\n:1006B000000000000000000000000000000000003A\n:1006C000000000000000000000000000000000002A\n:1006D000000000000000000000000000000000001A\n:1006E000000000000000000000000000000000000A\n:1006F00000000000000000000000000000000000FA\n:1007000000000000000000000000000000000000E9\n:1007100000000000000000000000000000000000D9\n:1007200000000000000000000000000000000000C9\n:1007300000000000000000000000000000000000B9\n:1007400000000000000000000000000000000000A9\n:100750000000000000000000000000000000000099\n:100760000000000000000000000000000000000089\n:100770000000000000000000000000000000000079\n:100780000000000000000000000000000000000069\n:100790000000000000000000000000000000000059\n:1007A0000000000000000000000000000000000049\n:1007B0000000000000000000000000000000000039\n:1007C0000000000000000000000000000000000029\n:1007D0000000000000000000000000000000000019\n:1007E0000000000000000000000000000000000009\n:1007F00000000000000000000000000000000000F9\n:1008000000000000000000000000000000000000E8\n:1008100000000000000000000000000000000000D8\n:1008200000000000000000000000000000000000C8\n:1008300000000000000000000000000000000000B8\n:1008400000000000000000000000000000000000A8\n:100850000000000000000000000000000000000098\n:100860000000000000000000000000000000000088\n:100870000000000000000000000000000000000078\n:100880000000000000000000000000000000000068\n:100890000000000000000000000000000000000058\n:1008A0000000000000000000000000000000000048\n:1008B0000000000000000000000000000000000038\n:1008C0000000000000000000000000000000000028\n:1008D0000000000000000000000000000000000018\n:1008E0000000000000000000000000000000000008\n:1008F00000000000000000000000000000000000F8\n:1009000000000000000000000000000000000000E7\n:1009100000000000000000000000000000000000D7\n:1009200000000000000000000000000000000000C7\n:1009300000000000000000000000000000000000B7\n:1009400000000000000000000000000000000000A7\n:100950000000000000000000000000000000000097\n:100960000000000000000000000000000000000087\n:100970000000000000000000000000000000000077\n:100980000000000000000000000000000000000067\n:100990000000000000000000000000000000000057\n:1009A0000000000000000000000000000000000047\n:1009B0000000000000000000000000000000000037\n:1009C0000000000000000000000000000000000027\n:1009D0000000000000000000000000000000000017\n:1009E0000000000000000000000000000000000007\n:1009F00000000000000000000000000000000000F7\n:100A000000000000000000000000000000000000E6\n:100A100000000000000000000000000000000000D6\n:100A200000000000000000000000000000000000C6\n:100A300000000000000000000000000000000000B6\n:100A400000000000000000000000000000000000A6\n:100A50000000000000000000000000000000000096\n:100A60000000000000000000000000000000000086\n:100A70000000000000000000000000000000000076\n:100A80000000000000000000000000000000000066\n:100A90000000000000000000000000000000000056\n:100AA0000000000000000000000000000000000046\n:100AB0000000000000000000000000000000000036\n:100AC0000000000000000000000000000000000026\n:100AD0000000000000000000000000000000000016\n:100AE0000000000000000000000000000000000006\n:100AF00000000000000000000000000000000000F6\n:100B000000000000000000000000000000000000E5\n:100B100000000000000000000000000000000000D5\n:100B200000000000000000000000000000000000C5\n:100B300000000000000000000000000000000000B5\n:100B400000000000000000000000000000000000A5\n:100B50000000000000000000000000000000000095\n:100B60000000000000000000000000000000000085\n:100B70000000000000000000000000000000000075\n:100B80000000000000000000000000000000000065\n:100B90000000000000000000000000000000000055\n:100BA0000000000000000000000000000000000045\n:100BB0000000000000000000000000000000000035\n:100BC0000000000000000000000000000000000025\n:100BD0000000000000000000000000000000000015\n:100BE0000000000000000000000000000000000005\n:100BF00000000000000000000000000000000000F5\n:100C000000000000000000000000000000000000E4\n:100C100000000000000000000000000000000000D4\n:100C200000000000000000000000000000000000C4\n:100C300000000000000000000000000000000000B4\n:100C400000000000000000000000000000000000A4\n:100C50000000000000000000000000000000000094\n:100C60000000000000000000000000000000000084\n:100C70000000000000000000000000000000000074\n:100C80000000000000000000000000000000000064\n:100C90000000000000000000000000000000000054\n:100CA0000000000000000000000000000000000044\n:100CB0000000000000000000000000000000000034\n:100CC0000000000000000000000000000000000024\n:100CD0000000000000000000000000000000000014\n:100CE0000000000000000000000000000000000004\n:100CF00000000000000000000000000000000000F4\n:100D000000000000000000000000000000000000E3\n:100D100000000000000000000000000000000000D3\n:100D200000000000000000000000000000000000C3\n:100D300000000000000000000000000000000000B3\n:100D400000000000000000000000000000000000A3\n:100D50000000000000000000000000000000000093\n:100D60000000000000000000000000000000000083\n:100D70000000000000000000000000000000000073\n:100D80000000000000000000000000000000000063\n:100D90000000000000000000000000000000000053\n:100DA0000000000000000000000000000000000043\n:100DB0000000000000000000000000000000000033\n:100DC0000000000000000000000000000000000023\n:100DD0000000000000000000000000000000000013\n:100DE0000000000000000000000000000000000003\n:100DF00000000000000000000000000000000000F3\n:100E000000000000000000000000000000000000E2\n:100E100000000000000000000000000000000000D2\n:100E200000000000000000000000000000000000C2\n:100E300000000000000000000000000000000000B2\n:100E400000000000000000000000000000000000A2\n:100E50000000000000000000000000000000000092\n:100E60000000000000000000000000000000000082\n:100E70000000000000000000000000000000000072\n:100E80000000000000000000000000000000000062\n:100E90000000000000000000000000000000000052\n:100EA0000000000000000000000000000000000042\n:100EB0000000000000000000000000000000000032\n:100EC0000000000000000000000000000000000022\n:100ED0000000000000000000000000000000000012\n:100EE0000000000000000000000000000000000002\n:100EF00000000000000000000000000000000000F2\n:100F000000000000000000000000000000000000E1\n:100F100000000000000000000000000000000000D1\n:100F200000000000000000000000000000000000C1\n:100F300000000000000000000000000000000000B1\n:100F400000000000000000000000000000000000A1\n:100F50000000000000000000000000000000000091\n:100F60000000000000000000000000000000000081\n:100F70000000000000000000000000000000000071\n:100F80000000000000000000000000000000000061\n:100F90000000000000000000000000000000000051\n:100FA0000000000000000000000000000000000041\n:100FB0000000000000000000000000000000000031\n:100FC0000000000000000000000000000000000021\n:100FD0000000000000000000000000000000000011\n:100FE0000000000000000000000000000000000001\n:100FF00000000000000000000000000000000000F1\n:1010000000000000000000000000000000000000E0\n:1010100000000000000000000000000000000000D0\n:1010200000000000000000000000000000000000C0\n:1010300000000000000000000000000000000000B0\n:1010400000000000000000000000000000000000A0\n:101050000000000000000000000000000000000090\n:101060000000000000000000000000000000000080\n:101070000000000000000000000000000000000070\n:101080000000000000000000000000000000000060\n:101090000000000000000000000000000000000050\n:1010A0000000000000000000000000000000000040\n:1010B0000000000000000000000000000000000030\n:1010C0000000000000000000000000000000000020\n:1010D0000000000000000000000000000000000010\n:1010E0000000000000000000000000000000000000\n:1010F00000000000000000000000000000000000F0\n:1011000000000000000000000000000000000000DF\n:1011100000000000000000000000000000000000CF\n:1011200000000000000000000000000000000000BF\n:1011300000000000000000000000000000000000AF\n:10114000000000000000000000000000000000009F\n:10115000000000000000000000000000000000008F\n:10116000000000000000000000000000000000007F\n:10117000000000000000000000000000000000006F\n:10118000000000000000000000000000000000005F\n:10119000000000000000000000000000000000004F\n:1011A000000000000000000000000000000000003F\n:1011B000000000000000000000000000000000002F\n:1011C000000000000000000000000000000000001F\n:1011D000000000000000000000000000000000000F\n:1011E00000000000000000000000000000000000FF\n:1011F00000000000000000000000000000000000EF\n:1012000000000000000000000000000000000000DE\n:1012100000000000000000000000000000000000CE\n:1012200000000000000000000000000000000000BE\n:1012300000000000000000000000000000000000AE\n:10124000000000000000000000000000000000009E\n:10125000000000000000000000000000000000008E\n:10126000000000000000000000000000000000007E\n:10127000000000000000000000000000000000006E\n:10128000000000000000000000000000000000005E\n:10129000000000000000000000000000000000004E\n:1012A000000000000000000000000000000000003E\n:1012B000000000000000000000000000000000002E\n:1012C000000000000000000000000000000000001E\n:1012D000000000000000000000000000000000000E\n:1012E00000000000000000000000000000000000FE\n:1012F00000000000000000000000000000000000EE\n:1013000000000000000000000000000000000000DD\n:1013100000000000000000000000000000000000CD\n:1013200000000000000000000000000000000000BD\n:1013300000000000000000000000000000000000AD\n:10134000000000000000000000000000000000009D\n:10135000000000000000000000000000000000008D\n:10136000000000000000000000000000000000007D\n:10137000000000000000000000000000000000006D\n:10138000000000000000000000000000000000005D\n:10139000000000000000000000000000000000004D\n:1013A000000000000000000000000000000000003D\n:1013B000000000000000000000000000000000002D\n:1013C000000000000000000000000000000000001D\n:1013D000000000000000000000000000000000000D\n:1013E00000000000000000000000000000000000FD\n:1013F00000000000000000000000000000000000ED\n:1014000000000000000000000000000000000000DC\n:1014100000000000000000000000000000000000CC\n:1014200000000000000000000000000000000000BC\n:1014300000000000000000000000000000000000AC\n:10144000000000000000000000000000000000009C\n:10145000000000000000000000000000000000008C\n:10146000000000000000000000000000000000007C\n:10147000000000000000000000000000000000006C\n:10148000000000000000000000000000000000005C\n:10149000000000000000000000000000000000004C\n:1014A000000000000000000000000000000000003C\n:1014B000000000000000000000000000000000002C\n:1014C000000000000000000000000000000000001C\n:1014D000000000000000000000000000000000000C\n:1014E00000000000000000000000000000000000FC\n:1014F00000000000000000000000000000000000EC\n:1015000000000000000000000000000000000000DB\n:1015100000000000000000000000000000000000CB\n:1015200000000000000000000000000000000000BB\n:1015300000000000000000000000000000000000AB\n:10154000000000000000000000000000000000009B\n:10155000000000000000000000000000000000008B\n:10156000000000000000000000000000000000007B\n:10157000000000000000000000000000000000006B\n:10158000000000000000000000000000000000005B\n:10159000000000000000000000000000000000004B\n:1015A000000000000000000000000000000000003B\n:1015B000000000000000000000000000000000002B\n:1015C000000000000000000000000000000000001B\n:1015D000000000000000000000000000000000000B\n:1015E00000000000000000000000000000000000FB\n:1015F00000000000000000000000000000000000EB\n:1016000000000000000000000000000000000000DA\n:1016100000000000000000000000000000000000CA\n:1016200000000000000000000000000000000000BA\n:1016300000000000000000000000000000000000AA\n:10164000000000000000000000000000000000009A\n:10165000000000000000000000000000000000008A\n:10166000000000000000000000000000000000007A\n:10167000000000000000000000000000000000006A\n:10168000000000000000000000000000000000005A\n:10169000000000000000000000000000000000004A\n:1016A000000000000000000000000000000000003A\n:1016B000000000000000000000000000000000002A\n:1016C000000000000000000000000000000000001A\n:1016D000000000000000000000000000000000000A\n:1016E00000000000000000000000000000000000FA\n:1016F00000000000000000000000000000000000EA\n:1017000000000000000000000000000000000000D9\n:1017100000000000000000000000000000000000C9\n:1017200000000000000000000000000000000000B9\n:1017300000000000000000000000000000000000A9\n:101740000000000000000000000000000000000099\n:101750000000000000000000000000000000000089\n:101760000000000000000000000000000000000079\n:101770000000000000000000000000000000000069\n:101780000000000000000000000000000000000059\n:101790000000000000000000000000000000000049\n:1017A0000000000000000000000000000000000039\n:1017B0000000000000000000000000000000000029\n:1017C0000000000000000000000000000000000019\n:1017D0000000000000000000000000000000000009\n:1017E00000000000000000000000000000000000F9\n:1017F00000000000000000000000000000000000E9\n:1018000000000000000000000000000000000000D8\n:1018100000000000000000000000000000000000C8\n:1018200000000000000000000000000000000000B8\n:1018300000000000000000000000000000000000A8\n:101840000000000000000000000000000000000098\n:101850000000000000000000000000000000000088\n:101860000000000000000000000000000000000078\n:101870000000000000000000000000000000000068\n:101880000000000000000000000000000000000058\n:101890000000000000000000000000000000000048\n:1018A0000000000000000000000000000000000038\n:1018B0000000000000000000000000000000000028\n:1018C0000000000000000000000000000000000018\n:1018D0000000000000000000000000000000000008\n:1018E00000000000000000000000000000000000F8\n:1018F00000000000000000000000000000000000E8\n:1019000000000000000000000000000000000000D7\n:1019100000000000000000000000000000000000C7\n:1019200000000000000000000000000000000000B7\n:1019300000000000000000000000000000000000A7\n:101940000000000000000000000000000000000097\n:101950000000000000000000000000000000000087\n:101960000000000000000000000000000000000077\n:101970000000000000000000000000000000000067\n:101980000000000000000000000000000000000057\n:101990000000000000000000000000000000000047\n:1019A0000000000000000000000000000000000037\n:1019B0000000000000000000000000000000000027\n:1019C0000000000000000000000000000000000017\n:1019D0000000000000000000000000000000000007\n:1019E00000000000000000000000000000000000F7\n:1019F00000000000000000000000000000000000E7\n:101A000000000000000000000000000000000000D6\n:101A100000000000000000000000000000000000C6\n:101A200000000000000000000000000000000000B6\n:101A300000000000000000000000000000000000A6\n:101A40000000000000000000000000000000000096\n:101A50000000000000000000000000000000000086\n:101A60000000000000000000000000000000000076\n:101A70000000000000000000000000000000000066\n:101A80000000000000000000000000000000000056\n:101A90000000000000000000000000000000000046\n:101AA0000000000000000000000000000000000036\n:101AB0000000000000000000000000000000000026\n:101AC0000000000000000000000000000000000016\n:101AD0000000000000000000000000000000000006\n:101AE00000000000000000000000000000000000F6\n:101AF00000000000000000000000000000000000E6\n:101B000000000000000000000000000000000000D5\n:101B100000000000000000000000000000000000C5\n:101B200000000000000000000000000000000000B5\n:101B300000000000000000000000000000000000A5\n:101B40000000000000000000000000000000000095\n:101B50000000000000000000000000000000000085\n:101B60000000000000000000000000000000000075\n:101B70000000000000000000000000000000000065\n:101B80000000000000000000000000000000000055\n:101B90000000000000000000000000000000000045\n:101BA0000000000000000000000000000000000035\n:101BB0000000000000000000000000000000000025\n:101BC0000000000000000000000000000000000015\n:101BD0000000000000000000000000000000000005\n:101BE00000000000000000000000000000000000F5\n:101BF00000000000000000000000000000000000E5\n:101C000000000000000000000000000000000000D4\n:101C100000000000000000000000000000000000C4\n:101C200000000000000000000000000000000000B4\n:101C300000000000000000000000000000000000A4\n:101C40000000000000000000000000000000000094\n:101C50000000000000000000000000000000000084\n:101C60000000000000000000000000000000000074\n:101C70000000000000000000000000000000000064\n:101C80000000000000000000000000000000000054\n:101C90000000000000000000000000000000000044\n:101CA0000000000000000000000000000000000034\n:101CB0000000000000000000000000000000000024\n:101CC0000000000000000000000000000000000014\n:101CD0000000000000000000000000000000000004\n:101CE00000000000000000000000000000000000F4\n:101CF00000000000000000000000000000000000E4\n:101D000000000000000000000000000000000000D3\n:101D100000000000000000000000000000000000C3\n:101D200000000000000000000000000000000000B3\n:101D300000000000000000000000000000000000A3\n:101D40000000000000000000000000000000000093\n:101D50000000000000000000000000000000000083\n:101D60000000000000000000000000000000000073\n:101D70000000000000000000000000000000000063\n:101D80000000000000000000000000000000000053\n:101D90000000000000000000000000000000000043\n:101DA0000000000000000000000000000000000033\n:101DB0000000000000000000000000000000000023\n:101DC0000000000000000000000000000000000013\n:101DD0000000000000000000000000000000000003\n:101DE00000000000000000000000000000000000F3\n:101DF00000000000000000000000000000000000E3\n:101E000000000000000000000000000000000000D2\n:101E100000000000000000000000000000000000C2\n:101E200000000000000000000000000000000000B2\n:101E300000000000000000000000000000000000A2\n:101E40000000000000000000000000000000000092\n:101E50000000000000000000000000000000000082\n:101E60000000000000000000000000000000000072\n:101E70000000000000000000000000000000000062\n:101E80000000000000000000000000000000000052\n:101E90000000000000000000000000000000000042\n:101EA0000000000000000000000000000000000032\n:101EB0000000000000000000000000000000000022\n:101EC0000000000000000000000000000000000012\n:101ED0000000000000000000000000000000000002\n:101EE00000000000000000000000000000000000F2\n:101EF00000000000000000000000000000000000E2\n:101F000000000000000000000000000000000000D1\n:101F100000000000000000000000000000000000C1\n:101F200000000000000000000000000000000000B1\n:101F300000000000000000000000000000000000A1\n:101F40000000000000000000000000000000000091\n:101F50000000000000000000000000000000000081\n:101F60000000000000000000000000000000000071\n:101F70000000000000000000000000000000000061\n:101F80000000000000000000000000000000000051\n:101F90000000000000000000000000000000000041\n:101FA0000000000000000000000000000000000031\n:101FB0000000000000000000000000000000000021\n:101FC0000000000000000000000000000000000011\n:101FD0000000000000000000000000000000000001\n:101FE00000000000000000000000000000000000F1\n:101FF00000000000000000000000000000000000E1\n:1020000000000000000000000000000000000000D0\n:1020100000000000000000000000000000000000C0\n:1020200000000000000000000000000000000000B0\n:1020300000000000000000000000000000000000A0\n:102040000000000000000000000000000000000090\n:102050000000000000000000000000000000000080\n:102060000000000000000000000000000000000070\n:102070000000000000000000000000000000000060\n:102080000000000000000000000000000000000050\n:102090000000000000000000000000000000000040\n:1020A0000000000000000000000000000000000030\n:1020B0000000000000000000000000000000000020\n:1020C0000000000000000000000000000000000010\n:1020D0000000000000000000000000000000000000\n:1020E00000000000000000000000000000000000F0\n:1020F00000000000000000000000000000000000E0\n:1021000000000000000000000000000000000000CF\n:1021100000000000000000000000000000000000BF\n:1021200000000000000000000000000000000000AF\n:10213000000000000000000000000000000000009F\n:10214000000000000000000000000000000000008F\n:10215000000000000000000000000000000000007F\n:10216000000000000000000000000000000000006F\n:10217000000000000000000000000000000000005F\n:10218000000000000000000000000000000000004F\n:10219000000000000000000000000000000000003F\n:1021A000000000000000000000000000000000002F\n:1021B000000000000000000000000000000000001F\n:1021C000000000000000000000000000000000000F\n:1021D00000000000000000000000000000000000FF\n:1021E00000000000000000000000000000000000EF\n:1021F00000000000000000000000000000000000DF\n:1022000000000000000000000000000000000000CE\n:1022100000000000000000000000000000000000BE\n:1022200000000000000000000000000000000000AE\n:10223000000000000000000000000000000000009E\n:10224000000000000000000000000000000000008E\n:10225000000000000000000000000000000000007E\n:10226000000000000000000000000000000000006E\n:10227000000000000000000000000000000000005E\n:10228000000000000000000000000000000000004E\n:10229000000000000000000000000000000000003E\n:1022A000000000000000000000000000000000002E\n:1022B000000000000000000000000000000000001E\n:1022C000000000000000000000000000000000000E\n:1022D00000000000000000000000000000000000FE\n:1022E00000000000000000000000000000000000EE\n:1022F00000000000000000000000000000000000DE\n:1023000000000000000000000000000000000000CD\n:1023100000000000000000000000000000000000BD\n:1023200000000000000000000000000000000000AD\n:10233000000000000000000000000000000000009D\n:10234000000000000000000000000000000000008D\n:10235000000000000000000000000000000000007D\n:10236000000000000000000000000000000000006D\n:10237000000000000000000000000000000000005D\n:10238000000000000000000000000000000000004D\n:10239000000000000000000000000000000000003D\n:1023A000000000000000000000000000000000002D\n:1023B000000000000000000000000000000000001D\n:1023C000000000000000000000000000000000000D\n:1023D00000000000000000000000000000000000FD\n:1023E00000000000000000000000000000000000ED\n:1023F00000000000000000000000000000000000DD\n:1024000000000000000000000000000000000000CC\n:1024100000000000000000000000000000000000BC\n:1024200000000000000000000000000000000000AC\n:10243000000000000000000000000000000000009C\n:10244000000000000000000000000000000000008C\n:10245000000000000000000000000000000000007C\n:10246000000000000000000000000000000000006C\n:10247000000000000000000000000000000000005C\n:10248000000000000000000000000000000000004C\n:10249000000000000000000000000000000000003C\n:1024A000000000000000000000000000000000002C\n:1024B000000000000000000000000000000000001C\n:1024C000000000000000000000000000000000000C\n:1024D00000000000000000000000000000000000FC\n:1024E00000000000000000000000000000000000EC\n:1024F00000000000000000000000000000000000DC\n:1025000000000000000000000000000000000000CB\n:1025100000000000000000000000000000000000BB\n:1025200000000000000000000000000000000000AB\n:10253000000000000000000000000000000000009B\n:10254000000000000000000000000000000000008B\n:10255000000000000000000000000000000000007B\n:10256000000000000000000000000000000000006B\n:10257000000000000000000000000000000000005B\n:10258000000000000000000000000000000000004B\n:10259000000000000000000000000000000000003B\n:1025A000000000000000000000000000000000002B\n:1025B000000000000000000000000000000000001B\n:1025C000000000000000000000000000000000000B\n:1025D00000000000000000000000000000000000FB\n:1025E00000000000000000000000000000000000EB\n:1025F00000000000000000000000000000000000DB\n:1026000000000000000000000000000000000000CA\n:1026100000000000000000000000000000000000BA\n:1026200000000000000000000000000000000000AA\n:10263000000000000000000000000000000000009A\n:10264000000000000000000000000000000000008A\n:10265000000000000000000000000000000000007A\n:10266000000000000000000000000000000000006A\n:10267000000000000000000000000000000000005A\n:10268000000000000000000000000000000000004A\n:10269000000000000000000000000000000000003A\n:1026A000000000000000000000000000000000002A\n:1026B000000000000000000000000000000000001A\n:1026C000000000000000000000000000000000000A\n:1026D00000000000000000000000000000000000FA\n:1026E00000000000000000000000000000000000EA\n:1026F00000000000000000000000000000000000DA\n:1027000000000000000000000000000000000000C9\n:1027100000000000000000000000000000000000B9\n:1027200000000000000000000000000000000000A9\n:102730000000000000000000000000000000000099\n:102740000000000000000000000000000000000089\n:102750000000000000000000000000000000000079\n:102760000000000000000000000000000000000069\n:102770000000000000000000000000000000000059\n:102780000000000000000000000000000000000049\n:102790000000000000000000000000000000000039\n:1027A0000000000000000000000000000000000029\n:1027B0000000000000000000000000000000000019\n:1027C0000000000000000000000000000000000009\n:1027D00000000000000000000000000000000000F9\n:1027E00000000000000000000000000000000000E9\n:1027F00000000000000000000000000000000000D9\n:1028000000000000000000000000000000000000C8\n:1028100000000000000000000000000000000000B8\n:1028200000000000000000000000000000000000A8\n:102830000000000000000000000000000000000098\n:102840000000000000000000000000000000000088\n:102850000000000000000000000000000000000078\n:102860000000000000000000000000000000000068\n:102870000000000000000000000000000000000058\n:102880000000000000000000000000000000000048\n:102890000000000000000000000000000000000038\n:1028A0000000000000000000000000000000000028\n:1028B0000000000000000000000000000000000018\n:1028C0000000000000000000000000000000000008\n:1028D00000000000000000000000000000000000F8\n:1028E00000000000000000000000000000000000E8\n:1028F00000000000000000000000000000000000D8\n:1029000000000000000000000000000000000000C7\n:1029100000000000000000000000000000000000B7\n:1029200000000000000000000000000000000000A7\n:102930000000000000000000000000000000000097\n:102940000000000000000000000000000000000087\n:102950000000000000000000000000000000000077\n:102960000000000000000000000000000000000067\n:102970000000000000000000000000000000000057\n:102980000000000000000000000000000000000047\n:102990000000000000000000000000000000000037\n:1029A0000000000000000000000000000000000027\n:1029B0000000000000000000000000000000000017\n:1029C0000000000000000000000000000000000007\n:1029D00000000000000000000000000000000000F7\n:1029E00000000000000000000000000000000000E7\n:1029F00000000000000000000000000000000000D7\n:102A000000000000000000000000000000000000C6\n:102A100000000000000000000000000000000000B6\n:102A200000000000000000000000000000000000A6\n:102A30000000000000000000000000000000000096\n:102A40000000000000000000000000000000000086\n:102A50000000000000000000000000000000000076\n:102A60000000000000000000000000000000000066\n:102A70000000000000000000000000000000000056\n:102A80000000000000000000000000000000000046\n:102A90000000000000000000000000000000000036\n:102AA0000000000000000000000000000000000026\n:102AB0000000000000000000000000000000000016\n:102AC0000000000000000000000000000000000006\n:102AD00000000000000000000000000000000000F6\n:102AE00000000000000000000000000000000000E6\n:102AF00000000000000000000000000000000000D6\n:102B000000000000000000000000000000000000C5\n:102B100000000000000000000000000000000000B5\n:102B200000000000000000000000000000000000A5\n:102B30000000000000000000000000000000000095\n:102B40000000000000000000000000000000000085\n:102B50000000000000000000000000000000000075\n:102B60000000000000000000000000000000000065\n:102B70000000000000000000000000000000000055\n:102B80000000000000000000000000000000000045\n:102B90000000000000000000000000000000000035\n:102BA0000000000000000000000000000000000025\n:102BB0000000000000000000000000000000000015\n:102BC0000000000000000000000000000000000005\n:102BD00000000000000000000000000000000000F5\n:102BE00000000000000000000000000000000000E5\n:102BF00000000000000000000000000000000000D5\n:102C000000000000000000000000000000000000C4\n:102C100000000000000000000000000000000000B4\n:102C200000000000000000000000000000000000A4\n:102C30000000000000000000000000000000000094\n:102C40000000000000000000000000000000000084\n:102C50000000000000000000000000000000000074\n:102C60000000000000000000000000000000000064\n:102C70000000000000000000000000000000000054\n:102C80000000000000000000000000000000000044\n:102C90000000000000000000000000000000000034\n:102CA0000000000000000000000000000000000024\n:102CB0000000000000000000000000000000000014\n:102CC0000000000000000000000000000000000004\n:102CD00000000000000000000000000000000000F4\n:102CE00000000000000000000000000000000000E4\n:102CF00000000000000000000000000000000000D4\n:102D000000000000000000000000000000000000C3\n:102D100000000000000000000000000000000000B3\n:102D200000000000000000000000000000000000A3\n:102D30000000000000000000000000000000000093\n:102D40000000000000000000000000000000000083\n:102D50000000000000000000000000000000000073\n:102D60000000000000000000000000000000000063\n:102D70000000000000000000000000000000000053\n:102D80000000000000000000000000000000000043\n:102D90000000000000000000000000000000000033\n:102DA0000000000000000000000000000000000023\n:102DB0000000000000000000000000000000000013\n:102DC0000000000000000000000000000000000003\n:102DD00000000000000000000000000000000000F3\n:102DE00000000000000000000000000000000000E3\n:102DF00000000000000000000000000000000000D3\n:102E000000000000000000000000000000000000C2\n:102E100000000000000000000000000000000000B2\n:102E200000000000000000000000000000000000A2\n:102E30000000000000000000000000000000000092\n:102E40000000000000000000000000000000000082\n:102E50000000000000000000000000000000000072\n:102E60000000000000000000000000000000000062\n:102E70000000000000000000000000000000000052\n:102E80000000000000000000000000000000000042\n:102E90000000000000000000000000000000000032\n:102EA0000000000000000000000000000000000022\n:102EB0000000000000000000000000000000000012\n:102EC0000000000000000000000000000000000002\n:102ED00000000000000000000000000000000000F2\n:102EE00000000000000000000000000000000000E2\n:102EF00000000000000000000000000000000000D2\n:102F000000000000000000000000000000000000C1\n:102F100000000000000000000000000000000000B1\n:102F200000000000000000000000000000000000A1\n:102F30000000000000000000000000000000000091\n:102F40000000000000000000000000000000000081\n:102F50000000000000000000000000000000000071\n:102F60000000000000000000000000000000000061\n:102F70000000000000000000000000000000000051\n:102F80000000000000000000000000000000000041\n:102F90000000000000000000000000000000000031\n:102FA0000000000000000000000000000000000021\n:102FB0000000000000000000000000000000000011\n:102FC0000000000000000000000000000000000001\n:102FD00000000000000000000000000000000000F1\n:102FE00000000000000000000000000000000000E1\n:102FF00000000000000000000000000000000000D1\n:1030000000000000000000000000000000000000C0\n:1030100000000000000000000000000000000000B0\n:1030200000000000000000000000000000000000A0\n:103030000000000000000000000000000000000090\n:103040000000000000000000000000000000000080\n:103050000000000000000000000000000000000070\n:103060000000000000000000000000000000000060\n:103070000000000000000000000000000000000050\n:103080000000000000000000000000000000000040\n:103090000000000000000000000000000000000030\n:1030A0000000000000000000000000000000000020\n:1030B0000000000000000000000000000000000010\n:1030C0000000000000000000000000000000000000\n:1030D00000000000000000000000000000000000F0\n:1030E00000000000000000000000000000000000E0\n:1030F00000000000000000000000000000000000D0\n:1031000000000000000000000000000000000000BF\n:1031100000000000000000000000000000000000AF\n:10312000000000000000000000000000000000009F\n:10313000000000000000000000000000000000008F\n:10314000000000000000000000000000000000007F\n:10315000000000000000000000000000000000006F\n:10316000000000000000000000000000000000005F\n:10317000000000000000000000000000000000004F\n:10318000000000000000000000000000000000003F\n:10319000000000000000000000000000000000002F\n:1031A000000000000000000000000000000000001F\n:1031B000000000000000000000000000000000000F\n:1031C00000000000000000000000000000000000FF\n:1031D00000000000000000000000000000000000EF\n:1031E00000000000000000000000000000000000DF\n:1031F00000000000000000000000000000000000CF\n:1032000000000000000000000000000000000000BE\n:1032100000000000000000000000000000000000AE\n:10322000000000000000000000000000000000009E\n:10323000000000000000000000000000000000008E\n:10324000000000000000000000000000000000007E\n:10325000000000000000000000000000000000006E\n:10326000000000000000000000000000000000005E\n:10327000000000000000000000000000000000004E\n:10328000000000000000000000000000000000003E\n:10329000000000000000000000000000000000002E\n:1032A000000000000000000000000000000000001E\n:1032B000000000000000000000000000000000000E\n:1032C00000000000000000000000000000000000FE\n:1032D00000000000000000000000000000000000EE\n:1032E00000000000000000000000000000000000DE\n:1032F00000000000000000000000000000000000CE\n:1033000000000000000000000000000000000000BD\n:1033100000000000000000000000000000000000AD\n:10332000000000000000000000000000000000009D\n:10333000000000000000000000000000000000008D\n:10334000000000000000000000000000000000007D\n:10335000000000000000000000000000000000006D\n:10336000000000000000000000000000000000005D\n:10337000000000000000000000000000000000004D\n:10338000000000000000000000000000000000003D\n:10339000000000000000000000000000000000002D\n:1033A000000000000000000000000000000000001D\n:1033B000000000000000000000000000000000000D\n:1033C00000000000000000000000000000000000FD\n:1033D00000000000000000000000000000000000ED\n:1033E00000000000000000000000000000000000DD\n:1033F00000000000000000000000000000000000CD\n:1034000000000000000000000000000000000000BC\n:1034100000000000000000000000000000000000AC\n:10342000000000000000000000000000000000009C\n:10343000000000000000000000000000000000008C\n:10344000000000000000000000000000000000007C\n:10345000000000000000000000000000000000006C\n:10346000000000000000000000000000000000005C\n:10347000000000000000000000000000000000004C\n:10348000000000000000000000000000000000003C\n:10349000000000000000000000000000000000002C\n:1034A000000000000000000000000000000000001C\n:1034B000000000000000000000000000000000000C\n:1034C00000000000000000000000000000000000FC\n:1034D00000000000000000000000000000000000EC\n:1034E00000000000000000000000000000000000DC\n:1034F00000000000000000000000000000000000CC\n:1035000000000000000000000000000000000000BB\n:1035100000000000000000000000000000000000AB\n:10352000000000000000000000000000000000009B\n:10353000000000000000000000000000000000008B\n:10354000000000000000000000000000000000007B\n:10355000000000000000000000000000000000006B\n:10356000000000000000000000000000000000005B\n:10357000000000000000000000000000000000004B\n:10358000000000000000000000000000000000003B\n:10359000000000000000000000000000000000002B\n:1035A000000000000000000000000000000000001B\n:1035B000000000000000000000000000000000000B\n:1035C00000000000000000000000000000000000FB\n:1035D00000000000000000000000000000000000EB\n:1035E00000000000000000000000000000000000DB\n:1035F00000000000000000000000000000000000CB\n:1036000000000000000000000000000000000000BA\n:1036100000000000000000000000000000000000AA\n:10362000000000000000000000000000000000009A\n:10363000000000000000000000000000000000008A\n:10364000000000000000000000000000000000007A\n:10365000000000000000000000000000000000006A\n:10366000000000000000000000000000000000005A\n:10367000000000000000000000000000000000004A\n:10368000000000000000000000000000000000003A\n:10369000000000000000000000000000000000002A\n:1036A000000000000000000000000000000000001A\n:1036B000000000000000000000000000000000000A\n:1036C00000000000000000000000000000000000FA\n:1036D00000000000000000000000000000000000EA\n:1036E00000000000000000000000000000000000DA\n:1036F00000000000000000000000000000000000CA\n:1037000000000000000000000000000000000000B9\n:1037100000000000000000000000000000000000A9\n:103720000000000000000000000000000000000099\n:103730000000000000000000000000000000000089\n:103740000000000000000000000000000000000079\n:103750000000000000000000000000000000000069\n:103760000000000000000000000000000000000059\n:103770000000000000000000000000000000000049\n:103780000000000000000000000000000000000039\n:103790000000000000000000000000000000000029\n:1037A0000000000000000000000000000000000019\n:1037B0000000000000000000000000000000000009\n:1037C00000000000000000000000000000000000F9\n:1037D00000000000000000000000000000000000E9\n:1037E00000000000000000000000000000000000D9\n:1037F00000000000000000000000000000000000C9\n:1038000000000000000000000000000000000000B8\n:1038100000000000000000000000000000000000A8\n:103820000000000000000000000000000000000098\n:103830000000000000000000000000000000000088\n:103840000000000000000000000000000000000078\n:103850000000000000000000000000000000000068\n:103860000000000000000000000000000000000058\n:103870000000000000000000000000000000000048\n:103880000000000000000000000000000000000038\n:103890000000000000000000000000000000000028\n:1038A0000000000000000000000000000000000018\n:1038B0000000000000000000000000000000000008\n:1038C00000000000000000000000000000000000F8\n:1038D00000000000000000000000000000000000E8\n:1038E00000000000000000000000000000000000D8\n:1038F00000000000000000000000000000000000C8\n:1039000000000000000000000000000000000000B7\n:1039100000000000000000000000000000000000A7\n:103920000000000000000000000000000000000097\n:103930000000000000000000000000000000000087\n:103940000000000000000000000000000000000077\n:103950000000000000000000000000000000000067\n:103960000000000000000000000000000000000057\n:103970000000000000000000000000000000000047\n:103980000000000000000000000000000000000037\n:103990000000000000000000000000000000000027\n:1039A0000000000000000000000000000000000017\n:1039B0000000000000000000000000000000000007\n:1039C00000000000000000000000000000000000F7\n:1039D00000000000000000000000000000000000E7\n:1039E00000000000000000000000000000000000D7\n:1039F00000000000000000000000000000000000C7\n:103A000000000000000000000000000000000000B6\n:103A100000000000000000000000000000000000A6\n:103A20000000000000000000000000000000000096\n:103A30000000000000000000000000000000000086\n:103A40000000000000000000000000000000000076\n:103A50000000000000000000000000000000000066\n:103A60000000000000000000000000000000000056\n:103A70000000000000000000000000000000000046\n:103A80000000000000000000000000000000000036\n:103A90000000000000000000000000000000000026\n:103AA0000000000000000000000000000000000016\n:103AB0000000000000000000000000000000000006\n:103AC00000000000000000000000000000000000F6\n:103AD00000000000000000000000000000000000E6\n:103AE00000000000000000000000000000000000D6\n:103AF00000000000000000000000000000000000C6\n:103B000000000000000000000000000000000000B5\n:103B100000000000000000000000000000000000A5\n:103B20000000000000000000000000000000000095\n:103B30000000000000000000000000000000000085\n:103B40000000000000000000000000000000000075\n:103B50000000000000000000000000000000000065\n:103B60000000000000000000000000000000000055\n:103B70000000000000000000000000000000000045\n:103B80000000000000000000000000000000000035\n:103B90000000000000000000000000000000000025\n:103BA0000000000000000000000000000000000015\n:103BB0000000000000000000000000000000000005\n:103BC00000000000000000000000000000000000F5\n:103BD00000000000000000000000000000000000E5\n:103BE00000000000000000000000000000000000D5\n:103BF00000000000000000000000000000000000C5\n:103C000000000000000000000000000000000000B4\n:103C100000000000000000000000000000000000A4\n:103C20000000000000000000000000000000000094\n:103C30000000000000000000000000000000000084\n:103C40000000000000000000000000000000000074\n:103C50000000000000000000000000000000000064\n:103C60000000000000000000000000000000000054\n:103C70000000000000000000000000000000000044\n:103C80000000000000000000000000000000000034\n:103C90000000000000000000000000000000000024\n:103CA0000000000000000000000000000000000014\n:103CB0000000000000000000000000000000000004\n:103CC00000000000000000000000000000000000F4\n:103CD00000000000000000000000000000000000E4\n:103CE00000000000000000000000000000000000D4\n:103CF00000000000000000000000000000000000C4\n:103D000000000000000000000000000000000000B3\n:103D100000000000000000000000000000000000A3\n:103D20000000000000000000000000000000000093\n:103D30000000000000000000000000000000000083\n:103D40000000000000000000000000000000000073\n:103D50000000000000000000000000000000000063\n:103D60000000000000000000000000000000000053\n:103D70000000000000000000000000000000000043\n:103D80000000000000000000000000000000000033\n:103D90000000000000000000000000000000000023\n:103DA0000000000000000000000000000000000013\n:103DB0000000000000000000000000000000000003\n:103DC00000000000000000000000000000000000F3\n:103DD00000000000000000000000000000000000E3\n:103DE00000000000000000000000000000000000D3\n:103DF00000000000000000000000000000000000C3\n:103E000000000000000000000000000000000000B2\n:103E100000000000000000000000000000000000A2\n:103E20000000000000000000000000000000000092\n:103E30000000000000000000000000000000000082\n:103E40000000000000000000000000000000000072\n:103E50000000000000000000000000000000000062\n:103E60000000000000000000000000000000000052\n:103E70000000000000000000000000000000000042\n:103E80000000000000000000000000000000000032\n:103E90000000000000000000000000000000000022\n:103EA0000000000000000000000000000000000012\n:103EB0000000000000000000000000000000000002\n:103EC00000000000000000000000000000000000F2\n:103ED00000000000000000000000000000000000E2\n:103EE00000000000000000000000000000000000D2\n:103EF00000000000000000000000000000000000C2\n:103F000000000000000000000000000000000000B1\n:103F100000000000000000000000000000000000A1\n:103F20000000000000000000000000000000000091\n:103F30000000000000000000000000000000000081\n:103F40000000000000000000000000000000000071\n:103F50000000000000000000000000000000000061\n:103F60000000000000000000000000000000000051\n:103F70000000000000000000000000000000000041\n:103F80000000000000000000000000000000000031\n:103F90000000000000000000000000000000000021\n:103FA0000000000000000000000000000000000011\n:103FB0000000000000000000000000000000000001\n:103FC00000000000000000000000000000000000F1\n:103FD00000000000000000000000000000000000E1\n:103FE00000000000000000000000000000000000D1\n:103FF00000000000000000000000000000000000C1\n:1040000000000000000000000000000000000000B0\n:1040100000000000000000000000000000000000A0\n:104020000000000000000000000000000000000090\n:104030000000000000000000000000000000000080\n:104040000000000000000000000000000000000070\n:104050000000000000000000000000000000000060\n:104060000000000000000000000000000000000050\n:104070000000000000000000000000000000000040\n:104080000000000000000000000000000000000030\n:104090000000000000000000000000000000000020\n:1040A0000000000000000000000000000000000010\n:1040B0000000000000000000000000000000000000\n:1040C00000000000000000000000000000000000F0\n:1040D00000000000000000000000000000000000E0\n:1040E00000000000000000000000000000000000D0\n:1040F00000000000000000000000000000000000C0\n:1041000000000000000000000000000000000000AF\n:10411000000000000000000000000000000000009F\n:10412000000000000000000000000000000000008F\n:10413000000000000000000000000000000000007F\n:10414000000000000000000000000000000000006F\n:10415000000000000000000000000000000000005F\n:10416000000000000000000000000000000000004F\n:10417000000000000000000000000000000000003F\n:10418000000000000000000000000000000000002F\n:10419000000000000000000000000000000000001F\n:1041A000000000000000000000000000000000000F\n:1041B00000000000000000000000000000000000FF\n:1041C00000000000000000000000000000000000EF\n:1041D00000000000000000000000000000000000DF\n:1041E00000000000000000000000000000000000CF\n:1041F00000000000000000000000000000000000BF\n:1042000000000000000000000000000000000000AE\n:10421000000000000000000000000000000000009E\n:10422000000000000000000000000000000000008E\n:10423000000000000000000000000000000000007E\n:10424000000000000000000000000000000000006E\n:10425000000000000000000000000000000000005E\n:10426000000000000000000000000000000000004E\n:10427000000000000000000000000000000000003E\n:10428000000000000000000000000000000000002E\n:10429000000000000000000000000000000000001E\n:1042A000000000000000000000000000000000000E\n:1042B00000000000000000000000000000000000FE\n:1042C00000000000000000000000000000000000EE\n:1042D00000000000000000000000000000000000DE\n:1042E00000000000000000000000000000000000CE\n:1042F00000000000000000000000000000000000BE\n:1043000000000000000000000000000000000000AD\n:10431000000000000000000000000000000000009D\n:10432000000000000000000000000000000000008D\n:10433000000000000000000000000000000000007D\n:10434000000000000000000000000000000000006D\n:10435000000000000000000000000000000000005D\n:10436000000000000000000000000000000000004D\n:10437000000000000000000000000000000000003D\n:10438000000000000000000000000000000000002D\n:10439000000000000000000000000000000000001D\n:1043A000000000000000000000000000000000000D\n:1043B00000000000000000000000000000000000FD\n:1043C00000000000000000000000000000000000ED\n:1043D00000000000000000000000000000000000DD\n:1043E00000000000000000000000000000000000CD\n:1043F00000000000000000000000000000000000BD\n:1044000000000000000000000000000000000000AC\n:10441000000000000000000000000000000000009C\n:10442000000000000000000000000000000000008C\n:10443000000000000000000000000000000000007C\n:10444000000000000000000000000000000000006C\n:10445000000000000000000000000000000000005C\n:10446000000000000000000000000000000000004C\n:10447000000000000000000000000000000000003C\n:10448000000000000000000000000000000000002C\n:10449000000000000000000000000000000000001C\n:1044A000000000000000000000000000000000000C\n:1044B00000000000000000000000000000000000FC\n:1044C00000000000000000000000000000000000EC\n:1044D00000000000000000000000000000000000DC\n:1044E00000000000000000000000000000000000CC\n:1044F00000000000000000000000000000000000BC\n:1045000000000000000000000000000000000000AB\n:10451000000000000000000000000000000000009B\n:10452000000000000000000000000000000000008B\n:10453000000000000000000000000000000000007B\n:10454000000000000000000000000000000000006B\n:10455000000000000000000000000000000000005B\n:10456000000000000000000000000000000000004B\n:10457000000000000000000000000000000000003B\n:10458000000000000000000000000000000000002B\n:10459000000000000000000000000000000000001B\n:1045A000000000000000000000000000000000000B\n:1045B00000000000000000000000000000000000FB\n:1045C00000000000000000000000000000000000EB\n:1045D00000000000000000000000000000000000DB\n:1045E00000000000000000000000000000000000CB\n:1045F00000000000000000000000000000000000BB\n:1046000000000000000000000000000000000000AA\n:10461000000000000000000000000000000000009A\n:10462000000000000000000000000000000000008A\n:10463000000000000000000000000000000000007A\n:10464000000000000000000000000000000000006A\n:10465000000000000000000000000000000000005A\n:10466000000000000000000000000000000000004A\n:10467000000000000000000000000000000000003A\n:10468000000000000000000000000000000000002A\n:10469000000000000000000000000000000000001A\n:1046A000000000000000000000000000000000000A\n:1046B00000000000000000000000000000000000FA\n:1046C00000000000000000000000000000000000EA\n:1046D00000000000000000000000000000000000DA\n:1046E00000000000000000000000000000000000CA\n:1046F00000000000000000000000000000000000BA\n:1047000000000000000000000000000000000000A9\n:104710000000000000000000000000000000000099\n:104720000000000000000000000000000000000089\n:104730000000000000000000000000000000000079\n:104740000000000000000000000000000000000069\n:104750000000000000000000000000000000000059\n:104760000000000000000000000000000000000049\n:104770000000000000000000000000000000000039\n:104780000000000000000000000000000000000029\n:104790000000000000000000000000000000000019\n:1047A0000000000000000000000000000000000009\n:1047B00000000000000000000000000000000000F9\n:1047C00000000000000000000000000000000000E9\n:1047D00000000000000000000000000000000000D9\n:1047E00000000000000000000000000000000000C9\n:1047F00000000000000000000000000000000000B9\n:1048000000000000000000000000000000000000A8\n:104810000000000000000000000000000000000098\n:104820000000000000000000000000000000000088\n:104830000000000000000000000000000000000078\n:104840000000000000000000000000000000000068\n:104850000000000000000000000000000000000058\n:104860000000000000000000000000000000000048\n:104870000000000000000000000000000000000038\n:104880000000000000000000000000000000000028\n:104890000000000000000000000000000000000018\n:1048A0000000000000000000000000000000000008\n:1048B00000000000000000000000000000000000F8\n:1048C00000000000000000000000000000000000E8\n:1048D00000000000000000000000000000000000D8\n:1048E00000000000000000000000000000000000C8\n:1048F00000000000000000000000000000000000B8\n:1049000000000000000000000000000000000000A7\n:104910000000000000000000000000000000000097\n:104920000000000000000000000000000000000087\n:104930000000000000000000000000000000000077\n:104940000000000000000000000000000000000067\n:104950000000000000000000000000000000000057\n:104960000000000000000000000000000000000047\n:104970000000000000000000000000000000000037\n:104980000000000000000000000000000000000027\n:104990000000000000000000000000000000000017\n:1049A0000000000000000000000000000000000007\n:1049B00000000000000000000000000000000000F7\n:1049C00000000000000000000000000000000000E7\n:1049D00000000000000000000000000000000000D7\n:1049E00000000000000000000000000000000000C7\n:1049F00000000000000000000000000000000000B7\n:104A000000000000000000000000000000000000A6\n:104A10000000000000000000000000000000000096\n:104A20000000000000000000000000000000000086\n:104A30000000000000000000000000000000000076\n:104A40000000000000000000000000000000000066\n:104A50000000000000000000000000000000000056\n:104A60000000000000000000000000000000000046\n:104A70000000000000000000000000000000000036\n:104A80000000000000000000000000000000000026\n:104A90000000000000000000000000000000000016\n:104AA0000000000000000000000000000000000006\n:104AB00000000000000000000000000000000000F6\n:104AC00000000000000000000000000000000000E6\n:104AD00000000000000000000000000000000000D6\n:104AE00000000000000000000000000000000000C6\n:104AF00000000000000000000000000000000000B6\n:104B000000000000000000000000000000000000A5\n:104B10000000000000000000000000000000000095\n:104B20000000000000000000000000000000000085\n:104B30000000000000000000000000000000000075\n:104B40000000000000000000000000000000000065\n:104B50000000000000000000000000000000000055\n:104B60000000000000000000000000000000000045\n:104B70000000000000000000000000000000000035\n:104B80000000000000000000000000000000000025\n:104B90000000000000000000000000000000000015\n:104BA0000000000000000000000000000000000005\n:104BB00000000000000000000000000000000000F5\n:104BC00000000000000000000000000000000000E5\n:104BD00000000000000000000000000000000000D5\n:104BE00000000000000000000000000000000000C5\n:104BF00000000000000000000000000000000000B5\n:104C000000000000000000000000000000000000A4\n:104C10000000000000000000000000000000000094\n:104C20000000000000000000000000000000000084\n:104C30000000000000000000000000000000000074\n:104C40000000000000000000000000000000000064\n:104C50000000000000000000000000000000000054\n:104C60000000000000000000000000000000000044\n:104C70000000000000000000000000000000000034\n:104C80000000000000000000000000000000000024\n:104C90000000000000000000000000000000000014\n:104CA0000000000000000000000000000000000004\n:104CB00000000000000000000000000000000000F4\n:104CC00000000000000000000000000000000000E4\n:104CD00000000000000000000000000000000000D4\n:104CE00000000000000000000000000000000000C4\n:104CF00000000000000000000000000000000000B4\n:104D000000000000000000000000000000000000A3\n:104D10000000000000000000000000000000000093\n:104D20000000000000000000000000000000000083\n:104D30000000000000000000000000000000000073\n:104D40000000000000000000000000000000000063\n:104D50000000000000000000000000000000000053\n:104D60000000000000000000000000000000000043\n:104D70000000000000000000000000000000000033\n:104D80000000000000000000000000000000000023\n:104D90000000000000000000000000000000000013\n:104DA0000000000000000000000000000000000003\n:104DB00000000000000000000000000000000000F3\n:104DC00000000000000000000000000000000000E3\n:104DD00000000000000000000000000000000000D3\n:104DE00000000000000000000000000000000000C3\n:104DF00000000000000000000000000000000000B3\n:104E000000000000000000000000000000000000A2\n:104E10000000000000000000000000000000000092\n:104E20000000000000000000000000000000000082\n:104E30000000000000000000000000000000000072\n:104E40000000000000000000000000000000000062\n:104E50000000000000000000000000000000000052\n:104E60000000000000000000000000000000000042\n:104E70000000000000000000000000000000000032\n:104E80000000000000000000000000000000000022\n:104E90000000000000000000000000000000000012\n:104EA0000000000000000000000000000000000002\n:104EB00000000000000000000000000000000000F2\n:104EC00000000000000000000000000000000000E2\n:104ED00000000000000000000000000000000000D2\n:104EE00000000000000000000000000000000000C2\n:104EF00000000000000000000000000000000000B2\n:104F000000000000000000000000000000000000A1\n:104F10000000000000000000000000000000000091\n:104F20000000000000000000000000000000000081\n:104F30000000000000000000000000000000000071\n:104F40000000000000000000000000000000000061\n:104F50000000000000000000000000000000000051\n:104F60000000000000000000000000000000000041\n:104F70000000000000000000000000000000000031\n:104F80000000000000000000000000000000000021\n:104F90000000000000000000000000000000000011\n:104FA0000000000000000000000000000000000001\n:104FB00000000000000000000000000000000000F1\n:104FC00000000000000000000000000000000000E1\n:104FD00000000000000000000000000000000000D1\n:104FE00000000000000000000000000000000000C1\n:104FF00000000000000000000000000000000000B1\n:1050000000000000000000000000000000000000A0\n:105010000000000000000000000000000000000090\n:105020000000000000000000000000000000000080\n:105030000000000000000000000000000000000070\n:105040000000000000000000000000000000000060\n:105050000000000000000000000000000000000050\n:105060000000000000000000000000000000000040\n:105070000000000000000000000000000000000030\n:105080000000000000000000000000000000000020\n:105090000000000000000000000000000000000010\n:1050A0000000000000000000000000000000000000\n:1050B00000000000000000000000000000000000F0\n:1050C00000000000000000000000000000000000E0\n:1050D00000000000000000000000000000000000D0\n:1050E00000000000000000000000000000000000C0\n:1050F00000000000000000000000000000000000B0\n:10510000000000000000000000000000000000009F\n:10511000000000000000000000000000000000008F\n:10512000000000000000000000000000000000007F\n:10513000000000000000000000000000000000006F\n:10514000000000000000000000000000000000005F\n:10515000000000000000000000000000000000004F\n:10516000000000000000000000000000000000003F\n:10517000000000000000000000000000000000002F\n:10518000000000000000000000000000000000001F\n:10519000000000000000000000000000000000000F\n:1051A00000000000000000000000000000000000FF\n:1051B00000000000000000000000000000000000EF\n:1051C00000000000000000000000000000000000DF\n:1051D00000000000000000000000000000000000CF\n:1051E00000000000000000000000000000000000BF\n:1051F00000000000000000000000000000000000AF\n:10520000000000000000000000000000000000009E\n:10521000000000000000000000000000000000008E\n:10522000000000000000000000000000000000007E\n:10523000000000000000000000000000000000006E\n:10524000000000000000000000000000000000005E\n:10525000000000000000000000000000000000004E\n:10526000000000000000000000000000000000003E\n:10527000000000000000000000000000000000002E\n:10528000000000000000000000000000000000001E\n:10529000000000000000000000000000000000000E\n:1052A00000000000000000000000000000000000FE\n:1052B00000000000000000000000000000000000EE\n:1052C00000000000000000000000000000000000DE\n:1052D00000000000000000000000000000000000CE\n:1052E00000000000000000000000000000000000BE\n:1052F00000000000000000000000000000000000AE\n:10530000000000000000000000000000000000009D\n:10531000000000000000000000000000000000008D\n:10532000000000000000000000000000000000007D\n:10533000000000000000000000000000000000006D\n:10534000000000000000000000000000000000005D\n:10535000000000000000000000000000000000004D\n:10536000000000000000000000000000000000003D\n:10537000000000000000000000000000000000002D\n:10538000000000000000000000000000000000001D\n:10539000000000000000000000000000000000000D\n:1053A00000000000000000000000000000000000FD\n:1053B00000000000000000000000000000000000ED\n:1053C00000000000000000000000000000000000DD\n:1053D00000000000000000000000000000000000CD\n:1053E00000000000000000000000000000000000BD\n:1053F00000000000000000000000000000000000AD\n:10540000000000000000000000000000000000009C\n:10541000000000000000000000000000000000008C\n:10542000000000000000000000000000000000007C\n:10543000000000000000000000000000000000006C\n:10544000000000000000000000000000000000005C\n:10545000000000000000000000000000000000004C\n:10546000000000000000000000000000000000003C\n:10547000000000000000000000000000000000002C\n:10548000000000000000000000000000000000001C\n:10549000000000000000000000000000000000000C\n:1054A00000000000000000000000000000000000FC\n:1054B00000000000000000000000000000000000EC\n:1054C00000000000000000000000000000000000DC\n:1054D00000000000000000000000000000000000CC\n:1054E00000000000000000000000000000000000BC\n:1054F00000000000000000000000000000000000AC\n:10550000000000000000000000000000000000009B\n:10551000000000000000000000000000000000008B\n:10552000000000000000000000000000000000007B\n:10553000000000000000000000000000000000006B\n:10554000000000000000000000000000000000005B\n:10555000000000000000000000000000000000004B\n:10556000000000000000000000000000000000003B\n:10557000000000000000000000000000000000002B\n:10558000000000000000000000000000000000001B\n:10559000000000000000000000000000000000000B\n:1055A00000000000000000000000000000000000FB\n:1055B00000000000000000000000000000000000EB\n:1055C00000000000000000000000000000000000DB\n:1055D00000000000000000000000000000000000CB\n:1055E00000000000000000000000000000000000BB\n:1055F00000000000000000000000000000000000AB\n:10560000000000000000000000000000000000009A\n:10561000000000000000000000000000000000008A\n:10562000000000000000000000000000000000007A\n:10563000000000000000000000000000000000006A\n:10564000000000000000000000000000000000005A\n:10565000000000000000000000000000000000004A\n:10566000000000000000000000000000000000003A\n:10567000000000000000000000000000000000002A\n:10568000000000000000000000000000000000001A\n:10569000000000000000000000000000000000000A\n:1056A00000000000000000000000000000000000FA\n:1056B00000000000000000000000000000000000EA\n:1056C00000000000000000000000000000000000DA\n:1056D00000000000000000000000000000000000CA\n:1056E00000000000000000000000000000000000BA\n:1056F00000000000000000000000000000000000AA\n:105700000000000000000000000000000000000099\n:105710000000000000000000000000000000000089\n:105720000000000000000000000000000000000079\n:105730000000000000000000000000000000000069\n:105740000000000000000000000000000000000059\n:105750000000000000000000000000000000000049\n:105760000000000000000000000000000000000039\n:105770000000000000000000000000000000000029\n:105780000000000000000000000000000000000019\n:105790000000000000000000000000000000000009\n:1057A00000000000000000000000000000000000F9\n:1057B00000000000000000000000000000000000E9\n:1057C00000000000000000000000000000000000D9\n:1057D00000000000000000000000000000000000C9\n:1057E00000000000000000000000000000000000B9\n:1057F00000000000000000000000000000000000A9\n:105800000000000000000000000000000000000098\n:105810000000000000000000000000000000000088\n:105820000000000000000000000000000000000078\n:105830000000000000000000000000000000000068\n:105840000000000000000000000000000000000058\n:105850000000000000000000000000000000000048\n:105860000000000000000000000000000000000038\n:105870000000000000000000000000000000000028\n:105880000000000000000000000000000000000018\n:105890000000000000000000000000000000000008\n:1058A00000000000000000000000000000000000F8\n:1058B00000000000000000000000000000000000E8\n:1058C00000000000000000000000000000000000D8\n:1058D00000000000000000000000000000000000C8\n:1058E00000000000000000000000000000000000B8\n:1058F00000000000000000000000000000000000A8\n:105900000000000000000000000000000000000097\n:105910000000000000000000000000000000000087\n:105920000000000000000000000000000000000077\n:105930000000000000000000000000000000000067\n:105940000000000000000000000000000000000057\n:105950000000000000000000000000000000000047\n:105960000000000000000000000000000000000037\n:105970000000000000000000000000000000000027\n:105980000000000000000000000000000000000017\n:105990000000000000000000000000000000000007\n:1059A00000000000000000000000000000000000F7\n:1059B00000000000000000000000000000000000E7\n:1059C00000000000000000000000000000000000D7\n:1059D00000000000000000000000000000000000C7\n:1059E00000000000000000000000000000000000B7\n:1059F00000000000000000000000000000000000A7\n:105A00000000000000000000000000000000000096\n:105A10000000000000000000000000000000000086\n:105A20000000000000000000000000000000000076\n:105A30000000000000000000000000000000000066\n:105A40000000000000000000000000000000000056\n:105A50000000000000000000000000000000000046\n:105A60000000000000000000000000000000000036\n:105A70000000000000000000000000000000000026\n:105A80000000000000000000000000000000000016\n:105A90000000000000000000000000000000000006\n:105AA00000000000000000000000000000000000F6\n:105AB00000000000000000000000000000000000E6\n:105AC00000000000000000000000000000000000D6\n:105AD00000000000000000000000000000000000C6\n:105AE00000000000000000000000000000000000B6\n:105AF00000000000000000000000000000000000A6\n:105B00000000000000000000000000000000000095\n:105B10000000000000000000000000000000000085\n:105B20000000000000000000000000000000000075\n:105B30000000000000000000000000000000000065\n:105B40000000000000000000000000000000000055\n:105B50000000000000000000000000000000000045\n:105B60000000000000000000000000000000000035\n:105B70000000000000000000000000000000000025\n:105B80000000000000000000000000000000000015\n:105B90000000000000000000000000000000000005\n:105BA00000000000000000000000000000000000F5\n:105BB00000000000000000000000000000000000E5\n:105BC00000000000000000000000000000000000D5\n:105BD00000000000000000000000000000000000C5\n:105BE00000000000000000000000000000000000B5\n:105BF00000000000000000000000000000000000A5\n:105C00000000000000000000000000000000000094\n:105C10000000000000000000000000000000000084\n:105C20000000000000000000000000000000000074\n:105C30000000000000000000000000000000000064\n:105C40000000000000000000000000000000000054\n:105C50000000000000000000000000000000000044\n:105C60000000000000000000000000000000000034\n:105C70000000000000000000000000000000000024\n:105C80000000000000000000000000000000000014\n:105C90000000000000000000000000000000000004\n:105CA00000000000000000000000000000000000F4\n:105CB00000000000000000000000000000000000E4\n:105CC00000000000000000000000000000000000D4\n:105CD00000000000000000000000000000000000C4\n:105CE00000000000000000000000000000000000B4\n:105CF00000000000000000000000000000000000A4\n:105D00000000000000000000000000000000000093\n:105D10000000000000000000000000000000000083\n:105D20000000000000000000000000000000000073\n:105D30000000000000000000000000000000000063\n:105D40000000000000000000000000000000000053\n:105D50000000000000000000000000000000000043\n:105D60000000000000000000000000000000000033\n:105D70000000000000000000000000000000000023\n:105D80000000000000000000000000000000000013\n:105D90000000000000000000000000000000000003\n:105DA00000000000000000000000000000000000F3\n:105DB00000000000000000000000000000000000E3\n:105DC00000000000000000000000000000000000D3\n:105DD00000000000000000000000000000000000C3\n:105DE00000000000000000000000000000000000B3\n:105DF00000000000000000000000000000000000A3\n:105E00000000000000000000000000000000000092\n:105E10000000000000000000000000000000000082\n:105E20000000000000000000000000000000000072\n:105E30000000000000000000000000000000000062\n:105E40000000000000000000000000000000000052\n:105E50000000000000000000000000000000000042\n:105E60000000000000000000000000000000000032\n:105E70000000000000000000000000000000000022\n:105E80000000000000000000000000000000000012\n:105E90000000000000000000000000000000000002\n:105EA00000000000000000000000000000000000F2\n:105EB00000000000000000000000000000000000E2\n:105EC00000000000000000000000000000000000D2\n:105ED00000000000000000000000000000000000C2\n:105EE00000000000000000000000000000000000B2\n:105EF00000000000000000000000000000000000A2\n:105F00000000000000000000000000000000000091\n:105F10000000000000000000000000000000000081\n:105F20000000000000000000000000000000000071\n:105F30000000000000000000000000000000000061\n:105F40000000000000000000000000000000000051\n:105F50000000000000000000000000000000000041\n:105F60000000000000000000000000000000000031\n:105F70000000000000000000000000000000000021\n:105F80000000000000000000000000000000000011\n:105F90000000000000000000000000000000000001\n:105FA00000000000000000000000000000000000F1\n:105FB00000000000000000000000000000000000E1\n:105FC00000000000000000000000000000000000D1\n:105FD00000000000000000000000000000000000C1\n:105FE00000000000000000000000000000000000B1\n:105FF00000000000000000000000000000000000A1\n:106000000000000000000000000000000000000090\n:106010000000000000000000000000000000000080\n:106020000000000000000000000000000000000070\n:106030000000000000000000000000000000000060\n:106040000000000000000000000000000000000050\n:106050000000000000000000000000000000000040\n:106060000000000000000000000000000000000030\n:106070000000000000000000000000000000000020\n:106080000000000000000000000000000000000010\n:106090000000000000000000000000000000000000\n:1060A00000000000000000000000000000000000F0\n:1060B00000000000000000000000000000000000E0\n:1060C00000000000000000000000000000000000D0\n:1060D00000000000000000000000000000000000C0\n:1060E00000000000000000000000000000000000B0\n:1060F00000000000000000000000000000000000A0\n:10610000000000000000000000000000000000008F\n:10611000000000000000000000000000000000007F\n:10612000000000000000000000000000000000006F\n:10613000000000000000000000000000000000005F\n:10614000000000000000000000000000000000004F\n:10615000000000000000000000000000000000003F\n:10616000000000000000000000000000000000002F\n:10617000000000000000000000000000000000001F\n:10618000000000000000000000000000000000000F\n:1061900000000000000000000000000000000000FF\n:1061A00000000000000000000000000000000000EF\n:1061B00000000000000000000000000000000000DF\n:1061C00000000000000000000000000000000000CF\n:1061D00000000000000000000000000000000000BF\n:1061E00000000000000000000000000000000000AF\n:1061F000000000000000000000000000000000009F\n:10620000000000000000000000000000000000008E\n:10621000000000000000000000000000000000007E\n:10622000000000000000000000000000000000006E\n:10623000000000000000000000000000000000005E\n:10624000000000000000000000000000000000004E\n:10625000000000000000000000000000000000003E\n:10626000000000000000000000000000000000002E\n:10627000000000000000000000000000000000001E\n:10628000000000000000000000000000000000000E\n:1062900000000000000000000000000000000000FE\n:1062A00000000000000000000000000000000000EE\n:1062B00000000000000000000000000000000000DE\n:1062C00000000000000000000000000000000000CE\n:1062D00000000000000000000000000000000000BE\n:1062E00000000000000000000000000000000000AE\n:1062F000000000000000000000000000000000009E\n:10630000000000000000000000000000000000008D\n:10631000000000000000000000000000000000007D\n:10632000000000000000000000000000000000006D\n:10633000000000000000000000000000000000005D\n:10634000000000000000000000000000000000004D\n:10635000000000000000000000000000000000003D\n:10636000000000000000000000000000000000002D\n:10637000000000000000000000000000000000001D\n:10638000000000000000000000000000000000000D\n:1063900000000000000000000000000000000000FD\n:1063A00000000000000000000000000000000000ED\n:1063B00000000000000000000000000000000000DD\n:1063C00000000000000000000000000000000000CD\n:1063D00000000000000000000000000000000000BD\n:1063E00000000000000000000000000000000000AD\n:1063F000000000000000000000000000000000009D\n:10640000000000000000000000000000000000008C\n:10641000000000000000000000000000000000007C\n:10642000000000000000000000000000000000006C\n:10643000000000000000000000000000000000005C\n:10644000000000000000000000000000000000004C\n:10645000000000000000000000000000000000003C\n:10646000000000000000000000000000000000002C\n:10647000000000000000000000000000000000001C\n:10648000000000000000000000000000000000000C\n:1064900000000000000000000000000000000000FC\n:1064A00000000000000000000000000000000000EC\n:1064B00000000000000000000000000000000000DC\n:1064C00000000000000000000000000000000000CC\n:1064D00000000000000000000000000000000000BC\n:1064E00000000000000000000000000000000000AC\n:1064F000000000000000000000000000000000009C\n:10650000000000000000000000000000000000008B\n:10651000000000000000000000000000000000007B\n:10652000000000000000000000000000000000006B\n:10653000000000000000000000000000000000005B\n:10654000000000000000000000000000000000004B\n:10655000000000000000000000000000000000003B\n:10656000000000000000000000000000000000002B\n:10657000000000000000000000000000000000001B\n:10658000000000000000000000000000000000000B\n:1065900000000000000000000000000000000000FB\n:1065A00000000000000000000000000000000000EB\n:1065B00000000000000000000000000000000000DB\n:1065C00000000000000000000000000000000000CB\n:1065D00000000000000000000000000000000000BB\n:1065E00000000000000000000000000000000000AB\n:1065F000000000000000000000000000000000009B\n:10660000000000000000000000000000000000008A\n:10661000000000000000000000000000000000007A\n:10662000000000000000000000000000000000006A\n:10663000000000000000000000000000000000005A\n:10664000000000000000000000000000000000004A\n:10665000000000000000000000000000000000003A\n:10666000000000000000000000000000000000002A\n:10667000000000000000000000000000000000001A\n:10668000000000000000000000000000000000000A\n:1066900000000000000000000000000000000000FA\n:1066A00000000000000000000000000000000000EA\n:1066B00000000000000000000000000000000000DA\n:1066C00000000000000000000000000000000000CA\n:1066D00000000000000000000000000000000000BA\n:1066E00000000000000000000000000000000000AA\n:1066F000000000000000000000000000000000009A\n:106700000000000000000000000000000000000089\n:106710000000000000000000000000000000000079\n:106720000000000000000000000000000000000069\n:106730000000000000000000000000000000000059\n:106740000000000000000000000000000000000049\n:106750000000000000000000000000000000000039\n:106760000000000000000000000000000000000029\n:106770000000000000000000000000000000000019\n:106780000000000000000000000000000000000009\n:1067900000000000000000000000000000000000F9\n:1067A00000000000000000000000000000000000E9\n:1067B00000000000000000000000000000000000D9\n:1067C00000000000000000000000000000000000C9\n:1067D00000000000000000000000000000000000B9\n:1067E00000000000000000000000000000000000A9\n:1067F0000000000000000000000000000000000099\n:106800000000000000000000000000000000000088\n:106810000000000000000000000000000000000078\n:106820000000000000000000000000000000000068\n:106830000000000000000000000000000000000058\n:106840000000000000000000000000000000000048\n:106850000000000000000000000000000000000038\n:106860000000000000000000000000000000000028\n:106870000000000000000000000000000000000018\n:106880000000000000000000000000000000000008\n:1068900000000000000000000000000000000000F8\n:1068A00000000000000000000000000000000000E8\n:1068B00000000000000000000000000000000000D8\n:1068C00000000000000000000000000000000000C8\n:1068D00000000000000000000000000000000000B8\n:1068E00000000000000000000000000000000000A8\n:1068F0000000000000000000000000000000000098\n:106900000000000000000000000000000000000087\n:106910000000000000000000000000000000000077\n:106920000000000000000000000000000000000067\n:106930000000000000000000000000000000000057\n:106940000000000000000000000000000000000047\n:106950000000000000000000000000000000000037\n:106960000000000000000000000000000000000027\n:106970000000000000000000000000000000000017\n:106980000000000000000000000000000000000007\n:1069900000000000000000000000000000000000F7\n:1069A00000000000000000000000000000000000E7\n:1069B00000000000000000000000000000000000D7\n:1069C00000000000000000000000000000000000C7\n:1069D00000000000000000000000000000000000B7\n:1069E00000000000000000000000000000000000A7\n:1069F0000000000000000000000000000000000097\n:106A00000000000000000000000000000000000086\n:106A10000000000000000000000000000000000076\n:106A20000000000000000000000000000000000066\n:106A30000000000000000000000000000000000056\n:106A40000000000000000000000000000000000046\n:106A50000000000000000000000000000000000036\n:106A60000000000000000000000000000000000026\n:106A70000000000000000000000000000000000016\n:106A80000000000000000000000000000000000006\n:106A900000000000000000000000000000000000F6\n:106AA00000000000000000000000000000000000E6\n:106AB00000000000000000000000000000000000D6\n:106AC00000000000000000000000000000000000C6\n:106AD00000000000000000000000000000000000B6\n:106AE00000000000000000000000000000000000A6\n:106AF0000000000000000000000000000000000096\n:106B00000000000000000000000000000000000085\n:106B10000000000000000000000000000000000075\n:106B20000000000000000000000000000000000065\n:106B30000000000000000000000000000000000055\n:106B40000000000000000000000000000000000045\n:106B50000000000000000000000000000000000035\n:106B60000000000000000000000000000000000025\n:106B70000000000000000000000000000000000015\n:106B80000000000000000000000000000000000005\n:106B900000000000000000000000000000000000F5\n:106BA00000000000000000000000000000000000E5\n:106BB00000000000000000000000000000000000D5\n:106BC00000000000000000000000000000000000C5\n:106BD00000000000000000000000000000000000B5\n:106BE00000000000000000000000000000000000A5\n:106BF0000000000000000000000000000000000095\n:106C00000000000000000000000000000000000084\n:106C10000000000000000000000000000000000074\n:106C20000000000000000000000000000000000064\n:106C30000000000000000000000000000000000054\n:106C40000000000000000000000000000000000044\n:106C50000000000000000000000000000000000034\n:106C60000000000000000000000000000000000024\n:106C70000000000000000000000000000000000014\n:106C80000000000000000000000000000000000004\n:106C900000000000000000000000000000000000F4\n:106CA00000000000000000000000000000000000E4\n:106CB00000000000000000000000000000000000D4\n:106CC00000000000000000000000000000000000C4\n:106CD00000000000000000000000000000000000B4\n:106CE00000000000000000000000000000000000A4\n:106CF0000000000000000000000000000000000094\n:106D00000000000000000000000000000000000083\n:106D10000000000000000000000000000000000073\n:106D20000000000000000000000000000000000063\n:106D30000000000000000000000000000000000053\n:106D40000000000000000000000000000000000043\n:106D50000000000000000000000000000000000033\n:106D60000000000000000000000000000000000023\n:106D70000000000000000000000000000000000013\n:106D80000000000000000000000000000000000003\n:106D900000000000000000000000000000000000F3\n:106DA00000000000000000000000000000000000E3\n:106DB00000000000000000000000000000000000D3\n:106DC00000000000000000000000000000000000C3\n:106DD00000000000000000000000000000000000B3\n:106DE00000000000000000000000000000000000A3\n:106DF0000000000000000000000000000000000093\n:106E00000000000000000000000000000000000082\n:106E10000000000000000000000000000000000072\n:106E20000000000000000000000000000000000062\n:106E30000000000000000000000000000000000052\n:106E40000000000000000000000000000000000042\n:106E50000000000000000000000000000000000032\n:106E60000000000000000000000000000000000022\n:106E70000000000000000000000000000000000012\n:106E80000000000000000000000000000000000002\n:106E900000000000000000000000000000000000F2\n:106EA00000000000000000000000000000000000E2\n:106EB00000000000000000000000000000000000D2\n:106EC00000000000000000000000000000000000C2\n:106ED00000000000000000000000000000000000B2\n:106EE00000000000000000000000000000000000A2\n:106EF0000000000000000000000000000000000092\n:106F00000000000000000000000000000000000081\n:106F10000000000000000000000000000000000071\n:106F20000000000000000000000000000000000061\n:106F30000000000000000000000000000000000051\n:106F40000000000000000000000000000000000041\n:106F50000000000000000000000000000000000031\n:106F60000000000000000000000000000000000021\n:106F70000000000000000000000000000000000011\n:106F80000000000000000000000000000000000001\n:106F900000000000000000000000000000000000F1\n:106FA00000000000000000000000000000000000E1\n:106FB00000000000000000000000000000000000D1\n:106FC00000000000000000000000000000000000C1\n:106FD00000000000000000000000000000000000B1\n:106FE00000000000000000000000000000000000A1\n:106FF0000000000000000000000000000000000091\n:107000000000000000000000000000000000000080\n:107010000000000000000000000000000000000070\n:107020000000000000000000000000000000000060\n:107030000000000000000000000000000000000050\n:107040000000000000000000000000000000000040\n:107050000000000000000000000000000000000030\n:107060000000000000000000000000000000000020\n:107070000000000000000000000000000000000010\n:107080000000000000000000000000000000000000\n:1070900000000000000000000000000000000000F0\n:1070A00000000000000000000000000000000000E0\n:1070B00000000000000000000000000000000000D0\n:1070C00000000000000000000000000000000000C0\n:1070D00000000000000000000000000000000000B0\n:1070E00000000000000000000000000000000000A0\n:1070F0000000000000000000000000000000000090\n:10710000000000000000000000000000000000007F\n:10711000000000000000000000000000000000006F\n:10712000000000000000000000000000000000005F\n:10713000000000000000000000000000000000004F\n:10714000000000000000000000000000000000003F\n:10715000000000000000000000000000000000002F\n:10716000000000000000000000000000000000001F\n:10717000000000000000000000000000000000000F\n:1071800000000000000000000000000000000000FF\n:1071900000000000000000000000000000000000EF\n:1071A00000000000000000000000000000000000DF\n:1071B00000000000000000000000000000000000CF\n:1071C00000000000000000000000000000000000BF\n:1071D00000000000000000000000000000000000AF\n:1071E000000000000000000000000000000000009F\n:1071F000000000000000000000000000000000008F\n:10720000000000000000000000000000000000007E\n:10721000000000000000000000000000000000006E\n:10722000000000000000000000000000000000005E\n:10723000000000000000000000000000000000004E\n:10724000000000000000000000000000000000003E\n:10725000000000000000000000000000000000002E\n:10726000000000000000000000000000000000001E\n:10727000000000000000000000000000000000000E\n:1072800000000000000000000000000000000000FE\n:1072900000000000000000000000000000000000EE\n:1072A00000000000000000000000000000000000DE\n:1072B00000000000000000000000000000000000CE\n:1072C00000000000000000000000000000000000BE\n:1072D00000000000000000000000000000000000AE\n:1072E000000000000000000000000000000000009E\n:1072F000000000000000000000000000000000008E\n:10730000000000000000000000000000000000007D\n:10731000000000000000000000000000000000006D\n:10732000000000000000000000000000000000005D\n:10733000000000000000000000000000000000004D\n:10734000000000000000000000000000000000003D\n:10735000000000000000000000000000000000002D\n:10736000000000000000000000000000000000001D\n:10737000000000000000000000000000000000000D\n:1073800000000000000000000000000000000000FD\n:1073900000000000000000000000000000000000ED\n:1073A00000000000000000000000000000000000DD\n:1073B00000000000000000000000000000000000CD\n:1073C00000000000000000000000000000000000BD\n:1073D00000000000000000000000000000000000AD\n:1073E000000000000000000000000000000000009D\n:1073F000000000000000000000000000000000008D\n:10740000000000000000000000000000000000007C\n:10741000000000000000000000000000000000006C\n:10742000000000000000000000000000000000005C\n:10743000000000000000000000000000000000004C\n:10744000000000000000000000000000000000003C\n:10745000000000000000000000000000000000002C\n:10746000000000000000000000000000000000001C\n:10747000000000000000000000000000000000000C\n:1074800000000000000000000000000000000000FC\n:1074900000000000000000000000000000000000EC\n:1074A00000000000000000000000000000000000DC\n:1074B00000000000000000000000000000000000CC\n:1074C00000000000000000000000000000000000BC\n:1074D00000000000000000000000000000000000AC\n:1074E000000000000000000000000000000000009C\n:1074F000000000000000000000000000000000008C\n:10750000000000000000000000000000000000007B\n:10751000000000000000000000000000000000006B\n:10752000000000000000000000000000000000005B\n:10753000000000000000000000000000000000004B\n:10754000000000000000000000000000000000003B\n:10755000000000000000000000000000000000002B\n:10756000000000000000000000000000000000001B\n:10757000000000000000000000000000000000000B\n:1075800000000000000000000000000000000000FB\n:1075900000000000000000000000000000000000EB\n:1075A00000000000000000000000000000000000DB\n:1075B00000000000000000000000000000000000CB\n:1075C00000000000000000000000000000000000BB\n:1075D00000000000000000000000000000000000AB\n:1075E000000000000000000000000000000000009B\n:1075F000000000000000000000000000000000008B\n:10760000000000000000000000000000000000007A\n:10761000000000000000000000000000000000006A\n:10762000000000000000000000000000000000005A\n:10763000000000000000000000000000000000004A\n:10764000000000000000000000000000000000003A\n:10765000000000000000000000000000000000002A\n:10766000000000000000000000000000000000001A\n:10767000000000000000000000000000000000000A\n:1076800000000000000000000000000000000000FA\n:1076900000000000000000000000000000000000EA\n:1076A00000000000000000000000000000000000DA\n:1076B00000000000000000000000000000000000CA\n:1076C00000000000000000000000000000000000BA\n:1076D00000000000000000000000000000000000AA\n:1076E000000000000000000000000000000000009A\n:1076F000000000000000000000000000000000008A\n:107700000000000000000000000000000000000079\n:107710000000000000000000000000000000000069\n:107720000000000000000000000000000000000059\n:107730000000000000000000000000000000000049\n:107740000000000000000000000000000000000039\n:107750000000000000000000000000000000000029\n:107760000000000000000000000000000000000019\n:107770000000000000000000000000000000000009\n:1077800000000000000000000000000000000000F9\n:1077900000000000000000000000000000000000E9\n:1077A00000000000000000000000000000000000D9\n:1077B00000000000000000000000000000000000C9\n:1077C00000000000000000000000000000000000B9\n:1077D00000000000000000000000000000000000A9\n:1077E0000000000000000000000000000000000099\n:1077F0000000000000000000000000000000000089\n:107800000000000000000000000000000000000078\n:107810000000000000000000000000000000000068\n:107820000000000000000000000000000000000058\n:107830000000000000000000000000000000000048\n:107840000000000000000000000000000000000038\n:107850000000000000000000000000000000000028\n:107860000000000000000000000000000000000018\n:107870000000000000000000000000000000000008\n:1078800000000000000000000000000000000000F8\n:1078900000000000000000000000000000000000E8\n:1078A00000000000000000000000000000000000D8\n:1078B00000000000000000000000000000000000C8\n:1078C00000000000000000000000000000000000B8\n:1078D00000000000000000000000000000000000A8\n:1078E0000000000000000000000000000000000098\n:1078F0000000000000000000000000000000000088\n:107900000000000000000000000000000000000077\n:107910000000000000000000000000000000000067\n:107920000000000000000000000000000000000057\n:107930000000000000000000000000000000000047\n:107940000000000000000000000000000000000037\n:107950000000000000000000000000000000000027\n:107960000000000000000000000000000000000017\n:107970000000000000000000000000000000000007\n:1079800000000000000000000000000000000000F7\n:1079900000000000000000000000000000000000E7\n:1079A00000000000000000000000000000000000D7\n:1079B00000000000000000000000000000000000C7\n:1079C00000000000000000000000000000000000B7\n:1079D00000000000000000000000000000000000A7\n:1079E0000000000000000000000000000000000097\n:1079F0000000000000000000000000000000000087\n:107A00000000000000000000000000000000000076\n:107A10000000000000000000000000000000000066\n:107A20000000000000000000000000000000000056\n:107A30000000000000000000000000000000000046\n:107A40000000000000000000000000000000000036\n:107A50000000000000000000000000000000000026\n:107A60000000000000000000000000000000000016\n:107A70000000000000000000000000000000000006\n:107A800000000000000000000000000000000000F6\n:107A900000000000000000000000000000000000E6\n:107AA00000000000000000000000000000000000D6\n:107AB00000000000000000000000000000000000C6\n:107AC00000000000000000000000000000000000B6\n:107AD00000000000000000000000000000000000A6\n:107AE0000000000000000000000000000000000096\n:107AF0000000000000000000000000000000000086\n:107B00000000000000000000000000000000000075\n:107B10000000000000000000000000000000000065\n:107B20000000000000000000000000000000000055\n:107B30000000000000000000000000000000000045\n:107B40000000000000000000000000000000000035\n:107B50000000000000000000000000000000000025\n:107B60000000000000000000000000000000000015\n:107B70000000000000000000000000000000000005\n:107B800000000000000000000000000000000000F5\n:107B900000000000000000000000000000000000E5\n:107BA00000000000000000000000000000000000D5\n:107BB00000000000000000000000000000000000C5\n:107BC00000000000000000000000000000000000B5\n:107BD00000000000000000000000000000000000A5\n:107BE0000000000000000000000000000000000095\n:107BF0000000000000000000000000000000000085\n:107C00000000000000000000000000000000000074\n:107C10000000000000000000000000000000000064\n:107C20000000000000000000000000000000000054\n:107C30000000000000000000000000000000000044\n:107C40000000000000000000000000000000000034\n:107C50000000000000000000000000000000000024\n:107C60000000000000000000000000000000000014\n:107C70000000000000000000000000000000000004\n:107C800000000000000000000000000000000000F4\n:107C900000000000000000000000000000000000E4\n:107CA00000000000000000000000000000000000D4\n:107CB00000000000000000000000000000000000C4\n:107CC00000000000000000000000000000000000B4\n:107CD00000000000000000000000000000000000A4\n:107CE0000000000000000000000000000000000094\n:107CF0000000000000000000000000000000000084\n:107D00000000000000000000000000000000000073\n:107D10000000000000000000000000000000000063\n:107D20000000000000000000000000000000000053\n:107D30000000000000000000000000000000000043\n:107D40000000000000000000000000000000000033\n:107D50000000000000000000000000000000000023\n:107D60000000000000000000000000000000000013\n:107D70000000000000000000000000000000000003\n:107D800000000000000000000000000000000000F3\n:107D900000000000000000000000000000000000E3\n:107DA00000000000000000000000000000000000D3\n:107DB00000000000000000000000000000000000C3\n:107DC00000000000000000000000000000000000B3\n:107DD00000000000000000000000000000000000A3\n:107DE0000000000000000000000000000000000093\n:107DF0000000000000000000000000000000000083\n:107E00000000000000000000000000000000000072\n:107E10000000000000000000000000000000000062\n:107E20000000000000000000000000000000000052\n:107E30000000000000000000000000000000000042\n:107E40000000000000000000000000000000000032\n:107E50000000000000000000000000000000000022\n:107E60000000000000000000000000000000000012\n:107E70000000000000000000000000000000000002\n:107E800000000000000000000000000000000000F2\n:107E900000000000000000000000000000000000E2\n:107EA00000000000000000000000000000000000D2\n:107EB00000000000000000000000000000000000C2\n:107EC00000000000000000000000000000000000B2\n:107ED00000000000000000000000000000000000A2\n:107EE0000000000000000000000000000000000092\n:107EF0000000000000000000000000000000000082\n:107F00000000000000000000000000000000000071\n:107F10000000000000000000000000000000000061\n:107F20000000000000000000000000000000000051\n:107F30000000000000000000000000000000000041\n:107F40000000000000000000000000000000000031\n:107F50000000000000000000000000000000000021\n:107F60000000000000000000000000000000000011\n:107F70000000000000000000000000000000000001\n:107F800000000000000000000000000000000000F1\n:107F900000000000000000000000000000000000E1\n:107FA00000000000000000000000000000000000D1\n:107FB00000000000000000000000000000000000C1\n:107FC00000000000000000000000000000000000B1\n:107FD00000000000000000000000000000000000A1\n:107FE0000000000000000000000000000000000091\n:107FF0000000000000000000000000000000000081\n:108000000000000000000000000000000000000070\n:108010000000000000000000000000000000000060\n:108020000000000000000000000000000000000050\n:108030000000000000000000000000000000000040\n:108040000000000000000000000000000000000030\n:108050000000000000000000000000000000000020\n:108060000000000000000000000000000000000010\n:108070000000000000000000000000000000000000\n:1080800000000000000000000000000000000000F0\n:1080900000000000000000000000000000000000E0\n:1080A00000000000000000000000000000000000D0\n:1080B00000000000000000000000000000000000C0\n:1080C00000000000000000000000000000000000B0\n:1080D00000000000000000000000000000000000A0\n:1080E0000000000000000000000000000000000090\n:1080F0000000000000000000000000000000000080\n:10810000000000000000000000000000000000006F\n:10811000000000000000000000000000000000005F\n:10812000000000000000000000000000000000004F\n:10813000000000000000000000000000000000003F\n:10814000000000000000000000000000000000002F\n:10815000000000000000000000000000000000001F\n:10816000000000000000000000000000000000000F\n:1081700000000000000000000000000000000000FF\n:1081800000000000000000000000000000000000EF\n:1081900000000000000000000000000000000000DF\n:1081A00000000000000000000000000000000000CF\n:1081B00000000000000000000000000000000000BF\n:1081C00000000000000000000000000000000000AF\n:1081D000000000000000000000000000000000009F\n:1081E000000000000000000000000000000000008F\n:1081F000000000000000000000000000000000007F\n:10820000000000000000000000000000000000006E\n:10821000000000000000000000000000000000005E\n:10822000000000000000000000000000000000004E\n:10823000000000000000000000000000000000003E\n:10824000000000000000000000000000000000002E\n:10825000000000000000000000000000000000001E\n:10826000000000000000000000000000000000000E\n:1082700000000000000000000000000000000000FE\n:1082800000000000000000000000000000000000EE\n:1082900000000000000000000000000000000000DE\n:1082A00000000000000000000000000000000000CE\n:1082B00000000000000000000000000000000000BE\n:1082C00000000000000000000000000000000000AE\n:1082D000000000000000000000000000000000009E\n:1082E000000000000000000000000000000000008E\n:1082F000000000000000000000000000000000007E\n:10830000000000000000000000000000000000006D\n:10831000000000000000000000000000000000005D\n:10832000000000000000000000000000000000004D\n:10833000000000000000000000000000000000003D\n:10834000000000000000000000000000000000002D\n:10835000000000000000000000000000000000001D\n:10836000000000000000000000000000000000000D\n:1083700000000000000000000000000000000000FD\n:1083800000000000000000000000000000000000ED\n:1083900000000000000000000000000000000000DD\n:1083A00000000000000000000000000000000000CD\n:1083B00000000000000000000000000000000000BD\n:1083C00000000000000000000000000000000000AD\n:1083D000000000000000000000000000000000009D\n:1083E000000000000000000000000000000000008D\n:1083F000000000000000000000000000000000007D\n:10840000000000000000000000000000000000006C\n:10841000000000000000000000000000000000005C\n:10842000000000000000000000000000000000004C\n:10843000000000000000000000000000000000003C\n:10844000000000000000000000000000000000002C\n:10845000000000000000000000000000000000001C\n:10846000000000000000000000000000000000000C\n:1084700000000000000000000000000000000000FC\n:1084800000000000000000000000000000000000EC\n:1084900000000000000000000000000000000000DC\n:1084A00000000000000000000000000000000000CC\n:1084B00000000000000000000000000000000000BC\n:1084C00000000000000000000000000000000000AC\n:1084D000000000000000000000000000000000009C\n:1084E000000000000000000000000000000000008C\n:1084F000000000000000000000000000000000007C\n:10850000000000000000000000000000000000006B\n:10851000000000000000000000000000000000005B\n:10852000000000000000000000000000000000004B\n:10853000000000000000000000000000000000003B\n:10854000000000000000000000000000000000002B\n:10855000000000000000000000000000000000001B\n:10856000000000000000000000000000000000000B\n:1085700000000000000000000000000000000000FB\n:1085800000000000000000000000000000000000EB\n:1085900000000000000000000000000000000000DB\n:1085A00000000000000000000000000000000000CB\n:1085B00000000000000000000000000000000000BB\n:1085C00000000000000000000000000000000000AB\n:1085D000000000000000000000000000000000009B\n:1085E000000000000000000000000000000000008B\n:1085F000000000000000000000000000000000007B\n:10860000000000000000000000000000000000006A\n:10861000000000000000000000000000000000005A\n:10862000000000000000000000000000000000004A\n:10863000000000000000000000000000000000003A\n:10864000000000000000000000000000000000002A\n:10865000000000000000000000000000000000001A\n:10866000000000000000000000000000000000000A\n:1086700000000000000000000000000000000000FA\n:1086800000000000000000000000000000000000EA\n:1086900000000000000000000000000000000000DA\n:1086A00000000000000000000000000000000000CA\n:1086B00000000000000000000000000000000000BA\n:1086C00000000000000000000000000000000000AA\n:1086D000000000000000000000000000000000009A\n:1086E000000000000000000000000000000000008A\n:1086F000000000000000000000000000000000007A\n:108700000000000000000000000000000000000069\n:108710000000000000000000000000000000000059\n:108720000000000000000000000000000000000049\n:108730000000000000000000000000000000000039\n:108740000000000000000000000000000000000029\n:108750000000000000000000000000000000000019\n:108760000000000000000000000000000000000009\n:1087700000000000000000000000000000000000F9\n:1087800000000000000000000000000000000000E9\n:1087900000000000000000000000000000000000D9\n:1087A00000000000000000000000000000000000C9\n:1087B00000000000000000000000000000000000B9\n:1087C00000000000000000000000000000000000A9\n:1087D0000000000000000000000000000000000099\n:1087E0000000000000000000000000000000000089\n:1087F0000000000000000000000000000000000079\n:108800000000000000000000000000000000000068\n:108810000000000000000000000000000000000058\n:108820000000000000000000000000000000000048\n:108830000000000000000000000000000000000038\n:108840000000000000000000000000000000000028\n:108850000000000000000000000000000000000018\n:108860000000000000000000000000000000000008\n:1088700000000000000000000000000000000000F8\n:1088800000000000000000000000000000000000E8\n:1088900000000000000000000000000000000000D8\n:1088A00000000000000000000000000000000000C8\n:1088B00000000000000000000000000000000000B8\n:1088C00000000000000000000000000000000000A8\n:1088D0000000000000000000000000000000000098\n:1088E0000000000000000000000000000000000088\n:1088F0000000000000000000000000000000000078\n:108900000000000000000000000000000000000067\n:108910000000000000000000000000000000000057\n:108920000000000000000000000000000000000047\n:108930000000000000000000000000000000000037\n:108940000000000000000000000000000000000027\n:108950000000000000000000000000000000000017\n:108960000000000000000000000000000000000007\n:1089700000000000000000000000000000000000F7\n:1089800000000000000000000000000000000000E7\n:1089900000000000000000000000000000000000D7\n:1089A00000000000000000000000000000000000C7\n:1089B00000000000000000000000000000000000B7\n:1089C00000000000000000000000000000000000A7\n:1089D0000000000000000000000000000000000097\n:1089E0000000000000000000000000000000000087\n:1089F0000000000000000000000000000000000077\n:108A00000000000000000000000000000000000066\n:108A10000000000000000000000000000000000056\n:108A20000000000000000000000000000000000046\n:108A30000000000000000000000000000000000036\n:108A40000000000000000000000000000000000026\n:108A50000000000000000000000000000000000016\n:108A60000000000000000000000000000000000006\n:108A700000000000000000000000000000000000F6\n:108A800000000000000000000000000000000000E6\n:108A900000000000000000000000000000000000D6\n:108AA00000000000000000000000000000000000C6\n:108AB00000000000000000000000000000000000B6\n:108AC00000000000000000000000000000000000A6\n:108AD0000000000000000000000000000000000096\n:108AE0000000000000000000000000000000000086\n:108AF0000000000000000000000000000000000076\n:108B00000000000000000000000000000000000065\n:108B10000000000000000000000000000000000055\n:108B20000000000000000000000000000000000045\n:108B30000000000000000000000000000000000035\n:108B40000000000000000000000000000000000025\n:108B50000000000000000000000000000000000015\n:108B60000000000000000000000000000000000005\n:108B700000000000000000000000000000000000F5\n:108B800000000000000000000000000000000000E5\n:108B900000000000000000000000000000000000D5\n:108BA00000000000000000000000000000000000C5\n:108BB00000000000000000000000000000000000B5\n:108BC00000000000000000000000000000000000A5\n:108BD0000000000000000000000000000000000095\n:108BE0000000000000000000000000000000000085\n:108BF0000000000000000000000000000000000075\n:108C00000000000000000000000000000000000064\n:108C10000000000000000000000000000000000054\n:108C20000000000000000000000000000000000044\n:108C30000000000000000000000000000000000034\n:108C40000000000000000000000000000000000024\n:108C50000000000000000000000000000000000014\n:108C60000000000000000000000000000000000004\n:108C700000000000000000000000000000000000F4\n:108C800000000000000000000000000000000000E4\n:108C900000000000000000000000000000000000D4\n:108CA00000000000000000000000000000000000C4\n:108CB00000000000000000000000000000000000B4\n:108CC00000000000000000000000000000000000A4\n:108CD0000000000000000000000000000000000094\n:108CE0000000000000000000000000000000000084\n:108CF0000000000000000000000000000000000074\n:108D00000000000000000000000000000000000063\n:108D10000000000000000000000000000000000053\n:108D20000000000000000000000000000000000043\n:108D30000000000000000000000000000000000033\n:108D40000000000000000000000000000000000023\n:108D50000000000000000000000000000000000013\n:108D60000000000000000000000000000000000003\n:108D700000000000000000000000000000000000F3\n:108D800000000000000000000000000000000000E3\n:108D900000000000000000000000000000000000D3\n:108DA00000000000000000000000000000000000C3\n:108DB00000000000000000000000000000000000B3\n:108DC00000000000000000000000000000000000A3\n:108DD0000000000000000000000000000000000093\n:108DE0000000000000000000000000000000000083\n:108DF0000000000000000000000000000000000073\n:108E00000000000000000000000000000000000062\n:108E10000000000000000000000000000000000052\n:108E20000000000000000000000000000000000042\n:108E30000000000000000000000000000000000032\n:108E40000000000000000000000000000000000022\n:108E50000000000000000000000000000000000012\n:108E60000000000000000000000000000000000002\n:108E700000000000000000000000000000000000F2\n:108E800000000000000000000000000000000000E2\n:108E900000000000000000000000000000000000D2\n:108EA00000000000000000000000000000000000C2\n:108EB00000000000000000000000000000000000B2\n:108EC00000000000000000000000000000000000A2\n:108ED0000000000000000000000000000000000092\n:108EE0000000000000000000000000000000000082\n:108EF0000000000000000000000000000000000072\n:108F00000000000000000000000000000000000061\n:108F10000000000000000000000000000000000051\n:108F20000000000000000000000000000000000041\n:108F30000000000000000000000000000000000031\n:108F40000000000000000000000000000000000021\n:108F50000000000000000000000000000000000011\n:108F60000000000000000000000000000000000001\n:108F700000000000000000000000000000000000F1\n:108F800000000000000000000000000000000000E1\n:108F900000000000000000000000000000000000D1\n:108FA00000000000000000000000000000000000C1\n:108FB00000000000000000000000000000000000B1\n:108FC00000000000000000000000000000000000A1\n:108FD0000000000000000000000000000000000091\n:108FE0000000000000000000000000000000000081\n:108FF0000000000000000000000000000000000071\n:109000000000000000000000000000000000000060\n:109010000000000000000000000000000000000050\n:109020000000000000000000000000000000000040\n:109030000000000000000000000000000000000030\n:109040000000000000000000000000000000000020\n:109050000000000000000000000000000000000010\n:109060000000000000000000000000000000000000\n:1090700000000000000000000000000000000000F0\n:1090800000000000000000000000000000000000E0\n:1090900000000000000000000000000000000000D0\n:1090A00000000000000000000000000000000000C0\n:1090B00000000000000000000000000000000000B0\n:1090C00000000000000000000000000000000000A0\n:1090D0000000000000000000000000000000000090\n:1090E0000000000000000000000000000000000080\n:1090F0000000000000000000000000000000000070\n:10910000000000000000000000000000000000005F\n:10911000000000000000000000000000000000004F\n:10912000000000000000000000000000000000003F\n:10913000000000000000000000000000000000002F\n:10914000000000000000000000000000000000001F\n:10915000000000000000000000000000000000000F\n:1091600000000000000000000000000000000000FF\n:1091700000000000000000000000000000000000EF\n:1091800000000000000000000000000000000000DF\n:1091900000000000000000000000000000000000CF\n:1091A00000000000000000000000000000000000BF\n:1091B00000000000000000000000000000000000AF\n:1091C000000000000000000000000000000000009F\n:1091D000000000000000000000000000000000008F\n:1091E000000000000000000000000000000000007F\n:1091F000000000000000000000000000000000006F\n:10920000000000000000000000000000000000005E\n:10921000000000000000000000000000000000004E\n:10922000000000000000000000000000000000003E\n:10923000000000000000000000000000000000002E\n:10924000000000000000000000000000000000001E\n:10925000000000000000000000000000000000000E\n:1092600000000000000000000000000000000000FE\n:1092700000000000000000000000000000000000EE\n:1092800000000000000000000000000000000000DE\n:1092900000000000000000000000000000000000CE\n:1092A00000000000000000000000000000000000BE\n:1092B00000000000000000000000000000000000AE\n:1092C000000000000000000000000000000000009E\n:1092D000000000000000000000000000000000008E\n:1092E000000000000000000000000000000000007E\n:1092F000000000000000000000000000000000006E\n:10930000000000000000000000000000000000005D\n:10931000000000000000000000000000000000004D\n:10932000000000000000000000000000000000003D\n:10933000000000000000000000000000000000002D\n:10934000000000000000000000000000000000001D\n:10935000000000000000000000000000000000000D\n:1093600000000000000000000000000000000000FD\n:1093700000000000000000000000000000000000ED\n:1093800000000000000000000000000000000000DD\n:1093900000000000000000000000000000000000CD\n:1093A00000000000000000000000000000000000BD\n:1093B00000000000000000000000000000000000AD\n:1093C000000000000000000000000000000000009D\n:1093D000000000000000000000000000000000008D\n:1093E000000000000000000000000000000000007D\n:1093F000000000000000000000000000000000006D\n:10940000000000000000000000000000000000005C\n:10941000000000000000000000000000000000004C\n:10942000000000000000000000000000000000003C\n:10943000000000000000000000000000000000002C\n:10944000000000000000000000000000000000001C\n:10945000000000000000000000000000000000000C\n:1094600000000000000000000000000000000000FC\n:1094700000000000000000000000000000000000EC\n:1094800000000000000000000000000000000000DC\n:1094900000000000000000000000000000000000CC\n:1094A00000000000000000000000000000000000BC\n:1094B00000000000000000000000000000000000AC\n:1094C000000000000000000000000000000000009C\n:1094D000000000000000000000000000000000008C\n:1094E000000000000000000000000000000000007C\n:1094F000000000000000000000000000000000006C\n:10950000000000000000000000000000000000005B\n:10951000000000000000000000000000000000004B\n:10952000000000000000000000000000000000003B\n:10953000000000000000000000000000000000002B\n:10954000000000000000000000000000000000001B\n:10955000000000000000000000000000000000000B\n:1095600000000000000000000000000000000000FB\n:1095700000000000000000000000000000000000EB\n:1095800000000000000000000000000000000000DB\n:1095900000000000000000000000000000000000CB\n:1095A00000000000000000000000000000000000BB\n:1095B00000000000000000000000000000000000AB\n:1095C000000000000000000000000000000000009B\n:1095D000000000000000000000000000000000008B\n:1095E000000000000000000000000000000000007B\n:1095F000000000000000000000000000000000006B\n:10960000000000000000000000000000000000005A\n:10961000000000000000000000000000000000004A\n:10962000000000000000000000000000000000003A\n:10963000000000000000000000000000000000002A\n:10964000000000000000000000000000000000001A\n:10965000000000000000000000000000000000000A\n:1096600000000000000000000000000000000000FA\n:1096700000000000000000000000000000000000EA\n:1096800000000000000000000000000000000000DA\n:1096900000000000000000000000000000000000CA\n:1096A00000000000000000000000000000000000BA\n:1096B00000000000000000000000000000000000AA\n:1096C000000000000000000000000000000000009A\n:1096D000000000000000000000000000000000008A\n:1096E000000000000000000000000000000000007A\n:1096F000000000000000000000000000000000006A\n:109700000000000000000000000000000000000059\n:109710000000000000000000000000000000000049\n:109720000000000000000000000000000000000039\n:109730000000000000000000000000000000000029\n:109740000000000000000000000000000000000019\n:109750000000000000000000000000000000000009\n:1097600000000000000000000000000000000000F9\n:1097700000000000000000000000000000000000E9\n:1097800000000000000000000000000000000000D9\n:1097900000000000000000000000000000000000C9\n:1097A00000000000000000000000000000000000B9\n:1097B00000000000000000000000000000000000A9\n:1097C0000000000000000000000000000000000099\n:1097D0000000000000000000000000000000000089\n:1097E0000000000000000000000000000000000079\n:1097F0000000000000000000000000000000000069\n:109800000000000000000000000000000000000058\n:109810000000000000000000000000000000000048\n:109820000000000000000000000000000000000038\n:109830000000000000000000000000000000000028\n:109840000000000000000000000000000000000018\n:109850000000000000000000000000000000000008\n:1098600000000000000000000000000000000000F8\n:1098700000000000000000000000000000000000E8\n:1098800000000000000000000000000000000000D8\n:1098900000000000000000000000000000000000C8\n:1098A00000000000000000000000000000000000B8\n:1098B00000000000000000000000000000000000A8\n:1098C0000000000000000000000000000000000098\n:1098D0000000000000000000000000000000000088\n:1098E0000000000000000000000000000000000078\n:1098F0000000000000000000000000000000000068\n:109900000000000000000000000000000000000057\n:109910000000000000000000000000000000000047\n:109920000000000000000000000000000000000037\n:109930000000000000000000000000000000000027\n:109940000000000000000000000000000000000017\n:109950000000000000000000000000000000000007\n:1099600000000000000000000000000000000000F7\n:1099700000000000000000000000000000000000E7\n:1099800000000000000000000000000000000000D7\n:1099900000000000000000000000000000000000C7\n:1099A00000000000000000000000000000000000B7\n:1099B00000000000000000000000000000000000A7\n:1099C0000000000000000000000000000000000097\n:1099D0000000000000000000000000000000000087\n:1099E0000000000000000000000000000000000077\n:1099F0000000000000000000000000000000000067\n:109A00000000000000000000000000000000000056\n:109A10000000000000000000000000000000000046\n:109A20000000000000000000000000000000000036\n:109A30000000000000000000000000000000000026\n:109A40000000000000000000000000000000000016\n:109A50000000000000000000000000000000000006\n:109A600000000000000000000000000000000000F6\n:109A700000000000000000000000000000000000E6\n:109A800000000000000000000000000000000000D6\n:109A900000000000000000000000000000000000C6\n:109AA00000000000000000000000000000000000B6\n:109AB00000000000000000000000000000000000A6\n:109AC0000000000000000000000000000000000096\n:109AD0000000000000000000000000000000000086\n:109AE0000000000000000000000000000000000076\n:109AF0000000000000000000000000000000000066\n:109B00000000000000000000000000000000000055\n:109B10000000000000000000000000000000000045\n:109B20000000000000000000000000000000000035\n:109B30000000000000000000000000000000000025\n:109B40000000000000000000000000000000000015\n:109B50000000000000000000000000000000000005\n:109B600000000000000000000000000000000000F5\n:109B700000000000000000000000000000000000E5\n:109B800000000000000000000000000000000000D5\n:109B900000000000000000000000000000000000C5\n:109BA00000000000000000000000000000000000B5\n:109BB00000000000000000000000000000000000A5\n:109BC0000000000000000000000000000000000095\n:109BD0000000000000000000000000000000000085\n:109BE0000000000000000000000000000000000075\n:109BF0000000000000000000000000000000000065\n:109C00000000000000000000000000000000000054\n:109C10000000000000000000000000000000000044\n:109C20000000000000000000000000000000000034\n:109C30000000000000000000000000000000000024\n:109C40000000000000000000000000000000000014\n:109C50000000000000000000000000000000000004\n:109C600000000000000000000000000000000000F4\n:109C700000000000000000000000000000000000E4\n:109C800000000000000000000000000000000000D4\n:109C900000000000000000000000000000000000C4\n:109CA00000000000000000000000000000000000B4\n:109CB00000000000000000000000000000000000A4\n:109CC0000000000000000000000000000000000094\n:109CD0000000000000000000000000000000000084\n:109CE0000000000000000000000000000000000074\n:109CF0000000000000000000000000000000000064\n:109D00000000000000000000000000000000000053\n:109D10000000000000000000000000000000000043\n:109D20000000000000000000000000000000000033\n:109D30000000000000000000000000000000000023\n:109D40000000000000000000000000000000000013\n:109D50000000000000000000000000000000000003\n:109D600000000000000000000000000000000000F3\n:109D700000000000000000000000000000000000E3\n:109D800000000000000000000000000000000000D3\n:109D900000000000000000000000000000000000C3\n:109DA00000000000000000000000000000000000B3\n:109DB00000000000000000000000000000000000A3\n:109DC0000000000000000000000000000000000093\n:109DD0000000000000000000000000000000000083\n:109DE0000000000000000000000000000000000073\n:109DF0000000000000000000000000000000000063\n:109E00000000000000000000000000000000000052\n:109E10000000000000000000000000000000000042\n:109E20000000000000000000000000000000000032\n:109E30000000000000000000000000000000000022\n:109E40000000000000000000000000000000000012\n:109E50000000000000000000000000000000000002\n:109E600000000000000000000000000000000000F2\n:109E700000000000000000000000000000000000E2\n:109E800000000000000000000000000000000000D2\n:109E900000000000000000000000000000000000C2\n:109EA00000000000000000000000000000000000B2\n:109EB00000000000000000000000000000000000A2\n:109EC0000000000000000000000000000000000092\n:109ED0000000000000000000000000000000000082\n:109EE0000000000000000000000000000000000072\n:109EF0000000000000000000000000000000000062\n:109F00000000000000000000000000000000000051\n:109F10000000000000000000000000000000000041\n:109F20000000000000000000000000000000000031\n:109F30000000000000000000000000000000000021\n:109F40000000000000000000000000000000000011\n:109F50000000000000000000000000000000000001\n:109F600000000000000000000000000000000000F1\n:109F700000000000000000000000000000000000E1\n:109F800000000000000000000000000000000000D1\n:109F900000000000000000000000000000000000C1\n:109FA00000000000000000000000000000000000B1\n:109FB00000000000000000000000000000000000A1\n:109FC0000000000000000000000000000000000091\n:109FD0000000000000000000000000000000000081\n:109FE0000000000000000000000000000000000071\n:109FF0000000000000000000000000000000000061\n:10A000000000000000000000000000000000000050\n:10A010000000000000000000000000000000000040\n:10A020000000000000000000000000000000000030\n:10A030000000000000000000000000000000000020\n:10A040000000000000000000000000000000000010\n:10A050000000000000000000000000000000000000\n:10A0600000000000000000000000000000000000F0\n:10A0700000000000000000000000000000000000E0\n:10A0800000000000000000000000000000000000D0\n:10A0900000000000000000000000000000000000C0\n:10A0A00000000000000000000000000000000000B0\n:10A0B00000000000000000000000000000000000A0\n:10A0C0000000000000000000000000000000000090\n:10A0D0000000000000000000000000000000000080\n:10A0E0000000000000000000000000000000000070\n:10A0F0000000000000000000000000000000000060\n:10A10000000000000000000000000000000000004F\n:10A11000000000000000000000000000000000003F\n:10A12000000000000000000000000000000000002F\n:10A13000000000000000000000000000000000001F\n:10A14000000000000000000000000000000000000F\n:10A1500000000000000000000000000000000000FF\n:10A1600000000000000000000000000000000000EF\n:10A1700000000000000000000000000000000000DF\n:10A1800000000000000000000000000000000000CF\n:10A1900000000000000000000000000000000000BF\n:10A1A00000000000000000000000000000000000AF\n:10A1B000000000000000000000000000000000009F\n:10A1C000000000000000000000000000000000008F\n:10A1D000000000000000000000000000000000007F\n:10A1E000000000000000000000000000000000006F\n:10A1F000000000000000000000000000000000005F\n:10A20000000000000000000000000000000000004E\n:10A21000000000000000000000000000000000003E\n:10A22000000000000000000000000000000000002E\n:10A23000000000000000000000000000000000001E\n:10A24000000000000000000000000000000000000E\n:10A2500000000000000000000000000000000000FE\n:10A2600000000000000000000000000000000000EE\n:10A2700000000000000000000000000000000000DE\n:10A2800000000000000000000000000000000000CE\n:10A2900000000000000000000000000000000000BE\n:10A2A00000000000000000000000000000000000AE\n:10A2B000000000000000000000000000000000009E\n:10A2C000000000000000000000000000000000008E\n:10A2D000000000000000000000000000000000007E\n:10A2E000000000000000000000000000000000006E\n:10A2F000000000000000000000000000000000005E\n:10A30000000000000000000000000000000000004D\n:10A31000000000000000000000000000000000003D\n:10A32000000000000000000000000000000000002D\n:10A33000000000000000000000000000000000001D\n:10A34000000000000000000000000000000000000D\n:10A3500000000000000000000000000000000000FD\n:10A3600000000000000000000000000000000000ED\n:10A3700000000000000000000000000000000000DD\n:10A3800000000000000000000000000000000000CD\n:10A3900000000000000000000000000000000000BD\n:10A3A00000000000000000000000000000000000AD\n:10A3B000000000000000000000000000000000009D\n:10A3C000000000000000000000000000000000008D\n:10A3D000000000000000000000000000000000007D\n:10A3E000000000000000000000000000000000006D\n:10A3F000000000000000000000000000000000005D\n:10A40000000000000000000000000000000000004C\n:10A41000000000000000000000000000000000003C\n:10A42000000000000000000000000000000000002C\n:10A43000000000000000000000000000000000001C\n:10A44000000000000000000000000000000000000C\n:10A4500000000000000000000000000000000000FC\n:10A4600000000000000000000000000000000000EC\n:10A4700000000000000000000000000000000000DC\n:10A4800000000000000000000000000000000000CC\n:10A4900000000000000000000000000000000000BC\n:10A4A00000000000000000000000000000000000AC\n:10A4B000000000000000000000000000000000009C\n:10A4C000000000000000000000000000000000008C\n:10A4D000000000000000000000000000000000007C\n:10A4E000000000000000000000000000000000006C\n:10A4F000000000000000000000000000000000005C\n:10A50000000000000000000000000000000000004B\n:10A51000000000000000000000000000000000003B\n:10A52000000000000000000000000000000000002B\n:10A53000000000000000000000000000000000001B\n:10A54000000000000000000000000000000000000B\n:10A5500000000000000000000000000000000000FB\n:10A5600000000000000000000000000000000000EB\n:10A5700000000000000000000000000000000000DB\n:10A5800000000000000000000000000000000000CB\n:10A5900000000000000000000000000000000000BB\n:10A5A00000000000000000000000000000000000AB\n:10A5B000000000000000000000000000000000009B\n:10A5C000000000000000000000000000000000008B\n:10A5D000000000000000000000000000000000007B\n:10A5E000000000000000000000000000000000006B\n:10A5F000000000000000000000000000000000005B\n:10A60000000000000000000000000000000000004A\n:10A61000000000000000000000000000000000003A\n:10A62000000000000000000000000000000000002A\n:10A63000000000000000000000000000000000001A\n:10A64000000000000000000000000000000000000A\n:10A6500000000000000000000000000000000000FA\n:10A6600000000000000000000000000000000000EA\n:10A6700000000000000000000000000000000000DA\n:10A6800000000000000000000000000000000000CA\n:10A6900000000000000000000000000000000000BA\n:10A6A00000000000000000000000000000000000AA\n:10A6B000000000000000000000000000000000009A\n:10A6C000000000000000000000000000000000008A\n:10A6D000000000000000000000000000000000007A\n:10A6E000000000000000000000000000000000006A\n:10A6F000000000000000000000000000000000005A\n:10A700000000000000000000000000000000000049\n:10A710000000000000000000000000000000000039\n:10A720000000000000000000000000000000000029\n:10A730000000000000000000000000000000000019\n:10A740000000000000000000000000000000000009\n:10A7500000000000000000000000000000000000F9\n:10A7600000000000000000000000000000000000E9\n:10A7700000000000000000000000000000000000D9\n:10A7800000000000000000000000000000000000C9\n:10A7900000000000000000000000000000000000B9\n:10A7A00000000000000000000000000000000000A9\n:10A7B0000000000000000000000000000000000099\n:10A7C0000000000000000000000000000000000089\n:10A7D0000000000000000000000000000000000079\n:10A7E0000000000000000000000000000000000069\n:10A7F0000000000000000000000000000000000059\n:10A800000000000000000000000000000000000048\n:10A810000000000000000000000000000000000038\n:10A820000000000000000000000000000000000028\n:10A830000000000000000000000000000000000018\n:10A840000000000000000000000000000000000008\n:10A8500000000000000000000000000000000000F8\n:10A8600000000000000000000000000000000000E8\n:10A8700000000000000000000000000000000000D8\n:10A8800000000000000000000000000000000000C8\n:10A8900000000000000000000000000000000000B8\n:10A8A00000000000000000000000000000000000A8\n:10A8B0000000000000000000000000000000000098\n:10A8C0000000000000000000000000000000000088\n:10A8D0000000000000000000000000000000000078\n:10A8E0000000000000000000000000000000000068\n:10A8F0000000000000000000000000000000000058\n:10A900000000000000000000000000000000000047\n:10A910000000000000000000000000000000000037\n:10A920000000000000000000000000000000000027\n:10A930000000000000000000000000000000000017\n:10A940000000000000000000000000000000000007\n:10A9500000000000000000000000000000000000F7\n:10A9600000000000000000000000000000000000E7\n:10A9700000000000000000000000000000000000D7\n:10A9800000000000000000000000000000000000C7\n:10A9900000000000000000000000000000000000B7\n:10A9A00000000000000000000000000000000000A7\n:10A9B0000000000000000000000000000000000097\n:10A9C0000000000000000000000000000000000087\n:10A9D0000000000000000000000000000000000077\n:10A9E0000000000000000000000000000000000067\n:10A9F0000000000000000000000000000000000057\n:10AA00000000000000000000000000000000000046\n:10AA10000000000000000000000000000000000036\n:10AA20000000000000000000000000000000000026\n:10AA30000000000000000000000000000000000016\n:10AA40000000000000000000000000000000000006\n:10AA500000000000000000000000000000000000F6\n:10AA600000000000000000000000000000000000E6\n:10AA700000000000000000000000000000000000D6\n:10AA800000000000000000000000000000000000C6\n:10AA900000000000000000000000000000000000B6\n:10AAA00000000000000000000000000000000000A6\n:10AAB0000000000000000000000000000000000096\n:10AAC0000000000000000000000000000000000086\n:10AAD0000000000000000000000000000000000076\n:10AAE0000000000000000000000000000000000066\n:10AAF0000000000000000000000000000000000056\n:10AB00000000000000000000000000000000000045\n:10AB10000000000000000000000000000000000035\n:10AB20000000000000000000000000000000000025\n:10AB30000000000000000000000000000000000015\n:10AB40000000000000000000000000000000000005\n:10AB500000000000000000000000000000000000F5\n:10AB600000000000000000000000000000000000E5\n:10AB700000000000000000000000000000000000D5\n:10AB800000000000000000000000000000000000C5\n:10AB900000000000000000000000000000000000B5\n:10ABA00000000000000000000000000000000000A5\n:10ABB0000000000000000000000000000000000095\n:10ABC0000000000000000000000000000000000085\n:10ABD0000000000000000000000000000000000075\n:10ABE0000000000000000000000000000000000065\n:10ABF0000000000000000000000000000000000055\n:10AC00000000000000000000000000000000000044\n:10AC10000000000000000000000000000000000034\n:10AC20000000000000000000000000000000000024\n:10AC30000000000000000000000000000000000014\n:10AC40000000000000000000000000000000000004\n:10AC500000000000000000000000000000000000F4\n:10AC600000000000000000000000000000000000E4\n:10AC700000000000000000000000000000000000D4\n:10AC800000000000000000000000000000000000C4\n:10AC900000000000000000000000000000000000B4\n:10ACA00000000000000000000000000000000000A4\n:10ACB0000000000000000000000000000000000094\n:10ACC0000000000000000000000000000000000084\n:10ACD0000000000000000000000000000000000074\n:10ACE0000000000000000000000000000000000064\n:10ACF0000000000000000000000000000000000054\n:10AD00000000000000000000000000000000000043\n:10AD10000000000000000000000000000000000033\n:10AD20000000000000000000000000000000000023\n:10AD30000000000000000000000000000000000013\n:10AD40000000000000000000000000000000000003\n:10AD500000000000000000000000000000000000F3\n:10AD600000000000000000000000000000000000E3\n:10AD700000000000000000000000000000000000D3\n:10AD800000000000000000000000000000000000C3\n:10AD900000000000000000000000000000000000B3\n:10ADA00000000000000000000000000000000000A3\n:10ADB0000000000000000000000000000000000093\n:10ADC0000000000000000000000000000000000083\n:10ADD0000000000000000000000000000000000073\n:10ADE0000000000000000000000000000000000063\n:10ADF0000000000000000000000000000000000053\n:10AE00000000000000000000000000000000000042\n:10AE10000000000000000000000000000000000032\n:10AE20000000000000000000000000000000000022\n:10AE30000000000000000000000000000000000012\n:10AE40000000000000000000000000000000000002\n:10AE500000000000000000000000000000000000F2\n:10AE600000000000000000000000000000000000E2\n:10AE700000000000000000000000000000000000D2\n:10AE800000000000000000000000000000000000C2\n:10AE900000000000000000000000000000000000B2\n:10AEA00000000000000000000000000000000000A2\n:10AEB0000000000000000000000000000000000092\n:10AEC0000000000000000000000000000000000082\n:10AED0000000000000000000000000000000000072\n:10AEE0000000000000000000000000000000000062\n:10AEF0000000000000000000000000000000000052\n:10AF00000000000000000000000000000000000041\n:10AF10000000000000000000000000000000000031\n:10AF20000000000000000000000000000000000021\n:10AF30000000000000000000000000000000000011\n:10AF40000000000000000000000000000000000001\n:10AF500000000000000000000000000000000000F1\n:10AF600000000000000000000000000000000000E1\n:10AF700000000000000000000000000000000000D1\n:10AF800000000000000000000000000000000000C1\n:10AF900000000000000000000000000000000000B1\n:10AFA00000000000000000000000000000000000A1\n:10AFB0000000000000000000000000000000000091\n:10AFC0000000000000000000000000000000000081\n:10AFD0000000000000000000000000000000000071\n:10AFE0000000000000000000000000000000000061\n:10AFF0000000000000000000000000000000000051\n:10B000000000000000000000000000000000000040\n:10B010000000000000000000000000000000000030\n:10B020000000000000000000000000000000000020\n:10B030000000000000000000000000000000000010\n:10B040000000000000000000000000000000000000\n:10B0500000000000000000000000000000000000F0\n:10B0600000000000000000000000000000000000E0\n:10B0700000000000000000000000000000000000D0\n:10B0800000000000000000000000000000000000C0\n:10B0900000000000000000000000000000000000B0\n:10B0A00000000000000000000000000000000000A0\n:10B0B0000000000000000000000000000000000090\n:10B0C0000000000000000000000000000000000080\n:10B0D0000000000000000000000000000000000070\n:10B0E0000000000000000000000000000000000060\n:10B0F0000000000000000000000000000000000050\n:10B10000000000000000000000000000000000003F\n:10B11000000000000000000000000000000000002F\n:10B12000000000000000000000000000000000001F\n:10B13000000000000000000000000000000000000F\n:10B1400000000000000000000000000000000000FF\n:10B1500000000000000000000000000000000000EF\n:10B1600000000000000000000000000000000000DF\n:10B1700000000000000000000000000000000000CF\n:10B1800000000000000000000000000000000000BF\n:10B1900000000000000000000000000000000000AF\n:10B1A000000000000000000000000000000000009F\n:10B1B000000000000000000000000000000000008F\n:10B1C000000000000000000000000000000000007F\n:10B1D000000000000000000000000000000000006F\n:10B1E000000000000000000000000000000000005F\n:10B1F000000000000000000000000000000000004F\n:10B20000000000000000000000000000000000003E\n:10B21000000000000000000000000000000000002E\n:10B22000000000000000000000000000000000001E\n:10B23000000000000000000000000000000000000E\n:10B2400000000000000000000000000000000000FE\n:10B2500000000000000000000000000000000000EE\n:10B2600000000000000000000000000000000000DE\n:10B2700000000000000000000000000000000000CE\n:10B2800000000000000000000000000000000000BE\n:10B2900000000000000000000000000000000000AE\n:10B2A000000000000000000000000000000000009E\n:10B2B000000000000000000000000000000000008E\n:10B2C000000000000000000000000000000000007E\n:10B2D000000000000000000000000000000000006E\n:10B2E000000000000000000000000000000000005E\n:10B2F000000000000000000000000000000000004E\n:10B30000000000000000000000000000000000003D\n:10B31000000000000000000000000000000000002D\n:10B32000000000000000000000000000000000001D\n:10B33000000000000000000000000000000000000D\n:10B3400000000000000000000000000000000000FD\n:10B3500000000000000000000000000000000000ED\n:10B3600000000000000000000000000000000000DD\n:10B3700000000000000000000000000000000000CD\n:10B3800000000000000000000000000000000000BD\n:10B3900000000000000000000000000000000000AD\n:10B3A000000000000000000000000000000000009D\n:10B3B000000000000000000000000000000000008D\n:10B3C000000000000000000000000000000000007D\n:10B3D000000000000000000000000000000000006D\n:10B3E000000000000000000000000000000000005D\n:10B3F000000000000000000000000000000000004D\n:10B40000000000000000000000000000000000003C\n:10B41000000000000000000000000000000000002C\n:10B42000000000000000000000000000000000001C\n:10B43000000000000000000000000000000000000C\n:10B4400000000000000000000000000000000000FC\n:10B4500000000000000000000000000000000000EC\n:10B4600000000000000000000000000000000000DC\n:10B4700000000000000000000000000000000000CC\n:10B4800000000000000000000000000000000000BC\n:10B4900000000000000000000000000000000000AC\n:10B4A000000000000000000000000000000000009C\n:10B4B000000000000000000000000000000000008C\n:10B4C000000000000000000000000000000000007C\n:10B4D000000000000000000000000000000000006C\n:10B4E000000000000000000000000000000000005C\n:10B4F000000000000000000000000000000000004C\n:10B50000000000000000000000000000000000003B\n:10B51000000000000000000000000000000000002B\n:10B52000000000000000000000000000000000001B\n:10B53000000000000000000000000000000000000B\n:10B5400000000000000000000000000000000000FB\n:10B5500000000000000000000000000000000000EB\n:10B5600000000000000000000000000000000000DB\n:10B5700000000000000000000000000000000000CB\n:10B5800000000000000000000000000000000000BB\n:10B5900000000000000000000000000000000000AB\n:10B5A000000000000000000000000000000000009B\n:10B5B000000000000000000000000000000000008B\n:10B5C000000000000000000000000000000000007B\n:10B5D000000000000000000000000000000000006B\n:10B5E000000000000000000000000000000000005B\n:10B5F000000000000000000000000000000000004B\n:10B60000000000000000000000000000000000003A\n:10B61000000000000000000000000000000000002A\n:10B62000000000000000000000000000000000001A\n:10B63000000000000000000000000000000000000A\n:10B6400000000000000000000000000000000000FA\n:10B6500000000000000000000000000000000000EA\n:10B6600000000000000000000000000000000000DA\n:10B6700000000000000000000000000000000000CA\n:10B6800000000000000000000000000000000000BA\n:10B6900000000000000000000000000000000000AA\n:10B6A000000000000000000000000000000000009A\n:10B6B000000000000000000000000000000000008A\n:10B6C000000000000000000000000000000000007A\n:10B6D000000000000000000000000000000000006A\n:10B6E000000000000000000000000000000000005A\n:10B6F000000000000000000000000000000000004A\n:10B700000000000000000000000000000000000039\n:10B710000000000000000000000000000000000029\n:10B720000000000000000000000000000000000019\n:10B730000000000000000000000000000000000009\n:10B7400000000000000000000000000000000000F9\n:10B7500000000000000000000000000000000000E9\n:10B7600000000000000000000000000000000000D9\n:10B7700000000000000000000000000000000000C9\n:10B7800000000000000000000000000000000000B9\n:10B7900000000000000000000000000000000000A9\n:10B7A0000000000000000000000000000000000099\n:10B7B0000000000000000000000000000000000089\n:10B7C0000000000000000000000000000000000079\n:10B7D0000000000000000000000000000000000069\n:10B7E0000000000000000000000000000000000059\n:10B7F0000000000000000000000000000000000049\n:10B800000000000000000000000000000000000038\n:10B810000000000000000000000000000000000028\n:10B820000000000000000000000000000000000018\n:10B830000000000000000000000000000000000008\n:10B8400000000000000000000000000000000000F8\n:10B8500000000000000000000000000000000000E8\n:10B8600000000000000000000000000000000000D8\n:10B8700000000000000000000000000000000000C8\n:10B8800000000000000000000000000000000000B8\n:10B8900000000000000000000000000000000000A8\n:10B8A0000000000000000000000000000000000098\n:10B8B0000000000000000000000000000000000088\n:10B8C0000000000000000000000000000000000078\n:10B8D0000000000000000000000000000000000068\n:10B8E0000000000000000000000000000000000058\n:10B8F0000000000000000000000000000000000048\n:10B900000000000000000000000000000000000037\n:10B910000000000000000000000000000000000027\n:10B920000000000000000000000000000000000017\n:10B930000000000000000000000000000000000007\n:10B9400000000000000000000000000000000000F7\n:10B9500000000000000000000000000000000000E7\n:10B9600000000000000000000000000000000000D7\n:10B9700000000000000000000000000000000000C7\n:10B9800000000000000000000000000000000000B7\n:10B9900000000000000000000000000000000000A7\n:10B9A0000000000000000000000000000000000097\n:10B9B0000000000000000000000000000000000087\n:10B9C0000000000000000000000000000000000077\n:10B9D0000000000000000000000000000000000067\n:10B9E0000000000000000000000000000000000057\n:10B9F0000000000000000000000000000000000047\n:10BA00000000000000000000000000000000000036\n:10BA10000000000000000000000000000000000026\n:10BA20000000000000000000000000000000000016\n:10BA30000000000000000000000000000000000006\n:10BA400000000000000000000000000000000000F6\n:10BA500000000000000000000000000000000000E6\n:10BA600000000000000000000000000000000000D6\n:10BA700000000000000000000000000000000000C6\n:10BA800000000000000000000000000000000000B6\n:10BA900000000000000000000000000000000000A6\n:10BAA0000000000000000000000000000000000096\n:10BAB0000000000000000000000000000000000086\n:10BAC0000000000000000000000000000000000076\n:10BAD0000000000000000000000000000000000066\n:10BAE0000000000000000000000000000000000056\n:10BAF0000000000000000000000000000000000046\n:10BB00000000000000000000000000000000000035\n:10BB10000000000000000000000000000000000025\n:10BB20000000000000000000000000000000000015\n:10BB30000000000000000000000000000000000005\n:10BB400000000000000000000000000000000000F5\n:10BB500000000000000000000000000000000000E5\n:10BB600000000000000000000000000000000000D5\n:10BB700000000000000000000000000000000000C5\n:10BB800000000000000000000000000000000000B5\n:10BB900000000000000000000000000000000000A5\n:10BBA0000000000000000000000000000000000095\n:10BBB0000000000000000000000000000000000085\n:10BBC0000000000000000000000000000000000075\n:10BBD0000000000000000000000000000000000065\n:10BBE0000000000000000000000000000000000055\n:10BBF0000000000000000000000000000000000045\n:10BC00000000000000000000000000000000000034\n:10BC10000000000000000000000000000000000024\n:10BC20000000000000000000000000000000000014\n:10BC30000000000000000000000000000000000004\n:10BC400000000000000000000000000000000000F4\n:10BC500000000000000000000000000000000000E4\n:10BC600000000000000000000000000000000000D4\n:10BC700000000000000000000000000000000000C4\n:10BC800000000000000000000000000000000000B4\n:10BC900000000000000000000000000000000000A4\n:10BCA0000000000000000000000000000000000094\n:10BCB0000000000000000000000000000000000084\n:10BCC0000000000000000000000000000000000074\n:10BCD0000000000000000000000000000000000064\n:10BCE0000000000000000000000000000000000054\n:10BCF0000000000000000000000000000000000044\n:10BD00000000000000000000000000000000000033\n:10BD10000000000000000000000000000000000023\n:10BD20000000000000000000000000000000000013\n:10BD30000000000000000000000000000000000003\n:10BD400000000000000000000000000000000000F3\n:10BD500000000000000000000000000000000000E3\n:10BD600000000000000000000000000000000000D3\n:10BD700000000000000000000000000000000000C3\n:10BD800000000000000000000000000000000000B3\n:10BD900000000000000000000000000000000000A3\n:10BDA0000000000000000000000000000000000093\n:10BDB0000000000000000000000000000000000083\n:10BDC0000000000000000000000000000000000073\n:10BDD0000000000000000000000000000000000063\n:10BDE0000000000000000000000000000000000053\n:10BDF0000000000000000000000000000000000043\n:10BE00000000000000000000000000000000000032\n:10BE10000000000000000000000000000000000022\n:10BE20000000000000000000000000000000000012\n:10BE30000000000000000000000000000000000002\n:10BE400000000000000000000000000000000000F2\n:10BE500000000000000000000000000000000000E2\n:10BE600000000000000000000000000000000000D2\n:10BE700000000000000000000000000000000000C2\n:10BE800000000000000000000000000000000000B2\n:10BE900000000000000000000000000000000000A2\n:10BEA0000000000000000000000000000000000092\n:10BEB0000000000000000000000000000000000082\n:10BEC0000000000000000000000000000000000072\n:10BED0000000000000000000000000000000000062\n:10BEE0000000000000000000000000000000000052\n:10BEF0000000000000000000000000000000000042\n:10BF00000000000000000000000000000000000031\n:10BF10000000000000000000000000000000000021\n:10BF20000000000000000000000000000000000011\n:10BF30000000000000000000000000000000000001\n:10BF400000000000000000000000000000000000F1\n:10BF500000000000000000000000000000000000E1\n:10BF600000000000000000000000000000000000D1\n:10BF700000000000000000000000000000000000C1\n:10BF800000000000000000000000000000000000B1\n:10BF900000000000000000000000000000000000A1\n:10BFA0000000000000000000000000000000000091\n:10BFB0000000000000000000000000000000000081\n:10BFC0000000000000000000000000000000000071\n:10BFD0000000000000000000000000000000000061\n:10BFE0000000000000000000000000000000000051\n:10BFF0000000000000000000000000000000000041\n:10C000000000000000000000000000000000000030\n:10C010000000000000000000000000000000000020\n:10C020000000000000000000000000000000000010\n:10C030000000000000000000000000000000000000\n:10C0400000000000000000000000000000000000F0\n:10C0500000000000000000000000000000000000E0\n:10C0600000000000000000000000000000000000D0\n:10C0700000000000000000000000000000000000C0\n:10C0800000000000000000000000000000000000B0\n:10C0900000000000000000000000000000000000A0\n:10C0A0000000000000000000000000000000000090\n:10C0B0000000000000000000000000000000000080\n:10C0C0000000000000000000000000000000000070\n:10C0D0000000000000000000000000000000000060\n:10C0E0000000000000000000000000000000000050\n:10C0F0000000000000000000000000000000000040\n:10C10000000000000000000000000000000000002F\n:10C11000000000000000000000000000000000001F\n:10C12000000000000000000000000000000000000F\n:10C1300000000000000000000000000000000000FF\n:10C1400000000000000000000000000000000000EF\n:10C1500000000000000000000000000000000000DF\n:10C1600000000000000000000000000000000000CF\n:10C1700000000000000000000000000000000000BF\n:10C1800000000000000000000000000000000000AF\n:10C19000000000000000000000000000000000009F\n:10C1A000000000000000000000000000000000008F\n:10C1B000000000000000000000000000000000007F\n:10C1C000000000000000000000000000000000006F\n:10C1D000000000000000000000000000000000005F\n:10C1E000000000000000000000000000000000004F\n:10C1F000000000000000000000000000000000003F\n:10C20000000000000000000000000000000000002E\n:10C21000000000000000000000000000000000001E\n:10C22000000000000000000000000000000000000E\n:10C2300000000000000000000000000000000000FE\n:10C2400000000000000000000000000000000000EE\n:10C2500000000000000000000000000000000000DE\n:10C2600000000000000000000000000000000000CE\n:10C2700000000000000000000000000000000000BE\n:10C2800000000000000000000000000000000000AE\n:10C29000000000000000000000000000000000009E\n:10C2A000000000000000000000000000000000008E\n:10C2B000000000000000000000000000000000007E\n:10C2C000000000000000000000000000000000006E\n:10C2D000000000000000000000000000000000005E\n:10C2E000000000000000000000000000000000004E\n:10C2F000000000000000000000000000000000003E\n:10C30000000000000000000000000000000000002D\n:10C31000000000000000000000000000000000001D\n:10C32000000000000000000000000000000000000D\n:10C3300000000000000000000000000000000000FD\n:10C3400000000000000000000000000000000000ED\n:10C3500000000000000000000000000000000000DD\n:10C3600000000000000000000000000000000000CD\n:10C3700000000000000000000000000000000000BD\n:10C3800000000000000000000000000000000000AD\n:10C39000000000000000000000000000000000009D\n:10C3A000000000000000000000000000000000008D\n:10C3B000000000000000000000000000000000007D\n:10C3C000000000000000000000000000000000006D\n:10C3D000000000000000000000000000000000005D\n:10C3E000000000000000000000000000000000004D\n:10C3F000000000000000000000000000000000003D\n:10C40000000000000000000000000000000000002C\n:10C41000000000000000000000000000000000001C\n:10C42000000000000000000000000000000000000C\n:10C4300000000000000000000000000000000000FC\n:10C4400000000000000000000000000000000000EC\n:10C4500000000000000000000000000000000000DC\n:10C4600000000000000000000000000000000000CC\n:10C4700000000000000000000000000000000000BC\n:10C4800000000000000000000000000000000000AC\n:10C49000000000000000000000000000000000009C\n:10C4A000000000000000000000000000000000008C\n:10C4B000000000000000000000000000000000007C\n:10C4C000000000000000000000000000000000006C\n:10C4D000000000000000000000000000000000005C\n:10C4E000000000000000000000000000000000004C\n:10C4F000000000000000000000000000000000003C\n:10C50000000000000000000000000000000000002B\n:10C51000000000000000000000000000000000001B\n:10C52000000000000000000000000000000000000B\n:10C5300000000000000000000000000000000000FB\n:10C5400000000000000000000000000000000000EB\n:10C5500000000000000000000000000000000000DB\n:10C5600000000000000000000000000000000000CB\n:10C5700000000000000000000000000000000000BB\n:10C5800000000000000000000000000000000000AB\n:10C59000000000000000000000000000000000009B\n:10C5A000000000000000000000000000000000008B\n:10C5B000000000000000000000000000000000007B\n:10C5C000000000000000000000000000000000006B\n:10C5D000000000000000000000000000000000005B\n:10C5E000000000000000000000000000000000004B\n:10C5F000000000000000000000000000000000003B\n:10C60000000000000000000000000000000000002A\n:10C61000000000000000000000000000000000001A\n:10C62000000000000000000000000000000000000A\n:10C6300000000000000000000000000000000000FA\n:10C6400000000000000000000000000000000000EA\n:10C6500000000000000000000000000000000000DA\n:10C6600000000000000000000000000000000000CA\n:10C6700000000000000000000000000000000000BA\n:10C6800000000000000000000000000000000000AA\n:10C69000000000000000000000000000000000009A\n:10C6A000000000000000000000000000000000008A\n:10C6B000000000000000000000000000000000007A\n:10C6C000000000000000000000000000000000006A\n:10C6D000000000000000000000000000000000005A\n:10C6E000000000000000000000000000000000004A\n:10C6F000000000000000000000000000000000003A\n:10C700000000000000000000000000000000000029\n:10C710000000000000000000000000000000000019\n:10C720000000000000000000000000000000000009\n:10C7300000000000000000000000000000000000F9\n:10C7400000000000000000000000000000000000E9\n:10C7500000000000000000000000000000000000D9\n:10C7600000000000000000000000000000000000C9\n:10C7700000000000000000000000000000000000B9\n:10C7800000000000000000000000000000000000A9\n:10C790000000000000000000000000000000000099\n:10C7A0000000000000000000000000000000000089\n:10C7B0000000000000000000000000000000000079\n:10C7C0000000000000000000000000000000000069\n:10C7D0000000000000000000000000000000000059\n:10C7E0000000000000000000000000000000000049\n:10C7F0000000000000000000000000000000000039\n:10C800000000000000000000000000000000000028\n:10C810000000000000000000000000000000000018\n:10C820000000000000000000000000000000000008\n:10C8300000000000000000000000000000000000F8\n:10C8400000000000000000000000000000000000E8\n:10C8500000000000000000000000000000000000D8\n:10C8600000000000000000000000000000000000C8\n:10C8700000000000000000000000000000000000B8\n:10C8800000000000000000000000000000000000A8\n:10C890000000000000000000000000000000000098\n:10C8A0000000000000000000000000000000000088\n:10C8B0000000000000000000000000000000000078\n:10C8C0000000000000000000000000000000000068\n:10C8D0000000000000000000000000000000000058\n:10C8E0000000000000000000000000000000000048\n:10C8F0000000000000000000000000000000000038\n:10C900000000000000000000000000000000000027\n:10C910000000000000000000000000000000000017\n:10C920000000000000000000000000000000000007\n:10C9300000000000000000000000000000000000F7\n:10C9400000000000000000000000000000000000E7\n:10C9500000000000000000000000000000000000D7\n:10C9600000000000000000000000000000000000C7\n:10C9700000000000000000000000000000000000B7\n:10C9800000000000000000000000000000000000A7\n:10C990000000000000000000000000000000000097\n:10C9A0000000000000000000000000000000000087\n:10C9B0000000000000000000000000000000000077\n:10C9C0000000000000000000000000000000000067\n:10C9D0000000000000000000000000000000000057\n:10C9E0000000000000000000000000000000000047\n:10C9F0000000000000000000000000000000000037\n:10CA00000000000000000000000000000000000026\n:10CA10000000000000000000000000000000000016\n:10CA20000000000000000000000000000000000006\n:10CA300000000000000000000000000000000000F6\n:10CA400000000000000000000000000000000000E6\n:10CA500000000000000000000000000000000000D6\n:10CA600000000000000000000000000000000000C6\n:10CA700000000000000000000000000000000000B6\n:10CA800000000000000000000000000000000000A6\n:10CA90000000000000000000000000000000000096\n:10CAA0000000000000000000000000000000000086\n:10CAB0000000000000000000000000000000000076\n:10CAC0000000000000000000000000000000000066\n:10CAD0000000000000000000000000000000000056\n:10CAE0000000000000000000000000000000000046\n:10CAF0000000000000000000000000000000000036\n:10CB00000000000000000000000000000000000025\n:10CB10000000000000000000000000000000000015\n:10CB20000000000000000000000000000000000005\n:10CB300000000000000000000000000000000000F5\n:10CB400000000000000000000000000000000000E5\n:10CB500000000000000000000000000000000000D5\n:10CB600000000000000000000000000000000000C5\n:10CB700000000000000000000000000000000000B5\n:10CB800000000000000000000000000000000000A5\n:10CB90000000000000000000000000000000000095\n:10CBA0000000000000000000000000000000000085\n:10CBB0000000000000000000000000000000000075\n:10CBC0000000000000000000000000000000000065\n:10CBD0000000000000000000000000000000000055\n:10CBE0000000000000000000000000000000000045\n:10CBF0000000000000000000000000000000000035\n:10CC00000000000000000000000000000000000024\n:10CC10000000000000000000000000000000000014\n:10CC20000000000000000000000000000000000004\n:10CC300000000000000000000000000000000000F4\n:10CC400000000000000000000000000000000000E4\n:10CC500000000000000000000000000000000000D4\n:10CC600000000000000000000000000000000000C4\n:10CC700000000000000000000000000000000000B4\n:10CC800000000000000000000000000000000000A4\n:10CC90000000000000000000000000000000000094\n:10CCA0000000000000000000000000000000000084\n:10CCB0000000000000000000000000000000000074\n:10CCC0000000000000000000000000000000000064\n:10CCD0000000000000000000000000000000000054\n:10CCE0000000000000000000000000000000000044\n:10CCF0000000000000000000000000000000000034\n:10CD00000000000000000000000000000000000023\n:10CD10000000000000000000000000000000000013\n:10CD20000000000000000000000000000000000003\n:10CD300000000000000000000000000000000000F3\n:10CD400000000000000000000000000000000000E3\n:10CD500000000000000000000000000000000000D3\n:10CD600000000000000000000000000000000000C3\n:10CD700000000000000000000000000000000000B3\n:10CD800000000000000000000000000000000000A3\n:10CD90000000000000000000000000000000000093\n:10CDA0000000000000000000000000000000000083\n:10CDB0000000000000000000000000000000000073\n:10CDC0000000000000000000000000000000000063\n:10CDD0000000000000000000000000000000000053\n:10CDE0000000000000000000000000000000000043\n:10CDF0000000000000000000000000000000000033\n:10CE00000000000000000000000000000000000022\n:10CE10000000000000000000000000000000000012\n:10CE20000000000000000000000000000000000002\n:10CE300000000000000000000000000000000000F2\n:10CE400000000000000000000000000000000000E2\n:10CE500000000000000000000000000000000000D2\n:10CE600000000000000000000000000000000000C2\n:10CE700000000000000000000000000000000000B2\n:10CE800000000000000000000000000000000000A2\n:10CE90000000000000000000000000000000000092\n:10CEA0000000000000000000000000000000000082\n:10CEB0000000000000000000000000000000000072\n:10CEC0000000000000000000000000000000000062\n:10CED0000000000000000000000000000000000052\n:10CEE0000000000000000000000000000000000042\n:10CEF0000000000000000000000000000000000032\n:10CF00000000000000000000000000000000000021\n:10CF10000000000000000000000000000000000011\n:10CF20000000000000000000000000000000000001\n:10CF300000000000000000000000000000000000F1\n:10CF400000000000000000000000000000000000E1\n:10CF500000000000000000000000000000000000D1\n:10CF600000000000000000000000000000000000C1\n:10CF700000000000000000000000000000000000B1\n:10CF800000000000000000000000000000000000A1\n:10CF90000000000000000000000000000000000091\n:10CFA0000000000000000000000000000000000081\n:10CFB0000000000000000000000000000000000071\n:10CFC0000000000000000000000000000000000061\n:10CFD0000000000000000000000000000000000051\n:10CFE0000000000000000000000000000000000041\n:10CFF0000000000000000000000000000000000031\n:10D000000000000000000000000000000000000020\n:10D010000000000000000000000000000000000010\n:10D020000000000000000000000000000000000000\n:10D0300000000000000000000000000000000000F0\n:10D0400000000000000000000000000000000000E0\n:10D0500000000000000000000000000000000000D0\n:10D0600000000000000000000000000000000000C0\n:10D0700000000000000000000000000000000000B0\n:10D0800000000000000000000000000000000000A0\n:10D090000000000000000000000000000000000090\n:10D0A0000000000000000000000000000000000080\n:10D0B0000000000000000000000000000000000070\n:10D0C0000000000000000000000000000000000060\n:10D0D0000000000000000000000000000000000050\n:10D0E0000000000000000000000000000000000040\n:10D0F0000000000000000000000000000000000030\n:10D10000000000000000000000000000000000001F\n:10D11000000000000000000000000000000000000F\n:10D1200000000000000000000000000000000000FF\n:10D1300000000000000000000000000000000000EF\n:10D1400000000000000000000000000000000000DF\n:10D1500000000000000000000000000000000000CF\n:10D1600000000000000000000000000000000000BF\n:10D1700000000000000000000000000000000000AF\n:10D18000000000000000000000000000000000009F\n:10D19000000000000000000000000000000000008F\n:10D1A000000000000000000000000000000000007F\n:10D1B000000000000000000000000000000000006F\n:10D1C000000000000000000000000000000000005F\n:10D1D000000000000000000000000000000000004F\n:10D1E000000000000000000000000000000000003F\n:10D1F000000000000000000000000000000000002F\n:10D20000000000000000000000000000000000001E\n:10D21000000000000000000000000000000000000E\n:10D2200000000000000000000000000000000000FE\n:10D2300000000000000000000000000000000000EE\n:10D2400000000000000000000000000000000000DE\n:10D2500000000000000000000000000000000000CE\n:10D2600000000000000000000000000000000000BE\n:10D2700000000000000000000000000000000000AE\n:10D28000000000000000000000000000000000009E\n:10D29000000000000000000000000000000000008E\n:10D2A000000000000000000000000000000000007E\n:10D2B000000000000000000000000000000000006E\n:10D2C000000000000000000000000000000000005E\n:10D2D000000000000000000000000000000000004E\n:10D2E000000000000000000000000000000000003E\n:10D2F000000000000000000000000000000000002E\n:10D30000000000000000000000000000000000001D\n:10D31000000000000000000000000000000000000D\n:10D3200000000000000000000000000000000000FD\n:10D3300000000000000000000000000000000000ED\n:10D3400000000000000000000000000000000000DD\n:10D3500000000000000000000000000000000000CD\n:10D3600000000000000000000000000000000000BD\n:10D3700000000000000000000000000000000000AD\n:10D38000000000000000000000000000000000009D\n:10D39000000000000000000000000000000000008D\n:10D3A000000000000000000000000000000000007D\n:10D3B000000000000000000000000000000000006D\n:10D3C000000000000000000000000000000000005D\n:10D3D000000000000000000000000000000000004D\n:10D3E000000000000000000000000000000000003D\n:10D3F000000000000000000000000000000000002D\n:10D40000000000000000000000000000000000001C\n:10D41000000000000000000000000000000000000C\n:10D4200000000000000000000000000000000000FC\n:10D4300000000000000000000000000000000000EC\n:10D4400000000000000000000000000000000000DC\n:10D4500000000000000000000000000000000000CC\n:10D4600000000000000000000000000000000000BC\n:10D4700000000000000000000000000000000000AC\n:10D48000000000000000000000000000000000009C\n:10D49000000000000000000000000000000000008C\n:10D4A000000000000000000000000000000000007C\n:10D4B000000000000000000000000000000000006C\n:10D4C000000000000000000000000000000000005C\n:10D4D000000000000000000000000000000000004C\n:10D4E000000000000000000000000000000000003C\n:10D4F000000000000000000000000000000000002C\n:10D50000000000000000000000000000000000001B\n:10D51000000000000000000000000000000000000B\n:10D5200000000000000000000000000000000000FB\n:10D5300000000000000000000000000000000000EB\n:10D5400000000000000000000000000000000000DB\n:10D5500000000000000000000000000000000000CB\n:10D5600000000000000000000000000000000000BB\n:10D5700000000000000000000000000000000000AB\n:10D58000000000000000000000000000000000009B\n:10D59000000000000000000000000000000000008B\n:10D5A000000000000000000000000000000000007B\n:10D5B000000000000000000000000000000000006B\n:10D5C000000000000000000000000000000000005B\n:10D5D000000000000000000000000000000000004B\n:10D5E000000000000000000000000000000000003B\n:10D5F000000000000000000000000000000000002B\n:10D60000000000000000000000000000000000001A\n:10D61000000000000000000000000000000000000A\n:10D6200000000000000000000000000000000000FA\n:10D6300000000000000000000000000000000000EA\n:10D6400000000000000000000000000000000000DA\n:10D6500000000000000000000000000000000000CA\n:10D6600000000000000000000000000000000000BA\n:10D6700000000000000000000000000000000000AA\n:10D68000000000000000000000000000000000009A\n:10D69000000000000000000000000000000000008A\n:10D6A000000000000000000000000000000000007A\n:10D6B000000000000000000000000000000000006A\n:10D6C000000000000000000000000000000000005A\n:10D6D000000000000000000000000000000000004A\n:10D6E000000000000000000000000000000000003A\n:10D6F000000000000000000000000000000000002A\n:10D700000000000000000000000000000000000019\n:10D710000000000000000000000000000000000009\n:10D7200000000000000000000000000000000000F9\n:10D7300000000000000000000000000000000000E9\n:10D7400000000000000000000000000000000000D9\n:10D7500000000000000000000000000000000000C9\n:10D7600000000000000000000000000000000000B9\n:10D7700000000000000000000000000000000000A9\n:10D780000000000000000000000000000000000099\n:10D790000000000000000000000000000000000089\n:10D7A0000000000000000000000000000000000079\n:10D7B0000000000000000000000000000000000069\n:10D7C0000000000000000000000000000000000059\n:10D7D0000000000000000000000000000000000049\n:10D7E0000000000000000000000000000000000039\n:10D7F0000000000000000000000000000000000029\n:10D800000000000000000000000000000000000018\n:10D810000000000000000000000000000000000008\n:10D8200000000000000000000000000000000000F8\n:10D8300000000000000000000000000000000000E8\n:10D8400000000000000000000000000000000000D8\n:10D8500000000000000000000000000000000000C8\n:10D8600000000000000000000000000000000000B8\n:10D8700000000000000000000000000000000000A8\n:10D880000000000000000000000000000000000098\n:10D890000000000000000000000000000000000088\n:10D8A0000000000000000000000000000000000078\n:10D8B0000000000000000000000000000000000068\n:10D8C0000000000000000000000000000000000058\n:10D8D0000000000000000000000000000000000048\n:10D8E0000000000000000000000000000000000038\n:10D8F0000000000000000000000000000000000028\n:10D900000000000000000000000000000000000017\n:10D910000000000000000000000000000000000007\n:10D9200000000000000000000000000000000000F7\n:10D9300000000000000000000000000000000000E7\n:10D9400000000000000000000000000000000000D7\n:10D9500000000000000000000000000000000000C7\n:10D9600000000000000000000000000000000000B7\n:10D9700000000000000000000000000000000000A7\n:10D980000000000000000000000000000000000097\n:10D990000000000000000000000000000000000087\n:10D9A0000000000000000000000000000000000077\n:10D9B0000000000000000000000000000000000067\n:10D9C0000000000000000000000000000000000057\n:10D9D0000000000000000000000000000000000047\n:10D9E0000000000000000000000000000000000037\n:10D9F0000000000000000000000000000000000027\n:10DA00000000000000000000000000000000000016\n:10DA10000000000000000000000000000000000006\n:10DA200000000000000000000000000000000000F6\n:10DA300000000000000000000000000000000000E6\n:10DA400000000000000000000000000000000000D6\n:10DA500000000000000000000000000000000000C6\n:10DA600000000000000000000000000000000000B6\n:10DA700000000000000000000000000000000000A6\n:10DA80000000000000000000000000000000000096\n:10DA90000000000000000000000000000000000086\n:10DAA0000000000000000000000000000000000076\n:10DAB0000000000000000000000000000000000066\n:10DAC0000000000000000000000000000000000056\n:10DAD0000000000000000000000000000000000046\n:10DAE0000000000000000000000000000000000036\n:10DAF0000000000000000000000000000000000026\n:10DB00000000000000000000000000000000000015\n:10DB10000000000000000000000000000000000005\n:10DB200000000000000000000000000000000000F5\n:10DB300000000000000000000000000000000000E5\n:10DB400000000000000000000000000000000000D5\n:10DB500000000000000000000000000000000000C5\n:10DB600000000000000000000000000000000000B5\n:10DB700000000000000000000000000000000000A5\n:10DB80000000000000000000000000000000000095\n:10DB90000000000000000000000000000000000085\n:10DBA0000000000000000000000000000000000075\n:10DBB0000000000000000000000000000000000065\n:10DBC0000000000000000000000000000000000055\n:10DBD0000000000000000000000000000000000045\n:10DBE0000000000000000000000000000000000035\n:10DBF0000000000000000000000000000000000025\n:10DC00000000000000000000000000000000000014\n:10DC10000000000000000000000000000000000004\n:10DC200000000000000000000000000000000000F4\n:10DC300000000000000000000000000000000000E4\n:10DC400000000000000000000000000000000000D4\n:10DC500000000000000000000000000000000000C4\n:10DC600000000000000000000000000000000000B4\n:10DC700000000000000000000000000000000000A4\n:10DC80000000000000000000000000000000000094\n:10DC90000000000000000000000000000000000084\n:10DCA0000000000000000000000000000000000074\n:10DCB0000000000000000000000000000000000064\n:10DCC0000000000000000000000000000000000054\n:10DCD0000000000000000000000000000000000044\n:10DCE0000000000000000000000000000000000034\n:10DCF0000000000000000000000000000000000024\n:10DD00000000000000000000000000000000000013\n:10DD10000000000000000000000000000000000003\n:10DD200000000000000000000000000000000000F3\n:10DD300000000000000000000000000000000000E3\n:10DD400000000000000000000000000000000000D3\n:10DD500000000000000000000000000000000000C3\n:10DD600000000000000000000000000000000000B3\n:10DD700000000000000000000000000000000000A3\n:10DD80000000000000000000000000000000000093\n:10DD90000000000000000000000000000000000083\n:10DDA0000000000000000000000000000000000073\n:10DDB0000000000000000000000000000000000063\n:10DDC0000000000000000000000000000000000053\n:10DDD0000000000000000000000000000000000043\n:10DDE0000000000000000000000000000000000033\n:10DDF0000000000000000000000000000000000023\n:10DE00000000000000000000000000000000000012\n:10DE10000000000000000000000000000000000002\n:10DE200000000000000000000000000000000000F2\n:10DE300000000000000000000000000000000000E2\n:10DE400000000000000000000000000000000000D2\n:10DE500000000000000000000000000000000000C2\n:10DE600000000000000000000000000000000000B2\n:10DE700000000000000000000000000000000000A2\n:10DE80000000000000000000000000000000000092\n:10DE90000000000000000000000000000000000082\n:10DEA0000000000000000000000000000000000072\n:10DEB0000000000000000000000000000000000062\n:10DEC0000000000000000000000000000000000052\n:10DED0000000000000000000000000000000000042\n:10DEE0000000000000000000000000000000000032\n:10DEF0000000000000000000000000000000000022\n:10DF00000000000000000000000000000000000011\n:10DF10000000000000000000000000000000000001\n:10DF200000000000000000000000000000000000F1\n:10DF300000000000000000000000000000000000E1\n:10DF400000000000000000000000000000000000D1\n:10DF500000000000000000000000000000000000C1\n:10DF600000000000000000000000000000000000B1\n:10DF700000000000000000000000000000000000A1\n:10DF80000000000000000000000000000000000091\n:10DF90000000000000000000000000000000000081\n:10DFA0000000000000000000000000000000000071\n:10DFB0000000000000000000000000000000000061\n:10DFC0000000000000000000000000000000000051\n:10DFD0000000000000000000000000000000000041\n:10DFE0000000000000000000000000000000000031\n:10DFF0000000000000000000000000000000000021\n:10E000000000000000000000000000000000000010\n:10E010000000000000000000000000000000000000\n:10E0200000000000000000000000000000000000F0\n:10E0300000000000000000000000000000000000E0\n:10E0400000000000000000000000000000000000D0\n:10E0500000000000000000000000000000000000C0\n:10E0600000000000000000000000000000000000B0\n:10E0700000000000000000000000000000000000A0\n:10E080000000000000000000000000000000000090\n:10E090000000000000000000000000000000000080\n:10E0A0000000000000000000000000000000000070\n:10E0B0000000000000000000000000000000000060\n:10E0C0000000000000000000000000000000000050\n:10E0D0000000000000000000000000000000000040\n:10E0E0000000000000000000000000000000000030\n:10E0F0000000000000000000000000000000000020\n:10E10000000000000000000000000000000000000F\n:10E1100000000000000000000000000000000000FF\n:10E1200000000000000000000000000000000000EF\n:10E1300000000000000000000000000000000000DF\n:10E1400000000000000000000000000000000000CF\n:10E1500000000000000000000000000000000000BF\n:10E1600000000000000000000000000000000000AF\n:10E17000000000000000000000000000000000009F\n:10E18000000000000000000000000000000000008F\n:10E19000000000000000000000000000000000007F\n:10E1A000000000000000000000000000000000006F\n:10E1B000000000000000000000000000000000005F\n:10E1C000000000000000000000000000000000004F\n:10E1D000000000000000000000000000000000003F\n:10E1E000000000000000000000000000000000002F\n:10E1F000000000000000000000000000000000001F\n:10E20000000000000000000000000000000000000E\n:10E2100000000000000000000000000000000000FE\n:10E2200000000000000000000000000000000000EE\n:10E2300000000000000000000000000000000000DE\n:10E2400000000000000000000000000000000000CE\n:10E2500000000000000000000000000000000000BE\n:10E2600000000000000000000000000000000000AE\n:10E27000000000000000000000000000000000009E\n:10E28000000000000000000000000000000000008E\n:10E29000000000000000000000000000000000007E\n:10E2A000000000000000000000000000000000006E\n:10E2B000000000000000000000000000000000005E\n:10E2C000000000000000000000000000000000004E\n:10E2D000000000000000000000000000000000003E\n:10E2E000000000000000000000000000000000002E\n:10E2F000000000000000000000000000000000001E\n:10E30000000000000000000000000000000000000D\n:10E3100000000000000000000000000000000000FD\n:10E3200000000000000000000000000000000000ED\n:10E3300000000000000000000000000000000000DD\n:10E3400000000000000000000000000000000000CD\n:10E3500000000000000000000000000000000000BD\n:10E3600000000000000000000000000000000000AD\n:10E37000000000000000000000000000000000009D\n:10E38000000000000000000000000000000000008D\n:10E39000000000000000000000000000000000007D\n:10E3A000000000000000000000000000000000006D\n:10E3B000000000000000000000000000000000005D\n:10E3C000000000000000000000000000000000004D\n:10E3D000000000000000000000000000000000003D\n:10E3E000000000000000000000000000000000002D\n:10E3F000000000000000000000000000000000001D\n:10E40000000000000000000000000000000000000C\n:10E4100000000000000000000000000000000000FC\n:10E4200000000000000000000000000000000000EC\n:10E4300000000000000000000000000000000000DC\n:10E4400000000000000000000000000000000000CC\n:10E4500000000000000000000000000000000000BC\n:10E4600000000000000000000000000000000000AC\n:10E47000000000000000000000000000000000009C\n:10E48000000000000000000000000000000000008C\n:10E49000000000000000000000000000000000007C\n:10E4A000000000000000000000000000000000006C\n:10E4B000000000000000000000000000000000005C\n:10E4C000000000000000000000000000000000004C\n:10E4D000000000000000000000000000000000003C\n:10E4E000000000000000000000000000000000002C\n:10E4F000000000000000000000000000000000001C\n:10E50000000000000000000000000000000000000B\n:10E5100000000000000000000000000000000000FB\n:10E5200000000000000000000000000000000000EB\n:10E5300000000000000000000000000000000000DB\n:10E5400000000000000000000000000000000000CB\n:10E5500000000000000000000000000000000000BB\n:10E5600000000000000000000000000000000000AB\n:10E57000000000000000000000000000000000009B\n:10E58000000000000000000000000000000000008B\n:10E59000000000000000000000000000000000007B\n:10E5A000000000000000000000000000000000006B\n:10E5B000000000000000000000000000000000005B\n:10E5C000000000000000000000000000000000004B\n:10E5D000000000000000000000000000000000003B\n:10E5E000000000000000000000000000000000002B\n:10E5F000000000000000000000000000000000001B\n:10E60000000000000000000000000000000000000A\n:10E6100000000000000000000000000000000000FA\n:10E6200000000000000000000000000000000000EA\n:10E6300000000000000000000000000000000000DA\n:10E6400000000000000000000000000000000000CA\n:10E6500000000000000000000000000000000000BA\n:10E6600000000000000000000000000000000000AA\n:10E67000000000000000000000000000000000009A\n:10E68000000000000000000000000000000000008A\n:10E69000000000000000000000000000000000007A\n:10E6A000000000000000000000000000000000006A\n:10E6B000000000000000000000000000000000005A\n:10E6C000000000000000000000000000000000004A\n:10E6D000000000000000000000000000000000003A\n:10E6E000000000000000000000000000000000002A\n:10E6F000000000000000000000000000000000001A\n:10E700000000000000000000000000000000000009\n:10E7100000000000000000000000000000000000F9\n:10E7200000000000000000000000000000000000E9\n:10E7300000000000000000000000000000000000D9\n:10E7400000000000000000000000000000000000C9\n:10E7500000000000000000000000000000000000B9\n:10E7600000000000000000000000000000000000A9\n:10E770000000000000000000000000000000000099\n:10E780000000000000000000000000000000000089\n:10E790000000000000000000000000000000000079\n:10E7A0000000000000000000000000000000000069\n:10E7B0000000000000000000000000000000000059\n:10E7C0000000000000000000000000000000000049\n:10E7D0000000000000000000000000000000000039\n:10E7E0000000000000000000000000000000000029\n:10E7F0000000000000000000000000000000000019\n:10E800000000000000000000000000000000000008\n:10E8100000000000000000000000000000000000F8\n:10E8200000000000000000000000000000000000E8\n:10E8300000000000000000000000000000000000D8\n:10E8400000000000000000000000000000000000C8\n:10E8500000000000000000000000000000000000B8\n:10E8600000000000000000000000000000000000A8\n:10E870000000000000000000000000000000000098\n:10E880000000000000000000000000000000000088\n:10E890000000000000000000000000000000000078\n:10E8A0000000000000000000000000000000000068\n:10E8B0000000000000000000000000000000000058\n:10E8C0000000000000000000000000000000000048\n:10E8D0000000000000000000000000000000000038\n:10E8E0000000000000000000000000000000000028\n:10E8F0000000000000000000000000000000000018\n:10E900000000000000000000000000000000000007\n:10E9100000000000000000000000000000000000F7\n:10E9200000000000000000000000000000000000E7\n:10E9300000000000000000000000000000000000D7\n:10E9400000000000000000000000000000000000C7\n:10E9500000000000000000000000000000000000B7\n:10E9600000000000000000000000000000000000A7\n:10E970000000000000000000000000000000000097\n:10E980000000000000000000000000000000000087\n:10E990000000000000000000000000000000000077\n:10E9A0000000000000000000000000000000000067\n:10E9B0000000000000000000000000000000000057\n:10E9C0000000000000000000000000000000000047\n:10E9D0000000000000000000000000000000000037\n:10E9E0000000000000000000000000000000000027\n:10E9F0000000000000000000000000000000000017\n:10EA00000000000000000000000000000000000006\n:10EA100000000000000000000000000000000000F6\n:10EA200000000000000000000000000000000000E6\n:10EA300000000000000000000000000000000000D6\n:10EA400000000000000000000000000000000000C6\n:10EA500000000000000000000000000000000000B6\n:10EA600000000000000000000000000000000000A6\n:10EA70000000000000000000000000000000000096\n:10EA80000000000000000000000000000000000086\n:10EA90000000000000000000000000000000000076\n:10EAA0000000000000000000000000000000000066\n:10EAB0000000000000000000000000000000000056\n:10EAC0000000000000000000000000000000000046\n:10EAD0000000000000000000000000000000000036\n:10EAE0000000000000000000000000000000000026\n:10EAF0000000000000000000000000000000000016\n:10EB00000000000000000000000000000000000005\n:10EB100000000000000000000000000000000000F5\n:10EB200000000000000000000000000000000000E5\n:10EB300000000000000000000000000000000000D5\n:10EB400000000000000000000000000000000000C5\n:10EB500000000000000000000000000000000000B5\n:10EB600000000000000000000000000000000000A5\n:10EB70000000000000000000000000000000000095\n:10EB80000000000000000000000000000000000085\n:10EB90000000000000000000000000000000000075\n:10EBA0000000000000000000000000000000000065\n:10EBB0000000000000000000000000000000000055\n:10EBC0000000000000000000000000000000000045\n:10EBD0000000000000000000000000000000000035\n:10EBE0000000000000000000000000000000000025\n:10EBF0000000000000000000000000000000000015\n:10EC00000000000000000000000000000000000004\n:10EC100000000000000000000000000000000000F4\n:10EC200000000000000000000000000000000000E4\n:10EC300000000000000000000000000000000000D4\n:10EC400000000000000000000000000000000000C4\n:10EC500000000000000000000000000000000000B4\n:10EC600000000000000000000000000000000000A4\n:10EC70000000000000000000000000000000000094\n:10EC80000000000000000000000000000000000084\n:10EC90000000000000000000000000000000000074\n:10ECA0000000000000000000000000000000000064\n:10ECB0000000000000000000000000000000000054\n:10ECC0000000000000000000000000000000000044\n:10ECD0000000000000000000000000000000000034\n:10ECE0000000000000000000000000000000000024\n:10ECF0000000000000000000000000000000000014\n:10ED00000000000000000000000000000000000003\n:10ED100000000000000000000000000000000000F3\n:10ED200000000000000000000000000000000000E3\n:10ED300000000000000000000000000000000000D3\n:10ED400000000000000000000000000000000000C3\n:10ED500000000000000000000000000000000000B3\n:10ED600000000000000000000000000000000000A3\n:10ED70000000000000000000000000000000000093\n:10ED80000000000000000000000000000000000083\n:10ED90000000000000000000000000000000000073\n:10EDA0000000000000000000000000000000000063\n:10EDB0000000000000000000000000000000000053\n:10EDC0000000000000000000000000000000000043\n:10EDD0000000000000000000000000000000000033\n:10EDE0000000000000000000000000000000000023\n:10EDF0000000000000000000000000000000000013\n:10EE00000000000000000000000000000000000002\n:10EE100000000000000000000000000000000000F2\n:10EE200000000000000000000000000000000000E2\n:10EE300000000000000000000000000000000000D2\n:10EE400000000000000000000000000000000000C2\n:10EE500000000000000000000000000000000000B2\n:10EE600000000000000000000000000000000000A2\n:10EE70000000000000000000000000000000000092\n:10EE80000000000000000000000000000000000082\n:10EE90000000000000000000000000000000000072\n:10EEA0000000000000000000000000000000000062\n:10EEB0000000000000000000000000000000000052\n:10EEC0000000000000000000000000000000000042\n:10EED0000000000000000000000000000000000032\n:10EEE0000000000000000000000000000000000022\n:10EEF0000000000000000000000000000000000012\n:10EF00000000000000000000000000000000000001\n:10EF100000000000000000000000000000000000F1\n:10EF200000000000000000000000000000000000E1\n:10EF300000000000000000000000000000000000D1\n:10EF400000000000000000000000000000000000C1\n:10EF500000000000000000000000000000000000B1\n:10EF600000000000000000000000000000000000A1\n:10EF70000000000000000000000000000000000091\n:10EF80000000000000000000000000000000000081\n:10EF90000000000000000000000000000000000071\n:10EFA0000000000000000000000000000000000061\n:10EFB0000000000000000000000000000000000051\n:10EFC0000000000000000000000000000000000041\n:10EFD0000000000000000000000000000000000031\n:10EFE0000000000000000000000000000000000021\n:10EFF0000000000000000000000000000000000011\n:10F000000000000000000000000000000000000000\n:10F0100000000000000000000000000000000000F0\n:10F0200000000000000000000000000000000000E0\n:10F0300000000000000000000000000000000000D0\n:10F0400000000000000000000000000000000000C0\n:10F0500000000000000000000000000000000000B0\n:10F0600000000000000000000000000000000000A0\n:10F070000000000000000000000000000000000090\n:10F080000000000000000000000000000000000080\n:10F090000000000000000000000000000000000070\n:10F0A0000000000000000000000000000000000060\n:10F0B0000000000000000000000000000000000050\n:10F0C0000000000000000000000000000000000040\n:10F0D0000000000000000000000000000000000030\n:10F0E0000000000000000000000000000000000020\n:10F0F0000000000000000000000000000000000010\n:10F1000000000000000000000000000000000000FF\n:10F1100000000000000000000000000000000000EF\n:10F1200000000000000000000000000000000000DF\n:10F1300000000000000000000000000000000000CF\n:10F1400000000000000000000000000000000000BF\n:10F1500000000000000000000000000000000000AF\n:10F16000000000000000000000000000000000009F\n:10F17000000000000000000000000000000000008F\n:10F18000000000000000000000000000000000007F\n:10F19000000000000000000000000000000000006F\n:10F1A000000000000000000000000000000000005F\n:10F1B000000000000000000000000000000000004F\n:10F1C000000000000000000000000000000000003F\n:10F1D000000000000000000000000000000000002F\n:10F1E000000000000000000000000000000000001F\n:10F1F000000000000000000000000000000000000F\n:10F2000000000000000000000000000000000000FE\n:10F2100000000000000000000000000000000000EE\n:10F2200000000000000000000000000000000000DE\n:10F2300000000000000000000000000000000000CE\n:10F2400000000000000000000000000000000000BE\n:10F2500000000000000000000000000000000000AE\n:10F26000000000000000000000000000000000009E\n:10F27000000000000000000000000000000000008E\n:10F28000000000000000000000000000000000007E\n:10F29000000000000000000000000000000000006E\n:10F2A000000000000000000000000000000000005E\n:10F2B000000000000000000000000000000000004E\n:10F2C000000000000000000000000000000000003E\n:10F2D000000000000000000000000000000000002E\n:10F2E000000000000000000000000000000000001E\n:10F2F000000000000000000000000000000000000E\n:10F3000000000000000000000000000000000000FD\n:10F3100000000000000000000000000000000000ED\n:10F3200000000000000000000000000000000000DD\n:10F3300000000000000000000000000000000000CD\n:10F3400000000000000000000000000000000000BD\n:10F3500000000000000000000000000000000000AD\n:10F36000000000000000000000000000000000009D\n:10F37000000000000000000000000000000000008D\n:10F38000000000000000000000000000000000007D\n:10F39000000000000000000000000000000000006D\n:10F3A000000000000000000000000000000000005D\n:10F3B000000000000000000000000000000000004D\n:10F3C000000000000000000000000000000000003D\n:10F3D000000000000000000000000000000000002D\n:10F3E000000000000000000000000000000000001D\n:10F3F000000000000000000000000000000000000D\n:10F4000000000000000000000000000000000000FC\n:10F4100000000000000000000000000000000000EC\n:10F4200000000000000000000000000000000000DC\n:10F4300000000000000000000000000000000000CC\n:10F4400000000000000000000000000000000000BC\n:10F4500000000000000000000000000000000000AC\n:10F46000000000000000000000000000000000009C\n:10F47000000000000000000000000000000000008C\n:10F48000000000000000000000000000000000007C\n:10F49000000000000000000000000000000000006C\n:10F4A000000000000000000000000000000000005C\n:10F4B000000000000000000000000000000000004C\n:10F4C000000000000000000000000000000000003C\n:10F4D000000000000000000000000000000000002C\n:10F4E000000000000000000000000000000000001C\n:10F4F000000000000000000000000000000000000C\n:10F5000000000000000000000000000000000000FB\n:10F5100000000000000000000000000000000000EB\n:10F5200000000000000000000000000000000000DB\n:10F5300000000000000000000000000000000000CB\n:10F5400000000000000000000000000000000000BB\n:10F5500000000000000000000000000000000000AB\n:10F56000000000000000000000000000000000009B\n:10F57000000000000000000000000000000000008B\n:10F58000000000000000000000000000000000007B\n:10F59000000000000000000000000000000000006B\n:10F5A000000000000000000000000000000000005B\n:10F5B000000000000000000000000000000000004B\n:10F5C000000000000000000000000000000000003B\n:10F5D000000000000000000000000000000000002B\n:10F5E000000000000000000000000000000000001B\n:10F5F000000000000000000000000000000000000B\n:10F6000000000000000000000000000000000000FA\n:10F6100000000000000000000000000000000000EA\n:10F6200000000000000000000000000000000000DA\n:10F6300000000000000000000000000000000000CA\n:10F6400000000000000000000000000000000000BA\n:10F6500000000000000000000000000000000000AA\n:10F66000000000000000000000000000000000009A\n:10F67000000000000000000000000000000000008A\n:10F68000000000000000000000000000000000007A\n:10F69000000000000000000000000000000000006A\n:10F6A000000000000000000000000000000000005A\n:10F6B000000000000000000000000000000000004A\n:10F6C000000000000000000000000000000000003A\n:10F6D000000000000000000000000000000000002A\n:10F6E000000000000000000000000000000000001A\n:10F6F000000000000000000000000000000000000A\n:10F7000000000000000000000000000000000000F9\n:10F7100000000000000000000000000000000000E9\n:10F7200000000000000000000000000000000000D9\n:10F7300000000000000000000000000000000000C9\n:10F7400000000000000000000000000000000000B9\n:10F7500000000000000000000000000000000000A9\n:10F760000000000000000000000000000000000099\n:10F770000000000000000000000000000000000089\n:10F780000000000000000000000000000000000079\n:10F790000000000000000000000000000000000069\n:10F7A0000000000000000000000000000000000059\n:10F7B0000000000000000000000000000000000049\n:10F7C0000000000000000000000000000000000039\n:10F7D0000000000000000000000000000000000029\n:10F7E0000000000000000000000000000000000019\n:10F7F0000000000000000000000000000000000009\n:10F8000000000000000000000000000000000000F8\n:10F8100000000000000000000000000000000000E8\n:10F8200000000000000000000000000000000000D8\n:10F8300000000000000000000000000000000000C8\n:10F8400000000000000000000000000000000000B8\n:10F8500000000000000000000000000000000000A8\n:10F860000000000000000000000000000000000098\n:10F870000000000000000000000000000000000088\n:10F880000000000000000000000000000000000078\n:10F890000000000000000000000000000000000068\n:10F8A0000000000000000000000000000000000058\n:10F8B0000000000000000000000000000000000048\n:10F8C0000000000000000000000000000000000038\n:10F8D0000000000000000000000000000000000028\n:10F8E0000000000000000000000000000000000018\n:10F8F0000000000000000000000000000000000008\n:10F9000000000000000000000000000000000000F7\n:10F9100000000000000000000000000000000000E7\n:10F9200000000000000000000000000000000000D7\n:10F9300000000000000000000000000000000000C7\n:10F9400000000000000000000000000000000000B7\n:10F9500000000000000000000000000000000000A7\n:10F960000000000000000000000000000000000097\n:10F970000000000000000000000000000000000087\n:10F980000000000000000000000000000000000077\n:10F990000000000000000000000000000000000067\n:10F9A0000000000000000000000000000000000057\n:10F9B0000000000000000000000000000000000047\n:10F9C0000000000000000000000000000000000037\n:10F9D0000000000000000000000000000000000027\n:10F9E0000000000000000000000000000000000017\n:10F9F0000000000000000000000000000000000007\n:10FA000000000000000000000000000000000000F6\n:10FA100000000000000000000000000000000000E6\n:10FA200000000000000000000000000000000000D6\n:10FA300000000000000000000000000000000000C6\n:10FA400000000000000000000000000000000000B6\n:10FA500000000000000000000000000000000000A6\n:10FA60000000000000000000000000000000000096\n:10FA70000000000000000000000000000000000086\n:10FA80000000000000000000000000000000000076\n:10FA90000000000000000000000000000000000066\n:10FAA0000000000000000000000000000000000056\n:10FAB0000000000000000000000000000000000046\n:10FAC0000000000000000000000000000000000036\n:10FAD0000000000000000000000000000000000026\n:10FAE0000000000000000000000000000000000016\n:10FAF0000000000000000000000000000000000006\n:10FB000000000000000000000000000000000000F5\n:10FB100000000000000000000000000000000000E5\n:10FB200000000000000000000000000000000000D5\n:10FB300000000000000000000000000000000000C5\n:10FB400000000000000000000000000000000000B5\n:10FB500000000000000000000000000000000000A5\n:10FB60000000000000000000000000000000000095\n:10FB70000000000000000000000000000000000085\n:10FB80000000000000000000000000000000000075\n:10FB90000000000000000000000000000000000065\n:10FBA0000000000000000000000000000000000055\n:10FBB0000000000000000000000000000000000045\n:10FBC0000000000000000000000000000000000035\n:10FBD0000000000000000000000000000000000025\n:10FBE0000000000000000000000000000000000015\n:10FBF0000000000000000000000000000000000005\n:10FC000000000000000000000000000000000000F4\n:10FC100000000000000000000000000000000000E4\n:10FC200000000000000000000000000000000000D4\n:10FC300000000000000000000000000000000000C4\n:10FC400000000000000000000000000000000000B4\n:10FC500000000000000000000000000000000000A4\n:10FC60000000000000000000000000000000000094\n:10FC70000000000000000000000000000000000084\n:10FC80000000000000000000000000000000000074\n:10FC90000000000000000000000000000000000064\n:10FCA0000000000000000000000000000000000054\n:10FCB0000000000000000000000000000000000044\n:10FCC0000000000000000000000000000000000034\n:10FCD0000000000000000000000000000000000024\n:10FCE0000000000000000000000000000000000014\n:10FCF0000000000000000000000000000000000004\n:10FD000000000000000000000000000000000000F3\n:10FD100000000000000000000000000000000000E3\n:10FD200000000000000000000000000000000000D3\n:10FD300000000000000000000000000000000000C3\n:10FD400000000000000000000000000000000000B3\n:10FD500000000000000000000000000000000000A3\n:10FD60000000000000000000000000000000000093\n:10FD70000000000000000000000000000000000083\n:10FD80000000000000000000000000000000000073\n:10FD90000000000000000000000000000000000063\n:10FDA0000000000000000000000000000000000053\n:10FDB0000000000000000000000000000000000043\n:10FDC0000000000000000000000000000000000033\n:10FDD0000000000000000000000000000000000023\n:10FDE0000000000000000000000000000000000013\n:10FDF0000000000000000000000000000000000003\n:10FE000000000000000000000000000000000000F2\n:10FE100000000000000000000000000000000000E2\n:10FE200000000000000000000000000000000000D2\n:10FE300000000000000000000000000000000000C2\n:10FE400000000000000000000000000000000000B2\n:10FE500000000000000000000000000000000000A2\n:10FE60000000000000000000000000000000000092\n:10FE70000000000000000000000000000000000082\n:10FE80000000000000000000000000000000000072\n:10FE90000000000000000000000000000000000062\n:10FEA0000000000000000000000000000000000052\n:10FEB0000000000000000000000000000000000042\n:10FEC0000000000000000000000000000000000032\n:10FED0000000000000000000000000000000000022\n:10FEE0000000000000000000000000000000000012\n:10FEF0000000000000000000000000000000000002\n:10FF000000000000000000000000000000000000F1\n:10FF100000000000000000000000000000000000E1\n:10FF200000000000000000000000000000000000D1\n:10FF300000000000000000000000000000000000C1\n:10FF400000000000000000000000000000000000B1\n:10FF500000000000000000000000000000000000A1\n:10FF60000000000000000000000000000000000091\n:10FF70000000000000000000000000000000000081\n:10FF80000000000000000000000000000000000071\n:10FF90000000000000000000000000000000000061\n:10FFA0000000000000000000000000000000000051\n:10FFB0000000000000000000000000000000000041\n:10FFC0000000000000000000000000000000000031\n:10FFD0000000000000000000000000000000000021\n:10FFE0000000000000000000000000000000000011\n:10FFF0000000000000000000000000000000000001\n:02000004620692\n:1000000000000000000000000000000000000000F0\n:1000100000000000000000000000000000000000E0\n:1000200000000000000000000000000000000000D0\n:1000300000000000000000000000000000000000C0\n:1000400000000000000000000000000000000000B0\n:1000500000000000000000000000000000000000A0\n:100060000000000000000000000000000000000090\n:100070000000000000000000000000000000000080\n:100080000000000000000000000000000000000070\n:100090000000000000000000000000000000000060\n:1000A0000000000000000000000000000000000050\n:1000B0000000000000000000000000000000000040\n:1000C0000000000000000000000000000000000030\n:1000D0000000000000000000000000000000000020\n:1000E0000000000000000000000000000000000010\n:1000F0000000000000000000000000000000000000\n:1001000000000000000000000000000000000000EF\n:1001100000000000000000000000000000000000DF\n:1001200000000000000000000000000000000000CF\n:1001300000000000000000000000000000000000BF\n:1001400000000000000000000000000000000000AF\n:10015000000000000000000000000000000000009F\n:10016000000000000000000000000000000000008F\n:10017000000000000000000000000000000000007F\n:10018000000000000000000000000000000000006F\n:0C01900000000000000000000000000063\n:040000056200004055\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/.gitignore",
    "content": ".dep\nsrc/main.lst\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H__ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\nmonitor mww 0xA0000050 0x01c2\nmonitor mdw 0xA0000050\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\nmonitor mww 0xA0000050 0x01c2\nmonitor mdw 0xA0000050\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/hitex_str7_ram.ld",
    "content": "/***********************************************************************************\n*\tCopyright 2005 Anglia Design\n*\tThis demo code and associated components are provided as is and has no warranty,\n*\timplied or otherwise.  You are free to use/modify any of the provided\n*\tcode at your own risk in your applications with the expressed limitation\n*\tof liability (see below)\n* \n*\tLIMITATION OF LIABILITY:   ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY\n*\tLOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR\n*\tINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER\n*\tTHIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n*\n*\tAuthor\t\t\t: Spencer Oliver\n*\tWeb     \t\t: www.anglia-designs.com\n*\n***********************************************************************************/\n\n/* Stack Sizes */\n\n\t_STACKSIZE     = 1024;\n\t_STACKSIZE_IRQ = 256;\n\t_STACKSIZE_FIQ = 0;\n\t_STACKSIZE_SVC = 1024;\n\t_STACKSIZE_ABT = 0;\n\t_STACKSIZE_UND = 0;\n\t_HEAPSIZE      = 1024;\n  \n/* Memory Definitions */\n\nMEMORY\n{\n\tDATA (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000\n}\n\n/* Section Definitions */\n\nSECTIONS\n{\t\n\t/* first section is .text which is used for code */\n\n\t.text :\n\t{\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP(*(.vectrom))\n\t\tKEEP(*(.init))\n\t\t*(.text .text.*)\n\t\t*(.gnu.linkonce.t.*)\n\t\t*(.glue_7t) *(.glue_7) *(.vfp11_veneer)\n\t\tKEEP(*(.fini))\n\t\t*(.gcc_except_table)\n\t} >DATA =0\n\t. = ALIGN(4);\n\n\t/* .ctors .dtors are used for c++ constructors/destructors */\n\t\n\t.ctors :\n\t{\n\t\tPROVIDE(__ctors_start__ = .);\n\t\tKEEP(*(SORT(.ctors.*)))\n\t\tKEEP(*(.ctors))\n\t\tPROVIDE(__ctors_end__ = .);\n\t} >DATA\n\n\t.dtors :\n\t{\n\t\tPROVIDE(__dtors_start__ = .); \n\t\tKEEP(*(SORT(.dtors.*)))\n\t\tKEEP(*(.dtors))\n\t\tPROVIDE(__dtors_end__ = .);\n\t} >DATA\n\t\n\t/* .rodata section which is used for read-only data (constants) */\n\n\t.rodata :\n\t{\n\t\t*(.rodata .rodata.*)\n\t\t*(.gnu.linkonce.r.*)\n\t} >DATA\n\t. = ALIGN(4);\n\n\t.init_array :\n\t{\n\t\t*(.init)\n        *(.fini)\n\t\tPROVIDE (__preinit_array_start = .);\n\t\tKEEP (*(.preinit_array))\n\t\tPROVIDE (__preinit_array_end = .);\n\t\tPROVIDE (__init_array_start = .);\n\t\tKEEP (*(SORT(.init_array.*)))\n\t\tKEEP (*(.init_array))\n\t\tPROVIDE (__init_array_end = .);\n\t\tPROVIDE (__fini_array_start = .);\n\t\tKEEP (*(.fini_array))\n\t\tKEEP (*(SORT(.fini_array.*)))\n\t\tPROVIDE (__fini_array_end = .);\n\t} >DATA\n\n\t. = ALIGN(4);\n\t\n\t/* .ARM.exidx is sorted, so has to go in its own output section.  */\n\t__exidx_start = .;\n\t.ARM.exidx :\n\t{\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t} >DATA\n\t__exidx_end = .;\n\n\t_vectext = .;\n\tPROVIDE (vectext = .);\n\n\t.vect : AT (_vectext)\n\t{\n\t\t_vecstart = .;\n\t\tKEEP(*(.vectram))\n\t\t_vecend = .;\n\t} >DATA\n\n\t_etext = _vectext + SIZEOF(.vect);\n\tPROVIDE (etext = .);\n\n\t/* .data section which is used for initialized data */\n\n\t.data : AT (_etext)\n\t{\n\t\t*(.data .data.*)\n\t\t*(.gnu.linkonce.d.*)\n\t\tSORT(CONSTRUCTORS)\n\t} >DATA\n\t. = ALIGN(4);\n\t\n\t__data_start = .;\n\t_edata = .;\n\tPROVIDE (edata = .);\n\n\t/* .bss section which is used for uninitialized data */\n\n\t.bss :\n\t{\n\t\t__bss_start = .;\n\t\t__bss_start__ = .;\n\t\t*(.bss .bss.*)\n\t\t*(.gnu.linkonce.b.*)\n\t\t*(COMMON)\n\t\t. = ALIGN(4);\n\t} >DATA\n\t. = ALIGN(4);\n\t__bss_end__ = .;\n\t\n\t_end = .;\n\tPROVIDE(end = .);\n\n\t/* .heap section which is used for memory allocation */\n\t\n\t.heap (NOLOAD) :\n\t{\n\t\t__heap_start__ = .;\n\t\t*(.heap)\n\t\t. = MAX(__heap_start__ + _HEAPSIZE , .);\n\t} >DATA\n\t__heap_end__ = __heap_start__ + SIZEOF(.heap);\n\t\n\t/* .stack section - user mode stack */\n\t\n\t.stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_start__ = .;\n\t\t*(.stack)\n\t\t. = MAX(__stack_start__ + _STACKSIZE , .);\n\t} >DATA\n\t__stack_end__ = __stack_start__ + SIZEOF(.stack);\n\n\t/* .stack_irq section */\n\t\n\t.stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_irq_start__ = .;\n\t\t*(.stack_irq)\n\t\t. = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .);\n\t} >DATA\n\t__stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq);\n\n\t/* .stack_fiq section */\n\t\n\t.stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_fiq_start__ = .;\n\t\t*(.stack_fiq)\n\t    . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .);\n\t} >DATA\n\t__stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq);\n\n\t/* .stack_svc section */\n\t\n\t.stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_svc_start__ = .;\n\t\t*(.stack_svc)\n\t\t. = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .);\n\t} >DATA\n\t__stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc);\n\n\t/* .stack_abt section */\n\t\n\t.stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_abt_start__ = .;\n\t\t*(.stack_abt)\n\t\t. = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .);\n\t} >DATA\n\t__stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt);\n\n\t/* .stack_und section */\n\t\n\t.stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_und_start__ = .;\n\t\t*(.stack_und)\n    \t. = MAX(__stack_und_start__ + _STACKSIZE_UND , .);\n\t} >DATA\n\t__stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und);\n\t\n\t/* Stabs debugging sections.  */\n\t.stab          0 : { *(.stab) }\n\t.stabstr       0 : { *(.stabstr) }\n\t.stab.excl     0 : { *(.stab.excl) }\n\t.stab.exclstr  0 : { *(.stab.exclstr) }\n\t.stab.index    0 : { *(.stab.index) }\n\t.stab.indexstr 0 : { *(.stab.indexstr) }\n\t.comment       0 : { *(.comment) }\n\t/* DWARF debug sections.\n\t\tSymbols in the DWARF debugging sections are relative to the beginning\n\t\tof the section so we begin them at 0.  */\n\t/* DWARF 1 */\n\t.debug          0 : { *(.debug) }\n\t.line           0 : { *(.line) }\n\t/* GNU DWARF 1 extensions */\n\t.debug_srcinfo  0 : { *(.debug_srcinfo) }\n\t.debug_sfnames  0 : { *(.debug_sfnames) }\n\t/* DWARF 1.1 and DWARF 2 */\n\t.debug_aranges  0 : { *(.debug_aranges) }\n\t.debug_pubnames 0 : { *(.debug_pubnames) }\n\t/* DWARF 2 */\n\t.debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\t.debug_abbrev   0 : { *(.debug_abbrev) }\n\t.debug_line     0 : { *(.debug_line) }\n\t.debug_frame    0 : { *(.debug_frame) }\n\t.debug_str      0 : { *(.debug_str) }\n\t.debug_loc      0 : { *(.debug_loc) }\n\t.debug_macinfo  0 : { *(.debug_macinfo) }\n\t/* SGI/MIPS DWARF 2 extensions */\n\t.debug_weaknames 0 : { *(.debug_weaknames) }\n\t.debug_funcnames 0 : { *(.debug_funcnames) }\n\t.debug_typenames 0 : { *(.debug_typenames) }\n\t.debug_varnames  0 : { *(.debug_varnames) }\t\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/hitex_str7_rom.ld",
    "content": "/***********************************************************************************\n*\tCopyright 2005 Anglia Design\n*\tThis demo code and associated components are provided as is and has no warranty,\n*\timplied or otherwise.  You are free to use/modify any of the provided\n*\tcode at your own risk in your applications with the expressed limitation\n*\tof liability (see below)\n* \n*\tLIMITATION OF LIABILITY:   ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY\n*\tLOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR\n*\tINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER\n*\tTHIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n*\n*\tAuthor\t\t\t: Spencer Oliver\n*\tWeb     \t\t: www.anglia-designs.com\n*\n***********************************************************************************/\n\n/* Stack Sizes */\n\n\t_STACKSIZE     = 1024;\n\t_STACKSIZE_IRQ = 256;\n\t_STACKSIZE_FIQ = 0;\n\t_STACKSIZE_SVC = 1024;\n\t_STACKSIZE_ABT = 0;\n\t_STACKSIZE_UND = 0;\n\t_HEAPSIZE      = 1024;\n\n/* Memory Definitions */\n\nMEMORY\n{\n\tCODE (rx) : ORIGIN = 0x40000000, LENGTH = 0x00040000\n\tDATA (rw) : ORIGIN = 0x20000000, LENGTH = 0x00010000\n}\n\n/* Section Definitions */\n\nSECTIONS\n{\n\t/* first section is .text which is used for code */\n\n\t.text :\n\t{\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP(*(.vectrom))\n\t\tKEEP(*(.init))\n\t\t*(.text .text.*)\n\t\t*(.gnu.linkonce.t.*)\n\t\t*(.glue_7t) *(.glue_7) *(.vfp11_veneer)\n\t\tKEEP(*(.fini))\n\t\t*(.gcc_except_table)\n\t} >CODE =0\n\t. = ALIGN(4);\n\n\t/* .ctors .dtors are used for c++ constructors/destructors */\n\t\n\t.ctors :\n\t{\n\t\tPROVIDE(__ctors_start__ = .);\n\t\tKEEP(*(SORT(.ctors.*)))\n\t\tKEEP(*(.ctors))\n\t\tPROVIDE(__ctors_end__ = .);\n\t} >CODE\n\n\t.dtors :\n\t{\n\t\tPROVIDE(__dtors_start__ = .); \n\t\tKEEP(*(SORT(.dtors.*)))\n\t\tKEEP(*(.dtors))\n\t\tPROVIDE(__dtors_end__ = .);\n\t} >CODE\n\t\n\t/* .rodata section which is used for read-only data (constants) */\n\n\t.rodata :\n\t{\n\t\t*(.rodata .rodata.*)\n\t\t*(.gnu.linkonce.r.*)\n\t} >CODE\n\t. = ALIGN(4);\n\n\t.init_array :\n\t{\n\t\t*(.init)\n        *(.fini)\n\t\tPROVIDE (__preinit_array_start = .);\n\t\tKEEP (*(.preinit_array))\n\t\tPROVIDE (__preinit_array_end = .);\n\t\tPROVIDE (__init_array_start = .);\n\t\tKEEP (*(SORT(.init_array.*)))\n\t\tKEEP (*(.init_array))\n\t\tPROVIDE (__init_array_end = .);\n\t\tPROVIDE (__fini_array_start = .);\n\t\tKEEP (*(.fini_array))\n\t\tKEEP (*(SORT(.fini_array.*)))\n\t\tPROVIDE (__fini_array_end = .);\n\t} >CODE\n\n\t. = ALIGN(4);\n\t\n\t/* .ARM.exidx is sorted, so has to go in its own output section.  */\n\t__exidx_start = .;\n\t.ARM.exidx :\n\t{\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t} >CODE\n\t__exidx_end = .;\n\n\t_vectext = .;\n\tPROVIDE (vectext = .);\n\n\t.vect : AT (_vectext)\n\t{\n\t\t_vecstart = .;\n\t\tKEEP(*(.vectram))\n\t\t_vecend = .;\n\t} >DATA\n\n\t_etext = _vectext + SIZEOF(.vect);\n\tPROVIDE (etext = .);\n\n\t/* .data section which is used for initialized data */\n\n\t.data : AT (_etext)\n\t{\n\t\t__data_start = .;\n\t\t*(.data .data.*)\n\t\t*(.gnu.linkonce.d.*)\n\t\tSORT(CONSTRUCTORS)\n\t\t. = ALIGN(4);\n\t\t*(.fastrun .fastrun.*)\n\t} >DATA\n\t. = ALIGN(4);\n\t\n\t_edata = .;\n\tPROVIDE (edata = .);\n\n\t/* .bss section which is used for uninitialized data */\n\n\t.bss :\n\t{\n\t\t__bss_start = .;\n\t\t__bss_start__ = .;\n\t\t*(.bss .bss.*)\n\t\t*(.gnu.linkonce.b.*)\n\t\t*(COMMON)\n\t\t. = ALIGN(4);\n\t} >DATA\n\t. = ALIGN(4);\n\t__bss_end__ = .;\n\t\n\t_end = .;\n\tPROVIDE(end = .);\n\n\t/* .heap section which is used for memory allocation */\n\t\n\t.heap (NOLOAD) :\n\t{\n\t\t__heap_start__ = .;\n\t\t*(.heap)\n\t\t. = MAX(__heap_start__ + _HEAPSIZE , .);\n\t} >DATA\n\t__heap_end__ = __heap_start__ + SIZEOF(.heap);\n\t\n\t/* .stack section - user mode stack */\n\t\n\t.stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_start__ = .;\n\t\t*(.stack)\n\t\t. = MAX(__stack_start__ + _STACKSIZE , .);\n\t} >DATA\n\t__stack_end__ = __stack_start__ + SIZEOF(.stack);\n\n\t/* .stack_irq section */\n\t\n\t.stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_irq_start__ = .;\n\t\t*(.stack_irq)\n\t\t. = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .);\n\t} >DATA\n\t__stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq);\n\n\t/* .stack_fiq section */\n\t\n\t.stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_fiq_start__ = .;\n\t\t*(.stack_fiq)\n\t    . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .);\n\t} >DATA\n\t__stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq);\n\n\t/* .stack_svc section */\n\t\n\t.stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_svc_start__ = .;\n\t\t*(.stack_svc)\n\t\t. = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .);\n\t} >DATA\n\t__stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc);\n\n\t/* .stack_abt section */\n\t\n\t.stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_abt_start__ = .;\n\t\t*(.stack_abt)\n\t\t. = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .);\n\t} >DATA\n\t__stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt);\n\n\t/* .stack_und section */\n\t\n\t.stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_und_start__ = .;\n\t\t*(.stack_und)\n    \t. = MAX(__stack_und_start__ + _STACKSIZE_UND , .);\n\t} >DATA\n\t__stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und);\n  \n\t/* Stabs debugging sections.  */\n\t.stab          0 : { *(.stab) }\n\t.stabstr       0 : { *(.stabstr) }\n\t.stab.excl     0 : { *(.stab.excl) }\n\t.stab.exclstr  0 : { *(.stab.exclstr) }\n\t.stab.index    0 : { *(.stab.index) }\n\t.stab.indexstr 0 : { *(.stab.indexstr) }\n\t.comment       0 : { *(.comment) }\n\t/* DWARF debug sections.\n\t\tSymbols in the DWARF debugging sections are relative to the beginning\n\t\tof the section so we begin them at 0.  */\n\t/* DWARF 1 */\n\t.debug          0 : { *(.debug) }\n\t.line           0 : { *(.line) }\n\t/* GNU DWARF 1 extensions */\n\t.debug_srcinfo  0 : { *(.debug_srcinfo) }\n\t.debug_sfnames  0 : { *(.debug_sfnames) }\n\t/* DWARF 1.1 and DWARF 2 */\n\t.debug_aranges  0 : { *(.debug_aranges) }\n\t.debug_pubnames 0 : { *(.debug_pubnames) }\n\t/* DWARF 2 */\n\t.debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\t.debug_abbrev   0 : { *(.debug_abbrev) }\n\t.debug_line     0 : { *(.debug_line) }\n\t.debug_frame    0 : { *(.debug_frame) }\n\t.debug_str      0 : { *(.debug_str) }\n\t.debug_loc      0 : { *(.debug_loc) }\n\t.debug_macinfo  0 : { *(.debug_macinfo) }\n\t/* SGI/MIPS DWARF 2 extensions */\n\t.debug_weaknames 0 : { *(.debug_weaknames) }\n\t.debug_funcnames 0 : { *(.debug_funcnames) }\n\t.debug_typenames 0 : { *(.debug_typenames) }\n\t.debug_varnames  0 : { *(.debug_varnames) }\t\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/str710_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 0\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst srst_pulls_trst\n\n#jtag scan chain\njtag newtap str7 cpu -irlen 4 -irmask 0xf\n\n#target configuration\ntarget create target0 arm7tdmi -endian little -chain-position 0\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x2000C000 -work-area-size 0x4000 -work-area-backup false\n\ntarget_script 0 gdb_program_config .\\prj\\str710_program.script\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nflash bank str7x 0x40000000 0x00040000 0 0 0 STR71x\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/prj/str710_program.script",
    "content": "flash protect 0 0 7 off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/src/crt.s",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*\n*  History:\n*\n*  04.03.06  mifi   First Version\n*                   This version based on an example from Ethernut and\n*                   \"ARM Cross Development with Eclipse\" from James P. Lynch\n*\n*  26.01.08  mifi   Change the code of the init section. Here I have used\n*                   some of the source from the Anglia startup.s\n*                   Author: Spencer Oliver (www.anglia-designs.com)\n****************************************************************************/\n\n/*\n * Some defines for the program status registers\n */\n   ARM_MODE_USER  = 0x10      /* Normal User Mode \t\t\t\t\t          */\n   ARM_MODE_FIQ   = 0x11      /* FIQ Fast Interrupts Mode \t\t\t\t      */\n   ARM_MODE_IRQ   = 0x12      /* IRQ Standard Interrupts Mode \t\t\t      */\n   ARM_MODE_SVC   = 0x13      /* Supervisor Interrupts Mode \t\t\t      */\n   ARM_MODE_ABORT = 0x17      /* Abort Processing memory Faults Mode \t\t  */\n   ARM_MODE_UNDEF = 0x1B      /* Undefined Instructions Mode \t\t          */\n   ARM_MODE_SYS   = 0x1F      /* System Running in Priviledged Operating Mode */\n   ARM_MODE_MASK  = 0x1F\n\n   I_BIT          = 0x80      /* disable IRQ when I bit is set */\n   F_BIT          = 0x40      /* disable IRQ when I bit is set */\n\n/*\n * Register Base Address\n */\n   PRCCU_BASE     = 0xA0000000\n   RCCU_CFR       = 0x08\n   RCCU_PLL1CR    = 0x18\n   PCU_MDIVR      = 0x40\n   PCU_PDIVR      = 0x44\n   PCU_BOOTCR     = 0x50\n\n\n   .section .vectors,\"ax\"\n   .code 32\n\n/****************************************************************************/\n/*               Vector table and reset entry                               */\n/****************************************************************************/\n_vectors:\n   ldr pc, ResetAddr    /* Reset                 */\n   ldr pc, UndefAddr    /* Undefined instruction */\n   ldr pc, SWIAddr      /* Software interrupt    */\n   ldr pc, PAbortAddr   /* Prefetch abort        */\n   ldr pc, DAbortAddr   /* Data abort            */\n   ldr pc, ReservedAddr /* Reserved              */\n   ldr pc, IRQAddr      /* IRQ interrupt         */\n   ldr pc, FIQAddr      /* FIQ interrupt         */\n\n\nResetAddr:     .word ResetHandler\nUndefAddr:     .word UndefHandler\nSWIAddr:       .word SWIHandler\nPAbortAddr:    .word PAbortHandler\nDAbortAddr:    .word DAbortHandler\nReservedAddr:  .word 0\nIRQAddr:       .word IRQHandler\nFIQAddr:       .word FIQHandler\n\n   .ltorg\n\n\n   .section .init, \"ax\"\n   .code 32\n\n   .global ResetHandler\n   .global ExitFunction\n   .extern main\n/****************************************************************************/\n/*                           Reset handler                                  */\n/****************************************************************************/\nResetHandler:\n/*\n * Wait for the oscillator is stable\n */\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n   nop\n\n/*\n * Setup STR71X, for more information about the register\n * take a look in the STR71x Microcontroller Reference Manual.\n *\n * Reference is made to: Rev. 6 March 2005\n *\n * 1. Map internal RAM to address 0\n *    In this case, we are running always in the RAM\n *    this make no sence. But if we are in flash, we\n *    can copy the interrupt vectors into the ram and\n *    switch to RAM mode.\n *\n * 2. Setup the PLL, the eval board HITEX STR7 is equipped\n *    with an external 16MHz oscillator. We want:\n *\n *    RCLK:  32MHz = (CLK2 * 16) / 4\n *    MCLK:  32Mhz\n *    PCLK1: 32MHz\n *    PCLK2: 32MHz\n *\n */\n\n   /*\n    * 1. Map RAM to the boot memory 0x00000000\n    */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x01C2\n   str   r1, [r0, #PCU_BOOTCR]\n\n\n   /*\n    * 2. Setup PLL start\n    */\n\n   /* Set the prescaling factor for APB and APB1 group */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0000             /* no prescaling PCLKx = RCLK */\n   str   r1, [r0, #PCU_PDIVR]\n\n   /* Set the prescaling factor for the Main System Clock MCLK */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0000             /* no prescaling MCLK = RCLK\n   str   r1, [r0, #PCU_MDIVR]\n\n   /* Configure the PLL1 ( * 16 , / 4 ) */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x0073\n   str   r1, [r0, #RCCU_PLL1CR]\n\n   /* Check if the PLL is locked */\npll_lock_loop:\n   ldr   r1, [r0, #RCCU_CFR]\n   tst   r1, #0x0002\n   beq   pll_lock_loop\n\n   /*  Select PLL1_Output as RCLK clock */\n   ldr   r0, =PRCCU_BASE\n   ldr   r1, =0x8009\n   str   r1, [r0, #RCCU_CFR]\n\n   /*\n    * Setup PLL end\n    */\n\n\n   /*\n    * Setup a stack for each mode\n    */\n   msr   CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT   /* Undefined Instruction Mode */\n   ldr   sp, =__stack_und_end__\n\n   msr   CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT   /* Abort Mode */\n   ldr   sp, =__stack_abt_end__\n\n   msr   CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT     /* FIQ Mode */\n   ldr   sp, =__stack_fiq_end__\n\n   msr   CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT     /* IRQ Mode */\n   ldr   sp, =__stack_irq_end__\n\n   msr   CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT     /* Supervisor Mode */\n   ldr   sp, =__stack_svc_end__\n\n\n   /*\n    * Now init all the sections\n    */\n\n\n   /*\n    * Relocate .data section (Copy from ROM to RAM)\n    */\n\t ldr   r1, =_etext\n\t ldr   r2, =__data_start\n\t ldr   r3, =_edata\nLoopRel:\n\t cmp   r2, r3\n\t ldrlo r0, [r1], #4\n\t strlo r0, [r2], #4\n\t blo   LoopRel\n\n\n   /*\n    * Clear .bss section (Zero init)\n    */\n\t mov   r0, #0\n\t ldr   r1, =__bss_start__\n\t ldr   r2, =__bss_end__\nLoopZI:\n\t cmp   r1, r2\n\t strlo r0, [r1], #4\n\t blo   LoopZI\n\n\n   /*\n    * Call C++ constructors\n    */\n\t ldr \t r0, =__ctors_start__\n\t ldr \t r1, =__ctors_end__\nctor_loop:\n\t cmp \t r0, r1\n\t beq \t ctor_end\n\t ldr \t r2, [r0], #4\n\t stmfd sp!, {r0-r1}\n\t mov \t lr, pc\n\t mov \t pc, r2\n\t ldmfd sp!, {r0-r1}\n\t b \t\t ctor_loop\nctor_end:\n\n\n   /*\n    * Jump to main\n    */\n   mrs   r0, cpsr\n   bic   r0, r0, #I_BIT | F_BIT     /* Enable FIQ and IRQ interrupt */\n   msr   cpsr, r0\n\n   mov   r0, #0 /* No arguments */\n   mov   r1, #0 /* No arguments */\n   ldr   r2, =main\n   mov   lr, pc\n   bx    r2     /* And jump... */\n\nExitFunction:\n   nop\n   nop\n   nop\n   b ExitFunction\n\n\n/****************************************************************************/\n/*                         Default interrupt handler                        */\n/****************************************************************************/\n\nUndefHandler:\n   b UndefHandler\n\nSWIHandler:\n   b SWIHandler\n\nPAbortHandler:\n   b PAbortHandler\n\nDAbortHandler:\n   b DAbortHandler\n\nIRQHandler:\n   b IRQHandler\n\nFIQHandler:\n   b FIQHandler\n\n   .weak ExitFunction\n   .weak UndefHandler, PAbortHandler, DAbortHandler\n   .weak IRQHandler, FIQHandler\n\n   .ltorg\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include \"typedefs.h\"\n\n/* Increase the size of this dummy global data to create a larger ROM image */\nstatic const char test[] =\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\"\n\t\t\"ljasdfljkasdfljsaflsjadflksjadflksjadfasdfsadfsa\";\n\n\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/test_ram.hex",
    "content": ":020000042000DA\n:100000000000A0E10000A0E10000A0E10000A0E1EC\n:100010000000A0E10000A0E10000A0E10000A0E1DC\n:100020000A02A0E304119FE5501080E50A02A0E354\n:100030000010A0E3441080E50A02A0E30010A0E352\n:100040000A02A0E37310A0E3181080E5081090E501\n:10005000020011E3FCFFFF0A0A02A0E3D0109FE5B3\n:10006000081080E5DBF021E3C8D09FE5D7F021E35D\n:10007000C4D09FE5D1F021E3C0D09FE5D2F021E3C9\n:10008000BCD09FE5D3F021E3B8D09FE5B8109FE541\n:10009000B8209FE5B8309FE5030052E10400913499\n:1000A00004008234FBFFFF3A0000A0E3A4109FE5A8\n:1000B000A4209FE5020051E104008134FCFFFF3AD7\n:1000C00098009FE598109FE5010050E10500000AA7\n:1000D000042090E403002DE90FE0A0E102F0A0E18C\n:1000E0000300BDE8F7FFFFEA00000FE1C000C0E336\n:1000F00000F029E10000A0E30010A0E364209FE5E8\n:100100000FE0A0E112FF2FE10000A0E10000A0E15C\n:100110000000A0E1FBFFFFEAFEFFFFEAFEFFFFEAAF\n:10012000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA37\n:10013000C201000009800000100F0020100F0020F5\n:10014000100B0020100B0020100F002010020020C8\n:1001500010020020100200201002002010020020D7\n:100160000C0200200C0200206C0100200CD04DE29B\n:100170000130A0E300308DE50230A0E304308DE5CE\n:100180000030A0E308308DE538309FE5002093E58E\n:1001900000309DE5023083E000308DE500309DE5C4\n:1001A000013083E200308DE504309DE5013083E2CB\n:1001B00004308DE500209DE504309DE5033082E0AC\n:0C01C00008308DE5F4FFFFEA0C0200207F\n:1001CC0018F09FE518F09FE518F09FE518F09FE5F3\n:1001DC0018F09FE518F09FE518F09FE518F09FE5E3\n:1001EC0000000020180100201C010020200100202C\n:1001FC002401002000000000280100202C01002018\n:04020C0007000000E7\n:0400000520000000D7\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR710Test/test_rom.hex",
    "content": ":020000044000BA\n:100000000000A0E10000A0E10000A0E10000A0E1EC\n:100010000000A0E10000A0E10000A0E10000A0E1DC\n:100020000A02A0E304119FE5501080E50A02A0E354\n:100030000010A0E3441080E50A02A0E30010A0E352\n:100040000A02A0E37310A0E3181080E5081090E501\n:10005000020011E3FCFFFF0A0A02A0E3D0109FE5B3\n:10006000081080E5DBF021E3C8D09FE5D7F021E35D\n:10007000C4D09FE5D1F021E3C0D09FE5D2F021E3C9\n:10008000BCD09FE5D3F021E3B8D09FE5B8109FE541\n:10009000B8209FE5B8309FE5030052E10400913499\n:1000A00004008234FBFFFF3A0000A0E3A4109FE5A8\n:1000B000A4209FE5020051E104008134FCFFFF3AD7\n:1000C00098009FE598109FE5010050E10500000AA7\n:1000D000042090E403002DE90FE0A0E102F0A0E18C\n:1000E0000300BDE8F7FFFFEA00000FE1C000C0E336\n:1000F00000F029E10000A0E30010A0E364209FE5E8\n:100100000FE0A0E112FF2FE10000A0E10000A0E15C\n:100110000000A0E1FBFFFFEAFEFFFFEAFEFFFFEAAF\n:10012000FEFFFFEAFEFFFFEAFEFFFFEAFEFFFFEA37\n:10013000C201000009800000000D0020000D002019\n:100140000009002000090020000D002010020040DE\n:10015000000000200000002000000020000000201F\n:100160000C0200400C0200406C0100400CD04DE23B\n:100170000130A0E300308DE50230A0E304308DE5CE\n:100180000030A0E308308DE538309FE5002093E58E\n:1001900000309DE5023083E000308DE500309DE5C4\n:1001A000013083E200308DE504309DE5013083E2CB\n:1001B00004308DE500209DE504309DE5033082E0AC\n:0C01C00008308DE5F4FFFFEA0C0200405F\n:1001CC0018F09FE518F09FE518F09FE518F09FE5F3\n:1001DC0018F09FE518F09FE518F09FE518F09FE5E3\n:1001EC0000000040180100401C01004020010040AC\n:1001FC002401004000000000280100402C010040B8\n:04020C0007000000E7\n:0400000540000000B7\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/inc/typedefs.h",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n****************************************************************************/\n#ifndef __TYPEDEFS_H__\n#define __TYPEDEFS_H__\n\n/*\n * Some types to use Windows like source\n */\ntypedef char            CHAR;    /* 8-bit signed data    */\ntypedef unsigned char   BYTE;    /* 8-bit unsigned data  */\ntypedef unsigned short  WORD;    /* 16-bit unsigned data */\ntypedef long            LONG;    /* 32-bit signed data   */\ntypedef unsigned long   ULONG;   /* 32-bit unsigned data */\ntypedef unsigned long   DWORD;   /* 32-bit unsigned data */\n\n\n#endif /* !__TYPEDEFS_H__ */\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/eclipse_ram.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 sw_bkpts enable\n\n# Set SRAM size to 96 KB\nmonitor mww 0x5C002034 0x0197\nmonitor mdw 0x5C002034\n\n# Set Flash, Bank0 size to 512 KB\nmonitor mww 0x54000000 0xf\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/eclipse_rom.gdb",
    "content": "target remote localhost:3333\nmonitor reset\nmonitor sleep 500\nmonitor poll\nmonitor soft_reset_halt\nmonitor arm7_9 force_hw_bkpts enable\n\n# Set SRAM size to 96 KB\nmonitor mww 0x5C002034 0x0197\nmonitor mdw 0x5C002034\n\n# Set Flash, Bank0 size to 512 KB\nmonitor mww 0x54000000 0xf\n\nload\nbreak main\ncontinue\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/str912_jtagkey.cfg",
    "content": "#daemon configuration\ntelnet_port 4444\ngdb_port 3333\n\n# tell gdb our flash memory map\n# and enable flash programming\ngdb_memory_map enable\ngdb_flash_program enable\n\n#interface\ninterface ft2232\nft2232_device_desc \"Amontec JTAGkey A\"\nft2232_layout jtagkey\nft2232_vid_pid 0x0403 0xcff8\njtag_speed 1\n\njtag_nsrst_delay 100\njtag_ntrst_delay 100\n\n#use combined on interfaces or targets that can't set TRST/SRST separately\nreset_config trst_and_srst\n\n#jtag scan chain\njtag newtap str9 flash -irlen 8\njtag newtap str9 cpu -irlen 4 -irmask 0xf\njtag newtap str9 bs -irlen 5\n\n#target configuration\ntarget create target0 arm966e -endian little -chain-position 1\n[new_target_name] configure -work-area-virt 0 -work-area-phys 0x50000000 -work-area-size 16384 -work-area-backup false\n\ntarget_script 0 gdb_program_config .\\prj\\str912_program.script\n\n#flash bank str7x <base> <size> 0 0 <target#> <variant>\nflash bank str9x 0x00000000 0x00080000 0 0 0\n\n# For more information about the configuration files,\n# look at the OpenOCD User's Guide.\n\ninit\nreset halt\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/str912_program.script",
    "content": "str9x flash_config 0 4 2 0 0x80000\nflash protect 0 0 7 off\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/str912_ram.ld",
    "content": "/***********************************************************************************\n*\tCopyright 2005 Anglia Design\n*\tThis demo code and associated components are provided as is and has no warranty,\n*\timplied or otherwise.  You are free to use/modify any of the provided\n*\tcode at your own risk in your applications with the expressed limitation\n*\tof liability (see below)\n* \n*\tLIMITATION OF LIABILITY:   ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY\n*\tLOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR\n*\tINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER\n*\tTHIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n*\n*\tAuthor\t\t\t: Spencer Oliver\n*\tWeb     \t\t: www.anglia-designs.com\n*\n***********************************************************************************/\n\n/* Stack Sizes */\n\n\t_STACKSIZE     = 1024;\n\t_STACKSIZE_IRQ = 256;\n\t_STACKSIZE_FIQ = 0;\n\t_STACKSIZE_SVC = 1024;\n\t_STACKSIZE_ABT = 0;\n\t_STACKSIZE_UND = 0;\n\t_HEAPSIZE      = 1024;\n\n/* Memory Definitions */\n\nMEMORY\n{\n\tDATA (rw) : ORIGIN = 0x04000000, LENGTH = 0x00018000\n}\n\n/* Section Definitions */\n\nSECTIONS\n{\n\t/* first section is .text which is used for code */\n\n\t.text :\n\t{\n\t\tKEEP(*(.vectors))\n\t\tKEEP(*(.init))\n\t\t*(.text .text.*)\n\t\t*(.gnu.linkonce.t.*)\n\t\t*(.glue_7t .glue_7)\n\t\tKEEP(*(.fini))\n\t\t*(.gcc_except_table)\n\t} >DATA =0\n\t. = ALIGN(4);\n\n\t/* .ctors .dtors are used for c++ constructors/destructors */\n\t\n\t.ctors :\n\t{\n\t\tPROVIDE(__ctors_start__ = .);\n\t\tKEEP(*(SORT(.ctors.*)))\n\t\tKEEP(*(.ctors))\n\t\tPROVIDE(__ctors_end__ = .);\n\t} >DATA\n\n\t.dtors :\n\t{\n\t\tPROVIDE(__dtors_start__ = .); \n\t\tKEEP(*(SORT(.dtors.*)))\n\t\tKEEP(*(.dtors))\n\t\tPROVIDE(__dtors_end__ = .);\n\t} >DATA\n\t\n\t/* .rodata section which is used for read-only data (constants) */\n\n\t.rodata :\n\t{\n\t\t*(.rodata .rodata.*)\n\t\t*(.gnu.linkonce.r.*)\n\t} >DATA\n\t. = ALIGN(4);\n\n\t_etext = .;\n\tPROVIDE (etext = .);\n\n\t/* .data section which is used for initialized data */\n\n\t.data : AT (_etext)\n\t{\n\t\t*(.data .data.*)\n\t\t*(.gnu.linkonce.d.*)\n\t\tSORT(CONSTRUCTORS)\n\t} >DATA\n\t. = ALIGN(4);\n\t\n\t__data_start = .;\n\t_edata = .;\n\tPROVIDE (edata = .);\n\n\t/* .bss section which is used for uninitialized data */\n\n\t.bss :\n\t{\n\t\t__bss_start = .;\n\t\t__bss_start__ = .;\n\t\t*(.bss .bss.*)\n\t\t*(.gnu.linkonce.b.*)\n\t\t*(COMMON)\n\t\t. = ALIGN(4);\n\t} >DATA\n\t. = ALIGN(4);\n\t__bss_end__ = .;\n\t\n\t_end = .;\n\tPROVIDE(end = .);\n\n\t/* .heap section which is used for memory allocation */\n\t\n\t.heap (NOLOAD) :\n\t{\n\t\t__heap_start__ = .;\n\t\t*(.heap)\n\t\t. = MAX(__heap_start__ + _HEAPSIZE , .);\n\t} >DATA\n\t__heap_end__ = __heap_start__ + SIZEOF(.heap);\n\t\n\t/* .stack section - user mode stack */\n\t\n\t.stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_start__ = .;\n\t\t*(.stack)\n\t\t. = MAX(__stack_start__ + _STACKSIZE , .);\n\t} >DATA\n\t__stack_end__ = __stack_start__ + SIZEOF(.stack);\n\n\t/* .stack_irq section */\n\t\n\t.stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_irq_start__ = .;\n\t\t*(.stack_irq)\n\t\t. = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .);\n\t} >DATA\n\t__stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq);\n\n\t/* .stack_fiq section */\n\t\n\t.stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_fiq_start__ = .;\n\t\t*(.stack_fiq)\n\t    . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .);\n\t} >DATA\n\t__stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq);\n\n\t/* .stack_svc section */\n\t\n\t.stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_svc_start__ = .;\n\t\t*(.stack_svc)\n\t\t. = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .);\n\t} >DATA\n\t__stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc);\n\n\t/* .stack_abt section */\n\t\n\t.stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_abt_start__ = .;\n\t\t*(.stack_abt)\n\t\t. = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .);\n\t} >DATA\n\t__stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt);\n\n\t/* .stack_und section */\n\t\n\t.stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_und_start__ = .;\n\t\t*(.stack_und)\n    \t. = MAX(__stack_und_start__ + _STACKSIZE_UND , .);\n\t} >DATA\n\t__stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und);\n\t\n\t/* Stabs debugging sections.  */\n\t.stab          0 : { *(.stab) }\n\t.stabstr       0 : { *(.stabstr) }\n\t.stab.excl     0 : { *(.stab.excl) }\n\t.stab.exclstr  0 : { *(.stab.exclstr) }\n\t.stab.index    0 : { *(.stab.index) }\n\t.stab.indexstr 0 : { *(.stab.indexstr) }\n\t.comment       0 : { *(.comment) }\n\t/* DWARF debug sections.\n\t\tSymbols in the DWARF debugging sections are relative to the beginning\n\t\tof the section so we begin them at 0.  */\n\t/* DWARF 1 */\n\t.debug          0 : { *(.debug) }\n\t.line           0 : { *(.line) }\n\t/* GNU DWARF 1 extensions */\n\t.debug_srcinfo  0 : { *(.debug_srcinfo) }\n\t.debug_sfnames  0 : { *(.debug_sfnames) }\n\t/* DWARF 1.1 and DWARF 2 */\n\t.debug_aranges  0 : { *(.debug_aranges) }\n\t.debug_pubnames 0 : { *(.debug_pubnames) }\n\t/* DWARF 2 */\n\t.debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\t.debug_abbrev   0 : { *(.debug_abbrev) }\n\t.debug_line     0 : { *(.debug_line) }\n\t.debug_frame    0 : { *(.debug_frame) }\n\t.debug_str      0 : { *(.debug_str) }\n\t.debug_loc      0 : { *(.debug_loc) }\n\t.debug_macinfo  0 : { *(.debug_macinfo) }\n\t/* SGI/MIPS DWARF 2 extensions */\n\t.debug_weaknames 0 : { *(.debug_weaknames) }\n\t.debug_funcnames 0 : { *(.debug_funcnames) }\n\t.debug_typenames 0 : { *(.debug_typenames) }\n\t.debug_varnames  0 : { *(.debug_varnames) }\t\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/prj/str912_rom.ld",
    "content": "/***********************************************************************************\n*\tCopyright 2005 Anglia Design\n*\tThis demo code and associated components are provided as is and has no warranty,\n*\timplied or otherwise.  You are free to use/modify any of the provided\n*\tcode at your own risk in your applications with the expressed limitation\n*\tof liability (see below)\n* \n*\tLIMITATION OF LIABILITY:   ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY\n*\tLOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR\n*\tINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER\n*\tTHIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n*\n*\tAuthor\t\t\t: Spencer Oliver\n*\tWeb     \t\t: www.anglia-designs.com\n*\n***********************************************************************************/\n\n/* Stack Sizes */\n\n\t_STACKSIZE     = 1024;\n\t_STACKSIZE_IRQ = 256;\n\t_STACKSIZE_FIQ = 0;\n\t_STACKSIZE_SVC = 1024;\n\t_STACKSIZE_ABT = 0;\n\t_STACKSIZE_UND = 0;\n\t_HEAPSIZE      = 1024;\n\n/* Memory Definitions */\n\nMEMORY\n{\n\tCODE (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000\n\tDATA (rw) : ORIGIN = 0x04000000, LENGTH = 0x00018000\n}\n\n/* Section Definitions */\n\nSECTIONS\n{\n\t/* first section is .text which is used for code */\n\n\t.text :\n\t{\n\t\tCREATE_OBJECT_SYMBOLS\n\t\tKEEP(*(.vectors))\n\t\tKEEP(*(.init))\n\t\t*(.text .text.*)\n\t\t*(.gnu.linkonce.t.*)\n\t\t*(.glue_7t) *(.glue_7) *(.vfp11_veneer)\n\t\tKEEP(*(.fini))\n\t\t*(.gcc_except_table)\n\t} >CODE =0\n\t. = ALIGN(4);\n\n\t/* .ctors .dtors are used for c++ constructors/destructors */\n\t\n\t.ctors :\n\t{\n\t\tPROVIDE(__ctors_start__ = .);\n\t\tKEEP(*(SORT(.ctors.*)))\n\t\tKEEP(*(.ctors))\n\t\tPROVIDE(__ctors_end__ = .);\n\t} >CODE\n\n\t.dtors :\n\t{\n\t\tPROVIDE(__dtors_start__ = .); \n\t\tKEEP(*(SORT(.dtors.*)))\n\t\tKEEP(*(.dtors))\n\t\tPROVIDE(__dtors_end__ = .);\n\t} >CODE\n\t\n\t/* .rodata section which is used for read-only data (constants) */\n\n\t.rodata :\n\t{\n\t\t*(.rodata .rodata.*)\n\t\t*(.gnu.linkonce.r.*)\n\t} >CODE\n\t. = ALIGN(4);\n\n\t.init_array :\n\t{\n\t\t*(.init)\n        *(.fini)\n\t\tPROVIDE_HIDDEN (__preinit_array_start = .);\n\t\tKEEP (*(.preinit_array))\n\t\tPROVIDE_HIDDEN (__preinit_array_end = .);\n\t\tPROVIDE_HIDDEN (__init_array_start = .);\n\t\tKEEP (*(SORT(.init_array.*)))\n\t\tKEEP (*(.init_array))\n\t\tPROVIDE_HIDDEN (__init_array_end = .);\n\t\tPROVIDE_HIDDEN (__fini_array_start = .);\n\t\tKEEP (*(.fini_array))\n\t\tKEEP (*(SORT(.fini_array.*)))\n\t\tPROVIDE_HIDDEN (__fini_array_end = .);\n\t} >CODE\n\n\t. = ALIGN(4);\n\n\t/* .ARM.exidx is sorted, so has to go in its own output section.  */\n\t__exidx_start = .;\n\t.ARM.exidx :\n\t{\n\t\t*(.ARM.exidx* .gnu.linkonce.armexidx.*)\n\t} >CODE\n\t__exidx_end = .;\n\n\t_etext = .;\n\tPROVIDE (etext = .);\n\n\t/* .data section which is used for initialized data */\n\n\t.data : AT (_etext)\n\t{\n\t\t__data_start = .;\n\t\t*(.data .data.*)\n\t\t*(.gnu.linkonce.d.*)\n\t\tSORT(CONSTRUCTORS)\n\t\t. = ALIGN(4);\n\t\t*(.fastrun .fastrun.*)\n\t} >DATA\n\t. = ALIGN(4);\n\t\n\t_edata = .;\n\tPROVIDE (edata = .);\n\n\t/* .bss section which is used for uninitialized data */\n\n\t.bss :\n\t{\n\t\t__bss_start = .;\n\t\t__bss_start__ = .;\n\t\t*(.bss .bss.*)\n\t\t*(.gnu.linkonce.b.*)\n\t\t*(COMMON)\n\t\t. = ALIGN(4);\n\t} >DATA\n\t. = ALIGN(4);\n\t__bss_end__ = .;\n\t\n\t_end = .;\n\tPROVIDE(end = .);\n\n\t/* .heap section which is used for memory allocation */\n\t\n\t.heap (NOLOAD) :\n\t{\n\t\t__heap_start__ = .;\n\t\t*(.heap)\n\t\t. = MAX(__heap_start__ + _HEAPSIZE , .);\n\t} >DATA\n\t__heap_end__ = __heap_start__ + SIZEOF(.heap);\n\t\n\t/* .stack section - user mode stack */\n\t\n\t.stack (__heap_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_start__ = .;\n\t\t*(.stack)\n\t\t. = MAX(__stack_start__ + _STACKSIZE , .);\n\t} >DATA\n\t__stack_end__ = __stack_start__ + SIZEOF(.stack);\n\n\t/* .stack_irq section */\n\t\n\t.stack_irq (__stack_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_irq_start__ = .;\n\t\t*(.stack_irq)\n\t\t. = MAX(__stack_irq_start__ + _STACKSIZE_IRQ , .);\n\t} >DATA\n\t__stack_irq_end__ = __stack_irq_start__ + SIZEOF(.stack_irq);\n\n\t/* .stack_fiq section */\n\t\n\t.stack_fiq (__stack_irq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_fiq_start__ = .;\n\t\t*(.stack_fiq)\n\t    . = MAX(__stack_fiq_start__ + _STACKSIZE_FIQ , .);\n\t} >DATA\n\t__stack_fiq_end__ = __stack_fiq_start__ + SIZEOF(.stack_fiq);\n\n\t/* .stack_svc section */\n\t\n\t.stack_svc (__stack_fiq_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_svc_start__ = .;\n\t\t*(.stack_svc)\n\t\t. = MAX(__stack_svc_start__ + _STACKSIZE_SVC , .);\n\t} >DATA\n\t__stack_svc_end__ = __stack_svc_start__ + SIZEOF(.stack_svc);\n\n\t/* .stack_abt section */\n\t\n\t.stack_abt (__stack_svc_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_abt_start__ = .;\n\t\t*(.stack_abt)\n\t\t. = MAX(__stack_abt_start__ + _STACKSIZE_ABT , .);\n\t} >DATA\n\t__stack_abt_end__ = __stack_abt_start__ + SIZEOF(.stack_abt);\n\n\t/* .stack_und section */\n\t\n\t.stack_und (__stack_abt_end__ + 3) / 4 * 4 (NOLOAD) :\n\t{\n\t\t__stack_und_start__ = .;\n\t\t*(.stack_und)\n    \t. = MAX(__stack_und_start__ + _STACKSIZE_UND , .);\n\t} >DATA\n\t__stack_und_end__ = __stack_und_start__ + SIZEOF(.stack_und);\n  \n\t/* Stabs debugging sections.  */\n\t.stab          0 : { *(.stab) }\n\t.stabstr       0 : { *(.stabstr) }\n\t.stab.excl     0 : { *(.stab.excl) }\n\t.stab.exclstr  0 : { *(.stab.exclstr) }\n\t.stab.index    0 : { *(.stab.index) }\n\t.stab.indexstr 0 : { *(.stab.indexstr) }\n\t.comment       0 : { *(.comment) }\n\t/* DWARF debug sections.\n\t\tSymbols in the DWARF debugging sections are relative to the beginning\n\t\tof the section so we begin them at 0.  */\n\t/* DWARF 1 */\n\t.debug          0 : { *(.debug) }\n\t.line           0 : { *(.line) }\n\t/* GNU DWARF 1 extensions */\n\t.debug_srcinfo  0 : { *(.debug_srcinfo) }\n\t.debug_sfnames  0 : { *(.debug_sfnames) }\n\t/* DWARF 1.1 and DWARF 2 */\n\t.debug_aranges  0 : { *(.debug_aranges) }\n\t.debug_pubnames 0 : { *(.debug_pubnames) }\n\t/* DWARF 2 */\n\t.debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }\n\t.debug_abbrev   0 : { *(.debug_abbrev) }\n\t.debug_line     0 : { *(.debug_line) }\n\t.debug_frame    0 : { *(.debug_frame) }\n\t.debug_str      0 : { *(.debug_str) }\n\t.debug_loc      0 : { *(.debug_loc) }\n\t.debug_macinfo  0 : { *(.debug_macinfo) }\n\t/* SGI/MIPS DWARF 2 extensions */\n\t.debug_weaknames 0 : { *(.debug_weaknames) }\n\t.debug_funcnames 0 : { *(.debug_funcnames) }\n\t.debug_typenames 0 : { *(.debug_typenames) }\n\t.debug_varnames  0 : { *(.debug_varnames) }\t\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/src/main.c",
    "content": "/****************************************************************************\n*  Copyright (c) 2006 by Michael Fischer. All rights reserved.\n*\n*  Redistribution and use in source and binary forms, with or without\n*  modification, are permitted provided that the following conditions\n*  are met:\n*\n*  1. Redistributions of source code must retain the above copyright\n*     notice, this list of conditions and the following disclaimer.\n*  2. Redistributions in binary form must reproduce the above copyright\n*     notice, this list of conditions and the following disclaimer in the\n*     documentation and/or other materials provided with the distribution.\n*  3. Neither the name of the author nor the names of its contributors may\n*     be used to endorse or promote products derived from this software\n*     without specific prior written permission.\n*\n*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n*  \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL\n*  THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS\n*  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\n*  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF\n*  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n*  SUCH DAMAGE.\n*\n****************************************************************************\n*  History:\n*\n*  30.03.06  mifi   First Version for Insight tutorial\n*  26.01.08  mifi   Added variable \"d\" to test const variable.\n****************************************************************************/\n#define __MAIN_C__\n\n/*\n * I use the include only, to show\n * how to setup a include dir in the makefile\n */\n#include \"typedefs.h\"\n\n/*=========================================================================*/\n/*  DEFINE: All Structures and Common Constants                            */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Prototypes                                                     */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Data                                   */\n/*=========================================================================*/\nstatic const DWORD d = 7;\n\n/*=========================================================================*/\n/*  DEFINE: Definition of all local Procedures                             */\n/*=========================================================================*/\n\n/*=========================================================================*/\n/*  DEFINE: All code exported                                              */\n/*=========================================================================*/\n/***************************************************************************/\n/*  main                                                                   */\n/***************************************************************************/\nint main (void)\n{\n  DWORD a = 1;\n  DWORD b = 2;\n  DWORD c = 0;\n\n  a = a + d;\n\n  while (1)\n  {\n    a++;\n    b++;\n    c = a + b;\n  }\n\n  /*\n   * This return here make no sense.\n   * But to prevent the compiler warning:\n   * \"return type of 'main' is not 'int'\n   * we use an int as return :-)\n   */\n  return(0);\n}\n\n/*** EOF ***/\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/src/startup.s",
    "content": "/***********************************************************************************\n*\tCopyright 2005 Anglia Design\n*\tThis demo code and associated components are provided as is and has no warranty,\n*\timplied or otherwise.  You are free to use/modify any of the provided\n*\tcode at your own risk in your applications with the expressed limitation\n*\tof liability (see below)\n* \n*\tLIMITATION OF LIABILITY:   ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY\n*\tLOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR\n*\tINDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER\n*\tTHIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n*\n*\tAuthor\t: Spencer Oliver\n*\tWeb     \t: www.anglia-designs.com\n*\n*     mifi, 22.01.2008, small changes by the init of the C++ eabi constructors. \n*                       Here I have replaced the eabi init by the normal init.\n*                       Thanks to Spen for the startup code. \n***********************************************************************************/\n\n/**** Startup Code (executed after Reset) ****/\n\n/* Frequency values kHz */\n/* set to suit target hardware */\n\n\t.equ\tFOSC,\t\t\t25000\n\t\n/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */\n\n\t.equ\tMode_USR,\t\t0x10\n\t.equ\tMode_FIQ,\t\t0x11\n\t.equ\tMode_IRQ,\t\t0x12\n\t.equ\tMode_SVC,\t\t0x13\n\t.equ\tMode_ABT,\t\t0x17\n\t.equ\tMode_UND,\t\t0x1B\n\t.equ\tMode_SYS,\t\t0x1F\t\t\t/* available on ARM Arch 4 and later */\n\n\t.equ\tI_Bit,\t\t\t0x80\t\t\t/* when I bit is set, IRQ is disabled */\n\t.equ\tF_Bit,\t\t\t0x40\t\t\t/* when F bit is set, FIQ is disabled */\n\n\t.equ\tSRAM32,\t\t\t0x00\n\t.equ\tSRAM64,\t\t\t0x08\n\t.equ\tSRAM96,\t\t\t0x10\n\n/* --- System memory locations */\n\n\t.equ\tSCRO_AHB_UMB,\t\t0x5C002034\t\t/* System configuration register 0 (unbuffered) */\n\n\t.equ\tFMI_BASE_UMB,\t\t0x54000000\t\t/* Flash FMI base address (unbuffered) */\n\t.equ\tBBSR_off_addr,\t\t0x00\n\t.equ\tNBBSR_off_addr,\t\t0x04\n\t.equ\tBBADR_off_addr,\t\t0x0C\n\t.equ\tNBBADR_off_addr,\t0x10\n\t.equ\tCR_off_addr,\t\t0x18\n\n.ifndef LIBUFF\n\t.equ\tLIBUFF, 0\n.endif\n\n/* Startup Code must be linked first at Address at which it expects to run. */\n\n\t.text\n\t.arm\n\t.section .init, \"ax\"\n\t\n\t.global _start\n\t.global _Main_Crystal\n\n/* After remap this will be our reset handler */\n\n_start:\n\t\tLDR     pc, =NextInst\nNextInst:\n\n\t\tNOP\t\t/* Wait for OSC stabilization */\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\t\tNOP\n\n/* Enable buffered mode */\n\n.if LIBUFF\n\t\tMRC\t\tp15, 0, r0, c1, c0, 0\t\t/* Read CP15 register 1 into r0 */\n\t\tORR\t\tr0, r0, #0x8\t\t\t\t/* Enable Write Buffer on AHB */\n\t\tMCR\t\tp15, 0, r0, c1, c0, 0 \t\t/* Write CP15 register 1 */\n.endif\n\n/* Remap Flash Bank 0 at address 0x0 and Bank 1 at address 0x80000, */\n/* when the bank 0 is the boot bank, then enable the Bank 1. */\n\n\t\tLDR\t\tr0, =FMI_BASE_UMB\n\t\tLDR\t\tr1, =0x4\t\t\t\t\t/* configure 512KB Boot bank 0 */\n\t\tSTR\t\tr1, [r0, #BBSR_off_addr]\n\n\t\tLDR\t\tr1, =0x2\t\t\t\t\t/* configure 32KB Non Boot bank 1 */\n\t\tSTR\t\tr1, [r0, #NBBSR_off_addr]\n\n\t\tLDR\t\tr1, =(0x00000000 >> 2)\t\t/* Boot Bank Base Address */\n\t\tSTR\t\tr1, [r0, #BBADR_off_addr]\n\n\t\tLDR\t\tr1, =(0x00080000 >> 2)\t\t/* Non Boot Bank Base Address */\n\t\tSTR\t\tr1, [r0, #NBBADR_off_addr]\n\n\t\tLDR\t\tr1, =0x18\t\t\t\t\t/* Flash Banks 0 1 enabled */\n\t\tSTR\t\tr1, [r0, #CR_off_addr]\n\t\t\n/* Enable 96K RAM */\n\n\t\tLDR\t\tr0, =SCRO_AHB_UMB\n#\t\tLDR\t\tr1, =0x0196\t\t\t\t/* prefetch disabled, default enabled */\n\t\tLDR\t\tr1, =0x0187|SRAM96\n\t\tSTR\t\tr1, [r0]\n\n/* Set bits 17-18 (Instruction/Data TCM order) of the */\n/* Core Configuration Control Register */\n \n\t\tMOV\t\tr0, #0x60000\n\t\tMCR\t\tp15, 0x1, r0, c15, c1, 0\n  \n/* Setup Stack for each mode */\n\n/* Enter Abort Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_ABT|I_Bit|F_Bit\n\t\tLDR\t\tsp, =__stack_abt_end__\n\n/* Enter Undefined Instruction Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_UND|I_Bit|F_Bit\n\t\tLDR\t\tsp, =__stack_und_end__\n\n/* Enter Supervisor Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_SVC|I_Bit|F_Bit\n\t\tLDR\t\tsp, =__stack_svc_end__\n\n/* Enter FIQ Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_FIQ|I_Bit|F_Bit\n\t\tLDR\t\tsp, =__stack_fiq_end__\n\n/* Enter IRQ Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_IRQ|I_Bit|F_Bit\n\t\tLDR\t\tsp, =__stack_irq_end__\n\n/* Enter System/User Mode and set its Stack Pointer */\n\n\t\tMSR\t\tcpsr_c, #Mode_SYS\n\t\tLDR\t\tsp, =__stack_end__\n\n/* Setup a default Stack Limit (when compiled with \"-mapcs-stack-check\") */\n\n\t\tLDR\t\tsl, =__bss_end__\n\n/* Relocate .data section (Copy from ROM to RAM) */\n\n\t\tLDR\t\tr1, =_etext\n\t\tLDR\t\tr2, =__data_start\n\t\tLDR\t\tr3, =_edata\nLoopRel:\n\t\tCMP\t\tr2, r3\n\t\tLDRLO\tr0, [r1], #4\n\t\tSTRLO\tr0, [r2], #4\n\t\tBLO\t\tLoopRel\n\n/* Clear .bss section (Zero init) */\n\n\t\tMOV\t\tr0, #0\n\t\tLDR\t\tr1, =__bss_start__\n\t\tLDR\t\tr2, =__bss_end__\nLoopZI:\n\t\tCMP\t\tr1, r2\n\t\tSTRLO\tr0, [r1], #4\n\t\tBLO\t\tLoopZI\n  \t\t\n/* Call C++ constructors */\n\n\t\tLDR\t\tr0, =__ctors_start__\n\t\tLDR \t\tr1, =__ctors_end__\nctor_loop:\n\t\tCMP \t\tr0, r1\n\t\tBEQ \t\tctor_end\n\t\tLDR \t\tr2, [r0], #4\n\t\tSTMFD \tsp!, {r0-r1}\n\t\tBLX\t\tr2\n\t\tLDMFD\t\tsp!, {r0-r1}\n\t\tB \t\tctor_loop\nctor_end:\n\n/* Need to set up standard file handles */\n/* Only used under simulator, normally overide syscall.c */\n\n#\t\tBL\t\tinitialise_monitor_handles\n\n/* if we use debug version of str9lib this will call the init function */\n\t\t\n\t\tBL\t\tlibdebug\nlibdebug:\t\t\n\n/* Enter the C code, use B instruction so as to never return */\n/* use BL main if you want to use c++ destructors below */\n\n\t\tB\t\tmain\n\n/* Return from main, loop forever. */\n\n#exit_loop:\n#\t\tB\t\texit_loop\n\t\n/* Fosc values, used by libstr9 */\n\n_Main_Crystal:\t.long\tFOSC\n\n\t.weak libdebug\n\t\n\t.end\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/test_ram.hex",
    "content": ":020000040400F6\n:10000000F8F09FE50000A0E10000A0E10000A0E101\n:100010000000A0E10000A0E10000A0E10000A0E1DC\n:100020000000A0E10000A0E11503A0E30410A0E39C\n:10003000001080E50210A0E3041080E50010A0E3AA\n:100040000C1080E50218A0E3101080E51810A0E362\n:10005000181080E5A8009FE5A8109FE5001080E536\n:100060000608A0E3110F2FEED7F021E398D09FE50B\n:10007000DBF021E394D09FE5D3F021E390D09FE51E\n:10008000D1F021E38CD09FE5D2F021E388D09FE529\n:100090001FF021E384D09FE584A09FE584109FE5B5\n:1000A00084209FE584309FE5030052E104009134F1\n:1000B00004008234FBFFFF3A0000A0E370109FE5CC\n:1000C0005C209FE5020051E104008134FCFFFF3A0F\n:1000D00060009FE560109FE5010050E10400000A08\n:1000E000042090E403002DE932FF2FE10300BDE876\n:1000F000F8FFFFEAFFFFFFEB100000EAA861000035\n:10010000040000043420005C97010000A40E0004E9\n:10011000A40E0004A40E0004A40A0004A40A00040F\n:10012000A4090004A4010004A4010004A401000423\n:10013000A4010004A4010004A0010004A001000423\n:100140000CD04DE20130A0E300308DE50230A0E399\n:1001500004308DE50030A0E308308DE538309FE5B0\n:10016000002093E500309DE5023083E000308DE50E\n:1001700000309DE5013083E200308DE504309DE5DF\n:10018000013083E204308DE500209DE504309DE5DB\n:10019000033082E008308DE5F4FFFFEAA00100049F\n:0401A0000700000054\n:0400000504000000F3\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/STR912Test/test_rom.hex",
    "content": ":10000000F8F09FE50000A0E10000A0E10000A0E101\n:100010000000A0E10000A0E10000A0E10000A0E1DC\n:100020000000A0E10000A0E11503A0E30410A0E39C\n:10003000001080E50210A0E3041080E50010A0E3AA\n:100040000C1080E50218A0E3101080E51810A0E362\n:10005000181080E5A8009FE5A8109FE5001080E536\n:100060000608A0E3110F2FEED7F021E398D09FE50B\n:10007000DBF021E394D09FE5D3F021E390D09FE51E\n:10008000D1F021E38CD09FE5D2F021E388D09FE529\n:100090001FF021E384D09FE584A09FE584109FE5B5\n:1000A00084209FE584309FE5030052E104009134F1\n:1000B00004008234FBFFFF3A0000A0E370109FE5CC\n:1000C0005C209FE5020051E104008134FCFFFF3A0F\n:1000D00060009FE560109FE5010050E10400000A08\n:1000E000042090E403002DE932FF2FE10300BDE876\n:1000F000F8FFFFEAFFFFFFEB100000EAA861000035\n:10010000040000003420005C97010000000D000492\n:10011000000D0004000D00040009000400090004A3\n:100120000008000400000004A40100000000000416\n:100130000000000400000004A0010000A001000075\n:100140000CD04DE20130A0E300308DE50230A0E399\n:1001500004308DE50030A0E308308DE538309FE5B0\n:10016000002093E500309DE5023083E000308DE50E\n:1001700000309DE5013083E200308DE504309DE5DF\n:10018000013083E204308DE500209DE504309DE5DB\n:10019000033082E008308DE5F4FFFFEAA0010000A3\n:0401A0000700000054\n:00000001FF\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/cortex/cm3-ftest.cfg",
    "content": "#\n# For each named Cortex-M3 vector_catch flag VECTOR ...\n#\t\tbus_err\t\tstate_err\n#\t\tchk_err\t\tnocp_err\n#\t\tmm_err\t\treset\n#\n# BUT NYET hard_err, int_err (their test cases don't yet work) ...\n#\n# Do the following:\n#\n#  - Test #1:  verify that OpenOCD ignores exceptions by default\n#     + l_VECTOR (loads testcase to RAM)\n#     + fault triggers loop-to-self exception \"handler\"\n#     + \"halt\"\n#     + observe fault \"handling\" -- loop-to-self from load_and_run (below)\n#\n#  - Test #2:  verify that \"vector_catch\" makes OpenOCD stops ignoring them\n#     + cortex_m vector_catch none\n#     + cortex_m vector_catch VECTOR\n#     + l_VECTOR (loads testcase to RAM)\n#     + fault triggers vector catch hardware\n#     + observe OpenOCD entering debug state with no assistance\n#\n# NOTE \"reset\" includes the NVIC, so that test case gets its reset vector\n# from the flash, not from the vector table set up here.  Which means that\n# for that vector_catch option, the Test #1 (above) \"observe\" step won't\n# use the SRAM address.\n#\n\n# we can fully automate test #2\nproc vector_test {tag} {\n\thalt\n\t# REVISIT -- annoying, we'd like to scrap vector_catch output\n\tcortex_m vector_catch none\n\tcortex_m vector_catch $tag\n\teval \"l_$tag\"\n}\n\n#\n# Load and start one vector_catch test case.\n#\n# name -- tag for the vector_catch flag being tested\n# halfwords -- array of instructions (some wide, some narrow)\n# n_instr -- how many instructions are in $halfwords\n#\nproc load_and_run { name halfwords n_instr } {\n\treset halt\n\n\t# Load code at beginning of SRAM.\n\techo \"# code to trigger $name vector\"\n\tset addr 0x20000000\n\n\t# write_memory should be faster, though we'd need to\n\t# compute the resulting $addr ourselves\n\tforeach opcode $halfwords {\n\t\tmwh $addr $opcode\n\t\tincr addr 2\n\t}\n\n\t# create default loop-to-self at $addr ... it serves as\n\t# (a) \"main loop\" on error\n\t# (b) handler for all exceptions that get triggered\n\tmwh $addr 0xe7fe\n\n\t# disassemble, as sanity check and what's-happening trace\n\tarm disassemble 0x20000000 [expr 1 + $n_instr ]\n\n\t# Assume that block of code is at most 16 halfwords long.\n\t# Create a basic table of loop-to-self exception handlers.\n\tmww 0x20000020 $addr 16\n\t# Store its address in VTOR\n\tmww 0xe000ed08 0x20000020\n\t# Use SHCSR to ensure nothing escalates to a HardFault\n\tmww 0xe000ed24 0x00070000\n\n\t# now start, trigering the $name vector catch logic\n\tresume 0x20000000\n}\n\n#proc l_hard_err {} {\n#\tIMPLEMENT ME\n#\tFORCED -- escalate something to HardFault\n#}\n\n#proc l_int_err {} {\n#\tIMPLEMENT ME\n#\tSTKERR -- exception stack BusFault\n#}\n\n# BusFault, escalates to HardFault\nproc l_bus_err {} {\n\t# PRECISERR -- assume less than 512 MBytes of SRAM\n\tload_and_run bus_err {\n\t\t0xf06f 0x4040\n\t\t0x7800\n\t} 2\n}\n\n# UsageFault, escalates to HardFault\nproc l_state_err {} {\n\t# UNDEFINSTR -- issue architecturally undefined instruction\n\tload_and_run state_err {\n\t\t0xde00\n\t} 1\n}\n\n# UsageFault, escalates to HardFault\nproc l_chk_err {} {\n\t# UNALIGNED -- LDM through unaligned pointer\n\tload_and_run chk_err {\n\t\t0xf04f 0x0001\n\t\t0xe890 0x0006\n\t} 2\n}\n\n# UsageFault, escalates to HardFault\nproc l_nocp_err {} {\n\t# NOCP -- issue cp14 DCC instruction\n\tload_and_run nocp_err {\n\t\t0xee10 0x0e15\n\t} 1\n}\n\n# MemManage, escalates to HardFault\nproc l_mm_err {} {\n\t# IACCVIOL -- instruction fetch from an XN region\n\tload_and_run mm_err {\n\t\t0xf04f 0x4060\n\t\t0x4687\n\t} 2\n}\n\nproc l_reset {} {\n\t# issue SYSRESETREQ via AIRCR\n\tload_and_run reset {\n\t\t0xf04f 0x0104\n\t\t0xf2c0 0x51fa\n\t\t0xf44f 0x406d\n\t\t0xf100 0x000c\n\t\t0xf2ce 0x0000\n\t\t0x6001\n\t} 6\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/cortex/fault.c",
    "content": "/*\n * COMPILE:  arm-none-eabi-gcc -mthumb -march=armv7-m ...\n *\t... plus, provide at least a default exception vector table.\n *\n * RUN:  this is best run from SRAM.  It starts at main() then triggers\n * a fault before more than a handful of instructions have executed.\n * Run each test case in two modes:\n *\n * (1)\tFaults caught on the Cortex-M3.  Default handlers are usually\n *\tloop-to-self NOPs, so a debugger won't notice faults until they\n *\thalt the core and examine xSPR and other registers.\n *\n *\tTo verify the fault triggered, issue \"halt\" from OpenOCD; you\n *\tshould be told about the fault and (some of) its details.\n *\tThen it's time to run the next test.\n *\n *\tNOTE however that \"reset\" will restart everything; verify that\n *\tcase by observing your reset handler doing its normal work.\n *\n * (2)\tFaults intercepted by OpenOCD \"vector_catch ...\" commands.\n *\n *\tOpenOCD should tell you about the fault, and show the same\n *\tdetails, without your \"halt\" command.\n *\n * Someday, a fancy version of this code could provide a vector table and\n * fault handlers which use semihosting (when that works on Cortex-M3) to\n * report what happened, again without needing a \"halt\" command.\n */\n\n\n/* These symbols match the OpenOCD \"cortex_m vector_catch\" bit names. */\nenum vc_case {\n\thard_err,\n\tint_err,\n\tbus_err,\n\tstate_err,\n\tchk_err,\n\tnocp_err,\n\tmm_err,\n\treset,\n};\n\n/* REVISIT come up with a way to avoid recompiling, maybe:\n *  - write it in RAM before starting\n *  - compiled-in BKPT, manual patch of r0, then resume\n *  - ...\n */\n\n#ifndef VC_ID\n#warning \"no VC_ID ... using reset\"\n#define VC_ID reset\n#endif\n\nint main(void) __attribute__ ((externally_visible, noreturn));\n\n/*\n * Trigger various Cortex-M3 faults to verify that OpenOCD behaves OK\n * in terms of its vector_catch handling.\n *\n * Fault handling should be left entirely up to the application code\n * UNLESS a \"vector_catch\" command tells OpenOCD to intercept a fault.\n *\n * See ARMv7-M architecure spec table B1-9 for the list of faults and\n * their mappings to the vector catch bits.\n */\nint main(void)\n{\n\t/* One test case for each vector catch bit.  We're not doing\n\t * hardware testing; so it doesn't matter when some DEMCR bits\n\t * could apply in multiple ways.\n\t */\n\tswitch (VC_ID) {\n\n\t/* \"cortex_m vector_catch hard_err\" */\n\tcase hard_err:\n\t\t/* FORCED - Fault escalation */\n\n\t\t/* FIXME code this */\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch int_err\" */\n\tcase int_err:\n\t\t/* STKERR -- Exception stack BusFault */\n\n\t\t/* FIXME code this */\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch bus_err\" */\n\tcase bus_err:\n\t\t/* PRECISERR -- precise data bus read\n\t\t * Here we assume a Cortex-M3 with 512 MBytes SRAM is very\n\t\t * unlikely, so the last SRAM byte isn't a valid address.\n\t\t */\n\t\t__asm__ volatile(\n\t\t\t\"mov r0, #0x3fffffff\\n\"\n\t\t\t\"ldrb r0, [r0]\\n\"\n\t\t\t);\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch state_err\" */\n\tcase state_err:\n\t\t/* UNDEFINSTR -- architectural undefined instruction */\n\t\t__asm__ volatile(\".hword 0xde00\");\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch chk_err\" */\n\tcase chk_err:\n\t\t/* UNALIGNED ldm */\n\t\t__asm__ volatile(\n\t\t\t\"mov r0, #1\\n\"\n\t\t\t\"ldm r0, {r1, r2}\\n\"\n\t\t\t);\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch nocp_err\" */\n\tcase nocp_err:\n\t\t/* NOCP ... Cortex-M3 has no coprocessors (like CP14 DCC),\n\t\t * but these instructions are allowed by ARMv7-M.\n\t\t */\n\t\t__asm__ volatile(\"mrc p14, 0, r0, c0, c5, 0\");\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch mm_err\" */\n\tcase mm_err:\n\t\t/* IACCVIOL -- instruction fetch from an XN region */\n\t\t__asm__ volatile(\n\t\t\t\"mov r0, #0xe0000000\\n\"\n\t\t\t\"mov pc, r0\\n\"\n\t\t\t);\n\t\tbreak;\n\n\t/* \"cortex_m vector_catch reset\" */\n\tcase reset:\n\t\t__asm__ volatile(\n\t\t\t/* r1 = SYSRESETREQ */\n\t\t\t\"mov r1, #0x0004\\n\"\n\t\t\t/* r1 |= VECTKEY */\n\t\t\t\"movt r1, #0x05fa\\n\"\n\t\t\t/* r0 = &AIRCR */\n\t\t\t\"mov r0, #0xed00\\n\"\n\t\t\t\"add r0, #0xc\\n\"\n\t\t\t\"movt r0, #0xe000\\n\"\n\t\t\t/* AIRCR = ... */\n\t\t\t\"str r1, [r0, #0]\\n\"\n\t\t\t);\n\t\tbreak;\n\t}\n\n\t/* don't return */\n\twhile (1)\n\t\tcontinue;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/cortex/test.c",
    "content": "/* simple app.\n\nmodify test.ld to change address.\n\nEven if the app is position independent, the symbols\nneed to match to test basic debugging.\n\nTo load the app to 0x20000000 in GDB, use:\n\nload a.out\nmonitor reg sp 0x20004000\nmonitor reg pc 0x20002000\nstepi\n\narm-elf-gcc -mthumb -mcpu = cortex-m3 -nostdlib -Ttest.ld test.c\n\n\n*/\nint j;\nvoid _start()\n{\n  int i;\n  for (i = 0; i < 1000; i++)\n    {\n      j++;\n    }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/cortex/test.ld",
    "content": "OUTPUT_FORMAT(\"elf32-littlearm\", \"elf32-bigarm\",\n\t      \"elf32-littlearm\")\nOUTPUT_ARCH(arm)\nENTRY(_start)\n/* Do we need any of these for elf?\n   __DYNAMIC = 0;    */\nSECTIONS\n{\n  /* Read-only sections, merged into text segment: */\n  . = 0x20002000;\n  .interp     : { *(.interp) \t}\n  .hash          : { *(.hash)\t\t}\n  .dynsym        : { *(.dynsym)\t\t}\n  .dynstr        : { *(.dynstr)\t\t}\n  .gnu.version   : { *(.gnu.version)\t}\n  .gnu.version_d   : { *(.gnu.version_d)\t}\n  .gnu.version_r   : { *(.gnu.version_r)\t}\n  .rel.init      : { *(.rel.init)\t}\n  .rela.init     : { *(.rela.init)\t}\n  .rel.text      :\n    {\n      *(.rel.text)\n      *(.rel.text.*)\n      *(.rel.gnu.linkonce.t*)\n    }\n  .rela.text     :\n    {\n      *(.rela.text)\n      *(.rela.text.*)\n      *(.rela.gnu.linkonce.t*)\n    }\n  .rel.fini      : { *(.rel.fini)\t}\n  .rela.fini     : { *(.rela.fini)\t}\n  .rel.rodata    :\n    {\n      *(.rel.rodata)\n      *(.rel.rodata.*)\n      *(.rel.gnu.linkonce.r*)\n    }\n  .rela.rodata   :\n    {\n      *(.rela.rodata)\n      *(.rela.rodata.*)\n      *(.rela.gnu.linkonce.r*)\n    }\n  .rel.data      :\n    {\n      *(.rel.data)\n      *(.rel.data.*)\n      *(.rel.gnu.linkonce.d*)\n    }\n  .rela.data     :\n    {\n      *(.rela.data)\n      *(.rela.data.*)\n      *(.rela.gnu.linkonce.d*)\n    }\n  .rel.ctors     : { *(.rel.ctors)\t}\n  .rela.ctors    : { *(.rela.ctors)\t}\n  .rel.dtors     : { *(.rel.dtors)\t}\n  .rela.dtors    : { *(.rela.dtors)\t}\n  .rel.got       : { *(.rel.got)\t\t}\n  .rela.got      : { *(.rela.got)\t\t}\n  .rel.sdata     :\n    {\n      *(.rel.sdata)\n      *(.rel.sdata.*)\n      *(.rel.gnu.linkonce.s*)\n    }\n  .rela.sdata     :\n    {\n      *(.rela.sdata)\n      *(.rela.sdata.*)\n      *(.rela.gnu.linkonce.s*)\n    }\n  .rel.sbss      : { *(.rel.sbss)\t\t}\n  .rela.sbss     : { *(.rela.sbss)\t}\n  .rel.bss       : { *(.rel.bss)\t\t}\n  .rela.bss      : { *(.rela.bss)\t\t}\n  .rel.plt       : { *(.rel.plt)\t\t}\n  .rela.plt      : { *(.rela.plt)\t\t}\n  .plt      : { *(.plt)\t}\n  .text      :\n  {\n    *(.text)\n    *(.text.*)\n    *(.stub)\n    /* .gnu.warning sections are handled specially by elf32.em.  */\n    *(.gnu.warning)\n    *(.gnu.linkonce.t*)\n    *(.glue_7t) *(.glue_7)\n  } =0\n  .init          : \n  { \n    KEEP (*(.init))\n  } =0\n  _etext = .;\n  PROVIDE (etext = .);\n  .fini      :\n  {\n    KEEP (*(.fini))\n  } =0\n  .rodata   : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }\n  .rodata1   : { *(.rodata1) }\n  .eh_frame_hdr : { *(.eh_frame_hdr) }\n  /* Adjust the address for the data segment.  We want to adjust up to\n     the same address within the page on the next page up.  */\n  . = ALIGN(256) + (. & (256 - 1));\n  .data    :\n  {\n    *(.data)\n    *(.data.*)\n    *(.gnu.linkonce.d*)\n    SORT(CONSTRUCTORS)\n  }\n  .data1   : { *(.data1) }\n  .eh_frame : { KEEP (*(.eh_frame)) }\n  .gcc_except_table : { *(.gcc_except_table) }\n  .ctors   : \n  {\n    /* gcc uses crtbegin.o to find the start of\n       the constructors, so we make sure it is\n       first.  Because this is a wildcard, it\n       doesn't matter if the user does not\n       actually link against crtbegin.o; the\n       linker won't look for a file to match a\n       wildcard.  The wildcard also means that it\n       doesn't matter which directory crtbegin.o\n       is in.  */\n    KEEP (*crtbegin.o(.ctors))\n    /* We don't want to include the .ctor section from\n       from the crtend.o file until after the sorted ctors.\n       The .ctor section from the crtend file contains the\n       end of ctors marker and it must be last */\n    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))\n    KEEP (*(SORT(.ctors.*)))\n    KEEP (*(.ctors))\n  }\n   .dtors         :\n  {\n    KEEP (*crtbegin.o(.dtors))\n    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))\n    KEEP (*(SORT(.dtors.*)))\n    KEEP (*(.dtors))\n  }\n  .jcr            : { KEEP (*(.jcr)) }\n  .got           : { *(.got.plt) *(.got) }\n  .dynamic       : { *(.dynamic) }\n  /* We want the small data sections together, so single-instruction offsets\n     can access them all, and initialized data all before uninitialized, so\n     we can shorten the on-disk segment size.  */\n  .sdata     : \n  {\n    *(.sdata) \n    *(.sdata.*)\n    *(.gnu.linkonce.s.*)\n  }\n  _edata = .;\n  PROVIDE (edata = .);\n  __bss_start = .;\n  __bss_start__ = .;\n  .sbss      :\n  {\n    *(.dynsbss)\n    *(.sbss)\n    *(.sbss.*)\n    *(.scommon)\n  }\n  .bss       :\n  {\n   *(.dynbss)\n   *(.bss)\n   *(.bss.*)\n   *(COMMON)\n   /* Align here to ensure that the .bss section occupies space up to\n      _end.  Align after .bss to ensure correct alignment even if the\n      .bss section disappears because there are no input sections.  */\n   . = ALIGN(32 / 8);\n  }\n  . = ALIGN(32 / 8);\n  _end = .;\n  _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;\n  PROVIDE (end = .);\n  /* Stabs debugging sections.  */\n  .stab 0 : { *(.stab) }\n  .stabstr 0 : { *(.stabstr) }\n  .stab.excl 0 : { *(.stab.excl) }\n  .stab.exclstr 0 : { *(.stab.exclstr) }\n  .stab.index 0 : { *(.stab.index) }\n  .stab.indexstr 0 : { *(.stab.indexstr) }\n  .comment 0 : { *(.comment) }\n  /* DWARF debug sections.\n     Symbols in the DWARF debugging sections are relative to the beginning\n     of the section so we begin them at 0.  */\n  /* DWARF 1 */\n  .debug          0 : { *(.debug) }\n  .line           0 : { *(.line) }\n  /* GNU DWARF 1 extensions */\n  .debug_srcinfo  0 : { *(.debug_srcinfo) }\n  .debug_sfnames  0 : { *(.debug_sfnames) }\n  /* DWARF 1.1 and DWARF 2 */\n  .debug_aranges  0 : { *(.debug_aranges) }\n  .debug_pubnames 0 : { *(.debug_pubnames) }\n  /* DWARF 2 */\n  .debug_info     0 : { *(.debug_info) }\n  .debug_abbrev   0 : { *(.debug_abbrev) }\n  .debug_line     0 : { *(.debug_line) }\n  .debug_frame    0 : { *(.debug_frame) }\n  .debug_str      0 : { *(.debug_str) }\n  .debug_loc      0 : { *(.debug_loc) }\n  .debug_macinfo  0 : { *(.debug_macinfo) }\n  .debug_ranges   0 : { *(.debug_ranges) }\n  /* SGI/MIPS DWARF 2 extensions */\n  .debug_weaknames 0 : { *(.debug_weaknames) }\n  .debug_funcnames 0 : { *(.debug_funcnames) }\n  .debug_typenames 0 : { *(.debug_typenames) }\n  .debug_varnames  0 : { *(.debug_varnames) }\n  .stack 0x20004000 : { _stack = .; *(.stack) }\n  /* These must appear regardless of  .  */\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx27ads/crt0.S",
    "content": "/* Sample initialization file */\n\t\n\t.extern\tmain\n\t.extern\texit\n\t\n/* .text is used instead of .section .text so it works with arm-aout too.  */\n\t.text\n\t.code 32\n\t.align \t0\n\n\t.global\t_mainCRTStartup\n\t.global\t_start\n\t.global\tstart\nstart:\n_start:\n_mainCRTStartup:\n\n/* Start by setting up a stack */\n\t/*  Set up the stack pointer to end of bss */\n\tldr\tr3, .LC2\n\tmov \tsp, r3\n\n\tsub\tsl, sp, #512\t/* Still assumes 512 bytes below sl */\n\n\tmov \ta2, #0\t\t/* Second arg: fill value */\n\tmov\tfp, a2\t\t/* Null frame pointer */\n\tmov\tr7, a2\t\t/* Null frame pointer for Thumb */\n\t\n\tldr\ta1, .LC1\t/* First arg: start of memory block */\n\tldr\ta3, .LC2\t/* Second arg: end of memory block */\n\tsub\ta3, a3, a1\t/* Third arg: length of block */\n\t\n\tmov\tr0, #0\t\t/*  no arguments  */\n\tmov\tr1, #0\t\t/*  no argv either */\n\n\tbl\tmain\n\tbl\texit\t\t/* Should not return */\n\n\t/* For Thumb, constants must be after the code since only \n\tpositive offsets are supported for PC relative addresses. */\n\t\n\t.align 0\n.LC1:\n\t.word\t__bss_start__\n.LC2:\n\t.word\t__bss_end__\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx27ads/gdbinit-imx27ads",
    "content": "echo Script to load ledtest on iMX27ADS.\\n\n\n# Note: you need to startup openocd with \"-f board/imx27ads.cfg\"\n# in order to it initialize RAM memory.\n\n# SETUP GDB :\n#\n# Common gdb setup for ARM CPUs\nset complaints 1\nset output-radix 10\nset input-radix 10\nset prompt (arm-gdb)\nset endian little\ndir .\n\n# CONNECT TO TARGET :\ntarget remote 127.0.0.1:3333\n\n#  LOAD IMAGE :\n#\n\n# Load the program executable called \"u-boot\"\nload test.elf\n\n# Load the symbols for the program.\nsymbol-file test.elf\n\n# RUN TO MAIN :\n#\n# Set a breakpoint at main().\n#b reset\nb main\n\n# Run to the breakpoint.\nc\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx27ads/ldscript",
    "content": "SECTIONS\n{\n    . = 0xA0000000;\n\t.text : { *(.text) }\n\t.data ALIGN(0x10): { *(.data) }\n\t.bss ALIGN(0x10): {\n\t    __bss_start__ = ABSOLUTE(.);\n\t    *(.bss)\n\t    . += 0x100;\n        }\n\t__bss_end__ = .;\nPROVIDE (__stack = .);\n\t_end = .;\n\t.debug_info     0 : { *(.debug_info) }\n   \t.debug_abbrev   0 : { *(.debug_abbrev) }\n   \t.debug_line     0 : { *(.debug_line) }\n   \t.debug_frame    0 : { *(.debug_frame) }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx27ads/test.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2009 by Alan Carvalho de Assis       \t\t           *\n *   acassis@gmail.com                                                     *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\nvoid delay()\n{\n\tint i;\n\tfor (i = 0; i < 500000; i++);\n}\n\n/* MAIN ARM FUNTION */\nint main (void)\n{\n\tint i;\n        volatile unsigned char *ledoff = ((volatile unsigned char *)0xD4000008);\n        volatile unsigned char *ledon = ((volatile unsigned char *)0xD400000C);\n\n\tfor (i = 0; i < 10000; i++)\n    \t{\n\t\t*ledon = 0x30;\n\t\tdelay();\n\t\t*ledoff = 0x30;\n\t\tdelay();\n    \t} /* FOR */\n\n} /* MAIN */\n\n__gccmain()\n{\n} /* GCCMAIN */\n\n\nvoid exit(int exit_code)\n{\n  while (1);\n} /* EXIT */\n\n\natexit()\n{\n  while (1);\n} /* ATEXIT */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx31pdk/crt0.S",
    "content": "/* Sample initialization file */\n\t\n\t.extern\tmain\n\t.extern\texit\n\t\n/* .text is used instead of .section .text so it works with arm-aout too.  */\n\t.text\n\t.code 32\n\t.align \t0\n\n\t.global\t_mainCRTStartup\n\t.global\t_start\n\t.global\tstart\nstart:\n_start:\n_mainCRTStartup:\n\n/* Start by setting up a stack */\n\t/*  Set up the stack pointer to end of bss */\n\tldr\tr3, .LC2\n\tmov \tsp, r3\n\n\tsub\tsl, sp, #512\t/* Still assumes 512 bytes below sl */\n\n\tmov \ta2, #0\t\t/* Second arg: fill value */\n\tmov\tfp, a2\t\t/* Null frame pointer */\n\tmov\tr7, a2\t\t/* Null frame pointer for Thumb */\n\t\n\tldr\ta1, .LC1\t/* First arg: start of memory block */\n\tldr\ta3, .LC2\t/* Second arg: end of memory block */\n\tsub\ta3, a3, a1\t/* Third arg: length of block */\n\t\n\tmov\tr0, #0\t\t/*  no arguments  */\n\tmov\tr1, #0\t\t/*  no argv either */\n\n\tbl\tmain\n\tbl\texit\t\t/* Should not return */\n\n\t/* For Thumb, constants must be after the code since only \n\tpositive offsets are supported for PC relative addresses. */\n\t\n\t.align 0\n.LC1:\n\t.word\t__bss_start__\n.LC2:\n\t.word\t__bss_end__\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx31pdk/gdbinit-imx31pdk",
    "content": "echo Script to load ledtest on iMX31PDK.\\n\n\n# Note: you need to startup openocd with \"-f board/imx31pdk.cfg\"\n# in order to it initialize RAM memory.\n\n# SETUP GDB :\n#\n# Common gdb setup for ARM CPUs\nset complaints 1\nset output-radix 10\nset input-radix 10\nset prompt (arm-gdb)\nset endian little\ndir .\n\n# CONNECT TO TARGET :\ntarget remote 127.0.0.1:3333\n\n#  LOAD IMAGE :\n#\n\n# Load the program executable called \"u-boot\"\nload test.elf\n\n# Load the symbols for the program.\nsymbol-file test.elf\n\n# RUN TO MAIN :\n#\n# Set a breakpoint at main().\n#b reset\nb main\n\n# Run to the breakpoint.\nc\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx31pdk/ldscript",
    "content": "SECTIONS\n{\n\t. = 0x80000100;\n\t.text : { *(.text) }\n\t.data ALIGN(0x10): { *(.data) }\n\t.bss ALIGN(0x10): {\n\t    __bss_start__ = ABSOLUTE(.);\n\t    *(.bss)\n\t    . += 0x100;\n        }\n\t__bss_end__ = .;\nPROVIDE (__stack = .);\n\t_end = .;\n\t.debug_info     0 : { *(.debug_info) }\n   \t.debug_abbrev   0 : { *(.debug_abbrev) }\n   \t.debug_line     0 : { *(.debug_line) }\n   \t.debug_frame    0 : { *(.debug_frame) }\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/examples/ledtest-imx31pdk/test.c",
    "content": "/***************************************************************************\n *   Copyright (C) 2009 by Alan Carvalho de Assis       \t\t           *\n *   acassis@gmail.com                                                     *\n *                                                                         *\n *   This program is free software; you can redistribute it and/or modify  *\n *   it under the terms of the GNU General Public License as published by  *\n *   the Free Software Foundation; either version 2 of the License, or     *\n *   (at your option) any later version.                                   *\n *                                                                         *\n *   This program is distributed in the hope that it will be useful,       *\n *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n *   GNU General Public License for more details.                          *\n *                                                                         *\n *   You should have received a copy of the GNU General Public License     *\n *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *\n ***************************************************************************/\n\nvoid delay()\n{\n\tint i;\n\tfor (i = 0; i < 500000; i++);\n}\n\n/* MAIN ARM FUNTION */\nint main (void)\n{\n        volatile unsigned char *led = ((volatile unsigned char *)0xB6020000);\n\n\twhile (1)\n    \t{\n\t\t*led = 0xFF;\n\t\tdelay();\n\t\t*led = 0x00;\n\t\tdelay();\n    \t} /* FOR */\n\n} /* MAIN */\n\n__gccmain()\n{\n} /* GCCMAIN */\n\n\nvoid exit(int exit_code)\n{\n  while (1);\n} /* EXIT */\n\n\natexit()\n{\n  while (1);\n} /* ATEXIT */\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/index.html",
    "content": "<html>\n\n\t<meta http-equiv=\"content-type\" content=\"text/html;charset=iso-8859-1\">\n\n\t<body>\n\t\t<h1>Release testing</h1>\n\t\tA release test must be done on code committed to git.\n\t\tCommit, then test. That way one can know for sure *what* code was actually tested.\n\t\t<p>\n\t\tNote that this testing document does not have anything to do with testing that is done\n\t\tbefore committing to git. It is a test document for released code. Pre-commit testing\n\t\tis done mostly by the developer who has written the change. Sometimes code is committed\n\t\tto synchronize work, even if it has known problems. Release testing is\n\t\tdone on code believed to be stable, often a couple of weeks old, and not by\n\t\tthe developers, but rather users and community testers who has the requisite hardware\n\t\tand test setup. Also the testing will take place over an extended period of time.\n\t\t<p>\n\t\tAll of the above makes it imperative that there can be no doubt about *which* code\n\t\tis tested and thus all tests refer to committed code by subversion number.\n\t\t<h1>Release procedure</h1>\n\t\tOpenOCD mainline is work in progress.\n\t\tExpect it to change daily and to have some quirks.\n\t\t<p>If you need the latest released and tested version, look for binary snapshots of OpenOCD. Worst case look up the test result table below for the features that are important to you and extract and build the version that has the right cocktail of working features for you. You can also work with the community to address the problems you are seing. Testing work and bug reports are highly appreciated.</p>\n\t\t<p>The OpenOCD community may decide to create release branches. If\n\t\tthis happens, then a branch will be created from OpenOCD mainline.\n\t\tThe particular version to create that branch might be an older version\n\t\trather than the latest and greatest. Fixes are then ported to that\n\t\trelease branch from OpenOCD mainline.</p>\n\t\t<hr>\n\t\t<h2>OpenOCD smoketests</h2>\n\t\tThis is a set of tests that exercise the entire OpenOCD system and various targets. It\n\t\tis a small suite of systemwide smoketests.\n\t\t<p>\n\t\t<a href=\"smoketests.html\">Smoketests</a>\n\t\t<h2>Test cases</h2>\n\t\tAdditionally OpenOCD has test cases that target specific functionality more precisely.\n\t\t<p>\n\t\tA full release test must include both smoketests and unit testing.\n\t\t<p>\n\t\t<a href=\"testcases.html\">Test cases</a>\n\t</body>\n\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/profile_stm32.txt",
    "content": "These are profile tests for the stm32 target.\n\nold version rev 1606:\n\nsingle step:   59 ms\nflash 64k :  24kB/s\nmdb 0 128 :  44ms\n\n\ntrunk rev 1662:\n\nsingle step:   99 ms\nflash 64k :  21.5kB/s\nmdb 0 128 :  72ms\n\n\nHow to run tests:\n\npoll off\nset before [flush_count]\nstep\nset step_count [expr [flush_count]-$before]\n\nset before [flush_count]\nmdb 0 128\nset mem_count [expr [flush_count]-$before]\n\nset before [flush_count]\nflash erase_address 0x8000000 0x10000\nset erase_count [expr [flush_count]-$before]\n\nset before [flush_count]\nflash fillb 0x8000000 0x55 0x10000\nset flash_fill_count [expr [flush_count]-$before]\n\nputs \"counts\" ; puts \"step       $step_count\" ; puts \"mem        $mem_count\" ; puts \"erase      $erase_count\" ; puts \"flash fill $flash_fill_count\"\n\nparport trunk rev 1675\n======================\n\nstep       336\nmem        160\nerase      3076\nflash fill 32754\n\nverify_ircapture disable\n\nstep       114\nmem        96\nerase      1547\nflash fill 15564\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/template.html",
    "content": "<html>\n\n\t<meta http-equiv=\"content-type\" content=\"text/html;charset=iso-8859-1\">\n\n\t<body>\n\t<a href=\"../testcases.html\">Testcases</a>\n\t<table border=\"1\">\n\t\t<tr><td>Test</td><td>Interface</td><td>Target</td><td>Result</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#CON001\">CON001</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#CON002\">CON002</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#RES001\">RES001</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#RES002\">RES002</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#RES003\">RES003</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t\t<tr><td><a href=\"../testcases.html#DBG001\">DBG001</a></td><td> FILL IN! </td><td>FILL IN!</td><td>PASS/FAIL</td></tr>\n\t</table>\n\t</body>\n\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/v0.4.0-rc1/AT91FR40162.html",
    "content": "<html>\n<head>\n<title>Test results for revision 1.62</title>\n</head>\n\n<body>\n\n<H1>SAM7</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON001\"/>CON001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Telnet connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On console, type<br><code>telnet ip port</code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON002\"/>CON002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>GDB server connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On GDB console, type<br><code>target remote ip:port</code></td>\n\t\t<td><code>Remote debugging using 10.0.0.73:3333</code></td>\n\t\t<td><code>\n\t\t\t(gdb) tar remo 10.0.0.138:3333<br>\n\t\t\tRemote debugging using 10.0.0.138:3333<br>\n\t\t\t0x000155b8 in ?? ()<br>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES001\"/>RES001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> mdw  0x01000000 32<br>                    \n\t\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x600000d3 pc: 0x00008a70<br>\n\t\t\t\t> <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES002\"/>RES002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset init on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset init</code></td>\n\t\t<td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset init<br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x600000d3 pc: 0x00008ea4<br>\n\t\t\t\t> <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS<br>\n\t\tNOTE! Even if there is no message, the reset script is being executed (proved by side effects)</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES003\"/>RES003</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset after a power cycle of the target</td>\n\t\t<td>Reset the target then power cycle the target</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\tSensed nSRST asserted<br>\n\t\t\t\tSensed power dropout.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0xd5dff7e6<br>\n\t\t\t\tSensed power restore.<br>\n\t\t\t\tSensed nSRST deasserted<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x0000072c<br>\n\t\t\t\t><br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES004\"/>RES004</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target where reset halt is supported</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n\t\t<td>\n\t\t\t> reset halt<br>\n\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0xf00000d3 pc: 0x00008b38<br>\n\t\t\t> <br>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES005\"/>RES005</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target using return clock</td>\n\t\t<td>Erase all the content of the flash, set the configuration script to use RCLK</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\tN/A, At91EB40A does <bold>NOT</bold> have support for RCLK\n\t\t\t</code>\t\n\t\t</td>\n\t\t<td>N/A</td>\t\n\t</tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD001\"/>SPD001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x00008ae8<br>\n\t\t\t\t> jtag_khz 16000  <br>\n\t\t\t\tjtag_speed 4 => JTAG clk=16.000000<br>\n\t\t\t\t16000 kHz<br>\n\t\t\t\t> mdw 0 32   <br>   \n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD002\"/>SPD002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset halt    <br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x00008c14<br>\n\t\t\t\t> jtag_khz 8000 <br>\n\t\t\t\tjtag_speed 8 => JTAG clk=8.000000<br>\n\t\t\t\t8000 kHz<br>\n\t\t\t\t> mdw 0 32  <br>   \n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t> <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD003\"/>SPD003</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>4MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset halt   <br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x00008bc4<br>\n\t\t\t\t> jtag_khz 4000<br>\n\t\t\t\tjtag_speed 16 => JTAG clk=4.000000<br>\n\t\t\t\t4000 kHz<br>\n\t\t\t\t> mdw 0 32  <br>   \n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t> <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD004\"/>SPD004</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>2MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x00009678<br>\n\t\t\t\t> jtag_khz 2000<br>\n\t\t\t\tjtag_speed 32 => JTAG clk=2.000000<br>\n\t\t\t\t2000 kHz<br>\n\t\t\t\t> mdw 0 32     <br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t> <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD005\"/>SPD005</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>RCLK on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 0<br>\n\t\t\t\tRCLK - adaptive<br>\n\t\t\t\tRCLK timeout<br>\n\t\t\t</code>\n\t\t\tN/A for this target\n\t\t</td>\n\t\t<td>N/A for this target</td>\t\n\t</tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG001\"/>DBG001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Load is working</td>\n\t\t<td>Reset init is working, RAM is accesible, GDB server is started</td>\n\t\t<td>On the console of the OS: <br>\n\t\t\t<code>$ arm-none-eabi-gdb redboot_ram.elf</code><br>\n\t\t\t<code>(gdb) target remote ip:port</code><br>\n\t\t\t<code>(gdb) load</load>\n\t\t</td>\n\t\t<td>Load should return without error, typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tLoading section .text, size 0x14c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 332<br>\n\t\t\t\tTransfer rate: 180 bytes/sec, 332 bytes/write.<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .rom_vectors, size 0x40 lma 0xc000<br>\n\t\t\tLoading section .text, size 0x103e8 lma 0xc040<br>\n\t\t\tLoading section .rodata, size 0x1a84 lma 0x1c428<br>\n\t\t\tLoading section .data, size 0x3ec lma 0x1deac<br>\n\t\t\tStart address 0xc040, load size 74392<br>\n\t\t\tTransfer rate: 572 KB/sec, 9299 bytes/write.<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\n\t<tr>\n\t\t<td><a name=\"DBG002\"/>DBG002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software breakpoint</td>\n\t\t<td>Load the redboot_ram.elf application, use instructions from GDB001</td>\n\t\t<td>In the GDB console:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor arm7_9 dbgrq enable<br>\n\t\t\t\tsoftware breakpoints enabled<br>\n\t\t\t\t(gdb) break cyg_start<br>\n\t\t\t\tBreakpoint 1 at 0xec: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The software breakpoint should be reached, a typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69\t  DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor arm7_9 dbgrq enable<br>\n\t\t\t\tuse of EmbeddedICE dbgrq instead of breakpoint for target halt enabled<br>\n\t\t\t\t(gdb) break cyg_start<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1 at 0x155b8: file /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c, line 264.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, cyg_start ()<br>\n\t\t\t\t    at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264<br>\n\t\t\t\t264\t    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);<br>\n\t\t\t\t(gdb) <br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG003\"/>DBG003</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in a RAM application</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>(gdb) step</code></td>\n\t\t<td>The next instruction should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t70\t  DWORD b = 2;\n\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t266\t    CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);<br>\n\t\t\t\t(gdb)<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG004\"/>DBG004</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software break points are working after a reset</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\t(gdb) load<br>\n\t\t\t(gdb) continue<br>\n\t\t\t</code></td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69\t  DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) moni reset init<br>\n\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0x600000d3 pc: 0x00008ae8<br>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .rom_vectors, size 0x40 lma 0xc000<br>\n\t\t\tLoading section .text, size 0x103e8 lma 0xc040<br>\n\t\t\tLoading section .rodata, size 0x1a84 lma 0x1c428<br>\n\t\t\tLoading section .data, size 0x3ec lma 0x1deac<br>\n\t\t\tStart address 0xc040, load size 74392<br>\n\t\t\tTransfer rate: 576 KB/sec, 9299 bytes/write.<br>\n\t\t\t(gdb) c<br>\n\t\t\tContinuing.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, cyg_start ()<br>\n\t\t\t    at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264<br>\n\t\t\t264\t    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);<br>\n\t\t\t(gdb) <br>\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG005\"/>DBG005</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint</td>\n\t\t<td>Flash the redboot_rom.elf application. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset init<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .rom_vectors, size 0x40 lma 0x1000000<br>\n\t\t\tLoading section .text, size 0x10638 lma 0x1000040<br>\n\t\t\tLoading section .rodata, size 0x1a84 lma 0x1010678<br>\n\t\t\tLoading section .data, size 0x428 lma 0x10120fc<br>\n\t\t\tStart address 0x1000040, load size 75044<br>\n\t\t\tTransfer rate: 33 KB/sec, 9380 bytes/write.<br>\n\t\t\t(gdb) break cyg_start<br>\n\t\t\tBreakpoint 1 at 0x100979c: file /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c, line 264.<br>\n\t\t\t(gdb) c<br>\n\t\t\tContinuing.<br>\n\t\t\tNote: automatically using hardware breakpoints for read-only addresses.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264<br>\n\t\t\t264\t    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);<br>\n\t\t\t(gdb) <br>\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG006\"/>DBG006</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint is set after a reset</td>\n\t\t<td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n\t\t<td>In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\t\tpc (/32): 0x00100000<br>\n\t\t\t\t(gdb) continue\n\t\t\t</code><br>\n\t\t\twhere the value inserted in PC is the start address of the application\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) moni reset init<br>\n\t\t\tJTAG tap: zy1000.cpu tap/device found: 0x1f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x1)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0x200000d3 pc: 0x01000200<br>\n\t\t\t(gdb) moni reg pc 0x1000000<br>\n\t\t\tpc (/32): 0x01000000<br>\n\t\t\t(gdb) c<br>\n\t\t\tContinuing.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264<br>\n\t\t\t264\t    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);<br>\n\t\t\t(gdb) <br>\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG007\"/>DBG007</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in ROM</td>\n\t\t<td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t\t(gdb) step\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\tBreakpoint 1, cyg_start () at /home/edgar/temp/ecosboard/packages/redboot/current/src/main.c:264<br>\n\t\t\t264\t    CYGACC_CALL_IF_MONITOR_VERSION_SET(RedBoot_version);<br>\n\t\t\t(gdb) step<br>\n\t\t\t266\t    CYGACC_CALL_IF_MONITOR_RETURN_SET(return_to_redboot);<br>\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM001\"/>RAM001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>32 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mww ram_address 0xdeadbeef 16<br>\n\t\t\t\t\t> mdw ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mww 0x0 0xdeadbeef 16<br>\n\t\t\t\t> mdw 0x0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n\t\t\t\t0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mww 0 0xdeadbeef 16<br>\n\t\t\t> mdw 0x0 32         <br>\n\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef <br>\n\t\t\t0x00000040: 15aadc6d 425b6f33 e789f955 d390dcc2 00080017 010067b4 010067b4 010067b4 <br>\n\t\t\t0x00000060: 010067b4 00006e74 00006e74 010067b4 010067b4 010067b4 010067b4 010067b4 <br>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM002\"/>RAM002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwh ram_address 0xbeef 16<br>\n\t\t\t\t\t> mdh ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mwh 0x0 0xbeef 16<br>\n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t\t0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t> mwh 0 0xbeef 16<br>    \n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br> \n\t\t\t\t0x00000020:   00   00   00   00   00   00   00   00   00   00   00   00   00   00   00   00 <br>\n\t\t\t</code></td>\n\t\t<td>PASS<br>There is a problem with the formatting of the output</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM003\"/>RAM003</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwb ram_address 0xab 16<br>\n\t\t\t\t\t> mdb ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n\t\t\t<code>\n\t\t\t\t> mwb ram_address 0xab 16<br>\n\t\t\t\t> mdb ram_address 32<br>\n\t\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mwb 0x0 0xab 16<br>\n\t\t\t> mdb 0x0 32     <br>\n\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br> \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA001\"/>FLA001</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash probe</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface:<br>\n\t\t\t<code>\t> flash probe 0</code>\n\t\t</td>\n\t\t<td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n\t\t\t<code>flash 'ecosflash' found at 0x01000000</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t> flash probe 0\n\t\t\tflash 'ecosflash' found at 0x01000000\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA002\"/>FLA002</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>flash fillw</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> flash fillw 0x100000 0xdeadbeef 16\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. The output looks like:<br>\n\t\t\t<code>\n\t\t\t\twrote 64 bytes to 0x0100000 in 11.610000s (0.091516 kb/s)\n\t\t\t</code><br>\n\t\t\tTo verify the contents of the flash:<br>\n\t\t\t<code>\n\t\t\t\t> mdw 0x100000 32<br>\n\t\t\t\t0x0100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x0100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t> flash fillw 0x01000000 0xdeadbeef 16 <br>  \n\t\t\t\twrote 64 bytes to 0x01000000 in 0.010000s (6.250 kb/s)<br>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n\t\t\t\t0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef <br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t\t>\n\t\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA003\"/>FLA003</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x100000 0x2000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x0100000 length 8192 in 4.970000s\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff. \n\t\t\t<code>\n\t\t\t\t> mdw 0x100000 32<br>\n\t\t\t\t0x0100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> flash erase_address 0x1000000 0x10000<br>\n\t\t\terased address 0x01000000 (length 65536) in 0.840000s (76.190 kb/s)<br>\n\t\t\t> mdw 0x1000000 32                     <br>\n\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff <br>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA004\"/>FLA004</td>\n\t\t<td>AT91FR40162</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Loading to flash from GDB</td>\n\t\t<td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n\t\t<td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n\t\t\t\t<code>\n\t\t\t\t\t(gdb) target remote ip:port<br>\n\t\t\t\t\t(gdb) monitor reset halt<br>\n\t\t\t\t\t(gdb) load<br>\n\t\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t\t(gdb) monitor verify_image path_to_elf_file\t\t\n\t\t\t\t</code>\n\t\t</td>\n\t\t<td>The output should look like:<br>\n\t\t\t<code>\n\t\t\t\tverified 404 bytes in 5.060000s\n\t\t\t</code><br>\n\t\t\tThe failure message is something like:<br>\n\t\t\t<code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .rom_vectors, size 0x40 lma 0x1000000<br>\n\t\t\t\tLoading section .text, size 0x10638 lma 0x1000040<br>\n\t\t\t\tLoading section .rodata, size 0x1a84 lma 0x1010678<br>\n\t\t\t\tLoading section .data, size 0x428 lma 0x10120fc<br>\n\t\t\t\tStart address 0x1000040, load size 75044<br>\n\t\t\t\tTransfer rate: 34 KB/sec, 9380 bytes/write.<br>\n\t\t\t\t(gdb) moni verify_image /tftp/10.0.0.190/redboot_rom.elf<br>\n\t\t\t\tkeep_alive() was not invoked in the 1000ms timelimit. GDB alive packet not sent! (1820). Workaround: increase \"set remotetimeout\" in GDB<br>\n\t\t\t\tverified 75044 bytes in 1.960000s (37.390 kb/s)<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\t\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/v0.4.0-rc1/LPC2148.html",
    "content": "<html>\n<head>\n<title>Test results for revision 1.62</title>\n</head>\n\n<body>\n\n<H1>LPC2148</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON001\"/>CON001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Telnet connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On console, type<br><code>telnet ip port</code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON002\"/>CON002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>GDB server connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On GDB console, type<br><code>target remote ip:port</code></td>\n\t\t<td><code>Remote debugging using 10.0.0.73:3333</code></td>\n\t\t<td><code>\n\t\t\t(gdb) tar remo 10.0.0.73:3333<br>\n\t\t\tRemote debugging using 10.0.0.73:3333<br>\n\t\t\t0x00000000 in ?? ()<br>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES001\"/>RES001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES002\"/>RES002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset init on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset init</code></td>\n\t\t<td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset init<br>\n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2da<br>\n\t\t\t\tcore state: ARM<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS<br>\n\t\tNOTE! Even if there is no message, the reset script is being executed (proved by side effects)</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES003\"/>RES003</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset after a power cycle of the target</td>\n\t\t<td>Reset the target then power cycle the target</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\tnsed nSRST asserted.<br>\n\t\t\t\tnsed power dropout.<br>\n\t\t\t\tnsed power restore.<br>\n\t\t\t\tSRST took 186ms to deassert<br>\n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\t\tcore state: ARM<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES004\"/>RES004</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target where reset halt is supported</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t> reset halt<br>\n\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES005\"/>RES005</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target using return clock</td>\n\t\t<td>Erase all the content of the flash, set the configuration script to use RCLK</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t> jtag_khz 0<br>\n\t\t\tRCLK - adaptive<br>\n\t\t\t> reset init<br>\n\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\tcore state: ARM<br>\n\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD001\"/>SPD001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 16000<br>\n\t\t\t\tjtag_speed 4 => JTAG clk=16.000000<br>\n\t\t\t\t16000 kHz<br>\n\t\t\t\t> reset halt<br>    \n\t\t\t\tJTAG scan chain interrogation failed: all zeroes<br>\n\t\t\t\tCheck JTAG interface, timings, target power, etc.<br>\n\t\t\t\terror: -100<br>\n\t\t\t\tCommand handler execution failed<br>\n\t\t\t\tin procedure 'reset' called at file \"command.c\", line 638<br>\n\t\t\t\tcalled at file \"/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c\", line 352<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tThumbEE -- incomplete support<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ThumbEE state due to debug-request, current mode: System<br>\n\t\t\t\tcpsr: 0x1fffffff pc: 0xfffffffa<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: System<br>\n\t\t\t\tcpsr: 0xc00003ff pc: 0xfffffff0<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tThumbEE -- incomplete support<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ThumbEE state due to debug-request, current mode: System<br>\n\t\t\t\tcpsr: 0xffffffff pc: 0xfffffffa<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD002\"/>SPD002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 8000<br> \n\t\t\t\tjtag_speed 8 => JTAG clk=8.000000<br>\n\t\t\t\t8000 kHz<br>\n\t\t\t\t> reset halt<br>   \n\t\t\t\tJTAG scan chain interrogation failed: all zeroes<br>\n\t\t\t\tCheck JTAG interface, timings, target power, etc.<br>\n\t\t\t\terror: -100<br>\n\t\t\t\tCommand handler execution failed<br>\n\t\t\t\tin procedure 'reset' called at file \"command.c\", line 638<br>\n\t\t\t\tcalled at file \"/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c\", line 352<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\tinvalid mode value encountered 0<br>\n\t\t\t\tcpsr contains invalid mode value - communication failure<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD003\"/>SPD003</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>4MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 4000<br>\n\t\t\t\tjtag_speed 16 => JTAG clk=4.000000<br>\n\t\t\t\t4000 kHz<br>\n\t\t\t\t> reset halt<br>   \n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0xc79f0f87 (mfg: 0x7c3, part: 0x79f0, ver: 0xc)<br>\n\t\t\t\tJTAG tap: lpc2148.cpu       UNEXPECTED: 0xc79f0f87 (mfg: 0x7c3, part: 0x79f0, ver: 0xc)<br>\n\t\t\t\tJTAG tap: lpc2148.cpu  expected 1 of 1: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tUnexpected idcode after end of chain: 64 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 160 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 192 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 320 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 352 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 384 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 480 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 512 0x0000007f<br>\n\t\t\t\tUnexpected idcode after end of chain: 544 0x0000007f<br>\n\t\t\t\tdouble-check your JTAG setup (interface, speed, missing TAPs, ...)<br>\n\t\t\t\terror: -100<br>\n\t\t\t\tCommand handler execution failed<br>\n\t\t\t\tin procedure 'reset' called at file \"command.c\", line 638<br>\n\t\t\t\tcalled at file \"/home/laurentiu/workspace/zy1000/build/../openocd/src/helper/command.c\", line 352<br>\n\t\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD004\"/>SPD004</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>2MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 2000<br>\n\t\t\t\tjtag_speed 32 => JTAG clk=2.000000<br>\n\t\t\t\t2000 kHz<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2da<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: e59f4034 e3a05002 e5845000 e3a05003 e5845004 e59f201c e3a03000 e1020093<br> \n\t\t\t\t0x00000020: e2822028 e1021093 e3c03007 e5023028 e51ff004 7fffd1c4 e002c014 e01fc000<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD005\"/>SPD005</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>RCLK on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 0<br>\n\t\t\t\tRCLK - adaptive<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: e59f4034 e3a05002 e5845000 e3a05003 e5845004 e59f201c e3a03000 e1020093<br> \n\t\t\t\t0x00000020: e2822028 e1021093 e3c03007 e5023028 e51ff004 7fffd1c4 e002c014 e01fc000<br> \n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG001\"/>DBG001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Load is working</td>\n\t\t<td>Reset init is working, RAM is accesible, GDB server is started</td>\n\t\t<td>On the console of the OS: <br>\n\t\t\t<code>arm-elf-gdb test_ram.elf</code><br>\n\t\t\t<code>(gdb) target remote ip:port</code><br>\n\t\t\t<code>(gdb) load</load>\n\t\t</td>\n\t\t<td>Load should return without error, typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tLoading section .text, size 0x14c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 332<br>\n\t\t\t\tTransfer rate: 180 bytes/sec, 332 bytes/write.<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .text, size 0x16c lma 0x40000000<br>\n\t\t\tStart address 0x40000040, load size 364<br>\n\t\t\tTransfer rate: 32 KB/sec, 364 bytes/write.<br>\n\t\t\t(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\n\t<tr>\n\t\t<td><a name=\"DBG002\"/>DBG002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software breakpoint</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001</td>\n\t\t<td>In the GDB console:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override soft<br>\n\t\t\t\tsoftware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0xec: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The software breakpoint should be reached, a typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override soft<br>\n\t\t\t\tforce soft breakpoints<br>\n\t\t\t\tCurrent language:  auto<br>\n\t\t\t\tThe current source language is \"auto; currently asm\".<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x4000010c: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) c<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71\t  DWORD a = 1;<br>\n\t\t\t\tCurrent language:  auto<br>\n\t\t\t\tThe current source language is \"auto; currently c\".<br>\n\t\t\t\t(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG003\"/>DBG003</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in a RAM application</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>(gdb) step</code></td>\n\t\t<td>The next instruction should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f0<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f4<br>\n\t\t\t\t72        DWORD b = 2;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t72\t  DWORD b = 2;<br>\n\t\t\t\t(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG004\"/>DBG004</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software break points are working after a reset</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\t(gdb) load<br>\n\t\t\t(gdb) continue<br>\n\t\t\t</code></td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) moni reset init<br>\n\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in Thumb state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0xa00000f3 pc: 0x7fffd2d6<br>\n\t\t\tcore state: ARM<br>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .text, size 0x16c lma 0x40000000<br>\n\t\t\tStart address 0x40000040, load size 364<br>\n\t\t\tTransfer rate: 27 KB/sec, 364 bytes/write.<br>\n\t\t\t(gdb) c<br>\n\t\t\tContinuing.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t71\t  DWORD a = 1;<br>\n\t\t\t(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG005\"/>DBG005</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint</td>\n\t\t<td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset init<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override hard<br>\n\t\t\t\tforce hard breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) monitor gdb_breakpoint_override hard<br>\n\t\t\tforce hard breakpoints<br>\n\t\t\t(gdb) break main<br>\n\t\t\tBreakpoint 1 at 0x10c: file src/main.c, line 71.<br>\n\t\t\t(gdb) continue<br>\n\t\t\tContinuing.<br>\n\t\t\tNote: automatically using hardware breakpoints for read-only addresses.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t71\t  DWORD a = 1;<br>\n\t\t\tCurrent language:  auto<br>\n\t\t\tThe current source language is \"auto; currently c\".<br>\n\t\t\t(gdb) \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS <font color=red>NOTE: This test is failing from time to time, not able to describe a cause</font></td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG006\"/>DBG006</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint is set after a reset</td>\n\t\t<td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n\t\t<td>In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\t\tpc (/32): 0x00100000<br>\n\t\t\t\t(gdb) continue\n\t\t\t</code><br>\n\t\t\twhere the value inserted in PC is the start address of the application\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\tJTAG tap: lpc2148.cpu tap/device found: 0x4f1f0f0f (mfg: 0x787, part: 0xf1f0, ver: 0x4)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00000160<br>\n\t\t\tcore state: ARM<br>\n\t\t\t(gdb) monitor reg pc 0x40<br>\n\t\t\tpc (/32): 0x00000040<br>\n\t\t\t(gdb) continue<br>\n\t\t\tContinuing.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t71\t  DWORD a = 1;<br>\n\t\t\t(gdb) \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG007\"/>DBG007</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in ROM</td>\n\t\t<td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override hard<br>\n\t\t\t\tforce hard breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t\t(gdb) step\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x16c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 364<br>\n\t\t\t\tTransfer rate: 637 bytes/sec, 364 bytes/write.<br>\n\t\t\t\t(gdb)  monitor gdb_breakpoint_override hard<br>\n\t\t\t\tforce hard breakpoints<br>\n\t\t\t\tCurrent language:  auto<br>\n\t\t\t\tThe current source language is \"auto; currently asm\".<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x10c: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\tNote: automatically using hardware breakpoints for read-only addresses.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71\t  DWORD a = 1;<br>\n\t\t\t\tCurrent language:  auto<br>\n\t\t\t\tThe current source language is \"auto; currently c\".<br>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t72\t  DWORD b = 2;<br>\n\t\t\t\t(gdb)\n\t\t\t\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM001\"/>RAM001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>32 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mww ram_address 0xdeadbeef 16<br>\n\t\t\t\t\t> mdw ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mww 0x0 0xdeadbeef 16<br>\n\t\t\t\t> mdw 0x0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n\t\t\t\t0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mww 0x40000000 0xdeadbeef 16<br>\n\t\t\t> mdw 0x40000000 32<br>\n\t\t\t0x40000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n\t\t\t0x40000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t0x40000040: e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000 e1a00000<br> \n\t\t\t0x40000060: e321f0db e59fd07c e321f0d7 e59fd078 e321f0d1 e59fd074 e321f0d2 e59fd070<br> \n\t\t\t> \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM002\"/>RAM002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwh ram_address 0xbeef 16<br>\n\t\t\t\t\t> mdh ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mwh 0x0 0xbeef 16<br>\n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t\t0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mwh 0x40000000 0xbeef 16<br>\n\t\t\t> mdh 0x40000000 32<br>       \n\t\t\t0x40000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br> \n\t\t\t0x40000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead<br> \n\t\t\t> \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM003\"/>RAM003</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwb ram_address 0xab 16<br>\n\t\t\t\t\t> mdb ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n\t\t\t<code>\n\t\t\t\t> mwb ram_address 0xab 16<br>\n\t\t\t\t> mdb ram_address 32<br>\n\t\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mwb 0x40000000 0xab 16\n\t\t\t> mdb 0x40000000 32     \n\t\t\t0x40000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be \n\t\t\t>\n\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA001\"/>FLA001</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash probe</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface:<br>\n\t\t\t<code>\t> flash probe 0</code>\n\t\t</td>\n\t\t<td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n\t\t\t<code>flash 'ecosflash' found at 0x01000000</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t> flash probe 0<br>\n\t\t\tflash 'lpc2000' found at 0x00000000\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA002\"/>FLA002</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>flash fillw</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> flash fillw 0x1000000 0xdeadbeef 16\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. The output looks like:<br>\n\t\t\t<code>\n\t\t\t\twrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s)\n\t\t\t</code><br>\n\t\t\tTo verify the contents of the flash:<br>\n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t> flash fillw 0x0 0xdeadbeef 16<br>\n\t\t\t\tVerification will fail since checksum in image (0xdeadbeef) to be written to flash is different from calculated vector checksum (0xe93fc777).<br>\n\t\t\t\tTo remove this warning modify build tools on developer PC to inject correct LPC vector checksum.<br>\n\t\t\t\twrote 64 bytes to 0x00000000 in 0.040000s (1.563 kb/s)<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef e93fc777 deadbeef deadbeef<br> \n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t> \n\t\t\t</code></td>\n\t\t<td><font color=red>FAIL</font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA003\"/>FLA003</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x1000000 0x2000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x01000000 length 8192 in 4.970000s\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff. \n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> flash erase_address 0 0x2000<br>\n\t\t\terased address 0x00000000 (length 8192) in 0.510000s (15.686 kb/s)<br>\n\t\t\t> mdw 0 32<br>\n\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t> \n\t\t</code></td>\t\t\t\t\n\t\t<td>PASS</td>\n\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA004\"/>FLA004</td>\n\t\t<td>LPC2148</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Loading to flash from GDB</td>\n\t\t<td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n\t\t<td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n\t\t\t\t<code>\n\t\t\t\t\t(gdb) target remote ip:port<br>\n\t\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t\t(gdb) load<br>\n\t\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.\n\t\t\t\t\t(gdb) monitor verify_image path_to_elf_file\t\t\n\t\t\t\t</code>\n\t\t</td>\n\t\t<td>The output should look like:<br>\n\t\t\t<code>\n\t\t\t\tverified 404 bytes in 5.060000s\n\t\t\t</code><br>\n\t\t\tThe failure message is something like:<br>\n\t\t\t<code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) moni verify_image /tftp/10.0.0.194/test_rom.elf<br>\n\t\t\t\tchecksum mismatch - attempting binary compare<br>\n\t\t\t\tVerify operation failed address 0x00000014. Was 0x58 instead of 0x60<br>\n\t\t\t\t<br>\n\t\t\t\tCommand handler execution failed<br>\n\t\t\t\tin procedure 'verify_image' called at file \"command.c\", line 647<br>\n\t\t\t\tcalled at file \"command.c\", line 361<br>\n\t\t\t\t(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red>FAIL</font></td>\n\t</tr>\t\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/v0.4.0-rc1/SAM7.html",
    "content": "<html>\n<head>\n<title>Test results for revision 1.62</title>\n</head>\n\n<body>\n\n<H1>SAM7</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON001\"/>CON001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Telnet connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On console, type<br><code>telnet ip port</code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON002\"/>CON002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>GDB server connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On GDB console, type<br><code>target remote ip:port</code></td>\n\t\t<td><code>Remote debugging using 10.0.0.73:3333</code></td>\n\t\t<td><code>\n\t\t\t(gdb) tar remo 10.0.0.73:3333<br>\n\t\t\tRemote debugging using 10.0.0.73:3333<br>\n\t\t\t0x00100174 in ?? ()<br>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES001\"/>RES001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tSRST took 2ms to deassert<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x600000d3 pc: 0x000003c4<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES002\"/>RES002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset init on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset init</code></td>\n\t\t<td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset init<br>\n\t\t\t\tSRST took 2ms to deassert<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x600000d3 pc: 0x000003c0<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS<br>\n\t\tNOTE! Even if there is no message, the reset script is being executed (proved by side effects)</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES003\"/>RES003</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset after a power cycle of the target</td>\n\t\t<td>Reset the target then power cycle the target</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\tSensed nSRST asserted<br>\n\t\t\t\tSensed power dropout.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0xd5dff7e6<br>\n\t\t\t\tSensed power restore.<br>\n\t\t\t\tSensed nSRST deasserted<br>\n\t\t\t\t> reset halt<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0xf00000d3 pc: 0x0000072c<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES004\"/>RES004</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target where reset halt is supported</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> reset halt<br>\n\t\t\t\tSRST took 2ms to deassert<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x300000d3 pc: 0x000003c0\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES005\"/>RES005</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target using return clock</td>\n\t\t<td>Erase all the content of the flash, set the configuration script to use RCLK</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 0<br>\n\t\t\t\tjtag_khz: 0<br>\n\t\t\t\t> reset init<br>\n\t\t\t\tSRST took 2ms to deassert<br>\n\t\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x300000d3 pc: 0x000003c0<br>\n\t\t\t\texecuting event/sam7s256_reset.script<br>\n\t\t\t\t>\n\t\t\t</code>\t\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD001\"/>SPD001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 16000<br>\n\t\t\t\tjtag_speed 4 => JTAG clk=16.000000<br>\n\t\t\t\tjtag_khz: 16000<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD002\"/>SPD002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 8000<br>\n\t\t\t\tjtag_speed 8 => JTAG clk=8.000000<br>\n\t\t\t\tjtag_khz: 8000<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD003\"/>SPD003</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>4MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 4000<br>\n\t\t\t\tjtag_speed 16 => JTAG clk=4.000000<br>\n\t\t\t\tjtag_khz: 4000<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD004\"/>SPD004</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>2MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 2000<br>\n\t\t\t\tjtag_speed 32 => JTAG clk=2.000000<br>\n\t\t\t\tjtag_khz: 2000<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD005\"/>SPD005</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>RCLK on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t> jtag_khz 0<br>\n\t\t\t\tjtag_khz: 0<br>\n\t\t\t\t> mdw 0 32<br>\n\t\t\t\t0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG001\"/>DBG001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Load is working</td>\n\t\t<td>Reset init is working, RAM is accesible, GDB server is started</td>\n\t\t<td>On the console of the OS: <br>\n\t\t\t<code>arm-elf-gdb test_ram.elf</code><br>\n\t\t\t<code>(gdb) target remote ip:port</code><br>\n\t\t\t<code>(gdb) load</load>\n\t\t</td>\n\t\t<td>Load should return without error, typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tLoading section .text, size 0x14c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 332<br>\n\t\t\t\tTransfer rate: 180 bytes/sec, 332 bytes/write.<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .text, size 0x194 lma 0x200000<br>\n\t\t\tStart address 0x200040, load size 404<br>\n\t\t\tTransfer rate: 443 bytes/sec, 404 bytes/write.<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\n\t<tr>\n\t\t<td><a name=\"DBG002\"/>DBG002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software breakpoint</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001</td>\n\t\t<td>In the GDB console:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor arm7_9 dbgrq enable<br>\n\t\t\t\tsoftware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0xec: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The software breakpoint should be reached, a typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69\t  DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor arm7_9 dbgrq enable<br>\n\t\t\t\tuse of EmbeddedICE dbgrq instead of breakpoint for target halt enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x200134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) c<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69\t  DWORD a = 1;<br>\n\t\t\t\tCurrent language:  auto<br>\n\t\t\t\tThe current source language is \"auto; currently c\".<br>\t\t\t\t\n\t\t\t\t(gdb)\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG003\"/>DBG003</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in a RAM application</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>(gdb) step</code></td>\n\t\t<td>The next instruction should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t70\t  DWORD b = 2;\n\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t70\t  DWORD b = 2;\n\t\t\t\t(gdb)\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG004\"/>DBG004</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software break points are working after a reset</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\t(gdb) load<br>\n\t\t\t(gdb) continue<br>\n\t\t\t</code></td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69\t  DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\tJTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug-request, current mode: Supervisor<br>\n\t\t\tcpsr: 0x600000d3 pc: 0x0000031c<br>\n\t\t\t(gdb) load<br>\n\t\t\tLoading section .text, size 0x194 lma 0x200000<br>\n\t\t\tStart address 0x200040, load size 404<br>\n\t\t\tTransfer rate: 26 KB/sec, 404 bytes/write.<br>\n\t\t\t(gdb) continue<br>\n\t\t\tContinuing.<br>\n\t\t\t<br>\n\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t69\t  DWORD a = 1;<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG005\"/>DBG005</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint</td>\n\t\t<td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset init<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t(gdb) break main<br>\n\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t(gdb) continue<br>\n\t\t\tContinuing.<br>\n\t\t\tNote: automatically using hardware breakpoints for read-only addresses.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00100134<br>\n<br>\n\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t69        DWORD a = 1;<br>\n\t\t\t(gdb)\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG006\"/>DBG006</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint is set after a reset</td>\n\t\t<td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n\t\t<td>In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\t\tpc (/32): 0x00100000<br>\n\t\t\t\t(gdb) continue\n\t\t\t</code><br>\n\t\t\twhere the value inserted in PC is the start address of the application\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\tSRST took 3ms to deassert<br>\n\t\t\tJTAG device found: 0x3f0f0f0f (Manufacturer: 0x787, Part: 0xf0f0, Version: 0x3)<br>\n\t\t\tsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to debug request, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00100168<br>\n\t\t\texecuting event/sam7s256_reset.script<br>\n\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\tpc (/32): 0x00100000<br>\n\t\t\t(gdb) continue<br>\n\t\t\tContinuing.<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00100040<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00100134<br>\n<br>\n\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t69        DWORD a = 1;<br>\n\t\t\t(gdb)\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG007\"/>DBG007</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in ROM</td>\n\t\t<td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t\t(gdb) step\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t69        DWORD a = 1;<br>\n\t\t\t(gdb) step<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x00100138<br>\n\t\t\ttarget state: halted<br>\n\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t70        DWORD b = 2;<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM001\"/>RAM001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>32 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mww ram_address 0xdeadbeef 16<br>\n\t\t\t\t\t> mdw ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mww 0x0 0xdeadbeef 16<br>\n\t\t\t\t> mdw 0x0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n\t\t\t\t0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mww 0x00200000 0xdeadbeef 16<br>\n\t\t\t> mdw 0x00200000 32<br>\n\t\t\t0x00200000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t0x00200020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t0x00200040: e59f10b4 e3a00902 e5810004 e59f00ac e59f10ac e5810000 e3e010ff e59f00a4<br>\n\t\t\t0x00200060: e5810060 e59f10a0 e3e00000 e5810130 e5810124 e321f0db e59fd090 e321f0d7\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM002\"/>RAM002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwh ram_address 0xbeef 16<br>\n\t\t\t\t\t> mdh ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mwh 0x0 0xbeef 16<br>\n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t\t0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> mwh 0x00200000 0xbeef 16<br>\n\t\t\t> mdh 0x00200000 32<br>\n\t\t\t0x00200000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t0x00200020: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM003\"/>RAM003</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwb ram_address 0xab 16<br>\n\t\t\t\t\t> mdb ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n\t\t\t<code>\n\t\t\t\t> mwb ram_address 0xab 16<br>\n\t\t\t\t> mdb ram_address 32<br>\n\t\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t>  mwb 0x00200000 0xab 16<br>\n\t\t\t> mdb 0x00200000 32<br>\n\t\t\t0x00200000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA001\"/>FLA001</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash probe</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface:<br>\n\t\t\t<code>\t> flash probe 0</code>\n\t\t</td>\n\t\t<td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n\t\t\t<code>flash 'ecosflash' found at 0x01000000</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t> flash probe 0<br>\n\t\t\tflash 'at91sam7' found at 0x00100000\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA002\"/>FLA002</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>flash fillw</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> flash fillw 0x100000 0xdeadbeef 16\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. The output looks like:<br>\n\t\t\t<code>\n\t\t\t\twrote 64 bytes to 0x0100000 in 11.610000s (0.091516 kb/s)\n\t\t\t</code><br>\n\t\t\tTo verify the contents of the flash:<br>\n\t\t\t<code>\n\t\t\t\t> mdw 0x100000 32<br>\n\t\t\t\t0x0100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x0100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t> flash fillw 0x100000 0xdeadbeef 16<br>\n\t\t\t\twrote 64 bytes to 0x00100000 in 0.040000s (26.562500 kb/s)<br>\n\t\t\t\t> mdw 0x100000 32<br>\n\t\t\t\t0x00100000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00100020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t>\n\t\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA003\"/>FLA003</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x100000 0x2000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x0100000 length 8192 in 4.970000s\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff. \n\t\t\t<code>\n\t\t\t\t> mdw 0x100000 32<br>\n\t\t\t\t0x0100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x0100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t> flash erase_address 0x100000 0x2000<br>\n\t\t\terased address 0x00100000 length 8192 in 0.020000s<br>\n\t\t\t> mdw 0x100000 32<br>\n\t\t\t0x00100000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t0x00100020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t0x00100040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t0x00100060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t>\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA004\"/>FLA004</td>\n\t\t<td>SAM7S64</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Loading to flash from GDB</td>\n\t\t<td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n\t\t<td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n\t\t\t\t<code>\n\t\t\t\t\t(gdb) target remote ip:port<br>\n\t\t\t\t\t(gdb) monitor reset halt<br>\n\t\t\t\t\t(gdb) load<br>\n\t\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t\t(gdb) monitor verify_image path_to_elf_file\t\t\n\t\t\t\t</code>\n\t\t</td>\n\t\t<td>The output should look like:<br>\n\t\t\t<code>\n\t\t\t\tverified 404 bytes in 5.060000s\n\t\t\t</code><br>\n\t\t\tThe failure message is something like:<br>\n\t\t\t<code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 4 KB/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) moni verify_image /tftp/10.0.0.9/c:/temp/testing/examples/SAM7S256Test/test_rom.elf<br>\n\t\t\t\tverified 404 bytes in 0.570000s\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\t\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/v0.4.0-rc1/STR710.html",
    "content": "<html>\n<head>\n<title>Test results for version 1.62</title>\n</head>\n\n<body>\n\n<H1>STR710</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON001\"/>CON001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Telnet connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On console, type<br><code>telnet ip port</code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td><code>> telnet 10.0.0.142<br>\n\t\t\t\t\tTrying 10.0.0.142...<br>\n\t\t\t\t\tConnected to 10.0.0.142.<br>\n\t\t\t\t\tEscape character is '^]'.<br>\n\t\t\t\t\tOpen On-Chip Debugger<br>\n\t\t\t\t\t>\n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON002\"/>CON002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>GDB server connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On GDB console, type<br><code>target remote ip:port</code></td>\n\t\t<td><code>Remote debugging using 10.0.0.73:3333</code></td>\n\t\t<td><code>\n\t\t\t(gdb) tar remo 10.0.0.142:3333<br>\n\t\t\tRemote debugging using 10.0.0.142:3333<br>\n\t\t\t0x00016434 in ?? ()<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES001\"/>RES001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n> mdw 0 32<br>\n0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e<br> \n0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292<br> \n0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18<br>\n0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8<br>\n> reset<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\n><br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES002\"/>RES002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset init on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset init</code></td>\n\t\t<td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n\t\t<td>\n\t\t\t<code>\n> reset init<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Undefined instruction<br>\ncpsr: 0xf00000db pc: 0x00000004<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES003\"/>RES003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset after a power cycle of the target</td>\n\t\t<td>Reset the target then power cycle the target</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n  nsed power dropout.<br>\n  nsed power dropout.<br>\n  nsed nSRST deasserted.<br>\n  invalid mode value encountered 0<br>\ncpsr contains invalid mode value - communication failure<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x100000d3 pc: 0x0000001c<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz<br>\n  nsed power restore.<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x500000d3 pc: 0x00000000<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz<br>\n> reset init<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x500000d3 pc: 0x00000000<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz<br>\n>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES004\"/>RES004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target where reset halt is supported</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n> reset halt<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x200000d3 pc: 0xfe50cba4<br>\n>\n</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES005\"/>RES005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target using return clock</td>\n\t\t<td>Erase all the content of the flash, set the configuration script to use RCLK</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t> jtag_khz 0<br>\nRCLK - adaptive<br>\nRCLK timeout<br>\nRCLK timeout<br>\nRCLK timeout<br>\n\t\t\t> reset halt<br>\n RCLK timeout<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x200000d3 pc: 0xfe50cb50<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD001\"/>SPD001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 16000<br>\njtag_speed 4 => JTAG clk=16.000000<br>\n16000 kHz<br>\n> mdw 0 32<br>\n0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e<br> \n0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292<br> \n0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18<br> \n0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8<br> \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD002\"/>SPD002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 8000<br>  \njtag_speed 8 => JTAG clk=8.000000<br> \n8000 kHz<br> \n> mdw 0 32<br>      \n0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e<br>  \n0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292<br>  \n0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18<br>  \n0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8<br>  \n>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD003\"/>SPD003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>4MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 4000<br> \njtag_speed 16 => JTAG clk=4.000000<br> \n4000 kHz<br> \n> mdw 0 32<br>      \n0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e<br>  \n0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292<br>  \n0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18<br>  \n0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8<br>  \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD004\"/>SPD004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>2MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> > jtag_khz 2000<br> \njtag_speed 32 => JTAG clk=2.000000<br>\n2000 kHz<br>\n> mdw 0 32<br>     \n0x00000000: 75755000 8a930104 65696f65 939a3e98 214751f1 fa0edb9b 6664686d 931a989e<br> \n0x00000020: 676c65e4 9a0a0982 25653445 da02ba90 c4ed3165 9b9a8a9a 65676365 01981292<br> \n0x00000040: 212e0982 82ba3f8b 34674765 96ba1a9a 6175e7e5 9b9ab91a 0789644d 120a9a18<br> \n0x00000060: 65446167 80d20982 6d6d6565 187090ca 65277d65 9a9a0b81 6960416c 9ffe88b8<br> \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD005\"/>SPD005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>RCLK on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 0<br>   \nRCLK - adaptive<br>\nRCLK timeout<br>\nRCLK timeout<br>\nRCLK timeout\n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG001\"/>DBG001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Load is working</td>\n\t\t<td>Reset init is working, RAM is accesible, GDB server is started</td>\n\t\t<td>On the console of the OS: <br>\n\t\t\t<code>arm-elf-gdb test_ram.elf</code><br>\n\t\t\t<code>(gdb) target remote ip:port</code><br>\n\t\t\t<code>(gdb) load</load>\n\t\t</td>\n\t\t<td>Load should return without error, typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tLoading section .text, size 0x14c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 332<br>\n\t\t\t\tTransfer rate: 180 bytes/sec, 332 bytes/write.<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n(gdb) load<br>\nLoading section .text, size 0x1cc lma 0x20000000<br>\nLoading section .vectors, size 0x40 lma 0x200001cc<br>\nLoading section .rodata, size 0x4 lma 0x2000020c<br>\nStart address 0x20000000, load size 528<br>\nTransfer rate: 64 KB/sec, 176 bytes/write.<br>\n(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\n\t<tr>\n\t\t<td><a name=\"DBG002\"/>DBG002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software breakpoint</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001</td>\n\t\t<td>In the GDB console:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override soft<br>\n\t\t\t\tforce soft breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0xec: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The software breakpoint should be reached, a typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n(gdb) monitor gdb_breakpoint_override soft<br>\nforce soft breakpoints<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently asm\".<br>\n(gdb) break main<br>\nBreakpoint 1 at 0x20000170: file src/main.c, line 69.<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG003\"/>DBG003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in a RAM application</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>(gdb) step</code></td>\n\t\t<td>The next instruction should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f0<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f4<br>\n\t\t\t\t72        DWORD b = 2;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t\t(gdb)\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG004\"/>DBG004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software break points are working after a reset</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\t(gdb) load<br>\n\t\t\t(gdb) continue<br>\n\t\t\t</code></td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n((gdb) monitor reset init<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x60000013 pc: 0x200001bc<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz<br>\n(gdb) load<br>\nLoading section .text, size 0x1cc lma 0x20000000<br>\nLoading section .vectors, size 0x40 lma 0x200001cc<br>\nLoading section .rodata, size 0x4 lma 0x2000020c<br>\nStart address 0x20000000, load size 528<br>\nTransfer rate: 64 KB/sec, 176 bytes/write.<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\n(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG005\"/>DBG005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint</td>\n\t\t<td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset init<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override hard<br>\n\t\t\t\tforce hard breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n(gdb) monitor gdb_breakpoint_override hard<br>\nforce hard breakpoints<br>\n(gdb) break main<br>\nBreakpoint 1 at 0x40000170: file src/main.c, line 69.<br>\n(gdb) c<br>\nContinuing.<br>\nNote: automatically using hardware breakpoints for read-only addresses.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG006\"/>DBG006</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint is set after a reset</td>\n\t\t<td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n\t\t<td>In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\t\tpc (/32): 0x00100000<br>\n\t\t\t\t(gdb) continue\n\t\t\t</code><br>\n\t\t\twhere the value inserted in PC is the start address of the application\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n(gdb) monitor reset init<br>\njtag_speed 6400 => JTAG clk=0.010000<br>\n10 kHz<br>\nJTAG tap: str710.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)<br>\nsrst pulls trst - can not reset into halted mode. Issuing halt after reset.<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Undefined instruction<br>\ncpsr: 0x400000db pc: 0x010aea80<br>\njtag_speed 10 => JTAG clk=6.400000<br>\n6400 kHz<br>\n(gdb) monitor reg pc 0x40000000<br>\npc (/32): 0x40000000<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb)\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG007\"/>DBG007</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in ROM</td>\n\t\t<td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t\t(gdb) step\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\nBreakpoint 2, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) step<br>\n70\t  DWORD b = 2;<br>\n(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM001\"/>RAM001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>32 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mww ram_address 0xdeadbeef 16<br>\n\t\t\t\t\t> mdw ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mww 0x0 0xdeadbeef 16<br>\n\t\t\t\t> mdw 0x0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n\t\t\t\t0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mww 0x20000000 0xdeadbeef 16<br>\n> mdw 0x20000000 32<br>\n0x20000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x20000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x20000040: e3a0020a e3a01073 e5801018 e5901008 e3110002 0afffffc e3a0020a e59f10d0<br> \n0x20000060: e5801008 e321f0db e59fd0c8 e321f0d7 e59fd0c4 e321f0d1 e59fd0c0 e321f0d2<br> \n> \n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM002\"/>RAM002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwh ram_address 0xbeef 16<br>\n\t\t\t\t\t> mdh ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mwh 0x0 0xbeef 16<br>\n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t\t0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mwh 0x20000000 0xbeef 16<br>\n> mdh 0x20000000 32<br>       \n0x20000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br> \n0x20000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead<br> \n> \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM003\"/>RAM003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwb ram_address 0xab 16<br>\n\t\t\t\t\t> mdb ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n\t\t\t<code>\n\t\t\t\t> mwb ram_address 0xab 16<br>\n\t\t\t\t> mdb ram_address 32<br>\n\t\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mwb 0x20000000 0xab 16<br>  \n> mdb 0x20000000 32<br>     \n0x20000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be<br> \n> \n \t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA001\"/>FLA001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash probe</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface:<br>\n\t\t\t<code>\t> flash probe 0</code>\n\t\t</td>\n\t\t<td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n\t\t\t<code>flash 'ecosflash' found at 0x01000000</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t> flash probe 0<br>\n\t\t\tflash 'str7x' found at 0x40000000<br>\n\t\t\t> \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA002\"/>FLA002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>flash fillw</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> flash fillw 0x1000000 0xdeadbeef 16\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. The output looks like:<br>\n\t\t\t<code>\n\t\t\t\twrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s)\n\t\t\t</code><br>\n\t\t\tTo verify the contents of the flash:<br>\n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t\t> flash fillw 0x40000000 0xdeadbeef 16<br>\n\t\t\t\twrote 64 bytes to 0x40000000 in 0.000000s (inf kb/s)<br>\n\t\t\t\t> mdw 0x40000000 32<br>\n\t\t\t\t0x40000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n\t\t\t\t0x40000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n\t\t\t\t0x40000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t0x40000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n\t\t\t\t> \n\t\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA003\"/>FLA003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x1000000 0x2000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x01000000 length 8192 in 4.970000s\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff. \n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> flash erase_address 0x40000000 0x2000<br>\nerased address 0x40000000 (length 8192) in 0.270000s (29.630 kb/s)<br>\n> mdw 0x40000000 32                    <br>\n0x40000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x40000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x40000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x40000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA004\"/>FLA004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Loading to flash from GDB</td>\n\t\t<td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n\t\t<td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n\t\t\t\t<code>\n\t\t\t\t\t(gdb) target remote ip:port<br>\n\t\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t\t(gdb) load<br>\n\t\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.\n\t\t\t\t\t(gdb) monitor verify_image path_to_elf_file\t\t\n\t\t\t\t</code>\n\t\t</td>\n\t\t<td>The output should look like:<br>\n\t\t\t<code>\n\t\t\t\tverified 404 bytes in 5.060000s\n\t\t\t</code><br>\n\t\t\tThe failure message is something like:<br>\n\t\t\t<code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n(gdb) load<br>\nLoading section .text, size 0x1cc lma 0x40000000<br>\nLoading section .vectors, size 0x40 lma 0x400001cc<br>\nLoading section .rodata, size 0x4 lma 0x4000020c<br>\nStart address 0x40000000, load size 528<br>\nTransfer rate: 53 bytes/sec, 176 bytes/write.<br>\n(gdb) monitor verify_image /tftp/10.0.0.194/test_rom.elf<br>\nverified 528 bytes in 4.760000s (0.108 kb/s)<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently asm\".<br>\n(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\t\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/results/v0.4.0-rc1/STR912.html",
    "content": "<html>\n<head>\n<title>Test results for version 1.62</title>\n</head>\n\n<body>\n\n<H1>STR912</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON001\"/>CON001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Telnet connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On console, type<br><code>telnet ip port</code></td>\n\t\t<td><code>Open On-Chip Debugger<br>></code></td>\n\t\t<td><code>> telnet 10.0.0.142<br>\n\t\t\t\t\tTrying 10.0.0.142...<br>\n\t\t\t\t\tConnected to 10.0.0.142.<br>\n\t\t\t\t\tEscape character is '^]'.<br>\n\t\t\t\t\tOpen On-Chip Debugger<br>\n\t\t\t\t\t>\n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"CON002\"/>CON002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>GDB server connection</td>\n\t\t<td>Power on, jtag target attached</td>\n\t\t<td>On GDB console, type<br><code>target remote ip:port</code></td>\n\t\t<td><code>Remote debugging using 10.0.0.73:3333</code></td>\n\t\t<td><code>\n\t\t\t(gdb) tar remo 10.0.0.142:3333<br>\n\t\t\tRemote debugging using 10.0.0.142:3333<br>\n\t\t\t0x00016434 in ?? ()<br>\n\t\t\t(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES001\"/>RES001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n> reset halt<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES002\"/>RES002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset init on a blank target</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset init</code></td>\n\t\t<td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n\t\t<td>\n\t\t\t<code>\n> reset init<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\ncleared protection for sectors 0 through 7 on flash bank 0<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES003\"/>RES003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset after a power cycle of the target</td>\n\t\t<td>Reset the target then power cycle the target</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n      nsed nSRST asserted.<br>\n  nsed power dropout.<br>\n  nsed power restore.<br>\nRCLK - adaptive<br>\nSRST took 85ms to deassert<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\ncleared protection for sectors 0 through 7 on flash bank 0<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n> reset halt<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES004\"/>RES004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target where reset halt is supported</td>\n\t\t<td>Erase all the content of the flash</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n\t\t<td>\n\t\t\t<code>\n> reset halt<br>\n RCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (Manufacturer: 0x020, Part: 0x4570, Version: 0x0)<br>\nJTAG Tap/device matched<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (Manufacturer: 0x020, Part: 0x5966, Version: 0x2)<br>\nJTAG Tap/device matched<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (Manufacturer: 0x020, Part: 0x457f, Version: 0x2)<br>\nJTAG Tap/device matched<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\n>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RES005\"/>RES005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Reset halt on a blank target using return clock</td>\n\t\t<td>Erase all the content of the flash, set the configuration script to use RCLK</td>\n\t\t<td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n\t\t<td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t> reset halt<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD001\"/>SPD001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 16000<br>\njtag_speed 4 => JTAG clk=16.000000<br>\n16000 kHz<br>\nThumbEE -- incomplete support<br>\ntarget state: halted<br>\ntarget halted in ThumbEE state due to debug-request, current mode: System<br>\ncpsr: 0xfdfdffff pc: 0xfdfdfff9<br>\n> mdw 0 32      <br>\n0x00000000: 00000000 00000000 ffffffff ffffffff 00000001 ffffffff 00000001 ffffffff<br> \n0x00000020: 00000001 00000001 00000001 00000001 00000001 fffffffe fffffffe 00000001<br> \n0x00000040: fffffffe 00000000 00000000 00000000 00000000 00000000 00000000 00000000<br> \n0x00000060: 00000000 00000000 00000000 00000000 ffffffff ffffffff 00000001 00000000<br> \ninvalid mode value encountered 0<br>\ncpsr contains invalid mode value - communication failure<br>\nThumbEE -- incomplete support<br>\ntarget state: halted<br>\ntarget halted in ThumbEE state due to debug-request, current mode: System<br>\ncpsr: 0xffffffff pc: 0xfffffff8<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD002\"/>SPD002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 8000<br>\njtag_speed 8 => JTAG clk=8.000000<br>\n8000 kHz<br>\n> halt      <br>   \ninvalid mode value encountered 0<br>\ncpsr contains invalid mode value - communication failure<br>\nCommand handler execution failed<br>\nin procedure 'halt' called at file \"command.c\", line 647<br>\ncalled at file \"command.c\", line 361<br>\nHalt timed out, wake up GDB.<br>\n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td><font color=red><b>FAIL</b></font></td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD003\"/>SPD003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>4MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 4000<br>\njtag_speed 16 => JTAG clk=4.000000<br>\n4000 kHz<br>\n> halt      <br>   \n> mdw 0 32     <br>\n0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD004\"/>SPD004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>2MHz on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 2000<br>\njtag_speed 32 => JTAG clk=2.000000<br>\n2000 kHz<br>\n> halt<br>\n> mdw 0 32<br>     \n0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"SPD005\"/>SPD005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>RCLK on normal operation</td>\n\t\t<td>Reset init the target according to RES002 </td>\n\t\t<td>Change speed and exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n\t\t<td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n\t\t<td>\n\t\t\t<code>\n> jtag_khz 0<br>   \nRCLK - adaptive<br>\n> halt      <br>\n> mdw 0 32  <br>\n0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG001\"/>DBG001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Load is working</td>\n\t\t<td>Reset init is working, RAM is accesible, GDB server is started</td>\n\t\t<td>On the console of the OS: <br>\n\t\t\t<code>arm-elf-gdb test_ram.elf</code><br>\n\t\t\t<code>(gdb) target remote ip:port</code><br>\n\t\t\t<code>(gdb) load</load>\n\t\t</td>\n\t\t<td>Load should return without error, typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\tLoading section .text, size 0x14c lma 0x0<br>\n\t\t\t\tStart address 0x40, load size 332<br>\n\t\t\t\tTransfer rate: 180 bytes/sec, 332 bytes/write.<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n(gdb) load<br>\nLoading section .text, size 0x1a0 lma 0x4000000<br>\nLoading section .rodata, size 0x4 lma 0x40001a0<br>\nStart address 0x4000000, load size 420<br>\nTransfer rate: 29 KB/sec, 210 bytes/write.<br>\n(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\n\t<tr>\n\t\t<td><a name=\"DBG002\"/>DBG002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software breakpoint</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001</td>\n\t\t<td>In the GDB console:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override soft<br>\n\t\t\t\tforce soft breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0xec: file src/main.c, line 71.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The software breakpoint should be reached, a typical output looks like:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n(gdb) monitor gdb_breakpoint_override soft<br>\nforce soft breakpoints<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently asm\".<br>\n(gdb) break main<br>\nBreakpoint 1 at 0x4000144: file src/main.c, line 69.<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\nwarning: Source file is more recent than executable.<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG003\"/>DBG003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in a RAM application</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>(gdb) step</code></td>\n\t\t<td>The next instruction should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f0<br>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Abort<br>\n\t\t\t\tcpsr: 0x20000097 pc: 0x000000f4<br>\n\t\t\t\t72        DWORD b = 2;\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n\t\t\t\t(gdb) step<br>\n\t\t\t\t70\t  DWORD b = 2;<br>\n\t\t\t\t(gdb)<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG004\"/>DBG004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Software break points are working after a reset</td>\n\t\t<td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n\t\t<td>In GDB, type <br><code>\n\t\t\t(gdb) monitor reset init<br>\n\t\t\t(gdb) load<br>\n\t\t\t(gdb) continue<br>\n\t\t\t</code></td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to breakpoint, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x000000d3 pc: 0x000000ec<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:71<br>\n\t\t\t\t71        DWORD a = 1;\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n(gdb) monitor reset init<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\ncleared protection for sectors 0 through 7 on flash bank 0<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n(gdb) load<br>\nLoading section .text, size 0x1a0 lma 0x4000000<br>\nLoading section .rodata, size 0x4 lma 0x40001a0<br>\nStart address 0x4000000, load size 420<br>\nTransfer rate: 25 KB/sec, 210 bytes/write.<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\n(gdb)\n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG005\"/>DBG005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint</td>\n\t\t<td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset init<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor gdb_breakpoint_override hard<br>\n\t\t\t\tforce hard breakpoints<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n(gdb) monitor reset init<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\ncleared protection for sectors 0 through 7 on flash bank 0<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n(gdb) load<br>\nLoading section .text, size 0x1a0 lma 0x0<br>\nLoading section .rodata, size 0x4 lma 0x1a0<br>\nStart address 0x0, load size 420<br>\nTransfer rate: 426 bytes/sec, 210 bytes/write.<br>\n(gdb) monitor gdb_breakpoint_override hard<br>\nforce hard breakpoints<br>\n(gdb) break main<br>\nBreakpoint 1 at 0x144: file src/main.c, line 69.<br>\n(gdb) continue<br>\nContinuing.<br>\nNote: automatically using hardware breakpoints for read-only addresses.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\nwarning: Source file is more recent than executable.<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG006\"/>DBG006</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Hardware breakpoint is set after a reset</td>\n\t\t<td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n\t\t<td>In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) monitor reg pc 0x100000<br>\n\t\t\t\tpc (/32): 0x00100000<br>\n\t\t\t\t(gdb) continue\n\t\t\t</code><br>\n\t\t\twhere the value inserted in PC is the start address of the application\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n(gdb) monitor reset init<br>\nRCLK - adaptive<br>\nSRST took 2ms to deassert<br>\nJTAG tap: str912.flash tap/device found: 0x04570041 (mfg: 0x020, part: 0x4570, ver: 0x0)<br>\nJTAG tap: str912.cpu tap/device found: 0x25966041 (mfg: 0x020, part: 0x5966, ver: 0x2)<br>\nJTAG tap: str912.bs tap/device found: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs       UNEXPECTED: 0x2457f041 (mfg: 0x020, part: 0x457f, ver: 0x2)<br>\nJTAG tap: str912.bs  expected 1 of 1: 0x1457f041 (mfg: 0x020, part: 0x457f, ver: 0x1)<br>\nTrying to use configured scan chain anyway...<br>\nBypassing JTAG setup events due to errors<br>\nSRST took 2ms to deassert<br>\ntarget state: halted<br>\ntarget halted in ARM state due to debug-request, current mode: Supervisor<br>\ncpsr: 0x000000d3 pc: 0x00000000<br>\ncleared protection for sectors 0 through 7 on flash bank 0<br>\nNOTE! DCC downloads have not been enabled, defaulting to slow memory writes. Type 'help dcc'.<br>\n(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 1, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\n(gdb)\n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"DBG007\"/>DBG007</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Single step in ROM</td>\n\t\t<td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n\t\t<td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n\t\t\t<code>\n\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t(gdb) load<br>\n\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.<br>\n\t\t\t\t(gdb) monitor arm7_9  force_hw_bkpts enable<br>\n\t\t\t\tforce hardware breakpoints enabled<br>\n\t\t\t\t(gdb) break main<br>\n\t\t\t\tBreakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n\t\t\t\t(gdb) continue<br>\n\t\t\t\tContinuing.<br>\n\t\t\t\t<br>\n\t\t\t\tBreakpoint 1, main () at src/main.c:69<br>\n\t\t\t\t69        DWORD a = 1;<br>\n\t\t\t\t(gdb) step\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The breakpoint should be reached, typical output:<br>\n\t\t\t<code>\n\t\t\t\ttarget state: halted<br>\n\t\t\t\ttarget halted in ARM state due to single step, current mode: Supervisor<br>\n\t\t\t\tcpsr: 0x60000013 pc: 0x0010013c<br>\n\t\t\t\t70        DWORD b = 2;<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n\t\t\t(gdb) c<br>\nContinuing.<br>\n<br>\nBreakpoint 2, main () at src/main.c:69<br>\n69\t  DWORD a = 1;<br>\nCurrent language:  auto<br>\nThe current source language is \"auto; currently c\".<br>\n(gdb) step<br>\n70\t  DWORD b = 2;<br>\n(gdb) \n\t\t</code></td>\n\t\t<td>PASS</td>\n\t</tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM001\"/>RAM001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>32 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mww ram_address 0xdeadbeef 16<br>\n\t\t\t\t\t> mdw ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mww 0x0 0xdeadbeef 16<br>\n\t\t\t\t> mdw 0x0 32<br>\n\t\t\t\t0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n\t\t\t\t0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mww 0x4000000 0xdeadbeef 16<br>\n> mdw 0x4000000 32            <br>\n0x04000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x04000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x04000040: e580100c e3a01802 e5801010 e3a01018 e5801018 e59f00a8 e59f10a8 e5801000<br> \n0x04000060: e3a00806 ee2f0f11 e321f0d7 e59fd098 e321f0db e59fd094 e321f0d3 e59fd090<br> \n> \n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM002\"/>RAM002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>16 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwh ram_address 0xbeef 16<br>\n\t\t\t\t\t> mdh ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n\t\t\t<code>\n\t\t\t\t> mwh 0x0 0xbeef 16<br>\n\t\t\t\t> mdh 0x0 32<br>\n\t\t\t\t0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n\t\t\t\t0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mwh 0x4000000 0xbeef 16<br>    \n> mdh 0x4000000 32<br>           \n0x04000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br> \n0x04000020: beef dead beef dead beef dead beef dead beef dead beef dead beef dead beef dead<br> \n> \n\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"RAM003\"/>RAM003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>8 bit Write/read RAM</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> mwb ram_address 0xab 16<br>\n\t\t\t\t\t> mdb ram_address 32\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n\t\t\t<code>\n\t\t\t\t> mwb ram_address 0xab 16<br>\n\t\t\t\t> mdb ram_address 32<br>\n\t\t\t\t0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n\t\t\t\t>\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> mwb 0x4000000 0xab 16<br>  \n> mdb 0x4000000 32<br>     \n0x04000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ef be ef be ef be ef be ef be ef be ef be ef be<br> \n> \n \t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n\t<tr>\n\t\t<td>ID</td>\n\t\t<td>Target</td>\n\t\t<td>Interface</td>\n\t\t<td>Description</td>\n\t\t<td>Initial state</td>\n\t\t<td>Input</td>\n\t\t<td>Expected output</td>\n\t\t<td>Actual output</td>\n\t\t<td>Pass/Fail</td>\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA001\"/>FLA001</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash probe</td>\n\t\t<td>Reset init is working</td>\n\t\t<td>On the telnet interface:<br>\n\t\t\t<code>\t> flash probe 0</code>\n\t\t</td>\n\t\t<td>The command should execute without error. The output should state the name of the flash and the starting address. An example of output:<br>\n\t\t\t<code>flash 'ecosflash' found at 0x01000000</code>\n\t\t</td>\n\t\t<td>\n\t\t<code>\n\t\t\t> flash probe 0<br>\n\t\t\tflash 'str9x' found at 0x00000000<br>\n\t\t\t> \n\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA002\"/>FLA002</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>flash fillw</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t> flash fillw 0x1000000 0xdeadbeef 16\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error. The output looks like:<br>\n\t\t\t<code>\n\t\t\t\twrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s)\n\t\t\t</code><br>\n\t\t\tTo verify the contents of the flash:<br>\n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> flash fillw 0x0 0xdeadbeef 16 <br>    \nwrote 64 bytes to 0x00000000 in 0.020000s (3.125 kb/s)<br>\n> mdw 0 32<br>\n0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br> \n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n\t\t\t</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA003\"/>FLA003</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x1000000 0x20000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x01000000 length 131072 in 4.970000s<br>\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff.<br> \n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> flash erase_address 0 0x20000<br>\nerased address 0x00000000 (length 131072) in 1.970000s (64.975 kb/s)<br>\n> mdw 0 32<br>\n0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br> \n> \n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t\t<tr>\n\t\t<td><a name=\"FLA004\"/>FLA004</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Entire flash erase</td>\n\t\t<td>Reset init is working, flash is probed</td>\n\t\t<td>On the telnet interface<br>\n\t\t\t<code>\t>  flash erase_address 0x0 0x80000\n\t\t\t</code>\n\t\t</td>\n\t\t<td>The commands should execute without error.<br>\n\t\t\t<code>\n\t\t\t\terased address 0x01000000 length 8192 in 4.970000s<br>\n\t\t\t</code>\n\t\t\tTo check that the flash has been erased, read at different addresses. The result should always be 0xff.<br> \n\t\t\t<code>\n\t\t\t\t> mdw 0x1000000 32<br>\n\t\t\t\t0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n\t\t\t\t0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t\t\t</code>\n\t\t</td>\n\t\t<td><code>\n> flash erase_address 0 0x80000<br>\n erased address 0x00000000 length 524288 in 1.020000s<br>\n<br>\n> mdw 0 32<br>\n 0x00000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n0x00000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n0x00000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n0x00000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n</code></td>\n\t\t<td>PASS</td>\t\n\t</tr>\n\t<tr>\n\t\t<td><a name=\"FLA005\"/>FLA005</td>\n\t\t<td>STR912</td>\n\t\t<td>ZY1000</td>\n\t\t<td>Loading to flash from GDB</td>\n\t\t<td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n\t\t<td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n\t\t\t\t<code>\n\t\t\t\t\t(gdb) target remote ip:port<br>\n\t\t\t\t\t(gdb) monitor reset<br>\n\t\t\t\t\t(gdb) load<br>\n\t\t\t\t\tLoading section .text, size 0x194 lma 0x100000<br>\n\t\t\t\t\tStart address 0x100040, load size 404<br>\n\t\t\t\t\tTransfer rate: 179 bytes/sec, 404 bytes/write.\n\t\t\t\t\t(gdb) monitor verify_image path_to_elf_file\t\t\n\t\t\t\t</code>\n\t\t</td>\n\t\t<td>The output should look like:<br>\n\t\t\t<code>\n\t\t\t\tverified 404 bytes in 5.060000s\n\t\t\t</code><br>\n\t\t\tThe failure message is something like:<br>\n\t\t\t<code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n\t\t</td>\n\t\t<td>\n\t\t\t<code>\n(gdb) load<br>\nLoading section .text, size 0x1a0 lma 0x0<br>\nLoading section .rodata, size 0x4 lma 0x1a0<br>\nStart address 0x0, load size 420<br>\nTransfer rate: 425 bytes/sec, 210 bytes/write.<br>\n(gdb) moni verify_image /tftp/10.0.0.194/test_rom.elf<br>\nverified 420 bytes in 0.350000s (1.172 kb/s)<br>\n(gdb) \n\t\t\t</code>\n\t\t</td>\n\t\t<td>PASS</td>\t\n\t</tr>\t\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/smoketests.html",
    "content": "<html>\n\n\t<meta http-equiv=\"content-type\" content=\"text/html;charset=iso-8859-1\">\n\n\t<body>\n\t\t<h1>OpenOCD smoketest results</h1>\n\t\tThese tests can be performed on any JTAG device as long as they are\n\t\texecuted using the unmodified code from git.\n\t\t<p>The latest version in which the test is known to have passed is in the table below.</p>\n\t\t<h2>Vocabulary</h2>\n\t\t<table border=\"1\">\n\t\t\t<tr>\n\t\t\t\t<td width=\"100\">Passed version</td>\n\t\t\t\t<td>The latest branch and version on which the test is known to pass</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"100\">Broken version</td>\n\t\t\t\t<td>The latest branch and version on which the test is known to fail. n/a when older than passed version.</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"100\">ID</td>\n\t\t\t\t<td>A unqiue ID to refer to a test. The unique numbers are maintained in this file. Note that the same test can be run on different hardware/interface. Each combination yields a unique id. </td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<p></p>\n\t\t<table border=\"1\">\n\t\t\t<tr>\n\t\t\t\t<th width=\"100\">Unique ID</th>\n\t\t\t\t<th width=\"165\">Synopsis</th>\n\t\t\t\t<th align=\"center\" width=\"110\">JTAG device</th>\n\t\t\t\t<th align=\"center\" width=\"110\">Passed version</th>\n\t\t\t\t<th align=\"center\" width=\"110\">Broken version</th>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >fill_malloc</td>\n\t\t\t\t<td width=\"165\">Fill malloc() memory with garbage</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >ocd1</td>\n\t\t\t\t<td width=\"165\">Telnet Windows</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >ocd2</td>\n\t\t\t\t<td width=\"165\">Telnet Linux</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >ocd3</td>\n\t\t\t\t<td width=\"165\">Telnet Cygwin</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#test_ocd4\">ocd4</a></td>\n\t\t\t\t<td width=\"165\">ARM7 debugging</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >SAM9260</td>\n\t\t\t\t<td width=\"165\">SAM9260 debugging</td>\n\t\t\t\t<td align=\"center\">ft2232 </td>\n\t\t\t\t<td align=\"center\">500</td>\n\t\t\t\t<td align=\"center\">n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >xscale1</td>\n\t\t\t\t<td width=\"165\">XScale debugging</td>\n\t\t\t\t<td align=\"center\" >bitbang</td>\n\t\t\t\t<td align=\"center\" >505</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td >xscale2</td>\n\t\t\t\t<td width=\"165\">XScale debugging</td>\n\t\t\t\t<td align=\"center\" >FT2232</td>\n\t\t\t\t<td align=\"center\" >202</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram1</a></td>\n\t\t\t\t<td width=\"165\">str710 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom2</a></td>\n\t\t\t\t<td width=\"165\">str710 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram3</a></td>\n\t\t\t\t<td width=\"165\">str912 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom4</a></td>\n\t\t\t\t<td width=\"165\">str912 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram5</a></td>\n\t\t\t\t<td width=\"165\">lpc2148 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom6</a></td>\n\t\t\t\t<td width=\"165\">lpc2148 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram7</a></td>\n\t\t\t\t<td width=\"165\">lpc2294 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom8</a></td>\n\t\t\t\t<td width=\"165\">lpc2294 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram9</a></td>\n\t\t\t\t<td width=\"165\">sam7s256 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom10</a></td>\n\t\t\t\t<td width=\"165\">sam7s256 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram11</a></td>\n\t\t\t\t<td width=\"165\">sam7x256 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-rom\">bdte-rom12</a></td>\n\t\t\t\t<td width=\"165\">sam7x256 rom debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td ><a href=\"#bdte-ram\">bdte-ram13</a></td>\n\t\t\t\t<td width=\"165\">at91r40008 ram debugging</td>\n\t\t\t\t<td align=\"center\" >JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<p></p>\n\t\t<hr>\n\t\t<h1>OpenOCD JTAG device test results</h1>\n\t\tEach JTAG device must be tested\n\n\t\t<table border=\"1\">\n\t\t\t<tr>\n\t\t\t\t<th align=\"center\" width=\"40\">ID</th>\n\t\t\t\t<th width=\"90\">Synopsis</th>\n\t\t\t\t<th >Passed version</th>\n\t\t\t\t<th >Broken version</th>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"40\">jtag1</td>\n\t\t\t\t<td width=\"90\">Parport</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"40\">jtag2</td>\n\t\t\t\t<td width=\"90\">JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"40\">jtag3</td>\n\t\t\t\t<td width=\"90\">Turtelizer2</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"40\">jtag4</td>\n\t\t\t\t<td width=\"90\">JTAGkey</td>\n\t\t\t\t<td align=\"center\" >657</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"40\">jtag5</td>\n\t\t\t\t<td width=\"90\">add new one</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t\t<td align=\"center\" >n/a</td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<p>jtag1:</p>\n\t\t<p>jtag2: Tested on Windows XP Prof. (SP2) with original FTDI&nbsp;driver.</p>\n\t\t<p>jtag3: Tested on Windows XP Prof. (SP2) with original FTDI&nbsp;driver.</p>\n\t\t<p>jtag4: Tested on Mac OS X (10.5.2, Intel) with libftdi-0.10 and libusb-0.1.12</p>\n\t\t<p>jtag5:</p>\n\t\t<hr>\n\t\t<h1>OpenOCD JTAG device speed test result</h1>\n\t\t<p>The test result is in KB/sec.</p>\n\t\t<table border=\"1\">\n\t\t\t<tr>\n\t\t\t\t<th align=\"center\" width=\"50\">ID</th>\n\t\t\t\t<th width=\"90\">Synopsis</th>\n\t\t\t\t<th width=\"40\">r320</th>\n\t\t\t\t<th width=\"40\">r420</th>\n\t\t\t\t<th width=\"40\">r423</th>\n\t\t\t\t<th width=\"40\">r459</th>\n\t\t\t\t<th width=\"40\">r517</th>\n\t\t\t\t<th width=\"40\">r536</th>\n\t\t\t\t<th width=\"40\">r651</th>\n\t\t\t\t<th width=\"40\">r657</th>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"50\"><a href=\"#speed1\">speed1</a></td>\n\t\t\t\t<td width=\"90\">JTAGkey</td>\n\t\t\t\t<td align=\"center\" width=\"40\">93</td>\n\t\t\t\t<td align=\"center\" width=\"40\">64 </td>\n\t\t\t\t<td align=\"center\" width=\"40\">93</td>\n\t\t\t\t<td align=\"center\" width=\"40\">93</td>\n\t\t\t\t<td align=\"center\" width=\"40\">93</td>\n\t\t\t\t<td align=\"center\" width=\"40\">93</td>\n\t\t\t\t<td align=\"center\" width=\"40\">162</td>\n\t\t\t\t<td align=\"center\" width=\"40\">165</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"50\"><a href=\"#speed2\">speed2</a></td>\n\t\t\t\t<td width=\"90\">JTAGkey</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">52</td>\n\t\t\t\t<td align=\"center\" width=\"40\">52</td>\n\t\t\t\t<td align=\"center\" width=\"40\">110</td>\n\t\t\t\t<td align=\"center\" width=\"40\">111</td>\n\t\t\t</tr>\n\t\t\t<tr>\n\t\t\t\t<td width=\"50\">speed3</td>\n\t\t\t\t<td width=\"90\">add new one</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t\t<td align=\"center\" width=\"40\">n/a</td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<p></p>\n\t\t<hr>\n\t\t<h1>Policy on removing features from OpenOCD</h1>\n\t\tIf a feature in OpenOCD is known to be broken and nobody has submitted\n\t\ta fix and the feature is causing trouble for maintainence, it can be\n\t\tremoved from OpenOCD mainline. The threshold for temporarily removing\n\t\tsomething from OpenOCD mainline is low to ease maintainence and place the burden of maintainence on those that care about a feature.\n\t\t<p>Note that code is never deleted from OpenOCD git, it remains in the\n\t\trepository so if somebody sees a feature removed that they would like\n\t\tkept, they have but to port and fix that feature back up to main\n\t\tmainline. This document can be helpful in this regard in that the latest working version and the known broken version may be listed.</p>\n\t\t<h1>Policy on adding features from OpenOCD</h1>\n\t\tTo add a feature to OpenOCD, generally it should not break any\n\t\texisting features and it should be functional and the code reasonably\n\t\treadable and useful to others in the OpenOCD community. The code does\n\t\tnot have to be completed. Work in progress is fine for OpenOCD\n\t\tmainline.\n\t\t<p>Also new tests should be defined. Note that the code does not have to pass all the tests. In fact it can be helpful to have tests to describe facets that really should be working, but aren't done yet. </p>\n\t\t<hr>\n\t\t<h1>ocd4 - ARM7 debugging<a name=\"test_ocd4\"></a></h1>\n\t\tConnect to ARM7 device(any), use GDB load to load a program into RAM and single halt, resume and single step.\n\t\t<hr>\n\t\t<h1>bdte-ram (Basic debugging test with Eclipse in RAM)<a id=\"bdte-ram\" name=\"bdte-ram\"></a></h1>\n\t\t<p>This test was made under Eclipse with the Zylin Embedded CDT&nbsp;plugin. For the GDB &quot;Initialize commands&quot; take a look in the examples/&lt;target&gt;/prj/<b>eclipse_ram.gdb</b> file.</p>\n\t\t<p>Start debugging,  the debugger should stop at main. set some breakpoints and &quot;Resume&quot;. If the debugger hit a breakpoint check if the &quot;Variables&quot; looks correct. Remove some breakpoints and &quot;Resume&quot; again. If the target is running, use the &quot;Suspend&quot; function and use &quot;Step Into&quot; or &quot;Step Over&quot; through the source. Even open the &quot;Disassembly&quot; view and enable the &quot;Instruction Stepping Mode&quot;. Now you can single step through the assembler source. Use &quot;Resume&quot; again to run the program, set a breakpoint while the target is running. Check if  you can inspect the variables with the mouse over. Play a little with the target...</p>\n\t\t<hr>\n\t\t<h1>bdte-rom (Basic debugging test with Eclipse in ROM)<a id=\"bdte-rom\" name=\"bdte-rom\"></a></h1>\n\t\t<p>This test was made under Eclipse with the Zylin Embedded CDT&nbsp;plugin. For the GDB &quot;Initialize commands&quot; take a look in the examples/&lt;target&gt;/prj/<b>eclipse_rom.gdb</b> file.</p>\n\t\t<p>Start debugging, the debugger should download and store the program in the flash of the target.</p>\n\t\t<p>Now you can make some tests like described in the <a href=\"#bdte-ram\">bdte-ram</a> section above too.</p>\n\t\t<hr>\n\t\t<h1>speed1 - Download speed test<a id=\"speed1\" name=\"speed1\"></a></h1>\n\t\t<p>For this test a STR710 with external memory was used. The example project can be found under examples/STR710JtagSpeed. Here Eclipse or the arm-elf-gdb can be used to download the test.elf file into the RAM. The result of the GDB&nbsp;can look like:</p>\n\t\t<p>Loading section .text, size 0x6019c lma 0x62000000<br>\n\t\t\tStart address 0x62000040, load size 393628<br>\n\t\t\tTransfer rate: 93 KB/sec, 2008 bytes/write.</p>\n\t\t<p>In this example a speed of 93 KB/sec was reached. The hardware which was used for the test can be found <a href=\"http://www.yagarto.de/projects/str7usbmsd/index.html\" target=\"new\">here</a>.</p>\n\t\t<p>The test was made on Windows XP Prof. (SP2) with a JTAGkey and the original FTDI driver.</p>\n\t\t<hr>\n\t\t<h1>speed2 - Download speed test<a id=\"speed2\" name=\"speed2\"></a></h1>\n\t\t<p>For this test a STR710 with external memory was used. The example project can be found under examples/STR710JtagSpeed. Here Eclipse or the arm-elf-gdb can be used to download the test.elf file into the RAM. The result of the GDB&nbsp;can look like:</p>\n\t\t<p>Loading section .text, size 0x6019c lma 0x62000000<br>\n\t\t\tStart address 0x62000040, load size 393628<br>Transfer rate: 52 KB/sec, 2008 bytes/write.</p>\n\t\t<p>In this example a speed of 52 KB/sec was reached. The hardware which was used for the test can be found <a href=\"http://www.yagarto.de/projects/str7usbmsd/index.html\" target=\"new\">here</a>.</p>\n\t\t<p>The test was made on Mac OS X (10.5.2, Intel)  with a JTAGkey and the following driver:</p>\n\t\t<p>- libftdi 0.10<br>\n\t\t\t- libusb 0.1.12</p>\n\t\t<p></p>\n\t\t<p></p>\n\t</body>\n\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/tcl_server.tcl",
    "content": "# Simple tcl client to connect to openocd\nputs \"Use empty line to exit\"\nset fo [socket 127.0.0.1 6666]\nputs -nonewline stdout \"> \"\nflush stdout\nwhile {[gets stdin line] >= 0} {\n    if {$line eq {}} break\n    puts $fo $line\n    flush $fo\n    gets $fo line\n    puts $line\n    puts -nonewline stdout \"> \"\n    flush stdout\n}\nclose $fo\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/tcl_test.tcl",
    "content": "if { $argc != 1 } {\n\tputs \"Usage: test_tcl.tcl <ipaddress>\"\n\texit 1\n}\n\nputs $argv\n\n# Simple tcl client to connect to openocd\nglobal fo\nset fo [socket $argv 6666]\n\n# If a fn is unknown to Tcl, send it off to OpenOCD\nproc unknown args {\t\n\tglobal fo\n\tputs $fo $args\n\tflush $fo\n\tgets $fo line\n\treturn $line\n}\n\n\n\n#Print help text for a command. Word wrap\n#help text that is too wide inside column.\nproc pc_help {args} {\n\tglobal ocd_helptext\n\tset cmd $args\n\tforeach a [lsort $ocd_helptext] {\n\t\tif {[string length $cmd]==0||[string first $cmd $a]!=-1||[string first $cmd [lindex $a 1]]!=-1} {\n\t\t\tset w 50\n\t\t\tset cmdname [lindex $a 0]\n\t\t\tset h [lindex $a 1]\n\t\t\tset n 0\n\t\t\twhile 1 {\n\t\t\t\tif {$n > [string length $h]} {break}\n\t\t\t\t\n\t\t\t\tset next_a [expr $n+$w]\n\t\t\t\tif {[string length $h]>$n+$w} {\n\t\t\t\t\tset xxxx [string range $h $n [expr $n+$w]]\n\t\t\t\t\tfor {set lastpos [expr [string length $xxxx]-1]} {$lastpos>=0&&[string compare [string range $xxxx $lastpos $lastpos] \" \"]!=0} {set lastpos [expr $lastpos-1]} {\n\t\t\t\t\t}\n\t\t\t\t\t#set next_a -1\n\t\t\t\t\tif {$lastpos!=-1} {\n\t\t\t\t\t\tset next_a [expr $lastpos+$n+1]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tputs [format \"%-25s %s\" $cmdname [string range $h $n [expr $next_a-1]] ]\n\t\t\t\tset cmdname \"\"\n\t\t\t\tset n [expr $next_a]\n\t\t\t}\n\t\t}\n\t}\n}\n\nputs \"Running flash_banks\"\nputs [flash_banks]\nputs \"Running help on PC using data from OpenOCD\"\nglobal ocd_helptext\nset ocd_helptext [get_help_text]\nputs [pc_help]\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/test-am335xgpio-deprecated-commands.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OpenOCD script to test that the deprecated \"am335xgpio *\" commands produce the\n# expected results. Run this command as:\n#\n# openocd -f <path>/test-linuxgpiod-deprecated-commands.cfg\n\n# Raise an error if the \"actual\" value does not match the \"expected\" value. Trim\n# whitespace (including newlines) from strings before comparing.\nproc expected_value {expected actual} {\n\tif {[string trim $expected] ne [string trim $actual]} {\n\t\terror [puts \"ERROR: '${actual}' != '${expected}'\"]\n\t}\n}\n\nadapter driver am335xgpio\n\nam335xgpio jtag_nums 1 2 3 4\nexpected_value \"adapter gpio tck (output): num 1, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\nexpected_value \"adapter gpio tms (output): num 2, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\nexpected_value \"adapter gpio tdi (output): num 3, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\nexpected_value \"adapter gpio tdo (input): num 4, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nam335xgpio tck_num 5\nexpected_value \"adapter gpio tck (output): num 5, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\n\nam335xgpio tms_num 6\nexpected_value \"adapter gpio tms (output): num 6, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\n\nam335xgpio tdi_num 7\nexpected_value \"adapter gpio tdi (output): num 7, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\n\nam335xgpio tdo_num 8\nexpected_value \"adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nam335xgpio swd_nums 9 10\nexpected_value \"adapter gpio swclk (output): num 9, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\nexpected_value \"adapter gpio swdio (bidirectional): num 10, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nam335xgpio swclk_num 11\nexpected_value \"adapter gpio swclk (output): num 11, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\n\nam335xgpio swdio_num 12\nexpected_value \"adapter gpio swdio (bidirectional): num 12, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nam335xgpio swdio_dir_num 13\nexpected_value \"adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none\" [eval adapter gpio swdio_dir]\n\nam335xgpio swdio_dir_output_state low\nexpected_value \"adapter gpio swdio_dir (output): num 13, chip 0, active-low, push-pull, pull-none\" [eval adapter gpio swdio_dir]\n\nam335xgpio swdio_dir_output_state high\nexpected_value \"adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none\" [eval adapter gpio swdio_dir]\n\nam335xgpio srst_num 14\nexpected_value \"adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio srst]\n\nam335xgpio trst_num 15\nexpected_value \"adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio trst]\n\nam335xgpio led_num 16\nexpected_value \"adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio led]\n\nam335xgpio led_on_state low\nexpected_value \"adapter gpio led (output): num 16, chip 0, active-low, push-pull, pull-none, init-state inactive\" [eval adapter gpio led]\n\nam335xgpio led_on_state high\nexpected_value \"adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio led]\n\nputs \"SUCCESS\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/test-bcm2835gpio-deprecated-commands.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OpenOCD script to test that the deprecated \"bcm2835gpio *\" and \"bcm2835gpio_*\"\n# commands produce the expected results. Run this command as:\n# openocd -f <path>/test-bcm2835gpio-deprecated-commands.cfg\n\n# Raise an error if the \"actual\" value does not match the \"expected\" value. Trim\n# whitespace (including newlines) from strings before comparing.\nproc expected_value {expected actual} {\n\tif {[string trim $expected] ne [string trim $actual]} {\n\t\terror [puts \"ERROR: '${actual}' != '${expected}'\"]\n\t}\n}\n\nset supported_signals {tdo tdi tms tck trst swdio swdio_dir swclk srst}\n\nadapter speed 100\nadapter driver bcm2835gpio\nputs \"Driver is '[adapter name]'\"\nexpected_value \"bcm2835gpio\" [adapter name]\necho [adapter gpio]\n\n#####################################\n# Test the \"bcm2835gpio *\" commands\n\n# Change the GPIO chip for all signals. Don't check directly here, do so when\n# each signal command is tested.\n# bcm2835gpio gpiochip 0\n\nbcm2835gpio jtag_nums 1 2 3 4\nexpected_value \"adapter gpio tck (output): num 1, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\nexpected_value \"adapter gpio tms (output): num 2, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\nexpected_value \"adapter gpio tdi (output): num 3, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\nexpected_value \"adapter gpio tdo (input): num 4, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nbcm2835gpio tck_num 5\nexpected_value \"adapter gpio tck (output): num 5, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\n\nbcm2835gpio tms_num 6\nexpected_value \"adapter gpio tms (output): num 6, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\n\nbcm2835gpio tdi_num 7\nexpected_value \"adapter gpio tdi (output): num 7, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\n\nbcm2835gpio tdo_num 8\nexpected_value \"adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nbcm2835gpio swd_nums 9 10\nexpected_value \"adapter gpio swclk (output): num 9, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\nexpected_value \"adapter gpio swdio (bidirectional): num 10, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nbcm2835gpio swclk_num 11\nexpected_value \"adapter gpio swclk (output): num 11, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\n\nbcm2835gpio swdio_num 12\nexpected_value \"adapter gpio swdio (bidirectional): num 12, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nbcm2835gpio swdio_dir_num 13\nexpected_value \"adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none\" [eval adapter gpio swdio_dir]\n\nbcm2835gpio srst_num 14\nexpected_value \"adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio srst]\n\nbcm2835gpio trst_num 15\nexpected_value \"adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio trst]\n\n\n#####################################\n# Test the old bcm2835gpio_* commands\n\n# Reset the GPIO chip for all signals. Don't check directly here, do so when\n# each signal command is tested.\nforeach sig_name $supported_signals {\n\teval adapter gpio $sig_name -chip -1\n}\n\nbcm2835gpio_jtag_nums 17 18 19 20\nexpected_value \"adapter gpio tck (output): num 17, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\nexpected_value \"adapter gpio tms (output): num 18, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\nexpected_value \"adapter gpio tdi (output): num 19, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\nexpected_value \"adapter gpio tdo (input): num 20, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nbcm2835gpio_tck_num 21\nexpected_value \"adapter gpio tck (output): num 21, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\n\nbcm2835gpio_tms_num 22\nexpected_value \"adapter gpio tms (output): num 22, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\n\nbcm2835gpio_tdi_num 23\nexpected_value \"adapter gpio tdi (output): num 23, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\n\nbcm2835gpio_tdo_num 24\nexpected_value \"adapter gpio tdo (input): num 24, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nbcm2835gpio_swd_nums 25 26\nexpected_value \"adapter gpio swclk (output): num 25, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\nexpected_value \"adapter gpio swdio (bidirectional): num 26, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nbcm2835gpio_swclk_num 27\nexpected_value \"adapter gpio swclk (output): num 27, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\n\nbcm2835gpio_swdio_num 28\nexpected_value \"adapter gpio swdio (bidirectional): num 28, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nputs \"SUCCESS\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/test-linuxgpiod-deprecated-commands.cfg",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# OpenOCD script to test that the deprecated \"linuxgpiod *\" and \"linuxgpiod_*\"\n# commands produce the expected results. Run this command as:\n# openocd -f <path>/test-linuxgpiod-deprecated-commands.cfg\n\n# Raise an error if the \"actual\" value does not match the \"expected\" value. Trim\n# whitespace (including newlines) from strings before comparing.\nproc expected_value {expected actual} {\n\tif {[string trim $expected] ne [string trim $actual]} {\n\t\terror [puts \"ERROR: '${actual}' != '${expected}'\"]\n\t}\n}\n\nadapter driver linuxgpiod\nputs \"Driver is '[adapter name]'\"\nexpected_value \"linuxgpiod\" [adapter name]\necho [adapter gpio]\n\n#####################################\n# Test the \"linuxgpiod *\" commands\n\n# Change the GPIO chip for all signals. Don't check directly here, do so when\n# each signal command is tested.\nlinuxgpiod gpiochip 0\n\nlinuxgpiod jtag_nums 1 2 3 4\nexpected_value \"adapter gpio tck (output): num 1, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\nexpected_value \"adapter gpio tms (output): num 2, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\nexpected_value \"adapter gpio tdi (output): num 3, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\nexpected_value \"adapter gpio tdo (input): num 4, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nlinuxgpiod tck_num 5\nexpected_value \"adapter gpio tck (output): num 5, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\n\nlinuxgpiod tms_num 6\nexpected_value \"adapter gpio tms (output): num 6, chip 0, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\n\nlinuxgpiod tdi_num 7\nexpected_value \"adapter gpio tdi (output): num 7, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\n\nlinuxgpiod tdo_num 8\nexpected_value \"adapter gpio tdo (input): num 8, chip 0, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nlinuxgpiod swd_nums 9 10\nexpected_value \"adapter gpio swclk (output): num 9, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\nexpected_value \"adapter gpio swdio (bidirectional): num 10, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nlinuxgpiod swclk_num 11\nexpected_value \"adapter gpio swclk (output): num 11, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\n\nlinuxgpiod swdio_num 12\nexpected_value \"adapter gpio swdio (bidirectional): num 12, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nlinuxgpiod swdio_dir_num 13\nexpected_value \"adapter gpio swdio_dir (output): num 13, chip 0, active-high, push-pull, pull-none\" [eval adapter gpio swdio_dir]\n\nlinuxgpiod srst_num 14\nexpected_value \"adapter gpio srst (output): num 14, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio srst]\n\nlinuxgpiod trst_num 15\nexpected_value \"adapter gpio trst (output): num 15, chip 0, active-low, pull-none, init-state inactive\" [eval adapter gpio trst]\n\nlinuxgpiod led_num 16\nexpected_value \"adapter gpio led (output): num 16, chip 0, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio led]\n\n#####################################\n# Test the old linuxgpiod_* commands\n\n# Change the GPIO chip for all signals. Don't check directly here, do so when\n# each signal command is tested.\nlinuxgpiod_gpiochip 1\n\nlinuxgpiod_jtag_nums 17 18 19 20\nexpected_value \"adapter gpio tck (output): num 17, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\nexpected_value \"adapter gpio tms (output): num 18, chip 1, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\nexpected_value \"adapter gpio tdi (output): num 19, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\nexpected_value \"adapter gpio tdo (input): num 20, chip 1, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nlinuxgpiod_tck_num 21\nexpected_value \"adapter gpio tck (output): num 21, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tck]\n\nlinuxgpiod_tms_num 22\nexpected_value \"adapter gpio tms (output): num 22, chip 1, active-high, push-pull, pull-none, init-state active\" [eval adapter gpio tms]\n\nlinuxgpiod_tdi_num 23\nexpected_value \"adapter gpio tdi (output): num 23, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio tdi]\n\nlinuxgpiod_tdo_num 24\nexpected_value \"adapter gpio tdo (input): num 24, chip 1, active-high, pull-none, init-state input\" [eval adapter gpio tdo]\n\nlinuxgpiod_swd_nums 25 26\nexpected_value \"adapter gpio swclk (output): num 25, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\nexpected_value \"adapter gpio swdio (bidirectional): num 26, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nlinuxgpiod_swclk_num 27\nexpected_value \"adapter gpio swclk (output): num 27, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swclk]\n\nlinuxgpiod_swdio_num 28\nexpected_value \"adapter gpio swdio (bidirectional): num 28, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio swdio]\n\nlinuxgpiod_led_num 29\nexpected_value \"adapter gpio led (output): num 29, chip 1, active-high, push-pull, pull-none, init-state inactive\" [eval adapter gpio led]\n\nputs \"SUCCESS\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/testing/testcases.html",
    "content": "<html>\n<head>\n<title>Test cases</title>\n</head>\n\n<body>\n<H1>Test cases</H1>\n<H2>Test case results</H2>\nThe test results are stored in seperate documents. One document for\neach subversion number.\n<table border=\"1\">\n       <tr><td>Test results</td><td>comment</td></tr>\n\t<tr><td><a href=\"examples/SAM7S256Test/results/607.html\">SAM7 R607</a></td><td>PASS</td></tr>\n\t<tr><td><a href=\"examples/STR710Test/results/607.html\">STR710 R607</a></td><td>PASS</td></tr>\n\n       <tr><td><a href=\"results/template.html\">template</a></td><td>Test results template</td></tr>\n</table>\n\n<H2>Vocabulary</H2>\n<table border=\"1\">\n       <tr>\n               <td width=\"100\">Passed version</td>\n\n               <td>The latest branch and version on which the test is known to pass</td>\n       </tr>\n       <tr>\n               <td width=\"100\">Broken version</td>\n               <td>The latest branch and version on which the test is known to fail. n/a when older than passed version.</td>\n       </tr>\n       <tr>\n               <td width=\"100\">ID</td>\n               <td>A unqiue ID to refer to a test. The unique numbers are maintained in this file. Note that the same test can be run on different hardware/interface. Each combination yields a unique id. </td>\n       </tr>\n       <tr>\n               <td width=\"100\">Test case</td>\n               <td>An atomic entity that describes the operations needed to test a feature or only a part of it. The test case should:\n                       <ul>\n                               <li>be uniquely identifiable</li>\n                               <li>define the complete prerequisites of the test (eg: the target, the interface, the initial state of the system)</li>\n                               <li>define the input to be applied to the system in order to execute the test</li>\n                               <li>define the expected output</li>\n                               <li>contain the output resulted by running the test case</li>\n                               <li>contain the result of the test (pass/fail)</li>\n                       </ul>\n               </td>\n       </tr>\n       <tr>\n               <td width=\"100\">Test suite</td>\n               <td>A (completable) collection of test cases</td>\n       </tr>\n       <tr>\n               <td width=\"100\">Testing</td>\n               <td>Testing refers to running the test suite for a specific revision of the software,\n               for one or many targets, using one or many JTAG interfaces. Testing should be be stored\n               along with all the other records for that specific revision. For releases, the results\n               can be stored along with the binaries</td>\n       </tr>\n       <tr>\n               <td width=\"100\">Target = ANY</td>\n               <td>Any target can be used for this test</td>\n       </tr>\n       <tr>\n               <td width=\"100\">Interface = ANY</td>\n               <td>Any interface can be used for this test</td>\n       </tr>\n       <tr>\n               <td width=\"100\">Target = \"reset_config srst_and_trst\"</td>\n               <td>Any target which supports the reset_config above</td>\n       </tr>\n</table>\n\n<H1>Test cases</H1>\n\n<H2>Connectivity</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"CON001\"/>CON001</td>\n               <td>ALL</td>\n               <td>ALL</td>\n               <td>Telnet connection</td>\n               <td>Power on, jtag target attached</td>\n               <td>On console, type<br><code>telnet ip port</code></td>\n               <td><code>Open On-Chip Debugger<br>></code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"CON002\"/>CON002</td>\n               <td>ALL</td>\n               <td>ALL</td>\n               <td>GDB server connection</td>\n               <td>Power on, jtag target attached</td>\n               <td>On GDB console, type<br><code>target remote ip:port</code></td>\n               <td><code>Remote debugging using 10.0.0.73:3333</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n<H2>Reset</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES001\"/>RES001</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Reset halt on a blank target</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES002\"/>RES002</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Reset init on a blank target</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset init</code></td>\n               <td>Reset should return without error and the output should contain <br><code>executing reset script 'name_of_the_script'</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES003\"/>RES003</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Reset after a power cycle of the target</td>\n               <td>Reset the target then power cycle the target</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code> after the power was detected</td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES004\"/>RES004</td>\n               <td>ARM7/9,reset_config srst_and_trst</td>\n               <td>ANY</td>\n               <td>Reset halt on a blank target where reset halt is supported</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RES005\"/>RES005</td>\n               <td>arm926ejs,reset_config srst_and_trst</td>\n               <td>ANY</td>\n               <td>Reset halt on a blank target where reset halt is supported. This target has problems with the reset vector catch being disabled by TRST</td>\n               <td>Erase all the content of the flash</td>\n               <td>Connect via the telnet interface and type <br><code>reset halt</code></td>\n               <td>Reset should return without error and the output should contain<br><code>target state: halted<br>pc = 0</code></td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n<H2>JTAG Speed</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"SPD001\"/>RES001</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>16MHz on normal operation</td>\n               <td>Reset init the target according to RES002 </td>\n               <td>Exercise a memory access over the JTAG, for example <br><code>mdw 0x0 32</code></td>\n               <td>The command should run without any errors. If any JTAG checking errors happen, the test failed</td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n<H2>Debugging</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG001\"/>DBG001</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Load is working</td>\n               <td>Reset init is working, RAM is accesible, GDB server is started</td>\n               <td>On the console of the OS: <br>\n                       <code>arm-elf-gdb test_ram.elf</code><br>\n                       <code>(gdb) target remote ip:port</code><br>\n                       <code>(gdb) load</load>\n               </td>\n               <td>Load should return without error, typical output looks like:<br>\n                       <code>\n                               Loading section .text, size 0x14c lma 0x0<br>\n                               Start address 0x40, load size 332<br>\n                               Transfer rate: 180 bytes/sec, 332 bytes/write.<br>\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG002\"/>DBG002</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Software breakpoint</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001</td>\n               <td>In the GDB console:<br>\n                       <code>\n                               (gdb) monitor arm7_9 sw_bkpts enable<br>\n                               software breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0xec: file src/main.c, line 71.<br>\n                               (gdb) continue<br>\n                               Continuing.\n                       </code>\n               </td>\n               <td>The software breakpoint should be reached, a typical output looks like:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                               cpsr: 0x000000d3 pc: 0x000000ec<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:71<br>\n                               71        DWORD a = 1;\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG003\"/>DBG003</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Single step in a RAM application</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n               <td>In GDB, type <br><code>(gdb) step</code></td>\n               <td>The next instruction should be reached, typical output:<br>\n                       <code>\n                               (gdb) step<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f0<br>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Abort<br>\n                               cpsr: 0x20000097 pc: 0x000000f4<br>\n                               72        DWORD b = 2;\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG004\"/>DBG004</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Software break points are working after a reset</td>\n               <td>Load the test_ram.elf application, use instructions from GDB001, break in main using the instructions from GDB002</td>\n               <td>In GDB, type <br><code>\n                       (gdb) monitor reset<br>\n                       (gdb) load<br>\n                       (gdb) continue<br>\n                       </code></td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to breakpoint, current mode: Supervisor<br>\n                               cpsr: 0x000000d3 pc: 0x000000ec<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:71<br>\n                               71        DWORD a = 1;\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG005\"/>DBG005</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Hardware breakpoint</td>\n               <td>Flash the test_rom.elf application. Make this test after FLA004 has passed</td>\n               <td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) load<br>\n                               Loading section .text, size 0x194 lma 0x100000<br>\n                               Start address 0x100040, load size 404<br>\n                               Transfer rate: 179 bytes/sec, 404 bytes/write.<br>\n                               (gdb) monitor arm7_9  force_hw_bkpts enable<br>\n                               force hardware breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n                               (gdb) continue<br>\n                       </code>\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG006\"/>DBG006</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Hardware breakpoint is set after a reset</td>\n               <td>Follow the instructions to flash and insert a hardware breakpoint from DBG005</td>\n               <td>In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) monitor reg pc 0x100000<br>\n                               pc (/32): 0x00100000<br>\n                               (gdb) continue\n                       </code>\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"DBG007\"/>DBG007</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Single step in ROM</td>\n               <td>Flash the test_rom.elf application and set a breakpoint in main, use DBG005. Make this test after FLA004 has passed</td>\n               <td>Be sure that <code>gdb_memory_map</code> and <code>gdb_flash_program</code> are enabled. In GDB, type <br>\n                       <code>\n                               (gdb) monitor reset<br>\n                               (gdb) load<br>\n                               Loading section .text, size 0x194 lma 0x100000<br>\n                               Start address 0x100040, load size 404<br>\n                               Transfer rate: 179 bytes/sec, 404 bytes/write.<br>\n                               (gdb) monitor arm7_9  force_hw_bkpts enable<br>\n                               force hardware breakpoints enabled<br>\n                               (gdb) break main<br>\n                               Breakpoint 1 at 0x100134: file src/main.c, line 69.<br>\n                               (gdb) continue<br>\n                               Continuing.<br>\n                               <br>\n                               Breakpoint 1, main () at src/main.c:69<br>\n                               69        DWORD a = 1;<br>\n                               (gdb) step\n                       </code>\n               </td>\n               <td>The breakpoint should be reached, typical output:<br>\n                       <code>\n                               target state: halted<br>\n                               target halted in ARM state due to single step, current mode: Supervisor<br>\n                               cpsr: 0x60000013 pc: 0x0010013c<br>\n                               70        DWORD b = 2;<br>\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n<H2>RAM access</H2>\nNote: these tests are not designed to test/debug the target, but to test functionalities!\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM001\"/>RAM001</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>32 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mww ram_address 0xdeadbeef 16<br>\n                                       > mdw ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 32bit long containing 0xdeadbeef.<br>\n                       <code>\n                               > mww 0x0 0xdeadbeef 16<br>\n                               > mdw 0x0 32<br>\n                               0x00000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x00000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x00000040: e1a00000 e59fa51c e59f051c e04aa000 00080017 00009388 00009388 00009388<br>\n                               0x00000060: 00009388 0002c2c0 0002c2c0 000094f8 000094f4 00009388 00009388 00009388<br>\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM001\"/>RAM001</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>16 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mwh ram_address 0xbeef 16<br>\n                                       > mdh ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 16bit long containing 0xbeef.<br>\n                       <code>\n                               > mwh 0x0 0xbeef 16<br>\n                               > mdh 0x0 32<br>\n                               0x00000000: beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef beef<br>\n                               0x00000020: 00e0 0000 021c 0000 0240 0000 026c 0000 0288 0000 0000 0000 0388 0000 0350 0000<br>\n                               >\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"RAM003\"/>RAM003</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>8 bit Write/read RAM</td>\n               <td>Reset init is working</td>\n               <td>On the telnet interface<br>\n                       <code>  > mwb ram_address 0xab 16<br>\n                                       > mdb ram_address 32\n                       </code>\n               </td>\n               <td>The commands should execute without error. A clear failure is a memory access exception. The result of running the commands should be a list of 16 locations 8bit long containing 0xab.<br>\n                       <code>\n                               > mwh 0x0 0x0 16<br>\n                               > mwb ram_address 0xab 16<br>\n                               > mdb ram_address 32<br>\n                               0x00000000: ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>\n                               >\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n\n\n<H2>Flash access</H2>\n<table border=1>\n       <tr>\n               <td>ID</td>\n               <td>Target</td>\n               <td>Interface</td>\n               <td>Description</td>\n               <td>Initial state</td>\n               <td>Input</td>\n               <td>Expected output</td>\n               <td>Pass/Fail</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA002\"/>FLA002</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>flash fillw</td>\n               <td>Reset init is working, flash is probed</td>\n               <td>On the telnet interface<br>\n                       <code>  > flash fillw 0x1000000 0xdeadbeef 16\n                       </code>\n               </td>\n               <td>The commands should execute without error. The output looks like:<br>\n                       <code>\n                               wrote 64 bytes to 0x01000000 in 11.610000s (0.091516 kb/s)\n                       </code><br>\n                       To verify the contents of the flash:<br>\n                       <code>\n                               > mdw 0x1000000 32<br>\n                               0x01000000: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x01000020: deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef deadbeef<br>\n                               0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA003\"/>FLA003</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Flash erase</td>\n               <td>Reset init is working, flash is probed</td>\n               <td>On the telnet interface<br>\n                       <code>  >  flash erase_address 0x1000000 0x2000\n                       </code>\n               </td>\n               <td>The commands should execute without error.<br>\n                       <code>\n                               erased address 0x01000000 length 8192 in 4.970000s\n                       </code>\n                       To check that the flash has been erased, read at different addresses. The result should always be 0xff.\n                       <code>\n                               > mdw 0x1000000 32<br>\n                               0x01000000: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000020: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000040: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff<br>\n                               0x01000060: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n                       </code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n       <tr>\n               <td><a name=\"FLA004\"/>FLA004</td>\n               <td>Fill in!</td>\n               <td>Fill in!</td>\n               <td>Loading to flash from GDB</td>\n               <td>Reset init is working, flash is probed, connectivity to GDB server is working</td>\n               <td>Start GDB using a ROM elf image, eg: arm-elf-gdb test_rom.elf. <br>\n                               <code>\n                                       (gdb) target remote ip:port<br>\n                                       (gdb) monitor reset<br>\n                                       (gdb) load<br>\n                                       Loading section .text, size 0x194 lma 0x100000<br>\n                                       Start address 0x100040, load size 404<br>\n                                       Transfer rate: 179 bytes/sec, 404 bytes/write.\n                                       (gdb) monitor verify_image path_to_elf_file\n                               </code>\n               </td>\n               <td>The output should look like:<br>\n                       <code>\n                               verified 404 bytes in 5.060000s\n                       </code><br>\n                       The failure message is something like:<br>\n                       <code>Verify operation failed address 0x00200000. Was 0x00 instead of 0x18</code>\n               </td>\n               <td>PASS/FAIL</td>\n       </tr>\n</table>\n\n</body>\n</html>\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/checkpatch.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\nsince=${1:-HEAD^}\ntools/scripts/checkpatch.pl --git ${since}..\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/disassemble_inc.sh",
    "content": "#!/bin/sh\n# SPDX-License-Identifier: GPL-2.0-or-later\n\n# Simple script to disassemble a file .inc generated by\n# src/helper/bin2char.sh\n# Can be useful to check the correctness of the file .inc\n#\n# By default it decodes ARM thumb little-endian, e.g. cortex-m.\n# Set CROSS_COMPILE for other toolchains.\n# Set OBJDUMP_FLAGS for different objdump flags.\n#\n# Usage:\n#   contrib/loaders/disassemble_inc.sh file.inc\n\ndefault_CROSS_COMPILE=\"arm-none-eabi-\"\ndefault_OBJDUMP_FLAGS=\"-m arm -EL -M force-thumb\"\n\nif [ $# != 1 -o ! -f \"$1\" ]; then\n\techo \"Usage:\"\n\techo \"    $0 path/to/file.inc\"\n\techo \"\"\n\techo \"Set CROSS_COMPILE and/or OBJDUMP_FLAGS to override current default:\"\n\techo \"    export CROSS_COMPILE=\\\"${default_CROSS_COMPILE}\\\"\"\n\techo \"    export OBJDUMP_FLAGS=\\\"${default_OBJDUMP_FLAGS}\\\"\"\n\texit 1\nfi\n\nif [ -z \"${CROSS_COMPILE}\" ]; then\n\tCROSS_COMPILE=\"${default_CROSS_COMPILE}\"\nfi\n\nif [ -z \"${OBJDUMP_FLAGS}\" ]; then\n\tOBJDUMP_FLAGS=\"${default_OBJDUMP_FLAGS}\"\nfi\n\nperl -v > /dev/null 2>&1\nif [ $? != 0 ]; then\n\techo \"Error: 'perl' interpreter not available.\"\n\texit 1\nfi\n\ntmpfile=$(mktemp --suffix=.bin)\n\necho \"Disassemble $1:\"\necho \"${CROSS_COMPILE}objdump ${OBJDUMP_FLAGS} -b binary -D ${tmpfile}\"\n\nperl -e 'while (<>){while ($_=~/(0x..)/g){print chr(hex($1));}}' $1 > ${tmpfile}\n${CROSS_COMPILE}objdump ${OBJDUMP_FLAGS} -b binary -D ${tmpfile}\n\nrm ${tmpfile}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/initial.sh",
    "content": "#!/bin/sh\nTOPDIR=`pwd`\nUSERNAME=$1\n\nif [ \"x$1\" = \"x\" ] ; then\n\techo \"Usage:\t$0\t<Username>\"\n\texit 1\nfi\n\nadd_remote()\n{\n\tremote_exist=`grep remote .git/config | grep review\t| wc -l`\n\tif [ \"x$remote_exist\" = \"x0\" ] ; then\n\t\tgit remote add review ssh://$USERNAME@review.openocd.org:29418/openocd.git\n\t\tgit config remote.review.push HEAD:refs/for/master\n\telse\n\t\techo \"Remote review exists\"\n\tfi\n}\n\nupdate_commit_msg()\n{\n\tcd \"${TOPDIR}/.git/hooks\"\n\tsave_file=commit-msg-`date +%F-%T`\n\tmv commit-msg $save_file\n\tprintf \"%-30s\"\t\"Updating commit-msg\"\n\tstatus=\"OK\"\n\twget -o log\thttps://review.openocd.org/tools/hooks/commit-msg\t|| status=\"FAIL\"\n\techo $status\n\tif [ $status = \"FAIL\" ] ; then\n\t\tmv\t$save_file\tcommit-msg\n\tfi\n\tchmod a+x commit-msg\n}\n\nadd_remote\nupdate_commit_msg\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/logger.pl",
    "content": "#!/usr/bin/perl\n# logger.pl: masks long meaningless output with pretty lines of dots\n#  Details: 1) reads lines from STDIN and echos them on STDOUT,\n#           2) print a '.' to STDERR every $N lines.\n#           3) print a newline after a sequence of $C dots\n\nuse strict;\nuse warnings;\n\n# make sure all output gets displayed immediately\n$| = 1;\n\n# TODO: add -n and -c options w/ zero checks)\n# line and column limits\nmy $N = 10;\nmy $C = 72;\n\n# current line and column counters\nmy $n = 0;\nmy $c = 0;\n\n# read all lines from STDIN\nwhile (<STDIN>)\n{\n\t# echo line to output\n\tprint STDOUT $_;\n\t# echo line to console if it is important\n\tif (/(Warning|Error)/) {\n\t\tprint STDERR \"\\n\" if $c;\n\t\tprint STDERR $_;\n\t\t$c = 0;\n\t}\n\t# only display progress every Nth step\n\tnext if ++$n % $N;\n\tprint STDERR \".\";\n\t# wrap at column C to provide fixed-width rows of dots\n\tprint STDERR \"\\n\" unless ++$c % $C;\n}\n\nprint STDERR \"\\n\" if $c;\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/release/helpers.sh",
    "content": "#!/bin/sh -e\n\ndie() {\n\techo \"$@\" >&2\n\texit 1\n}\n\npackage_info_load_name() {\n\tgrep AC_INIT configure.ac | perl -ne 's/^.+\\(\\[([-\\w]*)\\],.+$/$1/ and print'\n}\npackage_info_load_version() {\n\tgrep AC_INIT configure.ac | perl -ne 's/^.+\\[([-\\w\\.]*)\\],$/$1/ and print'\n}\n\npackage_info_load() {\n\t[ -f \"configure.ac\" ] || \\\n\t\tdie \"package_info_load: configure.ac is missing\"\n\n\tPACKAGE_NAME=\"$(package_info_load_name)\"\n\t# todo: fix this\n\tPACKAGE_TARNAME=\"${PACKAGE_NAME}\"\n\n\tPACKAGE_VERSION=\"$(package_info_load_version)\"\n\n\t[ \"${PACKAGE_NAME}\" -a \"${PACKAGE_VERSION}\" ] || \\\n\t\tdie \"package information is missing from configure script\"\n\n\tPACKAGE_VERSION_TAGS=\n\t[ \"${PACKAGE_VERSION/-/}\" = \"${PACKAGE_VERSION}\" ] || \\\n\t\tPACKAGE_VERSION_TAGS=\"-${PACKAGE_VERSION#*-}\"\n\tPACKAGE_VERSION_BASE=\"${PACKAGE_VERSION%%-*}\"\n\tPACKAGE_MICRO=\"${PACKAGE_VERSION_BASE##*.}\"\n\tPACKAGE_MAJOR_AND_MINOR=\"${PACKAGE_VERSION_BASE%.*}\"\n\tPACKAGE_MAJOR=\"${PACKAGE_MAJOR_AND_MINOR%.*}\"\n\tPACKAGE_MINOR=\"${PACKAGE_MAJOR_AND_MINOR#*.}\"\n\n\t[ \"${RELEASE_FINAL}\" ] \\\n\t\t&& RELEASE_VERSION=\"${PACKAGE_VERSION_BASE}\" \\\n\t\t|| RELEASE_VERSION=\"${PACKAGE_VERSION/-dev/}\"\n\tPACKAGE_RELEASE=\"${PACKAGE_TARNAME}-${RELEASE_VERSION}\"\n\tPACKAGE_STRING=\"${PACKAGE_NAME} ${PACKAGE_VERSION}\"\n}\n\npackage_info_show() {\n\tcat <<INFO\nName: ${PACKAGE_TARNAME}\nVersion: ${PACKAGE_VERSION}\nRelease: ${RELEASE_VERSION}\n   Number: ${PACKAGE_VERSION_BASE}\n   Series: ${PACKAGE_MAJOR_AND_MINOR}\n    Major: ${PACKAGE_MAJOR}\n    Minor: ${PACKAGE_MINOR}\n    Micro: ${PACKAGE_MICRO}\n     Tags: ${PACKAGE_VERSION_TAGS}\n   Full: ${PACKAGE_TARNAME}-${PACKAGE_VERSION_BASE}${PACKAGE_VERSION_TAGS}\nRelease: ${PACKAGE_RELEASE}\n   Type: ${RELEASE_TYPE}\nINFO\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/release/test.sh",
    "content": "#!/bin/sh -e\n\nSRC=\"$1\"\nif [ \"${SRC}\" ]; then\n\tshift\nelse\n\tSRC=\"${0%%/*}\"\nfi\nif [ ! -d \"${SRC}/.git\" ]; then\n\techo \"'${SRC}' is not a git repository\"\n\texit 1\nfi\n\nDST=\"$1\"\n[ \"${DST}\" ] || DST=\"release-${SRC}\"\n\nexport RELEASE_FAST=yes\n\ncat <<EOF\nStarting test release clone process:\n   from: '${SRC}'\n     to: '${DST}'\nThis will destroy any contents in '${DST}'.\nEOF\necho -n \"Press Control-C to abort in \"\nfor i in $(seq 5 -1 1); do echo -n \"$i \"; sleep 1; done\necho \"go!\"\n\nrm -rf \"${DST}\"\ngit clone \"${SRC}\" \"${DST}\"\n\ncd \"${DST}\"\n#     TAG+RELEASE     NEW BRANCH (w/ -dev)\n# \t0.3.0 \t\t0.4.0-rc0\ntools/release.sh release --next='minor' --start-rc\n\ngit checkout -q \"v0.3.0\"\n# \t<none>\t\t0.3.1\ntools/release.sh branch --next='micro'\n# \t0.3.1 \t\t0.3.2\ntools/release.sh release --next='micro'\n\ngit checkout \"v0.4.0-rc0-dev\"\n# \t0.4.0-rc0\t0.4.0-rc1\ntools/release.sh release --next='rc'\n# \t0.4.0\t\t1.0.0-rc0\ntools/release.sh release --next='major' --final --start-rc\n\ngit checkout -q \"v0.4.0\"\n# \t<none>\t\t0.4.1\ntools/release.sh branch --next='micro'\n# \t0.4.1 \t\t0.4.2\ntools/release.sh release --next='micro'\n\ngit checkout \"v1.0.0-rc0-dev\"\n# \t1.0.0-rc0\t1.0.0-rc1\ntools/release.sh release --next='rc'\n# \t1.0.0\t\t1.1.0-rc0\ntools/release.sh release --next='minor' --final --start-rc\n\ngit checkout -q \"v1.0.0\"\n# \t<none>\t\t1.0.1\ntools/release.sh branch --next='micro'\n# \t1.0.1 \t\t1.0.2\ntools/release.sh release --next='micro'\n\ngit checkout \"v1.1.0-rc0-dev\"\n# \t1.1.0-rc0\t1.1.0-rc1\ntools/release.sh release --next='rc'\n# \t1.1.0\t\t1.2.0\ntools/release.sh release --next='minor' --final --start-rc\n\ngit checkout -q \"v1.0.0\"\ntools/release.sh branch --next='major' --start-rc\n\n# \t<none>\t\t2.0.0-rc0\ngit checkout \"v2.0.0-rc0-dev\"\n# \t2.0.0-rc0\t2.0.0-rc1\ntools/release.sh release --next='rc'\n# \t2.0.0-rc1\t2.0.0-rc2\ntools/release.sh release --next='rc'\n# \t2.0.0\t\t2.1.0-rc0\ntools/release.sh release --next='minor' --final --start-rc\n\ngit checkout -q \"v1.1.0\"\n# \t<none>\t\t1.1.1\ntools/release.sh branch --next='micro'\n# \t1.1.1 \t\t1.1.2\ntools/release.sh release --next='micro'\n\ngit checkout -q \"v2.0.0\"\n# \t<none>\t\t2.0.0\ntools/release.sh branch --next='micro'\n# \t2.0.1\t\t2.0.2\ntools/release.sh release --next='micro'\n\ngit checkout \"v1.2.0-rc0-dev\"\n# \t1.2.0-rc0\t1.2.0-rc1\ntools/release.sh release --next='rc'\n# \t1.2.0\t\t1.3.0-rc0\ntools/release.sh release --next='micro' --final\n\ngit checkout \"v2.1.0-rc0-dev\"\n# \t2.1.0-rc0\t2.1.0-rc1\ntools/release.sh release --next='rc'\n# \t2.1.0-rc1\t2.1.0-rc2\ntools/release.sh release --next='rc'\n# \t2.1.0\t\t2.2.0-rc0\ntools/release.sh release --next='minor' --final --start-rc\n\ngit checkout -q \"v2.1.0\"\n# \t<none>\t\t2.1.1\ntools/release.sh branch --next='micro'\n# \t2.1.1\t\t2.1.2\ntools/release.sh release --next='micro'\n\ngit checkout \"v2.2.0-rc0-dev\"\n# \t2.2.0-rc0\t2.2.0-rc1\ntools/release.sh release --next='rc'\n\ngitk --all\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/release/version.sh",
    "content": "#!/bin/bash\n# version.sh: openocd version process automation\n# Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>\n# Release under the GNU GPL v2 (or later versions).\n\n# FIXME Remove more bash-isms.  Fix errors making \"ash -e\" lose.\n\n# NOTE Use with care!  \"RC\" should only follow x.x.x, with\n# vendor tags after that.  Be traditional; avoid \"rc0\".\n\n# NOTE:  This *ONLY* updates the \"configure.ac\" version tag.\n# It does not affect GIT tags.  Use this script immediately\n# before making a release, to remove the \"-dev\" tag and to\n# update the version label.  Then commit the change and tag\n# that commit to match the version label.\n\n. \"tools/release/helpers.sh\"\n\ndo_version_usage() {\n\tcat << USAGE\nusage: $0 <command>\nVersion Commands:\n  tag {add|remove} <label>     Add or remove the specified tag.\n  bump {major|minor|micro|rc}  Bump the specified version number, and\n                               reset less-significant numbers to zero.\n  bump tag <label>             Add or bump a versioned tag (e.g. -rcN).\n  bump final <label>           Remove a versioned tag (e.g. -rcN).\nUSAGE\n# REVISIT ... \"commit\" not listed.\n}\n\ndo_version_sed() {\n\tlocal OLD_VERSION=\"${PACKAGE_VERSION}\"\n\tlocal NEW_VERSION=\"$1\"\n\tlocal MSG=\"$2\"\n\n\tsed -i -e \"/AC_INIT/ s|${OLD_VERSION}|${NEW_VERSION}|\" configure.ac\n\tpackage_info_load\n\techo \"${MSG}: ${OLD_VERSION} -> ${NEW_VERSION}\"\n}\ndo_version_bump_sed() {\n\tlocal NEW_VERSION=\"$1\"\n\t[ -z \"${PACKAGE_VERSION_TAGS}\" ] || \\\n\t\tNEW_VERSION=\"${NEW_VERSION}${PACKAGE_VERSION_TAGS}\"\n\n\tdo_version_sed \"${NEW_VERSION}\" \\\n\t\t\"Bump ${CMD} package version number\"\n}\ndo_version_bump_major() {\n\tdo_version_bump_sed \"$((PACKAGE_MAJOR + 1)).0.0\"\n}\ndo_version_bump_minor() {\n\tdo_version_bump_sed \"${PACKAGE_MAJOR}.$((PACKAGE_MINOR + 1)).0\"\n}\ndo_version_bump_micro() {\n\tdo_version_bump_sed \"${PACKAGE_MAJOR_AND_MINOR}.$((PACKAGE_MICRO + 1))\"\n}\ndo_version_bump_tag() {\n\tlocal TAG=\"$1\"\n\t[ \"${TAG}\" ] || die \"TAG argument is missing\"\n\tlocal TAGS=\"${PACKAGE_VERSION_TAGS}\"\n\tif has_version_tag \"${TAG}\"; then\n\t\tlocal RC=$(do_version_tag_value \"${TAG}\")\n\t\tRC=$((${RC} + 1))\n\t\tTAGS=$(echo ${TAGS} | perl -npe \"s/-${TAG}[\\\\d]*/-${TAG}${RC}/\")\n\telse\n\t\tTAGS=\"-${TAG}0${PACKAGE_VERSION_TAGS}\"\n\tfi\n\tPACKAGE_VERSION_TAGS=\"${TAGS}\"\n\tdo_version_bump_sed \"${PACKAGE_VERSION_BASE}\"\n}\ndo_version_bump_final() {\n\tlocal TAG=\"$1\"\n\t[ \"${TAG}\" ] || die \"TAG argument is missing\"\n\thas_version_tag \"${TAG}\" || die \"-${TAG} tag is missing\"\n\tdo_version_tag_remove \"${TAG}$(do_version_tag_value \"${TAG}\")\"\n}\ndo_version_bump() {\n\tCMD=\"$1\"\n\tshift\n\tcase \"${CMD}\" in\n\tmajor|minor|micro|final|tag)\n\t\t\"do_version_bump_${CMD}\" \"$@\"\n\t\t;;\n\trc)\n\t\tdo_version_bump_tag \"rc\"\n\t\t;;\n\t*)\n\t\tdo_version_usage\n\t\t;;\n\tesac\n}\n\nhas_version_tag() {\n\ttest \"${PACKAGE_VERSION/-${1}/}\" != \"${PACKAGE_VERSION}\"\n}\ndo_version_tag_value() {\n\tlocal TAG=\"$1\"\n\techo ${PACKAGE_VERSION_TAGS} | perl -ne \"/-${TAG}\"'(\\d+)/ && print $1'\n}\ndo_version_tag_add() {\n\tlocal TAG=\"$1\"\n\thas_version_tag \"${TAG}\" && \\\n\t\tdie \"error: tag '-${TAG}' exists in '${PACKAGE_VERSION}'\"\n\tdo_version_sed \"${PACKAGE_VERSION}-${TAG}\" \\\n\t\t\"Add '-${TAG}' version tag\"\n}\ndo_version_tag_remove() {\n\tlocal TAG=\"$1\"\n\thas_version_tag \"${TAG}\" || \\\n\t\tdie \"error: tag '-${TAG}' missing from '${PACKAGE_VERSION}'\"\n\tdo_version_sed \"${PACKAGE_VERSION/-${TAG}/}\" \\\n\t\t\"Remove '-${TAG}' version tag\"\n}\ndo_version_tag() {\n\tCMD=\"$1\"\n\tshift\n\tcase \"${CMD}\" in\n\tadd|remove)\n\t\tlocal i=\n\t\tfor i in \"$@\"; do\n\t\t\t\"do_version_tag_${CMD}\" \"${i}\"\n\t\tdone\n\t\t;;\n\t*)\n\t\tdo_version_usage\n\t\t;;\n\tesac\n}\n\ndo_version() {\n\tCMD=\"$1\"\n\tshift\n\tcase \"${CMD}\" in\n\ttag|bump)\n\t\t\"do_version_${CMD}\" \"$@\"\n\t\t;;\n\tcommit)\n\t\tdo_version_commit \"$@\"\n\t\t;;\n\t*)\n\t\tdo_version_usage\n\t\t;;\n\tesac\n}\n\npackage_info_load\ndo_version \"$@\"\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/release.sh",
    "content": "#!/bin/bash\n# release.sh: openocd release process automation\n# Copyright (C) 2009 by Zachary T Welch <zw@superlucidity.net>\n# Release under the GNU GPL v2 (or later versions).\n\n# FIXME Remove more bash-isms.  Fix errors making \"ash -e\" lose.\n\n## set these to control the build process\n#CONFIG_OPTS=\"\"\n#MAKE_OPTS=\"\"\n\n## specifies the --next release type: major, minor, micro, rc, tag\n#RELEASE_TYPE=tag\n## For tag release type, specifies the name of the tag (e.g. \"foo\").\n## The default is the current user name, as found by the 'id' command.\n#RELEASE_TAG=\"$(id -un)\"\n\n. \"tools/release/helpers.sh\"\n\nVERSION_SH=\"tools/release/version.sh\"\n\nusage() {\n\tcat << USAGE\nusage: $0 <command> ...\nCommand Options:\n  --next name   The branch's next release type: major, minor, micro, rc, tag.\n  --next-tag name   The name for the package version tag.\n  --live        Perform the actions in the repository.\n\nMain Commands:\n  info          Show a summary of the next pending release.\n  release       Release the current tree as an archive.\n\nBuild Commands:\n  bootstrap     Prepare the working copy for configuration and building.\n  configure     Configures the package; runs bootstrap, if needed.\n  build         Compiles the project; runs configure, if needed.\n\nPackaging Commands:\n  package       Produce new distributable source archives.\n  stage         Move archives to staging area for upload.\n\nOther Commands:\n  clean         Forces regeneration of results.\n  clean_all     Removes all traces of the release process.\n  help          Provides this list of commands.\n\nFor more information about this script, see the Release Processes page\nin the OpenOCD Developer's Manual (doc/manual/release.txt).\nUSAGE\n\texit 0\n}\ndo_usage() { usage; }\ndo_help()  { usage; }\n\ndo_info() {\n\techo \"Current Release Analysis:\"\n\tpackage_info_show\n}\n\ndo_bootstrap() {\n\techo -n \"Bootstrapping...\"\n\t./bootstrap 2>&1 | perl tools/logger.pl > \"release-bootstrap.log\"\n}\nmaybe_bootstrap() { [ -f \"configure\" ] || do_bootstrap; }\n\ndo_configure() {\n\tmaybe_bootstrap\n\techo -n \"Configuring...\"\n\t./configure ${CONFIG_OPTS} 2>&1 | perl tools/logger.pl > \"release-config.log\"\n}\nmaybe_configure() { [ -f \"Makefile\" ] || do_configure; }\n\ndo_build() {\n\tmaybe_configure\n\techo -n \"Compiling OpenOCD ${PACKAGE_VERSION}\"\n\tmake ${MAKE_OPTS} -C doc stamp-vti 2>&1 \\\n\t\t| perl tools/logger.pl > \"release-version.log\"\n\tmake ${MAKE_OPTS} 2>&1 \\\n\t\t| perl tools/logger.pl > \"release-make.log\"\n}\nmaybe_build() { [ -f \"src/openocd\" ] || do_build; }\ndo_build_clean() { [ -f Makefile ] && make maintainer-clean >/dev/null; }\n\n\ndo_package() {\n\tmaybe_build\n\techo \"Building distribution packages...\"\n\tmake ${MAKE_OPTS} distcheck 2>&1 | perl tools/logger.pl > \"release-pkg.log\"\n}\nmaybe_package() { [ -f \"${PACKAGE_RELEASE}.zip\" ] || do_package; }\ndo_package_clean() {\n\tfor EXT in tar.gz tar.bz2 zip; do\n\t\trm -v -f *.${EXT}\n\tdone\n}\n\ndo_stage() {\n\tmaybe_package\n\techo \"Staging package archives:\"\n\tmkdir -p archives\n\tfor EXT in tar.gz tar.bz2 zip; do\n\t\tlocal FILE=\"${PACKAGE_RELEASE}.${EXT}\"\n\t\t# create archive signatures\n\t\tfor HASH in sha256; do\n\t\t\techo \"sign: ${FILE}.${HASH}\"\n\t\t\t${HASH}sum \"${FILE}\" > \"archives/${FILE}.${HASH}\"\n\t\tdone\n\t\t# save archive\n\t\tmv -v \"${FILE}\" archives/\n\tdone\n\tcp -a NEWS archives/\n}\ndo_stage_clean() { rm -v -f -r archives; }\n\ndo_clean() {\n\tdo_build_clean\n\tdo_package_clean\n\trm -v -f release-*.log\n}\ndo_clean_all() {\n\tdo_clean\n\tdo_stage_clean\n}\n\ndo_version_commit() {\n\t[ \"$*\" ] || die \"usage: $0 commit <message>\"\n\tgit add configure.ac || die \"error: no version changes to commit\"\n\tgit commit -q -m \"$*\" configure.ac\n}\n\ndo_version_finalize() {\n\techo \"The ${PACKAGE_NAME} ${RELEASE_VERSION} release.\"\n\techo\n\t${VERSION_SH} tag remove dev\n\t[ -z \"${RELEASE_FINAL}\" ] || ${VERSION_SH} bump final rc\n}\nhas_dev_tag() {\n\t[ \"${PACKAGE_VERSION/dev/}\" != \"${PACKAGE_VERSION}\" ]\n}\ndo_release_step_branch() {\n\tgit checkout -b \"v${RELEASE_VERSION}-release\"\n}\n\ndo_release_step_tag() {\n\tdo_version_commit \"$(do_version_finalize)\"\n\tpackage_info_load\n\t[ \"${PACKAGE_VERSION/dev/}\" = \"${PACKAGE_VERSION}\" ] || \\\n\t\tdie \"'${PACKAGE_NAME}-${PACKAGE_VERSION}' should not be tagged\"\n\tlocal MSG=\"The ${PACKAGE_STRING} release.\"\n\tgit tag -m \"${MSG}\" \"v${PACKAGE_VERSION}\"\n}\n\ndo_bump_version() {\n\techo -n \"Bump ${RELEASE_TYPE} \"\n\t[ -z \"${RELEASE_TAG}\" ] || echo -n \"-${RELEASE_TAG} \"\n\techo -n \"version and add \"\n\t[ -z \"${RELEASE_START_RC}\" ] || echo -n \"-rc0\"\n\techo \"-dev tag.\"\n\techo\n\t${VERSION_SH} bump \"${RELEASE_TYPE}\" \"${RELEASE_TAG}\"\n\t[ -z \"${RELEASE_START_RC}\" ] || ${VERSION_SH} bump tag rc\n\t${VERSION_SH} tag add dev\n}\ndo_release_step_bump() {\n\t# bump the version number\n\tdo_version_commit \"$(do_bump_version)\"\n}\n\ndo_release_step_news_msg() {\n\tcat <<MSG\nArchive and recreate NEWS file.\n\nArchive released NEWS file as NEWS-${RELEASE_VERSION}.\nCreate new NEWS file from release script template.\nMSG\n}\ndo_release_step_news() {\n\t# only archive the NEWS file for major/minor releases\n\t[ \"${RELEASE_TYPE}\" = \"major\" -o \"${RELEASE_TYPE}\" = \"minor\" ] || \\\n\t\treturn 0\n\t# archive NEWS and create new one from template\n\tgit mv \"NEWS\" \"NEWS-${RELEASE_VERSION}\"\n\n\tcat >NEWS <<NEWS\nThis file includes highlights of the changes made in the\nOpenOCD ${NEXT_RELEASE_VERSION} source archive release.  See the\nrepository history for details about what changed, including\nbugfixes and other issues not mentioned here.\n\nJTAG Layer:\nBoundary Scan:\nTarget Layer:\nFlash Layer:\nBoard, Target, and Interface Configuration Scripts:\nDocumentation:\nBuild and Release:\n\nFor more details about what has changed since the last release,\nsee the git repository history.  With gitweb, you can browse that\nin various levels of detail.\n\nFor older NEWS, see the NEWS files associated with each release\n(i.e. NEWS-<version>).\n\nFor more information about contributing test reports, bug fixes, or new\nfeatures and device support, please read the new Developer Manual (or\nthe BUGS and PATCHES.txt files in the source archive).\nNEWS\n\tgit add NEWS\n\n\tlocal MSG=\"$(do_release_step_news_msg)\"\n\tgit commit -q -m \"${MSG}\" NEWS \"NEWS-${RELEASE_VERSION}\"\n}\n\ndo_release_step_package() {\n\t[ -z \"${RELEASE_FAST}\" ] || return 0\n\n\tgit checkout -q \"v${RELEASE_VERSION}\"\n\tdo_stage\n\tdo_clean\n}\n\ndo_release_step_rebranch() {\n\t# return to the new development head\n\tlocal OLD_BRANCH=\"v${RELEASE_VERSION}-release\"\n\tgit checkout \"${OLD_BRANCH}\"\n\n\t# create new branch with new version information\n\tpackage_info_load\n\tgit checkout -b \"v${PACKAGE_VERSION}\"\n\tgit branch -d \"${OLD_BRANCH}\"\n}\n\ndo_release_setup() {\n\techo \"Starting $CMD for ${RELEASE_VERSION}...\"\n\t[ \"${RELEASE_TYPE}\" ] || \\\n\t\tdie \"The --next release type must be provided.  See --help.\"\n}\n\ndo_release_check() {\n\t[ -z \"${RELEASE_FAST}\" ] || return 0\n\techo \"Are you sure you want to ${CMD} '${PACKAGE_RELEASE}', \"\n\techo -n \"   to start a new  ${RELEASE_TYPE}  development cycle? (y/N) \"\n\tread ANSWER\n\tif [ \"${ANSWER}\" != 'y' ]; then\n\t\techo \"Live release aborted!\"\n\t\texit 0\n\tfi\n\tdo_countdown \"Starting live release\"\n}\ndo_countdown() {\n\techo -n \"$1 in \"\n\tfor i in $(seq 5 -1 1); do\n\t\techo -n \"$i, \"\n\t\tsleep 1\n\tdone\n\techo \"go!\"\n}\n\ndo_branch() {\n\tdo_release_setup\n\tlocal i=\n\tfor i in branch bump rebranch; do\n\t\t\"do_release_step_${i}\"\n\tdone\n}\n\ndo_release() {\n\tlocal CMD='release'\n\tdo_release_setup\n\tdo_release_check\n\tlocal i=\n\tfor i in branch tag bump news package rebranch; do\n\t\t\"do_release_step_${i}\"\n\tdone\n}\ndo_all() { do_release \"$@\"; }\n\ndo_reset() {\n\tmaybe_bootstrap\n\tmaybe_configure\n\tdo_clean_all\n\tgit checkout configure.ac\n}\n\nLONGOPTS=\"fast,final,start-rc,next-tag:,next:,help\"\nOPTIONS=$(getopt -o 'V,n:' --long \"${LONGOPTS}\" -n $0 -- \"$@\")\nif [ $? != 0 ] ; then echo \"Terminating...\" >&2 ; exit 1 ; fi\neval set -- \"${OPTIONS}\"\nwhile true; do\n\tcase \"$1\" in\n\t--fast)\n\t\tRELEASE_FAST=yes\n\t\tshift\n\t\t;;\n\t--final)\n\t\tRELEASE_FINAL=yes\n\t\tshift\n\t\t;;\n\t--start-rc)\n\t\tRELEASE_START_RC=yes\n\t\tshift\n\t\t;;\n\t-n|--next)\n\t\texport RELEASE_TYPE=\"$2\"\n\t\tshift 2\n\t\t;;\n\t--next-tag)\n\t\texport RELEASE_TAG=\"$2\"\n\t\tshift 2\n\t\t;;\n\t-V)\n\t\texec $0 info\n\t\t;;\n\t--)\n\t\tshift\n\t\tbreak\n\t\t;;\n\t--help)\n\t\tusage\n\t\tshift\n\t\t;;\n\t*)\n\t\techo \"Internal error\"\n\t\texit 1\n\t\t;;\n\tesac\ndone\n\ncase \"${RELEASE_TYPE}\" in\nmajor|minor|micro|rc)\n\t;;\ntag)\n\t[ \"${RELEASE_TAG}\" ] || RELEASE_TAG=\"$(id -u -n)\"\n\t;;\n'')\n\t;;\n*)\n\tdie \"Unknown release type '${RELEASE_TYPE}'\"\n\t;;\nesac\n\nCMD=$1\n[ \"${CMD}\" ] || usage\nshift\n\nACTION_CMDS=\"bootstrap|configure|build|package|stage|clean\"\nMISC_CMDS=\"all|info|release|branch|reset|help|usage\"\nCLEAN_CMDS=\"build_clean|package_clean|stage_clean|clean_all\"\nCMDS=\"|${ACTION_CMDS}|${CLEAN_CMDS}|${MISC_CMDS}|\"\nis_command() { echo \"${CMDS}\" | grep \"|$1|\" >/dev/null; }\n\npackage_info_load\nif is_command \"${CMD}\"; then\n\t\"do_${CMD}\" \"$@\"\n\techo \"Done with '${CMD}'.\" >&2\nelse\n\techo \"error: unknown command: '${CMD}'\"\n\tusage\nfi\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/rlink_make_speed_table/rlink_make_speed_table",
    "content": "#!/bin/sh\nexec perl \"$0.pl\" $*\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/rlink_make_speed_table/rlink_make_speed_table.pl",
    "content": "#!/bin/perl\n#***************************************************************************\n#*   Copyright (C) 2008 Lou Deluxe                                         *\n#*   lou.openocd012@fixit.nospammail.net                                   *\n#*                                                                         *\n#*   This program is free software; you can redistribute it and/or modify  *\n#*   it under the terms of the GNU General Public License as published by  *\n#*   the Free Software Foundation; either version 2 of the License, or     *\n#*   (at your option) any later version.                                   *\n#*                                                                         *\n#*   This program is distributed in the hope that it will be useful,       *\n#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n#*   GNU General Public License for more details.                          *\n#*                                                                         *\n#*   You should have received a copy of the GNU General Public License     *\n#*   along with this program; if not, write to the                         *\n#*   Free Software Foundation, Inc.,                                       *\n#*   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *\n#***************************************************************************\n\n# A simple utility to read a list of files (names composed by numeric prescaler arguments) and compose a C source file defining data structures which hold the binary data read from those files.\n\nmy @speed_table = ();\n\nprint <<HEADER;\n/* This file was created automatically by the following script:\n *   $0\n */\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#include \"rlink.h\"\n#include \"rlink_st7.h\"\n\nHEADER\n\nfor $prescaler (sort {$b <=> $a} @ARGV) {\n\tmy(@ary) = (\n\t\tbyte_array_from_file(${prescaler} . \"_init.dtc\"),\n\t\tbyte_array_from_file(${prescaler} . \"_call.dtc\")\n\t);\n\n\tfor $i (@ary) {\n\t\t$i = sprintf(\"%d\", $i);\n\t}\n\t$bytes = join(', ', @ary);\n\t$bytes =~ s/(^|\\s)(.{70}?\\S*)/\\2\\n/go;\t# break up long lines\n\t$bytes =~ s/\\n +/\\n/go;\n\t$bytes =~ s/(^|\\n)/\\1\\t/go;\t\t# format nicely\n\tprintf(\"static const uint8_t dtc_%d[] = {\\n%s\\n};\\n\\n\", $prescaler, $bytes);\n\tpush(@speed_table, sprintf(\"\\tdtc_%d, sizeof(dtc_%d), (ST7_FOSC * 2) / (1000 * %d), %d\\n\", $prescaler, $prescaler, $prescaler, $prescaler));\n}\n\nprintf(\"const struct rlink_speed_table rlink_speed_table[] = { {\\n%s} };\\n\\n\", join(\"}, {\\n\", @speed_table));\nprintf(\"const size_t rlink_speed_table_size = ARRAY_SIZE(rlink_speed_table);\\n\\n\");\n\n\nsub byte_array_from_file {\n\tmy($filename) = @_;\n\n\tmy(@array, $text, $i) = ();\n\n\topen(IN, '<', $filename) || die \"$filename: $!\";\n\tundef($/);\n\t$text = <IN>;\n\tclose(IN);\n\n\tfor($i = 0; $i < length($text); $i++) {\n\t\tpush(@array, ord(substr($text, $i, 1)));\n\t}\n\n\t@array;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/camelcase.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\n# The OpenOCD coding-style rules forbids CamelCase names for symbols,\n# either functions, variables, macros and enums.\n# The script checkpatch detects the CamelCase symbols.\n# This file contains the exceptions to the coding-style, mainly due\n# to external dependencies and libraries.\n\n# format types from inttypes.h (only some are already used)\nPRId8\nPRId16\nPRId32\nPRId64\nPRIi8\nPRIi16\nPRIi32\nPRIi64\nPRIo8\nPRIo16\nPRIo32\nPRIo64\nPRIu8\nPRIu16\nPRIu32\nPRIu64\nPRIx8\nPRIx16\nPRIx32\nPRIx64\nPRIX8\nPRIX16\nPRIX32\nPRIX64\nSCNd8\nSCNd16\nSCNd32\nSCNd64\nSCNi8\nSCNi16\nSCNi32\nSCNi64\nSCNo8\nSCNo16\nSCNo32\nSCNo64\nSCNu8\nSCNu16\nSCNu32\nSCNu64\nSCNx8\nSCNx16\nSCNx32\nSCNx64\nSCNX8\nSCNX16\nSCNX32\nSCNX64\n\n# OpenOCD format types\nTARGET_PRIdADDR\nTARGET_PRIoADDR\nTARGET_PRIuADDR\nTARGET_PRIxADDR\n\n# from libusb.h\nbcdDevice\nbConfigurationValue\nbEndpointAddress\nbInterfaceClass\nbInterfaceNumber\nbInterfaceProtocol\nbInterfaceSubClass\nbmAttributes\nbNumConfigurations\nbNumEndpoints\nbNumInterfaces\nidProduct\nidVendor\niInterface\niProduct\niSerialNumber\nwMaxPacketSize\n\n# from jimtcl/jim.h and jimtcl/jim-eventloop.h\nJim_AppendString\nJim_AppendStrings\nJim_Cmd\nJim_CmdPrivData\nJim_CmdProc\nJim_CompareStringImmediate\nJim_ConcatObj\nJim_CreateCommand\nJim_CreateInterp\nJim_DecrRefCount\nJim_DelCmdProc\nJim_DeleteAssocData\nJim_DeleteCommand\nJim_DictAddElement\nJim_DictPairs\nJim_DuplicateObj\nJim_Eval\nJim_EvalExpression\nJim_EvalObj\nJim_EvalObjPrefix\nJim_EvalSource\nJim_Eval_Named\nJim_FreeInterp\nJim_FreeObj\nJim_GetAssocData\nJim_GetCommand\nJim_GetDouble\nJim_GetEnum\nJim_GetExitCode\nJim_GetGlobalVariableStr\nJim_GetIntRepPtr\nJim_GetLong\nJim_GetResult\nJim_GetString\nJim_GetVariable\nJim_GetWide\nJim_IncrRefCount\nJim_InitStaticExtensions\nJim_Interp\nJim_ListAppendElement\nJim_ListGetIndex\nJim_ListLength\nJim_MakeErrorMessage\nJim_NewDictObj\nJim_NewEmptyStringObj\nJim_NewIntObj\nJim_NewListObj\nJim_NewStringObj\nJim_NewWideObj\nJim_Obj\nJim_ProcessEvents\nJim_RegisterCoreCommands\nJim_SetAssocData\nJim_SetEmptyResult\nJim_SetResult\nJim_SetResultBool\nJim_SetResultFormatted\nJim_SetResultInt\nJim_SetResultString\nJim_SetVariable\nJim_String\nJim_WrongNumArgs\ncmdProc\ncurrentScriptObj\ndelProc\nemptyObj\nprivData\nreturnCode\ntypePtr\n\n# from elf.h\nElf32_Addr\nElf32_Ehdr\nElf32_Half\nElf32_Off\nElf32_Phdr\nElf32_Size\nElf32_Word\nElf64_Addr\nElf64_Ehdr\nElf64_Half\nElf64_Off\nElf64_Phdr\nElf64_Word\nElf64_Xword\n\n# for BSD's\n__FreeBSD__\n__FreeBSD_kernel__\n\n# for Windows\nCreateFile\nCloseHandle\nFormatMessage\nGetModuleFileName\nGetSystemTimeAsFileTime\nGetTickCount\nGetVersionEx\nHighPart\nLowPart\nMsgWaitForMultipleObjects\nPeekMessage\nPeekNamedPipe\nQuadPart\nSetConsoleCtrlHandler\nSleep\nWaitForSingleObject\nWSACleanup\nWSAGetLastError\nWSAStartup\ndwHighDateTime\ndwLowDateTime\ndwPlatformId\ndwOSVersionInfoSize\n\n# OpenOCD exceptions that should be removed\nKiB\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/checkpatch.pl",
    "content": "#!/usr/bin/env perl\n# SPDX-License-Identifier: GPL-2.0\n#\n# (c) 2001, Dave Jones. (the file handling bit)\n# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)\n# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)\n# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>\n# (c) 2010-2018 Joe Perches <joe@perches.com>\n\nuse strict;\nuse warnings;\nuse POSIX;\nuse File::Basename;\nuse Cwd 'abs_path';\nuse Term::ANSIColor qw(:constants);\nuse Encode qw(decode encode);\n\nmy $P = $0;\nmy $D = dirname(abs_path($P));\n\nmy $V = '0.32';\n\nuse Getopt::Long qw(:config no_auto_abbrev);\n\n# ATTENTION: easily track modification to this script for OpenOCD.\n# When possible, don't modify the existing code, don't change its indentation,\n# but remove it enclosing it within:\n#\n# if (!$OpenOCD) {\n# original_code;\n# } # !$OpenOCD\n#\n# Mark every addition within comments\n# # OpenOCD specific: Begin[: additional comment]\n# # OpenOCD specific: End\nmy $OpenOCD = 1;\n\nmy $quiet = 0;\nmy $verbose = 0;\nmy %verbose_messages = ();\nmy %verbose_emitted = ();\nmy $tree = 1;\nmy $chk_signoff = 1;\nmy $chk_patch = 1;\nmy $tst_only;\nmy $emacs = 0;\nmy $terse = 0;\nmy $showfile = 0;\nmy $file = 0;\nmy $git = 0;\nmy %git_commits = ();\nmy $check = 0;\nmy $check_orig = 0;\nmy $summary = 1;\nmy $mailback = 0;\nmy $summary_file = 0;\nmy $show_types = 0;\nmy $list_types = 0;\nmy $fix = 0;\nmy $fix_inplace = 0;\nmy $root;\nmy $gitroot = $ENV{'GIT_DIR'};\n$gitroot = \".git\" if !defined($gitroot);\nmy %debug;\nmy %camelcase = ();\nmy %use_type = ();\nmy @use = ();\nmy %ignore_type = ();\nmy @ignore = ();\nmy $help = 0;\nmy $configuration_file = \".checkpatch.conf\";\nmy $max_line_length = 100;\nmy $ignore_perl_version = 0;\nmy $minimum_perl_version = 5.10.0;\nmy $min_conf_desc_length = 4;\nmy $spelling_file = \"$D/spelling.txt\";\nmy $codespell = 0;\nmy $codespellfile = \"/usr/share/codespell/dictionary.txt\";\nmy $user_codespellfile = \"\";\nmy $conststructsfile = \"$D/const_structs.checkpatch\";\nif (!$OpenOCD) {\nmy $docsfile = \"$D/../Documentation/dev-tools/checkpatch.rst\";\n} # !$OpenOCD\n# OpenOCD Specific: Begin\nmy $docsfile = \"$D/../../doc/checkpatch.rst\";\n# OpenOCD Specific: End\nmy $typedefsfile;\nmy $color = \"auto\";\nmy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE\n# git output parsing needs US English output, so first set backtick child process LANGUAGE\nmy $git_command ='export LANGUAGE=en_US.UTF-8; git';\nmy $tabsize = 8;\nmy ${CONFIG_} = \"CONFIG_\";\n\nsub help {\n\tmy ($exitcode) = @_;\n\n\tprint << \"EOM\";\nUsage: $P [OPTION]... [FILE]...\nVersion: $V\n\nOptions:\n  -q, --quiet                quiet\n  -v, --verbose              verbose mode\n  --no-tree                  run without an OpenOCD tree\n  --no-signoff               do not check for 'Signed-off-by' line\n  --patch                    treat FILE as patchfile (default)\n  --emacs                    emacs compile window format\n  --terse                    one line per report\n  --showfile                 emit diffed file position, not input file position\n  -g, --git                  treat FILE as a single commit or git revision range\n                             single git commit with:\n                               <rev>\n                               <rev>^\n                               <rev>~n\n                             multiple git commits with:\n                               <rev1>..<rev2>\n                               <rev1>...<rev2>\n                               <rev>-<count>\n                             git merges are ignored\n  -f, --file                 treat FILE as regular source file\n  --subjective, --strict     enable more subjective tests\n  --list-types               list the possible message types\n  --types TYPE(,TYPE2...)    show only these comma separated message types\n  --ignore TYPE(,TYPE2...)   ignore various comma separated message types\n  --show-types               show the specific message type in the output\n  --max-line-length=n        set the maximum line length, (default $max_line_length)\n                             if exceeded, warn on patches\n                             requires --strict for use with --file\n  --min-conf-desc-length=n   set the min description length, if shorter, warn\n  --tab-size=n               set the number of spaces for tab (default $tabsize)\n  --root=PATH                PATH to the OpenOCD tree root\n  --no-summary               suppress the per-file summary\n  --mailback                 only produce a report in case of warnings/errors\n  --summary-file             include the filename in summary\n  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of\n                             'values', 'possible', 'type', and 'attr' (default\n                             is all off)\n  --test-only=WORD           report only warnings/errors containing WORD\n                             literally\n  --fix                      EXPERIMENTAL - may create horrible results\n                             If correctable single-line errors exist, create\n                             \"<inputfile>.EXPERIMENTAL-checkpatch-fixes\"\n                             with potential errors corrected to the preferred\n                             checkpatch style\n  --fix-inplace              EXPERIMENTAL - may create horrible results\n                             Is the same as --fix, but overwrites the input\n                             file.  It's your fault if there's no backup or git\n  --ignore-perl-version      override checking of perl version.  expect\n                             runtime errors.\n  --codespell                Use the codespell dictionary for spelling/typos\n                             (default:$codespellfile)\n  --codespellfile            Use this codespell dictionary\n  --typedefsfile             Read additional types from this file\n  --color[=WHEN]             Use colors 'always', 'never', or only when output\n                             is a terminal ('auto'). Default is 'auto'.\n  --kconfig-prefix=WORD      use WORD as a prefix for Kconfig symbols (default\n                             ${CONFIG_})\n  -h, --help, --version      display this help and exit\n\nWhen FILE is - read standard input.\nEOM\n\n\texit($exitcode);\n}\n\nsub uniq {\n\tmy %seen;\n\treturn grep { !$seen{$_}++ } @_;\n}\n\nsub list_types {\n\tmy ($exitcode) = @_;\n\n\tmy $count = 0;\n\n\tlocal $/ = undef;\n\n\topen(my $script, '<', abs_path($P)) or\n\t    die \"$P: Can't read '$P' $!\\n\";\n\n\tmy $text = <$script>;\n\tclose($script);\n\n\tmy %types = ();\n\t# Also catch when type or level is passed through a variable\n\twhile ($text =~ /(?:(\\bCHK|\\bWARN|\\bERROR|&\\{\\$msg_level})\\s*\\(|\\$msg_type\\s*=)\\s*\"([^\"]+)\"/g) {\n\t\tif (defined($1)) {\n\t\t\tif (exists($types{$2})) {\n\t\t\t\t$types{$2} .= \",$1\" if ($types{$2} ne $1);\n\t\t\t} else {\n\t\t\t\t$types{$2} = $1;\n\t\t\t}\n\t\t} else {\n\t\t\t$types{$2} = \"UNDETERMINED\";\n\t\t}\n\t}\n\n\tprint(\"#\\tMessage type\\n\\n\");\n\tif ($color) {\n\t\tprint(\" ( Color coding: \");\n\t\tprint(RED . \"ERROR\" . RESET);\n\t\tprint(\" | \");\n\t\tprint(YELLOW . \"WARNING\" . RESET);\n\t\tprint(\" | \");\n\t\tprint(GREEN . \"CHECK\" . RESET);\n\t\tprint(\" | \");\n\t\tprint(\"Multiple levels / Undetermined\");\n\t\tprint(\" )\\n\\n\");\n\t}\n\n\tforeach my $type (sort keys %types) {\n\t\tmy $orig_type = $type;\n\t\tif ($color) {\n\t\t\tmy $level = $types{$type};\n\t\t\tif ($level eq \"ERROR\") {\n\t\t\t\t$type = RED . $type . RESET;\n\t\t\t} elsif ($level eq \"WARN\") {\n\t\t\t\t$type = YELLOW . $type . RESET;\n\t\t\t} elsif ($level eq \"CHK\") {\n\t\t\t\t$type = GREEN . $type . RESET;\n\t\t\t}\n\t\t}\n\t\tprint(++$count . \"\\t\" . $type . \"\\n\");\n\t\tif ($verbose && exists($verbose_messages{$orig_type})) {\n\t\t\tmy $message = $verbose_messages{$orig_type};\n\t\t\t$message =~ s/\\n/\\n\\t/g;\n\t\t\tprint(\"\\t\" . $message . \"\\n\\n\");\n\t\t}\n\t}\n\n\texit($exitcode);\n}\n\nmy $conf = which_conf($configuration_file);\nif (-f $conf) {\n\tmy @conf_args;\n\topen(my $conffile, '<', \"$conf\")\n\t    or warn \"$P: Can't find a readable $configuration_file file $!\\n\";\n\n\twhile (<$conffile>) {\n\t\tmy $line = $_;\n\n\t\t$line =~ s/\\s*\\n?$//g;\n\t\t$line =~ s/^\\s*//g;\n\t\t$line =~ s/\\s+/ /g;\n\n\t\tnext if ($line =~ m/^\\s*#/);\n\t\tnext if ($line =~ m/^\\s*$/);\n\n\t\tmy @words = split(\" \", $line);\n\t\tforeach my $word (@words) {\n\t\t\tlast if ($word =~ m/^#/);\n\t\t\tpush (@conf_args, $word);\n\t\t}\n\t}\n\tclose($conffile);\n\tunshift(@ARGV, @conf_args) if @conf_args;\n}\n\nsub load_docs {\n\topen(my $docs, '<', \"$docsfile\")\n\t    or warn \"$P: Can't read the documentation file $docsfile $!\\n\";\n\n\tmy $type = '';\n\tmy $desc = '';\n\tmy $in_desc = 0;\n\n\twhile (<$docs>) {\n\t\tchomp;\n\t\tmy $line = $_;\n\t\t$line =~ s/\\s+$//;\n\n\t\tif ($line =~ /^\\s*\\*\\*(.+)\\*\\*$/) {\n\t\t\tif ($desc ne '') {\n\t\t\t\t$verbose_messages{$type} = trim($desc);\n\t\t\t}\n\t\t\t$type = $1;\n\t\t\t$desc = '';\n\t\t\t$in_desc = 1;\n\t\t} elsif ($in_desc) {\n\t\t\tif ($line =~ /^(?:\\s{4,}|$)/) {\n\t\t\t\t$line =~ s/^\\s{4}//;\n\t\t\t\t$desc .= $line;\n\t\t\t\t$desc .= \"\\n\";\n\t\t\t} else {\n\t\t\t\t$verbose_messages{$type} = trim($desc);\n\t\t\t\t$type = '';\n\t\t\t\t$desc = '';\n\t\t\t\t$in_desc = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ($desc ne '') {\n\t\t$verbose_messages{$type} = trim($desc);\n\t}\n\tclose($docs);\n}\n\n# Perl's Getopt::Long allows options to take optional arguments after a space.\n# Prevent --color by itself from consuming other arguments\nforeach (@ARGV) {\n\tif ($_ eq \"--color\" || $_ eq \"-color\") {\n\t\t$_ = \"--color=$color\";\n\t}\n}\n\nGetOptions(\n\t'q|quiet+'\t=> \\$quiet,\n\t'v|verbose!'\t=> \\$verbose,\n\t'tree!'\t\t=> \\$tree,\n\t'signoff!'\t=> \\$chk_signoff,\n\t'patch!'\t=> \\$chk_patch,\n\t'emacs!'\t=> \\$emacs,\n\t'terse!'\t=> \\$terse,\n\t'showfile!'\t=> \\$showfile,\n\t'f|file!'\t=> \\$file,\n\t'g|git!'\t=> \\$git,\n\t'subjective!'\t=> \\$check,\n\t'strict!'\t=> \\$check,\n\t'ignore=s'\t=> \\@ignore,\n\t'types=s'\t=> \\@use,\n\t'show-types!'\t=> \\$show_types,\n\t'list-types!'\t=> \\$list_types,\n\t'max-line-length=i' => \\$max_line_length,\n\t'min-conf-desc-length=i' => \\$min_conf_desc_length,\n\t'tab-size=i'\t=> \\$tabsize,\n\t'root=s'\t=> \\$root,\n\t'summary!'\t=> \\$summary,\n\t'mailback!'\t=> \\$mailback,\n\t'summary-file!'\t=> \\$summary_file,\n\t'fix!'\t\t=> \\$fix,\n\t'fix-inplace!'\t=> \\$fix_inplace,\n\t'ignore-perl-version!' => \\$ignore_perl_version,\n\t'debug=s'\t=> \\%debug,\n\t'test-only=s'\t=> \\$tst_only,\n\t'codespell!'\t=> \\$codespell,\n\t'codespellfile=s'\t=> \\$user_codespellfile,\n\t'typedefsfile=s'\t=> \\$typedefsfile,\n\t'color=s'\t=> \\$color,\n\t'no-color'\t=> \\$color,\t#keep old behaviors of -nocolor\n\t'nocolor'\t=> \\$color,\t#keep old behaviors of -nocolor\n\t'kconfig-prefix=s'\t=> \\${CONFIG_},\n\t'h|help'\t=> \\$help,\n\t'version'\t=> \\$help\n) or $help = 2;\n\nif ($user_codespellfile) {\n\t# Use the user provided codespell file unconditionally\n\t$codespellfile = $user_codespellfile;\n} elsif (!(-f $codespellfile)) {\n\t# If /usr/share/codespell/dictionary.txt is not present, try to find it\n\t# under codespell's install directory: <codespell_root>/data/dictionary.txt\n\tif (($codespell || $help) && which(\"python3\") ne \"\") {\n\t\tmy $python_codespell_dict = << \"EOF\";\n\nimport os.path as op\nimport codespell_lib\ncodespell_dir = op.dirname(codespell_lib.__file__)\ncodespell_file = op.join(codespell_dir, 'data', 'dictionary.txt')\nprint(codespell_file, end='')\nEOF\n\n\t\tmy $codespell_dict = `python3 -c \"$python_codespell_dict\" 2> /dev/null`;\n\t\t$codespellfile = $codespell_dict if (-f $codespell_dict);\n\t}\n}\n\n# $help is 1 if either -h, --help or --version is passed as option - exitcode: 0\n# $help is 2 if invalid option is passed - exitcode: 1\nhelp($help - 1) if ($help);\n\ndie \"$P: --git cannot be used with --file or --fix\\n\" if ($git && ($file || $fix));\ndie \"$P: --verbose cannot be used with --terse\\n\" if ($verbose && $terse);\n\nif ($color =~ /^[01]$/) {\n\t$color = !$color;\n} elsif ($color =~ /^always$/i) {\n\t$color = 1;\n} elsif ($color =~ /^never$/i) {\n\t$color = 0;\n} elsif ($color =~ /^auto$/i) {\n\t$color = (-t STDOUT);\n} else {\n\tdie \"$P: Invalid color mode: $color\\n\";\n}\n\nload_docs() if ($verbose);\nlist_types(0) if ($list_types);\n\n$fix = 1 if ($fix_inplace);\n$check_orig = $check;\n\nmy $exit = 0;\n\nmy $perl_version_ok = 1;\nif ($^V && $^V lt $minimum_perl_version) {\n\t$perl_version_ok = 0;\n\tprintf \"$P: requires at least perl version %vd\\n\", $minimum_perl_version;\n\texit(1) if (!$ignore_perl_version);\n}\n\n#if no filenames are given, push '-' to read patch from stdin\nif ($#ARGV < 0) {\n\tpush(@ARGV, '-');\n}\n\n# skip TAB size 1 to avoid additional checks on $tabsize - 1\ndie \"$P: Invalid TAB size: $tabsize\\n\" if ($tabsize < 2);\n\nsub hash_save_array_words {\n\tmy ($hashRef, $arrayRef) = @_;\n\n\tmy @array = split(/,/, join(',', @$arrayRef));\n\tforeach my $word (@array) {\n\t\t$word =~ s/\\s*\\n?$//g;\n\t\t$word =~ s/^\\s*//g;\n\t\t$word =~ s/\\s+/ /g;\n\t\t$word =~ tr/[a-z]/[A-Z]/;\n\n\t\tnext if ($word =~ m/^\\s*#/);\n\t\tnext if ($word =~ m/^\\s*$/);\n\n\t\t$hashRef->{$word}++;\n\t}\n}\n\nsub hash_show_words {\n\tmy ($hashRef, $prefix) = @_;\n\n\tif (keys %$hashRef) {\n\t\tprint \"\\nNOTE: $prefix message types:\";\n\t\tforeach my $word (sort keys %$hashRef) {\n\t\t\tprint \" $word\";\n\t\t}\n\t\tprint \"\\n\";\n\t}\n}\n\nhash_save_array_words(\\%ignore_type, \\@ignore);\nhash_save_array_words(\\%use_type, \\@use);\n\nmy $dbg_values = 0;\nmy $dbg_possible = 0;\nmy $dbg_type = 0;\nmy $dbg_attr = 0;\nfor my $key (keys %debug) {\n\t## no critic\n\teval \"\\${dbg_$key} = '$debug{$key}';\";\n\tdie \"$@\" if ($@);\n}\n\nmy $rpt_cleaners = 0;\n\nif ($terse) {\n\t$emacs = 1;\n\t$quiet++;\n}\n\nif ($tree) {\n\tif (defined $root) {\n\t\tif (!top_of_kernel_tree($root)) {\n\t\t\tdie \"$P: $root: --root does not point at a valid tree\\n\";\n\t\t}\n\t} else {\n\t\tif (top_of_kernel_tree('.')) {\n\t\t\t$root = '.';\n\t\t# OpenOCD specific: Begin: replace s\"/scripts/\"/tools/scripts/\"\n\t\t} elsif ($0 =~ m@(.*)/tools/scripts/[^/]*$@ &&\n\t\t\t\t\t\ttop_of_kernel_tree($1)) {\n\t\t\t$root = $1;\n\t\t}\n\t\t# OpenOCD specific: End\n\t}\n\n\tif (!defined $root) {\n\t\tprint \"Must be run from the top-level dir. of an OpenOCD tree\\n\";\n\t\texit(2);\n\t}\n}\n\nmy $emitted_corrupt = 0;\n\nour $Ident\t= qr{\n\t\t\t[A-Za-z_][A-Za-z\\d_]*\n\t\t\t(?:\\s*\\#\\#\\s*[A-Za-z_][A-Za-z\\d_]*)*\n\t\t}x;\nour $Storage\t= qr{extern|static|asmlinkage};\nour $Sparse\t= qr{\n\t\t\t__user|\n\t\t\t__kernel|\n\t\t\t__force|\n\t\t\t__iomem|\n\t\t\t__must_check|\n\t\t\t__kprobes|\n\t\t\t__ref|\n\t\t\t__refconst|\n\t\t\t__refdata|\n\t\t\t__rcu|\n\t\t\t__private\n\t\t}x;\nour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};\nour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\\b)};\nour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\\b)};\nour $InitAttributeInit = qr{$InitAttributePrefix(?:init\\b)};\nour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};\n\n# Notes to $Attribute:\n# We need \\b after 'init' otherwise 'initconst' will cause a false positive in a check\nour $Attribute\t= qr{\n\t\t\tconst|\n\t\t\tvolatile|\n\t\t\t__percpu|\n\t\t\t__nocast|\n\t\t\t__safe|\n\t\t\t__bitwise|\n\t\t\t__packed__|\n\t\t\t__packed2__|\n\t\t\t__naked|\n\t\t\t__maybe_unused|\n\t\t\t__always_unused|\n\t\t\t__noreturn|\n\t\t\t__used|\n\t\t\t__cold|\n\t\t\t__pure|\n\t\t\t__noclone|\n\t\t\t__deprecated|\n\t\t\t__read_mostly|\n\t\t\t__ro_after_init|\n\t\t\t__kprobes|\n\t\t\t$InitAttribute|\n\t\t\t____cacheline_aligned|\n\t\t\t____cacheline_aligned_in_smp|\n\t\t\t____cacheline_internodealigned_in_smp|\n\t\t\t__weak|\n\t\t\t__alloc_size\\s*\\(\\s*\\d+\\s*(?:,\\s*\\d+\\s*)?\\)\n\t\t  }x;\nour $Modifier;\nour $Inline\t= qr{inline|__always_inline|noinline|__inline|__inline__};\nour $Member\t= qr{->$Ident|\\.$Ident|\\[[^]]*\\]};\nour $Lval\t= qr{$Ident(?:$Member)*};\n\nour $Int_type\t= qr{(?i)llu|ull|ll|lu|ul|l|u};\nour $Binary\t= qr{(?i)0b[01]+$Int_type?};\nour $Hex\t= qr{(?i)0x[0-9a-f]+$Int_type?};\nour $Int\t= qr{[0-9]+$Int_type?};\nour $Octal\t= qr{0[0-7]+$Int_type?};\nour $String\t= qr{(?:\\b[Lu])?\"[X\\t]*\"};\nour $Float_hex\t= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};\nour $Float_dec\t= qr{(?i)(?:[0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+)(?:e-?[0-9]+)?[fl]?};\nour $Float_int\t= qr{(?i)[0-9]+e-?[0-9]+[fl]?};\nour $Float\t= qr{$Float_hex|$Float_dec|$Float_int};\nour $Constant\t= qr{$Float|$Binary|$Octal|$Hex|$Int};\nour $Assignment\t= qr{\\*\\=|/=|%=|\\+=|-=|<<=|>>=|&=|\\^=|\\|=|=};\nour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};\nour $Arithmetic = qr{\\+|-|\\*|\\/|%};\nour $Operators\t= qr{\n\t\t\t<=|>=|==|!=|\n\t\t\t=>|->|<<|>>|<|>|!|~|\n\t\t\t&&|\\|\\||,|\\^|\\+\\+|--|&|\\||$Arithmetic\n\t\t  }x;\n\nour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;\n\nour $BasicType;\nour $NonptrType;\nour $NonptrTypeMisordered;\nour $NonptrTypeWithAttr;\nour $Type;\nour $TypeMisordered;\nour $Declare;\nour $DeclareMisordered;\n\nour $NON_ASCII_UTF8\t= qr{\n\t[\\xC2-\\xDF][\\x80-\\xBF]               # non-overlong 2-byte\n\t|  \\xE0[\\xA0-\\xBF][\\x80-\\xBF]        # excluding overlongs\n\t| [\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2}  # straight 3-byte\n\t|  \\xED[\\x80-\\x9F][\\x80-\\xBF]        # excluding surrogates\n\t|  \\xF0[\\x90-\\xBF][\\x80-\\xBF]{2}     # planes 1-3\n\t| [\\xF1-\\xF3][\\x80-\\xBF]{3}          # planes 4-15\n\t|  \\xF4[\\x80-\\x8F][\\x80-\\xBF]{2}     # plane 16\n}x;\n\nour $UTF8\t= qr{\n\t[\\x09\\x0A\\x0D\\x20-\\x7E]              # ASCII\n\t| $NON_ASCII_UTF8\n}x;\n\nour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};\nour $typeOtherOSTypedefs = qr{(?x:\n\tu_(?:char|short|int|long) |          # bsd\n\tu(?:nchar|short|int|long)            # sysv\n)};\nour $typeKernelTypedefs = qr{(?x:\n\t(?:__)?(?:u|s|be|le)(?:8|16|32|64)|\n\tatomic_t\n)};\nour $typeTypedefs = qr{(?x:\n\t$typeC99Typedefs\\b|\n\t$typeOtherOSTypedefs\\b|\n\t$typeKernelTypedefs\\b\n)};\n\nour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\\b};\n\nif (!$OpenOCD) {\nour $logFunctions = qr{(?x:\n\tprintk(?:_ratelimited|_once|_deferred_once|_deferred|)|\n\t(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|\n\tTP_printk|\n\tWARN(?:_RATELIMIT|_ONCE|)|\n\tpanic|\n\tMODULE_[A-Z_]+|\n\tseq_vprintf|seq_printf|seq_puts\n)};\n} # !$OpenOCD\n# OpenOCD specific: Begin: list log functions\nour $logFunctions = qr{(?x:\n\tLOG_(?:TARGET_|)(?:DEBUG_IO|DEBUG|INFO|WARNING|ERROR|USER|USER_N|OUTPUT)\n)};\n# OpenOCD specific: End\n\nour $allocFunctions = qr{(?x:\n\t(?:(?:devm_)?\n\t\t(?:kv|k|v)[czm]alloc(?:_array)?(?:_node)? |\n\t\tkstrdup(?:_const)? |\n\t\tkmemdup(?:_nul)?) |\n\t(?:\\w+)?alloc_skb(?:_ip_align)? |\n\t\t\t\t# dev_alloc_skb/netdev_alloc_skb, et al\n\tdma_alloc_coherent\n)};\n\nour $signature_tags = qr{(?xi:\n\tSigned-off-by:|\n\tCo-developed-by:|\n\tAcked-by:|\n\tTested-by:|\n\tReviewed-by:|\n\tReported-by:|\n\tSuggested-by:|\n\tTo:|\n\tCc:\n)};\n\nour $tracing_logging_tags = qr{(?xi:\n\t[=-]*> |\n\t<[=-]* |\n\t\\[ |\n\t\\] |\n\tstart |\n\tcalled |\n\tentered |\n\tentry |\n\tenter |\n\tin |\n\tinside |\n\there |\n\tbegin |\n\texit |\n\tend |\n\tdone |\n\tleave |\n\tcompleted |\n\tout |\n\treturn |\n\t[\\.\\!:\\s]*\n)};\n\nsub edit_distance_min {\n\tmy (@arr) = @_;\n\tmy $len = scalar @arr;\n\tif ((scalar @arr) < 1) {\n\t\t# if underflow, return\n\t\treturn;\n\t}\n\tmy $min = $arr[0];\n\tfor my $i (0 .. ($len-1)) {\n\t\tif ($arr[$i] < $min) {\n\t\t\t$min = $arr[$i];\n\t\t}\n\t}\n\treturn $min;\n}\n\nsub get_edit_distance {\n\tmy ($str1, $str2) = @_;\n\t$str1 = lc($str1);\n\t$str2 = lc($str2);\n\t$str1 =~ s/-//g;\n\t$str2 =~ s/-//g;\n\tmy $len1 = length($str1);\n\tmy $len2 = length($str2);\n\t# two dimensional array storing minimum edit distance\n\tmy @distance;\n\tfor my $i (0 .. $len1) {\n\t\tfor my $j (0 .. $len2) {\n\t\t\tif ($i == 0) {\n\t\t\t\t$distance[$i][$j] = $j;\n\t\t\t} elsif ($j == 0) {\n\t\t\t\t$distance[$i][$j] = $i;\n\t\t\t} elsif (substr($str1, $i-1, 1) eq substr($str2, $j-1, 1)) {\n\t\t\t\t$distance[$i][$j] = $distance[$i - 1][$j - 1];\n\t\t\t} else {\n\t\t\t\tmy $dist1 = $distance[$i][$j - 1]; #insert distance\n\t\t\t\tmy $dist2 = $distance[$i - 1][$j]; # remove\n\t\t\t\tmy $dist3 = $distance[$i - 1][$j - 1]; #replace\n\t\t\t\t$distance[$i][$j] = 1 + edit_distance_min($dist1, $dist2, $dist3);\n\t\t\t}\n\t\t}\n\t}\n\treturn $distance[$len1][$len2];\n}\n\nsub find_standard_signature {\n\tmy ($sign_off) = @_;\n\tmy @standard_signature_tags = (\n\t\t'Signed-off-by:', 'Co-developed-by:', 'Acked-by:', 'Tested-by:',\n\t\t'Reviewed-by:', 'Reported-by:', 'Suggested-by:'\n\t);\n\tforeach my $signature (@standard_signature_tags) {\n\t\treturn $signature if (get_edit_distance($sign_off, $signature) <= 2);\n\t}\n\n\treturn \"\";\n}\n\nour @typeListMisordered = (\n\tqr{char\\s+(?:un)?signed},\n\tqr{int\\s+(?:(?:un)?signed\\s+)?short\\s},\n\tqr{int\\s+short(?:\\s+(?:un)?signed)},\n\tqr{short\\s+int(?:\\s+(?:un)?signed)},\n\tqr{(?:un)?signed\\s+int\\s+short},\n\tqr{short\\s+(?:un)?signed},\n\tqr{long\\s+int\\s+(?:un)?signed},\n\tqr{int\\s+long\\s+(?:un)?signed},\n\tqr{long\\s+(?:un)?signed\\s+int},\n\tqr{int\\s+(?:un)?signed\\s+long},\n\tqr{int\\s+(?:un)?signed},\n\tqr{int\\s+long\\s+long\\s+(?:un)?signed},\n\tqr{long\\s+long\\s+int\\s+(?:un)?signed},\n\tqr{long\\s+long\\s+(?:un)?signed\\s+int},\n\tqr{long\\s+long\\s+(?:un)?signed},\n\tqr{long\\s+(?:un)?signed},\n);\n\nour @typeList = (\n\tqr{void},\n\tqr{(?:(?:un)?signed\\s+)?char},\n\tqr{(?:(?:un)?signed\\s+)?short\\s+int},\n\tqr{(?:(?:un)?signed\\s+)?short},\n\tqr{(?:(?:un)?signed\\s+)?int},\n\tqr{(?:(?:un)?signed\\s+)?long\\s+int},\n\tqr{(?:(?:un)?signed\\s+)?long\\s+long\\s+int},\n\tqr{(?:(?:un)?signed\\s+)?long\\s+long},\n\tqr{(?:(?:un)?signed\\s+)?long},\n\tqr{(?:un)?signed},\n\tqr{float},\n\tqr{double},\n\tqr{bool},\n\tqr{struct\\s+$Ident},\n\tqr{union\\s+$Ident},\n\tqr{enum\\s+$Ident},\n\tqr{${Ident}_t},\n\tqr{${Ident}_handler},\n\tqr{${Ident}_handler_fn},\n\t@typeListMisordered,\n);\n\nour $C90_int_types = qr{(?x:\n\tlong\\s+long\\s+int\\s+(?:un)?signed|\n\tlong\\s+long\\s+(?:un)?signed\\s+int|\n\tlong\\s+long\\s+(?:un)?signed|\n\t(?:(?:un)?signed\\s+)?long\\s+long\\s+int|\n\t(?:(?:un)?signed\\s+)?long\\s+long|\n\tint\\s+long\\s+long\\s+(?:un)?signed|\n\tint\\s+(?:(?:un)?signed\\s+)?long\\s+long|\n\n\tlong\\s+int\\s+(?:un)?signed|\n\tlong\\s+(?:un)?signed\\s+int|\n\tlong\\s+(?:un)?signed|\n\t(?:(?:un)?signed\\s+)?long\\s+int|\n\t(?:(?:un)?signed\\s+)?long|\n\tint\\s+long\\s+(?:un)?signed|\n\tint\\s+(?:(?:un)?signed\\s+)?long|\n\n\tint\\s+(?:un)?signed|\n\t(?:(?:un)?signed\\s+)?int\n)};\n\nour @typeListFile = ();\nour @typeListWithAttr = (\n\t@typeList,\n\tqr{struct\\s+$InitAttribute\\s+$Ident},\n\tqr{union\\s+$InitAttribute\\s+$Ident},\n);\n\nour @modifierList = (\n\tqr{fastcall},\n);\nour @modifierListFile = ();\n\nour @mode_permission_funcs = (\n\t[\"module_param\", 3],\n\t[\"module_param_(?:array|named|string)\", 4],\n\t[\"module_param_array_named\", 5],\n\t[\"debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)\", 2],\n\t[\"proc_create(?:_data|)\", 2],\n\t[\"(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR\", 2],\n\t[\"IIO_DEV_ATTR_[A-Z_]+\", 1],\n\t[\"SENSOR_(?:DEVICE_|)ATTR_2\", 2],\n\t[\"SENSOR_TEMPLATE(?:_2|)\", 3],\n\t[\"__ATTR\", 2],\n);\n\nmy $word_pattern = '\\b[A-Z]?[a-z]{2,}\\b';\n\n#Create a search pattern for all these functions to speed up a loop below\nour $mode_perms_search = \"\";\nforeach my $entry (@mode_permission_funcs) {\n\t$mode_perms_search .= '|' if ($mode_perms_search ne \"\");\n\t$mode_perms_search .= $entry->[0];\n}\n$mode_perms_search = \"(?:${mode_perms_search})\";\n\nour %deprecated_apis = (\n\t\"synchronize_rcu_bh\"\t\t\t=> \"synchronize_rcu\",\n\t\"synchronize_rcu_bh_expedited\"\t\t=> \"synchronize_rcu_expedited\",\n\t\"call_rcu_bh\"\t\t\t\t=> \"call_rcu\",\n\t\"rcu_barrier_bh\"\t\t\t=> \"rcu_barrier\",\n\t\"synchronize_sched\"\t\t\t=> \"synchronize_rcu\",\n\t\"synchronize_sched_expedited\"\t\t=> \"synchronize_rcu_expedited\",\n\t\"call_rcu_sched\"\t\t\t=> \"call_rcu\",\n\t\"rcu_barrier_sched\"\t\t\t=> \"rcu_barrier\",\n\t\"get_state_synchronize_sched\"\t\t=> \"get_state_synchronize_rcu\",\n\t\"cond_synchronize_sched\"\t\t=> \"cond_synchronize_rcu\",\n);\n\n#Create a search pattern for all these strings to speed up a loop below\nour $deprecated_apis_search = \"\";\nforeach my $entry (keys %deprecated_apis) {\n\t$deprecated_apis_search .= '|' if ($deprecated_apis_search ne \"\");\n\t$deprecated_apis_search .= $entry;\n}\n$deprecated_apis_search = \"(?:${deprecated_apis_search})\";\n\nour $mode_perms_world_writable = qr{\n\tS_IWUGO\t\t|\n\tS_IWOTH\t\t|\n\tS_IRWXUGO\t|\n\tS_IALLUGO\t|\n\t0[0-7][0-7][2367]\n}x;\n\nour %mode_permission_string_types = (\n\t\"S_IRWXU\" => 0700,\n\t\"S_IRUSR\" => 0400,\n\t\"S_IWUSR\" => 0200,\n\t\"S_IXUSR\" => 0100,\n\t\"S_IRWXG\" => 0070,\n\t\"S_IRGRP\" => 0040,\n\t\"S_IWGRP\" => 0020,\n\t\"S_IXGRP\" => 0010,\n\t\"S_IRWXO\" => 0007,\n\t\"S_IROTH\" => 0004,\n\t\"S_IWOTH\" => 0002,\n\t\"S_IXOTH\" => 0001,\n\t\"S_IRWXUGO\" => 0777,\n\t\"S_IRUGO\" => 0444,\n\t\"S_IWUGO\" => 0222,\n\t\"S_IXUGO\" => 0111,\n);\n\n#Create a search pattern for all these strings to speed up a loop below\nour $mode_perms_string_search = \"\";\nforeach my $entry (keys %mode_permission_string_types) {\n\t$mode_perms_string_search .= '|' if ($mode_perms_string_search ne \"\");\n\t$mode_perms_string_search .= $entry;\n}\nour $single_mode_perms_string_search = \"(?:${mode_perms_string_search})\";\nour $multi_mode_perms_string_search = qr{\n\t${single_mode_perms_string_search}\n\t(?:\\s*\\|\\s*${single_mode_perms_string_search})*\n}x;\n\nsub perms_to_octal {\n\tmy ($string) = @_;\n\n\treturn trim($string) if ($string =~ /^\\s*0[0-7]{3,3}\\s*$/);\n\n\tmy $val = \"\";\n\tmy $oval = \"\";\n\tmy $to = 0;\n\tmy $curpos = 0;\n\tmy $lastpos = 0;\n\twhile ($string =~ /\\b(($single_mode_perms_string_search)\\b(?:\\s*\\|\\s*)?\\s*)/g) {\n\t\t$curpos = pos($string);\n\t\tmy $match = $2;\n\t\tmy $omatch = $1;\n\t\tlast if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));\n\t\t$lastpos = $curpos;\n\t\t$to |= $mode_permission_string_types{$match};\n\t\t$val .= '\\s*\\|\\s*' if ($val ne \"\");\n\t\t$val .= $match;\n\t\t$oval .= $omatch;\n\t}\n\t$oval =~ s/^\\s*\\|\\s*//;\n\t$oval =~ s/\\s*\\|\\s*$//;\n\treturn sprintf(\"%04o\", $to);\n}\n\nour $allowed_asm_includes = qr{(?x:\n\tirq|\n\tmemory|\n\ttime|\n\treboot\n)};\n# memory.h: ARM has a custom one\n\n# Load common spelling mistakes and build regular expression list.\nmy $misspellings;\nmy %spelling_fix;\n\nif (open(my $spelling, '<', $spelling_file)) {\n\twhile (<$spelling>) {\n\t\tmy $line = $_;\n\n\t\t$line =~ s/\\s*\\n?$//g;\n\t\t$line =~ s/^\\s*//g;\n\n\t\tnext if ($line =~ m/^\\s*#/);\n\t\tnext if ($line =~ m/^\\s*$/);\n\n\t\tmy ($suspect, $fix) = split(/\\|\\|/, $line);\n\n\t\t$spelling_fix{$suspect} = $fix;\n\t}\n\tclose($spelling);\n} else {\n\twarn \"No typos will be found - file '$spelling_file': $!\\n\";\n}\n\nif ($codespell) {\n\tif (open(my $spelling, '<', $codespellfile)) {\n\t\twhile (<$spelling>) {\n\t\t\tmy $line = $_;\n\n\t\t\t$line =~ s/\\s*\\n?$//g;\n\t\t\t$line =~ s/^\\s*//g;\n\n\t\t\tnext if ($line =~ m/^\\s*#/);\n\t\t\tnext if ($line =~ m/^\\s*$/);\n\t\t\tnext if ($line =~ m/, disabled/i);\n\n\t\t\t$line =~ s/,.*$//;\n\n\t\t\tmy ($suspect, $fix) = split(/->/, $line);\n\n\t\t\t$spelling_fix{$suspect} = $fix;\n\t\t}\n\t\tclose($spelling);\n\t} else {\n\t\twarn \"No codespell typos will be found - file '$codespellfile': $!\\n\";\n\t}\n}\n\n$misspellings = join(\"|\", sort keys %spelling_fix) if keys %spelling_fix;\n\nsub read_words {\n\tmy ($wordsRef, $file) = @_;\n\n\tif (open(my $words, '<', $file)) {\n\t\twhile (<$words>) {\n\t\t\tmy $line = $_;\n\n\t\t\t$line =~ s/\\s*\\n?$//g;\n\t\t\t$line =~ s/^\\s*//g;\n\n\t\t\tnext if ($line =~ m/^\\s*#/);\n\t\t\tnext if ($line =~ m/^\\s*$/);\n\t\t\tif ($line =~ /\\s/) {\n\t\t\t\tprint(\"$file: '$line' invalid - ignored\\n\");\n\t\t\t\tnext;\n\t\t\t}\n\n\t\t\t$$wordsRef .= '|' if (defined $$wordsRef);\n\t\t\t$$wordsRef .= $line;\n\t\t}\n\t\tclose($file);\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n# OpenOCD specific: Begin: Load list of allowed CamelCase symbols\nif (show_type(\"CAMELCASE\")) {\n\tmy $allowed_camelcase_file = \"tools/scripts/camelcase.txt\";\n\tif (!$root) {\n\t\twarn \"Ignore list of allowed camelcase symbols.\\n\";\n\t} elsif (open(my $words, '<', \"$root/$allowed_camelcase_file\")) {\n\t\twhile (<$words>) {\n\t\t\t my $line = $_;\n\n\t\t\t$line =~ s/\\s*\\n?$//g;\n\t\t\t$line =~ s/^\\s*//g;\n\n\t\t\tnext if ($line =~ m/^\\s*#/);\n\t\t\tnext if ($line =~ m/^\\s*$/);\n\t\t\tif ($line =~ /\\s/) {\n\t\t\t\tprint(\"$allowed_camelcase_file: '$line' invalid - ignored\\n\");\n\t\t\t\tnext;\n\t\t\t}\n\n\t\t\t$camelcase{$line} = 1;\n\t\t}\n\t\tclose(\"$root/$allowed_camelcase_file\");\n\t} else {\n\t\twarn \"Failed opening file '$root/$allowed_camelcase_file': $!\\n\";\n\t}\n}\n# OpenOCD specific: End\n\nmy $const_structs;\nif (show_type(\"CONST_STRUCT\")) {\n\tread_words(\\$const_structs, $conststructsfile)\n\t    or warn \"No structs that should be const will be found - file '$conststructsfile': $!\\n\";\n}\n\nif (defined($typedefsfile)) {\n\tmy $typeOtherTypedefs;\n\tread_words(\\$typeOtherTypedefs, $typedefsfile)\n\t    or warn \"No additional types will be considered - file '$typedefsfile': $!\\n\";\n\t$typeTypedefs .= '|' . $typeOtherTypedefs if (defined $typeOtherTypedefs);\n}\n\nsub build_types {\n\tmy $mods = \"(?x:  \\n\" . join(\"|\\n  \", (@modifierList, @modifierListFile)) . \"\\n)\";\n\tmy $all = \"(?x:  \\n\" . join(\"|\\n  \", (@typeList, @typeListFile)) . \"\\n)\";\n\tmy $Misordered = \"(?x:  \\n\" . join(\"|\\n  \", @typeListMisordered) . \"\\n)\";\n\tmy $allWithAttr = \"(?x:  \\n\" . join(\"|\\n  \", @typeListWithAttr) . \"\\n)\";\n\t$Modifier\t= qr{(?:$Attribute|$Sparse|$mods)};\n\t$BasicType\t= qr{\n\t\t\t\t(?:$typeTypedefs\\b)|\n\t\t\t\t(?:${all}\\b)\n\t\t}x;\n\t$NonptrType\t= qr{\n\t\t\t(?:$Modifier\\s+|const\\s+)*\n\t\t\t(?:\n\t\t\t\t(?:typeof|__typeof__)\\s*\\([^\\)]*\\)|\n\t\t\t\t(?:$typeTypedefs\\b)|\n\t\t\t\t(?:${all}\\b)\n\t\t\t)\n\t\t\t(?:\\s+$Modifier|\\s+const)*\n\t\t  }x;\n\t$NonptrTypeMisordered\t= qr{\n\t\t\t(?:$Modifier\\s+|const\\s+)*\n\t\t\t(?:\n\t\t\t\t(?:${Misordered}\\b)\n\t\t\t)\n\t\t\t(?:\\s+$Modifier|\\s+const)*\n\t\t  }x;\n\t$NonptrTypeWithAttr\t= qr{\n\t\t\t(?:$Modifier\\s+|const\\s+)*\n\t\t\t(?:\n\t\t\t\t(?:typeof|__typeof__)\\s*\\([^\\)]*\\)|\n\t\t\t\t(?:$typeTypedefs\\b)|\n\t\t\t\t(?:${allWithAttr}\\b)\n\t\t\t)\n\t\t\t(?:\\s+$Modifier|\\s+const)*\n\t\t  }x;\n\t$Type\t= qr{\n\t\t\t$NonptrType\n\t\t\t(?:(?:\\s|\\*|\\[\\])+\\s*const|(?:\\s|\\*\\s*(?:const\\s*)?|\\[\\])+|(?:\\s*\\[\\s*\\])+){0,4}\n\t\t\t(?:\\s+$Inline|\\s+$Modifier)*\n\t\t  }x;\n\t$TypeMisordered\t= qr{\n\t\t\t$NonptrTypeMisordered\n\t\t\t(?:(?:\\s|\\*|\\[\\])+\\s*const|(?:\\s|\\*\\s*(?:const\\s*)?|\\[\\])+|(?:\\s*\\[\\s*\\])+){0,4}\n\t\t\t(?:\\s+$Inline|\\s+$Modifier)*\n\t\t  }x;\n\t$Declare\t= qr{(?:$Storage\\s+(?:$Inline\\s+)?)?$Type};\n\t$DeclareMisordered\t= qr{(?:$Storage\\s+(?:$Inline\\s+)?)?$TypeMisordered};\n}\nbuild_types();\n\nour $Typecast\t= qr{\\s*(\\(\\s*$NonptrType\\s*\\)){0,1}\\s*};\n\n# Using $balanced_parens, $LvalOrFunc, or $FuncArg\n# requires at least perl version v5.10.0\n# Any use must be runtime checked with $^V\n\nour $balanced_parens = qr/(\\((?:[^\\(\\)]++|(?-1))*\\))/;\nour $LvalOrFunc\t= qr{((?:[\\&\\*]\\s*)?$Lval)\\s*($balanced_parens{0,1})\\s*};\nour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};\n\nour $declaration_macros = qr{(?x:\n\t(?:$Storage\\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\\s*\\(|\n\t(?:$Storage\\s+)?[HLP]?LIST_HEAD\\s*\\(|\n\t(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\\s*\\(|\n\t(?:$Storage\\s+)?(?:XA_STATE|XA_STATE_ORDER)\\s*\\(\n)};\n\nour %allow_repeated_words = (\n\tadd => '',\n\tadded => '',\n\tbad => '',\n\tbe => '',\n);\n\nsub deparenthesize {\n\tmy ($string) = @_;\n\treturn \"\" if (!defined($string));\n\n\twhile ($string =~ /^\\s*\\(.*\\)\\s*$/) {\n\t\t$string =~ s@^\\s*\\(\\s*@@;\n\t\t$string =~ s@\\s*\\)\\s*$@@;\n\t}\n\n\t$string =~ s@\\s+@ @g;\n\n\treturn $string;\n}\n\nsub seed_camelcase_file {\n\tmy ($file) = @_;\n\n\treturn if (!(-f $file));\n\n\tlocal $/;\n\n\topen(my $include_file, '<', \"$file\")\n\t    or warn \"$P: Can't read '$file' $!\\n\";\n\tmy $text = <$include_file>;\n\tclose($include_file);\n\n\tmy @lines = split('\\n', $text);\n\n\tforeach my $line (@lines) {\n\t\tif (!$OpenOCD) {\n\t\tnext if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);\n\t\tif ($line =~ /^[ \\t]*(?:#[ \\t]*define|typedef\\s+$Type)\\s+(\\w*(?:[A-Z][a-z]|[a-z][A-Z])\\w*)/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t} elsif ($line =~ /^\\s*$Declare\\s+(\\w*(?:[A-Z][a-z]|[a-z][A-Z])\\w*)\\s*[\\(\\[,;]/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t} elsif ($line =~ /^\\s*(?:union|struct|enum)\\s+(\\w*(?:[A-Z][a-z]|[a-z][A-Z])\\w*)\\s*[;\\{]/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t}\n\t\t} # !$OpenOCD\n\t\t# OpenOCD Specific: Begin: extend to camel[0-9_]*CASE\n\t\tnext if ($line !~ /(?:[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z])/);\n\t\tif ($line =~ /^[ \\t]*(?:#[ \\t]*define|typedef\\s+$Type)\\s+(\\w*(?:[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z])\\w*)/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t} elsif ($line =~ /^\\s*$Declare\\s+(\\w*(?:[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z])\\w*)\\s*[\\(\\[,;]/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t} elsif ($line =~ /^\\s*(?:union|struct|enum)\\s+(\\w*(?:[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z])\\w*)\\s*[;\\{]/) {\n\t\t\t$camelcase{$1} = 1;\n\t\t}\n\t\t# OpenOCD Specific: End\n\t}\n}\n\nour %maintained_status = ();\n\nsub is_maintained_obsolete {\n\tmy ($filename) = @_;\n\n\treturn 0 if (!$tree || !(-e \"$root/scripts/get_maintainer.pl\"));\n\n\tif (!exists($maintained_status{$filename})) {\n\t\t$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;\n\t}\n\n\treturn $maintained_status{$filename} =~ /obsolete/i;\n}\n\nsub is_SPDX_License_valid {\n\tmy ($license) = @_;\n\n\t# OpenOCD specific: Begin: replace s\"scripts\"tools/scripts\"\n\treturn 1 if (!$tree || which(\"python3\") eq \"\" || !(-x \"$root/tools/scripts/spdxcheck.py\") || !(-e \"$gitroot\"));\n\n\tmy $root_path = abs_path($root);\n\tmy $status = `cd \"$root_path\"; echo \"$license\" | tools/scripts/spdxcheck.py -`;\n\t# OpenOCD specific: End\n\treturn 0 if ($status ne \"\");\n\treturn 1;\n}\n\nmy $camelcase_seeded = 0;\nsub seed_camelcase_includes {\n\treturn if ($camelcase_seeded);\n\n\tmy $files;\n\tmy $camelcase_cache = \"\";\n\tmy @include_files = ();\n\n\t$camelcase_seeded = 1;\n\n\tif (-e \"$gitroot\") {\n\t\tmy $git_last_include_commit = `${git_command} log --no-merges --pretty=format:\"%h%n\" -1 -- include`;\n\t\tchomp $git_last_include_commit;\n\t\t$camelcase_cache = \".checkpatch-camelcase.git.$git_last_include_commit\";\n\t} else {\n\t\tmy $last_mod_date = 0;\n\t\t$files = `find $root/include -name \"*.h\"`;\n\t\t@include_files = split('\\n', $files);\n\t\tforeach my $file (@include_files) {\n\t\t\tmy $date = POSIX::strftime(\"%Y%m%d%H%M\",\n\t\t\t\t\t\t   localtime((stat $file)[9]));\n\t\t\t$last_mod_date = $date if ($last_mod_date < $date);\n\t\t}\n\t\t$camelcase_cache = \".checkpatch-camelcase.date.$last_mod_date\";\n\t}\n\n\tif ($camelcase_cache ne \"\" && -f $camelcase_cache) {\n\t\topen(my $camelcase_file, '<', \"$camelcase_cache\")\n\t\t    or warn \"$P: Can't read '$camelcase_cache' $!\\n\";\n\t\twhile (<$camelcase_file>) {\n\t\t\tchomp;\n\t\t\t$camelcase{$_} = 1;\n\t\t}\n\t\tclose($camelcase_file);\n\n\t\treturn;\n\t}\n\n\tif (-e \"$gitroot\") {\n\t\t$files = `${git_command} ls-files \"include/*.h\"`;\n\t\t@include_files = split('\\n', $files);\n\t}\n\n\tforeach my $file (@include_files) {\n\t\tseed_camelcase_file($file);\n\t}\n\n\tif ($camelcase_cache ne \"\") {\n\t\tunlink glob \".checkpatch-camelcase.*\";\n\t\topen(my $camelcase_file, '>', \"$camelcase_cache\")\n\t\t    or warn \"$P: Can't write '$camelcase_cache' $!\\n\";\n\t\tforeach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {\n\t\t\tprint $camelcase_file (\"$_\\n\");\n\t\t}\n\t\tclose($camelcase_file);\n\t}\n}\n\nsub git_is_single_file {\n\tmy ($filename) = @_;\n\n\treturn 0 if ((which(\"git\") eq \"\") || !(-e \"$gitroot\"));\n\n\tmy $output = `${git_command} ls-files -- $filename 2>/dev/null`;\n\tmy $count = $output =~ tr/\\n//;\n\treturn $count eq 1 && $output =~ m{^${filename}$};\n}\n\nsub git_commit_info {\n\tmy ($commit, $id, $desc) = @_;\n\n\treturn ($id, $desc) if ((which(\"git\") eq \"\") || !(-e \"$gitroot\"));\n\n\tmy $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;\n\t$output =~ s/^\\s*//gm;\n\tmy @lines = split(\"\\n\", $output);\n\n\treturn ($id, $desc) if ($#lines < 0);\n\n\tif ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {\n# Maybe one day convert this block of bash into something that returns\n# all matching commit ids, but it's very slow...\n#\n#\t\techo \"checking commits $1...\"\n#\t\tgit rev-list --remotes | grep -i \"^$1\" |\n#\t\twhile read line ; do\n#\t\t    git log --format='%H %s' -1 $line |\n#\t\t    echo \"commit $(cut -c 1-12,41-)\"\n#\t\tdone\n\t} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\\./ ||\n\t\t $lines[0] =~ /^fatal: bad object $commit/) {\n\t\t$id = undef;\n\t} else {\n\t\t$id = substr($lines[0], 0, 12);\n\t\t$desc = substr($lines[0], 41);\n\t}\n\n\treturn ($id, $desc);\n}\n\n$chk_signoff = 0 if ($file);\n\nmy @rawlines = ();\nmy @lines = ();\nmy @fixed = ();\nmy @fixed_inserted = ();\nmy @fixed_deleted = ();\nmy $fixlinenr = -1;\n\n# If input is git commits, extract all commits from the commit expressions.\n# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.\ndie \"$P: No git repository found\\n\" if ($git && !-e \"$gitroot\");\n\nif ($git) {\n\tmy @commits = ();\n\tforeach my $commit_expr (@ARGV) {\n\t\tmy $git_range;\n\t\tif ($commit_expr =~ m/^(.*)-(\\d+)$/) {\n\t\t\t$git_range = \"-$2 $1\";\n\t\t} elsif ($commit_expr =~ m/\\.\\./) {\n\t\t\t$git_range = \"$commit_expr\";\n\t\t} else {\n\t\t\t$git_range = \"-1 $commit_expr\";\n\t\t}\n\t\tmy $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;\n\t\tforeach my $line (split(/\\n/, $lines)) {\n\t\t\t$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;\n\t\t\tnext if (!defined($1) || !defined($2));\n\t\t\tmy $sha1 = $1;\n\t\t\tmy $subject = $2;\n\t\t\tunshift(@commits, $sha1);\n\t\t\t$git_commits{$sha1} = $subject;\n\t\t}\n\t}\n\tdie \"$P: no git commits after extraction!\\n\" if (@commits == 0);\n\t@ARGV = @commits;\n}\n\nmy $vname;\n$allow_c99_comments = !defined $ignore_type{\"C99_COMMENT_TOLERANCE\"};\nfor my $filename (@ARGV) {\n\tmy $FILE;\n\tmy $is_git_file = git_is_single_file($filename);\n\tmy $oldfile = $file;\n\t$file = 1 if ($is_git_file);\n\tif ($git) {\n\t\topen($FILE, '-|', \"git format-patch -M --stdout -1 $filename\") ||\n\t\t\tdie \"$P: $filename: git format-patch failed - $!\\n\";\n\t} elsif ($file) {\n\t\topen($FILE, '-|', \"diff -u /dev/null $filename\") ||\n\t\t\tdie \"$P: $filename: diff failed - $!\\n\";\n\t} elsif ($filename eq '-') {\n\t\topen($FILE, '<&STDIN');\n\t} else {\n\t\topen($FILE, '<', \"$filename\") ||\n\t\t\tdie \"$P: $filename: open failed - $!\\n\";\n\t}\n\tif ($filename eq '-') {\n\t\t$vname = 'Your patch';\n\t} elsif ($git) {\n\t\t$vname = \"Commit \" . substr($filename, 0, 12) . ' (\"' . $git_commits{$filename} . '\")';\n\t} else {\n\t\t$vname = $filename;\n\t}\n\twhile (<$FILE>) {\n\t\tchomp;\n\t\tpush(@rawlines, $_);\n\t\t$vname = qq(\"$1\") if ($filename eq '-' && $_ =~ m/^Subject:\\s+(.+)/i);\n\t}\n\tclose($FILE);\n\n\tif ($#ARGV > 0 && $quiet == 0) {\n\t\tprint '-' x length($vname) . \"\\n\";\n\t\tprint \"$vname\\n\";\n\t\tprint '-' x length($vname) . \"\\n\";\n\t}\n\n\tif (!process($filename)) {\n\t\t$exit = 1;\n\t}\n\t@rawlines = ();\n\t@lines = ();\n\t@fixed = ();\n\t@fixed_inserted = ();\n\t@fixed_deleted = ();\n\t$fixlinenr = -1;\n\t@modifierListFile = ();\n\t@typeListFile = ();\n\tbuild_types();\n\t$file = $oldfile if ($is_git_file);\n}\n\nif (!$quiet) {\n\thash_show_words(\\%use_type, \"Used\");\n\thash_show_words(\\%ignore_type, \"Ignored\");\n\n\tif (!$perl_version_ok) {\n\t\tprint << \"EOM\"\n\nNOTE: perl $^V is not modern enough to detect all possible issues.\n      An upgrade to at least perl $minimum_perl_version is suggested.\nEOM\n\t}\n\tif ($exit) {\n\t\tif (!$OpenOCD) {\n\t\tprint << \"EOM\"\n\nNOTE: If any of the errors are false positives, please report\n      them to the maintainer, see CHECKPATCH in MAINTAINERS.\nEOM\n\t\t} # !$OpenOCD\n\t\t# OpenOCD specific: Begin\n\t\tprint << \"EOM\"\n\nNOTE: If any of the errors are false positives, please report\n      them to the openocd-devel mailing list or prepare a patch\n      and send it to Gerrit for review.\nEOM\n\t\t# OpenOCD specific: End\n\t}\n}\n\nexit($exit);\n\nsub top_of_kernel_tree {\n\tmy ($root) = @_;\n\n\tif (!$OpenOCD) {\n\tmy @tree_check = (\n\t\t\"COPYING\", \"CREDITS\", \"Kbuild\", \"MAINTAINERS\", \"Makefile\",\n\t\t\"README\", \"Documentation\", \"arch\", \"include\", \"drivers\",\n\t\t\"fs\", \"init\", \"ipc\", \"kernel\", \"lib\", \"scripts\",\n\t);\n\t} # !$OpenOCD\n\t# OpenOCD specific: Begin\n\tmy @tree_check = (\n\t\t\"AUTHORS\", \"BUGS\", \"COPYING\", \"HACKING\", \"Makefile.am\",\n\t\t\"README\", \"contrib\", \"doc\", \"src\", \"tcl\", \"testing\", \"tools\",\n\t);\n\t# OpenOCD specific: End\n\n\tforeach my $check (@tree_check) {\n\t\tif (! -e $root . '/' . $check) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\treturn 1;\n}\n\nsub parse_email {\n\tmy ($formatted_email) = @_;\n\n\tmy $name = \"\";\n\tmy $quoted = \"\";\n\tmy $name_comment = \"\";\n\tmy $address = \"\";\n\tmy $comment = \"\";\n\n\tif ($formatted_email =~ /^(.*)<(\\S+\\@\\S+)>(.*)$/) {\n\t\t$name = $1;\n\t\t$address = $2;\n\t\t$comment = $3 if defined $3;\n\t} elsif ($formatted_email =~ /^\\s*<(\\S+\\@\\S+)>(.*)$/) {\n\t\t$address = $1;\n\t\t$comment = $2 if defined $2;\n\t} elsif ($formatted_email =~ /(\\S+\\@\\S+)(.*)$/) {\n\t\t$address = $1;\n\t\t$comment = $2 if defined $2;\n\t\t$formatted_email =~ s/\\Q$address\\E.*$//;\n\t\t$name = $formatted_email;\n\t\t$name = trim($name);\n\t\t$name =~ s/^\\\"|\\\"$//g;\n\t\t# If there's a name left after stripping spaces and\n\t\t# leading quotes, and the address doesn't have both\n\t\t# leading and trailing angle brackets, the address\n\t\t# is invalid. ie:\n\t\t#   \"joe smith joe@smith.com\" bad\n\t\t#   \"joe smith <joe@smith.com\" bad\n\t\tif ($name ne \"\" && $address !~ /^<[^>]+>$/) {\n\t\t\t$name = \"\";\n\t\t\t$address = \"\";\n\t\t\t$comment = \"\";\n\t\t}\n\t# OpenOCD specific: Begin: handle jenkins as valid email\n\t} elsif ($formatted_email eq \"jenkins\") {\n\t\t\t$address = \"jenkins\";\n\t# OpenOCD specific: End\n\t}\n\n\t# Extract comments from names excluding quoted parts\n\t# \"John D. (Doe)\" - Do not extract\n\tif ($name =~ s/\\\"(.+)\\\"//) {\n\t\t$quoted = $1;\n\t}\n\twhile ($name =~ s/\\s*($balanced_parens)\\s*/ /) {\n\t\t$name_comment .= trim($1);\n\t}\n\t$name =~ s/^[ \\\"]+|[ \\\"]+$//g;\n\t$name = trim(\"$quoted $name\");\n\n\t$address = trim($address);\n\t$address =~ s/^\\<|\\>$//g;\n\t$comment = trim($comment);\n\n\tif ($name =~ /[^\\w \\-]/i) { ##has \"must quote\" chars\n\t\t$name =~ s/(?<!\\\\)\"/\\\\\"/g; ##escape quotes\n\t\t$name = \"\\\"$name\\\"\";\n\t}\n\n\treturn ($name, $name_comment, $address, $comment);\n}\n\nsub format_email {\n\tmy ($name, $name_comment, $address, $comment) = @_;\n\n\tmy $formatted_email;\n\n\t$name =~ s/^[ \\\"]+|[ \\\"]+$//g;\n\t$address = trim($address);\n\t$address =~ s/(?:\\.|\\,|\\\")+$//; ##trailing commas, dots or quotes\n\n\tif ($name =~ /[^\\w \\-]/i) { ##has \"must quote\" chars\n\t\t$name =~ s/(?<!\\\\)\"/\\\\\"/g; ##escape quotes\n\t\t$name = \"\\\"$name\\\"\";\n\t}\n\n\t$name_comment = trim($name_comment);\n\t$name_comment = \" $name_comment\" if ($name_comment ne \"\");\n\t$comment = trim($comment);\n\t$comment = \" $comment\" if ($comment ne \"\");\n\n\tif (\"$name\" eq \"\") {\n\t\t$formatted_email = \"$address\";\n\t} else {\n\t\t$formatted_email = \"$name$name_comment <$address>\";\n\t}\n\t$formatted_email .= \"$comment\";\n\treturn $formatted_email;\n}\n\nsub reformat_email {\n\tmy ($email) = @_;\n\n\tmy ($email_name, $name_comment, $email_address, $comment) = parse_email($email);\n\treturn format_email($email_name, $name_comment, $email_address, $comment);\n}\n\nsub same_email_addresses {\n\tmy ($email1, $email2) = @_;\n\n\tmy ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);\n\tmy ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);\n\n\treturn $email1_name eq $email2_name &&\n\t       $email1_address eq $email2_address &&\n\t       $name1_comment eq $name2_comment &&\n\t       $comment1 eq $comment2;\n}\n\nsub which {\n\tmy ($bin) = @_;\n\n\tforeach my $path (split(/:/, $ENV{PATH})) {\n\t\tif (-e \"$path/$bin\") {\n\t\t\treturn \"$path/$bin\";\n\t\t}\n\t}\n\n\treturn \"\";\n}\n\nsub which_conf {\n\tmy ($conf) = @_;\n\n\tforeach my $path (split(/:/, \".:$ENV{HOME}:.scripts\")) {\n\t\tif (-e \"$path/$conf\") {\n\t\t\treturn \"$path/$conf\";\n\t\t}\n\t}\n\n\treturn \"\";\n}\n\nsub expand_tabs {\n\tmy ($str) = @_;\n\n\tmy $res = '';\n\tmy $n = 0;\n\tfor my $c (split(//, $str)) {\n\t\tif ($c eq \"\\t\") {\n\t\t\t$res .= ' ';\n\t\t\t$n++;\n\t\t\tfor (; ($n % $tabsize) != 0; $n++) {\n\t\t\t\t$res .= ' ';\n\t\t\t}\n\t\t\tnext;\n\t\t}\n\t\t$res .= $c;\n\t\t$n++;\n\t}\n\n\treturn $res;\n}\nsub copy_spacing {\n\t(my $res = shift) =~ tr/\\t/ /c;\n\treturn $res;\n}\n\nsub line_stats {\n\tmy ($line) = @_;\n\n\t# Drop the diff line leader and expand tabs\n\t$line =~ s/^.//;\n\t$line = expand_tabs($line);\n\n\t# Pick the indent from the front of the line.\n\tmy ($white) = ($line =~ /^(\\s*)/);\n\n\treturn (length($line), length($white));\n}\n\nmy $sanitise_quote = '';\n\nsub sanitise_line_reset {\n\tmy ($in_comment) = @_;\n\n\tif ($in_comment) {\n\t\t$sanitise_quote = '*/';\n\t} else {\n\t\t$sanitise_quote = '';\n\t}\n}\nsub sanitise_line {\n\tmy ($line) = @_;\n\n\tmy $res = '';\n\tmy $l = '';\n\n\tmy $qlen = 0;\n\tmy $off = 0;\n\tmy $c;\n\n\t# Always copy over the diff marker.\n\t$res = substr($line, 0, 1);\n\n\tfor ($off = 1; $off < length($line); $off++) {\n\t\t$c = substr($line, $off, 1);\n\n\t\t# Comments we are whacking completely including the begin\n\t\t# and end, all to $;.\n\t\tif ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {\n\t\t\t$sanitise_quote = '*/';\n\n\t\t\tsubstr($res, $off, 2, \"$;$;\");\n\t\t\t$off++;\n\t\t\tnext;\n\t\t}\n\t\tif ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {\n\t\t\t$sanitise_quote = '';\n\t\t\tsubstr($res, $off, 2, \"$;$;\");\n\t\t\t$off++;\n\t\t\tnext;\n\t\t}\n\t\tif ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {\n\t\t\t$sanitise_quote = '//';\n\n\t\t\tsubstr($res, $off, 2, $sanitise_quote);\n\t\t\t$off++;\n\t\t\tnext;\n\t\t}\n\n\t\t# A \\ in a string means ignore the next character.\n\t\tif (($sanitise_quote eq \"'\" || $sanitise_quote eq '\"') &&\n\t\t    $c eq \"\\\\\") {\n\t\t\tsubstr($res, $off, 2, 'XX');\n\t\t\t$off++;\n\t\t\tnext;\n\t\t}\n\t\t# Regular quotes.\n\t\tif ($c eq \"'\" || $c eq '\"') {\n\t\t\tif ($sanitise_quote eq '') {\n\t\t\t\t$sanitise_quote = $c;\n\n\t\t\t\tsubstr($res, $off, 1, $c);\n\t\t\t\tnext;\n\t\t\t} elsif ($sanitise_quote eq $c) {\n\t\t\t\t$sanitise_quote = '';\n\t\t\t}\n\t\t}\n\n\t\t#print \"c<$c> SQ<$sanitise_quote>\\n\";\n\t\tif ($off != 0 && $sanitise_quote eq '*/' && $c ne \"\\t\") {\n\t\t\tsubstr($res, $off, 1, $;);\n\t\t} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne \"\\t\") {\n\t\t\tsubstr($res, $off, 1, $;);\n\t\t} elsif ($off != 0 && $sanitise_quote && $c ne \"\\t\") {\n\t\t\tsubstr($res, $off, 1, 'X');\n\t\t} else {\n\t\t\tsubstr($res, $off, 1, $c);\n\t\t}\n\t}\n\n\tif ($sanitise_quote eq '//') {\n\t\t$sanitise_quote = '';\n\t}\n\n\t# The pathname on a #include may be surrounded by '<' and '>'.\n\tif ($res =~ /^.\\s*\\#\\s*include\\s+\\<(.*)\\>/) {\n\t\tmy $clean = 'X' x length($1);\n\t\t$res =~ s@\\<.*\\>@<$clean>@;\n\n\t# The whole of a #error is a string.\n\t} elsif ($res =~ /^.\\s*\\#\\s*(?:error|warning)\\s+(.*)\\b/) {\n\t\tmy $clean = 'X' x length($1);\n\t\t$res =~ s@(\\#\\s*(?:error|warning)\\s+).*@$1$clean@;\n\t}\n\n\tif ($allow_c99_comments && $res =~ m@(//.*$)@) {\n\t\tmy $match = $1;\n\t\t$res =~ s/\\Q$match\\E/\"$;\" x length($match)/e;\n\t}\n\n\treturn $res;\n}\n\nsub get_quoted_string {\n\tmy ($line, $rawline) = @_;\n\n\treturn \"\" if (!defined($line) || !defined($rawline));\n\treturn \"\" if ($line !~ m/($String)/g);\n\treturn substr($rawline, $-[0], $+[0] - $-[0]);\n}\n\nsub ctx_statement_block {\n\tmy ($linenr, $remain, $off) = @_;\n\tmy $line = $linenr - 1;\n\tmy $blk = '';\n\tmy $soff = $off;\n\tmy $coff = $off - 1;\n\tmy $coff_set = 0;\n\n\tmy $loff = 0;\n\n\tmy $type = '';\n\tmy $level = 0;\n\tmy @stack = ();\n\tmy $p;\n\tmy $c;\n\tmy $len = 0;\n\n\tmy $remainder;\n\twhile (1) {\n\t\t@stack = (['', 0]) if ($#stack == -1);\n\n\t\t#warn \"CSB: blk<$blk> remain<$remain>\\n\";\n\t\t# If we are about to drop off the end, pull in more\n\t\t# context.\n\t\tif ($off >= $len) {\n\t\t\tfor (; $remain > 0; $line++) {\n\t\t\t\tlast if (!defined $lines[$line]);\n\t\t\t\tnext if ($lines[$line] =~ /^-/);\n\t\t\t\t$remain--;\n\t\t\t\t$loff = $len;\n\t\t\t\t$blk .= $lines[$line] . \"\\n\";\n\t\t\t\t$len = length($blk);\n\t\t\t\t$line++;\n\t\t\t\tlast;\n\t\t\t}\n\t\t\t# Bail if there is no further context.\n\t\t\t#warn \"CSB: blk<$blk> off<$off> len<$len>\\n\";\n\t\t\tif ($off >= $len) {\n\t\t\t\tlast;\n\t\t\t}\n\t\t\tif ($level == 0 && substr($blk, $off) =~ /^.\\s*#\\s*define/) {\n\t\t\t\t$level++;\n\t\t\t\t$type = '#';\n\t\t\t}\n\t\t}\n\t\t$p = $c;\n\t\t$c = substr($blk, $off, 1);\n\t\t$remainder = substr($blk, $off);\n\n\t\t#warn \"CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\\n\";\n\n\t\t# Handle nested #if/#else.\n\t\tif ($remainder =~ /^#\\s*(?:ifndef|ifdef|if)\\s/) {\n\t\t\tpush(@stack, [ $type, $level ]);\n\t\t} elsif ($remainder =~ /^#\\s*(?:else|elif)\\b/) {\n\t\t\t($type, $level) = @{$stack[$#stack - 1]};\n\t\t} elsif ($remainder =~ /^#\\s*endif\\b/) {\n\t\t\t($type, $level) = @{pop(@stack)};\n\t\t}\n\n\t\t# Statement ends at the ';' or a close '}' at the\n\t\t# outermost level.\n\t\tif ($level == 0 && $c eq ';') {\n\t\t\tlast;\n\t\t}\n\n\t\t# An else is really a conditional as long as its not else if\n\t\tif ($level == 0 && $coff_set == 0 &&\n\t\t\t\t(!defined($p) || $p =~ /(?:\\s|\\}|\\+)/) &&\n\t\t\t\t$remainder =~ /^(else)(?:\\s|{)/ &&\n\t\t\t\t$remainder !~ /^else\\s+if\\b/) {\n\t\t\t$coff = $off + length($1) - 1;\n\t\t\t$coff_set = 1;\n\t\t\t#warn \"CSB: mark coff<$coff> soff<$soff> 1<$1>\\n\";\n\t\t\t#warn \"[\" . substr($blk, $soff, $coff - $soff + 1) . \"]\\n\";\n\t\t}\n\n\t\tif (($type eq '' || $type eq '(') && $c eq '(') {\n\t\t\t$level++;\n\t\t\t$type = '(';\n\t\t}\n\t\tif ($type eq '(' && $c eq ')') {\n\t\t\t$level--;\n\t\t\t$type = ($level != 0)? '(' : '';\n\n\t\t\tif ($level == 0 && $coff < $soff) {\n\t\t\t\t$coff = $off;\n\t\t\t\t$coff_set = 1;\n\t\t\t\t#warn \"CSB: mark coff<$coff>\\n\";\n\t\t\t}\n\t\t}\n\t\tif (($type eq '' || $type eq '{') && $c eq '{') {\n\t\t\t$level++;\n\t\t\t$type = '{';\n\t\t}\n\t\tif ($type eq '{' && $c eq '}') {\n\t\t\t$level--;\n\t\t\t$type = ($level != 0)? '{' : '';\n\n\t\t\tif ($level == 0) {\n\t\t\t\tif (substr($blk, $off + 1, 1) eq ';') {\n\t\t\t\t\t$off++;\n\t\t\t\t}\n\t\t\t\tlast;\n\t\t\t}\n\t\t}\n\t\t# Preprocessor commands end at the newline unless escaped.\n\t\tif ($type eq '#' && $c eq \"\\n\" && $p ne \"\\\\\") {\n\t\t\t$level--;\n\t\t\t$type = '';\n\t\t\t$off++;\n\t\t\tlast;\n\t\t}\n\t\t$off++;\n\t}\n\t# We are truly at the end, so shuffle to the next line.\n\tif ($off == $len) {\n\t\t$loff = $len + 1;\n\t\t$line++;\n\t\t$remain--;\n\t}\n\n\tmy $statement = substr($blk, $soff, $off - $soff + 1);\n\tmy $condition = substr($blk, $soff, $coff - $soff + 1);\n\n\t#warn \"STATEMENT<$statement>\\n\";\n\t#warn \"CONDITION<$condition>\\n\";\n\n\t#print \"coff<$coff> soff<$off> loff<$loff>\\n\";\n\n\treturn ($statement, $condition,\n\t\t\t$line, $remain + 1, $off - $loff + 1, $level);\n}\n\nsub statement_lines {\n\tmy ($stmt) = @_;\n\n\t# Strip the diff line prefixes and rip blank lines at start and end.\n\t$stmt =~ s/(^|\\n)./$1/g;\n\t$stmt =~ s/^\\s*//;\n\t$stmt =~ s/\\s*$//;\n\n\tmy @stmt_lines = ($stmt =~ /\\n/g);\n\n\treturn $#stmt_lines + 2;\n}\n\nsub statement_rawlines {\n\tmy ($stmt) = @_;\n\n\tmy @stmt_lines = ($stmt =~ /\\n/g);\n\n\treturn $#stmt_lines + 2;\n}\n\nsub statement_block_size {\n\tmy ($stmt) = @_;\n\n\t$stmt =~ s/(^|\\n)./$1/g;\n\t$stmt =~ s/^\\s*{//;\n\t$stmt =~ s/}\\s*$//;\n\t$stmt =~ s/^\\s*//;\n\t$stmt =~ s/\\s*$//;\n\n\tmy @stmt_lines = ($stmt =~ /\\n/g);\n\tmy @stmt_statements = ($stmt =~ /;/g);\n\n\tmy $stmt_lines = $#stmt_lines + 2;\n\tmy $stmt_statements = $#stmt_statements + 1;\n\n\tif ($stmt_lines > $stmt_statements) {\n\t\treturn $stmt_lines;\n\t} else {\n\t\treturn $stmt_statements;\n\t}\n}\n\nsub ctx_statement_full {\n\tmy ($linenr, $remain, $off) = @_;\n\tmy ($statement, $condition, $level);\n\n\tmy (@chunks);\n\n\t# Grab the first conditional/block pair.\n\t($statement, $condition, $linenr, $remain, $off, $level) =\n\t\t\t\tctx_statement_block($linenr, $remain, $off);\n\t#print \"F: c<$condition> s<$statement> remain<$remain>\\n\";\n\tpush(@chunks, [ $condition, $statement ]);\n\tif (!($remain > 0 && $condition =~ /^\\s*(?:\\n[+-])?\\s*(?:if|else|do)\\b/s)) {\n\t\treturn ($level, $linenr, @chunks);\n\t}\n\n\t# Pull in the following conditional/block pairs and see if they\n\t# could continue the statement.\n\tfor (;;) {\n\t\t($statement, $condition, $linenr, $remain, $off, $level) =\n\t\t\t\tctx_statement_block($linenr, $remain, $off);\n\t\t#print \"C: c<$condition> s<$statement> remain<$remain>\\n\";\n\t\tlast if (!($remain > 0 && $condition =~ /^(?:\\s*\\n[+-])*\\s*(?:else|do)\\b/s));\n\t\t#print \"C: push\\n\";\n\t\tpush(@chunks, [ $condition, $statement ]);\n\t}\n\n\treturn ($level, $linenr, @chunks);\n}\n\nsub ctx_block_get {\n\tmy ($linenr, $remain, $outer, $open, $close, $off) = @_;\n\tmy $line;\n\tmy $start = $linenr - 1;\n\tmy $blk = '';\n\tmy @o;\n\tmy @c;\n\tmy @res = ();\n\n\tmy $level = 0;\n\tmy @stack = ($level);\n\tfor ($line = $start; $remain > 0; $line++) {\n\t\tnext if ($rawlines[$line] =~ /^-/);\n\t\t$remain--;\n\n\t\t$blk .= $rawlines[$line];\n\n\t\t# Handle nested #if/#else.\n\t\tif ($lines[$line] =~ /^.\\s*#\\s*(?:ifndef|ifdef|if)\\s/) {\n\t\t\tpush(@stack, $level);\n\t\t} elsif ($lines[$line] =~ /^.\\s*#\\s*(?:else|elif)\\b/) {\n\t\t\t$level = $stack[$#stack - 1];\n\t\t} elsif ($lines[$line] =~ /^.\\s*#\\s*endif\\b/) {\n\t\t\t$level = pop(@stack);\n\t\t}\n\n\t\tforeach my $c (split(//, $lines[$line])) {\n\t\t\t##print \"C<$c>L<$level><$open$close>O<$off>\\n\";\n\t\t\tif ($off > 0) {\n\t\t\t\t$off--;\n\t\t\t\tnext;\n\t\t\t}\n\n\t\t\tif ($c eq $close && $level > 0) {\n\t\t\t\t$level--;\n\t\t\t\tlast if ($level == 0);\n\t\t\t} elsif ($c eq $open) {\n\t\t\t\t$level++;\n\t\t\t}\n\t\t}\n\n\t\tif (!$outer || $level <= 1) {\n\t\t\tpush(@res, $rawlines[$line]);\n\t\t}\n\n\t\tlast if ($level == 0);\n\t}\n\n\treturn ($level, @res);\n}\nsub ctx_block_outer {\n\tmy ($linenr, $remain) = @_;\n\n\tmy ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);\n\treturn @r;\n}\nsub ctx_block {\n\tmy ($linenr, $remain) = @_;\n\n\tmy ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);\n\treturn @r;\n}\nsub ctx_statement {\n\tmy ($linenr, $remain, $off) = @_;\n\n\tmy ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);\n\treturn @r;\n}\nsub ctx_block_level {\n\tmy ($linenr, $remain) = @_;\n\n\treturn ctx_block_get($linenr, $remain, 0, '{', '}', 0);\n}\nsub ctx_statement_level {\n\tmy ($linenr, $remain, $off) = @_;\n\n\treturn ctx_block_get($linenr, $remain, 0, '(', ')', $off);\n}\n\nsub ctx_locate_comment {\n\tmy ($first_line, $end_line) = @_;\n\n\t# If c99 comment on the current line, or the line before or after\n\tmy ($current_comment) = ($rawlines[$end_line - 1] =~ m@^\\+.*(//.*$)@);\n\treturn $current_comment if (defined $current_comment);\n\t($current_comment) = ($rawlines[$end_line - 2] =~ m@^[\\+ ].*(//.*$)@);\n\treturn $current_comment if (defined $current_comment);\n\t($current_comment) = ($rawlines[$end_line] =~ m@^[\\+ ].*(//.*$)@);\n\treturn $current_comment if (defined $current_comment);\n\n\t# Catch a comment on the end of the line itself.\n\t($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\\*.*\\*/)\\s*(?:\\\\\\s*)?$@);\n\treturn $current_comment if (defined $current_comment);\n\n\t# Look through the context and try and figure out if there is a\n\t# comment.\n\tmy $in_comment = 0;\n\t$current_comment = '';\n\tfor (my $linenr = $first_line; $linenr < $end_line; $linenr++) {\n\t\tmy $line = $rawlines[$linenr - 1];\n\t\t#warn \"           $line\\n\";\n\t\tif ($linenr == $first_line and $line =~ m@^.\\s*\\*@) {\n\t\t\t$in_comment = 1;\n\t\t}\n\t\tif ($line =~ m@/\\*@) {\n\t\t\t$in_comment = 1;\n\t\t}\n\t\tif (!$in_comment && $current_comment ne '') {\n\t\t\t$current_comment = '';\n\t\t}\n\t\t$current_comment .= $line . \"\\n\" if ($in_comment);\n\t\tif ($line =~ m@\\*/@) {\n\t\t\t$in_comment = 0;\n\t\t}\n\t}\n\n\tchomp($current_comment);\n\treturn($current_comment);\n}\nsub ctx_has_comment {\n\tmy ($first_line, $end_line) = @_;\n\tmy $cmt = ctx_locate_comment($first_line, $end_line);\n\n\t##print \"LINE: $rawlines[$end_line - 1 ]\\n\";\n\t##print \"CMMT: $cmt\\n\";\n\n\treturn ($cmt ne '');\n}\n\nsub raw_line {\n\tmy ($linenr, $cnt) = @_;\n\n\tmy $offset = $linenr - 1;\n\t$cnt++;\n\n\tmy $line;\n\twhile ($cnt) {\n\t\t$line = $rawlines[$offset++];\n\t\tnext if (defined($line) && $line =~ /^-/);\n\t\t$cnt--;\n\t}\n\n\treturn $line;\n}\n\nsub get_stat_real {\n\tmy ($linenr, $lc) = @_;\n\n\tmy $stat_real = raw_line($linenr, 0);\n\tfor (my $count = $linenr + 1; $count <= $lc; $count++) {\n\t\t$stat_real = $stat_real . \"\\n\" . raw_line($count, 0);\n\t}\n\n\treturn $stat_real;\n}\n\nsub get_stat_here {\n\tmy ($linenr, $cnt, $here) = @_;\n\n\tmy $herectx = $here . \"\\n\";\n\tfor (my $n = 0; $n < $cnt; $n++) {\n\t\t$herectx .= raw_line($linenr, $n) . \"\\n\";\n\t}\n\n\treturn $herectx;\n}\n\nsub cat_vet {\n\tmy ($vet) = @_;\n\tmy ($res, $coded);\n\n\t$res = '';\n\twhile ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {\n\t\t$res .= $1;\n\t\tif ($2 ne '') {\n\t\t\t$coded = sprintf(\"^%c\", unpack('C', $2) + 64);\n\t\t\t$res .= $coded;\n\t\t}\n\t}\n\t$res =~ s/$/\\$/;\n\n\treturn $res;\n}\n\nmy $av_preprocessor = 0;\nmy $av_pending;\nmy @av_paren_type;\nmy $av_pend_colon;\n\nsub annotate_reset {\n\t$av_preprocessor = 0;\n\t$av_pending = '_';\n\t@av_paren_type = ('E');\n\t$av_pend_colon = 'O';\n}\n\nsub annotate_values {\n\tmy ($stream, $type) = @_;\n\n\tmy $res;\n\tmy $var = '_' x length($stream);\n\tmy $cur = $stream;\n\n\tprint \"$stream\\n\" if ($dbg_values > 1);\n\n\twhile (length($cur)) {\n\t\t@av_paren_type = ('E') if ($#av_paren_type < 0);\n\t\tprint \" <\" . join('', @av_paren_type) .\n\t\t\t\t\"> <$type> <$av_pending>\" if ($dbg_values > 1);\n\t\tif ($cur =~ /^(\\s+)/o) {\n\t\t\tprint \"WS($1)\\n\" if ($dbg_values > 1);\n\t\t\tif ($1 =~ /\\n/ && $av_preprocessor) {\n\t\t\t\t$type = pop(@av_paren_type);\n\t\t\t\t$av_preprocessor = 0;\n\t\t\t}\n\n\t\t} elsif ($cur =~ /^(\\(\\s*$Type\\s*)\\)/ && $av_pending eq '_') {\n\t\t\tprint \"CAST($1)\\n\" if ($dbg_values > 1);\n\t\t\tpush(@av_paren_type, $type);\n\t\t\t$type = 'c';\n\n\t\t} elsif ($cur =~ /^($Type)\\s*(?:$Ident|,|\\)|\\(|\\s*$)/) {\n\t\t\tprint \"DECLARE($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'T';\n\n\t\t} elsif ($cur =~ /^($Modifier)\\s*/) {\n\t\t\tprint \"MODIFIER($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'T';\n\n\t\t} elsif ($cur =~ /^(\\#\\s*define\\s*$Ident)(\\(?)/o) {\n\t\t\tprint \"DEFINE($1,$2)\\n\" if ($dbg_values > 1);\n\t\t\t$av_preprocessor = 1;\n\t\t\tpush(@av_paren_type, $type);\n\t\t\tif ($2 ne '') {\n\t\t\t\t$av_pending = 'N';\n\t\t\t}\n\t\t\t$type = 'E';\n\n\t\t} elsif ($cur =~ /^(\\#\\s*(?:undef\\s*$Ident|include\\b))/o) {\n\t\t\tprint \"UNDEF($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_preprocessor = 1;\n\t\t\tpush(@av_paren_type, $type);\n\n\t\t} elsif ($cur =~ /^(\\#\\s*(?:ifdef|ifndef|if))/o) {\n\t\t\tprint \"PRE_START($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_preprocessor = 1;\n\n\t\t\tpush(@av_paren_type, $type);\n\t\t\tpush(@av_paren_type, $type);\n\t\t\t$type = 'E';\n\n\t\t} elsif ($cur =~ /^(\\#\\s*(?:else|elif))/o) {\n\t\t\tprint \"PRE_RESTART($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_preprocessor = 1;\n\n\t\t\tpush(@av_paren_type, $av_paren_type[$#av_paren_type]);\n\n\t\t\t$type = 'E';\n\n\t\t} elsif ($cur =~ /^(\\#\\s*(?:endif))/o) {\n\t\t\tprint \"PRE_END($1)\\n\" if ($dbg_values > 1);\n\n\t\t\t$av_preprocessor = 1;\n\n\t\t\t# Assume all arms of the conditional end as this\n\t\t\t# one does, and continue as if the #endif was not here.\n\t\t\tpop(@av_paren_type);\n\t\t\tpush(@av_paren_type, $type);\n\t\t\t$type = 'E';\n\n\t\t} elsif ($cur =~ /^(\\\\\\n)/o) {\n\t\t\tprint \"PRECONT($1)\\n\" if ($dbg_values > 1);\n\n\t\t} elsif ($cur =~ /^(__attribute__)\\s*\\(?/o) {\n\t\t\tprint \"ATTR($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_pending = $type;\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(sizeof)\\s*(\\()?/o) {\n\t\t\tprint \"SIZEOF($1)\\n\" if ($dbg_values > 1);\n\t\t\tif (defined $2) {\n\t\t\t\t$av_pending = 'V';\n\t\t\t}\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(if|while|for)\\b/o) {\n\t\t\tprint \"COND($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_pending = 'E';\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~/^(case)/o) {\n\t\t\tprint \"CASE($1)\\n\" if ($dbg_values > 1);\n\t\t\t$av_pend_colon = 'C';\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\\b/o) {\n\t\t\tprint \"KEYWORD($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(\\()/o) {\n\t\t\tprint \"PAREN('$1')\\n\" if ($dbg_values > 1);\n\t\t\tpush(@av_paren_type, $av_pending);\n\t\t\t$av_pending = '_';\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(\\))/o) {\n\t\t\tmy $new_type = pop(@av_paren_type);\n\t\t\tif ($new_type ne '_') {\n\t\t\t\t$type = $new_type;\n\t\t\t\tprint \"PAREN('$1') -> $type\\n\"\n\t\t\t\t\t\t\tif ($dbg_values > 1);\n\t\t\t} else {\n\t\t\t\tprint \"PAREN('$1')\\n\" if ($dbg_values > 1);\n\t\t\t}\n\n\t\t} elsif ($cur =~ /^($Ident)\\s*\\(/o) {\n\t\t\tprint \"FUNC($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'V';\n\t\t\t$av_pending = 'V';\n\n\t\t} elsif ($cur =~ /^($Ident\\s*):(?:\\s*\\d+\\s*(,|=|;))?/) {\n\t\t\tif (defined $2 && $type eq 'C' || $type eq 'T') {\n\t\t\t\t$av_pend_colon = 'B';\n\t\t\t} elsif ($type eq 'E') {\n\t\t\t\t$av_pend_colon = 'L';\n\t\t\t}\n\t\t\tprint \"IDENT_COLON($1,$type>$av_pend_colon)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'V';\n\n\t\t} elsif ($cur =~ /^($Ident|$Constant)/o) {\n\t\t\tprint \"IDENT($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'V';\n\n\t\t} elsif ($cur =~ /^($Assignment)/o) {\n\t\t\tprint \"ASSIGN($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~/^(;|{|})/) {\n\t\t\tprint \"END($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'E';\n\t\t\t$av_pend_colon = 'O';\n\n\t\t} elsif ($cur =~/^(,)/) {\n\t\t\tprint \"COMMA($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'C';\n\n\t\t} elsif ($cur =~ /^(\\?)/o) {\n\t\t\tprint \"QUESTION($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(:)/o) {\n\t\t\tprint \"COLON($1,$av_pend_colon)\\n\" if ($dbg_values > 1);\n\n\t\t\tsubstr($var, length($res), 1, $av_pend_colon);\n\t\t\tif ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {\n\t\t\t\t$type = 'E';\n\t\t\t} else {\n\t\t\t\t$type = 'N';\n\t\t\t}\n\t\t\t$av_pend_colon = 'O';\n\n\t\t} elsif ($cur =~ /^(\\[)/o) {\n\t\t\tprint \"CLOSE($1)\\n\" if ($dbg_values > 1);\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^(-(?![->])|\\+(?!\\+)|\\*|\\&\\&|\\&)/o) {\n\t\t\tmy $variant;\n\n\t\t\tprint \"OPV($1)\\n\" if ($dbg_values > 1);\n\t\t\tif ($type eq 'V') {\n\t\t\t\t$variant = 'B';\n\t\t\t} else {\n\t\t\t\t$variant = 'U';\n\t\t\t}\n\n\t\t\tsubstr($var, length($res), 1, $variant);\n\t\t\t$type = 'N';\n\n\t\t} elsif ($cur =~ /^($Operators)/o) {\n\t\t\tprint \"OP($1)\\n\" if ($dbg_values > 1);\n\t\t\tif ($1 ne '++' && $1 ne '--') {\n\t\t\t\t$type = 'N';\n\t\t\t}\n\n\t\t} elsif ($cur =~ /(^.)/o) {\n\t\t\tprint \"C($1)\\n\" if ($dbg_values > 1);\n\t\t}\n\t\tif (defined $1) {\n\t\t\t$cur = substr($cur, length($1));\n\t\t\t$res .= $type x length($1);\n\t\t}\n\t}\n\n\treturn ($res, $var);\n}\n\nsub possible {\n\tmy ($possible, $line) = @_;\n\tmy $notPermitted = qr{(?:\n\t\t^(?:\n\t\t\t$Modifier|\n\t\t\t$Storage|\n\t\t\t$Type|\n\t\t\tDEFINE_\\S+\n\t\t)$|\n\t\t^(?:\n\t\t\tgoto|\n\t\t\treturn|\n\t\t\tcase|\n\t\t\telse|\n\t\t\tasm|__asm__|\n\t\t\tdo|\n\t\t\t\\#|\n\t\t\t\\#\\#|\n\t\t)(?:\\s|$)|\n\t\t^(?:typedef|struct|enum)\\b\n\t    )}x;\n\twarn \"CHECK<$possible> ($line)\\n\" if ($dbg_possible > 2);\n\tif ($possible !~ $notPermitted) {\n\t\t# Check for modifiers.\n\t\t$possible =~ s/\\s*$Storage\\s*//g;\n\t\t$possible =~ s/\\s*$Sparse\\s*//g;\n\t\tif ($possible =~ /^\\s*$/) {\n\n\t\t} elsif ($possible =~ /\\s/) {\n\t\t\t$possible =~ s/\\s*$Type\\s*//g;\n\t\t\tfor my $modifier (split(' ', $possible)) {\n\t\t\t\tif ($modifier !~ $notPermitted) {\n\t\t\t\t\twarn \"MODIFIER: $modifier ($possible) ($line)\\n\" if ($dbg_possible);\n\t\t\t\t\tpush(@modifierListFile, $modifier);\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\t\t\twarn \"POSSIBLE: $possible ($line)\\n\" if ($dbg_possible);\n\t\t\tpush(@typeListFile, $possible);\n\t\t}\n\t\tbuild_types();\n\t} else {\n\t\twarn \"NOTPOSS: $possible ($line)\\n\" if ($dbg_possible > 1);\n\t}\n}\n\nmy $prefix = '';\n\nsub show_type {\n\tmy ($type) = @_;\n\n\t$type =~ tr/[a-z]/[A-Z]/;\n\n\treturn defined $use_type{$type} if (scalar keys %use_type > 0);\n\n\treturn !defined $ignore_type{$type};\n}\n\nsub report {\n\tmy ($level, $type, $msg) = @_;\n\n\tif (!show_type($type) ||\n\t    (defined $tst_only && $msg !~ /\\Q$tst_only\\E/)) {\n\t\treturn 0;\n\t}\n\tmy $output = '';\n\tif ($color) {\n\t\tif ($level eq 'ERROR') {\n\t\t\t$output .= RED;\n\t\t} elsif ($level eq 'WARNING') {\n\t\t\t$output .= YELLOW;\n\t\t} else {\n\t\t\t$output .= GREEN;\n\t\t}\n\t}\n\t$output .= $prefix . $level . ':';\n\tif ($show_types) {\n\t\t$output .= BLUE if ($color);\n\t\t$output .= \"$type:\";\n\t}\n\t$output .= RESET if ($color);\n\t$output .= ' ' . $msg . \"\\n\";\n\n\tif ($showfile) {\n\t\tmy @lines = split(\"\\n\", $output, -1);\n\t\tsplice(@lines, 1, 1);\n\t\t$output = join(\"\\n\", @lines);\n\t}\n\n\tif ($terse) {\n\t\t$output = (split('\\n', $output))[0] . \"\\n\";\n\t}\n\n\tif ($verbose && exists($verbose_messages{$type}) &&\n\t    !exists($verbose_emitted{$type})) {\n\t\t$output .= $verbose_messages{$type} . \"\\n\\n\";\n\t\t$verbose_emitted{$type} = 1;\n\t}\n\n\tpush(our @report, $output);\n\n\treturn 1;\n}\n\nsub report_dump {\n\tour @report;\n}\n\nsub fixup_current_range {\n\tmy ($lineRef, $offset, $length) = @_;\n\n\tif ($$lineRef =~ /^\\@\\@ -\\d+,\\d+ \\+(\\d+),(\\d+) \\@\\@/) {\n\t\tmy $o = $1;\n\t\tmy $l = $2;\n\t\tmy $no = $o + $offset;\n\t\tmy $nl = $l + $length;\n\t\t$$lineRef =~ s/\\+$o,$l \\@\\@/\\+$no,$nl \\@\\@/;\n\t}\n}\n\nsub fix_inserted_deleted_lines {\n\tmy ($linesRef, $insertedRef, $deletedRef) = @_;\n\n\tmy $range_last_linenr = 0;\n\tmy $delta_offset = 0;\n\n\tmy $old_linenr = 0;\n\tmy $new_linenr = 0;\n\n\tmy $next_insert = 0;\n\tmy $next_delete = 0;\n\n\tmy @lines = ();\n\n\tmy $inserted = @{$insertedRef}[$next_insert++];\n\tmy $deleted = @{$deletedRef}[$next_delete++];\n\n\tforeach my $old_line (@{$linesRef}) {\n\t\tmy $save_line = 1;\n\t\tmy $line = $old_line;\t#don't modify the array\n\t\tif ($line =~ /^(?:\\+\\+\\+|\\-\\-\\-)\\s+\\S+/) {\t#new filename\n\t\t\t$delta_offset = 0;\n\t\t} elsif ($line =~ /^\\@\\@ -\\d+,\\d+ \\+\\d+,\\d+ \\@\\@/) {\t#new hunk\n\t\t\t$range_last_linenr = $new_linenr;\n\t\t\tfixup_current_range(\\$line, $delta_offset, 0);\n\t\t}\n\n\t\twhile (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {\n\t\t\t$deleted = @{$deletedRef}[$next_delete++];\n\t\t\t$save_line = 0;\n\t\t\tfixup_current_range(\\$lines[$range_last_linenr], $delta_offset--, -1);\n\t\t}\n\n\t\twhile (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {\n\t\t\tpush(@lines, ${$inserted}{'LINE'});\n\t\t\t$inserted = @{$insertedRef}[$next_insert++];\n\t\t\t$new_linenr++;\n\t\t\tfixup_current_range(\\$lines[$range_last_linenr], $delta_offset++, 1);\n\t\t}\n\n\t\tif ($save_line) {\n\t\t\tpush(@lines, $line);\n\t\t\t$new_linenr++;\n\t\t}\n\n\t\t$old_linenr++;\n\t}\n\n\treturn @lines;\n}\n\nsub fix_insert_line {\n\tmy ($linenr, $line) = @_;\n\n\tmy $inserted = {\n\t\tLINENR => $linenr,\n\t\tLINE => $line,\n\t};\n\tpush(@fixed_inserted, $inserted);\n}\n\nsub fix_delete_line {\n\tmy ($linenr, $line) = @_;\n\n\tmy $deleted = {\n\t\tLINENR => $linenr,\n\t\tLINE => $line,\n\t};\n\n\tpush(@fixed_deleted, $deleted);\n}\n\nsub ERROR {\n\tmy ($type, $msg) = @_;\n\n\tif (report(\"ERROR\", $type, $msg)) {\n\t\tour $clean = 0;\n\t\tour $cnt_error++;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\nsub WARN {\n\tmy ($type, $msg) = @_;\n\n\tif (report(\"WARNING\", $type, $msg)) {\n\t\tour $clean = 0;\n\t\tour $cnt_warn++;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\nsub CHK {\n\tmy ($type, $msg) = @_;\n\n\tif ($check && report(\"CHECK\", $type, $msg)) {\n\t\tour $clean = 0;\n\t\tour $cnt_chk++;\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nsub check_absolute_file {\n\tmy ($absolute, $herecurr) = @_;\n\tmy $file = $absolute;\n\n\t##print \"absolute<$absolute>\\n\";\n\n\t# See if any suffix of this path is a path within the tree.\n\twhile ($file =~ s@^[^/]*/@@) {\n\t\tif (-f \"$root/$file\") {\n\t\t\t##print \"file<$file>\\n\";\n\t\t\tlast;\n\t\t}\n\t}\n\tif (! -f _)  {\n\t\treturn 0;\n\t}\n\n\t# It is, so see if the prefix is acceptable.\n\tmy $prefix = $absolute;\n\tsubstr($prefix, -length($file)) = '';\n\n\t##print \"prefix<$prefix>\\n\";\n\tif ($prefix ne \".../\") {\n\t\tWARN(\"USE_RELATIVE_PATH\",\n\t\t     \"use relative pathname instead of absolute in changelog text\\n\" . $herecurr);\n\t}\n}\n\nsub trim {\n\tmy ($string) = @_;\n\n\t$string =~ s/^\\s+|\\s+$//g;\n\n\treturn $string;\n}\n\nsub ltrim {\n\tmy ($string) = @_;\n\n\t$string =~ s/^\\s+//;\n\n\treturn $string;\n}\n\nsub rtrim {\n\tmy ($string) = @_;\n\n\t$string =~ s/\\s+$//;\n\n\treturn $string;\n}\n\nsub string_find_replace {\n\tmy ($string, $find, $replace) = @_;\n\n\t$string =~ s/$find/$replace/g;\n\n\treturn $string;\n}\n\nsub tabify {\n\tmy ($leading) = @_;\n\n\tmy $source_indent = $tabsize;\n\tmy $max_spaces_before_tab = $source_indent - 1;\n\tmy $spaces_to_tab = \" \" x $source_indent;\n\n\t#convert leading spaces to tabs\n\t1 while $leading =~ s@^([\\t]*)$spaces_to_tab@$1\\t@g;\n\t#Remove spaces before a tab\n\t1 while $leading =~ s@^([\\t]*)( {1,$max_spaces_before_tab})\\t@$1\\t@g;\n\n\treturn \"$leading\";\n}\n\nsub pos_last_openparen {\n\tmy ($line) = @_;\n\n\tmy $pos = 0;\n\n\tmy $opens = $line =~ tr/\\(/\\(/;\n\tmy $closes = $line =~ tr/\\)/\\)/;\n\n\tmy $last_openparen = 0;\n\n\tif (($opens == 0) || ($closes >= $opens)) {\n\t\treturn -1;\n\t}\n\n\tmy $len = length($line);\n\n\tfor ($pos = 0; $pos < $len; $pos++) {\n\t\tmy $string = substr($line, $pos);\n\t\tif ($string =~ /^($FuncArg|$balanced_parens)/) {\n\t\t\t$pos += length($1) - 1;\n\t\t} elsif (substr($line, $pos, 1) eq '(') {\n\t\t\t$last_openparen = $pos;\n\t\t} elsif (index($string, '(') == -1) {\n\t\t\tlast;\n\t\t}\n\t}\n\n\treturn length(expand_tabs(substr($line, 0, $last_openparen))) + 1;\n}\n\nsub get_raw_comment {\n\tmy ($line, $rawline) = @_;\n\tmy $comment = '';\n\n\tfor my $i (0 .. (length($line) - 1)) {\n\t\tif (substr($line, $i, 1) eq \"$;\") {\n\t\t\t$comment .= substr($rawline, $i, 1);\n\t\t}\n\t}\n\n\treturn $comment;\n}\n\nsub exclude_global_initialisers {\n\tmy ($realfile) = @_;\n\n\t# Do not check for BPF programs (tools/testing/selftests/bpf/progs/*.c, samples/bpf/*_kern.c, *.bpf.c).\n\treturn $realfile =~ m@^tools/testing/selftests/bpf/progs/.*\\.c$@ ||\n\t\t$realfile =~ m@^samples/bpf/.*_kern\\.c$@ ||\n\t\t$realfile =~ m@/bpf/.*\\.bpf\\.c$@;\n}\n\nsub process {\n\tmy $filename = shift;\n\n\tmy $linenr=0;\n\tmy $prevline=\"\";\n\tmy $prevrawline=\"\";\n\tmy $stashline=\"\";\n\tmy $stashrawline=\"\";\n\n\tmy $length;\n\tmy $indent;\n\tmy $previndent=0;\n\tmy $stashindent=0;\n\n\tour $clean = 1;\n\tmy $signoff = 0;\n\tmy $author = '';\n\tmy $authorsignoff = 0;\n\tmy $author_sob = '';\n\tmy $is_patch = 0;\n\tmy $is_binding_patch = -1;\n\tmy $in_header_lines = $file ? 0 : 1;\n\tmy $in_commit_log = 0;\t\t#Scanning lines before patch\n\tmy $has_patch_separator = 0;\t#Found a --- line\n\tmy $has_commit_log = 0;\t\t#Encountered lines before patch\n\tmy $commit_log_lines = 0;\t#Number of commit log lines\n\tmy $commit_log_possible_stack_dump = 0;\n\tmy $commit_log_long_line = 0;\n\tmy $commit_log_has_diff = 0;\n\tmy $reported_maintainer_file = 0;\n\tmy $non_utf8_charset = 0;\n\n\tmy $last_git_commit_id_linenr = -1;\n\n\tmy $last_blank_line = 0;\n\tmy $last_coalesced_string_linenr = -1;\n\n\tour @report = ();\n\tour $cnt_lines = 0;\n\tour $cnt_error = 0;\n\tour $cnt_warn = 0;\n\tour $cnt_chk = 0;\n\n\t# Trace the real file/line as we go.\n\tmy $realfile = '';\n\tmy $realline = 0;\n\tmy $realcnt = 0;\n\tmy $here = '';\n\tmy $context_function;\t\t#undef'd unless there's a known function\n\tmy $in_comment = 0;\n\tmy $comment_edge = 0;\n\tmy $first_line = 0;\n\tmy $p1_prefix = '';\n\n\tmy $prev_values = 'E';\n\n\t# suppression flags\n\tmy %suppress_ifbraces;\n\tmy %suppress_whiletrailers;\n\tmy %suppress_export;\n\tmy $suppress_statement = 0;\n\n\tmy %signatures = ();\n\n\t# Pre-scan the patch sanitizing the lines.\n\t# Pre-scan the patch looking for any __setup documentation.\n\t#\n\tmy @setup_docs = ();\n\tmy $setup_docs = 0;\n\n\tmy $camelcase_file_seeded = 0;\n\n\tmy $checklicenseline = 1;\n\n\tsanitise_line_reset();\n\tmy $line;\n\tforeach my $rawline (@rawlines) {\n\t\t$linenr++;\n\t\t$line = $rawline;\n\n\t\tpush(@fixed, $rawline) if ($fix);\n\n\t\tif ($rawline=~/^\\+\\+\\+\\s+(\\S+)/) {\n\t\t\t$setup_docs = 0;\n\t\t\tif ($1 =~ m@Documentation/admin-guide/kernel-parameters.txt$@) {\n\t\t\t\t$setup_docs = 1;\n\t\t\t}\n\t\t\t#next;\n\t\t}\n\t\tif ($rawline =~ /^\\@\\@ -\\d+(?:,\\d+)? \\+(\\d+)(,(\\d+))? \\@\\@/) {\n\t\t\t$realline=$1-1;\n\t\t\tif (defined $2) {\n\t\t\t\t$realcnt=$3+1;\n\t\t\t} else {\n\t\t\t\t$realcnt=1+1;\n\t\t\t}\n\t\t\t$in_comment = 0;\n\n\t\t\t# Guestimate if this is a continuing comment.  Run\n\t\t\t# the context looking for a comment \"edge\".  If this\n\t\t\t# edge is a close comment then we must be in a comment\n\t\t\t# at context start.\n\t\t\tmy $edge;\n\t\t\tmy $cnt = $realcnt;\n\t\t\tfor (my $ln = $linenr + 1; $cnt > 0; $ln++) {\n\t\t\t\tnext if (defined $rawlines[$ln - 1] &&\n\t\t\t\t\t $rawlines[$ln - 1] =~ /^-/);\n\t\t\t\t$cnt--;\n\t\t\t\t#print \"RAW<$rawlines[$ln - 1]>\\n\";\n\t\t\t\tlast if (!defined $rawlines[$ln - 1]);\n\t\t\t\tif ($rawlines[$ln - 1] =~ m@(/\\*|\\*/)@ &&\n\t\t\t\t    $rawlines[$ln - 1] !~ m@\"[^\"]*(?:/\\*|\\*/)[^\"]*\"@) {\n\t\t\t\t\t($edge) = $1;\n\t\t\t\t\tlast;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (defined $edge && $edge eq '*/') {\n\t\t\t\t$in_comment = 1;\n\t\t\t}\n\n\t\t\t# Guestimate if this is a continuing comment.  If this\n\t\t\t# is the start of a diff block and this line starts\n\t\t\t# ' *' then it is very likely a comment.\n\t\t\tif (!defined $edge &&\n\t\t\t    $rawlines[$linenr] =~ m@^.\\s*(?:\\*\\*+| \\*)(?:\\s|$)@)\n\t\t\t{\n\t\t\t\t$in_comment = 1;\n\t\t\t}\n\n\t\t\t##print \"COMMENT:$in_comment edge<$edge> $rawline\\n\";\n\t\t\tsanitise_line_reset($in_comment);\n\n\t\t} elsif ($realcnt && $rawline =~ /^(?:\\+| |$)/) {\n\t\t\t# Standardise the strings and chars within the input to\n\t\t\t# simplify matching -- only bother with positive lines.\n\t\t\t$line = sanitise_line($rawline);\n\t\t}\n\t\tpush(@lines, $line);\n\n\t\tif ($realcnt > 1) {\n\t\t\t$realcnt-- if ($line =~ /^(?:\\+| |$)/);\n\t\t} else {\n\t\t\t$realcnt = 0;\n\t\t}\n\n\t\t#print \"==>$rawline\\n\";\n\t\t#print \"-->$line\\n\";\n\n\t\tif ($setup_docs && $line =~ /^\\+/) {\n\t\t\tpush(@setup_docs, $line);\n\t\t}\n\t}\n\n\t$prefix = '';\n\n\t$realcnt = 0;\n\t$linenr = 0;\n\t$fixlinenr = -1;\n\tforeach my $line (@lines) {\n\t\t$linenr++;\n\t\t$fixlinenr++;\n\t\tmy $sline = $line;\t#copy of $line\n\t\t$sline =~ s/$;/ /g;\t#with comments as spaces\n\n\t\tmy $rawline = $rawlines[$linenr - 1];\n\t\tmy $raw_comment = get_raw_comment($line, $rawline);\n\n# check if it's a mode change, rename or start of a patch\n\t\tif (!$in_commit_log &&\n\t\t    ($line =~ /^ mode change [0-7]+ => [0-7]+ \\S+\\s*$/ ||\n\t\t    ($line =~ /^rename (?:from|to) \\S+\\s*$/ ||\n\t\t     $line =~ /^diff --git a\\/[\\w\\/\\.\\_\\-]+ b\\/\\S+\\s*$/))) {\n\t\t\t$is_patch = 1;\n\t\t}\n\n#extract the line range in the file after the patch is applied\n\t\tif (!$in_commit_log &&\n\t\t    $line =~ /^\\@\\@ -\\d+(?:,\\d+)? \\+(\\d+)(,(\\d+))? \\@\\@(.*)/) {\n\t\t\tmy $context = $4;\n\t\t\t$is_patch = 1;\n\t\t\t$first_line = $linenr + 1;\n\t\t\t$realline=$1-1;\n\t\t\tif (defined $2) {\n\t\t\t\t$realcnt=$3+1;\n\t\t\t} else {\n\t\t\t\t$realcnt=1+1;\n\t\t\t}\n\t\t\tannotate_reset();\n\t\t\t$prev_values = 'E';\n\n\t\t\t%suppress_ifbraces = ();\n\t\t\t%suppress_whiletrailers = ();\n\t\t\t%suppress_export = ();\n\t\t\t$suppress_statement = 0;\n\t\t\tif ($context =~ /\\b(\\w+)\\s*\\(/) {\n\t\t\t\t$context_function = $1;\n\t\t\t} else {\n\t\t\t\tundef $context_function;\n\t\t\t}\n\t\t\tnext;\n\n# track the line number as we move through the hunk, note that\n# new versions of GNU diff omit the leading space on completely\n# blank context lines so we need to count that too.\n\t\t} elsif ($line =~ /^( |\\+|$)/) {\n\t\t\t$realline++;\n\t\t\t$realcnt-- if ($realcnt != 0);\n\n\t\t\t# Measure the line length and indent.\n\t\t\t($length, $indent) = line_stats($rawline);\n\n\t\t\t# Track the previous line.\n\t\t\t($prevline, $stashline) = ($stashline, $line);\n\t\t\t($previndent, $stashindent) = ($stashindent, $indent);\n\t\t\t($prevrawline, $stashrawline) = ($stashrawline, $rawline);\n\n\t\t\t#warn \"line<$line>\\n\";\n\n\t\t} elsif ($realcnt == 1) {\n\t\t\t$realcnt--;\n\t\t}\n\n\t\tmy $hunk_line = ($realcnt != 0);\n\n\t\t$here = \"#$linenr: \" if (!$file);\n\t\t$here = \"#$realline: \" if ($file);\n\n\t\tmy $found_file = 0;\n\t\t# extract the filename as it passes\n\t\tif ($line =~ /^diff --git.*?(\\S+)$/) {\n\t\t\t$realfile = $1;\n\t\t\t$realfile =~ s@^([^/]*)/@@ if (!$file);\n\t\t\t$in_commit_log = 0;\n\t\t\t$found_file = 1;\n\t\t} elsif ($line =~ /^\\+\\+\\+\\s+(\\S+)/) {\n\t\t\t$realfile = $1;\n\t\t\t$realfile =~ s@^([^/]*)/@@ if (!$file);\n\t\t\t$in_commit_log = 0;\n\n\t\t\t$p1_prefix = $1;\n\t\t\tif (!$file && $tree && $p1_prefix ne '' &&\n\t\t\t    -e \"$root/$p1_prefix\") {\n\t\t\t\tWARN(\"PATCH_PREFIX\",\n\t\t\t\t     \"patch prefix '$p1_prefix' exists, appears to be a -p0 patch\\n\");\n\t\t\t}\n\n\t\t\tif ($realfile =~ m@^include/asm/@) {\n\t\t\t\tERROR(\"MODIFIED_INCLUDE_ASM\",\n\t\t\t\t      \"do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\\n\" . \"$here$rawline\\n\");\n\t\t\t}\n\t\t\t$found_file = 1;\n\t\t}\n\n#make up the handle for any error we report on this line\n\t\tif ($showfile) {\n\t\t\t$prefix = \"$realfile:$realline: \"\n\t\t} elsif ($emacs) {\n\t\t\tif ($file) {\n\t\t\t\t$prefix = \"$filename:$realline: \";\n\t\t\t} else {\n\t\t\t\t$prefix = \"$filename:$linenr: \";\n\t\t\t}\n\t\t}\n\n\t\tif ($found_file) {\n\t\t\tif (is_maintained_obsolete($realfile)) {\n\t\t\t\tWARN(\"OBSOLETE\",\n\t\t\t\t     \"$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\\n\");\n\t\t\t}\n\t\t\tif ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {\n\t\t\t\t$check = 1;\n\t\t\t} else {\n\t\t\t\t$check = $check_orig;\n\t\t\t}\n\t\t\t$checklicenseline = 1;\n\n\t\t\tif ($realfile !~ /^MAINTAINERS/) {\n\t\t\t\tmy $last_binding_patch = $is_binding_patch;\n\n\t\t\t\t$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;\n\n\t\t\t\tif (($last_binding_patch != -1) &&\n\t\t\t\t    ($last_binding_patch ^ $is_binding_patch)) {\n\t\t\t\t\tWARN(\"DT_SPLIT_BINDING_PATCH\",\n\t\t\t\t\t     \"DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.rst\\n\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tnext;\n\t\t}\n\n\t\t$here .= \"FILE: $realfile:$realline:\" if ($realcnt != 0);\n\n\t\tmy $hereline = \"$here\\n$rawline\\n\";\n\t\tmy $herecurr = \"$here\\n$rawline\\n\";\n\t\tmy $hereprev = \"$here\\n$prevrawline\\n$rawline\\n\";\n\n\t\t$cnt_lines++ if ($realcnt != 0);\n\n# Verify the existence of a commit log if appropriate\n# 2 is used because a $signature is counted in $commit_log_lines\n\t\tif ($in_commit_log) {\n\t\t\tif ($line !~ /^\\s*$/) {\n\t\t\t\t$commit_log_lines++;\t#could be a $signature\n\t\t\t}\n\t\t} elsif ($has_commit_log && $commit_log_lines < 2) {\n\t\t\tWARN(\"COMMIT_MESSAGE\",\n\t\t\t     \"Missing commit description - Add an appropriate one\\n\");\n\t\t\t$commit_log_lines = 2;\t#warn only once\n\t\t}\n\n# Check if the commit log has what seems like a diff which can confuse patch\n\t\tif ($in_commit_log && !$commit_log_has_diff &&\n\t\t    (($line =~ m@^\\s+diff\\b.*a/([\\w/]+)@ &&\n\t\t      $line =~ m@^\\s+diff\\b.*a/[\\w/]+\\s+b/$1\\b@) ||\n\t\t     $line =~ m@^\\s*(?:\\-\\-\\-\\s+a/|\\+\\+\\+\\s+b/)@ ||\n\t\t     $line =~ m/^\\s*\\@\\@ \\-\\d+,\\d+ \\+\\d+,\\d+ \\@\\@/)) {\n\t\t\tERROR(\"DIFF_IN_COMMIT_MSG\",\n\t\t\t      \"Avoid using diff content in the commit message - patch(1) might not work\\n\" . $herecurr);\n\t\t\t$commit_log_has_diff = 1;\n\t\t}\n\n# Check for incorrect file permissions\n\t\tif ($line =~ /^new (file )?mode.*[7531]\\d{0,2}$/) {\n\t\t\tmy $permhere = $here . \"FILE: $realfile\\n\";\n\t\t\tif ($realfile !~ m@scripts/@ &&\n\t\t\t    $realfile !~ /\\.(py|pl|awk|sh)$/) {\n\t\t\t\tERROR(\"EXECUTE_PERMISSIONS\",\n\t\t\t\t      \"do not set execute permissions for source files\\n\" . $permhere);\n\t\t\t}\n\t\t}\n\n# Check the patch for a From:\n\t\tif (decode(\"MIME-Header\", $line) =~ /^From:\\s*(.*)/) {\n\t\t\t$author = $1;\n\t\t\tmy $curline = $linenr;\n\t\t\twhile(defined($rawlines[$curline]) && ($rawlines[$curline++] =~ /^[ \\t]\\s*(.*)/)) {\n\t\t\t\t$author .= $1;\n\t\t\t}\n\t\t\t$author = encode(\"utf8\", $author) if ($line =~ /=\\?utf-8\\?/i);\n\t\t\t$author =~ s/\"//g;\n\t\t\t$author = reformat_email($author);\n\t\t}\n\n# Check the patch for a signoff:\n\t\tif ($line =~ /^\\s*signed-off-by:\\s*(.*)/i) {\n\t\t\t$signoff++;\n\t\t\t$in_commit_log = 0;\n\t\t\tif ($author ne ''  && $authorsignoff != 1) {\n\t\t\t\tif (same_email_addresses($1, $author)) {\n\t\t\t\t\t$authorsignoff = 1;\n\t\t\t\t} else {\n\t\t\t\t\tmy $ctx = $1;\n\t\t\t\t\tmy ($email_name, $email_comment, $email_address, $comment1) = parse_email($ctx);\n\t\t\t\t\tmy ($author_name, $author_comment, $author_address, $comment2) = parse_email($author);\n\n\t\t\t\t\tif (lc $email_address eq lc $author_address && $email_name eq $author_name) {\n\t\t\t\t\t\t$author_sob = $ctx;\n\t\t\t\t\t\t$authorsignoff = 2;\n\t\t\t\t\t} elsif (lc $email_address eq lc $author_address) {\n\t\t\t\t\t\t$author_sob = $ctx;\n\t\t\t\t\t\t$authorsignoff = 3;\n\t\t\t\t\t} elsif ($email_name eq $author_name) {\n\t\t\t\t\t\t$author_sob = $ctx;\n\t\t\t\t\t\t$authorsignoff = 4;\n\n\t\t\t\t\t\tmy $address1 = $email_address;\n\t\t\t\t\t\tmy $address2 = $author_address;\n\n\t\t\t\t\t\tif ($address1 =~ /(\\S+)\\+\\S+(\\@.*)/) {\n\t\t\t\t\t\t\t$address1 = \"$1$2\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($address2 =~ /(\\S+)\\+\\S+(\\@.*)/) {\n\t\t\t\t\t\t\t$address2 = \"$1$2\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($address1 eq $address2) {\n\t\t\t\t\t\t\t$authorsignoff = 5;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# OpenOCD specific: Begin: Extend list of checkpatch tests to ignore\n\t\tif ($in_commit_log && $line =~ /^\\s*Checkpatch-ignore:\\s*(.*)/) {\n\t\t\tmy @array = split(/[\\s,]+/, $1);\n\t\t\thash_save_array_words(\\%ignore_type, \\@array);\n\t\t}\n# OpenOCD specific: End\n\n# Check for patch separator\n\t\tif ($line =~ /^---$/) {\n\t\t\t$has_patch_separator = 1;\n\t\t\t$in_commit_log = 0;\n\t\t}\n\n# Check if MAINTAINERS is being updated.  If so, there's probably no need to\n# emit the \"does MAINTAINERS need updating?\" message on file add/move/delete\n\t\tif ($line =~ /^\\s*MAINTAINERS\\s*\\|/) {\n\t\t\t$reported_maintainer_file = 1;\n\t\t}\n\n# Check signature styles\n\t\tif (!$in_header_lines &&\n\t\t    $line =~ /^(\\s*)([a-z0-9_-]+by:|$signature_tags)(\\s*)(.*)/i) {\n\t\t\tmy $space_before = $1;\n\t\t\tmy $sign_off = $2;\n\t\t\tmy $space_after = $3;\n\t\t\tmy $email = $4;\n\t\t\tmy $ucfirst_sign_off = ucfirst(lc($sign_off));\n\n\t\t\tif ($sign_off !~ /$signature_tags/) {\n\t\t\t\tmy $suggested_signature = find_standard_signature($sign_off);\n\t\t\t\tif ($suggested_signature eq \"\") {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t     \"Non-standard signature: $sign_off\\n\" . $herecurr);\n\t\t\t\t} else {\n\t\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t\t \"Non-standard signature: '$sign_off' - perhaps '$suggested_signature'?\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/$sign_off/$suggested_signature/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (defined $space_before && $space_before ne \"\") {\n\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t \"Do not use whitespace before $ucfirst_sign_off\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =\n\t\t\t\t\t    \"$ucfirst_sign_off $email\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {\n\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t \"'$ucfirst_sign_off' is the preferred signature form\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =\n\t\t\t\t\t    \"$ucfirst_sign_off $email\";\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tif (!defined $space_after || $space_after ne \" \") {\n\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t \"Use a single space after $ucfirst_sign_off\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =\n\t\t\t\t\t    \"$ucfirst_sign_off $email\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmy ($email_name, $name_comment, $email_address, $comment) = parse_email($email);\n\t\t\tmy $suggested_email = format_email(($email_name, $name_comment, $email_address, $comment));\n\t\t\tif ($suggested_email eq \"\") {\n\t\t\t\tERROR(\"BAD_SIGN_OFF\",\n\t\t\t\t      \"Unrecognized email address: '$email'\\n\" . $herecurr);\n\t\t\t} else {\n\t\t\t\tmy $dequoted = $suggested_email;\n\t\t\t\t$dequoted =~ s/^\"//;\n\t\t\t\t$dequoted =~ s/\" </ </;\n\t\t\t\t# Don't force email to have quotes\n\t\t\t\t# Allow just an angle bracketed address\n\t\t\t\tif (!same_email_addresses($email, $suggested_email)) {\n\t\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t\t \"email address '$email' might be better as '$suggested_email'\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$email\\E/$suggested_email/;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t# Address part shouldn't have comments\n\t\t\t\tmy $stripped_address = $email_address;\n\t\t\t\t$stripped_address =~ s/\\([^\\(\\)]*\\)//g;\n\t\t\t\tif ($email_address ne $stripped_address) {\n\t\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t\t \"address part of email should not have comments: '$email_address'\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$email_address\\E/$stripped_address/;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t# Only one name comment should be allowed\n\t\t\t\tmy $comment_count = () = $name_comment =~ /\\([^\\)]+\\)/g;\n\t\t\t\tif ($comment_count > 1) {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t     \"Use a single name comment in email: '$email'\\n\" . $herecurr);\n\t\t\t\t}\n\n\n\t\t\t\t# stable@vger.kernel.org or stable@kernel.org shouldn't\n\t\t\t\t# have an email name. In addition comments should strictly\n\t\t\t\t# begin with a #\n\t\t\t\tif ($email =~ /^.*stable\\@(?:vger\\.)?kernel\\.org/i) {\n\t\t\t\t\tif (($comment ne \"\" && $comment !~ /^#.+/) ||\n\t\t\t\t\t    ($email_name ne \"\")) {\n\t\t\t\t\t\tmy $cur_name = $email_name;\n\t\t\t\t\t\tmy $new_comment = $comment;\n\t\t\t\t\t\t$cur_name =~ s/[a-zA-Z\\s\\-\\\"]+//g;\n\n\t\t\t\t\t\t# Remove brackets enclosing comment text\n\t\t\t\t\t\t# and # from start of comments to get comment text\n\t\t\t\t\t\t$new_comment =~ s/^\\((.*)\\)$/$1/;\n\t\t\t\t\t\t$new_comment =~ s/^\\[(.*)\\]$/$1/;\n\t\t\t\t\t\t$new_comment =~ s/^[\\s\\#]+|\\s+$//g;\n\n\t\t\t\t\t\t$new_comment = trim(\"$new_comment $cur_name\") if ($cur_name ne $new_comment);\n\t\t\t\t\t\t$new_comment = \" # $new_comment\" if ($new_comment ne \"\");\n\t\t\t\t\t\tmy $new_email = \"$email_address$new_comment\";\n\n\t\t\t\t\t\tif (WARN(\"BAD_STABLE_ADDRESS_STYLE\",\n\t\t\t\t\t\t\t \"Invalid email format for stable: '$email', prefer '$new_email'\\n\" . $herecurr) &&\n\t\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$email\\E/$new_email/;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} elsif ($comment ne \"\" && $comment !~ /^(?:#.+|\\(.+\\))$/) {\n\t\t\t\t\tmy $new_comment = $comment;\n\n\t\t\t\t\t# Extract comment text from within brackets or\n\t\t\t\t\t# c89 style /*...*/ comments\n\t\t\t\t\t$new_comment =~ s/^\\[(.*)\\]$/$1/;\n\t\t\t\t\t$new_comment =~ s/^\\/\\*(.*)\\*\\/$/$1/;\n\n\t\t\t\t\t$new_comment = trim($new_comment);\n\t\t\t\t\t$new_comment =~ s/^[^\\w]$//; # Single lettered comment with non word character is usually a typo\n\t\t\t\t\t$new_comment = \"($new_comment)\" if ($new_comment ne \"\");\n\t\t\t\t\tmy $new_email = format_email($email_name, $name_comment, $email_address, $new_comment);\n\n\t\t\t\t\tif (WARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t\t \"Unexpected content after email: '$email', should be: '$new_email'\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$email\\E/$new_email/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n# Check for duplicate signatures\n\t\t\tmy $sig_nospace = $line;\n\t\t\t$sig_nospace =~ s/\\s//g;\n\t\t\t$sig_nospace = lc($sig_nospace);\n\t\t\tif (defined $signatures{$sig_nospace}) {\n\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t     \"Duplicate signature\\n\" . $herecurr);\n\t\t\t} else {\n\t\t\t\t$signatures{$sig_nospace} = 1;\n\t\t\t}\n\n# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email\n\t\t\tif ($sign_off =~ /^co-developed-by:$/i) {\n\t\t\t\tif ($email eq $author) {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t      \"Co-developed-by: should not be used to attribute nominal patch author '$author'\\n\" . \"$here\\n\" . $rawline);\n\t\t\t\t}\n\t\t\t\tif (!defined $lines[$linenr]) {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t     \"Co-developed-by: must be immediately followed by Signed-off-by:\\n\" . \"$here\\n\" . $rawline);\n\t\t\t\t} elsif ($rawlines[$linenr] !~ /^\\s*signed-off-by:\\s*(.*)/i) {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t     \"Co-developed-by: must be immediately followed by Signed-off-by:\\n\" . \"$here\\n\" . $rawline . \"\\n\" .$rawlines[$linenr]);\n\t\t\t\t} elsif ($1 ne $email) {\n\t\t\t\t\tWARN(\"BAD_SIGN_OFF\",\n\t\t\t\t\t     \"Co-developed-by and Signed-off-by: name/email do not match \\n\" . \"$here\\n\" . $rawline . \"\\n\" .$rawlines[$linenr]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check email subject for common tools that don't need to be mentioned\n\t\tif ($in_header_lines &&\n\t\t    $line =~ /^Subject:.*\\b(?:checkpatch|sparse|smatch)\\b[^:]/i) {\n\t\t\tWARN(\"EMAIL_SUBJECT\",\n\t\t\t     \"A patch subject line should describe the change not the tool that found it\\n\" . $herecurr);\n\t\t}\n\n# Check for Gerrit Change-Ids not in any patch context\n\t\tif ($realfile eq '' && !$has_patch_separator && $line =~ /^\\s*change-id:/i) {\n\t\t\tif (ERROR(\"GERRIT_CHANGE_ID\",\n\t\t\t          \"Remove Gerrit Change-Id's before submitting upstream\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t}\n\t\t}\n\n# Check if the commit log is in a possible stack dump\n\t\tif ($in_commit_log && !$commit_log_possible_stack_dump &&\n\t\t    ($line =~ /^\\s*(?:WARNING:|BUG:)/ ||\n\t\t     $line =~ /^\\s*\\[\\s*\\d+\\.\\d{6,6}\\s*\\]/ ||\n\t\t\t\t\t# timestamp\n\t\t     $line =~ /^\\s*\\[\\<[0-9a-fA-F]{8,}\\>\\]/) ||\n\t\t     $line =~ /^(?:\\s+\\w+:\\s+[0-9a-fA-F]+){3,3}/ ||\n\t\t     $line =~ /^\\s*\\#\\d+\\s*\\[[0-9a-fA-F]+\\]\\s*\\w+ at [0-9a-fA-F]+/) {\n\t\t\t\t\t# stack dump address styles\n\t\t\t$commit_log_possible_stack_dump = 1;\n\t\t}\n\n# Check for line lengths > 75 in commit log, warn once\n\t\tif ($in_commit_log && !$commit_log_long_line &&\n\t\t    length($line) > 75 &&\n\t\t    !($line =~ /^\\s*[a-zA-Z0-9_\\/\\.]+\\s+\\|\\s+\\d+/ ||\n\t\t\t\t\t# file delta changes\n\t\t      $line =~ /^\\s*(?:[\\w\\.\\-\\+]*\\/)++[\\w\\.\\-\\+]+:/ ||\n\t\t\t\t\t# filename then :\n\t\t      $line =~ /^\\s*(?:Fixes:|Link:|$signature_tags)/i ||\n\t\t\t\t\t# A Fixes: or Link: line or signature tag line\n\t\t      $commit_log_possible_stack_dump)) {\n\t\t\tWARN(\"COMMIT_LOG_LONG_LINE\",\n\t\t\t     \"Possible unwrapped commit description (prefer a maximum 75 chars per line)\\n\" . $herecurr);\n\t\t\t$commit_log_long_line = 1;\n\t\t}\n\n# Reset possible stack dump if a blank line is found\n\t\tif ($in_commit_log && $commit_log_possible_stack_dump &&\n\t\t    $line =~ /^\\s*$/) {\n\t\t\t$commit_log_possible_stack_dump = 0;\n\t\t}\n\n# Check for lines starting with a #\n\t\tif ($in_commit_log && $line =~ /^#/) {\n\t\t\tif (WARN(\"COMMIT_COMMENT_SYMBOL\",\n\t\t\t\t \"Commit log lines starting with '#' are dropped by git as comments\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/^/ /;\n\t\t\t}\n\t\t}\n\n# Check for git id commit length and improperly formed commit descriptions\n# A correctly formed commit description is:\n#    commit <SHA-1 hash length 12+ chars> (\"Complete commit subject\")\n# with the commit subject '(\"' prefix and '\")' suffix\n# This is a fairly compilicated block as it tests for what appears to be\n# bare SHA-1 hash with  minimum length of 5.  It also avoids several types of\n# possible SHA-1 matches.\n# A commit match can span multiple lines so this block attempts to find a\n# complete typical commit on a maximum of 3 lines\n\t\tif ($perl_version_ok &&\n\t\t    $in_commit_log && !$commit_log_possible_stack_dump &&\n\t\t    $line !~ /^\\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&\n\t\t    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&\n\t\t    (($line =~ /\\bcommit\\s+[0-9a-f]{5,}\\b/i ||\n\t\t      ($line =~ /\\bcommit\\s*$/i && defined($rawlines[$linenr]) && $rawlines[$linenr] =~ /^\\s*[0-9a-f]{5,}\\b/i)) ||\n\t\t     ($line =~ /(?:\\s|^)[0-9a-f]{12,40}(?:[\\s\"'\\(\\[]|$)/i &&\n\t\t      $line !~ /[\\<\\[][0-9a-f]{12,40}[\\>\\]]/i &&\n\t\t      $line !~ /\\bfixes:\\s*[0-9a-f]{12,40}/i))) {\n\t\t\tmy $init_char = \"c\";\n\t\t\tmy $orig_commit = \"\";\n\t\t\tmy $short = 1;\n\t\t\tmy $long = 0;\n\t\t\tmy $case = 1;\n\t\t\tmy $space = 1;\n\t\t\tmy $id = '0123456789ab';\n\t\t\tmy $orig_desc = \"commit description\";\n\t\t\tmy $description = \"\";\n\t\t\tmy $herectx = $herecurr;\n\t\t\tmy $has_parens = 0;\n\t\t\tmy $has_quotes = 0;\n\n\t\t\tmy $input = $line;\n\t\t\tif ($line =~ /(?:\\bcommit\\s+[0-9a-f]{5,}|\\bcommit\\s*$)/i) {\n\t\t\t\tfor (my $n = 0; $n < 2; $n++) {\n\t\t\t\t\tif ($input =~ /\\bcommit\\s+[0-9a-f]{5,}\\s*($balanced_parens)/i) {\n\t\t\t\t\t\t$orig_desc = $1;\n\t\t\t\t\t\t$has_parens = 1;\n\t\t\t\t\t\t# Always strip leading/trailing parens then double quotes if existing\n\t\t\t\t\t\t$orig_desc = substr($orig_desc, 1, -1);\n\t\t\t\t\t\tif ($orig_desc =~ /^\".*\"$/) {\n\t\t\t\t\t\t\t$orig_desc = substr($orig_desc, 1, -1);\n\t\t\t\t\t\t\t$has_quotes = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlast;\n\t\t\t\t\t}\n\t\t\t\t\tlast if ($#lines < $linenr + $n);\n\t\t\t\t\t$input .= \" \" . trim($rawlines[$linenr + $n]);\n\t\t\t\t\t$herectx .= \"$rawlines[$linenr + $n]\\n\";\n\t\t\t\t}\n\t\t\t\t$herectx = $herecurr if (!$has_parens);\n\t\t\t}\n\n\t\t\tif ($input =~ /\\b(c)ommit\\s+([0-9a-f]{5,})\\b/i) {\n\t\t\t\t$init_char = $1;\n\t\t\t\t$orig_commit = lc($2);\n\t\t\t\t$short = 0 if ($input =~ /\\bcommit\\s+[0-9a-f]{12,40}/i);\n\t\t\t\t$long = 1 if ($input =~ /\\bcommit\\s+[0-9a-f]{41,}/i);\n\t\t\t\t$space = 0 if ($input =~ /\\bcommit [0-9a-f]/i);\n\t\t\t\t$case = 0 if ($input =~ /\\b[Cc]ommit\\s+[0-9a-f]{5,40}[^A-F]/);\n\t\t\t} elsif ($input =~ /\\b([0-9a-f]{12,40})\\b/i) {\n\t\t\t\t$orig_commit = lc($1);\n\t\t\t}\n\n\t\t\t($id, $description) = git_commit_info($orig_commit,\n\t\t\t\t\t\t\t      $id, $orig_desc);\n\n\t\t\tif (defined($id) &&\n\t\t\t    ($short || $long || $space || $case || ($orig_desc ne $description) || !$has_quotes) &&\n\t\t\t    $last_git_commit_id_linenr != $linenr - 1) {\n\t\t\t\tERROR(\"GIT_COMMIT_ID\",\n\t\t\t\t      \"Please use git commit description style 'commit <12+ chars of sha1> (\\\"<title line>\\\")' - ie: '${init_char}ommit $id (\\\"$description\\\")'\\n\" . $herectx);\n\t\t\t}\n\t\t\t#don't report the next line if this line ends in commit and the sha1 hash is the next line\n\t\t\t$last_git_commit_id_linenr = $linenr if ($line =~ /\\bcommit\\s*$/i);\n\t\t}\n\n# Check for added, moved or deleted files\n\t\tif (!$reported_maintainer_file && !$in_commit_log &&\n\t\t    ($line =~ /^(?:new|deleted) file mode\\s*\\d+\\s*$/ ||\n\t\t     $line =~ /^rename (?:from|to) [\\w\\/\\.\\-]+\\s*$/ ||\n\t\t     ($line =~ /\\{\\s*([\\w\\/\\.\\-]*)\\s*\\=\\>\\s*([\\w\\/\\.\\-]*)\\s*\\}/ &&\n\t\t      (defined($1) || defined($2))))) {\n\t\t\t$is_patch = 1;\n\t\t\t$reported_maintainer_file = 1;\n\t\t\tWARN(\"FILE_PATH_CHANGES\",\n\t\t\t     \"added, moved or deleted file(s), does MAINTAINERS need updating?\\n\" . $herecurr);\n\t\t}\n\n# Check for adding new DT bindings not in schema format\n\t\tif (!$in_commit_log &&\n\t\t    ($line =~ /^new file mode\\s*\\d+\\s*$/) &&\n\t\t    ($realfile =~ m@^Documentation/devicetree/bindings/.*\\.txt$@)) {\n\t\t\tWARN(\"DT_SCHEMA_BINDING_PATCH\",\n\t\t\t     \"DT bindings should be in DT schema format. See: Documentation/devicetree/bindings/writing-schema.rst\\n\");\n\t\t}\n\n# Check for wrappage within a valid hunk of the file\n\t\tif ($realcnt != 0 && $line !~ m{^(?:\\+|-| |\\\\ No newline|$)}) {\n\t\t\tERROR(\"CORRUPTED_PATCH\",\n\t\t\t      \"patch seems to be corrupt (line wrapped?)\\n\" .\n\t\t\t\t$herecurr) if (!$emitted_corrupt++);\n\t\t}\n\n# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php\n\t\tif (($realfile =~ /^$/ || $line =~ /^\\+/) &&\n\t\t    $rawline !~ m/^$UTF8*$/) {\n\t\t\tmy ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);\n\n\t\t\tmy $blank = copy_spacing($rawline);\n\t\t\tmy $ptr = substr($blank, 0, length($utf8_prefix)) . \"^\";\n\t\t\tmy $hereptr = \"$hereline$ptr\\n\";\n\n\t\t\tCHK(\"INVALID_UTF8\",\n\t\t\t    \"Invalid UTF-8, patch and commit message should be encoded in UTF-8\\n\" . $hereptr);\n\t\t}\n\n# Check if it's the start of a commit log\n# (not a header line and we haven't seen the patch filename)\n\t\tif ($in_header_lines && $realfile =~ /^$/ &&\n\t\t    !($rawline =~ /^\\s+(?:\\S|$)/ ||\n\t\t      $rawline =~ /^(?:commit\\b|from\\b|[\\w-]+:)/i)) {\n\t\t\t$in_header_lines = 0;\n\t\t\t$in_commit_log = 1;\n\t\t\t$has_commit_log = 1;\n\t\t}\n\n# Check if there is UTF-8 in a commit log when a mail header has explicitly\n# declined it, i.e defined some charset where it is missing.\n\t\tif ($in_header_lines &&\n\t\t    $rawline =~ /^Content-Type:.+charset=\"(.+)\".*$/ &&\n\t\t    $1 !~ /utf-8/i) {\n\t\t\t$non_utf8_charset = 1;\n\t\t}\n\n\t\tif ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&\n\t\t    $rawline =~ /$NON_ASCII_UTF8/) {\n\t\t\tWARN(\"UTF8_BEFORE_PATCH\",\n\t\t\t    \"8-bit UTF-8 used in possible commit log\\n\" . $herecurr);\n\t\t}\n\n# Check for absolute kernel paths in commit message\n\t\tif ($tree && $in_commit_log) {\n\t\t\twhile ($line =~ m{(?:^|\\s)(/\\S*)}g) {\n\t\t\t\tmy $file = $1;\n\n\t\t\t\tif ($file =~ m{^(.*?)(?::\\d+)+:?$} &&\n\t\t\t\t    check_absolute_file($1, $herecurr)) {\n\t\t\t\t\t#\n\t\t\t\t} else {\n\t\t\t\t\tcheck_absolute_file($file, $herecurr);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check for various typo / spelling mistakes\n\t\tif (defined($misspellings) &&\n\t\t    # OpenOCD specific: Begin: don't check spelling on spelling_file\n\t\t    index($spelling_file, $realfile) + length($realfile) != length($spelling_file) &&\n\t\t    # OpenOCD specific: End\n\t\t    ($in_commit_log || $line =~ /^(?:\\+|Subject:)/i)) {\n\t\t\twhile ($rawline =~ /(?:^|[^\\w\\-'`])($misspellings)(?:[^\\w\\-'`]|$)/gi) {\n\t\t\t\tmy $typo = $1;\n\t\t\t\tmy $blank = copy_spacing($rawline);\n\t\t\t\tmy $ptr = substr($blank, 0, $-[1]) . \"^\" x length($typo);\n\t\t\t\tmy $hereptr = \"$hereline$ptr\\n\";\n\t\t\t\tmy $typo_fix = $spelling_fix{lc($typo)};\n\t\t\t\t$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);\n\t\t\t\t$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);\n\t\t\t\tmy $msg_level = \\&WARN;\n\t\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t\tif (&{$msg_level}(\"TYPO_SPELLING\",\n\t\t\t\t\t\t  \"'$typo' may be misspelled - perhaps '$typo_fix'?\\n\" . $hereptr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for invalid commit id\n\t\tif ($in_commit_log && $line =~ /(^fixes:|\\bcommit)\\s+([0-9a-f]{6,40})\\b/i) {\n\t\t\tmy $id;\n\t\t\tmy $description;\n\t\t\t($id, $description) = git_commit_info($2, undef, undef);\n\t\t\tif (!defined($id)) {\n\t\t\t\tWARN(\"UNKNOWN_COMMIT_ID\",\n\t\t\t\t     \"Unknown commit id '$2', maybe rebased or not pulled?\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for repeated words separated by a single space\n# avoid false positive from list command eg, '-rw-r--r-- 1 root root'\n\t\tif (($rawline =~ /^\\+/ || $in_commit_log) &&\n\t\t    $rawline !~ /[bcCdDlMnpPs\\?-][rwxsStT-]{9}/) {\n\t\t\tpos($rawline) = 1 if (!$in_commit_log);\n\t\t\twhile ($rawline =~ /\\b($word_pattern) (?=($word_pattern))/g) {\n\n\t\t\t\tmy $first = $1;\n\t\t\t\tmy $second = $2;\n\t\t\t\tmy $start_pos = $-[1];\n\t\t\t\tmy $end_pos = $+[2];\n\t\t\t\tif ($first =~ /(?:struct|union|enum)/) {\n\t\t\t\t\tpos($rawline) += length($first) + length($second) + 1;\n\t\t\t\t\tnext;\n\t\t\t\t}\n\n\t\t\t\tnext if (lc($first) ne lc($second));\n\t\t\t\tnext if ($first eq 'long');\n\n\t\t\t\t# check for character before and after the word matches\n\t\t\t\tmy $start_char = '';\n\t\t\t\tmy $end_char = '';\n\t\t\t\t$start_char = substr($rawline, $start_pos - 1, 1) if ($start_pos > ($in_commit_log ? 0 : 1));\n\t\t\t\t$end_char = substr($rawline, $end_pos, 1) if ($end_pos < length($rawline));\n\n\t\t\t\tnext if ($start_char =~ /^\\S$/);\n\t\t\t\tnext if (index(\" \\t.,;?!\", $end_char) == -1);\n\n\t\t\t\t# avoid repeating hex occurrences like 'ff ff fe 09 ...'\n\t\t\t\tif ($first =~ /\\b[0-9a-f]{2,}\\b/i) {\n\t\t\t\t\tnext if (!exists($allow_repeated_words{lc($first)}));\n\t\t\t\t}\n\n\t\t\t\tif (WARN(\"REPEATED_WORD\",\n\t\t\t\t\t \"Possible repeated word: '$first'\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\b$first $second\\b/$first/;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# if it's a repeated word on consecutive lines in a comment block\n\t\t\tif ($prevline =~ /$;+\\s*$/ &&\n\t\t\t    $prevrawline =~ /($word_pattern)\\s*$/) {\n\t\t\t\tmy $last_word = $1;\n\t\t\t\tif ($rawline =~ /^\\+\\s*\\*\\s*$last_word /) {\n\t\t\t\t\tif (WARN(\"REPEATED_WORD\",\n\t\t\t\t\t\t \"Possible repeated word: '$last_word'\\n\" . $hereprev) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/(\\+\\s*\\*\\s*)$last_word /$1/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# ignore non-hunk lines and lines being removed\n\t\tnext if (!$hunk_line || $line =~ /^-/);\n\n#trailing whitespace\n\t\tif ($line =~ /^\\+.*\\015/) {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\tif (ERROR(\"DOS_LINE_ENDINGS\",\n\t\t\t\t  \"DOS line endings\\n\" . $herevet) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/[\\s\\015]+$//;\n\t\t\t}\n\t\t} elsif ($rawline =~ /^\\+.*\\S\\s+$/ || $rawline =~ /^\\+\\s+$/) {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\tif (ERROR(\"TRAILING_WHITESPACE\",\n\t\t\t\t  \"trailing whitespace\\n\" . $herevet) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\s+$//;\n\t\t\t}\n\n\t\t\t$rpt_cleaners = 1;\n\t\t}\n\n# Check for FSF mailing addresses.\n\t\tif ($rawline =~ /\\bwrite to the Free/i ||\n\t\t    $rawline =~ /\\b675\\s+Mass\\s+Ave/i ||\n\t\t    $rawline =~ /\\b59\\s+Temple\\s+Pl/i ||\n\t\t    $rawline =~ /\\b51\\s+Franklin\\s+St/i) {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\tmy $msg_level = \\&ERROR;\n\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t&{$msg_level}(\"FSF_MAILING_ADDRESS\",\n\t\t\t\t      \"Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. OpenOCD already includes a copy of the GPL.\\n\" . $herevet)\n\t\t}\n\n# check for Kconfig help text having a real description\n# Only applies when adding the entry originally, after that we do not have\n# sufficient context to determine whether it is indeed long enough.\n\t\tif ($realfile =~ /Kconfig/ &&\n\t\t    # 'choice' is usually the last thing on the line (though\n\t\t    # Kconfig supports named choices), so use a word boundary\n\t\t    # (\\b) rather than a whitespace character (\\s)\n\t\t    $line =~ /^\\+\\s*(?:config|menuconfig|choice)\\b/) {\n\t\t\tmy $ln = $linenr;\n\t\t\tmy $needs_help = 0;\n\t\t\tmy $has_help = 0;\n\t\t\tmy $help_length = 0;\n\t\t\twhile (defined $lines[$ln]) {\n\t\t\t\tmy $f = $lines[$ln++];\n\n\t\t\t\tnext if ($f =~ /^-/);\n\t\t\t\tlast if ($f !~ /^[\\+ ]/);\t# !patch context\n\n\t\t\t\tif ($f =~ /^\\+\\s*(?:bool|tristate|prompt)\\s*[\"']/) {\n\t\t\t\t\t$needs_help = 1;\n\t\t\t\t\tnext;\n\t\t\t\t}\n\t\t\t\tif ($f =~ /^\\+\\s*help\\s*$/) {\n\t\t\t\t\t$has_help = 1;\n\t\t\t\t\tnext;\n\t\t\t\t}\n\n\t\t\t\t$f =~ s/^.//;\t# strip patch context [+ ]\n\t\t\t\t$f =~ s/#.*//;\t# strip # directives\n\t\t\t\t$f =~ s/^\\s+//;\t# strip leading blanks\n\t\t\t\tnext if ($f =~ /^$/);\t# skip blank lines\n\n\t\t\t\t# At the end of this Kconfig block:\n\t\t\t\t# This only checks context lines in the patch\n\t\t\t\t# and so hopefully shouldn't trigger false\n\t\t\t\t# positives, even though some of these are\n\t\t\t\t# common words in help texts\n\t\t\t\tif ($f =~ /^(?:config|menuconfig|choice|endchoice|\n\t\t\t\t\t       if|endif|menu|endmenu|source)\\b/x) {\n\t\t\t\t\tlast;\n\t\t\t\t}\n\t\t\t\t$help_length++ if ($has_help);\n\t\t\t}\n\t\t\tif ($needs_help &&\n\t\t\t    $help_length < $min_conf_desc_length) {\n\t\t\t\tmy $stat_real = get_stat_real($linenr, $ln - 1);\n\t\t\t\tWARN(\"CONFIG_DESCRIPTION\",\n\t\t\t\t     \"please write a help paragraph that fully describes the config symbol\\n\" . \"$here\\n$stat_real\\n\");\n\t\t\t}\n\t\t}\n\n# check MAINTAINERS entries\n\t\tif ($realfile =~ /^MAINTAINERS$/) {\n# check MAINTAINERS entries for the right form\n\t\t\tif ($rawline =~ /^\\+[A-Z]:/ &&\n\t\t\t    $rawline !~ /^\\+[A-Z]:\\t\\S/) {\n\t\t\t\tif (WARN(\"MAINTAINERS_STYLE\",\n\t\t\t\t\t \"MAINTAINERS entries use one tab after TYPE:\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/^(\\+[A-Z]):\\s*/$1:\\t/;\n\t\t\t\t}\n\t\t\t}\n# check MAINTAINERS entries for the right ordering too\n\t\t\tmy $preferred_order = 'MRLSWQBCPTFXNK';\n\t\t\tif ($rawline =~ /^\\+[A-Z]:/ &&\n\t\t\t    $prevrawline =~ /^[\\+ ][A-Z]:/) {\n\t\t\t\t$rawline =~ /^\\+([A-Z]):\\s*(.*)/;\n\t\t\t\tmy $cur = $1;\n\t\t\t\tmy $curval = $2;\n\t\t\t\t$prevrawline =~ /^[\\+ ]([A-Z]):\\s*(.*)/;\n\t\t\t\tmy $prev = $1;\n\t\t\t\tmy $prevval = $2;\n\t\t\t\tmy $curindex = index($preferred_order, $cur);\n\t\t\t\tmy $previndex = index($preferred_order, $prev);\n\t\t\t\tif ($curindex < 0) {\n\t\t\t\t\tWARN(\"MAINTAINERS_STYLE\",\n\t\t\t\t\t     \"Unknown MAINTAINERS entry type: '$cur'\\n\" . $herecurr);\n\t\t\t\t} else {\n\t\t\t\t\tif ($previndex >= 0 && $curindex < $previndex) {\n\t\t\t\t\t\tWARN(\"MAINTAINERS_STYLE\",\n\t\t\t\t\t\t     \"Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\\n\" . $hereprev);\n\t\t\t\t\t} elsif ((($prev eq 'F' && $cur eq 'F') ||\n\t\t\t\t\t\t  ($prev eq 'X' && $cur eq 'X')) &&\n\t\t\t\t\t\t ($prevval cmp $curval) > 0) {\n\t\t\t\t\t\tWARN(\"MAINTAINERS_STYLE\",\n\t\t\t\t\t\t     \"Misordered MAINTAINERS entry - list file patterns in alphabetic order\\n\" . $hereprev);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&\n\t\t    ($line =~ /\\+(EXTRA_[A-Z]+FLAGS).*/)) {\n\t\t\tmy $flag = $1;\n\t\t\tmy $replacement = {\n\t\t\t\t'EXTRA_AFLAGS' =>   'asflags-y',\n\t\t\t\t'EXTRA_CFLAGS' =>   'ccflags-y',\n\t\t\t\t'EXTRA_CPPFLAGS' => 'cppflags-y',\n\t\t\t\t'EXTRA_LDFLAGS' =>  'ldflags-y',\n\t\t\t};\n\n\t\t\tWARN(\"DEPRECATED_VARIABLE\",\n\t\t\t     \"Use of $flag is deprecated, please use \\`$replacement->{$flag} instead.\\n\" . $herecurr) if ($replacement->{$flag});\n\t\t}\n\n# check for DT compatible documentation\n\t\tif (defined $root &&\n\t\t\t(($realfile =~ /\\.dtsi?$/ && $line =~ /^\\+\\s*compatible\\s*=\\s*\\\"/) ||\n\t\t\t ($realfile =~ /\\.[ch]$/ && $line =~ /^\\+.*\\.compatible\\s*=\\s*\\\"/))) {\n\n\t\t\tmy @compats = $rawline =~ /\\\"([a-zA-Z0-9\\-\\,\\.\\+_]+)\\\"/g;\n\n\t\t\tmy $dt_path = $root . \"/Documentation/devicetree/bindings/\";\n\t\t\tmy $vp_file = $dt_path . \"vendor-prefixes.yaml\";\n\n\t\t\tforeach my $compat (@compats) {\n\t\t\t\tmy $compat2 = $compat;\n\t\t\t\t$compat2 =~ s/\\,[a-zA-Z0-9]*\\-/\\,<\\.\\*>\\-/;\n\t\t\t\tmy $compat3 = $compat;\n\t\t\t\t$compat3 =~ s/\\,([a-z]*)[0-9]*\\-/\\,$1<\\.\\*>\\-/;\n\t\t\t\t`grep -Erq \"$compat|$compat2|$compat3\" $dt_path`;\n\t\t\t\tif ( $? >> 8 ) {\n\t\t\t\t\tWARN(\"UNDOCUMENTED_DT_STRING\",\n\t\t\t\t\t     \"DT compatible string \\\"$compat\\\" appears un-documented -- check $dt_path\\n\" . $herecurr);\n\t\t\t\t}\n\n\t\t\t\tnext if $compat !~ /^([a-zA-Z0-9\\-]+)\\,/;\n\t\t\t\tmy $vendor = $1;\n\t\t\t\t`grep -Eq \"\\\\\"\\\\^\\Q$vendor\\E,\\\\.\\\\*\\\\\":\" $vp_file`;\n\t\t\t\tif ( $? >> 8 ) {\n\t\t\t\t\tWARN(\"UNDOCUMENTED_DT_STRING\",\n\t\t\t\t\t     \"DT compatible string vendor \\\"$vendor\\\" appears un-documented -- check $vp_file\\n\" . $herecurr);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for using SPDX license tag at beginning of files\n\t\tif ($realline == $checklicenseline) {\n\t\t\tif ($rawline =~ /^[ \\+]\\s*\\#\\!\\s*\\//) {\n\t\t\t\t$checklicenseline = 2;\n\t\t\t} elsif ($rawline =~ /^\\+/) {\n\t\t\t\tmy $comment = \"\";\n\t\t\t\tif ($realfile =~ /\\.(h|s|S)$/) {\n\t\t\t\t\t$comment = '/*';\n\t\t\t\t} elsif ($realfile =~ /\\.(c|dts|dtsi)$/) {\n\t\t\t\t\t$comment = '//';\n\t\t\t\t} elsif (($checklicenseline == 2) || $realfile =~ /\\.(sh|pl|py|awk|tc|yaml)$/) {\n\t\t\t\t\t$comment = '#';\n\t\t\t\t} elsif ($realfile =~ /\\.rst$/) {\n\t\t\t\t\t$comment = '..';\n\t\t\t\t# OpenOCD specific: Begin\n\t\t\t\t} elsif ($realfile =~ /\\.(am|cfg|tcl)$/) {\n\t\t\t\t\t$comment = '#';\n\t\t\t\t# OpenOCD specific: End\n\t\t\t\t}\n\n# check SPDX comment style for .[chsS] files\n\t\t\t\tif ($realfile =~ /\\.[chsS]$/ &&\n\t\t\t\t    $rawline =~ /SPDX-License-Identifier:/ &&\n\t\t\t\t    $rawline !~ m@^\\+\\s*\\Q$comment\\E\\s*@) {\n\t\t\t\t\tWARN(\"SPDX_LICENSE_TAG\",\n\t\t\t\t\t     \"Improper SPDX comment style for '$realfile', please use '$comment' instead\\n\" . $herecurr);\n\t\t\t\t}\n\n\t\t\t\tif ($comment !~ /^$/ &&\n\t\t\t\t    $rawline !~ m@^\\+\\Q$comment\\E SPDX-License-Identifier: @) {\n\t\t\t\t\tWARN(\"SPDX_LICENSE_TAG\",\n\t\t\t\t\t     \"Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\\n\" . $herecurr);\n\t\t\t\t} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {\n\t\t\t\t\tmy $spdx_license = $1;\n\t\t\t\t\tif (!is_SPDX_License_valid($spdx_license)) {\n\t\t\t\t\t\tWARN(\"SPDX_LICENSE_TAG\",\n\t\t\t\t\t\t     \"'$spdx_license' is not supported in LICENSES/...\\n\" . $herecurr);\n\t\t\t\t\t}\n\t\t\t\t\tif ($realfile =~ m@^Documentation/devicetree/bindings/@ &&\n\t\t\t\t\t    not $spdx_license =~ /GPL-2\\.0.*BSD-2-Clause/) {\n\t\t\t\t\t\tmy $msg_level = \\&WARN;\n\t\t\t\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t\t\t\tif (&{$msg_level}(\"SPDX_LICENSE_TAG\",\n\n\t\t\t\t\t\t\t\t  \"DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\\n\" . $herecurr) &&\n\t\t\t\t\t\t    $fix) {\n\t\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for embedded filenames\n\t\tif ($rawline =~ /^\\+.*\\Q$realfile\\E/) {\n\t\t\tWARN(\"EMBEDDED_FILENAME\",\n\t\t\t     \"It's generally not useful to have the filename in the file\\n\" . $herecurr);\n\t\t}\n\n# check we are in a valid source file if not then ignore this hunk\n\t\tnext if ($realfile !~ /\\.(h|c|s|S|sh|dtsi|dts)$/);\n\n# check for using SPDX-License-Identifier on the wrong line number\n\t\tif ($realline != $checklicenseline &&\n\t\t    $rawline =~ /\\bSPDX-License-Identifier:/ &&\n\t\t    substr($line, @-, @+ - @-) eq \"$;\" x (@+ - @-)) {\n\t\t\tWARN(\"SPDX_LICENSE_TAG\",\n\t\t\t     \"Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\\n\" . $herecurr);\n\t\t}\n\n# line length limit (with some exclusions)\n#\n# There are a few types of lines that may extend beyond $max_line_length:\n#\tlogging functions like pr_info that end in a string\n#\tlines with a single string\n#\t#defines that are a single string\n#\tlines with an RFC3986 like URL\n#\n# There are 3 different line length message types:\n# LONG_LINE_COMMENT\ta comment starts before but extends beyond $max_line_length\n# LONG_LINE_STRING\ta string starts before but extends beyond $max_line_length\n# LONG_LINE\t\tall other lines longer than $max_line_length\n#\n# if LONG_LINE is ignored, the other 2 types are also ignored\n#\n\n\t\tif ($line =~ /^\\+/ && $length > $max_line_length) {\n\t\t\tmy $msg_type = \"LONG_LINE\";\n\n\t\t\t# Check the allowed long line types first\n\n\t\t\t# logging functions that end in a string that starts\n\t\t\t# before $max_line_length\n\t\t\tif ($line =~ /^\\+\\s*$logFunctions\\s*\\(\\s*(?:(?:KERN_\\S+\\s*|[^\"]*))?($String\\s*(?:|,|\\)\\s*;)\\s*)$/ &&\n\t\t\t    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {\n\t\t\t\t$msg_type = \"\";\n\n\t\t\t# lines with only strings (w/ possible termination)\n\t\t\t# #defines with only strings\n\t\t\t} elsif ($line =~ /^\\+\\s*$String\\s*(?:\\s*|,|\\)\\s*;)\\s*$/ ||\n\t\t\t\t $line =~ /^\\+\\s*#\\s*define\\s+\\w+\\s+$String$/) {\n\t\t\t\t$msg_type = \"\";\n\n\t\t\t# More special cases\n\t\t\t} elsif ($line =~ /^\\+.*\\bEFI_GUID\\s*\\(/ ||\n\t\t\t\t $line =~ /^\\+\\s*(?:\\w+)?\\s*DEFINE_PER_CPU/) {\n\t\t\t\t$msg_type = \"\";\n\n\t\t\t# URL ($rawline is used in case the URL is in a comment)\n\t\t\t} elsif ($rawline =~ /^\\+.*\\b[a-z][\\w\\.\\+\\-]*:\\/\\/\\S+/i) {\n\t\t\t\t$msg_type = \"\";\n\n\t\t\t# Otherwise set the alternate message types\n\n\t\t\t# a comment starts before $max_line_length\n\t\t\t} elsif ($line =~ /($;[\\s$;]*)$/ &&\n\t\t\t\t length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {\n\t\t\t\t$msg_type = \"LONG_LINE_COMMENT\"\n\n\t\t\t# a quoted string starts before $max_line_length\n\t\t\t} elsif ($sline =~ /\\s*($String(?:\\s*(?:\\\\|,\\s*|\\)\\s*;\\s*))?)$/ &&\n\t\t\t\t length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {\n\t\t\t\t$msg_type = \"LONG_LINE_STRING\"\n\t\t\t}\n\n\t\t\tif ($msg_type ne \"\" &&\n\t\t\t    (show_type(\"LONG_LINE\") || show_type($msg_type))) {\n\t\t\t\tmy $msg_level = \\&WARN;\n\t\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t\t&{$msg_level}($msg_type,\n\t\t\t\t\t      \"line length of $length exceeds $max_line_length columns\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for adding lines without a newline.\n\t\tif ($line =~ /^\\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\\\ No newline at end of file/) {\n\t\t\tif (WARN(\"MISSING_EOF_NEWLINE\",\n\t\t\t         \"adding a line without newline at end of file\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_delete_line($fixlinenr+1, \"No newline at end of file\");\n\t\t\t}\n\t\t}\n\n# check for .L prefix local symbols in .S files\n\t\tif ($realfile =~ /\\.S$/ &&\n\t\t    $line =~ /^\\+\\s*(?:[A-Z]+_)?SYM_[A-Z]+_(?:START|END)(?:_[A-Z_]+)?\\s*\\(\\s*\\.L/) {\n\t\t\tWARN(\"AVOID_L_PREFIX\",\n\t\t\t     \"Avoid using '.L' prefixed local symbol names for denoting a range of code via 'SYM_*_START/END' annotations; see Documentation/asm-annotations.rst\\n\" . $herecurr);\n\t\t}\n\n# check we are in a valid source file C or perl if not then ignore this hunk\n\t\tnext if ($realfile !~ /\\.(h|c|pl|dtsi|dts)$/);\n\n# at the beginning of a line any tabs must come first and anything\n# more than $tabsize must use tabs.\n\t\tif ($rawline =~ /^\\+\\s* \\t\\s*\\S/ ||\n\t\t    $rawline =~ /^\\+\\s*        \\s*/) {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\t$rpt_cleaners = 1;\n\t\t\tif (ERROR(\"CODE_INDENT\",\n\t\t\t\t  \"code indent should use tabs where possible\\n\" . $herevet) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/^\\+([ \\t]+)/\"\\+\" . tabify($1)/e;\n\t\t\t}\n\t\t}\n\n# check for space before tabs.\n\t\tif ($rawline =~ /^\\+/ && $rawline =~ / \\t/) {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\tif (WARN(\"SPACE_BEFORE_TAB\",\n\t\t\t\t\"please, no space before tabs\\n\" . $herevet) &&\n\t\t\t    $fix) {\n\t\t\t\twhile ($fixed[$fixlinenr] =~\n\t\t\t\t\t   s/(^\\+.*) {$tabsize,$tabsize}\\t/$1\\t\\t/) {}\n\t\t\t\twhile ($fixed[$fixlinenr] =~\n\t\t\t\t\t   s/(^\\+.*) +\\t/$1\\t/) {}\n\t\t\t}\n\t\t}\n\n# check for assignments on the start of a line\n\t\tif ($sline =~ /^\\+\\s+($Assignment)[^=]/) {\n\t\t\tmy $operator = $1;\n\t\t\tif (CHK(\"ASSIGNMENT_CONTINUATIONS\",\n\t\t\t\t\"Assignment operator '$1' should be on the previous line\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevrawline =~ /^\\+/) {\n\t\t\t\t# add assignment operator to the previous line, remove from current line\n\t\t\t\t$fixed[$fixlinenr - 1] .= \" $operator\";\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$operator\\E\\s*//;\n\t\t\t}\n\t\t}\n\n# check for && or || at the start of a line\n\t\tif ($rawline =~ /^\\+\\s*(&&|\\|\\|)/) {\n\t\t\tmy $operator = $1;\n\t\t\tif (CHK(\"LOGICAL_CONTINUATIONS\",\n\t\t\t\t\"Logical continuations should be on the previous line\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevrawline =~ /^\\+/) {\n\t\t\t\t# insert logical operator at last non-comment, non-whitepsace char on previous line\n\t\t\t\t$prevline =~ /[\\s$;]*$/;\n\t\t\t\tmy $line_end = substr($prevrawline, $-[0]);\n\t\t\t\t$fixed[$fixlinenr - 1] =~ s/\\Q$line_end\\E$/ $operator$line_end/;\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$operator\\E\\s*//;\n\t\t\t}\n\t\t}\n\n# check indentation starts on a tab stop\n\t\tif ($perl_version_ok &&\n\t\t    $sline =~ /^\\+\\t+( +)(?:$c90_Keywords\\b|\\{\\s*$|\\}\\s*(?:else\\b|while\\b|\\s*$)|$Declare\\s*$Ident\\s*[;=])/) {\n\t\t\tmy $indent = length($1);\n\t\t\tif ($indent % $tabsize) {\n\t\t\t\tif (WARN(\"TABSTOP\",\n\t\t\t\t\t \"Statements should start on a tabstop\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s@(^\\+\\t+) +@$1 . \"\\t\" x ($indent/$tabsize)@e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check multi-line statement indentation matches previous line\n\t\tif ($perl_version_ok &&\n\t\t    $prevline =~ /^\\+([ \\t]*)((?:$c90_Keywords(?:\\s+if)\\s*)|(?:$Declare\\s*)?(?:$Ident|\\(\\s*\\*\\s*$Ident\\s*\\))\\s*|(?:\\*\\s*)*$Lval\\s*=\\s*$Ident\\s*)\\(.*(\\&\\&|\\|\\||,)\\s*$/) {\n\t\t\t$prevline =~ /^\\+(\\t*)(.*)$/;\n\t\t\tmy $oldindent = $1;\n\t\t\tmy $rest = $2;\n\n\t\t\tmy $pos = pos_last_openparen($rest);\n\t\t\tif ($pos >= 0) {\n\t\t\t\t$line =~ /^(\\+| )([ \\t]*)/;\n\t\t\t\tmy $newindent = $2;\n\n\t\t\t\tmy $goodtabindent = $oldindent .\n\t\t\t\t\t\"\\t\" x ($pos / $tabsize) .\n\t\t\t\t\t\" \"  x ($pos % $tabsize);\n\t\t\t\tmy $goodspaceindent = $oldindent . \" \"  x $pos;\n\n\t\t\t\tif ($newindent ne $goodtabindent &&\n\t\t\t\t    $newindent ne $goodspaceindent) {\n\n\t\t\t\t\tif (CHK(\"PARENTHESIS_ALIGNMENT\",\n\t\t\t\t\t\t\"Alignment should match open parenthesis\\n\" . $hereprev) &&\n\t\t\t\t\t    $fix && $line =~ /^\\+/) {\n\t\t\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t\t\t    s/^\\+[ \\t]*/\\+$goodtabindent/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for space after cast like \"(int) foo\" or \"(struct foo) bar\"\n# avoid checking a few false positives:\n#   \"sizeof(<type>)\" or \"__alignof__(<type>)\"\n#   function pointer declarations like \"(*foo)(int) = bar;\"\n#   structure definitions like \"(struct foo) { 0 };\"\n#   multiline macros that define functions\n#   known attributes or the __attribute__ keyword\n\t\tif ($line =~ /^\\+(.*)\\(\\s*$Type\\s*\\)([ \\t]++)((?![={]|\\\\$|$Attribute|__attribute__))/ &&\n\t\t    (!defined($1) || $1 !~ /\\b(?:sizeof|__alignof__)\\s*$/)) {\n\t\t\tif (CHK(\"SPACING\",\n\t\t\t\t\"No space is necessary after a cast\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/(\\(\\s*$Type\\s*\\))[ \\t]+/$1/;\n\t\t\t}\n\t\t}\n\n# Block comment styles\n# Networking with an initial /*\n\t\tif ($realfile =~ m@^(drivers/net/|net/)@ &&\n\t\t    $prevrawline =~ /^\\+[ \\t]*\\/\\*[ \\t]*$/ &&\n\t\t    $rawline =~ /^\\+[ \\t]*\\*/ &&\n\t\t    $realline > 3) { # Do not warn about the initial copyright comment block after SPDX-License-Identifier\n\t\t\tWARN(\"NETWORKING_BLOCK_COMMENT_STYLE\",\n\t\t\t     \"networking block comments don't use an empty /* line, use /* Comment...\\n\" . $hereprev);\n\t\t}\n\n# Block comments use * on subsequent lines\n\t\tif ($prevline =~ /$;[ \\t]*$/ &&\t\t\t#ends in comment\n\t\t    $prevrawline =~ /^\\+.*?\\/\\*/ &&\t\t#starting /*\n\t\t    $prevrawline !~ /\\*\\/[ \\t]*$/ &&\t\t#no trailing */\n\t\t    $rawline =~ /^\\+/ &&\t\t\t#line is new\n\t\t    $rawline !~ /^\\+[ \\t]*\\*/) {\t\t#no leading *\n\t\t\tWARN(\"BLOCK_COMMENT_STYLE\",\n\t\t\t     \"Block comments use * on subsequent lines\\n\" . $hereprev);\n\t\t}\n\n# Block comments use */ on trailing lines\n\t\tif ($rawline !~ m@^\\+[ \\t]*\\*/[ \\t]*$@ &&\t#trailing */\n\t\t    $rawline !~ m@^\\+.*/\\*.*\\*/[ \\t]*$@ &&\t#inline /*...*/\n\t\t    $rawline !~ m@^\\+.*\\*{2,}/[ \\t]*$@ &&\t#trailing **/\n\t\t    $rawline =~ m@^\\+[ \\t]*.+\\*\\/[ \\t]*$@) {\t#non blank */\n\t\t\tWARN(\"BLOCK_COMMENT_STYLE\",\n\t\t\t     \"Block comments use a trailing */ on a separate line\\n\" . $herecurr);\n\t\t}\n\n# Block comment * alignment\n\t\tif ($prevline =~ /$;[ \\t]*$/ &&\t\t\t#ends in comment\n\t\t    $line =~ /^\\+[ \\t]*$;/ &&\t\t\t#leading comment\n\t\t    $rawline =~ /^\\+[ \\t]*\\*/ &&\t\t#leading *\n\t\t    (($prevrawline =~ /^\\+.*?\\/\\*/ &&\t\t#leading /*\n\t\t      $prevrawline !~ /\\*\\/[ \\t]*$/) ||\t\t#no trailing */\n\t\t     $prevrawline =~ /^\\+[ \\t]*\\*/)) {\t\t#leading *\n\t\t\tmy $oldindent;\n\t\t\t$prevrawline =~ m@^\\+([ \\t]*/?)\\*@;\n\t\t\tif (defined($1)) {\n\t\t\t\t$oldindent = expand_tabs($1);\n\t\t\t} else {\n\t\t\t\t$prevrawline =~ m@^\\+(.*/?)\\*@;\n\t\t\t\t$oldindent = expand_tabs($1);\n\t\t\t}\n\t\t\t$rawline =~ m@^\\+([ \\t]*)\\*@;\n\t\t\tmy $newindent = $1;\n\t\t\t$newindent = expand_tabs($newindent);\n\t\t\tif (length($oldindent) ne length($newindent)) {\n\t\t\t\tWARN(\"BLOCK_COMMENT_STYLE\",\n\t\t\t\t     \"Block comments should align the * on each line\\n\" . $hereprev);\n\t\t\t}\n\t\t}\n\n# check for missing blank lines after struct/union declarations\n# with exceptions for various attributes and macros\n\t\tif ($prevline =~ /^[\\+ ]};?\\s*$/ &&\n\t\t    $line =~ /^\\+/ &&\n\t\t    !($line =~ /^\\+\\s*$/ ||\n\t\t      $line =~ /^\\+\\s*(?:EXPORT_SYMBOL|early_param)/ ||\n\t\t      $line =~ /^\\+\\s*MODULE_/i ||\n\t\t      $line =~ /^\\+\\s*\\#\\s*(?:end|elif|else)/ ||\n\t\t      $line =~ /^\\+[a-z_]*init/ ||\n\t\t      $line =~ /^\\+\\s*(?:static\\s+)?[A-Z_]*ATTR/ ||\n\t\t      $line =~ /^\\+\\s*DECLARE/ ||\n\t\t      $line =~ /^\\+\\s*builtin_[\\w_]*driver/ ||\n\t\t      $line =~ /^\\+\\s*__setup/)) {\n\t\t\tif (CHK(\"LINE_SPACING\",\n\t\t\t\t\"Please use a blank line after function/struct/union/enum declarations\\n\" . $hereprev) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_insert_line($fixlinenr, \"\\+\");\n\t\t\t}\n\t\t}\n\n# check for multiple consecutive blank lines\n\t\tif ($prevline =~ /^[\\+ ]\\s*$/ &&\n\t\t    $line =~ /^\\+\\s*$/ &&\n\t\t    $last_blank_line != ($linenr - 1)) {\n\t\t\tif (CHK(\"LINE_SPACING\",\n\t\t\t\t\"Please don't use multiple blank lines\\n\" . $hereprev) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t}\n\n\t\t\t$last_blank_line = $linenr;\n\t\t}\n\n# check for missing blank lines after declarations\n# (declarations must have the same indentation and not be at the start of line)\n\t\tif (($prevline =~ /\\+(\\s+)\\S/) && $sline =~ /^\\+$1\\S/) {\n\t\t\t# use temporaries\n\t\t\tmy $sl = $sline;\n\t\t\tmy $pl = $prevline;\n\t\t\t# remove $Attribute/$Sparse uses to simplify comparisons\n\t\t\t$sl =~ s/\\b(?:$Attribute|$Sparse)\\b//g;\n\t\t\t$pl =~ s/\\b(?:$Attribute|$Sparse)\\b//g;\n\t\t\tif (($pl =~ /^\\+\\s+$Declare\\s*$Ident\\s*[=,;:\\[]/ ||\n\t\t\t# function pointer declarations\n\t\t\t     $pl =~ /^\\+\\s+$Declare\\s*\\(\\s*\\*\\s*$Ident\\s*\\)\\s*[=,;:\\[\\(]/ ||\n\t\t\t# foo bar; where foo is some local typedef or #define\n\t\t\t     $pl =~ /^\\+\\s+$Ident(?:\\s+|\\s*\\*\\s*)$Ident\\s*[=,;\\[]/ ||\n\t\t\t# known declaration macros\n\t\t\t     $pl =~ /^\\+\\s+$declaration_macros/) &&\n\t\t\t# for \"else if\" which can look like \"$Ident $Ident\"\n\t\t\t    !($pl =~ /^\\+\\s+$c90_Keywords\\b/ ||\n\t\t\t# other possible extensions of declaration lines\n\t\t\t      $pl =~ /(?:$Compare|$Assignment|$Operators)\\s*$/ ||\n\t\t\t# not starting a section or a macro \"\\\" extended line\n\t\t\t      $pl =~ /(?:\\{\\s*|\\\\)$/) &&\n\t\t\t# looks like a declaration\n\t\t\t    !($sl =~ /^\\+\\s+$Declare\\s*$Ident\\s*[=,;:\\[]/ ||\n\t\t\t# function pointer declarations\n\t\t\t      $sl =~ /^\\+\\s+$Declare\\s*\\(\\s*\\*\\s*$Ident\\s*\\)\\s*[=,;:\\[\\(]/ ||\n\t\t\t# foo bar; where foo is some local typedef or #define\n\t\t\t      $sl =~ /^\\+\\s+$Ident(?:\\s+|\\s*\\*\\s*)$Ident\\s*[=,;\\[]/ ||\n\t\t\t# known declaration macros\n\t\t\t      $sl =~ /^\\+\\s+$declaration_macros/ ||\n\t\t\t# start of struct or union or enum\n\t\t\t      $sl =~ /^\\+\\s+(?:static\\s+)?(?:const\\s+)?(?:union|struct|enum|typedef)\\b/ ||\n\t\t\t# start or end of block or continuation of declaration\n\t\t\t      $sl =~ /^\\+\\s+(?:$|[\\{\\}\\.\\#\\\"\\?\\:\\(\\[])/ ||\n\t\t\t# bitfield continuation\n\t\t\t      $sl =~ /^\\+\\s+$Ident\\s*:\\s*\\d+\\s*[,;]/ ||\n\t\t\t# other possible extensions of declaration lines\n\t\t\t      $sl =~ /^\\+\\s+\\(?\\s*(?:$Compare|$Assignment|$Operators)/)) {\n\t\t\t\tif (WARN(\"LINE_SPACING\",\n\t\t\t\t\t \"Missing a blank line after declarations\\n\" . $hereprev) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\tfix_insert_line($fixlinenr, \"\\+\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for spaces at the beginning of a line.\n# Exceptions:\n#  1) within comments\n#  2) indented preprocessor commands\n#  3) hanging labels\n\t\tif ($rawline =~ /^\\+ / && $line !~ /^\\+ *(?:$;|#|$Ident:)/)  {\n\t\t\tmy $herevet = \"$here\\n\" . cat_vet($rawline) . \"\\n\";\n\t\t\tif (WARN(\"LEADING_SPACE\",\n\t\t\t\t \"please, no spaces at the start of a line\\n\" . $herevet) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/^\\+([ \\t]+)/\"\\+\" . tabify($1)/e;\n\t\t\t}\n\t\t}\n\n# check we are in a valid C source file if not then ignore this hunk\n\t\tnext if ($realfile !~ /\\.(h|c)$/);\n\n# check for unusual line ending [ or (\n\t\tif ($line =~ /^\\+.*([\\[\\(])\\s*$/) {\n\t\t\tCHK(\"OPEN_ENDED_LINE\",\n\t\t\t    \"Lines should not end with a '$1'\\n\" . $herecurr);\n\t\t}\n\n# check if this appears to be the start function declaration, save the name\n\t\tif ($sline =~ /^\\+\\{\\s*$/ &&\n\t\t    $prevline =~ /^\\+(?:(?:(?:$Storage|$Inline)\\s*)*\\s*$Type\\s*)?($Ident)\\(/) {\n\t\t\t$context_function = $1;\n\t\t}\n\n# check if this appears to be the end of function declaration\n\t\tif ($sline =~ /^\\+\\}\\s*$/) {\n\t\t\tundef $context_function;\n\t\t}\n\n# check indentation of any line with a bare else\n# (but not if it is a multiple line \"if (foo) return bar; else return baz;\")\n# if the previous line is a break or return and is indented 1 tab more...\n\t\tif ($sline =~ /^\\+([\\t]+)(?:}[ \\t]*)?else(?:[ \\t]*{)?\\s*$/) {\n\t\t\tmy $tabs = length($1) + 1;\n\t\t\tif ($prevline =~ /^\\+\\t{$tabs,$tabs}break\\b/ ||\n\t\t\t    ($prevline =~ /^\\+\\t{$tabs,$tabs}return\\b/ &&\n\t\t\t     defined $lines[$linenr] &&\n\t\t\t     $lines[$linenr] !~ /^[ \\+]\\t{$tabs,$tabs}return/)) {\n\t\t\t\tWARN(\"UNNECESSARY_ELSE\",\n\t\t\t\t     \"else is not generally useful after a break or return\\n\" . $hereprev);\n\t\t\t}\n\t\t}\n\n# check indentation of a line with a break;\n# if the previous line is a goto, return or break\n# and is indented the same # of tabs\n\t\tif ($sline =~ /^\\+([\\t]+)break\\s*;\\s*$/) {\n\t\t\tmy $tabs = $1;\n\t\t\tif ($prevline =~ /^\\+$tabs(goto|return|break)\\b/) {\n\t\t\t\tif (WARN(\"UNNECESSARY_BREAK\",\n\t\t\t\t\t \"break is not useful after a $1\\n\" . $hereprev) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for RCS/CVS revision markers\n\t\tif ($rawline =~ /^\\+.*\\$(Revision|Log|Id)(?:\\$|)/) {\n\t\t\tWARN(\"CVS_KEYWORD\",\n\t\t\t     \"CVS style keyword markers, these will _not_ be updated\\n\". $herecurr);\n\t\t}\n\n# check for old HOTPLUG __dev<foo> section markings\n\t\tif ($line =~ /\\b(__dev(init|exit)(data|const|))\\b/) {\n\t\t\tWARN(\"HOTPLUG_SECTION\",\n\t\t\t     \"Using $1 is unnecessary\\n\" . $herecurr);\n\t\t}\n\n# Check for potential 'bare' types\n\t\tmy ($stat, $cond, $line_nr_next, $remain_next, $off_next,\n\t\t    $realline_next);\n#print \"LINE<$line>\\n\";\n\t\tif ($linenr > $suppress_statement &&\n\t\t    $realcnt && $sline =~ /.\\s*\\S/) {\n\t\t\t($stat, $cond, $line_nr_next, $remain_next, $off_next) =\n\t\t\t\tctx_statement_block($linenr, $realcnt, 0);\n\t\t\t$stat =~ s/\\n./\\n /g;\n\t\t\t$cond =~ s/\\n./\\n /g;\n\n#print \"linenr<$linenr> <$stat>\\n\";\n\t\t\t# If this statement has no statement boundaries within\n\t\t\t# it there is no point in retrying a statement scan\n\t\t\t# until we hit end of it.\n\t\t\tmy $frag = $stat; $frag =~ s/;+\\s*$//;\n\t\t\tif ($frag !~ /(?:{|;)/) {\n#print \"skip<$line_nr_next>\\n\";\n\t\t\t\t$suppress_statement = $line_nr_next;\n\t\t\t}\n\n\t\t\t# Find the real next line.\n\t\t\t$realline_next = $line_nr_next;\n\t\t\tif (defined $realline_next &&\n\t\t\t    (!defined $lines[$realline_next - 1] ||\n\t\t\t     substr($lines[$realline_next - 1], $off_next) =~ /^\\s*$/)) {\n\t\t\t\t$realline_next++;\n\t\t\t}\n\n\t\t\tmy $s = $stat;\n\t\t\t$s =~ s/{.*$//s;\n\n\t\t\t# Ignore goto labels.\n\t\t\tif ($s =~ /$Ident:\\*$/s) {\n\n\t\t\t# Ignore functions being called\n\t\t\t} elsif ($s =~ /^.\\s*$Ident\\s*\\(/s) {\n\n\t\t\t} elsif ($s =~ /^.\\s*else\\b/s) {\n\n\t\t\t# declarations always start with types\n\t\t\t} elsif ($prev_values eq 'E' && $s =~ /^.\\s*(?:$Storage\\s+)?(?:$Inline\\s+)?(?:const\\s+)?((?:\\s*$Ident)+?)\\b(?:\\s+$Sparse)?\\s*\\**\\s*(?:$Ident|\\(\\*[^\\)]*\\))(?:\\s*$Modifier)?\\s*(?:;|=|,|\\()/s) {\n\t\t\t\tmy $type = $1;\n\t\t\t\t$type =~ s/\\s+/ /g;\n\t\t\t\tpossible($type, \"A:\" . $s);\n\n\t\t\t# definitions in global scope can only start with types\n\t\t\t} elsif ($s =~ /^.(?:$Storage\\s+)?(?:$Inline\\s+)?(?:const\\s+)?($Ident)\\b\\s*(?!:)/s) {\n\t\t\t\tpossible($1, \"B:\" . $s);\n\t\t\t}\n\n\t\t\t# any (foo ... *) is a pointer cast, and foo is a type\n\t\t\twhile ($s =~ /\\(($Ident)(?:\\s+$Sparse)*[\\s\\*]+\\s*\\)/sg) {\n\t\t\t\tpossible($1, \"C:\" . $s);\n\t\t\t}\n\n\t\t\t# Check for any sort of function declaration.\n\t\t\t# int foo(something bar, other baz);\n\t\t\t# void (*store_gdt)(x86_descr_ptr *);\n\t\t\tif ($prev_values eq 'E' && $s =~ /^(.(?:typedef\\s*)?(?:(?:$Storage|$Inline)\\s*)*\\s*$Type\\s*(?:\\b$Ident|\\(\\*\\s*$Ident\\))\\s*)\\(/s) {\n\t\t\t\tmy ($name_len) = length($1);\n\n\t\t\t\tmy $ctx = $s;\n\t\t\t\tsubstr($ctx, 0, $name_len + 1, '');\n\t\t\t\t$ctx =~ s/\\)[^\\)]*$//;\n\n\t\t\t\tfor my $arg (split(/\\s*,\\s*/, $ctx)) {\n\t\t\t\t\tif ($arg =~ /^(?:const\\s+)?($Ident)(?:\\s+$Sparse)*\\s*\\**\\s*(:?\\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {\n\n\t\t\t\t\t\tpossible($1, \"D:\" . $s);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n#\n# Checks which may be anchored in the context.\n#\n\n# Check for switch () and associated case and default\n# statements should be at the same indent.\n\t\tif ($line=~/\\bswitch\\s*\\(.*\\)/) {\n\t\t\tmy $err = '';\n\t\t\tmy $sep = '';\n\t\t\tmy @ctx = ctx_block_outer($linenr, $realcnt);\n\t\t\tshift(@ctx);\n\t\t\tfor my $ctx (@ctx) {\n\t\t\t\tmy ($clen, $cindent) = line_stats($ctx);\n\t\t\t\tif ($ctx =~ /^\\+\\s*(case\\s+|default:)/ &&\n\t\t\t\t\t\t\t$indent != $cindent) {\n\t\t\t\t\t$err .= \"$sep$ctx\\n\";\n\t\t\t\t\t$sep = '';\n\t\t\t\t} else {\n\t\t\t\t\t$sep = \"[...]\\n\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($err ne '') {\n\t\t\t\tERROR(\"SWITCH_CASE_INDENT_LEVEL\",\n\t\t\t\t      \"switch and case should be at the same indent\\n$hereline$err\");\n\t\t\t}\n\t\t}\n\n# if/while/etc brace do not go on next line, unless defining a do while loop,\n# or if that brace on the next line is for something else\n\t\tif ($line =~ /(.*)\\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\\s*\\(|do\\b|else\\b)/ && $line !~ /^.\\s*\\#/) {\n\t\t\tmy $pre_ctx = \"$1$2\";\n\n\t\t\tmy ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);\n\n\t\t\t# OpenOCD specific: Begin: replace s/6/10/\n\t\t\tif ($line =~ /^\\+\\t{10,}/) {\n\t\t\t# OpenOCD specific: End\n\t\t\t\tWARN(\"DEEP_INDENTATION\",\n\t\t\t\t     \"Too many leading tabs - consider code refactoring\\n\" . $herecurr);\n\t\t\t}\n\n\t\t\tmy $ctx_cnt = $realcnt - $#ctx - 1;\n\t\t\tmy $ctx = join(\"\\n\", @ctx);\n\n\t\t\tmy $ctx_ln = $linenr;\n\t\t\tmy $ctx_skip = $realcnt;\n\n\t\t\twhile ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&\n\t\t\t\t\tdefined $lines[$ctx_ln - 1] &&\n\t\t\t\t\t$lines[$ctx_ln - 1] =~ /^-/)) {\n\t\t\t\t##print \"SKIP<$ctx_skip> CNT<$ctx_cnt>\\n\";\n\t\t\t\t$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);\n\t\t\t\t$ctx_ln++;\n\t\t\t}\n\n\t\t\t#print \"realcnt<$realcnt> ctx_cnt<$ctx_cnt>\\n\";\n\t\t\t#print \"pre<$pre_ctx>\\nline<$line>\\nctx<$ctx>\\nnext<$lines[$ctx_ln - 1]>\\n\";\n\n\t\t\tif ($ctx !~ /{\\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\\+\\s*{/) {\n\t\t\t\tERROR(\"OPEN_BRACE\",\n\t\t\t\t      \"that open brace { should be on the previous line\\n\" .\n\t\t\t\t\t\"$here\\n$ctx\\n$rawlines[$ctx_ln - 1]\\n\");\n\t\t\t}\n\t\t\tif ($level == 0 && $pre_ctx !~ /}\\s*while\\s*\\($/ &&\n\t\t\t    $ctx =~ /\\)\\s*\\;\\s*$/ &&\n\t\t\t    defined $lines[$ctx_ln - 1])\n\t\t\t{\n\t\t\t\tmy ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);\n\t\t\t\tif ($nindent > $indent) {\n\t\t\t\t\tWARN(\"TRAILING_SEMICOLON\",\n\t\t\t\t\t     \"trailing semicolon indicates no statements, indent implies otherwise\\n\" .\n\t\t\t\t\t\t\"$here\\n$ctx\\n$rawlines[$ctx_ln - 1]\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check relative indent for conditionals and blocks.\n\t\tif ($line =~ /\\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\\s*\\(|(?:do|else)\\b)/ && $line !~ /^.\\s*#/ && $line !~ /\\}\\s*while\\s*/) {\n\t\t\t($stat, $cond, $line_nr_next, $remain_next, $off_next) =\n\t\t\t\tctx_statement_block($linenr, $realcnt, 0)\n\t\t\t\t\tif (!defined $stat);\n\t\t\tmy ($s, $c) = ($stat, $cond);\n\n\t\t\tsubstr($s, 0, length($c), '');\n\n\t\t\t# remove inline comments\n\t\t\t$s =~ s/$;/ /g;\n\t\t\t$c =~ s/$;/ /g;\n\n\t\t\t# Find out how long the conditional actually is.\n\t\t\tmy @newlines = ($c =~ /\\n/gs);\n\t\t\tmy $cond_lines = 1 + $#newlines;\n\n\t\t\t# Make sure we remove the line prefixes as we have\n\t\t\t# none on the first line, and are going to readd them\n\t\t\t# where necessary.\n\t\t\t$s =~ s/\\n./\\n/gs;\n\t\t\twhile ($s =~ /\\n\\s+\\\\\\n/) {\n\t\t\t\t$cond_lines += $s =~ s/\\n\\s+\\\\\\n/\\n/g;\n\t\t\t}\n\n\t\t\t# We want to check the first line inside the block\n\t\t\t# starting at the end of the conditional, so remove:\n\t\t\t#  1) any blank line termination\n\t\t\t#  2) any opening brace { on end of the line\n\t\t\t#  3) any do (...) {\n\t\t\tmy $continuation = 0;\n\t\t\tmy $check = 0;\n\t\t\t$s =~ s/^.*\\bdo\\b//;\n\t\t\t$s =~ s/^\\s*{//;\n\t\t\tif ($s =~ s/^\\s*\\\\//) {\n\t\t\t\t$continuation = 1;\n\t\t\t}\n\t\t\tif ($s =~ s/^\\s*?\\n//) {\n\t\t\t\t$check = 1;\n\t\t\t\t$cond_lines++;\n\t\t\t}\n\n\t\t\t# Also ignore a loop construct at the end of a\n\t\t\t# preprocessor statement.\n\t\t\tif (($prevline =~ /^.\\s*#\\s*define\\s/ ||\n\t\t\t    $prevline =~ /\\\\\\s*$/) && $continuation == 0) {\n\t\t\t\t$check = 0;\n\t\t\t}\n\n\t\t\tmy $cond_ptr = -1;\n\t\t\t$continuation = 0;\n\t\t\twhile ($cond_ptr != $cond_lines) {\n\t\t\t\t$cond_ptr = $cond_lines;\n\n\t\t\t\t# If we see an #else/#elif then the code\n\t\t\t\t# is not linear.\n\t\t\t\tif ($s =~ /^\\s*\\#\\s*(?:else|elif)/) {\n\t\t\t\t\t$check = 0;\n\t\t\t\t}\n\n\t\t\t\t# Ignore:\n\t\t\t\t#  1) blank lines, they should be at 0,\n\t\t\t\t#  2) preprocessor lines, and\n\t\t\t\t#  3) labels.\n\t\t\t\tif ($continuation ||\n\t\t\t\t    $s =~ /^\\s*?\\n/ ||\n\t\t\t\t    $s =~ /^\\s*#\\s*?/ ||\n\t\t\t\t    $s =~ /^\\s*$Ident\\s*:/) {\n\t\t\t\t\t$continuation = ($s =~ /^.*?\\\\\\n/) ? 1 : 0;\n\t\t\t\t\tif ($s =~ s/^.*?\\n//) {\n\t\t\t\t\t\t$cond_lines++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmy (undef, $sindent) = line_stats(\"+\" . $s);\n\t\t\tmy $stat_real = raw_line($linenr, $cond_lines);\n\n\t\t\t# Check if either of these lines are modified, else\n\t\t\t# this is not this patch's fault.\n\t\t\tif (!defined($stat_real) ||\n\t\t\t    $stat !~ /^\\+/ && $stat_real !~ /^\\+/) {\n\t\t\t\t$check = 0;\n\t\t\t}\n\t\t\tif (defined($stat_real) && $cond_lines > 1) {\n\t\t\t\t$stat_real = \"[...]\\n$stat_real\";\n\t\t\t}\n\n\t\t\t#print \"line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\\n\";\n\n\t\t\tif ($check && $s ne '' &&\n\t\t\t    (($sindent % $tabsize) != 0 ||\n\t\t\t     ($sindent < $indent) ||\n\t\t\t     ($sindent == $indent &&\n\t\t\t      ($s !~ /^\\s*(?:\\}|\\{|else\\b)/)) ||\n\t\t\t     ($sindent > $indent + $tabsize))) {\n\t\t\t\tWARN(\"SUSPECT_CODE_INDENT\",\n\t\t\t\t     \"suspect code indent for conditional statements ($indent, $sindent)\\n\" . $herecurr . \"$stat_real\\n\");\n\t\t\t}\n\t\t}\n\n\t\t# Track the 'values' across context and added lines.\n\t\tmy $opline = $line; $opline =~ s/^./ /;\n\t\tmy ($curr_values, $curr_vars) =\n\t\t\t\tannotate_values($opline . \"\\n\", $prev_values);\n\t\t$curr_values = $prev_values . $curr_values;\n\t\tif ($dbg_values) {\n\t\t\tmy $outline = $opline; $outline =~ s/\\t/ /g;\n\t\t\tprint \"$linenr > .$outline\\n\";\n\t\t\tprint \"$linenr > $curr_values\\n\";\n\t\t\tprint \"$linenr >  $curr_vars\\n\";\n\t\t}\n\t\t$prev_values = substr($curr_values, -1);\n\n#ignore lines not being added\n\t\tnext if ($line =~ /^[^\\+]/);\n\n# check for self assignments used to avoid compiler warnings\n# e.g.:\tint foo = foo, *bar = NULL;\n#\tstruct foo bar = *(&(bar));\n\t\tif ($line =~ /^\\+\\s*(?:$Declare)?([A-Za-z_][A-Za-z\\d_]*)\\s*=/) {\n\t\t\tmy $var = $1;\n\t\t\tif ($line =~ /^\\+\\s*(?:$Declare)?$var\\s*=\\s*(?:$var|\\*\\s*\\(?\\s*&\\s*\\(?\\s*$var\\s*\\)?\\s*\\)?)\\s*[;,]/) {\n\t\t\t\tWARN(\"SELF_ASSIGNMENT\",\n\t\t\t\t     \"Do not use self-assignments to avoid compiler warnings\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for dereferences that span multiple lines\n\t\tif ($prevline =~ /^\\+.*$Lval\\s*(?:\\.|->)\\s*$/ &&\n\t\t    $line =~ /^\\+\\s*(?!\\#\\s*(?!define\\s+|if))\\s*$Lval/) {\n\t\t\t$prevline =~ /($Lval\\s*(?:\\.|->))\\s*$/;\n\t\t\tmy $ref = $1;\n\t\t\t$line =~ /^.\\s*($Lval)/;\n\t\t\t$ref .= $1;\n\t\t\t$ref =~ s/\\s//g;\n\t\t\tWARN(\"MULTILINE_DEREFERENCE\",\n\t\t\t     \"Avoid multiple line dereference - prefer '$ref'\\n\" . $hereprev);\n\t\t}\n\n# check for declarations of signed or unsigned without int\n\t\twhile ($line =~ m{\\b($Declare)\\s*(?!char\\b|short\\b|int\\b|long\\b)\\s*($Ident)?\\s*[=,;\\[\\)\\(]}g) {\n\t\t\tmy $type = $1;\n\t\t\tmy $var = $2;\n\t\t\t$var = \"\" if (!defined $var);\n\t\t\tif ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\\s+)*((?:un)?signed)((?:\\s*\\*)*)\\s*$/) {\n\t\t\t\tmy $sign = $1;\n\t\t\t\tmy $pointer = $2;\n\n\t\t\t\t$pointer = \"\" if (!defined $pointer);\n\n\t\t\t\tif (WARN(\"UNSPECIFIED_INT\",\n\t\t\t\t\t \"Prefer '\" . trim($sign) . \" int\" . rtrim($pointer) . \"' to bare use of '$sign\" . rtrim($pointer) . \"'\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\tmy $decl = trim($sign) . \" int \";\n\t\t\t\t\tmy $comp_pointer = $pointer;\n\t\t\t\t\t$comp_pointer =~ s/\\s//g;\n\t\t\t\t\t$decl .= $comp_pointer;\n\t\t\t\t\t$decl = rtrim($decl) if ($var eq \"\");\n\t\t\t\t\t$fixed[$fixlinenr] =~ s@\\b$sign\\s*\\Q$pointer\\E\\s*$var\\b@$decl$var@;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# TEST: allow direct testing of the type matcher.\n\t\tif ($dbg_type) {\n\t\t\tif ($line =~ /^.\\s*$Declare\\s*$/) {\n\t\t\t\tERROR(\"TEST_TYPE\",\n\t\t\t\t      \"TEST: is type\\n\" . $herecurr);\n\t\t\t} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {\n\t\t\t\tERROR(\"TEST_NOT_TYPE\",\n\t\t\t\t      \"TEST: is not type ($1 is)\\n\". $herecurr);\n\t\t\t}\n\t\t\tnext;\n\t\t}\n# TEST: allow direct testing of the attribute matcher.\n\t\tif ($dbg_attr) {\n\t\t\tif ($line =~ /^.\\s*$Modifier\\s*$/) {\n\t\t\t\tERROR(\"TEST_ATTR\",\n\t\t\t\t      \"TEST: is attr\\n\" . $herecurr);\n\t\t\t} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {\n\t\t\t\tERROR(\"TEST_NOT_ATTR\",\n\t\t\t\t      \"TEST: is not attr ($1 is)\\n\". $herecurr);\n\t\t\t}\n\t\t\tnext;\n\t\t}\n\n# check for initialisation to aggregates open brace on the next line\n\t\tif ($line =~ /^.\\s*{/ &&\n\t\t    $prevline =~ /(?:^|[^=])=\\s*$/) {\n\t\t\tif (ERROR(\"OPEN_BRACE\",\n\t\t\t\t  \"that open brace { should be on the previous line\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevline =~ /^\\+/ && $line =~ /^\\+/) {\n\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\tmy $fixedline = $prevrawline;\n\t\t\t\t$fixedline =~ s/\\s*=\\s*$/ = {/;\n\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t$fixedline = $line;\n\t\t\t\t$fixedline =~ s/^(.\\s*)\\{\\s*/$1/;\n\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t}\n\t\t}\n\n#\n# Checks which are anchored on the added line.\n#\n\n# check for malformed paths in #include statements (uses RAW line)\n\t\tif ($rawline =~ m{^.\\s*\\#\\s*include\\s+[<\"](.*)[\">]}) {\n\t\t\tmy $path = $1;\n\t\t\tif ($path =~ m{//}) {\n\t\t\t\tERROR(\"MALFORMED_INCLUDE\",\n\t\t\t\t      \"malformed #include filename\\n\" . $herecurr);\n\t\t\t}\n\t\t\tif ($path =~ \"^uapi/\" && $realfile =~ m@\\binclude/uapi/@) {\n\t\t\t\tERROR(\"UAPI_INCLUDE\",\n\t\t\t\t      \"No #include in ...include/uapi/... should use a uapi/ path prefix\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# no C99 // comments\n\t\tif ($line =~ m{//}) {\n\t\t\tif (ERROR(\"C99_COMMENTS\",\n\t\t\t\t  \"do not use C99 // comments\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tmy $line = $fixed[$fixlinenr];\n\t\t\t\tif ($line =~ /\\/\\/(.*)$/) {\n\t\t\t\t\tmy $comment = trim($1);\n\t\t\t\t\t$fixed[$fixlinenr] =~ s@\\/\\/(.*)$@/\\* $comment \\*/@;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t# Remove C99 comments.\n\t\t$line =~ s@//.*@@;\n\t\t$opline =~ s@//.*@@;\n\n# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider\n# the whole statement.\n#print \"APW <$lines[$realline_next - 1]>\\n\";\n\t\tif (defined $realline_next &&\n\t\t    exists $lines[$realline_next - 1] &&\n\t\t    !defined $suppress_export{$realline_next} &&\n\t\t    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\\((.*)\\)/)) {\n\t\t\t# Handle definitions which produce identifiers with\n\t\t\t# a prefix:\n\t\t\t#   XXX(foo);\n\t\t\t#   EXPORT_SYMBOL(something_foo);\n\t\t\tmy $name = $1;\n\t\t\t$name =~ s/^\\s*($Ident).*/$1/;\n\t\t\tif ($stat =~ /^(?:.\\s*}\\s*\\n)?.([A-Z_]+)\\s*\\(\\s*($Ident)/ &&\n\t\t\t    $name =~ /^${Ident}_$2/) {\n#print \"FOO C name<$name>\\n\";\n\t\t\t\t$suppress_export{$realline_next} = 1;\n\n\t\t\t} elsif ($stat !~ /(?:\n\t\t\t\t\\n.}\\s*$|\n\t\t\t\t^.DEFINE_$Ident\\(\\Q$name\\E\\)|\n\t\t\t\t^.DECLARE_$Ident\\(\\Q$name\\E\\)|\n\t\t\t\t^.LIST_HEAD\\(\\Q$name\\E\\)|\n\t\t\t\t^.(?:$Storage\\s+)?$Type\\s*\\(\\s*\\*\\s*\\Q$name\\E\\s*\\)\\s*\\(|\n\t\t\t\t\\b\\Q$name\\E(?:\\s+$Attribute)*\\s*(?:;|=|\\[|\\()\n\t\t\t    )/x) {\n#print \"FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\\n\";\n\t\t\t\t$suppress_export{$realline_next} = 2;\n\t\t\t} else {\n\t\t\t\t$suppress_export{$realline_next} = 1;\n\t\t\t}\n\t\t}\n\t\tif (!defined $suppress_export{$linenr} &&\n\t\t    $prevline =~ /^.\\s*$/ &&\n\t\t    ($line =~ /EXPORT_SYMBOL.*\\((.*)\\)/)) {\n#print \"FOO B <$lines[$linenr - 1]>\\n\";\n\t\t\t$suppress_export{$linenr} = 2;\n\t\t}\n\t\tif (defined $suppress_export{$linenr} &&\n\t\t    $suppress_export{$linenr} == 2) {\n\t\t\tWARN(\"EXPORT_SYMBOL\",\n\t\t\t     \"EXPORT_SYMBOL(foo); should immediately follow its function/variable\\n\" . $herecurr);\n\t\t}\n\n# check for global initialisers.\n\t\tif ($line =~ /^\\+$Type\\s*$Ident(?:\\s+$Modifier)*\\s*=\\s*($zero_initializer)\\s*;/ &&\n\t\t    !exclude_global_initialisers($realfile)) {\n\t\t\tif (ERROR(\"GLOBAL_INITIALISERS\",\n\t\t\t\t  \"do not initialise globals to $1\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(^.$Type\\s*$Ident(?:\\s+$Modifier)*)\\s*=\\s*$zero_initializer\\s*;/$1;/;\n\t\t\t}\n\t\t}\n# check for static initialisers.\n\t\tif ($line =~ /^\\+.*\\bstatic\\s.*=\\s*($zero_initializer)\\s*;/) {\n\t\t\tif (ERROR(\"INITIALISED_STATIC\",\n\t\t\t\t  \"do not initialise statics to $1\\n\" .\n\t\t\t\t      $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(\\bstatic\\s.*?)\\s*=\\s*$zero_initializer\\s*;/$1;/;\n\t\t\t}\n\t\t}\n\n# check for misordered declarations of char/short/int/long with signed/unsigned\n\t\twhile ($sline =~ m{(\\b$TypeMisordered\\b)}g) {\n\t\t\tmy $tmp = trim($1);\n\t\t\tWARN(\"MISORDERED_TYPE\",\n\t\t\t     \"type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\\n\" . $herecurr);\n\t\t}\n\n# check for unnecessary <signed> int declarations of short/long/long long\n\t\twhile ($sline =~ m{\\b($TypeMisordered(\\s*\\*)*|$C90_int_types)\\b}g) {\n\t\t\tmy $type = trim($1);\n\t\t\tnext if ($type !~ /\\bint\\b/);\n\t\t\tnext if ($type !~ /\\b(?:short|long\\s+long|long)\\b/);\n\t\t\tmy $new_type = $type;\n\t\t\t$new_type =~ s/\\b\\s*int\\s*\\b/ /;\n\t\t\t$new_type =~ s/\\b\\s*(?:un)?signed\\b\\s*/ /;\n\t\t\t$new_type =~ s/^const\\s+//;\n\t\t\t$new_type = \"unsigned $new_type\" if ($type =~ /\\bunsigned\\b/);\n\t\t\t$new_type = \"const $new_type\" if ($type =~ /^const\\b/);\n\t\t\t$new_type =~ s/\\s+/ /g;\n\t\t\t$new_type = trim($new_type);\n\t\t\tif (WARN(\"UNNECESSARY_INT\",\n\t\t\t\t \"Prefer '$new_type' over '$type' as the int is unnecessary\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\b\\Q$type\\E\\b/$new_type/;\n\t\t\t}\n\t\t}\n\n# check for static const char * arrays.\n\t\tif ($line =~ /\\bstatic\\s+const\\s+char\\s*\\*\\s*(\\w+)\\s*\\[\\s*\\]\\s*=\\s*/) {\n\t\t\tWARN(\"STATIC_CONST_CHAR_ARRAY\",\n\t\t\t     \"static const char * array should probably be static const char * const\\n\" .\n\t\t\t\t$herecurr);\n\t\t}\n\n# check for initialized const char arrays that should be static const\n\t\tif ($line =~ /^\\+\\s*const\\s+(char|unsigned\\s+char|_*u8|(?:[us]_)?int8_t)\\s+\\w+\\s*\\[\\s*(?:\\w+\\s*)?\\]\\s*=\\s*\"/) {\n\t\t\tif (WARN(\"STATIC_CONST_CHAR_ARRAY\",\n\t\t\t\t \"const array should probably be static const\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(^.\\s*)const\\b/${1}static const/;\n\t\t\t}\n\t\t}\n\n# check for static char foo[] = \"bar\" declarations.\n\t\tif ($line =~ /\\bstatic\\s+char\\s+(\\w+)\\s*\\[\\s*\\]\\s*=\\s*\"/) {\n\t\t\tWARN(\"STATIC_CONST_CHAR_ARRAY\",\n\t\t\t     \"static char array declaration should probably be static const char\\n\" .\n\t\t\t\t$herecurr);\n\t\t}\n\n# check for const <foo> const where <foo> is not a pointer or array type\n\t\tif ($sline =~ /\\bconst\\s+($BasicType)\\s+const\\b/) {\n\t\t\tmy $found = $1;\n\t\t\tif ($sline =~ /\\bconst\\s+\\Q$found\\E\\s+const\\b\\s*\\*/) {\n\t\t\t\tWARN(\"CONST_CONST\",\n\t\t\t\t     \"'const $found const *' should probably be 'const $found * const'\\n\" . $herecurr);\n\t\t\t} elsif ($sline !~ /\\bconst\\s+\\Q$found\\E\\s+const\\s+\\w+\\s*\\[/) {\n\t\t\t\tWARN(\"CONST_CONST\",\n\t\t\t\t     \"'const $found const' should probably be 'const $found'\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for const static or static <non ptr type> const declarations\n# prefer 'static const <foo>' over 'const static <foo>' and 'static <foo> const'\n\t\tif ($sline =~ /^\\+\\s*const\\s+static\\s+($Type)\\b/ ||\n\t\t    $sline =~ /^\\+\\s*static\\s+($BasicType)\\s+const\\b/) {\n\t\t\tif (WARN(\"STATIC_CONST\",\n\t\t\t\t \"Move const after static - use 'static const $1'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\bconst\\s+static\\b/static const/;\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\bstatic\\s+($BasicType)\\s+const\\b/static const $1/;\n\t\t\t}\n\t\t}\n\n# check for non-global char *foo[] = {\"bar\", ...} declarations.\n\t\tif ($line =~ /^.\\s+(?:static\\s+|const\\s+)?char\\s+\\*\\s*\\w+\\s*\\[\\s*\\]\\s*=\\s*\\{/) {\n\t\t\tWARN(\"STATIC_CONST_CHAR_ARRAY\",\n\t\t\t     \"char * array declaration might be better as static const\\n\" .\n\t\t\t\t$herecurr);\n\t\t}\n\n# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)\n\t\tif ($line =~ m@\\bsizeof\\s*\\(\\s*($Lval)\\s*\\)@) {\n\t\t\tmy $array = $1;\n\t\t\tif ($line =~ m@\\b(sizeof\\s*\\(\\s*\\Q$array\\E\\s*\\)\\s*/\\s*sizeof\\s*\\(\\s*\\Q$array\\E\\s*\\[\\s*0\\s*\\]\\s*\\))@) {\n\t\t\t\tmy $array_div = $1;\n\t\t\t\tif (WARN(\"ARRAY_SIZE\",\n\t\t\t\t\t \"Prefer ARRAY_SIZE($array)\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$array_div\\E/ARRAY_SIZE($array)/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for function declarations without arguments like \"int foo()\"\n\t\tif ($line =~ /(\\b$Type\\s*$Ident)\\s*\\(\\s*\\)/) {\n\t\t\tif (ERROR(\"FUNCTION_WITHOUT_ARGS\",\n\t\t\t\t  \"Bad function definition - $1() should probably be $1(void)\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(\\b($Type)\\s+($Ident))\\s*\\(\\s*\\)/$2 $3(void)/;\n\t\t\t}\n\t\t}\n\n# check for new typedefs, only function parameters and sparse annotations\n# make sense.\n\t\tif ($line =~ /\\btypedef\\s/ &&\n\t\t    $line !~ /\\btypedef\\s+$Type\\s*\\(\\s*\\*?$Ident\\s*\\)\\s*\\(/ &&\n\t\t    $line !~ /\\btypedef\\s+$Type\\s+$Ident\\s*\\(/ &&\n\t\t    $line !~ /\\b$typeTypedefs\\b/ &&\n\t\t    $line !~ /\\b__bitwise\\b/) {\n\t\t\tWARN(\"NEW_TYPEDEFS\",\n\t\t\t     \"do not add new typedefs\\n\" . $herecurr);\n\t\t}\n\n# * goes on variable not on type\n\t\t# (char*[ const])\n\t\twhile ($line =~ m{(\\($NonptrType(\\s*(?:$Modifier\\b\\s*|\\*\\s*)+)\\))}g) {\n\t\t\t#print \"AA<$1>\\n\";\n\t\t\tmy ($ident, $from, $to) = ($1, $2, $2);\n\n\t\t\t# Should start with a space.\n\t\t\t$to =~ s/^(\\S)/ $1/;\n\t\t\t# Should not end with a space.\n\t\t\t$to =~ s/\\s+$//;\n\t\t\t# '*'s should not have spaces between.\n\t\t\twhile ($to =~ s/\\*\\s+\\*/\\*\\*/) {\n\t\t\t}\n\n##\t\t\tprint \"1: from<$from> to<$to> ident<$ident>\\n\";\n\t\t\tif ($from ne $to) {\n\t\t\t\tif (ERROR(\"POINTER_LOCATION\",\n\t\t\t\t\t  \"\\\"(foo$from)\\\" should be \\\"(foo$to)\\\"\\n\" .  $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\tmy $sub_from = $ident;\n\t\t\t\t\tmy $sub_to = $ident;\n\t\t\t\t\t$sub_to =~ s/\\Q$from\\E/$to/;\n\t\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t\t    s@\\Q$sub_from\\E@$sub_to@;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\twhile ($line =~ m{(\\b$NonptrType(\\s*(?:$Modifier\\b\\s*|\\*\\s*)+)($Ident))}g) {\n\t\t\t#print \"BB<$1>\\n\";\n\t\t\tmy ($match, $from, $to, $ident) = ($1, $2, $2, $3);\n\n\t\t\t# Should start with a space.\n\t\t\t$to =~ s/^(\\S)/ $1/;\n\t\t\t# Should not end with a space.\n\t\t\t$to =~ s/\\s+$//;\n\t\t\t# '*'s should not have spaces between.\n\t\t\twhile ($to =~ s/\\*\\s+\\*/\\*\\*/) {\n\t\t\t}\n\t\t\t# Modifiers should have spaces.\n\t\t\t$to =~ s/(\\b$Modifier$)/$1 /;\n\n##\t\t\tprint \"2: from<$from> to<$to> ident<$ident>\\n\";\n\t\t\tif ($from ne $to && $ident !~ /^$Modifier$/) {\n\t\t\t\tif (ERROR(\"POINTER_LOCATION\",\n\t\t\t\t\t  \"\\\"foo${from}bar\\\" should be \\\"foo${to}bar\\\"\\n\" .  $herecurr) &&\n\t\t\t\t    $fix) {\n\n\t\t\t\t\tmy $sub_from = $match;\n\t\t\t\t\tmy $sub_to = $match;\n\t\t\t\t\t$sub_to =~ s/\\Q$from\\E/$to/;\n\t\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t\t    s@\\Q$sub_from\\E@$sub_to@;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# avoid BUG() or BUG_ON()\n\t\tif ($line =~ /\\b(?:BUG|BUG_ON)\\b/) {\n\t\t\tmy $msg_level = \\&WARN;\n\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t&{$msg_level}(\"AVOID_BUG\",\n\t\t\t\t      \"Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\\n\" . $herecurr);\n\t\t}\n\n# avoid LINUX_VERSION_CODE\n\t\tif ($line =~ /\\bLINUX_VERSION_CODE\\b/) {\n\t\t\tWARN(\"LINUX_VERSION_CODE\",\n\t\t\t     \"LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\\n\" . $herecurr);\n\t\t}\n\n# check for uses of printk_ratelimit\n\t\tif ($line =~ /\\bprintk_ratelimit\\s*\\(/) {\n\t\t\tWARN(\"PRINTK_RATELIMITED\",\n\t\t\t     \"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\\n\" . $herecurr);\n\t\t}\n\n# printk should use KERN_* levels\n\t\tif ($line =~ /\\bprintk\\s*\\(\\s*(?!KERN_[A-Z]+\\b)/) {\n\t\t\tWARN(\"PRINTK_WITHOUT_KERN_LEVEL\",\n\t\t\t     \"printk() should include KERN_<LEVEL> facility level\\n\" . $herecurr);\n\t\t}\n\n# prefer variants of (subsystem|netdev|dev|pr)_<level> to printk(KERN_<LEVEL>\n\t\tif ($line =~ /\\b(printk(_once|_ratelimited)?)\\s*\\(\\s*KERN_([A-Z]+)/) {\n\t\t\tmy $printk = $1;\n\t\t\tmy $modifier = $2;\n\t\t\tmy $orig = $3;\n\t\t\t$modifier = \"\" if (!defined($modifier));\n\t\t\tmy $level = lc($orig);\n\t\t\t$level = \"warn\" if ($level eq \"warning\");\n\t\t\tmy $level2 = $level;\n\t\t\t$level2 = \"dbg\" if ($level eq \"debug\");\n\t\t\t$level .= $modifier;\n\t\t\t$level2 .= $modifier;\n\t\t\tWARN(\"PREFER_PR_LEVEL\",\n\t\t\t     \"Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to $printk(KERN_$orig ...\\n\" . $herecurr);\n\t\t}\n\n# prefer dev_<level> to dev_printk(KERN_<LEVEL>\n\t\tif ($line =~ /\\bdev_printk\\s*\\(\\s*KERN_([A-Z]+)/) {\n\t\t\tmy $orig = $1;\n\t\t\tmy $level = lc($orig);\n\t\t\t$level = \"warn\" if ($level eq \"warning\");\n\t\t\t$level = \"dbg\" if ($level eq \"debug\");\n\t\t\tWARN(\"PREFER_DEV_LEVEL\",\n\t\t\t     \"Prefer dev_$level(... to dev_printk(KERN_$orig, ...\\n\" . $herecurr);\n\t\t}\n\n# trace_printk should not be used in production code.\n\t\tif ($line =~ /\\b(trace_printk|trace_puts|ftrace_vprintk)\\s*\\(/) {\n\t\t\tWARN(\"TRACE_PRINTK\",\n\t\t\t     \"Do not use $1() in production code (this can be ignored if built only with a debug config option)\\n\" . $herecurr);\n\t\t}\n\n# ENOSYS means \"bad syscall nr\" and nothing else.  This will have a small\n# number of false positives, but assembly files are not checked, so at\n# least the arch entry code will not trigger this warning.\n\t\tif ($line =~ /\\bENOSYS\\b/) {\n\t\t\tWARN(\"ENOSYS\",\n\t\t\t     \"ENOSYS means 'invalid syscall nr' and nothing else\\n\" . $herecurr);\n\t\t}\n\n# ENOTSUPP is not a standard error code and should be avoided in new patches.\n# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.\n# Similarly to ENOSYS warning a small number of false positives is expected.\n\t\tif (!$file && $line =~ /\\bENOTSUPP\\b/) {\n\t\t\tif (WARN(\"ENOTSUPP\",\n\t\t\t\t \"ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\bENOTSUPP\\b/EOPNOTSUPP/;\n\t\t\t}\n\t\t}\n\n# function brace can't be on same line, except for #defines of do while,\n# or if closed on same line\n\t\tif ($perl_version_ok &&\n\t\t    $sline =~ /$Type\\s*$Ident\\s*$balanced_parens\\s*\\{/ &&\n\t\t    $sline !~ /\\#\\s*define\\b.*do\\s*\\{/ &&\n\t\t    $sline !~ /}/) {\n\t\t\tif (ERROR(\"OPEN_BRACE\",\n\t\t\t\t  \"open brace '{' following function definitions go on the next line\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\tmy $fixed_line = $rawline;\n\t\t\t\t$fixed_line =~ /(^..*$Type\\s*$Ident\\(.*\\)\\s*)\\{(.*)$/;\n\t\t\t\tmy $line1 = $1;\n\t\t\t\tmy $line2 = $2;\n\t\t\t\tfix_insert_line($fixlinenr, ltrim($line1));\n\t\t\t\tfix_insert_line($fixlinenr, \"\\+{\");\n\t\t\t\tif ($line2 !~ /^\\s*$/) {\n\t\t\t\t\tfix_insert_line($fixlinenr, \"\\+\\t\" . trim($line2));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# open braces for enum, union and struct go on the same line.\n\t\tif ($line =~ /^.\\s*{/ &&\n\t\t    $prevline =~ /^.\\s*(?:typedef\\s+)?(enum|union|struct)(?:\\s+$Ident)?\\s*$/) {\n\t\t\tif (ERROR(\"OPEN_BRACE\",\n\t\t\t\t  \"open brace '{' following $1 go on the same line\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevline =~ /^\\+/ && $line =~ /^\\+/) {\n\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\tmy $fixedline = rtrim($prevrawline) . \" {\";\n\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t$fixedline = $rawline;\n\t\t\t\t$fixedline =~ s/^(.\\s*)\\{\\s*/$1\\t/;\n\t\t\t\tif ($fixedline !~ /^\\+\\s*$/) {\n\t\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# missing space after union, struct or enum definition\n\t\tif ($line =~ /^.\\s*(?:typedef\\s+)?(enum|union|struct)(?:\\s+$Ident){1,2}[=\\{]/) {\n\t\t\tif (WARN(\"SPACING\",\n\t\t\t\t \"missing space after $1 definition\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/^(.\\s*(?:typedef\\s+)?(?:enum|union|struct)(?:\\s+$Ident){1,2})([=\\{])/$1 $2/;\n\t\t\t}\n\t\t}\n\n# Function pointer declarations\n# check spacing between type, funcptr, and args\n# canonical declaration is \"type (*funcptr)(args...)\"\n\t\tif ($line =~ /^.\\s*($Declare)\\((\\s*)\\*(\\s*)($Ident)(\\s*)\\)(\\s*)\\(/) {\n\t\t\tmy $declare = $1;\n\t\t\tmy $pre_pointer_space = $2;\n\t\t\tmy $post_pointer_space = $3;\n\t\t\tmy $funcname = $4;\n\t\t\tmy $post_funcname_space = $5;\n\t\t\tmy $pre_args_space = $6;\n\n# the $Declare variable will capture all spaces after the type\n# so check it for a missing trailing missing space but pointer return types\n# don't need a space so don't warn for those.\n\t\t\tmy $post_declare_space = \"\";\n\t\t\tif ($declare =~ /(\\s+)$/) {\n\t\t\t\t$post_declare_space = $1;\n\t\t\t\t$declare = rtrim($declare);\n\t\t\t}\n\t\t\tif ($declare !~ /\\*$/ && $post_declare_space =~ /^$/) {\n\t\t\t\tWARN(\"SPACING\",\n\t\t\t\t     \"missing space after return type\\n\" . $herecurr);\n\t\t\t\t$post_declare_space = \" \";\n\t\t\t}\n\n# unnecessary space \"type  (*funcptr)(args...)\"\n# This test is not currently implemented because these declarations are\n# equivalent to\n#\tint  foo(int bar, ...)\n# and this is form shouldn't/doesn't generate a checkpatch warning.\n#\n#\t\t\telsif ($declare =~ /\\s{2,}$/) {\n#\t\t\t\tWARN(\"SPACING\",\n#\t\t\t\t     \"Multiple spaces after return type\\n\" . $herecurr);\n#\t\t\t}\n\n# unnecessary space \"type ( *funcptr)(args...)\"\n\t\t\tif (defined $pre_pointer_space &&\n\t\t\t    $pre_pointer_space =~ /^\\s/) {\n\t\t\t\tWARN(\"SPACING\",\n\t\t\t\t     \"Unnecessary space after function pointer open parenthesis\\n\" . $herecurr);\n\t\t\t}\n\n# unnecessary space \"type (* funcptr)(args...)\"\n\t\t\tif (defined $post_pointer_space &&\n\t\t\t    $post_pointer_space =~ /^\\s/) {\n\t\t\t\tWARN(\"SPACING\",\n\t\t\t\t     \"Unnecessary space before function pointer name\\n\" . $herecurr);\n\t\t\t}\n\n# unnecessary space \"type (*funcptr )(args...)\"\n\t\t\tif (defined $post_funcname_space &&\n\t\t\t    $post_funcname_space =~ /^\\s/) {\n\t\t\t\tWARN(\"SPACING\",\n\t\t\t\t     \"Unnecessary space after function pointer name\\n\" . $herecurr);\n\t\t\t}\n\n# unnecessary space \"type (*funcptr) (args...)\"\n\t\t\tif (defined $pre_args_space &&\n\t\t\t    $pre_args_space =~ /^\\s/) {\n\t\t\t\tWARN(\"SPACING\",\n\t\t\t\t     \"Unnecessary space before function pointer arguments\\n\" . $herecurr);\n\t\t\t}\n\n\t\t\tif (show_type(\"SPACING\") && $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/^(.\\s*)$Declare\\s*\\(\\s*\\*\\s*$Ident\\s*\\)\\s*\\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;\n\t\t\t}\n\t\t}\n\n# check for spacing round square brackets; allowed:\n#  1. with a type on the left -- int [] a;\n#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,\n#  3. inside a curly brace -- = { [0...10] = 5 }\n\t\twhile ($line =~ /(.*?\\s)\\[/g) {\n\t\t\tmy ($where, $prefix) = ($-[1], $1);\n\t\t\tif ($prefix !~ /$Type\\s+$/ &&\n\t\t\t    ($where != 0 || $prefix !~ /^.\\s+$/) &&\n\t\t\t    $prefix !~ /[{,:]\\s+$/) {\n\t\t\t\tif (ERROR(\"BRACKET_SPACE\",\n\t\t\t\t\t  \"space prohibited before open square bracket '['\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t    $fixed[$fixlinenr] =~\n\t\t\t\t\ts/^(\\+.*?)\\s+\\[/$1\\[/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for spaces between functions and their parentheses.\n\t\twhile ($line =~ /($Ident)\\s+\\(/g) {\n\t\t\tmy $name = $1;\n\t\t\tmy $ctx_before = substr($line, 0, $-[1]);\n\t\t\tmy $ctx = \"$ctx_before$name\";\n\n\t\t\t# Ignore those directives where spaces _are_ permitted.\n\t\t\tif ($name =~ /^(?:\n\t\t\t\tif|for|while|switch|return|case|\n\t\t\t\tvolatile|__volatile__|\n\t\t\t\t__attribute__|format|__extension__|\n\t\t\t\tasm|__asm__)$/x)\n\t\t\t{\n\t\t\t# cpp #define statements have non-optional spaces, ie\n\t\t\t# if there is a space between the name and the open\n\t\t\t# parenthesis it is simply not a parameter group.\n\t\t\t} elsif ($ctx_before =~ /^.\\s*\\#\\s*define\\s*$/) {\n\n\t\t\t# cpp #elif statement condition may start with a (\n\t\t\t} elsif ($ctx =~ /^.\\s*\\#\\s*elif\\s*$/) {\n\n\t\t\t# If this whole things ends with a type its most\n\t\t\t# likely a typedef for a function.\n\t\t\t} elsif ($ctx =~ /$Type$/) {\n\n\t\t\t} else {\n\t\t\t\tif (WARN(\"SPACING\",\n\t\t\t\t\t \"space prohibited between function name and open parenthesis '('\\n\" . $herecurr) &&\n\t\t\t\t\t     $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t\t    s/\\b$name\\s+\\(/$name\\(/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check operator spacing.\n\t\tif (!($line=~/\\#\\s*include/)) {\n\t\t\tmy $fixed_line = \"\";\n\t\t\tmy $line_fixed = 0;\n\n\t\t\tmy $ops = qr{\n\t\t\t\t<<=|>>=|<=|>=|==|!=|\n\t\t\t\t\\+=|-=|\\*=|\\/=|%=|\\^=|\\|=|&=|\n\t\t\t\t=>|->|<<|>>|<|>|=|!|~|\n\t\t\t\t&&|\\|\\||,|\\^|\\+\\+|--|&|\\||\\+|-|\\*|\\/|%|\n\t\t\t\t\\?:|\\?|:\n\t\t\t}x;\n\t\t\tmy @elements = split(/($ops|;)/, $opline);\n\n##\t\t\tprint(\"element count: <\" . $#elements . \">\\n\");\n##\t\t\tforeach my $el (@elements) {\n##\t\t\t\tprint(\"el: <$el>\\n\");\n##\t\t\t}\n\n\t\t\tmy @fix_elements = ();\n\t\t\tmy $off = 0;\n\n\t\t\tforeach my $el (@elements) {\n\t\t\t\tpush(@fix_elements, substr($rawline, $off, length($el)));\n\t\t\t\t$off += length($el);\n\t\t\t}\n\n\t\t\t$off = 0;\n\n\t\t\tmy $blank = copy_spacing($opline);\n\t\t\tmy $last_after = -1;\n\n\t\t\tfor (my $n = 0; $n < $#elements; $n += 2) {\n\n\t\t\t\tmy $good = $fix_elements[$n] . $fix_elements[$n + 1];\n\n##\t\t\t\tprint(\"n: <$n> good: <$good>\\n\");\n\n\t\t\t\t$off += length($elements[$n]);\n\n\t\t\t\t# Pick up the preceding and succeeding characters.\n\t\t\t\tmy $ca = substr($opline, 0, $off);\n\t\t\t\tmy $cc = '';\n\t\t\t\tif (length($opline) >= ($off + length($elements[$n + 1]))) {\n\t\t\t\t\t$cc = substr($opline, $off + length($elements[$n + 1]));\n\t\t\t\t}\n\t\t\t\tmy $cb = \"$ca$;$cc\";\n\n\t\t\t\tmy $a = '';\n\t\t\t\t$a = 'V' if ($elements[$n] ne '');\n\t\t\t\t$a = 'W' if ($elements[$n] =~ /\\s$/);\n\t\t\t\t$a = 'C' if ($elements[$n] =~ /$;$/);\n\t\t\t\t$a = 'B' if ($elements[$n] =~ /(\\[|\\()$/);\n\t\t\t\t$a = 'O' if ($elements[$n] eq '');\n\t\t\t\t$a = 'E' if ($ca =~ /^\\s*$/);\n\n\t\t\t\tmy $op = $elements[$n + 1];\n\n\t\t\t\tmy $c = '';\n\t\t\t\tif (defined $elements[$n + 2]) {\n\t\t\t\t\t$c = 'V' if ($elements[$n + 2] ne '');\n\t\t\t\t\t$c = 'W' if ($elements[$n + 2] =~ /^\\s/);\n\t\t\t\t\t$c = 'C' if ($elements[$n + 2] =~ /^$;/);\n\t\t\t\t\t$c = 'B' if ($elements[$n + 2] =~ /^(\\)|\\]|;)/);\n\t\t\t\t\t$c = 'O' if ($elements[$n + 2] eq '');\n\t\t\t\t\t$c = 'E' if ($elements[$n + 2] =~ /^\\s*\\\\$/);\n\t\t\t\t} else {\n\t\t\t\t\t$c = 'E';\n\t\t\t\t}\n\n\t\t\t\tmy $ctx = \"${a}x${c}\";\n\n\t\t\t\tmy $at = \"(ctx:$ctx)\";\n\n\t\t\t\tmy $ptr = substr($blank, 0, $off) . \"^\";\n\t\t\t\tmy $hereptr = \"$hereline$ptr\\n\";\n\n\t\t\t\t# Pull out the value of this operator.\n\t\t\t\tmy $op_type = substr($curr_values, $off + 1, 1);\n\n\t\t\t\t# Get the full operator variant.\n\t\t\t\tmy $opv = $op . substr($curr_vars, $off, 1);\n\n\t\t\t\t# Ignore operators passed as parameters.\n\t\t\t\tif ($op_type ne 'V' &&\n\t\t\t\t    $ca =~ /\\s$/ && $cc =~ /^\\s*[,\\)]/) {\n\n#\t\t\t\t# Ignore comments\n#\t\t\t\t} elsif ($op =~ /^$;+$/) {\n\n\t\t\t\t# ; should have either the end of line or a space or \\ after it\n\t\t\t\t} elsif ($op eq ';') {\n\t\t\t\t\tif ($ctx !~ /.x[WEBC]/ &&\n\t\t\t\t\t    $cc !~ /^\\\\/ && $cc !~ /^;/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space required after that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . \" \";\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# // is a comment\n\t\t\t\t} elsif ($op eq '//') {\n\n\t\t\t\t#   :   when part of a bitfield\n\t\t\t\t} elsif ($opv eq ':B') {\n\t\t\t\t\t# skip the bitfield test for now\n\n\t\t\t\t# No spaces for:\n\t\t\t\t#   ->\n\t\t\t\t} elsif ($op eq '->') {\n\t\t\t\t\tif ($ctx =~ /Wx.|.xW/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"spaces prohibited around that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\tif (defined $fix_elements[$n + 2]) {\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# , must not have a space before and must have a space on the right.\n\t\t\t\t} elsif ($op eq ',') {\n\t\t\t\t\tmy $rtrim_before = 0;\n\t\t\t\t\tmy $space_after = 0;\n\t\t\t\t\tif ($ctx =~ /Wx./) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space prohibited before that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t\t$rtrim_before = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space required after that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t\t$last_after = $n;\n\t\t\t\t\t\t\t$space_after = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($rtrim_before || $space_after) {\n\t\t\t\t\t\tif ($rtrim_before) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($space_after) {\n\t\t\t\t\t\t\t$good .= \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# '*' as part of a type definition -- reported already.\n\t\t\t\t} elsif ($opv eq '*_') {\n\t\t\t\t\t#warn \"'*' is part of type\\n\";\n\n\t\t\t\t# unary operators should have a space before and\n\t\t\t\t# none after.  May be left adjacent to another\n\t\t\t\t# unary operator, or a cast\n\t\t\t\t} elsif ($op eq '!' || $op eq '~' ||\n\t\t\t\t\t $opv eq '*U' || $opv eq '-U' ||\n\t\t\t\t\t $opv eq '&U' || $opv eq '&&U') {\n\t\t\t\t\tif ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\\)|!|~|\\*|-|\\&|\\||\\+\\+|\\-\\-|\\{)$/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space required before that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\tif ($n != $last_after + 2) {\n\t\t\t\t\t\t\t\t$good = $fix_elements[$n] . \" \" . ltrim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($op eq '*' && $cc =~/\\s*$Modifier\\b/) {\n\t\t\t\t\t\t# A unary '*' may be const\n\n\t\t\t\t\t} elsif ($ctx =~ /.xW/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space prohibited after that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\tif (defined $fix_elements[$n + 2]) {\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# unary ++ and unary -- are allowed no space on one side.\n\t\t\t\t} elsif ($op eq '++' or $op eq '--') {\n\t\t\t\t\tif ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space required one side of that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . \" \";\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($ctx =~ /Wx[BE]/ ||\n\t\t\t\t\t    ($ctx =~ /Wx./ && $cc =~ /^;/)) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space prohibited before that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($ctx =~ /ExW/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space prohibited after that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\tif (defined $fix_elements[$n + 2]) {\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# << and >> may either have or not have spaces both sides\n\t\t\t\t} elsif ($op eq '<<' or $op eq '>>' or\n\t\t\t\t\t $op eq '&' or $op eq '^' or $op eq '|' or\n\t\t\t\t\t $op eq '+' or $op eq '-' or\n\t\t\t\t\t $op eq '*' or $op eq '/' or\n\t\t\t\t\t $op eq '%')\n\t\t\t\t{\n\t\t\t\t\tif ($check) {\n\t\t\t\t\t\tif (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {\n\t\t\t\t\t\t\tif (CHK(\"SPACING\",\n\t\t\t\t\t\t\t\t\"spaces preferred around that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . \" \" . trim($fix_elements[$n + 1]) . \" \";\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {\n\t\t\t\t\t\t\tif (CHK(\"SPACING\",\n\t\t\t\t\t\t\t\t\"space preferred before that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . \" \" . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"need consistent spacing around '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . \" \" . trim($fix_elements[$n + 1]) . \" \";\n\t\t\t\t\t\t\tif (defined $fix_elements[$n + 2]) {\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# A colon needs no spaces before when it is\n\t\t\t\t# terminating a case value or a label.\n\t\t\t\t} elsif ($opv eq ':C' || $opv eq ':L') {\n\t\t\t\t\tif ($ctx =~ /Wx./ and $realfile !~ m@.*\\.lds\\.h$@) {\n\t\t\t\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t\t\t\t  \"space prohibited before that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t# All the others need spaces both sides.\n\t\t\t\t} elsif ($ctx !~ /[EWC]x[CWE]/) {\n\t\t\t\t\tmy $ok = 0;\n\n\t\t\t\t\t# Ignore email addresses <foo@bar>\n\t\t\t\t\tif (($op eq '<' &&\n\t\t\t\t\t     $cc =~ /^\\S+\\@\\S+>/) ||\n\t\t\t\t\t    ($op eq '>' &&\n\t\t\t\t\t     $ca =~ /<\\S+\\@\\S+$/))\n\t\t\t\t\t{\n\t\t\t\t\t\t$ok = 1;\n\t\t\t\t\t}\n\n\t\t\t\t\t# for asm volatile statements\n\t\t\t\t\t# ignore a colon with another\n\t\t\t\t\t# colon immediately before or after\n\t\t\t\t\tif (($op eq ':') &&\n\t\t\t\t\t    ($ca =~ /:$/ || $cc =~ /^:/)) {\n\t\t\t\t\t\t$ok = 1;\n\t\t\t\t\t}\n\n\t\t\t\t\t# messages are ERROR, but ?: are CHK\n\t\t\t\t\tif ($ok == 0) {\n\t\t\t\t\t\tmy $msg_level = \\&ERROR;\n\t\t\t\t\t\t$msg_level = \\&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);\n\n\t\t\t\t\t\tif (&{$msg_level}(\"SPACING\",\n\t\t\t\t\t\t\t\t  \"spaces required around that '$op' $at\\n\" . $hereptr)) {\n\t\t\t\t\t\t\t$good = rtrim($fix_elements[$n]) . \" \" . trim($fix_elements[$n + 1]) . \" \";\n\t\t\t\t\t\t\tif (defined $fix_elements[$n + 2]) {\n\t\t\t\t\t\t\t\t$fix_elements[$n + 2] =~ s/^\\s+//;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$line_fixed = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$off += length($elements[$n + 1]);\n\n##\t\t\t\tprint(\"n: <$n> GOOD: <$good>\\n\");\n\n\t\t\t\t$fixed_line = $fixed_line . $good;\n\t\t\t}\n\n\t\t\tif (($#elements % 2) == 0) {\n\t\t\t\t$fixed_line = $fixed_line . $fix_elements[$#elements];\n\t\t\t}\n\n\t\t\tif ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {\n\t\t\t\t$fixed[$fixlinenr] = $fixed_line;\n\t\t\t}\n\n\n\t\t}\n\n# check for whitespace before a non-naked semicolon\n\t\tif ($line =~ /^\\+.*\\S\\s+;\\s*$/) {\n\t\t\tif (WARN(\"SPACING\",\n\t\t\t\t \"space prohibited before semicolon\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t1 while $fixed[$fixlinenr] =~\n\t\t\t\t    s/^(\\+.*\\S)\\s+;/$1;/;\n\t\t\t}\n\t\t}\n\n# check for multiple assignments\n\t\tif ($line =~ /^.\\s*$Lval\\s*=\\s*$Lval\\s*=(?!=)/) {\n\t\t\tCHK(\"MULTIPLE_ASSIGNMENTS\",\n\t\t\t    \"multiple assignments should be avoided\\n\" . $herecurr);\n\t\t}\n\n## # check for multiple declarations, allowing for a function declaration\n## # continuation.\n## \t\tif ($line =~ /^.\\s*$Type\\s+$Ident(?:\\s*=[^,{]*)?\\s*,\\s*$Ident.*/ &&\n## \t\t    $line !~ /^.\\s*$Type\\s+$Ident(?:\\s*=[^,{]*)?\\s*,\\s*$Type\\s*$Ident.*/) {\n##\n## \t\t\t# Remove any bracketed sections to ensure we do not\n## \t\t\t# falsely report the parameters of functions.\n## \t\t\tmy $ln = $line;\n## \t\t\twhile ($ln =~ s/\\([^\\(\\)]*\\)//g) {\n## \t\t\t}\n## \t\t\tif ($ln =~ /,/) {\n## \t\t\t\tWARN(\"MULTIPLE_DECLARATION\",\n##\t\t\t\t     \"declaring multiple variables together should be avoided\\n\" . $herecurr);\n## \t\t\t}\n## \t\t}\n\n#need space before brace following if, while, etc\n\t\tif (($line =~ /\\(.*\\)\\{/ && $line !~ /\\($Type\\)\\{/) ||\n\t\t    $line =~ /\\b(?:else|do)\\{/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space required before the open brace '{'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/^(\\+.*(?:do|else|\\)))\\{/$1 {/;\n\t\t\t}\n\t\t}\n\n## # check for blank lines before declarations\n##\t\tif ($line =~ /^.\\t+$Type\\s+$Ident(?:\\s*=.*)?;/ &&\n##\t\t    $prevrawline =~ /^.\\s*$/) {\n##\t\t\tWARN(\"SPACING\",\n##\t\t\t     \"No blank lines before declarations\\n\" . $hereprev);\n##\t\t}\n##\n\n# closing brace should have a space following it when it has anything\n# on the line\n\t\tif ($line =~ /}(?!(?:,|;|\\)|\\}))\\S/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space required after that close brace '}'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/}((?!(?:,|;|\\)))\\S)/} $1/;\n\t\t\t}\n\t\t}\n\n# check spacing on square brackets\n\t\tif ($line =~ /\\[\\s/ && $line !~ /\\[\\s*$/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space prohibited after that open square bracket '['\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/\\[\\s+/\\[/;\n\t\t\t}\n\t\t}\n\t\tif ($line =~ /\\s\\]/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space prohibited before that close square bracket ']'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/\\s+\\]/\\]/;\n\t\t\t}\n\t\t}\n\n# check spacing on parentheses\n\t\tif ($line =~ /\\(\\s/ && $line !~ /\\(\\s*(?:\\\\)?$/ &&\n\t\t    $line !~ /for\\s*\\(\\s+;/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space prohibited after that open parenthesis '('\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/\\(\\s+/\\(/;\n\t\t\t}\n\t\t}\n\t\tif ($line =~ /(\\s+)\\)/ && $line !~ /^.\\s*\\)/ &&\n\t\t    $line !~ /for\\s*\\(.*;\\s+\\)/ &&\n\t\t    $line !~ /:\\s+\\)/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space prohibited before that close parenthesis ')'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/\\s+\\)/\\)/;\n\t\t\t}\n\t\t}\n\n# check unnecessary parentheses around addressof/dereference single $Lvals\n# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar\n\n\t\twhile ($line =~ /(?:[^&]&\\s*|\\*)\\(\\s*($Ident\\s*(?:$Member\\s*)+)\\s*\\)/g) {\n\t\t\tmy $var = $1;\n\t\t\tif (CHK(\"UNNECESSARY_PARENTHESES\",\n\t\t\t\t\"Unnecessary parentheses around $var\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\(\\s*\\Q$var\\E\\s*\\)/$var/;\n\t\t\t}\n\t\t}\n\n# check for unnecessary parentheses around function pointer uses\n# ie: (foo->bar)(); should be foo->bar();\n# but not \"if (foo->bar) (\" to avoid some false positives\n\t\tif ($line =~ /(\\bif\\s*|)(\\(\\s*$Ident\\s*(?:$Member\\s*)+\\))[ \\t]*\\(/ && $1 !~ /^if/) {\n\t\t\tmy $var = $2;\n\t\t\tif (CHK(\"UNNECESSARY_PARENTHESES\",\n\t\t\t\t\"Unnecessary parentheses around function pointer $var\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tmy $var2 = deparenthesize($var);\n\t\t\t\t$var2 =~ s/\\s//g;\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$var\\E/$var2/;\n\t\t\t}\n\t\t}\n\n# check for unnecessary parentheses around comparisons in if uses\n# when !drivers/staging or command-line uses --strict\n\t\tif (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&\n\t\t    $perl_version_ok && defined($stat) &&\n\t\t    $stat =~ /(^.\\s*if\\s*($balanced_parens))/) {\n\t\t\tmy $if_stat = $1;\n\t\t\tmy $test = substr($2, 1, -1);\n\t\t\tmy $herectx;\n\t\t\twhile ($test =~ /(?:^|[^\\w\\&\\!\\~])+\\s*\\(\\s*([\\&\\!\\~]?\\s*$Lval\\s*(?:$Compare\\s*$FuncArg)?)\\s*\\)/g) {\n\t\t\t\tmy $match = $1;\n\t\t\t\t# avoid parentheses around potential macro args\n\t\t\t\tnext if ($match =~ /^\\s*\\w+\\s*$/);\n\t\t\t\tif (!defined($herectx)) {\n\t\t\t\t\t$herectx = $here . \"\\n\";\n\t\t\t\t\tmy $cnt = statement_rawlines($if_stat);\n\t\t\t\t\tfor (my $n = 0; $n < $cnt; $n++) {\n\t\t\t\t\t\tmy $rl = raw_line($linenr, $n);\n\t\t\t\t\t\t$herectx .=  $rl . \"\\n\";\n\t\t\t\t\t\tlast if $rl =~ /^[ \\+].*\\{/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tCHK(\"UNNECESSARY_PARENTHESES\",\n\t\t\t\t    \"Unnecessary parentheses around '$match'\\n\" . $herectx);\n\t\t\t}\n\t\t}\n\n# check that goto labels aren't indented (allow a single space indentation)\n# and ignore bitfield definitions like foo:1\n# Strictly, labels can have whitespace after the identifier and before the :\n# but this is not allowed here as many ?: uses would appear to be labels\n\t\tif ($sline =~ /^.\\s+[A-Za-z_][A-Za-z\\d_]*:(?!\\s*\\d+)/ &&\n\t\t    $sline !~ /^. [A-Za-z\\d_][A-Za-z\\d_]*:/ &&\n\t\t    $sline !~ /^.\\s+default:/) {\n\t\t\tif (WARN(\"INDENTED_LABEL\",\n\t\t\t\t \"labels should not be indented\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/^(.)\\s+/$1/;\n\t\t\t}\n\t\t}\n\n# check if a statement with a comma should be two statements like:\n#\tfoo = bar(),\t/* comma should be semicolon */\n#\tbar = baz();\n\t\tif (defined($stat) &&\n\t\t    $stat =~ /^\\+\\s*(?:$Lval\\s*$Assignment\\s*)?$FuncArg\\s*,\\s*(?:$Lval\\s*$Assignment\\s*)?$FuncArg\\s*;\\s*$/) {\n\t\t\tmy $cnt = statement_rawlines($stat);\n\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\t\t\tWARN(\"SUSPECT_COMMA_SEMICOLON\",\n\t\t\t     \"Possible comma where semicolon could be used\\n\" . $herectx);\n\t\t}\n\n# return is not a function\n\t\tif (defined($stat) && $stat =~ /^.\\s*return(\\s*)\\(/s) {\n\t\t\tmy $spacing = $1;\n\t\t\tif ($perl_version_ok &&\n\t\t\t    $stat =~ /^.\\s*return\\s*($balanced_parens)\\s*;\\s*$/) {\n\t\t\t\tmy $value = $1;\n\t\t\t\t$value = deparenthesize($value);\n\t\t\t\tif ($value =~ m/^\\s*$FuncArg\\s*(?:\\?|$)/) {\n\t\t\t\t\tERROR(\"RETURN_PARENTHESES\",\n\t\t\t\t\t      \"return is not a function, parentheses are not required\\n\" . $herecurr);\n\t\t\t\t}\n\t\t\t} elsif ($spacing !~ /\\s+/) {\n\t\t\t\tERROR(\"SPACING\",\n\t\t\t\t      \"space required before the open parenthesis '('\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# unnecessary return in a void function\n# at end-of-function, with the previous line a single leading tab, then return;\n# and the line before that not a goto label target like \"out:\"\n\t\tif ($sline =~ /^[ \\+]}\\s*$/ &&\n\t\t    $prevline =~ /^\\+\\treturn\\s*;\\s*$/ &&\n\t\t    $linenr >= 3 &&\n\t\t    $lines[$linenr - 3] =~ /^[ +]/ &&\n\t\t    $lines[$linenr - 3] !~ /^[ +]\\s*$Ident\\s*:/) {\n\t\t\tWARN(\"RETURN_VOID\",\n\t\t\t     \"void function return statements are not generally useful\\n\" . $hereprev);\n\t\t}\n\n# if statements using unnecessary parentheses - ie: if ((foo == bar))\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /\\bif\\s*((?:\\(\\s*){2,})/) {\n\t\t\tmy $openparens = $1;\n\t\t\tmy $count = $openparens =~ tr@\\(@\\(@;\n\t\t\tmy $msg = \"\";\n\t\t\tif ($line =~ /\\bif\\s*(?:\\(\\s*){$count,$count}$LvalOrFunc\\s*($Compare)\\s*$LvalOrFunc(?:\\s*\\)){$count,$count}/) {\n\t\t\t\tmy $comp = $4;\t#Not $1 because of $LvalOrFunc\n\t\t\t\t$msg = \" - maybe == should be = ?\" if ($comp eq \"==\");\n\t\t\t\tWARN(\"UNNECESSARY_PARENTHESES\",\n\t\t\t\t     \"Unnecessary parentheses$msg\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# comparisons with a constant or upper case identifier on the left\n#\tavoid cases like \"foo + BAR < baz\"\n#\tonly fix matches surrounded by parentheses to avoid incorrect\n#\tconversions like \"FOO < baz() + 5\" being \"misfixed\" to \"baz() > FOO + 5\"\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /^\\+(.*)\\b($Constant|[A-Z_][A-Z0-9_]*)\\s*($Compare)\\s*($LvalOrFunc)/) {\n\t\t\tmy $lead = $1;\n\t\t\tmy $const = $2;\n\t\t\tmy $comp = $3;\n\t\t\tmy $to = $4;\n\t\t\tmy $newcomp = $comp;\n\t\t\tif ($lead !~ /(?:$Operators|\\.)\\s*$/ &&\n\t\t\t    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&\n\t\t\t    WARN(\"CONSTANT_COMPARISON\",\n\t\t\t\t \"Comparisons should place the constant on the right side of the test\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tif ($comp eq \"<\") {\n\t\t\t\t\t$newcomp = \">\";\n\t\t\t\t} elsif ($comp eq \"<=\") {\n\t\t\t\t\t$newcomp = \">=\";\n\t\t\t\t} elsif ($comp eq \">\") {\n\t\t\t\t\t$newcomp = \"<\";\n\t\t\t\t} elsif ($comp eq \">=\") {\n\t\t\t\t\t$newcomp = \"<=\";\n\t\t\t\t}\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\(\\s*\\Q$const\\E\\s*$Compare\\s*\\Q$to\\E\\s*\\)/($to $newcomp $const)/;\n\t\t\t}\n\t\t}\n\n# Return of what appears to be an errno should normally be negative\n\t\tif ($sline =~ /\\breturn(?:\\s*\\(+\\s*|\\s+)(E[A-Z]+)(?:\\s*\\)+\\s*|\\s*)[;:,]/) {\n\t\t\tmy $name = $1;\n\t\t\tif ($name ne 'EOF' && $name ne 'ERROR' && $name !~ /^EPOLL/) {\n\t\t\t\tWARN(\"USE_NEGATIVE_ERRNO\",\n\t\t\t\t     \"return of an errno should typically be negative (ie: return -$1)\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# Need a space before open parenthesis after if, while etc\n\t\tif ($line =~ /\\b(if|while|for|switch)\\(/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"space required before the open parenthesis '('\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/\\b(if|while|for|switch)\\(/$1 \\(/;\n\t\t\t}\n\t\t}\n\n# Check for illegal assignment in if conditional -- and check for trailing\n# statements after the conditional.\n\t\tif ($line =~ /do\\s*(?!{)/) {\n\t\t\t($stat, $cond, $line_nr_next, $remain_next, $off_next) =\n\t\t\t\tctx_statement_block($linenr, $realcnt, 0)\n\t\t\t\t\tif (!defined $stat);\n\t\t\tmy ($stat_next) = ctx_statement_block($line_nr_next,\n\t\t\t\t\t\t$remain_next, $off_next);\n\t\t\t$stat_next =~ s/\\n./\\n /g;\n\t\t\t##print \"stat<$stat> stat_next<$stat_next>\\n\";\n\n\t\t\tif ($stat_next =~ /^\\s*while\\b/) {\n\t\t\t\t# If the statement carries leading newlines,\n\t\t\t\t# then count those as offsets.\n\t\t\t\tmy ($whitespace) =\n\t\t\t\t\t($stat_next =~ /^((?:\\s*\\n[+-])*\\s*)/s);\n\t\t\t\tmy $offset =\n\t\t\t\t\tstatement_rawlines($whitespace) - 1;\n\n\t\t\t\t$suppress_whiletrailers{$line_nr_next +\n\t\t\t\t\t\t\t\t$offset} = 1;\n\t\t\t}\n\t\t}\n\t\tif (!defined $suppress_whiletrailers{$linenr} &&\n\t\t    defined($stat) && defined($cond) &&\n\t\t    $line =~ /\\b(?:if|while|for)\\s*\\(/ && $line !~ /^.\\s*#/) {\n\t\t\tmy ($s, $c) = ($stat, $cond);\n\t\t\tmy $fixed_assign_in_if = 0;\n\n\t\t\tif ($c =~ /\\bif\\s*\\(.*[^<>!=]=[^=].*/s) {\n\t\t\t\tif (ERROR(\"ASSIGN_IN_IF\",\n\t\t\t\t\t  \"do not use assignment in if condition\\n\" . $herecurr) &&\n\t\t\t\t    $fix && $perl_version_ok) {\n\t\t\t\t\tif ($rawline =~ /^\\+(\\s+)if\\s*\\(\\s*(\\!)?\\s*\\(\\s*(($Lval)\\s*=\\s*$LvalOrFunc)\\s*\\)\\s*(?:($Compare)\\s*($FuncArg))?\\s*\\)\\s*(\\{)?\\s*$/) {\n\t\t\t\t\t\tmy $space = $1;\n\t\t\t\t\t\tmy $not = $2;\n\t\t\t\t\t\tmy $statement = $3;\n\t\t\t\t\t\tmy $assigned = $4;\n\t\t\t\t\t\tmy $test = $8;\n\t\t\t\t\t\tmy $against = $9;\n\t\t\t\t\t\tmy $brace = $15;\n\t\t\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\t\t\tfix_insert_line($fixlinenr, \"$space$statement;\");\n\t\t\t\t\t\tmy $newline = \"${space}if (\";\n\t\t\t\t\t\t$newline .= '!' if defined($not);\n\t\t\t\t\t\t$newline .= '(' if (defined $not && defined($test) && defined($against));\n\t\t\t\t\t\t$newline .= \"$assigned\";\n\t\t\t\t\t\t$newline .= \" $test $against\" if (defined($test) && defined($against));\n\t\t\t\t\t\t$newline .= ')' if (defined $not && defined($test) && defined($against));\n\t\t\t\t\t\t$newline .= ')';\n\t\t\t\t\t\t$newline .= \" {\" if (defined($brace));\n\t\t\t\t\t\tfix_insert_line($fixlinenr + 1, $newline);\n\t\t\t\t\t\t$fixed_assign_in_if = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# Find out what is on the end of the line after the\n\t\t\t# conditional.\n\t\t\tsubstr($s, 0, length($c), '');\n\t\t\t$s =~ s/\\n.*//g;\n\t\t\t$s =~ s/$;//g;\t# Remove any comments\n\t\t\tif (length($c) && $s !~ /^\\s*{?\\s*\\\\*\\s*$/ &&\n\t\t\t    $c !~ /}\\s*while\\s*/)\n\t\t\t{\n\t\t\t\t# Find out how long the conditional actually is.\n\t\t\t\tmy @newlines = ($c =~ /\\n/gs);\n\t\t\t\tmy $cond_lines = 1 + $#newlines;\n\t\t\t\tmy $stat_real = '';\n\n\t\t\t\t$stat_real = raw_line($linenr, $cond_lines)\n\t\t\t\t\t\t\t. \"\\n\" if ($cond_lines);\n\t\t\t\tif (defined($stat_real) && $cond_lines > 1) {\n\t\t\t\t\t$stat_real = \"[...]\\n$stat_real\";\n\t\t\t\t}\n\n\t\t\t\tif (ERROR(\"TRAILING_STATEMENTS\",\n\t\t\t\t\t  \"trailing statements should be on next line\\n\" . $herecurr . $stat_real) &&\n\t\t\t\t    !$fixed_assign_in_if &&\n\t\t\t\t    $cond_lines == 0 &&\n\t\t\t\t    $fix && $perl_version_ok &&\n\t\t\t\t    $fixed[$fixlinenr] =~ /^\\+(\\s*)((?:if|while|for)\\s*$balanced_parens)\\s*(.*)$/) {\n\t\t\t\t\tmy $indent = $1;\n\t\t\t\t\tmy $test = $2;\n\t\t\t\t\tmy $rest = rtrim($4);\n\t\t\t\t\tif ($rest =~ /;$/) {\n\t\t\t\t\t\t$fixed[$fixlinenr] = \"\\+$indent$test\";\n\t\t\t\t\t\tfix_insert_line($fixlinenr + 1, \"$indent\\t$rest\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check for bitwise tests written as boolean\n\t\tif ($line =~ /\n\t\t\t(?:\n\t\t\t\t(?:\\[|\\(|\\&\\&|\\|\\|)\n\t\t\t\t\\s*0[xX][0-9]+\\s*\n\t\t\t\t(?:\\&\\&|\\|\\|)\n\t\t\t|\n\t\t\t\t(?:\\&\\&|\\|\\|)\n\t\t\t\t\\s*0[xX][0-9]+\\s*\n\t\t\t\t(?:\\&\\&|\\|\\||\\)|\\])\n\t\t\t)/x)\n\t\t{\n\t\t\tWARN(\"HEXADECIMAL_BOOLEAN_TEST\",\n\t\t\t     \"boolean test with hexadecimal, perhaps just 1 \\& or \\|?\\n\" . $herecurr);\n\t\t}\n\n# if and else should not have general statements after it\n\t\tif ($line =~ /^.\\s*(?:}\\s*)?else\\b(.*)/) {\n\t\t\tmy $s = $1;\n\t\t\t$s =~ s/$;//g;\t# Remove any comments\n\t\t\tif ($s !~ /^\\s*(?:\\sif|(?:{|)\\s*\\\\?\\s*$)/) {\n\t\t\t\tERROR(\"TRAILING_STATEMENTS\",\n\t\t\t\t      \"trailing statements should be on next line\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n# if should not continue a brace\n\t\tif ($line =~ /}\\s*if\\b/) {\n\t\t\tERROR(\"TRAILING_STATEMENTS\",\n\t\t\t      \"trailing statements should be on next line (or did you mean 'else if'?)\\n\" .\n\t\t\t\t$herecurr);\n\t\t}\n# case and default should not have general statements after them\n\t\tif ($line =~ /^.\\s*(?:case\\s*.*|default\\s*):/g &&\n\t\t    $line !~ /\\G(?:\n\t\t\t(?:\\s*$;*)(?:\\s*{)?(?:\\s*$;*)(?:\\s*\\\\)?\\s*$|\n\t\t\t\\s*return\\s+\n\t\t    )/xg)\n\t\t{\n\t\t\tERROR(\"TRAILING_STATEMENTS\",\n\t\t\t      \"trailing statements should be on next line\\n\" . $herecurr);\n\t\t}\n\n\t\t# Check for }<nl>else {, these must be at the same\n\t\t# indent level to be relevant to each other.\n\t\tif ($prevline=~/}\\s*$/ and $line=~/^.\\s*else\\s*/ &&\n\t\t    $previndent == $indent) {\n\t\t\tif (ERROR(\"ELSE_AFTER_BRACE\",\n\t\t\t\t  \"else should follow close brace '}'\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevline =~ /^\\+/ && $line =~ /^\\+/) {\n\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\tmy $fixedline = $prevrawline;\n\t\t\t\t$fixedline =~ s/}\\s*$//;\n\t\t\t\tif ($fixedline !~ /^\\+\\s*$/) {\n\t\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t}\n\t\t\t\t$fixedline = $rawline;\n\t\t\t\t$fixedline =~ s/^(.\\s*)else/$1} else/;\n\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t}\n\t\t}\n\n\t\tif ($prevline=~/}\\s*$/ and $line=~/^.\\s*while\\s*/ &&\n\t\t    $previndent == $indent) {\n\t\t\tmy ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);\n\n\t\t\t# Find out what is on the end of the line after the\n\t\t\t# conditional.\n\t\t\tsubstr($s, 0, length($c), '');\n\t\t\t$s =~ s/\\n.*//g;\n\n\t\t\tif ($s =~ /^\\s*;/) {\n\t\t\t\tif (ERROR(\"WHILE_AFTER_BRACE\",\n\t\t\t\t\t  \"while should follow close brace '}'\\n\" . $hereprev) &&\n\t\t\t\t    $fix && $prevline =~ /^\\+/ && $line =~ /^\\+/) {\n\t\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\t\tmy $fixedline = $prevrawline;\n\t\t\t\t\tmy $trailing = $rawline;\n\t\t\t\t\t$trailing =~ s/^\\+//;\n\t\t\t\t\t$trailing = trim($trailing);\n\t\t\t\t\t$fixedline =~ s/}\\s*$/} $trailing/;\n\t\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n#Specific variable tests\n\t\twhile ($line =~ m{($Constant|$Lval)}g) {\n\t\t\tmy $var = $1;\n\n#CamelCase\n\t\t\tif (!$OpenOCD) {\n\t\t\tif ($var !~ /^$Constant$/ &&\n\t\t\t    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&\n#Ignore some autogenerated defines and enum values\n\t\t\t    $var !~ /^(?:[A-Z]+_){1,5}[A-Z]{1,3}[a-z]/ &&\n#Ignore Page<foo> variants\n\t\t\t    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&\n#Ignore SI style variants like nS, mV and dB\n#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)\n\t\t\t    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&\n#Ignore some three character SI units explicitly, like MiB and KHz\n\t\t\t    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {\n\t\t\t}\n\t\t\t} # !$OpenOCD\n\t\t\t# OpenOCD Specific: Begin: remove Linux exceptions, extend to camel[0-9_]*CASE\n\t\t\tif ($var !~ /^$Constant$/ &&\n\t\t\t    $var =~ /[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z]/) {\n\t\t\t# OpenOCD Specific: End\n\t\t\t\twhile ($var =~ m{\\b($Ident)}g) {\n\t\t\t\t\tmy $word = $1;\n\t\t\t\t\tif (!$OpenOCD) {\n\t\t\t\t\tnext if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);\n\t\t\t\t\t} # !$OpenOCD\n\t\t\t\t\t# OpenOCD Specific: Begin: extend to camel[0-9_]*CASE\n\t\t\t\t\tnext if ($word !~ /[A-Z][0-9_]*[a-z]|[a-z][0-9_]*[A-Z]/);\n\t\t\t\t\t# OpenOCD Specific: End\n\t\t\t\t\tif (!$OpenOCD) {\n\t\t\t\t\t# This will not work for OpenOCD jenkins because it runs\n\t\t\t\t\t# checkpatch from a tree already patched. Any new camelcase\n\t\t\t\t\t# in include file will be ignored as it was pre-existing.\n\t\t\t\t\tif ($check) {\n\t\t\t\t\t\tseed_camelcase_includes();\n\t\t\t\t\t\tif (!$file && !$camelcase_file_seeded) {\n\t\t\t\t\t\t\tseed_camelcase_file($realfile);\n\t\t\t\t\t\t\t$camelcase_file_seeded = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t} # !$OpenOCD\n\t\t\t\t\tif (!defined $camelcase{$word}) {\n\t\t\t\t\t\t$camelcase{$word} = 1;\n\t\t\t\t\t\tCHK(\"CAMELCASE\",\n\t\t\t\t\t\t    \"Avoid CamelCase: <$word>\\n\" . $herecurr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n#no spaces allowed after \\ in define\n\t\tif ($line =~ /\\#\\s*define.*\\\\\\s+$/) {\n\t\t\tif (WARN(\"WHITESPACE_AFTER_LINE_CONTINUATION\",\n\t\t\t\t \"Whitespace after \\\\ makes next lines useless\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\s+$//;\n\t\t\t}\n\t\t}\n\n# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes\n# itself <asm/foo.h> (uses RAW line)\n\t\tif ($tree && $rawline =~ m{^.\\s*\\#\\s*include\\s*\\<asm\\/(.*)\\.h\\>}) {\n\t\t\tmy $file = \"$1.h\";\n\t\t\tmy $checkfile = \"include/linux/$file\";\n\t\t\tif (-f \"$root/$checkfile\" &&\n\t\t\t    $realfile ne $checkfile &&\n\t\t\t    $1 !~ /$allowed_asm_includes/)\n\t\t\t{\n\t\t\t\tmy $asminclude = `grep -Ec \"#include\\\\s+<asm/$file>\" $root/$checkfile`;\n\t\t\t\tif ($asminclude > 0) {\n\t\t\t\t\tif ($realfile =~ m{^arch/}) {\n\t\t\t\t\t\tCHK(\"ARCH_INCLUDE_LINUX\",\n\t\t\t\t\t\t    \"Consider using #include <linux/$file> instead of <asm/$file>\\n\" . $herecurr);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tWARN(\"INCLUDE_LINUX\",\n\t\t\t\t\t\t     \"Use #include <linux/$file> instead of <asm/$file>\\n\" . $herecurr);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# multi-statement macros should be enclosed in a do while loop, grab the\n# first statement and ensure its the whole macro if its not enclosed\n# in a known good container\n\t\tif ($realfile !~ m@/vmlinux.lds.h$@ &&\n\t\t    $line =~ /^.\\s*\\#\\s*define\\s*$Ident(\\()?/) {\n\t\t\tmy $ln = $linenr;\n\t\t\tmy $cnt = $realcnt;\n\t\t\tmy ($off, $dstat, $dcond, $rest);\n\t\t\tmy $ctx = '';\n\t\t\tmy $has_flow_statement = 0;\n\t\t\tmy $has_arg_concat = 0;\n\t\t\t($dstat, $dcond, $ln, $cnt, $off) =\n\t\t\t\tctx_statement_block($linenr, $realcnt, 0);\n\t\t\t$ctx = $dstat;\n\t\t\t#print \"dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\\n\";\n\t\t\t#print \"LINE<$lines[$ln-1]> len<\" . length($lines[$ln-1]) . \"\\n\";\n\n\t\t\t$has_flow_statement = 1 if ($ctx =~ /\\b(goto|return)\\b/);\n\t\t\t$has_arg_concat = 1 if ($ctx =~ /\\#\\#/ && $ctx !~ /\\#\\#\\s*(?:__VA_ARGS__|args)\\b/);\n\n\t\t\t$dstat =~ s/^.\\s*\\#\\s*define\\s+$Ident(\\([^\\)]*\\))?\\s*//;\n\t\t\tmy $define_args = $1;\n\t\t\tmy $define_stmt = $dstat;\n\t\t\tmy @def_args = ();\n\n\t\t\tif (defined $define_args && $define_args ne \"\") {\n\t\t\t\t$define_args = substr($define_args, 1, length($define_args) - 2);\n\t\t\t\t$define_args =~ s/\\s*//g;\n\t\t\t\t$define_args =~ s/\\\\\\+?//g;\n\t\t\t\t@def_args = split(\",\", $define_args);\n\t\t\t}\n\n\t\t\t$dstat =~ s/$;//g;\n\t\t\t$dstat =~ s/\\\\\\n.//g;\n\t\t\t$dstat =~ s/^\\s*//s;\n\t\t\t$dstat =~ s/\\s*$//s;\n\n\t\t\t# Flatten any parentheses and braces\n\t\t\twhile ($dstat =~ s/\\([^\\(\\)]*\\)/1u/ ||\n\t\t\t       $dstat =~ s/\\{[^\\{\\}]*\\}/1u/ ||\n\t\t\t       $dstat =~ s/.\\[[^\\[\\]]*\\]/1u/)\n\t\t\t{\n\t\t\t}\n\n\t\t\t# Flatten any obvious string concatenation.\n\t\t\twhile ($dstat =~ s/($String)\\s*$Ident/$1/ ||\n\t\t\t       $dstat =~ s/$Ident\\s*($String)/$1/)\n\t\t\t{\n\t\t\t}\n\n\t\t\t# Make asm volatile uses seem like a generic function\n\t\t\t$dstat =~ s/\\b_*asm_*\\s+_*volatile_*\\b/asm_volatile/g;\n\n\t\t\tmy $exceptions = qr{\n\t\t\t\t$Declare|\n\t\t\t\tmodule_param_named|\n\t\t\t\tMODULE_PARM_DESC|\n\t\t\t\tDECLARE_PER_CPU|\n\t\t\t\tDEFINE_PER_CPU|\n\t\t\t\t__typeof__\\(|\n\t\t\t\tunion|\n\t\t\t\tstruct|\n\t\t\t\t\\.$Ident\\s*=\\s*|\n\t\t\t\t^\\\"|\\\"$|\n\t\t\t\t^\\[\n\t\t\t}x;\n\t\t\t#print \"REST<$rest> dstat<$dstat> ctx<$ctx>\\n\";\n\n\t\t\t$ctx =~ s/\\n*$//;\n\t\t\tmy $stmt_cnt = statement_rawlines($ctx);\n\t\t\tmy $herectx = get_stat_here($linenr, $stmt_cnt, $here);\n\n\t\t\tif ($dstat ne '' &&\n\t\t\t    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&\t\t\t# 10, // foo(),\n\t\t\t    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&\t\t\t# foo();\n\t\t\t    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&\t\t# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz\n\t\t\t    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&\t\t\t# character constants\n\t\t\t    $dstat !~ /$exceptions/ &&\n\t\t\t    $dstat !~ /^\\.$Ident\\s*=/ &&\t\t\t\t# .foo =\n\t\t\t    $dstat !~ /^(?:\\#\\s*$Ident|\\#\\s*$Constant)\\s*$/ &&\t\t# stringification #foo\n\t\t\t    $dstat !~ /^do\\s*$Constant\\s*while\\s*$Constant;?$/ &&\t# do {...} while (...); // do {...} while (...)\n\t\t\t    $dstat !~ /^while\\s*$Constant\\s*$Constant\\s*$/ &&\t\t# while (...) {...}\n\t\t\t    $dstat !~ /^for\\s*$Constant$/ &&\t\t\t\t# for (...)\n\t\t\t    $dstat !~ /^for\\s*$Constant\\s+(?:$Ident|-?$Constant)$/ &&\t# for (...) bar()\n\t\t\t    $dstat !~ /^do\\s*{/ &&\t\t\t\t\t# do {...\n\t\t\t    $dstat !~ /^\\(\\{/ &&\t\t\t\t\t\t# ({...\n\t\t\t    $ctx !~ /^.\\s*#\\s*define\\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\\b/)\n\t\t\t{\n\t\t\t\tif ($dstat =~ /^\\s*if\\b/) {\n\t\t\t\t\tERROR(\"MULTISTATEMENT_MACRO_USE_DO_WHILE\",\n\t\t\t\t\t      \"Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\\n\" . \"$herectx\");\n\t\t\t\t} elsif ($dstat =~ /;/) {\n\t\t\t\t\tERROR(\"MULTISTATEMENT_MACRO_USE_DO_WHILE\",\n\t\t\t\t\t      \"Macros with multiple statements should be enclosed in a do - while loop\\n\" . \"$herectx\");\n\t\t\t\t} else {\n\t\t\t\t\tERROR(\"COMPLEX_MACRO\",\n\t\t\t\t\t      \"Macros with complex values should be enclosed in parentheses\\n\" . \"$herectx\");\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t# Make $define_stmt single line, comment-free, etc\n\t\t\tmy @stmt_array = split('\\n', $define_stmt);\n\t\t\tmy $first = 1;\n\t\t\t$define_stmt = \"\";\n\t\t\tforeach my $l (@stmt_array) {\n\t\t\t\t$l =~ s/\\\\$//;\n\t\t\t\tif ($first) {\n\t\t\t\t\t$define_stmt = $l;\n\t\t\t\t\t$first = 0;\n\t\t\t\t} elsif ($l =~ /^[\\+ ]/) {\n\t\t\t\t\t$define_stmt .= substr($l, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\t$define_stmt =~ s/$;//g;\n\t\t\t$define_stmt =~ s/\\s+/ /g;\n\t\t\t$define_stmt = trim($define_stmt);\n\n# check if any macro arguments are reused (ignore '...' and 'type')\n\t\t\tforeach my $arg (@def_args) {\n\t\t\t        next if ($arg =~ /\\.\\.\\./);\n\t\t\t        next if ($arg =~ /^type$/i);\n\t\t\t\tmy $tmp_stmt = $define_stmt;\n\t\t\t\t$tmp_stmt =~ s/\\b(__must_be_array|offsetof|sizeof|sizeof_field|__stringify|typeof|__typeof__|__builtin\\w+|typecheck\\s*\\(\\s*$Type\\s*,|\\#+)\\s*\\(*\\s*$arg\\s*\\)*\\b//g;\n\t\t\t\t$tmp_stmt =~ s/\\#+\\s*$arg\\b//g;\n\t\t\t\t$tmp_stmt =~ s/\\b$arg\\s*\\#\\#//g;\n\t\t\t\tmy $use_cnt = () = $tmp_stmt =~ /\\b$arg\\b/g;\n\t\t\t\tif ($use_cnt > 1) {\n\t\t\t\t\tCHK(\"MACRO_ARG_REUSE\",\n\t\t\t\t\t    \"Macro argument reuse '$arg' - possible side-effects?\\n\" . \"$herectx\");\n\t\t\t\t    }\n# check if any macro arguments may have other precedence issues\n\t\t\t\tif ($tmp_stmt =~ m/($Operators)?\\s*\\b$arg\\b\\s*($Operators)?/m &&\n\t\t\t\t    ((defined($1) && $1 ne ',') ||\n\t\t\t\t     (defined($2) && $2 ne ','))) {\n\t\t\t\t\tCHK(\"MACRO_ARG_PRECEDENCE\",\n\t\t\t\t\t    \"Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\\n\" . \"$herectx\");\n\t\t\t\t}\n\t\t\t}\n\n# check for macros with flow control, but without ## concatenation\n# ## concatenation is commonly a macro that defines a function so ignore those\n\t\t\tif ($has_flow_statement && !$has_arg_concat) {\n\t\t\t\tmy $cnt = statement_rawlines($ctx);\n\t\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\t\tWARN(\"MACRO_WITH_FLOW_CONTROL\",\n\t\t\t\t     \"Macros with flow control statements should be avoided\\n\" . \"$herectx\");\n\t\t\t}\n\n# check for line continuations outside of #defines, preprocessor #, and asm\n\n\t\t} else {\n\t\t\tif ($prevline !~ /^..*\\\\$/ &&\n\t\t\t    $line !~ /^\\+\\s*\\#.*\\\\$/ &&\t\t# preprocessor\n\t\t\t    $line !~ /^\\+.*\\b(__asm__|asm)\\b.*\\\\$/ &&\t# asm\n\t\t\t    $line =~ /^\\+.*\\\\$/) {\n\t\t\t\tWARN(\"LINE_CONTINUATIONS\",\n\t\t\t\t     \"Avoid unnecessary line continuations\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# do {} while (0) macro tests:\n# single-statement macros do not need to be enclosed in do while (0) loop,\n# macro should not end with a semicolon\n\t\tif ($perl_version_ok &&\n\t\t    $realfile !~ m@/vmlinux.lds.h$@ &&\n\t\t    $line =~ /^.\\s*\\#\\s*define\\s+$Ident(\\()?/) {\n\t\t\tmy $ln = $linenr;\n\t\t\tmy $cnt = $realcnt;\n\t\t\tmy ($off, $dstat, $dcond, $rest);\n\t\t\tmy $ctx = '';\n\t\t\t($dstat, $dcond, $ln, $cnt, $off) =\n\t\t\t\tctx_statement_block($linenr, $realcnt, 0);\n\t\t\t$ctx = $dstat;\n\n\t\t\t$dstat =~ s/\\\\\\n.//g;\n\t\t\t$dstat =~ s/$;/ /g;\n\n\t\t\tif ($dstat =~ /^\\+\\s*#\\s*define\\s+$Ident\\s*${balanced_parens}\\s*do\\s*{(.*)\\s*}\\s*while\\s*\\(\\s*0\\s*\\)\\s*([;\\s]*)\\s*$/) {\n\t\t\t\tmy $stmts = $2;\n\t\t\t\tmy $semis = $3;\n\n\t\t\t\t$ctx =~ s/\\n*$//;\n\t\t\t\tmy $cnt = statement_rawlines($ctx);\n\t\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\t\tif (($stmts =~ tr/;/;/) == 1 &&\n\t\t\t\t    $stmts !~ /^\\s*(if|while|for|switch)\\b/) {\n\t\t\t\t\tWARN(\"SINGLE_STATEMENT_DO_WHILE_MACRO\",\n\t\t\t\t\t     \"Single statement macros should not use a do {} while (0) loop\\n\" . \"$herectx\");\n\t\t\t\t}\n\t\t\t\tif (defined $semis && $semis ne \"\") {\n\t\t\t\t\tWARN(\"DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON\",\n\t\t\t\t\t     \"do {} while (0) macros should not be semicolon terminated\\n\" . \"$herectx\");\n\t\t\t\t}\n\t\t\t} elsif ($dstat =~ /^\\+\\s*#\\s*define\\s+$Ident.*;\\s*$/) {\n\t\t\t\t$ctx =~ s/\\n*$//;\n\t\t\t\tmy $cnt = statement_rawlines($ctx);\n\t\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\t\tWARN(\"TRAILING_SEMICOLON\",\n\t\t\t\t     \"macros should not use a trailing semicolon\\n\" . \"$herectx\");\n\t\t\t}\n\t\t}\n\n# check for redundant bracing round if etc\n\t\tif ($line =~ /(^.*)\\bif\\b/ && $1 !~ /else\\s*$/) {\n\t\t\tmy ($level, $endln, @chunks) =\n\t\t\t\tctx_statement_full($linenr, $realcnt, 1);\n\t\t\t#print \"chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\\n\";\n\t\t\t#print \"APW: <<$chunks[1][0]>><<$chunks[1][1]>>\\n\";\n\t\t\tif ($#chunks > 0 && $level == 0) {\n\t\t\t\tmy @allowed = ();\n\t\t\t\tmy $allow = 0;\n\t\t\t\tmy $seen = 0;\n\t\t\t\tmy $herectx = $here . \"\\n\";\n\t\t\t\tmy $ln = $linenr - 1;\n\t\t\t\tfor my $chunk (@chunks) {\n\t\t\t\t\tmy ($cond, $block) = @{$chunk};\n\n\t\t\t\t\t# If the condition carries leading newlines, then count those as offsets.\n\t\t\t\t\tmy ($whitespace) = ($cond =~ /^((?:\\s*\\n[+-])*\\s*)/s);\n\t\t\t\t\tmy $offset = statement_rawlines($whitespace) - 1;\n\n\t\t\t\t\t$allowed[$allow] = 0;\n\t\t\t\t\t#print \"COND<$cond> whitespace<$whitespace> offset<$offset>\\n\";\n\n\t\t\t\t\t# We have looked at and allowed this specific line.\n\t\t\t\t\t$suppress_ifbraces{$ln + $offset} = 1;\n\n\t\t\t\t\t$herectx .= \"$rawlines[$ln + $offset]\\n[...]\\n\";\n\t\t\t\t\t$ln += statement_rawlines($block) - 1;\n\n\t\t\t\t\tsubstr($block, 0, length($cond), '');\n\n\t\t\t\t\t$seen++ if ($block =~ /^\\s*{/);\n\n\t\t\t\t\t#print \"cond<$cond> block<$block> allowed<$allowed[$allow]>\\n\";\n\t\t\t\t\tif (statement_lines($cond) > 1) {\n\t\t\t\t\t\t#print \"APW: ALLOWED: cond<$cond>\\n\";\n\t\t\t\t\t\t$allowed[$allow] = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif ($block =~/\\b(?:if|for|while)\\b/) {\n\t\t\t\t\t\t#print \"APW: ALLOWED: block<$block>\\n\";\n\t\t\t\t\t\t$allowed[$allow] = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (statement_block_size($block) > 1) {\n\t\t\t\t\t\t#print \"APW: ALLOWED: lines block<$block>\\n\";\n\t\t\t\t\t\t$allowed[$allow] = 1;\n\t\t\t\t\t}\n\t\t\t\t\t$allow++;\n\t\t\t\t}\n\t\t\t\tif ($seen) {\n\t\t\t\t\tmy $sum_allowed = 0;\n\t\t\t\t\tforeach (@allowed) {\n\t\t\t\t\t\t$sum_allowed += $_;\n\t\t\t\t\t}\n\t\t\t\t\tif ($sum_allowed == 0) {\n\t\t\t\t\t\tWARN(\"BRACES\",\n\t\t\t\t\t\t     \"braces {} are not necessary for any arm of this statement\\n\" . $herectx);\n\t\t\t\t\t} elsif ($sum_allowed != $allow &&\n\t\t\t\t\t\t $seen != $allow) {\n\t\t\t\t\t\tCHK(\"BRACES\",\n\t\t\t\t\t\t    \"braces {} should be used on all arms of this statement\\n\" . $herectx);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!defined $suppress_ifbraces{$linenr - 1} &&\n\t\t\t\t\t$line =~ /\\b(if|while|for|else)\\b/) {\n\t\t\tmy $allowed = 0;\n\n\t\t\t# Check the pre-context.\n\t\t\tif (substr($line, 0, $-[0]) =~ /(\\}\\s*)$/) {\n\t\t\t\t#print \"APW: ALLOWED: pre<$1>\\n\";\n\t\t\t\t$allowed = 1;\n\t\t\t}\n\n\t\t\tmy ($level, $endln, @chunks) =\n\t\t\t\tctx_statement_full($linenr, $realcnt, $-[0]);\n\n\t\t\t# Check the condition.\n\t\t\tmy ($cond, $block) = @{$chunks[0]};\n\t\t\t#print \"CHECKING<$linenr> cond<$cond> block<$block>\\n\";\n\t\t\tif (defined $cond) {\n\t\t\t\tsubstr($block, 0, length($cond), '');\n\t\t\t}\n\t\t\tif (statement_lines($cond) > 1) {\n\t\t\t\t#print \"APW: ALLOWED: cond<$cond>\\n\";\n\t\t\t\t$allowed = 1;\n\t\t\t}\n\t\t\tif ($block =~/\\b(?:if|for|while)\\b/) {\n\t\t\t\t#print \"APW: ALLOWED: block<$block>\\n\";\n\t\t\t\t$allowed = 1;\n\t\t\t}\n\t\t\tif (statement_block_size($block) > 1) {\n\t\t\t\t#print \"APW: ALLOWED: lines block<$block>\\n\";\n\t\t\t\t$allowed = 1;\n\t\t\t}\n\t\t\t# Check the post-context.\n\t\t\tif (defined $chunks[1]) {\n\t\t\t\tmy ($cond, $block) = @{$chunks[1]};\n\t\t\t\tif (defined $cond) {\n\t\t\t\t\tsubstr($block, 0, length($cond), '');\n\t\t\t\t}\n\t\t\t\tif ($block =~ /^\\s*\\{/) {\n\t\t\t\t\t#print \"APW: ALLOWED: chunk-1 block<$block>\\n\";\n\t\t\t\t\t$allowed = 1;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($level == 0 && $block =~ /^\\s*\\{/ && !$allowed) {\n\t\t\t\tmy $cnt = statement_rawlines($block);\n\t\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\t\tWARN(\"BRACES\",\n\t\t\t\t     \"braces {} are not necessary for single statement blocks\\n\" . $herectx);\n\t\t\t}\n\t\t}\n\n# check for single line unbalanced braces\n\t\tif ($sline =~ /^.\\s*\\}\\s*else\\s*$/ ||\n\t\t    $sline =~ /^.\\s*else\\s*\\{\\s*$/) {\n\t\t\tCHK(\"BRACES\", \"Unbalanced braces around else statement\\n\" . $herecurr);\n\t\t}\n\n# check for unnecessary blank lines around braces\n\t\tif (($line =~ /^.\\s*}\\s*$/ && $prevrawline =~ /^.\\s*$/)) {\n\t\t\tif (CHK(\"BRACES\",\n\t\t\t\t\"Blank lines aren't necessary before a close brace '}'\\n\" . $hereprev) &&\n\t\t\t    $fix && $prevrawline =~ /^\\+/) {\n\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t}\n\t\t}\n\t\tif (($rawline =~ /^.\\s*$/ && $prevline =~ /^..*{\\s*$/)) {\n\t\t\tif (CHK(\"BRACES\",\n\t\t\t\t\"Blank lines aren't necessary after an open brace '{'\\n\" . $hereprev) &&\n\t\t\t    $fix) {\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t}\n\t\t}\n\n# no volatiles please\n\t\tmy $asm_volatile = qr{\\b(__asm__|asm)\\s+(__volatile__|volatile)\\b};\n\t\tif ($line =~ /\\bvolatile\\b/ && $line !~ /$asm_volatile/) {\n\t\t\tWARN(\"VOLATILE\",\n\t\t\t     \"Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\\n\" . $herecurr);\n\t\t}\n\n# Check for user-visible strings broken across lines, which breaks the ability\n# to grep for the string.  Make exceptions when the previous string ends in a\n# newline (multiple lines in one string constant) or '\\t', '\\r', ';', or '{'\n# (common in inline assembly) or is a octal \\123 or hexadecimal \\xaf value\n\t\tif ($line =~ /^\\+\\s*$String/ &&\n\t\t    $prevline =~ /\"\\s*$/ &&\n\t\t    $prevrawline !~ /(?:\\\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\\s*|\\{\\s*)\"\\s*$/) {\n\t\t\tif (WARN(\"SPLIT_STRING\",\n\t\t\t\t \"quoted string split across lines\\n\" . $hereprev) &&\n\t\t\t\t     $fix &&\n\t\t\t\t     $prevrawline =~ /^\\+.*\"\\s*$/ &&\n\t\t\t\t     $last_coalesced_string_linenr != $linenr - 1) {\n\t\t\t\tmy $extracted_string = get_quoted_string($line, $rawline);\n\t\t\t\tmy $comma_close = \"\";\n\t\t\t\tif ($rawline =~ /\\Q$extracted_string\\E(\\s*\\)\\s*;\\s*$|\\s*,\\s*)/) {\n\t\t\t\t\t$comma_close = $1;\n\t\t\t\t}\n\n\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\tfix_delete_line($fixlinenr, $rawline);\n\t\t\t\tmy $fixedline = $prevrawline;\n\t\t\t\t$fixedline =~ s/\"\\s*$//;\n\t\t\t\t$fixedline .= substr($extracted_string, 1) . trim($comma_close);\n\t\t\t\tfix_insert_line($fixlinenr - 1, $fixedline);\n\t\t\t\t$fixedline = $rawline;\n\t\t\t\t$fixedline =~ s/\\Q$extracted_string\\E\\Q$comma_close\\E//;\n\t\t\t\tif ($fixedline !~ /\\+\\s*$/) {\n\t\t\t\t\tfix_insert_line($fixlinenr, $fixedline);\n\t\t\t\t}\n\t\t\t\t$last_coalesced_string_linenr = $linenr;\n\t\t\t}\n\t\t}\n\n# check for missing a space in a string concatenation\n\t\tif ($prevrawline =~ /[^\\\\]\\w\"$/ && $rawline =~ /^\\+[\\t ]+\"\\w/) {\n\t\t\tWARN('MISSING_SPACE',\n\t\t\t     \"break quoted strings at a space character\\n\" . $hereprev);\n\t\t}\n\n# check for an embedded function name in a string when the function is known\n# This does not work very well for -f --file checking as it depends on patch\n# context providing the function name or a single line form for in-file\n# function declarations\n\t\tif ($line =~ /^\\+.*$String/ &&\n\t\t    defined($context_function) &&\n\t\t    get_quoted_string($line, $rawline) =~ /\\b$context_function\\b/ &&\n\t\t    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {\n\t\t\tWARN(\"EMBEDDED_FUNCTION_NAME\",\n\t\t\t     \"Prefer using '\\\"%s...\\\", __func__' to using '$context_function', this function's name, in a string\\n\" . $herecurr);\n\t\t}\n\n# check for unnecessary function tracing like uses\n# This does not use $logFunctions because there are many instances like\n# 'dprintk(FOO, \"%s()\\n\", __func__);' which do not match $logFunctions\n\t\tif ($rawline =~ /^\\+.*\\([^\"]*\"$tracing_logging_tags{0,3}%s(?:\\s*\\(\\s*\\)\\s*)?$tracing_logging_tags{0,3}(?:\\\\n)?\"\\s*,\\s*__func__\\s*\\)\\s*;/) {\n\t\t\tif (WARN(\"TRACING_LOGGING\",\n\t\t\t\t \"Unnecessary ftrace-like logging - prefer using ftrace\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n                                fix_delete_line($fixlinenr, $rawline);\n\t\t\t}\n\t\t}\n\n# check for spaces before a quoted newline\n\t\tif ($rawline =~ /^.*\\\".*\\s\\\\n/) {\n\t\t\tif (WARN(\"QUOTED_WHITESPACE_BEFORE_NEWLINE\",\n\t\t\t\t \"unnecessary whitespace before a quoted newline\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/^(\\+.*\\\".*)\\s+\\\\n/$1\\\\n/;\n\t\t\t}\n\n\t\t}\n\n# concatenated string without spaces between elements\n\t\tif ($line =~ /$String[A-Z_]/ ||\n\t\t    ($line =~ /([A-Za-z0-9_]+)$String/ && $1 !~ /^[Lu]$/)) {\n\t\t\tif (CHK(\"CONCATENATED_STRING\",\n\t\t\t\t\"Concatenated strings should use spaces between elements\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\twhile ($line =~ /($String)/g) {\n\t\t\t\t\tmy $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$extracted_string\\E([A-Za-z0-9_])/$extracted_string $1/;\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\\Q$extracted_string\\E/$1 $extracted_string/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# uncoalesced string fragments\n\t\tif ($line =~ /$String\\s*[Lu]?\"/) {\n\t\t\tif (WARN(\"STRING_FRAGMENTS\",\n\t\t\t\t \"Consecutive strings are generally better as a single string\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\twhile ($line =~ /($String)(?=\\s*\")/g) {\n\t\t\t\t\tmy $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$extracted_string\\E\\s*\"/substr($extracted_string, 0, -1)/e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for non-standard and hex prefixed decimal printf formats\n\t\tmy $show_L = 1;\t#don't show the same defect twice\n\t\tmy $show_Z = 1;\n\t\twhile ($line =~ /(?:^|\")([X\\t]*)(?:\"|$)/g) {\n\t\t\tmy $string = substr($rawline, $-[1], $+[1] - $-[1]);\n\t\t\t$string =~ s/%%/__/g;\n\t\t\t# check for %L\n\t\t\tif ($show_L && $string =~ /%[\\*\\d\\.\\$]*L([diouxX])/) {\n\t\t\t\tWARN(\"PRINTF_L\",\n\t\t\t\t     \"\\%L$1 is non-standard C, use %ll$1\\n\" . $herecurr);\n\t\t\t\t$show_L = 0;\n\t\t\t}\n\t\t\t# check for %Z\n\t\t\tif ($show_Z && $string =~ /%[\\*\\d\\.\\$]*Z([diouxX])/) {\n\t\t\t\tWARN(\"PRINTF_Z\",\n\t\t\t\t     \"%Z$1 is non-standard C, use %z$1\\n\" . $herecurr);\n\t\t\t\t$show_Z = 0;\n\t\t\t}\n\t\t\t# check for 0x<decimal>\n\t\t\tif ($string =~ /0x%[\\*\\d\\.\\$\\Llzth]*[diou]/) {\n\t\t\t\tERROR(\"PRINTF_0XDECIMAL\",\n\t\t\t\t      \"Prefixing 0x with decimal output is defective\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for line continuations in quoted strings with odd counts of \"\n\t\tif ($rawline =~ /\\\\$/ && $sline =~ tr/\"/\"/ % 2) {\n\t\t\tWARN(\"LINE_CONTINUATIONS\",\n\t\t\t     \"Avoid line continuations in quoted strings\\n\" . $herecurr);\n\t\t}\n\n# warn about #if 0\n\t\tif ($line =~ /^.\\s*\\#\\s*if\\s+0\\b/) {\n\t\t\tWARN(\"IF_0\",\n\t\t\t     \"Consider removing the code enclosed by this #if 0 and its #endif\\n\" . $herecurr);\n\t\t}\n\n# warn about #if 1\n\t\tif ($line =~ /^.\\s*\\#\\s*if\\s+1\\b/) {\n\t\t\tWARN(\"IF_1\",\n\t\t\t     \"Consider removing the #if 1 and its #endif\\n\" . $herecurr);\n\t\t}\n\n# check for needless \"if (<foo>) fn(<foo>)\" uses\n\t\tif ($prevline =~ /\\bif\\s*\\(\\s*($Lval)\\s*\\)/) {\n\t\t\tmy $tested = quotemeta($1);\n\t\t\tmy $expr = '\\s*\\(\\s*' . $tested . '\\s*\\)\\s*;';\n\t\t\tif ($line =~ /\\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {\n\t\t\t\tmy $func = $1;\n\t\t\t\tif (WARN('NEEDLESS_IF',\n\t\t\t\t\t \"$func(NULL) is safe and this check is probably not required\\n\" . $hereprev) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\tmy $do_fix = 1;\n\t\t\t\t\tmy $leading_tabs = \"\";\n\t\t\t\t\tmy $new_leading_tabs = \"\";\n\t\t\t\t\tif ($lines[$linenr - 2] =~ /^\\+(\\t*)if\\s*\\(\\s*$tested\\s*\\)\\s*$/) {\n\t\t\t\t\t\t$leading_tabs = $1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$do_fix = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif ($lines[$linenr - 1] =~ /^\\+(\\t+)$func\\s*\\(\\s*$tested\\s*\\)\\s*;\\s*$/) {\n\t\t\t\t\t\t$new_leading_tabs = $1;\n\t\t\t\t\t\tif (length($leading_tabs) + 1 ne length($new_leading_tabs)) {\n\t\t\t\t\t\t\t$do_fix = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$do_fix = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif ($do_fix) {\n\t\t\t\t\t\tfix_delete_line($fixlinenr - 1, $prevrawline);\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/^\\+$new_leading_tabs/\\+$leading_tabs/;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for unnecessary \"Out of Memory\" messages\n\t\tif ($line =~ /^\\+.*\\b$logFunctions\\s*\\(/ &&\n\t\t    $prevline =~ /^[ \\+]\\s*if\\s*\\(\\s*(\\!\\s*|NULL\\s*==\\s*)?($Lval)(\\s*==\\s*NULL\\s*)?\\s*\\)/ &&\n\t\t    (defined $1 || defined $3) &&\n\t\t    $linenr > 3) {\n\t\t\tmy $testval = $2;\n\t\t\tmy $testline = $lines[$linenr - 3];\n\n\t\t\tmy ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);\n#\t\t\tprint(\"line: <$line>\\nprevline: <$prevline>\\ns: <$s>\\nc: <$c>\\n\\n\\n\");\n\n\t\t\tif ($s =~ /(?:^|\\n)[ \\+]\\s*(?:$Type\\s*)?\\Q$testval\\E\\s*=\\s*(?:\\([^\\)]*\\)\\s*)?\\s*$allocFunctions\\s*\\(/ &&\n\t\t\t    $s !~ /\\b__GFP_NOWARN\\b/ ) {\n\t\t\t\tWARN(\"OOM_MESSAGE\",\n\t\t\t\t     \"Possible unnecessary 'out of memory' message\\n\" . $hereprev);\n\t\t\t}\n\t\t}\n\n# check for logging functions with KERN_<LEVEL>\n\t\tif ($line !~ /printk(?:_ratelimited|_once)?\\s*\\(/ &&\n\t\t    $line =~ /\\b$logFunctions\\s*\\(.*\\b(KERN_[A-Z]+)\\b/) {\n\t\t\tmy $level = $1;\n\t\t\tif (WARN(\"UNNECESSARY_KERN_LEVEL\",\n\t\t\t\t \"Possible unnecessary $level\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\s*$level\\s*//;\n\t\t\t}\n\t\t}\n\n# check for logging continuations\n\t\tif ($line =~ /\\bprintk\\s*\\(\\s*KERN_CONT\\b|\\bpr_cont\\s*\\(/) {\n\t\t\tWARN(\"LOGGING_CONTINUATION\",\n\t\t\t     \"Avoid logging continuation uses where feasible\\n\" . $herecurr);\n\t\t}\n\n# check for unnecessary use of %h[xudi] and %hh[xudi] in logging functions\n\t\tif (defined $stat &&\n\t\t    $line =~ /\\b$logFunctions\\s*\\(/ &&\n\t\t    index($stat, '\"') >= 0) {\n\t\t\tmy $lc = $stat =~ tr@\\n@@;\n\t\t\t$lc = $lc + $linenr;\n\t\t\tmy $stat_real = get_stat_real($linenr, $lc);\n\t\t\tpos($stat_real) = index($stat_real, '\"');\n\t\t\twhile ($stat_real =~ /[^\\\"%]*(%[\\#\\d\\.\\*\\-]*(h+)[idux])/g) {\n\t\t\t\tmy $pspec = $1;\n\t\t\t\tmy $h = $2;\n\t\t\t\tmy $lineoff = substr($stat_real, 0, $-[1]) =~ tr@\\n@@;\n\t\t\t\tif (WARN(\"UNNECESSARY_MODIFIER\",\n\t\t\t\t\t \"Integer promotion: Using '$h' in '$pspec' is unnecessary\\n\" . \"$here\\n$stat_real\\n\") &&\n\t\t\t\t    $fix && $fixed[$fixlinenr + $lineoff] =~ /^\\+/) {\n\t\t\t\t\tmy $nspec = $pspec;\n\t\t\t\t\t$nspec =~ s/h//g;\n\t\t\t\t\t$fixed[$fixlinenr + $lineoff] =~ s/\\Q$pspec\\E/$nspec/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for mask then right shift without a parentheses\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /$LvalOrFunc\\s*\\&\\s*($LvalOrFunc)\\s*>>/ &&\n\t\t    $4 !~ /^\\&/) { # $LvalOrFunc may be &foo, ignore if so\n\t\t\tWARN(\"MASK_THEN_SHIFT\",\n\t\t\t     \"Possible precedence defect with mask then right shift - may need parentheses\\n\" . $herecurr);\n\t\t}\n\n# check for pointer comparisons to NULL\n\t\tif ($perl_version_ok) {\n\t\t\twhile ($line =~ /\\b$LvalOrFunc\\s*(==|\\!=)\\s*NULL\\b/g) {\n\t\t\t\tmy $val = $1;\n\t\t\t\tmy $equal = \"!\";\n\t\t\t\t$equal = \"\" if ($4 eq \"!=\");\n\t\t\t\tif (CHK(\"COMPARISON_TO_NULL\",\n\t\t\t\t\t\"Comparison to NULL could be written \\\"${equal}${val}\\\"\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\b\\Q$val\\E\\s*(?:==|\\!=)\\s*NULL\\b/$equal$val/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for bad placement of section $InitAttribute (e.g.: __initdata)\n\t\tif ($line =~ /(\\b$InitAttribute\\b)/) {\n\t\t\tmy $attr = $1;\n\t\t\tif ($line =~ /^\\+\\s*static\\s+(?:const\\s+)?(?:$attr\\s+)?($NonptrTypeWithAttr)\\s+(?:$attr\\s+)?($Ident(?:\\[[^]]*\\])?)\\s*[=;]/) {\n\t\t\t\tmy $ptr = $1;\n\t\t\t\tmy $var = $2;\n\t\t\t\tif ((($ptr =~ /\\b(union|struct)\\s+$attr\\b/ &&\n\t\t\t\t      ERROR(\"MISPLACED_INIT\",\n\t\t\t\t\t    \"$attr should be placed after $var\\n\" . $herecurr)) ||\n\t\t\t\t     ($ptr !~ /\\b(union|struct)\\s+$attr\\b/ &&\n\t\t\t\t      WARN(\"MISPLACED_INIT\",\n\t\t\t\t\t   \"$attr should be placed after $var\\n\" . $herecurr))) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/(\\bstatic\\s+(?:const\\s+)?)(?:$attr\\s+)?($NonptrTypeWithAttr)\\s+(?:$attr\\s+)?($Ident(?:\\[[^]]*\\])?)\\s*([=;])\\s*/\"$1\" . trim(string_find_replace($2, \"\\\\s*$attr\\\\s*\", \" \")) . \" \" . trim(string_find_replace($3, \"\\\\s*$attr\\\\s*\", \"\")) . \" $attr\" . (\"$4\" eq \";\" ? \";\" : \" = \")/e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for $InitAttributeData (ie: __initdata) with const\n\t\tif ($line =~ /\\bconst\\b/ && $line =~ /($InitAttributeData)/) {\n\t\t\tmy $attr = $1;\n\t\t\t$attr =~ /($InitAttributePrefix)(.*)/;\n\t\t\tmy $attr_prefix = $1;\n\t\t\tmy $attr_type = $2;\n\t\t\tif (ERROR(\"INIT_ATTRIBUTE\",\n\t\t\t\t  \"Use of const init definition must use ${attr_prefix}initconst\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/$InitAttributeData/${attr_prefix}initconst/;\n\t\t\t}\n\t\t}\n\n# check for $InitAttributeConst (ie: __initconst) without const\n\t\tif ($line !~ /\\bconst\\b/ && $line =~ /($InitAttributeConst)/) {\n\t\t\tmy $attr = $1;\n\t\t\tif (ERROR(\"INIT_ATTRIBUTE\",\n\t\t\t\t  \"Use of $attr requires a separate use of const\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tmy $lead = $fixed[$fixlinenr] =~\n\t\t\t\t    /(^\\+\\s*(?:static\\s+))/;\n\t\t\t\t$lead = rtrim($1);\n\t\t\t\t$lead = \"$lead \" if ($lead !~ /^\\+$/);\n\t\t\t\t$lead = \"${lead}const \";\n\t\t\t\t$fixed[$fixlinenr] =~ s/(^\\+\\s*(?:static\\s+))/$lead/;\n\t\t\t}\n\t\t}\n\n# check for __read_mostly with const non-pointer (should just be const)\n\t\tif ($line =~ /\\b__read_mostly\\b/ &&\n\t\t    $line =~ /($Type)\\s*$Ident/ && $1 !~ /\\*\\s*$/ && $1 =~ /\\bconst\\b/) {\n\t\t\tif (ERROR(\"CONST_READ_MOSTLY\",\n\t\t\t\t  \"Invalid use of __read_mostly with const type\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\s+__read_mostly\\b//;\n\t\t\t}\n\t\t}\n\n# don't use __constant_<foo> functions outside of include/uapi/\n\t\tif ($realfile !~ m@^include/uapi/@ &&\n\t\t    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\\s*\\(/) {\n\t\t\tmy $constant_func = $1;\n\t\t\tmy $func = $constant_func;\n\t\t\t$func =~ s/^__constant_//;\n\t\t\tif (WARN(\"CONSTANT_CONVERSION\",\n\t\t\t\t \"$constant_func should be $func\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\b$constant_func\\b/$func/g;\n\t\t\t}\n\t\t}\n\n# prefer usleep_range over udelay\n\t\tif ($line =~ /\\budelay\\s*\\(\\s*(\\d+)\\s*\\)/) {\n\t\t\tmy $delay = $1;\n\t\t\t# ignore udelay's < 10, however\n\t\t\tif (! ($delay < 10) ) {\n\t\t\t\tCHK(\"USLEEP_RANGE\",\n\t\t\t\t    \"usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\\n\" . $herecurr);\n\t\t\t}\n\t\t\tif ($delay > 2000) {\n\t\t\t\tWARN(\"LONG_UDELAY\",\n\t\t\t\t     \"long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# warn about unexpectedly long msleep's\n\t\tif ($line =~ /\\bmsleep\\s*\\((\\d+)\\);/) {\n\t\t\tif ($1 < 20) {\n\t\t\t\tWARN(\"MSLEEP\",\n\t\t\t\t     \"msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for comparisons of jiffies\n\t\tif ($line =~ /\\bjiffies\\s*$Compare|$Compare\\s*jiffies\\b/) {\n\t\t\tWARN(\"JIFFIES_COMPARISON\",\n\t\t\t     \"Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\\n\" . $herecurr);\n\t\t}\n\n# check for comparisons of get_jiffies_64()\n\t\tif ($line =~ /\\bget_jiffies_64\\s*\\(\\s*\\)\\s*$Compare|$Compare\\s*get_jiffies_64\\s*\\(\\s*\\)/) {\n\t\t\tWARN(\"JIFFIES_COMPARISON\",\n\t\t\t     \"Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\\n\" . $herecurr);\n\t\t}\n\n# warn about #ifdefs in C files\n#\t\tif ($line =~ /^.\\s*\\#\\s*if(|n)def/ && ($realfile =~ /\\.c$/)) {\n#\t\t\tprint \"#ifdef in C files should be avoided\\n\";\n#\t\t\tprint \"$herecurr\";\n#\t\t\t$clean = 0;\n#\t\t}\n\n# warn about spacing in #ifdefs\n\t\tif ($line =~ /^.\\s*\\#\\s*(ifdef|ifndef|elif)\\s\\s+/) {\n\t\t\tif (ERROR(\"SPACING\",\n\t\t\t\t  \"exactly one space required after that #$1\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~\n\t\t\t\t    s/^(.\\s*\\#\\s*(ifdef|ifndef|elif))\\s{2,}/$1 /;\n\t\t\t}\n\n\t\t}\n\n# check for spinlock_t definitions without a comment.\n\t\tif ($line =~ /^.\\s*(struct\\s+mutex|spinlock_t)\\s+\\S+;/ ||\n\t\t    $line =~ /^.\\s*(DEFINE_MUTEX)\\s*\\(/) {\n\t\t\tmy $which = $1;\n\t\t\tif (!ctx_has_comment($first_line, $linenr)) {\n\t\t\t\tCHK(\"UNCOMMENTED_DEFINITION\",\n\t\t\t\t    \"$1 definition without comment\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n# check for memory barriers without a comment.\n\n\t\tmy $barriers = qr{\n\t\t\tmb|\n\t\t\trmb|\n\t\t\twmb\n\t\t}x;\n\t\tmy $barrier_stems = qr{\n\t\t\tmb__before_atomic|\n\t\t\tmb__after_atomic|\n\t\t\tstore_release|\n\t\t\tload_acquire|\n\t\t\tstore_mb|\n\t\t\t(?:$barriers)\n\t\t}x;\n\t\tmy $all_barriers = qr{\n\t\t\t(?:$barriers)|\n\t\t\tsmp_(?:$barrier_stems)|\n\t\t\tvirt_(?:$barrier_stems)\n\t\t}x;\n\n\t\tif ($line =~ /\\b(?:$all_barriers)\\s*\\(/) {\n\t\t\tif (!ctx_has_comment($first_line, $linenr)) {\n\t\t\t\tWARN(\"MEMORY_BARRIER\",\n\t\t\t\t     \"memory barrier without comment\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n\t\tmy $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;\n\n\t\tif ($realfile !~ m@^include/asm-generic/@ &&\n\t\t    $realfile !~ m@/barrier\\.h$@ &&\n\t\t    $line =~ m/\\b(?:$underscore_smp_barriers)\\s*\\(/ &&\n\t\t    $line !~ m/^.\\s*\\#\\s*define\\s+(?:$underscore_smp_barriers)\\s*\\(/) {\n\t\t\tWARN(\"MEMORY_BARRIER\",\n\t\t\t     \"__smp memory barriers shouldn't be used outside barrier.h and asm-generic\\n\" . $herecurr);\n\t\t}\n\n# check for waitqueue_active without a comment.\n\t\tif ($line =~ /\\bwaitqueue_active\\s*\\(/) {\n\t\t\tif (!ctx_has_comment($first_line, $linenr)) {\n\t\t\t\tWARN(\"WAITQUEUE_ACTIVE\",\n\t\t\t\t     \"waitqueue_active without comment\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for data_race without a comment.\n\t\tif ($line =~ /\\bdata_race\\s*\\(/) {\n\t\t\tif (!ctx_has_comment($first_line, $linenr)) {\n\t\t\t\tWARN(\"DATA_RACE\",\n\t\t\t\t     \"data_race without comment\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check of hardware specific defines\n\t\tif ($line =~ m@^.\\s*\\#\\s*if.*\\b(__i386__|__powerpc64__|__sun__|__s390x__)\\b@ && $realfile !~ m@include/asm-@) {\n\t\t\tCHK(\"ARCH_DEFINES\",\n\t\t\t    \"architecture specific defines should be avoided\\n\" .  $herecurr);\n\t\t}\n\n# check that the storage class is not after a type\n\t\tif ($line =~ /\\b($Type)\\s+($Storage)\\b/) {\n\t\t\tWARN(\"STORAGE_CLASS\",\n\t\t\t     \"storage class '$2' should be located before type '$1'\\n\" . $herecurr);\n\t\t}\n# Check that the storage class is at the beginning of a declaration\n\t\tif ($line =~ /\\b$Storage\\b/ &&\n\t\t    $line !~ /^.\\s*$Storage/ &&\n\t\t    $line =~ /^.\\s*(.+?)\\$Storage\\s/ &&\n\t\t    $1 !~ /[\\,\\)]\\s*$/) {\n\t\t\tWARN(\"STORAGE_CLASS\",\n\t\t\t     \"storage class should be at the beginning of the declaration\\n\" . $herecurr);\n\t\t}\n\n# check the location of the inline attribute, that it is between\n# storage class and type.\n\t\tif ($line =~ /\\b$Type\\s+$Inline\\b/ ||\n\t\t    $line =~ /\\b$Inline\\s+$Storage\\b/) {\n\t\t\tERROR(\"INLINE_LOCATION\",\n\t\t\t      \"inline keyword should sit between storage class and type\\n\" . $herecurr);\n\t\t}\n\n# Check for __inline__ and __inline, prefer inline\n\t\tif ($realfile !~ m@\\binclude/uapi/@ &&\n\t\t    $line =~ /\\b(__inline__|__inline)\\b/) {\n\t\t\tif (WARN(\"INLINE\",\n\t\t\t\t \"plain inline is preferred over $1\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\b(__inline__|__inline)\\b/inline/;\n\n\t\t\t}\n\t\t}\n\n# Check for compiler attributes\n\t\tif ($realfile !~ m@\\binclude/uapi/@ &&\n\t\t    $rawline =~ /\\b__attribute__\\s*\\(\\s*($balanced_parens)\\s*\\)/) {\n\t\t\tmy $attr = $1;\n\t\t\t$attr =~ s/\\s*\\(\\s*(.*)\\)\\s*/$1/;\n\n\t\t\tmy %attr_list = (\n\t\t\t\t\"alias\"\t\t\t\t=> \"__alias\",\n\t\t\t\t\"aligned\"\t\t\t=> \"__aligned\",\n\t\t\t\t\"always_inline\"\t\t\t=> \"__always_inline\",\n\t\t\t\t\"assume_aligned\"\t\t=> \"__assume_aligned\",\n\t\t\t\t\"cold\"\t\t\t\t=> \"__cold\",\n\t\t\t\t\"const\"\t\t\t\t=> \"__attribute_const__\",\n\t\t\t\t\"copy\"\t\t\t\t=> \"__copy\",\n\t\t\t\t\"designated_init\"\t\t=> \"__designated_init\",\n\t\t\t\t\"externally_visible\"\t\t=> \"__visible\",\n\t\t\t\t\"format\"\t\t\t=> \"printf|scanf\",\n\t\t\t\t\"gnu_inline\"\t\t\t=> \"__gnu_inline\",\n\t\t\t\t\"malloc\"\t\t\t=> \"__malloc\",\n\t\t\t\t\"mode\"\t\t\t\t=> \"__mode\",\n\t\t\t\t\"no_caller_saved_registers\"\t=> \"__no_caller_saved_registers\",\n\t\t\t\t\"noclone\"\t\t\t=> \"__noclone\",\n\t\t\t\t\"noinline\"\t\t\t=> \"noinline\",\n\t\t\t\t\"nonstring\"\t\t\t=> \"__nonstring\",\n\t\t\t\t\"noreturn\"\t\t\t=> \"__noreturn\",\n\t\t\t\t\"packed\"\t\t\t=> \"__packed\",\n\t\t\t\t\"pure\"\t\t\t\t=> \"__pure\",\n\t\t\t\t\"section\"\t\t\t=> \"__section\",\n\t\t\t\t\"used\"\t\t\t\t=> \"__used\",\n\t\t\t\t\"weak\"\t\t\t\t=> \"__weak\"\n\t\t\t);\n\n\t\t\twhile ($attr =~ /\\s*(\\w+)\\s*(${balanced_parens})?/g) {\n\t\t\t\tmy $orig_attr = $1;\n\t\t\t\tmy $params = '';\n\t\t\t\t$params = $2 if defined($2);\n\t\t\t\tmy $curr_attr = $orig_attr;\n\t\t\t\t$curr_attr =~ s/^[\\s_]+|[\\s_]+$//g;\n\t\t\t\tif (exists($attr_list{$curr_attr})) {\n\t\t\t\t\tmy $new = $attr_list{$curr_attr};\n\t\t\t\t\tif ($curr_attr eq \"format\" && $params) {\n\t\t\t\t\t\t$params =~ /^\\s*\\(\\s*(\\w+)\\s*,\\s*(.*)/;\n\t\t\t\t\t\t$new = \"__$1\\($2\";\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$new = \"$new$params\";\n\t\t\t\t\t}\n\t\t\t\t\tif (WARN(\"PREFER_DEFINED_ATTRIBUTE_MACRO\",\n\t\t\t\t\t\t \"Prefer $new over __attribute__(($orig_attr$params))\\n\" . $herecurr) &&\n\t\t\t\t\t    $fix) {\n\t\t\t\t\t\tmy $remove = \"\\Q$orig_attr\\E\" . '\\s*' . \"\\Q$params\\E\" . '(?:\\s*,\\s*)?';\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/$remove//;\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\b__attribute__/$new __attribute__/;\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\}\\Q$new\\E/} $new/;\n\t\t\t\t\t\t$fixed[$fixlinenr] =~ s/ __attribute__\\s*\\(\\s*\\(\\s*\\)\\s*\\)//;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t# Check for __attribute__ unused, prefer __always_unused or __maybe_unused\n\t\t\tif ($attr =~ /^_*unused/) {\n\t\t\t\tWARN(\"PREFER_DEFINED_ATTRIBUTE_MACRO\",\n\t\t\t\t     \"__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# Check for __attribute__ weak, or __weak declarations (may have link issues)\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /(?:$Declare|$DeclareMisordered)\\s*$Ident\\s*$balanced_parens\\s*(?:$Attribute)?\\s*;/ &&\n\t\t    ($line =~ /\\b__attribute__\\s*\\(\\s*\\(.*\\bweak\\b/ ||\n\t\t     $line =~ /\\b__weak\\b/)) {\n\t\t\tERROR(\"WEAK_DECLARATION\",\n\t\t\t      \"Using weak declarations can have unintended link defects\\n\" . $herecurr);\n\t\t}\n\n# check for c99 types like uint8_t used outside of uapi/ and tools/\n\t\tif ($realfile !~ m@\\binclude/uapi/@ &&\n\t\t    $realfile !~ m@\\btools/@ &&\n\t\t    $line =~ /\\b($Declare)\\s*$Ident\\s*[=;,\\[]/) {\n\t\t\tmy $type = $1;\n\t\t\tif ($type =~ /\\b($typeC99Typedefs)\\b/) {\n\t\t\t\t$type = $1;\n\t\t\t\tmy $kernel_type = 'u';\n\t\t\t\t$kernel_type = 's' if ($type =~ /^_*[si]/);\n\t\t\t\t$type =~ /(\\d+)/;\n\t\t\t\t$kernel_type .= $1;\n\t\t\t\tif (CHK(\"PREFER_KERNEL_TYPES\",\n\t\t\t\t\t\"Prefer kernel type '$kernel_type' over '$type'\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\b$type\\b/$kernel_type/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for cast of C90 native int or longer types constants\n\t\tif ($line =~ /(\\(\\s*$C90_int_types\\s*\\)\\s*)($Constant)\\b/) {\n\t\t\tmy $cast = $1;\n\t\t\tmy $const = $2;\n\t\t\tmy $suffix = \"\";\n\t\t\tmy $newconst = $const;\n\t\t\t$newconst =~ s/${Int_type}$//;\n\t\t\t$suffix .= 'U' if ($cast =~ /\\bunsigned\\b/);\n\t\t\tif ($cast =~ /\\blong\\s+long\\b/) {\n\t\t\t    $suffix .= 'LL';\n\t\t\t} elsif ($cast =~ /\\blong\\b/) {\n\t\t\t    $suffix .= 'L';\n\t\t\t}\n\t\t\tif (WARN(\"TYPECAST_INT_CONSTANT\",\n\t\t\t\t \"Unnecessary typecast of c90 int constant - '$cast$const' could be '$const$suffix'\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$cast\\E$const\\b/$newconst$suffix/;\n\t\t\t}\n\t\t}\n\n# check for sizeof(&)\n\t\tif ($line =~ /\\bsizeof\\s*\\(\\s*\\&/) {\n\t\t\tWARN(\"SIZEOF_ADDRESS\",\n\t\t\t     \"sizeof(& should be avoided\\n\" . $herecurr);\n\t\t}\n\n# check for sizeof without parenthesis\n\t\tif ($line =~ /\\bsizeof\\s+((?:\\*\\s*|)$Lval|$Type(?:\\s+$Lval|))/) {\n\t\t\tif (WARN(\"SIZEOF_PARENTHESIS\",\n\t\t\t\t \"sizeof $1 should be sizeof($1)\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\bsizeof\\s+((?:\\*\\s*|)$Lval|$Type(?:\\s+$Lval|))/\"sizeof(\" . trim($1) . \")\"/ex;\n\t\t\t}\n\t\t}\n\n# check for struct spinlock declarations\n\t\tif ($line =~ /^.\\s*\\bstruct\\s+spinlock\\s+\\w+\\s*;/) {\n\t\t\tWARN(\"USE_SPINLOCK_T\",\n\t\t\t     \"struct spinlock should be spinlock_t\\n\" . $herecurr);\n\t\t}\n\n# check for seq_printf uses that could be seq_puts\n\t\tif ($sline =~ /\\bseq_printf\\s*\\(.*\"\\s*\\)\\s*;\\s*$/) {\n\t\t\tmy $fmt = get_quoted_string($line, $rawline);\n\t\t\t$fmt =~ s/%%//g;\n\t\t\tif ($fmt !~ /%/) {\n\t\t\t\tif (WARN(\"PREFER_SEQ_PUTS\",\n\t\t\t\t\t \"Prefer seq_puts to seq_printf\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bseq_printf\\b/seq_puts/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for vsprintf extension %p<foo> misuses\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+(?![^\\{]*\\{\\s*).*\\b(\\w+)\\s*\\(.*$String\\s*,/s &&\n\t\t    $1 !~ /^_*volatile_*$/) {\n\t\t\tmy $stat_real;\n\n\t\t\tmy $lc = $stat =~ tr@\\n@@;\n\t\t\t$lc = $lc + $linenr;\n\t\t        for (my $count = $linenr; $count <= $lc; $count++) {\n\t\t\t\tmy $specifier;\n\t\t\t\tmy $extension;\n\t\t\t\tmy $qualifier;\n\t\t\t\tmy $bad_specifier = \"\";\n\t\t\t\tmy $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));\n\t\t\t\t$fmt =~ s/%%//g;\n\n\t\t\t\twhile ($fmt =~ /(\\%[\\*\\d\\.]*p(\\w)(\\w*))/g) {\n\t\t\t\t\t$specifier = $1;\n\t\t\t\t\t$extension = $2;\n\t\t\t\t\t$qualifier = $3;\n\t\t\t\t\tif ($extension !~ /[4SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||\n\t\t\t\t\t    ($extension eq \"f\" &&\n\t\t\t\t\t     defined $qualifier && $qualifier !~ /^w/) ||\n\t\t\t\t\t    ($extension eq \"4\" &&\n\t\t\t\t\t     defined $qualifier && $qualifier !~ /^cc/)) {\n\t\t\t\t\t\t$bad_specifier = $specifier;\n\t\t\t\t\t\tlast;\n\t\t\t\t\t}\n\t\t\t\t\tif ($extension eq \"x\" && !defined($stat_real)) {\n\t\t\t\t\t\tif (!defined($stat_real)) {\n\t\t\t\t\t\t\t$stat_real = get_stat_real($linenr, $lc);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tWARN(\"VSPRINTF_SPECIFIER_PX\",\n\t\t\t\t\t\t     \"Using vsprintf specifier '\\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\\%p'.\\n\" . \"$here\\n$stat_real\\n\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($bad_specifier ne \"\") {\n\t\t\t\t\tmy $stat_real = get_stat_real($linenr, $lc);\n\t\t\t\t\tmy $ext_type = \"Invalid\";\n\t\t\t\t\tmy $use = \"\";\n\t\t\t\t\tif ($bad_specifier =~ /p[Ff]/) {\n\t\t\t\t\t\t$use = \" - use %pS instead\";\n\t\t\t\t\t\t$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);\n\t\t\t\t\t}\n\n\t\t\t\t\tWARN(\"VSPRINTF_POINTER_EXTENSION\",\n\t\t\t\t\t     \"$ext_type vsprintf pointer extension '$bad_specifier'$use\\n\" . \"$here\\n$stat_real\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# Check for misused memsets\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+(?:.*?)\\bmemset\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\,\\s*$FuncArg\\s*\\)/) {\n\n\t\t\tmy $ms_addr = $2;\n\t\t\tmy $ms_val = $7;\n\t\t\tmy $ms_size = $12;\n\n\t\t\tif ($ms_size =~ /^(0x|)0$/i) {\n\t\t\t\tERROR(\"MEMSET\",\n\t\t\t\t      \"memset to 0's uses 0 as the 2nd argument, not the 3rd\\n\" . \"$here\\n$stat\\n\");\n\t\t\t} elsif ($ms_size =~ /^(0x|)1$/i) {\n\t\t\t\tWARN(\"MEMSET\",\n\t\t\t\t     \"single byte memset is suspicious. Swapped 2nd/3rd argument?\\n\" . \"$here\\n$stat\\n\");\n\t\t\t}\n\t\t}\n\n# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)\n#\t\tif ($perl_version_ok &&\n#\t\t    defined $stat &&\n#\t\t    $stat =~ /^\\+(?:.*?)\\bmemcpy\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\,\\s*ETH_ALEN\\s*\\)/) {\n#\t\t\tif (WARN(\"PREFER_ETHER_ADDR_COPY\",\n#\t\t\t\t \"Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\\n\" . \"$here\\n$stat\\n\") &&\n#\t\t\t    $fix) {\n#\t\t\t\t$fixed[$fixlinenr] =~ s/\\bmemcpy\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\,\\s*ETH_ALEN\\s*\\)/ether_addr_copy($2, $7)/;\n#\t\t\t}\n#\t\t}\n\n# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)\n#\t\tif ($perl_version_ok &&\n#\t\t    defined $stat &&\n#\t\t    $stat =~ /^\\+(?:.*?)\\bmemcmp\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\,\\s*ETH_ALEN\\s*\\)/) {\n#\t\t\tWARN(\"PREFER_ETHER_ADDR_EQUAL\",\n#\t\t\t     \"Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\\n\" . \"$here\\n$stat\\n\")\n#\t\t}\n\n# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr\n# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr\n#\t\tif ($perl_version_ok &&\n#\t\t    defined $stat &&\n#\t\t    $stat =~ /^\\+(?:.*?)\\bmemset\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\,\\s*ETH_ALEN\\s*\\)/) {\n#\n#\t\t\tmy $ms_val = $7;\n#\n#\t\t\tif ($ms_val =~ /^(?:0x|)0+$/i) {\n#\t\t\t\tif (WARN(\"PREFER_ETH_ZERO_ADDR\",\n#\t\t\t\t\t \"Prefer eth_zero_addr over memset()\\n\" . \"$here\\n$stat\\n\") &&\n#\t\t\t\t    $fix) {\n#\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bmemset\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*,\\s*ETH_ALEN\\s*\\)/eth_zero_addr($2)/;\n#\t\t\t\t}\n#\t\t\t} elsif ($ms_val =~ /^(?:0xff|255)$/i) {\n#\t\t\t\tif (WARN(\"PREFER_ETH_BROADCAST_ADDR\",\n#\t\t\t\t\t \"Prefer eth_broadcast_addr() over memset()\\n\" . \"$here\\n$stat\\n\") &&\n#\t\t\t\t    $fix) {\n#\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bmemset\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*,\\s*ETH_ALEN\\s*\\)/eth_broadcast_addr($2)/;\n#\t\t\t\t}\n#\t\t\t}\n#\t\t}\n\n# strlcpy uses that should likely be strscpy\n\t\tif ($line =~ /\\bstrlcpy\\s*\\(/) {\n\t\t\tWARN(\"STRLCPY\",\n\t\t\t     \"Prefer strscpy over strlcpy - see: https://lore.kernel.org/r/CAHk-=wgfRnXz0W3D37d01q3JFkr_i_uTL=V6A6G1oUZcprmknw\\@mail.gmail.com/\\n\" . $herecurr);\n\t\t}\n\n# typecasts on min/max could be min_t/max_t\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+(?:.*?)\\b(min|max)\\s*\\(\\s*$FuncArg\\s*,\\s*$FuncArg\\s*\\)/) {\n\t\t\tif (defined $2 || defined $7) {\n\t\t\t\tmy $call = $1;\n\t\t\t\tmy $cast1 = deparenthesize($2);\n\t\t\t\tmy $arg1 = $3;\n\t\t\t\tmy $cast2 = deparenthesize($7);\n\t\t\t\tmy $arg2 = $8;\n\t\t\t\tmy $cast;\n\n\t\t\t\tif ($cast1 ne \"\" && $cast2 ne \"\" && $cast1 ne $cast2) {\n\t\t\t\t\t$cast = \"$cast1 or $cast2\";\n\t\t\t\t} elsif ($cast1 ne \"\") {\n\t\t\t\t\t$cast = $cast1;\n\t\t\t\t} else {\n\t\t\t\t\t$cast = $cast2;\n\t\t\t\t}\n\t\t\t\tWARN(\"MINMAX\",\n\t\t\t\t     \"$call() should probably be ${call}_t($cast, $arg1, $arg2)\\n\" . \"$here\\n$stat\\n\");\n\t\t\t}\n\t\t}\n\n# check usleep_range arguments\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+(?:.*?)\\busleep_range\\s*\\(\\s*($FuncArg)\\s*,\\s*($FuncArg)\\s*\\)/) {\n\t\t\tmy $min = $1;\n\t\t\tmy $max = $7;\n\t\t\tif ($min eq $max) {\n\t\t\t\tWARN(\"USLEEP_RANGE\",\n\t\t\t\t     \"usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\\n\" . \"$here\\n$stat\\n\");\n\t\t\t} elsif ($min =~ /^\\d+$/ && $max =~ /^\\d+$/ &&\n\t\t\t\t $min > $max) {\n\t\t\t\tWARN(\"USLEEP_RANGE\",\n\t\t\t\t     \"usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\\n\" . \"$here\\n$stat\\n\");\n\t\t\t}\n\t\t}\n\n# check for naked sscanf\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $line =~ /\\bsscanf\\b/ &&\n\t\t    ($stat !~ /$Ident\\s*=\\s*sscanf\\s*$balanced_parens/ &&\n\t\t     $stat !~ /\\bsscanf\\s*$balanced_parens\\s*(?:$Compare)/ &&\n\t\t     $stat !~ /(?:$Compare)\\s*\\bsscanf\\s*$balanced_parens/)) {\n\t\t\tmy $lc = $stat =~ tr@\\n@@;\n\t\t\t$lc = $lc + $linenr;\n\t\t\tmy $stat_real = get_stat_real($linenr, $lc);\n\t\t\tWARN(\"NAKED_SSCANF\",\n\t\t\t     \"unchecked sscanf return value\\n\" . \"$here\\n$stat_real\\n\");\n\t\t}\n\n# check for simple sscanf that should be kstrto<foo>\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $line =~ /\\bsscanf\\b/) {\n\t\t\tmy $lc = $stat =~ tr@\\n@@;\n\t\t\t$lc = $lc + $linenr;\n\t\t\tmy $stat_real = get_stat_real($linenr, $lc);\n\t\t\tif ($stat_real =~ /\\bsscanf\\b\\s*\\(\\s*$FuncArg\\s*,\\s*(\"[^\"]+\")/) {\n\t\t\t\tmy $format = $6;\n\t\t\t\tmy $count = $format =~ tr@%@%@;\n\t\t\t\tif ($count == 1 &&\n\t\t\t\t    $format =~ /^\"\\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])\"$/) {\n\t\t\t\t\tWARN(\"SSCANF_TO_KSTRTO\",\n\t\t\t\t\t     \"Prefer kstrto<type> to single variable sscanf\\n\" . \"$here\\n$stat_real\\n\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for new externs in .h files.\n\t\tif ($realfile =~ /\\.h$/ &&\n\t\t    $line =~ /^\\+\\s*(extern\\s+)$Type\\s*$Ident\\s*\\(/s) {\n\t\t\tif (CHK(\"AVOID_EXTERNS\",\n\t\t\t\t\"extern prototypes should be avoided in .h files\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(.*)\\bextern\\b\\s*(.*)/$1$2/;\n\t\t\t}\n\t\t}\n\n# check for new externs in .c files.\n\t\tif ($realfile =~ /\\.c$/ && defined $stat &&\n\t\t    $stat =~ /^.\\s*(?:extern\\s+)?$Type\\s+($Ident)(\\s*)\\(/s)\n\t\t{\n\t\t\tmy $function_name = $1;\n\t\t\tmy $paren_space = $2;\n\n\t\t\tmy $s = $stat;\n\t\t\tif (defined $cond) {\n\t\t\t\tsubstr($s, 0, length($cond), '');\n\t\t\t}\n\t\t\tif ($s =~ /^\\s*;/)\n\t\t\t{\n\t\t\t\tWARN(\"AVOID_EXTERNS\",\n\t\t\t\t     \"externs should be avoided in .c files\\n\" .  $herecurr);\n\t\t\t}\n\n\t\t\tif ($paren_space =~ /\\n/) {\n\t\t\t\tWARN(\"FUNCTION_ARGUMENTS\",\n\t\t\t\t     \"arguments for function declarations should follow identifier\\n\" . $herecurr);\n\t\t\t}\n\n\t\t} elsif ($realfile =~ /\\.c$/ && defined $stat &&\n\t\t    $stat =~ /^.\\s*extern\\s+/)\n\t\t{\n\t\t\tWARN(\"AVOID_EXTERNS\",\n\t\t\t     \"externs should be avoided in .c files\\n\" .  $herecurr);\n\t\t}\n\n# check for function declarations that have arguments without identifier names\n\t\tif (defined $stat &&\n\t\t    $stat =~ /^.\\s*(?:extern\\s+)?$Type\\s*(?:$Ident|\\(\\s*\\*\\s*$Ident\\s*\\))\\s*\\(\\s*([^{]+)\\s*\\)\\s*;/s &&\n\t\t    $1 ne \"void\") {\n\t\t\tmy $args = trim($1);\n\t\t\twhile ($args =~ m/\\s*($Type\\s*(?:$Ident|\\(\\s*\\*\\s*$Ident?\\s*\\)\\s*$balanced_parens)?)/g) {\n\t\t\t\tmy $arg = trim($1);\n\t\t\t\tif ($arg =~ /^$Type$/ && $arg !~ /enum\\s+$Ident$/) {\n\t\t\t\t\tWARN(\"FUNCTION_ARGUMENTS\",\n\t\t\t\t\t     \"function definition argument '$arg' should also have an identifier name\\n\" . $herecurr);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for function definitions\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^.\\s*(?:$Storage\\s+)?$Type\\s*($Ident)\\s*$balanced_parens\\s*{/s) {\n\t\t\t$context_function = $1;\n\n# check for multiline function definition with misplaced open brace\n\t\t\tmy $ok = 0;\n\t\t\tmy $cnt = statement_rawlines($stat);\n\t\t\tmy $herectx = $here . \"\\n\";\n\t\t\tfor (my $n = 0; $n < $cnt; $n++) {\n\t\t\t\tmy $rl = raw_line($linenr, $n);\n\t\t\t\t$herectx .=  $rl . \"\\n\";\n\t\t\t\t$ok = 1 if ($rl =~ /^[ \\+]\\{/);\n\t\t\t\t$ok = 1 if ($rl =~ /\\{/ && $n == 0);\n\t\t\t\tlast if $rl =~ /^[ \\+].*\\{/;\n\t\t\t}\n\t\t\tif (!$ok) {\n\t\t\t\tERROR(\"OPEN_BRACE\",\n\t\t\t\t      \"open brace '{' following function definitions go on the next line\\n\" . $herectx);\n\t\t\t}\n\t\t}\n\n# checks for new __setup's\n\t\tif ($rawline =~ /\\b__setup\\(\"([^\"]*)\"/) {\n\t\t\tmy $name = $1;\n\n\t\t\tif (!grep(/$name/, @setup_docs)) {\n\t\t\t\tCHK(\"UNDOCUMENTED_SETUP\",\n\t\t\t\t    \"__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for pointless casting of alloc functions\n\t\tif ($line =~ /\\*\\s*\\)\\s*$allocFunctions\\b/) {\n\t\t\tWARN(\"UNNECESSARY_CASTS\",\n\t\t\t     \"unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\\n\" . $herecurr);\n\t\t}\n\n# alloc style\n# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /\\b($Lval)\\s*\\=\\s*(?:$balanced_parens)?\\s*((?:kv|k|v)[mz]alloc(?:_node)?)\\s*\\(\\s*(sizeof\\s*\\(\\s*struct\\s+$Lval\\s*\\))/) {\n\t\t\tCHK(\"ALLOC_SIZEOF_STRUCT\",\n\t\t\t    \"Prefer $3(sizeof(*$1)...) over $3($4...)\\n\" . $herecurr);\n\t\t}\n\n# check for (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+\\s*($Lval)\\s*\\=\\s*(?:$balanced_parens)?\\s*((?:kv|k)[mz]alloc)\\s*\\(\\s*($FuncArg)\\s*\\*\\s*($FuncArg)\\s*,/) {\n\t\t\tmy $oldfunc = $3;\n\t\t\tmy $a1 = $4;\n\t\t\tmy $a2 = $10;\n\t\t\tmy $newfunc = \"kmalloc_array\";\n\t\t\t$newfunc = \"kvmalloc_array\" if ($oldfunc eq \"kvmalloc\");\n\t\t\t$newfunc = \"kvcalloc\" if ($oldfunc eq \"kvzalloc\");\n\t\t\t$newfunc = \"kcalloc\" if ($oldfunc eq \"kzalloc\");\n\t\t\tmy $r1 = $a1;\n\t\t\tmy $r2 = $a2;\n\t\t\tif ($a1 =~ /^sizeof\\s*\\S/) {\n\t\t\t\t$r1 = $a2;\n\t\t\t\t$r2 = $a1;\n\t\t\t}\n\t\t\tif ($r1 !~ /^sizeof\\b/ && $r2 =~ /^sizeof\\s*\\S/ &&\n\t\t\t    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {\n\t\t\t\tmy $cnt = statement_rawlines($stat);\n\t\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\t\tif (WARN(\"ALLOC_WITH_MULTIPLY\",\n\t\t\t\t\t \"Prefer $newfunc over $oldfunc with multiply\\n\" . $herectx) &&\n\t\t\t\t    $cnt == 1 &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\b($Lval)\\s*\\=\\s*(?:$balanced_parens)?\\s*((?:kv|k)[mz]alloc)\\s*\\(\\s*($FuncArg)\\s*\\*\\s*($FuncArg)/$1 . ' = ' . \"$newfunc(\" . trim($r1) . ', ' . trim($r2)/e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for krealloc arg reuse\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /\\b($Lval)\\s*\\=\\s*(?:$balanced_parens)?\\s*krealloc\\s*\\(\\s*($Lval)\\s*,/ &&\n\t\t    $1 eq $3) {\n\t\t\tWARN(\"KREALLOC_ARG_REUSE\",\n\t\t\t     \"Reusing the krealloc arg is almost always a bug\\n\" . $herecurr);\n\t\t}\n\n# check for alloc argument mismatch\n\t\tif ($line =~ /\\b((?:devm_)?(?:kcalloc|kmalloc_array))\\s*\\(\\s*sizeof\\b/) {\n\t\t\tWARN(\"ALLOC_ARRAY_ARGS\",\n\t\t\t     \"$1 uses number as first arg, sizeof is generally wrong\\n\" . $herecurr);\n\t\t}\n\n# check for multiple semicolons\n\t\tif ($line =~ /;\\s*;\\s*$/) {\n\t\t\tif (WARN(\"ONE_SEMICOLON\",\n\t\t\t\t \"Statements terminations use 1 semicolon\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/(\\s*;\\s*){2,}$/;/g;\n\t\t\t}\n\t\t}\n\n# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi\n\t\tif ($realfile !~ m@^include/uapi/@ &&\n\t\t    $line =~ /#\\s*define\\s+\\w+\\s+\\(?\\s*1\\s*([ulUL]*)\\s*\\<\\<\\s*(?:\\d+|$Ident)\\s*\\)?/) {\n\t\t\tmy $ull = \"\";\n\t\t\t$ull = \"_ULL\" if (defined($1) && $1 =~ /ll/i);\n\t\t\tif (CHK(\"BIT_MACRO\",\n\t\t\t\t\"Prefer using the BIT$ull macro\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\(?\\s*1\\s*[ulUL]*\\s*<<\\s*(\\d+|$Ident)\\s*\\)?/BIT${ull}($1)/;\n\t\t\t}\n\t\t}\n\n# check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)\n\t\tif ($rawline =~ /\\bIS_ENABLED\\s*\\(\\s*(\\w+)\\s*\\)/ && $1 !~ /^${CONFIG_}/) {\n\t\t\tWARN(\"IS_ENABLED_CONFIG\",\n\t\t\t     \"IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\\n\" . $herecurr);\n\t\t}\n\n# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE\n\t\tif ($line =~ /^\\+\\s*#\\s*if\\s+defined(?:\\s*\\(?\\s*|\\s+)(${CONFIG_}[A-Z_]+)\\s*\\)?\\s*\\|\\|\\s*defined(?:\\s*\\(?\\s*|\\s+)\\1_MODULE\\s*\\)?\\s*$/) {\n\t\t\tmy $config = $1;\n\t\t\tif (WARN(\"PREFER_IS_ENABLED\",\n\t\t\t\t \"Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] = \"\\+#if IS_ENABLED($config)\";\n\t\t\t}\n\t\t}\n\n# check for /* fallthrough */ like comment, prefer fallthrough;\n\t\tmy @fallthroughs = (\n\t\t\t'fallthrough',\n\t\t\t'@fallthrough@',\n\t\t\t'lint -fallthrough[ \\t]*',\n\t\t\t'intentional(?:ly)?[ \\t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',\n\t\t\t'(?:else,?\\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \\t.!]*(?:-[^\\n\\r]*)?',\n\t\t\t'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \\t.!]*(?:-[^\\n\\r]*)?',\n\t\t\t'fall(?:s | |-)?thr(?:ough|u|ew)[ \\t.!]*(?:-[^\\n\\r]*)?',\n\t\t    );\n\t\tif ($raw_comment ne '') {\n\t\t\tforeach my $ft (@fallthroughs) {\n\t\t\t\tif ($raw_comment =~ /$ft/) {\n\t\t\t\t\tmy $msg_level = \\&WARN;\n\t\t\t\t\t$msg_level = \\&CHK if ($file);\n\t\t\t\t\t&{$msg_level}(\"PREFER_FALLTHROUGH\",\n\t\t\t\t\t\t      \"Prefer 'fallthrough;' over fallthrough comment\\n\" . $herecurr);\n\t\t\t\t\tlast;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for switch/default statements without a break;\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /^\\+[$;\\s]*(?:case[$;\\s]+\\w+[$;\\s]*:[$;\\s]*|)*[$;\\s]*\\bdefault[$;\\s]*:[$;\\s]*;/g) {\n\t\t\tmy $cnt = statement_rawlines($stat);\n\t\t\tmy $herectx = get_stat_here($linenr, $cnt, $here);\n\n\t\t\tWARN(\"DEFAULT_NO_BREAK\",\n\t\t\t     \"switch default: should use break\\n\" . $herectx);\n\t\t}\n\n# check for gcc specific __FUNCTION__\n\t\tif ($line =~ /\\b__FUNCTION__\\b/) {\n\t\t\tif (WARN(\"USE_FUNC\",\n\t\t\t\t \"__func__ should be used instead of gcc specific __FUNCTION__\\n\"  . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\b__FUNCTION__\\b/__func__/g;\n\t\t\t}\n\t\t}\n\n# check for uses of __DATE__, __TIME__, __TIMESTAMP__\n\t\twhile ($line =~ /\\b(__(?:DATE|TIME|TIMESTAMP)__)\\b/g) {\n\t\t\tERROR(\"DATE_TIME\",\n\t\t\t      \"Use of the '$1' macro makes the build non-deterministic\\n\" . $herecurr);\n\t\t}\n\n# check for use of yield()\n\t\tif ($line =~ /\\byield\\s*\\(\\s*\\)/) {\n\t\t\tWARN(\"YIELD\",\n\t\t\t     \"Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\\n\"  . $herecurr);\n\t\t}\n\n# check for comparisons against true and false\n\t\tif ($line =~ /\\+\\s*(.*?)\\b(true|false|$Lval)\\s*(==|\\!=)\\s*(true|false|$Lval)\\b(.*)$/i) {\n\t\t\tmy $lead = $1;\n\t\t\tmy $arg = $2;\n\t\t\tmy $test = $3;\n\t\t\tmy $otype = $4;\n\t\t\tmy $trail = $5;\n\t\t\tmy $op = \"!\";\n\n\t\t\t($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);\n\n\t\t\tmy $type = lc($otype);\n\t\t\tif ($type =~ /^(?:true|false)$/) {\n\t\t\t\tif ((\"$test\" eq \"==\" && \"$type\" eq \"true\") ||\n\t\t\t\t    (\"$test\" eq \"!=\" && \"$type\" eq \"false\")) {\n\t\t\t\t\t$op = \"\";\n\t\t\t\t}\n\n\t\t\t\tCHK(\"BOOL_COMPARISON\",\n\t\t\t\t    \"Using comparison to $otype is error prone\\n\" . $herecurr);\n\n## maybe suggesting a correct construct would better\n##\t\t\t\t    \"Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\\n\" . $herecurr);\n\n\t\t\t}\n\t\t}\n\n# check for semaphores initialized locked\n\t\tif ($line =~ /^.\\s*sema_init.+,\\W?0\\W?\\)/) {\n\t\t\tWARN(\"CONSIDER_COMPLETION\",\n\t\t\t     \"consider using a completion\\n\" . $herecurr);\n\t\t}\n\n# recommend kstrto* over simple_strto* and strict_strto*\n\t\tif ($line =~ /\\b((simple|strict)_(strto(l|ll|ul|ull)))\\s*\\(/) {\n\t\t\tWARN(\"CONSIDER_KSTRTO\",\n\t\t\t     \"$1 is obsolete, use k$3 instead\\n\" . $herecurr);\n\t\t}\n\n# check for __initcall(), use device_initcall() explicitly or more appropriate function please\n\t\tif ($line =~ /^.\\s*__initcall\\s*\\(/) {\n\t\t\tWARN(\"USE_DEVICE_INITCALL\",\n\t\t\t     \"please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\\n\" . $herecurr);\n\t\t}\n\n# check for spin_is_locked(), suggest lockdep instead\n\t\tif ($line =~ /\\bspin_is_locked\\(/) {\n\t\t\tWARN(\"USE_LOCKDEP\",\n\t\t\t     \"Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\\n\" . $herecurr);\n\t\t}\n\n# check for deprecated apis\n\t\tif ($line =~ /\\b($deprecated_apis_search)\\b\\s*\\(/) {\n\t\t\tmy $deprecated_api = $1;\n\t\t\tmy $new_api = $deprecated_apis{$deprecated_api};\n\t\t\tWARN(\"DEPRECATED_API\",\n\t\t\t     \"Deprecated use of '$deprecated_api', prefer '$new_api' instead\\n\" . $herecurr);\n\t\t}\n\n# check for various structs that are normally const (ops, kgdb, device_tree)\n# and avoid what seem like struct definitions 'struct foo {'\n\t\tif (defined($const_structs) &&\n\t\t    $line !~ /\\bconst\\b/ &&\n\t\t    $line =~ /\\bstruct\\s+($const_structs)\\b(?!\\s*\\{)/) {\n\t\t\tWARN(\"CONST_STRUCT\",\n\t\t\t     \"struct $1 should normally be const\\n\" . $herecurr);\n\t\t}\n\n# use of NR_CPUS is usually wrong\n# ignore definitions of NR_CPUS and usage to define arrays as likely right\n# ignore designated initializers using NR_CPUS\n\t\tif ($line =~ /\\bNR_CPUS\\b/ &&\n\t\t    $line !~ /^.\\s*\\s*#\\s*if\\b.*\\bNR_CPUS\\b/ &&\n\t\t    $line !~ /^.\\s*\\s*#\\s*define\\b.*\\bNR_CPUS\\b/ &&\n\t\t    $line !~ /^.\\s*$Declare\\s.*\\[[^\\]]*NR_CPUS[^\\]]*\\]/ &&\n\t\t    $line !~ /\\[[^\\]]*\\.\\.\\.[^\\]]*NR_CPUS[^\\]]*\\]/ &&\n\t\t    $line !~ /\\[[^\\]]*NR_CPUS[^\\]]*\\.\\.\\.[^\\]]*\\]/ &&\n\t\t    $line !~ /^.\\s*\\.\\w+\\s*=\\s*.*\\bNR_CPUS\\b/)\n\t\t{\n\t\t\tWARN(\"NR_CPUS\",\n\t\t\t     \"usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\\n\" . $herecurr);\n\t\t}\n\n# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.\n\t\tif ($line =~ /\\+\\s*#\\s*define\\s+((?:__)?ARCH_(?:HAS|HAVE)\\w*)\\b/) {\n\t\t\tERROR(\"DEFINE_ARCH_HAS\",\n\t\t\t      \"#define of '$1' is wrong - use Kconfig variables or standard guards instead\\n\" . $herecurr);\n\t\t}\n\n# likely/unlikely comparisons similar to \"(likely(foo) > 0)\"\n\t\tif ($perl_version_ok &&\n\t\t    $line =~ /\\b((?:un)?likely)\\s*\\(\\s*$FuncArg\\s*\\)\\s*$Compare/) {\n\t\t\tWARN(\"LIKELY_MISUSE\",\n\t\t\t     \"Using $1 should generally have parentheses around the comparison\\n\" . $herecurr);\n\t\t}\n\n# return sysfs_emit(foo, fmt, ...) fmt without newline\n\t\tif ($line =~ /\\breturn\\s+sysfs_emit\\s*\\(\\s*$FuncArg\\s*,\\s*($String)/ &&\n\t\t    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\\\n\"$/) {\n\t\t\tmy $offset = $+[6] - 1;\n\t\t\tif (WARN(\"SYSFS_EMIT\",\n\t\t\t\t \"return sysfs_emit(...) formats should include a terminating newline\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\tsubstr($fixed[$fixlinenr], $offset, 0) = '\\\\n';\n\t\t\t}\n\t\t}\n\n# nested likely/unlikely calls\n\t\tif ($line =~ /\\b(?:(?:un)?likely)\\s*\\(\\s*!?\\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {\n\t\t\tWARN(\"LIKELY_MISUSE\",\n\t\t\t     \"nested (un)?likely() calls, $1 already uses unlikely() internally\\n\" . $herecurr);\n\t\t}\n\n# whine mightly about in_atomic\n\t\tif ($line =~ /\\bin_atomic\\s*\\(/) {\n\t\t\tif ($realfile =~ m@^drivers/@) {\n\t\t\t\tERROR(\"IN_ATOMIC\",\n\t\t\t\t      \"do not use in_atomic in drivers\\n\" . $herecurr);\n\t\t\t} elsif ($realfile !~ m@^kernel/@) {\n\t\t\t\tWARN(\"IN_ATOMIC\",\n\t\t\t\t     \"use of in_atomic() is incorrect outside core kernel code\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# check for lockdep_set_novalidate_class\n\t\tif ($line =~ /^.\\s*lockdep_set_novalidate_class\\s*\\(/ ||\n\t\t    $line =~ /__lockdep_no_validate__\\s*\\)/ ) {\n\t\t\tif ($realfile !~ m@^kernel/lockdep@ &&\n\t\t\t    $realfile !~ m@^include/linux/lockdep@ &&\n\t\t\t    $realfile !~ m@^drivers/base/core@) {\n\t\t\t\tERROR(\"LOCKDEP\",\n\t\t\t\t      \"lockdep_no_validate class is reserved for device->mutex.\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n\t\tif ($line =~ /debugfs_create_\\w+.*\\b$mode_perms_world_writable\\b/ ||\n\t\t    $line =~ /DEVICE_ATTR.*\\b$mode_perms_world_writable\\b/) {\n\t\t\tWARN(\"EXPORTED_WORLD_WRITABLE\",\n\t\t\t     \"Exporting world writable files is usually an error. Consider more restrictive permissions.\\n\" . $herecurr);\n\t\t}\n\n# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>\n# and whether or not function naming is typical and if\n# DEVICE_ATTR permissions uses are unusual too\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $stat =~ /\\bDEVICE_ATTR\\s*\\(\\s*(\\w+)\\s*,\\s*\\(?\\s*(\\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\\s*)\\s*\\)?\\s*,\\s*(\\w+)\\s*,\\s*(\\w+)\\s*\\)/) {\n\t\t\tmy $var = $1;\n\t\t\tmy $perms = $2;\n\t\t\tmy $show = $3;\n\t\t\tmy $store = $4;\n\t\t\tmy $octal_perms = perms_to_octal($perms);\n\t\t\tif ($show =~ /^${var}_show$/ &&\n\t\t\t    $store =~ /^${var}_store$/ &&\n\t\t\t    $octal_perms eq \"0644\") {\n\t\t\t\tif (WARN(\"DEVICE_ATTR_RW\",\n\t\t\t\t\t \"Use DEVICE_ATTR_RW\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bDEVICE_ATTR\\s*\\(\\s*$var\\s*,\\s*\\Q$perms\\E\\s*,\\s*$show\\s*,\\s*$store\\s*\\)/DEVICE_ATTR_RW(${var})/;\n\t\t\t\t}\n\t\t\t} elsif ($show =~ /^${var}_show$/ &&\n\t\t\t\t $store =~ /^NULL$/ &&\n\t\t\t\t $octal_perms eq \"0444\") {\n\t\t\t\tif (WARN(\"DEVICE_ATTR_RO\",\n\t\t\t\t\t \"Use DEVICE_ATTR_RO\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bDEVICE_ATTR\\s*\\(\\s*$var\\s*,\\s*\\Q$perms\\E\\s*,\\s*$show\\s*,\\s*NULL\\s*\\)/DEVICE_ATTR_RO(${var})/;\n\t\t\t\t}\n\t\t\t} elsif ($show =~ /^NULL$/ &&\n\t\t\t\t $store =~ /^${var}_store$/ &&\n\t\t\t\t $octal_perms eq \"0200\") {\n\t\t\t\tif (WARN(\"DEVICE_ATTR_WO\",\n\t\t\t\t\t \"Use DEVICE_ATTR_WO\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bDEVICE_ATTR\\s*\\(\\s*$var\\s*,\\s*\\Q$perms\\E\\s*,\\s*NULL\\s*,\\s*$store\\s*\\)/DEVICE_ATTR_WO(${var})/;\n\t\t\t\t}\n\t\t\t} elsif ($octal_perms eq \"0644\" ||\n\t\t\t\t $octal_perms eq \"0444\" ||\n\t\t\t\t $octal_perms eq \"0200\") {\n\t\t\t\tmy $newshow = \"$show\";\n\t\t\t\t$newshow = \"${var}_show\" if ($show ne \"NULL\" && $show ne \"${var}_show\");\n\t\t\t\tmy $newstore = $store;\n\t\t\t\t$newstore = \"${var}_store\" if ($store ne \"NULL\" && $store ne \"${var}_store\");\n\t\t\t\tmy $rename = \"\";\n\t\t\t\tif ($show ne $newshow) {\n\t\t\t\t\t$rename .= \" '$show' to '$newshow'\";\n\t\t\t\t}\n\t\t\t\tif ($store ne $newstore) {\n\t\t\t\t\t$rename .= \" '$store' to '$newstore'\";\n\t\t\t\t}\n\t\t\t\tWARN(\"DEVICE_ATTR_FUNCTIONS\",\n\t\t\t\t     \"Consider renaming function(s)$rename\\n\" . $herecurr);\n\t\t\t} else {\n\t\t\t\tWARN(\"DEVICE_ATTR_PERMS\",\n\t\t\t\t     \"DEVICE_ATTR unusual permissions '$perms' used\\n\" . $herecurr);\n\t\t\t}\n\t\t}\n\n# Mode permission misuses where it seems decimal should be octal\n# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop\n# o Ignore module_param*(...) uses with a decimal 0 permission as that has a\n#   specific definition of not visible in sysfs.\n# o Ignore proc_create*(...) uses with a decimal 0 permission as that means\n#   use the default permissions\n\t\tif ($perl_version_ok &&\n\t\t    defined $stat &&\n\t\t    $line =~ /$mode_perms_search/) {\n\t\t\tforeach my $entry (@mode_permission_funcs) {\n\t\t\t\tmy $func = $entry->[0];\n\t\t\t\tmy $arg_pos = $entry->[1];\n\n\t\t\t\tmy $lc = $stat =~ tr@\\n@@;\n\t\t\t\t$lc = $lc + $linenr;\n\t\t\t\tmy $stat_real = get_stat_real($linenr, $lc);\n\n\t\t\t\tmy $skip_args = \"\";\n\t\t\t\tif ($arg_pos > 1) {\n\t\t\t\t\t$arg_pos--;\n\t\t\t\t\t$skip_args = \"(?:\\\\s*$FuncArg\\\\s*,\\\\s*){$arg_pos,$arg_pos}\";\n\t\t\t\t}\n\t\t\t\tmy $test = \"\\\\b$func\\\\s*\\\\(${skip_args}($FuncArg(?:\\\\|\\\\s*$FuncArg)*)\\\\s*[,\\\\)]\";\n\t\t\t\tif ($stat =~ /$test/) {\n\t\t\t\t\tmy $val = $1;\n\t\t\t\t\t$val = $6 if ($skip_args ne \"\");\n\t\t\t\t\tif (!($func =~ /^(?:module_param|proc_create)/ && $val eq \"0\") &&\n\t\t\t\t\t    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||\n\t\t\t\t\t     ($val =~ /^$Octal$/ && length($val) ne 4))) {\n\t\t\t\t\t\tERROR(\"NON_OCTAL_PERMISSIONS\",\n\t\t\t\t\t\t      \"Use 4 digit octal (0777) not decimal permissions\\n\" . \"$here\\n\" . $stat_real);\n\t\t\t\t\t}\n\t\t\t\t\tif ($val =~ /^$Octal$/ && (oct($val) & 02)) {\n\t\t\t\t\t\tERROR(\"EXPORTED_WORLD_WRITABLE\",\n\t\t\t\t\t\t      \"Exporting writable files is usually an error. Consider more restrictive permissions.\\n\" . \"$here\\n\" . $stat_real);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for uses of S_<PERMS> that could be octal for readability\n\t\twhile ($line =~ m{\\b($multi_mode_perms_string_search)\\b}g) {\n\t\t\tmy $oval = $1;\n\t\t\tmy $octal = perms_to_octal($oval);\n\t\t\tif (WARN(\"SYMBOLIC_PERMS\",\n\t\t\t\t \"Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\\n\" . $herecurr) &&\n\t\t\t    $fix) {\n\t\t\t\t$fixed[$fixlinenr] =~ s/\\Q$oval\\E/$octal/;\n\t\t\t}\n\t\t}\n\n# validate content of MODULE_LICENSE against list from include/linux/module.h\n\t\tif ($line =~ /\\bMODULE_LICENSE\\s*\\(\\s*($String)\\s*\\)/) {\n\t\t\tmy $extracted_string = get_quoted_string($line, $rawline);\n\t\t\tmy $valid_licenses = qr{\n\t\t\t\t\t\tGPL|\n\t\t\t\t\t\tGPL\\ v2|\n\t\t\t\t\t\tGPL\\ and\\ additional\\ rights|\n\t\t\t\t\t\tDual\\ BSD/GPL|\n\t\t\t\t\t\tDual\\ MIT/GPL|\n\t\t\t\t\t\tDual\\ MPL/GPL|\n\t\t\t\t\t\tProprietary\n\t\t\t\t\t}x;\n\t\t\tif ($extracted_string !~ /^\"(?:$valid_licenses)\"$/x) {\n\t\t\t\tWARN(\"MODULE_LICENSE\",\n\t\t\t\t     \"unknown module license \" . $extracted_string . \"\\n\" . $herecurr);\n\t\t\t}\n\t\t\tif (!$file && $extracted_string eq '\"GPL v2\"') {\n\t\t\t\tif (WARN(\"MODULE_LICENSE\",\n\t\t\t\t     \"Prefer \\\"GPL\\\" over \\\"GPL v2\\\" - see commit bf7fbeeae6db (\\\"module: Cure the MODULE_LICENSE \\\"GPL\\\" vs. \\\"GPL v2\\\" bogosity\\\")\\n\" . $herecurr) &&\n\t\t\t\t    $fix) {\n\t\t\t\t\t$fixed[$fixlinenr] =~ s/\\bMODULE_LICENSE\\s*\\(\\s*\"GPL v2\"\\s*\\)/MODULE_LICENSE(\"GPL\")/;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n# check for sysctl duplicate constants\n\t\tif ($line =~ /\\.extra[12]\\s*=\\s*&(zero|one|int_max)\\b/) {\n\t\t\tWARN(\"DUPLICATED_SYSCTL_CONST\",\n\t\t\t\t\"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\\n\" . $herecurr);\n\t\t}\n\t}\n\n\t# If we have no input at all, then there is nothing to report on\n\t# so just keep quiet.\n\tif ($#rawlines == -1) {\n\t\texit(0);\n\t}\n\n\t# In mailback mode only produce a report in the negative, for\n\t# things that appear to be patches.\n\tif ($mailback && ($clean == 1 || !$is_patch)) {\n\t\texit(0);\n\t}\n\n\t# This is not a patch, and we are in 'no-patch' mode so\n\t# just keep quiet.\n\tif (!$chk_patch && !$is_patch) {\n\t\texit(0);\n\t}\n\n\tif (!$is_patch && $filename !~ /cover-letter\\.patch$/) {\n\t\tERROR(\"NOT_UNIFIED_DIFF\",\n\t\t      \"Does not appear to be a unified-diff format patch\\n\");\n\t}\n\tif ($is_patch && $has_commit_log && $chk_signoff) {\n\t\tif ($signoff == 0) {\n\t\t\tERROR(\"MISSING_SIGN_OFF\",\n\t\t\t      \"Missing Signed-off-by: line(s)\\n\");\n\t\t} elsif ($authorsignoff != 1) {\n\t\t\t# authorsignoff values:\n\t\t\t# 0 -> missing sign off\n\t\t\t# 1 -> sign off identical\n\t\t\t# 2 -> names and addresses match, comments mismatch\n\t\t\t# 3 -> addresses match, names different\n\t\t\t# 4 -> names match, addresses different\n\t\t\t# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match\n\n\t\t\tmy $sob_msg = \"'From: $author' != 'Signed-off-by: $author_sob'\";\n\n\t\t\tif ($authorsignoff == 0) {\n\t\t\t\tERROR(\"NO_AUTHOR_SIGN_OFF\",\n\t\t\t\t      \"Missing Signed-off-by: line by nominal patch author '$author'\\n\");\n\t\t\t} elsif ($authorsignoff == 2) {\n\t\t\t\tCHK(\"FROM_SIGN_OFF_MISMATCH\",\n\t\t\t\t    \"From:/Signed-off-by: email comments mismatch: $sob_msg\\n\");\n\t\t\t} elsif ($authorsignoff == 3) {\n\t\t\t\tWARN(\"FROM_SIGN_OFF_MISMATCH\",\n\t\t\t\t     \"From:/Signed-off-by: email name mismatch: $sob_msg\\n\");\n\t\t\t} elsif ($authorsignoff == 4) {\n\t\t\t\tWARN(\"FROM_SIGN_OFF_MISMATCH\",\n\t\t\t\t     \"From:/Signed-off-by: email address mismatch: $sob_msg\\n\");\n\t\t\t} elsif ($authorsignoff == 5) {\n\t\t\t\tWARN(\"FROM_SIGN_OFF_MISMATCH\",\n\t\t\t\t     \"From:/Signed-off-by: email subaddress mismatch: $sob_msg\\n\");\n\t\t\t}\n\t\t}\n\t}\n\n\tprint report_dump();\n\tif ($summary && !($clean == 1 && $quiet == 1)) {\n\t\tprint \"$filename \" if ($summary_file);\n\t\tprint \"total: $cnt_error errors, $cnt_warn warnings, \" .\n\t\t\t(($check)? \"$cnt_chk checks, \" : \"\") .\n\t\t\t\"$cnt_lines lines checked\\n\";\n\t}\n\n\tif ($quiet == 0) {\n\t\t# If there were any defects found and not already fixing them\n\t\tif (!$clean and !$fix) {\n\t\t\tprint << \"EOM\"\n\nNOTE: For some of the reported defects, checkpatch may be able to\n      mechanically convert to the typical style using --fix or --fix-inplace.\nEOM\n\t\t}\n\t\t# If there were whitespace errors which cleanpatch can fix\n\t\t# then suggest that.\n\t\tif ($rpt_cleaners) {\n\t\t\t$rpt_cleaners = 0;\n\t\t\tprint << \"EOM\"\n\nNOTE: Whitespace errors detected.\n      You may wish to use scripts/cleanpatch or scripts/cleanfile\nEOM\n\t\t}\n\t}\n\n\tif ($clean == 0 && $fix &&\n\t    (\"@rawlines\" ne \"@fixed\" ||\n\t     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {\n\t\tmy $newfile = $filename;\n\t\t$newfile .= \".EXPERIMENTAL-checkpatch-fixes\" if (!$fix_inplace);\n\t\tmy $linecount = 0;\n\t\tmy $f;\n\n\t\t@fixed = fix_inserted_deleted_lines(\\@fixed, \\@fixed_inserted, \\@fixed_deleted);\n\n\t\topen($f, '>', $newfile)\n\t\t    or die \"$P: Can't open $newfile for write\\n\";\n\t\tforeach my $fixed_line (@fixed) {\n\t\t\t$linecount++;\n\t\t\tif ($file) {\n\t\t\t\tif ($linecount > 3) {\n\t\t\t\t\t$fixed_line =~ s/^\\+//;\n\t\t\t\t\tprint $f $fixed_line . \"\\n\";\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tprint $f $fixed_line . \"\\n\";\n\t\t\t}\n\t\t}\n\t\tclose($f);\n\n\t\tif (!$quiet) {\n\t\t\tprint << \"EOM\";\n\nWrote EXPERIMENTAL --fix correction(s) to '$newfile'\n\nDo _NOT_ trust the results written to this file.\nDo _NOT_ submit these changes without inspecting them for correctness.\n\nThis EXPERIMENTAL file is simply a convenience to help rewrite patches.\nNo warranties, expressed or implied...\nEOM\n\t\t}\n\t}\n\n\tif ($quiet == 0) {\n\t\tprint \"\\n\";\n\t\tif ($clean == 1) {\n\t\t\tprint \"$vname has no obvious style problems and is ready for submission.\\n\";\n\t\t} else {\n\t\t\tprint \"$vname has style problems, please review.\\n\";\n\t\t}\n\t}\n\treturn $clean;\n}\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/const_structs.checkpatch",
    "content": ""
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/spdxcheck.py",
    "content": "#!/usr/bin/env python3\n# SPDX-License-Identifier: GPL-2.0\n# Copyright Thomas Gleixner <tglx@linutronix.de>\n\nfrom argparse import ArgumentParser\nfrom ply import lex, yacc\nimport locale\nimport traceback\nimport fnmatch\nimport sys\nimport git\nimport re\nimport os\n\nclass ParserException(Exception):\n    def __init__(self, tok, txt):\n        self.tok = tok\n        self.txt = txt\n\nclass SPDXException(Exception):\n    def __init__(self, el, txt):\n        self.el = el\n        self.txt = txt\n\nclass SPDXdata(object):\n    def __init__(self):\n        self.license_files = 0\n        self.exception_files = 0\n        self.licenses = [ ]\n        self.exceptions = { }\n\nclass dirinfo(object):\n    def __init__(self):\n        self.missing = 0\n        self.total = 0\n        self.files = []\n\n    def update(self, fname, basedir, miss):\n        self.total += 1\n        self.missing += miss\n        if miss:\n            fname = './' + fname\n            bdir = os.path.dirname(fname)\n            if bdir == basedir.rstrip('/'):\n                self.files.append(fname)\n\n# Read the spdx data from the LICENSES directory\ndef read_spdxdata(repo):\n\n    # The subdirectories of LICENSES in the kernel source\n    # Note: exceptions needs to be parsed as last directory.\n    # OpenOCD specific: Begin\n    license_dirs = [ \"preferred\", \"stand-alone\", \"exceptions\" ]\n    # OpenOCD specific: End\n    lictree = repo.head.commit.tree['LICENSES']\n\n    spdx = SPDXdata()\n\n    for d in license_dirs:\n        for el in lictree[d].traverse():\n            if not os.path.isfile(el.path):\n                continue\n\n            exception = None\n            for l in open(el.path, encoding=\"utf-8\").readlines():\n                if l.startswith('Valid-License-Identifier:'):\n                    lid = l.split(':')[1].strip().upper()\n                    if lid in spdx.licenses:\n                        raise SPDXException(el, 'Duplicate License Identifier: %s' %lid)\n                    else:\n                        spdx.licenses.append(lid)\n\n                elif l.startswith('SPDX-Exception-Identifier:'):\n                    exception = l.split(':')[1].strip().upper()\n                    spdx.exceptions[exception] = []\n\n                elif l.startswith('SPDX-Licenses:'):\n                    for lic in l.split(':')[1].upper().strip().replace(' ', '').replace('\\t', '').split(','):\n                        if not lic in spdx.licenses:\n                            raise SPDXException(None, 'Exception %s missing license %s' %(exception, lic))\n                        spdx.exceptions[exception].append(lic)\n\n                elif l.startswith(\"License-Text:\"):\n                    if exception:\n                        if not len(spdx.exceptions[exception]):\n                            raise SPDXException(el, 'Exception %s is missing SPDX-Licenses' %exception)\n                        spdx.exception_files += 1\n                    else:\n                        spdx.license_files += 1\n                    break\n    return spdx\n\nclass id_parser(object):\n\n    reserved = [ 'AND', 'OR', 'WITH' ]\n    tokens = [ 'LPAR', 'RPAR', 'ID', 'EXC' ] + reserved\n\n    precedence = ( ('nonassoc', 'AND', 'OR'), )\n\n    t_ignore = ' \\t'\n\n    def __init__(self, spdx):\n        self.spdx = spdx\n        self.lasttok = None\n        self.lastid = None\n        self.lexer = lex.lex(module = self, reflags = re.UNICODE)\n        # Initialize the parser. No debug file and no parser rules stored on disk\n        # The rules are small enough to be generated on the fly\n        self.parser = yacc.yacc(module = self, write_tables = False, debug = False)\n        self.lines_checked = 0\n        self.checked = 0\n        self.excluded = 0\n        self.spdx_valid = 0\n        self.spdx_errors = 0\n        self.spdx_dirs = {}\n        self.dirdepth = -1\n        self.basedir = '.'\n        self.curline = 0\n        self.deepest = 0\n\n    def set_dirinfo(self, basedir, dirdepth):\n        if dirdepth >= 0:\n            self.basedir = basedir\n            bdir = basedir.lstrip('./').rstrip('/')\n            if bdir != '':\n                parts = bdir.split('/')\n            else:\n                parts = []\n            self.dirdepth = dirdepth + len(parts)\n\n    # Validate License and Exception IDs\n    def validate(self, tok):\n        id = tok.value.upper()\n        if tok.type == 'ID':\n            if not id in self.spdx.licenses:\n                raise ParserException(tok, 'Invalid License ID')\n            self.lastid = id\n        elif tok.type == 'EXC':\n            if id not in self.spdx.exceptions:\n                raise ParserException(tok, 'Invalid Exception ID')\n            if self.lastid not in self.spdx.exceptions[id]:\n                raise ParserException(tok, 'Exception not valid for license %s' %self.lastid)\n            self.lastid = None\n        elif tok.type != 'WITH':\n            self.lastid = None\n\n    # Lexer functions\n    def t_RPAR(self, tok):\n        r'\\)'\n        self.lasttok = tok.type\n        return tok\n\n    def t_LPAR(self, tok):\n        r'\\('\n        self.lasttok = tok.type\n        return tok\n\n    def t_ID(self, tok):\n        r'[A-Za-z.0-9\\-+]+'\n\n        if self.lasttok == 'EXC':\n            print(tok)\n            raise ParserException(tok, 'Missing parentheses')\n\n        tok.value = tok.value.strip()\n        val = tok.value.upper()\n\n        if val in self.reserved:\n            tok.type = val\n        elif self.lasttok == 'WITH':\n            tok.type = 'EXC'\n\n        self.lasttok = tok.type\n        self.validate(tok)\n        return tok\n\n    def t_error(self, tok):\n        raise ParserException(tok, 'Invalid token')\n\n    def p_expr(self, p):\n        '''expr : ID\n                | ID WITH EXC\n                | expr AND expr\n                | expr OR expr\n                | LPAR expr RPAR'''\n        pass\n\n    def p_error(self, p):\n        if not p:\n            raise ParserException(None, 'Unfinished license expression')\n        else:\n            raise ParserException(p, 'Syntax error')\n\n    def parse(self, expr):\n        self.lasttok = None\n        self.lastid = None\n        self.parser.parse(expr, lexer = self.lexer)\n\n    def parse_lines(self, fd, maxlines, fname):\n        self.checked += 1\n        self.curline = 0\n        fail = 1\n        try:\n            for line in fd:\n                line = line.decode(locale.getpreferredencoding(False), errors='ignore')\n                self.curline += 1\n                if self.curline > maxlines:\n                    break\n                self.lines_checked += 1\n                if line.find(\"SPDX-License-Identifier:\") < 0:\n                    continue\n                expr = line.split(':')[1].strip()\n                # Remove trailing comment closure\n                if line.strip().endswith('*/'):\n                    expr = expr.rstrip('*/').strip()\n                # Remove trailing xml comment closure\n                if line.strip().endswith('-->'):\n                    expr = expr.rstrip('-->').strip()\n                # Special case for SH magic boot code files\n                if line.startswith('LIST \\\"'):\n                    expr = expr.rstrip('\\\"').strip()\n                self.parse(expr)\n                self.spdx_valid += 1\n                #\n                # Should we check for more SPDX ids in the same file and\n                # complain if there are any?\n                #\n                fail = 0\n                break\n\n        except ParserException as pe:\n            if pe.tok:\n                col = line.find(expr) + pe.tok.lexpos\n                tok = pe.tok.value\n                sys.stdout.write('%s: %d:%d %s: %s\\n' %(fname, self.curline, col, pe.txt, tok))\n            else:\n                sys.stdout.write('%s: %d:0 %s\\n' %(fname, self.curline, pe.txt))\n            self.spdx_errors += 1\n\n        if fname == '-':\n            return\n\n        base = os.path.dirname(fname)\n        if self.dirdepth > 0:\n            parts = base.split('/')\n            i = 0\n            base = '.'\n            while i < self.dirdepth and i < len(parts) and len(parts[i]):\n                base += '/' + parts[i]\n                i += 1\n        elif self.dirdepth == 0:\n            base = self.basedir\n        else:\n            base = './' + base.rstrip('/')\n        base += '/'\n\n        di = self.spdx_dirs.get(base, dirinfo())\n        di.update(fname, base, fail)\n        self.spdx_dirs[base] = di\n\nclass pattern(object):\n    def __init__(self, line):\n        self.pattern = line\n        self.match = self.match_file\n        if line == '.*':\n            self.match = self.match_dot\n        elif line.endswith('/'):\n            self.pattern = line[:-1]\n            self.match = self.match_dir\n        elif line.startswith('/'):\n            self.pattern = line[1:]\n            self.match = self.match_fn\n\n    def match_dot(self, fpath):\n        return os.path.basename(fpath).startswith('.')\n\n    def match_file(self, fpath):\n        return os.path.basename(fpath) == self.pattern\n\n    def match_fn(self, fpath):\n        return fnmatch.fnmatchcase(fpath, self.pattern)\n\n    def match_dir(self, fpath):\n        if self.match_fn(os.path.dirname(fpath)):\n            return True\n        return fpath.startswith(self.pattern)\n\ndef exclude_file(fpath):\n    for rule in exclude_rules:\n        if rule.match(fpath):\n            return True\n    return False\n\ndef scan_git_tree(tree, basedir, dirdepth):\n    parser.set_dirinfo(basedir, dirdepth)\n    for el in tree.traverse():\n        if not os.path.isfile(el.path):\n            continue\n        if exclude_file(el.path):\n            parser.excluded += 1\n            continue\n        with open(el.path, 'rb') as fd:\n            parser.parse_lines(fd, args.maxlines, el.path)\n\ndef scan_git_subtree(tree, path, dirdepth):\n    for p in path.strip('/').split('/'):\n        tree = tree[p]\n    scan_git_tree(tree, path.strip('/'), dirdepth)\n\ndef read_exclude_file(fname):\n    rules = []\n    if not fname:\n        return rules\n    with open(fname) as fd:\n        for line in fd:\n            line = line.strip()\n            if line.startswith('#'):\n                continue\n            if not len(line):\n                continue\n            rules.append(pattern(line))\n    return rules\n\nif __name__ == '__main__':\n\n    ap = ArgumentParser(description='SPDX expression checker')\n    ap.add_argument('path', nargs='*', help='Check path or file. If not given full git tree scan. For stdin use \"-\"')\n    ap.add_argument('-d', '--dirs', action='store_true',\n                    help='Show [sub]directory statistics.')\n    ap.add_argument('-D', '--depth', type=int, default=-1,\n                    help='Directory depth for -d statistics. Default: unlimited')\n    ap.add_argument('-e', '--exclude',\n                    help='File containing file patterns to exclude. Default: scripts/spdxexclude')\n    ap.add_argument('-f', '--files', action='store_true',\n                    help='Show files without SPDX.')\n    ap.add_argument('-m', '--maxlines', type=int, default=15,\n                    help='Maximum number of lines to scan in a file. Default 15')\n    ap.add_argument('-v', '--verbose', action='store_true', help='Verbose statistics output')\n    args = ap.parse_args()\n\n    # Sanity check path arguments\n    if '-' in args.path and len(args.path) > 1:\n        sys.stderr.write('stdin input \"-\" must be the only path argument\\n')\n        sys.exit(1)\n\n    try:\n        # Use git to get the valid license expressions\n        repo = git.Repo(os.getcwd())\n        assert not repo.bare\n\n        # Initialize SPDX data\n        spdx = read_spdxdata(repo)\n\n        # Initialize the parser\n        parser = id_parser(spdx)\n\n    except SPDXException as se:\n        if se.el:\n            sys.stderr.write('%s: %s\\n' %(se.el.path, se.txt))\n        else:\n            sys.stderr.write('%s\\n' %se.txt)\n        sys.exit(1)\n\n    except Exception as ex:\n        sys.stderr.write('FAIL: %s\\n' %ex)\n        sys.stderr.write('%s\\n' %traceback.format_exc())\n        sys.exit(1)\n\n    try:\n        fname = args.exclude\n        if not fname:\n            fname = os.path.join(os.path.dirname(__file__), 'spdxexclude')\n        exclude_rules = read_exclude_file(fname)\n    except Exception as ex:\n        sys.stderr.write('FAIL: Reading exclude file %s: %s\\n' %(fname, ex))\n        sys.exit(1)\n\n    try:\n        if len(args.path) and args.path[0] == '-':\n            stdin = os.fdopen(sys.stdin.fileno(), 'rb')\n            parser.parse_lines(stdin, args.maxlines, '-')\n        else:\n            if args.path:\n                for p in args.path:\n                    if os.path.isfile(p):\n                        parser.parse_lines(open(p, 'rb'), args.maxlines, p)\n                    elif os.path.isdir(p):\n                        scan_git_subtree(repo.head.reference.commit.tree, p,\n                                         args.depth)\n                    else:\n                        sys.stderr.write('path %s does not exist\\n' %p)\n                        sys.exit(1)\n            else:\n                # Full git tree scan\n                scan_git_tree(repo.head.commit.tree, '.', args.depth)\n\n            ndirs = len(parser.spdx_dirs)\n            dirsok = 0\n            if ndirs:\n                for di in parser.spdx_dirs.values():\n                    if not di.missing:\n                        dirsok += 1\n\n            if args.verbose:\n                sys.stderr.write('\\n')\n                sys.stderr.write('License files:     %12d\\n' %spdx.license_files)\n                sys.stderr.write('Exception files:   %12d\\n' %spdx.exception_files)\n                sys.stderr.write('License IDs        %12d\\n' %len(spdx.licenses))\n                sys.stderr.write('Exception IDs      %12d\\n' %len(spdx.exceptions))\n                sys.stderr.write('\\n')\n                sys.stderr.write('Files excluded:    %12d\\n' %parser.excluded)\n                sys.stderr.write('Files checked:     %12d\\n' %parser.checked)\n                sys.stderr.write('Lines checked:     %12d\\n' %parser.lines_checked)\n                if parser.checked:\n                    pc = int(100 * parser.spdx_valid / parser.checked)\n                    sys.stderr.write('Files with SPDX:   %12d %3d%%\\n' %(parser.spdx_valid, pc))\n                sys.stderr.write('Files with errors: %12d\\n' %parser.spdx_errors)\n                if ndirs:\n                    sys.stderr.write('\\n')\n                    sys.stderr.write('Directories accounted: %8d\\n' %ndirs)\n                    pc = int(100 * dirsok / ndirs)\n                    sys.stderr.write('Directories complete:  %8d %3d%%\\n' %(dirsok, pc))\n\n            if ndirs and ndirs != dirsok and args.dirs:\n                if args.verbose:\n                    sys.stderr.write('\\n')\n                sys.stderr.write('Incomplete directories: SPDX in Files\\n')\n                for f in sorted(parser.spdx_dirs.keys()):\n                    di = parser.spdx_dirs[f]\n                    if di.missing:\n                        valid = di.total - di.missing\n                        pc = int(100 * valid / di.total)\n                        sys.stderr.write('    %-80s: %5d of %5d  %3d%%\\n' %(f, valid, di.total, pc))\n\n            if ndirs and ndirs != dirsok and args.files:\n                if args.verbose or args.dirs:\n                    sys.stderr.write('\\n')\n                sys.stderr.write('Files without SPDX:\\n')\n                for f in sorted(parser.spdx_dirs.keys()):\n                    di = parser.spdx_dirs[f]\n                    for f in sorted(di.files):\n                        sys.stderr.write('    %s\\n' %f)\n\n            sys.exit(0)\n\n    except Exception as ex:\n        sys.stderr.write('FAIL: %s\\n' %ex)\n        sys.stderr.write('%s\\n' %traceback.format_exc())\n        sys.exit(1)\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/spdxexclude",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n#\n# Patterns for excluding files and directories\n\n# Ignore the license directory and the licensing documentation which would\n# create lots of noise for no value\nLICENSES/\nlicense-rules.rst\n\n# Other files without copyrightable content\n/NEWS*\ntesting/\n\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/spelling.txt",
    "content": "# Originally from Debian's Lintian tool. Various false positives have been\n# removed, and various additions have been made as they've been discovered\n# in the kernel source.\n#\n# License: GPLv2\n#\n# The format of each line is:\n# mistake||correction\n#\nabandonning||abandoning\nabigious||ambiguous\nabitrary||arbitrary\nabitrate||arbitrate\nabnornally||abnormally\nabnrormal||abnormal\nabord||abort\naboslute||absolute\nabov||above\nabreviated||abbreviated\nabsense||absence\nabsolut||absolute\nabsoulte||absolute\nacccess||access\nacceess||access\naccelaration||acceleration\nacceleratoin||acceleration\naccelleration||acceleration\naccesing||accessing\naccesnt||accent\naccessable||accessible\naccesss||access\naccidentaly||accidentally\naccidentually||accidentally\nacclerated||accelerated\naccoding||according\naccomodate||accommodate\naccomodates||accommodates\naccordign||according\naccoring||according\naccout||account\naccquire||acquire\naccquired||acquired\naccross||across\naccumalate||accumulate\naccumalator||accumulator\nacessable||accessible\nacess||access\nacessing||accessing\nachitecture||architecture\nacient||ancient\nacitions||actions\nacitve||active\nacknowldegement||acknowledgment\nacknowledgement||acknowledgment\nackowledge||acknowledge\nackowledged||acknowledged\nacording||according\nactivete||activate\nactived||activated\nactualy||actually\nacumulating||accumulating\nacumulative||accumulative\nacumulator||accumulator\nacutally||actually\nadapater||adapter\naddional||additional\nadditionaly||additionally\nadditonal||additional\naddres||address\nadddress||address\naddreses||addresses\naddresss||address\naddrress||address\naditional||additional\naditionally||additionally\naditionaly||additionally\nadminstrative||administrative\nadress||address\nadresses||addresses\nadrresses||addresses\nadvertisment||advertisement\nadviced||advised\nafecting||affecting\nagaint||against\nagaist||against\naggreataon||aggregation\naggreation||aggregation\najust||adjust\nalbumns||albums\nalegorical||allegorical\nalgined||aligned\nalgorith||algorithm\nalgorithmical||algorithmically\nalgoritm||algorithm\nalgoritms||algorithms\nalgorithmn||algorithm\nalgorrithm||algorithm\nalgorritm||algorithm\naligment||alignment\nalignement||alignment\nallign||align\nalligned||aligned\nalllocate||allocate\nalloated||allocated\nallocatote||allocate\nallocatrd||allocated\nallocte||allocate\nallocted||allocated\nallpication||application\nalocate||allocate\nalogirhtms||algorithms\nalogrithm||algorithm\nalot||a lot\nalow||allow\nalows||allows\nalreay||already\nalredy||already\naltough||although\nalue||value\nambigious||ambiguous\nambigous||ambiguous\namoung||among\namout||amount\namplifer||amplifier\namplifyer||amplifier\nan union||a union\nan user||a user\nan userspace||a userspace\nan one||a one\nanalysator||analyzer\nang||and\nanniversery||anniversary\nannoucement||announcement\nanomolies||anomalies\nanomoly||anomaly\nanway||anyway\naplication||application\nappearence||appearance\napplicaion||application\nappliction||application\napplictions||applications\napplys||applies\nappplications||applications\nappropiate||appropriate\nappropriatly||appropriately\napproriate||appropriate\napproriately||appropriately\napropriate||appropriate\naquainted||acquainted\naquired||acquired\naquisition||acquisition\narbitary||arbitrary\narchitechture||architecture\narguement||argument\narguements||arguments\narithmatic||arithmetic\naritmetic||arithmetic\narne't||aren't\narraival||arrival\nartifical||artificial\nartillary||artillery\nasign||assign\nasser||assert\nassertation||assertion\nassertting||asserting\nassgined||assigned\nassiged||assigned\nassigment||assignment\nassigments||assignments\nassistent||assistant\nassocaited||associated\nassocating||associating\nassocation||association\nassocicated||associated\nassotiated||associated\nasssert||assert\nassum||assume\nassumtpion||assumption\nasuming||assuming\nasycronous||asynchronous\nasychronous||asynchronous\nasynchnous||asynchronous\nasynchronus||asynchronous\nasynchromous||asynchronous\nasymetric||asymmetric\nasymmeric||asymmetric\natleast||at least\natomatically||automatically\natomicly||atomically\natempt||attempt\natrributes||attributes\nattachement||attachment\nattatch||attach\nattched||attached\nattemp||attempt\nattemps||attempts\nattemping||attempting\nattepmpt||attempt\nattnetion||attention\nattruibutes||attributes\nauthentification||authentication\nauthenicated||authenticated\nautomaticaly||automatically\nautomaticly||automatically\nautomatize||automate\nautomatized||automated\nautomatizes||automates\nautonymous||autonomous\nauxillary||auxiliary\nauxilliary||auxiliary\navaiable||available\navaible||available\navailabe||available\navailabled||available\navailablity||availability\navailaible||available\navailale||available\navailavility||availability\navailble||available\navailiable||available\navailible||available\navalable||available\navaliable||available\naysnc||async\nbackgroud||background\nbackword||backward\nbackwords||backwards\nbahavior||behavior\nbakup||backup\nbaloon||balloon\nbaloons||balloons\nbandwith||bandwidth\nbanlance||balance\nbatery||battery\nbattey||battery\nbeacuse||because\nbecasue||because\nbecomming||becoming\nbecuase||because\nbeeing||being\nbefor||before\nbegining||beginning\nbeter||better\nbetweeen||between\nbianries||binaries\nbitmast||bitmask\nbitwiedh||bitwidth\nboardcast||broadcast\nborad||board\nboundry||boundary\nbrievely||briefly\nbrigde||bridge\nbroadcase||broadcast\nbroadcat||broadcast\nbufer||buffer\nbufufer||buffer\ncacluated||calculated\ncaculate||calculate\ncaculation||calculation\ncadidate||candidate\ncahces||caches\ncalender||calendar\ncalescing||coalescing\ncalle||called\ncallibration||calibration\ncallled||called\ncallser||caller\ncalucate||calculate\ncalulate||calculate\ncancelation||cancellation\ncancle||cancel\ncant||can't\ncant'||can't\ncanot||cannot\ncann't||can't\ncapabilites||capabilities\ncapabilties||capabilities\ncapabilty||capability\ncapabitilies||capabilities\ncapablity||capability\ncapatibilities||capabilities\ncapapbilities||capabilities\ncaputure||capture\ncarefuly||carefully\ncariage||carriage\ncatagory||category\ncehck||check\nchallange||challenge\nchallanges||challenges\nchache||cache\nchanell||channel\nchangable||changeable\nchanined||chained\nchannle||channel\nchannnel||channel\ncharachter||character\ncharachters||characters\ncharactor||character\ncharater||character\ncharaters||characters\ncharcter||character\nchcek||check\nchck||check\nchecksumed||checksummed\nchecksuming||checksumming\nchildern||children\nchilds||children\nchiled||child\nchked||checked\nchnage||change\nchnages||changes\nchnnel||channel\nchoosen||chosen\nchouse||chose\ncircumvernt||circumvent\nclaread||cleared\nclared||cleared\ncloseing||closing\nclustred||clustered\ncnfiguration||configuration\ncoexistance||coexistence\ncolescing||coalescing\ncollapsable||collapsible\ncolorfull||colorful\ncomand||command\ncomit||commit\ncommerical||commercial\ncomming||coming\ncomminucation||communication\ncommited||committed\ncommiting||committing\ncommitt||commit\ncommnunication||communication\ncommoditiy||commodity\ncomsume||consume\ncomsumer||consumer\ncomsuming||consuming\ncomaptible||compatible\ncompability||compatibility\ncompaibility||compatibility\ncomparsion||comparison\ncompatability||compatibility\ncompatable||compatible\ncompatibililty||compatibility\ncompatibiliy||compatibility\ncompatibilty||compatibility\ncompatiblity||compatibility\ncompetion||completion\ncompilant||compliant\ncompleatly||completely\ncompletition||completion\ncompletly||completely\ncomplient||compliant\ncomponnents||components\ncompoment||component\ncomppatible||compatible\ncompres||compress\ncompresion||compression\ncompresser||compressor\ncomression||compression\ncomsumed||consumed\ncomunicate||communicate\ncomunication||communication\nconbination||combination\nconditionaly||conditionally\nconditon||condition\ncondtion||condition\nconected||connected\nconector||connector\nconfigration||configuration\nconfigred||configured\nconfiguartion||configuration\nconfiguation||configuration\nconfigued||configured\nconfiguratoin||configuration\nconfiguraton||configuration\nconfiguretion||configuration\nconfigutation||configuration\nconider||consider\nconjuction||conjunction\nconnecetd||connected\nconnectinos||connections\nconnetor||connector\nconnnection||connection\nconnnections||connections\nconsistancy||consistency\nconsistant||consistent\ncontaines||contains\ncontaints||contains\ncontaisn||contains\ncontant||contact\ncontence||contents\ncontiguos||contiguous\ncontinious||continuous\ncontinous||continuous\ncontinously||continuously\ncontinueing||continuing\ncontraints||constraints\ncontruct||construct\ncontol||control\ncontoller||controller\ncontroled||controlled\ncontroler||controller\ncontroll||control\ncontruction||construction\ncontry||country\nconuntry||country\nconvertion||conversion\nconvertor||converter\nconvienient||convenient\nconvinient||convenient\ncorected||corrected\ncorreponding||corresponding\ncorreponds||corresponds\ncorrespoding||corresponding\ncotrol||control\ncound||could\ncouter||counter\ncoutner||counter\ncryptocraphic||cryptographic\ncunter||counter\ncurently||currently\ncylic||cyclic\ndafault||default\ndeactive||deactivate\ndeafult||default\ndeamon||daemon\ndebouce||debounce\ndecendant||descendant\ndecendants||descendants\ndecompres||decompress\ndecsribed||described\ndecription||description\ndectected||detected\ndefailt||default\ndeferal||deferral\ndeffered||deferred\ndefferred||deferred\ndefinate||definite\ndefinately||definitely\ndefiniation||definition\ndefintion||definition\ndefintions||definitions\ndefualt||default\ndefult||default\ndeintializing||deinitializing\ndeintialize||deinitialize\ndeintialized||deinitialized\ndeivce||device\ndelared||declared\ndelare||declare\ndelares||declares\ndelaring||declaring\ndelemiter||delimiter\ndelievered||delivered\ndemodualtor||demodulator\ndemension||dimension\ndependancies||dependencies\ndependancy||dependency\ndependant||dependent\ndependend||dependent\ndepreacted||deprecated\ndepreacte||deprecate\ndesactivate||deactivate\ndesciptor||descriptor\ndesciptors||descriptors\ndescripto||descriptor\ndescripton||description\ndescrition||description\ndescritptor||descriptor\ndesctiptor||descriptor\ndesriptor||descriptor\ndesriptors||descriptors\ndesination||destination\ndestionation||destination\ndestoried||destroyed\ndestory||destroy\ndestoryed||destroyed\ndestorys||destroys\ndestroied||destroyed\ndetabase||database\ndeteced||detected\ndetectt||detect\ndevelope||develop\ndevelopement||development\ndevelopped||developed\ndeveloppement||development\ndevelopper||developer\ndeveloppment||development\ndeveolpment||development\ndevided||divided\ndeviece||device\ndevision||division\ndiable||disable\ndiabled||disabled\ndicline||decline\ndictionnary||dictionary\ndidnt||didn't\ndiferent||different\ndifferrence||difference\ndiffrent||different\ndifferenciate||differentiate\ndiffrentiate||differentiate\ndifinition||definition\ndigial||digital\ndimention||dimension\ndimesions||dimensions\ndiconnected||disconnected\ndisabed||disabled\ndisble||disable\ndisgest||digest\ndisired||desired\ndispalying||displaying\ndissable||disable\ndiplay||display\ndirecton||direction\ndirecly||directly\ndireectly||directly\ndiregard||disregard\ndisassocation||disassociation\ndisapear||disappear\ndisapeared||disappeared\ndisappared||disappeared\ndisbale||disable\ndisbaled||disabled\ndisble||disable\ndisbled||disabled\ndisconnet||disconnect\ndiscontinous||discontinuous\ndisharge||discharge\ndisnabled||disabled\ndispertion||dispersion\ndissapears||disappears\ndissconect||disconnect\ndistiction||distinction\ndivisable||divisible\ndivsiors||divisors\ndsiabled||disabled\ndocuentation||documentation\ndocumantation||documentation\ndocumentaion||documentation\ndocumment||document\ndoesnt||doesn't\ndonwload||download\ndonwloading||downloading\ndorp||drop\ndosen||doesn\ndownlad||download\ndownlads||downloads\ndroped||dropped\ndroput||dropout\ndruing||during\ndyanmic||dynamic\ndynmaic||dynamic\neanable||enable\neanble||enable\neasilly||easily\necspecially||especially\nedditable||editable\neditting||editing\nefective||effective\neffectivness||effectiveness\nefficently||efficiently\nehther||ether\neigth||eight\nelementry||elementary\neletronic||electronic\nembeded||embedded\nenabledi||enabled\nenbale||enable\nenble||enable\nenchanced||enhanced\nencorporating||incorporating\nencrupted||encrypted\nencrypiton||encryption\nencryptio||encryption\nendianess||endianness\nenpoint||endpoint\nenhaced||enhanced\nenlightnment||enlightenment\nenqueing||enqueuing\nentires||entries\nentites||entities\nentrys||entries\nenocded||encoded\nenought||enough\nenterily||entirely\nenviroiment||environment\nenviroment||environment\nenvironement||environment\nenvironent||environment\neqivalent||equivalent\nequiped||equipped\nequivelant||equivalent\nequivilant||equivalent\neror||error\nerrorr||error\nerrror||error\nestbalishment||establishment\netsablishment||establishment\netsbalishment||establishment\nevalute||evaluate\nevalutes||evaluates\nevalution||evaluation\nexcecutable||executable\nexceded||exceeded\nexceds||exceeds\nexceeed||exceed\nexcellant||excellent\nexchnage||exchange\nexeceeded||exceeded\nexeceeds||exceeds\nexeed||exceed\nexeeds||exceeds\nexeuction||execution\nexistance||existence\nexistant||existent\nexixt||exist\nexlcude||exclude\nexlcusive||exclusive\nexmaple||example\nexpecially||especially\nexperies||expires\nexplicite||explicit\nexplicitely||explicitly\nexplict||explicit\nexplictely||explicitly\nexplictly||explicitly\nexpresion||expression\nexprimental||experimental\nextened||extended\nexteneded||extended\nextensability||extensibility\nextention||extension\nextenstion||extension\nextracter||extractor\nfaied||failed\nfaield||failed\nfaild||failed\nfailded||failed\nfailer||failure\nfaill||fail\nfailied||failed\nfaillure||failure\nfailue||failure\nfailuer||failure\nfailng||failing\nfaireness||fairness\nfalied||failed\nfaliure||failure\nfallbck||fallback\nfamilar||familiar\nfatser||faster\nfeauture||feature\nfeautures||features\nfetaure||feature\nfetaures||features\nfileystem||filesystem\nfimrware||firmware\nfimware||firmware\nfirmare||firmware\nfirmaware||firmware\nfirware||firmware\nfirwmare||firmware\nfinanize||finalize\nfindn||find\nfinilizes||finalizes\nfinsih||finish\nflusing||flushing\nfolloing||following\nfollowign||following\nfollowings||following\nfollwing||following\nfonud||found\nforseeable||foreseeable\nforse||force\nfortan||fortran\nforwardig||forwarding\nframbuffer||framebuffer\nframming||framing\nframwork||framework\nfrequence||frequency\nfrequncy||frequency\nfrequancy||frequency\nfrome||from\nfronend||frontend\nfucntion||function\nfuction||function\nfuctions||functions\nfullill||fulfill\nfuncation||function\nfuncion||function\nfunctionallity||functionality\nfunctionaly||functionally\nfunctionnality||functionality\nfunctonality||functionality\nfuntion||function\nfuntions||functions\nfurthur||further\nfuthermore||furthermore\nfutrue||future\ngatable||gateable\ngateing||gating\ngauage||gauge\ngaurenteed||guaranteed\ngeneriously||generously\ngenereate||generate\ngenereted||generated\ngenric||generic\nglobel||global\ngrabing||grabbing\ngrahical||graphical\ngrahpical||graphical\ngranularty||granularity\ngrapic||graphic\ngrranted||granted\nguage||gauge\nguarenteed||guaranteed\nguarentee||guarantee\nhalfs||halves\nhander||handler\nhandfull||handful\nhanlde||handle\nhanled||handled\nhappend||happened\nhardare||hardware\nharware||hardware\nhavind||having\nheirarchically||hierarchically\nheirarchy||hierarchy\nhelpfull||helpful\nhearbeat||heartbeat\nheterogenous||heterogeneous\nhexdecimal||hexadecimal\nhybernate||hibernate\nhierachy||hierarchy\nhierarchie||hierarchy\nhomogenous||homogeneous\nhowver||however\nhsould||should\nhypervior||hypervisor\nhypter||hyper\nidentidier||identifier\niligal||illegal\nilligal||illegal\nillgal||illegal\niomaped||iomapped\nimblance||imbalance\nimmeadiately||immediately\nimmedaite||immediate\nimmedate||immediate\nimmediatelly||immediately\nimmediatly||immediately\nimmidiate||immediate\nimmutible||immutable\nimpelentation||implementation\nimpementated||implemented\nimplemantation||implementation\nimplemenation||implementation\nimplementaiton||implementation\nimplementated||implemented\nimplemention||implementation\nimplementd||implemented\nimplemetation||implementation\nimplemntation||implementation\nimplentation||implementation\nimplmentation||implementation\nimplmenting||implementing\nincative||inactive\nincomming||incoming\nincompaitiblity||incompatibility\nincompatabilities||incompatibilities\nincompatable||incompatible\nincompatble||incompatible\ninconsistant||inconsistent\nincreas||increase\nincremeted||incremented\nincrment||increment\nincuding||including\ninculde||include\nindendation||indentation\nindended||intended\nindependant||independent\nindependantly||independently\nindepended||independent\nindiate||indicate\nindicat||indicate\ninexpect||inexpected\ninferface||interface\ninfinit||infinite\ninfomation||information\ninformatiom||information\ninformations||information\ninformtion||information\ninfromation||information\ningore||ignore\ninital||initial\ninitalized||initialized\ninitalised||initialized\ninitalise||initialize\ninitalize||initialize\ninitation||initiation\ninitators||initiators\ninitialiazation||initialization\ninitializationg||initialization\ninitializiation||initialization\ninitialze||initialize\ninitialzed||initialized\ninitialzing||initializing\ninitilization||initialization\ninitilize||initialize\ninitliaze||initialize\ninitilized||initialized\ninofficial||unofficial\ninrerface||interface\ninsititute||institute\ninstace||instance\ninstal||install\ninstanciate||instantiate\ninstanciated||instantiated\ninstuments||instruments\ninsufficent||insufficient\ninteface||interface\nintegreated||integrated\nintegrety||integrity\nintegrey||integrity\nintendet||intended\nintented||intended\ninteranl||internal\ninterchangable||interchangeable\ninterferring||interfering\ninterger||integer\nintergrated||integrated\nintermittant||intermittent\ninternel||internal\ninteroprability||interoperability\ninteruupt||interrupt\ninterupt||interrupt\ninterupts||interrupts\ninterrface||interface\ninterrrupt||interrupt\ninterrup||interrupt\ninterrups||interrupts\ninterruptted||interrupted\ninterupted||interrupted\nintiailized||initialized\nintial||initial\nintialisation||initialisation\nintialised||initialised\nintialise||initialise\nintialization||initialization\nintialized||initialized\nintialize||initialize\nintregral||integral\nintrerrupt||interrupt\nintrrupt||interrupt\nintterrupt||interrupt\nintuative||intuitive\ninavlid||invalid\ninvaid||invalid\ninvaild||invalid\ninvailid||invalid\ninvald||invalid\ninvalde||invalid\ninvalide||invalid\ninvalidiate||invalidate\ninvalud||invalid\ninvididual||individual\ninvokation||invocation\ninvokations||invocations\nireelevant||irrelevant\nirrelevent||irrelevant\nisnt||isn't\nisssue||issue\nissus||issues\niteraions||iterations\niternations||iterations\nitertation||iteration\nitslef||itself\njave||java\njeffies||jiffies\njumpimng||jumping\njuse||just\njus||just\nkown||known\nlangage||language\nlangauage||language\nlangauge||language\nlangugage||language\nlauch||launch\nlayed||laid\nlegnth||length\nleightweight||lightweight\nlengh||length\nlenght||length\nlenth||length\nlesstiff||lesstif\nlibaries||libraries\nlibary||library\nlibrairies||libraries\nlibraris||libraries\nlicenceing||licencing\nlimted||limited\nlogaritmic||logarithmic\nloggging||logging\nloggin||login\nlogile||logfile\nloobpack||loopback\nloosing||losing\nlosted||lost\nmaangement||management\nmachinary||machinery\nmaibox||mailbox\nmaintainance||maintenance\nmaintainence||maintenance\nmaintan||maintain\nmakeing||making\nmailformed||malformed\nmalplaced||misplaced\nmalplace||misplace\nmanagable||manageable\nmanagament||management\nmanagment||management\nmangement||management\nmanger||manager\nmanoeuvering||maneuvering\nmanufaucturing||manufacturing\nmappping||mapping\nmaping||mapping\nmatchs||matches\nmathimatical||mathematical\nmathimatic||mathematic\nmathimatics||mathematics\nmaximium||maximum\nmaxium||maximum\nmechamism||mechanism\nmeetign||meeting\nmemeory||memory\nmemmber||member\nmemoery||memory\nmemroy||memory\nment||meant\nmergable||mergeable\nmesage||message\nmessags||messages\nmessgaes||messages\nmesssage||message\nmesssages||messages\nmetdata||metadata\nmicropone||microphone\nmicroprocesspr||microprocessor\nmigrateable||migratable\nmillenium||millennium\nmilliseonds||milliseconds\nminium||minimum\nminimam||minimum\nminimun||minimum\nminiumum||minimum\nminumum||minimum\nmisalinged||misaligned\nmiscelleneous||miscellaneous\nmisformed||malformed\nmispelled||misspelled\nmispelt||misspelt\nmising||missing\nmismactch||mismatch\nmissign||missing\nmissmanaged||mismanaged\nmissmatch||mismatch\nmisssing||missing\nmiximum||maximum\nmmnemonic||mnemonic\nmnay||many\nmodfiy||modify\nmodifer||modifier\nmodul||module\nmodulues||modules\nmomery||memory\nmemomry||memory\nmonitring||monitoring\nmonochorome||monochrome\nmonochromo||monochrome\nmonocrome||monochrome\nmopdule||module\nmroe||more\nmultipler||multiplier\nmulitplied||multiplied\nmultidimensionnal||multidimensional\nmultipe||multiple\nmultple||multiple\nmumber||number\nmuticast||multicast\nmutilcast||multicast\nmutiple||multiple\nmutli||multi\nnams||names\nnavagating||navigating\nnead||need\nneccecary||necessary\nneccesary||necessary\nneccessary||necessary\nnecesary||necessary\nneded||needed\nnegaive||negative\nnegoitation||negotiation\nnegotation||negotiation\nnerver||never\nnescessary||necessary\nnessessary||necessary\nnoticable||noticeable\nnotication||notification\nnotications||notifications\nnotifcations||notifications\nnotifed||notified\nnotity||notify\nnubmer||number\nnumebr||number\nnumner||number\nnunber||number\nobtaion||obtain\nobusing||abusing\noccassionally||occasionally\noccationally||occasionally\noccurance||occurrence\noccurances||occurrences\noccurd||occurred\noccured||occurred\noccurence||occurrence\noccure||occurred\noccuring||occurring\noffser||offset\noffet||offset\nofflaod||offload\noffloded||offloaded\noffseting||offsetting\nomited||omitted\nomiting||omitting\nomitt||omit\nommiting||omitting\nommitted||omitted\nonself||oneself\nony||only\nopenning||opening\noperatione||operation\nopertaions||operations\nopportunies||opportunities\noptionnal||optional\noptmizations||optimizations\norientatied||orientated\norientied||oriented\norignal||original\noriginial||original\notherise||otherwise\nouput||output\noustanding||outstanding\noveraall||overall\noverhread||overhead\noverlaping||overlapping\noveflow||overflow\noverflw||overflow\noverlfow||overflow\noveride||override\noverrided||overridden\noverriden||overridden\noverrrun||overrun\noverun||overrun\noverwritting||overwriting\noverwriten||overwritten\npacakge||package\npachage||package\npackacge||package\npackege||package\npackge||package\npacktes||packets\npakage||package\npaket||packet\npallette||palette\npaln||plan\nparamameters||parameters\nparamaters||parameters\nparamater||parameter\nparametes||parameters\nparametised||parametrised\nparamter||parameter\nparamters||parameters\nparmaters||parameters\nparticuarly||particularly\nparticularily||particularly\npartion||partition\npartions||partitions\npartiton||partition\npased||passed\npassin||passing\npathes||paths\npattrns||patterns\npecularities||peculiarities\npeformance||performance\npeforming||performing\npeice||piece\npendantic||pedantic\npeprocessor||preprocessor\nperfomance||performance\nperfoming||performing\nperfomring||performing\nperiperal||peripheral\nperipherial||peripheral\npermissons||permissions\nperoid||period\npersistance||persistence\npersistant||persistent\nphoneticly||phonetically\nplalform||platform\nplatfoem||platform\nplatfrom||platform\nplattform||platform\npleaes||please\nploting||plotting\nplugable||pluggable\npoinnter||pointer\npointeur||pointer\npoiter||pointer\nposible||possible\npositon||position\npossibilites||possibilities\npotocol||protocol\npowerfull||powerful\npramater||parameter\npreamle||preamble\npreample||preamble\npreapre||prepare\npreceeded||preceded\npreceeding||preceding\npreceed||precede\nprecendence||precedence\nprecission||precision\npreemptable||preemptible\nprefered||preferred\nprefferably||preferably\nprefitler||prefilter\npreform||perform\npremption||preemption\nprepaired||prepared\nprepate||prepare\npreperation||preparation\npreprare||prepare\npressre||pressure\npresuambly||presumably\npreviosuly||previously\nprevisously||previously\nprimative||primitive\nprincliple||principle\npriorty||priority\nprivilaged||privileged\nprivilage||privilege\npriviledge||privilege\npriviledges||privileges\nprivleges||privileges\nprobaly||probably\nprocceed||proceed\nproccesors||processors\nprocesed||processed\nproces||process\nprocesing||processing\nprocessessing||processing\nprocessess||processes\nprocesspr||processor\nprocesssed||processed\nprocesssing||processing\nprocteted||protected\nprodecure||procedure\nprogamming||programming\nprogams||programs\nprogess||progress\nprogramable||programmable\nprogramers||programmers\nprogramm||program\nprogramms||programs\nprogres||progress\nprogresss||progress\nprohibitted||prohibited\nprohibitting||prohibiting\npromiscous||promiscuous\npromps||prompts\npronnounced||pronounced\nprononciation||pronunciation\npronouce||pronounce\npronunce||pronounce\npropery||property\npropigate||propagate\npropigation||propagation\npropogation||propagation\npropogate||propagate\nprosess||process\nprotable||portable\nprotcol||protocol\nprotecion||protection\nprotedcted||protected\nprotocoll||protocol\npromixity||proximity\npsudo||pseudo\npsuedo||pseudo\npsychadelic||psychedelic\npurgable||purgeable\npwoer||power\nqueing||queuing\nquering||querying\nqueus||queues\nrandomally||randomly\nraoming||roaming\nreasearcher||researcher\nreasearchers||researchers\nreasearch||research\nreceieve||receive\nrecepient||recipient\nrecevied||received\nreceving||receiving\nrecievd||received\nrecieved||received\nrecieve||receive\nreciever||receiver\nrecieves||receives\nrecieving||receiving\nrecogniced||recognised\nrecognizeable||recognizable\nrecommanded||recommended\nrecyle||recycle\nredircet||redirect\nredirectrion||redirection\nredundacy||redundancy\nreename||rename\nrefcounf||refcount\nrefence||reference\nrefered||referred\nreferenace||reference\nrefering||referring\nrefernces||references\nrefernnce||reference\nrefrence||reference\nregisted||registered\nregisterd||registered\nregisteration||registration\nregisteresd||registered\nregisterred||registered\nregistes||registers\nregistraration||registration\nregsiter||register\nregster||register\nregualar||regular\nreguator||regulator\nregulamentations||regulations\nreigstration||registration\nreleated||related\nrelevent||relevant\nreloade||reload\nremoote||remote\nremore||remote\nremoveable||removable\nrepectively||respectively\nreplacable||replaceable\nreplacments||replacements\nreplys||replies\nreponse||response\nrepresentaion||representation\nreqeust||request\nreqister||register\nrequed||requeued\nrequestied||requested\nrequiere||require\nrequirment||requirement\nrequred||required\nrequried||required\nrequst||request\nrequsted||requested\nreregisteration||reregistration\nreseting||resetting\nreseved||reserved\nreseverd||reserved\nresizeable||resizable\nresouce||resource\nresouces||resources\nresoures||resources\nresponce||response\nresrouce||resource\nressizes||resizes\nressource||resource\nressources||resources\nrestesting||retesting\nresumbmitting||resubmitting\nretransmited||retransmitted\nretreived||retrieved\nretreive||retrieve\nretreiving||retrieving\nretrive||retrieve\nretrived||retrieved\nretrun||return\nretun||return\nretuned||returned\nreudce||reduce\nreuest||request\nreuqest||request\nreutnred||returned\nrevsion||revision\nrmeoved||removed\nrmeove||remove\nrmeoves||removes\nrountine||routine\nroutins||routines\nrquest||request\nruning||running\nrunned||ran\nrunnnig||running\nrunnning||running\nruntine||runtime\nsacrifying||sacrificing\nsafly||safely\nsafty||safety\nsavable||saveable\nscaleing||scaling\nscaned||scanned\nscaning||scanning\nscarch||search\nschdule||schedule\nseach||search\nsearchs||searches\nsecion||section\nsecquence||sequence\nsecund||second\nsegement||segment\nseleted||selected\nsemaphone||semaphore\nsenario||scenario\nsenarios||scenarios\nsentivite||sensitive\nseparatly||separately\nsepcify||specify\nseperated||separated\nseperately||separately\nseperate||separate\nseperatly||separately\nseperator||separator\nsepperate||separate\nseqeunce||sequence\nseqeuncer||sequencer\nseqeuencer||sequencer\nsequece||sequence\nsequemce||sequence\nsequencial||sequential\nserivce||service\nserveral||several\nservive||service\nsetts||sets\nsettting||setting\nshapshot||snapshot\nshoft||shift\nshotdown||shutdown\nshoud||should\nshouldnt||shouldn't\nshoule||should\nshrinked||shrunk\nsiginificantly||significantly\nsignabl||signal\nsignificanly||significantly\nsimilary||similarly\nsimiliar||similar\nsimlar||similar\nsimliar||similar\nsimpified||simplified\nsimultanous||simultaneous\nsingaled||signaled\nsingal||signal\nsinged||signed\nsleeped||slept\nsliped||slipped\nsoftwade||software\nsoftwares||software\nsoley||solely\nsouce||source\nspeach||speech\nspecfic||specific\nspecfield||specified\nspeciefied||specified\nspecifc||specific\nspecifed||specified\nspecificatin||specification\nspecificaton||specification\nspecificed||specified\nspecifing||specifying\nspecifiy||specify\nspecifiying||specifying\nspeficied||specified\nspeicify||specify\nspeling||spelling\nspinlcok||spinlock\nspinock||spinlock\nsplitted||split\nspreaded||spread\nspurrious||spurious\nsructure||structure\nstablilization||stabilization\nstaically||statically\nstaion||station\nstandardss||standards\nstandartization||standardization\nstandart||standard\nstandy||standby\nstardard||standard\nstaticly||statically\nstatuss||status\nstoped||stopped\nstoping||stopping\nstoppped||stopped\nstraming||streaming\nstruc||struct\nstructres||structures\nstuct||struct\nstrucuture||structure\nstucture||structure\nsturcture||structure\nsubdirectoires||subdirectories\nsuble||subtle\nsubstract||subtract\nsubmited||submitted\nsubmition||submission\nsucceded||succeeded\nsuceed||succeed\nsuccesfully||successfully\nsuccesful||successful\nsuccessed||succeeded\nsuccessfull||successful\nsuccessfuly||successfully\nsucessfully||successfully\nsucessful||successful\nsucess||success\nsuperflous||superfluous\nsuperseeded||superseded\nsuplied||supplied\nsuported||supported\nsuport||support\nsupportet||supported\nsuppored||supported\nsupportin||supporting\nsuppoted||supported\nsuppported||supported\nsuppport||support\nsupprot||support\nsupress||suppress\nsurpressed||suppressed\nsurpresses||suppresses\nsusbsystem||subsystem\nsuspeneded||suspended\nsuspsend||suspend\nsuspicously||suspiciously\nswaping||swapping\nswitchs||switches\nswith||switch\nswithable||switchable\nswithc||switch\nswithced||switched\nswithcing||switching\nswithed||switched\nswithing||switching\nswtich||switch\nsyfs||sysfs\nsymetric||symmetric\nsynax||syntax\nsynchonized||synchronized\nsychronization||synchronization\nsynchronuously||synchronously\nsyncronize||synchronize\nsyncronized||synchronized\nsyncronizing||synchronizing\nsyncronus||synchronous\nsyste||system\nsytem||system\nsythesis||synthesis\ntaht||that\ntained||tainted\ntansmit||transmit\ntargetted||targeted\ntargetting||targeting\ntaskelt||tasklet\nteh||the\ntemorary||temporary\ntemproarily||temporarily\ntemperture||temperature\nthead||thread\ntherfore||therefore\nthier||their\nthreds||threads\nthreee||three\nthreshhold||threshold\nthresold||threshold\nthrought||through\ntrackling||tracking\ntroughput||throughput\ntrys||tries\nthses||these\ntiggers||triggers\ntiggered||triggered\ntipically||typically\ntimeing||timing\ntimout||timeout\ntmis||this\ntoogle||toggle\ntorerable||tolerable\ntorlence||tolerance\ntraget||target\ntraking||tracking\ntramsmitted||transmitted\ntramsmit||transmit\ntranasction||transaction\ntranceiver||transceiver\ntranfer||transfer\ntranmission||transmission\ntranscevier||transceiver\ntransciever||transceiver\ntransferd||transferred\ntransfered||transferred\ntransfering||transferring\ntransision||transition\ntransistioned||transitioned\ntransmittd||transmitted\ntransormed||transformed\ntrasfer||transfer\ntrasmission||transmission\ntreshold||threshold\ntriggerd||triggered\ntrigerred||triggered\ntrigerring||triggering\ntrun||turn\ntunning||tuning\nture||true\ntyep||type\nudpate||update\nuesd||used\nuknown||unknown\nusccess||success\nuncommited||uncommitted\nuncompatible||incompatible\nunconditionaly||unconditionally\nundeflow||underflow\nunderun||underrun\nunecessary||unnecessary\nunexecpted||unexpected\nunexepected||unexpected\nunexpcted||unexpected\nunexpectd||unexpected\nunexpeted||unexpected\nunexpexted||unexpected\nunfortunatelly||unfortunately\nunifiy||unify\nuniterrupted||uninterrupted\nuninterruptable||uninterruptible\nunintialized||uninitialized\nunitialized||uninitialized\nunkmown||unknown\nunknonw||unknown\nunknouwn||unknown\nunknow||unknown\nunkown||unknown\nunamed||unnamed\nuneeded||unneeded\nunneded||unneeded\nunneccecary||unnecessary\nunneccesary||unnecessary\nunneccessary||unnecessary\nunnecesary||unnecessary\nunneedingly||unnecessarily\nunnsupported||unsupported\nunmached||unmatched\nunprecise||imprecise\nunregester||unregister\nunresgister||unregister\nunrgesiter||unregister\nunsinged||unsigned\nunstabel||unstable\nunsolicitied||unsolicited\nunsuccessfull||unsuccessful\nunsuported||unsupported\nuntill||until\nununsed||unused\nunuseful||useless\nunvalid||invalid\nupate||update\nupsupported||unsupported\nuseable||usable\nusefule||useful\nusefull||useful\nusege||usage\nusera||users\nusualy||usually\nusupported||unsupported\nutilites||utilities\nutillities||utilities\nutilties||utilities\nutiltity||utility\nutitity||utility\nutitlty||utility\nvaid||valid\nvaild||valid\nvalide||valid\nvariantions||variations\nvarible||variable\nvarient||variant\nvaule||value\nverbse||verbose\nveify||verify\nverfication||verification\nveriosn||version\nverisons||versions\nverison||version\nverson||version\nvicefersa||vice-versa\nvirtal||virtual\nvirtaul||virtual\nvirtiual||virtual\nvisiters||visitors\nvitual||virtual\nvunerable||vulnerable\nwakeus||wakeups\nwas't||wasn't\nwathdog||watchdog\nwating||waiting\nwiat||wait\nwether||whether\nwhataver||whatever\nwhcih||which\nwhenver||whenever\nwheter||whether\nwhe||when\nwierd||weird\nwiil||will\nwirte||write\nwithing||within\nwnat||want\nwont||won't\nworkarould||workaround\nwriteing||writing\nwritting||writing\nwtih||with\nzombe||zombie\nzomebie||zombie\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/scripts/typedefs.txt",
    "content": "# SPDX-License-Identifier: GPL-2.0-or-later\n\nfd_set\nJim_Cmd\nJim_CmdProc\nJim_DelCmdProc\nJim_Interp\nJim_Obj\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/st7_dtc_as/st7_dtc_as",
    "content": "#!/bin/sh\nexec perl \"$0.pl\" $*\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/st7_dtc_as/st7_dtc_as.pl",
    "content": "#!/bin/perl\n#***************************************************************************\n#*   Copyright (C) 2008 Lou Deluxe                                         *\n#*   lou.openocd012@fixit.nospammail.net                                   *\n#*                                                                         *\n#*   This program is free software; you can redistribute it and/or modify  *\n#*   it under the terms of the GNU General Public License as published by  *\n#*   the Free Software Foundation; either version 2 of the License, or     *\n#*   (at your option) any later version.                                   *\n#*                                                                         *\n#*   This program is distributed in the hope that it will be useful,       *\n#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\n#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\n#*   GNU General Public License for more details.                          *\n#*                                                                         *\n#*   You should have received a copy of the GNU General Public License     *\n#*   along with this program; if not, write to the                         *\n#*   Free Software Foundation, Inc.,                                       *\n#*   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *\n#***************************************************************************\n\n# A rudimentary assembler for DTC code.\n# It is not robust, by any means, but it gets the job done.\n\n{package DTC_as;\n\nmy($i);\t# for later loop to generate reverse lookup\n\nsub new {\n\tmy($self) = bless{};\n\n\t$self->{'pagewidth'} = 60;\n\t$self;\n}\n\n\n\n%status_bit_arg = (\n\t'STOP' => 0x01,\n\t'ERROR' => 0x02,\n);\n\n%cp_arg = (\n\t'A=>X' => 0x00,\n\t'A<X' => 0x01,\n\t'CARRY' => 0x02,\n\t'ALWAYS' => 0x03,\n\t'ADR_BUFFER0=>CMP0' => 0x04,\n\t'ADR_BUFFER0<CMP0' => 0x05,\n\t'ADR_BUFFER1=>CMP1' => 0x06,\n\t'ADR_BUFFER1<CMP1' => 0x07,\n);\n\n%shift_unit_arg = (\n\t'CARD' => 0x00,\n\t'MPEG' => 0x08,\n);\n\n%shift_pin_arg = (\n\t'PIN0=>IN' => 0x00,\n\t'PIN1=>IN' => 0x04,\n\t'OUT=>PIN0' => 0x01,\n\t'OUT=>PIN1' => 0x03,\n);\n\n@ld_arg = (\n\t'<Y>',\n\t'X',\n\t'Y',\n\t'MASK',\n\t'ADR_BUFFER00',\n\t'ADR_BUFFER01',\n\t'ADR_BUFFER10',\n\t'ADR_BUFFER11',\n\t'CMP00',\n\t'CMP01',\n\t'CMP10',\n\t'CMP11',\n\t'DATA_FLASH',\n\t'CTRL_FCI',\n\t'CTRL_CARD',\n\t'CTRL_MPEG',\n\t'DR_PARALLEL',\n\t'DDR_PARALLEL',\n\t'OR_PARALLEL',\n\t'DR_CARD',\n\t'DDR_CARD',\n\t'OR_CARD',\n\t'SHIFT_CARD',\n\t'DR_MPEG',\n\t'DDR_MPEG',\n\t'OR_MPEG',\n\t'SHIFT_MPEG',\n\t'DATA_BUFFER0',\n\t'DATA_BUFFER1',\n\t'ECC_CRC',\n\t'TMP_ECC',\n\t'BUFFER_MNGT'\n);\n\nfor($i = 0; $i < @ld_arg; $i++) {\n\t$ld_arg{$ld_arg[$i]} = $i;\n}\n\n\n# ADDER8 / SUB8\nsub alu8 {\n\tmy($self) = shift;\n\tmy($operand, $i) = shift;\n\n\tif(defined($ld_arg{$operand})) {\n\t\t$i = $ld_arg{$operand};\n\n\t\tif($i > 0x00 && $i < 0x04) {\n\t\t\treturn(($i - 0x01) << 3);\n\t\t}\n\t}\n\n\treturn undef;\n}\n\n# ADDER16 / SUB16\nsub alu16 {\n\tmy($self) = shift;\n\tmy($operand, $i) = shift;\n\n\t$operand .= '0';\n\n\tif(defined($ld_arg{$operand})) {\n\t\t$i = $ld_arg{$operand};\n\n\t\tif($i > 0x03 && $i < 0x0c) {\n\t\t\treturn(($i - 0x04) << 2);\n\t\t}\n\t}\n\n\treturn undef;\n}\n\n\n# BSET / BCLR\nsub bsetorclr {\n\tmy($self) = shift;\n\tmy($ret);\n\t\n\tif(@_ < 1) {\n\t\treturn undef;\n\t}\n\t$ret = $_[0];\n\n\tif(($ret < 0) || ($ret > 3)) {\n\t\treturn undef;\n\t}\n\n\treturn $ret;\n}\n\n\n# Opcode lookup table\n%op = (\n\t'NOP' => [\n\t\t0x0,\n\t],\n\t'SEC' => [\n\t\t0x1,\n\t],\n\t'CLC' => [\n\t\t0x2,\n\t],\n\t'RET' => [\n\t\t0x3,\n\t],\n\t'STATUS' => [\n\t\t0x4,\n\t\tsub {\n\t\t\tmy($self) = shift;\n\t\t\tmy($ret, $i);\n\n\t\t\tfor $i (@_) {\n\t\t\t\tif(!defined($status_bit_arg{\"\\U$i\"})) {\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\n\t\t\t\t$ret |= $status_bit_arg{\"\\U$i\"};\n\t\t\t}\n\t\t\tif($ret < 1) {\n\t\t\t\treturn undef;\n\t\t\t}\n\n\t\t\treturn $ret;\n\t\t}\n\t],\n\t'CP' => [\n\t\t0x8,\n\t\tsub {\n\t\t\tmy($self) = shift;\n\t\t\tif((@_ != 1) || (!defined($cp_arg{\"\\U$_[0]\"}))) {\n\t\t\t\treturn undef;\n\t\t\t}\n\t\t\treturn($cp_arg{\"\\U$_[0]\"});\n\t\t}\n\t],\n\t'SHIFT' => [\n\t\t0x10,\n\t\tsub {\n\t\t\tmy($self) = shift;\n\t\t\tmy($ret, $i);\n\t\t\t\n\t\t\tif((@_ < 2) || (!defined($shift_unit_arg{\"\\U$_[0]\"}))) {\n\t\t\t\treturn undef;\n\t\t\t}\n\t\t\t$ret = $shift_unit_arg{\"\\U$_[0]\"};\n\t\t\tshift;\n\n\t\t\tfor $i (@_) {\n\t\t\t\tif(!defined($shift_pin_arg{\"\\U$i\"})) {\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\n\t\t\t\t$ret |= $shift_pin_arg{\"\\U$i\"};\n\t\t\t}\n\n\t\t\treturn $ret;\n\t\t}\n\t],\n\t'SUB8' => [\n\t\t0x24,\n\t\t\\&alu8\n\t],\n\t'ADDER8' => [\n\t\t0x25,\n\t\t\\&alu8\n\t],\n\t'SUB16' => [\n\t\t0x26,\n\t\t\\&alu16\n\t],\n\t'ADDER16' => [\n\t\t0x27,\n\t\t\\&alu16\n\t],\n\t'BCLR' => [\n\t\t0x28,\n\t\t\\&bsetorclr\n\t],\n\t'BSET' => [\n\t\t0x38,\n\t\t\\&bsetorclr\n\t],\n\t'REVERSE' => [\n\t\t0x30,\n\t],\n\t'XOR' => [\n\t\t0x31,\n\t],\n\t'AND' => [\n\t\t0x32,\n\t],\n\t'EXCHANGE' => [\n\t\t0x33,\n\t],\n\t'DECY' => [\n\t\t0x3c,\n\t],\n\t'INCY' => [\n\t\t0x3d,\n\t],\n\t'JP' => [\n\t\t0x40,\n\t\tsub {\n\t\t\tmy($self) = shift;\n\t\t\tmy($i);\n\n\t\t\tif(@_ != 1) {\n\t\t\t\treturn undef;\n\t\t\t}\n\t\t\t$i = $_[0];\n\t\t\tif(!defined($self->{'label'}{$i})) {\n\t\t\t\t$i =~ s/^://o;\n\t\t\t\tif(!defined($self->{'label'}{$i})) {\n\t\t\t\t\t# not a defined label\n\t\t\t\t\tundef $i;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(defined($i)) {\n\t\t\t\t$i = $self->{'label'}{$i} - $self->{'pc'};\n\t\t\t} else {\n\t\t\t\t$i = $_[0];\n\t\t\t}\n\n\t\t\tif($i =~ m/^([+-]?\\d+)$/) {\n\t\t\t\t$i = 0 + $1;\n\t\t\t\tif(($i > 31) || ($i < -31)) {\n\t\t\t\t\twarn \"relative jump ($i) out of range\";\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\t\t\t\tif($i < 0) {\n\t\t\t\t\treturn(0x20 - $1);\n\t\t\t\t} else {\n\t\t\t\t\treturn(0x00 + $1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn undef;\n\t\t}\n\t],\n\t'BRANCH' => [\n\t\t0x60,\n\t],\n\t'LD' => [\n\t\t0x80,\n\t\tsub {\n\t\t\tmy($self) = shift;\n\t\t\tmy($i);\n\n#\t\t\tprint STDERR join(\", \", LD, @_), \"\\n\";\n\n\t\t\tif(@_ == 1) {\n\t\t\t\t$_[1] = 'A';\n\t\t\t}\n\t\t\tif(@_ != 2) {\n\t\t\t\treturn undef;\n\t\t\t}\n\n\t\t\t\t\n\t\t\tif($_[0] =~ m/^([ML])S[BN]$/o) {\n\t\t\t\t# MSB/LSB aka MSN/LSN\n\t\t\t\tif($1 eq 'L') {\n\t\t\t\t\t$_[0] = 'A.L';\n\t\t\t\t} else {\n\t\t\t\t\t$_[0] = 'A.H';\n\t\t\t\t}\n\t\t\t}\n\t\t\tif($_[0] =~ m/^A\\.([LH])$/o) {\n\t\t\t\t# A.L/A.H\n\t\t\t\tmy($islsb) = ($1 eq 'L') ? 1 : 0;\n\t\t\t\t$i = $_[1];\n\t\t\t\tif($i =~ s/^0x([0-9a-fA-F])$/hex($1)/e) {\n#\t\t\t\t\tprint \"$i looks hex\\n\";\n\t\t\t\t} elsif($i =~ m/^\\d+$/) {\n#\t\t\t\t\tprint \"$i looks decimal\\n\";\n\t\t\t\t} elsif(defined($self->{'label'}{$i})) {\n#\t\t\t\t\tprint \"label match for $i ($self->{'label'}{$i})\\n\";\n\t\t\t\t\t$i = $self->{'label'}{$i};\n#\t\t\t\t\tprint \"\\$i=$i\\n\";\n#\t\t\t\t\tprint \"\\$islsb=$islsb\\n\";\n\t\t\t\t\tif($islsb) {\n\t\t\t\t\t\t$i = ($i & 0xf);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$i = ($i >> 4) & 0xf;\n\t\t\t\t\t}\n#\t\t\t\t\tprint \"\\$i=$i\\n\";\n\t\t\t\t} else {\n\t\t\t\t\tprint \"no label match for $i\\n\";\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\t\t\t\tif(($i < 0) || ($i > 0xf)) {\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\t\t\t\tif($islsb) {\n\t\t\t\t\t$i |= 0x10;\n\t\t\t\t};\n\t\t\t\treturn(0x20 | $i);\n\t\t\t} elsif($_[0] eq 'A') {\n\t\t\t\tif(!defined($ld_arg{$_[1]})) {\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\t\t\t\treturn(0x40 | $ld_arg{$_[1]});\n\t\t\t} elsif($_[1] eq 'A') {\n\t\t\t\tif(!defined($ld_arg{$_[0]})) {\n\t\t\t\t\treturn undef;\n\t\t\t\t}\n\t\t\t\treturn(0x00 | $ld_arg{$_[0]});\n\t\t\t}\n\n\t\t\treturn undef;\n\t\t}\n\t],\n);\n\n$op{'JR'} = $op{'JP'};\n\n\nsub pass {\n\tmy($self, $ifh, $ofh, $passnum) = @_;\n\n\t# passnum=0 for plain parsing pass to populate label values\n\t# passnum=1 for actual pass to assemble\n\n\tmy($line, $oline, $opcd);\n\n\tif($passnum == 0) {\n\t\tdelete($self->{'label'});\n\t\tdelete($self->{'binary'});\n\t\tdelete($self->{'ENTRY'});\n\t\tdelete($self->{'LUT'});\n\t}\n\n\tseek($ifh, 0, 0); # rewind\n\t$self->{'pc'} = 0;\n\t$self->{'line_number'} = 0;\n\twhile(defined($line = <$ifh>)) {\n\t\t$self->{'line_number'}++;\n\t\t$line =~ s/\\s+$//so;\n\t\t$oline = $line;\n\t\t$line =~ s/;.*//o;\n\t\t$line =~ s/^\\s+//o;\n\t\t@_ = split(/[\\s,]+/, $line);\n\n\t\tundef($opcd);\n\n\t\tif(@_ > 0) {\n\n\t\t\tif(\n\t\t\t\t($_[0] =~ s/^://o)\n\t\t\t\t||\n\t\t\t\t($_[0] =~ s/:$//o)\n\t\t\t) {\n\t\t\t\tif($passnum == 0) {\n\t\t\t\t\tif(defined($self->{'label'}{$_[0]})) {\n\t\t\t\t\t\tdie \"label redefinition for \\\"$_[0]\\\" in line $self->{'line_number'}\";\n\t\t\t\t\t}\n\t\t\t\t\t$self->{'label'}{$_[0]} = $self->{'pc'};\n\t\t\t\t}\n\t\t\t\tshift(@_);\n\t\t\t}\n\n\t\t\tif(@_ > 0) {\n\t\t\t\tif($passnum == 1) {\n\t\t\t\t\tif((@_ == 3) && ($_[1] eq '=')) {\n\t\t\t\t\t\t# convert this = that to LD \n\t\t\t\t\t\t$_[1] = $_[0];\n\t\t\t\t\t\t$_[0] = 'LD';\n\t\t\t\t\t}\n\t\t\t\t\telsif((@_ == 3) && ($_[1] eq '+=')) {\n\t\t\t\t\t\t# convert this += that to ADDER8 or ADDER16\n\t\t\t\t\t\tif($_[0] eq 'A') {\n\t\t\t\t\t\t\t@_ = ('ADDER8', $_[2]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telsif($_[2] eq 'X') {\n\t\t\t\t\t\t\t@_ = ('ADDER16', $_[0]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telsif((@_ == 3) && ($_[1] eq '-=')) {\n\t\t\t\t\t\t# convert this -= that to ADDER8 or ADDER16\n\t\t\t\t\t\tif($_[0] eq 'A') {\n\t\t\t\t\t\t\t@_ = ('SUB8', $_[2]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telsif($_[2] eq 'X') {\n\t\t\t\t\t\t\t@_ = ('SUB16', $_[0]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telsif((@_ == 1) && ($_[0] =~ m/^(B((SET)|(CLR)))([1-4])$/oi)) {\n\t\t\t\t\t\t# convert BSETn or BCLRn to BSET n-1 or BCLR n-1\n\t\t\t\t\t\t$_[0] = $1;\n\t\t\t\t\t\t$_[1] = $5 - 1;\n\t\t\t\t\t}\n\n\t\t\t\t\t$op = \"\\U$_[0]\";\n\t\t\t\t\tif(!defined($op{$op})) {\n\t\t\t\t\t\tdie \"unknown instruction: $op in line $self->{'line_number'}\";\n\t\t\t\t\t}\n\t\t\t\t\tshift(@_);\n\n\t\t\t\t\t$op = $op{$op};\n\t\t\t\t\t$sub = $op->[1];\n\t\t\t\t\tif(defined($sub)) {\n\t\t\t\t\t\t$opcd = &$sub($self, @_);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$opcd = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!defined($opcd)) {\n\t\t\t\t\t\tdie \"bad argument(s) in line $self->{'line_number'}\";\n\t\t\t\t\t}\n\n\t\t\t\t\t$opcd |= $op->[0];\n\t\t\t\t}\n\n\t\t\t\t$self->{'pc'}++;\n\t\t\t}\n\n\t\t} else {\n\t\t\tif($passnum == 0) {\n\t\t\t\tif($oline =~ m/^;LUT; (.*)/o) {\n\t\t\t\t\tmy($entry, $label) = split(/\\s+/, $1);\n\t\t\t\t\t$entry =~ s/^0x//o;\n\t\t\t\t\t$self->{'LUT'}[hex($entry)] = $label;\n\t\t\t\t}\n\t\t\t\tif($oline =~ m/^;ENTRY; (.*)/o) {\n\t\t\t\t\tmy($id, $label) = split(/\\s+/, $1);\n\t\t\t\t\t$self->{'ENTRY'}{$id} = $label;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif($passnum == 1) {\n\t\t\tif(defined($opcd)) {\n\t\t\t\t$self->{'binary'} .= chr($opcd);\n\n\t\t\t\tprintf $ofh (\"/* 0x%02x */ 0x%02x%s /* %-*s */\\n\",\n\t\t\t\t\t$self->{'pc'} - 1,\n\t\t\t\t\t$opcd,\n\t\t\t\t\t(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\t($self->{'last pc'} < 0xff)\n\t\t\t\t\t\t\t|| \n\t\t\t\t\t\t\t($self->{'last pc'} != $self->{'pc'} - 1)\n\t\t\t\t\t\t) ?\n\t\t\t\t\t\t\t','\n\t\t\t\t\t\t:\n\t\t\t\t\t\t\t''\n\t\t\t\t\t),\n\t\t\t\t\t$self->{'pagewidth'} - 23,\n\t\t\t\t\t$oline\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tif($oline ne '') {\n\t\t\t\t\tprint $ofh \"                 /* $oline */\\n\";\n\t\t\t\t} else {\n\t\t\t\t\tprint $ofh \"\\n\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif($passnum == 0) {\n\t\t$self->{'last pc'} = $self->{'pc'} - 1;\n\t}\n\n\tif($passnum == 1) {\n\t\twhile($self->{'pc'} < 0xff) {\n\t\t\tprintf $ofh (\"/* 0x%02x */ 0,\\n\",\n\t\t\t\t$self->{'pc'}\n\t\t\t);\n\t\t\t$self->{'pc'}++;\n\t\t}\n\t\tif($self->{'pc'} < 0x100) {\n\t\t\tprintf $ofh (\"/* 0x%02x */ 0\\n\",\n\t\t\t\t$self->{'pc'}\n\t\t\t);\n\t\t\t$self->{'pc'}++;\n\t\t}\n\t}\n}\n\n} # package DTC_as\n\n\nuse Getopt::Std;\n\n%opt = (\n\t't' => 'unsigned char',\n);\n\n# -t type of arrays (defaults to unsigned char)\n# -l lookup table array name (no table generated if not provided)\n# -d DTC code array name (naked elements if not provided)\n# -i input filename (trailing argument if not provided)\n# -o output filename (stdout if not provided)\ngetopts('l:d:i:o:t:b', \\%opt);\n\nif(defined($opt{'i'})) {\n\t$infile = $opt{'i'};\n} else {\n\t$infile = shift;\n}\n\nif(!open(IN, '<', $infile)) {\n\tdie \"$infile: $!\";\n}\n\n\nif($opt{'b'}) {\n\tif(!defined($opt{'o'})) {\n\t\tdie \"binary format requires -o\";\n\t}\n\tif(!open(OUT, '>&', *STDOUT)) {\n\t\tdie \"dup stdout: $!\";\n\t}\n\topen(STDOUT, '>&', *STDERR);\n} else {\n\tif(defined($opt{'o'})) {\n\t\tif(!open(OUT, '>', $opt{'o'})) {\n\t\t\tdie \"$opt{'o'}: $!\";\n\t\t}\n\t} else {\n\t\tif(!open(OUT, '>&', *STDOUT)) {\n\t\t\tdie \"dup stdout: $!\";\n\t\t}\n\t\topen(STDOUT, '>&', *STDERR);\n\t}\n}\n\t\n\n$as = new DTC_as;\n\n$as->pass(*IN, *OUT, 0);\n\nif(defined($opt{'d'})) {\n\tprint OUT \"$opt{'t'} $opt{'d'}\", \"[0x100] = {\\n\";\n}\n$as->pass(*IN, *OUT, 1);\nif(defined($opt{'d'})) {\n\tprint OUT \"};\\n\\n\";\n}\n\nclose(IN);\n\nif(defined($opt{'l'})) {\n\tprint OUT \"$opt{'t'} $opt{'l'}\", \"[0x40] = {\\n\";\n#\t$end = @{$as->{'LUT'}};\n#\tif($end > 0x100) {\n#\t\t$end = 0x100;\n#\t}\n\tfor($i = 0xc0; $i < 0x100; $i++) {\n\t\t$label = $as->{'LUT'}[$i];\n\t\tif(defined($label)) {\n\t\t\tif(defined($as->{'label'}{$label})) {\n\t\t\t\tprintf OUT (\"/* 0x%02x */ 0x%02x%s /* %s */\\n\",\n\t\t\t\t\t$i,\n\t\t\t\t\t$as->{'label'}{$label},\n\t\t\t\t\t(($i < 0xff) ? ',' : ''),\n\t\t\t\t\t$label\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tdie \"label $label has not been defined\";\n\t\t\t}\n\t\t} else {\n\t\t\tprintf OUT (\"/* 0x%02x */ 0%s\\n\",\n\t\t\t\t$i,\n\t\t\t\t(($i < 0xff) ? ',' : ''),\n\t\t\t);\n\t\t}\n\t}\n\tprint OUT \"};\\n\\n\";\n}\n\n\nclose(OUT);\n\nsub DTCLOAD_COMMENT { 0; }\nsub DTCLOAD_ENTRY { 1; }\nsub DTCLOAD_LOAD { 2; }\nsub DTCLOAD_RUN { 3; }\nsub DTCLOAD_LUT_START { 4; }\nsub DTCLOAD_LUT { 5; }\n\n\nif($opt{'b'}) {\n\topen(OUT, \">\", $opt{'o'}) || die \"$opt{'o'}: $!\";\n\tsyswrite(OUT, pack('CC', DTCLOAD_LUT_COMMENT, 3 - 1) . 'DTC');\n\t\n\t$ref = $as->{'LUT'};\n\tif(@$ref > 0) {\n\t\tfor($start = 0; $start < @$ref && !defined($ref->[$start]); $start++) {}\n\t\tfor($end = 0xff; $end >= $start && !defined($ref->[$end]); $end--) {}\n\t\tundef($lut);\n\t\tfor($i = $start; $i <= $end; $i++) {\n\t\t\tif(!defined($ref->[$i])) {\n\t\t\t\t$lut .= \"\\0\";\n\t\t\t\tnext;\n\t\t\t}\n\t\t\t$label = $ref->[$i];\n\t\t\tif(defined($as->{'label'}{$label})) {\n\t\t\t\t$label = $as->{'label'}{$label};\n#\t\t\t\tprintf(\"adding LUT entry 0x%02x\\n\", $label);\n\t\t\t\t$lut .= chr($label);\n\t\t\t} else {\n\t\t\t\tdie \"label $label has not been defined\";\n\t\t\t}\n\t\t}\n\t\tif(length($lut) > 0) {\n\t\t\tsyswrite(OUT, pack('CCC', DTCLOAD_LUT_START, 1 - 1, $start));\n\t\t\tsyswrite(OUT, pack('CC', DTCLOAD_LUT, length($lut) - 1) . $lut);\n\t\t}\n\t}\n\n\twhile(($key, $label) = each(%{$as->{'ENTRY'}})) {\n#\t\tprint \"$key = $label\\n\";\n\t\tif(defined($as->{'label'}{$label})) {\n\t\t\t$label = $as->{'label'}{$label};\n#\t\t\tprint \"key=$key\\n\";\n#\t\t\tprint \"label=$label\\n\";\n\t\t\tsyswrite(OUT, pack('CCC', DTCLOAD_ENTRY, length($key), $label) . $key);\n\t\t} else {\n\t\t\tdie \"label $label has not been defined\";\n\t\t}\n\t}\n\n\tif(length($as->{'binary'})) {\n#\t\tprintf(\"DTC code size: 0x%x\\n\", length($as->{'binary'}));\n\t\tsyswrite(OUT, pack('CC',\n\t\t\tDTCLOAD_LOAD ,\n\t\t\tlength($as->{'binary'}) - 1\n\t\t) . $as->{'binary'});\n\n\t\tif(%{$as->{'ENTRY'}} < 1) {\n\t\t\tsyswrite(OUT, pack('CCC', DTCLOAD_RUN, 1 - 1, 0x00));\n\t\t}\n\t}\n\n\tclose(OUT);\n}\n\n\n0;\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/tools/uncrustify1.sh",
    "content": "#!/bin/sh\n# Run the beautifier \"Uncrustify\" on a single file.\n# Because the file \"uncrustify.cfg\" only exists in the top level of the project\n# you should run this script from there so this script can find your uncrustify.cfg file.\n\n\nUNCRUSTIFYTMP=/tmp/uncrustify.tmp\n\n\nif [ ! -f uncrustify.cfg ]; then\n    echo \"unable to find uncrustify.cfg, aborting\"\n    exit 1\nfi\n\nUNCRUSTIFYBIN=`which uncrustify`\n\nif [ \"$UNCRUSTIFYBIN\" = \"\" ]; then\n    echo \"you must specify uncrustify in your PATH, I cannot find it\"\n    exit 2\nfi\n\nif [ $# -lt 1 ]; then\n    echo \"Usage $0 <filename .c or .h>\"\n    exit 3\nfi\n\nuncrustify -c uncrustify.cfg <$1 >$UNCRUSTIFYTMP\n\n# you can comment this out while tuning the uncrustify.cfg file:\nmv $UNCRUSTIFYTMP $1\n"
  },
  {
    "path": "Tools/CH347/ch347-main/OpenOCD_SourceCode_CH347/uncrustify.cfg",
    "content": "tok_split_gte=false\nutf8_byte=false\nutf8_force=false\nindent_cmt_with_tabs=true\nindent_align_string=false\nindent_braces=false\nindent_braces_no_func=false\nindent_braces_no_class=false\nindent_braces_no_struct=false\nindent_brace_parent=false\nindent_namespace=false\nindent_extern=false\nindent_class=false\nindent_class_colon=false\nindent_else_if=false\nindent_var_def_cont=false\nindent_func_call_param=true\nindent_func_def_param=true\nindent_func_proto_param=false\nindent_func_class_param=false\nindent_func_ctor_var_param=false\nindent_template_param=false\nindent_func_param_double=true\nindent_relative_single_line_comments=false\nindent_col1_comment=false\nindent_access_spec_body=false\nindent_paren_nl=false\nindent_comma_paren=false\nindent_bool_paren=false\nindent_first_bool_expr=false\nindent_square_nl=false\nindent_preserve_sql=false\nindent_align_assign=false\nsp_balance_nested_parens=false\nalign_keep_tabs=false\nalign_with_tabs=false\nalign_on_tabstop=false\nalign_number_left=false\nalign_func_params=false\nalign_same_func_call_params=false\nalign_var_def_colon=false\nalign_var_def_attribute=false\nalign_var_def_inline=false\nalign_right_cmt_mix=false\nalign_on_operator=false\nalign_mix_var_proto=false\nalign_single_line_func=false\nalign_single_line_brace=false\nalign_nl_cont=false\nalign_left_shift=true\nalign_oc_decl_colon=false\nnl_collapse_empty_body=false\nnl_assign_leave_one_liners=false\nnl_class_leave_one_liners=false\nnl_enum_leave_one_liners=false\nnl_getset_leave_one_liners=false\nnl_func_leave_one_liners=false\nnl_if_leave_one_liners=false\nnl_multi_line_cond=false\nnl_multi_line_define=false\nnl_before_case=false\nnl_after_case=false\nnl_after_return=false\nnl_after_semicolon=false\nnl_after_brace_open=false\nnl_after_brace_open_cmt=false\nnl_after_vbrace_open=true\nnl_after_vbrace_open_empty=false\nnl_after_brace_close=false\nnl_after_vbrace_close=false\nnl_define_macro=false\nnl_squeeze_ifdef=false\nnl_ds_struct_enum_cmt=false\nnl_ds_struct_enum_close_brace=false\nnl_create_if_one_liner=false\nnl_create_for_one_liner=false\nnl_create_while_one_liner=false\nls_for_split_full=false\nls_func_split_full=true\nnl_after_multiline_comment=false\neat_blanks_after_open_brace=false\neat_blanks_before_close_brace=false\nmod_full_brace_if_chain=false\nmod_pawn_semicolon=false\nmod_full_paren_if_bool=false\nmod_remove_extra_semicolon=false\nmod_sort_import=false\nmod_sort_using=false\nmod_sort_include=false\nmod_move_case_break=false\nmod_remove_empty_return=false\ncmt_indent_multi=false\ncmt_c_group=true\ncmt_c_nl_start=false\ncmt_c_nl_end=false\ncmt_cpp_group=false\ncmt_cpp_nl_start=false\ncmt_cpp_nl_end=false\ncmt_cpp_to_c=true\ncmt_star_cont=true\ncmt_multi_check_last=false\ncmt_insert_before_preproc=false\npp_indent_at_level=false\npp_region_indent_code=false\npp_if_indent_code=false\npp_define_at_level=false\nindent_columns=8\nindent_continue=8\nindent_switch_case=8\nnl_end_of_file_min=1\ncode_width=100\nmod_full_brace_nl=2\ncmt_width=100\ncmt_reflow_mode=2\nindent_with_tabs=2\nsp_after_assign=force\nsp_compare=add\nsp_before_ptr_star=force\nsp_between_ptr_star=remove\nsp_after_ptr_star=remove\nsp_before_ptr_star_func=force\nsp_before_sparen=add\nsp_inside_sparen=remove\nsp_inside_fparen=remove\nsp_else_brace=force\nsp_brace_else=force\nnl_end_of_file=force\nnl_assign_brace=remove\nnl_enum_brace=remove\nnl_struct_brace=remove\nnl_union_brace=remove\nnl_if_brace=remove\nnl_brace_else=remove\nnl_elseif_brace=remove\nnl_else_brace=remove\nnl_for_brace=remove\nnl_while_brace=remove\nnl_switch_brace=remove\nnl_func_type_name=remove\nnl_fdef_brace=force\nmod_full_brace_for=remove\nmod_full_brace_if=remove\n"
  },
  {
    "path": "Tools/README.md",
    "content": " Tools List\n\n./CH347\n- CH343CDC.ZIP - Driver for ch347 (From WCH)\n- ch347-main - Flash util for ch347 (From WCH)\n- If your ch347 is bricked DM me I made a tool to fix - 10 USD\n"
  }
]